From hdegoede at redhat.com  Sat Aug  1 00:25:16 2015
From: hdegoede at redhat.com (Hans de Goede)
Date: Sat,  1 Aug 2015 09:25:16 +0200
Subject: [PATCH v3 resend 0/2] mfd: axp20x: Add usb-power-supply support
Message-ID: <1438413918-15765-1-git-send-email-hdegoede@redhat.com>

Hi Lee,

AFAICT these 2 are ready for merging but I do not see them in mfd/for-mfd-next
hence this resend.

Thanks,

Hans


From hdegoede at redhat.com  Sat Aug  1 00:25:17 2015
From: hdegoede at redhat.com (Hans de Goede)
Date: Sat,  1 Aug 2015 09:25:17 +0200
Subject: [PATCH v3 resend 1/2] mfd: axp20x: Add missing registers,
 and mark more registers volatile
In-Reply-To: <1438413918-15765-1-git-send-email-hdegoede@redhat.com>
References: <1438413918-15765-1-git-send-email-hdegoede@redhat.com>
Message-ID: <1438413918-15765-2-git-send-email-hdegoede@redhat.com>

From: Bruno Pr?mont <bonbons at linux-vserver.org>

Add an extra set of registers which is necessary tu support the PMICs
battery charger function, and mark registers which contain status bits,
gpio status, and adc readings as volatile.

Cc: Bruno Pr?mont <bonbons at linux-vserver.org>
Signed-off-by: Bruno Pr?mont <bonbons at linux-vserver.org>
Signed-off-by: Hans de Goede <hdegoede at redhat.com>
Acked-by: Lee Jones <lee.jones at linaro.org>
Acked-by: Maxime Ripard <maxime.ripard at free-electrons.com>
---
Changes in v2:
-Add a AXP20X_OCV_MAX define
Changes in v3:
-Add Bruno's S-o-b
---
 drivers/mfd/axp20x.c       | 8 +++++++-
 include/linux/mfd/axp20x.h | 6 ++++++
 2 files changed, 13 insertions(+), 1 deletion(-)

diff --git a/drivers/mfd/axp20x.c b/drivers/mfd/axp20x.c
index b369cfc..8bd3283 100644
--- a/drivers/mfd/axp20x.c
+++ b/drivers/mfd/axp20x.c
@@ -61,10 +61,16 @@ static const struct regmap_access_table axp152_volatile_table = {
 static const struct regmap_range axp20x_writeable_ranges[] = {
 	regmap_reg_range(AXP20X_DATACACHE(0), AXP20X_IRQ5_STATE),
 	regmap_reg_range(AXP20X_DCDC_MODE, AXP20X_FG_RES),
+	regmap_reg_range(AXP20X_RDC_H, AXP20X_OCV(15)),
 };
 
 static const struct regmap_range axp20x_volatile_ranges[] = {
+	regmap_reg_range(AXP20X_PWR_INPUT_STATUS, AXP20X_USB_OTG_STATUS),
+	regmap_reg_range(AXP20X_CHRG_CTRL1, AXP20X_CHRG_CTRL2),
 	regmap_reg_range(AXP20X_IRQ1_EN, AXP20X_IRQ5_STATE),
+	regmap_reg_range(AXP20X_ACIN_V_ADC_H, AXP20X_IPSOUT_V_HIGH_L),
+	regmap_reg_range(AXP20X_GPIO20_SS, AXP20X_GPIO3_CTRL),
+	regmap_reg_range(AXP20X_FG_RES, AXP20X_RDC_L),
 };
 
 static const struct regmap_access_table axp20x_writeable_table = {
@@ -195,7 +201,7 @@ static const struct regmap_config axp20x_regmap_config = {
 	.val_bits	= 8,
 	.wr_table	= &axp20x_writeable_table,
 	.volatile_table	= &axp20x_volatile_table,
-	.max_register	= AXP20X_FG_RES,
+	.max_register	= AXP20X_OCV(AXP20X_OCV_MAX),
 	.cache_type	= REGCACHE_RBTREE,
 };
 
diff --git a/include/linux/mfd/axp20x.h b/include/linux/mfd/axp20x.h
index 52203d5..cc8ad1e 100644
--- a/include/linux/mfd/axp20x.h
+++ b/include/linux/mfd/axp20x.h
@@ -190,6 +190,12 @@ enum {
 #define AXP20X_CC_CTRL			0xb8
 #define AXP20X_FG_RES			0xb9
 
+/* OCV */
+#define AXP20X_RDC_H			0xba
+#define AXP20X_RDC_L			0xbb
+#define AXP20X_OCV(m)			(0xc0 + (m))
+#define AXP20X_OCV_MAX			0xf
+
 /* AXP22X specific registers */
 #define AXP22X_BATLOW_THRES1		0xe6
 
-- 
2.4.3



From hdegoede at redhat.com  Sat Aug  1 00:25:18 2015
From: hdegoede at redhat.com (Hans de Goede)
Date: Sat,  1 Aug 2015 09:25:18 +0200
Subject: [PATCH v3 resend 2/2] mfd: axp20x: Add a cell for the usb
 power_supply part of the axp20x PMICs
In-Reply-To: <1438413918-15765-1-git-send-email-hdegoede@redhat.com>
References: <1438413918-15765-1-git-send-email-hdegoede@redhat.com>
Message-ID: <1438413918-15765-3-git-send-email-hdegoede@redhat.com>

Add a cell for the usb power_supply part of the axp20x PMICs.

Note that this cell is only for the usb power_supply part and not the
ac-power / battery-charger / rtc-backup-bat-charger bits.

Depending on the board each of those must be enabled / disabled separately
in devicetree as most boards do not use all 4. So in dt each one needs its
own child-node of the axp20x node. Another reason for using separate child
nodes for each is so that other devicetree nodes can have a power-supply
property with a phandle referencing a node representing a single
power-supply.

The decision to use a separate devicetree node for each is reflected on
the kernel side by each getting its own mfd-cell / platform_device and
platform-driver.

Note this commit also makes some whitespace changes to the intialization
of existing cells in axp20x_cells, these are pure whitespace changes,
functionally nothing changes.

Cc: Bruno Pr?mont <bonbons at linux-vserver.org>
Signed-off-by: Bruno Pr?mont <bonbons at linux-vserver.org>
Signed-off-by: Hans de Goede <hdegoede at redhat.com>
Acked-by: Maxime Ripard <maxime.ripard at free-electrons.com>
Acked-by: Lee Jones <lee.jones at linaro.org>
---
Changes in v2:
-Use DEFINE_RES_IRQ_NAMED
-Change indentation of axp20x_cells initializers to avoid line wrapping
Changes in v3:
-Improve commit message
-Add Bruno's S-o-b
---
 drivers/mfd/axp20x.c | 20 ++++++++++++++++----
 1 file changed, 16 insertions(+), 4 deletions(-)

diff --git a/drivers/mfd/axp20x.c b/drivers/mfd/axp20x.c
index 8bd3283..a69b996 100644
--- a/drivers/mfd/axp20x.c
+++ b/drivers/mfd/axp20x.c
@@ -140,6 +140,13 @@ static struct resource axp20x_pek_resources[] = {
 	},
 };
 
+static struct resource axp20x_usb_power_supply_resources[] = {
+	DEFINE_RES_IRQ_NAMED(AXP20X_IRQ_VBUS_PLUGIN, "VBUS_PLUGIN"),
+	DEFINE_RES_IRQ_NAMED(AXP20X_IRQ_VBUS_REMOVAL, "VBUS_REMOVAL"),
+	DEFINE_RES_IRQ_NAMED(AXP20X_IRQ_VBUS_VALID, "VBUS_VALID"),
+	DEFINE_RES_IRQ_NAMED(AXP20X_IRQ_VBUS_NOT_VALID, "VBUS_NOT_VALID"),
+};
+
 static struct resource axp22x_pek_resources[] = {
 	{
 		.name   = "PEK_DBR",
@@ -432,11 +439,16 @@ static const struct regmap_irq_chip axp288_regmap_irq_chip = {
 
 static struct mfd_cell axp20x_cells[] = {
 	{
-		.name			= "axp20x-pek",
-		.num_resources		= ARRAY_SIZE(axp20x_pek_resources),
-		.resources		= axp20x_pek_resources,
+		.name		= "axp20x-pek",
+		.num_resources	= ARRAY_SIZE(axp20x_pek_resources),
+		.resources	= axp20x_pek_resources,
 	}, {
-		.name			= "axp20x-regulator",
+		.name		= "axp20x-regulator",
+	}, {
+		.name		= "axp20x-usb-power-supply",
+		.of_compatible	= "x-powers,axp202-usb-power-supply",
+		.num_resources	= ARRAY_SIZE(axp20x_usb_power_supply_resources),
+		.resources	= axp20x_usb_power_supply_resources,
 	},
 };
 
-- 
2.4.3



From hdegoede at redhat.com  Sat Aug  1 00:43:24 2015
From: hdegoede at redhat.com (Hans de Goede)
Date: Sat, 1 Aug 2015 09:43:24 +0200
Subject: [PATCH v3 1/4] ARM: dts: Add binding documentation for AXP20x
 pmic usb power supply
In-Reply-To: <20150724145928.GG27569@earth>
References: <1435316357-26606-1-git-send-email-hdegoede@redhat.com>
 <20150724145928.GG27569@earth>
Message-ID: <55BC789C.4020205@redhat.com>

Hi,

On 24-07-15 16:59, Sebastian Reichel wrote:
> Hi,
>
> On Fri, Jun 26, 2015 at 12:59:14PM +0200, Hans de Goede wrote:
>> Add binding documentation for the usb power supply part of the AXP20x pmic.
>> [...]
>> +Example:
>> +
>> [...]
>> +
>> +	usb_power_supply: usb_power_supply {
>                        ^^^^^^^^^^^^^^^^
>                        use usb-power-supply here.

Ok, fixed for the upcoming v4 of the power-supply part of this patch set.

Regards,

Hans


From k.kozlowski at samsung.com  Sat Aug  1 00:43:58 2015
From: k.kozlowski at samsung.com (Krzysztof Kozlowski)
Date: Sat, 01 Aug 2015 16:43:58 +0900
Subject: [PATCH v3 3/5] ARM: Exynos: switch to using generic cpufreq driver
 for Exynos4x12
In-Reply-To: <1438368557-2352-4-git-send-email-b.zolnierkie@samsung.com>
References: <1438368557-2352-1-git-send-email-b.zolnierkie@samsung.com>
 <1438368557-2352-4-git-send-email-b.zolnierkie@samsung.com>
Message-ID: <55BC78BE.5020102@samsung.com>

W dniu 01.08.2015 o 03:49, Bartlomiej Zolnierkiewicz pisze:
> The new CPU clock type allows the use of generic CPUfreq driver.
> Switch Exynos4x12 to using generic cpufreq driver.
> 
> Also make CPUFREQ_DT config option select Exynos thermal driver
> if Exynos platform support is enabled.

Why? I think this wasn't in your previous patch.

Best regards,
Krzysztof


> 
> Please also note that the switch to use the generic cpufreq-dt
> driver fixes the minor issue present with the old code (support
> for 'boost' mode in the exynos-cpufreq driver was enabled for
> all supported SoCs even though 'boost' frequency was provided
> only for Exynos4x12 ones).
> 
> Cc: Tomasz Figa <tomasz.figa at gmail.com>
> Cc: Kukjin Kim <kgene.kim at samsung.com>
> Cc: Thomas Abraham <thomas.ab at samsung.com>
> Cc: Javier Martinez Canillas <javier at osg.samsung.com>
> Signed-off-by: Bartlomiej Zolnierkiewicz <b.zolnierkie at samsung.com>
> ---
>  arch/arm/mach-exynos/exynos.c | 2 ++
>  drivers/cpufreq/Kconfig       | 1 +
>  2 files changed, 3 insertions(+)
> 
> diff --git a/arch/arm/mach-exynos/exynos.c b/arch/arm/mach-exynos/exynos.c
> index 77ac021..1c47aee 100644
> --- a/arch/arm/mach-exynos/exynos.c
> +++ b/arch/arm/mach-exynos/exynos.c
> @@ -227,6 +227,8 @@ static void __init exynos_init_irq(void)
>  static const struct of_device_id exynos_cpufreq_matches[] = {
>  	{ .compatible = "samsung,exynos3250", .data = "cpufreq-dt" },
>  	{ .compatible = "samsung,exynos4210", .data = "cpufreq-dt" },
> +	{ .compatible = "samsung,exynos4212", .data = "cpufreq-dt" },
> +	{ .compatible = "samsung,exynos4412", .data = "cpufreq-dt" },
>  	{ .compatible = "samsung,exynos5250", .data = "cpufreq-dt" },
>  	{ /* sentinel */ }
>  };
> diff --git a/drivers/cpufreq/Kconfig b/drivers/cpufreq/Kconfig
> index 659879a..bf6d596 100644
> --- a/drivers/cpufreq/Kconfig
> +++ b/drivers/cpufreq/Kconfig
> @@ -191,6 +191,7 @@ config CPUFREQ_DT
>  	# if CPU_THERMAL is on and THERMAL=m, CPUFREQ_DT cannot be =y:
>  	depends on !CPU_THERMAL || THERMAL
>  	select PM_OPP
> +	select EXYNOS_THERMAL if ARCH_EXYNOS
>  	help
>  	  This adds a generic DT based cpufreq driver for frequency management.
>  	  It supports both uniprocessor (UP) and symmetric multiprocessor (SMP)
> 



From hdegoede at redhat.com  Sat Aug  1 00:44:05 2015
From: hdegoede at redhat.com (Hans de Goede)
Date: Sat, 1 Aug 2015 09:44:05 +0200
Subject: [PATCH v3 4/4] power: Add an axp20x-usb-power driver
In-Reply-To: <20150724151020.GH27569@earth>
References: <1435316357-26606-1-git-send-email-hdegoede@redhat.com>
 <1435316357-26606-4-git-send-email-hdegoede@redhat.com>
 <20150724151020.GH27569@earth>
Message-ID: <55BC78C5.8090400@redhat.com>

Hi,

On 24-07-15 17:10, Sebastian Reichel wrote:
> Hi,
>
> On Fri, Jun 26, 2015 at 12:59:17PM +0200, Hans de Goede wrote:
>> This adds a driver for the usb power_supply bits of the axp20x PMICs.
>>
>> I initially started writing my own driver, before coming aware of
>> Bruno Pr?mont's excellent earlier RFC with a driver for this.
>>
>> My driver was lacking CURRENT_MAX and VOLTAGE_MIN support Bruno's
>> drvier has, so I've copied the code for those from his driver.
>>
>> Note that the AC-power-supply and battery charger bits will need separate
>> drivers. Each one needs its own devictree child-node so that other
>> devicetree nodes can reference the right power-supply, and thus each one
>> will get its own mfd-cell / platform_device and platform-driver.
>
> Once the other comments have been taken care of, the driver looks ok
> to me.

Ok, I will do a v4 of the power-supply part of this patch set, with the
various remarks on this patch fixed.

Thanks & Regards,

Hans


From hdegoede at redhat.com  Sat Aug  1 01:39:37 2015
From: hdegoede at redhat.com (Hans de Goede)
Date: Sat,  1 Aug 2015 10:39:37 +0200
Subject: [PATCH v4 1/2] ARM: dts: Add binding documentation for AXP20x pmic
 usb power supply
Message-ID: <1438418378-32656-1-git-send-email-hdegoede@redhat.com>

Add binding documentation for the usb power supply part of the AXP20x pmic.

Signed-off-by: Hans de Goede <hdegoede at redhat.com>
---
Changes in v2:
-Split out into a separate patch from the actual driver commit
Changes in v4:
-s/usb_power_supply/usb-power-supply/ in the dts example code
---
 .../bindings/power_supply/axp20x_usb_power.txt     | 34 ++++++++++++++++++++++
 1 file changed, 34 insertions(+)
 create mode 100644 Documentation/devicetree/bindings/power_supply/axp20x_usb_power.txt

diff --git a/Documentation/devicetree/bindings/power_supply/axp20x_usb_power.txt b/Documentation/devicetree/bindings/power_supply/axp20x_usb_power.txt
new file mode 100644
index 0000000..862f4a4
--- /dev/null
+++ b/Documentation/devicetree/bindings/power_supply/axp20x_usb_power.txt
@@ -0,0 +1,34 @@
+AXP20x USB power supply
+
+Required Properties:
+-compatible: "x-powers,axp202-usb-power-supply"
+
+This node is a subnode of the axp20x PMIC.
+
+Example:
+
+axp209: pmic at 34 {
+	compatible = "x-powers,axp209";
+	reg = <0x34>;
+	interrupt-parent = <&nmi_intc>;
+	interrupts = <0 IRQ_TYPE_LEVEL_LOW>;
+	interrupt-controller;
+	#interrupt-cells = <1>;
+
+	regulators {
+		x-powers,dcdc-freq = <1500>;
+
+		vdd_cpu: dcdc2 {
+			regulator-always-on;
+			regulator-min-microvolt = <1000000>;
+			regulator-max-microvolt = <1450000>;
+			regulator-name = "vdd-cpu";
+		};
+
+		...
+	};
+
+	usb-power-supply: usb-power-supply {
+		compatible = "x-powers,axp202-usb-power-supply";
+	};
+};
-- 
2.4.3



From hdegoede at redhat.com  Sat Aug  1 01:39:38 2015
From: hdegoede at redhat.com (Hans de Goede)
Date: Sat,  1 Aug 2015 10:39:38 +0200
Subject: [PATCH v4 2/2] power: Add an axp20x-usb-power driver
In-Reply-To: <1438418378-32656-1-git-send-email-hdegoede@redhat.com>
References: <1438418378-32656-1-git-send-email-hdegoede@redhat.com>
Message-ID: <1438418378-32656-2-git-send-email-hdegoede@redhat.com>

This adds a driver for the usb power_supply bits of the axp20x PMICs.

I initially started writing my own driver, before coming aware of
Bruno Pr?mont's excellent earlier RFC with a driver for this.

My driver was lacking CURRENT_MAX and VOLTAGE_MIN support Bruno's
drvier has, so I've copied the code for those from his driver.

Note that the AC-power-supply and battery charger bits will need separate
drivers. Each one needs its own devictree child-node so that other
devicetree nodes can reference the right power-supply, and thus each one
will get its own mfd-cell / platform_device and platform-driver.

Cc: Bruno Pr?mont <bonbons at linux-vserver.org>
Acked-by: Lee Jones <lee.jones at linaro.org>
Signed-off-by: Bruno Pr?mont <bonbons at linux-vserver.org>
Signed-off-by: Hans de Goede <hdegoede at redhat.com>
---
Changes in v2:
-Split out the dt-bindings documentation into a separate patch
-Renamed axp20x_read_16bit to axp20x_read_variable_width
-Use better local variable names inside axp20x_read_variable_width
Changes in v3:
-Add Bruno's S-o-b
Changes in v4:
-Check that parent drv data is not NULL
-Replace "r" local variable with a "ret" variable
---
 drivers/power/Kconfig            |   7 ++
 drivers/power/Makefile           |   1 +
 drivers/power/axp20x_usb_power.c | 248 +++++++++++++++++++++++++++++++++++++++
 include/linux/mfd/axp20x.h       |  24 ++++
 4 files changed, 280 insertions(+)
 create mode 100644 drivers/power/axp20x_usb_power.c

diff --git a/drivers/power/Kconfig b/drivers/power/Kconfig
index 08beeed..29b447f 100644
--- a/drivers/power/Kconfig
+++ b/drivers/power/Kconfig
@@ -467,6 +467,13 @@ config CHARGER_RT9455
 	help
 	  Say Y to enable support for Richtek RT9455 battery charger.
 
+config AXP20X_POWER
+	tristate "AXP20x power supply driver"
+	depends on MFD_AXP20X
+	help
+	  This driver provides support for the power supply features of
+	  AXP20x PMIC.
+
 source "drivers/power/reset/Kconfig"
 
 endif # POWER_SUPPLY
diff --git a/drivers/power/Makefile b/drivers/power/Makefile
index 5752ce8..fb4413e 100644
--- a/drivers/power/Makefile
+++ b/drivers/power/Makefile
@@ -9,6 +9,7 @@ obj-$(CONFIG_GENERIC_ADC_BATTERY)	+= generic-adc-battery.o
 
 obj-$(CONFIG_PDA_POWER)		+= pda_power.o
 obj-$(CONFIG_APM_POWER)		+= apm_power.o
+obj-$(CONFIG_AXP20X_POWER)	+= axp20x_usb_power.o
 obj-$(CONFIG_MAX8925_POWER)	+= max8925_power.o
 obj-$(CONFIG_WM831X_BACKUP)	+= wm831x_backup.o
 obj-$(CONFIG_WM831X_POWER)	+= wm831x_power.o
diff --git a/drivers/power/axp20x_usb_power.c b/drivers/power/axp20x_usb_power.c
new file mode 100644
index 0000000..421a90b
--- /dev/null
+++ b/drivers/power/axp20x_usb_power.c
@@ -0,0 +1,248 @@
+/*
+ * AXP20x PMIC USB power supply status driver
+ *
+ * Copyright (C) 2015 Hans de Goede <hdegoede at redhat.com>
+ * Copyright (C) 2014 Bruno Pr?mont <bonbons at linux-vserver.org>
+ *
+ * This program is free software; you can redistribute it and/or modify it
+ * under  the terms of the GNU General  Public License as published by the
+ * Free Software Foundation;  either version 2 of the License, or (at your
+ * option) any later version.
+ */
+
+#include <linux/device.h>
+#include <linux/init.h>
+#include <linux/interrupt.h>
+#include <linux/kernel.h>
+#include <linux/mfd/axp20x.h>
+#include <linux/module.h>
+#include <linux/of.h>
+#include <linux/platform_device.h>
+#include <linux/power_supply.h>
+#include <linux/regmap.h>
+#include <linux/slab.h>
+
+#define DRVNAME "axp20x-usb-power-supply"
+
+#define AXP20X_PWR_STATUS_VBUS_PRESENT	BIT(5)
+#define AXP20X_PWR_STATUS_VBUS_USED	BIT(4)
+
+#define AXP20X_USB_STATUS_VBUS_VALID	BIT(2)
+
+#define AXP20X_VBUS_VHOLD_uV(b)		(4000000 + (((b) >> 3) & 7) * 100000)
+#define AXP20X_VBUS_CLIMIT_MASK		3
+#define AXP20X_VBUC_CLIMIT_900mA	0
+#define AXP20X_VBUC_CLIMIT_500mA	1
+#define AXP20X_VBUC_CLIMIT_100mA	2
+#define AXP20X_VBUC_CLIMIT_NONE		3
+
+#define AXP20X_ADC_EN1_VBUS_CURR	BIT(2)
+#define AXP20X_ADC_EN1_VBUS_VOLT	BIT(3)
+
+#define AXP20X_VBUS_MON_VBUS_VALID	BIT(3)
+
+struct axp20x_usb_power {
+	struct regmap *regmap;
+	struct power_supply *supply;
+};
+
+static irqreturn_t axp20x_usb_power_irq(int irq, void *devid)
+{
+	struct axp20x_usb_power *power = devid;
+
+	power_supply_changed(power->supply);
+
+	return IRQ_HANDLED;
+}
+
+static int axp20x_usb_power_get_property(struct power_supply *psy,
+	enum power_supply_property psp, union power_supply_propval *val)
+{
+	struct axp20x_usb_power *power = power_supply_get_drvdata(psy);
+	unsigned int input, v;
+	int ret;
+
+	switch (psp) {
+	case POWER_SUPPLY_PROP_VOLTAGE_MIN:
+		ret = regmap_read(power->regmap, AXP20X_VBUS_IPSOUT_MGMT, &v);
+		if (ret)
+			return ret;
+
+		val->intval = AXP20X_VBUS_VHOLD_uV(v);
+		return 0;
+	case POWER_SUPPLY_PROP_VOLTAGE_NOW:
+		ret = axp20x_read_variable_width(power->regmap,
+						 AXP20X_VBUS_V_ADC_H, 12);
+		if (ret < 0)
+			return ret;
+
+		val->intval = ret * 1700; /* 1 step = 1.7 mV */
+		return 0;
+	case POWER_SUPPLY_PROP_CURRENT_MAX:
+		ret = regmap_read(power->regmap, AXP20X_VBUS_IPSOUT_MGMT, &v);
+		if (ret)
+			return ret;
+
+		switch (v & AXP20X_VBUS_CLIMIT_MASK) {
+		case AXP20X_VBUC_CLIMIT_100mA:
+			val->intval = 100000;
+			break;
+		case AXP20X_VBUC_CLIMIT_500mA:
+			val->intval = 500000;
+			break;
+		case AXP20X_VBUC_CLIMIT_900mA:
+			val->intval = 900000;
+			break;
+		case AXP20X_VBUC_CLIMIT_NONE:
+			val->intval = -1;
+			break;
+		}
+		return 0;
+	case POWER_SUPPLY_PROP_CURRENT_NOW:
+		ret = axp20x_read_variable_width(power->regmap,
+						 AXP20X_VBUS_I_ADC_H, 12);
+		if (ret < 0)
+			return ret;
+
+		val->intval = ret * 375; /* 1 step = 0.375 mA */
+		return 0;
+	default:
+		break;
+	}
+
+	/* All the properties below need the input-status reg value */
+	ret = regmap_read(power->regmap, AXP20X_PWR_INPUT_STATUS, &input);
+	if (ret)
+		return ret;
+
+	switch (psp) {
+	case POWER_SUPPLY_PROP_HEALTH:
+		if (!(input & AXP20X_PWR_STATUS_VBUS_PRESENT)) {
+			val->intval = POWER_SUPPLY_HEALTH_UNKNOWN;
+			break;
+		}
+
+		ret = regmap_read(power->regmap, AXP20X_USB_OTG_STATUS, &v);
+		if (ret)
+			return ret;
+
+		if (!(v & AXP20X_USB_STATUS_VBUS_VALID)) {
+			val->intval = POWER_SUPPLY_HEALTH_UNSPEC_FAILURE;
+			break;
+		}
+
+		val->intval = POWER_SUPPLY_HEALTH_GOOD;
+		break;
+	case POWER_SUPPLY_PROP_PRESENT:
+		val->intval = !!(input & AXP20X_PWR_STATUS_VBUS_PRESENT);
+		break;
+	case POWER_SUPPLY_PROP_ONLINE:
+		val->intval = !!(input & AXP20X_PWR_STATUS_VBUS_USED);
+		break;
+	default:
+		return -EINVAL;
+	}
+
+	return 0;
+}
+
+static enum power_supply_property axp20x_usb_power_properties[] = {
+	POWER_SUPPLY_PROP_HEALTH,
+	POWER_SUPPLY_PROP_PRESENT,
+	POWER_SUPPLY_PROP_ONLINE,
+	POWER_SUPPLY_PROP_VOLTAGE_MIN,
+	POWER_SUPPLY_PROP_VOLTAGE_NOW,
+	POWER_SUPPLY_PROP_CURRENT_MAX,
+	POWER_SUPPLY_PROP_CURRENT_NOW,
+};
+
+static const struct power_supply_desc axp20x_usb_power_desc = {
+	.name = "axp20x-usb",
+	.type = POWER_SUPPLY_TYPE_USB,
+	.properties = axp20x_usb_power_properties,
+	.num_properties = ARRAY_SIZE(axp20x_usb_power_properties),
+	.get_property = axp20x_usb_power_get_property,
+};
+
+static int axp20x_usb_power_probe(struct platform_device *pdev)
+{
+	struct axp20x_dev *axp20x = dev_get_drvdata(pdev->dev.parent);
+	struct power_supply_config psy_cfg = {};
+	struct axp20x_usb_power *power;
+	static const char * const irq_names[] = { "VBUS_PLUGIN",
+		"VBUS_REMOVAL", "VBUS_VALID", "VBUS_NOT_VALID" };
+	int i, irq, ret;
+
+	if (!of_device_is_available(pdev->dev.of_node))
+		return -ENODEV;
+
+	if (!axp20x) {
+		dev_err(&pdev->dev, "Parent drvdata not set\n");
+		return -EINVAL;
+	}
+
+	power = devm_kzalloc(&pdev->dev, sizeof(*power), GFP_KERNEL);
+	if (!power)
+		return -ENOMEM;
+
+	power->regmap = axp20x->regmap;
+
+	/* Enable vbus valid checking */
+	ret = regmap_update_bits(power->regmap, AXP20X_VBUS_MON,
+		    AXP20X_VBUS_MON_VBUS_VALID, AXP20X_VBUS_MON_VBUS_VALID);
+	if (ret)
+		return ret;
+
+	/* Enable vbus voltage and current measurement */
+	ret = regmap_update_bits(power->regmap, AXP20X_ADC_EN1,
+			AXP20X_ADC_EN1_VBUS_CURR | AXP20X_ADC_EN1_VBUS_VOLT,
+			AXP20X_ADC_EN1_VBUS_CURR | AXP20X_ADC_EN1_VBUS_VOLT);
+	if (ret)
+		return ret;
+
+	psy_cfg.of_node = pdev->dev.of_node;
+	psy_cfg.drv_data = power;
+
+	power->supply = devm_power_supply_register(&pdev->dev,
+					&axp20x_usb_power_desc, &psy_cfg);
+	if (IS_ERR(power->supply))
+		return PTR_ERR(power->supply);
+
+	/* Request irqs after registering, as irqs may trigger immediately */
+	for (i = 0; i < ARRAY_SIZE(irq_names); i++) {
+		irq = platform_get_irq_byname(pdev, irq_names[i]);
+		if (irq < 0) {
+			dev_warn(&pdev->dev, "No IRQ for %s: %d\n",
+				 irq_names[i], irq);
+			continue;
+		}
+		irq = regmap_irq_get_virq(axp20x->regmap_irqc, irq);
+		ret = devm_request_any_context_irq(&pdev->dev, irq,
+				axp20x_usb_power_irq, 0, DRVNAME, power);
+		if (ret < 0)
+			dev_warn(&pdev->dev, "Error requesting %s IRQ: %d\n",
+				 irq_names[i], ret);
+	}
+
+	return 0;
+}
+
+static const struct of_device_id axp20x_usb_power_match[] = {
+	{ .compatible = "x-powers,axp202-usb-power-supply" },
+	{ }
+};
+MODULE_DEVICE_TABLE(of, axp20x_usb_power_match);
+
+static struct platform_driver axp20x_usb_power_driver = {
+	.probe = axp20x_usb_power_probe,
+	.driver = {
+		.name = DRVNAME,
+		.of_match_table = axp20x_usb_power_match,
+	},
+};
+
+module_platform_driver(axp20x_usb_power_driver);
+
+MODULE_AUTHOR("Hans de Goede <hdegoede at redhat.com>");
+MODULE_DESCRIPTION("AXP20x PMIC USB power supply status driver");
+MODULE_LICENSE("GPL");
diff --git a/include/linux/mfd/axp20x.h b/include/linux/mfd/axp20x.h
index cc8ad1e..b24c771 100644
--- a/include/linux/mfd/axp20x.h
+++ b/include/linux/mfd/axp20x.h
@@ -11,6 +11,8 @@
 #ifndef __LINUX_MFD_AXP20X_H
 #define __LINUX_MFD_AXP20X_H
 
+#include <linux/regmap.h>
+
 enum {
 	AXP152_ID = 0,
 	AXP202_ID,
@@ -438,4 +440,26 @@ struct axp288_extcon_pdata {
 	struct gpio_desc *gpio_mux_cntl;
 };
 
+/* generic helper function for reading 9-16 bit wide regs */
+static inline int axp20x_read_variable_width(struct regmap *regmap,
+	unsigned int reg, unsigned int width)
+{
+	unsigned int reg_val, result;
+	int err;
+
+	err = regmap_read(regmap, reg, &reg_val);
+	if (err)
+		return err;
+
+	result = reg_val << (width - 8);
+
+	err = regmap_read(regmap, reg + 1, &reg_val);
+	if (err)
+		return err;
+
+	result |= reg_val;
+
+	return result;
+}
+
 #endif /* __LINUX_MFD_AXP20X_H */
-- 
2.4.3



From hdegoede at redhat.com  Sat Aug  1 02:01:18 2015
From: hdegoede at redhat.com (Hans de Goede)
Date: Sat, 1 Aug 2015 11:01:18 +0200
Subject: [PATCH v2] mmc: sunxi: Don't start commands while the card is busy
In-Reply-To: <CAPDyKFoNe0bghfSXs48stHzZToTc7Hjd5gVPy-VbDF8bzdVVMQ@mail.gmail.com>
References: <1436541284-11800-1-git-send-email-hdegoede@redhat.com>
 <CAPDyKFoNe0bghfSXs48stHzZToTc7Hjd5gVPy-VbDF8bzdVVMQ@mail.gmail.com>
Message-ID: <55BC8ADE.3070802@redhat.com>

Hi,

On 21-07-15 14:15, Ulf Hansson wrote:
> On 10 July 2015 at 17:14, Hans de Goede <hdegoede at redhat.com> wrote:
>> Some sdio wifi modules have not been working reliable with the sunxi-mmc
>> host code. This turns out to be caused by it starting new commands while
>> the card signals that it is still busy processing a previous command.
>
> Which are those commands?

The code were things get stuck when not waiting for the busy signal uses
the following sdio helper functions:

sdio_readb/sdio_writeb
sdio_f0_readb/sdio_f0_writeb
sdio_readw/sdio_writew
sdio_readl/sdio_writel
sdio_readsb
sdio_memcpy_fromio/sdio_memcpy_toio

And directly issues the following command:

         mmc_dat.flags = write ? MMC_DATA_WRITE : MMC_DATA_READ;
         mmc_cmd.opcode = SD_IO_RW_EXTENDED;
         mmc_cmd.arg = write ? 1<<31 : 0;        /* write flag  */
         mmc_cmd.arg |= (fn & 0x7) << 28;        /* SDIO func num */
         mmc_cmd.arg |= 1<<27;                   /* block mode */
         /* for function 1 the addr will be incremented */
         mmc_cmd.arg |= (fn == 1) ? 1<<26 : 0;
         mmc_cmd.flags = MMC_RSP_SPI_R5 | MMC_RSP_R5 | MMC_CMD_ADTC;

I do not know if the busy wait is necessary for all
of these, but the hack in the android kernel code,
which inserts calls to a wait_card_busy function directly
into: drivers/net/wireless/brcm80211/brcmfmac/bcmsdh.c

Does so for all of these.

 > Or more interesting, which response types do
> these commands expect?
> I don't think this is a sunxi specific issue, I have seen similar
> issues for other host controllers.

Agreed, recent dw-mmc patches address the same issue, also involving
broadcom sdio wifi chips.

> I am thinking that perhaps this should be managed by the mmc core
> instead of local hacks to sunxi. Potentially we could make the core to
> invoke the already existing host_ops->card_busy() callback when
> needed...

I'm fine with solving this either way, implementing host_ops->card_busy()
for sunxi is easy, and if the core os modified to call that function
before issue sdio io ops (which seems to be the common thing here),
then that indeed is better then having the sunxi code always do
the busy check.

> Within this context, could I ask whether you controller supports IRQ
> based HW-busy detection? Or you need polling of the status register?

I'm afraid that we need to poll the status register. I've been unable
to find an irq flag corresponding to this.

Regards,

Hans


>> This commit fixes this, thereby fixing the wifi reliability issues on
>> the Cubietruck and other sunxi boards using sdio wifi.
>>
>> Reported-by: Eugene K <sigintmailru at gmail.com>
>> Suggested-by: Eugene K <sigintmailru at gmail.com>
>> Cc: Eugene K <sigintmailru at gmail.com>
>> Cc: Arend van Spriel <arend at broadcom.com>
>> Signed-off-by: Hans de Goede <hdegoede at redhat.com>
>> ---
>> Changes in v2:
>> -Properly accredit Eugene K for coming up with the fix for this
>> ---
>>   drivers/mmc/host/sunxi-mmc.c | 32 ++++++++++++++++++++++++++++++++
>>   1 file changed, 32 insertions(+)
>>
>> diff --git a/drivers/mmc/host/sunxi-mmc.c b/drivers/mmc/host/sunxi-mmc.c
>> index 4d3e1ff..daa90b7 100644
>> --- a/drivers/mmc/host/sunxi-mmc.c
>> +++ b/drivers/mmc/host/sunxi-mmc.c
>> @@ -289,6 +289,24 @@ static int sunxi_mmc_init_host(struct mmc_host *mmc)
>>          return 0;
>>   }
>>
>> +/* Wait for card to report ready before starting a new cmd */
>> +static int sunxi_mmc_wait_card_ready(struct sunxi_mmc_host *host)
>> +{
>> +       unsigned long expire = jiffies + msecs_to_jiffies(500);
>> +       u32 rval;
>> +
>> +       do {
>> +               rval = mmc_readl(host, REG_STAS);
>> +       } while (time_before(jiffies, expire) && (rval & SDXC_CARD_DATA_BUSY));
>> +
>> +       if (rval & SDXC_CARD_DATA_BUSY) {
>> +               dev_err(mmc_dev(host->mmc), "Error R1 ready timeout\n");
>> +               return -EIO;
>> +       }
>> +
>> +       return 0;
>> +}
>> +
>>   static void sunxi_mmc_init_idma_des(struct sunxi_mmc_host *host,
>>                                      struct mmc_data *data)
>>   {
>> @@ -383,6 +401,8 @@ static void sunxi_mmc_send_manual_stop(struct sunxi_mmc_host *host,
>>          u32 arg, cmd_val, ri;
>>          unsigned long expire = jiffies + msecs_to_jiffies(1000);
>>
>> +       sunxi_mmc_wait_card_ready(host);
>> +
>>          cmd_val = SDXC_START | SDXC_RESP_EXPIRE |
>>                    SDXC_STOP_ABORT_CMD | SDXC_CHECK_RESPONSE_CRC;
>>
>> @@ -597,6 +617,11 @@ static int sunxi_mmc_oclk_onoff(struct sunxi_mmc_host *host, u32 oclk_en)
>>   {
>>          unsigned long expire = jiffies + msecs_to_jiffies(250);
>>          u32 rval;
>> +       int ret;
>> +
>> +       ret = sunxi_mmc_wait_card_ready(host);
>> +       if (ret)
>> +               return ret;
>>
>>          rval = mmc_readl(host, REG_CLKCR);
>>          rval &= ~(SDXC_CARD_CLOCK_ON | SDXC_LOW_POWER_ON);
>> @@ -785,6 +810,13 @@ static void sunxi_mmc_request(struct mmc_host *mmc, struct mmc_request *mrq)
>>                  return;
>>          }
>>
>> +       ret = sunxi_mmc_wait_card_ready(host);
>> +       if (ret) {
>> +               mrq->cmd->error = ret;
>> +               mmc_request_done(mmc, mrq);
>> +               return;
>> +       }
>> +
>>          if (data) {
>>                  ret = sunxi_mmc_map_dma(host, data);
>>                  if (ret < 0) {
>> --
>> 2.4.3
>>
>
> Kind regards
> Uffe
>


From laurent.pinchart at ideasonboard.com  Sat Aug  1 02:11:47 2015
From: laurent.pinchart at ideasonboard.com (Laurent Pinchart)
Date: Sat, 01 Aug 2015 12:11:47 +0300
Subject: [PATCH] media: atmel-isi: parse the DT parameters for vsync/hsync
 polarity
In-Reply-To: <1438338812-22329-1-git-send-email-josh.wu@atmel.com>
References: <1438338812-22329-1-git-send-email-josh.wu@atmel.com>
Message-ID: <1896672.nsMcFlgNH5@avalon>

Hi Josh,

Thank you for the patch.

On Friday 31 July 2015 18:33:32 Josh Wu wrote:
> This patch will get the DT parameters of vsync/hsync polarity, and pass to
> the platform data.
> 
> Also add a debug information for test purpose.
> 
> Signed-off-by: Josh Wu <josh.wu at atmel.com>
> ---
> 
>  drivers/media/platform/soc_camera/atmel-isi.c | 10 ++++++++++
>  1 file changed, 10 insertions(+)
> 
> diff --git a/drivers/media/platform/soc_camera/atmel-isi.c
> b/drivers/media/platform/soc_camera/atmel-isi.c index fe9247a..a7de55c
> 100644
> --- a/drivers/media/platform/soc_camera/atmel-isi.c
> +++ b/drivers/media/platform/soc_camera/atmel-isi.c
> @@ -811,6 +811,11 @@ static int isi_camera_set_bus_param(struct
> soc_camera_device *icd) if (common_flags & V4L2_MBUS_PCLK_SAMPLE_FALLING)
>  		cfg1 |= ISI_CFG1_PIXCLK_POL_ACTIVE_FALLING;
> 
> +	dev_dbg(icd->parent, "vsync is active %s, hsyc is active %s, pix clock is
> sampling %s\n",

s/hsyc/hsync/

I'd write it as "vsync active %s, hsync active %s, sampling on pix clock %s 
edge\n" with "falling" and "rising" instead of "fall" and "rise".

> +		common_flags & V4L2_MBUS_VSYNC_ACTIVE_LOW ? "low" : "high",
> +		common_flags & V4L2_MBUS_HSYNC_ACTIVE_LOW ? "low" : "high",
> +		common_flags & V4L2_MBUS_PCLK_SAMPLE_FALLING ? "fall" : "rise");
> +
>  	if (isi->pdata.has_emb_sync)
>  		cfg1 |= ISI_CFG1_EMB_SYNC;
>  	if (isi->pdata.full_mode)
> @@ -898,6 +903,11 @@ static int atmel_isi_probe_dt(struct atmel_isi *isi,
>  		goto err_probe_dt;
>  	}
> 
> +	if (ep.bus.parallel.flags & V4L2_MBUS_HSYNC_ACTIVE_LOW)
> +		isi->pdata.hsync_act_low = true;
> +	if (ep.bus.parallel.flags & V4L2_MBUS_VSYNC_ACTIVE_LOW)
> +		isi->pdata.vsync_act_low = true;

While you're at it, how about setting has_emb_sync based on ep.bus_type and 
pclk_act_falling from flags & V4L2_MBUS_PCLK_SAMPLE_FALLING ?

>  err_probe_dt:
>  	of_node_put(np);

-- 
Regards,

Laurent Pinchart



From yalin.wang2010 at gmail.com  Sat Aug  1 03:00:23 2015
From: yalin.wang2010 at gmail.com (yalin wang)
Date: Sat, 1 Aug 2015 18:00:23 +0800
Subject: [RFC] arm64:change jump_label to use branch instruction,
 not use NOP instr
In-Reply-To: <20150731101432.GA29497@arm.com>
References: <94E2034B-9DE4-4ADF-8B2F-197D38A363CF@gmail.com>
 <20150731075259.GR25159@twins.programming.kicks-ass.net>
 <8F6A71B0-C7DB-4505-BEE2-79967FC91A8F@gmail.com>
 <20150731093355.GU25159@twins.programming.kicks-ass.net>
 <20150731101432.GA29497@arm.com>
Message-ID: <33D3C3BF-C8E7-4423-8062-DA83EF826872@gmail.com>


> ? 2015?7?31??18:14?Will Deacon <will.deacon at arm.com> ???
> 
> On Fri, Jul 31, 2015 at 10:33:55AM +0100, Peter Zijlstra wrote:
>> On Fri, Jul 31, 2015 at 05:25:02PM +0800, yalin wang wrote:
>>>> On Jul 31, 2015, at 15:52, Peter Zijlstra <peterz at infradead.org> wrote:
>>>> On Fri, Jul 31, 2015 at 03:41:37PM +0800, yalin wang wrote:
>>>>> This change a little arch_static_branch(), use b . + 4 for false
>>>>> return, why? According to aarch64 TRM, if both source and dest
>>>>> instr are branch instr, can patch the instr directly, don't need
>>>>> all cpu to do ISB for sync, this means we can call
>>>>> aarch64_insn_patch_text_nosync() during patch_text(),
>>>>> will improve the performance when change a static_key.
>>>> 
>>>> This doesn't parse.. What?
>>>> 
>>>> Also, this conflicts with the jump label patches I've got.
>>> 
>>> this is arch depend , you can see aarch64_insn_patch_text( ) for more info,
>>> if aarch64_insn_hotpatch_safe() is true, will patch the text directly.
>> 
>> So I patched all arches, including aargh64.
>> 
>>> what is your git branch base? i make the patch based on linux-next branch,
>>> maybe a little delay than yours , could you share your branch git address?
>>> i can make a new based on yours .
>> 
>> https://git.kernel.org/cgit/linux/kernel/git/peterz/queue.git/log/?h=locking/jump_label
>> 
>> Don't actually use that branch for anything permanent, this is throw-away
>> git stuff.
>> 
>> But you're replacing a NOP with an unconditional branch to the next
>> instruction? I suppose I'll leave that to Will and co.. I just had
>> trouble understanding your Changelog -- also I was very much not awake
>> yet.
> 
> Optimising the (hopefully rare) patching operation but having a potential
> impact on the runtime code (assumedly a hotpath) seems completely backwards
> to me.
> 
> Yalin, do you have a reason for this change or did you just notice that
> paragraph in the architecture and decide to apply it here?
> 
in fact, i don?t have any special reason to must change like this, just found we can do this when i read
AARCH64 TRM,  then i make this patch :)


> Even then, I think there are technical issues with the proposal, since
> we could get spurious execution of the old code without explicitsynchronisation (see the kick_all_cpus_sync() call in
> aarch64_insn_patch_text).
i think jump_label code don?t have responsibility to make sure the sync with other cores,
if it is not safe to execute old and new patch code on different cores, the caller should 
do this sync, he can cancel  a work_struct  /  cu_sync()  or some thing like this,
i have a look at the software implementation (!HAVE_JUMP_LABEL) ,
it also doesn?t do any sync, just atomic_inc()  and return directly .

if the ARCH technology concern is not a matter, i think we can apply it  :) 

in fact , i have another solution for jump_label, i see we calculate the jump instruction every time ,
why  not let the compiler do this during compile time , during run time , we just need swap it with NOP 
instruction,  and by this method, we don?t need store target address in struct jump_entry ,
it can save some space ,

this is my patch for this method :
?
yalin at ubuntu:~/linux-next$ git diff
diff --git a/arch/arm64/include/asm/jump_label.h b/arch/arm64/include/asm/jump_label.h
index 1b5e0e8..c040cd3 100644
--- a/arch/arm64/include/asm/jump_label.h
+++ b/arch/arm64/include/asm/jump_label.h
@@ -28,16 +28,17 @@
 
 static __always_inline bool arch_static_branch(struct static_key *key, bool branch)
 {
-       asm goto("1: nop\n\t"
+       asm goto("1: b %l[l_no]\n\t"
                 ".pushsection __jump_table,  \"aw\"\n\t"
                 ".align 3\n\t"
-                ".quad 1b, %l[l_yes], %c0\n\t"
+                ".word %c0 - 1b\n\t"
+                "nop\n\t"
+                ".quad %c0\n\t"
                 ".popsection\n\t"
-                :  :  "i"(&((char *)key)[branch]) :  : l_yes);
-
-       return false;
-l_yes:
+                :  :  "i"(&((char *)key)[branch]) :  : l_no);
        return true;
+l_no:
+       return false;
 }
 
 static __always_inline bool arch_static_branch_jump(struct static_key *key, bool branch)
@@ -45,10 +46,11 @@ static __always_inline bool arch_static_branch_jump(struct static_key *key, bool
        asm goto("1: b %l[l_yes]\n\t"
                 ".pushsection __jump_table,  \"aw\"\n\t"
                 ".align 3\n\t"
-                ".quad 1b, %l[l_yes], %c0\n\t"
+                ".word %c0 - 1b\n\t"
+                "nop\n\t"
+                ".quad %c0\n\t"
                 ".popsection\n\t"
                 :  :  "i"(&((char *)key)[branch]) :  : l_yes);
-
        return false;
 l_yes:
        return true;
@@ -57,8 +59,8 @@ l_yes:
 typedef u64 jump_label_t;
 
 struct jump_entry {
-       jump_label_t code;
-       jump_label_t target;
+       s32 offset;
+       u32 insn;
        jump_label_t key;
...skipping...
@@ -45,10 +46,11 @@ static __always_inline bool arch_static_branch_jump(struct static_key *key, bool
        asm goto("1: b %l[l_yes]\n\t"
                 ".pushsection __jump_table,  \"aw\"\n\t"
                 ".align 3\n\t"
-                ".quad 1b, %l[l_yes], %c0\n\t"
+                ".word %c0 - 1b\n\t"
+                "nop\n\t"
+                ".quad %c0\n\t"
                 ".popsection\n\t"
                 :  :  "i"(&((char *)key)[branch]) :  : l_yes);
-
        return false;
 l_yes:
        return true;
@@ -57,8 +59,8 @@ l_yes:
 typedef u64 jump_label_t;
 
 struct jump_entry {
-       jump_label_t code;
-       jump_label_t target;
+       s32 offset;
+       u32 insn;
        jump_label_t key;
 };
 
diff --git a/arch/arm64/kernel/jump_label.c b/arch/arm64/kernel/jump_label.c
index c2dd1ad..2e0e7bc 100644
--- a/arch/arm64/kernel/jump_label.c
+++ b/arch/arm64/kernel/jump_label.c
@@ -25,17 +25,10 @@
 void arch_jump_label_transform(struct jump_entry *entry,
                               enum jump_label_type type)
 {
-       void *addr = (void *)entry->code;
-       u32 insn;
-
-       if (type == JUMP_LABEL_JMP) {
-               insn = aarch64_insn_gen_branch_imm(entry->code,
-                                                  entry->target,
-                                                  AARCH64_INSN_BRANCH_NOLINK);
-       } else {
-               insn = aarch64_insn_gen_nop();
-       }
-
+       void *addr = (void *)entry->key - entry->offset;
+       u32 old = *(u32*)addr;
+       u32 insn = entry->insn;
+       entry->insn = old;
        aarch64_insn_patch_text(&addr, &insn, 1);
 }
 --- 
i  just store a offset relative *key address and store a NOP in jump_entry,
when need change a static_key,  we just need swap the jump insert and NOP instr .
the jump_entry is shrieked to u64[2]   , save some space .

Thanks








From kishon at ti.com  Sat Aug  1 03:24:27 2015
From: kishon at ti.com (Kishon Vijay Abraham I)
Date: Sat, 1 Aug 2015 15:54:27 +0530
Subject: [PATCH 1/3] phy-sun4i-usb: Add missing EXPORT_SYMBOL for
 sun4i_usb_phy_set_squelch_detect
In-Reply-To: <1438329702-10365-2-git-send-email-hdegoede@redhat.com>
References: <1438329702-10365-1-git-send-email-hdegoede@redhat.com>
 <1438329702-10365-2-git-send-email-hdegoede@redhat.com>
Message-ID: <55BC9E5B.7010201@ti.com>

Hi,

On Friday 31 July 2015 01:31 PM, Hans de Goede wrote:
> sun4i_usb_phy_set_squelch_detect is used by other code, which may be built
> as a module, so it should be exported.
> 
> Signed-off-by: Hans de Goede <hdegoede at redhat.com>
> ---
> Changes in v6:
> -New patch in v6 of the sunxi musb support series
> ---
>  drivers/phy/phy-sun4i-usb.c | 1 +
>  1 file changed, 1 insertion(+)
> 
> diff --git a/drivers/phy/phy-sun4i-usb.c b/drivers/phy/phy-sun4i-usb.c
> index 5138843..d514a9b 100644
> --- a/drivers/phy/phy-sun4i-usb.c
> +++ b/drivers/phy/phy-sun4i-usb.c
> @@ -347,6 +347,7 @@ void sun4i_usb_phy_set_squelch_detect(struct phy *_phy, bool enabled)
>  
>  	sun4i_usb_phy_write(phy, PHY_SQUELCH_DETECT, enabled ? 0 : 2, 2);
>  }
> +EXPORT_SYMBOL(sun4i_usb_phy_set_squelch_detect);

changed it to EXPORT_SYMBOL_GPL and merged it.

Thanks
Kishon


From viresh.kumar at linaro.org  Sat Aug  1 03:48:25 2015
From: viresh.kumar at linaro.org (Viresh Kumar)
Date: Sat, 1 Aug 2015 16:18:25 +0530
Subject: [PATCH v3 2/5] ARM: dts: Exynos4x12: add CPU OPP and regulator
 supply property
In-Reply-To: <1438368557-2352-3-git-send-email-b.zolnierkie@samsung.com>
References: <1438368557-2352-1-git-send-email-b.zolnierkie@samsung.com>
 <1438368557-2352-3-git-send-email-b.zolnierkie@samsung.com>
Message-ID: <20150801104825.GF899@linux>

On 31-07-15, 20:49, Bartlomiej Zolnierkiewicz wrote:
> For Exynos4x12 platforms, add CPU operating points (using
> opp-v2 bindings) and CPU regulator supply properties for
> migrating from Exynos specific cpufreq driver to using
> generic cpufreq driver.
> 
> Based on the earlier work by Thomas Abraham.
> 
> Cc: Kukjin Kim <kgene.kim at samsung.com>
> Cc: Doug Anderson <dianders at chromium.org>
> Cc: Andreas Faerber <afaerber at suse.de>
> Cc: Thomas Abraham <thomas.ab at samsung.com>
> Reviewed-by: Javier Martinez Canillas <javier at osg.samsung.com>
> Reviewed-by: Krzysztof Kozlowski <k.kozlowski at samsung.com>
> Signed-off-by: Bartlomiej Zolnierkiewicz <b.zolnierkie at samsung.com>
> ---
>  arch/arm/boot/dts/exynos4212.dtsi               | 81 ++++++++++++++++++++++++
>  arch/arm/boot/dts/exynos4412-odroid-common.dtsi |  4 ++
>  arch/arm/boot/dts/exynos4412-origen.dts         |  4 ++
>  arch/arm/boot/dts/exynos4412-trats2.dts         |  4 ++
>  arch/arm/boot/dts/exynos4412.dtsi               | 83 +++++++++++++++++++++++++
>  5 files changed, 176 insertions(+)
> 
> diff --git a/arch/arm/boot/dts/exynos4212.dtsi b/arch/arm/boot/dts/exynos4212.dtsi
> index d9c8efee..5389011 100644
> --- a/arch/arm/boot/dts/exynos4212.dtsi
> +++ b/arch/arm/boot/dts/exynos4212.dtsi
> @@ -30,6 +30,9 @@
>  			device_type = "cpu";
>  			compatible = "arm,cortex-a9";
>  			reg = <0xA00>;
> +			clocks = <&clock CLK_ARM_CLK>;
> +			clock-names = "cpu";
> +			operating-points-v2 = <&cpu0_opp_table>;
>  			cooling-min-level = <13>;
>  			cooling-max-level = <7>;
>  			#cooling-cells = <2>; /* min followed by max */
> @@ -39,6 +42,84 @@
>  			device_type = "cpu";
>  			compatible = "arm,cortex-a9";
>  			reg = <0xA01>;
> +			operating-points-v2 = <&cpu0_opp_table>;
> +		};
> +	};
> +
> +	cpu0_opp_table: opp_table0 {
> +		compatible = "operating-points-v2";
> +		opp-shared;
> +
> +		opp00 {
> +			opp-hz = /bits/ 64 <200000000>;
> +			opp-microvolt = <900000>;
> +			clock-latency-ns = <200000>;
> +		};
> +		opp01 {
> +			opp-hz = /bits/ 64 <300000000>;
> +			opp-microvolt = <900000>;
> +			clock-latency-ns = <200000>;
> +		};
> +		opp02 {
> +			opp-hz = /bits/ 64 <400000000>;
> +			opp-microvolt = <925000>;
> +			clock-latency-ns = <200000>;
> +		};
> +		opp03 {
> +			opp-hz = /bits/ 64 <500000000>;
> +			opp-microvolt = <950000>;
> +			clock-latency-ns = <200000>;
> +		};
> +		opp04 {
> +			opp-hz = /bits/ 64 <600000000>;
> +			opp-microvolt = <975000>;
> +			clock-latency-ns = <200000>;
> +		};
> +		opp05 {
> +			opp-hz = /bits/ 64 <700000000>;
> +			opp-microvolt = <987500>;
> +			clock-latency-ns = <200000>;
> +		};
> +		opp06 {
> +			opp-hz = /bits/ 64 <800000000>;
> +			opp-microvolt = <1000000>;
> +			clock-latency-ns = <200000>;
> +		};
> +		opp07 {
> +			opp-hz = /bits/ 64 <900000000>;
> +			opp-microvolt = <1037500>;
> +			clock-latency-ns = <200000>;
> +		};
> +		opp08 {
> +			opp-hz = /bits/ 64 <1000000000>;
> +			opp-microvolt = <1087500>;
> +			clock-latency-ns = <200000>;
> +		};
> +		opp09 {
> +			opp-hz = /bits/ 64 <1100000000>;
> +			opp-microvolt = <1137500>;
> +			clock-latency-ns = <200000>;
> +		};
> +		opp10 {
> +			opp-hz = /bits/ 64 <1200000000>;
> +			opp-microvolt = <1187500>;
> +			clock-latency-ns = <200000>;
> +		};
> +		opp11 {
> +			opp-hz = /bits/ 64 <1300000000>;
> +			opp-microvolt = <1250000>;
> +			clock-latency-ns = <200000>;
> +		};
> +		opp12 {
> +			opp-hz = /bits/ 64 <1400000000>;
> +			opp-microvolt = <1287500>;
> +			clock-latency-ns = <200000>;
> +		};
> +		opp13 {
> +			opp-hz = /bits/ 64 <1500000000>;
> +			opp-microvolt = <1350000>;
> +			clock-latency-ns = <200000>;
> +			turbo-mode;
>  		};
>  	};
>  };

I'm lovin' it :)

Acked-by: Viresh Kumar <viresh.kumar at linaro.org>

-- 
viresh


From viresh.kumar at linaro.org  Sat Aug  1 03:50:13 2015
From: viresh.kumar at linaro.org (Viresh Kumar)
Date: Sat, 1 Aug 2015 16:20:13 +0530
Subject: [PATCH v3 4/5] cpufreq: exynos: remove Exynos4x12 specific
 cpufreq driver support
In-Reply-To: <1438368557-2352-5-git-send-email-b.zolnierkie@samsung.com>
References: <1438368557-2352-1-git-send-email-b.zolnierkie@samsung.com>
 <1438368557-2352-5-git-send-email-b.zolnierkie@samsung.com>
Message-ID: <20150801105013.GG899@linux>

Cc'ing Rafael, please keep him in loop for such patches and better use
get_maintainers to get the cc list automatically.

On 31-07-15, 20:49, Bartlomiej Zolnierkiewicz wrote:
> Exynos4x12 based platforms have switched over to use generic
> cpufreq driver for cpufreq functionality.  So the Exynos
> specific cpufreq support for these platforms can be removed.
> 
> Also once Exynos4x12 based platforms support have been removed
> the shared exynos-cpufreq driver is no longer needed and can
> be deleted.
> 
> Based on the earlier work by Thomas Abraham.
> 
> Cc: Viresh Kumar <viresh.kumar at linaro.org>
> Cc: Thomas Abraham <thomas.ab at samsung.com>
> Reviewed-by: Javier Martinez Canillas <javier at osg.samsung.com>
> Reviewed-by: Krzysztof Kozlowski <k.kozlowski at samsung.com>
> Signed-off-by: Bartlomiej Zolnierkiewicz <b.zolnierkie at samsung.com>
> ---
>  drivers/cpufreq/Kconfig.arm          |  38 ------
>  drivers/cpufreq/Makefile             |   2 -
>  drivers/cpufreq/exynos-cpufreq.c     | 236 -----------------------------------
>  drivers/cpufreq/exynos-cpufreq.h     |  72 -----------
>  drivers/cpufreq/exynos4x12-cpufreq.c | 236 -----------------------------------
>  5 files changed, 584 deletions(-)
>  delete mode 100644 drivers/cpufreq/exynos-cpufreq.c
>  delete mode 100644 drivers/cpufreq/exynos-cpufreq.h
>  delete mode 100644 drivers/cpufreq/exynos4x12-cpufreq.c

Acked-by: Viresh Kumar <viresh.kumar at linaro.org>

-- 
viresh


From viresh.kumar at linaro.org  Sat Aug  1 04:15:37 2015
From: viresh.kumar at linaro.org (Viresh Kumar)
Date: Sat, 1 Aug 2015 16:45:37 +0530
Subject: [PATCH v3 5/5] cpufreq: remove no longer needed
 CPU_FREQ_BOOST_SW config option
In-Reply-To: <1438368557-2352-6-git-send-email-b.zolnierkie@samsung.com>
References: <1438368557-2352-1-git-send-email-b.zolnierkie@samsung.com>
 <1438368557-2352-6-git-send-email-b.zolnierkie@samsung.com>
Message-ID: <20150801111537.GH899@linux>

On 31-07-15, 20:49, Bartlomiej Zolnierkiewicz wrote:
> Remove no longer needed CPU_FREQ_BOOST_SW config option.
> 
> As a result scaling_boost_freqs sysfs attribute is available
> when cpufreq-dt driver is used and boost support is enabled.
> 
> Cc: Viresh Kumar <viresh.kumar at linaro.org>
> Cc: Thomas Abraham <thomas.ab at samsung.com>
> Cc: Javier Martinez Canillas <javier at osg.samsung.com>
> Cc: Krzysztof Kozlowski <k.kozlowski at samsung.com>
> Signed-off-by: Bartlomiej Zolnierkiewicz <b.zolnierkie at samsung.com>
> ---
>  drivers/cpufreq/Kconfig      | 4 ----
>  drivers/cpufreq/freq_table.c | 2 --
>  2 files changed, 6 deletions(-)
> 
> diff --git a/drivers/cpufreq/Kconfig b/drivers/cpufreq/Kconfig
> index bf6d596..de00a52 100644
> --- a/drivers/cpufreq/Kconfig
> +++ b/drivers/cpufreq/Kconfig
> @@ -21,10 +21,6 @@ if CPU_FREQ
>  config CPU_FREQ_GOV_COMMON
>  	bool
>  
> -config CPU_FREQ_BOOST_SW
> -	bool
> -	depends on THERMAL
> -
>  config CPU_FREQ_STAT
>  	tristate "CPU frequency translation statistics"
>  	default y
> diff --git a/drivers/cpufreq/freq_table.c b/drivers/cpufreq/freq_table.c
> index a8f1daf..4c5de5b 100644
> --- a/drivers/cpufreq/freq_table.c
> +++ b/drivers/cpufreq/freq_table.c
> @@ -293,9 +293,7 @@ EXPORT_SYMBOL_GPL(cpufreq_freq_attr_scaling_boost_freqs);
>  
>  struct freq_attr *cpufreq_generic_attr[] = {
>  	&cpufreq_freq_attr_scaling_available_freqs,
> -#ifdef CONFIG_CPU_FREQ_BOOST_SW
>  	&cpufreq_freq_attr_scaling_boost_freqs,
> -#endif
>  	NULL,
>  };
>  EXPORT_SYMBOL_GPL(cpufreq_generic_attr);

So, this will start appearing for all platforms that use cpufreq_generic_attr
and that may not be the right thing. We may only want to show boost frequencies
only if the driver supports it.

@Rafael: What do you say?

-- 
viresh


From viresh.kumar at linaro.org  Sat Aug  1 04:17:21 2015
From: viresh.kumar at linaro.org (Viresh Kumar)
Date: Sat, 1 Aug 2015 16:47:21 +0530
Subject: [PATCH v3 3/5] ARM: Exynos: switch to using generic cpufreq
 driver for Exynos4x12
In-Reply-To: <1438368557-2352-4-git-send-email-b.zolnierkie@samsung.com>
References: <1438368557-2352-1-git-send-email-b.zolnierkie@samsung.com>
 <1438368557-2352-4-git-send-email-b.zolnierkie@samsung.com>
Message-ID: <20150801111721.GI899@linux>

On 31-07-15, 20:49, Bartlomiej Zolnierkiewicz wrote:
> diff --git a/drivers/cpufreq/Kconfig b/drivers/cpufreq/Kconfig
> index 659879a..bf6d596 100644
> --- a/drivers/cpufreq/Kconfig
> +++ b/drivers/cpufreq/Kconfig
> @@ -191,6 +191,7 @@ config CPUFREQ_DT
>  	# if CPU_THERMAL is on and THERMAL=m, CPUFREQ_DT cannot be =y:
>  	depends on !CPU_THERMAL || THERMAL
>  	select PM_OPP
> +	select EXYNOS_THERMAL if ARCH_EXYNOS
>  	help
>  	  This adds a generic DT based cpufreq driver for frequency management.
>  	  It supports both uniprocessor (UP) and symmetric multiprocessor (SMP)

No, we shouldn't pollute generic Kconfig options with platform specific stuff.
Why don't you enable thermal in your .config?

-- 
viresh


From viresh.kumar at linaro.org  Sat Aug  1 04:36:02 2015
From: viresh.kumar at linaro.org (Viresh Kumar)
Date: Sat, 1 Aug 2015 17:06:02 +0530
Subject: [PATCH v4 2/2] dt: power: st: Provide bindings for ST's OPPs
In-Reply-To: <20150731163715.GV3159@codeaurora.org>
References: <1438010430-5802-1-git-send-email-lee.jones@linaro.org>
 <1438010430-5802-2-git-send-email-lee.jones@linaro.org>
 <20150728022936.GB1229@linux>
 <20150728225510.GB3159@codeaurora.org> <20150729081403.GH2284@x1>
 <20150729221526.GE3159@codeaurora.org> <20150730084634.GD9319@x1>
 <CAL_JsqKQLQ15qSt95zBZykzzPhcUrtZzhk29a76n+r_3719AiA@mail.gmail.com>
 <20150731163715.GV3159@codeaurora.org>
Message-ID: <20150801113602.GM899@linux>

On 31-07-15, 09:37, Stephen Boyd wrote:
> Do we need vendor specific properties for that though?

Sorry Lee :), but this is exactly why I wanted this thread to exist. We must and
should do this in a generic enough way.

-- 
viresh


From heiko at sntech.de  Sat Aug  1 05:35:18 2015
From: heiko at sntech.de (Heiko =?ISO-8859-1?Q?St=FCbner?=)
Date: Sat, 01 Aug 2015 14:35:18 +0200
Subject: [PATCH 1/2] ARM: dts: rockchip: reserve unusable memory region on
 rk3288
Message-ID: <15143985.aGzb1oeyb9@diego>

The rk3288 has problems accessing the memory region 0xfe000000~0xff000000.
So block off the affected region to prevent its use.

Tested on 4GB Veyron Minnie and 2GB Veyron Jerry devices.

Signed-off-by: Heiko Stuebner <heiko at sntech.de>
---
 arch/arm/boot/dts/rk3288.dtsi | 10 ++++++++++
 1 file changed, 10 insertions(+)

diff --git a/arch/arm/boot/dts/rk3288.dtsi b/arch/arm/boot/dts/rk3288.dtsi
index 2db91c9..19766af 100644
--- a/arch/arm/boot/dts/rk3288.dtsi
+++ b/arch/arm/boot/dts/rk3288.dtsi
@@ -169,6 +169,16 @@
 		};
 	};
 
+	reserved-memory {
+		#address-cells = <1>;
+		#size-cells = <1>;
+		ranges;
+
+		unusable at fe000000 {
+			reg = <0xfe000000 0x1000000>;
+		};
+	};
+
 	xin24m: oscillator {
 		compatible = "fixed-clock";
 		clock-frequency = <24000000>;
-- 
2.1.4




From heiko at sntech.de  Sat Aug  1 05:36:33 2015
From: heiko at sntech.de (Heiko =?ISO-8859-1?Q?St=FCbner?=)
Date: Sat, 01 Aug 2015 14:36:33 +0200
Subject: [PATCH 2/2] ARM: dts: rockchip: add veyron-minnie board
In-Reply-To: <15143985.aGzb1oeyb9@diego>
References: <15143985.aGzb1oeyb9@diego>
Message-ID: <46403642.3tph1CqEDH@diego>

From: Alexandru M Stan <amstan at chromium.org>

Also known as the Asus Chromebook Flip.

Signed-off-by: Alexandru M Stan <amstan at chromium.org>
Signed-off-by: Heiko Stuebner <heiko at sntech.de>
---
 Documentation/devicetree/bindings/arm/rockchip.txt |   7 +
 arch/arm/boot/dts/Makefile                         |   1 +
 arch/arm/boot/dts/rk3288-veyron-minnie.dts         | 253 +++++++++++++++++++++
 3 files changed, 261 insertions(+)
 create mode 100644 arch/arm/boot/dts/rk3288-veyron-minnie.dts

diff --git a/Documentation/devicetree/bindings/arm/rockchip.txt b/Documentation/devicetree/bindings/arm/rockchip.txt
index c7411cc..af58cd7 100644
--- a/Documentation/devicetree/bindings/arm/rockchip.txt
+++ b/Documentation/devicetree/bindings/arm/rockchip.txt
@@ -38,6 +38,13 @@ Rockchip platforms device tree bindings
 		     "google,veyron-jerry-rev3", "google,veyron-jerry",
 		     "google,veyron", "rockchip,rk3288";
 
+- Google Minnie (Asus Chromebook Flip C100P):
+    Required root node properties:
+      - compatible = "google,veyron-minnie-rev4", "google,veyron-minnie-rev3",
+		     "google,veyron-minnie-rev2", "google,veyron-minnie-rev1",
+		     "google,veyron-minnie-rev0", "google,veyron-minnie",
+		     "google,veyron", "rockchip,rk3288";
+
 - Google Pinky (dev-board):
     Required root node properties:
       - compatible = "google,veyron-pinky-rev2", "google,veyron-pinky",
diff --git a/arch/arm/boot/dts/Makefile b/arch/arm/boot/dts/Makefile
index 7017d8e..7805a65 100644
--- a/arch/arm/boot/dts/Makefile
+++ b/arch/arm/boot/dts/Makefile
@@ -491,6 +491,7 @@ dtb-$(CONFIG_ARCH_ROCKCHIP) += \
 	rk3288-firefly.dtb \
 	rk3288-r89.dtb \
 	rk3288-veyron-jerry.dtb \
+	rk3288-veyron-minnie.dtb \
 	rk3288-veyron-pinky.dtb \
 	rk3288-veyron-speedy.dtb
 dtb-$(CONFIG_ARCH_S3C24XX) += \
diff --git a/arch/arm/boot/dts/rk3288-veyron-minnie.dts b/arch/arm/boot/dts/rk3288-veyron-minnie.dts
new file mode 100644
index 0000000..4ce1ec9
--- /dev/null
+++ b/arch/arm/boot/dts/rk3288-veyron-minnie.dts
@@ -0,0 +1,253 @@
+/*
+ * Google Veyron Minnie Rev 0+ board device tree source
+ *
+ * Copyright 2015 Google, Inc
+ *
+ * This file is dual-licensed: you can use it either under the terms
+ * of the GPL or the X11 license, at your option. Note that this dual
+ * licensing only applies to this file, and not this project as a
+ * whole.
+ *
+ *  a) This file is free software; you can redistribute it and/or
+ *     modify it under the terms of the GNU General Public License as
+ *     published by the Free Software Foundation; either version 2 of the
+ *     License, or (at your option) any later version.
+ *
+ *     This file is distributed in the hope that it will be useful,
+ *     but WITHOUT ANY WARRANTY; without even the implied warranty of
+ *     MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ *     GNU General Public License for more details.
+ *
+ *  Or, alternatively,
+ *
+ *  b) Permission is hereby granted, free of charge, to any person
+ *     obtaining a copy of this software and associated documentation
+ *     files (the "Software"), to deal in the Software without
+ *     restriction, including without limitation the rights to use,
+ *     copy, modify, merge, publish, distribute, sublicense, and/or
+ *     sell copies of the Software, and to permit persons to whom the
+ *     Software is furnished to do so, subject to the following
+ *     conditions:
+ *
+ *     The above copyright notice and this permission notice shall be
+ *     included in all copies or substantial portions of the Software.
+ *
+ *     THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
+ *     EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES
+ *     OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
+ *     NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT
+ *     HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY,
+ *     WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
+ *     FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR
+ *     OTHER DEALINGS IN THE SOFTWARE.
+ */
+
+/dts-v1/;
+#include "rk3288-veyron-chromebook.dtsi"
+
+/ {
+	model = "Google Minnie";
+	compatible = "google,veyron-minnie-rev4", "google,veyron-minnie-rev3",
+		     "google,veyron-minnie-rev2", "google,veyron-minnie-rev1",
+		     "google,veyron-minnie-rev0", "google,veyron-minnie",
+		     "google,veyron", "rockchip,rk3288";
+
+	backlight_regulator: backlight-regulator {
+		compatible = "regulator-fixed";
+		enable-active-high;
+		gpio = <&gpio2 12 GPIO_ACTIVE_HIGH>;
+		pinctrl-names = "default";
+		pinctrl-0 = <&bl_pwr_en>;
+		regulator-name = "backlight_regulator";
+		vin-supply = <&vcc33_sys>;
+		startup-delay-us = <15000>;
+	};
+
+	panel_regulator: panel-regulator {
+		compatible = "regulator-fixed";
+		enable-active-high;
+		gpio = <&gpio7 14 GPIO_ACTIVE_HIGH>;
+		pinctrl-names = "default";
+		pinctrl-0 = <&lcd_enable_h>;
+		regulator-name = "panel_regulator";
+		vin-supply = <&vcc33_sys>;
+	};
+
+	vcc18_lcd: vcc18-lcd {
+		compatible = "regulator-fixed";
+		enable-active-high;
+		gpio = <&gpio2 13 GPIO_ACTIVE_HIGH>;
+		pinctrl-names = "default";
+		pinctrl-0 = <&avdd_1v8_disp_en>;
+		regulator-name = "vcc18_lcd";
+		regulator-always-on;
+		regulator-boot-on;
+		vin-supply = <&vcc18_wl>;
+	};
+};
+
+&gpio_keys {
+	pinctrl-0 = <&pwr_key_l &ap_lid_int_l &volum_down_l &volum_up_l>;
+
+	volum_down {
+		label = "Volum_down";
+		gpios = <&gpio5 11 GPIO_ACTIVE_LOW>;
+		linux,code = <KEY_VOLUMEDOWN>;
+		debounce-interval = <100>;
+	};
+
+	volum_up {
+		label = "Volum_up";
+		gpios = <&gpio5 10 GPIO_ACTIVE_LOW>;
+		linux,code = <KEY_VOLUMEUP>;
+		debounce-interval = <100>;
+	};
+};
+
+&i2c_tunnel {
+	battery: bq27500 at 55 {
+		compatible = "ti,bq27500";
+		reg = <0x55>;
+	};
+};
+
+&i2c3 {
+	status = "okay";
+
+	/*
+	 * Touchscreen pin control is shared between Atmel and Elan devices,
+	 * so we have to pull it up to the bus level.
+	 */
+	pinctrl-names = "default";
+	pinctrl-0 = <&i2c3_xfer &touch_int &touch_rst>;
+
+	clock-frequency = <400000>;
+	i2c-scl-falling-time-ns = <50>;
+	i2c-scl-rising-time-ns = <300>;
+
+	touchscreen at 10 {
+		compatible = "elan,ekth3500";
+		reg = <0x10>;
+		interrupt-parent = <&gpio2>;
+		interrupts = <14 IRQ_TYPE_EDGE_FALLING>;
+		reset-gpios = <&gpio2 15 GPIO_ACTIVE_LOW>;
+		vcc33-supply = <&vcc33_touch>;
+		vccio-supply = <&vcc33_touch>;
+	};
+
+	touchscreen at 4a {
+		compatible = "atmel,atmel_mxt_ts";
+		reg = <0x4a>;
+		atmel,reset-gpios = <&gpio2 15 GPIO_ACTIVE_LOW>;
+		avdd-supply = <&vcc5v_touch>;
+		interrupt-parent = <&gpio2>;
+		interrupts = <14 IRQ_TYPE_EDGE_FALLING>;
+		vdd-supply = <&vcc33_touch>;
+	};
+};
+
+&rk808 {
+	pinctrl-names = "default";
+	pinctrl-0 = <&pmic_int_l &dvs_1 &dvs_2>;
+
+	regulators {
+		vcc33_touch: LDO_REG2 {
+			regulator-min-microvolt = <3300000>;
+			regulator-max-microvolt = <3300000>;
+			regulator-name = "vcc33_touch";
+			regulator-suspend-mem-disabled;
+		};
+
+		vcc5v_touch: SWITCH_REG2 {
+			regulator-name = "vcc5v_touch";
+			regulator-suspend-mem-disabled;
+		};
+	};
+};
+
+&sdmmc {
+	disable-wp;
+	pinctrl-names = "default";
+	pinctrl-0 = <&sdmmc_clk &sdmmc_cmd &sdmmc_cd_disabled &sdmmc_cd_gpio
+			&sdmmc_bus4>;
+};
+
+&vcc_5v {
+	enable-active-high;
+	gpio = <&gpio7 21 GPIO_ACTIVE_HIGH>;
+	pinctrl-names = "default";
+	pinctrl-0 = <&drv_5v>;
+};
+
+&vcc50_hdmi {
+	enable-active-high;
+	gpio = <&gpio5 19 GPIO_ACTIVE_HIGH>;
+	pinctrl-names = "default";
+	pinctrl-0 = <&vcc50_hdmi_en>;
+};
+
+&pinctrl {
+	backlight {
+		bl_pwr_en: bl_pwr_en {
+			rockchip,pins = <2 12 RK_FUNC_GPIO &pcfg_pull_none>;
+		};
+	};
+
+	buck-5v {
+		drv_5v: drv-5v {
+			rockchip,pins = <7 21 RK_FUNC_GPIO &pcfg_pull_none>;
+		};
+	};
+
+	buttons {
+		volum_down_l: volum-down-l {
+			rockchip,pins = <5 11 RK_FUNC_GPIO &pcfg_pull_up>;
+		};
+
+		volum_up_l: volum-up-l {
+			rockchip,pins = <5 10 RK_FUNC_GPIO &pcfg_pull_up>;
+		};
+	};
+
+	hdmi {
+		vcc50_hdmi_en: vcc50-hdmi-en {
+			rockchip,pins = <5 19 RK_FUNC_GPIO &pcfg_pull_none>;
+		};
+	};
+
+	lcd {
+		lcd_enable_h: lcd-en {
+			rockchip,pins = <7 14 RK_FUNC_GPIO &pcfg_pull_none>;
+		};
+
+		avdd_1v8_disp_en: avdd-1v8-disp-en {
+			rockchip,pins = <2 13 RK_FUNC_GPIO &pcfg_pull_none>;
+		};
+	};
+
+	pmic {
+		dvs_1: dvs-1 {
+			rockchip,pins = <7 12 RK_FUNC_GPIO &pcfg_pull_down>;
+		};
+
+		dvs_2: dvs-2 {
+			rockchip,pins = <7 15 RK_FUNC_GPIO &pcfg_pull_down>;
+		};
+	};
+
+	prochot {
+		gpio_prochot: gpio-prochot {
+			rockchip,pins = <2 8 RK_FUNC_GPIO &pcfg_pull_none>;
+		};
+	};
+
+	touchscreen {
+		touch_int: touch-int {
+			rockchip,pins = <2 14 RK_FUNC_GPIO &pcfg_pull_none>;
+		};
+
+		touch_rst: touch-rst {
+			rockchip,pins = <2 15 RK_FUNC_GPIO &pcfg_pull_none>;
+		};
+	};
+};
-- 
2.1.4




From pawelo at king.net.pl  Sat Aug  1 08:27:30 2015
From: pawelo at king.net.pl (Paul Osmialowski)
Date: Sat, 1 Aug 2015 17:27:30 +0200 (CEST)
Subject: [PATCH v2 3/9] arm: twr-k70f120m: clock driver for Kinetis SoC
In-Reply-To: <20150801005810.23791.8199@quantum>
References: <1435667250-28299-1-git-send-email-pawelo@king.net.pl>
 <alpine.DEB.2.11.1507030006280.3916@nanos> <2009463.YLtdMegFel@wuerfel>
 <alpine.LNX.2.00.1507042327490.1296@localhost.localdomain>
 <20150724034229.642.88156@quantum>
 <alpine.LNX.2.00.1507262211470.28341@localhost.localdomain>
 <20150728160347.642.31950@quantum>
 <alpine.LNX.2.00.1507282201220.2619@localhost.localdomain>
 <20150729230517.642.66061@quantum>
 <alpine.LNX.2.00.1507302326500.20387@localhost.localdomain>
 <20150801005810.23791.8199@quantum>
Message-ID: <alpine.LNX.2.00.1508011647140.32078@localhost.localdomain>


Hi Mike,

On Fri, 31 Jul 2015, Michael Turquette wrote:

> Quoting Paul Osmialowski (2015-07-30 14:40:48)
> > Hi Mike,
> > 
> > I encountered some trouble while I tried to implement code fitting to DTS 
> > that you proposed. SIM_CLKDIVx are SIM device registers, not MCG. 
> > Therefore, in MCG device code I won't be able to figure out clock rate 
> > for outputed clocks unles I try to access SIM registers from MCG driver - 
> 
> Right, the MCG driver will only know the rates of the clocks that it
> outputs, namely:
> 
> MCGIRCLK
> MCGFFCLK
> MCGOUTCLK
> MCGFLLCLK
> MCGPLL0CLK
> MCGPLL1CLK
> 
> The naming scheme in the TRM is a bit unfortunate; it looks like some of
> the clock outputs coming out of SIM also retain the MCG* names.

I wonder if I really need to implement support for all of these clocks 
while to run Linux on this board reference 2.6 kernel uses only MCGOUTCLK 
(and for this, it never considers FLL as a source). 
I can also provide support for MCGPLL0CLK and MCGPLL1CLK as well since 
their rates are computed as a byproduct while determining rate of 
MCGOUTCLK. I may define constants for all of them in related header file, 
but I'm thinking about leaving most of implementations as TBD - otherwise 
I doubt I'll be ever able to test that my driver fully works.

> 
> Why is clock-cells zero? I think the MCG block outputs all of the clocks
> that I listed above? As such they should be addressable as <&mcg N> by
> any downstream users.
> 

Ok, will be 1, to distinguish between MCGOUTCLK, MCGPLL0CLK, MCGPLL1CLK.


> >                         reg = <0x40064000 0x14>;
> >                         clocks = <&osc0>, <&osc1>, <&rtc>;
> >                         clock-names = "osc0", "osc1", "rtc";
> 
> Are the oscN and rtc clocks modeled as fixed-rate clocks in DT?
> 

Yes, I skipped the part above soc during copy-paste.

> It looks like the SIM block should also consume:
> 
> MCGFLLCLK
> MCGIRCLK
> MCGFFCLK
> MCGPLL0CLK
> MCGPLL1CLK
> OSC0ERCLK
> OSC1ERCLK
> OSC032KCLK
> RTCCLK (I made that name up)
> 
> The mcg clocks should come out of the mcg node. It looks like you
> already modeled oscN and rtc clocks, which is great. There are some
> gates after these clocks (e.g. OSC0ERCLK). I wonder if those gates are
> actually in the osc IP block or if they actually live in SIM. More on
> that below...
> 
> Well they certainly can be exposed if you need them to be. If a device
> driver wants to get the core clock and set it's rate then it should be
> able to with something like <&sim CORE_CLK>.
> 

Ok, the user of the clock does not relly need to know whether it is clock 
device or a clock gate - fortunately, I already learnt how to implement 
such thing.

> > 
> > Also note that fec (ethernet device) driver is connected directly to osc0 
> > (though clock gate, you can see this CG attached to osc0 on the diagram 
> > too) - to control this gate I need to access SIM device registers, so it 
> > should be covered by the same fsl,kinetis-sim driver.
> 
> Do you mean the SIM_SOPT2 register? It looks like the connection is not
> "direct", as the osc0 signal feeds into the SIM block and the gate there
> controls it.  Perhaps the diagram is incorrect by placing the CG block
> inside osc0? It looks like you correctly modeled this relationship in
> the sim node.

In order to enable network device, bit 0 of SIM_SCGC2 must be set for RMII 
mode to work, and according to what I see on the page 228 of the reference
manual, it is osc0 clock behind this gate.

In the context of network device, I would need to read SIM_SOPT2 to 
determine clock source for IEEE 1588 timestamp while implementing PTP 
support - which currently I don't have in my plans, network device can do 
without it.

Thanks,
Paul

> 
> Besides my annoying questions above this binding is starting to shape up
> very well. Thanks for your patience!
> 
> Regards,
> Mike
> 
> > 
> > On Wed, 29 Jul 2015, Michael Turquette wrote:
> > 
> > > Quoting Paul Osmialowski (2015-07-28 13:30:17)
> > > > Hi Mike,
> > > > 
> > > > My trouble is that now I'm dealing with two conradictory opinions on how 
> > > > this driver should be written. The one you presented in your previous post 
> > > > assumes that there will be a header file with defines shared between the 
> > > > clock driver and DTS, also with clock gating details hidden behind some 
> > > > additional level of indirection, e.g.:
> > > > 
> > > > clocks = <&sim SIM_SCGC4_UART1_CLK>;
> > > > 
> > > > Note that I've been through this at the very beginning, though the names 
> > > > I used have been bit different, e.g.:
> > > > 
> > > > #define KINETIS_CG_UART1       KINETIS_MKCG(3, 11)     /* SIM_SCGC4[11] */
> > > > 
> > > > This was rejected with a comment by Arnd:
> > > > 
> > > > Instead of using a triple indirection here, just put the tuples
> > > > in the DT directly using #clock-cells=<2>, and get rid of both this
> > > > header file and the dt-bindings/clock/kinetis-mcg.h file.
> > > 
> > > Arnd, are you OK with my type of binding description now that I
> > > explained it with some examples?
> > > 
> > > > 
> > > > So I dropped all of these includes and started to use magic numbers (as 
> > > > you put it). Now I need to go one way or another or even go the third way: 
> > > > extend #clock-cells to <3> and address it like: <&sim parent_clock_id 
> > > > scgc_register_number bit_index_number>.
> > > 
> > > Paul,
> > > 
> > > >From my understanding the DT folks do not like register-level or
> > > bit-level details going into DT. It is better to handle the clock
> > > signals as abstract resources and link a provider and consumer with a
> > > simple phandle plus an index representing that abstract resource (i.e.
> > > the clock output signal).
> > > 
> > > > 
> > > > Reading your previous post I'm starting to feel that it would bring me 
> > > > closer to final acceptance if I stick to what you proposed in that post 
> > > > (I'm really grateful to you for writting so huge chunk of DTS for me!), so 
> > > > I'll probably adopt that.
> > > > 
> > > > You're right about my "get things up and running" attitude - currently I 
> > > > want to develop things extensively (cover as much subsystems as 
> > > > possible) and then at some stage switch to intensive approach. This board 
> > > > is a somewhat huge monster (for a Cortex-M4 SoC) and there will be a lot 
> > > > of coding opportunity in this field in the future.
> > > 
> > > I'm happy to take clock drivers and add my Reviewed-by to .dts files
> > > that make use of fixed-rate and fixed-factor clocks as an interim
> > > solution.  Of course it will be best to get The Real Thing merged
> > > upstream asap, but this is something I've done before to help get new
> > > platform upstream before and I'm fine to do it again.
> > > 
> > > With that said, Devicetree bindings are allegedly a stable ABI that
> > > cannot be broken. So let's make sure that any Kinetis clock binding
> > > description is in good shape before merging it. The rest can follow on
> > > later if it needs to.
> > > 
> > > Regards,
> > > Mike
> > > 
> > > > 
> > > > Thanks,
> > > > Paul
> > > > 
> > > > On Tue, 28 Jul 2015, Michael Turquette wrote:
> > > > 
> > > > > Quoting Paul Osmialowski (2015-07-26 13:24:08)
> > > > > > Hi Mike,
> > > > > > 
> > > > > > Thank you for spending time on this and pointing me into the right 
> > > > > > direction. I'm wondering about going even further with it. Assuming that I 
> > > > > 
> > > > > Hi Paul,
> > > > > 
> > > > > No problem! And thanks for the quick turnaround on your patches so far.
> > > > > 
> > > > > > know everything about my board, I can skip run-time discovery phase (note 
> > > > > > that the original driver was designed for other Kinetis-based boards too) 
> > > > > > and move everything into DTS, somewhat like this:
> > > > > > 
> > > > > > / {
> > > > > >         osc0: clock {
> > > > > >                 compatible = "fixed-clock";
> > > > > >                 #clock-cells = <0>;
> > > > > >                 clock-frequency = <50000000>;
> > > > > >         };
> > > > > > 
> > > > > >         osc1: clock {
> > > > > >                 compatible = "fixed-clock";
> > > > > >                 #clock-cells = <0>;
> > > > > >                 clock-frequency = <12000000>;
> > > > > >         };
> > > > > > 
> > > > > >         rtc: clock {
> > > > > >                 compatible = "fixed-clock";
> > > > > >                 #clock-cells = <0>;
> > > > > >                 clock-frequency = <32768>;
> > > > > >         };
> > > > > > 
> > > > > >         mcgout: clock {
> > > > > >                 compatible = "fixed-factor-clock";
> > > > > >                 #clock-cells = <0>;
> > > > > >                 clocks = <&osc0>;
> > > > > >                 clock-mult = <12>;
> > > > > >                 clock-div = <5>;
> > > > > >         };
> > > > > 
> > > > > I think this is a step backwards.
> > > > > 
> > > > > Did you look at the qcom clock binding and read the email where I
> > > > > detailed how that binding works?
> > > > > 
> > > > > The point of that type of binding is to not shove per-clock data into
> > > > > DT, but instead to declare every clock controller IP block (e.g. the
> > > > > device) as well as every board-level clock (e.g. as osc that feeds into
> > > > > your mcu). Once these "clock providers" are enumerated in DT, then we
> > > > > create linkage between the clock providers and the clock consumers by
> > > > > using phandles + an index. Linux device drivers tap into this by using
> > > > > clk_get() and using the "clock-names" property from DT.
> > > > > 
> > > > > Put another way: we mostly use DT to model "devices". That is open to
> > > > > interpretation for but for clock-related stuff we typically interpret
> > > > > the clock controller as the device, not the individual clock outputs
> > > > > coming out of the controller.
> > > > > 
> > > > > Note that a clock controller IP block may be both a provider and a
> > > > > consumer.  I/O controllers are a very common type of consumer (e.g. USB
> > > > > host controller, MMC controller, GPU, etc).
> > > > > 
> > > > > Additionally, from my reading of the reference manual, mcgout is defined
> > > > > as:
> > > > > 
> > > > > """
> > > > > MCG output of either IRC, MCGFLLCLK MCGPLL0CLK,
> > > > > MCGPLL1CLK, or MCG's external reference clock that
> > > > > sources the core, system, bus, FlexBus, and flash clock. It is
> > > > > also an option for the debug trace clock.
> > > > > """
> > > > > 
> > > > > So why is it listed here as a fixed-factor clock? Is it not a
> > > > > multiplexer? Also, why is it listed here at all? Please take another
> > > > > look at the qcom binding example I linked to in my previous mail.
> > > > > 
> > > > > > 
> > > > > >         core: clock {
> > > > > >                 compatible = "fixed-factor-clock";
> > > > > >                 #clock-cells = <0>;
> > > > > >                 clocks = <&mcgout>;
> > > > > >                 clock-mult = <1>;
> > > > > >                 clock-div = <1>;
> > > > > >         };
> > > > > > 
> > > > > >         bus: clock {
> > > > > >                 compatible = "fixed-factor-clock";
> > > > > >                 #clock-cells = <0>;
> > > > > >                 clocks = <&mcgout>;
> > > > > >                 clock-mult = <1>;
> > > > > >                 clock-div = <2>;
> > > > > 
> > > > > These are actually not fixed dividers but programmable dividers. You can
> > > > > probably use drivers/clk/clk-divider.c for these. I'm fine with using
> > > > > fixed-dividers for the initial merge just to get things up and running
> > > > > if that is your strategy, but you'll need to revisit them later on when
> > > > > you need more flexible support for other boards.
> > > > > 
> > > > > Again, I'm not sure why these clocks are enumerated in DT. Why not just
> > > > > enumerate your mcg clock controller and your sim clock controller? If
> > > > > you want to be a perfectionist then it appears that there is an osc
> > > > > clock controller upstream from the mcg controller as well ;-)
> > > > > 
> > > > > It occurs to me that maybe you are trying to use fixed-factor clocks so
> > > > > that you can program a sane default rate? We use the
> > > > > assigned-clock-rates property for that. Note that this value is a
> > > > > property of some device which *consumes* the clock, not the clock
> > > > > controller or the clock output itself.
> > > > > 
> > > > > >         };
> > > > > > 
> > > > > >         soc {
> > > > > >                 cmu at 0x40047000 {
> > > > > >                         compatible = "fsl,kinetis-gate-clock";
> > > > > >                         reg = <0x40047000 0x1100>;
> > > > > > 
> > > > > >                         mcg_core_gate: clock-gate {
> > > > > >                                 clocks = <&core>;
> > > > > >                                 #clock-cells = <2>;
> > > > > >                         };
> > > > > > 
> > > > > >                         mcg_bus_gate: clock-gate {
> > > > > >                                 clocks = <&bus>;
> > > > > >                                 #clock-cells = <2>;
> > > > > >                         };
> > > > > > 
> > > > > >                         osc0_erclk_gate: clock-gate {
> > > > > >                                 clocks = <&osc0>;
> > > > > >                                 #clock-cells = <2>;
> > > > > >                         };
> > > > > >                 };
> > > > > > 
> > > > > >                 uart0: serial at 4006a000 {
> > > > > >                         compatible = "fsl,kinetis-lpuart";
> > > > > >                         reg = <0x4006a000 0x1000>;
> > > > > >                         interrupts = <45>, <46>;
> > > > > >                         interrupt-names = "uart-stat", "uart-err";
> > > > > >                         clocks = <&mcg_core_gate 3 10>;
> > > > > 
> > > > > Magic numbers are not good. dtc has been able to use preprocessor macros
> > > > > for a while now which means we can use constants instead of magic
> > > > > numbers. Please look at the shared header in the qcom binding for an
> > > > > example.
> > > > > 
> > > > > >                         clock-names = "ipg";
> > > > > >                         dmas = <&edma 0 2>;
> > > > > >                         dma-names = "rx";
> > > > > >                         status = "disabled";
> > > > > >                 };
> > > > > >         };
> > > > > > };
> > > > > > 
> > > > > > As you can see, mcg part is not required anymore.
> > > > > 
> > > > > I think the mcg should be required. The mcg is a real IP block on your
> > > > > SoC, according to my reading of your technical reference manual. Just
> > > > > because you can model a few of its output clocks in dts does not mean
> > > > > that you should.
> > > > > 
> > > > > I did a quick grep and didn't find "cmu" anywhere in the reference
> > > > > manual.
> > > > > 
> > > > > > 
> > > > > > I guess that the approach above would require split into soc-specific and 
> > > > > > board-specific part (as I said, dividers arrangement is something board 
> > > > > > specific), but I wonder what you thing about this proposal.
> > > > > 
> > > > > Splitting is good. Chip-specific stuff can go into the chip-specific
> > > > > dtsi file. The board-level (osc) stuff can go into the individual board
> > > > > files. The ultimate goal is to make it trivial to add new boards.
> > > > > 
> > > > > Regards,
> > > > > Mike
> > > > > 
> > > > > > 
> > > > > > Thanks,
> > > > > > Paul
> > > > > > 
> > > > > > On Thu, 23 Jul 2015, Michael Turquette wrote:
> > > > > > 
> > > > > > > Quoting Paul Osmialowski (2015-07-04 14:50:03)
> > > > > > > > Hi Arnd,
> > > > > > > > 
> > > > > > > > I'm attaching excerpt from Kinetis reference manual that may make 
> > > > > > > > situation clearer.
> > > > > > > 
> > > > > > > Hi Paul,
> > > > > > > 
> > > > > > > Can you please post the patch in the body of the email instead of an
> > > > > > > attachment? It makes it easier to review. Another small nitpick is that
> > > > > > > the $SUBJECT for this patch might be better off as something like:
> > > > > > > 
> > > > > > > clk: mcg and sim clock drivers for twr-k70f120m Kinetis SoC
> > > > > > > 
> > > > > > > At least it helps me find the patch I care about when skimming the
> > > > > > > series ;-)
> > > > > > > 
> > > > > > > > 
> > > > > > > > These MCG and SIM registers are used only to determine configuration 
> > > > > > > > (clock fixed rates and clock signal origins) at run time.
> > > > > > > > 
> > > > > > > > Namely, the real MCGOUTCLK source (in the middle) which is the parent for 
> > > > > > > > core clock (CCLK) and peripheral clock (PCLK) is determined at run time by 
> > > > > > > > reading MCG registers, let me quote commit message from Emcraft git repo:
> > > > > > > > 
> > > > > > > >       * Determine in run-time what oscillator module (OSC0 or OSC1) is used
> > > > > > > >      as clock source for the main PLL.
> > > > > > > 
> > > > > > > According to [0] there are three options: a 32k RTC osc clock and osc0
> > > > > > > both feed into a mux. You should model this 32k clock with the
> > > > > > > fixed-rate binding.
> > > > > > > 
> > > > > > > >       * When OSC1 is selected, assume its frequency to be 12 MHz on all
> > > > > > > >      boards (there is a 12 MHz oscillator on XTAL1/EXTAL1 on K70-SOM and
> > > > > > > >      TWR-K70F120M boards).
> > > > > > > > 
> > > > > > > > In my .dts I'm trying to possibly follow real clock hierarchy, but to go 
> > > > > > > > anywhere behind MCGOUTCLK would require ability to rewrite .dtb e.g. by 
> > > > > > > > U-boot. But that's too demanding for any potential users of this BSP. So 
> > > > > > > > let's asume that MCGOUTCLK is the root clock and a parent for CCLK and 
> > > > > > > > PCLK.
> > > > > > > 
> > > > > > > I'm confused. The point of device tree is to solve problems like this;
> > > > > > > i.e. board-specific differences such as different oscillator
> > > > > > > frequencies.
> > > > > > > 
> > > > > > > OSC0 and OSC1 should each be a fixed-rate clock in your board-specific
> > > > > > > TWR-K70F120M DTS (not a chip-specific file). They do not belong in the
> > > > > > > cmu node, and they should use the "fixed-clock" binding. The 32k RTC osc
> > > > > > > can probably go in your chip-specific .dtsi as a fixed-rate clock since
> > > > > > > it appears to mandated in the reference manual[0].
> > > > > > > 
> > > > > > > These three fixed-rate clocks are your root clock nodes. Customers only
> > > > > > > need to worry about this if they spin a board, and then they will need
> > > > > > > to populate the frequencies of OSC0 and OSC1 in their board-specific
> > > > > > > .dts.
> > > > > > > 
> > > > > > > Please break clk-kinetis.c into two files:
> > > > > > > drivers/clk/kinetis/clk-mcg.c
> > > > > > > drivers/clk/kinetis/clk-sim.c
> > > > > > > 
> > > > > > > Below is what your binding/dts should look like:
> > > > > > > 
> > > > > > > {
> > > > > > >       osc0: clock {
> > > > > > >               compatible = "fixed-clock";
> > > > > > >               #clock-cells = <0>;
> > > > > > >               clock-frequency = <50000000>;
> > > > > > >       };
> > > > > > > 
> > > > > > >       osc1: clock {
> > > > > > >               compatible = "fixed-clock";
> > > > > > >               #clock-cells = <0>;
> > > > > > >               clock-frequency = <12000000>;
> > > > > > >       };
> > > > > > > 
> > > > > > >       rtc: clock {
> > > > > > >               compatible = "fixed-clock";
> > > > > > >               #clock-cells = <0>;
> > > > > > >               clock-frequency = <32768>;
> > > > > > >       };
> > > > > > > 
> > > > > > >       soc: soc {
> > > > > > >               mcg: clock-controller at 40064000 {
> > > > > > >                       compatible = "fsl,kinetis-mcg";
> > > > > > >                       clock-cells = <1>;
> > > > > > >                       reg = <0x40064000 0x14>;
> > > > > > >                       clocks = <&osc0>, <&osc1>, <&rtc>;
> > > > > > >                       clock-names = "osc0", "osc1", "rtc";
> > > > > > >               };
> > > > > > > 
> > > > > > >               sim: clock-controller at 40047000 {
> > > > > > >                       compatible = "fsl,kinetis-sim";
> > > > > > >                       clock-cells = <1>;
> > > > > > >                       reg = <0x40047000 0x1100>;
> > > > > > >                       clocks = <&mcg MCG_MCGOUTCLK_DIV1>, <&mcg MCG_MCGOUTCLK_DIV2>, <&mcg MCG_MCGOUTCLK_DIV3> <&mcg MCG_MCGOUTCLK_DIV4>;
> > > > > > >                       clock-names = "core", "bus", "flexbus", "flash";
> > > > > > >               };
> > > > > > >       };
> > > > > > > 
> > > > > > >       uart0: serial at 4006a000 {
> > > > > > >               compatible = "fsl,kinetis-lpuart";
> > > > > > >               reg = <0x4006a000 0x1000>;
> > > > > > >               clocks = <&sim SIM_SCGC4_UART1_CLK>;
> > > > > > >               clock-names = "gate";
> > > > > > >       };
> > > > > > > 
> > > > > > > I removed the interrupts and dma stuff from the uart0 node for clarity.
> > > > > > > The above is the only style of binding that I have been accepting for
> > > > > > > some time; first declare the clock controller and establish its register
> > > > > > > space, and then consumers can consume clocks by providing the phandle to
> > > > > > > the controller plus an offset corresponding to a unique clock. The
> > > > > > > clock-names property makes it really easy to use with the clkdev stuff
> > > > > > > (e.g. clk_get()).
> > > > > > > 
> > > > > > > I've covered this before on the mailing list so here is a link
> > > > > > > describing how the qcom bindings do it in detail:
> > > > > > > 
> > > > > > > http://lkml.kernel.org/r/<20150416192014.19585.9663 at quantum>
> > > > > > > 
> > > > > > > Technically you could encode the same bits as sub-nodes of the mcg and
> > > > > > > sim nodes, but the shared header is how the magic happens with the
> > > > > > > driver so it's best to keep the clock controller binding small and
> > > > > > > light.
> > > > > > > 
> > > > > > > I think this means you can also get rid of kinetis_of_clk_get_name and
> > > > > > > kinetis_clk_gate_get but my brain is tired so I'll leave that as an
> > > > > > > exercise to the reader.
> > > > > > > 
> > > > > > > [0] http://cache.freescale.com/files/microcontrollers/doc/ref_manual/K70P256M150SF3RM.pdf
> > > > > > > 
> > > > > > > Regards,
> > > > > > > Mike
> > > > > > > 
> > > > > > > > 
> > > > > > > > In my most recent version I added OSC0ERCLK explicitly as one more root 
> > > > > > > > clock, since it is also used directly (through CG reg. 1 bit 0) by 
> > > > > > > > Freescale fec network device whose in-tree driver I'm trying to make 
> > > > > > > > usable for Kinetis.
> > > > > > > > 
> > > > > > > > On Sat, 4 Jul 2015, Arnd Bergmann wrote:
> > > > > > > > 
> > > > > > > > > On Friday 03 July 2015 00:08:27 Thomas Gleixner wrote:
> > > > > > > > >> On Thu, 2 Jul 2015, Paul Osmialowski wrote:
> > > > > > > > >>> On Thu, 2 Jul 2015, Arnd Bergmann wrote:
> > > > > > > > >>>
> > > > > > > > >>>> I wonder if you could move out the fixed rate clocks into their own
> > > > > > > > >>>> nodes. Are they actually controlled by the same block? If they are
> > > > > > > > >>>> just fixed, you can use the normal binding for fixed rate clocks
> > > > > > > > >>>> and only describe the clocks that are related to the driver.
> > > > > > > > >>>
> > > > > > > > >>> In my view having these clocks grouped together looks more convincing. After
> > > > > > > > >>> all, they all share the same I/O regs in order to read configuration.
> > > > > > > > >>
> > > > > > > > >> The fact that they share a register is not making them a group. That's
> > > > > > > > >> just a HW design decision and you need to deal with that by protecting
> > > > > > > > >> the register access, but not by trying to group them artificially at
> > > > > > > > >> the functional level.
> > > > > > > > >
> > > > > > > > > I'd disagree with that: The clock controller is the device that owns the
> > > > > > > > > registers and that should be one node in DT, as Paul's first version does.
> > > > > > > > >
> > > > > > > > > The part I'm still struggling with is understanding how the fixed-rate
> > > > > > > > > clocks are controlled through those registers. If they are indeed configured
> > > > > > > > > through the registers, the name is probably wrong and should be changed
> > > > > > > > > to whatever kind of non-fixed clock this is.
> > > > > > > > >
> > > > > > > > >       Arnd
> > > > > > > > >
> > > > > > > > 
> > > > > > > > _______________________________________________
> > > > > > > > linux-arm-kernel mailing list
> > > > > > > > linux-arm-kernel at lists.infradead.org
> > > > > > > > http://lists.infradead.org/mailman/listinfo/linux-arm-kernel
> > > > > > > 
> > > > > > --
> > > > > > To unsubscribe from this list: send the line "unsubscribe linux-kernel" in
> > > > > > the body of a message to majordomo at vger.kernel.org
> > > > > > More majordomo info at  http://vger.kernel.org/majordomo-info.html
> > > > > > Please read the FAQ at  http://www.tux.org/lkml/
> > > > > 
> > > > --
> > > > To unsubscribe from this list: send the line "unsubscribe linux-kernel" in
> > > > the body of a message to majordomo at vger.kernel.org
> > > > More majordomo info at  http://vger.kernel.org/majordomo-info.html
> > > > Please read the FAQ at  http://www.tux.org/lkml/
> > > 
> > --
> > To unsubscribe from this list: send the line "unsubscribe linux-kernel" in
> > the body of a message to majordomo at vger.kernel.org
> > More majordomo info at  http://vger.kernel.org/majordomo-info.html
> > Please read the FAQ at  http://www.tux.org/lkml/
> 


From nsekhar at ti.com  Sat Aug  1 08:33:56 2015
From: nsekhar at ti.com (Sekhar Nori)
Date: Sat, 1 Aug 2015 21:03:56 +0530
Subject: [PATCH] ARM: davinci: cp_intc: use IRQCHIP_SKIP_SET_WAKE instead of
 irq_set_wake callback
In-Reply-To: <1435941754-21102-1-git-send-email-sudeep.holla@arm.com>
References: <1435941754-21102-1-git-send-email-sudeep.holla@arm.com>
Message-ID: <1438443236-30206-1-git-send-email-nsekhar@ti.com>

From: Sudeep Holla <sudeep.holla at arm.com>

Commit 60f96b41f71d ("genirq: Add IRQCHIP_SKIP_SET_WAKE flag")
introduced a new flag to skip the irq_set_wake callback in the irqchip
core to avoid adding dummy irq_set_wake in the irqchip implementations.

This patch removes the dummy callback and sets the IRQCHIP_SKIP_SET_WAKE
flags.

Cc: Sekhar Nori <nsekhar at ti.com>
Cc: Kevin Hilman <khilman at deeprootsystems.com>
Signed-off-by: Sudeep Holla <sudeep.holla at arm.com>
Signed-off-by: Sekhar Nori <nsekhar at ti.com>
---
ARM-SoC, can you please apply this patch directly?
I do not have any other patches queued, so not sending
a pull request.

 arch/arm/mach-davinci/cp_intc.c | 12 +-----------
 1 file changed, 1 insertion(+), 11 deletions(-)

diff --git a/arch/arm/mach-davinci/cp_intc.c b/arch/arm/mach-davinci/cp_intc.c
index 006dae8dfe44..9fda75c18c04 100644
--- a/arch/arm/mach-davinci/cp_intc.c
+++ b/arch/arm/mach-davinci/cp_intc.c
@@ -85,23 +85,13 @@ static int cp_intc_set_irq_type(struct irq_data *d, unsigned int flow_type)
 	return 0;
 }
 
-/*
- * Faking this allows us to to work with suspend functions of
- * generic drivers which call {enable|disable}_irq_wake for
- * wake up interrupt sources (eg RTC on DA850).
- */
-static int cp_intc_set_wake(struct irq_data *d, unsigned int on)
-{
-	return 0;
-}
-
 static struct irq_chip cp_intc_irq_chip = {
 	.name		= "cp_intc",
 	.irq_ack	= cp_intc_ack_irq,
 	.irq_mask	= cp_intc_mask_irq,
 	.irq_unmask	= cp_intc_unmask_irq,
 	.irq_set_type	= cp_intc_set_irq_type,
-	.irq_set_wake	= cp_intc_set_wake,
+	.flags		= IRQCHIP_SKIP_SET_WAKE,
 };
 
 static struct irq_domain *cp_intc_domain;
-- 
2.4.4.408.g16da57c



From maxime.ripard at free-electrons.com  Sat Aug  1 02:30:46 2015
From: maxime.ripard at free-electrons.com (Maxime Ripard)
Date: Sat, 1 Aug 2015 11:30:46 +0200
Subject: [linux-sunxi] Re: [PATCH 5/5] ARM: dts: sun7i: Add dts file for
 Wits Pro A20 DKT
In-Reply-To: <55BB9E92.30604@redhat.com>
References: <1438333194-21181-1-git-send-email-hdegoede@redhat.com>
 <1438333194-21181-6-git-send-email-hdegoede@redhat.com>
 <20150731102028.GE2564@lukather>
 <CAGb2v65TEogqYFAfen1VnOaiepvez5t8Oh+Q=OYsRS_aZUMO3A@mail.gmail.com>
 <55BB9E92.30604@redhat.com>
Message-ID: <20150801093046.GX2564@lukather>

On Fri, Jul 31, 2015 at 06:13:06PM +0200, Hans de Goede wrote:
> mmc-pwrseq-simple supports multiple reset/enable gpios (by listing
> them all as reset-gpios and setting GPIO_ACTIVE_LOW/HIGH depending
> on which value they need to be to activate things).
> 
> It also supports listing clocks which need to be enabled. I think
> that it may be a good idea to use this to also enable the bluetooth
> bits of the ap6210 module on the cubietruck. I know that the
> actual bt is interfaced over an uart, and we really should have
> a mechanism to enable/disable it separately, but for not this seems
> like a good way to get bluetooth to work.
> 
> We should ofcourse add a comment to the dts file that this is not a
> 100% ideal solution, but other then that I think this should work
> nicely. Maxime would enabling the bluetooth bits of this sdio
> module via mmc-pwrseq be acceptable to you?

As long as we have some comment on top, yep.

> ChenYu if Maxime acks this solution I hope you can write a patch for
> this, since you've been working on the bluetooth support before.

Note that I'm in holidays starting today. I plan on doing my
pull-requests for 4.3 later today, and will probably not be able to
merge any patches during the next two weeks, which mean that your
mmc-power seq patch for the cubietruck was probably the last one I was
merging for the 4.3 merge window.

Maxime

-- 
Maxime Ripard, Free Electrons
Embedded Linux, Kernel and Android engineering
http://free-electrons.com
-------------- next part --------------
A non-text attachment was scrubbed...
Name: signature.asc
Type: application/pgp-signature
Size: 819 bytes
Desc: Digital signature
URL: <http://lists.infradead.org/pipermail/linux-arm-kernel/attachments/20150801/a03c54cf/attachment.sig>

From maxime.ripard at free-electrons.com  Sat Aug  1 02:26:38 2015
From: maxime.ripard at free-electrons.com (Maxime Ripard)
Date: Sat, 1 Aug 2015 11:26:38 +0200
Subject: [PATCH] ARM: dts: sun7i: Change cubietruck wifi enable pin to
 use mmc-pwrseq
In-Reply-To: <1438357312-17378-1-git-send-email-hdegoede@redhat.com>
References: <1438357312-17378-1-git-send-email-hdegoede@redhat.com>
Message-ID: <20150801092638.GW2564@lukather>

On Fri, Jul 31, 2015 at 05:41:52PM +0200, Hans de Goede wrote:
> The wifi-enable pin of the ap6210 module is not really a regulator,
> switch to the mmc-pwrseq framework for controlling it. This more
> accurately reflects how the hardware actually works.
> 
> Signed-off-by: Hans de Goede <hdegoede at redhat.com>
> ---
>  arch/arm/boot/dts/sun7i-a20-cubietruck.dts | 13 +++++--------
>  1 file changed, 5 insertions(+), 8 deletions(-)
> 
> diff --git a/arch/arm/boot/dts/sun7i-a20-cubietruck.dts b/arch/arm/boot/dts/sun7i-a20-cubietruck.dts
> index de3e195..0b2f914 100644
> --- a/arch/arm/boot/dts/sun7i-a20-cubietruck.dts
> +++ b/arch/arm/boot/dts/sun7i-a20-cubietruck.dts
> @@ -88,15 +88,11 @@
>  		};
>  	};
>  
> -	reg_vmmc3: vmmc3 {
> -		compatible = "regulator-fixed";
> +	mmc3_pwrseq: mmc3_pwrseq {
> +		compatible = "mmc-pwrseq-simple";
>  		pinctrl-names = "default";
>  		pinctrl-0 = <&vmmc3_pin_cubietruck>;

The pinctrl name shouldn't be called that way anymore.

Changed it to mmc3_pwrseq_pin_cubietruck, and applied the patch.

Thanks!
Maxime

-- 
Maxime Ripard, Free Electrons
Embedded Linux, Kernel and Android engineering
http://free-electrons.com
-------------- next part --------------
A non-text attachment was scrubbed...
Name: signature.asc
Type: application/pgp-signature
Size: 819 bytes
Desc: Digital signature
URL: <http://lists.infradead.org/pipermail/linux-arm-kernel/attachments/20150801/e8beae06/attachment.sig>

From maxime.ripard at free-electrons.com  Sat Aug  1 02:18:30 2015
From: maxime.ripard at free-electrons.com (Maxime Ripard)
Date: Sat, 1 Aug 2015 11:18:30 +0200
Subject: [linux-sunxi] Re: [PATCH 5/5] ARM: dts: sun7i: Add dts file for
 Wits Pro A20 DKT
In-Reply-To: <55BBB840.80107@redhat.com>
References: <1438333194-21181-1-git-send-email-hdegoede@redhat.com>
 <1438333194-21181-6-git-send-email-hdegoede@redhat.com>
 <20150731102028.GE2564@lukather>
 <CAGb2v65TEogqYFAfen1VnOaiepvez5t8Oh+Q=OYsRS_aZUMO3A@mail.gmail.com>
 <20150731165655.GG2564@lukather> <55BBB840.80107@redhat.com>
Message-ID: <20150801091830.GV2564@lukather>

On Fri, Jul 31, 2015 at 08:02:40PM +0200, Hans de Goede wrote:
> Hi,
> 
> On 31-07-15 18:56, Maxime Ripard wrote:
> >On Fri, Jul 31, 2015 at 06:25:29PM +0800, Chen-Yu Tsai wrote:
> >>>Note that it's a bit of a pain for now to support such cases, as
> >>>there's nothing to tie something from the DT to an SDIO device. I
> >>>don't have a better solution than marking it always-on at the moment,
> >>>with a big FIXME comment on top... :/
> >>
> >>One could use the mmc-pwr-seq stuff. I don't know if it has been
> >>extended for multiple GPIOs, not that you would need it in this use
> >>case.
> >
> >It doesn't really improve the situation. It doesn't handle the
> >regulators,
> 
> The regulator(s) are already handled by the vmmc and vqmcc regulators
> of the mmc controller binding.

Except that vmmc and vqmmc are regulators to power up the SD bus
itself, not the chip at the other end.

> If more regulators are needed, we can easily extend mmc-pwrseq-simple
> to support them, or define a whole new powerseq driver.
> 
> > it doesn't allow the real driver to get its resources
> >either, basically, it's just a hack.
> 
> Not involving the real driver is by design really, the real driver
> cannot bind / have its probe function called until its sdio interface
> has been probed which is where the pwrseq driver comes in.

Except that you might need to handle these resources later on, to shut
down or change the voltage or current of its regulator, adjust a clock
rate, whatever, which is clearly not possible right now. The only
thing that it allows is to setup the resources we want beside the
drivers back, even though he's the more knowledgeable about how to
manage its resources.

And the fact that it doesn't enumerate until some resources have been
enabled is not really an argument. Writing to memory-mapped devices
without enabling the clocks or the power domain first generates aborts
on some SoCs, yet the driver is still the one in charge of its
resources.

> This also allows re-using existing sdio drivers without needing
> them to be aware of certain board perculiarities

I don't really get what the board does here. reg-on, vbat and so on is
this case are pins of the WiFi chip. It doesn't change from one board
to another.

What does change is what these pins are tied to, but we do already
have a way to abstract that for every devices. Only the SDIO devices
seem to be special.

> If a special power on (or suspend) order is nescessary a custom
> pwrseq driver can be created for this, even one which is meant
> to work in tandem with a specific sdio device driver. The idea
> is that the device driver will ask the mmc core to powerdown the
> device for powersaving in certain cases (e.g. suspend) and then
> the mmc core will call into the powerseq driver.

Which effectively duplicate the logic between the real driver and a
power-seq one.

> Granted there may be more complex scenarios where thighter control
> over the resources is needed, but for now this seems to work really
> well and it is much better then the deadlock we had before were
> all solutions were shot down as not flexible enough.

I know.

Maxime

-- 
Maxime Ripard, Free Electrons
Embedded Linux, Kernel and Android engineering
http://free-electrons.com
-------------- next part --------------
A non-text attachment was scrubbed...
Name: signature.asc
Type: application/pgp-signature
Size: 819 bytes
Desc: Digital signature
URL: <http://lists.infradead.org/pipermail/linux-arm-kernel/attachments/20150801/5d0fab97/attachment.sig>

From ariel at vanguardiasur.com.ar  Sat Aug  1 11:35:30 2015
From: ariel at vanguardiasur.com.ar (Ariel D'Alessandro)
Date: Sat, 01 Aug 2015 15:35:30 -0300
Subject: [PATCH v4 1/2] watchdog: NXP LPC18xx Watchdog Timer Driver
In-Reply-To: <20150729151737.GA13628@roeck-us.net>
References: <20150729151737.GA13628@roeck-us.net>
Message-ID: <55BD1172.5010309@vanguardiasur.com.ar>

Hi Guenter,

El 29/07/15 a las 12:17, Guenter Roeck escibi?:
> On Mon, Jul 27, 2015 at 02:04:52AM -0300, Ariel D'Alessandro wrote:
>> This commit adds support for the watchdog timer found in NXP LPC SoCs
>> family, which includes LPC18xx/LPC43xx. Other SoCs in that family may
>> share the same watchdog hardware.
>>
>> Watchdog driver registers a restart handler that will restart the system
>> by performing an incorrect feed after ensuring the watchdog is enabled in
>> reset mode.
>>
>> As watchdog cannot be disabled in hardware, driver's stop routine will
>> regularly send a keepalive ping using a timer.
>>
>> Signed-off-by: Ariel D'Alessandro <ariel at vanguardiasur.com.ar>
> 
> Hi Ariel,
> 
> Please run the patch through checkpatch --strict.
> 
> Specifically, loook out for
> 
> WARNING: quoted string split across lines
> CHECK: No space is necessary after a cast
> CHECK: Please don't use multiple blank lines
> 
> Also see additional nitpick below.
> 

OK, I'm sending patchset v5 with these modifications.


From ariel at vanguardiasur.com.ar  Sat Aug  1 11:37:15 2015
From: ariel at vanguardiasur.com.ar (Ariel D'Alessandro)
Date: Sat,  1 Aug 2015 15:37:15 -0300
Subject: [PATCH v5 0/2] Add support for NXP LPC18xx Watchdog timer
Message-ID: <1438454237-22043-1-git-send-email-ariel@vanguardiasur.com.ar>

This patch series adds support for the watchdog timer found in NXP LPC
SoCs family which includes LPC18xx/LPC43xx. Other SoCs in that family may
share the same watchdog hardware.

Patchset is based on tag next-20150624 of the linux-next repository.
It has been successfully tested on a Hitex LPC4350 Evaluation Board and
on a CIAA NXP LPC4337 Board.

Changes since v4:
* Minor coding style fixes.

Changes since v3:
* Changed default timeout to 30.
* Minor changes.

Changes since v2:
* Changed config tristate to "LPC18xx/43xx".
* Added COMPILE_TEST as a dependency.
* Replaced raw_local_irq* calls by spinlock.
* Changed dt compatible string to "nxp,lpc1850-wwdt".

Changes since v1:
* Dropped "Windowed" term in Watchdog's name.
* Changed default timeout value from 1 to 5 because it was too tight.
* Fixed module remove function, since it was keeping the timer enabled. Warning
  message was added.
* Changed dt compatible string to "nxp,lpc1850-wdt".
* Renamed clocks matching most of the other lpc18xx drivers.

Ariel D'Alessandro (2):
  watchdog: NXP LPC18xx Watchdog Timer Driver
  DT: watchdog: Add NXP LPC18xx Watchdog Timer binding documentation

 .../devicetree/bindings/watchdog/lpc18xx-wdt.txt   |  19 ++
 drivers/watchdog/Kconfig                           |  11 +
 drivers/watchdog/Makefile                          |   1 +
 drivers/watchdog/lpc18xx_wdt.c                     | 340 +++++++++++++++++++++
 4 files changed, 371 insertions(+)
 create mode 100644 Documentation/devicetree/bindings/watchdog/lpc18xx-wdt.txt
 create mode 100644 drivers/watchdog/lpc18xx_wdt.c

-- 
1.9.1



From ariel at vanguardiasur.com.ar  Sat Aug  1 11:37:16 2015
From: ariel at vanguardiasur.com.ar (Ariel D'Alessandro)
Date: Sat,  1 Aug 2015 15:37:16 -0300
Subject: [PATCH v5 1/2] watchdog: NXP LPC18xx Watchdog Timer Driver
In-Reply-To: <1438454237-22043-1-git-send-email-ariel@vanguardiasur.com.ar>
References: <1438454237-22043-1-git-send-email-ariel@vanguardiasur.com.ar>
Message-ID: <1438454237-22043-2-git-send-email-ariel@vanguardiasur.com.ar>

This commit adds support for the watchdog timer found in NXP LPC SoCs
family, which includes LPC18xx/LPC43xx. Other SoCs in that family may
share the same watchdog hardware.

Watchdog driver registers a restart handler that will restart the system
by performing an incorrect feed after ensuring the watchdog is enabled in
reset mode.

As watchdog cannot be disabled in hardware, driver's stop routine will
regularly send a keepalive ping using a timer.

Signed-off-by: Ariel D'Alessandro <ariel at vanguardiasur.com.ar>
---
 drivers/watchdog/Kconfig       |  11 ++
 drivers/watchdog/Makefile      |   1 +
 drivers/watchdog/lpc18xx_wdt.c | 340 +++++++++++++++++++++++++++++++++++++++++
 3 files changed, 352 insertions(+)
 create mode 100644 drivers/watchdog/lpc18xx_wdt.c

diff --git a/drivers/watchdog/Kconfig b/drivers/watchdog/Kconfig
index 742fbbc..af5e2e3 100644
--- a/drivers/watchdog/Kconfig
+++ b/drivers/watchdog/Kconfig
@@ -547,6 +547,17 @@ config DIGICOLOR_WATCHDOG
 	  To compile this driver as a module, choose M here: the
 	  module will be called digicolor_wdt.
 
+config LPC18XX_WATCHDOG
+	tristate "LPC18xx/43xx Watchdog"
+	depends on ARCH_LPC18XX || COMPILE_TEST
+	select WATCHDOG_CORE
+	help
+	  Say Y here if to include support for the watchdog timer
+	  in NXP LPC SoCs family, which includes LPC18xx/LPC43xx
+	  processors.
+	  To compile this driver as a module, choose M here: the
+	  module will be called lpc18xx_wdt.
+
 # AVR32 Architecture
 
 config AT32AP700X_WDT
diff --git a/drivers/watchdog/Makefile b/drivers/watchdog/Makefile
index 59ea9a1..1b0ef48 100644
--- a/drivers/watchdog/Makefile
+++ b/drivers/watchdog/Makefile
@@ -66,6 +66,7 @@ obj-$(CONFIG_TEGRA_WATCHDOG) += tegra_wdt.o
 obj-$(CONFIG_MESON_WATCHDOG) += meson_wdt.o
 obj-$(CONFIG_MEDIATEK_WATCHDOG) += mtk_wdt.o
 obj-$(CONFIG_DIGICOLOR_WATCHDOG) += digicolor_wdt.o
+obj-$(CONFIG_LPC18XX_WATCHDOG) += lpc18xx_wdt.o
 
 # AVR32 Architecture
 obj-$(CONFIG_AT32AP700X_WDT) += at32ap700x_wdt.o
diff --git a/drivers/watchdog/lpc18xx_wdt.c b/drivers/watchdog/lpc18xx_wdt.c
new file mode 100644
index 0000000..00ff5bd
--- /dev/null
+++ b/drivers/watchdog/lpc18xx_wdt.c
@@ -0,0 +1,340 @@
+/*
+ * NXP LPC18xx Watchdog Timer (WDT)
+ *
+ * Copyright (c) 2015 Ariel D'Alessandro <ariel at vanguardiasur.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.
+ *
+ * Notes
+ * -----
+ * The Watchdog consists of a fixed divide-by-4 clock pre-scaler and a 24-bit
+ * counter which decrements on every clock cycle.
+ */
+
+#include <linux/clk.h>
+#include <linux/io.h>
+#include <linux/module.h>
+#include <linux/of.h>
+#include <linux/platform_device.h>
+#include <linux/reboot.h>
+#include <linux/watchdog.h>
+
+/* Registers */
+#define LPC18XX_WDT_MOD			0x00
+#define LPC18XX_WDT_MOD_WDEN		BIT(0)
+#define LPC18XX_WDT_MOD_WDRESET		BIT(1)
+
+#define LPC18XX_WDT_TC			0x04
+#define LPC18XX_WDT_TC_MIN		0xff
+#define LPC18XX_WDT_TC_MAX		0xffffff
+
+#define LPC18XX_WDT_FEED		0x08
+#define LPC18XX_WDT_FEED_MAGIC1		0xaa
+#define LPC18XX_WDT_FEED_MAGIC2		0x55
+
+#define LPC18XX_WDT_TV			0x0c
+
+/* Clock pre-scaler */
+#define LPC18XX_WDT_CLK_DIV		4
+
+/* Timeout values in seconds */
+#define LPC18XX_WDT_DEF_TIMEOUT		30U
+
+static int heartbeat;
+module_param(heartbeat, int, 0);
+MODULE_PARM_DESC(heartbeat, "Watchdog heartbeats in seconds (default="
+		 __MODULE_STRING(LPC18XX_WDT_DEF_TIMEOUT) ")");
+
+static bool nowayout = WATCHDOG_NOWAYOUT;
+module_param(nowayout, bool, 0);
+MODULE_PARM_DESC(nowayout, "Watchdog cannot be stopped once started (default="
+		 __MODULE_STRING(WATCHDOG_NOWAYOUT) ")");
+
+struct lpc18xx_wdt_dev {
+	struct watchdog_device	wdt_dev;
+	struct clk		*reg_clk;
+	struct clk		*wdt_clk;
+	unsigned long		clk_rate;
+	void __iomem		*base;
+	struct timer_list	timer;
+	struct notifier_block	restart_handler;
+	spinlock_t		lock;
+};
+
+static int lpc18xx_wdt_feed(struct watchdog_device *wdt_dev)
+{
+	struct lpc18xx_wdt_dev *lpc18xx_wdt = watchdog_get_drvdata(wdt_dev);
+	unsigned long flags;
+
+	/*
+	 * An abort condition will occur if an interrupt happens during the feed
+	 * sequence.
+	 */
+	spin_lock_irqsave(&lpc18xx_wdt->lock, flags);
+	writel(LPC18XX_WDT_FEED_MAGIC1, lpc18xx_wdt->base + LPC18XX_WDT_FEED);
+	writel(LPC18XX_WDT_FEED_MAGIC2, lpc18xx_wdt->base + LPC18XX_WDT_FEED);
+	spin_unlock_irqrestore(&lpc18xx_wdt->lock, flags);
+
+	return 0;
+}
+
+static void lpc18xx_wdt_timer_feed(unsigned long data)
+{
+	struct watchdog_device *wdt_dev = (struct watchdog_device *)data;
+	struct lpc18xx_wdt_dev *lpc18xx_wdt = watchdog_get_drvdata(wdt_dev);
+
+	lpc18xx_wdt_feed(wdt_dev);
+
+	/* Use safe value (1/2 of real timeout) */
+	mod_timer(&lpc18xx_wdt->timer, jiffies +
+		  msecs_to_jiffies((wdt_dev->timeout * MSEC_PER_SEC) / 2));
+}
+
+/*
+ * Since LPC18xx Watchdog cannot be disabled in hardware, we must keep feeding
+ * it with a timer until userspace watchdog software takes over.
+ */
+static int lpc18xx_wdt_stop(struct watchdog_device *wdt_dev)
+{
+	lpc18xx_wdt_timer_feed((unsigned long)wdt_dev);
+
+	return 0;
+}
+
+static void __lpc18xx_wdt_set_timeout(struct lpc18xx_wdt_dev *lpc18xx_wdt)
+{
+	unsigned int val;
+
+	val = DIV_ROUND_UP(lpc18xx_wdt->wdt_dev.timeout * lpc18xx_wdt->clk_rate,
+			   LPC18XX_WDT_CLK_DIV);
+	writel(val, lpc18xx_wdt->base + LPC18XX_WDT_TC);
+}
+
+static int lpc18xx_wdt_set_timeout(struct watchdog_device *wdt_dev,
+				   unsigned int new_timeout)
+{
+	struct lpc18xx_wdt_dev *lpc18xx_wdt = watchdog_get_drvdata(wdt_dev);
+
+	lpc18xx_wdt->wdt_dev.timeout = new_timeout;
+	__lpc18xx_wdt_set_timeout(lpc18xx_wdt);
+
+	return 0;
+}
+
+unsigned int lpc18xx_wdt_get_timeleft(struct watchdog_device *wdt_dev)
+{
+	struct lpc18xx_wdt_dev *lpc18xx_wdt = watchdog_get_drvdata(wdt_dev);
+	unsigned int val;
+
+	val = readl(lpc18xx_wdt->base + LPC18XX_WDT_TV);
+	return (val * LPC18XX_WDT_CLK_DIV) / lpc18xx_wdt->clk_rate;
+}
+
+static int lpc18xx_wdt_start(struct watchdog_device *wdt_dev)
+{
+	struct lpc18xx_wdt_dev *lpc18xx_wdt = watchdog_get_drvdata(wdt_dev);
+	unsigned int val;
+
+	if (timer_pending(&lpc18xx_wdt->timer))
+		del_timer(&lpc18xx_wdt->timer);
+
+	val = readl(lpc18xx_wdt->base + LPC18XX_WDT_MOD);
+	val |= LPC18XX_WDT_MOD_WDEN;
+	val |= LPC18XX_WDT_MOD_WDRESET;
+	writel(val, lpc18xx_wdt->base + LPC18XX_WDT_MOD);
+
+	/*
+	 * Setting the WDEN bit in the WDMOD register is not sufficient to
+	 * enable the Watchdog. A valid feed sequence must be completed after
+	 * setting WDEN before the Watchdog is capable of generating a reset.
+	 */
+	lpc18xx_wdt_feed(wdt_dev);
+
+	return 0;
+}
+
+static struct watchdog_info lpc18xx_wdt_info = {
+	.identity	= "NXP LPC18xx Watchdog",
+	.options	= WDIOF_SETTIMEOUT |
+			  WDIOF_KEEPALIVEPING |
+			  WDIOF_MAGICCLOSE,
+};
+
+static const struct watchdog_ops lpc18xx_wdt_ops = {
+	.owner		= THIS_MODULE,
+	.start		= lpc18xx_wdt_start,
+	.stop		= lpc18xx_wdt_stop,
+	.ping		= lpc18xx_wdt_feed,
+	.set_timeout	= lpc18xx_wdt_set_timeout,
+	.get_timeleft	= lpc18xx_wdt_get_timeleft,
+};
+
+static int lpc18xx_wdt_restart(struct notifier_block *this, unsigned long mode,
+			       void *cmd)
+{
+	struct lpc18xx_wdt_dev *lpc18xx_wdt = container_of(this,
+				struct lpc18xx_wdt_dev, restart_handler);
+	unsigned long flags;
+	int val;
+
+	/*
+	 * Incorrect feed sequence causes immediate watchdog reset if enabled.
+	 */
+	spin_lock_irqsave(&lpc18xx_wdt->lock, flags);
+
+	val = readl(lpc18xx_wdt->base + LPC18XX_WDT_MOD);
+	val |= LPC18XX_WDT_MOD_WDEN;
+	val |= LPC18XX_WDT_MOD_WDRESET;
+	writel(val, lpc18xx_wdt->base + LPC18XX_WDT_MOD);
+
+	writel(LPC18XX_WDT_FEED_MAGIC1, lpc18xx_wdt->base + LPC18XX_WDT_FEED);
+	writel(LPC18XX_WDT_FEED_MAGIC2, lpc18xx_wdt->base + LPC18XX_WDT_FEED);
+
+	writel(LPC18XX_WDT_FEED_MAGIC1, lpc18xx_wdt->base + LPC18XX_WDT_FEED);
+	writel(LPC18XX_WDT_FEED_MAGIC1, lpc18xx_wdt->base + LPC18XX_WDT_FEED);
+
+	spin_unlock_irqrestore(&lpc18xx_wdt->lock, flags);
+
+	return NOTIFY_OK;
+}
+
+static int lpc18xx_wdt_probe(struct platform_device *pdev)
+{
+	struct lpc18xx_wdt_dev *lpc18xx_wdt;
+	struct device *dev = &pdev->dev;
+	struct resource *res;
+	int ret;
+
+	lpc18xx_wdt = devm_kzalloc(dev, sizeof(*lpc18xx_wdt), GFP_KERNEL);
+	if (!lpc18xx_wdt)
+		return -ENOMEM;
+
+	res = platform_get_resource(pdev, IORESOURCE_MEM, 0);
+	lpc18xx_wdt->base = devm_ioremap_resource(dev, res);
+	if (IS_ERR(lpc18xx_wdt->base))
+		return PTR_ERR(lpc18xx_wdt->base);
+
+	lpc18xx_wdt->reg_clk = devm_clk_get(dev, "reg");
+	if (IS_ERR(lpc18xx_wdt->reg_clk)) {
+		dev_err(dev, "failed to get the reg clock\n");
+		return PTR_ERR(lpc18xx_wdt->reg_clk);
+	}
+
+	lpc18xx_wdt->wdt_clk = devm_clk_get(dev, "wdtclk");
+	if (IS_ERR(lpc18xx_wdt->wdt_clk)) {
+		dev_err(dev, "failed to get the wdt clock\n");
+		return PTR_ERR(lpc18xx_wdt->wdt_clk);
+	}
+
+	ret = clk_prepare_enable(lpc18xx_wdt->reg_clk);
+	if (ret) {
+		dev_err(dev, "could not prepare or enable sys clock\n");
+		return ret;
+	}
+
+	ret = clk_prepare_enable(lpc18xx_wdt->wdt_clk);
+	if (ret) {
+		dev_err(dev, "could not prepare or enable wdt clock\n");
+		goto disable_reg_clk;
+	}
+
+	/* We use the clock rate to calculate timeouts */
+	lpc18xx_wdt->clk_rate = clk_get_rate(lpc18xx_wdt->wdt_clk);
+	if (lpc18xx_wdt->clk_rate == 0) {
+		dev_err(dev, "failed to get clock rate\n");
+		ret = -EINVAL;
+		goto disable_wdt_clk;
+	}
+
+	lpc18xx_wdt->wdt_dev.info = &lpc18xx_wdt_info;
+	lpc18xx_wdt->wdt_dev.ops = &lpc18xx_wdt_ops;
+
+	lpc18xx_wdt->wdt_dev.min_timeout = DIV_ROUND_UP(LPC18XX_WDT_TC_MIN *
+				LPC18XX_WDT_CLK_DIV, lpc18xx_wdt->clk_rate);
+
+	lpc18xx_wdt->wdt_dev.max_timeout = (LPC18XX_WDT_TC_MAX *
+				LPC18XX_WDT_CLK_DIV) / lpc18xx_wdt->clk_rate;
+
+	lpc18xx_wdt->wdt_dev.timeout = min(lpc18xx_wdt->wdt_dev.max_timeout,
+					   LPC18XX_WDT_DEF_TIMEOUT);
+
+	spin_lock_init(&lpc18xx_wdt->lock);
+
+	lpc18xx_wdt->wdt_dev.parent = dev;
+	watchdog_set_drvdata(&lpc18xx_wdt->wdt_dev, lpc18xx_wdt);
+
+	ret = watchdog_init_timeout(&lpc18xx_wdt->wdt_dev, heartbeat, dev);
+
+	__lpc18xx_wdt_set_timeout(lpc18xx_wdt);
+
+	setup_timer(&lpc18xx_wdt->timer, lpc18xx_wdt_timer_feed,
+		    (unsigned long)&lpc18xx_wdt->wdt_dev);
+
+	watchdog_set_nowayout(&lpc18xx_wdt->wdt_dev, nowayout);
+
+	platform_set_drvdata(pdev, lpc18xx_wdt);
+
+	ret = watchdog_register_device(&lpc18xx_wdt->wdt_dev);
+	if (ret)
+		goto disable_wdt_clk;
+
+	lpc18xx_wdt->restart_handler.notifier_call = lpc18xx_wdt_restart;
+	lpc18xx_wdt->restart_handler.priority = 128;
+	ret = register_restart_handler(&lpc18xx_wdt->restart_handler);
+	if (ret)
+		dev_warn(dev, "failed to register restart handler: %d\n", ret);
+
+	return 0;
+
+disable_wdt_clk:
+	clk_disable_unprepare(lpc18xx_wdt->wdt_clk);
+disable_reg_clk:
+	clk_disable_unprepare(lpc18xx_wdt->reg_clk);
+	return ret;
+}
+
+static void lpc18xx_wdt_shutdown(struct platform_device *pdev)
+{
+	struct lpc18xx_wdt_dev *lpc18xx_wdt = platform_get_drvdata(pdev);
+
+	lpc18xx_wdt_stop(&lpc18xx_wdt->wdt_dev);
+}
+
+static int lpc18xx_wdt_remove(struct platform_device *pdev)
+{
+	struct lpc18xx_wdt_dev *lpc18xx_wdt = platform_get_drvdata(pdev);
+
+	unregister_restart_handler(&lpc18xx_wdt->restart_handler);
+
+	dev_warn(&pdev->dev, "I quit now, hardware will probably reboot!\n");
+	del_timer(&lpc18xx_wdt->timer);
+
+	watchdog_unregister_device(&lpc18xx_wdt->wdt_dev);
+	clk_disable_unprepare(lpc18xx_wdt->wdt_clk);
+	clk_disable_unprepare(lpc18xx_wdt->reg_clk);
+
+	return 0;
+}
+
+static const struct of_device_id lpc18xx_wdt_match[] = {
+	{ .compatible = "nxp,lpc1850-wwdt" },
+	{}
+};
+MODULE_DEVICE_TABLE(of, lpc18xx_wdt_match);
+
+static struct platform_driver lpc18xx_wdt_driver = {
+	.driver = {
+		.name = "lpc18xx-wdt",
+		.of_match_table	= lpc18xx_wdt_match,
+	},
+	.probe = lpc18xx_wdt_probe,
+	.remove = lpc18xx_wdt_remove,
+	.shutdown = lpc18xx_wdt_shutdown,
+};
+module_platform_driver(lpc18xx_wdt_driver);
+
+MODULE_AUTHOR("Ariel D'Alessandro <ariel at vanguardiasur.com.ar>");
+MODULE_DESCRIPTION("NXP LPC18xx Watchdog Timer Driver");
+MODULE_LICENSE("GPL v2");
-- 
1.9.1



From ariel at vanguardiasur.com.ar  Sat Aug  1 11:37:17 2015
From: ariel at vanguardiasur.com.ar (Ariel D'Alessandro)
Date: Sat,  1 Aug 2015 15:37:17 -0300
Subject: [PATCH v5 2/2] DT: watchdog: Add NXP LPC18xx Watchdog Timer binding
 documentation
In-Reply-To: <1438454237-22043-1-git-send-email-ariel@vanguardiasur.com.ar>
References: <1438454237-22043-1-git-send-email-ariel@vanguardiasur.com.ar>
Message-ID: <1438454237-22043-3-git-send-email-ariel@vanguardiasur.com.ar>

Add the devicetree binding document for NXP LPC18xx Watchdog Timer.

Signed-off-by: Ariel D'Alessandro <ariel at vanguardiasur.com.ar>
---
 .../devicetree/bindings/watchdog/lpc18xx-wdt.txt      | 19 +++++++++++++++++++
 1 file changed, 19 insertions(+)
 create mode 100644 Documentation/devicetree/bindings/watchdog/lpc18xx-wdt.txt

diff --git a/Documentation/devicetree/bindings/watchdog/lpc18xx-wdt.txt b/Documentation/devicetree/bindings/watchdog/lpc18xx-wdt.txt
new file mode 100644
index 0000000..09f6b24
--- /dev/null
+++ b/Documentation/devicetree/bindings/watchdog/lpc18xx-wdt.txt
@@ -0,0 +1,19 @@
+* NXP LPC18xx Watchdog Timer (WDT)
+
+Required properties:
+- compatible: Should be "nxp,lpc1850-wwdt"
+- reg: Should contain WDT registers location and length
+- clocks: Must contain an entry for each entry in clock-names.
+- clock-names: Should contain "wdtclk" and "reg"; the watchdog counter
+               clock and register interface clock respectively.
+- interrupts: Should contain WDT interrupt
+
+Examples:
+
+watchdog at 40080000 {
+	compatible = "nxp,lpc1850-wwdt";
+	reg = <0x40080000 0x24>;
+	clocks = <&cgu BASE_SAFE_CLK>, <&ccu1 CLK_CPU_WWDT>;
+	clock-names = "wdtclk", "reg";
+	interrupts = <49>;
+};
-- 
1.9.1



From linux at roeck-us.net  Sat Aug  1 11:52:00 2015
From: linux at roeck-us.net (Guenter Roeck)
Date: Sat, 01 Aug 2015 11:52:00 -0700
Subject: [PATCH v5 1/2] watchdog: NXP LPC18xx Watchdog Timer Driver
In-Reply-To: <1438454237-22043-2-git-send-email-ariel@vanguardiasur.com.ar>
References: <1438454237-22043-1-git-send-email-ariel@vanguardiasur.com.ar>
 <1438454237-22043-2-git-send-email-ariel@vanguardiasur.com.ar>
Message-ID: <55BD1550.708@roeck-us.net>

On 08/01/2015 11:37 AM, Ariel D'Alessandro wrote:
> This commit adds support for the watchdog timer found in NXP LPC SoCs
> family, which includes LPC18xx/LPC43xx. Other SoCs in that family may
> share the same watchdog hardware.
>
> Watchdog driver registers a restart handler that will restart the system
> by performing an incorrect feed after ensuring the watchdog is enabled in
> reset mode.
>
> As watchdog cannot be disabled in hardware, driver's stop routine will
> regularly send a keepalive ping using a timer.
>
> Signed-off-by: Ariel D'Alessandro <ariel at vanguardiasur.com.ar>

Reviewed-by: Guenter Roeck <linux at roeck-us.net>



From linux at roeck-us.net  Sat Aug  1 11:52:45 2015
From: linux at roeck-us.net (Guenter Roeck)
Date: Sat, 01 Aug 2015 11:52:45 -0700
Subject: [PATCH v5 2/2] DT: watchdog: Add NXP LPC18xx Watchdog Timer
 binding documentation
In-Reply-To: <1438454237-22043-3-git-send-email-ariel@vanguardiasur.com.ar>
References: <1438454237-22043-1-git-send-email-ariel@vanguardiasur.com.ar>
 <1438454237-22043-3-git-send-email-ariel@vanguardiasur.com.ar>
Message-ID: <55BD157D.2020404@roeck-us.net>

On 08/01/2015 11:37 AM, Ariel D'Alessandro wrote:
> Add the devicetree binding document for NXP LPC18xx Watchdog Timer.
>
> Signed-off-by: Ariel D'Alessandro <ariel at vanguardiasur.com.ar>

Reviewed-by: Guenter Roeck <linux at roeck-us.net>




From arnd at arndb.de  Sat Aug  1 14:08:06 2015
From: arnd at arndb.de (Arnd Bergmann)
Date: Sat, 01 Aug 2015 23:08:06 +0200
Subject: [RFC] arm64: defconfig: enable 48-bit VA by default
In-Reply-To: <CAKv+Gu88g7o8+BzK9TtZVmq9+n8uK7GzbMJUygTbgZ9Pf1_1cw@mail.gmail.com>
References: <CY1PR0301MB07488D6DC5F0B171D6B290E187830@CY1PR0301MB0748.namprd03.prod.outlook.com>
 <20150731132238.GP407@e104818-lin.cambridge.arm.com>
 <CAKv+Gu88g7o8+BzK9TtZVmq9+n8uK7GzbMJUygTbgZ9Pf1_1cw@mail.gmail.com>
Message-ID: <1524396.PS7zpagrm1@wuerfel>

On Friday 31 July 2015 15:30:23 Ard Biesheuvel wrote:
> On 31 July 2015 at 15:22, Catalin Marinas <catalin.marinas at arm.com> wrote:
> >> > I tried something like that for RealView PBX in the past but it was
> >> > hard-coded (no multi-platform at the time). See
> >> > arch/arm/mach-realview/include/mach/memory.h.
> >>
> >> Yes, that looks vaguely like what I had in mind.
> >>
> >> IOW, we could partition the direct mapping just like the ARM
> >> recommendation, i.e.,
> >>
> >> 0 - 2 GB
> >> 2 - 32 GB
> >> 32 - 512 GB
> >>
> >> but default to 1:1 correspondence, so that
> >>
> >> PHYS_OFFSET = PHYS_OFFSET0 = memstart_addr
> >> PHYS_OFFSET1 = memstart_addr + 2 GB
> >> PHYS_OFFSET2 = memstart_addr + 32 GB
> >>
> >> and only if the ARM recommended physical memory map is detected (with
> >> memstart_addr @ 0x8000_0000), switch to
> >>
> >> PHYS_OFFSET = PHYS_OFFSET0 = memstart_addr
> >> PHYS_OFFSET1 = memstart_addr + 30 GB
> >> PHYS_OFFSET2 = memstart_addr + 480 GB
> >
> > I don't really like such complexity when all you need on arm64 is to
> > enable 48-bit VA (though it would be interesting to benchmark it).

More importantly, hardwiring this in virt_to_phys() would mean we can
no longer run a kernel with this hack turned on with systems that have
contiguous memory or any other layout besides the one from the document.

I also don't think it's a huge issue. On systems with lots of RAM,
you want the 48-bit VA space anyway to run things like databases
(which tend to mmap large files) efficiently, so all distros will
use that anyway (except the crazy ones that use 64kb pages and
also don't have the problem), and anyone with less than 32GB can
live with 3-leval tables if they run a custom kernel.

> >> I guess such a special case would be out of the question for one-off
> >> crazy designs like Freescale, but since this is the layout recommended
> >> by ARM itself, I suppose we could try and support it a bit better.
> >
> > I'm trying to get the layout fixed before it spreads any further ;).
> 
> Yes, that would be even better.

+1

	Arnd


From arnd at arndb.de  Sat Aug  1 14:28:19 2015
From: arnd at arndb.de (Arnd Bergmann)
Date: Sat, 01 Aug 2015 23:28:19 +0200
Subject: [PATCH] dmaengine: xgene-dma: Add ACPI support for X-Gene DMA
 engine driver
In-Reply-To: <CAFd313xntHx7JhfTWSsJo+bTm-DuEcbAzqXt9in1s0irL3g7sw@mail.gmail.com>
References: <1437484479-2822-1-git-send-email-rsahu@apm.com>
 <2384915.JHlOHWBXHy@wuerfel>
 <CAFd313xntHx7JhfTWSsJo+bTm-DuEcbAzqXt9in1s0irL3g7sw@mail.gmail.com>
Message-ID: <2216844.XmXxxWVjii@wuerfel>

On Thursday 30 July 2015 14:21:07 Rameshwar Sahu wrote:
> Hi Arnd,
> 
> On Wed, Jul 29, 2015 at 8:04 PM, Arnd Bergmann <arnd at arndb.de> wrote:
> > On Tuesday 21 July 2015 18:44:39 Rameshwar Prasad Sahu wrote:
> >> This patch adds ACPI support for the APM X-Gene DMA engine driver.
> >>
> >> Signed-off-by: Rameshwar Prasad Sahu <rsahu at apm.com>
> >>
> >
> > How does a slave driver refer to a channel in case of ACPI?
> 
> We don't support slave dma here. This driver supports only memcp, xor,
> pq, scatter-gather offloading, so,
> client driver can use linux dmaengine APIs like dma_request_channel()
> etc to request channel.

Ok, makes sense. Thanks!

	Arnd


From dianders at chromium.org  Sat Aug  1 14:32:32 2015
From: dianders at chromium.org (Doug Anderson)
Date: Sat, 1 Aug 2015 14:32:32 -0700
Subject: [PATCH 1/2] ARM: dts: rockchip: reserve unusable memory region on
 rk3288
In-Reply-To: <15143985.aGzb1oeyb9@diego>
References: <15143985.aGzb1oeyb9@diego>
Message-ID: <CAD=FV=W2LSQh4e9+=ooTf34VzM_yPZn497DqSVEdb1kehZbqQQ@mail.gmail.com>

Heiko

On Sat, Aug 1, 2015 at 5:35 AM, Heiko St?bner <heiko at sntech.de> wrote:
> The rk3288 has problems accessing the memory region 0xfe000000~0xff000000.
> So block off the affected region to prevent its use.
>
> Tested on 4GB Veyron Minnie and 2GB Veyron Jerry devices.
>
> Signed-off-by: Heiko Stuebner <heiko at sntech.de>
> ---
>  arch/arm/boot/dts/rk3288.dtsi | 10 ++++++++++
>  1 file changed, 10 insertions(+)
>
> diff --git a/arch/arm/boot/dts/rk3288.dtsi b/arch/arm/boot/dts/rk3288.dtsi
> index 2db91c9..19766af 100644
> --- a/arch/arm/boot/dts/rk3288.dtsi
> +++ b/arch/arm/boot/dts/rk3288.dtsi
> @@ -169,6 +169,16 @@
>                 };
>         };
>
> +       reserved-memory {
> +               #address-cells = <1>;
> +               #size-cells = <1>;
> +               ranges;
> +
> +               unusable at fe000000 {
> +                       reg = <0xfe000000 0x1000000>;
> +               };
> +       };
> +

I don't object to just reserving this memory, but I do object a little
to this implementation.

It's 16 MB we're talking about here, which is pretty small compared to
the 4G of memory that you must have when this is a problem.  However,
at some point we might want to try to actually use this 16 MB.

The memory is actually _not_ unusable, it's only unusable for DMA.  In
theory the kernel is supposed to have a way to mark memory as unusable
for DMA which would then allow us to use this memory for non-DMA
purposes...

Nobody ever managed to figure this out in the Chrome OS tree (it was
16 megs so we just reserved it and never got back around to it), but
when folks were looking at it they looked at things like ZONE_DMA,
dma_set_mask_and_coherent, etc.

In any case, to leave the door open for people to fix this in the
future, it seems prudent to fix this in code like
<https://chromium-review.googlesource.com/#/c/245107/> rather than to
put the limit in DTS.

-Doug


From hermr2d2 at gmail.com  Sat Aug  1 15:06:31 2015
From: hermr2d2 at gmail.com (Hermann Kraus)
Date: Sun, 02 Aug 2015 00:06:31 +0200
Subject: [PATCH] spi: spi-sun4i, spi-sun6i: Fix bit rate calculation
Message-ID: <op.x2pmc5kiltbbtz@localhost>

Use requested bit rate instead of maximum possible and correctly calculate
the divider.

There are two different maximum bitrates. "max_speed_hz" which is the  
maximum
for a given SPI device and "speed_hz" in "struct spi_transfer" which is  
the rate
used for this transfer. If "speed_hz" is non-zero it must be used.
The divider must be calculated by calling ilog2 only once, because this  
function
truncates the fractional part. Calling it twice increases the error so  
much that
certain bit rates which are available from the hardware can't be reached by
the kernel.
The result of this calculation must be checked to fit into the register  
size
instead of being truncated silently.

Signed-off-by: Hermann Kraus <hermr2d2 at gmail.com>
---
  drivers/spi/spi-sun4i.c | 16 ++++++++++++----
  drivers/spi/spi-sun6i.c | 16 ++++++++++++----
  2 files changed, 24 insertions(+), 8 deletions(-)

diff --git a/drivers/spi/spi-sun4i.c b/drivers/spi/spi-sun4i.c
index fbb0a4d..82d717d 100644
--- a/drivers/spi/spi-sun4i.c
+++ b/drivers/spi/spi-sun4i.c
@@ -173,6 +173,7 @@ static int sun4i_spi_transfer_one(struct spi_master  
*master,
  	unsigned int tx_len = 0;
  	int ret = 0;
  	u32 reg;
+	u32 speed_hz = tfr->speed_hz ? : spi->max_speed_hz;

  	/* We don't support transfer larger than the FIFO */
  	if (tfr->len > SUN4I_FIFO_DEPTH)
@@ -229,8 +230,8 @@ static int sun4i_spi_transfer_one(struct spi_master  
*master,

  	/* Ensure that we have a parent clock fast enough */
  	mclk_rate = clk_get_rate(sspi->mclk);
-	if (mclk_rate < (2 * spi->max_speed_hz)) {
-		clk_set_rate(sspi->mclk, 2 * spi->max_speed_hz);
+	if (mclk_rate < (2 * speed_hz)) {
+		clk_set_rate(sspi->mclk, 2 * speed_hz);
  		mclk_rate = clk_get_rate(sspi->mclk);
  	}

@@ -248,14 +249,21 @@ static int sun4i_spi_transfer_one(struct spi_master  
*master,
  	 * First try CDR2, and if we can't reach the expected
  	 * frequency, fall back to CDR1.
  	 */
-	div = mclk_rate / (2 * spi->max_speed_hz);
+	div = mclk_rate / (2 * speed_hz);
  	if (div <= (SUN4I_CLK_CTL_CDR2_MASK + 1)) {
  		if (div > 0)
  			div--;

  		reg = SUN4I_CLK_CTL_CDR2(div) | SUN4I_CLK_CTL_DRS;
  	} else {
-		div = ilog2(mclk_rate) - ilog2(spi->max_speed_hz);
+		/* ilog2 truncates the fractional part. Therefore we don't
+		 * subtract 1 from the result. */
+		div = ilog2(mclk_rate / speed_hz + 1);
+		if (div & ~SUN4I_CLK_CTL_CDR1_MASK) {
+			/* Can't reach low enough bit rate. */
+			ret = -EINVAL;
+			goto out;
+		}
  		reg = SUN4I_CLK_CTL_CDR1(div);
  	}

diff --git a/drivers/spi/spi-sun6i.c b/drivers/spi/spi-sun6i.c
index ac48f59..c3870be 100644
--- a/drivers/spi/spi-sun6i.c
+++ b/drivers/spi/spi-sun6i.c
@@ -163,6 +163,7 @@ static int sun6i_spi_transfer_one(struct spi_master  
*master,
  	unsigned int tx_len = 0;
  	int ret = 0;
  	u32 reg;
+	u32 speed_hz = tfr->speed_hz ? : spi->max_speed_hz;

  	/* We don't support transfer larger than the FIFO */
  	if (tfr->len > SUN6I_FIFO_DEPTH)
@@ -217,8 +218,8 @@ static int sun6i_spi_transfer_one(struct spi_master  
*master,

  	/* Ensure that we have a parent clock fast enough */
  	mclk_rate = clk_get_rate(sspi->mclk);
-	if (mclk_rate < (2 * spi->max_speed_hz)) {
-		clk_set_rate(sspi->mclk, 2 * spi->max_speed_hz);
+	if (mclk_rate < (2 * speed_hz)) {
+		clk_set_rate(sspi->mclk, 2 * speed_hz);
  		mclk_rate = clk_get_rate(sspi->mclk);
  	}

@@ -236,14 +237,21 @@ static int sun6i_spi_transfer_one(struct spi_master  
*master,
  	 * First try CDR2, and if we can't reach the expected
  	 * frequency, fall back to CDR1.
  	 */
-	div = mclk_rate / (2 * spi->max_speed_hz);
+	div = mclk_rate / (2 * speed_hz);
  	if (div <= (SUN6I_CLK_CTL_CDR2_MASK + 1)) {
  		if (div > 0)
  			div--;

  		reg = SUN6I_CLK_CTL_CDR2(div) | SUN6I_CLK_CTL_DRS;
  	} else {
-		div = ilog2(mclk_rate) - ilog2(spi->max_speed_hz);
+		/* ilog2 truncates the fractional part. Therefore we don't
+		 * subtract 1 from the result. */
+		div = ilog2(mclk_rate / speed_hz + 1);
+		if (div & ~SUN6I_CLK_CTL_CDR1_MASK) {
+			/* Can't reach low enough bit rate. */
+			ret = -EINVAL;
+			goto out;
+		}
  		reg = SUN6I_CLK_CTL_CDR1(div);
  	}

-- 
2.1.4


From heiko at sntech.de  Sat Aug  1 15:52:44 2015
From: heiko at sntech.de (Heiko =?ISO-8859-1?Q?St=FCbner?=)
Date: Sun, 02 Aug 2015 00:52:44 +0200
Subject: [PATCH 1/2] ARM: dts: rockchip: reserve unusable memory region on
 rk3288
In-Reply-To: <CAD=FV=W2LSQh4e9+=ooTf34VzM_yPZn497DqSVEdb1kehZbqQQ@mail.gmail.com>
References: <15143985.aGzb1oeyb9@diego>
 <CAD=FV=W2LSQh4e9+=ooTf34VzM_yPZn497DqSVEdb1kehZbqQQ@mail.gmail.com>
Message-ID: <4605286.lfFsCUY5jc@diego>

Hi Doug,

Am Samstag, 1. August 2015, 14:32:32 schrieb Doug Anderson:
> On Sat, Aug 1, 2015 at 5:35 AM, Heiko St?bner <heiko at sntech.de> wrote:
> > The rk3288 has problems accessing the memory region 0xfe000000~0xff000000.
> > So block off the affected region to prevent its use.
> > 
> > Tested on 4GB Veyron Minnie and 2GB Veyron Jerry devices.
> > 
> > Signed-off-by: Heiko Stuebner <heiko at sntech.de>
> > ---
> > 
> >  arch/arm/boot/dts/rk3288.dtsi | 10 ++++++++++
> >  1 file changed, 10 insertions(+)
> > 
> > diff --git a/arch/arm/boot/dts/rk3288.dtsi b/arch/arm/boot/dts/rk3288.dtsi
> > index 2db91c9..19766af 100644
> > --- a/arch/arm/boot/dts/rk3288.dtsi
> > +++ b/arch/arm/boot/dts/rk3288.dtsi
> > @@ -169,6 +169,16 @@
> > 
> >                 };
> >         
> >         };
> > 
> > +       reserved-memory {
> > +               #address-cells = <1>;
> > +               #size-cells = <1>;
> > +               ranges;
> > +
> > +               unusable at fe000000 {
> > +                       reg = <0xfe000000 0x1000000>;
> > +               };
> > +       };
> > +
> 
> I don't object to just reserving this memory, but I do object a little
> to this implementation.
> 
> It's 16 MB we're talking about here, which is pretty small compared to
> the 4G of memory that you must have when this is a problem.  However,
> at some point we might want to try to actually use this 16 MB.
> 
> The memory is actually _not_ unusable, it's only unusable for DMA.  In
> theory the kernel is supposed to have a way to mark memory as unusable
> for DMA which would then allow us to use this memory for non-DMA
> purposes...

Ok, the patch message in the chromeos-patch didn't mention dma, but I could've 
thought of that myself, sorry.


> Nobody ever managed to figure this out in the Chrome OS tree (it was
> 16 megs so we just reserved it and never got back around to it), but
> when folks were looking at it they looked at things like ZONE_DMA,
> dma_set_mask_and_coherent, etc.
> 
> In any case, to leave the door open for people to fix this in the
> future, it seems prudent to fix this in code like
> <https://chromium-review.googlesource.com/#/c/245107/> rather than to
> put the limit in DTS.


The dt code when creating the platform-devices assumes a 32bit dma mask and 
expects the drivers to set the correct dma_masks (in of_dma_configure). But 
from the original description this looks more like a limitation of the rk3288, 
not the individual dwmmc, dwc2, etc.

So from my cursory glance, ZONE_DMA seems to be the best solution. As you said 
that this was investigated too, do you know if they encountered any obstacles 
that resulted in not adjusting the dma zone?


@Jeffy: do you know how widespread this is? I.e. are socs like the rk3128 or 
possibly more importantly the rk3368 also affected by this in 4GB 
configurations?


If the rk3368 does it too, this might get "interesting". In one of the mails 
about ZONE_DMA from september 2014, Arnd mentioned that there was a patch 
about getting the zone size from devicetree floating around, but it doesn't 
look like this landed.


Heiko


From heiko at sntech.de  Sat Aug  1 16:13:08 2015
From: heiko at sntech.de (Heiko =?ISO-8859-1?Q?St=FCbner?=)
Date: Sun, 02 Aug 2015 01:13:08 +0200
Subject: [PATCH 1/2] ARM: dts: rockchip: reserve unusable memory region on
 rk3288
In-Reply-To: <4605286.lfFsCUY5jc@diego>
References: <15143985.aGzb1oeyb9@diego>
 <CAD=FV=W2LSQh4e9+=ooTf34VzM_yPZn497DqSVEdb1kehZbqQQ@mail.gmail.com>
 <4605286.lfFsCUY5jc@diego>
Message-ID: <1634487.FDgX1HIOR2@diego>

Am Sonntag, 2. August 2015, 00:52:44 schrieb Heiko St?bner:
> Hi Doug,
> 
> Am Samstag, 1. August 2015, 14:32:32 schrieb Doug Anderson:
> > On Sat, Aug 1, 2015 at 5:35 AM, Heiko St?bner <heiko at sntech.de> wrote:
> > > The rk3288 has problems accessing the memory region
> > > 0xfe000000~0xff000000.
> > > So block off the affected region to prevent its use.
> > > 
> > > Tested on 4GB Veyron Minnie and 2GB Veyron Jerry devices.
> > > 
> > > Signed-off-by: Heiko Stuebner <heiko at sntech.de>
> > > ---
> > > 
> > >  arch/arm/boot/dts/rk3288.dtsi | 10 ++++++++++
> > >  1 file changed, 10 insertions(+)
> > > 
> > > diff --git a/arch/arm/boot/dts/rk3288.dtsi
> > > b/arch/arm/boot/dts/rk3288.dtsi
> > > index 2db91c9..19766af 100644
> > > --- a/arch/arm/boot/dts/rk3288.dtsi
> > > +++ b/arch/arm/boot/dts/rk3288.dtsi
> > > @@ -169,6 +169,16 @@
> > > 
> > >                 };
> > >         
> > >         };
> > > 
> > > +       reserved-memory {
> > > +               #address-cells = <1>;
> > > +               #size-cells = <1>;
> > > +               ranges;
> > > +
> > > +               unusable at fe000000 {
> > > +                       reg = <0xfe000000 0x1000000>;
> > > +               };
> > > +       };
> > > +
> > 
> > I don't object to just reserving this memory, but I do object a little
> > to this implementation.
> > 
> > It's 16 MB we're talking about here, which is pretty small compared to
> > the 4G of memory that you must have when this is a problem.  However,
> > at some point we might want to try to actually use this 16 MB.
> > 
> > The memory is actually _not_ unusable, it's only unusable for DMA.  In
> > theory the kernel is supposed to have a way to mark memory as unusable
> > for DMA which would then allow us to use this memory for non-DMA
> > purposes...
> 
> Ok, the patch message in the chromeos-patch didn't mention dma, but I
> could've thought of that myself, sorry.
> 
> > Nobody ever managed to figure this out in the Chrome OS tree (it was
> > 16 megs so we just reserved it and never got back around to it), but
> > when folks were looking at it they looked at things like ZONE_DMA,
> > dma_set_mask_and_coherent, etc.
> > 
> > In any case, to leave the door open for people to fix this in the
> > future, it seems prudent to fix this in code like
> > <https://chromium-review.googlesource.com/#/c/245107/> rather than to
> > put the limit in DTS.
> 
> The dt code when creating the platform-devices assumes a 32bit dma mask and
> expects the drivers to set the correct dma_masks (in of_dma_configure). But
> from the original description this looks more like a limitation of the
> rk3288, not the individual dwmmc, dwc2, etc.
> 
> So from my cursory glance, ZONE_DMA seems to be the best solution. As you
> said that this was investigated too, do you know if they encountered any
> obstacles that resulted in not adjusting the dma zone?
> 
> 
> @Jeffy: do you know how widespread this is? I.e. are socs like the rk3128 or
> possibly more importantly the rk3368 also affected by this in 4GB
> configurations?
> 
> 
> If the rk3368 does it too, this might get "interesting". In one of the mails
> about ZONE_DMA from september 2014, Arnd mentioned that there was a patch
> about getting the zone size from devicetree floating around, but it doesn't
> look like this landed.

actually the "dma-ranges" property also looks promising (through 
of_dma_get_range() called fromof_dma_configure() )


From wsa at the-dreams.de  Sat Aug  1 18:59:00 2015
From: wsa at the-dreams.de (Wolfram Sang)
Date: Sun, 2 Aug 2015 03:59:00 +0200
Subject: [PATCH V2] i2c: s3c2410: remove unused variable
In-Reply-To: <1437164839-9287-1-git-send-email-laurent.navet@gmail.com>
References: <1437164839-9287-1-git-send-email-laurent.navet@gmail.com>
Message-ID: <20150802015900.GA1726@katana>


> @@ -565,7 +564,7 @@ static int i2c_s3c_irq_nextbyte(struct s3c24xx_i2c *i2c, unsigned long iicstat)
>  	tmp &= ~S3C2410_IICCON_IRQPEND;
>  	writel(tmp, i2c->regs + S3C2410_IICCON);
>   out:
> -	return ret;
> +	return;

What about removing out: and return as well?

-------------- next part --------------
A non-text attachment was scrubbed...
Name: signature.asc
Type: application/pgp-signature
Size: 819 bytes
Desc: Digital signature
URL: <http://lists.infradead.org/pipermail/linux-arm-kernel/attachments/20150802/2360b276/attachment.sig>

From ard.biesheuvel at linaro.org  Sat Aug  1 23:19:07 2015
From: ard.biesheuvel at linaro.org (Ard Biesheuvel)
Date: Sun, 2 Aug 2015 08:19:07 +0200
Subject: [RFC] arm64: defconfig: enable 48-bit VA by default
In-Reply-To: <1524396.PS7zpagrm1@wuerfel>
References: <CY1PR0301MB07488D6DC5F0B171D6B290E187830@CY1PR0301MB0748.namprd03.prod.outlook.com>
 <20150731132238.GP407@e104818-lin.cambridge.arm.com>
 <CAKv+Gu88g7o8+BzK9TtZVmq9+n8uK7GzbMJUygTbgZ9Pf1_1cw@mail.gmail.com>
 <1524396.PS7zpagrm1@wuerfel>
Message-ID: <CAKv+Gu89UGzL9=0tYjQmv9dX7KOsfobpO4zG1E8X0g4W9u5Bkg@mail.gmail.com>

On 1 August 2015 at 23:08, Arnd Bergmann <arnd at arndb.de> wrote:
> On Friday 31 July 2015 15:30:23 Ard Biesheuvel wrote:
>> On 31 July 2015 at 15:22, Catalin Marinas <catalin.marinas at arm.com> wrote:
>> >> > I tried something like that for RealView PBX in the past but it was
>> >> > hard-coded (no multi-platform at the time). See
>> >> > arch/arm/mach-realview/include/mach/memory.h.
>> >>
>> >> Yes, that looks vaguely like what I had in mind.
>> >>
>> >> IOW, we could partition the direct mapping just like the ARM
>> >> recommendation, i.e.,
>> >>
>> >> 0 - 2 GB
>> >> 2 - 32 GB
>> >> 32 - 512 GB
>> >>
>> >> but default to 1:1 correspondence, so that
>> >>
>> >> PHYS_OFFSET = PHYS_OFFSET0 = memstart_addr
>> >> PHYS_OFFSET1 = memstart_addr + 2 GB
>> >> PHYS_OFFSET2 = memstart_addr + 32 GB
>> >>
>> >> and only if the ARM recommended physical memory map is detected (with
>> >> memstart_addr @ 0x8000_0000), switch to
>> >>
>> >> PHYS_OFFSET = PHYS_OFFSET0 = memstart_addr
>> >> PHYS_OFFSET1 = memstart_addr + 30 GB
>> >> PHYS_OFFSET2 = memstart_addr + 480 GB
>> >
>> > I don't really like such complexity when all you need on arm64 is to
>> > enable 48-bit VA (though it would be interesting to benchmark it).
>
> More importantly, hardwiring this in virt_to_phys() would mean we can
> no longer run a kernel with this hack turned on with systems that have
> contiguous memory or any other layout besides the one from the document.
>

Well the hack, if enabled, would be turned on dynamically iff the
exact layout from the recommendation is detected, and the kernel is
loaded right at the base of DRAM.
Note that the first layout I presented is effectively the current
linear mapping, but with three steps.

> I also don't think it's a huge issue. On systems with lots of RAM,
> you want the 48-bit VA space anyway to run things like databases
> (which tend to mmap large files) efficiently, so all distros will
> use that anyway (except the crazy ones that use 64kb pages and
> also don't have the problem), and anyone with less than 32GB can
> live with 3-leval tables if they run a custom kernel.
>
>> >> I guess such a special case would be out of the question for one-off
>> >> crazy designs like Freescale, but since this is the layout recommended
>> >> by ARM itself, I suppose we could try and support it a bit better.
>> >
>> > I'm trying to get the layout fixed before it spreads any further ;).
>>
>> Yes, that would be even better.
>
> +1
>
>         Arnd


From viresh.kumar at linaro.org  Sun Aug  2 00:27:08 2015
From: viresh.kumar at linaro.org (Viresh Kumar)
Date: Sun, 2 Aug 2015 12:57:08 +0530
Subject: [PATCH v6 0/4] Add Mediatek MT8173 cpufreq driver
In-Reply-To: <1436437661-17606-1-git-send-email-pi-cheng.chen@linaro.org>
References: <1436437661-17606-1-git-send-email-pi-cheng.chen@linaro.org>
Message-ID: <CAKohpo=jnXkcbE-2N7BVPnuNBQz=zX97Eydc0NwFXSaCcZZJLg@mail.gmail.com>

On 9 July 2015 at 15:57, Pi-Cheng Chen <pi-cheng.chen at linaro.org> wrote:
> MT8173 is a ARMv8 based SoC with 2 clusters. All CPUs in a single cluster
> share the same power and clock domain. This series tries to add cpufreq support
> for MT8173 SoC.
>
> changes in v6:
> - Move clock and regulator consumer properties document to the device tree
>   bindings documents of MT8173 CPU DVFS clock driver
> - Add change log to describe what is implemented in the MT8173 cpufreq driver
> - Add missed rcu_read_unlock() in the error path
> - Move of_init_opp_table() call to make sure all required hardware resources
>   are already there before it is called
> - Add comments to describe why both platform driver and deivce registration
>   codes are put in the initcall function
> - Use the term "voltage tracking" instead of "voltage trace" according to an
>   internal SoC document
>

@Rafael: Can you please apply these patches [1,3,4] for 4.3?


From olof at lixom.net  Sun Aug  2 00:29:38 2015
From: olof at lixom.net (Olof Johansson)
Date: Sun, 2 Aug 2015 09:29:38 +0200
Subject: [GIT PULL] ARM: SoC fixes
Message-ID: <20150802072938.GA27455@localhost>

Hi Linus,

Here's this week's pull request for arm-soc. Please merge.


Thanks!

-Olof


The following changes since commit 3eae03daa538303e0d28f56412c6c51f6452e493:

  Merge tag 'pxa-fixes-v4.2-rc2' of https://github.com/rjarzmik/linux into fixesD (2015-07-18 21:06:10 -0700)

are available in the git repository at:

  git://git.kernel.org/pub/scm/linux/kernel/git/arm/arm-soc.git tags/armsoc-for-linus

for you to fetch changes up to c1bfa985ded82cacdfc6403e78f329c44e35534a:

  ARM: dts: keystone: fix dt bindings to use post div register for mainpll (2015-07-31 22:30:11 +0200)

----------------------------------------------------------------
ARM: SoC fixes

Things are calming down nicely here w.r.t. fixes. This batch includes two
week's worth since I missed to send before -rc4.

Nothing particularly scary to point out, smaller fixes here and
there. Shortlog describes it pretty well.

----------------------------------------------------------------
Beata Michalska (1):
      ARM: dts: Update video-phy node with syscon phandle for exynos3250

Denis Carikli (1):
      ARM: dts: i.MX35: Fix can support.

Linus Walleij (1):
      ARM: nomadik: disable UART0 on Nomadik boards

Murali Karicheri (1):
      ARM: dts: keystone: fix dt bindings to use post div register for mainpll

Olof Johansson (3):
      Merge tag 'samsung-fixes-1' of git://git.kernel.org/.../kgene/linux-samsung into fixes
      Merge tag 'for-v4.2-rc/omap-fixes-a' of git://git.kernel.org/.../pjw/omap-pending into fixes
      Merge tag 'imx-fixes-4.2-2' of git://git.kernel.org/.../shawnguo/linux into fixes

Roger Quadros (2):
      ARM: DRA7: hwmod: fix gpmc hwmod
      ARM: OMAP2+: hwmod: Fix _wait_target_ready() for hwmods without sysc

Thomas Abraham (1):
      ARM: dts: add CPU OPP and regulator supply property for exynos4210

 arch/arm/boot/dts/exynos3250.dtsi               |  2 +-
 arch/arm/boot/dts/exynos4210-origen.dts         |  4 ++++
 arch/arm/boot/dts/exynos4210-trats.dts          |  4 ++++
 arch/arm/boot/dts/exynos4210-universal_c210.dts |  4 ++++
 arch/arm/boot/dts/exynos4210.dtsi               | 12 ++++++++++++
 arch/arm/boot/dts/imx35.dtsi                    |  8 ++++----
 arch/arm/boot/dts/k2e-clocks.dtsi               |  5 ++---
 arch/arm/boot/dts/k2hk-clocks.dtsi              |  5 ++---
 arch/arm/boot/dts/k2l-clocks.dtsi               |  5 ++---
 arch/arm/boot/dts/ste-nomadik-nhk15.dts         |  1 +
 arch/arm/boot/dts/ste-nomadik-s8815.dts         |  4 ++++
 arch/arm/boot/dts/ste-nomadik-stn8815.dtsi      |  1 +
 arch/arm/mach-omap2/omap_hwmod.c                | 24 ++++++++++++++++--------
 arch/arm/mach-omap2/omap_hwmod_7xx_data.c       |  5 ++---
 14 files changed, 59 insertions(+), 25 deletions(-)


From Haibo.Chen at freescale.com  Sun Aug  2 01:59:04 2015
From: Haibo.Chen at freescale.com (Chen Bough)
Date: Sun, 2 Aug 2015 08:59:04 +0000
Subject: [PATCH v3 1/6] mmc: sdhci-esdhc-imx: add imx7d support and
 support HS400
In-Reply-To: <20150731141507.GB27806@shlinux1.ap.freescale.net>
References: <1438160637-28061-1-git-send-email-haibo.chen@freescale.com>
 <1438160637-28061-2-git-send-email-haibo.chen@freescale.com>
 <20150731141507.GB27806@shlinux1.ap.freescale.net>
Message-ID: <BY1PR03MB13889195F33D0010E6759D309A880@BY1PR03MB1388.namprd03.prod.outlook.com>



> -----Original Message-----
> From: Dong Aisheng [mailto:aisheng.dong at freescale.com]
> Sent: Friday, July 31, 2015 10:15 PM
> To: Chen Haibo-B51421
> Cc: robh+dt at kernel.org; pawel.moll at arm.com; mark.rutland at arm.com;
> ijc+devicetree at hellion.org.uk; galak at codeaurora.org; shawnguo at kernel.org;
> kernel at pengutronix.de; linux at arm.linux.org.uk; ulf.hansson at linaro.org;
> johan.derycke at barco.com; Estevam Fabio-R49496; Dong Aisheng-B29396;
> devicetree at vger.kernel.org; linux-kernel at vger.kernel.org; linux-arm-
> kernel at lists.infradead.org; linux-mmc at vger.kernel.org
> Subject: Re: [PATCH v3 1/6] mmc: sdhci-esdhc-imx: add imx7d support and
> support HS400
> 
> On Wed, Jul 29, 2015 at 05:03:52PM +0800, Haibo Chen wrote:
> > The imx7d usdhc is derived from imx6sx, the difference is that imx7d
> > support HS400.
> >
> > So introduce a new compatible string for imx7d and add HS400 support
> > for imx7d usdhc.
> >
> > Signed-off-by: Haibo Chen <haibo.chen at freescale.com>
> > ---
> >  drivers/mmc/host/sdhci-esdhc-imx.c | 66
> > ++++++++++++++++++++++++++++++++++++++
> >  1 file changed, 66 insertions(+)
> >
> > diff --git a/drivers/mmc/host/sdhci-esdhc-imx.c
> > b/drivers/mmc/host/sdhci-esdhc-imx.c
> > index c6b9f64..b441eed 100644
> > --- a/drivers/mmc/host/sdhci-esdhc-imx.c
> > +++ b/drivers/mmc/host/sdhci-esdhc-imx.c
> > @@ -44,6 +44,7 @@
> >  #define  ESDHC_MIX_CTRL_EXE_TUNE	(1 << 22)
> >  #define  ESDHC_MIX_CTRL_SMPCLK_SEL	(1 << 23)
> >  #define  ESDHC_MIX_CTRL_FBCLK_SEL	(1 << 25)
> > +#define  ESDHC_MIX_CTRL_HS400_EN	(1 << 26)
> >  /* Bits 3 and 6 are not SDHCI standard definitions */
> >  #define  ESDHC_MIX_CTRL_SDHCI_MASK	0xb7
> >  /* Tuning bits */
> > @@ -60,6 +61,16 @@
> >  #define  ESDHC_TUNE_CTRL_MIN		0
> >  #define  ESDHC_TUNE_CTRL_MAX		((1 << 7) - 1)
> >
> > +/* strobe dll register */
> > +#define ESDHC_STROBE_DLL_CTRL		0x70
> > +#define ESDHC_STROBE_DLL_CTRL_ENABLE	(1 << 0)
> > +#define ESDHC_STROBE_DLL_CTRL_RESET	(1 << 1)
> > +#define ESDHC_STROBE_DLL_CTRL_SLV_DLY_TARGET_SHIFT	3
> > +
> > +#define ESDHC_STROBE_DLL_STATUS		0x74
> > +#define ESDHC_STROBE_DLL_STS_REF_LOCK	(1 << 1)
> > +#define ESDHC_STROBE_DLL_STS_SLV_LOCK	0x1
> > +
> >  #define ESDHC_TUNING_CTRL		0xcc
> >  #define ESDHC_STD_TUNING_EN		(1 << 24)
> >  /* NOTE: the minimum valid tuning start tap for mx6sl is 1 */ @@
> > -120,6 +131,8 @@
> >  #define ESDHC_FLAG_ERR004536		BIT(7)
> >  /* The IP supports HS200 mode */
> >  #define ESDHC_FLAG_HS200		BIT(8)
> > +/* The IP supports HS400 mode */
> > +#define ESDHC_FLAG_SUP_HS400		BIT(9)
> >
> >  struct esdhc_soc_data {
> >  	u32 flags;
> > @@ -156,6 +169,12 @@ static struct esdhc_soc_data usdhc_imx6sx_data = {
> >  			| ESDHC_FLAG_HAVE_CAP1 | ESDHC_FLAG_HS200,  };
> >
> > +static struct esdhc_soc_data usdhc_imx7d_data = {
> > +	.flags = ESDHC_FLAG_USDHC | ESDHC_FLAG_STD_TUNING
> > +			| ESDHC_FLAG_HAVE_CAP1 | ESDHC_FLAG_HS200
> > +			| ESDHC_FLAG_SUP_HS400,
> > +};
> > +
> >  struct pltfm_imx_data {
> >  	u32 scratchpad;
> >  	struct pinctrl *pinctrl;
> > @@ -199,6 +218,7 @@ static const struct of_device_id imx_esdhc_dt_ids[]
> = {
> >  	{ .compatible = "fsl,imx6sx-usdhc", .data = &usdhc_imx6sx_data, },
> >  	{ .compatible = "fsl,imx6sl-usdhc", .data = &usdhc_imx6sl_data, },
> >  	{ .compatible = "fsl,imx6q-usdhc", .data = &usdhc_imx6q_data, },
> > +	{ .compatible = "fsl,imx7d-usdhc", .data = &usdhc_imx7d_data, },
> >  	{ /* sentinel */ }
> >  };
> >  MODULE_DEVICE_TABLE(of, imx_esdhc_dt_ids); @@ -274,6 +294,10 @@
> > static u32 esdhc_readl_le(struct sdhci_host *host, int reg)
> >  				val = SDHCI_SUPPORT_DDR50 | SDHCI_SUPPORT_SDR104
> >  					| SDHCI_SUPPORT_SDR50
> >  					| SDHCI_USE_SDR50_TUNING;
> > +
> > +			/* imx7d does not have a support_hs400 register, fake
> one */
> 
> You could remove this line.
> It's bit, not register and i think no need such comment.
> 
> > +			if (imx_data->socdata->flags & ESDHC_FLAG_SUP_HS400)
> > +				val |= SDHCI_SUPPORT_HS400;
> >  		}
> >  	}
> >
> > @@ -774,6 +798,7 @@ static int esdhc_change_pinstate(struct sdhci_host
> *host,
> >  		break;
> >  	case MMC_TIMING_UHS_SDR104:
> >  	case MMC_TIMING_MMC_HS200:
> > +	case MMC_TIMING_MMC_HS400:
> >  		pinctrl = imx_data->pins_200mhz;
> >  		break;
> >  	default:
> > @@ -784,6 +809,30 @@ static int esdhc_change_pinstate(struct sdhci_host
> *host,
> >  	return pinctrl_select_state(imx_data->pinctrl, pinctrl);  }
> >
> > +static void esdhc_set_strobe_dll(struct sdhci_host *host)
> 
> It would be good if we can add some comments for this function for better
> understand.
> 

[haibo] okay, I will add comments here. 

> > +{
> > +	u32 v;
> > +
> > +	/* force a reset on strobe dll */
> > +	writel(ESDHC_STROBE_DLL_CTRL_RESET, host->ioaddr +
> ESDHC_STROBE_DLL_CTRL);
> > +	/*
> > +	 * enable strobe dll ctrl and adjust the delay target
> > +	 * for the uSDHC loopback read clock
> > +	 */
> > +	v = ESDHC_STROBE_DLL_CTRL_ENABLE |
> > +		(7 << ESDHC_STROBE_DLL_CTRL_SLV_DLY_TARGET_SHIFT);
> > +	writel(v, host->ioaddr + ESDHC_STROBE_DLL_CTRL);
> > +	/* wait 1us to make sure strobe dll status register stable */
> > +	udelay(1);
> > +	v = readl(host->ioaddr + ESDHC_STROBE_DLL_STATUS);
> > +	if (!(v & ESDHC_STROBE_DLL_STS_REF_LOCK))
> > +		dev_warn(mmc_dev(host->mmc),
> > +			"warning! HS400 strobe DLL status REF not lock!\n");
> > +	if (!(v & ESDHC_STROBE_DLL_STS_SLV_LOCK))
> > +		dev_warn(mmc_dev(host->mmc),
> > +			"warning! HS400 strobe DLL status SLV not lock!\n"); }
> > +
> >  static void esdhc_set_uhs_signaling(struct sdhci_host *host, unsigned
> > timing)  {
> >  	struct sdhci_pltfm_host *pltfm_host = sdhci_priv(host); @@ -795,7
> > +844,13 @@ static void esdhc_set_uhs_signaling(struct sdhci_host *host,
> unsigned timing)
> >  	case MMC_TIMING_UHS_SDR25:
> >  	case MMC_TIMING_UHS_SDR50:
> >  	case MMC_TIMING_UHS_SDR104:
> > +		break;
> >  	case MMC_TIMING_MMC_HS200:
> > +		/* disable ddr mode and disable HS400 mode */
> > +		writel(readl(host->ioaddr + ESDHC_MIX_CTRL) &
> > +			~(ESDHC_MIX_CTRL_DDREN | ESDHC_MIX_CTRL_HS400_EN),
> > +			host->ioaddr + ESDHC_MIX_CTRL);
> > +		imx_data->is_ddr = 0;
> >  		break;
> >  	case MMC_TIMING_UHS_DDR50:
> >  	case MMC_TIMING_MMC_DDR52:
> > @@ -813,6 +868,14 @@ static void esdhc_set_uhs_signaling(struct
> sdhci_host *host, unsigned timing)
> >  			writel(v, host->ioaddr + ESDHC_DLL_CTRL);
> >  		}
> >  		break;
> > +	case MMC_TIMING_MMC_HS400:
> > +		writel(readl(host->ioaddr + ESDHC_MIX_CTRL) |
> > +				ESDHC_MIX_CTRL_DDREN | ESDHC_MIX_CTRL_HS400_EN,
> > +				host->ioaddr + ESDHC_MIX_CTRL);
> > +		imx_data->is_ddr = 1;
> > +		if (host->clock == 200000000)
> 
> I can't remember, but could this be a range required by SoC?

[haibo]we should set strobe_dll only when the host clock is 200MHz. For other condition, no need to do this.

> 
> > +			esdhc_set_strobe_dll(host);
> > +		break;
> >  	}
> >
> >  	esdhc_change_pinstate(host, timing); @@ -1100,6 +1163,9 @@ static
> > int sdhci_esdhc_imx_probe(struct platform_device *pdev)
> >  	if (imx_data->socdata->flags & ESDHC_FLAG_ERR004536)
> >  		host->quirks |= SDHCI_QUIRK_BROKEN_ADMA;
> >
> > +	if (imx_data->socdata->flags & ESDHC_FLAG_SUP_HS400)
> > +		host->quirks2 |= SDHCI_QUIRK2_CAPS_BIT63_FOR_HS400;
> > +
> >  	if (of_id)
> >  		err = sdhci_esdhc_imx_probe_dt(pdev, host, imx_data);
> >  	else
> > --
> > 1.9.1
> >
> 
> Regards
> Dong Aisheng


From Haibo.Chen at freescale.com  Sun Aug  2 02:02:21 2015
From: Haibo.Chen at freescale.com (Chen Bough)
Date: Sun, 2 Aug 2015 09:02:21 +0000
Subject: [PATCH v3 4/6] mmc: sdhci-esdhc-imx: add compatible string in
 bingding doc
In-Reply-To: <20150731144354.GC27806@shlinux1.ap.freescale.net>
References: <1438160637-28061-1-git-send-email-haibo.chen@freescale.com>
 <1438160637-28061-5-git-send-email-haibo.chen@freescale.com>
 <20150731144354.GC27806@shlinux1.ap.freescale.net>
Message-ID: <BY1PR03MB138864C76E6D8922405CA2359A880@BY1PR03MB1388.namprd03.prod.outlook.com>



> -----Original Message-----
> From: Dong Aisheng [mailto:aisheng.dong at freescale.com]
> Sent: Friday, July 31, 2015 10:44 PM
> To: Chen Haibo-B51421
> Cc: robh+dt at kernel.org; pawel.moll at arm.com; mark.rutland at arm.com;
> ijc+devicetree at hellion.org.uk; galak at codeaurora.org; shawnguo at kernel.org;
> kernel at pengutronix.de; linux at arm.linux.org.uk; ulf.hansson at linaro.org;
> johan.derycke at barco.com; Estevam Fabio-R49496; Dong Aisheng-B29396;
> devicetree at vger.kernel.org; linux-kernel at vger.kernel.org; linux-arm-
> kernel at lists.infradead.org; linux-mmc at vger.kernel.org
> Subject: Re: [PATCH v3 4/6] mmc: sdhci-esdhc-imx: add compatible string
> in bingding doc
> 
> On Wed, Jul 29, 2015 at 05:03:55PM +0800, Haibo Chen wrote:
> > Add a required property "fsl,imx7d-usdhc" in binding doc.
> > Add an optional property "fsl,tuning-step" in binding doc.
> >
> 
> Better change to:
> mmc: sdhci-esdhc-imx: add imx7d support in bingding doc
> 
> > Signed-off-by: Haibo Chen <haibo.chen at freescale.com>
> > ---
> >  Documentation/devicetree/bindings/mmc/fsl-imx-esdhc.txt | 2 ++
> >  1 file changed, 2 insertions(+)
> >
> > diff --git a/Documentation/devicetree/bindings/mmc/fsl-imx-esdhc.txt
> > b/Documentation/devicetree/bindings/mmc/fsl-imx-esdhc.txt
> > index 211e778..c6624bc 100644
> > --- a/Documentation/devicetree/bindings/mmc/fsl-imx-esdhc.txt
> > +++ b/Documentation/devicetree/bindings/mmc/fsl-imx-esdhc.txt
> > @@ -15,6 +15,7 @@ Required properties:
> >  	       "fsl,imx6q-usdhc"
> >  	       "fsl,imx6sl-usdhc"
> >  	       "fsl,imx6sx-usdhc"
> > +	       "fsl,imx7d-usdhc"
> >
> >  Optional properties:
> >  - fsl,wp-controller : Indicate to use controller internal write
> > protection @@ -27,6 +28,7 @@ Optional properties:
> >    transparent level shifters on the outputs of the controller. Two
> cells are
> >    required, first cell specifies minimum slot voltage (mV), second
> cell
> >    specifies maximum slot voltage (mV). Several ranges could be
> specified.
> > +- fsl,tuning-step: Specify the increasing delay cell steps in tuning
> procedure.
> 
> we could add more explain about this property for better understanding:
> e.g. The uSDHC is using one delay cell as default increasing step to do
> tuning process. This property allows user to change the tuning step to
> more than one delay cells which is useful for some special boards or
> cards when the default tuning step can't find the proper delay window
> within limited tuning reties.

[haibo] for imx7d, seems this is soc related. But here, yes, I should do more explain.
 
> 
> >
> >  Examples:
> >
> > --
> > 1.9.1
> >
> 
> Regards
> Dong Aisheng


From tglx at linutronix.de  Sun Aug  2 02:10:21 2015
From: tglx at linutronix.de (Thomas Gleixner)
Date: Sun, 2 Aug 2015 11:10:21 +0200 (CEST)
Subject: [PATCH 1/3] clocksource: atmel-st: Remove irq handler when clock
 event is unused
In-Reply-To: <alpine.DEB.2.11.1507202245310.18576@nanos>
References: <1437161608-26782-1-git-send-email-alexandre.belloni@free-electrons.com>
 <1437161608-26782-2-git-send-email-alexandre.belloni@free-electrons.com>
 <alpine.DEB.2.11.1507180942360.18576@nanos>
 <20150718222308.GA30489@piout.net>
 <alpine.DEB.2.11.1507201103550.18576@nanos> <20150720193726.GJ15539@piout.net>
 <alpine.DEB.2.11.1507202245310.18576@nanos>
Message-ID: <alpine.DEB.2.11.1508021100390.3825@nanos>

On Mon, 20 Jul 2015, Thomas Gleixner wrote:

> On Mon, 20 Jul 2015, Alexandre Belloni wrote:
> 
> > On 20/07/2015 at 11:04:30 +0200, Thomas Gleixner wrote :
> > > That's why I used setup/remove_irq() in the stale RT changes.
> > > 
> > 
> > Hum, actually, you hit the same thing with setup/remove_irq (and I'm not sure
> > to follow why):
> 
> It's the kmalloc of the proc interface. So back to the drawing
> board. I'll think about it tomorrow with brain awake.

So the only idea I could come up with is the old approach of creating
a dummy irq chip for the interrupts which share that timer/uart/rtc
whatever line.

I think Boris Brezillon had implemented it at some point, but it was
shot down for reasons I can't remember. That would allow us to simply
have disable_irq_nosync/enable_irq in the relevant code pathes and be
done with it. I guess I need to find the references and give it a try
again if nobody beats me to it.

Thanks,

	tglx




From peterz at infradead.org  Sun Aug  2 02:40:28 2015
From: peterz at infradead.org (Peter Zijlstra)
Date: Sun, 2 Aug 2015 11:40:28 +0200
Subject: [PATCH 1/3] clocksource: atmel-st: Remove irq handler when clock
 event is unused
In-Reply-To: <alpine.DEB.2.11.1508021100390.3825@nanos>
References: <1437161608-26782-1-git-send-email-alexandre.belloni@free-electrons.com>
 <1437161608-26782-2-git-send-email-alexandre.belloni@free-electrons.com>
 <alpine.DEB.2.11.1507180942360.18576@nanos>
 <20150718222308.GA30489@piout.net>
 <alpine.DEB.2.11.1507201103550.18576@nanos>
 <20150720193726.GJ15539@piout.net>
 <alpine.DEB.2.11.1507202245310.18576@nanos>
 <alpine.DEB.2.11.1508021100390.3825@nanos>
Message-ID: <20150802094028.GN12596@twins.programming.kicks-ass.net>

On Sun, Aug 02, 2015 at 11:10:21AM +0200, Thomas Gleixner wrote:
> I think Boris Brezillon had implemented it at some point, but it was
> shot down for reasons I can't remember. 

You weren't around at the time.. DT people didn't like it, said they
didn't like having to make up fake hardware in their DT crap.

> That would allow us to simply
> have disable_irq_nosync/enable_irq in the relevant code pathes and be
> done with it. I guess I need to find the references and give it a try
> again if nobody beats me to it.

lkml.kernel.org/r/1422527620-8308-3-git-send-email-boris.brezillon at free-electrons.com


From tglx at linutronix.de  Sun Aug  2 03:22:24 2015
From: tglx at linutronix.de (Thomas Gleixner)
Date: Sun, 2 Aug 2015 12:22:24 +0200 (CEST)
Subject: [PATCH] irqchip: bcm2836: Use a CPU notifier enable IPIs.
In-Reply-To: <1438027789-1637-1-git-send-email-eric@anholt.net>
References: <55B67C81.1010900@gmail.com>
 <1438027789-1637-1-git-send-email-eric@anholt.net>
Message-ID: <alpine.DEB.2.11.1508021221370.3825@nanos>

On Mon, 27 Jul 2015, Eric Anholt wrote:
> +/* Unmasks the IPI on the CPU wen it's first brought online. */

when

> +static int bcm2836_arm_irqchip_cpu_notify(struct notifier_block *nfb,
> +					  unsigned long action, void *hcpu)
> +{
> +	unsigned int cpu = (unsigned long)hcpu;
> +	unsigned int int_reg = LOCAL_MAILBOX_INT_CONTROL0;
> +	unsigned int mailbox = 0;
> +
> +	if (action == CPU_STARTING || action == CPU_STARTING_FROZEN)
> +		bcm2836_arm_irqchip_unmask_per_cpu_irq(int_reg, mailbox, cpu);

Shouldn't you mask the irq on CPU_DYING?

Thanks,

	tglx


From hdegoede at redhat.com  Sun Aug  2 05:58:11 2015
From: hdegoede at redhat.com (Hans de Goede)
Date: Sun, 2 Aug 2015 14:58:11 +0200
Subject: [linux-sunxi] Re: [PATCH 5/5] ARM: dts: sun7i: Add dts file for
 Wits Pro A20 DKT
In-Reply-To: <20150801093046.GX2564@lukather>
References: <1438333194-21181-1-git-send-email-hdegoede@redhat.com>
 <1438333194-21181-6-git-send-email-hdegoede@redhat.com>
 <20150731102028.GE2564@lukather>
 <CAGb2v65TEogqYFAfen1VnOaiepvez5t8Oh+Q=OYsRS_aZUMO3A@mail.gmail.com>
 <55BB9E92.30604@redhat.com> <20150801093046.GX2564@lukather>
Message-ID: <55BE13E3.8060503@redhat.com>

Hi,

On 01-08-15 11:30, Maxime Ripard wrote:
> On Fri, Jul 31, 2015 at 06:13:06PM +0200, Hans de Goede wrote:
>> mmc-pwrseq-simple supports multiple reset/enable gpios (by listing
>> them all as reset-gpios and setting GPIO_ACTIVE_LOW/HIGH depending
>> on which value they need to be to activate things).
>>
>> It also supports listing clocks which need to be enabled. I think
>> that it may be a good idea to use this to also enable the bluetooth
>> bits of the ap6210 module on the cubietruck. I know that the
>> actual bt is interfaced over an uart, and we really should have
>> a mechanism to enable/disable it separately, but for not this seems
>> like a good way to get bluetooth to work.
>>
>> We should ofcourse add a comment to the dts file that this is not a
>> 100% ideal solution, but other then that I think this should work
>> nicely. Maxime would enabling the bluetooth bits of this sdio
>> module via mmc-pwrseq be acceptable to you?
>
> As long as we have some comment on top, yep.

Great, thanks.

>> ChenYu if Maxime acks this solution I hope you can write a patch for
>> this, since you've been working on the bluetooth support before.
>
> Note that I'm in holidays starting today. I plan on doing my
> pull-requests for 4.3 later today, and will probably not be able to
> merge any patches during the next two weeks, which mean that your
> mmc-power seq patch for the cubietruck was probably the last one I was
> merging for the 4.3 merge window.

OK, that is good to know, thanks for the headsup and enjoy your hollidays.

Regards,

Hans


From hdegoede at redhat.com  Sun Aug  2 06:00:37 2015
From: hdegoede at redhat.com (Hans de Goede)
Date: Sun, 2 Aug 2015 15:00:37 +0200
Subject: [linux-sunxi] Re: [PATCH 5/5] ARM: dts: sun7i: Add dts file for
 Wits Pro A20 DKT
In-Reply-To: <20150801093046.GX2564@lukather>
References: <1438333194-21181-1-git-send-email-hdegoede@redhat.com>
 <1438333194-21181-6-git-send-email-hdegoede@redhat.com>
 <20150731102028.GE2564@lukather>
 <CAGb2v65TEogqYFAfen1VnOaiepvez5t8Oh+Q=OYsRS_aZUMO3A@mail.gmail.com>
 <55BB9E92.30604@redhat.com> <20150801093046.GX2564@lukather>
Message-ID: <55BE1475.6040904@redhat.com>

Hi,

On 01-08-15 11:30, Maxime Ripard wrote:
> On Fri, Jul 31, 2015 at 06:13:06PM +0200, Hans de Goede wrote:
>> mmc-pwrseq-simple supports multiple reset/enable gpios (by listing
>> them all as reset-gpios and setting GPIO_ACTIVE_LOW/HIGH depending
>> on which value they need to be to activate things).
>>
>> It also supports listing clocks which need to be enabled. I think
>> that it may be a good idea to use this to also enable the bluetooth
>> bits of the ap6210 module on the cubietruck. I know that the
>> actual bt is interfaced over an uart, and we really should have
>> a mechanism to enable/disable it separately, but for not this seems
>> like a good way to get bluetooth to work.
>>
>> We should ofcourse add a comment to the dts file that this is not a
>> 100% ideal solution, but other then that I think this should work
>> nicely. Maxime would enabling the bluetooth bits of this sdio
>> module via mmc-pwrseq be acceptable to you?
>
> As long as we have some comment on top, yep.
>
>> ChenYu if Maxime acks this solution I hope you can write a patch for
>> this, since you've been working on the bluetooth support before.
>
> Note that I'm in holidays starting today. I plan on doing my
> pull-requests for 4.3 later today, and will probably not be able to
> merge any patches during the next two weeks, which mean that your
> mmc-power seq patch for the cubietruck was probably the last one I was
> merging for the 4.3 merge window.

I just noticed that your last push to

https://git.kernel.org/cgit/linux/kernel/git/mripard/linux.git/log/?h=sunxi/for-next

Is not in your github sunxi-next branch, it would be good if you could
merge the last changes there (when your back from your holliday).

Regards,

Hans


From andreyknvl at google.com  Sun Aug  2 08:11:04 2015
From: andreyknvl at google.com (Andrey Konovalov)
Date: Sun,  2 Aug 2015 17:11:04 +0200
Subject: [PATCH v2] arch: use WRITE_ONCE/READ_ONCE in
 smp_store_release/smp_load_acquire
Message-ID: <1438528264-714-1-git-send-email-andreyknvl@google.com>

Replace ACCESS_ONCE() macro in smp_store_release() and smp_load_acquire()
with WRITE_ONCE() and READ_ONCE() on x86, arm, arm64, ia64, metag, mips,
powerpc, s390, sparc and asm-generic since ACCESS_ONCE does not work
reliably on non-scalar types.

WRITE_ONCE() and READ_ONCE() were introduced in the commits 230fa253df63
("kernel: Provide READ_ONCE and ASSIGN_ONCE") and 43239cbe79fc ("kernel:
Change ASSIGN_ONCE(val, x) to WRITE_ONCE(x, val)").

Signed-off-by: Andrey Konovalov <andreyknvl at google.com>
---
Changed in v2:
  - Other archs besides x86.

 arch/arm/include/asm/barrier.h      | 4 ++--
 arch/arm64/include/asm/barrier.h    | 4 ++--
 arch/ia64/include/asm/barrier.h     | 4 ++--
 arch/metag/include/asm/barrier.h    | 4 ++--
 arch/mips/include/asm/barrier.h     | 4 ++--
 arch/powerpc/include/asm/barrier.h  | 4 ++--
 arch/s390/include/asm/barrier.h     | 4 ++--
 arch/sparc/include/asm/barrier_64.h | 4 ++--
 arch/x86/include/asm/barrier.h      | 8 ++++----
 include/asm-generic/barrier.h       | 4 ++--
 10 files changed, 22 insertions(+), 22 deletions(-)

diff --git a/arch/arm/include/asm/barrier.h b/arch/arm/include/asm/barrier.h
index 6c2327e..7039357 100644
--- a/arch/arm/include/asm/barrier.h
+++ b/arch/arm/include/asm/barrier.h
@@ -67,12 +67,12 @@
 do {									\
 	compiletime_assert_atomic_type(*p);				\
 	smp_mb();							\
-	ACCESS_ONCE(*p) = (v);						\
+	WRITE_ONCE(*p, v);						\
 } while (0)
 
 #define smp_load_acquire(p)						\
 ({									\
-	typeof(*p) ___p1 = ACCESS_ONCE(*p);				\
+	typeof(*p) ___p1 = READ_ONCE(*p);				\
 	compiletime_assert_atomic_type(*p);				\
 	smp_mb();							\
 	___p1;								\
diff --git a/arch/arm64/include/asm/barrier.h b/arch/arm64/include/asm/barrier.h
index 0fa47c4..ef93b20 100644
--- a/arch/arm64/include/asm/barrier.h
+++ b/arch/arm64/include/asm/barrier.h
@@ -44,12 +44,12 @@
 do {									\
 	compiletime_assert_atomic_type(*p);				\
 	barrier();							\
-	ACCESS_ONCE(*p) = (v);						\
+	WRITE_ONCE(*p, v);						\
 } while (0)
 
 #define smp_load_acquire(p)						\
 ({									\
-	typeof(*p) ___p1 = ACCESS_ONCE(*p);				\
+	typeof(*p) ___p1 = READ_ONCE(*p);				\
 	compiletime_assert_atomic_type(*p);				\
 	barrier();							\
 	___p1;								\
diff --git a/arch/ia64/include/asm/barrier.h b/arch/ia64/include/asm/barrier.h
index 843ba43..df896a1 100644
--- a/arch/ia64/include/asm/barrier.h
+++ b/arch/ia64/include/asm/barrier.h
@@ -66,12 +66,12 @@
 do {									\
 	compiletime_assert_atomic_type(*p);				\
 	barrier();							\
-	ACCESS_ONCE(*p) = (v);						\
+	WRITE_ONCE(*p, v);						\
 } while (0)
 
 #define smp_load_acquire(p)						\
 ({									\
-	typeof(*p) ___p1 = ACCESS_ONCE(*p);				\
+	typeof(*p) ___p1 = READ_ONCE(*p);				\
 	compiletime_assert_atomic_type(*p);				\
 	barrier();							\
 	___p1;								\
diff --git a/arch/metag/include/asm/barrier.h b/arch/metag/include/asm/barrier.h
index 5a696e5..172b7e5 100644
--- a/arch/metag/include/asm/barrier.h
+++ b/arch/metag/include/asm/barrier.h
@@ -90,12 +90,12 @@ static inline void fence(void)
 do {									\
 	compiletime_assert_atomic_type(*p);				\
 	smp_mb();							\
-	ACCESS_ONCE(*p) = (v);						\
+	WRITE_ONCE(*p, v);						\
 } while (0)
 
 #define smp_load_acquire(p)						\
 ({									\
-	typeof(*p) ___p1 = ACCESS_ONCE(*p);				\
+	typeof(*p) ___p1 = READ_ONCE(*p);				\
 	compiletime_assert_atomic_type(*p);				\
 	smp_mb();							\
 	___p1;								\
diff --git a/arch/mips/include/asm/barrier.h b/arch/mips/include/asm/barrier.h
index 7ecba84..752e0b8 100644
--- a/arch/mips/include/asm/barrier.h
+++ b/arch/mips/include/asm/barrier.h
@@ -133,12 +133,12 @@
 do {									\
 	compiletime_assert_atomic_type(*p);				\
 	smp_mb();							\
-	ACCESS_ONCE(*p) = (v);						\
+	WRITE_ONCE(*p, v);						\
 } while (0)
 
 #define smp_load_acquire(p)						\
 ({									\
-	typeof(*p) ___p1 = ACCESS_ONCE(*p);				\
+	typeof(*p) ___p1 = READ_ONCE(*p);				\
 	compiletime_assert_atomic_type(*p);				\
 	smp_mb();							\
 	___p1;								\
diff --git a/arch/powerpc/include/asm/barrier.h b/arch/powerpc/include/asm/barrier.h
index 51ccc72..0eca6ef 100644
--- a/arch/powerpc/include/asm/barrier.h
+++ b/arch/powerpc/include/asm/barrier.h
@@ -76,12 +76,12 @@
 do {									\
 	compiletime_assert_atomic_type(*p);				\
 	smp_lwsync();							\
-	ACCESS_ONCE(*p) = (v);						\
+	WRITE_ONCE(*p, v);						\
 } while (0)
 
 #define smp_load_acquire(p)						\
 ({									\
-	typeof(*p) ___p1 = ACCESS_ONCE(*p);				\
+	typeof(*p) ___p1 = READ_ONCE(*p);				\
 	compiletime_assert_atomic_type(*p);				\
 	smp_lwsync();							\
 	___p1;								\
diff --git a/arch/s390/include/asm/barrier.h b/arch/s390/include/asm/barrier.h
index e6f8615..d48fe01 100644
--- a/arch/s390/include/asm/barrier.h
+++ b/arch/s390/include/asm/barrier.h
@@ -42,12 +42,12 @@
 do {									\
 	compiletime_assert_atomic_type(*p);				\
 	barrier();							\
-	ACCESS_ONCE(*p) = (v);						\
+	WRITE_ONCE(*p, v);						\
 } while (0)
 
 #define smp_load_acquire(p)						\
 ({									\
-	typeof(*p) ___p1 = ACCESS_ONCE(*p);				\
+	typeof(*p) ___p1 = READ_ONCE(*p);				\
 	compiletime_assert_atomic_type(*p);				\
 	barrier();							\
 	___p1;								\
diff --git a/arch/sparc/include/asm/barrier_64.h b/arch/sparc/include/asm/barrier_64.h
index 809941e..14a9286 100644
--- a/arch/sparc/include/asm/barrier_64.h
+++ b/arch/sparc/include/asm/barrier_64.h
@@ -60,12 +60,12 @@ do {	__asm__ __volatile__("ba,pt	%%xcc, 1f\n\t" \
 do {									\
 	compiletime_assert_atomic_type(*p);				\
 	barrier();							\
-	ACCESS_ONCE(*p) = (v);						\
+	WRITE_ONCE(*p, v);						\
 } while (0)
 
 #define smp_load_acquire(p)						\
 ({									\
-	typeof(*p) ___p1 = ACCESS_ONCE(*p);				\
+	typeof(*p) ___p1 = READ_ONCE(*p);				\
 	compiletime_assert_atomic_type(*p);				\
 	barrier();							\
 	___p1;								\
diff --git a/arch/x86/include/asm/barrier.h b/arch/x86/include/asm/barrier.h
index e51a8f8..d2bcfbe 100644
--- a/arch/x86/include/asm/barrier.h
+++ b/arch/x86/include/asm/barrier.h
@@ -57,12 +57,12 @@
 do {									\
 	compiletime_assert_atomic_type(*p);				\
 	smp_mb();							\
-	ACCESS_ONCE(*p) = (v);						\
+	WRITE_ONCE(*p, v);						\
 } while (0)
 
 #define smp_load_acquire(p)						\
 ({									\
-	typeof(*p) ___p1 = ACCESS_ONCE(*p);				\
+	typeof(*p) ___p1 = READ_ONCE(*p);				\
 	compiletime_assert_atomic_type(*p);				\
 	smp_mb();							\
 	___p1;								\
@@ -74,12 +74,12 @@ do {									\
 do {									\
 	compiletime_assert_atomic_type(*p);				\
 	barrier();							\
-	ACCESS_ONCE(*p) = (v);						\
+	WRITE_ONCE(*p, v);						\
 } while (0)
 
 #define smp_load_acquire(p)						\
 ({									\
-	typeof(*p) ___p1 = ACCESS_ONCE(*p);				\
+	typeof(*p) ___p1 = READ_ONCE(*p);				\
 	compiletime_assert_atomic_type(*p);				\
 	barrier();							\
 	___p1;								\
diff --git a/include/asm-generic/barrier.h b/include/asm-generic/barrier.h
index 55e3abc..b42afad 100644
--- a/include/asm-generic/barrier.h
+++ b/include/asm-generic/barrier.h
@@ -108,12 +108,12 @@
 do {									\
 	compiletime_assert_atomic_type(*p);				\
 	smp_mb();							\
-	ACCESS_ONCE(*p) = (v);						\
+	WRITE_ONCE(*p, v);						\
 } while (0)
 
 #define smp_load_acquire(p)						\
 ({									\
-	typeof(*p) ___p1 = ACCESS_ONCE(*p);				\
+	typeof(*p) ___p1 = READ_ONCE(*p);				\
 	compiletime_assert_atomic_type(*p);				\
 	smp_mb();							\
 	___p1;								\
-- 
2.5.0.rc2.392.g76e840b



From peterz at infradead.org  Sun Aug  2 09:08:09 2015
From: peterz at infradead.org (Peter Zijlstra)
Date: Sun, 2 Aug 2015 18:08:09 +0200
Subject: [PATCH v2] arch: use WRITE_ONCE/READ_ONCE in
 smp_store_release/smp_load_acquire
In-Reply-To: <1438528264-714-1-git-send-email-andreyknvl@google.com>
References: <1438528264-714-1-git-send-email-andreyknvl@google.com>
Message-ID: <20150802160809.GF25159@twins.programming.kicks-ass.net>

On Sun, Aug 02, 2015 at 05:11:04PM +0200, Andrey Konovalov wrote:
> Replace ACCESS_ONCE() macro in smp_store_release() and smp_load_acquire()
> with WRITE_ONCE() and READ_ONCE() on x86, arm, arm64, ia64, metag, mips,
> powerpc, s390, sparc and asm-generic since ACCESS_ONCE does not work
> reliably on non-scalar types.
> 
> WRITE_ONCE() and READ_ONCE() were introduced in the commits 230fa253df63
> ("kernel: Provide READ_ONCE and ASSIGN_ONCE") and 43239cbe79fc ("kernel:
> Change ASSIGN_ONCE(val, x) to WRITE_ONCE(x, val)").
> 
> Signed-off-by: Andrey Konovalov <andreyknvl at google.com>

Thanks!


From public_timo.s at silentcreek.de  Sun Aug  2 09:18:25 2015
From: public_timo.s at silentcreek.de (Timo Sigurdsson)
Date: Sun,  2 Aug 2015 18:18:25 +0200
Subject: [PATCH v2] ARM: dts: sunxi: Add regulators for LeMaker BananaPi
Message-ID: <1438532305-5884-1-git-send-email-public_timo.s@silentcreek.de>

sun7i-a20-bananapi.dts doesn't contain regulator nodes for the AXP209 PMU
driver, so add them to allow for voltage-scaling with cpufreq-dt.

Signed-off-by: Timo Sigurdsson <public_timo.s at silentcreek.de>
---
Changes since v1 (RFC):

- Dropped the changes to the cpufreq operating points and renamed the patch
accordingly
- Limited the CPU voltage range so it doesn't exceed the SOC specifications
---
 arch/arm/boot/dts/sun7i-a20-bananapi.dts | 35 ++++++++++++++++++++++++++++----
 1 file changed, 31 insertions(+), 4 deletions(-)

diff --git a/arch/arm/boot/dts/sun7i-a20-bananapi.dts b/arch/arm/boot/dts/sun7i-a20-bananapi.dts
index 9f7b472..74382f3 100644
--- a/arch/arm/boot/dts/sun7i-a20-bananapi.dts
+++ b/arch/arm/boot/dts/sun7i-a20-bananapi.dts
@@ -92,6 +92,10 @@
 	status = "okay";
 };
 
+&cpu0 {
+	cpu-supply = <&reg_dcdc2>;
+};
+
 &ehci0 {
 	status = "okay";
 };
@@ -119,13 +123,9 @@
 	status = "okay";
 
 	axp209: pmic at 34 {
-		compatible = "x-powers,axp209";
 		reg = <0x34>;
 		interrupt-parent = <&nmi_intc>;
 		interrupts = <0 IRQ_TYPE_LEVEL_LOW>;
-
-		interrupt-controller;
-		#interrupt-cells = <1>;
 	};
 };
 
@@ -182,6 +182,33 @@
 	};
 };
 
+#include "axp209.dtsi"
+
+&reg_dcdc2 {
+	regulator-always-on;
+	regulator-min-microvolt = <1000000>;
+	regulator-max-microvolt = <1400000>;
+	regulator-name = "vdd-cpu";
+};
+
+&reg_dcdc3 {
+	regulator-always-on;
+	regulator-min-microvolt = <1000000>;
+	regulator-max-microvolt = <1400000>;
+	regulator-name = "vdd-int-dll";
+};
+
+&reg_ldo1 {
+	regulator-name = "vdd-rtc";
+};
+
+&reg_ldo2 {
+	regulator-always-on;
+	regulator-min-microvolt = <3000000>;
+	regulator-max-microvolt = <3000000>;
+	regulator-name = "avcc";
+};
+
 &reg_usb1_vbus {
 	status = "okay";
 };
-- 
2.1.4



From jic23 at kernel.org  Sun Aug  2 09:55:17 2015
From: jic23 at kernel.org (Jonathan Cameron)
Date: Sun, 2 Aug 2015 17:55:17 +0100
Subject: [V3] [TWL4030 MADC] Fix ADC[3:6] readings
In-Reply-To: <1437439755-30618-1-git-send-email-adam.yh.lee@gmail.com>
References: <1437439755-30618-1-git-send-email-adam.yh.lee@gmail.com>
Message-ID: <55BE4B75.9090708@kernel.org>

On 21/07/15 01:49, Adam YH Lee wrote:
> MADC[3:6] reads incorrect values without these two following changes:
> 
> - enable the 3v1 bias regulator for ADC[3:6]
> - configure ADC[3:6] lines as input, not as USB
> 
> Signed-off-by: Adam YH Lee <adam.yh.lee at gmail.com>
> ---
>  drivers/iio/adc/twl4030-madc.c | 36 ++++++++++++++++++++++++++++++++++++
>  1 file changed, 36 insertions(+)
> 
> diff --git a/drivers/iio/adc/twl4030-madc.c b/drivers/iio/adc/twl4030-madc.c
> index 94c5f05..ae33eba 100644
> --- a/drivers/iio/adc/twl4030-madc.c
> +++ b/drivers/iio/adc/twl4030-madc.c
> @@ -45,13 +45,18 @@
>  #include <linux/types.h>
>  #include <linux/gfp.h>
>  #include <linux/err.h>
> +#include <linux/regulator/consumer.h>
>  
>  #include <linux/iio/iio.h>
>  
> +#define TWL4030_USB_SEL_MADC_MCPC	(1<<3)
> +#define TWL4030_USB_CARKIT_ANA_CTRL	0xBB
> +
>  /**
>   * struct twl4030_madc_data - a container for madc info
>   * @dev:		Pointer to device structure for madc
>   * @lock:		Mutex protecting this data structure
> + * @regulator:		Pointer to bias regulator for madc
>   * @requests:		Array of request struct corresponding to SW1, SW2 and RT
>   * @use_second_irq:	IRQ selection (main or co-processor)
>   * @imr:		Interrupt mask register of MADC
> @@ -60,6 +65,7 @@
>  struct twl4030_madc_data {
>  	struct device *dev;
>  	struct mutex lock;	/* mutex protecting this data structure */
> +	struct regulator *usb3v1;
>  	struct twl4030_madc_request requests[TWL4030_MADC_NUM_METHODS];
>  	bool use_second_irq;
>  	u8 imr;
> @@ -848,6 +854,33 @@ static int twl4030_madc_probe(struct platform_device *pdev)
>  		goto err_i2c;
>  	}
>  
At this point in the driver the userspace (an in kernel) interfaces to read
from the device are exposed. Thus if you need this stuff set up right, it
wants to be done before the iio_device_register call.
> +	/* Configure MADC[3:6] */
> +	ret = twl_i2c_read_u8(TWL_MODULE_USB, &regval,
> +			TWL4030_USB_CARKIT_ANA_CTRL);
> +	if (ret) {
> +		dev_err(&pdev->dev, "unable to read reg CARKIT_ANA_CTRL  0x%X\n",
> +				TWL4030_USB_CARKIT_ANA_CTRL);
> +		goto err_i2c;
> +	}
> +	regval |= TWL4030_USB_SEL_MADC_MCPC;
> +	ret = twl_i2c_write_u8(TWL_MODULE_USB, regval,
> +				 TWL4030_USB_CARKIT_ANA_CTRL);
> +	if (ret) {
> +		dev_err(&pdev->dev, "unable to write reg CARKIT_ANA_CTRL 0x%X\n",
> +				TWL4030_USB_CARKIT_ANA_CTRL);
> +		goto err_i2c;
> +	}
> +
> +
> +	/* Enable 3v1 bias regulator for MADC[3:6] */
> +	madc->usb3v1 = devm_regulator_get(madc->dev, "vusb3v1");
> +	if (IS_ERR(madc->usb3v1))
> +		return -ENODEV;
> +
> +	ret = regulator_enable(madc->usb3v1);
> +	if (ret)
> +		dev_err(madc->dev, "could not enable 3v1 bias regulator\n");
> +
>  	return 0;
>  
>  err_i2c:
> @@ -867,6 +900,9 @@ static int twl4030_madc_remove(struct platform_device *pdev)
>  	twl4030_madc_set_current_generator(madc, 0, 0);
>  	twl4030_madc_set_power(madc, 0);
>  
> +	regulator_disable(madc->usb3v1);
> +	devm_regulator_put(madc->usb3v1);
The whole point of devm_ allocators (or in this case _gets) is that when
the driver is removed they are cleaned up automatically.  Hence you don't
need them in your remove call.  Obviously it also clears up the error
handling in probe as well.
> +
>  	return 0;
>  }
>  
> 



From hauke at hauke-m.de  Sun Aug  2 11:03:46 2015
From: hauke at hauke-m.de (Hauke Mehrtens)
Date: Sun, 02 Aug 2015 20:03:46 +0200
Subject: [PATCH] bcma: populate bus DT subnodes as platform_device-s
In-Reply-To: <1435504633-20831-1-git-send-email-zajec5@gmail.com>
References: <1435504633-20831-1-git-send-email-zajec5@gmail.com>
Message-ID: <55BE5B82.7060301@hauke-m.de>

On 06/28/2015 05:17 PM, Rafa? Mi?ecki wrote:
> Our bus should allow defining children nodes as we may want to specify
> devices attached to the bus. This is required e.g. to specify NAND or
> ChipCommon cores and use bus's address and IRQ mappings.
> 
> Signed-off-by: Rafa? Mi?ecki <zajec5 at gmail.com>
> ---
>  drivers/bcma/main.c | 8 ++++++++
>  1 file changed, 8 insertions(+)
> 
> diff --git a/drivers/bcma/main.c b/drivers/bcma/main.c
> index 9635f10..5912847 100644
> --- a/drivers/bcma/main.c
> +++ b/drivers/bcma/main.c
> @@ -12,6 +12,7 @@
>  #include <linux/slab.h>
>  #include <linux/of_address.h>
>  #include <linux/of_irq.h>
> +#include <linux/of_platform.h>
>  
>  MODULE_DESCRIPTION("Broadcom's specific AMBA driver");
>  MODULE_LICENSE("GPL");
> @@ -409,6 +410,13 @@ int bcma_bus_register(struct bcma_bus *bus)
>  		bcma_core_pci_early_init(&bus->drv_pci[0]);
>  	}
>  
> +	if (bus->host_pdev) {

Here is an other problem. So many bugs in this line. ;-)
host_pdev is in a union so this is also true for PCIe devices, but then
the offset of the dev structure probably is wrong. You should check for
the hosttype. I will send a patch.

> +		struct device *dev = &bus->host_pdev->dev;
> +
> +		of_platform_populate(dev->of_node, of_default_bus_match_table,
> +				     NULL, dev);
> +	}
> +
>  	/* Cores providing flash access go before SPROM init */
>  	list_for_each_entry(core, &bus->cores, list) {
>  		if (bcma_is_core_needed_early(core->id.id))
> 



From matwey.kornilov at gmail.com  Sun Aug  2 11:42:18 2015
From: matwey.kornilov at gmail.com (Matwey V. Kornilov)
Date: Sun, 2 Aug 2015 21:42:18 +0300
Subject: [PATCH v2 0/7] uio_pruss cleanup and platform support
In-Reply-To: <20121003150058.GB11180@beef>
References: <1348861072-14507-1-git-send-email-mporter@ti.com>
 <20121003150058.GB11180@beef>
Message-ID: <CAJs94EZAEmab8K=sxtBFu4+86XFmS9UfbvafUFSiZaf5ecoqEg@mail.gmail.com>

2012-10-03 19:00 GMT+04:00 Matt Porter <mporter at ti.com>:
> On Fri, Sep 28, 2012 at 03:37:45PM -0400, Matt Porter wrote:
>> Changes since v1:
>>       - Replaced uio_pruss private SRAM API use with genalloc
>>       - Added DA850 platform device and clock support
>>       - Added DA850 L3 RAM gen_pool support
>>       - Split out DT binding
>>
>> This series enables uio_pruss on both DA850 and AM33xx. The driver
>> previously was not enabled by any platform and the private SRAM API
>> was accessing an invalid SRAM bank for use on DA850. For AM33xx,
>> DT, pinctrl, and runtime PM support are added since AM33xx only
>> boots via DT.
>
> I'm dropping AM33xx/OMAP support from v3 for this series since the
> focus has turned to fixing Davinci SRAM to provide genalloc support
> and the associated use of that in the driver.
>
> I'll have a separate series with AM33xx support since dealing cleanly
> with external resets on OMAP is a bigger issue.

Hello Matt,

Any news on AM33xx support here?

I would even try to implement it by myself, but at the moment stuff
about external resets is too complicated to me, I even can not
understand where problem is. Fetching config from DT instead of
platform in pruss_probe seems to be trivial.

>
> -Matt
> --
> To unsubscribe from this list: send the line "unsubscribe linux-kernel" in
> the body of a message to majordomo at vger.kernel.org
> More majordomo info at  http://vger.kernel.org/majordomo-info.html
> Please read the FAQ at  http://www.tux.org/lkml/
>
>



-- 
With best regards,
Matwey V. Kornilov
http://blog.matwey.name
xmpp://0x2207 at jabber.ru


From public_timo.s at silentcreek.de  Sun Aug  2 12:23:06 2015
From: public_timo.s at silentcreek.de (Timo Sigurdsson)
Date: Sun,  2 Aug 2015 21:23:06 +0200
Subject: [PATCH] ARM: dts: sunxi: Raise minimum CPU voltage for sun7i-a20 to a
 level all boards can supply
Message-ID: <1438543386-7253-1-git-send-email-public_timo.s@silentcreek.de>

sun7i-a20.dtsi contains an cpufreq operating point at 0.9 volts. Most A20 boards
(or all?), however, do not allow the voltage to go below 1.0V. Thus, raise the
voltage for the lowest operating point to 1.0V so all boards can actually use
it.

Signed-off-by: Timo Sigurdsson <public_timo.s at silentcreek.de>
---
 arch/arm/boot/dts/sun7i-a20.dtsi | 2 +-
 1 file changed, 1 insertion(+), 1 deletion(-)

diff --git a/arch/arm/boot/dts/sun7i-a20.dtsi b/arch/arm/boot/dts/sun7i-a20.dtsi
index 6a63f30..f5f384c 100644
--- a/arch/arm/boot/dts/sun7i-a20.dtsi
+++ b/arch/arm/boot/dts/sun7i-a20.dtsi
@@ -107,7 +107,7 @@
 				720000	1200000
 				528000	1100000
 				312000	1000000
-				144000	900000
+				144000	1000000
 				>;
 			#cooling-cells = <2>;
 			cooling-min-level = <0>;
-- 
2.1.4



From bonbons at linux-vserver.org  Sun Aug  2 12:43:10 2015
From: bonbons at linux-vserver.org (Bruno =?UTF-8?B?UHLDqW1vbnQ=?=)
Date: Sun, 2 Aug 2015 21:43:10 +0200
Subject: [PATCH v3 resend 1/2] mfd: axp20x: Add missing registers, and
 mark more registers volatile
In-Reply-To: <1438413918-15765-2-git-send-email-hdegoede@redhat.com>
References: <1438413918-15765-1-git-send-email-hdegoede@redhat.com>
 <1438413918-15765-2-git-send-email-hdegoede@redhat.com>
Message-ID: <20150802214310.7ac05f25@uranus>

On Sat,  1 Aug 2015 09:25:17 Hans de Goede <hdegoede at redhat.com> wrote:
> From: Bruno Pr?mont <bonbons at linux-vserver.org>
> 
> Add an extra set of registers which is necessary tu support the PMICs
> battery charger function, and mark registers which contain status bits,
> gpio status, and adc readings as volatile.
> 
> Cc: Bruno Pr?mont <bonbons at linux-vserver.org>
> Signed-off-by: Bruno Pr?mont <bonbons at linux-vserver.org>
> Signed-off-by: Hans de Goede <hdegoede at redhat.com>
> Acked-by: Lee Jones <lee.jones at linaro.org>
> Acked-by: Maxime Ripard <maxime.ripard at free-electrons.com>
> ---
> Changes in v2:
> -Add a AXP20X_OCV_MAX define
> Changes in v3:
> -Add Bruno's S-o-b
> ---
>  drivers/mfd/axp20x.c       | 8 +++++++-
>  include/linux/mfd/axp20x.h | 6 ++++++
>  2 files changed, 13 insertions(+), 1 deletion(-)
> 
> diff --git a/drivers/mfd/axp20x.c b/drivers/mfd/axp20x.c
> index b369cfc..8bd3283 100644
> --- a/drivers/mfd/axp20x.c
> +++ b/drivers/mfd/axp20x.c
> @@ -61,10 +61,16 @@ static const struct regmap_access_table axp152_volatile_table = {
>  static const struct regmap_range axp20x_writeable_ranges[] = {
>  	regmap_reg_range(AXP20X_DATACACHE(0), AXP20X_IRQ5_STATE),
>  	regmap_reg_range(AXP20X_DCDC_MODE, AXP20X_FG_RES),
> +	regmap_reg_range(AXP20X_RDC_H, AXP20X_OCV(15)),

As AXP20X_OCV_MAX has been added, this should be:
+	regmap_reg_range(AXP20X_RDC_H, AXP20X_OCV(AXP20X_OCV_MAX)),

>  };
>  
>  static const struct regmap_range axp20x_volatile_ranges[] = {
> +	regmap_reg_range(AXP20X_PWR_INPUT_STATUS, AXP20X_USB_OTG_STATUS),
> +	regmap_reg_range(AXP20X_CHRG_CTRL1, AXP20X_CHRG_CTRL2),
>  	regmap_reg_range(AXP20X_IRQ1_EN, AXP20X_IRQ5_STATE),
> +	regmap_reg_range(AXP20X_ACIN_V_ADC_H, AXP20X_IPSOUT_V_HIGH_L),
> +	regmap_reg_range(AXP20X_GPIO20_SS, AXP20X_GPIO3_CTRL),
> +	regmap_reg_range(AXP20X_FG_RES, AXP20X_RDC_L),
>  };
>  
>  static const struct regmap_access_table axp20x_writeable_table = {
> @@ -195,7 +201,7 @@ static const struct regmap_config axp20x_regmap_config = {
>  	.val_bits	= 8,
>  	.wr_table	= &axp20x_writeable_table,
>  	.volatile_table	= &axp20x_volatile_table,
> -	.max_register	= AXP20X_FG_RES,
> +	.max_register	= AXP20X_OCV(AXP20X_OCV_MAX),
>  	.cache_type	= REGCACHE_RBTREE,
>  };
>  
> diff --git a/include/linux/mfd/axp20x.h b/include/linux/mfd/axp20x.h
> index 52203d5..cc8ad1e 100644
> --- a/include/linux/mfd/axp20x.h
> +++ b/include/linux/mfd/axp20x.h
> @@ -190,6 +190,12 @@ enum {
>  #define AXP20X_CC_CTRL			0xb8
>  #define AXP20X_FG_RES			0xb9
>  
> +/* OCV */
> +#define AXP20X_RDC_H			0xba
> +#define AXP20X_RDC_L			0xbb
> +#define AXP20X_OCV(m)			(0xc0 + (m))
> +#define AXP20X_OCV_MAX			0xf
> +
>  /* AXP22X specific registers */
>  #define AXP22X_BATLOW_THRES1		0xe6
>  



From andre.przywara at arm.com  Sun Aug  2 13:20:49 2015
From: andre.przywara at arm.com (Andre Przywara)
Date: Sun, 2 Aug 2015 21:20:49 +0100
Subject: [PATCH v2 14/15] KVM: arm64: implement MSI injection in ITS
 emulation
In-Reply-To: <55BB7678.5080105@linaro.org>
References: <1436538111-4294-1-git-send-email-andre.przywara@arm.com>
 <1436538111-4294-15-git-send-email-andre.przywara@arm.com>
 <55BB7678.5080105@linaro.org>
Message-ID: <55BE7BA1.40403@arm.com>

On 31/07/15 14:22, Eric Auger wrote:

Salut Eric,

> On 07/10/2015 04:21 PM, Andre Przywara wrote:
>> When userland wants to inject a MSI into the guest, we have to use
>> our data structures to find the LPI number and the VCPU to receive
>> the interrupt.
>> Use the wrapper functions to iterate the linked lists and find the
>> proper Interrupt Translation Table Entry. Then set the pending bit
>> in this ITTE to be later picked up by the LR handling code. Kick
>> the VCPU which is meant to handle this interrupt.
>> We provide a VGIC emulation model specific routine for the actual
>> MSI injection. The wrapper functions return an error for models not
>> (yet) implementing MSIs (like the GICv2 emulation).
>> We also provide the handler for the ITS "INT" command, which allows a
>> guest to trigger an MSI via the ITS command queue.
>>
>> Signed-off-by: Andre Przywara <andre.przywara at arm.com>
>> ---
>>  include/kvm/arm_vgic.h      |  1 +
>>  virt/kvm/arm/its-emul.c     | 65 +++++++++++++++++++++++++++++++++++++++++++++
>>  virt/kvm/arm/its-emul.h     |  2 ++
>>  virt/kvm/arm/vgic-v3-emul.c |  1 +
>>  4 files changed, 69 insertions(+)
>>
>> diff --git a/include/kvm/arm_vgic.h b/include/kvm/arm_vgic.h
>> index 323c33a..9e1abf9 100644
>> --- a/include/kvm/arm_vgic.h
>> +++ b/include/kvm/arm_vgic.h
>> @@ -149,6 +149,7 @@ struct vgic_vm_ops {
>>  	int	(*map_resources)(struct kvm *, const struct vgic_params *);
>>  	bool	(*queue_lpis)(struct kvm_vcpu *);
>>  	void	(*unqueue_lpi)(struct kvm_vcpu *, int irq);
>> +	int	(*inject_msi)(struct kvm *, struct kvm_msi *);
>>  };
>>  
>>  struct vgic_io_device {
>> diff --git a/virt/kvm/arm/its-emul.c b/virt/kvm/arm/its-emul.c
>> index 89534c6..a1c12bb 100644
>> --- a/virt/kvm/arm/its-emul.c
>> +++ b/virt/kvm/arm/its-emul.c
>> @@ -323,6 +323,55 @@ static bool handle_mmio_gits_idregs(struct kvm_vcpu *vcpu,
>>  }
>>  
>>  /*
>> + * Translates an incoming MSI request into the redistributor (=VCPU) and
>> + * the associated LPI number. Sets the LPI pending bit and also marks the
>> + * VCPU as having a pending interrupt.
>> + */
>> +int vits_inject_msi(struct kvm *kvm, struct kvm_msi *msi)
>> +{
>> +	struct vgic_dist *dist = &kvm->arch.vgic;
>> +	struct vgic_its *its = &dist->its;
>> +	struct its_itte *itte;
>> +	int cpuid;
>> +	bool inject = false;
>> +	int ret = 0;
>> +
>> +	if (!vgic_has_its(kvm))
>> +		return -ENODEV;
>> +
>> +	if (!(msi->flags & KVM_MSI_VALID_DEVID))
>> +		return -EINVAL;
> I am currently reworking the GSI routing series according to latest
> comments (flag usage on userside and removal of EXTENDED_MSI type on
> kernel side as you suggested). Given the data path,
> 
> kvm_send_userspace_msi (kvm_msi*)
> |_ kvm_set_msi (kvm_kernel_irq_routing_entry *)
> 	|_ kvm->arch.vgic.vm_ops.inject_msi (kvm_msi *)
> 
> the above check is useless I think since in kvm_set_msi I need to
> populate a kvm_msi struct from a kernel routing entry struct. The kernel
> routing entry struct has no info about the validity of devid so I
> systematically sets the flag in kvm_msi.
> 
> I am still dubious about not storing the KVM_MSI_VALID_DEVID info
> somewhere in the kernel routing entry struct.

When I reworked our code to only use a flag and not a separate routing
type I ended up with the flag only guarding assignments, which wouldn't
hurt if done unconditionally (since they are all u32's). So the whole
usage of the flag is somewhat in jeopardy now.
Either the eventual MSI consumer requires a DevID (ITS emulation, which
will not work without it) or the consumer does not care at all and can
totally ignore it (GICv2m). So I think we can always pass on the DevID
field and let the final function decide whether to use it or not. But
somehow this doesn't sound right to me, so maybe I am missing something
here?

Cheers,
Andre.




From andre.przywara at arm.com  Sun Aug  2 13:23:14 2015
From: andre.przywara at arm.com (Andre Przywara)
Date: Sun, 2 Aug 2015 21:23:14 +0100
Subject: [PATCH v2 7/7] KVM: arm: implement kvm_set_msi by gsi direct
 mapping
In-Reply-To: <55BB714A.8030307@linaro.org>
References: <1436430137-24205-1-git-send-email-eric.auger@linaro.org>
 <1436430137-24205-8-git-send-email-eric.auger@linaro.org>
 <55A05282.6020105@arm.com> <55BB714A.8030307@linaro.org>
Message-ID: <55BE7C32.8070707@arm.com>

On 31/07/15 13:59, Eric Auger wrote:
> Hi Andre,
> On 07/11/2015 01:17 AM, Andre Przywara wrote:
>> On 09/07/15 09:22, Eric Auger wrote:
>>> If the ITS modality is not available, let's simply support MSI
>>> injection by transforming the MSI.data into an SPI ID.
>>>
>>> This becomes possible to use KVM_SIGNAL_MSI ioctl for arm too.
>>>
>>> Signed-off-by: Eric Auger <eric.auger at linaro.org>
>>>
>>> ---
>>>
>>> v1 -> v2:
>>> - introduce vgic_v2m_inject_msi in vgic-v2-emul.c following Andre's
>>>   advice
>>> ---
>>>  arch/arm/kvm/Kconfig        |  1 +
>>>  virt/kvm/arm/vgic-v2-emul.c | 12 ++++++++++++
>>>  2 files changed, 13 insertions(+)
>>>
>>> diff --git a/arch/arm/kvm/Kconfig b/arch/arm/kvm/Kconfig
>>> index 151e710..0f58baf 100644
>>> --- a/arch/arm/kvm/Kconfig
>>> +++ b/arch/arm/kvm/Kconfig
>>> @@ -31,6 +31,7 @@ config KVM
>>>  	select KVM_VFIO
>>>  	select HAVE_KVM_EVENTFD
>>>  	select HAVE_KVM_IRQFD
>>> +	select HAVE_KVM_MSI
>>
>> I wonder if this requires some more code to only advertise
>> KVM_CAP_SIGNAL_MSI if userland actually sets up a GICv2M?
>> Otherwise userland could get the idea of being able to inectj MSIs
>> without the guest actually being prepared for that (because the GICv2M
>> driver did not initialize).
> Not sure I get what you mean here. By directly transforming the user
> provided MSI msg into an SPI ID, do we really have to care about GICv2M?

By user provided message you mean from user space? So this is an
emulated device, which the guest programs with an MSI payload and a
doorbell address at least? So how would a guest know these things
without having a MSI capable interrupt controller?

Or are we talking about different things here?

Cheers,
Andre.

> 
> Best Regards
> 
> Eric
>>
>> Cheers,
>> Andre.
>>
>>>  	select HAVE_KVM_IRQCHIP
>>>  	select HAVE_KVM_IRQ_ROUTING
>>>  	depends on ARM_VIRT_EXT && ARM_LPAE && ARM_ARCH_TIMER
>>> diff --git a/virt/kvm/arm/vgic-v2-emul.c b/virt/kvm/arm/vgic-v2-emul.c
>>> index 1390797..43013cc 100644
>>> --- a/virt/kvm/arm/vgic-v2-emul.c
>>> +++ b/virt/kvm/arm/vgic-v2-emul.c
>>> @@ -478,6 +478,17 @@ static bool vgic_v2_queue_sgi(struct kvm_vcpu *vcpu, int irq)
>>>  }
>>>  
>>>  /**
>>> + * Emulates GICv2M MSI injection by injecting the SPI ID matching
>>> + * the msi data
>>> + * @kvm: pointer to the kvm struct
>>> + * @msi: the msi struct handle
>>> + */
>>> +static int vgic_v2m_inject_msi(struct kvm *kvm, struct kvm_msi *msi)
>>> +{
>>> +	return kvm_vgic_inject_irq(kvm, 0, msi->data, 1);
>>> +}
>>> +
>>> +/**
>>>   * kvm_vgic_map_resources - Configure global VGIC state before running any VCPUs
>>>   * @kvm: pointer to the kvm struct
>>>   *
>>> @@ -566,6 +577,7 @@ void vgic_v2_init_emulation(struct kvm *kvm)
>>>  	dist->vm_ops.add_sgi_source = vgic_v2_add_sgi_source;
>>>  	dist->vm_ops.init_model = vgic_v2_init_model;
>>>  	dist->vm_ops.map_resources = vgic_v2_map_resources;
>>> +	dist->vm_ops.inject_msi = vgic_v2m_inject_msi;
>>>  
>>>  	kvm->arch.max_vcpus = VGIC_V2_MAX_CPUS;
>>>  }
>>>
>>
> 



From joe at perches.com  Sun Aug  2 13:30:53 2015
From: joe at perches.com (Joe Perches)
Date: Sun, 02 Aug 2015 13:30:53 -0700
Subject: [TRIVIAL PATCH] [media] s5p-mfc: Correct misuse of %0x<decimal>
Message-ID: <1438547453.29569.10.camel@perches.com>

Correct misuse of 0x%d in logging message.

Signed-off-by: Joe Perches <joe at perches.com>
---
 drivers/media/platform/s5p-mfc/s5p_mfc_opr_v6.c | 2 +-
 1 file changed, 1 insertion(+), 1 deletion(-)

diff --git a/drivers/media/platform/s5p-mfc/s5p_mfc_opr_v6.c b/drivers/media/platform/s5p-mfc/s5p_mfc_opr_v6.c
index 12497f5..c10ad57 100644
--- a/drivers/media/platform/s5p-mfc/s5p_mfc_opr_v6.c
+++ b/drivers/media/platform/s5p-mfc/s5p_mfc_opr_v6.c
@@ -520,7 +520,7 @@ static int s5p_mfc_set_enc_stream_buffer_v6(struct s5p_mfc_ctx *ctx,
        writel(addr, mfc_regs->e_stream_buffer_addr); /* 16B align */
        writel(size, mfc_regs->e_stream_buffer_size);
 
-       mfc_debug(2, "stream buf addr: 0x%08lx, size: 0x%d\n",
+       mfc_debug(2, "stream buf addr: 0x%08lx, size: 0x%x\n",
                  addr, size);
 
        return 0;


From heiko at sntech.de  Sun Aug  2 14:43:12 2015
From: heiko at sntech.de (Heiko =?ISO-8859-1?Q?St=FCbner?=)
Date: Sun, 02 Aug 2015 23:43:12 +0200
Subject: [PATCH 1/3] ARM: dts: rockchip: set correct dwc2 params for cortex-a9
 socs
Message-ID: <1617149.AMXNNUATDo@diego>

According to the manual, the fifo sizes are the same as on later socs
like the rk3288 and this also fixes an error about "insufficient fifo
memory", as it seems the values read from the ip are wrong.

Signed-off-by: Heiko Stuebner <heiko at sntech.de>
---
 arch/arm/boot/dts/rk3xxx.dtsi | 6 ++++++
 1 file changed, 6 insertions(+)

diff --git a/arch/arm/boot/dts/rk3xxx.dtsi b/arch/arm/boot/dts/rk3xxx.dtsi
index a2ae9f3..c571ac8 100644
--- a/arch/arm/boot/dts/rk3xxx.dtsi
+++ b/arch/arm/boot/dts/rk3xxx.dtsi
@@ -172,6 +172,11 @@
 		interrupts = <GIC_SPI 16 IRQ_TYPE_LEVEL_HIGH>;
 		clocks = <&cru HCLK_OTG0>;
 		clock-names = "otg";
+		dr_mode = "otg";
+		g-np-tx-fifo-size = <16>;
+		g-rx-fifo-size = <275>;
+		g-tx-fifo-size = <256 128 128 64 64 32>;
+		g-use-dma;
 		status = "disabled";
 	};
 
@@ -181,6 +186,7 @@
 		interrupts = <GIC_SPI 17 IRQ_TYPE_LEVEL_HIGH>;
 		clocks = <&cru HCLK_OTG1>;
 		clock-names = "otg";
+		dr_mode = "host";
 		status = "disabled";
 	};
 
-- 
2.1.4




From heiko at sntech.de  Sun Aug  2 14:44:39 2015
From: heiko at sntech.de (Heiko =?ISO-8859-1?Q?St=FCbner?=)
Date: Sun, 02 Aug 2015 23:44:39 +0200
Subject: [PATCH 2/3] ARM: dts: rockchip: add usb phys to Cortex-A9 socs
In-Reply-To: <1617149.AMXNNUATDo@diego>
References: <1617149.AMXNNUATDo@diego>
Message-ID: <1667603.JGEDfygFyh@diego>

This adds the usbphy nodes to rk3066 and rk3188, which share the usb hosts
in rk3xxx.dtsi and also enables it on boards based around these socs.

The usb-phy itself is the same as used on the rk3288 already.

Signed-off-by: Heiko Stuebner <heiko at sntech.de>
---
 arch/arm/boot/dts/rk3066a-marsboard.dts |  4 ++++
 arch/arm/boot/dts/rk3066a-rayeager.dts  |  4 ++++
 arch/arm/boot/dts/rk3066a.dtsi          | 22 ++++++++++++++++++++++
 arch/arm/boot/dts/rk3188-radxarock.dts  |  4 ++++
 arch/arm/boot/dts/rk3188.dtsi           | 22 ++++++++++++++++++++++
 arch/arm/boot/dts/rk3xxx.dtsi           |  4 ++++
 6 files changed, 60 insertions(+)

diff --git a/arch/arm/boot/dts/rk3066a-marsboard.dts b/arch/arm/boot/dts/rk3066a-marsboard.dts
index 4355966..08f5b43 100644
--- a/arch/arm/boot/dts/rk3066a-marsboard.dts
+++ b/arch/arm/boot/dts/rk3066a-marsboard.dts
@@ -202,6 +202,10 @@
 	status = "okay";
 };
 
+&usbphy {
+	status = "okay";
+};
+
 &wdt {
 	status = "okay";
 };
diff --git a/arch/arm/boot/dts/rk3066a-rayeager.dts b/arch/arm/boot/dts/rk3066a-rayeager.dts
index 7ccd376..e36383c 100644
--- a/arch/arm/boot/dts/rk3066a-rayeager.dts
+++ b/arch/arm/boot/dts/rk3066a-rayeager.dts
@@ -460,6 +460,10 @@
 	status = "okay";
 };
 
+&usbphy {
+	status = "okay";
+};
+
 &usb_otg {
 	status = "okay";
 };
diff --git a/arch/arm/boot/dts/rk3066a.dtsi b/arch/arm/boot/dts/rk3066a.dtsi
index d32229b..870e6f5 100644
--- a/arch/arm/boot/dts/rk3066a.dtsi
+++ b/arch/arm/boot/dts/rk3066a.dtsi
@@ -169,6 +169,28 @@
 		clock-names = "timer", "pclk";
 	};
 
+	usbphy: phy {
+		compatible = "rockchip,rk3066a-usb-phy", "rockchip,rk3288-usb-phy";
+		rockchip,grf = <&grf>;
+		#address-cells = <1>;
+		#size-cells = <0>;
+		status = "disabled";
+
+		usbphy0: usb-phy0 {
+			#phy-cells = <0>;
+			reg = <0x17c>;
+			clocks = <&cru SCLK_OTGPHY0>;
+			clock-names = "phyclk";
+		};
+
+		usbphy1: usb-phy1 {
+			#phy-cells = <0>;
+			reg = <0x188>;
+			clocks = <&cru SCLK_OTGPHY1>;
+			clock-names = "phyclk";
+		};
+	};
+
 	pinctrl: pinctrl {
 		compatible = "rockchip,rk3066a-pinctrl";
 		rockchip,grf = <&grf>;
diff --git a/arch/arm/boot/dts/rk3188-radxarock.dts b/arch/arm/boot/dts/rk3188-radxarock.dts
index 4bb014d..d2180e5 100644
--- a/arch/arm/boot/dts/rk3188-radxarock.dts
+++ b/arch/arm/boot/dts/rk3188-radxarock.dts
@@ -359,6 +359,10 @@
 	status = "okay";
 };
 
+&usbphy {
+	status = "okay";
+};
+
 &usb_host {
 	status = "okay";
 };
diff --git a/arch/arm/boot/dts/rk3188.dtsi b/arch/arm/boot/dts/rk3188.dtsi
index 0f23aed..3163042 100644
--- a/arch/arm/boot/dts/rk3188.dtsi
+++ b/arch/arm/boot/dts/rk3188.dtsi
@@ -130,6 +130,28 @@
 		#reset-cells = <1>;
 	};
 
+	usbphy: phy {
+		compatible = "rockchip,rk3188-usb-phy", "rockchip,rk3288-usb-phy";
+		rockchip,grf = <&grf>;
+		#address-cells = <1>;
+		#size-cells = <0>;
+		status = "disabled";
+
+		usbphy0: usb-phy0 {
+			#phy-cells = <0>;
+			reg = <0x10c>;
+			clocks = <&cru SCLK_OTGPHY0>;
+			clock-names = "phyclk";
+		};
+
+		usbphy1: usb-phy1 {
+			#phy-cells = <0>;
+			reg = <0x11c>;
+			clocks = <&cru SCLK_OTGPHY1>;
+			clock-names = "phyclk";
+		};
+	};
+
 	pinctrl: pinctrl {
 		compatible = "rockchip,rk3188-pinctrl";
 		rockchip,grf = <&grf>;
diff --git a/arch/arm/boot/dts/rk3xxx.dtsi b/arch/arm/boot/dts/rk3xxx.dtsi
index c571ac8..4497d28 100644
--- a/arch/arm/boot/dts/rk3xxx.dtsi
+++ b/arch/arm/boot/dts/rk3xxx.dtsi
@@ -177,6 +177,8 @@
 		g-rx-fifo-size = <275>;
 		g-tx-fifo-size = <256 128 128 64 64 32>;
 		g-use-dma;
+		phys = <&usbphy0>;
+		phy-names = "usb2-phy";
 		status = "disabled";
 	};
 
@@ -187,6 +189,8 @@
 		clocks = <&cru HCLK_OTG1>;
 		clock-names = "otg";
 		dr_mode = "host";
+		phys = <&usbphy1>;
+		phy-names = "usb2-phy";
 		status = "disabled";
 	};
 
-- 
2.1.4




From heiko at sntech.de  Sun Aug  2 14:45:13 2015
From: heiko at sntech.de (Heiko =?ISO-8859-1?Q?St=FCbner?=)
Date: Sun, 02 Aug 2015 23:45:13 +0200
Subject: [PATCH 3/3] ARM: dts: rockchip: enable usb controller on marsboard
In-Reply-To: <1617149.AMXNNUATDo@diego>
References: <1617149.AMXNNUATDo@diego>
Message-ID: <5410702.spv0GayXVB@diego>

This enables the previously disabled usb controllers on the marsboard
and makes it possible to for example mount usb mass storage devices.

Signed-off-by: Heiko Stuebner <heiko at sntech.de>
---
 arch/arm/boot/dts/rk3066a-marsboard.dts | 8 ++++++++
 1 file changed, 8 insertions(+)

diff --git a/arch/arm/boot/dts/rk3066a-marsboard.dts b/arch/arm/boot/dts/rk3066a-marsboard.dts
index 08f5b43..bae965c 100644
--- a/arch/arm/boot/dts/rk3066a-marsboard.dts
+++ b/arch/arm/boot/dts/rk3066a-marsboard.dts
@@ -206,6 +206,14 @@
 	status = "okay";
 };
 
+&usb_host {
+	status = "okay";
+};
+
+&usb_otg {
+	status = "okay";
+};
+
 &wdt {
 	status = "okay";
 };
-- 
2.1.4




From linus.walleij at linaro.org  Sun Aug  2 14:55:51 2015
From: linus.walleij at linaro.org (Linus Walleij)
Date: Sun,  2 Aug 2015 23:55:51 +0200
Subject: [PATCH 1/4] ARM: nomadik: move hog code to use DT hogs
Message-ID: <1438552551-4480-1-git-send-email-linus.walleij@linaro.org>

Instead of introducing a board-specific DT node for biasing the
MMC/SD and SATA ports, use the new device tree hogs.

Signed-off-by: Linus Walleij <linus.walleij at linaro.org>
---
 arch/arm/boot/dts/ste-nomadik-nhk15.dts | 18 +++++++++--------
 arch/arm/boot/dts/ste-nomadik-s8815.dts | 18 +++++++++--------
 arch/arm/mach-nomadik/cpu-8815.c        | 36 ---------------------------------
 3 files changed, 20 insertions(+), 52 deletions(-)

diff --git a/arch/arm/boot/dts/ste-nomadik-nhk15.dts b/arch/arm/boot/dts/ste-nomadik-nhk15.dts
index 3d25dba143a5..0e167ed2857b 100644
--- a/arch/arm/boot/dts/ste-nomadik-nhk15.dts
+++ b/arch/arm/boot/dts/ste-nomadik-nhk15.dts
@@ -131,6 +131,16 @@
 				#gpio-cells = <2>;
 				interrupt-controller;
 				#interrupt-cells = <2>;
+				/*
+				 * This will turn off SATA so that MMC/SD
+				 * can thrive
+				 */
+				mmcsd-gpio {
+					gpio-hog;
+					gpios = <2 0x0>;
+					output-low;
+					line-name = "SATA EN";
+				};
 			};
 		};
 	};
@@ -141,12 +151,4 @@
 			wp-gpios = <&stmpe_gpio44 18 GPIO_ACTIVE_HIGH>;
 		};
 	};
-
-	/* Custom board node with GPIO pins to active etc */
-	usb-s8815 {
-		/* This will turn off SATA so that MMC/SD can thrive */
-		mmcsd-gpio {
-			gpios = <&stmpe_gpio44 2 0x1>;
-		};
-	};
 };
diff --git a/arch/arm/boot/dts/ste-nomadik-s8815.dts b/arch/arm/boot/dts/ste-nomadik-s8815.dts
index 3c140d05f796..edcfe2413ee7 100644
--- a/arch/arm/boot/dts/ste-nomadik-s8815.dts
+++ b/arch/arm/boot/dts/ste-nomadik-s8815.dts
@@ -19,6 +19,16 @@
 		serial1 = &uart1;
 	};
 
+	gpio3: gpio at 101e7000 {
+		/* This hog will bias the MMC/SD card detect line */
+		mmcsd-gpio {
+			gpio-hog;
+			gpios = <16 0x0>;
+			output-low;
+			line-name = "card detect bias";
+		};
+	};
+
 	src at 101e0000 {
 		/* These chrystal drivers are not used on this board */
 		disable-sxtalo;
@@ -109,14 +119,6 @@
 		};
 	};
 
-	/* Custom board node with GPIO pins to active etc */
-	usb-s8815 {
-		/* This will bias the MMC/SD card detect line */
-		mmcsd-gpio {
-			gpios = <&gpio3 16 0x1>;
-		};
-	};
-
 	/* The user LED on the board is set up to be used for heartbeat */
 	leds {
 		compatible = "gpio-leds";
diff --git a/arch/arm/mach-nomadik/cpu-8815.c b/arch/arm/mach-nomadik/cpu-8815.c
index 9bda46f1fab7..82831dc6122f 100644
--- a/arch/arm/mach-nomadik/cpu-8815.c
+++ b/arch/arm/mach-nomadik/cpu-8815.c
@@ -26,10 +26,8 @@
 #include <linux/irq.h>
 #include <linux/dma-mapping.h>
 #include <linux/of_irq.h>
-#include <linux/of_gpio.h>
 #include <linux/of_address.h>
 #include <linux/of_platform.h>
-#include <linux/gpio.h>
 
 #include <asm/mach/arch.h>
 #include <asm/mach/map.h>
@@ -109,40 +107,6 @@ static void cpu8815_restart(enum reboot_mode mode, const char *cmd)
 	writel(1, srcbase + 0x18);
 }
 
-/*
- * This GPIO pin turns on a line that is used to detect card insertion
- * on this board.
- */
-static int __init cpu8815_mmcsd_init(void)
-{
-	struct device_node *cdbias;
-	int gpio, err;
-
-	cdbias = of_find_node_by_path("/usb-s8815/mmcsd-gpio");
-	if (!cdbias) {
-		pr_info("could not find MMC/SD card detect bias node\n");
-		return 0;
-	}
-	gpio = of_get_gpio(cdbias, 0);
-	if (gpio < 0) {
-		pr_info("could not obtain MMC/SD card detect bias GPIO\n");
-		return 0;
-	}
-	err = gpio_request(gpio, "card detect bias");
-	if (err) {
-		pr_info("failed to request card detect bias GPIO %d\n", gpio);
-		return -ENODEV;
-	}
-	err = gpio_direction_output(gpio, 0);
-	if (err){
-		pr_info("failed to set GPIO %d as output, low\n", gpio);
-		return err;
-	}
-	pr_info("enabled USB-S8815 CD bias GPIO %d, low\n", gpio);
-	return 0;
-}
-device_initcall(cpu8815_mmcsd_init);
-
 static const char * cpu8815_board_compat[] = {
 	"st,nomadik-nhk-15",
 	"calaosystems,usb-s8815",
-- 
2.4.3



From linus.walleij at linaro.org  Sun Aug  2 14:56:21 2015
From: linus.walleij at linaro.org (Linus Walleij)
Date: Sun,  2 Aug 2015 23:56:21 +0200
Subject: [PATCH 2/4] ARM: nomadik: selectively enable UART0 on boards
Message-ID: <1438552581-4531-1-git-send-email-linus.walleij@linaro.org>

The S8815 board is using RX/TX on UART0, and the NHK8815 is
using RX/TX and CTS/RTS (the latter connected to a Bluetooth
chip). Activate the right groups with the u0 UART0 function
on each board and undisable it. Get rid of the old erroneous
default definition from the SoC file.

Signed-off-by: Linus Walleij <linus.walleij at linaro.org>
---
 arch/arm/boot/dts/ste-nomadik-nhk15.dts    | 16 ++++++++++++++++
 arch/arm/boot/dts/ste-nomadik-s8815.dts    | 18 +++++++++++++++++-
 arch/arm/boot/dts/ste-nomadik-stn8815.dtsi | 10 ----------
 3 files changed, 33 insertions(+), 11 deletions(-)

diff --git a/arch/arm/boot/dts/ste-nomadik-nhk15.dts b/arch/arm/boot/dts/ste-nomadik-nhk15.dts
index 0e167ed2857b..9d888b0e75af 100644
--- a/arch/arm/boot/dts/ste-nomadik-nhk15.dts
+++ b/arch/arm/boot/dts/ste-nomadik-nhk15.dts
@@ -17,12 +17,22 @@
 	};
 
 	aliases {
+		serial0 = &uart0;
 		serial1 = &uart1;
 		stmpe-i2c0 = &stmpe0;
 		stmpe-i2c1 = &stmpe1;
 	};
 
 	pinctrl {
+		uart0 {
+			uart0_nhk_mode: uart0_mux {
+				u0_default_mux {
+					function = "u0";
+					groups = "u0txrx_a_1", "u0ctsrts_a_1";
+				};
+			};
+		};
+
 		stmpe2401_1 {
 			stmpe2401_1_nhk_mode: stmpe2401_1_nhk {
 				nhk_cfg1 {
@@ -146,6 +156,12 @@
 	};
 
 	amba {
+		/* Activate RX/TX and CTS/RTS on UART 0 */
+		uart0: uart at 101fd000 {
+			pinctrl-names = "default";
+			pinctrl-0 = <&uart0_nhk_mode>;
+			status = "okay";
+		};
 		mmcsd: sdi at 101f6000 {
 			cd-gpios = <&stmpe_gpio44 7 GPIO_ACTIVE_LOW>;
 			wp-gpios = <&stmpe_gpio44 18 GPIO_ACTIVE_HIGH>;
diff --git a/arch/arm/boot/dts/ste-nomadik-s8815.dts b/arch/arm/boot/dts/ste-nomadik-s8815.dts
index edcfe2413ee7..11b5e34150b8 100644
--- a/arch/arm/boot/dts/ste-nomadik-s8815.dts
+++ b/arch/arm/boot/dts/ste-nomadik-s8815.dts
@@ -16,6 +16,7 @@
 	};
 
 	aliases {
+		serial0 = &uart0;
 		serial1 = &uart1;
 	};
 
@@ -40,6 +41,15 @@
 		pinctrl-names = "default";
 		pinctrl-0 = <&cd_default_mode>;
 
+		uart0 {
+			/* Only use RX/TX pins */
+			uart0_s8815_mode: uart0_mux {
+				u0_default_mux {
+					function = "u0";
+					groups = "u0txrx_a_1";
+				};
+			};
+		};
 		mmcsd-cd {
 			cd_default_mode: cd_default {
 				cd_default_cfg1 {
@@ -112,8 +122,14 @@
 	};
 
 
-	/* Configure card detect for the uSD slot */
 	amba {
+		/* Activate RXTX on UART 0 */
+		uart0: uart at 101fd000 {
+			pinctrl-names = "default";
+			pinctrl-0 = <&uart0_s8815_mode>;
+			status = "okay";
+		};
+		/* Configure card detect for the uSD slot */
 		mmcsd: sdi at 101f6000 {
 			cd-gpios = <&gpio3 15 GPIO_ACTIVE_LOW>;
 		};
diff --git a/arch/arm/boot/dts/ste-nomadik-stn8815.dtsi b/arch/arm/boot/dts/ste-nomadik-stn8815.dtsi
index 8e601d02ca8c..0edab6d23211 100644
--- a/arch/arm/boot/dts/ste-nomadik-stn8815.dtsi
+++ b/arch/arm/boot/dts/ste-nomadik-stn8815.dtsi
@@ -103,14 +103,6 @@
 		compatible = "stericsson,stn8815-pinctrl";
 		nomadik-gpio-chips = <&gpio0>, <&gpio1>, <&gpio2>, <&gpio3>;
 		/* Pin configurations */
-		uart0 {
-			uart0_default_mux: uart0_mux {
-				u0_default_mux {
-					function = "u0";
-					groups = "u0_a_1";
-				};
-			};
-		};
 		uart1 {
 			uart1_default_mux: uart1_mux {
 				u1_default_mux {
@@ -761,8 +753,6 @@
 			interrupts = <12>;
 			clocks = <&uart0clk>, <&pclkuart0>;
 			clock-names = "uartclk", "apb_pclk";
-			pinctrl-names = "default";
-			pinctrl-0 = <&uart0_default_mux>;
 			status = "disabled";
 		};
 
-- 
2.4.3



From linus.walleij at linaro.org  Sun Aug  2 14:56:33 2015
From: linus.walleij at linaro.org (Linus Walleij)
Date: Sun,  2 Aug 2015 23:56:33 +0200
Subject: [PATCH 3/4] ARM: nomadik: move l2x0 setup to device tree
Message-ID: <1438552593-4578-1-git-send-email-linus.walleij@linaro.org>

The cache setup magic value in the Nomadik machine is plain wrong,
the correct settings can be done using device tree in accordance
with the settings from ST's own port.

Signed-off-by: Linus Walleij <linus.walleij at linaro.org>
---
 arch/arm/boot/dts/ste-nomadik-stn8815.dtsi | 7 +++++++
 arch/arm/mach-nomadik/cpu-8815.c           | 5 ++---
 2 files changed, 9 insertions(+), 3 deletions(-)

diff --git a/arch/arm/boot/dts/ste-nomadik-stn8815.dtsi b/arch/arm/boot/dts/ste-nomadik-stn8815.dtsi
index 0edab6d23211..defabe053114 100644
--- a/arch/arm/boot/dts/ste-nomadik-stn8815.dtsi
+++ b/arch/arm/boot/dts/ste-nomadik-stn8815.dtsi
@@ -21,6 +21,13 @@
 		interrupts = <30>;
 		cache-unified;
 		cache-level = <2>;
+		cache-size = <131072>;
+		cache-sets = <512>;
+		cache-line-size = <32>;
+		/* At full speed latency must be >=2 */
+		arm,tag-latency = <2>;
+		arm,data-latency = <2 2>;
+		arm,dirty-latency = <2>;
 	};
 
 	mtu0: mtu at 101e2000 {
diff --git a/arch/arm/mach-nomadik/cpu-8815.c b/arch/arm/mach-nomadik/cpu-8815.c
index 82831dc6122f..009754055f09 100644
--- a/arch/arm/mach-nomadik/cpu-8815.c
+++ b/arch/arm/mach-nomadik/cpu-8815.c
@@ -114,9 +114,8 @@ static const char * cpu8815_board_compat[] = {
 };
 
 DT_MACHINE_START(NOMADIK_DT, "Nomadik STn8815")
-	/* At full speed latency must be >=2, so 0x249 in low bits */
-	.l2c_aux_val	= 0x00700249,
-	.l2c_aux_mask	= 0xfe0fefff,
+	.l2c_aux_val	= 0x0,
+	.l2c_aux_mask	= ~0x0UL,
 	.map_io		= cpu8815_map_io,
 	.restart	= cpu8815_restart,
 	.dt_compat      = cpu8815_board_compat,
-- 
2.4.3



From linus.walleij at linaro.org  Sun Aug  2 14:56:46 2015
From: linus.walleij at linaro.org (Linus Walleij)
Date: Sun,  2 Aug 2015 23:56:46 +0200
Subject: [PATCH 4/4] ARM: nomadik: push accelerometer down to boards
Message-ID: <1438552606-4625-1-git-send-email-linus.walleij@linaro.org>

The two Nomadik variants have the accelerometer mounted on
different I2C lines. Push the definition down to the top-level
board DTS files to get things right.

Signed-off-by: Linus Walleij <linus.walleij at linaro.org>
---
 arch/arm/boot/dts/ste-nomadik-nhk15.dts    | 5 +++++
 arch/arm/boot/dts/ste-nomadik-s8815.dts    | 8 ++++++++
 arch/arm/boot/dts/ste-nomadik-stn8815.dtsi | 5 -----
 3 files changed, 13 insertions(+), 5 deletions(-)

diff --git a/arch/arm/boot/dts/ste-nomadik-nhk15.dts b/arch/arm/boot/dts/ste-nomadik-nhk15.dts
index 9d888b0e75af..4a21c6492dbb 100644
--- a/arch/arm/boot/dts/ste-nomadik-nhk15.dts
+++ b/arch/arm/boot/dts/ste-nomadik-nhk15.dts
@@ -83,6 +83,11 @@
 	};
 
 	i2c0 {
+		lis3lv02dl at 1d {
+			/* Accelerometer */
+			compatible = "st,lis3lv02dl-accel";
+			reg = <0x1d>;
+		};
 		stmpe0: stmpe2401 at 43 {
 			compatible = "st,stmpe2401";
 			reg = <0x43>;
diff --git a/arch/arm/boot/dts/ste-nomadik-s8815.dts b/arch/arm/boot/dts/ste-nomadik-s8815.dts
index 11b5e34150b8..35282c0105c6 100644
--- a/arch/arm/boot/dts/ste-nomadik-s8815.dts
+++ b/arch/arm/boot/dts/ste-nomadik-s8815.dts
@@ -105,6 +105,14 @@
 		};
 	};
 
+	i2c1 {
+		lis3lv02dl at 1d {
+			/* Accelerometer */
+			compatible = "st,lis3lv02dl-accel";
+			reg = <0x1d>;
+		};
+	};
+
 	/* GPIO I2C connected to the USB portions of the STw4811 only */
 	gpio-i2c {
 		compatible = "i2c-gpio";
diff --git a/arch/arm/boot/dts/ste-nomadik-stn8815.dtsi b/arch/arm/boot/dts/ste-nomadik-stn8815.dtsi
index defabe053114..314f59c12162 100644
--- a/arch/arm/boot/dts/ste-nomadik-stn8815.dtsi
+++ b/arch/arm/boot/dts/ste-nomadik-stn8815.dtsi
@@ -726,11 +726,6 @@
 			   compatible = "st,stw5095";
 			   reg = <0x1a>;
 		};
-		lis3lv02dl at 1d {
-			/* Accelerometer */
-			compatible = "st,lis3lv02dl-accel";
-			reg = <0x1d>;
-		};
 	};
 
 	amba {
-- 
2.4.3



From public_timo.s at silentcreek.de  Sun Aug  2 15:00:06 2015
From: public_timo.s at silentcreek.de (Timo Sigurdsson)
Date: Mon,  3 Aug 2015 00:00:06 +0200 (CEST)
Subject: [linux-sunxi] [RFC] ARM: dts: sunxi: Add regulators and
 board-specific operating points for LeMaker BananaPi
In-Reply-To: <55B79FCA.7070907@redhat.com>
References: <1437960486-2809-1-git-send-email-public_timo.s@silentcreek.de>
 <55B5E6DB.8020009@redhat.com>
 <20150727120918.191F76C82FB4@dd34104.kasserver.com>
 <55B62768.6040403@redhat.com>
 <20150728124911.GA2564@lukather><55B790BA.5000509@redhat.com>
 <20150728150929.233B56C80391@dd34104.kasserver.com><55B79FCA.7070907@redhat.com>
Message-ID: <20150802220006.E5BE06C810BC@dd34104.kasserver.com>

Hi Stefan,

you didn't include me in your answer, hence the late reply...

Stefan Monnier schrieb am 29.07.2015 02:02:
>> IMHO for a common maximum opp that's a good approach. But for the lowest
>> frequency setting, it would seem more logical to me, to raise the voltage
>> to a point where all boards will run fine with them, unless those boards
>> cannot handle the frequency regardless of the higher voltage.

> I generally agre, tho IIRC some measurements seem to indicate that the
> lowest frequency settings did not bring much (if any) reduction in power
> consumption, making them rather useless.

That's an interesting point. However, that would be a different discussion. I
wouldn't mind if the 144MHz would be removed - my point was just that if it's 
supposed to be a common setting, it should work on all boards. I posted a patch
today to fix this. [1] That might be a good place to discuss whether this
setting should be removed entirely.

Regards,

Timo

[1] https://groups.google.com/forum/#!topic/linux-sunxi/fIfbdn7mrQA



From linux at arm.linux.org.uk  Sun Aug  2 15:06:26 2015
From: linux at arm.linux.org.uk (Russell King - ARM Linux)
Date: Sun, 2 Aug 2015 23:06:26 +0100
Subject: [PATCH 3/4] ARM: nomadik: move l2x0 setup to device tree
In-Reply-To: <1438552593-4578-1-git-send-email-linus.walleij@linaro.org>
References: <1438552593-4578-1-git-send-email-linus.walleij@linaro.org>
Message-ID: <20150802220626.GG7557@n2100.arm.linux.org.uk>

On Sun, Aug 02, 2015 at 11:56:33PM +0200, Linus Walleij wrote:
> -	/* At full speed latency must be >=2, so 0x249 in low bits */
> -	.l2c_aux_val	= 0x00700249,
> -	.l2c_aux_mask	= 0xfe0fefff,
> +	.l2c_aux_val	= 0x0,
> +	.l2c_aux_mask	= ~0x0UL,

It always amazes me by the things people come up with... what prompted
the addition of "UL" on that constant?  Why do you think it needs it?

A simple:

	.l2c_aux_val	= 0,
	.l2c_aux_mask	= ~0,

will suffice.

-- 
FTTC broadband for 0.8mile line: currently at 10.5Mbps down 400kbps up
according to speedtest.net.


From linus.walleij at linaro.org  Sun Aug  2 15:43:23 2015
From: linus.walleij at linaro.org (Linus Walleij)
Date: Mon, 3 Aug 2015 00:43:23 +0200
Subject: [PATCH 3/4] ARM: nomadik: move l2x0 setup to device tree
In-Reply-To: <20150802220626.GG7557@n2100.arm.linux.org.uk>
References: <1438552593-4578-1-git-send-email-linus.walleij@linaro.org>
 <20150802220626.GG7557@n2100.arm.linux.org.uk>
Message-ID: <CACRpkdZAU8Mjs=uTGs4iFLQ6xYcK1ZUeyh_jL0VbTpRn8yyV2g@mail.gmail.com>

On Mon, Aug 3, 2015 at 12:06 AM, Russell King - ARM Linux
<linux at arm.linux.org.uk> wrote:
> On Sun, Aug 02, 2015 at 11:56:33PM +0200, Linus Walleij wrote:
>> -     /* At full speed latency must be >=2, so 0x249 in low bits */
>> -     .l2c_aux_val    = 0x00700249,
>> -     .l2c_aux_mask   = 0xfe0fefff,
>> +     .l2c_aux_val    = 0x0,
>> +     .l2c_aux_mask   = ~0x0UL,
>
> It always amazes me by the things people come up with... what prompted
> the addition of "UL" on that constant?  Why do you think it needs it?

Good old mindless cut'n'paste.
Will fix, thanks!

Yours,
Linus Walleij


From colin.king at canonical.com  Sun Aug  2 16:10:45 2015
From: colin.king at canonical.com (Colin King)
Date: Mon,  3 Aug 2015 00:10:45 +0100
Subject: [PATCH] pinctrl/mediatek: fix spelling mistake in dev_err error
 message
Message-ID: <1438557045-3590-1-git-send-email-colin.king@canonical.com>

From: Colin Ian King <colin.king at canonical.com>

Trivial change, fix spelling mistake 'invaild' -> 'invalid' in
dev_err message.

Signed-off-by: Colin Ian King <colin.king at canonical.com>
---
 drivers/pinctrl/mediatek/pinctrl-mtk-common.c | 2 +-
 1 file changed, 1 insertion(+), 1 deletion(-)

diff --git a/drivers/pinctrl/mediatek/pinctrl-mtk-common.c b/drivers/pinctrl/mediatek/pinctrl-mtk-common.c
index ad1ea16..5af5441 100644
--- a/drivers/pinctrl/mediatek/pinctrl-mtk-common.c
+++ b/drivers/pinctrl/mediatek/pinctrl-mtk-common.c
@@ -702,7 +702,7 @@ static int mtk_pmx_set_mux(struct pinctrl_dev *pctldev,
 
 	ret = mtk_pctrl_is_function_valid(pctl, g->pin, function);
 	if (!ret) {
-		dev_err(pctl->dev, "invaild function %d on group %d .\n",
+		dev_err(pctl->dev, "invalid function %d on group %d .\n",
 				function, group);
 		return -EINVAL;
 	}
-- 
2.5.0



From julian.calaby at gmail.com  Sun Aug  2 16:35:51 2015
From: julian.calaby at gmail.com (Julian Calaby)
Date: Mon, 3 Aug 2015 09:35:51 +1000
Subject: [linux-sunxi] [PATCH] ARM: dts: sunxi: Raise minimum CPU voltage
 for sun7i-a20 to a level all boards can supply
In-Reply-To: <1438543386-7253-1-git-send-email-public_timo.s@silentcreek.de>
References: <1438543386-7253-1-git-send-email-public_timo.s@silentcreek.de>
Message-ID: <CAGRGNgV6b9yt2HnB2x2Wyc05KEahoX-Y+mVhxsryztcfA36H1g@mail.gmail.com>

Hi Timo,

On Mon, Aug 3, 2015 at 5:23 AM, Timo Sigurdsson
<public_timo.s at silentcreek.de> wrote:
> sun7i-a20.dtsi contains an cpufreq operating point at 0.9 volts. Most A20 boards
> (or all?), however, do not allow the voltage to go below 1.0V. Thus, raise the
> voltage for the lowest operating point to 1.0V so all boards can actually use
> it.

Surely it wouldn't be added here if some could supply 0.9v.

Is the code that uses this smart enough to sensibly switch between two
operating points with the same frequency and different voltages? If
so, maybe just add a 144MHz @ 1.0v operating point?

(Alternatively, would it make sense to modify the code that uses this
to use frequencies with voltages specified that are lower than can be
supplied with the lowest voltage it can?)

Thanks,

-- 
Julian Calaby

Email: julian.calaby at gmail.com
Profile: http://www.google.com/profiles/julian.calaby/


From horms at verge.net.au  Sun Aug  2 17:53:53 2015
From: horms at verge.net.au (Simon Horman)
Date: Mon, 3 Aug 2015 09:53:53 +0900
Subject: [PATCH v2 1/2] ARM: shmobile: r8a7794: add MMCIF DT support
In-Reply-To: <2274701.D1UH0V9VRM@wasted.cogentembedded.com>
References: <1546028.CFITDbxXtD@wasted.cogentembedded.com>
 <2274701.D1UH0V9VRM@wasted.cogentembedded.com>
Message-ID: <20150803005353.GC29555@verge.net.au>

On Fri, Jul 31, 2015 at 12:54:05AM +0300, Sergei Shtylyov wrote:
> Define the generic R8A7794 part of the MMCIF0 device node.
> 
> Based on the orginal patch by Shinobu Uehara <shinobu.uehara.xc at renesas.com>.
> 
> Signed-off-by: Sergei Shtylyov <sergei.shtylyov at cogentembedded.com>
> 
> ---
> Changes in version  2:
> - updated the patch due to the SDHI patch being accepted first;
> - refreshed the patch.

Thanks, I have queued-up this and the following patch.


From Haibo.Chen at freescale.com  Sun Aug  2 18:08:28 2015
From: Haibo.Chen at freescale.com (Chen Bough)
Date: Mon, 3 Aug 2015 01:08:28 +0000
Subject: [PATCH v3 6/6] mmc: sdhci-esdhc-imx: set back the
 burst_length_enable bit to 1
In-Reply-To: <20150731145751.GG27806@shlinux1.ap.freescale.net>
References: <1438160637-28061-1-git-send-email-haibo.chen@freescale.com>
 <1438160637-28061-7-git-send-email-haibo.chen@freescale.com>
 <20150731145751.GG27806@shlinux1.ap.freescale.net>
Message-ID: <BY1PR03MB138838EFB0DE8834DE5889669A770@BY1PR03MB1388.namprd03.prod.outlook.com>



> -----Original Message-----
> From: Dong Aisheng [mailto:aisheng.dong at freescale.com]
> Sent: Friday, July 31, 2015 10:58 PM
> To: Chen Haibo-B51421
> Cc: robh+dt at kernel.org; pawel.moll at arm.com; mark.rutland at arm.com;
> ijc+devicetree at hellion.org.uk; galak at codeaurora.org; shawnguo at kernel.org;
> kernel at pengutronix.de; linux at arm.linux.org.uk; ulf.hansson at linaro.org;
> johan.derycke at barco.com; Estevam Fabio-R49496; Dong Aisheng-B29396;
> devicetree at vger.kernel.org; linux-kernel at vger.kernel.org; linux-arm-
> kernel at lists.infradead.org; linux-mmc at vger.kernel.org
> Subject: Re: [PATCH v3 6/6] mmc: sdhci-esdhc-imx: set back the
> burst_length_enable bit to 1
> 
> On Wed, Jul 29, 2015 at 05:03:57PM +0800, Haibo Chen wrote:
> > Currently we find that if a usdhc is choosed to boot system, then ROM
> > code will set the burst length enable bit of this usdhc as 0.
> >
> > This will make performance drop a lot if this usdhc's burst length is
> > 16. So this patch set back the burst_length_enable bit as 1, which is
> > the default value, and means burst length is enabled for INCR.
> >
> > Signed-off-by: Haibo Chen <haibo.chen at freescale.com>
> > ---
> >  drivers/mmc/host/sdhci-esdhc-imx.c | 11 +++++++++++
> >  1 file changed, 11 insertions(+)
> >
> > diff --git a/drivers/mmc/host/sdhci-esdhc-imx.c
> > b/drivers/mmc/host/sdhci-esdhc-imx.c
> > index 37d0095..dd945e5 100644
> > --- a/drivers/mmc/host/sdhci-esdhc-imx.c
> > +++ b/drivers/mmc/host/sdhci-esdhc-imx.c
> > @@ -32,6 +32,7 @@
> >  #include "sdhci-esdhc.h"
> >
> >  #define	ESDHC_CTRL_D3CD			0x08
> > +#define ESDHC_BURST_LEN_EN_INCR		(1 << 27)
> >  /* VENDOR SPEC register */
> >  #define ESDHC_VENDOR_SPEC		0xc0
> >  #define  ESDHC_VENDOR_SPEC_SDIO_QUIRK	(1 << 1)
> > @@ -1158,6 +1159,16 @@ static int sdhci_esdhc_imx_probe(struct
> platform_device *pdev)
> >  		host->quirks2 |= SDHCI_QUIRK2_PRESET_VALUE_BROKEN;
> >  		host->mmc->caps |= MMC_CAP_1_8V_DDR;
> >
> > +		/*
> > +		 * ROM code will change the burst_length_enable setting to
> > +		 * zero if this usdhc is choosed to boot system. Change it
> > +		 * back here, otherwise it will impact the performance a
> > +		 * lot if the burst length is 16.
> 
> Can you clarify a bit more on why performance drops a lot if burst length
> is 16?
> Caused by the burst length setting did not work due to ROM disabled it?


[haibo] this bit is used to enable/disable the burst length for the external AHB2AXI bridge, 
It's useful especially for INCR transfer because without burst length indicator, the AHB2AXI 
bridge doesn't know the burst length in advance. And without burst length indicator, AHB INCR 
transfers can only be converted to singles on the AXI side.

Seting this bit means burst length enabled for INCR.
If this bit is not set, performance will drop a lot when burst length is 8 or 16. I will add 
this in the commit log.
 
> 
> Regards
> Dong Aisheng
> 
> > +		 */
> > +		writel(readl(host->ioaddr + SDHCI_HOST_CONTROL)
> > +			| ESDHC_BURST_LEN_EN_INCR,
> > +			host->ioaddr + SDHCI_HOST_CONTROL);
> > +
> >  		if (!(imx_data->socdata->flags & ESDHC_FLAG_HS200))
> >  			host->quirks2 |= SDHCI_QUIRK2_BROKEN_HS200;
> >
> > --
> > 1.9.1
> >


From leo.yan at linaro.org  Sun Aug  2 18:13:07 2015
From: leo.yan at linaro.org (Leo Yan)
Date: Mon,  3 Aug 2015 09:13:07 +0800
Subject: [RFC PATCH 0/3] mailbox: hisilicon: add mailbox driver
Message-ID: <1438564390-28111-1-git-send-email-leo.yan@linaro.org>

This patch series is to implement Hisilicon's mailbox driver and enable
the mailbox controller on Hi6220.

The Hisilicon mailbox supports up to 32 channels. Each channel is
unidirectional with a maximum message size of 8 words. I/O is performed
using register access (there is no DMA) and the cell raises an interrupt
when messages are received.

For easily extending for Hisilicon series SoCs (SoCs may have difference
for register's definition with each other), so firstly implement common
mailbox driver; this common mailbox driver provides three mainly
functionality:

 - help register channels into framework;
 - hook low level callback functions for register's operations;
 - Enhance rx channel's message queue, which is based on the code in
   drivers/mailbox/omap-mailbox.c.

Base on this common driver, also has enabled Hi6220 mailbox controller.


Leo Yan (3):
  dt-bindings: mailbox: Document Hisilicon mailbox driver
  mailbox: Hisilicon: add mailbox driver
  arm64: dts: add Hi6220 mailbox node

 .../devicetree/bindings/mailbox/hisi-mailbox.txt   |  57 ++++
 arch/arm64/boot/dts/hisilicon/hi6220-hikey.dts     |  20 +-
 arch/arm64/boot/dts/hisilicon/hi6220.dtsi          |   8 +
 drivers/mailbox/Kconfig                            |   2 +
 drivers/mailbox/Makefile                           |   2 +
 drivers/mailbox/hisilicon/Kconfig                  |  13 +
 drivers/mailbox/hisilicon/Makefile                 |   2 +
 drivers/mailbox/hisilicon/common.c                 | 282 +++++++++++++++++++
 drivers/mailbox/hisilicon/common.h                 | 114 ++++++++
 drivers/mailbox/hisilicon/hi6220-mailbox.c         | 305 +++++++++++++++++++++
 10 files changed, 802 insertions(+), 3 deletions(-)
 create mode 100644 Documentation/devicetree/bindings/mailbox/hisi-mailbox.txt
 create mode 100644 drivers/mailbox/hisilicon/Kconfig
 create mode 100644 drivers/mailbox/hisilicon/Makefile
 create mode 100644 drivers/mailbox/hisilicon/common.c
 create mode 100644 drivers/mailbox/hisilicon/common.h
 create mode 100644 drivers/mailbox/hisilicon/hi6220-mailbox.c

-- 
1.9.1



From leo.yan at linaro.org  Sun Aug  2 18:13:08 2015
From: leo.yan at linaro.org (Leo Yan)
Date: Mon,  3 Aug 2015 09:13:08 +0800
Subject: [RFC PATCH 1/3] dt-bindings: mailbox: Document Hisilicon mailbox
 driver
In-Reply-To: <1438564390-28111-1-git-send-email-leo.yan@linaro.org>
References: <1438564390-28111-1-git-send-email-leo.yan@linaro.org>
Message-ID: <1438564390-28111-2-git-send-email-leo.yan@linaro.org>

Document the new compatible for Hisilicon mailbox driver.

Signed-off-by: Leo Yan <leo.yan at linaro.org>
---
 .../devicetree/bindings/mailbox/hisi-mailbox.txt   | 57 ++++++++++++++++++++++
 1 file changed, 57 insertions(+)
 create mode 100644 Documentation/devicetree/bindings/mailbox/hisi-mailbox.txt

diff --git a/Documentation/devicetree/bindings/mailbox/hisi-mailbox.txt b/Documentation/devicetree/bindings/mailbox/hisi-mailbox.txt
new file mode 100644
index 0000000..898823d
--- /dev/null
+++ b/Documentation/devicetree/bindings/mailbox/hisi-mailbox.txt
@@ -0,0 +1,57 @@
+Hisilicon Mailbox Driver
+========================
+
+The Hisilicon mailbox supports up to 32 channels. Each channel
+is unidirectional with a maximum message size of 8 words. I/O is
+performed using register access (there is no DMA) and the cell
+raises an interrupt when messages are received.
+
+Mailbox Device Node:
+====================
+
+Required properties:
+--------------------
+- compatible:		Shall be "hisilicon,hi6220-mbox"
+- reg:			Contains the mailbox register address range (base
+			address and length); the first item is for IPC
+			registers, the second item is shared buffer for
+			slots.
+- #mbox-cells		Common mailbox binding property to identify the number
+			of cells required for the mailbox specifier. Should be 1.
+- interrupts:		Contains the interrupt information for the mailbox
+			device. The format is dependent on which interrupt
+			controller the SoCs use.
+
+Example:
+--------
+
+	mailbox: mailbox at F7510000 {
+		#mbox-cells = <1>;
+		compatible = "hisilicon,hi6220-mbox";
+		reg = <0x0 0xF7510000 0x0 0x1000>, /* IPC_S */
+		      <0x0 0x06DFF800 0x0 0x0800>; /* Mailbox */
+		interrupt-parent = <&gic>;
+		interrupts = <0 94 4>;
+	};
+
+
+Mailbox client
+===============
+
+"mboxes" and the optional "mbox-names" (please see
+Documentation/devicetree/bindings/mailbox/mailbox.txt for details). Each value
+of the mboxes property should contain a phandle to the mailbox controller
+device node and second argument is the channel index. It must be 0 (hardware
+support only one channel). The equivalent "mbox-names" property value can be
+used to give a name to the communication channel to be used by the client user.
+
+Example:
+--------
+
+	stub_clock: stub_clock {
+		compatible = "hisilicon,hi6220-stub-clk";
+		hisilicon,hi6220-clk-sram = <&sram>;
+		#clock-cells = <1>;
+		mbox-names = "mbox-tx";
+		mboxes = <&mailbox 1>;
+	};
-- 
1.9.1



From leo.yan at linaro.org  Sun Aug  2 18:13:09 2015
From: leo.yan at linaro.org (Leo Yan)
Date: Mon,  3 Aug 2015 09:13:09 +0800
Subject: [RFC PATCH 2/3] mailbox: Hisilicon: add mailbox driver
In-Reply-To: <1438564390-28111-1-git-send-email-leo.yan@linaro.org>
References: <1438564390-28111-1-git-send-email-leo.yan@linaro.org>
Message-ID: <1438564390-28111-3-git-send-email-leo.yan@linaro.org>

Add Hisilicon mailbox's common driver, it registers mailbox channels
into framework; it also invokes low level callback functions for
register's related operations. Enhance rx channel's message queue,
which is based on the code in drivers/mailbox/omap-mailbox.c.

Enable Hi6220 mailbox driver as the first platform to use this
framework. Hi6220's mailbox communicates with MCU; for sending data,
it can support two methods for low level implementation: one is to
use interrupt as acknowledge, another is automatic mode which without
any acknowledge. These two methods have been supported in the driver;
for receiving data, it will depend on the interrupt to notify the
channel has incoming message.

Now mailbox driver is used to send message to MCU to control dynamic
voltage and frequency scaling for CPU, GPU and DDR.

Signed-off-by: Leo Yan <leo.yan at linaro.org>
---
 drivers/mailbox/Kconfig                    |   2 +
 drivers/mailbox/Makefile                   |   2 +
 drivers/mailbox/hisilicon/Kconfig          |  13 ++
 drivers/mailbox/hisilicon/Makefile         |   2 +
 drivers/mailbox/hisilicon/common.c         | 282 ++++++++++++++++++++++++++
 drivers/mailbox/hisilicon/common.h         | 114 +++++++++++
 drivers/mailbox/hisilicon/hi6220-mailbox.c | 305 +++++++++++++++++++++++++++++
 7 files changed, 720 insertions(+)
 create mode 100644 drivers/mailbox/hisilicon/Kconfig
 create mode 100644 drivers/mailbox/hisilicon/Makefile
 create mode 100644 drivers/mailbox/hisilicon/common.c
 create mode 100644 drivers/mailbox/hisilicon/common.h
 create mode 100644 drivers/mailbox/hisilicon/hi6220-mailbox.c

diff --git a/drivers/mailbox/Kconfig b/drivers/mailbox/Kconfig
index e269f08..a426901 100644
--- a/drivers/mailbox/Kconfig
+++ b/drivers/mailbox/Kconfig
@@ -70,4 +70,6 @@ config BCM2835_MBOX
 	  the services of the Videocore. Say Y here if you want to use the
 	  BCM2835 Mailbox.
 
+source "drivers/mailbox/hisilicon/Kconfig"
+
 endif
diff --git a/drivers/mailbox/Makefile b/drivers/mailbox/Makefile
index 8e6d822..1e82dfb 100644
--- a/drivers/mailbox/Makefile
+++ b/drivers/mailbox/Makefile
@@ -13,3 +13,5 @@ obj-$(CONFIG_PCC)		+= pcc.o
 obj-$(CONFIG_ALTERA_MBOX)	+= mailbox-altera.o
 
 obj-$(CONFIG_BCM2835_MBOX)	+= bcm2835-mailbox.o
+
+obj-$(CONFIG_HISI_MBOX)		+= hisilicon/
diff --git a/drivers/mailbox/hisilicon/Kconfig b/drivers/mailbox/hisilicon/Kconfig
new file mode 100644
index 0000000..87548a9
--- /dev/null
+++ b/drivers/mailbox/hisilicon/Kconfig
@@ -0,0 +1,13 @@
+config HISI_MBOX
+	bool "Hisilicon's Mailbox"
+	depends on ARCH_HISI || OF
+	help
+	  Support for mailbox drivers on Hisilicon series of SoCs.
+
+config HI6220_MBOX
+	tristate "Hi6220 Mailbox Controller"
+	depends on HISI_MBOX
+	help
+	  An implementation of the hi6220 mailbox. It is used to send message
+	  between application processors and MCU. Say Y here if you want to build
+	  the Hi6220 mailbox controller driver.
diff --git a/drivers/mailbox/hisilicon/Makefile b/drivers/mailbox/hisilicon/Makefile
new file mode 100644
index 0000000..59135b0
--- /dev/null
+++ b/drivers/mailbox/hisilicon/Makefile
@@ -0,0 +1,2 @@
+obj-$(CONFIG_HISI_MBOX) += common.o
+obj-$(CONFIG_HI6220_MBOX) += hi6220-mailbox.o
diff --git a/drivers/mailbox/hisilicon/common.c b/drivers/mailbox/hisilicon/common.c
new file mode 100644
index 0000000..c3c8e49
--- /dev/null
+++ b/drivers/mailbox/hisilicon/common.c
@@ -0,0 +1,282 @@
+/*
+ * Hisilicon mailbox common driver
+ *
+ * This is skeleton driver for Hisilicon's mailbox, it registers mailbox
+ * channels into framework; it also need invoke low level's callback
+ * functions for low level operations. RX channel's message queue is
+ * based on the code written in drivers/mailbox/omap-mailbox.c.
+
+ * Copyright (c) 2015 Hisilicon Limited.
+ * Copyright (c) 2015 Linaro Limited.
+ *
+ * Author: Leo Yan <leo.yan at linaro.org>
+ *
+ * This program is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation, version 2 of the License.
+ *
+ * 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/device.h>
+#include <linux/err.h>
+#include <linux/interrupt.h>
+#include <linux/slab.h>
+
+#include "common.h"
+
+#define MBOX_MSG_LEN		(32)
+#define MBOX_MSG_NUM		(16)
+#define MBOX_MSG_FIFO_SIZE	(MBOX_MSG_LEN * MBOX_MSG_NUM)
+
+static bool hisi_mbox_last_tx_done(struct mbox_chan *chan)
+{
+	struct hisi_mbox_chan *mchan = chan->con_priv;
+	struct hisi_mbox_hw *mbox_hw = mchan->mbox_hw;
+
+	/* Only set idle state for polling mode */
+	BUG_ON(mbox_hw->tx_irq_mode);
+
+	return mbox_hw->ops->tx_is_done(mchan);
+}
+
+static int hisi_mbox_send_data(struct mbox_chan *chan, void *msg)
+{
+	struct hisi_mbox_chan *mchan = chan->con_priv;
+	struct hisi_mbox_hw *mbox_hw = mchan->mbox_hw;
+
+	return mbox_hw->ops->tx(mchan, msg, MBOX_MSG_LEN);
+}
+
+static void hisi_mbox_rx_work(struct work_struct *work)
+{
+	struct hisi_mbox_queue *mq =
+			container_of(work, struct hisi_mbox_queue, work);
+	struct mbox_chan *chan = mq->chan;
+	struct hisi_mbox_chan *mchan = chan->con_priv;
+	struct hisi_mbox_hw *mbox_hw = mchan->mbox_hw;
+
+	char msg[MBOX_MSG_LEN];
+	int len;
+
+	while (kfifo_len(&mq->fifo) >= sizeof(msg)) {
+		len = kfifo_out(&mq->fifo, (unsigned char *)&msg, sizeof(msg));
+		WARN_ON(len != sizeof(msg));
+
+		mbox_chan_received_data(chan, (void *)msg);
+		spin_lock_irq(&mq->lock);
+		if (mq->full) {
+			mq->full = false;
+			mbox_hw->ops->enable_irq(mchan);
+		}
+		spin_unlock_irq(&mq->lock);
+	}
+}
+
+static void hisi_mbox_tx_interrupt(struct mbox_chan *chan)
+{
+	struct hisi_mbox_chan *mchan = chan->con_priv;
+	struct hisi_mbox_hw *mbox_hw = mchan->mbox_hw;
+
+	mbox_hw->ops->clear_irq(mchan);
+	mbox_hw->ops->ack(mchan);
+
+	mbox_chan_txdone(chan, 0);
+}
+
+static void hisi_mbox_rx_interrupt(struct mbox_chan *chan)
+{
+	struct hisi_mbox_chan *mchan = chan->con_priv;
+	struct hisi_mbox_queue *mq = mchan->mq;
+	struct hisi_mbox_hw *mbox_hw = mchan->mbox_hw;
+	char msg[MBOX_MSG_LEN];
+	int len;
+
+	if (unlikely(kfifo_avail(&mq->fifo) < sizeof(msg))) {
+		mbox_hw->ops->disable_irq(mchan);
+		mq->full = true;
+		goto nomem;
+	}
+
+	mbox_hw->ops->rx(mchan, msg, sizeof(msg));
+
+	len = kfifo_in(&mq->fifo, (unsigned char *)&msg, sizeof(msg));
+	WARN_ON(len != sizeof(msg));
+
+	mbox_hw->ops->ack(mchan);
+nomem:
+	schedule_work(&mq->work);
+}
+
+static irqreturn_t hisi_mbox_interrupt(int irq, void *p)
+{
+	struct hisi_mbox *mbox = p;
+	struct hisi_mbox_hw *mbox_hw = mbox->hw;
+	struct hisi_mbox_chan *mchan;
+	struct mbox_chan *chan;
+	unsigned int state;
+	unsigned int intr_bit;
+
+	state = mbox_hw->ops->get_pending_irq(mbox_hw);
+	if (!state) {
+		dev_warn(mbox_hw->dev, "%s: spurious interrupt\n",
+			 __func__);
+		return IRQ_HANDLED;
+	}
+
+	while (state) {
+		intr_bit = __ffs(state);
+		state &= (state - 1);
+
+		chan = mbox->irq_map_chan[intr_bit];
+		if (!chan) {
+			dev_warn(mbox_hw->dev, "%s: unexpected irq vector %d\n",
+				 __func__, intr_bit);
+			continue;
+		}
+
+		mchan = chan->con_priv;
+		if (mchan->dir == MBOX_TX)
+			hisi_mbox_tx_interrupt(chan);
+		else
+			hisi_mbox_rx_interrupt(chan);
+	}
+
+	return IRQ_HANDLED;
+}
+
+static struct hisi_mbox_queue *hisi_mbox_queue_alloc(
+		struct mbox_chan *chan,
+		void (*work)(struct work_struct *))
+{
+	struct hisi_mbox_queue *mq;
+
+	if (!work)
+		return NULL;
+
+	mq = kzalloc(sizeof(struct hisi_mbox_queue), GFP_KERNEL);
+	if (!mq)
+		return NULL;
+
+	spin_lock_init(&mq->lock);
+
+	if (kfifo_alloc(&mq->fifo, MBOX_MSG_FIFO_SIZE, GFP_KERNEL))
+		goto error;
+
+	mq->chan = chan;
+	INIT_WORK(&mq->work, work);
+	return mq;
+
+error:
+	kfree(mq);
+	return NULL;
+}
+
+static void hisi_mbox_queue_free(struct hisi_mbox_queue *mq)
+{
+	kfifo_free(&mq->fifo);
+	kfree(mq);
+}
+
+static int hisi_mbox_startup(struct mbox_chan *chan)
+{
+	struct hisi_mbox_chan *mchan = chan->con_priv;
+	struct hisi_mbox_hw *mbox_hw = mchan->mbox_hw;
+	struct hisi_mbox *mbox = mchan->mbox_hw->parent;
+
+	struct hisi_mbox_queue *mq;
+	unsigned int irq = mchan->local_irq;
+
+	mq = hisi_mbox_queue_alloc(chan, hisi_mbox_rx_work);
+	if (!mq)
+		return -ENOMEM;
+	mchan->mq = mq;
+
+	mbox->irq_map_chan[irq] = (void *)chan;
+	return mbox_hw->ops->startup(mchan);
+}
+
+static void hisi_mbox_shutdown(struct mbox_chan *chan)
+{
+	struct hisi_mbox_chan *mchan = chan->con_priv;
+	struct hisi_mbox_hw *mbox_hw = mchan->mbox_hw;
+	struct hisi_mbox *mbox = mbox_hw->parent;
+	unsigned int irq = mchan->local_irq;
+
+	mbox_hw->ops->shutdown(mchan);
+
+	mbox->irq_map_chan[irq] = NULL;
+	flush_work(&mchan->mq->work);
+	hisi_mbox_queue_free(mchan->mq);
+}
+
+static struct mbox_chan_ops hisi_mbox_chan_ops = {
+	.send_data    = hisi_mbox_send_data,
+	.startup      = hisi_mbox_startup,
+	.shutdown     = hisi_mbox_shutdown,
+	.last_tx_done = hisi_mbox_last_tx_done,
+};
+
+int hisi_mbox_register(struct hisi_mbox_hw *mbox_hw)
+{
+	struct device *dev = mbox_hw->dev;
+	struct hisi_mbox *mbox;
+	int i, err;
+
+	mbox = devm_kzalloc(dev, sizeof(*mbox), GFP_KERNEL);
+	if (!mbox)
+		return -ENOMEM;
+
+	mbox->hw = mbox_hw;
+	mbox->chan = devm_kzalloc(dev,
+		mbox_hw->chan_num * sizeof(struct mbox_chan), GFP_KERNEL);
+	if (!mbox)
+		return -ENOMEM;
+
+	err = devm_request_irq(dev, mbox_hw->irq, hisi_mbox_interrupt, 0,
+			dev_name(dev), mbox);
+	if (err) {
+		dev_err(dev, "Failed to register a mailbox IRQ handler: %d\n",
+			err);
+		return -ENODEV;
+	}
+
+	for (i = 0; i < mbox_hw->chan_num; i++) {
+		mbox->chan[i].con_priv = &mbox_hw->chan[i];
+		mbox->irq_map_chan[i] = NULL;
+	}
+
+	mbox->controller.dev = dev;
+	mbox->controller.chans = &mbox->chan[0];
+	mbox->controller.num_chans = mbox_hw->chan_num;
+	mbox->controller.ops = &hisi_mbox_chan_ops;
+
+	if (mbox_hw->tx_irq_mode)
+		mbox->controller.txdone_irq = true;
+	else {
+		mbox->controller.txdone_poll = true;
+		mbox->controller.txpoll_period = 5;
+	}
+
+	err = mbox_controller_register(&mbox->controller);
+	if (err) {
+		dev_err(dev, "Failed to register mailbox %d\n", err);
+		return err;
+	}
+
+	mbox_hw->parent = mbox;
+	return 0;
+}
+EXPORT_SYMBOL_GPL(hisi_mbox_register);
+
+void hisi_mbox_unregister(struct hisi_mbox_hw *mbox_hw)
+{
+	struct hisi_mbox *mbox = mbox_hw->parent;
+
+	mbox_controller_unregister(&mbox->controller);
+}
+EXPORT_SYMBOL_GPL(hisi_mbox_unregister);
diff --git a/drivers/mailbox/hisilicon/common.h b/drivers/mailbox/hisilicon/common.h
new file mode 100644
index 0000000..c2199e2
--- /dev/null
+++ b/drivers/mailbox/hisilicon/common.h
@@ -0,0 +1,114 @@
+/*
+ * Hisilicon mailbox definition
+ *
+ * Copyright (c) 2015 Hisilicon Limited.
+ * Copyright (c) 2015 Linaro Limited.
+ *
+ * Author: Leo Yan <leo.yan at linaro.org>
+ *
+ * This program is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation, version 2 of the License.
+ *
+ * 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 __HISI_MBOX_H
+#define __HISI_MBOX_H
+
+#include <linux/device.h>
+#include <linux/io.h>
+#include <linux/kfifo.h>
+#include <linux/mailbox_controller.h>
+#include <linux/spinlock.h>
+
+#define MBOX_MAX_CHANS		32
+#define MBOX_RX			0x0
+#define MBOX_TX			0x1
+
+struct hisi_mbox_queue {
+	spinlock_t lock;
+	struct kfifo fifo;
+	struct work_struct work;
+	struct mbox_chan *chan;
+	bool full;
+};
+
+struct hisi_mbox_chan {
+
+	/*
+	 * Description for channel's hardware info:
+	 * - direction;
+	 * - peer core id for communication;
+	 * - local irq vector or number;
+	 * - remoted irq vector or number for peer core;
+	 */
+	unsigned int dir;
+	unsigned int peer_core;
+	unsigned int remote_irq;
+	unsigned int local_irq;
+
+	/*
+	 * Slot address is cached value derived from index
+	 * within buffer for every channel
+	 */
+	void __iomem *slot;
+
+	/* For rx's fifo operations */
+	struct hisi_mbox_queue *mq;
+
+	struct hisi_mbox_hw *mbox_hw;
+};
+
+struct hisi_mbox_ops {
+	int (*startup)(struct hisi_mbox_chan *chan);
+	void (*shutdown)(struct hisi_mbox_chan *chan);
+
+	int (*rx)(struct hisi_mbox_chan *chan, void *msg, int len);
+	int (*tx)(struct hisi_mbox_chan *chan, void *msg, int len);
+	int (*tx_is_done)(struct hisi_mbox_chan *chan);
+	int (*ack)(struct hisi_mbox_chan *chan);
+
+	u32 (*get_pending_irq)(struct hisi_mbox_hw *mbox_hw);
+
+	void (*clear_irq)(struct hisi_mbox_chan *chan);
+	void (*enable_irq)(struct hisi_mbox_chan *chan);
+	void (*disable_irq)(struct hisi_mbox_chan *chan);
+};
+
+struct hisi_mbox_hw {
+	struct device *dev;
+
+	unsigned int irq;
+
+	/* flag of enabling tx's irq mode */
+	bool tx_irq_mode;
+
+	/* region for ipc event */
+	void __iomem *ipc;
+
+	/* region for share mem */
+	void __iomem *buf;
+
+	unsigned int chan_num;
+	struct hisi_mbox_chan *chan;
+	struct hisi_mbox_ops *ops;
+	struct hisi_mbox *parent;
+};
+
+struct hisi_mbox {
+	struct hisi_mbox_hw *hw;
+
+	void *irq_map_chan[MBOX_MAX_CHANS];
+	struct mbox_chan *chan;
+	struct mbox_controller controller;
+};
+
+extern int hisi_mbox_register(struct hisi_mbox_hw *mbox_hw);
+extern void hisi_mbox_unregister(struct hisi_mbox_hw *mbox_hw);
+
+#endif /* __HISI_MBOX_H */
diff --git a/drivers/mailbox/hisilicon/hi6220-mailbox.c b/drivers/mailbox/hisilicon/hi6220-mailbox.c
new file mode 100644
index 0000000..099e21d
--- /dev/null
+++ b/drivers/mailbox/hisilicon/hi6220-mailbox.c
@@ -0,0 +1,305 @@
+/*
+ * Hisilicon's Hi6220 mailbox low level driver
+ *
+ * Copyright (c) 2015 Hisilicon Limited.
+ * Copyright (c) 2015 Linaro Limited.
+ *
+ * Author: Leo Yan <leo.yan at linaro.org>
+ *
+ * This program is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation, version 2 of the License.
+ *
+ * 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/err.h>
+#include <linux/module.h>
+#include <linux/of_address.h>
+#include <linux/of_irq.h>
+#include <linux/platform_device.h>
+#include <linux/slab.h>
+
+#include "common.h"
+
+#define HI6220_MBOX_CHAN_NUM			2
+#define HI6220_MBOX_CHAN_SLOT_SIZE		(1 << 6)
+
+/* Status & Mode Register */
+#define HI6220_MBOX_MODE_REG			(0x0)
+
+#define HI6220_MBOX_STATUS_MASK			(0xF << 4)
+#define HI6220_MBOX_STATUS_IDLE			(0x1 << 4)
+#define HI6220_MBOX_STATUS_TX			(0x2 << 4)
+#define HI6220_MBOX_STATUS_RX			(0x4 << 4)
+#define HI6220_MBOX_STATUS_ACK			(0x8 << 4)
+#define HI6220_MBOX_ACK_CONFIG_MASK		(0x1 << 0)
+#define HI6220_MBOX_ACK_AUTOMATIC		(0x1 << 0)
+#define HI6220_MBOX_ACK_IRQ			(0x0 << 0)
+
+/* Data Registers */
+#define HI6220_MBOX_DATA_REG(i)			(0x4 + (i << 2))
+
+/* ACPU Interrupt Register */
+#define HI6220_MBOX_ACPU_INT_RAW_REG		(0x400)
+#define HI6220_MBOX_ACPU_INT_MSK_REG		(0x404)
+#define HI6220_MBOX_ACPU_INT_STAT_REG		(0x408)
+#define HI6220_MBOX_ACPU_INT_CLR_REG		(0x40c)
+#define HI6220_MBOX_ACPU_INT_ENA_REG		(0x500)
+#define HI6220_MBOX_ACPU_INT_DIS_REG		(0x504)
+
+/* MCU Interrupt Register */
+#define HI6220_MBOX_MCU_INT_RAW_REG		(0x420)
+
+/* Core Id */
+#define HI6220_CORE_ACPU			(0x0)
+#define HI6220_CORE_MCU				(0x2)
+
+static u32 hi6220_mbox_get_status(struct hisi_mbox_chan *chan)
+{
+	u32 status;
+
+	status = readl(chan->slot + HI6220_MBOX_MODE_REG);
+	return status & HI6220_MBOX_STATUS_MASK;
+}
+
+static void hi6220_mbox_set_status(struct hisi_mbox_chan *chan, u32 val)
+{
+	u32 status;
+
+	status = readl(chan->slot + HI6220_MBOX_MODE_REG);
+	status &= ~HI6220_MBOX_STATUS_MASK;
+	status |= val;
+	writel(status, chan->slot + HI6220_MBOX_MODE_REG);
+}
+
+static void hi6220_mbox_set_mode(struct hisi_mbox_chan *chan, u32 val)
+{
+	u32 mode;
+
+	mode = readl(chan->slot + HI6220_MBOX_MODE_REG);
+	mode &= ~HI6220_MBOX_ACK_CONFIG_MASK;
+	mode |= val;
+	writel(mode, chan->slot + HI6220_MBOX_MODE_REG);
+}
+
+static void hi6220_mbox_clear_irq(struct hisi_mbox_chan *chan)
+{
+	struct hisi_mbox_hw *mbox_hw = chan->mbox_hw;
+	int irq = chan->local_irq;
+
+	writel(1 << irq, mbox_hw->ipc + HI6220_MBOX_ACPU_INT_CLR_REG);
+}
+
+static void hi6220_mbox_enable_irq(struct hisi_mbox_chan *chan)
+{
+	struct hisi_mbox_hw *mbox_hw = chan->mbox_hw;
+	int irq = chan->local_irq;
+
+	writel(1 << irq, mbox_hw->ipc + HI6220_MBOX_ACPU_INT_ENA_REG);
+}
+
+static void hi6220_mbox_disable_irq(struct hisi_mbox_chan *chan)
+{
+	struct hisi_mbox_hw *mbox_hw = chan->mbox_hw;
+	int irq = chan->local_irq;
+
+	writel(1 << irq, mbox_hw->ipc + HI6220_MBOX_ACPU_INT_DIS_REG);
+}
+
+static u32 hi6220_mbox_get_pending_irq(struct hisi_mbox_hw *mbox_hw)
+{
+	return readl(mbox_hw->ipc + HI6220_MBOX_ACPU_INT_STAT_REG);
+}
+
+static int hi6220_mbox_startup(struct hisi_mbox_chan *chan)
+{
+	hi6220_mbox_enable_irq(chan);
+	return 0;
+}
+
+static void hi6220_mbox_shutdown(struct hisi_mbox_chan *chan)
+{
+	hi6220_mbox_disable_irq(chan);
+}
+
+static int hi6220_mbox_rx(struct hisi_mbox_chan *chan, void *msg, int len)
+{
+	int *buf = msg;
+	int i;
+
+	for (i = 0; i < (len >> 2); i++)
+		buf[i] = readl(chan->slot + HI6220_MBOX_DATA_REG(i));
+
+	/* clear IRQ source */
+	hi6220_mbox_clear_irq(chan);
+	hi6220_mbox_set_status(chan, HI6220_MBOX_STATUS_IDLE);
+	return len;
+}
+
+static int hi6220_mbox_tx(struct hisi_mbox_chan *chan, void *msg, int len)
+{
+	struct hisi_mbox_hw *mbox_hw = chan->mbox_hw;
+	int *buf = msg;
+	int irq = chan->remote_irq, i;
+
+	hi6220_mbox_set_status(chan, HI6220_MBOX_STATUS_TX);
+
+	if (mbox_hw->tx_irq_mode)
+		hi6220_mbox_set_mode(chan, HI6220_MBOX_ACK_IRQ);
+	else
+		hi6220_mbox_set_mode(chan, HI6220_MBOX_ACK_AUTOMATIC);
+
+	for (i = 0; i < (len >> 2); i++)
+		writel(buf[i], chan->slot + HI6220_MBOX_DATA_REG(i));
+
+	/* trigger remote request */
+	writel(1 << irq, mbox_hw->ipc + HI6220_MBOX_MCU_INT_RAW_REG);
+	return 0;
+}
+
+static int hi6220_mbox_tx_is_done(struct hisi_mbox_chan *chan)
+{
+	int status;
+
+	status = hi6220_mbox_get_status(chan);
+	return (status == HI6220_MBOX_STATUS_IDLE);
+}
+
+static int hi6220_mbox_ack(struct hisi_mbox_chan *chan)
+{
+	hi6220_mbox_set_status(chan, HI6220_MBOX_STATUS_IDLE);
+	return 0;
+}
+
+static struct hisi_mbox_ops hi6220_mbox_ops = {
+	.startup	 = hi6220_mbox_startup,
+	.shutdown	 = hi6220_mbox_shutdown,
+
+	.clear_irq	 = hi6220_mbox_clear_irq,
+	.enable_irq	 = hi6220_mbox_enable_irq,
+	.disable_irq	 = hi6220_mbox_disable_irq,
+	.get_pending_irq = hi6220_mbox_get_pending_irq,
+
+	.rx		 = hi6220_mbox_rx,
+	.tx		 = hi6220_mbox_tx,
+	.tx_is_done	 = hi6220_mbox_tx_is_done,
+	.ack		 = hi6220_mbox_ack,
+};
+
+static void hi6220_mbox_init_hw(struct hisi_mbox_hw *mbox_hw)
+{
+	struct hisi_mbox_chan init_data[HI6220_MBOX_CHAN_NUM] = {
+		{ MBOX_RX, HI6220_CORE_MCU, 1, 10 },
+		{ MBOX_TX, HI6220_CORE_MCU, 0, 11 },
+	};
+	struct hisi_mbox_chan *chan = mbox_hw->chan;
+	int i;
+
+	for (i = 0; i < HI6220_MBOX_CHAN_NUM; i++) {
+		memcpy(&chan[i], &init_data[i], sizeof(*chan));
+		chan[i].slot = mbox_hw->buf + HI6220_MBOX_CHAN_SLOT_SIZE;
+		chan[i].mbox_hw = mbox_hw;
+	}
+
+	/* mask and clear all interrupt vectors */
+	writel(0x0,  mbox_hw->ipc + HI6220_MBOX_ACPU_INT_MSK_REG);
+	writel(~0x0, mbox_hw->ipc + HI6220_MBOX_ACPU_INT_CLR_REG);
+
+	/* use interrupt for tx's ack */
+	mbox_hw->tx_irq_mode = true;
+
+	/* set low level ops */
+	mbox_hw->ops = &hi6220_mbox_ops;
+}
+
+static const struct of_device_id hi6220_mbox_of_match[] = {
+	{ .compatible = "hisilicon,hi6220-mbox", },
+	{},
+};
+MODULE_DEVICE_TABLE(of, hi6220_mbox_of_match);
+
+static int hi6220_mbox_probe(struct platform_device *pdev)
+{
+	struct device *dev = &pdev->dev;
+	struct hisi_mbox_hw *mbox_hw;
+	struct resource *res;
+	int err;
+
+	mbox_hw = devm_kzalloc(dev, sizeof(*mbox_hw), GFP_KERNEL);
+	if (!mbox_hw)
+		return -ENOMEM;
+
+	mbox_hw->dev = dev;
+	mbox_hw->chan_num = HI6220_MBOX_CHAN_NUM;
+	mbox_hw->chan = devm_kzalloc(dev,
+		mbox_hw->chan_num * sizeof(struct hisi_mbox_chan), GFP_KERNEL);
+	if (!mbox_hw->chan)
+		return -ENOMEM;
+
+	mbox_hw->irq = platform_get_irq(pdev, 0);
+	if (mbox_hw->irq < 0)
+		return mbox_hw->irq;
+
+	res = platform_get_resource(pdev, IORESOURCE_MEM, 0);
+	mbox_hw->ipc = devm_ioremap_resource(dev, res);
+	if (IS_ERR(mbox_hw->ipc)) {
+		dev_err(dev, "ioremap ipc failed\n");
+		return PTR_ERR(mbox_hw->ipc);
+	}
+
+	res = platform_get_resource(pdev, IORESOURCE_MEM, 1);
+	mbox_hw->buf = devm_ioremap_resource(dev, res);
+	if (IS_ERR(mbox_hw->buf)) {
+		dev_err(dev, "ioremap buffer failed\n");
+		return PTR_ERR(mbox_hw->buf);
+	}
+
+	hi6220_mbox_init_hw(mbox_hw);
+
+	err = hisi_mbox_register(mbox_hw);
+	if (err)
+		return err;
+
+	platform_set_drvdata(pdev, mbox_hw);
+	dev_info(dev, "Mailbox enabled\n");
+	return 0;
+}
+
+static int hi6220_mbox_remove(struct platform_device *pdev)
+{
+	struct hisi_mbox_hw *mbox_hw = platform_get_drvdata(pdev);
+
+	hisi_mbox_unregister(mbox_hw);
+	return 0;
+}
+
+static struct platform_driver hi6220_mbox_driver = {
+	.driver = {
+		.name = "hi6220-mbox",
+		.owner = THIS_MODULE,
+		.of_match_table = of_match_ptr(hi6220_mbox_of_match),
+	},
+	.probe	= hi6220_mbox_probe,
+	.remove	= hi6220_mbox_remove,
+};
+
+static int __init hi6220_mbox_init(void)
+{
+	return platform_driver_register(&hi6220_mbox_driver);
+}
+module_init(hi6220_mbox_init);
+
+static void __exit hi6220_mbox_exit(void)
+{
+	platform_driver_unregister(&hi6220_mbox_driver);
+}
+module_exit(hi6220_mbox_exit);
+
+MODULE_AUTHOR("Leo Yan <leo.yan at linaro.org>");
+MODULE_DESCRIPTION("Hi6220 mailbox driver");
+MODULE_LICENSE("GPL v2");
-- 
1.9.1



From leo.yan at linaro.org  Sun Aug  2 18:13:10 2015
From: leo.yan at linaro.org (Leo Yan)
Date: Mon,  3 Aug 2015 09:13:10 +0800
Subject: [RFC PATCH 3/3] arm64: dts: add Hi6220 mailbox node
In-Reply-To: <1438564390-28111-1-git-send-email-leo.yan@linaro.org>
References: <1438564390-28111-1-git-send-email-leo.yan@linaro.org>
Message-ID: <1438564390-28111-4-git-send-email-leo.yan@linaro.org>

On Hi6220, below memory regions in DDR have specific purpose:

- 0x05e0,0000 - 0x05ef,ffff: For MCU firmware using at runtime;
- 0x0740,f000 - 0x0740,ffff: For MCU firmware's section;
- 0x06df,f000 - 0x06df,ffff: For mailbox message data.

This patch reserves these memory regions and add device node for
mailbox in dts.

Signed-off-by: Leo Yan <leo.yan at linaro.org>
---
 arch/arm64/boot/dts/hisilicon/hi6220-hikey.dts | 20 +++++++++++++++++---
 arch/arm64/boot/dts/hisilicon/hi6220.dtsi      |  8 ++++++++
 2 files changed, 25 insertions(+), 3 deletions(-)

diff --git a/arch/arm64/boot/dts/hisilicon/hi6220-hikey.dts b/arch/arm64/boot/dts/hisilicon/hi6220-hikey.dts
index e36a539..1715f9d 100644
--- a/arch/arm64/boot/dts/hisilicon/hi6220-hikey.dts
+++ b/arch/arm64/boot/dts/hisilicon/hi6220-hikey.dts
@@ -7,9 +7,6 @@
 
 /dts-v1/;
 
-/*Reserved 1MB memory for MCU*/
-/memreserve/ 0x05e00000 0x00100000;
-
 #include "hi6220.dtsi"
 
 / {
@@ -28,4 +25,21 @@
 		device_type = "memory";
 		reg = <0x0 0x0 0x0 0x40000000>;
 	};
+
+	reserved-memory {
+		#address-cells = <2>;
+		#size-cells = <2>;
+		ranges;
+
+		mcu-buf at 05e00000 {
+			no-map;
+			reg = <0x0 0x0740f000 0x0 0x00001000>,	/* MCU firmware section */
+			      <0x0 0x05e00000 0x0 0x00100000>;	/* MCU firmware buffer */
+		};
+
+		mbox-buf at 06dff000 {
+			no-map;
+			reg = <0x0 0x06dff000 0x0 0x00001000>;	/* Mailbox message buf */
+		};
+	};
 };
diff --git a/arch/arm64/boot/dts/hisilicon/hi6220.dtsi b/arch/arm64/boot/dts/hisilicon/hi6220.dtsi
index 3f03380..b42a9b7 100644
--- a/arch/arm64/boot/dts/hisilicon/hi6220.dtsi
+++ b/arch/arm64/boot/dts/hisilicon/hi6220.dtsi
@@ -167,5 +167,13 @@
 			clocks = <&ao_ctrl 36>, <&ao_ctrl 36>;
 			clock-names = "uartclk", "apb_pclk";
 		};
+
+		mailbox: mailbox {
+			#mbox-cells = <1>;
+			compatible = "hisilicon,hi6220-mbox";
+			reg = <0x0 0xf7510000 0x0 0x1000>, /* IPC_S */
+			      <0x0 0x06dff800 0x0 0x0800>; /* Mailbox buffer */
+			interrupts = <GIC_SPI 94 IRQ_TYPE_LEVEL_HIGH>;
+		};
 	};
 };
-- 
1.9.1



From leo.yan at linaro.org  Sun Aug  2 18:13:33 2015
From: leo.yan at linaro.org (Leo Yan)
Date: Mon,  3 Aug 2015 09:13:33 +0800
Subject: [PATCH v3 0/5] clk: hisilicon: support stub clock
Message-ID: <1438564418-15948-1-git-send-email-leo.yan@linaro.org>

This series adds support for hisilicon stub clock driver. On hi6220,
the bootloader needs load the firmware image and set info for OPPs;
after run into kernel, the stub clock driver is used to communicate
w/t firmware for cpu dynamic frequency scaling.

In patch series v1/v2, the stub clock driver simply writes request in
sram and send ipc to firmware; For patch series v3, the firmware has
been upgraded to use mailbox, so stub clock driver will call standard
mailbox APIs to request mailbox channel and send message to firmware.

These patches have been tested on 96board hikey and is used by cpufreq
driver.

Changes from v2:
* Use platform_device's probe for clock's initialization
* Use mailbox channel for clock frequency change

Changes from v1:
* Refine parameter checking for init flow
* Remove unnecessary debugging info
* Modify to check spinlock pointer when register clocks


Leo Yan (5):
  clk: hisi: refine parameter checking for init
  dt-bindings: arm: Hi6220: add doc for SRAM controller
  dt-bindings: clk: Hi6220: Document stub clock driver
  clk: Hi6220: add stub clock driver
  arm64: dts: add Hi6220's stub clock node

 .../bindings/arm/hisilicon/hisilicon.txt           |  18 ++
 .../devicetree/bindings/clock/hi6220-clock.txt     |  19 +-
 arch/arm64/boot/dts/hisilicon/hi6220.dtsi          |  23 ++
 drivers/clk/hisilicon/Kconfig                      |   2 +-
 drivers/clk/hisilicon/Makefile                     |   2 +-
 drivers/clk/hisilicon/clk-hi6220-stub.c            | 279 +++++++++++++++++++++
 drivers/clk/hisilicon/clk.c                        |  11 +-
 7 files changed, 343 insertions(+), 11 deletions(-)
 create mode 100644 drivers/clk/hisilicon/clk-hi6220-stub.c

-- 
1.9.1



From leo.yan at linaro.org  Sun Aug  2 18:13:34 2015
From: leo.yan at linaro.org (Leo Yan)
Date: Mon,  3 Aug 2015 09:13:34 +0800
Subject: [PATCH v3 1/5] clk: hisi: refine parameter checking for init
In-Reply-To: <1438564418-15948-1-git-send-email-leo.yan@linaro.org>
References: <1438564418-15948-1-git-send-email-leo.yan@linaro.org>
Message-ID: <1438564418-15948-2-git-send-email-leo.yan@linaro.org>

*of_iomap()* will check the device node pointer, and if the pointer is
NULL it will return error code. So refine clock's init flow by checking
the device node with this simple way; and polish a little for the print
out message.

Signed-off-by: Leo Yan <leo.yan at linaro.org>
---
 drivers/clk/hisilicon/clk.c | 11 +++--------
 1 file changed, 3 insertions(+), 8 deletions(-)

diff --git a/drivers/clk/hisilicon/clk.c b/drivers/clk/hisilicon/clk.c
index c90a897..156435d 100644
--- a/drivers/clk/hisilicon/clk.c
+++ b/drivers/clk/hisilicon/clk.c
@@ -45,14 +45,9 @@ struct hisi_clock_data __init *hisi_clk_init(struct device_node *np,
 	struct clk **clk_table;
 	void __iomem *base;
 
-	if (np) {
-		base = of_iomap(np, 0);
-		if (!base) {
-			pr_err("failed to map Hisilicon clock registers\n");
-			goto err;
-		}
-	} else {
-		pr_err("failed to find Hisilicon clock node in DTS\n");
+	base = of_iomap(np, 0);
+	if (!base) {
+		pr_err("%s: failed to map clock registers\n", __func__);
 		goto err;
 	}
 
-- 
1.9.1



From leo.yan at linaro.org  Sun Aug  2 18:13:35 2015
From: leo.yan at linaro.org (Leo Yan)
Date: Mon,  3 Aug 2015 09:13:35 +0800
Subject: [PATCH v3 2/5] dt-bindings: arm: Hi6220: add doc for SRAM controller
In-Reply-To: <1438564418-15948-1-git-send-email-leo.yan@linaro.org>
References: <1438564418-15948-1-git-send-email-leo.yan@linaro.org>
Message-ID: <1438564418-15948-3-git-send-email-leo.yan@linaro.org>

Document "hisilicon,hi6220-sramctrl" for SRAM controller.

Signed-off-by: Leo Yan <leo.yan at linaro.org>
---
 .../devicetree/bindings/arm/hisilicon/hisilicon.txt    | 18 ++++++++++++++++++
 1 file changed, 18 insertions(+)

diff --git a/Documentation/devicetree/bindings/arm/hisilicon/hisilicon.txt b/Documentation/devicetree/bindings/arm/hisilicon/hisilicon.txt
index c431c67..c733e28 100644
--- a/Documentation/devicetree/bindings/arm/hisilicon/hisilicon.txt
+++ b/Documentation/devicetree/bindings/arm/hisilicon/hisilicon.txt
@@ -127,6 +127,24 @@ Example:
 		#clock-cells = <1>;
 	};
 
+
+Hisilicon Hi6220 SRAM controller
+
+Required properties:
+- compatible : "hisilicon,hi6220-sramctrl", "syscon"
+- reg : Register address and size
+
+Hisilicon's SoCs use sram for multiple purpose; on Hi6220 there have several
+SRAM banks for power management, modem, security, etc. Further, use "syscon"
+managing the common sram which can be shared by multiple modules.
+
+Example:
+	/*for Hi6220*/
+	sram: sram at fff80000 {
+		compatible = "hisilicon,hi6220-sramctrl", "syscon";
+		reg = <0x0 0xfff80000 0x0 0x12000>;
+	};
+
 -----------------------------------------------------------------------
 Hisilicon HiP01 system controller
 
-- 
1.9.1



From leo.yan at linaro.org  Sun Aug  2 18:13:36 2015
From: leo.yan at linaro.org (Leo Yan)
Date: Mon,  3 Aug 2015 09:13:36 +0800
Subject: [PATCH v3 3/5] dt-bindings: clk: Hi6220: Document stub clock driver
In-Reply-To: <1438564418-15948-1-git-send-email-leo.yan@linaro.org>
References: <1438564418-15948-1-git-send-email-leo.yan@linaro.org>
Message-ID: <1438564418-15948-4-git-send-email-leo.yan@linaro.org>

Document the new compatible for stub clock driver which is used for CPU
and DDR's dynamic frequency scaling.

Signed-off-by: Leo Yan <leo.yan at linaro.org>
---
 .../devicetree/bindings/clock/hi6220-clock.txt        | 19 ++++++++++++++++++-
 1 file changed, 18 insertions(+), 1 deletion(-)

diff --git a/Documentation/devicetree/bindings/clock/hi6220-clock.txt b/Documentation/devicetree/bindings/clock/hi6220-clock.txt
index 259e30a..e4d5fea 100644
--- a/Documentation/devicetree/bindings/clock/hi6220-clock.txt
+++ b/Documentation/devicetree/bindings/clock/hi6220-clock.txt
@@ -15,19 +15,36 @@ Required Properties:
 	- "hisilicon,hi6220-sysctrl"
 	- "hisilicon,hi6220-mediactrl"
 	- "hisilicon,hi6220-pmctrl"
+	- "hisilicon,hi6220-stub-clk"
 
 - reg: physical base address of the controller and length of memory mapped
   region.
 
 - #clock-cells: should be 1.
 
-For example:
+Optional Properties:
+
+- hisilicon,hi6220-clk-sram: phandle to the syscon managing the SoC internal sram;
+  the driver need use the sram to pass parameters for frequency change.
+
+- mboxes: use the label reference for the mailbox as the first parameter, the
+  second parameter is the channel number.
+
+Example 1:
 	sys_ctrl: sys_ctrl at f7030000 {
 		compatible = "hisilicon,hi6220-sysctrl", "syscon";
 		reg = <0x0 0xf7030000 0x0 0x2000>;
 		#clock-cells = <1>;
 	};
 
+Example 2:
+	stub_clock: stub_clock {
+		compatible = "hisilicon,hi6220-stub-clk";
+		hisilicon,hi6220-clk-sram = <&sram>;
+		#clock-cells = <1>;
+		mboxes = <&mailbox 1>;
+	};
+
 Each clock is assigned an identifier and client nodes use this identifier
 to specify the clock which they consume.
 
-- 
1.9.1



From leo.yan at linaro.org  Sun Aug  2 18:13:37 2015
From: leo.yan at linaro.org (Leo Yan)
Date: Mon,  3 Aug 2015 09:13:37 +0800
Subject: [PATCH v3 4/5] clk: Hi6220: add stub clock driver
In-Reply-To: <1438564418-15948-1-git-send-email-leo.yan@linaro.org>
References: <1438564418-15948-1-git-send-email-leo.yan@linaro.org>
Message-ID: <1438564418-15948-5-git-send-email-leo.yan@linaro.org>

On Hi6220, there have some clocks which can use mailbox channel to send
messages to power controller to change frequency; this includes CPU, GPU
and DDR clocks.

For dynamic frequency scaling, firstly need write the frequency value to
SRAM region, and then send message to mailbox to trigger power controller
to handle this requirement. This driver will use syscon APIs to pass SRAM
memory region and use common mailbox APIs for channels accessing.

This init driver will support cpu frequency change firstly.

Signed-off-by: Leo Yan <leo.yan at linaro.org>
---
 drivers/clk/hisilicon/Kconfig           |   2 +-
 drivers/clk/hisilicon/Makefile          |   2 +-
 drivers/clk/hisilicon/clk-hi6220-stub.c | 279 ++++++++++++++++++++++++++++++++
 3 files changed, 281 insertions(+), 2 deletions(-)
 create mode 100644 drivers/clk/hisilicon/clk-hi6220-stub.c

diff --git a/drivers/clk/hisilicon/Kconfig b/drivers/clk/hisilicon/Kconfig
index b4165ba..2c16807 100644
--- a/drivers/clk/hisilicon/Kconfig
+++ b/drivers/clk/hisilicon/Kconfig
@@ -1,6 +1,6 @@
 config COMMON_CLK_HI6220
 	bool "Hi6220 Clock Driver"
-	depends on ARCH_HISI || COMPILE_TEST
+	depends on (ARCH_HISI || COMPILE_TEST) && MAILBOX
 	default ARCH_HISI
 	help
 	  Build the Hisilicon Hi6220 clock driver based on the common clock framework.
diff --git a/drivers/clk/hisilicon/Makefile b/drivers/clk/hisilicon/Makefile
index 48f0116..4a1001a 100644
--- a/drivers/clk/hisilicon/Makefile
+++ b/drivers/clk/hisilicon/Makefile
@@ -7,4 +7,4 @@ obj-y	+= clk.o clkgate-separated.o clkdivider-hi6220.o
 obj-$(CONFIG_ARCH_HI3xxx)	+= clk-hi3620.o
 obj-$(CONFIG_ARCH_HIP04)	+= clk-hip04.o
 obj-$(CONFIG_ARCH_HIX5HD2)	+= clk-hix5hd2.o
-obj-$(CONFIG_COMMON_CLK_HI6220)	+= clk-hi6220.o
+obj-$(CONFIG_COMMON_CLK_HI6220)	+= clk-hi6220.o clk-hi6220-stub.o
diff --git a/drivers/clk/hisilicon/clk-hi6220-stub.c b/drivers/clk/hisilicon/clk-hi6220-stub.c
new file mode 100644
index 0000000..0931666
--- /dev/null
+++ b/drivers/clk/hisilicon/clk-hi6220-stub.c
@@ -0,0 +1,279 @@
+/*
+ * Hi6220 stub clock driver
+ *
+ * Copyright (c) 2015 Hisilicon Limited.
+ * Copyright (c) 2015 Linaro Limited.
+ *
+ * Author: Leo Yan <leo.yan at linaro.org>
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License version 2 as
+ * published by the Free Software Foundation.
+ *
+ */
+
+#include <linux/clkdev.h>
+#include <linux/clk-provider.h>
+#include <linux/clk.h>
+#include <linux/err.h>
+#include <linux/mfd/syscon.h>
+#include <linux/mailbox_client.h>
+#include <linux/of.h>
+#include <linux/of_device.h>
+#include <linux/regmap.h>
+#include <linux/slab.h>
+#include <linux/kernel.h>
+
+#include <dt-bindings/clock/hi6220-clock.h>
+
+/* Stub clocks id */
+#define HI6220_STUB_ACPU0		0
+#define HI6220_STUB_ACPU1		1
+#define HI6220_STUB_GPU			2
+#define HI6220_STUB_DDR			5
+
+/* Mailbox message */
+#define HI6220_MBOX_MSG_LEN		8
+
+#define HI6220_MBOX_FREQ		(0xA)
+#define HI6220_MBOX_CMD_SET		(0x3)
+#define HI6220_MBOX_OBJ_AP		(0x0)
+
+/* CPU dynamic frequency scaling */
+#define ACPU_DFS_FREQ_MAX		(0x1724)
+#define ACPU_DFS_CUR_FREQ		(0x17CC)
+#define ACPU_DFS_FLAG			(0x1B30)
+#define ACPU_DFS_FREQ_REQ		(0x1B34)
+#define ACPU_DFS_FREQ_LMT		(0x1B38)
+#define ACPU_DFS_LOCK_FLAG		(0xAEAEAEAE)
+
+#define to_stub_clk(hw) container_of(hw, struct hi6220_stub_clk, hw)
+
+struct hi6220_stub_clk {
+	u32 id;
+	u32 rate;
+
+	struct device *dev;
+	struct clk_hw hw;
+
+	struct regmap *dfs_map;
+	struct mbox_client cl;
+	struct mbox_chan *mbox;
+};
+
+struct hi6220_mbox_msg {
+	unsigned char type;
+	unsigned char cmd;
+	unsigned char obj;
+	unsigned char src;
+	unsigned char para[4];
+};
+
+union hi6220_mbox_data {
+	unsigned int data[HI6220_MBOX_MSG_LEN];
+	struct hi6220_mbox_msg msg;
+};
+
+static unsigned int hi6220_acpu_get_freq(struct hi6220_stub_clk *stub_clk)
+{
+	unsigned int freq;
+
+	regmap_read(stub_clk->dfs_map, ACPU_DFS_CUR_FREQ, &freq);
+	return freq;
+}
+
+static int hi6220_acpu_set_freq(struct hi6220_stub_clk *stub_clk,
+				unsigned int freq)
+{
+	union hi6220_mbox_data data;
+
+	stub_clk->mbox = mbox_request_channel(&stub_clk->cl, 0);
+	if (IS_ERR(stub_clk->mbox)) {
+		dev_err(stub_clk->dev, "failed get mailbox channel\n");
+		return PTR_ERR(stub_clk->mbox);
+	};
+
+	/* set the frequency in sram */
+	regmap_write(stub_clk->dfs_map, ACPU_DFS_FREQ_REQ, freq);
+
+	/* compound mailbox message */
+	data.msg.type = HI6220_MBOX_FREQ;
+	data.msg.cmd  = HI6220_MBOX_CMD_SET;
+	data.msg.obj  = HI6220_MBOX_OBJ_AP;
+	data.msg.src  = HI6220_MBOX_OBJ_AP;
+
+	mbox_send_message(stub_clk->mbox, &data);
+	mbox_free_channel(stub_clk->mbox);
+	return 0;
+}
+
+static int hi6220_acpu_round_freq(struct hi6220_stub_clk *stub_clk,
+				  unsigned int freq)
+{
+	unsigned int limit_flag, limit_freq = UINT_MAX;
+	unsigned int max_freq;
+
+	/* check the constrainted frequency */
+	regmap_read(stub_clk->dfs_map, ACPU_DFS_FLAG, &limit_flag);
+	if (limit_flag == ACPU_DFS_LOCK_FLAG)
+		regmap_read(stub_clk->dfs_map, ACPU_DFS_FREQ_LMT, &limit_freq);
+
+	/* check the supported maximum frequency */
+	regmap_read(stub_clk->dfs_map, ACPU_DFS_FREQ_MAX, &max_freq);
+
+	/* calculate the real maximum frequency */
+	max_freq = min(max_freq, limit_freq);
+
+	if (WARN_ON(freq > max_freq))
+		freq = max_freq;
+
+	return freq;
+}
+
+static unsigned long hi6220_stub_clk_recalc_rate(struct clk_hw *hw,
+		unsigned long parent_rate)
+{
+	u32 rate = 0;
+	struct hi6220_stub_clk *stub_clk = to_stub_clk(hw);
+
+	switch (stub_clk->id) {
+	case HI6220_STUB_ACPU0:
+		rate = hi6220_acpu_get_freq(stub_clk);
+
+		/* convert from KHz to Hz */
+		rate *= 1000;
+		break;
+
+	default:
+		dev_err(stub_clk->dev, "%s: un-supported clock id %d\n",
+			__func__, stub_clk->id);
+		break;
+	}
+
+	return rate;
+}
+
+static int hi6220_stub_clk_set_rate(struct clk_hw *hw, unsigned long rate,
+                    unsigned long parent_rate)
+{
+	struct hi6220_stub_clk *stub_clk = to_stub_clk(hw);
+	unsigned long new_rate = rate / 1000;  /* Khz */
+	int ret = 0;
+
+	switch (stub_clk->id) {
+	case HI6220_STUB_ACPU0:
+		ret = hi6220_acpu_set_freq(stub_clk, new_rate);
+		if (ret < 0)
+			return ret;
+
+		break;
+
+	default:
+		dev_err(stub_clk->dev, "%s: un-supported clock id %d\n",
+			__func__, stub_clk->id);
+		break;
+	}
+
+	stub_clk->rate = new_rate;
+
+	pr_debug("%s: set rate=%ldKhz\n", __func__, new_rate);
+	return ret;
+}
+
+static long hi6220_stub_clk_round_rate(struct clk_hw *hw, unsigned long rate,
+		unsigned long *parent_rate)
+{
+	struct hi6220_stub_clk *stub_clk = to_stub_clk(hw);
+	unsigned long new_rate = rate / 1000;  /* Khz */
+
+	switch (stub_clk->id) {
+	case HI6220_STUB_ACPU0:
+		new_rate = hi6220_acpu_round_freq(stub_clk, new_rate);
+
+		/* convert from KHz to Hz */
+		new_rate *= 1000;
+		break;
+
+	default:
+		dev_err(stub_clk->dev, "%s: un-supported clock id %d\n",
+			__func__, stub_clk->id);
+		break;
+	}
+
+	return new_rate;
+}
+
+static struct clk_ops hi6220_stub_clk_ops = {
+	.recalc_rate	= hi6220_stub_clk_recalc_rate,
+	.round_rate	= hi6220_stub_clk_round_rate,
+	.set_rate	= hi6220_stub_clk_set_rate,
+};
+
+static int hi6220_stub_clk_probe(struct platform_device *pdev)
+{
+	struct device *dev = &pdev->dev;
+	struct clk_init_data init;
+	struct hi6220_stub_clk *stub_clk;
+	struct clk *clk;
+	struct device_node *np = pdev->dev.of_node;
+
+	stub_clk = devm_kzalloc(&pdev->dev, sizeof(*stub_clk), GFP_KERNEL);
+	if (!stub_clk)
+		return -ENOMEM;
+
+	stub_clk->dfs_map = syscon_regmap_lookup_by_phandle(np,
+				"hisilicon,hi6220-clk-sram");
+	if (IS_ERR(stub_clk->dfs_map)) {
+		dev_err(dev, "failed to get sram regmap\n");
+		return PTR_ERR(stub_clk->dfs_map);
+	}
+
+	stub_clk->hw.init = &init;
+	stub_clk->dev = dev;
+	stub_clk->id = HI6220_STUB_ACPU0;
+
+	/* Use mailbox client with blocking mode */
+	stub_clk->cl.dev = &pdev->dev;
+	stub_clk->cl.tx_done = NULL;
+	stub_clk->cl.tx_block = true;
+	stub_clk->cl.tx_tout = 500;
+	stub_clk->cl.knows_txdone = false;
+
+	init.name = "acpu0";
+	init.ops = &hi6220_stub_clk_ops;
+	init.num_parents = 0;
+	init.flags = CLK_IS_ROOT;
+
+	clk = clk_register(NULL, &stub_clk->hw);
+	if (IS_ERR(clk))
+		return PTR_ERR(clk);
+
+	of_clk_add_provider(pdev->dev.of_node, of_clk_src_simple_get, clk);
+
+	/* initialize buffer to zero */
+	regmap_write(stub_clk->dfs_map, ACPU_DFS_FLAG, 0x0);
+	regmap_write(stub_clk->dfs_map, ACPU_DFS_FREQ_REQ, 0x0);
+	regmap_write(stub_clk->dfs_map, ACPU_DFS_FREQ_LMT, 0x0);
+
+	dev_dbg(&pdev->dev, "Registered clock '%s'\n", init.name);
+	return 0;
+}
+
+static const struct of_device_id hi6220_stub_clk_of_match[] = {
+	{ .compatible = "hisilicon,hi6220-stub-clk", },
+	{}
+};
+
+static struct platform_driver hi6220_stub_clk_driver = {
+	.driver	= {
+		.name = "hi6220-stub-clk",
+		.of_match_table = of_match_ptr(hi6220_stub_clk_of_match),
+	},
+	.probe = hi6220_stub_clk_probe,
+};
+
+static int __init hi6220_stub_clk_init(void)
+{
+	return platform_driver_register(&hi6220_stub_clk_driver);
+}
+core_initcall(hi6220_stub_clk_init);
-- 
1.9.1



From leo.yan at linaro.org  Sun Aug  2 18:13:38 2015
From: leo.yan at linaro.org (Leo Yan)
Date: Mon,  3 Aug 2015 09:13:38 +0800
Subject: [PATCH v3 5/5] arm64: dts: add Hi6220's stub clock node
In-Reply-To: <1438564418-15948-1-git-send-email-leo.yan@linaro.org>
References: <1438564418-15948-1-git-send-email-leo.yan@linaro.org>
Message-ID: <1438564418-15948-6-git-send-email-leo.yan@linaro.org>

Enable SRAM node and stub clock node for Hi6220; furthermore
add the CPU's clock so it will be used by cpufreq-dt driver.

Signed-off-by: Leo Yan <leo.yan at linaro.org>
---
 arch/arm64/boot/dts/hisilicon/hi6220.dtsi | 23 +++++++++++++++++++++++
 1 file changed, 23 insertions(+)

diff --git a/arch/arm64/boot/dts/hisilicon/hi6220.dtsi b/arch/arm64/boot/dts/hisilicon/hi6220.dtsi
index b42a9b7..94b8310 100644
--- a/arch/arm64/boot/dts/hisilicon/hi6220.dtsi
+++ b/arch/arm64/boot/dts/hisilicon/hi6220.dtsi
@@ -57,6 +57,17 @@
 			device_type = "cpu";
 			reg = <0x0 0x0>;
 			enable-method = "psci";
+			clocks = <&stub_clock 0>;
+			clock-latency = <0>;
+			operating-points = <
+				/* kHz */
+				1200000  0
+				960000   0
+				729000   0
+				432000   0
+				208000   0
+			>;
+			#cooling-cells = <2>; /* min followed by max */
 		};
 
 		cpu1: cpu at 1 {
@@ -136,6 +147,11 @@
 		#size-cells = <2>;
 		ranges;
 
+		sram: sram at fff80000 {
+			compatible = "hisilicon,hi6220-sramctrl", "syscon";
+			reg = <0x0 0xfff80000 0x0 0x12000>;
+		};
+
 		ao_ctrl: ao_ctrl at f7800000 {
 			compatible = "hisilicon,hi6220-aoctrl", "syscon";
 			reg = <0x0 0xf7800000 0x0 0x2000>;
@@ -160,6 +176,13 @@
 			#clock-cells = <1>;
 		};
 
+		stub_clock: stub_clock {
+			compatible = "hisilicon,hi6220-stub-clk";
+			hisilicon,hi6220-clk-sram = <&sram>;
+			#clock-cells = <1>;
+			mboxes = <&mailbox 1>;
+		};
+
 		uart0: uart at f8015000 {	/* console */
 			compatible = "arm,pl011", "arm,primecell";
 			reg = <0x0 0xf8015000 0x0 0x1000>;
-- 
1.9.1



From dave at stgolabs.net  Sun Aug  2 13:50:31 2015
From: dave at stgolabs.net (Davidlohr Bueso)
Date: Sun, 02 Aug 2015 13:50:31 -0700
Subject: [PATCH v2] arch: use WRITE_ONCE/READ_ONCE in
 smp_store_release/smp_load_acquire
In-Reply-To: <1438528264-714-1-git-send-email-andreyknvl@google.com>
References: <1438528264-714-1-git-send-email-andreyknvl@google.com>
Message-ID: <1438548631.2249.125.camel@stgolabs.net>

On Sun, 2015-08-02 at 17:11 +0200, Andrey Konovalov wrote:
> Replace ACCESS_ONCE() macro in smp_store_release() and smp_load_acquire()
> with WRITE_ONCE() and READ_ONCE() on x86, arm, arm64, ia64, metag, mips,
> powerpc, s390, sparc and asm-generic since ACCESS_ONCE does not work
> reliably on non-scalar types.
> 
> WRITE_ONCE() and READ_ONCE() were introduced in the commits 230fa253df63
> ("kernel: Provide READ_ONCE and ASSIGN_ONCE") and 43239cbe79fc ("kernel:
> Change ASSIGN_ONCE(val, x) to WRITE_ONCE(x, val)").
> 
> Signed-off-by: Andrey Konovalov <andreyknvl at google.com>

Acked-by: Davidlohr Bueso <dbueso at suse.de>



From mpe at ellerman.id.au  Sun Aug  2 18:41:58 2015
From: mpe at ellerman.id.au (Michael Ellerman)
Date: Mon, 03 Aug 2015 11:41:58 +1000
Subject: [PATCH v2] arch: use WRITE_ONCE/READ_ONCE in
 smp_store_release/smp_load_acquire
In-Reply-To: <1438528264-714-1-git-send-email-andreyknvl@google.com>
References: <1438528264-714-1-git-send-email-andreyknvl@google.com>
Message-ID: <1438566118.8863.3.camel@ellerman.id.au>

On Sun, 2015-08-02 at 17:11 +0200, Andrey Konovalov wrote:
> Replace ACCESS_ONCE() macro in smp_store_release() and smp_load_acquire()
> with WRITE_ONCE() and READ_ONCE() on x86, arm, arm64, ia64, metag, mips,
> powerpc, s390, sparc and asm-generic since ACCESS_ONCE does not work
> reliably on non-scalar types.

.. and there are no restrictions on the argument to smp_load_acquire(), so it
may be a non-scalar type.

Though from a quick grep it looks like no one is doing that at the moment?

> WRITE_ONCE() and READ_ONCE() were introduced in the commits 230fa253df63
> ("kernel: Provide READ_ONCE and ASSIGN_ONCE") and 43239cbe79fc ("kernel:
> Change ASSIGN_ONCE(val, x) to WRITE_ONCE(x, val)").
> 
> Signed-off-by: Andrey Konovalov <andreyknvl at google.com>
> ---
> Changed in v2:
>   - Other archs besides x86.
> 
>  arch/powerpc/include/asm/barrier.h  | 4 ++--

> diff --git a/arch/powerpc/include/asm/barrier.h b/arch/powerpc/include/asm/barrier.h
> index 51ccc72..0eca6ef 100644
> --- a/arch/powerpc/include/asm/barrier.h
> +++ b/arch/powerpc/include/asm/barrier.h
> @@ -76,12 +76,12 @@
>  do {									\
>  	compiletime_assert_atomic_type(*p);				\
>  	smp_lwsync();							\
> -	ACCESS_ONCE(*p) = (v);						\
> +	WRITE_ONCE(*p, v);						\
>  } while (0)
>  
>  #define smp_load_acquire(p)						\
>  ({									\
> -	typeof(*p) ___p1 = ACCESS_ONCE(*p);				\
> +	typeof(*p) ___p1 = READ_ONCE(*p);				\
>  	compiletime_assert_atomic_type(*p);				\
>  	smp_lwsync();							\
>  	___p1;								\

Acked-by: Michael Ellerman <mpe at ellerman.id.au> (powerpc)

cheers




From wens at csie.org  Sun Aug  2 19:37:35 2015
From: wens at csie.org (Chen-Yu Tsai)
Date: Mon, 3 Aug 2015 10:37:35 +0800
Subject: [linux-sunxi] [PATCH] ARM: dts: sunxi: Raise minimum CPU voltage
 for sun7i-a20 to a level all boards can supply
In-Reply-To: <CAGRGNgV6b9yt2HnB2x2Wyc05KEahoX-Y+mVhxsryztcfA36H1g@mail.gmail.com>
References: <1438543386-7253-1-git-send-email-public_timo.s@silentcreek.de>
 <CAGRGNgV6b9yt2HnB2x2Wyc05KEahoX-Y+mVhxsryztcfA36H1g@mail.gmail.com>
Message-ID: <CAGb2v67o-=_cL2RWfXJ+3C86zfQ_1b5DYRi3_zwvwy6su6+gdw@mail.gmail.com>

Hi,

On Mon, Aug 3, 2015 at 7:35 AM, Julian Calaby <julian.calaby at gmail.com> wrote:
> Hi Timo,
>
> On Mon, Aug 3, 2015 at 5:23 AM, Timo Sigurdsson
> <public_timo.s at silentcreek.de> wrote:
>> sun7i-a20.dtsi contains an cpufreq operating point at 0.9 volts. Most A20 boards
>> (or all?), however, do not allow the voltage to go below 1.0V. Thus, raise the
>> voltage for the lowest operating point to 1.0V so all boards can actually use
>> it.
>
> Surely it wouldn't be added here if some could supply 0.9v.

On the side, the original OPPs in the FEX files are actually
frequency/voltage ranges, and not just points. Mainlines OPPv2
will support these, along with turbo frequencies.

Furthermore, the FEX files also have fields that limit the
minimum and maximum frequencies.

> Is the code that uses this smart enough to sensibly switch between two
> operating points with the same frequency and different voltages? If
> so, maybe just add a 144MHz @ 1.0v operating point?

You could try. Though I really don't see much to gain here.

> (Alternatively, would it make sense to modify the code that uses this
> to use frequencies with voltages specified that are lower than can be
> supplied with the lowest voltage it can?)

I think that's a bit harder to get accepted.


ChenYu


From ezequiel at vanguardiasur.com.ar  Sun Aug  2 19:49:55 2015
From: ezequiel at vanguardiasur.com.ar (Ezequiel Garcia)
Date: Sun, 2 Aug 2015 23:49:55 -0300
Subject: [PATCH v2 0/4] mtd: pxa3xx_nand: rework the timing setup
In-Reply-To: <87wpxufw2v.fsf@belgarion.home>
References: <1436281707-20106-1-git-send-email-antoine.tenart@free-electrons.com>
 <20150717134159.GC10608@kwain>
 <55A912F0.7080605@vanguardiasur.com.ar>
 <87h9p2is8e.fsf@belgarion.home>
 <CAAEAJfCcdioVQKZs9U3DP6H94BiuQ2qU21DsMKevS5+j+-XEKA@mail.gmail.com>
 <87wpxufw2v.fsf@belgarion.home>
Message-ID: <CAAEAJfB3caa+DmJN=Pa8brx0uGC11QA29KJb3NQdJjXTgw-yuA@mail.gmail.com>

On 20 July 2015 at 16:49, Robert Jarzmik <robert.jarzmik at free.fr> wrote:
> Ezequiel Garcia <ezequiel at vanguardiasur.com.ar> writes:
>
>> Here you go:
>>
>> http://git.infradead.org/users/ezequielg/linux/shortlog/refs/heads/pxa3xx-nand-timing-rework-v2
>
> Okay, I've tested this on cm-x300. The result is not bright :
>         nand: device found, Manufacturer ID: 0xec, Chip ID: 0xdc
>         nand: Samsung NAND 512MiB 3,3V 8-bit
>         nand: 512 MiB, SLC, erase size: 128 KiB, page size: 2048, OOB size: 64
>         pxa3xx-nand pxa3xx-nand: ECC strength 1, ECC step size 512
>         Scanning device for bad blocks
>         random: nonblocking pool is initialized
>         Bad eraseblock 1037 at 0x0000081a0000
>         Creating 6 MTD partitions on "pxa3xx_nand-0":
>         0x000000000000-0x000000040000 : "OBM"
>         0x000000040000-0x000000080000 : "U-Boot"
>         0x000000080000-0x0000000c0000 : "Environment"
>         0x0000000c0000-0x000000200000 : "reserved"
>         0x000000200000-0x000000600000 : "kernel"
>         0x000000600000-0x000020000000 : "fs"
>
> The bad black is not bad normally.
> And then :
>         # dd if=/dev/mtd0 of=toto count=1
>         pxa3xx-nand pxa3xx-nand: Wait time out!!!
>         1+0 records in
>         1+0 records out
>         # ls -l toto
>         -rw-r--r--    1 root     root           512 Jan  1 00:02 toto
>         # hexdump-C toto
>         00000000  ff ff ff ff ff ff ff ff  ff ff ff ff ff ff ff ff  |................|
>         *
>         00000200
>
> That's not possible, as it should have dumped the OBMI.
>
> And yet, I hesitate to incriminate this patchset, I will try without it. It wont
> be very fast, as my USB to serial converter just broke, and my order will take a
> couple of days to complete.
>

Just tested linux-next (hence *without* the patchset) and I see
the same "Wait time out". In other words, pxa3xx-nand is broken
on PXA :/

Interestingly, the culprit doesn't seem to be in pxa3xx-nand itself.
Reverting the recent commits on pxa3xx-nand doesn't help.

ce914e6 mtd: nand: pxa3xx: fix build on ARM64
afca11e mtd: nand: pxa3xx: Switch FIFO draining to jiffies-based timeout
e5860c1 mtd: pxa3xx_nand: cleanup wait_for_completion handling
7c2f717 mtd: pxa3xx_nand: initialiaze pxa3xx_flash_ids to 0
ed446cc Merge MTD updates into -next
e423c90 mtd: pxa3xx_nand: fix driver when num_cs is 0
2454225 mtd: pxa3xx-nand: handle PIO in threaded interrupt
8dad038 mtd: nand: pxa3xx: Fix PIO FIFO draining
b7e46062 mtd: pxa3xx_nand: make the driver work on big-endian systems
5b3e507 mtd: nand: pxa3xx: Use ECC strength and step size devicetree binding
eee0166 mtd: nand: pxa3xx: Clean pxa_ecc_init() error handling
17754ad mtd: nand: pxa3xx: Make of_device_id array const
e634ce5 mtd: nand: pxa3xx: Print actual ECC strength in error message

Yet v3.18 succeeds to pass a few NAND blocks on nandtest.

Robert: any ideas?
-- 
Ezequiel Garc?a, VanguardiaSur
www.vanguardiasur.com.ar


From viresh.kumar at linaro.org  Sun Aug  2 20:46:42 2015
From: viresh.kumar at linaro.org (Viresh Kumar)
Date: Mon, 3 Aug 2015 09:16:42 +0530
Subject: [PATCH v4 2/2] dt: power: st: Provide bindings for ST's OPPs
In-Reply-To: <20150731163715.GV3159@codeaurora.org>
References: <1438010430-5802-1-git-send-email-lee.jones@linaro.org>
 <1438010430-5802-2-git-send-email-lee.jones@linaro.org>
 <20150728022936.GB1229@linux>
 <20150728225510.GB3159@codeaurora.org> <20150729081403.GH2284@x1>
 <20150729221526.GE3159@codeaurora.org> <20150730084634.GD9319@x1>
 <CAL_JsqKQLQ15qSt95zBZykzzPhcUrtZzhk29a76n+r_3719AiA@mail.gmail.com>
 <20150731163715.GV3159@codeaurora.org>
Message-ID: <20150803034642.GV899@linux>

On 31-07-15, 09:37, Stephen Boyd wrote:
> For qcom platforms, the frequency is almost always constant.
> There may be some tables where we have a couple higher
> frequencies than others because the speed bin is different.
> Otherwise the voltage/current is changing based on the silicon
> characteristics. So the biggest duplication is the frequency
> property.
> 
> As far as I know there isn't any algorithm to generate the
> voltage values. It's all hand tuned tables based on the silicon
> characterization, so we're left to store these tables in DT and
> pick the right one at runtime. With regards to the table
> explosion, on qcom platforms we haven't worried that we have ~40
> tables, but I'm not opposed to expressing it in a smaller set of
> nodes, tables, etc. if that's what's desired.
> 
> Do we need vendor specific properties for that though? Or do we
> need some sort of extended frequency/voltage properties that are
> arrays of values that we can index into based on some silicon
> characteristics? I like the name based approach because it's
> simple. Use this OPP table because it's called
> x-y-z-characteristics and be done. Cramming the tables into less
> lines may save us some typing and dtb space, but I'm not sure
> what else it does.

What about something like this:

diff --git a/Documentation/devicetree/bindings/opp/opp.txt b/Documentation/devicetree/bindings/opp/opp.txt
index 0cb44dc21f97..bad7a8299b9c 100644
--- a/Documentation/devicetree/bindings/opp/opp.txt
+++ b/Documentation/devicetree/bindings/opp/opp.txt
@@ -74,6 +74,8 @@ This describes the OPPs belonging to a device. This node can have following
   reference an OPP.
 
 Optional properties:
+- opp-cuts: One or more strings, describing the versions of hardware the OPPs
+  can support.
 - opp-shared: Indicates that device nodes using this OPP Table Node's phandle
   switch their DVFS state together, i.e. they share clock/voltage/current lines.
   Missing property means devices have independent clock/voltage/current lines,
@@ -100,6 +102,9 @@ properties.
   Entries for multiple regulators must be present in the same order as
   regulators are specified in device's DT node.
 
+  If used with 'opp-cuts', then the number of entries present here must match
+  the number of strings present in 'opp-cuts'.
+
 - opp-microamp: The maximum current drawn by the device in microamperes
   considering system specific parameters (such as transients, process, aging,
   maximum operating temperature range etc.) as necessary. This may be used to

-- 
viresh


From bhupesh.sharma at freescale.com  Sun Aug  2 21:12:00 2015
From: bhupesh.sharma at freescale.com (Sharma Bhupesh)
Date: Mon, 3 Aug 2015 04:12:00 +0000
Subject: [Query] ARM64: Softlockup when using PSCI for secondary CPU_ON
Message-ID: <BY1PR0301MB1303EC5AAE8F0B4DAA70D15F82770@BY1PR0301MB1303.namprd03.prod.outlook.com>

Hi ARM64 experts,

I am working on a Freescale ARM64 based SoC, which has 4 Cortex-A53 cores and I am using the
PSCI conducts to turn on the secondary CPUs via a custom implementation of a secure runtime
firmware (something similar to the ARM Trusted Firmware).

Following is my boot-flow:

- BootROM (runs in EL3, All secondaries are held up in reset) ->

- UEFI bootloader- PEI Phase (Runs only on Primary, starts up in EL3) ->

- Secure Firmware (runs in EL3, transitions primary core to EL2) ->

- UEFI bootloader- Rest of the Phases (Runs only on Primary, in EL2) ->

- UEFI Linux loader launches linux (Runs only on Primary, transitions core to EL1) ->

- Linux runs and calls PSCI conducts to turn on secondary cores via smc calls to secure run-time firmware ->

- Now I can see that the ARM64 linux is able to recognize that the secondaries are boot'ed properly:

PSCI Logs:
----------
psci: probing for conduit method from DT.
psci: PSCIv0.2 detected in firmware.
psci: Using standard PSCI v0.2 function IDs
..

Architected cp15 timer(s) running at 25.00MHz (phys).
sched_clock: 56 bits at 25MHz, resolution 40ns, wraps every 2748779069440ns

..

CPU1: Booted secondary processor
Detected VIPT I-cache on CPU1
CPU2: Booted secondary processor
Detected VIPT I-cache on CPU2
CPU3: Booted secondary processor
Detected VIPT I-cache on CPU3
Brought up 4 CPUs
SMP: Total of 4 processors activated.


- However, when the Linux boot proceeds further, I see softlockups which usually show that one
of the secondaries was stuck in 'secondary_start_kernel' (detailed logs below).

- When I turn of CONFIG_SMP from the .config, I can see that the softlockups disappear. So, I am
correlating these softlockups to SMP and PSCI conducts.

- Any pointers on what can be going wrong here?

Detailed logs:
--------------

preempt self-detected stall on CPU { 3}  (t=17194 jiffies g=-267 c=-268 q=1)
Task dump for CPU 0:
swapper/0       R  running task        0     0      0 0x00000000
Call trace:
[<ffffffc00008655c>] __switch_to+0x74/0x8c
Task dump for CPU 1:
swapper/1       R  running task        0     0      1 0x00000000
Call trace:
[<ffffffc00008655c>] __switch_to+0x74/0x8c
Task dump for CPU 2:
swapper/2       R  running task        0     0      1 0x00000002
Call trace:
[<ffffffc00008655c>] __switch_to+0x74/0x8c
[<ffffffc0000a4828>] irq_exit+0x80/0xd0
[<ffffffc0000da6a8>] __handle_domain_irq+0x64/0xb0
[<ffffffc00008141c>] gic_handle_irq+0x34/0x80
Exception stack(0xffffffc0790d7e30 to 0xffffffc0790d7f50)
7e20:                                     790d4000 ffffffc0 0070457c ffffffc0
7e40: 790d7f70 ffffffc0 00086164 ffffffc0 00000000 00000000 00000000 00000000
7e60: 7fea4b1c ffffffc0 7fea4b1c ffffffc0 78c24170 ffffffc0 790d7ef0 ffffffc0
7e80: 00000000 00000000 7feb3458 ffffffc0 790d7f10 ffffffc0 000f6548 ffffffc0
7ea0: 00763000 ffffffc0 00763c00 ffffffc0 73316280 00000050 006fe000 ffffffc0
7ec0: 006fe000 ffffffc0 00639c98 ffffffc0 005184b8 ffffffc0 80785000 00000000
7ee0: 000815e0 ffffffc0 80000000 00000040 000001f5 00000000 00000148 00000000
7f00: 790d7f10 ffffffc0 000f6544 ffffffc0 790d7f50 ffffffc0 000f6c14 ffffffc0
7f20: 7fea4f38 ffffffc0 7332edf8 00000050 007044f8 ffffffc0 0075480a ffffffc0
7f40: 00000001 00000000 7fea4f38 ffffffc0
[<ffffffc000084da4>] el1_irq+0x64/0xd8
Task dump for CPU 3:
swapper/3       R  running task        0     0      1 0x00000000
Call trace:
[<ffffffc000089148>] dump_backtrace+0x0/0x12c
[<ffffffc000089284>] show_stack+0x10/0x1c
[<ffffffc0000c2b84>] sched_show_task+0xa8/0x100
[<ffffffc0000c5cbc>] dump_cpu_task+0x3c/0x4c
[<ffffffc0000e213c>] rcu_dump_cpu_stacks+0x98/0xe8
[<ffffffc0000e58c0>] rcu_check_callbacks+0x438/0x78c
[<ffffffc0000e8f5c>] update_process_times+0x38/0x6c
[<ffffffc0000f6978>] tick_sched_handle.isra.16+0x1c/0x68
[<ffffffc0000f6a04>] tick_sched_timer+0x40/0x7c
[<ffffffc0000e9628>] __run_hrtimer.isra.34+0x48/0x104
[<ffffffc0000e9cbc>] hrtimer_interrupt+0xd4/0x268
[<ffffffc00041bea4>] arch_timer_handler_phys+0x28/0x38
[<ffffffc0000de1d8>] handle_percpu_devid_irq+0x74/0x98
[<ffffffc0000da388>] generic_handle_irq+0x30/0x4c
[<ffffffc0000da6a4>] __handle_domain_irq+0x60/0xb0
[<ffffffc00008141c>] gic_handle_irq+0x34/0x80
Exception stack(0xffffffc0790dbe30 to 0xffffffc0790dbf50)
be20:                                     790d8000 ffffffc0 0070457c ffffffc0
be40: 790dbf70 ffffffc0 00086164 ffffffc0 00000000 00000000 00000000 00000000
be60: 7feb1b1c ffffffc0 00000000 00000000 00000000 00000000 790dbef0 ffffffc0
be80: 00000000 00000000 00000000 00000000 790c9ab0 ffffffc0 790dbd90 ffffffc0
bea0: ffffcea0 00000000 01010101 01010101 00000038 00000000 00000000 00000000
bec0: b0b80a34 0000007f b0cb5598 0000007f 0017b670 ffffffc0 b0c3c100 0000007f
bee0: ce1e74a0 0000007f 790d8000 ffffffc0 0070457c ffffffc0 007044f8 ffffffc0
bf00: 0075480a ffffffc0 00000001 00000000 00639c98 ffffffc0 005184b8 ffffffc0
bf20: 80785000 00000000 000815e0 ffffffc0 80000000 00000040 790dbf70 ffffffc0
bf40: 00086160 ffffffc0 790dbf70 ffffffc0
[<ffffffc000084da4>] el1_irq+0x64/0xd8
[<ffffffc0000d1c04>] cpu_startup_entry+0xe8/0x12c
[<ffffffc000091910>] secondary_start_kernel+0x124/0x134

 { 0}  (t=17194 jiffies g=-267 c=-268 q=1)
Task dump for CPU 0:
swapper/0       R  running task        0     0      0 0x00000000
Call trace:
[<ffffffc000089148>] dump_backtrace+0x0/0x12c
[<ffffffc000089284>] show_stack+0x10/0x1c
[<ffffffc0000c2b84>] sched_show_task+0xa8/0x100
[<ffffffc0000c5cbc>] dump_cpu_task+0x3c/0x4c
[<ffffffc0000e213c>] rcu_dump_cpu_stacks+0x98/0xe8
[<ffffffc0000e58c0>] rcu_check_callbacks+0x438/0x78c
[<ffffffc0000e8f5c>] update_process_times+0x38/0x6c
[<ffffffc0000f6978>] tick_sched_handle.isra.16+0x1c/0x68
[<ffffffc0000f6a04>] tick_sched_timer+0x40/0x7c
[<ffffffc0000e9628>] __run_hrtimer.isra.34+0x48/0x104
[<ffffffc0000e9cbc>] hrtimer_interrupt+0xd4/0x268
[<ffffffc00041bea4>] arch_timer_handler_phys+0x28/0x38
[<ffffffc0000de1d8>] handle_percpu_devid_irq+0x74/0x98
[<ffffffc0000da388>] generic_handle_irq+0x30/0x4c
[<ffffffc0000da6a4>] __handle_domain_irq+0x60/0xb0
[<ffffffc00008141c>] gic_handle_irq+0x34/0x80
Exception stack(0xffffffc0006fbde0 to 0xffffffc0006fbf00)
bde0: 006f8000 ffffffc0 0070457c ffffffc0 006fbf20 ffffffc0 00086164 ffffffc0
be00: 00000000 00000000 00000000 00000000 7fe8ab1c ffffffc0 7fe8ab1c ffffffc0
be20: 7741ee00 ffffffc0 006fbea0 ffffffc0 00000000 00000000 666d6873 fefefeff
be40: 0070aaf0 ffffffc0 006fbd40 ffffffc0 7f7f7f7f 7f7f7f7f 01010101 01010101
be60: 00000020 00000000 00000000 00000000 b0b80a34 0000007f b0cb5598 0000007f
be80: 0017b670 ffffffc0 b0c3c100 0000007f ce1e74a0 0000007f 006f8000 ffffffc0
bea0: 0070457c ffffffc0 007044f8 ffffffc0 0075480a ffffffc0 00000001 00000000
bec0: 00639c98 ffffffc0 005184b8 ffffffc0 80785000 00000000 00080270 ffffffc0
bee0: 80000000 00000040 006fbf20 ffffffc0 00086160 ffffffc0 006fbf20 ffffffc0
[<ffffffc000084da4>] el1_irq+0x64/0xd8
[<ffffffc0000d1c04>] cpu_startup_entry+0xe8/0x12c
[<ffffffc000508d88>] rest_init+0x7c/0x88
[<ffffffc0006bc98c>] start_kernel+0x39c/0x3b4
Task dump for CPU 1:
swapper/1       R  running task        0     0      1 0x00000000
Call trace:
[<ffffffc00008655c>] __switch_to+0x74/0x8c
Task dump for CPU 2:
swapper/2       R  running task        0     0      1 0x00000002
Call trace:
[<ffffffc00008655c>] __switch_to+0x74/0x8c
[<ffffffc0000a4828>] irq_exit+0x80/0xd0
[<ffffffc0000da6a8>] __handle_domain_irq+0x64/0xb0
[<ffffffc00008141c>] gic_handle_irq+0x34/0x80
Exception stack(0xffffffc0790d7e30 to 0xffffffc0790d7f50)
7e20:                                     790d4000 ffffffc0 0070457c ffffffc0
7e40: 790d7f70 ffffffc0 00086164 ffffffc0 00000000 00000000 00000000 00000000
7e60: 7fea4b1c ffffffc0 7fea4b1c ffffffc0 78c24170 ffffffc0 790d7ef0 ffffffc0
7e80: 00000000 00000000 7feb3458 ffffffc0 790d7f10 ffffffc0 000f6548 ffffffc0
7ea0: 00763000 ffffffc0 00763c00 ffffffc0 73316280 00000050 006fe000 ffffffc0
7ec0: 006fe000 ffffffc0 00639c98 ffffffc0 005184b8 ffffffc0 80785000 00000000
7ee0: 000815e0 ffffffc0 80000000 00000040 000001f5 00000000 00000148 00000000
7f00: 790d7f10 ffffffc0 000f6544 ffffffc0 790d7f50 ffffffc0 000f6c14 ffffffc0
7f20: 7fea4f38 ffffffc0 7332edf8 00000050 007044f8 ffffffc0 0075480a ffffffc0
7f40: 00000001 00000000 7fea4f38 ffffffc0
[<ffffffc000084da4>] el1_irq+0x64/0xd8

INFO: rcu_preempt detected stalls on CPUs/tasks: { 1 2} (detected by 0, t=287104493908 jiffies, g=-267, c=-268, q=2)
Task dump for CPU 1:
swapper/1       R  running task        0     0      1 0x00000002
Call trace:
[<ffffffc00008655c>] __switch_to+0x74/0x8c
Task dump for CPU 2:
swapper/2       R  running task        0     0      1 0x00000002
Call trace:
[<ffffffc00008655c>] __switch_to+0x74/0x8c
[<ffffffc0000a4828>] irq_exit+0x80/0xd0
[<ffffffc0000da6a8>] __handle_domain_irq+0x64/0xb0
[<ffffffc00008141c>] gic_handle_irq+0x34/0x80
Exception stack(0xffffffc0790d7e30 to 0xffffffc0790d7f50)
7e20:                                     790d4000 ffffffc0 0070457c ffffffc0
7e40: 790d7f70 ffffffc0 00086164 ffffffc0 00000000 00000000 00000000 00000000
7e60: 7fea4b1c ffffffc0 7fea4b1c ffffffc0 790d7e90 ffffffc0 000ef710 ffffffc0
7e80: 007638c8 ffffffc0 00000007 00000000 790d7f10 ffffffc0 000f6548 ffffffc0
7ea0: 00763000 ffffffc0 00763c00 ffffffc0 73316280 00000050 006fe000 ffffffc0
7ec0: 006fe000 ffffffc0 00639c98 ffffffc0 005184b8 ffffffc0 80785000 00000000
7ee0: 000815e0 ffffffc0 80000000 00000040 000001f5 00000000 00000148 00000000
7f00: 790d7f10 ffffffc0 000f6544 ffffffc0 790d7f50 ffffffc0 000f6c14 ffffffc0
7f20: 7fea4f38 ffffffc0 7332edf8 00000050 007044f8 ffffffc0 0075480a ffffffc0
7f40: 00000001 00000000 7fea4f38 ffffffc0
[<ffffffc000084da4>] el1_irq+0x64/0xd8
INFO: rcu_preempt detected stalls on CPUs/tasks: { 1 2} (detected by 0, t=287104508993 jiffies, g=-267, c=-268, q=6)
Task dump for CPU 1:
swapper/1       R  running task        0     0      1 0x00000002
Call trace:
[<ffffffc00008655c>] __switch_to+0x74/0x8c
Task dump for CPU 2:
swapper/2       R  running task        0     0      1 0x00000002
Call trace:
[<ffffffc00008655c>] __switch_to+0x74/0x8c
[<ffffffc0000a4828>] irq_exit+0x80/0xd0
[<ffffffc0000da6a8>] __handle_domain_irq+0x64/0xb0
[<ffffffc00008141c>] gic_handle_irq+0x34/0x80
Exception stack(0xffffffc0790d7e30 to 0xffffffc0790d7f50)
7e20:                                     790d4000 ffffffc0 0070457c ffffffc0
7e40: 790d7f70 ffffffc0 00086164 ffffffc0 00000000 00000000 00000000 00000000
7e60: 7fea4b1c ffffffc0 7fea4b1c ffffffc0 790d7e90 ffffffc0 000ef710 ffffffc0
7e80: 007638c8 ffffffc0 00000007 00000000 790d7f10 ffffffc0 000f6548 ffffffc0
7ea0: 00763000 ffffffc0 00763c00 ffffffc0 73316280 00000050 006fe000 ffffffc0
7ec0: 006fe000 ffffffc0 00639c98 ffffffc0 005184b8 ffffffc0 80785000 00000000
7ee0: 000815e0 ffffffc0 80000000 00000040 000001f5 00000000 00000148 00000000
7f00: 790d7f10 ffffffc0 000f6544 ffffffc0 790d7f50 ffffffc0 000f6c14 ffffffc0
7f20: 7fea4f38 ffffffc0 7332edf8 00000050 007044f8 ffffffc0 0075480a ffffffc0
7f40: 00000001 00000000 7fea4f38 ffffffc0
[<ffffffc000084da4>] el1_irq+0x64/0xd8
INFO: rcu_preempt detected stalls on CPUs/tasks: { 1} (detected by 0, t=354658509690 jiffies, g=-267, c=-268, q=6)
Task dump for CPU 1:
swapper/1       R  running task        0     0      1 0x00000002
Call trace:
[<ffffffc00008655c>] __switch_to+0x74/0x8c
NMI watchdog: BUG: soft lockup - CPU#1 stuck for 8524s! [swapper/1:0]
Modules linked in:

CPU: 1 PID: 0 Comm: swapper/1 Not tainted 3.19.3+ #18
Hardware name: LS1043A RDB Board (DT)
task: ffffffc0790c8000 ti: ffffffc0790d0000 task.ti: ffffffc0790d0000
PC is at arch_cpu_idle+0x10/0x18
LR is at arch_cpu_idle+0xc/0x18
pc : [<ffffffc000086164>] lr : [<ffffffc000086160>] pstate: 60000045
sp : ffffffc0790d3f70
x29: ffffffc0790d3f70 x28: 0000004080000000
x27: ffffffc0000815e0 x26: 0000000080785000
x25: ffffffc0005184b8 x24: ffffffc000639c98
x23: 0000000000000001 x22: ffffffc00075480a
x21: ffffffc0007044f8 x20: ffffffc00070457c
x19: ffffffc0790d0000 x18: 000000000000000e
x17: 0000000000000007 x16: 0000000000000001
x15: 0000000000000007 x14: 0fffffffffffffff
x13: 0000000000000010 x12: ffffffc0006fe000
x11: 00000000005e0000 x10: 00000000ffffcea0
x9 : ffffffc0790d3d90 x8 : ffffffc0790c8530
x7 : 0000000000000001 x6 : 0000000000000000
x5 : ffffffc0790d3ef0 x4 : ffffffc0790f8000
x3 : ffffffc07fe97b1c x2 : ffffffc07fe97b1c
x1 : 0000000000000000 x0 : 0000000000000000

INFO: rcu_preempt detected stalls on CPUs/tasks: { 1} (detected by 0, t=575334887890 jiffies, g=-267, c=-268, q=6)
Task dump for CPU 1:
swapper/1       R  running task        0     0      1 0x00000002
Call trace:
[<ffffffc00008655c>] __switch_to+0x74/0x8c
sched: RT throttling activated
INFO: rcu_preempt detected stalls on CPUs/tasks: { 1} (detected by 0, t=576460802941 jiffies, g=-267, c=-268, q=6)
Task dump for CPU 1:
swapper/1       R  running task        0     0      1 0x00000002
Call trace:
[<ffffffc00008655c>] __switch_to+0x74/0x8c
INFO: rcu_preempt detected stalls on CPUs/tasks: { 1} (detected by 0, t=642888903855 jiffies, g=-267, c=-268, q=6)
Task dump for CPU 1:
swapper/1       R  running task        0     0      1 0x00000002
Call trace:
[<ffffffc00008655c>] __switch_to+0x74/0x8c
hrtimer: interrupt took 8635652818586378360 ns
INFO: rcu_preempt detected stalls on CPUs/tasks: { 1} (detected by 0, t=864691196905 jiffies, g=-267, c=-268, q=6)
Task dump for CPU 1:
swapper/1       R  running task        0     0      1 0x00000002
Call trace:
[<ffffffc00008655c>] __switch_to+0x74/0x8c
------------[ cut here ]------------
------------[ cut here ]------------
WARNING: CPU: 0 PID: 0 at kernel/time/clockevents.c:249 clockevents_program_event+0xf4/0x104()
Modules linked in:
CPU: 0 PID: 0 Comm: swapper/0 Tainted: G             L 3.19.3+ #18
Hardware name: LS1043A RDB Board (DT)
Call trace:
[<ffffffc000089148>] dump_backtrace+0x0/0x12c
[<ffffffc000089284>] show_stack+0x10/0x1c
[<ffffffc00050e2c0>] dump_stack+0x88/0xd8
[<ffffffc0000a0cb4>] warn_slowpath_common+0x94/0xcc
[<ffffffc0000a0db0>] warn_slowpath_null+0x14/0x20
[<ffffffc0000f40d0>] clockevents_program_event+0xf0/0x104
[<ffffffc0000f6044>] tick_program_event+0x28/0x34
[<ffffffc0000e9d78>] hrtimer_interrupt+0x190/0x268
[<ffffffc00041bea4>] arch_timer_handler_phys+0x28/0x38
[<ffffffc0000de1d8>] handle_percpu_devid_irq+0x74/0x98
[<ffffffc0000da388>] generic_handle_irq+0x30/0x4c
[<ffffffc0000da6a4>] __handle_domain_irq+0x60/0xb0
[<ffffffc00008141c>] gic_handle_irq+0x34/0x80
Exception stack(0xffffffc0006fbde0 to 0xffffffc0006fbf00)
bde0: 006f8000 ffffffc0 0070457c ffffffc0 006fbf20 ffffffc0 00086164 ffffffc0
be00: 00000000 00000000 00000000 00000000 7fe8ab1c ffffffc0 7fe8ab1c ffffffc0
be20: 7741ee00 ffffffc0 006fbea0 ffffffc0 5035998f 780000d7 00763bc0 ffffffc0
be40: 0070aaf0 ffffffc0 006fbd40 ffffffc0 036568cc 00000002 0004baf6 00000000
be60: 00000018 00000000 e8000000 00000003 0000003f 00000000 30000000 0ebd9208
be80: 00190250 ffffffc0 b0c411b0 0000007f ce1e77d0 0000007f 006f8000 ffffffc0
bea0: 0070457c ffffffc0 007044f8 ffffffc0 0075480a ffffffc0 00000001 00000000
bec0: 00639c98 ffffffc0 005184b8 ffffffc0 80785000 00000000 00080270 ffffffc0
bee0: 80000000 00000040 006fbf20 ffffffc0 00086160 ffffffc0 006fbf20 ffffffc0
[<ffffffc000084da4>] el1_irq+0x64/0xd8
[<ffffffc0000d1c04>] cpu_startup_entry+0xe8/0x12c
[<ffffffc000508d88>] rest_init+0x7c/0x88
[<ffffffc0006bc98c>] start_kernel+0x39c/0x3b4
---[ end trace 5a3a0a43fd142b8b ]---
WARNING: CPU: 2 PID: 0 at kernel/time/clockevents.c:249 clockevents_program_event+0xf4/0x104()
Modules linked in:
CPU: 2 PID: 0 Comm: swapper/2 Tainted: G        W    L 3.19.3+ #18
Hardware name: LS1043A RDB Board (DT)
Call trace:
[<ffffffc000089148>] dump_backtrace+0x0/0x12c
[<ffffffc000089284>] show_stack+0x10/0x1c
[<ffffffc00050e2c0>] dump_stack+0x88/0xd8
[<ffffffc0000a0cb4>] warn_slowpath_common+0x94/0xcc
[<ffffffc0000a0db0>] warn_slowpath_null+0x14/0x20
[<ffffffc0000f40d0>] clockevents_program_event+0xf0/0x104
[<ffffffc0000f6044>] tick_program_event+0x28/0x34
[<ffffffc0000e9d78>] hrtimer_interrupt+0x190/0x268
[<ffffffc00041bea4>] arch_timer_handler_phys+0x28/0x38
[<ffffffc0000de1d8>] handle_percpu_devid_irq+0x74/0x98
[<ffffffc0000da388>] generic_handle_irq+0x30/0x4c
[<ffffffc0000da6a4>] __handle_domain_irq+0x60/0xb0
[<ffffffc00008141c>] gic_handle_irq+0x34/0x80
Exception stack(0xffffffc0790d7e30 to 0xffffffc0790d7f50)
7e20:                                     790d4000 ffffffc0 0070457c ffffffc0
7e40: 790d7f70 ffffffc0 00086164 ffffffc0 00000000 00000000 00000000 00000000
7e60: 7fea4b1c ffffffc0 0041bf50 ffffffc0 00000020 00000000 00000000 00000000
7e80: 7fea4c88 ffffffc0 7fea5070 ffffffc0 790c8ff0 ffffffc0 790d7d90 ffffffc0
7ea0: 005191c4 ffffffc0 005191c0 ffffffc0 00000000 00989680 00000000 00000000
7ec0: 00000008 00000000 00000000 00000000 00000001 00000000 00000007 00000000
7ee0: 0000000e 00000000 790d4000 ffffffc0 0070457c ffffffc0 007044f8 ffffffc0
7f00: 0075480a ffffffc0 00000001 00000000 00639c98 ffffffc0 005184b8 ffffffc0
7f20: 80785000 00000000 000815e0 ffffffc0 80000000 00000040 790d7f70 ffffffc0
7f40: 00086160 ffffffc0 790d7f70 ffffffc0
[<ffffffc000084da4>] el1_irq+0x64/0xd8
[<ffffffc0000d1c04>] cpu_startup_entry+0xe8/0x12c
[<ffffffc000091910>] secondary_start_kernel+0x124/0x134

Regards,
Bhupesh


From julian.calaby at gmail.com  Sun Aug  2 21:22:13 2015
From: julian.calaby at gmail.com (Julian Calaby)
Date: Mon, 3 Aug 2015 14:22:13 +1000
Subject: [linux-sunxi] [PATCH] ARM: dts: sunxi: Raise minimum CPU voltage
 for sun7i-a20 to a level all boards can supply
In-Reply-To: <CAGb2v67o-=_cL2RWfXJ+3C86zfQ_1b5DYRi3_zwvwy6su6+gdw@mail.gmail.com>
References: <1438543386-7253-1-git-send-email-public_timo.s@silentcreek.de>
 <CAGRGNgV6b9yt2HnB2x2Wyc05KEahoX-Y+mVhxsryztcfA36H1g@mail.gmail.com>
 <CAGb2v67o-=_cL2RWfXJ+3C86zfQ_1b5DYRi3_zwvwy6su6+gdw@mail.gmail.com>
Message-ID: <CAGRGNgXH90m9h0DDejd5MTf8enduGFQ8dPKrRhmc8Z6y_PaC1w@mail.gmail.com>

Hi Chen-Yu,

On Mon, Aug 3, 2015 at 12:37 PM, Chen-Yu Tsai <wens at csie.org> wrote:
> Hi,
>
> On Mon, Aug 3, 2015 at 7:35 AM, Julian Calaby <julian.calaby at gmail.com> wrote:
>> Hi Timo,
>>
>> On Mon, Aug 3, 2015 at 5:23 AM, Timo Sigurdsson
>> <public_timo.s at silentcreek.de> wrote:
>>> sun7i-a20.dtsi contains an cpufreq operating point at 0.9 volts. Most A20 boards
>>> (or all?), however, do not allow the voltage to go below 1.0V. Thus, raise the
>>> voltage for the lowest operating point to 1.0V so all boards can actually use
>>> it.
>>
>> Surely it wouldn't be added here if some could supply 0.9v.
>
> On the side, the original OPPs in the FEX files are actually
> frequency/voltage ranges, and not just points. Mainlines OPPv2
> will support these, along with turbo frequencies.

Ah, that makes sense.

> Furthermore, the FEX files also have fields that limit the
> minimum and maximum frequencies.

Is this going to be supported by OPPv2 too?

>> Is the code that uses this smart enough to sensibly switch between two
>> operating points with the same frequency and different voltages? If
>> so, maybe just add a 144MHz @ 1.0v operating point?
>
> You could try. Though I really don't see much to gain here.

>From what I recall, lower frequency = less power usage, though my
experience is from x86 laptops, not ARM SoCs and I'm sure I'm missing
a lot of details. This is the sort of thing that requires thorough
testing on a dev board.

>> (Alternatively, would it make sense to modify the code that uses this
>> to use frequencies with voltages specified that are lower than can be
>> supplied with the lowest voltage it can?)
>
> I think that's a bit harder to get accepted.

Oh, definitely. It kinda makes sense, but at the same time it'll
require some seriously thorough testing on a lot of different boards.

My only real objection here is are there boards that can go down to
0.9v and if so, won't this change make them less power efficient in
the almost-idle case? And are those power savings enough to justify
not accepting this patch?

Thanks,

-- 
Julian Calaby

Email: julian.calaby at gmail.com
Profile: http://www.google.com/profiles/julian.calaby/


From wens at csie.org  Sun Aug  2 21:26:17 2015
From: wens at csie.org (Chen-Yu Tsai)
Date: Mon, 3 Aug 2015 12:26:17 +0800
Subject: [linux-sunxi] [PATCH] ARM: dts: sunxi: Raise minimum CPU voltage
 for sun7i-a20 to a level all boards can supply
In-Reply-To: <CAGRGNgXH90m9h0DDejd5MTf8enduGFQ8dPKrRhmc8Z6y_PaC1w@mail.gmail.com>
References: <1438543386-7253-1-git-send-email-public_timo.s@silentcreek.de>
 <CAGRGNgV6b9yt2HnB2x2Wyc05KEahoX-Y+mVhxsryztcfA36H1g@mail.gmail.com>
 <CAGb2v67o-=_cL2RWfXJ+3C86zfQ_1b5DYRi3_zwvwy6su6+gdw@mail.gmail.com>
 <CAGRGNgXH90m9h0DDejd5MTf8enduGFQ8dPKrRhmc8Z6y_PaC1w@mail.gmail.com>
Message-ID: <CAGb2v67p5UhZ9Kwd_YEEQQzgiK7dgHqeQMckS7aw4HCFCCGoUA@mail.gmail.com>

On Mon, Aug 3, 2015 at 12:22 PM, Julian Calaby <julian.calaby at gmail.com> wrote:
> Hi Chen-Yu,
>
> On Mon, Aug 3, 2015 at 12:37 PM, Chen-Yu Tsai <wens at csie.org> wrote:
>> Hi,
>>
>> On Mon, Aug 3, 2015 at 7:35 AM, Julian Calaby <julian.calaby at gmail.com> wrote:
>>> Hi Timo,
>>>
>>> On Mon, Aug 3, 2015 at 5:23 AM, Timo Sigurdsson
>>> <public_timo.s at silentcreek.de> wrote:
>>>> sun7i-a20.dtsi contains an cpufreq operating point at 0.9 volts. Most A20 boards
>>>> (or all?), however, do not allow the voltage to go below 1.0V. Thus, raise the
>>>> voltage for the lowest operating point to 1.0V so all boards can actually use
>>>> it.
>>>
>>> Surely it wouldn't be added here if some could supply 0.9v.
>>
>> On the side, the original OPPs in the FEX files are actually
>> frequency/voltage ranges, and not just points. Mainlines OPPv2
>> will support these, along with turbo frequencies.
>
> Ah, that makes sense.
>
>> Furthermore, the FEX files also have fields that limit the
>> minimum and maximum frequencies.
>
> Is this going to be supported by OPPv2 too?

IIRC yes, OPPv2 moves to a range profile. OPPv2 is not merged yet.

>>> Is the code that uses this smart enough to sensibly switch between two
>>> operating points with the same frequency and different voltages? If
>>> so, maybe just add a 144MHz @ 1.0v operating point?
>>
>> You could try. Though I really don't see much to gain here.
>
> From what I recall, lower frequency = less power usage, though my
> experience is from x86 laptops, not ARM SoCs and I'm sure I'm missing
> a lot of details. This is the sort of thing that requires thorough
> testing on a dev board.

I agree, though my limited experiences tell me that the major savings
come from lowering the core voltage.

>>> (Alternatively, would it make sense to modify the code that uses this
>>> to use frequencies with voltages specified that are lower than can be
>>> supplied with the lowest voltage it can?)
>>
>> I think that's a bit harder to get accepted.
>
> Oh, definitely. It kinda makes sense, but at the same time it'll
> require some seriously thorough testing on a lot of different boards.
>
> My only real objection here is are there boards that can go down to
> 0.9v and if so, won't this change make them less power efficient in
> the almost-idle case? And are those power savings enough to justify
> not accepting this patch?

This will require most testing as well. (sigh) Alas, my boards aren't
stable enough at 0.9V, so I can't say much about it.


ChenYu


From ulli.kroll at googlemail.com  Sun Aug  2 21:32:02 2015
From: ulli.kroll at googlemail.com (Hans Ulli Kroll)
Date: Mon, 3 Aug 2015 06:32:02 +0200 (CEST)
Subject: [PATCH 9/15 V2] drivers: rtc: Drop (un)likely before
 IS_ERR(_OR_NULL)
In-Reply-To: <b8be698a8625ceb9adc8da51cd9474626db7c3d1.1438339891.git.viresh.kumar@linaro.org>
References: <cdfa3fb76901fe1c4a5756e7e64cb3370cf6317a.1438331416.git.viresh.kumar@linaro.org>
 <b8be698a8625ceb9adc8da51cd9474626db7c3d1.1438339891.git.viresh.kumar@linaro.org>
Message-ID: <alpine.LNX.2.00.1508030631150.8913@T520.work>

Hi

On Fri, 31 Jul 2015, Viresh Kumar wrote:

> IS_ERR(_OR_NULL) already contain an 'unlikely' compiler flag and there
> is no need to do that again from its callers. Drop it.
> 
> gemini driver was using likely() for a failure case while the rtc driver
> is getting registered. That looks wrong and it should really be
> unlikely. But because we are killing all the unlikely() flags, lets kill
> that too.
> 
> Signed-off-by: Viresh Kumar <viresh.kumar at linaro.org>
> ---
> V1->V2:
> - Removed the likely() part from gemini driver and the changelog wasn't
>   updated to match that. Fixed the changelog now.
> 
>  drivers/rtc/interface.c  | 2 +-
>  drivers/rtc/rtc-bfin.c   | 2 +-
>  drivers/rtc/rtc-gemini.c | 2 +-
>  3 files changed, 3 insertions(+), 3 deletions(-)
> 
> diff --git a/drivers/rtc/interface.c b/drivers/rtc/interface.c
> index 11b639067312..5836751b8203 100644
> --- a/drivers/rtc/interface.c
> +++ b/drivers/rtc/interface.c
> @@ -564,7 +564,7 @@ enum hrtimer_restart rtc_pie_update_irq(struct hrtimer *timer)
>  void rtc_update_irq(struct rtc_device *rtc,
>  		unsigned long num, unsigned long events)
>  {
> -	if (unlikely(IS_ERR_OR_NULL(rtc)))
> +	if (IS_ERR_OR_NULL(rtc))
>  		return;
>  
>  	pm_stay_awake(rtc->dev.parent);
> diff --git a/drivers/rtc/rtc-bfin.c b/drivers/rtc/rtc-bfin.c
> index 3d44b11721ea..535a5f9338d0 100644
> --- a/drivers/rtc/rtc-bfin.c
> +++ b/drivers/rtc/rtc-bfin.c
> @@ -361,7 +361,7 @@ static int bfin_rtc_probe(struct platform_device *pdev)
>  	/* Register our RTC with the RTC framework */
>  	rtc->rtc_dev = devm_rtc_device_register(dev, pdev->name, &bfin_rtc_ops,
>  						THIS_MODULE);
> -	if (unlikely(IS_ERR(rtc->rtc_dev)))
> +	if (IS_ERR(rtc->rtc_dev))
>  		return PTR_ERR(rtc->rtc_dev);
>  
>  	/* Grab the IRQ and init the hardware */
> diff --git a/drivers/rtc/rtc-gemini.c b/drivers/rtc/rtc-gemini.c
> index 35f4486738fc..2fed93e1114a 100644
> --- a/drivers/rtc/rtc-gemini.c
> +++ b/drivers/rtc/rtc-gemini.c
> @@ -148,7 +148,7 @@ static int gemini_rtc_probe(struct platform_device *pdev)
>  
>  	rtc->rtc_dev = rtc_device_register(pdev->name, dev,
>  					   &gemini_rtc_ops, THIS_MODULE);
> -	if (likely(IS_ERR(rtc->rtc_dev)))
> +	if (IS_ERR(rtc->rtc_dev))
>  		return PTR_ERR(rtc->rtc_dev);
>  
>  	return 0;
> -- 
> 2.4.0
> 
> 

For the mach-gemini part
Acked-by: Hans Ulli Kroll <ulli.kroll at googlemail.com>




From robert.jarzmik at free.fr  Sun Aug  2 21:44:21 2015
From: robert.jarzmik at free.fr (Robert Jarzmik)
Date: Mon, 03 Aug 2015 06:44:21 +0200
Subject: [PATCH v2 0/4] mtd: pxa3xx_nand: rework the timing setup
In-Reply-To: <CAAEAJfB3caa+DmJN=Pa8brx0uGC11QA29KJb3NQdJjXTgw-yuA@mail.gmail.com>
 (Ezequiel Garcia's message of "Sun, 2 Aug 2015 23:49:55 -0300")
References: <1436281707-20106-1-git-send-email-antoine.tenart@free-electrons.com>
 <20150717134159.GC10608@kwain> <55A912F0.7080605@vanguardiasur.com.ar>
 <87h9p2is8e.fsf@belgarion.home>
 <CAAEAJfCcdioVQKZs9U3DP6H94BiuQ2qU21DsMKevS5+j+-XEKA@mail.gmail.com>
 <87wpxufw2v.fsf@belgarion.home>
 <CAAEAJfB3caa+DmJN=Pa8brx0uGC11QA29KJb3NQdJjXTgw-yuA@mail.gmail.com>
Message-ID: <87si81m15m.fsf@belgarion.home>

Ezequiel Garcia <ezequiel at vanguardiasur.com.ar> writes:

> Just tested linux-next (hence *without* the patchset) and I see
> the same "Wait time out". In other words, pxa3xx-nand is broken
> on PXA :/
>
> Interestingly, the culprit doesn't seem to be in pxa3xx-nand itself.
> Reverting the recent commits on pxa3xx-nand doesn't help.
>
> ce914e6 mtd: nand: pxa3xx: fix build on ARM64
> afca11e mtd: nand: pxa3xx: Switch FIFO draining to jiffies-based timeout
> e5860c1 mtd: pxa3xx_nand: cleanup wait_for_completion handling
> 7c2f717 mtd: pxa3xx_nand: initialiaze pxa3xx_flash_ids to 0
> ed446cc Merge MTD updates into -next
> e423c90 mtd: pxa3xx_nand: fix driver when num_cs is 0
> 2454225 mtd: pxa3xx-nand: handle PIO in threaded interrupt
> 8dad038 mtd: nand: pxa3xx: Fix PIO FIFO draining
> b7e46062 mtd: pxa3xx_nand: make the driver work on big-endian systems
> 5b3e507 mtd: nand: pxa3xx: Use ECC strength and step size devicetree binding
> eee0166 mtd: nand: pxa3xx: Clean pxa_ecc_init() error handling
> 17754ad mtd: nand: pxa3xx: Make of_device_id array const
> e634ce5 mtd: nand: pxa3xx: Print actual ECC strength in error message
>
> Yet v3.18 succeeds to pass a few NAND blocks on nandtest.
>
> Robert: any ideas?
Actually yes, I worked on that this weekend.
Would you try the following patch [1] to see if it works for you ?

The issue I see is that :
 - there is a bug in the clk driver for pxa3xx I introduced (CKEN_AB)
 - and shutting down the GCU clock prevents the NAND from working (I can't
 explain that one yet)

Cheers.

-- 
Robert

[1] Clocks patch
---8>---
diff --git a/drivers/clk/pxa/clk-pxa3xx.c b/drivers/clk/pxa/clk-pxa3xx.c
index c677b9ab5367..a47a0c40f937 100644
--- a/drivers/clk/pxa/clk-pxa3xx.c
+++ b/drivers/clk/pxa/clk-pxa3xx.c
@@ -126,7 +126,7 @@ PARENTS(pxa3xx_ac97_bus) = { "ring_osc_60mhz", "ac97" };
 PARENTS(pxa3xx_sbus) = { "ring_osc_60mhz", "system_bus" };
 PARENTS(pxa3xx_smemcbus) = { "ring_osc_60mhz", "smemc" };
 
-#define CKEN_AB(bit) ((CKEN_ ## bit > 31) ? &CKENA : &CKENB)
+#define CKEN_AB(bit) ((CKEN_ ## bit > 31) ? &CKENB : &CKENA)
 #define PXA3XX_CKEN(dev_id, con_id, parents, mult_lp, div_lp, mult_hp,	\
 		    div_hp, bit, is_lp, flags)				\
 	PXA_CKEN(dev_id, con_id, bit, parents, mult_lp, div_lp,		\
@@ -136,6 +136,10 @@ PARENTS(pxa3xx_smemcbus) = { "ring_osc_60mhz", "smemc" };
 			 mult_hp, div_hp, delay)			\
 	PXA3XX_CKEN(dev_id, con_id, pxa3xx_pbus_parents, mult_lp,	\
 		    div_lp, mult_hp, div_hp, bit, pxa3xx_is_ring_osc_forced, 0)
+#define PXA3XX_PBUS_CKENF(dev_id, con_id, bit, mult_lp, div_lp,		\
+			  mult_hp, div_hp, delay, flag)			\
+	PXA3XX_CKEN(dev_id, con_id, pxa3xx_pbus_parents, mult_lp,	\
+		    div_lp, mult_hp, div_hp, bit, pxa3xx_is_ring_osc_forced, flag)
 #define PXA3XX_CKEN_1RATE(dev_id, con_id, bit, parents)			\
 	PXA_CKEN_1RATE(dev_id, con_id, bit, parents,			\
 		       CKEN_AB(bit), (CKEN_ ## bit % 32), 0)
@@ -173,13 +177,13 @@ static struct desc_clk_cken pxa3xx_clocks[] __initdata = {
 
 static struct desc_clk_cken pxa300_310_clocks[] __initdata = {
 
-	PXA3XX_PBUS_CKEN("pxa3xx-gcu", NULL, PXA300_GCU, 1, 1, 1, 1, 0),
-	PXA3XX_PBUS_CKEN("pxa3xx-nand", NULL, NAND, 1, 2, 1, 4, 0),
+	PXA3XX_PBUS_CKENF("pxa3xx-gcu", NULL, PXA300_GCU, 1, 1, 1, 1, 0, CLK_IGNORE_UNUSED),
+	PXA3XX_PBUS_CKENF("pxa3xx-nand", NULL, NAND, 1, 2, 1, 4, 0, CLK_IGNORE_UNUSED),
 	PXA3XX_CKEN_1RATE("pxa3xx-gpio", NULL, GPIO, pxa3xx_13MHz_bus_parents),
 };
 
 static struct desc_clk_cken pxa320_clocks[] __initdata = {
-	PXA3XX_PBUS_CKEN("pxa3xx-nand", NULL, NAND, 1, 2, 1, 6, 0),
+	PXA3XX_PBUS_CKENF("pxa3xx-nand", NULL, NAND, 1, 2, 1, 4, 0, CLK_IGNORE_UNUSED),
 	PXA3XX_PBUS_CKEN("pxa3xx-gcu", NULL, PXA320_GCU, 1, 1, 1, 1, 0),
 	PXA3XX_CKEN_1RATE("pxa3xx-gpio", NULL, GPIO, pxa3xx_13MHz_bus_parents),
 };
@@ -187,7 +191,7 @@ static struct desc_clk_cken pxa320_clocks[] __initdata = {
 static struct desc_clk_cken pxa93x_clocks[] __initdata = {
 
 	PXA3XX_PBUS_CKEN("pxa3xx-gcu", NULL, PXA300_GCU, 1, 1, 1, 1, 0),
-	PXA3XX_PBUS_CKEN("pxa3xx-nand", NULL, NAND, 1, 2, 1, 4, 0),
+	PXA3XX_PBUS_CKENF("pxa3xx-nand", NULL, NAND, 1, 2, 1, 4, 0, CLK_IGNORE_UNUSED),
 	PXA3XX_CKEN_1RATE("pxa93x-gpio", NULL, GPIO, pxa3xx_13MHz_bus_parents),
 };
 


From vigneshr at ti.com  Sun Aug  2 21:57:19 2015
From: vigneshr at ti.com (Vignesh R)
Date: Mon, 3 Aug 2015 10:27:19 +0530
Subject: [RFC PATCH 1/5] spi: introduce flag for memory mapped read
In-Reply-To: <20150731181745.GM20873@sirena.org.uk>
References: <1438072876-16338-1-git-send-email-vigneshr@ti.com>
 <1438072876-16338-2-git-send-email-vigneshr@ti.com>
 <20150731181745.GM20873@sirena.org.uk>
Message-ID: <55BEF4AF.5090704@ti.com>

Hi,

On 7/31/2015 11:47 PM, Mark Brown wrote:
> On Tue, Jul 28, 2015 at 02:11:12PM +0530, Vignesh R wrote:
> 
>> Introduce use_mmap_read field in spi_message struct. This can be set by
>> mtd devices (m25p80) to indicate to spi-master (ti-qspi) to perform
>> memory mapped read. This helps to distinguish whether the spi-message is
>> from mtd layer(hence mmap read is possible) or by other spi devices.
> 
> Based on this description and...
> 
>> + * @use_mmap_mode: Indicate to spi master to perform memory mapped
>> + *	read if possible.
> 
> ...the internal documentation I unable to tell what is meant by "perform
> a memory mapped read", at least to the extent where it is visible
> outside of the driver.  This means we can't really use this as a generic
> API since other people won't be able to tell what it does.
> 


Will the following documentation provide better idea regarding the flag:

@use_mmap_mode: Some SPI controller chips are optimized for interacting
with serial flash memories. These chips have memory mapped interface,
through which entire serial flash memory slave can be read/written as if
though they are physical memories (like RAM). Using this interface,
flash can be accessed using memcpy() function and the spi controller
hardware will take care of communicating with serial flash over SPI.
Setting this flag will indicate the SPI controller driver that the
spi_message is from mtd layer to read from/write to flash. The SPI
master driver can then appropriately switch the controller to memory
mapped interface to read from/write to flash, based on this flag (See
drivers/spi/spi-ti-qspi.c for example).
NOTE: If the SPI controller chip lacks memory mapped interface, then the
driver will ignore this flag and use normal SPI protocol to read
from/write to flash. Communication with non-flash SPI devices is not
possible using the memory mapped interface.

I can update the patch commit message and documentation accordingly?

Regards
Vignesh


From vigneshr at ti.com  Sun Aug  2 22:02:09 2015
From: vigneshr at ti.com (Vignesh R)
Date: Mon, 3 Aug 2015 10:32:09 +0530
Subject: [RFC PATCH 4/5] ARM: dts: DRA7: Add memory map region entries
 for qspi
In-Reply-To: <20150731181903.GN20873@sirena.org.uk>
References: <1438072876-16338-1-git-send-email-vigneshr@ti.com>
 <1438072876-16338-5-git-send-email-vigneshr@ti.com>
 <20150731181903.GN20873@sirena.org.uk>
Message-ID: <55BEF5D1.1050608@ti.com>



On 07/31/2015 11:49 PM, Mark Brown wrote:
> On Tue, Jul 28, 2015 at 02:11:15PM +0530, Vignesh R wrote:
>> Add qspi memory mapped region entries for DRA7xx based SoCs.
>>
>> Signed-off-by: Vignesh R <vigneshr at ti.com>
> 
>>  		qspi: qspi at 47900000 {
>>  			compatible = "ti,am4372-qspi";
>> -			reg = <0x47900000 0x100>;
>> +			reg = <0x47900000 0x100>,
>> +			      <0x30000000 0x3ffffff>;
>> +			reg-names = "qspi_base", "qspi_mmap";
> 
> The DT binding document for the controller needs to be extended to
> document this change in the binding.
> 

DT bindings are already documented at
Documentation/devicetree/bindings/spi/ti_qspi.txt. Did you mean to add
this node as an example in that file?

-- 
Regards
Vignesh


From vigneshr at ti.com  Sun Aug  2 22:06:44 2015
From: vigneshr at ti.com (Vignesh R)
Date: Mon, 3 Aug 2015 10:36:44 +0530
Subject: [RFC PATCH 4/5] ARM: dts: DRA7: Add memory map region entries
 for qspi
In-Reply-To: <20150731212847.GH10676@google.com>
References: <1438072876-16338-1-git-send-email-vigneshr@ti.com>
 <1438072876-16338-5-git-send-email-vigneshr@ti.com>
 <20150731212847.GH10676@google.com>
Message-ID: <55BEF6E4.2000905@ti.com>



On 08/01/2015 02:58 AM, Brian Norris wrote:
> On Tue, Jul 28, 2015 at 02:11:15PM +0530, Vignesh R wrote:
>> Add qspi memory mapped region entries for DRA7xx based SoCs.
>>
>> Signed-off-by: Vignesh R <vigneshr at ti.com>
>> ---
>>  arch/arm/boot/dts/am4372.dtsi | 4 +++-
>>  1 file changed, 3 insertions(+), 1 deletion(-)
>>
>> diff --git a/arch/arm/boot/dts/am4372.dtsi b/arch/arm/boot/dts/am4372.dtsi
>> index ade28c790f4b..5317a0f24ab9 100644
>> --- a/arch/arm/boot/dts/am4372.dtsi
>> +++ b/arch/arm/boot/dts/am4372.dtsi
>> @@ -902,7 +902,9 @@
>>  
>>  		qspi: qspi at 47900000 {
>>  			compatible = "ti,am4372-qspi";
>> -			reg = <0x47900000 0x100>;
>> +			reg = <0x47900000 0x100>,
>> +			      <0x30000000 0x3ffffff>;
> 
> Are you sure this region is 1 byte shy of 64MB in length? Same question
> for patch 5.
> 

Oops, my bad... Its 64MB in length, I entered offset of last byte
instead of length. Will correct this in the actual patch.

>> +			reg-names = "qspi_base", "qspi_mmap";
>>  			#address-cells = <1>;
>>  			#size-cells = <0>;
>>  			ti,hwmods = "qspi";
>> -- 
>> 2.4.6
>>

-- 
Regards
Vignesh


From vigneshr at ti.com  Sun Aug  2 22:09:38 2015
From: vigneshr at ti.com (Vignesh R)
Date: Mon, 3 Aug 2015 10:39:38 +0530
Subject: [RFC PATCH 4/5] ARM: dts: DRA7: Add memory map region entries
 for qspi
In-Reply-To: <55BB7CA4.1020300@ti.com>
References: <1438072876-16338-1-git-send-email-vigneshr@ti.com>
 <1438072876-16338-5-git-send-email-vigneshr@ti.com> <55BB7CA4.1020300@ti.com>
Message-ID: <55BEF792.7000307@ti.com>



On 07/31/2015 07:18 PM, Sekhar Nori wrote:
> On Tuesday 28 July 2015 02:11 PM, Vignesh R wrote:
>> Add qspi memory mapped region entries for DRA7xx based SoCs.
>>
>> Signed-off-by: Vignesh R <vigneshr at ti.com>
>> ---
>>  arch/arm/boot/dts/am4372.dtsi | 4 +++-
>>  1 file changed, 3 insertions(+), 1 deletion(-)
>>
>> diff --git a/arch/arm/boot/dts/am4372.dtsi b/arch/arm/boot/dts/am4372.dtsi
>> index ade28c790f4b..5317a0f24ab9 100644
>> --- a/arch/arm/boot/dts/am4372.dtsi
>> +++ b/arch/arm/boot/dts/am4372.dtsi
> 
> The patch talks about DRA7x in subject and description but you modify
> AM437x here. You have got commit text mixed up between 4/5 and 5/5.
> 
> Probably not the kind of feedback you are looking for an RFC, but since
> I noticed it..

Oh, my bad.. I will correct $subject when I submit actual patch series.

-- 
Regards
Vignesh


From peter.chen at freescale.com  Sun Aug  2 21:47:08 2015
From: peter.chen at freescale.com (Peter Chen)
Date: Mon, 3 Aug 2015 12:47:08 +0800
Subject: [PATCH v2 00/10] USB: chipidea misc patches
Message-ID: <1438577238-10153-1-git-send-email-peter.chen@freescale.com>

Hi all,

In this series, I add several new interfaces for chipidea driver,
they are mainly for system configuration adjustment. The USB
performance may be improved with these configuration changing,
but each vendor driver owner needs to consult with your IC
owner which configuration parameters are suitable for your system
before changing it, and only change it if necessary.

The other changes are for imx, it shows how imx uses these interfaces.
Shawn, the patch [5/10] and [9/10] are dts changes, help to review it
please.

Changes for v2:
- Use the bit fields which are not used. [Patch 2/10, 6/10, 10/10]
- According to Greg and Sascha comments, format patch 2/10's
  commit log.
- using non-burst instead of unburst for patch 7/10

Peter Chen (10):
  usb: chipidea: udc: zero-length packet is only needed for TX
  usb: chipidea: define stream mode disable for both roles
  usb: chipidea: imx: add stream mode enable for device mode at
    imx6sl/imx6sx
  Doc: usb: ci-hdrc-usb2: add ahb-burst-config for binding doc
  ARM: imx6: set ahb-burst-config as 0 for USB
  usb: chipidea: add ahb burst configuration interface
  usb: chipidea: usbmisc_imx: add non-burst setting for imx6
  Doc: usb: ci-hdrc-usb2: add tx(rx)-burst-config-dword for binding doc
  ARM: imx6: change default burst size for USB
  usb: chipidea: add tx/rx burst size configuration interface

 .../devicetree/bindings/usb/ci-hdrc-usb2.txt       | 10 ++++
 arch/arm/boot/dts/imx6qdl.dtsi                     | 12 +++++
 arch/arm/boot/dts/imx6sl.dtsi                      |  9 ++++
 arch/arm/boot/dts/imx6sx.dtsi                      |  9 ++++
 drivers/usb/chipidea/bits.h                        |  7 +++
 drivers/usb/chipidea/ci.h                          |  1 +
 drivers/usb/chipidea/ci_hdrc_imx.c                 | 16 +++---
 drivers/usb/chipidea/core.c                        | 62 +++++++++++++++++++++-
 drivers/usb/chipidea/udc.c                         |  2 +-
 drivers/usb/chipidea/usbmisc_imx.c                 | 12 ++++-
 include/linux/usb/chipidea.h                       | 11 +++-
 11 files changed, 140 insertions(+), 11 deletions(-)

-- 
1.9.1



From peter.chen at freescale.com  Sun Aug  2 21:47:09 2015
From: peter.chen at freescale.com (Peter Chen)
Date: Mon, 3 Aug 2015 12:47:09 +0800
Subject: [PATCH v2 01/10] usb: chipidea: udc: zero-length packet is only
 needed for TX
In-Reply-To: <1438577238-10153-1-git-send-email-peter.chen@freescale.com>
References: <1438577238-10153-1-git-send-email-peter.chen@freescale.com>
Message-ID: <1438577238-10153-2-git-send-email-peter.chen@freescale.com>

The zero-length packet is the sendor tells the receiver that there
is no more data, so it is only needed at the TX side.

Signed-off-by: Peter Chen <peter.chen at freescale.com>
---
 drivers/usb/chipidea/udc.c | 2 +-
 1 file changed, 1 insertion(+), 1 deletion(-)

diff --git a/drivers/usb/chipidea/udc.c b/drivers/usb/chipidea/udc.c
index 06b7224..51e66a1 100644
--- a/drivers/usb/chipidea/udc.c
+++ b/drivers/usb/chipidea/udc.c
@@ -445,7 +445,7 @@ static int _hardware_enqueue(struct ci_hw_ep *hwep, struct ci_hw_req *hwreq)
 		rest -= count;
 	}
 
-	if (hwreq->req.zero && hwreq->req.length
+	if (hwreq->req.zero && hwreq->req.length && hwep->dir == TX
 	    && (hwreq->req.length % hwep->ep.maxpacket == 0))
 		add_td_to_list(hwep, hwreq, 0);
 
-- 
1.9.1



From peter.chen at freescale.com  Sun Aug  2 21:47:10 2015
From: peter.chen at freescale.com (Peter Chen)
Date: Mon, 3 Aug 2015 12:47:10 +0800
Subject: [PATCH v2 02/10] usb: chipidea: define stream mode disable for both
 roles
In-Reply-To: <1438577238-10153-1-git-send-email-peter.chen@freescale.com>
References: <1438577238-10153-1-git-send-email-peter.chen@freescale.com>
Message-ID: <1438577238-10153-3-git-send-email-peter.chen@freescale.com>

The system bus and chipidea IP have different limitations for
both host and device mode.
For example, with below errata, we need to enable SDIS(Stream Disable
Mode) at host mode. But we don't want it for device mode at the
same system.

TAR 9000378958
Title: Non-Double Word Aligned Buffer Address Sometimes Causes Host to
Hang on OUT Retry
Impacted Configuration: Host mode, all transfer types
Description:
The host core operating in streaming mode may under run while sending
the data packet of an OUT transaction. This under run can occur if
there are unexpected system delays in fetching the remaining packet
data from memory. The host forces a bad CRC on the packet, the device
detects the error and discards the packet. The host then retries a Bulk,
Interrupt, or Control transfer if an under run occurs according to the
USB specification. During simulations, it was found that the host does
not issue the retry of the failed bulk OUT. It does not issue any other
transactions except SOF packets that have incorrect frame numbers.

The second failure mode occurs if the under run occurs on an ISO OUT
transaction and the next ISO transaction is a zero byte packet. The host
does not issue any transactions (including SOFs). The device detects a
Suspend condition, reverts to full speed, and waits for resume signaling.

A third failure mode occurs when the host under runs on an ISO OUT and
the next ISO in the schedule is an ISO OUT with two max packets of 1024
bytes each. The host should issue MDATA for the first OUT followed by
DATA1 for the second. However, it drops the MDATA transaction, and
issues the DATA1 transaction.

The system impact of this bug is the same regardless of the failure mode
observed. The host core hangs, the ehci_ctrl state machine waits for the
protocol engine to send the completion status for the corrupted
transaction, which never occurs. No indication is sent to the host
controller driver, no register bits change and no interrupts occur.
Eventually the requesting application times out.

Detailed internal behavior:
The EHCI control state machine (ehci_ctrl) in the DMA block is responsible
for parsing the schedules and initiating all transactions. The ehci_ctrl
state machine passes the transaction details to the protocol block by
writing the transaction information in to the TxFIFO. It then asserts
the pe_hst_run_pkt signal to inform the host protocol state machine
(pe_hst_state) that there is a packet in the TxFIFO.
A tag of 0x0 indicates a start of packet with the data providing the
following information:

35:32 Tag
31:30 Reserved
29:23 Endpoint (lowest 4 bits)
22:16 Address
15:10 Reserved
9:8 Endpoint speed
7:6 Endpoint type
5:6 Data Toggle
3:0 PID
The pe_hst_state reads the packet information and constructs the packet
and issues it to the PHY interface.
The ehci_ctrl state machine writes the start transaction information in
to the TxFIFO as 0x03002910c for the OUT packet that had the under run
error. However, it writes 0xC3002910C for the retry of the Out
transaction, which is incorrect.
The pe_hst_state enters a bus timeout state after sending the bad CRC
for the packet that under ran. It then purges any data that was back
filled in to the TxFIFO for the packet that under ran. The pe_hst_state
machine stops purging the TxFIFO when it is empty or if it reads a
location that has a tag of 0x0, indicating a start of packet command.

The pe_hst_state reads 0xC3002910C and discards it as it does not decode
to a start of packet command. It continues to purge the OUT data that
has been pre-buffered for the OUT retry . The pe_hst_state detects the
hst_packet_run signal and attempts to read the PID and address
information from the TxFIFO. This location has packet data and so does
not decode to a valid PID and so falls through to the PE_HST_SOF_LOAD
state where the frame_num_counter is updated. The frame_num_counter
is updated with the data in the TxFIFO. In this case, the data is
incorrect as the ehci_ctrl state machine did not initiate the load.
The hst_pe_state machine detects the SOF request signal and sends an
SOF with the bad frame number. Meanwhile, the ehci_ctrl state machine
waits indefinitely in the run_pkt state waiting for the completion
status from pe_hst_state machine, which will never happen.

The ISO failure case is similar except that there is no retry for ISO.
The ehci_ctrl state machine moves to the next transfer in the periodic
schedule. If the under run occurs on the last entry of the periodic
list then it moves to the Async schedule.

In the case of ISO OUT simulations, the next ISO is a zero byte OUT
and again the start of packet command gets corrupted. The TxFIFO is
empty when the hst_pe_state attempts to read the Address and PID
information as the transaction is a zero byte packet. This results
in the hst_pe_state machine staying in the GET_PID state, which means
that it does not issue any transactions (including SOFs). The device
detects a Suspend condition and reverts to full speed mode and waits
for a Resume or Reset signal.

The EHCI specification allows a Non-DoubleWord (32 bits) offset to
be used as a current offset for Buffer Pointer Page 0 of the qTD.
In Non-DoubleWord aligned cases, the core reads the packet data
from the AHB memory, performs the alignment operation before writing
it in to the TxFIFO as a 32 bit data word. An End Of Packet tag (EOP)
is written to the TxFIFO after all the packet data has been written
in to the TxFIFO. The alignment function is reset to Idle by the EOP
tag. The corruption of the start of packet command arises because the
packet buffer for the OUT transaction that under ran is not aligned
to a DoubleWord, and hence no EOP tag is written to the TxFIFO. The
alignment function is still active when the start packet information
is written in to the TxFIFO for the retry of the bulk packet or for
the next transaction in the case of an under run on an ISO. This
results in the corruption of the start tag and the transaction
information.

Click for waveform showing the command 0x 0000300291 being written in
to the TX FIFO for the Out that under ran.
Click for waveform showing the command 0xC3002910C written to the
TxFIFO instead of 0x 0000300291
Versions affected: Versions 2.10a and previous versions
How discovered: Customer simulation

Workaround:
1- The EHCI specification allows a non-DoubleWord offset to be used
as a current offset for Buffer Pointer Page 0 of the qTD. However,
if a DoubleWord offset is used then this issue does not arise.
2- Use non streaming mode to eliminate under runs.

Resolution:
The fix involves changes to the traffic state machine in the
vusb_hs_dma_traf block. The ehci_ctrl state machine updates the context
information by encoding the transaction results on the
hst_op_context_update signals at the end of a transaction. The signal
hst_op_context_update is added to the traffic state machine, and the
tx_fifo_under_ran_r signal is generated if the transaction results in
an under run error. Click for waveform

The traffic state machine then traverses to the do_eop states if the
tx_fifo_under_ran error is asserted. Thus an EOP tag is written in to
the TxFIFO as shown in this waveform .

The EOP tag resets the align state machine to the Idle state ensuring
that the next command written by the echi_ctrl state machine does not
get corrupted.

File(s) modified:
RTL code fixed: ?..
Method of reproducing: This failure cannot be reproduced in the current
test bench.
Date Found: March 2010
Date Fixed: June 2010
Update information:
Added the RTL code fix

Signed-off-by: Peter Chen <peter.chen at freescale.com>
---
 drivers/usb/chipidea/core.c  | 13 ++++++++++++-
 include/linux/usb/chipidea.h |  5 ++++-
 2 files changed, 16 insertions(+), 2 deletions(-)

diff --git a/drivers/usb/chipidea/core.c b/drivers/usb/chipidea/core.c
index 9cbb846..38bd036 100644
--- a/drivers/usb/chipidea/core.c
+++ b/drivers/usb/chipidea/core.c
@@ -64,6 +64,7 @@
 #include <linux/of.h>
 #include <linux/phy.h>
 #include <linux/regulator/consumer.h>
+#include <linux/usb/ehci_def.h>
 
 #include "ci.h"
 #include "udc.h"
@@ -413,7 +414,17 @@ static int ci_usb_phy_init(struct ci_hdrc *ci)
  */
 void ci_platform_configure(struct ci_hdrc *ci)
 {
-	if (ci->platdata->flags & CI_HDRC_DISABLE_STREAMING)
+	bool is_device_mode, is_host_mode;
+
+	is_device_mode = hw_read(ci, OP_USBMODE, USBMODE_CM) == USBMODE_CM_DC;
+	is_host_mode = hw_read(ci, OP_USBMODE, USBMODE_CM) == USBMODE_CM_HC;
+
+	if (is_device_mode &&
+		(ci->platdata->flags & CI_HDRC_DISABLE_DEVICE_STREAMING))
+		hw_write(ci, OP_USBMODE, USBMODE_CI_SDIS, USBMODE_CI_SDIS);
+
+	if (is_host_mode &&
+		(ci->platdata->flags & CI_HDRC_DISABLE_HOST_STREAMING))
 		hw_write(ci, OP_USBMODE, USBMODE_CI_SDIS, USBMODE_CI_SDIS);
 
 	if (ci->platdata->flags & CI_HDRC_FORCE_FULLSPEED) {
diff --git a/include/linux/usb/chipidea.h b/include/linux/usb/chipidea.h
index aa49177..034f7e1 100644
--- a/include/linux/usb/chipidea.h
+++ b/include/linux/usb/chipidea.h
@@ -19,8 +19,11 @@ struct ci_hdrc_platform_data {
 	enum usb_phy_interface phy_mode;
 	unsigned long	 flags;
 #define CI_HDRC_REGS_SHARED		BIT(0)
+#define CI_HDRC_DISABLE_DEVICE_STREAMING	BIT(1)
 #define CI_HDRC_SUPPORTS_RUNTIME_PM	BIT(2)
-#define CI_HDRC_DISABLE_STREAMING	BIT(3)
+#define CI_HDRC_DISABLE_HOST_STREAMING	BIT(3)
+#define CI_HDRC_DISABLE_STREAMING (CI_HDRC_DISABLE_DEVICE_STREAMING |	\
+		CI_HDRC_DISABLE_HOST_STREAMING)
 	/*
 	 * Only set it when DCCPARAMS.DC==1 and DCCPARAMS.HC==1,
 	 * but otg is not supported (no register otgsc).
-- 
1.9.1



From peter.chen at freescale.com  Sun Aug  2 21:47:11 2015
From: peter.chen at freescale.com (Peter Chen)
Date: Mon, 3 Aug 2015 12:47:11 +0800
Subject: [PATCH v2 03/10] usb: chipidea: imx: add stream mode enable for
 device mode at imx6sl/imx6sx
In-Reply-To: <1438577238-10153-1-git-send-email-peter.chen@freescale.com>
References: <1438577238-10153-1-git-send-email-peter.chen@freescale.com>
Message-ID: <1438577238-10153-4-git-send-email-peter.chen@freescale.com>

Stream mode enable is known for better performance, this stream mode
enable patch has been passed with stress tests at device mode for
imx6sl and imx6sx, and no issue is found.

Signed-off-by: Peter Chen <peter.chen at freescale.com>
---
 drivers/usb/chipidea/ci_hdrc_imx.c | 16 ++++++++++------
 1 file changed, 10 insertions(+), 6 deletions(-)

diff --git a/drivers/usb/chipidea/ci_hdrc_imx.c b/drivers/usb/chipidea/ci_hdrc_imx.c
index 6d2a85a..3f41679 100644
--- a/drivers/usb/chipidea/ci_hdrc_imx.c
+++ b/drivers/usb/chipidea/ci_hdrc_imx.c
@@ -29,26 +29,31 @@ struct ci_hdrc_imx_platform_flag {
 };
 
 static const struct ci_hdrc_imx_platform_flag imx27_usb_data = {
+		CI_HDRC_DISABLE_STREAMING,
 };
 
 static const struct ci_hdrc_imx_platform_flag imx28_usb_data = {
 	.flags = CI_HDRC_IMX28_WRITE_FIX |
-		CI_HDRC_TURN_VBUS_EARLY_ON,
+		CI_HDRC_TURN_VBUS_EARLY_ON |
+		CI_HDRC_DISABLE_STREAMING,
 };
 
 static const struct ci_hdrc_imx_platform_flag imx6q_usb_data = {
 	.flags = CI_HDRC_SUPPORTS_RUNTIME_PM |
-		CI_HDRC_TURN_VBUS_EARLY_ON,
+		CI_HDRC_TURN_VBUS_EARLY_ON |
+		CI_HDRC_DISABLE_STREAMING,
 };
 
 static const struct ci_hdrc_imx_platform_flag imx6sl_usb_data = {
 	.flags = CI_HDRC_SUPPORTS_RUNTIME_PM |
-		CI_HDRC_TURN_VBUS_EARLY_ON,
+		CI_HDRC_TURN_VBUS_EARLY_ON |
+		CI_HDRC_DISABLE_HOST_STREAMING,
 };
 
 static const struct ci_hdrc_imx_platform_flag imx6sx_usb_data = {
 	.flags = CI_HDRC_SUPPORTS_RUNTIME_PM |
-		CI_HDRC_TURN_VBUS_EARLY_ON,
+		CI_HDRC_TURN_VBUS_EARLY_ON |
+		CI_HDRC_DISABLE_HOST_STREAMING,
 };
 
 static const struct of_device_id ci_hdrc_imx_dt_ids[] = {
@@ -126,8 +131,7 @@ static int ci_hdrc_imx_probe(struct platform_device *pdev)
 	struct ci_hdrc_platform_data pdata = {
 		.name		= dev_name(&pdev->dev),
 		.capoffset	= DEF_CAPOFFSET,
-		.flags		= CI_HDRC_DISABLE_STREAMING |
-					CI_HDRC_SET_NON_ZERO_TTHA,
+		.flags		= CI_HDRC_SET_NON_ZERO_TTHA,
 	};
 	int ret;
 	const struct of_device_id *of_id =
-- 
1.9.1



From peter.chen at freescale.com  Sun Aug  2 21:47:12 2015
From: peter.chen at freescale.com (Peter Chen)
Date: Mon, 3 Aug 2015 12:47:12 +0800
Subject: [PATCH v2 04/10] Doc: usb: ci-hdrc-usb2: add ahb-burst-config for
 binding doc
In-Reply-To: <1438577238-10153-1-git-send-email-peter.chen@freescale.com>
References: <1438577238-10153-1-git-send-email-peter.chen@freescale.com>
Message-ID: <1438577238-10153-5-git-send-email-peter.chen@freescale.com>

It is used to change ahb burst configuration for platforms, it is
vendor specific.

Signed-off-by: Peter Chen <peter.chen at freescale.com>
---
 Documentation/devicetree/bindings/usb/ci-hdrc-usb2.txt | 4 ++++
 1 file changed, 4 insertions(+)

diff --git a/Documentation/devicetree/bindings/usb/ci-hdrc-usb2.txt b/Documentation/devicetree/bindings/usb/ci-hdrc-usb2.txt
index 4159c8c..3c377a3 100644
--- a/Documentation/devicetree/bindings/usb/ci-hdrc-usb2.txt
+++ b/Documentation/devicetree/bindings/usb/ci-hdrc-usb2.txt
@@ -32,6 +32,8 @@ Optional properties:
 - external-vbus-divider: (FSL only) enables off-chip resistor divider for Vbus
 - itc-setting: interrupt threshold control register control, the setting
   should be aligned with ITC bits at register USBCMD.
+- ahb-burst-config: it is vendor dependent, the required value should be
+  aligned with AHBBRST at SBUSCFG, the range is from 0x0 to 0x7.
 
 Example:
 
@@ -44,4 +46,6 @@ Example:
 		phy-names = "usb-phy";
 		vbus-supply = <&reg_usb0_vbus>;
 		gadget-itc-setting = <0x4>; /* 4 micro-frames */
+		 /* Incremental burst of unspecified length */
+		ahb-burst-config = <0x0>;
 	};
-- 
1.9.1



From peter.chen at freescale.com  Sun Aug  2 21:47:13 2015
From: peter.chen at freescale.com (Peter Chen)
Date: Mon, 3 Aug 2015 12:47:13 +0800
Subject: [PATCH v2 05/10] ARM: imx6: set ahb-burst-config as 0 for USB
In-Reply-To: <1438577238-10153-1-git-send-email-peter.chen@freescale.com>
References: <1438577238-10153-1-git-send-email-peter.chen@freescale.com>
Message-ID: <1438577238-10153-6-git-send-email-peter.chen@freescale.com>

After setting ahb burst configuration as 0, we can increase tx/rx
burst size, it will improve the USB performance

Signed-off-by: Peter Chen <peter.chen at freescale.com>
---
 arch/arm/boot/dts/imx6qdl.dtsi | 4 ++++
 arch/arm/boot/dts/imx6sl.dtsi  | 3 +++
 arch/arm/boot/dts/imx6sx.dtsi  | 3 +++
 3 files changed, 10 insertions(+)

diff --git a/arch/arm/boot/dts/imx6qdl.dtsi b/arch/arm/boot/dts/imx6qdl.dtsi
index e6d1359..42d62b0 100644
--- a/arch/arm/boot/dts/imx6qdl.dtsi
+++ b/arch/arm/boot/dts/imx6qdl.dtsi
@@ -853,6 +853,7 @@
 				clocks = <&clks IMX6QDL_CLK_USBOH3>;
 				fsl,usbphy = <&usbphy1>;
 				fsl,usbmisc = <&usbmisc 0>;
+				ahb-burst-config = <0x0>;
 				status = "disabled";
 			};
 
@@ -864,6 +865,7 @@
 				fsl,usbphy = <&usbphy2>;
 				fsl,usbmisc = <&usbmisc 1>;
 				dr_mode = "host";
+				ahb-burst-config = <0x0>;
 				status = "disabled";
 			};
 
@@ -874,6 +876,7 @@
 				clocks = <&clks IMX6QDL_CLK_USBOH3>;
 				fsl,usbmisc = <&usbmisc 2>;
 				dr_mode = "host";
+				ahb-burst-config = <0x0>;
 				status = "disabled";
 			};
 
@@ -884,6 +887,7 @@
 				clocks = <&clks IMX6QDL_CLK_USBOH3>;
 				fsl,usbmisc = <&usbmisc 3>;
 				dr_mode = "host";
+				ahb-burst-config = <0x0>;
 				status = "disabled";
 			};
 
diff --git a/arch/arm/boot/dts/imx6sl.dtsi b/arch/arm/boot/dts/imx6sl.dtsi
index a78e715..066fac9 100644
--- a/arch/arm/boot/dts/imx6sl.dtsi
+++ b/arch/arm/boot/dts/imx6sl.dtsi
@@ -688,6 +688,7 @@
 				clocks = <&clks IMX6SL_CLK_USBOH3>;
 				fsl,usbphy = <&usbphy1>;
 				fsl,usbmisc = <&usbmisc 0>;
+				ahb-burst-config = <0x0>;
 				status = "disabled";
 			};
 
@@ -698,6 +699,7 @@
 				clocks = <&clks IMX6SL_CLK_USBOH3>;
 				fsl,usbphy = <&usbphy2>;
 				fsl,usbmisc = <&usbmisc 1>;
+				ahb-burst-config = <0x0>;
 				status = "disabled";
 			};
 
@@ -708,6 +710,7 @@
 				clocks = <&clks IMX6SL_CLK_USBOH3>;
 				fsl,usbmisc = <&usbmisc 2>;
 				dr_mode = "host";
+				ahb-burst-config = <0x0>;
 				status = "disabled";
 			};
 
diff --git a/arch/arm/boot/dts/imx6sx.dtsi b/arch/arm/boot/dts/imx6sx.dtsi
index 708175d..3656a1d 100644
--- a/arch/arm/boot/dts/imx6sx.dtsi
+++ b/arch/arm/boot/dts/imx6sx.dtsi
@@ -746,6 +746,7 @@
 				fsl,usbphy = <&usbphy1>;
 				fsl,usbmisc = <&usbmisc 0>;
 				fsl,anatop = <&anatop>;
+				ahb-burst-config = <0x0>;
 				status = "disabled";
 			};
 
@@ -756,6 +757,7 @@
 				clocks = <&clks IMX6SX_CLK_USBOH3>;
 				fsl,usbphy = <&usbphy2>;
 				fsl,usbmisc = <&usbmisc 1>;
+				ahb-burst-config = <0x0>;
 				status = "disabled";
 			};
 
@@ -768,6 +770,7 @@
 				phy_type = "hsic";
 				fsl,anatop = <&anatop>;
 				dr_mode = "host";
+				ahb-burst-config = <0x0>;
 				status = "disabled";
 			};
 
-- 
1.9.1



From peter.chen at freescale.com  Sun Aug  2 21:47:14 2015
From: peter.chen at freescale.com (Peter Chen)
Date: Mon, 3 Aug 2015 12:47:14 +0800
Subject: [PATCH v2 06/10] usb: chipidea: add ahb burst configuration interface
In-Reply-To: <1438577238-10153-1-git-send-email-peter.chen@freescale.com>
References: <1438577238-10153-1-git-send-email-peter.chen@freescale.com>
Message-ID: <1438577238-10153-7-git-send-email-peter.chen@freescale.com>

The users can change it through dts or platform data if they
want to change the default value.

Signed-off-by: Peter Chen <peter.chen at freescale.com>
---
 drivers/usb/chipidea/bits.h  |  3 +++
 drivers/usb/chipidea/core.c  | 14 ++++++++++++++
 include/linux/usb/chipidea.h |  2 ++
 3 files changed, 19 insertions(+)

diff --git a/drivers/usb/chipidea/bits.h b/drivers/usb/chipidea/bits.h
index 831a8f6..462ad02 100644
--- a/drivers/usb/chipidea/bits.h
+++ b/drivers/usb/chipidea/bits.h
@@ -25,6 +25,9 @@
 #define VERSION		      (0xF << 25)
 #define CIVERSION	      (0x7 << 29)
 
+/* SBUSCFG */
+#define AHBBRST_MASK		0x7
+
 /* HCCPARAMS */
 #define HCCPARAMS_LEN         BIT(17)
 
diff --git a/drivers/usb/chipidea/core.c b/drivers/usb/chipidea/core.c
index 38bd036..f60cbf6 100644
--- a/drivers/usb/chipidea/core.c
+++ b/drivers/usb/chipidea/core.c
@@ -439,6 +439,9 @@ void ci_platform_configure(struct ci_hdrc *ci)
 
 	hw_write(ci, OP_USBCMD, 0xff0000, ci->platdata->itc_setting << 16);
 
+	if (ci->platdata->flags & CI_HDRC_OVERRIDE_AHB_BURST)
+		hw_write_id_reg(ci, ID_SBUSCFG, AHBBRST_MASK,
+			ci->platdata->ahb_burst_config);
 }
 
 /**
@@ -647,6 +650,17 @@ static int ci_get_platdata(struct device *dev,
 		}
 	}
 
+	if (of_find_property(dev->of_node, "ahb-burst-config", NULL)) {
+		ret = of_property_read_u32(dev->of_node, "ahb-burst-config",
+			&platdata->ahb_burst_config);
+		if (ret) {
+			dev_err(dev,
+				"failed to get ahb-burst-config\n");
+			return ret;
+		}
+		platdata->flags |= CI_HDRC_OVERRIDE_AHB_BURST;
+	}
+
 	return 0;
 }
 
diff --git a/include/linux/usb/chipidea.h b/include/linux/usb/chipidea.h
index 034f7e1..fe3c8eb 100644
--- a/include/linux/usb/chipidea.h
+++ b/include/linux/usb/chipidea.h
@@ -33,6 +33,7 @@ struct ci_hdrc_platform_data {
 #define CI_HDRC_FORCE_FULLSPEED		BIT(6)
 #define CI_HDRC_TURN_VBUS_EARLY_ON	BIT(7)
 #define CI_HDRC_SET_NON_ZERO_TTHA	BIT(8)
+#define CI_HDRC_OVERRIDE_AHB_BURST	BIT(9)
 	enum usb_dr_mode	dr_mode;
 #define CI_HDRC_CONTROLLER_RESET_EVENT		0
 #define CI_HDRC_CONTROLLER_STOPPED_EVENT	1
@@ -42,6 +43,7 @@ struct ci_hdrc_platform_data {
 	bool			tpl_support;
 	/* interrupt threshold setting */
 	u32			itc_setting;
+	u32			ahb_burst_config;
 };
 
 /* Default offset of capability registers */
-- 
1.9.1



From peter.chen at freescale.com  Sun Aug  2 21:47:15 2015
From: peter.chen at freescale.com (Peter Chen)
Date: Mon, 3 Aug 2015 12:47:15 +0800
Subject: [PATCH v2 07/10] usb: chipidea: usbmisc_imx: add non-burst setting
 for imx6
In-Reply-To: <1438577238-10153-1-git-send-email-peter.chen@freescale.com>
References: <1438577238-10153-1-git-send-email-peter.chen@freescale.com>
Message-ID: <1438577238-10153-8-git-send-email-peter.chen@freescale.com>

With this setting and AHBBRST at SBUSCFG as "Incremental burst of
unspecified length", each non-burst size can be taken as single
transfer. It is benefit for non-burst size transfer.

Signed-off-by: Peter Chen <peter.chen at freescale.com>
---
 drivers/usb/chipidea/usbmisc_imx.c | 12 ++++++++++--
 1 file changed, 10 insertions(+), 2 deletions(-)

diff --git a/drivers/usb/chipidea/usbmisc_imx.c b/drivers/usb/chipidea/usbmisc_imx.c
index 3cefd49..5ddab30 100644
--- a/drivers/usb/chipidea/usbmisc_imx.c
+++ b/drivers/usb/chipidea/usbmisc_imx.c
@@ -54,6 +54,7 @@
 #define MX53_USB_PHYCTRL1_PLLDIV_MASK	0x3
 #define MX53_USB_PLL_DIV_24_MHZ		0x01
 
+#define MX6_BM_NON_BURST_SETTING	BIT(1)
 #define MX6_BM_OVER_CUR_DIS		BIT(7)
 #define MX6_BM_WAKEUP_ENABLE		BIT(10)
 #define MX6_BM_ID_WAKEUP		BIT(16)
@@ -255,14 +256,21 @@ static int usbmisc_imx6q_init(struct imx_usbmisc_data *data)
 	if (data->index > 3)
 		return -EINVAL;
 
+	spin_lock_irqsave(&usbmisc->lock, flags);
+
 	if (data->disable_oc) {
-		spin_lock_irqsave(&usbmisc->lock, flags);
 		reg = readl(usbmisc->base + data->index * 4);
 		writel(reg | MX6_BM_OVER_CUR_DIS,
 			usbmisc->base + data->index * 4);
-		spin_unlock_irqrestore(&usbmisc->lock, flags);
 	}
 
+	/* SoC non-burst setting */
+	reg = readl(usbmisc->base + data->index * 4);
+	writel(reg | MX6_BM_NON_BURST_SETTING,
+			usbmisc->base + data->index * 4);
+
+	spin_unlock_irqrestore(&usbmisc->lock, flags);
+
 	usbmisc_imx6q_set_wakeup(data, false);
 
 	return 0;
-- 
1.9.1



From peter.chen at freescale.com  Sun Aug  2 21:47:16 2015
From: peter.chen at freescale.com (Peter Chen)
Date: Mon, 3 Aug 2015 12:47:16 +0800
Subject: [PATCH v2 08/10] Doc: usb: ci-hdrc-usb2: add
 tx(rx)-burst-config-dword for binding doc
In-Reply-To: <1438577238-10153-1-git-send-email-peter.chen@freescale.com>
References: <1438577238-10153-1-git-send-email-peter.chen@freescale.com>
Message-ID: <1438577238-10153-9-git-send-email-peter.chen@freescale.com>

It is used to override the default setting for burst size, changing
burst size takes effect only when the SBUSCFG.AHBBRST = 0.

Signed-off-by: Peter Chen <peter.chen at freescale.com>
---
 Documentation/devicetree/bindings/usb/ci-hdrc-usb2.txt | 6 ++++++
 1 file changed, 6 insertions(+)

diff --git a/Documentation/devicetree/bindings/usb/ci-hdrc-usb2.txt b/Documentation/devicetree/bindings/usb/ci-hdrc-usb2.txt
index 3c377a3..0f0929c 100644
--- a/Documentation/devicetree/bindings/usb/ci-hdrc-usb2.txt
+++ b/Documentation/devicetree/bindings/usb/ci-hdrc-usb2.txt
@@ -34,6 +34,10 @@ Optional properties:
   should be aligned with ITC bits at register USBCMD.
 - ahb-burst-config: it is vendor dependent, the required value should be
   aligned with AHBBRST at SBUSCFG, the range is from 0x0 to 0x7.
+- tx-burst-size-dword: it is vendor dependent, the tx burst size in dword
+  (4 bytes).
+- rx-burst-size-dword: it is vendor dependent, the rx burst size in dword
+  (4 bytes).
 
 Example:
 
@@ -48,4 +52,6 @@ Example:
 		gadget-itc-setting = <0x4>; /* 4 micro-frames */
 		 /* Incremental burst of unspecified length */
 		ahb-burst-config = <0x0>;
+		tx-burst-size-dword = <0x10>; /* 64 bytes */
+		rx-burst-size-dword = <0x10>;
 	};
-- 
1.9.1



From peter.chen at freescale.com  Sun Aug  2 21:47:17 2015
From: peter.chen at freescale.com (Peter Chen)
Date: Mon, 3 Aug 2015 12:47:17 +0800
Subject: [PATCH v2 09/10] ARM: imx6: change default burst size for USB
In-Reply-To: <1438577238-10153-1-git-send-email-peter.chen@freescale.com>
References: <1438577238-10153-1-git-send-email-peter.chen@freescale.com>
Message-ID: <1438577238-10153-10-git-send-email-peter.chen@freescale.com>

It can improve the USB performance when choosing larger
burst size at some systems (bus size is larger), there is
no side effect if this burst size is larger than bus size.

Signed-off-by: Peter Chen <peter.chen at freescale.com>
---
 arch/arm/boot/dts/imx6qdl.dtsi | 8 ++++++++
 arch/arm/boot/dts/imx6sl.dtsi  | 6 ++++++
 arch/arm/boot/dts/imx6sx.dtsi  | 6 ++++++
 3 files changed, 20 insertions(+)

diff --git a/arch/arm/boot/dts/imx6qdl.dtsi b/arch/arm/boot/dts/imx6qdl.dtsi
index 42d62b0..b9f2e3a 100644
--- a/arch/arm/boot/dts/imx6qdl.dtsi
+++ b/arch/arm/boot/dts/imx6qdl.dtsi
@@ -854,6 +854,8 @@
 				fsl,usbphy = <&usbphy1>;
 				fsl,usbmisc = <&usbmisc 0>;
 				ahb-burst-config = <0x0>;
+				tx-burst-size-dword = <0x10>;
+				rx-burst-size-dword = <0x10>;
 				status = "disabled";
 			};
 
@@ -866,6 +868,8 @@
 				fsl,usbmisc = <&usbmisc 1>;
 				dr_mode = "host";
 				ahb-burst-config = <0x0>;
+				tx-burst-size-dword = <0x10>;
+				rx-burst-size-dword = <0x10>;
 				status = "disabled";
 			};
 
@@ -877,6 +881,8 @@
 				fsl,usbmisc = <&usbmisc 2>;
 				dr_mode = "host";
 				ahb-burst-config = <0x0>;
+				tx-burst-size-dword = <0x10>;
+				rx-burst-size-dword = <0x10>;
 				status = "disabled";
 			};
 
@@ -888,6 +894,8 @@
 				fsl,usbmisc = <&usbmisc 3>;
 				dr_mode = "host";
 				ahb-burst-config = <0x0>;
+				tx-burst-size-dword = <0x10>;
+				rx-burst-size-dword = <0x10>;
 				status = "disabled";
 			};
 
diff --git a/arch/arm/boot/dts/imx6sl.dtsi b/arch/arm/boot/dts/imx6sl.dtsi
index 066fac9..627549f 100644
--- a/arch/arm/boot/dts/imx6sl.dtsi
+++ b/arch/arm/boot/dts/imx6sl.dtsi
@@ -689,6 +689,8 @@
 				fsl,usbphy = <&usbphy1>;
 				fsl,usbmisc = <&usbmisc 0>;
 				ahb-burst-config = <0x0>;
+				tx-burst-size-dword = <0x10>;
+				rx-burst-size-dword = <0x10>;
 				status = "disabled";
 			};
 
@@ -700,6 +702,8 @@
 				fsl,usbphy = <&usbphy2>;
 				fsl,usbmisc = <&usbmisc 1>;
 				ahb-burst-config = <0x0>;
+				tx-burst-size-dword = <0x10>;
+				rx-burst-size-dword = <0x10>;
 				status = "disabled";
 			};
 
@@ -711,6 +715,8 @@
 				fsl,usbmisc = <&usbmisc 2>;
 				dr_mode = "host";
 				ahb-burst-config = <0x0>;
+				tx-burst-size-dword = <0x10>;
+				rx-burst-size-dword = <0x10>;
 				status = "disabled";
 			};
 
diff --git a/arch/arm/boot/dts/imx6sx.dtsi b/arch/arm/boot/dts/imx6sx.dtsi
index 3656a1d..6844e9e 100644
--- a/arch/arm/boot/dts/imx6sx.dtsi
+++ b/arch/arm/boot/dts/imx6sx.dtsi
@@ -747,6 +747,8 @@
 				fsl,usbmisc = <&usbmisc 0>;
 				fsl,anatop = <&anatop>;
 				ahb-burst-config = <0x0>;
+				tx-burst-size-dword = <0x10>;
+				rx-burst-size-dword = <0x10>;
 				status = "disabled";
 			};
 
@@ -758,6 +760,8 @@
 				fsl,usbphy = <&usbphy2>;
 				fsl,usbmisc = <&usbmisc 1>;
 				ahb-burst-config = <0x0>;
+				tx-burst-size-dword = <0x10>;
+				rx-burst-size-dword = <0x10>;
 				status = "disabled";
 			};
 
@@ -771,6 +775,8 @@
 				fsl,anatop = <&anatop>;
 				dr_mode = "host";
 				ahb-burst-config = <0x0>;
+				tx-burst-size-dword = <0x10>;
+				rx-burst-size-dword = <0x10>;
 				status = "disabled";
 			};
 
-- 
1.9.1



From peter.chen at freescale.com  Sun Aug  2 21:47:18 2015
From: peter.chen at freescale.com (Peter Chen)
Date: Mon, 3 Aug 2015 12:47:18 +0800
Subject: [PATCH v2 10/10] usb: chipidea: add tx/rx burst size configuration
 interface
In-Reply-To: <1438577238-10153-1-git-send-email-peter.chen@freescale.com>
References: <1438577238-10153-1-git-send-email-peter.chen@freescale.com>
Message-ID: <1438577238-10153-11-git-send-email-peter.chen@freescale.com>

The user can adjust it through dts or platform data

Signed-off-by: Peter Chen <peter.chen at freescale.com>
---
 drivers/usb/chipidea/bits.h  |  4 ++++
 drivers/usb/chipidea/ci.h    |  1 +
 drivers/usb/chipidea/core.c  | 35 +++++++++++++++++++++++++++++++++++
 include/linux/usb/chipidea.h |  4 ++++
 4 files changed, 44 insertions(+)

diff --git a/drivers/usb/chipidea/bits.h b/drivers/usb/chipidea/bits.h
index 462ad02..e462f55 100644
--- a/drivers/usb/chipidea/bits.h
+++ b/drivers/usb/chipidea/bits.h
@@ -61,6 +61,10 @@
 /* Set non-zero value for internal TT Hub address representation */
 #define TTCTRL_TTHA		(0x7fUL << 24)
 
+/* BURSTSIZE */
+#define RX_BURST_MASK		0xff
+#define TX_BURST_MASK		0xff00
+
 /* PORTSC */
 #define PORTSC_CCS            BIT(0)
 #define PORTSC_CSC            BIT(1)
diff --git a/drivers/usb/chipidea/ci.h b/drivers/usb/chipidea/ci.h
index b562544..41d7cf6 100644
--- a/drivers/usb/chipidea/ci.h
+++ b/drivers/usb/chipidea/ci.h
@@ -51,6 +51,7 @@ enum ci_hw_regs {
 	OP_DEVICEADDR,
 	OP_ENDPTLISTADDR,
 	OP_TTCTRL,
+	OP_BURSTSIZE,
 	OP_PORTSC,
 	OP_DEVLC,
 	OP_OTGSC,
diff --git a/drivers/usb/chipidea/core.c b/drivers/usb/chipidea/core.c
index f60cbf6..0375412 100644
--- a/drivers/usb/chipidea/core.c
+++ b/drivers/usb/chipidea/core.c
@@ -86,6 +86,7 @@ static const u8 ci_regs_nolpm[] = {
 	[OP_DEVICEADDR]		= 0x14U,
 	[OP_ENDPTLISTADDR]	= 0x18U,
 	[OP_TTCTRL]		= 0x1CU,
+	[OP_BURSTSIZE]		= 0x20U,
 	[OP_PORTSC]		= 0x44U,
 	[OP_DEVLC]		= 0x84U,
 	[OP_OTGSC]		= 0x64U,
@@ -109,6 +110,7 @@ static const u8 ci_regs_lpm[] = {
 	[OP_DEVICEADDR]		= 0x14U,
 	[OP_ENDPTLISTADDR]	= 0x18U,
 	[OP_TTCTRL]		= 0x1CU,
+	[OP_BURSTSIZE]		= 0x20U,
 	[OP_PORTSC]		= 0x44U,
 	[OP_DEVLC]		= 0x84U,
 	[OP_OTGSC]		= 0xC4U,
@@ -442,6 +444,17 @@ void ci_platform_configure(struct ci_hdrc *ci)
 	if (ci->platdata->flags & CI_HDRC_OVERRIDE_AHB_BURST)
 		hw_write_id_reg(ci, ID_SBUSCFG, AHBBRST_MASK,
 			ci->platdata->ahb_burst_config);
+
+	/* override burst size, take effect only when ahb_burst_config is 0 */
+	if (!hw_read_id_reg(ci, ID_SBUSCFG, AHBBRST_MASK)) {
+		if (ci->platdata->flags & CI_HDRC_OVERRIDE_TX_BURST)
+			hw_write(ci, OP_BURSTSIZE, TX_BURST_MASK,
+			ci->platdata->tx_burst_size << __ffs(TX_BURST_MASK));
+
+		if (ci->platdata->flags & CI_HDRC_OVERRIDE_RX_BURST)
+			hw_write(ci, OP_BURSTSIZE, RX_BURST_MASK,
+				ci->platdata->rx_burst_size);
+	}
 }
 
 /**
@@ -661,6 +674,28 @@ static int ci_get_platdata(struct device *dev,
 		platdata->flags |= CI_HDRC_OVERRIDE_AHB_BURST;
 	}
 
+	if (of_find_property(dev->of_node, "tx-burst-size-dword", NULL)) {
+		ret = of_property_read_u32(dev->of_node, "tx-burst-size-dword",
+			&platdata->tx_burst_size);
+		if (ret) {
+			dev_err(dev,
+				"failed to get tx-burst-size-dword\n");
+			return ret;
+		}
+		platdata->flags |= CI_HDRC_OVERRIDE_TX_BURST;
+	}
+
+	if (of_find_property(dev->of_node, "rx-burst-size-dword", NULL)) {
+		ret = of_property_read_u32(dev->of_node, "rx-burst-size-dword",
+			&platdata->rx_burst_size);
+		if (ret) {
+			dev_err(dev,
+				"failed to get rx-burst-size-dword\n");
+			return ret;
+		}
+		platdata->flags |= CI_HDRC_OVERRIDE_RX_BURST;
+	}
+
 	return 0;
 }
 
diff --git a/include/linux/usb/chipidea.h b/include/linux/usb/chipidea.h
index fe3c8eb..a41833c 100644
--- a/include/linux/usb/chipidea.h
+++ b/include/linux/usb/chipidea.h
@@ -34,6 +34,8 @@ struct ci_hdrc_platform_data {
 #define CI_HDRC_TURN_VBUS_EARLY_ON	BIT(7)
 #define CI_HDRC_SET_NON_ZERO_TTHA	BIT(8)
 #define CI_HDRC_OVERRIDE_AHB_BURST	BIT(9)
+#define CI_HDRC_OVERRIDE_TX_BURST	BIT(10)
+#define CI_HDRC_OVERRIDE_RX_BURST	BIT(11)
 	enum usb_dr_mode	dr_mode;
 #define CI_HDRC_CONTROLLER_RESET_EVENT		0
 #define CI_HDRC_CONTROLLER_STOPPED_EVENT	1
@@ -44,6 +46,8 @@ struct ci_hdrc_platform_data {
 	/* interrupt threshold setting */
 	u32			itc_setting;
 	u32			ahb_burst_config;
+	u32			tx_burst_size;
+	u32			rx_burst_size;
 };
 
 /* Default offset of capability registers */
-- 
1.9.1



From ralf at linux-mips.org  Sun Aug  2 23:02:17 2015
From: ralf at linux-mips.org (Ralf Baechle)
Date: Mon, 3 Aug 2015 08:02:17 +0200
Subject: [PATCH v2] arch: use WRITE_ONCE/READ_ONCE in
 smp_store_release/smp_load_acquire
In-Reply-To: <1438528264-714-1-git-send-email-andreyknvl@google.com>
References: <1438528264-714-1-git-send-email-andreyknvl@google.com>
Message-ID: <20150803060217.GB16650@linux-mips.org>

On Sun, Aug 02, 2015 at 05:11:04PM +0200, Andrey Konovalov wrote:

> diff --git a/arch/mips/include/asm/barrier.h b/arch/mips/include/asm/barrier.h
> index 7ecba84..752e0b8 100644
> --- a/arch/mips/include/asm/barrier.h
> +++ b/arch/mips/include/asm/barrier.h
> @@ -133,12 +133,12 @@
>  do {									\
>  	compiletime_assert_atomic_type(*p);				\
>  	smp_mb();							\
> -	ACCESS_ONCE(*p) = (v);						\
> +	WRITE_ONCE(*p, v);						\
>  } while (0)
>  
>  #define smp_load_acquire(p)						\
>  ({									\
> -	typeof(*p) ___p1 = ACCESS_ONCE(*p);				\
> +	typeof(*p) ___p1 = READ_ONCE(*p);				\
>  	compiletime_assert_atomic_type(*p);				\
>  	smp_mb();							\
>  	___p1;								\

Acked-by: Ralf Baechle <ralf at linux-mips.org>

  Ralf


From horms+renesas at verge.net.au  Sun Aug  2 23:04:55 2015
From: horms+renesas at verge.net.au (Simon Horman)
Date: Mon,  3 Aug 2015 15:04:55 +0900
Subject: [GIT PULL v2] Renesas ARM Based SoC Marzen Board Removal for v4.3
Message-ID: <cover.1438581659.git.horms+renesas@verge.net.au>

Hi Olof, Hi Kevin, Hi Arnd,

Please consider these Renesas ARM based SoC marzen board removal for v4.3.


This series removes legacy r8a7779 SoC and marzen board code.
It aims to do do so in a way that does not introduce feature regressions
when when booting the r8a7779/marzen board using shmobile_defconfig,
which provides for booting using multiplatform, a scenario which previously
used board code to provide some features including SMP.

Because of the above this series modifies SoC and DT files,
and then removes code. And because of that it was not entirely clear to
me which branch it should go into, so I have provided it in a stand-alone
branch.

Unfortunately this branch has a number of minor conflicts with the "Renesas
ARM Based SoC Cleanup for v4.3", tagged as renesas-cleanup-for-v4.3, which
you have previously pulled.

A resolution to those conflicts can be found in the
renesas-next-20150730-v4.2-rc1 tag of the renesas tree.

On a more positive note, I believe this to well over 8000 lines of legacy
code removed in this cycle :)


Changes between v1 and v2:

* As requested by Olof: Do not include defconfig updates;
  these will be handled separately


The following changes since commit d770e558e21961ad6cfdf0ff7df0eb5d7d4f0754:

  Linux 4.2-rc1 (2015-07-05 11:01:52 -0700)

are available in the git repository at:

  git://git.kernel.org/pub/scm/linux/kernel/git/horms/renesas.git tags/renesas-marzen-board-removal-for-v4.3

for you to fetch changes up to c99cd90d98a98aa101b169e44d249e5cd71f46f2:

  ARM: shmobile: r8a7779: Remove legacy SoC code (2015-07-28 09:27:16 +0900)

----------------------------------------------------------------
Renesas ARM Based SoC Marzen Board Removal for v4.3

* Remove legacy r8a7779 SoC code
* Remove legacy marzen board code

----------------------------------------------------------------
Magnus Damm (6):
      ARM: shmobile: r8a7779: Generic CCF and timer support
      ARM: shmobile: r8a7779: Generic SMP ops
      ARM: shmobile: marzen-reference: Remove C board code
      ARM: shmobile: r8a7779: Cleanup header file
      ARM: shmobile: marzen: Remove legacy board code
      ARM: shmobile: r8a7779: Remove legacy SoC code

 arch/arm/boot/dts/Makefile                      |   1 -
 arch/arm/mach-shmobile/Kconfig                  |  14 -
 arch/arm/mach-shmobile/Makefile                 |   6 +-
 arch/arm/mach-shmobile/Makefile.boot            |   1 -
 arch/arm/mach-shmobile/board-marzen-reference.c |  56 --
 arch/arm/mach-shmobile/board-marzen.c           | 347 ------------
 arch/arm/mach-shmobile/clock-r8a7779.c          | 271 ----------
 arch/arm/mach-shmobile/r8a7779.h                |  19 -
 arch/arm/mach-shmobile/setup-r8a7779.c          | 681 +-----------------------
 arch/arm/mach-shmobile/smp-r8a7779.c            |   9 -
 10 files changed, 15 insertions(+), 1390 deletions(-)
 delete mode 100644 arch/arm/mach-shmobile/board-marzen-reference.c
 delete mode 100644 arch/arm/mach-shmobile/board-marzen.c
 delete mode 100644 arch/arm/mach-shmobile/clock-r8a7779.c


From horms+renesas at verge.net.au  Sun Aug  2 23:04:52 2015
From: horms+renesas at verge.net.au (Simon Horman)
Date: Mon,  3 Aug 2015 15:04:52 +0900
Subject: [PATCH 1/6] ARM: shmobile: r8a7779: Generic CCF and timer support
In-Reply-To: <cover.1438581659.git.horms+renesas@verge.net.au>
References: <cover.1438581659.git.horms+renesas@verge.net.au>
Message-ID: <131c2e0480b0f7afefbc9a46cc4e158e17caa844.1438581659.git.horms+renesas@verge.net.au>

From: Magnus Damm <damm+renesas at opensource.se>

Add a r8a7779-specific callback to initialize CCF and
clocksources. With this in place we are one step closer
to be able to use r8a7779 without C board code.

Also add a multiplatform wrapper to avoid breaking the
r8a7779 marzen legacy case.

Signed-off-by: Magnus Damm <damm+renesas at opensource.se>
Acked-by: Geert Uytterhoeven <geert+renesas at glider.be>
Signed-off-by: Simon Horman <horms+renesas at verge.net.au>
---
 arch/arm/mach-shmobile/setup-r8a7779.c | 12 ++++++++++++
 1 file changed, 12 insertions(+)

diff --git a/arch/arm/mach-shmobile/setup-r8a7779.c b/arch/arm/mach-shmobile/setup-r8a7779.c
index c03e562be12b..5625fd1c89c0 100644
--- a/arch/arm/mach-shmobile/setup-r8a7779.c
+++ b/arch/arm/mach-shmobile/setup-r8a7779.c
@@ -14,6 +14,8 @@
  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
  * GNU General Public License for more details.
  */
+#include <linux/clk/shmobile.h>
+#include <linux/clocksource.h>
 #include <linux/kernel.h>
 #include <linux/init.h>
 #include <linux/interrupt.h>
@@ -756,6 +758,14 @@ u32 __init r8a7779_read_mode_pins(void)
 	return mode;
 }
 
+#ifdef CONFIG_ARCH_SHMOBILE_MULTI
+
+static void __init r8a7779_init_time(void)
+{
+	r8a7779_clocks_init(r8a7779_read_mode_pins());
+	clocksource_of_init();
+}
+
 static const char *r8a7779_compat_dt[] __initdata = {
 	"renesas,r8a7779",
 	NULL,
@@ -764,8 +774,10 @@ static const char *r8a7779_compat_dt[] __initdata = {
 DT_MACHINE_START(R8A7779_DT, "Generic R8A7779 (Flattened Device Tree)")
 	.map_io		= r8a7779_map_io,
 	.init_early	= shmobile_init_delay,
+	.init_time	= r8a7779_init_time,
 	.init_irq	= r8a7779_init_irq_dt,
 	.init_late	= shmobile_init_late,
 	.dt_compat	= r8a7779_compat_dt,
 MACHINE_END
+#endif /* CONFIG_ARCH_SHMOBILE_MULTI */
 #endif /* CONFIG_USE_OF */
-- 
2.1.4



From horms+renesas at verge.net.au  Sun Aug  2 23:04:53 2015
From: horms+renesas at verge.net.au (Simon Horman)
Date: Mon,  3 Aug 2015 15:04:53 +0900
Subject: [PATCH 2/6] ARM: shmobile: r8a7779: Generic SMP ops
In-Reply-To: <cover.1438581659.git.horms+renesas@verge.net.au>
References: <cover.1438581659.git.horms+renesas@verge.net.au>
Message-ID: <44ade5edf90ccd38efa741240efb2586239c9751.1438581659.git.horms+renesas@verge.net.au>

From: Magnus Damm <damm+renesas at opensource.se>

Add a r8a7779-specific SMP operation pointer to support
all 4 CPU cores through SMP on r8a7779 without C board code.

Signed-off-by: Magnus Damm <damm+renesas at opensource.se>
Acked-by: Geert Uytterhoeven <geert+renesas at glider.be>
Signed-off-by: Simon Horman <horms+renesas at verge.net.au>
---
 arch/arm/mach-shmobile/setup-r8a7779.c | 1 +
 1 file changed, 1 insertion(+)

diff --git a/arch/arm/mach-shmobile/setup-r8a7779.c b/arch/arm/mach-shmobile/setup-r8a7779.c
index 5625fd1c89c0..2c3e433f84ca 100644
--- a/arch/arm/mach-shmobile/setup-r8a7779.c
+++ b/arch/arm/mach-shmobile/setup-r8a7779.c
@@ -772,6 +772,7 @@ static const char *r8a7779_compat_dt[] __initdata = {
 };
 
 DT_MACHINE_START(R8A7779_DT, "Generic R8A7779 (Flattened Device Tree)")
+	.smp		= smp_ops(r8a7779_smp_ops),
 	.map_io		= r8a7779_map_io,
 	.init_early	= shmobile_init_delay,
 	.init_time	= r8a7779_init_time,
-- 
2.1.4



From horms+renesas at verge.net.au  Sun Aug  2 23:04:54 2015
From: horms+renesas at verge.net.au (Simon Horman)
Date: Mon,  3 Aug 2015 15:04:54 +0900
Subject: [PATCH 3/6] ARM: shmobile: marzen-reference: Remove C board code
In-Reply-To: <cover.1438581659.git.horms+renesas@verge.net.au>
References: <cover.1438581659.git.horms+renesas@verge.net.au>
Message-ID: <26f9e03fb1c8b8b5dd2f1ad34da775cc129df98a.1438581659.git.horms+renesas@verge.net.au>

From: Magnus Damm <damm+renesas at opensource.se>

The generic r8a7779 machine vector is now feature-wise equivalent
to the Marzen-reference case, so simply remove the Marzen C board
code to fall over on the generic r8a7779 machine vector.

Signed-off-by: Magnus Damm <damm+renesas at opensource.se>
Acked-by: Geert Uytterhoeven <geert+renesas at glider.be>
Signed-off-by: Simon Horman <horms+renesas at verge.net.au>
---
 arch/arm/mach-shmobile/Kconfig                  |  7 ----
 arch/arm/mach-shmobile/Makefile                 |  4 +-
 arch/arm/mach-shmobile/board-marzen-reference.c | 56 -------------------------
 3 files changed, 1 insertion(+), 66 deletions(-)
 delete mode 100644 arch/arm/mach-shmobile/board-marzen-reference.c

diff --git a/arch/arm/mach-shmobile/Kconfig b/arch/arm/mach-shmobile/Kconfig
index 45006479d461..3d6f46cb8b18 100644
--- a/arch/arm/mach-shmobile/Kconfig
+++ b/arch/arm/mach-shmobile/Kconfig
@@ -89,13 +89,6 @@ config ARCH_SH73A0
 	select ARCH_RMOBILE
 	select RENESAS_INTC_IRQPIN
 
-comment "Renesas ARM SoCs Board Type"
-
-config MACH_MARZEN
-	bool "MARZEN board"
-	depends on ARCH_R8A7779
-	select REGULATOR_FIXED_VOLTAGE if REGULATOR
-
 comment "Renesas ARM SoCs System Configuration"
 endif
 
diff --git a/arch/arm/mach-shmobile/Makefile b/arch/arm/mach-shmobile/Makefile
index 89e463de4479..08b12b4d3f90 100644
--- a/arch/arm/mach-shmobile/Makefile
+++ b/arch/arm/mach-shmobile/Makefile
@@ -51,9 +51,7 @@ obj-$(CONFIG_PM_RMOBILE)	+= pm-rmobile.o
 obj-$(CONFIG_ARCH_RCAR_GEN2)	+= pm-rcar-gen2.o
 
 # Board objects
-ifdef CONFIG_ARCH_SHMOBILE_MULTI
-obj-$(CONFIG_MACH_MARZEN)	+= board-marzen-reference.o
-else
+ifndef CONFIG_ARCH_SHMOBILE_MULTI
 obj-$(CONFIG_MACH_BOCKW)	+= board-bockw.o
 obj-$(CONFIG_MACH_BOCKW_REFERENCE)	+= board-bockw-reference.o
 obj-$(CONFIG_MACH_MARZEN)	+= board-marzen.o
diff --git a/arch/arm/mach-shmobile/board-marzen-reference.c b/arch/arm/mach-shmobile/board-marzen-reference.c
deleted file mode 100644
index b15eb923263f..000000000000
--- a/arch/arm/mach-shmobile/board-marzen-reference.c
+++ /dev/null
@@ -1,56 +0,0 @@
-/*
- * marzen board support - Reference DT implementation
- *
- * Copyright (C) 2011  Renesas Solutions Corp.
- * Copyright (C) 2011  Magnus Damm
- * Copyright (C) 2013  Simon Horman
- *
- * 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; version 2 of the License.
- *
- * 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/shmobile.h>
-#include <linux/clocksource.h>
-#include <linux/of_platform.h>
-
-#include <asm/irq.h>
-#include <asm/mach/arch.h>
-
-#include "common.h"
-#include "irqs.h"
-#include "r8a7779.h"
-
-static void __init marzen_init_timer(void)
-{
-	r8a7779_clocks_init(r8a7779_read_mode_pins());
-	clocksource_of_init();
-}
-
-static void __init marzen_init(void)
-{
-	of_platform_populate(NULL, of_default_bus_match_table, NULL, NULL);
-	r8a7779_init_irq_extpin_dt(1); /* IRQ1 as individual interrupt */
-}
-
-static const char *marzen_boards_compat_dt[] __initdata = {
-	"renesas,marzen",
-	"renesas,marzen-reference",
-	NULL,
-};
-
-DT_MACHINE_START(MARZEN, "marzen")
-	.smp		= smp_ops(r8a7779_smp_ops),
-	.map_io		= r8a7779_map_io,
-	.init_early	= shmobile_init_delay,
-	.init_time	= marzen_init_timer,
-	.init_irq	= r8a7779_init_irq_dt,
-	.init_machine	= marzen_init,
-	.init_late	= shmobile_init_late,
-	.dt_compat	= marzen_boards_compat_dt,
-MACHINE_END
-- 
2.1.4



From horms+renesas at verge.net.au  Sun Aug  2 23:04:55 2015
From: horms+renesas at verge.net.au (Simon Horman)
Date: Mon,  3 Aug 2015 15:04:55 +0900
Subject: [PATCH 4/6] ARM: shmobile: r8a7779: Cleanup header file
In-Reply-To: <cover.1438581659.git.horms+renesas@verge.net.au>
References: <cover.1438581659.git.horms+renesas@verge.net.au>
Message-ID: <640780efdd97eefd9ee78e1cd03ba97b1a1e1d9a.1438581659.git.horms+renesas@verge.net.au>

From: Magnus Damm <damm+renesas at opensource.se>

Remove unused function prototypes from r8a7779.h and
make the functions static.

Signed-off-by: Magnus Damm <damm+renesas at opensource.se>
Acked-by: Geert Uytterhoeven <geert+renesas at glider.be>
Signed-off-by: Simon Horman <horms+renesas at verge.net.au>
---
 arch/arm/mach-shmobile/clock-r8a7779.c | 2 +-
 arch/arm/mach-shmobile/r8a7779.h       | 2 --
 arch/arm/mach-shmobile/setup-r8a7779.c | 2 +-
 3 files changed, 2 insertions(+), 4 deletions(-)

diff --git a/arch/arm/mach-shmobile/clock-r8a7779.c b/arch/arm/mach-shmobile/clock-r8a7779.c
index fa8ab2cc9187..a376ba3b67c0 100644
--- a/arch/arm/mach-shmobile/clock-r8a7779.c
+++ b/arch/arm/mach-shmobile/clock-r8a7779.c
@@ -201,7 +201,7 @@ static struct clk_lookup lookups[] = {
 	CLKDEV_DEV_ID("rcar-du-r8a7779", &mstp_clks[MSTP103]), /* DU */
 };
 
-void __init r8a7779_clock_init(void)
+static void __init r8a7779_clock_init(void)
 {
 	u32 mode = r8a7779_read_mode_pins();
 	int k, ret = 0;
diff --git a/arch/arm/mach-shmobile/r8a7779.h b/arch/arm/mach-shmobile/r8a7779.h
index 19f97046dd70..f69c7477178b 100644
--- a/arch/arm/mach-shmobile/r8a7779.h
+++ b/arch/arm/mach-shmobile/r8a7779.h
@@ -11,7 +11,6 @@ enum {
 };
 
 extern void r8a7779_init_irq_extpin(int irlm);
-extern void r8a7779_init_irq_extpin_dt(int irlm);
 extern void r8a7779_init_irq_dt(void);
 extern void r8a7779_map_io(void);
 extern void r8a7779_earlytimer_init(void);
@@ -19,7 +18,6 @@ extern void r8a7779_add_early_devices(void);
 extern void r8a7779_add_standard_devices(void);
 extern void r8a7779_init_late(void);
 extern u32 r8a7779_read_mode_pins(void);
-extern void r8a7779_clock_init(void);
 extern void r8a7779_pinmux_init(void);
 extern void r8a7779_pm_init(void);
 extern void r8a7779_register_twd(void);
diff --git a/arch/arm/mach-shmobile/setup-r8a7779.c b/arch/arm/mach-shmobile/setup-r8a7779.c
index 2c3e433f84ca..f436cba958fa 100644
--- a/arch/arm/mach-shmobile/setup-r8a7779.c
+++ b/arch/arm/mach-shmobile/setup-r8a7779.c
@@ -99,7 +99,7 @@ static struct resource irqpin0_resources[] __initdata = {
 	DEFINE_RES_IRQ(gic_spi(30)), /* IRQ3 */
 };
 
-void __init r8a7779_init_irq_extpin_dt(int irlm)
+static void __init r8a7779_init_irq_extpin_dt(int irlm)
 {
 	void __iomem *icr0 = ioremap_nocache(0xfe780000, PAGE_SIZE);
 	u32 tmp;
-- 
2.1.4



From horms+renesas at verge.net.au  Sun Aug  2 23:04:56 2015
From: horms+renesas at verge.net.au (Simon Horman)
Date: Mon,  3 Aug 2015 15:04:56 +0900
Subject: [PATCH 5/6] ARM: shmobile: marzen: Remove legacy board code
In-Reply-To: <cover.1438581659.git.horms+renesas@verge.net.au>
References: <cover.1438581659.git.horms+renesas@verge.net.au>
Message-ID: <b97fdb836a36df53de5685278c0126a222903c5e.1438581659.git.horms+renesas@verge.net.au>

From: Magnus Damm <damm+renesas at opensource.se>

Remove Marzen legacy board code written in C. Instead
board support expressed in DT shall be used together
with Multiplatform and shmobile_defconfig.

Signed-off-by: Magnus Damm <damm+renesas at opensource.se>
Acked-by: Geert Uytterhoeven <geert+renesas at glider.be>
Signed-off-by: Simon Horman <horms+renesas at verge.net.au>
---
 arch/arm/boot/dts/Makefile            |   1 -
 arch/arm/mach-shmobile/Kconfig        |   7 -
 arch/arm/mach-shmobile/Makefile       |   1 -
 arch/arm/mach-shmobile/Makefile.boot  |   1 -
 arch/arm/mach-shmobile/board-marzen.c | 347 ----------------------------------
 5 files changed, 357 deletions(-)
 delete mode 100644 arch/arm/mach-shmobile/board-marzen.c

diff --git a/arch/arm/boot/dts/Makefile b/arch/arm/boot/dts/Makefile
index 246473a244f6..2e3fabad0f7a 100644
--- a/arch/arm/boot/dts/Makefile
+++ b/arch/arm/boot/dts/Makefile
@@ -504,7 +504,6 @@ dtb-$(CONFIG_ARCH_SHMOBILE_LEGACY) += \
 	r8a7740-armadillo800eva.dtb \
 	r8a7778-bockw.dtb \
 	r8a7778-bockw-reference.dtb \
-	r8a7779-marzen.dtb \
 	sh73a0-kzm9g.dtb
 dtb-$(CONFIG_ARCH_SHMOBILE_MULTI) += \
 	emev2-kzm9d.dtb \
diff --git a/arch/arm/mach-shmobile/Kconfig b/arch/arm/mach-shmobile/Kconfig
index 3d6f46cb8b18..1fe775c7e004 100644
--- a/arch/arm/mach-shmobile/Kconfig
+++ b/arch/arm/mach-shmobile/Kconfig
@@ -157,13 +157,6 @@ config MACH_BOCKW_REFERENCE
 
 	   This is intended to aid developers
 
-config MACH_MARZEN
-	bool "MARZEN board"
-	depends on ARCH_R8A7779
-	select ARCH_REQUIRE_GPIOLIB
-	select REGULATOR_FIXED_VOLTAGE if REGULATOR
-	select USE_OF
-
 config MACH_KZM9G
 	bool "KZM-A9-GT board"
 	depends on ARCH_SH73A0
diff --git a/arch/arm/mach-shmobile/Makefile b/arch/arm/mach-shmobile/Makefile
index 08b12b4d3f90..dd214ca8b09e 100644
--- a/arch/arm/mach-shmobile/Makefile
+++ b/arch/arm/mach-shmobile/Makefile
@@ -54,7 +54,6 @@ obj-$(CONFIG_ARCH_RCAR_GEN2)	+= pm-rcar-gen2.o
 ifndef CONFIG_ARCH_SHMOBILE_MULTI
 obj-$(CONFIG_MACH_BOCKW)	+= board-bockw.o
 obj-$(CONFIG_MACH_BOCKW_REFERENCE)	+= board-bockw-reference.o
-obj-$(CONFIG_MACH_MARZEN)	+= board-marzen.o
 obj-$(CONFIG_MACH_ARMADILLO800EVA)	+= board-armadillo800eva.o
 obj-$(CONFIG_MACH_KZM9G)	+= board-kzm9g.o intc-sh73a0.o
 endif
diff --git a/arch/arm/mach-shmobile/Makefile.boot b/arch/arm/mach-shmobile/Makefile.boot
index e1ef19cef89c..7e7e0f47848c 100644
--- a/arch/arm/mach-shmobile/Makefile.boot
+++ b/arch/arm/mach-shmobile/Makefile.boot
@@ -4,7 +4,6 @@ loadaddr-$(CONFIG_MACH_ARMADILLO800EVA) += 0x40008000
 loadaddr-$(CONFIG_MACH_BOCKW) += 0x60008000
 loadaddr-$(CONFIG_MACH_BOCKW_REFERENCE) += 0x60008000
 loadaddr-$(CONFIG_MACH_KZM9G) += 0x41008000
-loadaddr-$(CONFIG_MACH_MARZEN) += 0x60008000
 
 __ZRELADDR	:= $(sort $(loadaddr-y))
    zreladdr-y   += $(__ZRELADDR)
diff --git a/arch/arm/mach-shmobile/board-marzen.c b/arch/arm/mach-shmobile/board-marzen.c
deleted file mode 100644
index 51db288f192a..000000000000
--- a/arch/arm/mach-shmobile/board-marzen.c
+++ /dev/null
@@ -1,347 +0,0 @@
-/*
- * marzen board support
- *
- * Copyright (C) 2011, 2013  Renesas Solutions Corp.
- * Copyright (C) 2011  Magnus Damm
- * Copyright (C) 2013  Cogent Embedded, Inc.
- *
- * 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; version 2 of the License.
- *
- * 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/kernel.h>
-#include <linux/init.h>
-#include <linux/interrupt.h>
-#include <linux/irq.h>
-#include <linux/platform_device.h>
-#include <linux/delay.h>
-#include <linux/io.h>
-#include <linux/leds.h>
-#include <linux/dma-mapping.h>
-#include <linux/pinctrl/machine.h>
-#include <linux/platform_data/camera-rcar.h>
-#include <linux/platform_data/gpio-rcar.h>
-#include <linux/platform_data/usb-rcar-phy.h>
-#include <linux/regulator/fixed.h>
-#include <linux/regulator/machine.h>
-#include <linux/smsc911x.h>
-#include <linux/spi/spi.h>
-#include <linux/spi/sh_hspi.h>
-#include <linux/mmc/host.h>
-#include <linux/mmc/sh_mobile_sdhi.h>
-#include <linux/mfd/tmio.h>
-
-#include <media/soc_camera.h>
-#include <asm/mach-types.h>
-#include <asm/mach/arch.h>
-#include <asm/traps.h>
-
-#include "common.h"
-#include "irqs.h"
-#include "r8a7779.h"
-
-/* Fixed 3.3V regulator to be used by SDHI0 */
-static struct regulator_consumer_supply fixed3v3_power_consumers[] = {
-	REGULATOR_SUPPLY("vmmc", "sh_mobile_sdhi.0"),
-	REGULATOR_SUPPLY("vqmmc", "sh_mobile_sdhi.0"),
-};
-
-/* Dummy supplies, where voltage doesn't matter */
-static struct regulator_consumer_supply dummy_supplies[] = {
-	REGULATOR_SUPPLY("vddvario", "smsc911x"),
-	REGULATOR_SUPPLY("vdd33a", "smsc911x"),
-};
-
-/* USB PHY */
-static struct resource usb_phy_resources[] = {
-	[0] = {
-		.start		= 0xffe70800,
-		.end		= 0xffe70900 - 1,
-		.flags		= IORESOURCE_MEM,
-	},
-};
-
-static struct rcar_phy_platform_data usb_phy_platform_data;
-
-static struct platform_device usb_phy = {
-	.name		= "rcar_usb_phy",
-	.id		= -1,
-	.dev  = {
-		.platform_data = &usb_phy_platform_data,
-	},
-	.resource	= usb_phy_resources,
-	.num_resources	= ARRAY_SIZE(usb_phy_resources),
-};
-
-/* SMSC LAN89218 */
-static struct resource smsc911x_resources[] = {
-	[0] = {
-		.start		= 0x18000000, /* ExCS0 */
-		.end		= 0x180000ff, /* A1->A7 */
-		.flags		= IORESOURCE_MEM,
-	},
-	[1] = {
-		.start		= irq_pin(1), /* IRQ 1 */
-		.flags		= IORESOURCE_IRQ,
-	},
-};
-
-static struct smsc911x_platform_config smsc911x_platdata = {
-	.flags		= SMSC911X_USE_32BIT, /* 32-bit SW on 16-bit HW bus */
-	.phy_interface	= PHY_INTERFACE_MODE_MII,
-	.irq_polarity	= SMSC911X_IRQ_POLARITY_ACTIVE_LOW,
-	.irq_type	= SMSC911X_IRQ_TYPE_PUSH_PULL,
-};
-
-static struct platform_device eth_device = {
-	.name		= "smsc911x",
-	.id		= -1,
-	.dev  = {
-		.platform_data = &smsc911x_platdata,
-	},
-	.resource	= smsc911x_resources,
-	.num_resources	= ARRAY_SIZE(smsc911x_resources),
-};
-
-static struct resource sdhi0_resources[] = {
-	[0] = {
-		.name	= "sdhi0",
-		.start	= 0xffe4c000,
-		.end	= 0xffe4c0ff,
-		.flags	= IORESOURCE_MEM,
-	},
-	[1] = {
-		.start	= gic_iid(0x88),
-		.flags	= IORESOURCE_IRQ,
-	},
-};
-
-static struct tmio_mmc_data sdhi0_platform_data = {
-	.chan_priv_tx = (void *)HPBDMA_SLAVE_SDHI0_TX,
-	.chan_priv_rx = (void *)HPBDMA_SLAVE_SDHI0_RX,
-	.flags        = TMIO_MMC_WRPROTECT_DISABLE | TMIO_MMC_HAS_IDLE_WAIT,
-	.capabilities = MMC_CAP_SD_HIGHSPEED,
-};
-
-static struct platform_device sdhi0_device = {
-	.name = "sh_mobile_sdhi",
-	.num_resources = ARRAY_SIZE(sdhi0_resources),
-	.resource = sdhi0_resources,
-	.id = 0,
-	.dev = {
-		.platform_data = &sdhi0_platform_data,
-	}
-};
-
-/* Thermal */
-static struct resource thermal_resources[] = {
-	[0] = {
-		.start		= 0xFFC48000,
-		.end		= 0xFFC48038 - 1,
-		.flags		= IORESOURCE_MEM,
-	},
-};
-
-static struct platform_device thermal_device = {
-	.name		= "rcar_thermal",
-	.resource	= thermal_resources,
-	.num_resources	= ARRAY_SIZE(thermal_resources),
-};
-
-/* HSPI */
-static struct resource hspi_resources[] = {
-	[0] = {
-		.start		= 0xFFFC7000,
-		.end		= 0xFFFC7018 - 1,
-		.flags		= IORESOURCE_MEM,
-	},
-};
-
-static struct platform_device hspi_device = {
-	.name	= "sh-hspi",
-	.id	= 0,
-	.resource	= hspi_resources,
-	.num_resources	= ARRAY_SIZE(hspi_resources),
-};
-
-/* LEDS */
-static struct gpio_led marzen_leds[] = {
-	{
-		.name		= "led2",
-		.gpio		= RCAR_GP_PIN(4, 29),
-		.default_state	= LEDS_GPIO_DEFSTATE_ON,
-	}, {
-		.name		= "led3",
-		.gpio		= RCAR_GP_PIN(4, 30),
-		.default_state	= LEDS_GPIO_DEFSTATE_ON,
-	}, {
-		.name		= "led4",
-		.gpio		= RCAR_GP_PIN(4, 31),
-		.default_state	= LEDS_GPIO_DEFSTATE_ON,
-	},
-};
-
-static struct gpio_led_platform_data marzen_leds_pdata = {
-	.leds		= marzen_leds,
-	.num_leds	= ARRAY_SIZE(marzen_leds),
-};
-
-static struct platform_device leds_device = {
-	.name	= "leds-gpio",
-	.id	= 0,
-	.dev	= {
-		.platform_data  = &marzen_leds_pdata,
-	},
-};
-
-/* VIN */
-static struct rcar_vin_platform_data vin_platform_data __initdata = {
-	.flags	= RCAR_VIN_BT656,
-};
-
-#define MARZEN_VIN(idx)						\
-static struct resource vin##idx##_resources[] __initdata = {	\
-	DEFINE_RES_MEM(0xffc50000 + 0x1000 * (idx), 0x1000),	\
-	DEFINE_RES_IRQ(gic_iid(0x5f + (idx))),			\
-};								\
-								\
-static struct platform_device_info vin##idx##_info __initdata = { \
-	.name		= "r8a7779-vin",			\
-	.id		= idx,					\
-	.res		= vin##idx##_resources,			\
-	.num_res	= ARRAY_SIZE(vin##idx##_resources),	\
-	.dma_mask	= DMA_BIT_MASK(32),			\
-	.data		= &vin_platform_data,			\
-	.size_data	= sizeof(vin_platform_data),		\
-}
-MARZEN_VIN(1);
-MARZEN_VIN(3);
-
-#define MARZEN_CAMERA(idx)					\
-static struct i2c_board_info camera##idx##_info = {		\
-	I2C_BOARD_INFO("adv7180", 0x20 + (idx)),		\
-};								\
-								\
-static struct soc_camera_link iclink##idx##_adv7180 = {		\
-	.bus_id		= 1 + 2 * (idx),			\
-	.i2c_adapter_id	= 0,					\
-	.board_info	= &camera##idx##_info,			\
-};								\
-								\
-static struct platform_device camera##idx##_device = {		\
-	.name	= "soc-camera-pdrv",				\
-	.id	= idx,						\
-	.dev	= {						\
-		.platform_data	= &iclink##idx##_adv7180,	\
-	},							\
-};
-
-MARZEN_CAMERA(0);
-MARZEN_CAMERA(1);
-
-static struct platform_device *marzen_devices[] __initdata = {
-	&eth_device,
-	&sdhi0_device,
-	&thermal_device,
-	&hspi_device,
-	&leds_device,
-	&usb_phy,
-	&camera0_device,
-	&camera1_device,
-};
-
-static const struct pinctrl_map marzen_pinctrl_map[] = {
-	/* DU (CN10: ARGB0, CN13: LVDS) */
-	PIN_MAP_MUX_GROUP_DEFAULT("rcar-du-r8a7779", "pfc-r8a7779",
-				  "du0_rgb888", "du0"),
-	PIN_MAP_MUX_GROUP_DEFAULT("rcar-du-r8a7779", "pfc-r8a7779",
-				  "du0_sync_1", "du0"),
-	PIN_MAP_MUX_GROUP_DEFAULT("rcar-du-r8a7779", "pfc-r8a7779",
-				  "du0_clk_out_0", "du0"),
-	PIN_MAP_MUX_GROUP_DEFAULT("rcar-du-r8a7779", "pfc-r8a7779",
-				  "du1_rgb666", "du1"),
-	PIN_MAP_MUX_GROUP_DEFAULT("rcar-du-r8a7779", "pfc-r8a7779",
-				  "du1_sync_1", "du1"),
-	PIN_MAP_MUX_GROUP_DEFAULT("rcar-du-r8a7779", "pfc-r8a7779",
-				  "du1_clk_out", "du1"),
-	/* HSPI0 */
-	PIN_MAP_MUX_GROUP_DEFAULT("sh-hspi.0", "pfc-r8a7779",
-				  "hspi0", "hspi0"),
-	/* SCIF2 (CN18: DEBUG0) */
-	PIN_MAP_MUX_GROUP_DEFAULT("sh-sci.2", "pfc-r8a7779",
-				  "scif2_data_c", "scif2"),
-	/* SCIF4 (CN19: DEBUG1) */
-	PIN_MAP_MUX_GROUP_DEFAULT("sh-sci.4", "pfc-r8a7779",
-				  "scif4_data", "scif4"),
-	/* SDHI0 */
-	PIN_MAP_MUX_GROUP_DEFAULT("sh_mobile_sdhi.0", "pfc-r8a7779",
-				  "sdhi0_data4", "sdhi0"),
-	PIN_MAP_MUX_GROUP_DEFAULT("sh_mobile_sdhi.0", "pfc-r8a7779",
-				  "sdhi0_ctrl", "sdhi0"),
-	PIN_MAP_MUX_GROUP_DEFAULT("sh_mobile_sdhi.0", "pfc-r8a7779",
-				  "sdhi0_cd", "sdhi0"),
-	/* SMSC */
-	PIN_MAP_MUX_GROUP_DEFAULT("smsc911x", "pfc-r8a7779",
-				  "intc_irq1_b", "intc"),
-	PIN_MAP_MUX_GROUP_DEFAULT("smsc911x", "pfc-r8a7779",
-				  "lbsc_ex_cs0", "lbsc"),
-	/* USB0 */
-	PIN_MAP_MUX_GROUP_DEFAULT("ehci-platform.0", "pfc-r8a7779",
-				  "usb0", "usb0"),
-	/* USB1 */
-	PIN_MAP_MUX_GROUP_DEFAULT("ehci-platform.0", "pfc-r8a7779",
-				  "usb1", "usb1"),
-	/* USB2 */
-	PIN_MAP_MUX_GROUP_DEFAULT("ehci-platform.1", "pfc-r8a7779",
-				  "usb2", "usb2"),
-	/* VIN1 */
-	PIN_MAP_MUX_GROUP_DEFAULT("r8a7779-vin.1", "pfc-r8a7779",
-				  "vin1_clk", "vin1"),
-	PIN_MAP_MUX_GROUP_DEFAULT("r8a7779-vin.1", "pfc-r8a7779",
-				  "vin1_data8", "vin1"),
-	/* VIN3 */
-	PIN_MAP_MUX_GROUP_DEFAULT("r8a7779-vin.3", "pfc-r8a7779",
-				  "vin3_clk", "vin3"),
-	PIN_MAP_MUX_GROUP_DEFAULT("r8a7779-vin.3", "pfc-r8a7779",
-				  "vin3_data8", "vin3"),
-};
-
-static void __init marzen_init(void)
-{
-	regulator_register_always_on(0, "fixed-3.3V", fixed3v3_power_consumers,
-				ARRAY_SIZE(fixed3v3_power_consumers), 3300000);
-	regulator_register_fixed(1, dummy_supplies,
-				ARRAY_SIZE(dummy_supplies));
-
-	pinctrl_register_mappings(marzen_pinctrl_map,
-				  ARRAY_SIZE(marzen_pinctrl_map));
-	r8a7779_pinmux_init();
-	r8a7779_init_irq_extpin(1); /* IRQ1 as individual interrupt */
-
-	r8a7779_add_standard_devices();
-	platform_device_register_full(&vin1_info);
-	platform_device_register_full(&vin3_info);
-	platform_add_devices(marzen_devices, ARRAY_SIZE(marzen_devices));
-}
-
-static const char *marzen_boards_compat_dt[] __initdata = {
-        "renesas,marzen",
-        NULL,
-};
-
-DT_MACHINE_START(MARZEN, "marzen")
-	.smp		= smp_ops(r8a7779_smp_ops),
-	.map_io		= r8a7779_map_io,
-	.init_early	= r8a7779_add_early_devices,
-	.init_irq	= r8a7779_init_irq_dt,
-	.init_machine	= marzen_init,
-	.init_late	= r8a7779_init_late,
-	.dt_compat	= marzen_boards_compat_dt,
-	.init_time	= r8a7779_earlytimer_init,
-MACHINE_END
-- 
2.1.4



From horms+renesas at verge.net.au  Sun Aug  2 23:04:57 2015
From: horms+renesas at verge.net.au (Simon Horman)
Date: Mon,  3 Aug 2015 15:04:57 +0900
Subject: [PATCH 6/6] ARM: shmobile: r8a7779: Remove legacy SoC code
In-Reply-To: <cover.1438581659.git.horms+renesas@verge.net.au>
References: <cover.1438581659.git.horms+renesas@verge.net.au>
Message-ID: <c99cd90d98a98aa101b169e44d249e5cd71f46f2.1438581659.git.horms+renesas@verge.net.au>

From: Magnus Damm <damm+renesas at opensource.se>

Now when the Marzen legacy board code is gone this patch
removes the unused r8a7779 legacy SoC code.

Signed-off-by: Magnus Damm <damm+renesas at opensource.se>
Acked-by: Geert Uytterhoeven <geert+renesas at glider.be>
Signed-off-by: Simon Horman <horms+renesas at verge.net.au>
---
 arch/arm/mach-shmobile/Makefile        |   1 -
 arch/arm/mach-shmobile/clock-r8a7779.c | 271 -------------
 arch/arm/mach-shmobile/r8a7779.h       |  17 -
 arch/arm/mach-shmobile/setup-r8a7779.c | 674 +--------------------------------
 arch/arm/mach-shmobile/smp-r8a7779.c   |   9 -
 5 files changed, 4 insertions(+), 968 deletions(-)
 delete mode 100644 arch/arm/mach-shmobile/clock-r8a7779.c

diff --git a/arch/arm/mach-shmobile/Makefile b/arch/arm/mach-shmobile/Makefile
index dd214ca8b09e..039445ce1ed8 100644
--- a/arch/arm/mach-shmobile/Makefile
+++ b/arch/arm/mach-shmobile/Makefile
@@ -23,7 +23,6 @@ obj-y				+= clock.o
 obj-$(CONFIG_ARCH_SH73A0)	+= clock-sh73a0.o
 obj-$(CONFIG_ARCH_R8A7740)	+= clock-r8a7740.o
 obj-$(CONFIG_ARCH_R8A7778)	+= clock-r8a7778.o
-obj-$(CONFIG_ARCH_R8A7779)	+= clock-r8a7779.o
 endif
 
 # CPU reset vector handling objects
diff --git a/arch/arm/mach-shmobile/clock-r8a7779.c b/arch/arm/mach-shmobile/clock-r8a7779.c
deleted file mode 100644
index a376ba3b67c0..000000000000
--- a/arch/arm/mach-shmobile/clock-r8a7779.c
+++ /dev/null
@@ -1,271 +0,0 @@
-/*
- * r8a7779 clock framework support
- *
- * Copyright (C) 2011  Renesas Solutions Corp.
- * Copyright (C) 2011  Magnus Damm
- *
- * 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
- *
- * 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/bitops.h>
-#include <linux/init.h>
-#include <linux/kernel.h>
-#include <linux/io.h>
-#include <linux/sh_clk.h>
-#include <linux/clkdev.h>
-#include <linux/sh_timer.h>
-
-#include "clock.h"
-#include "common.h"
-#include "r8a7779.h"
-
-/*
- *		MD1 = 1			MD1 = 0
- *		(PLLA = 1500)		(PLLA = 1600)
- *		(MHz)			(MHz)
- *------------------------------------------------+--------------------
- * clkz		1000   (2/3)		800   (1/2)
- * clkzs	 250   (1/6)		200   (1/8)
- * clki		 750   (1/2)		800   (1/2)
- * clks		 250   (1/6)		200   (1/8)
- * clks1	 125   (1/12)		100   (1/16)
- * clks3	 187.5 (1/8)		200   (1/8)
- * clks4	  93.7 (1/16)		100   (1/16)
- * clkp		  62.5 (1/24)		 50   (1/32)
- * clkg		  62.5 (1/24)		 66.6 (1/24)
- * clkb, CLKOUT
- * (MD2 = 0)	  62.5 (1/24)		 66.6 (1/24)
- * (MD2 = 1)	  41.6 (1/36)		 50   (1/32)
-*/
-
-#define MD(nr)	BIT(nr)
-
-#define MSTPCR0		IOMEM(0xffc80030)
-#define MSTPCR1		IOMEM(0xffc80034)
-#define MSTPCR3		IOMEM(0xffc8003c)
-#define MSTPSR1		IOMEM(0xffc80044)
-
-/* ioremap() through clock mapping mandatory to avoid
- * collision with ARM coherent DMA virtual memory range.
- */
-
-static struct clk_mapping cpg_mapping = {
-	.phys	= 0xffc80000,
-	.len	= 0x80,
-};
-
-/*
- * Default rate for the root input clock, reset this with clk_set_rate()
- * from the platform code.
- */
-static struct clk plla_clk = {
-	/* .rate will be updated on r8a7779_clock_init() */
-	.mapping	= &cpg_mapping,
-};
-
-/*
- * clock ratio of these clock will be updated
- * on r8a7779_clock_init()
- */
-SH_FIXED_RATIO_CLK_SET(clkz_clk,	plla_clk, 1, 1);
-SH_FIXED_RATIO_CLK_SET(clkzs_clk,	plla_clk, 1, 1);
-SH_FIXED_RATIO_CLK_SET(clki_clk,	plla_clk, 1, 1);
-SH_FIXED_RATIO_CLK_SET(clks_clk,	plla_clk, 1, 1);
-SH_FIXED_RATIO_CLK_SET(clks1_clk,	plla_clk, 1, 1);
-SH_FIXED_RATIO_CLK_SET(clks3_clk,	plla_clk, 1, 1);
-SH_FIXED_RATIO_CLK_SET(clks4_clk,	plla_clk, 1, 1);
-SH_FIXED_RATIO_CLK_SET(clkb_clk,	plla_clk, 1, 1);
-SH_FIXED_RATIO_CLK_SET(clkout_clk,	plla_clk, 1, 1);
-SH_FIXED_RATIO_CLK_SET(clkp_clk,	plla_clk, 1, 1);
-SH_FIXED_RATIO_CLK_SET(clkg_clk,	plla_clk, 1, 1);
-
-static struct clk *main_clks[] = {
-	&plla_clk,
-	&clkz_clk,
-	&clkzs_clk,
-	&clki_clk,
-	&clks_clk,
-	&clks1_clk,
-	&clks3_clk,
-	&clks4_clk,
-	&clkb_clk,
-	&clkout_clk,
-	&clkp_clk,
-	&clkg_clk,
-};
-
-enum { MSTP323, MSTP322, MSTP321, MSTP320,
-	MSTP120,
-	MSTP116, MSTP115, MSTP114,
-	MSTP110, MSTP109, MSTP108,
-	MSTP103, MSTP101, MSTP100,
-	MSTP030,
-	MSTP029, MSTP028, MSTP027, MSTP026, MSTP025, MSTP024, MSTP023, MSTP022, MSTP021,
-	MSTP016, MSTP015, MSTP014,
-	MSTP007,
-	MSTP_NR };
-
-static struct clk mstp_clks[MSTP_NR] = {
-	[MSTP323] = SH_CLK_MSTP32(&clkp_clk, MSTPCR3, 23, 0), /* SDHI0 */
-	[MSTP322] = SH_CLK_MSTP32(&clkp_clk, MSTPCR3, 22, 0), /* SDHI1 */
-	[MSTP321] = SH_CLK_MSTP32(&clkp_clk, MSTPCR3, 21, 0), /* SDHI2 */
-	[MSTP320] = SH_CLK_MSTP32(&clkp_clk, MSTPCR3, 20, 0), /* SDHI3 */
-	[MSTP120] = SH_CLK_MSTP32_STS(&clks_clk, MSTPCR1, 20, MSTPSR1, 0), /* VIN3 */
-	[MSTP116] = SH_CLK_MSTP32_STS(&clkp_clk, MSTPCR1, 16, MSTPSR1, 0), /* PCIe */
-	[MSTP115] = SH_CLK_MSTP32_STS(&clkp_clk, MSTPCR1, 15, MSTPSR1, 0), /* SATA */
-	[MSTP114] = SH_CLK_MSTP32_STS(&clkp_clk, MSTPCR1, 14, MSTPSR1, 0), /* Ether */
-	[MSTP110] = SH_CLK_MSTP32_STS(&clks_clk, MSTPCR1, 10, MSTPSR1, 0), /* VIN0 */
-	[MSTP109] = SH_CLK_MSTP32_STS(&clks_clk, MSTPCR1,  9, MSTPSR1, 0), /* VIN1 */
-	[MSTP108] = SH_CLK_MSTP32_STS(&clks_clk, MSTPCR1,  8, MSTPSR1, 0), /* VIN2 */
-	[MSTP103] = SH_CLK_MSTP32_STS(&clks_clk, MSTPCR1,  3, MSTPSR1, 0), /* DU */
-	[MSTP101] = SH_CLK_MSTP32_STS(&clkp_clk, MSTPCR1,  1, MSTPSR1, 0), /* USB2 */
-	[MSTP100] = SH_CLK_MSTP32_STS(&clkp_clk, MSTPCR1,  0, MSTPSR1, 0), /* USB0/1 */
-	[MSTP030] = SH_CLK_MSTP32(&clkp_clk, MSTPCR0, 30, 0), /* I2C0 */
-	[MSTP029] = SH_CLK_MSTP32(&clkp_clk, MSTPCR0, 29, 0), /* I2C1 */
-	[MSTP028] = SH_CLK_MSTP32(&clkp_clk, MSTPCR0, 28, 0), /* I2C2 */
-	[MSTP027] = SH_CLK_MSTP32(&clkp_clk, MSTPCR0, 27, 0), /* I2C3 */
-	[MSTP026] = SH_CLK_MSTP32(&clkp_clk, MSTPCR0, 26, 0), /* SCIF0 */
-	[MSTP025] = SH_CLK_MSTP32(&clkp_clk, MSTPCR0, 25, 0), /* SCIF1 */
-	[MSTP024] = SH_CLK_MSTP32(&clkp_clk, MSTPCR0, 24, 0), /* SCIF2 */
-	[MSTP023] = SH_CLK_MSTP32(&clkp_clk, MSTPCR0, 23, 0), /* SCIF3 */
-	[MSTP022] = SH_CLK_MSTP32(&clkp_clk, MSTPCR0, 22, 0), /* SCIF4 */
-	[MSTP021] = SH_CLK_MSTP32(&clkp_clk, MSTPCR0, 21, 0), /* SCIF5 */
-	[MSTP016] = SH_CLK_MSTP32(&clkp_clk, MSTPCR0, 16, 0), /* TMU0 */
-	[MSTP015] = SH_CLK_MSTP32(&clkp_clk, MSTPCR0, 15, 0), /* TMU1 */
-	[MSTP014] = SH_CLK_MSTP32(&clkp_clk, MSTPCR0, 14, 0), /* TMU2 */
-	[MSTP007] = SH_CLK_MSTP32(&clks_clk, MSTPCR0,  7, 0), /* HSPI */
-};
-
-static struct clk_lookup lookups[] = {
-	/* main clocks */
-	CLKDEV_CON_ID("plla_clk", &plla_clk),
-	CLKDEV_CON_ID("clkz_clk", &clkz_clk),
-	CLKDEV_CON_ID("clkzs_clk", &clkzs_clk),
-
-	/* DIV4 clocks */
-	CLKDEV_CON_ID("shyway_clk",	&clks_clk),
-	CLKDEV_CON_ID("bus_clk",	&clkout_clk),
-	CLKDEV_CON_ID("shyway4_clk",	&clks4_clk),
-	CLKDEV_CON_ID("shyway3_clk",	&clks3_clk),
-	CLKDEV_CON_ID("shyway1_clk",	&clks1_clk),
-	CLKDEV_CON_ID("peripheral_clk",	&clkp_clk),
-
-	/* MSTP32 clocks */
-	CLKDEV_DEV_ID("r8a7779-vin.3", &mstp_clks[MSTP120]), /* VIN3 */
-	CLKDEV_DEV_ID("rcar-pcie", &mstp_clks[MSTP116]), /* PCIe */
-	CLKDEV_DEV_ID("sata_rcar", &mstp_clks[MSTP115]), /* SATA */
-	CLKDEV_DEV_ID("fc600000.sata", &mstp_clks[MSTP115]), /* SATA w/DT */
-	CLKDEV_DEV_ID("r8a777x-ether", &mstp_clks[MSTP114]), /* Ether */
-	CLKDEV_DEV_ID("r8a7779-vin.0", &mstp_clks[MSTP110]), /* VIN0 */
-	CLKDEV_DEV_ID("r8a7779-vin.1", &mstp_clks[MSTP109]), /* VIN1 */
-	CLKDEV_DEV_ID("r8a7779-vin.2", &mstp_clks[MSTP108]), /* VIN2 */
-	CLKDEV_DEV_ID("ehci-platform.1", &mstp_clks[MSTP101]), /* USB EHCI port2 */
-	CLKDEV_DEV_ID("ohci-platform.1", &mstp_clks[MSTP101]), /* USB OHCI port2 */
-	CLKDEV_DEV_ID("ehci-platform.0", &mstp_clks[MSTP100]), /* USB EHCI port0/1 */
-	CLKDEV_DEV_ID("ohci-platform.0", &mstp_clks[MSTP100]), /* USB OHCI port0/1 */
-	CLKDEV_ICK_ID("fck", "sh-tmu.0", &mstp_clks[MSTP016]), /* TMU0 */
-	CLKDEV_DEV_ID("i2c-rcar.0", &mstp_clks[MSTP030]), /* I2C0 */
-	CLKDEV_DEV_ID("ffc70000.i2c", &mstp_clks[MSTP030]), /* I2C0 */
-	CLKDEV_DEV_ID("i2c-rcar.1", &mstp_clks[MSTP029]), /* I2C1 */
-	CLKDEV_DEV_ID("ffc71000.i2c", &mstp_clks[MSTP029]), /* I2C1 */
-	CLKDEV_DEV_ID("i2c-rcar.2", &mstp_clks[MSTP028]), /* I2C2 */
-	CLKDEV_DEV_ID("ffc72000.i2c", &mstp_clks[MSTP028]), /* I2C2 */
-	CLKDEV_DEV_ID("i2c-rcar.3", &mstp_clks[MSTP027]), /* I2C3 */
-	CLKDEV_DEV_ID("ffc73000.i2c", &mstp_clks[MSTP027]), /* I2C3 */
-	CLKDEV_DEV_ID("sh-sci.0", &mstp_clks[MSTP026]), /* SCIF0 */
-	CLKDEV_DEV_ID("sh-sci.1", &mstp_clks[MSTP025]), /* SCIF1 */
-	CLKDEV_DEV_ID("sh-sci.2", &mstp_clks[MSTP024]), /* SCIF2 */
-	CLKDEV_DEV_ID("sh-sci.3", &mstp_clks[MSTP023]), /* SCIF3 */
-	CLKDEV_DEV_ID("sh-sci.4", &mstp_clks[MSTP022]), /* SCIF4 */
-	CLKDEV_DEV_ID("sh-sci.5", &mstp_clks[MSTP021]), /* SCIF6 */
-	CLKDEV_DEV_ID("sh-hspi.0", &mstp_clks[MSTP007]), /* HSPI0 */
-	CLKDEV_DEV_ID("fffc7000.spi", &mstp_clks[MSTP007]), /* HSPI0 */
-	CLKDEV_DEV_ID("sh-hspi.1", &mstp_clks[MSTP007]), /* HSPI1 */
-	CLKDEV_DEV_ID("fffc8000.spi", &mstp_clks[MSTP007]), /* HSPI1 */
-	CLKDEV_DEV_ID("sh-hspi.2", &mstp_clks[MSTP007]), /* HSPI2 */
-	CLKDEV_DEV_ID("fffc6000.spi", &mstp_clks[MSTP007]), /* HSPI2 */
-	CLKDEV_DEV_ID("sh_mobile_sdhi.0", &mstp_clks[MSTP323]), /* SDHI0 */
-	CLKDEV_DEV_ID("ffe4c000.sd", &mstp_clks[MSTP323]), /* SDHI0 */
-	CLKDEV_DEV_ID("sh_mobile_sdhi.1", &mstp_clks[MSTP322]), /* SDHI1 */
-	CLKDEV_DEV_ID("ffe4d000.sd", &mstp_clks[MSTP322]), /* SDHI1 */
-	CLKDEV_DEV_ID("sh_mobile_sdhi.2", &mstp_clks[MSTP321]), /* SDHI2 */
-	CLKDEV_DEV_ID("ffe4e000.sd", &mstp_clks[MSTP321]), /* SDHI2 */
-	CLKDEV_DEV_ID("sh_mobile_sdhi.3", &mstp_clks[MSTP320]), /* SDHI3 */
-	CLKDEV_DEV_ID("ffe4f000.sd", &mstp_clks[MSTP320]), /* SDHI3 */
-	CLKDEV_DEV_ID("rcar-du-r8a7779", &mstp_clks[MSTP103]), /* DU */
-};
-
-static void __init r8a7779_clock_init(void)
-{
-	u32 mode = r8a7779_read_mode_pins();
-	int k, ret = 0;
-
-	if (mode & MD(1)) {
-		plla_clk.rate = 1500000000;
-
-		SH_CLK_SET_RATIO(&clkz_clk_ratio,	2, 3);
-		SH_CLK_SET_RATIO(&clkzs_clk_ratio,	1, 6);
-		SH_CLK_SET_RATIO(&clki_clk_ratio,	1, 2);
-		SH_CLK_SET_RATIO(&clks_clk_ratio,	1, 6);
-		SH_CLK_SET_RATIO(&clks1_clk_ratio,	1, 12);
-		SH_CLK_SET_RATIO(&clks3_clk_ratio,	1, 8);
-		SH_CLK_SET_RATIO(&clks4_clk_ratio,	1, 16);
-		SH_CLK_SET_RATIO(&clkp_clk_ratio,	1, 24);
-		SH_CLK_SET_RATIO(&clkg_clk_ratio,	1, 24);
-		if (mode & MD(2)) {
-			SH_CLK_SET_RATIO(&clkb_clk_ratio,	1, 36);
-			SH_CLK_SET_RATIO(&clkout_clk_ratio,	1, 36);
-		} else {
-			SH_CLK_SET_RATIO(&clkb_clk_ratio,	1, 24);
-			SH_CLK_SET_RATIO(&clkout_clk_ratio,	1, 24);
-		}
-	} else {
-		plla_clk.rate = 1600000000;
-
-		SH_CLK_SET_RATIO(&clkz_clk_ratio,	1, 2);
-		SH_CLK_SET_RATIO(&clkzs_clk_ratio,	1, 8);
-		SH_CLK_SET_RATIO(&clki_clk_ratio,	1, 2);
-		SH_CLK_SET_RATIO(&clks_clk_ratio,	1, 8);
-		SH_CLK_SET_RATIO(&clks1_clk_ratio,	1, 16);
-		SH_CLK_SET_RATIO(&clks3_clk_ratio,	1, 8);
-		SH_CLK_SET_RATIO(&clks4_clk_ratio,	1, 16);
-		SH_CLK_SET_RATIO(&clkp_clk_ratio,	1, 32);
-		SH_CLK_SET_RATIO(&clkg_clk_ratio,	1, 24);
-		if (mode & MD(2)) {
-			SH_CLK_SET_RATIO(&clkb_clk_ratio,	1, 32);
-			SH_CLK_SET_RATIO(&clkout_clk_ratio,	1, 32);
-		} else {
-			SH_CLK_SET_RATIO(&clkb_clk_ratio,	1, 24);
-			SH_CLK_SET_RATIO(&clkout_clk_ratio,	1, 24);
-		}
-	}
-
-	for (k = 0; !ret && (k < ARRAY_SIZE(main_clks)); k++)
-		ret = clk_register(main_clks[k]);
-
-	if (!ret)
-		ret = sh_clk_mstp_register(mstp_clks, MSTP_NR);
-
-	clkdev_add_table(lookups, ARRAY_SIZE(lookups));
-
-	if (!ret)
-		shmobile_clk_init();
-	else
-		panic("failed to setup r8a7779 clocks\n");
-}
-
-/* do nothing for !CONFIG_SMP or !CONFIG_HAVE_TWD */
-void __init __weak r8a7779_register_twd(void) { }
-
-void __init r8a7779_earlytimer_init(void)
-{
-	r8a7779_clock_init();
-	r8a7779_register_twd();
-	shmobile_earlytimer_init();
-}
diff --git a/arch/arm/mach-shmobile/r8a7779.h b/arch/arm/mach-shmobile/r8a7779.h
index f69c7477178b..db303f76704e 100644
--- a/arch/arm/mach-shmobile/r8a7779.h
+++ b/arch/arm/mach-shmobile/r8a7779.h
@@ -3,24 +3,7 @@
 
 #include <linux/sh_clk.h>
 
-/* HPB-DMA slave IDs */
-enum {
-	HPBDMA_SLAVE_DUMMY,
-	HPBDMA_SLAVE_SDHI0_TX,
-	HPBDMA_SLAVE_SDHI0_RX,
-};
-
-extern void r8a7779_init_irq_extpin(int irlm);
-extern void r8a7779_init_irq_dt(void);
-extern void r8a7779_map_io(void);
-extern void r8a7779_earlytimer_init(void);
-extern void r8a7779_add_early_devices(void);
-extern void r8a7779_add_standard_devices(void);
-extern void r8a7779_init_late(void);
-extern u32 r8a7779_read_mode_pins(void);
-extern void r8a7779_pinmux_init(void);
 extern void r8a7779_pm_init(void);
-extern void r8a7779_register_twd(void);
 
 #ifdef CONFIG_PM
 extern void __init r8a7779_init_pm_domains(void);
diff --git a/arch/arm/mach-shmobile/setup-r8a7779.c b/arch/arm/mach-shmobile/setup-r8a7779.c
index f436cba958fa..c18d85a96c67 100644
--- a/arch/arm/mach-shmobile/setup-r8a7779.c
+++ b/arch/arm/mach-shmobile/setup-r8a7779.c
@@ -16,37 +16,15 @@
  */
 #include <linux/clk/shmobile.h>
 #include <linux/clocksource.h>
-#include <linux/kernel.h>
 #include <linux/init.h>
-#include <linux/interrupt.h>
 #include <linux/irq.h>
 #include <linux/irqchip.h>
 #include <linux/irqchip/arm-gic.h>
-#include <linux/of_platform.h>
-#include <linux/platform_data/dma-rcar-hpbdma.h>
-#include <linux/platform_data/gpio-rcar.h>
-#include <linux/platform_data/irq-renesas-intc-irqpin.h>
-#include <linux/platform_device.h>
-#include <linux/delay.h>
-#include <linux/input.h>
-#include <linux/io.h>
-#include <linux/serial_sci.h>
-#include <linux/sh_timer.h>
-#include <linux/dma-mapping.h>
-#include <linux/usb/otg.h>
-#include <linux/usb/hcd.h>
-#include <linux/usb/ehci_pdriver.h>
-#include <linux/usb/ohci_pdriver.h>
-#include <linux/pm_runtime.h>
 
-#include <asm/mach-types.h>
 #include <asm/mach/arch.h>
-#include <asm/mach/time.h>
 #include <asm/mach/map.h>
-#include <asm/hardware/cache-l2x0.h>
 
 #include "common.h"
-#include "irqs.h"
 #include "r8a7779.h"
 
 static struct map_desc r8a7779_io_desc[] __initdata = {
@@ -66,7 +44,7 @@ static struct map_desc r8a7779_io_desc[] __initdata = {
 	},
 };
 
-void __init r8a7779_map_io(void)
+static void __init r8a7779_map_io(void)
 {
 	debug_ll_io_init();
 	iotable_init(r8a7779_io_desc, ARRAY_SIZE(r8a7779_io_desc));
@@ -82,652 +60,12 @@ void __init r8a7779_map_io(void)
 #define INT2NTSR0 IOMEM(0xfe700060)
 #define INT2NTSR1 IOMEM(0xfe700064)
 
-static struct renesas_intc_irqpin_config irqpin0_platform_data __initdata = {
-	.irq_base = irq_pin(0), /* IRQ0 -> IRQ3 */
-	.sense_bitfield_width = 2,
-};
-
-static struct resource irqpin0_resources[] __initdata = {
-	DEFINE_RES_MEM(0xfe78001c, 4), /* ICR1 */
-	DEFINE_RES_MEM(0xfe780010, 4), /* INTPRI */
-	DEFINE_RES_MEM(0xfe780024, 4), /* INTREQ */
-	DEFINE_RES_MEM(0xfe780044, 4), /* INTMSK0 */
-	DEFINE_RES_MEM(0xfe780064, 4), /* INTMSKCLR0 */
-	DEFINE_RES_IRQ(gic_spi(27)), /* IRQ0 */
-	DEFINE_RES_IRQ(gic_spi(28)), /* IRQ1 */
-	DEFINE_RES_IRQ(gic_spi(29)), /* IRQ2 */
-	DEFINE_RES_IRQ(gic_spi(30)), /* IRQ3 */
-};
-
-static void __init r8a7779_init_irq_extpin_dt(int irlm)
-{
-	void __iomem *icr0 = ioremap_nocache(0xfe780000, PAGE_SIZE);
-	u32 tmp;
-
-	if (!icr0) {
-		pr_warn("r8a7779: unable to setup external irq pin mode\n");
-		return;
-	}
-
-	tmp = ioread32(icr0);
-	if (irlm)
-		tmp |= 1 << 23; /* IRQ0 -> IRQ3 as individual pins */
-	else
-		tmp &= ~(1 << 23); /* IRL mode - not supported */
-	tmp |= (1 << 21); /* LVLMODE = 1 */
-	iowrite32(tmp, icr0);
-	iounmap(icr0);
-}
-
-void __init r8a7779_init_irq_extpin(int irlm)
-{
-	r8a7779_init_irq_extpin_dt(irlm);
-	if (irlm)
-		platform_device_register_resndata(
-			NULL, "renesas_intc_irqpin", -1,
-			irqpin0_resources, ARRAY_SIZE(irqpin0_resources),
-			&irqpin0_platform_data, sizeof(irqpin0_platform_data));
-}
-
-/* PFC/GPIO */
-static struct resource r8a7779_pfc_resources[] = {
-	DEFINE_RES_MEM(0xfffc0000, 0x023c),
-};
-
-static struct platform_device r8a7779_pfc_device = {
-	.name		= "pfc-r8a7779",
-	.id		= -1,
-	.resource	= r8a7779_pfc_resources,
-	.num_resources	= ARRAY_SIZE(r8a7779_pfc_resources),
-};
-
-#define R8A7779_GPIO(idx, npins) \
-static struct resource r8a7779_gpio##idx##_resources[] = {		\
-	DEFINE_RES_MEM(0xffc40000 + (0x1000 * (idx)), 0x002c),		\
-	DEFINE_RES_IRQ(gic_iid(0xad + (idx))),				\
-};									\
-									\
-static struct gpio_rcar_config r8a7779_gpio##idx##_platform_data = {	\
-	.gpio_base	= 32 * (idx),					\
-	.irq_base	= 0,						\
-	.number_of_pins	= npins,					\
-	.pctl_name	= "pfc-r8a7779",				\
-};									\
-									\
-static struct platform_device r8a7779_gpio##idx##_device = {		\
-	.name		= "gpio_rcar",					\
-	.id		= idx,						\
-	.resource	= r8a7779_gpio##idx##_resources,		\
-	.num_resources	= ARRAY_SIZE(r8a7779_gpio##idx##_resources),	\
-	.dev		= {						\
-		.platform_data	= &r8a7779_gpio##idx##_platform_data,	\
-	},								\
-}
-
-R8A7779_GPIO(0, 32);
-R8A7779_GPIO(1, 32);
-R8A7779_GPIO(2, 32);
-R8A7779_GPIO(3, 32);
-R8A7779_GPIO(4, 32);
-R8A7779_GPIO(5, 32);
-R8A7779_GPIO(6, 9);
-
-static struct platform_device *r8a7779_pinctrl_devices[] __initdata = {
-	&r8a7779_pfc_device,
-	&r8a7779_gpio0_device,
-	&r8a7779_gpio1_device,
-	&r8a7779_gpio2_device,
-	&r8a7779_gpio3_device,
-	&r8a7779_gpio4_device,
-	&r8a7779_gpio5_device,
-	&r8a7779_gpio6_device,
-};
-
-void __init r8a7779_pinmux_init(void)
-{
-	platform_add_devices(r8a7779_pinctrl_devices,
-			    ARRAY_SIZE(r8a7779_pinctrl_devices));
-}
-
-/* SCIF */
-#define R8A7779_SCIF(index, baseaddr, irq)			\
-static struct plat_sci_port scif##index##_platform_data = {	\
-	.type		= PORT_SCIF,				\
-	.flags		= UPF_BOOT_AUTOCONF | UPF_IOREMAP,	\
-	.scscr		= SCSCR_RE | SCSCR_TE | SCSCR_CKE1,	\
-};								\
-								\
-static struct resource scif##index##_resources[] = {		\
-	DEFINE_RES_MEM(baseaddr, 0x100),			\
-	DEFINE_RES_IRQ(irq),					\
-};								\
-								\
-static struct platform_device scif##index##_device = {		\
-	.name		= "sh-sci",				\
-	.id		= index,				\
-	.resource	= scif##index##_resources,		\
-	.num_resources	= ARRAY_SIZE(scif##index##_resources),	\
-	.dev		= {					\
-		.platform_data	= &scif##index##_platform_data,	\
-	},							\
-}
-
-R8A7779_SCIF(0, 0xffe40000, gic_iid(0x78));
-R8A7779_SCIF(1, 0xffe41000, gic_iid(0x79));
-R8A7779_SCIF(2, 0xffe42000, gic_iid(0x7a));
-R8A7779_SCIF(3, 0xffe43000, gic_iid(0x7b));
-R8A7779_SCIF(4, 0xffe44000, gic_iid(0x7c));
-R8A7779_SCIF(5, 0xffe45000, gic_iid(0x7d));
-
-/* TMU */
-static struct sh_timer_config tmu0_platform_data = {
-	.channels_mask = 7,
-};
-
-static struct resource tmu0_resources[] = {
-	DEFINE_RES_MEM(0xffd80000, 0x30),
-	DEFINE_RES_IRQ(gic_iid(0x40)),
-	DEFINE_RES_IRQ(gic_iid(0x41)),
-	DEFINE_RES_IRQ(gic_iid(0x42)),
-};
-
-static struct platform_device tmu0_device = {
-	.name		= "sh-tmu",
-	.id		= 0,
-	.dev = {
-		.platform_data	= &tmu0_platform_data,
-	},
-	.resource	= tmu0_resources,
-	.num_resources	= ARRAY_SIZE(tmu0_resources),
-};
-
-/* I2C */
-static struct resource rcar_i2c0_res[] = {
-	{
-		.start  = 0xffc70000,
-		.end    = 0xffc70fff,
-		.flags  = IORESOURCE_MEM,
-	}, {
-		.start  = gic_iid(0x6f),
-		.flags  = IORESOURCE_IRQ,
-	},
-};
-
-static struct platform_device i2c0_device = {
-	.name		= "i2c-rcar",
-	.id		= 0,
-	.resource	= rcar_i2c0_res,
-	.num_resources	= ARRAY_SIZE(rcar_i2c0_res),
-};
-
-static struct resource rcar_i2c1_res[] = {
-	{
-		.start  = 0xffc71000,
-		.end    = 0xffc71fff,
-		.flags  = IORESOURCE_MEM,
-	}, {
-		.start  = gic_iid(0x72),
-		.flags  = IORESOURCE_IRQ,
-	},
-};
-
-static struct platform_device i2c1_device = {
-	.name		= "i2c-rcar",
-	.id		= 1,
-	.resource	= rcar_i2c1_res,
-	.num_resources	= ARRAY_SIZE(rcar_i2c1_res),
-};
-
-static struct resource rcar_i2c2_res[] = {
-	{
-		.start  = 0xffc72000,
-		.end    = 0xffc72fff,
-		.flags  = IORESOURCE_MEM,
-	}, {
-		.start  = gic_iid(0x70),
-		.flags  = IORESOURCE_IRQ,
-	},
-};
-
-static struct platform_device i2c2_device = {
-	.name		= "i2c-rcar",
-	.id		= 2,
-	.resource	= rcar_i2c2_res,
-	.num_resources	= ARRAY_SIZE(rcar_i2c2_res),
-};
-
-static struct resource rcar_i2c3_res[] = {
-	{
-		.start  = 0xffc73000,
-		.end    = 0xffc73fff,
-		.flags  = IORESOURCE_MEM,
-	}, {
-		.start  = gic_iid(0x71),
-		.flags  = IORESOURCE_IRQ,
-	},
-};
-
-static struct platform_device i2c3_device = {
-	.name		= "i2c-rcar",
-	.id		= 3,
-	.resource	= rcar_i2c3_res,
-	.num_resources	= ARRAY_SIZE(rcar_i2c3_res),
-};
-
-static struct resource sata_resources[] = {
-	[0] = {
-		.name	= "rcar-sata",
-		.start	= 0xfc600000,
-		.end	= 0xfc601fff,
-		.flags	= IORESOURCE_MEM,
-	},
-	[1] = {
-		.start	= gic_iid(0x84),
-		.flags	= IORESOURCE_IRQ,
-	},
-};
-
-static struct platform_device sata_device = {
-	.name		= "sata_rcar",
-	.id		= -1,
-	.resource	= sata_resources,
-	.num_resources	= ARRAY_SIZE(sata_resources),
-	.dev		= {
-		.dma_mask		= &sata_device.dev.coherent_dma_mask,
-		.coherent_dma_mask	= DMA_BIT_MASK(32),
-	},
-};
-
-/* USB */
-static struct usb_phy *phy;
-
-static int usb_power_on(struct platform_device *pdev)
+static void __init r8a7779_init_irq_dt(void)
 {
-	if (IS_ERR(phy))
-		return PTR_ERR(phy);
-
-	pm_runtime_enable(&pdev->dev);
-	pm_runtime_get_sync(&pdev->dev);
-
-	usb_phy_init(phy);
-
-	return 0;
-}
-
-static void usb_power_off(struct platform_device *pdev)
-{
-	if (IS_ERR(phy))
-		return;
-
-	usb_phy_shutdown(phy);
-
-	pm_runtime_put_sync(&pdev->dev);
-	pm_runtime_disable(&pdev->dev);
-}
-
-static int ehci_init_internal_buffer(struct usb_hcd *hcd)
-{
-	/*
-	 * Below are recommended values from the datasheet;
-	 * see [USB :: Setting of EHCI Internal Buffer].
-	 */
-	/* EHCI IP internal buffer setting */
-	iowrite32(0x00ff0040, hcd->regs + 0x0094);
-	/* EHCI IP internal buffer enable */
-	iowrite32(0x00000001, hcd->regs + 0x009C);
-
-	return 0;
-}
-
-static struct usb_ehci_pdata ehcix_pdata = {
-	.power_on	= usb_power_on,
-	.power_off	= usb_power_off,
-	.power_suspend	= usb_power_off,
-	.pre_setup	= ehci_init_internal_buffer,
-};
-
-static struct resource ehci0_resources[] = {
-	[0] = {
-		.start	= 0xffe70000,
-		.end	= 0xffe70400 - 1,
-		.flags	= IORESOURCE_MEM,
-	},
-	[1] = {
-		.start	= gic_iid(0x4c),
-		.flags	= IORESOURCE_IRQ,
-	},
-};
-
-static struct platform_device ehci0_device = {
-	.name	= "ehci-platform",
-	.id	= 0,
-	.dev	= {
-		.dma_mask		= &ehci0_device.dev.coherent_dma_mask,
-		.coherent_dma_mask	= 0xffffffff,
-		.platform_data		= &ehcix_pdata,
-	},
-	.num_resources	= ARRAY_SIZE(ehci0_resources),
-	.resource	= ehci0_resources,
-};
-
-static struct resource ehci1_resources[] = {
-	[0] = {
-		.start	= 0xfff70000,
-		.end	= 0xfff70400 - 1,
-		.flags	= IORESOURCE_MEM,
-	},
-	[1] = {
-		.start	= gic_iid(0x4d),
-		.flags	= IORESOURCE_IRQ,
-	},
-};
-
-static struct platform_device ehci1_device = {
-	.name	= "ehci-platform",
-	.id	= 1,
-	.dev	= {
-		.dma_mask		= &ehci1_device.dev.coherent_dma_mask,
-		.coherent_dma_mask	= 0xffffffff,
-		.platform_data		= &ehcix_pdata,
-	},
-	.num_resources	= ARRAY_SIZE(ehci1_resources),
-	.resource	= ehci1_resources,
-};
-
-static struct usb_ohci_pdata ohcix_pdata = {
-	.power_on	= usb_power_on,
-	.power_off	= usb_power_off,
-	.power_suspend	= usb_power_off,
-};
-
-static struct resource ohci0_resources[] = {
-	[0] = {
-		.start	= 0xffe70400,
-		.end	= 0xffe70800 - 1,
-		.flags	= IORESOURCE_MEM,
-	},
-	[1] = {
-		.start	= gic_iid(0x4c),
-		.flags	= IORESOURCE_IRQ,
-	},
-};
-
-static struct platform_device ohci0_device = {
-	.name	= "ohci-platform",
-	.id	= 0,
-	.dev	= {
-		.dma_mask		= &ohci0_device.dev.coherent_dma_mask,
-		.coherent_dma_mask	= 0xffffffff,
-		.platform_data		= &ohcix_pdata,
-	},
-	.num_resources	= ARRAY_SIZE(ohci0_resources),
-	.resource	= ohci0_resources,
-};
-
-static struct resource ohci1_resources[] = {
-	[0] = {
-		.start	= 0xfff70400,
-		.end	= 0xfff70800 - 1,
-		.flags	= IORESOURCE_MEM,
-	},
-	[1] = {
-		.start	= gic_iid(0x4d),
-		.flags	= IORESOURCE_IRQ,
-	},
-};
-
-static struct platform_device ohci1_device = {
-	.name	= "ohci-platform",
-	.id	= 1,
-	.dev	= {
-		.dma_mask		= &ohci1_device.dev.coherent_dma_mask,
-		.coherent_dma_mask	= 0xffffffff,
-		.platform_data		= &ohcix_pdata,
-	},
-	.num_resources	= ARRAY_SIZE(ohci1_resources),
-	.resource	= ohci1_resources,
-};
-
-/* HPB-DMA */
-
-/* Asynchronous mode register bits */
-#define HPB_DMAE_ASYNCMDR_ASMD43_MASK		BIT(23)	/* MMC1 */
-#define HPB_DMAE_ASYNCMDR_ASMD43_SINGLE		BIT(23)	/* MMC1 */
-#define HPB_DMAE_ASYNCMDR_ASMD43_MULTI		0	/* MMC1 */
-#define HPB_DMAE_ASYNCMDR_ASBTMD43_MASK		BIT(22)	/* MMC1 */
-#define HPB_DMAE_ASYNCMDR_ASBTMD43_BURST	BIT(22)	/* MMC1 */
-#define HPB_DMAE_ASYNCMDR_ASBTMD43_NBURST	0	/* MMC1 */
-#define HPB_DMAE_ASYNCMDR_ASMD24_MASK		BIT(21)	/* MMC0 */
-#define HPB_DMAE_ASYNCMDR_ASMD24_SINGLE		BIT(21)	/* MMC0 */
-#define HPB_DMAE_ASYNCMDR_ASMD24_MULTI		0	/* MMC0 */
-#define HPB_DMAE_ASYNCMDR_ASBTMD24_MASK		BIT(20)	/* MMC0 */
-#define HPB_DMAE_ASYNCMDR_ASBTMD24_BURST	BIT(20)	/* MMC0 */
-#define HPB_DMAE_ASYNCMDR_ASBTMD24_NBURST	0	/* MMC0 */
-#define HPB_DMAE_ASYNCMDR_ASMD41_MASK		BIT(19)	/* SDHI3 */
-#define HPB_DMAE_ASYNCMDR_ASMD41_SINGLE		BIT(19)	/* SDHI3 */
-#define HPB_DMAE_ASYNCMDR_ASMD41_MULTI		0	/* SDHI3 */
-#define HPB_DMAE_ASYNCMDR_ASBTMD41_MASK		BIT(18)	/* SDHI3 */
-#define HPB_DMAE_ASYNCMDR_ASBTMD41_BURST	BIT(18)	/* SDHI3 */
-#define HPB_DMAE_ASYNCMDR_ASBTMD41_NBURST	0	/* SDHI3 */
-#define HPB_DMAE_ASYNCMDR_ASMD40_MASK		BIT(17)	/* SDHI3 */
-#define HPB_DMAE_ASYNCMDR_ASMD40_SINGLE		BIT(17)	/* SDHI3 */
-#define HPB_DMAE_ASYNCMDR_ASMD40_MULTI		0	/* SDHI3 */
-#define HPB_DMAE_ASYNCMDR_ASBTMD40_MASK		BIT(16)	/* SDHI3 */
-#define HPB_DMAE_ASYNCMDR_ASBTMD40_BURST	BIT(16)	/* SDHI3 */
-#define HPB_DMAE_ASYNCMDR_ASBTMD40_NBURST	0	/* SDHI3 */
-#define HPB_DMAE_ASYNCMDR_ASMD39_MASK		BIT(15)	/* SDHI3 */
-#define HPB_DMAE_ASYNCMDR_ASMD39_SINGLE		BIT(15)	/* SDHI3 */
-#define HPB_DMAE_ASYNCMDR_ASMD39_MULTI		0	/* SDHI3 */
-#define HPB_DMAE_ASYNCMDR_ASBTMD39_MASK		BIT(14)	/* SDHI3 */
-#define HPB_DMAE_ASYNCMDR_ASBTMD39_BURST	BIT(14)	/* SDHI3 */
-#define HPB_DMAE_ASYNCMDR_ASBTMD39_NBURST	0	/* SDHI3 */
-#define HPB_DMAE_ASYNCMDR_ASMD27_MASK		BIT(13)	/* SDHI2 */
-#define HPB_DMAE_ASYNCMDR_ASMD27_SINGLE		BIT(13)	/* SDHI2 */
-#define HPB_DMAE_ASYNCMDR_ASMD27_MULTI		0	/* SDHI2 */
-#define HPB_DMAE_ASYNCMDR_ASBTMD27_MASK		BIT(12)	/* SDHI2 */
-#define HPB_DMAE_ASYNCMDR_ASBTMD27_BURST	BIT(12)	/* SDHI2 */
-#define HPB_DMAE_ASYNCMDR_ASBTMD27_NBURST	0	/* SDHI2 */
-#define HPB_DMAE_ASYNCMDR_ASMD26_MASK		BIT(11)	/* SDHI2 */
-#define HPB_DMAE_ASYNCMDR_ASMD26_SINGLE		BIT(11)	/* SDHI2 */
-#define HPB_DMAE_ASYNCMDR_ASMD26_MULTI		0	/* SDHI2 */
-#define HPB_DMAE_ASYNCMDR_ASBTMD26_MASK		BIT(10)	/* SDHI2 */
-#define HPB_DMAE_ASYNCMDR_ASBTMD26_BURST	BIT(10)	/* SDHI2 */
-#define HPB_DMAE_ASYNCMDR_ASBTMD26_NBURST	0	/* SDHI2 */
-#define HPB_DMAE_ASYNCMDR_ASMD25_MASK		BIT(9)	/* SDHI2 */
-#define HPB_DMAE_ASYNCMDR_ASMD25_SINGLE		BIT(9)	/* SDHI2 */
-#define HPB_DMAE_ASYNCMDR_ASMD25_MULTI		0	/* SDHI2 */
-#define HPB_DMAE_ASYNCMDR_ASBTMD25_MASK		BIT(8)	/* SDHI2 */
-#define HPB_DMAE_ASYNCMDR_ASBTMD25_BURST	BIT(8)	/* SDHI2 */
-#define HPB_DMAE_ASYNCMDR_ASBTMD25_NBURST	0	/* SDHI2 */
-#define HPB_DMAE_ASYNCMDR_ASMD23_MASK		BIT(7)	/* SDHI0 */
-#define HPB_DMAE_ASYNCMDR_ASMD23_SINGLE		BIT(7)	/* SDHI0 */
-#define HPB_DMAE_ASYNCMDR_ASMD23_MULTI		0	/* SDHI0 */
-#define HPB_DMAE_ASYNCMDR_ASBTMD23_MASK		BIT(6)	/* SDHI0 */
-#define HPB_DMAE_ASYNCMDR_ASBTMD23_BURST	BIT(6)	/* SDHI0 */
-#define HPB_DMAE_ASYNCMDR_ASBTMD23_NBURST	0	/* SDHI0 */
-#define HPB_DMAE_ASYNCMDR_ASMD22_MASK		BIT(5)	/* SDHI0 */
-#define HPB_DMAE_ASYNCMDR_ASMD22_SINGLE		BIT(5)	/* SDHI0 */
-#define HPB_DMAE_ASYNCMDR_ASMD22_MULTI		0	/* SDHI0 */
-#define HPB_DMAE_ASYNCMDR_ASBTMD22_MASK		BIT(4)	/* SDHI0 */
-#define HPB_DMAE_ASYNCMDR_ASBTMD22_BURST	BIT(4)	/* SDHI0 */
-#define HPB_DMAE_ASYNCMDR_ASBTMD22_NBURST	0	/* SDHI0 */
-#define HPB_DMAE_ASYNCMDR_ASMD21_MASK		BIT(3)	/* SDHI0 */
-#define HPB_DMAE_ASYNCMDR_ASMD21_SINGLE		BIT(3)	/* SDHI0 */
-#define HPB_DMAE_ASYNCMDR_ASMD21_MULTI		0	/* SDHI0 */
-#define HPB_DMAE_ASYNCMDR_ASBTMD21_MASK		BIT(2)	/* SDHI0 */
-#define HPB_DMAE_ASYNCMDR_ASBTMD21_BURST	BIT(2)	/* SDHI0 */
-#define HPB_DMAE_ASYNCMDR_ASBTMD21_NBURST	0	/* SDHI0 */
-#define HPB_DMAE_ASYNCMDR_ASMD20_MASK		BIT(1)	/* SDHI1 */
-#define HPB_DMAE_ASYNCMDR_ASMD20_SINGLE		BIT(1)	/* SDHI1 */
-#define HPB_DMAE_ASYNCMDR_ASMD20_MULTI		0	/* SDHI1 */
-#define HPB_DMAE_ASYNCMDR_ASBTMD20_MASK		BIT(0)	/* SDHI1 */
-#define HPB_DMAE_ASYNCMDR_ASBTMD20_BURST	BIT(0)	/* SDHI1 */
-#define HPB_DMAE_ASYNCMDR_ASBTMD20_NBURST	0	/* SDHI1 */
-
-static const struct hpb_dmae_slave_config hpb_dmae_slaves[] = {
-	{
-		.id	= HPBDMA_SLAVE_SDHI0_TX,
-		.addr	= 0xffe4c000 + 0x30,
-		.dcr	= HPB_DMAE_DCR_SPDS_16BIT |
-			  HPB_DMAE_DCR_DMDL |
-			  HPB_DMAE_DCR_DPDS_16BIT,
-		.rstr	= HPB_DMAE_ASYNCRSTR_ASRST21 |
-			  HPB_DMAE_ASYNCRSTR_ASRST22 |
-			  HPB_DMAE_ASYNCRSTR_ASRST23,
-		.mdr	= HPB_DMAE_ASYNCMDR_ASMD21_SINGLE |
-			  HPB_DMAE_ASYNCMDR_ASBTMD21_NBURST,
-		.mdm	= HPB_DMAE_ASYNCMDR_ASMD21_MASK |
-			  HPB_DMAE_ASYNCMDR_ASBTMD21_MASK,
-		.port	= 0x0D0C,
-		.flags	= HPB_DMAE_SET_ASYNC_RESET | HPB_DMAE_SET_ASYNC_MODE,
-		.dma_ch	= 21,
-	}, {
-		.id	= HPBDMA_SLAVE_SDHI0_RX,
-		.addr	= 0xffe4c000 + 0x30,
-		.dcr	= HPB_DMAE_DCR_SMDL |
-			  HPB_DMAE_DCR_SPDS_16BIT |
-			  HPB_DMAE_DCR_DPDS_16BIT,
-		.rstr	= HPB_DMAE_ASYNCRSTR_ASRST21 |
-			  HPB_DMAE_ASYNCRSTR_ASRST22 |
-			  HPB_DMAE_ASYNCRSTR_ASRST23,
-		.mdr	= HPB_DMAE_ASYNCMDR_ASMD22_SINGLE |
-			  HPB_DMAE_ASYNCMDR_ASBTMD22_NBURST,
-		.mdm	= HPB_DMAE_ASYNCMDR_ASMD22_MASK |
-			  HPB_DMAE_ASYNCMDR_ASBTMD22_MASK,
-		.port	= 0x0D0C,
-		.flags	= HPB_DMAE_SET_ASYNC_RESET | HPB_DMAE_SET_ASYNC_MODE,
-		.dma_ch	= 22,
-	},
-};
-
-static const struct hpb_dmae_channel hpb_dmae_channels[] = {
-	HPB_DMAE_CHANNEL(0x93, HPBDMA_SLAVE_SDHI0_TX), /* ch. 21 */
-	HPB_DMAE_CHANNEL(0x93, HPBDMA_SLAVE_SDHI0_RX), /* ch. 22 */
-};
-
-static struct hpb_dmae_pdata dma_platform_data __initdata = {
-	.slaves			= hpb_dmae_slaves,
-	.num_slaves		= ARRAY_SIZE(hpb_dmae_slaves),
-	.channels		= hpb_dmae_channels,
-	.num_channels		= ARRAY_SIZE(hpb_dmae_channels),
-	.ts_shift		= {
-		[XMIT_SZ_8BIT]	= 0,
-		[XMIT_SZ_16BIT]	= 1,
-		[XMIT_SZ_32BIT]	= 2,
-	},
-	.num_hw_channels	= 44,
-};
-
-static struct resource hpb_dmae_resources[] __initdata = {
-	/* Channel registers */
-	DEFINE_RES_MEM(0xffc08000, 0x1000),
-	/* Common registers */
-	DEFINE_RES_MEM(0xffc09000, 0x170),
-	/* Asynchronous reset registers */
-	DEFINE_RES_MEM(0xffc00300, 4),
-	/* Asynchronous mode registers */
-	DEFINE_RES_MEM(0xffc00400, 4),
-	/* IRQ for DMA channels */
-	DEFINE_RES_NAMED(gic_iid(0x8e), 12, NULL, IORESOURCE_IRQ),
-};
-
-static void __init r8a7779_register_hpb_dmae(void)
-{
-	platform_device_register_resndata(NULL, "hpb-dma-engine",
-					  -1, hpb_dmae_resources,
-					  ARRAY_SIZE(hpb_dmae_resources),
-					  &dma_platform_data,
-					  sizeof(dma_platform_data));
-}
-
-static struct platform_device *r8a7779_early_devices[] __initdata = {
-	&tmu0_device,
-};
-
-static struct platform_device *r8a7779_standard_devices[] __initdata = {
-	&scif0_device,
-	&scif1_device,
-	&scif2_device,
-	&scif3_device,
-	&scif4_device,
-	&scif5_device,
-	&i2c0_device,
-	&i2c1_device,
-	&i2c2_device,
-	&i2c3_device,
-	&sata_device,
-};
-
-void __init r8a7779_add_standard_devices(void)
-{
-#ifdef CONFIG_CACHE_L2X0
-	/* Shared attribute override enable, 64K*16way */
-	l2x0_init(IOMEM(0xf0100000), 0x00400000, 0xc20f0fff);
-#endif
-	r8a7779_pm_init();
-
-	r8a7779_init_pm_domains();
-
-	platform_add_devices(r8a7779_early_devices,
-			    ARRAY_SIZE(r8a7779_early_devices));
-	platform_add_devices(r8a7779_standard_devices,
-			    ARRAY_SIZE(r8a7779_standard_devices));
-	r8a7779_register_hpb_dmae();
-}
-
-void __init r8a7779_add_early_devices(void)
-{
-	early_platform_add_devices(r8a7779_early_devices,
-				   ARRAY_SIZE(r8a7779_early_devices));
-
-	/* Early serial console setup is not included here due to
-	 * memory map collisions. The SCIF serial ports in r8a7779
-	 * are difficult to identity map 1:1 due to collision with the
-	 * virtual memory range used by the coherent DMA code on ARM.
-	 *
-	 * Anyone wanting to debug early can remove UPF_IOREMAP from
-	 * the sh-sci serial console platform data, adjust mapbase
-	 * to a static M:N virt:phys mapping that needs to be added to
-	 * the mappings passed with iotable_init() above.
-	 *
-	 * Then add a call to shmobile_setup_console() from this function.
-	 *
-	 * As a final step pass earlyprint=sh-sci.2,115200 on the kernel
-	 * command line in case of the marzen board.
-	 */
-}
-
-static struct platform_device *r8a7779_late_devices[] __initdata = {
-	&ehci0_device,
-	&ehci1_device,
-	&ohci0_device,
-	&ohci1_device,
-};
-
-void __init r8a7779_init_late(void)
-{
-	/* get USB PHY */
-	phy = usb_get_phy(USB_PHY_TYPE_USB2);
-
-	shmobile_init_late();
-	platform_add_devices(r8a7779_late_devices,
-			     ARRAY_SIZE(r8a7779_late_devices));
-}
-
-#ifdef CONFIG_USE_OF
-void __init r8a7779_init_irq_dt(void)
-{
-#ifdef CONFIG_ARCH_SHMOBILE_LEGACY
-	void __iomem *gic_dist_base = ioremap_nocache(0xf0001000, 0x1000);
-	void __iomem *gic_cpu_base = ioremap_nocache(0xf0000100, 0x1000);
-#endif
 	gic_set_irqchip_flags(IRQCHIP_SKIP_SET_WAKE);
 
-#ifdef CONFIG_ARCH_SHMOBILE_LEGACY
-	gic_init(0, 29, gic_dist_base, gic_cpu_base);
-#else
 	irqchip_init();
-#endif
+
 	/* route all interrupts to ARM */
 	__raw_writel(0xffffffff, INT2NTSR0);
 	__raw_writel(0x3fffffff, INT2NTSR1);
@@ -742,7 +80,7 @@ void __init r8a7779_init_irq_dt(void)
 
 #define MODEMR		0xffcc0020
 
-u32 __init r8a7779_read_mode_pins(void)
+static u32 __init r8a7779_read_mode_pins(void)
 {
 	static u32 mode;
 	static bool mode_valid;
@@ -758,8 +96,6 @@ u32 __init r8a7779_read_mode_pins(void)
 	return mode;
 }
 
-#ifdef CONFIG_ARCH_SHMOBILE_MULTI
-
 static void __init r8a7779_init_time(void)
 {
 	r8a7779_clocks_init(r8a7779_read_mode_pins());
@@ -780,5 +116,3 @@ DT_MACHINE_START(R8A7779_DT, "Generic R8A7779 (Flattened Device Tree)")
 	.init_late	= shmobile_init_late,
 	.dt_compat	= r8a7779_compat_dt,
 MACHINE_END
-#endif /* CONFIG_ARCH_SHMOBILE_MULTI */
-#endif /* CONFIG_USE_OF */
diff --git a/arch/arm/mach-shmobile/smp-r8a7779.c b/arch/arm/mach-shmobile/smp-r8a7779.c
index 01f792fcb220..6756ada34bc0 100644
--- a/arch/arm/mach-shmobile/smp-r8a7779.c
+++ b/arch/arm/mach-shmobile/smp-r8a7779.c
@@ -23,7 +23,6 @@
 #include <asm/cacheflush.h>
 #include <asm/smp_plat.h>
 #include <asm/smp_scu.h>
-#include <asm/smp_twd.h>
 
 #include "common.h"
 #include "pm-rcar.h"
@@ -56,14 +55,6 @@ static struct rcar_sysc_ch *r8a7779_ch_cpu[4] = {
 	[3] = &r8a7779_ch_cpu3,
 };
 
-#if defined(CONFIG_HAVE_ARM_TWD) && !defined(CONFIG_ARCH_MULTIPLATFORM)
-static DEFINE_TWD_LOCAL_TIMER(twd_local_timer, R8A7779_SCU_BASE + 0x600, 29);
-void __init r8a7779_register_twd(void)
-{
-	twd_local_timer_register(&twd_local_timer);
-}
-#endif
-
 static int r8a7779_platform_cpu_kill(unsigned int cpu)
 {
 	struct rcar_sysc_ch *ch = NULL;
-- 
2.1.4



From yh.huang at mediatek.com  Sun Aug  2 23:21:32 2015
From: yh.huang at mediatek.com (YH Huang)
Date: Mon, 3 Aug 2015 14:21:32 +0800
Subject: [PATCH v6 0/3] Add MediaTek display PWM driver
In-Reply-To: <1437729058.11386.4.camel@mtksdaap41>
References: <1437380237-28961-1-git-send-email-yh.huang@mediatek.com>
 <2181696.fQcvS98Cqx@ubix> <1437729058.11386.4.camel@mtksdaap41>
Message-ID: <1438582892.19953.4.camel@mtksdaap41>

On Fri, 2015-07-24 at 17:10 +0800, YH Huang wrote:
> On Fri, 2015-07-24 at 10:42 +0200, Matthias Brugger wrote:
> > On Monday, July 20, 2015 04:17:14 PM YH Huang wrote:
> > > This patch series add the use of display PWM driver, documentation
> > > and device tree for Mediatek SoCs. The driver is used to support
> > > the backlight of the panel. This is based on v4.2-rc1.
> > > 
> > > The clock definitions (CLK_MM_DISP_PWM*) are added by James Liao's patch:
> > > clk: mediatek: Add subsystem clocks of MT8173
> > > 
> > > Change in v6:
> > > 1. Enable clocks in the pwm_enable function
> > > 2. Remove suspend/resume code since pwm-backlight driver has done the same
> > > things 3. Revise some code to make it easier to read
> > > 
> > 
> > Can you please provide the whole change log for all versions the next time.
> > It's easier this way to understand the evolution of the series.
> 
> Change in v6:
> 1. Enable clocks in the pwm_enable function.
> 2. Remove suspend/resume code since pwm-backlight driver has done the
> same things.
> 3. Revise some code to make it easier to read.
> 
> Change in v5:
> 1. Configure PWM output via pinctrl.
> 2. Fix the parameter name in dtsi.
> 
> Change in v4:
> 1. Codebase is on v4.2-rc1.
> 2. Add the PWM node in dtsi.
> 3. Change the dependency in Kconfig.
> 4. Rewrite some code for readability.
> 
> Change in v3:
> 1. Add suspend/resume function.
> 2. Fix the formula for high_width calculation.
> 3. Rewrite some code to make it easier to read.
> 4. Add more information in the commit message.
> 
> Change in v2:
> 1. Rewrite descriptions for driver in kconfig to make it much clear.
> 2. Rename the driver from "pwm-mediatek-disp" to "pwm-mtk-disp".
> 3. Disable clocks in the error path.
> 4. Change the shift values in decimal instead of hex.
> 5. Rename and add some variables or function name for consistency and
> readability.
> 6. Drop unnecessary parentheses, spaces, variables and add newlines to
> make the code easiler to read.
> 
> Thanks for your suggestion.

Hi Thierry,

Do you have any suggestions?
Maybe we could apply the patch?

Regards,
YH Huang



From josh.wu at atmel.com  Sun Aug  2 23:40:18 2015
From: josh.wu at atmel.com (Josh Wu)
Date: Mon, 3 Aug 2015 14:40:18 +0800
Subject: [RFC PATCH 2/3] ARM: at91/dt: add sama5d2 pinmux
In-Reply-To: <1438355290-28255-3-git-send-email-ludovic.desroches@atmel.com>
References: <1438355290-28255-1-git-send-email-ludovic.desroches@atmel.com>
 <1438355290-28255-3-git-send-email-ludovic.desroches@atmel.com>
Message-ID: <55BF0CD2.5030204@atmel.com>

Hi, Ludovic

On 7/31/2015 11:08 PM, Ludovic Desroches wrote:
> Signed-off-by: Ludovic Desroches <ludovic.desroches at atmel.com>
> ---
>   arch/arm/boot/dts/sama5d2-pinfunc.h | 760 ++++++++++++++++++++++++++++++++++++
>   1 file changed, 760 insertions(+)
>   create mode 100644 arch/arm/boot/dts/sama5d2-pinfunc.h
>
> diff --git a/arch/arm/boot/dts/sama5d2-pinfunc.h b/arch/arm/boot/dts/sama5d2-pinfunc.h
> new file mode 100644
> index 0000000..046d1d5
> --- /dev/null
> +++ b/arch/arm/boot/dts/sama5d2-pinfunc.h
>

[snip...]

> +#define PIN_PB24__FLEXCOM3_IO3		PINMUX_PIN(PIN_PB24, 5, 3)
> +#define PIN_PB24__ISI_D10		PINMUX_PIN(PIN_PB24, 6, 3)

As sama5d2 use ISC, so It's better to run  s/ISI_/ISC_/ in this file, 
which is consistent with the datasheet.

Best Regards,
Josh Wu



From p.fedin at samsung.com  Sun Aug  2 23:41:33 2015
From: p.fedin at samsung.com (Pavel Fedin)
Date: Mon, 03 Aug 2015 09:41:33 +0300
Subject: [PATCH v2 14/15] KVM: arm64: implement MSI injection in ITS
 emulation
In-Reply-To: <55BE7BA1.40403@arm.com>
References: <1436538111-4294-1-git-send-email-andre.przywara@arm.com>
 <1436538111-4294-15-git-send-email-andre.przywara@arm.com>
 <55BB7678.5080105@linaro.org> <55BE7BA1.40403@arm.com>
Message-ID: <00a201d0cdb7$70a623f0$51f26bd0$@samsung.com>

 Hi!

> When I reworked our code to only use a flag and not a separate routing
> type I ended up with the flag only guarding assignments, which wouldn't
> hurt if done unconditionally (since they are all u32's). So the whole
> usage of the flag is somewhat in jeopardy now.
> Either the eventual MSI consumer requires a DevID (ITS emulation, which
> will not work without it) or the consumer does not care at all and can
> totally ignore it (GICv2m). So I think we can always pass on the DevID

 I have just checked my current code, and you know what... You are right. We already have a per-VM
capability which actually tells us that MSIs for this VM require devID. Therefore, we really don't
need this flag at all, neither for MSI doorbell, nor for GSI routing.
 All we need is 'devid' field, which indeed can be just ignored for GICv2(m), just for simplicity.
Ignoring would happen automatically, because IIRC older kernels do not explicitly check 'pad' for
being zero, do they? And indeed in this case the userland can supply devid unconditionally, making
things even simpler.

Kind regards,
Pavel Fedin
Expert Engineer
Samsung Electronics Research center Russia




From ludovic.desroches at atmel.com  Sun Aug  2 23:59:15 2015
From: ludovic.desroches at atmel.com (Ludovic Desroches)
Date: Mon, 3 Aug 2015 08:59:15 +0200
Subject: [RFC PATCH 2/3] ARM: at91/dt: add sama5d2 pinmux
In-Reply-To: <55BF0CD2.5030204@atmel.com>
References: <1438355290-28255-1-git-send-email-ludovic.desroches@atmel.com>
 <1438355290-28255-3-git-send-email-ludovic.desroches@atmel.com>
 <55BF0CD2.5030204@atmel.com>
Message-ID: <20150803065915.GF4055@odux.rfo.atmel.com>

Hi Josh,

On Mon, Aug 03, 2015 at 02:40:18PM +0800, Josh Wu wrote:
> Hi, Ludovic
> 
> On 7/31/2015 11:08 PM, Ludovic Desroches wrote:
> >Signed-off-by: Ludovic Desroches <ludovic.desroches at atmel.com>
> >---
> >  arch/arm/boot/dts/sama5d2-pinfunc.h | 760 ++++++++++++++++++++++++++++++++++++
> >  1 file changed, 760 insertions(+)
> >  create mode 100644 arch/arm/boot/dts/sama5d2-pinfunc.h
> >
> >diff --git a/arch/arm/boot/dts/sama5d2-pinfunc.h b/arch/arm/boot/dts/sama5d2-pinfunc.h
> >new file mode 100644
> >index 0000000..046d1d5
> >--- /dev/null
> >+++ b/arch/arm/boot/dts/sama5d2-pinfunc.h
> >
> 
> [snip...]
> 
> >+#define PIN_PB24__FLEXCOM3_IO3		PINMUX_PIN(PIN_PB24, 5, 3)
> >+#define PIN_PB24__ISI_D10		PINMUX_PIN(PIN_PB24, 6, 3)
> 
> As sama5d2 use ISC, so It's better to run  s/ISI_/ISC_/ in this file, which
> is consistent with the datasheet.
>

Ok, the one I used was a bit older and was still with ISI instead of
ISC. I'll update this file.

Regards

Ludovic


From zhaoshenglong at huawei.com  Sun Aug  2 23:59:57 2015
From: zhaoshenglong at huawei.com (Shannon Zhao)
Date: Mon, 3 Aug 2015 14:59:57 +0800
Subject: [PATCH 1/2] drivers: PL061: add support for platform driver probing
In-Reply-To: <1438585198-8764-1-git-send-email-zhaoshenglong@huawei.com>
References: <1438585198-8764-1-git-send-email-zhaoshenglong@huawei.com>
Message-ID: <1438585198-8764-2-git-send-email-zhaoshenglong@huawei.com>

From: Shannon Zhao <shannon.zhao at linaro.org>

Since PL061 currently only supports AMBA driver, to support using GPIO
PL061 by DT or ACPI, it needs to add support for platform driver.
A DT binding is provided with this patch, ACPI support is added in a
separate one.

Signed-off-by: Shannon Zhao <zhaoshenglong at huawei.com>
Signed-off-by: Shannon Zhao <shannon.zhao at linaro.org>
---
 drivers/gpio/gpio-pl061.c | 108 ++++++++++++++++++++++++++++++++++++++++++++++
 1 file changed, 108 insertions(+)

diff --git a/drivers/gpio/gpio-pl061.c b/drivers/gpio/gpio-pl061.c
index 0475613..64c10eb 100644
--- a/drivers/gpio/gpio-pl061.c
+++ b/drivers/gpio/gpio-pl061.c
@@ -24,6 +24,7 @@
 #include <linux/slab.h>
 #include <linux/pinctrl/consumer.h>
 #include <linux/pm.h>
+#include <linux/platform_device.h>
 
 #define GPIODIR 0x400
 #define GPIOIS  0x404
@@ -241,6 +242,94 @@ static struct irq_chip pl061_irqchip = {
 	.irq_set_type	= pl061_irq_type,
 };
 
+static int pl061_platform_probe(struct platform_device *pdev)
+{
+	struct device *dev = &pdev->dev;
+	struct pl061_platform_data *pdata = dev_get_platdata(dev);
+	struct pl061_gpio *chip;
+	int ret, irq, i, irq_base;
+	struct resource *mem;
+
+	mem = platform_get_resource(pdev, IORESOURCE_MEM, 0);
+	if (!mem)
+		return -EINVAL;
+
+	chip = devm_kzalloc(dev, sizeof(*chip), GFP_KERNEL);
+	if (chip == NULL)
+		return -ENOMEM;
+
+	if (pdata) {
+		chip->gc.base = pdata->gpio_base;
+		irq_base = pdata->irq_base;
+		if (irq_base <= 0) {
+			dev_err(&pdev->dev, "invalid IRQ base in pdata\n");
+			return -ENODEV;
+		}
+	} else {
+		chip->gc.base = -1;
+		irq_base = 0;
+	}
+
+	chip->base = devm_ioremap(dev, mem->start, resource_size(mem));
+	if (IS_ERR(chip->base))
+		return PTR_ERR(chip->base);
+
+	spin_lock_init(&chip->lock);
+	if (of_property_read_bool(dev->of_node, "gpio-ranges"))
+		chip->uses_pinctrl = true;
+
+	chip->gc.request = pl061_gpio_request;
+	chip->gc.free = pl061_gpio_free;
+	chip->gc.direction_input = pl061_direction_input;
+	chip->gc.direction_output = pl061_direction_output;
+	chip->gc.get = pl061_get_value;
+	chip->gc.set = pl061_set_value;
+	chip->gc.ngpio = PL061_GPIO_NR;
+	chip->gc.label = dev_name(dev);
+	chip->gc.dev = dev;
+	chip->gc.owner = THIS_MODULE;
+
+	ret = gpiochip_add(&chip->gc);
+	if (ret)
+		return ret;
+
+	/*
+	 * irq_chip support
+	 */
+	writeb(0, chip->base + GPIOIE); /* disable irqs */
+	irq = platform_get_irq(pdev, 0);
+	if (irq < 0) {
+		dev_err(&pdev->dev, "invalid IRQ\n");
+		return -ENODEV;
+	}
+
+	ret = gpiochip_irqchip_add(&chip->gc, &pl061_irqchip,
+				   irq_base, handle_simple_irq,
+				   IRQ_TYPE_NONE);
+	if (ret) {
+		dev_info(&pdev->dev, "could not add irqchip\n");
+		return ret;
+	}
+	gpiochip_set_chained_irqchip(&chip->gc, &pl061_irqchip,
+				     irq, pl061_irq_handler);
+
+	for (i = 0; i < PL061_GPIO_NR; i++) {
+		if (pdata) {
+			if (pdata->directions & (BIT(i)))
+				pl061_direction_output(&chip->gc, i,
+						pdata->values & (BIT(i)));
+			else
+				pl061_direction_input(&chip->gc, i);
+		}
+	}
+
+	platform_set_drvdata(pdev, chip);
+	dev_info(&pdev->dev, "PL061 GPIO chip @%pa registered\n",
+		 &mem->start);
+
+	return 0;
+}
+
 static int pl061_probe(struct amba_device *adev, const struct amba_id *id)
 {
 	struct device *dev = &adev->dev;
@@ -376,6 +465,23 @@ static const struct dev_pm_ops pl061_dev_pm_ops = {
 };
 #endif
 
+static const struct of_device_id pl061_of_match[] = {
+	{ .compatible = "arm,pl061", },
+	{},
+};
+MODULE_DEVICE_TABLE(of, pl061_of_match);
+
+static struct platform_driver pl061_gpio_platform_driver = {
+	.driver = {
+		.name	= "pl061_gpio",
+		.of_match_table	= pl061_of_match,
+#ifdef CONFIG_PM
+		.pm	= &pl061_dev_pm_ops,
+#endif
+	},
+	.probe		= pl061_platform_probe,
+};
+
 static struct amba_id pl061_ids[] = {
 	{
 		.id	= 0x00041061,
@@ -399,6 +505,8 @@ static struct amba_driver pl061_gpio_driver = {
 
 static int __init pl061_gpio_init(void)
 {
+	if (platform_driver_register(&pl061_gpio_platform_driver))
+		pr_warn("could not register PL061 platform driver\n");
 	return amba_driver_register(&pl061_gpio_driver);
 }
 module_init(pl061_gpio_init);
-- 
2.0.4




From zhaoshenglong at huawei.com  Sun Aug  2 23:59:56 2015
From: zhaoshenglong at huawei.com (Shannon Zhao)
Date: Mon, 3 Aug 2015 14:59:56 +0800
Subject: [PATCH 0/2] drivers: PL061: Add platform driver probing support
Message-ID: <1438585198-8764-1-git-send-email-zhaoshenglong@huawei.com>

From: Shannon Zhao <shannon.zhao at linaro.org>

According to ACPI SPEC, it supports ARM boards to use "GPIO-signaled
ACPI Events". These events can be used for input events. And to QEMU, it
uses GPIO PL061 controller for input events.

These two patches add platform driver support for PL061 probed by DT or
ACPI.

Shannon Zhao (2):
  drivers: PL061: add support for platform driver probing
  drivers: PL061: add ACPI probing for PL061

 drivers/gpio/gpio-pl061.c | 116 ++++++++++++++++++++++++++++++++++++++++++++++
 1 file changed, 116 insertions(+)

-- 
2.0.4




From zhaoshenglong at huawei.com  Sun Aug  2 23:59:58 2015
From: zhaoshenglong at huawei.com (Shannon Zhao)
Date: Mon, 3 Aug 2015 14:59:58 +0800
Subject: [PATCH 2/2] drivers: PL061: add ACPI probing for PL061
In-Reply-To: <1438585198-8764-1-git-send-email-zhaoshenglong@huawei.com>
References: <1438585198-8764-1-git-send-email-zhaoshenglong@huawei.com>
Message-ID: <1438585198-8764-3-git-send-email-zhaoshenglong@huawei.com>

From: Shannon Zhao <shannon.zhao at linaro.org>

Add the necessary driver boilerplate to let the driver be used when
the respective ACPI table is discovered by the ACPI subsystem.

Signed-off-by: Shannon Zhao <zhaoshenglong at huawei.com>
Signed-off-by: Shannon Zhao <shannon.zhao at linaro.org>
---
 drivers/gpio/gpio-pl061.c | 8 ++++++++
 1 file changed, 8 insertions(+)

diff --git a/drivers/gpio/gpio-pl061.c b/drivers/gpio/gpio-pl061.c
index 64c10eb..41fcf7b 100644
--- a/drivers/gpio/gpio-pl061.c
+++ b/drivers/gpio/gpio-pl061.c
@@ -25,6 +25,7 @@
 #include <linux/pinctrl/consumer.h>
 #include <linux/pm.h>
 #include <linux/platform_device.h>
+#include <linux/acpi.h>
 
 #define GPIODIR 0x400
 #define GPIOIS  0x404
@@ -471,10 +472,17 @@ static const struct of_device_id pl061_of_match[] = {
 };
 MODULE_DEVICE_TABLE(of, pl061_of_match);
 
+static const struct acpi_device_id pl061_acpi_match[] = {
+	{ "ARMH0061",},
+	{ }
+};
+MODULE_DEVICE_TABLE(acpi, pl061_acpi_match);
+
 static struct platform_driver pl061_gpio_platform_driver = {
 	.driver = {
 		.name	= "pl061_gpio",
 		.of_match_table	= pl061_of_match,
+		.acpi_match_table = ACPI_PTR(pl061_acpi_match),
 #ifdef CONFIG_PM
 		.pm	= &pl061_dev_pm_ops,
 #endif
-- 
2.0.4




From linus.walleij at linaro.org  Mon Aug  3 00:08:39 2015
From: linus.walleij at linaro.org (Linus Walleij)
Date: Mon, 3 Aug 2015 09:08:39 +0200
Subject: [PATCH] ARM: ux500: fix ux500 secondary CPU boot regression
In-Reply-To: <20150731110353.GV7557@n2100.arm.linux.org.uk>
References: <1438331874-1682-1-git-send-email-linus.walleij@linaro.org>
 <20150731110353.GV7557@n2100.arm.linux.org.uk>
Message-ID: <CACRpkdbEMM17zHDoUwsPFC2c=8UU_oHa6S3=VkBw7_-Or=wGow@mail.gmail.com>

On Fri, Jul 31, 2015 at 1:03 PM, Russell King - ARM Linux
<linux at arm.linux.org.uk> wrote:
> On Fri, Jul 31, 2015 at 10:37:54AM +0200, Linus Walleij wrote:
>> +     scu_desc.pfn = __phys_to_pfn(res.start);
>> +     scu_desc.length = resource_size(&res);
>> +     iotable_init(&scu_desc, 1);
>> +     /* As in devicemaps_init() */
>> +     local_flush_tlb_all();
>> +     flush_cache_all();
>
> I don't like stuff moving out of the well-defined methods where it should
> be done - it makes maintanence of the arch code harder to have platforms
> going off and doing their own stuff in random other methods.
>
> IOW, setting up mappings in this way should only be in the ->map_io method.

OK I have the better fix which is a bit more invasive (fixes device tree
and deletes the while pen hold/release and headsmp.S code chunk) but
then maybe we should just apply that instead.

Yours,
Linus Walleij


From linus.walleij at linaro.org  Mon Aug  3 00:26:41 2015
From: linus.walleij at linaro.org (Linus Walleij)
Date: Mon,  3 Aug 2015 09:26:41 +0200
Subject: [PATCH 1/2] ARM: ux500: add an SMP enablement type and move cpu nodes
Message-ID: <1438586801-30115-1-git-send-email-linus.walleij@linaro.org>

The "cpus" node cannot be inside the "soc" node, while this
works for the CoreSight blocks, the early boot code will look
for "cpus" directly under the root node, so this is a hard
convention. So move the CPU nodes.

Augment the "reg" property to match what is actually in the
hardware: 0x300 and 0x301 respectively.

Then add an SMP enablement type to be used by the SMP init
code, "ste,dbx500-smp".

Signed-off-by: Linus Walleij <linus.walleij at linaro.org>
---
Hi ARM SoC people: please apply this as a fix for v4.2
as it is prerequisite for 2/2 which is a more proper fix
for the secondary CPU boot regression addressed by the
fixed remappings patch.
---
 Documentation/devicetree/bindings/arm/cpus.txt |  1 +
 arch/arm/boot/dts/ste-dbx5x0.dtsi              | 53 +++++++++++++-------------
 2 files changed, 28 insertions(+), 26 deletions(-)

diff --git a/Documentation/devicetree/bindings/arm/cpus.txt b/Documentation/devicetree/bindings/arm/cpus.txt
index d6b794cef0b8..91e6e5c478d0 100644
--- a/Documentation/devicetree/bindings/arm/cpus.txt
+++ b/Documentation/devicetree/bindings/arm/cpus.txt
@@ -199,6 +199,7 @@ nodes to be present and contain the properties described below.
 			    "qcom,kpss-acc-v1"
 			    "qcom,kpss-acc-v2"
 			    "rockchip,rk3066-smp"
+			    "ste,dbx500-smp"
 
 	- cpu-release-addr
 		Usage: required for systems that have an "enable-method"
diff --git a/arch/arm/boot/dts/ste-dbx5x0.dtsi b/arch/arm/boot/dts/ste-dbx5x0.dtsi
index a75f3289e653..b8f81fb418ce 100644
--- a/arch/arm/boot/dts/ste-dbx5x0.dtsi
+++ b/arch/arm/boot/dts/ste-dbx5x0.dtsi
@@ -15,6 +15,33 @@
 #include "skeleton.dtsi"
 
 / {
+	cpus {
+		#address-cells = <1>;
+		#size-cells = <0>;
+		enable-method = "ste,dbx500-smp";
+
+		cpu-map {
+			cluster0 {
+				core0 {
+					cpu = <&CPU0>;
+				};
+				core1 {
+					cpu = <&CPU1>;
+				};
+			};
+		};
+		CPU0: cpu at 300 {
+			device_type = "cpu";
+			compatible = "arm,cortex-a9";
+			reg = <0x300>;
+		};
+		CPU1: cpu at 301 {
+			device_type = "cpu";
+			compatible = "arm,cortex-a9";
+			reg = <0x301>;
+		};
+	};
+
 	soc {
 		#address-cells = <1>;
 		#size-cells = <1>;
@@ -22,32 +49,6 @@
 		interrupt-parent = <&intc>;
 		ranges;
 
-		cpus {
-			#address-cells = <1>;
-			#size-cells = <0>;
-
-			cpu-map {
-				cluster0 {
-					core0 {
-						cpu = <&CPU0>;
-					};
-					core1 {
-						cpu = <&CPU1>;
-					};
-				};
-			};
-			CPU0: cpu at 0 {
-				device_type = "cpu";
-				compatible = "arm,cortex-a9";
-				reg = <0>;
-			};
-			CPU1: cpu at 1 {
-				device_type = "cpu";
-				compatible = "arm,cortex-a9";
-				reg = <1>;
-			};
-		};
-
 		ptm at 801ae000 {
 			compatible = "arm,coresight-etm3x", "arm,primecell";
 			reg = <0x801ae000 0x1000>;
-- 
2.4.3



From linus.walleij at linaro.org  Mon Aug  3 00:26:52 2015
From: linus.walleij at linaro.org (Linus Walleij)
Date: Mon,  3 Aug 2015 09:26:52 +0200
Subject: [PATCH 2/2] ARM: ux500: simplify secondary CPU boot
Message-ID: <1438586812-30164-1-git-send-email-linus.walleij@linaro.org>

This removes a lot of ancient cruft from the Ux500 SMP boot.
Instead of the pen grab/release, just point the ROM to
secondary_boot() and start the second CPU there, then send
the IPI.

Use our own SMP enable method. This enables us to remove the
last static mapping and get both CPUs booting properly.

Tested this and it just works.

Signed-off-by: Linus Walleij <linus.walleij at linaro.org>
---
Hi ARM SoC folks: please apply this to fixes for v4.2. I was
intending it for v4.3 but we might as well just kill off the
legacy boot method right now so we do not need to restore any
static maps and undo the cleanup (which would be just as
invasive).
---
 arch/arm/mach-ux500/Makefile     |   2 +-
 arch/arm/mach-ux500/cpu-db8500.c |   1 -
 arch/arm/mach-ux500/headsmp.S    |  37 -----------
 arch/arm/mach-ux500/platsmp.c    | 132 ++++++++++++---------------------------
 arch/arm/mach-ux500/setup.h      |   1 -
 5 files changed, 40 insertions(+), 133 deletions(-)
 delete mode 100644 arch/arm/mach-ux500/headsmp.S

diff --git a/arch/arm/mach-ux500/Makefile b/arch/arm/mach-ux500/Makefile
index 4418a5078833..c8643ac5db71 100644
--- a/arch/arm/mach-ux500/Makefile
+++ b/arch/arm/mach-ux500/Makefile
@@ -7,7 +7,7 @@ obj-$(CONFIG_CACHE_L2X0)	+= cache-l2x0.o
 obj-$(CONFIG_UX500_SOC_DB8500)	+= cpu-db8500.o
 obj-$(CONFIG_MACH_MOP500)	+= board-mop500-regulators.o \
 				board-mop500-audio.o
-obj-$(CONFIG_SMP)		+= platsmp.o headsmp.o
+obj-$(CONFIG_SMP)		+= platsmp.o
 obj-$(CONFIG_HOTPLUG_CPU)	+= hotplug.o
 obj-$(CONFIG_PM_GENERIC_DOMAINS) += pm_domains.o
 
diff --git a/arch/arm/mach-ux500/cpu-db8500.c b/arch/arm/mach-ux500/cpu-db8500.c
index 16913800bbf9..ba708ce08616 100644
--- a/arch/arm/mach-ux500/cpu-db8500.c
+++ b/arch/arm/mach-ux500/cpu-db8500.c
@@ -154,7 +154,6 @@ static const char * stericsson_dt_platform_compat[] = {
 };
 
 DT_MACHINE_START(U8500_DT, "ST-Ericsson Ux5x0 platform (Device Tree Support)")
-	.smp            = smp_ops(ux500_smp_ops),
 	.map_io		= u8500_map_io,
 	.init_irq	= ux500_init_irq,
 	/* we re-use nomadik timer here */
diff --git a/arch/arm/mach-ux500/headsmp.S b/arch/arm/mach-ux500/headsmp.S
deleted file mode 100644
index 9cdea049485d..000000000000
--- a/arch/arm/mach-ux500/headsmp.S
+++ /dev/null
@@ -1,37 +0,0 @@
-/*
- *  Copyright (c) 2009 ST-Ericsson
- *	This file is based  ARM Realview platform
- *  Copyright (c) 2003 ARM Limited
- *  All Rights Reserved
- *
- * This program is free software; you can redistribute it and/or modify
- * it under the terms of the GNU General Public License version 2 as
- * published by the Free Software Foundation.
- */
-#include <linux/linkage.h>
-#include <linux/init.h>
-
-/*
- * U8500 specific entry point for secondary CPUs.
- */
-ENTRY(u8500_secondary_startup)
-	mrc	p15, 0, r0, c0, c0, 5
-	and	r0, r0, #15
-	adr	r4, 1f
-	ldmia	r4, {r5, r6}
-	sub	r4, r4, r5
-	add	r6, r6, r4
-pen:	ldr	r7, [r6]
-	cmp	r7, r0
-	bne	pen
-
-	/*
-	 * we've been released from the holding pen: secondary_stack
-	 * should now contain the SVC stack for this core
-	 */
-	b	secondary_startup
-ENDPROC(u8500_secondary_startup)
-
-	.align 2
-1:	.long	.
-	.long	pen_release
diff --git a/arch/arm/mach-ux500/platsmp.c b/arch/arm/mach-ux500/platsmp.c
index 62b1de922bd8..70766b963758 100644
--- a/arch/arm/mach-ux500/platsmp.c
+++ b/arch/arm/mach-ux500/platsmp.c
@@ -28,135 +28,81 @@
 #include "db8500-regs.h"
 #include "id.h"
 
-static void __iomem *scu_base;
-static void __iomem *backupram;
-
-/* This is called from headsmp.S to wakeup the secondary core */
-extern void u8500_secondary_startup(void);
-
-/*
- * Write pen_release in a way that is guaranteed to be visible to all
- * observers, irrespective of whether they're taking part in coherency
- * or not.  This is necessary for the hotplug code to work reliably.
- */
-static void write_pen_release(int val)
-{
-	pen_release = val;
-	smp_wmb();
-	sync_cache_w(&pen_release);
-}
-
-static DEFINE_SPINLOCK(boot_lock);
-
-static void ux500_secondary_init(unsigned int cpu)
-{
-	/*
-	 * let the primary processor know we're out of the
-	 * pen, then head off into the C entry point
-	 */
-	write_pen_release(-1);
-
-	/*
-	 * Synchronise with the boot thread.
-	 */
-	spin_lock(&boot_lock);
-	spin_unlock(&boot_lock);
-}
+/* Magic triggers in backup RAM */
+#define UX500_CPU1_JUMPADDR_OFFSET 0x1FF4
+#define UX500_CPU1_WAKEMAGIC_OFFSET 0x1FF0
 
-static int ux500_boot_secondary(unsigned int cpu, struct task_struct *idle)
+static void wakeup_secondary(void)
 {
-	unsigned long timeout;
-
-	/*
-	 * set synchronisation state between this boot processor
-	 * and the secondary one
-	 */
-	spin_lock(&boot_lock);
-
-	/*
-	 * The secondary processor is waiting to be released from
-	 * the holding pen - release it, then wait for it to flag
-	 * that it has been released by resetting pen_release.
-	 */
-	write_pen_release(cpu_logical_map(cpu));
-
-	arch_send_wakeup_ipi_mask(cpumask_of(cpu));
+	struct device_node *np;
+	static void __iomem *backupram;
 
-	timeout = jiffies + (1 * HZ);
-	while (time_before(jiffies, timeout)) {
-		if (pen_release == -1)
-			break;
+	np = of_find_compatible_node(NULL, NULL, "ste,dbx500-backupram");
+	if (!np) {
+		pr_err("No backupram base address\n");
+		return;
+	}
+	backupram = of_iomap(np, 0);
+	of_node_put(np);
+	if (!backupram) {
+		pr_err("No backupram remap\n");
+		return;
 	}
 
 	/*
-	 * now the secondary core is starting up let it run its
-	 * calibrations, then wait for it to finish
-	 */
-	spin_unlock(&boot_lock);
-
-	return pen_release != -1 ? -ENOSYS : 0;
-}
-
-static void __init wakeup_secondary(void)
-{
-	/*
 	 * write the address of secondary startup into the backup ram register
 	 * at offset 0x1FF4, then write the magic number 0xA1FEED01 to the
 	 * backup ram register at offset 0x1FF0, which is what boot rom code
-	 * is waiting for. This would wake up the secondary core from WFE
+	 * is waiting for. This will wake up the secondary core from WFE.
 	 */
-#define UX500_CPU1_JUMPADDR_OFFSET 0x1FF4
-	__raw_writel(virt_to_phys(u8500_secondary_startup),
-		     backupram + UX500_CPU1_JUMPADDR_OFFSET);
-
-#define UX500_CPU1_WAKEMAGIC_OFFSET 0x1FF0
-	__raw_writel(0xA1FEED01,
-		     backupram + UX500_CPU1_WAKEMAGIC_OFFSET);
+	writel(virt_to_phys(secondary_startup),
+	       backupram + UX500_CPU1_JUMPADDR_OFFSET);
+	writel(0xA1FEED01,
+	       backupram + UX500_CPU1_WAKEMAGIC_OFFSET);
 
 	/* make sure write buffer is drained */
 	mb();
+	iounmap(backupram);
 }
 
-/*
- * Initialise the CPU possible map early - this describes the CPUs
- * which may be present or become present in the system.
- */
-static void __init ux500_smp_init_cpus(void)
+static void __init ux500_smp_prepare_cpus(unsigned int max_cpus)
 {
-	unsigned int i, ncores;
 	struct device_node *np;
+	static void __iomem *scu_base;
+	unsigned int ncores;
+	int i;
 
 	np = of_find_compatible_node(NULL, NULL, "arm,cortex-a9-scu");
+	if (!np) {
+		pr_err("No SCU base address\n");
+		return;
+	}
 	scu_base = of_iomap(np, 0);
 	of_node_put(np);
-	if (!scu_base)
+	if (!scu_base) {
+		pr_err("No SCU remap\n");
 		return;
-	backupram = ioremap(U8500_BACKUPRAM0_BASE, SZ_8K);
-	ncores = scu_get_core_count(scu_base);
-
-	/* 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;
 	}
 
+	scu_enable(scu_base);
+	ncores = scu_get_core_count(scu_base);
 	for (i = 0; i < ncores; i++)
 		set_cpu_possible(i, true);
+	iounmap(scu_base);
 }
 
-static void __init ux500_smp_prepare_cpus(unsigned int max_cpus)
+static int ux500_boot_secondary(unsigned int cpu, struct task_struct *idle)
 {
-	scu_enable(scu_base);
 	wakeup_secondary();
+	arch_send_wakeup_ipi_mask(cpumask_of(cpu));
+	return 0;
 }
 
 struct smp_operations ux500_smp_ops __initdata = {
-	.smp_init_cpus		= ux500_smp_init_cpus,
 	.smp_prepare_cpus	= ux500_smp_prepare_cpus,
-	.smp_secondary_init	= ux500_secondary_init,
 	.smp_boot_secondary	= ux500_boot_secondary,
 #ifdef CONFIG_HOTPLUG_CPU
 	.cpu_die		= ux500_cpu_die,
 #endif
 };
+CPU_METHOD_OF_DECLARE(ux500_smp, "ste,dbx500-smp", &ux500_smp_ops);
diff --git a/arch/arm/mach-ux500/setup.h b/arch/arm/mach-ux500/setup.h
index 1fb6ad2789f1..65876eac0761 100644
--- a/arch/arm/mach-ux500/setup.h
+++ b/arch/arm/mach-ux500/setup.h
@@ -26,7 +26,6 @@ extern struct device *ux500_soc_device_init(const char *soc_id);
 
 extern void ux500_timer_init(void);
 
-extern struct smp_operations ux500_smp_ops;
 extern void ux500_cpu_die(unsigned int cpu);
 
 #endif /*  __ASM_ARCH_SETUP_H */
-- 
2.4.3



From afenkart at gmail.com  Mon Aug  3 00:28:24 2015
From: afenkart at gmail.com (Andreas Fenkart)
Date: Mon, 3 Aug 2015 09:28:24 +0200
Subject: [PATCH 00/17] omap_hsmmc: regulator usage cleanup and fixes
In-Reply-To: <1438168187-1614-1-git-send-email-kishon@ti.com>
References: <1438168187-1614-1-git-send-email-kishon@ti.com>
Message-ID: <CALtMJEDP1-Q9W=x-0hq3tZQ1QZ2LVwVj47=ADYDjT7BsfanffA@mail.gmail.com>

Hi Kishon,

Thanks for taking a look at the regulator code. Do you have a public
git repository so I can pull your patches instead of cherry picking
1-by-1?

/Andi

2015-07-29 13:09 GMT+02:00 Kishon Vijay Abraham I <kishon at ti.com>:
> This patch series does the following
> *) Uses devm_regulator_get_optional() for vmmc and then removes the
>    CONFIG_REGULATOR check altogether.
> *) return on -EPROBE_DEFER
> *) enable/disable vmmc_aux regulator based on prior state
>
> This series is in preparation for implementing the voltage switch
> sequence so that UHS cards can be supported.
>
> Did basic read/write test in J6, J6 Eco, Beagle-x15, AM437x EVM,
> Beaglebone black, OMAP5 uEVM and OMAP4 PANDA.
>
> Kishon Vijay Abraham I (16):
>   mmc: host: omap_hsmmc: use devm_regulator_get_optional() for vmmc
>   mmc: host: omap_hsmmc: return error from omap_hsmmc_reg_get on
>     -EPROBE_DEFER
>   mmc: host: omap_hsmmc: cleanup omap_hsmmc_reg_get()
>   mmc: host: omap_hsmmc: use the ocrmask provided by the vmmc regulator
>   mmc: host: omap_hsmmc: use mmc_host's vmmc and vqmmc
>   mmc: host: omap_hsmmc: remove unnecessary pbias set_voltage
>   mmc: host: omap_hsmmc: return error if any of the regulator APIs fail
>   mmc: host: omap_hsmmc: add separate functions for enable/disable
>     supply
>   mmc: host: omap_hsmmc: add separate function to set pbias
>   mmc: host: omap_hsmmc: avoid pbias regulator enable on power off
>   mmc: host: omap_hsmmc: don't use ->set_power to set initial regulator
>     state
>   ARM: dts: am57xx-beagle-x15: Fix regulator populated in MMC1 dt node
>   mmc: host: omap_hsmmc: enable/disable vmmc_aux regulator based on
>     prior state
>   mmc: host: omap_hsmmc: use regulator_is_enabled to find pbias status
>   mmc: host: omap_hsmmc: use ios->vdd for setting vmmc voltage
>   mmc: host: omap_hsmmc: remove CONFIG_REGULATOR check
>
> Roger Quadros (1):
>   mmc: host: omap_hsmmc: use "mmc_of_parse_voltage" to get ocr_avail
>
>  .../devicetree/bindings/mmc/ti-omap-hsmmc.txt      |    2 +
>  arch/arm/boot/dts/am57xx-beagle-x15.dts            |    1 -
>  drivers/mmc/host/omap_hsmmc.c                      |  333 +++++++++++++-------
>  3 files changed, 216 insertions(+), 120 deletions(-)
>
> --
> 1.7.9.5
>


From linus.walleij at linaro.org  Mon Aug  3 00:30:47 2015
From: linus.walleij at linaro.org (Linus Walleij)
Date: Mon, 3 Aug 2015 09:30:47 +0200
Subject: [PATCH 1/2] ARM: integrator: move framebuffers to driver
In-Reply-To: <20150729193846.GQ7557@n2100.arm.linux.org.uk>
References: <1438172831-11450-1-git-send-email-linus.walleij@linaro.org>
 <20150729193846.GQ7557@n2100.arm.linux.org.uk>
Message-ID: <CACRpkdYkHgKJHDGp+6gS==9829tUsnFyPrdrevyyUuod04mNvw@mail.gmail.com>

On Wed, Jul 29, 2015 at 9:38 PM, Russell King - ARM Linux
<linux at arm.linux.org.uk> wrote:
> On Wed, Jul 29, 2015 at 02:27:11PM +0200, Linus Walleij wrote:
>> Commit 11c32d7b6274cb0f554943d65bd4a126c4a86dcd
>> "video: move Versatile CLCD helpers" already moved the
>> CLCD mode setting helpers for Versatile and Integrator/CP
>> to drivers/video/fbdev. Let's do the same for the IM-PD1
>> add-on board, copy the missing displays into the database
>> and simplify the code.
>
> And thereby break the support.  The IM-PD1 CLCD can only access the memory
> on the IM-PD1.  That's why the CLCD driver itself doesn't just allocate
> the frame buffer using dma_alloc_writecombine().  Where the memory comes
> from is platform specific.  In this case...
>
>> -static int impd1fb_clcd_setup(struct clcd_fb *fb)
>> -{
>> -     unsigned long framebase = fb->dev->res.start + 0x01000000;
>> -     unsigned long framesize = SZ_1M;
>
> It's a chunk of SRAM offset by the specified value and of the specified
> size above.

Argh how typical. I need to get one of these PROSPECTOR displays
so I can actually test this stuff. I have tried to get VGA out working with
the IM-PD1 but it just doesn't seem to come up no matter how I
try.

Yours,
Linus Walleij


From javier at osg.samsung.com  Mon Aug  3 00:38:28 2015
From: javier at osg.samsung.com (Javier Martinez Canillas)
Date: Mon, 3 Aug 2015 09:38:28 +0200
Subject: [PATCH] PM / devfreq: event: Remove incorrect property in
 exynos-ppmu DT binding
In-Reply-To: <1733224792.341671438577931309.JavaMail.weblogic@epmlwas06d>
References: <1733224792.341671438577931309.JavaMail.weblogic@epmlwas06d>
Message-ID: <55BF1A74.50105@osg.samsung.com>

Hello MyungJoo,

On 08/03/2015 06:58 AM, MyungJoo Ham wrote:
>> Hello Myungjoo,
>>
>> On 07/23/2015 10:30 AM, Javier Martinez Canillas wrote:
>>> Hello Chanwoo,
>>>
>>> On 07/23/2015 10:19 AM, Chanwoo Choi wrote:
>>>> Hi Javier,
>>>>
>>>> On 07/13/2015 03:58 PM, Javier Martinez Canillas wrote:
>>>>> The exynos-ppmu driver is only a clock consumer and not a clock
>>>>> provider but its Device Tree binding listed #clock-cells as an
>>>>> optional property.
>>>>>
>>>>> Signed-off-by: Javier Martinez Canillas <javier at osg.samsung.com>
>>>>>
> []
>>>>>
>>>>> Example1 : PPMU nodes in exynos3250.dtsi are listed below.
>>>>>
>>>>>
>>>>
>>>> Reviewed-by: Chanwoo Choi <cw00.choi at samsung.com>
>>>>
>>>> + Devfreq maintainer (Myungjoo Ham)
>>>
>>> Thanks for the review and for cc'ing Myungjoo. The get_maintainer.pl script
>>> didn't tell me that so I think Documentation/devicetree/bindings/devfreq/
>>> sub-dir should be added to the DEVICE FREQUENCY (DEVFREQ) entry in the
>>> MAINTAINERS file.
>>>
>>>> I think that this patch will be more appropriate on devfreq git tree
>>>> than linux-samsung git tree.
>>>>
>>>
>>> Agreed.
>>>
>>
>> Any comments about this patch?
> 
> Nope. It's applied.
> 
> 
> Thanks.
> 
>

Great, thanks a lot.
 
> 
> MyungJoo
> 

Best regards,
-- 
Javier Martinez Canillas
Open Source Group
Samsung Research America


From linux at arm.linux.org.uk  Mon Aug  3 00:58:48 2015
From: linux at arm.linux.org.uk (Russell King - ARM Linux)
Date: Mon, 3 Aug 2015 08:58:48 +0100
Subject: [PATCH 0/2] drivers: PL061: Add platform driver probing support
In-Reply-To: <1438585198-8764-1-git-send-email-zhaoshenglong@huawei.com>
References: <1438585198-8764-1-git-send-email-zhaoshenglong@huawei.com>
Message-ID: <20150803075848.GH7557@n2100.arm.linux.org.uk>

On Mon, Aug 03, 2015 at 02:59:56PM +0800, Shannon Zhao wrote:
> From: Shannon Zhao <shannon.zhao at linaro.org>
> 
> According to ACPI SPEC, it supports ARM boards to use "GPIO-signaled
> ACPI Events". These events can be used for input events. And to QEMU, it
> uses GPIO PL061 controller for input events.
> 
> These two patches add platform driver support for PL061 probed by DT or
> ACPI.

This certainly is incorrect for DT, and is probably wrong for ACPI too.
DT creates amba devices, so binds via the amba device driver.

-- 
FTTC broadband for 0.8mile line: currently at 10.5Mbps down 400kbps up
according to speedtest.net.


From arnd at arndb.de  Mon Aug  3 01:00:17 2015
From: arnd at arndb.de (Arnd Bergmann)
Date: Mon, 03 Aug 2015 10:00:17 +0200
Subject: [RFC] arm64: defconfig: enable 48-bit VA by default
In-Reply-To: <CAKv+Gu89UGzL9=0tYjQmv9dX7KOsfobpO4zG1E8X0g4W9u5Bkg@mail.gmail.com>
References: <CY1PR0301MB07488D6DC5F0B171D6B290E187830@CY1PR0301MB0748.namprd03.prod.outlook.com>
 <1524396.PS7zpagrm1@wuerfel>
 <CAKv+Gu89UGzL9=0tYjQmv9dX7KOsfobpO4zG1E8X0g4W9u5Bkg@mail.gmail.com>
Message-ID: <1950491.fy9Zn5k0xY@wuerfel>

On Sunday 02 August 2015 08:19:07 Ard Biesheuvel wrote:
> >> >>
> >> >> PHYS_OFFSET = PHYS_OFFSET0 = memstart_addr
> >> >> PHYS_OFFSET1 = memstart_addr + 2 GB
> >> >> PHYS_OFFSET2 = memstart_addr + 32 GB
> >> >>
> >> >> and only if the ARM recommended physical memory map is detected (with
> >> >> memstart_addr @ 0x8000_0000), switch to
> >> >>
> >> >> PHYS_OFFSET = PHYS_OFFSET0 = memstart_addr
> >> >> PHYS_OFFSET1 = memstart_addr + 30 GB
> >> >> PHYS_OFFSET2 = memstart_addr + 480 GB
> >> >
> >> > I don't really like such complexity when all you need on arm64 is to
> >> > enable 48-bit VA (though it would be interesting to benchmark it).
> >
> > More importantly, hardwiring this in virt_to_phys() would mean we can
> > no longer run a kernel with this hack turned on with systems that have
> > contiguous memory or any other layout besides the one from the document.
> >
> 
> Well the hack, if enabled, would be turned on dynamically iff the
> exact layout from the recommendation is detected, and the kernel is
> loaded right at the base of DRAM.
> Note that the first layout I presented is effectively the current
> linear mapping, but with three steps.

Ok, I see. So it would work everywhere, at the price of another conditional
for each virt_to_phys, either runtime or by binary patching at boottime.

	Arnd


From linus.walleij at linaro.org  Mon Aug  3 01:01:31 2015
From: linus.walleij at linaro.org (Linus Walleij)
Date: Mon, 3 Aug 2015 10:01:31 +0200
Subject: [rtc-linux] [PATCH] drivers/rtc/rtc-pl031.c: reset registers in
 init flow
In-Reply-To: <20150729111700.GA12912@leoy-linaro>
References: <1438149721-11072-1-git-send-email-leo.yan@linaro.org>
 <CACRpkdZ5Kvc0LPeG_HAHwejoCRV4JRbpA2+zwNCAxTqzxdDYzQ@mail.gmail.com>
 <20150729111700.GA12912@leoy-linaro>
Message-ID: <CACRpkdYnr8bw_3a7jnaSZqMmA6j+yyVKNrdA+TzSTdNxzaUu+A@mail.gmail.com>

On Wed, Jul 29, 2015 at 1:17 PM, Leo Yan <leo.yan at linaro.org> wrote:

> This issue is found when i use file
> kernel/power/suspend_test.c to verify the system suspend. Before the
> system suspend, the flow need set 10's alarm in RTC for waken up
> event.
>
> But what i observed the phenomenon is:
>
> At the init phase:
> RTC_LR = 0x0;
> RTC_DR = 0x0;
> RTC_MR = 0x0;
>
> According to the timeout is 10s, the function *pl031_set_alarm()* will
> set RTC_MR = 10; So usually RTC_DR will increase one for every second
> and will trigger interrupt when RTC_DR equal to RTC_MR. But on
> Hi6220, though the RTC_DR init value is zero, but very soon it will be
> set a random value which is bigger than 10.

Aha, that's annoying.

> So it will never match with
> RTC_MR register anymore; finally the system cannot resume back due the
> waken up event will not be triggered.

OK I see.

> So suspect RTC_LR has not been initailized correctly and it will load
> random value to RTC_DR. After reset the RTC_LR, this issue will be
> fixed.
>
>> > +       /* Init registers */
>> > +       writel(0x0, ldata->base + RTC_LR);
>>
>> This will reset the clock to jan 1st 1970 on every reboot.
>> The idea is that the RTC should *preserve* the system time
>> if you reboot the system, so NACK.
>>
>> Usually userspace has a script using hwclock to read the
>> system time from the rtc to system time with hwclock -s
>> after userspace comes up. Likewise it writes it back with
>> hwclock -w before rebooting.
>
> This change is wrong.

I don't see what you mean here...

Most RTCs in the world have a battery back-up, so they
sustain time during shutdown. On an ARM system like this,
this PL031 derivative probably loose the time on shutdown,
but not on a soft reset.

However probe() will be called no matter if a shutdown or
soft reset happened, and the time will be reset to
1970-01-01 in any case with this change, even if it was
a soft reset and the time in the RTC is actually valid.

>> > +       writel(RTC_BIT_AI, ldata->base + RTC_ICR);
>>
>> So why do we want to have the alarm enabled by
>> default, before the kernel nor userspace has requested
>> it?
>
> This is to clear any pending interrupt, but not enable alarm.

OK.

>
>> If your problem is with suspend/resume I suggest you work
>> on the [runtime]_suspend/resume hooks instead of probe().
>> Possibly you need to save/restore state across suspend/resume.
>
> Do you think below change is make sense?

It's not using suspend/resume hooks but let's see...

> +       /* Init registers */
> +       writel(0x0, ldata->base + RTC_IMSC);
> +       writel(RTC_BIT_AI, ldata->base + RTC_ICR);

Looks OK.

> @@ -368,6 +372,9 @@ static int pl031_probe(struct amba_device *adev, const struct amba_id *id)
>                                 writel(time, ldata->base + RTC_LR);
>                         }
>                 }
> +       } else {
> +               time = readl(ldata->base + RTC_DR);
> +               writel(time, ldata->base + RTC_LR);
>         }

This badly needs a comment in the else-clause describing
what is happening here.

But I think it looks right! This will preserve the time across
soft reboots properly if I read it right.

Yours,
Linus Walleij


From linus.walleij at linaro.org  Mon Aug  3 01:19:12 2015
From: linus.walleij at linaro.org (Linus Walleij)
Date: Mon, 3 Aug 2015 10:19:12 +0200
Subject: [RESEND PATCH] pinctrl: at91: fix null pointer dereference
In-Reply-To: <1438069696-25303-1-git-send-email-ludovic.desroches@atmel.com>
References: <20150715133048.GD14886@odux.rfo.atmel.com>
 <1438069696-25303-1-git-send-email-ludovic.desroches@atmel.com>
Message-ID: <CACRpkdZnL7g6O1CgBG0gZ525QZs43tvzTx-1NXZ2HR6cQXbyDA@mail.gmail.com>

On Tue, Jul 28, 2015 at 9:48 AM, Ludovic Desroches
<ludovic.desroches at atmel.com> wrote:

> From: David Dueck <davidcdueck at googlemail.com>
>
> Not all gpio banks are necessarily enabled, in the current code this can
> lead to null pointer dereferences.
(...)
>
> Signed-off-by: David Dueck <davidcdueck at googlemail.com>
> Acked-by: Ludovic Desroches <ludovic.desroches at atmel.com>
> Acked-by: Alexandre Belloni <alexandre.belloni at free-electrons.com>
> CC: Nicolas Ferre <nicolas.ferre at atmel.com>
> CC: Boris Brezillon <boris.brezillon at free-electrons.com>
> CC: linux-arm-kernel at lists.infradead.org
> CC: linux-kernel at vger.kernel.org
> ---
>
> This patch fixes a oops in the kernel because of a NULL pointer in a table.
> Having a NULL pointer in this table is the normal behavior if a PIO controller
> is not enabled. So this fix is not a quick and dirty hack, it's usual to skip
> an entry from a table if it is not filled.

This v2 version applied for fixes with v3.18+ stable tag.

Yours,
Linus Walleij


From public_timo.s at silentcreek.de  Mon Aug  3 01:37:51 2015
From: public_timo.s at silentcreek.de (Timo Sigurdsson)
Date: Mon,  3 Aug 2015 10:37:51 +0200 (CEST)
Subject: [linux-sunxi] [PATCH] ARM: dts: sunxi: Raise minimum CPU voltage
 for sun7i-a20 to a level all boards can supply
In-Reply-To: <CAGRGNgV6b9yt2HnB2x2Wyc05KEahoX-Y+mVhxsryztcfA36H1g@mail.gmail.com>
References: <1438543386-7253-1-git-send-email-public_timo.s@silentcreek.de><CAGRGNgV6b9yt2HnB2x2Wyc05KEahoX-Y+mVhxsryztcfA36H1g@mail.gmail.com>
Message-ID: <20150803083751.1BCF56C80391@dd34104.kasserver.com>

Hi Julian,

Julian Calaby schrieb am 03.08.2015 01:35:
>> sun7i-a20.dtsi contains an cpufreq operating point at 0.9 volts. Most A20
>> boards
>> (or all?), however, do not allow the voltage to go below 1.0V. Thus, raise the
>> voltage for the lowest operating point to 1.0V so all boards can actually use
>> it.
> 
> Surely it wouldn't be added here if some could supply 0.9v.

Maybe. I just know some boards don't (e.g. Cubieboard 2, Cubietruck, BananaPi)
and don't know of any that does. But that's not my point. I think that a common
minimum operating point, defined on the SOC level, should be defined in a way
that works on all boards.

> 
> Is the code that uses this smart enough to sensibly switch between two
> operating points with the same frequency and different voltages? If
> so, maybe just add a 144MHz @ 1.0v operating point?

I never tried and I probably won't have time to test that before the weekend.
The current behaviour is this, though: On boards that set their minimum CPU
voltage to 1.0V, the lowest operating point will simply not be available to
the user.

> (Alternatively, would it make sense to modify the code that uses this
> to use frequencies with voltages specified that are lower than can be
> supplied with the lowest voltage it can?)

Considering OPPv2 is in the works, maybe not?


Thanks,

Timo


From jonathanh at nvidia.com  Mon Aug  3 01:38:37 2015
From: jonathanh at nvidia.com (Jon Hunter)
Date: Mon, 3 Aug 2015 09:38:37 +0100
Subject: Tegra baseline test results for v4.2-rc5
Message-ID: <55BF288D.6070109@nvidia.com>

Here are some basic Tegra test results for Linux v4.2-rc5.
Logs and other details at:

    https://nvtb.github.io//linux/test_v4.2-rc5/20150802190102/


Test summary
------------

Build: zImage:
    Pass: ( 2/ 2): multi_v7_defconfig, tegra_defconfig

Build: Image:
    Pass: ( 1/ 1): defconfig

Boot to userspace: defconfig:
    Pass: ( 1/ 1): qemu-vexpress64

Boot to userspace: multi_v7_defconfig:
    Pass: ( 4/ 4): tegra114-dalmore-a04, tegra124-jetson-tk1,
		   tegra20-trimslice, tegra30-beaver

Boot to userspace: tegra_defconfig:
    Pass: ( 4/ 4): tegra114-dalmore-a04, tegra124-jetson-tk1,
		   tegra20-trimslice, tegra30-beaver


vmlinux object size
(delta in bytes from test_v4.2-rc4 (cbfe8fa6cd672011c755c3cd85c9ffd4e2d10a6f)):
   text     data      bss    total  kernel
    +24        0        0      +24  defconfig
  +2240        0        0    +2240  multi_v7_defconfig
   +592     +256        0     +848  tegra_defconfig


Boot-time memory difference
(delta in bytes from test_v4.2-rc4 (cbfe8fa6cd672011c755c3cd85c9ffd4e2d10a6f))
    avail    rsrvd     high    freed                board              kconfig                  dtb
        .        .        .        .      qemu-vexpress64            defconfig           __internal
        .        .        .        . tegra114-dalmore-a04   multi_v7_defconfig     tegra114-dalmore
        .        .        .      -4k tegra114-dalmore-a04      tegra_defconfig     tegra114-dalmore
        .        .        .        .  tegra124-jetson-tk1   multi_v7_defconfig  tegra124-jetson-tk1
        .        .        .      -4k  tegra124-jetson-tk1      tegra_defconfig  tegra124-jetson-tk1
        .        .        .        .    tegra20-trimslice   multi_v7_defconfig    tegra20-trimslice
        .        .        .      -4k    tegra20-trimslice      tegra_defconfig    tegra20-trimslice
        .        .        .        .       tegra30-beaver   multi_v7_defconfig       tegra30-beaver
        .        .        .      -4k       tegra30-beaver      tegra_defconfig       tegra30-beaver


From ian.campbell at citrix.com  Mon Aug  3 01:48:08 2015
From: ian.campbell at citrix.com (Ian Campbell)
Date: Mon, 3 Aug 2015 09:48:08 +0100
Subject: [PATCH v3] dtb: Create a common home for cross-architecture
 dtsi files.
In-Reply-To: <CAK7LNARqFCF3hcR4VNp5hhfyNNMxcx4majzRTx8=HPMYgpVcTg@mail.gmail.com>
References: <1438353109-373-1-git-send-email-ian.campbell@citrix.com>
 <CAK7LNATj96OKFDTgyPC8Uu0qt=4NQ7ZVeLKEEP3K7-smFP2SCw@mail.gmail.com>
 <CAK7LNARqFCF3hcR4VNp5hhfyNNMxcx4majzRTx8=HPMYgpVcTg@mail.gmail.com>
Message-ID: <1438591688.30740.95.camel@citrix.com>

On Sat, 2015-08-01 at 15:43 +0900, Masahiro Yamada wrote:
> 2015-08-01 15:21 GMT+09:00 Masahiro Yamada <yamada.masahiro at socionext.com
> >:
> > 2015-07-31 23:31 GMT+09:00 Ian Campbell <ian.campbell at citrix.com>:
> > > Commit 9ccd608070b6 "arm64: dts: add device tree for ARM SMM-A53x2 on
> > > LogicTile Express 20MG" added a new dts file to arch/arm64 which
> > > included "../../../../arm/boot/dts/vexpress-v2m-rs1.dtsi", i.e. a
> > > .dtsi supplied by arch/arm.
> > > 
> > > Unfortunately this causes some issues for the split device tree
> > > repository[0], since things get moved around there. In that context
> > > the new .dts ends up at src/arm64/arm/vexpress-v2f-1xv7-ca53x2.dts
> > > while the include is at src/arm/vexpress-v2m-rs1.dtsi.
> > 
> > Typo?
> > 
> > src/arm64  ->  arch/arm64
> > src/arm    ->  arch/arm
> > 
> 
> 
> I retract this comment with my apology.
> (I was seeing the kernel tree, not devicetree-rebasing)

Right ;-)

I fixed the commit formatting and took your Reviewed-by. I shall post v4
shortly.

Thanks,
Ian.



From ian.campbell at citrix.com  Mon Aug  3 01:55:11 2015
From: ian.campbell at citrix.com (Ian Campbell)
Date: Mon, 3 Aug 2015 09:55:11 +0100
Subject: [PATCH v4] dtb: Create a common home for cross-architecture dtsi
 files.
Message-ID: <1438592111-8471-1-git-send-email-ian.campbell@citrix.com>

Commit 9ccd608070b6 ("arm64: dts: add device tree for ARM SMM-A53x2 on
LogicTile Express 20MG") added a new dts file to arch/arm64 which
included "../../../../arm/boot/dts/vexpress-v2m-rs1.dtsi", i.e. a
.dtsi supplied by arch/arm.

Unfortunately this causes some issues for the split device tree
repository[0], since things get moved around there. In that context
the new .dts ends up at src/arm64/arm/vexpress-v2f-1xv7-ca53x2.dts
while the include is at src/arm/vexpress-v2m-rs1.dtsi.

The sharing of the .dtsi is legitimate since the baseboard is the same
for various vexpress systems whatever processor they use.

Rather than using ../../ tricks to pickup .dtsi files from another
arch this patch creates a new directory kernel/dts as a home for such
cross-arch .dtsi files, arranges for it to be in the include path when
the .dts files are processed by cpp and switches the .dts files to use
cpp #include instead of /include/. The dtsi file itself is moved into
a vendor subdir in this case "arm" (the vendor, not the ARCH=).

[0] https://git.kernel.org/cgit/linux/kernel/git/devicetree/devicetree-rebasing.git/

Signed-off-by: Ian Campbell <ian.campbell at citrix.com>
Cc: Rob Herring <robh+dt at kernel.org>
Cc: Pawel Moll <pawel.moll at arm.com>
Cc: Mark Rutland <mark.rutland at arm.com>
Cc: Kumar Gala <galak at codeaurora.org>
Cc: Liviu Dudau <liviu.dudau at arm.com>
Cc: Sudeep Holla <sudeep.holla at arm.com>
Cc: Lorenzo Pieralisi <lorenzo.pieralisi at arm.com>
Cc: Russell King <linux at arm.linux.org.uk>
Cc: Catalin Marinas <catalin.marinas at arm.com>
Cc: Will Deacon <will.deacon at arm.com>
Cc: Kristina Martsenko <kristina.martsenko at arm.com>
Cc: Kevin Hilman <khilman at linaro.org>
Cc: devicetree at vger.kernel.org
Cc: linux-kernel at vger.kernel.org
Cc: linux-arm-kernel at lists.infradead.org
Cc: linux-kbuild at vger.kernel.org
Acked-by: Mark Rutland <mark.rutland at arm.com>
Acked-by: Rob Herring <robh at kernel.org>
Acked-by: Liviu Dudau <Liviu.Dudau at arm.com>
Reviewed-by: Masahiro Yamada <yamada.masahiro at socionext.com>
---
v2: Move to include/dt-dtsi and introduce a per-vendor subdirectory.

v3: Move to kernel/dts.
    Include new directory in DTC include path as well as cpp path, and
    therefore switch back to /include/.
    Update MAINTAINERS

v4: Change path in changelog too.
    Add ()s to title of 9ccd608070b6.
---
 Documentation/devicetree/bindings/arm/vexpress.txt          | 2 +-
 MAINTAINERS                                                 | 1 +
 arch/arm/boot/dts/vexpress-v2p-ca15-tc1.dts                 | 2 +-
 arch/arm/boot/dts/vexpress-v2p-ca15_a7.dts                  | 2 +-
 arch/arm/boot/dts/vexpress-v2p-ca5s.dts                     | 2 +-
 arch/arm64/boot/dts/arm/vexpress-v2f-1xv7-ca53x2.dts        | 2 +-
 {arch/arm/boot/dts => kernel/dts/arm}/vexpress-v2m-rs1.dtsi | 0
 scripts/Makefile.lib                                        | 3 ++-
 8 files changed, 8 insertions(+), 6 deletions(-)
 rename {arch/arm/boot/dts => kernel/dts/arm}/vexpress-v2m-rs1.dtsi (100%)

diff --git a/Documentation/devicetree/bindings/arm/vexpress.txt b/Documentation/devicetree/bindings/arm/vexpress.txt
index 39844cd..b6031d9 100644
--- a/Documentation/devicetree/bindings/arm/vexpress.txt
+++ b/Documentation/devicetree/bindings/arm/vexpress.txt
@@ -223,7 +223,7 @@ Example of a VE tile description (simplified)
 		/* Active high IRQ 0 is connected to GIC's SPI0 */
 		interrupt-map = <0 0 0 &gic 0 0 4>;
 
-		/include/ "vexpress-v2m-rs1.dtsi"
+		/include/ "arm/vexpress-v2m-rs1.dtsi"
 	};
 };
 
diff --git a/MAINTAINERS b/MAINTAINERS
index a226416..1941078 100644
--- a/MAINTAINERS
+++ b/MAINTAINERS
@@ -7537,6 +7537,7 @@ S:	Maintained
 F:	Documentation/devicetree/
 F:	arch/*/boot/dts/
 F:	include/dt-bindings/
+F:	kernel/dts/
 
 OPEN FIRMWARE AND DEVICE TREE OVERLAYS
 M:	Pantelis Antoniou <pantelis.antoniou at konsulko.com>
diff --git a/arch/arm/boot/dts/vexpress-v2p-ca15-tc1.dts b/arch/arm/boot/dts/vexpress-v2p-ca15-tc1.dts
index 9420053..b144092 100644
--- a/arch/arm/boot/dts/vexpress-v2p-ca15-tc1.dts
+++ b/arch/arm/boot/dts/vexpress-v2p-ca15-tc1.dts
@@ -278,6 +278,6 @@
 				<0 0 41 &gic 0 41 4>,
 				<0 0 42 &gic 0 42 4>;
 
-		/include/ "vexpress-v2m-rs1.dtsi"
+		/include/ "arm/vexpress-v2m-rs1.dtsi"
 	};
 };
diff --git a/arch/arm/boot/dts/vexpress-v2p-ca15_a7.dts b/arch/arm/boot/dts/vexpress-v2p-ca15_a7.dts
index 17f63f7..350f402 100644
--- a/arch/arm/boot/dts/vexpress-v2p-ca15_a7.dts
+++ b/arch/arm/boot/dts/vexpress-v2p-ca15_a7.dts
@@ -636,6 +636,6 @@
 				<0 0 41 &gic 0 41 4>,
 				<0 0 42 &gic 0 42 4>;
 
-		/include/ "vexpress-v2m-rs1.dtsi"
+		/include/ "arm/vexpress-v2m-rs1.dtsi"
 	};
 };
diff --git a/arch/arm/boot/dts/vexpress-v2p-ca5s.dts b/arch/arm/boot/dts/vexpress-v2p-ca5s.dts
index d2709b7..585ced0 100644
--- a/arch/arm/boot/dts/vexpress-v2p-ca5s.dts
+++ b/arch/arm/boot/dts/vexpress-v2p-ca5s.dts
@@ -248,6 +248,6 @@
 				<0 0 41 &gic 0 41 4>,
 				<0 0 42 &gic 0 42 4>;
 
-		/include/ "vexpress-v2m-rs1.dtsi"
+		/include/ "arm/vexpress-v2m-rs1.dtsi"
 	};
 };
diff --git a/arch/arm64/boot/dts/arm/vexpress-v2f-1xv7-ca53x2.dts b/arch/arm64/boot/dts/arm/vexpress-v2f-1xv7-ca53x2.dts
index 5b1d018..c044804 100644
--- a/arch/arm64/boot/dts/arm/vexpress-v2f-1xv7-ca53x2.dts
+++ b/arch/arm64/boot/dts/arm/vexpress-v2f-1xv7-ca53x2.dts
@@ -186,6 +186,6 @@
 				<0 0 41 &gic GIC_SPI 41 IRQ_TYPE_LEVEL_HIGH>,
 				<0 0 42 &gic GIC_SPI 42 IRQ_TYPE_LEVEL_HIGH>;
 
-		/include/ "../../../../arm/boot/dts/vexpress-v2m-rs1.dtsi"
+		/include/ "arm/vexpress-v2m-rs1.dtsi"
 	};
 };
diff --git a/arch/arm/boot/dts/vexpress-v2m-rs1.dtsi b/kernel/dts/arm/vexpress-v2m-rs1.dtsi
similarity index 100%
rename from arch/arm/boot/dts/vexpress-v2m-rs1.dtsi
rename to kernel/dts/arm/vexpress-v2m-rs1.dtsi
diff --git a/scripts/Makefile.lib b/scripts/Makefile.lib
index 79e8661..b4d9fb6 100644
--- a/scripts/Makefile.lib
+++ b/scripts/Makefile.lib
@@ -163,6 +163,7 @@ dtc_cpp_flags  = -Wp,-MD,$(depfile).pre.tmp -nostdinc                    \
 		 -I$(srctree)/arch/$(SRCARCH)/boot/dts                   \
 		 -I$(srctree)/arch/$(SRCARCH)/boot/dts/include           \
 		 -I$(srctree)/drivers/of/testcase-data                   \
+		 -I$(srctree)/kernel/dts                                 \
 		 -undef -D__DTS__
 
 # Finds the multi-part object the current object will be linked into
@@ -285,7 +286,7 @@ quiet_cmd_dtc = DTC     $@
 cmd_dtc = mkdir -p $(dir ${dtc-tmp}) ; \
 	$(CPP) $(dtc_cpp_flags) -x assembler-with-cpp -o $(dtc-tmp) $< ; \
 	$(objtree)/scripts/dtc/dtc -O dtb -o $@ -b 0 \
-		-i $(dir $<) $(DTC_FLAGS) \
+		-i $(dir $<) -i $(srctree)/kernel/dts $(DTC_FLAGS) \
 		-d $(depfile).dtc.tmp $(dtc-tmp) ; \
 	cat $(depfile).pre.tmp $(depfile).dtc.tmp > $(depfile)
 
-- 
2.1.4



From public_timo.s at silentcreek.de  Mon Aug  3 02:03:52 2015
From: public_timo.s at silentcreek.de (Timo Sigurdsson)
Date: Mon,  3 Aug 2015 11:03:52 +0200 (CEST)
Subject: [linux-sunxi] [PATCH] ARM: dts: sunxi: Raise minimum CPU voltage
 for sun7i-a20 to a level all boards can supply
In-Reply-To: <CAGRGNgXH90m9h0DDejd5MTf8enduGFQ8dPKrRhmc8Z6y_PaC1w@mail.gmail.com>
References: <1438543386-7253-1-git-send-email-public_timo.s@silentcreek.de>
 <CAGRGNgV6b9yt2HnB2x2Wyc05KEahoX-Y+mVhxsryztcfA36H1g@mail.gmail.com>
 <CAGb2v67o-=_cL2RWfXJ+3C86zfQ_1b5DYRi3_zwvwy6su6+gdw@mail.gmail.com><CAGRGNgXH90m9h0DDejd5MTf8enduGFQ8dPKrRhmc8Z6y_PaC1w@mail.gmail.com>
Message-ID: <20150803090352.621CC6C80865@dd34104.kasserver.com>

Hi again,

Julian Calaby schrieb am 03.08.2015 06:22:
> My only real objection here is are there boards that can go down to
> 0.9v and if so, won't this change make them less power efficient in
> the almost-idle case? And are those power savings enough to justify
> not accepting this patch?

It will probably make those boards less power efficient, yes. On the
other hand, boards that have their CPU regulator set to min. 1.0V might
also draw more power because the lowest frequency is not available, 
even though the savings due to frequency are likely to be lower than
the savings due to voltage.

However, Stefan Monnier (added to CC) mentioned in an earlier
discussion that the savings for the lowest opp are rather small and
thus the benefit of the 144MHz opp would be questionable.

Unfortunately, I don't have measurement equipment precise enough to
test this myself and haven't found a way to read power consumption
internally via the PMU in mainline yet.

Thanks,

Timo


From ranjit.waghmode at xilinx.com  Mon Aug  3 02:05:05 2015
From: ranjit.waghmode at xilinx.com (Ranjit Waghmode)
Date: Mon, 3 Aug 2015 14:35:05 +0530
Subject: [LINUX RFC 0/2] spi: add dual parallel mode support in Zynq MPSoC
 GQSPI controller
Message-ID: <1438592707-30713-1-git-send-email-ranjit.waghmode@xilinx.com>

This series is to add dual parallel mode support for Zynq Ultrascale+ MPSoC GQSPI controller driver.

What is dual parallel mode?
---------------------------
ZynqMP GQSPI controller supports Dual Parallel mode with following functionalities:
1) Supporting two SPI flash memories operating in parallel. 8 I/O lines.
2) Chip selects and clock are shared to both the flash devices
3) This mode is targeted for faster read/write speed and also doubles the size
4) Commands/data can be transmitted/received from both the devices(mirror),
   or only upper or only lower flash memory devices.
5) Data arrangement:
   With stripe enabled,
   Even bytes i.e. 0, 2, 4,... are transmitted on Lower Data Bus
   Odd bytes i.e. 1, 3, 5,.. are transmitted on Upper Data Bus.

This series also updated MTD layer files for adding parallel mode support.

MTD layer dependency changes:
-----------------------------
1) Added Support for two flashes
2) Support to enable/disable data stripe as and when required.
3) Added required parameters to spi_nor structure. Initialized all
   added parameters in spi_nor_scan()
4) Added support for dual parallel in spi_nor_read/write/erase functions by:
   a) Increasing page_size, sector_size, erase_size and toatal flash size
      as and when required.
   b) Dividing address by 2
   c) Updating spi->master->flags for qspi driver to change CS
5) Updated read_sr() to get status of both flashes
6) Also updated read_fsr() to get status of both flashes

These all are very high level changes and expected to make an idea clear.
Comments and suggestions are always welcomed.

Ranjit Waghmode (2):
  mtd: spi-nor: add dual parallel mode support
  spi: zynqmp: gqspi: add support for dual parallel mode configuration

 drivers/mtd/devices/m25p80.c   |  1 +
 drivers/mtd/spi-nor/spi-nor.c  | 92 +++++++++++++++++++++++++++++++++---------
 drivers/spi/spi-zynqmp-gqspi.c | 24 ++++++++++-
 include/linux/mtd/spi-nor.h    |  3 ++
 include/linux/spi/spi.h        |  2 +
 5 files changed, 102 insertions(+), 20 deletions(-)

--
2.1.2



From ranjit.waghmode at xilinx.com  Mon Aug  3 02:05:07 2015
From: ranjit.waghmode at xilinx.com (Ranjit Waghmode)
Date: Mon, 3 Aug 2015 14:35:07 +0530
Subject: [LINUX RFC 2/2] spi: zynqmp: gqspi: add support for dual parallel
 mode configuration
In-Reply-To: <1438592707-30713-1-git-send-email-ranjit.waghmode@xilinx.com>
References: <1438592707-30713-1-git-send-email-ranjit.waghmode@xilinx.com>
Message-ID: <1438592707-30713-3-git-send-email-ranjit.waghmode@xilinx.com>

This patch adds support of dual parallel mode configuration for
Zynq Ultrascale+ MPSoC GQSPI controller driver.

Signed-off-by: Ranjit Waghmode <ranjit.waghmode at xilinx.com>
---
 drivers/spi/spi-zynqmp-gqspi.c | 24 +++++++++++++++++++++++-
 1 file changed, 23 insertions(+), 1 deletion(-)

diff --git a/drivers/spi/spi-zynqmp-gqspi.c b/drivers/spi/spi-zynqmp-gqspi.c
index f23f36e..7a72781 100644
--- a/drivers/spi/spi-zynqmp-gqspi.c
+++ b/drivers/spi/spi-zynqmp-gqspi.c
@@ -153,6 +153,7 @@ enum mode_type {GQSPI_MODE_IO, GQSPI_MODE_DMA};
  * @dma_rx_bytes:	Remaining bytes to receive by DMA mode
  * @dma_addr:		DMA address after mapping the kernel buffer
  * @genfifoentry:	Used for storing the genfifoentry instruction.
+ * @isinstr:		To determine whether the transfer is instruction
  * @mode:		Defines the mode in which QSPI is operating
  */
 struct zynqmp_qspi {
@@ -170,6 +171,7 @@ struct zynqmp_qspi {
 	u32 dma_rx_bytes;
 	dma_addr_t dma_addr;
 	u32 genfifoentry;
+	bool isinstr;
 	enum mode_type mode;
 };

@@ -405,9 +407,20 @@ static void zynqmp_qspi_chipselect(struct spi_device *qspi, bool is_high)
 	genfifoentry |= GQSPI_GENFIFO_MODE_SPI;
 	genfifoentry |= xqspi->genfifobus;

+	if (qspi->master->flags & SPI_MASTER_BOTH_CS) {
+		zynqmp_gqspi_selectslave(xqspi,
+				GQSPI_SELECT_FLASH_CS_BOTH,
+				GQSPI_SELECT_FLASH_BUS_BOTH);
+	} else {
+		zynqmp_gqspi_selectslave(xqspi,
+				GQSPI_SELECT_FLASH_CS_LOWER,
+				GQSPI_SELECT_FLASH_BUS_LOWER);
+	}
+
 	if (!is_high) {
 		genfifoentry |= xqspi->genfifocs;
 		genfifoentry |= GQSPI_GENFIFO_CS_SETUP;
+		xqspi->isinstr = true;
 	} else {
 		genfifoentry |= GQSPI_GENFIFO_CS_HOLD;
 	}
@@ -664,6 +677,7 @@ static irqreturn_t zynqmp_qspi_irq(int irq, void *dev_id)
 	if ((xqspi->bytes_to_receive == 0) && (xqspi->bytes_to_transfer == 0)
 			&& ((status & GQSPI_IRQ_MASK) == GQSPI_IRQ_MASK)) {
 		zynqmp_gqspi_write(xqspi, GQSPI_IDR_OFST, GQSPI_ISR_IDR_MASK);
+		xqspi->isinstr = false;
 		spi_finalize_current_transfer(master);
 		ret = IRQ_HANDLED;
 	}
@@ -827,6 +841,9 @@ static int zynqmp_qspi_start_transfer(struct spi_master *master,
 	genfifoentry |= xqspi->genfifocs;
 	genfifoentry |= xqspi->genfifobus;

+	if ((!xqspi->isinstr) && (master->flags & SPI_MASTER_DATA_STRIPE))
+		genfifoentry |= GQSPI_GENFIFO_STRIPE;
+
 	zynqmp_qspi_txrxsetup(xqspi, transfer, &genfifoentry);

 	if (xqspi->mode == GQSPI_MODE_DMA)
@@ -983,6 +1000,7 @@ static int zynqmp_qspi_probe(struct platform_device *pdev)
 	struct zynqmp_qspi *xqspi;
 	struct resource *res;
 	struct device *dev = &pdev->dev;
+	u32 num_cs;

 	master = spi_alloc_master(&pdev->dev, sizeof(*xqspi));
 	if (!master)
@@ -1043,7 +1061,11 @@ static int zynqmp_qspi_probe(struct platform_device *pdev)
 		goto clk_dis_all;
 	}

-	master->num_chipselect = GQSPI_DEFAULT_NUM_CS;
+	ret = of_property_read_u32(pdev->dev.of_node, "num-cs", &num_cs);
+	if (ret < 0)
+		master->num_chipselect = GQSPI_DEFAULT_NUM_CS;
+	else
+		master->num_chipselect = num_cs;

 	master->setup = zynqmp_qspi_setup;
 	master->set_cs = zynqmp_qspi_chipselect;
--
2.1.2



From ranjit.waghmode at xilinx.com  Mon Aug  3 02:05:06 2015
From: ranjit.waghmode at xilinx.com (Ranjit Waghmode)
Date: Mon, 3 Aug 2015 14:35:06 +0530
Subject: [LINUX RFC 1/2] mtd: spi-nor: add dual parallel mode support
In-Reply-To: <1438592707-30713-1-git-send-email-ranjit.waghmode@xilinx.com>
References: <1438592707-30713-1-git-send-email-ranjit.waghmode@xilinx.com>
Message-ID: <1438592707-30713-2-git-send-email-ranjit.waghmode@xilinx.com>

This patch adds support for dual parallel configuration.

- Added required parameters to spi_nor structure. Initialized all
  added parameters in spi_nor_scan()

- Updated read_sr() and read_fsr() for getting status of both flashes

- Added support for dual parallel in spi_nor_read/write/erase functions by:
  a) Increasing page_size, sector_size, erase_size and toatal flash size
     as and when required.
  b) Dividing address by 2
  c) Updating spi->master->flags for qspi driver to change CS

- Added defines for data stripe and two flash support

Signed-off-by: Ranjit Waghmode <ranjit.waghmode at xilinx.com>
---
 drivers/mtd/devices/m25p80.c  |  1 +
 drivers/mtd/spi-nor/spi-nor.c | 92 ++++++++++++++++++++++++++++++++++---------
 include/linux/mtd/spi-nor.h   |  3 ++
 include/linux/spi/spi.h       |  2 +
 4 files changed, 79 insertions(+), 19 deletions(-)

diff --git a/drivers/mtd/devices/m25p80.c b/drivers/mtd/devices/m25p80.c
index d313f948b..174ed0f 100644
--- a/drivers/mtd/devices/m25p80.c
+++ b/drivers/mtd/devices/m25p80.c
@@ -207,6 +207,7 @@ static int m25p_probe(struct spi_device *spi)
 	spi_set_drvdata(spi, flash);
 	flash->mtd.priv = nor;
 	flash->spi = spi;
+	nor->spi = spi;

 	if (spi->mode & SPI_RX_QUAD)
 		mode = SPI_NOR_QUAD;
diff --git a/drivers/mtd/spi-nor/spi-nor.c b/drivers/mtd/spi-nor/spi-nor.c
index d78831b..9818a76 100644
--- a/drivers/mtd/spi-nor/spi-nor.c
+++ b/drivers/mtd/spi-nor/spi-nor.c
@@ -22,6 +22,7 @@
 #include <linux/of_platform.h>
 #include <linux/spi/flash.h>
 #include <linux/mtd/spi-nor.h>
+#include <linux/spi/spi.h>

 /* Define max times to check status register before we give up. */
 #define	MAX_READY_WAIT_JIFFIES	(40 * HZ) /* M25P16 specs 40s max chip erase */
@@ -69,15 +70,24 @@ static const struct spi_device_id *spi_nor_match_id(const char *name);
 static int read_sr(struct spi_nor *nor)
 {
 	int ret;
-	u8 val;
+	u8 val[2];

-	ret = nor->read_reg(nor, SPINOR_OP_RDSR, &val, 1);
-	if (ret < 0) {
-		pr_err("error %d reading SR\n", (int) ret);
-		return ret;
+	if (nor->isparallel) {
+		ret = nor->read_reg(nor, SPINOR_OP_RDSR, &val[0], 2);
+		if (ret < 0) {
+			pr_err("error %d reading SR\n", (int) ret);
+			return ret;
+		}
+		val[0] |= val[1];
+	} else {
+		ret = nor->read_reg(nor, SPINOR_OP_RDSR, &val[0], 1);
+		if (ret < 0) {
+			pr_err("error %d reading SR\n", (int) ret);
+			return ret;
+		}
 	}

-	return val;
+	return val[0];
 }

 /*
@@ -87,16 +97,24 @@ static int read_sr(struct spi_nor *nor)
  */
 static int read_fsr(struct spi_nor *nor)
 {
-	int ret;
-	u8 val;
+	int ret, size;
+	u8 val[2];
+
+	size = 1;
+	val[1] = 0xff;
+
+	if (nor->isparallel)
+		size = 2;

-	ret = nor->read_reg(nor, SPINOR_OP_RDFSR, &val, 1);
+	ret = nor->read_reg(nor, SPINOR_OP_RDFSR, &val[0], size);
 	if (ret < 0) {
 		pr_err("error %d reading FSR\n", ret);
 		return ret;
 	}

-	return val;
+	val[0] &= val[1];
+
+	return val[0];
 }

 /*
@@ -317,6 +335,9 @@ static int spi_nor_erase(struct mtd_info *mtd, struct erase_info *instr)
 	if (ret)
 		return ret;

+	if (nor->isparallel)
+		nor->spi->master->flags |= SPI_MASTER_DATA_STRIPE;
+
 	/* whole-chip erase? */
 	if (len == mtd->size) {
 		write_enable(nor);
@@ -340,6 +361,8 @@ static int spi_nor_erase(struct mtd_info *mtd, struct erase_info *instr)
 		while (len) {
 			write_enable(nor);

+			addr = addr >> nor->shift;
+
 			if (nor->erase(nor, addr)) {
 				ret = -EIO;
 				goto erase_err;
@@ -360,19 +383,22 @@ static int spi_nor_erase(struct mtd_info *mtd, struct erase_info *instr)

 	instr->state = MTD_ERASE_DONE;
 	mtd_erase_callback(instr);
-
+	if (nor->isparallel)
+		nor->spi->master->flags &= ~SPI_MASTER_DATA_STRIPE;
 	return ret;

 erase_err:
 	spi_nor_unlock_and_unprep(nor, SPI_NOR_OPS_ERASE);
 	instr->state = MTD_ERASE_FAILED;
+	if (nor->isparallel)
+		nor->spi->master->flags &= ~SPI_MASTER_DATA_STRIPE;
 	return ret;
 }

 static int stm_lock(struct spi_nor *nor, loff_t ofs, uint64_t len)
 {
 	struct mtd_info *mtd = nor->mtd;
-	uint32_t offset = ofs;
+	uint32_t offset = ofs >> nor->shift;
 	uint8_t status_old, status_new;
 	int ret = 0;

@@ -406,7 +432,7 @@ static int stm_lock(struct spi_nor *nor, loff_t ofs, uint64_t len)
 static int stm_unlock(struct spi_nor *nor, loff_t ofs, uint64_t len)
 {
 	struct mtd_info *mtd = nor->mtd;
-	uint32_t offset = ofs;
+	uint32_t offset = ofs >> nor->shift;
 	uint8_t status_old, status_new;
 	int ret = 0;

@@ -446,6 +472,8 @@ static int spi_nor_lock(struct mtd_info *mtd, loff_t ofs, uint64_t len)
 	if (ret)
 		return ret;

+	ofs = ofs >> nor->shift;
+
 	ret = nor->flash_lock(nor, ofs, len);

 	spi_nor_unlock_and_unprep(nor, SPI_NOR_OPS_UNLOCK);
@@ -461,6 +489,8 @@ static int spi_nor_unlock(struct mtd_info *mtd, loff_t ofs, uint64_t len)
 	if (ret)
 		return ret;

+	ofs = ofs >> nor->shift;
+
 	ret = nor->flash_unlock(nor, ofs, len);

 	spi_nor_unlock_and_unprep(nor, SPI_NOR_OPS_LOCK);
@@ -707,6 +737,7 @@ static const struct spi_device_id *spi_nor_read_id(struct spi_nor *nor)
 	int			tmp;
 	u8			id[SPI_NOR_MAX_ID_LEN];
 	struct flash_info	*info;
+	nor->spi->master->flags &= ~SPI_MASTER_BOTH_CS;

 	tmp = nor->read_reg(nor, SPINOR_OP_RDID, id, SPI_NOR_MAX_ID_LEN);
 	if (tmp < 0) {
@@ -738,7 +769,13 @@ static int spi_nor_read(struct mtd_info *mtd, loff_t from, size_t len,
 	if (ret)
 		return ret;

-	ret = nor->read(nor, from, len, retlen, buf);
+	if (nor->isparallel)
+		nor->spi->master->flags |= SPI_MASTER_DATA_STRIPE;
+
+	ret = nor->read(nor, from >> nor->shift, len, retlen, buf);
+
+	if (nor->isparallel)
+		nor->spi->master->flags &= ~SPI_MASTER_DATA_STRIPE;

 	spi_nor_unlock_and_unprep(nor, SPI_NOR_OPS_READ);
 	return ret;
@@ -834,11 +871,11 @@ static int spi_nor_write(struct mtd_info *mtd, loff_t to, size_t len,

 	/* do all the bytes fit onto one page? */
 	if (page_offset + len <= nor->page_size) {
-		nor->write(nor, to, len, retlen, buf);
+		nor->write(nor, to >> nor->shift, len, retlen, buf);
 	} else {
 		/* the size of data remaining on the first page */
 		page_size = nor->page_size - page_offset;
-		nor->write(nor, to, page_size, retlen, buf);
+		nor->write(nor, to >> nor->shift, page_size, retlen, buf);

 		/* write everything in nor->page_size chunks */
 		for (i = page_size; i < len; i += page_size) {
@@ -852,12 +889,15 @@ static int spi_nor_write(struct mtd_info *mtd, loff_t to, size_t len,

 			write_enable(nor);

-			nor->write(nor, to + i, page_size, retlen, buf + i);
+			nor->write(nor, (to + i) >> nor->shift, page_size,
+					retlen, buf + i);
 		}
 	}

 	ret = spi_nor_wait_till_ready(nor);
 write_err:
+	if (nor->isparallel)
+		nor->spi->master->flags &= ~SPI_MASTER_DATA_STRIPE;
 	spi_nor_unlock_and_unprep(nor, SPI_NOR_OPS_WRITE);
 	return ret;
 }
@@ -1073,6 +1113,20 @@ int spi_nor_scan(struct spi_nor *nor, const char *name, enum read_mode mode)
 	mtd->_erase = spi_nor_erase;
 	mtd->_read = spi_nor_read;

+#ifdef CONFIG_OF
+	struct device_node *np_spi = of_get_next_parent(np);
+	u32 is_dual;
+
+	if (of_property_read_u32(np_spi, "is-dual", &is_dual) > 0) {
+		nor->shift = 1;
+		info->sector_size <<= nor->shift;
+		info->page_size <<= nor->shift;
+		mtd->size <<= nor->shift;
+		nor->isparallel = 1;
+		nor->spi->master->flags |= SPI_MASTER_BOTH_CS;
+	}
+#endif
+
 	/* nor protection support for STmicro chips */
 	if (JEDEC_MFR(info) == CFI_MFR_ST) {
 		nor->flash_lock = stm_lock;
@@ -1097,10 +1151,10 @@ int spi_nor_scan(struct spi_nor *nor, const char *name, enum read_mode mode)
 	/* prefer "small sector" erase if possible */
 	if (info->flags & SECT_4K) {
 		nor->erase_opcode = SPINOR_OP_BE_4K;
-		mtd->erasesize = 4096;
+		mtd->erasesize = 4096 << nor->shift;
 	} else if (info->flags & SECT_4K_PMC) {
 		nor->erase_opcode = SPINOR_OP_BE_4K_PMC;
-		mtd->erasesize = 4096;
+		mtd->erasesize = 4096 << nor->shift;
 	} else
 #endif
 	{
diff --git a/include/linux/mtd/spi-nor.h b/include/linux/mtd/spi-nor.h
index e540952..6ef25a8 100644
--- a/include/linux/mtd/spi-nor.h
+++ b/include/linux/mtd/spi-nor.h
@@ -163,6 +163,7 @@ struct spi_nor {
 	struct mtd_info		*mtd;
 	struct mutex		lock;
 	struct device		*dev;
+	struct spi_device	*spi;
 	u32			page_size;
 	u8			addr_width;
 	u8			erase_opcode;
@@ -170,6 +171,8 @@ struct spi_nor {
 	u8			read_dummy;
 	u8			program_opcode;
 	enum read_mode		flash_read;
+	bool			shift;
+	bool			isparallel;
 	bool			sst_write_second;
 	u32			flags;
 	struct spi_nor_xfer_cfg	cfg;
diff --git a/include/linux/spi/spi.h b/include/linux/spi/spi.h
index d673072..8dec349 100644
--- a/include/linux/spi/spi.h
+++ b/include/linux/spi/spi.h
@@ -355,6 +355,8 @@ struct spi_master {
 #define SPI_MASTER_NO_TX	BIT(2)		/* can't do buffer write */
 #define SPI_MASTER_MUST_RX      BIT(3)		/* requires rx */
 #define SPI_MASTER_MUST_TX      BIT(4)		/* requires tx */
+#define SPI_MASTER_DATA_STRIPE		BIT(7)		/* support data stripe */
+#define SPI_MASTER_BOTH_CS		BIT(8)		/* enable both chips */

 	/* lock and mutex for SPI bus locking */
 	spinlock_t		bus_lock_spinlock;
--
2.1.2



From eric.auger at linaro.org  Mon Aug  3 02:07:29 2015
From: eric.auger at linaro.org (Eric Auger)
Date: Mon, 03 Aug 2015 11:07:29 +0200
Subject: [PATCH v2 14/15] KVM: arm64: implement MSI injection in ITS
 emulation
In-Reply-To: <00a201d0cdb7$70a623f0$51f26bd0$@samsung.com>
References: <1436538111-4294-1-git-send-email-andre.przywara@arm.com>
 <1436538111-4294-15-git-send-email-andre.przywara@arm.com>
 <55BB7678.5080105@linaro.org> <55BE7BA1.40403@arm.com>
 <00a201d0cdb7$70a623f0$51f26bd0$@samsung.com>
Message-ID: <55BF2F51.6020701@linaro.org>

Hi Andre, Pavel,
On 08/03/2015 08:41 AM, Pavel Fedin wrote:
>  Hi!
> 
>> When I reworked our code to only use a flag and not a separate routing
>> type I ended up with the flag only guarding assignments, which wouldn't
>> hurt if done unconditionally (since they are all u32's). So the whole
>> usage of the flag is somewhat in jeopardy now.
>> Either the eventual MSI consumer requires a DevID (ITS emulation, which
>> will not work without it) or the consumer does not care at all and can
>> totally ignore it (GICv2m). So I think we can always pass on the DevID
> 
>  I have just checked my current code, and you know what... You are right. We already have a per-VM
> capability which actually tells us that MSIs for this VM require devID. Therefore, we really don't
> need this flag at all, neither for MSI doorbell, nor for GSI routing.
>  All we need is 'devid' field, which indeed can be just ignored for GICv2(m), just for simplicity.
> Ignoring would happen automatically, because IIRC older kernels do not explicitly check 'pad' for
> being zero, do they? And indeed in this case the userland can supply devid unconditionally, making
> things even simpler.

Again the case that leaves me uncomfortable is the one where the
userspace does not provide the devid whereas it must (GICv3 ITS case).
We cannot be confident in userspace to behave correctly. In such a case
devid == 0 and we cannot discriminate this from a valid devid. Do I miss
something?

Best Regards

Eric
> 
> Kind regards,
> Pavel Fedin
> Expert Engineer
> Samsung Electronics Research center Russia
> 
> 
> --
> To unsubscribe from this list: send the line "unsubscribe kvm" in
> the body of a message to majordomo at vger.kernel.org
> More majordomo info at  http://vger.kernel.org/majordomo-info.html
> 



From will.deacon at arm.com  Mon Aug  3 02:09:51 2015
From: will.deacon at arm.com (Will Deacon)
Date: Mon, 3 Aug 2015 10:09:51 +0100
Subject: [RFC 2/3] arm64: refactor save_stack_trace()
In-Reply-To: <20150720162004.GL9908@arm.com>
References: <12F47692-3010-4886-B87D-3D7820609177@gmail.com>
 <20150716113115.45a17f17@gandalf.local.home>
 <20150716121658.7982fdf5@gandalf.local.home>
 <20150717124054.GE26091@leverpostej>
 <20150717090009.720f6bd0@gandalf.local.home>
 <77EA0F10-D5F6-48BD-8652-3B979A978659@gmail.com>
 <20150717104144.6588b2f7@gandalf.local.home>
 <0886A996-40E1-49E9-823C-85E55A858716@gmail.com>
 <1357EA74-B972-4B99-ADB0-BC7E8F06DDB5@gmail.com>
 <20150720162004.GL9908@arm.com>
Message-ID: <20150803090951.GA10501@arm.com>

Hi guys,

On Mon, Jul 20, 2015 at 05:20:04PM +0100, Will Deacon wrote:
> On Fri, Jul 17, 2015 at 04:34:21PM +0100, Jungseok Lee wrote:
> > On Jul 17, 2015, at 11:59 PM, Jungseok Lee wrote:
> > > On Jul 17, 2015, at 11:41 PM, Steven Rostedt wrote:
> > >> Thanks! Can you repost patch 1 with the changes I recommended, so that
> > >> I can get an Acked-by from the arm64 maintainers and pull all the
> > >> changes in together. This is fine for a 4.3 release, right? That is, it
> > >> doesn't need to go into 4.2-rcs.
> > >> 
> > > 
> > > It's not hard to repost a patch, but I feel like we have to wait for Akashi's response.
> > > Also, it might be needed to consider Mark's comment on arch part.
> > > 
> > > If they are okay, I will proceed.
> > 
> > The [RFC 1/3] patch used in my environment is shaped as follows.
> > I leave the hunk for *only* clear synchronization. This is why I choose this format
> > instead of reposting a patch. I hope it would help to track down this thread.
> > 
> > I think this is my best at this point.

[...]

> The arm64 bits look fine to me:
> 
>   Acked-by: Will Deacon <will.deacon at arm.com>

What happened to this? Is it queued someplace, or are we waiting for a
new version?

Will


From eric.auger at linaro.org  Mon Aug  3 02:11:19 2015
From: eric.auger at linaro.org (Eric Auger)
Date: Mon, 03 Aug 2015 11:11:19 +0200
Subject: [PATCH v2 7/7] KVM: arm: implement kvm_set_msi by gsi direct
 mapping
In-Reply-To: <55BE7C32.8070707@arm.com>
References: <1436430137-24205-1-git-send-email-eric.auger@linaro.org>
 <1436430137-24205-8-git-send-email-eric.auger@linaro.org>
 <55A05282.6020105@arm.com> <55BB714A.8030307@linaro.org>
 <55BE7C32.8070707@arm.com>
Message-ID: <55BF3037.4090605@linaro.org>

On 08/02/2015 10:23 PM, Andre Przywara wrote:
> On 31/07/15 13:59, Eric Auger wrote:
>> Hi Andre,
>> On 07/11/2015 01:17 AM, Andre Przywara wrote:
>>> On 09/07/15 09:22, Eric Auger wrote:
>>>> If the ITS modality is not available, let's simply support MSI
>>>> injection by transforming the MSI.data into an SPI ID.
>>>>
>>>> This becomes possible to use KVM_SIGNAL_MSI ioctl for arm too.
>>>>
>>>> Signed-off-by: Eric Auger <eric.auger at linaro.org>
>>>>
>>>> ---
>>>>
>>>> v1 -> v2:
>>>> - introduce vgic_v2m_inject_msi in vgic-v2-emul.c following Andre's
>>>>   advice
>>>> ---
>>>>  arch/arm/kvm/Kconfig        |  1 +
>>>>  virt/kvm/arm/vgic-v2-emul.c | 12 ++++++++++++
>>>>  2 files changed, 13 insertions(+)
>>>>
>>>> diff --git a/arch/arm/kvm/Kconfig b/arch/arm/kvm/Kconfig
>>>> index 151e710..0f58baf 100644
>>>> --- a/arch/arm/kvm/Kconfig
>>>> +++ b/arch/arm/kvm/Kconfig
>>>> @@ -31,6 +31,7 @@ config KVM
>>>>  	select KVM_VFIO
>>>>  	select HAVE_KVM_EVENTFD
>>>>  	select HAVE_KVM_IRQFD
>>>> +	select HAVE_KVM_MSI
>>>
>>> I wonder if this requires some more code to only advertise
>>> KVM_CAP_SIGNAL_MSI if userland actually sets up a GICv2M?
>>> Otherwise userland could get the idea of being able to inectj MSIs
>>> without the guest actually being prepared for that (because the GICv2M
>>> driver did not initialize).
>> Not sure I get what you mean here. By directly transforming the user
>> provided MSI msg into an SPI ID, do we really have to care about GICv2M?
> 
> By user provided message you mean from user space? So this is an
> emulated device, which the guest programs with an MSI payload and a
> doorbell address at least? So how would a guest know these things
> without having a MSI capable interrupt controller?
> 
> Or are we talking about different things here?

I meant GICv2m is emulated on user-side today so I don't see how the
kernel could check anything. For the MSI injection, in that case, we
only use irqfd standard IRQ injection.

Cheers

Eric
> 
> Cheers,
> Andre.
> 
>>
>> Best Regards
>>
>> Eric
>>>
>>> Cheers,
>>> Andre.
>>>
>>>>  	select HAVE_KVM_IRQCHIP
>>>>  	select HAVE_KVM_IRQ_ROUTING
>>>>  	depends on ARM_VIRT_EXT && ARM_LPAE && ARM_ARCH_TIMER
>>>> diff --git a/virt/kvm/arm/vgic-v2-emul.c b/virt/kvm/arm/vgic-v2-emul.c
>>>> index 1390797..43013cc 100644
>>>> --- a/virt/kvm/arm/vgic-v2-emul.c
>>>> +++ b/virt/kvm/arm/vgic-v2-emul.c
>>>> @@ -478,6 +478,17 @@ static bool vgic_v2_queue_sgi(struct kvm_vcpu *vcpu, int irq)
>>>>  }
>>>>  
>>>>  /**
>>>> + * Emulates GICv2M MSI injection by injecting the SPI ID matching
>>>> + * the msi data
>>>> + * @kvm: pointer to the kvm struct
>>>> + * @msi: the msi struct handle
>>>> + */
>>>> +static int vgic_v2m_inject_msi(struct kvm *kvm, struct kvm_msi *msi)
>>>> +{
>>>> +	return kvm_vgic_inject_irq(kvm, 0, msi->data, 1);
>>>> +}
>>>> +
>>>> +/**
>>>>   * kvm_vgic_map_resources - Configure global VGIC state before running any VCPUs
>>>>   * @kvm: pointer to the kvm struct
>>>>   *
>>>> @@ -566,6 +577,7 @@ void vgic_v2_init_emulation(struct kvm *kvm)
>>>>  	dist->vm_ops.add_sgi_source = vgic_v2_add_sgi_source;
>>>>  	dist->vm_ops.init_model = vgic_v2_init_model;
>>>>  	dist->vm_ops.map_resources = vgic_v2_map_resources;
>>>> +	dist->vm_ops.inject_msi = vgic_v2m_inject_msi;
>>>>  
>>>>  	kvm->arch.max_vcpus = VGIC_V2_MAX_CPUS;
>>>>  }
>>>>
>>>
>>
> 



From maxime.ripard at free-electrons.com  Mon Aug  3 02:13:00 2015
From: maxime.ripard at free-electrons.com (Maxime Ripard)
Date: Mon, 3 Aug 2015 11:13:00 +0200
Subject: [PATCH] ARM: dts: sunxi: Raise minimum CPU voltage for sun7i-a20
 to a level all boards can supply
In-Reply-To: <1438543386-7253-1-git-send-email-public_timo.s@silentcreek.de>
References: <1438543386-7253-1-git-send-email-public_timo.s@silentcreek.de>
Message-ID: <20150803091300.GY2564@lukather>

On Sun, Aug 02, 2015 at 09:23:06PM +0200, Timo Sigurdsson wrote:
> sun7i-a20.dtsi contains an cpufreq operating point at 0.9 volts. Most A20 boards
> (or all?), however, do not allow the voltage to go below 1.0V. Thus, raise the
> voltage for the lowest operating point to 1.0V so all boards can actually use
> it.

This is not a property of a board, but is the actual limit documented
by Allwinner for the A20. Some individual SoCs might have wider
tolerances, but that's not a property of a board, it's really a
property of a single SoC, and we cannot make any assumption on the
board.

(and please make sure to run checkpatch before sending your patches)

Thanks!
Maxime

-- 
Maxime Ripard, Free Electrons
Embedded Linux, Kernel and Android engineering
http://free-electrons.com
-------------- next part --------------
A non-text attachment was scrubbed...
Name: signature.asc
Type: application/pgp-signature
Size: 819 bytes
Desc: Digital signature
URL: <http://lists.infradead.org/pipermail/linux-arm-kernel/attachments/20150803/50e7d12a/attachment.sig>

From maxime.ripard at free-electrons.com  Mon Aug  3 02:16:24 2015
From: maxime.ripard at free-electrons.com (Maxime Ripard)
Date: Mon, 3 Aug 2015 11:16:24 +0200
Subject: [linux-sunxi] [PATCH] ARM: dts: sunxi: Raise minimum CPU voltage
 for sun7i-a20 to a level all boards can supply
In-Reply-To: <CAGRGNgV6b9yt2HnB2x2Wyc05KEahoX-Y+mVhxsryztcfA36H1g@mail.gmail.com>
References: <1438543386-7253-1-git-send-email-public_timo.s@silentcreek.de>
 <CAGRGNgV6b9yt2HnB2x2Wyc05KEahoX-Y+mVhxsryztcfA36H1g@mail.gmail.com>
Message-ID: <20150803091624.GZ2564@lukather>

On Mon, Aug 03, 2015 at 09:35:51AM +1000, Julian Calaby wrote:
> Hi Timo,
> 
> On Mon, Aug 3, 2015 at 5:23 AM, Timo Sigurdsson
> <public_timo.s at silentcreek.de> wrote:
> > sun7i-a20.dtsi contains an cpufreq operating point at 0.9 volts. Most A20 boards
> > (or all?), however, do not allow the voltage to go below 1.0V. Thus, raise the
> > voltage for the lowest operating point to 1.0V so all boards can actually use
> > it.
> 
> Surely it wouldn't be added here if some could supply 0.9v.
> 
> Is the code that uses this smart enough to sensibly switch between two
> operating points with the same frequency and different voltages? If
> so, maybe just add a 144MHz @ 1.0v operating point?

And how would it choose between the two exactly ? Switch to the 144MHz
@ 0.9V and see if it works ? If it doesn't you might have screwed your
system already, and might not be able to recover from it at all.

Maxime

-- 
Maxime Ripard, Free Electrons
Embedded Linux, Kernel and Android engineering
http://free-electrons.com
-------------- next part --------------
A non-text attachment was scrubbed...
Name: signature.asc
Type: application/pgp-signature
Size: 819 bytes
Desc: Digital signature
URL: <http://lists.infradead.org/pipermail/linux-arm-kernel/attachments/20150803/08e0c339/attachment.sig>

From p.fedin at samsung.com  Mon Aug  3 02:16:27 2015
From: p.fedin at samsung.com (Pavel Fedin)
Date: Mon, 03 Aug 2015 12:16:27 +0300
Subject: [PATCH v2 14/15] KVM: arm64: implement MSI injection in ITS
 emulation
In-Reply-To: <55BF2F51.6020701@linaro.org>
References: <1436538111-4294-1-git-send-email-andre.przywara@arm.com>
 <1436538111-4294-15-git-send-email-andre.przywara@arm.com>
 <55BB7678.5080105@linaro.org> <55BE7BA1.40403@arm.com>
 <00a201d0cdb7$70a623f0$51f26bd0$@samsung.com> <55BF2F51.6020701@linaro.org>
Message-ID: <00f101d0cdcd$146a6090$3d3f21b0$@samsung.com>

 Hello!

> Again the case that leaves me uncomfortable is the one where the
> userspace does not provide the devid whereas it must (GICv3 ITS case).

 Hypothetical broken userland which does not exist for now ?
 IMHO the userland should just know, that if it supports ITS, it has to provide devIDs.

Kind regards,
Pavel Fedin
Expert Engineer
Samsung Electronics Research center Russia




From maxime.ripard at free-electrons.com  Mon Aug  3 02:23:25 2015
From: maxime.ripard at free-electrons.com (Maxime Ripard)
Date: Mon, 3 Aug 2015 11:23:25 +0200
Subject: [linux-sunxi] [PATCH] ARM: dts: sunxi: Raise minimum CPU voltage
 for sun7i-a20 to a level all boards can supply
In-Reply-To: <20150803083751.1BCF56C80391@dd34104.kasserver.com>
References: <1438543386-7253-1-git-send-email-public_timo.s@silentcreek.de>
 <CAGRGNgV6b9yt2HnB2x2Wyc05KEahoX-Y+mVhxsryztcfA36H1g@mail.gmail.com>
 <20150803083751.1BCF56C80391@dd34104.kasserver.com>
Message-ID: <20150803092325.GA2564@lukather>

On Mon, Aug 03, 2015 at 10:37:51AM +0200, Timo Sigurdsson wrote:
> Hi Julian,
> 
> Julian Calaby schrieb am 03.08.2015 01:35:
> >> sun7i-a20.dtsi contains an cpufreq operating point at 0.9 volts. Most A20
> >> boards
> >> (or all?), however, do not allow the voltage to go below 1.0V. Thus, raise the
> >> voltage for the lowest operating point to 1.0V so all boards can actually use
> >> it.
> > 
> > Surely it wouldn't be added here if some could supply 0.9v.
> 
> Maybe. I just know some boards don't (e.g. Cubieboard 2, Cubietruck, BananaPi)
> and don't know of any that does. But that's not my point. I think that a common
> minimum operating point, defined on the SOC level, should be defined in a way
> that works on all boards.

All of them can supply it. The DCDC2 regulator they use for the CPU
can go as low as 0.7V. The question is whether the CPU itself can work
at such a low voltage. And the operating limits for the CPU is
documented to be 1V - 1.4V. Anything else is either over or
underclocking, which might or might not work on individual SoCs. So
it's not something that we're going to support.

Maxime

-- 
Maxime Ripard, Free Electrons
Embedded Linux, Kernel and Android engineering
http://free-electrons.com
-------------- next part --------------
A non-text attachment was scrubbed...
Name: signature.asc
Type: application/pgp-signature
Size: 819 bytes
Desc: Digital signature
URL: <http://lists.infradead.org/pipermail/linux-arm-kernel/attachments/20150803/3773a03f/attachment.sig>

From stefan at agner.ch  Mon Aug  3 02:27:28 2015
From: stefan at agner.ch (Stefan Agner)
Date: Mon,  3 Aug 2015 11:27:28 +0200
Subject: [PATCH v10 3/5] mtd: nand: vf610_nfc: add device tree bindings
In-Reply-To: <1438594050-4595-1-git-send-email-stefan@agner.ch>
References: <1438594050-4595-1-git-send-email-stefan@agner.ch>
Message-ID: <1438594050-4595-4-git-send-email-stefan@agner.ch>

Signed-off-by: Bill Pringlemeir <bpringlemeir at nbsps.com>
Acked-by: Shawn Guo <shawnguo at kernel.org>
Reviewed-by: Brian Norris <computersforpeace at gmail.com>
Signed-off-by: Stefan Agner <stefan at agner.ch>
---
 .../devicetree/bindings/mtd/vf610-nfc.txt          | 45 ++++++++++++++++++++++
 1 file changed, 45 insertions(+)
 create mode 100644 Documentation/devicetree/bindings/mtd/vf610-nfc.txt

diff --git a/Documentation/devicetree/bindings/mtd/vf610-nfc.txt b/Documentation/devicetree/bindings/mtd/vf610-nfc.txt
new file mode 100644
index 0000000..cae5f25
--- /dev/null
+++ b/Documentation/devicetree/bindings/mtd/vf610-nfc.txt
@@ -0,0 +1,45 @@
+Freescale's NAND flash controller (NFC)
+
+This variant of the Freescale NAND flash controller (NFC) can be found on
+Vybrid (vf610), MPC5125, MCF54418 and Kinetis K70.
+
+Required properties:
+- compatible: Should be set to "fsl,vf610-nfc"
+- reg: address range of the NFC
+- interrupts: interrupt of the NFC
+- nand-bus-width: see nand.txt
+- nand-ecc-mode: see nand.txt
+- nand-on-flash-bbt: see nand.txt
+- assigned-clocks: main clock from the SoC, for Vybrid <&clks VF610_CLK_NFC>;
+- assigned-clock-rates: The NAND bus timing is derived from this clock
+    rate and should not exceed maximum timing for any NAND memory chip
+    in a board stuffing. Typical NAND memory timings derived from this
+    clock are found in the SoC hardware reference manual. Furthermore,
+    there might be restrictions on maximum rates when using hardware ECC.
+
+- #address-cells, #size-cells : Must be present if the device has sub-nodes
+  representing partitions.
+
+Required properties for hardware ECC:
+- nand-ecc-strength: supported strengths are 24 and 32 bit (see nand.txt)
+- nand-ecc-step-size: step size equals page size, currently only 2k pages are
+    supported
+
+Example:
+
+	nfc: nand at 400e0000 {
+		compatible = "fsl,vf610-nfc";
+		#address-cells = <1>;
+		#size-cells = <1>;
+		reg = <0x400e0000 0x4000>;
+		interrupts = <GIC_SPI 83 IRQ_TYPE_LEVEL_HIGH>;
+		clocks = <&clks VF610_CLK_NFC>;
+		clock-names = "nfc";
+		assigned-clocks = <&clks VF610_CLK_NFC>;
+		assigned-clock-rates = <33000000>;
+		nand-bus-width = <8>;
+		nand-ecc-mode = "hw";
+		nand-ecc-strength = <32>;
+		nand-ecc-step-size = <2048>;
+		nand-on-flash-bbt;
+	};
-- 
2.5.0



From stefan at agner.ch  Mon Aug  3 02:27:27 2015
From: stefan at agner.ch (Stefan Agner)
Date: Mon,  3 Aug 2015 11:27:27 +0200
Subject: [PATCH v10 2/5] mtd: nand: vf610_nfc: add hardware BCH-ECC support
In-Reply-To: <1438594050-4595-1-git-send-email-stefan@agner.ch>
References: <1438594050-4595-1-git-send-email-stefan@agner.ch>
Message-ID: <1438594050-4595-3-git-send-email-stefan@agner.ch>

This adds hardware ECC support using the BCH encoder in the NFC IP.
The ECC encoder supports up to 32-bit correction by using 60 error
correction bytes. There is no sub-page ECC step, ECC is calculated
always accross the whole page (up to 2k pages). Raw writes writes
are possible through the common nand_write_page_raw implementation,
however raw reads are not possible since the hardware ECC mode need
to be enabled at command time.

Signed-off-by: Bill Pringlemeir <bpringlemeir at nbsps.com>
Signed-off-by: Stefan Agner <stefan at agner.ch>
---
 drivers/mtd/nand/Kconfig     |   6 +-
 drivers/mtd/nand/vf610_nfc.c | 206 ++++++++++++++++++++++++++++++++++++++++++-
 2 files changed, 209 insertions(+), 3 deletions(-)

diff --git a/drivers/mtd/nand/Kconfig b/drivers/mtd/nand/Kconfig
index 8550b14..e05f53c 100644
--- a/drivers/mtd/nand/Kconfig
+++ b/drivers/mtd/nand/Kconfig
@@ -469,8 +469,10 @@ config MTD_NAND_VF610_NFC
 	help
 	  Enables support for NAND Flash Controller on some Freescale
 	  processors like the VF610, MPC5125, MCF54418 or Kinetis K70.
-	  The driver supports a maximum 2k page size. The driver
-	  currently does not support hardware ECC.
+	  The driver supports a maximum 2k page size. With 2k pages and
+	  64 bytes or more of OOB, hardware ECC with up to 32-bit error
+	  correction is supported. Hardware ECC is only enabled through
+	  device tree.
 
 config MTD_NAND_MXC
 	tristate "MXC NAND support"
diff --git a/drivers/mtd/nand/vf610_nfc.c b/drivers/mtd/nand/vf610_nfc.c
index 5c8dfe8..247f06a 100644
--- a/drivers/mtd/nand/vf610_nfc.c
+++ b/drivers/mtd/nand/vf610_nfc.c
@@ -19,6 +19,8 @@
  * - Untested on MPC5125 and M54418.
  * - DMA not used.
  * - 2K pages or less.
+ * - Only 2K page w. 64+ OOB and hardware ECC.
+ * - Raw page reads not implemented when using ECC.
  */
 
 #include <linux/module.h>
@@ -73,6 +75,8 @@
 
 /* NFC ECC mode define */
 #define ECC_BYPASS			0
+#define ECC_45_BYTE			6
+#define ECC_60_BYTE			7
 
 /*** Register Mask and bit definitions */
 
@@ -125,6 +129,21 @@
 #define CMD_DONE_CLEAR_BIT			BIT(18)
 #define IDLE_CLEAR_BIT				BIT(17)
 
+/* ECC status placed at end of buffers. */
+#define ECC_SRAM_ADDR	((PAGE_2K + 256 - 8) >> 3)
+#define ECC_STATUS_MASK	0x80
+#define ECC_ERR_COUNT	0x3F
+
+/*
+ * ECC status is stored at NFC_CFG[ECCADD] +4 for little-endian
+ * and +7 for big-endian SoCs.
+ */
+#ifdef __LITTLE_ENDIAN
+#define ECC_OFFSET	4
+#else
+#define ECC_OFFSET	7
+#endif
+
 struct vf610_nfc {
 	struct mtd_info mtd;
 	struct nand_chip chip;
@@ -139,10 +158,40 @@ struct vf610_nfc {
 #define ALT_BUF_STAT 2
 #define ALT_BUF_ONFI 3
 	struct clk *clk;
+	bool use_hw_ecc;
+	u32 ecc_mode;
 };
 
 #define mtd_to_nfc(_mtd) container_of(_mtd, struct vf610_nfc, mtd)
 
+static struct nand_ecclayout vf610_nfc_ecc45 = {
+	.eccbytes = 45,
+	.eccpos = {19, 20, 21, 22, 23,
+		   24, 25, 26, 27, 28, 29, 30, 31,
+		   32, 33, 34, 35, 36, 37, 38, 39,
+		   40, 41, 42, 43, 44, 45, 46, 47,
+		   48, 49, 50, 51, 52, 53, 54, 55,
+		   56, 57, 58, 59, 60, 61, 62, 63},
+	.oobfree = {
+		{.offset = 2,
+		 .length = 17} }
+};
+
+static struct nand_ecclayout vf610_nfc_ecc60 = {
+	.eccbytes = 60,
+	.eccpos = { 4,  5,  6,  7,  8,  9, 10, 11,
+		   12, 13, 14, 15, 16, 17, 18, 19,
+		   20, 21, 22, 23, 24, 25, 26, 27,
+		   28, 29, 30, 31, 32, 33, 34, 35,
+		   36, 37, 38, 39, 40, 41, 42, 43,
+		   44, 45, 46, 47, 48, 49, 50, 51,
+		   52, 53, 54, 55, 56, 57, 58, 59,
+		   60, 61, 62, 63 },
+	.oobfree = {
+		{.offset = 2,
+		 .length = 2} }
+};
+
 static inline u32 vf610_nfc_read(struct vf610_nfc *nfc, uint reg)
 {
 	return readl(nfc->regs + reg);
@@ -285,6 +334,13 @@ static void vf610_nfc_addr_cycle(struct vf610_nfc *nfc, int column, int page)
 				    ROW_ADDR_SHIFT, page);
 }
 
+static inline void vf610_nfc_ecc_mode(struct vf610_nfc *nfc, int ecc_mode)
+{
+	vf610_nfc_set_field(nfc, NFC_FLASH_CONFIG,
+			    CONFIG_ECC_MODE_MASK,
+			    CONFIG_ECC_MODE_SHIFT, ecc_mode);
+}
+
 static inline void vf610_nfc_transfer_size(struct vf610_nfc *nfc, int size)
 {
 	vf610_nfc_write(nfc, NFC_SECTOR_SIZE, size);
@@ -303,13 +359,20 @@ static void vf610_nfc_command(struct mtd_info *mtd, unsigned command,
 	case NAND_CMD_SEQIN:
 		/* Use valid column/page from preread... */
 		vf610_nfc_addr_cycle(nfc, column, page);
+		nfc->buf_offset = 0;
+
 		/*
 		 * SEQIN => data => PAGEPROG sequence is done by the controller
 		 * hence we do not need to issue the command here...
 		 */
 		return;
 	case NAND_CMD_PAGEPROG:
-		page_sz += mtd->writesize + mtd->oobsize;
+		page_sz += nfc->page_sz;
+		if (nfc->use_hw_ecc)
+			vf610_nfc_ecc_mode(nfc, nfc->ecc_mode);
+		else
+			vf610_nfc_ecc_mode(nfc, ECC_BYPASS);
+
 		vf610_nfc_transfer_size(nfc, page_sz);
 		vf610_nfc_send_commands(nfc, NAND_CMD_SEQIN,
 					command, PROGRAM_PAGE_CMD_CODE);
@@ -327,11 +390,13 @@ static void vf610_nfc_command(struct mtd_info *mtd, unsigned command,
 		vf610_nfc_send_commands(nfc, NAND_CMD_READ0,
 					NAND_CMD_READSTART, READ_PAGE_CMD_CODE);
 		vf610_nfc_addr_cycle(nfc, column, page);
+		vf610_nfc_ecc_mode(nfc, ECC_BYPASS);
 		break;
 
 	case NAND_CMD_READ0:
 		page_sz += mtd->writesize + mtd->oobsize;
 		vf610_nfc_transfer_size(nfc, page_sz);
+		vf610_nfc_ecc_mode(nfc, nfc->ecc_mode);
 		vf610_nfc_send_commands(nfc, NAND_CMD_READ0,
 					NAND_CMD_READSTART, READ_PAGE_CMD_CODE);
 		vf610_nfc_addr_cycle(nfc, column, page);
@@ -343,6 +408,7 @@ static void vf610_nfc_command(struct mtd_info *mtd, unsigned command,
 		vf610_nfc_send_command(nfc, command, READ_ONFI_PARAM_CMD_CODE);
 		vf610_nfc_set_field(nfc, NFC_ROW_ADDR, ROW_ADDR_MASK,
 				    ROW_ADDR_SHIFT, column);
+		vf610_nfc_ecc_mode(nfc, ECC_BYPASS);
 		break;
 
 	case NAND_CMD_ERASE1:
@@ -371,6 +437,9 @@ static void vf610_nfc_command(struct mtd_info *mtd, unsigned command,
 	}
 
 	vf610_nfc_done(nfc);
+
+	nfc->use_hw_ecc = false;
+	nfc->page_sz = 0;
 }
 
 static void vf610_nfc_read_buf(struct mtd_info *mtd, u_char *buf, int len)
@@ -396,6 +465,7 @@ static void vf610_nfc_write_buf(struct mtd_info *mtd, const uint8_t *buf,
 	l = min_t(uint, len, mtd->writesize + mtd->oobsize - c);
 	vf610_nfc_memcpy(nfc->regs + NFC_MAIN_AREA(0) + c, buf, l);
 
+	nfc->page_sz += l;
 	nfc->buf_offset += l;
 }
 
@@ -462,6 +532,91 @@ static void vf610_nfc_select_chip(struct mtd_info *mtd, int chip)
 #endif
 }
 
+/* Count the number of 0's in buff up to max_bits */
+static inline int count_written_bits(uint8_t *buff, int size, int max_bits)
+{
+	uint32_t *buff32 = (uint32_t *)buff;
+	int k, written_bits = 0;
+
+	for (k = 0; k < (size / 4); k++) {
+		written_bits += hweight32(~buff32[k]);
+		if (written_bits > max_bits)
+			break;
+	}
+
+	return written_bits;
+}
+
+static inline int vf610_nfc_correct_data(struct mtd_info *mtd, uint8_t *dat,
+					 uint8_t *oob, int oob_loaded)
+{
+	struct vf610_nfc *nfc = mtd_to_nfc(mtd);
+	u8 ecc_status;
+	u8 ecc_count;
+	int flip;
+
+	ecc_status = __raw_readb(nfc->regs + ECC_SRAM_ADDR * 8 + ECC_OFFSET);
+	ecc_count = ecc_status & ECC_ERR_COUNT;
+
+	if (!(ecc_status & ECC_STATUS_MASK))
+		return ecc_count;
+
+	if (!oob_loaded)
+		vf610_nfc_read_buf(mtd, oob, mtd->oobsize);
+
+	/*
+	 * On an erased page, bit count (including OOB) should be zero or
+	 * at least less then half of the ECC strength.
+	 */
+	flip = count_written_bits(dat, nfc->chip.ecc.size, ecc_count);
+	flip += count_written_bits(oob, mtd->oobsize - nfc->chip.ecc.bytes,
+				   ecc_count);
+
+	if (flip > ecc_count && flip > (nfc->chip.ecc.strength / 2))
+		return -1;
+
+	/* Erased page. */
+	memset(dat, 0xff, nfc->chip.ecc.size);
+	return 0;
+}
+
+static int vf610_nfc_read_page(struct mtd_info *mtd, struct nand_chip *chip,
+				uint8_t *buf, int oob_required, int page)
+{
+	int eccsize = chip->ecc.size;
+	int stat;
+
+	vf610_nfc_read_buf(mtd, buf, eccsize);
+	if (oob_required)
+		vf610_nfc_read_buf(mtd, chip->oob_poi, mtd->oobsize);
+
+	stat = vf610_nfc_correct_data(mtd, buf, chip->oob_poi, oob_required);
+
+	if (stat < 0) {
+		mtd->ecc_stats.failed++;
+		return 0;
+	} else {
+		mtd->ecc_stats.corrected += stat;
+		return stat;
+	}
+}
+
+static int vf610_nfc_write_page(struct mtd_info *mtd, struct nand_chip *chip,
+			       const uint8_t *buf, int oob_required)
+{
+	struct vf610_nfc *nfc = mtd_to_nfc(mtd);
+
+	vf610_nfc_write_buf(mtd, buf, mtd->writesize);
+	if (oob_required)
+		vf610_nfc_write_buf(mtd, chip->oob_poi, mtd->oobsize);
+
+	/* Always write whole page including OOB due to HW ECC */
+	nfc->use_hw_ecc = true;
+	nfc->page_sz = mtd->writesize + mtd->oobsize;
+
+	return 0;
+}
+
 static const struct of_device_id vf610_nfc_dt_ids[] = {
 	{ .compatible = "fsl,vf610-nfc" },
 	{ /* sentinel */ }
@@ -488,6 +643,16 @@ static void vf610_nfc_init_controller(struct vf610_nfc *nfc)
 		vf610_nfc_set(nfc, NFC_FLASH_CONFIG, CONFIG_16BIT);
 	else
 		vf610_nfc_clear(nfc, NFC_FLASH_CONFIG, CONFIG_16BIT);
+
+	if (nfc->chip.ecc.mode == NAND_ECC_HW) {
+		/* Set ECC status offset in SRAM */
+		vf610_nfc_set_field(nfc, NFC_FLASH_CONFIG,
+				    CONFIG_ECC_SRAM_ADDR_MASK,
+				    CONFIG_ECC_SRAM_ADDR_SHIFT, ECC_SRAM_ADDR);
+
+		/* Enable ECC status in SRAM */
+		vf610_nfc_set(nfc, NFC_FLASH_CONFIG, CONFIG_ECC_SRAM_REQ_BIT);
+	}
 }
 
 static int vf610_nfc_probe(struct platform_device *pdev)
@@ -571,6 +736,45 @@ static int vf610_nfc_probe(struct platform_device *pdev)
 		goto error;
 	}
 
+	if (chip->ecc.mode == NAND_ECC_HW) {
+		if (mtd->writesize != PAGE_2K && mtd->oobsize < 64) {
+			dev_err(nfc->dev, "Unsupported flash with hwecc\n");
+			err = -ENXIO;
+			goto error;
+		}
+
+		if (chip->ecc.size != mtd->writesize) {
+			dev_err(nfc->dev, "Step size needs to be page size\n");
+			err = -ENXIO;
+			goto error;
+		}
+
+		/* Only 64 byte ECC layouts known */
+		if (mtd->oobsize > 64)
+			mtd->oobsize = 64;
+
+		if (chip->ecc.strength == 32) {
+			nfc->ecc_mode = ECC_60_BYTE;
+			chip->ecc.bytes = 60;
+			chip->ecc.layout = &vf610_nfc_ecc60;
+		} else if (chip->ecc.strength == 24) {
+			nfc->ecc_mode = ECC_45_BYTE;
+			chip->ecc.bytes = 45;
+			chip->ecc.layout = &vf610_nfc_ecc45;
+		} else {
+			dev_err(nfc->dev, "Unsupported ECC strength\n");
+			err = -ENXIO;
+			goto error;
+		}
+
+		/* propagate ecc.layout to mtd_info */
+		mtd->ecclayout = chip->ecc.layout;
+		chip->ecc.read_page = vf610_nfc_read_page;
+		chip->ecc.write_page = vf610_nfc_write_page;
+
+		chip->ecc.size = PAGE_2K;
+	}
+
 	/* second phase scan */
 	if (nand_scan_tail(mtd)) {
 		err = -ENXIO;
-- 
2.5.0



From stefan at agner.ch  Mon Aug  3 02:27:25 2015
From: stefan at agner.ch (Stefan Agner)
Date: Mon,  3 Aug 2015 11:27:25 +0200
Subject: [PATCH v10 0/5] mtd: nand: vf610_nfc: Freescale NFC for VF610
Message-ID: <1438594050-4595-1-git-send-email-stefan@agner.ch>

The 10th revision includes some more review comments, including an
improved handling of empty NAND pages with hardware ECC.

More information and the full test log of earlier patchset version
can be found in the cover letter of the last revision v6:
http://thread.gmane.org/gmane.linux.kernel/1979868

Changes since v9:
- Remove inline of vf610_nfc_done
- Add __iomem to src argument of vf610_nfc_memcpy
- Handle return value of mtd_device_parse_register correctly
- Count bits in OOB too (only non-ECC bits)
- Return bitflips in ecc.read_page callback vf610_nfc_read_page
- Fall-through ALT_BUF_ONFI
- Use BIT macros

Changes since v8:
- Fix 16-Bit NAND flash support by splitting up initialization
  (introduce vf610_nfc_preinit_controller)
- Updated comments in initialziation functions

Changes since v7:
- vf610-twr.dts: Moved NFC pinmux into the existing iomuxc node
  and sort new nfc node behind the existing iomuxc node as well.
- vf610-twr.dts/vf-colibri.dtsi: Dropped _1 suffixes

Changes since v6:
- Rebased ontop of l2-mtd/master (v4.2-rc1 based)
- Removed HAVE_NAND_VF610_NFC and use depends on. This made
  "[PATCH v6 4/6] ARM: vf610: enable NAND Flash Controller" unnecessary

Changes since v5:
- Removed fsl,mpc5125-nfc compatible string
- Removed readl/writel_relaxed
- Change interface of vf610_nfc_transfer_size to match other accessors

Changes since v4:
- Rebased ontop of l2-mtd/master (v4.1-rc4 based)
- Eliminate unnecessary page read (NAND_CMD_SEQIN) since the driver does
  not support sub-page writes anyway (improves write performance)
- Support ONFI by enabling READID command with offset and parameter page
  reads (CMD_PARAM)
- Change to dedicated read_page/write_page function, enables raw writes
- Use __LITTLE_ENDIAN to distingush between LE/BE relevant statements
- Eliminated vf610_nfc_probe_dt in favor of common DT init code
- Use wait_for_completion_timeout
- Some style fixes (spaces, etc.)

Changes since v3:
- Make the driver selectable when COMPILE_TEST is set
- Fix compile error due to superfluous ECC_STATUS configuration in initial
  patch (without ECC correction ECC_STATUS does not need to be configured)
- Remove custom BBT pattern and switch to in-band BBT in the initial patch
- Include two bug fixes, for details see the corresponding U-Boot patches:
  http://thread.gmane.org/gmane.comp.boot-loaders.u-boot/215802

Changes since v2:
- Updated binding documentation

Changes since v1:
- Nest nfc_config struct within the main nfc struct
- Use assigned clock binding to specify NFC clock
- Rebased ontop of MSCM IR patchset (driver parts have been merged)
- Split out arch Kconfig in a separate config
- Fix module license
- Updated MAINTAINERS

Changes since RFC (Bill Pringlemeir):
- Renamed driver from fsl_nfc to vf610_nfc
- Use readl/writel for all register in accessor functions
- Optimized field accessor functions
- Implemented PM (suspend/resume) functions
- Implemented basic support for ECC strength/ECC step size from dt
- Improved performance of count_written_bits by using hweight32
- Support ECC with 60-bytes to correct up to 32 bit errors
- Changed to in-band BBT (NAND_BBT_NO_OOB) which also allows ECC modes
  which uses up to 60 bytes on 64 byte OOB
- Removed custom (downstream) BBT pattern since BBT table won't be
  compatible anyway (due to the change above)

*** SUBJECT HERE ***

*** BLURB HERE ***

Stefan Agner (5):
  mtd: nand: vf610_nfc: Freescale NFC for VF610, MPC5125 and others
  mtd: nand: vf610_nfc: add hardware BCH-ECC support
  mtd: nand: vf610_nfc: add device tree bindings
  ARM: dts: vf610twr: add NAND flash controller peripherial
  ARM: dts: vf-colibri: enable NAND flash controller

 .../devicetree/bindings/mtd/vf610-nfc.txt          |  45 ++
 MAINTAINERS                                        |   6 +
 arch/arm/boot/dts/vf-colibri.dtsi                  |  32 +
 arch/arm/boot/dts/vf610-twr.dts                    |  40 +
 arch/arm/boot/dts/vfxxx.dtsi                       |   8 +
 drivers/mtd/nand/Kconfig                           |  11 +
 drivers/mtd/nand/Makefile                          |   1 +
 drivers/mtd/nand/vf610_nfc.c                       | 849 +++++++++++++++++++++
 8 files changed, 992 insertions(+)
 create mode 100644 Documentation/devicetree/bindings/mtd/vf610-nfc.txt
 create mode 100644 drivers/mtd/nand/vf610_nfc.c

-- 
2.5.0



From stefan at agner.ch  Mon Aug  3 02:27:29 2015
From: stefan at agner.ch (Stefan Agner)
Date: Mon,  3 Aug 2015 11:27:29 +0200
Subject: [PATCH v10 4/5] ARM: dts: vf610twr: add NAND flash controller
 peripherial
In-Reply-To: <1438594050-4595-1-git-send-email-stefan@agner.ch>
References: <1438594050-4595-1-git-send-email-stefan@agner.ch>
Message-ID: <1438594050-4595-5-git-send-email-stefan@agner.ch>

This adds the NAND flash controller (NFC) peripherial. The driver
supports the SLC NAND chips found on Freescale's Vybrid Tower System
Module. The Micron NAND chip on the module needs 4-bit ECC per 512
byte page. Use 24-bit ECC per 2k page, which is supported by the
driver.

Signed-off-by: Bill Pringlemeir <bpringlemeir at nbsps.com>
Reviewed-by: Brian Norris <computersforpeace at gmail.com>
Signed-off-by: Stefan Agner <stefan at agner.ch>
---
 arch/arm/boot/dts/vf610-twr.dts | 40 ++++++++++++++++++++++++++++++++++++++++
 arch/arm/boot/dts/vfxxx.dtsi    |  8 ++++++++
 2 files changed, 48 insertions(+)

diff --git a/arch/arm/boot/dts/vf610-twr.dts b/arch/arm/boot/dts/vf610-twr.dts
index 375ab23..2a278a2 100644
--- a/arch/arm/boot/dts/vf610-twr.dts
+++ b/arch/arm/boot/dts/vf610-twr.dts
@@ -237,6 +237,33 @@
 			>;
 		};
 
+		pinctrl_nfc: nfcgrp {
+			fsl,pins = <
+			VF610_PAD_PTD31__NF_IO15	0x28df
+			VF610_PAD_PTD30__NF_IO14	0x28df
+			VF610_PAD_PTD29__NF_IO13	0x28df
+			VF610_PAD_PTD28__NF_IO12	0x28df
+			VF610_PAD_PTD27__NF_IO11	0x28df
+			VF610_PAD_PTD26__NF_IO10	0x28df
+			VF610_PAD_PTD25__NF_IO9		0x28df
+			VF610_PAD_PTD24__NF_IO8		0x28df
+			VF610_PAD_PTD23__NF_IO7		0x28df
+			VF610_PAD_PTD22__NF_IO6		0x28df
+			VF610_PAD_PTD21__NF_IO5		0x28df
+			VF610_PAD_PTD20__NF_IO4		0x28df
+			VF610_PAD_PTD19__NF_IO3		0x28df
+			VF610_PAD_PTD18__NF_IO2		0x28df
+			VF610_PAD_PTD17__NF_IO1		0x28df
+			VF610_PAD_PTD16__NF_IO0		0x28df
+			VF610_PAD_PTB24__NF_WE_B	0x28c2
+			VF610_PAD_PTB25__NF_CE0_B	0x28c2
+			VF610_PAD_PTB27__NF_RE_B	0x28c2
+			VF610_PAD_PTC26__NF_RB_B	0x283d
+			VF610_PAD_PTC27__NF_ALE		0x28c2
+			VF610_PAD_PTC28__NF_CLE		0x28c2
+			>;
+		};
+
 		pinctrl_pwm0: pwm0grp {
 			fsl,pins = <
 				VF610_PAD_PTB0__FTM0_CH0		0x1582
@@ -274,6 +301,19 @@
 	};
 };
 
+&nfc {
+	assigned-clocks = <&clks VF610_CLK_NFC>;
+	assigned-clock-rates = <33000000>;
+	nand-bus-width = <16>;
+	nand-ecc-mode = "hw";
+	nand-ecc-step-size = <2048>;
+	nand-ecc-strength = <24>;
+	nand-on-flash-bbt;
+	pinctrl-names = "default";
+	pinctrl-0 = <&pinctrl_nfc>;
+	status = "okay";
+};
+
 &pwm0 {
 	pinctrl-names = "default";
 	pinctrl-0 = <&pinctrl_pwm0>;
diff --git a/arch/arm/boot/dts/vfxxx.dtsi b/arch/arm/boot/dts/vfxxx.dtsi
index 4aa3351..2f4b04d 100644
--- a/arch/arm/boot/dts/vfxxx.dtsi
+++ b/arch/arm/boot/dts/vfxxx.dtsi
@@ -520,6 +520,14 @@
 				status = "disabled";
 			};
 
+			nfc: nand at 400e0000 {
+				compatible = "fsl,vf610-nfc";
+				reg = <0x400e0000 0x4000>;
+				interrupts = <83 IRQ_TYPE_LEVEL_HIGH>;
+				clocks = <&clks VF610_CLK_NFC>;
+				clock-names = "nfc";
+				status = "disabled";
+			};
 		};
 	};
 };
-- 
2.5.0



From stefan at agner.ch  Mon Aug  3 02:27:26 2015
From: stefan at agner.ch (Stefan Agner)
Date: Mon,  3 Aug 2015 11:27:26 +0200
Subject: [PATCH v10 1/5] mtd: nand: vf610_nfc: Freescale NFC for VF610,
 MPC5125 and others
In-Reply-To: <1438594050-4595-1-git-send-email-stefan@agner.ch>
References: <1438594050-4595-1-git-send-email-stefan@agner.ch>
Message-ID: <1438594050-4595-2-git-send-email-stefan@agner.ch>

This driver supports Freescale NFC (NAND flash controller) found on
Vybrid (VF610), MPC5125, MCF54418 and Kinetis K70. The driver has
been tested on 8-bit and 16-bit NAND interface and supports ONFI
parameter page reading.

Limitations:
- DMA and pipelining not used
- Pages larger than 2k are not supported
- No hardware ECC

The driver has only been tested on Vybrid SoC VF610 and VF500.

Some paths have been hand-optimized and evaluated by measurements
made using mtd_speedtest.ko on a 100MB MTD partition.

Colibri VF50
    eb write     %   eb read     %   page write      %   page read     %
rel/opt     5175           11537                4560             11039
opt         5164 -0.21     11420 -1.01          4737 +3.88       10918 -1.10
none        5113 -1.20     11352 -1.60          4490 -1.54       10865 -1.58

Colibri VF61
    eb write     %   eb read     %   page write      %   page read     %
rel/opt     5766           13096                5459             12846
opt         5883 +2.03     13064 -0.24          5561 +1.87       12802 -0.34
none        5701 -1.13     12980 -0.89          5488 +0.53       12735 -0.86

rel = using readl_relaxed/writel_relaxed in optimized paths
opt = hand-optimized by combining multiple accesses into one read/write

The measurements have not been statistically verfied, hence use them
with care. The author came to the conclusion that using the relaxed
variants of readl/writel are not worth the additional code.

Signed-off-by: Bill Pringlemeir <bpringlemeir at nbsps.com>
Tested-by: Albert ARIBAUD <albert.aribaud at 3adev.fr>
Signed-off-by: Stefan Agner <stefan at agner.ch>
---
 MAINTAINERS                  |   6 +
 drivers/mtd/nand/Kconfig     |   9 +
 drivers/mtd/nand/Makefile    |   1 +
 drivers/mtd/nand/vf610_nfc.c | 645 +++++++++++++++++++++++++++++++++++++++++++
 4 files changed, 661 insertions(+)
 create mode 100644 drivers/mtd/nand/vf610_nfc.c

diff --git a/MAINTAINERS b/MAINTAINERS
index 9567329..59975c7 100644
--- a/MAINTAINERS
+++ b/MAINTAINERS
@@ -10835,6 +10835,12 @@ S:	Maintained
 F:	Documentation/fb/uvesafb.txt
 F:	drivers/video/fbdev/uvesafb.*
 
+VF610 NAND DRIVER
+M:	Stefan Agner <stefan at agner.ch>
+L:	linux-mtd at lists.infradead.org
+S:	Supported
+F:	drivers/mtd/nand/vf610_nfc.c
+
 VFAT/FAT/MSDOS FILESYSTEM
 M:	OGAWA Hirofumi <hirofumi at mail.parknet.co.jp>
 S:	Maintained
diff --git a/drivers/mtd/nand/Kconfig b/drivers/mtd/nand/Kconfig
index 5b2806a..8550b14 100644
--- a/drivers/mtd/nand/Kconfig
+++ b/drivers/mtd/nand/Kconfig
@@ -463,6 +463,15 @@ config MTD_NAND_MPC5121_NFC
 	  This enables the driver for the NAND flash controller on the
 	  MPC5121 SoC.
 
+config MTD_NAND_VF610_NFC
+	tristate "Support for Freescale NFC for VF610/MPC5125"
+	depends on (SOC_VF610 || COMPILE_TEST)
+	help
+	  Enables support for NAND Flash Controller on some Freescale
+	  processors like the VF610, MPC5125, MCF54418 or Kinetis K70.
+	  The driver supports a maximum 2k page size. The driver
+	  currently does not support hardware ECC.
+
 config MTD_NAND_MXC
 	tristate "MXC NAND support"
 	depends on ARCH_MXC
diff --git a/drivers/mtd/nand/Makefile b/drivers/mtd/nand/Makefile
index 1f897ec..a490af8 100644
--- a/drivers/mtd/nand/Makefile
+++ b/drivers/mtd/nand/Makefile
@@ -45,6 +45,7 @@ obj-$(CONFIG_MTD_NAND_SOCRATES)		+= socrates_nand.o
 obj-$(CONFIG_MTD_NAND_TXX9NDFMC)	+= txx9ndfmc.o
 obj-$(CONFIG_MTD_NAND_NUC900)		+= nuc900_nand.o
 obj-$(CONFIG_MTD_NAND_MPC5121_NFC)	+= mpc5121_nfc.o
+obj-$(CONFIG_MTD_NAND_VF610_NFC)	+= vf610_nfc.o
 obj-$(CONFIG_MTD_NAND_RICOH)		+= r852.o
 obj-$(CONFIG_MTD_NAND_JZ4740)		+= jz4740_nand.o
 obj-$(CONFIG_MTD_NAND_GPMI_NAND)	+= gpmi-nand/
diff --git a/drivers/mtd/nand/vf610_nfc.c b/drivers/mtd/nand/vf610_nfc.c
new file mode 100644
index 0000000..5c8dfe8
--- /dev/null
+++ b/drivers/mtd/nand/vf610_nfc.c
@@ -0,0 +1,645 @@
+/*
+ * Copyright 2009-2015 Freescale Semiconductor, Inc. and others
+ *
+ * Description: MPC5125, VF610, MCF54418 and Kinetis K70 Nand driver.
+ * Jason ported to M54418TWR and MVFA5 (VF610).
+ * Authors: Stefan Agner <stefan.agner at toradex.com>
+ *          Bill Pringlemeir <bpringlemeir at nbsps.com>
+ *          Shaohui Xie <b21989 at freescale.com>
+ *          Jason Jin <Jason.jin at freescale.com>
+ *
+ * Based on original driver mpc5121_nfc.c.
+ *
+ * This 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.
+ *
+ * Limitations:
+ * - Untested on MPC5125 and M54418.
+ * - DMA not used.
+ * - 2K pages or less.
+ */
+
+#include <linux/module.h>
+#include <linux/bitops.h>
+#include <linux/clk.h>
+#include <linux/delay.h>
+#include <linux/init.h>
+#include <linux/interrupt.h>
+#include <linux/io.h>
+#include <linux/mtd/mtd.h>
+#include <linux/mtd/nand.h>
+#include <linux/mtd/partitions.h>
+#include <linux/platform_device.h>
+#include <linux/slab.h>
+#include <linux/of_mtd.h>
+
+#define	DRV_NAME		"vf610_nfc"
+
+/* Register Offsets */
+#define NFC_FLASH_CMD1			0x3F00
+#define NFC_FLASH_CMD2			0x3F04
+#define NFC_COL_ADDR			0x3F08
+#define NFC_ROW_ADDR			0x3F0c
+#define NFC_ROW_ADDR_INC		0x3F14
+#define NFC_FLASH_STATUS1		0x3F18
+#define NFC_FLASH_STATUS2		0x3F1c
+#define NFC_CACHE_SWAP			0x3F28
+#define NFC_SECTOR_SIZE			0x3F2c
+#define NFC_FLASH_CONFIG		0x3F30
+#define NFC_IRQ_STATUS			0x3F38
+
+/* Addresses for NFC MAIN RAM BUFFER areas */
+#define NFC_MAIN_AREA(n)		((n) *  0x1000)
+
+#define PAGE_2K				0x0800
+#define OOB_64				0x0040
+
+/*
+ * NFC_CMD2[CODE] values. See section:
+ *  - 31.4.7 Flash Command Code Description, Vybrid manual
+ *  - 23.8.6 Flash Command Sequencer, MPC5125 manual
+ *
+ * Briefly these are bitmasks of controller cycles.
+ */
+#define READ_PAGE_CMD_CODE		0x7EE0
+#define READ_ONFI_PARAM_CMD_CODE	0x4860
+#define PROGRAM_PAGE_CMD_CODE		0x7FC0
+#define ERASE_CMD_CODE			0x4EC0
+#define READ_ID_CMD_CODE		0x4804
+#define RESET_CMD_CODE			0x4040
+#define STATUS_READ_CMD_CODE		0x4068
+
+/* NFC ECC mode define */
+#define ECC_BYPASS			0
+
+/*** Register Mask and bit definitions */
+
+/* NFC_FLASH_CMD1 Field */
+#define CMD_BYTE2_MASK				0xFF000000
+#define CMD_BYTE2_SHIFT				24
+
+/* NFC_FLASH_CM2 Field */
+#define CMD_BYTE1_MASK				0xFF000000
+#define CMD_BYTE1_SHIFT				24
+#define CMD_CODE_MASK				0x00FFFF00
+#define CMD_CODE_SHIFT				8
+#define BUFNO_MASK				0x00000006
+#define BUFNO_SHIFT				1
+#define START_BIT				BIT(0)
+
+/* NFC_COL_ADDR Field */
+#define COL_ADDR_MASK				0x0000FFFF
+#define COL_ADDR_SHIFT				0
+
+/* NFC_ROW_ADDR Field */
+#define ROW_ADDR_MASK				0x00FFFFFF
+#define ROW_ADDR_SHIFT				0
+#define ROW_ADDR_CHIP_SEL_RB_MASK		0xF0000000
+#define ROW_ADDR_CHIP_SEL_RB_SHIFT		28
+#define ROW_ADDR_CHIP_SEL_MASK			0x0F000000
+#define ROW_ADDR_CHIP_SEL_SHIFT			24
+
+/* NFC_FLASH_STATUS2 Field */
+#define STATUS_BYTE1_MASK			0x000000FF
+
+/* NFC_FLASH_CONFIG Field */
+#define CONFIG_ECC_SRAM_ADDR_MASK		0x7FC00000
+#define CONFIG_ECC_SRAM_ADDR_SHIFT		22
+#define CONFIG_ECC_SRAM_REQ_BIT			BIT(21)
+#define CONFIG_DMA_REQ_BIT			BIT(20)
+#define CONFIG_ECC_MODE_MASK			0x000E0000
+#define CONFIG_ECC_MODE_SHIFT			17
+#define CONFIG_FAST_FLASH_BIT			BIT(16)
+#define CONFIG_16BIT				BIT(7)
+#define CONFIG_BOOT_MODE_BIT			BIT(6)
+#define CONFIG_ADDR_AUTO_INCR_BIT		BIT(5)
+#define CONFIG_BUFNO_AUTO_INCR_BIT		BIT(4)
+#define CONFIG_PAGE_CNT_MASK			0xF
+#define CONFIG_PAGE_CNT_SHIFT			0
+
+/* NFC_IRQ_STATUS Field */
+#define IDLE_IRQ_BIT				BIT(29)
+#define IDLE_EN_BIT				BIT(20)
+#define CMD_DONE_CLEAR_BIT			BIT(18)
+#define IDLE_CLEAR_BIT				BIT(17)
+
+struct vf610_nfc {
+	struct mtd_info mtd;
+	struct nand_chip chip;
+	struct device *dev;
+	void __iomem *regs;
+	struct completion cmd_done;
+	uint buf_offset;
+	int page_sz;
+	/* Status and ID are in alternate locations. */
+	int alt_buf;
+#define ALT_BUF_ID   1
+#define ALT_BUF_STAT 2
+#define ALT_BUF_ONFI 3
+	struct clk *clk;
+};
+
+#define mtd_to_nfc(_mtd) container_of(_mtd, struct vf610_nfc, mtd)
+
+static inline u32 vf610_nfc_read(struct vf610_nfc *nfc, uint reg)
+{
+	return readl(nfc->regs + reg);
+}
+
+static inline void vf610_nfc_write(struct vf610_nfc *nfc, uint reg, u32 val)
+{
+	writel(val, nfc->regs + reg);
+}
+
+static inline void vf610_nfc_set(struct vf610_nfc *nfc, uint reg, u32 bits)
+{
+	vf610_nfc_write(nfc, reg, vf610_nfc_read(nfc, reg) | bits);
+}
+
+static inline void vf610_nfc_clear(struct vf610_nfc *nfc, uint reg, u32 bits)
+{
+	vf610_nfc_write(nfc, reg, vf610_nfc_read(nfc, reg) & ~bits);
+}
+
+static inline void vf610_nfc_set_field(struct vf610_nfc *nfc, u32 reg,
+				       u32 mask, u32 shift, u32 val)
+{
+	vf610_nfc_write(nfc, reg,
+			(vf610_nfc_read(nfc, reg) & (~mask)) | val << shift);
+}
+
+static inline void vf610_nfc_memcpy(void *dst, const void __iomem *src,
+				    size_t n)
+{
+	/*
+	 * Use this accessor for the internal SRAM buffers. On the ARM
+	 * Freescale Vybrid SoC it's known that the driver can treat
+	 * the SRAM buffer as if it's memory. Other platform might need
+	 * to treat the buffers differently.
+	 *
+	 * For the time being, use memcpy
+	 */
+	memcpy(dst, src, n);
+}
+
+/* Clear flags for upcoming command */
+static inline void vf610_nfc_clear_status(struct vf610_nfc *nfc)
+{
+	u32 tmp = vf610_nfc_read(nfc, NFC_IRQ_STATUS);
+
+	tmp |= CMD_DONE_CLEAR_BIT | IDLE_CLEAR_BIT;
+	vf610_nfc_write(nfc, NFC_IRQ_STATUS, tmp);
+}
+
+static void vf610_nfc_done(struct vf610_nfc *nfc)
+{
+	unsigned long timeout = msecs_to_jiffies(100);
+
+	/*
+	 * Barrier is needed after this write. This write need
+	 * to be done before reading the next register the first
+	 * time.
+	 * vf610_nfc_set implicates such a barrier by using writel
+	 * to write to the register.
+	 */
+	vf610_nfc_set(nfc, NFC_IRQ_STATUS, IDLE_EN_BIT);
+	vf610_nfc_set(nfc, NFC_FLASH_CMD2, START_BIT);
+
+	if (!(vf610_nfc_read(nfc, NFC_IRQ_STATUS) & IDLE_IRQ_BIT)) {
+		if (!wait_for_completion_timeout(&nfc->cmd_done, timeout))
+			dev_warn(nfc->dev, "Timeout while waiting for BUSY.\n");
+	}
+	vf610_nfc_clear_status(nfc);
+}
+
+static u8 vf610_nfc_get_id(struct vf610_nfc *nfc, int col)
+{
+	u32 flash_id;
+
+	if (col < 4) {
+		flash_id = vf610_nfc_read(nfc, NFC_FLASH_STATUS1);
+		flash_id >>= (3 - col) * 8;
+	} else {
+		flash_id = vf610_nfc_read(nfc, NFC_FLASH_STATUS2);
+		flash_id >>= 24;
+	}
+
+	return flash_id & 0xff;
+}
+
+static u8 vf610_nfc_get_status(struct vf610_nfc *nfc)
+{
+	return vf610_nfc_read(nfc, NFC_FLASH_STATUS2) & STATUS_BYTE1_MASK;
+}
+
+static void vf610_nfc_send_command(struct vf610_nfc *nfc, u32 cmd_byte1,
+				   u32 cmd_code)
+{
+	u32 tmp;
+
+	vf610_nfc_clear_status(nfc);
+
+	tmp = vf610_nfc_read(nfc, NFC_FLASH_CMD2);
+	tmp &= ~(CMD_BYTE1_MASK | CMD_CODE_MASK | BUFNO_MASK);
+	tmp |= cmd_byte1 << CMD_BYTE1_SHIFT;
+	tmp |= cmd_code << CMD_CODE_SHIFT;
+	vf610_nfc_write(nfc, NFC_FLASH_CMD2, tmp);
+}
+
+static void vf610_nfc_send_commands(struct vf610_nfc *nfc, u32 cmd_byte1,
+				    u32 cmd_byte2, u32 cmd_code)
+{
+	u32 tmp;
+
+	vf610_nfc_send_command(nfc, cmd_byte1, cmd_code);
+
+	tmp = vf610_nfc_read(nfc, NFC_FLASH_CMD1);
+	tmp &= ~CMD_BYTE2_MASK;
+	tmp |= cmd_byte2 << CMD_BYTE2_SHIFT;
+	vf610_nfc_write(nfc, NFC_FLASH_CMD1, tmp);
+}
+
+static irqreturn_t vf610_nfc_irq(int irq, void *data)
+{
+	struct mtd_info *mtd = data;
+	struct vf610_nfc *nfc = mtd_to_nfc(mtd);
+
+	vf610_nfc_clear(nfc, NFC_IRQ_STATUS, IDLE_EN_BIT);
+	complete(&nfc->cmd_done);
+
+	return IRQ_HANDLED;
+}
+
+static void vf610_nfc_addr_cycle(struct vf610_nfc *nfc, int column, int page)
+{
+	if (column != -1) {
+		if (nfc->chip.options & NAND_BUSWIDTH_16)
+			column = column / 2;
+		vf610_nfc_set_field(nfc, NFC_COL_ADDR, COL_ADDR_MASK,
+				    COL_ADDR_SHIFT, column);
+	}
+	if (page != -1)
+		vf610_nfc_set_field(nfc, NFC_ROW_ADDR, ROW_ADDR_MASK,
+				    ROW_ADDR_SHIFT, page);
+}
+
+static inline void vf610_nfc_transfer_size(struct vf610_nfc *nfc, int size)
+{
+	vf610_nfc_write(nfc, NFC_SECTOR_SIZE, size);
+}
+
+static void vf610_nfc_command(struct mtd_info *mtd, unsigned command,
+			      int column, int page)
+{
+	struct vf610_nfc *nfc = mtd_to_nfc(mtd);
+	int page_sz = nfc->chip.options & NAND_BUSWIDTH_16 ? 1 : 0;
+
+	nfc->buf_offset = max(column, 0);
+	nfc->alt_buf = 0;
+
+	switch (command) {
+	case NAND_CMD_SEQIN:
+		/* Use valid column/page from preread... */
+		vf610_nfc_addr_cycle(nfc, column, page);
+		/*
+		 * SEQIN => data => PAGEPROG sequence is done by the controller
+		 * hence we do not need to issue the command here...
+		 */
+		return;
+	case NAND_CMD_PAGEPROG:
+		page_sz += mtd->writesize + mtd->oobsize;
+		vf610_nfc_transfer_size(nfc, page_sz);
+		vf610_nfc_send_commands(nfc, NAND_CMD_SEQIN,
+					command, PROGRAM_PAGE_CMD_CODE);
+		break;
+
+	case NAND_CMD_RESET:
+		vf610_nfc_transfer_size(nfc, 0);
+		vf610_nfc_send_command(nfc, command, RESET_CMD_CODE);
+		break;
+
+	case NAND_CMD_READOOB:
+		page_sz += mtd->oobsize;
+		column = mtd->writesize;
+		vf610_nfc_transfer_size(nfc, page_sz);
+		vf610_nfc_send_commands(nfc, NAND_CMD_READ0,
+					NAND_CMD_READSTART, READ_PAGE_CMD_CODE);
+		vf610_nfc_addr_cycle(nfc, column, page);
+		break;
+
+	case NAND_CMD_READ0:
+		page_sz += mtd->writesize + mtd->oobsize;
+		vf610_nfc_transfer_size(nfc, page_sz);
+		vf610_nfc_send_commands(nfc, NAND_CMD_READ0,
+					NAND_CMD_READSTART, READ_PAGE_CMD_CODE);
+		vf610_nfc_addr_cycle(nfc, column, page);
+		break;
+
+	case NAND_CMD_PARAM:
+		nfc->alt_buf = ALT_BUF_ONFI;
+		vf610_nfc_transfer_size(nfc, 768);
+		vf610_nfc_send_command(nfc, command, READ_ONFI_PARAM_CMD_CODE);
+		vf610_nfc_set_field(nfc, NFC_ROW_ADDR, ROW_ADDR_MASK,
+				    ROW_ADDR_SHIFT, column);
+		break;
+
+	case NAND_CMD_ERASE1:
+		vf610_nfc_transfer_size(nfc, 0);
+		vf610_nfc_send_commands(nfc, command,
+					NAND_CMD_ERASE2, ERASE_CMD_CODE);
+		vf610_nfc_addr_cycle(nfc, column, page);
+		break;
+
+	case NAND_CMD_READID:
+		nfc->alt_buf = ALT_BUF_ID;
+		nfc->buf_offset = 0;
+		vf610_nfc_transfer_size(nfc, 0);
+		vf610_nfc_send_command(nfc, command, READ_ID_CMD_CODE);
+		vf610_nfc_set_field(nfc, NFC_ROW_ADDR, ROW_ADDR_MASK,
+				    ROW_ADDR_SHIFT, column);
+		break;
+
+	case NAND_CMD_STATUS:
+		nfc->alt_buf = ALT_BUF_STAT;
+		vf610_nfc_transfer_size(nfc, 0);
+		vf610_nfc_send_command(nfc, command, STATUS_READ_CMD_CODE);
+		break;
+	default:
+		return;
+	}
+
+	vf610_nfc_done(nfc);
+}
+
+static void vf610_nfc_read_buf(struct mtd_info *mtd, u_char *buf, int len)
+{
+	struct vf610_nfc *nfc = mtd_to_nfc(mtd);
+	uint c = nfc->buf_offset;
+
+	/* Alternate buffers are only supported through read_byte */
+	WARN_ON(nfc->alt_buf);
+
+	vf610_nfc_memcpy(buf, nfc->regs + NFC_MAIN_AREA(0) + c, len);
+
+	nfc->buf_offset += len;
+}
+
+static void vf610_nfc_write_buf(struct mtd_info *mtd, const uint8_t *buf,
+				int len)
+{
+	struct vf610_nfc *nfc = mtd_to_nfc(mtd);
+	uint c = nfc->buf_offset;
+	uint l;
+
+	l = min_t(uint, len, mtd->writesize + mtd->oobsize - c);
+	vf610_nfc_memcpy(nfc->regs + NFC_MAIN_AREA(0) + c, buf, l);
+
+	nfc->buf_offset += l;
+}
+
+static uint8_t vf610_nfc_read_byte(struct mtd_info *mtd)
+{
+	struct vf610_nfc *nfc = mtd_to_nfc(mtd);
+	u8 tmp;
+	uint c = nfc->buf_offset;
+
+	switch (nfc->alt_buf) {
+	case ALT_BUF_ID:
+		tmp = vf610_nfc_get_id(nfc, c);
+		break;
+	case ALT_BUF_STAT:
+		tmp = vf610_nfc_get_status(nfc);
+		break;
+#ifdef __LITTLE_ENDIAN
+	case ALT_BUF_ONFI:
+		/* Reverse byte since the controller uses big endianness */
+		c = nfc->buf_offset ^ 0x3;
+		/* fall-through */
+#endif
+	default:
+		tmp = *((u8 *)(nfc->regs + NFC_MAIN_AREA(0) + c));
+		break;
+	}
+	nfc->buf_offset++;
+	return tmp;
+}
+
+static u16 vf610_nfc_read_word(struct mtd_info *mtd)
+{
+	u16 tmp;
+
+	vf610_nfc_read_buf(mtd, (u_char *)&tmp, sizeof(tmp));
+	return tmp;
+}
+
+/* If not provided, upper layers apply a fixed delay. */
+static int vf610_nfc_dev_ready(struct mtd_info *mtd)
+{
+	/* NFC handles R/B internally; always ready.  */
+	return 1;
+}
+
+/*
+ * This function supports Vybrid only (MPC5125 would have full RB and four CS)
+ */
+static void vf610_nfc_select_chip(struct mtd_info *mtd, int chip)
+{
+#ifdef CONFIG_SOC_VF610
+	struct vf610_nfc *nfc = mtd_to_nfc(mtd);
+	u32 tmp = vf610_nfc_read(nfc, NFC_ROW_ADDR);
+
+	tmp &= ~(ROW_ADDR_CHIP_SEL_RB_MASK | ROW_ADDR_CHIP_SEL_MASK);
+	tmp |= 1 << ROW_ADDR_CHIP_SEL_RB_SHIFT;
+
+	if (chip == 0)
+		tmp |= 1 << ROW_ADDR_CHIP_SEL_SHIFT;
+	else if (chip == 1)
+		tmp |= 2 << ROW_ADDR_CHIP_SEL_SHIFT;
+
+	vf610_nfc_write(nfc, NFC_ROW_ADDR, tmp);
+#endif
+}
+
+static const struct of_device_id vf610_nfc_dt_ids[] = {
+	{ .compatible = "fsl,vf610-nfc" },
+	{ /* sentinel */ }
+};
+MODULE_DEVICE_TABLE(of, vf610_nfc_dt_ids);
+
+static void vf610_nfc_preinit_controller(struct vf610_nfc *nfc)
+{
+	vf610_nfc_clear(nfc, NFC_FLASH_CONFIG, CONFIG_16BIT);
+	vf610_nfc_clear(nfc, NFC_FLASH_CONFIG, CONFIG_ADDR_AUTO_INCR_BIT);
+	vf610_nfc_clear(nfc, NFC_FLASH_CONFIG, CONFIG_BUFNO_AUTO_INCR_BIT);
+	vf610_nfc_clear(nfc, NFC_FLASH_CONFIG, CONFIG_BOOT_MODE_BIT);
+	vf610_nfc_clear(nfc, NFC_FLASH_CONFIG, CONFIG_DMA_REQ_BIT);
+	vf610_nfc_set(nfc, NFC_FLASH_CONFIG, CONFIG_FAST_FLASH_BIT);
+
+	/* Disable virtual pages, only one elementary transfer unit */
+	vf610_nfc_set_field(nfc, NFC_FLASH_CONFIG, CONFIG_PAGE_CNT_MASK,
+			    CONFIG_PAGE_CNT_SHIFT, 1);
+}
+
+static void vf610_nfc_init_controller(struct vf610_nfc *nfc)
+{
+	if (nfc->chip.options & NAND_BUSWIDTH_16)
+		vf610_nfc_set(nfc, NFC_FLASH_CONFIG, CONFIG_16BIT);
+	else
+		vf610_nfc_clear(nfc, NFC_FLASH_CONFIG, CONFIG_16BIT);
+}
+
+static int vf610_nfc_probe(struct platform_device *pdev)
+{
+	struct vf610_nfc *nfc;
+	struct resource *res;
+	struct mtd_info *mtd;
+	struct nand_chip *chip;
+	int err = 0;
+	int irq;
+
+	nfc = devm_kzalloc(&pdev->dev, sizeof(*nfc), GFP_KERNEL);
+	if (!nfc)
+		return -ENOMEM;
+
+	nfc->dev = &pdev->dev;
+	mtd = &nfc->mtd;
+	chip = &nfc->chip;
+
+	mtd->priv = chip;
+	mtd->owner = THIS_MODULE;
+	mtd->dev.parent = nfc->dev;
+	mtd->name = DRV_NAME;
+
+	irq = platform_get_irq(pdev, 0);
+	if (irq <= 0)
+		return -EINVAL;
+
+	res = platform_get_resource(pdev, IORESOURCE_MEM, 0);
+	nfc->regs = devm_ioremap_resource(nfc->dev, res);
+	if (IS_ERR(nfc->regs))
+		return PTR_ERR(nfc->regs);
+
+	nfc->clk = devm_clk_get(&pdev->dev, NULL);
+	if (IS_ERR(nfc->clk))
+		return PTR_ERR(nfc->clk);
+
+	err = clk_prepare_enable(nfc->clk);
+	if (err) {
+		dev_err(nfc->dev, "Unable to enable clock!\n");
+		return err;
+	}
+
+	chip->dn = nfc->dev->of_node;
+	chip->dev_ready = vf610_nfc_dev_ready;
+	chip->cmdfunc = vf610_nfc_command;
+	chip->read_byte = vf610_nfc_read_byte;
+	chip->read_word = vf610_nfc_read_word;
+	chip->read_buf = vf610_nfc_read_buf;
+	chip->write_buf = vf610_nfc_write_buf;
+	chip->select_chip = vf610_nfc_select_chip;
+
+	chip->options |= NAND_NO_SUBPAGE_WRITE;
+
+	init_completion(&nfc->cmd_done);
+
+	err = devm_request_irq(nfc->dev, irq, vf610_nfc_irq, 0, DRV_NAME, mtd);
+	if (err) {
+		dev_err(nfc->dev, "Error requesting IRQ!\n");
+		goto error;
+	}
+
+	vf610_nfc_preinit_controller(nfc);
+
+	/* first scan to find the device and get the page size */
+	if (nand_scan_ident(mtd, 1, NULL)) {
+		err = -ENXIO;
+		goto error;
+	}
+
+	vf610_nfc_init_controller(nfc);
+
+	/* Bad block options. */
+	if (chip->bbt_options & NAND_BBT_USE_FLASH)
+		chip->bbt_options |= NAND_BBT_NO_OOB;
+
+	/* Single buffer only, max 256 OOB minus ECC status */
+	if (mtd->writesize + mtd->oobsize > PAGE_2K + 256 - 8) {
+		dev_err(nfc->dev, "Unsupported flash page size\n");
+		err = -ENXIO;
+		goto error;
+	}
+
+	/* second phase scan */
+	if (nand_scan_tail(mtd)) {
+		err = -ENXIO;
+		goto error;
+	}
+
+	platform_set_drvdata(pdev, mtd);
+
+	/* Register device in MTD */
+	return mtd_device_parse_register(mtd, NULL,
+		&(struct mtd_part_parser_data){
+			.of_node = pdev->dev.of_node,
+		},
+		NULL, 0);
+
+error:
+	clk_disable_unprepare(nfc->clk);
+	return err;
+}
+
+static int vf610_nfc_remove(struct platform_device *pdev)
+{
+	struct mtd_info *mtd = platform_get_drvdata(pdev);
+	struct vf610_nfc *nfc = mtd_to_nfc(mtd);
+
+	nand_release(mtd);
+	clk_disable_unprepare(nfc->clk);
+	return 0;
+}
+
+#ifdef CONFIG_PM_SLEEP
+static int vf610_nfc_suspend(struct device *dev)
+{
+	struct mtd_info *mtd = dev_get_drvdata(dev);
+	struct vf610_nfc *nfc = mtd_to_nfc(mtd);
+
+	clk_disable_unprepare(nfc->clk);
+	return 0;
+}
+
+static int vf610_nfc_resume(struct device *dev)
+{
+	struct mtd_info *mtd = dev_get_drvdata(dev);
+	struct vf610_nfc *nfc = mtd_to_nfc(mtd);
+
+	pinctrl_pm_select_default_state(dev);
+
+	clk_prepare_enable(nfc->clk);
+
+	vf610_nfc_preinit_controller(nfc);
+	vf610_nfc_init_controller(nfc);
+	return 0;
+}
+#endif
+
+static SIMPLE_DEV_PM_OPS(vf610_nfc_pm_ops, vf610_nfc_suspend, vf610_nfc_resume);
+
+static struct platform_driver vf610_nfc_driver = {
+	.driver		= {
+		.name	= DRV_NAME,
+		.of_match_table = vf610_nfc_dt_ids,
+		.pm	= &vf610_nfc_pm_ops,
+	},
+	.probe		= vf610_nfc_probe,
+	.remove		= vf610_nfc_remove,
+};
+
+module_platform_driver(vf610_nfc_driver);
+
+MODULE_AUTHOR("Stefan Agner <stefan.agner at toradex.com>");
+MODULE_DESCRIPTION("Freescale VF610/MPC5125 NFC MTD NAND driver");
+MODULE_LICENSE("GPL");
-- 
2.5.0



From stefan at agner.ch  Mon Aug  3 02:27:30 2015
From: stefan at agner.ch (Stefan Agner)
Date: Mon,  3 Aug 2015 11:27:30 +0200
Subject: [PATCH v10 5/5] ARM: dts: vf-colibri: enable NAND flash controller
In-Reply-To: <1438594050-4595-1-git-send-email-stefan@agner.ch>
References: <1438594050-4595-1-git-send-email-stefan@agner.ch>
Message-ID: <1438594050-4595-6-git-send-email-stefan@agner.ch>

Enable NAND access by adding pinmux and NAND flash controller node
to device tree. The NAND chips currently used on the Colibri VF61
requires 8-bit ECC per 512 byte page, hence specify 32-bit ECC
strength per 2k page size.

Reviewed-by: Brian Norris <computersforpeace at gmail.com>
Signed-off-by: Stefan Agner <stefan at agner.ch>
---
 arch/arm/boot/dts/vf-colibri.dtsi | 32 ++++++++++++++++++++++++++++++++
 1 file changed, 32 insertions(+)

diff --git a/arch/arm/boot/dts/vf-colibri.dtsi b/arch/arm/boot/dts/vf-colibri.dtsi
index 68ca125..ab2e74b 100644
--- a/arch/arm/boot/dts/vf-colibri.dtsi
+++ b/arch/arm/boot/dts/vf-colibri.dtsi
@@ -52,6 +52,19 @@
 	pinctrl-0 = <&pinctrl_i2c0>;
 };
 
+&nfc {
+	assigned-clocks = <&clks VF610_CLK_NFC>;
+	assigned-clock-rates = <33000000>;
+	nand-bus-width = <8>;
+	nand-ecc-mode = "hw";
+	nand-ecc-step-size = <2048>;
+	nand-ecc-strength = <32>;
+	nand-on-flash-bbt;
+	pinctrl-names = "default";
+	pinctrl-0 = <&pinctrl_nfc>;
+	status = "okay";
+};
+
 &pwm0 {
 	pinctrl-names = "default";
 	pinctrl-0 = <&pinctrl_pwm0>;
@@ -156,6 +169,25 @@
 			>;
 		};
 
+		pinctrl_nfc: nfcgrp {
+			fsl,pins = <
+				VF610_PAD_PTD23__NF_IO7		0x28df
+				VF610_PAD_PTD22__NF_IO6		0x28df
+				VF610_PAD_PTD21__NF_IO5		0x28df
+				VF610_PAD_PTD20__NF_IO4		0x28df
+				VF610_PAD_PTD19__NF_IO3		0x28df
+				VF610_PAD_PTD18__NF_IO2		0x28df
+				VF610_PAD_PTD17__NF_IO1		0x28df
+				VF610_PAD_PTD16__NF_IO0		0x28df
+				VF610_PAD_PTB24__NF_WE_B	0x28c2
+				VF610_PAD_PTB25__NF_CE0_B	0x28c2
+				VF610_PAD_PTB27__NF_RE_B	0x28c2
+				VF610_PAD_PTC26__NF_RB_B	0x283d
+				VF610_PAD_PTC27__NF_ALE		0x28c2
+				VF610_PAD_PTC28__NF_CLE		0x28c2
+			>;
+		};
+
 		pinctrl_pwm0: pwm0grp {
 			fsl,pins = <
 				VF610_PAD_PTB0__FTM0_CH0		0x1182
-- 
2.5.0



From maxime.ripard at free-electrons.com  Mon Aug  3 02:28:39 2015
From: maxime.ripard at free-electrons.com (Maxime Ripard)
Date: Mon, 3 Aug 2015 11:28:39 +0200
Subject: [linux-sunxi] [PATCH] ARM: dts: sunxi: Raise minimum CPU voltage
 for sun7i-a20 to a level all boards can supply
In-Reply-To: <CAGRGNgXH90m9h0DDejd5MTf8enduGFQ8dPKrRhmc8Z6y_PaC1w@mail.gmail.com>
References: <1438543386-7253-1-git-send-email-public_timo.s@silentcreek.de>
 <CAGRGNgV6b9yt2HnB2x2Wyc05KEahoX-Y+mVhxsryztcfA36H1g@mail.gmail.com>
 <CAGb2v67o-=_cL2RWfXJ+3C86zfQ_1b5DYRi3_zwvwy6su6+gdw@mail.gmail.com>
 <CAGRGNgXH90m9h0DDejd5MTf8enduGFQ8dPKrRhmc8Z6y_PaC1w@mail.gmail.com>
Message-ID: <20150803092839.GB2564@lukather>

On Mon, Aug 03, 2015 at 02:22:13PM +1000, Julian Calaby wrote:
> >> Is the code that uses this smart enough to sensibly switch between two
> >> operating points with the same frequency and different voltages? If
> >> so, maybe just add a 144MHz @ 1.0v operating point?
> >
> > You could try. Though I really don't see much to gain here.
> 
> From what I recall, lower frequency = less power usage, though my
> experience is from x86 laptops, not ARM SoCs and I'm sure I'm missing
> a lot of details. This is the sort of thing that requires thorough
> testing on a dev board.

Not on *a* dev board. On virtually all the A20 SoCs ever produced. If
you have a setting that works better for *your* SoC, fine, patch your
DT, but that's not going to be a default if it's outside of the SoC
operating range.

Maxime

-- 
Maxime Ripard, Free Electrons
Embedded Linux, Kernel and Android engineering
http://free-electrons.com
-------------- next part --------------
A non-text attachment was scrubbed...
Name: signature.asc
Type: application/pgp-signature
Size: 819 bytes
Desc: Digital signature
URL: <http://lists.infradead.org/pipermail/linux-arm-kernel/attachments/20150803/94c58540/attachment.sig>

From zhaoshenglong at huawei.com  Mon Aug  3 02:26:05 2015
From: zhaoshenglong at huawei.com (Shannon Zhao)
Date: Mon, 3 Aug 2015 17:26:05 +0800
Subject: [PATCH 0/2] drivers: PL061: Add platform driver probing support
In-Reply-To: <20150803075848.GH7557@n2100.arm.linux.org.uk>
References: <1438585198-8764-1-git-send-email-zhaoshenglong@huawei.com>
 <20150803075848.GH7557@n2100.arm.linux.org.uk>
Message-ID: <55BF33AD.5040502@huawei.com>

Hi Russell,

On 2015/8/3 15:58, Russell King - ARM Linux wrote:
> On Mon, Aug 03, 2015 at 02:59:56PM +0800, Shannon Zhao wrote:
>> From: Shannon Zhao <shannon.zhao at linaro.org>
>>
>> According to ACPI SPEC, it supports ARM boards to use "GPIO-signaled
>> ACPI Events". These events can be used for input events. And to QEMU, it
>> uses GPIO PL061 controller for input events.
>>
>> These two patches add platform driver support for PL061 probed by DT or
>> ACPI.
> 
> This certainly is incorrect for DT, and is probably wrong for ACPI too.
> DT creates amba devices, so binds via the amba device driver.
> 

Oh, sorry. The changes for DT are not necessary. But for ACPI I think it
needs to convert pl061 to platform device since ACPI doesn't support
AMBA devices. The Pl011 also does the same thing to support ACPI
probing. See drivers/tty/serial/amba-pl011.c

Thanks,
-- 
Shannon



From stefan at agner.ch  Mon Aug  3 02:28:43 2015
From: stefan at agner.ch (Stefan Agner)
Date: Mon, 03 Aug 2015 11:28:43 +0200
Subject: [PATCH v10 2/5] mtd: nand: vf610_nfc: add hardware BCH-ECC support
In-Reply-To: <1438594050-4595-3-git-send-email-stefan@agner.ch>
References: <1438594050-4595-1-git-send-email-stefan@agner.ch>
 <1438594050-4595-3-git-send-email-stefan@agner.ch>
Message-ID: <ff2e2716578a1ae5f0c4b0e0ca8bbdc3@agner.ch>

Hi Brian,

On 2015-08-03 11:27, Stefan Agner wrote:
<snip>
> +static inline int vf610_nfc_correct_data(struct mtd_info *mtd, uint8_t *dat,
> +					 uint8_t *oob, int oob_loaded)
> +{
> +	struct vf610_nfc *nfc = mtd_to_nfc(mtd);
> +	u8 ecc_status;
> +	u8 ecc_count;
> +	int flip;
> +
> +	ecc_status = __raw_readb(nfc->regs + ECC_SRAM_ADDR * 8 + ECC_OFFSET);
> +	ecc_count = ecc_status & ECC_ERR_COUNT;
> +
> +	if (!(ecc_status & ECC_STATUS_MASK))
> +		return ecc_count;
> +
> +	if (!oob_loaded)
> +		vf610_nfc_read_buf(mtd, oob, mtd->oobsize);
> +
> +	/*
> +	 * On an erased page, bit count (including OOB) should be zero or
> +	 * at least less then half of the ECC strength.
> +	 */
> +	flip = count_written_bits(dat, nfc->chip.ecc.size, ecc_count);
> +	flip += count_written_bits(oob, mtd->oobsize - nfc->chip.ecc.bytes,
> +				   ecc_count);

With ECC the controller seems to clear the ECC bytes in SRAM buffer.
This is a dump of 64 Bit OOB with the 32-error ECC mode which requires
60 bytes of OOB for ECC:

[   22.190273] ff ff ff ff 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
[   22.209698] vf610_nfc_correct_data, flips 1

Not sure if this is acceptable, but I now only count the bits in the
non-ECC area of the OOB.

Btw, if the ECC check fails, the controller seems kind of count the
amount of bitflips. It works for most devices reliable, but we had
devices for which that number was not accurate, see:
http://thread.gmane.org/gmane.linux.ports.arm.kernel/357439

--
Stefan



From maxime.ripard at free-electrons.com  Mon Aug  3 02:34:20 2015
From: maxime.ripard at free-electrons.com (Maxime Ripard)
Date: Mon, 3 Aug 2015 11:34:20 +0200
Subject: [linux-sunxi] [PATCH] ARM: dts: sunxi: Raise minimum CPU voltage
 for sun7i-a20 to a level all boards can supply
In-Reply-To: <20150803090352.621CC6C80865@dd34104.kasserver.com>
References: <1438543386-7253-1-git-send-email-public_timo.s@silentcreek.de>
 <CAGRGNgV6b9yt2HnB2x2Wyc05KEahoX-Y+mVhxsryztcfA36H1g@mail.gmail.com>
 <CAGb2v67o-=_cL2RWfXJ+3C86zfQ_1b5DYRi3_zwvwy6su6+gdw@mail.gmail.com>
 <CAGRGNgXH90m9h0DDejd5MTf8enduGFQ8dPKrRhmc8Z6y_PaC1w@mail.gmail.com>
 <20150803090352.621CC6C80865@dd34104.kasserver.com>
Message-ID: <20150803093420.GC2564@lukather>

On Mon, Aug 03, 2015 at 11:03:52AM +0200, Timo Sigurdsson wrote:
> Hi again,
> 
> Julian Calaby schrieb am 03.08.2015 06:22:
> > My only real objection here is are there boards that can go down to
> > 0.9v and if so, won't this change make them less power efficient in
> > the almost-idle case? And are those power savings enough to justify
> > not accepting this patch?
> 
> It will probably make those boards less power efficient, yes. On the
> other hand, boards that have their CPU regulator set to min. 1.0V might
> also draw more power because the lowest frequency is not available, 
> even though the savings due to frequency are likely to be lower than
> the savings due to voltage.

Guys, isn't this whole discussion a bit moot? We're not doing any kind
of power management but cpufreq, so maybe there's a lot more to do
before we actually can have these kind of arguments?

Plus this OPP has never been used anyway, so this patch is not going
to increase the power consumption either.

Maxime

-- 
Maxime Ripard, Free Electrons
Embedded Linux, Kernel and Android engineering
http://free-electrons.com
-------------- next part --------------
A non-text attachment was scrubbed...
Name: signature.asc
Type: application/pgp-signature
Size: 819 bytes
Desc: Digital signature
URL: <http://lists.infradead.org/pipermail/linux-arm-kernel/attachments/20150803/6e4a74ec/attachment.sig>

From julian.calaby at gmail.com  Mon Aug  3 02:36:32 2015
From: julian.calaby at gmail.com (Julian Calaby)
Date: Mon, 3 Aug 2015 19:36:32 +1000
Subject: [linux-sunxi] [PATCH] ARM: dts: sunxi: Raise minimum CPU voltage
 for sun7i-a20 to a level all boards can supply
In-Reply-To: <20150803093420.GC2564@lukather>
References: <1438543386-7253-1-git-send-email-public_timo.s@silentcreek.de>
 <CAGRGNgV6b9yt2HnB2x2Wyc05KEahoX-Y+mVhxsryztcfA36H1g@mail.gmail.com>
 <CAGb2v67o-=_cL2RWfXJ+3C86zfQ_1b5DYRi3_zwvwy6su6+gdw@mail.gmail.com>
 <CAGRGNgXH90m9h0DDejd5MTf8enduGFQ8dPKrRhmc8Z6y_PaC1w@mail.gmail.com>
 <20150803090352.621CC6C80865@dd34104.kasserver.com>
 <20150803093420.GC2564@lukather>
Message-ID: <CAGRGNgUohUAH9_jUfFrg8w+EWRq1A9WLHO=pcFDnp9djbPL1qQ@mail.gmail.com>

Hi Maxime,

On Mon, Aug 3, 2015 at 7:34 PM, Maxime Ripard
<maxime.ripard at free-electrons.com> wrote:
> On Mon, Aug 03, 2015 at 11:03:52AM +0200, Timo Sigurdsson wrote:
>> Hi again,
>>
>> Julian Calaby schrieb am 03.08.2015 06:22:
>> > My only real objection here is are there boards that can go down to
>> > 0.9v and if so, won't this change make them less power efficient in
>> > the almost-idle case? And are those power savings enough to justify
>> > not accepting this patch?
>>
>> It will probably make those boards less power efficient, yes. On the
>> other hand, boards that have their CPU regulator set to min. 1.0V might
>> also draw more power because the lowest frequency is not available,
>> even though the savings due to frequency are likely to be lower than
>> the savings due to voltage.
>
> Guys, isn't this whole discussion a bit moot? We're not doing any kind
> of power management but cpufreq, so maybe there's a lot more to do
> before we actually can have these kind of arguments?
>
> Plus this OPP has never been used anyway, so this patch is not going
> to increase the power consumption either.

Oh, I didn't know that. Therefore I withdraw my objections, patch away!

Thanks,

-- 
Julian Calaby

Email: julian.calaby at gmail.com
Profile: http://www.google.com/profiles/julian.calaby/


From maxime.ripard at free-electrons.com  Mon Aug  3 02:41:43 2015
From: maxime.ripard at free-electrons.com (Maxime Ripard)
Date: Mon, 3 Aug 2015 11:41:43 +0200
Subject: [GIT PULL] Allwinner DT changes for 4.3
Message-ID: <20150803094143.GA16612@lukather>

Hi Arnd, Kevin, Olof,

Here is the DT changes for the 4.3 merge window.

I'll be in holidays for the three next weeks, so this is probably
going to be my last "feature" pull request for the 4.3 merge window.

Thanks!
Maxime


The following changes since commit d770e558e21961ad6cfdf0ff7df0eb5d7d4f0754:

  Linux 4.2-rc1 (2015-07-05 11:01:52 -0700)

are available in the git repository at:

  https://git.kernel.org/pub/scm/linux/kernel/git/mripard/linux.git tags/sunxi-dt-for-4.3

for you to fetch changes up to 60018d027d792bdfe9d98c83a470fa2cdd6a0e1a:

  ARM: dts: sun7i: Change cubietruck wifi enable pin to use mmc-pwrseq (2015-08-01 11:25:11 +0200)

----------------------------------------------------------------
Allwinner Device Tree changes for 4.3

A bunch of device tree patches that:
  - Enable the OTG controller on some boards
  - Various additions to the existing boards
  - New boards: A33 Ippo Q8H, Iteaduino Plus,

----------------------------------------------------------------
Chen-Yu Tsai (4):
      ARM: dts: sun8i: Add support for USB controllers on A23/A33
      ARM: dts: sun8i: sina33: Enable USB hosts
      ARM: dts: sun5i: hsg-h702: Enable side volume buttons with LRADC
      ARM: dts: sun5i: hsg-h702: Enable USB OTG controller

Hans de Goede (22):
      ARM: dts: sun4i: Add USB Dual Role Controller
      ARM: dts: sun5i: Add USB Dual Role Controller
      ARM: dts: sun6i: Add USB Dual Role Controller
      ARM: dts: sun8i: Add A23 usb-phy and otg nodes
      ARM: dts: sun8i: Add A33 usb-phy and otg nodes
      ARM: dts: sun4i: Enable USB DRC on Chuwi V7 CW0825
      ARM: dts: sun4i: Enable USB DRC on the Cubieboard
      ARM: dts: sun5i: Enable USB DRC on UTOO P66
      ARM: dts: sun6i: Enable USB DRC on the Mele A1000G quad
      ARM: dts: sun7i: Enable USB DRC on A20-OLinuxIno-Lime
      ARM: dts: sun7i: Enable USB DRC on A20-OLinuxIno-Micro
      ARM: dts: sun8i: Enable USB DRC on Ippo Q8H-A23 tablets
      ARM: dts: sun8i: Enable USB DRC on GA10H-A33 tablets
      ARM: dts: sun8i: Enable USB host on GA10H-A33 tablets
      ARM: sun8i: dts: Add Ippo-q8h v1.2 with A33
      ARM: dts: sunxi: Add regulator-boot-on to usb host port regulator nodes
      ARM: dts: sun4i: Enable otg controller on the ba10-tvbox
      ARM: dts: sun4i: Enable otg controller on the mini-x
      ARM: dts: sun6i: Enable otg controller on the cs908
      ARM: dts: sun5i: Enable USB DRC on A10s OLinuxIno Micro
      ARM: dts: sun8i: Enable USB DRC on Ippo Q8H-A33 tablet
      ARM: dts: sun7i: Change cubietruck wifi enable pin to use mmc-pwrseq

Josef Gajdusek (1):
      ARM: dts: sun4i: Add Iteaduino Plus A10

Karsten Merker (1):
      devicetree: Add msi to the vendor-prefix list

Mark Janssen (1):
      ARM: dts: sun5i: Enable USB DRC on A13 OLinuxIno

Maxime Ripard (1):
      ARM: sunxi: dt: Convert users to the PIO interrupts binding

Michal Suchanek (2):
      ARM: dts: axp152: Add a dtsi file for the axp152 pmic
      ARM: dts: A10s-OLinuxIno: Add a node for axp152 pmic

Remy van Elst (1):
      ARM: dts: sun4i: Enable USB DRC on A10 OLinuxIno Lime

Roman Byshko (2):
      ARM: dts: sun7i: Add USB Dual Role Controller
      ARM: dts: sun7i: Enable USB DRC on Cubietruck

 .../devicetree/bindings/vendor-prefixes.txt        |   1 +
 arch/arm/boot/dts/Makefile                         |   2 +
 arch/arm/boot/dts/axp152.dtsi                      |  49 +++++
 arch/arm/boot/dts/sun4i-a10-ba10-tvbox.dts         |  15 ++
 arch/arm/boot/dts/sun4i-a10-chuwi-v7-cw0825.dts    |  34 ++++
 arch/arm/boot/dts/sun4i-a10-cubieboard.dts         |  19 ++
 .../boot/dts/sun4i-a10-itead-iteaduino-plus.dts    | 202 +++++++++++++++++++++
 arch/arm/boot/dts/sun4i-a10-mini-xplus.dts         |  15 ++
 arch/arm/boot/dts/sun4i-a10-olinuxino-lime.dts     |  32 ++++
 arch/arm/boot/dts/sun4i-a10.dtsi                   |  16 +-
 arch/arm/boot/dts/sun5i-a10s-olinuxino-micro.dts   |  37 +++-
 arch/arm/boot/dts/sun5i-a13-hsg-h702.dts           |  58 ++++++
 arch/arm/boot/dts/sun5i-a13-olinuxino.dts          |  37 ++++
 arch/arm/boot/dts/sun5i-a13-utoo-p66.dts           |  29 ++-
 arch/arm/boot/dts/sun5i.dtsi                       |  16 +-
 arch/arm/boot/dts/sun6i-a31-mele-a1000g-quad.dts   |   5 +
 arch/arm/boot/dts/sun6i-a31.dtsi                   |  16 +-
 arch/arm/boot/dts/sun6i-a31s-cs908.dts             |   5 +
 arch/arm/boot/dts/sun7i-a20-cubietruck.dts         |  56 ++++--
 arch/arm/boot/dts/sun7i-a20-i12-tvbox.dts          |   2 +-
 arch/arm/boot/dts/sun7i-a20-olinuxino-lime.dts     |  32 ++++
 arch/arm/boot/dts/sun7i-a20-olinuxino-micro.dts    |  32 ++++
 arch/arm/boot/dts/sun7i-a20.dtsi                   |  16 +-
 arch/arm/boot/dts/sun8i-a23-a33.dtsi               |  25 ++-
 arch/arm/boot/dts/sun8i-a23-ippo-q8h-v5.dts        |   9 +
 arch/arm/boot/dts/sun8i-a23.dtsi                   |  33 ++++
 arch/arm/boot/dts/sun8i-a33-ga10h-v1.1.dts         |  17 ++
 arch/arm/boot/dts/sun8i-a33-ippo-q8h-v1.2.dts      | 133 ++++++++++++++
 arch/arm/boot/dts/sun8i-a33-sinlinx-sina33.dts     |  13 ++
 arch/arm/boot/dts/sun8i-a33.dtsi                   |  33 ++++
 arch/arm/boot/dts/sunxi-common-regulators.dtsi     |   2 +
 31 files changed, 962 insertions(+), 29 deletions(-)
 create mode 100644 arch/arm/boot/dts/axp152.dtsi
 create mode 100644 arch/arm/boot/dts/sun4i-a10-itead-iteaduino-plus.dts
 create mode 100644 arch/arm/boot/dts/sun8i-a33-ippo-q8h-v1.2.dts

-- 
Maxime Ripard, Free Electrons
Embedded Linux, Kernel and Android engineering
http://free-electrons.com
-------------- next part --------------
A non-text attachment was scrubbed...
Name: signature.asc
Type: application/pgp-signature
Size: 819 bytes
Desc: Digital signature
URL: <http://lists.infradead.org/pipermail/linux-arm-kernel/attachments/20150803/50eb4ded/attachment-0001.sig>

From maxime.ripard at free-electrons.com  Mon Aug  3 02:43:47 2015
From: maxime.ripard at free-electrons.com (Maxime Ripard)
Date: Mon, 3 Aug 2015 11:43:47 +0200
Subject: [GIT PULL] Allwinner defconfig changes for 4.3
Message-ID: <20150803094347.GA17185@lukather>

Hi Arnd, Kevin, Olof,

Please pull the following defconfig patches for the 4.3 merge window.

Thanks!
Maxime

The following changes since commit bc0195aad0daa2ad5b0d76cce22b167bc3435590:

  Linux 4.2-rc2 (2015-07-12 15:10:30 -0700)

are available in the git repository at:

  https://git.kernel.org/pub/scm/linux/kernel/git/mripard/linux.git tags/sunxi-defconfig-for-4.3

for you to fetch changes up to 8faf3554cb7a83413f9dfbe1a3420a81c52efe47:

  ARM: multi_v7_defconfig: Enable Allwinner P2WI, PWM, DMA_SUN6I, cryptodev (2015-07-31 20:01:24 +0200)

----------------------------------------------------------------
Allwinner defconfig changes for 4.3

Two patches that enable various Allwinner related drivers drivers both in
sunxi_defconfig and in multi_v7_defconfig

----------------------------------------------------------------
Chen-Yu Tsai (2):
      ARM: sunxi_defconfig: Enable DMA_SUN6I, P2WI, PWM, cryptodev, EXTCON, FHANDLE
      ARM: multi_v7_defconfig: Enable Allwinner P2WI, PWM, DMA_SUN6I, cryptodev

 arch/arm/configs/multi_v7_defconfig |  5 +++++
 arch/arm/configs/sunxi_defconfig    | 10 +++++++++-
 2 files changed, 14 insertions(+), 1 deletion(-)

-- 
Maxime Ripard, Free Electrons
Embedded Linux, Kernel and Android engineering
http://free-electrons.com
-------------- next part --------------
A non-text attachment was scrubbed...
Name: signature.asc
Type: application/pgp-signature
Size: 819 bytes
Desc: Digital signature
URL: <http://lists.infradead.org/pipermail/linux-arm-kernel/attachments/20150803/de98862f/attachment.sig>

From maxime.ripard at free-electrons.com  Mon Aug  3 02:47:23 2015
From: maxime.ripard at free-electrons.com (Maxime Ripard)
Date: Mon, 3 Aug 2015 11:47:23 +0200
Subject: [PATCH v2] ARM: dts: sunxi: Add regulators for LeMaker BananaPi
In-Reply-To: <1438532305-5884-1-git-send-email-public_timo.s@silentcreek.de>
References: <1438532305-5884-1-git-send-email-public_timo.s@silentcreek.de>
Message-ID: <20150803094723.GD2564@lukather>

On Sun, Aug 02, 2015 at 06:18:25PM +0200, Timo Sigurdsson wrote:
> sun7i-a20-bananapi.dts doesn't contain regulator nodes for the AXP209 PMU
> driver, so add them to allow for voltage-scaling with cpufreq-dt.
> 
> Signed-off-by: Timo Sigurdsson <public_timo.s at silentcreek.de>
> ---
> Changes since v1 (RFC):
> 
> - Dropped the changes to the cpufreq operating points and renamed the patch
> accordingly
> - Limited the CPU voltage range so it doesn't exceed the SOC specifications
> ---
>  arch/arm/boot/dts/sun7i-a20-bananapi.dts | 35 ++++++++++++++++++++++++++++----
>  1 file changed, 31 insertions(+), 4 deletions(-)
> 
> diff --git a/arch/arm/boot/dts/sun7i-a20-bananapi.dts b/arch/arm/boot/dts/sun7i-a20-bananapi.dts
> index 9f7b472..74382f3 100644
> --- a/arch/arm/boot/dts/sun7i-a20-bananapi.dts
> +++ b/arch/arm/boot/dts/sun7i-a20-bananapi.dts
> @@ -92,6 +92,10 @@
>  	status = "okay";
>  };
>  
> +&cpu0 {
> +	cpu-supply = <&reg_dcdc2>;
> +};
> +
>  &ehci0 {
>  	status = "okay";
>  };
> @@ -119,13 +123,9 @@
>  	status = "okay";
>  
>  	axp209: pmic at 34 {
> -		compatible = "x-powers,axp209";
>  		reg = <0x34>;
>  		interrupt-parent = <&nmi_intc>;
>  		interrupts = <0 IRQ_TYPE_LEVEL_LOW>;
> -
> -		interrupt-controller;
> -		#interrupt-cells = <1>;
>  	};
>  };
>  
> @@ -182,6 +182,33 @@
>  	};
>  };
>  
> +#include "axp209.dtsi"
> +
> +&reg_dcdc2 {
> +	regulator-always-on;
> +	regulator-min-microvolt = <1000000>;
> +	regulator-max-microvolt = <1400000>;
> +	regulator-name = "vdd-cpu";
> +};
> +
> +&reg_dcdc3 {
> +	regulator-always-on;
> +	regulator-min-microvolt = <1000000>;
> +	regulator-max-microvolt = <1400000>;
> +	regulator-name = "vdd-int-dll";
> +};
> +
> +&reg_ldo1 {
> +	regulator-name = "vdd-rtc";
> +};
> +
> +&reg_ldo2 {
> +	regulator-always-on;
> +	regulator-min-microvolt = <3000000>;
> +	regulator-max-microvolt = <3000000>;
> +	regulator-name = "avcc";
> +};

What regulator provides the 3.3V regulator used in the rest of this DT
then (MMC, GMAC) ?

Maxime

-- 
Maxime Ripard, Free Electrons
Embedded Linux, Kernel and Android engineering
http://free-electrons.com
-------------- next part --------------
A non-text attachment was scrubbed...
Name: signature.asc
Type: application/pgp-signature
Size: 819 bytes
Desc: Digital signature
URL: <http://lists.infradead.org/pipermail/linux-arm-kernel/attachments/20150803/fd1a3c05/attachment.sig>

From linux at arm.linux.org.uk  Mon Aug  3 02:49:23 2015
From: linux at arm.linux.org.uk (Russell King - ARM Linux)
Date: Mon, 3 Aug 2015 10:49:23 +0100
Subject: [PATCH 0/2] drivers: PL061: Add platform driver probing support
In-Reply-To: <55BF33AD.5040502@huawei.com>
References: <1438585198-8764-1-git-send-email-zhaoshenglong@huawei.com>
 <20150803075848.GH7557@n2100.arm.linux.org.uk>
 <55BF33AD.5040502@huawei.com>
Message-ID: <20150803094923.GI7557@n2100.arm.linux.org.uk>

On Mon, Aug 03, 2015 at 05:26:05PM +0800, Shannon Zhao wrote:
> Hi Russell,
> 
> On 2015/8/3 15:58, Russell King - ARM Linux wrote:
> > On Mon, Aug 03, 2015 at 02:59:56PM +0800, Shannon Zhao wrote:
> >> From: Shannon Zhao <shannon.zhao at linaro.org>
> >>
> >> According to ACPI SPEC, it supports ARM boards to use "GPIO-signaled
> >> ACPI Events". These events can be used for input events. And to QEMU, it
> >> uses GPIO PL061 controller for input events.
> >>
> >> These two patches add platform driver support for PL061 probed by DT or
> >> ACPI.
> > 
> > This certainly is incorrect for DT, and is probably wrong for ACPI too.
> > DT creates amba devices, so binds via the amba device driver.
> > 
> 
> Oh, sorry. The changes for DT are not necessary. But for ACPI I think it
> needs to convert pl061 to platform device since ACPI doesn't support
> AMBA devices. The Pl011 also does the same thing to support ACPI
> probing. See drivers/tty/serial/amba-pl011.c

Maybe rather than having every AMBA driver also converted to a platform
driver (which GregKH hates) maybe ACPI should support the AMBA bus
instead?

Greg?

-- 
FTTC broadband for 0.8mile line: currently at 10.5Mbps down 400kbps up
according to speedtest.net.


From jslaby at suse.cz  Mon Aug  3 02:52:23 2015
From: jslaby at suse.cz (Jiri Slaby)
Date: Mon,  3 Aug 2015 11:52:23 +0200
Subject: [patch added to the 3.12 stable tree] clocksource: exynos_mct: Avoid
 blocking calls in the cpu hotplug notifier
In-Reply-To: <1438595559-22252-1-git-send-email-jslaby@suse.cz>
References: <1438595559-22252-1-git-send-email-jslaby@suse.cz>
Message-ID: <1438595559-22252-36-git-send-email-jslaby@suse.cz>

From: Damian Eppel <d.eppel at samsung.com>

This patch has been added to the 3.12 stable tree. If you have any
objections, please let us know.

===============

commit 56a94f13919c0db5958611b388e1581b4852f3c9 upstream.

Whilst testing cpu hotplug events on kernel configured with
DEBUG_PREEMPT and DEBUG_ATOMIC_SLEEP we get following BUG message,
caused by calling request_irq() and free_irq() in the context of
hotplug notification (which is in this case atomic context).

[   40.785859] CPU1: Software reset
[   40.786660] BUG: sleeping function called from invalid context at mm/slub.c:1241
[   40.786668] in_atomic(): 1, irqs_disabled(): 128, pid: 0, name: swapper/1
[   40.786678] Preemption disabled at:[<  (null)>]   (null)
[   40.786681]
[   40.786692] CPU: 1 PID: 0 Comm: swapper/1 Not tainted 3.19.0-rc4-00024-g7dca860 #36
[   40.786698] Hardware name: SAMSUNG EXYNOS (Flattened Device Tree)
[   40.786728] [<c0014a00>] (unwind_backtrace) from [<c0011980>] (show_stack+0x10/0x14)
[   40.786747] [<c0011980>] (show_stack) from [<c0449ba0>] (dump_stack+0x70/0xbc)
[   40.786767] [<c0449ba0>] (dump_stack) from [<c00c6124>] (kmem_cache_alloc+0xd8/0x170)
[   40.786785] [<c00c6124>] (kmem_cache_alloc) from [<c005d6f8>] (request_threaded_irq+0x64/0x128)
[   40.786804] [<c005d6f8>] (request_threaded_irq) from [<c0350b8c>] (exynos4_local_timer_setup+0xc0/0x13c)
[   40.786820] [<c0350b8c>] (exynos4_local_timer_setup) from [<c0350ca8>] (exynos4_mct_cpu_notify+0x30/0xa8)
[   40.786838] [<c0350ca8>] (exynos4_mct_cpu_notify) from [<c003b330>] (notifier_call_chain+0x44/0x84)
[   40.786857] [<c003b330>] (notifier_call_chain) from [<c0022fd4>] (__cpu_notify+0x28/0x44)
[   40.786873] [<c0022fd4>] (__cpu_notify) from [<c0013714>] (secondary_start_kernel+0xec/0x150)
[   40.786886] [<c0013714>] (secondary_start_kernel) from [<40008764>] (0x40008764)

Interrupts cannot be requested/freed in the CPU_STARTING/CPU_DYING
notifications which run on the hotplugged cpu with interrupts and
preemption disabled.

To avoid the issue, request the interrupts for all possible cpus in
the boot code. The interrupts are marked NO_AUTOENABLE to avoid a racy
request_irq/disable_irq() sequence. The flag prevents the
request_irq() code from enabling the interrupt immediately.

The interrupt is then enabled in the CPU_STARTING notifier of the
hotplugged cpu and again disabled with disable_irq_nosync() in the
CPU_DYING notifier.

[ tglx: Massaged changelog to match the patch ]

Fixes: 7114cd749a12 ("clocksource: exynos_mct: use (request/free)_irq calls for local timer registration")
Reported-by: Krzysztof Kozlowski <k.kozlowski at samsung.com>
Reviewed-by: Krzysztof Kozlowski <k.kozlowski at samsung.com>
Tested-by: Krzysztof Kozlowski <k.kozlowski at samsung.com>
Tested-by: Marcin Jabrzyk <m.jabrzyk at samsung.com>
Signed-off-by: Damian Eppel <d.eppel at samsung.com>
Cc: m.szyprowski at samsung.com
Cc: kyungmin.park at samsung.com
Cc: daniel.lezcano at linaro.org
Cc: kgene at kernel.org
Cc: linux-arm-kernel at lists.infradead.org
Link: http://lkml.kernel.org/r/1435324984-7328-1-git-send-email-d.eppel at samsung.com
Signed-off-by: Thomas Gleixner <tglx at linutronix.de>
Cc: <stable at vger.kernel.org>
Signed-off-by: Jiri Slaby <jslaby at suse.cz>
---
 drivers/clocksource/exynos_mct.c | 43 ++++++++++++++++++++++++++++------------
 1 file changed, 30 insertions(+), 13 deletions(-)

diff --git a/drivers/clocksource/exynos_mct.c b/drivers/clocksource/exynos_mct.c
index 12fbec743fac..fc0e502022de 100644
--- a/drivers/clocksource/exynos_mct.c
+++ b/drivers/clocksource/exynos_mct.c
@@ -418,15 +418,12 @@ static int exynos4_local_timer_setup(struct clock_event_device *evt)
 	exynos4_mct_write(TICK_BASE_CNT, mevt->base + MCT_L_TCNTB_OFFSET);
 
 	if (mct_int_type == MCT_INT_SPI) {
-		evt->irq = mct_irqs[MCT_L0_IRQ + cpu];
-		if (request_irq(evt->irq, exynos4_mct_tick_isr,
-				IRQF_TIMER | IRQF_NOBALANCING,
-				evt->name, mevt)) {
-			pr_err("exynos-mct: cannot register IRQ %d\n",
-				evt->irq);
+
+		if (evt->irq == -1)
 			return -EIO;
-		}
-		irq_force_affinity(mct_irqs[MCT_L0_IRQ + cpu], cpumask_of(cpu));
+
+		irq_force_affinity(evt->irq, cpumask_of(cpu));
+		enable_irq(evt->irq);
 	} else {
 		enable_percpu_irq(mct_irqs[MCT_L0_IRQ], 0);
 	}
@@ -439,10 +436,12 @@ static int exynos4_local_timer_setup(struct clock_event_device *evt)
 static void exynos4_local_timer_stop(struct clock_event_device *evt)
 {
 	evt->set_mode(CLOCK_EVT_MODE_UNUSED, evt);
-	if (mct_int_type == MCT_INT_SPI)
-		free_irq(evt->irq, this_cpu_ptr(&percpu_mct_tick));
-	else
+	if (mct_int_type == MCT_INT_SPI) {
+		if (evt->irq != -1)
+			disable_irq_nosync(evt->irq);
+	} else {
 		disable_percpu_irq(mct_irqs[MCT_L0_IRQ]);
+	}
 }
 
 static int exynos4_mct_cpu_notify(struct notifier_block *self,
@@ -474,7 +473,7 @@ static struct notifier_block exynos4_mct_cpu_nb = {
 
 static void __init exynos4_timer_resources(struct device_node *np, void __iomem *base)
 {
-	int err;
+	int err, cpu;
 	struct mct_clock_event_device *mevt = this_cpu_ptr(&percpu_mct_tick);
 	struct clk *mct_clk, *tick_clk;
 
@@ -501,7 +500,25 @@ static void __init exynos4_timer_resources(struct device_node *np, void __iomem
 		WARN(err, "MCT: can't request IRQ %d (%d)\n",
 		     mct_irqs[MCT_L0_IRQ], err);
 	} else {
-		irq_set_affinity(mct_irqs[MCT_L0_IRQ], cpumask_of(0));
+		for_each_possible_cpu(cpu) {
+			int mct_irq = mct_irqs[MCT_L0_IRQ + cpu];
+			struct mct_clock_event_device *pcpu_mevt =
+				per_cpu_ptr(&percpu_mct_tick, cpu);
+
+			pcpu_mevt->evt.irq = -1;
+
+			irq_set_status_flags(mct_irq, IRQ_NOAUTOEN);
+			if (request_irq(mct_irq,
+					exynos4_mct_tick_isr,
+					IRQF_TIMER | IRQF_NOBALANCING,
+					pcpu_mevt->name, pcpu_mevt)) {
+				pr_err("exynos-mct: cannot register IRQ (cpu%d)\n",
+									cpu);
+
+				continue;
+			}
+			pcpu_mevt->evt.irq = mct_irq;
+		}
 	}
 
 	err = register_cpu_notifier(&exynos4_mct_cpu_nb);
-- 
2.5.0



From stefano.stabellini at eu.citrix.com  Mon Aug  3 02:54:56 2015
From: stefano.stabellini at eu.citrix.com (Stefano Stabellini)
Date: Mon, 3 Aug 2015 10:54:56 +0100
Subject: [PATCH] arm/xen: Drop the definition of
 xen_pci_platform_unplug
In-Reply-To: <1437845641-32052-1-git-send-email-julien.grall@citrix.com>
References: <1437845641-32052-1-git-send-email-julien.grall@citrix.com>
Message-ID: <alpine.DEB.2.02.1508031054310.11337@kaball.uk.xensource.com>

On Sat, 25 Jul 2015, Julien Grall wrote:
> the xen_platform_pci int." makes the x86 version of
> xen_pci_platform_unplug static.
> 
> Therefore we don't need anymore to define a dummy xen_pci_platform_unplug
> for ARM.
> 
> Signed-off-by: Julien Grall <julien.grall at citrix.com>
> Cc: Stefano Stabellini <stefano.stabellini at eu.citrix.com>
> Cc: Russell King <linux at arm.linux.org.uk>

Queued for 4.3.


>  arch/arm/xen/enlighten.c | 3 ---
>  1 file changed, 3 deletions(-)
> 
> diff --git a/arch/arm/xen/enlighten.c b/arch/arm/xen/enlighten.c
> index 6c09cc4..9055c92 100644
> --- a/arch/arm/xen/enlighten.c
> +++ b/arch/arm/xen/enlighten.c
> @@ -49,9 +49,6 @@ struct xen_memory_region xen_extra_mem[XEN_EXTRA_MEM_MAX_REGIONS] __initdata;
>  __read_mostly int xen_have_vector_callback;
>  EXPORT_SYMBOL_GPL(xen_have_vector_callback);
>  
> -int xen_platform_pci_unplug = XEN_UNPLUG_ALL;
> -EXPORT_SYMBOL_GPL(xen_platform_pci_unplug);
> -
>  static __read_mostly unsigned int xen_events_irq;
>  
>  static __initdata struct device_node *xen_node;
> -- 
> 2.1.4
> 


From marc.zyngier at arm.com  Mon Aug  3 02:58:47 2015
From: marc.zyngier at arm.com (Marc Zyngier)
Date: Mon, 03 Aug 2015 10:58:47 +0100
Subject: [PATCH V2 1/2] irqchip/gic: Only allow the primary GIC to set
 the CPU map
In-Reply-To: <1438332252-25248-1-git-send-email-jonathanh@nvidia.com>
References: <1438332252-25248-1-git-send-email-jonathanh@nvidia.com>
Message-ID: <55BF3B57.3090203@arm.com>

On 31/07/15 09:44, Jon Hunter wrote:
> The gic_init_bases() function initialises an array that stores the mapping
> between the GIC and CPUs. This array is a global array that is
> unconditionally initialised on every call to gic_init_bases(). Although,
> it is not common for there to be more than one GIC instance, there are
> some devices that do support nested GIC controllers and gic_init_bases()
> can be called more than once.
> 
> A 2nd call to gic_init_bases() will clear the previous CPU mapping and
> will only setup the mapping again for the CPU calling gic_init_bases().
> Fix this by only allowing the CPU map to be configured for the primary GIC.
> 
> For secondary GICs the CPU map is not relevant because these GICs do not
> directly route the interrupts to the main CPU(s) but to other GICs or
> devices.
> 
> Signed-off-by: Jon Hunter <jonathanh at nvidia.com>

Looks good to me:

Reviewed-by: Marc Zyngier <marc.zyngier at arm.com>

	M.

> ---
> V2 changes:
> - Rebased on v4.2-rc4
> 
>  drivers/irqchip/irq-gic.c | 43 +++++++++++++++++++++++++------------------
>  1 file changed, 25 insertions(+), 18 deletions(-)
> 
> diff --git a/drivers/irqchip/irq-gic.c b/drivers/irqchip/irq-gic.c
> index 4dd88264dff5..dc5090543eca 100644
> --- a/drivers/irqchip/irq-gic.c
> +++ b/drivers/irqchip/irq-gic.c
> @@ -401,19 +401,26 @@ static void gic_cpu_init(struct gic_chip_data *gic)
>  	int i;
>  
>  	/*
> -	 * Get what the GIC says our CPU mask is.
> +	 * Setting up the CPU map is only relevant for the primary GIC
> +	 * because any nested/secondary GICs do not directly interface
> +	 * with the CPU(s).
>  	 */
> -	BUG_ON(cpu >= NR_GIC_CPU_IF);
> -	cpu_mask = gic_get_cpumask(gic);
> -	gic_cpu_map[cpu] = cpu_mask;
> +	if (gic == &gic_data[0]) {
> +		/*
> +		 * Get what the GIC says our CPU mask is.
> +		 */
> +		BUG_ON(cpu >= NR_GIC_CPU_IF);
> +		cpu_mask = gic_get_cpumask(gic);
> +		gic_cpu_map[cpu] = cpu_mask;
>  
> -	/*
> -	 * Clear our mask from the other map entries in case they're
> -	 * still undefined.
> -	 */
> -	for (i = 0; i < NR_GIC_CPU_IF; i++)
> -		if (i != cpu)
> -			gic_cpu_map[i] &= ~cpu_mask;
> +		/*
> +		 * Clear our mask from the other map entries in case they're
> +		 * still undefined.
> +		 */
> +		for (i = 0; i < NR_GIC_CPU_IF; i++)
> +			if (i != cpu)
> +				gic_cpu_map[i] &= ~cpu_mask;
> +	}
>  
>  	gic_cpu_config(dist_base, NULL);
>  
> @@ -930,13 +937,6 @@ void __init gic_init_bases(unsigned int gic_nr, int irq_start,
>  	}
>  
>  	/*
> -	 * Initialize the CPU interface map to all CPUs.
> -	 * It will be refined as each CPU probes its ID.
> -	 */
> -	for (i = 0; i < NR_GIC_CPU_IF; i++)
> -		gic_cpu_map[i] = 0xff;
> -
> -	/*
>  	 * Find out how many interrupts are supported.
>  	 * The GIC only supports up to 1020 interrupt sources.
>  	 */
> @@ -981,6 +981,13 @@ void __init gic_init_bases(unsigned int gic_nr, int irq_start,
>  		return;
>  
>  	if (gic_nr == 0) {
> +		/*
> +		 * Initialize the CPU interface map to all CPUs.
> +		 * It will be refined as each CPU probes its ID.
> +		 * This is only necessary for the primary GIC.
> +		 */
> +		for (i = 0; i < NR_GIC_CPU_IF; i++)
> +			gic_cpu_map[i] = 0xff;
>  #ifdef CONFIG_SMP
>  		set_smp_cross_call(gic_raise_softirq);
>  		register_cpu_notifier(&gic_cpu_notifier);
> 


-- 
Jazz is not dead. It just smells funny...


From marc.zyngier at arm.com  Mon Aug  3 03:02:41 2015
From: marc.zyngier at arm.com (Marc Zyngier)
Date: Mon, 03 Aug 2015 11:02:41 +0100
Subject: [PATCH V2 2/2] irqchip/gic: Ensure gic_cpu_if_up/down() programs
 correct GIC instance
In-Reply-To: <1438332252-25248-2-git-send-email-jonathanh@nvidia.com>
References: <1438332252-25248-1-git-send-email-jonathanh@nvidia.com>
 <1438332252-25248-2-git-send-email-jonathanh@nvidia.com>
Message-ID: <55BF3C41.7000000@arm.com>

On 31/07/15 09:44, Jon Hunter wrote:
> Commit 3228950621d9 ("irqchip: gic: Preserve gic V2 bypass bits in cpu
> ctrl register") added a new function, gic_cpu_if_up(), to program the
> GIC CPU_CTRL register. This function assumes that there is only one GIC
> instance present and hence always uses the chip data for the primary GIC
> controller. Although it is not common for there to be a secondary, some
> devices do support a secondary. Therefore, fix this by passing
> gic_cpu_if_up() a pointer to the appropriate chip data structure.
> 
> Similarly, the function gic_cpu_if_down() only assumes that there is a
> single GIC instance present. Update this function so that an instance
> number is passed for the appropriate GIC and return an error code on
> failure. The vexpress TC2 (which has a single GIC) is currently the only
> user of this function and so update it accordingly. Note that because the
> TC2 only has a single GIC, the call to gic_cpu_if_down() should always
> be successful.
> 
> Signed-off-by: Jon Hunter <jonathanh at nvidia.com>

Reviewed-by: Marc Zyngier <marc.zyngier at arm.com>

I also gave both patches a test run on Realview EB11MP and PB1176, and
both seem happy enough.

Thanks,

	M.

> ---
> V2 changes:
> - Rebased on v4.2-rc4
> - Added test to ensure GIC instance is valid to gic_cpu_if_down() and
>   updated gic_cpu_if_down() to return an error code on failure.
> 
>  arch/arm/mach-vexpress/tc2_pm.c |  2 +-
>  drivers/irqchip/irq-gic.c       | 18 ++++++++++++------
>  include/linux/irqchip/arm-gic.h |  2 +-
>  3 files changed, 14 insertions(+), 8 deletions(-)
> 
> diff --git a/arch/arm/mach-vexpress/tc2_pm.c b/arch/arm/mach-vexpress/tc2_pm.c
> index b3328cd46c33..1aa4ccece69f 100644
> --- a/arch/arm/mach-vexpress/tc2_pm.c
> +++ b/arch/arm/mach-vexpress/tc2_pm.c
> @@ -80,7 +80,7 @@ static void tc2_pm_cpu_powerdown_prepare(unsigned int cpu, unsigned int cluster)
>  	 * to the CPU by disabling the GIC CPU IF to prevent wfi
>  	 * from completing execution behind power controller back
>  	 */
> -	gic_cpu_if_down();
> +	gic_cpu_if_down(0);
>  }
>  
>  static void tc2_pm_cluster_powerdown_prepare(unsigned int cluster)
> diff --git a/drivers/irqchip/irq-gic.c b/drivers/irqchip/irq-gic.c
> index dc5090543eca..fdd1b0e6e5c3 100644
> --- a/drivers/irqchip/irq-gic.c
> +++ b/drivers/irqchip/irq-gic.c
> @@ -355,9 +355,9 @@ static u8 gic_get_cpumask(struct gic_chip_data *gic)
>  	return mask;
>  }
>  
> -static void gic_cpu_if_up(void)
> +static void gic_cpu_if_up(struct gic_chip_data *gic)
>  {
> -	void __iomem *cpu_base = gic_data_cpu_base(&gic_data[0]);
> +	void __iomem *cpu_base = gic_data_cpu_base(gic);
>  	u32 bypass = 0;
>  
>  	/*
> @@ -425,17 +425,23 @@ static void gic_cpu_init(struct gic_chip_data *gic)
>  	gic_cpu_config(dist_base, NULL);
>  
>  	writel_relaxed(GICC_INT_PRI_THRESHOLD, base + GIC_CPU_PRIMASK);
> -	gic_cpu_if_up();
> +	gic_cpu_if_up(gic);
>  }
>  
> -void gic_cpu_if_down(void)
> +int gic_cpu_if_down(unsigned int gic_nr)
>  {
> -	void __iomem *cpu_base = gic_data_cpu_base(&gic_data[0]);
> +	void __iomem *cpu_base;
>  	u32 val = 0;
>  
> +	if (gic_nr >= MAX_GIC_NR)
> +		return -EINVAL;
> +
> +	cpu_base = gic_data_cpu_base(&gic_data[gic_nr]);
>  	val = readl(cpu_base + GIC_CPU_CTRL);
>  	val &= ~GICC_ENABLE;
>  	writel_relaxed(val, cpu_base + GIC_CPU_CTRL);
> +
> +	return 0;
>  }
>  
>  #ifdef CONFIG_CPU_PM
> @@ -571,7 +577,7 @@ static void gic_cpu_restore(unsigned int gic_nr)
>  					dist_base + GIC_DIST_PRI + i * 4);
>  
>  	writel_relaxed(GICC_INT_PRI_THRESHOLD, cpu_base + GIC_CPU_PRIMASK);
> -	gic_cpu_if_up();
> +	gic_cpu_if_up(&gic_data[gic_nr]);
>  }
>  
>  static int gic_notifier(struct notifier_block *self, unsigned long cmd,	void *v)
> diff --git a/include/linux/irqchip/arm-gic.h b/include/linux/irqchip/arm-gic.h
> index 9de976b4f9a7..da6aced1105e 100644
> --- a/include/linux/irqchip/arm-gic.h
> +++ b/include/linux/irqchip/arm-gic.h
> @@ -99,7 +99,7 @@ void gic_set_irqchip_flags(unsigned long flags);
>  void gic_init_bases(unsigned int, int, void __iomem *, void __iomem *,
>  		    u32 offset, struct device_node *);
>  void gic_cascade_irq(unsigned int gic_nr, unsigned int irq);
> -void gic_cpu_if_down(void);
> +int gic_cpu_if_down(unsigned int gic_nr);
>  
>  static inline void gic_init(unsigned int nr, int start,
>  			    void __iomem *dist , void __iomem *cpu)
> 


-- 
Jazz is not dead. It just smells funny...


From mark.rutland at arm.com  Mon Aug  3 03:02:51 2015
From: mark.rutland at arm.com (Mark Rutland)
Date: Mon, 3 Aug 2015 11:02:51 +0100
Subject: [Query] ARM64: Softlockup when using PSCI for secondary CPU_ON
In-Reply-To: <BY1PR0301MB1303EC5AAE8F0B4DAA70D15F82770@BY1PR0301MB1303.namprd03.prod.outlook.com>
References: <BY1PR0301MB1303EC5AAE8F0B4DAA70D15F82770@BY1PR0301MB1303.namprd03.prod.outlook.com>
Message-ID: <20150803100248.GA25627@leverpostej>

On Mon, Aug 03, 2015 at 05:12:00AM +0100, Sharma Bhupesh wrote:
> Hi ARM64 experts,
> 
> I am working on a Freescale ARM64 based SoC, which has 4 Cortex-A53 cores and I am using the
> PSCI conducts to turn on the secondary CPUs via a custom implementation of a secure runtime
> firmware (something similar to the ARM Trusted Firmware).
> 
> Following is my boot-flow:
> 
> - BootROM (runs in EL3, All secondaries are held up in reset) ->
> 
> - UEFI bootloader- PEI Phase (Runs only on Primary, starts up in EL3) ->
> 
> - Secure Firmware (runs in EL3, transitions primary core to EL2) ->
> 
> - UEFI bootloader- Rest of the Phases (Runs only on Primary, in EL2) ->
> 
> - UEFI Linux loader launches linux (Runs only on Primary, transitions core to EL1) ->
>
> - Linux runs and calls PSCI conducts to turn on secondary cores via smc calls to secure run-time firmware ->

Which version of Linux are you using?

Is Linux itself booted at EL1 or EL2?

EL2 is very strongly preferable unless you're already running a
hypervisor at EL2. That way Linux can ensure that things are initialised
correctly at EL2 (e.g. CNTVOFF), regardless of whether you want to use
KVM.

> - Now I can see that the ARM64 linux is able to recognize that the secondaries are boot'ed properly:
> 
> PSCI Logs:
> ----------
> psci: probing for conduit method from DT.
> psci: PSCIv0.2 detected in firmware.
> psci: Using standard PSCI v0.2 function IDs
> ..
> 
> Architected cp15 timer(s) running at 25.00MHz (phys).
> sched_clock: 56 bits at 25MHz, resolution 40ns, wraps every 2748779069440ns
> 
> ..
> 
> CPU1: Booted secondary processor
> Detected VIPT I-cache on CPU1
> CPU2: Booted secondary processor
> Detected VIPT I-cache on CPU2
> CPU3: Booted secondary processor
> Detected VIPT I-cache on CPU3
> Brought up 4 CPUs
> SMP: Total of 4 processors activated.

Ok. This all looks fine.

> - However, when the Linux boot proceeds further, I see softlockups which usually show that one
> of the secondaries was stuck in 'secondary_start_kernel' (detailed logs below).
>
> - When I turn of CONFIG_SMP from the .config, I can see that the softlockups disappear. So, I am
> correlating these softlockups to SMP and PSCI conducts.

Ok, that likely means it's in the idle loop. Given that the CPUs made it
into the kernel this sounds like a generic SMP issue rather than
something specific to PSCI.

> preempt self-detected stall on CPU { 3}  (t=17194 jiffies g=-267 c=-268 q=1)

> INFO: rcu_preempt detected stalls on CPUs/tasks: { 1 2} (detected by 0, t=287104493908 jiffies, g=-267, c=-268, q=2)

It looks like your timekeeping has gone wrong. As mentioned above, I'd
suspect that CNTVOFF_EL2 is not programmed consistently across all CPUs.

Are you able to boot Linux at EL2 instead? Or can you verify that
CNTVOFF_EL2 is initialised?

Thanks,
Mark.


From bhupesh.sharma at freescale.com  Mon Aug  3 03:17:03 2015
From: bhupesh.sharma at freescale.com (Sharma Bhupesh)
Date: Mon, 3 Aug 2015 10:17:03 +0000
Subject: [Query] ARM64: Softlockup when using PSCI for secondary CPU_ON
In-Reply-To: <20150803100248.GA25627@leverpostej>
References: <BY1PR0301MB1303EC5AAE8F0B4DAA70D15F82770@BY1PR0301MB1303.namprd03.prod.outlook.com>
 <20150803100248.GA25627@leverpostej>
Message-ID: <BY1PR0301MB1303B775B1D5D318A64350C582770@BY1PR0301MB1303.namprd03.prod.outlook.com>

Hi Mark,

Thanks for the reply.

> From: Mark Rutland [mailto:mark.rutland at arm.com]
> Sent: Monday, August 03, 2015 3:33 PM
>
> On Mon, Aug 03, 2015 at 05:12:00AM +0100, Sharma Bhupesh wrote:
> > Hi ARM64 experts,
> >
> > I am working on a Freescale ARM64 based SoC, which has 4 Cortex-A53
> > cores and I am using the PSCI conducts to turn on the secondary CPUs
> > via a custom implementation of a secure runtime firmware (something
> similar to the ARM Trusted Firmware).
> >
> > Following is my boot-flow:
> >
> > - BootROM (runs in EL3, All secondaries are held up in reset) ->
> >
> > - UEFI bootloader- PEI Phase (Runs only on Primary, starts up in EL3)
> > ->
> >
> > - Secure Firmware (runs in EL3, transitions primary core to EL2) ->
> >
> > - UEFI bootloader- Rest of the Phases (Runs only on Primary, in EL2)
> > ->
> >
> > - UEFI Linux loader launches linux (Runs only on Primary, transitions
> > core to EL1) ->
> >
> > - Linux runs and calls PSCI conducts to turn on secondary cores via
> > smc calls to secure run-time firmware ->
> 
> Which version of Linux are you using?

I am using 3.19.3
 
> Is Linux itself booted at EL1 or EL2?

UEFI leaves the execution level of the primary core in EL2.
KVM is turned-off in my defconfig, so I am not loading any hypervisor at EL2 as of now.

> EL2 is very strongly preferable unless you're already running a
> hypervisor at EL2. That way Linux can ensure that things are initialised
> correctly at EL2 (e.g. CNTVOFF), regardless of whether you want to use
> KVM.

I notice that in the kernel primary core successfully switches to EL1 and starts executing the
relevant 'start_kernel' routine.
 
> > - Now I can see that the ARM64 linux is able to recognize that the
> secondaries are boot'ed properly:
> >
> > PSCI Logs:
> > ----------
> > psci: probing for conduit method from DT.
> > psci: PSCIv0.2 detected in firmware.
> > psci: Using standard PSCI v0.2 function IDs ..
> >
> > Architected cp15 timer(s) running at 25.00MHz (phys).
> > sched_clock: 56 bits at 25MHz, resolution 40ns, wraps every
> > 2748779069440ns
> >
> > ..
> >
> > CPU1: Booted secondary processor
> > Detected VIPT I-cache on CPU1
> > CPU2: Booted secondary processor
> > Detected VIPT I-cache on CPU2
> > CPU3: Booted secondary processor
> > Detected VIPT I-cache on CPU3
> > Brought up 4 CPUs
> > SMP: Total of 4 processors activated.
> 
> Ok. This all looks fine.
> 
> > - However, when the Linux boot proceeds further, I see softlockups
> > which usually show that one of the secondaries was stuck in
> 'secondary_start_kernel' (detailed logs below).
> >
> > - When I turn of CONFIG_SMP from the .config, I can see that the
> > softlockups disappear. So, I am correlating these softlockups to SMP
> and PSCI conducts.
> 
> Ok, that likely means it's in the idle loop. Given that the CPUs made it
> into the kernel this sounds like a generic SMP issue rather than
> something specific to PSCI.

Ok.
 
> > preempt self-detected stall on CPU { 3}  (t=17194 jiffies g=-267
> > c=-268 q=1)
> 
> > INFO: rcu_preempt detected stalls on CPUs/tasks: { 1 2} (detected by
> > 0, t=287104493908 jiffies, g=-267, c=-268, q=2)
> 
> It looks like your timekeeping has gone wrong. As mentioned above, I'd
> suspect that CNTVOFF_EL2 is not programmed consistently across all CPUs.
> 
> Are you able to boot Linux at EL2 instead? Or can you verify that
> CNTVOFF_EL2 is initialised?
> 

Ok, let me check the CNTVOFF_EL2 part then.
I will get back with details soon.

Regards,
Bhupesh


From b.zolnierkie at samsung.com  Mon Aug  3 03:17:51 2015
From: b.zolnierkie at samsung.com (Bartlomiej Zolnierkiewicz)
Date: Mon, 03 Aug 2015 12:17:51 +0200
Subject: [PATCH v3 3/5] ARM: Exynos: switch to using generic cpufreq driver
 for Exynos4x12
In-Reply-To: <20150801111721.GI899@linux>
References: <1438368557-2352-1-git-send-email-b.zolnierkie@samsung.com>
 <1438368557-2352-4-git-send-email-b.zolnierkie@samsung.com>
 <20150801111721.GI899@linux>
Message-ID: <5201904.0cZWHobiJs@amdc1976>


Hi,

On Saturday, August 01, 2015 04:47:21 PM Viresh Kumar wrote:
> On 31-07-15, 20:49, Bartlomiej Zolnierkiewicz wrote:
> > diff --git a/drivers/cpufreq/Kconfig b/drivers/cpufreq/Kconfig
> > index 659879a..bf6d596 100644
> > --- a/drivers/cpufreq/Kconfig
> > +++ b/drivers/cpufreq/Kconfig
> > @@ -191,6 +191,7 @@ config CPUFREQ_DT
> >  	# if CPU_THERMAL is on and THERMAL=m, CPUFREQ_DT cannot be =y:
> >  	depends on !CPU_THERMAL || THERMAL
> >  	select PM_OPP
> > +	select EXYNOS_THERMAL if ARCH_EXYNOS
> >  	help
> >  	  This adds a generic DT based cpufreq driver for frequency management.
> >  	  It supports both uniprocessor (UP) and symmetric multiprocessor (SMP)
> 
> No, we shouldn't pollute generic Kconfig options with platform specific stuff.

The old code depended on this.  You couldn't enable boost support
without enabling thermal support (ARM_EXYNOS_CPU_FREQ_BOOST_SW
config option selected EXYNOS_THERMAL).

> Why don't you enable thermal in your .config?

It is enabled in exynos_defconfig but without the above change it
can disabled manually which is something that we don't want.

Best regards,
--
Bartlomiej Zolnierkiewicz
Samsung R&D Institute Poland
Samsung Electronics



From sudeep.holla at arm.com  Mon Aug  3 03:18:43 2015
From: sudeep.holla at arm.com (Sudeep Holla)
Date: Mon, 03 Aug 2015 11:18:43 +0100
Subject: [PATCH 0/3] Move clk-sp810 to assigned clock parents
In-Reply-To: <1438386285-5070-1-git-send-email-sboyd@codeaurora.org>
References: <55BBB2FC.9030102@codeaurora.org>
 <1438386285-5070-1-git-send-email-sboyd@codeaurora.org>
Message-ID: <55BF4003.3040708@arm.com>

Hi Stephen,

On 01/08/15 00:44, Stephen Boyd wrote:
> This patch set converts this code to use the assigned-clock-parents
> property instead of doing some interesting stuff in the .prepare
> op. I can route the dts patches through arm-soc but I'd like to take
> the clk patch through clk tree because it removes some usage of the
> struct clk based provider APIs that we're trying to get rid of. Also,
> this is completely untested, so testing would be appreciated.
> Can this be tested with qemu? I haven't tried but I was thinking
> that might be an option.
>
> Cc: Pawel Moll <pawel.moll at arm.com>
> Cc: Linus Walleij <linus.walleij at linaro.org>
> Cc: Sudeep Holla <sudeep.holla at arm.com>
>

Tested-by: Sudeep Holla <sudeep.holla at arm.com>
(Tested the series on Juno R0 and Vexpress TC2 platform)

Regards,
Sudeep


From Liviu.Dudau at arm.com  Mon Aug  3 03:18:45 2015
From: Liviu.Dudau at arm.com (Liviu Dudau)
Date: Mon, 3 Aug 2015 11:18:45 +0100
Subject: [PATCH v6 0/8] ARM64: juno: add SCPI mailbox protocol, clock and
 CPUFreq support
In-Reply-To: <1438364591-1144-1-git-send-email-sudeep.holla@arm.com>
References: <1438364591-1144-1-git-send-email-sudeep.holla@arm.com>
Message-ID: <20150803101845.GU20890@e106497-lin.cambridge.arm.com>

On Fri, Jul 31, 2015 at 06:43:03PM +0100, Sudeep Holla wrote:
> Hi ARM-SoC guys,
> 
> It has been on the list for a while and have got all the necessary ACKs.
> Can you please pull this series for v4.3 ?
> 
> Regards,
> Sudeep
> 
> This patch series adds support for:
>   1. SCPI(System Control and Power Interface) mailbox protocol driver.
>      It uses ARM MHU mailbox controller driver on Juno but can work with
>      any mailbox controllers using standard mailbox APIs
>   2. Add support for clocks provided by SCP firmware through the SCPI
>      interface
>   3. Using the existing arm_big_little cpufreq driver and the newly
>      added SCPI clock driver, it also adds support for CPU DVFS on
>      ARM64 JUNO development platforms.

Hi Sudeep,

Is there a branch where I can pull this series from?

Best regards,
Liviu

> 
> The SCPI protocol document is available @[1],[2]
> 
> Changes v5->v6:
> 	- Minor review comments on clock bindings and clock driver
> 	- Added all the ACKs necessary
> 
> Changes v4->v5:
> 	- Updated the SCPI clock bindings to correct the clock specifier
> 	  usage and other minor updates as per review feedback
> 	- Updated clock driver to use SCPI specifier clock specifier
> 	  decode function
> 	- Minor reshuffling in Juno DTS files, no functionality change
> 
> Changes v3->v4:
> 	- Updated the SCPI binding based on MarkR's feedback
> 	- Updated SCPI clock driver to incorporate Stephen Boyd's review
> 	  comments + used clk_set_rate_range to limit the clock range
> 	- Since no major changes are expected in SCPI DT, updated the
> 	  Juno DTS to support SCPI and dependent device nodes.
> 
> Changes v2->v3:
> 	- Minor fix in SCPI driver and added Tixy's reviewed-by tag
> 	- Updated scpi clock driver to incorporate all the comments from
> 	  Stephen
> 	- Added Viresh's ack
> 
> Changes v1->v2:
> 	- Updated the token handling in scpi driver as per Tixy's
> 	  suggestion along with other review comments
> 	- Removed multiple drivers in scpi clock as Lorenzo suggested
> 	- Added free_opp_table in scpi-cpufreq as Viresh suggested
> 	- Separated the DT binding document
> 	- Moved SCPI protocol driver to drivers/firmware
> 
> [1] http://community.arm.com/servlet/JiveServlet/download/8401-45-18326/DUI0922B_scp_message_interface.pdf
> [2] https://wiki.linaro.org/ARM/Juno?action=AttachFile&do=get&target=DUI0922B_scp_message_interface.pdf
> v1: https://lkml.org/lkml/2015/4/27/232
> v2: https://lkml.org/lkml/2015/5/14/470
> v3: https://lkml.org/lkml/2015/5/27/220
> v4: https://lkml.org/lkml/2015/6/8/178
> v5: https://lkml.org/lkml/2015/7/23/270
> 
> Cc: devicetree at vger.kernel.org
> Cc: linux-clk at vger.kernel.org
> Cc: linux-pm at vger.kernel.org
> 
> Sudeep Holla (8):
>   Documentation: add DT binding for ARM System Control and Power
>     Interface(SCPI) protocol
>   firmware: add support for ARM System Control and Power Interface(SCPI)
>     protocol
>   clk: add support for clocks provided by SCP(System Control Processor)
>   clk: scpi: add support for cpufreq virtual device
>   cpufreq: arm_big_little: add SCPI interface driver
>   arm64: dts: add SRAM, MHU mailbox and SCPI support on Juno
>   arm64: dts: add CPU topology on Juno
>   arm64: dts: add clock support for all the cpus
> 
>  Documentation/devicetree/bindings/arm/arm,scpi.txt | 150 +++++
>  MAINTAINERS                                        |  10 +
>  arch/arm64/boot/dts/arm/juno-base.dtsi             |  54 ++
>  arch/arm64/boot/dts/arm/juno-r1.dts                |  32 +
>  arch/arm64/boot/dts/arm/juno.dts                   |  32 +
>  drivers/clk/Kconfig                                |  10 +
>  drivers/clk/Makefile                               |   1 +
>  drivers/clk/clk-scpi.c                             | 325 ++++++++++
>  drivers/cpufreq/Kconfig.arm                        |   9 +
>  drivers/cpufreq/Makefile                           |   1 +
>  drivers/cpufreq/scpi-cpufreq.c                     | 124 ++++
>  drivers/firmware/Kconfig                           |  19 +
>  drivers/firmware/Makefile                          |   1 +
>  drivers/firmware/arm_scpi.c                        | 711 +++++++++++++++++++++
>  include/linux/scpi_protocol.h                      |  61 ++
>  15 files changed, 1540 insertions(+)
>  create mode 100644 Documentation/devicetree/bindings/arm/arm,scpi.txt
>  create mode 100644 drivers/clk/clk-scpi.c
>  create mode 100644 drivers/cpufreq/scpi-cpufreq.c
>  create mode 100644 drivers/firmware/arm_scpi.c
>  create mode 100644 include/linux/scpi_protocol.h
> 
> -- 
> 1.9.1
> 

-- 
====================
| I would like to |
| fix the world,  |
| but they're not |
| giving me the   |
 \ source code!  /
  ---------------
    ?\_(?)_/?



From yong.wu at mediatek.com  Mon Aug  3 03:21:13 2015
From: yong.wu at mediatek.com (Yong Wu)
Date: Mon, 3 Aug 2015 18:21:13 +0800
Subject: [PATCH v4 0/6] MT8173 IOMMU SUPPORT
Message-ID: <1438597279-2937-1-git-send-email-yong.wu@mediatek.com>

This patch set adds support for m4u(Multimedia Memory Management Unit),
Currently it only support the m4u with 2 levels of pagetable on mt8173.

  It's based on Robin Murphy's arm64 DMA-v5[1] and Robin's allow DMA API use in
io-pgtable-arm[2]. The dsti is based on MTK clock patch[3].
 
  Please check the hardware block diagram of Mediatek IOMMU.
 
              EMI (External Memory Interface)
               |
              m4u (Multimedia Memory Management Unit)
               |
              smi (Smart Multimedia Interface)
               |
        +---------------+-------
        |               |
        |               |
    vdec larb       disp larb      ... SoCs have different local arbiter(larb).
        |               |
        |               |
   +----+----+    +-----+-----+
   |    |    |    |     |     |    ...
   |    |    |    |     |     |    ...
   |    |    |    |     |     |    ...
  MC   PP   VLD  OVL0 RDMA0 WDMA0  ... There are different ports in each larb.
  
  Normally we specify a local arbiter(larb) for each multimedia hardware like
display, video decode, video encode and camera. And there are different ports in
each larb. Take a example, there are some ports like MC, PP, UFO, VLD, AVC_MV,
PRED_RD in video larb, all the ports are according to the video hardware.
 
  From the diagram, all the multimedia module connect with m4u via smi.
SMI is responsible to enable/disable iommu and control the clocks for each local
arbiter. If we should enable the iommu of video decode, it should config the
video's ports. And if the video hardware work whether enable/disable iommu, 
it should enable the clock of its larb's clock. And smi also help bandwidth
control for each local. So we add a special driver for smi and locate
it drivers/memory.

v4:
-use only one iommu domain here based on the Robin's DMA-v5.
-remove flush_pgtable.
-change writel to writel_relaxed.
-about Short-descriptor: move dma_map_single into io-pgtable-arm-short.
 Improve the flow of free pgtable and add NO_XN+NO_PERMS quirk following
 Will's suggestion.
-Change two sytle issues in dtsi according to Daniel's suggestion.

v3: http://lists.linuxfoundation.org/pipermail/iommu/2015-July/013632.html
-rebased onto v4.2-rc1
-improve iommu flow based on the Robin's DMA v3[4].
-change mtk iommu-cells from 1 to 2.
-about Short-descriptor: add split function; add self-test; add some other bits like nG,
 XN according to the spec; add SUPERSECTION and MTK quirk; move io_pgtable_ops_to_pgtable
 out from LPAE to the header file.
-about SMI: move from driver/soc/mediatek to driver/memory; change the clocks from
 clk[2] to clk_apb and clk_smi; add pm.
-add iommu suspend/resume to backup/restore register.

v2: http://lists.linuxfoundation.org/pipermail/iommu/2015-May/013028.html
-add arm short descriptor support.
-seperate smi common from smi and change the clock-names according
 to smi HW.
-delete the hardcode of the port-names in mt8173.
 replace this with larb-portes-nr in dtsi.
-fix some coding style issues.

v1: http://lists.infradead.org/pipermail/linux-mediatek/2015-March/000058.html
-initial version.

[1]: http://lists.linuxfoundation.org/pipermail/iommu/2015-July/013900.html
[2]: http://lists.linuxfoundation.org/pipermail/iommu/2015-July/013876.html
[3]: http://lists.infradead.org/pipermail/linux-mediatek/2015-July/001800.html
[4]: http://lists.linuxfoundation.org/pipermail/iommu/2015-July/013597.html

Yong Wu (6):
  dt-bindings: iommu: Add binding for mediatek IOMMU
  dt-bindings: mediatek: Add smi dts binding
  iommu: add ARM short descriptor page table allocator.
  memory: mediatek: Add SMI driver
  iommu/mediatek: Add mt8173 IOMMU driver
  dts: mt8173: Add iommu/smi nodes for mt8173

 .../devicetree/bindings/iommu/mediatek,iommu.txt   |  61 ++
 .../memory-controllers/mediatek,smi-larb.txt       |  25 +
 .../bindings/memory-controllers/mediatek,smi.txt   |  24 +
 arch/arm64/boot/dts/mediatek/mt8173.dtsi           |  81 ++
 drivers/iommu/Kconfig                              |  31 +
 drivers/iommu/Makefile                             |   2 +
 drivers/iommu/io-pgtable-arm-short.c               | 811 +++++++++++++++++++++
 drivers/iommu/io-pgtable-arm.c                     |   3 -
 drivers/iommu/io-pgtable.c                         |   4 +
 drivers/iommu/io-pgtable.h                         |  14 +
 drivers/iommu/mtk_iommu.c                          | 714 ++++++++++++++++++
 drivers/memory/Kconfig                             |   8 +
 drivers/memory/Makefile                            |   1 +
 drivers/memory/mtk-smi.c                           | 285 ++++++++
 include/dt-bindings/memory/mt8173-larb-port.h      | 105 +++
 include/soc/mediatek/smi.h                         |  60 ++
 16 files changed, 2226 insertions(+), 3 deletions(-)
 create mode 100644 Documentation/devicetree/bindings/iommu/mediatek,iommu.txt
 create mode 100644 Documentation/devicetree/bindings/memory-controllers/mediatek,smi-larb.txt
 create mode 100644 Documentation/devicetree/bindings/memory-controllers/mediatek,smi.txt
 create mode 100644 drivers/iommu/io-pgtable-arm-short.c
 create mode 100644 drivers/iommu/mtk_iommu.c
 create mode 100644 drivers/memory/mtk-smi.c
 create mode 100644 include/dt-bindings/memory/mt8173-larb-port.h
 create mode 100644 include/soc/mediatek/smi.h

-- 
1.8.1.1.dirty



From yong.wu at mediatek.com  Mon Aug  3 03:21:14 2015
From: yong.wu at mediatek.com (Yong Wu)
Date: Mon, 3 Aug 2015 18:21:14 +0800
Subject: [PATCH v4 1/6] dt-bindings: iommu: Add binding for mediatek IOMMU
In-Reply-To: <1438597279-2937-1-git-send-email-yong.wu@mediatek.com>
References: <1438597279-2937-1-git-send-email-yong.wu@mediatek.com>
Message-ID: <1438597279-2937-2-git-send-email-yong.wu@mediatek.com>

This patch add mediatek iommu dts binding document.

Signed-off-by: Yong Wu <yong.wu at mediatek.com>
---
 .../devicetree/bindings/iommu/mediatek,iommu.txt   |  61 ++++++++++++
 include/dt-bindings/memory/mt8173-larb-port.h      | 105 +++++++++++++++++++++
 2 files changed, 166 insertions(+)
 create mode 100644 Documentation/devicetree/bindings/iommu/mediatek,iommu.txt
 create mode 100644 include/dt-bindings/memory/mt8173-larb-port.h

diff --git a/Documentation/devicetree/bindings/iommu/mediatek,iommu.txt b/Documentation/devicetree/bindings/iommu/mediatek,iommu.txt
new file mode 100644
index 0000000..691739a
--- /dev/null
+++ b/Documentation/devicetree/bindings/iommu/mediatek,iommu.txt
@@ -0,0 +1,61 @@
+* Mediatek IOMMU Architecture Implementation
+
+  Mediatek Socs may contain a implementation of Multimedia Memory
+Management Unit(M4U),which use ARM Short-descriptor translation table
+to achieve address translation.
+
+  The IOMMU Hardware Block Diagram, please check below:
+
+              EMI (External Memory Interface)
+               |
+              m4u (Multimedia Memory Management Unit)
+               |
+              smi (Smart Multimedia Interface)
+               |
+        +---------------+-------
+        |               |
+        |               |
+    vdec larb       disp larb      ... SoCs have different local arbiter(larb).
+        |               |
+        |               |
+   +----+----+    +-----+-----+
+   |    |    |    |     |     |    ...
+   |    |    |    |     |     |    ...
+   |    |    |    |     |     |    ...
+  MC   PP   VLD  OVL0 RDMA0 WDMA0  ... There are different ports in each larb.
+
+  As above, The Multimedia HW will go through SMI and M4U while it
+access EMI. SMI is a brige between m4u and the Multimedia HW. It contain
+smi local arbiter and smi common. It will control whether the Multimedia
+HW should go though the m4u for translation or bypass it and talk
+directly with EMI. And also SMI help control the clocks for each
+local arbiter.
+  Normally we specify a local arbiter(larb) for each multimedia HW
+like display, video decode, and camera. And there are different ports
+in each larb. Take a example, There are some ports like MC, PP, VLD in the
+video decode local arbiter, all the ports are according to the video HW.
+
+Required properties:
+- compatible : must be "mediatek,mt8173-m4u".
+- reg : m4u register base and size.
+- interrupts : the interrupt of m4u.
+- clocks : must contain one entry for each clock-names.
+- clock-names : must be "bclk", It is the block clock of m4u.
+- mediatek,larb : List of phandle to the local arbiters in the current Socs.
+	Refer to bindings/memory-controllers/mediatek,smi-larb.txt. It must sort
+	according to the local arbiter index, like larb0, larb1, larb2...
+- iommu-cells : must be 2. There are 2 cells needed to enable/disable iommu.
+	The first one is local arbiter index(larbid), and the other is port
+	index(portid) within local arbiter. Specifies the larbid and portid as
+	defined in dt-binding/memory/mt8173-larb-port.h.
+
+Example:
+	iommu: mmsys_iommu at 10205000 {
+		compatible = "mediatek,mt8173-m4u";
+		reg = <0 0x10205000 0 0x1000>;
+		interrupts = <GIC_SPI 139 IRQ_TYPE_LEVEL_LOW>;
+		clocks = <&infracfg CLK_INFRA_M4U>;
+		clock-names = "bclk";
+		mediatek,larb = <&larb0 &larb1 &larb2 &larb3 &larb4 &larb5>;
+		#iommu-cells = <2>;
+	};
diff --git a/include/dt-bindings/memory/mt8173-larb-port.h b/include/dt-bindings/memory/mt8173-larb-port.h
new file mode 100644
index 0000000..7517087
--- /dev/null
+++ b/include/dt-bindings/memory/mt8173-larb-port.h
@@ -0,0 +1,105 @@
+/*
+ * Copyright (c) 2014-2015 MediaTek Inc.
+ * Author: Yong Wu <yong.wu at 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.
+ */
+#ifndef __DTS_IOMMU_PORT_MT8173_H
+#define __DTS_IOMMU_PORT_MT8173_H
+
+#define M4U_LARB0_ID			0
+#define M4U_LARB1_ID			1
+#define M4U_LARB2_ID			2
+#define M4U_LARB3_ID			3
+#define M4U_LARB4_ID			4
+#define M4U_LARB5_ID			5
+
+/* larb0 */
+#define	M4U_PORT_DISP_OVL0		0
+#define	M4U_PORT_DISP_RDMA0		1
+#define	M4U_PORT_DISP_WDMA0		2
+#define	M4U_PORT_DISP_OD_R		3
+#define	M4U_PORT_DISP_OD_W		4
+#define	M4U_PORT_MDP_RDMA0		5
+#define	M4U_PORT_MDP_WDMA		6
+#define	M4U_PORT_MDP_WROT0		7
+
+/* larb1 */
+#define	M4U_PORT_HW_VDEC_MC_EXT		0
+#define	M4U_PORT_HW_VDEC_PP_EXT		1
+#define	M4U_PORT_HW_VDEC_UFO_EXT	2
+#define	M4U_PORT_HW_VDEC_VLD_EXT	3
+#define	M4U_PORT_HW_VDEC_VLD2_EXT	4
+#define	M4U_PORT_HW_VDEC_AVC_MV_EXT	5
+#define	M4U_PORT_HW_VDEC_PRED_RD_EXT	6
+#define	M4U_PORT_HW_VDEC_PRED_WR_EXT	7
+#define	M4U_PORT_HW_VDEC_PPWRAP_EXT	8
+#define	M4U_PORT_HW_VDEC_TILE		9
+
+/* larb2 */
+#define	M4U_PORT_IMGO			0
+#define	M4U_PORT_RRZO			1
+#define	M4U_PORT_AAO			2
+#define	M4U_PORT_LCSO			3
+#define	M4U_PORT_ESFKO			4
+#define	M4U_PORT_IMGO_D			5
+#define	M4U_PORT_LSCI			6
+#define	M4U_PORT_LSCI_D			7
+#define	M4U_PORT_BPCI			8
+#define	M4U_PORT_BPCI_D			9
+#define	M4U_PORT_UFDI			10
+#define	M4U_PORT_IMGI			11
+#define	M4U_PORT_IMG2O			12
+#define	M4U_PORT_IMG3O			13
+#define	M4U_PORT_VIPI			14
+#define	M4U_PORT_VIP2I			15
+#define	M4U_PORT_VIP3I			16
+#define	M4U_PORT_LCEI			17
+#define	M4U_PORT_RB			18
+#define	M4U_PORT_RP			19
+#define	M4U_PORT_WR			20
+
+/* larb3 */
+#define	M4U_PORT_VENC_RCPU		0
+#define	M4U_PORT_VENC_REC		1
+#define	M4U_PORT_VENC_BSDMA		2
+#define	M4U_PORT_VENC_SV_COMV		3
+#define	M4U_PORT_VENC_RD_COMV		4
+#define	M4U_PORT_JPGENC_RDMA		5
+#define	M4U_PORT_JPGENC_BSDMA		6
+#define	M4U_PORT_JPGDEC_WDMA		7
+#define	M4U_PORT_JPGDEC_BSDMA		8
+#define	M4U_PORT_VENC_CUR_LUMA		9
+#define	M4U_PORT_VENC_CUR_CHROMA	10
+#define	M4U_PORT_VENC_REF_LUMA		11
+#define	M4U_PORT_VENC_REF_CHROMA	12
+#define	M4U_PORT_VENC_NBM_RDMA		13
+#define	M4U_PORT_VENC_NBM_WDMA		14
+
+/* larb4 */
+#define	M4U_PORT_DISP_OVL1		0
+#define	M4U_PORT_DISP_RDMA1		1
+#define	M4U_PORT_DISP_RDMA2		2
+#define	M4U_PORT_DISP_WDMA1		3
+#define	M4U_PORT_MDP_RDMA1		4
+#define	M4U_PORT_MDP_WROT1		5
+
+/* larb5 */
+#define	M4U_PORT_VENC_RCPU_SET2		0
+#define	M4U_PORT_VENC_REC_FRM_SET2	1
+#define	M4U_PORT_VENC_REF_LUMA_SET2	2
+#define	M4U_PORT_VENC_REC_CHROMA_SET2	3
+#define	M4U_PORT_VENC_BSDMA_SET2	4
+#define	M4U_PORT_VENC_CUR_LUMA_SET2	5
+#define	M4U_PORT_VENC_CUR_CHROMA_SET2	6
+#define	M4U_PORT_VENC_RD_COMA_SET2	7
+#define	M4U_PORT_VENC_SV_COMA_SET2	8
+
+#endif
-- 
1.8.1.1.dirty



From yong.wu at mediatek.com  Mon Aug  3 03:21:15 2015
From: yong.wu at mediatek.com (Yong Wu)
Date: Mon, 3 Aug 2015 18:21:15 +0800
Subject: [PATCH v4 2/6] dt-bindings: mediatek: Add smi dts binding
In-Reply-To: <1438597279-2937-1-git-send-email-yong.wu@mediatek.com>
References: <1438597279-2937-1-git-send-email-yong.wu@mediatek.com>
Message-ID: <1438597279-2937-3-git-send-email-yong.wu@mediatek.com>

This patch add smi binding document.

Signed-off-by: Yong Wu <yong.wu at mediatek.com>
---
 .../memory-controllers/mediatek,smi-larb.txt       | 25 ++++++++++++++++++++++
 .../bindings/memory-controllers/mediatek,smi.txt   | 24 +++++++++++++++++++++
 2 files changed, 49 insertions(+)
 create mode 100644 Documentation/devicetree/bindings/memory-controllers/mediatek,smi-larb.txt
 create mode 100644 Documentation/devicetree/bindings/memory-controllers/mediatek,smi.txt

diff --git a/Documentation/devicetree/bindings/memory-controllers/mediatek,smi-larb.txt b/Documentation/devicetree/bindings/memory-controllers/mediatek,smi-larb.txt
new file mode 100644
index 0000000..55ff3b7
--- /dev/null
+++ b/Documentation/devicetree/bindings/memory-controllers/mediatek,smi-larb.txt
@@ -0,0 +1,25 @@
+SMI (Smart Multimedia Interface) Local Arbiter
+
+The hardware block diagram please check bindings/iommu/mediatek,iommu.txt
+
+Required properties:
+- compatible : must be "mediatek,mt8173-smi-larb"
+- reg : the register and size of this local arbiter.
+- mediatek,smi : a phandle to the smi_common node.
+- power-domains : a phandle to the power domain of this local arbiter.
+- clocks : Must contain an entry for each entry in clock-names.
+- clock-names: must contain 2 entries, as follows:
+  - "apb" : Advanced Peripheral Bus clock, It's the clock for setting
+	    the register.
+  - "smi" : It's the clock for transfer data and command.
+
+Example:
+	larb1: larb at 16010000 {
+		compatible = "mediatek,mt8173-smi-larb";
+		reg = <0 0x16010000 0 0x1000>;
+		mediatek,smi = <&smi_common>;
+		power-domains = <&scpsys MT8173_POWER_DOMAIN_VDEC>;
+		clocks = <&vdecsys CLK_VDEC_CKEN>,
+			 <&vdecsys CLK_VDEC_LARB_CKEN>;
+		clock-names = "apb", "smi";
+	};
diff --git a/Documentation/devicetree/bindings/memory-controllers/mediatek,smi.txt b/Documentation/devicetree/bindings/memory-controllers/mediatek,smi.txt
new file mode 100644
index 0000000..f54e91c
--- /dev/null
+++ b/Documentation/devicetree/bindings/memory-controllers/mediatek,smi.txt
@@ -0,0 +1,24 @@
+SMI (Smart Multimedia Interface)
+
+The hardware block diagram please check bindings/iommu/mediatek,iommu.txt
+
+Required properties:
+- compatible : must be "mediatek,mt8173-smi"
+- reg : the register and size of the SMI block.
+- power-domains : a phandle to the power domain of this local arbiter.
+- clocks : Must contain an entry for each entry in clock-names.
+- clock-names : must contain 2 entries, as follows:
+  - "apb" : Advanced Peripheral Bus clock, It's the clock for setting
+	    the register.
+  - "smi" : It's the clock for transfer data and command.
+  They may be the same if both source clock are the same.
+
+Example:
+	smi_common: smi at 14022000 {
+		compatible = "mediatek,mt8173-smi";
+		reg = <0 0x14022000 0 0x1000>;
+		power-domains = <&scpsys MT8173_POWER_DOMAIN_MM>;
+		clocks = <&mmsys CLK_MM_SMI_COMMON>,
+			 <&mmsys CLK_MM_SMI_COMMON>;
+		clock-names = "apb", "smi";
+	};
-- 
1.8.1.1.dirty



From yong.wu at mediatek.com  Mon Aug  3 03:21:16 2015
From: yong.wu at mediatek.com (Yong Wu)
Date: Mon, 3 Aug 2015 18:21:16 +0800
Subject: [PATCH v4 3/6] iommu: add ARM short descriptor page table allocator.
In-Reply-To: <1438597279-2937-1-git-send-email-yong.wu@mediatek.com>
References: <1438597279-2937-1-git-send-email-yong.wu@mediatek.com>
Message-ID: <1438597279-2937-4-git-send-email-yong.wu@mediatek.com>

This patch is for ARM Short Descriptor Format.

Signed-off-by: Yong Wu <yong.wu at mediatek.com>
---
 drivers/iommu/Kconfig                |  18 +
 drivers/iommu/Makefile               |   1 +
 drivers/iommu/io-pgtable-arm-short.c | 813 +++++++++++++++++++++++++++++++++++
 drivers/iommu/io-pgtable-arm.c       |   3 -
 drivers/iommu/io-pgtable.c           |   4 +
 drivers/iommu/io-pgtable.h           |  14 +
 6 files changed, 850 insertions(+), 3 deletions(-)
 create mode 100644 drivers/iommu/io-pgtable-arm-short.c

diff --git a/drivers/iommu/Kconfig b/drivers/iommu/Kconfig
index f1fb1d3..3abd066 100644
--- a/drivers/iommu/Kconfig
+++ b/drivers/iommu/Kconfig
@@ -39,6 +39,24 @@ config IOMMU_IO_PGTABLE_LPAE_SELFTEST
 
 	  If unsure, say N here.
 
+config IOMMU_IO_PGTABLE_SHORT
+	bool "ARMv7/v8 Short Descriptor Format"
+	select IOMMU_IO_PGTABLE
+	depends on ARM || ARM64 || COMPILE_TEST
+	help
+	  Enable support for the ARM Short-descriptor pagetable format.
+	  This allocator supports 2 levels translation tables which supports
+	  a memory map based on memory sections or pages.
+
+config IOMMU_IO_PGTABLE_SHORT_SELFTEST
+	bool "Short Descriptor selftests"
+	depends on IOMMU_IO_PGTABLE_SHORT
+	help
+	  Enable self-tests for Short-descriptor page table allocator.
+	  This performs a series of page-table consistency checks during boot.
+
+	  If unsure, say N here.
+
 endmenu
 
 config IOMMU_IOVA
diff --git a/drivers/iommu/Makefile b/drivers/iommu/Makefile
index c6dcc51..06df3e6 100644
--- a/drivers/iommu/Makefile
+++ b/drivers/iommu/Makefile
@@ -3,6 +3,7 @@ obj-$(CONFIG_IOMMU_API) += iommu-traces.o
 obj-$(CONFIG_IOMMU_API) += iommu-sysfs.o
 obj-$(CONFIG_IOMMU_IO_PGTABLE) += io-pgtable.o
 obj-$(CONFIG_IOMMU_IO_PGTABLE_LPAE) += io-pgtable-arm.o
+obj-$(CONFIG_IOMMU_IO_PGTABLE_SHORT) += io-pgtable-arm-short.o
 obj-$(CONFIG_IOMMU_IOVA) += iova.o
 obj-$(CONFIG_OF_IOMMU)	+= of_iommu.o
 obj-$(CONFIG_MSM_IOMMU) += msm_iommu.o msm_iommu_dev.o
diff --git a/drivers/iommu/io-pgtable-arm-short.c b/drivers/iommu/io-pgtable-arm-short.c
new file mode 100644
index 0000000..56f5480
--- /dev/null
+++ b/drivers/iommu/io-pgtable-arm-short.c
@@ -0,0 +1,813 @@
+/*
+ * Copyright (c) 2014-2015 MediaTek Inc.
+ * Author: Yong Wu <yong.wu at 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.
+ */
+#define pr_fmt(fmt)	"arm-short-desc io-pgtable: "fmt
+
+#include <linux/err.h>
+#include <linux/slab.h>
+#include <linux/iommu.h>
+#include <linux/errno.h>
+#include "io-pgtable.h"
+
+typedef u32 arm_short_iopte;
+
+struct arm_short_io_pgtable {
+	struct io_pgtable	iop;
+	struct kmem_cache	*pgtable_cached;
+	size_t			pgd_size;
+	void			*pgd;
+};
+
+#define io_pgtable_to_data(x)			\
+	container_of((x), struct arm_short_io_pgtable, iop)
+
+#define io_pgtable_ops_to_data(x)		\
+	io_pgtable_to_data(io_pgtable_ops_to_pgtable(x))
+
+#define io_pgtable_cfg_to_pgtable(x)		\
+	container_of((x), struct io_pgtable, cfg)
+
+#define io_pgtable_cfg_to_data(x)		\
+	io_pgtable_to_data(io_pgtable_cfg_to_pgtable(x))
+
+#define ARM_SHORT_PGDIR_SHIFT			20
+#define ARM_SHORT_PAGE_SHIFT			12
+#define ARM_SHORT_PTRS_PER_PTE			\
+	(1 << (ARM_SHORT_PGDIR_SHIFT - ARM_SHORT_PAGE_SHIFT))
+#define ARM_SHORT_BYTES_PER_PTE			\
+	(ARM_SHORT_PTRS_PER_PTE * sizeof(arm_short_iopte))
+
+/* level 1 pagetable */
+#define ARM_SHORT_PGD_TYPE_PGTABLE		BIT(0)
+#define ARM_SHORT_PGD_TYPE_SECTION		BIT(1)
+#define ARM_SHORT_PGD_B				BIT(2)
+#define ARM_SHORT_PGD_C				BIT(3)
+#define ARM_SHORT_PGD_PGTABLE_NS		BIT(3)
+#define ARM_SHORT_PGD_SECTION_XN		BIT(4)
+#define ARM_SHORT_PGD_IMPLE			BIT(9)
+#define ARM_SHORT_PGD_RD_WR			(3 << 10)
+#define ARM_SHORT_PGD_RDONLY			BIT(15)
+#define ARM_SHORT_PGD_S				BIT(16)
+#define ARM_SHORT_PGD_nG			BIT(17)
+#define ARM_SHORT_PGD_SUPERSECTION		BIT(18)
+#define ARM_SHORT_PGD_SECTION_NS		BIT(19)
+
+#define ARM_SHORT_PGD_TYPE_SUPERSECTION		\
+	(ARM_SHORT_PGD_TYPE_SECTION | ARM_SHORT_PGD_SUPERSECTION)
+#define ARM_SHORT_PGD_SECTION_TYPE_MSK		\
+	(ARM_SHORT_PGD_TYPE_SECTION | ARM_SHORT_PGD_SUPERSECTION)
+#define ARM_SHORT_PGD_PGTABLE_TYPE_MSK		\
+	(ARM_SHORT_PGD_TYPE_SECTION | ARM_SHORT_PGD_TYPE_PGTABLE)
+#define ARM_SHORT_PGD_TYPE_IS_PGTABLE(pgd)	\
+	(((pgd) & ARM_SHORT_PGD_PGTABLE_TYPE_MSK) == ARM_SHORT_PGD_TYPE_PGTABLE)
+#define ARM_SHORT_PGD_TYPE_IS_SECTION(pgd)	\
+	(((pgd) & ARM_SHORT_PGD_SECTION_TYPE_MSK) == ARM_SHORT_PGD_TYPE_SECTION)
+#define ARM_SHORT_PGD_TYPE_IS_SUPERSECTION(pgd)	\
+	(((pgd) & ARM_SHORT_PGD_SECTION_TYPE_MSK) == \
+	ARM_SHORT_PGD_TYPE_SUPERSECTION)
+#define ARM_SHORT_PGD_PGTABLE_MSK		0xfffffc00
+#define ARM_SHORT_PGD_SECTION_MSK		(~(SZ_1M - 1))
+#define ARM_SHORT_PGD_SUPERSECTION_MSK		(~(SZ_16M - 1))
+
+/* level 2 pagetable */
+#define ARM_SHORT_PTE_TYPE_LARGE		BIT(0)
+#define ARM_SHORT_PTE_SMALL_XN			BIT(0)
+#define ARM_SHORT_PTE_TYPE_SMALL		BIT(1)
+#define ARM_SHORT_PTE_B				BIT(2)
+#define ARM_SHORT_PTE_C				BIT(3)
+#define ARM_SHORT_PTE_RD_WR			(3 << 4)
+#define ARM_SHORT_PTE_RDONLY			BIT(9)
+#define ARM_SHORT_PTE_S				BIT(10)
+#define ARM_SHORT_PTE_nG			BIT(11)
+#define ARM_SHORT_PTE_LARGE_XN			BIT(15)
+#define ARM_SHORT_PTE_LARGE_MSK			(~(SZ_64K - 1))
+#define ARM_SHORT_PTE_SMALL_MSK			(~(SZ_4K - 1))
+#define ARM_SHORT_PTE_TYPE_MSK			\
+	(ARM_SHORT_PTE_TYPE_LARGE | ARM_SHORT_PTE_TYPE_SMALL)
+#define ARM_SHORT_PTE_TYPE_IS_SMALLPAGE(pte)	\
+	(((pte) & ARM_SHORT_PTE_TYPE_SMALL) == ARM_SHORT_PTE_TYPE_SMALL)
+#define ARM_SHORT_PTE_TYPE_IS_LARGEPAGE(pte)	\
+	(((pte) & ARM_SHORT_PTE_TYPE_MSK) == ARM_SHORT_PTE_TYPE_LARGE)
+
+#define ARM_SHORT_PGD_IDX(a)			((a) >> ARM_SHORT_PGDIR_SHIFT)
+#define ARM_SHORT_PTE_IDX(a)			\
+	(((a) >> ARM_SHORT_PAGE_SHIFT) & (ARM_SHORT_PTRS_PER_PTE - 1))
+
+#define ARM_SHORT_GET_PGTABLE_VA(pgd)		\
+	(phys_to_virt((unsigned long)pgd & ARM_SHORT_PGD_PGTABLE_MSK))
+
+#define ARM_SHORT_PTE_LARGE_GET_PROT(pte)	\
+	(((pte) & (~ARM_SHORT_PTE_LARGE_MSK)) & ~ARM_SHORT_PTE_TYPE_MSK)
+
+#define ARM_SHORT_PGD_GET_PROT(pgd)		\
+	(((pgd) & (~ARM_SHORT_PGD_SECTION_MSK)) & ~ARM_SHORT_PGD_SUPERSECTION)
+
+static bool selftest_running;
+
+static arm_short_iopte *
+arm_short_get_pte_in_pgd(arm_short_iopte pgd, unsigned int iova)
+{
+	arm_short_iopte *pte;
+
+	pte = ARM_SHORT_GET_PGTABLE_VA(pgd);
+	pte += ARM_SHORT_PTE_IDX(iova);
+	return pte;
+}
+
+static dma_addr_t
+__arm_short_dma_addr(struct device *dev, void *va)
+{
+	return phys_to_dma(dev, virt_to_phys(va));
+}
+
+static int
+__arm_short_set_pte(arm_short_iopte *ptep, arm_short_iopte pte,
+		    unsigned int ptenr, struct io_pgtable_cfg *cfg)
+{
+	struct device *dev = cfg->iommu_dev;
+	int i;
+
+	for (i = 0; i < ptenr; i++) {
+		if (ptep[i] && pte) {
+			/* Someone else may have allocated for this pte */
+			WARN_ON(!selftest_running);
+			goto err_exist_pte;
+		}
+		ptep[i] = pte;
+	}
+
+	if (selftest_running)
+		return 0;
+
+	dma_sync_single_for_device(dev, __arm_short_dma_addr(dev, ptep),
+				   sizeof(*ptep) * ptenr, DMA_TO_DEVICE);
+	return 0;
+
+err_exist_pte:
+	while (i--)
+		ptep[i] = 0;
+	return -EEXIST;
+}
+
+static void *
+__arm_short_alloc_pgtable(size_t size, gfp_t gfp, bool pgd,
+			  struct io_pgtable_cfg *cfg)
+{
+	struct arm_short_io_pgtable *data;
+	struct device *dev = cfg->iommu_dev;
+	dma_addr_t dma;
+	void *va;
+
+	if (pgd) {/* lvl1 pagetable */
+		va = alloc_pages_exact(size, gfp);
+	} else {  /* lvl2 pagetable */
+		data = io_pgtable_cfg_to_data(cfg);
+		va = kmem_cache_zalloc(data->pgtable_cached, gfp);
+	}
+
+	if (!va)
+		return NULL;
+
+	if (selftest_running)
+		return va;
+
+	dma = dma_map_single(dev, va, size, DMA_TO_DEVICE);
+	if (dma_mapping_error(dev, dma))
+		goto out_free;
+
+	if (dma != __arm_short_dma_addr(dev, va))
+		goto out_unmap;
+
+	if (!pgd) {
+		kmemleak_ignore(va);
+		dma_sync_single_for_device(dev, __arm_short_dma_addr(dev, va),
+					   size, DMA_TO_DEVICE);
+	}
+
+	return va;
+
+out_unmap:
+	dev_err_ratelimited(dev, "Cannot accommodate DMA translation for IOMMU page tables\n");
+	dma_unmap_single(dev, dma, size, DMA_TO_DEVICE);
+out_free:
+	if (pgd)
+		free_pages_exact(va, size);
+	else
+		kmem_cache_free(data->pgtable_cached, va);
+	return NULL;
+}
+
+static void
+__arm_short_free_pgtable(void *va, size_t size, bool pgd,
+			 struct io_pgtable_cfg *cfg)
+{
+	struct arm_short_io_pgtable *data = io_pgtable_cfg_to_data(cfg);
+	struct device *dev = cfg->iommu_dev;
+
+	if (!selftest_running)
+		dma_unmap_single(dev, __arm_short_dma_addr(dev, va),
+				 size, DMA_TO_DEVICE);
+
+	if (pgd)
+		free_pages_exact(va, size);
+	else
+		kmem_cache_free(data->pgtable_cached, va);
+}
+
+static arm_short_iopte
+__arm_short_pte_prot(struct arm_short_io_pgtable *data, int prot, bool large)
+{
+	arm_short_iopte pteprot;
+	int quirk = data->iop.cfg.quirks;
+
+	pteprot = ARM_SHORT_PTE_S | ARM_SHORT_PTE_nG;
+	pteprot |= large ? ARM_SHORT_PTE_TYPE_LARGE :
+				ARM_SHORT_PTE_TYPE_SMALL;
+	if (prot & IOMMU_CACHE)
+		pteprot |=  ARM_SHORT_PTE_B | ARM_SHORT_PTE_C;
+	if (!(quirk & IO_PGTABLE_QUIRK_SHORT_NO_XN) && (prot & IOMMU_NOEXEC)) {
+			pteprot |= large ? ARM_SHORT_PTE_LARGE_XN :
+				ARM_SHORT_PTE_SMALL_XN;
+	}
+	if (!(quirk & IO_PGTABLE_QUIRK_SHORT_NO_PERMS)) {
+		pteprot |= ARM_SHORT_PTE_RD_WR;
+		if (!(prot & IOMMU_WRITE) && (prot & IOMMU_READ))
+			pteprot |= ARM_SHORT_PTE_RDONLY;
+	}
+	return pteprot;
+}
+
+static arm_short_iopte
+__arm_short_pgd_prot(struct arm_short_io_pgtable *data, int prot, bool super)
+{
+	arm_short_iopte pgdprot;
+	int quirk = data->iop.cfg.quirks;
+
+	pgdprot = ARM_SHORT_PGD_S | ARM_SHORT_PGD_nG;
+	pgdprot |= super ? ARM_SHORT_PGD_TYPE_SUPERSECTION :
+				ARM_SHORT_PGD_TYPE_SECTION;
+	if (prot & IOMMU_CACHE)
+		pgdprot |= ARM_SHORT_PGD_C | ARM_SHORT_PGD_B;
+	if (quirk & IO_PGTABLE_QUIRK_ARM_NS)
+		pgdprot |= ARM_SHORT_PGD_SECTION_NS;
+
+	if (!(quirk & IO_PGTABLE_QUIRK_SHORT_NO_XN) && (prot & IOMMU_NOEXEC))
+			pgdprot |= ARM_SHORT_PGD_SECTION_XN;
+
+	if (!(quirk & IO_PGTABLE_QUIRK_SHORT_NO_PERMS)) {
+		pgdprot |= ARM_SHORT_PGD_RD_WR;
+		if (!(prot & IOMMU_WRITE) && (prot & IOMMU_READ))
+			pgdprot |= ARM_SHORT_PGD_RDONLY;
+	}
+	return pgdprot;
+}
+
+static arm_short_iopte
+__arm_short_pte_prot_split(struct arm_short_io_pgtable *data,
+			   arm_short_iopte pgdprot,
+			   arm_short_iopte pteprot_large,
+			   bool large)
+{
+	arm_short_iopte pteprot = 0;
+
+	pteprot = ARM_SHORT_PTE_S | ARM_SHORT_PTE_nG | ARM_SHORT_PTE_RD_WR;
+	pteprot |= large ? ARM_SHORT_PTE_TYPE_LARGE :
+				ARM_SHORT_PTE_TYPE_SMALL;
+
+	/* large page to small page pte prot. Only large page may split */
+	if (!pgdprot && !large) {
+		pteprot |= pteprot_large & ~ARM_SHORT_PTE_SMALL_MSK;
+		if (pteprot_large & ARM_SHORT_PTE_LARGE_XN)
+			pteprot |= ARM_SHORT_PTE_SMALL_XN;
+	}
+
+	/* section to pte prot */
+	if (pgdprot & ARM_SHORT_PGD_C)
+		pteprot |= ARM_SHORT_PTE_C;
+	if (pgdprot & ARM_SHORT_PGD_B)
+		pteprot |= ARM_SHORT_PTE_B;
+	if (pgdprot & ARM_SHORT_PGD_nG)
+		pteprot |= ARM_SHORT_PTE_nG;
+	if (pgdprot & ARM_SHORT_PGD_SECTION_XN)
+		pteprot |= large ? ARM_SHORT_PTE_LARGE_XN :
+				ARM_SHORT_PTE_SMALL_XN;
+	if (pgdprot & ARM_SHORT_PGD_RD_WR)
+		pteprot |= ARM_SHORT_PTE_RD_WR;
+	if (pgdprot & ARM_SHORT_PGD_RDONLY)
+		pteprot |= ARM_SHORT_PTE_RDONLY;
+
+	return pteprot;
+}
+
+static arm_short_iopte
+__arm_short_pgtable_prot(struct arm_short_io_pgtable *data)
+{
+	arm_short_iopte pgdprot = 0;
+
+	pgdprot = ARM_SHORT_PGD_TYPE_PGTABLE;
+	if (data->iop.cfg.quirks & IO_PGTABLE_QUIRK_ARM_NS)
+		pgdprot |= ARM_SHORT_PGD_PGTABLE_NS;
+	return pgdprot;
+}
+
+static int
+_arm_short_map(struct arm_short_io_pgtable *data,
+	       unsigned int iova, phys_addr_t paddr,
+	       arm_short_iopte pgdprot, arm_short_iopte pteprot,
+	       bool large)
+{
+	struct io_pgtable_cfg *cfg = &data->iop.cfg;
+	arm_short_iopte *pgd = data->pgd, *pte;
+	void *pte_new = NULL;
+	int ret;
+
+	pgd += ARM_SHORT_PGD_IDX(iova);
+
+	if (!pteprot) { /* section or supersection */
+		pte = pgd;
+		pteprot = pgdprot;
+	} else {        /* page or largepage */
+		if (!(*pgd)) {
+			pte_new = __arm_short_alloc_pgtable(
+					ARM_SHORT_BYTES_PER_PTE,
+					GFP_ATOMIC, false, cfg);
+			if (unlikely(!pte_new))
+				return -ENOMEM;
+
+			pgdprot |= virt_to_phys(pte_new);
+			__arm_short_set_pte(pgd, pgdprot, 1, cfg);
+		}
+		pte = arm_short_get_pte_in_pgd(*pgd, iova);
+	}
+
+	pteprot |= (arm_short_iopte)paddr;
+	ret = __arm_short_set_pte(pte, pteprot, large ? 16 : 1, cfg);
+	if (ret && pte_new)
+		__arm_short_free_pgtable(pte_new, ARM_SHORT_BYTES_PER_PTE,
+					 false, cfg);
+	return ret;
+}
+
+static int arm_short_map(struct io_pgtable_ops *ops, unsigned long iova,
+			 phys_addr_t paddr, size_t size, int prot)
+{
+	struct arm_short_io_pgtable *data = io_pgtable_ops_to_data(ops);
+	arm_short_iopte pgdprot = 0, pteprot = 0;
+	bool large;
+
+	/* If no access, then nothing to do */
+	if (!(prot & (IOMMU_READ | IOMMU_WRITE)))
+		return 0;
+
+	if (WARN_ON((iova | paddr) & (size - 1)))
+		return -EINVAL;
+
+	switch (size) {
+	case SZ_4K:
+	case SZ_64K:
+		large = (size == SZ_64K) ? true : false;
+		pteprot = __arm_short_pte_prot(data, prot, large);
+		pgdprot = __arm_short_pgtable_prot(data);
+		break;
+
+	case SZ_1M:
+	case SZ_16M:
+		large = (size == SZ_16M) ? true : false;
+		pgdprot = __arm_short_pgd_prot(data, prot, large);
+		break;
+	default:
+		return -EINVAL;
+	}
+
+	return _arm_short_map(data, iova, paddr, pgdprot, pteprot, large);
+}
+
+static phys_addr_t arm_short_iova_to_phys(struct io_pgtable_ops *ops,
+					  unsigned long iova)
+{
+	struct arm_short_io_pgtable *data = io_pgtable_ops_to_data(ops);
+	arm_short_iopte *pte, *pgd = data->pgd;
+	phys_addr_t pa = 0;
+
+	pgd += ARM_SHORT_PGD_IDX(iova);
+
+	if (ARM_SHORT_PGD_TYPE_IS_PGTABLE(*pgd)) {
+		pte = arm_short_get_pte_in_pgd(*pgd, iova);
+
+		if (ARM_SHORT_PTE_TYPE_IS_LARGEPAGE(*pte)) {
+			pa = (*pte) & ARM_SHORT_PTE_LARGE_MSK;
+			pa |= iova & ~ARM_SHORT_PTE_LARGE_MSK;
+		} else if (ARM_SHORT_PTE_TYPE_IS_SMALLPAGE(*pte)) {
+			pa = (*pte) & ARM_SHORT_PTE_SMALL_MSK;
+			pa |= iova & ~ARM_SHORT_PTE_SMALL_MSK;
+		}
+	} else if (ARM_SHORT_PGD_TYPE_IS_SECTION(*pgd)) {
+		pa = (*pgd) & ARM_SHORT_PGD_SECTION_MSK;
+		pa |= iova & ~ARM_SHORT_PGD_SECTION_MSK;
+	} else if (ARM_SHORT_PGD_TYPE_IS_SUPERSECTION(*pgd)) {
+		pa = (*pgd) & ARM_SHORT_PGD_SUPERSECTION_MSK;
+		pa |= iova & ~ARM_SHORT_PGD_SUPERSECTION_MSK;
+	}
+
+	return pa;
+}
+
+static bool _arm_short_whether_free_pgtable(arm_short_iopte *pgd)
+{
+	arm_short_iopte *pte;
+	int i;
+
+	pte = ARM_SHORT_GET_PGTABLE_VA(*pgd);
+	for (i = 0; i < ARM_SHORT_PTRS_PER_PTE; i++) {
+		if (pte[i] != 0)
+			return false;
+	}
+
+	return true;
+}
+
+static int
+arm_short_split_blk_unmap(struct io_pgtable_ops *ops, unsigned int iova,
+			  phys_addr_t paddr, size_t size,
+			  arm_short_iopte pgdprotup, arm_short_iopte pteprotup,
+			  size_t blk_size)
+{
+	struct arm_short_io_pgtable *data = io_pgtable_ops_to_data(ops);
+	const struct iommu_gather_ops *tlb = data->iop.cfg.tlb;
+	struct io_pgtable_cfg *cfg = &data->iop.cfg;
+	unsigned long *pgbitmap = &cfg->pgsize_bitmap;
+	unsigned int blk_base, blk_start, blk_end, i;
+	arm_short_iopte pgdprot, pteprot;
+	phys_addr_t blk_paddr;
+	size_t mapsize = 0, nextmapsize;
+	int ret;
+
+	/* find the nearest mapsize */
+	for (i = find_first_bit(pgbitmap, BITS_PER_LONG);
+	     i < BITS_PER_LONG && ((1 << i) < blk_size) &&
+	     IS_ALIGNED(size, 1 << i);
+	     i = find_next_bit(pgbitmap, BITS_PER_LONG, i + 1))
+		mapsize = 1 << i;
+
+	if (WARN_ON(!mapsize))
+		return 0; /* Bytes unmapped */
+	nextmapsize = 1 << i;
+
+	blk_base = iova & ~(blk_size - 1);
+	blk_start = blk_base;
+	blk_end = blk_start + blk_size;
+	blk_paddr = paddr;
+
+	for (; blk_start < blk_end;
+	     blk_start += mapsize, blk_paddr += mapsize) {
+		/* Unmap! */
+		if (blk_start == iova)
+			continue;
+
+		/* Try to upper map */
+		if (blk_base != blk_start &&
+		    IS_ALIGNED(blk_start | blk_paddr, nextmapsize) &&
+		    mapsize != nextmapsize) {
+			mapsize = nextmapsize;
+			i = find_next_bit(pgbitmap, BITS_PER_LONG, i + 1);
+			if (i < BITS_PER_LONG)
+				nextmapsize = 1 << i;
+		}
+
+		if (mapsize == SZ_1M) {
+			pgdprot = pgdprotup;
+			pgdprot |= __arm_short_pgd_prot(data, 0, false);
+			pteprot = 0;
+		} else { /* small or large page */
+			pgdprot = (blk_size == SZ_64K) ? 0 : pgdprotup;
+			pteprot = __arm_short_pte_prot_split(
+					data, pgdprot, pteprotup,
+					mapsize == SZ_64K);
+			pgdprot = __arm_short_pgtable_prot(data);
+		}
+
+		ret = _arm_short_map(data, blk_start, blk_paddr, pgdprot,
+				     pteprot, mapsize == SZ_64K);
+		if (ret < 0) {
+			/* Free the table we allocated */
+			arm_short_iopte *pgd = data->pgd, *pte;
+
+			pgd += ARM_SHORT_PGD_IDX(blk_base);
+			if (*pgd) {
+				pte = ARM_SHORT_GET_PGTABLE_VA(*pgd);
+				__arm_short_set_pte(pgd, 0, 1, cfg);
+				tlb->tlb_add_flush(blk_base, blk_size, true,
+						   data->iop.cookie);
+				tlb->tlb_sync(data->iop.cookie);
+				__arm_short_free_pgtable(
+					pte, ARM_SHORT_BYTES_PER_PTE,
+					false, cfg);
+			}
+			return 0;/* Bytes unmapped */
+		}
+	}
+
+	tlb->tlb_add_flush(blk_base, blk_size, true, data->iop.cookie);
+	tlb->tlb_sync(data->iop.cookie);
+	return size;
+}
+
+static int arm_short_unmap(struct io_pgtable_ops *ops,
+			   unsigned long iova,
+			   size_t size)
+{
+	struct arm_short_io_pgtable *data = io_pgtable_ops_to_data(ops);
+	struct io_pgtable_cfg *cfg = &data->iop.cfg;
+	arm_short_iopte *pgd, *pte = NULL;
+	arm_short_iopte curpgd, curpte = 0;
+	phys_addr_t paddr;
+	unsigned int iova_base, blk_size = 0;
+	void *cookie = data->iop.cookie;
+	bool pgtablefree = false;
+
+	pgd = (arm_short_iopte *)data->pgd + ARM_SHORT_PGD_IDX(iova);
+
+	/* Get block size */
+	if (ARM_SHORT_PGD_TYPE_IS_PGTABLE(*pgd)) {
+		pte = arm_short_get_pte_in_pgd(*pgd, iova);
+
+		if (ARM_SHORT_PTE_TYPE_IS_SMALLPAGE(*pte))
+			blk_size = SZ_4K;
+		else if (ARM_SHORT_PTE_TYPE_IS_LARGEPAGE(*pte))
+			blk_size = SZ_64K;
+		else
+			WARN_ON(1);
+	} else if (ARM_SHORT_PGD_TYPE_IS_SECTION(*pgd)) {
+		blk_size = SZ_1M;
+	} else if (ARM_SHORT_PGD_TYPE_IS_SUPERSECTION(*pgd)) {
+		blk_size = SZ_16M;
+	} else {
+		WARN_ON(1);
+	}
+
+	iova_base = iova & ~(blk_size - 1);
+	pgd = (arm_short_iopte *)data->pgd + ARM_SHORT_PGD_IDX(iova_base);
+	paddr = arm_short_iova_to_phys(ops, iova_base);
+	curpgd = *pgd;
+
+	if (blk_size == SZ_4K || blk_size == SZ_64K) {
+		pte = arm_short_get_pte_in_pgd(*pgd, iova_base);
+		curpte = *pte;
+		__arm_short_set_pte(pte, 0, blk_size / SZ_4K, cfg);
+
+		pgtablefree = _arm_short_whether_free_pgtable(pgd);
+		if (pgtablefree)
+			__arm_short_set_pte(pgd, 0, 1, cfg);
+	} else if (blk_size == SZ_1M || blk_size == SZ_16M) {
+		__arm_short_set_pte(pgd, 0, blk_size / SZ_1M, cfg);
+	}
+
+	cfg->tlb->tlb_add_flush(iova_base, blk_size, true, cookie);
+	cfg->tlb->tlb_sync(cookie);
+
+	if (pgtablefree)/* Free pgtable after tlb-flush */
+		__arm_short_free_pgtable(ARM_SHORT_GET_PGTABLE_VA(curpgd),
+					 ARM_SHORT_BYTES_PER_PTE, false, cfg);
+
+	if (blk_size > size) { /* Split the block */
+		return arm_short_split_blk_unmap(
+				ops, iova, paddr, size,
+				ARM_SHORT_PGD_GET_PROT(curpgd),
+				ARM_SHORT_PTE_LARGE_GET_PROT(curpte),
+				blk_size);
+	} else if (blk_size < size) {
+		/* Unmap the block while remap partial again after split */
+		return blk_size +
+			arm_short_unmap(ops, iova + blk_size, size - blk_size);
+	}
+
+	return size;
+}
+
+static struct io_pgtable *
+arm_short_alloc_pgtable(struct io_pgtable_cfg *cfg, void *cookie)
+{
+	struct arm_short_io_pgtable *data;
+
+	if (cfg->ias > 32 || cfg->oas > 32)
+		return NULL;
+
+	cfg->pgsize_bitmap &=
+		(cfg->quirks & IO_PGTABLE_QUIRK_SHORT_SUPERSECTION) ?
+		(SZ_4K | SZ_64K | SZ_1M | SZ_16M) : (SZ_4K | SZ_64K | SZ_1M);
+
+	data = kzalloc(sizeof(*data), GFP_KERNEL);
+	if (!data)
+		return NULL;
+
+	data->pgd_size = SZ_16K;
+	data->pgd = __arm_short_alloc_pgtable(
+					data->pgd_size,
+					GFP_KERNEL | __GFP_ZERO | __GFP_DMA,
+					true, cfg);
+	if (!data->pgd)
+		goto out_free_data;
+	wmb();/* Ensure the empty pgd is visible before any actual TTBR write */
+
+	data->pgtable_cached = kmem_cache_create(
+					"io-pgtable-arm-short",
+					 ARM_SHORT_BYTES_PER_PTE,
+					 ARM_SHORT_BYTES_PER_PTE,
+					 0, NULL);
+	if (!data->pgtable_cached)
+		goto out_free_pgd;
+
+	/* TTBRs */
+	cfg->arm_short_cfg.ttbr[0] = virt_to_phys(data->pgd);
+	cfg->arm_short_cfg.ttbr[1] = 0;
+	cfg->arm_short_cfg.tcr = 0;
+	cfg->arm_short_cfg.nmrr = 0;
+	cfg->arm_short_cfg.prrr = 0;
+
+	data->iop.ops = (struct io_pgtable_ops) {
+		.map		= arm_short_map,
+		.unmap		= arm_short_unmap,
+		.iova_to_phys	= arm_short_iova_to_phys,
+	};
+
+	return &data->iop;
+
+out_free_pgd:
+	__arm_short_free_pgtable(data->pgd, data->pgd_size, true, cfg);
+out_free_data:
+	kfree(data);
+	return NULL;
+}
+
+static void arm_short_free_pgtable(struct io_pgtable *iop)
+{
+	struct arm_short_io_pgtable *data = io_pgtable_to_data(iop);
+
+	kmem_cache_destroy(data->pgtable_cached);
+	__arm_short_free_pgtable(data->pgd, data->pgd_size,
+				 true, &data->iop.cfg);
+	kfree(data);
+}
+
+struct io_pgtable_init_fns io_pgtable_arm_short_init_fns = {
+	.alloc	= arm_short_alloc_pgtable,
+	.free	= arm_short_free_pgtable,
+};
+
+#ifdef CONFIG_IOMMU_IO_PGTABLE_SHORT_SELFTEST
+
+static struct io_pgtable_cfg *cfg_cookie;
+
+static void dummy_tlb_flush_all(void *cookie)
+{
+	WARN_ON(cookie != cfg_cookie);
+}
+
+static void dummy_tlb_add_flush(unsigned long iova, size_t size, bool leaf,
+				void *cookie)
+{
+	WARN_ON(cookie != cfg_cookie);
+	WARN_ON(!(size & cfg_cookie->pgsize_bitmap));
+}
+
+static void dummy_tlb_sync(void *cookie)
+{
+	WARN_ON(cookie != cfg_cookie);
+}
+
+static struct iommu_gather_ops dummy_tlb_ops = {
+	.tlb_flush_all	= dummy_tlb_flush_all,
+	.tlb_add_flush	= dummy_tlb_add_flush,
+	.tlb_sync	= dummy_tlb_sync,
+};
+
+#define __FAIL(ops)	({				\
+		WARN(1, "selftest: test failed\n");	\
+		selftest_running = false;		\
+		-EFAULT;				\
+})
+
+static int __init arm_short_do_selftests(void)
+{
+	struct io_pgtable_ops *ops;
+	struct io_pgtable_cfg cfg = {
+		.tlb = &dummy_tlb_ops,
+		.oas = 32,
+		.ias = 32,
+		.quirks = IO_PGTABLE_QUIRK_ARM_NS |
+			IO_PGTABLE_QUIRK_SHORT_SUPERSECTION,
+		.pgsize_bitmap = SZ_4K | SZ_64K | SZ_1M | SZ_16M,
+	};
+	unsigned int iova, size, iova_start;
+	unsigned int i, loopnr = 0;
+
+	selftest_running = true;
+
+	cfg_cookie = &cfg;
+
+	ops = alloc_io_pgtable_ops(ARM_SHORT_DESC, &cfg, &cfg);
+	if (!ops) {
+		pr_err("Failed to alloc short desc io pgtable\n");
+		return -EINVAL;
+	}
+
+	/*
+	 * Initial sanity checks.
+	 * Empty page tables shouldn't provide any translations.
+	 */
+	if (ops->iova_to_phys(ops, 42))
+		return __FAIL(ops);
+
+	if (ops->iova_to_phys(ops, SZ_1G + 42))
+		return __FAIL(ops);
+
+	if (ops->iova_to_phys(ops, SZ_2G + 42))
+		return __FAIL(ops);
+
+	/*
+	 * Distinct mappings of different granule sizes.
+	 */
+	iova = 0;
+	i = find_first_bit(&cfg.pgsize_bitmap, BITS_PER_LONG);
+	while (i != BITS_PER_LONG) {
+		size = 1UL << i;
+		if (ops->map(ops, iova, iova, size, IOMMU_READ |
+						    IOMMU_WRITE |
+						    IOMMU_NOEXEC |
+						    IOMMU_CACHE))
+			return __FAIL(ops);
+
+		/* Overlapping mappings */
+		if (!ops->map(ops, iova, iova + size, size,
+			      IOMMU_READ | IOMMU_NOEXEC))
+			return __FAIL(ops);
+
+		if (ops->iova_to_phys(ops, iova + 42) != (iova + 42))
+			return __FAIL(ops);
+
+		iova += SZ_16M;
+		i++;
+		i = find_next_bit(&cfg.pgsize_bitmap, BITS_PER_LONG, i);
+		loopnr++;
+	}
+
+	/* Partial unmap */
+	i = 1;
+	size = 1UL << __ffs(cfg.pgsize_bitmap);
+	while (i < loopnr) {
+		iova_start = i * SZ_16M;
+		if (ops->unmap(ops, iova_start + size, size) != size)
+			return __FAIL(ops);
+
+		/* Remap of partial unmap */
+		if (ops->map(ops, iova_start + size, size, size, IOMMU_READ))
+			return __FAIL(ops);
+
+		if (ops->iova_to_phys(ops, iova_start + size + 42)
+		    != (size + 42))
+			return __FAIL(ops);
+		i++;
+	}
+
+	/* Full unmap */
+	iova = 0;
+	i = find_first_bit(&cfg.pgsize_bitmap, BITS_PER_LONG);
+	while (i != BITS_PER_LONG) {
+		size = 1UL << i;
+
+		if (ops->unmap(ops, iova, size) != size)
+			return __FAIL(ops);
+
+		if (ops->iova_to_phys(ops, iova + 42))
+			return __FAIL(ops);
+
+		/* Remap full block */
+		if (ops->map(ops, iova, iova, size, IOMMU_WRITE))
+			return __FAIL(ops);
+
+		if (ops->iova_to_phys(ops, iova + 42) != (iova + 42))
+			return __FAIL(ops);
+
+		iova += SZ_16M;
+		i++;
+		i = find_next_bit(&cfg.pgsize_bitmap, BITS_PER_LONG, i);
+	}
+
+	free_io_pgtable_ops(ops);
+
+	selftest_running = false;
+	return 0;
+}
+
+subsys_initcall(arm_short_do_selftests);
+#endif
diff --git a/drivers/iommu/io-pgtable-arm.c b/drivers/iommu/io-pgtable-arm.c
index e4bc2b2..9978eca 100644
--- a/drivers/iommu/io-pgtable-arm.c
+++ b/drivers/iommu/io-pgtable-arm.c
@@ -38,9 +38,6 @@
 #define io_pgtable_to_data(x)						\
 	container_of((x), struct arm_lpae_io_pgtable, iop)
 
-#define io_pgtable_ops_to_pgtable(x)					\
-	container_of((x), struct io_pgtable, ops)
-
 #define io_pgtable_ops_to_data(x)					\
 	io_pgtable_to_data(io_pgtable_ops_to_pgtable(x))
 
diff --git a/drivers/iommu/io-pgtable.c b/drivers/iommu/io-pgtable.c
index 6436fe2..14a9b3a 100644
--- a/drivers/iommu/io-pgtable.c
+++ b/drivers/iommu/io-pgtable.c
@@ -28,6 +28,7 @@ extern struct io_pgtable_init_fns io_pgtable_arm_32_lpae_s1_init_fns;
 extern struct io_pgtable_init_fns io_pgtable_arm_32_lpae_s2_init_fns;
 extern struct io_pgtable_init_fns io_pgtable_arm_64_lpae_s1_init_fns;
 extern struct io_pgtable_init_fns io_pgtable_arm_64_lpae_s2_init_fns;
+extern struct io_pgtable_init_fns io_pgtable_arm_short_init_fns;
 
 static const struct io_pgtable_init_fns *
 io_pgtable_init_table[IO_PGTABLE_NUM_FMTS] =
@@ -38,6 +39,9 @@ io_pgtable_init_table[IO_PGTABLE_NUM_FMTS] =
 	[ARM_64_LPAE_S1] = &io_pgtable_arm_64_lpae_s1_init_fns,
 	[ARM_64_LPAE_S2] = &io_pgtable_arm_64_lpae_s2_init_fns,
 #endif
+#ifdef CONFIG_IOMMU_IO_PGTABLE_SHORT
+	[ARM_SHORT_DESC] = &io_pgtable_arm_short_init_fns,
+#endif
 };
 
 struct io_pgtable_ops *alloc_io_pgtable_ops(enum io_pgtable_fmt fmt,
diff --git a/drivers/iommu/io-pgtable.h b/drivers/iommu/io-pgtable.h
index 68c63d9..0f45e60 100644
--- a/drivers/iommu/io-pgtable.h
+++ b/drivers/iommu/io-pgtable.h
@@ -9,6 +9,7 @@ enum io_pgtable_fmt {
 	ARM_32_LPAE_S2,
 	ARM_64_LPAE_S1,
 	ARM_64_LPAE_S2,
+	ARM_SHORT_DESC,
 	IO_PGTABLE_NUM_FMTS,
 };
 
@@ -45,6 +46,9 @@ struct iommu_gather_ops {
  */
 struct io_pgtable_cfg {
 	#define IO_PGTABLE_QUIRK_ARM_NS	(1 << 0)	/* Set NS bit in PTEs */
+	#define IO_PGTABLE_QUIRK_SHORT_SUPERSECTION     BIT(1)
+	#define IO_PGTABLE_QUIRK_SHORT_NO_XN		BIT(2) /* No XN bit */
+	#define IO_PGTABLE_QUIRK_SHORT_NO_PERMS		BIT(3) /* No AP bit */
 	int				quirks;
 	unsigned long			pgsize_bitmap;
 	unsigned int			ias;
@@ -64,6 +68,13 @@ struct io_pgtable_cfg {
 			u64	vttbr;
 			u64	vtcr;
 		} arm_lpae_s2_cfg;
+
+		struct {
+			u32	ttbr[2];
+			u32	tcr;
+			u32	nmrr;
+			u32	prrr;
+		} arm_short_cfg;
 	};
 };
 
@@ -130,6 +141,9 @@ struct io_pgtable {
 	struct io_pgtable_ops	ops;
 };
 
+#define io_pgtable_ops_to_pgtable(x)		\
+	container_of((x), struct io_pgtable, ops)
+
 /**
  * struct io_pgtable_init_fns - Alloc/free a set of page tables for a
  *                              particular format.
-- 
1.8.1.1.dirty



From yong.wu at mediatek.com  Mon Aug  3 03:21:17 2015
From: yong.wu at mediatek.com (Yong Wu)
Date: Mon, 3 Aug 2015 18:21:17 +0800
Subject: [PATCH v4 4/6] memory: mediatek: Add SMI driver
In-Reply-To: <1438597279-2937-1-git-send-email-yong.wu@mediatek.com>
References: <1438597279-2937-1-git-send-email-yong.wu@mediatek.com>
Message-ID: <1438597279-2937-5-git-send-email-yong.wu@mediatek.com>

This patch add SMI(Smart Multimedia Interface) driver. This driver
is responsible to enable/disable iommu and control the clocks of each
local arbiter

Signed-off-by: Yong Wu <yong.wu at mediatek.com>
---
 drivers/memory/Kconfig     |   8 ++
 drivers/memory/Makefile    |   1 +
 drivers/memory/mtk-smi.c   | 285 +++++++++++++++++++++++++++++++++++++++++++++
 include/soc/mediatek/smi.h |  60 ++++++++++
 4 files changed, 354 insertions(+)
 create mode 100644 drivers/memory/mtk-smi.c
 create mode 100644 include/soc/mediatek/smi.h

diff --git a/drivers/memory/Kconfig b/drivers/memory/Kconfig
index 8406c668..c0e1607 100644
--- a/drivers/memory/Kconfig
+++ b/drivers/memory/Kconfig
@@ -100,6 +100,14 @@ config JZ4780_NEMC
 	  the Ingenic JZ4780. This controller is used to handle external
 	  memory devices such as NAND and SRAM.
 
+config MTK_SMI
+	bool
+	depends on ARCH_MEDIATEK || COMPILE_TEST
+	help
+	  This driver is for the Memory Controller module in MediaTek SoCs,
+	  mainly help enable/disable iommu and control the clock for each
+	  local arbiter.
+
 source "drivers/memory/tegra/Kconfig"
 
 endif
diff --git a/drivers/memory/Makefile b/drivers/memory/Makefile
index b670441..f854e40 100644
--- a/drivers/memory/Makefile
+++ b/drivers/memory/Makefile
@@ -14,5 +14,6 @@ obj-$(CONFIG_FSL_IFC)		+= fsl_ifc.o
 obj-$(CONFIG_MVEBU_DEVBUS)	+= mvebu-devbus.o
 obj-$(CONFIG_TEGRA20_MC)	+= tegra20-mc.o
 obj-$(CONFIG_JZ4780_NEMC)	+= jz4780-nemc.o
+obj-$(CONFIG_MTK_SMI)		+= mtk-smi.o
 
 obj-$(CONFIG_TEGRA_MC)		+= tegra/
diff --git a/drivers/memory/mtk-smi.c b/drivers/memory/mtk-smi.c
new file mode 100644
index 0000000..e62cceb
--- /dev/null
+++ b/drivers/memory/mtk-smi.c
@@ -0,0 +1,285 @@
+/*
+ * Copyright (c) 2014-2015 MediaTek Inc.
+ * Author: Yong Wu <yong.wu at 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/io.h>
+#include <linux/platform_device.h>
+#include <linux/clk.h>
+#include <linux/err.h>
+#include <linux/slab.h>
+#include <linux/of_address.h>
+#include <linux/of_irq.h>
+#include <linux/of_platform.h>
+#include <linux/pm_runtime.h>
+#include <soc/mediatek/smi.h>
+
+#define SMI_LARB_MMU_EN		0xf00
+#define F_SMI_MMU_EN(port)	BIT(port)
+
+struct mtk_smi_common {
+	struct clk		*clk_apb;
+	struct clk		*clk_smi;
+};
+
+struct mtk_smi_larb {
+	void __iomem		*base;
+	struct clk		*clk_apb;
+	struct clk		*clk_smi;
+	struct device		*smi;
+};
+
+struct mtk_larb_mmu {
+	u32			mmu;
+};
+
+static int mtk_smi_common_get(struct device *smidev)
+{
+	struct mtk_smi_common *smipriv = dev_get_drvdata(smidev);
+	int ret;
+
+	ret = pm_runtime_get_sync(smidev);
+	if (ret < 0)
+		return ret;
+
+	ret = clk_prepare_enable(smipriv->clk_apb);
+	if (ret) {
+		dev_err(smidev, "Failed to enable the apb clock\n");
+		goto err_put_pm;
+	}
+	ret = clk_prepare_enable(smipriv->clk_smi);
+	if (ret) {
+		dev_err(smidev, "Failed to enable the smi clock\n");
+		goto err_disable_apb;
+	}
+	return ret;
+
+err_disable_apb:
+	clk_disable_unprepare(smipriv->clk_apb);
+err_put_pm:
+	pm_runtime_put(smidev);
+	return ret;
+}
+
+static void mtk_smi_common_put(struct device *smidev)
+{
+	struct mtk_smi_common *smipriv = dev_get_drvdata(smidev);
+
+	clk_disable_unprepare(smipriv->clk_smi);
+	clk_disable_unprepare(smipriv->clk_apb);
+	pm_runtime_put(smidev);
+}
+
+int mtk_smi_larb_get(struct device *larbdev)
+{
+	struct mtk_smi_larb *larbpriv = dev_get_drvdata(larbdev);
+	struct mtk_larb_mmu *mmucfg = larbdev->archdata.iommu;
+	int ret;
+
+	ret = mtk_smi_common_get(larbpriv->smi);
+	if (ret)
+		return ret;
+
+	ret = pm_runtime_get_sync(larbdev);
+	if (ret < 0)
+		goto err_put_smicommon;
+
+	ret = clk_prepare_enable(larbpriv->clk_apb);
+	if (ret) {
+		dev_err(larbdev, "Failed to enable the apb clock\n");
+		goto err_put_pm;
+	}
+
+	ret = clk_prepare_enable(larbpriv->clk_smi);
+	if (ret) {
+		dev_err(larbdev, "Failed to enable the smi clock\n");
+		goto err_disable_apb;
+	}
+
+	/* config iommu */
+	writel_relaxed(mmucfg->mmu, larbpriv->base + SMI_LARB_MMU_EN);
+
+	return ret;
+
+err_disable_apb:
+	clk_disable_unprepare(larbpriv->clk_apb);
+err_put_pm:
+	pm_runtime_put(larbdev);
+err_put_smicommon:
+	mtk_smi_common_put(larbpriv->smi);
+	return ret;
+}
+
+void mtk_smi_larb_put(struct device *larbdev)
+{
+	struct mtk_smi_larb *larbpriv = dev_get_drvdata(larbdev);
+
+	clk_disable_unprepare(larbpriv->clk_smi);
+	clk_disable_unprepare(larbpriv->clk_apb);
+	pm_runtime_put(larbdev);
+	mtk_smi_common_put(larbpriv->smi);
+}
+
+int mtk_smi_config_port(struct device *larbdev, unsigned int larbportid,
+			bool enable)
+{
+	struct mtk_larb_mmu *mmucfg = larbdev->archdata.iommu;
+
+	if (!mmucfg) {
+		mmucfg = kzalloc(sizeof(*mmucfg), GFP_KERNEL);
+		if (!mmucfg)
+			return -ENOMEM;
+		larbdev->archdata.iommu = mmucfg;
+	}
+
+	dev_dbg(larbdev, "%s iommu port id %d\n",
+		enable ? "enable" : "disable", larbportid);
+
+	if (enable)
+		mmucfg->mmu |= F_SMI_MMU_EN(larbportid);
+	else
+		mmucfg->mmu &= ~F_SMI_MMU_EN(larbportid);
+
+	return 0;
+}
+
+static int mtk_smi_larb_probe(struct platform_device *pdev)
+{
+	struct mtk_smi_larb *larbpriv;
+	struct resource *res;
+	struct device *dev = &pdev->dev;
+	struct device_node *smi_node;
+	struct platform_device *smi_pdev;
+
+	larbpriv = devm_kzalloc(dev, sizeof(*larbpriv), GFP_KERNEL);
+	if (!larbpriv)
+		return -ENOMEM;
+
+	res = platform_get_resource(pdev, IORESOURCE_MEM, 0);
+	larbpriv->base = devm_ioremap_resource(dev, res);
+	if (IS_ERR(larbpriv->base))
+		return PTR_ERR(larbpriv->base);
+
+	larbpriv->clk_apb = devm_clk_get(dev, "apb");
+	if (IS_ERR(larbpriv->clk_apb))
+		return PTR_ERR(larbpriv->clk_apb);
+
+	larbpriv->clk_smi = devm_clk_get(dev, "smi");
+	if (IS_ERR(larbpriv->clk_smi))
+		return PTR_ERR(larbpriv->clk_smi);
+
+	smi_node = of_parse_phandle(dev->of_node, "mediatek,smi", 0);
+	if (!smi_node)
+		return -EINVAL;
+
+	smi_pdev = of_find_device_by_node(smi_node);
+	of_node_put(smi_node);
+	if (smi_pdev) {
+		larbpriv->smi = &smi_pdev->dev;
+	} else {
+		dev_err(dev, "Failed to get the smi_common device\n");
+		return -EINVAL;
+	}
+
+	pm_runtime_enable(dev);
+	dev_set_drvdata(dev, larbpriv);
+	return 0;
+}
+
+static int mtk_smi_larb_remove(struct platform_device *pdev)
+{
+	struct mtk_larb_mmu *mmucfg = pdev->dev.archdata.iommu;
+
+	kfree(mmucfg);
+	pm_runtime_disable(&pdev->dev);
+	return 0;
+}
+
+static const struct of_device_id mtk_smi_larb_of_ids[] = {
+	{ .compatible = "mediatek,mt8173-smi-larb",},
+	{}
+};
+
+static struct platform_driver mtk_smi_larb_driver = {
+	.probe	= mtk_smi_larb_probe,
+	.remove = mtk_smi_larb_remove,
+	.driver	= {
+		.name = "mtk-smi-larb",
+		.of_match_table = mtk_smi_larb_of_ids,
+	}
+};
+
+static int mtk_smi_probe(struct platform_device *pdev)
+{
+	struct device *dev = &pdev->dev;
+	struct mtk_smi_common *smipriv;
+	int ret;
+
+	smipriv = devm_kzalloc(dev, sizeof(*smipriv), GFP_KERNEL);
+	if (!smipriv)
+		return -ENOMEM;
+
+	smipriv->clk_apb = devm_clk_get(dev, "apb");
+	if (IS_ERR(smipriv->clk_apb))
+		return PTR_ERR(smipriv->clk_apb);
+
+	smipriv->clk_smi = devm_clk_get(dev, "smi");
+	if (IS_ERR(smipriv->clk_smi))
+		return PTR_ERR(smipriv->clk_smi);
+
+	pm_runtime_enable(dev);
+	dev_set_drvdata(dev, smipriv);
+	return ret;
+}
+
+static int mtk_smi_remove(struct platform_device *pdev)
+{
+	pm_runtime_disable(&pdev->dev);
+	return 0;
+}
+
+static const struct of_device_id mtk_smi_of_ids[] = {
+	{ .compatible = "mediatek,mt8173-smi",},
+	{}
+};
+
+static struct platform_driver mtk_smi_driver = {
+	.probe	= mtk_smi_probe,
+	.remove = mtk_smi_remove,
+	.driver	= {
+		.name = "mtk-smi",
+		.of_match_table = mtk_smi_of_ids,
+	}
+};
+
+static int __init mtk_smi_init(void)
+{
+	int ret;
+
+	ret = platform_driver_register(&mtk_smi_driver);
+	if (ret != 0) {
+		pr_err("Failed to register SMI driver\n");
+		return ret;
+	}
+
+	ret = platform_driver_register(&mtk_smi_larb_driver);
+	if (ret != 0) {
+		pr_err("Failed to register SMI-LARB driver\n");
+		goto err_unreg_smi;
+	}
+	return ret;
+
+err_unreg_smi:
+	platform_driver_unregister(&mtk_smi_driver);
+	return ret;
+}
+
+subsys_initcall(mtk_smi_init);
diff --git a/include/soc/mediatek/smi.h b/include/soc/mediatek/smi.h
new file mode 100644
index 0000000..189d575
--- /dev/null
+++ b/include/soc/mediatek/smi.h
@@ -0,0 +1,60 @@
+/*
+ * Copyright (c) 2014-2015 MediaTek Inc.
+ * Author: Yong Wu <yong.wu at 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.
+ */
+#ifndef MTK_IOMMU_SMI_H
+#define MTK_IOMMU_SMI_H
+
+#include <linux/device.h>
+
+#ifdef CONFIG_MTK_SMI
+
+/*
+ * Record the iommu info for each port in the local arbiter.
+ * It is only for iommu.
+ *
+ * Returns 0 if successfully, others if failed.
+ */
+int mtk_smi_config_port(struct device *larbdev, unsigned int larbportid,
+			bool enable);
+/*
+ * The two function below config iommu and enable/disable the clock
+ * for the larb.
+ *
+ * mtk_smi_larb_get must be called before the multimedia HW work.
+ * mtk_smi_larb_put must be called after HW done.
+ * Both should be called in non-atomic context.
+ *
+ * Returns 0 if successfully, others if failed.
+ */
+int mtk_smi_larb_get(struct device *larbdev);
+void mtk_smi_larb_put(struct device *larbdev);
+
+#else
+
+static int
+mtk_smi_config_port(struct device *larbdev, unsigned int larbportid,
+		    bool enable)
+{
+	return 0;
+}
+
+static inline int mtk_smi_larb_get(struct device *larbdev)
+{
+	return 0;
+}
+
+static inline void mtk_smi_larb_put(struct device *larbdev) { }
+
+#endif
+
+#endif
-- 
1.8.1.1.dirty



From yong.wu at mediatek.com  Mon Aug  3 03:21:18 2015
From: yong.wu at mediatek.com (Yong Wu)
Date: Mon, 3 Aug 2015 18:21:18 +0800
Subject: [PATCH v4 5/6] iommu/mediatek: Add mt8173 IOMMU driver
In-Reply-To: <1438597279-2937-1-git-send-email-yong.wu@mediatek.com>
References: <1438597279-2937-1-git-send-email-yong.wu@mediatek.com>
Message-ID: <1438597279-2937-6-git-send-email-yong.wu@mediatek.com>

This patch adds support for mediatek m4u (MultiMedia Memory Management
Unit).

Signed-off-by: Yong Wu <yong.wu at mediatek.com>
---
 drivers/iommu/Kconfig     |  13 +
 drivers/iommu/Makefile    |   1 +
 drivers/iommu/mtk_iommu.c | 714 ++++++++++++++++++++++++++++++++++++++++++++++
 3 files changed, 728 insertions(+)
 create mode 100644 drivers/iommu/mtk_iommu.c

diff --git a/drivers/iommu/Kconfig b/drivers/iommu/Kconfig
index 3abd066..f0ae553e 100644
--- a/drivers/iommu/Kconfig
+++ b/drivers/iommu/Kconfig
@@ -386,4 +386,17 @@ config ARM_SMMU_V3
 	  Say Y here if your system includes an IOMMU device implementing
 	  the ARM SMMUv3 architecture.
 
+config MTK_IOMMU
+	bool "MTK IOMMU Support"
+	depends on ARCH_MEDIATEK || COMPILE_TEST
+	select IOMMU_API
+	select IOMMU_DMA
+	select IOMMU_IO_PGTABLE_SHORT
+	select MEMORY
+	select MTK_SMI
+	help
+	  Support for the IOMMUs on certain Mediatek SOCs.
+
+	  If unsure, say N here.
+
 endif # IOMMU_SUPPORT
diff --git a/drivers/iommu/Makefile b/drivers/iommu/Makefile
index 06df3e6..f4f2f2c 100644
--- a/drivers/iommu/Makefile
+++ b/drivers/iommu/Makefile
@@ -21,6 +21,7 @@ obj-$(CONFIG_ROCKCHIP_IOMMU) += rockchip-iommu.o
 obj-$(CONFIG_TEGRA_IOMMU_GART) += tegra-gart.o
 obj-$(CONFIG_TEGRA_IOMMU_SMMU) += tegra-smmu.o
 obj-$(CONFIG_EXYNOS_IOMMU) += exynos-iommu.o
+obj-$(CONFIG_MTK_IOMMU) += mtk_iommu.o
 obj-$(CONFIG_SHMOBILE_IOMMU) += shmobile-iommu.o
 obj-$(CONFIG_SHMOBILE_IPMMU) += shmobile-ipmmu.o
 obj-$(CONFIG_FSL_PAMU) += fsl_pamu.o fsl_pamu_domain.o
diff --git a/drivers/iommu/mtk_iommu.c b/drivers/iommu/mtk_iommu.c
new file mode 100644
index 0000000..3c4f1b5
--- /dev/null
+++ b/drivers/iommu/mtk_iommu.c
@@ -0,0 +1,714 @@
+/*
+ * Copyright (c) 2014-2015 MediaTek Inc.
+ * Author: Yong Wu <yong.wu at 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/io.h>
+#include <linux/interrupt.h>
+#include <linux/platform_device.h>
+#include <linux/iommu.h>
+#include <linux/dma-mapping.h>
+#include <linux/dma-iommu.h>
+#include <linux/of_iommu.h>
+#include <linux/of_address.h>
+#include <linux/of_irq.h>
+#include <linux/of_platform.h>
+#include <linux/list.h>
+#include <linux/clk.h>
+#include <linux/iopoll.h>
+#include <asm/cacheflush.h>
+#include <soc/mediatek/smi.h>
+
+#include "io-pgtable.h"
+
+#define REG_MMU_PT_BASE_ADDR			0x000
+
+#define REG_MMU_INVALIDATE			0x020
+#define F_ALL_INVLD				0x2
+#define F_MMU_INV_RANGE				0x1
+
+#define REG_MMU_INVLD_START_A			0x024
+#define REG_MMU_INVLD_END_A			0x028
+
+#define REG_MMU_INV_SEL				0x038
+#define F_INVLD_EN0				BIT(0)
+#define F_INVLD_EN1				BIT(1)
+
+#define REG_MMU_STANDARD_AXI_MODE		0x048
+#define REG_MMU_DCM_DIS				0x050
+
+#define REG_MMU_CTRL_REG			0x110
+#define F_MMU_PREFETCH_RT_REPLACE_MOD		BIT(4)
+#define F_MMU_TF_PROTECT_SEL(prot)		(((prot) & 0x3) << 5)
+#define F_COHERENCE_EN				BIT(8)
+
+#define REG_MMU_IVRP_PADDR			0x114
+#define F_MMU_IVRP_PA_SET(pa)			((pa) >> 1)
+
+#define REG_MMU_INT_CONTROL0			0x120
+#define F_L2_MULIT_HIT_EN			BIT(0)
+#define F_TABLE_WALK_FAULT_INT_EN		BIT(1)
+#define F_PREETCH_FIFO_OVERFLOW_INT_EN		BIT(2)
+#define F_MISS_FIFO_OVERFLOW_INT_EN		BIT(3)
+#define F_PREFETCH_FIFO_ERR_INT_EN		BIT(5)
+#define F_MISS_FIFO_ERR_INT_EN			BIT(6)
+#define F_INT_L2_CLR_BIT			BIT(12)
+
+#define REG_MMU_INT_MAIN_CONTROL		0x124
+#define F_INT_TRANSLATION_FAULT			BIT(0)
+#define F_INT_MAIN_MULTI_HIT_FAULT		BIT(1)
+#define F_INT_INVALID_PA_FAULT			BIT(2)
+#define F_INT_ENTRY_REPLACEMENT_FAULT		BIT(3)
+#define F_INT_TLB_MISS_FAULT			BIT(4)
+#define F_INT_MISS_TRANSATION_FIFO_FAULT	BIT(5)
+#define F_INT_PRETETCH_TRANSATION_FIFO_FAULT	BIT(6)
+
+#define REG_MMU_CPE_DONE			0x12C
+
+#define REG_MMU_FAULT_ST1			0x134
+
+#define REG_MMU_FAULT_VA			0x13c
+#define F_MMU_FAULT_VA_MSK			0xfffff000
+#define F_MMU_FAULT_VA_WRITE_BIT		BIT(1)
+#define F_MMU_FAULT_VA_LAYER_BIT		BIT(0)
+
+#define REG_MMU_INVLD_PA			0x140
+#define REG_MMU_INT_ID				0x150
+#define F_MMU0_INT_ID_LARB_ID(a)		(((a) >> 7) & 0x7)
+#define F_MMU0_INT_ID_PORT_ID(a)		(((a) >> 2) & 0x1f)
+
+#define MTK_PROTECT_PA_ALIGN			128
+#define MTK_IOMMU_LARB_MAX_NR			8
+#define MTK_IOMMU_REG_NR			10
+
+struct mtk_iommu_suspend_reg {
+	u32				standard_axi_mode;
+	u32				dcm_dis;
+	u32				ctrl_reg;
+	u32				ivrp_paddr;
+	u32				int_control0;
+	u32				int_main_control;
+};
+
+struct mtk_iommu_data {
+	void __iomem			*base;
+	int				irq;
+	struct device			*dev;
+	struct device			*larbdev[MTK_IOMMU_LARB_MAX_NR];
+	struct clk			*bclk;
+	phys_addr_t			protect_base; /* protect memory base */
+	int				larb_nr;/* local arbiter number */
+	struct mtk_iommu_suspend_reg	reg;
+};
+
+struct mtk_iommu_domain {
+	struct imu_pgd_t		*pgd;
+	spinlock_t			pgtlock; /* lock for page table */
+
+	struct io_pgtable_cfg		cfg;
+	struct io_pgtable_ops		*iop;
+
+	struct mtk_iommu_data		*data;
+	struct iommu_domain		domain;
+};
+
+struct mtk_iommu_client_priv {
+	struct list_head		client;
+	unsigned int			larbid;
+	unsigned int			portid;
+};
+
+static struct iommu_ops mtk_iommu_ops;
+
+/*
+ * There is only one iommu domain called the m4u domain that
+ * all Multimedia modules share.
+ */
+static struct mtk_iommu_domain	*m4udom;
+
+static struct mtk_iommu_domain *to_mtk_domain(struct iommu_domain *dom)
+{
+	return container_of(dom, struct mtk_iommu_domain, domain);
+}
+
+static void mtk_iommu_clear_intr(const struct mtk_iommu_data *data)
+{
+	u32 val;
+
+	val = readl_relaxed(data->base + REG_MMU_INT_CONTROL0);
+	val |= F_INT_L2_CLR_BIT;
+	writel_relaxed(val, data->base + REG_MMU_INT_CONTROL0);
+}
+
+static void mtk_iommu_tlb_flush_all(void *cookie)
+{
+	struct mtk_iommu_domain *domain = cookie;
+	void __iomem *base;
+
+	base = domain->data->base;
+	writel_relaxed(F_INVLD_EN1 | F_INVLD_EN0, base + REG_MMU_INV_SEL);
+	writel_relaxed(F_ALL_INVLD, base + REG_MMU_INVALIDATE);
+	mb();/* Make sure flush all done */
+}
+
+static void mtk_iommu_tlb_add_flush(unsigned long iova, size_t size,
+				    bool leaf, void *cookie)
+{
+	struct mtk_iommu_domain *domain = cookie;
+	void __iomem *base = domain->data->base;
+	unsigned int iova_start = iova, iova_end = iova + size - 1;
+
+	writel_relaxed(F_INVLD_EN1 | F_INVLD_EN0, base + REG_MMU_INV_SEL);
+
+	writel_relaxed(iova_start, base + REG_MMU_INVLD_START_A);
+	writel_relaxed(iova_end, base + REG_MMU_INVLD_END_A);
+	writel_relaxed(F_MMU_INV_RANGE, base + REG_MMU_INVALIDATE);
+}
+
+static void mtk_iommu_tlb_sync(void *cookie)
+{
+	struct mtk_iommu_domain *domain = cookie;
+	void __iomem *base = domain->data->base;
+	int ret;
+	u32 tmp;
+
+	ret = readl_poll_timeout_atomic(base + REG_MMU_CPE_DONE, tmp,
+					tmp != 0, 10, 1000000);
+	if (ret) {
+		dev_warn(domain->data->dev,
+			 "Partial TLB flush timed out, falling back to full flush\n");
+		mtk_iommu_tlb_flush_all(cookie);
+	}
+	writel_relaxed(0, base + REG_MMU_CPE_DONE);
+}
+
+static struct iommu_gather_ops mtk_iommu_gather_ops = {
+	.tlb_flush_all = mtk_iommu_tlb_flush_all,
+	.tlb_add_flush = mtk_iommu_tlb_add_flush,
+	.tlb_sync = mtk_iommu_tlb_sync,
+};
+
+static irqreturn_t mtk_iommu_isr(int irq, void *dev_id)
+{
+	struct mtk_iommu_domain *mtkdom = dev_id;
+	struct mtk_iommu_data *data = mtkdom->data;
+	u32 int_state, regval, fault_iova, fault_pa;
+	unsigned int fault_larb, fault_port;
+	bool layer, write;
+
+	int_state = readl_relaxed(data->base + REG_MMU_FAULT_ST1);
+
+	/* read error info from registers */
+	fault_iova = readl_relaxed(data->base + REG_MMU_FAULT_VA);
+	layer = fault_iova & F_MMU_FAULT_VA_LAYER_BIT;
+	write = fault_iova & F_MMU_FAULT_VA_WRITE_BIT;
+	fault_iova &= F_MMU_FAULT_VA_MSK;
+	fault_pa = readl_relaxed(data->base + REG_MMU_INVLD_PA);
+	regval = readl_relaxed(data->base + REG_MMU_INT_ID);
+	fault_larb = F_MMU0_INT_ID_LARB_ID(regval);
+	fault_port = F_MMU0_INT_ID_PORT_ID(regval);
+
+	if (report_iommu_fault(&mtkdom->domain, data->dev, fault_iova,
+			       write ? IOMMU_FAULT_WRITE : IOMMU_FAULT_READ)) {
+		dev_err_ratelimited(
+			data->dev,
+			"fault type=0x%x iova=0x%x pa=0x%x larb=%d port=%d layer=%d %s\n",
+			int_state, fault_iova, fault_pa, fault_larb, fault_port,
+			layer, write ? "write" : "read");
+	}
+
+	mtk_iommu_clear_intr(data);
+	mtk_iommu_tlb_flush_all(mtkdom);
+
+	return IRQ_HANDLED;
+}
+
+static int mtk_iommu_parse_dt(struct platform_device *pdev,
+			      struct mtk_iommu_data *data)
+{
+	struct device *dev = &pdev->dev;
+	struct device_node *ofnode;
+	struct resource *res;
+	int i;
+
+	ofnode = dev->of_node;
+
+	res = platform_get_resource(pdev, IORESOURCE_MEM, 0);
+	data->base = devm_ioremap_resource(&pdev->dev, res);
+	if (IS_ERR(data->base))
+		return PTR_ERR(data->base);
+
+	data->irq = platform_get_irq(pdev, 0);
+	if (data->irq < 0)
+		return data->irq;
+
+	data->bclk = devm_clk_get(dev, "bclk");
+	if (IS_ERR(data->bclk))
+		return PTR_ERR(data->bclk);
+
+	data->larb_nr = of_count_phandle_with_args(
+					ofnode, "mediatek,larb", NULL);
+	if (data->larb_nr < 0)
+		return data->larb_nr;
+
+	for (i = 0; i < data->larb_nr; i++) {
+		struct device_node *larbnode;
+		struct platform_device *plarbdev;
+
+		larbnode = of_parse_phandle(ofnode, "mediatek,larb", i);
+		if (!larbnode)
+			return -EINVAL;
+
+		plarbdev = of_find_device_by_node(larbnode);
+		of_node_put(larbnode);
+		if (!plarbdev)
+			return -EPROBE_DEFER;
+		data->larbdev[i] = &plarbdev->dev;
+	}
+
+	return 0;
+}
+
+static int mtk_iommu_hw_init(const struct mtk_iommu_domain *mtkdom)
+{
+	struct mtk_iommu_data *data = mtkdom->data;
+	void __iomem *base = data->base;
+	u32 regval;
+	int ret = 0;
+
+	ret = clk_prepare_enable(data->bclk);
+	if (ret) {
+		dev_err(data->dev, "Failed to enable iommu clk(%d)\n", ret);
+		return ret;
+	}
+
+	writel_relaxed(mtkdom->cfg.arm_short_cfg.ttbr[0],
+		       base + REG_MMU_PT_BASE_ADDR);
+
+	regval = F_MMU_PREFETCH_RT_REPLACE_MOD |
+		F_MMU_TF_PROTECT_SEL(2) |
+		F_COHERENCE_EN;
+	writel_relaxed(regval, base + REG_MMU_CTRL_REG);
+
+	regval = F_L2_MULIT_HIT_EN |
+		F_TABLE_WALK_FAULT_INT_EN |
+		F_PREETCH_FIFO_OVERFLOW_INT_EN |
+		F_MISS_FIFO_OVERFLOW_INT_EN |
+		F_PREFETCH_FIFO_ERR_INT_EN |
+		F_MISS_FIFO_ERR_INT_EN;
+	writel_relaxed(regval, base + REG_MMU_INT_CONTROL0);
+
+	regval = F_INT_TRANSLATION_FAULT |
+		F_INT_MAIN_MULTI_HIT_FAULT |
+		F_INT_INVALID_PA_FAULT |
+		F_INT_ENTRY_REPLACEMENT_FAULT |
+		F_INT_TLB_MISS_FAULT |
+		F_INT_MISS_TRANSATION_FIFO_FAULT |
+		F_INT_PRETETCH_TRANSATION_FIFO_FAULT;
+	writel_relaxed(regval, base + REG_MMU_INT_MAIN_CONTROL);
+
+	regval = ALIGN(data->protect_base, MTK_PROTECT_PA_ALIGN);
+	regval = F_MMU_IVRP_PA_SET(regval);
+	writel_relaxed(regval, base + REG_MMU_IVRP_PADDR);
+
+	writel_relaxed(0, base + REG_MMU_DCM_DIS);
+	writel_relaxed(0, base + REG_MMU_STANDARD_AXI_MODE);
+
+	if (devm_request_irq(data->dev, data->irq, mtk_iommu_isr, 0,
+			     dev_name(data->dev), (void *)mtkdom)) {
+		writel_relaxed(0, base + REG_MMU_PT_BASE_ADDR);
+		clk_disable_unprepare(data->bclk);
+		dev_err(data->dev, "Failed @ IRQ-%d Request\n", data->irq);
+		return -ENODEV;
+	}
+
+	return 0;
+}
+
+static int mtk_iommu_config(struct mtk_iommu_domain *mtkdom,
+			    struct device *dev, bool enable)
+{
+	struct mtk_iommu_data *data = mtkdom->data;
+	struct mtk_iommu_client_priv *head, *cur, *next;
+
+	head = dev->archdata.iommu;
+	list_for_each_entry_safe(cur, next, &head->client, client) {
+		if (cur->larbid >= data->larb_nr) {
+			dev_err(data->dev, "Invalid larb:%d\n", cur->larbid);
+			return -EINVAL;
+		}
+
+		mtk_smi_config_port(data->larbdev[cur->larbid],
+				    cur->portid, enable);
+		if (!enable) {
+			list_del(&cur->client);
+			kfree(cur);
+		}
+	}
+
+	if (!enable) {
+		kfree(head);
+		dev->archdata.iommu = NULL;
+	}
+	return 0;
+}
+
+static int mtk_iommu_init_domain_context(struct mtk_iommu_domain *dom)
+{
+	int ret;
+
+	if (dom->iop)
+		return 0;
+
+	spin_lock_init(&dom->pgtlock);
+	dom->cfg.quirks = IO_PGTABLE_QUIRK_ARM_NS |
+			IO_PGTABLE_QUIRK_SHORT_SUPERSECTION |
+			IO_PGTABLE_QUIRK_SHORT_NO_XN |
+			IO_PGTABLE_QUIRK_SHORT_NO_PERMS;
+	dom->cfg.pgsize_bitmap = mtk_iommu_ops.pgsize_bitmap,
+	dom->cfg.ias = 32;
+	dom->cfg.oas = 32;
+	dom->cfg.tlb = &mtk_iommu_gather_ops;
+	dom->cfg.iommu_dev = dom->data->dev;
+
+	dom->iop = alloc_io_pgtable_ops(ARM_SHORT_DESC, &dom->cfg, dom);
+	if (!dom->iop) {
+		dev_err(dom->data->dev, "Failed to alloc io pgtable\n");
+		return -EINVAL;
+	}
+
+	/* Update our support page sizes bitmap */
+	mtk_iommu_ops.pgsize_bitmap = dom->cfg.pgsize_bitmap;
+
+	ret = mtk_iommu_hw_init(dom);
+	if (ret)
+		free_io_pgtable_ops(dom->iop);
+
+	return ret;
+}
+
+static struct iommu_domain *mtk_iommu_domain_alloc(unsigned type)
+{
+	struct mtk_iommu_domain *priv;
+
+	if (type != IOMMU_DOMAIN_UNMANAGED && type != IOMMU_DOMAIN_DMA)
+		return NULL;
+
+	if (m4udom)/* The m4u domain exist. */
+		return &m4udom->domain;
+
+	priv = kzalloc(sizeof(*priv), GFP_KERNEL);
+	if (!priv)
+		return NULL;
+
+	priv->domain.geometry.aperture_start = 0;
+	priv->domain.geometry.aperture_end = DMA_BIT_MASK(32);
+	priv->domain.geometry.force_aperture = true;
+
+	m4udom = priv;
+
+	return &priv->domain;
+}
+
+static void mtk_iommu_domain_free(struct iommu_domain *domain)
+{
+	kfree(to_mtk_domain(domain));
+}
+
+static int mtk_iommu_attach_device(struct iommu_domain *domain,
+				   struct device *dev)
+{
+	struct mtk_iommu_domain *priv = to_mtk_domain(domain);
+	struct iommu_group *group;
+	int ret;
+
+	group = iommu_group_get(dev);
+	if (!group)
+		return 0;
+	iommu_group_put(group);
+
+	ret = mtk_iommu_init_domain_context(priv);
+	if (ret)
+		return ret;
+
+	return mtk_iommu_config(priv, dev, true);
+}
+
+static void mtk_iommu_detach_device(struct iommu_domain *domain,
+				    struct device *dev)
+{
+	mtk_iommu_config(to_mtk_domain(domain), dev, false);
+}
+
+static int mtk_iommu_map(struct iommu_domain *domain, unsigned long iova,
+			 phys_addr_t paddr, size_t size, int prot)
+{
+	struct mtk_iommu_domain *priv = to_mtk_domain(domain);
+	unsigned long flags;
+	int ret;
+
+	spin_lock_irqsave(&priv->pgtlock, flags);
+	ret = priv->iop->map(priv->iop, iova, paddr, size, prot);
+	spin_unlock_irqrestore(&priv->pgtlock, flags);
+
+	return ret;
+}
+
+static size_t mtk_iommu_unmap(struct iommu_domain *domain,
+			      unsigned long iova, size_t size)
+{
+	struct mtk_iommu_domain *priv = to_mtk_domain(domain);
+	unsigned long flags;
+	size_t unmapsize;
+
+	spin_lock_irqsave(&priv->pgtlock, flags);
+	unmapsize = priv->iop->unmap(priv->iop, iova, size);
+	spin_unlock_irqrestore(&priv->pgtlock, flags);
+
+	return unmapsize;
+}
+
+static phys_addr_t mtk_iommu_iova_to_phys(struct iommu_domain *domain,
+					  dma_addr_t iova)
+{
+	struct mtk_iommu_domain *priv = to_mtk_domain(domain);
+	unsigned long flags;
+	phys_addr_t pa;
+
+	spin_lock_irqsave(&priv->pgtlock, flags);
+	pa = priv->iop->iova_to_phys(priv->iop, iova);
+	spin_unlock_irqrestore(&priv->pgtlock, flags);
+
+	return pa;
+}
+
+static int mtk_iommu_add_device(struct device *dev)
+{
+	struct iommu_group *group;
+	int ret;
+
+	if (!dev->archdata.iommu) /* Not a iommu client device */
+		return -ENODEV;
+
+	group = iommu_group_get(dev);
+	if (!group) {
+		group = iommu_group_alloc();
+		if (IS_ERR(group)) {
+			dev_err(dev, "Failed to allocate IOMMU group\n");
+			return PTR_ERR(group);
+		}
+	}
+
+	ret = iommu_group_add_device(group, dev);
+	if (ret) {
+		dev_err(dev, "Failed to add IOMMU group\n");
+		goto err_group_put;
+	}
+
+	ret = iommu_attach_group(&m4udom->domain, group);
+	if (ret)
+		dev_err(dev, "Failed to attach IOMMU group\n");
+
+err_group_put:
+	iommu_group_put(group);
+	return ret;
+}
+
+static void mtk_iommu_remove_device(struct device *dev)
+{
+	if (!dev->archdata.iommu)
+		return;
+
+	iommu_group_remove_device(dev);
+}
+
+static int mtk_iommu_of_xlate(struct device *dev, struct of_phandle_args *args)
+{
+	struct mtk_iommu_client_priv *head, *priv, *next;
+
+	if (args->args_count != 2) {
+		dev_err(dev, "invalid #iommu-cells(%d) property for IOMMU\n",
+			args->args_count);
+		return -EINVAL;
+	}
+
+	if (!dev->archdata.iommu) {
+		head = kzalloc(sizeof(*head), GFP_KERNEL);
+		if (!head)
+			return -ENOMEM;
+
+		dev->archdata.iommu = head;
+		INIT_LIST_HEAD(&head->client);
+	} else {
+		head = dev->archdata.iommu;
+	}
+
+	priv = kzalloc(sizeof(*priv), GFP_KERNEL);
+	if (!priv)
+		goto err_free_mem;
+
+	priv->larbid = args->args[0];
+	priv->portid = args->args[1];
+	list_add_tail(&priv->client, &head->client);
+
+	return 0;
+
+err_free_mem:
+	list_for_each_entry_safe(priv, next, &head->client, client)
+		kfree(priv);
+	kfree(head);
+	dev->archdata.iommu = NULL;
+	return -ENOMEM;
+}
+
+static struct iommu_ops mtk_iommu_ops = {
+	.domain_alloc	= mtk_iommu_domain_alloc,
+	.domain_free	= mtk_iommu_domain_free,
+	.attach_dev	= mtk_iommu_attach_device,
+	.detach_dev	= mtk_iommu_detach_device,
+	.map		= mtk_iommu_map,
+	.unmap		= mtk_iommu_unmap,
+	.map_sg		= default_iommu_map_sg,
+	.iova_to_phys	= mtk_iommu_iova_to_phys,
+	.add_device	= mtk_iommu_add_device,
+	.remove_device	= mtk_iommu_remove_device,
+	.of_xlate	= mtk_iommu_of_xlate,
+	.pgsize_bitmap	= SZ_4K | SZ_64K | SZ_1M | SZ_16M,
+};
+
+static const struct of_device_id mtk_iommu_of_ids[] = {
+	{ .compatible = "mediatek,mt8173-m4u", },
+	{}
+};
+
+static int mtk_iommu_init_fn(struct device_node *np)
+{
+	struct platform_device *pdev;
+
+	pdev = of_platform_device_create(np, NULL, platform_bus_type.dev_root);
+	if (IS_ERR(pdev))
+		return PTR_ERR(pdev);
+
+	of_iommu_set_ops(np, &mtk_iommu_ops);
+
+	return 0;
+}
+
+IOMMU_OF_DECLARE(mtkm4u, "mediatek,mt8173-m4u", mtk_iommu_init_fn);
+
+static int mtk_iommu_probe(struct platform_device *pdev)
+{
+	struct mtk_iommu_data   *data;
+	struct device           *dev = &pdev->dev;
+	void __iomem	        *protect;
+	int                     ret;
+
+	data = devm_kzalloc(dev, sizeof(*data), GFP_KERNEL);
+	if (!data)
+		return -ENOMEM;
+
+	/* Protect memory. HW will access here while translation fault.*/
+	protect = devm_kzalloc(dev, MTK_PROTECT_PA_ALIGN * 2, GFP_KERNEL);
+	if (!protect)
+		return -ENOMEM;
+	data->protect_base = virt_to_phys(protect);
+
+	ret = mtk_iommu_parse_dt(pdev, data);
+	if (ret)
+		return ret;
+
+	if (!m4udom)/* There is no iommu client */
+		return 0;
+
+	data->dev = dev;
+	m4udom->data = data;
+	dev_set_drvdata(dev, m4udom);
+
+	return 0;
+}
+
+static int mtk_iommu_remove(struct platform_device *pdev)
+{
+	struct mtk_iommu_domain *mtkdom = dev_get_drvdata(&pdev->dev);
+
+	if (!mtkdom)
+		return 0;
+
+	free_io_pgtable_ops(mtkdom->iop); /* Destroy domain context */
+	clk_disable_unprepare(mtkdom->data->bclk);
+	return 0;
+}
+
+static int mtk_iommu_suspend(struct device *dev)
+{
+	struct mtk_iommu_domain *mtkdom = dev_get_drvdata(dev);
+	struct mtk_iommu_suspend_reg *reg = &mtkdom->data->reg;
+	void __iomem *base = mtkdom->data->base;
+
+	reg->standard_axi_mode = readl_relaxed(base +
+					       REG_MMU_STANDARD_AXI_MODE);
+	reg->dcm_dis = readl_relaxed(base + REG_MMU_DCM_DIS);
+	reg->ctrl_reg = readl_relaxed(base + REG_MMU_CTRL_REG);
+	reg->ivrp_paddr = readl_relaxed(base + REG_MMU_IVRP_PADDR);
+	reg->int_control0 = readl_relaxed(base + REG_MMU_INT_CONTROL0);
+	reg->int_main_control = readl_relaxed(base + REG_MMU_INT_MAIN_CONTROL);
+	return 0;
+}
+
+static int mtk_iommu_resume(struct device *dev)
+{
+	struct mtk_iommu_domain *mtkdom = dev_get_drvdata(dev);
+	struct mtk_iommu_suspend_reg *reg = &mtkdom->data->reg;
+	void __iomem *base = mtkdom->data->base;
+
+	writel_relaxed(mtkdom->cfg.arm_short_cfg.ttbr[0],
+		       base + REG_MMU_PT_BASE_ADDR);
+	writel_relaxed(reg->standard_axi_mode,
+		       base + REG_MMU_STANDARD_AXI_MODE);
+	writel_relaxed(reg->dcm_dis, base + REG_MMU_DCM_DIS);
+	writel_relaxed(reg->ctrl_reg, base + REG_MMU_CTRL_REG);
+	writel_relaxed(reg->ivrp_paddr, base + REG_MMU_IVRP_PADDR);
+	writel_relaxed(reg->int_control0, base + REG_MMU_INT_CONTROL0);
+	writel_relaxed(reg->int_main_control, base + REG_MMU_INT_MAIN_CONTROL);
+	return 0;
+}
+
+const struct dev_pm_ops mtk_iommu_pm_ops = {
+	SET_SYSTEM_SLEEP_PM_OPS(mtk_iommu_suspend, mtk_iommu_resume)
+};
+
+static struct platform_driver mtk_iommu_driver = {
+	.probe	= mtk_iommu_probe,
+	.remove	= mtk_iommu_remove,
+	.driver	= {
+		.name = "mtk-iommu",
+		.of_match_table = mtk_iommu_of_ids,
+		.pm = &mtk_iommu_pm_ops,
+	}
+};
+
+static int __init mtk_iommu_init(void)
+{
+	int ret;
+
+	ret = platform_driver_register(&mtk_iommu_driver);
+	if (ret) {
+		pr_err("%s: Failed to register driver\n", __func__);
+		return ret;
+	}
+
+	if (!iommu_present(&platform_bus_type))
+		bus_set_iommu(&platform_bus_type, &mtk_iommu_ops);
+
+	return 0;
+}
+
+subsys_initcall(mtk_iommu_init);
-- 
1.8.1.1.dirty



From yong.wu at mediatek.com  Mon Aug  3 03:21:19 2015
From: yong.wu at mediatek.com (Yong Wu)
Date: Mon, 3 Aug 2015 18:21:19 +0800
Subject: [PATCH v4 6/6] dts: mt8173: Add iommu/smi nodes for mt8173
In-Reply-To: <1438597279-2937-1-git-send-email-yong.wu@mediatek.com>
References: <1438597279-2937-1-git-send-email-yong.wu@mediatek.com>
Message-ID: <1438597279-2937-7-git-send-email-yong.wu@mediatek.com>

This patch add the iommu/larbs nodes for mt8173

Signed-off-by: Yong Wu <yong.wu at mediatek.com>
---
 arch/arm64/boot/dts/mediatek/mt8173.dtsi | 81 ++++++++++++++++++++++++++++++++
 1 file changed, 81 insertions(+)

diff --git a/arch/arm64/boot/dts/mediatek/mt8173.dtsi b/arch/arm64/boot/dts/mediatek/mt8173.dtsi
index 6c3f047..a92956d 100644
--- a/arch/arm64/boot/dts/mediatek/mt8173.dtsi
+++ b/arch/arm64/boot/dts/mediatek/mt8173.dtsi
@@ -14,6 +14,7 @@
 #include <dt-bindings/clock/mt8173-clk.h>
 #include <dt-bindings/interrupt-controller/irq.h>
 #include <dt-bindings/interrupt-controller/arm-gic.h>
+#include <dt-bindings/memory/mt8173-larb-port.h>
 #include <dt-bindings/power/mt8173-power.h>
 #include <dt-bindings/reset-controller/mt8173-resets.h>
 #include "mt8173-pinfunc.h"
@@ -265,6 +266,17 @@
 			reg = <0 0x10200620 0 0x20>;
 		};
 
+		iommu: iommu at 10205000 {
+			compatible = "mediatek,mt8173-m4u";
+			reg = <0 0x10205000 0 0x1000>;
+			interrupts = <GIC_SPI 139 IRQ_TYPE_LEVEL_LOW>;
+			clocks = <&infracfg CLK_INFRA_M4U>;
+			clock-names = "bclk";
+			mediatek,larb = <&larb0 &larb1 &larb2
+					 &larb3 &larb4 &larb5>;
+			#iommu-cells = <2>;
+		};
+
 		apmixedsys: clock-controller at 10209000 {
 			compatible = "mediatek,mt8173-apmixedsys";
 			reg = <0 0x10209000 0 0x1000>;
@@ -501,29 +513,98 @@
 			#clock-cells = <1>;
 		};
 
+		larb0: larb at 14021000 {
+			compatible = "mediatek,mt8173-smi-larb";
+			reg = <0 0x14021000 0 0x1000>;
+			mediatek,smi = <&smi_common>;
+			power-domains = <&scpsys MT8173_POWER_DOMAIN_MM>;
+			clocks = <&mmsys CLK_MM_SMI_LARB0>,
+				 <&mmsys CLK_MM_SMI_LARB0>;
+			clock-names = "apb", "smi";
+		};
+
+		smi_common: smi at 14022000 {
+			compatible = "mediatek,mt8173-smi";
+			reg = <0 0x14022000 0 0x1000>;
+			power-domains = <&scpsys MT8173_POWER_DOMAIN_MM>;
+			clocks = <&mmsys CLK_MM_SMI_COMMON>,
+				 <&mmsys CLK_MM_SMI_COMMON>;
+			clock-names = "apb", "smi";
+		};
+
+		larb4: larb at 14027000 {
+			compatible = "mediatek,mt8173-smi-larb";
+			reg = <0 0x14027000 0 0x1000>;
+			mediatek,smi = <&smi_common>;
+			power-domains = <&scpsys MT8173_POWER_DOMAIN_MM>;
+			clocks = <&mmsys CLK_MM_SMI_LARB4>,
+				 <&mmsys CLK_MM_SMI_LARB4>;
+			clock-names = "apb", "smi";
+		};
+
 		imgsys: clock-controller at 15000000 {
 			compatible = "mediatek,mt8173-imgsys", "syscon";
 			reg = <0 0x15000000 0 0x1000>;
 			#clock-cells = <1>;
 		};
 
+		larb2: larb at 15001000 {
+			compatible = "mediatek,mt8173-smi-larb";
+			reg = <0 0x15001000 0 0x1000>;
+			mediatek,smi = <&smi_common>;
+			power-domains = <&scpsys MT8173_POWER_DOMAIN_ISP>;
+			clocks = <&imgsys CLK_IMG_LARB2_SMI>,
+				 <&imgsys CLK_IMG_LARB2_SMI>;
+			clock-names = "apb", "smi";
+		};
+
 		vdecsys: clock-controller at 16000000 {
 			compatible = "mediatek,mt8173-vdecsys", "syscon";
 			reg = <0 0x16000000 0 0x1000>;
 			#clock-cells = <1>;
 		};
 
+		larb1: larb at 16010000 {
+			compatible = "mediatek,mt8173-smi-larb";
+			reg = <0 0x16010000 0 0x1000>;
+			mediatek,smi = <&smi_common>;
+			power-domains = <&scpsys MT8173_POWER_DOMAIN_VDEC>;
+			clocks = <&vdecsys CLK_VDEC_CKEN>,
+				 <&vdecsys CLK_VDEC_LARB_CKEN>;
+			clock-names = "apb", "smi";
+		};
+
 		vencsys: clock-controller at 18000000 {
 			compatible = "mediatek,mt8173-vencsys", "syscon";
 			reg = <0 0x18000000 0 0x1000>;
 			#clock-cells = <1>;
 		};
 
+		larb3: larb at 18001000 {
+			compatible = "mediatek,mt8173-smi-larb";
+			reg = <0 0x18001000 0 0x1000>;
+			mediatek,smi = <&smi_common>;
+			power-domains = <&scpsys MT8173_POWER_DOMAIN_VENC>;
+			clocks = <&vencsys CLK_VENC_CKE1>,
+				 <&vencsys CLK_VENC_CKE0>;
+			clock-names = "apb", "smi";
+		};
+
 		vencltsys: clock-controller at 19000000 {
 			compatible = "mediatek,mt8173-vencltsys", "syscon";
 			reg = <0 0x19000000 0 0x1000>;
 			#clock-cells = <1>;
 		};
+
+		larb5: larb at 19001000 {
+			compatible = "mediatek,mt8173-smi-larb";
+			reg = <0 0x19001000 0 0x1000>;
+			mediatek,smi = <&smi_common>;
+			power-domains = <&scpsys MT8173_POWER_DOMAIN_VENC_LT>;
+			clocks = <&vencltsys CLK_VENCLT_CKE1>,
+				 <&vencltsys CLK_VENCLT_CKE0>;
+			clock-names = "apb", "smi";
+		};
 	};
 };
 
-- 
1.8.1.1.dirty



From aisheng.dong at freescale.com  Mon Aug  3 03:14:26 2015
From: aisheng.dong at freescale.com (Dong Aisheng)
Date: Mon, 3 Aug 2015 18:14:26 +0800
Subject: [PATCH v3 5/6] mmc: sdhci-esdhc-imx: config watermark level
 and burst length
In-Reply-To: <20150731151345.GX7557@n2100.arm.linux.org.uk>
References: <1438160637-28061-1-git-send-email-haibo.chen@freescale.com>
 <1438160637-28061-6-git-send-email-haibo.chen@freescale.com>
 <20150731145140.GE27806@shlinux1.ap.freescale.net>
 <20150731151345.GX7557@n2100.arm.linux.org.uk>
Message-ID: <20150803101423.GA24870@shlinux1.ap.freescale.net>

On Fri, Jul 31, 2015 at 04:13:45PM +0100, Russell King - ARM Linux wrote:
> On Fri, Jul 31, 2015 at 10:51:41PM +0800, Dong Aisheng wrote:
> > On Wed, Jul 29, 2015 at 05:03:56PM +0800, Haibo Chen wrote:
> > > i.MX7D support eMMC HS400 mode, this mode can run in 8 bit,200MHZ
> > > DDR mode. So the I/O speed improve a lot compare to SD3.0
> > > 
> > > The default burst length is 8, if we don't change this value, in
> > > HS400 mode, when we do eMMC read operation, we can find that the
> > > clock signal will stop for a period of time. This means the speed
> > > of data moving on AHB bus is slower than I/O speed. So we should
> > > improve the speed of data moving on AHB bus.
> > > 
> > > For imx7d usdhc, this patch set the burst length as 16, and set
> > > watermark level as 64. The test result is the clock signal has
> > > no stop during the eMMC HS400 operation. For other imx usdhc, remain
> > > the default value: burst length as 8, watermark level as 16.
> > > 
> > > Signed-off-by: Haibo Chen <haibo.chen at freescale.com>
> > > ---
> > >  drivers/mmc/host/sdhci-esdhc-imx.c | 11 ++++++++++-
> > >  1 file changed, 10 insertions(+), 1 deletion(-)
> > > 
> > > diff --git a/drivers/mmc/host/sdhci-esdhc-imx.c b/drivers/mmc/host/sdhci-esdhc-imx.c
> > > index 158f93b..37d0095 100644
> > > --- a/drivers/mmc/host/sdhci-esdhc-imx.c
> > > +++ b/drivers/mmc/host/sdhci-esdhc-imx.c
> > > @@ -239,6 +239,11 @@ static inline int is_imx6q_usdhc(struct pltfm_imx_data *data)
> > >  	return data->socdata == &usdhc_imx6q_data;
> > >  }
> > >  
> > > +static inline int is_imx7d_usdhc(struct pltfm_imx_data *data)
> > > +{
> > > +	return data->socdata == &usdhc_imx7d_data;
> > > +}
> > 
> > Can we using flag to check instead of adding more is_imx_usdhc()?
> 
> No, not more flags.  Do the job properly and parameterise the differences.
> 

Hi Russell,

Thanks for the review.

I mean using the exist flag to do like:
if (imx_data->socdata->flags & ESDHC_FLAG_SUP_HS400)
        writel(0x10401040, host->ioaddr + ESDHC_WTMK_LVL);
else    
        writel(0x08100810, host->ioaddr + ESDHC_WTMK_LVL);
Not adding another new flag.

ESDHC_FLAG_SUP_HS400 represents the new feature support of HS400 which is
already added in patch
[PATCH v3 1/6] mmc: sdhci-esdhc-imx: add imx7d support and support HS400

> > >  static inline int esdhc_is_usdhc(struct pltfm_imx_data *data)
> > >  {
> > >  	return !!(data->socdata->flags & ESDHC_FLAG_USDHC);
> > > @@ -1145,7 +1150,11 @@ static int sdhci_esdhc_imx_probe(struct platform_device *pdev)
> > >  	 * to something insane.  Change it back here.
> > >  	 */
> > >  	if (esdhc_is_usdhc(imx_data)) {
> > > -		writel(0x08100810, host->ioaddr + ESDHC_WTMK_LVL);
> > > +		if (is_imx7d_usdhc(imx_data))
> > > +			writel(0x10401040, host->ioaddr + ESDHC_WTMK_LVL);
> > > +		else
> > > +			writel(0x08100810, host->ioaddr + ESDHC_WTMK_LVL);
> 
> So the value to be written to this register should come from the
> driver data, which is already used as a struct esdhc_soc_data to
> extrapolate out the differences.
> 
> Going down the flag path will lead you to an even more of a stinking
> shitpile than sdhci already is - if another version of the SoC requires
> a different value there, what are you going to do?  Add yet another
> flag for the next value?  What are you going to do when you have 16
> different values?  Use 16 different flags?  Clearly that path is insane.
> 

I understand your concern for the potential bad situation.

Here the watermark level setting of mx7d is dependant on the new feature
of HS400, so it seems make senese to use that flag to set value and does
not need adding new flag.

Actually that is the current approach for uSDHC driver to distinguish
the difference between register offset/settings by checking feature flags.
e.g. ESDHC_FLAG_USDHC, ESDHC_FLAG_STD_TUNING, ESDHC_FLAG_HS200 and etc.
This approach can save us a lot more flags for SoC checking for common
feature part. And up till now, things seem good.

If really new SoC comes while it requires a different value, if it's feature
dependant, we may still use feature flag for it.
If not, probably a quirk may be needed if it's IP limitation.

If it's normal situation and such situation happened too many in the future,
we may choose to parameterise all these normal feature independent settings
into esdhc_soc_data to avoid adding meaningless flags.
e.g.
static struct esdhc_soc_data usdhc_imx6sx_data = {
        .flags = ESDHC_FLAG_USDHC | ESDHC_FLAG_STD_TUNING
                        | ESDHC_FLAG_HAVE_CAP1 | ESDHC_FLAG_HS200,
        .wml = 32,
};

static struct esdhc_soc_data usdhc_imx7d_data = {
        .flags = ESDHC_FLAG_USDHC | ESDHC_FLAG_STD_TUNING
                        | ESDHC_FLAG_HAVE_CAP1 | ESDHC_FLAG_HS200,
        .wml = 64,
};

But currently i still did not see such urgent requirement to do it for only
water mark level settings.

Regards
Dong Aisheng

> -- 
> FTTC broadband for 0.8mile line: currently at 10.5Mbps down 400kbps up
> according to speedtest.net.


From ard.biesheuvel at linaro.org  Mon Aug  3 03:24:53 2015
From: ard.biesheuvel at linaro.org (Ard Biesheuvel)
Date: Mon, 3 Aug 2015 12:24:53 +0200
Subject: [Query] ARM64: Softlockup when using PSCI for secondary CPU_ON
In-Reply-To: <BY1PR0301MB1303EC5AAE8F0B4DAA70D15F82770@BY1PR0301MB1303.namprd03.prod.outlook.com>
References: <BY1PR0301MB1303EC5AAE8F0B4DAA70D15F82770@BY1PR0301MB1303.namprd03.prod.outlook.com>
Message-ID: <CAKv+Gu8i-HC7zb-CuCaVE5vcoEO6T19_=s3JtHqnNHaUmdwQqg@mail.gmail.com>

On 3 August 2015 at 06:12, Sharma Bhupesh <bhupesh.sharma at freescale.com> wrote:
> Hi ARM64 experts,
>
> I am working on a Freescale ARM64 based SoC, which has 4 Cortex-A53 cores and I am using the
> PSCI conducts to turn on the secondary CPUs via a custom implementation of a secure runtime
> firmware (something similar to the ARM Trusted Firmware).
>
> Following is my boot-flow:
>
> - BootROM (runs in EL3, All secondaries are held up in reset) ->
>
> - UEFI bootloader- PEI Phase (Runs only on Primary, starts up in EL3) ->
>
> - Secure Firmware (runs in EL3, transitions primary core to EL2) ->
>
> - UEFI bootloader- Rest of the Phases (Runs only on Primary, in EL2) ->
>
> - UEFI Linux loader launches linux (Runs only on Primary, transitions core to EL1) ->
>

Why are you using the Linux loader? The arm64 kernel can be booted
directly from UEFI, which is strongly preferred since you will not
have access to the UEFI Runtime Services otherwise.
Also, the ARM BDS and the LinuxLoader for arm64 in Tianocore/EDK2 are
quite badly broken and may be removed completely in the future.

-- 
Ard.


From viresh.kumar at linaro.org  Mon Aug  3 03:29:26 2015
From: viresh.kumar at linaro.org (Viresh Kumar)
Date: Mon, 3 Aug 2015 15:59:26 +0530
Subject: [PATCH v3 3/5] ARM: Exynos: switch to using generic cpufreq
 driver for Exynos4x12
In-Reply-To: <5201904.0cZWHobiJs@amdc1976>
References: <1438368557-2352-1-git-send-email-b.zolnierkie@samsung.com>
 <1438368557-2352-4-git-send-email-b.zolnierkie@samsung.com>
 <20150801111721.GI899@linux> <5201904.0cZWHobiJs@amdc1976>
Message-ID: <20150803102926.GA21529@linux>

On 03-08-15, 12:17, Bartlomiej Zolnierkiewicz wrote:
> 
> Hi,
> 
> On Saturday, August 01, 2015 04:47:21 PM Viresh Kumar wrote:
> > On 31-07-15, 20:49, Bartlomiej Zolnierkiewicz wrote:
> > > diff --git a/drivers/cpufreq/Kconfig b/drivers/cpufreq/Kconfig
> > > index 659879a..bf6d596 100644
> > > --- a/drivers/cpufreq/Kconfig
> > > +++ b/drivers/cpufreq/Kconfig
> > > @@ -191,6 +191,7 @@ config CPUFREQ_DT
> > >  	# if CPU_THERMAL is on and THERMAL=m, CPUFREQ_DT cannot be =y:
> > >  	depends on !CPU_THERMAL || THERMAL
> > >  	select PM_OPP
> > > +	select EXYNOS_THERMAL if ARCH_EXYNOS
> > >  	help
> > >  	  This adds a generic DT based cpufreq driver for frequency management.
> > >  	  It supports both uniprocessor (UP) and symmetric multiprocessor (SMP)
> > 
> > No, we shouldn't pollute generic Kconfig options with platform specific stuff.
> 
> The old code depended on this.  You couldn't enable boost support
> without enabling thermal support (ARM_EXYNOS_CPU_FREQ_BOOST_SW
> config option selected EXYNOS_THERMAL).
> 
> > Why don't you enable thermal in your .config?
> 
> It is enabled in exynos_defconfig but without the above change it
> can disabled manually which is something that we don't want.

You are not getting it. I am not asking you to not select thermal, but
to select it from within your architecture Kconfig option if you want.

Over that, thermal is really an option, not a dependency. So, if
someone manually disables it, its his problem not yours :)

-- 
viresh


From b.zolnierkie at samsung.com  Mon Aug  3 03:31:32 2015
From: b.zolnierkie at samsung.com (Bartlomiej Zolnierkiewicz)
Date: Mon, 03 Aug 2015 12:31:32 +0200
Subject: [PATCH v3 3/5] ARM: Exynos: switch to using generic cpufreq driver
 for Exynos4x12
In-Reply-To: <55BC78BE.5020102@samsung.com>
References: <1438368557-2352-1-git-send-email-b.zolnierkie@samsung.com>
 <1438368557-2352-4-git-send-email-b.zolnierkie@samsung.com>
 <55BC78BE.5020102@samsung.com>
Message-ID: <59949991.607t9GcIyz@amdc1976>


[ added Zhang & Eduardo to Cc: ]

Hi,

On Saturday, August 01, 2015 04:43:58 PM Krzysztof Kozlowski wrote:
> W dniu 01.08.2015 o 03:49, Bartlomiej Zolnierkiewicz pisze:
> > The new CPU clock type allows the use of generic CPUfreq driver.
> > Switch Exynos4x12 to using generic cpufreq driver.
> > 
> > Also make CPUFREQ_DT config option select Exynos thermal driver
> > if Exynos platform support is enabled.
> 
> Why? I think this wasn't in your previous patch.

Previous patch kept ARM_EXYNOS_CPU_FREQ_BOOST_SW config option
which selected EXYNOS_THERMAL.  After recent changes (boost
support enabled in the cpufreq-dt driver when there are turbo
OPPs in board's dts file) ARM_EXYNOS_CPU_FREQ_BOOST_SW config
option become redundant and was removed.  However we still
would like to allow enabling boost support only if thermal
support is also enabled for Exynos platforms.

[ There may be a better way to do this in the future (runtime
  checking for thermal support being enabled) but currently
  there seems to be no thermal infrastructure to allow this. ]

Best regards,
--
Bartlomiej Zolnierkiewicz
Samsung R&D Institute Poland
Samsung Electronics

> Best regards,
> Krzysztof
> 
> 
> > 
> > Please also note that the switch to use the generic cpufreq-dt
> > driver fixes the minor issue present with the old code (support
> > for 'boost' mode in the exynos-cpufreq driver was enabled for
> > all supported SoCs even though 'boost' frequency was provided
> > only for Exynos4x12 ones).
> > 
> > Cc: Tomasz Figa <tomasz.figa at gmail.com>
> > Cc: Kukjin Kim <kgene.kim at samsung.com>
> > Cc: Thomas Abraham <thomas.ab at samsung.com>
> > Cc: Javier Martinez Canillas <javier at osg.samsung.com>
> > Signed-off-by: Bartlomiej Zolnierkiewicz <b.zolnierkie at samsung.com>
> > ---
> >  arch/arm/mach-exynos/exynos.c | 2 ++
> >  drivers/cpufreq/Kconfig       | 1 +
> >  2 files changed, 3 insertions(+)
> > 
> > diff --git a/arch/arm/mach-exynos/exynos.c b/arch/arm/mach-exynos/exynos.c
> > index 77ac021..1c47aee 100644
> > --- a/arch/arm/mach-exynos/exynos.c
> > +++ b/arch/arm/mach-exynos/exynos.c
> > @@ -227,6 +227,8 @@ static void __init exynos_init_irq(void)
> >  static const struct of_device_id exynos_cpufreq_matches[] = {
> >  	{ .compatible = "samsung,exynos3250", .data = "cpufreq-dt" },
> >  	{ .compatible = "samsung,exynos4210", .data = "cpufreq-dt" },
> > +	{ .compatible = "samsung,exynos4212", .data = "cpufreq-dt" },
> > +	{ .compatible = "samsung,exynos4412", .data = "cpufreq-dt" },
> >  	{ .compatible = "samsung,exynos5250", .data = "cpufreq-dt" },
> >  	{ /* sentinel */ }
> >  };
> > diff --git a/drivers/cpufreq/Kconfig b/drivers/cpufreq/Kconfig
> > index 659879a..bf6d596 100644
> > --- a/drivers/cpufreq/Kconfig
> > +++ b/drivers/cpufreq/Kconfig
> > @@ -191,6 +191,7 @@ config CPUFREQ_DT
> >  	# if CPU_THERMAL is on and THERMAL=m, CPUFREQ_DT cannot be =y:
> >  	depends on !CPU_THERMAL || THERMAL
> >  	select PM_OPP
> > +	select EXYNOS_THERMAL if ARCH_EXYNOS
> >  	help
> >  	  This adds a generic DT based cpufreq driver for frequency management.
> >  	  It supports both uniprocessor (UP) and symmetric multiprocessor (SMP)



From lftan at altera.com  Mon Aug  3 03:34:41 2015
From: lftan at altera.com (Ley Foon Tan)
Date: Mon, 3 Aug 2015 18:34:41 +0800
Subject: [PATCH v2 2/5] pci:host: Add Altera PCIe host controller driver
In-Reply-To: <55BB6B45.7010705@arm.com>
References: <1438337715-22594-1-git-send-email-lftan@altera.com>
 <1438337715-22594-3-git-send-email-lftan@altera.com>
 <55BB6B45.7010705@arm.com>
Message-ID: <CAFiDJ59i89hhj94KN3JwcPCxkpX4-KmV3uCg=-vn+1Y1hHdL2g@mail.gmail.com>

On Fri, Jul 31, 2015 at 8:34 PM, Marc Zyngier <marc.zyngier at arm.com> wrote:
> On 31/07/15 11:15, Ley Foon Tan wrote:
>> This patch adds the Altera PCIe host controller driver.
>>
>> Signed-off-by: Ley Foon Tan <lftan at altera.com>
>> ---
>>  drivers/pci/host/Kconfig       |   8 +
>>  drivers/pci/host/Makefile      |   1 +
>>  drivers/pci/host/pcie-altera.c | 526 +++++++++++++++++++++++++++++++++++++++++
>>  3 files changed, 535 insertions(+)
>>  create mode 100644 drivers/pci/host/pcie-altera.c
>>
>> diff --git a/drivers/pci/host/Kconfig b/drivers/pci/host/Kconfig
>> index 675c2d1..108500a 100644
>> --- a/drivers/pci/host/Kconfig
>> +++ b/drivers/pci/host/Kconfig
>> @@ -145,4 +145,12 @@ config PCIE_IPROC_BCMA
>>         Say Y here if you want to use the Broadcom iProc PCIe controller
>>         through the BCMA bus interface
>>
>> +config PCIE_ALTERA
>> +     tristate "Altera PCIe controller"
>> +     depends on ARCH_SOCFPGA
>> +     select PCI_MSI_IRQ_DOMAIN if PCI_MSI
>
> Why would you select this here? MSI support is in another driver, so I
> don't see the point.
Will move select PCI_MSI_IRQ_DOMAIN to config  PCIE_ALTERA_MSI section.

>
>> +     help
>> +       Say Y here if you want to enable PCIe controller support for Altera
>> +       SoCFPGA family of SoCs.
>> +
>>  endmenu

>> +static const struct irq_domain_ops intx_domain_ops = {
>> +     .map = altera_pcie_intx_map,
>> +};
>> +
>> +static irqreturn_t altera_pcie_isr(int irq, void *arg)
>> +{
>> +     struct altera_pcie *pcie = arg;
>> +     u32 status, i;
>> +
>> +     status = cra_readl(pcie, P2A_INT_STATUS) & P2A_INT_STS_ALL;
>> +
>> +     /* clear interrupts */
>> +     cra_writel(pcie, status, P2A_INT_STATUS);
>> +
>> +     for (i = 0; i < INTX_NUM; i++) {
>> +             if (status & (1 << i))
>
> find_first/next_set_bit?
Yes, change this to find_first_bit().

>
>> +                     generic_handle_irq(irq_find_mapping(pcie->irq_domain,
>> +                                                     i + 1));
>
> Rule of thumb: if you're calling generic_handle_irq from an interrupt
> handler, this is a chained IRQ controller. Please implement it as such.
Okay, will change this to chained_irq_enter/chained_irq_exit implementation.
>
>> +     }
>> +
>> +     return IRQ_HANDLED;
>> +}
>> +
>> +static void altera_pcie_release_of_pci_ranges(struct altera_pcie *pcie)
>> +{
>> +     pci_free_resource_list(&pcie->resources);
>> +}
>> +
>> +static int altera_pcie_parse_request_of_pci_ranges(struct altera_pcie *pcie)
>> +{
>> +     int err, res_valid = 0;
>> +     struct device *dev = &pcie->pdev->dev;
>> +     struct device_node *np = dev->of_node;
>> +     resource_size_t iobase;
>> +     struct resource_entry *win;
>> +     int offset = 0;
>> +
>> +     err = of_pci_get_host_bridge_resources(np, 0, 0xff, &pcie->resources,
>> +                                            &iobase);
>> +     if (err)
>> +             return err;
>> +
>> +     resource_list_for_each_entry(win, &pcie->resources) {
>> +             struct resource *parent, *res = win->res;
>> +
>> +             switch (resource_type(res)) {
>> +             case IORESOURCE_MEM:
>> +                     parent = &iomem_resource;
>> +                     res_valid |= !(res->flags & IORESOURCE_PREFETCH);
>> +                     cra_writel(pcie, res->start,
>> +                             A2P_ADDR_MAP_LO0 + offset);
>> +                     cra_writel(pcie, 0,
>> +                             A2P_ADDR_MAP_HI0 + offset);
>> +                     offset += ATT_ENTRY_SIZE;
>> +                     break;
>> +             default:
>> +                     continue;
>> +             }
>> +
>> +             err = devm_request_resource(dev, parent, res);
>> +             if (err)
>> +                     goto out_release_res;
>> +     }
>> +
>> +     if (!res_valid) {
>> +             dev_err(dev, "non-prefetchable memory resource required\n");
>> +             err = -EINVAL;
>> +             goto out_release_res;
>> +     }
>> +
>> +     return 0;
>> +
>> +out_release_res:
>> +     altera_pcie_release_of_pci_ranges(pcie);
>> +     return err;
>> +}
>> +
>> +static void altera_pcie_free_irq_domain(struct altera_pcie *pcie)
>> +{
>> +     int i;
>> +     u32 irq;
>> +
>> +     for (i = 0; i < INTX_NUM; i++) {
>> +             irq = irq_find_mapping(pcie->irq_domain, i);
>> +             if (irq > 0)
>> +                     irq_dispose_mapping(irq);
>> +     }
>> +
>> +     irq_domain_remove(pcie->irq_domain);
>> +}
>> +
>> +static int altera_pcie_init_irq_domain(struct altera_pcie *pcie)
>> +{
>> +     struct device *dev = &pcie->pdev->dev;
>> +     struct device_node *node = dev->of_node;
>> +
>> +     /* Setup INTx */
>> +     pcie->irq_domain = irq_domain_add_linear(node, INTX_NUM,
>> +                                     &intx_domain_ops, pcie);
>> +     if (!pcie->irq_domain) {
>> +             dev_err(dev, "Failed to get a INTx IRQ domain\n");
>> +             return PTR_ERR(pcie->irq_domain);
>> +     }
>> +
>> +     return 0;
>> +}
>> +
>> +static int altera_pcie_parse_dt(struct altera_pcie *pcie)
>> +{
>> +     struct resource *cra;
>> +     int ret;
>> +     struct platform_device *pdev = pcie->pdev;
>> +
>> +     cra = platform_get_resource_byname(pdev, IORESOURCE_MEM, "Cra");
>> +     pcie->cra_base = devm_ioremap_resource(&pdev->dev, cra);
>> +     if (IS_ERR(pcie->cra_base)) {
>> +             dev_err(&pdev->dev, "get Cra resource failed\n");
>> +             return PTR_ERR(pcie->cra_base);
>> +     }
>> +
>> +     /* setup IRQ */
>> +     pcie->hwirq = platform_get_irq(pdev, 0);
>> +     if (pcie->hwirq <= 0) {
>
> This is definitely not a hardware interrupt number. It is completely
> virtual. I suggest you give it a better name.
Noted.

>
>> +             dev_err(&pdev->dev, "failed to get IRQ: %d\n", pcie->hwirq);
>> +             return -EINVAL;
>> +     }
>> +     ret = devm_request_irq(&pdev->dev, pcie->hwirq, altera_pcie_isr,
>> +                     IRQF_SHARED, pdev->name, pcie);
>
> You're implementing a cascading interrupt controller again. Please fix
> it just like you did for your MSI support.
Sure, will change to irq_set_chained_handler_and_data here.


Thanks for reviewing.

Regards
Ley Foon


From albert.aribaud at 3adev.fr  Mon Aug  3 03:35:41 2015
From: albert.aribaud at 3adev.fr (Albert ARIBAUD)
Date: Mon, 3 Aug 2015 12:35:41 +0200
Subject: [PATCH v10 0/5] mtd: nand: vf610_nfc: Freescale NFC for VF610
In-Reply-To: <1438594050-4595-1-git-send-email-stefan@agner.ch>
References: <1438594050-4595-1-git-send-email-stefan@agner.ch>
Message-ID: <20150803123541.54d4228e.albert.aribaud@3adev.fr>

Hi Stefan,

Le Mon,  3 Aug 2015 11:27:25 +0200, Stefan Agner <stefan at agner.ch> a
?crit :

> The 10th revision includes some more review comments, including an
> improved handling of empty NAND pages with hardware ECC.
> 
> More information and the full test log of earlier patchset version
> can be found in the cover letter of the last revision v6:
> http://thread.gmane.org/gmane.linux.kernel/1979868
> 
> Changes since v9:
> - Remove inline of vf610_nfc_done
> - Add __iomem to src argument of vf610_nfc_memcpy
> - Handle return value of mtd_device_parse_register correctly
> - Count bits in OOB too (only non-ECC bits)
> - Return bitflips in ecc.read_page callback vf610_nfc_read_page
> - Fall-through ALT_BUF_ONFI
> - Use BIT macros
> 
> Changes since v8:
> - Fix 16-Bit NAND flash support by splitting up initialization
>   (introduce vf610_nfc_preinit_controller)
> - Updated comments in initialziation functions
> 
> Changes since v7:
> - vf610-twr.dts: Moved NFC pinmux into the existing iomuxc node
>   and sort new nfc node behind the existing iomuxc node as well.
> - vf610-twr.dts/vf-colibri.dtsi: Dropped _1 suffixes
> 
> Changes since v6:
> - Rebased ontop of l2-mtd/master (v4.2-rc1 based)
> - Removed HAVE_NAND_VF610_NFC and use depends on. This made
>   "[PATCH v6 4/6] ARM: vf610: enable NAND Flash Controller" unnecessary
> 
> Changes since v5:
> - Removed fsl,mpc5125-nfc compatible string
> - Removed readl/writel_relaxed
> - Change interface of vf610_nfc_transfer_size to match other accessors
> 
> Changes since v4:
> - Rebased ontop of l2-mtd/master (v4.1-rc4 based)
> - Eliminate unnecessary page read (NAND_CMD_SEQIN) since the driver does
>   not support sub-page writes anyway (improves write performance)
> - Support ONFI by enabling READID command with offset and parameter page
>   reads (CMD_PARAM)
> - Change to dedicated read_page/write_page function, enables raw writes
> - Use __LITTLE_ENDIAN to distingush between LE/BE relevant statements
> - Eliminated vf610_nfc_probe_dt in favor of common DT init code
> - Use wait_for_completion_timeout
> - Some style fixes (spaces, etc.)
> 
> Changes since v3:
> - Make the driver selectable when COMPILE_TEST is set
> - Fix compile error due to superfluous ECC_STATUS configuration in initial
>   patch (without ECC correction ECC_STATUS does not need to be configured)
> - Remove custom BBT pattern and switch to in-band BBT in the initial patch
> - Include two bug fixes, for details see the corresponding U-Boot patches:
>   http://thread.gmane.org/gmane.comp.boot-loaders.u-boot/215802
> 
> Changes since v2:
> - Updated binding documentation
> 
> Changes since v1:
> - Nest nfc_config struct within the main nfc struct
> - Use assigned clock binding to specify NFC clock
> - Rebased ontop of MSCM IR patchset (driver parts have been merged)
> - Split out arch Kconfig in a separate config
> - Fix module license
> - Updated MAINTAINERS
> 
> Changes since RFC (Bill Pringlemeir):
> - Renamed driver from fsl_nfc to vf610_nfc
> - Use readl/writel for all register in accessor functions
> - Optimized field accessor functions
> - Implemented PM (suspend/resume) functions
> - Implemented basic support for ECC strength/ECC step size from dt
> - Improved performance of count_written_bits by using hweight32
> - Support ECC with 60-bytes to correct up to 32 bit errors
> - Changed to in-band BBT (NAND_BBT_NO_OOB) which also allows ECC modes
>   which uses up to 60 bytes on 64 byte OOB
> - Removed custom (downstream) BBT pattern since BBT table won't be
>   compatible anyway (due to the change above)

For the sake of regression testing:

Tested-by: Albert ARIBAUD <albert.aribaud at 3adev.fr>

Still works fine here on a Vybrid and 16-bit Micron NAND.

Cordialement,
Albert ARIBAUD
3ADEV


From b.zolnierkie at samsung.com  Mon Aug  3 03:36:14 2015
From: b.zolnierkie at samsung.com (Bartlomiej Zolnierkiewicz)
Date: Mon, 03 Aug 2015 12:36:14 +0200
Subject: [PATCH v3 3/5] ARM: Exynos: switch to using generic cpufreq driver
 for Exynos4x12
In-Reply-To: <20150803102926.GA21529@linux>
References: <1438368557-2352-1-git-send-email-b.zolnierkie@samsung.com>
 <5201904.0cZWHobiJs@amdc1976> <20150803102926.GA21529@linux>
Message-ID: <4532306.AVvo5hem3c@amdc1976>

On Monday, August 03, 2015 03:59:26 PM Viresh Kumar wrote:
> On 03-08-15, 12:17, Bartlomiej Zolnierkiewicz wrote:
> > 
> > Hi,
> > 
> > On Saturday, August 01, 2015 04:47:21 PM Viresh Kumar wrote:
> > > On 31-07-15, 20:49, Bartlomiej Zolnierkiewicz wrote:
> > > > diff --git a/drivers/cpufreq/Kconfig b/drivers/cpufreq/Kconfig
> > > > index 659879a..bf6d596 100644
> > > > --- a/drivers/cpufreq/Kconfig
> > > > +++ b/drivers/cpufreq/Kconfig
> > > > @@ -191,6 +191,7 @@ config CPUFREQ_DT
> > > >  	# if CPU_THERMAL is on and THERMAL=m, CPUFREQ_DT cannot be =y:
> > > >  	depends on !CPU_THERMAL || THERMAL
> > > >  	select PM_OPP
> > > > +	select EXYNOS_THERMAL if ARCH_EXYNOS
> > > >  	help
> > > >  	  This adds a generic DT based cpufreq driver for frequency management.
> > > >  	  It supports both uniprocessor (UP) and symmetric multiprocessor (SMP)
> > > 
> > > No, we shouldn't pollute generic Kconfig options with platform specific stuff.
> > 
> > The old code depended on this.  You couldn't enable boost support
> > without enabling thermal support (ARM_EXYNOS_CPU_FREQ_BOOST_SW
> > config option selected EXYNOS_THERMAL).
> > 
> > > Why don't you enable thermal in your .config?
> > 
> > It is enabled in exynos_defconfig but without the above change it
> > can disabled manually which is something that we don't want.
> 
> You are not getting it. I am not asking you to not select thermal, but
> to select it from within your architecture Kconfig option if you want.

OK.  Krzysztof/Kukjin do you agree with selecting EXYNOS_THERMAL
from ARCH_EXYNOS in the platform code?

> Over that, thermal is really an option, not a dependency. So, if
> someone manually disables it, its his problem not yours :)

I would really like it to be dependency not an option (+ I think
that ideally it should be checked at runtime, IOW we should be
checking from cpufreq-dt driver if the thermal support is enabled
before enabling boost support).

Best regards,
--
Bartlomiej Zolnierkiewicz
Samsung R&D Institute Poland
Samsung Electronics



From lftan at altera.com  Mon Aug  3 03:37:30 2015
From: lftan at altera.com (Ley Foon Tan)
Date: Mon, 3 Aug 2015 18:37:30 +0800
Subject: [PATCH v2 3/5] pci: altera: Add Altera PCIe MSI driver
In-Reply-To: <55BB6621.9060505@arm.com>
References: <1438337715-22594-1-git-send-email-lftan@altera.com>
 <1438337715-22594-4-git-send-email-lftan@altera.com>
 <55BB6621.9060505@arm.com>
Message-ID: <CAFiDJ5-5eZEBFwbuzrPB+XKX_E2Fd0qEeP-_H3Wz2jT8pcbJfQ@mail.gmail.com>

On Fri, Jul 31, 2015 at 8:12 PM, Marc Zyngier <marc.zyngier at arm.com> wrote:
> On 31/07/15 11:15, Ley Foon Tan wrote:
>> This patch adds Altera PCIe MSI driver. This soft IP supports configurable
>> number of vectors, which is a dts parameter.
>
> I've reviewed the initial drop of this code; basic courtesy would be to
> keep me CCed on the follow-up series.
Will keep you in CC for the following revision. Sorry about this.

>>
>> Signed-off-by: Ley Foon Tan <lftan at altera.com>
>> ---
>>  drivers/pci/host/Kconfig           |   7 +
>>  drivers/pci/host/Makefile          |   1 +
>>  drivers/pci/host/pcie-altera-msi.c | 324 +++++++++++++++++++++++++++++++++++++
>>  3 files changed, 332 insertions(+)
>>  create mode 100644 drivers/pci/host/pcie-altera-msi.c
>>
>> diff --git a/drivers/pci/host/Kconfig b/drivers/pci/host/Kconfig
>> index 108500a..51d0468 100644
>> --- a/drivers/pci/host/Kconfig
>> +++ b/drivers/pci/host/Kconfig
>> @@ -153,4 +153,11 @@ config PCIE_ALTERA
>>         Say Y here if you want to enable PCIe controller support for Altera
>>         SoCFPGA family of SoCs.
>>
>> +config PCIE_ALTERA_MSI
>> +     bool "Altera PCIe MSI feature"
>> +     depends on PCI_MSI
>> +     help
>> +       Say Y here if you want PCIe MSI support for the Altera SocFPGA SoC.
>> +       This MSI driver supports Altera MSI to GIC controller IP.
>> +
>>  endmenu
>> diff --git a/drivers/pci/host/Makefile b/drivers/pci/host/Makefile
>> index 6954f76..6c4913d 100644
>> --- a/drivers/pci/host/Makefile
>> +++ b/drivers/pci/host/Makefile
>> @@ -18,3 +18,4 @@ obj-$(CONFIG_PCIE_IPROC) += pcie-iproc.o
>>  obj-$(CONFIG_PCIE_IPROC_PLATFORM) += pcie-iproc-platform.o
>>  obj-$(CONFIG_PCIE_IPROC_BCMA) += pcie-iproc-bcma.o
>>  obj-$(CONFIG_PCIE_ALTERA) += pcie-altera.o
>> +obj-$(CONFIG_PCIE_ALTERA_MSI) += pcie-altera-msi.o
>> diff --git a/drivers/pci/host/pcie-altera-msi.c b/drivers/pci/host/pcie-altera-msi.c
>> new file mode 100644
>> index 0000000..6014719
>> --- /dev/null
>> +++ b/drivers/pci/host/pcie-altera-msi.c
>> @@ -0,0 +1,324 @@
>> +/*
>> + * Copyright Altera Corporation (C) 2013-2015. All rights reserved
>> + *
>> + * This program is free software; you can redistribute it and/or modify it
>> + * under the terms and conditions of the GNU General Public License,
>> + * version 2, as published by the Free Software Foundation.
>> + *
>> + * This program is distributed in the hope 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.
>> + *
>> + * You should have received a copy of the GNU General Public License along with
>> + * this program.  If not, see <http://www.gnu.org/licenses/>.
>> + */
>> +#include <linux/interrupt.h>
>> +#include <linux/irqchip/chained_irq.h>
>> +#include <linux/module.h>
>> +#include <linux/msi.h>
>> +#include <linux/of_address.h>
>> +#include <linux/of_irq.h>
>> +#include <linux/of_pci.h>
>> +#include <linux/pci.h>
>> +#include <linux/platform_device.h>
>> +#include <linux/slab.h>
>> +
>> +#define MSI_STATUS           0x0
>> +#define MSI_ERROR            0x4
>> +#define MSI_INTMASK          0x8
>> +
>> +#define MAX_MSI_VECTORS              32
>> +struct altera_msi {
>> +     DECLARE_BITMAP(used, MAX_MSI_VECTORS);
>> +     struct mutex            lock;   /* proctect used variable */
>> +     struct platform_device  *pdev;
>> +     struct irq_domain               *msi_domain;
>> +     struct irq_domain               *inner_domain;
>> +     void __iomem            *csr_base;
>> +     void __iomem            *vector_base;
>> +     phys_addr_t             vector_phy;
>> +     u32                     num_of_vectors;
>> +     int                     irq;
>> +};
>> +
>> +static inline void msi_writel(struct altera_msi *msi, u32 value, u32 reg)
>> +{
>> +     writel_relaxed(value, msi->csr_base + reg);
>> +}
>> +
>> +static inline u32 msi_readl(struct altera_msi *msi, u32 reg)
>> +{
>> +     return readl_relaxed(msi->csr_base + reg);
>> +}
>> +
>> +static void altera_msi_isr(unsigned int irq, struct irq_desc *desc)
>> +{
>> +     struct irq_chip *chip = irq_desc_get_chip(desc);
>> +     struct altera_msi *msi;
>> +     unsigned long status;
>> +     u32 num_of_vectors;
>> +     u32 bit;
>> +
>> +     chained_irq_enter(chip, desc);
>> +     msi = irq_desc_get_handler_data(desc);
>> +     num_of_vectors = msi->num_of_vectors;
>> +
>> +     do {
>> +             status = msi_readl(msi, MSI_STATUS);
>> +             if (!status)
>> +                     break;
>> +
>> +             do {
>> +                     bit = find_first_bit(&status, num_of_vectors);
>> +                     /* Dummy read from vector to clear the interrupt */
>> +                     readl_relaxed(msi->vector_base + (bit * sizeof(u32)));
>> +
>> +                     irq = irq_find_mapping(msi->inner_domain, bit);
>
> Use of irq is a bit confusing, as this is a parameter describing the
> chaining interrupt. Consider using a different name for this variable.
Okay, will change it to 'virq'.

>
>> +                     if (irq) {
>> +                             if (test_bit(bit, msi->used))
>> +                                     generic_handle_irq(irq);
>> +                             else
>> +                                     dev_info(&msi->pdev->dev, "unhandled MSI\n");
>> +                     } else
>> +                             dev_info(&msi->pdev->dev, "unexpected MSI\n");
>
> The whole statement could be rewritten as:
>
> if (irq && test_bit(bit, msi->used))
>         generic_handle_irq(irq);
> else
>         dev_err(...);
>
> In all cases, this is a grave error, so dev_info is not appropriate here.
Noted.

>
>> +
>> +                     /* Clear the bit from status and repeat without reading
>> +                      * again status register. */
>> +                     clear_bit(bit, &status);
>
> You don't need an atomic operation here, so __clear_bit() should be enough.
Noted.

>
>> +             } while (status);
>> +     } while (1);
>> +
>> +     chained_irq_exit(chip, desc);
>> +}
>> +
>> +static struct irq_chip altera_msi_irq_chip = {
>> +     .name = "Altera PCIe MSI",
>> +     .irq_enable = pci_msi_unmask_irq,
>> +     .irq_disable = pci_msi_mask_irq,
>> +     .irq_mask = pci_msi_mask_irq,
>> +     .irq_unmask = pci_msi_unmask_irq,
>> +};
>> +
>> +static struct msi_domain_info altera_msi_domain_info = {
>> +     .flags  = (MSI_FLAG_USE_DEF_DOM_OPS | MSI_FLAG_USE_DEF_CHIP_OPS |
>> +                  MSI_FLAG_PCI_MSIX),
>> +     .chip   = &altera_msi_irq_chip,
>> +};
>> +
>> +static void altera_compose_msi_msg(struct irq_data *data, struct msi_msg *msg)
>> +{
>> +     u32 mask;
>> +     struct altera_msi *msi = irq_data_get_irq_chip_data(data);
>> +     u64 addr = msi->vector_phy + (data->hwirq * sizeof(u32));
>
> Use phys_addr_t.
Noted.

>
>> +
>> +     msg->address_lo = lower_32_bits(addr);
>> +     msg->address_hi = upper_32_bits(addr);
>> +     msg->data = data->hwirq;
>> +
>> +     mask = msi_readl(msi, MSI_INTMASK);
>> +     mask |= 1 << data->hwirq;
>> +     msi_writel(msi, mask, MSI_INTMASK);
>
> It feels a bit weird to unmask the interrupt when you compose the
> message. I'd expect this to be done in the mask/unmask methods.
Do you refer to these 2 callbacks?
.irq_mask = pci_msi_mask_irq,
.irq_unmask = pci_msi_unmask_irq,

How about we move this INTMASK code above to altera_irq_domain_alloc()?
We have unmask code in altera_irq_domain_free() now.

>
>> +     dev_dbg(&msi->pdev->dev, "msi#%d address_lo 0x%x\n", (int)data->hwirq,
>> +             msg->address_lo);
>
> You may want to print the whole address here.
Noted.

>
>> +}
>> +
>> +static int altera_msi_set_affinity(struct irq_data *irq_data,
>> +                              const struct cpumask *mask, bool force)
>> +{
>> +      return -EINVAL;
>> +}
>> +
>> +static struct irq_chip altera_msi_bottom_irq_chip = {
>> +     .name                   = "Altera MSI",
>> +     .irq_compose_msi_msg    = altera_compose_msi_msg,
>> +     .irq_set_affinity       = altera_msi_set_affinity,
>> +};
>> +
>> +static int altera_irq_domain_alloc(struct irq_domain *domain, unsigned int virq,
>> +                               unsigned int nr_irqs, void *args)
>> +{
>> +     struct altera_msi *msi = domain->host_data;
>> +     int bit;
>> +
>> +     mutex_lock(&msi->lock);
>> +
>> +     bit = find_first_zero_bit(msi->used, msi->num_of_vectors);
>> +     if (bit < msi->num_of_vectors)
>> +             set_bit(bit, msi->used);
>> +
>> +     mutex_unlock(&msi->lock);
>> +
>> +     if (bit < 0)
>> +             return bit;
>
> How can "bit" be negative here? find_first_zero_bit returns an unsigned
> long... You probably want to change the type of "bit" to reflect that.
Okay, will change to "unsigned long" type.
>
>> +     else if (bit >= msi->num_of_vectors)
>
> Useless "else" anyway.

I think we still need to check for failing case, if we don't have
available unused bit.
This could be rewritten  as below:

bit = find_first_zero_bit(msi->used, msi->num_of_vectors);
if (bit < msi->num_of_vectors)
      set_bit(bit, msi->used);
else
      return -ENOSPC;

>
>> +             return -ENOSPC;
>> +
>> +     irq_domain_set_info(domain, virq, bit, &altera_msi_bottom_irq_chip,
>> +                         domain->host_data, handle_simple_irq,
>> +                         NULL, NULL);
>> +     set_irq_flags(virq, IRQF_VALID);
>> +
>> +     return 0;
>> +}
>> +
>> +static void altera_irq_domain_free(struct irq_domain *domain,
>> +                               unsigned int virq, unsigned int nr_irqs)
>> +{
>> +     struct irq_data *d = irq_domain_get_irq_data(domain, virq);
>> +     struct altera_msi *msi = irq_data_get_irq_chip_data(d);
>> +     u32 mask;
>> +
>> +     mutex_lock(&msi->lock);
>> +
>> +     if (!test_bit(d->hwirq, msi->used))
>> +             dev_err(&msi->pdev->dev, "trying to free unused MSI#%lu\n",
>> +             d->hwirq);
>
> Put this statement in { } so that it matches the "else" construct.
Noted.

>
>> +     else {
>> +             clear_bit(d->hwirq, msi->used);
>
> No need for an atomic operation here, you own the mutex.
Okay, change to __clear_bit.


>
>> +             mask = msi_readl(msi, MSI_INTMASK);
>> +             mask &= ~(1 << d->hwirq);
>> +             msi_writel(msi, mask, MSI_INTMASK);
>> +     }
>> +
>> +     mutex_unlock(&msi->lock);
>> +}
>> +
>> +static const struct irq_domain_ops msi_domain_ops = {
>> +     .alloc  = altera_irq_domain_alloc,
>> +     .free   = altera_irq_domain_free,
>> +};
>> +
>> +static int altera_allocate_domains(struct altera_msi *msi)
>> +{
>> +     msi->inner_domain = irq_domain_add_linear(NULL, msi->num_of_vectors,
>> +                                          &msi_domain_ops, msi);
>> +     if (!msi->inner_domain) {
>> +             dev_err(&msi->pdev->dev, "failed to create IRQ domain\n");
>> +             return -ENOMEM;
>> +     }
>> +
>> +     msi->msi_domain = pci_msi_create_irq_domain(
>> +                             msi->pdev->dev.of_node,
>
> Please put at least one argument to the function on the same line. This
> is otherwise very hard to read.
Okay.

>
>> +                             &altera_msi_domain_info, msi->inner_domain);
>> +     if (!msi->msi_domain) {
>> +             dev_err(&msi->pdev->dev, "failed to create MSI domain\n");
>> +             irq_domain_remove(msi->inner_domain);
>> +             return -ENOMEM;
>> +     }
>> +
>> +     return 0;
>> +}
>> +
>> +static void altera_free_domains(struct altera_msi *msi)
>> +{
>> +     irq_domain_remove(msi->msi_domain);
>> +     irq_domain_remove(msi->inner_domain);
>> +}
>> +
>> +
>> +static int altera_msi_remove(struct platform_device *pdev)
>> +{
>> +     struct altera_msi *msi = platform_get_drvdata(pdev);
>> +
>> +     msi_writel(msi, 0, MSI_INTMASK);
>> +     irq_set_chained_handler(msi->irq, NULL);
>> +     irq_set_handler_data(msi->irq, NULL);
>> +
>> +     altera_free_domains(msi);
>> +
>> +     platform_set_drvdata(pdev, NULL);
>> +     return 0;
>> +}
>> +
>> +int altera_msi_probe(struct platform_device *pdev)
>
> Make this static.
Okay.

>
>> +{
>> +     struct altera_msi *msi;
>> +     struct device_node *np = pdev->dev.of_node;
>> +     struct resource *res;
>> +     int ret;
>> +
>> +     msi = devm_kzalloc(&pdev->dev, sizeof(struct altera_msi),
>> +             GFP_KERNEL);
>> +     if (!msi)
>> +             return -ENOMEM;
>> +
>> +     mutex_init(&msi->lock);
>> +     msi->pdev = pdev;
>> +
>> +     res = platform_get_resource_byname(pdev, IORESOURCE_MEM, "csr");
>> +     msi->csr_base = devm_ioremap_resource(&pdev->dev, res);
>> +     if (IS_ERR(msi->csr_base)) {
>> +             dev_err(&pdev->dev, "get csr resource failed\n");
>> +             return PTR_ERR(msi->csr_base);
>> +     }
>> +
>> +     res = platform_get_resource_byname(pdev, IORESOURCE_MEM,
>> +                     "vector_slave");
>> +     msi->vector_base = devm_ioremap_resource(&pdev->dev, res);
>> +     if (IS_ERR(msi->vector_base)) {
>> +             dev_err(&pdev->dev, "get vector slave resource failed\n");
>> +             return PTR_ERR(msi->vector_base);
>> +     }
>> +
>> +     msi->vector_phy = res->start;
>> +
>> +     if (of_property_read_u32(np, "num-vectors", &msi->num_of_vectors)) {
>> +             dev_err(&pdev->dev, "failed to parse the number of vectors\n");
>> +             return -EINVAL;
>> +     }
>> +
>> +     ret = altera_allocate_domains(msi);
>> +     if (ret)
>> +             return ret;
>> +
>> +     msi->irq = platform_get_irq(pdev, 0);
>> +     if (msi->irq <= 0) {
>> +             dev_err(&pdev->dev, "failed to map IRQ: %d\n", msi->irq);
>> +             ret = -ENODEV;
>> +             goto err;
>> +     }
>> +
>> +     irq_set_chained_handler(msi->irq, altera_msi_isr);
>> +     ret = irq_set_handler_data(msi->irq, msi);
>
> Use irq_set_chained_handler_and_data.
Okay.

>
>> +     if (ret) {
>> +             dev_err(&pdev->dev, "failed to register IRQ handler: %d\n",
>> +                     ret);
>> +             goto err;
>> +     }
>> +
>> +     platform_set_drvdata(pdev, msi);
>> +
>> +     return 0;
>> +
>> +err:
>> +     altera_msi_remove(pdev);
>> +     return ret;
>> +}
>> +
>> +static const struct of_device_id altera_msi_of_match[] = {
>> +     { .compatible = "altr,msi-1.0", NULL },
>> +     { },
>> +};
>> +MODULE_DEVICE_TABLE(of, altera_msi_of_match);
>> +
>> +static struct platform_driver altera_msi_driver = {
>> +     .driver = {
>> +             .name = "altera-msi",
>> +             .owner = THIS_MODULE,
>
> Remove this .owner assignment, the core code deals with it.
Okay.

>
>> +             .of_match_table = altera_msi_of_match,
>> +     },
>> +     .probe = altera_msi_probe,
>> +     .remove = altera_msi_remove,
>> +};
>> +
>> +static int __init altera_msi_init(void)
>> +{
>> +     return platform_driver_register(&altera_msi_driver);
>> +}
>> +
>> +subsys_initcall(altera_msi_init);
>
> Hmmm. if you're initializing this as part of the core kernel, it will
> never be a module. What is the point of the MODULE_DEVICE_TABLE above?
Okay, will remove MODULE_DEVICE_TABLE.

Thanks for reviewing.

Regards
Ley Foon


From viresh.kumar at linaro.org  Mon Aug  3 03:40:44 2015
From: viresh.kumar at linaro.org (Viresh Kumar)
Date: Mon, 3 Aug 2015 16:10:44 +0530
Subject: [PATCH v3 3/5] ARM: Exynos: switch to using generic cpufreq
 driver for Exynos4x12
In-Reply-To: <4532306.AVvo5hem3c@amdc1976>
References: <1438368557-2352-1-git-send-email-b.zolnierkie@samsung.com>
 <5201904.0cZWHobiJs@amdc1976> <20150803102926.GA21529@linux>
 <4532306.AVvo5hem3c@amdc1976>
Message-ID: <20150803104044.GB21529@linux>

On 03-08-15, 12:36, Bartlomiej Zolnierkiewicz wrote:
> I would really like it to be dependency not an option (+ I think
> that ideally it should be checked at runtime, IOW we should be
> checking from cpufreq-dt driver if the thermal support is enabled
> before enabling boost support).

I don't think boost has any dependency on thermal support. Yeah, it
may be true for your platform but we can't force it. People might have
different algorithms to control boost modes, thermal is just one
option they may look at. For few, enabling boost may not be a thermal
issue, but power. So, they want to allow it only when they want, but
that wouldn't burn their chip.

So, a platform can choose how it wants to have it. :)

-- 
viresh


From marc.zyngier at arm.com  Mon Aug  3 03:44:29 2015
From: marc.zyngier at arm.com (Marc Zyngier)
Date: Mon, 03 Aug 2015 11:44:29 +0100
Subject: [PATCH 1/3] Docs: dt: add generic MSI bindings
In-Reply-To: <20150727094638.GB9169@leverpostej>
References: <1437670365-20704-1-git-send-email-mark.rutland@arm.com>
 <1437670365-20704-2-git-send-email-mark.rutland@arm.com>
 <55B5E5A6.2030509@arm.com> <20150727094638.GB9169@leverpostej>
Message-ID: <55BF460D.3040901@arm.com>

On 27/07/15 10:46, Mark Rutland wrote:
> On Mon, Jul 27, 2015 at 09:02:46AM +0100, Marc Zyngier wrote:
>> Hi Mark,
> 
> Hi,
> 
>> On 23/07/15 17:52, Mark Rutland wrote:
>>> Currently msi-parent is used in a couple of drivers despite being fairly
>>> underspecified. This patch adds a generic binding for MSIs (including
>>> the existing msi-parent property) enabling the description of platform
>>> devices capable of using MSIs.
>>>
>>> While MSIs are primarily distinguished by doorbell and payload, some MSI
>>> controllers (e.g. the GICv3 ITS) also use side-band information
>>> accompanying the write to identify the master which originated the MSI,
>>> to allow for sandboxing. This sideband information is non-probeable and
>>> needs to be described in the DT. Other MSI controllers may have
>>> additional configuration details which need to be described per-master.
>>>
>>> This patch adds a generic msi-parent binding document, extending the
>>> de-facto standard with a new (optional) #msi-cells which can be used to
>>> express any per-master configuration and/or sideband data. This is
>>> sufficient to describe non-hotpluggable devices.
>>>
>>> For busses where sideband data may be derived from some bus-specific
>>> master ID scheme, other properties will be required to describe the
>>> mapping.
>>>
>>> Signed-off-by: Mark Rutland <mark.rutland at arm.com>
>>> ---
>>>  .../bindings/interrupt-controller/msi.txt          | 135 +++++++++++++++++++++
>>>  1 file changed, 135 insertions(+)
>>>  create mode 100644 Documentation/devicetree/bindings/interrupt-controller/msi.txt
>>>
>>> diff --git a/Documentation/devicetree/bindings/interrupt-controller/msi.txt b/Documentation/devicetree/bindings/interrupt-controller/msi.txt
>>> new file mode 100644
>>> index 0000000..c60c034
>>> --- /dev/null
>>> +++ b/Documentation/devicetree/bindings/interrupt-controller/msi.txt
>>> @@ -0,0 +1,135 @@
>>> +This document describes the generic device tree binding for MSI controllers and
>>> +their master(s).
>>> +
>>> +Message Signaled Interrupts (MSIs) are a class of interrupts generated by a
>>> +write to an MMIO address.
>>> +
>>> +MSIs were originally specified by PCI (and are used with PCIe), but may also be
>>> +used with other busses, and hence a mechanism is required to relate devices on
>>> +those busses to the MSI controllers which they are capable of using,
>>> +potentially including additional information.
>>> +
>>> +MSIs are distinguished by some combination of:
>>> +
>>> +- The doorbell (the MMIO address written to).
>>> +  
>>> +  Devices may be configured by software to write to arbitrary doorbells which
>>> +  they can address. An MSI controller may feature a number of doorbells.
>>> +
>>> +- The payload (the value written to the doorbell).
>>> +  
>>> +  Devices may be configured to write an arbitrary payload chosen by software.
>>> +  MSI controllers may have restrictions on permitted payloads.
>>> +
>>> +- Sideband information accompanying the write.
>>> +  
>>> +  Typically this is neither configurable nor probeable, and depends on the path
>>> +  taken through the memory system (i.e. it is a property of the combination of
>>> +  MSI controller and device rather than a property of either in isolation).
>>> +
>>> +
>>> +MSI controllers:
>>> +================
>>> +
>>> +An MSI controller signals interrupts to a CPU when a write is made to an MMIO
>>> +address by some master. An MSI controller may feature a number of doorbells.
>>> +
>>> +Required properties:
>>> +--------------------
>>> +
>>> +- msi-controller: Identifies the node as an MSI controller.
>>> +
>>> +Optional properties:
>>> +--------------------
>>> +
>>> +- #msi-cells: The number of cells in an msi-specifier, required if not zero.
>>> +
>>> +  Typically this will encode information related to sideband data, and will
>>> +  not encode doorbells or payloads as these can be configured dynamically.
>>> +
>>> +  The meaning of the msi-specifier is defined by the device tree binding of
>>> +  the specific MSI controller. 
>>> +
>>> +
>>> +MSI clients
>>> +===========
>>> +
>>> +MSI clients are devices which generate MSIs. For each MSI they wish to
>>> +generate, the doorbell and payload may be configured, though sideband
>>> +information may not be configurable.
>>> +
>>> +Required properties:
>>> +--------------------
>>> +
>>> +- msi-parent: A list of phandle + msi-specifier pairs, one for each MSI
>>> +  controller which the device is capable of using.
>>> +
>>> +  This property is unordered, and MSIs may be allocated from any combination of
>>> +  MSI controllers listed in the msi-parent property.
>>> +
>>> +  If a device has restrictions on the allocation of MSIs, these restrictions
>>> +  must be described with additional properties.
>>> +
>>> +  When #msi-cells is non-zero, busses with an msi-parent will require
>>> +  additional properties to describe the relationship between devices on the bus
>>> +  and the set of MSIs they can potentially generate.
>>> +
>>> +
>>> +Example
>>> +=======
>>> +
>>> +/ {
>>> +	#address-cells = <1>;
>>> +	#size-cells = <1>;
>>> +
>>> +	msi_a: msi-controller at a {
>>> +		reg = <0xa 0xf00>;
>>> +		compatible = "vendor-a,some-controller";
>>> +		msi-controller;
>>> +		/* No sideband data, so #msi-cells omitted */
>>> +	};
>>> +
>>> +	msi_b: msi-controller at b {
>>> +		reg = <0xb 0xf00>;
>>> +		compatible = "vendor-b,another-controller";
>>> +		msi-controller;
>>> +		/* Each device has some unique ID */
>>> +		#msi-cells = <1>;
>>> +	};
>>> +
>>> +	msi_c: msi-controller at c {
>>> +		reg = <0xb 0xf00>;
>>> +		compatible = "vendor-b,another-controller";
>>> +		msi-controller;
>>> +		/* Each device has some unique ID */
>>> +		#msi-cells = <1>;
>>> +	};
>>> +
>>> +	dev at 0 {
>>> +		reg = <0x0 0xf00>;
>>> +		compatible = "vendor-c,some-device";
>>> +
>>> +		/* Can only generate MSIs to msi_a */
>>> +		msi-parent = <&msi_a>;
>>> +	};
>>> +
>>> +	dev at 1 {
>>> +		reg = <0x1 0xf00>;
>>> +		compatible = "vendor-c,some-device";
>>> +
>>> +		/* 
>>> +		 * Can generate MSIs to either A or B.
>>> +		 */
>>> +		msi-parent = <&msi_a>, <&msi_b 0x17>;
>>> +	};
>>> +
>>> +	dev at 2 {
>>> +		reg = <0x2 0xf00>;
>>> +		compatible = "vendor-c,some-device";
>>> +		/*
>>> +		 * Has different IDs at each MSI controller.
>>> +		 * Can generate MSIs to all of the MSI controllers.
>>> +		 */
>>> +		msi-parent = <&msi_a>, <&msi_b 0x17>, <&msi_c 0x53>;
>>> +	};
>>> +};
>>>
>>
>> This looks quite good for the non-PCI stuff. Should you also cover the
>> PCI usage of msi-parent?
> 
> As far as I can tell, the current PCI usage of msi-parent is practically
> identical to the generic usage, with the proviso that the devices under
> a PCI root complex are assumed to be indistinguishable from the root
> complex from the PoV of the MSI controller.
> 
> So I'm not sure what would be relevant to describe here.
> 
>> I'm can't really see the meaning of #msi-cells in that context. Should
>> it be entirely ignored? OR did you have some specific usage in mind?
> 
> It shouldn't be ignored; if the MSI controller has a non-zero #msi-cells
> then it requires that information to operate correctly (e.g. to
> distinguish masters).
> 
> It may simply be that all devices under the root complex are
> indistinguishable from each other, but can be distinguished form other
> devices in the system using the same MSI controller.
> 
> I also imagine that there may be PCI root complexes which signal their
> own management interrupts as MSIs. Such a root complex needs msi-parent
> to describe its relationship with the MSI controller, which is distinct
> from the relationship between its children and the MSI controller.

Looks tortuous, but why not... ;-)

As an aside, the GICv3 ITS part of the non-PCI MSI support which is
queued for 4.3 is using now this binding to find out about the deviceID,
and I believe Ma Jun is going to use this for his mbigen driver.

I also have additional patches for the core code to parse some of the
properties.

Thanks,

	M.

It would be good if we could make some forward progress to merge this
-- 
Jazz is not dead. It just smells funny...


From sudeep.holla at arm.com  Mon Aug  3 03:48:37 2015
From: sudeep.holla at arm.com (Sudeep Holla)
Date: Mon, 03 Aug 2015 11:48:37 +0100
Subject: [PATCH v6 0/8] ARM64: juno: add SCPI mailbox protocol, clock
 and CPUFreq support
In-Reply-To: <20150803101845.GU20890@e106497-lin.cambridge.arm.com>
References: <1438364591-1144-1-git-send-email-sudeep.holla@arm.com>
 <20150803101845.GU20890@e106497-lin.cambridge.arm.com>
Message-ID: <55BF4705.9030300@arm.com>



On 03/08/15 11:18, Liviu Dudau wrote:
> On Fri, Jul 31, 2015 at 06:43:03PM +0100, Sudeep Holla wrote:
>> Hi ARM-SoC guys,
>>
>> It has been on the list for a while and have got all the necessary ACKs.
>> Can you please pull this series for v4.3 ?
>>
>> Regards,
>> Sudeep
>>
>> This patch series adds support for:
>>    1. SCPI(System Control and Power Interface) mailbox protocol driver.
>>       It uses ARM MHU mailbox controller driver on Juno but can work with
>>       any mailbox controllers using standard mailbox APIs
>>    2. Add support for clocks provided by SCP firmware through the SCPI
>>       interface
>>    3. Using the existing arm_big_little cpufreq driver and the newly
>>       added SCPI clock driver, it also adds support for CPU DVFS on
>>       ARM64 JUNO development platforms.
>
> Hi Sudeep,
>
> Is there a branch where I can pull this series from?
>

Yes, you can pull from
git://linux-arm.org/linux-skn.git juno_dvfs

Regards,
Sudeep


From b.zolnierkie at samsung.com  Mon Aug  3 03:47:57 2015
From: b.zolnierkie at samsung.com (Bartlomiej Zolnierkiewicz)
Date: Mon, 03 Aug 2015 12:47:57 +0200
Subject: [PATCH v3 3/5] ARM: Exynos: switch to using generic cpufreq driver
 for Exynos4x12
In-Reply-To: <20150803104044.GB21529@linux>
References: <1438368557-2352-1-git-send-email-b.zolnierkie@samsung.com>
 <4532306.AVvo5hem3c@amdc1976> <20150803104044.GB21529@linux>
Message-ID: <2295533.OBI6Q4a3b9@amdc1976>

On Monday, August 03, 2015 04:10:44 PM Viresh Kumar wrote:
> On 03-08-15, 12:36, Bartlomiej Zolnierkiewicz wrote:
> > I would really like it to be dependency not an option (+ I think
> > that ideally it should be checked at runtime, IOW we should be
> > checking from cpufreq-dt driver if the thermal support is enabled
> > before enabling boost support).
> 
> I don't think boost has any dependency on thermal support. Yeah, it
> may be true for your platform but we can't force it. People might have
> different algorithms to control boost modes, thermal is just one
> option they may look at. For few, enabling boost may not be a thermal
> issue, but power. So, they want to allow it only when they want, but
> that wouldn't burn their chip.

OK, I see your point (I have not thought about power being the boost
limitation previously).

> So, a platform can choose how it wants to have it. :)

I'll re-do this patch.  Thank you.

Best regards,
--
Bartlomiej Zolnierkiewicz
Samsung R&D Institute Poland
Samsung Electronics



From marc.zyngier at arm.com  Mon Aug  3 03:53:36 2015
From: marc.zyngier at arm.com (Marc Zyngier)
Date: Mon, 03 Aug 2015 11:53:36 +0100
Subject: [PATCH v2 3/5] pci: altera: Add Altera PCIe MSI driver
In-Reply-To: <CAFiDJ5-5eZEBFwbuzrPB+XKX_E2Fd0qEeP-_H3Wz2jT8pcbJfQ@mail.gmail.com>
References: <1438337715-22594-1-git-send-email-lftan@altera.com>	<1438337715-22594-4-git-send-email-lftan@altera.com>	<55BB6621.9060505@arm.com>
 <CAFiDJ5-5eZEBFwbuzrPB+XKX_E2Fd0qEeP-_H3Wz2jT8pcbJfQ@mail.gmail.com>
Message-ID: <55BF4830.9050104@arm.com>

On 03/08/15 11:37, Ley Foon Tan wrote:
> On Fri, Jul 31, 2015 at 8:12 PM, Marc Zyngier <marc.zyngier at arm.com> wrote:
>> On 31/07/15 11:15, Ley Foon Tan wrote:
>>> This patch adds Altera PCIe MSI driver. This soft IP supports configurable
>>> number of vectors, which is a dts parameter.
>>
>> I've reviewed the initial drop of this code; basic courtesy would be to
>> keep me CCed on the follow-up series.
> Will keep you in CC for the following revision. Sorry about this.
> 
>>>
>>> Signed-off-by: Ley Foon Tan <lftan at altera.com>
>>> ---
>>>  drivers/pci/host/Kconfig           |   7 +
>>>  drivers/pci/host/Makefile          |   1 +
>>>  drivers/pci/host/pcie-altera-msi.c | 324 +++++++++++++++++++++++++++++++++++++
>>>  3 files changed, 332 insertions(+)
>>>  create mode 100644 drivers/pci/host/pcie-altera-msi.c
>>>

[...]

>>> +
>>> +     msg->address_lo = lower_32_bits(addr);
>>> +     msg->address_hi = upper_32_bits(addr);
>>> +     msg->data = data->hwirq;
>>> +
>>> +     mask = msi_readl(msi, MSI_INTMASK);
>>> +     mask |= 1 << data->hwirq;
>>> +     msi_writel(msi, mask, MSI_INTMASK);
>>
>> It feels a bit weird to unmask the interrupt when you compose the
>> message. I'd expect this to be done in the mask/unmask methods.
> Do you refer to these 2 callbacks?
> .irq_mask = pci_msi_mask_irq,
> .irq_unmask = pci_msi_unmask_irq,
> 
> How about we move this INTMASK code above to altera_irq_domain_alloc()?
> We have unmask code in altera_irq_domain_free() now.

Either you move the mask/unmask code to local irq_mask/irq_unmask
methods (and call pci_msi_(un)mask_irq from there), or you move it
entierely to alloc/free.

Some level of symmetry helps following what is going on in the code.

[...]

>>> +static int altera_irq_domain_alloc(struct irq_domain *domain, unsigned int virq,
>>> +                               unsigned int nr_irqs, void *args)
>>> +{
>>> +     struct altera_msi *msi = domain->host_data;
>>> +     int bit;
>>> +
>>> +     mutex_lock(&msi->lock);
>>> +
>>> +     bit = find_first_zero_bit(msi->used, msi->num_of_vectors);
>>> +     if (bit < msi->num_of_vectors)
>>> +             set_bit(bit, msi->used);
>>> +
>>> +     mutex_unlock(&msi->lock);
>>> +
>>> +     if (bit < 0)
>>> +             return bit;
>>
>> How can "bit" be negative here? find_first_zero_bit returns an unsigned
>> long... You probably want to change the type of "bit" to reflect that.
> Okay, will change to "unsigned long" type.
>>
>>> +     else if (bit >= msi->num_of_vectors)
>>
>> Useless "else" anyway.
> 
> I think we still need to check for failing case, if we don't have
> available unused bit.
> This could be rewritten  as below:
> 
> bit = find_first_zero_bit(msi->used, msi->num_of_vectors);
> if (bit < msi->num_of_vectors)
>       set_bit(bit, msi->used);
> else
>       return -ENOSPC;

The more logical to write this is:

	if (bit >= msi->num_of_vectors)
		return -ENOSPC;

	set_bit(bit, msi->used);

which gets rid of the error case early and streamlines the normal case.

> 
>>
>>> +             return -ENOSPC;
>>> +
>>> +     irq_domain_set_info(domain, virq, bit, &altera_msi_bottom_irq_chip,
>>> +                         domain->host_data, handle_simple_irq,
>>> +                         NULL, NULL);
>>> +     set_irq_flags(virq, IRQF_VALID);
>>> +
>>> +     return 0;
>>> +}

Thanks,

	M.
-- 
Jazz is not dead. It just smells funny...


From lftan at altera.com  Mon Aug  3 04:00:13 2015
From: lftan at altera.com (Ley Foon Tan)
Date: Mon, 3 Aug 2015 19:00:13 +0800
Subject: [PATCH v2 3/5] pci: altera: Add Altera PCIe MSI driver
In-Reply-To: <55BF4830.9050104@arm.com>
References: <1438337715-22594-1-git-send-email-lftan@altera.com>
 <1438337715-22594-4-git-send-email-lftan@altera.com>
 <55BB6621.9060505@arm.com>
 <CAFiDJ5-5eZEBFwbuzrPB+XKX_E2Fd0qEeP-_H3Wz2jT8pcbJfQ@mail.gmail.com>
 <55BF4830.9050104@arm.com>
Message-ID: <CAFiDJ5_WaNwXMppkhbxVakW2UddN29ypxE9dxhnyfEw5iwvmcQ@mail.gmail.com>

On Mon, Aug 3, 2015 at 6:53 PM, Marc Zyngier <marc.zyngier at arm.com> wrote:
> On 03/08/15 11:37, Ley Foon Tan wrote:

>>>> +     msg->address_lo = lower_32_bits(addr);
>>>> +     msg->address_hi = upper_32_bits(addr);
>>>> +     msg->data = data->hwirq;
>>>> +
>>>> +     mask = msi_readl(msi, MSI_INTMASK);
>>>> +     mask |= 1 << data->hwirq;
>>>> +     msi_writel(msi, mask, MSI_INTMASK);
>>>
>>> It feels a bit weird to unmask the interrupt when you compose the
>>> message. I'd expect this to be done in the mask/unmask methods.
>> Do you refer to these 2 callbacks?
>> .irq_mask = pci_msi_mask_irq,
>> .irq_unmask = pci_msi_unmask_irq,
>>
>> How about we move this INTMASK code above to altera_irq_domain_alloc()?
>> We have unmask code in altera_irq_domain_free() now.
>
> Either you move the mask/unmask code to local irq_mask/irq_unmask
> methods (and call pci_msi_(un)mask_irq from there), or you move it
> entierely to alloc/free.
>
> Some level of symmetry helps following what is going on in the code.
Okay, will move it to alloc/free.
>
> [...]
>
>>>> +static int altera_irq_domain_alloc(struct irq_domain *domain, unsigned int virq,
>>>> +                               unsigned int nr_irqs, void *args)
>>>> +{
>>>> +     struct altera_msi *msi = domain->host_data;
>>>> +     int bit;
>>>> +
>>>> +     mutex_lock(&msi->lock);
>>>> +
>>>> +     bit = find_first_zero_bit(msi->used, msi->num_of_vectors);
>>>> +     if (bit < msi->num_of_vectors)
>>>> +             set_bit(bit, msi->used);
>>>> +
>>>> +     mutex_unlock(&msi->lock);
>>>> +
>>>> +     if (bit < 0)
>>>> +             return bit;
>>>
>>> How can "bit" be negative here? find_first_zero_bit returns an unsigned
>>> long... You probably want to change the type of "bit" to reflect that.
>> Okay, will change to "unsigned long" type.
>>>
>>>> +     else if (bit >= msi->num_of_vectors)
>>>
>>> Useless "else" anyway.
>>
>> I think we still need to check for failing case, if we don't have
>> available unused bit.
>> This could be rewritten  as below:
>>
>> bit = find_first_zero_bit(msi->used, msi->num_of_vectors);
>> if (bit < msi->num_of_vectors)
>>       set_bit(bit, msi->used);
>> else
>>       return -ENOSPC;
>
> The more logical to write this is:
>
>         if (bit >= msi->num_of_vectors)
>                 return -ENOSPC;
>
>         set_bit(bit, msi->used);
>
> which gets rid of the error case early and streamlines the normal case.
Yes, will change to this way.

Thanks.

Regards
Ley Foon


From will.deacon at arm.com  Mon Aug  3 04:09:08 2015
From: will.deacon at arm.com (Will Deacon)
Date: Mon, 3 Aug 2015 12:09:08 +0100
Subject: [RFC PATCH V2 00/10] ARM64: Uprobe support added
In-Reply-To: <cover.1434598237.git.panand@redhat.com>
References: <cover.1434598237.git.panand@redhat.com>
Message-ID: <20150803110908.GC10501@arm.com>

On Thu, Jun 18, 2015 at 04:58:47AM +0100, Pratyush Anand wrote:
> These patches have been prepared on top of ARM64 kprobe v7 patches [1].
> Keeping as RFC, because kprobe-v7 still need to be ACKed.

Unfortunately, I've not seen any movement on the kprobes patches recently,
so this is out of the picture for 4.3.

Dave: did you plan to respin your series after Steve's comments on v7?

Will


From pi-cheng.chen at linaro.org  Mon Aug  3 04:13:36 2015
From: pi-cheng.chen at linaro.org (Pi-Cheng Chen)
Date: Mon, 3 Aug 2015 19:13:36 +0800
Subject: [PATCH] clk: mediatek: Export CPU mux clocks for CPU frequency
 control
In-Reply-To: <1436942326-19747-1-git-send-email-pi-cheng.chen@linaro.org>
References: <CAGS+omAa=3W+SZLmFaDD6uJuhXtu2zX12TsvL2etDif+mKkoVA@mail.gmail.com>
 <1436942326-19747-1-git-send-email-pi-cheng.chen@linaro.org>
Message-ID: <20150803111335.GA5165@gmail.com>

On Wed, Jul 15, 2015 at 02:38:46PM +0800, Pi-Cheng Chen wrote:
> From: "pi-cheng.chen" <pi-cheng.chen at linaro.org>
> 
> This patch adds CPU mux clocks which are used by Mediatek cpufreq driver
> for intermediate clock source switching.

Hi Mike and Stephen,

since the MT8173 cpufreq driver is likely going to be merged[1] and we still
need the CPU MUX clocks consumed by MT8173 cpufreq driver, may I have some
comments from you to get this patch moving forwards so that MT8173 cpufreq
driver could work completely?

Or the regmap supported basic clock type[2] is the prefered way?
Thanks.

Best Regards,
Pi-Cheng

[1] http://marc.info/?l=linux-pm&m=143850044118837&w=2
[2] http://marc.info/?l=linux-kernel&m=143835585905028&w=2

> 
> Signed-off-by: Pi-Cheng Chen <pi-cheng.chen at linaro.org>
> Reviewed-by: Daniel Kurtz <djkurtz at chromium.org>
> ---
> Changes in v4:
> - Address comments for v3
> - Rebase to the patch that adds 13mhz clock for MT8173[1]
> 
> Changes in v3:
> - Rebase to 4.2-rc1
> - Fix some issues of v2
> 
> Changes in v2:
> - Remove use of .determine_rate callback
> 
> [1] http://patchwork.kernerl.xyz/patch/6777041/
> ---
>  drivers/clk/mediatek/Makefile          |   2 +-
>  drivers/clk/mediatek/clk-cpumux.c      | 127 +++++++++++++++++++++++++++++++++
>  drivers/clk/mediatek/clk-cpumux.h      |  22 ++++++
>  drivers/clk/mediatek/clk-mt8173.c      |  23 ++++++
>  include/dt-bindings/clock/mt8173-clk.h |   4 +-
>  5 files changed, 176 insertions(+), 2 deletions(-)
>  create mode 100644 drivers/clk/mediatek/clk-cpumux.c
>  create mode 100644 drivers/clk/mediatek/clk-cpumux.h
> 
> diff --git a/drivers/clk/mediatek/Makefile b/drivers/clk/mediatek/Makefile
> index 8e4b2a4..299917a 100644
> --- a/drivers/clk/mediatek/Makefile
> +++ b/drivers/clk/mediatek/Makefile
> @@ -1,4 +1,4 @@
> -obj-y += clk-mtk.o clk-pll.o clk-gate.o
> +obj-y += clk-mtk.o clk-pll.o clk-gate.o clk-cpumux.o
>  obj-$(CONFIG_RESET_CONTROLLER) += reset.o
>  obj-y += clk-mt8135.o
>  obj-y += clk-mt8173.o
> diff --git a/drivers/clk/mediatek/clk-cpumux.c b/drivers/clk/mediatek/clk-cpumux.c
> new file mode 100644
> index 0000000..fb04fe1
> --- /dev/null
> +++ b/drivers/clk/mediatek/clk-cpumux.c
> @@ -0,0 +1,127 @@
> +/*
> + * Copyright (c) 2015 Linaro Ltd.
> + * Author: Pi-Cheng Chen <pi-cheng.chen at linaro.org>
> + *
> + * This program is free software; you can redistribute it and/or modify
> + * it under the terms of the GNU General Public License version 2 as
> + * published by the Free Software Foundation.
> + *
> + * 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/mfd/syscon.h>
> +#include <linux/slab.h>
> +
> +#include "clk-mtk.h"
> +#include "clk-cpumux.h"
> +
> +struct mtk_clk_cpumux {
> +	struct clk_hw	hw;
> +	struct regmap	*regmap;
> +	u32		reg;
> +	u32		mask;
> +	u8		shift;
> +};
> +
> +static inline struct mtk_clk_cpumux *to_clk_mux(struct clk_hw *_hw)
> +{
> +	return container_of(_hw, struct mtk_clk_cpumux, hw);
> +}
> +
> +static u8 clk_cpumux_get_parent(struct clk_hw *hw)
> +{
> +	struct mtk_clk_cpumux *mux = to_clk_mux(hw);
> +	int num_parents = __clk_get_num_parents(hw->clk);
> +	unsigned int val;
> +
> +	regmap_read(mux->regmap, mux->reg, &val);
> +
> +	val >>= mux->shift;
> +	val &= mux->mask;
> +
> +	if (val >= num_parents)
> +		return -EINVAL;
> +
> +	return val;
> +}
> +
> +static int clk_cpumux_set_parent(struct clk_hw *hw, u8 index)
> +{
> +	struct mtk_clk_cpumux *mux = to_clk_mux(hw);
> +	u32 mask, val;
> +
> +	val = index << mux->shift;
> +	mask = mux->mask << mux->shift;
> +
> +	return regmap_update_bits(mux->regmap, mux->reg, mask, val);
> +}
> +
> +static const struct clk_ops clk_cpumux_ops = {
> +	.get_parent = clk_cpumux_get_parent,
> +	.set_parent = clk_cpumux_set_parent,
> +};
> +
> +static struct clk __init *mtk_clk_register_cpumux(const struct mtk_composite *mux,
> +					   struct regmap *regmap)
> +{
> +	struct mtk_clk_cpumux *cpumux;
> +	struct clk *clk;
> +	struct clk_init_data init;
> +
> +	cpumux = kzalloc(sizeof(*cpumux), GFP_KERNEL);
> +	if (!cpumux)
> +		return ERR_PTR(-ENOMEM);
> +
> +	init.name = mux->name;
> +	init.ops = &clk_cpumux_ops;
> +	init.parent_names = mux->parent_names;
> +	init.num_parents = mux->num_parents;
> +	init.flags = mux->flags;
> +
> +	cpumux->reg = mux->mux_reg;
> +	cpumux->shift = mux->mux_shift;
> +	cpumux->mask = BIT(mux->mux_width) - 1;
> +	cpumux->regmap = regmap;
> +	cpumux->hw.init = &init;
> +
> +	clk = clk_register(NULL, &cpumux->hw);
> +	if (IS_ERR(clk))
> +		kfree(cpumux);
> +
> +	return clk;
> +}
> +
> +int __init mtk_clk_register_cpumuxes(struct device_node *node,
> +			      const struct mtk_composite *clks, int num,
> +			      struct clk_onecell_data *clk_data)
> +{
> +	int i;
> +	struct clk *clk;
> +	struct regmap *regmap;
> +
> +	regmap = syscon_node_to_regmap(node);
> +	if (IS_ERR(regmap)) {
> +		pr_err("Cannot find regmap for %s: %ld\n", node->full_name,
> +		       PTR_ERR(regmap));
> +		return PTR_ERR(regmap);
> +	}
> +
> +	for (i = 0; i < num; i++) {
> +		const struct mtk_composite *mux = &clks[i];
> +
> +		clk = mtk_clk_register_cpumux(mux, regmap);
> +		if (IS_ERR(clk)) {
> +			pr_err("Failed to register clk %s: %ld\n",
> +			       mux->name, PTR_ERR(clk));
> +			continue;
> +		}
> +
> +		clk_data->clks[mux->id] = clk;
> +	}
> +
> +	return 0;
> +}
> diff --git a/drivers/clk/mediatek/clk-cpumux.h b/drivers/clk/mediatek/clk-cpumux.h
> new file mode 100644
> index 0000000..52c769f
> --- /dev/null
> +++ b/drivers/clk/mediatek/clk-cpumux.h
> @@ -0,0 +1,22 @@
> +/*
> + * Copyright (c) 2015 Linaro Ltd.
> + * Author: Pi-Cheng Chen <pi-cheng.chen at linaro.org>
> + *
> + * This program is free software; you can redistribute it and/or modify
> + * it under the terms of the GNU General Public License version 2 as
> + * published by the Free Software Foundation.
> + *
> + * 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 __DRV_CLK_CPUMUX_H
> +#define __DRV_CLK_CPUMUX_H
> +
> +int mtk_clk_register_cpumuxes(struct device_node *node,
> +			      const struct mtk_composite *clks, int num,
> +			      struct clk_onecell_data *clk_data);
> +
> +#endif /* __DRV_CLK_CPUMUX_H */
> diff --git a/drivers/clk/mediatek/clk-mt8173.c b/drivers/clk/mediatek/clk-mt8173.c
> index 540c5c3..053ca27 100644
> --- a/drivers/clk/mediatek/clk-mt8173.c
> +++ b/drivers/clk/mediatek/clk-mt8173.c
> @@ -19,6 +19,7 @@
>  
>  #include "clk-mtk.h"
>  #include "clk-gate.h"
> +#include "clk-cpumux.h"
>  
>  #include <dt-bindings/clock/mt8173-clk.h>
>  
> @@ -517,6 +518,25 @@ static const char * const i2s3_b_ck_parents[] __initconst = {
>  	"apll2_div5"
>  };
>  
> +static const char * const ca53_parents[] __initconst = {
> +	"clk26m",
> +	"armca7pll",
> +	"mainpll",
> +	"univpll"
> +};
> +
> +static const char * const ca57_parents[] __initconst = {
> +	"clk26m",
> +	"armca15pll",
> +	"mainpll",
> +	"univpll"
> +};
> +
> +static const struct mtk_composite cpu_muxes[] __initconst = {
> +	MUX(CLK_INFRA_CA53SEL, "infra_ca53_sel", ca53_parents, 0x0000, 0, 2),
> +	MUX(CLK_INFRA_CA57SEL, "infra_ca57_sel", ca57_parents, 0x0000, 2, 2),
> +};
> +
>  static const struct mtk_composite top_muxes[] __initconst = {
>  	/* CLK_CFG_0 */
>  	MUX(CLK_TOP_AXI_SEL, "axi_sel", axi_parents, 0x0040, 0, 3),
> @@ -743,6 +763,9 @@ static void __init mtk_infrasys_init(struct device_node *node)
>  						clk_data);
>  	mtk_clk_register_factors(infra_divs, ARRAY_SIZE(infra_divs), clk_data);
>  
> +	mtk_clk_register_cpumuxes(node, cpu_muxes, ARRAY_SIZE(cpu_muxes),
> +						clk_data);
> +
>  	r = of_clk_add_provider(node, of_clk_src_onecell_get, clk_data);
>  	if (r)
>  		pr_err("%s(): could not register clock provider: %d\n",
> diff --git a/include/dt-bindings/clock/mt8173-clk.h b/include/dt-bindings/clock/mt8173-clk.h
> index fa2a2bb..a17cbaa 100644
> --- a/include/dt-bindings/clock/mt8173-clk.h
> +++ b/include/dt-bindings/clock/mt8173-clk.h
> @@ -188,7 +188,9 @@
>  #define CLK_INFRA_PMICSPI		10
>  #define CLK_INFRA_PMICWRAP		11
>  #define CLK_INFRA_CLK_13M		12
> -#define CLK_INFRA_NR_CLK		13
> +#define CLK_INFRA_CA53SEL		13
> +#define CLK_INFRA_CA57SEL		14
> +#define CLK_INFRA_NR_CLK		15
>  
>  /* PERI_SYS */
>  
> -- 
> 1.9.1
> 


From k.kozlowski at samsung.com  Mon Aug  3 04:15:13 2015
From: k.kozlowski at samsung.com (Krzysztof Kozlowski)
Date: Mon, 03 Aug 2015 20:15:13 +0900
Subject: [PATCH v3 3/5] ARM: Exynos: switch to using generic cpufreq driver
 for Exynos4x12
In-Reply-To: <4532306.AVvo5hem3c@amdc1976>
References: <1438368557-2352-1-git-send-email-b.zolnierkie@samsung.com>
 <5201904.0cZWHobiJs@amdc1976> <20150803102926.GA21529@linux>
 <4532306.AVvo5hem3c@amdc1976>
Message-ID: <55BF4D41.1060903@samsung.com>

W dniu 03.08.2015 o 19:36, Bartlomiej Zolnierkiewicz pisze:
> On Monday, August 03, 2015 03:59:26 PM Viresh Kumar wrote:
>> On 03-08-15, 12:17, Bartlomiej Zolnierkiewicz wrote:
>>>
>>> Hi,
>>>
>>> On Saturday, August 01, 2015 04:47:21 PM Viresh Kumar wrote:
>>>> On 31-07-15, 20:49, Bartlomiej Zolnierkiewicz wrote:
>>>>> diff --git a/drivers/cpufreq/Kconfig b/drivers/cpufreq/Kconfig
>>>>> index 659879a..bf6d596 100644
>>>>> --- a/drivers/cpufreq/Kconfig
>>>>> +++ b/drivers/cpufreq/Kconfig
>>>>> @@ -191,6 +191,7 @@ config CPUFREQ_DT
>>>>>  	# if CPU_THERMAL is on and THERMAL=m, CPUFREQ_DT cannot be =y:
>>>>>  	depends on !CPU_THERMAL || THERMAL
>>>>>  	select PM_OPP
>>>>> +	select EXYNOS_THERMAL if ARCH_EXYNOS
>>>>>  	help
>>>>>  	  This adds a generic DT based cpufreq driver for frequency management.
>>>>>  	  It supports both uniprocessor (UP) and symmetric multiprocessor (SMP)
>>>>
>>>> No, we shouldn't pollute generic Kconfig options with platform specific stuff.
>>>
>>> The old code depended on this.  You couldn't enable boost support
>>> without enabling thermal support (ARM_EXYNOS_CPU_FREQ_BOOST_SW
>>> config option selected EXYNOS_THERMAL).
>>>
>>>> Why don't you enable thermal in your .config?
>>>
>>> It is enabled in exynos_defconfig but without the above change it
>>> can disabled manually which is something that we don't want.
>>
>> You are not getting it. I am not asking you to not select thermal, but
>> to select it from within your architecture Kconfig option if you want.
> 
> OK.  Krzysztof/Kukjin do you agree with selecting EXYNOS_THERMAL
> from ARCH_EXYNOS in the platform code?

I agree, with your explanation it seems good. Can you just add this
justification to the commit message?

> 
>> Over that, thermal is really an option, not a dependency. So, if
>> someone manually disables it, its his problem not yours :)
> 
> I would really like it to be dependency not an option (+ I think
> that ideally it should be checked at runtime, IOW we should be
> checking from cpufreq-dt driver if the thermal support is enabled
> before enabling boost support).

That would be the best. It is fine with me if you want to do this in
consecutive patches (after applying patch selecting/depending on it in
mach-exynos code).

Best regards,
Krzysztof



From gabriele.paoloni at huawei.com  Mon Aug  3 04:18:09 2015
From: gabriele.paoloni at huawei.com (Gabriele Paoloni)
Date: Mon, 3 Aug 2015 11:18:09 +0000
Subject: [PATCH v6] PCI: Store PCIe bus address in struct of_pci_range
In-Reply-To: <CAL_JsqJqjiWVaKs-3ghQ1EBQzRRQ38GzkMV+FELPj53bSF-yXQ@mail.gmail.com>
References: <1438010223-124422-1-git-send-email-gabriele.paoloni@huawei.com>
 <20150729172053.GE31170@google.com>
 <EE11001F9E5DDD47B7634E2F8A612F2E01D6F350@lhreml503-mbs>
 <CAL_JsqKs11-sXQTdBD+ZjbVYFWUHBARTW9q5MF1hCXUhZ+nWLQ@mail.gmail.com>
 <EE11001F9E5DDD47B7634E2F8A612F2E01D6F94A@lhreml503-mbs>
 <20150730161447.GG9640@google.com>
 <EE11001F9E5DDD47B7634E2F8A612F2E01D6FB3B@lhreml503-mbs>
 <20150730171445.GI9640@google.com>
 <EE11001F9E5DDD47B7634E2F8A612F2E01D6FC15@lhreml503-mbs>
 <CAL_Jsq+aQVakaZf4xo7sxnVyTmPR+HJ-9ByyS6OYJ0PHDYOwmg@mail.gmail.com>
 <EE11001F9E5DDD47B7634E2F8A612F2E01D70589@lhreml503-mbs>
 <55BB8CC6.1080203@ti.com>
 <CAL_JsqJqjiWVaKs-3ghQ1EBQzRRQ38GzkMV+FELPj53bSF-yXQ@mail.gmail.com>
Message-ID: <EE11001F9E5DDD47B7634E2F8A612F2E01D712E7@lhreml503-mbs>

Rob, Kishon what about the following solution?....

---
 drivers/pci/host/pci-dra7xx.c      | 12 ++++++++++++
 drivers/pci/host/pcie-designware.c |  9 +++------
 2 files changed, 15 insertions(+), 6 deletions(-)

diff --git a/drivers/pci/host/pci-dra7xx.c b/drivers/pci/host/pci-dra7xx.c
index 80db09e..bb2635f 100644
--- a/drivers/pci/host/pci-dra7xx.c
+++ b/drivers/pci/host/pci-dra7xx.c
@@ -61,6 +61,7 @@
 
 #define	PCIECTRL_DRA7XX_CONF_PHY_CS			0x010C
 #define	LINK_UP						BIT(16)
+#define CPU_TO_BUS_ADDR             0x0FFFFFFF
 
 struct dra7xx_pcie {
 	void __iomem		*base;
@@ -138,6 +139,17 @@ static void dra7xx_pcie_enable_interrupts(struct pcie_port *pp)
 
 static void dra7xx_pcie_host_init(struct pcie_port *pp)
 {
+	if (pp->io_mod_base)
+		pp->io_mod_base &= CPU_TO_BUS_ADDR;
+
+	if (pp->mem_mod_base)
+		pp->mem_mod_base &= CPU_TO_BUS_ADDR;
+
+	if (pp->cfg0_mod_base) {
+		pp->cfg0_mod_base &= CPU_TO_BUS_ADDR;
+		pp->cfg1_mod_base &= CPU_TO_BUS_ADDR;
+	}
+
 	dw_pcie_setup_rc(pp);
 	dra7xx_pcie_establish_link(pp);
 	if (IS_ENABLED(CONFIG_PCI_MSI))
diff --git a/drivers/pci/host/pcie-designware.c b/drivers/pci/host/pcie-designware.c
index 69486be..06c682b 100644
--- a/drivers/pci/host/pcie-designware.c
+++ b/drivers/pci/host/pcie-designware.c
@@ -416,8 +416,7 @@ int dw_pcie_host_init(struct pcie_port *pp)
 			pp->io_base = range.cpu_addr;
 
 			/* Find the untranslated IO space address */
-			pp->io_mod_base = of_read_number(parser.range -
-							 parser.np + na, ns);
+			pp->io_mod_base = range.cpu_addr;;
 		}
 		if (restype == IORESOURCE_MEM) {
 			of_pci_range_to_resource(&range, np, &pp->mem);
@@ -426,8 +425,7 @@ int dw_pcie_host_init(struct pcie_port *pp)
 			pp->mem_bus_addr = range.pci_addr;
 
 			/* Find the untranslated MEM space address */
-			pp->mem_mod_base = of_read_number(parser.range -
-							  parser.np + na, ns);
+			pp->mem_mod_base = range.cpu_addr;
 		}
 		if (restype == 0) {
 			of_pci_range_to_resource(&range, np, &pp->cfg);
@@ -437,8 +435,7 @@ int dw_pcie_host_init(struct pcie_port *pp)
 			pp->cfg1_base = pp->cfg.start + pp->cfg0_size;
 
 			/* Find the untranslated configuration space address */
-			pp->cfg0_mod_base = of_read_number(parser.range -
-							   parser.np + na, ns);
+			pp->cfg0_mod_base = range.cpu_addr;
 			pp->cfg1_mod_base = pp->cfg0_mod_base +
 					    pp->cfg0_size;
 		}
-- 
1.9.1


> -----Original Message-----
> From: linux-pci-owner at vger.kernel.org [mailto:linux-pci-
> owner at vger.kernel.org] On Behalf Of Rob Herring
> Sent: Friday, July 31, 2015 5:53 PM
> To: Kishon Vijay Abraham I
> Cc: Gabriele Paoloni; Bjorn Helgaas; arnd at arndb.de;
> lorenzo.pieralisi at arm.com; Wangzhou (B); robh+dt at kernel.org;
> james.morse at arm.com; Liviu.Dudau at arm.com; linux-pci at vger.kernel.org;
> linux-arm-kernel at lists.infradead.org; devicetree at vger.kernel.org;
> Yuanzhichang; Zhudacai; zhangjukuo; qiuzhenfa; Liguozhu (Kenneth);
> Jingoo Han; Pratyush Anand; Arnd Bergmann
> Subject: Re: [PATCH v6] PCI: Store PCIe bus address in struct
> of_pci_range
> 
> On Fri, Jul 31, 2015 at 9:57 AM, Kishon Vijay Abraham I <kishon at ti.com>
> wrote:
> > +Arnd
> >
> > Hi,
> >
> > On Friday 31 July 2015 07:55 PM, Gabriele Paoloni wrote:
> >> [+cc Kishon]
> >>
> >>> -----Original Message-----
> >>> From: linux-pci-owner at vger.kernel.org [mailto:linux-pci-
> >>> owner at vger.kernel.org] On Behalf Of Rob Herring
> >>> Sent: Thursday, July 30, 2015 9:42 PM
> >>> To: Gabriele Paoloni
> >>> Cc: Bjorn Helgaas; arnd at arndb.de; lorenzo.pieralisi at arm.com;
> Wangzhou
> >>> (B); robh+dt at kernel.org; james.morse at arm.com; Liviu.Dudau at arm.com;
> >>> linux-pci at vger.kernel.org; linux-arm-kernel at lists.infradead.org;
> >>> devicetree at vger.kernel.org; Yuanzhichang; Zhudacai; zhangjukuo;
> >>> qiuzhenfa; Liguozhu (Kenneth); Jingoo Han; Pratyush Anand
> >>> Subject: Re: [PATCH v6] PCI: Store PCIe bus address in struct
> >>> of_pci_range
> >>>
> >>> On Thu, Jul 30, 2015 at 12:34 PM, Gabriele Paoloni
> >>> <gabriele.paoloni at huawei.com> wrote:
> >>>>> -----Original Message-----
> >>>>> From: Bjorn Helgaas [mailto:bhelgaas at google.com]
> >>>>> Sent: 30 July 2015 18:15
> >>>>> On Thu, Jul 30, 2015 at 04:50:55PM +0000, Gabriele Paoloni wrote:
> >>>>>>> -----Original Message-----
> >>>>>>> From: linux-pci-owner at vger.kernel.org [mailto:linux-pci-
> >>>>>>> owner at vger.kernel.org] On Behalf Of Bjorn Helgaas
> >>>>>>> Sent: Thursday, July 30, 2015 5:15 PM
> >>>>>>> On Thu, Jul 30, 2015 at 01:52:13PM +0000, Gabriele Paoloni
> wrote:
> >>>
> >>> [...]
> >>>
> >>>>>>>> I don?t think we should rely on [CPU] addresses...what if the
> >>>>>>> intermediate
> >>>>>>>> translation layer changes the lower significant bits of the
> >>> "bus
> >>>>>>> address"
> >>>>>>>> to translate into a cpu address?
> >>>>>>>
> >>>>>>> Is it really a possiblity that the lower bits could be changed?
> >>>>>>
> >>>>>> I've checked all the current deignware users DTs except "pci-
> >>>>> layerscape"
> >>>>>> that I could not find:
> >>>>>> spear1310.dtsi
> >>>>>> spear1340.dtsi
> >>>>>> dra7.dtsi
> >>>>>> imx6qdl.dtsi
> >>>>>> imx6sx.dtsi
> >>>>>> keystone.dtsi
> >>>>>> exynos5440.dtsi
> >>>>>>
> >>>>>> None of them modifies the lower bits. To be more precise the
> only
> >>> guy
> >>>>>> that provides another translation layer is "dra7.dtsi":
> >>>>>> axi0
> >>>>>> http://lxr.free-
> >>> electrons.com/source/arch/arm/boot/dts/dra7.dtsi#L207
> >>>>>>
> >>>>>> axi1
> >>>>>> http://lxr.free-
> >>> electrons.com/source/arch/arm/boot/dts/dra7.dtsi#L241
> >>>>>>
> >>>>>> For this case masking the top 4bits (bits28 to 31) should make
> the
> >>> job.
> >>>
> >>> IMO, we should just fix this case. After further study, I don't
> think
> >>> this is a DW issue, but rather an SOC integration issue.
> >>>
> >>> I believe you can just fixup the address in the pp->ops->host_init
> hook.
> >>>
> >>
> >> Yes I guess that I could just assign pp->(*)_mod_base to the CPU
> address
> >> in DW and mask it out in dra7xx_pcie_host_init()...
> >>
> >> Kishon, would you be ok with that?
> >
> > Initially I was using *base-mask* property from dt. Me and Arnd
> (cc'ed) had
> > this discussion [1] before we decided the current approach. It'll be
> good to
> > check with Arnd too.
> >
> > [1] ->  http://lists.infradead.org/pipermail/linux-arm-kernel/2014-
> May/253528.html
> 
> The problem I have here is the use of ranges does not necessarily mean
> fewer address bits are available. It can be used just for convenience
> of not putting the full address into every node's reg property. And
> vice versa, there are probably plenty of cases where we have the full
> address in the nodes, but really only some of the address bits are
> decoded at the IP block. Whether the address bits are present is
> rarely cared about or known by s/w folks until you hit a problem like
> this. Given this is an isolated case ATM, I would fix it in an
> isolated way. It does not affect the binding and could be changed in
> the kernel later if this becomes a common need.
> 
> Rob
> --
> To unsubscribe from this list: send the line "unsubscribe linux-pci" in
> the body of a message to majordomo at vger.kernel.org
> More majordomo info at  http://vger.kernel.org/majordomo-info.html

From Liviu.Dudau at arm.com  Mon Aug  3 04:23:53 2015
From: Liviu.Dudau at arm.com (Liviu Dudau)
Date: Mon, 3 Aug 2015 12:23:53 +0100
Subject: [PATCH v6 6/8] arm64: dts: add SRAM, MHU mailbox and SCPI
 support on Juno
In-Reply-To: <1438364591-1144-7-git-send-email-sudeep.holla@arm.com>
References: <1438364591-1144-1-git-send-email-sudeep.holla@arm.com>
 <1438364591-1144-7-git-send-email-sudeep.holla@arm.com>
Message-ID: <20150803112353.GV20890@e106497-lin.cambridge.arm.com>

On Fri, Jul 31, 2015 at 06:43:09PM +0100, Sudeep Holla wrote:
> This patch adds support for the MHU mailbox peripheral used on Juno by
> application processors to communicate with remote SCP handling most of
> the CPU/system power management. It also adds the SRAM reserving the
> shared memory and SCPI message protocol using that shared memory.
> 
> Signed-off-by: Sudeep Holla <sudeep.holla at arm.com>
> Acked-by: Liviu Dudau <Liviu.Dudau at arm.com>
> Cc: Jon Medhurst (Tixy) <tixy at linaro.org>
> ---
>  arch/arm64/boot/dts/arm/juno-base.dtsi | 54 ++++++++++++++++++++++++++++++++++
>  1 file changed, 54 insertions(+)
> 
> diff --git a/arch/arm64/boot/dts/arm/juno-base.dtsi b/arch/arm64/boot/dts/arm/juno-base.dtsi
> index e3ee96036eca..c624208edef6 100644
> --- a/arch/arm64/boot/dts/arm/juno-base.dtsi
> +++ b/arch/arm64/boot/dts/arm/juno-base.dtsi
> @@ -17,6 +17,18 @@
>  		};
>  	};
>  
> +	mailbox: mhu at 2b1f0000 {
> +		compatible = "arm,mhu", "arm,primecell";
> +		reg = <0x0 0x2b1f0000 0x0 0x1000>;
> +		interrupts = <GIC_SPI 36 IRQ_TYPE_LEVEL_HIGH>,
> +			     <GIC_SPI 35 IRQ_TYPE_LEVEL_HIGH>;
> +		interrupt-names = "mhu_lpri_rx",
> +				  "mhu_hpri_rx";
> +		#mbox-cells = <1>;
> +		clocks = <&soc_refclk100mhz>;
> +		clock-names = "apb_pclk";
> +	};
> +
>  	gic: interrupt-controller at 2c010000 {
>  		compatible = "arm,gic-400", "arm,cortex-a15-gic";
>  		reg = <0x0 0x2c010000 0 0x1000>,
> @@ -44,6 +56,48 @@
>  			     <GIC_PPI 10 (GIC_CPU_MASK_SIMPLE(6) | IRQ_TYPE_LEVEL_LOW)>;
>  	};
>  
> +	sram: sram at 2e000000 {
> +		compatible = "arm,juno-sram-ns", "mmio-sram";
> +		reg = <0x0 0x2e000000 0x0 0x8000>;
> +
> +		#address-cells = <1>;
> +		#size-cells = <1>;
> +		ranges = <0 0x0 0x2e000000 0x8000>;
> +
> +		cpu_scp_lpri: scp-shmem at 0 {
> +			compatible = "arm,juno-scp-shmem";
> +			reg = <0x0 0x200>;
> +		};
> +
> +		cpu_scp_hpri: scp-shmem at 200 {
> +			compatible = "arm,juno-scp-shmem";
> +			reg = <0x200 0x200>;
> +		};
> +	};
> +
> +	scpi {
> +		compatible = "arm,scpi";
> +		mboxes = <&mailbox 1>;
> +		shmem = <&cpu_scp_hpri>;
> +
> +		clocks {
> +			compatible = "arm,scpi-clocks";
> +
> +			scpi_dvfs: scpi_clocks at 0 {
> +				compatible = "arm,scpi-dvfs-clocks";
> +				#clock-cells = <1>;
> +				clock-indices = <0>, <1>, <2>;
> +				clock-output-names = "atlclk", "aplclk","gpuclk";
> +			};
> +			scpi_clk: scpi_clocks at 3 {
> +				compatible = "arm,scpi-variable-clocks";
> +				#clock-cells = <1>;
> +				clock-indices = <3>, <4>;
> +				clock-output-names = "pxlclk0", "pxlclk1";
> +			};
> +		};
> +	};
> +

Sorry for noticing this after the ACK, is there any reason why the scpi node is not inside
the juno-clocks.dtsi file?

Best regards,
Liviu

>  	/include/ "juno-clocks.dtsi"
>  
>  	dma at 7ff00000 {
> -- 
> 1.9.1
> 

-- 
====================
| I would like to |
| fix the world,  |
| but they're not |
| giving me the   |
 \ source code!  /
  ---------------
    ?\_(?)_/?



From joro at 8bytes.org  Mon Aug  3 04:33:31 2015
From: joro at 8bytes.org (Joerg Roedel)
Date: Mon, 3 Aug 2015 13:33:31 +0200
Subject: [PATCH 00/18] Clean up exposure of arch-internal code
In-Reply-To: <20150727140905.GA16858@ulmo.nvidia.com>
References: <20150727122824.GH7557@n2100.arm.linux.org.uk>
 <20150727140905.GA16858@ulmo.nvidia.com>
Message-ID: <20150803113331.GG14980@8bytes.org>

Hey Thierry,

On Mon, Jul 27, 2015 at 04:09:06PM +0200, Thierry Reding wrote:
> What's the plan for merging this? Should it all go in through Joerg's
> tree so that potentially other driver conversions can go in on top of
> this, or would you prefer to take it through the ARM tree?

So it would be great if you can work in your review comments and send me
a pull request with the result. I'll put it into the iommu-tree for v4.3
then.


	Joerg



From sudeep.holla at arm.com  Mon Aug  3 04:44:39 2015
From: sudeep.holla at arm.com (Sudeep Holla)
Date: Mon, 03 Aug 2015 12:44:39 +0100
Subject: [PATCH v6 6/8] arm64: dts: add SRAM, MHU mailbox and SCPI support
 on Juno
In-Reply-To: <20150803112353.GV20890@e106497-lin.cambridge.arm.com>
References: <1438364591-1144-1-git-send-email-sudeep.holla@arm.com>
 <1438364591-1144-7-git-send-email-sudeep.holla@arm.com>
 <20150803112353.GV20890@e106497-lin.cambridge.arm.com>
Message-ID: <55BF5427.2010605@arm.com>



On 03/08/15 12:23, Liviu Dudau wrote:
> On Fri, Jul 31, 2015 at 06:43:09PM +0100, Sudeep Holla wrote:
>> This patch adds support for the MHU mailbox peripheral used on Juno by
>> application processors to communicate with remote SCP handling most of
>> the CPU/system power management. It also adds the SRAM reserving the
>> shared memory and SCPI message protocol using that shared memory.
>>
>> Signed-off-by: Sudeep Holla <sudeep.holla at arm.com>
>> Acked-by: Liviu Dudau <Liviu.Dudau at arm.com>
>> Cc: Jon Medhurst (Tixy) <tixy at linaro.org>
>> ---
>>   arch/arm64/boot/dts/arm/juno-base.dtsi | 54 ++++++++++++++++++++++++++++++++++
>>   1 file changed, 54 insertions(+)
>>
>> diff --git a/arch/arm64/boot/dts/arm/juno-base.dtsi b/arch/arm64/boot/dts/arm/juno-base.dtsi
>> index e3ee96036eca..c624208edef6 100644
>> --- a/arch/arm64/boot/dts/arm/juno-base.dtsi
>> +++ b/arch/arm64/boot/dts/arm/juno-base.dtsi
>> @@ -17,6 +17,18 @@
>>   		};
>>   	};
>>
>> +	mailbox: mhu at 2b1f0000 {
>> +		compatible = "arm,mhu", "arm,primecell";
>> +		reg = <0x0 0x2b1f0000 0x0 0x1000>;
>> +		interrupts = <GIC_SPI 36 IRQ_TYPE_LEVEL_HIGH>,
>> +			     <GIC_SPI 35 IRQ_TYPE_LEVEL_HIGH>;
>> +		interrupt-names = "mhu_lpri_rx",
>> +				  "mhu_hpri_rx";
>> +		#mbox-cells = <1>;
>> +		clocks = <&soc_refclk100mhz>;
>> +		clock-names = "apb_pclk";
>> +	};
>> +
>>   	gic: interrupt-controller at 2c010000 {
>>   		compatible = "arm,gic-400", "arm,cortex-a15-gic";
>>   		reg = <0x0 0x2c010000 0 0x1000>,
>> @@ -44,6 +56,48 @@
>>   			     <GIC_PPI 10 (GIC_CPU_MASK_SIMPLE(6) | IRQ_TYPE_LEVEL_LOW)>;
>>   	};
>>
>> +	sram: sram at 2e000000 {
>> +		compatible = "arm,juno-sram-ns", "mmio-sram";
>> +		reg = <0x0 0x2e000000 0x0 0x8000>;
>> +
>> +		#address-cells = <1>;
>> +		#size-cells = <1>;
>> +		ranges = <0 0x0 0x2e000000 0x8000>;
>> +
>> +		cpu_scp_lpri: scp-shmem at 0 {
>> +			compatible = "arm,juno-scp-shmem";
>> +			reg = <0x0 0x200>;
>> +		};
>> +
>> +		cpu_scp_hpri: scp-shmem at 200 {
>> +			compatible = "arm,juno-scp-shmem";
>> +			reg = <0x200 0x200>;
>> +		};
>> +	};
>> +
>> +	scpi {
>> +		compatible = "arm,scpi";
>> +		mboxes = <&mailbox 1>;
>> +		shmem = <&cpu_scp_hpri>;
>> +
>> +		clocks {
>> +			compatible = "arm,scpi-clocks";
>> +
>> +			scpi_dvfs: scpi_clocks at 0 {
>> +				compatible = "arm,scpi-dvfs-clocks";
>> +				#clock-cells = <1>;
>> +				clock-indices = <0>, <1>, <2>;
>> +				clock-output-names = "atlclk", "aplclk","gpuclk";
>> +			};
>> +			scpi_clk: scpi_clocks at 3 {
>> +				compatible = "arm,scpi-variable-clocks";
>> +				#clock-cells = <1>;
>> +				clock-indices = <3>, <4>;
>> +				clock-output-names = "pxlclk0", "pxlclk1";
>> +			};
>> +		};
>> +	};
>> +
>
> Sorry for noticing this after the ACK, is there any reason why the scpi node is not inside
> the juno-clocks.dtsi file?
>

Yes, scpi node will have other nodes like sensors/hwmon. So the whole
scpi node can't sit in juno-clocks. Ideally the clocks belongs to
juno-clocks, but I got troubles with the way the DTSI are includes and
could not keep scpi node in base and just update clocks in
juno-clocks.dtsi. It needs some rework the way include file are used.
It's in my todo and I will look at that when I get time.

Regards,
Sudeep


From tixy at linaro.org  Mon Aug  3 04:46:33 2015
From: tixy at linaro.org (Jon Medhurst (Tixy))
Date: Mon, 03 Aug 2015 12:46:33 +0100
Subject: [PATCH v6 6/8] arm64: dts: add SRAM, MHU mailbox and SCPI
 support on Juno
In-Reply-To: <20150803112353.GV20890@e106497-lin.cambridge.arm.com>
References: <1438364591-1144-1-git-send-email-sudeep.holla@arm.com>
 <1438364591-1144-7-git-send-email-sudeep.holla@arm.com>
 <20150803112353.GV20890@e106497-lin.cambridge.arm.com>
Message-ID: <1438602393.5218.3.camel@linaro.org>

On Mon, 2015-08-03 at 12:23 +0100, Liviu Dudau wrote:
> On Fri, Jul 31, 2015 at 06:43:09PM +0100, Sudeep Holla wrote:
> > This patch adds support for the MHU mailbox peripheral used on Juno by
> > application processors to communicate with remote SCP handling most of
> > the CPU/system power management. It also adds the SRAM reserving the
> > shared memory and SCPI message protocol using that shared memory.
> > 
> > Signed-off-by: Sudeep Holla <sudeep.holla at arm.com>
> > Acked-by: Liviu Dudau <Liviu.Dudau at arm.com>
> > Cc: Jon Medhurst (Tixy) <tixy at linaro.org>
> > ---
> >  arch/arm64/boot/dts/arm/juno-base.dtsi | 54 ++++++++++++++++++++++++++++++++++
> >  1 file changed, 54 insertions(+)
> > 
> > diff --git a/arch/arm64/boot/dts/arm/juno-base.dtsi b/arch/arm64/boot/dts/arm/juno-base.dtsi
> > index e3ee96036eca..c624208edef6 100644
> > --- a/arch/arm64/boot/dts/arm/juno-base.dtsi
> > +++ b/arch/arm64/boot/dts/arm/juno-base.dtsi
[...]
> > +	scpi {
> > +		compatible = "arm,scpi";
> > +		mboxes = <&mailbox 1>;
> > +		shmem = <&cpu_scp_hpri>;
> > +
> > +		clocks {
> > +			compatible = "arm,scpi-clocks";
> > +
> > +			scpi_dvfs: scpi_clocks at 0 {
> > +				compatible = "arm,scpi-dvfs-clocks";
> > +				#clock-cells = <1>;
> > +				clock-indices = <0>, <1>, <2>;
> > +				clock-output-names = "atlclk", "aplclk","gpuclk";
> > +			};
> > +			scpi_clk: scpi_clocks at 3 {
> > +				compatible = "arm,scpi-variable-clocks";
> > +				#clock-cells = <1>;
> > +				clock-indices = <3>, <4>;
> > +				clock-output-names = "pxlclk0", "pxlclk1";
> > +			};
> > +		};
> > +	};
> > +
> 
> Sorry for noticing this after the ACK, is there any reason why the scpi node is not inside
> the juno-clocks.dtsi file?

Because SCPI is not just about clocks? Just happens that these first
patches are but there's thermal sensors and other things as well.

-- 
Tixy



From catalin.marinas at arm.com  Mon Aug  3 05:00:08 2015
From: catalin.marinas at arm.com (Catalin Marinas)
Date: Mon, 3 Aug 2015 13:00:08 +0100
Subject: [PATCH] arm64: dma-mapping: Simplify pgprot handling
In-Reply-To: <a82d2ce0db8d1511ea91bb37ef8432ce33b4719e.1438363644.git.robin.murphy@arm.com>
References: <a82d2ce0db8d1511ea91bb37ef8432ce33b4719e.1438363644.git.robin.murphy@arm.com>
Message-ID: <20150803120007.GD4033@e104818-lin.cambridge.arm.com>

On Fri, Jul 31, 2015 at 06:28:34PM +0100, Robin Murphy wrote:
> Since __get_dma_pgprot() does The Right Thing(TM) in the non-coherent
> case, and the non-cacheable alias for DMA buffers is private to the
> kernel anyway, we can simplify things slightly and make the code more
> readable by just using PAGE_KERNEL as the base pgprot.
> 
> Suggested-by: Catalin Marinas <catalin.marinas at arm.com>
> Signed-off-by: Robin Murphy <robin.murphy at arm.com>
> ---
>  arch/arm64/mm/dma-mapping.c | 5 ++---
>  1 file changed, 2 insertions(+), 3 deletions(-)
> 
> diff --git a/arch/arm64/mm/dma-mapping.c b/arch/arm64/mm/dma-mapping.c
> index e5d74cd..0bcc4bc 100644
> --- a/arch/arm64/mm/dma-mapping.c
> +++ b/arch/arm64/mm/dma-mapping.c
> @@ -144,6 +144,7 @@ static void *__dma_alloc(struct device *dev, size_t size,
>  	struct page *page;
>  	void *ptr, *coherent_ptr;
>  	bool coherent = is_device_dma_coherent(dev);
> +	pgprot_t prot = __get_dma_pgprot(attrs, PAGE_KERNEL, false);
>  
>  	size = PAGE_ALIGN(size);
>  
> @@ -171,9 +172,7 @@ static void *__dma_alloc(struct device *dev, size_t size,
>  	/* create a coherent mapping */
>  	page = virt_to_page(ptr);
>  	coherent_ptr = dma_common_contiguous_remap(page, size, VM_USERMAP,
> -				__get_dma_pgprot(attrs,
> -					__pgprot(PROT_NORMAL_NC), false),
> -					NULL);
> +						   prot, NULL);
>  	if (!coherent_ptr)
>  		goto no_map;

Reviewed-by: Catalin Marinas <catalin.marinas at arm.com>


From kishon at ti.com  Mon Aug  3 05:12:57 2015
From: kishon at ti.com (Kishon Vijay Abraham I)
Date: Mon, 3 Aug 2015 17:42:57 +0530
Subject: [PATCH 00/17] omap_hsmmc: regulator usage cleanup and fixes
In-Reply-To: <CALtMJEDP1-Q9W=x-0hq3tZQ1QZ2LVwVj47=ADYDjT7BsfanffA@mail.gmail.com>
References: <1438168187-1614-1-git-send-email-kishon@ti.com>
 <CALtMJEDP1-Q9W=x-0hq3tZQ1QZ2LVwVj47=ADYDjT7BsfanffA@mail.gmail.com>
Message-ID: <55BF5AC9.9000007@ti.com>

Hi,

On Monday 03 August 2015 12:58 PM, Andreas Fenkart wrote:
> Hi Kishon,
> 
> Thanks for taking a look at the regulator code. Do you have a public
> git repository so I can pull your patches instead of cherry picking
> 1-by-1?

I'll post v2 shortly. With that I'll have the patches in a git tree.

Thanks
Kishon

> 
> /Andi
> 
> 2015-07-29 13:09 GMT+02:00 Kishon Vijay Abraham I <kishon at ti.com>:
>> This patch series does the following
>> *) Uses devm_regulator_get_optional() for vmmc and then removes the
>>    CONFIG_REGULATOR check altogether.
>> *) return on -EPROBE_DEFER
>> *) enable/disable vmmc_aux regulator based on prior state
>>
>> This series is in preparation for implementing the voltage switch
>> sequence so that UHS cards can be supported.
>>
>> Did basic read/write test in J6, J6 Eco, Beagle-x15, AM437x EVM,
>> Beaglebone black, OMAP5 uEVM and OMAP4 PANDA.
>>
>> Kishon Vijay Abraham I (16):
>>   mmc: host: omap_hsmmc: use devm_regulator_get_optional() for vmmc
>>   mmc: host: omap_hsmmc: return error from omap_hsmmc_reg_get on
>>     -EPROBE_DEFER
>>   mmc: host: omap_hsmmc: cleanup omap_hsmmc_reg_get()
>>   mmc: host: omap_hsmmc: use the ocrmask provided by the vmmc regulator
>>   mmc: host: omap_hsmmc: use mmc_host's vmmc and vqmmc
>>   mmc: host: omap_hsmmc: remove unnecessary pbias set_voltage
>>   mmc: host: omap_hsmmc: return error if any of the regulator APIs fail
>>   mmc: host: omap_hsmmc: add separate functions for enable/disable
>>     supply
>>   mmc: host: omap_hsmmc: add separate function to set pbias
>>   mmc: host: omap_hsmmc: avoid pbias regulator enable on power off
>>   mmc: host: omap_hsmmc: don't use ->set_power to set initial regulator
>>     state
>>   ARM: dts: am57xx-beagle-x15: Fix regulator populated in MMC1 dt node
>>   mmc: host: omap_hsmmc: enable/disable vmmc_aux regulator based on
>>     prior state
>>   mmc: host: omap_hsmmc: use regulator_is_enabled to find pbias status
>>   mmc: host: omap_hsmmc: use ios->vdd for setting vmmc voltage
>>   mmc: host: omap_hsmmc: remove CONFIG_REGULATOR check
>>
>> Roger Quadros (1):
>>   mmc: host: omap_hsmmc: use "mmc_of_parse_voltage" to get ocr_avail
>>
>>  .../devicetree/bindings/mmc/ti-omap-hsmmc.txt      |    2 +
>>  arch/arm/boot/dts/am57xx-beagle-x15.dts            |    1 -
>>  drivers/mmc/host/omap_hsmmc.c                      |  333 +++++++++++++-------
>>  3 files changed, 216 insertions(+), 120 deletions(-)
>>
>> --
>> 1.7.9.5
>>


From aisheng.dong at freescale.com  Mon Aug  3 05:09:34 2015
From: aisheng.dong at freescale.com (Dong Aisheng)
Date: Mon, 3 Aug 2015 20:09:34 +0800
Subject: [PATCH v3 1/6] mmc: sdhci-esdhc-imx: add imx7d support and
 support HS400
In-Reply-To: <BY1PR03MB13889195F33D0010E6759D309A880@BY1PR03MB1388.namprd03.prod.outlook.com>
References: <1438160637-28061-1-git-send-email-haibo.chen@freescale.com>
 <1438160637-28061-2-git-send-email-haibo.chen@freescale.com>
 <20150731141507.GB27806@shlinux1.ap.freescale.net>
 <BY1PR03MB13889195F33D0010E6759D309A880@BY1PR03MB1388.namprd03.prod.outlook.com>
Message-ID: <20150803120932.GB24870@shlinux1.ap.freescale.net>

On Sun, Aug 02, 2015 at 04:59:04PM +0800, Chen Haibo-B51421 wrote:
> 
> 
> > -----Original Message-----
> > From: Dong Aisheng [mailto:aisheng.dong at freescale.com]
> > Sent: Friday, July 31, 2015 10:15 PM
> > To: Chen Haibo-B51421
> > Cc: robh+dt at kernel.org; pawel.moll at arm.com; mark.rutland at arm.com;
> > ijc+devicetree at hellion.org.uk; galak at codeaurora.org; shawnguo at kernel.org;
> > kernel at pengutronix.de; linux at arm.linux.org.uk; ulf.hansson at linaro.org;
> > johan.derycke at barco.com; Estevam Fabio-R49496; Dong Aisheng-B29396;
> > devicetree at vger.kernel.org; linux-kernel at vger.kernel.org; linux-arm-
> > kernel at lists.infradead.org; linux-mmc at vger.kernel.org
> > Subject: Re: [PATCH v3 1/6] mmc: sdhci-esdhc-imx: add imx7d support and
> > support HS400
> > 
> > On Wed, Jul 29, 2015 at 05:03:52PM +0800, Haibo Chen wrote:
> > > The imx7d usdhc is derived from imx6sx, the difference is that imx7d
> > > support HS400.
> > >
> > > So introduce a new compatible string for imx7d and add HS400 support
> > > for imx7d usdhc.
> > >
> > > Signed-off-by: Haibo Chen <haibo.chen at freescale.com>
> > > ---
> > >  drivers/mmc/host/sdhci-esdhc-imx.c | 66
> > > ++++++++++++++++++++++++++++++++++++++
> > >  1 file changed, 66 insertions(+)
> > >
> > > diff --git a/drivers/mmc/host/sdhci-esdhc-imx.c
> > > b/drivers/mmc/host/sdhci-esdhc-imx.c
> > > index c6b9f64..b441eed 100644
> > > --- a/drivers/mmc/host/sdhci-esdhc-imx.c
> > > +++ b/drivers/mmc/host/sdhci-esdhc-imx.c
> > > @@ -44,6 +44,7 @@
> > >  #define  ESDHC_MIX_CTRL_EXE_TUNE	(1 << 22)
> > >  #define  ESDHC_MIX_CTRL_SMPCLK_SEL	(1 << 23)
> > >  #define  ESDHC_MIX_CTRL_FBCLK_SEL	(1 << 25)
> > > +#define  ESDHC_MIX_CTRL_HS400_EN	(1 << 26)
> > >  /* Bits 3 and 6 are not SDHCI standard definitions */
> > >  #define  ESDHC_MIX_CTRL_SDHCI_MASK	0xb7
> > >  /* Tuning bits */
> > > @@ -60,6 +61,16 @@
> > >  #define  ESDHC_TUNE_CTRL_MIN		0
> > >  #define  ESDHC_TUNE_CTRL_MAX		((1 << 7) - 1)
> > >
> > > +/* strobe dll register */
> > > +#define ESDHC_STROBE_DLL_CTRL		0x70
> > > +#define ESDHC_STROBE_DLL_CTRL_ENABLE	(1 << 0)
> > > +#define ESDHC_STROBE_DLL_CTRL_RESET	(1 << 1)
> > > +#define ESDHC_STROBE_DLL_CTRL_SLV_DLY_TARGET_SHIFT	3
> > > +
> > > +#define ESDHC_STROBE_DLL_STATUS		0x74
> > > +#define ESDHC_STROBE_DLL_STS_REF_LOCK	(1 << 1)
> > > +#define ESDHC_STROBE_DLL_STS_SLV_LOCK	0x1
> > > +
> > >  #define ESDHC_TUNING_CTRL		0xcc
> > >  #define ESDHC_STD_TUNING_EN		(1 << 24)
> > >  /* NOTE: the minimum valid tuning start tap for mx6sl is 1 */ @@
> > > -120,6 +131,8 @@
> > >  #define ESDHC_FLAG_ERR004536		BIT(7)
> > >  /* The IP supports HS200 mode */
> > >  #define ESDHC_FLAG_HS200		BIT(8)
> > > +/* The IP supports HS400 mode */
> > > +#define ESDHC_FLAG_SUP_HS400		BIT(9)
> > >
> > >  struct esdhc_soc_data {
> > >  	u32 flags;
> > > @@ -156,6 +169,12 @@ static struct esdhc_soc_data usdhc_imx6sx_data = {
> > >  			| ESDHC_FLAG_HAVE_CAP1 | ESDHC_FLAG_HS200,  };
> > >
> > > +static struct esdhc_soc_data usdhc_imx7d_data = {
> > > +	.flags = ESDHC_FLAG_USDHC | ESDHC_FLAG_STD_TUNING
> > > +			| ESDHC_FLAG_HAVE_CAP1 | ESDHC_FLAG_HS200
> > > +			| ESDHC_FLAG_SUP_HS400,
> > > +};
> > > +
> > >  struct pltfm_imx_data {
> > >  	u32 scratchpad;
> > >  	struct pinctrl *pinctrl;
> > > @@ -199,6 +218,7 @@ static const struct of_device_id imx_esdhc_dt_ids[]
> > = {
> > >  	{ .compatible = "fsl,imx6sx-usdhc", .data = &usdhc_imx6sx_data, },
> > >  	{ .compatible = "fsl,imx6sl-usdhc", .data = &usdhc_imx6sl_data, },
> > >  	{ .compatible = "fsl,imx6q-usdhc", .data = &usdhc_imx6q_data, },
> > > +	{ .compatible = "fsl,imx7d-usdhc", .data = &usdhc_imx7d_data, },
> > >  	{ /* sentinel */ }
> > >  };
> > >  MODULE_DEVICE_TABLE(of, imx_esdhc_dt_ids); @@ -274,6 +294,10 @@
> > > static u32 esdhc_readl_le(struct sdhci_host *host, int reg)
> > >  				val = SDHCI_SUPPORT_DDR50 | SDHCI_SUPPORT_SDR104
> > >  					| SDHCI_SUPPORT_SDR50
> > >  					| SDHCI_USE_SDR50_TUNING;
> > > +
> > > +			/* imx7d does not have a support_hs400 register, fake
> > one */
> > 
> > You could remove this line.
> > It's bit, not register and i think no need such comment.
> > 
> > > +			if (imx_data->socdata->flags & ESDHC_FLAG_SUP_HS400)
> > > +				val |= SDHCI_SUPPORT_HS400;
> > >  		}
> > >  	}
> > >
> > > @@ -774,6 +798,7 @@ static int esdhc_change_pinstate(struct sdhci_host
> > *host,
> > >  		break;
> > >  	case MMC_TIMING_UHS_SDR104:
> > >  	case MMC_TIMING_MMC_HS200:
> > > +	case MMC_TIMING_MMC_HS400:
> > >  		pinctrl = imx_data->pins_200mhz;
> > >  		break;
> > >  	default:
> > > @@ -784,6 +809,30 @@ static int esdhc_change_pinstate(struct sdhci_host
> > *host,
> > >  	return pinctrl_select_state(imx_data->pinctrl, pinctrl);  }
> > >
> > > +static void esdhc_set_strobe_dll(struct sdhci_host *host)
> > 
> > It would be good if we can add some comments for this function for better
> > understand.
> > 
> 
> [haibo] okay, I will add comments here. 
> 
> > > +{
> > > +	u32 v;
> > > +
> > > +	/* force a reset on strobe dll */
> > > +	writel(ESDHC_STROBE_DLL_CTRL_RESET, host->ioaddr +
> > ESDHC_STROBE_DLL_CTRL);
> > > +	/*
> > > +	 * enable strobe dll ctrl and adjust the delay target
> > > +	 * for the uSDHC loopback read clock
> > > +	 */
> > > +	v = ESDHC_STROBE_DLL_CTRL_ENABLE |
> > > +		(7 << ESDHC_STROBE_DLL_CTRL_SLV_DLY_TARGET_SHIFT);
> > > +	writel(v, host->ioaddr + ESDHC_STROBE_DLL_CTRL);
> > > +	/* wait 1us to make sure strobe dll status register stable */
> > > +	udelay(1);
> > > +	v = readl(host->ioaddr + ESDHC_STROBE_DLL_STATUS);
> > > +	if (!(v & ESDHC_STROBE_DLL_STS_REF_LOCK))
> > > +		dev_warn(mmc_dev(host->mmc),
> > > +			"warning! HS400 strobe DLL status REF not lock!\n");
> > > +	if (!(v & ESDHC_STROBE_DLL_STS_SLV_LOCK))
> > > +		dev_warn(mmc_dev(host->mmc),
> > > +			"warning! HS400 strobe DLL status SLV not lock!\n"); }
> > > +
> > >  static void esdhc_set_uhs_signaling(struct sdhci_host *host, unsigned
> > > timing)  {
> > >  	struct sdhci_pltfm_host *pltfm_host = sdhci_priv(host); @@ -795,7
> > > +844,13 @@ static void esdhc_set_uhs_signaling(struct sdhci_host *host,
> > unsigned timing)
> > >  	case MMC_TIMING_UHS_SDR25:
> > >  	case MMC_TIMING_UHS_SDR50:
> > >  	case MMC_TIMING_UHS_SDR104:
> > > +		break;
> > >  	case MMC_TIMING_MMC_HS200:
> > > +		/* disable ddr mode and disable HS400 mode */
> > > +		writel(readl(host->ioaddr + ESDHC_MIX_CTRL) &
> > > +			~(ESDHC_MIX_CTRL_DDREN | ESDHC_MIX_CTRL_HS400_EN),
> > > +			host->ioaddr + ESDHC_MIX_CTRL);
> > > +		imx_data->is_ddr = 0;
> > >  		break;
> > >  	case MMC_TIMING_UHS_DDR50:
> > >  	case MMC_TIMING_MMC_DDR52:
> > > @@ -813,6 +868,14 @@ static void esdhc_set_uhs_signaling(struct
> > sdhci_host *host, unsigned timing)
> > >  			writel(v, host->ioaddr + ESDHC_DLL_CTRL);
> > >  		}
> > >  		break;
> > > +	case MMC_TIMING_MMC_HS400:
> > > +		writel(readl(host->ioaddr + ESDHC_MIX_CTRL) |
> > > +				ESDHC_MIX_CTRL_DDREN | ESDHC_MIX_CTRL_HS400_EN,
> > > +				host->ioaddr + ESDHC_MIX_CTRL);
> > > +		imx_data->is_ddr = 1;
> > > +		if (host->clock == 200000000)
> > 
> > I can't remember, but could this be a range required by SoC?
> 
> [haibo]we should set strobe_dll only when the host clock is 200MHz. For other condition, no need to do this.
> 

It is not quite make sense for only 200Mhz clock here.

First, shall we check host->mmc->actual_clock instead of host->clock?
That is the real clock frequency the controller is working on.


Second, even MMC core requests to set 200Mhz clock for HS400, the real
clock controller working on may be less than 200Mhz which depends on the
uSDHC root clock capability.
e.g. it may be 192Mhz if the parent is 384Mhz or less.
If that, do we need call strobe_dll too?

Can you check above two concerns?

Regards
Dong Aisheng

> > 
> > > +			esdhc_set_strobe_dll(host);
> > > +		break;
> > >  	}
> > >
> > >  	esdhc_change_pinstate(host, timing); @@ -1100,6 +1163,9 @@ static
> > > int sdhci_esdhc_imx_probe(struct platform_device *pdev)
> > >  	if (imx_data->socdata->flags & ESDHC_FLAG_ERR004536)
> > >  		host->quirks |= SDHCI_QUIRK_BROKEN_ADMA;
> > >
> > > +	if (imx_data->socdata->flags & ESDHC_FLAG_SUP_HS400)
> > > +		host->quirks2 |= SDHCI_QUIRK2_CAPS_BIT63_FOR_HS400;
> > > +
> > >  	if (of_id)
> > >  		err = sdhci_esdhc_imx_probe_dt(pdev, host, imx_data);
> > >  	else
> > > --
> > > 1.9.1
> > >
> > 
> > Regards
> > Dong Aisheng


From aisheng.dong at freescale.com  Mon Aug  3 05:12:36 2015
From: aisheng.dong at freescale.com (Dong Aisheng)
Date: Mon, 3 Aug 2015 20:12:36 +0800
Subject: [PATCH v3 6/6] mmc: sdhci-esdhc-imx: set back the
 burst_length_enable bit to 1
In-Reply-To: <BY1PR03MB138838EFB0DE8834DE5889669A770@BY1PR03MB1388.namprd03.prod.outlook.com>
References: <1438160637-28061-1-git-send-email-haibo.chen@freescale.com>
 <1438160637-28061-7-git-send-email-haibo.chen@freescale.com>
 <20150731145751.GG27806@shlinux1.ap.freescale.net>
 <BY1PR03MB138838EFB0DE8834DE5889669A770@BY1PR03MB1388.namprd03.prod.outlook.com>
Message-ID: <20150803121235.GC24870@shlinux1.ap.freescale.net>

On Mon, Aug 03, 2015 at 09:08:28AM +0800, Chen Haibo-B51421 wrote:
> 
> 
> > -----Original Message-----
> > From: Dong Aisheng [mailto:aisheng.dong at freescale.com]
> > Sent: Friday, July 31, 2015 10:58 PM
> > To: Chen Haibo-B51421
> > Cc: robh+dt at kernel.org; pawel.moll at arm.com; mark.rutland at arm.com;
> > ijc+devicetree at hellion.org.uk; galak at codeaurora.org; shawnguo at kernel.org;
> > kernel at pengutronix.de; linux at arm.linux.org.uk; ulf.hansson at linaro.org;
> > johan.derycke at barco.com; Estevam Fabio-R49496; Dong Aisheng-B29396;
> > devicetree at vger.kernel.org; linux-kernel at vger.kernel.org; linux-arm-
> > kernel at lists.infradead.org; linux-mmc at vger.kernel.org
> > Subject: Re: [PATCH v3 6/6] mmc: sdhci-esdhc-imx: set back the
> > burst_length_enable bit to 1
> > 
> > On Wed, Jul 29, 2015 at 05:03:57PM +0800, Haibo Chen wrote:
> > > Currently we find that if a usdhc is choosed to boot system, then ROM
> > > code will set the burst length enable bit of this usdhc as 0.
> > >
> > > This will make performance drop a lot if this usdhc's burst length is
> > > 16. So this patch set back the burst_length_enable bit as 1, which is
> > > the default value, and means burst length is enabled for INCR.
> > >
> > > Signed-off-by: Haibo Chen <haibo.chen at freescale.com>
> > > ---
> > >  drivers/mmc/host/sdhci-esdhc-imx.c | 11 +++++++++++
> > >  1 file changed, 11 insertions(+)
> > >
> > > diff --git a/drivers/mmc/host/sdhci-esdhc-imx.c
> > > b/drivers/mmc/host/sdhci-esdhc-imx.c
> > > index 37d0095..dd945e5 100644
> > > --- a/drivers/mmc/host/sdhci-esdhc-imx.c
> > > +++ b/drivers/mmc/host/sdhci-esdhc-imx.c
> > > @@ -32,6 +32,7 @@
> > >  #include "sdhci-esdhc.h"
> > >
> > >  #define	ESDHC_CTRL_D3CD			0x08
> > > +#define ESDHC_BURST_LEN_EN_INCR		(1 << 27)
> > >  /* VENDOR SPEC register */
> > >  #define ESDHC_VENDOR_SPEC		0xc0
> > >  #define  ESDHC_VENDOR_SPEC_SDIO_QUIRK	(1 << 1)
> > > @@ -1158,6 +1159,16 @@ static int sdhci_esdhc_imx_probe(struct
> > platform_device *pdev)
> > >  		host->quirks2 |= SDHCI_QUIRK2_PRESET_VALUE_BROKEN;
> > >  		host->mmc->caps |= MMC_CAP_1_8V_DDR;
> > >
> > > +		/*
> > > +		 * ROM code will change the burst_length_enable setting to
> > > +		 * zero if this usdhc is choosed to boot system. Change it
> > > +		 * back here, otherwise it will impact the performance a
> > > +		 * lot if the burst length is 16.
> > 
> > Can you clarify a bit more on why performance drops a lot if burst length
> > is 16?
> > Caused by the burst length setting did not work due to ROM disabled it?
> 
> 
> [haibo] this bit is used to enable/disable the burst length for the external AHB2AXI bridge, 
> It's useful especially for INCR transfer because without burst length indicator, the AHB2AXI 
> bridge doesn't know the burst length in advance. And without burst length indicator, AHB INCR 
> transfers can only be converted to singles on the AXI side.
> 
> Seting this bit means burst length enabled for INCR.
> If this bit is not set, performance will drop a lot when burst length is 8 or 16. I will add 
> this in the commit log.
>  

Thanks for clarify.
One question: with this patch, can we set the default watermark level to 64 by default for all
SoC types?

If yes, we may not need patch 5 anymore.
[PATCH v3 5/6] mmc: sdhci-esdhc-imx: config watermark level and burst length

Regards
Dong Aisheng

> > 
> > Regards
> > Dong Aisheng
> > 
> > > +		 */
> > > +		writel(readl(host->ioaddr + SDHCI_HOST_CONTROL)
> > > +			| ESDHC_BURST_LEN_EN_INCR,
> > > +			host->ioaddr + SDHCI_HOST_CONTROL);
> > > +
> > >  		if (!(imx_data->socdata->flags & ESDHC_FLAG_HS200))
> > >  			host->quirks2 |= SDHCI_QUIRK2_BROKEN_HS200;
> > >
> > > --
> > > 1.9.1
> > >


From stefan at agner.ch  Mon Aug  3 05:22:30 2015
From: stefan at agner.ch (Stefan Agner)
Date: Mon, 03 Aug 2015 14:22:30 +0200
Subject: [PATCH v5 2/2] ARM: dts: add property for maximum ADC clock
 frequencies
In-Reply-To: <557477BE.5050108@kernel.org>
References: <1432730872-14325-1-git-send-email-stefan@agner.ch>
 <1432730872-14325-3-git-send-email-stefan@agner.ch>
 <557477BE.5050108@kernel.org>
Message-ID: <f598169164aaacc28292d8ccc6afb32d@agner.ch>

Hi Shawn,

I guess this will go through your tree? Haven't seen it appear on imx/dt
so far...

--
Stefan

On 2015-06-07 18:56, Jonathan Cameron wrote:
> On 27/05/15 13:47, Stefan Agner wrote:
>> The ADC clock frequency is limited depending on modes used. Add
>> device tree property which allow to set the mode used and the
>> maximum frequency ratings for the instance. These allows to
>> set the ADC clock to a frequency which is within specification
>> according to the actual mode used.
>>
>> Acked-by: Fugang Duan <B38611 at freescale.com>
>> Signed-off-by: Stefan Agner <stefan at agner.ch>
> I'm happy to take this via IIO if people want me to, otherwise give
> it's connection to the previous patch that I just applied,
> 
> Acked-by: Jonathan Cameron <jic23 at kernel.org>
> 
>> ---
>>  arch/arm/boot/dts/vfxxx.dtsi | 4 ++++
>>  1 file changed, 4 insertions(+)
>>
>> diff --git a/arch/arm/boot/dts/vfxxx.dtsi b/arch/arm/boot/dts/vfxxx.dtsi
>> index a29c7ce..c6609bd 100644
>> --- a/arch/arm/boot/dts/vfxxx.dtsi
>> +++ b/arch/arm/boot/dts/vfxxx.dtsi
>> @@ -189,6 +189,8 @@
>>  				clocks = <&clks VF610_CLK_ADC0>;
>>  				clock-names = "adc";
>>  				status = "disabled";
>> +				fsl,adck-max-frequency = <30000000>, <40000000>,
>> +							<20000000>;
>>  			};
>>
>>  			wdoga5: wdog at 4003e000 {
>> @@ -387,6 +389,8 @@
>>  				clocks = <&clks VF610_CLK_ADC1>;
>>  				clock-names = "adc";
>>  				status = "disabled";
>> +				fsl,adck-max-frequency = <30000000>, <40000000>,
>> +							<20000000>;
>>  			};
>>
>>  			esdhc1: esdhc at 400b2000 {
>>



From linus.walleij at linaro.org  Mon Aug  3 05:32:48 2015
From: linus.walleij at linaro.org (Linus Walleij)
Date: Mon, 3 Aug 2015 14:32:48 +0200
Subject: [PATCH 0/2] drivers: PL061: Add platform driver probing support
In-Reply-To: <20150803094923.GI7557@n2100.arm.linux.org.uk>
References: <1438585198-8764-1-git-send-email-zhaoshenglong@huawei.com>
 <20150803075848.GH7557@n2100.arm.linux.org.uk>
 <55BF33AD.5040502@huawei.com>
 <20150803094923.GI7557@n2100.arm.linux.org.uk>
Message-ID: <CACRpkdbDduYxcubVKAuqdmwnw6d6R8bvQfYa0uRRYCF_Q6+MyQ@mail.gmail.com>

On Mon, Aug 3, 2015 at 11:49 AM, Russell King - ARM Linux
<linux at arm.linux.org.uk> wrote:
> On Mon, Aug 03, 2015 at 05:26:05PM +0800, Shannon Zhao wrote:

>> Oh, sorry. The changes for DT are not necessary. But for ACPI I think it
>> needs to convert pl061 to platform device since ACPI doesn't support
>> AMBA devices. The Pl011 also does the same thing to support ACPI
>> probing. See drivers/tty/serial/amba-pl011.c
>
> Maybe rather than having every AMBA driver also converted to a platform
> driver (which GregKH hates) maybe ACPI should support the AMBA bus
> instead?

I agree with Russell, and overall I'm not sure I'm very happy with
commit 0dd1e247fd39aed20fd2baacc62ca44d82534798
"drivers: PL011: add support for the ARM SBSA generic UART"
either.

I can see how this works, but it adds a big chunk of overhead to
every driver that want to support both PrimeCell MMIO probing
and devicetree and ACPI.

Devicetree is spawning awesome AMBA devices for PrimeCells
in drivers/of/platform.c, so why can't ACPI do the same?

The AMBA bus is intelligent and very helpful with things like
runtime suspend/resume. It also supports reading the version
registers to autodetect device characteristics.

Yours,
Linus Walleij


From k.kozlowski.k at gmail.com  Mon Aug  3 05:37:25 2015
From: k.kozlowski.k at gmail.com (Krzysztof Kozlowski)
Date: Mon,  3 Aug 2015 21:37:25 +0900
Subject: [PATCH 0/2] mfd/EXYNOS: Properly shutdown Odroid XU3
Message-ID: <1438605447-6836-1-git-send-email-k.kozlowski.k@gmail.com>

Hi,

This fixes shutdown of Odroid XU3 family. More details in patch 1.

Patches are independent, please pick up freely.

Best regards,
Krzysztof

Krzysztof Kozlowski (2):
  mfd: s2mps11: Add manual shutdown method for Odroid XU3
  ARM: dts: Fix power off method on exynos5422-odroidxu3

 Documentation/devicetree/bindings/mfd/s2mps11.txt  |  4 +++
 arch/arm/boot/dts/exynos5422-odroidxu3-common.dtsi |  1 +
 drivers/mfd/sec-core.c                             | 31 ++++++++++++++++++++++
 include/linux/mfd/samsung/core.h                   |  2 ++
 include/linux/mfd/samsung/s2mps11.h                |  1 +
 5 files changed, 39 insertions(+)

-- 
2.1.4



From k.kozlowski.k at gmail.com  Mon Aug  3 05:37:26 2015
From: k.kozlowski.k at gmail.com (Krzysztof Kozlowski)
Date: Mon,  3 Aug 2015 21:37:26 +0900
Subject: [PATCH 1/2] mfd: s2mps11: Add manual shutdown method for Odroid XU3
In-Reply-To: <1438605447-6836-1-git-send-email-k.kozlowski.k@gmail.com>
References: <1438605447-6836-1-git-send-email-k.kozlowski.k@gmail.com>
Message-ID: <1438605447-6836-2-git-send-email-k.kozlowski.k@gmail.com>

On Odroid XU3 board (with S2MPS11 PMIC) the PWRHOLD bit in CTRL1
register must be manually set to 0 before initiating power off sequence.

One of usual power down methods for Exynos based devices looks like:
1. PWRHOLD pin of PMIC is connected to PSHOLD of Exynos.
2. Exynos holds up this pin during system operation.
3. ACOKB pin of PMIC is pulled up to VBATT and optionally to pin in
   other device.
4. When PWRHOLD/PSHOLD goes low, the PMIC will turn off the power if
   ACOKB goes high.

On Odroid XU3 family the difference is in (3) - the ACOKB is grounded.
This means that PMIC must manually set PWRHOLD field to low and then
wait for signal from Application Processor (the usual change in
PWRHOLD/PSHOLD pin will actually cut off the power).

The patch adds respective binding allowing Odroid XU3 device to be
powered off.

Signed-off-by: Krzysztof Kozlowski <k.kozlowski.k at gmail.com>
Reported-by: Anand Moon <linux.amoon at gmail.com>

---

Patch is losely based on patch in Hardkernel repository [0] and previous
work of Anand Moon [1].

[0] https://github.com/hardkernel/linux/commit/6897e62ba328bd1c8c095d918101863250cd73e7
[1] http://www.spinics.net/lists/linux-samsung-soc/msg45959.html
---
 Documentation/devicetree/bindings/mfd/s2mps11.txt |  4 +++
 drivers/mfd/sec-core.c                            | 31 +++++++++++++++++++++++
 include/linux/mfd/samsung/core.h                  |  2 ++
 include/linux/mfd/samsung/s2mps11.h               |  1 +
 4 files changed, 38 insertions(+)

diff --git a/Documentation/devicetree/bindings/mfd/s2mps11.txt b/Documentation/devicetree/bindings/mfd/s2mps11.txt
index 57a045016fca..90eaef393325 100644
--- a/Documentation/devicetree/bindings/mfd/s2mps11.txt
+++ b/Documentation/devicetree/bindings/mfd/s2mps11.txt
@@ -15,6 +15,10 @@ Optional properties:
 - interrupt-parent: Specifies the phandle of the interrupt controller to which
   the interrupts from s2mps11 are delivered to.
 - interrupts: Interrupt specifiers for interrupt sources.
+- samsung,s2mps11-acokb-ground: Indicates that ACOKB pin of S2MPS11 PMIC is
+  connected to the ground so the PMIC must manually set PWRHOLD bit in CTRL1
+  register to turn off the power. Usually the ACOKB is pulled up to VBATT so
+  when PWRHOLD pin goes low, the rising ACOKB will trigger power off.
 
 Optional nodes:
 - clocks: s2mps11, s2mps13 and s5m8767 provide three(AP/CP/BT) buffered 32.768
diff --git a/drivers/mfd/sec-core.c b/drivers/mfd/sec-core.c
index d206a3e8fe87..a56ab2102a32 100644
--- a/drivers/mfd/sec-core.c
+++ b/drivers/mfd/sec-core.c
@@ -278,6 +278,8 @@ static struct sec_platform_data *sec_pmic_i2c_parse_dt_pdata(
 	 * not parsed here.
 	 */
 
+	pd->manual_poweroff = of_property_read_bool(dev->of_node,
+						"samsung,s2mps11-acokb-ground");
 	return pd;
 }
 #else
@@ -440,6 +442,34 @@ static int sec_pmic_remove(struct i2c_client *i2c)
 	return 0;
 }
 
+static void sec_pmic_shutdown(struct i2c_client *i2c)
+{
+	struct sec_pmic_dev *sec_pmic = i2c_get_clientdata(i2c);
+	unsigned int reg, mask;
+
+	if (!sec_pmic->pdata->manual_poweroff)
+		return;
+
+	switch (sec_pmic->device_type) {
+	case S2MPS11X:
+		reg = S2MPS11_REG_CTRL1;
+		mask = S2MPS11_CTRL1_PWRHOLD_MASK;
+		break;
+	default:
+		/*
+		 * Currently only one board with S2MPS11 needs this, so just
+		 * ignore the rest.
+		 */
+		dev_warn(sec_pmic->dev,
+			"Unsupported device %lu for manual power off\n",
+			sec_pmic->device_type);
+		return;
+	}
+
+	regmap_update_bits(sec_pmic->regmap_pmic, reg, mask, 0);
+}
+
+
 #ifdef CONFIG_PM_SLEEP
 static int sec_pmic_suspend(struct device *dev)
 {
@@ -491,6 +521,7 @@ static struct i2c_driver sec_pmic_driver = {
 	},
 	.probe = sec_pmic_probe,
 	.remove = sec_pmic_remove,
+	.shutdown = sec_pmic_shutdown,
 	.id_table = sec_pmic_id,
 };
 
diff --git a/include/linux/mfd/samsung/core.h b/include/linux/mfd/samsung/core.h
index 75115384f3fc..aa78957e092f 100644
--- a/include/linux/mfd/samsung/core.h
+++ b/include/linux/mfd/samsung/core.h
@@ -132,6 +132,8 @@ struct sec_platform_data {
 	int				buck2_init;
 	int				buck3_init;
 	int				buck4_init;
+	/* Whether or not manually set PWRHOLD to low during shutdown. */
+	bool				manual_poweroff;
 };
 
 /**
diff --git a/include/linux/mfd/samsung/s2mps11.h b/include/linux/mfd/samsung/s2mps11.h
index 7981a9d77d3f..b288965e8101 100644
--- a/include/linux/mfd/samsung/s2mps11.h
+++ b/include/linux/mfd/samsung/s2mps11.h
@@ -179,6 +179,7 @@ enum s2mps11_regulators {
 #define S2MPS11_BUCK_N_VOLTAGES (S2MPS11_BUCK_VSEL_MASK + 1)
 #define S2MPS11_RAMP_DELAY	25000		/* uV/us */
 
+#define S2MPS11_CTRL1_PWRHOLD_MASK	BIT(4)
 
 #define S2MPS11_BUCK2_RAMP_SHIFT	6
 #define S2MPS11_BUCK34_RAMP_SHIFT	4
-- 
2.1.4



From k.kozlowski.k at gmail.com  Mon Aug  3 05:37:27 2015
From: k.kozlowski.k at gmail.com (Krzysztof Kozlowski)
Date: Mon,  3 Aug 2015 21:37:27 +0900
Subject: [PATCH 2/2] ARM: dts: Fix power off method on exynos5422-odroidxu3
In-Reply-To: <1438605447-6836-1-git-send-email-k.kozlowski.k@gmail.com>
References: <1438605447-6836-1-git-send-email-k.kozlowski.k@gmail.com>
Message-ID: <1438605447-6836-3-git-send-email-k.kozlowski.k@gmail.com>

The Odroid XU3 family boards have ACOKB pin of PMIC grounded, instead of
pulled up as usual. This means that PMIC must manually set PWRHOLD field
in its CTRL1 register to low before initiating power down.

This fixes Odroid XU3 powering off:
[   25.966053] reboot: Power down
[   25.967679] Power down.
[   26.070174] Power down failed, please power off system manually.

Signed-off-by: Krzysztof Kozlowski <k.kozlowski.k at gmail.com>
Reported-by: Anand Moon <linux.amoon at gmail.com>
---
 arch/arm/boot/dts/exynos5422-odroidxu3-common.dtsi | 1 +
 1 file changed, 1 insertion(+)

diff --git a/arch/arm/boot/dts/exynos5422-odroidxu3-common.dtsi b/arch/arm/boot/dts/exynos5422-odroidxu3-common.dtsi
index 1565667e6f69..48cecc8cf26e 100644
--- a/arch/arm/boot/dts/exynos5422-odroidxu3-common.dtsi
+++ b/arch/arm/boot/dts/exynos5422-odroidxu3-common.dtsi
@@ -159,6 +159,7 @@
 		s2mps11,buck2-ramp-enable = <1>;
 		s2mps11,buck3-ramp-enable = <1>;
 		s2mps11,buck4-ramp-enable = <1>;
+		samsung,s2mps11-acokb-ground;
 
 		interrupt-parent = <&gpx0>;
 		interrupts = <4 IRQ_TYPE_EDGE_FALLING>;
-- 
2.1.4



From linus.walleij at linaro.org  Mon Aug  3 05:40:07 2015
From: linus.walleij at linaro.org (Linus Walleij)
Date: Mon, 3 Aug 2015 14:40:07 +0200
Subject: [PATCH 1/2] drivers: PL061: add support for platform driver
 probing
In-Reply-To: <1438585198-8764-2-git-send-email-zhaoshenglong@huawei.com>
References: <1438585198-8764-1-git-send-email-zhaoshenglong@huawei.com>
 <1438585198-8764-2-git-send-email-zhaoshenglong@huawei.com>
Message-ID: <CACRpkdY6ZfB-gnnr49He+BYELy4fhiV0g5jkEHhyVsJOc_SBFw@mail.gmail.com>

On Mon, Aug 3, 2015 at 8:59 AM, Shannon Zhao <zhaoshenglong at huawei.com> wrote:

> From: Shannon Zhao <shannon.zhao at linaro.org>
>
> Since PL061 currently only supports AMBA driver, to support using GPIO
> PL061 by DT or ACPI, it needs to add support for platform driver.
> A DT binding is provided with this patch, ACPI support is added in a
> separate one.
>
> Signed-off-by: Shannon Zhao <zhaoshenglong at huawei.com>
> Signed-off-by: Shannon Zhao <shannon.zhao at linaro.org>

I already stated in 0/2 what the problem is with this, and it's obviously adding
a huge codechunk, very similar to the AMBA probe path.

We need to investigate if ACPI can just spawn AMBA/PrimeCell type devices
instead.

Yours,
Linus Walleij


From sudeep.holla at arm.com  Mon Aug  3 05:43:09 2015
From: sudeep.holla at arm.com (Sudeep Holla)
Date: Mon, 03 Aug 2015 13:43:09 +0100
Subject: [PATCH v6 6/8] arm64: dts: add SRAM, MHU mailbox and SCPI support
 on Juno
In-Reply-To: <1438602393.5218.3.camel@linaro.org>
References: <1438364591-1144-1-git-send-email-sudeep.holla@arm.com>	
 <1438364591-1144-7-git-send-email-sudeep.holla@arm.com>	
 <20150803112353.GV20890@e106497-lin.cambridge.arm.com>
 <1438602393.5218.3.camel@linaro.org>
Message-ID: <55BF61DD.7020003@arm.com>



On 03/08/15 12:46, Jon Medhurst (Tixy) wrote:
> On Mon, 2015-08-03 at 12:23 +0100, Liviu Dudau wrote:
>> On Fri, Jul 31, 2015 at 06:43:09PM +0100, Sudeep Holla wrote:
>>> This patch adds support for the MHU mailbox peripheral used on Juno by
>>> application processors to communicate with remote SCP handling most of
>>> the CPU/system power management. It also adds the SRAM reserving the
>>> shared memory and SCPI message protocol using that shared memory.
>>>
>>> Signed-off-by: Sudeep Holla <sudeep.holla at arm.com>
>>> Acked-by: Liviu Dudau <Liviu.Dudau at arm.com>
>>> Cc: Jon Medhurst (Tixy) <tixy at linaro.org>
>>> ---
>>>   arch/arm64/boot/dts/arm/juno-base.dtsi | 54 ++++++++++++++++++++++++++++++++++
>>>   1 file changed, 54 insertions(+)
>>>
>>> diff --git a/arch/arm64/boot/dts/arm/juno-base.dtsi b/arch/arm64/boot/dts/arm/juno-base.dtsi
>>> index e3ee96036eca..c624208edef6 100644
>>> --- a/arch/arm64/boot/dts/arm/juno-base.dtsi
>>> +++ b/arch/arm64/boot/dts/arm/juno-base.dtsi
> [...]
>>> +	scpi {
>>> +		compatible = "arm,scpi";
>>> +		mboxes = <&mailbox 1>;
>>> +		shmem = <&cpu_scp_hpri>;
>>> +
>>> +		clocks {
>>> +			compatible = "arm,scpi-clocks";
>>> +
>>> +			scpi_dvfs: scpi_clocks at 0 {
>>> +				compatible = "arm,scpi-dvfs-clocks";
>>> +				#clock-cells = <1>;
>>> +				clock-indices = <0>, <1>, <2>;
>>> +				clock-output-names = "atlclk", "aplclk","gpuclk";
>>> +			};
>>> +			scpi_clk: scpi_clocks at 3 {
>>> +				compatible = "arm,scpi-variable-clocks";
>>> +				#clock-cells = <1>;
>>> +				clock-indices = <3>, <4>;
>>> +				clock-output-names = "pxlclk0", "pxlclk1";
>>> +			};
>>> +		};
>>> +	};
>>> +
>>
>> Sorry for noticing this after the ACK, is there any reason why the scpi node is not inside
>> the juno-clocks.dtsi file?
>
> Because SCPI is not just about clocks? Just happens that these first
> patches are but there's thermal sensors and other things as well.
>

I think we cross posted. Anyways I completely agree with you.
However I wanted the clock nodes to be put in juno-clock.dtsi but got
into horrible issue with the way we include headers. It may need some
reworking to get that working.

The idea was:
/* in juno-base.dtsi */
SCPI: scpi {
	compatible = "arm,scpi";
	mboxes = <&mailbox 1>;
	shmem = <&cpu_scp_hpri>;
	...
};
/* in juno-clock.dtsi */
&SCPI {
         clocks {
                 compatible = "arm,scpi-clocks";
                 scpi_dvfs: scpi_clocks at 0 {
                         compatible = "arm,scpi-dvfs-clocks";
                         #clock-cells = <1>;
                         clock-indices = <0>, <1>, <2>;
                         clock-output-names = "atlclk","aplclk","gpuclk";
                 };
};

I will look at that when I get some time. There are many DTS files
already using something similar.

Regards,
Sudeep


From Liviu.Dudau at arm.com  Mon Aug  3 05:47:58 2015
From: Liviu.Dudau at arm.com (Liviu Dudau)
Date: Mon, 3 Aug 2015 13:47:58 +0100
Subject: [PATCH v6 6/8] arm64: dts: add SRAM, MHU mailbox and SCPI
 support on Juno
In-Reply-To: <55BF5427.2010605@arm.com>
References: <1438364591-1144-1-git-send-email-sudeep.holla@arm.com>
 <1438364591-1144-7-git-send-email-sudeep.holla@arm.com>
 <20150803112353.GV20890@e106497-lin.cambridge.arm.com>
 <55BF5427.2010605@arm.com>
Message-ID: <20150803124758.GW20890@e106497-lin.cambridge.arm.com>

On Mon, Aug 03, 2015 at 12:44:39PM +0100, Sudeep Holla wrote:
> 
> 
> On 03/08/15 12:23, Liviu Dudau wrote:
> > On Fri, Jul 31, 2015 at 06:43:09PM +0100, Sudeep Holla wrote:
> >> This patch adds support for the MHU mailbox peripheral used on Juno by
> >> application processors to communicate with remote SCP handling most of
> >> the CPU/system power management. It also adds the SRAM reserving the
> >> shared memory and SCPI message protocol using that shared memory.
> >>
> >> Signed-off-by: Sudeep Holla <sudeep.holla at arm.com>
> >> Acked-by: Liviu Dudau <Liviu.Dudau at arm.com>
> >> Cc: Jon Medhurst (Tixy) <tixy at linaro.org>
> >> ---
> >>   arch/arm64/boot/dts/arm/juno-base.dtsi | 54 ++++++++++++++++++++++++++++++++++
> >>   1 file changed, 54 insertions(+)
> >>
> >> diff --git a/arch/arm64/boot/dts/arm/juno-base.dtsi b/arch/arm64/boot/dts/arm/juno-base.dtsi
> >> index e3ee96036eca..c624208edef6 100644
> >> --- a/arch/arm64/boot/dts/arm/juno-base.dtsi
> >> +++ b/arch/arm64/boot/dts/arm/juno-base.dtsi
> >> @@ -17,6 +17,18 @@
> >>   		};
> >>   	};
> >>
> >> +	mailbox: mhu at 2b1f0000 {
> >> +		compatible = "arm,mhu", "arm,primecell";
> >> +		reg = <0x0 0x2b1f0000 0x0 0x1000>;
> >> +		interrupts = <GIC_SPI 36 IRQ_TYPE_LEVEL_HIGH>,
> >> +			     <GIC_SPI 35 IRQ_TYPE_LEVEL_HIGH>;
> >> +		interrupt-names = "mhu_lpri_rx",
> >> +				  "mhu_hpri_rx";
> >> +		#mbox-cells = <1>;
> >> +		clocks = <&soc_refclk100mhz>;
> >> +		clock-names = "apb_pclk";
> >> +	};
> >> +
> >>   	gic: interrupt-controller at 2c010000 {
> >>   		compatible = "arm,gic-400", "arm,cortex-a15-gic";
> >>   		reg = <0x0 0x2c010000 0 0x1000>,
> >> @@ -44,6 +56,48 @@
> >>   			     <GIC_PPI 10 (GIC_CPU_MASK_SIMPLE(6) | IRQ_TYPE_LEVEL_LOW)>;
> >>   	};
> >>
> >> +	sram: sram at 2e000000 {
> >> +		compatible = "arm,juno-sram-ns", "mmio-sram";
> >> +		reg = <0x0 0x2e000000 0x0 0x8000>;
> >> +
> >> +		#address-cells = <1>;
> >> +		#size-cells = <1>;
> >> +		ranges = <0 0x0 0x2e000000 0x8000>;
> >> +
> >> +		cpu_scp_lpri: scp-shmem at 0 {
> >> +			compatible = "arm,juno-scp-shmem";
> >> +			reg = <0x0 0x200>;
> >> +		};
> >> +
> >> +		cpu_scp_hpri: scp-shmem at 200 {
> >> +			compatible = "arm,juno-scp-shmem";
> >> +			reg = <0x200 0x200>;
> >> +		};
> >> +	};
> >> +
> >> +	scpi {
> >> +		compatible = "arm,scpi";
> >> +		mboxes = <&mailbox 1>;
> >> +		shmem = <&cpu_scp_hpri>;
> >> +
> >> +		clocks {
> >> +			compatible = "arm,scpi-clocks";
> >> +
> >> +			scpi_dvfs: scpi_clocks at 0 {
> >> +				compatible = "arm,scpi-dvfs-clocks";
> >> +				#clock-cells = <1>;
> >> +				clock-indices = <0>, <1>, <2>;
> >> +				clock-output-names = "atlclk", "aplclk","gpuclk";
> >> +			};
> >> +			scpi_clk: scpi_clocks at 3 {
> >> +				compatible = "arm,scpi-variable-clocks";
> >> +				#clock-cells = <1>;
> >> +				clock-indices = <3>, <4>;
> >> +				clock-output-names = "pxlclk0", "pxlclk1";
> >> +			};
> >> +		};
> >> +	};
> >> +
> >
> > Sorry for noticing this after the ACK, is there any reason why the scpi node is not inside
> > the juno-clocks.dtsi file?
> >
> 
> Yes, scpi node will have other nodes like sensors/hwmon. So the whole
> scpi node can't sit in juno-clocks. Ideally the clocks belongs to
> juno-clocks, but I got troubles with the way the DTSI are includes and
> could not keep scpi node in base and just update clocks in
> juno-clocks.dtsi. It needs some rework the way include file are used.
> It's in my todo and I will look at that when I get time.

OK, it makes sense. I haven't had a chance to go through Punit's series yet,
I've missed the fact that thermal is going to be attached to this node as well.

Best regards,
Liviu

> 
> Regards,
> Sudeep
> 

-- 
====================
| I would like to |
| fix the world,  |
| but they're not |
| giving me the   |
 \ source code!  /
  ---------------
    ?\_(?)_/?



From geert at linux-m68k.org  Mon Aug  3 06:00:32 2015
From: geert at linux-m68k.org (Geert Uytterhoeven)
Date: Mon, 3 Aug 2015 15:00:32 +0200
Subject: [PATCH v3] ARM: shmobile: silk: initial device tree
In-Reply-To: <2360526.88foRQAOiM@wasted.cogentembedded.com>
References: <201404250239.39150.sergei.shtylyov@cogentembedded.com>
 <2360526.88foRQAOiM@wasted.cogentembedded.com>
Message-ID: <CAMuHMdWT=nzsFuM-vfe5GoAtDE-AtW4LAZoEnBGGVZm54-mAzg@mail.gmail.com>

Hi Sergei,

On Wed, Jul 29, 2015 at 12:14 AM, Sergei Shtylyov
<sergei.shtylyov at cogentembedded.com> wrote:
> --- /dev/null
> +++ renesas/arch/arm/boot/dts/r8a7794-silk.dts
> @@ -0,0 +1,51 @@

> +/ {
> +       model = "SILK";
> +       compatible = "renesas,silk", "renesas,r8a7794";

WARNING: DT compatible string "renesas,silk" appears un-documented --
check ./Documentation/devicetree/bindings/

Do you plan to update Documentation/devicetree/bindings/arm/shmobile.txt?

Thanks!

Gr{oetje,eeting}s,

                        Geert

--
Geert Uytterhoeven -- There's lots of Linux beyond ia32 -- geert at linux-m68k.org

In personal conversations with technical people, I call myself a hacker. But
when I'm talking to journalists I just say "programmer" or something like that.
                                -- Linus Torvalds


From will.deacon at arm.com  Mon Aug  3 06:11:32 2015
From: will.deacon at arm.com (Will Deacon)
Date: Mon, 3 Aug 2015 14:11:32 +0100
Subject: [PATCH v3 1/2] PCI: generic: remove dependency on hw_pci
In-Reply-To: <20150731162716.GA7182@red-moon>
References: <1438183681-30519-1-git-send-email-jchandra@broadcom.com>
 <20150730133521.GA12999@red-moon>
 <20150731160654.GB31408@jayachandranc.netlogicmicro.com>
 <20150731162716.GA7182@red-moon>
Message-ID: <20150803131131.GF10501@arm.com>

Hi Jayachandran, Bjorn,

On Fri, Jul 31, 2015 at 05:27:16PM +0100, Lorenzo Pieralisi wrote:
> On Fri, Jul 31, 2015 at 05:07:01PM +0100, Jayachandran C. wrote:
> > On Thu, Jul 30, 2015 at 02:35:21PM +0100, Lorenzo Pieralisi wrote:
> > > On Wed, Jul 29, 2015 at 04:28:00PM +0100, Jayachandran C wrote:
> > > > -	pci_common_init_dev(dev, &hw);
> > > > +	/* do not reassign resource if probe only */
> > > > +	if (!pci_has_flag(PCI_PROBE_ONLY))
> > > > +		pci_add_flags(PCI_REASSIGN_ALL_RSRC);
> > > 
> > > You should add PCI_REASSIGN_ALL_BUS here. As I said in patch 2 comment,
> > 
> > The idea is to do exactly what pci_common_init_dev does on ARM. There is
> > not need to change behavior on ARM and deal with the fallout in this
> > patchset.
> 
> You are enabling this driver on ARM64, and on ARM64 that flag does
> make a difference, it does not on ARM as far as I can tell, but you do
> not seem to care.
> 
> Actually Rob asked you to put together a function since most of
> this code is replicated across ARM drivers eg:
> 
> drivers/pci/host/pci-versatile.c
> 
> Leave the code as it is and I will consolidate the code later.
> 
> > > please enable setup-irq.c in an explicit commit, re-sequence the
> > > series and fold the Kconfig ARM64 enablement in this patch.
> > 
> > I would think that the Makefile and Kconfig changes should be
> > togethter as the arm64 enablement patch. The previous patch is
> > to update the gen_pci driver, and it really makes sense in that
> > order.  I am not sure why you suggest this change.
> 
> Because this is not the only driver that requires compiling
> drivers/pci/setup-irq.c on ARM64, I thought it made more sense
> to do it in a separate patch to make that change standalone.
> 
> If for any reason we have to revert your patch that enables
> PCI host generic on ARM64 (and we remove with it the compilation
> of setup-irq.c) we would break other ARM64 PCI hosts that require it,
> right ?
> 
> I leave the decision to Bjorn since I am away next week, I am fine
> with the code as it is so please go ahead.

In the interest of getting something merged, can I suggest you
(Jayachandran) repost the patches with Lorenzo's suggestions to reorder
the series and split up the setup-irq compilation into a separate patch?

You can also add his ack to this patch.

It's a pity that the code isn't quite how we'd like it to end up, but
this at least enables people for 4.3 and I know that Lorenzo is working
on tidying up the loose ends as additional patches (but he's on holiday
this week). That includes removal of the PROBE_ONLY bodge that I've got
queued in arch/arm64/kernel/pci.c.

Bjorn, does that sound ok to you? I'm keen to have something working, as
I'm starting to get beaten up about the lack of generic PCI on arm64.

Cheers,

Will


From hdegoede at redhat.com  Mon Aug  3 06:11:41 2015
From: hdegoede at redhat.com (Hans de Goede)
Date: Mon, 3 Aug 2015 15:11:41 +0200
Subject: [linux-sunxi] Re: [PATCH v2] ARM: dts: sunxi: Add regulators for
 LeMaker BananaPi
In-Reply-To: <20150803094723.GD2564@lukather>
References: <1438532305-5884-1-git-send-email-public_timo.s@silentcreek.de>
 <20150803094723.GD2564@lukather>
Message-ID: <55BF688D.5010905@redhat.com>

Hi,

On 03-08-15 11:47, Maxime Ripard wrote:
> On Sun, Aug 02, 2015 at 06:18:25PM +0200, Timo Sigurdsson wrote:
>> sun7i-a20-bananapi.dts doesn't contain regulator nodes for the AXP209 PMU
>> driver, so add them to allow for voltage-scaling with cpufreq-dt.
>>
>> Signed-off-by: Timo Sigurdsson <public_timo.s at silentcreek.de>
>> ---
>> Changes since v1 (RFC):
>>
>> - Dropped the changes to the cpufreq operating points and renamed the patch
>> accordingly
>> - Limited the CPU voltage range so it doesn't exceed the SOC specifications
>> ---
>>   arch/arm/boot/dts/sun7i-a20-bananapi.dts | 35 ++++++++++++++++++++++++++++----
>>   1 file changed, 31 insertions(+), 4 deletions(-)
>>
>> diff --git a/arch/arm/boot/dts/sun7i-a20-bananapi.dts b/arch/arm/boot/dts/sun7i-a20-bananapi.dts
>> index 9f7b472..74382f3 100644
>> --- a/arch/arm/boot/dts/sun7i-a20-bananapi.dts
>> +++ b/arch/arm/boot/dts/sun7i-a20-bananapi.dts
>> @@ -92,6 +92,10 @@
>>   	status = "okay";
>>   };
>>
>> +&cpu0 {
>> +	cpu-supply = <&reg_dcdc2>;
>> +};
>> +
>>   &ehci0 {
>>   	status = "okay";
>>   };
>> @@ -119,13 +123,9 @@
>>   	status = "okay";
>>
>>   	axp209: pmic at 34 {
>> -		compatible = "x-powers,axp209";
>>   		reg = <0x34>;
>>   		interrupt-parent = <&nmi_intc>;
>>   		interrupts = <0 IRQ_TYPE_LEVEL_LOW>;
>> -
>> -		interrupt-controller;
>> -		#interrupt-cells = <1>;
>>   	};
>>   };
>>
>> @@ -182,6 +182,33 @@
>>   	};
>>   };
>>
>> +#include "axp209.dtsi"
>> +
>> +&reg_dcdc2 {
>> +	regulator-always-on;
>> +	regulator-min-microvolt = <1000000>;
>> +	regulator-max-microvolt = <1400000>;
>> +	regulator-name = "vdd-cpu";
>> +};
>> +
>> +&reg_dcdc3 {
>> +	regulator-always-on;
>> +	regulator-min-microvolt = <1000000>;
>> +	regulator-max-microvolt = <1400000>;
>> +	regulator-name = "vdd-int-dll";
>> +};
>> +
>> +&reg_ldo1 {
>> +	regulator-name = "vdd-rtc";
>> +};
>> +
>> +&reg_ldo2 {
>> +	regulator-always-on;
>> +	regulator-min-microvolt = <3000000>;
>> +	regulator-max-microvolt = <3000000>;
>> +	regulator-name = "avcc";
>> +};
>
> What regulator provides the 3.3V regulator used in the rest of this DT
> then (MMC, GMAC) ?

A separate fixed regulator, like most (all?) other axp209 using boards,
e.g. the cubieboard has a TCS4199 regulator for this, and the banana
boards use a XL8206/UP1746 for this, according to the schematics I
have.

Regards,

Hans

>
> Maxime
>


From will.deacon at arm.com  Mon Aug  3 06:25:48 2015
From: will.deacon at arm.com (Will Deacon)
Date: Mon,  3 Aug 2015 14:25:48 +0100
Subject: [PATCH 06/13] iommu/arm-smmu: Clean up DMA API usage
In-Reply-To: <1438608355-7335-1-git-send-email-will.deacon@arm.com>
References: <1438608355-7335-1-git-send-email-will.deacon@arm.com>
Message-ID: <1438608355-7335-7-git-send-email-will.deacon@arm.com>

From: Robin Murphy <Robin.Murphy at arm.com>

With the correct DMA API calls now integrated into the io-pgtable code,
let that handle the flushing of non-coherent page table updates.

Signed-off-by: Robin Murphy <robin.murphy at arm.com>
Signed-off-by: Will Deacon <will.deacon at arm.com>
---
 drivers/iommu/arm-smmu.c | 22 ++++++----------------
 1 file changed, 6 insertions(+), 16 deletions(-)

diff --git a/drivers/iommu/arm-smmu.c b/drivers/iommu/arm-smmu.c
index 0583ed2f33c0..5770ab98fa38 100644
--- a/drivers/iommu/arm-smmu.c
+++ b/drivers/iommu/arm-smmu.c
@@ -611,24 +611,13 @@ static void arm_smmu_tlb_inv_range_nosync(unsigned long iova, size_t size,
 static void arm_smmu_flush_pgtable(void *addr, size_t size, void *cookie)
 {
 	struct arm_smmu_domain *smmu_domain = cookie;
-	struct arm_smmu_device *smmu = smmu_domain->smmu;
-	unsigned long offset = (unsigned long)addr & ~PAGE_MASK;
-
 
-	/* Ensure new page tables are visible to the hardware walker */
-	if (smmu->features & ARM_SMMU_FEAT_COHERENT_WALK) {
+	/*
+	 * Ensure new page tables are visible to a coherent hardware walker.
+	 * The page table code deals with flushing for the non-coherent case.
+	 */
+	if (smmu_domain->smmu->features & ARM_SMMU_FEAT_COHERENT_WALK)
 		dsb(ishst);
-	} else {
-		/*
-		 * If the SMMU can't walk tables in the CPU caches, treat them
-		 * like non-coherent DMA since we need to flush the new entries
-		 * all the way out to memory. There's no possibility of
-		 * recursion here as the SMMU table walker will not be wired
-		 * through another SMMU.
-		 */
-		dma_map_page(smmu->dev, virt_to_page(addr), offset, size,
-			     DMA_TO_DEVICE);
-	}
 }
 
 static struct iommu_gather_ops arm_smmu_gather_ops = {
@@ -899,6 +888,7 @@ static int arm_smmu_init_domain_context(struct iommu_domain *domain,
 		.ias		= ias,
 		.oas		= oas,
 		.tlb		= &arm_smmu_gather_ops,
+		.iommu_dev	= smmu->dev,
 	};
 
 	smmu_domain->smmu = smmu;
-- 
2.1.4



From will.deacon at arm.com  Mon Aug  3 06:25:49 2015
From: will.deacon at arm.com (Will Deacon)
Date: Mon,  3 Aug 2015 14:25:49 +0100
Subject: [PATCH 07/13] iommu/arm-smmu: Clean up DMA API usage
In-Reply-To: <1438608355-7335-1-git-send-email-will.deacon@arm.com>
References: <1438608355-7335-1-git-send-email-will.deacon@arm.com>
Message-ID: <1438608355-7335-8-git-send-email-will.deacon@arm.com>

From: Robin Murphy <Robin.Murphy at arm.com>

With the correct DMA API calls now integrated into the io-pgtable code,
let that handle the flushing of non-coherent page table updates.

Signed-off-by: Robin Murphy <robin.murphy at arm.com>
Signed-off-by: Will Deacon <will.deacon at arm.com>
---
 drivers/iommu/arm-smmu-v3.c | 18 +++---------------
 1 file changed, 3 insertions(+), 15 deletions(-)

diff --git a/drivers/iommu/arm-smmu-v3.c b/drivers/iommu/arm-smmu-v3.c
index 4f093373f4c3..38a891e28e13 100644
--- a/drivers/iommu/arm-smmu-v3.c
+++ b/drivers/iommu/arm-smmu-v3.c
@@ -1334,23 +1334,10 @@ static void arm_smmu_tlb_inv_range_nosync(unsigned long iova, size_t size,
 static void arm_smmu_flush_pgtable(void *addr, size_t size, void *cookie)
 {
 	struct arm_smmu_domain *smmu_domain = cookie;
-	struct arm_smmu_device *smmu = smmu_domain->smmu;
-	unsigned long offset = (unsigned long)addr & ~PAGE_MASK;
 
-	if (smmu->features & ARM_SMMU_FEAT_COHERENCY) {
+	/* The page table code handles flushing in the non-coherent case */
+	if (smmu_domain->smmu->features & ARM_SMMU_FEAT_COHERENCY)
 		dsb(ishst);
-	} else {
-		dma_addr_t dma_addr;
-		struct device *dev = smmu->dev;
-
-		dma_addr = dma_map_page(dev, virt_to_page(addr), offset, size,
-					DMA_TO_DEVICE);
-
-		if (dma_mapping_error(dev, dma_addr))
-			dev_err(dev, "failed to flush pgtable at %p\n", addr);
-		else
-			dma_unmap_page(dev, dma_addr, size, DMA_TO_DEVICE);
-	}
 }
 
 static struct iommu_gather_ops arm_smmu_gather_ops = {
@@ -1532,6 +1519,7 @@ static int arm_smmu_domain_finalise(struct iommu_domain *domain)
 		.ias		= ias,
 		.oas		= oas,
 		.tlb		= &arm_smmu_gather_ops,
+		.iommu_dev	= smmu->dev,
 	};
 
 	pgtbl_ops = alloc_io_pgtable_ops(fmt, &pgtbl_cfg, smmu_domain);
-- 
2.1.4



From will.deacon at arm.com  Mon Aug  3 06:25:51 2015
From: will.deacon at arm.com (Will Deacon)
Date: Mon,  3 Aug 2015 14:25:51 +0100
Subject: [PATCH 09/13] iommu/io-pgtable-arm: Centralise sync points
In-Reply-To: <1438608355-7335-1-git-send-email-will.deacon@arm.com>
References: <1438608355-7335-1-git-send-email-will.deacon@arm.com>
Message-ID: <1438608355-7335-10-git-send-email-will.deacon@arm.com>

From: Robin Murphy <Robin.Murphy at arm.com>

With all current users now opted in to DMA API operations, make the
iommu_dev pointer mandatory, rendering the flush_pgtable callback
redundant for cache maintenance. However, since the DMA calls could be
nops in the case of a coherent IOMMU, we still need to ensure the page
table updates are fully synchronised against a subsequent page table
walk. In the unmap path, the TLB sync will usually need to do this
anyway, so just cement that requirement; in the map path which may
consist solely of cacheable memory writes (in the coherent case),
insert an appropriate barrier at the end of the operation, and obviate
the need to call flush_pgtable on every individual update for
synchronisation.

Signed-off-by: Robin Murphy <robin.murphy at arm.com>
[will: slight clarification to tlb_sync comment]
Signed-off-by: Will Deacon <will.deacon at arm.com>
---
 drivers/iommu/io-pgtable-arm.c | 43 +++++++++++++++++++++++-------------------
 drivers/iommu/io-pgtable.h     |  4 +++-
 2 files changed, 27 insertions(+), 20 deletions(-)

diff --git a/drivers/iommu/io-pgtable-arm.c b/drivers/iommu/io-pgtable-arm.c
index 28cca8a652f9..06176872fb78 100644
--- a/drivers/iommu/io-pgtable-arm.c
+++ b/drivers/iommu/io-pgtable-arm.c
@@ -26,6 +26,8 @@
 #include <linux/slab.h>
 #include <linux/types.h>
 
+#include <asm/barrier.h>
+
 #include "io-pgtable.h"
 
 #define ARM_LPAE_MAX_ADDR_BITS		48
@@ -215,7 +217,7 @@ static void *__arm_lpae_alloc_pages(size_t size, gfp_t gfp,
 	if (!pages)
 		return NULL;
 
-	if (dev) {
+	if (!selftest_running) {
 		dma = dma_map_single(dev, pages, size, DMA_TO_DEVICE);
 		if (dma_mapping_error(dev, dma))
 			goto out_free;
@@ -243,24 +245,22 @@ static void __arm_lpae_free_pages(void *pages, size_t size,
 {
 	struct device *dev = cfg->iommu_dev;
 
-	if (dev)
+	if (!selftest_running)
 		dma_unmap_single(dev, __arm_lpae_dma_addr(dev, pages),
 				 size, DMA_TO_DEVICE);
 	free_pages_exact(pages, size);
 }
 
 static void __arm_lpae_set_pte(arm_lpae_iopte *ptep, arm_lpae_iopte pte,
-			       struct io_pgtable_cfg *cfg, void *cookie)
+			       struct io_pgtable_cfg *cfg)
 {
 	struct device *dev = cfg->iommu_dev;
 
 	*ptep = pte;
 
-	if (dev)
+	if (!selftest_running)
 		dma_sync_single_for_device(dev, __arm_lpae_dma_addr(dev, ptep),
 					   sizeof(pte), DMA_TO_DEVICE);
-	else if (cfg->tlb->flush_pgtable)
-		cfg->tlb->flush_pgtable(ptep, sizeof(pte), cookie);
 }
 
 static int arm_lpae_init_pte(struct arm_lpae_io_pgtable *data,
@@ -288,7 +288,7 @@ static int arm_lpae_init_pte(struct arm_lpae_io_pgtable *data,
 	pte |= ARM_LPAE_PTE_AF | ARM_LPAE_PTE_SH_IS;
 	pte |= pfn_to_iopte(paddr >> data->pg_shift, data);
 
-	__arm_lpae_set_pte(ptep, pte, cfg, data->iop.cookie);
+	__arm_lpae_set_pte(ptep, pte, cfg);
 	return 0;
 }
 
@@ -297,7 +297,6 @@ static int __arm_lpae_map(struct arm_lpae_io_pgtable *data, unsigned long iova,
 			  int lvl, arm_lpae_iopte *ptep)
 {
 	arm_lpae_iopte *cptep, pte;
-	void *cookie = data->iop.cookie;
 	size_t block_size = ARM_LPAE_BLOCK_SIZE(lvl, data);
 	struct io_pgtable_cfg *cfg = &data->iop.cfg;
 
@@ -323,7 +322,7 @@ static int __arm_lpae_map(struct arm_lpae_io_pgtable *data, unsigned long iova,
 		pte = __pa(cptep) | ARM_LPAE_PTE_TYPE_TABLE;
 		if (cfg->quirks & IO_PGTABLE_QUIRK_ARM_NS)
 			pte |= ARM_LPAE_PTE_NSTABLE;
-		__arm_lpae_set_pte(ptep, pte, cfg, cookie);
+		__arm_lpae_set_pte(ptep, pte, cfg);
 	} else {
 		cptep = iopte_deref(pte, data);
 	}
@@ -370,7 +369,7 @@ static int arm_lpae_map(struct io_pgtable_ops *ops, unsigned long iova,
 {
 	struct arm_lpae_io_pgtable *data = io_pgtable_ops_to_data(ops);
 	arm_lpae_iopte *ptep = data->pgd;
-	int lvl = ARM_LPAE_START_LVL(data);
+	int ret, lvl = ARM_LPAE_START_LVL(data);
 	arm_lpae_iopte prot;
 
 	/* If no access, then nothing to do */
@@ -378,7 +377,14 @@ static int arm_lpae_map(struct io_pgtable_ops *ops, unsigned long iova,
 		return 0;
 
 	prot = arm_lpae_prot_to_pte(data, iommu_prot);
-	return __arm_lpae_map(data, iova, paddr, size, prot, lvl, ptep);
+	ret = __arm_lpae_map(data, iova, paddr, size, prot, lvl, ptep);
+	/*
+	 * Synchronise all PTE updates for the new mapping before there's
+	 * a chance for anything to kick off a table walk for the new iova.
+	 */
+	wmb();
+
+	return ret;
 }
 
 static void __arm_lpae_free_pgtable(struct arm_lpae_io_pgtable *data, int lvl,
@@ -428,7 +434,6 @@ static int arm_lpae_split_blk_unmap(struct arm_lpae_io_pgtable *data,
 	phys_addr_t blk_paddr;
 	arm_lpae_iopte table = 0;
 	struct io_pgtable_cfg *cfg = &data->iop.cfg;
-	void *cookie = data->iop.cookie;
 
 	blk_start = iova & ~(blk_size - 1);
 	blk_end = blk_start + blk_size;
@@ -454,9 +459,9 @@ static int arm_lpae_split_blk_unmap(struct arm_lpae_io_pgtable *data,
 		}
 	}
 
-	__arm_lpae_set_pte(ptep, table, cfg, cookie);
+	__arm_lpae_set_pte(ptep, table, cfg);
 	iova &= ~(blk_size - 1);
-	cfg->tlb->tlb_add_flush(iova, blk_size, true, cookie);
+	cfg->tlb->tlb_add_flush(iova, blk_size, true, data->iop.cookie);
 	return size;
 }
 
@@ -478,7 +483,7 @@ static int __arm_lpae_unmap(struct arm_lpae_io_pgtable *data,
 
 	/* If the size matches this level, we're in the right place */
 	if (size == blk_size) {
-		__arm_lpae_set_pte(ptep, 0, &data->iop.cfg, cookie);
+		__arm_lpae_set_pte(ptep, 0, &data->iop.cfg);
 
 		if (!iopte_leaf(pte, lvl)) {
 			/* Also flush any partial walks */
@@ -703,8 +708,8 @@ arm_64_lpae_alloc_pgtable_s1(struct io_pgtable_cfg *cfg, void *cookie)
 	if (!data->pgd)
 		goto out_free_data;
 
-	if (cfg->tlb->flush_pgtable)
-		cfg->tlb->flush_pgtable(data->pgd, data->pgd_size, cookie);
+	/* Ensure the empty pgd is visible before any actual TTBR write */
+	wmb();
 
 	/* TTBRs */
 	cfg->arm_lpae_s1_cfg.ttbr[0] = virt_to_phys(data->pgd);
@@ -792,8 +797,8 @@ arm_64_lpae_alloc_pgtable_s2(struct io_pgtable_cfg *cfg, void *cookie)
 	if (!data->pgd)
 		goto out_free_data;
 
-	if (cfg->tlb->flush_pgtable)
-		cfg->tlb->flush_pgtable(data->pgd, data->pgd_size, cookie);
+	/* Ensure the empty pgd is visible before any actual TTBR write */
+	wmb();
 
 	/* VTTBR */
 	cfg->arm_lpae_s2_cfg.vttbr = virt_to_phys(data->pgd);
diff --git a/drivers/iommu/io-pgtable.h b/drivers/iommu/io-pgtable.h
index c69529c78914..e8fadb012ed2 100644
--- a/drivers/iommu/io-pgtable.h
+++ b/drivers/iommu/io-pgtable.h
@@ -17,7 +17,9 @@ enum io_pgtable_fmt {
  *
  * @tlb_flush_all: Synchronously invalidate the entire TLB context.
  * @tlb_add_flush: Queue up a TLB invalidation for a virtual address range.
- * @tlb_sync:      Ensure any queue TLB invalidation has taken effect.
+ * @tlb_sync:      Ensure any queued TLB invalidation has taken effect, and
+ *                 any corresponding page table updates are visible to the
+ *                 IOMMU.
  * @flush_pgtable: Ensure page table updates are visible to the IOMMU.
  *
  * Note that these can all be called in atomic context and must therefore
-- 
2.1.4



From boris.brezillon at free-electrons.com  Mon Aug  3 06:30:04 2015
From: boris.brezillon at free-electrons.com (Boris Brezillon)
Date: Mon, 3 Aug 2015 15:30:04 +0200
Subject: [PATCH 1/3] clocksource: atmel-st: Remove irq handler when
 clock event is unused
In-Reply-To: <20150802094028.GN12596@twins.programming.kicks-ass.net>
References: <1437161608-26782-1-git-send-email-alexandre.belloni@free-electrons.com>
 <1437161608-26782-2-git-send-email-alexandre.belloni@free-electrons.com>
 <alpine.DEB.2.11.1507180942360.18576@nanos>
 <20150718222308.GA30489@piout.net>
 <alpine.DEB.2.11.1507201103550.18576@nanos>
 <20150720193726.GJ15539@piout.net>
 <alpine.DEB.2.11.1507202245310.18576@nanos>
 <alpine.DEB.2.11.1508021100390.3825@nanos>
 <20150802094028.GN12596@twins.programming.kicks-ass.net>
Message-ID: <20150803153004.4a74d99a@bbrezillon>

Peter, Thomas,

On Sun, 2 Aug 2015 11:40:28 +0200
Peter Zijlstra <peterz at infradead.org> wrote:

> On Sun, Aug 02, 2015 at 11:10:21AM +0200, Thomas Gleixner wrote:
> > I think Boris Brezillon had implemented it at some point, but it was
> > shot down for reasons I can't remember. 
> 
> You weren't around at the time.. DT people didn't like it, said they
> didn't like having to make up fake hardware in their DT crap.

I don't know who was right, but the fact is they won't be inclined to
take such an approach unless the virtual demuxer is not exposed in the
DT, which is almost impossible since irq users are identifying their
irq lines with a phandle to the interrupt controller and an interrupt
id (usually extracted from the datasheet).

Anyway, below is a solution providing a way to disable specific
handlers without reworking the way we are modeling shared interrupts.
Thomas, I know you were not in favor of the proposed approach, but,
AFAICT, it does not add any conditional path to the interrupt handling
path (which, IIRC, was one of your requirements), and is simple enough
to be used by people really needing it.

There's probably other drawback I haven't noticed, so please don't
hesitate to share your thoughts.

Thanks,

Boris

--- >8 ---

From 3add0dceff714d94748106eba9867ea9aa3cd6a8 Mon Sep 17 00:00:00 2001
From: Boris Brezillon <boris.brezillon at free-electrons.com>
Date: Mon, 3 Aug 2015 15:18:08 +0200
Subject: [PATCH] irq: add disable_irq_handler()/enable_irq_handler() functions

Sometime we need to disable a specific handler on a shared irq line.
Currently, the only way this can be achieved is by freeing the irq handler
when we want to disable the irq and creating a new one when we want to
enable it.
This is not only adding some overhead to the disable/enable operations, but
the request_irq function cannot be called in atomic context, which means
it prevents disabling the interrupt in such situation.

This patch introduces three new functions: disable_irq_handler(),
disable_irq_handler_nosync() and enable_irq_handler() to allow disabling
a specific handler on a shared irq line.

Signed-off-by: Boris Brezillon <boris.brezillon at free-electrons.com>
---
 include/linux/irqdesc.h |  1 +
 kernel/irq/manage.c     | 82 +++++++++++++++++++++++++++++++++++++++++++++++++
 2 files changed, 83 insertions(+)

diff --git a/include/linux/irqdesc.h b/include/linux/irqdesc.h
index fcea4e4..c8bd055 100644
--- a/include/linux/irqdesc.h
+++ b/include/linux/irqdesc.h
@@ -52,6 +52,7 @@ struct irq_desc {
 	irq_preflow_handler_t	preflow_handler;
 #endif
 	struct irqaction	*action;	/* IRQ action list */
+	struct irqaction	*disabled_actions;	/* IRQ disabled action list */
 	unsigned int		status_use_accessors;
 	unsigned int		core_internal_state__do_not_mess_with_it;
 	unsigned int		depth;		/* nested irq disables */
diff --git a/kernel/irq/manage.c b/kernel/irq/manage.c
index f974485..4690ab4 100644
--- a/kernel/irq/manage.c
+++ b/kernel/irq/manage.c
@@ -458,6 +458,47 @@ void disable_irq_nosync(unsigned int irq)
 }
 EXPORT_SYMBOL(disable_irq_nosync);
 
+static int __disable_irq_handler_nosync(unsigned int irq, void *dev_id)
+{
+	unsigned long flags;
+	struct irqaction *action, **prev;
+	struct irq_desc *desc = irq_get_desc_buslock(irq, &flags, IRQ_GET_DESC_CHECK_GLOBAL);
+	int ret = 0;
+
+	if (!desc)
+		return -EINVAL;
+
+	for (action = desc->action, prev = &desc->action; action; action = action->next) {
+		if (action->dev_id == dev_id)
+			break;
+
+		prev = &action->next;
+	}
+
+	if (!action)
+		goto out;
+
+	*prev = action->next;
+
+	action->next = desc->disabled_actions;
+	desc->disabled_actions = action;
+	if (!desc->action) {
+		__disable_irq(desc, irq);
+		ret = 1;
+	}
+
+out:
+	irq_put_desc_busunlock(desc, flags);
+	return ret;
+}
+
+static void disable_irq_handler_nosync(unsigned int irq, void *dev_id)
+{
+	__disable_irq_handler_nosync(irq, dev_id);
+}
+EXPORT_SYMBOL(disable_irq_handler_nosync);
+
+
 /**
  *	disable_irq - disable an irq and wait for completion
  *	@irq: Interrupt to disable
@@ -477,6 +518,13 @@ void disable_irq(unsigned int irq)
 }
 EXPORT_SYMBOL(disable_irq);
 
+void disable_irq_handler(unsigned int irq, )
+{
+	if (__disable_irq_handler_nosync(irq) > 0)
+		synchronize_irq(irq);
+}
+EXPORT_SYMBOL(disable_irq);
+
 /**
  *	disable_hardirq - disables an irq and waits for hardirq completion
  *	@irq: Interrupt to disable
@@ -552,6 +600,40 @@ out:
 }
 EXPORT_SYMBOL(enable_irq);
 
+void enable_irq_handler(unsigned int irq, void *dev_id)
+{
+	unsigned long flags;
+	struct irqaction *action, **prev;
+	struct irq_desc *desc = irq_get_desc_buslock(irq, &flags, IRQ_GET_DESC_CHECK_GLOBAL);
+
+	if (!desc)
+		return -EINVAL;
+
+	for (action = desc->disabled_actions, prev = &desc->action; action;
+	     action = action->next) {
+		if (action->dev_id == dev_id)
+			break;
+
+		prev = &action->next;
+	}
+
+	if (!action)
+		goto out;
+
+	*prev = action->next;
+
+	action->next = desc->action;
+	desc->action = action;
+
+	if (!action->next)
+		__enable_irq(desc, irq);
+
+out:
+	irq_put_desc_busunlock(desc, flags);
+
+}
+EXPORT_SYMBOL(enable_irq_handler);
+
 static int set_irq_wake_real(unsigned int irq, unsigned int on)
 {
 	struct irq_desc *desc = irq_to_desc(irq);
-- 
1.9.1


From will.deacon at arm.com  Mon Aug  3 06:25:55 2015
From: will.deacon at arm.com (Will Deacon)
Date: Mon,  3 Aug 2015 14:25:55 +0100
Subject: [PATCH 13/13] iommu/arm-smmu: Treat unknown OAS as 48-bit
In-Reply-To: <1438608355-7335-1-git-send-email-will.deacon@arm.com>
References: <1438608355-7335-1-git-send-email-will.deacon@arm.com>
Message-ID: <1438608355-7335-14-git-send-email-will.deacon@arm.com>

A late change to the SMMUv3 architecture ensures that the OAS field
will be monotonically increasing, so we can assume that an unknown OAS
is at least 48-bit and use that, rather than fail the device probe.

Signed-off-by: Will Deacon <will.deacon at arm.com>
---
 drivers/iommu/arm-smmu-v3.c | 7 +++----
 1 file changed, 3 insertions(+), 4 deletions(-)

diff --git a/drivers/iommu/arm-smmu-v3.c b/drivers/iommu/arm-smmu-v3.c
index 15fb669282b4..a435e706226a 100644
--- a/drivers/iommu/arm-smmu-v3.c
+++ b/drivers/iommu/arm-smmu-v3.c
@@ -2528,12 +2528,11 @@ static int arm_smmu_device_probe(struct arm_smmu_device *smmu)
 	case IDR5_OAS_44_BIT:
 		smmu->oas = 44;
 		break;
+	default:
+		dev_info(smmu->dev,
+			"unknown output address size. Truncating to 48-bit\n");
 	case IDR5_OAS_48_BIT:
 		smmu->oas = 48;
-		break;
-	default:
-		dev_err(smmu->dev, "unknown output address size!\n");
-		return -ENXIO;
 	}
 
 	/* Set the DMA mask for our table walker */
-- 
2.1.4



From will.deacon at arm.com  Mon Aug  3 06:25:53 2015
From: will.deacon at arm.com (Will Deacon)
Date: Mon,  3 Aug 2015 14:25:53 +0100
Subject: [PATCH 11/13] iommu/arm-smmu: Remove arm_smmu_flush_pgtable()
In-Reply-To: <1438608355-7335-1-git-send-email-will.deacon@arm.com>
References: <1438608355-7335-1-git-send-email-will.deacon@arm.com>
Message-ID: <1438608355-7335-12-git-send-email-will.deacon@arm.com>

From: Robin Murphy <Robin.Murphy at arm.com>

With the io-pgtable code now enforcing its own appropriate sync points,
the vestigial flush_pgtable callback becomes entirely redundant, so
remove it altogether.

Signed-off-by: Robin Murphy <robin.murphy at arm.com>
Signed-off-by: Will Deacon <will.deacon at arm.com>
---
 drivers/iommu/arm-smmu-v3.c | 10 ----------
 1 file changed, 10 deletions(-)

diff --git a/drivers/iommu/arm-smmu-v3.c b/drivers/iommu/arm-smmu-v3.c
index 38a891e28e13..15fb669282b4 100644
--- a/drivers/iommu/arm-smmu-v3.c
+++ b/drivers/iommu/arm-smmu-v3.c
@@ -1331,20 +1331,10 @@ static void arm_smmu_tlb_inv_range_nosync(unsigned long iova, size_t size,
 	arm_smmu_cmdq_issue_cmd(smmu, &cmd);
 }
 
-static void arm_smmu_flush_pgtable(void *addr, size_t size, void *cookie)
-{
-	struct arm_smmu_domain *smmu_domain = cookie;
-
-	/* The page table code handles flushing in the non-coherent case */
-	if (smmu_domain->smmu->features & ARM_SMMU_FEAT_COHERENCY)
-		dsb(ishst);
-}
-
 static struct iommu_gather_ops arm_smmu_gather_ops = {
 	.tlb_flush_all	= arm_smmu_tlb_inv_context,
 	.tlb_add_flush	= arm_smmu_tlb_inv_range_nosync,
 	.tlb_sync	= arm_smmu_tlb_sync,
-	.flush_pgtable	= arm_smmu_flush_pgtable,
 };
 
 /* IOMMU API */
-- 
2.1.4



From will.deacon at arm.com  Mon Aug  3 06:25:52 2015
From: will.deacon at arm.com (Will Deacon)
Date: Mon,  3 Aug 2015 14:25:52 +0100
Subject: [PATCH 10/13] iommu/arm-smmu: Remove arm_smmu_flush_pgtable()
In-Reply-To: <1438608355-7335-1-git-send-email-will.deacon@arm.com>
References: <1438608355-7335-1-git-send-email-will.deacon@arm.com>
Message-ID: <1438608355-7335-11-git-send-email-will.deacon@arm.com>

From: Robin Murphy <Robin.Murphy at arm.com>

With the io-pgtable code now enforcing its own appropriate sync points,
the vestigial flush_pgtable callback becomes entirely redundant, so
remove it altogether.

Signed-off-by: Robin Murphy <robin.murphy at arm.com>
Signed-off-by: Will Deacon <will.deacon at arm.com>
---
 drivers/iommu/arm-smmu.c | 13 -------------
 1 file changed, 13 deletions(-)

diff --git a/drivers/iommu/arm-smmu.c b/drivers/iommu/arm-smmu.c
index 5770ab98fa38..48a39dfa9777 100644
--- a/drivers/iommu/arm-smmu.c
+++ b/drivers/iommu/arm-smmu.c
@@ -608,23 +608,10 @@ static void arm_smmu_tlb_inv_range_nosync(unsigned long iova, size_t size,
 	}
 }
 
-static void arm_smmu_flush_pgtable(void *addr, size_t size, void *cookie)
-{
-	struct arm_smmu_domain *smmu_domain = cookie;
-
-	/*
-	 * Ensure new page tables are visible to a coherent hardware walker.
-	 * The page table code deals with flushing for the non-coherent case.
-	 */
-	if (smmu_domain->smmu->features & ARM_SMMU_FEAT_COHERENT_WALK)
-		dsb(ishst);
-}
-
 static struct iommu_gather_ops arm_smmu_gather_ops = {
 	.tlb_flush_all	= arm_smmu_tlb_inv_context,
 	.tlb_add_flush	= arm_smmu_tlb_inv_range_nosync,
 	.tlb_sync	= arm_smmu_tlb_sync,
-	.flush_pgtable	= arm_smmu_flush_pgtable,
 };
 
 static irqreturn_t arm_smmu_context_fault(int irq, void *dev)
-- 
2.1.4



From will.deacon at arm.com  Mon Aug  3 06:25:44 2015
From: will.deacon at arm.com (Will Deacon)
Date: Mon,  3 Aug 2015 14:25:44 +0100
Subject: [PATCH 02/13] iommu/arm-smmu: Fix MSI memory attributes to match
 specification
In-Reply-To: <1438608355-7335-1-git-send-email-will.deacon@arm.com>
References: <1438608355-7335-1-git-send-email-will.deacon@arm.com>
Message-ID: <1438608355-7335-3-git-send-email-will.deacon@arm.com>

From: Marc Zyngier <marc.zyngier at arm.com>

The MSI memory attributes in the SMMUv3 driver are from an older
revision of the spec, which doesn't match the current implementations.

Out with the old, in with the new.

Signed-off-by: Marc Zyngier <marc.zyngier at arm.com>
Signed-off-by: Will Deacon <will.deacon at arm.com>
---
 drivers/iommu/arm-smmu-v3.c | 12 ++++++------
 1 file changed, 6 insertions(+), 6 deletions(-)

diff --git a/drivers/iommu/arm-smmu-v3.c b/drivers/iommu/arm-smmu-v3.c
index 5d2cbdab5afa..c2c1ad8915d9 100644
--- a/drivers/iommu/arm-smmu-v3.c
+++ b/drivers/iommu/arm-smmu-v3.c
@@ -174,14 +174,14 @@
 #define ARM_SMMU_PRIQ_IRQ_CFG2		0xdc
 
 /* Common MSI config fields */
-#define MSI_CFG0_SH_SHIFT		60
-#define MSI_CFG0_SH_NSH			(0UL << MSI_CFG0_SH_SHIFT)
-#define MSI_CFG0_SH_OSH			(2UL << MSI_CFG0_SH_SHIFT)
-#define MSI_CFG0_SH_ISH			(3UL << MSI_CFG0_SH_SHIFT)
-#define MSI_CFG0_MEMATTR_SHIFT		56
-#define MSI_CFG0_MEMATTR_DEVICE_nGnRE	(0x1 << MSI_CFG0_MEMATTR_SHIFT)
 #define MSI_CFG0_ADDR_SHIFT		2
 #define MSI_CFG0_ADDR_MASK		0x3fffffffffffUL
+#define MSI_CFG2_SH_SHIFT		4
+#define MSI_CFG2_SH_NSH			(0UL << MSI_CFG2_SH_SHIFT)
+#define MSI_CFG2_SH_OSH			(2UL << MSI_CFG2_SH_SHIFT)
+#define MSI_CFG2_SH_ISH			(3UL << MSI_CFG2_SH_SHIFT)
+#define MSI_CFG2_MEMATTR_SHIFT		0
+#define MSI_CFG2_MEMATTR_DEVICE_nGnRE	(0x1 << MSI_CFG2_MEMATTR_SHIFT)
 
 #define Q_IDX(q, p)			((p) & ((1 << (q)->max_n_shift) - 1))
 #define Q_WRP(q, p)			((p) & (1 << (q)->max_n_shift))
-- 
2.1.4



From will.deacon at arm.com  Mon Aug  3 06:25:45 2015
From: will.deacon at arm.com (Will Deacon)
Date: Mon,  3 Aug 2015 14:25:45 +0100
Subject: [PATCH 03/13] iommu/arm-smmu: Limit 2-level strtab allocation for
 small SID sizes
In-Reply-To: <1438608355-7335-1-git-send-email-will.deacon@arm.com>
References: <1438608355-7335-1-git-send-email-will.deacon@arm.com>
Message-ID: <1438608355-7335-4-git-send-email-will.deacon@arm.com>

If the StreamIDs in a system can all be resolved by a single level-2
stream table (i.e. SIDSIZE < SPLIT), then we currently get our maths
wrong and allocate the largest strtab we support, thanks to unsigned
overflow in our calculation.

This patch fixes the issue by checking the SIDSIZE explicitly when
calculating the size of our first-level stream table.

Reported-by: Matt Evans <matt.evans at arm.com>
Signed-off-by: Will Deacon <will.deacon at arm.com>
---
 drivers/iommu/arm-smmu-v3.c | 14 +++++++++++---
 1 file changed, 11 insertions(+), 3 deletions(-)

diff --git a/drivers/iommu/arm-smmu-v3.c b/drivers/iommu/arm-smmu-v3.c
index c2c1ad8915d9..4f093373f4c3 100644
--- a/drivers/iommu/arm-smmu-v3.c
+++ b/drivers/iommu/arm-smmu-v3.c
@@ -2054,9 +2054,17 @@ static int arm_smmu_init_strtab_2lvl(struct arm_smmu_device *smmu)
 	int ret;
 	struct arm_smmu_strtab_cfg *cfg = &smmu->strtab_cfg;
 
-	/* Calculate the L1 size, capped to the SIDSIZE */
-	size = STRTAB_L1_SZ_SHIFT - (ilog2(STRTAB_L1_DESC_DWORDS) + 3);
-	size = min(size, smmu->sid_bits - STRTAB_SPLIT);
+	/*
+	 * If we can resolve everything with a single L2 table, then we
+	 * just need a single L1 descriptor. Otherwise, calculate the L1
+	 * size, capped to the SIDSIZE.
+	 */
+	if (smmu->sid_bits < STRTAB_SPLIT) {
+		size = 0;
+	} else {
+		size = STRTAB_L1_SZ_SHIFT - (ilog2(STRTAB_L1_DESC_DWORDS) + 3);
+		size = min(size, smmu->sid_bits - STRTAB_SPLIT);
+	}
 	cfg->num_l1_ents = 1 << size;
 
 	size += STRTAB_SPLIT;
-- 
2.1.4



From will.deacon at arm.com  Mon Aug  3 06:25:42 2015
From: will.deacon at arm.com (Will Deacon)
Date: Mon,  3 Aug 2015 14:25:42 +0100
Subject: [PATCH 00/13] iommu/arm-smmu: Updates for 4.3
Message-ID: <1438608355-7335-1-git-send-email-will.deacon@arm.com>

Hi all,

This is the ARM SMMU driver queue I currently have for 4.3. The diffstat
is slightly noisy since Robin cleaned up the DMA API usage in the
io-pgtable code so the client drivers no longer need to perform
dma_map_page hacks in order to clean the CPU caches on non-coherent
systems.

Other changes include some MSI prep., a couple of minor fixes for
SMMUv3 and honouring of the dma-coherent property for SMMUv1/2.

In the absence of any issues, I plan to send a pull request to Joerg
later this week.

Cheers,

Will

--->8

Marc Zyngier (2):
  iommu/arm-smmu: Fix enabling of PRIQ interrupt
  iommu/arm-smmu: Fix MSI memory attributes to match specification

Robin Murphy (9):
  iommu/arm-smmu: Sort out coherency
  iommu/io-pgtable-arm: Allow appropriate DMA API use
  iommu/arm-smmu: Clean up DMA API usage
  iommu/arm-smmu: Clean up DMA API usage
  iommu/ipmmu-vmsa: Clean up DMA API usage
  iommu/io-pgtable-arm: Centralise sync points
  iommu/arm-smmu: Remove arm_smmu_flush_pgtable()
  iommu/arm-smmu: Remove arm_smmu_flush_pgtable()
  iommu/io-pgtable: Remove flush_pgtable callback

Will Deacon (2):
  iommu/arm-smmu: Limit 2-level strtab allocation for small SID sizes
  iommu/arm-smmu: Treat unknown OAS as 48-bit

 .../devicetree/bindings/iommu/arm,smmu.txt         |   6 +
 drivers/iommu/Kconfig                              |   3 +-
 drivers/iommu/arm-smmu-v3.c                        |  65 +++++------
 drivers/iommu/arm-smmu.c                           |  45 +++-----
 drivers/iommu/io-pgtable-arm.c                     | 126 +++++++++++++++------
 drivers/iommu/io-pgtable.h                         |   9 +-
 drivers/iommu/ipmmu-vmsa.c                         |  19 +---
 7 files changed, 156 insertions(+), 117 deletions(-)

-- 
2.1.4



From will.deacon at arm.com  Mon Aug  3 06:25:43 2015
From: will.deacon at arm.com (Will Deacon)
Date: Mon,  3 Aug 2015 14:25:43 +0100
Subject: [PATCH 01/13] iommu/arm-smmu: Fix enabling of PRIQ interrupt
In-Reply-To: <1438608355-7335-1-git-send-email-will.deacon@arm.com>
References: <1438608355-7335-1-git-send-email-will.deacon@arm.com>
Message-ID: <1438608355-7335-2-git-send-email-will.deacon@arm.com>

From: Marc Zyngier <marc.zyngier at arm.com>

When an ARM SMMUv3 instance supports PRI, the driver registers
an interrupt handler, but fails to enable the generation of
such interrupt at the SMMU level.

This patches simply moves the enable flags to a variable that
gets updated by the PRI handling code before being written to the
SMMU register.

Signed-off-by: Marc Zyngier <marc.zyngier at arm.com>
Signed-off-by: Will Deacon <will.deacon at arm.com>
---
 drivers/iommu/arm-smmu-v3.c | 8 +++++---
 1 file changed, 5 insertions(+), 3 deletions(-)

diff --git a/drivers/iommu/arm-smmu-v3.c b/drivers/iommu/arm-smmu-v3.c
index da902baaa794..5d2cbdab5afa 100644
--- a/drivers/iommu/arm-smmu-v3.c
+++ b/drivers/iommu/arm-smmu-v3.c
@@ -118,6 +118,7 @@
 
 #define ARM_SMMU_IRQ_CTRL		0x50
 #define IRQ_CTRL_EVTQ_IRQEN		(1 << 2)
+#define IRQ_CTRL_PRIQ_IRQEN		(1 << 1)
 #define IRQ_CTRL_GERROR_IRQEN		(1 << 0)
 
 #define ARM_SMMU_IRQ_CTRLACK		0x54
@@ -2198,6 +2199,7 @@ static int arm_smmu_write_reg_sync(struct arm_smmu_device *smmu, u32 val,
 static int arm_smmu_setup_irqs(struct arm_smmu_device *smmu)
 {
 	int ret, irq;
+	u32 irqen_flags = IRQ_CTRL_EVTQ_IRQEN | IRQ_CTRL_GERROR_IRQEN;
 
 	/* Disable IRQs first */
 	ret = arm_smmu_write_reg_sync(smmu, 0, ARM_SMMU_IRQ_CTRL,
@@ -2252,13 +2254,13 @@ static int arm_smmu_setup_irqs(struct arm_smmu_device *smmu)
 			if (IS_ERR_VALUE(ret))
 				dev_warn(smmu->dev,
 					 "failed to enable priq irq\n");
+			else
+				irqen_flags |= IRQ_CTRL_PRIQ_IRQEN;
 		}
 	}
 
 	/* Enable interrupt generation on the SMMU */
-	ret = arm_smmu_write_reg_sync(smmu,
-				      IRQ_CTRL_EVTQ_IRQEN |
-				      IRQ_CTRL_GERROR_IRQEN,
+	ret = arm_smmu_write_reg_sync(smmu, irqen_flags,
 				      ARM_SMMU_IRQ_CTRL, ARM_SMMU_IRQ_CTRLACK);
 	if (ret)
 		dev_warn(smmu->dev, "failed to enable irqs\n");
-- 
2.1.4



From will.deacon at arm.com  Mon Aug  3 06:25:54 2015
From: will.deacon at arm.com (Will Deacon)
Date: Mon,  3 Aug 2015 14:25:54 +0100
Subject: [PATCH 12/13] iommu/io-pgtable: Remove flush_pgtable callback
In-Reply-To: <1438608355-7335-1-git-send-email-will.deacon@arm.com>
References: <1438608355-7335-1-git-send-email-will.deacon@arm.com>
Message-ID: <1438608355-7335-13-git-send-email-will.deacon@arm.com>

From: Robin Murphy <Robin.Murphy at arm.com>

With the users fully converted to DMA API operations, it's dead, Jim.

Signed-off-by: Robin Murphy <robin.murphy at arm.com>
Signed-off-by: Will Deacon <will.deacon at arm.com>
---
 drivers/iommu/io-pgtable-arm.c | 6 ------
 drivers/iommu/io-pgtable.h     | 2 --
 2 files changed, 8 deletions(-)

diff --git a/drivers/iommu/io-pgtable-arm.c b/drivers/iommu/io-pgtable-arm.c
index 06176872fb78..e4bc2b23ab96 100644
--- a/drivers/iommu/io-pgtable-arm.c
+++ b/drivers/iommu/io-pgtable-arm.c
@@ -884,16 +884,10 @@ static void dummy_tlb_sync(void *cookie)
 	WARN_ON(cookie != cfg_cookie);
 }
 
-static void dummy_flush_pgtable(void *ptr, size_t size, void *cookie)
-{
-	WARN_ON(cookie != cfg_cookie);
-}
-
 static struct iommu_gather_ops dummy_tlb_ops __initdata = {
 	.tlb_flush_all	= dummy_tlb_flush_all,
 	.tlb_add_flush	= dummy_tlb_add_flush,
 	.tlb_sync	= dummy_tlb_sync,
-	.flush_pgtable	= dummy_flush_pgtable,
 };
 
 static void __init arm_lpae_dump_ops(struct io_pgtable_ops *ops)
diff --git a/drivers/iommu/io-pgtable.h b/drivers/iommu/io-pgtable.h
index e8fadb012ed2..48538a35d078 100644
--- a/drivers/iommu/io-pgtable.h
+++ b/drivers/iommu/io-pgtable.h
@@ -20,7 +20,6 @@ enum io_pgtable_fmt {
  * @tlb_sync:      Ensure any queued TLB invalidation has taken effect, and
  *                 any corresponding page table updates are visible to the
  *                 IOMMU.
- * @flush_pgtable: Ensure page table updates are visible to the IOMMU.
  *
  * Note that these can all be called in atomic context and must therefore
  * not block.
@@ -30,7 +29,6 @@ struct iommu_gather_ops {
 	void (*tlb_add_flush)(unsigned long iova, size_t size, bool leaf,
 			      void *cookie);
 	void (*tlb_sync)(void *cookie);
-	void (*flush_pgtable)(void *ptr, size_t size, void *cookie);
 };
 
 /**
-- 
2.1.4



From will.deacon at arm.com  Mon Aug  3 06:25:50 2015
From: will.deacon at arm.com (Will Deacon)
Date: Mon,  3 Aug 2015 14:25:50 +0100
Subject: [PATCH 08/13] iommu/ipmmu-vmsa: Clean up DMA API usage
In-Reply-To: <1438608355-7335-1-git-send-email-will.deacon@arm.com>
References: <1438608355-7335-1-git-send-email-will.deacon@arm.com>
Message-ID: <1438608355-7335-9-git-send-email-will.deacon@arm.com>

From: Robin Murphy <Robin.Murphy at arm.com>

With the correct DMA API calls now integrated into the io-pgtable code,
let that handle the flushing of non-coherent page table updates.

Signed-off-by: Robin Murphy <robin.murphy at arm.com>
Signed-off-by: Will Deacon <will.deacon at arm.com>
---
 drivers/iommu/ipmmu-vmsa.c | 19 +++++--------------
 1 file changed, 5 insertions(+), 14 deletions(-)

diff --git a/drivers/iommu/ipmmu-vmsa.c b/drivers/iommu/ipmmu-vmsa.c
index 1a67c531a07e..8cf605fa9946 100644
--- a/drivers/iommu/ipmmu-vmsa.c
+++ b/drivers/iommu/ipmmu-vmsa.c
@@ -283,24 +283,10 @@ static void ipmmu_tlb_add_flush(unsigned long iova, size_t size, bool leaf,
 	/* The hardware doesn't support selective TLB flush. */
 }
 
-static void ipmmu_flush_pgtable(void *ptr, size_t size, void *cookie)
-{
-	unsigned long offset = (unsigned long)ptr & ~PAGE_MASK;
-	struct ipmmu_vmsa_domain *domain = cookie;
-
-	/*
-	 * TODO: Add support for coherent walk through CCI with DVM and remove
-	 * cache handling.
-	 */
-	dma_map_page(domain->mmu->dev, virt_to_page(ptr), offset, size,
-		     DMA_TO_DEVICE);
-}
-
 static struct iommu_gather_ops ipmmu_gather_ops = {
 	.tlb_flush_all = ipmmu_tlb_flush_all,
 	.tlb_add_flush = ipmmu_tlb_add_flush,
 	.tlb_sync = ipmmu_tlb_flush_all,
-	.flush_pgtable = ipmmu_flush_pgtable,
 };
 
 /* -----------------------------------------------------------------------------
@@ -327,6 +313,11 @@ static int ipmmu_domain_init_context(struct ipmmu_vmsa_domain *domain)
 	domain->cfg.ias = 32;
 	domain->cfg.oas = 40;
 	domain->cfg.tlb = &ipmmu_gather_ops;
+	/*
+	 * TODO: Add support for coherent walk through CCI with DVM and remove
+	 * cache handling. For now, delegate it to the io-pgtable code.
+	 */
+	domain->cfg.iommu_dev = domain->mmu->dev;
 
 	domain->iop = alloc_io_pgtable_ops(ARM_32_LPAE_S1, &domain->cfg,
 					   domain);
-- 
2.1.4



From will.deacon at arm.com  Mon Aug  3 06:25:46 2015
From: will.deacon at arm.com (Will Deacon)
Date: Mon,  3 Aug 2015 14:25:46 +0100
Subject: [PATCH 04/13] iommu/arm-smmu: Sort out coherency
In-Reply-To: <1438608355-7335-1-git-send-email-will.deacon@arm.com>
References: <1438608355-7335-1-git-send-email-will.deacon@arm.com>
Message-ID: <1438608355-7335-5-git-send-email-will.deacon@arm.com>

From: Robin Murphy <Robin.Murphy at arm.com>

Currently, we detect whether the SMMU has coherent page table walk
capability from the IDR0.CTTW field, and base our cache maintenance
decisions on that. In preparation for fixing the bogus DMA API usage,
however, we need to ensure that the DMA API agrees about this, which
necessitates deferring to the dma-coherent property in the device tree
for the final say.

As an added bonus, since systems exist where an external CTTW signal
has been tied off incorrectly at integration, allowing DT to override
it offers a neat workaround for coherency issues with such SMMUs.

Signed-off-by: Robin Murphy <robin.murphy at arm.com>
Signed-off-by: Will Deacon <will.deacon at arm.com>
---
 Documentation/devicetree/bindings/iommu/arm,smmu.txt |  6 ++++++
 drivers/iommu/arm-smmu.c                             | 20 +++++++++++++++++---
 2 files changed, 23 insertions(+), 3 deletions(-)

diff --git a/Documentation/devicetree/bindings/iommu/arm,smmu.txt b/Documentation/devicetree/bindings/iommu/arm,smmu.txt
index 06760503a819..718074501fcb 100644
--- a/Documentation/devicetree/bindings/iommu/arm,smmu.txt
+++ b/Documentation/devicetree/bindings/iommu/arm,smmu.txt
@@ -43,6 +43,12 @@ conditions.
 
 ** System MMU optional properties:
 
+- dma-coherent  : Present if page table walks made by the SMMU are
+                  cache coherent with the CPU.
+
+                  NOTE: this only applies to the SMMU itself, not
+                  masters connected upstream of the SMMU.
+
 - calxeda,smmu-secure-config-access : Enable proper handling of buggy
                   implementations that always use secure access to
                   SMMU configuration registers. In this case non-secure
diff --git a/drivers/iommu/arm-smmu.c b/drivers/iommu/arm-smmu.c
index 4cd0c29cb585..0583ed2f33c0 100644
--- a/drivers/iommu/arm-smmu.c
+++ b/drivers/iommu/arm-smmu.c
@@ -37,6 +37,7 @@
 #include <linux/iopoll.h>
 #include <linux/module.h>
 #include <linux/of.h>
+#include <linux/of_address.h>
 #include <linux/pci.h>
 #include <linux/platform_device.h>
 #include <linux/slab.h>
@@ -1532,6 +1533,7 @@ static int arm_smmu_device_cfg_probe(struct arm_smmu_device *smmu)
 	unsigned long size;
 	void __iomem *gr0_base = ARM_SMMU_GR0(smmu);
 	u32 id;
+	bool cttw_dt, cttw_reg;
 
 	dev_notice(smmu->dev, "probing hardware configuration...\n");
 	dev_notice(smmu->dev, "SMMUv%d with:\n", smmu->version);
@@ -1571,10 +1573,22 @@ static int arm_smmu_device_cfg_probe(struct arm_smmu_device *smmu)
 		dev_notice(smmu->dev, "\taddress translation ops\n");
 	}
 
-	if (id & ID0_CTTW) {
+	/*
+	 * In order for DMA API calls to work properly, we must defer to what
+	 * the DT says about coherency, regardless of what the hardware claims.
+	 * Fortunately, this also opens up a workaround for systems where the
+	 * ID register value has ended up configured incorrectly.
+	 */
+	cttw_dt = of_dma_is_coherent(smmu->dev->of_node);
+	cttw_reg = !!(id & ID0_CTTW);
+	if (cttw_dt)
 		smmu->features |= ARM_SMMU_FEAT_COHERENT_WALK;
-		dev_notice(smmu->dev, "\tcoherent table walk\n");
-	}
+	if (cttw_dt || cttw_reg)
+		dev_notice(smmu->dev, "\t%scoherent table walk\n",
+			   cttw_dt ? "" : "non-");
+	if (cttw_dt != cttw_reg)
+		dev_notice(smmu->dev,
+			   "\t(IDR0.CTTW overridden by dma-coherent property)\n");
 
 	if (id & ID0_SMS) {
 		u32 smr, sid, mask;
-- 
2.1.4



From will.deacon at arm.com  Mon Aug  3 06:25:47 2015
From: will.deacon at arm.com (Will Deacon)
Date: Mon,  3 Aug 2015 14:25:47 +0100
Subject: [PATCH 05/13] iommu/io-pgtable-arm: Allow appropriate DMA API use
In-Reply-To: <1438608355-7335-1-git-send-email-will.deacon@arm.com>
References: <1438608355-7335-1-git-send-email-will.deacon@arm.com>
Message-ID: <1438608355-7335-6-git-send-email-will.deacon@arm.com>

From: Robin Murphy <Robin.Murphy at arm.com>

Currently, users of the LPAE page table code are (ab)using dma_map_page()
as a means to flush page table updates for non-coherent IOMMUs. Since
from the CPU's point of view, creating IOMMU page tables *is* passing
DMA buffers to a device (the IOMMU's page table walker), there's little
reason not to use the DMA API correctly.

Allow IOMMU drivers to opt into DMA API operations for page table
allocation and updates by providing their appropriate device pointer.
The expectation is that an LPAE IOMMU should have a full view of system
memory, so use streaming mappings to avoid unnecessary pressure on
ZONE_DMA, and treat any DMA translation as a warning sign.

Signed-off-by: Robin Murphy <robin.murphy at arm.com>
Signed-off-by: Will Deacon <will.deacon at arm.com>
---
 drivers/iommu/Kconfig          |   3 +-
 drivers/iommu/io-pgtable-arm.c | 107 ++++++++++++++++++++++++++++++++---------
 drivers/iommu/io-pgtable.h     |   3 ++
 3 files changed, 89 insertions(+), 24 deletions(-)

diff --git a/drivers/iommu/Kconfig b/drivers/iommu/Kconfig
index f1fb1d3ccc56..d77a848d50de 100644
--- a/drivers/iommu/Kconfig
+++ b/drivers/iommu/Kconfig
@@ -23,7 +23,8 @@ config IOMMU_IO_PGTABLE
 config IOMMU_IO_PGTABLE_LPAE
 	bool "ARMv7/v8 Long Descriptor Format"
 	select IOMMU_IO_PGTABLE
-	depends on ARM || ARM64 || COMPILE_TEST
+	# SWIOTLB guarantees a dma_to_phys() implementation
+	depends on ARM || ARM64 || (COMPILE_TEST && SWIOTLB)
 	help
 	  Enable support for the ARM long descriptor pagetable format.
 	  This allocator supports 4K/2M/1G, 16K/32M and 64K/512M page
diff --git a/drivers/iommu/io-pgtable-arm.c b/drivers/iommu/io-pgtable-arm.c
index 4e460216bd16..28cca8a652f9 100644
--- a/drivers/iommu/io-pgtable-arm.c
+++ b/drivers/iommu/io-pgtable-arm.c
@@ -200,12 +200,76 @@ typedef u64 arm_lpae_iopte;
 
 static bool selftest_running = false;
 
+static dma_addr_t __arm_lpae_dma_addr(struct device *dev, void *pages)
+{
+	return phys_to_dma(dev, virt_to_phys(pages));
+}
+
+static void *__arm_lpae_alloc_pages(size_t size, gfp_t gfp,
+				    struct io_pgtable_cfg *cfg)
+{
+	struct device *dev = cfg->iommu_dev;
+	dma_addr_t dma;
+	void *pages = alloc_pages_exact(size, gfp | __GFP_ZERO);
+
+	if (!pages)
+		return NULL;
+
+	if (dev) {
+		dma = dma_map_single(dev, pages, size, DMA_TO_DEVICE);
+		if (dma_mapping_error(dev, dma))
+			goto out_free;
+		/*
+		 * We depend on the IOMMU being able to work with any physical
+		 * address directly, so if the DMA layer suggests it can't by
+		 * giving us back some translation, that bodes very badly...
+		 */
+		if (dma != __arm_lpae_dma_addr(dev, pages))
+			goto out_unmap;
+	}
+
+	return pages;
+
+out_unmap:
+	dev_err(dev, "Cannot accommodate DMA translation for IOMMU page tables\n");
+	dma_unmap_single(dev, dma, size, DMA_TO_DEVICE);
+out_free:
+	free_pages_exact(pages, size);
+	return NULL;
+}
+
+static void __arm_lpae_free_pages(void *pages, size_t size,
+				  struct io_pgtable_cfg *cfg)
+{
+	struct device *dev = cfg->iommu_dev;
+
+	if (dev)
+		dma_unmap_single(dev, __arm_lpae_dma_addr(dev, pages),
+				 size, DMA_TO_DEVICE);
+	free_pages_exact(pages, size);
+}
+
+static void __arm_lpae_set_pte(arm_lpae_iopte *ptep, arm_lpae_iopte pte,
+			       struct io_pgtable_cfg *cfg, void *cookie)
+{
+	struct device *dev = cfg->iommu_dev;
+
+	*ptep = pte;
+
+	if (dev)
+		dma_sync_single_for_device(dev, __arm_lpae_dma_addr(dev, ptep),
+					   sizeof(pte), DMA_TO_DEVICE);
+	else if (cfg->tlb->flush_pgtable)
+		cfg->tlb->flush_pgtable(ptep, sizeof(pte), cookie);
+}
+
 static int arm_lpae_init_pte(struct arm_lpae_io_pgtable *data,
 			     unsigned long iova, phys_addr_t paddr,
 			     arm_lpae_iopte prot, int lvl,
 			     arm_lpae_iopte *ptep)
 {
 	arm_lpae_iopte pte = prot;
+	struct io_pgtable_cfg *cfg = &data->iop.cfg;
 
 	/* We require an unmap first */
 	if (iopte_leaf(*ptep, lvl)) {
@@ -213,7 +277,7 @@ static int arm_lpae_init_pte(struct arm_lpae_io_pgtable *data,
 		return -EEXIST;
 	}
 
-	if (data->iop.cfg.quirks & IO_PGTABLE_QUIRK_ARM_NS)
+	if (cfg->quirks & IO_PGTABLE_QUIRK_ARM_NS)
 		pte |= ARM_LPAE_PTE_NS;
 
 	if (lvl == ARM_LPAE_MAX_LEVELS - 1)
@@ -224,8 +288,7 @@ static int arm_lpae_init_pte(struct arm_lpae_io_pgtable *data,
 	pte |= ARM_LPAE_PTE_AF | ARM_LPAE_PTE_SH_IS;
 	pte |= pfn_to_iopte(paddr >> data->pg_shift, data);
 
-	*ptep = pte;
-	data->iop.cfg.tlb->flush_pgtable(ptep, sizeof(*ptep), data->iop.cookie);
+	__arm_lpae_set_pte(ptep, pte, cfg, data->iop.cookie);
 	return 0;
 }
 
@@ -236,12 +299,13 @@ static int __arm_lpae_map(struct arm_lpae_io_pgtable *data, unsigned long iova,
 	arm_lpae_iopte *cptep, pte;
 	void *cookie = data->iop.cookie;
 	size_t block_size = ARM_LPAE_BLOCK_SIZE(lvl, data);
+	struct io_pgtable_cfg *cfg = &data->iop.cfg;
 
 	/* Find our entry at the current level */
 	ptep += ARM_LPAE_LVL_IDX(iova, lvl, data);
 
 	/* If we can install a leaf entry at this level, then do so */
-	if (size == block_size && (size & data->iop.cfg.pgsize_bitmap))
+	if (size == block_size && (size & cfg->pgsize_bitmap))
 		return arm_lpae_init_pte(data, iova, paddr, prot, lvl, ptep);
 
 	/* We can't allocate tables at the final level */
@@ -251,18 +315,15 @@ static int __arm_lpae_map(struct arm_lpae_io_pgtable *data, unsigned long iova,
 	/* Grab a pointer to the next level */
 	pte = *ptep;
 	if (!pte) {
-		cptep = alloc_pages_exact(1UL << data->pg_shift,
-					 GFP_ATOMIC | __GFP_ZERO);
+		cptep = __arm_lpae_alloc_pages(1UL << data->pg_shift,
+					       GFP_ATOMIC, cfg);
 		if (!cptep)
 			return -ENOMEM;
 
-		data->iop.cfg.tlb->flush_pgtable(cptep, 1UL << data->pg_shift,
-						 cookie);
 		pte = __pa(cptep) | ARM_LPAE_PTE_TYPE_TABLE;
-		if (data->iop.cfg.quirks & IO_PGTABLE_QUIRK_ARM_NS)
+		if (cfg->quirks & IO_PGTABLE_QUIRK_ARM_NS)
 			pte |= ARM_LPAE_PTE_NSTABLE;
-		*ptep = pte;
-		data->iop.cfg.tlb->flush_pgtable(ptep, sizeof(*ptep), cookie);
+		__arm_lpae_set_pte(ptep, pte, cfg, cookie);
 	} else {
 		cptep = iopte_deref(pte, data);
 	}
@@ -347,7 +408,7 @@ static void __arm_lpae_free_pgtable(struct arm_lpae_io_pgtable *data, int lvl,
 		__arm_lpae_free_pgtable(data, lvl + 1, iopte_deref(pte, data));
 	}
 
-	free_pages_exact(start, table_size);
+	__arm_lpae_free_pages(start, table_size, &data->iop.cfg);
 }
 
 static void arm_lpae_free_pgtable(struct io_pgtable *iop)
@@ -366,8 +427,8 @@ static int arm_lpae_split_blk_unmap(struct arm_lpae_io_pgtable *data,
 	unsigned long blk_start, blk_end;
 	phys_addr_t blk_paddr;
 	arm_lpae_iopte table = 0;
+	struct io_pgtable_cfg *cfg = &data->iop.cfg;
 	void *cookie = data->iop.cookie;
-	const struct iommu_gather_ops *tlb = data->iop.cfg.tlb;
 
 	blk_start = iova & ~(blk_size - 1);
 	blk_end = blk_start + blk_size;
@@ -393,10 +454,9 @@ static int arm_lpae_split_blk_unmap(struct arm_lpae_io_pgtable *data,
 		}
 	}
 
-	*ptep = table;
-	tlb->flush_pgtable(ptep, sizeof(*ptep), cookie);
+	__arm_lpae_set_pte(ptep, table, cfg, cookie);
 	iova &= ~(blk_size - 1);
-	tlb->tlb_add_flush(iova, blk_size, true, cookie);
+	cfg->tlb->tlb_add_flush(iova, blk_size, true, cookie);
 	return size;
 }
 
@@ -418,13 +478,12 @@ static int __arm_lpae_unmap(struct arm_lpae_io_pgtable *data,
 
 	/* If the size matches this level, we're in the right place */
 	if (size == blk_size) {
-		*ptep = 0;
-		tlb->flush_pgtable(ptep, sizeof(*ptep), cookie);
+		__arm_lpae_set_pte(ptep, 0, &data->iop.cfg, cookie);
 
 		if (!iopte_leaf(pte, lvl)) {
 			/* Also flush any partial walks */
 			tlb->tlb_add_flush(iova, size, false, cookie);
-			tlb->tlb_sync(data->iop.cookie);
+			tlb->tlb_sync(cookie);
 			ptep = iopte_deref(pte, data);
 			__arm_lpae_free_pgtable(data, lvl + 1, ptep);
 		} else {
@@ -640,11 +699,12 @@ arm_64_lpae_alloc_pgtable_s1(struct io_pgtable_cfg *cfg, void *cookie)
 	cfg->arm_lpae_s1_cfg.mair[1] = 0;
 
 	/* Looking good; allocate a pgd */
-	data->pgd = alloc_pages_exact(data->pgd_size, GFP_KERNEL | __GFP_ZERO);
+	data->pgd = __arm_lpae_alloc_pages(data->pgd_size, GFP_KERNEL, cfg);
 	if (!data->pgd)
 		goto out_free_data;
 
-	cfg->tlb->flush_pgtable(data->pgd, data->pgd_size, cookie);
+	if (cfg->tlb->flush_pgtable)
+		cfg->tlb->flush_pgtable(data->pgd, data->pgd_size, cookie);
 
 	/* TTBRs */
 	cfg->arm_lpae_s1_cfg.ttbr[0] = virt_to_phys(data->pgd);
@@ -728,11 +788,12 @@ arm_64_lpae_alloc_pgtable_s2(struct io_pgtable_cfg *cfg, void *cookie)
 	cfg->arm_lpae_s2_cfg.vtcr = reg;
 
 	/* Allocate pgd pages */
-	data->pgd = alloc_pages_exact(data->pgd_size, GFP_KERNEL | __GFP_ZERO);
+	data->pgd = __arm_lpae_alloc_pages(data->pgd_size, GFP_KERNEL, cfg);
 	if (!data->pgd)
 		goto out_free_data;
 
-	cfg->tlb->flush_pgtable(data->pgd, data->pgd_size, cookie);
+	if (cfg->tlb->flush_pgtable)
+		cfg->tlb->flush_pgtable(data->pgd, data->pgd_size, cookie);
 
 	/* VTTBR */
 	cfg->arm_lpae_s2_cfg.vttbr = virt_to_phys(data->pgd);
diff --git a/drivers/iommu/io-pgtable.h b/drivers/iommu/io-pgtable.h
index 10e32f69c668..c69529c78914 100644
--- a/drivers/iommu/io-pgtable.h
+++ b/drivers/iommu/io-pgtable.h
@@ -41,6 +41,8 @@ struct iommu_gather_ops {
  * @ias:           Input address (iova) size, in bits.
  * @oas:           Output address (paddr) size, in bits.
  * @tlb:           TLB management callbacks for this set of tables.
+ * @iommu_dev:     The device representing the DMA configuration for the
+ *                 page table walker.
  */
 struct io_pgtable_cfg {
 	#define IO_PGTABLE_QUIRK_ARM_NS	(1 << 0)	/* Set NS bit in PTEs */
@@ -49,6 +51,7 @@ struct io_pgtable_cfg {
 	unsigned int			ias;
 	unsigned int			oas;
 	const struct iommu_gather_ops	*tlb;
+	struct device			*iommu_dev;
 
 	/* Low-level data specific to the table format */
 	union {
-- 
2.1.4



From dave.long at linaro.org  Mon Aug  3 06:43:53 2015
From: dave.long at linaro.org (David Long)
Date: Mon, 03 Aug 2015 09:43:53 -0400
Subject: [RFC PATCH V2 00/10] ARM64: Uprobe support added
In-Reply-To: <20150803110908.GC10501@arm.com>
References: <cover.1434598237.git.panand@redhat.com>
 <20150803110908.GC10501@arm.com>
Message-ID: <55BF7019.9080007@linaro.org>

On 08/03/15 07:09, Will Deacon wrote:
> On Thu, Jun 18, 2015 at 04:58:47AM +0100, Pratyush Anand wrote:
>> These patches have been prepared on top of ARM64 kprobe v7 patches [1].
>> Keeping as RFC, because kprobe-v7 still need to be ACKed.
>
> Unfortunately, I've not seen any movement on the kprobes patches recently,
> so this is out of the picture for 4.3.
>
> Dave: did you plan to respin your series after Steve's comments on v7?
>
> Will
>

Catalin's comments last week helped me clarify in my own mind that we 
should be able to simplfy the register pushing somewhat. Will, does that 
also make sense to you?

So, also taking into consideration Steve's suggestions about 
reorganizing the asm code, I am now working on a new revision.

-dl



From dave.long at linaro.org  Mon Aug  3 06:45:35 2015
From: dave.long at linaro.org (David Long)
Date: Mon, 03 Aug 2015 09:45:35 -0400
Subject: [RFC PATCH V2 00/10] ARM64: Uprobe support added
In-Reply-To: <55BF7019.9080007@linaro.org>
References: <cover.1434598237.git.panand@redhat.com>
 <20150803110908.GC10501@arm.com> <55BF7019.9080007@linaro.org>
Message-ID: <55BF707F.7020208@linaro.org>

On 08/03/15 09:43, David Long wrote:
> On 08/03/15 07:09, Will Deacon wrote:
>> On Thu, Jun 18, 2015 at 04:58:47AM +0100, Pratyush Anand wrote:
>>> These patches have been prepared on top of ARM64 kprobe v7 patches [1].
>>> Keeping as RFC, because kprobe-v7 still need to be ACKed.
>>
>> Unfortunately, I've not seen any movement on the kprobes patches
>> recently,
>> so this is out of the picture for 4.3.
>>
>> Dave: did you plan to respin your series after Steve's comments on v7?
>>
>> Will
>>
>
> Catalin's comments last week helped me clarify in my own mind that we
> should be able to simplfy the register pushing somewhat. Will, does that
> also make sense to you?
>

^^ That question was aimed at Will Cohen, just to clarify.

> So, also taking into consideration Steve's suggestions about
> reorganizing the asm code, I am now working on a new revision.
>
> -dl
>



From ezequiel at vanguardiasur.com.ar  Mon Aug  3 06:48:55 2015
From: ezequiel at vanguardiasur.com.ar (Ezequiel Garcia)
Date: Mon, 3 Aug 2015 10:48:55 -0300
Subject: [PATCH v2 0/4] mtd: pxa3xx_nand: rework the timing setup
In-Reply-To: <87si81m15m.fsf@belgarion.home>
References: <1436281707-20106-1-git-send-email-antoine.tenart@free-electrons.com>
 <20150717134159.GC10608@kwain>
 <55A912F0.7080605@vanguardiasur.com.ar>
 <87h9p2is8e.fsf@belgarion.home>
 <CAAEAJfCcdioVQKZs9U3DP6H94BiuQ2qU21DsMKevS5+j+-XEKA@mail.gmail.com>
 <87wpxufw2v.fsf@belgarion.home>
 <CAAEAJfB3caa+DmJN=Pa8brx0uGC11QA29KJb3NQdJjXTgw-yuA@mail.gmail.com>
 <87si81m15m.fsf@belgarion.home>
Message-ID: <CAAEAJfBMpQ8nf5aLTUqrCsJkMQbnkQTB1yA5MBiJ6R4h6RgupQ@mail.gmail.com>

On 3 August 2015 at 01:44, Robert Jarzmik <robert.jarzmik at free.fr> wrote:
> Ezequiel Garcia <ezequiel at vanguardiasur.com.ar> writes:
>
>> Just tested linux-next (hence *without* the patchset) and I see
>> the same "Wait time out". In other words, pxa3xx-nand is broken
>> on PXA :/
>>
>> Interestingly, the culprit doesn't seem to be in pxa3xx-nand itself.
>> Reverting the recent commits on pxa3xx-nand doesn't help.
>>
>> ce914e6 mtd: nand: pxa3xx: fix build on ARM64
>> afca11e mtd: nand: pxa3xx: Switch FIFO draining to jiffies-based timeout
>> e5860c1 mtd: pxa3xx_nand: cleanup wait_for_completion handling
>> 7c2f717 mtd: pxa3xx_nand: initialiaze pxa3xx_flash_ids to 0
>> ed446cc Merge MTD updates into -next
>> e423c90 mtd: pxa3xx_nand: fix driver when num_cs is 0
>> 2454225 mtd: pxa3xx-nand: handle PIO in threaded interrupt
>> 8dad038 mtd: nand: pxa3xx: Fix PIO FIFO draining
>> b7e46062 mtd: pxa3xx_nand: make the driver work on big-endian systems
>> 5b3e507 mtd: nand: pxa3xx: Use ECC strength and step size devicetree binding
>> eee0166 mtd: nand: pxa3xx: Clean pxa_ecc_init() error handling
>> 17754ad mtd: nand: pxa3xx: Make of_device_id array const
>> e634ce5 mtd: nand: pxa3xx: Print actual ECC strength in error message
>>
>> Yet v3.18 succeeds to pass a few NAND blocks on nandtest.
>>
>> Robert: any ideas?
> Actually yes, I worked on that this weekend.
> Would you try the following patch [1] to see if it works for you ?
>
> The issue I see is that :
>  - there is a bug in the clk driver for pxa3xx I introduced (CKEN_AB)
>  - and shutting down the GCU clock prevents the NAND from working (I can't
>  explain that one yet)
>

IIRC, on Armada 370/XP SoCs we have two clocks feeding the NAND
controller: one for the NAND logic (not really sure?), and one for the
NAND ECC engine.

Maybe the GCU feeds the ECC?

> Cheers.
>
> --
> Robert
>
> [1] Clocks patch

Ah, good. I was almost sure it was the clock (after trying a bunch of
other stuff it was the only big change left).

I'll try this and will let you know.

> ---8>---
> diff --git a/drivers/clk/pxa/clk-pxa3xx.c b/drivers/clk/pxa/clk-pxa3xx.c
> index c677b9ab5367..a47a0c40f937 100644
> --- a/drivers/clk/pxa/clk-pxa3xx.c
> +++ b/drivers/clk/pxa/clk-pxa3xx.c
> @@ -126,7 +126,7 @@ PARENTS(pxa3xx_ac97_bus) = { "ring_osc_60mhz", "ac97" };
>  PARENTS(pxa3xx_sbus) = { "ring_osc_60mhz", "system_bus" };
>  PARENTS(pxa3xx_smemcbus) = { "ring_osc_60mhz", "smemc" };
>
> -#define CKEN_AB(bit) ((CKEN_ ## bit > 31) ? &CKENA : &CKENB)
> +#define CKEN_AB(bit) ((CKEN_ ## bit > 31) ? &CKENB : &CKENA)
>  #define PXA3XX_CKEN(dev_id, con_id, parents, mult_lp, div_lp, mult_hp, \
>                     div_hp, bit, is_lp, flags)                          \
>         PXA_CKEN(dev_id, con_id, bit, parents, mult_lp, div_lp,         \
> @@ -136,6 +136,10 @@ PARENTS(pxa3xx_smemcbus) = { "ring_osc_60mhz", "smemc" };
>                          mult_hp, div_hp, delay)                        \
>         PXA3XX_CKEN(dev_id, con_id, pxa3xx_pbus_parents, mult_lp,       \
>                     div_lp, mult_hp, div_hp, bit, pxa3xx_is_ring_osc_forced, 0)
> +#define PXA3XX_PBUS_CKENF(dev_id, con_id, bit, mult_lp, div_lp,                \
> +                         mult_hp, div_hp, delay, flag)                 \
> +       PXA3XX_CKEN(dev_id, con_id, pxa3xx_pbus_parents, mult_lp,       \
> +                   div_lp, mult_hp, div_hp, bit, pxa3xx_is_ring_osc_forced, flag)
>  #define PXA3XX_CKEN_1RATE(dev_id, con_id, bit, parents)                        \
>         PXA_CKEN_1RATE(dev_id, con_id, bit, parents,                    \
>                        CKEN_AB(bit), (CKEN_ ## bit % 32), 0)
> @@ -173,13 +177,13 @@ static struct desc_clk_cken pxa3xx_clocks[] __initdata = {
>
>  static struct desc_clk_cken pxa300_310_clocks[] __initdata = {
>
> -       PXA3XX_PBUS_CKEN("pxa3xx-gcu", NULL, PXA300_GCU, 1, 1, 1, 1, 0),
> -       PXA3XX_PBUS_CKEN("pxa3xx-nand", NULL, NAND, 1, 2, 1, 4, 0),
> +       PXA3XX_PBUS_CKENF("pxa3xx-gcu", NULL, PXA300_GCU, 1, 1, 1, 1, 0, CLK_IGNORE_UNUSED),
> +       PXA3XX_PBUS_CKENF("pxa3xx-nand", NULL, NAND, 1, 2, 1, 4, 0, CLK_IGNORE_UNUSED),
>         PXA3XX_CKEN_1RATE("pxa3xx-gpio", NULL, GPIO, pxa3xx_13MHz_bus_parents),
>  };
>
>  static struct desc_clk_cken pxa320_clocks[] __initdata = {
> -       PXA3XX_PBUS_CKEN("pxa3xx-nand", NULL, NAND, 1, 2, 1, 6, 0),
> +       PXA3XX_PBUS_CKENF("pxa3xx-nand", NULL, NAND, 1, 2, 1, 4, 0, CLK_IGNORE_UNUSED),
>         PXA3XX_PBUS_CKEN("pxa3xx-gcu", NULL, PXA320_GCU, 1, 1, 1, 1, 0),
>         PXA3XX_CKEN_1RATE("pxa3xx-gpio", NULL, GPIO, pxa3xx_13MHz_bus_parents),
>  };
> @@ -187,7 +191,7 @@ static struct desc_clk_cken pxa320_clocks[] __initdata = {
>  static struct desc_clk_cken pxa93x_clocks[] __initdata = {
>
>         PXA3XX_PBUS_CKEN("pxa3xx-gcu", NULL, PXA300_GCU, 1, 1, 1, 1, 0),
> -       PXA3XX_PBUS_CKEN("pxa3xx-nand", NULL, NAND, 1, 2, 1, 4, 0),
> +       PXA3XX_PBUS_CKENF("pxa3xx-nand", NULL, NAND, 1, 2, 1, 4, 0, CLK_IGNORE_UNUSED),
>         PXA3XX_CKEN_1RATE("pxa93x-gpio", NULL, GPIO, pxa3xx_13MHz_bus_parents),
>  };
>



-- 
Ezequiel Garc?a, VanguardiaSur
www.vanguardiasur.com.ar


From b.zolnierkie at samsung.com  Mon Aug  3 06:55:17 2015
From: b.zolnierkie at samsung.com (Bartlomiej Zolnierkiewicz)
Date: Mon, 03 Aug 2015 15:55:17 +0200
Subject: [PATCH v3 3/5] ARM: Exynos: switch to using generic cpufreq driver
 for Exynos4x12
In-Reply-To: <55BF4D41.1060903@samsung.com>
References: <1438368557-2352-1-git-send-email-b.zolnierkie@samsung.com>
 <4532306.AVvo5hem3c@amdc1976> <55BF4D41.1060903@samsung.com>
Message-ID: <2347616.SxxJmTVssu@amdc1976>


Hi,

On Monday, August 03, 2015 08:15:13 PM Krzysztof Kozlowski wrote:
> W dniu 03.08.2015 o 19:36, Bartlomiej Zolnierkiewicz pisze:
> > On Monday, August 03, 2015 03:59:26 PM Viresh Kumar wrote:
> >> On 03-08-15, 12:17, Bartlomiej Zolnierkiewicz wrote:
> >>>
> >>> Hi,
> >>>
> >>> On Saturday, August 01, 2015 04:47:21 PM Viresh Kumar wrote:
> >>>> On 31-07-15, 20:49, Bartlomiej Zolnierkiewicz wrote:
> >>>>> diff --git a/drivers/cpufreq/Kconfig b/drivers/cpufreq/Kconfig
> >>>>> index 659879a..bf6d596 100644
> >>>>> --- a/drivers/cpufreq/Kconfig
> >>>>> +++ b/drivers/cpufreq/Kconfig
> >>>>> @@ -191,6 +191,7 @@ config CPUFREQ_DT
> >>>>>  	# if CPU_THERMAL is on and THERMAL=m, CPUFREQ_DT cannot be =y:
> >>>>>  	depends on !CPU_THERMAL || THERMAL
> >>>>>  	select PM_OPP
> >>>>> +	select EXYNOS_THERMAL if ARCH_EXYNOS
> >>>>>  	help
> >>>>>  	  This adds a generic DT based cpufreq driver for frequency management.
> >>>>>  	  It supports both uniprocessor (UP) and symmetric multiprocessor (SMP)
> >>>>
> >>>> No, we shouldn't pollute generic Kconfig options with platform specific stuff.
> >>>
> >>> The old code depended on this.  You couldn't enable boost support
> >>> without enabling thermal support (ARM_EXYNOS_CPU_FREQ_BOOST_SW
> >>> config option selected EXYNOS_THERMAL).
> >>>
> >>>> Why don't you enable thermal in your .config?
> >>>
> >>> It is enabled in exynos_defconfig but without the above change it
> >>> can disabled manually which is something that we don't want.
> >>
> >> You are not getting it. I am not asking you to not select thermal, but
> >> to select it from within your architecture Kconfig option if you want.
> > 
> > OK.  Krzysztof/Kukjin do you agree with selecting EXYNOS_THERMAL
> > from ARCH_EXYNOS in the platform code?
> 
> I agree, with your explanation it seems good. Can you just add this
> justification to the commit message?

Updated patch below (I'm not resending the whole series as all other
patches remain unchanged).

> > 
> >> Over that, thermal is really an option, not a dependency. So, if
> >> someone manually disables it, its his problem not yours :)
> > 
> > I would really like it to be dependency not an option (+ I think
> > that ideally it should be checked at runtime, IOW we should be
> > checking from cpufreq-dt driver if the thermal support is enabled
> > before enabling boost support).
> 
> That would be the best. It is fine with me if you want to do this in
> consecutive patches (after applying patch selecting/depending on it in
> mach-exynos code).

---------------------8<-------------------

>From 2595b5e6164a2d1b76626e14302b148b7af5e050 Mon Sep 17 00:00:00 2001
From: Bartlomiej Zolnierkiewicz <b.zolnierkie at samsung.com>
Date: Mon, 3 Aug 2015 15:49:06 +0200
Subject: [PATCH] ARM: Exynos: switch to using generic cpufreq driver for
 Exynos4x12

The new CPU clock type allows the use of generic CPUfreq driver.
Switch Exynos4x12 to using generic cpufreq driver.

Previously (when exynos-cpufreq driver was used with boost
functionality) ARM_EXYNOS_CPU_FREQ_BOOST_SW config option
(which enabled boost functionality) selected EXYNOS_THERMAL
one.  After switching Exynos4x12 platforms to use cpufreq-dt
driver boost support is enabled in the cpufreq-dt driver
itself (because there are turbo OPPs defined in the board's
DTS file).  However we still would like to allow enabling
boost support only if thermal support is also enabled for
Exynos platforms.  To achieve this make ARCH_EXYNOS config
option select THERMAL and EXYNOS_THERMAL ones.

Please also note that the switch to use the generic cpufreq-dt
driver fixes the minor issue present with the old code (support
for 'boost' mode in the exynos-cpufreq driver was enabled for
all supported SoCs even though 'boost' frequency was provided
only for Exynos4x12 ones).

Cc: Tomasz Figa <tomasz.figa at gmail.com>
Cc: Kukjin Kim <kgene.kim at samsung.com>
Cc: Thomas Abraham <thomas.ab at samsung.com>
Cc: Javier Martinez Canillas <javier at osg.samsung.com>
Signed-off-by: Bartlomiej Zolnierkiewicz <b.zolnierkie at samsung.com>
---
 arch/arm/mach-exynos/Kconfig  | 2 ++
 arch/arm/mach-exynos/exynos.c | 2 ++
 2 files changed, 4 insertions(+)

diff --git a/arch/arm/mach-exynos/Kconfig b/arch/arm/mach-exynos/Kconfig
index 81064cd..491914c 100644
--- a/arch/arm/mach-exynos/Kconfig
+++ b/arch/arm/mach-exynos/Kconfig
@@ -25,6 +25,8 @@ menuconfig ARCH_EXYNOS
 	select S5P_DEV_MFC
 	select SRAM
 	select MFD_SYSCON
+	select THERMAL
+	select EXYNOS_THERMAL
 	help
 	  Support for SAMSUNG EXYNOS SoCs (EXYNOS4/5)
 
diff --git a/arch/arm/mach-exynos/exynos.c b/arch/arm/mach-exynos/exynos.c
index 77ac021..1c47aee 100644
--- a/arch/arm/mach-exynos/exynos.c
+++ b/arch/arm/mach-exynos/exynos.c
@@ -227,6 +227,8 @@ static void __init exynos_init_irq(void)
 static const struct of_device_id exynos_cpufreq_matches[] = {
 	{ .compatible = "samsung,exynos3250", .data = "cpufreq-dt" },
 	{ .compatible = "samsung,exynos4210", .data = "cpufreq-dt" },
+	{ .compatible = "samsung,exynos4212", .data = "cpufreq-dt" },
+	{ .compatible = "samsung,exynos4412", .data = "cpufreq-dt" },
 	{ .compatible = "samsung,exynos5250", .data = "cpufreq-dt" },
 	{ /* sentinel */ }
 };
-- 
1.9.1





From robherring2 at gmail.com  Mon Aug  3 07:00:46 2015
From: robherring2 at gmail.com (Rob Herring)
Date: Mon, 3 Aug 2015 09:00:46 -0500
Subject: [PATCH v2 04/10] Doc: usb: ci-hdrc-usb2: add ahb-burst-config for
 binding doc
In-Reply-To: <1438577238-10153-5-git-send-email-peter.chen@freescale.com>
References: <1438577238-10153-1-git-send-email-peter.chen@freescale.com>
 <1438577238-10153-5-git-send-email-peter.chen@freescale.com>
Message-ID: <CAL_Jsq+GNQq+SQCeMhy=W-XTPJn1ROAYHpm2+W9wwUa9+t-XwA@mail.gmail.com>

On Sun, Aug 2, 2015 at 11:47 PM, Peter Chen <peter.chen at freescale.com> wrote:
> It is used to change ahb burst configuration for platforms, it is
> vendor specific.
>
> Signed-off-by: Peter Chen <peter.chen at freescale.com>
> ---
>  Documentation/devicetree/bindings/usb/ci-hdrc-usb2.txt | 4 ++++
>  1 file changed, 4 insertions(+)
>
> diff --git a/Documentation/devicetree/bindings/usb/ci-hdrc-usb2.txt b/Documentation/devicetree/bindings/usb/ci-hdrc-usb2.txt
> index 4159c8c..3c377a3 100644
> --- a/Documentation/devicetree/bindings/usb/ci-hdrc-usb2.txt
> +++ b/Documentation/devicetree/bindings/usb/ci-hdrc-usb2.txt
> @@ -32,6 +32,8 @@ Optional properties:
>  - external-vbus-divider: (FSL only) enables off-chip resistor divider for Vbus
>  - itc-setting: interrupt threshold control register control, the setting
>    should be aligned with ITC bits at register USBCMD.
> +- ahb-burst-config: it is vendor dependent, the required value should be
> +  aligned with AHBBRST at SBUSCFG, the range is from 0x0 to 0x7.

What do the values mean and what happens if the property is not
present? Please define that here.

Rob

>
>  Example:
>
> @@ -44,4 +46,6 @@ Example:
>                 phy-names = "usb-phy";
>                 vbus-supply = <&reg_usb0_vbus>;
>                 gadget-itc-setting = <0x4>; /* 4 micro-frames */
> +                /* Incremental burst of unspecified length */
> +               ahb-burst-config = <0x0>;
>         };
> --
> 1.9.1
>


From will.deacon at arm.com  Mon Aug  3 07:04:36 2015
From: will.deacon at arm.com (Will Deacon)
Date: Mon, 3 Aug 2015 15:04:36 +0100
Subject: [RFC 2/3] arm64: refactor save_stack_trace()
In-Reply-To: <20150803100140.31ad51dd@gandalf.local.home>
References: <20150716121658.7982fdf5@gandalf.local.home>
 <20150717124054.GE26091@leverpostej>
 <20150717090009.720f6bd0@gandalf.local.home>
 <77EA0F10-D5F6-48BD-8652-3B979A978659@gmail.com>
 <20150717104144.6588b2f7@gandalf.local.home>
 <0886A996-40E1-49E9-823C-85E55A858716@gmail.com>
 <1357EA74-B972-4B99-ADB0-BC7E8F06DDB5@gmail.com>
 <20150720162004.GL9908@arm.com> <20150803090951.GA10501@arm.com>
 <20150803100140.31ad51dd@gandalf.local.home>
Message-ID: <20150803140436.GG10501@arm.com>

On Mon, Aug 03, 2015 at 03:01:40PM +0100, Steven Rostedt wrote:
> On Mon, 3 Aug 2015 10:09:51 +0100
> Will Deacon <will.deacon at arm.com> wrote:
> 
>  
> > > The arm64 bits look fine to me:
> > > 
> > >   Acked-by: Will Deacon <will.deacon at arm.com>
> > 
> > What happened to this? Is it queued someplace, or are we waiting for a
> > new version?
> 
> I went on vacation :-)  I'm back and trying to catch up. I'll be
> pulling in a bunch of things today. Hopefully I can get to this.

Cheers, Steve. Just wanted to make sure it didn't got lost (I'd briefly
forgotten about it myself!).

I hope you had a good holiday.

Will


From robherring2 at gmail.com  Mon Aug  3 07:04:27 2015
From: robherring2 at gmail.com (Rob Herring)
Date: Mon, 3 Aug 2015 09:04:27 -0500
Subject: [PATCH v2 06/10] usb: chipidea: add ahb burst configuration
 interface
In-Reply-To: <1438577238-10153-7-git-send-email-peter.chen@freescale.com>
References: <1438577238-10153-1-git-send-email-peter.chen@freescale.com>
 <1438577238-10153-7-git-send-email-peter.chen@freescale.com>
Message-ID: <CAL_JsqJn16OvfL_Ggf1wSi2XkJkjDMrmuRit3q8eVY5bNp8oYw@mail.gmail.com>

On Sun, Aug 2, 2015 at 11:47 PM, Peter Chen <peter.chen at freescale.com> wrote:
> The users can change it through dts or platform data if they
> want to change the default value.
>
> Signed-off-by: Peter Chen <peter.chen at freescale.com>
> ---
>  drivers/usb/chipidea/bits.h  |  3 +++
>  drivers/usb/chipidea/core.c  | 14 ++++++++++++++
>  include/linux/usb/chipidea.h |  2 ++
>  3 files changed, 19 insertions(+)
>
> diff --git a/drivers/usb/chipidea/bits.h b/drivers/usb/chipidea/bits.h
> index 831a8f6..462ad02 100644
> --- a/drivers/usb/chipidea/bits.h
> +++ b/drivers/usb/chipidea/bits.h
> @@ -25,6 +25,9 @@
>  #define VERSION                      (0xF << 25)
>  #define CIVERSION            (0x7 << 29)
>
> +/* SBUSCFG */
> +#define AHBBRST_MASK           0x7
> +
>  /* HCCPARAMS */
>  #define HCCPARAMS_LEN         BIT(17)
>
> diff --git a/drivers/usb/chipidea/core.c b/drivers/usb/chipidea/core.c
> index 38bd036..f60cbf6 100644
> --- a/drivers/usb/chipidea/core.c
> +++ b/drivers/usb/chipidea/core.c
> @@ -439,6 +439,9 @@ void ci_platform_configure(struct ci_hdrc *ci)
>
>         hw_write(ci, OP_USBCMD, 0xff0000, ci->platdata->itc_setting << 16);
>
> +       if (ci->platdata->flags & CI_HDRC_OVERRIDE_AHB_BURST)
> +               hw_write_id_reg(ci, ID_SBUSCFG, AHBBRST_MASK,
> +                       ci->platdata->ahb_burst_config);
>  }
>
>  /**
> @@ -647,6 +650,17 @@ static int ci_get_platdata(struct device *dev,
>                 }
>         }
>
> +       if (of_find_property(dev->of_node, "ahb-burst-config", NULL)) {
> +               ret = of_property_read_u32(dev->of_node, "ahb-burst-config",
> +                       &platdata->ahb_burst_config);
> +               if (ret) {
> +                       dev_err(dev,
> +                               "failed to get ahb-burst-config\n");
> +                       return ret;
> +               }
> +               platdata->flags |= CI_HDRC_OVERRIDE_AHB_BURST;
> +       }
> +

This can be simplified to:

ret = of_property_read_u32(dev->of_node, "ahb-burst-config",
&platdata->ahb_burst_config);
if (!ret)
  platdata->flags |= CI_HDRC_OVERRIDE_AHB_BURST;

The error condition can't really happen.

Rob


From henryc.chen at mediatek.com  Mon Aug  3 07:15:51 2015
From: henryc.chen at mediatek.com (Henry Chen)
Date: Mon, 3 Aug 2015 22:15:51 +0800
Subject: [PATCH] regulator: mt6311: Modify the maximum voltage of buck.
Message-ID: <1438611351-4245-1-git-send-email-henryc.chen@mediatek.com>

The maximum voltage of buck should be 1.39375V.
1.39375V = 0.6V + 0.00625V * 127, 127 is the max_sel of linear range.

Reported-by: Axel Lin <axel.lin at ingics.com>
signed-off-by: Henry Chen <henryc.chen at mediatek.com>
---
 drivers/regulator/mt6311-regulator.c | 2 +-
 1 file changed, 1 insertion(+), 1 deletion(-)

diff --git a/drivers/regulator/mt6311-regulator.c b/drivers/regulator/mt6311-regulator.c
index 096e620..b140da0 100644
--- a/drivers/regulator/mt6311-regulator.c
+++ b/drivers/regulator/mt6311-regulator.c
@@ -34,7 +34,7 @@ static const struct regmap_config mt6311_regmap_config = {
 
 /* Default limits measured in millivolts and milliamps */
 #define MT6311_MIN_UV		600000
-#define MT6311_MAX_UV		1400000
+#define MT6311_MAX_UV		1393750
 #define MT6311_STEP_UV		6250
 
 static const struct regulator_linear_range buck_volt_range[] = {
-- 
1.8.1.1.dirty



From rostedt at goodmis.org  Mon Aug  3 07:01:40 2015
From: rostedt at goodmis.org (Steven Rostedt)
Date: Mon, 3 Aug 2015 10:01:40 -0400
Subject: [RFC 2/3] arm64: refactor save_stack_trace()
In-Reply-To: <20150803090951.GA10501@arm.com>
References: <12F47692-3010-4886-B87D-3D7820609177@gmail.com>
 <20150716113115.45a17f17@gandalf.local.home>
 <20150716121658.7982fdf5@gandalf.local.home>
 <20150717124054.GE26091@leverpostej>
 <20150717090009.720f6bd0@gandalf.local.home>
 <77EA0F10-D5F6-48BD-8652-3B979A978659@gmail.com>
 <20150717104144.6588b2f7@gandalf.local.home>
 <0886A996-40E1-49E9-823C-85E55A858716@gmail.com>
 <1357EA74-B972-4B99-ADB0-BC7E8F06DDB5@gmail.com>
 <20150720162004.GL9908@arm.com> <20150803090951.GA10501@arm.com>
Message-ID: <20150803100140.31ad51dd@gandalf.local.home>

On Mon, 3 Aug 2015 10:09:51 +0100
Will Deacon <will.deacon at arm.com> wrote:

 
> > The arm64 bits look fine to me:
> > 
> >   Acked-by: Will Deacon <will.deacon at arm.com>
> 
> What happened to this? Is it queued someplace, or are we waiting for a
> new version?

I went on vacation :-)  I'm back and trying to catch up. I'll be
pulling in a bunch of things today. Hopefully I can get to this.

-- Steve


From jroedel at suse.de  Mon Aug  3 07:26:14 2015
From: jroedel at suse.de (Joerg Roedel)
Date: Mon, 3 Aug 2015 16:26:14 +0200
Subject: [PATCH v3 04/24] intel_iommu: fix leaked ioremap mapping
In-Reply-To: <20150730165401.33962.81348.stgit@dwillia2-desk3.amr.corp.intel.com>
References: <20150730165155.33962.64121.stgit@dwillia2-desk3.amr.corp.intel.com>
 <20150730165401.33962.81348.stgit@dwillia2-desk3.amr.corp.intel.com>
Message-ID: <20150803142537.GY27614@suse.de>

On Thu, Jul 30, 2015 at 12:54:01PM -0400, Dan Williams wrote:
> iommu_load_old_irte() appears to leak the old_irte mapping after use.
> 
> Cc: Joerg Roedel <jroedel at suse.de>
> Signed-off-by: Dan Williams <dan.j.williams at intel.com>
> ---
>  drivers/iommu/intel_irq_remapping.c |    2 ++
>  1 file changed, 2 insertions(+)

Applied, thanks.



From joro at 8bytes.org  Mon Aug  3 07:27:16 2015
From: joro at 8bytes.org (Joerg Roedel)
Date: Mon, 3 Aug 2015 16:27:16 +0200
Subject: [PATCH v2 17/25] intel-iommu: switch from ioremap_cache to
 memremap
In-Reply-To: <20150725023933.8664.85856.stgit@dwillia2-desk3.amr.corp.intel.com>
References: <20150725023649.8664.59145.stgit@dwillia2-desk3.amr.corp.intel.com>
 <20150725023933.8664.85856.stgit@dwillia2-desk3.amr.corp.intel.com>
Message-ID: <20150803142716.GC20968@8bytes.org>

On Fri, Jul 24, 2015 at 10:39:33PM -0400, Dan Williams wrote:
> In preparation for deprecating ioremap_cache() convert its usage in
> intel-iommu to memremap.  This also eliminates the mishandling of the
> __iomem annotation in the implementation.
> 
> Cc: David Woodhouse <dwmw2 at infradead.org>
> Cc: Joerg Roedel <joro at 8bytes.org>
> Signed-off-by: Dan Williams <dan.j.williams at intel.com>
> ---
>  drivers/iommu/intel-iommu.c         |   10 ++++++----
>  drivers/iommu/intel_irq_remapping.c |    4 ++--
>  2 files changed, 8 insertions(+), 6 deletions(-)

Acked-by: Joerg Roedel <jroedel at suse.de>



From pawel.moll at arm.com  Mon Aug  3 07:01:20 2015
From: pawel.moll at arm.com (Pawel Moll)
Date: Mon, 03 Aug 2015 15:01:20 +0100
Subject: [PATCH 1/3] clk: versatile: Switch to assigned clock parents
In-Reply-To: <1438386285-5070-2-git-send-email-sboyd@codeaurora.org>
References: <55BBB2FC.9030102@codeaurora.org>
 <1438386285-5070-1-git-send-email-sboyd@codeaurora.org>
 <1438386285-5070-2-git-send-email-sboyd@codeaurora.org>
Message-ID: <1438610480.2142.14.camel@arm.com>

On Sat, 2015-08-01 at 00:44 +0100, Stephen Boyd wrote:
> @@ -179,6 +124,15 @@ static void __init clk_sp810_of_setup(struct device_node *node)
>  		sp810->timerclken[i].channel = i;
>  		sp810->timerclken[i].hw.init = &init;
>  
> +		/*
> +		 * If DT isn't setting the parent, force it to be
> +		 * the 1 MHz clock without going through the framework.
> +		 * We do this before clk_register() so that it can determine
> +		 * the parent and setup the tree properly.
> +		 */
> +		if (deprecated)
> +			init.ops->set_parent(&sp810->timerclken[i].hw, 1);
> +
>  		sp810->timerclken[i].clk = clk_register(NULL,
>  				&sp810->timerclken[i].hw);
>  		WARN_ON(IS_ERR(sp810->timerclken[i].clk));

So that's one thing I've got a (small) problem here...

The above change assumes that SP810 always have 32kHz clock on input 0
and 1MHz clock on input 1. Yes, this is how it made on VExpress, but it
doesn't have to be the case. The magic picking up the faster clock was
added to handle all possible cases.

The bottom line is: if all we care is VExpress than it works, but it's
still a hack. Personally I don't like it, however I won't nak the patch
because of this.

Pawel



From tglx at linutronix.de  Mon Aug  3 07:36:29 2015
From: tglx at linutronix.de (Thomas Gleixner)
Date: Mon, 3 Aug 2015 16:36:29 +0200 (CEST)
Subject: [PATCH 1/3] clocksource: atmel-st: Remove irq handler when clock
 event is unused
In-Reply-To: <20150803153004.4a74d99a@bbrezillon>
References: <1437161608-26782-1-git-send-email-alexandre.belloni@free-electrons.com>
 <1437161608-26782-2-git-send-email-alexandre.belloni@free-electrons.com>
 <alpine.DEB.2.11.1507180942360.18576@nanos>
 <20150718222308.GA30489@piout.net>
 <alpine.DEB.2.11.1507201103550.18576@nanos> <20150720193726.GJ15539@piout.net>
 <alpine.DEB.2.11.1507202245310.18576@nanos>
 <alpine.DEB.2.11.1508021100390.3825@nanos>
 <20150802094028.GN12596@twins.programming.kicks-ass.net>
 <20150803153004.4a74d99a@bbrezillon>
Message-ID: <alpine.DEB.2.11.1508031619230.3825@nanos>

On Mon, 3 Aug 2015, Boris Brezillon wrote:
> On Sun, 2 Aug 2015 11:40:28 +0200
> Peter Zijlstra <peterz at infradead.org> wrote:
> 
> > On Sun, Aug 02, 2015 at 11:10:21AM +0200, Thomas Gleixner wrote:
> > > I think Boris Brezillon had implemented it at some point, but it was
> > > shot down for reasons I can't remember. 
> > 
> > You weren't around at the time.. DT people didn't like it, said they
> > didn't like having to make up fake hardware in their DT crap.
> 
> I don't know who was right, but the fact is they won't be inclined to
> take such an approach unless the virtual demuxer is not exposed in the
> DT, which is almost impossible since irq users are identifying their
> irq lines with a phandle to the interrupt controller and an interrupt
> id (usually extracted from the datasheet).

I really have no idea why DT folks think that virtual devices are not
suitable for DT entries. Marks working assumption from the old thread:

 > This sounds like a DT-workaround for a Linux implementation problem,
 > and I don't think this the right way to solve your problem.

is simply wrong. This has nothing to do with a Linux implementation
problem. It's a sensible workaround for braindamaged hardware at the
proper abstraction level.

> Anyway, below is a solution providing a way to disable specific
> handlers without reworking the way we are modeling shared interrupts.
> Thomas, I know you were not in favor of the proposed approach, but,
> AFAICT, it does not add any conditional path to the interrupt handling
> path (which, IIRC, was one of your requirements), and is simple enough
> to be used by people really needing it.
> 
> There's probably other drawback I haven't noticed, so please don't
> hesitate to share your thoughts.

Yes, aside of the bloat, it needs special handling in free_irq() as
well.

Thanks,

	tglx




From will.deacon at arm.com  Mon Aug  3 07:37:03 2015
From: will.deacon at arm.com (Will Deacon)
Date: Mon, 3 Aug 2015 15:37:03 +0100
Subject: [PATCHv5 0/5] arm/arm64: Unify PSCI client support
In-Reply-To: <1438353980-7611-1-git-send-email-mark.rutland@arm.com>
References: <1438353980-7611-1-git-send-email-mark.rutland@arm.com>
Message-ID: <20150803143703.GH10501@arm.com>

Hi all,

On Fri, Jul 31, 2015 at 03:46:15PM +0100, Mark Rutland wrote:
> This series unifies the 32-bit and 64-bit PSCI client code, moving the bulk of
> the FW invocation and probing out to a common location in drivers/firmware. The
> bulk of the PSCI 0.2 cleanups have hit mainline now, so this is just the
> unification portion.
> 
> This results in a reasonable saving in terms of lines of code, and will allow
> for PSCI 1.0 support to be unified form the beginning, avoiding further
> duplication.
> 
> Since v4 [1]:
> * Apply Rob Herring's ack
> * Rebase to v4.2-rc2 to handle a trivial conflict
> * Reorder the series to keep arch/arm patches together
> Since v3 [2]:
> * Drop the PSCI 0.2 patches as they're in mainline
> * s/__pa/virt_to_idmap/ from Grygorii Strashko
> * Use macros for Calxeda CPU_SUSPEND parameters
> 
> Russell, are you happy with the arch/arm patches? If so, are you happy for them
> to go via another tree, or would you prefer that I set up a stable branch for
> merging?
> 
> I was under the impression that you had already taken Grygorii's patch but I
> couldn't spot it in any branches. I can drop that if you already have it.

I've been looking at merging this, but it's a tad fiddly touching all of
arm, arm64 and drivers. One way to do it would be:

  (1) I create a branch containing patches 1,2 and 5 based on -rc2 and
      merge that into the arm64/for-next/core branch. There's a minor
      conflict, but it's easy to resolve.

  (2) I create another branch, which is just the branch merged in (1) +
      patches 3 and 4 on top. I send a pull request for that to rmk.

  (3) Torvalds will get the minor conflict resolved in (1) when he merges
      the arm and arm64 trees.

If we're not comfortable with (3), then the whole lot could go via
arm-soc instead (including the conflict resolution).

Russell, Olof, any preferences?

Will


From jingoohan1 at gmail.com  Mon Aug  3 07:41:20 2015
From: jingoohan1 at gmail.com (Jingoo Han)
Date: Mon, 3 Aug 2015 23:41:20 +0900
Subject: [PATCH v6] PCI: Store PCIe bus address in struct of_pci_range
In-Reply-To: <EE11001F9E5DDD47B7634E2F8A612F2E01D70641@lhreml503-mbs>
References: <1438010223-124422-1-git-send-email-gabriele.paoloni@huawei.com>
 <20150729172053.GE31170@google.com>
 <EE11001F9E5DDD47B7634E2F8A612F2E01D6F350@lhreml503-mbs>
 <CAL_JsqKs11-sXQTdBD+ZjbVYFWUHBARTW9q5MF1hCXUhZ+nWLQ@mail.gmail.com>
 <EE11001F9E5DDD47B7634E2F8A612F2E01D6F94A@lhreml503-mbs>
 <20150730161447.GG9640@google.com>
 <EE11001F9E5DDD47B7634E2F8A612F2E01D6FB3B@lhreml503-mbs>
 <20150730171445.GI9640@google.com>
 <EE11001F9E5DDD47B7634E2F8A612F2E01D6FC15@lhreml503-mbs>
 <CAL_Jsq+aQVakaZf4xo7sxnVyTmPR+HJ-9ByyS6OYJ0PHDYOwmg@mail.gmail.com>
 <EE11001F9E5DDD47B7634E2F8A612F2E01D70589@lhreml503-mbs>
 <55BB8CC6.1080203@ti.com>
 <EE11001F9E5DDD47B7634E2F8A612F2E01D70641@lhreml503-mbs>
Message-ID: <D6845CEF-67C3-4777-A219-D224C84BACE4@gmail.com>

On 2015. 8. 1., at AM 12:09, Gabriele Paoloni <gabriele.paoloni at huawei.com> wrote:
> 
>> -----Original Message-----
>> From: Kishon Vijay Abraham I [mailto:kishon at ti.com]
>> Sent: Friday, July 31, 2015 3:57 PM
>> To: Gabriele Paoloni; Rob Herring
>> Cc: Bjorn Helgaas; arnd at arndb.de; lorenzo.pieralisi at arm.com; Wangzhou
>> (B); robh+dt at kernel.org; james.morse at arm.com; Liviu.Dudau at arm.com;
>> linux-pci at vger.kernel.org; linux-arm-kernel at lists.infradead.org;
>> devicetree at vger.kernel.org; Yuanzhichang; Zhudacai; zhangjukuo;
>> qiuzhenfa; Liguozhu (Kenneth); Jingoo Han; Pratyush Anand; Arnd
>> Bergmann; Arnd Bergmann
>> Subject: Re: [PATCH v6] PCI: Store PCIe bus address in struct
>> of_pci_range
>> 
>> +Arnd
>> 
>> Hi,
>> 
>>> On Friday 31 July 2015 07:55 PM, Gabriele Paoloni wrote:
>>> [+cc Kishon]
>>> 
>>>> -----Original Message-----
>>>> From: linux-pci-owner at vger.kernel.org [mailto:linux-pci-
>>>> owner at vger.kernel.org] On Behalf Of Rob Herring
>>>> Sent: Thursday, July 30, 2015 9:42 PM
>>>> To: Gabriele Paoloni
>>>> Cc: Bjorn Helgaas; arnd at arndb.de; lorenzo.pieralisi at arm.com;
>> Wangzhou
>>>> (B); robh+dt at kernel.org; james.morse at arm.com; Liviu.Dudau at arm.com;
>>>> linux-pci at vger.kernel.org; linux-arm-kernel at lists.infradead.org;
>>>> devicetree at vger.kernel.org; Yuanzhichang; Zhudacai; zhangjukuo;
>>>> qiuzhenfa; Liguozhu (Kenneth); Jingoo Han; Pratyush Anand
>>>> Subject: Re: [PATCH v6] PCI: Store PCIe bus address in struct
>>>> of_pci_range
>>>> 
>>>> On Thu, Jul 30, 2015 at 12:34 PM, Gabriele Paoloni
>>>> <gabriele.paoloni at huawei.com> wrote:
>>>>>> -----Original Message-----
>>>>>> From: Bjorn Helgaas [mailto:bhelgaas at google.com]
>>>>>> Sent: 30 July 2015 18:15
>>>>>> On Thu, Jul 30, 2015 at 04:50:55PM +0000, Gabriele Paoloni wrote:
>>>>>>>> -----Original Message-----
>>>>>>>> From: linux-pci-owner at vger.kernel.org [mailto:linux-pci-
>>>>>>>> owner at vger.kernel.org] On Behalf Of Bjorn Helgaas
>>>>>>>> Sent: Thursday, July 30, 2015 5:15 PM
>>>>>>>> On Thu, Jul 30, 2015 at 01:52:13PM +0000, Gabriele Paoloni wrote:
>>>> 
>>>> [...]
>>>> 
>>>>>>>>> I don?t think we should rely on [CPU] addresses...what if the
>>>>>>>> intermediate
>>>>>>>>> translation layer changes the lower significant bits of the
>>>> "bus
>>>>>>>> address"
>>>>>>>>> to translate into a cpu address?
>>>>>>>> 
>>>>>>>> Is it really a possiblity that the lower bits could be changed?
>>>>>>> 
>>>>>>> I've checked all the current deignware users DTs except "pci-
>>>>>> layerscape"
>>>>>>> that I could not find:
>>>>>>> spear1310.dtsi
>>>>>>> spear1340.dtsi
>>>>>>> dra7.dtsi
>>>>>>> imx6qdl.dtsi
>>>>>>> imx6sx.dtsi
>>>>>>> keystone.dtsi
>>>>>>> exynos5440.dtsi
>>>>>>> 
>>>>>>> None of them modifies the lower bits. To be more precise the only
>>>> guy
>>>>>>> that provides another translation layer is "dra7.dtsi":
>>>>>>> axi0
>>>>>>> http://lxr.free-
>>>> electrons.com/source/arch/arm/boot/dts/dra7.dtsi#L207
>>>>>>> 
>>>>>>> axi1
>>>>>>> http://lxr.free-
>>>> electrons.com/source/arch/arm/boot/dts/dra7.dtsi#L241
>>>>>>> 
>>>>>>> For this case masking the top 4bits (bits28 to 31) should make
>> the
>>>> job.
>>>> 
>>>> IMO, we should just fix this case. After further study, I don't
>> think
>>>> this is a DW issue, but rather an SOC integration issue.
>>>> 
>>>> I believe you can just fixup the address in the pp->ops->host_init
>> hook.

Yep, it is SOC specific code for dra7.
This is NOT a DW issue.

>>> 
>>> Yes I guess that I could just assign pp->(*)_mod_base to the CPU
>> address
>>> in DW and mask it out in dra7xx_pcie_host_init()...
>>> 
>>> Kishon, would you be ok with that?
>> 
>> Initially I was using *base-mask* property from dt. Me and Arnd (cc'ed)
>> had
>> this discussion [1] before we decided the current approach. It'll be
>> good to
>> check with Arnd too.
>> 
>> [1] ->  http://lists.infradead.org/pipermail/linux-arm-kernel/2014-
>> May/253528.html
> 
> 
> In this patch you use the mask into designware....instead the approach 
> proposed by Rob means to have the mask declared in the dra7 driver and
> you modified the pp members in dra7xx_pcie_host_init by masking them...

I want to move that code to dra7 driver,
because that code is dra7-specific.

Best regards,
Jingoo Han

> BTW good to have Arnd opinion too..
>> 
>> Thanks
>> Kishon


From gg at slimlogic.co.uk  Mon Aug  3 08:13:31 2015
From: gg at slimlogic.co.uk (Graeme Gregory)
Date: Mon, 03 Aug 2015 16:13:31 +0100
Subject: [PATCH 1/2] drivers: PL061: add support for platform driver
 probing
In-Reply-To: <CACRpkdY6ZfB-gnnr49He+BYELy4fhiV0g5jkEHhyVsJOc_SBFw@mail.gmail.com>
References: <1438585198-8764-1-git-send-email-zhaoshenglong@huawei.com>
 <1438585198-8764-2-git-send-email-zhaoshenglong@huawei.com>
 <CACRpkdY6ZfB-gnnr49He+BYELy4fhiV0g5jkEHhyVsJOc_SBFw@mail.gmail.com>
Message-ID: <1438614811.2338188.346456017.5D258EC5@webmail.messagingengine.com>



On Mon, 3 Aug 2015, at 01:40 PM, Linus Walleij wrote:
> On Mon, Aug 3, 2015 at 8:59 AM, Shannon Zhao <zhaoshenglong at huawei.com>
> wrote:
> 
> > From: Shannon Zhao <shannon.zhao at linaro.org>
> >
> > Since PL061 currently only supports AMBA driver, to support using GPIO
> > PL061 by DT or ACPI, it needs to add support for platform driver.
> > A DT binding is provided with this patch, ACPI support is added in a
> > separate one.
> >
> > Signed-off-by: Shannon Zhao <zhaoshenglong at huawei.com>
> > Signed-off-by: Shannon Zhao <shannon.zhao at linaro.org>
> 
> I already stated in 0/2 what the problem is with this, and it's obviously
> adding
> a huge codechunk, very similar to the AMBA probe path.
> 
> We need to investigate if ACPI can just spawn AMBA/PrimeCell type devices
> instead.
> 
AMBA DT support is a hideous hack, we had kind of hoped to avoid doing
that in ACPI.

If you notice ARM already updated pl011 driver to support platform
device type probing this seems to be the way to go.

Graeme


From sergei.shtylyov at cogentembedded.com  Mon Aug  3 08:13:38 2015
From: sergei.shtylyov at cogentembedded.com (Sergei Shtylyov)
Date: Mon, 3 Aug 2015 18:13:38 +0300
Subject: [PATCH v3] ARM: shmobile: silk: initial device tree
In-Reply-To: <CAMuHMdWT=nzsFuM-vfe5GoAtDE-AtW4LAZoEnBGGVZm54-mAzg@mail.gmail.com>
References: <201404250239.39150.sergei.shtylyov@cogentembedded.com>
 <2360526.88foRQAOiM@wasted.cogentembedded.com>
 <CAMuHMdWT=nzsFuM-vfe5GoAtDE-AtW4LAZoEnBGGVZm54-mAzg@mail.gmail.com>
Message-ID: <55BF8522.1010906@cogentembedded.com>

Hello.

On 08/03/2015 04:00 PM, Geert Uytterhoeven wrote:

>> --- /dev/null
>> +++ renesas/arch/arm/boot/dts/r8a7794-silk.dts
>> @@ -0,0 +1,51 @@

>> +/ {
>> +       model = "SILK";
>> +       compatible = "renesas,silk", "renesas,r8a7794";

> WARNING: DT compatible string "renesas,silk" appears un-documented --
> check ./Documentation/devicetree/bindings/

> Do you plan to update Documentation/devicetree/bindings/arm/shmobile.txt?

    No, I had no idea I should record the board names somewhere too...

> Thanks!

> Gr{oetje,eeting}s,

>                          Geert

MBR, Sergei



From maitysanchayan at gmail.com  Mon Aug  3 08:10:28 2015
From: maitysanchayan at gmail.com (Sanchayan Maity)
Date: Mon,  3 Aug 2015 20:40:28 +0530
Subject: [PATCH] Add continuous sampling with IIO buffers for Vybrid
Message-ID: <cover.1438610517.git.maitysanchayan@gmail.com>

Hello,

This patch adds support for continuous sampling provided by the
ADC block on Vybrid by leveraging the IIO triggered buffer and
IIO sysfs trigger infrastructure.

The patch has been tested on Colibri VF50 and VF61 on shawn's
tree for-next branch with the patches [1] and [2] applied.

The below script was used for testing.

#!/bin/sh
echo 0 > /sys/bus/iio/devices/iio:device0/scan_elements/in_voltage8_en
echo 0 > /sys/bus/iio/devices/iio:device0/scan_elements/in_voltage9_en
echo 1 > /sys/bus/iio/devices/iio:device0/scan_elements/in_temp_en
echo 1 > /sys/bus/iio/devices/iio:device0/scan_elements/in_timestamp_en
echo 0 > /sys/bus/iio/devices/iio_sysfs_trigger/add_trigger
/home/root/generic_buffer -n 4003b000.adc -t sysfstrig0 -l 512 -c 10
echo 0 > /sys/bus/iio/devices/iio:device0/scan_elements/in_timestamp_en
echo 0 > /sys/bus/iio/devices/iio:device0/scan_elements/in_temp_en
echo 0 > /sys/bus/iio/devices/iio:device0/scan_elements/in_voltage8_en
echo 0 > /sys/bus/iio/devices/iio:device0/scan_elements/in_voltage9_en

Feedback and comments are most welcome.

Had some additional queries.

On shawn's tree, using imx_v6_v7_defconfig and running the above
script on VF50 gives me the following trace:

[  199.976662] INFO: rcu_sched self-detected stall on CPU
[  199.982015]  0: (2600 ticks this GP) idle=181/140000000000002/0 softirq=14591/14591 fqs=0
[  199.990406]   (t=2600 jiffies g=11024 c=11023 q=20)
[  199.995430] rcu_sched kthread starved for 2600 jiffies! g11024 c11023 f0x0
[  200.002523] Task dump for CPU 0:
[  200.005830] generic_buffer  R running      0   414    413 0x00000002
[  200.012370] Backtrace:
[  200.014974] [<80013708>] (dump_backtrace) from [<800138fc>] (show_stack+0x18/0x1c)
[  200.022665]  r7:80ae0f40 r6:80b374e8 r5:0000019d r4:85fdd080
[  200.028578] [<800138e4>] (show_stack) from [<800557bc>] (sched_show_task+0x11c/0x22c)
[  200.036555] [<800556a0>] (sched_show_task) from [<80057efc>] (dump_cpu_task+0x34/0x44)
[  200.044596]  r6:80000193 r5:80ae0f40 r4:00000000
[  200.049432] [<80057ec8>] (dump_cpu_task) from [<800820f8>] (rcu_dump_cpu_stacks+0x8c/0xd0)
[  200.057821]  r5:80ae0f40 r4:00000000
[  200.061563] [<8008206c>] (rcu_dump_cpu_stacks) from [<80085b88>] (rcu_check_callbacks+0x4dc/0x854)
[  200.070655]  r9:80ae0f40 r8:0720b000 r7:80ad09cc r6:80ae0f40 r5:80acd600 r4:87cd8600
[  200.078701] [<800856ac>] (rcu_check_callbacks) from [<80088820>] (update_process_times+0x40/0x6c)
[  200.087699]  r10:87cd5fc0 r9:8009a180 r8:80aedb80 r7:0000002e r6:8764c12d r5:00000000
[  200.095800]  r4:85fdd080
[  200.098462] [<800887e0>] (update_process_times) from [<8009a17c>] (tick_sched_handle.isra.19+0x4c/0x50)
[  200.108049]  r5:85e85d40 r4:87cd5fc0
[  200.111822] [<8009a130>] (tick_sched_handle.isra.19) from [<8009a1e4>] (tick_sched_timer+0x64/0xb0)
[  200.121098] [<8009a180>] (tick_sched_timer) from [<80089220>] (__hrtimer_run_queues+0xc4/0x1cc)
[  200.129989]  r7:0000002e r6:87649b3a r5:87cd5d00 r4:87cd5c80
[  200.135915] [<8008915c>] (__hrtimer_run_queues) from [<80089950>] (hrtimer_interrupt+0xc8/0x21c)
[  200.144898]  r10:87cd5d38 r9:87cd5d58 r8:87cd5c80 r7:87cd5cc0 r6:ffffffff r5:7fffffff
[  200.153061]  r4:00000003
[  200.155752] [<80089888>] (hrtimer_interrupt) from [<8054dcd0>] (gt_clockevent_interrupt+0x48/0x74)
[  200.164905]  r10:85e85f80 r9:87806000 r8:00000010 r7:87817b40 r6:87808100 r5:87cdab40
[  200.173082]  r4:00000001
[  200.175758] [<8054dc88>] (gt_clockevent_interrupt) from [<8007cab0>] (handle_percpu_devid_irq+0x8c/0xac)
[  200.185442]  r5:80aedd20 r4:87cdab40
[  200.189215] [<8007ca24>] (handle_percpu_devid_irq) from [<800786e4>] (generic_handle_irq+0x30/0x44)
[  200.198460]  r9:87806000 r8:00000001 r7:85e85e30 r6:80ad0b30 r5:00000010 r4:00000010
[  200.206567] [<800786b4>] (generic_handle_irq) from [<80078a08>] (__handle_domain_irq+0x6c/0xe8)
[  200.215455]  r5:00000010 r4:80acb5fc
[  200.219219] [<8007899c>] (__handle_domain_irq) from [<80009560>] (gic_handle_irq+0x28/0x68)
[  200.227759]  r9:87806000 r8:00000001 r7:88002100 r6:80ad0ca8 r5:8800210c r4:85e85d40
[  200.235861] [<80009538>] (gic_handle_irq) from [<80014564>] (__irq_svc+0x44/0x5c)
[  200.243526] Exception stack(0x85e85d40 to 0x85e85d88)
[  200.248720] 5d40: 00000001 85fdd548 00000000 85fdd080 00000202 00000000 80ad0b30 80ad0080
[  200.257104] 5d60: 00000001 87806000 85e85f80 85e85dcc 80c9f5d0 85e85d88 8006b5a0 8002ff80
[  200.265468] 5d80: 60000113 ffffffff
[  200.269056]  r7:85e85d74 r6:ffffffff r5:60000113 r4:8002ff80
[  200.274995] [<8002fec8>] (__do_softirq) from [<800304c8>] (irq_exit+0xc4/0x138)
[  200.282486]  r10:85e85f80 r9:87806000 r8:00000001 r7:00000000 r6:80ad0b30 r5:00000000
[  200.290660]  r4:80acb5fc
[  200.293345] [<80030404>] (irq_exit) from [<80078a10>] (__handle_domain_irq+0x74/0xe8)
[  200.301367]  r5:00000000 r4:80acb5fc
[  200.305135] [<8007899c>] (__handle_domain_irq) from [<80009560>] (gic_handle_irq+0x28/0x68)
[  200.313680]  r9:85efc60c r8:85e4bc00 r7:88002100 r6:80ad0ca8 r5:8800210c r4:85e85e30
[  200.321777] [<80009538>] (gic_handle_irq) from [<80014564>] (__irq_svc+0x44/0x5c)
[  200.329442] Exception stack(0x85e85e30 to 0x85e85e78)
[  200.334628] 5e20:                                     00000001 85fdd548 00000000 85fdd080
[  200.343010] 5e40: 00000001 803ce7c8 85e4bc00 00000000 85e4bc00 85efc60c 85e85f80 85e85e84
[  200.351384] 5e60: 80c9f5d0 85e85e78 8006b5a0 803ce7e8 60000013 ffffffff
[  200.358131]  r7:85e85e64 r6:ffffffff r5:60000013 r4:803ce7e8
[  200.364087] [<803ce7c8>] (dev_attr_store) from [<801739a0>] (sysfs_kf_write+0x54/0x58)
[  200.372217] [<8017394c>] (sysfs_kf_write) from [<80172b60>] (kernfs_fop_write+0xc4/0x1a8)
[  200.380579]  r7:00000000 r6:00000000 r5:00000001 r4:85efc600
[  200.386518] [<80172a9c>] (kernfs_fop_write) from [<80104f10>] (__vfs_write+0x2c/0xe0)
[  200.394535]  r10:00000000 r9:85e84000 r8:8000fc84 r7:85e85f80 r6:76fa3000 r5:85e85f80
[  200.402696]  r4:85fb2500
[  200.405376] [<80104ee4>] (__vfs_write) from [<801057b4>] (vfs_write+0x98/0x16c)
[  200.412865]  r8:8000fc84 r7:85e85f80 r6:76fa3000 r5:00000001 r4:85fb2500
[  200.419878] [<8010571c>] (vfs_write) from [<80106028>] (SyS_write+0x4c/0xa8)
[  200.427072]  r8:8000fc84 r7:00000001 r6:76fa3000 r5:85fb2500 r4:85fb2500
[  200.434099] [<80105fdc>] (SyS_write) from [<8000faa0>] (ret_fast_syscall+0x0/0x54)
[  200.441848]  r7:00000004 r6:76fa3000 r5:00000001 r4:002be960

On shawn's tree, using our own defconfig it all works fine.

The RCU related configs in imx_v6_v7_defconfig are:
# RCU Subsystem
CONFIG_TREE_RCU=y
# CONFIG_RCU_EXPERT is not set
CONFIG_SRCU=y
# CONFIG_TASKS_RCU is not set
CONFIG_RCU_STALL_COMMON=y
# CONFIG_TREE_RCU_TRACE is not set
# CONFIG_RCU_NOCB_CPU is not set
# CONFIG_RCU_EXPEDITE_BOOT is not set
# RCU Debugging
CONFIG_PROVE_RCU=y
# CONFIG_PROVE_RCU_REPEATEDLY is not set
# CONFIG_SPARSE_RCU_POINTER is not set
# CONFIG_RCU_TORTURE_TEST is not set
CONFIG_RCU_CPU_STALL_TIMEOUT=21
CONFIG_RCU_CPU_STALL_INFO=y
# CONFIG_RCU_TRACE is not set
# CONFIG_RCU_EQS_DEBUG is not set

The RCU configs in our own defconfig are:
# RCU Subsystem
CONFIG_TINY_RCU=y
CONFIG_SRCU=y
# CONFIG_TASKS_RCU is not set
# CONFIG_RCU_STALL_COMMON is not set
# CONFIG_TREE_RCU_TRACE is not set
CONFIG_RCU_KTHREAD_PRIO=0
# RCU Debugging
# CONFIG_SPARSE_RCU_POINTER is not set
# CONFIG_RCU_TORTURE_TEST is not set
# CONFIG_RCU_TRACE is not set

With the above second set of configs I do not encounter any problems.

I do not have any knowledge on the RCU front, can someone also comment
with regards to that? Perhaps I am doing something wrong in the driver?
My guess would be those RCU STALL configs?

[1]. https://lkml.org/lkml/2015/5/27/350
[2]. https://lkml.org/lkml/2015/7/14/395

Thanks & Regards,
Sanchayan Maity.

Sanchayan Maity (1):
  iio: adc: vf610: Add IIO buffer support for Vybrid ADC

 drivers/iio/adc/Kconfig     |   4 ++
 drivers/iio/adc/vf610_adc.c | 122 +++++++++++++++++++++++++++++++++++++++++---
 2 files changed, 120 insertions(+), 6 deletions(-)

-- 
2.5.0



From maitysanchayan at gmail.com  Mon Aug  3 08:10:29 2015
From: maitysanchayan at gmail.com (Sanchayan Maity)
Date: Mon,  3 Aug 2015 20:40:29 +0530
Subject: [PATCH] iio: adc: vf610: Add IIO buffer support for Vybrid ADC
In-Reply-To: <cover.1438610517.git.maitysanchayan@gmail.com>
References: <cover.1438610517.git.maitysanchayan@gmail.com>
Message-ID: <1f11be7d7bc1c3fcebf7d0bcf274f1fcbef35999.1438610517.git.maitysanchayan@gmail.com>

This patch adds support for IIO buffer to the Vybrid ADC driver.
IIO triggered buffer infrastructure along with iio sysfs trigger
is used to leverage continuous sampling support provided by the
ADC block.

Signed-off-by: Sanchayan Maity <maitysanchayan at gmail.com>
---
 drivers/iio/adc/Kconfig     |   4 ++
 drivers/iio/adc/vf610_adc.c | 122 +++++++++++++++++++++++++++++++++++++++++---
 2 files changed, 120 insertions(+), 6 deletions(-)

diff --git a/drivers/iio/adc/Kconfig b/drivers/iio/adc/Kconfig
index 7c55658..4661241 100644
--- a/drivers/iio/adc/Kconfig
+++ b/drivers/iio/adc/Kconfig
@@ -337,6 +337,10 @@ config TWL6030_GPADC
 config VF610_ADC
 	tristate "Freescale vf610 ADC driver"
 	depends on OF
+	select IIO_BUFFER
+	select IIO_TRIGGER
+	select IIO_SYSFS_TRIGGER
+	select IIO_TRIGGERED_BUFFER
 	help
 	  Say yes here to support for Vybrid board analog-to-digital converter.
 	  Since the IP is used for i.MX6SLX, the driver also support i.MX6SLX.
diff --git a/drivers/iio/adc/vf610_adc.c b/drivers/iio/adc/vf610_adc.c
index 23b8fb9..af72b9a 100644
--- a/drivers/iio/adc/vf610_adc.c
+++ b/drivers/iio/adc/vf610_adc.c
@@ -34,8 +34,11 @@
 #include <linux/err.h>
 
 #include <linux/iio/iio.h>
+#include <linux/iio/buffer.h>
 #include <linux/iio/sysfs.h>
-#include <linux/iio/driver.h>
+#include <linux/iio/trigger.h>
+#include <linux/iio/trigger_consumer.h>
+#include <linux/iio/triggered_buffer.h>
 
 /* This will be the driver name the kernel reports */
 #define DRIVER_NAME "vf610-adc"
@@ -170,6 +173,7 @@ struct vf610_adc {
 	u32 sample_freq_avail[5];
 
 	struct completion completion;
+	u16 *buffer;
 };
 
 static const u32 vf610_hw_avgs[] = { 1, 4, 8, 16, 32 };
@@ -505,12 +509,22 @@ static const struct iio_chan_spec_ext_info vf610_ext_info[] = {
 	.info_mask_shared_by_type = BIT(IIO_CHAN_INFO_SCALE) |	\
 				BIT(IIO_CHAN_INFO_SAMP_FREQ),	\
 	.ext_info = vf610_ext_info,				\
+	.address = (_idx),				\
+	.scan_index = (_idx),			\
+	.scan_type.sign = 'u',			\
+	.scan_type.realbits = 12,		\
+	.scan_type.storagebits = 16,	\
 }
 
 #define VF610_ADC_TEMPERATURE_CHAN(_idx, _chan_type) {	\
 	.type = (_chan_type),	\
 	.channel = (_idx),		\
 	.info_mask_separate = BIT(IIO_CHAN_INFO_PROCESSED),	\
+	.address = (_idx),						\
+	.scan_index = (_idx),					\
+	.scan_type.sign = 'u',					\
+	.scan_type.realbits = 12,				\
+	.scan_type.storagebits = 16,			\
 }
 
 static const struct iio_chan_spec vf610_adc_iio_channels[] = {
@@ -531,6 +545,7 @@ static const struct iio_chan_spec vf610_adc_iio_channels[] = {
 	VF610_ADC_CHAN(14, IIO_VOLTAGE),
 	VF610_ADC_CHAN(15, IIO_VOLTAGE),
 	VF610_ADC_TEMPERATURE_CHAN(26, IIO_TEMP),
+	IIO_CHAN_SOFT_TIMESTAMP(32),
 	/* sentinel */
 };
 
@@ -559,13 +574,21 @@ static int vf610_adc_read_data(struct vf610_adc *info)
 
 static irqreturn_t vf610_adc_isr(int irq, void *dev_id)
 {
-	struct vf610_adc *info = (struct vf610_adc *)dev_id;
+	struct iio_dev *indio_dev = (struct iio_dev *)dev_id;
+	struct vf610_adc *info = iio_priv(indio_dev);
 	int coco;
 
 	coco = readl(info->regs + VF610_REG_ADC_HS);
 	if (coco & VF610_ADC_HS_COCO0) {
 		info->value = vf610_adc_read_data(info);
-		complete(&info->completion);
+		if (iio_buffer_enabled(indio_dev)) {
+			info->buffer[0] = info->value;
+			writel(0, info->regs + VF610_REG_ADC_HS);
+			iio_push_to_buffers_with_timestamp(indio_dev,
+					info->buffer, iio_get_time_ns());
+			iio_trigger_notify_done(indio_dev->trig);
+		} else
+			complete(&info->completion);
 	}
 
 	return IRQ_HANDLED;
@@ -612,6 +635,9 @@ static int vf610_read_raw(struct iio_dev *indio_dev,
 	switch (mask) {
 	case IIO_CHAN_INFO_RAW:
 	case IIO_CHAN_INFO_PROCESSED:
+		if (iio_buffer_enabled(indio_dev))
+			return -EBUSY;
+
 		mutex_lock(&indio_dev->mlock);
 		reinit_completion(&info->completion);
 
@@ -694,6 +720,81 @@ static int vf610_write_raw(struct iio_dev *indio_dev,
 	return -EINVAL;
 }
 
+static int vf610_adc_buffer_postenable(struct iio_dev *indio_dev)
+{
+	struct vf610_adc *info = iio_priv(indio_dev);
+	unsigned int channel;
+	int ret;
+	int val;
+
+	ret = iio_triggered_buffer_postenable(indio_dev);
+	if (ret)
+		return ret;
+
+	val = readl(info->regs + VF610_REG_ADC_GC);
+	val |= VF610_ADC_ADCON;
+	writel(val, info->regs + VF610_REG_ADC_GC);
+
+	channel = find_first_bit(indio_dev->active_scan_mask,
+						indio_dev->masklength);
+
+	val = VF610_ADC_ADCHC(channel);
+	val |= VF610_ADC_AIEN;
+
+	writel(val, info->regs + VF610_REG_ADC_HC0);
+
+	return 0;
+}
+
+static int vf610_adc_buffer_postdisable(struct iio_dev *indio_dev)
+{
+	struct vf610_adc *info = iio_priv(indio_dev);
+	unsigned int hc_cfg = 0;
+	int val;
+
+	val = readl(info->regs + VF610_REG_ADC_GC);
+	val &= ~VF610_ADC_ADCON;
+	writel(val, info->regs + VF610_REG_ADC_GC);
+
+	hc_cfg |= VF610_ADC_CONV_DISABLE;
+	hc_cfg &= ~VF610_ADC_AIEN;
+
+	writel(hc_cfg, info->regs + VF610_REG_ADC_HC0);
+
+	return 0;
+}
+
+static int vf610_adc_update_scan_mode(struct iio_dev *indio_dev,
+	const unsigned long *scan_mask)
+{
+	struct vf610_adc *info = iio_priv(indio_dev);
+
+	kfree(info->buffer);
+	info->buffer = kmalloc(indio_dev->scan_bytes, GFP_KERNEL);
+	if (!info->buffer)
+		return -ENOMEM;
+
+	return 0;
+}
+
+static const struct iio_buffer_setup_ops iio_triggered_buffer_setup_ops = {
+	.postenable = &vf610_adc_buffer_postenable,
+	.predisable = &iio_triggered_buffer_predisable,
+	.postdisable = &vf610_adc_buffer_postdisable,
+	.validate_scan_mask = &iio_validate_scan_mask_onehot,
+};
+
+static int vf610_adc_buffer_init(struct iio_dev *indio_dev)
+{
+	return iio_triggered_buffer_setup(indio_dev, &iio_pollfunc_store_time,
+		NULL, &iio_triggered_buffer_setup_ops);
+}
+
+static void vf610_adc_buffer_remove(struct iio_dev *indio_dev)
+{
+	iio_triggered_buffer_cleanup(indio_dev);
+}
+
 static int vf610_adc_reg_access(struct iio_dev *indio_dev,
 			unsigned reg, unsigned writeval,
 			unsigned *readval)
@@ -714,6 +815,7 @@ static const struct iio_info vf610_adc_iio_info = {
 	.read_raw = &vf610_read_raw,
 	.write_raw = &vf610_write_raw,
 	.debugfs_reg_access = &vf610_adc_reg_access,
+	.update_scan_mode = &vf610_adc_update_scan_mode,
 	.attrs = &vf610_attribute_group,
 };
 
@@ -753,7 +855,7 @@ static int vf610_adc_probe(struct platform_device *pdev)
 
 	ret = devm_request_irq(info->dev, irq,
 				vf610_adc_isr, 0,
-				dev_name(&pdev->dev), info);
+				dev_name(&pdev->dev), indio_dev);
 	if (ret < 0) {
 		dev_err(&pdev->dev, "failed requesting irq, irq = %d\n", irq);
 		return ret;
@@ -806,15 +908,22 @@ static int vf610_adc_probe(struct platform_device *pdev)
 	vf610_adc_cfg_init(info);
 	vf610_adc_hw_init(info);
 
+	ret = vf610_adc_buffer_init(indio_dev);
+	if (ret < 0) {
+		dev_err(&pdev->dev, "Couldn't initialise the buffer\n");
+		goto error_iio_device_register;
+	}
+
 	ret = iio_device_register(indio_dev);
 	if (ret) {
 		dev_err(&pdev->dev, "Couldn't register the device.\n");
-		goto error_iio_device_register;
+		goto error_adc_buffer_init;
 	}
 
 	return 0;
 
-
+error_adc_buffer_init:
+	vf610_adc_buffer_remove(indio_dev);
 error_iio_device_register:
 	clk_disable_unprepare(info->clk);
 error_adc_clk_enable:
@@ -829,6 +938,7 @@ static int vf610_adc_remove(struct platform_device *pdev)
 	struct vf610_adc *info = iio_priv(indio_dev);
 
 	iio_device_unregister(indio_dev);
+	vf610_adc_buffer_remove(indio_dev);
 	regulator_disable(info->vref);
 	clk_disable_unprepare(info->clk);
 
-- 
2.5.0



From geert at linux-m68k.org  Mon Aug  3 08:19:21 2015
From: geert at linux-m68k.org (Geert Uytterhoeven)
Date: Mon, 3 Aug 2015 17:19:21 +0200
Subject: [PATCH v3] ARM: shmobile: silk: initial device tree
In-Reply-To: <55BF8522.1010906@cogentembedded.com>
References: <201404250239.39150.sergei.shtylyov@cogentembedded.com>
 <2360526.88foRQAOiM@wasted.cogentembedded.com>
 <CAMuHMdWT=nzsFuM-vfe5GoAtDE-AtW4LAZoEnBGGVZm54-mAzg@mail.gmail.com>
 <55BF8522.1010906@cogentembedded.com>
Message-ID: <CAMuHMdVRKjO9iQfhQYJUb9rBKCX3TS+_Vq_SWr0YoY7ov2BCLg@mail.gmail.com>

Hi Sergei,

On Mon, Aug 3, 2015 at 5:13 PM, Sergei Shtylyov
<sergei.shtylyov at cogentembedded.com> wrote:
> On 08/03/2015 04:00 PM, Geert Uytterhoeven wrote:
>>> --- /dev/null
>>> +++ renesas/arch/arm/boot/dts/r8a7794-silk.dts
>>> @@ -0,0 +1,51 @@
>
>>> +/ {
>>> +       model = "SILK";
>>> +       compatible = "renesas,silk", "renesas,r8a7794";
>
>> WARNING: DT compatible string "renesas,silk" appears un-documented --
>> check ./Documentation/devicetree/bindings/
>
>> Do you plan to update Documentation/devicetree/bindings/arm/shmobile.txt?
>
>    No, I had no idea I should record the board names somewhere too...

All "compatible" values should be documented before being used in a
.dts(i) file.

Gr{oetje,eeting}s,

                        Geert

--
Geert Uytterhoeven -- There's lots of Linux beyond ia32 -- geert at linux-m68k.org

In personal conversations with technical people, I call myself a hacker. But
when I'm talking to journalists I just say "programmer" or something like that.
                                -- Linus Torvalds


From pmeerw at pmeerw.net  Mon Aug  3 08:24:48 2015
From: pmeerw at pmeerw.net (Peter Meerwald)
Date: Mon, 3 Aug 2015 17:24:48 +0200 (CEST)
Subject: [PATCH] iio: adc: vf610: Add IIO buffer support for Vybrid ADC
In-Reply-To: <1f11be7d7bc1c3fcebf7d0bcf274f1fcbef35999.1438610517.git.maitysanchayan@gmail.com>
References: <cover.1438610517.git.maitysanchayan@gmail.com>
 <1f11be7d7bc1c3fcebf7d0bcf274f1fcbef35999.1438610517.git.maitysanchayan@gmail.com>
Message-ID: <alpine.DEB.2.02.1508031716370.12576@pmeerw.net>

On Mon, 3 Aug 2015, Sanchayan Maity wrote:

> This patch adds support for IIO buffer to the Vybrid ADC driver.
> IIO triggered buffer infrastructure along with iio sysfs trigger
> is used to leverage continuous sampling support provided by the
> ADC block.

comments below
 
> Signed-off-by: Sanchayan Maity <maitysanchayan at gmail.com>
> ---
>  drivers/iio/adc/Kconfig     |   4 ++
>  drivers/iio/adc/vf610_adc.c | 122 +++++++++++++++++++++++++++++++++++++++++---
>  2 files changed, 120 insertions(+), 6 deletions(-)
> 
> diff --git a/drivers/iio/adc/Kconfig b/drivers/iio/adc/Kconfig
> index 7c55658..4661241 100644
> --- a/drivers/iio/adc/Kconfig
> +++ b/drivers/iio/adc/Kconfig
> @@ -337,6 +337,10 @@ config TWL6030_GPADC
>  config VF610_ADC
>  	tristate "Freescale vf610 ADC driver"
>  	depends on OF
> +	select IIO_BUFFER
> +	select IIO_TRIGGER
> +	select IIO_SYSFS_TRIGGER
> +	select IIO_TRIGGERED_BUFFER
>  	help
>  	  Say yes here to support for Vybrid board analog-to-digital converter.
>  	  Since the IP is used for i.MX6SLX, the driver also support i.MX6SLX.
> diff --git a/drivers/iio/adc/vf610_adc.c b/drivers/iio/adc/vf610_adc.c
> index 23b8fb9..af72b9a 100644
> --- a/drivers/iio/adc/vf610_adc.c
> +++ b/drivers/iio/adc/vf610_adc.c
> @@ -34,8 +34,11 @@
>  #include <linux/err.h>
>  
>  #include <linux/iio/iio.h>
> +#include <linux/iio/buffer.h>
>  #include <linux/iio/sysfs.h>
> -#include <linux/iio/driver.h>
> +#include <linux/iio/trigger.h>
> +#include <linux/iio/trigger_consumer.h>
> +#include <linux/iio/triggered_buffer.h>
>  
>  /* This will be the driver name the kernel reports */
>  #define DRIVER_NAME "vf610-adc"
> @@ -170,6 +173,7 @@ struct vf610_adc {
>  	u32 sample_freq_avail[5];
>  
>  	struct completion completion;
> +	u16 *buffer;
>  };
>  
>  static const u32 vf610_hw_avgs[] = { 1, 4, 8, 16, 32 };
> @@ -505,12 +509,22 @@ static const struct iio_chan_spec_ext_info vf610_ext_info[] = {
>  	.info_mask_shared_by_type = BIT(IIO_CHAN_INFO_SCALE) |	\
>  				BIT(IIO_CHAN_INFO_SAMP_FREQ),	\
>  	.ext_info = vf610_ext_info,				\
> +	.address = (_idx),				\

address is not used, no need to set it

> +	.scan_index = (_idx),			\

often this is written .scan_type = {.sign = 'u', ...}

> +	.scan_type.sign = 'u',			\
> +	.scan_type.realbits = 12,		\
> +	.scan_type.storagebits = 16,	\
>  }
>  
>  #define VF610_ADC_TEMPERATURE_CHAN(_idx, _chan_type) {	\
>  	.type = (_chan_type),	\
>  	.channel = (_idx),		\
>  	.info_mask_separate = BIT(IIO_CHAN_INFO_PROCESSED),	\
> +	.address = (_idx),						\
> +	.scan_index = (_idx),					\
> +	.scan_type.sign = 'u',					\
> +	.scan_type.realbits = 12,				\
> +	.scan_type.storagebits = 16,			\
>  }
>  
>  static const struct iio_chan_spec vf610_adc_iio_channels[] = {
> @@ -531,6 +545,7 @@ static const struct iio_chan_spec vf610_adc_iio_channels[] = {
>  	VF610_ADC_CHAN(14, IIO_VOLTAGE),
>  	VF610_ADC_CHAN(15, IIO_VOLTAGE),
>  	VF610_ADC_TEMPERATURE_CHAN(26, IIO_TEMP),
> +	IIO_CHAN_SOFT_TIMESTAMP(32),
>  	/* sentinel */
>  };
>  
> @@ -559,13 +574,21 @@ static int vf610_adc_read_data(struct vf610_adc *info)
>  
>  static irqreturn_t vf610_adc_isr(int irq, void *dev_id)
>  {
> -	struct vf610_adc *info = (struct vf610_adc *)dev_id;
> +	struct iio_dev *indio_dev = (struct iio_dev *)dev_id;
> +	struct vf610_adc *info = iio_priv(indio_dev);
>  	int coco;
>  
>  	coco = readl(info->regs + VF610_REG_ADC_HS);
>  	if (coco & VF610_ADC_HS_COCO0) {
>  		info->value = vf610_adc_read_data(info);
> -		complete(&info->completion);
> +		if (iio_buffer_enabled(indio_dev)) {
> +			info->buffer[0] = info->value;
> +			writel(0, info->regs + VF610_REG_ADC_HS);
> +			iio_push_to_buffers_with_timestamp(indio_dev,
> +					info->buffer, iio_get_time_ns());
> +			iio_trigger_notify_done(indio_dev->trig);
> +		} else
> +			complete(&info->completion);
>  	}
>  
>  	return IRQ_HANDLED;
> @@ -612,6 +635,9 @@ static int vf610_read_raw(struct iio_dev *indio_dev,
>  	switch (mask) {
>  	case IIO_CHAN_INFO_RAW:
>  	case IIO_CHAN_INFO_PROCESSED:
> +		if (iio_buffer_enabled(indio_dev))
> +			return -EBUSY;
> +
>  		mutex_lock(&indio_dev->mlock);
>  		reinit_completion(&info->completion);
>  
> @@ -694,6 +720,81 @@ static int vf610_write_raw(struct iio_dev *indio_dev,
>  	return -EINVAL;
>  }
>  
> +static int vf610_adc_buffer_postenable(struct iio_dev *indio_dev)
> +{
> +	struct vf610_adc *info = iio_priv(indio_dev);
> +	unsigned int channel;
> +	int ret;
> +	int val;
> +
> +	ret = iio_triggered_buffer_postenable(indio_dev);
> +	if (ret)
> +		return ret;
> +
> +	val = readl(info->regs + VF610_REG_ADC_GC);
> +	val |= VF610_ADC_ADCON;
> +	writel(val, info->regs + VF610_REG_ADC_GC);
> +
> +	channel = find_first_bit(indio_dev->active_scan_mask,
> +						indio_dev->masklength);
> +
> +	val = VF610_ADC_ADCHC(channel);
> +	val |= VF610_ADC_AIEN;
> +
> +	writel(val, info->regs + VF610_REG_ADC_HC0);
> +
> +	return 0;
> +}
> +
> +static int vf610_adc_buffer_postdisable(struct iio_dev *indio_dev)
> +{
> +	struct vf610_adc *info = iio_priv(indio_dev);
> +	unsigned int hc_cfg = 0;
> +	int val;
> +
> +	val = readl(info->regs + VF610_REG_ADC_GC);
> +	val &= ~VF610_ADC_ADCON;
> +	writel(val, info->regs + VF610_REG_ADC_GC);
> +
> +	hc_cfg |= VF610_ADC_CONV_DISABLE;
> +	hc_cfg &= ~VF610_ADC_AIEN;
> +
> +	writel(hc_cfg, info->regs + VF610_REG_ADC_HC0);
> +
> +	return 0;
> +}
> +
> +static int vf610_adc_update_scan_mode(struct iio_dev *indio_dev,
> +	const unsigned long *scan_mask)
> +{
> +	struct vf610_adc *info = iio_priv(indio_dev);
> +
> +	kfree(info->buffer);

only one channel can be read (onehot), why not use a fixed size buffer 
(one u16, perhaps as a local variable in _adc_isr()?

> +	info->buffer = kmalloc(indio_dev->scan_bytes, GFP_KERNEL);
> +	if (!info->buffer)
> +		return -ENOMEM;
> +
> +	return 0;
> +}
> +
> +static const struct iio_buffer_setup_ops iio_triggered_buffer_setup_ops = {
> +	.postenable = &vf610_adc_buffer_postenable,
> +	.predisable = &iio_triggered_buffer_predisable,
> +	.postdisable = &vf610_adc_buffer_postdisable,
> +	.validate_scan_mask = &iio_validate_scan_mask_onehot,
> +};
> +
> +static int vf610_adc_buffer_init(struct iio_dev *indio_dev)
> +{
> +	return iio_triggered_buffer_setup(indio_dev, &iio_pollfunc_store_time,
> +		NULL, &iio_triggered_buffer_setup_ops);
> +}
> +
> +static void vf610_adc_buffer_remove(struct iio_dev *indio_dev)
> +{
> +	iio_triggered_buffer_cleanup(indio_dev);
> +}
> +
>  static int vf610_adc_reg_access(struct iio_dev *indio_dev,
>  			unsigned reg, unsigned writeval,
>  			unsigned *readval)
> @@ -714,6 +815,7 @@ static const struct iio_info vf610_adc_iio_info = {
>  	.read_raw = &vf610_read_raw,
>  	.write_raw = &vf610_write_raw,
>  	.debugfs_reg_access = &vf610_adc_reg_access,
> +	.update_scan_mode = &vf610_adc_update_scan_mode,
>  	.attrs = &vf610_attribute_group,
>  };
>  
> @@ -753,7 +855,7 @@ static int vf610_adc_probe(struct platform_device *pdev)
>  
>  	ret = devm_request_irq(info->dev, irq,
>  				vf610_adc_isr, 0,
> -				dev_name(&pdev->dev), info);
> +				dev_name(&pdev->dev), indio_dev);
>  	if (ret < 0) {
>  		dev_err(&pdev->dev, "failed requesting irq, irq = %d\n", irq);
>  		return ret;
> @@ -806,15 +908,22 @@ static int vf610_adc_probe(struct platform_device *pdev)
>  	vf610_adc_cfg_init(info);
>  	vf610_adc_hw_init(info);
>  
> +	ret = vf610_adc_buffer_init(indio_dev);
> +	if (ret < 0) {
> +		dev_err(&pdev->dev, "Couldn't initialise the buffer\n");
> +		goto error_iio_device_register;
> +	}
> +
>  	ret = iio_device_register(indio_dev);
>  	if (ret) {
>  		dev_err(&pdev->dev, "Couldn't register the device.\n");
> -		goto error_iio_device_register;
> +		goto error_adc_buffer_init;
>  	}
>  
>  	return 0;
>  
> -
> +error_adc_buffer_init:
> +	vf610_adc_buffer_remove(indio_dev);
>  error_iio_device_register:
>  	clk_disable_unprepare(info->clk);
>  error_adc_clk_enable:
> @@ -829,6 +938,7 @@ static int vf610_adc_remove(struct platform_device *pdev)
>  	struct vf610_adc *info = iio_priv(indio_dev);
>  
>  	iio_device_unregister(indio_dev);
> +	vf610_adc_buffer_remove(indio_dev);
>  	regulator_disable(info->vref);
>  	clk_disable_unprepare(info->clk);
>  
> 

-- 

Peter Meerwald
+43-664-2444418 (mobile)


From maitysanchayan at gmail.com  Mon Aug  3 08:25:44 2015
From: maitysanchayan at gmail.com (maitysanchayan at gmail.com)
Date: Mon, 3 Aug 2015 20:55:44 +0530
Subject: [PATCH v2 3/4] touchscreen: colibri-vf50-ts: Add touchscreen
 support for Colibri VF50
In-Reply-To: <20150721172044.GC39076@dtor-ws>
References: <cover.1437058481.git.maitysanchayan@gmail.com>
 <26748bd9a7bde7c2304b6b971f1150bb575e4938.1437058481.git.maitysanchayan@gmail.com>
 <20150717234242.GJ39282@dtor-ws>
 <40d7c372e64c7f25b7df3e48930386de@agner.ch>
 <20150721172044.GC39076@dtor-ws>
Message-ID: <20150803152544.GA9716@Sanchayan-Arch.toradex.int>

Hello Dmitry,

On 15-07-21 10:20:44, Dmitry Torokhov wrote:
> Hi Stefan,
> 
> On Tue, Jul 21, 2015 at 04:43:36PM +0200, Stefan Agner wrote:
> > Hi Dmitry,
> > 
> > As the original author of the driver I have some remarks to your review
> > 
> > On 2015-07-18 01:42, Dmitry Torokhov wrote:
> > >> +		/*
> > >> +		 * If touch pressure is too low, stop measuring and reenable
> > >> +		 * touch detection
> > >> +		 */
> > >> +		if (val_p < min_pressure || val_p > 2000)
> > >> +			break;
> > 
> > This is where the modules touch pressure is used to stop the measurement
> > process and switch back to interrupt mode. See my remarks at the end.
> > 
> > >> +
> > >> +		/*
> > >> +		 * The pressure may not be enough for the first x and the
> > >> +		 * second y measurement, but, the pressure is ok when the
> > >> +		 * driver is doing the third and fourth measurement. To
> > >> +		 * take care of this, we drop the first measurement always.
> > >> +		 */
> > >> +		if (discard_val_on_start) {
> > >> +			discard_val_on_start = false;
> > >> +		} else {
> > >> +			/*
> > >> +			 * Report touch position and sleep for
> > >> +			 * next measurement
> > >> +			 */
> > >> +			input_report_abs(vf50_ts->ts_input,
> > >> +					ABS_X, VF_ADC_MAX - val_x);
> > >> +			input_report_abs(vf50_ts->ts_input,
> > >> +					ABS_Y, VF_ADC_MAX - val_y);
> > >> +			input_report_abs(vf50_ts->ts_input,
> > >> +					ABS_PRESSURE, val_p);
> > >> +			input_report_key(vf50_ts->ts_input, BTN_TOUCH, 1);
> > >> +			input_sync(vf50_ts->ts_input);
> > >> +		}
> > >> +
> > >> +		msleep(10);
> > >> +	}
> > >> +
> > >> +	/* Report no more touch, reenable touch detection */
> > >> +	input_report_abs(vf50_ts->ts_input, ABS_PRESSURE, 0);
> > >> +	input_report_key(vf50_ts->ts_input, BTN_TOUCH, 0);
> > >> +	input_sync(vf50_ts->ts_input);
> > >> +
> > >> +	vf50_ts_enable_touch_detection(vf50_ts);
> > >> +
> > >> +	/* Wait for the pull-up to be stable on high */
> > >> +	msleep(10);
> > >> +
> > >> +	/* Reenable IRQ to detect touch */
> > >> +	enable_irq(vf50_ts->pen_irq);
> > >> +
> > >> +	dev_dbg(dev, "Reenabled touch detection interrupt\n");
> > >> +}
> > >> +
> > >> +static irqreturn_t vf50_ts_touched(int irq, void *dev_id)
> > >> +{
> > >> +	struct vf50_touch_device *vf50_ts = (struct vf50_touch_device *)dev_id;
> > >> +	struct device *dev = &vf50_ts->pdev->dev;
> > >> +
> > >> +	dev_dbg(dev, "Touch detected, start worker thread\n");
> > >> +
> > >> +	disable_irq_nosync(irq);
> > >> +
> > >> +	/* Disable the touch detection plates */
> > >> +	gpiod_set_value(vf50_ts->gpio_ym, 0);
> > >> +
> > >> +	/* Let the platform mux to default state in order to mux as ADC */
> > >> +	pinctrl_pm_select_default_state(dev);
> > >> +
> > >> +	queue_work(vf50_ts->ts_workqueue, &vf50_ts->ts_work);
> > > 
> > > If you convert this to a threaded interrupt you won't need to
> > > disable/reenable interrupt or queue work. You should also be able to use
> > > gpiod_set_value_cansleep() extending the range of ways the controller
> > > could be connected to systems.
> > > 
> > 
> > I'm not sure if a threaded interrupt is the right thing here. While the
> > pen is on the touchscreen (which can be for several seconds)
> > measurements have to be made in a continuous loop. Is it ok for a
> > threaded interrupt to run that long?
> 
> Yes, why not? Threaded interrupt is simply a kernel thread that is woken
> when hard interrupt handler tells it to wake up. Very similar to
> interrupt + work queue, except that the kernel manages interactions
> properly for you. There are several drivers in kernel that do that, for
> example auo-pixcir-ts.c or tsc2007.c
> 
> > 
> > I'm also not sure if it is really safe to _not_ disable the pen down
> > GPIO interrupt. If we get a interrupt while measuring, we should ignore
> > that interrupt.
> 
> The interrupt management core (you'll have to annotate it as
> IRQF_ONESHOT) will make sure it stays masked properly until the threaded
> handler completes so you do not need to disable it explicitly.

After working some more on threaded irq implementation, if IRQ_ONESHOT
flag is used while requesting threaded irq, on entering the IRQ handler
the vf610_gpio_irq_mask is not called and vf610_gpio_irq_unmask is not
called on exiting the thread function, not something we expected.

In contrast, using explicit disable_irq_nosync and enable_irq in the IRQ
handler and thread respectively results in the respective mask and unmask
function being called.

The vf610_gpio_irq_*mask functions are in the gpio driver for Vybrid in
drivers/gpio/gpio-vf610.c.

Can you point me in the right direction?

Thanks & Regards,
Sanchayan.


From eric.auger at linaro.org  Mon Aug  3 08:31:22 2015
From: eric.auger at linaro.org (Eric Auger)
Date: Mon,  3 Aug 2015 17:31:22 +0200
Subject: [PATCH v3 0/7] KVM: arm/arm64: gsi routing support
Message-ID: <1438615889-10892-1-git-send-email-eric.auger@linaro.org>

With the advent of GICv3 ITS in-kernel emulation, KVM GSI routing
appears to be requested. More specifically MSI routing is needed.
irqchip routing does not sound to be really useful on arm but usage of
MSI routing also mandates to integrate irqchip routing. The initial
implementation of irqfd on arm must be upgraded with the integration
of kvm irqchip.c code and the implementation of its standard hooks
in the architecture specific part.

In case KVM_SET_GSI_ROUTING ioctl is not called, a default routing
table with flat irqchip routing entries is built enabling to inject gsi
corresponding to the SPI indexes seen by the guest.

As soon as KVM_SET_GSI_ROUTING is called, user-space overwrites this
default routing table and is responsible for building the whole routing
table.

for arm/arm64 KVM_SET_GSI_ROUTING has a limited support:
- only applies to KVM_IRQFD and not to KVM_IRQ_LINE

- irqchip routing was tested on Calxeda midway (VFIO with irqfd)
  with and without explicit routing
- MSI routing without GICv3 ITS was tested using APM Xgene-I
  (qemu VIRTIO-PCI vhost-net without gsi_direct_mapping).
- MSI routing with GICv3 ITS is *NOT* tested.

Code can be found at https://git.linaro.org/people/eric.auger/linux.git/shortlog/refs/heads/v4.2-rc4-gsi-routing-v3

It applies on Andre's [PATCH v2 00/15] KVM: arm64: GICv3 ITS emulation
(http://lists.infradead.org/pipermail/linux-arm-kernel/2015-July/355727.html)

History:
v2 -> v3:
- eventually got rid of KVM_IRQ_ROUTING_EXTENDED_MSI new type at user
  api level and use KVM_MSI_VALID_DEVID flag instead
- remove usage of KVM_IRQ_ROUTING_EXTENDED_MSI type at kernel level too.
- propagate user flags downto the kernel to make sure the userspace
  correctly set devid in GICv3 ITS case (still under discussion)

v1 -> v2:
- user API changed:
  x devid id passed in kvm_irq_routing_msi
  x kept the new routing entry type: KVM_IRQ_ROUTING_EXTENDED_MSI
- kvm_host.h: adopt Andre's proposal to replace the msi_msg by a struct
  composed of the msi_msg and devid in kvm_kernel_irq_routing_entry
- Fix bug reported by Pavel: Added KVM_IRQ_ROUTING_EXTENDED_MSI handling
  in eventfd.c
- added vgic_v2m_inject_msi in vgic-v2-emul.c as suggested by Andre
- fix bug reported by Andre: bad setting of msi.flags and msi.devid
  in kvm_send_userspace_msi
- avoid injecting reserved IRQ numbers in vgic_irqfd_set_irq

RFC -> PATCH:
- clearly state limited support on arm/arm64:
  KVM_IRQ_LINE not impacted by GSI routing
- add default routing table feature (new patch file)
- changed uapi to use padding field area
- reword api.txt

Eric Auger (7):
  KVM: api: pass the devid in the msi routing entry
  KVM: kvm_host: add devid in kvm_kernel_irq_routing_entry
  KVM: irqchip: convey devid to kvm_set_msi
  KVM: arm/arm64: enable irqchip routing
  KVM: arm/arm64: build a default routing table
  KVM: arm/arm64: enable MSI routing
  KVM: arm: enable KVM_SIGNAL_MSI and MSI routing

 Documentation/virtual/kvm/api.txt |  35 ++++++++++---
 arch/arm/include/asm/kvm_host.h   |   2 +
 arch/arm/kvm/Kconfig              |   3 ++
 arch/arm/kvm/Makefile             |   2 +-
 arch/arm64/include/asm/kvm_host.h |   1 +
 arch/arm64/kvm/Kconfig            |   2 +
 arch/arm64/kvm/Makefile           |   2 +-
 include/kvm/arm_vgic.h            |   2 -
 include/linux/kvm_host.h          |   8 ++-
 include/uapi/linux/kvm.h          |   5 +-
 virt/kvm/arm/vgic-v2-emul.c       |  16 ++++++
 virt/kvm/arm/vgic.c               | 107 ++++++++++++++++++++++++++++++--------
 virt/kvm/irqchip.c                |   8 ++-
 13 files changed, 158 insertions(+), 35 deletions(-)

-- 
1.9.1



From eric.auger at linaro.org  Mon Aug  3 08:31:23 2015
From: eric.auger at linaro.org (Eric Auger)
Date: Mon,  3 Aug 2015 17:31:23 +0200
Subject: [PATCH v3 1/7] KVM: api: pass the devid in the msi routing entry
In-Reply-To: <1438615889-10892-1-git-send-email-eric.auger@linaro.org>
References: <1438615889-10892-1-git-send-email-eric.auger@linaro.org>
Message-ID: <1438615889-10892-2-git-send-email-eric.auger@linaro.org>

On ARM, the MSI msg (address and data) comes along with
out-of-band device ID information. The device ID encodes the
device that writes the MSI msg. Let's convey the device id in
kvm_irq_routing_msi and use KVM_MSI_VALID_DEVID flag value in
kvm_irq_routing_entry to indicate the msi devid is populated.

Signed-off-by: Eric Auger <eric.auger at linaro.org>

---
v2 -> v3:
- replace usage of KVM_IRQ_ROUTING_EXTENDED_MSI type by
  usage of KVM_MSI_VALID_DEVID flag
- add note about KVM_CAP_MSI_DEVID capability

v1 -> v2:
- devid id passed in kvm_irq_routing_msi instead of in
  kvm_irq_routing_entry

RFC -> PATCH
- remove kvm_irq_routing_extended_msi and use union instead
---
 Documentation/virtual/kvm/api.txt | 18 ++++++++++++++++--
 include/uapi/linux/kvm.h          |  5 ++++-
 2 files changed, 20 insertions(+), 3 deletions(-)

diff --git a/Documentation/virtual/kvm/api.txt b/Documentation/virtual/kvm/api.txt
index 1b53155..d4b29df 100644
--- a/Documentation/virtual/kvm/api.txt
+++ b/Documentation/virtual/kvm/api.txt
@@ -1454,7 +1454,10 @@ struct kvm_irq_routing_entry {
 #define KVM_IRQ_ROUTING_MSI 2
 #define KVM_IRQ_ROUTING_S390_ADAPTER 3
 
-No flags are specified so far, the corresponding field must be set to zero.
+flags:
+- KVM_MSI_VALID_DEVID: used along with KVM_IRQ_ROUTING_MSI
+  routing entry type, it tells the msi devid contains a valid value.
+- zero otherwise
 
 struct kvm_irq_routing_irqchip {
 	__u32 irqchip;
@@ -1465,9 +1468,20 @@ struct kvm_irq_routing_msi {
 	__u32 address_lo;
 	__u32 address_hi;
 	__u32 data;
-	__u32 pad;
+	union {
+		__u32 pad;
+		__u32 devid;
+	};
 };
 
+devid: If KVM_MSI_VALID_DEVID is set, contains a unique device identifier
+       for the device that wrote the MSI message.
+       For PCI, this is usually a BFD identifier in the lower 16 bits.
+
+The per-VM KVM_CAP_MSI_DEVID capability advertises the need to provide
+the device ID. If this capability is not set, userland cannot rely on
+the kernel to allow the KVM_MSI_VALID_DEVID flag being set.
+
 struct kvm_irq_routing_s390_adapter {
 	__u64 ind_addr;
 	__u64 summary_addr;
diff --git a/include/uapi/linux/kvm.h b/include/uapi/linux/kvm.h
index 1c48def..3c865b9 100644
--- a/include/uapi/linux/kvm.h
+++ b/include/uapi/linux/kvm.h
@@ -830,7 +830,10 @@ struct kvm_irq_routing_msi {
 	__u32 address_lo;
 	__u32 address_hi;
 	__u32 data;
-	__u32 pad;
+	union {
+		__u32 pad;
+		__u32 devid;
+	};
 };
 
 struct kvm_irq_routing_s390_adapter {
-- 
1.9.1



From eric.auger at linaro.org  Mon Aug  3 08:31:24 2015
From: eric.auger at linaro.org (Eric Auger)
Date: Mon,  3 Aug 2015 17:31:24 +0200
Subject: [PATCH v3 2/7] KVM: kvm_host: add devid in
 kvm_kernel_irq_routing_entry
In-Reply-To: <1438615889-10892-1-git-send-email-eric.auger@linaro.org>
References: <1438615889-10892-1-git-send-email-eric.auger@linaro.org>
Message-ID: <1438615889-10892-3-git-send-email-eric.auger@linaro.org>

Extend kvm_kernel_irq_routing_entry to transport the device id
field, devid. A new flags field makes possible to indicate the
devid is valid. Those additions are used for ARM GICv3 ITS MSI
injection.

Signed-off-by: Eric Auger <eric.auger at linaro.org>

---
v2 -> v3:
- add flags

v1 -> v2:
- replace msi_msg field by a struct composed of msi_msg and devid

RFC -> PATCH:
- reword the commit message after change in first patch (uapi)
---
 include/linux/kvm_host.h | 6 +++++-
 1 file changed, 5 insertions(+), 1 deletion(-)

diff --git a/include/linux/kvm_host.h b/include/linux/kvm_host.h
index 05e99b8..b784465 100644
--- a/include/linux/kvm_host.h
+++ b/include/linux/kvm_host.h
@@ -321,7 +321,11 @@ struct kvm_kernel_irq_routing_entry {
 			unsigned irqchip;
 			unsigned pin;
 		} irqchip;
-		struct msi_msg msi;
+		struct {
+			struct msi_msg msi;
+			u32 flags;
+			u32 devid;
+		};
 		struct kvm_s390_adapter_int adapter;
 	};
 	struct hlist_node link;
-- 
1.9.1



From eric.auger at linaro.org  Mon Aug  3 08:31:25 2015
From: eric.auger at linaro.org (Eric Auger)
Date: Mon,  3 Aug 2015 17:31:25 +0200
Subject: [PATCH v3 3/7] KVM: irqchip: convey devid to kvm_set_msi
In-Reply-To: <1438615889-10892-1-git-send-email-eric.auger@linaro.org>
References: <1438615889-10892-1-git-send-email-eric.auger@linaro.org>
Message-ID: <1438615889-10892-4-git-send-email-eric.auger@linaro.org>

on ARM, a devid field is populated in kvm_msi struct in case the
flag is set to KVM_MSI_VALID_DEVID. Let's propagate both flags and
devid field in kvm_kernel_irq_routing_entry.

Signed-off-by: Eric Auger <eric.auger at linaro.org>

---

v2 -> v3:
- do not set the type to KVM_IRQ_ROUTING_EXTENDED_MSI anymore as
  suggested by Andre
- correct msi->flags check
- propagate the flags
---
 virt/kvm/irqchip.c | 4 +++-
 1 file changed, 3 insertions(+), 1 deletion(-)

diff --git a/virt/kvm/irqchip.c b/virt/kvm/irqchip.c
index 21c1424..75c9931 100644
--- a/virt/kvm/irqchip.c
+++ b/virt/kvm/irqchip.c
@@ -72,12 +72,14 @@ int kvm_send_userspace_msi(struct kvm *kvm, struct kvm_msi *msi)
 {
 	struct kvm_kernel_irq_routing_entry route;
 
-	if (!irqchip_in_kernel(kvm) || msi->flags != 0)
+	if (!irqchip_in_kernel(kvm) || (msi->flags & ~KVM_MSI_VALID_DEVID))
 		return -EINVAL;
 
 	route.msi.address_lo = msi->address_lo;
 	route.msi.address_hi = msi->address_hi;
 	route.msi.data = msi->data;
+	route.flags = msi->flags;
+	route.devid = msi->devid;
 
 	return kvm_set_msi(&route, kvm, KVM_USERSPACE_IRQ_SOURCE_ID, 1, false);
 }
-- 
1.9.1



From eric.auger at linaro.org  Mon Aug  3 08:31:26 2015
From: eric.auger at linaro.org (Eric Auger)
Date: Mon,  3 Aug 2015 17:31:26 +0200
Subject: [PATCH v3 4/7] KVM: arm/arm64: enable irqchip routing
In-Reply-To: <1438615889-10892-1-git-send-email-eric.auger@linaro.org>
References: <1438615889-10892-1-git-send-email-eric.auger@linaro.org>
Message-ID: <1438615889-10892-5-git-send-email-eric.auger@linaro.org>

This patch adds compilation and link against irqchip.

On ARM, irqchip routing is not really useful since there is
a single irqchip. However main motivation behind using irqchip
code is to enable MSI routing code. With the support of in-kernel
GICv3 ITS emulation, it now seems to be a MUST HAVE requirement.

Functions previously implemented in vgic.c and substitute
to more complex irqchip implementation are removed:

- kvm_send_userspace_msi
- kvm_irq_map_chip_pin
- kvm_set_irq
- kvm_irq_map_gsi.

Routing standard hooks are now implemented in vgic:
- kvm_set_routing_entry
- kvm_set_irq
- kvm_set_msi

Both HAVE_KVM_IRQCHIP and HAVE_KVM_IRQ_ROUTING are defined.
KVM_CAP_IRQ_ROUTING is advertised and KVM_SET_GSI_ROUTING is allowed.

MSI routing setup is not yet allowed.

Signed-off-by: Eric Auger <eric.auger at linaro.org>

---
v2 -> v3:
- unconditionally set devid and KVM_MSI_VALID_DEVID flag as suggested
  by Andre (KVM_IRQ_ROUTING_EXTENDED_MSI type not used anymore)
- vgic_irqfd_set_irq now is static
- propagate flags
- add comments

v1 -> v2:
- fix bug reported by Andre related to msi.flags and msi.devid setting
  in kvm_send_userspace_msi
- avoid injecting reserved IRQ numbers in vgic_irqfd_set_irq

RFC -> PATCH
- reword api.txt:
  x move MSI routing comments in a subsequent patch,
  x clearly state GSI routing does not apply to KVM_IRQ_LINE

Conflicts:
	include/kvm/arm_vgic.h
	virt/kvm/arm/vgic.c
---
 Documentation/virtual/kvm/api.txt | 12 ++++--
 arch/arm/include/asm/kvm_host.h   |  2 +
 arch/arm/kvm/Kconfig              |  2 +
 arch/arm/kvm/Makefile             |  2 +-
 arch/arm64/include/asm/kvm_host.h |  1 +
 arch/arm64/kvm/Kconfig            |  2 +
 arch/arm64/kvm/Makefile           |  2 +-
 include/kvm/arm_vgic.h            |  2 -
 virt/kvm/arm/vgic.c               | 82 ++++++++++++++++++++++++++++-----------
 virt/kvm/irqchip.c                |  2 +
 10 files changed, 78 insertions(+), 31 deletions(-)

diff --git a/Documentation/virtual/kvm/api.txt b/Documentation/virtual/kvm/api.txt
index d4b29df..b6913c9 100644
--- a/Documentation/virtual/kvm/api.txt
+++ b/Documentation/virtual/kvm/api.txt
@@ -1421,13 +1421,16 @@ KVM_ASSIGN_DEV_IRQ. Partial deassignment of host or guest IRQ is allowed.
 4.52 KVM_SET_GSI_ROUTING
 
 Capability: KVM_CAP_IRQ_ROUTING
-Architectures: x86 s390
+Architectures: x86 s390 arm arm64
 Type: vm ioctl
 Parameters: struct kvm_irq_routing (in)
 Returns: 0 on success, -1 on error
 
 Sets the GSI routing table entries, overwriting any previously set entries.
 
+On arm/arm64, GSI routing has the following limitation:
+- GSI routing does not apply to KVM_IRQ_LINE but only to KVM_IRQFD.
+
 struct kvm_irq_routing {
 	__u32 nr;
 	__u32 flags;
@@ -2345,9 +2348,10 @@ Note that closing the resamplefd is not sufficient to disable the
 irqfd.  The KVM_IRQFD_FLAG_RESAMPLE is only necessary on assignment
 and need not be specified with KVM_IRQFD_FLAG_DEASSIGN.
 
-On ARM/ARM64, the gsi field in the kvm_irqfd struct specifies the Shared
-Peripheral Interrupt (SPI) index, such that the GIC interrupt ID is
-given by gsi + 32.
+On arm/arm64, gsi routing being supported, the following can happen:
+- in case no routing entry is associated to this gsi, injection fails
+- in case the gsi is associated to an irqchip routing entry,
+  irqchip.pin + 32 corresponds to the injected SPI ID.
 
 4.76 KVM_PPC_ALLOCATE_HTAB
 
diff --git a/arch/arm/include/asm/kvm_host.h b/arch/arm/include/asm/kvm_host.h
index 56cac05..8a68e9e 100644
--- a/arch/arm/include/asm/kvm_host.h
+++ b/arch/arm/include/asm/kvm_host.h
@@ -42,6 +42,8 @@
 
 #define KVM_VCPU_MAX_FEATURES 2
 
+#define KVM_IRQCHIP_NUM_PINS 988 /* 1020 - 32 is the number of SPI */
+
 #include <kvm/arm_vgic.h>
 
 u32 *kvm_vcpu_reg(struct kvm_vcpu *vcpu, u8 reg_num, u32 mode);
diff --git a/arch/arm/kvm/Kconfig b/arch/arm/kvm/Kconfig
index bfb915d..151e710 100644
--- a/arch/arm/kvm/Kconfig
+++ b/arch/arm/kvm/Kconfig
@@ -31,6 +31,8 @@ config KVM
 	select KVM_VFIO
 	select HAVE_KVM_EVENTFD
 	select HAVE_KVM_IRQFD
+	select HAVE_KVM_IRQCHIP
+	select HAVE_KVM_IRQ_ROUTING
 	depends on ARM_VIRT_EXT && ARM_LPAE && ARM_ARCH_TIMER
 	---help---
 	  Support hosting virtualized guest machines.
diff --git a/arch/arm/kvm/Makefile b/arch/arm/kvm/Makefile
index c5eef02c..1a8f48a 100644
--- a/arch/arm/kvm/Makefile
+++ b/arch/arm/kvm/Makefile
@@ -15,7 +15,7 @@ AFLAGS_init.o := -Wa,-march=armv7-a$(plus_virt)
 AFLAGS_interrupts.o := -Wa,-march=armv7-a$(plus_virt)
 
 KVM := ../../../virt/kvm
-kvm-arm-y = $(KVM)/kvm_main.o $(KVM)/coalesced_mmio.o $(KVM)/eventfd.o $(KVM)/vfio.o
+kvm-arm-y = $(KVM)/kvm_main.o $(KVM)/coalesced_mmio.o $(KVM)/eventfd.o $(KVM)/vfio.o $(KVM)/irqchip.o
 
 obj-y += kvm-arm.o init.o interrupts.o
 obj-y += arm.o handle_exit.o guest.o mmu.o emulate.o reset.o
diff --git a/arch/arm64/include/asm/kvm_host.h b/arch/arm64/include/asm/kvm_host.h
index 8d78a72..38a3291 100644
--- a/arch/arm64/include/asm/kvm_host.h
+++ b/arch/arm64/include/asm/kvm_host.h
@@ -44,6 +44,7 @@
 #include <kvm/arm_arch_timer.h>
 
 #define KVM_VCPU_MAX_FEATURES 3
+#define KVM_IRQCHIP_NUM_PINS 988 /* 1020 - 32 is the number of SPI */
 
 int __attribute_const__ kvm_target_cpu(void);
 int kvm_reset_vcpu(struct kvm_vcpu *vcpu);
diff --git a/arch/arm64/kvm/Kconfig b/arch/arm64/kvm/Kconfig
index ff9722f..1a9900d 100644
--- a/arch/arm64/kvm/Kconfig
+++ b/arch/arm64/kvm/Kconfig
@@ -32,6 +32,8 @@ config KVM
 	select HAVE_KVM_EVENTFD
 	select HAVE_KVM_IRQFD
 	select HAVE_KVM_MSI
+	select HAVE_KVM_IRQCHIP
+	select HAVE_KVM_IRQ_ROUTING
 	---help---
 	  Support hosting virtualized guest machines.
 
diff --git a/arch/arm64/kvm/Makefile b/arch/arm64/kvm/Makefile
index 9803307..90a08457 100644
--- a/arch/arm64/kvm/Makefile
+++ b/arch/arm64/kvm/Makefile
@@ -11,7 +11,7 @@ ARM=../../../arch/arm/kvm
 
 obj-$(CONFIG_KVM_ARM_HOST) += kvm.o
 
-kvm-$(CONFIG_KVM_ARM_HOST) += $(KVM)/kvm_main.o $(KVM)/coalesced_mmio.o $(KVM)/eventfd.o $(KVM)/vfio.o
+kvm-$(CONFIG_KVM_ARM_HOST) += $(KVM)/kvm_main.o $(KVM)/coalesced_mmio.o $(KVM)/eventfd.o $(KVM)/vfio.o $(KVM)/irqchip.o
 kvm-$(CONFIG_KVM_ARM_HOST) += $(ARM)/arm.o $(ARM)/mmu.o $(ARM)/mmio.o
 kvm-$(CONFIG_KVM_ARM_HOST) += $(ARM)/psci.o $(ARM)/perf.o
 
diff --git a/include/kvm/arm_vgic.h b/include/kvm/arm_vgic.h
index f50081c..1b370a0 100644
--- a/include/kvm/arm_vgic.h
+++ b/include/kvm/arm_vgic.h
@@ -375,6 +375,4 @@ static inline int vgic_v3_probe(struct device_node *vgic_node,
 }
 #endif
 
-int kvm_send_userspace_msi(struct kvm *kvm, struct kvm_msi *msi);
-
 #endif
diff --git a/virt/kvm/arm/vgic.c b/virt/kvm/arm/vgic.c
index 081a1ef..8114235 100644
--- a/virt/kvm/arm/vgic.c
+++ b/virt/kvm/arm/vgic.c
@@ -2215,42 +2215,78 @@ out_free_irq:
 	return ret;
 }
 
-int kvm_irq_map_gsi(struct kvm *kvm,
-		    struct kvm_kernel_irq_routing_entry *entries,
-		    int gsi)
-{
-	return 0;
-}
-
-int kvm_irq_map_chip_pin(struct kvm *kvm, unsigned irqchip, unsigned pin)
-{
-	return pin;
-}
-
-int kvm_set_irq(struct kvm *kvm, int irq_source_id,
-		u32 irq, int level, bool line_status)
+/**
+ * vgic_irqfd_set_irq: inject the IRQ corresponding to the
+ * irqchip routing entry
+ *
+ * This is the entry point for irqfd IRQ injection
+ */
+static int vgic_irqfd_set_irq(struct kvm_kernel_irq_routing_entry *e,
+			struct kvm *kvm, int irq_source_id,
+			int level, bool line_status)
 {
-	unsigned int spi = irq + VGIC_NR_PRIVATE_IRQS;
+	unsigned int spi_id = e->irqchip.pin + VGIC_NR_PRIVATE_IRQS;
 
-	trace_kvm_set_irq(irq, level, irq_source_id);
+	trace_kvm_set_irq(spi_id, level, irq_source_id);
 
 	BUG_ON(!vgic_initialized(kvm));
 
-	return kvm_vgic_inject_irq(kvm, 0, spi, level);
+	if (spi_id > min(kvm->arch.vgic.nr_irqs, 1020))
+		return -EINVAL;
+	return kvm_vgic_inject_irq(kvm, 0, spi_id, level);
+}
+
+/**
+ * kvm_set_routing_entry: populate a kvm routing entry
+ * from a user routing entry
+ *
+ * @e: kvm kernel routing entry handle
+ * @ue: user api routing entry handle
+ * return 0 on success, -EINVAL on errors.
+ */
+int kvm_set_routing_entry(struct kvm_kernel_irq_routing_entry *e,
+			  const struct kvm_irq_routing_entry *ue)
+{
+	int r = -EINVAL;
+
+	switch (ue->type) {
+	case KVM_IRQ_ROUTING_IRQCHIP:
+		e->set = vgic_irqfd_set_irq;
+		e->irqchip.irqchip = ue->u.irqchip.irqchip;
+		e->irqchip.pin = ue->u.irqchip.pin;
+		if ((e->irqchip.pin >= KVM_IRQCHIP_NUM_PINS) ||
+		    (e->irqchip.irqchip >= KVM_NR_IRQCHIPS))
+			goto out;
+		break;
+	default:
+		goto out;
+	}
+	r = 0;
+out:
+	return r;
 }
 
-/* MSI not implemented yet */
+/**
+ * kvm_set_msi: inject the MSI corresponding to the
+ * MSI routing entry
+ *
+ * This is the entry point for irqfd MSI injection
+ * and userspace MSI injection.
+ */
 int kvm_set_msi(struct kvm_kernel_irq_routing_entry *e,
 		struct kvm *kvm, int irq_source_id,
 		int level, bool line_status)
 {
-	return 0;
-}
+	struct kvm_msi msi;
+
+	msi.address_lo = e->msi.address_lo;
+	msi.address_hi = e->msi.address_hi;
+	msi.data = e->msi.data;
+	msi.flags = e->flags;
+	msi.devid = e->devid;
 
-int kvm_send_userspace_msi(struct kvm *kvm, struct kvm_msi *msi)
-{
 	if (kvm->arch.vgic.vm_ops.inject_msi)
-		return kvm->arch.vgic.vm_ops.inject_msi(kvm, msi);
+		return kvm->arch.vgic.vm_ops.inject_msi(kvm, &msi);
 	else
 		return -ENODEV;
 }
diff --git a/virt/kvm/irqchip.c b/virt/kvm/irqchip.c
index 75c9931..e1559d4 100644
--- a/virt/kvm/irqchip.c
+++ b/virt/kvm/irqchip.c
@@ -29,7 +29,9 @@
 #include <linux/srcu.h>
 #include <linux/export.h>
 #include <trace/events/kvm.h>
+#if !defined(CONFIG_ARM) && !defined(CONFIG_ARM64)
 #include "irq.h"
+#endif
 
 struct kvm_irq_routing_table {
 	int chip[KVM_NR_IRQCHIPS][KVM_IRQCHIP_NUM_PINS];
-- 
1.9.1



From eric.auger at linaro.org  Mon Aug  3 08:31:27 2015
From: eric.auger at linaro.org (Eric Auger)
Date: Mon,  3 Aug 2015 17:31:27 +0200
Subject: [PATCH v3 5/7] KVM: arm/arm64: build a default routing table
In-Reply-To: <1438615889-10892-1-git-send-email-eric.auger@linaro.org>
References: <1438615889-10892-1-git-send-email-eric.auger@linaro.org>
Message-ID: <1438615889-10892-6-git-send-email-eric.auger@linaro.org>

Implement a default routing table made of flat irqchip routing
entries (gsi = irqchip.pin) covering the VGIC SPI indexes.
This routing table is overwritten by the first user-space call
to KVM_SET_GSI_ROUTING ioctl.

Signed-off-by: Eric Auger <eric.auger at linaro.org>

---

PATCH: creation
---
 virt/kvm/arm/vgic.c | 21 +++++++++++++++++++++
 1 file changed, 21 insertions(+)

diff --git a/virt/kvm/arm/vgic.c b/virt/kvm/arm/vgic.c
index 8114235..1b092e3 100644
--- a/virt/kvm/arm/vgic.c
+++ b/virt/kvm/arm/vgic.c
@@ -1785,6 +1785,8 @@ int vgic_init(struct kvm *kvm)
 	ret |= vgic_init_bitmap(&dist->irq_cfg, nr_cpus, nr_irqs);
 	ret |= vgic_init_bytemap(&dist->irq_priority, nr_cpus, nr_irqs);
 
+	ret |= kvm_setup_default_irq_routing(kvm);
+
 	if (ret)
 		goto out;
 
@@ -2266,6 +2268,25 @@ out:
 	return r;
 }
 
+int kvm_setup_default_irq_routing(struct kvm *kvm)
+{
+	struct kvm_irq_routing_entry *entries;
+	u32 nr = kvm->arch.vgic.nr_irqs - VGIC_NR_PRIVATE_IRQS;
+	int i, ret;
+
+	entries = kcalloc(nr, sizeof(struct kvm_kernel_irq_routing_entry),
+			  GFP_KERNEL);
+	for (i = 0; i < nr; i++) {
+		entries[i].gsi = i;
+		entries[i].type = KVM_IRQ_ROUTING_IRQCHIP;
+		entries[i].u.irqchip.irqchip = 0;
+		entries[i].u.irqchip.pin = i;
+	}
+	ret = kvm_set_irq_routing(kvm, entries, nr, 0);
+	kfree(entries);
+	return ret;
+}
+
 /**
  * kvm_set_msi: inject the MSI corresponding to the
  * MSI routing entry
-- 
1.9.1



From eric.auger at linaro.org  Mon Aug  3 08:31:28 2015
From: eric.auger at linaro.org (Eric Auger)
Date: Mon,  3 Aug 2015 17:31:28 +0200
Subject: [PATCH v3 6/7] KVM: arm/arm64: enable MSI routing
In-Reply-To: <1438615889-10892-1-git-send-email-eric.auger@linaro.org>
References: <1438615889-10892-1-git-send-email-eric.auger@linaro.org>
Message-ID: <1438615889-10892-7-git-send-email-eric.auger@linaro.org>

Up to now, only irqchip routing entries could be set. This patch
adds the capability to insert MSI routing entries.

For ARM64, let's also increase KVM_MAX_IRQ_ROUTES to 4096: this
include SPI irqchip routes plus MSI routes. In the future this
might be extended.

Signed-off-by: Eric Auger <eric.auger at linaro.org>

---
v2 -> v3:
- remove any reference to KVM_IRQ_ROUTING_EXTENDED_MSI type
- unconditionnaly uapi flags and devid downto the kernel
  routing entry struct
- handle KVM_MSI_VALID_DEVID flag in kvm_set_irq_routing
- note about KVM_CAP_MSI_DEVID moved in the first patch file
  of the series

v1 -> v2:
- adapt to new routing entry types

RFC -> PATCH:
- move api MSI routing updates into that patch file
- use new devid field of user api struct
---
 Documentation/virtual/kvm/api.txt | 5 +++++
 include/linux/kvm_host.h          | 2 ++
 virt/kvm/arm/vgic.c               | 8 ++++++++
 virt/kvm/irqchip.c                | 2 +-
 4 files changed, 16 insertions(+), 1 deletion(-)

diff --git a/Documentation/virtual/kvm/api.txt b/Documentation/virtual/kvm/api.txt
index b6913c9..4f15347 100644
--- a/Documentation/virtual/kvm/api.txt
+++ b/Documentation/virtual/kvm/api.txt
@@ -2352,6 +2352,11 @@ On arm/arm64, gsi routing being supported, the following can happen:
 - in case no routing entry is associated to this gsi, injection fails
 - in case the gsi is associated to an irqchip routing entry,
   irqchip.pin + 32 corresponds to the injected SPI ID.
+- in case the gsi is associated to an MSI routing entry,
+  * without GICv3 ITS in-kernel emulation, MSI data matches the SPI ID
+    of the injected SPI
+  * with GICv3 ITS in-kernel emulation, the MSI message and device ID
+    are translated into an LPI.
 
 4.76 KVM_PPC_ALLOCATE_HTAB
 
diff --git a/include/linux/kvm_host.h b/include/linux/kvm_host.h
index b784465..d00a113 100644
--- a/include/linux/kvm_host.h
+++ b/include/linux/kvm_host.h
@@ -995,6 +995,8 @@ static inline int mmu_notifier_retry(struct kvm *kvm, unsigned long mmu_seq)
 
 #ifdef CONFIG_S390
 #define KVM_MAX_IRQ_ROUTES 4096 //FIXME: we can have more than that...
+#elif defined(CONFIG_ARM64)
+#define KVM_MAX_IRQ_ROUTES 4096
 #else
 #define KVM_MAX_IRQ_ROUTES 1024
 #endif
diff --git a/virt/kvm/arm/vgic.c b/virt/kvm/arm/vgic.c
index 1b092e3..0165f34 100644
--- a/virt/kvm/arm/vgic.c
+++ b/virt/kvm/arm/vgic.c
@@ -2260,6 +2260,14 @@ int kvm_set_routing_entry(struct kvm_kernel_irq_routing_entry *e,
 		    (e->irqchip.irqchip >= KVM_NR_IRQCHIPS))
 			goto out;
 		break;
+	case KVM_IRQ_ROUTING_MSI:
+		e->set = kvm_set_msi;
+		e->msi.address_lo = ue->u.msi.address_lo;
+		e->msi.address_hi = ue->u.msi.address_hi;
+		e->msi.data = ue->u.msi.data;
+		e->flags = ue->flags;
+		e->devid = ue->u.msi.devid;
+		break;
 	default:
 		goto out;
 	}
diff --git a/virt/kvm/irqchip.c b/virt/kvm/irqchip.c
index e1559d4..48ebc4d 100644
--- a/virt/kvm/irqchip.c
+++ b/virt/kvm/irqchip.c
@@ -217,7 +217,7 @@ int kvm_set_irq_routing(struct kvm *kvm,
 			goto out;
 
 		r = -EINVAL;
-		if (ue->flags)
+		if (ue->flags & ~KVM_MSI_VALID_DEVID)
 			goto out;
 		r = setup_routing_entry(new, e, ue);
 		if (r)
-- 
1.9.1



From eric.auger at linaro.org  Mon Aug  3 08:31:29 2015
From: eric.auger at linaro.org (Eric Auger)
Date: Mon,  3 Aug 2015 17:31:29 +0200
Subject: [PATCH v3 7/7] KVM: arm: enable KVM_SIGNAL_MSI and MSI routing
In-Reply-To: <1438615889-10892-1-git-send-email-eric.auger@linaro.org>
References: <1438615889-10892-1-git-send-email-eric.auger@linaro.org>
Message-ID: <1438615889-10892-8-git-send-email-eric.auger@linaro.org>

If the ITS modality is not available, let's simply support MSI
injection by transforming the MSI.data into an SPI ID.

This becomes possible to use KVM_SIGNAL_MSI ioctl and MSI
routing for arm too.

Signed-off-by: Eric Auger <eric.auger at linaro.org>

---

v2 -> v3:
- reword the commit message
- add sanity check about devid provision

v1 -> v2:
- introduce vgic_v2m_inject_msi in vgic-v2-emul.c following Andre's
  advice
---
 arch/arm/kvm/Kconfig        |  1 +
 virt/kvm/arm/vgic-v2-emul.c | 16 ++++++++++++++++
 2 files changed, 17 insertions(+)

diff --git a/arch/arm/kvm/Kconfig b/arch/arm/kvm/Kconfig
index 151e710..0f58baf 100644
--- a/arch/arm/kvm/Kconfig
+++ b/arch/arm/kvm/Kconfig
@@ -31,6 +31,7 @@ config KVM
 	select KVM_VFIO
 	select HAVE_KVM_EVENTFD
 	select HAVE_KVM_IRQFD
+	select HAVE_KVM_MSI
 	select HAVE_KVM_IRQCHIP
 	select HAVE_KVM_IRQ_ROUTING
 	depends on ARM_VIRT_EXT && ARM_LPAE && ARM_ARCH_TIMER
diff --git a/virt/kvm/arm/vgic-v2-emul.c b/virt/kvm/arm/vgic-v2-emul.c
index 8faa28c..ba2b393 100644
--- a/virt/kvm/arm/vgic-v2-emul.c
+++ b/virt/kvm/arm/vgic-v2-emul.c
@@ -478,6 +478,21 @@ static bool vgic_v2_queue_sgi(struct kvm_vcpu *vcpu, int irq)
 }
 
 /**
+ * vgic_v2m_inject_msi: emulates GICv2M MSI injection by injecting
+ * the SPI ID matching the msi data
+ *
+ * @kvm: pointer to the kvm struct
+ * @msi: the msi struct handle
+ */
+static int vgic_v2m_inject_msi(struct kvm *kvm, struct kvm_msi *msi)
+{
+	if (msi->flags & KVM_MSI_VALID_DEVID)
+		return -EINVAL;
+
+	return kvm_vgic_inject_irq(kvm, 0, msi->data, 1);
+}
+
+/**
  * kvm_vgic_map_resources - Configure global VGIC state before running any VCPUs
  * @kvm: pointer to the kvm struct
  *
@@ -566,6 +581,7 @@ void vgic_v2_init_emulation(struct kvm *kvm)
 	dist->vm_ops.add_sgi_source = vgic_v2_add_sgi_source;
 	dist->vm_ops.init_model = vgic_v2_init_model;
 	dist->vm_ops.map_resources = vgic_v2_map_resources;
+	dist->vm_ops.inject_msi = vgic_v2m_inject_msi;
 
 	dist->vgic_cpu_base = VGIC_ADDR_UNDEF;
 	dist->vgic_dist_base = VGIC_ADDR_UNDEF;
-- 
1.9.1



From b.zolnierkie at samsung.com  Mon Aug  3 08:33:24 2015
From: b.zolnierkie at samsung.com (Bartlomiej Zolnierkiewicz)
Date: Mon, 03 Aug 2015 17:33:24 +0200
Subject: MAINTAINERS/s5p: Kamil Debski no longer with Samsung?
In-Reply-To: <1438548040.30149.1.camel@perches.com>
References: <20150802203128.1B6952691B2@smtprelay05.hostedemail.com>
 <1438548040.30149.1.camel@perches.com>
Message-ID: <5606140.737HZuKSvR@amdc1976>


Hi,

On Sunday, August 02, 2015 01:40:40 PM Joe Perches wrote:
> On Sun, 2015-08-02 at 20:31 +0000, Mail Delivery System wrote:
> > <k.debski at samsung.com>: host mailin.samsung.com[203.254.224.12] 
> > said: 550 5.1.1
> >     Recipient address rejected: User unknown (in reply to RCPT TO 
> > command)
> 
> His email address bounces.
> 
> Should MAINTAINERS be updated?

Please wait with these changes, the situation should be clarified soon
(I've added Kamil to Cc).

Best regards,
--
Bartlomiej Zolnierkiewicz
Samsung R&D Institute Poland
Samsung Electronics

> ---
>  MAINTAINERS | 8 ++------
>  1 file changed, 2 insertions(+), 6 deletions(-)
> 
> diff --git a/MAINTAINERS b/MAINTAINERS
> index 826affa..b5197c7 100644
> --- a/MAINTAINERS
> +++ b/MAINTAINERS
> @@ -1442,7 +1442,6 @@ F:        arch/arm/mach-s5pv210/
>  
>  ARM/SAMSUNG S5P SERIES 2D GRAPHICS ACCELERATION (G2D) SUPPORT
>  M:     Kyungmin Park <kyungmin.park at samsung.com>
> -M:     Kamil Debski <k.debski at samsung.com>
>  L:     linux-arm-kernel at lists.infradead.org
>  L:     linux-media at vger.kernel.org
>  S:     Maintained
> @@ -1450,7 +1449,6 @@ F:        drivers/media/platform/s5p-g2d/
>  
>  ARM/SAMSUNG S5P SERIES Multi Format Codec (MFC) SUPPORT
>  M:     Kyungmin Park <kyungmin.park at samsung.com>
> -M:     Kamil Debski <k.debski at samsung.com>
>  M:     Jeongtae Park <jtp.park at samsung.com>
>  L:     linux-arm-kernel at lists.infradead.org
>  L:     linux-media at vger.kernel.org
> @@ -8248,9 +8246,8 @@ S:        Maintained
>  F:     drivers/media/usb/pwc/*
>  
>  PWM FAN DRIVER
> -M:     Kamil Debski <k.debski at samsung.com>
>  L:     lm-sensors at lm-sensors.org
> -S:     Supported
> +S:     Orphan
>  F:     Documentation/devicetree/bindings/hwmon/pwm-fan.txt
>  F:     Documentation/hwmon/pwm-fan
>  F:     drivers/hwmon/pwm-fan.c
> @@ -8906,9 +8903,8 @@ T:        https://github.com/lmajewski/linux-samsung-thermal.git
>  F:     drivers/thermal/samsung/
>  
>  SAMSUNG USB2 PHY DRIVER
> -M:     Kamil Debski <k.debski at samsung.com>
>  L:     linux-kernel at vger.kernel.org
> -S:     Supported
> +S:     Orphan
>  F:     Documentation/devicetree/bindings/phy/samsung-phy.txt
>  F:     Documentation/phy/samsung-usb2.txt
>  F:     drivers/phy/phy-exynos4210-usb2.c



From viresh.kumar at linaro.org  Mon Aug  3 08:50:41 2015
From: viresh.kumar at linaro.org (Viresh Kumar)
Date: Mon, 3 Aug 2015 21:20:41 +0530
Subject: [PATCH v3 3/5] ARM: Exynos: switch to using generic cpufreq
 driver for Exynos4x12
In-Reply-To: <2347616.SxxJmTVssu@amdc1976>
References: <1438368557-2352-1-git-send-email-b.zolnierkie@samsung.com>
 <4532306.AVvo5hem3c@amdc1976> <55BF4D41.1060903@samsung.com>
 <2347616.SxxJmTVssu@amdc1976>
Message-ID: <20150803155041.GE21529@linux>

On 03-08-15, 15:55, Bartlomiej Zolnierkiewicz wrote:
> diff --git a/arch/arm/mach-exynos/Kconfig b/arch/arm/mach-exynos/Kconfig
> index 81064cd..491914c 100644
> --- a/arch/arm/mach-exynos/Kconfig
> +++ b/arch/arm/mach-exynos/Kconfig
> @@ -25,6 +25,8 @@ menuconfig ARCH_EXYNOS
>  	select S5P_DEV_MFC
>  	select SRAM
>  	select MFD_SYSCON
> +	select THERMAL
> +	select EXYNOS_THERMAL

Why do you need to select both of them?

>  	help
>  	  Support for SAMSUNG EXYNOS SoCs (EXYNOS4/5)
>  
> diff --git a/arch/arm/mach-exynos/exynos.c b/arch/arm/mach-exynos/exynos.c
> index 77ac021..1c47aee 100644
> --- a/arch/arm/mach-exynos/exynos.c
> +++ b/arch/arm/mach-exynos/exynos.c
> @@ -227,6 +227,8 @@ static void __init exynos_init_irq(void)
>  static const struct of_device_id exynos_cpufreq_matches[] = {
>  	{ .compatible = "samsung,exynos3250", .data = "cpufreq-dt" },
>  	{ .compatible = "samsung,exynos4210", .data = "cpufreq-dt" },
> +	{ .compatible = "samsung,exynos4212", .data = "cpufreq-dt" },
> +	{ .compatible = "samsung,exynos4412", .data = "cpufreq-dt" },
>  	{ .compatible = "samsung,exynos5250", .data = "cpufreq-dt" },
>  	{ /* sentinel */ }
>  };

Otherwise looks fine:

Acked-by: Viresh Kumar <viresh.kumar at linaro.org>

-- 
viresh


From daniel.lezcano at linaro.org  Mon Aug  3 08:51:35 2015
From: daniel.lezcano at linaro.org (Daniel Lezcano)
Date: Mon, 03 Aug 2015 17:51:35 +0200
Subject: [PATCH v2 4/9] clocksource: mediatek: Use GPT as sched clock
 source
In-Reply-To: <1431763110-443-5-git-send-email-yingjoe.chen@mediatek.com>
References: <1431763110-443-1-git-send-email-yingjoe.chen@mediatek.com>
 <1431763110-443-5-git-send-email-yingjoe.chen@mediatek.com>
Message-ID: <55BF8E07.7090308@linaro.org>

On 05/16/2015 09:58 AM, Yingjoe Chen wrote:
> When cpu is in deep idle, arch timer will stop counting. Setup GPT as
> sched clock source so it can keep counting in idle.
>
> Signed-off-by: Yingjoe Chen <yingjoe.chen at mediatek.com>
> ---

Acked-by: Daniel Lezcano <daniel.lezcano at linaro.org>

-- 
  <http://www.linaro.org/> Linaro.org ? Open source software for ARM SoCs

Follow Linaro:  <http://www.facebook.com/pages/Linaro> Facebook |
<http://twitter.com/#!/linaroorg> Twitter |
<http://www.linaro.org/linaro-blog/> Blog



From eric.auger at linaro.org  Mon Aug  3 08:37:28 2015
From: eric.auger at linaro.org (Eric Auger)
Date: Mon, 03 Aug 2015 17:37:28 +0200
Subject: [PATCH v2 14/15] KVM: arm64: implement MSI injection in ITS
 emulation
In-Reply-To: <00f101d0cdcd$146a6090$3d3f21b0$@samsung.com>
References: <1436538111-4294-1-git-send-email-andre.przywara@arm.com>
 <1436538111-4294-15-git-send-email-andre.przywara@arm.com>
 <55BB7678.5080105@linaro.org> <55BE7BA1.40403@arm.com>
 <00a201d0cdb7$70a623f0$51f26bd0$@samsung.com> <55BF2F51.6020701@linaro.org>
 <00f101d0cdcd$146a6090$3d3f21b0$@samsung.com>
Message-ID: <55BF8AB8.5050408@linaro.org>

Andre, Pavel,
On 08/03/2015 11:16 AM, Pavel Fedin wrote:
>  Hello!
> 
>> Again the case that leaves me uncomfortable is the one where the
>> userspace does not provide the devid whereas it must (GICv3 ITS case).
> 
>  Hypothetical broken userland which does not exist for now ?
Yes but that's the rule to be not confident in *any* userspace, isn't it?

As of now I prefer keeping the flags at uapi level and propagate it
downto the kernel, as long as I don't have any answer for the unset
devid discrimination question. Please apologize for my stubbornness ;-)

Best Regards

Eric


>  IMHO the userland should just know, that if it supports ITS, it has to provide devIDs.
> 
> Kind regards,
> Pavel Fedin
> Expert Engineer
> Samsung Electronics Research center Russia
> 
> 



From robherring2 at gmail.com  Mon Aug  3 08:55:11 2015
From: robherring2 at gmail.com (Rob Herring)
Date: Mon, 3 Aug 2015 10:55:11 -0500
Subject: [PATCH v4] dtb: Create a common home for cross-architecture dtsi
 files.
In-Reply-To: <1438592111-8471-1-git-send-email-ian.campbell@citrix.com>
References: <1438592111-8471-1-git-send-email-ian.campbell@citrix.com>
Message-ID: <CAL_JsqLU_CMaYN=FpVdeenVYgvBNDUQsqvi=uwuENOk=pt0WZQ@mail.gmail.com>

On Mon, Aug 3, 2015 at 3:55 AM, Ian Campbell <ian.campbell at citrix.com> wrote:
> Commit 9ccd608070b6 ("arm64: dts: add device tree for ARM SMM-A53x2 on
> LogicTile Express 20MG") added a new dts file to arch/arm64 which
> included "../../../../arm/boot/dts/vexpress-v2m-rs1.dtsi", i.e. a
> .dtsi supplied by arch/arm.
>
> Unfortunately this causes some issues for the split device tree
> repository[0], since things get moved around there. In that context
> the new .dts ends up at src/arm64/arm/vexpress-v2f-1xv7-ca53x2.dts
> while the include is at src/arm/vexpress-v2m-rs1.dtsi.
>
> The sharing of the .dtsi is legitimate since the baseboard is the same
> for various vexpress systems whatever processor they use.
>
> Rather than using ../../ tricks to pickup .dtsi files from another
> arch this patch creates a new directory kernel/dts as a home for such
> cross-arch .dtsi files, arranges for it to be in the include path when
> the .dts files are processed by cpp and switches the .dts files to use
> cpp #include instead of /include/. The dtsi file itself is moved into
> a vendor subdir in this case "arm" (the vendor, not the ARCH=).

Sigh, it was not the include path I was referring to being wrong
although that was too. It was the part about using #include instead of
/include/.

Rob

>
> [0] https://git.kernel.org/cgit/linux/kernel/git/devicetree/devicetree-rebasing.git/
>
> Signed-off-by: Ian Campbell <ian.campbell at citrix.com>
> Cc: Rob Herring <robh+dt at kernel.org>
> Cc: Pawel Moll <pawel.moll at arm.com>
> Cc: Mark Rutland <mark.rutland at arm.com>
> Cc: Kumar Gala <galak at codeaurora.org>
> Cc: Liviu Dudau <liviu.dudau at arm.com>
> Cc: Sudeep Holla <sudeep.holla at arm.com>
> Cc: Lorenzo Pieralisi <lorenzo.pieralisi at arm.com>
> Cc: Russell King <linux at arm.linux.org.uk>
> Cc: Catalin Marinas <catalin.marinas at arm.com>
> Cc: Will Deacon <will.deacon at arm.com>
> Cc: Kristina Martsenko <kristina.martsenko at arm.com>
> Cc: Kevin Hilman <khilman at linaro.org>
> Cc: devicetree at vger.kernel.org
> Cc: linux-kernel at vger.kernel.org
> Cc: linux-arm-kernel at lists.infradead.org
> Cc: linux-kbuild at vger.kernel.org
> Acked-by: Mark Rutland <mark.rutland at arm.com>
> Acked-by: Rob Herring <robh at kernel.org>
> Acked-by: Liviu Dudau <Liviu.Dudau at arm.com>
> Reviewed-by: Masahiro Yamada <yamada.masahiro at socionext.com>
> ---
> v2: Move to include/dt-dtsi and introduce a per-vendor subdirectory.
>
> v3: Move to kernel/dts.
>     Include new directory in DTC include path as well as cpp path, and
>     therefore switch back to /include/.
>     Update MAINTAINERS
>
> v4: Change path in changelog too.
>     Add ()s to title of 9ccd608070b6.
> ---
>  Documentation/devicetree/bindings/arm/vexpress.txt          | 2 +-
>  MAINTAINERS                                                 | 1 +
>  arch/arm/boot/dts/vexpress-v2p-ca15-tc1.dts                 | 2 +-
>  arch/arm/boot/dts/vexpress-v2p-ca15_a7.dts                  | 2 +-
>  arch/arm/boot/dts/vexpress-v2p-ca5s.dts                     | 2 +-
>  arch/arm64/boot/dts/arm/vexpress-v2f-1xv7-ca53x2.dts        | 2 +-
>  {arch/arm/boot/dts => kernel/dts/arm}/vexpress-v2m-rs1.dtsi | 0
>  scripts/Makefile.lib                                        | 3 ++-
>  8 files changed, 8 insertions(+), 6 deletions(-)
>  rename {arch/arm/boot/dts => kernel/dts/arm}/vexpress-v2m-rs1.dtsi (100%)
>
> diff --git a/Documentation/devicetree/bindings/arm/vexpress.txt b/Documentation/devicetree/bindings/arm/vexpress.txt
> index 39844cd..b6031d9 100644
> --- a/Documentation/devicetree/bindings/arm/vexpress.txt
> +++ b/Documentation/devicetree/bindings/arm/vexpress.txt
> @@ -223,7 +223,7 @@ Example of a VE tile description (simplified)
>                 /* Active high IRQ 0 is connected to GIC's SPI0 */
>                 interrupt-map = <0 0 0 &gic 0 0 4>;
>
> -               /include/ "vexpress-v2m-rs1.dtsi"
> +               /include/ "arm/vexpress-v2m-rs1.dtsi"
>         };
>  };
>
> diff --git a/MAINTAINERS b/MAINTAINERS
> index a226416..1941078 100644
> --- a/MAINTAINERS
> +++ b/MAINTAINERS
> @@ -7537,6 +7537,7 @@ S:        Maintained
>  F:     Documentation/devicetree/
>  F:     arch/*/boot/dts/
>  F:     include/dt-bindings/
> +F:     kernel/dts/
>
>  OPEN FIRMWARE AND DEVICE TREE OVERLAYS
>  M:     Pantelis Antoniou <pantelis.antoniou at konsulko.com>
> diff --git a/arch/arm/boot/dts/vexpress-v2p-ca15-tc1.dts b/arch/arm/boot/dts/vexpress-v2p-ca15-tc1.dts
> index 9420053..b144092 100644
> --- a/arch/arm/boot/dts/vexpress-v2p-ca15-tc1.dts
> +++ b/arch/arm/boot/dts/vexpress-v2p-ca15-tc1.dts
> @@ -278,6 +278,6 @@
>                                 <0 0 41 &gic 0 41 4>,
>                                 <0 0 42 &gic 0 42 4>;
>
> -               /include/ "vexpress-v2m-rs1.dtsi"
> +               /include/ "arm/vexpress-v2m-rs1.dtsi"
>         };
>  };
> diff --git a/arch/arm/boot/dts/vexpress-v2p-ca15_a7.dts b/arch/arm/boot/dts/vexpress-v2p-ca15_a7.dts
> index 17f63f7..350f402 100644
> --- a/arch/arm/boot/dts/vexpress-v2p-ca15_a7.dts
> +++ b/arch/arm/boot/dts/vexpress-v2p-ca15_a7.dts
> @@ -636,6 +636,6 @@
>                                 <0 0 41 &gic 0 41 4>,
>                                 <0 0 42 &gic 0 42 4>;
>
> -               /include/ "vexpress-v2m-rs1.dtsi"
> +               /include/ "arm/vexpress-v2m-rs1.dtsi"
>         };
>  };
> diff --git a/arch/arm/boot/dts/vexpress-v2p-ca5s.dts b/arch/arm/boot/dts/vexpress-v2p-ca5s.dts
> index d2709b7..585ced0 100644
> --- a/arch/arm/boot/dts/vexpress-v2p-ca5s.dts
> +++ b/arch/arm/boot/dts/vexpress-v2p-ca5s.dts
> @@ -248,6 +248,6 @@
>                                 <0 0 41 &gic 0 41 4>,
>                                 <0 0 42 &gic 0 42 4>;
>
> -               /include/ "vexpress-v2m-rs1.dtsi"
> +               /include/ "arm/vexpress-v2m-rs1.dtsi"
>         };
>  };
> diff --git a/arch/arm64/boot/dts/arm/vexpress-v2f-1xv7-ca53x2.dts b/arch/arm64/boot/dts/arm/vexpress-v2f-1xv7-ca53x2.dts
> index 5b1d018..c044804 100644
> --- a/arch/arm64/boot/dts/arm/vexpress-v2f-1xv7-ca53x2.dts
> +++ b/arch/arm64/boot/dts/arm/vexpress-v2f-1xv7-ca53x2.dts
> @@ -186,6 +186,6 @@
>                                 <0 0 41 &gic GIC_SPI 41 IRQ_TYPE_LEVEL_HIGH>,
>                                 <0 0 42 &gic GIC_SPI 42 IRQ_TYPE_LEVEL_HIGH>;
>
> -               /include/ "../../../../arm/boot/dts/vexpress-v2m-rs1.dtsi"
> +               /include/ "arm/vexpress-v2m-rs1.dtsi"
>         };
>  };
> diff --git a/arch/arm/boot/dts/vexpress-v2m-rs1.dtsi b/kernel/dts/arm/vexpress-v2m-rs1.dtsi
> similarity index 100%
> rename from arch/arm/boot/dts/vexpress-v2m-rs1.dtsi
> rename to kernel/dts/arm/vexpress-v2m-rs1.dtsi
> diff --git a/scripts/Makefile.lib b/scripts/Makefile.lib
> index 79e8661..b4d9fb6 100644
> --- a/scripts/Makefile.lib
> +++ b/scripts/Makefile.lib
> @@ -163,6 +163,7 @@ dtc_cpp_flags  = -Wp,-MD,$(depfile).pre.tmp -nostdinc                    \
>                  -I$(srctree)/arch/$(SRCARCH)/boot/dts                   \
>                  -I$(srctree)/arch/$(SRCARCH)/boot/dts/include           \
>                  -I$(srctree)/drivers/of/testcase-data                   \
> +                -I$(srctree)/kernel/dts                                 \
>                  -undef -D__DTS__
>
>  # Finds the multi-part object the current object will be linked into
> @@ -285,7 +286,7 @@ quiet_cmd_dtc = DTC     $@
>  cmd_dtc = mkdir -p $(dir ${dtc-tmp}) ; \
>         $(CPP) $(dtc_cpp_flags) -x assembler-with-cpp -o $(dtc-tmp) $< ; \
>         $(objtree)/scripts/dtc/dtc -O dtb -o $@ -b 0 \
> -               -i $(dir $<) $(DTC_FLAGS) \
> +               -i $(dir $<) -i $(srctree)/kernel/dts $(DTC_FLAGS) \
>                 -d $(depfile).dtc.tmp $(dtc-tmp) ; \
>         cat $(depfile).pre.tmp $(depfile).dtc.tmp > $(depfile)
>
> --
> 2.1.4
>


From b.zolnierkie at samsung.com  Mon Aug  3 08:57:36 2015
From: b.zolnierkie at samsung.com (Bartlomiej Zolnierkiewicz)
Date: Mon, 03 Aug 2015 17:57:36 +0200
Subject: [PATCH v3 3/5] ARM: Exynos: switch to using generic cpufreq driver
 for Exynos4x12
In-Reply-To: <20150803155041.GE21529@linux>
References: <1438368557-2352-1-git-send-email-b.zolnierkie@samsung.com>
 <2347616.SxxJmTVssu@amdc1976> <20150803155041.GE21529@linux>
Message-ID: <1560319.pWyQuLxb1l@amdc1976>

On Monday, August 03, 2015 09:20:41 PM Viresh Kumar wrote:
> On 03-08-15, 15:55, Bartlomiej Zolnierkiewicz wrote:
> > diff --git a/arch/arm/mach-exynos/Kconfig b/arch/arm/mach-exynos/Kconfig
> > index 81064cd..491914c 100644
> > --- a/arch/arm/mach-exynos/Kconfig
> > +++ b/arch/arm/mach-exynos/Kconfig
> > @@ -25,6 +25,8 @@ menuconfig ARCH_EXYNOS
> >  	select S5P_DEV_MFC
> >  	select SRAM
> >  	select MFD_SYSCON
> > +	select THERMAL
> > +	select EXYNOS_THERMAL
> 
> Why do you need to select both of them?

Because otherwise you can disable the whole THERMAL subsystem support
(effectively disabling EXYNOS_THERMAL in the process).

This is the same way in which ARCH_EXYNOS handles PINCTRL_EXYNOS
support currently (it also selects PINCTRL subsystem).

> >  	help
> >  	  Support for SAMSUNG EXYNOS SoCs (EXYNOS4/5)
> >  
> > diff --git a/arch/arm/mach-exynos/exynos.c b/arch/arm/mach-exynos/exynos.c
> > index 77ac021..1c47aee 100644
> > --- a/arch/arm/mach-exynos/exynos.c
> > +++ b/arch/arm/mach-exynos/exynos.c
> > @@ -227,6 +227,8 @@ static void __init exynos_init_irq(void)
> >  static const struct of_device_id exynos_cpufreq_matches[] = {
> >  	{ .compatible = "samsung,exynos3250", .data = "cpufreq-dt" },
> >  	{ .compatible = "samsung,exynos4210", .data = "cpufreq-dt" },
> > +	{ .compatible = "samsung,exynos4212", .data = "cpufreq-dt" },
> > +	{ .compatible = "samsung,exynos4412", .data = "cpufreq-dt" },
> >  	{ .compatible = "samsung,exynos5250", .data = "cpufreq-dt" },
> >  	{ /* sentinel */ }
> >  };
> 
> Otherwise looks fine:
> 
> Acked-by: Viresh Kumar <viresh.kumar at linaro.org>

Thanks!

Best regards,
--
Bartlomiej Zolnierkiewicz
Samsung R&D Institute Poland
Samsung Electronics



From ian.campbell at citrix.com  Mon Aug  3 09:03:59 2015
From: ian.campbell at citrix.com (Ian Campbell)
Date: Mon, 3 Aug 2015 17:03:59 +0100
Subject: [PATCH v4] dtb: Create a common home for cross-architecture
 dtsi files.
In-Reply-To: <CAL_JsqLU_CMaYN=FpVdeenVYgvBNDUQsqvi=uwuENOk=pt0WZQ@mail.gmail.com>
References: <1438592111-8471-1-git-send-email-ian.campbell@citrix.com>
 <CAL_JsqLU_CMaYN=FpVdeenVYgvBNDUQsqvi=uwuENOk=pt0WZQ@mail.gmail.com>
Message-ID: <1438617839.31129.30.camel@citrix.com>

On Mon, 2015-08-03 at 10:55 -0500, Rob Herring wrote:
> On Mon, Aug 3, 2015 at 3:55 AM, Ian Campbell <ian.campbell at citrix.com> 
> wrote:
> > Commit 9ccd608070b6 ("arm64: dts: add device tree for ARM SMM-A53x2 on
> > LogicTile Express 20MG") added a new dts file to arch/arm64 which
> > included "../../../../arm/boot/dts/vexpress-v2m-rs1.dtsi", i.e. a
> > .dtsi supplied by arch/arm.
> > 
> > Unfortunately this causes some issues for the split device tree
> > repository[0], since things get moved around there. In that context
> > the new .dts ends up at src/arm64/arm/vexpress-v2f-1xv7-ca53x2.dts
> > while the include is at src/arm/vexpress-v2m-rs1.dtsi.
> > 
> > The sharing of the .dtsi is legitimate since the baseboard is the same
> > for various vexpress systems whatever processor they use.
> > 
> > Rather than using ../../ tricks to pickup .dtsi files from another
> > arch this patch creates a new directory kernel/dts as a home for such
> > cross-arch .dtsi files, arranges for it to be in the include path when
> > the .dts files are processed by cpp and switches the .dts files to use
> > cpp #include instead of /include/. The dtsi file itself is moved into
> > a vendor subdir in this case "arm" (the vendor, not the ARCH=).
> 
> Sigh, it was not the include path I was referring to being wrong
> although that was too. It was the part about using #include instead of
> /include/.

Damn, how did I miss that!

v5 coming up, sorry :-/



From ian.campbell at citrix.com  Mon Aug  3 09:06:33 2015
From: ian.campbell at citrix.com (Ian Campbell)
Date: Mon, 3 Aug 2015 17:06:33 +0100
Subject: [PATCH v4] dtb: Create a common home for cross-architecture dtsi
 files.
Message-ID: <1438617993-1012-1-git-send-email-ian.campbell@citrix.com>

Commit 9ccd608070b6 ("arm64: dts: add device tree for ARM SMM-A53x2 on
LogicTile Express 20MG") added a new dts file to arch/arm64 which
included "../../../../arm/boot/dts/vexpress-v2m-rs1.dtsi", i.e. a
.dtsi supplied by arch/arm.

Unfortunately this causes some issues for the split device tree
repository[0], since things get moved around there. In that context
the new .dts ends up at src/arm64/arm/vexpress-v2f-1xv7-ca53x2.dts
while the include is at src/arm/vexpress-v2m-rs1.dtsi.

The sharing of the .dtsi is legitimate since the baseboard is the same
for various vexpress systems whatever processor they use.

Rather than using ../../ tricks to pickup .dtsi files from another
arch this patch creates a new directory kernel/dts as a home for such
cross-arch .dtsi files and arranges for it to be in the include path
for both dtc and cpp. The dtsi file itself is moved into a vendor
subdir in this case "arm" (the vendor, not the ARCH=).

[0] https://git.kernel.org/cgit/linux/kernel/git/devicetree/devicetree-rebasing.git/

Signed-off-by: Ian Campbell <ian.campbell at citrix.com>
Cc: Rob Herring <robh+dt at kernel.org>
Cc: Pawel Moll <pawel.moll at arm.com>
Cc: Mark Rutland <mark.rutland at arm.com>
Cc: Kumar Gala <galak at codeaurora.org>
Cc: Liviu Dudau <liviu.dudau at arm.com>
Cc: Sudeep Holla <sudeep.holla at arm.com>
Cc: Lorenzo Pieralisi <lorenzo.pieralisi at arm.com>
Cc: Russell King <linux at arm.linux.org.uk>
Cc: Catalin Marinas <catalin.marinas at arm.com>
Cc: Will Deacon <will.deacon at arm.com>
Cc: Kristina Martsenko <kristina.martsenko at arm.com>
Cc: Kevin Hilman <khilman at linaro.org>
Cc: devicetree at vger.kernel.org
Cc: linux-kernel at vger.kernel.org
Cc: linux-arm-kernel at lists.infradead.org
Cc: linux-kbuild at vger.kernel.org
Acked-by: Mark Rutland <mark.rutland at arm.com>
Acked-by: Rob Herring <robh at kernel.org>
Acked-by: Liviu Dudau <Liviu.Dudau at arm.com>
Reviewed-by: Masahiro Yamada <yamada.masahiro at socionext.com>
---
v2: Move to include/dt-dtsi and introduce a per-vendor subdirectory.

v3: Move to kernel/dts.
    Include new directory in DTC include path as well as cpp path, and
    therefore switch back to /include/.
    Update MAINTAINERS

v4: Change path in changelog too.
    Add ()s to title of 9ccd608070b6.

v5: Remove stale reference to switching from /include/ to #include.
---
 Documentation/devicetree/bindings/arm/vexpress.txt          | 2 +-
 MAINTAINERS                                                 | 1 +
 arch/arm/boot/dts/vexpress-v2p-ca15-tc1.dts                 | 2 +-
 arch/arm/boot/dts/vexpress-v2p-ca15_a7.dts                  | 2 +-
 arch/arm/boot/dts/vexpress-v2p-ca5s.dts                     | 2 +-
 arch/arm64/boot/dts/arm/vexpress-v2f-1xv7-ca53x2.dts        | 2 +-
 {arch/arm/boot/dts => kernel/dts/arm}/vexpress-v2m-rs1.dtsi | 0
 scripts/Makefile.lib                                        | 3 ++-
 8 files changed, 8 insertions(+), 6 deletions(-)
 rename {arch/arm/boot/dts => kernel/dts/arm}/vexpress-v2m-rs1.dtsi (100%)

diff --git a/Documentation/devicetree/bindings/arm/vexpress.txt b/Documentation/devicetree/bindings/arm/vexpress.txt
index 39844cd..b6031d9 100644
--- a/Documentation/devicetree/bindings/arm/vexpress.txt
+++ b/Documentation/devicetree/bindings/arm/vexpress.txt
@@ -223,7 +223,7 @@ Example of a VE tile description (simplified)
 		/* Active high IRQ 0 is connected to GIC's SPI0 */
 		interrupt-map = <0 0 0 &gic 0 0 4>;
 
-		/include/ "vexpress-v2m-rs1.dtsi"
+		/include/ "arm/vexpress-v2m-rs1.dtsi"
 	};
 };
 
diff --git a/MAINTAINERS b/MAINTAINERS
index a226416..1941078 100644
--- a/MAINTAINERS
+++ b/MAINTAINERS
@@ -7537,6 +7537,7 @@ S:	Maintained
 F:	Documentation/devicetree/
 F:	arch/*/boot/dts/
 F:	include/dt-bindings/
+F:	kernel/dts/
 
 OPEN FIRMWARE AND DEVICE TREE OVERLAYS
 M:	Pantelis Antoniou <pantelis.antoniou at konsulko.com>
diff --git a/arch/arm/boot/dts/vexpress-v2p-ca15-tc1.dts b/arch/arm/boot/dts/vexpress-v2p-ca15-tc1.dts
index 9420053..b144092 100644
--- a/arch/arm/boot/dts/vexpress-v2p-ca15-tc1.dts
+++ b/arch/arm/boot/dts/vexpress-v2p-ca15-tc1.dts
@@ -278,6 +278,6 @@
 				<0 0 41 &gic 0 41 4>,
 				<0 0 42 &gic 0 42 4>;
 
-		/include/ "vexpress-v2m-rs1.dtsi"
+		/include/ "arm/vexpress-v2m-rs1.dtsi"
 	};
 };
diff --git a/arch/arm/boot/dts/vexpress-v2p-ca15_a7.dts b/arch/arm/boot/dts/vexpress-v2p-ca15_a7.dts
index 17f63f7..350f402 100644
--- a/arch/arm/boot/dts/vexpress-v2p-ca15_a7.dts
+++ b/arch/arm/boot/dts/vexpress-v2p-ca15_a7.dts
@@ -636,6 +636,6 @@
 				<0 0 41 &gic 0 41 4>,
 				<0 0 42 &gic 0 42 4>;
 
-		/include/ "vexpress-v2m-rs1.dtsi"
+		/include/ "arm/vexpress-v2m-rs1.dtsi"
 	};
 };
diff --git a/arch/arm/boot/dts/vexpress-v2p-ca5s.dts b/arch/arm/boot/dts/vexpress-v2p-ca5s.dts
index d2709b7..585ced0 100644
--- a/arch/arm/boot/dts/vexpress-v2p-ca5s.dts
+++ b/arch/arm/boot/dts/vexpress-v2p-ca5s.dts
@@ -248,6 +248,6 @@
 				<0 0 41 &gic 0 41 4>,
 				<0 0 42 &gic 0 42 4>;
 
-		/include/ "vexpress-v2m-rs1.dtsi"
+		/include/ "arm/vexpress-v2m-rs1.dtsi"
 	};
 };
diff --git a/arch/arm64/boot/dts/arm/vexpress-v2f-1xv7-ca53x2.dts b/arch/arm64/boot/dts/arm/vexpress-v2f-1xv7-ca53x2.dts
index 5b1d018..c044804 100644
--- a/arch/arm64/boot/dts/arm/vexpress-v2f-1xv7-ca53x2.dts
+++ b/arch/arm64/boot/dts/arm/vexpress-v2f-1xv7-ca53x2.dts
@@ -186,6 +186,6 @@
 				<0 0 41 &gic GIC_SPI 41 IRQ_TYPE_LEVEL_HIGH>,
 				<0 0 42 &gic GIC_SPI 42 IRQ_TYPE_LEVEL_HIGH>;
 
-		/include/ "../../../../arm/boot/dts/vexpress-v2m-rs1.dtsi"
+		/include/ "arm/vexpress-v2m-rs1.dtsi"
 	};
 };
diff --git a/arch/arm/boot/dts/vexpress-v2m-rs1.dtsi b/kernel/dts/arm/vexpress-v2m-rs1.dtsi
similarity index 100%
rename from arch/arm/boot/dts/vexpress-v2m-rs1.dtsi
rename to kernel/dts/arm/vexpress-v2m-rs1.dtsi
diff --git a/scripts/Makefile.lib b/scripts/Makefile.lib
index 79e8661..b4d9fb6 100644
--- a/scripts/Makefile.lib
+++ b/scripts/Makefile.lib
@@ -163,6 +163,7 @@ dtc_cpp_flags  = -Wp,-MD,$(depfile).pre.tmp -nostdinc                    \
 		 -I$(srctree)/arch/$(SRCARCH)/boot/dts                   \
 		 -I$(srctree)/arch/$(SRCARCH)/boot/dts/include           \
 		 -I$(srctree)/drivers/of/testcase-data                   \
+		 -I$(srctree)/kernel/dts                                 \
 		 -undef -D__DTS__
 
 # Finds the multi-part object the current object will be linked into
@@ -285,7 +286,7 @@ quiet_cmd_dtc = DTC     $@
 cmd_dtc = mkdir -p $(dir ${dtc-tmp}) ; \
 	$(CPP) $(dtc_cpp_flags) -x assembler-with-cpp -o $(dtc-tmp) $< ; \
 	$(objtree)/scripts/dtc/dtc -O dtb -o $@ -b 0 \
-		-i $(dir $<) $(DTC_FLAGS) \
+		-i $(dir $<) -i $(srctree)/kernel/dts $(DTC_FLAGS) \
 		-d $(depfile).dtc.tmp $(dtc-tmp) ; \
 	cat $(depfile).pre.tmp $(depfile).dtc.tmp > $(depfile)
 
-- 
2.1.4



From ian.campbell at citrix.com  Mon Aug  3 09:06:40 2015
From: ian.campbell at citrix.com (Ian Campbell)
Date: Mon, 3 Aug 2015 17:06:40 +0100
Subject: [PATCH v5] dtb: Create a common home for cross-architecture dtsi
 files.
Message-ID: <1438618000-1091-1-git-send-email-ian.campbell@citrix.com>

Commit 9ccd608070b6 ("arm64: dts: add device tree for ARM SMM-A53x2 on
LogicTile Express 20MG") added a new dts file to arch/arm64 which
included "../../../../arm/boot/dts/vexpress-v2m-rs1.dtsi", i.e. a
.dtsi supplied by arch/arm.

Unfortunately this causes some issues for the split device tree
repository[0], since things get moved around there. In that context
the new .dts ends up at src/arm64/arm/vexpress-v2f-1xv7-ca53x2.dts
while the include is at src/arm/vexpress-v2m-rs1.dtsi.

The sharing of the .dtsi is legitimate since the baseboard is the same
for various vexpress systems whatever processor they use.

Rather than using ../../ tricks to pickup .dtsi files from another
arch this patch creates a new directory kernel/dts as a home for such
cross-arch .dtsi files and arranges for it to be in the include path
for both dtc and cpp. The dtsi file itself is moved into a vendor
subdir in this case "arm" (the vendor, not the ARCH=).

[0] https://git.kernel.org/cgit/linux/kernel/git/devicetree/devicetree-rebasing.git/

Signed-off-by: Ian Campbell <ian.campbell at citrix.com>
Cc: Rob Herring <robh+dt at kernel.org>
Cc: Pawel Moll <pawel.moll at arm.com>
Cc: Mark Rutland <mark.rutland at arm.com>
Cc: Kumar Gala <galak at codeaurora.org>
Cc: Liviu Dudau <liviu.dudau at arm.com>
Cc: Sudeep Holla <sudeep.holla at arm.com>
Cc: Lorenzo Pieralisi <lorenzo.pieralisi at arm.com>
Cc: Russell King <linux at arm.linux.org.uk>
Cc: Catalin Marinas <catalin.marinas at arm.com>
Cc: Will Deacon <will.deacon at arm.com>
Cc: Kristina Martsenko <kristina.martsenko at arm.com>
Cc: Kevin Hilman <khilman at linaro.org>
Cc: devicetree at vger.kernel.org
Cc: linux-kernel at vger.kernel.org
Cc: linux-arm-kernel at lists.infradead.org
Cc: linux-kbuild at vger.kernel.org
Acked-by: Mark Rutland <mark.rutland at arm.com>
Acked-by: Rob Herring <robh at kernel.org>
Acked-by: Liviu Dudau <Liviu.Dudau at arm.com>
Reviewed-by: Masahiro Yamada <yamada.masahiro at socionext.com>
---
v2: Move to include/dt-dtsi and introduce a per-vendor subdirectory.

v3: Move to kernel/dts.
    Include new directory in DTC include path as well as cpp path, and
    therefore switch back to /include/.
    Update MAINTAINERS

v4: Change path in changelog too.
    Add ()s to title of 9ccd608070b6.

v5: Remove stale reference to switching from /include/ to #include.
---
 Documentation/devicetree/bindings/arm/vexpress.txt          | 2 +-
 MAINTAINERS                                                 | 1 +
 arch/arm/boot/dts/vexpress-v2p-ca15-tc1.dts                 | 2 +-
 arch/arm/boot/dts/vexpress-v2p-ca15_a7.dts                  | 2 +-
 arch/arm/boot/dts/vexpress-v2p-ca5s.dts                     | 2 +-
 arch/arm64/boot/dts/arm/vexpress-v2f-1xv7-ca53x2.dts        | 2 +-
 {arch/arm/boot/dts => kernel/dts/arm}/vexpress-v2m-rs1.dtsi | 0
 scripts/Makefile.lib                                        | 3 ++-
 8 files changed, 8 insertions(+), 6 deletions(-)
 rename {arch/arm/boot/dts => kernel/dts/arm}/vexpress-v2m-rs1.dtsi (100%)

diff --git a/Documentation/devicetree/bindings/arm/vexpress.txt b/Documentation/devicetree/bindings/arm/vexpress.txt
index 39844cd..b6031d9 100644
--- a/Documentation/devicetree/bindings/arm/vexpress.txt
+++ b/Documentation/devicetree/bindings/arm/vexpress.txt
@@ -223,7 +223,7 @@ Example of a VE tile description (simplified)
 		/* Active high IRQ 0 is connected to GIC's SPI0 */
 		interrupt-map = <0 0 0 &gic 0 0 4>;
 
-		/include/ "vexpress-v2m-rs1.dtsi"
+		/include/ "arm/vexpress-v2m-rs1.dtsi"
 	};
 };
 
diff --git a/MAINTAINERS b/MAINTAINERS
index a226416..1941078 100644
--- a/MAINTAINERS
+++ b/MAINTAINERS
@@ -7537,6 +7537,7 @@ S:	Maintained
 F:	Documentation/devicetree/
 F:	arch/*/boot/dts/
 F:	include/dt-bindings/
+F:	kernel/dts/
 
 OPEN FIRMWARE AND DEVICE TREE OVERLAYS
 M:	Pantelis Antoniou <pantelis.antoniou at konsulko.com>
diff --git a/arch/arm/boot/dts/vexpress-v2p-ca15-tc1.dts b/arch/arm/boot/dts/vexpress-v2p-ca15-tc1.dts
index 9420053..b144092 100644
--- a/arch/arm/boot/dts/vexpress-v2p-ca15-tc1.dts
+++ b/arch/arm/boot/dts/vexpress-v2p-ca15-tc1.dts
@@ -278,6 +278,6 @@
 				<0 0 41 &gic 0 41 4>,
 				<0 0 42 &gic 0 42 4>;
 
-		/include/ "vexpress-v2m-rs1.dtsi"
+		/include/ "arm/vexpress-v2m-rs1.dtsi"
 	};
 };
diff --git a/arch/arm/boot/dts/vexpress-v2p-ca15_a7.dts b/arch/arm/boot/dts/vexpress-v2p-ca15_a7.dts
index 17f63f7..350f402 100644
--- a/arch/arm/boot/dts/vexpress-v2p-ca15_a7.dts
+++ b/arch/arm/boot/dts/vexpress-v2p-ca15_a7.dts
@@ -636,6 +636,6 @@
 				<0 0 41 &gic 0 41 4>,
 				<0 0 42 &gic 0 42 4>;
 
-		/include/ "vexpress-v2m-rs1.dtsi"
+		/include/ "arm/vexpress-v2m-rs1.dtsi"
 	};
 };
diff --git a/arch/arm/boot/dts/vexpress-v2p-ca5s.dts b/arch/arm/boot/dts/vexpress-v2p-ca5s.dts
index d2709b7..585ced0 100644
--- a/arch/arm/boot/dts/vexpress-v2p-ca5s.dts
+++ b/arch/arm/boot/dts/vexpress-v2p-ca5s.dts
@@ -248,6 +248,6 @@
 				<0 0 41 &gic 0 41 4>,
 				<0 0 42 &gic 0 42 4>;
 
-		/include/ "vexpress-v2m-rs1.dtsi"
+		/include/ "arm/vexpress-v2m-rs1.dtsi"
 	};
 };
diff --git a/arch/arm64/boot/dts/arm/vexpress-v2f-1xv7-ca53x2.dts b/arch/arm64/boot/dts/arm/vexpress-v2f-1xv7-ca53x2.dts
index 5b1d018..c044804 100644
--- a/arch/arm64/boot/dts/arm/vexpress-v2f-1xv7-ca53x2.dts
+++ b/arch/arm64/boot/dts/arm/vexpress-v2f-1xv7-ca53x2.dts
@@ -186,6 +186,6 @@
 				<0 0 41 &gic GIC_SPI 41 IRQ_TYPE_LEVEL_HIGH>,
 				<0 0 42 &gic GIC_SPI 42 IRQ_TYPE_LEVEL_HIGH>;
 
-		/include/ "../../../../arm/boot/dts/vexpress-v2m-rs1.dtsi"
+		/include/ "arm/vexpress-v2m-rs1.dtsi"
 	};
 };
diff --git a/arch/arm/boot/dts/vexpress-v2m-rs1.dtsi b/kernel/dts/arm/vexpress-v2m-rs1.dtsi
similarity index 100%
rename from arch/arm/boot/dts/vexpress-v2m-rs1.dtsi
rename to kernel/dts/arm/vexpress-v2m-rs1.dtsi
diff --git a/scripts/Makefile.lib b/scripts/Makefile.lib
index 79e8661..b4d9fb6 100644
--- a/scripts/Makefile.lib
+++ b/scripts/Makefile.lib
@@ -163,6 +163,7 @@ dtc_cpp_flags  = -Wp,-MD,$(depfile).pre.tmp -nostdinc                    \
 		 -I$(srctree)/arch/$(SRCARCH)/boot/dts                   \
 		 -I$(srctree)/arch/$(SRCARCH)/boot/dts/include           \
 		 -I$(srctree)/drivers/of/testcase-data                   \
+		 -I$(srctree)/kernel/dts                                 \
 		 -undef -D__DTS__
 
 # Finds the multi-part object the current object will be linked into
@@ -285,7 +286,7 @@ quiet_cmd_dtc = DTC     $@
 cmd_dtc = mkdir -p $(dir ${dtc-tmp}) ; \
 	$(CPP) $(dtc_cpp_flags) -x assembler-with-cpp -o $(dtc-tmp) $< ; \
 	$(objtree)/scripts/dtc/dtc -O dtb -o $@ -b 0 \
-		-i $(dir $<) $(DTC_FLAGS) \
+		-i $(dir $<) -i $(srctree)/kernel/dts $(DTC_FLAGS) \
 		-d $(depfile).dtc.tmp $(dtc-tmp) ; \
 	cat $(depfile).pre.tmp $(depfile).dtc.tmp > $(depfile)
 
-- 
2.1.4



From broonie at kernel.org  Mon Aug  3 09:08:29 2015
From: broonie at kernel.org (Mark Brown)
Date: Mon, 3 Aug 2015 17:08:29 +0100
Subject: [LINUX RFC 1/2] mtd: spi-nor: add dual parallel mode support
In-Reply-To: <1438592707-30713-2-git-send-email-ranjit.waghmode@xilinx.com>
References: <1438592707-30713-1-git-send-email-ranjit.waghmode@xilinx.com>
 <1438592707-30713-2-git-send-email-ranjit.waghmode@xilinx.com>
Message-ID: <20150803160829.GX20873@sirena.org.uk>

On Mon, Aug 03, 2015 at 02:35:06PM +0530, Ranjit Waghmode wrote:

>  drivers/mtd/devices/m25p80.c  |  1 +
>  drivers/mtd/spi-nor/spi-nor.c | 92 ++++++++++++++++++++++++++++++++++---------
>  include/linux/mtd/spi-nor.h   |  3 ++
>  include/linux/spi/spi.h       |  2 +
>  4 files changed, 79 insertions(+), 19 deletions(-)

You need to at least split this into two patches, one adding a new SPI
interface and another using it in MTD.  Probably the MTD core and driver
changes need splitting too.  Please see SubmittingPatches for discussion
of splitting things.

> diff --git a/include/linux/spi/spi.h b/include/linux/spi/spi.h
> index d673072..8dec349 100644
> --- a/include/linux/spi/spi.h
> +++ b/include/linux/spi/spi.h
> @@ -355,6 +355,8 @@ struct spi_master {
>  #define SPI_MASTER_NO_TX	BIT(2)		/* can't do buffer write */
>  #define SPI_MASTER_MUST_RX      BIT(3)		/* requires rx */
>  #define SPI_MASTER_MUST_TX      BIT(4)		/* requires tx */
> +#define SPI_MASTER_DATA_STRIPE		BIT(7)		/* support data stripe */
> +#define SPI_MASTER_BOTH_CS		BIT(8)		/* enable both chips */

This is really not adequate description for a new API, I can't tell what
"data stripe" is supposed to mean at all and I've got at best a vague
idea what "both chips" really means.  This means other developers won't
be able to tell how to use or implement these flags either, and it means
I can't really review this.  You need to provide more information here,
both in the code and in the commit message.

I'd also expect some handling in the core for these, for example error
handling if they can't be supported.
-------------- next part --------------
A non-text attachment was scrubbed...
Name: signature.asc
Type: application/pgp-signature
Size: 473 bytes
Desc: Digital signature
URL: <http://lists.infradead.org/pipermail/linux-arm-kernel/attachments/20150803/e21281f6/attachment.sig>

From gregkh at linuxfoundation.org  Mon Aug  3 09:26:23 2015
From: gregkh at linuxfoundation.org (Greg Kroah-Hartman)
Date: Mon, 3 Aug 2015 09:26:23 -0700
Subject: [PATCH 0/2] drivers: PL061: Add platform driver probing support
In-Reply-To: <20150803094923.GI7557@n2100.arm.linux.org.uk>
References: <1438585198-8764-1-git-send-email-zhaoshenglong@huawei.com>
 <20150803075848.GH7557@n2100.arm.linux.org.uk>
 <55BF33AD.5040502@huawei.com>
 <20150803094923.GI7557@n2100.arm.linux.org.uk>
Message-ID: <20150803162623.GB30867@kroah.com>

On Mon, Aug 03, 2015 at 10:49:23AM +0100, Russell King - ARM Linux wrote:
> On Mon, Aug 03, 2015 at 05:26:05PM +0800, Shannon Zhao wrote:
> > Hi Russell,
> > 
> > On 2015/8/3 15:58, Russell King - ARM Linux wrote:
> > > On Mon, Aug 03, 2015 at 02:59:56PM +0800, Shannon Zhao wrote:
> > >> From: Shannon Zhao <shannon.zhao at linaro.org>
> > >>
> > >> According to ACPI SPEC, it supports ARM boards to use "GPIO-signaled
> > >> ACPI Events". These events can be used for input events. And to QEMU, it
> > >> uses GPIO PL061 controller for input events.
> > >>
> > >> These two patches add platform driver support for PL061 probed by DT or
> > >> ACPI.
> > > 
> > > This certainly is incorrect for DT, and is probably wrong for ACPI too.
> > > DT creates amba devices, so binds via the amba device driver.
> > > 
> > 
> > Oh, sorry. The changes for DT are not necessary. But for ACPI I think it
> > needs to convert pl061 to platform device since ACPI doesn't support
> > AMBA devices. The Pl011 also does the same thing to support ACPI
> > probing. See drivers/tty/serial/amba-pl011.c
> 
> Maybe rather than having every AMBA driver also converted to a platform
> driver (which GregKH hates) maybe ACPI should support the AMBA bus
> instead?
> 
> Greg?

The ACPI developers have been doing work to allow a driver to handle
getting the resources from either DT or ACPI no matter what bus it is
on, so converting anything to a platform driver shouldn't be needed.

but I don't really know the details here, and this isn't being sent to
the ACPI mailing list, so I don't know what to suggest...

greg k-h


From jungseoklee85 at gmail.com  Mon Aug  3 09:30:50 2015
From: jungseoklee85 at gmail.com (Jungseok Lee)
Date: Tue, 4 Aug 2015 01:30:50 +0900
Subject: [RFC 2/3] arm64: refactor save_stack_trace()
In-Reply-To: <20150803090951.GA10501@arm.com>
References: <12F47692-3010-4886-B87D-3D7820609177@gmail.com>
 <20150716113115.45a17f17@gandalf.local.home>
 <20150716121658.7982fdf5@gandalf.local.home>
 <20150717124054.GE26091@leverpostej>
 <20150717090009.720f6bd0@gandalf.local.home>
 <77EA0F10-D5F6-48BD-8652-3B979A978659@gmail.com>
 <20150717104144.6588b2f7@gandalf.local.home>
 <0886A996-40E1-49E9-823C-85E55A858716@gmail.com>
 <1357EA74-B972-4B99-ADB0-BC7E8F06DDB5@gmail.com>
 <20150720162004.GL9908@arm.com> <20150803090951.GA10501@arm.com>
Message-ID: <D7BD8A9F-8710-42D5-A0ED-8747D2B6B268@gmail.com>

On Aug 3, 2015, at 6:09 PM, Will Deacon wrote:
> Hi guys,

Hi Will,

> On Mon, Jul 20, 2015 at 05:20:04PM +0100, Will Deacon wrote:
>> On Fri, Jul 17, 2015 at 04:34:21PM +0100, Jungseok Lee wrote:
>>> On Jul 17, 2015, at 11:59 PM, Jungseok Lee wrote:
>>>> On Jul 17, 2015, at 11:41 PM, Steven Rostedt wrote:
>>>>> Thanks! Can you repost patch 1 with the changes I recommended, so that
>>>>> I can get an Acked-by from the arm64 maintainers and pull all the
>>>>> changes in together. This is fine for a 4.3 release, right? That is, it
>>>>> doesn't need to go into 4.2-rcs.
>>>>> 
>>>> 
>>>> It's not hard to repost a patch, but I feel like we have to wait for Akashi's response.
>>>> Also, it might be needed to consider Mark's comment on arch part.
>>>> 
>>>> If they are okay, I will proceed.
>>> 
>>> The [RFC 1/3] patch used in my environment is shaped as follows.
>>> I leave the hunk for *only* clear synchronization. This is why I choose this format
>>> instead of reposting a patch. I hope it would help to track down this thread.
>>> 
>>> I think this is my best at this point.
> 
> [...]
> 
>> The arm64 bits look fine to me:
>> 
>>  Acked-by: Will Deacon <will.deacon at arm.com>
> 
> What happened to this? Is it queued someplace, or are we waiting for a
> new version?

There are two issues in the current version.
1) The change does not work correctly when function_graph feature is enabled.
2) Akashi have raised an issue that size field of stack tracer is inaccurate.

So, I think this patch set is not ready yet.

Best Regards
Jungseok Lee

From frowand.list at gmail.com  Mon Aug  3 09:47:42 2015
From: frowand.list at gmail.com (Frank Rowand)
Date: Mon, 03 Aug 2015 09:47:42 -0700
Subject: [PATCH v5] dtb: Create a common home for cross-architecture dtsi
 files.
In-Reply-To: <1438618000-1091-1-git-send-email-ian.campbell@citrix.com>
References: <1438618000-1091-1-git-send-email-ian.campbell@citrix.com>
Message-ID: <55BF9B2E.1060206@gmail.com>

On 8/3/2015 9:06 AM, Ian Campbell wrote:
> Commit 9ccd608070b6 ("arm64: dts: add device tree for ARM SMM-A53x2 on
> LogicTile Express 20MG") added a new dts file to arch/arm64 which
> included "../../../../arm/boot/dts/vexpress-v2m-rs1.dtsi", i.e. a
> .dtsi supplied by arch/arm.
> 
> Unfortunately this causes some issues for the split device tree
> repository[0], since things get moved around there. In that context
> the new .dts ends up at src/arm64/arm/vexpress-v2f-1xv7-ca53x2.dts
> while the include is at src/arm/vexpress-v2m-rs1.dtsi.
> 
> The sharing of the .dtsi is legitimate since the baseboard is the same
> for various vexpress systems whatever processor they use.
> 
> Rather than using ../../ tricks to pickup .dtsi files from another
> arch this patch creates a new directory kernel/dts as a home for such
> cross-arch .dtsi files and arranges for it to be in the include path
> for both dtc and cpp. The dtsi file itself is moved into a vendor
> subdir in this case "arm" (the vendor, not the ARCH=).
> 
> [0] https://git.kernel.org/cgit/linux/kernel/git/devicetree/devicetree-rebasing.git/
> 
> Signed-off-by: Ian Campbell <ian.campbell at citrix.com>
> Cc: Rob Herring <robh+dt at kernel.org>
> Cc: Pawel Moll <pawel.moll at arm.com>
> Cc: Mark Rutland <mark.rutland at arm.com>
> Cc: Kumar Gala <galak at codeaurora.org>
> Cc: Liviu Dudau <liviu.dudau at arm.com>
> Cc: Sudeep Holla <sudeep.holla at arm.com>
> Cc: Lorenzo Pieralisi <lorenzo.pieralisi at arm.com>
> Cc: Russell King <linux at arm.linux.org.uk>
> Cc: Catalin Marinas <catalin.marinas at arm.com>
> Cc: Will Deacon <will.deacon at arm.com>
> Cc: Kristina Martsenko <kristina.martsenko at arm.com>
> Cc: Kevin Hilman <khilman at linaro.org>
> Cc: devicetree at vger.kernel.org
> Cc: linux-kernel at vger.kernel.org
> Cc: linux-arm-kernel at lists.infradead.org
> Cc: linux-kbuild at vger.kernel.org
> Acked-by: Mark Rutland <mark.rutland at arm.com>
> Acked-by: Rob Herring <robh at kernel.org>
> Acked-by: Liviu Dudau <Liviu.Dudau at arm.com>
> Reviewed-by: Masahiro Yamada <yamada.masahiro at socionext.com>
> ---
> v2: Move to include/dt-dtsi and introduce a per-vendor subdirectory.
> 
> v3: Move to kernel/dts.
>     Include new directory in DTC include path as well as cpp path, and
>     therefore switch back to /include/.
>     Update MAINTAINERS
> 
> v4: Change path in changelog too.
>     Add ()s to title of 9ccd608070b6.
> 
> v5: Remove stale reference to switching from /include/ to #include.
> ---
>  Documentation/devicetree/bindings/arm/vexpress.txt          | 2 +-
>  MAINTAINERS                                                 | 1 +
>  arch/arm/boot/dts/vexpress-v2p-ca15-tc1.dts                 | 2 +-
>  arch/arm/boot/dts/vexpress-v2p-ca15_a7.dts                  | 2 +-
>  arch/arm/boot/dts/vexpress-v2p-ca5s.dts                     | 2 +-
>  arch/arm64/boot/dts/arm/vexpress-v2f-1xv7-ca53x2.dts        | 2 +-
>  {arch/arm/boot/dts => kernel/dts/arm}/vexpress-v2m-rs1.dtsi | 0
>  scripts/Makefile.lib                                        | 3 ++-
>  8 files changed, 8 insertions(+), 6 deletions(-)
>  rename {arch/arm/boot/dts => kernel/dts/arm}/vexpress-v2m-rs1.dtsi (100%)

Reviewed-by: Frank Rowand <frank.rowand at sonymobile.com>



From rostedt at goodmis.org  Mon Aug  3 09:57:11 2015
From: rostedt at goodmis.org (Steven Rostedt)
Date: Mon, 3 Aug 2015 12:57:11 -0400
Subject: [RFC 2/3] arm64: refactor save_stack_trace()
In-Reply-To: <D7BD8A9F-8710-42D5-A0ED-8747D2B6B268@gmail.com>
References: <12F47692-3010-4886-B87D-3D7820609177@gmail.com>
 <20150716113115.45a17f17@gandalf.local.home>
 <20150716121658.7982fdf5@gandalf.local.home>
 <20150717124054.GE26091@leverpostej>
 <20150717090009.720f6bd0@gandalf.local.home>
 <77EA0F10-D5F6-48BD-8652-3B979A978659@gmail.com>
 <20150717104144.6588b2f7@gandalf.local.home>
 <0886A996-40E1-49E9-823C-85E55A858716@gmail.com>
 <1357EA74-B972-4B99-ADB0-BC7E8F06DDB5@gmail.com>
 <20150720162004.GL9908@arm.com> <20150803090951.GA10501@arm.com>
 <D7BD8A9F-8710-42D5-A0ED-8747D2B6B268@gmail.com>
Message-ID: <20150803125711.65463359@gandalf.local.home>

On Tue, 4 Aug 2015 01:30:50 +0900
Jungseok Lee <jungseoklee85 at gmail.com> wrote:


> There are two issues in the current version.
> 1) The change does not work correctly when function_graph feature is enabled.
> 2) Akashi have raised an issue that size field of stack tracer is inaccurate.
> 
> So, I think this patch set is not ready yet.

Do you still want me to add code that does:

 if (*p == (stack_dump_trace[i] + FTRACE_STACK_FRAME_OFFSET)) {

?

If you expect to need that, I can get it into the next merge window and
you can base the code of that in the merge window after that.

-- Steve


From marc.zyngier at arm.com  Mon Aug  3 10:06:56 2015
From: marc.zyngier at arm.com (Marc Zyngier)
Date: Mon, 03 Aug 2015 18:06:56 +0100
Subject: [PATCH v2 14/15] KVM: arm64: implement MSI injection in ITS
 emulation
In-Reply-To: <55BF8AB8.5050408@linaro.org>
References: <1436538111-4294-1-git-send-email-andre.przywara@arm.com>
 <1436538111-4294-15-git-send-email-andre.przywara@arm.com>
 <55BB7678.5080105@linaro.org> <55BE7BA1.40403@arm.com>
 <00a201d0cdb7$70a623f0$51f26bd0$@samsung.com> <55BF2F51.6020701@linaro.org>
 <00f101d0cdcd$146a6090$3d3f21b0$@samsung.com> <55BF8AB8.5050408@linaro.org>
Message-ID: <55BF9FB0.6070804@arm.com>

On 03/08/15 16:37, Eric Auger wrote:
> Andre, Pavel,
> On 08/03/2015 11:16 AM, Pavel Fedin wrote:
>>  Hello!
>>
>>> Again the case that leaves me uncomfortable is the one where the
>>> userspace does not provide the devid whereas it must (GICv3 ITS case).
>>
>>  Hypothetical broken userland which does not exist for now ?
> Yes but that's the rule to be not confident in *any* userspace, isn't it?
> 
> As of now I prefer keeping the flags at uapi level and propagate it
> downto the kernel, as long as I don't have any answer for the unset
> devid discrimination question. Please apologize for my stubbornness ;-)

I think this flag should be kept, as it really indicates what is valid
in the MSI structure. It also has other benefits such as making obvious
what userspace expects, which can then be checked against the kernel's
own expectations.

Thanks,

	M.
-- 
Jazz is not dead. It just smells funny...


From srinivas.pandruvada at intel.com  Mon Aug  3 10:12:03 2015
From: srinivas.pandruvada at intel.com (Pandruvada, Srinivas)
Date: Mon, 3 Aug 2015 17:12:03 +0000
Subject: [PATCH v3 5/5] cpufreq: remove no longer needed
 CPU_FREQ_BOOST_SW config option
In-Reply-To: <20150801111537.GH899@linux>
References: <1438368557-2352-1-git-send-email-b.zolnierkie@samsung.com>
 <1438368557-2352-6-git-send-email-b.zolnierkie@samsung.com>
 <20150801111537.GH899@linux>
Message-ID: <1438621775.17718.22.camel@spandruv-DESK3.jf.intel.com>

On Sat, 2015-08-01 at 16:45 +0530, Viresh Kumar wrote:
> On 31-07-15, 20:49, Bartlomiej Zolnierkiewicz wrote:
> > Remove no longer needed CPU_FREQ_BOOST_SW config option.
> > 
> > As a result scaling_boost_freqs sysfs attribute is available
> > when cpufreq-dt driver is used and boost support is enabled.
> > 
> > Cc: Viresh Kumar <viresh.kumar at linaro.org>
> > Cc: Thomas Abraham <thomas.ab at samsung.com>
> > Cc: Javier Martinez Canillas <javier at osg.samsung.com>
> > Cc: Krzysztof Kozlowski <k.kozlowski at samsung.com>
> > Signed-off-by: Bartlomiej Zolnierkiewicz <b.zolnierkie at samsung.com>
> > ---
> >  drivers/cpufreq/Kconfig      | 4 ----
> >  drivers/cpufreq/freq_table.c | 2 --
> >  2 files changed, 6 deletions(-)
> > 
> > diff --git a/drivers/cpufreq/Kconfig b/drivers/cpufreq/Kconfig
> > index bf6d596..de00a52 100644
> > --- a/drivers/cpufreq/Kconfig
> > +++ b/drivers/cpufreq/Kconfig
> > @@ -21,10 +21,6 @@ if CPU_FREQ
> >  config CPU_FREQ_GOV_COMMON
> >  	bool
> >  
> > -config CPU_FREQ_BOOST_SW
> > -	bool
> > -	depends on THERMAL
> > -
> >  config CPU_FREQ_STAT
> >  	tristate "CPU frequency translation statistics"
> >  	default y
> > diff --git a/drivers/cpufreq/freq_table.c b/drivers/cpufreq/freq_table.c
> > index a8f1daf..4c5de5b 100644
> > --- a/drivers/cpufreq/freq_table.c
> > +++ b/drivers/cpufreq/freq_table.c
> > @@ -293,9 +293,7 @@ EXPORT_SYMBOL_GPL(cpufreq_freq_attr_scaling_boost_freqs);
> >  
> >  struct freq_attr *cpufreq_generic_attr[] = {
> >  	&cpufreq_freq_attr_scaling_available_freqs,
> > -#ifdef CONFIG_CPU_FREQ_BOOST_SW
> >  	&cpufreq_freq_attr_scaling_boost_freqs,
> > -#endif
> >  	NULL,
> >  };
> >  EXPORT_SYMBOL_GPL(cpufreq_generic_attr);
> 
> So, this will start appearing for all platforms that use cpufreq_generic_attr
> and that may not be the right thing. We may only want to show boost frequencies
> only if the driver supports it.
I agree. Although acpi-cpufreq or Intel P state driver is not using
generic_attr, but we have a plan to show boost frequencies on platforms,
where we have some control. Support of boost mode doesn't mean that we
can select the boost frequency, so in that case we will avoid showing
them.

Thanks,
Srinivas
> 
> @Rafael: What do you say?
> 


From geert at linux-m68k.org  Mon Aug  3 10:20:47 2015
From: geert at linux-m68k.org (Geert Uytterhoeven)
Date: Mon, 3 Aug 2015 19:20:47 +0200
Subject: [PATCH v3 00/16] ARM: shmobile: Add CPG/MSTP Clock Domain
In-Reply-To: <CAPDyKFp=zoo1OY9K-dYh9e2OV-OFVp36MbXX83vT19uFWB+0Yg@mail.gmail.com>
References: <1435766290-3005-1-git-send-email-geert+renesas@glider.be>
 <CAPDyKFp=zoo1OY9K-dYh9e2OV-OFVp36MbXX83vT19uFWB+0Yg@mail.gmail.com>
Message-ID: <CAMuHMdUxCgXnF6AM=LefR7ZHX0d8XNcn-O=eA7o4C18O4kJbAg@mail.gmail.com>

On Wed, Jul 22, 2015 at 3:00 PM, Ulf Hansson <ulf.hansson at linaro.org> wrote:
> On 1 July 2015 at 17:57, Geert Uytterhoeven <geert+renesas at glider.be> wrote:
>> This patch series adds Clock Domain support to the Clock Pulse Generator
>> (CPG) Module Stop (MSTP) Clocks driver using the generic PM Domain, to
>> be used on shmobile SoCs without device power domains (R-Car Gen1 and
>> Gen2, RZ).  This allows to power-manage the module clocks of SoC devices
>> that are part of the CPG/MSTP Clock Domain using Runtime PM, or for
>> system suspend/resume, similar to SoCs with device power domains
>> (SH-Mobile and R-Mobile).

[...]

> Unless it's too late; for the series - feel free to add:
>
> Reviewed-by: Ulf Hansson <ulf.hansson at linaro.org>

Thank you.

I have to respin anyway, as new nodes have been added to various .dtsi files.

Gr{oetje,eeting}s,

                        Geert

--
Geert Uytterhoeven -- There's lots of Linux beyond ia32 -- geert at linux-m68k.org

In personal conversations with technical people, I call myself a hacker. But
when I'm talking to journalists I just say "programmer" or something like that.
                                -- Linus Torvalds


From ross.zwisler at linux.intel.com  Mon Aug  3 10:21:27 2015
From: ross.zwisler at linux.intel.com (Ross Zwisler)
Date: Mon, 03 Aug 2015 11:21:27 -0600
Subject: [PATCH v3 24/24] pmem: convert to generic memremap
In-Reply-To: <20150730165553.33962.20257.stgit@dwillia2-desk3.amr.corp.intel.com>
References: <20150730165155.33962.64121.stgit@dwillia2-desk3.amr.corp.intel.com>
 <20150730165553.33962.20257.stgit@dwillia2-desk3.amr.corp.intel.com>
Message-ID: <1438622487.9404.2.camel@linux.intel.com>

On Thu, 2015-07-30 at 12:55 -0400, Dan Williams wrote:
> Update memremap_pmem() to query the architecture for the mapping type of
> the given persistent memory range  and then pass those flags to generic
> memremap().  arch_memremap_pmem_flags() is provided an address range to
> evaluate in the event an arch has a need for different mapping types by
> address range.  For example the ACPI NFIT carries EFI mapping types in
> its memory range description table.
> 
> Cc: Ross Zwisler <ross.zwisler at linux.intel.com>
> Signed-off-by: Dan Williams <dan.j.williams at intel.com>
> ---
>  arch/x86/include/asm/io.h |    2 +-
>  arch/x86/mm/ioremap.c     |   16 ++++++++++------
>  include/linux/pmem.h      |   26 +++++++++++++++-----------
>  3 files changed, 26 insertions(+), 18 deletions(-)
> 
> diff --git a/arch/x86/include/asm/io.h b/arch/x86/include/asm/io.h
> index 1a9d44ee9ed0..26c81b01419c 100644
> --- a/arch/x86/include/asm/io.h
> +++ b/arch/x86/include/asm/io.h
> @@ -245,7 +245,7 @@ static inline void flush_write_buffers(void)
>  #endif
>  }
>  
> -void __pmem *arch_memremap_pmem(resource_size_t offset, size_t size);
> +unsigned long arch_memremap_pmem_flags(resource_size_t offset, size_t size);
>  #endif /* __KERNEL__ */
>  
>  extern void native_io_delay(void);
> diff --git a/arch/x86/mm/ioremap.c b/arch/x86/mm/ioremap.c
> index ffbfcf2e701b..5a41e3e4ea1e 100644
> --- a/arch/x86/mm/ioremap.c
> +++ b/arch/x86/mm/ioremap.c
> @@ -205,6 +205,16 @@ err_free_memtype:
>  	return NULL;
>  }
>  
> +unsigned long arch_memremap_pmem_flags(resource_size_t offset, size_t size)
> +{
> +	/*
> +	 * TODO: check the mapping type provided by platform firmware,
> +	 * per range.
> +	 */
> +	return MEMREMAP_WB;
> +}
> +EXPORT_SYMBOL(arch_memremap_pmem_flags);

I'm not sure that the architecture code has the right information to be able
to tell the caller what the correct mapping is.

I think what you are ultimately looking for is the "Address Range Memory
Mapping Attribute" found in the System Physical Address Range Structure of the
NFIT, right?  (ACPI 6.0, table 5-128)  How can we get to that structure from
nfit-independent architecture code like arch_memremap_pmem_flags()?  It seems
like that if we want to make the mapping type dynamic we should get the flags
from ND when the SPA range is provided by ND, and provide a reasonable default
(WB, it seems) when we are dealing with legacy PMEM?  If PMEM had the flag
from whatever source, it could then pass it in to memremap_pmem(), and get a
mapping of the appropriate caching.

Another option of course is to just ignore the mapping attribute in the NFIT
like we've been doing, and just say "we know WB will be good enough", and
remove the TODO.




From eric.auger at linaro.org  Mon Aug  3 10:20:39 2015
From: eric.auger at linaro.org (Eric Auger)
Date: Mon,  3 Aug 2015 19:20:39 +0200
Subject: [PATCH v4 0/5] KVM: irqfd consumer based on IRQ bypass manager
Message-ID: <1438622444-25444-1-git-send-email-eric.auger@linaro.org>

This series transforms irqfd into an IRQ bypass consumer and
introduce the infrastructure shared by Intel posted-interrupts
and ARM forwarded IRQ series.

The bypass manager gets compiled for x86 and arm/arm64 when
KVM is used. A new kvm_irqfd.h header is created to externalize
some irqfd declarations going to be used by architecture specific
code. A new CONFIG_HAVE_KVM_IRQ_BYPASS option is introduced
to enable architecture specific IRQ manager hooks.

the series depends on the IRQ bypass manager:
- [PATCH v2] virt: IRQ bypass manager
  (https://lkml.org/lkml/2015/7/16/810)

can be found at:
https://git.linaro.org/people/eric.auger/linux.git/shortlog/refs/heads/v4.2-rc5-irqfd-consumer-v4

Best Regards

Eric

History:

v3 -> v4:
- fix compilation for arm/arm64
- rearrange signoffs/history on some patch files

v2 -> v3 (Feng Wu):
- rebase on IRQ bypass manager [PATCH v2] virt: IRQ bypass manager:
  https://lkml.org/lkml/2015/7/16/810
- Correct some minor errors and typo
- Add something needed for posted-interrupts

v1 -> v2:
- isolate the bypass manager and irqfd consumer in this series
- take into account Paolo's comments and use container_of strategy and
  remove additional fields introduced in v1.
- create kvm_irqfd.h
- add unregistration in irqfd_shutdown

v1: originally part of [RFC 00/17] ARM IRQ forward control based on IRQ
    bypass manager (https://lkml.org/lkml/2015/7/2/268)


Eric Auger (4):
  KVM: arm/arm64: select IRQ_BYPASS_MANAGER
  KVM: create kvm_irqfd.h
  KVM: introduce kvm_arch functions for IRQ bypass
  KVM: eventfd: add irq bypass consumer management

Feng Wu (1):
  KVM: x86: select IRQ_BYPASS_MANAGER

 arch/arm/kvm/Kconfig      |   2 +
 arch/arm/kvm/Makefile     |   1 +
 arch/arm64/kvm/Kconfig    |   2 +
 arch/arm64/kvm/Makefile   |   1 +
 arch/x86/kvm/Kconfig      |   2 +
 arch/x86/kvm/Makefile     |   3 ++
 include/linux/kvm_host.h  |  33 +++++++++++++++
 include/linux/kvm_irqfd.h |  71 +++++++++++++++++++++++++++++++
 virt/kvm/Kconfig          |   3 ++
 virt/kvm/eventfd.c        | 105 +++++++++++++++-------------------------------
 10 files changed, 151 insertions(+), 72 deletions(-)
 create mode 100644 include/linux/kvm_irqfd.h

-- 
1.9.1



From eric.auger at linaro.org  Mon Aug  3 10:20:40 2015
From: eric.auger at linaro.org (Eric Auger)
Date: Mon,  3 Aug 2015 19:20:40 +0200
Subject: [PATCH v4 1/5] KVM: x86: select IRQ_BYPASS_MANAGER
In-Reply-To: <1438622444-25444-1-git-send-email-eric.auger@linaro.org>
References: <1438622444-25444-1-git-send-email-eric.auger@linaro.org>
Message-ID: <1438622444-25444-2-git-send-email-eric.auger@linaro.org>

From: Feng Wu <feng.wu at intel.com>

Select IRQ_BYPASS_MANAGER for x86 when CONFIG_KVM is set

Signed-off-by: Feng Wu <feng.wu at intel.com>
---
 arch/x86/kvm/Kconfig  | 2 ++
 arch/x86/kvm/Makefile | 3 +++
 2 files changed, 5 insertions(+)

diff --git a/arch/x86/kvm/Kconfig b/arch/x86/kvm/Kconfig
index d8a1d56..c951d44 100644
--- a/arch/x86/kvm/Kconfig
+++ b/arch/x86/kvm/Kconfig
@@ -3,6 +3,7 @@
 #
 
 source "virt/kvm/Kconfig"
+source "virt/lib/Kconfig"
 
 menuconfig VIRTUALIZATION
 	bool "Virtualization"
@@ -28,6 +29,7 @@ config KVM
 	select ANON_INODES
 	select HAVE_KVM_IRQCHIP
 	select HAVE_KVM_IRQFD
+	select IRQ_BYPASS_MANAGER
 	select HAVE_KVM_IRQ_ROUTING
 	select HAVE_KVM_EVENTFD
 	select KVM_APIC_ARCHITECTURE
diff --git a/arch/x86/kvm/Makefile b/arch/x86/kvm/Makefile
index 67d215c..05cc2d7 100644
--- a/arch/x86/kvm/Makefile
+++ b/arch/x86/kvm/Makefile
@@ -6,6 +6,9 @@ CFLAGS_svm.o := -I.
 CFLAGS_vmx.o := -I.
 
 KVM := ../../../virt/kvm
+LIB := ../../../virt/lib
+
+obj-$(CONFIG_IRQ_BYPASS_MANAGER)	+= $(LIB)/
 
 kvm-y			+= $(KVM)/kvm_main.o $(KVM)/coalesced_mmio.o \
 				$(KVM)/eventfd.o $(KVM)/irqchip.o $(KVM)/vfio.o
-- 
1.9.1



From eric.auger at linaro.org  Mon Aug  3 10:20:42 2015
From: eric.auger at linaro.org (Eric Auger)
Date: Mon,  3 Aug 2015 19:20:42 +0200
Subject: [PATCH v4 3/5] KVM: create kvm_irqfd.h
In-Reply-To: <1438622444-25444-1-git-send-email-eric.auger@linaro.org>
References: <1438622444-25444-1-git-send-email-eric.auger@linaro.org>
Message-ID: <1438622444-25444-4-git-send-email-eric.auger@linaro.org>

Move _irqfd_resampler and _irqfd struct declarations in a new
public header: kvm_irqfd.h. They are respectively renamed into
kvm_kernel_irqfd_resampler and kvm_kernel_irqfd. Those datatypes
will be used by architecture specific code, in the context of
IRQ bypass manager integration.

Signed-off-by: Eric Auger <eric.auger at linaro.org>
---
 include/linux/kvm_irqfd.h | 69 ++++++++++++++++++++++++++++++++++
 virt/kvm/eventfd.c        | 95 ++++++++++++-----------------------------------
 2 files changed, 92 insertions(+), 72 deletions(-)
 create mode 100644 include/linux/kvm_irqfd.h

diff --git a/include/linux/kvm_irqfd.h b/include/linux/kvm_irqfd.h
new file mode 100644
index 0000000..f926b39
--- /dev/null
+++ b/include/linux/kvm_irqfd.h
@@ -0,0 +1,69 @@
+/*
+ * 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.
+ *
+ * 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.
+ *
+ * irqfd: Allows an fd to be used to inject an interrupt to the guest
+ * Credit goes to Avi Kivity for the original idea.
+ */
+
+#ifndef __LINUX_KVM_IRQFD_H
+#define __LINUX_KVM_IRQFD_H
+
+#include <linux/kvm_host.h>
+#include <linux/poll.h>
+
+/*
+ * Resampling irqfds are a special variety of irqfds used to emulate
+ * level triggered interrupts.  The interrupt is asserted on eventfd
+ * trigger.  On acknowledgment through the irq ack notifier, the
+ * interrupt is de-asserted and userspace is notified through the
+ * resamplefd.  All resamplers on the same gsi are de-asserted
+ * together, so we don't need to track the state of each individual
+ * user.  We can also therefore share the same irq source ID.
+ */
+struct kvm_kernel_irqfd_resampler {
+	struct kvm *kvm;
+	/*
+	 * List of resampling struct _irqfd objects sharing this gsi.
+	 * RCU list modified under kvm->irqfds.resampler_lock
+	 */
+	struct list_head list;
+	struct kvm_irq_ack_notifier notifier;
+	/*
+	 * Entry in list of kvm->irqfd.resampler_list.  Use for sharing
+	 * resamplers among irqfds on the same gsi.
+	 * Accessed and modified under kvm->irqfds.resampler_lock
+	 */
+	struct list_head link;
+};
+
+struct kvm_kernel_irqfd {
+	/* Used for MSI fast-path */
+	struct kvm *kvm;
+	wait_queue_t wait;
+	/* Update side is protected by irqfds.lock */
+	struct kvm_kernel_irq_routing_entry irq_entry;
+	seqcount_t irq_entry_sc;
+	/* Used for level IRQ fast-path */
+	int gsi;
+	struct work_struct inject;
+	/* The resampler used by this irqfd (resampler-only) */
+	struct kvm_kernel_irqfd_resampler *resampler;
+	/* Eventfd notified on resample (resampler-only) */
+	struct eventfd_ctx *resamplefd;
+	/* Entry in list of irqfds for a resampler (resampler-only) */
+	struct list_head resampler_link;
+	/* Used for setup/shutdown */
+	struct eventfd_ctx *eventfd;
+	struct list_head list;
+	poll_table pt;
+	struct work_struct shutdown;
+};
+
+#endif /* __LINUX_KVM_IRQFD_H */
diff --git a/virt/kvm/eventfd.c b/virt/kvm/eventfd.c
index 9ff4193..647ffb8 100644
--- a/virt/kvm/eventfd.c
+++ b/virt/kvm/eventfd.c
@@ -23,6 +23,7 @@
 
 #include <linux/kvm_host.h>
 #include <linux/kvm.h>
+#include <linux/kvm_irqfd.h>
 #include <linux/workqueue.h>
 #include <linux/syscalls.h>
 #include <linux/wait.h>
@@ -39,68 +40,14 @@
 #include <kvm/iodev.h>
 
 #ifdef CONFIG_HAVE_KVM_IRQFD
-/*
- * --------------------------------------------------------------------
- * irqfd: Allows an fd to be used to inject an interrupt to the guest
- *
- * Credit goes to Avi Kivity for the original idea.
- * --------------------------------------------------------------------
- */
-
-/*
- * Resampling irqfds are a special variety of irqfds used to emulate
- * level triggered interrupts.  The interrupt is asserted on eventfd
- * trigger.  On acknowledgement through the irq ack notifier, the
- * interrupt is de-asserted and userspace is notified through the
- * resamplefd.  All resamplers on the same gsi are de-asserted
- * together, so we don't need to track the state of each individual
- * user.  We can also therefore share the same irq source ID.
- */
-struct _irqfd_resampler {
-	struct kvm *kvm;
-	/*
-	 * List of resampling struct _irqfd objects sharing this gsi.
-	 * RCU list modified under kvm->irqfds.resampler_lock
-	 */
-	struct list_head list;
-	struct kvm_irq_ack_notifier notifier;
-	/*
-	 * Entry in list of kvm->irqfd.resampler_list.  Use for sharing
-	 * resamplers among irqfds on the same gsi.
-	 * Accessed and modified under kvm->irqfds.resampler_lock
-	 */
-	struct list_head link;
-};
-
-struct _irqfd {
-	/* Used for MSI fast-path */
-	struct kvm *kvm;
-	wait_queue_t wait;
-	/* Update side is protected by irqfds.lock */
-	struct kvm_kernel_irq_routing_entry irq_entry;
-	seqcount_t irq_entry_sc;
-	/* Used for level IRQ fast-path */
-	int gsi;
-	struct work_struct inject;
-	/* The resampler used by this irqfd (resampler-only) */
-	struct _irqfd_resampler *resampler;
-	/* Eventfd notified on resample (resampler-only) */
-	struct eventfd_ctx *resamplefd;
-	/* Entry in list of irqfds for a resampler (resampler-only) */
-	struct list_head resampler_link;
-	/* Used for setup/shutdown */
-	struct eventfd_ctx *eventfd;
-	struct list_head list;
-	poll_table pt;
-	struct work_struct shutdown;
-};
 
 static struct workqueue_struct *irqfd_cleanup_wq;
 
 static void
 irqfd_inject(struct work_struct *work)
 {
-	struct _irqfd *irqfd = container_of(work, struct _irqfd, inject);
+	struct kvm_kernel_irqfd *irqfd =
+		container_of(work, struct kvm_kernel_irqfd, inject);
 	struct kvm *kvm = irqfd->kvm;
 
 	if (!irqfd->resampler) {
@@ -121,12 +68,13 @@ irqfd_inject(struct work_struct *work)
 static void
 irqfd_resampler_ack(struct kvm_irq_ack_notifier *kian)
 {
-	struct _irqfd_resampler *resampler;
+	struct kvm_kernel_irqfd_resampler *resampler;
 	struct kvm *kvm;
-	struct _irqfd *irqfd;
+	struct kvm_kernel_irqfd *irqfd;
 	int idx;
 
-	resampler = container_of(kian, struct _irqfd_resampler, notifier);
+	resampler = container_of(kian,
+			struct kvm_kernel_irqfd_resampler, notifier);
 	kvm = resampler->kvm;
 
 	kvm_set_irq(kvm, KVM_IRQFD_RESAMPLE_IRQ_SOURCE_ID,
@@ -141,9 +89,9 @@ irqfd_resampler_ack(struct kvm_irq_ack_notifier *kian)
 }
 
 static void
-irqfd_resampler_shutdown(struct _irqfd *irqfd)
+irqfd_resampler_shutdown(struct kvm_kernel_irqfd *irqfd)
 {
-	struct _irqfd_resampler *resampler = irqfd->resampler;
+	struct kvm_kernel_irqfd_resampler *resampler = irqfd->resampler;
 	struct kvm *kvm = resampler->kvm;
 
 	mutex_lock(&kvm->irqfds.resampler_lock);
@@ -168,7 +116,8 @@ irqfd_resampler_shutdown(struct _irqfd *irqfd)
 static void
 irqfd_shutdown(struct work_struct *work)
 {
-	struct _irqfd *irqfd = container_of(work, struct _irqfd, shutdown);
+	struct kvm_kernel_irqfd *irqfd =
+		container_of(work, struct kvm_kernel_irqfd, shutdown);
 	u64 cnt;
 
 	/*
@@ -198,7 +147,7 @@ irqfd_shutdown(struct work_struct *work)
 
 /* assumes kvm->irqfds.lock is held */
 static bool
-irqfd_is_active(struct _irqfd *irqfd)
+irqfd_is_active(struct kvm_kernel_irqfd *irqfd)
 {
 	return list_empty(&irqfd->list) ? false : true;
 }
@@ -209,7 +158,7 @@ irqfd_is_active(struct _irqfd *irqfd)
  * assumes kvm->irqfds.lock is held
  */
 static void
-irqfd_deactivate(struct _irqfd *irqfd)
+irqfd_deactivate(struct kvm_kernel_irqfd *irqfd)
 {
 	BUG_ON(!irqfd_is_active(irqfd));
 
@@ -224,7 +173,8 @@ irqfd_deactivate(struct _irqfd *irqfd)
 static int
 irqfd_wakeup(wait_queue_t *wait, unsigned mode, int sync, void *key)
 {
-	struct _irqfd *irqfd = container_of(wait, struct _irqfd, wait);
+	struct kvm_kernel_irqfd *irqfd =
+		container_of(wait, struct kvm_kernel_irqfd, wait);
 	unsigned long flags = (unsigned long)key;
 	struct kvm_kernel_irq_routing_entry irq;
 	struct kvm *kvm = irqfd->kvm;
@@ -274,12 +224,13 @@ static void
 irqfd_ptable_queue_proc(struct file *file, wait_queue_head_t *wqh,
 			poll_table *pt)
 {
-	struct _irqfd *irqfd = container_of(pt, struct _irqfd, pt);
+	struct kvm_kernel_irqfd *irqfd =
+		container_of(pt, struct kvm_kernel_irqfd, pt);
 	add_wait_queue(wqh, &irqfd->wait);
 }
 
 /* Must be called under irqfds.lock */
-static void irqfd_update(struct kvm *kvm, struct _irqfd *irqfd)
+static void irqfd_update(struct kvm *kvm, struct kvm_kernel_irqfd *irqfd)
 {
 	struct kvm_kernel_irq_routing_entry *e;
 	struct kvm_kernel_irq_routing_entry entries[KVM_NR_IRQCHIPS];
@@ -304,7 +255,7 @@ static void irqfd_update(struct kvm *kvm, struct _irqfd *irqfd)
 static int
 kvm_irqfd_assign(struct kvm *kvm, struct kvm_irqfd *args)
 {
-	struct _irqfd *irqfd, *tmp;
+	struct kvm_kernel_irqfd *irqfd, *tmp;
 	struct fd f;
 	struct eventfd_ctx *eventfd = NULL, *resamplefd = NULL;
 	int ret;
@@ -340,7 +291,7 @@ kvm_irqfd_assign(struct kvm *kvm, struct kvm_irqfd *args)
 	irqfd->eventfd = eventfd;
 
 	if (args->flags & KVM_IRQFD_FLAG_RESAMPLE) {
-		struct _irqfd_resampler *resampler;
+		struct kvm_kernel_irqfd_resampler *resampler;
 
 		resamplefd = eventfd_ctx_fdget(args->resamplefd);
 		if (IS_ERR(resamplefd)) {
@@ -525,7 +476,7 @@ kvm_eventfd_init(struct kvm *kvm)
 static int
 kvm_irqfd_deassign(struct kvm *kvm, struct kvm_irqfd *args)
 {
-	struct _irqfd *irqfd, *tmp;
+	struct kvm_kernel_irqfd *irqfd, *tmp;
 	struct eventfd_ctx *eventfd;
 
 	eventfd = eventfd_ctx_fdget(args->fd);
@@ -581,7 +532,7 @@ kvm_irqfd(struct kvm *kvm, struct kvm_irqfd *args)
 void
 kvm_irqfd_release(struct kvm *kvm)
 {
-	struct _irqfd *irqfd, *tmp;
+	struct kvm_kernel_irqfd *irqfd, *tmp;
 
 	spin_lock_irq(&kvm->irqfds.lock);
 
@@ -604,7 +555,7 @@ kvm_irqfd_release(struct kvm *kvm)
  */
 void kvm_irq_routing_update(struct kvm *kvm)
 {
-	struct _irqfd *irqfd;
+	struct kvm_kernel_irqfd *irqfd;
 
 	spin_lock_irq(&kvm->irqfds.lock);
 
-- 
1.9.1



From eric.auger at linaro.org  Mon Aug  3 10:20:43 2015
From: eric.auger at linaro.org (Eric Auger)
Date: Mon,  3 Aug 2015 19:20:43 +0200
Subject: [PATCH v4 4/5] KVM: introduce kvm_arch functions for IRQ bypass
In-Reply-To: <1438622444-25444-1-git-send-email-eric.auger@linaro.org>
References: <1438622444-25444-1-git-send-email-eric.auger@linaro.org>
Message-ID: <1438622444-25444-5-git-send-email-eric.auger@linaro.org>

This patch introduces
- kvm_arch_irq_bypass_add_producer
- kvm_arch_irq_bypass_del_producer
- kvm_arch_irq_bypass_stop
- kvm_arch_irq_bypass_start

They make possible to specialize the KVM IRQ bypass consumer in
case CONFIG_KVM_HAVE_IRQ_BYPASS is set.

Signed-off-by: Eric Auger <eric.auger at linaro.org>
Signed-off-by: Feng Wu <feng.wu at intel.com>

---

v2 -> v3 (Feng Wu):
- use 'kvm_arch_irq_bypass_start' instead of 'kvm_arch_irq_bypass_resume'
- Remove 'kvm_arch_irq_bypass_update', which is not needed to be
  a irqbypass callback per Alex's comments.
- Make kvm_arch_irq_bypass_add_producer return 'int'

v1 -> v2:
- use CONFIG_KVM_HAVE_IRQ_BYPASS instead CONFIG_IRQ_BYPASS_MANAGER
- rename all functions according to Paolo's proposal
- add kvm_arch_irq_bypass_update according to Feng's need
---
 include/linux/kvm_host.h | 33 +++++++++++++++++++++++++++++++++
 virt/kvm/Kconfig         |  3 +++
 2 files changed, 36 insertions(+)

diff --git a/include/linux/kvm_host.h b/include/linux/kvm_host.h
index 05e99b8..84b5feb 100644
--- a/include/linux/kvm_host.h
+++ b/include/linux/kvm_host.h
@@ -24,6 +24,7 @@
 #include <linux/err.h>
 #include <linux/irqflags.h>
 #include <linux/context_tracking.h>
+#include <linux/irqbypass.h>
 #include <asm/signal.h>
 
 #include <linux/kvm.h>
@@ -1151,5 +1152,37 @@ static inline void kvm_vcpu_set_dy_eligible(struct kvm_vcpu *vcpu, bool val)
 {
 }
 #endif /* CONFIG_HAVE_KVM_CPU_RELAX_INTERCEPT */
+
+#ifdef CONFIG_HAVE_KVM_IRQ_BYPASS
+
+int kvm_arch_irq_bypass_add_producer(struct irq_bypass_consumer *,
+			   struct irq_bypass_producer *);
+void kvm_arch_irq_bypass_del_producer(struct irq_bypass_consumer *,
+			   struct irq_bypass_producer *);
+void kvm_arch_irq_bypass_stop(struct irq_bypass_consumer *);
+void kvm_arch_irq_bypass_start(struct irq_bypass_consumer *);
+
+#else
+
+static inline int kvm_arch_irq_bypass_add_producer(
+			struct irq_bypass_consumer *cons,
+			struct irq_bypass_producer *prod)
+{
+	return -1;
+}
+static inline void kvm_arch_irq_bypass_del_producer(
+			struct irq_bypass_consumer *cons,
+			struct irq_bypass_producer *prod)
+{
+}
+static inline void kvm_arch_irq_bypass_stop(
+			struct irq_bypass_consumer *cons)
+{
+}
+static inline void kvm_arch_irq_bypass_start(
+			struct irq_bypass_consumer *cons)
+{
+}
+#endif /* CONFIG_HAVE_KVM_IRQ_BYPASS */
 #endif
 
diff --git a/virt/kvm/Kconfig b/virt/kvm/Kconfig
index e2c876d..9f8014d 100644
--- a/virt/kvm/Kconfig
+++ b/virt/kvm/Kconfig
@@ -47,3 +47,6 @@ config KVM_GENERIC_DIRTYLOG_READ_PROTECT
 config KVM_COMPAT
        def_bool y
        depends on COMPAT && !S390
+
+config HAVE_KVM_IRQ_BYPASS
+       bool
-- 
1.9.1



From eric.auger at linaro.org  Mon Aug  3 10:20:41 2015
From: eric.auger at linaro.org (Eric Auger)
Date: Mon,  3 Aug 2015 19:20:41 +0200
Subject: [PATCH v4 2/5] KVM: arm/arm64: select IRQ_BYPASS_MANAGER
In-Reply-To: <1438622444-25444-1-git-send-email-eric.auger@linaro.org>
References: <1438622444-25444-1-git-send-email-eric.auger@linaro.org>
Message-ID: <1438622444-25444-3-git-send-email-eric.auger@linaro.org>

Select IRQ_BYPASS_MANAGER when CONFIG_KVM is set
Also add compilation of virt/lib.

Signed-off-by: Eric Auger <eric.auger at linaro.org>
Signed-off-by: Feng Wu <feng.wu at intel.com>

---

v3 -> v4:
- add compilation of virt/lib in arm/arm64 KVM

v2 -> v3:
- [Feng Wu] Correct a typo in 'arch/arm64/kvm/Kconfig'

v1 -> v2:
- also set IRQ_BYPASS_MANAGER for arm64
---
 arch/arm/kvm/Kconfig    | 2 ++
 arch/arm/kvm/Makefile   | 1 +
 arch/arm64/kvm/Kconfig  | 2 ++
 arch/arm64/kvm/Makefile | 1 +
 4 files changed, 6 insertions(+)

diff --git a/arch/arm/kvm/Kconfig b/arch/arm/kvm/Kconfig
index bfb915d..3c565b9 100644
--- a/arch/arm/kvm/Kconfig
+++ b/arch/arm/kvm/Kconfig
@@ -3,6 +3,7 @@
 #
 
 source "virt/kvm/Kconfig"
+source "virt/lib/Kconfig"
 
 menuconfig VIRTUALIZATION
 	bool "Virtualization"
@@ -31,6 +32,7 @@ config KVM
 	select KVM_VFIO
 	select HAVE_KVM_EVENTFD
 	select HAVE_KVM_IRQFD
+	select IRQ_BYPASS_MANAGER
 	depends on ARM_VIRT_EXT && ARM_LPAE && ARM_ARCH_TIMER
 	---help---
 	  Support hosting virtualized guest machines.
diff --git a/arch/arm/kvm/Makefile b/arch/arm/kvm/Makefile
index c5eef02c..a6a41dd 100644
--- a/arch/arm/kvm/Makefile
+++ b/arch/arm/kvm/Makefile
@@ -24,3 +24,4 @@ obj-y += $(KVM)/arm/vgic.o
 obj-y += $(KVM)/arm/vgic-v2.o
 obj-y += $(KVM)/arm/vgic-v2-emul.o
 obj-y += $(KVM)/arm/arch_timer.o
+obj-y += ../../../virt/lib/
diff --git a/arch/arm64/kvm/Kconfig b/arch/arm64/kvm/Kconfig
index bfffe8f..2509539 100644
--- a/arch/arm64/kvm/Kconfig
+++ b/arch/arm64/kvm/Kconfig
@@ -3,6 +3,7 @@
 #
 
 source "virt/kvm/Kconfig"
+source "virt/lib/Kconfig"
 
 menuconfig VIRTUALIZATION
 	bool "Virtualization"
@@ -31,6 +32,7 @@ config KVM
 	select KVM_VFIO
 	select HAVE_KVM_EVENTFD
 	select HAVE_KVM_IRQFD
+	select IRQ_BYPASS_MANAGER
 	---help---
 	  Support hosting virtualized guest machines.
 
diff --git a/arch/arm64/kvm/Makefile b/arch/arm64/kvm/Makefile
index f90f4aa..55eec69 100644
--- a/arch/arm64/kvm/Makefile
+++ b/arch/arm64/kvm/Makefile
@@ -27,3 +27,4 @@ kvm-$(CONFIG_KVM_ARM_HOST) += $(KVM)/arm/vgic-v3.o
 kvm-$(CONFIG_KVM_ARM_HOST) += $(KVM)/arm/vgic-v3-emul.o
 kvm-$(CONFIG_KVM_ARM_HOST) += vgic-v3-switch.o
 kvm-$(CONFIG_KVM_ARM_HOST) += $(KVM)/arm/arch_timer.o
+kvm-$(CONFIG_KVM_ARM_HOST) += ../../../virt/lib/
-- 
1.9.1



From jungseoklee85 at gmail.com  Mon Aug  3 10:22:16 2015
From: jungseoklee85 at gmail.com (Jungseok Lee)
Date: Tue, 4 Aug 2015 02:22:16 +0900
Subject: [RFC 2/3] arm64: refactor save_stack_trace()
In-Reply-To: <20150803125711.65463359@gandalf.local.home>
References: <12F47692-3010-4886-B87D-3D7820609177@gmail.com>
 <20150716113115.45a17f17@gandalf.local.home>
 <20150716121658.7982fdf5@gandalf.local.home>
 <20150717124054.GE26091@leverpostej>
 <20150717090009.720f6bd0@gandalf.local.home>
 <77EA0F10-D5F6-48BD-8652-3B979A978659@gmail.com>
 <20150717104144.6588b2f7@gandalf.local.home>
 <0886A996-40E1-49E9-823C-85E55A858716@gmail.com>
 <1357EA74-B972-4B99-ADB0-BC7E8F06DDB5@gmail.com>
 <20150720162004.GL9908@arm.com> <20150803090951.GA10501@arm.com>
 <D7BD8A9F-8710-42D5-A0ED-8747D2B6B268@gmail.com>
 <20150803125711.65463359@gandalf.local.home>
Message-ID: <24AFDCDB-55DE-4A23-A26A-750B48AC365C@gmail.com>

On Aug 4, 2015, at 1:57 AM, Steven Rostedt wrote:
> On Tue, 4 Aug 2015 01:30:50 +0900
> Jungseok Lee <jungseoklee85 at gmail.com> wrote:
> 
> 
>> There are two issues in the current version.
>> 1) The change does not work correctly when function_graph feature is enabled.
>> 2) Akashi have raised an issue that size field of stack tracer is inaccurate.
>> 
>> So, I think this patch set is not ready yet.
> 
> Do you still want me to add code that does:
> 
> if (*p == (stack_dump_trace[i] + FTRACE_STACK_FRAME_OFFSET)) {
> 
> ?
> 
> If you expect to need that, I can get it into the next merge window and
> you can base the code of that in the merge window after that.

It would be better to add the snippet when a new version is ready.
That way might help to figure out easily why the macro is introduced and how
it can be used in architecture code.

Best Regards
Jungseok Lee

From f.fainelli at gmail.com  Mon Aug  3 10:28:58 2015
From: f.fainelli at gmail.com (Florian Fainelli)
Date: Mon, 03 Aug 2015 10:28:58 -0700
Subject: [PATCH v4 4/4] ARM: dts: brcmstb: add BCM7445 GPIO nodes
In-Reply-To: <1438391865-7862-5-git-send-email-gregory.0xf0@gmail.com>
References: <1438391865-7862-1-git-send-email-gregory.0xf0@gmail.com>
 <1438391865-7862-5-git-send-email-gregory.0xf0@gmail.com>
Message-ID: <55BFA4DA.5010208@gmail.com>

On 31/07/15 18:17, Gregory Fong wrote:
> Need the aon_pm_l2_intc and irq0_aon_intc descriptions, so included
> those as well.
> 
> Signed-off-by: Gregory Fong <gregory.0xf0 at gmail.com>

Applied to devicetree/next, thanks!
-- 
Florian


From rostedt at goodmis.org  Mon Aug  3 10:32:20 2015
From: rostedt at goodmis.org (Steven Rostedt)
Date: Mon, 3 Aug 2015 13:32:20 -0400
Subject: [RFC 2/3] arm64: refactor save_stack_trace()
In-Reply-To: <24AFDCDB-55DE-4A23-A26A-750B48AC365C@gmail.com>
References: <12F47692-3010-4886-B87D-3D7820609177@gmail.com>
 <20150716113115.45a17f17@gandalf.local.home>
 <20150716121658.7982fdf5@gandalf.local.home>
 <20150717124054.GE26091@leverpostej>
 <20150717090009.720f6bd0@gandalf.local.home>
 <77EA0F10-D5F6-48BD-8652-3B979A978659@gmail.com>
 <20150717104144.6588b2f7@gandalf.local.home>
 <0886A996-40E1-49E9-823C-85E55A858716@gmail.com>
 <1357EA74-B972-4B99-ADB0-BC7E8F06DDB5@gmail.com>
 <20150720162004.GL9908@arm.com> <20150803090951.GA10501@arm.com>
 <D7BD8A9F-8710-42D5-A0ED-8747D2B6B268@gmail.com>
 <20150803125711.65463359@gandalf.local.home>
 <24AFDCDB-55DE-4A23-A26A-750B48AC365C@gmail.com>
Message-ID: <20150803133220.46db9839@gandalf.local.home>

On Tue, 4 Aug 2015 02:22:16 +0900
Jungseok Lee <jungseoklee85 at gmail.com> wrote:


> It would be better to add the snippet when a new version is ready.
> That way might help to figure out easily why the macro is introduced and how
> it can be used in architecture code.


OK, which ever.

-- Steve


From catalin.marinas at arm.com  Mon Aug  3 10:33:48 2015
From: catalin.marinas at arm.com (Catalin Marinas)
Date: Mon, 3 Aug 2015 18:33:48 +0100
Subject: [PATCH v5 2/3] arm64: Add IOMMU dma_ops
In-Reply-To: <8a5abd0a9929aae160ccb74d7a8d9c3698f61910.1438362603.git.robin.murphy@arm.com>
References: <cover.1438362603.git.robin.murphy@arm.com>
 <8a5abd0a9929aae160ccb74d7a8d9c3698f61910.1438362603.git.robin.murphy@arm.com>
Message-ID: <20150803173348.GD11772@e104818-lin.cambridge.arm.com>

On Fri, Jul 31, 2015 at 06:18:28PM +0100, Robin Murphy wrote:
> Taking some inspiration from the arch/arm code, implement the
> arch-specific side of the DMA mapping ops using the new IOMMU-DMA layer.
> 
> Unfortunately the device setup code has to start out as a big ugly mess
> in order to work usefully right now, as 'proper' operation depends on
> changes to device probe and DMA configuration ordering, IOMMU groups for
> platform devices, and default domain support in arm/arm64 IOMMU drivers.
> The workarounds here need only exist until that work is finished.
> 
> Signed-off-by: Robin Murphy <robin.murphy at arm.com>

Reviewed-by: Catalin Marinas <catalin.marinas at arm.com>


From f.fainelli at gmail.com  Mon Aug  3 10:33:06 2015
From: f.fainelli at gmail.com (Florian Fainelli)
Date: Mon, 03 Aug 2015 10:33:06 -0700
Subject: [PATCH v4 0/4] GPIO support for BRCMSTB
In-Reply-To: <1438391865-7862-1-git-send-email-gregory.0xf0@gmail.com>
References: <1438391865-7862-1-git-send-email-gregory.0xf0@gmail.com>
Message-ID: <55BFA5D2.1090305@gmail.com>

On 31/07/15 18:17, Gregory Fong wrote:
> Adds interrupt support for the GPIO controller (UPG GIO) used on Broadcom's
> various BRCMSTB SoCs (BCM7XXX and others).  For all existing hardware, this
> block hooks up to the BCM7120 L2 IRQ controller and so will require
> CONFIG_BCM7120_L2_IRQ=y.

For this entire series:

Reviewed-by: Florian Fainelli <f.fainelli at gmail.com>

Thanks!

> 
> New in v4:
> - add nodes for the BRCMSTB GPIO controller to the BCM7445 dts file
> - a few improvements suggested by Linus Walleij on v3
> - remove unused 'irq' argument to brcmstb_gpio_irq_bank_handler()
> 
> The following are not included in this patchset:
> - Initial device tree bindings (merged from v1 to GPIO tree)
> - Initial GPIO support w/o interrupts (merged from v2 to GPIO tree)
> - ARM Kconfig changes (merged from v2 to arm-soc tree)
> - fix for null ptr deref in driver remove (merged from v3)
> 
> Previous versions:
> v1: https://lkml.org/lkml/2015/5/6/199
> v2: https://lkml.org/lkml/2015/5/28/853
> v3: https://lkml.org/lkml/2015/6/17/960
> 
> Gregory Fong (4):
>   dt-bindings: brcmstb-gpio: document properties for wakeup
>   gpio: brcmstb: Add interrupt and wakeup source support
>   gpio: brcmstb: support wakeup from S5 cold boot
>   ARM: dts: brcmstb: add BCM7445 GPIO nodes
> 
>  .../devicetree/bindings/gpio/brcm,brcmstb-gpio.txt |  35 ++-
>  arch/arm/boot/dts/bcm7445.dtsi                     |  50 ++++
>  drivers/gpio/Kconfig                               |   1 +
>  drivers/gpio/gpio-brcmstb.c                        | 306 ++++++++++++++++++++-
>  4 files changed, 379 insertions(+), 13 deletions(-)
> 


-- 
Florian


From catalin.marinas at arm.com  Mon Aug  3 10:40:10 2015
From: catalin.marinas at arm.com (Catalin Marinas)
Date: Mon, 3 Aug 2015 18:40:10 +0100
Subject: [PATCH v5 1/3] iommu: Implement common IOMMU ops for DMA mapping
In-Reply-To: <6ce6b501501f611297ae0eae31e07b0d2060eaae.1438362603.git.robin.murphy@arm.com>
References: <cover.1438362603.git.robin.murphy@arm.com>
 <6ce6b501501f611297ae0eae31e07b0d2060eaae.1438362603.git.robin.murphy@arm.com>
Message-ID: <20150803174010.GE11772@e104818-lin.cambridge.arm.com>

On Fri, Jul 31, 2015 at 06:18:27PM +0100, Robin Murphy wrote:
> Taking inspiration from the existing arch/arm code, break out some
> generic functions to interface the DMA-API to the IOMMU-API. This will
> do the bulk of the heavy lifting for IOMMU-backed dma-mapping.
> 
> Signed-off-by: Robin Murphy <robin.murphy at arm.com>

Acked-by: Catalin Marinas <catalin.marinas at arm.com>


From eric.auger at linaro.org  Mon Aug  3 10:20:44 2015
From: eric.auger at linaro.org (Eric Auger)
Date: Mon,  3 Aug 2015 19:20:44 +0200
Subject: [PATCH v4 5/5] KVM: eventfd: add irq bypass consumer management
In-Reply-To: <1438622444-25444-1-git-send-email-eric.auger@linaro.org>
References: <1438622444-25444-1-git-send-email-eric.auger@linaro.org>
Message-ID: <1438622444-25444-6-git-send-email-eric.auger@linaro.org>

This patch adds the registration/unregistration of an
irq_bypass_consumer on irqfd assignment/deassignment.

Signed-off-by: Eric Auger <eric.auger at linaro.org>
Signed-off-by: Feng Wu <feng.wu at intel.com>

---

v2 -> v3 (Feng Wu):
- Use kvm_arch_irq_bypass_start
- Remove kvm_arch_irq_bypass_update
- Add member 'struct irq_bypass_producer *producer' in
  'struct kvm_kernel_irqfd', it is needed by posted interrupt.
- Remove 'irq_bypass_unregister_consumer' in kvm_irqfd_deassign()

v1 -> v2:
- populate of kvm and gsi removed
- unregister the consumer on irqfd_shutdown
---
 include/linux/kvm_irqfd.h |  2 ++
 virt/kvm/eventfd.c        | 10 ++++++++++
 2 files changed, 12 insertions(+)

diff --git a/include/linux/kvm_irqfd.h b/include/linux/kvm_irqfd.h
index f926b39..0c1de05 100644
--- a/include/linux/kvm_irqfd.h
+++ b/include/linux/kvm_irqfd.h
@@ -64,6 +64,8 @@ struct kvm_kernel_irqfd {
 	struct list_head list;
 	poll_table pt;
 	struct work_struct shutdown;
+	struct irq_bypass_consumer consumer;
+	struct irq_bypass_producer *producer;
 };
 
 #endif /* __LINUX_KVM_IRQFD_H */
diff --git a/virt/kvm/eventfd.c b/virt/kvm/eventfd.c
index 647ffb8..08855de 100644
--- a/virt/kvm/eventfd.c
+++ b/virt/kvm/eventfd.c
@@ -35,6 +35,7 @@
 #include <linux/srcu.h>
 #include <linux/slab.h>
 #include <linux/seqlock.h>
+#include <linux/irqbypass.h>
 #include <trace/events/kvm.h>
 
 #include <kvm/iodev.h>
@@ -140,6 +141,7 @@ irqfd_shutdown(struct work_struct *work)
 	/*
 	 * It is now safe to release the object's resources
 	 */
+	irq_bypass_unregister_consumer(&irqfd->consumer);
 	eventfd_ctx_put(irqfd->eventfd);
 	kfree(irqfd);
 }
@@ -380,6 +382,14 @@ kvm_irqfd_assign(struct kvm *kvm, struct kvm_irqfd *args)
 	 */
 	fdput(f);
 
+	irqfd->consumer.token = (void *)irqfd->eventfd;
+	irqfd->consumer.add_producer = kvm_arch_irq_bypass_add_producer;
+	irqfd->consumer.del_producer = kvm_arch_irq_bypass_del_producer;
+	irqfd->consumer.stop = kvm_arch_irq_bypass_stop;
+	irqfd->consumer.start = kvm_arch_irq_bypass_start;
+	ret = irq_bypass_register_consumer(&irqfd->consumer);
+	WARN_ON(ret);
+
 	return 0;
 
 fail:
-- 
1.9.1



From sboyd at codeaurora.org  Mon Aug  3 10:55:29 2015
From: sboyd at codeaurora.org (Stephen Boyd)
Date: Mon, 03 Aug 2015 10:55:29 -0700
Subject: [PATCH 1/3] clk: versatile: Switch to assigned clock parents
In-Reply-To: <1438610480.2142.14.camel@arm.com>
References: <55BBB2FC.9030102@codeaurora.org>
 <1438386285-5070-1-git-send-email-sboyd@codeaurora.org>
 <1438386285-5070-2-git-send-email-sboyd@codeaurora.org>
 <1438610480.2142.14.camel@arm.com>
Message-ID: <55BFAB11.7080600@codeaurora.org>

On 08/03/2015 07:01 AM, Pawel Moll wrote:
> On Sat, 2015-08-01 at 00:44 +0100, Stephen Boyd wrote:
>> @@ -179,6 +124,15 @@ static void __init clk_sp810_of_setup(struct device_node *node)
>>   		sp810->timerclken[i].channel = i;
>>   		sp810->timerclken[i].hw.init = &init;
>>   
>> +		/*
>> +		 * If DT isn't setting the parent, force it to be
>> +		 * the 1 MHz clock without going through the framework.
>> +		 * We do this before clk_register() so that it can determine
>> +		 * the parent and setup the tree properly.
>> +		 */
>> +		if (deprecated)
>> +			init.ops->set_parent(&sp810->timerclken[i].hw, 1);
>> +
>>   		sp810->timerclken[i].clk = clk_register(NULL,
>>   				&sp810->timerclken[i].hw);
>>   		WARN_ON(IS_ERR(sp810->timerclken[i].clk));
> So that's one thing I've got a (small) problem here...
>
> The above change assumes that SP810 always have 32kHz clock on input 0
> and 1MHz clock on input 1. Yes, this is how it made on VExpress, but it
> doesn't have to be the case. The magic picking up the faster clock was
> added to handle all possible cases.
>
> The bottom line is: if all we care is VExpress than it works, but it's
> still a hack. Personally I don't like it, however I won't nak the patch
> because of this.
>

All current dts files in the kernel tree have 1MHz on input 1, so we 
make this change here to set the parent to input 1 if there isn't an 
assigned-clock-parents property. Presumably new dts files should have 
the new property so that things work properly. I tried to find the 
binding document, but it doesn't look to exist, so I didn't have 
anything to update.


-- 
Qualcomm Innovation Center, Inc. is a member of Code Aurora Forum,
a Linux Foundation Collaborative Project



From jdelvare at suse.de  Mon Aug  3 10:06:52 2015
From: jdelvare at suse.de (Jean Delvare)
Date: Mon, 03 Aug 2015 19:06:52 +0200
Subject: [lm-sensors] MAINTAINERS/s5p: Kamil Debski no longer with Samsung?
In-Reply-To: <5606140.737HZuKSvR@amdc1976>
References: <20150802203128.1B6952691B2@smtprelay05.hostedemail.com>
 <1438548040.30149.1.camel@perches.com>  <5606140.737HZuKSvR@amdc1976>
Message-ID: <1438621612.10722.27.camel@chaos.site>

Hi Bartlomiej,

Le Monday 03 August 2015 ? 17:33 +0200, Bartlomiej Zolnierkiewicz a
?crit :
> Hi,
> 
> On Sunday, August 02, 2015 01:40:40 PM Joe Perches wrote:
> > On Sun, 2015-08-02 at 20:31 +0000, Mail Delivery System wrote:
> > > <k.debski at samsung.com>: host mailin.samsung.com[203.254.224.12] 
> > > said: 550 5.1.1
> > >     Recipient address rejected: User unknown (in reply to RCPT TO 
> > > command)
> > 
> > His email address bounces.
> > 
> > Should MAINTAINERS be updated?
> 
> Please wait with these changes, the situation should be clarified soon
> (I've added Kamil to Cc).

Already clarified behind the scenes ;-) The patch should be discarded.

Thanks,
-- 
Jean Delvare
SUSE L3 Support



From dan.j.williams at intel.com  Mon Aug  3 11:01:46 2015
From: dan.j.williams at intel.com (Dan Williams)
Date: Mon, 3 Aug 2015 11:01:46 -0700
Subject: [PATCH v3 24/24] pmem: convert to generic memremap
In-Reply-To: <1438622487.9404.2.camel@linux.intel.com>
References: <20150730165155.33962.64121.stgit@dwillia2-desk3.amr.corp.intel.com>
 <20150730165553.33962.20257.stgit@dwillia2-desk3.amr.corp.intel.com>
 <1438622487.9404.2.camel@linux.intel.com>
Message-ID: <CAPcyv4gCPyXwwgjidaUaNyNe8ZitmwVa-NF7pBT-y3rV4XBUzA@mail.gmail.com>

On Mon, Aug 3, 2015 at 10:21 AM, Ross Zwisler
<ross.zwisler at linux.intel.com> wrote:
> On Thu, 2015-07-30 at 12:55 -0400, Dan Williams wrote:
>> Update memremap_pmem() to query the architecture for the mapping type of
>> the given persistent memory range  and then pass those flags to generic
>> memremap().  arch_memremap_pmem_flags() is provided an address range to
>> evaluate in the event an arch has a need for different mapping types by
>> address range.  For example the ACPI NFIT carries EFI mapping types in
>> its memory range description table.
>>
>> Cc: Ross Zwisler <ross.zwisler at linux.intel.com>
>> Signed-off-by: Dan Williams <dan.j.williams at intel.com>
>> ---
>>  arch/x86/include/asm/io.h |    2 +-
>>  arch/x86/mm/ioremap.c     |   16 ++++++++++------
>>  include/linux/pmem.h      |   26 +++++++++++++++-----------
>>  3 files changed, 26 insertions(+), 18 deletions(-)
>>
>> diff --git a/arch/x86/include/asm/io.h b/arch/x86/include/asm/io.h
>> index 1a9d44ee9ed0..26c81b01419c 100644
>> --- a/arch/x86/include/asm/io.h
>> +++ b/arch/x86/include/asm/io.h
>> @@ -245,7 +245,7 @@ static inline void flush_write_buffers(void)
>>  #endif
>>  }
>>
>> -void __pmem *arch_memremap_pmem(resource_size_t offset, size_t size);
>> +unsigned long arch_memremap_pmem_flags(resource_size_t offset, size_t size);
>>  #endif /* __KERNEL__ */
>>
>>  extern void native_io_delay(void);
>> diff --git a/arch/x86/mm/ioremap.c b/arch/x86/mm/ioremap.c
>> index ffbfcf2e701b..5a41e3e4ea1e 100644
>> --- a/arch/x86/mm/ioremap.c
>> +++ b/arch/x86/mm/ioremap.c
>> @@ -205,6 +205,16 @@ err_free_memtype:
>>       return NULL;
>>  }
>>
>> +unsigned long arch_memremap_pmem_flags(resource_size_t offset, size_t size)
>> +{
>> +     /*
>> +      * TODO: check the mapping type provided by platform firmware,
>> +      * per range.
>> +      */
>> +     return MEMREMAP_WB;
>> +}
>> +EXPORT_SYMBOL(arch_memremap_pmem_flags);
>
> I'm not sure that the architecture code has the right information to be able
> to tell the caller what the correct mapping is.
>

It does in this instance as it has to pick a mapping type that is
compatible with memcpy_to_pmem() and wmb_pmem().

> I think what you are ultimately looking for is the "Address Range Memory
> Mapping Attribute" found in the System Physical Address Range Structure of the
> NFIT, right?  (ACPI 6.0, table 5-128)  How can we get to that structure from
> nfit-independent architecture code like arch_memremap_pmem_flags()?  It seems
> like that if we want to make the mapping type dynamic we should get the flags
> from ND when the SPA range is provided by ND, and provide a reasonable default
> (WB, it seems) when we are dealing with legacy PMEM?  If PMEM had the flag
> from whatever source, it could then pass it in to memremap_pmem(), and get a
> mapping of the appropriate caching.

We can do what ioremap() does and look it up through other means.

> Another option of course is to just ignore the mapping attribute in the NFIT
> like we've been doing, and just say "we know WB will be good enough", and
> remove the TODO.

I agree, but there may be a non-zero chance that a platform
implementation wants strict adherence.  Maybe move the TODO to a
dev_dbg() that flags platforms where the NFIT mapping type is not
"WB"?


From joe at perches.com  Mon Aug  3 11:02:50 2015
From: joe at perches.com (Joe Perches)
Date: Mon, 03 Aug 2015 11:02:50 -0700
Subject: [lm-sensors] MAINTAINERS/s5p: Kamil Debski no longer with Samsung?
In-Reply-To: <1438621612.10722.27.camel@chaos.site>
References: <20150802203128.1B6952691B2@smtprelay05.hostedemail.com>
 <1438548040.30149.1.camel@perches.com>  <5606140.737HZuKSvR@amdc1976>
 <1438621612.10722.27.camel@chaos.site>
Message-ID: <1438624970.16753.9.camel@perches.com>

On Mon, 2015-08-03 at 19:06 +0200, Jean Delvare wrote:
> Hi Bartlomiej,
> 
> Le Monday 03 August 2015 ? 17:33 +0200, Bartlomiej Zolnierkiewicz a
> ?crit :
> > Hi,
> > 
> > On Sunday, August 02, 2015 01:40:40 PM Joe Perches wrote:
> > > On Sun, 2015-08-02 at 20:31 +0000, Mail Delivery System wrote:
> > > > <k.debski at samsung.com>: host mailin.samsung.com[203.254.224.12] 
> > > > said: 550 5.1.1
> > > >     Recipient address rejected: User unknown (in reply to RCPT TO 
> > > > command)
> > > 
> > > His email address bounces.
> > > 
> > > Should MAINTAINERS be updated?
> > 
> > Please wait with these changes, the situation should be clarified soon
> > (I've added Kamil to Cc).
> 
> Already clarified behind the scenes ;-) The patch should be 
> discarded.

It wasn't a patch, it was a question with a list of
sections that might be modified, and it wasn't signed.



From m-karicheri2 at ti.com  Mon Aug  3 11:11:57 2015
From: m-karicheri2 at ti.com (Murali Karicheri)
Date: Mon, 3 Aug 2015 14:11:57 -0400
Subject: [PATCH 1/2] ARM: dts: keystone: fix the clock node for mdio
Message-ID: <1438625518-21315-1-git-send-email-m-karicheri2@ti.com>

Currently the MDIO clock is pointing to clkpa instead of clkcpgmac.
MDIO is part of the ethss and the clock should be clkcpgmac.

Signed-off-by: Murali Karicheri <m-karicheri2 at ti.com>
---
 arch/arm/boot/dts/keystone.dtsi | 2 +-
 1 file changed, 1 insertion(+), 1 deletion(-)

diff --git a/arch/arm/boot/dts/keystone.dtsi b/arch/arm/boot/dts/keystone.dtsi
index e7a6f6d..6245a17 100644
--- a/arch/arm/boot/dts/keystone.dtsi
+++ b/arch/arm/boot/dts/keystone.dtsi
@@ -273,7 +273,7 @@
 			#size-cells = <0>;
 			reg		= <0x02090300 0x100>;
 			status = "disabled";
-			clocks = <&clkpa>;
+			clocks = <&clkcpgmac>;
 			clock-names = "fck";
 			bus_freq	= <2500000>;
 		};
-- 
1.9.1



From m-karicheri2 at ti.com  Mon Aug  3 11:11:58 2015
From: m-karicheri2 at ti.com (Murali Karicheri)
Date: Mon, 3 Aug 2015 14:11:58 -0400
Subject: [PATCH 2/2] ARM: dts: keystone: Fix the mdio bindings by moving it to
 soc specific file
In-Reply-To: <1438625518-21315-1-git-send-email-m-karicheri2@ti.com>
References: <1438625518-21315-1-git-send-email-m-karicheri2@ti.com>
Message-ID: <1438625518-21315-2-git-send-email-m-karicheri2@ti.com>

Currently mdio bindings are defined in keystone.dtsi and this results
in incorrect unit address for the node on K2E and K2L SoCs. Fix this
by moving them to SoC specific DTS file.

Signed-off-by: Murali Karicheri <m-karicheri2 at ti.com>
---
 arch/arm/boot/dts/k2e.dtsi      | 15 +++++++++++----
 arch/arm/boot/dts/k2hk.dtsi     | 11 +++++++++++
 arch/arm/boot/dts/k2l.dtsi      | 16 +++++++++++-----
 arch/arm/boot/dts/keystone.dtsi | 11 -----------
 4 files changed, 33 insertions(+), 20 deletions(-)

diff --git a/arch/arm/boot/dts/k2e.dtsi b/arch/arm/boot/dts/k2e.dtsi
index 1b6494f..675fb8e 100644
--- a/arch/arm/boot/dts/k2e.dtsi
+++ b/arch/arm/boot/dts/k2e.dtsi
@@ -131,10 +131,17 @@
 					<GIC_SPI 376 IRQ_TYPE_EDGE_RISING>;
 			};
 		};
+
+		mdio: mdio at 24200f00 {
+			compatible	= "ti,keystone_mdio", "ti,davinci_mdio";
+			#address-cells = <1>;
+			#size-cells = <0>;
+			reg = <0x24200f00 0x100>;
+			status = "disabled";
+			clocks = <&clkcpgmac>;
+			clock-names = "fck";
+			bus_freq	= <2500000>;
+		};
 		/include/ "k2e-netcp.dtsi"
 	};
 };
-
-&mdio {
-	reg = <0x24200f00 0x100>;
-};
diff --git a/arch/arm/boot/dts/k2hk.dtsi b/arch/arm/boot/dts/k2hk.dtsi
index ae64724..d0810a5 100644
--- a/arch/arm/boot/dts/k2hk.dtsi
+++ b/arch/arm/boot/dts/k2hk.dtsi
@@ -98,6 +98,17 @@
 			#gpio-cells = <2>;
 			gpio,syscon-dev = <&devctrl 0x25c>;
 		};
+
+		mdio: mdio at 02090300 {
+			compatible	= "ti,keystone_mdio", "ti,davinci_mdio";
+			#address-cells = <1>;
+			#size-cells = <0>;
+			reg = <0x02090300 0x100>;
+			status = "disabled";
+			clocks = <&clkcpgmac>;
+			clock-names = "fck";
+			bus_freq	= <2500000>;
+		};
 		/include/ "k2hk-netcp.dtsi"
 	};
 };
diff --git a/arch/arm/boot/dts/k2l.dtsi b/arch/arm/boot/dts/k2l.dtsi
index 0e00748..49fd414 100644
--- a/arch/arm/boot/dts/k2l.dtsi
+++ b/arch/arm/boot/dts/k2l.dtsi
@@ -29,7 +29,6 @@
 	};
 
 	soc {
-
 		/include/ "k2l-clocks.dtsi"
 
 		uart2: serial at 02348400 {
@@ -79,6 +78,17 @@
 			#gpio-cells = <2>;
 			gpio,syscon-dev = <&devctrl 0x24c>;
 		};
+
+		mdio: mdio at 26200f00 {
+			compatible	= "ti,keystone_mdio", "ti,davinci_mdio";
+			#address-cells = <1>;
+			#size-cells = <0>;
+			reg = <0x26200f00 0x100>;
+			status = "disabled";
+			clocks = <&clkcpgmac>;
+			clock-names = "fck";
+			bus_freq	= <2500000>;
+		};
 		/include/ "k2l-netcp.dtsi"
 	};
 };
@@ -96,7 +106,3 @@
        /* Pin muxed. Enabled and configured by Bootloader */
        status = "disabled";
 };
-
-&mdio {
-	reg = <0x26200f00 0x100>;
-};
diff --git a/arch/arm/boot/dts/keystone.dtsi b/arch/arm/boot/dts/keystone.dtsi
index 6245a17..72816d6 100644
--- a/arch/arm/boot/dts/keystone.dtsi
+++ b/arch/arm/boot/dts/keystone.dtsi
@@ -267,17 +267,6 @@
 				  1 0 0x21000A00 0x00000100>;
 		};
 
-		mdio: mdio at 02090300 {
-			compatible	= "ti,keystone_mdio", "ti,davinci_mdio";
-			#address-cells = <1>;
-			#size-cells = <0>;
-			reg		= <0x02090300 0x100>;
-			status = "disabled";
-			clocks = <&clkcpgmac>;
-			clock-names = "fck";
-			bus_freq	= <2500000>;
-		};
-
 		kirq0: keystone_irq at 26202a0 {
 			compatible = "ti,keystone-irq";
 			interrupts = <GIC_SPI 4 IRQ_TYPE_EDGE_RISING>;
-- 
1.9.1



From m-karicheri2 at ti.com  Mon Aug  3 11:18:18 2015
From: m-karicheri2 at ti.com (Murali Karicheri)
Date: Mon, 3 Aug 2015 14:18:18 -0400
Subject: [PATCH] ARM/PCI: set MPS before pci_bus_add_devices()
In-Reply-To: <20150723145936.GX21967@google.com>
References: <1437514519-18545-1-git-send-email-m-karicheri2@ti.com>
 <20150723145936.GX21967@google.com>
Message-ID: <55BFB06A.3040904@ti.com>

On 07/23/2015 10:59 AM, Bjorn Helgaas wrote:
> On Tue, Jul 21, 2015 at 05:35:19PM -0400, Murali Karicheri wrote:
>> The MPS configuration should be done *before* pci_bus_add_devices().
>> After pci_bus_add_devices(), drivers may be bound to devices, and
>> the PCI core shouldn't touch device configuration while a driver
>> owns the device.
>>
>> Signed-off-by: Murali Karicheri <m-karicheri2 at ti.com>
>> Reported-by: Bjorn Helgaas <bhelgaas at google.com>
>
> Applied to pci/enumeration for v4.3, thanks!  I removed the "bus" test; let
> me know if you think that's incorrect.
Ok. Will do. Thanks.

Murali

>
>> ---
>>   arch/arm/kernel/bios32.c | 19 +++++--------------
>>   1 file changed, 5 insertions(+), 14 deletions(-)
>>
>> diff --git a/arch/arm/kernel/bios32.c b/arch/arm/kernel/bios32.c
>> index fcbbbb1..17efde7 100644
>> --- a/arch/arm/kernel/bios32.c
>> +++ b/arch/arm/kernel/bios32.c
>> @@ -520,7 +520,8 @@ void pci_common_init_dev(struct device *parent, struct hw_pci *hw)
>>   	list_for_each_entry(sys, &head, node) {
>>   		struct pci_bus *bus = sys->bus;
>>
>> -		if (!pci_has_flag(PCI_PROBE_ONLY)) {
>> +		if (bus && !pci_has_flag(PCI_PROBE_ONLY)) {
>
> I think the test for "bus" being non-NULL is superfluous here.  If "bus"
> were NULL, we would already oops in pci_bus_add_devices().
>
>> +			struct pci_bus *child;
>>   			/*
>>   			 * Size the bridge windows.
>>   			 */
>> @@ -530,25 +531,15 @@ void pci_common_init_dev(struct device *parent, struct hw_pci *hw)
>>   			 * Assign resources.
>>   			 */
>>   			pci_bus_assign_resources(bus);
>> -		}
>>
>> +			list_for_each_entry(child, &bus->children, node)
>> +				pcie_bus_configure_settings(child);
>> +		}
>>   		/*
>>   		 * Tell drivers about devices found.
>>   		 */
>>   		pci_bus_add_devices(bus);
>>   	}
>> -
>> -	list_for_each_entry(sys, &head, node) {
>> -		struct pci_bus *bus = sys->bus;
>> -
>> -		/* Configure PCI Express settings */
>> -		if (bus && !pci_has_flag(PCI_PROBE_ONLY)) {
>> -			struct pci_bus *child;
>> -
>> -			list_for_each_entry(child, &bus->children, node)
>> -				pcie_bus_configure_settings(child);
>> -		}
>> -	}
>>   }
>>
>>   #ifndef CONFIG_PCI_HOST_ITE8152
>> --
>> 1.9.1
>>
>
> _______________________________________________
> linux-arm-kernel mailing list
> linux-arm-kernel at lists.infradead.org
> http://lists.infradead.org/mailman/listinfo/linux-arm-kernel
>


-- 
Murali Karicheri
Linux Kernel, Keystone


From m-karicheri2 at ti.com  Mon Aug  3 11:22:19 2015
From: m-karicheri2 at ti.com (Murali Karicheri)
Date: Mon, 3 Aug 2015 14:22:19 -0400
Subject: [PATCH 1/2] ARM: dts: keystone: fix the clock node for mdio
In-Reply-To: <1438625518-21315-1-git-send-email-m-karicheri2@ti.com>
References: <1438625518-21315-1-git-send-email-m-karicheri2@ti.com>
Message-ID: <55BFB15B.8040207@ti.com>

On 08/03/2015 02:11 PM, Murali Karicheri wrote:
> Currently the MDIO clock is pointing to clkpa instead of clkcpgmac.
> MDIO is part of the ethss and the clock should be clkcpgmac.
>
> Signed-off-by: Murali Karicheri <m-karicheri2 at ti.com>
> ---
>   arch/arm/boot/dts/keystone.dtsi | 2 +-
>   1 file changed, 1 insertion(+), 1 deletion(-)
>
> diff --git a/arch/arm/boot/dts/keystone.dtsi b/arch/arm/boot/dts/keystone.dtsi
> index e7a6f6d..6245a17 100644
> --- a/arch/arm/boot/dts/keystone.dtsi
> +++ b/arch/arm/boot/dts/keystone.dtsi
> @@ -273,7 +273,7 @@
>   			#size-cells = <0>;
>   			reg		= <0x02090300 0x100>;
>   			status = "disabled";
> -			clocks = <&clkpa>;
> +			clocks = <&clkcpgmac>;
>   			clock-names = "fck";
>   			bus_freq	= <2500000>;
>   		};
>
Santosh,

This is a big fix and needs to go in v4.2-rc. So please review and apply 
asap. v4.2 is the first release that has netcp driver fully functional 
and I want to fix as many known bugs as possible.

Thanks.

-- 
Murali Karicheri
Linux Kernel, Keystone


From sergei.shtylyov at cogentembedded.com  Mon Aug  3 11:23:14 2015
From: sergei.shtylyov at cogentembedded.com (Sergei Shtylyov)
Date: Mon, 3 Aug 2015 21:23:14 +0300
Subject: [PATCH 13/13] iommu/arm-smmu: Treat unknown OAS as 48-bit
In-Reply-To: <1438608355-7335-14-git-send-email-will.deacon@arm.com>
References: <1438608355-7335-1-git-send-email-will.deacon@arm.com>
 <1438608355-7335-14-git-send-email-will.deacon@arm.com>
Message-ID: <55BFB192.1040505@cogentembedded.com>

Hello.

On 08/03/2015 04:25 PM, Will Deacon wrote:

> A late change to the SMMUv3 architecture ensures that the OAS field
> will be monotonically increasing, so we can assume that an unknown OAS
> is at least 48-bit and use that, rather than fail the device probe.

> Signed-off-by: Will Deacon <will.deacon at arm.com>
> ---
>   drivers/iommu/arm-smmu-v3.c | 7 +++----
>   1 file changed, 3 insertions(+), 4 deletions(-)

> diff --git a/drivers/iommu/arm-smmu-v3.c b/drivers/iommu/arm-smmu-v3.c
> index 15fb669282b4..a435e706226a 100644
> --- a/drivers/iommu/arm-smmu-v3.c
> +++ b/drivers/iommu/arm-smmu-v3.c
> @@ -2528,12 +2528,11 @@ static int arm_smmu_device_probe(struct arm_smmu_device *smmu)
>   	case IDR5_OAS_44_BIT:
>   		smmu->oas = 44;
>   		break;
> +	default:
> +		dev_info(smmu->dev,
> +			"unknown output address size. Truncating to 48-bit\n");

    Please add a comment like /* FALLTHRU */ here.

>   	case IDR5_OAS_48_BIT:
>   		smmu->oas = 48;
> -		break;
> -	default:
> -		dev_err(smmu->dev, "unknown output address size!\n");
> -		return -ENXIO;
>   	}
>
>   	/* Set the DMA mask for our table walker */

MBR, Sergei



From santosh.shilimkar at oracle.com  Mon Aug  3 11:30:04 2015
From: santosh.shilimkar at oracle.com (santosh.shilimkar at oracle.com)
Date: Mon, 03 Aug 2015 11:30:04 -0700
Subject: [PATCH 1/2] ARM: dts: keystone: fix the clock node for mdio
In-Reply-To: <55BFB15B.8040207@ti.com>
References: <1438625518-21315-1-git-send-email-m-karicheri2@ti.com>
 <55BFB15B.8040207@ti.com>
Message-ID: <55BFB32C.6080201@oracle.com>

On 8/3/15 11:22 AM, Murali Karicheri wrote:
> On 08/03/2015 02:11 PM, Murali Karicheri wrote:
>> Currently the MDIO clock is pointing to clkpa instead of clkcpgmac.
>> MDIO is part of the ethss and the clock should be clkcpgmac.
>>
>> Signed-off-by: Murali Karicheri <m-karicheri2 at ti.com>
>> ---
>>   arch/arm/boot/dts/keystone.dtsi | 2 +-
>>   1 file changed, 1 insertion(+), 1 deletion(-)
>>
>> diff --git a/arch/arm/boot/dts/keystone.dtsi
>> b/arch/arm/boot/dts/keystone.dtsi
>> index e7a6f6d..6245a17 100644
>> --- a/arch/arm/boot/dts/keystone.dtsi
>> +++ b/arch/arm/boot/dts/keystone.dtsi
>> @@ -273,7 +273,7 @@
>>               #size-cells = <0>;
>>               reg        = <0x02090300 0x100>;
>>               status = "disabled";
>> -            clocks = <&clkpa>;
>> +            clocks = <&clkcpgmac>;
>>               clock-names = "fck";
>>               bus_freq    = <2500000>;
>>           };
>>
> Santosh,
>
> This is a big fix and needs to go in v4.2-rc. So please review and apply
> asap. v4.2 is the first release that has netcp driver fully functional
> and I want to fix as many known bugs as possible.
>
Do you have more fixes ? If yes, please post them so that I can include
them along with these two. I will try to send them up next week.

Thanks !!

Regards,
Santosh


From m-karicheri2 at ti.com  Mon Aug  3 11:50:20 2015
From: m-karicheri2 at ti.com (Murali Karicheri)
Date: Mon, 3 Aug 2015 14:50:20 -0400
Subject: [PATCH 1/2] ARM: dts: keystone: fix the clock node for mdio
In-Reply-To: <55BFB32C.6080201@oracle.com>
References: <1438625518-21315-1-git-send-email-m-karicheri2@ti.com>
 <55BFB15B.8040207@ti.com> <55BFB32C.6080201@oracle.com>
Message-ID: <55BFB7EC.4060408@ti.com>

On 08/03/2015 02:30 PM, santosh.shilimkar at oracle.com wrote:
> On 8/3/15 11:22 AM, Murali Karicheri wrote:
>> On 08/03/2015 02:11 PM, Murali Karicheri wrote:
>>> Currently the MDIO clock is pointing to clkpa instead of clkcpgmac.
>>> MDIO is part of the ethss and the clock should be clkcpgmac.
>>>
>>> Signed-off-by: Murali Karicheri <m-karicheri2 at ti.com>
>>> ---
>>>   arch/arm/boot/dts/keystone.dtsi | 2 +-
>>>   1 file changed, 1 insertion(+), 1 deletion(-)
>>>
>>> diff --git a/arch/arm/boot/dts/keystone.dtsi
>>> b/arch/arm/boot/dts/keystone.dtsi
>>> index e7a6f6d..6245a17 100644
>>> --- a/arch/arm/boot/dts/keystone.dtsi
>>> +++ b/arch/arm/boot/dts/keystone.dtsi
>>> @@ -273,7 +273,7 @@
>>>               #size-cells = <0>;
>>>               reg        = <0x02090300 0x100>;
>>>               status = "disabled";
>>> -            clocks = <&clkpa>;
>>> +            clocks = <&clkcpgmac>;
>>>               clock-names = "fck";
>>>               bus_freq    = <2500000>;
>>>           };
>>>
>> Santosh,
>>
>> This is a big fix and needs to go in v4.2-rc. So please review and apply
>> asap. v4.2 is the first release that has netcp driver fully functional
>> and I want to fix as many known bugs as possible.
>>
> Do you have more fixes ? If yes, please post them so that I can include
> them along with these two. I will try to send them up next week.

I think we have got most of the know issues fixed in the netcp driver 
and dts for v4.2-rc. Another lingering issue is the one with multiple 
clock handling not supported in run time pm API causing us to use the 
work around 'clk_ignore_unused'. Probably this needs to be addressed in 
the future as fixing this is not trivial. Generic PD support would 
partially solve the issue for Keystone, but also needs to handle 
multiple clocks for keystone.

Another option is to  fix the NetCP and QMSS/KNAV driver for now in 
v4.0-rc using explicit clock APIs so that we don't have to use 
'clk_ignore_unused'. And then migrate all of the drivers to run time PM 
API later when proper framework is implemented along with K2G support. 
Does this make sense?

Anyways, please submit these patches at your earliest opportunity.

Thanks

Murali

>
> Thanks !!
>
> Regards,
> Santosh
>
>


-- 
Murali Karicheri
Linux Kernel, Keystone


From linux.amoon at gmail.com  Mon Aug  3 11:52:00 2015
From: linux.amoon at gmail.com (Anand Moon)
Date: Tue, 4 Aug 2015 00:22:00 +0530
Subject: [PATCH 1/2] mfd: s2mps11: Add manual shutdown method for Odroid
 XU3
In-Reply-To: <1438605447-6836-2-git-send-email-k.kozlowski.k@gmail.com>
References: <1438605447-6836-1-git-send-email-k.kozlowski.k@gmail.com>
 <1438605447-6836-2-git-send-email-k.kozlowski.k@gmail.com>
Message-ID: <CANAwSgSSdiTWDhkeGgYtPzWXDJ8EpD6YN_W05W6GEyF4Y4AFng@mail.gmail.com>

Hi Krzysztof,

On 3 August 2015 at 18:07, Krzysztof Kozlowski <k.kozlowski.k at gmail.com> wrote:
> On Odroid XU3 board (with S2MPS11 PMIC) the PWRHOLD bit in CTRL1
> register must be manually set to 0 before initiating power off sequence.
>
> One of usual power down methods for Exynos based devices looks like:
> 1. PWRHOLD pin of PMIC is connected to PSHOLD of Exynos.
> 2. Exynos holds up this pin during system operation.
> 3. ACOKB pin of PMIC is pulled up to VBATT and optionally to pin in
>    other device.
> 4. When PWRHOLD/PSHOLD goes low, the PMIC will turn off the power if
>    ACOKB goes high.
>
> On Odroid XU3 family the difference is in (3) - the ACOKB is grounded.
> This means that PMIC must manually set PWRHOLD field to low and then
> wait for signal from Application Processor (the usual change in
> PWRHOLD/PSHOLD pin will actually cut off the power).
>
> The patch adds respective binding allowing Odroid XU3 device to be
> powered off.
>
> Signed-off-by: Krzysztof Kozlowski <k.kozlowski.k at gmail.com>
> Reported-by: Anand Moon <linux.amoon at gmail.com>
>
> ---
>
> Patch is losely based on patch in Hardkernel repository [0] and previous
> work of Anand Moon [1].
>
> [0] https://github.com/hardkernel/linux/commit/6897e62ba328bd1c8c095d918101863250cd73e7
> [1] http://www.spinics.net/lists/linux-samsung-soc/msg45959.html
> ---
>  Documentation/devicetree/bindings/mfd/s2mps11.txt |  4 +++
>  drivers/mfd/sec-core.c                            | 31 +++++++++++++++++++++++
>  include/linux/mfd/samsung/core.h                  |  2 ++
>  include/linux/mfd/samsung/s2mps11.h               |  1 +
>  4 files changed, 38 insertions(+)
>
> diff --git a/Documentation/devicetree/bindings/mfd/s2mps11.txt b/Documentation/devicetree/bindings/mfd/s2mps11.txt
> index 57a045016fca..90eaef393325 100644
> --- a/Documentation/devicetree/bindings/mfd/s2mps11.txt
> +++ b/Documentation/devicetree/bindings/mfd/s2mps11.txt
> @@ -15,6 +15,10 @@ Optional properties:
>  - interrupt-parent: Specifies the phandle of the interrupt controller to which
>    the interrupts from s2mps11 are delivered to.
>  - interrupts: Interrupt specifiers for interrupt sources.
> +- samsung,s2mps11-acokb-ground: Indicates that ACOKB pin of S2MPS11 PMIC is
> +  connected to the ground so the PMIC must manually set PWRHOLD bit in CTRL1
> +  register to turn off the power. Usually the ACOKB is pulled up to VBATT so
> +  when PWRHOLD pin goes low, the rising ACOKB will trigger power off.
>
>  Optional nodes:
>  - clocks: s2mps11, s2mps13 and s5m8767 provide three(AP/CP/BT) buffered 32.768
> diff --git a/drivers/mfd/sec-core.c b/drivers/mfd/sec-core.c
> index d206a3e8fe87..a56ab2102a32 100644
> --- a/drivers/mfd/sec-core.c
> +++ b/drivers/mfd/sec-core.c
> @@ -278,6 +278,8 @@ static struct sec_platform_data *sec_pmic_i2c_parse_dt_pdata(
>          * not parsed here.
>          */
>
> +       pd->manual_poweroff = of_property_read_bool(dev->of_node,
> +                                               "samsung,s2mps11-acokb-ground");
>         return pd;
>  }
>  #else
> @@ -440,6 +442,34 @@ static int sec_pmic_remove(struct i2c_client *i2c)
>         return 0;
>  }
>
> +static void sec_pmic_shutdown(struct i2c_client *i2c)
> +{
> +       struct sec_pmic_dev *sec_pmic = i2c_get_clientdata(i2c);
> +       unsigned int reg, mask;
> +
> +       if (!sec_pmic->pdata->manual_poweroff)
> +               return;
> +
> +       switch (sec_pmic->device_type) {
> +       case S2MPS11X:
> +               reg = S2MPS11_REG_CTRL1;
> +               mask = S2MPS11_CTRL1_PWRHOLD_MASK;
> +               break;
> +       default:
> +               /*
> +                * Currently only one board with S2MPS11 needs this, so just
> +                * ignore the rest.
> +                */
> +               dev_warn(sec_pmic->dev,
> +                       "Unsupported device %lu for manual power off\n",
> +                       sec_pmic->device_type);
> +               return;
> +       }
> +
> +       regmap_update_bits(sec_pmic->regmap_pmic, reg, mask, 0);
> +}
> +
> +
>  #ifdef CONFIG_PM_SLEEP
>  static int sec_pmic_suspend(struct device *dev)
>  {
> @@ -491,6 +521,7 @@ static struct i2c_driver sec_pmic_driver = {
>         },
>         .probe = sec_pmic_probe,
>         .remove = sec_pmic_remove,
> +       .shutdown = sec_pmic_shutdown,
>         .id_table = sec_pmic_id,
>  };
>
> diff --git a/include/linux/mfd/samsung/core.h b/include/linux/mfd/samsung/core.h
> index 75115384f3fc..aa78957e092f 100644
> --- a/include/linux/mfd/samsung/core.h
> +++ b/include/linux/mfd/samsung/core.h
> @@ -132,6 +132,8 @@ struct sec_platform_data {
>         int                             buck2_init;
>         int                             buck3_init;
>         int                             buck4_init;
> +       /* Whether or not manually set PWRHOLD to low during shutdown. */
> +       bool                            manual_poweroff;
>  };
>
>  /**
> diff --git a/include/linux/mfd/samsung/s2mps11.h b/include/linux/mfd/samsung/s2mps11.h
> index 7981a9d77d3f..b288965e8101 100644
> --- a/include/linux/mfd/samsung/s2mps11.h
> +++ b/include/linux/mfd/samsung/s2mps11.h
> @@ -179,6 +179,7 @@ enum s2mps11_regulators {
>  #define S2MPS11_BUCK_N_VOLTAGES (S2MPS11_BUCK_VSEL_MASK + 1)
>  #define S2MPS11_RAMP_DELAY     25000           /* uV/us */
>
> +#define S2MPS11_CTRL1_PWRHOLD_MASK     BIT(4)
>
>  #define S2MPS11_BUCK2_RAMP_SHIFT       6
>  #define S2MPS11_BUCK34_RAMP_SHIFT      4
> --
> 2.1.4
>
Thanks. Tested on Odroid-XU3 board.

Tested-by: Anand Moon <linux.amoon at gmail.com>


From linux at arm.linux.org.uk  Mon Aug  3 12:07:00 2015
From: linux at arm.linux.org.uk (Russell King - ARM Linux)
Date: Mon, 3 Aug 2015 20:07:00 +0100
Subject: [PATCH 1/2] drivers: PL061: add support for platform driver
 probing
In-Reply-To: <1438614811.2338188.346456017.5D258EC5@webmail.messagingengine.com>
References: <1438585198-8764-1-git-send-email-zhaoshenglong@huawei.com>
 <1438585198-8764-2-git-send-email-zhaoshenglong@huawei.com>
 <CACRpkdY6ZfB-gnnr49He+BYELy4fhiV0g5jkEHhyVsJOc_SBFw@mail.gmail.com>
 <1438614811.2338188.346456017.5D258EC5@webmail.messagingengine.com>
Message-ID: <20150803190700.GK7557@n2100.arm.linux.org.uk>

On Mon, Aug 03, 2015 at 04:13:31PM +0100, Graeme Gregory wrote:
> 
> 
> On Mon, 3 Aug 2015, at 01:40 PM, Linus Walleij wrote:
> > On Mon, Aug 3, 2015 at 8:59 AM, Shannon Zhao <zhaoshenglong at huawei.com>
> > wrote:
> > 
> > > From: Shannon Zhao <shannon.zhao at linaro.org>
> > >
> > > Since PL061 currently only supports AMBA driver, to support using GPIO
> > > PL061 by DT or ACPI, it needs to add support for platform driver.
> > > A DT binding is provided with this patch, ACPI support is added in a
> > > separate one.
> > >
> > > Signed-off-by: Shannon Zhao <zhaoshenglong at huawei.com>
> > > Signed-off-by: Shannon Zhao <shannon.zhao at linaro.org>
> > 
> > I already stated in 0/2 what the problem is with this, and it's obviously
> > adding
> > a huge codechunk, very similar to the AMBA probe path.
> > 
> > We need to investigate if ACPI can just spawn AMBA/PrimeCell type devices
> > instead.
> > 
> AMBA DT support is a hideous hack, we had kind of hoped to avoid doing
> that in ACPI.
> 
> If you notice ARM already updated pl011 driver to support platform
> device type probing this seems to be the way to go.

As the AMBA bus maintainer, NAK on that.

-- 
FTTC broadband for 0.8mile line: currently at 10.5Mbps down 400kbps up
according to speedtest.net.


From hongzhou.yang at mediatek.com  Mon Aug  3 12:08:26 2015
From: hongzhou.yang at mediatek.com (Hongzhou Yang)
Date: Mon, 3 Aug 2015 12:08:26 -0700
Subject: [PATCH] pinctrl/mediatek: fix spelling mistake in dev_err error
 message
In-Reply-To: <1438557045-3590-1-git-send-email-colin.king@canonical.com>
References: <1438557045-3590-1-git-send-email-colin.king@canonical.com>
Message-ID: <1438628906.32493.1.camel@mussux00.eus.mediatek.inc>

On Mon, 2015-08-03 at 00:10 +0100, Colin King wrote:
> From: Colin Ian King <colin.king at canonical.com>
> 
> Trivial change, fix spelling mistake 'invaild' -> 'invalid' in
> dev_err message.
> 
> Signed-off-by: Colin Ian King <colin.king at canonical.com>
> ---
>  drivers/pinctrl/mediatek/pinctrl-mtk-common.c | 2 +-
>  1 file changed, 1 insertion(+), 1 deletion(-)
> 
> diff --git a/drivers/pinctrl/mediatek/pinctrl-mtk-common.c b/drivers/pinctrl/mediatek/pinctrl-mtk-common.c
> index ad1ea16..5af5441 100644
> --- a/drivers/pinctrl/mediatek/pinctrl-mtk-common.c
> +++ b/drivers/pinctrl/mediatek/pinctrl-mtk-common.c
> @@ -702,7 +702,7 @@ static int mtk_pmx_set_mux(struct pinctrl_dev *pctldev,
>  
>  	ret = mtk_pctrl_is_function_valid(pctl, g->pin, function);
>  	if (!ret) {
> -		dev_err(pctl->dev, "invaild function %d on group %d .\n",
> +		dev_err(pctl->dev, "invalid function %d on group %d .\n",
>  				function, group);
>  		return -EINVAL;
>  	}

Hi Colin,

Thank you very much.

Acked-by: Hongzhou Yang <hongzhou.yang at mediatek.com>

Hongzhou



From linux at arm.linux.org.uk  Mon Aug  3 12:09:35 2015
From: linux at arm.linux.org.uk (Russell King - ARM Linux)
Date: Mon, 3 Aug 2015 20:09:35 +0100
Subject: [PATCH 0/2] drivers: PL061: Add platform driver probing support
In-Reply-To: <20150803162623.GB30867@kroah.com>
References: <1438585198-8764-1-git-send-email-zhaoshenglong@huawei.com>
 <20150803075848.GH7557@n2100.arm.linux.org.uk>
 <55BF33AD.5040502@huawei.com>
 <20150803094923.GI7557@n2100.arm.linux.org.uk>
 <20150803162623.GB30867@kroah.com>
Message-ID: <20150803190935.GL7557@n2100.arm.linux.org.uk>

On Mon, Aug 03, 2015 at 09:26:23AM -0700, Greg Kroah-Hartman wrote:
> On Mon, Aug 03, 2015 at 10:49:23AM +0100, Russell King - ARM Linux wrote:
> > On Mon, Aug 03, 2015 at 05:26:05PM +0800, Shannon Zhao wrote:
> > > Hi Russell,
> > > 
> > > On 2015/8/3 15:58, Russell King - ARM Linux wrote:
> > > > On Mon, Aug 03, 2015 at 02:59:56PM +0800, Shannon Zhao wrote:
> > > >> From: Shannon Zhao <shannon.zhao at linaro.org>
> > > >>
> > > >> According to ACPI SPEC, it supports ARM boards to use "GPIO-signaled
> > > >> ACPI Events". These events can be used for input events. And to QEMU, it
> > > >> uses GPIO PL061 controller for input events.
> > > >>
> > > >> These two patches add platform driver support for PL061 probed by DT or
> > > >> ACPI.
> > > > 
> > > > This certainly is incorrect for DT, and is probably wrong for ACPI too.
> > > > DT creates amba devices, so binds via the amba device driver.
> > > > 
> > > 
> > > Oh, sorry. The changes for DT are not necessary. But for ACPI I think it
> > > needs to convert pl061 to platform device since ACPI doesn't support
> > > AMBA devices. The Pl011 also does the same thing to support ACPI
> > > probing. See drivers/tty/serial/amba-pl011.c
> > 
> > Maybe rather than having every AMBA driver also converted to a platform
> > driver (which GregKH hates) maybe ACPI should support the AMBA bus
> > instead?
> > 
> > Greg?
> 
> The ACPI developers have been doing work to allow a driver to handle
> getting the resources from either DT or ACPI no matter what bus it is
> on, so converting anything to a platform driver shouldn't be needed.
> 
> but I don't really know the details here, and this isn't being sent to
> the ACPI mailing list, so I don't know what to suggest...

Greg,

You're the one who's said many times that you'd like to see platform
devices and platform device drivers to go away.  So, when I give you
the opportunity to comment on platform devices being used to augment
existing device drivers such as the AMBA bus drivers (which you've
also previously said is a more preferable way to use the driver model)
why not support that view?

Right now, there seems to be a move to convert _all_ AMBA device drivers
to become dual-drivers: an amba bus driver and a platform driver.  Is
that something you really want to see, irrespective of ACPI issues?

-- 
FTTC broadband for 0.8mile line: currently at 10.5Mbps down 400kbps up
according to speedtest.net.


From santosh.shilimkar at oracle.com  Mon Aug  3 12:00:27 2015
From: santosh.shilimkar at oracle.com (santosh.shilimkar at oracle.com)
Date: Mon, 03 Aug 2015 12:00:27 -0700
Subject: [PATCH 1/2] ARM: dts: keystone: fix the clock node for mdio
In-Reply-To: <55BFB7EC.4060408@ti.com>
References: <1438625518-21315-1-git-send-email-m-karicheri2@ti.com>
 <55BFB15B.8040207@ti.com> <55BFB32C.6080201@oracle.com>
 <55BFB7EC.4060408@ti.com>
Message-ID: <55BFBA4B.6070406@oracle.com>



On 8/3/15 11:50 AM, Murali Karicheri wrote:
> On 08/03/2015 02:30 PM, santosh.shilimkar at oracle.com wrote:
>> On 8/3/15 11:22 AM, Murali Karicheri wrote:
>>> On 08/03/2015 02:11 PM, Murali Karicheri wrote:
>>>> Currently the MDIO clock is pointing to clkpa instead of clkcpgmac.
>>>> MDIO is part of the ethss and the clock should be clkcpgmac.
>>>>
>>>> Signed-off-by: Murali Karicheri <m-karicheri2 at ti.com>
>>>> ---
>>>>   arch/arm/boot/dts/keystone.dtsi | 2 +-
>>>>   1 file changed, 1 insertion(+), 1 deletion(-)
>>>>
>>>> diff --git a/arch/arm/boot/dts/keystone.dtsi
>>>> b/arch/arm/boot/dts/keystone.dtsi
>>>> index e7a6f6d..6245a17 100644
>>>> --- a/arch/arm/boot/dts/keystone.dtsi
>>>> +++ b/arch/arm/boot/dts/keystone.dtsi
>>>> @@ -273,7 +273,7 @@
>>>>               #size-cells = <0>;
>>>>               reg        = <0x02090300 0x100>;
>>>>               status = "disabled";
>>>> -            clocks = <&clkpa>;
>>>> +            clocks = <&clkcpgmac>;
>>>>               clock-names = "fck";
>>>>               bus_freq    = <2500000>;
>>>>           };
>>>>
>>> Santosh,
>>>
>>> This is a big fix and needs to go in v4.2-rc. So please review and apply
>>> asap. v4.2 is the first release that has netcp driver fully functional
>>> and I want to fix as many known bugs as possible.
>>>
>> Do you have more fixes ? If yes, please post them so that I can include
>> them along with these two. I will try to send them up next week.
>
> I think we have got most of the know issues fixed in the netcp driver
> and dts for v4.2-rc. Another lingering issue is the one with multiple
> clock handling not supported in run time pm API causing us to use the
> work around 'clk_ignore_unused'. Probably this needs to be addressed in
> the future as fixing this is not trivial. Generic PD support would
> partially solve the issue for Keystone, but also needs to handle
> multiple clocks for keystone.
>
Yeah. I was also wondering on what happened to that work which was
active at some point of time.

> Another option is to  fix the NetCP and QMSS/KNAV driver for now in
> v4.0-rc using explicit clock APIs so that we don't have to use
> 'clk_ignore_unused'. And then migrate all of the drivers to run time PM
> API later when proper framework is implemented along with K2G support.
> Does this make sense?
>
Multiple clock node support work which was started needs to be revived.
Direct clock isn't the way to go about it.

> Anyways, please submit these patches at your earliest opportunity.
>
Sure.

Regards,
Santosh


From albeu at free.fr  Mon Aug  3 12:12:30 2015
From: albeu at free.fr (Alban Bedel)
Date: Mon,  3 Aug 2015 21:12:30 +0200
Subject: [PATCH] usb: ehci-platform: Fix using multiple controllers from OF
Message-ID: <1438629150-11662-1-git-send-email-albeu@free.fr>

When using OF defined controllers the platform data struct is shared
between all devices, so it can't be used for device specific settings.
However it is currently used for the OF properties
needs-reset-on-resume and has-transaction-translator.

To fix this issue move setting hcd->has_tt to the probe and
move pdata->reset_on_resume to the private data.

Signed-off-by: Alban Bedel <albeu at free.fr>
---
 drivers/usb/host/ehci-platform.c | 13 +++++++++----
 1 file changed, 9 insertions(+), 4 deletions(-)

diff --git a/drivers/usb/host/ehci-platform.c b/drivers/usb/host/ehci-platform.c
index 2593def..40d029e 100644
--- a/drivers/usb/host/ehci-platform.c
+++ b/drivers/usb/host/ehci-platform.c
@@ -45,6 +45,7 @@ struct ehci_platform_priv {
 	struct reset_control *rst;
 	struct phy **phys;
 	int num_phys;
+	bool reset_on_resume;
 };
 
 static const char hcd_name[] = "ehci-platform";
@@ -56,7 +57,6 @@ static int ehci_platform_reset(struct usb_hcd *hcd)
 	struct ehci_hcd *ehci = hcd_to_ehci(hcd);
 	int retval;
 
-	hcd->has_tt = pdata->has_tt;
 	ehci->has_synopsys_hc_bug = pdata->has_synopsys_hc_bug;
 
 	if (pdata->pre_setup) {
@@ -193,11 +193,11 @@ static int ehci_platform_probe(struct platform_device *dev)
 
 		if (of_property_read_bool(dev->dev.of_node,
 					  "needs-reset-on-resume"))
-			pdata->reset_on_resume = 1;
+			priv->reset_on_resume = 1;
 
 		if (of_property_read_bool(dev->dev.of_node,
 					  "has-transaction-translator"))
-			pdata->has_tt = 1;
+			hcd->has_tt = 1;
 
 		priv->num_phys = of_count_phandle_with_args(dev->dev.of_node,
 				"phys", "#phy-cells");
@@ -247,6 +247,10 @@ static int ehci_platform_probe(struct platform_device *dev)
 		ehci->big_endian_desc = 1;
 	if (pdata->big_endian_mmio)
 		ehci->big_endian_mmio = 1;
+	if (pdata->has_tt)
+		hcd->has_tt = 1;
+	if (pdata->reset_on_resume)
+		priv->reset_on_resume = true;
 
 #ifndef CONFIG_USB_EHCI_BIG_ENDIAN_MMIO
 	if (ehci->big_endian_mmio) {
@@ -359,6 +363,7 @@ static int ehci_platform_resume(struct device *dev)
 	struct usb_ehci_pdata *pdata = dev_get_platdata(dev);
 	struct platform_device *pdev =
 		container_of(dev, struct platform_device, dev);
+	struct ehci_platform_priv *priv = hcd_to_ehci_priv(hcd);
 
 	if (pdata->power_on) {
 		int err = pdata->power_on(pdev);
@@ -366,7 +371,7 @@ static int ehci_platform_resume(struct device *dev)
 			return err;
 	}
 
-	ehci_resume(hcd, pdata->reset_on_resume);
+	ehci_resume(hcd, priv->reset_on_resume);
 	return 0;
 }
 #endif /* CONFIG_PM_SLEEP */
-- 
2.0.0



From linux at arm.linux.org.uk  Mon Aug  3 12:13:40 2015
From: linux at arm.linux.org.uk (Russell King - ARM Linux)
Date: Mon, 3 Aug 2015 20:13:40 +0100
Subject: [PATCH] ARM/PCI: set MPS before pci_bus_add_devices()
In-Reply-To: <1437514519-18545-1-git-send-email-m-karicheri2@ti.com>
References: <1437514519-18545-1-git-send-email-m-karicheri2@ti.com>
Message-ID: <20150803191340.GM7557@n2100.arm.linux.org.uk>

On Tue, Jul 21, 2015 at 05:35:19PM -0400, Murali Karicheri wrote:
> The MPS configuration should be done *before* pci_bus_add_devices().
> After pci_bus_add_devices(), drivers may be bound to devices, and
> the PCI core shouldn't touch device configuration while a driver
> owns the device.
> 
> Signed-off-by: Murali Karicheri <m-karicheri2 at ti.com>
> Reported-by: Bjorn Helgaas <bhelgaas at google.com>
> ---
>  arch/arm/kernel/bios32.c | 19 +++++--------------
>  1 file changed, 5 insertions(+), 14 deletions(-)
> 
> diff --git a/arch/arm/kernel/bios32.c b/arch/arm/kernel/bios32.c
> index fcbbbb1..17efde7 100644
> --- a/arch/arm/kernel/bios32.c
> +++ b/arch/arm/kernel/bios32.c
> @@ -520,7 +520,8 @@ void pci_common_init_dev(struct device *parent, struct hw_pci *hw)
>  	list_for_each_entry(sys, &head, node) {
>  		struct pci_bus *bus = sys->bus;
>  
> -		if (!pci_has_flag(PCI_PROBE_ONLY)) {
> +		if (bus && !pci_has_flag(PCI_PROBE_ONLY)) {

Let's get rid of that useless check.  bus can't be NULL here.

In the original code (below) if bus was NULL, then we would've already
oopsed before we got here.  As we don't oops here, no one is ever
seeing it being NULL, so the test is redundant.

> -	list_for_each_entry(sys, &head, node) {
> -		struct pci_bus *bus = sys->bus;
> -
> -		/* Configure PCI Express settings */
> -		if (bus && !pci_has_flag(PCI_PROBE_ONLY)) {

Thanks.

-- 
FTTC broadband for 0.8mile line: currently at 10.5Mbps down 400kbps up
according to speedtest.net.


From sergei.shtylyov at cogentembedded.com  Mon Aug  3 12:23:42 2015
From: sergei.shtylyov at cogentembedded.com (Sergei Shtylyov)
Date: Mon, 3 Aug 2015 22:23:42 +0300
Subject: [PATCH] usb: ehci-platform: Fix using multiple controllers from OF
In-Reply-To: <1438629150-11662-1-git-send-email-albeu@free.fr>
References: <1438629150-11662-1-git-send-email-albeu@free.fr>
Message-ID: <55BFBFBE.5050905@cogentembedded.com>

On 08/03/2015 10:12 PM, Alban Bedel wrote:

> When using OF defined controllers the platform data struct is shared
> between all devices, so it can't be used for device specific settings.
> However it is currently used for the OF properties
> needs-reset-on-resume and has-transaction-translator.

> To fix this issue move setting hcd->has_tt to the probe and
> move pdata->reset_on_resume to the private data.

> Signed-off-by: Alban Bedel <albeu at free.fr>
> ---
>   drivers/usb/host/ehci-platform.c | 13 +++++++++----
>   1 file changed, 9 insertions(+), 4 deletions(-)

> diff --git a/drivers/usb/host/ehci-platform.c b/drivers/usb/host/ehci-platform.c
> index 2593def..40d029e 100644
> --- a/drivers/usb/host/ehci-platform.c
> +++ b/drivers/usb/host/ehci-platform.c
> @@ -45,6 +45,7 @@ struct ehci_platform_priv {
>   	struct reset_control *rst;
>   	struct phy **phys;
>   	int num_phys;
> +	bool reset_on_resume;
>   };
>
>   static const char hcd_name[] = "ehci-platform";
[...]
> @@ -193,11 +193,11 @@ static int ehci_platform_probe(struct platform_device *dev)
>
>   		if (of_property_read_bool(dev->dev.of_node,
>   					  "needs-reset-on-resume"))
> -			pdata->reset_on_resume = 1;
> +			priv->reset_on_resume = 1;

    'true' since the typi is 'bool'.

[...]

MBR, Sergei



From sboyd at codeaurora.org  Mon Aug  3 12:24:27 2015
From: sboyd at codeaurora.org (Stephen Boyd)
Date: Mon, 3 Aug 2015 12:24:27 -0700
Subject: [PATCH v7 01/13] clk: qcom: Add support for GDSCs
In-Reply-To: <1438076046-4706-2-git-send-email-rnayak@codeaurora.org>
References: <1438076046-4706-1-git-send-email-rnayak@codeaurora.org>
 <1438076046-4706-2-git-send-email-rnayak@codeaurora.org>
Message-ID: <20150803192427.GA7096@codeaurora.org>

On 07/28, Rajendra Nayak wrote:
> +
> +#define PWR_ON_MASK		BIT(31)
> +#define EN_REST_WAIT_MASK	GENMASK(23, 20)
> +#define EN_FEW_WAIT_MASK	GENMASK(19, 16)
> +#define CLK_DIS_WAIT_MASK	GENMASK(15, 12)

This trips up some static checker...

drivers/clk/qcom/gdsc.c:234:53: warning: cast truncates bits from
constant value (fffffffffff006 becomes fffff006)

So I think we can use GENMASK_ULL here instead.

-- 
Qualcomm Innovation Center, Inc. is a member of Code Aurora Forum,
a Linux Foundation Collaborative Project


From sebastian.hesselbarth at gmail.com  Mon Aug  3 12:24:44 2015
From: sebastian.hesselbarth at gmail.com (Sebastian Hesselbarth)
Date: Mon,  3 Aug 2015 21:24:44 +0200
Subject: [GIT PULL] ARM: berlin: Initial Marvell Berlin ARM64 support
Message-ID: <1438629886-6390-1-git-send-email-sebastian.hesselbarth@gmail.com>

Hi Arnd, Kevin, Olof,

this is initial Marvell Berlin4CT ARM64 support for v4.3. It contains minimum SoC
dtsi and basic dts for the development board. The patches have been posted by
Marvell's Jisheng Zhang a while ago on the lists.

Please pull.

The following changes since commit d770e558e21961ad6cfdf0ff7df0eb5d7d4f0754:

  Linux 4.2-rc1 (2015-07-05 11:01:52 -0700)

are available in the git repository at:

  git://git.infradead.org/users/hesselba/linux-berlin.git tags/berlin64-for-v4.3-1

for you to fetch changes up to d93ac74ad150c89f2d0a3b90754cbccdc6ab102c:

  arm64: dts: Add dts files for Marvell Berlin4CT SoC (2015-08-03 20:45:54 +0200)

----------------------------------------------------------------
Initial support for Marvell Berlin4CT ARM64 SoC

----------------------------------------------------------------
Jisheng Zhang (1):
      arm64: dts: Add dts files for Marvell Berlin4CT SoC

 arch/arm64/boot/dts/Makefile                  |   1 +
 arch/arm64/boot/dts/marvell/Makefile          |   5 +
 arch/arm64/boot/dts/marvell/berlin4ct-dmp.dts |  66 +++++++++++
 arch/arm64/boot/dts/marvell/berlin4ct.dtsi    | 164 ++++++++++++++++++++++++++
 4 files changed, 236 insertions(+)
 create mode 100644 arch/arm64/boot/dts/marvell/Makefile
 create mode 100644 arch/arm64/boot/dts/marvell/berlin4ct-dmp.dts
 create mode 100644 arch/arm64/boot/dts/marvell/berlin4ct.dtsi


From sebastian.hesselbarth at gmail.com  Mon Aug  3 12:24:46 2015
From: sebastian.hesselbarth at gmail.com (Sebastian Hesselbarth)
Date: Mon,  3 Aug 2015 21:24:46 +0200
Subject: [PATCH 2/2] arm64: Enable Marvell Berlin SoC family in defconfig
In-Reply-To: <1438629886-6390-1-git-send-email-sebastian.hesselbarth@gmail.com>
References: <1438629886-6390-1-git-send-email-sebastian.hesselbarth@gmail.com>
Message-ID: <1438629886-6390-3-git-send-email-sebastian.hesselbarth@gmail.com>

From: Jisheng Zhang <jszhang at marvell.com>

Enable Marvell Berlin SoC family in arm64 defconfig.

Signed-off-by: Jisheng Zhang <jszhang at marvell.com>
Signed-off-by: Sebastian Hesselbarth <sebastian.hesselbarth at gmail.com>
---
Also discussed with Olof on IRC, this is the defconfig changes singled
out from Jisheng's original patch.

Sebastian
---
 arch/arm64/configs/defconfig | 1 +
 1 file changed, 1 insertion(+)

diff --git a/arch/arm64/configs/defconfig b/arch/arm64/configs/defconfig
index f38c94f1d898..9e8978c35772 100644
--- a/arch/arm64/configs/defconfig
+++ b/arch/arm64/configs/defconfig
@@ -31,6 +31,7 @@ CONFIG_MODULES=y
 CONFIG_MODULE_UNLOAD=y
 # CONFIG_BLK_DEV_BSG is not set
 # CONFIG_IOSCHED_DEADLINE is not set
+CONFIG_ARCH_BERLIN=y
 CONFIG_ARCH_EXYNOS7=y
 CONFIG_ARCH_FSL_LS2085A=y
 CONFIG_ARCH_HISI=y
-- 
2.1.0



From sebastian.hesselbarth at gmail.com  Mon Aug  3 12:24:45 2015
From: sebastian.hesselbarth at gmail.com (Sebastian Hesselbarth)
Date: Mon,  3 Aug 2015 21:24:45 +0200
Subject: [PATCH 1/2] arm64: Enable Marvell Berlin SoC family in Kconfig
In-Reply-To: <1438629886-6390-1-git-send-email-sebastian.hesselbarth@gmail.com>
References: <1438629886-6390-1-git-send-email-sebastian.hesselbarth@gmail.com>
Message-ID: <1438629886-6390-2-git-send-email-sebastian.hesselbarth@gmail.com>

From: Jisheng Zhang <jszhang at marvell.com>

This patch introduces ARCH_BERLIN to enable Marvell Berlin SoC family in
Kconfig.

Signed-off-by: Jisheng Zhang <jszhang at marvell.com>
Signed-off-by: Sebastian Hesselbarth <sebastian.hesselbarth at gmail.com>
---
As discussed with Olof on IRC, this is Jisheng's Kconfig patch for
ARM64 Berlin. Olof agreed to rework this to finally land in
Kconfig.platforms, i.e. after
  eed6b3eb20b9 ("arm64: Split out platform options to separate Kconfig")

Sebastian
---
 arch/arm64/Kconfig | 6 ++++++
 1 file changed, 6 insertions(+)

diff --git a/arch/arm64/Kconfig b/arch/arm64/Kconfig
index 0f6edb14b7e4..d5c615312d87 100644
--- a/arch/arm64/Kconfig
+++ b/arch/arm64/Kconfig
@@ -162,6 +162,12 @@ source "kernel/Kconfig.freezer"
 
 menu "Platform selection"
 
+config ARCH_BERLIN
+	bool "Marvell Berlin SoC Family"
+	select DW_APB_ICTL
+	help
+	  This enables support for Marvell Berlin SoC Family
+
 config ARCH_EXYNOS
 	bool
 	help
-- 
2.1.0



From christoffer.dall at linaro.org  Mon Aug  3 12:39:03 2015
From: christoffer.dall at linaro.org (Christoffer Dall)
Date: Mon, 3 Aug 2015 21:39:03 +0200
Subject: [PATCH 04/18] KVM: ARM64: Add reset and access handlers for
 PMCR_EL0 register
In-Reply-To: <55AD9D89.7010502@linaro.org>
References: <1436149068-3784-1-git-send-email-shannon.zhao@linaro.org>
 <1436149068-3784-5-git-send-email-shannon.zhao@linaro.org>
 <20150716195534.GD14024@cbox> <55A8C0B8.1000101@linaro.org>
 <20150717102133.GN14024@cbox> <55AD9D89.7010502@linaro.org>
Message-ID: <20150803193903.GA4690@cbox>

On Tue, Jul 21, 2015 at 09:16:57AM +0800, Shannon Zhao wrote:
> 
> 
> On 2015/7/17 18:21, Christoffer Dall wrote:
> > On Fri, Jul 17, 2015 at 04:45:44PM +0800, Shannon Zhao wrote:
> >>
> >>
> >> On 2015/7/17 3:55, Christoffer Dall wrote:
> >>> On Mon, Jul 06, 2015 at 10:17:34AM +0800, shannon.zhao at linaro.org wrote:
> >>>> From: Shannon Zhao <shannon.zhao at linaro.org>
> >>>>
> >>>> Add reset handler which gets host value of PMCR_EL0 and make writable
> >>>> bits architecturally UNKNOWN. Add access handler which emulates
> >>>> writing and reading PMCR_EL0 register.
> >>>>
> >>>> Signed-off-by: Shannon Zhao <shannon.zhao at linaro.org>
> >>>> ---
> >>>>  arch/arm64/kvm/sys_regs.c | 41 ++++++++++++++++++++++++++++++++++++++++-
> >>>>  1 file changed, 40 insertions(+), 1 deletion(-)
> >>>>
> >>>> diff --git a/arch/arm64/kvm/sys_regs.c b/arch/arm64/kvm/sys_regs.c
> >>>> index c370b40..152ee17 100644
> >>>> --- a/arch/arm64/kvm/sys_regs.c
> >>>> +++ b/arch/arm64/kvm/sys_regs.c
> >>>> @@ -33,6 +33,7 @@
> >>>>  #include <asm/kvm_emulate.h>
> >>>>  #include <asm/kvm_host.h>
> >>>>  #include <asm/kvm_mmu.h>
> >>>> +#include <asm/pmu.h>
> >>>>  
> >>>>  #include <trace/events/kvm.h>
> >>>>  
> >>>> @@ -236,6 +237,44 @@ static void reset_mpidr(struct kvm_vcpu *vcpu, const struct sys_reg_desc *r)
> >>>>  	vcpu_sys_reg(vcpu, MPIDR_EL1) = (1ULL << 31) | mpidr;
> >>>>  }
> >>>>  
> >>>> +static void reset_pmcr_el0(struct kvm_vcpu *vcpu, const struct sys_reg_desc *r)
> >>>> +{
> >>>> +	u32 pmcr;
> >>>> +
> >>>> +	asm volatile("mrs %0, pmcr_el0\n" : "=r" (pmcr));
> >>>> +	vcpu_sys_reg(vcpu, PMCR_EL0) = (pmcr & ~ARMV8_PMCR_MASK)
> >>>> +				       | (ARMV8_PMCR_MASK & 0xdecafbad);
> >>>
> >>> You could add a comment that this resets to UNKNOWN as to not make
> >>> people confused about the pseudo-random hex value.
> >>>
> >> Ok.
> >>
> >>> Have we thought about whether we want to tell the guest that it has the
> >>> same PMU as available on the real hardware, or does the virtualization
> >>> layer suggest to us that we should adjust this somehow?
> >>>
> >> I guess here the number of PMU counters is what we can adjust, right?
> >> Are we worried about that the host will run out of counters when guest
> >> and host register lots of events?
> > 
> > that's what I wonder; if perf itself reserves a counter for example,
> > then we'll at best be able to measure with N-1 counters for the guest (N
> > being the number of counters on the physical CPU), so why tell the guest
> > we have N counters?
> > 
> 
> I'm not sure whether perf itself reserves one counter. Here I just pass
> the hardware information to guest.
> 
> > Of course, we can never even be guaranteed to have N-1 counters
> > avaialable either, so maybe the sane choice is just to tell the guest
> > what kind of hardware we have, and then fiddle the best we can with the
> > remaining counters?  After all, correct functionality of the guest
> > doesn't depend on this, it's a best-effort kind of thing...
> > 
> > Thoughts?
> > 
> >> The PMU of cortex-a57 has 6 counters. IIUC, if one of the guest vcpu
> >> process registers 6 events and some host process register 6 events too,
> >> these events will be monitored in real hardware PMU counter when the
> >> related process runs on the cpu. And when other processes are scheduled
> >> to run, it will switch the contexts of PMU counters.
> > 
> > That depends on the way the counters are used by perf I think.  What if
> > you have system wide events?  What if the KVM (vcpu) process itself is
> > being monitored for some events?
> > 
> 
> Not sure what will happen when the number of monitored events is greater
> than counters. I guess the perf layer may balance the events?
> 
I'm not sure either, but we need to have thought about these things, I
suppose.  You should probably look at the code or try it out.

Thanks,
-Christoffer


From stern at rowland.harvard.edu  Mon Aug  3 12:39:45 2015
From: stern at rowland.harvard.edu (Alan Stern)
Date: Mon, 3 Aug 2015 15:39:45 -0400 (EDT)
Subject: [PATCH] usb: ehci-platform: Fix using multiple controllers from OF
In-Reply-To: <1438629150-11662-1-git-send-email-albeu@free.fr>
Message-ID: <Pine.LNX.4.44L0.1508031538370.1667-100000@iolanthe.rowland.org>

On Mon, 3 Aug 2015, Alban Bedel wrote:

> When using OF defined controllers the platform data struct is shared
> between all devices, so it can't be used for device specific settings.
> However it is currently used for the OF properties
> needs-reset-on-resume and has-transaction-translator.
> 
> To fix this issue move setting hcd->has_tt to the probe and
> move pdata->reset_on_resume to the private data.
> 
> Signed-off-by: Alban Bedel <albeu at free.fr>

That's a subtle problem and a good call on your part.

Acked-by: Alan Stern <stern at rowland.harvard.edu>

Alan Stern



From christoffer.dall at linaro.org  Mon Aug  3 12:55:47 2015
From: christoffer.dall at linaro.org (Christoffer Dall)
Date: Mon, 3 Aug 2015 21:55:47 +0200
Subject: [PATCH 07/18] KVM: ARM64: PMU: Add perf event map and introduce
 perf event creating function
In-Reply-To: <55ADA1C7.5040002@linaro.org>
References: <1436149068-3784-1-git-send-email-shannon.zhao@linaro.org>
 <1436149068-3784-8-git-send-email-shannon.zhao@linaro.org>
 <20150717143043.GR14024@cbox> <55ADA1C7.5040002@linaro.org>
Message-ID: <20150803195547.GB4690@cbox>

On Tue, Jul 21, 2015 at 09:35:03AM +0800, Shannon Zhao wrote:
> 
> 
> On 2015/7/17 22:30, Christoffer Dall wrote:
> > On Mon, Jul 06, 2015 at 10:17:37AM +0800, shannon.zhao at linaro.org wrote:
> >> From: Shannon Zhao <shannon.zhao at linaro.org>
> >>
> >> When we use tools like perf on host, perf passes the event type and the
> >> id in this type category to kernel, then kernel will map them to event
> >> number and write this number to PMU PMEVTYPER<n>_EL0 register. While
> >> we're trapping and emulating guest accesses to PMU registers, we get the
> >> event number and map it to the event type and the id reversely.
> > 
> > There's something with the nomenclature that makes this really hard to
> > read.
> > 
> > you mention here: "event type", "the id", and "event number".  The
> > former two I think are perf identifiers, and the latter is the hardware
> > event number, is this right?
> > 
> 
> Yeah, right.
> 

ok, if we can clarify our nomenclature throughout here I think that
would make the patches easier to understand/read.

> >>
> >> Check whether the event type is same with the one to be set.
> > 
> > when?
> > 
> In function kvm_pmu_set_counter_event_type before create a new perf event.

do you mean when the guest configures some counter and we we create a
perf event accordingly?

If so, I think this could be clarified in the commit text.

> 
> >> +	if ((data & ARMV8_EVTYPE_EVENT) == pmc->eventsel)
> >> +		return;
> 
> 
> >> If not,
> >> stop counter to monitor current event and find the event type map id.
> >> According to the bits of data to configure this perf_event attr and
> >> set exclude_host to 1 for guest. Then call perf_event API to create the
> >> corresponding event and save the event pointer.
> >>
> >> Signed-off-by: Shannon Zhao <shannon.zhao at linaro.org>
> >> ---
> >>  include/kvm/arm_pmu.h |   4 ++
> >>  virt/kvm/arm/pmu.c    | 173 ++++++++++++++++++++++++++++++++++++++++++++++++++
> >>  2 files changed, 177 insertions(+)
> >>
> >> diff --git a/include/kvm/arm_pmu.h b/include/kvm/arm_pmu.h
> >> index 27d14ca..1050b24 100644
> >> --- a/include/kvm/arm_pmu.h
> >> +++ b/include/kvm/arm_pmu.h
> >> @@ -45,9 +45,13 @@ struct kvm_pmu {
> >>  
> >>  #ifdef CONFIG_KVM_ARM_PMU
> >>  void kvm_pmu_vcpu_reset(struct kvm_vcpu *vcpu);
> >> +void kvm_pmu_set_counter_event_type(struct kvm_vcpu *vcpu, unsigned long data,
> >> +				    unsigned long select_idx);
> >>  void kvm_pmu_init(struct kvm_vcpu *vcpu);
> >>  #else
> >>  static inline void kvm_pmu_vcpu_reset(struct kvm_vcpu *vcpu) {}
> >> +void kvm_pmu_set_counter_event_type(struct kvm_vcpu *vcpu, unsigned long data,
> >> +				    unsigned long select_idx) {}
> >>  static inline void kvm_pmu_init(struct kvm_vcpu *vcpu) {}
> >>  #endif
> >>  
> >> diff --git a/virt/kvm/arm/pmu.c b/virt/kvm/arm/pmu.c
> >> index dc252d0..50a3c82 100644
> >> --- a/virt/kvm/arm/pmu.c
> >> +++ b/virt/kvm/arm/pmu.c
> >> @@ -18,8 +18,68 @@
> >>  #include <linux/cpu.h>
> >>  #include <linux/kvm.h>
> >>  #include <linux/kvm_host.h>
> >> +#include <linux/perf_event.h>
> >>  #include <kvm/arm_pmu.h>
> >>  
> >> +/* PMU HW events mapping. */
> >> +static struct kvm_pmu_hw_event_map {
> >> +	unsigned eventsel;
> >> +	unsigned event_type;
> >> +} kvm_pmu_hw_events[] = {
> >> +	[0] = { 0x11, PERF_COUNT_HW_CPU_CYCLES },
> >> +	[1] = { 0x08, PERF_COUNT_HW_INSTRUCTIONS },
> >> +	[2] = { 0x04, PERF_COUNT_HW_CACHE_REFERENCES },
> >> +	[3] = { 0x03, PERF_COUNT_HW_CACHE_MISSES },
> >> +	[4] = { 0x10, PERF_COUNT_HW_BRANCH_MISSES },
> >> +};
> >> +
> >> +/* PMU HW cache events mapping. */
> >> +static struct kvm_pmu_hw_cache_event_map {
> >> +	unsigned eventsel;
> >> +	unsigned cache_type;
> >> +	unsigned cache_op;
> >> +	unsigned cache_result;
> >> +} kvm_pmu_hw_cache_events[] = {
> >> +	[0] = { 0x04, PERF_COUNT_HW_CACHE_L1D, PERF_COUNT_HW_CACHE_OP_READ,
> >> +		      PERF_COUNT_HW_CACHE_RESULT_ACCESS },
> >> +	[1] = { 0x03, PERF_COUNT_HW_CACHE_L1D, PERF_COUNT_HW_CACHE_OP_READ,
> >> +		      PERF_COUNT_HW_CACHE_RESULT_MISS },
> >> +	[2] = { 0x04, PERF_COUNT_HW_CACHE_L1D, PERF_COUNT_HW_CACHE_OP_WRITE,
> >> +		      PERF_COUNT_HW_CACHE_RESULT_ACCESS },
> >> +	[3] = { 0x03, PERF_COUNT_HW_CACHE_L1D, PERF_COUNT_HW_CACHE_OP_WRITE,
> >> +		      PERF_COUNT_HW_CACHE_RESULT_MISS },
> > 
> > seems to me that the four entries above will never be used, because
> > you'll always match them in kvm_pmu_hw_events above?
> > 
> 
> Yes, I found this before, but for the completeness I list them.
> 

hmm, having unused entries for completeness is a bit weird, IMHO.
Either way, a comment explaining why they're missing or that some are
never used would be helpful.

> > Is this because perf map multiple generic perf events to the same
> > hardware event? 
> I think so.
> 
> > Does it matter if we register this with perf as one or
> > the other then?
> > 
> I think it's ok because the hardware event numbers are same.
> 

ok

> 
> >> +	[4] = { 0x12, PERF_COUNT_HW_CACHE_BPU, PERF_COUNT_HW_CACHE_OP_READ,
> >> +		      PERF_COUNT_HW_CACHE_RESULT_ACCESS },
> >> +	[5] = { 0x10, PERF_COUNT_HW_CACHE_BPU, PERF_COUNT_HW_CACHE_OP_READ,
> >> +		      PERF_COUNT_HW_CACHE_RESULT_MISS },
> >> +	[6] = { 0x12, PERF_COUNT_HW_CACHE_BPU, PERF_COUNT_HW_CACHE_OP_WRITE,
> >> +		      PERF_COUNT_HW_CACHE_RESULT_ACCESS },
> >> +	[7] = { 0x10, PERF_COUNT_HW_CACHE_BPU, PERF_COUNT_HW_CACHE_OP_WRITE,
> >> +		      PERF_COUNT_HW_CACHE_RESULT_MISS },
> >> +};
> >> +
> >> +/**
> >> + * kvm_pmu_stop_counter - stop PMU counter for the selected counter
> >> + * @vcpu: The vcpu pointer
> >> + * @select_idx: The counter index
> >> + *
> >> + * If this counter has been configured to monitor some event, disable and
> >> + * release it.
> >> + */
> >> +static void kvm_pmu_stop_counter(struct kvm_vcpu *vcpu,
> >> +				 unsigned long select_idx)
> >> +{
> >> +	struct kvm_pmu *pmu = &vcpu->arch.pmu;
> >> +	struct kvm_pmc *pmc = &pmu->pmc[select_idx];
> >> +
> >> +	if (pmc->perf_event) {
> >> +		perf_event_disable(pmc->perf_event);
> >> +		perf_event_release_kernel(pmc->perf_event);
> >> +	}
> >> +	pmc->perf_event = NULL;
> >> +	pmc->eventsel = 0xff;
> > 
> > why is 0xff 'unused' or reserved?  If we're choosing this arbitrarily,
> > why is it not 0x3ff?  Should we create a define for this?
> > 
> 
> Yeah, 0x3ff may be better.
> 
> >> +}
> >> +
> >>  /**
> >>   * kvm_pmu_vcpu_reset - reset pmu state for cpu
> >>   * @vcpu: The vcpu pointer
> >> @@ -27,12 +87,125 @@
> >>   */
> >>  void kvm_pmu_vcpu_reset(struct kvm_vcpu *vcpu)
> >>  {
> >> +	int i;
> >>  	struct kvm_pmu *pmu = &vcpu->arch.pmu;
> >>  
> >> +	for (i = 0; i < ARMV8_MAX_COUNTERS; i++)
> >> +		kvm_pmu_stop_counter(vcpu, i);
> >> +	pmu->overflow_status = 0;
> >>  	pmu->irq_pending = false;
> >>  }
> >>  
> >>  /**
> >> + * kvm_pmu_find_hw_event - find hardware event
> >> + * @pmu: The pmu pointer
> >> + * @event_select: The number of selected event type
> >> + *
> >> + * Based on the number of selected event type, find out whether it belongs to
> >> + * PERF_TYPE_HARDWARE. If so, return the corresponding event id.
> >> + */
> >> +static unsigned kvm_pmu_find_hw_event(struct kvm_pmu *pmu,
> >> +				      unsigned long event_select)
> >> +{
> >> +	int i;
> >> +
> >> +	for (i = 0; i < ARRAY_SIZE(kvm_pmu_hw_events); i++)
> >> +		if (kvm_pmu_hw_events[i].eventsel == event_select)
> >> +			break;
> >> +
> >> +	if (i == ARRAY_SIZE(kvm_pmu_hw_events))
> >> +		return PERF_COUNT_HW_MAX;
> >> +
> >> +	return kvm_pmu_hw_events[i].event_type;
> > 
> > you can just return this directly in the loop if you have a match and
> > unconditionally return PERF_COUNT_HW_MAX outside the loop without having
> > to check the loop condition.
> > 
> ok
> >> +}
> >> +
> >> +/**
> >> + * kvm_pmu_find_hw_cache_event - find hardware cache event
> >> + * @pmu: The pmu pointer
> >> + * @event_select: The number of selected event type
> >> + *
> >> + * Based on the number of selected event type, find out whether it belongs to
> >> + * PERF_TYPE_HW_CACHE. If so, return the corresponding event id.
> >> + */
> >> +static unsigned kvm_pmu_find_hw_cache_event(struct kvm_pmu *pmu,
> >> +					    unsigned long event_select)
> >> +{
> >> +	int i;
> >> +	unsigned config;
> >> +
> >> +	for (i = 0; i < ARRAY_SIZE(kvm_pmu_hw_cache_events); i++)
> >> +		if (kvm_pmu_hw_cache_events[i].eventsel == event_select)
> >> +			break;
> >> +
> >> +	if (i == ARRAY_SIZE(kvm_pmu_hw_cache_events))
> >> +		return PERF_COUNT_HW_CACHE_MAX;
> > 
> > I feel like I just read this code, can we reuse it with a pointer to the
> > array?
> > 
> >> +
> >> +	config = (kvm_pmu_hw_cache_events[i].cache_type & 0xff)
> >> +		 | ((kvm_pmu_hw_cache_events[i].cache_op & 0xff) << 8)
> >> +		 | ((kvm_pmu_hw_cache_events[i].cache_result & 0xff) << 16);
> >> +
> >> +	return config;
> >> +}
> >> +
> >> +/**
> >> + * kvm_pmu_set_counter_event_type - set selected counter to monitor some event
> >> + * @vcpu: The vcpu pointer
> >> + * @data: The data guest writes to PMXEVTYPER_EL0
> >> + * @select_idx: The number of selected counter
> >> + *
> >> + * Firstly check whether the event type is same with the one to be set.
> >> + * If not, stop counter to monitor current event and find the event type map id.
> >> + * According to the bits of data to configure this perf_event attr and set
> >> + * exclude_host to 1 for guest. Then call perf_event API to create the
> >> + * corresponding event and save the event pointer.
> > 
> > This text seems to be describing more how the function does something,
> > as opposed to what it does and why.  I found it a little hard to read.
> > 
> >> + */
> >> +void kvm_pmu_set_counter_event_type(struct kvm_vcpu *vcpu, unsigned long data,
> >> +				    unsigned long select_idx)
> >> +{
> >> +	struct kvm_pmu *pmu = &vcpu->arch.pmu;
> >> +	struct kvm_pmc *pmc = &pmu->pmc[select_idx];
> >> +	struct perf_event *event;
> >> +	struct perf_event_attr attr;
> >> +	unsigned config, type = PERF_TYPE_RAW;
> >> +
> >> +	if ((data & ARMV8_EVTYPE_EVENT) == pmc->eventsel)
> >> +		return;
> >> +
> >> +	kvm_pmu_stop_counter(vcpu, select_idx);
> >> +	pmc->eventsel = data & ARMV8_EVTYPE_EVENT;
> >> +
> >> +	config = kvm_pmu_find_hw_event(pmu, pmc->eventsel);
> >> +	if (config != PERF_COUNT_HW_MAX) {
> >> +		type = PERF_TYPE_HARDWARE;
> >> +	} else {
> >> +		config = kvm_pmu_find_hw_cache_event(pmu, pmc->eventsel);
> >> +		if (config != PERF_COUNT_HW_CACHE_MAX)
> >> +			type = PERF_TYPE_HW_CACHE;
> >> +	}
> >> +
> >> +	if (type == PERF_TYPE_RAW)
> >> +		config = pmc->eventsel;
> > 
> > don't you need to memset attr to 0 first?
> > 
> ok
> > otherwise, how do you ensure that for example exclude_guest is always
> > clear?
> > 
> >> +
> >> +	attr.type = type;
> >> +	attr.size = sizeof(attr);
> >> +	attr.pinned = true;
> >> +	attr.exclude_user = data & ARMV8_EXCLUDE_EL0 ? 1 : 0;
> >> +	attr.exclude_kernel = data & ARMV8_EXCLUDE_EL1 ? 1 : 0;
> >> +	attr.exclude_hv = data & ARMV8_INCLUDE_EL2 ? 0 : 1;
> > 
> > should the guest be able to see something counted in the hypervisor ever
> > or should that only be the host being able to see that?
> > 
> > my gut feeling is that the hypervisor should be hidden from the guest
> > and that exclude_hv = 0, is the right choice.  But this is a question
> > about the semantics of perf, I suppose.
> > 
> 
> This is what I'm not sure. I just thought about if guest has complete
> ELs(EL3-EL0) and how to deal with nested virtualization.
> 

nested virtualization is really not very likely to happen on arm64.  I
think the right way to look at this is that we're emulating a platform
without EL2 and therefore the guest should not see any events from EL2.

> >> +	attr.exclude_host = 1;
> >> +	attr.config = config;
> >> +	attr.sample_period = (-pmc->counter) & (((u64)1 << 32) - 1);
> > 
> > whoa, what is this scary calculation?
> > 
> > definitely needs an explanation?
> > 
> >> +
> >> +	event = perf_event_create_kernel_counter(&attr, -1, current, NULL, pmc);
> >> +	if (IS_ERR(event)) {
> >> +		kvm_err("kvm: pmu event creation failed %ld\n",
> >> +			  PTR_ERR(event));
> > 
> > doesn't this mean we'll spam the kernel log if the guest supplies
> > bogus/unsupported event numbers?
> > 
> 
> X86 uses printk_once, is that ok to us here?

yeah, that should be fine.

> 
> > In that case it shoudl be kvm_debug and the guest should be able to see
> > this somehow (e.g. events don't count).
> > 
> 
> Yes, will think about this.
> 

printk_once of kvm_debug would be fine.

Thanks,
-Christoffer


From dianders at chromium.org  Mon Aug  3 12:57:26 2015
From: dianders at chromium.org (Doug Anderson)
Date: Mon, 3 Aug 2015 12:57:26 -0700
Subject: [PATCH v1 1/2] clk: rockchip: add pclk_pd_pmu to the list of
 rk3288 critical clocks
In-Reply-To: <1438574211-4887-1-git-send-email-hl@rock-chips.com>
References: <1438574211-4887-1-git-send-email-hl@rock-chips.com>
Message-ID: <CAD=FV=VpYF7+Qkw3qiuQyU4n9k7aigf_on+t-kJcBQ_kHE7Nhg@mail.gmail.com>

hl,

On Sun, Aug 2, 2015 at 8:56 PM, huang lin <hl at rock-chips.com> wrote:
> pclk_pd_pmu needs to keep running and with the upcoming gpio clock
> handling this is not always the case anymore. So add it to the list
> of critical clocks for now.
>
> Signed-off-by: Heiko Stuebner <heiko at sntech.de>
>
> Signed-off-by: huang lin <hl at rock-chips.com>
> ---
>  drivers/clk/rockchip/clk-rk3288.c | 1 +
>  1 file changed, 1 insertion(+)

Probably should get rid of the blank line between the two SoBs.
...and probably should fix your name to be capitalized?  ...but I
assume the maintainer can fix that when landing?  Otherwise:

Reviewed-by: Douglas Anderson <dianders at chromium.org>


From boris.brezillon at free-electrons.com  Mon Aug  3 13:07:29 2015
From: boris.brezillon at free-electrons.com (Boris Brezillon)
Date: Mon, 3 Aug 2015 22:07:29 +0200
Subject: [PATCH 1/3] clocksource: atmel-st: Remove irq handler when
 clock event is unused
In-Reply-To: <alpine.DEB.2.11.1508031619230.3825@nanos>
References: <1437161608-26782-1-git-send-email-alexandre.belloni@free-electrons.com>
 <1437161608-26782-2-git-send-email-alexandre.belloni@free-electrons.com>
 <alpine.DEB.2.11.1507180942360.18576@nanos>
 <20150718222308.GA30489@piout.net>
 <alpine.DEB.2.11.1507201103550.18576@nanos>
 <20150720193726.GJ15539@piout.net>
 <alpine.DEB.2.11.1507202245310.18576@nanos>
 <alpine.DEB.2.11.1508021100390.3825@nanos>
 <20150802094028.GN12596@twins.programming.kicks-ass.net>
 <20150803153004.4a74d99a@bbrezillon>
 <alpine.DEB.2.11.1508031619230.3825@nanos>
Message-ID: <20150803220729.23feba3f@bbrezillon>

On Mon, 3 Aug 2015 16:36:29 +0200 (CEST)
Thomas Gleixner <tglx at linutronix.de> wrote:

> On Mon, 3 Aug 2015, Boris Brezillon wrote:
> > On Sun, 2 Aug 2015 11:40:28 +0200
> > Peter Zijlstra <peterz at infradead.org> wrote:
> > 
> > > On Sun, Aug 02, 2015 at 11:10:21AM +0200, Thomas Gleixner wrote:
> > > > I think Boris Brezillon had implemented it at some point, but it was
> > > > shot down for reasons I can't remember. 
> > > 
> > > You weren't around at the time.. DT people didn't like it, said they
> > > didn't like having to make up fake hardware in their DT crap.
> > 
> > I don't know who was right, but the fact is they won't be inclined to
> > take such an approach unless the virtual demuxer is not exposed in the
> > DT, which is almost impossible since irq users are identifying their
> > irq lines with a phandle to the interrupt controller and an interrupt
> > id (usually extracted from the datasheet).
> 
> I really have no idea why DT folks think that virtual devices are not
> suitable for DT entries. Marks working assumption from the old thread:
> 
>  > This sounds like a DT-workaround for a Linux implementation problem,
>  > and I don't think this the right way to solve your problem.
> 
> is simply wrong. This has nothing to do with a Linux implementation
> problem. It's a sensible workaround for braindamaged hardware at the
> proper abstraction level.
> 
> > Anyway, below is a solution providing a way to disable specific
> > handlers without reworking the way we are modeling shared interrupts.
> > Thomas, I know you were not in favor of the proposed approach, but,
> > AFAICT, it does not add any conditional path to the interrupt handling
> > path (which, IIRC, was one of your requirements), and is simple enough
> > to be used by people really needing it.
> > 
> > There's probably other drawback I haven't noticed, so please don't
> > hesitate to share your thoughts.
> 
> Yes, aside of the bloat, it needs special handling in free_irq() as
> well.

Right. Below is a patch fixing the __setup_irq()/__free_irq() functions.

Anyway, I won't insist on this approach unless you want me to go
further, and I don't plan to spend more time on convincing DT folks that
the virtual demux is what we need (I already spent more time than I
wanted arguing on this feature :-/).

Best Regards,

Boris

--- >8 ---

From 96448d56b202f2140e7008a3ca291b133696b4c8 Mon Sep 17 00:00:00 2001
From: Boris Brezillon <boris.brezillon at free-electrons.com>
Date: Mon, 3 Aug 2015 21:59:29 +0200
Subject: [PATCH] irq: add disable_irq_handler()/enable_irq_handler() functions

Sometime we need to disable a specific handler on a shared irq line.
Currently, the only way this can be achieved is by freeing the irq handler
when we want to disable the irq and creating a new one when we want to
enable.
This is not only adding some overhead to the disable/enable operations, but
the request_irq function cannot be called in atomic context, which means
it prevents disabling the interrupt in such situation.

This patch introduces three new functions: disable_irq_handler(),
disable_irq_handler_nosync() and enable_irq_handler() to allow disabling
a specific handler on a shared irq line.

Signed-off-by: Boris Brezillon <boris.brezillon at free-electrons.com>
---
 include/linux/irqdesc.h |   1 +
 kernel/irq/manage.c     | 143 ++++++++++++++++++++++++++++++++++++++++++------
 2 files changed, 126 insertions(+), 18 deletions(-)

diff --git a/include/linux/irqdesc.h b/include/linux/irqdesc.h
index fcea4e4..c8bd055 100644
--- a/include/linux/irqdesc.h
+++ b/include/linux/irqdesc.h
@@ -52,6 +52,7 @@ struct irq_desc {
 	irq_preflow_handler_t	preflow_handler;
 #endif
 	struct irqaction	*action;	/* IRQ action list */
+	struct irqaction	*disabled_actions;	/* IRQ disabled action list */
 	unsigned int		status_use_accessors;
 	unsigned int		core_internal_state__do_not_mess_with_it;
 	unsigned int		depth;		/* nested irq disables */
diff --git a/kernel/irq/manage.c b/kernel/irq/manage.c
index f974485..0e7432b 100644
--- a/kernel/irq/manage.c
+++ b/kernel/irq/manage.c
@@ -458,6 +458,47 @@ void disable_irq_nosync(unsigned int irq)
 }
 EXPORT_SYMBOL(disable_irq_nosync);
 
+static int __disable_irq_handler_nosync(unsigned int irq, void *dev_id)
+{
+	unsigned long flags;
+	struct irqaction *action, **prev;
+	struct irq_desc *desc = irq_get_desc_buslock(irq, &flags, IRQ_GET_DESC_CHECK_GLOBAL);
+	int ret = 0;
+
+	if (!desc)
+		return -EINVAL;
+
+	for (action = desc->action, prev = &desc->action; action; action = action->next) {
+		if (action->dev_id == dev_id)
+			break;
+
+		prev = &action->next;
+	}
+
+	if (!action)
+		goto out;
+
+	*prev = action->next;
+
+	action->next = desc->disabled_actions;
+	desc->disabled_actions = action;
+	if (!desc->action) {
+		__disable_irq(desc, irq);
+		ret = 1;
+	}
+
+out:
+	irq_put_desc_busunlock(desc, flags);
+	return ret;
+}
+
+static void disable_irq_handler_nosync(unsigned int irq, void *dev_id)
+{
+	__disable_irq_handler_nosync(irq, dev_id);
+}
+EXPORT_SYMBOL(disable_irq_handler_nosync);
+
+
 /**
  *	disable_irq - disable an irq and wait for completion
  *	@irq: Interrupt to disable
@@ -477,6 +518,13 @@ void disable_irq(unsigned int irq)
 }
 EXPORT_SYMBOL(disable_irq);
 
+void disable_irq_handler(unsigned int irq, )
+{
+	if (__disable_irq_handler_nosync(irq) > 0)
+		synchronize_irq(irq);
+}
+EXPORT_SYMBOL(disable_irq);
+
 /**
  *	disable_hardirq - disables an irq and waits for hardirq completion
  *	@irq: Interrupt to disable
@@ -552,6 +600,40 @@ out:
 }
 EXPORT_SYMBOL(enable_irq);
 
+void enable_irq_handler(unsigned int irq, void *dev_id)
+{
+	unsigned long flags;
+	struct irqaction *action, **prev;
+	struct irq_desc *desc = irq_get_desc_buslock(irq, &flags, IRQ_GET_DESC_CHECK_GLOBAL);
+
+	if (!desc)
+		return -EINVAL;
+
+	for (action = desc->disabled_actions, prev = &desc->action; action;
+	     action = action->next) {
+		if (action->dev_id == dev_id)
+			break;
+
+		prev = &action->next;
+	}
+
+	if (!action)
+		goto out;
+
+	*prev = action->next;
+
+	action->next = desc->action;
+	desc->action = action;
+
+	if (!action->next)
+		__enable_irq(desc, irq);
+
+out:
+	irq_put_desc_busunlock(desc, flags);
+
+}
+EXPORT_SYMBOL(enable_irq_handler);
+
 static int set_irq_wake_real(unsigned int irq, unsigned int on)
 {
 	struct irq_desc *desc = irq_to_desc(irq);
@@ -1118,6 +1200,12 @@ __setup_irq(unsigned int irq, struct irq_desc *desc, struct irqaction *new)
 	raw_spin_lock_irqsave(&desc->lock, flags);
 	old_ptr = &desc->action;
 	old = *old_ptr;
+	if (!old) {
+		old_ptr = &desc->disabled_actions;
+		old = *old_ptr;
+	}
+
+	old = desc->action ? : desc->disabled_actions;
 	if (old) {
 		/*
 		 * Can't share interrupts unless both agree to and are
@@ -1136,20 +1224,27 @@ __setup_irq(unsigned int irq, struct irq_desc *desc, struct irqaction *new)
 		    (new->flags & IRQF_PERCPU))
 			goto mismatch;
 
-		/* add new interrupt at end of irq queue */
-		do {
-			/*
-			 * Or all existing action->thread_mask bits,
-			 * so we can find the next zero bit for this
-			 * new action.
-			 */
-			thread_mask |= old->thread_mask;
-			old_ptr = &old->next;
-			old = *old_ptr;
-		} while (old);
 		shared = 1;
 	}
 
+	if (irq_settings_can_autoenable(desc))
+		old_ptr = &desc->action;
+	else
+		old_ptr = &desc->disabled_actions;
+	old = *old_ptr;
+
+	/* add new interrupt at end of irq queue */
+	while (old) {
+		/*
+		 * Or all existing action->thread_mask bits,
+		 * so we can find the next zero bit for this
+		 * new action.
+		 */
+		thread_mask |= old->thread_mask;
+		old_ptr = &old->next;
+		old = *old_ptr;
+	}
+
 	/*
 	 * Setup the thread mask for this irqaction for ONESHOT. For
 	 * !ONESHOT irqs the thread mask is 0 so we can avoid a
@@ -1373,25 +1468,37 @@ static struct irqaction *__free_irq(unsigned int irq, void *dev_id)
 	for (;;) {
 		action = *action_ptr;
 
-		if (!action) {
-			WARN(1, "Trying to free already-free IRQ %d\n", irq);
-			raw_spin_unlock_irqrestore(&desc->lock, flags);
-
-			return NULL;
-		}
 
 		if (action->dev_id == dev_id)
 			break;
 		action_ptr = &action->next;
 	}
 
+	if (!action) {
+		action_ptr = &desc->disabled_actions;
+		for (;;) {
+			action = *action_ptr;
+
+			if (action->dev_id == dev_id)
+				break;
+			action_ptr = &action->next;
+		}
+	}
+
+	if (!action) {
+		WARN(1, "Trying to free already-free IRQ %d\n", irq);
+		raw_spin_unlock_irqrestore(&desc->lock, flags);
+
+		return NULL;
+	}
+
 	/* Found it - now remove it from the list of entries: */
 	*action_ptr = action->next;
 
 	irq_pm_remove_action(desc, action);
 
 	/* If this was the last handler, shut down the IRQ line: */
-	if (!desc->action) {
+	if (!desc->action && !desc->disabled_actions) {
 		irq_shutdown(desc);
 		irq_release_resources(desc);
 	}
-- 
1.9.1


From xander.huff at ni.com  Mon Aug  3 13:18:36 2015
From: xander.huff at ni.com (Xander Huff)
Date: Mon, 03 Aug 2015 15:18:36 -0500
Subject: [PATCH v3] iio: adc: xilinx-xadc: Push interrupts into threaded
 context
In-Reply-To: <55B231DE.4080308@metafoo.de>
References: <CAKfKVtGTO81wLWk50M303t2WjcBEMEt_LUnsJ3_WmvR_3izUjg@mail.gmail.com>
 <1437434050-32907-1-git-send-email-xander.huff@ni.com>
 <55B231DE.4080308@metafoo.de>
Message-ID: <55BFCC9C.5040305@ni.com>

On 7/24/2015 7:38 AM, Lars-Peter Clausen wrote:
> Hi,
>
> Sorry, but I don't think this patch has been sufficiently tested against a
> mainline kernel. The driver wont even probe the way it is right now.
>
Thanks for your responses. I'm not sure why it doesn't probe for you since I was 
able to do a fair amount of tests with it on our device.

I'll get to work on your suggestions and hopefully having a v4 out sometime next 
week.

-- 
Xander Huff
Staff Software Engineer
National Instruments


From dianders at chromium.org  Mon Aug  3 13:21:27 2015
From: dianders at chromium.org (Doug Anderson)
Date: Mon, 3 Aug 2015 13:21:27 -0700
Subject: [PATCH v1 2/2] pinctrl: rockchip: only enable gpio clock when it
 setting
In-Reply-To: <1438574211-4887-2-git-send-email-hl@rock-chips.com>
References: <1438574211-4887-1-git-send-email-hl@rock-chips.com>
 <1438574211-4887-2-git-send-email-hl@rock-chips.com>
Message-ID: <CAD=FV=WCGtBgzy6=dWqZ5ZKLhxUsxLom56UfWwXNp+ospR4JRA@mail.gmail.com>

hl

On Sun, Aug 2, 2015 at 8:56 PM, huang lin <hl at rock-chips.com> wrote:
> gpio can keep state even the clock disable, for save power
> consumption, only enable gpio clock when it setting
>
> Signed-off-by: Heiko Stuebner <heiko at sntech.de>
> Signed-off-by: huang lin <hl at rock-chips.com>
>
> Signed-off-by: huang lin <hl at rock-chips.com>

Your "Signed-off-by"s are a little wonky here...  Can you fix up?

> ---
>  drivers/pinctrl/pinctrl-rockchip.c | 60 ++++++++++++++++++++++++++++++++++----
>  1 file changed, 54 insertions(+), 6 deletions(-)
>
> diff --git a/drivers/pinctrl/pinctrl-rockchip.c b/drivers/pinctrl/pinctrl-rockchip.c
> index cc2843a..445829f 100644
> --- a/drivers/pinctrl/pinctrl-rockchip.c
> +++ b/drivers/pinctrl/pinctrl-rockchip.c
> @@ -945,17 +945,20 @@ static int _rockchip_pmx_gpio_set_direction(struct gpio_chip *chip,
>         if (ret < 0)
>                 return ret;
>
> +       clk_enable(bank->clk);
>         spin_lock_irqsave(&bank->slock, flags);
>
> -       data = readl_relaxed(bank->reg_base + GPIO_SWPORT_DDR);
> +       data = readl(bank->reg_base + GPIO_SWPORT_DDR);

I am a little curious why you need to change the readl_relaxed() to a
read().  Are you trying to ensure that the clock was on before the
read happened?  If so, I think this won't help.  I see:

#define readl(c) ({ u32 __v = readl_relaxed(c); __iormb(); __v; })

...so that means that the iormb() is _after_ the readl.

...but I would believe that the clk_enable() call itself would be
guaranteeing that the clock was enabled in time.  ...and if not then
grabbing the spinlock is another barrier, right?  I think you do this
in a few places...

Other than that this patch looks good to me....

-Doug


From bhupesh.sharma at freescale.com  Mon Aug  3 13:38:53 2015
From: bhupesh.sharma at freescale.com (Sharma Bhupesh)
Date: Mon, 3 Aug 2015 20:38:53 +0000
Subject: [Query] ARM64: Softlockup when using PSCI for secondary CPU_ON
In-Reply-To: <BY1PR0301MB1303B775B1D5D318A64350C582770@BY1PR0301MB1303.namprd03.prod.outlook.com>
References: <BY1PR0301MB1303EC5AAE8F0B4DAA70D15F82770@BY1PR0301MB1303.namprd03.prod.outlook.com>
 <20150803100248.GA25627@leverpostej>
 <BY1PR0301MB1303B775B1D5D318A64350C582770@BY1PR0301MB1303.namprd03.prod.outlook.com>
Message-ID: <BY1PR0301MB13035E3B09536F34F4C281CF82770@BY1PR0301MB1303.namprd03.prod.outlook.com>

Hi Mark,

> On Behalf Of Sharma Bhupesh
> Sent: Monday, August 03, 2015 3:47 PM
> 
> Hi Mark,
> 
> Thanks for the reply.
> 
> > From: Mark Rutland [mailto:mark.rutland at arm.com]
> > Sent: Monday, August 03, 2015 3:33 PM
> >
> > On Mon, Aug 03, 2015 at 05:12:00AM +0100, Sharma Bhupesh wrote:
> > > Hi ARM64 experts,
> > >
> > > I am working on a Freescale ARM64 based SoC, which has 4 Cortex-A53
> > > cores and I am using the PSCI conducts to turn on the secondary CPUs
> > > via a custom implementation of a secure runtime firmware (something
> > similar to the ARM Trusted Firmware).
> > >
> > > Following is my boot-flow:
> > >
> > > - BootROM (runs in EL3, All secondaries are held up in reset) ->
> > >
> > > - UEFI bootloader- PEI Phase (Runs only on Primary, starts up in
> > > EL3)
> > > ->
> > >
> > > - Secure Firmware (runs in EL3, transitions primary core to EL2) ->
> > >
> > > - UEFI bootloader- Rest of the Phases (Runs only on Primary, in EL2)
> > > ->
> > >
> > > - UEFI Linux loader launches linux (Runs only on Primary,
> > > transitions core to EL1) ->
> > >
> > > - Linux runs and calls PSCI conducts to turn on secondary cores via
> > > smc calls to secure run-time firmware ->
> >
> > Which version of Linux are you using?
> 
> I am using 3.19.3
> 
> > Is Linux itself booted at EL1 or EL2?
> 
> UEFI leaves the execution level of the primary core in EL2.
> KVM is turned-off in my defconfig, so I am not loading any hypervisor at
> EL2 as of now.
> 
> > EL2 is very strongly preferable unless you're already running a
> > hypervisor at EL2. That way Linux can ensure that things are
> > initialised correctly at EL2 (e.g. CNTVOFF), regardless of whether you
> > want to use KVM.
> 
> I notice that in the kernel primary core successfully switches to EL1 and
> starts executing the relevant 'start_kernel' routine.
> 
> > > - Now I can see that the ARM64 linux is able to recognize that the
> > secondaries are boot'ed properly:
> > >
> > > PSCI Logs:
> > > ----------
> > > psci: probing for conduit method from DT.
> > > psci: PSCIv0.2 detected in firmware.
> > > psci: Using standard PSCI v0.2 function IDs ..
> > >
> > > Architected cp15 timer(s) running at 25.00MHz (phys).
> > > sched_clock: 56 bits at 25MHz, resolution 40ns, wraps every
> > > 2748779069440ns
> > >
> > > ..
> > >
> > > CPU1: Booted secondary processor
> > > Detected VIPT I-cache on CPU1
> > > CPU2: Booted secondary processor
> > > Detected VIPT I-cache on CPU2
> > > CPU3: Booted secondary processor
> > > Detected VIPT I-cache on CPU3
> > > Brought up 4 CPUs
> > > SMP: Total of 4 processors activated.
> >
> > Ok. This all looks fine.
> >
> > > - However, when the Linux boot proceeds further, I see softlockups
> > > which usually show that one of the secondaries was stuck in
> > 'secondary_start_kernel' (detailed logs below).
> > >
> > > - When I turn of CONFIG_SMP from the .config, I can see that the
> > > softlockups disappear. So, I am correlating these softlockups to SMP
> > and PSCI conducts.
> >
> > Ok, that likely means it's in the idle loop. Given that the CPUs made
> > it into the kernel this sounds like a generic SMP issue rather than
> > something specific to PSCI.
> 
> Ok.
> 
> > > preempt self-detected stall on CPU { 3}  (t=17194 jiffies g=-267
> > > c=-268 q=1)
> >
> > > INFO: rcu_preempt detected stalls on CPUs/tasks: { 1 2} (detected by
> > > 0, t=287104493908 jiffies, g=-267, c=-268, q=2)
> >
> > It looks like your timekeeping has gone wrong. As mentioned above, I'd
> > suspect that CNTVOFF_EL2 is not programmed consistently across all CPUs.
> >
> > Are you able to boot Linux at EL2 instead? Or can you verify that
> > CNTVOFF_EL2 is initialised?
> >
> 
> Ok, let me check the CNTVOFF_EL2 part then.
> I will get back with details soon.
> 

Indeed. Using the following code in the run-time EL3 firmware to correctly set the
CNTVOFF_EL2 to zero for secondaries solves the soft-lockup. I took a reference from your u-boot
patch (see [1]).

+	/* Initialize Generic Timers */
+	msr	cntvoff_el2, xzr

[1] http://marc.info/?l=u-boot&m=140230240621878&w=2

Many thanks for the quick pointers.

Regards,
Bhupesh


From heiko at sntech.de  Mon Aug  3 13:50:33 2015
From: heiko at sntech.de (Heiko =?ISO-8859-1?Q?St=FCbner?=)
Date: Mon, 03 Aug 2015 22:50:33 +0200
Subject: [PATCH v1 2/2] pinctrl: rockchip: only enable gpio clock when it
 setting
In-Reply-To: <CAD=FV=WCGtBgzy6=dWqZ5ZKLhxUsxLom56UfWwXNp+ospR4JRA@mail.gmail.com>
References: <1438574211-4887-1-git-send-email-hl@rock-chips.com>
 <1438574211-4887-2-git-send-email-hl@rock-chips.com>
 <CAD=FV=WCGtBgzy6=dWqZ5ZKLhxUsxLom56UfWwXNp+ospR4JRA@mail.gmail.com>
Message-ID: <2472708.6oReK8jXV2@diego>

Am Montag, 3. August 2015, 13:21:27 schrieb Doug Anderson:
> hl
> 
> On Sun, Aug 2, 2015 at 8:56 PM, huang lin <hl at rock-chips.com> wrote:
> > gpio can keep state even the clock disable, for save power
> > consumption, only enable gpio clock when it setting
> > 
> > Signed-off-by: Heiko Stuebner <heiko at sntech.de>
> > Signed-off-by: huang lin <hl at rock-chips.com>
> > 
> > Signed-off-by: huang lin <hl at rock-chips.com>
> 
> Your "Signed-off-by"s are a little wonky here...  Can you fix up?
> 
> > ---
> > 
> >  drivers/pinctrl/pinctrl-rockchip.c | 60
> >  ++++++++++++++++++++++++++++++++++---- 1 file changed, 54 insertions(+),
> >  6 deletions(-)
> > 
> > diff --git a/drivers/pinctrl/pinctrl-rockchip.c
> > b/drivers/pinctrl/pinctrl-rockchip.c index cc2843a..445829f 100644
> > --- a/drivers/pinctrl/pinctrl-rockchip.c
> > +++ b/drivers/pinctrl/pinctrl-rockchip.c
> > @@ -945,17 +945,20 @@ static int _rockchip_pmx_gpio_set_direction(struct
> > gpio_chip *chip,> 
> >         if (ret < 0)
> >         
> >                 return ret;
> > 
> > +       clk_enable(bank->clk);
> > 
> >         spin_lock_irqsave(&bank->slock, flags);
> > 
> > -       data = readl_relaxed(bank->reg_base + GPIO_SWPORT_DDR);
> > +       data = readl(bank->reg_base + GPIO_SWPORT_DDR);
> 
> I am a little curious why you need to change the readl_relaxed() to a
> read().  Are you trying to ensure that the clock was on before the
> read happened?  If so, I think this won't help.  I see:
> 
> #define readl(c) ({ u32 __v = readl_relaxed(c); __iormb(); __v; })
> 
> ...so that means that the iormb() is _after_ the readl.
> 
> ...but I would believe that the clk_enable() call itself would be
> guaranteeing that the clock was enabled in time.  ...and if not then
> grabbing the spinlock is another barrier, right?  I think you do this
> in a few places...
> 
> Other than that this patch looks good to me....

I think that was my fault ... looking at stuff before figuring out that we're 
actually loosing the pd_pmu clock, and then forgetting to take this out again, 
before getting it to hl.

In retospect it also seems silly to have changed them in the first place ;-) .
So yes, they should be changed back to their original.


Heiko


From tjakobi at math.uni-bielefeld.de  Mon Aug  3 13:55:00 2015
From: tjakobi at math.uni-bielefeld.de (Tobias Jakobi)
Date: Mon, 03 Aug 2015 22:55:00 +0200
Subject: [PATCH v3 0/5] cpufreq: use generic cpufreq drivers for
 Exynos4x12 platform
In-Reply-To: <1438368557-2352-1-git-send-email-b.zolnierkie@samsung.com>
References: <1438368557-2352-1-git-send-email-b.zolnierkie@samsung.com>
Message-ID: <55BFD524.6080102@math.uni-bielefeld.de>

Hello,

Bartlomiej Zolnierkiewicz wrote:
> Hi,
> 
> This patch series removes the use of Exynos4x12 specific support
> from cpufreq-exynos driver and enables the use of cpufreq-dt driver
> for this platform.
> 
> This patch series has been tested on Exynos4412 based Odroid-U3 and
> Trats2 boards.
I've tested this series on my Odroid-X2 (also Exynos4412) with
powersave, performance and ondemand governor. Scaling works like
expected, so no issues to report!

Tested-by: Tobias Jakobi <tjakobi at math.uni-bielefeld.de>


With best wishes,
Tobias


> 
> Depends on:
> - next-20150730 branch of linux-next kernel tree
> - "[PATCH V3 00/16] OPP: Add code to support operating-points-v2 bindings"
>   (http://www.spinics.net/lists/arm-kernel/msg435408.html)
> 
> Changes since v2
> (http://thread.gmane.org/gmane.linux.kernel.samsung-soc/46653):
> - rebased on top of next-20150730 branch of linux-next kernel tree
> - ported over V3 of opp-v2 bindings support patch series
> - put cpu0 nodes in alphabetical order in dts files
> - added Reviewed-by tags from Javier and Krzysztof
> - added Acked-by tag from Sylwester
> 
> Changes since v1
> (http://thread.gmane.org/gmane.linux.kernel.samsung-soc/44361):
> - rebased on top of next-20150629 branch of linux-next kernel tree
> - rebased on top of Exynos5250 cpufreq-dt support patch series
> - fixed if-statement in exynos4_clk_init() (noticed by Tobias Jakobi)
> - ported over opp-v2 bindings (requested by Viresh Kumar)
> 
> Best regards,
> --
> Bartlomiej Zolnierkiewicz
> Samsung R&D Institute Poland
> Samsung Electronics
> 
> 
> Bartlomiej Zolnierkiewicz (5):
>   clk: samsung: exynos4x12: add cpu clock configuration data and
>     instantiate cpu clock
>   ARM: dts: Exynos4x12: add CPU OPP and regulator supply property
>   ARM: Exynos: switch to using generic cpufreq driver for Exynos4x12
>   cpufreq: exynos: remove Exynos4x12 specific cpufreq driver support
>   cpufreq: remove no longer needed CPU_FREQ_BOOST_SW config option
> 
>  arch/arm/boot/dts/exynos4212.dtsi               |  81 ++++++++
>  arch/arm/boot/dts/exynos4412-odroid-common.dtsi |   4 +
>  arch/arm/boot/dts/exynos4412-origen.dts         |   4 +
>  arch/arm/boot/dts/exynos4412-trats2.dts         |   4 +
>  arch/arm/boot/dts/exynos4412.dtsi               |  83 +++++++++
>  arch/arm/mach-exynos/exynos.c                   |   2 +
>  drivers/clk/samsung/clk-exynos4.c               |  50 +++++
>  drivers/cpufreq/Kconfig                         |   5 +-
>  drivers/cpufreq/Kconfig.arm                     |  38 ----
>  drivers/cpufreq/Makefile                        |   2 -
>  drivers/cpufreq/exynos-cpufreq.c                | 236 ------------------------
>  drivers/cpufreq/exynos-cpufreq.h                |  72 --------
>  drivers/cpufreq/exynos4x12-cpufreq.c            | 236 ------------------------
>  drivers/cpufreq/freq_table.c                    |   2 -
>  14 files changed, 229 insertions(+), 590 deletions(-)
>  delete mode 100644 drivers/cpufreq/exynos-cpufreq.c
>  delete mode 100644 drivers/cpufreq/exynos-cpufreq.h
>  delete mode 100644 drivers/cpufreq/exynos4x12-cpufreq.c
> 



From dmitry.torokhov at gmail.com  Mon Aug  3 14:04:09 2015
From: dmitry.torokhov at gmail.com (Dmitry Torokhov)
Date: Mon, 3 Aug 2015 14:04:09 -0700
Subject: [PATCH v2 3/4] touchscreen: colibri-vf50-ts: Add touchscreen
 support for Colibri VF50
In-Reply-To: <20150803152544.GA9716@Sanchayan-Arch.toradex.int>
References: <cover.1437058481.git.maitysanchayan@gmail.com>
 <26748bd9a7bde7c2304b6b971f1150bb575e4938.1437058481.git.maitysanchayan@gmail.com>
 <20150717234242.GJ39282@dtor-ws>
 <40d7c372e64c7f25b7df3e48930386de@agner.ch>
 <20150721172044.GC39076@dtor-ws>
 <20150803152544.GA9716@Sanchayan-Arch.toradex.int>
Message-ID: <20150803210409.GG38878@dtor-ws>

Hi Sanchayan,

On Mon, Aug 03, 2015 at 08:55:44PM +0530, maitysanchayan at gmail.com wrote:
> Hello Dmitry,
> 
> On 15-07-21 10:20:44, Dmitry Torokhov wrote:
> > Hi Stefan,
> > 
> > On Tue, Jul 21, 2015 at 04:43:36PM +0200, Stefan Agner wrote:
> > > Hi Dmitry,
> > > 
> > > As the original author of the driver I have some remarks to your review
> > > 
> > > On 2015-07-18 01:42, Dmitry Torokhov wrote:
> > > >> +		/*
> > > >> +		 * If touch pressure is too low, stop measuring and reenable
> > > >> +		 * touch detection
> > > >> +		 */
> > > >> +		if (val_p < min_pressure || val_p > 2000)
> > > >> +			break;
> > > 
> > > This is where the modules touch pressure is used to stop the measurement
> > > process and switch back to interrupt mode. See my remarks at the end.
> > > 
> > > >> +
> > > >> +		/*
> > > >> +		 * The pressure may not be enough for the first x and the
> > > >> +		 * second y measurement, but, the pressure is ok when the
> > > >> +		 * driver is doing the third and fourth measurement. To
> > > >> +		 * take care of this, we drop the first measurement always.
> > > >> +		 */
> > > >> +		if (discard_val_on_start) {
> > > >> +			discard_val_on_start = false;
> > > >> +		} else {
> > > >> +			/*
> > > >> +			 * Report touch position and sleep for
> > > >> +			 * next measurement
> > > >> +			 */
> > > >> +			input_report_abs(vf50_ts->ts_input,
> > > >> +					ABS_X, VF_ADC_MAX - val_x);
> > > >> +			input_report_abs(vf50_ts->ts_input,
> > > >> +					ABS_Y, VF_ADC_MAX - val_y);
> > > >> +			input_report_abs(vf50_ts->ts_input,
> > > >> +					ABS_PRESSURE, val_p);
> > > >> +			input_report_key(vf50_ts->ts_input, BTN_TOUCH, 1);
> > > >> +			input_sync(vf50_ts->ts_input);
> > > >> +		}
> > > >> +
> > > >> +		msleep(10);
> > > >> +	}
> > > >> +
> > > >> +	/* Report no more touch, reenable touch detection */
> > > >> +	input_report_abs(vf50_ts->ts_input, ABS_PRESSURE, 0);
> > > >> +	input_report_key(vf50_ts->ts_input, BTN_TOUCH, 0);
> > > >> +	input_sync(vf50_ts->ts_input);
> > > >> +
> > > >> +	vf50_ts_enable_touch_detection(vf50_ts);
> > > >> +
> > > >> +	/* Wait for the pull-up to be stable on high */
> > > >> +	msleep(10);
> > > >> +
> > > >> +	/* Reenable IRQ to detect touch */
> > > >> +	enable_irq(vf50_ts->pen_irq);
> > > >> +
> > > >> +	dev_dbg(dev, "Reenabled touch detection interrupt\n");
> > > >> +}
> > > >> +
> > > >> +static irqreturn_t vf50_ts_touched(int irq, void *dev_id)
> > > >> +{
> > > >> +	struct vf50_touch_device *vf50_ts = (struct vf50_touch_device *)dev_id;
> > > >> +	struct device *dev = &vf50_ts->pdev->dev;
> > > >> +
> > > >> +	dev_dbg(dev, "Touch detected, start worker thread\n");
> > > >> +
> > > >> +	disable_irq_nosync(irq);
> > > >> +
> > > >> +	/* Disable the touch detection plates */
> > > >> +	gpiod_set_value(vf50_ts->gpio_ym, 0);
> > > >> +
> > > >> +	/* Let the platform mux to default state in order to mux as ADC */
> > > >> +	pinctrl_pm_select_default_state(dev);
> > > >> +
> > > >> +	queue_work(vf50_ts->ts_workqueue, &vf50_ts->ts_work);
> > > > 
> > > > If you convert this to a threaded interrupt you won't need to
> > > > disable/reenable interrupt or queue work. You should also be able to use
> > > > gpiod_set_value_cansleep() extending the range of ways the controller
> > > > could be connected to systems.
> > > > 
> > > 
> > > I'm not sure if a threaded interrupt is the right thing here. While the
> > > pen is on the touchscreen (which can be for several seconds)
> > > measurements have to be made in a continuous loop. Is it ok for a
> > > threaded interrupt to run that long?
> > 
> > Yes, why not? Threaded interrupt is simply a kernel thread that is woken
> > when hard interrupt handler tells it to wake up. Very similar to
> > interrupt + work queue, except that the kernel manages interactions
> > properly for you. There are several drivers in kernel that do that, for
> > example auo-pixcir-ts.c or tsc2007.c
> > 
> > > 
> > > I'm also not sure if it is really safe to _not_ disable the pen down
> > > GPIO interrupt. If we get a interrupt while measuring, we should ignore
> > > that interrupt.
> > 
> > The interrupt management core (you'll have to annotate it as
> > IRQF_ONESHOT) will make sure it stays masked properly until the threaded
> > handler completes so you do not need to disable it explicitly.
> 
> After working some more on threaded irq implementation, if IRQ_ONESHOT
> flag is used while requesting threaded irq, on entering the IRQ handler
> the vf610_gpio_irq_mask is not called and vf610_gpio_irq_unmask is not
> called on exiting the thread function, not something we expected.
> 
> In contrast, using explicit disable_irq_nosync and enable_irq in the IRQ
> handler and thread respectively results in the respective mask and unmask
> function being called.
> 
> The vf610_gpio_irq_*mask functions are in the gpio driver for Vybrid in
> drivers/gpio/gpio-vf610.c.

Well, for edge interrupts we normally do not mask/unmask IRQ as we
expect the controller to latch onto the state and not re-raise intil
interrupt is acked and I believe goes through edge condition again.
For level-triggered IRQs we do mask the interrupt line. See
kernel/irq/handle.c::handle_level_irq() and handle_edge_irq().

Thanks.

-- 
Dmitry


From sergei.shtylyov at cogentembedded.com  Mon Aug  3 14:36:27 2015
From: sergei.shtylyov at cogentembedded.com (Sergei Shtylyov)
Date: Tue, 04 Aug 2015 00:36:27 +0300
Subject: [PATCH v2 0/2] Add R8A7794 GPIO DT support
Message-ID: <6388101.Drn6rL87rl@wasted.cogentembedded.com>

Hello.

   Here's the set of 2 patches against Simon Horman's 'renesas.git' repo,
'renesas-devel-20150803-v4.2-rc5' tag. Here we add the GPIO device tree support
for the R8A7794 SoC.

[1/2] ARM: shmobile: r8a7794: add GPIO clocks
[2/2] ARM: shmobile: r8a7794: add GPIO DT support

WBR, Sergei



From sboyd at codeaurora.org  Mon Aug  3 14:37:52 2015
From: sboyd at codeaurora.org (Stephen Boyd)
Date: Mon, 3 Aug 2015 14:37:52 -0700
Subject: [PATCH v3 4/5] clk: Hi6220: add stub clock driver
In-Reply-To: <1438564418-15948-5-git-send-email-leo.yan@linaro.org>
References: <1438564418-15948-1-git-send-email-leo.yan@linaro.org>
 <1438564418-15948-5-git-send-email-leo.yan@linaro.org>
Message-ID: <20150803213752.GB21068@codeaurora.org>

On 08/03, Leo Yan wrote:
> diff --git a/drivers/clk/hisilicon/clk-hi6220-stub.c b/drivers/clk/hisilicon/clk-hi6220-stub.c
> new file mode 100644
> index 0000000..0931666
> --- /dev/null
> +++ b/drivers/clk/hisilicon/clk-hi6220-stub.c
> @@ -0,0 +1,279 @@
> +/*
> + * Hi6220 stub clock driver
> + *
> + * Copyright (c) 2015 Hisilicon Limited.
> + * Copyright (c) 2015 Linaro Limited.
> + *
> + * Author: Leo Yan <leo.yan at linaro.org>
> + *
> + * This program is free software; you can redistribute it and/or modify
> + * it under the terms of the GNU General Public License version 2 as
> + * published by the Free Software Foundation.
> + *
> + */
> +
> +#include <linux/clkdev.h>

Is this include used?

> +#include <linux/clk-provider.h>
> +#include <linux/clk.h>

Is this include used?

> +#include <linux/err.h>
> +#include <linux/mfd/syscon.h>
> +#include <linux/mailbox_client.h>
> +#include <linux/of.h>
> +#include <linux/of_device.h>
> +#include <linux/regmap.h>
> +#include <linux/slab.h>
> +#include <linux/kernel.h>
> +
> +#include <dt-bindings/clock/hi6220-clock.h>
> +
> +/* Stub clocks id */
> +#define HI6220_STUB_ACPU0		0
> +#define HI6220_STUB_ACPU1		1
> +#define HI6220_STUB_GPU			2
> +#define HI6220_STUB_DDR			5
> +
> +/* Mailbox message */
> +#define HI6220_MBOX_MSG_LEN		8
> +
> +#define HI6220_MBOX_FREQ		(0xA)
> +#define HI6220_MBOX_CMD_SET		(0x3)
> +#define HI6220_MBOX_OBJ_AP		(0x0)
> +
> +/* CPU dynamic frequency scaling */
> +#define ACPU_DFS_FREQ_MAX		(0x1724)
> +#define ACPU_DFS_CUR_FREQ		(0x17CC)
> +#define ACPU_DFS_FLAG			(0x1B30)
> +#define ACPU_DFS_FREQ_REQ		(0x1B34)
> +#define ACPU_DFS_FREQ_LMT		(0x1B38)
> +#define ACPU_DFS_LOCK_FLAG		(0xAEAEAEAE)

We don't need parenthesis around single values in these macros.

> +
> +#define to_stub_clk(hw) container_of(hw, struct hi6220_stub_clk, hw)
> +
> +struct hi6220_stub_clk {
> +	u32 id;
> +	u32 rate;
> +
> +	struct device *dev;
> +	struct clk_hw hw;
> +
> +	struct regmap *dfs_map;
> +	struct mbox_client cl;
> +	struct mbox_chan *mbox;
> +};
> +
> +struct hi6220_mbox_msg {
> +	unsigned char type;
> +	unsigned char cmd;
> +	unsigned char obj;
> +	unsigned char src;
> +	unsigned char para[4];
> +};
> +
> +union hi6220_mbox_data {
> +	unsigned int data[HI6220_MBOX_MSG_LEN];
> +	struct hi6220_mbox_msg msg;
> +};
> +
> +static unsigned int hi6220_acpu_get_freq(struct hi6220_stub_clk *stub_clk)
> +{
> +	unsigned int freq;
> +
> +	regmap_read(stub_clk->dfs_map, ACPU_DFS_CUR_FREQ, &freq);
> +	return freq;
> +}
> +
> +static int hi6220_acpu_set_freq(struct hi6220_stub_clk *stub_clk,
> +				unsigned int freq)
> +{
> +	union hi6220_mbox_data data;
> +
> +	stub_clk->mbox = mbox_request_channel(&stub_clk->cl, 0);

Why not request the channel once in probe?

> +	if (IS_ERR(stub_clk->mbox)) {
> +		dev_err(stub_clk->dev, "failed get mailbox channel\n");
> +		return PTR_ERR(stub_clk->mbox);
> +	};
> +
> +	/* set the frequency in sram */
> +	regmap_write(stub_clk->dfs_map, ACPU_DFS_FREQ_REQ, freq);
> +
> +	/* compound mailbox message */
> +	data.msg.type = HI6220_MBOX_FREQ;
> +	data.msg.cmd  = HI6220_MBOX_CMD_SET;
> +	data.msg.obj  = HI6220_MBOX_OBJ_AP;
> +	data.msg.src  = HI6220_MBOX_OBJ_AP;
> +
> +	mbox_send_message(stub_clk->mbox, &data);
> +	mbox_free_channel(stub_clk->mbox);
> +	return 0;
> +}
> +
> +static int hi6220_acpu_round_freq(struct hi6220_stub_clk *stub_clk,
> +				  unsigned int freq)
> +{
> +	unsigned int limit_flag, limit_freq = UINT_MAX;
> +	unsigned int max_freq;
> +
> +	/* check the constrainted frequency */

s/constrainted/constrained/ ?

> +	regmap_read(stub_clk->dfs_map, ACPU_DFS_FLAG, &limit_flag);
> +	if (limit_flag == ACPU_DFS_LOCK_FLAG)
> +		regmap_read(stub_clk->dfs_map, ACPU_DFS_FREQ_LMT, &limit_freq);
> +
> +	/* check the supported maximum frequency */
> +	regmap_read(stub_clk->dfs_map, ACPU_DFS_FREQ_MAX, &max_freq);
> +
> +	/* calculate the real maximum frequency */
> +	max_freq = min(max_freq, limit_freq);
> +
> +	if (WARN_ON(freq > max_freq))
> +		freq = max_freq;
> +
> +	return freq;
> +}
> +
> +static unsigned long hi6220_stub_clk_recalc_rate(struct clk_hw *hw,
> +		unsigned long parent_rate)
> +{
> +	u32 rate = 0;
> +	struct hi6220_stub_clk *stub_clk = to_stub_clk(hw);
> +
> +	switch (stub_clk->id) {
> +	case HI6220_STUB_ACPU0:
> +		rate = hi6220_acpu_get_freq(stub_clk);
> +
> +		/* convert from KHz to Hz */

s/KHz/kHz/ ?

> +		rate *= 1000;
> +		break;
> +
> +	default:
> +		dev_err(stub_clk->dev, "%s: un-supported clock id %d\n",
> +			__func__, stub_clk->id);
> +		break;
> +	}
> +
> +	return rate;
> +}
> +
> +static int hi6220_stub_clk_set_rate(struct clk_hw *hw, unsigned long rate,
> +                    unsigned long parent_rate)
> +{
> +	struct hi6220_stub_clk *stub_clk = to_stub_clk(hw);
> +	unsigned long new_rate = rate / 1000;  /* Khz */

s/KHz/kHz/ ?

> +	int ret = 0;
> +
> +	switch (stub_clk->id) {
> +	case HI6220_STUB_ACPU0:
> +		ret = hi6220_acpu_set_freq(stub_clk, new_rate);
> +		if (ret < 0)
> +			return ret;
> +
> +		break;
> +
> +	default:
> +		dev_err(stub_clk->dev, "%s: un-supported clock id %d\n",
> +			__func__, stub_clk->id);
> +		break;
> +	}
> +
> +	stub_clk->rate = new_rate;

Why do we store away the rate? Is this used anywhere?

> +
> +	pr_debug("%s: set rate=%ldKhz\n", __func__, new_rate);
> +	return ret;
> +}
> +
> +static long hi6220_stub_clk_round_rate(struct clk_hw *hw, unsigned long rate,
> +		unsigned long *parent_rate)
> +{
> +	struct hi6220_stub_clk *stub_clk = to_stub_clk(hw);
> +	unsigned long new_rate = rate / 1000;  /* Khz */

s/KHz/kHz/ ?

> +
> +	switch (stub_clk->id) {
> +	case HI6220_STUB_ACPU0:
> +		new_rate = hi6220_acpu_round_freq(stub_clk, new_rate);
> +
> +		/* convert from KHz to Hz */

s/KHz/kHz/ ?

> +		new_rate *= 1000;
> +		break;
> +
> +	default:
> +		dev_err(stub_clk->dev, "%s: un-supported clock id %d\n",
> +			__func__, stub_clk->id);
> +		break;
> +	}
> +
> +	return new_rate;
> +}
> +
> +static struct clk_ops hi6220_stub_clk_ops = {

const?

> +	.recalc_rate	= hi6220_stub_clk_recalc_rate,
> +	.round_rate	= hi6220_stub_clk_round_rate,
> +	.set_rate	= hi6220_stub_clk_set_rate,
> +};
> +
> +static int hi6220_stub_clk_probe(struct platform_device *pdev)
> +{
> +	struct device *dev = &pdev->dev;
> +	struct clk_init_data init;
> +	struct hi6220_stub_clk *stub_clk;
> +	struct clk *clk;
> +	struct device_node *np = pdev->dev.of_node;
> +
> +	stub_clk = devm_kzalloc(&pdev->dev, sizeof(*stub_clk), GFP_KERNEL);

just use dev?

> +	if (!stub_clk)
> +		return -ENOMEM;
> +
> +	stub_clk->dfs_map = syscon_regmap_lookup_by_phandle(np,
> +				"hisilicon,hi6220-clk-sram");
> +	if (IS_ERR(stub_clk->dfs_map)) {
> +		dev_err(dev, "failed to get sram regmap\n");
> +		return PTR_ERR(stub_clk->dfs_map);
> +	}
> +
> +	stub_clk->hw.init = &init;
> +	stub_clk->dev = dev;
> +	stub_clk->id = HI6220_STUB_ACPU0;
> +
> +	/* Use mailbox client with blocking mode */
> +	stub_clk->cl.dev = &pdev->dev;

just use dev?

> +	stub_clk->cl.tx_done = NULL;
> +	stub_clk->cl.tx_block = true;
> +	stub_clk->cl.tx_tout = 500;
> +	stub_clk->cl.knows_txdone = false;
> +
> +	init.name = "acpu0";
> +	init.ops = &hi6220_stub_clk_ops;
> +	init.num_parents = 0;
> +	init.flags = CLK_IS_ROOT;
> +
> +	clk = clk_register(NULL, &stub_clk->hw);

why not devm_clk_register?

> +	if (IS_ERR(clk))
> +		return PTR_ERR(clk);
> +
> +	of_clk_add_provider(pdev->dev.of_node, of_clk_src_simple_get, clk);

And check this for an error return value? Also, just use dev?

> +
> +	/* initialize buffer to zero */
> +	regmap_write(stub_clk->dfs_map, ACPU_DFS_FLAG, 0x0);
> +	regmap_write(stub_clk->dfs_map, ACPU_DFS_FREQ_REQ, 0x0);
> +	regmap_write(stub_clk->dfs_map, ACPU_DFS_FREQ_LMT, 0x0);
> +
> +	dev_dbg(&pdev->dev, "Registered clock '%s'\n", init.name);

just use dev?

> +	return 0;
> +}
> +
> +static const struct of_device_id hi6220_stub_clk_of_match[] = {
> +	{ .compatible = "hisilicon,hi6220-stub-clk", },
> +	{}
> +};
> +
> +static struct platform_driver hi6220_stub_clk_driver = {
> +	.driver	= {
> +		.name = "hi6220-stub-clk",
> +		.of_match_table = of_match_ptr(hi6220_stub_clk_of_match),

We can leave off of_match_ptr() here.

> +	},
> +	.probe = hi6220_stub_clk_probe,
> +};

-- 
Qualcomm Innovation Center, Inc. is a member of Code Aurora Forum,
a Linux Foundation Collaborative Project


From sergei.shtylyov at cogentembedded.com  Mon Aug  3 14:38:01 2015
From: sergei.shtylyov at cogentembedded.com (Sergei Shtylyov)
Date: Mon, 03 Aug 2015 14:38:01 -0700 (PDT)
Subject: [PATCH v2 1/2] ARM: shmobile: r8a7794: add GPIO clocks
In-Reply-To: <6388101.Drn6rL87rl@wasted.cogentembedded.com>
References: <6388101.Drn6rL87rl@wasted.cogentembedded.com>
Message-ID: <4462688.4GuBmS2g6G@wasted.cogentembedded.com>

Describe the GPIO clocks in the R8A7794 device tree.

Based on the original patch by Koji Matsuoka <koji.matsuoka.xm at renesas.com>.

Signed-off-by: Sergei Shtylyov <sergei.shtylyov at cogentembedded.com>
Acked-by: Geert Uytterhoeven <geert+renesas at glider.be>
Acked-by: Laurent Pinchart <laurent.pinchart at ideasonboard.com>

---
Changes in version 2:
- refreshed the patch;
- added Geert's and Laurent's ACKs.

 arch/arm/boot/dts/r8a7794.dtsi |   22 ++++++++++++++--------
 1 file changed, 14 insertions(+), 8 deletions(-)

Index: renesas/arch/arm/boot/dts/r8a7794.dtsi
===================================================================
--- renesas.orig/arch/arm/boot/dts/r8a7794.dtsi
+++ renesas/arch/arm/boot/dts/r8a7794.dtsi
@@ -720,16 +720,22 @@
 		mstp9_clks: mstp9_clks at e6150994 {
 			compatible = "renesas,r8a7794-mstp-clocks", "renesas,cpg-mstp-clocks";
 			reg = <0 0xe6150994 0 4>, <0 0xe61509a4 0 4>;
-			clocks = <&cpg_clocks R8A7794_CLK_QSPI>, <&hp_clk>, <&hp_clk>,
-				<&hp_clk>, <&hp_clk>, <&hp_clk>, <&hp_clk>;
+			clocks = <&cp_clk>, <&cp_clk>, <&cp_clk>, <&cp_clk>,
+				 <&cp_clk>, <&cp_clk>, <&cp_clk>,
+				 <&cpg_clocks R8A7794_CLK_QSPI>, <&hp_clk>, <&hp_clk>,
+				 <&hp_clk>, <&hp_clk>, <&hp_clk>, <&hp_clk>;
 			#clock-cells = <1>;
-			clock-indices = <
-				R8A7794_CLK_QSPI_MOD R8A7794_CLK_I2C5 R8A7794_CLK_I2C4
-				R8A7794_CLK_I2C3 R8A7794_CLK_I2C2 R8A7794_CLK_I2C1
-				R8A7794_CLK_I2C0
-			>;
+			clock-indices = <R8A7794_CLK_GPIO6 R8A7794_CLK_GPIO5
+					 R8A7794_CLK_GPIO4 R8A7794_CLK_GPIO3
+					 R8A7794_CLK_GPIO2 R8A7794_CLK_GPIO1
+					 R8A7794_CLK_GPIO0 R8A7794_CLK_QSPI_MOD
+					 R8A7794_CLK_I2C5 R8A7794_CLK_I2C4
+					 R8A7794_CLK_I2C3 R8A7794_CLK_I2C2
+					 R8A7794_CLK_I2C1 R8A7794_CLK_I2C0>;
 			clock-output-names =
-				"qspi_mod", "i2c5", "i2c4", "i2c3", "i2c2", "i2c1", "i2c0";
+				"gpio6", "gpio5", "gpio4", "gpio3", "gpio2",
+				"gpio1", "gpio0", "qspi_mod",
+				"i2c5", "i2c4", "i2c3", "i2c2", "i2c1", "i2c0";
 		};
 		mstp11_clks: mstp11_clks at e615099c {
 			compatible = "renesas,r8a7794-mstp-clocks", "renesas,cpg-mstp-clocks";



From sergei.shtylyov at cogentembedded.com  Mon Aug  3 14:39:14 2015
From: sergei.shtylyov at cogentembedded.com (Sergei Shtylyov)
Date: Tue, 04 Aug 2015 00:39:14 +0300
Subject: [PATCH v2 2/2] ARM: shmobile: r8a7794: add GPIO DT support
In-Reply-To: <6388101.Drn6rL87rl@wasted.cogentembedded.com>
References: <6388101.Drn6rL87rl@wasted.cogentembedded.com>
Message-ID: <2762710.QvQ3jKvG4A@wasted.cogentembedded.com>

Describe GPIO[0-6] controllers in the R8A7794 device tree.

Based on original patch by Hisashi Nakamura <hisashi.nakamura.ak at renesas.com>.

Signed-off-by: Sergei Shtylyov <sergei.shtylyov at cogentembedded.com>
Acked-by: Geert Uytterhoeven <geert+renesas at glider.be>

---
Changes in version 2:
- fixed "gpio-ranges" property's last value for GPIO1/5/6;
- added Geert's ACK.

 arch/arm/boot/dts/r8a7794.dtsi |   84 +++++++++++++++++++++++++++++++++++++++++
 1 file changed, 84 insertions(+)

Index: renesas/arch/arm/boot/dts/r8a7794.dtsi
===================================================================
--- renesas.orig/arch/arm/boot/dts/r8a7794.dtsi
+++ renesas/arch/arm/boot/dts/r8a7794.dtsi
@@ -50,6 +50,90 @@
 		interrupts = <1 9 (GIC_CPU_MASK_SIMPLE(2) | IRQ_TYPE_LEVEL_HIGH)>;
 	};
 
+	gpio0: gpio at e6050000 {
+		compatible = "renesas,gpio-r8a7794", "renesas,gpio-rcar";
+		reg = <0 0xe6050000 0 0x50>;
+		interrupts = <0 4 IRQ_TYPE_LEVEL_HIGH>;
+		#gpio-cells = <2>;
+		gpio-controller;
+		gpio-ranges = <&pfc 0 0 32>;
+		#interrupt-cells = <2>;
+		interrupt-controller;
+		clocks = <&mstp9_clks R8A7794_CLK_GPIO0>;
+	};
+
+	gpio1: gpio at e6051000 {
+		compatible = "renesas,gpio-r8a7794", "renesas,gpio-rcar";
+		reg = <0 0xe6051000 0 0x50>;
+		interrupts = <0 5 IRQ_TYPE_LEVEL_HIGH>;
+		#gpio-cells = <2>;
+		gpio-controller;
+		gpio-ranges = <&pfc 0 32 26>;
+		#interrupt-cells = <2>;
+		interrupt-controller;
+		clocks = <&mstp9_clks R8A7794_CLK_GPIO1>;
+	};
+
+	gpio2: gpio at e6052000 {
+		compatible = "renesas,gpio-r8a7794", "renesas,gpio-rcar";
+		reg = <0 0xe6052000 0 0x50>;
+		interrupts = <0 6 IRQ_TYPE_LEVEL_HIGH>;
+		#gpio-cells = <2>;
+		gpio-controller;
+		gpio-ranges = <&pfc 0 64 32>;
+		#interrupt-cells = <2>;
+		interrupt-controller;
+		clocks = <&mstp9_clks R8A7794_CLK_GPIO2>;
+	};
+
+	gpio3: gpio at e6053000 {
+		compatible = "renesas,gpio-r8a7794", "renesas,gpio-rcar";
+		reg = <0 0xe6053000 0 0x50>;
+		interrupts = <0 7 IRQ_TYPE_LEVEL_HIGH>;
+		#gpio-cells = <2>;
+		gpio-controller;
+		gpio-ranges = <&pfc 0 96 32>;
+		#interrupt-cells = <2>;
+		interrupt-controller;
+		clocks = <&mstp9_clks R8A7794_CLK_GPIO3>;
+	};
+
+	gpio4: gpio at e6054000 {
+		compatible = "renesas,gpio-r8a7794", "renesas,gpio-rcar";
+		reg = <0 0xe6054000 0 0x50>;
+		interrupts = <0 8 IRQ_TYPE_LEVEL_HIGH>;
+		#gpio-cells = <2>;
+		gpio-controller;
+		gpio-ranges = <&pfc 0 128 32>;
+		#interrupt-cells = <2>;
+		interrupt-controller;
+		clocks = <&mstp9_clks R8A7794_CLK_GPIO4>;
+	};
+
+	gpio5: gpio at e6055000 {
+		compatible = "renesas,gpio-r8a7794", "renesas,gpio-rcar";
+		reg = <0 0xe6055000 0 0x50>;
+		interrupts = <0 9 IRQ_TYPE_LEVEL_HIGH>;
+		#gpio-cells = <2>;
+		gpio-controller;
+		gpio-ranges = <&pfc 0 160 28>;
+		#interrupt-cells = <2>;
+		interrupt-controller;
+		clocks = <&mstp9_clks R8A7794_CLK_GPIO5>;
+	};
+
+	gpio6: gpio at e6055400 {
+		compatible = "renesas,gpio-r8a7794", "renesas,gpio-rcar";
+		reg = <0 0xe6055400 0 0x50>;
+		interrupts = <0 10 IRQ_TYPE_LEVEL_HIGH>;
+		#gpio-cells = <2>;
+		gpio-controller;
+		gpio-ranges = <&pfc 0 192 26>;
+		#interrupt-cells = <2>;
+		interrupt-controller;
+		clocks = <&mstp9_clks R8A7794_CLK_GPIO6>;
+	};
+
 	cmt0: timer at ffca0000 {
 		compatible = "renesas,cmt-48-gen2";
 		reg = <0 0xffca0000 0 0x1004>;



From sboyd at codeaurora.org  Mon Aug  3 14:46:03 2015
From: sboyd at codeaurora.org (Stephen Boyd)
Date: Mon, 3 Aug 2015 14:46:03 -0700
Subject: [PATCH v3 1/5] clk: hisi: refine parameter checking for init
In-Reply-To: <1438564418-15948-2-git-send-email-leo.yan@linaro.org>
References: <1438564418-15948-1-git-send-email-leo.yan@linaro.org>
 <1438564418-15948-2-git-send-email-leo.yan@linaro.org>
Message-ID: <20150803214603.GC21068@codeaurora.org>

On 08/03, Leo Yan wrote:
> *of_iomap()* will check the device node pointer, and if the pointer is
> NULL it will return error code. So refine clock's init flow by checking
> the device node with this simple way; and polish a little for the print
> out message.
> 
> Signed-off-by: Leo Yan <leo.yan at linaro.org>
> ---

Applied to clk-next

-- 
Qualcomm Innovation Center, Inc. is a member of Code Aurora Forum,
a Linux Foundation Collaborative Project


From bhelgaas at google.com  Mon Aug  3 15:34:36 2015
From: bhelgaas at google.com (Bjorn Helgaas)
Date: Mon, 3 Aug 2015 17:34:36 -0500
Subject: [PATCH] ARM/PCI: set MPS before pci_bus_add_devices()
In-Reply-To: <20150803191340.GM7557@n2100.arm.linux.org.uk>
References: <1437514519-18545-1-git-send-email-m-karicheri2@ti.com>
 <20150803191340.GM7557@n2100.arm.linux.org.uk>
Message-ID: <CAErSpo4PBKL9KFf80C6n8CwGRB6zq02rJ9i-LhG5RQYaYKcsWg@mail.gmail.com>

On Mon, Aug 3, 2015 at 2:13 PM, Russell King - ARM Linux
<linux at arm.linux.org.uk> wrote:
> On Tue, Jul 21, 2015 at 05:35:19PM -0400, Murali Karicheri wrote:
>> The MPS configuration should be done *before* pci_bus_add_devices().
>> After pci_bus_add_devices(), drivers may be bound to devices, and
>> the PCI core shouldn't touch device configuration while a driver
>> owns the device.
>>
>> Signed-off-by: Murali Karicheri <m-karicheri2 at ti.com>
>> Reported-by: Bjorn Helgaas <bhelgaas at google.com>
>> ---
>>  arch/arm/kernel/bios32.c | 19 +++++--------------
>>  1 file changed, 5 insertions(+), 14 deletions(-)
>>
>> diff --git a/arch/arm/kernel/bios32.c b/arch/arm/kernel/bios32.c
>> index fcbbbb1..17efde7 100644
>> --- a/arch/arm/kernel/bios32.c
>> +++ b/arch/arm/kernel/bios32.c
>> @@ -520,7 +520,8 @@ void pci_common_init_dev(struct device *parent, struct hw_pci *hw)
>>       list_for_each_entry(sys, &head, node) {
>>               struct pci_bus *bus = sys->bus;
>>
>> -             if (!pci_has_flag(PCI_PROBE_ONLY)) {
>> +             if (bus && !pci_has_flag(PCI_PROBE_ONLY)) {
>
> Let's get rid of that useless check.  bus can't be NULL here.
>
> In the original code (below) if bus was NULL, then we would've already
> oopsed before we got here.  As we don't oops here, no one is ever
> seeing it being NULL, so the test is redundant.
>
>> -     list_for_each_entry(sys, &head, node) {
>> -             struct pci_bus *bus = sys->bus;
>> -
>> -             /* Configure PCI Express settings */
>> -             if (bus && !pci_has_flag(PCI_PROBE_ONLY)) {
>

Sorry, I had forgotten to push this branch, but I did already get rid
of the check for bus being NULL:

http://git.kernel.org/cgit/linux/kernel/git/helgaas/pci.git/commit/?id=808b27a5ae05


From heiko at sntech.de  Mon Aug  3 15:38:03 2015
From: heiko at sntech.de (Heiko =?ISO-8859-1?Q?St=FCbner?=)
Date: Tue, 04 Aug 2015 00:38:03 +0200
Subject: [PATCH 1/2] ARM: dts: rockchip: reserve unusable memory region on
 rk3288
In-Reply-To: <CAD=FV=W2LSQh4e9+=ooTf34VzM_yPZn497DqSVEdb1kehZbqQQ@mail.gmail.com>
References: <15143985.aGzb1oeyb9@diego>
 <CAD=FV=W2LSQh4e9+=ooTf34VzM_yPZn497DqSVEdb1kehZbqQQ@mail.gmail.com>
Message-ID: <10674303.GIsaEKUXGC@diego>

Am Samstag, 1. August 2015, 14:32:32 schrieb Doug Anderson:
> Heiko
> 
> On Sat, Aug 1, 2015 at 5:35 AM, Heiko St?bner <heiko at sntech.de> wrote:
> > The rk3288 has problems accessing the memory region 0xfe000000~0xff000000.
> > So block off the affected region to prevent its use.
> > 
> > Tested on 4GB Veyron Minnie and 2GB Veyron Jerry devices.
> > 
> > Signed-off-by: Heiko Stuebner <heiko at sntech.de>
> > ---
> > 
> >  arch/arm/boot/dts/rk3288.dtsi | 10 ++++++++++
> >  1 file changed, 10 insertions(+)
> > 
> > diff --git a/arch/arm/boot/dts/rk3288.dtsi b/arch/arm/boot/dts/rk3288.dtsi
> > index 2db91c9..19766af 100644
> > --- a/arch/arm/boot/dts/rk3288.dtsi
> > +++ b/arch/arm/boot/dts/rk3288.dtsi
> > @@ -169,6 +169,16 @@
> > 
> >                 };
> >         
> >         };
> > 
> > +       reserved-memory {
> > +               #address-cells = <1>;
> > +               #size-cells = <1>;
> > +               ranges;
> > +
> > +               unusable at fe000000 {
> > +                       reg = <0xfe000000 0x1000000>;
> > +               };
> > +       };
> > +
> 
> I don't object to just reserving this memory, but I do object a little
> to this implementation.
> 
> It's 16 MB we're talking about here, which is pretty small compared to
> the 4G of memory that you must have when this is a problem.  However,
> at some point we might want to try to actually use this 16 MB.
> 
> The memory is actually _not_ unusable, it's only unusable for DMA.  In
> theory the kernel is supposed to have a way to mark memory as unusable
> for DMA which would then allow us to use this memory for non-DMA
> purposes...
> 
> Nobody ever managed to figure this out in the Chrome OS tree (it was
> 16 megs so we just reserved it and never got back around to it), but
> when folks were looking at it they looked at things like ZONE_DMA,
> dma_set_mask_and_coherent, etc.
> 
> In any case, to leave the door open for people to fix this in the
> future, it seems prudent to fix this in code like
> <https://chromium-review.googlesource.com/#/c/245107/> rather than to
> put the limit in DTS.

hmm, a counter argument in favor of even having the stopgap section disabling 
the memory in the dts might be, that as Jeffy said all current Rockchip socs 
are affected, even the rk3368.

So a future real solution would be declaring the usable dma area in devicetree 
anyway and not in kernel code. So in my mind devices can disable the memory 
for now in dt and later (once something usable is defined) can switch the soc-
level devicetree to this one, describing the actually usable dma area.

Old devicetrees would keep working anyway and could switch at their 
convenience. So I don't see a real transistion problem here (aka no API 
breakage or so)?


Heiko


From dianders at chromium.org  Mon Aug  3 15:52:13 2015
From: dianders at chromium.org (Doug Anderson)
Date: Mon, 3 Aug 2015 15:52:13 -0700
Subject: [PATCH 1/2] ARM: dts: rockchip: reserve unusable memory region on
 rk3288
In-Reply-To: <4605286.lfFsCUY5jc@diego>
References: <15143985.aGzb1oeyb9@diego>
 <CAD=FV=W2LSQh4e9+=ooTf34VzM_yPZn497DqSVEdb1kehZbqQQ@mail.gmail.com>
 <4605286.lfFsCUY5jc@diego>
Message-ID: <CAD=FV=VHsU08e5HB4bGoVNEy-nRG_f2SkxPOK6wu_BA=r4xVeA@mail.gmail.com>

Hi,

On Sat, Aug 1, 2015 at 3:52 PM, Heiko St?bner <heiko at sntech.de> wrote:

> The dt code when creating the platform-devices assumes a 32bit dma mask and
> expects the drivers to set the correct dma_masks (in of_dma_configure). But
> from the original description this looks more like a limitation of the rk3288,
> not the individual dwmmc, dwc2, etc.
>
> So from my cursory glance, ZONE_DMA seems to be the best solution. As you said
> that this was investigated too, do you know if they encountered any obstacles
> that resulted in not adjusting the dma zone?
>
>
> @Jeffy: do you know how widespread this is? I.e. are socs like the rk3128 or
> possibly more importantly the rk3368 also affected by this in 4GB
> configurations?
>
>
> If the rk3368 does it too, this might get "interesting". In one of the mails
> about ZONE_DMA from september 2014, Arnd mentioned that there was a patch
> about getting the zone size from devicetree floating around, but it doesn't
> look like this landed.

I don't actually know all the details of the problems since others
investigated.  I was just trying to quickly summarize what I could
find in the internal bug for the benefit of the list...  Sorry if
that's not terribly helpful.  :(

-Doug


From dianders at chromium.org  Mon Aug  3 15:53:46 2015
From: dianders at chromium.org (Doug Anderson)
Date: Mon, 3 Aug 2015 15:53:46 -0700
Subject: [PATCH 1/2] ARM: dts: rockchip: reserve unusable memory region on
 rk3288
In-Reply-To: <10674303.GIsaEKUXGC@diego>
References: <15143985.aGzb1oeyb9@diego>
 <CAD=FV=W2LSQh4e9+=ooTf34VzM_yPZn497DqSVEdb1kehZbqQQ@mail.gmail.com>
 <10674303.GIsaEKUXGC@diego>
Message-ID: <CAD=FV=V3=2azZJzNtfqBa-RZ_s+p5rbGFbPveRtuYudd_TJk6Q@mail.gmail.com>

Hi,

On Mon, Aug 3, 2015 at 3:38 PM, Heiko St?bner <heiko at sntech.de> wrote:
>> I don't object to just reserving this memory, but I do object a little
>> to this implementation.
>>
>> It's 16 MB we're talking about here, which is pretty small compared to
>> the 4G of memory that you must have when this is a problem.  However,
>> at some point we might want to try to actually use this 16 MB.
>>
>> The memory is actually _not_ unusable, it's only unusable for DMA.  In
>> theory the kernel is supposed to have a way to mark memory as unusable
>> for DMA which would then allow us to use this memory for non-DMA
>> purposes...
>>
>> Nobody ever managed to figure this out in the Chrome OS tree (it was
>> 16 megs so we just reserved it and never got back around to it), but
>> when folks were looking at it they looked at things like ZONE_DMA,
>> dma_set_mask_and_coherent, etc.
>>
>> In any case, to leave the door open for people to fix this in the
>> future, it seems prudent to fix this in code like
>> <https://chromium-review.googlesource.com/#/c/245107/> rather than to
>> put the limit in DTS.
>
> hmm, a counter argument in favor of even having the stopgap section disabling
> the memory in the dts might be, that as Jeffy said all current Rockchip socs
> are affected, even the rk3368.
>
> So a future real solution would be declaring the usable dma area in devicetree
> anyway and not in kernel code. So in my mind devices can disable the memory
> for now in dt and later (once something usable is defined) can switch the soc-
> level devicetree to this one, describing the actually usable dma area.
>
> Old devicetrees would keep working anyway and could switch at their
> convenience. So I don't see a real transistion problem here (aka no API
> breakage or so)?

OK, interesting point.

OK, we can do this in device tree, but we should probably at least
have a comment saying that it's only a problem for DMA?  ...or at
least something in the commit message?

-Doug


From eric at anholt.net  Mon Aug  3 16:23:09 2015
From: eric at anholt.net (Eric Anholt)
Date: Mon, 03 Aug 2015 16:23:09 -0700
Subject: [PATCH] irqchip: bcm2836: Use a CPU notifier enable IPIs.
In-Reply-To: <alpine.DEB.2.11.1508021221370.3825@nanos>
References: <55B67C81.1010900@gmail.com>
 <1438027789-1637-1-git-send-email-eric@anholt.net>
 <alpine.DEB.2.11.1508021221370.3825@nanos>
Message-ID: <87fv40lzxe.fsf@eliezer.anholt.net>

Thomas Gleixner <tglx at linutronix.de> writes:

> On Mon, 27 Jul 2015, Eric Anholt wrote:
>> +/* Unmasks the IPI on the CPU wen it's first brought online. */
>
> when
>
>> +static int bcm2836_arm_irqchip_cpu_notify(struct notifier_block *nfb,
>> +					  unsigned long action, void *hcpu)
>> +{
>> +	unsigned int cpu = (unsigned long)hcpu;
>> +	unsigned int int_reg = LOCAL_MAILBOX_INT_CONTROL0;
>> +	unsigned int mailbox = 0;
>> +
>> +	if (action == CPU_STARTING || action == CPU_STARTING_FROZEN)
>> +		bcm2836_arm_irqchip_unmask_per_cpu_irq(int_reg, mailbox, cpu);
>
> Shouldn't you mask the irq on CPU_DYING?

I was just following what other drivers were doing.  Is CPU_DYING the
only thing that needs masking?
-------------- next part --------------
A non-text attachment was scrubbed...
Name: signature.asc
Type: application/pgp-signature
Size: 818 bytes
Desc: not available
URL: <http://lists.infradead.org/pipermail/linux-arm-kernel/attachments/20150803/f573d5f4/attachment.sig>

From bhelgaas at google.com  Mon Aug  3 16:24:39 2015
From: bhelgaas at google.com (Bjorn Helgaas)
Date: Mon, 3 Aug 2015 18:24:39 -0500
Subject: [PATCH v3 1/2] PCI: generic: remove dependency on hw_pci
In-Reply-To: <20150803131131.GF10501@arm.com>
References: <1438183681-30519-1-git-send-email-jchandra@broadcom.com>
 <20150730133521.GA12999@red-moon>
 <20150731160654.GB31408@jayachandranc.netlogicmicro.com>
 <20150731162716.GA7182@red-moon> <20150803131131.GF10501@arm.com>
Message-ID: <20150803232439.GD11144@google.com>

On Mon, Aug 03, 2015 at 02:11:32PM +0100, Will Deacon wrote:
> Hi Jayachandran, Bjorn,
> 
> On Fri, Jul 31, 2015 at 05:27:16PM +0100, Lorenzo Pieralisi wrote:
> > On Fri, Jul 31, 2015 at 05:07:01PM +0100, Jayachandran C. wrote:
> > > On Thu, Jul 30, 2015 at 02:35:21PM +0100, Lorenzo Pieralisi wrote:
> > > > On Wed, Jul 29, 2015 at 04:28:00PM +0100, Jayachandran C wrote:
> > > > > -	pci_common_init_dev(dev, &hw);
> > > > > +	/* do not reassign resource if probe only */
> > > > > +	if (!pci_has_flag(PCI_PROBE_ONLY))
> > > > > +		pci_add_flags(PCI_REASSIGN_ALL_RSRC);
> > > > 
> > > > You should add PCI_REASSIGN_ALL_BUS here. As I said in patch 2 comment,
> > > 
> > > The idea is to do exactly what pci_common_init_dev does on ARM. There is
> > > not need to change behavior on ARM and deal with the fallout in this
> > > patchset.
> > 
> > You are enabling this driver on ARM64, and on ARM64 that flag does
> > make a difference, it does not on ARM as far as I can tell, but you do
> > not seem to care.
> > 
> > Actually Rob asked you to put together a function since most of
> > this code is replicated across ARM drivers eg:
> > 
> > drivers/pci/host/pci-versatile.c
> > 
> > Leave the code as it is and I will consolidate the code later.
> > 
> > > > please enable setup-irq.c in an explicit commit, re-sequence the
> > > > series and fold the Kconfig ARM64 enablement in this patch.
> > > 
> > > I would think that the Makefile and Kconfig changes should be
> > > togethter as the arm64 enablement patch. The previous patch is
> > > to update the gen_pci driver, and it really makes sense in that
> > > order.  I am not sure why you suggest this change.
> > 
> > Because this is not the only driver that requires compiling
> > drivers/pci/setup-irq.c on ARM64, I thought it made more sense
> > to do it in a separate patch to make that change standalone.
> > 
> > If for any reason we have to revert your patch that enables
> > PCI host generic on ARM64 (and we remove with it the compilation
> > of setup-irq.c) we would break other ARM64 PCI hosts that require it,
> > right ?
> > 
> > I leave the decision to Bjorn since I am away next week, I am fine
> > with the code as it is so please go ahead.
> 
> In the interest of getting something merged, can I suggest you
> (Jayachandran) repost the patches with Lorenzo's suggestions to reorder
> the series and split up the setup-irq compilation into a separate patch?
> 
> You can also add his ack to this patch.
> 
> It's a pity that the code isn't quite how we'd like it to end up, but
> this at least enables people for 4.3 and I know that Lorenzo is working
> on tidying up the loose ends as additional patches (but he's on holiday
> this week). That includes removal of the PROBE_ONLY bodge that I've got
> queued in arch/arm64/kernel/pci.c.
> 
> Bjorn, does that sound ok to you? I'm keen to have something working, as
> I'm starting to get beaten up about the lack of generic PCI on arm64.

Sounds good to me.


From drew.richardson at arm.com  Mon Aug  3 17:15:26 2015
From: drew.richardson at arm.com (Drew Richardson)
Date: Mon, 3 Aug 2015 17:15:26 -0700
Subject: [PATCH] arm: perf: Add event descriptions
Message-ID: <20150804001522.GA13214@dreric01-gentoo.localdomain>

Add additional information about hardware events to make counters self
describing. This makes the hardware PMUs easier to use as perf list
contains the possible events instead of users having to refer to
documentation like the ARM TRMs. This could also allow tools like
oprofile to support PMUs without requiring an update.

Signed-off-by: Drew Richardson <drew.richardson at arm.com>
---
 arch/arm/kernel/perf_event.c    |   1 +
 arch/arm/kernel/perf_event_v7.c | 617 ++++++++++++++++++++++++++++++++++++++++
 2 files changed, 618 insertions(+)

diff --git a/arch/arm/kernel/perf_event.c b/arch/arm/kernel/perf_event.c
index 54272e0be713..a7f2c84bae15 100644
--- a/arch/arm/kernel/perf_event.c
+++ b/arch/arm/kernel/perf_event.c
@@ -548,6 +548,7 @@ static void armpmu_init(struct arm_pmu *armpmu)
 		.stop		= armpmu_stop,
 		.read		= armpmu_read,
 		.filter_match	= armpmu_filter_match,
+		.attr_groups	= armpmu->pmu.attr_groups,
 	};
 }
 
diff --git a/arch/arm/kernel/perf_event_v7.c b/arch/arm/kernel/perf_event_v7.c
index f9b37f876e20..d46bc78b5997 100644
--- a/arch/arm/kernel/perf_event_v7.c
+++ b/arch/arm/kernel/perf_event_v7.c
@@ -547,6 +547,616 @@ static const unsigned scorpion_perf_cache_map[PERF_COUNT_HW_CACHE_MAX]
 	[C(BPU)][C(OP_WRITE)][C(RESULT_MISS)] = ARMV7_PERFCTR_PC_BRANCH_MIS_PRED,
 };
 
+static ssize_t armv7_event_show(struct device *dev,
+				struct device_attribute *attr, char *buf)
+{
+	struct dev_ext_attribute *ea = container_of(attr,
+						    struct dev_ext_attribute,
+						    attr);
+
+	return snprintf(buf, PAGE_SIZE, "%s\n", (char *)ea->var);
+}
+
+#define ARMV7_EVENT_ATTR(config, name) \
+	struct dev_ext_attribute armv7_event_attr_##config##_##name = \
+		{ __ATTR(name, S_IRUGO, armv7_event_show, NULL), \
+		  "config=0x" #config }
+
+static ARMV7_EVENT_ATTR(00, sw_incr);
+static ARMV7_EVENT_ATTR(01, l1i_cache_refill);
+static ARMV7_EVENT_ATTR(02, l1i_tlb_refill);
+static ARMV7_EVENT_ATTR(03, l1d_cache_refill);
+static ARMV7_EVENT_ATTR(04, l1d_cache);
+static ARMV7_EVENT_ATTR(05, l1d_tlb_refill);
+static ARMV7_EVENT_ATTR(06, ld_retired);
+static ARMV7_EVENT_ATTR(07, st_retired);
+static ARMV7_EVENT_ATTR(08, inst_retired);
+static ARMV7_EVENT_ATTR(09, exc_taken);
+static ARMV7_EVENT_ATTR(0a, exc_return);
+static ARMV7_EVENT_ATTR(0b, cid_write_retired);
+static ARMV7_EVENT_ATTR(0c, pc_write_retired);
+static ARMV7_EVENT_ATTR(0d, br_immed_retired);
+static ARMV7_EVENT_ATTR(0e, br_return_retired);
+static ARMV7_EVENT_ATTR(0f, unaligned_ldst_retired);
+static ARMV7_EVENT_ATTR(10, br_mis_pred);
+static ARMV7_EVENT_ATTR(11, cpu_cycles);
+static ARMV7_EVENT_ATTR(12, br_pred);
+static ARMV7_EVENT_ATTR(13, mem_access);
+static ARMV7_EVENT_ATTR(14, l1i_cache);
+static ARMV7_EVENT_ATTR(15, l1d_cache_wb);
+static ARMV7_EVENT_ATTR(16, l2d_cache);
+static ARMV7_EVENT_ATTR(17, l2d_cache_refill);
+static ARMV7_EVENT_ATTR(18, l2d_cache_wb);
+static ARMV7_EVENT_ATTR(19, bus_access);
+static ARMV7_EVENT_ATTR(1a, memory_error);
+static ARMV7_EVENT_ATTR(1b, inst_spec);
+static ARMV7_EVENT_ATTR(1c, ttbr_write_retired);
+static ARMV7_EVENT_ATTR(1d, bus_cycles);
+static ARMV7_EVENT_ATTR(40, java_bc_exec);
+static ARMV7_EVENT_ATTR(40, l1d_cache_ld);
+static ARMV7_EVENT_ATTR(40, wb_full);
+static ARMV7_EVENT_ATTR(41, java_swbc_exec);
+static ARMV7_EVENT_ATTR(41, l1d_cache_st);
+static ARMV7_EVENT_ATTR(41, l2_store_merged);
+static ARMV7_EVENT_ATTR(42, jazelle_branch_executed);
+static ARMV7_EVENT_ATTR(42, l1d_cache_refill_ld);
+static ARMV7_EVENT_ATTR(42, l2_store_bufferable);
+static ARMV7_EVENT_ATTR(43, l1d_cache_refill_st);
+static ARMV7_EVENT_ATTR(43, l2_access);
+static ARMV7_EVENT_ATTR(44, l2_miss);
+static ARMV7_EVENT_ATTR(45, axi_read);
+static ARMV7_EVENT_ATTR(46, axi_write);
+static ARMV7_EVENT_ATTR(46, l1d_cache_wb_victim);
+static ARMV7_EVENT_ATTR(47, l1d_cache_wb_clean);
+static ARMV7_EVENT_ATTR(47, mem_replay);
+static ARMV7_EVENT_ATTR(48, l1d_cache_inval);
+static ARMV7_EVENT_ATTR(48, mem_replay_unaligned);
+static ARMV7_EVENT_ATTR(49, l1d_miss_hash);
+static ARMV7_EVENT_ATTR(4a, l1i_miss_hash);
+static ARMV7_EVENT_ATTR(4b, l1d_page_coloring);
+static ARMV7_EVENT_ATTR(4c, l1d_hit_neon);
+static ARMV7_EVENT_ATTR(4c, l1d_tlb_refill_ld);
+static ARMV7_EVENT_ATTR(4d, l1d_access_neon);
+static ARMV7_EVENT_ATTR(4d, l1d_tlb_refill_st);
+static ARMV7_EVENT_ATTR(4e, l2_access_neon);
+static ARMV7_EVENT_ATTR(4f, l2_hit_neon);
+static ARMV7_EVENT_ATTR(50, coherent_miss);
+static ARMV7_EVENT_ATTR(50, l1i_access);
+static ARMV7_EVENT_ATTR(50, l2d_cache_ld);
+static ARMV7_EVENT_ATTR(51, coherent_hit);
+static ARMV7_EVENT_ATTR(51, l2d_cache_st);
+static ARMV7_EVENT_ATTR(51, return_mispredict);
+static ARMV7_EVENT_ATTR(52, branch_mispredict);
+static ARMV7_EVENT_ATTR(52, l2d_cache_refill_ld);
+static ARMV7_EVENT_ATTR(53, branch_predict_taken);
+static ARMV7_EVENT_ATTR(53, l2d_cache_refill_st);
+static ARMV7_EVENT_ATTR(54, branch_predictable_taken);
+static ARMV7_EVENT_ATTR(55, operation_issued);
+static ARMV7_EVENT_ATTR(56, inst_stall);
+static ARMV7_EVENT_ATTR(56, l2d_cache_wb_victim);
+static ARMV7_EVENT_ATTR(57, inst_issued);
+static ARMV7_EVENT_ATTR(57, l2d_cache_wb_clean);
+static ARMV7_EVENT_ATTR(58, l2d_cache_inval);
+static ARMV7_EVENT_ATTR(58, stall_neon_data);
+static ARMV7_EVENT_ATTR(59, stall_neon_inst);
+static ARMV7_EVENT_ATTR(5a, int_neon_busy);
+static ARMV7_EVENT_ATTR(60, bus_access_ld);
+static ARMV7_EVENT_ATTR(60, stall_inst);
+static ARMV7_EVENT_ATTR(61, bus_access_st);
+static ARMV7_EVENT_ATTR(61, stall_data);
+static ARMV7_EVENT_ATTR(62, bus_access_shared);
+static ARMV7_EVENT_ATTR(62, stall_tlb);
+static ARMV7_EVENT_ATTR(63, bus_access_not_shared);
+static ARMV7_EVENT_ATTR(63, strex_pass);
+static ARMV7_EVENT_ATTR(64, bus_access_normal);
+static ARMV7_EVENT_ATTR(64, strex_failed);
+static ARMV7_EVENT_ATTR(65, bus_access_periph);
+static ARMV7_EVENT_ATTR(65, data_evict);
+static ARMV7_EVENT_ATTR(66, issue_no_dispatch);
+static ARMV7_EVENT_ATTR(66, mem_access_ld);
+static ARMV7_EVENT_ATTR(67, issue_empty);
+static ARMV7_EVENT_ATTR(67, mem_access_st);
+static ARMV7_EVENT_ATTR(68, inst_exec);
+static ARMV7_EVENT_ATTR(68, unaligned_ld_spec);
+static ARMV7_EVENT_ATTR(69, cache_linefill);
+static ARMV7_EVENT_ATTR(69, unaligned_st_spec);
+static ARMV7_EVENT_ATTR(6a, prefetch_linefill);
+static ARMV7_EVENT_ATTR(6a, unaligned_ldst_spec);
+static ARMV7_EVENT_ATTR(6b, prefetch_hit);
+static ARMV7_EVENT_ATTR(6c, ldrex_spec);
+static ARMV7_EVENT_ATTR(6d, strex_pass_spec);
+static ARMV7_EVENT_ATTR(6e, predictable_ret);
+static ARMV7_EVENT_ATTR(6e, strex_fail_spec);
+static ARMV7_EVENT_ATTR(6f, strex_spec);
+static ARMV7_EVENT_ATTR(70, inst_main_exec);
+static ARMV7_EVENT_ATTR(70, ld_spec);
+static ARMV7_EVENT_ATTR(70, pmuextin0);
+static ARMV7_EVENT_ATTR(71, inst_second_exec);
+static ARMV7_EVENT_ATTR(71, pmuextin1);
+static ARMV7_EVENT_ATTR(71, st_spec);
+static ARMV7_EVENT_ATTR(72, inst_load_store);
+static ARMV7_EVENT_ATTR(72, ldst_spec);
+static ARMV7_EVENT_ATTR(72, pmuextin);
+static ARMV7_EVENT_ATTR(73, dp_spec);
+static ARMV7_EVENT_ATTR(73, inst_fp);
+static ARMV7_EVENT_ATTR(74, ase_spec);
+static ARMV7_EVENT_ATTR(74, inst_neon);
+static ARMV7_EVENT_ATTR(75, vfp_spec);
+static ARMV7_EVENT_ATTR(76, pc_write_spec);
+static ARMV7_EVENT_ATTR(78, br_immed_spec);
+static ARMV7_EVENT_ATTR(79, br_return_spec);
+static ARMV7_EVENT_ATTR(7a, br_indirect_spec);
+static ARMV7_EVENT_ATTR(7c, isb_spec);
+static ARMV7_EVENT_ATTR(7d, dsb_spec);
+static ARMV7_EVENT_ATTR(7e, dmb_spec);
+static ARMV7_EVENT_ATTR(80, stall_pld);
+static ARMV7_EVENT_ATTR(81, exc_undef);
+static ARMV7_EVENT_ATTR(81, stall_write);
+static ARMV7_EVENT_ATTR(82, stall_inst_tlb);
+static ARMV7_EVENT_ATTR(83, stall_data_tlb);
+static ARMV7_EVENT_ATTR(84, stall_inst_mtlb);
+static ARMV7_EVENT_ATTR(85, stall_data_mtlb);
+static ARMV7_EVENT_ATTR(86, exc_irq);
+static ARMV7_EVENT_ATTR(86, stall_dmb);
+static ARMV7_EVENT_ATTR(87, exc_fiq);
+static ARMV7_EVENT_ATTR(8a, clock_int);
+static ARMV7_EVENT_ATTR(8a, exc_hvc);
+static ARMV7_EVENT_ATTR(8b, clock_data);
+static ARMV7_EVENT_ATTR(8c, clock_neon);
+static ARMV7_EVENT_ATTR(8d, tlb_inst);
+static ARMV7_EVENT_ATTR(8e, tlb_data);
+static ARMV7_EVENT_ATTR(90, inst_isb);
+static ARMV7_EVENT_ATTR(91, inst_dsb);
+static ARMV7_EVENT_ATTR(92, inst_dmb);
+static ARMV7_EVENT_ATTR(93, ext_irq);
+static ARMV7_EVENT_ATTR(c0, ext_mem_req);
+static ARMV7_EVENT_ATTR(c0, stall_inst_linefill);
+static ARMV7_EVENT_ATTR(c1, ext_mem_req_nc);
+static ARMV7_EVENT_ATTR(c1, stall_inst_tlb);
+static ARMV7_EVENT_ATTR(c2, cache_tag);
+static ARMV7_EVENT_ATTR(c2, prefetch_linefill);
+static ARMV7_EVENT_ATTR(c3, cache_data);
+static ARMV7_EVENT_ATTR(c3, prefetch_linefill_drop);
+static ARMV7_EVENT_ATTR(c4, cache_btac);
+static ARMV7_EVENT_ATTR(c4, read_alloc_enter);
+static ARMV7_EVENT_ATTR(c5, read_alloc);
+static ARMV7_EVENT_ATTR(c7, etm_out0);
+static ARMV7_EVENT_ATTR(c8, etm_out1);
+static ARMV7_EVENT_ATTR(c9, stall_sb_full);
+static ARMV7_EVENT_ATTR(ca, local_cluster_snoop);
+static ARMV7_EVENT_ATTR(d3, busy_lsu);
+static ARMV7_EVENT_ATTR(d8, busy_lsi);
+static ARMV7_EVENT_ATTR(d9, busy_dpi);
+static ARMV7_EVENT_ATTR(da, busy_dei);
+static ARMV7_EVENT_ATTR(db, neon_cond_fail);
+static ARMV7_EVENT_ATTR(dc, trap_hv);
+static ARMV7_EVENT_ATTR(de, ptm_extout0);
+static ARMV7_EVENT_ATTR(df, ptm_extout1);
+static ARMV7_EVENT_ATTR(e0, mmu_walk);
+static ARMV7_EVENT_ATTR(e1, mmu_s1_walk);
+static ARMV7_EVENT_ATTR(e2, mmu_s2_walk);
+static ARMV7_EVENT_ATTR(e3, mmu_lsu_walk);
+static ARMV7_EVENT_ATTR(e4, mmu_inst_walk);
+static ARMV7_EVENT_ATTR(e5, mmu_pre_walk);
+static ARMV7_EVENT_ATTR(e6, mmu_cp15_walk);
+static ARMV7_EVENT_ATTR(e7, tlb_pld_refill);
+static ARMV7_EVENT_ATTR(e8, tlb_cp15_refill);
+static ARMV7_EVENT_ATTR(e9, tlb_flush);
+static ARMV7_EVENT_ATTR(ea, tlb_access);
+static ARMV7_EVENT_ATTR(eb, tlb_miss);
+
+static struct attribute *armv7_a8_event_attrs[] = {
+	&armv7_event_attr_00_sw_incr.attr.attr,
+	&armv7_event_attr_01_l1i_cache_refill.attr.attr,
+	&armv7_event_attr_02_l1i_tlb_refill.attr.attr,
+	&armv7_event_attr_03_l1d_cache_refill.attr.attr,
+	&armv7_event_attr_04_l1d_cache.attr.attr,
+	&armv7_event_attr_05_l1d_tlb_refill.attr.attr,
+	&armv7_event_attr_06_ld_retired.attr.attr,
+	&armv7_event_attr_07_st_retired.attr.attr,
+	&armv7_event_attr_08_inst_retired.attr.attr,
+	&armv7_event_attr_09_exc_taken.attr.attr,
+	&armv7_event_attr_0a_exc_return.attr.attr,
+	&armv7_event_attr_0b_cid_write_retired.attr.attr,
+	&armv7_event_attr_0c_pc_write_retired.attr.attr,
+	&armv7_event_attr_0d_br_immed_retired.attr.attr,
+	&armv7_event_attr_0e_br_return_retired.attr.attr,
+	&armv7_event_attr_0f_unaligned_ldst_retired.attr.attr,
+	&armv7_event_attr_10_br_mis_pred.attr.attr,
+	&armv7_event_attr_11_cpu_cycles.attr.attr,
+	&armv7_event_attr_12_br_pred.attr.attr,
+	&armv7_event_attr_40_wb_full.attr.attr,
+	&armv7_event_attr_41_l2_store_merged.attr.attr,
+	&armv7_event_attr_42_l2_store_bufferable.attr.attr,
+	&armv7_event_attr_43_l2_access.attr.attr,
+	&armv7_event_attr_44_l2_miss.attr.attr,
+	&armv7_event_attr_45_axi_read.attr.attr,
+	&armv7_event_attr_46_axi_write.attr.attr,
+	&armv7_event_attr_47_mem_replay.attr.attr,
+	&armv7_event_attr_48_mem_replay_unaligned.attr.attr,
+	&armv7_event_attr_49_l1d_miss_hash.attr.attr,
+	&armv7_event_attr_4a_l1i_miss_hash.attr.attr,
+	&armv7_event_attr_4b_l1d_page_coloring.attr.attr,
+	&armv7_event_attr_4c_l1d_hit_neon.attr.attr,
+	&armv7_event_attr_4d_l1d_access_neon.attr.attr,
+	&armv7_event_attr_4e_l2_access_neon.attr.attr,
+	&armv7_event_attr_4f_l2_hit_neon.attr.attr,
+	&armv7_event_attr_50_l1i_access.attr.attr,
+	&armv7_event_attr_51_return_mispredict.attr.attr,
+	&armv7_event_attr_52_branch_mispredict.attr.attr,
+	&armv7_event_attr_53_branch_predict_taken.attr.attr,
+	&armv7_event_attr_54_branch_predictable_taken.attr.attr,
+	&armv7_event_attr_55_operation_issued.attr.attr,
+	&armv7_event_attr_56_inst_stall.attr.attr,
+	&armv7_event_attr_57_inst_issued.attr.attr,
+	&armv7_event_attr_58_stall_neon_data.attr.attr,
+	&armv7_event_attr_59_stall_neon_inst.attr.attr,
+	&armv7_event_attr_5a_int_neon_busy.attr.attr,
+	&armv7_event_attr_70_pmuextin0.attr.attr,
+	&armv7_event_attr_71_pmuextin1.attr.attr,
+	&armv7_event_attr_72_pmuextin.attr.attr,
+	NULL
+};
+
+static struct attribute_group armv7_a8_events_attr_group = {
+	.name = "events",
+	.attrs = armv7_a8_event_attrs,
+};
+
+static const struct attribute_group *armv7_a8_attr_groups[] = {
+	&armv7_a8_events_attr_group,
+	NULL
+};
+
+static struct attribute *armv7_a9_event_attrs[] = {
+	&armv7_event_attr_00_sw_incr.attr.attr,
+	&armv7_event_attr_01_l1i_cache_refill.attr.attr,
+	&armv7_event_attr_02_l1i_tlb_refill.attr.attr,
+	&armv7_event_attr_03_l1d_cache_refill.attr.attr,
+	&armv7_event_attr_04_l1d_cache.attr.attr,
+	&armv7_event_attr_05_l1d_tlb_refill.attr.attr,
+	&armv7_event_attr_06_ld_retired.attr.attr,
+	&armv7_event_attr_07_st_retired.attr.attr,
+	&armv7_event_attr_09_exc_taken.attr.attr,
+	&armv7_event_attr_0a_exc_return.attr.attr,
+	&armv7_event_attr_0b_cid_write_retired.attr.attr,
+	&armv7_event_attr_0c_pc_write_retired.attr.attr,
+	&armv7_event_attr_0d_br_immed_retired.attr.attr,
+	&armv7_event_attr_0f_unaligned_ldst_retired.attr.attr,
+	&armv7_event_attr_10_br_mis_pred.attr.attr,
+	&armv7_event_attr_11_cpu_cycles.attr.attr,
+	&armv7_event_attr_12_br_pred.attr.attr,
+	&armv7_event_attr_40_java_bc_exec.attr.attr,
+	&armv7_event_attr_41_java_swbc_exec.attr.attr,
+	&armv7_event_attr_42_jazelle_branch_executed.attr.attr,
+	&armv7_event_attr_50_coherent_miss.attr.attr,
+	&armv7_event_attr_51_coherent_hit.attr.attr,
+	&armv7_event_attr_60_stall_inst.attr.attr,
+	&armv7_event_attr_61_stall_data.attr.attr,
+	&armv7_event_attr_62_stall_tlb.attr.attr,
+	&armv7_event_attr_63_strex_pass.attr.attr,
+	&armv7_event_attr_64_strex_failed.attr.attr,
+	&armv7_event_attr_65_data_evict.attr.attr,
+	&armv7_event_attr_66_issue_no_dispatch.attr.attr,
+	&armv7_event_attr_67_issue_empty.attr.attr,
+	&armv7_event_attr_68_inst_exec.attr.attr,
+	&armv7_event_attr_69_cache_linefill.attr.attr,
+	&armv7_event_attr_6a_prefetch_linefill.attr.attr,
+	&armv7_event_attr_6b_prefetch_hit.attr.attr,
+	&armv7_event_attr_6e_predictable_ret.attr.attr,
+	&armv7_event_attr_70_inst_main_exec.attr.attr,
+	&armv7_event_attr_71_inst_second_exec.attr.attr,
+	&armv7_event_attr_72_inst_load_store.attr.attr,
+	&armv7_event_attr_73_inst_fp.attr.attr,
+	&armv7_event_attr_74_inst_neon.attr.attr,
+	&armv7_event_attr_80_stall_pld.attr.attr,
+	&armv7_event_attr_81_stall_write.attr.attr,
+	&armv7_event_attr_82_stall_inst_tlb.attr.attr,
+	&armv7_event_attr_83_stall_data_tlb.attr.attr,
+	&armv7_event_attr_84_stall_inst_mtlb.attr.attr,
+	&armv7_event_attr_85_stall_data_mtlb.attr.attr,
+	&armv7_event_attr_86_stall_dmb.attr.attr,
+	&armv7_event_attr_8a_clock_int.attr.attr,
+	&armv7_event_attr_8b_clock_data.attr.attr,
+	&armv7_event_attr_8c_clock_neon.attr.attr,
+	&armv7_event_attr_8d_tlb_inst.attr.attr,
+	&armv7_event_attr_8e_tlb_data.attr.attr,
+	&armv7_event_attr_90_inst_isb.attr.attr,
+	&armv7_event_attr_91_inst_dsb.attr.attr,
+	&armv7_event_attr_92_inst_dmb.attr.attr,
+	&armv7_event_attr_93_ext_irq.attr.attr,
+	NULL
+};
+
+static struct attribute_group armv7_a9_events_attr_group = {
+	.name = "events",
+	.attrs = armv7_a9_event_attrs,
+};
+
+static const struct attribute_group *armv7_a9_attr_groups[] = {
+	&armv7_a9_events_attr_group,
+	NULL
+};
+
+static struct attribute *armv7_a5_event_attrs[] = {
+	&armv7_event_attr_00_sw_incr.attr.attr,
+	&armv7_event_attr_01_l1i_cache_refill.attr.attr,
+	&armv7_event_attr_02_l1i_tlb_refill.attr.attr,
+	&armv7_event_attr_03_l1d_cache_refill.attr.attr,
+	&armv7_event_attr_04_l1d_cache.attr.attr,
+	&armv7_event_attr_05_l1d_tlb_refill.attr.attr,
+	&armv7_event_attr_06_ld_retired.attr.attr,
+	&armv7_event_attr_07_st_retired.attr.attr,
+	&armv7_event_attr_08_inst_retired.attr.attr,
+	&armv7_event_attr_09_exc_taken.attr.attr,
+	&armv7_event_attr_0a_exc_return.attr.attr,
+	&armv7_event_attr_0b_cid_write_retired.attr.attr,
+	&armv7_event_attr_0c_pc_write_retired.attr.attr,
+	&armv7_event_attr_0d_br_immed_retired.attr.attr,
+	&armv7_event_attr_0e_br_return_retired.attr.attr,
+	&armv7_event_attr_0f_unaligned_ldst_retired.attr.attr,
+	&armv7_event_attr_10_br_mis_pred.attr.attr,
+	&armv7_event_attr_11_cpu_cycles.attr.attr,
+	&armv7_event_attr_12_br_pred.attr.attr,
+	&armv7_event_attr_13_mem_access.attr.attr,
+	&armv7_event_attr_14_l1i_cache.attr.attr,
+	&armv7_event_attr_15_l1d_cache_wb.attr.attr,
+	&armv7_event_attr_86_exc_irq.attr.attr,
+	&armv7_event_attr_87_exc_fiq.attr.attr,
+	&armv7_event_attr_c0_ext_mem_req.attr.attr,
+	&armv7_event_attr_c1_ext_mem_req_nc.attr.attr,
+	&armv7_event_attr_c2_prefetch_linefill.attr.attr,
+	&armv7_event_attr_c3_prefetch_linefill_drop.attr.attr,
+	&armv7_event_attr_c4_read_alloc_enter.attr.attr,
+	&armv7_event_attr_c5_read_alloc.attr.attr,
+	&armv7_event_attr_c7_etm_out0.attr.attr,
+	&armv7_event_attr_c8_etm_out1.attr.attr,
+	&armv7_event_attr_c9_stall_sb_full.attr.attr,
+	NULL
+};
+
+static struct attribute_group armv7_a5_events_attr_group = {
+	.name = "events",
+	.attrs = armv7_a5_event_attrs,
+};
+
+static const struct attribute_group *armv7_a5_attr_groups[] = {
+	&armv7_a5_events_attr_group,
+	NULL
+};
+
+static struct attribute *armv7_a15_event_attrs[] = {
+	&armv7_event_attr_00_sw_incr.attr.attr,
+	&armv7_event_attr_01_l1i_cache_refill.attr.attr,
+	&armv7_event_attr_02_l1i_tlb_refill.attr.attr,
+	&armv7_event_attr_03_l1d_cache_refill.attr.attr,
+	&armv7_event_attr_04_l1d_cache.attr.attr,
+	&armv7_event_attr_05_l1d_tlb_refill.attr.attr,
+	&armv7_event_attr_08_inst_retired.attr.attr,
+	&armv7_event_attr_09_exc_taken.attr.attr,
+	&armv7_event_attr_0a_exc_return.attr.attr,
+	&armv7_event_attr_0b_cid_write_retired.attr.attr,
+	&armv7_event_attr_10_br_mis_pred.attr.attr,
+	&armv7_event_attr_11_cpu_cycles.attr.attr,
+	&armv7_event_attr_12_br_pred.attr.attr,
+	&armv7_event_attr_13_mem_access.attr.attr,
+	&armv7_event_attr_14_l1i_cache.attr.attr,
+	&armv7_event_attr_15_l1d_cache_wb.attr.attr,
+	&armv7_event_attr_16_l2d_cache.attr.attr,
+	&armv7_event_attr_17_l2d_cache_refill.attr.attr,
+	&armv7_event_attr_18_l2d_cache_wb.attr.attr,
+	&armv7_event_attr_19_bus_access.attr.attr,
+	&armv7_event_attr_1a_memory_error.attr.attr,
+	&armv7_event_attr_1b_inst_spec.attr.attr,
+	&armv7_event_attr_1c_ttbr_write_retired.attr.attr,
+	&armv7_event_attr_1d_bus_cycles.attr.attr,
+	&armv7_event_attr_40_l1d_cache_ld.attr.attr,
+	&armv7_event_attr_41_l1d_cache_st.attr.attr,
+	&armv7_event_attr_42_l1d_cache_refill_ld.attr.attr,
+	&armv7_event_attr_43_l1d_cache_refill_st.attr.attr,
+	&armv7_event_attr_46_l1d_cache_wb_victim.attr.attr,
+	&armv7_event_attr_47_l1d_cache_wb_clean.attr.attr,
+	&armv7_event_attr_48_l1d_cache_inval.attr.attr,
+	&armv7_event_attr_4c_l1d_tlb_refill_ld.attr.attr,
+	&armv7_event_attr_4d_l1d_tlb_refill_st.attr.attr,
+	&armv7_event_attr_50_l2d_cache_ld.attr.attr,
+	&armv7_event_attr_51_l2d_cache_st.attr.attr,
+	&armv7_event_attr_52_l2d_cache_refill_ld.attr.attr,
+	&armv7_event_attr_53_l2d_cache_refill_st.attr.attr,
+	&armv7_event_attr_56_l2d_cache_wb_victim.attr.attr,
+	&armv7_event_attr_57_l2d_cache_wb_clean.attr.attr,
+	&armv7_event_attr_58_l2d_cache_inval.attr.attr,
+	&armv7_event_attr_60_bus_access_ld.attr.attr,
+	&armv7_event_attr_61_bus_access_st.attr.attr,
+	&armv7_event_attr_62_bus_access_shared.attr.attr,
+	&armv7_event_attr_63_bus_access_not_shared.attr.attr,
+	&armv7_event_attr_64_bus_access_normal.attr.attr,
+	&armv7_event_attr_65_bus_access_periph.attr.attr,
+	&armv7_event_attr_66_mem_access_ld.attr.attr,
+	&armv7_event_attr_67_mem_access_st.attr.attr,
+	&armv7_event_attr_68_unaligned_ld_spec.attr.attr,
+	&armv7_event_attr_69_unaligned_st_spec.attr.attr,
+	&armv7_event_attr_6a_unaligned_ldst_spec.attr.attr,
+	&armv7_event_attr_6c_ldrex_spec.attr.attr,
+	&armv7_event_attr_6d_strex_pass_spec.attr.attr,
+	&armv7_event_attr_6e_strex_fail_spec.attr.attr,
+	&armv7_event_attr_70_ld_spec.attr.attr,
+	&armv7_event_attr_71_st_spec.attr.attr,
+	&armv7_event_attr_72_ldst_spec.attr.attr,
+	&armv7_event_attr_73_dp_spec.attr.attr,
+	&armv7_event_attr_74_ase_spec.attr.attr,
+	&armv7_event_attr_75_vfp_spec.attr.attr,
+	&armv7_event_attr_76_pc_write_spec.attr.attr,
+	&armv7_event_attr_78_br_immed_spec.attr.attr,
+	&armv7_event_attr_79_br_return_spec.attr.attr,
+	&armv7_event_attr_7a_br_indirect_spec.attr.attr,
+	&armv7_event_attr_7c_isb_spec.attr.attr,
+	&armv7_event_attr_7d_dsb_spec.attr.attr,
+	&armv7_event_attr_7e_dmb_spec.attr.attr,
+	NULL
+};
+
+static struct attribute_group armv7_a15_events_attr_group = {
+	.name = "events",
+	.attrs = armv7_a15_event_attrs,
+};
+
+static const struct attribute_group *armv7_a15_attr_groups[] = {
+	&armv7_a15_events_attr_group,
+	NULL
+};
+
+static struct attribute *armv7_a7_event_attrs[] = {
+	&armv7_event_attr_00_sw_incr.attr.attr,
+	&armv7_event_attr_01_l1i_cache_refill.attr.attr,
+	&armv7_event_attr_02_l1i_tlb_refill.attr.attr,
+	&armv7_event_attr_03_l1d_cache_refill.attr.attr,
+	&armv7_event_attr_04_l1d_cache.attr.attr,
+	&armv7_event_attr_05_l1d_tlb_refill.attr.attr,
+	&armv7_event_attr_06_ld_retired.attr.attr,
+	&armv7_event_attr_07_st_retired.attr.attr,
+	&armv7_event_attr_08_inst_retired.attr.attr,
+	&armv7_event_attr_09_exc_taken.attr.attr,
+	&armv7_event_attr_0a_exc_return.attr.attr,
+	&armv7_event_attr_0b_cid_write_retired.attr.attr,
+	&armv7_event_attr_0c_pc_write_retired.attr.attr,
+	&armv7_event_attr_0d_br_immed_retired.attr.attr,
+	&armv7_event_attr_0e_br_return_retired.attr.attr,
+	&armv7_event_attr_0f_unaligned_ldst_retired.attr.attr,
+	&armv7_event_attr_10_br_mis_pred.attr.attr,
+	&armv7_event_attr_11_cpu_cycles.attr.attr,
+	&armv7_event_attr_12_br_pred.attr.attr,
+	&armv7_event_attr_13_mem_access.attr.attr,
+	&armv7_event_attr_14_l1i_cache.attr.attr,
+	&armv7_event_attr_15_l1d_cache_wb.attr.attr,
+	&armv7_event_attr_16_l2d_cache.attr.attr,
+	&armv7_event_attr_17_l2d_cache_refill.attr.attr,
+	&armv7_event_attr_18_l2d_cache_wb.attr.attr,
+	&armv7_event_attr_19_bus_access.attr.attr,
+	&armv7_event_attr_1d_bus_cycles.attr.attr,
+	&armv7_event_attr_60_bus_access_ld.attr.attr,
+	&armv7_event_attr_61_bus_access_st.attr.attr,
+	&armv7_event_attr_86_exc_irq.attr.attr,
+	&armv7_event_attr_87_exc_fiq.attr.attr,
+	&armv7_event_attr_c0_ext_mem_req.attr.attr,
+	&armv7_event_attr_c1_ext_mem_req_nc.attr.attr,
+	&armv7_event_attr_c2_prefetch_linefill.attr.attr,
+	&armv7_event_attr_c3_prefetch_linefill_drop.attr.attr,
+	&armv7_event_attr_c4_read_alloc_enter.attr.attr,
+	&armv7_event_attr_c5_read_alloc.attr.attr,
+	&armv7_event_attr_c7_etm_out0.attr.attr,
+	&armv7_event_attr_c8_etm_out1.attr.attr,
+	&armv7_event_attr_c9_stall_sb_full.attr.attr,
+	&armv7_event_attr_ca_local_cluster_snoop.attr.attr,
+	NULL
+};
+
+static struct attribute_group armv7_a7_events_attr_group = {
+	.name = "events",
+	.attrs = armv7_a7_event_attrs,
+};
+
+static const struct attribute_group *armv7_a7_attr_groups[] = {
+	&armv7_a7_events_attr_group,
+	NULL
+};
+
+static struct attribute *armv7_a17_event_attrs[] = {
+	&armv7_event_attr_01_l1i_cache_refill.attr.attr,
+	&armv7_event_attr_02_l1i_tlb_refill.attr.attr,
+	&armv7_event_attr_03_l1d_cache_refill.attr.attr,
+	&armv7_event_attr_04_l1d_cache.attr.attr,
+	&armv7_event_attr_05_l1d_tlb_refill.attr.attr,
+	&armv7_event_attr_08_inst_retired.attr.attr,
+	&armv7_event_attr_09_exc_taken.attr.attr,
+	&armv7_event_attr_0a_exc_return.attr.attr,
+	&armv7_event_attr_0b_cid_write_retired.attr.attr,
+	&armv7_event_attr_10_br_mis_pred.attr.attr,
+	&armv7_event_attr_11_cpu_cycles.attr.attr,
+	&armv7_event_attr_12_br_pred.attr.attr,
+	&armv7_event_attr_13_mem_access.attr.attr,
+	&armv7_event_attr_14_l1i_cache.attr.attr,
+	&armv7_event_attr_15_l1d_cache_wb.attr.attr,
+	&armv7_event_attr_16_l2d_cache.attr.attr,
+	&armv7_event_attr_17_l2d_cache_refill.attr.attr,
+	&armv7_event_attr_18_l2d_cache_wb.attr.attr,
+	&armv7_event_attr_19_bus_access.attr.attr,
+	&armv7_event_attr_1b_inst_spec.attr.attr,
+	&armv7_event_attr_1c_ttbr_write_retired.attr.attr,
+	&armv7_event_attr_1d_bus_cycles.attr.attr,
+	&armv7_event_attr_40_l1d_cache_ld.attr.attr,
+	&armv7_event_attr_41_l1d_cache_st.attr.attr,
+	&armv7_event_attr_50_l2d_cache_ld.attr.attr,
+	&armv7_event_attr_51_l2d_cache_st.attr.attr,
+	&armv7_event_attr_56_l2d_cache_wb_victim.attr.attr,
+	&armv7_event_attr_57_l2d_cache_wb_clean.attr.attr,
+	&armv7_event_attr_58_l2d_cache_inval.attr.attr,
+	&armv7_event_attr_62_bus_access_shared.attr.attr,
+	&armv7_event_attr_63_bus_access_not_shared.attr.attr,
+	&armv7_event_attr_64_bus_access_normal.attr.attr,
+	&armv7_event_attr_65_bus_access_periph.attr.attr,
+	&armv7_event_attr_66_mem_access_ld.attr.attr,
+	&armv7_event_attr_67_mem_access_st.attr.attr,
+	&armv7_event_attr_68_unaligned_ld_spec.attr.attr,
+	&armv7_event_attr_69_unaligned_st_spec.attr.attr,
+	&armv7_event_attr_6a_unaligned_ldst_spec.attr.attr,
+	&armv7_event_attr_6c_ldrex_spec.attr.attr,
+	&armv7_event_attr_6e_strex_fail_spec.attr.attr,
+	&armv7_event_attr_6f_strex_spec.attr.attr,
+	&armv7_event_attr_70_ld_spec.attr.attr,
+	&armv7_event_attr_71_st_spec.attr.attr,
+	&armv7_event_attr_72_ldst_spec.attr.attr,
+	&armv7_event_attr_73_dp_spec.attr.attr,
+	&armv7_event_attr_74_ase_spec.attr.attr,
+	&armv7_event_attr_75_vfp_spec.attr.attr,
+	&armv7_event_attr_76_pc_write_spec.attr.attr,
+	&armv7_event_attr_78_br_immed_spec.attr.attr,
+	&armv7_event_attr_79_br_return_spec.attr.attr,
+	&armv7_event_attr_7a_br_indirect_spec.attr.attr,
+	&armv7_event_attr_7c_isb_spec.attr.attr,
+	&armv7_event_attr_7d_dsb_spec.attr.attr,
+	&armv7_event_attr_7e_dmb_spec.attr.attr,
+	&armv7_event_attr_81_exc_undef.attr.attr,
+	&armv7_event_attr_8a_exc_hvc.attr.attr,
+	&armv7_event_attr_c0_stall_inst_linefill.attr.attr,
+	&armv7_event_attr_c1_stall_inst_tlb.attr.attr,
+	&armv7_event_attr_c2_cache_tag.attr.attr,
+	&armv7_event_attr_c3_cache_data.attr.attr,
+	&armv7_event_attr_c4_cache_btac.attr.attr,
+	&armv7_event_attr_ca_local_cluster_snoop.attr.attr,
+	&armv7_event_attr_d3_busy_lsu.attr.attr,
+	&armv7_event_attr_d8_busy_lsi.attr.attr,
+	&armv7_event_attr_d9_busy_dpi.attr.attr,
+	&armv7_event_attr_da_busy_dei.attr.attr,
+	&armv7_event_attr_db_neon_cond_fail.attr.attr,
+	&armv7_event_attr_dc_trap_hv.attr.attr,
+	&armv7_event_attr_de_ptm_extout0.attr.attr,
+	&armv7_event_attr_df_ptm_extout1.attr.attr,
+	&armv7_event_attr_e0_mmu_walk.attr.attr,
+	&armv7_event_attr_e1_mmu_s1_walk.attr.attr,
+	&armv7_event_attr_e2_mmu_s2_walk.attr.attr,
+	&armv7_event_attr_e3_mmu_lsu_walk.attr.attr,
+	&armv7_event_attr_e4_mmu_inst_walk.attr.attr,
+	&armv7_event_attr_e5_mmu_pre_walk.attr.attr,
+	&armv7_event_attr_e6_mmu_cp15_walk.attr.attr,
+	&armv7_event_attr_e7_tlb_pld_refill.attr.attr,
+	&armv7_event_attr_e8_tlb_cp15_refill.attr.attr,
+	&armv7_event_attr_e9_tlb_flush.attr.attr,
+	&armv7_event_attr_ea_tlb_access.attr.attr,
+	&armv7_event_attr_eb_tlb_miss.attr.attr,
+	NULL
+};
+
+static struct attribute_group armv7_a17_events_attr_group = {
+	.name = "events",
+	.attrs = armv7_a17_event_attrs,
+};
+
+static const struct attribute_group *armv7_a17_attr_groups[] = {
+	&armv7_a17_events_attr_group,
+	NULL
+};
+
 /*
  * Perf Events' indices
  */
@@ -1085,6 +1695,7 @@ static int armv7_a8_pmu_init(struct arm_pmu *cpu_pmu)
 	armv7pmu_init(cpu_pmu);
 	cpu_pmu->name		= "armv7_cortex_a8";
 	cpu_pmu->map_event	= armv7_a8_map_event;
+	cpu_pmu->pmu.attr_groups = armv7_a8_attr_groups;
 	return armv7_probe_num_events(cpu_pmu);
 }
 
@@ -1093,6 +1704,7 @@ static int armv7_a9_pmu_init(struct arm_pmu *cpu_pmu)
 	armv7pmu_init(cpu_pmu);
 	cpu_pmu->name		= "armv7_cortex_a9";
 	cpu_pmu->map_event	= armv7_a9_map_event;
+	cpu_pmu->pmu.attr_groups = armv7_a9_attr_groups;
 	return armv7_probe_num_events(cpu_pmu);
 }
 
@@ -1101,6 +1713,7 @@ static int armv7_a5_pmu_init(struct arm_pmu *cpu_pmu)
 	armv7pmu_init(cpu_pmu);
 	cpu_pmu->name		= "armv7_cortex_a5";
 	cpu_pmu->map_event	= armv7_a5_map_event;
+	cpu_pmu->pmu.attr_groups = armv7_a5_attr_groups;
 	return armv7_probe_num_events(cpu_pmu);
 }
 
@@ -1110,6 +1723,7 @@ static int armv7_a15_pmu_init(struct arm_pmu *cpu_pmu)
 	cpu_pmu->name		= "armv7_cortex_a15";
 	cpu_pmu->map_event	= armv7_a15_map_event;
 	cpu_pmu->set_event_filter = armv7pmu_set_event_filter;
+	cpu_pmu->pmu.attr_groups = armv7_a15_attr_groups;
 	return armv7_probe_num_events(cpu_pmu);
 }
 
@@ -1119,6 +1733,7 @@ static int armv7_a7_pmu_init(struct arm_pmu *cpu_pmu)
 	cpu_pmu->name		= "armv7_cortex_a7";
 	cpu_pmu->map_event	= armv7_a7_map_event;
 	cpu_pmu->set_event_filter = armv7pmu_set_event_filter;
+	cpu_pmu->pmu.attr_groups = armv7_a7_attr_groups;
 	return armv7_probe_num_events(cpu_pmu);
 }
 
@@ -1128,6 +1743,7 @@ static int armv7_a12_pmu_init(struct arm_pmu *cpu_pmu)
 	cpu_pmu->name		= "armv7_cortex_a12";
 	cpu_pmu->map_event	= armv7_a12_map_event;
 	cpu_pmu->set_event_filter = armv7pmu_set_event_filter;
+	cpu_pmu->pmu.attr_groups = armv7_a17_attr_groups;
 	return armv7_probe_num_events(cpu_pmu);
 }
 
@@ -1135,6 +1751,7 @@ static int armv7_a17_pmu_init(struct arm_pmu *cpu_pmu)
 {
 	int ret = armv7_a12_pmu_init(cpu_pmu);
 	cpu_pmu->name = "armv7_cortex_a17";
+	cpu_pmu->pmu.attr_groups = armv7_a17_attr_groups;
 	return ret;
 }
 
-- 
2.1.4



From rjw at rjwysocki.net  Mon Aug  3 18:09:11 2015
From: rjw at rjwysocki.net (Rafael J. Wysocki)
Date: Tue, 04 Aug 2015 03:09:11 +0200
Subject: [PATCH v3 5/5] cpufreq: remove no longer needed CPU_FREQ_BOOST_SW
 config option
In-Reply-To: <20150801111537.GH899@linux>
References: <1438368557-2352-1-git-send-email-b.zolnierkie@samsung.com>
 <1438368557-2352-6-git-send-email-b.zolnierkie@samsung.com>
 <20150801111537.GH899@linux>
Message-ID: <6122974.sHQrqqlTov@vostro.rjw.lan>

On Saturday, August 01, 2015 04:45:37 PM Viresh Kumar wrote:
> On 31-07-15, 20:49, Bartlomiej Zolnierkiewicz wrote:
> > Remove no longer needed CPU_FREQ_BOOST_SW config option.
> > 
> > As a result scaling_boost_freqs sysfs attribute is available
> > when cpufreq-dt driver is used and boost support is enabled.
> > 
> > Cc: Viresh Kumar <viresh.kumar at linaro.org>
> > Cc: Thomas Abraham <thomas.ab at samsung.com>
> > Cc: Javier Martinez Canillas <javier at osg.samsung.com>
> > Cc: Krzysztof Kozlowski <k.kozlowski at samsung.com>
> > Signed-off-by: Bartlomiej Zolnierkiewicz <b.zolnierkie at samsung.com>
> > ---
> >  drivers/cpufreq/Kconfig      | 4 ----
> >  drivers/cpufreq/freq_table.c | 2 --
> >  2 files changed, 6 deletions(-)
> > 
> > diff --git a/drivers/cpufreq/Kconfig b/drivers/cpufreq/Kconfig
> > index bf6d596..de00a52 100644
> > --- a/drivers/cpufreq/Kconfig
> > +++ b/drivers/cpufreq/Kconfig
> > @@ -21,10 +21,6 @@ if CPU_FREQ
> >  config CPU_FREQ_GOV_COMMON
> >  	bool
> >  
> > -config CPU_FREQ_BOOST_SW
> > -	bool
> > -	depends on THERMAL
> > -
> >  config CPU_FREQ_STAT
> >  	tristate "CPU frequency translation statistics"
> >  	default y
> > diff --git a/drivers/cpufreq/freq_table.c b/drivers/cpufreq/freq_table.c
> > index a8f1daf..4c5de5b 100644
> > --- a/drivers/cpufreq/freq_table.c
> > +++ b/drivers/cpufreq/freq_table.c
> > @@ -293,9 +293,7 @@ EXPORT_SYMBOL_GPL(cpufreq_freq_attr_scaling_boost_freqs);
> >  
> >  struct freq_attr *cpufreq_generic_attr[] = {
> >  	&cpufreq_freq_attr_scaling_available_freqs,
> > -#ifdef CONFIG_CPU_FREQ_BOOST_SW
> >  	&cpufreq_freq_attr_scaling_boost_freqs,
> > -#endif
> >  	NULL,
> >  };
> >  EXPORT_SYMBOL_GPL(cpufreq_generic_attr);
> 
> So, this will start appearing for all platforms that use cpufreq_generic_attr
> and that may not be the right thing. We may only want to show boost frequencies
> only if the driver supports it.
> 
> @Rafael: What do you say?

I agree.

Thanks,
Rafael



From k.kozlowski at samsung.com  Mon Aug  3 17:43:41 2015
From: k.kozlowski at samsung.com (Krzysztof Kozlowski)
Date: Tue, 04 Aug 2015 09:43:41 +0900
Subject: [PATCH v3 3/5] ARM: Exynos: switch to using generic cpufreq driver
 for Exynos4x12
In-Reply-To: <2347616.SxxJmTVssu@amdc1976>
References: <1438368557-2352-1-git-send-email-b.zolnierkie@samsung.com>
 <4532306.AVvo5hem3c@amdc1976> <55BF4D41.1060903@samsung.com>
 <2347616.SxxJmTVssu@amdc1976>
Message-ID: <55C00ABD.3050805@samsung.com>

On 03.08.2015 22:55, Bartlomiej Zolnierkiewicz wrote:
> 
> Hi,
> 
> On Monday, August 03, 2015 08:15:13 PM Krzysztof Kozlowski wrote:
>> W dniu 03.08.2015 o 19:36, Bartlomiej Zolnierkiewicz pisze:
>>> On Monday, August 03, 2015 03:59:26 PM Viresh Kumar wrote:
>>>> On 03-08-15, 12:17, Bartlomiej Zolnierkiewicz wrote:
>>>>>
>>>>> Hi,
>>>>>
>>>>> On Saturday, August 01, 2015 04:47:21 PM Viresh Kumar wrote:
>>>>>> On 31-07-15, 20:49, Bartlomiej Zolnierkiewicz wrote:
>>>>>>> diff --git a/drivers/cpufreq/Kconfig b/drivers/cpufreq/Kconfig
>>>>>>> index 659879a..bf6d596 100644
>>>>>>> --- a/drivers/cpufreq/Kconfig
>>>>>>> +++ b/drivers/cpufreq/Kconfig
>>>>>>> @@ -191,6 +191,7 @@ config CPUFREQ_DT
>>>>>>>  	# if CPU_THERMAL is on and THERMAL=m, CPUFREQ_DT cannot be =y:
>>>>>>>  	depends on !CPU_THERMAL || THERMAL
>>>>>>>  	select PM_OPP
>>>>>>> +	select EXYNOS_THERMAL if ARCH_EXYNOS
>>>>>>>  	help
>>>>>>>  	  This adds a generic DT based cpufreq driver for frequency management.
>>>>>>>  	  It supports both uniprocessor (UP) and symmetric multiprocessor (SMP)
>>>>>>
>>>>>> No, we shouldn't pollute generic Kconfig options with platform specific stuff.
>>>>>
>>>>> The old code depended on this.  You couldn't enable boost support
>>>>> without enabling thermal support (ARM_EXYNOS_CPU_FREQ_BOOST_SW
>>>>> config option selected EXYNOS_THERMAL).
>>>>>
>>>>>> Why don't you enable thermal in your .config?
>>>>>
>>>>> It is enabled in exynos_defconfig but without the above change it
>>>>> can disabled manually which is something that we don't want.
>>>>
>>>> You are not getting it. I am not asking you to not select thermal, but
>>>> to select it from within your architecture Kconfig option if you want.
>>>
>>> OK.  Krzysztof/Kukjin do you agree with selecting EXYNOS_THERMAL
>>> from ARCH_EXYNOS in the platform code?
>>
>> I agree, with your explanation it seems good. Can you just add this
>> justification to the commit message?
> 
> Updated patch below (I'm not resending the whole series as all other
> patches remain unchanged).
> 
>>>
>>>> Over that, thermal is really an option, not a dependency. So, if
>>>> someone manually disables it, its his problem not yours :)
>>>
>>> I would really like it to be dependency not an option (+ I think
>>> that ideally it should be checked at runtime, IOW we should be
>>> checking from cpufreq-dt driver if the thermal support is enabled
>>> before enabling boost support).
>>
>> That would be the best. It is fine with me if you want to do this in
>> consecutive patches (after applying patch selecting/depending on it in
>> mach-exynos code).
> 
> ---------------------8<-------------------
> 
>>From 2595b5e6164a2d1b76626e14302b148b7af5e050 Mon Sep 17 00:00:00 2001
> From: Bartlomiej Zolnierkiewicz <b.zolnierkie at samsung.com>
> Date: Mon, 3 Aug 2015 15:49:06 +0200
> Subject: [PATCH] ARM: Exynos: switch to using generic cpufreq driver for
>  Exynos4x12
> 
> The new CPU clock type allows the use of generic CPUfreq driver.
> Switch Exynos4x12 to using generic cpufreq driver.
> 
> Previously (when exynos-cpufreq driver was used with boost
> functionality) ARM_EXYNOS_CPU_FREQ_BOOST_SW config option
> (which enabled boost functionality) selected EXYNOS_THERMAL
> one.  After switching Exynos4x12 platforms to use cpufreq-dt
> driver boost support is enabled in the cpufreq-dt driver
> itself (because there are turbo OPPs defined in the board's
> DTS file).  However we still would like to allow enabling
> boost support only if thermal support is also enabled for
> Exynos platforms.  To achieve this make ARCH_EXYNOS config
> option select THERMAL and EXYNOS_THERMAL ones.
> 
> Please also note that the switch to use the generic cpufreq-dt
> driver fixes the minor issue present with the old code (support
> for 'boost' mode in the exynos-cpufreq driver was enabled for
> all supported SoCs even though 'boost' frequency was provided
> only for Exynos4x12 ones).
> 
> Cc: Tomasz Figa <tomasz.figa at gmail.com>
> Cc: Kukjin Kim <kgene.kim at samsung.com>
> Cc: Thomas Abraham <thomas.ab at samsung.com>
> Cc: Javier Martinez Canillas <javier at osg.samsung.com>
> Signed-off-by: Bartlomiej Zolnierkiewicz <b.zolnierkie at samsung.com>
> ---
>  arch/arm/mach-exynos/Kconfig  | 2 ++
>  arch/arm/mach-exynos/exynos.c | 2 ++
>  2 files changed, 4 insertions(+)
> 
> diff --git a/arch/arm/mach-exynos/Kconfig b/arch/arm/mach-exynos/Kconfig
> index 81064cd..491914c 100644
> --- a/arch/arm/mach-exynos/Kconfig
> +++ b/arch/arm/mach-exynos/Kconfig
> @@ -25,6 +25,8 @@ menuconfig ARCH_EXYNOS
>  	select S5P_DEV_MFC
>  	select SRAM
>  	select MFD_SYSCON
> +	select THERMAL
> +	select EXYNOS_THERMAL
>  	help
>  	  Support for SAMSUNG EXYNOS SoCs (EXYNOS4/5)
>  
> diff --git a/arch/arm/mach-exynos/exynos.c b/arch/arm/mach-exynos/exynos.c
> index 77ac021..1c47aee 100644
> --- a/arch/arm/mach-exynos/exynos.c
> +++ b/arch/arm/mach-exynos/exynos.c
> @@ -227,6 +227,8 @@ static void __init exynos_init_irq(void)
>  static const struct of_device_id exynos_cpufreq_matches[] = {
>  	{ .compatible = "samsung,exynos3250", .data = "cpufreq-dt" },
>  	{ .compatible = "samsung,exynos4210", .data = "cpufreq-dt" },
> +	{ .compatible = "samsung,exynos4212", .data = "cpufreq-dt" },
> +	{ .compatible = "samsung,exynos4412", .data = "cpufreq-dt" },
>  	{ .compatible = "samsung,exynos5250", .data = "cpufreq-dt" },
>  	{ /* sentinel */ }
>  };
> 

Reviewed-by: Krzysztof Kozlowski <k.kozlowski at samsung.com>

Best regards,
Krzysztof



From horms at verge.net.au  Mon Aug  3 17:53:41 2015
From: horms at verge.net.au (Simon Horman)
Date: Tue, 4 Aug 2015 09:53:41 +0900
Subject: [PATCH v3] ARM: shmobile: silk: initial device tree
In-Reply-To: <55BF8522.1010906@cogentembedded.com>
References: <201404250239.39150.sergei.shtylyov@cogentembedded.com>
 <2360526.88foRQAOiM@wasted.cogentembedded.com>
 <CAMuHMdWT=nzsFuM-vfe5GoAtDE-AtW4LAZoEnBGGVZm54-mAzg@mail.gmail.com>
 <55BF8522.1010906@cogentembedded.com>
Message-ID: <20150804005341.GB16257@verge.net.au>

On Mon, Aug 03, 2015 at 06:13:38PM +0300, Sergei Shtylyov wrote:
> Hello.
> 
> On 08/03/2015 04:00 PM, Geert Uytterhoeven wrote:
> 
> >>--- /dev/null
> >>+++ renesas/arch/arm/boot/dts/r8a7794-silk.dts
> >>@@ -0,0 +1,51 @@
> 
> >>+/ {
> >>+       model = "SILK";
> >>+       compatible = "renesas,silk", "renesas,r8a7794";
> 
> >WARNING: DT compatible string "renesas,silk" appears un-documented --
> >check ./Documentation/devicetree/bindings/
> 
> >Do you plan to update Documentation/devicetree/bindings/arm/shmobile.txt?
> 
>    No, I had no idea I should record the board names somewhere too...

Sergei, please submit a parch as suggested by Geert.


From sboyd at codeaurora.org  Mon Aug  3 18:14:17 2015
From: sboyd at codeaurora.org (Stephen Boyd)
Date: Mon, 03 Aug 2015 18:14:17 -0700
Subject: [PATCH v2 1/2] clk: rockchip: add pclk_pd_pmu to the list of
 rk3288 critical clocks
In-Reply-To: <1438650222-14357-1-git-send-email-hl@rock-chips.com>
References: <1438650222-14357-1-git-send-email-hl@rock-chips.com>
Message-ID: <55C011E9.3000002@codeaurora.org>

On 08/03/2015 06:03 PM, Lin Huang wrote:
> From: huang lin <hl at rock-chips.com>
>
> pclk_pd_pmu needs to keep running and with the upcoming gpio clock
> handling this is not always the case anymore. So add it to the list
> of critical clocks for now.
>
> Signed-off-by: Heiko Stuebner <heiko at sntech.de>
> Signed-off-by: Lin Huang <hl at rock-chips.com>

From: says huang lin, first signed-off-by is Heiko Stuebner, and final 
signed-off-by is Lin Huang... who actually authored this patch? Is Lin 
Huang the same person as huang lin ?

-- 
Qualcomm Innovation Center, Inc. is a member of Code Aurora Forum,
a Linux Foundation Collaborative Project



From k.kozlowski at samsung.com  Mon Aug  3 18:31:59 2015
From: k.kozlowski at samsung.com (Krzysztof Kozlowski)
Date: Tue, 04 Aug 2015 10:31:59 +0900
Subject: [PATCH v2 2/7] cpufreq: opp: fix handling of turbo modes
In-Reply-To: <55BA36A7.3050107@kernel.org>
References: <1436456621-29839-1-git-send-email-b.zolnierkie@samsung.com>
 <3141301.RS9TLygaba@amdc1976> <20150727113641.GB10181@linux>
 <2681271.3UazeZ9PAQ@amdc1976> <55BA36A7.3050107@kernel.org>
Message-ID: <55C0160F.6080301@samsung.com>

On 30.07.2015 23:37, Kukjin Kim wrote:
> On 07/27/15 20:47, Bartlomiej Zolnierkiewicz wrote:
>> On Monday, July 27, 2015 05:06:41 PM Viresh Kumar wrote:
>>> On 27-07-15, 13:14, Bartlomiej Zolnierkiewicz wrote:
>>>> Sorry but you don't seem to understand the issue.
>>>
>>> :)
>>>
>>> No, I did. I understand that if someone uses opp bindings today with
>>> some entries as turbo OPPs, cpufreq will use them as normal
>>> frequencies. And that may harm the board.
>>>
>>> BUT, opp-v2 code isn't ready to be used yet. And platforms should see
>>> what all is implemented before trying to use them.
>>
>> OK.
>>
>>> All I was saying is, this isn't a FIX as we haven't introduced the
>>> feature yet. Otherwise I had no issues with the patch.
>>
>> I will update the description for the next patchset revision.
>>
> Hi Bart,
> 
> When will you re-post v3? Because I have a plan to send a pull-request
> to arm-soc until this weekend...

Dear Kukjin,

We are already at 4.2-rc5 and you did not send the pull request before
the weekend as you said. It is really late and there is no special
reason for delaying the request. What happened?

Best regards,
Krzysztof



From peter.chen at freescale.com  Mon Aug  3 17:36:02 2015
From: peter.chen at freescale.com (Peter Chen)
Date: Tue, 4 Aug 2015 08:36:02 +0800
Subject: [PATCH v2 06/10] usb: chipidea: add ahb burst configuration
 interface
In-Reply-To: <CAL_JsqJn16OvfL_Ggf1wSi2XkJkjDMrmuRit3q8eVY5bNp8oYw@mail.gmail.com>
References: <1438577238-10153-1-git-send-email-peter.chen@freescale.com>
 <1438577238-10153-7-git-send-email-peter.chen@freescale.com>
 <CAL_JsqJn16OvfL_Ggf1wSi2XkJkjDMrmuRit3q8eVY5bNp8oYw@mail.gmail.com>
Message-ID: <20150804003600.GA20208@shlinux2>

On Mon, Aug 03, 2015 at 09:04:27AM -0500, Rob Herring wrote:
> On Sun, Aug 2, 2015 at 11:47 PM, Peter Chen <peter.chen at freescale.com> wrote:
> > The users can change it through dts or platform data if they
> > want to change the default value.
> >
> > Signed-off-by: Peter Chen <peter.chen at freescale.com>
> > ---
> >  drivers/usb/chipidea/bits.h  |  3 +++
> >  drivers/usb/chipidea/core.c  | 14 ++++++++++++++
> >  include/linux/usb/chipidea.h |  2 ++
> >  3 files changed, 19 insertions(+)
> >
> > diff --git a/drivers/usb/chipidea/bits.h b/drivers/usb/chipidea/bits.h
> > index 831a8f6..462ad02 100644
> > --- a/drivers/usb/chipidea/bits.h
> > +++ b/drivers/usb/chipidea/bits.h
> > @@ -25,6 +25,9 @@
> >  #define VERSION                      (0xF << 25)
> >  #define CIVERSION            (0x7 << 29)
> >
> > +/* SBUSCFG */
> > +#define AHBBRST_MASK           0x7
> > +
> >  /* HCCPARAMS */
> >  #define HCCPARAMS_LEN         BIT(17)
> >
> > diff --git a/drivers/usb/chipidea/core.c b/drivers/usb/chipidea/core.c
> > index 38bd036..f60cbf6 100644
> > --- a/drivers/usb/chipidea/core.c
> > +++ b/drivers/usb/chipidea/core.c
> > @@ -439,6 +439,9 @@ void ci_platform_configure(struct ci_hdrc *ci)
> >
> >         hw_write(ci, OP_USBCMD, 0xff0000, ci->platdata->itc_setting << 16);
> >
> > +       if (ci->platdata->flags & CI_HDRC_OVERRIDE_AHB_BURST)
> > +               hw_write_id_reg(ci, ID_SBUSCFG, AHBBRST_MASK,
> > +                       ci->platdata->ahb_burst_config);
> >  }
> >
> >  /**
> > @@ -647,6 +650,17 @@ static int ci_get_platdata(struct device *dev,
> >                 }
> >         }
> >
> > +       if (of_find_property(dev->of_node, "ahb-burst-config", NULL)) {
> > +               ret = of_property_read_u32(dev->of_node, "ahb-burst-config",
> > +                       &platdata->ahb_burst_config);
> > +               if (ret) {
> > +                       dev_err(dev,
> > +                               "failed to get ahb-burst-config\n");
> > +                       return ret;
> > +               }
> > +               platdata->flags |= CI_HDRC_OVERRIDE_AHB_BURST;
> > +       }
> > +
> 
> This can be simplified to:
> 
> ret = of_property_read_u32(dev->of_node, "ahb-burst-config",
> &platdata->ahb_burst_config);
> if (!ret)
>   platdata->flags |= CI_HDRC_OVERRIDE_AHB_BURST;
> 
> The error condition can't really happen.
> 
> Rob

Thanks, I will change others accordingly.

-- 

Best Regards,
Peter Chen


From scott.shu at mediatek.com  Mon Aug  3 19:47:37 2015
From: scott.shu at mediatek.com (Scott Shu)
Date: Tue, 4 Aug 2015 10:47:37 +0800
Subject: [PATCH] ARM64: dts: mt6795: enable basic SMP bringup for MT6795
Message-ID: <1438656457-60278-1-git-send-email-scott.shu@mediatek.com>

This patch adds support SMP on MediaTek MT6795 Cortex-A53 Octa-core SoC.

The patch is based on v4.2-rc1 and following patch series:
(1) Mars Cheng's "Add mt6795 basic chip support" [1]

[1] https://lkml.org/lkml/2015/7/14/63

Signed-off-by: Scott Shu <scott.shu at mediatek.com>
---
 arch/arm64/boot/dts/mediatek/mt6795.dtsi |   13 +++++++++++++
 1 file changed, 13 insertions(+)

diff --git a/arch/arm64/boot/dts/mediatek/mt6795.dtsi b/arch/arm64/boot/dts/mediatek/mt6795.dtsi
index da200e7..c85659d 100644
--- a/arch/arm64/boot/dts/mediatek/mt6795.dtsi
+++ b/arch/arm64/boot/dts/mediatek/mt6795.dtsi
@@ -20,6 +20,11 @@
 	#address-cells = <2>;
 	#size-cells = <2>;
 
+	psci {
+		compatible = "arm,psci-0.2";
+		method = "smc";
+	};
+
 	cpus {
 		#address-cells = <1>;
 		#size-cells = <0>;
@@ -27,48 +32,56 @@
 		cpu0: cpu at 0 {
 			device_type = "cpu";
 			compatible = "arm,cortex-a53";
+			enable-method = "psci";
 			reg = <0x000>;
 		};
 
 		cpu1: cpu at 1 {
 			device_type = "cpu";
 			compatible = "arm,cortex-a53";
+			enable-method = "psci";
 			reg = <0x001>;
 		};
 
 		cpu2: cpu at 2 {
 			device_type = "cpu";
 			compatible = "arm,cortex-a53";
+			enable-method = "psci";
 			reg = <0x002>;
 		};
 
 		cpu3: cpu at 3 {
 			device_type = "cpu";
 			compatible = "arm,cortex-a53";
+			enable-method = "psci";
 			reg = <0x003>;
 		};
 
 		cpu4: cpu at 100 {
 			device_type = "cpu";
 			compatible = "arm,cortex-a53";
+			enable-method = "psci";
 			reg = <0x100>;
 		};
 
 		cpu5: cpu at 101 {
 			device_type = "cpu";
 			compatible = "arm,cortex-a53";
+			enable-method = "psci";
 			reg = <0x101>;
 		};
 
 		cpu6: cpu at 102 {
 			device_type = "cpu";
 			compatible = "arm,cortex-a53";
+			enable-method = "psci";
 			reg = <0x102>;
 		};
 
 		cpu7: cpu at 103 {
 			device_type = "cpu";
 			compatible = "arm,cortex-a53";
+			enable-method = "psci";
 			reg = <0x103>;
 		};
 	};
-- 
1.7.9.5



From fugang.duan at freescale.com  Mon Aug  3 20:18:46 2015
From: fugang.duan at freescale.com (Duan Andy)
Date: Tue, 4 Aug 2015 03:18:46 +0000
Subject: [PATCH] iio: adc: vf610: Add IIO buffer support for Vybrid ADC
In-Reply-To: <1f11be7d7bc1c3fcebf7d0bcf274f1fcbef35999.1438610517.git.maitysanchayan@gmail.com>
References: <cover.1438610517.git.maitysanchayan@gmail.com>
 <1f11be7d7bc1c3fcebf7d0bcf274f1fcbef35999.1438610517.git.maitysanchayan@gmail.com>
Message-ID: <BN3PR0301MB12191A12387C829F111B612BF5760@BN3PR0301MB1219.namprd03.prod.outlook.com>

From: Sanchayan Maity <maitysanchayan at gmail.com> Sent: Monday, August 03, 2015 11:10 PM
> To: jic23 at kernel.org; linux-iio at vger.kernel.org
> Cc: stefan at agner.ch; Duan Fugang-B38611; hofrat at osadl.org;
> sanjeev_sharma at mentor.com; Estevam Fabio-R49496; knaack.h at gmx.de;
> lars at metafoo.de; pmeerw at pmeerw.net; antoine.tenart at free-electrons.com;
> linux-kernel at vger.kernel.org; linux-arm-kernel at lists.infradead.org;
> Sanchayan Maity
> Subject: [PATCH] iio: adc: vf610: Add IIO buffer support for Vybrid ADC
> 
> This patch adds support for IIO buffer to the Vybrid ADC driver.
> IIO triggered buffer infrastructure along with iio sysfs trigger is used
> to leverage continuous sampling support provided by the ADC block.
> 
> Signed-off-by: Sanchayan Maity <maitysanchayan at gmail.com>
> ---
>  drivers/iio/adc/Kconfig     |   4 ++
>  drivers/iio/adc/vf610_adc.c | 122
> +++++++++++++++++++++++++++++++++++++++++---
>  2 files changed, 120 insertions(+), 6 deletions(-)
> 
> diff --git a/drivers/iio/adc/Kconfig b/drivers/iio/adc/Kconfig index
> 7c55658..4661241 100644
> --- a/drivers/iio/adc/Kconfig
> +++ b/drivers/iio/adc/Kconfig
> @@ -337,6 +337,10 @@ config TWL6030_GPADC  config VF610_ADC
>  	tristate "Freescale vf610 ADC driver"
>  	depends on OF
> +	select IIO_BUFFER
> +	select IIO_TRIGGER
> +	select IIO_SYSFS_TRIGGER
> +	select IIO_TRIGGERED_BUFFER
>  	help
>  	  Say yes here to support for Vybrid board analog-to-digital
> converter.
>  	  Since the IP is used for i.MX6SLX, the driver also support
> i.MX6SLX.
> diff --git a/drivers/iio/adc/vf610_adc.c b/drivers/iio/adc/vf610_adc.c
> index 23b8fb9..af72b9a 100644
> --- a/drivers/iio/adc/vf610_adc.c
> +++ b/drivers/iio/adc/vf610_adc.c
> @@ -34,8 +34,11 @@
>  #include <linux/err.h>
> 
>  #include <linux/iio/iio.h>
> +#include <linux/iio/buffer.h>
>  #include <linux/iio/sysfs.h>
> -#include <linux/iio/driver.h>
> +#include <linux/iio/trigger.h>
> +#include <linux/iio/trigger_consumer.h> #include
> +<linux/iio/triggered_buffer.h>
> 
>  /* This will be the driver name the kernel reports */  #define
> DRIVER_NAME "vf610-adc"
> @@ -170,6 +173,7 @@ struct vf610_adc {
>  	u32 sample_freq_avail[5];
> 
>  	struct completion completion;
> +	u16 *buffer;
>  };
> 
>  static const u32 vf610_hw_avgs[] = { 1, 4, 8, 16, 32 }; @@ -505,12
> +509,22 @@ static const struct iio_chan_spec_ext_info vf610_ext_info[] =
> {
>  	.info_mask_shared_by_type = BIT(IIO_CHAN_INFO_SCALE) |	\
>  				BIT(IIO_CHAN_INFO_SAMP_FREQ),	\
>  	.ext_info = vf610_ext_info,				\
> +	.address = (_idx),				\
> +	.scan_index = (_idx),			\
> +	.scan_type.sign = 'u',			\
> +	.scan_type.realbits = 12,		\
> +	.scan_type.storagebits = 16,	\
>  }
> 
>  #define VF610_ADC_TEMPERATURE_CHAN(_idx, _chan_type) {	\
>  	.type = (_chan_type),	\
>  	.channel = (_idx),		\
>  	.info_mask_separate = BIT(IIO_CHAN_INFO_PROCESSED),	\
> +	.address = (_idx),						\
> +	.scan_index = (_idx),					\
> +	.scan_type.sign = 'u',					\
> +	.scan_type.realbits = 12,				\
> +	.scan_type.storagebits = 16,			\
>  }
> 
>  static const struct iio_chan_spec vf610_adc_iio_channels[] = { @@ -531,6
> +545,7 @@ static const struct iio_chan_spec vf610_adc_iio_channels[] = {
>  	VF610_ADC_CHAN(14, IIO_VOLTAGE),
>  	VF610_ADC_CHAN(15, IIO_VOLTAGE),
>  	VF610_ADC_TEMPERATURE_CHAN(26, IIO_TEMP),
> +	IIO_CHAN_SOFT_TIMESTAMP(32),
>  	/* sentinel */
>  };
> 
> @@ -559,13 +574,21 @@ static int vf610_adc_read_data(struct vf610_adc
> *info)
> 
>  static irqreturn_t vf610_adc_isr(int irq, void *dev_id)  {
> -	struct vf610_adc *info = (struct vf610_adc *)dev_id;
> +	struct iio_dev *indio_dev = (struct iio_dev *)dev_id;
> +	struct vf610_adc *info = iio_priv(indio_dev);
>  	int coco;
> 
>  	coco = readl(info->regs + VF610_REG_ADC_HS);
>  	if (coco & VF610_ADC_HS_COCO0) {
>  		info->value = vf610_adc_read_data(info);
> -		complete(&info->completion);
> +		if (iio_buffer_enabled(indio_dev)) {
> +			info->buffer[0] = info->value;
> +			writel(0, info->regs + VF610_REG_ADC_HS);
The register is read only. After ADC_Rn is read, the coco bit is cleared.

> +			iio_push_to_buffers_with_timestamp(indio_dev,
> +					info->buffer, iio_get_time_ns());
> +			iio_trigger_notify_done(indio_dev->trig);
> +		} else
> +			complete(&info->completion);
>  	}
> 
>  	return IRQ_HANDLED;
> @@ -612,6 +635,9 @@ static int vf610_read_raw(struct iio_dev *indio_dev,
>  	switch (mask) {
>  	case IIO_CHAN_INFO_RAW:
>  	case IIO_CHAN_INFO_PROCESSED:
> +		if (iio_buffer_enabled(indio_dev))
> +			return -EBUSY;
> +
>  		mutex_lock(&indio_dev->mlock);
>  		reinit_completion(&info->completion);
> 
> @@ -694,6 +720,81 @@ static int vf610_write_raw(struct iio_dev *indio_dev,
>  	return -EINVAL;
>  }
> 
> +static int vf610_adc_buffer_postenable(struct iio_dev *indio_dev) {
> +	struct vf610_adc *info = iio_priv(indio_dev);
> +	unsigned int channel;
> +	int ret;
> +	int val;
> +
> +	ret = iio_triggered_buffer_postenable(indio_dev);
> +	if (ret)
> +		return ret;
> +
> +	val = readl(info->regs + VF610_REG_ADC_GC);
> +	val |= VF610_ADC_ADCON;
> +	writel(val, info->regs + VF610_REG_ADC_GC);
> +
> +	channel = find_first_bit(indio_dev->active_scan_mask,
> +						indio_dev->masklength);
> +
> +	val = VF610_ADC_ADCHC(channel);
> +	val |= VF610_ADC_AIEN;
> +
> +	writel(val, info->regs + VF610_REG_ADC_HC0);
> +
> +	return 0;
> +}
> +
> +static int vf610_adc_buffer_postdisable(struct iio_dev *indio_dev) {
> +	struct vf610_adc *info = iio_priv(indio_dev);
> +	unsigned int hc_cfg = 0;
> +	int val;
> +
> +	val = readl(info->regs + VF610_REG_ADC_GC);
> +	val &= ~VF610_ADC_ADCON;
> +	writel(val, info->regs + VF610_REG_ADC_GC);
> +
> +	hc_cfg |= VF610_ADC_CONV_DISABLE;
> +	hc_cfg &= ~VF610_ADC_AIEN;
> +
> +	writel(hc_cfg, info->regs + VF610_REG_ADC_HC0);
> +
> +	return 0;
> +}
> +
> +static int vf610_adc_update_scan_mode(struct iio_dev *indio_dev,
> +	const unsigned long *scan_mask)
> +{
> +	struct vf610_adc *info = iio_priv(indio_dev);
> +
> +	kfree(info->buffer);
> +	info->buffer = kmalloc(indio_dev->scan_bytes, GFP_KERNEL);
> +	if (!info->buffer)
> +		return -ENOMEM;
> +
> +	return 0;
> +}
> +
> +static const struct iio_buffer_setup_ops iio_triggered_buffer_setup_ops
> = {
> +	.postenable = &vf610_adc_buffer_postenable,
> +	.predisable = &iio_triggered_buffer_predisable,
> +	.postdisable = &vf610_adc_buffer_postdisable,
> +	.validate_scan_mask = &iio_validate_scan_mask_onehot, };
> +
> +static int vf610_adc_buffer_init(struct iio_dev *indio_dev) {
> +	return iio_triggered_buffer_setup(indio_dev,
> &iio_pollfunc_store_time,
> +		NULL, &iio_triggered_buffer_setup_ops); }
> +
> +static void vf610_adc_buffer_remove(struct iio_dev *indio_dev) {
> +	iio_triggered_buffer_cleanup(indio_dev);
> +}
> +
>  static int vf610_adc_reg_access(struct iio_dev *indio_dev,
>  			unsigned reg, unsigned writeval,
>  			unsigned *readval)
> @@ -714,6 +815,7 @@ static const struct iio_info vf610_adc_iio_info = {
>  	.read_raw = &vf610_read_raw,
>  	.write_raw = &vf610_write_raw,
>  	.debugfs_reg_access = &vf610_adc_reg_access,
> +	.update_scan_mode = &vf610_adc_update_scan_mode,
>  	.attrs = &vf610_attribute_group,
>  };
> 
> @@ -753,7 +855,7 @@ static int vf610_adc_probe(struct platform_device
> *pdev)
> 
>  	ret = devm_request_irq(info->dev, irq,
>  				vf610_adc_isr, 0,
> -				dev_name(&pdev->dev), info);
> +				dev_name(&pdev->dev), indio_dev);
>  	if (ret < 0) {
>  		dev_err(&pdev->dev, "failed requesting irq, irq = %d\n", irq);
>  		return ret;
> @@ -806,15 +908,22 @@ static int vf610_adc_probe(struct platform_device
> *pdev)
>  	vf610_adc_cfg_init(info);
>  	vf610_adc_hw_init(info);
> 
> +	ret = vf610_adc_buffer_init(indio_dev);
> +	if (ret < 0) {
> +		dev_err(&pdev->dev, "Couldn't initialise the buffer\n");
> +		goto error_iio_device_register;
> +	}
> +
>  	ret = iio_device_register(indio_dev);
>  	if (ret) {
>  		dev_err(&pdev->dev, "Couldn't register the device.\n");
> -		goto error_iio_device_register;
> +		goto error_adc_buffer_init;
>  	}
> 
>  	return 0;
> 
> -
> +error_adc_buffer_init:
> +	vf610_adc_buffer_remove(indio_dev);
>  error_iio_device_register:
>  	clk_disable_unprepare(info->clk);
>  error_adc_clk_enable:
> @@ -829,6 +938,7 @@ static int vf610_adc_remove(struct platform_device
> *pdev)
>  	struct vf610_adc *info = iio_priv(indio_dev);
> 
>  	iio_device_unregister(indio_dev);
> +	vf610_adc_buffer_remove(indio_dev);
>  	regulator_disable(info->vref);
>  	clk_disable_unprepare(info->clk);
> 
> --
> 2.5.0


From aisheng.dong at freescale.com  Mon Aug  3 20:25:15 2015
From: aisheng.dong at freescale.com (Dong Aisheng)
Date: Tue, 4 Aug 2015 11:25:15 +0800
Subject: [PATCH v3 1/6] mmc: sdhci-esdhc-imx: add imx7d support and
 support HS400
In-Reply-To: <1438160637-28061-2-git-send-email-haibo.chen@freescale.com>
References: <1438160637-28061-1-git-send-email-haibo.chen@freescale.com>
 <1438160637-28061-2-git-send-email-haibo.chen@freescale.com>
Message-ID: <20150804032513.GD24870@shlinux1.ap.freescale.net>

On Wed, Jul 29, 2015 at 05:03:52PM +0800, Haibo Chen wrote:
> The imx7d usdhc is derived from imx6sx, the difference is that
> imx7d support HS400.
> 
> So introduce a new compatible string for imx7d and add HS400
> support for imx7d usdhc.
> 
> Signed-off-by: Haibo Chen <haibo.chen at freescale.com>
> ---
>  drivers/mmc/host/sdhci-esdhc-imx.c | 66 ++++++++++++++++++++++++++++++++++++++
>  1 file changed, 66 insertions(+)
> 
> diff --git a/drivers/mmc/host/sdhci-esdhc-imx.c b/drivers/mmc/host/sdhci-esdhc-imx.c
> index c6b9f64..b441eed 100644
> --- a/drivers/mmc/host/sdhci-esdhc-imx.c
> +++ b/drivers/mmc/host/sdhci-esdhc-imx.c
> @@ -44,6 +44,7 @@
>  #define  ESDHC_MIX_CTRL_EXE_TUNE	(1 << 22)
>  #define  ESDHC_MIX_CTRL_SMPCLK_SEL	(1 << 23)
>  #define  ESDHC_MIX_CTRL_FBCLK_SEL	(1 << 25)
> +#define  ESDHC_MIX_CTRL_HS400_EN	(1 << 26)
>  /* Bits 3 and 6 are not SDHCI standard definitions */
>  #define  ESDHC_MIX_CTRL_SDHCI_MASK	0xb7
>  /* Tuning bits */
> @@ -60,6 +61,16 @@
>  #define  ESDHC_TUNE_CTRL_MIN		0
>  #define  ESDHC_TUNE_CTRL_MAX		((1 << 7) - 1)
>  
> +/* strobe dll register */
> +#define ESDHC_STROBE_DLL_CTRL		0x70
> +#define ESDHC_STROBE_DLL_CTRL_ENABLE	(1 << 0)
> +#define ESDHC_STROBE_DLL_CTRL_RESET	(1 << 1)
> +#define ESDHC_STROBE_DLL_CTRL_SLV_DLY_TARGET_SHIFT	3
> +
> +#define ESDHC_STROBE_DLL_STATUS		0x74
> +#define ESDHC_STROBE_DLL_STS_REF_LOCK	(1 << 1)
> +#define ESDHC_STROBE_DLL_STS_SLV_LOCK	0x1
> +
>  #define ESDHC_TUNING_CTRL		0xcc
>  #define ESDHC_STD_TUNING_EN		(1 << 24)
>  /* NOTE: the minimum valid tuning start tap for mx6sl is 1 */
> @@ -120,6 +131,8 @@
>  #define ESDHC_FLAG_ERR004536		BIT(7)
>  /* The IP supports HS200 mode */
>  #define ESDHC_FLAG_HS200		BIT(8)
> +/* The IP supports HS400 mode */
> +#define ESDHC_FLAG_SUP_HS400		BIT(9)
>  
>  struct esdhc_soc_data {
>  	u32 flags;
> @@ -156,6 +169,12 @@ static struct esdhc_soc_data usdhc_imx6sx_data = {
>  			| ESDHC_FLAG_HAVE_CAP1 | ESDHC_FLAG_HS200,
>  };
>  
> +static struct esdhc_soc_data usdhc_imx7d_data = {
> +	.flags = ESDHC_FLAG_USDHC | ESDHC_FLAG_STD_TUNING
> +			| ESDHC_FLAG_HAVE_CAP1 | ESDHC_FLAG_HS200
> +			| ESDHC_FLAG_SUP_HS400,

Better to use ESDHC_FLAG_HS400 to keep align with exist ESDHC_FLAG_HS200.

Regards
Dong Aisheng


From jingoohan1 at gmail.com  Mon Aug  3 21:19:50 2015
From: jingoohan1 at gmail.com (Jingoo Han)
Date: Tue, 4 Aug 2015 13:19:50 +0900
Subject: [PATCH v6] PCI: Store PCIe bus address in struct of_pci_range
In-Reply-To: <EE11001F9E5DDD47B7634E2F8A612F2E01D712E7@lhreml503-mbs>
References: <1438010223-124422-1-git-send-email-gabriele.paoloni@huawei.com>
 <20150729172053.GE31170@google.com>
 <EE11001F9E5DDD47B7634E2F8A612F2E01D6F350@lhreml503-mbs>
 <CAL_JsqKs11-sXQTdBD+ZjbVYFWUHBARTW9q5MF1hCXUhZ+nWLQ@mail.gmail.com>
 <EE11001F9E5DDD47B7634E2F8A612F2E01D6F94A@lhreml503-mbs>
 <20150730161447.GG9640@google.com>
 <EE11001F9E5DDD47B7634E2F8A612F2E01D6FB3B@lhreml503-mbs>
 <20150730171445.GI9640@google.com>
 <EE11001F9E5DDD47B7634E2F8A612F2E01D6FC15@lhreml503-mbs>
 <CAL_Jsq+aQVakaZf4xo7sxnVyTmPR+HJ-9ByyS6OYJ0PHDYOwmg@mail.gmail.com>
 <EE11001F9E5DDD47B7634E2F8A612F2E01D70589@lhreml503-mbs>
 <55BB8CC6.1080203@ti.com>
 <CAL_JsqJqjiWVaKs-3ghQ1EBQzRRQ38GzkMV+FELPj53bSF-yXQ@mail.gmail.com>
 <EE11001F9E5DDD47B7634E2F8A612F2E01D712E7@lhreml503-mbs>
Message-ID: <7F6386B4-D2F5-4840-AC72-F8C76CBC3B94@gmail.com>

On 2015. 8. 3., at PM 8:18, Gabriele Paoloni <gabriele.paoloni at huawei.com> wrote:
> 
> Rob, Kishon what about the following solution?....
> 
> ---
> drivers/pci/host/pci-dra7xx.c      | 12 ++++++++++++
> drivers/pci/host/pcie-designware.c |  9 +++------

Hi Paoloni,

OK, it looks good.
I want you to revert the following patch. 

commit "f4c55c5a3f7f (PCI: designware: Program ATU with untranslated address)"

Would you remove all '*_mode_base's?

Best regards,
Jingoo Han

> 2 files changed, 15 insertions(+), 6 deletions(-)
> 
> diff --git a/drivers/pci/host/pci-dra7xx.c b/drivers/pci/host/pci-dra7xx.c
> index 80db09e..bb2635f 100644
> --- a/drivers/pci/host/pci-dra7xx.c
> +++ b/drivers/pci/host/pci-dra7xx.c
> @@ -61,6 +61,7 @@
> 
> #define    PCIECTRL_DRA7XX_CONF_PHY_CS            0x010C
> #define    LINK_UP                        BIT(16)
> +#define CPU_TO_BUS_ADDR             0x0FFFFFFF
> 
> struct dra7xx_pcie {
>    void __iomem        *base;
> @@ -138,6 +139,17 @@ static void dra7xx_pcie_enable_interrupts(struct pcie_port *pp)
> 
> static void dra7xx_pcie_host_init(struct pcie_port *pp)
> {
> +    if (pp->io_mod_base)
> +        pp->io_mod_base &= CPU_TO_BUS_ADDR;
> +
> +    if (pp->mem_mod_base)
> +        pp->mem_mod_base &= CPU_TO_BUS_ADDR;
> +
> +    if (pp->cfg0_mod_base) {
> +        pp->cfg0_mod_base &= CPU_TO_BUS_ADDR;
> +        pp->cfg1_mod_base &= CPU_TO_BUS_ADDR;
> +    }
> +
>    dw_pcie_setup_rc(pp);
>    dra7xx_pcie_establish_link(pp);
>    if (IS_ENABLED(CONFIG_PCI_MSI))
> diff --git a/drivers/pci/host/pcie-designware.c b/drivers/pci/host/pcie-designware.c
> index 69486be..06c682b 100644
> --- a/drivers/pci/host/pcie-designware.c
> +++ b/drivers/pci/host/pcie-designware.c
> @@ -416,8 +416,7 @@ int dw_pcie_host_init(struct pcie_port *pp)
>            pp->io_base = range.cpu_addr;
> 
>            /* Find the untranslated IO space address */
> -            pp->io_mod_base = of_read_number(parser.range -
> -                             parser.np + na, ns);
> +            pp->io_mod_base = range.cpu_addr;;
>        }
>        if (restype == IORESOURCE_MEM) {
>            of_pci_range_to_resource(&range, np, &pp->mem);
> @@ -426,8 +425,7 @@ int dw_pcie_host_init(struct pcie_port *pp)
>            pp->mem_bus_addr = range.pci_addr;
> 
>            /* Find the untranslated MEM space address */
> -            pp->mem_mod_base = of_read_number(parser.range -
> -                              parser.np + na, ns);
> +            pp->mem_mod_base = range.cpu_addr;
>        }
>        if (restype == 0) {
>            of_pci_range_to_resource(&range, np, &pp->cfg);
> @@ -437,8 +435,7 @@ int dw_pcie_host_init(struct pcie_port *pp)
>            pp->cfg1_base = pp->cfg.start + pp->cfg0_size;
> 
>            /* Find the untranslated configuration space address */
> -            pp->cfg0_mod_base = of_read_number(parser.range -
> -                               parser.np + na, ns);
> +            pp->cfg0_mod_base = range.cpu_addr;
>            pp->cfg1_mod_base = pp->cfg0_mod_base +
>                        pp->cfg0_size;
>        }
> -- 
> 1.9.1
> 
> 
>> -----Original Message-----
>> From: linux-pci-owner at vger.kernel.org [mailto:linux-pci-
>> owner at vger.kernel.org] On Behalf Of Rob Herring
>> Sent: Friday, July 31, 2015 5:53 PM
>> To: Kishon Vijay Abraham I
>> Cc: Gabriele Paoloni; Bjorn Helgaas; arnd at arndb.de;
>> lorenzo.pieralisi at arm.com; Wangzhou (B); robh+dt at kernel.org;
>> james.morse at arm.com; Liviu.Dudau at arm.com; linux-pci at vger.kernel.org;
>> linux-arm-kernel at lists.infradead.org; devicetree at vger.kernel.org;
>> Yuanzhichang; Zhudacai; zhangjukuo; qiuzhenfa; Liguozhu (Kenneth);
>> Jingoo Han; Pratyush Anand; Arnd Bergmann
>> Subject: Re: [PATCH v6] PCI: Store PCIe bus address in struct
>> of_pci_range
>> 
>> On Fri, Jul 31, 2015 at 9:57 AM, Kishon Vijay Abraham I <kishon at ti.com>
>> wrote:
>>> +Arnd
>>> 
>>> Hi,
>>> 
>>>> On Friday 31 July 2015 07:55 PM, Gabriele Paoloni wrote:
>>>> [+cc Kishon]
>>>> 
>>>>> -----Original Message-----
>>>>> From: linux-pci-owner at vger.kernel.org [mailto:linux-pci-
>>>>> owner at vger.kernel.org] On Behalf Of Rob Herring
>>>>> Sent: Thursday, July 30, 2015 9:42 PM
>>>>> To: Gabriele Paoloni
>>>>> Cc: Bjorn Helgaas; arnd at arndb.de; lorenzo.pieralisi at arm.com;
>> Wangzhou
>>>>> (B); robh+dt at kernel.org; james.morse at arm.com; Liviu.Dudau at arm.com;
>>>>> linux-pci at vger.kernel.org; linux-arm-kernel at lists.infradead.org;
>>>>> devicetree at vger.kernel.org; Yuanzhichang; Zhudacai; zhangjukuo;
>>>>> qiuzhenfa; Liguozhu (Kenneth); Jingoo Han; Pratyush Anand
>>>>> Subject: Re: [PATCH v6] PCI: Store PCIe bus address in struct
>>>>> of_pci_range
>>>>> 
>>>>> On Thu, Jul 30, 2015 at 12:34 PM, Gabriele Paoloni
>>>>> <gabriele.paoloni at huawei.com> wrote:
>>>>>>> -----Original Message-----
>>>>>>> From: Bjorn Helgaas [mailto:bhelgaas at google.com]
>>>>>>> Sent: 30 July 2015 18:15
>>>>>>> On Thu, Jul 30, 2015 at 04:50:55PM +0000, Gabriele Paoloni wrote:
>>>>>>>>> -----Original Message-----
>>>>>>>>> From: linux-pci-owner at vger.kernel.org [mailto:linux-pci-
>>>>>>>>> owner at vger.kernel.org] On Behalf Of Bjorn Helgaas
>>>>>>>>> Sent: Thursday, July 30, 2015 5:15 PM
>>>>>>>>> On Thu, Jul 30, 2015 at 01:52:13PM +0000, Gabriele Paoloni
>> wrote:
>>>>> 
>>>>> [...]
>>>>> 
>>>>>>>>>> I don?t think we should rely on [CPU] addresses...what if the
>>>>>>>>> intermediate
>>>>>>>>>> translation layer changes the lower significant bits of the
>>>>> "bus
>>>>>>>>> address"
>>>>>>>>>> to translate into a cpu address?
>>>>>>>>> 
>>>>>>>>> Is it really a possiblity that the lower bits could be changed?
>>>>>>>> 
>>>>>>>> I've checked all the current deignware users DTs except "pci-
>>>>>>> layerscape"
>>>>>>>> that I could not find:
>>>>>>>> spear1310.dtsi
>>>>>>>> spear1340.dtsi
>>>>>>>> dra7.dtsi
>>>>>>>> imx6qdl.dtsi
>>>>>>>> imx6sx.dtsi
>>>>>>>> keystone.dtsi
>>>>>>>> exynos5440.dtsi
>>>>>>>> 
>>>>>>>> None of them modifies the lower bits. To be more precise the
>> only
>>>>> guy
>>>>>>>> that provides another translation layer is "dra7.dtsi":
>>>>>>>> axi0
>>>>>>>> http://lxr.free-
>>>>> electrons.com/source/arch/arm/boot/dts/dra7.dtsi#L207
>>>>>>>> 
>>>>>>>> axi1
>>>>>>>> http://lxr.free-
>>>>> electrons.com/source/arch/arm/boot/dts/dra7.dtsi#L241
>>>>>>>> 
>>>>>>>> For this case masking the top 4bits (bits28 to 31) should make
>> the
>>>>> job.
>>>>> 
>>>>> IMO, we should just fix this case. After further study, I don't
>> think
>>>>> this is a DW issue, but rather an SOC integration issue.
>>>>> 
>>>>> I believe you can just fixup the address in the pp->ops->host_init
>> hook.
>>>> 
>>>> Yes I guess that I could just assign pp->(*)_mod_base to the CPU
>> address
>>>> in DW and mask it out in dra7xx_pcie_host_init()...
>>>> 
>>>> Kishon, would you be ok with that?
>>> 
>>> Initially I was using *base-mask* property from dt. Me and Arnd
>> (cc'ed) had
>>> this discussion [1] before we decided the current approach. It'll be
>> good to
>>> check with Arnd too.
>>> 
>>> [1] ->  http://lists.infradead.org/pipermail/linux-arm-kernel/2014-
>> May/253528.html
>> 
>> The problem I have here is the use of ranges does not necessarily mean
>> fewer address bits are available. It can be used just for convenience
>> of not putting the full address into every node's reg property. And
>> vice versa, there are probably plenty of cases where we have the full
>> address in the nodes, but really only some of the address bits are
>> decoded at the IP block. Whether the address bits are present is
>> rarely cared about or known by s/w folks until you hit a problem like
>> this. Given this is an isolated case ATM, I would fix it in an
>> isolated way. It does not affect the binding and could be changed in
>> the kernel later if this becomes a common need.
>> 
>> Rob
>> --
>> To unsubscribe from this list: send the line "unsubscribe linux-pci" in
>> the body of a message to majordomo at vger.kernel.org
>> More majordomo info at  http://vger.kernel.org/majordomo-info.html


From shubhrajyoti.datta at gmail.com  Mon Aug  3 22:34:52 2015
From: shubhrajyoti.datta at gmail.com (Shubhrajyoti Datta)
Date: Tue, 4 Aug 2015 11:04:52 +0530
Subject: [PATCH v3] iio: adc: xilinx-xadc: Push interrupts into threaded
 context
In-Reply-To: <55B231DE.4080308@metafoo.de>
References: <CAKfKVtGTO81wLWk50M303t2WjcBEMEt_LUnsJ3_WmvR_3izUjg@mail.gmail.com>
 <1437434050-32907-1-git-send-email-xander.huff@ni.com>
 <55B231DE.4080308@metafoo.de>
Message-ID: <CAKfKVtGegy2P_YWQAtKEzByN-+q+bq=uus4zNvO4sghXRjpGPQ@mail.gmail.com>

On Fri, Jul 24, 2015 at 6:08 PM, Lars-Peter Clausen <lars at metafoo.de> wrote:
> Hi,
>
> Sorry, but I don't think this patch has been sufficiently tested against a
> mainline kernel. The driver wont even probe the way it is right now.
>
> On 07/21/2015 01:14 AM, Xander Huff wrote:
>>
>> The driver currently registers a pair of irq handlers using
>> request_threaded_irq(), however the synchronization mechanism between the
>> hardirq and the threadedirq handler is a regular spinlock.
>
>
> If everything runs in threaded context we don't really need the spinlock
> anymore and can use the mutex throughout.

that should be better from the performance point of view.

>
>>
>> Unfortunately, this breaks PREEMPT_RT builds, where a spinlock can sleep,
>> and is thus not able to be acquired from a hardirq handler. This patch
>> gets
>> rid of the hardirq handler and pushes all interrupt handling into the
>> threaded context.
>
>
> We actually might as well run everything in the hardirq handler (which will
> be threaded in PREEMPT_RT). The reason why we have the threaded handler is
> because xadc_handle_event() used to sleep, but it doesn't do this anymore.

The point is why have the hard irq. If we use hardirq then not mutex
can be used and spinlock will
be busy.

is there something i may be missing?
>
>


From pranavkumar at linaro.org  Mon Aug  3 22:48:19 2015
From: pranavkumar at linaro.org (Pranavkumar Sawargaonkar)
Date: Tue, 4 Aug 2015 11:18:19 +0530
Subject: [RFC 0/2] VFIO: Add virtual MSI doorbell support.
In-Reply-To: <1438106335.5211.219.camel@redhat.com>
References: <1437728590-23126-1-git-send-email-pranavkumar@linaro.org>
 <1438100507.5211.170.camel@redhat.com>
 <CY1PR0301MB127660D71378F009918DDDD5908D0@CY1PR0301MB1276.namprd03.prod.outlook.com>
 <1438106335.5211.219.camel@redhat.com>
Message-ID: <CAAHg+HgosCe=1T5ER-4AS1g779RxCDjcrazKV4CQC-43zDK-+Q@mail.gmail.com>

Hi Bharat,

On 28 July 2015 at 23:28, Alex Williamson <alex.williamson at redhat.com> wrote:
> On Tue, 2015-07-28 at 17:23 +0000, Bhushan Bharat wrote:
>> Hi Alex,
>>
>> > -----Original Message-----
>> > From: Alex Williamson [mailto:alex.williamson at redhat.com]
>> > Sent: Tuesday, July 28, 2015 9:52 PM
>> > To: Pranavkumar Sawargaonkar
>> > Cc: kvm at vger.kernel.org; kvmarm at lists.cs.columbia.edu; linux-arm-
>> > kernel at lists.infradead.org; linux-kernel at vger.kernel.org;
>> > christoffer.dall at linaro.org; marc.zyngier at arm.com; will.deacon at arm.com;
>> > bhelgaas at google.com; arnd at arndb.de; rob.herring at linaro.org;
>> > eric.auger at linaro.org; patches at apm.com; Bhushan Bharat-R65777; Yoder
>> > Stuart-B08248
>> > Subject: Re: [RFC 0/2] VFIO: Add virtual MSI doorbell support.
>> >
>> > On Fri, 2015-07-24 at 14:33 +0530, Pranavkumar Sawargaonkar wrote:
>> > > In current VFIO MSI/MSI-X implementation, linux host kernel allocates
>> > > MSI/MSI-X vectors when userspace requests through vfio ioctls.
>> > > Vfio creates irqfd mappings to notify MSI/MSI-X interrupts to the
>> > > userspace when raised.
>> > > Guest OS will see emulated MSI/MSI-X controller and receives an
>> > > interrupt when kernel notifies the same via irqfd.
>> > >
>> > > Host kernel allocates MSI/MSI-X using standard linux routines like
>> > > pci_enable_msix_range() and pci_enable_msi_range().
>> > > These routines along with requset_irq() in host kernel sets up
>> > > MSI/MSI-X vectors with Physical MSI/MSI-X addresses provided by
>> > > interrupt controller driver in host kernel.
>> > >
>> > > This means when a device is assigned with the guest OS, MSI/MSI-X
>> > > addresses present in PCIe EP are the PAs programmed by the host linux
>> > kernel.
>> > >
>> > > In x86 MSI/MSI-X physical address range is reserved and iommu is aware
>> > > about these addreses and transalation is bypassed for these address range.
>> > >
>> > > Unlike x86, ARM/ARM64 does not reserve MSI/MSI-X Physical address
>> > > range and all the transactions including MSI go through iommu/smmu
>> > without bypass.
>> > > This requires extending current vfio MSI layer with additional
>> > > functionality for ARM/ARM64 by 1. Programing IOVA (referred as a MSI
>> > > virtual doorbell address)
>> > >    in device's MSI vector as a MSI address.
>> > >    This IOVA will be provided by the userspace based on the
>> > >    MSI/MSI-X addresses reserved for the guest.
>> > > 2. Create an IOMMU mapping between this IOVA and
>> > >    Physical address (PA) assigned to the MSI vector.
>> > >
>> > > This RFC is proposing a solution for MSI/MSI-X passthrough for
>> > ARM/ARM64.
>> >
>> >
>> > Hi Pranavkumar,
>> >
>> > Freescale has the same, or very similar, need, so any solution in this space
>> > will need to work for both ARM and powerpc.  I'm not a big fan of this
>> > approach as it seems to require the user to configure MSI/X via ioctl and then
>> > call a separate ioctl mapping the doorbells.  That's more code for the user,
>> > more code to get wrong and potentially a gap between configuring MSI/X
>> > and enabling mappings where we could see IOMMU faults.
>> >
>> > If we know that doorbell mappings are required, why can't we set aside a
>> > bank of IOVA space and have them mapped automatically as MSI/X is being
>> > configured?  Then the user's need for special knowledge and handling of this
>> > case is limited to setup.  The IOVA space will be mapped and used as needed,
>> > we only need the user to specify the IOVA space reserved for this.  Thanks,
>>
>> We probably need a mix of both to support Freescale PowerPC and ARM
>> based machines.
>> In this mix mode kernel vfio driver will reserve some IOVA for mapping
>> MSI page/s.
>
> If vfio is reserving pages independently from the user, this becomes
> what Marc called "shaping" the VM and what x86 effectively does.  An
> interface extension should expose these implicit regions so the user can
> avoid them for DMA memory mapping.
>
>>  If any other iova mapping will overlap with this then it will return
>> error and user-space. Ideally this should be choosen in such a way
>> that it never overlap, which is easy on some systems but can be tricky
>> on some other system like Freescale PowerPC. This is not sufficient
>> for at-least Freescale PowerPC based SOC. This is because of hardware
>> limitation, where we need to fit this reserved iova address within
>> aperture decided by user-space. So if we allow user-space to change
>> this reserved iova address to a value decided by user-spece itself
>> then we can support both ARM/PowerPC based solutions.
>
> Yes, that's my intention, to allow userspace to specify the reserved
> region.  I believe you have some additional restrictions on the number
> of MSI banks available and whether MSI banks can be shared, but I would
> hope that doesn't preclude a shared interface with ARM.
>
>> I have some implementation ready/tested with this approach and if this
>> approach looks good then I can submit a RFC patch.
>
> Yes, please post.  Thanks,

Could you please share a tentative timeline by which you will be
posting your patches ?
Also are you planning to post counterpart patches for qemu or kvmtool ?

Thanks,
Pranav


From Bharat.Bhushan at freescale.com  Mon Aug  3 22:52:01 2015
From: Bharat.Bhushan at freescale.com (Bhushan Bharat)
Date: Tue, 4 Aug 2015 05:52:01 +0000
Subject: [RFC 0/2] VFIO: Add virtual MSI doorbell support.
In-Reply-To: <CAAHg+HgosCe=1T5ER-4AS1g779RxCDjcrazKV4CQC-43zDK-+Q@mail.gmail.com>
References: <1437728590-23126-1-git-send-email-pranavkumar@linaro.org>
 <1438100507.5211.170.camel@redhat.com>
 <CY1PR0301MB127660D71378F009918DDDD5908D0@CY1PR0301MB1276.namprd03.prod.outlook.com>
 <1438106335.5211.219.camel@redhat.com>
 <CAAHg+HgosCe=1T5ER-4AS1g779RxCDjcrazKV4CQC-43zDK-+Q@mail.gmail.com>
Message-ID: <CY1PR0301MB12761E7FA759BD1D6F218B8B90760@CY1PR0301MB1276.namprd03.prod.outlook.com>



> -----Original Message-----
> From: Pranavkumar Sawargaonkar [mailto:pranavkumar at linaro.org]
> Sent: Tuesday, August 04, 2015 11:18 AM
> To: Bhushan Bharat-R65777
> Cc: kvm at vger.kernel.org; Alex Williamson; kvmarm at lists.cs.columbia.edu;
> linux-arm-kernel at lists.infradead.org; linux-kernel at vger.kernel.org;
> christoffer.dall at linaro.org; marc.zyngier at arm.com; will.deacon at arm.com;
> bhelgaas at google.com; arnd at arndb.de; rob.herring at linaro.org;
> eric.auger at linaro.org; patches at apm.com; Yoder Stuart-B08248
> Subject: Re: [RFC 0/2] VFIO: Add virtual MSI doorbell support.
> 
> Hi Bharat,
> 
> On 28 July 2015 at 23:28, Alex Williamson <alex.williamson at redhat.com>
> wrote:
> > On Tue, 2015-07-28 at 17:23 +0000, Bhushan Bharat wrote:
> >> Hi Alex,
> >>
> >> > -----Original Message-----
> >> > From: Alex Williamson [mailto:alex.williamson at redhat.com]
> >> > Sent: Tuesday, July 28, 2015 9:52 PM
> >> > To: Pranavkumar Sawargaonkar
> >> > Cc: kvm at vger.kernel.org; kvmarm at lists.cs.columbia.edu; linux-arm-
> >> > kernel at lists.infradead.org; linux-kernel at vger.kernel.org;
> >> > christoffer.dall at linaro.org; marc.zyngier at arm.com;
> >> > will.deacon at arm.com; bhelgaas at google.com; arnd at arndb.de;
> >> > rob.herring at linaro.org; eric.auger at linaro.org; patches at apm.com;
> >> > Bhushan Bharat-R65777; Yoder
> >> > Stuart-B08248
> >> > Subject: Re: [RFC 0/2] VFIO: Add virtual MSI doorbell support.
> >> >
> >> > On Fri, 2015-07-24 at 14:33 +0530, Pranavkumar Sawargaonkar wrote:
> >> > > In current VFIO MSI/MSI-X implementation, linux host kernel
> >> > > allocates MSI/MSI-X vectors when userspace requests through vfio
> ioctls.
> >> > > Vfio creates irqfd mappings to notify MSI/MSI-X interrupts to the
> >> > > userspace when raised.
> >> > > Guest OS will see emulated MSI/MSI-X controller and receives an
> >> > > interrupt when kernel notifies the same via irqfd.
> >> > >
> >> > > Host kernel allocates MSI/MSI-X using standard linux routines
> >> > > like
> >> > > pci_enable_msix_range() and pci_enable_msi_range().
> >> > > These routines along with requset_irq() in host kernel sets up
> >> > > MSI/MSI-X vectors with Physical MSI/MSI-X addresses provided by
> >> > > interrupt controller driver in host kernel.
> >> > >
> >> > > This means when a device is assigned with the guest OS, MSI/MSI-X
> >> > > addresses present in PCIe EP are the PAs programmed by the host
> >> > > linux
> >> > kernel.
> >> > >
> >> > > In x86 MSI/MSI-X physical address range is reserved and iommu is
> >> > > aware about these addreses and transalation is bypassed for these
> address range.
> >> > >
> >> > > Unlike x86, ARM/ARM64 does not reserve MSI/MSI-X Physical address
> >> > > range and all the transactions including MSI go through
> >> > > iommu/smmu
> >> > without bypass.
> >> > > This requires extending current vfio MSI layer with additional
> >> > > functionality for ARM/ARM64 by 1. Programing IOVA (referred as a
> >> > > MSI virtual doorbell address)
> >> > >    in device's MSI vector as a MSI address.
> >> > >    This IOVA will be provided by the userspace based on the
> >> > >    MSI/MSI-X addresses reserved for the guest.
> >> > > 2. Create an IOMMU mapping between this IOVA and
> >> > >    Physical address (PA) assigned to the MSI vector.
> >> > >
> >> > > This RFC is proposing a solution for MSI/MSI-X passthrough for
> >> > ARM/ARM64.
> >> >
> >> >
> >> > Hi Pranavkumar,
> >> >
> >> > Freescale has the same, or very similar, need, so any solution in
> >> > this space will need to work for both ARM and powerpc.  I'm not a
> >> > big fan of this approach as it seems to require the user to
> >> > configure MSI/X via ioctl and then call a separate ioctl mapping
> >> > the doorbells.  That's more code for the user, more code to get
> >> > wrong and potentially a gap between configuring MSI/X and enabling
> mappings where we could see IOMMU faults.
> >> >
> >> > If we know that doorbell mappings are required, why can't we set
> >> > aside a bank of IOVA space and have them mapped automatically as
> >> > MSI/X is being configured?  Then the user's need for special
> >> > knowledge and handling of this case is limited to setup.  The IOVA
> >> > space will be mapped and used as needed, we only need the user to
> >> > specify the IOVA space reserved for this.  Thanks,
> >>
> >> We probably need a mix of both to support Freescale PowerPC and ARM
> >> based machines.
> >> In this mix mode kernel vfio driver will reserve some IOVA for
> >> mapping MSI page/s.
> >
> > If vfio is reserving pages independently from the user, this becomes
> > what Marc called "shaping" the VM and what x86 effectively does.  An
> > interface extension should expose these implicit regions so the user
> > can avoid them for DMA memory mapping.
> >
> >>  If any other iova mapping will overlap with this then it will return
> >> error and user-space. Ideally this should be choosen in such a way
> >> that it never overlap, which is easy on some systems but can be
> >> tricky on some other system like Freescale PowerPC. This is not
> >> sufficient for at-least Freescale PowerPC based SOC. This is because
> >> of hardware limitation, where we need to fit this reserved iova
> >> address within aperture decided by user-space. So if we allow
> >> user-space to change this reserved iova address to a value decided by
> >> user-spece itself then we can support both ARM/PowerPC based
> solutions.
> >
> > Yes, that's my intention, to allow userspace to specify the reserved
> > region.  I believe you have some additional restrictions on the number
> > of MSI banks available and whether MSI banks can be shared, but I
> > would hope that doesn't preclude a shared interface with ARM.
> >
> >> I have some implementation ready/tested with this approach and if
> >> this approach looks good then I can submit a RFC patch.
> >
> > Yes, please post.  Thanks,
> 
> Could you please share a tentative timeline by which you will be posting your
> patches ?

I have not touched that code for a while, I am planning to send the patch in couple of weeks.

> Also are you planning to post counterpart patches for qemu or kvmtool ?

I will send only QEMU side changes.

Thanks
-Bharat

> 
> Thanks,
> Pranav

From moinejf at free.fr  Mon Aug  3 23:05:57 2015
From: moinejf at free.fr (Jean-Francois Moine)
Date: Tue, 4 Aug 2015 08:05:57 +0200
Subject: [PATCH v2] drm/i2c: tda998x: Fix bad checksum of the HDMI AVI
 infoframe
In-Reply-To: <E1ZK5bb-00079F-WC@bombadil.infradead.org>
References: <E1ZK5bb-00079F-WC@bombadil.infradead.org>
Message-ID: <20150804080557.58244c7c@armhf>

On Tue, 28 Jul 2015 15:59:17 +0200
Jean-Francois Moine <moinejf at free.fr> wrote:

> Using hdmi_avi_infoframe_pack() to create the AVI infoframe calculates
> the checksum of the frame and breaks the second calculation which is
> done in tda998x_write_if(). Then the HDMI AVI frame is wrong and
> the display device does not handle correctly the video frames.
> 
> Fixes: 8c7a075da9f7980c ("use drm_hdmi_avi_infoframe_from_display_mode()")
> Signed-off-by: Jean-Francois Moine <moinejf at free.fr>
> ---
> v2: add the Fixes: tag
> ---
>  drivers/gpu/drm/i2c/tda998x_drv.c | 4 ++--
>  1 file changed, 2 insertions(+), 2 deletions(-)
> 
> diff --git a/drivers/gpu/drm/i2c/tda998x_drv.c b/drivers/gpu/drm/i2c/tda998x_drv.c
> index fe1599d..424228b 100644
> --- a/drivers/gpu/drm/i2c/tda998x_drv.c
> +++ b/drivers/gpu/drm/i2c/tda998x_drv.c
> @@ -606,8 +606,6 @@ static void
>  tda998x_write_if(struct tda998x_priv *priv, uint8_t bit, uint16_t addr,
>  		 uint8_t *buf, size_t size)
>  {
> -	buf[PB(0)] = tda998x_cksum(buf, size);
> -
>  	reg_clear(priv, REG_DIP_IF_FLAGS, bit);
>  	reg_write_range(priv, addr, buf, size);
>  	reg_set(priv, REG_DIP_IF_FLAGS, bit);
> @@ -627,6 +625,8 @@ tda998x_write_aif(struct tda998x_priv *priv, struct tda998x_encoder_params *p)
>  	buf[PB(4)] = p->audio_frame[4];
>  	buf[PB(5)] = p->audio_frame[5] & 0xf8; /* DM_INH + LSV */
>  
> +	buf[PB(0)] = tda998x_cksum(buf, sizeof(buf));
> +
>  	tda998x_write_if(priv, DIP_IF_FLAGS_IF4, REG_IF4_HB0, buf,
>  			 sizeof(buf));
>  }

Ping!

-- 
Ken ar c'henta?	|	      ** Breizh ha Linux atav! **
Jef		|		http://moinejf.free.fr/


From drinkcat at chromium.org  Mon Aug  3 23:09:56 2015
From: drinkcat at chromium.org (Nicolas Boichat)
Date: Tue,  4 Aug 2015 14:09:56 +0800
Subject: [PATCH 1/3] spi: bitbang: Replace spinlock by mutex when calling
 chipselect
Message-ID: <1438668598-6678-1-git-send-email-drinkcat@chromium.org>

Enabling CONFIG_DEBUG_ATOMIC_SLEEP in kernel configuration, we get
this warning in spi_gpio_setup:
[    1.177747] BUG: sleeping function called from invalid context at drivers/gpio/gpiolib.c:1431
[    1.190182] in_atomic(): 1, irqs_disabled(): 128, pid: 1, name: swapper/0
[    1.196922] 3 locks held by swapper/0/1:
[    1.200812]  #0:  (&dev->mutex){......}, at: [<ffffffc00051db78>] __driver_attach+0x58/0x98
[    1.209147]  #1:  (spi_add_lock){+.+.+.}, at: [<ffffffc000578164>] spi_add_device+0x80/0x14c
[    1.217564]  #2:  (&(&bitbang->lock)->rlock){......}, at: [<ffffffc00057b054>] spi_bitbang_setup+0x84/0xc4
[    1.227185] irq event stamp: 279856
[    1.230645] hardirqs last  enabled at (279855): [<ffffffc0007cce70>] __mutex_unlock_slowpath+0x158/0x16c
[    1.240070] hardirqs last disabled at (279856): [<ffffffc0007cead0>] _raw_spin_lock_irqsave+0x20/0x6c
[    1.249233] softirqs last  enabled at (262072): [<ffffffc0002f0954>] bdi_register+0x124/0x1d0
[    1.257707] softirqs last disabled at (262070): [<ffffffc0002f0930>] bdi_register+0x100/0x1d0
[    1.266185] CPU: 3 PID: 1 Comm: swapper/0 Not tainted 3.18.0 #608
[    1.277419] Call trace:
[    1.279848] [<ffffffc000208754>] dump_backtrace+0x0/0x12c
[    1.285209] [<ffffffc000208890>] show_stack+0x10/0x1c
[    1.290223] [<ffffffc0007c897c>] dump_stack+0x80/0xb4
[    1.295238] [<ffffffc000244248>] __might_sleep+0x110/0x11c
[    1.300687] [<ffffffc0004722d4>] gpiod_set_raw_value_cansleep+0x24/0x4c
[    1.307255] [<ffffffc00057b464>] spi_gpio_chipselect+0x74/0x88
[    1.313045] [<ffffffc00057b068>] spi_bitbang_setup+0x98/0xc4
[    1.318664] [<ffffffc00057bb44>] spi_gpio_setup+0x50/0xc8
[    1.324022] [<ffffffc0005780d0>] spi_setup+0xe4/0xf8
[    1.328950] [<ffffffc0005781b4>] spi_add_device+0xd0/0x14c
[    1.334396] [<ffffffc000579ba8>] spi_register_master+0x6a8/0x718
[    1.340359] [<ffffffc00057b358>] spi_bitbang_start+0xe8/0x108
[    1.346064] [<ffffffc00057bf70>] spi_gpio_probe+0x3b4/0x448
[    1.351595] [<ffffffc00051f65c>] platform_drv_probe+0x4c/0x9c
[    1.357301] [<ffffffc00051d930>] driver_probe_device+0xd4/0x23c
[    1.363180] [<ffffffc00051db88>] __driver_attach+0x68/0x98
[    1.368627] [<ffffffc00051ca30>] bus_for_each_dev+0x7c/0xb0
[    1.374160] [<ffffffc00051d4bc>] driver_attach+0x1c/0x28
[    1.379434] [<ffffffc00051d07c>] bus_add_driver+0xd8/0x1e0
[    1.384881] [<ffffffc00051e654>] driver_register+0xbc/0x10c
[    1.390412] [<ffffffc00051f58c>] __platform_driver_register+0x5c/0x68
[    1.396808] [<ffffffc000c28584>] spi_gpio_driver_init+0x14/0x20
[    1.402685] [<ffffffc000200a04>] do_one_initcall+0x18c/0x1ac
[    1.408306] [<ffffffc000c00c64>] kernel_init_freeable+0x228/0x2e0
[    1.414356] [<ffffffc0007c5f60>] kernel_init+0x10/0xd8

chipselect (in this case, spi_gpio_chipselect, which calls
gpiod_set_raw_value_cansleep), can sleep, so we should not hold
a spinlock while calling it.

This issue was introduced by this commit, which converted spi-gpio
to cansleep variants:
d9dda5a191 "spi: spi-gpio: Use 'cansleep' variants to access GPIO"

Replace spinlock + busy variable by a mutex, and get rid of
spi_bitbang_prepare_hardware and spi_bitbang_unprepare_hardware,
which are not useful anymore.

Signed-off-by: Nicolas Boichat <drinkcat at chromium.org>
---

Actually, I'm not sure if I understand the existing code: why are we not
waiting for busy to go down to 0, then call chipselect, instead of not calling
it at all if the bus happens to be busy when we setup the device? With the
current approach, it would be easy to just use an unconditional mutex_lock.

Also, is it harmful to deactivate the newly setup device in spi_bitbang_setup,
even if the bus is busy with another device? chipselect should be independent
for each device (or is it not?). So I'm not clear why we need any locking at
all...

Hopefully someone can shine some light on this...

Anyway, this patch series does not change the existing behaviour, applies on
top of broonie-sound/for-next, and, along with the 2 follow-up patches, was
compile-tested on x86-64/arm (allyesconfig) and ppc44x (defconfig+SPI driver),
and runtime-tested on an arm platform.

 drivers/spi/spi-bitbang.c       | 42 +++++++----------------------------------
 include/linux/spi/spi_bitbang.h |  3 +--
 2 files changed, 8 insertions(+), 37 deletions(-)

diff --git a/drivers/spi/spi-bitbang.c b/drivers/spi/spi-bitbang.c
index 840a498..931c37e 100644
--- a/drivers/spi/spi-bitbang.c
+++ b/drivers/spi/spi-bitbang.c
@@ -180,7 +180,6 @@ int spi_bitbang_setup(struct spi_device *spi)
 {
 	struct spi_bitbang_cs	*cs = spi->controller_state;
 	struct spi_bitbang	*bitbang;
-	unsigned long		flags;
 
 	bitbang = spi_master_get_devdata(spi->master);
 
@@ -210,12 +209,11 @@ int spi_bitbang_setup(struct spi_device *spi)
 	 */
 
 	/* deselect chip (low or high) */
-	spin_lock_irqsave(&bitbang->lock, flags);
-	if (!bitbang->busy) {
+	if (mutex_trylock(&bitbang->lock)) {
 		bitbang->chipselect(spi, BITBANG_CS_INACTIVE);
 		ndelay(cs->nsecs);
+		mutex_unlock(&bitbang->lock);
 	}
-	spin_unlock_irqrestore(&bitbang->lock, flags);
 
 	return 0;
 }
@@ -252,20 +250,6 @@ static int spi_bitbang_bufs(struct spi_device *spi, struct spi_transfer *t)
  * transfer-at-a-time ones to leverage dma or fifo hardware.
  */
 
-static int spi_bitbang_prepare_hardware(struct spi_master *spi)
-{
-	struct spi_bitbang	*bitbang;
-	unsigned long		flags;
-
-	bitbang = spi_master_get_devdata(spi);
-
-	spin_lock_irqsave(&bitbang->lock, flags);
-	bitbang->busy = 1;
-	spin_unlock_irqrestore(&bitbang->lock, flags);
-
-	return 0;
-}
-
 static int spi_bitbang_transfer_one(struct spi_master *master,
 				    struct spi_message *m)
 {
@@ -279,6 +263,8 @@ static int spi_bitbang_transfer_one(struct spi_master *master,
 
 	bitbang = spi_master_get_devdata(master);
 
+	mutex_lock(&bitbang->lock);
+
 	/* FIXME this is made-up ... the correct value is known to
 	 * word-at-a-time bitbang code, and presumably chipselect()
 	 * should enforce these requirements too?
@@ -372,21 +358,9 @@ static int spi_bitbang_transfer_one(struct spi_master *master,
 
 	spi_finalize_current_message(master);
 
-	return status;
-}
-
-static int spi_bitbang_unprepare_hardware(struct spi_master *spi)
-{
-	struct spi_bitbang	*bitbang;
-	unsigned long		flags;
+	mutex_unlock(&bitbang->lock);
 
-	bitbang = spi_master_get_devdata(spi);
-
-	spin_lock_irqsave(&bitbang->lock, flags);
-	bitbang->busy = 0;
-	spin_unlock_irqrestore(&bitbang->lock, flags);
-
-	return 0;
+	return status;
 }
 
 /*----------------------------------------------------------------------*/
@@ -427,7 +401,7 @@ int spi_bitbang_start(struct spi_bitbang *bitbang)
 	if (!master || !bitbang->chipselect)
 		return -EINVAL;
 
-	spin_lock_init(&bitbang->lock);
+	mutex_init(&bitbang->lock);
 
 	if (!master->mode_bits)
 		master->mode_bits = SPI_CPOL | SPI_CPHA | bitbang->flags;
@@ -435,8 +409,6 @@ int spi_bitbang_start(struct spi_bitbang *bitbang)
 	if (master->transfer || master->transfer_one_message)
 		return -EINVAL;
 
-	master->prepare_transfer_hardware = spi_bitbang_prepare_hardware;
-	master->unprepare_transfer_hardware = spi_bitbang_unprepare_hardware;
 	master->transfer_one_message = spi_bitbang_transfer_one;
 
 	if (!bitbang->txrx_bufs) {
diff --git a/include/linux/spi/spi_bitbang.h b/include/linux/spi/spi_bitbang.h
index 85578d4..1329053 100644
--- a/include/linux/spi/spi_bitbang.h
+++ b/include/linux/spi/spi_bitbang.h
@@ -4,8 +4,7 @@
 #include <linux/workqueue.h>
 
 struct spi_bitbang {
-	spinlock_t		lock;
-	u8			busy;
+	struct mutex		lock;
 	u8			use_dma;
 	u8			flags;		/* extra spi->mode support */
 
-- 
2.5.0.rc2.392.g76e840b



From drinkcat at chromium.org  Mon Aug  3 23:09:57 2015
From: drinkcat at chromium.org (Nicolas Boichat)
Date: Tue,  4 Aug 2015 14:09:57 +0800
Subject: [PATCH 2/3] spi: ppc44x: Remove chipselect from setupxfer
In-Reply-To: <1438668598-6678-1-git-send-email-drinkcat@chromium.org>
References: <1438668598-6678-1-git-send-email-drinkcat@chromium.org>
Message-ID: <1438668598-6678-2-git-send-email-drinkcat@chromium.org>

The chipselect operation is already done in spi_bitbang_transfer_one,
or in spi_bitbang_setup, so there is no need to do it in setupxfer
as well.

Signed-off-by: Nicolas Boichat <drinkcat at chromium.org>
---
 drivers/spi/spi-ppc4xx.c | 7 -------
 1 file changed, 7 deletions(-)

diff --git a/drivers/spi/spi-ppc4xx.c b/drivers/spi/spi-ppc4xx.c
index 54fb984..55947f6 100644
--- a/drivers/spi/spi-ppc4xx.c
+++ b/drivers/spi/spi-ppc4xx.c
@@ -210,13 +210,6 @@ static int spi_ppc4xx_setupxfer(struct spi_device *spi, struct spi_transfer *t)
 	if (in_8(&hw->regs->cdm) != cdm)
 		out_8(&hw->regs->cdm, cdm);
 
-	spin_lock(&hw->bitbang.lock);
-	if (!hw->bitbang.busy) {
-		hw->bitbang.chipselect(spi, BITBANG_CS_INACTIVE);
-		/* Need to ndelay here? */
-	}
-	spin_unlock(&hw->bitbang.lock);
-
 	return 0;
 }
 
-- 
2.5.0.rc2.392.g76e840b



From drinkcat at chromium.org  Mon Aug  3 23:09:58 2015
From: drinkcat at chromium.org (Nicolas Boichat)
Date: Tue,  4 Aug 2015 14:09:58 +0800
Subject: [PATCH 3/3] spi: s3c24xx: Convert spinlock to mutex
In-Reply-To: <1438668598-6678-1-git-send-email-drinkcat@chromium.org>
References: <1438668598-6678-1-git-send-email-drinkcat@chromium.org>
Message-ID: <1438668598-6678-3-git-send-email-drinkcat@chromium.org>

bitbang->lock is now a mutex: replace spinlock function calls
by mutex functions.

Signed-off-by: Nicolas Boichat <drinkcat at chromium.org>
---
 drivers/spi/spi-s3c24xx.c | 5 ++---
 1 file changed, 2 insertions(+), 3 deletions(-)

diff --git a/drivers/spi/spi-s3c24xx.c b/drivers/spi/spi-s3c24xx.c
index f36bc32..b1d03e5 100644
--- a/drivers/spi/spi-s3c24xx.c
+++ b/drivers/spi/spi-s3c24xx.c
@@ -198,12 +198,11 @@ static int s3c24xx_spi_setup(struct spi_device *spi)
 	if (ret)
 		return ret;
 
-	spin_lock(&hw->bitbang.lock);
-	if (!hw->bitbang.busy) {
+	if (mutex_trylock(&hw->bitbang.lock)) {
 		hw->bitbang.chipselect(spi, BITBANG_CS_INACTIVE);
 		/* need to ndelay for 0.5 clocktick ? */
+		mutex_unlock(&hw->bitbang.lock);
 	}
-	spin_unlock(&hw->bitbang.lock);
 
 	return 0;
 }
-- 
2.5.0.rc2.392.g76e840b



From eddie.huang at mediatek.com  Mon Aug  3 23:13:49 2015
From: eddie.huang at mediatek.com (Eddie Huang)
Date: Tue, 4 Aug 2015 14:13:49 +0800
Subject: [PATCH] i2c: mediatek: fix transfer error handling
In-Reply-To: <20150731110045.GJ1522@katana>
References: <1438054685-25214-1-git-send-email-eddie.huang@mediatek.com>
 <20150731110045.GJ1522@katana>
Message-ID: <1438668829.16626.4.camel@mtksdaap41>

On Fri, 2015-07-31 at 13:00 +0200, Wolfram Sang wrote:
> On Tue, Jul 28, 2015 at 11:38:05AM +0800, Eddie Huang wrote:
> > From: Liguo Zhang <liguo.zhang at mediatek.com>
> > 
> > Reset i2c dma engine in hw init function.
> > When occur i2c ack error, mtk_i2c_irq may is twice,
> > first is the ack error interrupt, then the complete interrupt,
> > so i2c->irq_stat need keep the two interrupt value, and only
> > call complete() for the complete interrupt.
> > 
> > Signed-off-by: Liguo Zhang <liguo.zhang at mediatek.com>
> > Signed-off-by: Eddie Huang <eddie.huang at mediatek.com>
> 
> Looks to me this patch needs to be split up into one patch per issue?
OK, I can split 

> And doesn't it kill the auto_restart functionality? Sascha?

No. restart_flag already set in mtk_i2c_do_transfer() function.It is not
necessary check restart_flag again in mtk_i2c_irq(). It is simpler to
just read status bit and write back to clear interrupt status.

Eddie
Thanks

> 
> > ---
> >  drivers/i2c/busses/i2c-mt65xx.c |   25 ++++++++++++++++++-------
> >  1 file changed, 18 insertions(+), 7 deletions(-)
> > 
> > diff --git a/drivers/i2c/busses/i2c-mt65xx.c b/drivers/i2c/busses/i2c-mt65xx.c
> > index 9920eef..57d11b7 100644
> > --- a/drivers/i2c/busses/i2c-mt65xx.c
> > +++ b/drivers/i2c/busses/i2c-mt65xx.c
> > @@ -59,6 +59,7 @@
> >  #define I2C_DMA_START_EN		0x0001
> >  #define I2C_DMA_INT_FLAG_NONE		0x0000
> >  #define I2C_DMA_CLR_FLAG		0x0000
> > +#define I2C_DMA_HARD_RST		0x0002
> >  
> >  #define I2C_DEFAULT_SPEED		100000	/* hz */
> >  #define MAX_FS_MODE_SPEED		400000
> > @@ -81,6 +82,7 @@ enum DMA_REGS_OFFSET {
> >  	OFFSET_INT_FLAG = 0x0,
> >  	OFFSET_INT_EN = 0x04,
> >  	OFFSET_EN = 0x08,
> > +	OFFSET_RST = 0x0c,
> >  	OFFSET_CON = 0x18,
> >  	OFFSET_TX_MEM_ADDR = 0x1c,
> >  	OFFSET_RX_MEM_ADDR = 0x20,
> > @@ -262,6 +264,10 @@ static void mtk_i2c_init_hw(struct mtk_i2c *i2c)
> >  		      I2C_CONTROL_CLK_EXT_EN | I2C_CONTROL_DMA_EN;
> >  	writew(control_reg, i2c->base + OFFSET_CONTROL);
> >  	writew(I2C_DELAY_LEN, i2c->base + OFFSET_DELAY_LEN);
> > +
> > +	writel(I2C_DMA_HARD_RST, i2c->pdmabase + OFFSET_RST);
> > +	udelay(50);
> > +	writel(I2C_DMA_CLR_FLAG, i2c->pdmabase + OFFSET_RST);
> >  }
> >  
> >  /*
> > @@ -550,16 +556,20 @@ err_exit:
> >  static irqreturn_t mtk_i2c_irq(int irqno, void *dev_id)
> >  {
> >  	struct mtk_i2c *i2c = dev_id;
> > -	u16 restart_flag = 0;
> > +	u16 intr_stat = 0;
> >  
> > -	if (i2c->dev_comp->auto_restart)
> > -		restart_flag = I2C_RS_TRANSFER;
> > +	intr_stat = readw(i2c->base + OFFSET_INTR_STAT);
> > +	writew(intr_stat, i2c->base + OFFSET_INTR_STAT);
> >  
> > -	i2c->irq_stat = readw(i2c->base + OFFSET_INTR_STAT);
> > -	writew(restart_flag | I2C_HS_NACKERR | I2C_ACKERR
> > -		| I2C_TRANSAC_COMP, i2c->base + OFFSET_INTR_STAT);
> > +	/*
> > +	 * when occurs i2c ack error, mtk_i2c_irq is called twice,
> > +	 * first is the ack error interrupt, then the complete interrupt,
> > +	 * i2c->irq_stat need keep the two interrupt value.
> > +	 */
> > +	i2c->irq_stat |= intr_stat;
> >  
> > -	complete(&i2c->msg_complete);
> > +	if (i2c->irq_stat & I2C_TRANSAC_COMP)
> > +		complete(&i2c->msg_complete);
> >  
> >  	return IRQ_HANDLED;
> >  }
> > @@ -729,3 +739,4 @@ module_platform_driver(mtk_i2c_driver);
> >  MODULE_LICENSE("GPL v2");
> >  MODULE_DESCRIPTION("MediaTek I2C Bus Driver");
> >  MODULE_AUTHOR("Xudong Chen <xudong.chen at mediatek.com>");
> > +MODULE_AUTHOR("Liguo Zhang <liguo.zhang at mediatek.com>");
> > -- 
> > 1.7.9.5
> > 




From bob at xsdiecasting.cn  Mon Aug  3 23:06:31 2015
From: bob at xsdiecasting.cn (Bob)
Date: Tue, 4 Aug 2015 14:06:31 +0800
Subject: Low pressure die castings
Message-ID: <201508041406311098023@xsdiecasting.cn>

Hello,

Here is the prefossional aluminum foundry with advanced machining equipments.
To reduce cost, manufacturers in your market are buying casting parts and component from us.

We have developed the low pressure die castings for their parts instead of gravity casting and sand casting, so that they are more pressure tight and leak free.
Of course, other castings are also available from us, like gravity die casting, sand casting, premanent mold casting to meet your different demand.
All molds made by ourself to reduce your cost. Advanced machining equipments and testing equipments are available from us.

40% of our shipment are for your market, which are proving our competitive in pricing and quality.
Shall you have any interest, pls contact for possible deal.

b.rgds
-----------------------------------------------------------
Bob Hu

Ningbo Yinzhou Xusheng Machinery Factory
Skype: bobhu1
Tel: 0086-574-88128603
Cell: 0086-1395832 7774
bob at xs-aluminumcasting.com
www.xs-aluminumcasting.com

From josh.wu at atmel.com  Mon Aug  3 23:21:45 2015
From: josh.wu at atmel.com (Josh Wu)
Date: Tue, 4 Aug 2015 14:21:45 +0800
Subject: [PATCH] media: atmel-isi: parse the DT parameters for vsync/hsync
 polarity
In-Reply-To: <1896672.nsMcFlgNH5@avalon>
References: <1438338812-22329-1-git-send-email-josh.wu@atmel.com>
 <1896672.nsMcFlgNH5@avalon>
Message-ID: <55C059F9.6070906@atmel.com>

Hi, Laurent

On 8/1/2015 5:11 PM, Laurent Pinchart wrote:
> Hi Josh,
>
> Thank you for the patch.
>
> On Friday 31 July 2015 18:33:32 Josh Wu wrote:
>> This patch will get the DT parameters of vsync/hsync polarity, and pass to
>> the platform data.
>>
>> Also add a debug information for test purpose.
>>
>> Signed-off-by: Josh Wu <josh.wu at atmel.com>
>> ---
>>
>>   drivers/media/platform/soc_camera/atmel-isi.c | 10 ++++++++++
>>   1 file changed, 10 insertions(+)
>>
>> diff --git a/drivers/media/platform/soc_camera/atmel-isi.c
>> b/drivers/media/platform/soc_camera/atmel-isi.c index fe9247a..a7de55c
>> 100644
>> --- a/drivers/media/platform/soc_camera/atmel-isi.c
>> +++ b/drivers/media/platform/soc_camera/atmel-isi.c
>> @@ -811,6 +811,11 @@ static int isi_camera_set_bus_param(struct
>> soc_camera_device *icd) if (common_flags & V4L2_MBUS_PCLK_SAMPLE_FALLING)
>>   		cfg1 |= ISI_CFG1_PIXCLK_POL_ACTIVE_FALLING;
>>
>> +	dev_dbg(icd->parent, "vsync is active %s, hsyc is active %s, pix clock is
>> sampling %s\n",
> s/hsyc/hsync/
>
> I'd write it as "vsync active %s, hsync active %s, sampling on pix clock %s
> edge\n" with "falling" and "rising" instead of "fall" and "rise".

Thanks, I'll correct it.

>
>> +		common_flags & V4L2_MBUS_VSYNC_ACTIVE_LOW ? "low" : "high",
>> +		common_flags & V4L2_MBUS_HSYNC_ACTIVE_LOW ? "low" : "high",
>> +		common_flags & V4L2_MBUS_PCLK_SAMPLE_FALLING ? "fall" : "rise");
>> +
>>   	if (isi->pdata.has_emb_sync)
>>   		cfg1 |= ISI_CFG1_EMB_SYNC;
>>   	if (isi->pdata.full_mode)
>> @@ -898,6 +903,11 @@ static int atmel_isi_probe_dt(struct atmel_isi *isi,
>>   		goto err_probe_dt;
>>   	}
>>
>> +	if (ep.bus.parallel.flags & V4L2_MBUS_HSYNC_ACTIVE_LOW)
>> +		isi->pdata.hsync_act_low = true;
>> +	if (ep.bus.parallel.flags & V4L2_MBUS_VSYNC_ACTIVE_LOW)
>> +		isi->pdata.vsync_act_low = true;
> While you're at it, how about setting has_emb_sync based on ep.bus_type and
> pclk_act_falling from flags & V4L2_MBUS_PCLK_SAMPLE_FALLING ?

I will add the pclk_act_falling handling code as well. And rebase this 
patch on top of your dt modifications.

Best Regards
Josh Wu
>
>>   err_probe_dt:
>>   	of_node_put(np);



From leo.yan at linaro.org  Mon Aug  3 23:27:46 2015
From: leo.yan at linaro.org (Leo Yan)
Date: Tue, 4 Aug 2015 14:27:46 +0800
Subject: [PATCH v3 4/5] clk: Hi6220: add stub clock driver
In-Reply-To: <20150803213752.GB21068@codeaurora.org>
References: <1438564418-15948-1-git-send-email-leo.yan@linaro.org>
 <1438564418-15948-5-git-send-email-leo.yan@linaro.org>
 <20150803213752.GB21068@codeaurora.org>
Message-ID: <20150804062746.GA9112@leoy-linaro>

Hi Stephen,

On Mon, Aug 03, 2015 at 02:37:52PM -0700, Stephen Boyd wrote:
> On 08/03, Leo Yan wrote:
> > diff --git a/drivers/clk/hisilicon/clk-hi6220-stub.c b/drivers/clk/hisilicon/clk-hi6220-stub.c
> > new file mode 100644
> > index 0000000..0931666
> > --- /dev/null
> > +++ b/drivers/clk/hisilicon/clk-hi6220-stub.c
> > @@ -0,0 +1,279 @@
> > +/*
> > + * Hi6220 stub clock driver
> > + *
> > + * Copyright (c) 2015 Hisilicon Limited.
> > + * Copyright (c) 2015 Linaro Limited.
> > + *
> > + * Author: Leo Yan <leo.yan at linaro.org>
> > + *
> > + * This program is free software; you can redistribute it and/or modify
> > + * it under the terms of the GNU General Public License version 2 as
> > + * published by the Free Software Foundation.
> > + *
> > + */
> > +
> > +#include <linux/clkdev.h>
> 
> Is this include used?
> 
> > +#include <linux/clk-provider.h>
> > +#include <linux/clk.h>
> 
> Is this include used?
> 
> > +#include <linux/err.h>
> > +#include <linux/mfd/syscon.h>
> > +#include <linux/mailbox_client.h>
> > +#include <linux/of.h>
> > +#include <linux/of_device.h>
> > +#include <linux/regmap.h>
> > +#include <linux/slab.h>
> > +#include <linux/kernel.h>
> > +
> > +#include <dt-bindings/clock/hi6220-clock.h>
> > +
> > +/* Stub clocks id */
> > +#define HI6220_STUB_ACPU0		0
> > +#define HI6220_STUB_ACPU1		1
> > +#define HI6220_STUB_GPU			2
> > +#define HI6220_STUB_DDR			5
> > +
> > +/* Mailbox message */
> > +#define HI6220_MBOX_MSG_LEN		8
> > +
> > +#define HI6220_MBOX_FREQ		(0xA)
> > +#define HI6220_MBOX_CMD_SET		(0x3)
> > +#define HI6220_MBOX_OBJ_AP		(0x0)
> > +
> > +/* CPU dynamic frequency scaling */
> > +#define ACPU_DFS_FREQ_MAX		(0x1724)
> > +#define ACPU_DFS_CUR_FREQ		(0x17CC)
> > +#define ACPU_DFS_FLAG			(0x1B30)
> > +#define ACPU_DFS_FREQ_REQ		(0x1B34)
> > +#define ACPU_DFS_FREQ_LMT		(0x1B38)
> > +#define ACPU_DFS_LOCK_FLAG		(0xAEAEAEAE)
> 
> We don't need parenthesis around single values in these macros.
> 
> > +
> > +#define to_stub_clk(hw) container_of(hw, struct hi6220_stub_clk, hw)
> > +
> > +struct hi6220_stub_clk {
> > +	u32 id;
> > +	u32 rate;
> > +
> > +	struct device *dev;
> > +	struct clk_hw hw;
> > +
> > +	struct regmap *dfs_map;
> > +	struct mbox_client cl;
> > +	struct mbox_chan *mbox;
> > +};
> > +
> > +struct hi6220_mbox_msg {
> > +	unsigned char type;
> > +	unsigned char cmd;
> > +	unsigned char obj;
> > +	unsigned char src;
> > +	unsigned char para[4];
> > +};
> > +
> > +union hi6220_mbox_data {
> > +	unsigned int data[HI6220_MBOX_MSG_LEN];
> > +	struct hi6220_mbox_msg msg;
> > +};
> > +
> > +static unsigned int hi6220_acpu_get_freq(struct hi6220_stub_clk *stub_clk)
> > +{
> > +	unsigned int freq;
> > +
> > +	regmap_read(stub_clk->dfs_map, ACPU_DFS_CUR_FREQ, &freq);
> > +	return freq;
> > +}
> > +
> > +static int hi6220_acpu_set_freq(struct hi6220_stub_clk *stub_clk,
> > +				unsigned int freq)
> > +{
> > +	union hi6220_mbox_data data;
> > +
> > +	stub_clk->mbox = mbox_request_channel(&stub_clk->cl, 0);
> 
> Why not request the channel once in probe?
> 
> > +	if (IS_ERR(stub_clk->mbox)) {
> > +		dev_err(stub_clk->dev, "failed get mailbox channel\n");
> > +		return PTR_ERR(stub_clk->mbox);
> > +	};
> > +
> > +	/* set the frequency in sram */
> > +	regmap_write(stub_clk->dfs_map, ACPU_DFS_FREQ_REQ, freq);
> > +
> > +	/* compound mailbox message */
> > +	data.msg.type = HI6220_MBOX_FREQ;
> > +	data.msg.cmd  = HI6220_MBOX_CMD_SET;
> > +	data.msg.obj  = HI6220_MBOX_OBJ_AP;
> > +	data.msg.src  = HI6220_MBOX_OBJ_AP;
> > +
> > +	mbox_send_message(stub_clk->mbox, &data);
> > +	mbox_free_channel(stub_clk->mbox);
> > +	return 0;
> > +}
> > +
> > +static int hi6220_acpu_round_freq(struct hi6220_stub_clk *stub_clk,
> > +				  unsigned int freq)
> > +{
> > +	unsigned int limit_flag, limit_freq = UINT_MAX;
> > +	unsigned int max_freq;
> > +
> > +	/* check the constrainted frequency */
> 
> s/constrainted/constrained/ ?
> 
> > +	regmap_read(stub_clk->dfs_map, ACPU_DFS_FLAG, &limit_flag);
> > +	if (limit_flag == ACPU_DFS_LOCK_FLAG)
> > +		regmap_read(stub_clk->dfs_map, ACPU_DFS_FREQ_LMT, &limit_freq);
> > +
> > +	/* check the supported maximum frequency */
> > +	regmap_read(stub_clk->dfs_map, ACPU_DFS_FREQ_MAX, &max_freq);
> > +
> > +	/* calculate the real maximum frequency */
> > +	max_freq = min(max_freq, limit_freq);
> > +
> > +	if (WARN_ON(freq > max_freq))
> > +		freq = max_freq;
> > +
> > +	return freq;
> > +}
> > +
> > +static unsigned long hi6220_stub_clk_recalc_rate(struct clk_hw *hw,
> > +		unsigned long parent_rate)
> > +{
> > +	u32 rate = 0;
> > +	struct hi6220_stub_clk *stub_clk = to_stub_clk(hw);
> > +
> > +	switch (stub_clk->id) {
> > +	case HI6220_STUB_ACPU0:
> > +		rate = hi6220_acpu_get_freq(stub_clk);
> > +
> > +		/* convert from KHz to Hz */
> 
> s/KHz/kHz/ ?
> 
> > +		rate *= 1000;
> > +		break;
> > +
> > +	default:
> > +		dev_err(stub_clk->dev, "%s: un-supported clock id %d\n",
> > +			__func__, stub_clk->id);
> > +		break;
> > +	}
> > +
> > +	return rate;
> > +}
> > +
> > +static int hi6220_stub_clk_set_rate(struct clk_hw *hw, unsigned long rate,
> > +                    unsigned long parent_rate)
> > +{
> > +	struct hi6220_stub_clk *stub_clk = to_stub_clk(hw);
> > +	unsigned long new_rate = rate / 1000;  /* Khz */
> 
> s/KHz/kHz/ ?
> 
> > +	int ret = 0;
> > +
> > +	switch (stub_clk->id) {
> > +	case HI6220_STUB_ACPU0:
> > +		ret = hi6220_acpu_set_freq(stub_clk, new_rate);
> > +		if (ret < 0)
> > +			return ret;
> > +
> > +		break;
> > +
> > +	default:
> > +		dev_err(stub_clk->dev, "%s: un-supported clock id %d\n",
> > +			__func__, stub_clk->id);
> > +		break;
> > +	}
> > +
> > +	stub_clk->rate = new_rate;
> 
> Why do we store away the rate? Is this used anywhere?
> 
> > +
> > +	pr_debug("%s: set rate=%ldKhz\n", __func__, new_rate);
> > +	return ret;
> > +}
> > +
> > +static long hi6220_stub_clk_round_rate(struct clk_hw *hw, unsigned long rate,
> > +		unsigned long *parent_rate)
> > +{
> > +	struct hi6220_stub_clk *stub_clk = to_stub_clk(hw);
> > +	unsigned long new_rate = rate / 1000;  /* Khz */
> 
> s/KHz/kHz/ ?
> 
> > +
> > +	switch (stub_clk->id) {
> > +	case HI6220_STUB_ACPU0:
> > +		new_rate = hi6220_acpu_round_freq(stub_clk, new_rate);
> > +
> > +		/* convert from KHz to Hz */
> 
> s/KHz/kHz/ ?
> 
> > +		new_rate *= 1000;
> > +		break;
> > +
> > +	default:
> > +		dev_err(stub_clk->dev, "%s: un-supported clock id %d\n",
> > +			__func__, stub_clk->id);
> > +		break;
> > +	}
> > +
> > +	return new_rate;
> > +}
> > +
> > +static struct clk_ops hi6220_stub_clk_ops = {
> 
> const?
> 
> > +	.recalc_rate	= hi6220_stub_clk_recalc_rate,
> > +	.round_rate	= hi6220_stub_clk_round_rate,
> > +	.set_rate	= hi6220_stub_clk_set_rate,
> > +};
> > +
> > +static int hi6220_stub_clk_probe(struct platform_device *pdev)
> > +{
> > +	struct device *dev = &pdev->dev;
> > +	struct clk_init_data init;
> > +	struct hi6220_stub_clk *stub_clk;
> > +	struct clk *clk;
> > +	struct device_node *np = pdev->dev.of_node;
> > +
> > +	stub_clk = devm_kzalloc(&pdev->dev, sizeof(*stub_clk), GFP_KERNEL);
> 
> just use dev?
> 
> > +	if (!stub_clk)
> > +		return -ENOMEM;
> > +
> > +	stub_clk->dfs_map = syscon_regmap_lookup_by_phandle(np,
> > +				"hisilicon,hi6220-clk-sram");
> > +	if (IS_ERR(stub_clk->dfs_map)) {
> > +		dev_err(dev, "failed to get sram regmap\n");
> > +		return PTR_ERR(stub_clk->dfs_map);
> > +	}
> > +
> > +	stub_clk->hw.init = &init;
> > +	stub_clk->dev = dev;
> > +	stub_clk->id = HI6220_STUB_ACPU0;
> > +
> > +	/* Use mailbox client with blocking mode */
> > +	stub_clk->cl.dev = &pdev->dev;
> 
> just use dev?
> 
> > +	stub_clk->cl.tx_done = NULL;
> > +	stub_clk->cl.tx_block = true;
> > +	stub_clk->cl.tx_tout = 500;
> > +	stub_clk->cl.knows_txdone = false;
> > +
> > +	init.name = "acpu0";
> > +	init.ops = &hi6220_stub_clk_ops;
> > +	init.num_parents = 0;
> > +	init.flags = CLK_IS_ROOT;
> > +
> > +	clk = clk_register(NULL, &stub_clk->hw);
> 
> why not devm_clk_register?
> 
> > +	if (IS_ERR(clk))
> > +		return PTR_ERR(clk);
> > +
> > +	of_clk_add_provider(pdev->dev.of_node, of_clk_src_simple_get, clk);
> 
> And check this for an error return value? Also, just use dev?
> 
> > +
> > +	/* initialize buffer to zero */
> > +	regmap_write(stub_clk->dfs_map, ACPU_DFS_FLAG, 0x0);
> > +	regmap_write(stub_clk->dfs_map, ACPU_DFS_FREQ_REQ, 0x0);
> > +	regmap_write(stub_clk->dfs_map, ACPU_DFS_FREQ_LMT, 0x0);
> > +
> > +	dev_dbg(&pdev->dev, "Registered clock '%s'\n", init.name);
> 
> just use dev?
> 
> > +	return 0;
> > +}
> > +
> > +static const struct of_device_id hi6220_stub_clk_of_match[] = {
> > +	{ .compatible = "hisilicon,hi6220-stub-clk", },
> > +	{}
> > +};
> > +
> > +static struct platform_driver hi6220_stub_clk_driver = {
> > +	.driver	= {
> > +		.name = "hi6220-stub-clk",
> > +		.of_match_table = of_match_ptr(hi6220_stub_clk_of_match),
> 
> We can leave off of_match_ptr() here.
> 
> > +	},
> > +	.probe = hi6220_stub_clk_probe,
> > +};


Thanks for review; Accept all comments and will refine for them :)

Thanks,
Leo Yan


From josh.wu at atmel.com  Mon Aug  3 23:47:07 2015
From: josh.wu at atmel.com (Josh Wu)
Date: Tue, 4 Aug 2015 14:47:07 +0800
Subject: [PATCH v2] media: atmel-isi: parse the DT parameters for
 vsync/hsync/pixclock polarity
Message-ID: <1438670828-19845-1-git-send-email-josh.wu@atmel.com>

This patch will get the DT parameters of vsync/hsync/pixclock polarity, and
pass to driver.

Also add a debug information for test purpose.

Signed-off-by: Josh Wu <josh.wu at atmel.com>
---

Changes in v2:
- rewrite the debug message and add pix clock polarity setup thanks to
  Laurent.
- update the commit log.

 drivers/media/platform/soc_camera/atmel-isi.c | 12 ++++++++++++
 1 file changed, 12 insertions(+)

diff --git a/drivers/media/platform/soc_camera/atmel-isi.c b/drivers/media/platform/soc_camera/atmel-isi.c
index fead841..d6f8def 100644
--- a/drivers/media/platform/soc_camera/atmel-isi.c
+++ b/drivers/media/platform/soc_camera/atmel-isi.c
@@ -1061,6 +1061,11 @@ static int isi_camera_set_bus_param(struct soc_camera_device *icd)
 	if (common_flags & V4L2_MBUS_PCLK_SAMPLE_FALLING)
 		cfg1 |= ISI_CFG1_PIXCLK_POL_ACTIVE_FALLING;
 
+	dev_dbg(icd->parent, "vsync active %s, hsync active %s, sampling on pix clock %s\n",
+		common_flags & V4L2_MBUS_VSYNC_ACTIVE_LOW ? "low" : "high",
+		common_flags & V4L2_MBUS_HSYNC_ACTIVE_LOW ? "low" : "high",
+		common_flags & V4L2_MBUS_PCLK_SAMPLE_FALLING ? "falling" : "rising");
+
 	if (isi->pdata.has_emb_sync)
 		cfg1 |= ISI_CFG1_EMB_SYNC;
 	if (isi->pdata.full_mode)
@@ -1148,6 +1153,13 @@ static int atmel_isi_parse_dt(struct atmel_isi *isi,
 		return -EINVAL;
 	}
 
+	if (ep.bus.parallel.flags & V4L2_MBUS_HSYNC_ACTIVE_LOW)
+		isi->pdata.hsync_act_low = true;
+	if (ep.bus.parallel.flags & V4L2_MBUS_VSYNC_ACTIVE_LOW)
+		isi->pdata.vsync_act_low = true;
+	if (ep.bus.parallel.flags & V4L2_MBUS_PCLK_SAMPLE_FALLING)
+		isi->pdata.pclk_act_falling = true;
+
 	return 0;
 }
 
-- 
1.9.1



From p.fedin at samsung.com  Mon Aug  3 23:53:07 2015
From: p.fedin at samsung.com (Pavel Fedin)
Date: Tue, 04 Aug 2015 09:53:07 +0300
Subject: [PATCH v2 14/15] KVM: arm64: implement MSI injection in ITS
 emulation
In-Reply-To: <55BF9FB0.6070804@arm.com>
References: <1436538111-4294-1-git-send-email-andre.przywara@arm.com>
 <1436538111-4294-15-git-send-email-andre.przywara@arm.com>
 <55BB7678.5080105@linaro.org> <55BE7BA1.40403@arm.com>
 <00a201d0cdb7$70a623f0$51f26bd0$@samsung.com> <55BF2F51.6020701@linaro.org>
 <00f101d0cdcd$146a6090$3d3f21b0$@samsung.com> <55BF8AB8.5050408@linaro.org>
 <55BF9FB0.6070804@arm.com>
Message-ID: <00b101d0ce82$38caa7a0$aa5ff6e0$@samsung.com>

 Hello!

> I think this flag should be kept, as it really indicates what is valid
> in the MSI structure. It also has other benefits such as making obvious
> what userspace expects, which can then be checked against the kernel's
> own expectations.

 I'm OK with the flag despite it's indeed a small bit redundant. But i see that kernel's policy is
to have insurance against all possible and impossible bad inputs, and the flag really fits into the
concept.

Kind regards,
Pavel Fedin
Expert Engineer
Samsung Electronics Research center Russia



From tglx at linutronix.de  Tue Aug  4 00:14:34 2015
From: tglx at linutronix.de (Thomas Gleixner)
Date: Tue, 4 Aug 2015 09:14:34 +0200 (CEST)
Subject: [PATCH] irqchip: bcm2836: Use a CPU notifier enable IPIs.
In-Reply-To: <87fv40lzxe.fsf@eliezer.anholt.net>
References: <55B67C81.1010900@gmail.com>
 <1438027789-1637-1-git-send-email-eric@anholt.net>
 <alpine.DEB.2.11.1508021221370.3825@nanos>
 <87fv40lzxe.fsf@eliezer.anholt.net>
Message-ID: <alpine.DEB.2.11.1508040913490.3959@nanos>

On Mon, 3 Aug 2015, Eric Anholt wrote:

> Thomas Gleixner <tglx at linutronix.de> writes:
> 
> > On Mon, 27 Jul 2015, Eric Anholt wrote:
> >> +/* Unmasks the IPI on the CPU wen it's first brought online. */
> >
> > when
> >
> >> +static int bcm2836_arm_irqchip_cpu_notify(struct notifier_block *nfb,
> >> +					  unsigned long action, void *hcpu)
> >> +{
> >> +	unsigned int cpu = (unsigned long)hcpu;
> >> +	unsigned int int_reg = LOCAL_MAILBOX_INT_CONTROL0;
> >> +	unsigned int mailbox = 0;
> >> +
> >> +	if (action == CPU_STARTING || action == CPU_STARTING_FROZEN)
> >> +		bcm2836_arm_irqchip_unmask_per_cpu_irq(int_reg, mailbox, cpu);
> >
> > Shouldn't you mask the irq on CPU_DYING?
> 
> I was just following what other drivers were doing.  Is CPU_DYING the
> only thing that needs masking?

CPPU_DYING is the counterpart of CPU_STARTING. It's called from the
CPU which goes down.

Thanks,

	tglx



From leo.yan at linaro.org  Tue Aug  4 00:27:25 2015
From: leo.yan at linaro.org (Leo Yan)
Date: Tue,  4 Aug 2015 15:27:25 +0800
Subject: [PATCH v4 0/4] clk: hisilicon: support stub clock
Message-ID: <1438673249-6051-1-git-send-email-leo.yan@linaro.org>

This series adds support for hisilicon stub clock driver. On hi6220,
the bootloader needs load the firmware image and set info for OPPs;
after run into kernel, the stub clock driver is used to communicate
w/t firmware for cpu dynamic frequency scaling.

In patch series v1/v2, the stub clock driver simply writes request in
sram and send ipc to firmware; For patch series v3, the firmware has
been upgraded to use mailbox, so stub clock driver will call standard
mailbox APIs to request mailbox channel and send message to firmware.

Patch 4 adds stub clock node into dts and it references mailbox with
phandle, so patch 4 will depend on mailbox driver's patch series [1].
These patches have been tested on 96board hikey and is used by cpufreq
driver.

Changes from v3:
* Patch "clk: hisi: refine parameter checking for init" [2] has been
  applied to clk-next, so skip it in v4
* According to Stephen Boyd's review, fix and refine stub clock driver
* The stub clock driver depends on mailbox channel's initialization, so
  mailbox init firstly with core_initcall() and use subsys_initcall()
  for stub clock driver

Changes from v2:
* Use platform_device's probe for clock's initialization
* Use mailbox channel for clock frequency change

Changes from v1:
* Refine parameter checking for init flow
* Remove unnecessary debugging info
* Modify to check spinlock pointer when register clocks

[1] http://archive.arm.linux.org.uk/lurker/message/20150803.011307.1062b247.en.html
[2] http://archive.arm.linux.org.uk/lurker/message/20150803.011334.4b6f2fc7.en.html


Leo Yan (4):
  dt-bindings: arm: Hi6220: add doc for SRAM controller
  dt-bindings: clk: Hi6220: Document stub clock driver
  clk: Hi6220: add stub clock driver
  arm64: dts: add Hi6220's stub clock node

 .../bindings/arm/hisilicon/hisilicon.txt           |  18 ++
 .../devicetree/bindings/clock/hi6220-clock.txt     |  19 +-
 arch/arm64/boot/dts/hisilicon/hi6220.dtsi          |  23 ++
 drivers/clk/hisilicon/Kconfig                      |   2 +-
 drivers/clk/hisilicon/Makefile                     |   2 +-
 drivers/clk/hisilicon/clk-hi6220-stub.c            | 276 +++++++++++++++++++++
 6 files changed, 337 insertions(+), 3 deletions(-)
 create mode 100644 drivers/clk/hisilicon/clk-hi6220-stub.c

-- 
1.9.1



From leo.yan at linaro.org  Tue Aug  4 00:27:26 2015
From: leo.yan at linaro.org (Leo Yan)
Date: Tue,  4 Aug 2015 15:27:26 +0800
Subject: [PATCH v4 1/4] dt-bindings: arm: Hi6220: add doc for SRAM controller
In-Reply-To: <1438673249-6051-1-git-send-email-leo.yan@linaro.org>
References: <1438673249-6051-1-git-send-email-leo.yan@linaro.org>
Message-ID: <1438673249-6051-2-git-send-email-leo.yan@linaro.org>

Document "hisilicon,hi6220-sramctrl" for SRAM controller.

Signed-off-by: Leo Yan <leo.yan at linaro.org>
---
 .../devicetree/bindings/arm/hisilicon/hisilicon.txt    | 18 ++++++++++++++++++
 1 file changed, 18 insertions(+)

diff --git a/Documentation/devicetree/bindings/arm/hisilicon/hisilicon.txt b/Documentation/devicetree/bindings/arm/hisilicon/hisilicon.txt
index c431c67..c733e28 100644
--- a/Documentation/devicetree/bindings/arm/hisilicon/hisilicon.txt
+++ b/Documentation/devicetree/bindings/arm/hisilicon/hisilicon.txt
@@ -127,6 +127,24 @@ Example:
 		#clock-cells = <1>;
 	};
 
+
+Hisilicon Hi6220 SRAM controller
+
+Required properties:
+- compatible : "hisilicon,hi6220-sramctrl", "syscon"
+- reg : Register address and size
+
+Hisilicon's SoCs use sram for multiple purpose; on Hi6220 there have several
+SRAM banks for power management, modem, security, etc. Further, use "syscon"
+managing the common sram which can be shared by multiple modules.
+
+Example:
+	/*for Hi6220*/
+	sram: sram at fff80000 {
+		compatible = "hisilicon,hi6220-sramctrl", "syscon";
+		reg = <0x0 0xfff80000 0x0 0x12000>;
+	};
+
 -----------------------------------------------------------------------
 Hisilicon HiP01 system controller
 
-- 
1.9.1



From leo.yan at linaro.org  Tue Aug  4 00:27:27 2015
From: leo.yan at linaro.org (Leo Yan)
Date: Tue,  4 Aug 2015 15:27:27 +0800
Subject: [PATCH v4 2/4] dt-bindings: clk: Hi6220: Document stub clock driver
In-Reply-To: <1438673249-6051-1-git-send-email-leo.yan@linaro.org>
References: <1438673249-6051-1-git-send-email-leo.yan@linaro.org>
Message-ID: <1438673249-6051-3-git-send-email-leo.yan@linaro.org>

Document the new compatible for stub clock driver which is used for CPU
and DDR's dynamic frequency scaling.

Signed-off-by: Leo Yan <leo.yan at linaro.org>
---
 .../devicetree/bindings/clock/hi6220-clock.txt        | 19 ++++++++++++++++++-
 1 file changed, 18 insertions(+), 1 deletion(-)

diff --git a/Documentation/devicetree/bindings/clock/hi6220-clock.txt b/Documentation/devicetree/bindings/clock/hi6220-clock.txt
index 259e30a..e4d5fea 100644
--- a/Documentation/devicetree/bindings/clock/hi6220-clock.txt
+++ b/Documentation/devicetree/bindings/clock/hi6220-clock.txt
@@ -15,19 +15,36 @@ Required Properties:
 	- "hisilicon,hi6220-sysctrl"
 	- "hisilicon,hi6220-mediactrl"
 	- "hisilicon,hi6220-pmctrl"
+	- "hisilicon,hi6220-stub-clk"
 
 - reg: physical base address of the controller and length of memory mapped
   region.
 
 - #clock-cells: should be 1.
 
-For example:
+Optional Properties:
+
+- hisilicon,hi6220-clk-sram: phandle to the syscon managing the SoC internal sram;
+  the driver need use the sram to pass parameters for frequency change.
+
+- mboxes: use the label reference for the mailbox as the first parameter, the
+  second parameter is the channel number.
+
+Example 1:
 	sys_ctrl: sys_ctrl at f7030000 {
 		compatible = "hisilicon,hi6220-sysctrl", "syscon";
 		reg = <0x0 0xf7030000 0x0 0x2000>;
 		#clock-cells = <1>;
 	};
 
+Example 2:
+	stub_clock: stub_clock {
+		compatible = "hisilicon,hi6220-stub-clk";
+		hisilicon,hi6220-clk-sram = <&sram>;
+		#clock-cells = <1>;
+		mboxes = <&mailbox 1>;
+	};
+
 Each clock is assigned an identifier and client nodes use this identifier
 to specify the clock which they consume.
 
-- 
1.9.1



From leo.yan at linaro.org  Tue Aug  4 00:27:28 2015
From: leo.yan at linaro.org (Leo Yan)
Date: Tue,  4 Aug 2015 15:27:28 +0800
Subject: [PATCH v4 3/4] clk: Hi6220: add stub clock driver
In-Reply-To: <1438673249-6051-1-git-send-email-leo.yan@linaro.org>
References: <1438673249-6051-1-git-send-email-leo.yan@linaro.org>
Message-ID: <1438673249-6051-4-git-send-email-leo.yan@linaro.org>

On Hi6220, there have some clocks which can use mailbox channel to send
messages to power controller to change frequency; this includes CPU, GPU
and DDR clocks.

For dynamic frequency scaling, firstly need write the frequency value to
SRAM region, and then send message to mailbox to trigger power controller
to handle this requirement. This driver will use syscon APIs to pass SRAM
memory region and use common mailbox APIs for channels accessing.

This init driver will support cpu frequency change firstly.

Signed-off-by: Leo Yan <leo.yan at linaro.org>
---
 drivers/clk/hisilicon/Kconfig           |   2 +-
 drivers/clk/hisilicon/Makefile          |   2 +-
 drivers/clk/hisilicon/clk-hi6220-stub.c | 276 ++++++++++++++++++++++++++++++++
 3 files changed, 278 insertions(+), 2 deletions(-)
 create mode 100644 drivers/clk/hisilicon/clk-hi6220-stub.c

diff --git a/drivers/clk/hisilicon/Kconfig b/drivers/clk/hisilicon/Kconfig
index b4165ba..2c16807 100644
--- a/drivers/clk/hisilicon/Kconfig
+++ b/drivers/clk/hisilicon/Kconfig
@@ -1,6 +1,6 @@
 config COMMON_CLK_HI6220
 	bool "Hi6220 Clock Driver"
-	depends on ARCH_HISI || COMPILE_TEST
+	depends on (ARCH_HISI || COMPILE_TEST) && MAILBOX
 	default ARCH_HISI
 	help
 	  Build the Hisilicon Hi6220 clock driver based on the common clock framework.
diff --git a/drivers/clk/hisilicon/Makefile b/drivers/clk/hisilicon/Makefile
index 48f0116..4a1001a 100644
--- a/drivers/clk/hisilicon/Makefile
+++ b/drivers/clk/hisilicon/Makefile
@@ -7,4 +7,4 @@ obj-y	+= clk.o clkgate-separated.o clkdivider-hi6220.o
 obj-$(CONFIG_ARCH_HI3xxx)	+= clk-hi3620.o
 obj-$(CONFIG_ARCH_HIP04)	+= clk-hip04.o
 obj-$(CONFIG_ARCH_HIX5HD2)	+= clk-hix5hd2.o
-obj-$(CONFIG_COMMON_CLK_HI6220)	+= clk-hi6220.o
+obj-$(CONFIG_COMMON_CLK_HI6220)	+= clk-hi6220.o clk-hi6220-stub.o
diff --git a/drivers/clk/hisilicon/clk-hi6220-stub.c b/drivers/clk/hisilicon/clk-hi6220-stub.c
new file mode 100644
index 0000000..9337d43
--- /dev/null
+++ b/drivers/clk/hisilicon/clk-hi6220-stub.c
@@ -0,0 +1,276 @@
+/*
+ * Hi6220 stub clock driver
+ *
+ * Copyright (c) 2015 Hisilicon Limited.
+ * Copyright (c) 2015 Linaro Limited.
+ *
+ * Author: Leo Yan <leo.yan at linaro.org>
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License version 2 as
+ * published by the Free Software Foundation.
+ *
+ */
+
+#include <linux/clk-provider.h>
+#include <linux/err.h>
+#include <linux/kernel.h>
+#include <linux/mfd/syscon.h>
+#include <linux/mailbox_client.h>
+#include <linux/of.h>
+#include <linux/of_device.h>
+#include <linux/regmap.h>
+
+/* Stub clocks id */
+#define HI6220_STUB_ACPU0		0
+#define HI6220_STUB_ACPU1		1
+#define HI6220_STUB_GPU			2
+#define HI6220_STUB_DDR			5
+
+/* Mailbox message */
+#define HI6220_MBOX_MSG_LEN		8
+
+#define HI6220_MBOX_FREQ		0xA
+#define HI6220_MBOX_CMD_SET		0x3
+#define HI6220_MBOX_OBJ_AP		0x0
+
+/* CPU dynamic frequency scaling */
+#define ACPU_DFS_FREQ_MAX		0x1724
+#define ACPU_DFS_CUR_FREQ		0x17CC
+#define ACPU_DFS_FLAG			0x1B30
+#define ACPU_DFS_FREQ_REQ		0x1B34
+#define ACPU_DFS_FREQ_LMT		0x1B38
+#define ACPU_DFS_LOCK_FLAG		0xAEAEAEAE
+
+#define to_stub_clk(hw) container_of(hw, struct hi6220_stub_clk, hw)
+
+struct hi6220_stub_clk {
+	u32 id;
+
+	struct device *dev;
+	struct clk_hw hw;
+
+	struct regmap *dfs_map;
+	struct mbox_client cl;
+	struct mbox_chan *mbox;
+};
+
+struct hi6220_mbox_msg {
+	unsigned char type;
+	unsigned char cmd;
+	unsigned char obj;
+	unsigned char src;
+	unsigned char para[4];
+};
+
+union hi6220_mbox_data {
+	unsigned int data[HI6220_MBOX_MSG_LEN];
+	struct hi6220_mbox_msg msg;
+};
+
+static unsigned int hi6220_acpu_get_freq(struct hi6220_stub_clk *stub_clk)
+{
+	unsigned int freq;
+
+	regmap_read(stub_clk->dfs_map, ACPU_DFS_CUR_FREQ, &freq);
+	return freq;
+}
+
+static int hi6220_acpu_set_freq(struct hi6220_stub_clk *stub_clk,
+				unsigned int freq)
+{
+	union hi6220_mbox_data data;
+
+	/* set the frequency in sram */
+	regmap_write(stub_clk->dfs_map, ACPU_DFS_FREQ_REQ, freq);
+
+	/* compound mailbox message */
+	data.msg.type = HI6220_MBOX_FREQ;
+	data.msg.cmd  = HI6220_MBOX_CMD_SET;
+	data.msg.obj  = HI6220_MBOX_OBJ_AP;
+	data.msg.src  = HI6220_MBOX_OBJ_AP;
+
+	mbox_send_message(stub_clk->mbox, &data);
+	return 0;
+}
+
+static int hi6220_acpu_round_freq(struct hi6220_stub_clk *stub_clk,
+				  unsigned int freq)
+{
+	unsigned int limit_flag, limit_freq = UINT_MAX;
+	unsigned int max_freq;
+
+	/* check the constrained frequency */
+	regmap_read(stub_clk->dfs_map, ACPU_DFS_FLAG, &limit_flag);
+	if (limit_flag == ACPU_DFS_LOCK_FLAG)
+		regmap_read(stub_clk->dfs_map, ACPU_DFS_FREQ_LMT, &limit_freq);
+
+	/* check the supported maximum frequency */
+	regmap_read(stub_clk->dfs_map, ACPU_DFS_FREQ_MAX, &max_freq);
+
+	/* calculate the real maximum frequency */
+	max_freq = min(max_freq, limit_freq);
+
+	if (WARN_ON(freq > max_freq))
+		freq = max_freq;
+
+	return freq;
+}
+
+static unsigned long hi6220_stub_clk_recalc_rate(struct clk_hw *hw,
+		unsigned long parent_rate)
+{
+	u32 rate = 0;
+	struct hi6220_stub_clk *stub_clk = to_stub_clk(hw);
+
+	switch (stub_clk->id) {
+	case HI6220_STUB_ACPU0:
+		rate = hi6220_acpu_get_freq(stub_clk);
+
+		/* convert from kHz to Hz */
+		rate *= 1000;
+		break;
+
+	default:
+		dev_err(stub_clk->dev, "%s: un-supported clock id %d\n",
+			__func__, stub_clk->id);
+		break;
+	}
+
+	return rate;
+}
+
+static int hi6220_stub_clk_set_rate(struct clk_hw *hw, unsigned long rate,
+                    unsigned long parent_rate)
+{
+	struct hi6220_stub_clk *stub_clk = to_stub_clk(hw);
+	unsigned long new_rate = rate / 1000;  /* kHz */
+	int ret = 0;
+
+	switch (stub_clk->id) {
+	case HI6220_STUB_ACPU0:
+		ret = hi6220_acpu_set_freq(stub_clk, new_rate);
+		if (ret < 0)
+			return ret;
+
+		break;
+
+	default:
+		dev_err(stub_clk->dev, "%s: un-supported clock id %d\n",
+			__func__, stub_clk->id);
+		break;
+	}
+
+	pr_debug("%s: set rate=%ldkHz\n", __func__, new_rate);
+	return ret;
+}
+
+static long hi6220_stub_clk_round_rate(struct clk_hw *hw, unsigned long rate,
+		unsigned long *parent_rate)
+{
+	struct hi6220_stub_clk *stub_clk = to_stub_clk(hw);
+	unsigned long new_rate = rate / 1000;  /* kHz */
+
+	switch (stub_clk->id) {
+	case HI6220_STUB_ACPU0:
+		new_rate = hi6220_acpu_round_freq(stub_clk, new_rate);
+
+		/* convert from kHz to Hz */
+		new_rate *= 1000;
+		break;
+
+	default:
+		dev_err(stub_clk->dev, "%s: un-supported clock id %d\n",
+			__func__, stub_clk->id);
+		break;
+	}
+
+	return new_rate;
+}
+
+static const struct clk_ops hi6220_stub_clk_ops = {
+	.recalc_rate	= hi6220_stub_clk_recalc_rate,
+	.round_rate	= hi6220_stub_clk_round_rate,
+	.set_rate	= hi6220_stub_clk_set_rate,
+};
+
+static int hi6220_stub_clk_probe(struct platform_device *pdev)
+{
+	struct device *dev = &pdev->dev;
+	struct clk_init_data init;
+	struct hi6220_stub_clk *stub_clk;
+	struct clk *clk;
+	struct device_node *np = pdev->dev.of_node;
+	int ret;
+
+	stub_clk = devm_kzalloc(dev, sizeof(*stub_clk), GFP_KERNEL);
+	if (!stub_clk)
+		return -ENOMEM;
+
+	stub_clk->dfs_map = syscon_regmap_lookup_by_phandle(np,
+				"hisilicon,hi6220-clk-sram");
+	if (IS_ERR(stub_clk->dfs_map)) {
+		dev_err(dev, "failed to get sram regmap\n");
+		return PTR_ERR(stub_clk->dfs_map);
+	}
+
+	stub_clk->hw.init = &init;
+	stub_clk->dev = dev;
+	stub_clk->id = HI6220_STUB_ACPU0;
+
+	/* Use mailbox client with blocking mode */
+	stub_clk->cl.dev = dev;
+	stub_clk->cl.tx_done = NULL;
+	stub_clk->cl.tx_block = true;
+	stub_clk->cl.tx_tout = 500;
+	stub_clk->cl.knows_txdone = false;
+
+	/* Allocate mailbox channel */
+	stub_clk->mbox = mbox_request_channel(&stub_clk->cl, 0);
+	if (IS_ERR(stub_clk->mbox)) {
+		dev_err(dev, "failed get mailbox channel\n");
+		return PTR_ERR(stub_clk->mbox);
+	};
+
+	init.name = "acpu0";
+	init.ops = &hi6220_stub_clk_ops;
+	init.num_parents = 0;
+	init.flags = CLK_IS_ROOT;
+
+	clk = devm_clk_register(dev, &stub_clk->hw);
+	if (IS_ERR(clk))
+		return PTR_ERR(clk);
+
+	ret = of_clk_add_provider(np, of_clk_src_simple_get, clk);
+	if (ret) {
+		dev_err(dev, "failed to register OF clock provider\n");
+		return ret;
+	}
+
+	/* initialize buffer to zero */
+	regmap_write(stub_clk->dfs_map, ACPU_DFS_FLAG, 0x0);
+	regmap_write(stub_clk->dfs_map, ACPU_DFS_FREQ_REQ, 0x0);
+	regmap_write(stub_clk->dfs_map, ACPU_DFS_FREQ_LMT, 0x0);
+
+	dev_dbg(dev, "Registered clock '%s'\n", init.name);
+	return 0;
+}
+
+static const struct of_device_id hi6220_stub_clk_of_match[] = {
+	{ .compatible = "hisilicon,hi6220-stub-clk", },
+	{}
+};
+
+static struct platform_driver hi6220_stub_clk_driver = {
+	.driver	= {
+		.name = "hi6220-stub-clk",
+		.of_match_table = hi6220_stub_clk_of_match,
+	},
+	.probe = hi6220_stub_clk_probe,
+};
+
+static int __init hi6220_stub_clk_init(void)
+{
+	return platform_driver_register(&hi6220_stub_clk_driver);
+}
+subsys_initcall(hi6220_stub_clk_init);
-- 
1.9.1



From leo.yan at linaro.org  Tue Aug  4 00:27:29 2015
From: leo.yan at linaro.org (Leo Yan)
Date: Tue,  4 Aug 2015 15:27:29 +0800
Subject: [PATCH v4 4/4] arm64: dts: add Hi6220's stub clock node
In-Reply-To: <1438673249-6051-1-git-send-email-leo.yan@linaro.org>
References: <1438673249-6051-1-git-send-email-leo.yan@linaro.org>
Message-ID: <1438673249-6051-5-git-send-email-leo.yan@linaro.org>

Enable SRAM node and stub clock node for Hi6220; furthermore
add the CPU's clock so it will be used by cpufreq-dt driver.

Signed-off-by: Leo Yan <leo.yan at linaro.org>
---
 arch/arm64/boot/dts/hisilicon/hi6220.dtsi | 23 +++++++++++++++++++++++
 1 file changed, 23 insertions(+)

diff --git a/arch/arm64/boot/dts/hisilicon/hi6220.dtsi b/arch/arm64/boot/dts/hisilicon/hi6220.dtsi
index b42a9b7..94b8310 100644
--- a/arch/arm64/boot/dts/hisilicon/hi6220.dtsi
+++ b/arch/arm64/boot/dts/hisilicon/hi6220.dtsi
@@ -57,6 +57,17 @@
 			device_type = "cpu";
 			reg = <0x0 0x0>;
 			enable-method = "psci";
+			clocks = <&stub_clock 0>;
+			clock-latency = <0>;
+			operating-points = <
+				/* kHz */
+				1200000  0
+				960000   0
+				729000   0
+				432000   0
+				208000   0
+			>;
+			#cooling-cells = <2>; /* min followed by max */
 		};
 
 		cpu1: cpu at 1 {
@@ -136,6 +147,11 @@
 		#size-cells = <2>;
 		ranges;
 
+		sram: sram at fff80000 {
+			compatible = "hisilicon,hi6220-sramctrl", "syscon";
+			reg = <0x0 0xfff80000 0x0 0x12000>;
+		};
+
 		ao_ctrl: ao_ctrl at f7800000 {
 			compatible = "hisilicon,hi6220-aoctrl", "syscon";
 			reg = <0x0 0xf7800000 0x0 0x2000>;
@@ -160,6 +176,13 @@
 			#clock-cells = <1>;
 		};
 
+		stub_clock: stub_clock {
+			compatible = "hisilicon,hi6220-stub-clk";
+			hisilicon,hi6220-clk-sram = <&sram>;
+			#clock-cells = <1>;
+			mboxes = <&mailbox 1>;
+		};
+
 		uart0: uart at f8015000 {	/* console */
 			compatible = "arm,pl011", "arm,primecell";
 			reg = <0x0 0xf8015000 0x0 0x1000>;
-- 
1.9.1



From kgene at kernel.org  Tue Aug  4 00:28:21 2015
From: kgene at kernel.org (Kukjin Kim)
Date: Tue, 04 Aug 2015 16:28:21 +0900
Subject: [GIT PULL 1/5] Samsung non-critical-fixes for v4.3
Message-ID: <55C06995.2030600@kernel.org>

Hi Arnd, Olof, Kevin,

Here is Samsung non-critical-fixes for v4.3.
Please pull.

Thanks,
Kukjin

The following changes since commit d770e558e21961ad6cfdf0ff7df0eb5d7d4f0754:

  Linux 4.2-rc1 (2015-07-05 11:01:52 -0700)

are available in the git repository at:

  git://git.kernel.org/pub/scm/linux/kernel/git/kgene/linux-samsung.git
tags/samsung-non-critical-1

for you to fetch changes up to 2cc6b813579415c4f627b08a043079bdc5b87a33:

  ARM: EXYNOS: Use IOMEM_ERR_PTR when function returns iomem (2015-07-21
13:19:06 +0900)

----------------------------------------------------------------
Samsung non-critical fixes for v4.3

- fix sparse warning for returning iomem
- fix clock-frequency of display timing0 for exynos3250-rinato

----------------------------------------------------------------
Hyungwon Hwang (1):
      ARM: dts: fix clock-frequency of display timing0 for exynos3250-rinato

Krzysztof Kozlowski (1):
      ARM: EXYNOS: Use IOMEM_ERR_PTR when function returns iomem

 arch/arm/boot/dts/exynos3250-rinato.dts | 2 +-
 arch/arm/mach-exynos/platsmp.c          | 2 +-
 2 files changed, 2 insertions(+), 2 deletions(-)


From kgene at kernel.org  Tue Aug  4 00:28:47 2015
From: kgene at kernel.org (Kukjin Kim)
Date: Tue, 04 Aug 2015 16:28:47 +0900
Subject: [GIT PULL 2/5] Samsung cleanup for v4.3
Message-ID: <55C069AF.5050300@kernel.org>

Hi,

Please pull Samsung cleanup for v4.3.
Note I'm going to cleanup non-used definitions based on this soon.

Thanks,
Kukjin


The following changes since commit d770e558e21961ad6cfdf0ff7df0eb5d7d4f0754:

  Linux 4.2-rc1 (2015-07-05 11:01:52 -0700)

are available in the git repository at:

  git://git.kernel.org/pub/scm/linux/kernel/git/kgene/linux-samsung.git
tags/samsung-cleanup

for you to fetch changes up to d306d08f07183fe1504257101b25b5b33d77bae9:

  ARM: SAMSUNG: remove keypad-core header in plat-samsung (2015-07-30
02:02:06 +0900)

----------------------------------------------------------------
Samsung cleanup for v4.3

- make the following headers local
  watchdog-reset, onenand-core, irq-uart, backlight,
  ata-core, regs-usb-hsotg-phy, spi-core, nand-core,
  fb-core and regs-srom headers
- make the following c file local
  s5p-dev-mfc, dev-backlight and setup-camif c file
- remove keypad-core.h file
- drop owner assignment in pmu.c
- remove duplicated define of SLEEP_MAGIC
- make exynos5420_powerdown_conf() staic

----------------------------------------------------------------
Krzysztof Kozlowski (3):
      ARM: EXYNOS: Make local function static
      ARM: EXYNOS: Remove duplicated define of SLEEP_MAGIC
      ARM: EXYNOS: Drop owner assignment in pmu.c

Kukjin Kim (14):
      ARM: SAMSUNG: make local setup-camif in mach-s3c24xx
      ARM: SAMSUNG: make local dev-backlight in mach-s3c64xx
      ARM: SAMSUNG: make local s5p-dev-mfc in mach-exynos
      ARM: SAMSUNG: local regs-srom header in mach-exynos
      ARM: SAMSUNG: local fb-core header in mach-s3c24xx
      ARM: SAMSUNG: local nand-core header in mach-s3c24xx
      ARM: SAMSUNG: local spi-core header in mach-s3c24xx
      ARM: SAMSUNG: local regs-usb-hsotg-phy header in mach-s3c64xx
      ARM: SAMSUNG: local ata-core header in mach-s3c64xx
      ARM: SAMSUNG: local backlight header in mach-s3c64xx
      ARM: SAMSUNG: local irq-uart header in mach-s3c64xx
      ARM: SAMSUNG: local onenand-core header in mach-s3c64xx
      ARM: SAMSUNG: local watchdog-reset header in mach-s3c64xx
      ARM: SAMSUNG: remove keypad-core header in plat-samsung

 arch/arm/mach-exynos/Kconfig                       |  5 ++++
 arch/arm/mach-exynos/Makefile                      |  2 ++
 arch/arm/mach-exynos/common.h                      |  6 +++++
 arch/arm/mach-exynos/firmware.c                    |  2 --
 arch/arm/mach-exynos/pmu.c                         |  3 +--
 .../include/plat => mach-exynos}/regs-srom.h       |  3 +--
 .../{plat-samsung => mach-exynos}/s5p-dev-mfc.c    |  0
 arch/arm/mach-exynos/suspend.c                     |  8 +++---
 arch/arm/mach-s3c24xx/Kconfig                      |  5 ++++
 arch/arm/mach-s3c24xx/Makefile                     |  1 +
 .../include/plat => mach-s3c24xx}/fb-core.h        |  2 --
 .../include/plat => mach-s3c24xx}/nand-core.h      |  3 +--
 arch/arm/mach-s3c24xx/s3c2412.c                    |  2 +-
 arch/arm/mach-s3c24xx/s3c2416.c                    |  6 ++---
 arch/arm/mach-s3c24xx/s3c2443.c                    |  7 ++---
 arch/arm/mach-s3c24xx/s3c244x.c                    |  2 +-
 .../{plat-samsung => mach-s3c24xx}/setup-camif.c   |  0
 .../include/plat => mach-s3c24xx}/spi-core.h       |  0
 arch/arm/mach-s3c64xx/Kconfig                      |  6 +++++
 arch/arm/mach-s3c64xx/Makefile                     |  2 ++
 .../include/plat => mach-s3c64xx}/ata-core.h       |  3 +--
 .../include/plat => mach-s3c64xx}/backlight.h      |  3 +--
 arch/arm/mach-s3c64xx/common.c                     |  4 +--
 .../{plat-samsung => mach-s3c64xx}/dev-backlight.c |  6 ++---
 .../include/plat => mach-s3c64xx}/irq-uart.h       |  3 +--
 arch/arm/mach-s3c64xx/mach-s3c64xx-dt.c            |  3 +--
 arch/arm/mach-s3c64xx/mach-smdk6410.c              |  2 +-
 .../include/plat => mach-s3c64xx}/onenand-core.h   |  2 --
 .../plat => mach-s3c64xx}/regs-usb-hsotg-phy.h     |  3 +--
 arch/arm/mach-s3c64xx/s3c6400.c                    |  2 +-
 arch/arm/mach-s3c64xx/s3c6410.c                    |  4 +--
 arch/arm/mach-s3c64xx/setup-usb-phy.c              |  2 +-
 .../include/plat => mach-s3c64xx}/watchdog-reset.h |  3 +--
 arch/arm/plat-samsung/Kconfig                      | 17 ------------
 arch/arm/plat-samsung/Makefile                     |  5 ----
 arch/arm/plat-samsung/include/plat/keypad-core.h   | 31
----------------------
 36 files changed, 58 insertions(+), 100 deletions(-)
 rename arch/arm/{plat-samsung/include/plat => mach-exynos}/regs-srom.h
(96%)
 rename arch/arm/{plat-samsung => mach-exynos}/s5p-dev-mfc.c (100%)
 rename arch/arm/{plat-samsung/include/plat => mach-s3c24xx}/fb-core.h (93%)
 rename arch/arm/{plat-samsung/include/plat => mach-s3c24xx}/nand-core.h
(93%)
 rename arch/arm/{plat-samsung => mach-s3c24xx}/setup-camif.c (100%)
 rename arch/arm/{plat-samsung/include/plat => mach-s3c24xx}/spi-core.h
(100%)
 rename arch/arm/{plat-samsung/include/plat => mach-s3c64xx}/ata-core.h
(92%)
 rename arch/arm/{plat-samsung/include/plat => mach-s3c64xx}/backlight.h
(92%)
 rename arch/arm/{plat-samsung => mach-s3c64xx}/dev-backlight.c (98%)
 rename arch/arm/{plat-samsung/include/plat => mach-s3c64xx}/irq-uart.h
(90%)
 rename arch/arm/{plat-samsung/include/plat =>
mach-s3c64xx}/onenand-core.h (95%)
 rename arch/arm/{plat-samsung/include/plat =>
mach-s3c64xx}/regs-usb-hsotg-phy.h (96%)
 rename arch/arm/{plat-samsung/include/plat =>
mach-s3c64xx}/watchdog-reset.h (91%)
 delete mode 100644 arch/arm/plat-samsung/include/plat/keypad-core.h


From kgene at kernel.org  Tue Aug  4 00:29:06 2015
From: kgene at kernel.org (Kukjin Kim)
Date: Tue, 04 Aug 2015 16:29:06 +0900
Subject: [GIT PULL 3/5] Samsung DT updates for v4.3
Message-ID: <55C069C2.7040208@kernel.org>

Hi,

Please pull Samsung DT updates for v4.3.

Thanks,
Kukjin


The following changes since commit d770e558e21961ad6cfdf0ff7df0eb5d7d4f0754:

  Linux 4.2-rc1 (2015-07-05 11:01:52 -0700)

are available in the git repository at:

  git://git.kernel.org/pub/scm/linux/kernel/git/kgene/linux-samsung.git
tags/samsung-dt-1

for you to fetch changes up to 5e080b078fa1f929d9aa5586985d5e7c0739d207:

  ARM: dts: Extend exynos5420-pinctrl nodes using labels instead of
paths (2015-07-21 13:01:23 +0900)

----------------------------------------------------------------
Samsung 1st DT updates for v4.3

- for exynos3250
  : update video-phy node with syscon phandle
- for exynos4210
  : add CPU OPP and regulator supply property
  : use labels for overriding nodes for exynos4210-universal_c210
- for exynos4412-trats2
  : set max17047 over heat and voltage thresholds
- for exynos5250 and 5420
  : extend exynos5250/5420-pinctrl nodes using labels
  : include exynos5250/5420-pinctrl after the nodes definitions
- for exynos5410-smdk5410
  : clean up indentation
- for exynos5422-odroidxu3
  : define default thermal-zones for exynos5422
  : enable USB3 regulators, TMU and thermal-zones
  : add pwm-fan node

----------------------------------------------------------------
Anand Moon (5):
      ARM: dts: Enable USB3 regulators for exynos5422-odroidxu3
      ARM: dts: Add pwm-fan node for exynos5422-odroidxu3
      ARM: dts: Enable TMU for exynos5422-odroidxu3
      ARM: dts: Define default thermal-zones for exynos5422
      ARM: dts: Enable thermal-zones for exynos5422-odroidxu3

Andreas Faerber (1):
      ARM: dts: Clean up indentation for exynos5410-smdk5410

Beata Michalska (1):
      ARM: dts: Update video-phy node with syscon phandle for exynos3250

Javier Martinez Canillas (4):
      ARM: dts: Include exynos5250-pinctrl after the nodes were defined
for exynos5250
      ARM: dts: Extend exynos5250-pinctrl nodes using labels instead of
paths
      ARM: dts: Include exynos5420-pinctrl after the nodes were defined
for exynos5420
      ARM: dts: Extend exynos5420-pinctrl nodes using labels instead of
paths

Krzysztof Kozlowski (2):
      ARM: dts: Set max17047 over heat and voltage thresholds for
exynos4412-trats2
      ARM: dts: Use labels for overriding nodes for
exynos4210-universal_c210

Thomas Abraham (1):
      ARM: dts: add CPU OPP and regulator supply property for exynos4210

 arch/arm/boot/dts/exynos3250.dtsi                  |    2 +-
 arch/arm/boot/dts/exynos4210-origen.dts            |    4 +
 arch/arm/boot/dts/exynos4210-trats.dts             |    4 +
 arch/arm/boot/dts/exynos4210-universal_c210.dts    |  618 ++++----
 arch/arm/boot/dts/exynos4210.dtsi                  |   12 +
 arch/arm/boot/dts/exynos4412-trats2.dts            |    3 +
 arch/arm/boot/dts/exynos5250-pinctrl.dtsi          | 1600
++++++++++----------
 arch/arm/boot/dts/exynos5250.dtsi                  |    3 +-
 arch/arm/boot/dts/exynos5410-smdk5410.dts          |    6 +-
 arch/arm/boot/dts/exynos5420-pinctrl.dtsi          | 1411 +++++++++--------
 arch/arm/boot/dts/exynos5420.dtsi                  |    3 +-
 arch/arm/boot/dts/exynos5422-cpu-thermal.dtsi      |   59 +
 arch/arm/boot/dts/exynos5422-odroidxu3-common.dtsi |   46 +
 13 files changed, 1951 insertions(+), 1820 deletions(-)
 create mode 100644 arch/arm/boot/dts/exynos5422-cpu-thermal.dtsi


From kgene at kernel.org  Tue Aug  4 00:29:25 2015
From: kgene at kernel.org (Kukjin Kim)
Date: Tue, 04 Aug 2015 16:29:25 +0900
Subject: [GIT PULL 4/5] Samsung 2nd DT updates for v4.3
Message-ID: <55C069D5.1050409@kernel.org>

Hi Arnd, Olof, Kevin

This 2nd DT update branch is based tags/samsung-dt-1 +
v4.3-topic/clk-samsung branch because of dependency to support generic
cpufreq driver. Please pull.

Thanks,
Kukjin


The following changes since commit e4a39d904c3c3e4855287b7325306289ff044b06:

  Merge branch 'v4.3-topic/clk-samsung' into v4.3-next/dt-samsung-2
(2015-07-24 12:54:00 +0900)

are available in the git repository at:


  git://git.kernel.org/pub/scm/linux/kernel/git/kgene/linux-samsung.git
tags/samsung-dt-2

for you to fetch changes up to 71ae9acc2e3b4b85a08c65e7f411d110b786ca1d:

  ARM: dts: Add SPI CS on exynos5250-snow (2015-07-30 23:12:43 +0900)

----------------------------------------------------------------
Samsung 2nd DT updates for v4.3

- for exynos3250 and 5250
  : add CPU OPP and regulator supply property
    (note depends on v4.3-topic/clk-samsung)
- for exynos3250
  : add CPU cooling binding for exynos3250 boards
- for exynos5250-snow
  : add SPI CS
- for exynos5422
  : add exynos5422-cpus.dtsi to correct cpu order

----------------------------------------------------------------
Chanho Park (1):
      ARM: dts: add exynos5422-cpus.dtsi to correct cpu order

Chanwoo Choi (2):
      ARM: dts: Add CPU OPP and regulator supply property for exynos3250
      ARM: dts: Add CPU cooling binding for exynos3250 boards

Michal Suchanek (1):
      ARM: dts: Add SPI CS on exynos5250-snow

Thomas Abraham (1):
      ARM: dts: add CPU OPP and regulator supply property for exynos5250

 arch/arm/boot/dts/exynos3250-monk.dts              | 19 +++++
 arch/arm/boot/dts/exynos3250-rinato.dts            | 19 +++++
 arch/arm/boot/dts/exynos3250.dtsi                  | 16 +++++
 arch/arm/boot/dts/exynos5250-arndale.dts           |  4 ++
 arch/arm/boot/dts/exynos5250-smdk5250.dts          |  4 ++
 arch/arm/boot/dts/exynos5250-snow.dts              |  5 ++
 arch/arm/boot/dts/exynos5250-spring.dts            |  4 ++
 arch/arm/boot/dts/exynos5250.dtsi                  | 22 ++++++
 arch/arm/boot/dts/exynos5422-cpus.dtsi             | 81
++++++++++++++++++++++
 arch/arm/boot/dts/exynos5422-odroidxu3-common.dtsi |  1 +
 10 files changed, 175 insertions(+)
 create mode 100644 arch/arm/boot/dts/exynos5422-cpus.dtsi


From kgene at kernel.org  Tue Aug  4 00:30:18 2015
From: kgene at kernel.org (Kukjin Kim)
Date: Tue, 04 Aug 2015 16:30:18 +0900
Subject: [GIT PULL 5/5] Samsung driver updates for v4.3
Message-ID: <55C06A0A.6040407@kernel.org>

Hi,

This branch is including to support generic cpufreq driver in
mach-exynos dir. for exynos3250 and exynos5250 even the tag name is
driver. Because it is depending on clk and cpufreq changes which acked
by regarding maintainers, Mike and Viresh.

Please pull and if any problems, please kindly let me know.

Thanks,
Kukjin

The following changes since commit 995008abdf5146feb0ffdeb15ddb0e90010aff50:

  Merge branch 'v4.3-next/dt-samsung-2' into
v4.3-next/clk-cpufreq-samsung (2015-08-04 15:59:14 +0900)

are available in the git repository at:


  git://git.kernel.org/pub/scm/linux/kernel/git/kgene/linux-samsung.git
tags/samsung-driver

for you to fetch changes up to 6b1621c4a15b9110cda7cc2e2eb3e8e1a0c2bcfc:

  ARM: EXYNOS: Add exynos3250 compatible to use generic cpufreq driver
(2015-08-04 15:59:33 +0900)

----------------------------------------------------------------
Samsung mach-exynos and driver updates for v4.3

- Use generic cpufreq driver for exynos3250 and exynos5250
  : note depends on the following
    v4.3-topic/clk-samsung (acked by clk maintainer, Mike)
    v4.3-topic/cpufreq-samsung (acked by cpufreq maintainer, Viresh)
    v4.3-next/dt-samsung-2 (add CPU OPP and regulator supply)

----------------------------------------------------------------
Chanwoo Choi (1):
      ARM: EXYNOS: Add exynos3250 compatible to use generic cpufreq driver

Thomas Abraham (1):
      ARM: EXYNOS: switch to using generic cpufreq driver for exynos5250

 arch/arm/mach-exynos/exynos.c | 2 ++
 1 file changed, 2 insertions(+)


From p.fedin at samsung.com  Tue Aug  4 00:35:59 2015
From: p.fedin at samsung.com (Pavel Fedin)
Date: Tue, 04 Aug 2015 10:35:59 +0300
Subject: [PATCH v3 1/2] PCI: generic: remove dependency on hw_pci
In-Reply-To: <1438183681-30519-1-git-send-email-jchandra@broadcom.com>
References: <1438183681-30519-1-git-send-email-jchandra@broadcom.com>
Message-ID: <00b601d0ce88$35b2f8a0$a118e9e0$@samsung.com>

 Hello!

> Notes:
>  - passing a zeroed out pci_sys_data for ARM looks ok, but I haven't
>    tested it on ARM.
>  - tested it on ARM64 fast model
>  - Any information on how this can be tested on arm is welcome.

 I have tested it on SMDK5410, works OK. By the way, PCI generic is missing MSI support, i had to
add it. I can share the patch if interested, it's very small.

Tested-by: Pavel Fedin <p.fedin at samsung.com>

Kind regards,
Pavel Fedin
Expert Engineer
Samsung Electronics Research center Russia




From k.kozlowski at samsung.com  Tue Aug  4 00:39:25 2015
From: k.kozlowski at samsung.com (Krzysztof Kozlowski)
Date: Tue, 04 Aug 2015 16:39:25 +0900
Subject: [GIT PULL 1/5] Samsung non-critical-fixes for v4.3
In-Reply-To: <55C06995.2030600@kernel.org>
References: <55C06995.2030600@kernel.org>
Message-ID: <55C06C2D.2010804@samsung.com>

On 04.08.2015 16:28, Kukjin Kim wrote:
> Hi Arnd, Olof, Kevin,
> 
> Here is Samsung non-critical-fixes for v4.3.
> Please pull.
> 
> Thanks,
> Kukjin
> 
> The following changes since commit d770e558e21961ad6cfdf0ff7df0eb5d7d4f0754:
> 
>   Linux 4.2-rc1 (2015-07-05 11:01:52 -0700)
> 
> are available in the git repository at:
> 
>   git://git.kernel.org/pub/scm/linux/kernel/git/kgene/linux-samsung.git
> tags/samsung-non-critical-1
> 
> for you to fetch changes up to 2cc6b813579415c4f627b08a043079bdc5b87a33:
> 
>   ARM: EXYNOS: Use IOMEM_ERR_PTR when function returns iomem (2015-07-21
> 13:19:06 +0900)
> 
> ----------------------------------------------------------------
> Samsung non-critical fixes for v4.3
> 
> - fix sparse warning for returning iomem
> - fix clock-frequency of display timing0 for exynos3250-rinato

One more set, which we agreed for pushing to v4.2, is missing:
1. cpufreq: exynos: Fix for memory leak in case SOC name does not match
2. video: fbdev: s3c-fb: Constify platform_device_id (this can actually
go for v4.3... but it's not here...)

Do you plan to send pull request with them?

Best regards,
Krzysztof



From takahiro.akashi at linaro.org  Tue Aug  4 00:41:55 2015
From: takahiro.akashi at linaro.org (AKASHI Takahiro)
Date: Tue, 04 Aug 2015 16:41:55 +0900
Subject: [RFC 2/3] arm64: refactor save_stack_trace()
In-Reply-To: <20150803133220.46db9839@gandalf.local.home>
References: <12F47692-3010-4886-B87D-3D7820609177@gmail.com>	<20150716113115.45a17f17@gandalf.local.home>	<20150716121658.7982fdf5@gandalf.local.home>	<20150717124054.GE26091@leverpostej>	<20150717090009.720f6bd0@gandalf.local.home>	<77EA0F10-D5F6-48BD-8652-3B979A978659@gmail.com>	<20150717104144.6588b2f7@gandalf.local.home>	<0886A996-40E1-49E9-823C-85E55A858716@gmail.com>	<1357EA74-B972-4B99-ADB0-BC7E8F06DDB5@gmail.com>	<20150720162004.GL9908@arm.com>	<20150803090951.GA10501@arm.com>	<D7BD8A9F-8710-42D5-A0ED-8747D2B6B268@gmail.com>	<20150803125711.65463359@gandalf.local.home>	<24AFDCDB-55DE-4A23-A26A-750B48AC365C@gmail.com>
 <20150803133220.46db9839@gandalf.local.home>
Message-ID: <55C06CC3.5090603@linaro.org>

On 08/04/2015 02:32 AM, Steven Rostedt wrote:
> On Tue, 4 Aug 2015 02:22:16 +0900
> Jungseok Lee <jungseoklee85 at gmail.com> wrote:
>
>
>> It would be better to add the snippet when a new version is ready.
>> That way might help to figure out easily why the macro is introduced and how
>> it can be used in architecture code.
>
>
> OK, which ever.

I'm making best efforts to fix the problem, but it seems to me that the current
check_stack() doesn't fit to arm64 due to the differences in stack frame usage
on architectures.
Although my current patch doesn't solve all the issues I've noticed so far,
I'd like to get any comments about whether I'm doing it the right way.
Please take a look at my new vesion (v2) of RFC.

Thanks,
-Takahiro AKASHI


> -- Steve
>


From takahiro.akashi at linaro.org  Tue Aug  4 00:44:05 2015
From: takahiro.akashi at linaro.org (AKASHI Takahiro)
Date: Tue,  4 Aug 2015 16:44:05 +0900
Subject: [RFC v2 0/4] arm64: ftrace: fix incorrect output from stack tracer
Message-ID: <1438674249-3447-1-git-send-email-takahiro.akashi@linaro.org>

See the following threads [1],[2] for the background.

With this patch series, I'm trying to fix several problems I noticed
with stack tracer on arm64. But it is rather experimental, and there still
remained are several issues. 

Patch #1 modifies ftrace framework so that we can provide arm64-specific
stack tracer later.
(Well, I know there is some room for further refactoring, but this is
just a prototype code.)
Patch #2 implements this arch_check_stack() using unwind_stackframe() to
traverse stack frames and identify a stack index for each traced function.
Patch #3 addresses an issue that stack tracer doesn't work well in
conjuction with function graph tracer.
Patch #4 addresses an issue that unwind_stackframe() misses a function
that is the one when an exception happens by setting up a stack frame
for exception handler.

See below for the result with those patches.
Issues include:
a) Size of gic_handle_irq() is 48 (#13), but should be 64.
b) We cannot identify a location of function which is being returned
   and hooked temporarily by return_to_handler() (#18)
c) A meaningless entry (#62) as well as a bogus size for the first
   function, el0_svc (#61)
d) Size doesn't contain a function's "dynamically allocated local
   variables," if any, but instead is sumed up in child's size.
   (See details in [3].)

I'm afraid that we cannot fix issue b) unless we can do *atomically*
push/pop a return adress in current->ret_stack[], increment/decrement
current->curr_ret_stack and restore lr register.

We will be able to fix issue d) once we know all the locations in
the list, including b).

[1] http://lists.infradead.org/pipermail/linux-arm-kernel/2015-July/354126.html
[2] http://lists.infradead.org/pipermail/linux-arm-kernel/2015-July/355920.html
[3] http://lists.infradead.org/pipermail/linux-arm-kernel/2015-July/358034.html


=== stack tracer with function graph tracer
# cat /sys/kernel/debug/tracing/stack_max_size /sys/kernel/debug/tracing/stack_t
race
5376
        Depth    Size   Location    (63 entries)
        -----    ----   --------
  0)     5376      64   notifier_call_chain+0x2c/0x94
  1)     5312      48   raw_notifier_call_chain+0x34/0x44
  2)     5264      64   timekeeping_update+0xe4/0x150
  3)     5200     128   update_wall_time+0x400/0x6e4
  4)     5072      80   tick_do_update_jiffies64+0xd8/0x154
  5)     4992      32   tick_sched_do_timer+0x50/0x60
  6)     4960      48   tick_sched_timer+0x34/0x90
  7)     4912     112   __hrtimer_run_queues+0xbc/0x278
  8)     4800     112   hrtimer_interrupt+0xa0/0x214
  9)     4688      32   arch_timer_handler_phys+0x38/0x48
 10)     4656      64   handle_percpu_devid_irq+0x84/0x188
 11)     4592      32   generic_handle_irq+0x38/0x54
 12)     4560      64   __handle_domain_irq+0x68/0xbc
 13)     4496      48   gic_handle_irq+0x38/0x88
 14)     4448     288   el1_irq+0x68/0xdc
 15)     4160      64   sched_clock+0x38/0x88
 16)     4096      32   trace_clock_local+0x1c/0x54
 17)     4064      96   ftrace_return_to_handler+0x64/0x120
 18)     3968      80             (null)
 19)     3888      96   xprt_complete_rqst+0xfc/0x1b0
 20)     3792      48   xs_udp_data_ready+0x168/0x170
 21)     3744      48   sock_queue_rcv_skb+0x1fc/0x270
 22)     3696      48   __udp_queue_rcv_skb+0x58/0x19c
 23)     3648      96   udp_queue_rcv_skb+0x258/0x3e4
 24)     3552      32   __udp4_lib_rcv+0x424/0x684
 25)     3520      48   udp_rcv+0x2c/0x3c
 26)     3472      64   ip_local_deliver+0xa4/0x224
 27)     3408     128   ip_rcv+0x360/0x580
 28)     3280      32   __netif_receive_skb_core+0x4d0/0x80c
 29)     3248      80   __netif_receive_skb+0x24/0x84
 30)     3168     160   process_backlog+0x9c/0x15c
 31)     3008     128   net_rx_action+0x1ec/0x32c
 32)     2880      32   __do_softirq+0x10c/0x2e8
 33)     2848      32   do_softirq+0x60/0x68
 34)     2816      96   __local_bh_enable_ip+0xb0/0xd4
 35)     2720      64   ip_finish_output2+0x1b8/0x4b8
 36)     2656      64   ip_finish_output+0x124/0x1cc
 37)     2592      32   ip_output+0xf0/0x120
 38)     2560      48   ip_local_out_sk+0x40/0x50
 39)     2512      80   ip_send_skb+0x24/0xbc
 40)     2432     272   udp_send_skb+0xfc/0x2f4
 41)     2160      48   udp_sendmsg+0x2a8/0x7a0
 42)     2112      32   inet_sendmsg+0xa0/0xd0
 43)     2080      64   sock_sendmsg+0x30/0x78
 44)     2016     176   kernel_sendmsg+0x48/0x58
 45)     1840     112   xs_send_kvec+0xdc/0xec
 46)     1728      64   xs_sendpages+0x88/0x254
 47)     1664      64   xs_udp_send_request+0x4c/0xf0
 48)     1600      48   xprt_transmit+0x54/0x264
 49)     1552     112   call_transmit+0x168/0x200
 50)     1440      48   __rpc_execute+0x68/0x37c
 51)     1392      32   rpc_execute+0x6c/0xec
 52)     1360     112   rpc_run_task+0x90/0xb4
 53)     1248      80   rpc_call_sync+0x60/0xdc
 54)     1168      48   nfs_proc_getattr+0x54/0x64
 55)     1120      96   __nfs_revalidate_inode+0xd0/0x25c
 56)     1024      80   nfs_lookup_revalidate+0x468/0x4a0
 57)      944     192   lookup_dcache+0x74/0xc8
 58)      752     272   path_openat+0x3f4/0xe8c
 59)      480     112   do_filp_open+0x70/0xec
 60)      368      64   SyS_openat+0x38/0x48
 61)      304   -7600   el0_svc_naked+0x20/0x28
 62)     7904    7904   0x471e04

AKASHI Takahiro (4):
  ftrace: allow arch-specific check_stack()
  arm64: ftrace: add arch-specific stack tracer
  arm64: ftrace: fix a stack trace result under function graph tracer
  arm64: ftrace: add a stack frame for exception handler

 arch/arm64/include/asm/ftrace.h |    2 +
 arch/arm64/kernel/entry.S       |    4 ++
 arch/arm64/kernel/ftrace.c      |   37 +++++++++++++++
 arch/arm64/kernel/stacktrace.c  |   97 ++++++++++++++++++++++++++++++++++++++-
 include/linux/stacktrace.h      |    4 ++
 kernel/trace/trace_stack.c      |   88 ++++++++++++++++++++---------------
 6 files changed, 194 insertions(+), 38 deletions(-)

-- 
1.7.9.5



From takahiro.akashi at linaro.org  Tue Aug  4 00:44:06 2015
From: takahiro.akashi at linaro.org (AKASHI Takahiro)
Date: Tue,  4 Aug 2015 16:44:06 +0900
Subject: [RFC v2 1/4] ftrace: allow arch-specific check_stack()
In-Reply-To: <1438674249-3447-1-git-send-email-takahiro.akashi@linaro.org>
References: <1438674249-3447-1-git-send-email-takahiro.akashi@linaro.org>
Message-ID: <1438674249-3447-2-git-send-email-takahiro.akashi@linaro.org>

A stack frame pointer may be used in a different way depending on
cpu architecture. Thus it is not always appropriate to slurp the stack
contents, as currently done in check_stack(), in order to calcurate
a stack index (height) at a given function call. At least not on arm64.

This patch extract potentially arch-specific code from check_stack()
and puts it into a new arch_check_stack(), which is declared as weak.
So we will be able to add arch-specific and most efficient way of
stack traversing Later.

Signed-off-by: AKASHI Takahiro <takahiro.akashi at linaro.org>
---
 include/linux/stacktrace.h |    4 ++
 kernel/trace/trace_stack.c |   88 ++++++++++++++++++++++++++------------------
 2 files changed, 56 insertions(+), 36 deletions(-)

diff --git a/include/linux/stacktrace.h b/include/linux/stacktrace.h
index 0a34489..bfae605 100644
--- a/include/linux/stacktrace.h
+++ b/include/linux/stacktrace.h
@@ -10,6 +10,10 @@ struct pt_regs;
 struct stack_trace {
 	unsigned int nr_entries, max_entries;
 	unsigned long *entries;
+#ifdef CONFIG_STACK_TRACER
+	unsigned *index;
+	unsigned long *sp;
+#endif
 	int skip;	/* input argument: How many entries to skip */
 };
 
diff --git a/kernel/trace/trace_stack.c b/kernel/trace/trace_stack.c
index 3d9356b..021b8c3 100644
--- a/kernel/trace/trace_stack.c
+++ b/kernel/trace/trace_stack.c
@@ -27,9 +27,10 @@ static unsigned stack_dump_index[STACK_TRACE_ENTRIES];
  * us to remove most or all of the stack size overhead
  * added by the stack tracer itself.
  */
-static struct stack_trace max_stack_trace = {
+	struct stack_trace max_stack_trace = {
 	.max_entries		= STACK_TRACE_ENTRIES - 1,
 	.entries		= &stack_dump_trace[0],
+	.index			= &stack_dump_index[0],
 };
 
 static unsigned long max_stack_size;
@@ -65,42 +66,15 @@ static inline void print_max_stack(void)
 	}
 }
 
-static inline void
-check_stack(unsigned long ip, unsigned long *stack)
+void __weak
+arch_check_stack(unsigned long ip, unsigned long *stack,
+			unsigned long *max_size, unsigned int *tracer_size)
 {
-	unsigned long this_size, flags; unsigned long *p, *top, *start;
-	static int tracer_frame;
-	int frame_size = ACCESS_ONCE(tracer_frame);
+	unsigned long *p, *top, *start;
+	unsigned long this_size;
 	int i, x;
 
-	this_size = ((unsigned long)stack) & (THREAD_SIZE-1);
-	this_size = THREAD_SIZE - this_size;
-	/* Remove the frame of the tracer */
-	this_size -= frame_size;
-
-	if (this_size <= max_stack_size)
-		return;
-
-	/* we do not handle interrupt stacks yet */
-	if (!object_is_on_stack(stack))
-		return;
-
-	local_irq_save(flags);
-	arch_spin_lock(&max_stack_lock);
-
-	/* In case another CPU set the tracer_frame on us */
-	if (unlikely(!frame_size))
-		this_size -= tracer_frame;
-
-	/* a race could have already updated it */
-	if (this_size <= max_stack_size)
-		goto out;
-
-	max_stack_size = this_size;
-
-	max_stack_trace.nr_entries = 0;
 	max_stack_trace.skip = 3;
-
 	save_stack_trace(&max_stack_trace);
 
 	/* Skip over the overhead of the stack tracer itself */
@@ -116,6 +90,7 @@ check_stack(unsigned long ip, unsigned long *stack)
 	start = stack;
 	top = (unsigned long *)
 		(((unsigned long)start & ~(THREAD_SIZE-1)) + THREAD_SIZE);
+	this_size = *max_size;
 
 	/*
 	 * Loop through all the entries. One of the entries may
@@ -146,10 +121,10 @@ check_stack(unsigned long ip, unsigned long *stack)
 				 * out what that is, then figure it out
 				 * now.
 				 */
-				if (unlikely(!tracer_frame)) {
-					tracer_frame = (p - stack) *
+				if (unlikely(!*tracer_size)) {
+					*tracer_size = (p - stack) *
 						sizeof(unsigned long);
-					max_stack_size -= tracer_frame;
+					*max_size -= *tracer_size;
 				}
 			}
 		}
@@ -161,6 +136,47 @@ check_stack(unsigned long ip, unsigned long *stack)
 	max_stack_trace.nr_entries = x;
 	for (; x < i; x++)
 		stack_dump_trace[x] = ULONG_MAX;
+}
+
+static inline void
+check_stack(unsigned long ip, unsigned long *stack)
+{
+	unsigned long this_size, flags;
+	static int tracer_frame;
+	int frame_size = ACCESS_ONCE(tracer_frame);
+
+	this_size = ((unsigned long)stack) & (THREAD_SIZE-1);
+	this_size = THREAD_SIZE - this_size;
+	/* for safety, depending on arch_check_stack() */
+	if (this_size < frame_size)
+		return;
+
+	/* Remove the frame of the tracer */
+	this_size -= frame_size;
+
+	if (this_size <= max_stack_size)
+		return;
+
+	/* we do not handle interrupt stacks yet */
+	if (!object_is_on_stack(stack))
+		return;
+
+	local_irq_save(flags);
+	arch_spin_lock(&max_stack_lock);
+
+	/* In case another CPU set the tracer_frame on us */
+	if (unlikely(!frame_size))
+		this_size -= tracer_frame;
+
+	/* a race could have already updated it */
+	if (this_size <= max_stack_size)
+		goto out;
+
+	max_stack_size = this_size;
+
+	max_stack_trace.nr_entries = 0;
+
+	arch_check_stack(ip, stack, &max_stack_size, &tracer_frame);
 
 	if (task_stack_end_corrupted(current)) {
 		print_max_stack();
-- 
1.7.9.5



From takahiro.akashi at linaro.org  Tue Aug  4 00:44:07 2015
From: takahiro.akashi at linaro.org (AKASHI Takahiro)
Date: Tue,  4 Aug 2015 16:44:07 +0900
Subject: [RFC v2 2/4] arm64: ftrace: add arch-specific stack tracer
In-Reply-To: <1438674249-3447-1-git-send-email-takahiro.akashi@linaro.org>
References: <1438674249-3447-1-git-send-email-takahiro.akashi@linaro.org>
Message-ID: <1438674249-3447-3-git-send-email-takahiro.akashi@linaro.org>

This patch uses walk_stackframe(), instead of slurping stack contents
as orignal check_stack() does, to identify each stack frame.
return_to_handler() is handled in a special way because it is not
a function, but invoked via function graph tracer by faking a saved lr
register on stack.

Signed-off-by: AKASHI Takahiro <takahiro.akashi at linaro.org>
---
 arch/arm64/include/asm/ftrace.h |    2 ++
 arch/arm64/kernel/ftrace.c      |   37 +++++++++++++++++++++++++
 arch/arm64/kernel/stacktrace.c  |   58 +++++++++++++++++++++++++++++++++++++--
 3 files changed, 95 insertions(+), 2 deletions(-)

diff --git a/arch/arm64/include/asm/ftrace.h b/arch/arm64/include/asm/ftrace.h
index 2b43e20..b7d597c 100644
--- a/arch/arm64/include/asm/ftrace.h
+++ b/arch/arm64/include/asm/ftrace.h
@@ -29,6 +29,8 @@ struct dyn_arch_ftrace {
 
 extern unsigned long ftrace_graph_call;
 
+extern void return_to_handler(void);
+
 static inline unsigned long ftrace_call_adjust(unsigned long addr)
 {
 	/*
diff --git a/arch/arm64/kernel/ftrace.c b/arch/arm64/kernel/ftrace.c
index c851be7..d812870 100644
--- a/arch/arm64/kernel/ftrace.c
+++ b/arch/arm64/kernel/ftrace.c
@@ -176,3 +176,40 @@ int ftrace_disable_ftrace_graph_caller(void)
 }
 #endif /* CONFIG_DYNAMIC_FTRACE */
 #endif /* CONFIG_FUNCTION_GRAPH_TRACER */
+
+#ifdef CONFIG_STACK_TRACER
+#define stack_top(fp) (((fp) & ~(THREAD_SIZE-1)) + THREAD_SIZE)
+#define stack_index(fp) (stack_top((fp)) - (fp))
+
+extern struct stack_trace max_stack_trace;
+extern void save_stack_trace_index(struct stack_trace *trace);
+
+void arch_check_stack(unsigned long ip, unsigned long *stack,
+		      unsigned long *max_size, int *tracer_size)
+{
+	int i, j;
+
+	max_stack_trace.skip = 0;
+	save_stack_trace_index(&max_stack_trace);
+	max_stack_trace.nr_entries--; /* for '-1' entry */
+
+	/* Skip over the overhead of the stack tracer itself */
+	for (i = 0; i < max_stack_trace.nr_entries; i++) {
+		if ((max_stack_trace.entries[i] + FTRACE_STACK_FRAME_OFFSET)
+				== ip)
+			break;
+	}
+
+	if (unlikely(!*tracer_size)) {
+		*tracer_size = stack_index((unsigned long)stack)
+			- max_stack_trace.index[i];
+		*max_size -= *tracer_size;
+	}
+
+	max_stack_trace.nr_entries -= i;
+	for (j = 0; j < max_stack_trace.nr_entries; j++) {
+		max_stack_trace.index[j] = max_stack_trace.index[j + i];
+		max_stack_trace.entries[j] = max_stack_trace.entries[j + i];
+	}
+}
+#endif /* CONFIG_STACK_TRACER */
diff --git a/arch/arm64/kernel/stacktrace.c b/arch/arm64/kernel/stacktrace.c
index bc0689a..496ab0f 100644
--- a/arch/arm64/kernel/stacktrace.c
+++ b/arch/arm64/kernel/stacktrace.c
@@ -17,12 +17,15 @@
  */
 #include <linux/kernel.h>
 #include <linux/export.h>
+#include <linux/ftrace.h>
 #include <linux/sched.h>
 #include <linux/stacktrace.h>
 
 #include <asm/insn.h>
 #include <asm/stacktrace.h>
 
+#define S_FRAME_SIZE sizeof(struct pt_regs) /* asm-offsets.h */
+
 /*
  * AArch64 PCS assigns the frame pointer to x29.
  *
@@ -78,9 +81,29 @@ struct stack_trace_data {
 	struct stack_trace *trace;
 	unsigned int no_sched_functions;
 	unsigned int skip;
+#ifdef CONFIG_STACK_TRACER
+	int ftracer;
+	int ret_stack_index;
+#endif
 };
 
-static int save_trace(struct stackframe *frame, void *d)
+#ifdef CONFIG_STACK_TRACER
+static void notrace arm64_stack_index(struct stackframe *frame,
+		struct stack_trace_data *data)
+{
+	struct stack_trace *trace = data->trace;
+	unsigned long top;
+	unsigned int x = trace->nr_entries;
+
+	top = (frame->fp & ~(THREAD_SIZE-1)) + THREAD_SIZE;
+	trace->index[x] = top - frame->fp;
+	/* should not go beyond this frame */
+	if (trace->index[x] == THREAD_SIZE)
+		trace->index[x] = 0;
+}
+#endif /* CONFIG_STACK_TRACER */
+
+static int notrace save_trace(struct stackframe *frame, void *d)
 {
 	struct stack_trace_data *data = d;
 	struct stack_trace *trace = data->trace;
@@ -93,7 +116,13 @@ static int save_trace(struct stackframe *frame, void *d)
 		return 0;
 	}
 
-	trace->entries[trace->nr_entries++] = addr;
+	trace->entries[trace->nr_entries] = addr;
+#ifdef CONFIG_STACK_TRACER
+	if (data->ftracer) {
+		arm64_stack_index(frame, data);
+	}
+#endif
+	trace->nr_entries++;
 
 	return trace->nr_entries >= trace->max_entries;
 }
@@ -105,6 +134,9 @@ void save_stack_trace_tsk(struct task_struct *tsk, struct stack_trace *trace)
 
 	data.trace = trace;
 	data.skip = trace->skip;
+#ifdef CONFIG_STACK_TRACER
+	data.ftracer = 0;
+#endif
 
 	if (tsk != current) {
 		data.no_sched_functions = 1;
@@ -128,4 +160,26 @@ void save_stack_trace(struct stack_trace *trace)
 	save_stack_trace_tsk(current, trace);
 }
 EXPORT_SYMBOL_GPL(save_stack_trace);
+
+#ifdef CONFIG_STACK_TRACER
+void notrace save_stack_trace_index(struct stack_trace *trace)
+{
+	struct stack_trace_data data;
+	struct stackframe frame;
+
+	data.trace = trace;
+	data.skip = trace->skip;
+	data.ftracer = 1;
+	data.ret_stack_index = current->curr_ret_stack;
+
+	data.no_sched_functions = 0;
+	frame.fp = (unsigned long)__builtin_frame_address(0);
+	frame.sp = current_stack_pointer;
+	frame.pc = (unsigned long)save_stack_trace_index;
+
+	walk_stackframe(&frame, save_trace, &data);
+	if (trace->nr_entries < trace->max_entries)
+		trace->entries[trace->nr_entries++] = ULONG_MAX;
+}
+#endif /* CONFIG_STACK_TRACER */
 #endif
-- 
1.7.9.5



From takahiro.akashi at linaro.org  Tue Aug  4 00:44:08 2015
From: takahiro.akashi at linaro.org (AKASHI Takahiro)
Date: Tue,  4 Aug 2015 16:44:08 +0900
Subject: [RFC v2 3/4] arm64: ftrace: fix a stack trace result under function
 graph tracer
In-Reply-To: <1438674249-3447-1-git-send-email-takahiro.akashi@linaro.org>
References: <1438674249-3447-1-git-send-email-takahiro.akashi@linaro.org>
Message-ID: <1438674249-3447-4-git-send-email-takahiro.akashi@linaro.org>

Function graph tracer modifies a saved lr register on stack in order
to hook a function return. This results in finding many bogus entries
in a stack trace list.

This patch replaces such entries with originals values stored in
current->ret_stack[].

Signed-off-by: AKASHI Takahiro <takahiro.akashi at linaro.org>
---
 arch/arm64/kernel/stacktrace.c |   22 ++++++++++++++++++++++
 1 file changed, 22 insertions(+)

diff --git a/arch/arm64/kernel/stacktrace.c b/arch/arm64/kernel/stacktrace.c
index 496ab0f..d1790eb 100644
--- a/arch/arm64/kernel/stacktrace.c
+++ b/arch/arm64/kernel/stacktrace.c
@@ -100,6 +100,28 @@ static void notrace arm64_stack_index(struct stackframe *frame,
 	/* should not go beyond this frame */
 	if (trace->index[x] == THREAD_SIZE)
 		trace->index[x] = 0;
+
+	if (trace->entries[x] ==
+			((unsigned long)return_to_handler + 0x8)) {
+		/*
+		 * This is a case where return_to_handler() is calling
+		 * ftrace_return_to_handler(). As we are already on
+		 * an original function's stack, we have no way to fetch
+		 * a correct pc value, just skip it.
+		 */
+		trace->entries[x] = 0x0;
+	} else if (trace->entries[x] ==
+			(unsigned long)return_to_handler - AARCH64_INSN_SIZE) {
+		/*
+		 * This is a case where function graph tracer has
+		 * modified lr register on a stack to hook a function
+		 * return.
+		 * So replace it to original value.
+		 */
+		trace->entries[x] =
+			current->ret_stack[data->ret_stack_index--].ret
+							- AARCH64_INSN_SIZE;
+	}
 }
 #endif /* CONFIG_STACK_TRACER */
 
-- 
1.7.9.5



From takahiro.akashi at linaro.org  Tue Aug  4 00:44:09 2015
From: takahiro.akashi at linaro.org (AKASHI Takahiro)
Date: Tue,  4 Aug 2015 16:44:09 +0900
Subject: [RFC v2 4/4] arm64: ftrace: add a stack frame for exception handler
In-Reply-To: <1438674249-3447-1-git-send-email-takahiro.akashi@linaro.org>
References: <1438674249-3447-1-git-send-email-takahiro.akashi@linaro.org>
Message-ID: <1438674249-3447-5-git-send-email-takahiro.akashi@linaro.org>

On arm64, an exception handler use the same stack as in non-exception
contexts, but doesn't create a stack frame for elx_xx entry, only updating
sp register. This behavior results in save_stace_trace() missing a function
that is the one when an exception happens.

This patch creates a stack frame for this case, and puts an additional
entry for the function  in a stack trace list.

Signed-off-by: AKASHI Takahiro <takahiro.akashi at linaro.org>
---
 arch/arm64/kernel/entry.S      |    4 ++++
 arch/arm64/kernel/stacktrace.c |   17 +++++++++++++++++
 2 files changed, 21 insertions(+)

diff --git a/arch/arm64/kernel/entry.S b/arch/arm64/kernel/entry.S
index f860bfd..aacb6c6 100644
--- a/arch/arm64/kernel/entry.S
+++ b/arch/arm64/kernel/entry.S
@@ -107,6 +107,8 @@
 	str	x21, [sp, #S_SYSCALLNO]
 	.endif
 
+	/* create a stack frame for stack tracer */
+	mov	x29, sp
 	/*
 	 * Registers that may be useful after this macro is invoked:
 	 *
@@ -737,3 +739,5 @@ ENTRY(sys_rt_sigreturn_wrapper)
 	mov	x0, sp
 	b	sys_rt_sigreturn
 ENDPROC(sys_rt_sigreturn_wrapper)
+
+ENTRY(end_of_vectors)
diff --git a/arch/arm64/kernel/stacktrace.c b/arch/arm64/kernel/stacktrace.c
index d1790eb..22ce7c9 100644
--- a/arch/arm64/kernel/stacktrace.c
+++ b/arch/arm64/kernel/stacktrace.c
@@ -25,6 +25,10 @@
 #include <asm/stacktrace.h>
 
 #define S_FRAME_SIZE sizeof(struct pt_regs) /* asm-offsets.h */
+#define S_FP offsetof(struct pt_regs, regs[29])
+#define S_LR offsetof(struct pt_regs, regs[30])
+
+extern unsigned int *vectors, *end_of_vectors;
 
 /*
  * AArch64 PCS assigns the frame pointer to x29.
@@ -50,6 +54,19 @@ int notrace unwind_frame(struct stackframe *frame)
 	if (fp < low || fp > high - 0x18 || fp & 0xf)
 		return -EINVAL;
 
+	if ((frame->pc >= (unsigned long)&vectors) &&
+			(frame->pc < (unsigned long)&end_of_vectors)) {
+		/*
+		 * Expection handler does not use a normal format of
+		 * stack frame, but allocates struct pt_regs.
+		 */
+		frame->sp = frame->sp + S_FRAME_SIZE;
+		frame->fp = *(unsigned long *)(fp + S_FP);
+		frame->pc = *(unsigned long *)(fp + S_LR);
+
+		return 0;
+	}
+
 	frame->sp = fp + 0x10;
 	frame->fp = *(unsigned long *)(fp);
 	/*
-- 
1.7.9.5



From kgene at kernel.org  Tue Aug  4 00:53:37 2015
From: kgene at kernel.org (Kukjin Kim)
Date: Tue, 04 Aug 2015 16:53:37 +0900
Subject: [GIT PULL 1/5] Samsung non-critical-fixes for v4.3
In-Reply-To: <55C06C2D.2010804@samsung.com>
References: <55C06995.2030600@kernel.org> <55C06C2D.2010804@samsung.com>
Message-ID: <052201d0ce8a$aba37790$02ea66b0$@kernel.org>

Krzysztof Kozlowski wrote:
> 
> On 04.08.2015 16:28, Kukjin Kim wrote:
> > Hi Arnd, Olof, Kevin,
> >
> > Here is Samsung non-critical-fixes for v4.3.
> > Please pull.
> >
> > Thanks,
> > Kukjin
> >
> > The following changes since commit d770e558e21961ad6cfdf0ff7df0eb5d7d4f0754:
> >
> >   Linux 4.2-rc1 (2015-07-05 11:01:52 -0700)
> >
> > are available in the git repository at:
> >
> >   git://git.kernel.org/pub/scm/linux/kernel/git/kgene/linux-samsung.git
> > tags/samsung-non-critical-1
> >
> > for you to fetch changes up to 2cc6b813579415c4f627b08a043079bdc5b87a33:
> >
> >   ARM: EXYNOS: Use IOMEM_ERR_PTR when function returns iomem (2015-07-21
> > 13:19:06 +0900)
> >
> > ----------------------------------------------------------------
> > Samsung non-critical fixes for v4.3
> >
> > - fix sparse warning for returning iomem
> > - fix clock-frequency of display timing0 for exynos3250-rinato
> 
Hi,

> One more set, which we agreed for pushing to v4.2, is missing:
> 1. cpufreq: exynos: Fix for memory leak in case SOC name does not match

As you can see in ml, I've sent it to Rafael because it would be handled in
cpufreq tree not samsung tree/arm-soc tree.

> 2. video: fbdev: s3c-fb: Constify platform_device_id (this can actually

Same as above, this would be handled in fb tree? Can you please send it?

- Kukjin



From k.kozlowski at samsung.com  Tue Aug  4 00:57:02 2015
From: k.kozlowski at samsung.com (Krzysztof Kozlowski)
Date: Tue, 04 Aug 2015 16:57:02 +0900
Subject: [GIT PULL 1/5] Samsung non-critical-fixes for v4.3
In-Reply-To: <052201d0ce8a$aba37790$02ea66b0$@kernel.org>
References: <55C06995.2030600@kernel.org> <55C06C2D.2010804@samsung.com>
 <052201d0ce8a$aba37790$02ea66b0$@kernel.org>
Message-ID: <55C0704E.7020907@samsung.com>

On 04.08.2015 16:53, Kukjin Kim wrote:
> Krzysztof Kozlowski wrote:
>>
>> On 04.08.2015 16:28, Kukjin Kim wrote:
>>> Hi Arnd, Olof, Kevin,
>>>
>>> Here is Samsung non-critical-fixes for v4.3.
>>> Please pull.
>>>
>>> Thanks,
>>> Kukjin
>>>
>>> The following changes since commit d770e558e21961ad6cfdf0ff7df0eb5d7d4f0754:
>>>
>>>   Linux 4.2-rc1 (2015-07-05 11:01:52 -0700)
>>>
>>> are available in the git repository at:
>>>
>>>   git://git.kernel.org/pub/scm/linux/kernel/git/kgene/linux-samsung.git
>>> tags/samsung-non-critical-1
>>>
>>> for you to fetch changes up to 2cc6b813579415c4f627b08a043079bdc5b87a33:
>>>
>>>   ARM: EXYNOS: Use IOMEM_ERR_PTR when function returns iomem (2015-07-21
>>> 13:19:06 +0900)
>>>
>>> ----------------------------------------------------------------
>>> Samsung non-critical fixes for v4.3
>>>
>>> - fix sparse warning for returning iomem
>>> - fix clock-frequency of display timing0 for exynos3250-rinato
>>
> Hi,
> 
>> One more set, which we agreed for pushing to v4.2, is missing:
>> 1. cpufreq: exynos: Fix for memory leak in case SOC name does not match
> 
> As you can see in ml, I've sent it to Rafael because it would be handled in
> cpufreq tree not samsung tree/arm-soc tree.
> 
>> 2. video: fbdev: s3c-fb: Constify platform_device_id (this can actually
> 
> Same as above, this would be handled in fb tree? Can you please send it?

This was on LKML for 3 months (including a resend). As this is S3C frame
buffer I think this can go via samsung-soc tree, since fb guys did not
picked it.

On list of patches few more are also missing:
1. cpufreq: exynos: remove Exynos5250 specific cpufreq driver support
2. clk: samsung: exynos5250: add cpu clock configuration data and
instantiate cpu clock
3. defconfig changes (separate pull request?)

Best regards,
Krzysztof


From lars at metafoo.de  Tue Aug  4 01:01:36 2015
From: lars at metafoo.de (Lars-Peter Clausen)
Date: Tue, 04 Aug 2015 10:01:36 +0200
Subject: [PATCH v3] iio: adc: xilinx-xadc: Push interrupts into threaded
 context
In-Reply-To: <55BFCC9C.5040305@ni.com>
References: <CAKfKVtGTO81wLWk50M303t2WjcBEMEt_LUnsJ3_WmvR_3izUjg@mail.gmail.com>
 <1437434050-32907-1-git-send-email-xander.huff@ni.com>
 <55B231DE.4080308@metafoo.de> <55BFCC9C.5040305@ni.com>
Message-ID: <55C07160.5040907@metafoo.de>

On 08/03/2015 10:18 PM, Xander Huff wrote:
> On 7/24/2015 7:38 AM, Lars-Peter Clausen wrote:
>> Hi,
>>
>> Sorry, but I don't think this patch has been sufficiently tested against a
>> mainline kernel. The driver wont even probe the way it is right now.
>>
> Thanks for your responses. I'm not sure why it doesn't probe for you since I
> was able to do a fair amount of tests with it on our device.

genirq: Threaded irq requested with handler=NULL and !ONESHOT for irq 157
xadc: probe of f8007100.xadc failed with error -22

You can' request a threaded IRQ without having IRQF_ONESHOT set, since this
will effectively result in a IRQ storm.

> 
> I'll get to work on your suggestions and hopefully having a v4 out sometime
> next week.
> 



From lars at metafoo.de  Tue Aug  4 01:05:00 2015
From: lars at metafoo.de (Lars-Peter Clausen)
Date: Tue, 04 Aug 2015 10:05:00 +0200
Subject: [PATCH v3] iio: adc: xilinx-xadc: Push interrupts into threaded
 context
In-Reply-To: <CAKfKVtGegy2P_YWQAtKEzByN-+q+bq=uus4zNvO4sghXRjpGPQ@mail.gmail.com>
References: <CAKfKVtGTO81wLWk50M303t2WjcBEMEt_LUnsJ3_WmvR_3izUjg@mail.gmail.com>	<1437434050-32907-1-git-send-email-xander.huff@ni.com>	<55B231DE.4080308@metafoo.de>
 <CAKfKVtGegy2P_YWQAtKEzByN-+q+bq=uus4zNvO4sghXRjpGPQ@mail.gmail.com>
Message-ID: <55C0722C.7080904@metafoo.de>

On 08/04/2015 07:34 AM, Shubhrajyoti Datta wrote:
> On Fri, Jul 24, 2015 at 6:08 PM, Lars-Peter Clausen <lars at metafoo.de> wrote:
>> Hi,
>>
>> Sorry, but I don't think this patch has been sufficiently tested against a
>> mainline kernel. The driver wont even probe the way it is right now.
>>
>> On 07/21/2015 01:14 AM, Xander Huff wrote:
>>>
>>> The driver currently registers a pair of irq handlers using
>>> request_threaded_irq(), however the synchronization mechanism between the
>>> hardirq and the threadedirq handler is a regular spinlock.
>>
>>
>> If everything runs in threaded context we don't really need the spinlock
>> anymore and can use the mutex throughout.
> 
> that should be better from the performance point of view.
> 
>>
>>>
>>> Unfortunately, this breaks PREEMPT_RT builds, where a spinlock can sleep,
>>> and is thus not able to be acquired from a hardirq handler. This patch
>>> gets
>>> rid of the hardirq handler and pushes all interrupt handling into the
>>> threaded context.
>>
>>
>> We actually might as well run everything in the hardirq handler (which will
>> be threaded in PREEMPT_RT). The reason why we have the threaded handler is
>> because xadc_handle_event() used to sleep, but it doesn't do this anymore.
> 
> The point is why have the hard irq. If we use hardirq then not mutex
> can be used and spinlock will
> be busy.

Well there is no need to use a threaded IRQ. The interrupt handler is quite
small and doesn't take too much time and doesn't have any delays or sleeps
in it either.




From p.zabel at pengutronix.de  Tue Aug  4 01:09:32 2015
From: p.zabel at pengutronix.de (Philipp Zabel)
Date: Tue, 04 Aug 2015 10:09:32 +0200
Subject: [RFCv3 1/4] docs: dts: Added documentation for Xilinx Zynq
 Reset Controller bindings.
In-Reply-To: <1438305237-18497-2-git-send-email-moritz.fischer@ettus.com>
References: <1438305237-18497-1-git-send-email-moritz.fischer@ettus.com>
 <1438305237-18497-2-git-send-email-moritz.fischer@ettus.com>
Message-ID: <1438675772.3793.18.camel@pengutronix.de>

Hi Moritz,

Am Donnerstag, den 30.07.2015, 18:13 -0700 schrieb Moritz Fischer:
> Signed-off-by: Moritz Fischer <moritz.fischer at ettus.com>
> ---
>  .../devicetree/bindings/reset/zynq-reset.txt       | 68 ++++++++++++++++++++++
>  1 file changed, 68 insertions(+)
>  create mode 100644 Documentation/devicetree/bindings/reset/zynq-reset.txt
> 
> diff --git a/Documentation/devicetree/bindings/reset/zynq-reset.txt b/Documentation/devicetree/bindings/reset/zynq-reset.txt
> new file mode 100644
> index 0000000..498c037a
> --- /dev/null
> +++ b/Documentation/devicetree/bindings/reset/zynq-reset.txt
> @@ -0,0 +1,68 @@
> +Xilinx Zynq Reset Manager
> +
> +The Zynq AP-SoC has several different resets.
> +
> +See Chapter 26 of the Zynq TRM (UG585) for more information about Zynq resets.
> +
> +Required properties:
> +- compatible: "xlnx,zynq-reset"
> +- reg: SLCR offset and size taken via syscon <0x200 0x48>
> +- syscon: <&slcr>
> +  This should be a phandle to the Zynq's SLCR register.

                                                 ^ register singular?

I still think the syscon phandle property is superfluous,
but I'm fine with keeping it for consistency.
It could always be made optional later.

> +- #reset-cells: Must be 1
> +
> +The Zynq Reset Manager needs to be a childnode of the SLCR.
> +
> +Example:
> +	rstc: rstc at 200 {
> +		compatible = "xlnx,zynq-reset";
> +		reg = <0x200 0x48>;
> +		#reset-cells = <1>;
> +		syscon = <&slcr>;
> +	};
> +
> +Reset outputs:
> + 0  : soft reset
> + 32 : ddr reset
> + 64 : topsw reset
> + 96 : dmac reset
> + 128: usb0 reset
> + 129: usb1 reset
> + 160: gem0 reset
> + 161: gem1 reset
> + 164: gem0 rx reset
> + 165: gem1 rx reset
> + 166: gem0 ref reset
> + 167: gem1 ref reset
> + 192: sdio0 reset
> + 193: sdio1 reset
> + 196: sdio0 ref reset
> + 197: sdio1 ref reset
> + 224: spi0 reset
> + 225: spi1 reset
> + 226: spi0 ref reset
> + 227: spi1 ref reset
> + 256: can0 reset
> + 257: can1 reset
> + 258: can0 ref reset
> + 259: can1 ref reset
> + 288: i2c0 reset
> + 289: i2c1 reset
> + 320: uart0 reset
> + 321: uart1 reset
> + 322: uart0 ref reset
> + 323: uart1 ref reset
> + 352: gpio reset
> + 384: lqspi reset
> + 385: qspi ref reset
> + 416: smc reset
> + 417: smc ref reset
> + 448: ocm reset
> + 512: fpga0 out reset
> + 513: fpga1 out reset
> + 514: fpga2 out reset
> + 515: fpga3 out reset
> + 544: a9 reset 0
> + 545: a9 reset 1
> + 552: peri reset
> +

regards
Philipp



From kgene at kernel.org  Tue Aug  4 01:11:26 2015
From: kgene at kernel.org (Kukjin Kim)
Date: Tue, 04 Aug 2015 17:11:26 +0900
Subject: [GIT PULL 1/5] Samsung non-critical-fixes for v4.3
In-Reply-To: <55C0704E.7020907@samsung.com>
References: <55C06995.2030600@kernel.org> <55C06C2D.2010804@samsung.com>
 <052201d0ce8a$aba37790$02ea66b0$@kernel.org> <55C0704E.7020907@samsung.com>
Message-ID: <053301d0ce8d$293eda80$7bbc8f80$@kernel.org>

Krzysztof Kozlowski wrote:
> 
> On 04.08.2015 16:53, Kukjin Kim wrote:
> > Krzysztof Kozlowski wrote:
> >>
> >> On 04.08.2015 16:28, Kukjin Kim wrote:
> >>> Hi Arnd, Olof, Kevin,
> >>>
> >>> Here is Samsung non-critical-fixes for v4.3.
> >>> Please pull.
> >>>
> >>> Thanks,
> >>> Kukjin
> >>>
> >>> The following changes since commit d770e558e21961ad6cfdf0ff7df0eb5d7d4f0754:
> >>>
> >>>   Linux 4.2-rc1 (2015-07-05 11:01:52 -0700)
> >>>
> >>> are available in the git repository at:
> >>>
> >>>   git://git.kernel.org/pub/scm/linux/kernel/git/kgene/linux-samsung.git
> >>> tags/samsung-non-critical-1
> >>>
> >>> for you to fetch changes up to 2cc6b813579415c4f627b08a043079bdc5b87a33:
> >>>
> >>>   ARM: EXYNOS: Use IOMEM_ERR_PTR when function returns iomem (2015-07-21
> >>> 13:19:06 +0900)
> >>>
> >>> ----------------------------------------------------------------
> >>> Samsung non-critical fixes for v4.3
> >>>
> >>> - fix sparse warning for returning iomem
> >>> - fix clock-frequency of display timing0 for exynos3250-rinato
> >>
> > Hi,
> >
Hi,

> >> One more set, which we agreed for pushing to v4.2, is missing:
> >> 1. cpufreq: exynos: Fix for memory leak in case SOC name does not match
> >
> > As you can see in ml, I've sent it to Rafael because it would be handled in
> > cpufreq tree not samsung tree/arm-soc tree.
> >
> >> 2. video: fbdev: s3c-fb: Constify platform_device_id (this can actually
> >
> > Same as above, this would be handled in fb tree? Can you please send it?
> 
> This was on LKML for 3 months (including a resend). As this is S3C frame
> buffer I think this can go via samsung-soc tree, since fb guys did not
> picked it.
> 
Oh, OK. Let me look at its status again. Thanks.

> On list of patches few more are also missing:
> 1. cpufreq: exynos: remove Exynos5250 specific cpufreq driver support

This is included in tags/samsung-driver...let me note in the pull-request to
clarify.

> 2. clk: samsung: exynos5250: add cpu clock configuration data and
> instantiate cpu clock

Yeah, I'm aware of that and I need to sort it out soon.

> 3. defconfig changes (separate pull request?)
> 
Yeah, I'm sorting out some other defconfig updates and it will be sent out soon.

Thanks,
Kukjin



From michal.simek at xilinx.com  Tue Aug  4 01:13:50 2015
From: michal.simek at xilinx.com (Michal Simek)
Date: Tue, 4 Aug 2015 10:13:50 +0200
Subject: [RFCv3 2/4] dts: zynq: Add devicetree entry for Xilinx Zynq reset
 controller.
In-Reply-To: <1438305237-18497-3-git-send-email-moritz.fischer@ettus.com>
References: <1438305237-18497-1-git-send-email-moritz.fischer@ettus.com>
 <1438305237-18497-3-git-send-email-moritz.fischer@ettus.com>
Message-ID: <55C0743E.1090406@xilinx.com>

On 07/31/2015 03:13 AM, Moritz Fischer wrote:
> Signed-off-by: Moritz Fischer <moritz.fischer at ettus.com>
> ---
>  arch/arm/boot/dts/zynq-7000.dtsi | 8 ++++++++
>  1 file changed, 8 insertions(+)
> 
> diff --git a/arch/arm/boot/dts/zynq-7000.dtsi b/arch/arm/boot/dts/zynq-7000.dtsi
> index 0691508..6bebf02 100644
> --- a/arch/arm/boot/dts/zynq-7000.dtsi
> +++ b/arch/arm/boot/dts/zynq-7000.dtsi
> @@ -1,5 +1,6 @@
>  /*
>   *  Copyright (C) 2011 - 2014 Xilinx
> + *  Copyright (C) 2015 National Instruments Corp.
>   *
>   * This software is licensed under the terms of the GNU General Public
>   * License version 2, as published by the Free Software Foundation, and
> @@ -258,6 +259,13 @@
>  				reg = <0x100 0x100>;
>  			};
>  
> +			rstc: rstc at 200 {
> +				compatible = "xlnx,zynq-reset";
> +				reg = <0x200 0x48>;
> +				#reset-cells = <1>;
> +				syscon = <&slcr>;
> +			};
> +
>  			pinctrl0: pinctrl at 700 {
>  				compatible = "xlnx,pinctrl-zynq";
>  				reg = <0x700 0x200>;
> 

Acked-by: Michal Simek <michal.simek at xilinx.com>

Thanks,
Michal


From jamesjj.liao at mediatek.com  Tue Aug  4 01:16:50 2015
From: jamesjj.liao at mediatek.com (James Liao)
Date: Tue, 4 Aug 2015 16:16:50 +0800
Subject: [PATCH v6 1/9] clk: mediatek: Removed unused dpi_ck clock from MT8173
In-Reply-To: <1438676218-11310-1-git-send-email-jamesjj.liao@mediatek.com>
References: <1438676218-11310-1-git-send-email-jamesjj.liao@mediatek.com>
Message-ID: <1438676218-11310-2-git-send-email-jamesjj.liao@mediatek.com>

The dpi_ck clock can be removed because it not actually used
in topckgen and subsystems.

Signed-off-by: James Liao <jamesjj.liao at mediatek.com>
---
 drivers/clk/mediatek/clk-mt8173.c      | 1 -
 include/dt-bindings/clock/mt8173-clk.h | 1 -
 2 files changed, 2 deletions(-)

diff --git a/drivers/clk/mediatek/clk-mt8173.c b/drivers/clk/mediatek/clk-mt8173.c
index 8b6523d..80871e2 100644
--- a/drivers/clk/mediatek/clk-mt8173.c
+++ b/drivers/clk/mediatek/clk-mt8173.c
@@ -26,7 +26,6 @@ static DEFINE_SPINLOCK(mt8173_clk_lock);
 
 static const struct mtk_fixed_factor root_clk_alias[] __initconst = {
 	FACTOR(CLK_TOP_CLKPH_MCK_O, "clkph_mck_o", "clk_null", 1, 1),
-	FACTOR(CLK_TOP_DPI, "dpi_ck", "clk_null", 1, 1),
 	FACTOR(CLK_TOP_USB_SYSPLL_125M, "usb_syspll_125m", "clk_null", 1, 1),
 	FACTOR(CLK_TOP_HDMITX_DIG_CTS, "hdmitx_dig_cts", "clk_null", 1, 1),
 };
diff --git a/include/dt-bindings/clock/mt8173-clk.h b/include/dt-bindings/clock/mt8173-clk.h
index 4ad76ed..7230c38 100644
--- a/include/dt-bindings/clock/mt8173-clk.h
+++ b/include/dt-bindings/clock/mt8173-clk.h
@@ -18,7 +18,6 @@
 /* TOPCKGEN */
 
 #define CLK_TOP_CLKPH_MCK_O		1
-#define CLK_TOP_DPI			2
 #define CLK_TOP_USB_SYSPLL_125M		3
 #define CLK_TOP_HDMITX_DIG_CTS		4
 #define CLK_TOP_ARMCA7PLL_754M		5
-- 
1.8.1.1.dirty



From jamesjj.liao at mediatek.com  Tue Aug  4 01:16:49 2015
From: jamesjj.liao at mediatek.com (James Liao)
Date: Tue, 4 Aug 2015 16:16:49 +0800
Subject: [PATCH v6 0/9] Fixes and new clocks support for Mediatek MT8173
Message-ID: <1438676218-11310-1-git-send-email-jamesjj.liao@mediatek.com>

This patchset is based on 4.2-rc2 and [1], and contains minor fixes and
subsystem clocks support for Mediatek MT8173.

The previous reviews can be found in [2]. The most different from previous
patchset is rebasing to 4.2-rc2.

changes since v5:
- Rebase to 4.2-rc2.
- Patch "Fix enabling of critical clocks" had been included in 4.2-rc2,
  so it need not be included in this patchset.

changes since v4:
- Add a separated patch to remove unused dpi_ck.
- Add separated patches to fix clk/mediatek in release 4.2-rc1.
- Add __init* for initialization data and functions.
- Rename dummy_clk with oscillator in DT.
- Remove mtk_clk_register_apmixed_ex(), call mtk_clk_register_ref2usb_tx()
  directly to register USB clock.

changes since v3:
- Remove clk_null dependency from root clocks.
- Use fixed-rate clocks with typical rate to replace clk_null.
- Separate ref2usb_tx implementation to clk-apmixed.c
- Use clock-controller as the name of clock providers.

changes since v2:
- Rebase to 4.2-rc1.
- Add device tree nodes for subsystem clocks.
- Fine tune comments of patches.
- Add __init, __initconst and const to init data and functions.
- Removed unused code from init functions of subsystem clocks.

changes since v1:
- Add CA7PLL and CA15PLL as critical clocks.
- Use the same register descriptor for imgsys, vensys and vencltsys.
- Generalize apmixedsys special clocks registration.

[1] https://patchwork.kernel.org/patch/6446341/
[2] http://lists.infradead.org/pipermail/linux-mediatek/2015-July/001800.html

James Liao (9):
  clk: mediatek: Removed unused dpi_ck clock from MT8173
  clk: mediatek: Remove unused code from MT8173.
  clk: mediatek: Add __initdata and __init for data and functions
  clk: mediatek: Add fixed clocks support for Mediatek SoC.
  clk: mediatek: Fix rate and dependency of MT8173 clocks
  dt-bindings: ARM: Mediatek: Document devicetree bindings for clock
    controllers
  clk: mediatek: Add subsystem clocks of MT8173
  clk: mediatek: Add USB clock support in MT8173 APMIXEDSYS
  arm64: dts: mt8173: Add subsystem clock controller device nodes

 .../bindings/arm/mediatek/mediatek,imgsys.txt      |  22 ++
 .../bindings/arm/mediatek/mediatek,mmsys.txt       |  22 ++
 .../bindings/arm/mediatek/mediatek,vdecsys.txt     |  22 ++
 .../bindings/arm/mediatek/mediatek,vencltsys.txt   |  22 ++
 .../bindings/arm/mediatek/mediatek,vencsys.txt     |  22 ++
 arch/arm64/boot/dts/mediatek/mt8173.dtsi           |  37 +++
 drivers/clk/mediatek/Makefile                      |   2 +-
 drivers/clk/mediatek/clk-apmixed.c                 | 107 +++++++
 drivers/clk/mediatek/clk-gate.c                    |   2 +-
 drivers/clk/mediatek/clk-mt8173.c                  | 335 ++++++++++++++++++++-
 drivers/clk/mediatek/clk-mtk.c                     |  36 ++-
 drivers/clk/mediatek/clk-mtk.h                     |  24 +-
 drivers/clk/mediatek/clk-pll.c                     |   7 +-
 include/dt-bindings/clock/mt8173-clk.h             | 101 ++++++-
 14 files changed, 728 insertions(+), 33 deletions(-)
 create mode 100644 Documentation/devicetree/bindings/arm/mediatek/mediatek,imgsys.txt
 create mode 100644 Documentation/devicetree/bindings/arm/mediatek/mediatek,mmsys.txt
 create mode 100644 Documentation/devicetree/bindings/arm/mediatek/mediatek,vdecsys.txt
 create mode 100644 Documentation/devicetree/bindings/arm/mediatek/mediatek,vencltsys.txt
 create mode 100644 Documentation/devicetree/bindings/arm/mediatek/mediatek,vencsys.txt
 create mode 100644 drivers/clk/mediatek/clk-apmixed.c

--
1.8.1.1.dirty



From jamesjj.liao at mediatek.com  Tue Aug  4 01:16:52 2015
From: jamesjj.liao at mediatek.com (James Liao)
Date: Tue, 4 Aug 2015 16:16:52 +0800
Subject: [PATCH v6 3/9] clk: mediatek: Add __initdata and __init for data and
 functions
In-Reply-To: <1438676218-11310-1-git-send-email-jamesjj.liao@mediatek.com>
References: <1438676218-11310-1-git-send-email-jamesjj.liao@mediatek.com>
Message-ID: <1438676218-11310-4-git-send-email-jamesjj.liao@mediatek.com>

Add __init for clock registration functions, and add __initdata for
mtk_gate_regs initial structures.

Signed-off-by: James Liao <jamesjj.liao at mediatek.com>
---
 drivers/clk/mediatek/clk-gate.c   |  2 +-
 drivers/clk/mediatek/clk-mt8173.c |  6 +++---
 drivers/clk/mediatek/clk-mtk.c    | 13 +++++++------
 3 files changed, 11 insertions(+), 10 deletions(-)

diff --git a/drivers/clk/mediatek/clk-gate.c b/drivers/clk/mediatek/clk-gate.c
index 5702036..576bdb7 100644
--- a/drivers/clk/mediatek/clk-gate.c
+++ b/drivers/clk/mediatek/clk-gate.c
@@ -97,7 +97,7 @@ const struct clk_ops mtk_clk_gate_ops_setclr_inv = {
 	.disable	= mtk_cg_disable_inv,
 };
 
-struct clk *mtk_clk_register_gate(
+struct clk * __init mtk_clk_register_gate(
 		const char *name,
 		const char *parent_name,
 		struct regmap *regmap,
diff --git a/drivers/clk/mediatek/clk-mt8173.c b/drivers/clk/mediatek/clk-mt8173.c
index 13aa432..361fe32 100644
--- a/drivers/clk/mediatek/clk-mt8173.c
+++ b/drivers/clk/mediatek/clk-mt8173.c
@@ -586,7 +586,7 @@ static const struct mtk_composite top_muxes[] __initconst = {
 	MUX(CLK_TOP_I2S3_B_SEL, "i2s3_b_ck_sel", i2s3_b_ck_parents, 0x120, 8, 1),
 };
 
-static const struct mtk_gate_regs infra_cg_regs = {
+static const struct mtk_gate_regs infra_cg_regs __initconst = {
 	.set_ofs = 0x0040,
 	.clr_ofs = 0x0044,
 	.sta_ofs = 0x0048,
@@ -615,13 +615,13 @@ static const struct mtk_gate infra_clks[] __initconst = {
 	GATE_ICG(CLK_INFRA_PMICWRAP, "infra_pmicwrap", "axi_sel", 23),
 };
 
-static const struct mtk_gate_regs peri0_cg_regs = {
+static const struct mtk_gate_regs peri0_cg_regs __initconst = {
 	.set_ofs = 0x0008,
 	.clr_ofs = 0x0010,
 	.sta_ofs = 0x0018,
 };
 
-static const struct mtk_gate_regs peri1_cg_regs = {
+static const struct mtk_gate_regs peri1_cg_regs __initconst = {
 	.set_ofs = 0x000c,
 	.clr_ofs = 0x0014,
 	.sta_ofs = 0x001c,
diff --git a/drivers/clk/mediatek/clk-mtk.c b/drivers/clk/mediatek/clk-mtk.c
index 18444ae..268b6ff 100644
--- a/drivers/clk/mediatek/clk-mtk.c
+++ b/drivers/clk/mediatek/clk-mtk.c
@@ -24,7 +24,7 @@
 #include "clk-mtk.h"
 #include "clk-gate.h"
 
-struct clk_onecell_data *mtk_alloc_clk_data(unsigned int clk_num)
+struct clk_onecell_data * __init mtk_alloc_clk_data(unsigned int clk_num)
 {
 	int i;
 	struct clk_onecell_data *clk_data;
@@ -49,8 +49,8 @@ err_out:
 	return NULL;
 }
 
-void mtk_clk_register_factors(const struct mtk_fixed_factor *clks, int num,
-		struct clk_onecell_data *clk_data)
+void __init mtk_clk_register_factors(const struct mtk_fixed_factor *clks,
+		int num, struct clk_onecell_data *clk_data)
 {
 	int i;
 	struct clk *clk;
@@ -72,7 +72,8 @@ void mtk_clk_register_factors(const struct mtk_fixed_factor *clks, int num,
 	}
 }
 
-int mtk_clk_register_gates(struct device_node *node, const struct mtk_gate *clks,
+int __init mtk_clk_register_gates(struct device_node *node,
+		const struct mtk_gate *clks,
 		int num, struct clk_onecell_data *clk_data)
 {
 	int i;
@@ -111,7 +112,7 @@ int mtk_clk_register_gates(struct device_node *node, const struct mtk_gate *clks
 	return 0;
 }
 
-struct clk *mtk_clk_register_composite(const struct mtk_composite *mc,
+struct clk * __init mtk_clk_register_composite(const struct mtk_composite *mc,
 		void __iomem *base, spinlock_t *lock)
 {
 	struct clk *clk;
@@ -196,7 +197,7 @@ err_out:
 	return ERR_PTR(ret);
 }
 
-void mtk_clk_register_composites(const struct mtk_composite *mcs,
+void __init mtk_clk_register_composites(const struct mtk_composite *mcs,
 		int num, void __iomem *base, spinlock_t *lock,
 		struct clk_onecell_data *clk_data)
 {
-- 
1.8.1.1.dirty



From jamesjj.liao at mediatek.com  Tue Aug  4 01:16:55 2015
From: jamesjj.liao at mediatek.com (James Liao)
Date: Tue, 4 Aug 2015 16:16:55 +0800
Subject: [PATCH v6 6/9] dt-bindings: ARM: Mediatek: Document devicetree
 bindings for clock controllers
In-Reply-To: <1438676218-11310-1-git-send-email-jamesjj.liao@mediatek.com>
References: <1438676218-11310-1-git-send-email-jamesjj.liao@mediatek.com>
Message-ID: <1438676218-11310-7-git-send-email-jamesjj.liao@mediatek.com>

This adds the binding documentation for the mmsys, imgsys, vdecsys,
vencsys and vencltsys controllers found on Mediatek SoCs.

Signed-off-by: James Liao <jamesjj.liao at mediatek.com>
---
 .../bindings/arm/mediatek/mediatek,imgsys.txt      | 22 ++++++++++++++++++++++
 .../bindings/arm/mediatek/mediatek,mmsys.txt       | 22 ++++++++++++++++++++++
 .../bindings/arm/mediatek/mediatek,vdecsys.txt     | 22 ++++++++++++++++++++++
 .../bindings/arm/mediatek/mediatek,vencltsys.txt   | 22 ++++++++++++++++++++++
 .../bindings/arm/mediatek/mediatek,vencsys.txt     | 22 ++++++++++++++++++++++
 5 files changed, 110 insertions(+)
 create mode 100644 Documentation/devicetree/bindings/arm/mediatek/mediatek,imgsys.txt
 create mode 100644 Documentation/devicetree/bindings/arm/mediatek/mediatek,mmsys.txt
 create mode 100644 Documentation/devicetree/bindings/arm/mediatek/mediatek,vdecsys.txt
 create mode 100644 Documentation/devicetree/bindings/arm/mediatek/mediatek,vencltsys.txt
 create mode 100644 Documentation/devicetree/bindings/arm/mediatek/mediatek,vencsys.txt

diff --git a/Documentation/devicetree/bindings/arm/mediatek/mediatek,imgsys.txt b/Documentation/devicetree/bindings/arm/mediatek/mediatek,imgsys.txt
new file mode 100644
index 0000000..b1f2ce1
--- /dev/null
+++ b/Documentation/devicetree/bindings/arm/mediatek/mediatek,imgsys.txt
@@ -0,0 +1,22 @@
+Mediatek imgsys controller
+============================
+
+The Mediatek imgsys controller provides various clocks to the system.
+
+Required Properties:
+
+- compatible: Should be:
+	- "mediatek,mt8173-imgsys", "syscon"
+- #clock-cells: Must be 1
+
+The imgsys controller uses the common clk binding from
+Documentation/devicetree/bindings/clock/clock-bindings.txt
+The available clocks are defined in dt-bindings/clock/mt*-clk.h.
+
+Example:
+
+imgsys: clock-controller at 15000000 {
+	compatible = "mediatek,mt8173-imgsys", "syscon";
+	reg = <0 0x15000000 0 0x1000>;
+	#clock-cells = <1>;
+};
diff --git a/Documentation/devicetree/bindings/arm/mediatek/mediatek,mmsys.txt b/Documentation/devicetree/bindings/arm/mediatek/mediatek,mmsys.txt
new file mode 100644
index 0000000..4385946
--- /dev/null
+++ b/Documentation/devicetree/bindings/arm/mediatek/mediatek,mmsys.txt
@@ -0,0 +1,22 @@
+Mediatek mmsys controller
+============================
+
+The Mediatek mmsys controller provides various clocks to the system.
+
+Required Properties:
+
+- compatible: Should be:
+	- "mediatek,mt8173-mmsys", "syscon"
+- #clock-cells: Must be 1
+
+The mmsys controller uses the common clk binding from
+Documentation/devicetree/bindings/clock/clock-bindings.txt
+The available clocks are defined in dt-bindings/clock/mt*-clk.h.
+
+Example:
+
+mmsys: clock-controller at 14000000 {
+	compatible = "mediatek,mt8173-mmsys", "syscon";
+	reg = <0 0x14000000 0 0x1000>;
+	#clock-cells = <1>;
+};
diff --git a/Documentation/devicetree/bindings/arm/mediatek/mediatek,vdecsys.txt b/Documentation/devicetree/bindings/arm/mediatek/mediatek,vdecsys.txt
new file mode 100644
index 0000000..1faacf1
--- /dev/null
+++ b/Documentation/devicetree/bindings/arm/mediatek/mediatek,vdecsys.txt
@@ -0,0 +1,22 @@
+Mediatek vdecsys controller
+============================
+
+The Mediatek vdecsys controller provides various clocks to the system.
+
+Required Properties:
+
+- compatible: Should be:
+	- "mediatek,mt8173-vdecsys", "syscon"
+- #clock-cells: Must be 1
+
+The vdecsys controller uses the common clk binding from
+Documentation/devicetree/bindings/clock/clock-bindings.txt
+The available clocks are defined in dt-bindings/clock/mt*-clk.h.
+
+Example:
+
+vdecsys: clock-controller at 16000000 {
+	compatible = "mediatek,mt8173-vdecsys", "syscon";
+	reg = <0 0x16000000 0 0x1000>;
+	#clock-cells = <1>;
+};
diff --git a/Documentation/devicetree/bindings/arm/mediatek/mediatek,vencltsys.txt b/Documentation/devicetree/bindings/arm/mediatek/mediatek,vencltsys.txt
new file mode 100644
index 0000000..3cc299f
--- /dev/null
+++ b/Documentation/devicetree/bindings/arm/mediatek/mediatek,vencltsys.txt
@@ -0,0 +1,22 @@
+Mediatek vencltsys controller
+============================
+
+The Mediatek vencltsys controller provides various clocks to the system.
+
+Required Properties:
+
+- compatible: Should be:
+	- "mediatek,mt8173-vencltsys", "syscon"
+- #clock-cells: Must be 1
+
+The vencltsys controller uses the common clk binding from
+Documentation/devicetree/bindings/clock/clock-bindings.txt
+The available clocks are defined in dt-bindings/clock/mt*-clk.h.
+
+Example:
+
+vencltsys: clock-controller at 19000000 {
+	compatible = "mediatek,mt8173-vencltsys", "syscon";
+	reg = <0 0x19000000 0 0x1000>;
+	#clock-cells = <1>;
+};
diff --git a/Documentation/devicetree/bindings/arm/mediatek/mediatek,vencsys.txt b/Documentation/devicetree/bindings/arm/mediatek/mediatek,vencsys.txt
new file mode 100644
index 0000000..5bb2866
--- /dev/null
+++ b/Documentation/devicetree/bindings/arm/mediatek/mediatek,vencsys.txt
@@ -0,0 +1,22 @@
+Mediatek vencsys controller
+============================
+
+The Mediatek vencsys controller provides various clocks to the system.
+
+Required Properties:
+
+- compatible: Should be:
+	- "mediatek,mt8173-vencsys", "syscon"
+- #clock-cells: Must be 1
+
+The vencsys controller uses the common clk binding from
+Documentation/devicetree/bindings/clock/clock-bindings.txt
+The available clocks are defined in dt-bindings/clock/mt*-clk.h.
+
+Example:
+
+vencsys: clock-controller at 18000000 {
+	compatible = "mediatek,mt8173-vencsys", "syscon";
+	reg = <0 0x18000000 0 0x1000>;
+	#clock-cells = <1>;
+};
-- 
1.8.1.1.dirty



From jamesjj.liao at mediatek.com  Tue Aug  4 01:16:53 2015
From: jamesjj.liao at mediatek.com (James Liao)
Date: Tue, 4 Aug 2015 16:16:53 +0800
Subject: [PATCH v6 4/9] clk: mediatek: Add fixed clocks support for Mediatek
 SoC.
In-Reply-To: <1438676218-11310-1-git-send-email-jamesjj.liao@mediatek.com>
References: <1438676218-11310-1-git-send-email-jamesjj.liao@mediatek.com>
Message-ID: <1438676218-11310-5-git-send-email-jamesjj.liao@mediatek.com>

This patch adds fixed clocks support by using CCF fixed-rate
clock implementation.

Signed-off-by: James Liao <jamesjj.liao at mediatek.com>
---
 drivers/clk/mediatek/clk-mtk.c | 23 +++++++++++++++++++++++
 drivers/clk/mediatek/clk-mtk.h | 17 +++++++++++++++++
 2 files changed, 40 insertions(+)

diff --git a/drivers/clk/mediatek/clk-mtk.c b/drivers/clk/mediatek/clk-mtk.c
index 268b6ff..cf08db6 100644
--- a/drivers/clk/mediatek/clk-mtk.c
+++ b/drivers/clk/mediatek/clk-mtk.c
@@ -49,6 +49,29 @@ err_out:
 	return NULL;
 }
 
+void __init mtk_clk_register_fixed_clks(const struct mtk_fixed_clk *clks,
+		int num, struct clk_onecell_data *clk_data)
+{
+	int i;
+	struct clk *clk;
+
+	for (i = 0; i < num; i++) {
+		const struct mtk_fixed_clk *rc = &clks[i];
+
+		clk = clk_register_fixed_rate(NULL, rc->name, rc->parent,
+				rc->parent ? 0 : CLK_IS_ROOT, rc->rate);
+
+		if (IS_ERR(clk)) {
+			pr_err("Failed to register clk %s: %ld\n",
+					rc->name, PTR_ERR(clk));
+			continue;
+		}
+
+		if (clk_data)
+			clk_data->clks[rc->id] = clk;
+	}
+}
+
 void __init mtk_clk_register_factors(const struct mtk_fixed_factor *clks,
 		int num, struct clk_onecell_data *clk_data)
 {
diff --git a/drivers/clk/mediatek/clk-mtk.h b/drivers/clk/mediatek/clk-mtk.h
index 740fe5e..32d4f55 100644
--- a/drivers/clk/mediatek/clk-mtk.h
+++ b/drivers/clk/mediatek/clk-mtk.h
@@ -25,6 +25,23 @@
 
 #define MHZ (1000 * 1000)
 
+struct mtk_fixed_clk {
+	int id;
+	const char *name;
+	const char *parent;
+	unsigned long rate;
+};
+
+#define FIXED_CLK(_id, _name, _parent, _rate) {		\
+		.id = _id,				\
+		.name = _name,				\
+		.parent = _parent,			\
+		.rate = _rate,				\
+	}
+
+void mtk_clk_register_fixed_clks(const struct mtk_fixed_clk *clks,
+		int num, struct clk_onecell_data *clk_data);
+
 struct mtk_fixed_factor {
 	int id;
 	const char *name;
-- 
1.8.1.1.dirty



From jamesjj.liao at mediatek.com  Tue Aug  4 01:16:54 2015
From: jamesjj.liao at mediatek.com (James Liao)
Date: Tue, 4 Aug 2015 16:16:54 +0800
Subject: [PATCH v6 5/9] clk: mediatek: Fix rate and dependency of MT8173 clocks
In-Reply-To: <1438676218-11310-1-git-send-email-jamesjj.liao@mediatek.com>
References: <1438676218-11310-1-git-send-email-jamesjj.liao@mediatek.com>
Message-ID: <1438676218-11310-6-git-send-email-jamesjj.liao@mediatek.com>

Remove the dependency from clk_null, and give all root clocks a
typical rate, include clkph_mck_o, usb_syspll_125m and hdmitx_dig_cts.

dpi_ck was removed due to no clock reference to it.

Replace parent clock of infra_cpum with cpum_ck, which is an external
clock and can be defined in the device tree.

Signed-off-by: James Liao <jamesjj.liao at mediatek.com>
---
 drivers/clk/mediatek/clk-mt8173.c | 12 ++++++------
 1 file changed, 6 insertions(+), 6 deletions(-)

diff --git a/drivers/clk/mediatek/clk-mt8173.c b/drivers/clk/mediatek/clk-mt8173.c
index 361fe32..f37ace6 100644
--- a/drivers/clk/mediatek/clk-mt8173.c
+++ b/drivers/clk/mediatek/clk-mt8173.c
@@ -22,10 +22,9 @@
 
 static DEFINE_SPINLOCK(mt8173_clk_lock);
 
-static const struct mtk_fixed_factor root_clk_alias[] __initconst = {
-	FACTOR(CLK_TOP_CLKPH_MCK_O, "clkph_mck_o", "clk_null", 1, 1),
-	FACTOR(CLK_TOP_USB_SYSPLL_125M, "usb_syspll_125m", "clk_null", 1, 1),
-	FACTOR(CLK_TOP_HDMITX_DIG_CTS, "hdmitx_dig_cts", "clk_null", 1, 1),
+static const struct mtk_fixed_clk fixed_clks[] __initconst = {
+	FIXED_CLK(CLK_TOP_CLKPH_MCK_O, "clkph_mck_o", "clk26m", 400 * MHZ),
+	FIXED_CLK(CLK_TOP_USB_SYSPLL_125M, "usb_syspll_125m", "clk26m", 125 * MHZ),
 };
 
 static const struct mtk_fixed_factor top_divs[] __initconst = {
@@ -50,6 +49,7 @@ static const struct mtk_fixed_factor top_divs[] __initconst = {
 	FACTOR(CLK_TOP_CLKRTC_INT, "clkrtc_int", "clk26m", 1, 793),
 	FACTOR(CLK_TOP_FPC, "fpc_ck", "clk26m", 1, 1),
 
+	FACTOR(CLK_TOP_HDMITX_DIG_CTS, "hdmitx_dig_cts", "tvdpll_445p5m", 1, 3),
 	FACTOR(CLK_TOP_HDMITXPLL_D2, "hdmitxpll_d2", "hdmitx_dig_cts", 1, 2),
 	FACTOR(CLK_TOP_HDMITXPLL_D3, "hdmitxpll_d3", "hdmitx_dig_cts", 1, 3),
 
@@ -608,7 +608,7 @@ static const struct mtk_gate infra_clks[] __initconst = {
 	GATE_ICG(CLK_INFRA_GCE, "infra_gce", "axi_sel", 6),
 	GATE_ICG(CLK_INFRA_L2C_SRAM, "infra_l2c_sram", "axi_sel", 7),
 	GATE_ICG(CLK_INFRA_M4U, "infra_m4u", "mem_sel", 8),
-	GATE_ICG(CLK_INFRA_CPUM, "infra_cpum", "clk_null", 15),
+	GATE_ICG(CLK_INFRA_CPUM, "infra_cpum", "cpum_ck", 15),
 	GATE_ICG(CLK_INFRA_KP, "infra_kp", "axi_sel", 16),
 	GATE_ICG(CLK_INFRA_CEC, "infra_cec", "clk26m", 18),
 	GATE_ICG(CLK_INFRA_PMICSPI, "infra_pmicspi", "pmicspi_sel", 22),
@@ -727,7 +727,7 @@ static void __init mtk_topckgen_init(struct device_node *node)
 
 	mt8173_top_clk_data = clk_data = mtk_alloc_clk_data(CLK_TOP_NR_CLK);
 
-	mtk_clk_register_factors(root_clk_alias, ARRAY_SIZE(root_clk_alias), clk_data);
+	mtk_clk_register_fixed_clks(fixed_clks, ARRAY_SIZE(fixed_clks), clk_data);
 	mtk_clk_register_factors(top_divs, ARRAY_SIZE(top_divs), clk_data);
 	mtk_clk_register_composites(top_muxes, ARRAY_SIZE(top_muxes), base,
 			&mt8173_clk_lock, clk_data);
-- 
1.8.1.1.dirty



From jamesjj.liao at mediatek.com  Tue Aug  4 01:16:58 2015
From: jamesjj.liao at mediatek.com (James Liao)
Date: Tue, 4 Aug 2015 16:16:58 +0800
Subject: [PATCH v6 9/9] arm64: dts: mt8173: Add subsystem clock controller
 device nodes
In-Reply-To: <1438676218-11310-1-git-send-email-jamesjj.liao@mediatek.com>
References: <1438676218-11310-1-git-send-email-jamesjj.liao@mediatek.com>
Message-ID: <1438676218-11310-10-git-send-email-jamesjj.liao@mediatek.com>

This patch adds device nodes providing subsystem clocks on MT8173,
includes mmsys, imgsys, vdecsys, vencsys and vencltsys.

Signed-off-by: James Liao <jamesjj.liao at mediatek.com>
---
 arch/arm64/boot/dts/mediatek/mt8173.dtsi | 37 ++++++++++++++++++++++++++++++++
 1 file changed, 37 insertions(+)

diff --git a/arch/arm64/boot/dts/mediatek/mt8173.dtsi b/arch/arm64/boot/dts/mediatek/mt8173.dtsi
index a2f63e4..32c85cc 100644
--- a/arch/arm64/boot/dts/mediatek/mt8173.dtsi
+++ b/arch/arm64/boot/dts/mediatek/mt8173.dtsi
@@ -102,6 +102,13 @@
 		clock-output-names = "clk32k";
 	};
 
+	cpum_ck: oscillator at 2 {
+		compatible = "fixed-clock";
+		#clock-cells = <0>;
+		clock-frequency = <0>;
+		clock-output-names = "cpum_ck";
+	};
+
 	timer {
 		compatible = "arm,armv8-timer";
 		interrupt-parent = <&gic>;
@@ -227,6 +234,36 @@
 			clocks = <&uart_clk>;
 			status = "disabled";
 		};
+
+		mmsys: clock-controller at 14000000 {
+			compatible = "mediatek,mt8173-mmsys", "syscon";
+			reg = <0 0x14000000 0 0x1000>;
+			#clock-cells = <1>;
+		};
+
+		imgsys: clock-controller at 15000000 {
+			compatible = "mediatek,mt8173-imgsys", "syscon";
+			reg = <0 0x15000000 0 0x1000>;
+			#clock-cells = <1>;
+		};
+
+		vdecsys: clock-controller at 16000000 {
+			compatible = "mediatek,mt8173-vdecsys", "syscon";
+			reg = <0 0x16000000 0 0x1000>;
+			#clock-cells = <1>;
+		};
+
+		vencsys: clock-controller at 18000000 {
+			compatible = "mediatek,mt8173-vencsys", "syscon";
+			reg = <0 0x18000000 0 0x1000>;
+			#clock-cells = <1>;
+		};
+
+		vencltsys: clock-controller at 19000000 {
+			compatible = "mediatek,mt8173-vencltsys", "syscon";
+			reg = <0 0x19000000 0 0x1000>;
+			#clock-cells = <1>;
+		};
 	};
 };
 
-- 
1.8.1.1.dirty



From jamesjj.liao at mediatek.com  Tue Aug  4 01:16:56 2015
From: jamesjj.liao at mediatek.com (James Liao)
Date: Tue, 4 Aug 2015 16:16:56 +0800
Subject: [PATCH v6 7/9] clk: mediatek: Add subsystem clocks of MT8173
In-Reply-To: <1438676218-11310-1-git-send-email-jamesjj.liao@mediatek.com>
References: <1438676218-11310-1-git-send-email-jamesjj.liao@mediatek.com>
Message-ID: <1438676218-11310-8-git-send-email-jamesjj.liao@mediatek.com>

Most multimedia subsystem clocks will be accessed by multiple
drivers, so it's a better way to manage these clocks in CCF.
This patch adds clock support for MM, IMG, VDEC, VENC and VENC_LT
subsystems.

Signed-off-by: James Liao <jamesjj.liao at mediatek.com>
---
 drivers/clk/mediatek/clk-mt8173.c      | 267 +++++++++++++++++++++++++++++++++
 include/dt-bindings/clock/mt8173-clk.h |  97 +++++++++++-
 2 files changed, 361 insertions(+), 3 deletions(-)

diff --git a/drivers/clk/mediatek/clk-mt8173.c b/drivers/clk/mediatek/clk-mt8173.c
index f37ace6..05335e5 100644
--- a/drivers/clk/mediatek/clk-mt8173.c
+++ b/drivers/clk/mediatek/clk-mt8173.c
@@ -25,6 +25,10 @@ static DEFINE_SPINLOCK(mt8173_clk_lock);
 static const struct mtk_fixed_clk fixed_clks[] __initconst = {
 	FIXED_CLK(CLK_TOP_CLKPH_MCK_O, "clkph_mck_o", "clk26m", 400 * MHZ),
 	FIXED_CLK(CLK_TOP_USB_SYSPLL_125M, "usb_syspll_125m", "clk26m", 125 * MHZ),
+	FIXED_CLK(CLK_TOP_DSI0_DIG, "dsi0_dig", "clk26m", 130 * MHZ),
+	FIXED_CLK(CLK_TOP_DSI1_DIG, "dsi1_dig", "clk26m", 130 * MHZ),
+	FIXED_CLK(CLK_TOP_LVDS_PXL, "lvds_pxl", "lvdspll", 148.5 * MHZ),
+	FIXED_CLK(CLK_TOP_LVDS_CTS, "lvds_cts", "lvdspll", 51.975 * MHZ),
 };
 
 static const struct mtk_fixed_factor top_divs[] __initconst = {
@@ -697,6 +701,183 @@ static const struct mtk_composite peri_clks[] __initconst = {
 	MUX(CLK_PERI_UART3_SEL, "uart3_ck_sel", uart_ck_sel_parents, 0x40c, 3, 1),
 };
 
+static const struct mtk_gate_regs cg_regs_4_8_0 __initconst = {
+	.set_ofs = 0x0004,
+	.clr_ofs = 0x0008,
+	.sta_ofs = 0x0000,
+};
+
+#define GATE_IMG(_id, _name, _parent, _shift) {			\
+		.id = _id,					\
+		.name = _name,					\
+		.parent_name = _parent,				\
+		.regs = &cg_regs_4_8_0,				\
+		.shift = _shift,				\
+		.ops = &mtk_clk_gate_ops_setclr,		\
+	}
+
+static const struct mtk_gate img_clks[] __initconst = {
+	GATE_IMG(CLK_IMG_LARB2_SMI, "img_larb2_smi", "mm_sel", 0),
+	GATE_IMG(CLK_IMG_CAM_SMI, "img_cam_smi", "mm_sel", 5),
+	GATE_IMG(CLK_IMG_CAM_CAM, "img_cam_cam", "mm_sel", 6),
+	GATE_IMG(CLK_IMG_SEN_TG, "img_sen_tg", "camtg_sel", 7),
+	GATE_IMG(CLK_IMG_SEN_CAM, "img_sen_cam", "mm_sel", 8),
+	GATE_IMG(CLK_IMG_CAM_SV, "img_cam_sv", "mm_sel", 9),
+	GATE_IMG(CLK_IMG_FD, "img_fd", "mm_sel", 11),
+};
+
+static const struct mtk_gate_regs mm0_cg_regs __initconst = {
+	.set_ofs = 0x0104,
+	.clr_ofs = 0x0108,
+	.sta_ofs = 0x0100,
+};
+
+static const struct mtk_gate_regs mm1_cg_regs __initconst = {
+	.set_ofs = 0x0114,
+	.clr_ofs = 0x0118,
+	.sta_ofs = 0x0110,
+};
+
+#define GATE_MM0(_id, _name, _parent, _shift) {			\
+		.id = _id,					\
+		.name = _name,					\
+		.parent_name = _parent,				\
+		.regs = &mm0_cg_regs,				\
+		.shift = _shift,				\
+		.ops = &mtk_clk_gate_ops_setclr,		\
+	}
+
+#define GATE_MM1(_id, _name, _parent, _shift) {			\
+		.id = _id,					\
+		.name = _name,					\
+		.parent_name = _parent,				\
+		.regs = &mm1_cg_regs,				\
+		.shift = _shift,				\
+		.ops = &mtk_clk_gate_ops_setclr,		\
+	}
+
+static const struct mtk_gate mm_clks[] __initconst = {
+	/* MM0 */
+	GATE_MM0(CLK_MM_SMI_COMMON, "mm_smi_common", "mm_sel", 0),
+	GATE_MM0(CLK_MM_SMI_LARB0, "mm_smi_larb0", "mm_sel", 1),
+	GATE_MM0(CLK_MM_CAM_MDP, "mm_cam_mdp", "mm_sel", 2),
+	GATE_MM0(CLK_MM_MDP_RDMA0, "mm_mdp_rdma0", "mm_sel", 3),
+	GATE_MM0(CLK_MM_MDP_RDMA1, "mm_mdp_rdma1", "mm_sel", 4),
+	GATE_MM0(CLK_MM_MDP_RSZ0, "mm_mdp_rsz0", "mm_sel", 5),
+	GATE_MM0(CLK_MM_MDP_RSZ1, "mm_mdp_rsz1", "mm_sel", 6),
+	GATE_MM0(CLK_MM_MDP_RSZ2, "mm_mdp_rsz2", "mm_sel", 7),
+	GATE_MM0(CLK_MM_MDP_TDSHP0, "mm_mdp_tdshp0", "mm_sel", 8),
+	GATE_MM0(CLK_MM_MDP_TDSHP1, "mm_mdp_tdshp1", "mm_sel", 9),
+	GATE_MM0(CLK_MM_MDP_WDMA, "mm_mdp_wdma", "mm_sel", 11),
+	GATE_MM0(CLK_MM_MDP_WROT0, "mm_mdp_wrot0", "mm_sel", 12),
+	GATE_MM0(CLK_MM_MDP_WROT1, "mm_mdp_wrot1", "mm_sel", 13),
+	GATE_MM0(CLK_MM_FAKE_ENG, "mm_fake_eng", "mm_sel", 14),
+	GATE_MM0(CLK_MM_MUTEX_32K, "mm_mutex_32k", "rtc_sel", 15),
+	GATE_MM0(CLK_MM_DISP_OVL0, "mm_disp_ovl0", "mm_sel", 16),
+	GATE_MM0(CLK_MM_DISP_OVL1, "mm_disp_ovl1", "mm_sel", 17),
+	GATE_MM0(CLK_MM_DISP_RDMA0, "mm_disp_rdma0", "mm_sel", 18),
+	GATE_MM0(CLK_MM_DISP_RDMA1, "mm_disp_rdma1", "mm_sel", 19),
+	GATE_MM0(CLK_MM_DISP_RDMA2, "mm_disp_rdma2", "mm_sel", 20),
+	GATE_MM0(CLK_MM_DISP_WDMA0, "mm_disp_wdma0", "mm_sel", 21),
+	GATE_MM0(CLK_MM_DISP_WDMA1, "mm_disp_wdma1", "mm_sel", 22),
+	GATE_MM0(CLK_MM_DISP_COLOR0, "mm_disp_color0", "mm_sel", 23),
+	GATE_MM0(CLK_MM_DISP_COLOR1, "mm_disp_color1", "mm_sel", 24),
+	GATE_MM0(CLK_MM_DISP_AAL, "mm_disp_aal", "mm_sel", 25),
+	GATE_MM0(CLK_MM_DISP_GAMMA, "mm_disp_gamma", "mm_sel", 26),
+	GATE_MM0(CLK_MM_DISP_UFOE, "mm_disp_ufoe", "mm_sel", 27),
+	GATE_MM0(CLK_MM_DISP_SPLIT0, "mm_disp_split0", "mm_sel", 28),
+	GATE_MM0(CLK_MM_DISP_SPLIT1, "mm_disp_split1", "mm_sel", 29),
+	GATE_MM0(CLK_MM_DISP_MERGE, "mm_disp_merge", "mm_sel", 30),
+	GATE_MM0(CLK_MM_DISP_OD, "mm_disp_od", "mm_sel", 31),
+	/* MM1 */
+	GATE_MM1(CLK_MM_DISP_PWM0MM, "mm_disp_pwm0mm", "mm_sel", 0),
+	GATE_MM1(CLK_MM_DISP_PWM026M, "mm_disp_pwm026m", "pwm_sel", 1),
+	GATE_MM1(CLK_MM_DISP_PWM1MM, "mm_disp_pwm1mm", "mm_sel", 2),
+	GATE_MM1(CLK_MM_DISP_PWM126M, "mm_disp_pwm126m", "pwm_sel", 3),
+	GATE_MM1(CLK_MM_DSI0_ENGINE, "mm_dsi0_engine", "mm_sel", 4),
+	GATE_MM1(CLK_MM_DSI0_DIGITAL, "mm_dsi0_digital", "dsi0_dig", 5),
+	GATE_MM1(CLK_MM_DSI1_ENGINE, "mm_dsi1_engine", "mm_sel", 6),
+	GATE_MM1(CLK_MM_DSI1_DIGITAL, "mm_dsi1_digital", "dsi1_dig", 7),
+	GATE_MM1(CLK_MM_DPI_PIXEL, "mm_dpi_pixel", "dpi0_sel", 8),
+	GATE_MM1(CLK_MM_DPI_ENGINE, "mm_dpi_engine", "mm_sel", 9),
+	GATE_MM1(CLK_MM_DPI1_PIXEL, "mm_dpi1_pixel", "lvds_pxl", 10),
+	GATE_MM1(CLK_MM_DPI1_ENGINE, "mm_dpi1_engine", "mm_sel", 11),
+	GATE_MM1(CLK_MM_HDMI_PIXEL, "mm_hdmi_pixel", "dpi0_sel", 12),
+	GATE_MM1(CLK_MM_HDMI_PLLCK, "mm_hdmi_pllck", "hdmi_sel", 13),
+	GATE_MM1(CLK_MM_HDMI_AUDIO, "mm_hdmi_audio", "apll1", 14),
+	GATE_MM1(CLK_MM_HDMI_SPDIF, "mm_hdmi_spdif", "apll2", 15),
+	GATE_MM1(CLK_MM_LVDS_PIXEL, "mm_lvds_pixel", "lvds_pxl", 16),
+	GATE_MM1(CLK_MM_LVDS_CTS, "mm_lvds_cts", "lvds_cts", 17),
+	GATE_MM1(CLK_MM_SMI_LARB4, "mm_smi_larb4", "mm_sel", 18),
+	GATE_MM1(CLK_MM_HDMI_HDCP, "mm_hdmi_hdcp", "hdcp_sel", 19),
+	GATE_MM1(CLK_MM_HDMI_HDCP24M, "mm_hdmi_hdcp24m", "hdcp_24m_sel", 20),
+};
+
+static const struct mtk_gate_regs vdec0_cg_regs __initconst = {
+	.set_ofs = 0x0000,
+	.clr_ofs = 0x0004,
+	.sta_ofs = 0x0000,
+};
+
+static const struct mtk_gate_regs vdec1_cg_regs __initconst = {
+	.set_ofs = 0x0008,
+	.clr_ofs = 0x000c,
+	.sta_ofs = 0x0008,
+};
+
+#define GATE_VDEC0(_id, _name, _parent, _shift) {		\
+		.id = _id,					\
+		.name = _name,					\
+		.parent_name = _parent,				\
+		.regs = &vdec0_cg_regs,				\
+		.shift = _shift,				\
+		.ops = &mtk_clk_gate_ops_setclr_inv,		\
+	}
+
+#define GATE_VDEC1(_id, _name, _parent, _shift) {		\
+		.id = _id,					\
+		.name = _name,					\
+		.parent_name = _parent,				\
+		.regs = &vdec1_cg_regs,				\
+		.shift = _shift,				\
+		.ops = &mtk_clk_gate_ops_setclr_inv,		\
+	}
+
+static const struct mtk_gate vdec_clks[] __initconst = {
+	GATE_VDEC0(CLK_VDEC_CKEN, "vdec_cken", "vdec_sel", 0),
+	GATE_VDEC1(CLK_VDEC_LARB_CKEN, "vdec_larb_cken", "mm_sel", 0),
+};
+
+#define GATE_VENC(_id, _name, _parent, _shift) {		\
+		.id = _id,					\
+		.name = _name,					\
+		.parent_name = _parent,				\
+		.regs = &cg_regs_4_8_0,				\
+		.shift = _shift,				\
+		.ops = &mtk_clk_gate_ops_setclr_inv,		\
+	}
+
+static const struct mtk_gate venc_clks[] __initconst = {
+	GATE_VENC(CLK_VENC_CKE0, "venc_cke0", "mm_sel", 0),
+	GATE_VENC(CLK_VENC_CKE1, "venc_cke1", "venc_sel", 4),
+	GATE_VENC(CLK_VENC_CKE2, "venc_cke2", "venc_sel", 8),
+	GATE_VENC(CLK_VENC_CKE3, "venc_cke3", "venc_sel", 12),
+};
+
+#define GATE_VENCLT(_id, _name, _parent, _shift) {		\
+		.id = _id,					\
+		.name = _name,					\
+		.parent_name = _parent,				\
+		.regs = &cg_regs_4_8_0,				\
+		.shift = _shift,				\
+		.ops = &mtk_clk_gate_ops_setclr_inv,		\
+	}
+
+static const struct mtk_gate venclt_clks[] __initconst = {
+	GATE_VENCLT(CLK_VENCLT_CKE0, "venclt_cke0", "mm_sel", 0),
+	GATE_VENCLT(CLK_VENCLT_CKE1, "venclt_cke1", "venclt_sel", 4),
+};
+
 static struct clk_onecell_data *mt8173_top_clk_data __initdata;
 static struct clk_onecell_data *mt8173_pll_clk_data __initdata;
 
@@ -841,3 +1022,89 @@ static void __init mtk_apmixedsys_init(struct device_node *node)
 }
 CLK_OF_DECLARE(mtk_apmixedsys, "mediatek,mt8173-apmixedsys",
 		mtk_apmixedsys_init);
+
+static void __init mtk_imgsys_init(struct device_node *node)
+{
+	struct clk_onecell_data *clk_data;
+	int r;
+
+	clk_data = mtk_alloc_clk_data(CLK_IMG_NR_CLK);
+
+	mtk_clk_register_gates(node, img_clks, ARRAY_SIZE(img_clks),
+						clk_data);
+
+	r = of_clk_add_provider(node, of_clk_src_onecell_get, clk_data);
+
+	if (r)
+		pr_err("%s(): could not register clock provider: %d\n",
+			__func__, r);
+}
+CLK_OF_DECLARE(mtk_imgsys, "mediatek,mt8173-imgsys", mtk_imgsys_init);
+
+static void __init mtk_mmsys_init(struct device_node *node)
+{
+	struct clk_onecell_data *clk_data;
+	int r;
+
+	clk_data = mtk_alloc_clk_data(CLK_MM_NR_CLK);
+
+	mtk_clk_register_gates(node, mm_clks, ARRAY_SIZE(mm_clks),
+						clk_data);
+
+	r = of_clk_add_provider(node, of_clk_src_onecell_get, clk_data);
+	if (r)
+		pr_err("%s(): could not register clock provider: %d\n",
+			__func__, r);
+}
+CLK_OF_DECLARE(mtk_mmsys, "mediatek,mt8173-mmsys", mtk_mmsys_init);
+
+static void __init mtk_vdecsys_init(struct device_node *node)
+{
+	struct clk_onecell_data *clk_data;
+	int r;
+
+	clk_data = mtk_alloc_clk_data(CLK_VDEC_NR_CLK);
+
+	mtk_clk_register_gates(node, vdec_clks, ARRAY_SIZE(vdec_clks),
+						clk_data);
+
+	r = of_clk_add_provider(node, of_clk_src_onecell_get, clk_data);
+	if (r)
+		pr_err("%s(): could not register clock provider: %d\n",
+			__func__, r);
+}
+CLK_OF_DECLARE(mtk_vdecsys, "mediatek,mt8173-vdecsys", mtk_vdecsys_init);
+
+static void __init mtk_vencsys_init(struct device_node *node)
+{
+	struct clk_onecell_data *clk_data;
+	int r;
+
+	clk_data = mtk_alloc_clk_data(CLK_VENC_NR_CLK);
+
+	mtk_clk_register_gates(node, venc_clks, ARRAY_SIZE(venc_clks),
+						clk_data);
+
+	r = of_clk_add_provider(node, of_clk_src_onecell_get, clk_data);
+	if (r)
+		pr_err("%s(): could not register clock provider: %d\n",
+			__func__, r);
+}
+CLK_OF_DECLARE(mtk_vencsys, "mediatek,mt8173-vencsys", mtk_vencsys_init);
+
+static void __init mtk_vencltsys_init(struct device_node *node)
+{
+	struct clk_onecell_data *clk_data;
+	int r;
+
+	clk_data = mtk_alloc_clk_data(CLK_VENCLT_NR_CLK);
+
+	mtk_clk_register_gates(node, venclt_clks, ARRAY_SIZE(venclt_clks),
+						clk_data);
+
+	r = of_clk_add_provider(node, of_clk_src_onecell_get, clk_data);
+	if (r)
+		pr_err("%s(): could not register clock provider: %d\n",
+			__func__, r);
+}
+CLK_OF_DECLARE(mtk_vencltsys, "mediatek,mt8173-vencltsys", mtk_vencltsys_init);
diff --git a/include/dt-bindings/clock/mt8173-clk.h b/include/dt-bindings/clock/mt8173-clk.h
index 7230c38..87820ee 100644
--- a/include/dt-bindings/clock/mt8173-clk.h
+++ b/include/dt-bindings/clock/mt8173-clk.h
@@ -153,12 +153,16 @@
 #define CLK_TOP_I2S2_M_SEL		135
 #define CLK_TOP_I2S3_M_SEL		136
 #define CLK_TOP_I2S3_B_SEL		137
-#define CLK_TOP_NR_CLK			138
+#define CLK_TOP_DSI0_DIG		138
+#define CLK_TOP_DSI1_DIG		139
+#define CLK_TOP_LVDS_PXL		140
+#define CLK_TOP_LVDS_CTS		141
+#define CLK_TOP_NR_CLK			142
 
 /* APMIXED_SYS */
 
-#define CLK_APMIXED_ARMCA15PLL	1
-#define CLK_APMIXED_ARMCA7PLL	2
+#define CLK_APMIXED_ARMCA15PLL		1
+#define CLK_APMIXED_ARMCA7PLL		2
 #define CLK_APMIXED_MAINPLL		3
 #define CLK_APMIXED_UNIVPLL		4
 #define CLK_APMIXED_MMPLL		5
@@ -231,4 +235,91 @@
 #define CLK_PERI_UART3_SEL		39
 #define CLK_PERI_NR_CLK			40
 
+/* IMG_SYS */
+
+#define CLK_IMG_LARB2_SMI		1
+#define CLK_IMG_CAM_SMI			2
+#define CLK_IMG_CAM_CAM			3
+#define CLK_IMG_SEN_TG			4
+#define CLK_IMG_SEN_CAM			5
+#define CLK_IMG_CAM_SV			6
+#define CLK_IMG_FD			7
+#define CLK_IMG_NR_CLK			8
+
+/* MM_SYS */
+
+#define CLK_MM_SMI_COMMON		1
+#define CLK_MM_SMI_LARB0		2
+#define CLK_MM_CAM_MDP			3
+#define CLK_MM_MDP_RDMA0		4
+#define CLK_MM_MDP_RDMA1		5
+#define CLK_MM_MDP_RSZ0			6
+#define CLK_MM_MDP_RSZ1			7
+#define CLK_MM_MDP_RSZ2			8
+#define CLK_MM_MDP_TDSHP0		9
+#define CLK_MM_MDP_TDSHP1		10
+#define CLK_MM_MDP_WDMA			11
+#define CLK_MM_MDP_WROT0		12
+#define CLK_MM_MDP_WROT1		13
+#define CLK_MM_FAKE_ENG			14
+#define CLK_MM_MUTEX_32K		15
+#define CLK_MM_DISP_OVL0		16
+#define CLK_MM_DISP_OVL1		17
+#define CLK_MM_DISP_RDMA0		18
+#define CLK_MM_DISP_RDMA1		19
+#define CLK_MM_DISP_RDMA2		20
+#define CLK_MM_DISP_WDMA0		21
+#define CLK_MM_DISP_WDMA1		22
+#define CLK_MM_DISP_COLOR0		23
+#define CLK_MM_DISP_COLOR1		24
+#define CLK_MM_DISP_AAL			25
+#define CLK_MM_DISP_GAMMA		26
+#define CLK_MM_DISP_UFOE		27
+#define CLK_MM_DISP_SPLIT0		28
+#define CLK_MM_DISP_SPLIT1		29
+#define CLK_MM_DISP_MERGE		30
+#define CLK_MM_DISP_OD			31
+#define CLK_MM_DISP_PWM0MM		32
+#define CLK_MM_DISP_PWM026M		33
+#define CLK_MM_DISP_PWM1MM		34
+#define CLK_MM_DISP_PWM126M		35
+#define CLK_MM_DSI0_ENGINE		36
+#define CLK_MM_DSI0_DIGITAL		37
+#define CLK_MM_DSI1_ENGINE		38
+#define CLK_MM_DSI1_DIGITAL		39
+#define CLK_MM_DPI_PIXEL		40
+#define CLK_MM_DPI_ENGINE		41
+#define CLK_MM_DPI1_PIXEL		42
+#define CLK_MM_DPI1_ENGINE		43
+#define CLK_MM_HDMI_PIXEL		44
+#define CLK_MM_HDMI_PLLCK		45
+#define CLK_MM_HDMI_AUDIO		46
+#define CLK_MM_HDMI_SPDIF		47
+#define CLK_MM_LVDS_PIXEL		48
+#define CLK_MM_LVDS_CTS			49
+#define CLK_MM_SMI_LARB4		50
+#define CLK_MM_HDMI_HDCP		51
+#define CLK_MM_HDMI_HDCP24M		52
+#define CLK_MM_NR_CLK			53
+
+/* VDEC_SYS */
+
+#define CLK_VDEC_CKEN			1
+#define CLK_VDEC_LARB_CKEN		2
+#define CLK_VDEC_NR_CLK			3
+
+/* VENC_SYS */
+
+#define CLK_VENC_CKE0			1
+#define CLK_VENC_CKE1			2
+#define CLK_VENC_CKE2			3
+#define CLK_VENC_CKE3			4
+#define CLK_VENC_NR_CLK			5
+
+/* VENCLT_SYS */
+
+#define CLK_VENCLT_CKE0			1
+#define CLK_VENCLT_CKE1			2
+#define CLK_VENCLT_NR_CLK		3
+
 #endif /* _DT_BINDINGS_CLK_MT8173_H */
-- 
1.8.1.1.dirty



From jamesjj.liao at mediatek.com  Tue Aug  4 01:16:51 2015
From: jamesjj.liao at mediatek.com (James Liao)
Date: Tue, 4 Aug 2015 16:16:51 +0800
Subject: [PATCH v6 2/9] clk: mediatek: Remove unused code from MT8173.
In-Reply-To: <1438676218-11310-1-git-send-email-jamesjj.liao@mediatek.com>
References: <1438676218-11310-1-git-send-email-jamesjj.liao@mediatek.com>
Message-ID: <1438676218-11310-3-git-send-email-jamesjj.liao@mediatek.com>

Remove unused header files from MT8173, and remove unused
keywords from function declaration.

Signed-off-by: James Liao <jamesjj.liao at mediatek.com>
---
 drivers/clk/mediatek/clk-mt8173.c | 2 --
 drivers/clk/mediatek/clk-mtk.h    | 4 ++--
 2 files changed, 2 insertions(+), 4 deletions(-)

diff --git a/drivers/clk/mediatek/clk-mt8173.c b/drivers/clk/mediatek/clk-mt8173.c
index 80871e2..13aa432 100644
--- a/drivers/clk/mediatek/clk-mt8173.c
+++ b/drivers/clk/mediatek/clk-mt8173.c
@@ -14,8 +14,6 @@
 
 #include <linux/of.h>
 #include <linux/of_address.h>
-#include <linux/slab.h>
-#include <linux/mfd/syscon.h>
 
 #include "clk-mtk.h"
 #include "clk-gate.h"
diff --git a/drivers/clk/mediatek/clk-mtk.h b/drivers/clk/mediatek/clk-mtk.h
index 9dda9d8..740fe5e 100644
--- a/drivers/clk/mediatek/clk-mtk.h
+++ b/drivers/clk/mediatek/clk-mtk.h
@@ -41,7 +41,7 @@ struct mtk_fixed_factor {
 		.div = _div,				\
 	}
 
-extern void mtk_clk_register_factors(const struct mtk_fixed_factor *clks,
+void mtk_clk_register_factors(const struct mtk_fixed_factor *clks,
 		int num, struct clk_onecell_data *clk_data);
 
 struct mtk_composite {
@@ -152,7 +152,7 @@ struct mtk_pll_data {
 	int pcw_shift;
 };
 
-void __init mtk_clk_register_plls(struct device_node *node,
+void mtk_clk_register_plls(struct device_node *node,
 		const struct mtk_pll_data *plls, int num_plls,
 		struct clk_onecell_data *clk_data);
 
-- 
1.8.1.1.dirty



From jamesjj.liao at mediatek.com  Tue Aug  4 01:16:57 2015
From: jamesjj.liao at mediatek.com (James Liao)
Date: Tue, 4 Aug 2015 16:16:57 +0800
Subject: [PATCH v6 8/9] clk: mediatek: Add USB clock support in MT8173
 APMIXEDSYS
In-Reply-To: <1438676218-11310-1-git-send-email-jamesjj.liao@mediatek.com>
References: <1438676218-11310-1-git-send-email-jamesjj.liao@mediatek.com>
Message-ID: <1438676218-11310-9-git-send-email-jamesjj.liao@mediatek.com>

Add REF2USB_TX clock support into MT8173 APMIXEDSYS. This clock
is needed by USB 3.0.

Signed-off-by: James Liao <jamesjj.liao at mediatek.com>
---
 drivers/clk/mediatek/Makefile          |   2 +-
 drivers/clk/mediatek/clk-apmixed.c     | 107 +++++++++++++++++++++++++++++++++
 drivers/clk/mediatek/clk-mt8173.c      |  47 +++++++++++++++
 drivers/clk/mediatek/clk-mtk.h         |   3 +
 drivers/clk/mediatek/clk-pll.c         |   7 +--
 include/dt-bindings/clock/mt8173-clk.h |   3 +-
 6 files changed, 161 insertions(+), 8 deletions(-)
 create mode 100644 drivers/clk/mediatek/clk-apmixed.c

diff --git a/drivers/clk/mediatek/Makefile b/drivers/clk/mediatek/Makefile
index 8e4b2a4..95fdfac 100644
--- a/drivers/clk/mediatek/Makefile
+++ b/drivers/clk/mediatek/Makefile
@@ -1,4 +1,4 @@
-obj-y += clk-mtk.o clk-pll.o clk-gate.o
+obj-y += clk-mtk.o clk-pll.o clk-gate.o clk-apmixed.o
 obj-$(CONFIG_RESET_CONTROLLER) += reset.o
 obj-y += clk-mt8135.o
 obj-y += clk-mt8173.o
diff --git a/drivers/clk/mediatek/clk-apmixed.c b/drivers/clk/mediatek/clk-apmixed.c
new file mode 100644
index 0000000..5303c59
--- /dev/null
+++ b/drivers/clk/mediatek/clk-apmixed.c
@@ -0,0 +1,107 @@
+/*
+ * Copyright (c) 2015 MediaTek Inc.
+ * Author: James Liao <jamesjj.liao at 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/delay.h>
+#include <linux/of_address.h>
+#include <linux/slab.h>
+
+#include "clk-mtk.h"
+
+#define REF2USB_TX_EN		BIT(0)
+#define REF2USB_TX_LPF_EN	BIT(1)
+#define REF2USB_TX_OUT_EN	BIT(2)
+#define REF2USB_EN_MASK		(REF2USB_TX_EN | REF2USB_TX_LPF_EN | \
+				 REF2USB_TX_OUT_EN)
+
+struct mtk_ref2usb_tx {
+	struct clk_hw	hw;
+	void __iomem	*base_addr;
+};
+
+static inline struct mtk_ref2usb_tx *to_mtk_ref2usb_tx(struct clk_hw *hw)
+{
+	return container_of(hw, struct mtk_ref2usb_tx, hw);
+}
+
+static int mtk_ref2usb_tx_is_prepared(struct clk_hw *hw)
+{
+	struct mtk_ref2usb_tx *tx = to_mtk_ref2usb_tx(hw);
+
+	return (readl(tx->base_addr) & REF2USB_EN_MASK) == REF2USB_EN_MASK;
+}
+
+static int mtk_ref2usb_tx_prepare(struct clk_hw *hw)
+{
+	struct mtk_ref2usb_tx *tx = to_mtk_ref2usb_tx(hw);
+	u32 val;
+
+	val = readl(tx->base_addr);
+
+	val |= REF2USB_TX_EN;
+	writel(val, tx->base_addr);
+	udelay(100);
+
+	val |= REF2USB_TX_LPF_EN;
+	writel(val, tx->base_addr);
+
+	val |= REF2USB_TX_OUT_EN;
+	writel(val, tx->base_addr);
+
+	return 0;
+}
+
+static void mtk_ref2usb_tx_unprepare(struct clk_hw *hw)
+{
+	struct mtk_ref2usb_tx *tx = to_mtk_ref2usb_tx(hw);
+	u32 val;
+
+	val = readl(tx->base_addr);
+	val &= ~REF2USB_EN_MASK;
+	writel(val, tx->base_addr);
+}
+
+static const struct clk_ops mtk_ref2usb_tx_ops = {
+	.is_prepared	= mtk_ref2usb_tx_is_prepared,
+	.prepare	= mtk_ref2usb_tx_prepare,
+	.unprepare	= mtk_ref2usb_tx_unprepare,
+};
+
+struct clk * __init mtk_clk_register_ref2usb_tx(const char *name,
+			const char *parent_name, void __iomem *reg)
+{
+	struct mtk_ref2usb_tx *tx;
+	struct clk_init_data init = {};
+	struct clk *clk;
+
+	tx = kzalloc(sizeof(*tx), GFP_KERNEL);
+	if (!tx)
+		return ERR_PTR(-ENOMEM);
+
+	tx->base_addr = reg;
+	tx->hw.init = &init;
+
+	init.name = name;
+	init.ops = &mtk_ref2usb_tx_ops;
+	init.parent_names = &parent_name;
+	init.num_parents = 1;
+
+	clk = clk_register(NULL, &tx->hw);
+
+	if (IS_ERR(clk)) {
+		pr_err("Failed to register clk %s: %ld\n", name, PTR_ERR(clk));
+		kfree(tx);
+	}
+
+	return clk;
+}
diff --git a/drivers/clk/mediatek/clk-mt8173.c b/drivers/clk/mediatek/clk-mt8173.c
index 05335e5..63662d0 100644
--- a/drivers/clk/mediatek/clk-mt8173.c
+++ b/drivers/clk/mediatek/clk-mt8173.c
@@ -969,6 +969,24 @@ static void __init mtk_pericfg_init(struct device_node *node)
 }
 CLK_OF_DECLARE(mtk_pericfg, "mediatek,mt8173-pericfg", mtk_pericfg_init);
 
+struct mtk_clk_usb {
+	int id;
+	const char *name;
+	const char *parent;
+	u32 reg_ofs;
+};
+
+#define APMIXED_USB(_id, _name, _parent, _reg_ofs) {			\
+		.id = _id,						\
+		.name = _name,						\
+		.parent = _parent,					\
+		.reg_ofs = _reg_ofs,					\
+	}
+
+static const struct mtk_clk_usb apmixed_usb[] __initconst = {
+	APMIXED_USB(CLK_APMIXED_REF2USB_TX, "ref2usb_tx", "clk26m", 0x8),
+};
+
 #define MT8173_PLL_FMAX		(3000UL * MHZ)
 
 #define CON0_MT8173_RST_BAR	BIT(24)
@@ -1011,6 +1029,15 @@ static const struct mtk_pll_data plls[] = {
 static void __init mtk_apmixedsys_init(struct device_node *node)
 {
 	struct clk_onecell_data *clk_data;
+	void __iomem *base;
+	struct clk *clk;
+	int r, i;
+
+	base = of_iomap(node, 0);
+	if (!base) {
+		pr_err("%s(): ioremap failed\n", __func__);
+		return;
+	}
 
 	mt8173_pll_clk_data = clk_data = mtk_alloc_clk_data(CLK_APMIXED_NR_CLK);
 	if (!clk_data)
@@ -1018,6 +1045,26 @@ static void __init mtk_apmixedsys_init(struct device_node *node)
 
 	mtk_clk_register_plls(node, plls, ARRAY_SIZE(plls), clk_data);
 
+	for (i = 0; i < ARRAY_SIZE(apmixed_usb); i++) {
+		const struct mtk_clk_usb *cku = &apmixed_usb[i];
+
+		clk = mtk_clk_register_ref2usb_tx(cku->name, cku->parent,
+					base + cku->reg_ofs);
+
+		if (IS_ERR(clk)) {
+			pr_err("Failed to register clk %s: %ld\n", cku->name,
+					PTR_ERR(clk));
+			continue;
+		}
+
+		clk_data->clks[cku->id] = clk;
+	}
+
+	r = of_clk_add_provider(node, of_clk_src_onecell_get, clk_data);
+	if (r)
+		pr_err("%s(): could not register clock provider: %d\n",
+			__func__, r);
+
 	mtk_clk_enable_critical();
 }
 CLK_OF_DECLARE(mtk_apmixedsys, "mediatek,mt8173-apmixedsys",
diff --git a/drivers/clk/mediatek/clk-mtk.h b/drivers/clk/mediatek/clk-mtk.h
index 32d4f55..cf19363 100644
--- a/drivers/clk/mediatek/clk-mtk.h
+++ b/drivers/clk/mediatek/clk-mtk.h
@@ -173,6 +173,9 @@ void mtk_clk_register_plls(struct device_node *node,
 		const struct mtk_pll_data *plls, int num_plls,
 		struct clk_onecell_data *clk_data);
 
+struct clk *mtk_clk_register_ref2usb_tx(const char *name,
+			const char *parent_name, void __iomem *reg);
+
 #ifdef CONFIG_RESET_CONTROLLER
 void mtk_register_reset_controller(struct device_node *np,
 			unsigned int num_regs, int regofs);
diff --git a/drivers/clk/mediatek/clk-pll.c b/drivers/clk/mediatek/clk-pll.c
index 44409e9..813f0c7 100644
--- a/drivers/clk/mediatek/clk-pll.c
+++ b/drivers/clk/mediatek/clk-pll.c
@@ -302,7 +302,7 @@ void __init mtk_clk_register_plls(struct device_node *node,
 		const struct mtk_pll_data *plls, int num_plls, struct clk_onecell_data *clk_data)
 {
 	void __iomem *base;
-	int r, i;
+	int i;
 	struct clk *clk;
 
 	base = of_iomap(node, 0);
@@ -324,9 +324,4 @@ void __init mtk_clk_register_plls(struct device_node *node,
 
 		clk_data->clks[pll->id] = clk;
 	}
-
-	r = of_clk_add_provider(node, of_clk_src_onecell_get, clk_data);
-	if (r)
-		pr_err("%s(): could not register clock provider: %d\n",
-			__func__, r);
 }
diff --git a/include/dt-bindings/clock/mt8173-clk.h b/include/dt-bindings/clock/mt8173-clk.h
index 87820ee..e3db63a 100644
--- a/include/dt-bindings/clock/mt8173-clk.h
+++ b/include/dt-bindings/clock/mt8173-clk.h
@@ -175,7 +175,8 @@
 #define CLK_APMIXED_APLL2		12
 #define CLK_APMIXED_LVDSPLL		13
 #define CLK_APMIXED_MSDCPLL2		14
-#define CLK_APMIXED_NR_CLK		15
+#define CLK_APMIXED_REF2USB_TX		15
+#define CLK_APMIXED_NR_CLK		16
 
 /* INFRA_SYS */
 
-- 
1.8.1.1.dirty



From michal.simek at xilinx.com  Tue Aug  4 01:18:54 2015
From: michal.simek at xilinx.com (Michal Simek)
Date: Tue, 4 Aug 2015 10:18:54 +0200
Subject: [RFCv3 1/4] docs: dts: Added documentation for Xilinx Zynq Reset
 Controller bindings.
In-Reply-To: <1438675772.3793.18.camel@pengutronix.de>
References: <1438305237-18497-1-git-send-email-moritz.fischer@ettus.com>
 <1438305237-18497-2-git-send-email-moritz.fischer@ettus.com>
 <1438675772.3793.18.camel@pengutronix.de>
Message-ID: <55C0756E.8050003@xilinx.com>

On 08/04/2015 10:09 AM, Philipp Zabel wrote:
> Hi Moritz,
> 
> Am Donnerstag, den 30.07.2015, 18:13 -0700 schrieb Moritz Fischer:
>> Signed-off-by: Moritz Fischer <moritz.fischer at ettus.com>
>> ---
>>  .../devicetree/bindings/reset/zynq-reset.txt       | 68 ++++++++++++++++++++++
>>  1 file changed, 68 insertions(+)
>>  create mode 100644 Documentation/devicetree/bindings/reset/zynq-reset.txt
>>
>> diff --git a/Documentation/devicetree/bindings/reset/zynq-reset.txt b/Documentation/devicetree/bindings/reset/zynq-reset.txt
>> new file mode 100644
>> index 0000000..498c037a
>> --- /dev/null
>> +++ b/Documentation/devicetree/bindings/reset/zynq-reset.txt
>> @@ -0,0 +1,68 @@
>> +Xilinx Zynq Reset Manager
>> +
>> +The Zynq AP-SoC has several different resets.
>> +
>> +See Chapter 26 of the Zynq TRM (UG585) for more information about Zynq resets.
>> +
>> +Required properties:
>> +- compatible: "xlnx,zynq-reset"
>> +- reg: SLCR offset and size taken via syscon <0x200 0x48>
>> +- syscon: <&slcr>
>> +  This should be a phandle to the Zynq's SLCR register.
> 
>                                                  ^ register singular?
> 
> I still think the syscon phandle property is superfluous,
> but I'm fine with keeping it for consistency.
> It could always be made optional later.

Great.

Philipp: I expect you want to take at least 1/4 and 3/4 via your tree.
I am fine if you also want to add 2/4 and 4/4 via your tree.
If you think that they should go via arm-soc please let me know and I
will add them to the queue.

Thanks,
Michal


From pebolle at tiscali.nl  Tue Aug  4 01:30:24 2015
From: pebolle at tiscali.nl (Paul Bolle)
Date: Tue, 04 Aug 2015 10:30:24 +0200
Subject: [RFC PATCH 2/3] mailbox: Hisilicon: add mailbox driver
In-Reply-To: <1438564390-28111-3-git-send-email-leo.yan@linaro.org>
References: <1438564390-28111-1-git-send-email-leo.yan@linaro.org>
 <1438564390-28111-3-git-send-email-leo.yan@linaro.org>
Message-ID: <1438677024.8734.24.camel@tiscali.nl>

(This RFC was part of this mornings catch of my crude mail filter. So,
for what it's worth, what follows are a few random comments for the few
things I'm able to spot.)

On ma, 2015-08-03 at 09:13 +0800, Leo Yan wrote:
> --- /dev/null
> +++ b/drivers/mailbox/hisilicon/Kconfig

> +config HISI_MBOX
> +	bool "Hisilicon's Mailbox"
> +	depends on ARCH_HISI || OF

ARCH_HISI is available on either ARM64 or ARM. ARM64 selects OF. On ARM
ARCH_HISI depends on ARCH_MULTIV7 which depends on ARCH_MULTIPLATFORM.
That selects USE_OF which on its turn selects OF.

So, HISI_MBOX implies OF, correct?

> +	help
> +	  Support for mailbox drivers on Hisilicon series of SoCs.
> +
> +config HI6220_MBOX
> +	tristate "Hi6220 Mailbox Controller"
> +	depends on HISI_MBOX
> +	help
> +	  An implementation of the hi6220 mailbox. It is used to send message
> +	  between application processors and MCU. Say Y here if you want to build
> +	  the Hi6220 mailbox controller driver.

> --- /dev/null
> +++ b/drivers/mailbox/hisilicon/common.c

> +int hisi_mbox_register(struct hisi_mbox_hw *mbox_hw)
> +{
> +	[...]
> +
> +	mbox->chan = devm_kzalloc(dev,
> +		mbox_hw->chan_num * sizeof(struct mbox_chan), GFP_KERNEL);
> +	if (!mbox)

	if (!mbox->chan)

> +		return -ENOMEM;
> +
> +	[...]
> +}

> --- /dev/null
> +++ b/drivers/mailbox/hisilicon/hi6220-mailbox.c

> +static struct platform_driver hi6220_mbox_driver = {
> +	.driver = {
> +		[...]
> +		.of_match_table = of_match_ptr(hi6220_mbox_of_match),

of_match_ptr(x) becomes NULL when CONFIG_OF is not defined. But I think
CONFIG_OF will always be defined, see above. So of_match_ptr() isn't per
se needed.

> +	},
> +	[...]
> +};

> +static int __init hi6220_mbox_init(void)
> +{
> +	return platform_driver_register(&hi6220_mbox_driver);
> +}
> +module_init(hi6220_mbox_init);
> +
> +static void __exit hi6220_mbox_exit(void)
> +{
> +	platform_driver_unregister(&hi6220_mbox_driver);
> +}
> +module_exit(hi6220_mbox_exit);

This could be flattened into one line:
    module_platform_driver(hi6220_mbox_driver);

Thanks,


Paul Bolle


From laurent.pinchart at ideasonboard.com  Tue Aug  4 01:33:55 2015
From: laurent.pinchart at ideasonboard.com (Laurent Pinchart)
Date: Tue, 04 Aug 2015 11:33:55 +0300
Subject: [PATCH v2] media: atmel-isi: parse the DT parameters for
 vsync/hsync/pixclock polarity
In-Reply-To: <1438670828-19845-1-git-send-email-josh.wu@atmel.com>
References: <1438670828-19845-1-git-send-email-josh.wu@atmel.com>
Message-ID: <1733630.bVGppG7AmL@avalon>

Hi Josh,

Thank you for the patch.

On Tuesday 04 August 2015 14:47:07 Josh Wu wrote:
> This patch will get the DT parameters of vsync/hsync/pixclock polarity, and
> pass to driver.
> 
> Also add a debug information for test purpose.
> 
> Signed-off-by: Josh Wu <josh.wu at atmel.com>
> ---
> 
> Changes in v2:
> - rewrite the debug message and add pix clock polarity setup thanks to
>   Laurent.
> - update the commit log.
> 
>  drivers/media/platform/soc_camera/atmel-isi.c | 12 ++++++++++++
>  1 file changed, 12 insertions(+)
> 
> diff --git a/drivers/media/platform/soc_camera/atmel-isi.c
> b/drivers/media/platform/soc_camera/atmel-isi.c index fead841..d6f8def
> 100644
> --- a/drivers/media/platform/soc_camera/atmel-isi.c
> +++ b/drivers/media/platform/soc_camera/atmel-isi.c
> @@ -1061,6 +1061,11 @@ static int isi_camera_set_bus_param(struct
> soc_camera_device *icd) if (common_flags & V4L2_MBUS_PCLK_SAMPLE_FALLING)
>  		cfg1 |= ISI_CFG1_PIXCLK_POL_ACTIVE_FALLING;
> 
> +	dev_dbg(icd->parent, "vsync active %s, hsync active %s, sampling on pix
> clock %s\n",

You forgot " edge" right before "\n" :-)

> +		common_flags & V4L2_MBUS_VSYNC_ACTIVE_LOW ? "low" : "high",
> +		common_flags & V4L2_MBUS_HSYNC_ACTIVE_LOW ? "low" : "high",
> +		common_flags & V4L2_MBUS_PCLK_SAMPLE_FALLING ? "falling" : "rising");
> +
>  	if (isi->pdata.has_emb_sync)
>  		cfg1 |= ISI_CFG1_EMB_SYNC;
>  	if (isi->pdata.full_mode)
> @@ -1148,6 +1153,13 @@ static int atmel_isi_parse_dt(struct atmel_isi *isi,
>  		return -EINVAL;
>  	}
> 
> +	if (ep.bus.parallel.flags & V4L2_MBUS_HSYNC_ACTIVE_LOW)
> +		isi->pdata.hsync_act_low = true;
> +	if (ep.bus.parallel.flags & V4L2_MBUS_VSYNC_ACTIVE_LOW)
> +		isi->pdata.vsync_act_low = true;
> +	if (ep.bus.parallel.flags & V4L2_MBUS_PCLK_SAMPLE_FALLING)
> +		isi->pdata.pclk_act_falling = true;
> +

How about has_emb_sync, which can be set from ep.bus_type ?

>  	return 0;
>  }

-- 
Regards,

Laurent Pinchart



From p.zabel at pengutronix.de  Tue Aug  4 01:38:01 2015
From: p.zabel at pengutronix.de (Philipp Zabel)
Date: Tue, 04 Aug 2015 10:38:01 +0200
Subject: [RFCv3 4/4] ARM: zynq: Select ARCH_HAS_RESET_CONTROLLER
In-Reply-To: <20150731164707.GF2650@xsjsorenbubuntu>
References: <1438305237-18497-1-git-send-email-moritz.fischer@ettus.com>
 <1438305237-18497-5-git-send-email-moritz.fischer@ettus.com>
 <55BB2D39.6000004@xilinx.com> <20150731164707.GF2650@xsjsorenbubuntu>
Message-ID: <1438677481.3793.22.camel@pengutronix.de>

Hi,

Am Freitag, den 31.07.2015, 09:47 -0700 schrieb S?ren Brinkmann:
> On Fri, 2015-07-31 at 10:09AM +0200, Michal Simek wrote:
[...]
> > Reviewed-by: Michal Simek <michal.simek at xilinx.com>
> Acked-by: S?ren Brinkmann <soren.brinkmann at xilinx.com>

I'll assume these apply to the whole series and queue patches 1 and 3.

best regards
Philipp



From public_timo.s at silentcreek.de  Tue Aug  4 01:38:19 2015
From: public_timo.s at silentcreek.de (Timo Sigurdsson)
Date: Tue,  4 Aug 2015 10:38:19 +0200 (CEST)
Subject: [PATCH] ARM: dts: sunxi: Raise minimum CPU voltage for sun7i-a20
 to a level all boards can supply
In-Reply-To: <20150803091300.GY2564@lukather>
References: <1438543386-7253-1-git-send-email-public_timo.s@silentcreek.de><20150803091300.GY2564@lukather>
Message-ID: <20150804083819.2F3EE6C83EF9@dd34104.kasserver.com>

Hi Maxime,

Maxime Ripard schrieb am 03.08.2015 11:13:
> On Sun, Aug 02, 2015 at 09:23:06PM +0200, Timo Sigurdsson wrote:
>> sun7i-a20.dtsi contains an cpufreq operating point at 0.9 volts. Most A20
>> boards
>> (or all?), however, do not allow the voltage to go below 1.0V. Thus, raise the
>> voltage for the lowest operating point to 1.0V so all boards can actually use
>> it.
> 
> This is not a property of a board, but is the actual limit documented
> by Allwinner for the A20. Some individual SoCs might have wider
> tolerances, but that's not a property of a board, it's really a
> property of a single SoC, and we cannot make any assumption on the
> board.

Thanks for the clarification. That was a misunderstanding on my side. I can 
update the commit message in a second version of the patch, but the actual
code change can be kept as is then, I guess.

> (and please make sure to run checkpatch before sending your patches)

Sorry about that. Will do when I post a second version of the patch.

Thanks,

Timo


From b20788 at freescale.com  Tue Aug  4 09:32:52 2015
From: b20788 at freescale.com (Anson Huang)
Date: Wed, 5 Aug 2015 00:32:52 +0800
Subject: [PATCH] ARM: imx: add cpuidle support for i.mx6ul
Message-ID: <1438705972-3082-1-git-send-email-b20788@freescale.com>

This patch introduces an independent cpuidle driver for
i.MX6UL, totally 3 levels of cpuidle are supported as below:

1. ARM WFI;
2. SOC in WAIT mode;
3. SOC in WAIT mode + ARM power off.

Signed-off-by: Anson Huang <b20788 at freescale.com>
---
 arch/arm/mach-imx/Makefile         |   1 +
 arch/arm/mach-imx/cpuidle-imx6ul.c | 106 +++++++++++++++++++++++++++++++++++++
 arch/arm/mach-imx/cpuidle.h        |   5 ++
 arch/arm/mach-imx/mach-imx6ul.c    |   8 +++
 4 files changed, 120 insertions(+)
 create mode 100644 arch/arm/mach-imx/cpuidle-imx6ul.c

diff --git a/arch/arm/mach-imx/Makefile b/arch/arm/mach-imx/Makefile
index fb689d8..1d7df9c 100644
--- a/arch/arm/mach-imx/Makefile
+++ b/arch/arm/mach-imx/Makefile
@@ -28,6 +28,7 @@ obj-$(CONFIG_SOC_IMX5) += cpuidle-imx5.o
 obj-$(CONFIG_SOC_IMX6Q) += cpuidle-imx6q.o
 obj-$(CONFIG_SOC_IMX6SL) += cpuidle-imx6sl.o
 obj-$(CONFIG_SOC_IMX6SX) += cpuidle-imx6sx.o
+obj-$(CONFIG_SOC_IMX6UL) += cpuidle-imx6ul.o
 endif
 
 ifdef CONFIG_SND_IMX_SOC
diff --git a/arch/arm/mach-imx/cpuidle-imx6ul.c b/arch/arm/mach-imx/cpuidle-imx6ul.c
new file mode 100644
index 0000000..93793a1
--- /dev/null
+++ b/arch/arm/mach-imx/cpuidle-imx6ul.c
@@ -0,0 +1,106 @@
+/*
+ * Copyright (C) 2015 Freescale Semiconductor, Inc.
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License version 2 as
+ * published by the Free Software Foundation.
+ */
+
+#include <linux/cpuidle.h>
+#include <linux/cpu_pm.h>
+#include <linux/module.h>
+#include <asm/cacheflush.h>
+#include <asm/cpuidle.h>
+#include <asm/suspend.h>
+
+#include "common.h"
+#include "cpuidle.h"
+
+static int imx6ul_idle_finish(unsigned long val)
+{
+	flush_cache_all();
+	cpu_do_idle();
+
+	return 0;
+}
+
+static int imx6ul_enter_wait(struct cpuidle_device *dev,
+			    struct cpuidle_driver *drv, int index)
+{
+	imx6_set_lpm(WAIT_UNCLOCKED);
+
+	switch (index) {
+	case 1:
+		cpu_do_idle();
+		break;
+	case 2:
+		imx6_enable_rbc(true);
+		imx_gpc_set_arm_power_in_lpm(true);
+		imx_set_cpu_jump(0, v7_cpu_resume);
+		/* Need to notify there is a cpu pm operation. */
+		cpu_pm_enter();
+		cpu_cluster_pm_enter();
+
+		cpu_suspend(0, imx6ul_idle_finish);
+
+		cpu_cluster_pm_exit();
+		cpu_pm_exit();
+		imx_gpc_set_arm_power_in_lpm(false);
+		imx6_enable_rbc(false);
+		break;
+	default:
+		break;
+	}
+
+	imx6_set_lpm(WAIT_CLOCKED);
+
+	return index;
+}
+
+static struct cpuidle_driver imx6ul_cpuidle_driver = {
+	.name = "imx6ul_cpuidle",
+	.owner = THIS_MODULE,
+	.states = {
+		/* WFI */
+		ARM_CPUIDLE_WFI_STATE,
+		/* WAIT */
+		{
+			.exit_latency = 50,
+			.target_residency = 75,
+			.flags = CPUIDLE_FLAG_TIMER_STOP,
+			.enter = imx6ul_enter_wait,
+			.name = "WAIT",
+			.desc = "Clock off",
+		},
+		/* WAIT + ARM power off  */
+		{
+			/*
+			 * ARM gating 31us * 5 + RBC clear 65us
+			 * and some margin for SW execution, here set it
+			 * to 300us.
+			 */
+			.exit_latency = 300,
+			.target_residency = 500,
+			.enter = imx6ul_enter_wait,
+			.name = "LOW-POWER-IDLE",
+			.desc = "ARM power off",
+		},
+	},
+	.state_count = 3,
+	.safe_state_index = 0,
+};
+
+int __init imx6ul_cpuidle_init(void)
+{
+	imx6_enable_rbc(false);
+	/*
+	 * set ARM power up/down timing to the fastest,
+	 * sw2iso and sw can be set to one 32K cycle = 31us
+	 * except for power up sw2iso which need to be
+	 * larger than LDO ramp up time.
+	 */
+	imx_gpc_set_arm_power_up_timing(2, 1);
+	imx_gpc_set_arm_power_down_timing(1, 1);
+
+	return cpuidle_register(&imx6ul_cpuidle_driver, NULL);
+}
diff --git a/arch/arm/mach-imx/cpuidle.h b/arch/arm/mach-imx/cpuidle.h
index f914012..4dcf71d 100644
--- a/arch/arm/mach-imx/cpuidle.h
+++ b/arch/arm/mach-imx/cpuidle.h
@@ -15,6 +15,7 @@ extern int imx5_cpuidle_init(void);
 extern int imx6q_cpuidle_init(void);
 extern int imx6sl_cpuidle_init(void);
 extern int imx6sx_cpuidle_init(void);
+extern int imx6ul_cpuidle_init(void);
 #else
 static inline int imx5_cpuidle_init(void)
 {
@@ -32,4 +33,8 @@ static inline int imx6sx_cpuidle_init(void)
 {
 	return 0;
 }
+static inline int imx6ul_cpuidle_init(void)
+{
+	return 0;
+}
 #endif
diff --git a/arch/arm/mach-imx/mach-imx6ul.c b/arch/arm/mach-imx/mach-imx6ul.c
index f206506..0f4b95c 100644
--- a/arch/arm/mach-imx/mach-imx6ul.c
+++ b/arch/arm/mach-imx/mach-imx6ul.c
@@ -11,6 +11,7 @@
 #include <asm/mach/map.h>
 
 #include "common.h"
+#include "cpuidle.h"
 
 static void __init imx6ul_init_machine(void)
 {
@@ -29,6 +30,12 @@ static void __init imx6ul_init_irq(void)
 	imx_init_revision_from_anatop();
 	imx_src_init();
 	irqchip_init();
+	imx6_pm_ccm_init("fsl,imx6ul-ccm");
+}
+
+static void __init imx6ul_init_late(void)
+{
+	imx6ul_cpuidle_init();
 }
 
 static const char *imx6ul_dt_compat[] __initconst = {
@@ -40,4 +47,5 @@ DT_MACHINE_START(IMX6UL, "Freescale i.MX6 Ultralite (Device Tree)")
 	.init_irq	= imx6ul_init_irq,
 	.init_machine	= imx6ul_init_machine,
 	.dt_compat	= imx6ul_dt_compat,
+	.init_late	= imx6ul_init_late,
 MACHINE_END
-- 
1.9.1



From josh.wu at atmel.com  Tue Aug  4 01:41:45 2015
From: josh.wu at atmel.com (Josh Wu)
Date: Tue, 4 Aug 2015 16:41:45 +0800
Subject: [PATCH v2] media: atmel-isi: parse the DT parameters for
 vsync/hsync/pixclock polarity
In-Reply-To: <1733630.bVGppG7AmL@avalon>
References: <1438670828-19845-1-git-send-email-josh.wu@atmel.com>
 <1733630.bVGppG7AmL@avalon>
Message-ID: <55C07AC9.70700@atmel.com>

Hi, Laurent

On 8/4/2015 4:33 PM, Laurent Pinchart wrote:
> Hi Josh,
>
> Thank you for the patch.
>
> On Tuesday 04 August 2015 14:47:07 Josh Wu wrote:
>> This patch will get the DT parameters of vsync/hsync/pixclock polarity, and
>> pass to driver.
>>
>> Also add a debug information for test purpose.
>>
>> Signed-off-by: Josh Wu <josh.wu at atmel.com>
>> ---
>>
>> Changes in v2:
>> - rewrite the debug message and add pix clock polarity setup thanks to
>>    Laurent.
>> - update the commit log.
>>
>>   drivers/media/platform/soc_camera/atmel-isi.c | 12 ++++++++++++
>>   1 file changed, 12 insertions(+)
>>
>> diff --git a/drivers/media/platform/soc_camera/atmel-isi.c
>> b/drivers/media/platform/soc_camera/atmel-isi.c index fead841..d6f8def
>> 100644
>> --- a/drivers/media/platform/soc_camera/atmel-isi.c
>> +++ b/drivers/media/platform/soc_camera/atmel-isi.c
>> @@ -1061,6 +1061,11 @@ static int isi_camera_set_bus_param(struct
>> soc_camera_device *icd) if (common_flags & V4L2_MBUS_PCLK_SAMPLE_FALLING)
>>   		cfg1 |= ISI_CFG1_PIXCLK_POL_ACTIVE_FALLING;
>>
>> +	dev_dbg(icd->parent, "vsync active %s, hsync active %s, sampling on pix
>> clock %s\n",
> You forgot " edge" right before "\n" :-)

oops, I missed the word.

>
>> +		common_flags & V4L2_MBUS_VSYNC_ACTIVE_LOW ? "low" : "high",
>> +		common_flags & V4L2_MBUS_HSYNC_ACTIVE_LOW ? "low" : "high",
>> +		common_flags & V4L2_MBUS_PCLK_SAMPLE_FALLING ? "falling" : "rising");
>> +
>>   	if (isi->pdata.has_emb_sync)
>>   		cfg1 |= ISI_CFG1_EMB_SYNC;
>>   	if (isi->pdata.full_mode)
>> @@ -1148,6 +1153,13 @@ static int atmel_isi_parse_dt(struct atmel_isi *isi,
>>   		return -EINVAL;
>>   	}
>>
>> +	if (ep.bus.parallel.flags & V4L2_MBUS_HSYNC_ACTIVE_LOW)
>> +		isi->pdata.hsync_act_low = true;
>> +	if (ep.bus.parallel.flags & V4L2_MBUS_VSYNC_ACTIVE_LOW)
>> +		isi->pdata.vsync_act_low = true;
>> +	if (ep.bus.parallel.flags & V4L2_MBUS_PCLK_SAMPLE_FALLING)
>> +		isi->pdata.pclk_act_falling = true;
>> +
> How about has_emb_sync, which can be set from ep.bus_type ?

yes, right. I forgot this as well.
I'll generate a new version of this patch soon. Thanks for the catching.

Best Regards,
Josh Wu

>
>>   	return 0;
>>   }



From leo.yan at linaro.org  Tue Aug  4 01:49:30 2015
From: leo.yan at linaro.org (Leo Yan)
Date: Tue, 4 Aug 2015 16:49:30 +0800
Subject: [RFC PATCH 2/3] mailbox: Hisilicon: add mailbox driver
In-Reply-To: <1438677024.8734.24.camel@tiscali.nl>
References: <1438564390-28111-1-git-send-email-leo.yan@linaro.org>
 <1438564390-28111-3-git-send-email-leo.yan@linaro.org>
 <1438677024.8734.24.camel@tiscali.nl>
Message-ID: <20150804084930.GA27609@leoy-linaro>

Hi Paul,

On Tue, Aug 04, 2015 at 10:30:24AM +0200, Paul Bolle wrote:
> (This RFC was part of this mornings catch of my crude mail filter. So,
> for what it's worth, what follows are a few random comments for the few
> things I'm able to spot.)
> 
> On ma, 2015-08-03 at 09:13 +0800, Leo Yan wrote:
> > --- /dev/null
> > +++ b/drivers/mailbox/hisilicon/Kconfig
> 
> > +config HISI_MBOX
> > +	bool "Hisilicon's Mailbox"
> > +	depends on ARCH_HISI || OF
> 
> ARCH_HISI is available on either ARM64 or ARM. ARM64 selects OF. On ARM
> ARCH_HISI depends on ARCH_MULTIV7 which depends on ARCH_MULTIPLATFORM.
> That selects USE_OF which on its turn selects OF.
> 
> So, HISI_MBOX implies OF, correct?

Exactly, will simply use "depends on ARCH_HISI".

> > +	help
> > +	  Support for mailbox drivers on Hisilicon series of SoCs.
> > +
> > +config HI6220_MBOX
> > +	tristate "Hi6220 Mailbox Controller"
> > +	depends on HISI_MBOX
> > +	help
> > +	  An implementation of the hi6220 mailbox. It is used to send message
> > +	  between application processors and MCU. Say Y here if you want to build
> > +	  the Hi6220 mailbox controller driver.
> 
> > --- /dev/null
> > +++ b/drivers/mailbox/hisilicon/common.c
> 
> > +int hisi_mbox_register(struct hisi_mbox_hw *mbox_hw)
> > +{
> > +	[...]
> > +
> > +	mbox->chan = devm_kzalloc(dev,
> > +		mbox_hw->chan_num * sizeof(struct mbox_chan), GFP_KERNEL);
> > +	if (!mbox)
> 
> 	if (!mbox->chan)

Will fix.

> > +		return -ENOMEM;
> > +
> > +	[...]
> > +}
> 
> > --- /dev/null
> > +++ b/drivers/mailbox/hisilicon/hi6220-mailbox.c
> 
> > +static struct platform_driver hi6220_mbox_driver = {
> > +	.driver = {
> > +		[...]
> > +		.of_match_table = of_match_ptr(hi6220_mbox_of_match),
> 
> of_match_ptr(x) becomes NULL when CONFIG_OF is not defined. But I think
> CONFIG_OF will always be defined, see above. So of_match_ptr() isn't per
> se needed.

Will fix.

> > +	},
> > +	[...]
> > +};
> 
> > +static int __init hi6220_mbox_init(void)
> > +{
> > +	return platform_driver_register(&hi6220_mbox_driver);
> > +}
> > +module_init(hi6220_mbox_init);
> > +
> > +static void __exit hi6220_mbox_exit(void)
> > +{
> > +	platform_driver_unregister(&hi6220_mbox_driver);
> > +}
> > +module_exit(hi6220_mbox_exit);
> 
> This could be flattened into one line:
>     module_platform_driver(hi6220_mbox_driver);

Will refine. And thanks a lot for your review.

Thanks,
Leo Yan


From public_timo.s at silentcreek.de  Tue Aug  4 01:51:30 2015
From: public_timo.s at silentcreek.de (Timo Sigurdsson)
Date: Tue,  4 Aug 2015 10:51:30 +0200 (CEST)
Subject: [linux-sunxi] [PATCH] ARM: dts: sunxi: Raise minimum CPU voltage
 for sun7i-a20 to a level all boards can supply
In-Reply-To: <20150803093420.GC2564@lukather>
References: <1438543386-7253-1-git-send-email-public_timo.s@silentcreek.de>
 <CAGRGNgV6b9yt2HnB2x2Wyc05KEahoX-Y+mVhxsryztcfA36H1g@mail.gmail.com>
 <CAGb2v67o-=_cL2RWfXJ+3C86zfQ_1b5DYRi3_zwvwy6su6+gdw@mail.gmail.com>
 <CAGRGNgXH90m9h0DDejd5MTf8enduGFQ8dPKrRhmc8Z6y_PaC1w@mail.gmail.com>
 <20150803090352.621CC6C80865@dd34104.kasserver.com><20150803093420.GC2564@lukather>
Message-ID: <20150804085130.602FA6C83EF9@dd34104.kasserver.com>

Hi Maxime,

Maxime Ripard schrieb am 03.08.2015 11:34:

> On Mon, Aug 03, 2015 at 11:03:52AM +0200, Timo Sigurdsson wrote:
>> Julian Calaby schrieb am 03.08.2015 06:22:
>> > My only real objection here is are there boards that can go down to
>> > 0.9v and if so, won't this change make them less power efficient in
>> > the almost-idle case? And are those power savings enough to justify
>> > not accepting this patch?
>> 
>> It will probably make those boards less power efficient, yes. On the
>> other hand, boards that have their CPU regulator set to min. 1.0V might
>> also draw more power because the lowest frequency is not available, 
>> even though the savings due to frequency are likely to be lower than
>> the savings due to voltage.
> 
> Guys, isn't this whole discussion a bit moot? We're not doing any kind
> of power management but cpufreq, so maybe there's a lot more to do
> before we actually can have these kind of arguments?
> 
> Plus this OPP has never been used anyway, so this patch is not going
> to increase the power consumption either.

You are right. When I wrote that, I was under the impression that the
Olinuxino Lime 2 board at least used this setting since it has has a cpu
regulator defined to go as low as 0.7V. But now I checked again and see
the regulator is not referenced in the cpu node, so I guess cpufreq
doesn't use it. So, this discussion was really hypothetical and more
importantly, as you mentioned, it's an out-of-spec opp that shouldn't
be supported anyway.

Thanks,

Timo


From heiko at sntech.de  Tue Aug  4 01:53:15 2015
From: heiko at sntech.de (Heiko =?ISO-8859-1?Q?St=FCbner?=)
Date: Tue, 04 Aug 2015 10:53:15 +0200
Subject: [PATCH v3 2/2] pinctrl: rockchip: only enable gpio clock when it
 setting
In-Reply-To: <1438670487-27598-2-git-send-email-hl@rock-chips.com>
References: <1438670487-27598-1-git-send-email-hl@rock-chips.com>
 <1438670487-27598-2-git-send-email-hl@rock-chips.com>
Message-ID: <4658505.Inxl9yYzep@diego>

Hi,

Am Dienstag, 4. August 2015, 14:41:27 schrieb Lin Huang:
> gpio can keep state even the clock disable, for save power
> consumption, only enable gpio clock when it setting
> 
> Signed-off-by: Heiko Stuebner <heiko at sntech.de>
> Signed-off-by: Lin Huang <hl at rock-chips.com>
> ---
> Changes in v3:
> -match author and Signed-off-by name

I guess this patch has the same problem as Stephen pointed out for the clk-one 
with the Signed-off-bys. As you did most of the development here, you should 
probably simply remove my Signed-off-by.

You can add a
Reviewed-by: Heiko Stuebner <heiko at sntech.de>

instead. Two additional nits below.


> 
>  drivers/pinctrl/pinctrl-rockchip.c | 57
> +++++++++++++++++++++++++++++++++++--- 1 file changed, 53 insertions(+), 4
> deletions(-)
> 
> diff --git a/drivers/pinctrl/pinctrl-rockchip.c
> b/drivers/pinctrl/pinctrl-rockchip.c index cc2843a..70a4539 100644
> --- a/drivers/pinctrl/pinctrl-rockchip.c
> +++ b/drivers/pinctrl/pinctrl-rockchip.c
> @@ -945,6 +945,7 @@ static int _rockchip_pmx_gpio_set_direction(struct
> gpio_chip *chip, if (ret < 0)
>  		return ret;
> 
> +	clk_enable(bank->clk);
>  	spin_lock_irqsave(&bank->slock, flags);
> 
>  	data = readl_relaxed(bank->reg_base + GPIO_SWPORT_DDR);
> @@ -953,9 +954,11 @@ static int _rockchip_pmx_gpio_set_direction(struct
> gpio_chip *chip, data |= BIT(pin);
>  	else
>  		data &= ~BIT(pin);
> +

unrelated new blank line


>  	writel_relaxed(data, bank->reg_base + GPIO_SWPORT_DDR);
> 
>  	spin_unlock_irqrestore(&bank->slock, flags);
> +	clk_disable(bank->clk);
> 
>  	return 0;
>  }
> @@ -1389,6 +1392,7 @@ static void rockchip_gpio_set(struct gpio_chip *gc,
> unsigned offset, int value) unsigned long flags;
>  	u32 data;
> 
> +	clk_enable(bank->clk);
>  	spin_lock_irqsave(&bank->slock, flags);
> 
>  	data = readl(reg);
> @@ -1398,6 +1402,7 @@ static void rockchip_gpio_set(struct gpio_chip *gc,
> unsigned offset, int value) writel(data, reg);
> 
>  	spin_unlock_irqrestore(&bank->slock, flags);
> +	clk_disable(bank->clk);
>  }
> 
>  /*
> @@ -1409,7 +1414,9 @@ static int rockchip_gpio_get(struct gpio_chip *gc,
> unsigned offset) struct rockchip_pin_bank *bank = gc_to_pin_bank(gc);
>  	u32 data;
> 
> +	clk_enable(bank->clk);
>  	data = readl(bank->reg_base + GPIO_EXT_PORT);
> +	clk_disable(bank->clk);
>  	data >>= offset;
>  	data &= 1;
>  	return data;
> @@ -1546,6 +1553,7 @@ static int rockchip_irq_set_type(struct irq_data *d,
> unsigned int type) if (ret < 0)
>  		return ret;
> 
> +	clk_enable(bank->clk);
>  	spin_lock_irqsave(&bank->slock, flags);
> 
>  	data = readl_relaxed(bank->reg_base + GPIO_SWPORT_DDR);
> @@ -1603,6 +1611,7 @@ static int rockchip_irq_set_type(struct irq_data *d,
> unsigned int type) default:
>  		irq_gc_unlock(gc);
>  		spin_unlock_irqrestore(&bank->slock, flags);
> +		clk_disable(bank->clk);
>  		return -EINVAL;
>  	}
> 
> @@ -1611,6 +1620,7 @@ static int rockchip_irq_set_type(struct irq_data *d,
> unsigned int type)
> 
>  	irq_gc_unlock(gc);
>  	spin_unlock_irqrestore(&bank->slock, flags);
> +	clk_disable(bank->clk);
> 
>  	return 0;
>  }
> @@ -1620,8 +1630,10 @@ static void rockchip_irq_suspend(struct irq_data *d)
>  	struct irq_chip_generic *gc = irq_data_get_irq_chip_data(d);
>  	struct rockchip_pin_bank *bank = gc->private;
> 
> +	clk_enable(bank->clk);
>  	bank->saved_masks = irq_reg_readl(gc, GPIO_INTMASK);
>  	irq_reg_writel(gc, ~gc->wake_active, GPIO_INTMASK);
> +	clk_disable(bank->clk);
>  }
> 
>  static void rockchip_irq_resume(struct irq_data *d)
> @@ -1629,7 +1641,27 @@ static void rockchip_irq_resume(struct irq_data *d)
>  	struct irq_chip_generic *gc = irq_data_get_irq_chip_data(d);
>  	struct rockchip_pin_bank *bank = gc->private;
> 
> +	clk_enable(bank->clk);
>  	irq_reg_writel(gc, bank->saved_masks, GPIO_INTMASK);
> +	clk_disable(bank->clk);
> +}
> +
> +static void rockchip_irq_gc_mask_clr_bit(struct irq_data *d)
> +{
> +	struct irq_chip_generic *gc = irq_data_get_irq_chip_data(d);
> +	struct rockchip_pin_bank *bank = gc->private;
> +
> +	clk_enable(bank->clk);
> +	irq_gc_mask_clr_bit(d);
> +}
> +
> +void rockchip_irq_gc_mask_set_bit(struct irq_data *d)
> +{
> +	struct irq_chip_generic *gc = irq_data_get_irq_chip_data(d);
> +	struct rockchip_pin_bank *bank = gc->private;
> +
> +	irq_gc_mask_set_bit(d);
> +	clk_disable(bank->clk);
>  }
> 
>  static int rockchip_interrupts_register(struct platform_device *pdev,
> @@ -1640,7 +1672,7 @@ static int rockchip_interrupts_register(struct
> platform_device *pdev, unsigned int clr = IRQ_NOREQUEST | IRQ_NOPROBE |
> IRQ_NOAUTOEN;
>  	struct irq_chip_generic *gc;
>  	int ret;
> -	int i;
> +	int i, j;
> 
>  	for (i = 0; i < ctrl->nr_banks; ++i, ++bank) {
>  		if (!bank->valid) {
> @@ -1649,11 +1681,19 @@ static int rockchip_interrupts_register(struct
> platform_device *pdev, continue;
>  		}
> 
> +		ret = clk_enable(bank->clk);
> +		if (ret) {
> +			dev_err(&pdev->dev, "failed to enable clock for bank %s\n",
> +				bank->name);
> +			continue;
> +		}
> +
>  		bank->domain = irq_domain_add_linear(bank->of_node, 32,
>  						&irq_generic_chip_ops, NULL);
>  		if (!bank->domain) {
>  			dev_warn(&pdev->dev, "could not initialize irq domain for bank 
%s\n",
>  				 bank->name);
> +			clk_disable(bank->clk);
>  			continue;
>  		}
> 
> @@ -1664,6 +1704,7 @@ static int rockchip_interrupts_register(struct
> platform_device *pdev, dev_err(&pdev->dev, "could not alloc generic chips
> for bank %s\n", bank->name);
>  			irq_domain_remove(bank->domain);
> +			clk_disable(bank->clk);
>  			continue;
>  		}
> 
> @@ -1681,8 +1722,9 @@ static int rockchip_interrupts_register(struct
> platform_device *pdev, gc->chip_types[0].regs.mask = GPIO_INTMASK;
>  		gc->chip_types[0].regs.ack = GPIO_PORTS_EOI;
>  		gc->chip_types[0].chip.irq_ack = irq_gc_ack_set_bit;
> -		gc->chip_types[0].chip.irq_mask = irq_gc_mask_set_bit;
> -		gc->chip_types[0].chip.irq_unmask = irq_gc_mask_clr_bit;
> +		gc->chip_types[0].chip.irq_mask = rockchip_irq_gc_mask_set_bit;
> +		gc->chip_types[0].chip.irq_unmask =
> +						  rockchip_irq_gc_mask_clr_bit;
>  		gc->chip_types[0].chip.irq_set_wake = irq_gc_set_wake;
>  		gc->chip_types[0].chip.irq_suspend = rockchip_irq_suspend;
>  		gc->chip_types[0].chip.irq_resume = rockchip_irq_resume;
> @@ -1691,6 +1733,12 @@ static int rockchip_interrupts_register(struct
> platform_device *pdev,
> 
>  		irq_set_chained_handler_and_data(bank->irq,
>  						 rockchip_irq_demux, bank);
> +
> +		/* map the gpio irqs here, when the clock is still running */
> +		for (j = 0 ; j < 32 ; j++)
> +			irq_create_mapping(bank->domain, j);
> +
> +		clk_disable(bank->clk);
>  	}
> 
>  	return 0;
> @@ -1808,7 +1856,7 @@ static int rockchip_get_bank_data(struct
> rockchip_pin_bank *bank, if (IS_ERR(bank->clk))
>  		return PTR_ERR(bank->clk);
> 
> -	return clk_prepare_enable(bank->clk);
> +	return clk_prepare(bank->clk);
>  }
> 
>  static const struct of_device_id rockchip_pinctrl_dt_match[];
> @@ -1927,6 +1975,7 @@ static int __maybe_unused
> rockchip_pinctrl_suspend(struct device *dev) static int __maybe_unused
> rockchip_pinctrl_resume(struct device *dev) {
>  	struct rockchip_pinctrl *info = dev_get_drvdata(dev);
> +

this new blank looks unrelated


>  	int ret = regmap_write(info->regmap_base, RK3288_GRF_GPIO6C_IOMUX,
>  			       rk3288_grf_gpio6c_iomux |
>  			       GPIO6C6_SEL_WRITE_ENABLE);



From l.stach at pengutronix.de  Tue Aug  4 01:54:08 2015
From: l.stach at pengutronix.de (Lucas Stach)
Date: Tue, 04 Aug 2015 10:54:08 +0200
Subject: [PATCH] ARM: imx: add cpuidle support for i.mx6ul
In-Reply-To: <1438705972-3082-1-git-send-email-b20788@freescale.com>
References: <1438705972-3082-1-git-send-email-b20788@freescale.com>
Message-ID: <1438678448.2458.26.camel@pengutronix.de>

Am Mittwoch, den 05.08.2015, 00:32 +0800 schrieb Anson Huang:
> This patch introduces an independent cpuidle driver for
> i.MX6UL, totally 3 levels of cpuidle are supported as below:
> 
> 1. ARM WFI;
> 2. SOC in WAIT mode;
> 3. SOC in WAIT mode + ARM power off.
> 
> Signed-off-by: Anson Huang <b20788 at freescale.com>
> ---
>  arch/arm/mach-imx/Makefile         |   1 +
>  arch/arm/mach-imx/cpuidle-imx6ul.c | 106 +++++++++++++++++++++++++++++++++++++
>  arch/arm/mach-imx/cpuidle.h        |   5 ++
>  arch/arm/mach-imx/mach-imx6ul.c    |   8 +++
>  4 files changed, 120 insertions(+)
>  create mode 100644 arch/arm/mach-imx/cpuidle-imx6ul.c
> 
> diff --git a/arch/arm/mach-imx/Makefile b/arch/arm/mach-imx/Makefile
> index fb689d8..1d7df9c 100644
> --- a/arch/arm/mach-imx/Makefile
> +++ b/arch/arm/mach-imx/Makefile
> @@ -28,6 +28,7 @@ obj-$(CONFIG_SOC_IMX5) += cpuidle-imx5.o
>  obj-$(CONFIG_SOC_IMX6Q) += cpuidle-imx6q.o
>  obj-$(CONFIG_SOC_IMX6SL) += cpuidle-imx6sl.o
>  obj-$(CONFIG_SOC_IMX6SX) += cpuidle-imx6sx.o
> +obj-$(CONFIG_SOC_IMX6UL) += cpuidle-imx6ul.o
>  endif
>  
>  ifdef CONFIG_SND_IMX_SOC
> diff --git a/arch/arm/mach-imx/cpuidle-imx6ul.c b/arch/arm/mach-imx/cpuidle-imx6ul.c
> new file mode 100644
> index 0000000..93793a1
> --- /dev/null
> +++ b/arch/arm/mach-imx/cpuidle-imx6ul.c
> @@ -0,0 +1,106 @@
> +/*
> + * Copyright (C) 2015 Freescale Semiconductor, Inc.
> + *
> + * This program is free software; you can redistribute it and/or modify
> + * it under the terms of the GNU General Public License version 2 as
> + * published by the Free Software Foundation.
> + */
> +
> +#include <linux/cpuidle.h>
> +#include <linux/cpu_pm.h>
> +#include <linux/module.h>
> +#include <asm/cacheflush.h>
> +#include <asm/cpuidle.h>
> +#include <asm/suspend.h>
> +
> +#include "common.h"
> +#include "cpuidle.h"
> +
> +static int imx6ul_idle_finish(unsigned long val)
> +{
> +	flush_cache_all();
> +	cpu_do_idle();
> +
> +	return 0;
> +}
> +
> +static int imx6ul_enter_wait(struct cpuidle_device *dev,
> +			    struct cpuidle_driver *drv, int index)
> +{
> +	imx6_set_lpm(WAIT_UNCLOCKED);
> +
> +	switch (index) {
> +	case 1:
> +		cpu_do_idle();
> +		break;
> +	case 2:
> +		imx6_enable_rbc(true);
> +		imx_gpc_set_arm_power_in_lpm(true);
> +		imx_set_cpu_jump(0, v7_cpu_resume);
> +		/* Need to notify there is a cpu pm operation. */
> +		cpu_pm_enter();
> +		cpu_cluster_pm_enter();
> +
> +		cpu_suspend(0, imx6ul_idle_finish);
> +
> +		cpu_cluster_pm_exit();
> +		cpu_pm_exit();
> +		imx_gpc_set_arm_power_in_lpm(false);
> +		imx6_enable_rbc(false);
> +		break;
> +	default:
> +		break;
> +	}
> +
> +	imx6_set_lpm(WAIT_CLOCKED);
> +
> +	return index;
> +}
> +
> +static struct cpuidle_driver imx6ul_cpuidle_driver = {
> +	.name = "imx6ul_cpuidle",
> +	.owner = THIS_MODULE,
> +	.states = {
> +		/* WFI */
> +		ARM_CPUIDLE_WFI_STATE,
> +		/* WAIT */
> +		{
> +			.exit_latency = 50,
> +			.target_residency = 75,
> +			.flags = CPUIDLE_FLAG_TIMER_STOP,
> +			.enter = imx6ul_enter_wait,
> +			.name = "WAIT",
> +			.desc = "Clock off",
> +		},
> +		/* WAIT + ARM power off  */
> +		{
> +			/*
> +			 * ARM gating 31us * 5 + RBC clear 65us
> +			 * and some margin for SW execution, here set it
> +			 * to 300us.
> +			 */
> +			.exit_latency = 300,
> +			.target_residency = 500,

Why is ".flags = CPUIDLE_FLAG_TIMER_STOP," omitted here?

> +			.enter = imx6ul_enter_wait,
> +			.name = "LOW-POWER-IDLE",
> +			.desc = "ARM power off",
> +		},
> +	},
> +	.state_count = 3,
> +	.safe_state_index = 0,
> +};
> +
> +int __init imx6ul_cpuidle_init(void)
> +{
> +	imx6_enable_rbc(false);
> +	/*
> +	 * set ARM power up/down timing to the fastest,
> +	 * sw2iso and sw can be set to one 32K cycle = 31us
> +	 * except for power up sw2iso which need to be
> +	 * larger than LDO ramp up time.
> +	 */
> +	imx_gpc_set_arm_power_up_timing(2, 1);
> +	imx_gpc_set_arm_power_down_timing(1, 1);
> +
> +	return cpuidle_register(&imx6ul_cpuidle_driver, NULL);
> +}
> diff --git a/arch/arm/mach-imx/cpuidle.h b/arch/arm/mach-imx/cpuidle.h
> index f914012..4dcf71d 100644
> --- a/arch/arm/mach-imx/cpuidle.h
> +++ b/arch/arm/mach-imx/cpuidle.h
> @@ -15,6 +15,7 @@ extern int imx5_cpuidle_init(void);
>  extern int imx6q_cpuidle_init(void);
>  extern int imx6sl_cpuidle_init(void);
>  extern int imx6sx_cpuidle_init(void);
> +extern int imx6ul_cpuidle_init(void);
>  #else
>  static inline int imx5_cpuidle_init(void)
>  {
> @@ -32,4 +33,8 @@ static inline int imx6sx_cpuidle_init(void)
>  {
>  	return 0;
>  }
> +static inline int imx6ul_cpuidle_init(void)
> +{
> +	return 0;
> +}
>  #endif
> diff --git a/arch/arm/mach-imx/mach-imx6ul.c b/arch/arm/mach-imx/mach-imx6ul.c
> index f206506..0f4b95c 100644
> --- a/arch/arm/mach-imx/mach-imx6ul.c
> +++ b/arch/arm/mach-imx/mach-imx6ul.c
> @@ -11,6 +11,7 @@
>  #include <asm/mach/map.h>
>  
>  #include "common.h"
> +#include "cpuidle.h"
>  
>  static void __init imx6ul_init_machine(void)
>  {
> @@ -29,6 +30,12 @@ static void __init imx6ul_init_irq(void)
>  	imx_init_revision_from_anatop();
>  	imx_src_init();
>  	irqchip_init();
> +	imx6_pm_ccm_init("fsl,imx6ul-ccm");
> +}
> +
> +static void __init imx6ul_init_late(void)
> +{
> +	imx6ul_cpuidle_init();
>  }
>  
>  static const char *imx6ul_dt_compat[] __initconst = {
> @@ -40,4 +47,5 @@ DT_MACHINE_START(IMX6UL, "Freescale i.MX6 Ultralite (Device Tree)")
>  	.init_irq	= imx6ul_init_irq,
>  	.init_machine	= imx6ul_init_machine,
>  	.dt_compat	= imx6ul_dt_compat,
> +	.init_late	= imx6ul_init_late,
>  MACHINE_END

-- 
Pengutronix e.K.             | Lucas Stach                 |
Industrial Linux Solutions   | http://www.pengutronix.de/  |



From heiko at sntech.de  Tue Aug  4 01:54:06 2015
From: heiko at sntech.de (Heiko =?ISO-8859-1?Q?St=FCbner?=)
Date: Tue, 04 Aug 2015 10:54:06 +0200
Subject: [PATCH v3 1/2] clk: rockchip: add pclk_pd_pmu to the list of
 rk3288 critical clocks
In-Reply-To: <1438670487-27598-1-git-send-email-hl@rock-chips.com>
References: <1438670487-27598-1-git-send-email-hl@rock-chips.com>
Message-ID: <1588782.u2WKR6eVuV@diego>

Hi,

Am Dienstag, 4. August 2015, 14:41:26 schrieb Lin Huang:

I guess this patch then would need a

From: Heiko Stuebner <heiko at sntech.de>

at this point to override the author then.


> pclk_pd_pmu needs to keep running and with the upcoming gpio clock
> handling this is not always the case anymore. So add it to the list
> of critical clocks for now.
> 
> Signed-off-by: Heiko Stuebner <heiko at sntech.de>
> Signed-off-by: Lin Huang <hl at rock-chips.com>
> ---
> Changes in v3:
> -match the author and Signed-off-by name
> 
>  drivers/clk/rockchip/clk-rk3288.c | 1 +
>  1 file changed, 1 insertion(+)
> 
> diff --git a/drivers/clk/rockchip/clk-rk3288.c
> b/drivers/clk/rockchip/clk-rk3288.c index 0df5bae..9040878 100644
> --- a/drivers/clk/rockchip/clk-rk3288.c
> +++ b/drivers/clk/rockchip/clk-rk3288.c
> @@ -780,6 +780,7 @@ static const char *const rk3288_critical_clocks[]
> __initconst = { "aclk_cpu",
>  	"aclk_peri",
>  	"hclk_peri",
> +	"pclk_pd_pmu",
>  };
> 
>  #ifdef CONFIG_PM_SLEEP



From albeu at free.fr  Tue Aug  4 01:59:17 2015
From: albeu at free.fr (Alban Bedel)
Date: Tue,  4 Aug 2015 10:59:17 +0200
Subject: [PATCH v2] usb: ehci-platform: Fix using multiple controllers from OF
Message-ID: <1438678757-26582-1-git-send-email-albeu@free.fr>

When using OF defined controllers the platform data struct is shared
between all devices, so it can't be used for device specific settings.
However it is currently used for the OF properties
needs-reset-on-resume and has-transaction-translator.

To fix this issue move setting hcd->has_tt to the probe and
move pdata->reset_on_resume to the private data.

Signed-off-by: Alban Bedel <albeu at free.fr>
---
Changelog:
v2: * Use true instead of 1 to set boolean type
---
 drivers/usb/host/ehci-platform.c | 13 +++++++++----
 1 file changed, 9 insertions(+), 4 deletions(-)

diff --git a/drivers/usb/host/ehci-platform.c b/drivers/usb/host/ehci-platform.c
index 2593def..5c3c085 100644
--- a/drivers/usb/host/ehci-platform.c
+++ b/drivers/usb/host/ehci-platform.c
@@ -45,6 +45,7 @@ struct ehci_platform_priv {
 	struct reset_control *rst;
 	struct phy **phys;
 	int num_phys;
+	bool reset_on_resume;
 };
 
 static const char hcd_name[] = "ehci-platform";
@@ -56,7 +57,6 @@ static int ehci_platform_reset(struct usb_hcd *hcd)
 	struct ehci_hcd *ehci = hcd_to_ehci(hcd);
 	int retval;
 
-	hcd->has_tt = pdata->has_tt;
 	ehci->has_synopsys_hc_bug = pdata->has_synopsys_hc_bug;
 
 	if (pdata->pre_setup) {
@@ -193,11 +193,11 @@ static int ehci_platform_probe(struct platform_device *dev)
 
 		if (of_property_read_bool(dev->dev.of_node,
 					  "needs-reset-on-resume"))
-			pdata->reset_on_resume = 1;
+			priv->reset_on_resume = true;
 
 		if (of_property_read_bool(dev->dev.of_node,
 					  "has-transaction-translator"))
-			pdata->has_tt = 1;
+			hcd->has_tt = 1;
 
 		priv->num_phys = of_count_phandle_with_args(dev->dev.of_node,
 				"phys", "#phy-cells");
@@ -247,6 +247,10 @@ static int ehci_platform_probe(struct platform_device *dev)
 		ehci->big_endian_desc = 1;
 	if (pdata->big_endian_mmio)
 		ehci->big_endian_mmio = 1;
+	if (pdata->has_tt)
+		hcd->has_tt = 1;
+	if (pdata->reset_on_resume)
+		priv->reset_on_resume = true;
 
 #ifndef CONFIG_USB_EHCI_BIG_ENDIAN_MMIO
 	if (ehci->big_endian_mmio) {
@@ -359,6 +363,7 @@ static int ehci_platform_resume(struct device *dev)
 	struct usb_ehci_pdata *pdata = dev_get_platdata(dev);
 	struct platform_device *pdev =
 		container_of(dev, struct platform_device, dev);
+	struct ehci_platform_priv *priv = hcd_to_ehci_priv(hcd);
 
 	if (pdata->power_on) {
 		int err = pdata->power_on(pdev);
@@ -366,7 +371,7 @@ static int ehci_platform_resume(struct device *dev)
 			return err;
 	}
 
-	ehci_resume(hcd, pdata->reset_on_resume);
+	ehci_resume(hcd, priv->reset_on_resume);
 	return 0;
 }
 #endif /* CONFIG_PM_SLEEP */
-- 
2.0.0



From leo.yan at linaro.org  Tue Aug  4 02:00:59 2015
From: leo.yan at linaro.org (Leo Yan)
Date: Tue, 4 Aug 2015 17:00:59 +0800
Subject: [RFC PATCH 2/3] mailbox: Hisilicon: add mailbox driver
In-Reply-To: <20150804084930.GA27609@leoy-linaro>
References: <1438564390-28111-1-git-send-email-leo.yan@linaro.org>
 <1438564390-28111-3-git-send-email-leo.yan@linaro.org>
 <1438677024.8734.24.camel@tiscali.nl>
 <20150804084930.GA27609@leoy-linaro>
Message-ID: <20150804090059.GB27609@leoy-linaro>

Hi Paul,

On Tue, Aug 04, 2015 at 04:49:30PM +0800, Leo Yan wrote:
> On Tue, Aug 04, 2015 at 10:30:24AM +0200, Paul Bolle wrote:
> > (This RFC was part of this mornings catch of my crude mail filter. So,
> > for what it's worth, what follows are a few random comments for the few
> > things I'm able to spot.)

[...]

> > > +static int __init hi6220_mbox_init(void)
> > > +{
> > > +	return platform_driver_register(&hi6220_mbox_driver);
> > > +}
> > > +module_init(hi6220_mbox_init);
> > > +
> > > +static void __exit hi6220_mbox_exit(void)
> > > +{
> > > +	platform_driver_unregister(&hi6220_mbox_driver);
> > > +}
> > > +module_exit(hi6220_mbox_exit);
> > 
> > This could be flattened into one line:
> >     module_platform_driver(hi6220_mbox_driver);

Need clarify one thing: will modify to use core_initcall() for driver's
initialization; due another clock driver depends on this mailbox driver,
so mailbox init firstly with core_initcall() and use subsys_initcall()
for clock driver.

Thanks,
Leo Yan


From public_timo.s at silentcreek.de  Tue Aug  4 02:02:24 2015
From: public_timo.s at silentcreek.de (Timo Sigurdsson)
Date: Tue,  4 Aug 2015 11:02:24 +0200 (CEST)
Subject: [PATCH v2] ARM: dts: sunxi: Add regulators for LeMaker BananaPi
In-Reply-To: <20150803094723.GD2564@lukather>
References: <1438532305-5884-1-git-send-email-public_timo.s@silentcreek.de><20150803094723.GD2564@lukather>
Message-ID: <20150804090224.4B5676C83963@dd34104.kasserver.com>

Hi Maxime,

Maxime Ripard schrieb am 03.08.2015 11:47:
> What regulator provides the 3.3V regulator used in the rest of this DT
> then (MMC, GMAC) ?

For GMAC, there is a reg_gmac_3v3 defined in sun7i-a20-bananapi.dts [1].
MMC uses reg_vcc3v3 included from sunxi-common-regulators.dtsi. Am I
missing something? Is this not sufficient?


Thanks,

Timo

[1] https://git.kernel.org/cgit/linux/kernel/git/torvalds/linux.git/tree/arch/arm/boot/dts/sun7i-a20-bananapi.dts?id=v4.2-rc5#n78


From skarajga at visteon.com  Tue Aug  4 02:07:30 2015
From: skarajga at visteon.com (Karajgaonkar, Saurabh (S.))
Date: Tue, 4 Aug 2015 09:07:30 +0000
Subject: [PATCH 0/9] usb: Simplify return statements
Message-ID: <cover.1438678566.git.skarajga@visteon.com>

From: Saurabh Karajgaonkar <skarajga at visteon.com>

This patch series is created using simple_return.cocci coccinelle script.
It replaces the redundant instances where variable is first assigned
return value from a function call and then used in return statement,
by direct function call in the return statement.

Saurabh Karajgaonkar (9):
  usb: phy: phy-mxs-usb: Simplify return statement
  usb: phy: phy-keystone: Simplify return statement
  usb: musb: musb_dsps: Simplify return statement
  usb: host: ehci-st: Simplify return statement
  usb: host: oxu210hp-hcd: Simplify return statement
  usb: host: u132-hcd: Simplify return statement
  usb: host: xhci: Simplify return statement
  usb: serial: mxuport: Simplify return statement
  usb: misc: ftdi-elan: Simplify return statement

 drivers/usb/host/ehci-st.c      |  7 +------
 drivers/usb/host/oxu210hp-hcd.c |  7 +------
 drivers/usb/host/u132-hcd.c     | 27 +++++----------------------
 drivers/usb/host/xhci.c         |  6 +-----
 drivers/usb/misc/ftdi-elan.c    | 10 ++--------
 drivers/usb/musb/musb_dsps.c    |  6 +-----
 drivers/usb/phy/phy-keystone.c  |  6 +-----
 drivers/usb/phy/phy-mxs-usb.c   |  6 +-----
 drivers/usb/serial/mxuport.c    |  6 +-----
 9 files changed, 14 insertions(+), 67 deletions(-)

-- 
1.9.1


From skarajga at visteon.com  Tue Aug  4 02:08:35 2015
From: skarajga at visteon.com (Karajgaonkar, Saurabh (S.))
Date: Tue, 4 Aug 2015 09:08:35 +0000
Subject: [PATCH 1/9] usb: phy: phy-mxs-usb: Simplify return statement
In-Reply-To: <cover.1438678566.git.skarajga@visteon.com>
References: <cover.1438678566.git.skarajga@visteon.com>
Message-ID: <0e24e9030dc43d6191c74039faf79de49e45c191.1438678566.git.skarajga@visteon.com>

From: Saurabh Karajgaonkar <skarajga at visteon.com>

Replace redundant variable use in return statement.

Signed-off-by: Saurabh Karajgaonkar <skarajga at visteon.com>
---
 drivers/usb/phy/phy-mxs-usb.c | 6 +-----
 1 file changed, 1 insertion(+), 5 deletions(-)

diff --git a/drivers/usb/phy/phy-mxs-usb.c b/drivers/usb/phy/phy-mxs-usb.c
index 3fcc048..4d863eb 100644
--- a/drivers/usb/phy/phy-mxs-usb.c
+++ b/drivers/usb/phy/phy-mxs-usb.c
@@ -506,11 +506,7 @@ static int mxs_phy_probe(struct platform_device *pdev)
 
 	device_set_wakeup_capable(&pdev->dev, true);
 
-	ret = usb_add_phy_dev(&mxs_phy->phy);
-	if (ret)
-		return ret;
-
-	return 0;
+	return usb_add_phy_dev(&mxs_phy->phy);
 }
 
 static int mxs_phy_remove(struct platform_device *pdev)
-- 
1.9.1


From skarajga at visteon.com  Tue Aug  4 02:09:11 2015
From: skarajga at visteon.com (Karajgaonkar, Saurabh (S.))
Date: Tue, 4 Aug 2015 09:09:11 +0000
Subject: [PATCH 2/9] usb: phy: phy-keystone: Simplify return statement
In-Reply-To: <cover.1438678566.git.skarajga@visteon.com>
References: <cover.1438678566.git.skarajga@visteon.com>
Message-ID: <40402eeb0cd861569faf838efccc1ef4672da83c.1438678566.git.skarajga@visteon.com>

From: Saurabh Karajgaonkar <skarajga at visteon.com>

Replace redundant variable use in return statement.

Signed-off-by: Saurabh Karajgaonkar <skarajga at visteon.com>
---
 drivers/usb/phy/phy-keystone.c | 6 +-----
 1 file changed, 1 insertion(+), 5 deletions(-)

diff --git a/drivers/usb/phy/phy-keystone.c b/drivers/usb/phy/phy-keystone.c
index e0556f7..01d4e4c 100644
--- a/drivers/usb/phy/phy-keystone.c
+++ b/drivers/usb/phy/phy-keystone.c
@@ -96,11 +96,7 @@ static int keystone_usbphy_probe(struct platform_device *pdev)
 
 	platform_set_drvdata(pdev, k_phy);
 
-	ret = usb_add_phy_dev(&k_phy->usb_phy_gen.phy);
-	if (ret)
-		return ret;
-
-	return 0;
+	return usb_add_phy_dev(&k_phy->usb_phy_gen.phy);
 }
 
 static int keystone_usbphy_remove(struct platform_device *pdev)
-- 
1.9.1


From skarajga at visteon.com  Tue Aug  4 02:09:42 2015
From: skarajga at visteon.com (Karajgaonkar, Saurabh (S.))
Date: Tue, 4 Aug 2015 09:09:42 +0000
Subject: [PATCH 3/9] usb: musb: musb_dsps: Simplify return statement
In-Reply-To: <cover.1438678566.git.skarajga@visteon.com>
References: <cover.1438678566.git.skarajga@visteon.com>
Message-ID: <0484e5c9da0a2f46386c79115be618f228b42443.1438678566.git.skarajga@visteon.com>

From: Saurabh Karajgaonkar <skarajga at visteon.com>

Replace redundant variable use in return statement.

Signed-off-by: Saurabh Karajgaonkar <skarajga at visteon.com>
---
 drivers/usb/musb/musb_dsps.c | 6 +-----
 1 file changed, 1 insertion(+), 5 deletions(-)

diff --git a/drivers/usb/musb/musb_dsps.c b/drivers/usb/musb/musb_dsps.c
index 1334a3d..a0cfead 100644
--- a/drivers/usb/musb/musb_dsps.c
+++ b/drivers/usb/musb/musb_dsps.c
@@ -482,11 +482,7 @@ static int dsps_musb_init(struct musb *musb)
 		dsps_writeb(musb->mregs, MUSB_BABBLE_CTL, val);
 	}
 
-	ret = dsps_musb_dbg_init(musb, glue);
-	if (ret)
-		return ret;
-
-	return 0;
+	return dsps_musb_dbg_init(musb, glue);
 }
 
 static int dsps_musb_exit(struct musb *musb)
-- 
1.9.1


From skarajga at visteon.com  Tue Aug  4 02:10:09 2015
From: skarajga at visteon.com (Karajgaonkar, Saurabh (S.))
Date: Tue, 4 Aug 2015 09:10:09 +0000
Subject: [PATCH 4/9] usb: host: ehci-st: Simplify return statement
In-Reply-To: <cover.1438678566.git.skarajga@visteon.com>
References: <cover.1438678566.git.skarajga@visteon.com>
Message-ID: <29a173be5ace786d064ae14c02324fee42fee06c.1438678566.git.skarajga@visteon.com>

From: Saurabh Karajgaonkar <skarajga at visteon.com>

Replace redundant variable use in return statement.

Signed-off-by: Saurabh Karajgaonkar <skarajga at visteon.com>
---
 drivers/usb/host/ehci-st.c | 7 +------
 1 file changed, 1 insertion(+), 6 deletions(-)

diff --git a/drivers/usb/host/ehci-st.c b/drivers/usb/host/ehci-st.c
index 7e4bd39..b7c5cfa 100644
--- a/drivers/usb/host/ehci-st.c
+++ b/drivers/usb/host/ehci-st.c
@@ -54,7 +54,6 @@ static int st_ehci_platform_reset(struct usb_hcd *hcd)
 	struct platform_device *pdev = to_platform_device(hcd->self.controller);
 	struct usb_ehci_pdata *pdata = dev_get_platdata(&pdev->dev);
 	struct ehci_hcd *ehci = hcd_to_ehci(hcd);
-	int retval;
 	u32 threshold;
 
 	/* Set EHCI packet buffer IN/OUT threshold to 128 bytes */
@@ -62,11 +61,7 @@ static int st_ehci_platform_reset(struct usb_hcd *hcd)
 	writel(threshold, hcd->regs + AHB2STBUS_INSREG01);
 
 	ehci->caps = hcd->regs + pdata->caps_offset;
-	retval = ehci_setup(hcd);
-	if (retval)
-		return retval;
-
-	return 0;
+	return ehci_setup(hcd);
 }
 
 static int st_ehci_platform_power_on(struct platform_device *dev)
-- 
1.9.1


From skarajga at visteon.com  Tue Aug  4 02:10:35 2015
From: skarajga at visteon.com (Karajgaonkar, Saurabh (S.))
Date: Tue, 4 Aug 2015 09:10:35 +0000
Subject: [PATCH 5/9] usb: host: oxu210hp-hcd: Simplify return statement
In-Reply-To: <cover.1438678566.git.skarajga@visteon.com>
References: <cover.1438678566.git.skarajga@visteon.com>
Message-ID: <36c30f52509df9691c70ce6a2b2d0404d50681e9.1438678566.git.skarajga@visteon.com>

From: Saurabh Karajgaonkar <skarajga at visteon.com>

Replace redundant variable use in return statement.

Signed-off-by: Saurabh Karajgaonkar <skarajga at visteon.com>
---
 drivers/usb/host/oxu210hp-hcd.c | 7 +------
 1 file changed, 1 insertion(+), 6 deletions(-)

diff --git a/drivers/usb/host/oxu210hp-hcd.c b/drivers/usb/host/oxu210hp-hcd.c
index 6352f54..fe3bd1c 100644
--- a/drivers/usb/host/oxu210hp-hcd.c
+++ b/drivers/usb/host/oxu210hp-hcd.c
@@ -2670,7 +2670,6 @@ static int oxu_hcd_init(struct usb_hcd *hcd)
 static int oxu_reset(struct usb_hcd *hcd)
 {
 	struct oxu_hcd *oxu = hcd_to_oxu(hcd);
-	int ret;
 
 	spin_lock_init(&oxu->mem_lock);
 	INIT_LIST_HEAD(&oxu->urb_list);
@@ -2696,11 +2695,7 @@ static int oxu_reset(struct usb_hcd *hcd)
 	oxu->hcs_params = readl(&oxu->caps->hcs_params);
 	oxu->sbrn = 0x20;
 
-	ret = oxu_hcd_init(hcd);
-	if (ret)
-		return ret;
-
-	return 0;
+	return oxu_hcd_init(hcd);
 }
 
 static int oxu_run(struct usb_hcd *hcd)
-- 
1.9.1


From skarajga at visteon.com  Tue Aug  4 02:11:05 2015
From: skarajga at visteon.com (Karajgaonkar, Saurabh (S.))
Date: Tue, 4 Aug 2015 09:11:05 +0000
Subject: [PATCH 6/9] usb: host: u132-hcd: Simplify return statement
In-Reply-To: <cover.1438678566.git.skarajga@visteon.com>
References: <cover.1438678566.git.skarajga@visteon.com>
Message-ID: <4a709b250542c3af2783955f53f1e980b010082a.1438678566.git.skarajga@visteon.com>

From: Saurabh Karajgaonkar <skarajga at visteon.com>

Replace redundant variable use in return statement.

Signed-off-by: Saurabh Karajgaonkar <skarajga at visteon.com>
---
 drivers/usb/host/u132-hcd.c | 27 +++++----------------------
 1 file changed, 5 insertions(+), 22 deletions(-)

diff --git a/drivers/usb/host/u132-hcd.c b/drivers/usb/host/u132-hcd.c
index d516877..1cfb811 100644
--- a/drivers/usb/host/u132-hcd.c
+++ b/drivers/usb/host/u132-hcd.c
@@ -1542,11 +1542,8 @@ static int u132_periodic_reinit(struct u132 *u132)
 		(fit ^ FIT) | u132->hc_fminterval);
 	if (retval)
 		return retval;
-	retval = u132_write_pcimem(u132, periodicstart,
+	return u132_write_pcimem(u132, periodicstart,
 		((9 * fi) / 10) & 0x3fff);
-	if (retval)
-		return retval;
-	return 0;
 }
 
 static char *hcfs2string(int state)
@@ -2701,28 +2698,18 @@ static int u132_roothub_setportfeature(struct u132 *u132, u16 wValue,
 	if (wIndex == 0 || wIndex > u132->num_ports) {
 		return -EINVAL;
 	} else {
-		int retval;
 		int port_index = wIndex - 1;
 		struct u132_port *port = &u132->port[port_index];
 		port->Status &= ~(1 << wValue);
 		switch (wValue) {
 		case USB_PORT_FEAT_SUSPEND:
-			retval = u132_write_pcimem(u132,
+			return u132_write_pcimem(u132,
 				roothub.portstatus[port_index], RH_PS_PSS);
-			if (retval)
-				return retval;
-			return 0;
 		case USB_PORT_FEAT_POWER:
-			retval = u132_write_pcimem(u132,
+			return u132_write_pcimem(u132,
 				roothub.portstatus[port_index], RH_PS_PPS);
-			if (retval)
-				return retval;
-			return 0;
 		case USB_PORT_FEAT_RESET:
-			retval = u132_roothub_portreset(u132, port_index);
-			if (retval)
-				return retval;
-			return 0;
+			return u132_roothub_portreset(u132, port_index);
 		default:
 			return -EPIPE;
 		}
@@ -2737,7 +2724,6 @@ static int u132_roothub_clearportfeature(struct u132 *u132, u16 wValue,
 	} else {
 		int port_index = wIndex - 1;
 		u32 temp;
-		int retval;
 		struct u132_port *port = &u132->port[port_index];
 		port->Status &= ~(1 << wValue);
 		switch (wValue) {
@@ -2773,11 +2759,8 @@ static int u132_roothub_clearportfeature(struct u132 *u132, u16 wValue,
 		default:
 			return -EPIPE;
 		}
-		retval = u132_write_pcimem(u132, roothub.portstatus[port_index],
+		return u132_write_pcimem(u132, roothub.portstatus[port_index],
 			 temp);
-		if (retval)
-			return retval;
-		return 0;
 	}
 }
 
-- 
1.9.1


From skarajga at visteon.com  Tue Aug  4 02:11:32 2015
From: skarajga at visteon.com (Karajgaonkar, Saurabh (S.))
Date: Tue, 4 Aug 2015 09:11:32 +0000
Subject: [PATCH 7/9] usb: host: xhci: Simplify return statement
In-Reply-To: <cover.1438678566.git.skarajga@visteon.com>
References: <cover.1438678566.git.skarajga@visteon.com>
Message-ID: <111974a782999d7133f4fa38d8775241c6c88aee.1438678566.git.skarajga@visteon.com>

From: Saurabh Karajgaonkar <skarajga at visteon.com>

Replace redundant variable use in return statement.

Signed-off-by: Saurabh Karajgaonkar <skarajga at visteon.com>
---
 drivers/usb/host/xhci.c | 6 +-----
 1 file changed, 1 insertion(+), 5 deletions(-)

diff --git a/drivers/usb/host/xhci.c b/drivers/usb/host/xhci.c
index 526ebc0..19076fa 100644
--- a/drivers/usb/host/xhci.c
+++ b/drivers/usb/host/xhci.c
@@ -4678,7 +4678,6 @@ int xhci_disable_usb3_lpm_timeout(struct usb_hcd *hcd,
 {
 	struct xhci_hcd	*xhci;
 	u16 mel;
-	int ret;
 
 	xhci = hcd_to_xhci(hcd);
 	if (!xhci || !(xhci->quirks & XHCI_LPM_SUPPORT) ||
@@ -4686,10 +4685,7 @@ int xhci_disable_usb3_lpm_timeout(struct usb_hcd *hcd,
 		return 0;
 
 	mel = calculate_max_exit_latency(udev, state, USB3_LPM_DISABLED);
-	ret = xhci_change_max_exit_latency(xhci, udev, mel);
-	if (ret)
-		return ret;
-	return 0;
+	return xhci_change_max_exit_latency(xhci, udev, mel);
 }
 #else /* CONFIG_PM */
 
-- 
1.9.1


From skarajga at visteon.com  Tue Aug  4 02:11:59 2015
From: skarajga at visteon.com (Karajgaonkar, Saurabh (S.))
Date: Tue, 4 Aug 2015 09:11:59 +0000
Subject: [PATCH 8/9] usb: serial: mxuport: Simplify return statement
In-Reply-To: <cover.1438678566.git.skarajga@visteon.com>
References: <cover.1438678566.git.skarajga@visteon.com>
Message-ID: <1d0403e01eb663ac195926d1976974bec5c08f12.1438678566.git.skarajga@visteon.com>

From: Saurabh Karajgaonkar <skarajga at visteon.com>

Replace redundant variable use in return statement.

Signed-off-by: Saurabh Karajgaonkar <skarajga at visteon.com>
---
 drivers/usb/serial/mxuport.c | 6 +-----
 1 file changed, 1 insertion(+), 5 deletions(-)

diff --git a/drivers/usb/serial/mxuport.c b/drivers/usb/serial/mxuport.c
index 460a406..7792407 100644
--- a/drivers/usb/serial/mxuport.c
+++ b/drivers/usb/serial/mxuport.c
@@ -1137,13 +1137,9 @@ static int mxuport_port_probe(struct usb_serial_port *port)
 		return err;
 
 	/* Set interface (RS-232) */
-	err = mxuport_send_ctrl_urb(serial, RQ_VENDOR_SET_INTERFACE,
+	return mxuport_send_ctrl_urb(serial, RQ_VENDOR_SET_INTERFACE,
 				    MX_INT_RS232,
 				    port->port_number);
-	if (err)
-		return err;
-
-	return 0;
 }
 
 static int mxuport_alloc_write_urb(struct usb_serial *serial,
-- 
1.9.1


From skarajga at visteon.com  Tue Aug  4 02:12:28 2015
From: skarajga at visteon.com (Karajgaonkar, Saurabh (S.))
Date: Tue, 4 Aug 2015 09:12:28 +0000
Subject: [PATCH 9/9] usb: misc: ftdi-elan: Simplify return statement
In-Reply-To: <cover.1438678566.git.skarajga@visteon.com>
References: <cover.1438678566.git.skarajga@visteon.com>
Message-ID: <21701034f1472a3d154c77dd8d8be017565885f6.1438678566.git.skarajga@visteon.com>

From: Saurabh Karajgaonkar <skarajga at visteon.com>

Replace redundant variable use in return statement.

Signed-off-by: Saurabh Karajgaonkar <skarajga at visteon.com>
---
 drivers/usb/misc/ftdi-elan.c | 10 ++--------
 1 file changed, 2 insertions(+), 8 deletions(-)

diff --git a/drivers/usb/misc/ftdi-elan.c b/drivers/usb/misc/ftdi-elan.c
index 8ab1f8f..1545f12 100644
--- a/drivers/usb/misc/ftdi-elan.c
+++ b/drivers/usb/misc/ftdi-elan.c
@@ -2568,11 +2568,8 @@ static int ftdi_elan_close_controller(struct usb_ftdi *ftdi, int fn)
 					    0x00);
 	if (UxxxStatus)
 		return UxxxStatus;
-	UxxxStatus = ftdi_elan_read_config(ftdi, activePCIfn | reg, 0,
+	return ftdi_elan_read_config(ftdi, activePCIfn | reg, 0,
 					   &pcidata);
-	if (UxxxStatus)
-		return UxxxStatus;
-	return 0;
 }
 
 static int ftdi_elan_found_controller(struct usb_ftdi *ftdi, int fn, int quirk)
@@ -2695,11 +2692,8 @@ static int ftdi_elan_setupOHCI(struct usb_ftdi *ftdi)
 		}
 	}
 	if (ftdi->function > 0) {
-		UxxxStatus = ftdi_elan_setup_controller(ftdi,
+		return ftdi_elan_setup_controller(ftdi,
 							ftdi->function - 1);
-		if (UxxxStatus)
-			return UxxxStatus;
-		return 0;
 	} else if (controllers > 0) {
 		return -ENXIO;
 	} else if (unrecognized > 0) {
-- 
1.9.1


From pebolle at tiscali.nl  Tue Aug  4 02:17:39 2015
From: pebolle at tiscali.nl (Paul Bolle)
Date: Tue, 04 Aug 2015 11:17:39 +0200
Subject: [RFC PATCH 2/3] mailbox: Hisilicon: add mailbox driver
In-Reply-To: <20150804084930.GA27609@leoy-linaro>
References: <1438564390-28111-1-git-send-email-leo.yan@linaro.org>
 <1438564390-28111-3-git-send-email-leo.yan@linaro.org>
 <1438677024.8734.24.camel@tiscali.nl> <20150804084930.GA27609@leoy-linaro>
Message-ID: <1438679859.8734.35.camel@tiscali.nl>

On di, 2015-08-04 at 16:49 +0800, Leo Yan wrote:
> On Tue, Aug 04, 2015 at 10:30:24AM +0200, Paul Bolle wrote:
> > On ma, 2015-08-03 at 09:13 +0800, Leo Yan wrote:
> > > --- /dev/null
> > > +++ b/drivers/mailbox/hisilicon/Kconfig
> > 
> > > +config HISI_MBOX
> > > +	bool "Hisilicon's Mailbox"
> > > +	depends on ARCH_HISI || OF
> > 
> > ARCH_HISI is available on either ARM64 or ARM. ARM64 selects OF. On ARM
> > ARCH_HISI depends on ARCH_MULTIV7 which depends on ARCH_MULTIPLATFORM.
> > That selects USE_OF which on its turn selects OF.
> > 
> > So, HISI_MBOX implies OF, correct?
> 
> Exactly, will simply use "depends on ARCH_HISI".

That change would alter the dependencies. My remark was made just to
make clear why I think CONFIG_OF will always be defined. But now I guess
you actually meant
	depends on ARCH_HISI && OF

And that would, I think, indeed be equivalent to
	depends on ARCH_HISI

Thanks,


Paul Bolle


From mpa at pengutronix.de  Tue Aug  4 02:23:21 2015
From: mpa at pengutronix.de (Markus Pargmann)
Date: Tue,  4 Aug 2015 11:23:21 +0200
Subject: [PATCH 4/6] gpiolib-sysfs: Add gpio name parsing for sysfs export
In-Reply-To: <1438680203-13432-1-git-send-email-mpa@pengutronix.de>
References: <1438680203-13432-1-git-send-email-mpa@pengutronix.de>
Message-ID: <1438680203-13432-5-git-send-email-mpa@pengutronix.de>

Signed-off-by: Markus Pargmann <mpa at pengutronix.de>
---
 drivers/gpio/gpiolib-sysfs.c | 47 ++++++++++++++++++++++++++++++++------------
 1 file changed, 34 insertions(+), 13 deletions(-)

diff --git a/drivers/gpio/gpiolib-sysfs.c b/drivers/gpio/gpiolib-sysfs.c
index b57ed8e55ab5..e22a86e31c90 100644
--- a/drivers/gpio/gpiolib-sysfs.c
+++ b/drivers/gpio/gpiolib-sysfs.c
@@ -443,18 +443,28 @@ static ssize_t export_store(struct class *class,
 				const char *buf, size_t len)
 {
 	long			gpio;
-	struct gpio_desc	*desc;
+	struct gpio_desc	*desc = NULL;
 	int			status;
 
 	status = kstrtol(buf, 0, &gpio);
-	if (status < 0)
-		goto done;
+	if (!status)
+		desc = gpio_to_desc(gpio);
 
-	desc = gpio_to_desc(gpio);
-	/* reject invalid GPIOs */
+	/* Fall back on detection by name */
 	if (!desc) {
-		pr_warn("%s: invalid GPIO %ld\n", __func__, gpio);
-		return -EINVAL;
+		char *gpio_name = kstrdup(buf, GFP_KERNEL);
+
+		if (!gpio_name)
+			return -ENOMEM;
+
+		desc = gpio_name_to_desc(strim(gpio_name));
+		kfree(gpio_name);
+
+		/* reject invalid GPIOs */
+		if (!desc) {
+			pr_warn("%s: invalid GPIO %s\n", __func__, buf);
+			return -EINVAL;
+		}
 	}
 
 	/* No extra locking here; FLAG_SYSFS just signifies that the
@@ -485,17 +495,28 @@ static ssize_t unexport_store(struct class *class,
 				const char *buf, size_t len)
 {
 	long			gpio;
-	struct gpio_desc	*desc;
+	struct gpio_desc	*desc = NULL;
 	int			status;
 
 	status = kstrtol(buf, 0, &gpio);
-	if (status < 0)
-		goto done;
+	if (!status)
+		desc = gpio_to_desc(gpio);
+
+	/* Fall back on detection by name */
+	if (!desc) {
+		char *gpio_name = kstrdup(buf, GFP_KERNEL);
+
+		if (!gpio_name)
+			return -ENOMEM;
+
+		desc = gpio_name_to_desc(strim(gpio_name));
+		kfree(gpio_name);
+	}
+
 
-	desc = gpio_to_desc(gpio);
 	/* reject bogus commands (gpio_unexport ignores them) */
 	if (!desc) {
-		pr_warn("%s: invalid GPIO %ld\n", __func__, gpio);
+		pr_warn("%s: invalid GPIO %s\n", __func__, buf);
 		return -EINVAL;
 	}
 
@@ -509,7 +530,7 @@ static ssize_t unexport_store(struct class *class,
 		status = 0;
 		gpiod_free(desc);
 	}
-done:
+
 	if (status)
 		pr_debug("%s: status %d\n", __func__, status);
 	return status ? : len;
-- 
2.1.4



From mpa at pengutronix.de  Tue Aug  4 02:23:23 2015
From: mpa at pengutronix.de (Markus Pargmann)
Date: Tue,  4 Aug 2015 11:23:23 +0200
Subject: [PATCH 6/6] gpiolib: Add gpio name information to
 /sys/kernel/debug/gpio
In-Reply-To: <1438680203-13432-1-git-send-email-mpa@pengutronix.de>
References: <1438680203-13432-1-git-send-email-mpa@pengutronix.de>
Message-ID: <1438680203-13432-7-git-send-email-mpa@pengutronix.de>

Add some information about gpio names to the debugfs gpio file. name and
label of a GPIO are then displayed next to each other. This way it is
easy to see what the real name of GPIO is and what the driver requested
it for.

Signed-off-by: Markus Pargmann <mpa at pengutronix.de>
---
 drivers/gpio/gpiolib.c | 11 ++++++++---
 1 file changed, 8 insertions(+), 3 deletions(-)

diff --git a/drivers/gpio/gpiolib.c b/drivers/gpio/gpiolib.c
index edfeb0485112..926a1507431f 100644
--- a/drivers/gpio/gpiolib.c
+++ b/drivers/gpio/gpiolib.c
@@ -2307,14 +2307,19 @@ static void gpiolib_dbg_show(struct seq_file *s, struct gpio_chip *chip)
 	int			is_irq;
 
 	for (i = 0; i < chip->ngpio; i++, gpio++, gdesc++) {
-		if (!test_bit(FLAG_REQUESTED, &gdesc->flags))
+		if (!test_bit(FLAG_REQUESTED, &gdesc->flags)) {
+			if (gdesc->name) {
+				seq_printf(s, " gpio-%-3d (%-20.20s)\n",
+					   gpio, gdesc->name);
+			}
 			continue;
+		}
 
 		gpiod_get_direction(gdesc);
 		is_out = test_bit(FLAG_IS_OUT, &gdesc->flags);
 		is_irq = test_bit(FLAG_USED_AS_IRQ, &gdesc->flags);
-		seq_printf(s, " gpio-%-3d (%-20.20s) %s %s %s",
-			gpio, gdesc->label,
+		seq_printf(s, " gpio-%-3d (%-20.20s|%-20.20s) %s %s %s",
+			gpio, gdesc->name ? gdesc->name : "", gdesc->label,
 			is_out ? "out" : "in ",
 			chip->get
 				? (chip->get(chip, i) ? "hi" : "lo")
-- 
2.1.4



From mpa at pengutronix.de  Tue Aug  4 02:23:22 2015
From: mpa at pengutronix.de (Markus Pargmann)
Date: Tue,  4 Aug 2015 11:23:22 +0200
Subject: [PATCH 5/6] gpiolib-sysfs: Show gpio-name in
 /sys/class/gpio/gpio*/name
In-Reply-To: <1438680203-13432-1-git-send-email-mpa@pengutronix.de>
References: <1438680203-13432-1-git-send-email-mpa@pengutronix.de>
Message-ID: <1438680203-13432-6-git-send-email-mpa@pengutronix.de>

This patch adds a sysfs attribute 'name' to gpios that were exported. It
exposes the newly added name property of gpio descriptors.

Signed-off-by: Markus Pargmann <mpa at pengutronix.de>
---
 drivers/gpio/gpiolib-sysfs.c | 12 ++++++++++++
 1 file changed, 12 insertions(+)

diff --git a/drivers/gpio/gpiolib-sysfs.c b/drivers/gpio/gpiolib-sysfs.c
index e22a86e31c90..c5e8224428ac 100644
--- a/drivers/gpio/gpiolib-sysfs.c
+++ b/drivers/gpio/gpiolib-sysfs.c
@@ -139,6 +139,17 @@ static ssize_t value_store(struct device *dev,
 }
 static DEVICE_ATTR_RW(value);
 
+static ssize_t name_show(struct device *dev, struct device_attribute *attr,
+			 char *buf)
+{
+	struct gpiod_data *data = dev_get_drvdata(dev);
+	struct gpio_desc *desc = data->desc;
+
+	return sprintf(buf, "%s\n", desc->name ? : "");
+}
+
+static DEVICE_ATTR_RO(name);
+
 static irqreturn_t gpio_sysfs_irq(int irq, void *priv)
 {
 	struct gpiod_data *data = priv;
@@ -377,6 +388,7 @@ static struct attribute *gpio_attrs[] = {
 	&dev_attr_edge.attr,
 	&dev_attr_value.attr,
 	&dev_attr_active_low.attr,
+	&dev_attr_name.attr,
 	NULL,
 };
 
-- 
2.1.4



From mpa at pengutronix.de  Tue Aug  4 02:23:17 2015
From: mpa at pengutronix.de (Markus Pargmann)
Date: Tue,  4 Aug 2015 11:23:17 +0200
Subject: [PATCH 0/6] gpiolib: Add GPIO name support
Message-ID: <1438680203-13432-1-git-send-email-mpa@pengutronix.de>

Hi,

Changes in v2:
 - Removed patch 'gpiolib: Fix possible use of wrong name'
 - Removed discussed patch 'gpio: Allow hogged gpios to be requested' from this
   series
 - Fixed show gpio name patch (locks, (null) printing, and getting the descriptor)
 - Merged gpio name patch into gpio_name_to_desc() patch

Description from v1:

This is a proposal to add GPIO names to the kernel based on devicetree
descriptions.

This series adds GPIO name support. Until now it is only possible to use names
for already requested GPIOs (for example what they are used for). It is not
possible to identify GPIOs by a name although most of them have a name for
example in the schematics of the board. This makes it difficult to identify
a specific GPIO from userspace.

As the GPIO name information is a hardware description this series uses the
devicetree bindings introduced by the GPIO hogging mechanism, specifically
'line-name', to identify GPIOs. The sysfs 'export' file is changed to accept
names as fallback. The gpio numbers still have a higher priority to ensure
backwards compatibility.

Exported GPIOs are still using their number as directory name (gpio<ID>). But the
directories now contain a 'name' file which is '' for non-existent names and
the name otherwise.

This series can be used to have an easy name mapping for udev with a quite
simple rule similar to this:
	SUBSYSTEM=="gpio", KERNEL=="gpio*", ATTR{name}!="(null)", ACTION=="add", \
	PROGRAM+="/bin/sh -c 'mkdir -p /dev/gpios; rm -f /dev/gpios/$attr{name}; ln -s /sys%p/ /dev/gpios/$attr{name}"
With this rule udev adds a link for each exported GPIO with a name into
/dev/gpios/. This way it is not necessary to know the number of a GPIO to use
it.

Best Regards,

Markus


Markus Pargmann (6):
  gpiolib-of: Rename gpio_hog functions to be generic
  gpio: Introduce gpio descriptor 'name'
  gpiolib-of: Reuse 'line-name' from DT as gpio descriptor name
  gpiolib-sysfs: Add gpio name parsing for sysfs export
  gpiolib-sysfs: Show gpio-name in /sys/class/gpio/gpio*/name
  gpiolib: Add gpio name information to /sys/kernel/debug/gpio

 drivers/gpio/gpiolib-of.c     | 41 ++++++++++++++++++------------
 drivers/gpio/gpiolib-sysfs.c  | 59 +++++++++++++++++++++++++++++++++----------
 drivers/gpio/gpiolib.c        | 43 ++++++++++++++++++++++++++++---
 drivers/gpio/gpiolib.h        |  3 +++
 include/linux/gpio/consumer.h |  7 +++++
 5 files changed, 121 insertions(+), 32 deletions(-)

-- 
2.1.4



From mpa at pengutronix.de  Tue Aug  4 02:23:19 2015
From: mpa at pengutronix.de (Markus Pargmann)
Date: Tue,  4 Aug 2015 11:23:19 +0200
Subject: [PATCH 2/6] gpio: Introduce gpio descriptor 'name'
In-Reply-To: <1438680203-13432-1-git-send-email-mpa@pengutronix.de>
References: <1438680203-13432-1-git-send-email-mpa@pengutronix.de>
Message-ID: <1438680203-13432-3-git-send-email-mpa@pengutronix.de>

The latest gpio hogging mechanism assigns each gpio a 'line-name' in the
devicetree. The 'name' field is different from the 'label' field.
'label' is only used for requested GPIOs to describe its current use by
driver or userspace.

The 'name' field describes the GPIO itself, not the use. This is most
likely identical to the label in the schematic on the GPIO line and
should help to find this particular GPIO.

This patch adds a helper function to find gpio descriptors by name
instead of gpio number.

Signed-off-by: Markus Pargmann <mpa at pengutronix.de>
---
 drivers/gpio/gpiolib.c        | 32 ++++++++++++++++++++++++++++++++
 drivers/gpio/gpiolib.h        |  3 +++
 include/linux/gpio/consumer.h |  7 +++++++
 3 files changed, 42 insertions(+)

diff --git a/drivers/gpio/gpiolib.c b/drivers/gpio/gpiolib.c
index bf4bd1d120c3..edfeb0485112 100644
--- a/drivers/gpio/gpiolib.c
+++ b/drivers/gpio/gpiolib.c
@@ -90,6 +90,38 @@ struct gpio_desc *gpio_to_desc(unsigned gpio)
 EXPORT_SYMBOL_GPL(gpio_to_desc);
 
 /**
+ * Convert a GPIO name to its descriptor
+ */
+struct gpio_desc *gpio_name_to_desc(const char *name)
+{
+	struct gpio_chip *chip;
+	unsigned long flags;
+
+	spin_lock_irqsave(&gpio_lock, flags);
+
+	list_for_each_entry(chip, &gpio_chips, list) {
+		int i;
+
+		for (i = 0; i != chip->ngpio; ++i) {
+			struct gpio_desc *gpio = &chip->desc[i];
+
+			if (!gpio->name)
+				continue;
+
+			if (!strcmp(gpio->name, name)) {
+				spin_unlock_irqrestore(&gpio_lock, flags);
+				return gpio;
+			}
+		}
+	}
+
+	spin_unlock_irqrestore(&gpio_lock, flags);
+
+	return NULL;
+}
+EXPORT_SYMBOL_GPL(gpio_name_to_desc);
+
+/**
  * Get the GPIO descriptor corresponding to the given hw number for this chip.
  */
 struct gpio_desc *gpiochip_get_desc(struct gpio_chip *chip,
diff --git a/drivers/gpio/gpiolib.h b/drivers/gpio/gpiolib.h
index bf343004b008..78e634d1c719 100644
--- a/drivers/gpio/gpiolib.h
+++ b/drivers/gpio/gpiolib.h
@@ -89,7 +89,10 @@ struct gpio_desc {
 #define FLAG_USED_AS_IRQ 9	/* GPIO is connected to an IRQ */
 #define FLAG_IS_HOGGED	11	/* GPIO is hogged */
 
+	/* Connection label */
 	const char		*label;
+	/* Name of the GPIO */
+	const char		*name;
 };
 
 int gpiod_request(struct gpio_desc *desc, const char *label);
diff --git a/include/linux/gpio/consumer.h b/include/linux/gpio/consumer.h
index adac255aee86..a873b8b47ab3 100644
--- a/include/linux/gpio/consumer.h
+++ b/include/linux/gpio/consumer.h
@@ -130,6 +130,7 @@ int gpiod_to_irq(const struct gpio_desc *desc);
 /* Convert between the old gpio_ and new gpiod_ interfaces */
 struct gpio_desc *gpio_to_desc(unsigned gpio);
 int desc_to_gpio(const struct gpio_desc *desc);
+struct gpio_desc *gpio_name_to_desc(const char *name);
 
 /* Child properties interface */
 struct fwnode_handle;
@@ -400,6 +401,12 @@ static inline struct gpio_desc *gpio_to_desc(unsigned gpio)
 {
 	return ERR_PTR(-EINVAL);
 }
+
+static inline struct gpio_desc *gpio_name_to_desc(const char *name)
+{
+	return ERR_PTR(-EINVAL);
+}
+
 static inline int desc_to_gpio(const struct gpio_desc *desc)
 {
 	/* GPIO can never have been requested */
-- 
2.1.4



From mpa at pengutronix.de  Tue Aug  4 02:23:20 2015
From: mpa at pengutronix.de (Markus Pargmann)
Date: Tue,  4 Aug 2015 11:23:20 +0200
Subject: [PATCH 3/6] gpiolib-of: Reuse 'line-name' from DT as gpio descriptor
 name
In-Reply-To: <1438680203-13432-1-git-send-email-mpa@pengutronix.de>
References: <1438680203-13432-1-git-send-email-mpa@pengutronix.de>
Message-ID: <1438680203-13432-4-git-send-email-mpa@pengutronix.de>

The DT describes gpios with subnodes. These subnodes can contain a
property 'line-name'. This information can be useful in other areas
where we want to identify a GPIO by its name.

This patch stores the line-name in the gpio descriptor.

Signed-off-by: Markus Pargmann <mpa at pengutronix.de>
---
 drivers/gpio/gpiolib-of.c | 27 ++++++++++++++++++---------
 1 file changed, 18 insertions(+), 9 deletions(-)

diff --git a/drivers/gpio/gpiolib-of.c b/drivers/gpio/gpiolib-of.c
index 41a4945b346e..fbf449a4120b 100644
--- a/drivers/gpio/gpiolib-of.c
+++ b/drivers/gpio/gpiolib-of.c
@@ -184,11 +184,6 @@ static struct gpio_desc *of_parse_gpio(struct device_node *np,
 		*dflags |= GPIOD_OUT_LOW;
 	else if (of_property_read_bool(np, "output-high"))
 		*dflags |= GPIOD_OUT_HIGH;
-	else {
-		pr_warn("GPIO line %d (%s): no hogging state specified, bailing out\n",
-			desc_to_gpio(gg_data.out_gpio), np->name);
-		return ERR_PTR(-EINVAL);
-	}
 
 	if (name && of_property_read_string(np, "line-name", name))
 		*name = np->name;
@@ -214,15 +209,29 @@ static void of_gpiochip_scan_gpios(struct gpio_chip *chip)
 	enum gpiod_flags dflags;
 
 	for_each_child_of_node(chip->of_node, np) {
-		if (!of_property_read_bool(np, "gpio-hog"))
-			continue;
+		struct gpio_desc *name_desc;
 
 		desc = of_parse_gpio(np, &name, &lflags, &dflags);
 		if (IS_ERR(desc))
 			continue;
 
-		if (gpiod_hog(desc, name, lflags, dflags))
-			continue;
+		name_desc = gpio_name_to_desc(name);
+		if (name_desc)
+			pr_warn("GPIO name collision for '%s' detected at GPIO line %d (%s)\n",
+				name, desc_to_gpio(desc), np->name);
+		else
+			desc->name = name;
+
+		if (of_property_read_bool(np, "gpio-hog")) {
+			if (!dflags) {
+				pr_warn("GPIO line %d (%s): no hogging state specified, bailing out\n",
+					desc_to_gpio(desc), np->name);
+				continue;
+			}
+
+			if (gpiod_hog(desc, name, lflags, dflags))
+				continue;
+		}
 	}
 }
 
-- 
2.1.4



From mpa at pengutronix.de  Tue Aug  4 02:25:19 2015
From: mpa at pengutronix.de (Markus Pargmann)
Date: Tue, 4 Aug 2015 11:25:19 +0200
Subject: [PATCH 0/6 v2] gpiolib: Add GPIO name support
In-Reply-To: <1438680203-13432-1-git-send-email-mpa@pengutronix.de>
References: <1438680203-13432-1-git-send-email-mpa@pengutronix.de>
Message-ID: <20150804092519.GG19600@pengutronix.de>

On Tue, Aug 04, 2015 at 11:23:17AM +0200, Markus Pargmann wrote:
> Hi,
> 
> Changes in v2:

Sorry, forgot to add v2 into the subject.

Best regards,

Markus

>  - Removed patch 'gpiolib: Fix possible use of wrong name'
>  - Removed discussed patch 'gpio: Allow hogged gpios to be requested' from this
>    series
>  - Fixed show gpio name patch (locks, (null) printing, and getting the descriptor)
>  - Merged gpio name patch into gpio_name_to_desc() patch
> 
> Description from v1:
> 
> This is a proposal to add GPIO names to the kernel based on devicetree
> descriptions.
> 
> This series adds GPIO name support. Until now it is only possible to use names
> for already requested GPIOs (for example what they are used for). It is not
> possible to identify GPIOs by a name although most of them have a name for
> example in the schematics of the board. This makes it difficult to identify
> a specific GPIO from userspace.
> 
> As the GPIO name information is a hardware description this series uses the
> devicetree bindings introduced by the GPIO hogging mechanism, specifically
> 'line-name', to identify GPIOs. The sysfs 'export' file is changed to accept
> names as fallback. The gpio numbers still have a higher priority to ensure
> backwards compatibility.
> 
> Exported GPIOs are still using their number as directory name (gpio<ID>). But the
> directories now contain a 'name' file which is '' for non-existent names and
> the name otherwise.
> 
> This series can be used to have an easy name mapping for udev with a quite
> simple rule similar to this:
> 	SUBSYSTEM=="gpio", KERNEL=="gpio*", ATTR{name}!="(null)", ACTION=="add", \
> 	PROGRAM+="/bin/sh -c 'mkdir -p /dev/gpios; rm -f /dev/gpios/$attr{name}; ln -s /sys%p/ /dev/gpios/$attr{name}"
> With this rule udev adds a link for each exported GPIO with a name into
> /dev/gpios/. This way it is not necessary to know the number of a GPIO to use
> it.
> 
> Best Regards,
> 
> Markus
> 
> 
> Markus Pargmann (6):
>   gpiolib-of: Rename gpio_hog functions to be generic
>   gpio: Introduce gpio descriptor 'name'
>   gpiolib-of: Reuse 'line-name' from DT as gpio descriptor name
>   gpiolib-sysfs: Add gpio name parsing for sysfs export
>   gpiolib-sysfs: Show gpio-name in /sys/class/gpio/gpio*/name
>   gpiolib: Add gpio name information to /sys/kernel/debug/gpio
> 
>  drivers/gpio/gpiolib-of.c     | 41 ++++++++++++++++++------------
>  drivers/gpio/gpiolib-sysfs.c  | 59 +++++++++++++++++++++++++++++++++----------
>  drivers/gpio/gpiolib.c        | 43 ++++++++++++++++++++++++++++---
>  drivers/gpio/gpiolib.h        |  3 +++
>  include/linux/gpio/consumer.h |  7 +++++
>  5 files changed, 121 insertions(+), 32 deletions(-)
> 
> -- 
> 2.1.4
> 
> 

-- 
Pengutronix e.K.                           |                             |
Industrial Linux Solutions                 | http://www.pengutronix.de/  |
Peiner Str. 6-8, 31137 Hildesheim, Germany | Phone: +49-5121-206917-0    |
Amtsgericht Hildesheim, HRA 2686           | Fax:   +49-5121-206917-5555 |
-------------- next part --------------
A non-text attachment was scrubbed...
Name: signature.asc
Type: application/pgp-signature
Size: 819 bytes
Desc: Digital signature
URL: <http://lists.infradead.org/pipermail/linux-arm-kernel/attachments/20150804/8fc4f720/attachment-0001.sig>

From josh.wu at atmel.com  Tue Aug  4 02:37:49 2015
From: josh.wu at atmel.com (Josh Wu)
Date: Tue, 4 Aug 2015 17:37:49 +0800
Subject: [PATCH v3] media: atmel-isi: parse the DT parameters for
 vsync/hsync/pixclock polarity
Message-ID: <1438681069-16981-1-git-send-email-josh.wu@atmel.com>

This patch will get the DT parameters of vsync/hsync/pixclock polarity, and
pass to driver.

Also add a debug information for test purpose.

Signed-off-by: Josh Wu <josh.wu at atmel.com>
---

Changes in v3:
- add embedded sync dt property support.

Changes in v2:
- rewrite the debug message and add pix clock polarity setup thanks to
  Laurent.
- update the commit log.

 drivers/media/platform/soc_camera/atmel-isi.c | 15 +++++++++++++++
 1 file changed, 15 insertions(+)

diff --git a/drivers/media/platform/soc_camera/atmel-isi.c b/drivers/media/platform/soc_camera/atmel-isi.c
index fead841..4efc939 100644
--- a/drivers/media/platform/soc_camera/atmel-isi.c
+++ b/drivers/media/platform/soc_camera/atmel-isi.c
@@ -1061,6 +1061,11 @@ static int isi_camera_set_bus_param(struct soc_camera_device *icd)
 	if (common_flags & V4L2_MBUS_PCLK_SAMPLE_FALLING)
 		cfg1 |= ISI_CFG1_PIXCLK_POL_ACTIVE_FALLING;
 
+	dev_dbg(icd->parent, "vsync active %s, hsync active %s, sampling on pix clock %s edge\n",
+		common_flags & V4L2_MBUS_VSYNC_ACTIVE_LOW ? "low" : "high",
+		common_flags & V4L2_MBUS_HSYNC_ACTIVE_LOW ? "low" : "high",
+		common_flags & V4L2_MBUS_PCLK_SAMPLE_FALLING ? "falling" : "rising");
+
 	if (isi->pdata.has_emb_sync)
 		cfg1 |= ISI_CFG1_EMB_SYNC;
 	if (isi->pdata.full_mode)
@@ -1148,6 +1153,16 @@ static int atmel_isi_parse_dt(struct atmel_isi *isi,
 		return -EINVAL;
 	}
 
+	if (ep.bus.parallel.flags & V4L2_MBUS_HSYNC_ACTIVE_LOW)
+		isi->pdata.hsync_act_low = true;
+	if (ep.bus.parallel.flags & V4L2_MBUS_VSYNC_ACTIVE_LOW)
+		isi->pdata.vsync_act_low = true;
+	if (ep.bus.parallel.flags & V4L2_MBUS_PCLK_SAMPLE_FALLING)
+		isi->pdata.pclk_act_falling = true;
+
+	if (ep.bus_type == V4L2_MBUS_BT656)
+		isi->pdata.has_emb_sync = true;
+
 	return 0;
 }
 
-- 
1.9.1



From james.morse at arm.com  Tue Aug  4 02:34:38 2015
From: james.morse at arm.com (James Morse)
Date: Tue, 04 Aug 2015 10:34:38 +0100
Subject: [PATCH v5 2/5] PCI: designware: Add ARM64 support
In-Reply-To: <55B71F75.5030907@hisilicon.com>
References: <1437794486-21134-1-git-send-email-wangzhou1@hisilicon.com>
 <1437794486-21134-3-git-send-email-wangzhou1@hisilicon.com>
 <55B71F75.5030907@hisilicon.com>
Message-ID: <55C0872E.9060507@arm.com>

On 28/07/15 07:21, Zhou Wang wrote:
> On 2015/7/25 11:21, Zhou Wang wrote:
>> This patch tries to unify ARM32 and ARM64 PCIe in designware driver. Delete
>> function dw_pcie_setup, dw_pcie_scan_bus, dw_pcie_map_irq and struct hw_pci,
>> move related operations to dw_pcie_host_init. Also set pp->root_bus_nr = 0 in
>> each PCIe host driver which is based on pcie-designware. This patch also try
>> to use of_pci_get_host_bridge_resources for ARM32 and ARM64 according to the
>> suggestion for Gabriele[1]
>>
>> This patch is based on Gabriele's patch about of_pci_range fix[2]
>>
>> I have compiled the driver with multi_v7_defconfig. However, I don't have
>> ARM32 PCIe related board to do test. It will be appreciated if someone could
>> help to test it.
>>
> 
> Hi James,
> 
> If you have time, could you help to test this patch on i.MX 6Quad board?
> You need apply Gabriele's patch before applying this patch.
> 
> It will be very appreciate and helpful if we can get test result from you.

Applying patches 1 and 2, from v5, onto 4.2-rc5, I still get the same
problem as before: config cycles to enumerate the second bus aren't
working. (good news - I have a workaround)

Output from dmesg below, the lines 'dw_pcie_cfg_read(0xf0180000, 0x0, 0x4,
=0x8878086)' were added by me, 0x8878086 is the intel wireless card
attached to the board.

>From v4.2-rc5:
----------------------------------------------------------------------------------
imx6q-pcie 1ffc000.pcie: PCI host bridge to bus 0000:00
pci_bus 0000:00: root bus resource [io 0x1000-0xffff]
pci_bus 0000:00: root bus resource [mem 0x01000000-0x01efffff]
pci_bus 0000:00: root bus resource [bus 00-ff]
pci 0000:00:00.0: [16c3:abcd] type 01 class 0x060400
pci 0000:00:00.0: reg 0x10: [mem 0x00000000-0x000fffff]
pci 0000:00:00.0: reg 0x38: [mem 0x00000000-0x0000ffff pref]
pci 0000:00:00.0: IOMMU is currently not supported for PCI
pci 0000:00:00.0: supports D1
pci 0000:00:00.0: PME# supported from D0 D1 D3hot D3cold
PCI: bus0: Fast back to back transfers disabled
dw_pcie_cfg_read(0xf0180000, 0x0, 0x4, =0x8878086)
pci 0000:01:00.0: [8086:0887] type 00 class 0x028000
dw_pcie_cfg_read(0xf0180000, 0x0, 0x4, =0x8878086)
pci 0000:01:00.0: reg 0x10: [mem 0x00000000-0x00001fff 64bit]
pci 0000:01:00.0: IOMMU is currently not supported for PCI
pci 0000:01:00.0: PME# supported from D0 D3hot D3cold
PCI: bus1: Fast back to back transfers disabled
pci_bus 0000:01: busn_res: [bus 01-ff] end is updated to 01
pci 0000:00:00.0: BAR 0: assigned [mem 0x01000000-0x010fffff]
pci 0000:00:00.0: BAR 8: assigned [mem 0x01100000-0x011fffff]
pci 0000:00:00.0: BAR 6: assigned [mem 0x01200000-0x0120ffff pref
]
pci 0000:01:00.0: BAR 0: assigned [mem 0x01100000-0x01101fff 64bi
t]
pci 0000:00:00.0: PCI bridge to [bus 01]
pci 0000:00:00.0:bridge window [mem 0x01100000-0x011fffff]
pcieport 0000:00:00.0: Signaling PME through PCIe PME interrupt
pci 0000:01:00.0: Signaling PME through PCIe PME interrupt
pcie_pme 0000:00:00.0:pcie01: service driver pcie_pme loaded
----------------------------------------------------------------------------------

And then with your two patches:
----------------------------------------------------------------------------------
PCI host bridge /soc/pcie at 0x01000000 ranges:
No bus range found for /soc/pcie at 0x01000000, using [bus 00-ff]
err 0x01f00000..0x01f7ffff -> 0x01f00000
IO 0x01f80000..0x01f8ffff -> 0x00000000
MEM 0x01000000..0x01efffff -> 0x01000000
imx6q-pcie 1ffc000.pcie: PCI host bridge to bus 0000:00
pci_bus 0000:00: root bus resource [bus 00-ff]
pci_bus 0000:00: root bus resource [??? 0x01f00000-0x01f7ffff fla
gs 0x0]
pci_bus 0000:00: root bus resource [io 0x0000-0xffff]
pci_bus 0000:00: root bus resource [mem 0x01000000-0x01efffff]
pci 0000:00:00.0: [16c3:abcd] type 01 class 0x060400
pci 0000:00:00.0: reg 0x10: [mem 0x00000000-0x000fffff]
pci 0000:00:00.0: reg 0x38: [mem 0x00000000-0x0000ffff pref]
pci 0000:00:00.0: IOMMU is currently not supported for PCI
pci 0000:00:00.0: supports D1
pci 0000:00:00.0: PME# supported from D0 D1 D3hot D3cold
PCI: bus0: Fast back to back transfers disabled
dw_pcie_cfg_read(0xf0180000, 0x0, 0x4, =0x0)
PCI: bus1: Fast back to back transfers enabled
pci 0000:00:00.0: BAR 0: assigned [mem 0x01000000-0x010fffff]
pci 0000:00:00.0: BAR 6: assigned [mem 0x01100000-0x0110ffff pref
]
pci 0000:00:00.0: PCI bridge to [bus 01]
pcieport 0000:00:00.0: Signaling PME through PCIe PME interrupt
pcie_pme 0000:00:00.0:pcie01: service driver pcie_pme loaded
----------------------------------------------------------------------------------

Root-cause appears to be that the designware driver relies on ATU for
config and IO accesses. dw_pcie_rd_other_conf() does the appropriate magic,
but with your patches 'pp->cfg0_base' is NULL, despite being correctly
initialised in dw_pcie_host_init().

dw_pcie_host_init() initialises the pp->cfg* values correctly after its call:
>  platform_get_resource_byname(pdev, IORESOURCE_MEM, "config");

But the new code introduced by patch 2 then walks the whole resource_list
and re-initialises the pp->cfg* values. The fault occurs at:
> /* Find the untranslated configuration space address */
> pp->cfg0_mod_base = win->__res.start

where win->__res is uninitialised. The comment in linux/resource_ext.h says
this is the 'default storage for res', so its not valid to assume it
contains different values to win->res. (in this case, it contains no useful
values).

The workaround is to remove the re-initialisation of the pp->cfg* values,
as they were already correctly initialised earlier. However, other resource
types are accessing __res directly ... which is probably not correct.

I need to read-up on what these 'untranslated' addresses are for...



James




From mpa at pengutronix.de  Tue Aug  4 02:27:04 2015
From: mpa at pengutronix.de (Markus Pargmann)
Date: Tue,  4 Aug 2015 11:27:04 +0200
Subject: [PATCH v2] gpio: Allow hogged gpios to be requested
Message-ID: <1438680424-698-1-git-send-email-mpa@pengutronix.de>

It can be useful to claim hogged gpios later, for example from
userspace. This allows to set defaults for GPIOs using the hogging
mechanism and override the setup later from userspace or a kernel driver.

This patch adds a check for hogged gpios to allow requesting them. If
the gpio is not hogged but marked as requested, it still fails with
-EBUSY.

Signed-off-by: Markus Pargmann <mpa at pengutronix.de>
---

Only change is, that it is separated from the other series now.

 drivers/gpio/gpiolib.c | 3 ++-
 1 file changed, 2 insertions(+), 1 deletion(-)

diff --git a/drivers/gpio/gpiolib.c b/drivers/gpio/gpiolib.c
index 926a1507431f..0f1d1f5faf5d 100644
--- a/drivers/gpio/gpiolib.c
+++ b/drivers/gpio/gpiolib.c
@@ -830,7 +830,8 @@ static int __gpiod_request(struct gpio_desc *desc, const char *label)
 	 * before IRQs are enabled, for non-sleeping (SOC) GPIOs.
 	 */
 
-	if (test_and_set_bit(FLAG_REQUESTED, &desc->flags) == 0) {
+	if (test_and_set_bit(FLAG_REQUESTED, &desc->flags) == 0 ||
+	    test_and_clear_bit(FLAG_IS_HOGGED, &desc->flags) == 1) {
 		desc_set_label(desc, label ? : "?");
 		status = 0;
 	} else {
-- 
2.1.4



From mpa at pengutronix.de  Tue Aug  4 02:23:18 2015
From: mpa at pengutronix.de (Markus Pargmann)
Date: Tue,  4 Aug 2015 11:23:18 +0200
Subject: [PATCH 1/6] gpiolib-of: Rename gpio_hog functions to be generic
In-Reply-To: <1438680203-13432-1-git-send-email-mpa@pengutronix.de>
References: <1438680203-13432-1-git-send-email-mpa@pengutronix.de>
Message-ID: <1438680203-13432-2-git-send-email-mpa@pengutronix.de>

The gpio hogging functions are currently only used for gpio-hogging. But
these functions are widely generic ones which parse gpio device nodes in
the DT.

Signed-off-by: Markus Pargmann <mpa at pengutronix.de>
---
 drivers/gpio/gpiolib-of.c | 14 +++++++-------
 1 file changed, 7 insertions(+), 7 deletions(-)

diff --git a/drivers/gpio/gpiolib-of.c b/drivers/gpio/gpiolib-of.c
index 9a0ec48a4737..41a4945b346e 100644
--- a/drivers/gpio/gpiolib-of.c
+++ b/drivers/gpio/gpiolib-of.c
@@ -119,17 +119,17 @@ int of_get_named_gpio_flags(struct device_node *np, const char *list_name,
 EXPORT_SYMBOL(of_get_named_gpio_flags);
 
 /**
- * of_get_gpio_hog() - Get a GPIO hog descriptor, names and flags for GPIO API
+ * of_parse_gpio() - Get a GPIO hog descriptor, names and flags for GPIO API
  * @np:		device node to get GPIO from
  * @name:	GPIO line name
  * @lflags:	gpio_lookup_flags - returned from of_find_gpio() or
- *		of_get_gpio_hog()
+ *		of_parse_gpio()
  * @dflags:	gpiod_flags - optional GPIO initialization flags
  *
  * Returns GPIO descriptor to use with Linux GPIO API, or one of the errno
  * value on the error condition.
  */
-static struct gpio_desc *of_get_gpio_hog(struct device_node *np,
+static struct gpio_desc *of_parse_gpio(struct device_node *np,
 				  const char **name,
 				  enum gpio_lookup_flags *lflags,
 				  enum gpiod_flags *dflags)
@@ -199,13 +199,13 @@ static struct gpio_desc *of_get_gpio_hog(struct device_node *np,
 }
 
 /**
- * of_gpiochip_scan_hogs - Scan gpio-controller and apply GPIO hog as requested
+ * of_gpiochip_scan_gpios - Scan gpio-controller for gpio definitions
  * @chip:	gpio chip to act on
  *
  * This is only used by of_gpiochip_add to request/set GPIO initial
  * configuration.
  */
-static void of_gpiochip_scan_hogs(struct gpio_chip *chip)
+static void of_gpiochip_scan_gpios(struct gpio_chip *chip)
 {
 	struct gpio_desc *desc = NULL;
 	struct device_node *np;
@@ -217,7 +217,7 @@ static void of_gpiochip_scan_hogs(struct gpio_chip *chip)
 		if (!of_property_read_bool(np, "gpio-hog"))
 			continue;
 
-		desc = of_get_gpio_hog(np, &name, &lflags, &dflags);
+		desc = of_parse_gpio(np, &name, &lflags, &dflags);
 		if (IS_ERR(desc))
 			continue;
 
@@ -436,7 +436,7 @@ void of_gpiochip_add(struct gpio_chip *chip)
 	of_gpiochip_add_pin_range(chip);
 	of_node_get(chip->of_node);
 
-	of_gpiochip_scan_hogs(chip);
+	of_gpiochip_scan_gpios(chip);
 }
 
 void of_gpiochip_remove(struct gpio_chip *chip)
-- 
2.1.4



From aisheng.dong at freescale.com  Tue Aug  4 02:45:57 2015
From: aisheng.dong at freescale.com (Dong Aisheng)
Date: Tue, 4 Aug 2015 17:45:57 +0800
Subject: [PATCH V3 0/5] clk: support clocks which requires parent clock
 on during operation
In-Reply-To: <20150728143824.GB16916@shlinux1.ap.freescale.net>
References: <1438089585-30103-1-git-send-email-aisheng.dong@freescale.com>
 <20150728143824.GB16916@shlinux1.ap.freescale.net>
Message-ID: <20150804094556.GE24870@shlinux1.ap.freescale.net>

On Tue, Jul 28, 2015 at 10:38:25PM +0800, Dong Aisheng wrote:
> On Tue, Jul 28, 2015 at 09:19:40PM +0800, Dong Aisheng wrote:
> > This patch series adds support in clock framework for clocks which operations
> > requires its parent clock is on.
> > 
> > Such clock type is initially met on Freescale i.MX7D platform that all clocks
> > operations, including enable/disable, rate change and re-parent, requires its
> > parent clock on. No sure if any other SoC has the similar clock type.
> > 
> > Current clock core can not support such type of clock well.
> > 
> > This patch introduce a new flag CLK_SET_PARENT_ON to handle this special case
> > in clock core that enable its parent clock firstly for each operation and disable
> > it later after operation complete.
> > 
> > The most special case is for set_parent() operation which requires both parent,
> > old one and new one, to be enabled at the same time during the operation.
> > 
> > The patch series is based on for-next branch of Michael's git:
> > git://git.kernel.org/pub/scm/linux/kernel/git/clk/linux.git
> > 
> > Change Log:
> > v2->v3:
> >  * rebased version, no other changes.
> > 
> > v1->v2:
> >  Mainly addressed Stephen Boyd's comments
> >  * remove dupliciated code with __clk_set_parent_after
> >  * introduce more clk_core_x APIs for core easily use
> >  * move clk_disable_unused code position
> >  * use clk_core_x API to make code more clean and easily read
> > 
> > Dong Aisheng (5):
> >   clk: remove duplicated code with __clk_set_parent_after
> >   clk: introduce clk_core_enable_lock and clk_core_disable_lock
> >     functions
> >   clk: move clk_disable_unused after clk_core_disable_unprepare function
> >   clk: core: add CLK_OPS_PARENT_ON flags to support clocks require
> >     parent on
> >   clk: core: add CLK_OPS_PARENT_ON flags to support clocks require
> >     parent on
> > 
> >  drivers/clk/clk.c            | 338 +++++++++++++++++++++++++------------------
> >  include/linux/clk-provider.h |   5 +
> >  2 files changed, 200 insertions(+), 143 deletions(-)
> > 
> 
> Sorry, forgot to update Mike's new email address.
> Updated.
> 

Ping...

Regards
Dong Aisheng

> Regards
> Dong Aisheng
> 
> > -- 
> > 1.9.1
> > 


From leo.yan at linaro.org  Tue Aug  4 02:56:26 2015
From: leo.yan at linaro.org (Leo Yan)
Date: Tue, 4 Aug 2015 17:56:26 +0800
Subject: [RFC PATCH 2/3] mailbox: Hisilicon: add mailbox driver
In-Reply-To: <1438679859.8734.35.camel@tiscali.nl>
References: <1438564390-28111-1-git-send-email-leo.yan@linaro.org>
 <1438564390-28111-3-git-send-email-leo.yan@linaro.org>
 <1438677024.8734.24.camel@tiscali.nl>
 <20150804084930.GA27609@leoy-linaro>
 <1438679859.8734.35.camel@tiscali.nl>
Message-ID: <20150804095626.GC27609@leoy-linaro>

On Tue, Aug 04, 2015 at 11:17:39AM +0200, Paul Bolle wrote:
> On di, 2015-08-04 at 16:49 +0800, Leo Yan wrote:
> > On Tue, Aug 04, 2015 at 10:30:24AM +0200, Paul Bolle wrote:
> > > On ma, 2015-08-03 at 09:13 +0800, Leo Yan wrote:
> > > > --- /dev/null
> > > > +++ b/drivers/mailbox/hisilicon/Kconfig
> > > 
> > > > +config HISI_MBOX
> > > > +	bool "Hisilicon's Mailbox"
> > > > +	depends on ARCH_HISI || OF
> > > 
> > > ARCH_HISI is available on either ARM64 or ARM. ARM64 selects OF. On ARM
> > > ARCH_HISI depends on ARCH_MULTIV7 which depends on ARCH_MULTIPLATFORM.
> > > That selects USE_OF which on its turn selects OF.
> > > 
> > > So, HISI_MBOX implies OF, correct?
> > 
> > Exactly, will simply use "depends on ARCH_HISI".
> 
> That change would alter the dependencies. My remark was made just to
> make clear why I think CONFIG_OF will always be defined. But now I guess
> you actually meant
> 	depends on ARCH_HISI && OF

Correct, shame for my wrong logic :)

> And that would, I think, indeed be equivalent to
> 	depends on ARCH_HISI

Thanks,
Leo Yan


From b20788 at freescale.com  Tue Aug  4 10:48:35 2015
From: b20788 at freescale.com (Anson Huang)
Date: Wed, 5 Aug 2015 01:48:35 +0800
Subject: [PATCH 1/3] ARM: dts: imx6ul: add sram support for i.mx6ul
Message-ID: <1438710517-6515-1-git-send-email-b20788@freescale.com>

Add SRAM support for i.MX6UL, it has 128KB ocram
starting from 0x900000.

Signed-off-by: Anson Huang <b20788 at freescale.com>
---
 arch/arm/boot/dts/imx6ul.dtsi | 5 +++++
 1 file changed, 5 insertions(+)

diff --git a/arch/arm/boot/dts/imx6ul.dtsi b/arch/arm/boot/dts/imx6ul.dtsi
index b6c6c31..227ba6e 100644
--- a/arch/arm/boot/dts/imx6ul.dtsi
+++ b/arch/arm/boot/dts/imx6ul.dtsi
@@ -133,6 +133,11 @@
 			status = "disabled";
 		};
 
+		ocram: sram at 00900000 {
+			compatible = "mmio-sram";
+			reg = <0x00900000 0x20000>;
+		};
+
 		aips1: aips-bus at 02000000 {
 			compatible = "fsl,aips-bus", "simple-bus";
 			#address-cells = <1>;
-- 
1.9.1



From b20788 at freescale.com  Tue Aug  4 10:48:36 2015
From: b20788 at freescale.com (Anson Huang)
Date: Wed, 5 Aug 2015 01:48:36 +0800
Subject: [PATCH 2/3] ARM: dts: imx6ul: add mmdc support for i.mx6ul
In-Reply-To: <1438710517-6515-1-git-send-email-b20788@freescale.com>
References: <1438710517-6515-1-git-send-email-b20788@freescale.com>
Message-ID: <1438710517-6515-2-git-send-email-b20788@freescale.com>

Add MMDC support for i.MX6UL.

Signed-off-by: Anson Huang <b20788 at freescale.com>
---
 arch/arm/boot/dts/imx6ul.dtsi | 5 +++++
 1 file changed, 5 insertions(+)

diff --git a/arch/arm/boot/dts/imx6ul.dtsi b/arch/arm/boot/dts/imx6ul.dtsi
index 227ba6e..d3c7ae1 100644
--- a/arch/arm/boot/dts/imx6ul.dtsi
+++ b/arch/arm/boot/dts/imx6ul.dtsi
@@ -585,6 +585,11 @@
 				status = "disabled";
 			};
 
+			mmdc: mmdc at 021b0000 {
+				compatible = "fsl,imx6ul-mmdc", "fsl,imx6q-mmdc";
+				reg = <0x021b0000 0x4000>;
+			};
+
 			qspi: qspi at 021e0000 {
 				#address-cells = <1>;
 				#size-cells = <0>;
-- 
1.9.1



From b20788 at freescale.com  Tue Aug  4 10:48:37 2015
From: b20788 at freescale.com (Anson Huang)
Date: Wed, 5 Aug 2015 01:48:37 +0800
Subject: [PATCH 3/3] ARM: imx: add suspend/resume support for i.mx6ul
In-Reply-To: <1438710517-6515-1-git-send-email-b20788@freescale.com>
References: <1438710517-6515-1-git-send-email-b20788@freescale.com>
Message-ID: <1438710517-6515-3-git-send-email-b20788@freescale.com>

This patch adds suspend function for i.MX6UL, it supports
"standby" and "mem" mode, for "standby" mode, SoC will
enter STOP mode only, while for "mem" mode, SoC will
enter STOP mode and DDR IO will be set to low power
mode.

As i.MX6UL contains a "Cortex-A7" ARM core which has no
PL310, so we need to avoid any PL310 operations during
suspend/resume, also, we need to flush Cortex-A7's inernal
L2 cache before suspend.

Signed-off-by: Anson Huang <b20788 at freescale.com>
---
 arch/arm/mach-imx/common.h       |  1 +
 arch/arm/mach-imx/mach-imx6ul.c  |  2 ++
 arch/arm/mach-imx/pm-imx6.c      | 46 ++++++++++++++++++++++++++++++++++------
 arch/arm/mach-imx/suspend-imx6.S |  3 +++
 4 files changed, 46 insertions(+), 6 deletions(-)

diff --git a/arch/arm/mach-imx/common.h b/arch/arm/mach-imx/common.h
index 21e4e86..e2d5383 100644
--- a/arch/arm/mach-imx/common.h
+++ b/arch/arm/mach-imx/common.h
@@ -131,6 +131,7 @@ void imx6q_pm_init(void);
 void imx6dl_pm_init(void);
 void imx6sl_pm_init(void);
 void imx6sx_pm_init(void);
+void imx6ul_pm_init(void);
 
 #ifdef CONFIG_PM
 void imx51_pm_init(void);
diff --git a/arch/arm/mach-imx/mach-imx6ul.c b/arch/arm/mach-imx/mach-imx6ul.c
index f206506..f78c107 100644
--- a/arch/arm/mach-imx/mach-imx6ul.c
+++ b/arch/arm/mach-imx/mach-imx6ul.c
@@ -22,6 +22,7 @@ static void __init imx6ul_init_machine(void)
 
 	of_platform_populate(NULL, of_default_bus_match_table, NULL, NULL);
 	imx_anatop_init();
+	imx6ul_pm_init();
 }
 
 static void __init imx6ul_init_irq(void)
@@ -29,6 +30,7 @@ static void __init imx6ul_init_irq(void)
 	imx_init_revision_from_anatop();
 	imx_src_init();
 	irqchip_init();
+	imx6_pm_ccm_init("fsl,imx6ul-ccm");
 }
 
 static const char *imx6ul_dt_compat[] __initconst = {
diff --git a/arch/arm/mach-imx/pm-imx6.c b/arch/arm/mach-imx/pm-imx6.c
index 8ff8fc0..4470376 100644
--- a/arch/arm/mach-imx/pm-imx6.c
+++ b/arch/arm/mach-imx/pm-imx6.c
@@ -93,6 +93,7 @@ struct imx6_pm_socdata {
 	const char *src_compat;
 	const char *iomuxc_compat;
 	const char *gpc_compat;
+	const char *pl310_compat;
 	const u32 mmdc_io_num;
 	const u32 *mmdc_io_offset;
 };
@@ -137,11 +138,19 @@ static const u32 imx6sx_mmdc_io_offset[] __initconst = {
 	0x330, 0x334, 0x338, 0x33c, /* SDQS0 ~ SDQS3 */
 };
 
+static const u32 imx6ul_mmdc_io_offset[] __initconst = {
+	0x244, 0x248, 0x24c, 0x250, /* DQM0, DQM1, RAS, CAS */
+	0x27c, 0x498, 0x4a4, 0x490, /* SDCLK0, GPR_B0DS-B1DS, GPR_ADDS */
+	0x280, 0x284, 0x260, 0x264, /* SDQS0~1, SODT0, SODT1 */
+	0x494, 0x4b0,	            /* MODE_CTL, MODE, */
+};
+
 static const struct imx6_pm_socdata imx6q_pm_data __initconst = {
 	.mmdc_compat = "fsl,imx6q-mmdc",
 	.src_compat = "fsl,imx6q-src",
 	.iomuxc_compat = "fsl,imx6q-iomuxc",
 	.gpc_compat = "fsl,imx6q-gpc",
+	.pl310_compat = "arm,pl310-cache",
 	.mmdc_io_num = ARRAY_SIZE(imx6q_mmdc_io_offset),
 	.mmdc_io_offset = imx6q_mmdc_io_offset,
 };
@@ -151,6 +160,7 @@ static const struct imx6_pm_socdata imx6dl_pm_data __initconst = {
 	.src_compat = "fsl,imx6q-src",
 	.iomuxc_compat = "fsl,imx6dl-iomuxc",
 	.gpc_compat = "fsl,imx6q-gpc",
+	.pl310_compat = "arm,pl310-cache",
 	.mmdc_io_num = ARRAY_SIZE(imx6dl_mmdc_io_offset),
 	.mmdc_io_offset = imx6dl_mmdc_io_offset,
 };
@@ -160,6 +170,7 @@ static const struct imx6_pm_socdata imx6sl_pm_data __initconst = {
 	.src_compat = "fsl,imx6sl-src",
 	.iomuxc_compat = "fsl,imx6sl-iomuxc",
 	.gpc_compat = "fsl,imx6sl-gpc",
+	.pl310_compat = "arm,pl310-cache",
 	.mmdc_io_num = ARRAY_SIZE(imx6sl_mmdc_io_offset),
 	.mmdc_io_offset = imx6sl_mmdc_io_offset,
 };
@@ -169,10 +180,21 @@ static const struct imx6_pm_socdata imx6sx_pm_data __initconst = {
 	.src_compat = "fsl,imx6sx-src",
 	.iomuxc_compat = "fsl,imx6sx-iomuxc",
 	.gpc_compat = "fsl,imx6sx-gpc",
+	.pl310_compat = "arm,pl310-cache",
 	.mmdc_io_num = ARRAY_SIZE(imx6sx_mmdc_io_offset),
 	.mmdc_io_offset = imx6sx_mmdc_io_offset,
 };
 
+static const struct imx6_pm_socdata imx6ul_pm_data __initconst = {
+	.mmdc_compat = "fsl,imx6ul-mmdc",
+	.src_compat = "fsl,imx6ul-src",
+	.iomuxc_compat = "fsl,imx6ul-iomuxc",
+	.gpc_compat = "fsl,imx6ul-gpc",
+	.pl310_compat = NULL,
+	.mmdc_io_num = ARRAY_SIZE(imx6ul_mmdc_io_offset),
+	.mmdc_io_offset = imx6ul_mmdc_io_offset,
+};
+
 /*
  * This structure is for passing necessary data for low level ocram
  * suspend code(arch/arm/mach-imx/suspend-imx6.S), if this struct
@@ -290,7 +312,7 @@ int imx6_set_lpm(enum mxc_cpu_pwr_mode mode)
 		val |= BM_CLPCR_SBYOS;
 		if (cpu_is_imx6sl())
 			val |= BM_CLPCR_BYPASS_PMIC_READY;
-		if (cpu_is_imx6sl() || cpu_is_imx6sx())
+		if (cpu_is_imx6sl() || cpu_is_imx6sx() || cpu_is_imx6ul())
 			val |= BM_CLPCR_BYP_MMDC_CH0_LPM_HS;
 		else
 			val |= BM_CLPCR_BYP_MMDC_CH1_LPM_HS;
@@ -330,6 +352,10 @@ static int imx6q_suspend_finish(unsigned long val)
 		 * as we need to float DDR IO.
 		 */
 		local_flush_tlb_all();
+		/* check if need to flush internal L2 cache */
+		if (!((struct imx6_cpu_pm_info *)
+			suspend_ocram_base)->l2_base.vbase)
+			flush_cache_all();
 		imx6_suspend_in_ocram_fn(suspend_ocram_base);
 	}
 
@@ -470,6 +496,7 @@ static int __init imx6q_suspend_init(const struct imx6_pm_socdata *socdata)
 	suspend_ocram_base = __arm_ioremap_exec(ocram_pbase,
 		MX6Q_SUSPEND_OCRAM_SIZE, false);
 
+	memset(suspend_ocram_base, 0, sizeof(*pm_info));
 	pm_info = suspend_ocram_base;
 	pm_info->pbase = ocram_pbase;
 	pm_info->resume_addr = virt_to_phys(v7_cpu_resume);
@@ -505,11 +532,13 @@ static int __init imx6q_suspend_init(const struct imx6_pm_socdata *socdata)
 		goto gpc_map_failed;
 	}
 
-	ret = imx6_pm_get_base(&pm_info->l2_base, "arm,pl310-cache");
-	if (ret) {
-		pr_warn("%s: failed to get pl310-cache base %d!\n",
-			__func__, ret);
-		goto pl310_cache_map_failed;
+	if (socdata->pl310_compat) {
+		ret = imx6_pm_get_base(&pm_info->l2_base, socdata->pl310_compat);
+		if (ret) {
+			pr_warn("%s: failed to get pl310-cache base %d!\n",
+				__func__, ret);
+			goto pl310_cache_map_failed;
+		}
 	}
 
 	pm_info->ddr_type = imx_mmdc_get_ddr_type();
@@ -610,3 +639,8 @@ void __init imx6sx_pm_init(void)
 {
 	imx6_pm_common_init(&imx6sx_pm_data);
 }
+
+void __init imx6ul_pm_init(void)
+{
+	imx6_pm_common_init(&imx6ul_pm_data);
+}
diff --git a/arch/arm/mach-imx/suspend-imx6.S b/arch/arm/mach-imx/suspend-imx6.S
index b99987b..76ee2ce 100644
--- a/arch/arm/mach-imx/suspend-imx6.S
+++ b/arch/arm/mach-imx/suspend-imx6.S
@@ -79,12 +79,15 @@
 	/* sync L2 cache to drain L2's buffers to DRAM. */
 #ifdef CONFIG_CACHE_L2X0
 	ldr	r11, [r0, #PM_INFO_MX6Q_L2_V_OFFSET]
+	teq	r11, #0
+	beq	6f
 	mov	r6, #0x0
 	str	r6, [r11, #L2X0_CACHE_SYNC]
 1:
 	ldr	r6, [r11, #L2X0_CACHE_SYNC]
 	ands	r6, r6, #0x1
 	bne	1b
+6:
 #endif
 
 	.endm
-- 
1.9.1



From p.fedin at samsung.com  Tue Aug  4 02:59:49 2015
From: p.fedin at samsung.com (Pavel Fedin)
Date: Tue, 04 Aug 2015 12:59:49 +0300
Subject: [PATCH TRIVIAL] Enable GICv2m on ARM virt machine
Message-ID: <00f501d0ce9c$4d57bcc0$e8073640$@samsung.com>

qemu implementation of "virt" includes GICv2m. This commit allows to use
it also on ARM32 architecture.

Signed-off-by: Pavel Fedin <p.fedin at samsung.com>
---
 arch/arm/Kconfig            | 1 +
 arch/arm/include/asm/Kbuild | 1 +
 2 files changed, 2 insertions(+)

diff --git a/arch/arm/Kconfig b/arch/arm/Kconfig
index 45df48b..1091025 100644
--- a/arch/arm/Kconfig
+++ b/arch/arm/Kconfig
@@ -815,6 +815,7 @@ config ARCH_VIRT
 	bool "Dummy Virtual Machine" if ARCH_MULTI_V7
 	select ARM_AMBA
 	select ARM_GIC
+	select ARM_GIC_V2M if PCI_MSI
 	select ARM_PSCI
 	select HAVE_ARM_ARCH_TIMER
 
diff --git a/arch/arm/include/asm/Kbuild b/arch/arm/include/asm/Kbuild
index 3c4596d..01806f5 100644
--- a/arch/arm/include/asm/Kbuild
+++ b/arch/arm/include/asm/Kbuild
@@ -14,6 +14,7 @@ generic-y += local.h
 generic-y += local64.h
 generic-y += mcs_spinlock.h
 generic-y += msgbuf.h
+generic-y += msi.h
 generic-y += param.h
 generic-y += parport.h
 generic-y += poll.h
-- 
1.9.5.msysgit.0




From sergei.shtylyov at cogentembedded.com  Tue Aug  4 03:03:17 2015
From: sergei.shtylyov at cogentembedded.com (Sergei Shtylyov)
Date: Tue, 4 Aug 2015 13:03:17 +0300
Subject: [PATCH 9/9] usb: misc: ftdi-elan: Simplify return statement
In-Reply-To: <21701034f1472a3d154c77dd8d8be017565885f6.1438678566.git.skarajga@visteon.com>
References: <cover.1438678566.git.skarajga@visteon.com>
 <21701034f1472a3d154c77dd8d8be017565885f6.1438678566.git.skarajga@visteon.com>
Message-ID: <55C08DE5.3060106@cogentembedded.com>

Hello.

On 8/4/2015 12:12 PM, Karajgaonkar, Saurabh (S.) wrote:

> From: Saurabh Karajgaonkar <skarajga at visteon.com>

> Replace redundant variable use in return statement.

> Signed-off-by: Saurabh Karajgaonkar <skarajga at visteon.com>
> ---
>   drivers/usb/misc/ftdi-elan.c | 10 ++--------
>   1 file changed, 2 insertions(+), 8 deletions(-)

> diff --git a/drivers/usb/misc/ftdi-elan.c b/drivers/usb/misc/ftdi-elan.c
> index 8ab1f8f..1545f12 100644
> --- a/drivers/usb/misc/ftdi-elan.c
> +++ b/drivers/usb/misc/ftdi-elan.c
> @@ -2568,11 +2568,8 @@ static int ftdi_elan_close_controller(struct usb_ftdi *ftdi, int fn)
>   					    0x00);
>   	if (UxxxStatus)
>   		return UxxxStatus;
> -	UxxxStatus = ftdi_elan_read_config(ftdi, activePCIfn | reg, 0,
> +	return ftdi_elan_read_config(ftdi, activePCIfn | reg, 0,
>   					   &pcidata);

    Please keep the continuation line aligned by starting it under 'ftdi'.

[...]
> @@ -2695,11 +2692,8 @@ static int ftdi_elan_setupOHCI(struct usb_ftdi *ftdi)
>   		}
>   	}
>   	if (ftdi->function > 0) {
> -		UxxxStatus = ftdi_elan_setup_controller(ftdi,
> +		return ftdi_elan_setup_controller(ftdi,
>   							ftdi->function - 1);

    Likewise.

[...]

MBR, Sergei



From b20788 at freescale.com  Tue Aug  4 10:59:24 2015
From: b20788 at freescale.com (Anson Huang)
Date: Wed, 5 Aug 2015 01:59:24 +0800
Subject: [PATCH V2] ARM: imx: add cpuidle support for i.mx6ul
Message-ID: <1438711164-9106-1-git-send-email-b20788@freescale.com>

This patch introduces an independent cpuidle driver for
i.MX6UL, totally 3 levels of cpuidle are supported as below:

1. ARM WFI;
2. SOC in WAIT mode;
3. SOC in WAIT mode + ARM power off.

Signed-off-by: Anson Huang <b20788 at freescale.com>
---
change from V1:
	remove CPUIDLE_FLAG_TIMER_STOP flag as i.MX6UL does
NOT use local timer.
 arch/arm/mach-imx/Makefile         |   1 +
 arch/arm/mach-imx/cpuidle-imx6ul.c | 105 +++++++++++++++++++++++++++++++++++++
 arch/arm/mach-imx/cpuidle.h        |   5 ++
 arch/arm/mach-imx/mach-imx6ul.c    |   8 +++
 4 files changed, 119 insertions(+)
 create mode 100644 arch/arm/mach-imx/cpuidle-imx6ul.c

diff --git a/arch/arm/mach-imx/Makefile b/arch/arm/mach-imx/Makefile
index fb689d8..1d7df9c 100644
--- a/arch/arm/mach-imx/Makefile
+++ b/arch/arm/mach-imx/Makefile
@@ -28,6 +28,7 @@ obj-$(CONFIG_SOC_IMX5) += cpuidle-imx5.o
 obj-$(CONFIG_SOC_IMX6Q) += cpuidle-imx6q.o
 obj-$(CONFIG_SOC_IMX6SL) += cpuidle-imx6sl.o
 obj-$(CONFIG_SOC_IMX6SX) += cpuidle-imx6sx.o
+obj-$(CONFIG_SOC_IMX6UL) += cpuidle-imx6ul.o
 endif
 
 ifdef CONFIG_SND_IMX_SOC
diff --git a/arch/arm/mach-imx/cpuidle-imx6ul.c b/arch/arm/mach-imx/cpuidle-imx6ul.c
new file mode 100644
index 0000000..27ab28a
--- /dev/null
+++ b/arch/arm/mach-imx/cpuidle-imx6ul.c
@@ -0,0 +1,105 @@
+/*
+ * Copyright (C) 2015 Freescale Semiconductor, Inc.
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License version 2 as
+ * published by the Free Software Foundation.
+ */
+
+#include <linux/cpuidle.h>
+#include <linux/cpu_pm.h>
+#include <linux/module.h>
+#include <asm/cacheflush.h>
+#include <asm/cpuidle.h>
+#include <asm/suspend.h>
+
+#include "common.h"
+#include "cpuidle.h"
+
+static int imx6ul_idle_finish(unsigned long val)
+{
+	flush_cache_all();
+	cpu_do_idle();
+
+	return 0;
+}
+
+static int imx6ul_enter_wait(struct cpuidle_device *dev,
+			    struct cpuidle_driver *drv, int index)
+{
+	imx6_set_lpm(WAIT_UNCLOCKED);
+
+	switch (index) {
+	case 1:
+		cpu_do_idle();
+		break;
+	case 2:
+		imx6_enable_rbc(true);
+		imx_gpc_set_arm_power_in_lpm(true);
+		imx_set_cpu_jump(0, v7_cpu_resume);
+		/* Need to notify there is a cpu pm operation. */
+		cpu_pm_enter();
+		cpu_cluster_pm_enter();
+
+		cpu_suspend(0, imx6ul_idle_finish);
+
+		cpu_cluster_pm_exit();
+		cpu_pm_exit();
+		imx_gpc_set_arm_power_in_lpm(false);
+		imx6_enable_rbc(false);
+		break;
+	default:
+		break;
+	}
+
+	imx6_set_lpm(WAIT_CLOCKED);
+
+	return index;
+}
+
+static struct cpuidle_driver imx6ul_cpuidle_driver = {
+	.name = "imx6ul_cpuidle",
+	.owner = THIS_MODULE,
+	.states = {
+		/* WFI */
+		ARM_CPUIDLE_WFI_STATE,
+		/* WAIT */
+		{
+			.exit_latency = 50,
+			.target_residency = 75,
+			.enter = imx6ul_enter_wait,
+			.name = "WAIT",
+			.desc = "Clock off",
+		},
+		/* WAIT + ARM power off  */
+		{
+			/*
+			 * ARM gating 31us * 5 + RBC clear 65us
+			 * and some margin for SW execution, here set it
+			 * to 300us.
+			 */
+			.exit_latency = 300,
+			.target_residency = 500,
+			.enter = imx6ul_enter_wait,
+			.name = "LOW-POWER-IDLE",
+			.desc = "ARM power off",
+		},
+	},
+	.state_count = 3,
+	.safe_state_index = 0,
+};
+
+int __init imx6ul_cpuidle_init(void)
+{
+	imx6_enable_rbc(false);
+	/*
+	 * set ARM power up/down timing to the fastest,
+	 * sw2iso and sw can be set to one 32K cycle = 31us
+	 * except for power up sw2iso which need to be
+	 * larger than LDO ramp up time.
+	 */
+	imx_gpc_set_arm_power_up_timing(2, 1);
+	imx_gpc_set_arm_power_down_timing(1, 1);
+
+	return cpuidle_register(&imx6ul_cpuidle_driver, NULL);
+}
diff --git a/arch/arm/mach-imx/cpuidle.h b/arch/arm/mach-imx/cpuidle.h
index f914012..4dcf71d 100644
--- a/arch/arm/mach-imx/cpuidle.h
+++ b/arch/arm/mach-imx/cpuidle.h
@@ -15,6 +15,7 @@ extern int imx5_cpuidle_init(void);
 extern int imx6q_cpuidle_init(void);
 extern int imx6sl_cpuidle_init(void);
 extern int imx6sx_cpuidle_init(void);
+extern int imx6ul_cpuidle_init(void);
 #else
 static inline int imx5_cpuidle_init(void)
 {
@@ -32,4 +33,8 @@ static inline int imx6sx_cpuidle_init(void)
 {
 	return 0;
 }
+static inline int imx6ul_cpuidle_init(void)
+{
+	return 0;
+}
 #endif
diff --git a/arch/arm/mach-imx/mach-imx6ul.c b/arch/arm/mach-imx/mach-imx6ul.c
index f206506..0f4b95c 100644
--- a/arch/arm/mach-imx/mach-imx6ul.c
+++ b/arch/arm/mach-imx/mach-imx6ul.c
@@ -11,6 +11,7 @@
 #include <asm/mach/map.h>
 
 #include "common.h"
+#include "cpuidle.h"
 
 static void __init imx6ul_init_machine(void)
 {
@@ -29,6 +30,12 @@ static void __init imx6ul_init_irq(void)
 	imx_init_revision_from_anatop();
 	imx_src_init();
 	irqchip_init();
+	imx6_pm_ccm_init("fsl,imx6ul-ccm");
+}
+
+static void __init imx6ul_init_late(void)
+{
+	imx6ul_cpuidle_init();
 }
 
 static const char *imx6ul_dt_compat[] __initconst = {
@@ -40,4 +47,5 @@ DT_MACHINE_START(IMX6UL, "Freescale i.MX6 Ultralite (Device Tree)")
 	.init_irq	= imx6ul_init_irq,
 	.init_machine	= imx6ul_init_machine,
 	.dt_compat	= imx6ul_dt_compat,
+	.init_late	= imx6ul_init_late,
 MACHINE_END
-- 
1.9.1



From gabriele.paoloni at huawei.com  Tue Aug  4 03:12:05 2015
From: gabriele.paoloni at huawei.com (Gabriele Paoloni)
Date: Tue, 4 Aug 2015 10:12:05 +0000
Subject: [PATCH v6] PCI: Store PCIe bus address in struct of_pci_range
In-Reply-To: <7F6386B4-D2F5-4840-AC72-F8C76CBC3B94@gmail.com>
References: <1438010223-124422-1-git-send-email-gabriele.paoloni@huawei.com>
 <20150729172053.GE31170@google.com>
 <EE11001F9E5DDD47B7634E2F8A612F2E01D6F350@lhreml503-mbs>
 <CAL_JsqKs11-sXQTdBD+ZjbVYFWUHBARTW9q5MF1hCXUhZ+nWLQ@mail.gmail.com>
 <EE11001F9E5DDD47B7634E2F8A612F2E01D6F94A@lhreml503-mbs>
 <20150730161447.GG9640@google.com>
 <EE11001F9E5DDD47B7634E2F8A612F2E01D6FB3B@lhreml503-mbs>
 <20150730171445.GI9640@google.com>
 <EE11001F9E5DDD47B7634E2F8A612F2E01D6FC15@lhreml503-mbs>
 <CAL_Jsq+aQVakaZf4xo7sxnVyTmPR+HJ-9ByyS6OYJ0PHDYOwmg@mail.gmail.com>
 <EE11001F9E5DDD47B7634E2F8A612F2E01D70589@lhreml503-mbs>
 <55BB8CC6.1080203@ti.com>
 <CAL_JsqJqjiWVaKs-3ghQ1EBQzRRQ38GzkMV+FELPj53bSF-yXQ@mail.gmail.com>
 <EE11001F9E5DDD47B7634E2F8A612F2E01D712E7@lhreml503-mbs>
 <7F6386B4-D2F5-4840-AC72-F8C76CBC3B94@gmail.com>
Message-ID: <EE11001F9E5DDD47B7634E2F8A612F2E01D719D1@lhreml503-mbs>



> -----Original Message-----
> From: Jingoo Han [mailto:jingoohan1 at gmail.com]
> Sent: Tuesday, August 04, 2015 5:20 AM
> To: Gabriele Paoloni
> Cc: Rob Herring; Kishon Vijay Abraham I; Bjorn Helgaas; arnd at arndb.de;
> lorenzo.pieralisi at arm.com; Wangzhou (B); robh+dt at kernel.org;
> james.morse at arm.com; Liviu.Dudau at arm.com; linux-pci at vger.kernel.org;
> linux-arm-kernel at lists.infradead.org; devicetree at vger.kernel.org;
> Yuanzhichang; Zhudacai; zhangjukuo; qiuzhenfa; Liguozhu (Kenneth);
> Pratyush Anand; Arnd Bergmann; jingoohan1 at gmail.com
> Subject: Re: [PATCH v6] PCI: Store PCIe bus address in struct
> of_pci_range
> 
> On 2015. 8. 3., at PM 8:18, Gabriele Paoloni
> <gabriele.paoloni at huawei.com> wrote:
> >
> > Rob, Kishon what about the following solution?....
> >
> > ---
> > drivers/pci/host/pci-dra7xx.c      | 12 ++++++++++++
> > drivers/pci/host/pcie-designware.c |  9 +++------
> 
> Hi Paoloni,
> 
> OK, it looks good.
> I want you to revert the following patch.
> 
> commit "f4c55c5a3f7f (PCI: designware: Program ATU with untranslated
> address)"
> 
> Would you remove all '*_mode_base's?

Hi Jingoo Han,

If I reverted the commit, in order to get designware working, dra7 
should mask directly the CPU addresses stored in pp->cfg0_base, 
pp->cfg1_base, pp->mem_base and pp->io_base.

The masking would happen at this point: 
http://lxr.free-electrons.com/source/drivers/pci/host/pcie-designware.c#L493

Now:
- I see that pp->cfg<0/1>_base are used in devm_ioremap before that 
  point and nowhere else, so they should be ok.
- pp->mem_base is used in dw_pcie_setup_rc(); dw_pcie_setup_rc() is called
  in dra7xx_pcie_host_init()...so here I should move the masking after
  dw_pcie_setup() retuned, but I think it should be ok
- pp->io_base is used in pci_ioremap_io() in dw_pcie_setup(). Now currently
  in designware this is called by pci_bios_init_hw(); this is after the 
  masking....so here we would have a the wrong value passed

Said that if you look at "[PATCH v5 2/5] PCI: designware: Add ARM64 support",
that is the patchset where this patch is needed, you can see that 
dw_pcie_setup() is removed and pp->io_base is used in pci_remap_iospace() before 
the masking would happen in dra7xx_pcie_host_init()...so for this patchset we 
should be good to revert the commit.

I propose to add a new patch in the patchset "[PATCH v5 0/5] PCI: hisi: Add PCIe 
host support for HiSilicon SoC Hip05" as the one I just posted in this 
thread (this would not revert the commit but just moves the masking to dra7xx)

I would revert the commit in "[PATCH v5 2/5] PCI: designware: Add ARM64 support"
together with the rest of designware rework. 

So we would have always a working version of designware...

Are you ok with this?

> 
> Best regards,
> Jingoo Han
> 
> > 2 files changed, 15 insertions(+), 6 deletions(-)
> >
> > diff --git a/drivers/pci/host/pci-dra7xx.c b/drivers/pci/host/pci-
> dra7xx.c
> > index 80db09e..bb2635f 100644
> > --- a/drivers/pci/host/pci-dra7xx.c
> > +++ b/drivers/pci/host/pci-dra7xx.c
> > @@ -61,6 +61,7 @@
> >
> > #define    PCIECTRL_DRA7XX_CONF_PHY_CS            0x010C
> > #define    LINK_UP                        BIT(16)
> > +#define CPU_TO_BUS_ADDR             0x0FFFFFFF
> >
> > struct dra7xx_pcie {
> >    void __iomem        *base;
> > @@ -138,6 +139,17 @@ static void dra7xx_pcie_enable_interrupts(struct
> pcie_port *pp)
> >
> > static void dra7xx_pcie_host_init(struct pcie_port *pp)
> > {
> > +    if (pp->io_mod_base)
> > +        pp->io_mod_base &= CPU_TO_BUS_ADDR;
> > +
> > +    if (pp->mem_mod_base)
> > +        pp->mem_mod_base &= CPU_TO_BUS_ADDR;
> > +
> > +    if (pp->cfg0_mod_base) {
> > +        pp->cfg0_mod_base &= CPU_TO_BUS_ADDR;
> > +        pp->cfg1_mod_base &= CPU_TO_BUS_ADDR;
> > +    }
> > +
> >    dw_pcie_setup_rc(pp);
> >    dra7xx_pcie_establish_link(pp);
> >    if (IS_ENABLED(CONFIG_PCI_MSI))
> > diff --git a/drivers/pci/host/pcie-designware.c
> b/drivers/pci/host/pcie-designware.c
> > index 69486be..06c682b 100644
> > --- a/drivers/pci/host/pcie-designware.c
> > +++ b/drivers/pci/host/pcie-designware.c
> > @@ -416,8 +416,7 @@ int dw_pcie_host_init(struct pcie_port *pp)
> >            pp->io_base = range.cpu_addr;
> >
> >            /* Find the untranslated IO space address */
> > -            pp->io_mod_base = of_read_number(parser.range -
> > -                             parser.np + na, ns);
> > +            pp->io_mod_base = range.cpu_addr;;
> >        }
> >        if (restype == IORESOURCE_MEM) {
> >            of_pci_range_to_resource(&range, np, &pp->mem);
> > @@ -426,8 +425,7 @@ int dw_pcie_host_init(struct pcie_port *pp)
> >            pp->mem_bus_addr = range.pci_addr;
> >
> >            /* Find the untranslated MEM space address */
> > -            pp->mem_mod_base = of_read_number(parser.range -
> > -                              parser.np + na, ns);
> > +            pp->mem_mod_base = range.cpu_addr;
> >        }
> >        if (restype == 0) {
> >            of_pci_range_to_resource(&range, np, &pp->cfg);
> > @@ -437,8 +435,7 @@ int dw_pcie_host_init(struct pcie_port *pp)
> >            pp->cfg1_base = pp->cfg.start + pp->cfg0_size;
> >
> >            /* Find the untranslated configuration space address */
> > -            pp->cfg0_mod_base = of_read_number(parser.range -
> > -                               parser.np + na, ns);
> > +            pp->cfg0_mod_base = range.cpu_addr;
> >            pp->cfg1_mod_base = pp->cfg0_mod_base +
> >                        pp->cfg0_size;
> >        }
> > --
> > 1.9.1
> >
> >
> >> -----Original Message-----
> >> From: linux-pci-owner at vger.kernel.org [mailto:linux-pci-
> >> owner at vger.kernel.org] On Behalf Of Rob Herring
> >> Sent: Friday, July 31, 2015 5:53 PM
> >> To: Kishon Vijay Abraham I
> >> Cc: Gabriele Paoloni; Bjorn Helgaas; arnd at arndb.de;
> >> lorenzo.pieralisi at arm.com; Wangzhou (B); robh+dt at kernel.org;
> >> james.morse at arm.com; Liviu.Dudau at arm.com; linux-pci at vger.kernel.org;
> >> linux-arm-kernel at lists.infradead.org; devicetree at vger.kernel.org;
> >> Yuanzhichang; Zhudacai; zhangjukuo; qiuzhenfa; Liguozhu (Kenneth);
> >> Jingoo Han; Pratyush Anand; Arnd Bergmann
> >> Subject: Re: [PATCH v6] PCI: Store PCIe bus address in struct
> >> of_pci_range
> >>
> >> On Fri, Jul 31, 2015 at 9:57 AM, Kishon Vijay Abraham I
> <kishon at ti.com>
> >> wrote:
> >>> +Arnd
> >>>
> >>> Hi,
> >>>
> >>>> On Friday 31 July 2015 07:55 PM, Gabriele Paoloni wrote:
> >>>> [+cc Kishon]
> >>>>
> >>>>> -----Original Message-----
> >>>>> From: linux-pci-owner at vger.kernel.org [mailto:linux-pci-
> >>>>> owner at vger.kernel.org] On Behalf Of Rob Herring
> >>>>> Sent: Thursday, July 30, 2015 9:42 PM
> >>>>> To: Gabriele Paoloni
> >>>>> Cc: Bjorn Helgaas; arnd at arndb.de; lorenzo.pieralisi at arm.com;
> >> Wangzhou
> >>>>> (B); robh+dt at kernel.org; james.morse at arm.com; Liviu.Dudau at arm.com;
> >>>>> linux-pci at vger.kernel.org; linux-arm-kernel at lists.infradead.org;
> >>>>> devicetree at vger.kernel.org; Yuanzhichang; Zhudacai; zhangjukuo;
> >>>>> qiuzhenfa; Liguozhu (Kenneth); Jingoo Han; Pratyush Anand
> >>>>> Subject: Re: [PATCH v6] PCI: Store PCIe bus address in struct
> >>>>> of_pci_range
> >>>>>
> >>>>> On Thu, Jul 30, 2015 at 12:34 PM, Gabriele Paoloni
> >>>>> <gabriele.paoloni at huawei.com> wrote:
> >>>>>>> -----Original Message-----
> >>>>>>> From: Bjorn Helgaas [mailto:bhelgaas at google.com]
> >>>>>>> Sent: 30 July 2015 18:15
> >>>>>>> On Thu, Jul 30, 2015 at 04:50:55PM +0000, Gabriele Paoloni
> wrote:
> >>>>>>>>> -----Original Message-----
> >>>>>>>>> From: linux-pci-owner at vger.kernel.org [mailto:linux-pci-
> >>>>>>>>> owner at vger.kernel.org] On Behalf Of Bjorn Helgaas
> >>>>>>>>> Sent: Thursday, July 30, 2015 5:15 PM
> >>>>>>>>> On Thu, Jul 30, 2015 at 01:52:13PM +0000, Gabriele Paoloni
> >> wrote:
> >>>>>
> >>>>> [...]
> >>>>>
> >>>>>>>>>> I don?t think we should rely on [CPU] addresses...what if
> the
> >>>>>>>>> intermediate
> >>>>>>>>>> translation layer changes the lower significant bits of the
> >>>>> "bus
> >>>>>>>>> address"
> >>>>>>>>>> to translate into a cpu address?
> >>>>>>>>>
> >>>>>>>>> Is it really a possiblity that the lower bits could be
> changed?
> >>>>>>>>
> >>>>>>>> I've checked all the current deignware users DTs except "pci-
> >>>>>>> layerscape"
> >>>>>>>> that I could not find:
> >>>>>>>> spear1310.dtsi
> >>>>>>>> spear1340.dtsi
> >>>>>>>> dra7.dtsi
> >>>>>>>> imx6qdl.dtsi
> >>>>>>>> imx6sx.dtsi
> >>>>>>>> keystone.dtsi
> >>>>>>>> exynos5440.dtsi
> >>>>>>>>
> >>>>>>>> None of them modifies the lower bits. To be more precise the
> >> only
> >>>>> guy
> >>>>>>>> that provides another translation layer is "dra7.dtsi":
> >>>>>>>> axi0
> >>>>>>>> http://lxr.free-
> >>>>> electrons.com/source/arch/arm/boot/dts/dra7.dtsi#L207
> >>>>>>>>
> >>>>>>>> axi1
> >>>>>>>> http://lxr.free-
> >>>>> electrons.com/source/arch/arm/boot/dts/dra7.dtsi#L241
> >>>>>>>>
> >>>>>>>> For this case masking the top 4bits (bits28 to 31) should make
> >> the
> >>>>> job.
> >>>>>
> >>>>> IMO, we should just fix this case. After further study, I don't
> >> think
> >>>>> this is a DW issue, but rather an SOC integration issue.
> >>>>>
> >>>>> I believe you can just fixup the address in the pp->ops-
> >host_init
> >> hook.
> >>>>
> >>>> Yes I guess that I could just assign pp->(*)_mod_base to the CPU
> >> address
> >>>> in DW and mask it out in dra7xx_pcie_host_init()...
> >>>>
> >>>> Kishon, would you be ok with that?
> >>>
> >>> Initially I was using *base-mask* property from dt. Me and Arnd
> >> (cc'ed) had
> >>> this discussion [1] before we decided the current approach. It'll
> be
> >> good to
> >>> check with Arnd too.
> >>>
> >>> [1] ->  http://lists.infradead.org/pipermail/linux-arm-kernel/2014-
> >> May/253528.html
> >>
> >> The problem I have here is the use of ranges does not necessarily
> mean
> >> fewer address bits are available. It can be used just for
> convenience
> >> of not putting the full address into every node's reg property. And
> >> vice versa, there are probably plenty of cases where we have the
> full
> >> address in the nodes, but really only some of the address bits are
> >> decoded at the IP block. Whether the address bits are present is
> >> rarely cared about or known by s/w folks until you hit a problem
> like
> >> this. Given this is an isolated case ATM, I would fix it in an
> >> isolated way. It does not affect the binding and could be changed in
> >> the kernel later if this becomes a common need.
> >>
> >> Rob
> >> --
> >> To unsubscribe from this list: send the line "unsubscribe linux-pci"
> in
> >> the body of a message to majordomo at vger.kernel.org
> >> More majordomo info at  http://vger.kernel.org/majordomo-info.html

From gabriele.paoloni at huawei.com  Tue Aug  4 03:23:58 2015
From: gabriele.paoloni at huawei.com (Gabriele Paoloni)
Date: Tue, 4 Aug 2015 10:23:58 +0000
Subject: [PATCH v5 2/5] PCI: designware: Add ARM64 support
In-Reply-To: <55C0872E.9060507@arm.com>
References: <1437794486-21134-1-git-send-email-wangzhou1@hisilicon.com>
 <1437794486-21134-3-git-send-email-wangzhou1@hisilicon.com>
 <55B71F75.5030907@hisilicon.com> <55C0872E.9060507@arm.com>
Message-ID: <EE11001F9E5DDD47B7634E2F8A612F2E01D719E9@lhreml503-mbs>

Hi James

Please see "[PATCH v6] PCI: Store PCIe bus address in struct of_pci_range"

I think if you apply this patch your problem should be solved...

If you follow the discussion you see that this patch is going to be part 
of the next designware patchset...

Wang Zhou said "You need apply Gabriele's patch before applying this patch."
but he didn't specify which one and obviously this patch should have been part
of the patch-set

Sorry for the confusion 

Gab

> -----Original Message-----
> From: James Morse [mailto:james.morse at arm.com]
> Sent: Tuesday, August 04, 2015 10:35 AM
> To: Wangzhou (B)
> Cc: Bjorn Helgaas; Jingoo Han; Pratyush Anand; Arnd Bergmann; Gabriele
> Paoloni; Lorenzo Pieralisi; Liviu Dudau; thomas.petazzoni at free-
> electrons.com; Jason Cooper; robh at kernel.org; linux-pci at vger.kernel.org;
> linux-arm-kernel at lists.infradead.org; devicetree at vger.kernel.org;
> Yuanzhichang; Zhudacai; zhangjukuo; qiuzhenfa; liudongdong (C);
> qiujiang; Kangfenglong; Liguozhu (Kenneth)
> Subject: Re: [PATCH v5 2/5] PCI: designware: Add ARM64 support
> 
> On 28/07/15 07:21, Zhou Wang wrote:
> > On 2015/7/25 11:21, Zhou Wang wrote:
> >> This patch tries to unify ARM32 and ARM64 PCIe in designware driver.
> Delete
> >> function dw_pcie_setup, dw_pcie_scan_bus, dw_pcie_map_irq and struct
> hw_pci,
> >> move related operations to dw_pcie_host_init. Also set pp-
> >root_bus_nr = 0 in
> >> each PCIe host driver which is based on pcie-designware. This patch
> also try
> >> to use of_pci_get_host_bridge_resources for ARM32 and ARM64
> according to the
> >> suggestion for Gabriele[1]
> >>
> >> This patch is based on Gabriele's patch about of_pci_range fix[2]
> >>
> >> I have compiled the driver with multi_v7_defconfig. However, I don't
> have
> >> ARM32 PCIe related board to do test. It will be appreciated if
> someone could
> >> help to test it.
> >>
> >
> > Hi James,
> >
> > If you have time, could you help to test this patch on i.MX 6Quad
> board?
> > You need apply Gabriele's patch before applying this patch.
> >
> > It will be very appreciate and helpful if we can get test result from
> you.
> 
> Applying patches 1 and 2, from v5, onto 4.2-rc5, I still get the same
> problem as before: config cycles to enumerate the second bus aren't
> working. (good news - I have a workaround)
> 
> Output from dmesg below, the lines 'dw_pcie_cfg_read(0xf0180000, 0x0,
> 0x4,
> =0x8878086)' were added by me, 0x8878086 is the intel wireless card
> attached to the board.
> 
> From v4.2-rc5:
> -----------------------------------------------------------------------
> -----------
> imx6q-pcie 1ffc000.pcie: PCI host bridge to bus 0000:00
> pci_bus 0000:00: root bus resource [io 0x1000-0xffff]
> pci_bus 0000:00: root bus resource [mem 0x01000000-0x01efffff]
> pci_bus 0000:00: root bus resource [bus 00-ff]
> pci 0000:00:00.0: [16c3:abcd] type 01 class 0x060400
> pci 0000:00:00.0: reg 0x10: [mem 0x00000000-0x000fffff]
> pci 0000:00:00.0: reg 0x38: [mem 0x00000000-0x0000ffff pref]
> pci 0000:00:00.0: IOMMU is currently not supported for PCI
> pci 0000:00:00.0: supports D1
> pci 0000:00:00.0: PME# supported from D0 D1 D3hot D3cold
> PCI: bus0: Fast back to back transfers disabled
> dw_pcie_cfg_read(0xf0180000, 0x0, 0x4, =0x8878086)
> pci 0000:01:00.0: [8086:0887] type 00 class 0x028000
> dw_pcie_cfg_read(0xf0180000, 0x0, 0x4, =0x8878086)
> pci 0000:01:00.0: reg 0x10: [mem 0x00000000-0x00001fff 64bit]
> pci 0000:01:00.0: IOMMU is currently not supported for PCI
> pci 0000:01:00.0: PME# supported from D0 D3hot D3cold
> PCI: bus1: Fast back to back transfers disabled
> pci_bus 0000:01: busn_res: [bus 01-ff] end is updated to 01
> pci 0000:00:00.0: BAR 0: assigned [mem 0x01000000-0x010fffff]
> pci 0000:00:00.0: BAR 8: assigned [mem 0x01100000-0x011fffff]
> pci 0000:00:00.0: BAR 6: assigned [mem 0x01200000-0x0120ffff pref
> ]
> pci 0000:01:00.0: BAR 0: assigned [mem 0x01100000-0x01101fff 64bi
> t]
> pci 0000:00:00.0: PCI bridge to [bus 01]
> pci 0000:00:00.0:bridge window [mem 0x01100000-0x011fffff]
> pcieport 0000:00:00.0: Signaling PME through PCIe PME interrupt
> pci 0000:01:00.0: Signaling PME through PCIe PME interrupt
> pcie_pme 0000:00:00.0:pcie01: service driver pcie_pme loaded
> -----------------------------------------------------------------------
> -----------
> 
> And then with your two patches:
> -----------------------------------------------------------------------
> -----------
> PCI host bridge /soc/pcie at 0x01000000 ranges:
> No bus range found for /soc/pcie at 0x01000000, using [bus 00-ff]
> err 0x01f00000..0x01f7ffff -> 0x01f00000
> IO 0x01f80000..0x01f8ffff -> 0x00000000
> MEM 0x01000000..0x01efffff -> 0x01000000
> imx6q-pcie 1ffc000.pcie: PCI host bridge to bus 0000:00
> pci_bus 0000:00: root bus resource [bus 00-ff]
> pci_bus 0000:00: root bus resource [??? 0x01f00000-0x01f7ffff fla
> gs 0x0]
> pci_bus 0000:00: root bus resource [io 0x0000-0xffff]
> pci_bus 0000:00: root bus resource [mem 0x01000000-0x01efffff]
> pci 0000:00:00.0: [16c3:abcd] type 01 class 0x060400
> pci 0000:00:00.0: reg 0x10: [mem 0x00000000-0x000fffff]
> pci 0000:00:00.0: reg 0x38: [mem 0x00000000-0x0000ffff pref]
> pci 0000:00:00.0: IOMMU is currently not supported for PCI
> pci 0000:00:00.0: supports D1
> pci 0000:00:00.0: PME# supported from D0 D1 D3hot D3cold
> PCI: bus0: Fast back to back transfers disabled
> dw_pcie_cfg_read(0xf0180000, 0x0, 0x4, =0x0)
> PCI: bus1: Fast back to back transfers enabled
> pci 0000:00:00.0: BAR 0: assigned [mem 0x01000000-0x010fffff]
> pci 0000:00:00.0: BAR 6: assigned [mem 0x01100000-0x0110ffff pref
> ]
> pci 0000:00:00.0: PCI bridge to [bus 01]
> pcieport 0000:00:00.0: Signaling PME through PCIe PME interrupt
> pcie_pme 0000:00:00.0:pcie01: service driver pcie_pme loaded
> -----------------------------------------------------------------------
> -----------
> 
> Root-cause appears to be that the designware driver relies on ATU for
> config and IO accesses. dw_pcie_rd_other_conf() does the appropriate
> magic,
> but with your patches 'pp->cfg0_base' is NULL, despite being correctly
> initialised in dw_pcie_host_init().
> 
> dw_pcie_host_init() initialises the pp->cfg* values correctly after its
> call:
> >  platform_get_resource_byname(pdev, IORESOURCE_MEM, "config");
> 
> But the new code introduced by patch 2 then walks the whole
> resource_list
> and re-initialises the pp->cfg* values. The fault occurs at:
> > /* Find the untranslated configuration space address */
> > pp->cfg0_mod_base = win->__res.start
> 
> where win->__res is uninitialised. The comment in linux/resource_ext.h
> says
> this is the 'default storage for res', so its not valid to assume it
> contains different values to win->res. (in this case, it contains no
> useful
> values).
> 
> The workaround is to remove the re-initialisation of the pp->cfg*
> values,
> as they were already correctly initialised earlier. However, other
> resource
> types are accessing __res directly ... which is probably not correct.
> 
> I need to read-up on what these 'untranslated' addresses are for...
> 
> 
> 
> James
> 



From daniel.lezcano at linaro.org  Tue Aug  4 03:31:19 2015
From: daniel.lezcano at linaro.org (Daniel Lezcano)
Date: Tue, 04 Aug 2015 12:31:19 +0200
Subject: [PATCH 19/20] clocksource: atmel-st: get and use slow clock
In-Reply-To: <1438215726-27452-20-git-send-email-alexandre.belloni@free-electrons.com>
References: <1438215726-27452-1-git-send-email-alexandre.belloni@free-electrons.com>
 <1438215726-27452-20-git-send-email-alexandre.belloni@free-electrons.com>
Message-ID: <55C09477.3080209@linaro.org>

On 07/30/2015 02:22 AM, Alexandre Belloni wrote:
> The current slow clock rate is hardcoded. Properly get the slow clock
> and use its rate.
>
> Signed-off-by: Alexandre Belloni <alexandre.belloni at free-electrons.com>
> ---

[ ... ]

> +struct clk *sclk;

Do you need this variable global ? AFAICS, its scope is in the init 
function, no ?

> +int timer_latch;

static.


-- 
  <http://www.linaro.org/> Linaro.org ? Open source software for ARM SoCs

Follow Linaro:  <http://www.facebook.com/pages/Linaro> Facebook |
<http://twitter.com/#!/linaroorg> Twitter |
<http://www.linaro.org/linaro-blog/> Blog



From james.morse at arm.com  Tue Aug  4 03:40:20 2015
From: james.morse at arm.com (James Morse)
Date: Tue, 04 Aug 2015 11:40:20 +0100
Subject: [PATCH v5 2/5] PCI: designware: Add ARM64 support
In-Reply-To: <EE11001F9E5DDD47B7634E2F8A612F2E01D719E9@lhreml503-mbs>
References: <1437794486-21134-1-git-send-email-wangzhou1@hisilicon.com>
 <1437794486-21134-3-git-send-email-wangzhou1@hisilicon.com>
 <55B71F75.5030907@hisilicon.com> <55C0872E.9060507@arm.com>
 <EE11001F9E5DDD47B7634E2F8A612F2E01D719E9@lhreml503-mbs>
Message-ID: <55C09694.30506@arm.com>

On 04/08/15 11:23, Gabriele Paoloni wrote:
> Hi James
> 
> Please see "[PATCH v6] PCI: Store PCIe bus address in struct of_pci_range"
> 
> I think if you apply this patch your problem should be solved...
> 
> If you follow the discussion you see that this patch is going to be part 
> of the next designware patchset...

Yes I just spotted that series after continuing through my email backlog.

> Wang Zhou said "You need apply Gabriele's patch before applying this patch."
> but he didn't specify which one and obviously this patch should have been part
> of the patch-set

I assumed he meant your patch 1 in the same series, (given the reply was to
patch 2).

With the '[PATCH v6] PCI: Store PCIe bus address in struct of_pci_range'
applied before patches and 1 and 2 of this series - pcie on the
'Freescale i.MX6 Quad SABRE Lite Board' works fine.

I can rescan the bus, load firmware, list nearby APs, and even get MSIs
coming from the card.

Tested-by: James Morse <james.morse at arm.com>



James


From gabriele.paoloni at huawei.com  Tue Aug  4 03:43:06 2015
From: gabriele.paoloni at huawei.com (Gabriele Paoloni)
Date: Tue, 4 Aug 2015 10:43:06 +0000
Subject: [PATCH v5 2/5] PCI: designware: Add ARM64 support
In-Reply-To: <55C09694.30506@arm.com>
References: <1437794486-21134-1-git-send-email-wangzhou1@hisilicon.com>
 <1437794486-21134-3-git-send-email-wangzhou1@hisilicon.com>
 <55B71F75.5030907@hisilicon.com> <55C0872E.9060507@arm.com>
 <EE11001F9E5DDD47B7634E2F8A612F2E01D719E9@lhreml503-mbs>
 <55C09694.30506@arm.com>
Message-ID: <EE11001F9E5DDD47B7634E2F8A612F2E01D71A2D@lhreml503-mbs>

> -----Original Message-----
> From: James Morse [mailto:james.morse at arm.com]
> Sent: Tuesday, August 04, 2015 11:40 AM
> To: Gabriele Paoloni; Wangzhou (B)
> Cc: Bjorn Helgaas; Jingoo Han; Pratyush Anand; Arnd Bergmann; Lorenzo
> Pieralisi; Liviu Dudau; thomas.petazzoni at free-electrons.com; Jason
> Cooper; robh at kernel.org; linux-pci at vger.kernel.org; linux-arm-
> kernel at lists.infradead.org; devicetree at vger.kernel.org; Yuanzhichang;
> Zhudacai; zhangjukuo; qiuzhenfa; liudongdong (C); qiujiang;
> Kangfenglong; Liguozhu (Kenneth)
> Subject: Re: [PATCH v5 2/5] PCI: designware: Add ARM64 support
> 
> On 04/08/15 11:23, Gabriele Paoloni wrote:
> > Hi James
> >
> > Please see "[PATCH v6] PCI: Store PCIe bus address in struct
> of_pci_range"
> >
> > I think if you apply this patch your problem should be solved...
> >
> > If you follow the discussion you see that this patch is going to be
> part
> > of the next designware patchset...
> 
> Yes I just spotted that series after continuing through my email
> backlog.
> 
> > Wang Zhou said "You need apply Gabriele's patch before applying this
> patch."
> > but he didn't specify which one and obviously this patch should have
> been part
> > of the patch-set
> 
> I assumed he meant your patch 1 in the same series, (given the reply
> was to
> patch 2).
> 
> With the '[PATCH v6] PCI: Store PCIe bus address in struct
> of_pci_range'
> applied before patches and 1 and 2 of this series - pcie on the
> 'Freescale i.MX6 Quad SABRE Lite Board' works fine.
> 
> I can rescan the bus, load firmware, list nearby APs, and even get MSIs
> coming from the card.

This is Great NEWS! Thanks a Lot!

> 
> Tested-by: James Morse <james.morse at arm.com>
> 
> 
> 
> James


From broonie at kernel.org  Tue Aug  4 03:59:57 2015
From: broonie at kernel.org (Mark Brown)
Date: Tue, 4 Aug 2015 11:59:57 +0100
Subject: [PATCH 1/3] spi: bitbang: Replace spinlock by mutex when calling
 chipselect
In-Reply-To: <1438668598-6678-1-git-send-email-drinkcat@chromium.org>
References: <1438668598-6678-1-git-send-email-drinkcat@chromium.org>
Message-ID: <20150804105957.GI20873@sirena.org.uk>

On Tue, Aug 04, 2015 at 02:09:56PM +0800, Nicolas Boichat wrote:
> Enabling CONFIG_DEBUG_ATOMIC_SLEEP in kernel configuration, we get
> this warning in spi_gpio_setup:
> [    1.177747] BUG: sleeping function called from invalid context at drivers/gpio/gpiolib.c:1431
> [    1.190182] in_atomic(): 1, irqs_disabled(): 128, pid: 1, name: swapper/0
> [    1.196922] 3 locks held by swapper/0/1:

Please don't include entire stack traces in commit logs, they're
enormous and overwhelm the actual content (like here where the trace is
much bigger than the actual commit message).  If you feel the
information from the trace adds something please present *edited*
highlights instead.

> Actually, I'm not sure if I understand the existing code: why are we not
> waiting for busy to go down to 0, then call chipselect, instead of not calling
> it at all if the bus happens to be busy when we setup the device? With the
> current approach, it would be easy to just use an unconditional mutex_lock.

We shouldn't be blocking waiting for the bus to become free, that's not
how the interface works.

> Also, is it harmful to deactivate the newly setup device in spi_bitbang_setup,
> even if the bus is busy with another device? chipselect should be independent
> for each device (or is it not?). So I'm not clear why we need any locking at
> all...

If you assert chip select on one device while another device is still
being interacted with then the new device will see the traffic for the
old device and become confused.

> Anyway, this patch series does not change the existing behaviour, applies on
> top of broonie-sound/for-next, and, along with the 2 follow-up patches, was
> compile-tested on x86-64/arm (allyesconfig) and ppc44x (defconfig+SPI driver),
> and runtime-tested on an arm platform.

I'm not seeing enough analysis in the commit log of what's being locked
and why - I don't fully understand what the busy stuff is for either
(not that I've looked at the code in detail just now) but I think that's
going to be the key thing here.
-------------- next part --------------
A non-text attachment was scrubbed...
Name: signature.asc
Type: application/pgp-signature
Size: 473 bytes
Desc: Digital signature
URL: <http://lists.infradead.org/pipermail/linux-arm-kernel/attachments/20150804/7bc725ed/attachment-0001.sig>

From alexandre.belloni at free-electrons.com  Tue Aug  4 04:00:44 2015
From: alexandre.belloni at free-electrons.com (Alexandre Belloni)
Date: Tue, 4 Aug 2015 13:00:44 +0200
Subject: [PATCH 19/20] clocksource: atmel-st: get and use slow clock
In-Reply-To: <55C09477.3080209@linaro.org>
References: <1438215726-27452-1-git-send-email-alexandre.belloni@free-electrons.com>
 <1438215726-27452-20-git-send-email-alexandre.belloni@free-electrons.com>
 <55C09477.3080209@linaro.org>
Message-ID: <20150804110044.GK3486@piout.net>

On 04/08/2015 at 12:31:19 +0200, Daniel Lezcano wrote :
> On 07/30/2015 02:22 AM, Alexandre Belloni wrote:
> >The current slow clock rate is hardcoded. Properly get the slow clock
> >and use its rate.
> >
> >Signed-off-by: Alexandre Belloni <alexandre.belloni at free-electrons.com>
> >---
> 
> [ ... ]
> 
> >+struct clk *sclk;
> 
> Do you need this variable global ? AFAICS, its scope is in the init
> function, no ?
> 

Indeed.

> >+int timer_latch;
> 
> static.
> 

Yeah, this was changed in v2 (that I forgot to label as v2).

-- 
Alexandre Belloni, Free Electrons
Embedded Linux, Kernel and Android engineering
http://free-electrons.com


From broonie at kernel.org  Tue Aug  4 04:00:41 2015
From: broonie at kernel.org (Mark Brown)
Date: Tue, 4 Aug 2015 12:00:41 +0100
Subject: [PATCH 3/3] spi: s3c24xx: Convert spinlock to mutex
In-Reply-To: <1438668598-6678-3-git-send-email-drinkcat@chromium.org>
References: <1438668598-6678-1-git-send-email-drinkcat@chromium.org>
 <1438668598-6678-3-git-send-email-drinkcat@chromium.org>
Message-ID: <20150804110040.GJ20873@sirena.org.uk>

On Tue, Aug 04, 2015 at 02:09:58PM +0800, Nicolas Boichat wrote:
> bitbang->lock is now a mutex: replace spinlock function calls
> by mutex functions.

This would need to be combined with the first patch, individual patches
shouldn't break the build.
-------------- next part --------------
A non-text attachment was scrubbed...
Name: signature.asc
Type: application/pgp-signature
Size: 473 bytes
Desc: Digital signature
URL: <http://lists.infradead.org/pipermail/linux-arm-kernel/attachments/20150804/c4a9c636/attachment.sig>

From mark.rutland at arm.com  Tue Aug  4 04:12:59 2015
From: mark.rutland at arm.com (Mark Rutland)
Date: Tue, 4 Aug 2015 12:12:59 +0100
Subject: [Query] ARM64: Softlockup when using PSCI for secondary CPU_ON
In-Reply-To: <BY1PR0301MB13035E3B09536F34F4C281CF82770@BY1PR0301MB1303.namprd03.prod.outlook.com>
References: <BY1PR0301MB1303EC5AAE8F0B4DAA70D15F82770@BY1PR0301MB1303.namprd03.prod.outlook.com>
 <20150803100248.GA25627@leverpostej>
 <BY1PR0301MB1303B775B1D5D318A64350C582770@BY1PR0301MB1303.namprd03.prod.outlook.com>
 <BY1PR0301MB13035E3B09536F34F4C281CF82770@BY1PR0301MB1303.namprd03.prod.outlook.com>
Message-ID: <20150804111258.GC7056@leverpostej>

Hi,

> > > Is Linux itself booted at EL1 or EL2?
> > 
> > UEFI leaves the execution level of the primary core in EL2.
> > KVM is turned-off in my defconfig, so I am not loading any hypervisor at
> > EL2 as of now.

[...]

> > > > preempt self-detected stall on CPU { 3}  (t=17194 jiffies g=-267
> > > > c=-268 q=1)
> > >
> > > > INFO: rcu_preempt detected stalls on CPUs/tasks: { 1 2} (detected by
> > > > 0, t=287104493908 jiffies, g=-267, c=-268, q=2)
> > >
> > > It looks like your timekeeping has gone wrong. As mentioned above, I'd
> > > suspect that CNTVOFF_EL2 is not programmed consistently across all CPUs.
> > >
> > > Are you able to boot Linux at EL2 instead? Or can you verify that
> > > CNTVOFF_EL2 is initialised?
> > >
> > 
> > Ok, let me check the CNTVOFF_EL2 part then.
> > I will get back with details soon.
> > 
> 
> Indeed. Using the following code in the run-time EL3 firmware to correctly set the
> CNTVOFF_EL2 to zero for secondaries solves the soft-lockup. I took a reference from your u-boot
> patch (see [1]).
> 
> +	/* Initialize Generic Timers */
> +	msr	cntvoff_el2, xzr
> 
> [1] http://marc.info/?l=u-boot&m=140230240621878&w=2

That's good to hear!

However, this implies there are a couple of other issues. It sounds like
your UEFI Linux Loader doesn't correctly initialise EL2 state, and drops
EL1N before starting the kernel (or the kernel would have initialised
CNTVOFF itself).

PSCI should boot CPUs into the first available non-secure exception
level, which in this case is EL2, but it sounds like your implementation
boots them to EL1N instead, which is incorrect and prevents Linux from
being able to initialise EL2 correctly.

In the absence of a hypervisor, you should enter the kernel on all CPUs
at EL2. That means we can configure more EL2 state in the kernel and
your bootlaoder/firmware needs to do less.

I would also strongly recommend booting Linux as an EFI application
rather than using the Linux Loader, as the loader isn't even compliant
with the Linux boot protocol and hampers Linux booting correctly.

Thanks,
Mark.


From sjoerd.simons at collabora.co.uk  Tue Aug  4 04:18:19 2015
From: sjoerd.simons at collabora.co.uk (Sjoerd Simons)
Date: Tue,  4 Aug 2015 13:18:19 +0200
Subject: [PATCH v2 4/4] ARM: dts: rockchip: Add SPDIF optical out on Radxa Rock
In-Reply-To: <1438687099-14282-1-git-send-email-sjoerd.simons@collabora.co.uk>
References: <1438687099-14282-1-git-send-email-sjoerd.simons@collabora.co.uk>
Message-ID: <1438687099-14282-5-git-send-email-sjoerd.simons@collabora.co.uk>

This enables the SPDIF optical audio output on the Radxa Rock

Signed-off-by: Sjoerd Simons <sjoerd.simons at collabora.co.uk>

---

Changes in v2: None

 arch/arm/boot/dts/rk3188-radxarock.dts | 19 +++++++++++++++++++
 1 file changed, 19 insertions(+)

diff --git a/arch/arm/boot/dts/rk3188-radxarock.dts b/arch/arm/boot/dts/rk3188-radxarock.dts
index 4bb014d..dea020c 100644
--- a/arch/arm/boot/dts/rk3188-radxarock.dts
+++ b/arch/arm/boot/dts/rk3188-radxarock.dts
@@ -90,6 +90,21 @@
 		};
 	};
 
+	sound {
+		compatible = "simple-audio-card";
+		simple-audio-card,name = "SPDIF";
+
+		simple-audio-card,dai-link at 1 {  /* S/PDIF - S/PDIF */
+			cpu { sound-dai = <&spdif>; };
+			codec { sound-dai = <&spdif_out>; };
+		};
+	};
+
+	spdif_out: spdif-out {
+		compatible = "linux,spdif-dit";
+		#sound-dai-cells = <0>;
+	};
+
 	ir_recv: gpio-ir-receiver {
 		compatible = "gpio-ir-receiver";
 		gpios = <&gpio0 10 1>;
@@ -343,6 +358,10 @@
 	};
 };
 
+&spdif {
+	status = "okay";
+};
+
 &uart0 {
 	status = "okay";
 };
-- 
2.5.0



From sjoerd.simons at collabora.co.uk  Tue Aug  4 04:18:18 2015
From: sjoerd.simons at collabora.co.uk (Sjoerd Simons)
Date: Tue,  4 Aug 2015 13:18:18 +0200
Subject: [PATCH v2 3/4] ARM: dts: rockchip: Add SPDIF transceiver for RK3188
In-Reply-To: <1438687099-14282-1-git-send-email-sjoerd.simons@collabora.co.uk>
References: <1438687099-14282-1-git-send-email-sjoerd.simons@collabora.co.uk>
Message-ID: <1438687099-14282-4-git-send-email-sjoerd.simons@collabora.co.uk>

Add the SPDIF transceiver controller and pin for RK3188

Signed-off-by: Sjoerd Simons <sjoerd.simons at collabora.co.uk>

---

Changes in v2:
- Sort the spdif node properties
- Drop the 0x prefix from the node name
- Rename the spdif@ node to sound@

 arch/arm/boot/dts/rk3188.dtsi | 22 ++++++++++++++++++++++
 1 file changed, 22 insertions(+)

diff --git a/arch/arm/boot/dts/rk3188.dtsi b/arch/arm/boot/dts/rk3188.dtsi
index 0f23aed..abdb5bc 100644
--- a/arch/arm/boot/dts/rk3188.dtsi
+++ b/arch/arm/boot/dts/rk3188.dtsi
@@ -121,6 +121,22 @@
 		status = "disabled";
 	};
 
+	spdif: sound at 1011e000 {
+		compatible = "rockchip,rk3188-spdif", "rockchip,rk3066-spdif";
+		reg = <0x1011e000 0x2000>;
+		#address-cells = <1>;
+		#size-cells = <0>;
+		#sound-dai-cells = <0>;
+		clock-names = "spdif_hclk", "spdif_clk";
+		clocks = <&cru HCLK_SPDIF>, <&cru SCLK_SPDIF>;
+		dmas = <&dmac1_s 8>;
+		dma-names = "tx";
+		interrupts = <GIC_SPI 32 IRQ_TYPE_LEVEL_HIGH>;
+		pinctrl-names = "default";
+		pinctrl-0 = <&spdif_tx>;
+		status = "disabled";
+	};
+
 	cru: clock-controller at 20000000 {
 		compatible = "rockchip,rk3188-cru";
 		reg = <0x20000000 0x1000>;
@@ -462,6 +478,12 @@
 						<RK_GPIO1 21 RK_FUNC_1 &pcfg_pull_none>;
 			};
 		};
+
+		spdif {
+			spdif_tx: spdif-tx {
+				rockchip,pins = <RK_GPIO1 14 RK_FUNC_1 &pcfg_pull_none>;
+			};
+		};
 	};
 };
 
-- 
2.5.0



From sjoerd.simons at collabora.co.uk  Tue Aug  4 04:18:15 2015
From: sjoerd.simons at collabora.co.uk (Sjoerd Simons)
Date: Tue,  4 Aug 2015 13:18:15 +0200
Subject: [PATCH v2 0/4] Add SPDIF support for rockchip
Message-ID: <1438687099-14282-1-git-send-email-sjoerd.simons@collabora.co.uk>

This patchset adds support for the Rockchip SPDIF transceiver as present
on RK3066, RK3188 and RK3288 boards and enables it on a Radxa rock pro.
Tested on a Radxa Rock Pro board.

Changes in v2:
- Remove platform: module alias as it was unused
- Call MODULE_DEVICE_TABLE(of, ) right after the of match table
- use rk_spdif as a prefix consistenly throughout the driver
- Check return code of regmap_update and bubble it up
- Sort the spdif node properties
- Drop the 0x prefix from the node name
- Rename the spdif@ node to sound@

Sjoerd Simons (4):
  ASoC: dt-bindings: add rockchip tranceiver bindings
  ASoc: rockchip: Add rockchip SPDIF transceiver driver
  ARM: dts: rockchip: Add SPDIF transceiver for RK3188
  ARM: dts: rockchip: Add SPDIF optical out on Radxa Rock

 .../devicetree/bindings/sound/rockchip-spdif.txt   |  41 +++
 arch/arm/boot/dts/rk3188-radxarock.dts             |  19 +
 arch/arm/boot/dts/rk3188.dtsi                      |  22 ++
 sound/soc/rockchip/Kconfig                         |   8 +
 sound/soc/rockchip/Makefile                        |   2 +
 sound/soc/rockchip/rockchip_spdif.c                | 381 +++++++++++++++++++++
 sound/soc/rockchip/rockchip_spdif.h                |  63 ++++
 7 files changed, 536 insertions(+)
 create mode 100644 Documentation/devicetree/bindings/sound/rockchip-spdif.txt
 create mode 100644 sound/soc/rockchip/rockchip_spdif.c
 create mode 100644 sound/soc/rockchip/rockchip_spdif.h

-- 
2.5.0



From sjoerd.simons at collabora.co.uk  Tue Aug  4 04:18:16 2015
From: sjoerd.simons at collabora.co.uk (Sjoerd Simons)
Date: Tue,  4 Aug 2015 13:18:16 +0200
Subject: [PATCH v2 1/4] ASoC: dt-bindings: add rockchip tranceiver bindings
In-Reply-To: <1438687099-14282-1-git-send-email-sjoerd.simons@collabora.co.uk>
References: <1438687099-14282-1-git-send-email-sjoerd.simons@collabora.co.uk>
Message-ID: <1438687099-14282-2-git-send-email-sjoerd.simons@collabora.co.uk>

Add devicetree bindings for the spdif tranceiver found on
found on rk3066, rk3188 and rk3288 SoCs

Signed-off-by: Sjoerd Simons <sjoerd.simons at collabora.co.uk>
---

Changes in v2: None

 .../devicetree/bindings/sound/rockchip-spdif.txt   | 41 ++++++++++++++++++++++
 1 file changed, 41 insertions(+)
 create mode 100644 Documentation/devicetree/bindings/sound/rockchip-spdif.txt

diff --git a/Documentation/devicetree/bindings/sound/rockchip-spdif.txt b/Documentation/devicetree/bindings/sound/rockchip-spdif.txt
new file mode 100644
index 0000000..2da8a09
--- /dev/null
+++ b/Documentation/devicetree/bindings/sound/rockchip-spdif.txt
@@ -0,0 +1,41 @@
+* Rockchip SPDIF transceiver
+
+The S/PDIF audio block is a stereo transceiver that allows the
+processor to receive and transmit digital audio via an coaxial cable or
+a fibre cable.
+
+Required properties:
+
+- compatible: should be one of the following:
+   - "rockchip,rk3066-spdif": for rk3066
+   - "rockchip,rk3188-spdif", "rockchip,rk3066-spdif": for rk3188
+   - "rockchip,rk3288-spdif", "rockchip,rk3066-spdif": for rk3288
+- reg: physical base address of the controller and length of memory mapped
+  region.
+- interrupts: should contain the SPDIF interrupt.
+- #address-cells: should be 1.
+- #size-cells: should be 0.
+- dmas: DMA specifiers for tx dma. See the DMA client binding,
+  Documentation/devicetree/bindings/dma/dma.txt
+- dma-names: should be "tx"
+- clocks: a list of phandle + clock-specifier pairs, one for each entry
+  in clock-names.
+- clock-names: should contain following:
+   - "spdif_hclk": clock for SPPIF controller
+   - "spdif_clk" : clock for SPDIF bus
+
+Example for the rk3188 SPDIF controller:
+
+spdif: spdif at 0x1011e000 {
+	compatible = "rockchip,rk3188-spdif", "rockchip,rk3066-spdif";
+	reg = <0x1011e000 0x2000>;
+	interrupts = <GIC_SPI 32 IRQ_TYPE_LEVEL_HIGH>;
+	#address-cells = <1>;
+	#size-cells = <0>;
+	dmas = <&dmac1_s 8>;
+	dma-names = "tx";
+	clock-names = "spdif_hclk", "spdif_clk";
+	clocks = <&cru HCLK_SPDIF>, <&cru SCLK_SPDIF>;
+	status = "disabled";
+	#sound-dai-cells = <0>;
+};
-- 
2.5.0



From sjoerd.simons at collabora.co.uk  Tue Aug  4 04:18:17 2015
From: sjoerd.simons at collabora.co.uk (Sjoerd Simons)
Date: Tue,  4 Aug 2015 13:18:17 +0200
Subject: [PATCH v2 2/4] ASoc: rockchip: Add rockchip SPDIF transceiver driver
In-Reply-To: <1438687099-14282-1-git-send-email-sjoerd.simons@collabora.co.uk>
References: <1438687099-14282-1-git-send-email-sjoerd.simons@collabora.co.uk>
Message-ID: <1438687099-14282-3-git-send-email-sjoerd.simons@collabora.co.uk>

Add a driver for the SDPIF transceiver available on RK3066, RK3188 and
RK3288. Heavily based on the rockchip i2s driver.

Signed-off-by: Sjoerd Simons <sjoerd.simons at collabora.co.uk>

---

Changes in v2:
- Remove platform: module alias as it was unused
- Call MODULE_DEVICE_TABLE(of, ) right after the of match table
- use rk_spdif as a prefix consistenly throughout the driver
- Check return code of regmap_update and bubble it up

 sound/soc/rockchip/Kconfig          |   8 +
 sound/soc/rockchip/Makefile         |   2 +
 sound/soc/rockchip/rockchip_spdif.c | 381 ++++++++++++++++++++++++++++++++++++
 sound/soc/rockchip/rockchip_spdif.h |  63 ++++++
 4 files changed, 454 insertions(+)
 create mode 100644 sound/soc/rockchip/rockchip_spdif.c
 create mode 100644 sound/soc/rockchip/rockchip_spdif.h

diff --git a/sound/soc/rockchip/Kconfig b/sound/soc/rockchip/Kconfig
index 58bae8e..603fd1f 100644
--- a/sound/soc/rockchip/Kconfig
+++ b/sound/soc/rockchip/Kconfig
@@ -15,6 +15,14 @@ config SND_SOC_ROCKCHIP_I2S
 	  Rockchip I2S device. The device supports upto maximum of
 	  8 channels each for play and record.
 
+config SND_SOC_ROCKCHIP_SPDIF
+	tristate "Rockchip SPDIF Device Driver"
+	depends on CLKDEV_LOOKUP && SND_SOC_ROCKCHIP
+	select SND_SOC_GENERIC_DMAENGINE_PCM
+	help
+	  Say Y or M if you want to add support for SPDIF driver for
+	  Rockchip SPDIF transceiver device.
+
 config SND_SOC_ROCKCHIP_MAX98090
 	tristate "ASoC support for Rockchip boards using a MAX98090 codec"
 	depends on SND_SOC_ROCKCHIP && I2C && GPIOLIB
diff --git a/sound/soc/rockchip/Makefile b/sound/soc/rockchip/Makefile
index 1bc1dc3..9a244d7 100644
--- a/sound/soc/rockchip/Makefile
+++ b/sound/soc/rockchip/Makefile
@@ -1,7 +1,9 @@
 # ROCKCHIP Platform Support
 snd-soc-i2s-objs := rockchip_i2s.o
+snd-soc-spdif-objs := rockchip_spdif.o
 
 obj-$(CONFIG_SND_SOC_ROCKCHIP_I2S) += snd-soc-i2s.o
+obj-$(CONFIG_SND_SOC_ROCKCHIP_SPDIF) += snd-soc-spdif.o
 
 snd-soc-rockchip-max98090-objs := rockchip_max98090.o
 snd-soc-rockchip-rt5645-objs := rockchip_rt5645.o
diff --git a/sound/soc/rockchip/rockchip_spdif.c b/sound/soc/rockchip/rockchip_spdif.c
new file mode 100644
index 0000000..39d33c0
--- /dev/null
+++ b/sound/soc/rockchip/rockchip_spdif.c
@@ -0,0 +1,381 @@
+/* sound/soc/rockchip/rk_spdif.c
+ *
+ * ALSA SoC Audio Layer - Rockchip I2S Controller driver
+ *
+ * Copyright (c) 2014 Rockchip Electronics Co. Ltd.
+ * Author: Jianqun <jay.xu at rock-chips.com>
+ * Copyright (c) 2015 Collabora Ltd.
+ * Author: Sjoerd Simons <sjoerd.simons at collabora.co.uk>
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License version 2 as
+ * published by the Free Software Foundation.
+ */
+
+#include <linux/module.h>
+#include <linux/delay.h>
+#include <linux/of_gpio.h>
+#include <linux/clk.h>
+#include <linux/pm_runtime.h>
+#include <linux/regmap.h>
+#include <sound/pcm_params.h>
+#include <sound/dmaengine_pcm.h>
+
+#include "rockchip_spdif.h"
+
+struct rk_spdif_dev {
+	struct device *dev;
+
+	struct clk *mclk;
+	struct clk *hclk;
+
+	struct snd_dmaengine_dai_dma_data playback_dma_data;
+
+	struct regmap *regmap;
+};
+
+static int rk_spdif_runtime_suspend(struct device *dev)
+{
+	struct rk_spdif_dev *spdif = dev_get_drvdata(dev);
+
+	clk_disable_unprepare(spdif->mclk);
+
+	return 0;
+}
+
+static int rk_spdif_runtime_resume(struct device *dev)
+{
+	struct rk_spdif_dev *spdif = dev_get_drvdata(dev);
+	int ret;
+
+	ret = clk_prepare_enable(spdif->mclk);
+	if (ret) {
+		dev_err(spdif->dev, "clock enable failed %d\n", ret);
+		return ret;
+	}
+
+	return 0;
+}
+
+static inline struct rk_spdif_dev *to_info(struct snd_soc_dai *dai)
+{
+	return snd_soc_dai_get_drvdata(dai);
+}
+
+static int rk_spdif_snd_txctrl(struct rk_spdif_dev *spdif, int on)
+{
+	int ret;
+
+	if (on) {
+		ret = regmap_update_bits(spdif->regmap, SPDIF_DMACR,
+				   SPDIF_DMACR_TDE_ENABLE,
+				   SPDIF_DMACR_TDE_ENABLE);
+
+		if (ret != 0)
+			goto bail;
+
+		ret = regmap_update_bits(spdif->regmap, SPDIF_XFER,
+				   SPDIF_XFER_TXS_START,
+				   SPDIF_XFER_TXS_START);
+	} else {
+		ret = regmap_update_bits(spdif->regmap, SPDIF_DMACR,
+				   SPDIF_DMACR_TDE_ENABLE,
+				   SPDIF_DMACR_TDE_DISABLE);
+
+		if (ret != 0)
+			goto bail;
+
+		ret = regmap_update_bits(spdif->regmap, SPDIF_XFER,
+				   SPDIF_XFER_TXS_START,
+				   SPDIF_XFER_TXS_STOP);
+	}
+
+bail:
+	return ret;
+}
+
+static int rk_spdif_hw_params(struct snd_pcm_substream *substream,
+				  struct snd_pcm_hw_params *params,
+				  struct snd_soc_dai *dai)
+{
+	struct rk_spdif_dev *spdif = to_info(dai);
+	unsigned int val = SPDIF_CFGR_HALFWORD_ENABLE;
+	int srate, mclk;
+
+	srate = params_rate(params);
+	switch (srate) {
+	case 32000:
+	case 48000:
+	case 96000:
+		mclk = 12288000;
+		break;
+	case 44100:
+		mclk = 11289600;
+		break;
+	default:
+		return -EINVAL;
+	}
+
+	switch (params_format(params)) {
+	case SNDRV_PCM_FORMAT_S16_LE:
+		val |= SPDIF_CFGR_VDW_16;
+		break;
+	case SNDRV_PCM_FORMAT_S20_3LE:
+		val |= SPDIF_CFGR_VDW_20;
+		break;
+	case SNDRV_PCM_FORMAT_S24_LE:
+		val |= SPDIF_CFGR_VDW_24;
+		break;
+	default:
+		return -EINVAL;
+	}
+
+	/* Set clock and calculate divider */
+	clk_set_rate(spdif->mclk, mclk);
+	val |= SPDIF_CFGR_CLK_DIV(mclk/(srate * 256));
+
+	return regmap_update_bits(spdif->regmap, SPDIF_CFGR,
+		SPDIF_CFGR_CLK_DIV_MASK | SPDIF_CFGR_HALFWORD_ENABLE |
+		SDPIF_CFGR_VDW_MASK,
+		val);
+}
+
+static int rk_spdif_trigger(struct snd_pcm_substream *substream,
+				int cmd, struct snd_soc_dai *dai)
+{
+	struct rk_spdif_dev *spdif = to_info(dai);
+	int ret;
+
+	switch (cmd) {
+	case SNDRV_PCM_TRIGGER_START:
+	case SNDRV_PCM_TRIGGER_RESUME:
+	case SNDRV_PCM_TRIGGER_PAUSE_RELEASE:
+		ret = rk_spdif_snd_txctrl(spdif, true);
+		break;
+	case SNDRV_PCM_TRIGGER_SUSPEND:
+	case SNDRV_PCM_TRIGGER_STOP:
+	case SNDRV_PCM_TRIGGER_PAUSE_PUSH:
+		ret = rk_spdif_snd_txctrl(spdif, false);
+		break;
+	default:
+		ret = -EINVAL;
+		break;
+	}
+
+	return ret;
+}
+
+static int rk_spdif_dai_probe(struct snd_soc_dai *dai)
+{
+	struct rk_spdif_dev *spdif = snd_soc_dai_get_drvdata(dai);
+
+	dai->playback_dma_data = &spdif->playback_dma_data;
+
+	return 0;
+}
+
+static const struct snd_soc_dai_ops rk_spdif_dai_ops = {
+	.hw_params = rk_spdif_hw_params,
+	.trigger = rk_spdif_trigger,
+};
+
+static struct snd_soc_dai_driver rk_spdif_dai = {
+	.probe = rk_spdif_dai_probe,
+	.playback = {
+		.stream_name = "Playback",
+		.channels_min = 2,
+		.channels_max = 2,
+		.rates = (SNDRV_PCM_RATE_32000 |
+			  SNDRV_PCM_RATE_44100 |
+			  SNDRV_PCM_RATE_48000 |
+			  SNDRV_PCM_RATE_96000),
+		.formats = (SNDRV_PCM_FMTBIT_S16_LE |
+			    SNDRV_PCM_FMTBIT_S20_3LE |
+			    SNDRV_PCM_FMTBIT_S24_LE),
+	},
+	.ops = &rk_spdif_dai_ops,
+};
+
+static const struct snd_soc_component_driver rk_spdif_component = {
+	.name = "rockchip-spdif",
+};
+
+static bool rk_spdif_wr_reg(struct device *dev, unsigned int reg)
+{
+	switch (reg) {
+	case SPDIF_CFGR:
+	case SPDIF_DMACR:
+	case SPDIF_INTCR:
+	case SPDIF_XFER:
+	case SPDIF_SMPDR:
+		return true;
+	default:
+		return false;
+	}
+}
+
+static bool rk_spdif_rd_reg(struct device *dev, unsigned int reg)
+{
+	switch (reg) {
+	case SPDIF_CFGR:
+	case SPDIF_SDBLR:
+	case SPDIF_INTCR:
+	case SPDIF_INTSR:
+	case SPDIF_XFER:
+		return true;
+	default:
+		return false;
+	}
+}
+
+static bool rk_spdif_volatile_reg(struct device *dev, unsigned int reg)
+{
+	switch (reg) {
+	case SPDIF_INTSR:
+	case SPDIF_SDBLR:
+		return true;
+	default:
+		return false;
+	}
+}
+
+static const struct regmap_config rk_spdif_regmap_config = {
+	.reg_bits = 32,
+	.reg_stride = 4,
+	.val_bits = 32,
+	.max_register = SPDIF_SMPDR,
+	.writeable_reg = rk_spdif_wr_reg,
+	.readable_reg = rk_spdif_rd_reg,
+	.volatile_reg = rk_spdif_volatile_reg,
+	.cache_type = REGCACHE_FLAT,
+};
+
+static int rk_spdif_probe(struct platform_device *pdev)
+{
+	struct rk_spdif_dev *spdif;
+	struct resource *res;
+	void __iomem *regs;
+	int ret;
+
+	spdif = devm_kzalloc(&pdev->dev, sizeof(*spdif), GFP_KERNEL);
+	if (!spdif)
+		return -ENOMEM;
+
+	spdif->hclk = devm_clk_get(&pdev->dev, "spdif_hclk");
+	if (IS_ERR(spdif->hclk)) {
+		dev_err(&pdev->dev, "Can't retrieve rk_spdif bus clock\n");
+		return PTR_ERR(spdif->hclk);
+	}
+	ret = clk_prepare_enable(spdif->hclk);
+	if (ret) {
+		dev_err(spdif->dev, "hclock enable failed %d\n", ret);
+		return ret;
+	}
+
+	spdif->mclk = devm_clk_get(&pdev->dev, "spdif_clk");
+	if (IS_ERR(spdif->mclk)) {
+		dev_err(&pdev->dev, "Can't retrieve rk_spdif master clock\n");
+		return PTR_ERR(spdif->hclk);
+	}
+
+	ret = clk_prepare_enable(spdif->mclk);
+	if (ret) {
+		dev_err(spdif->dev, "clock enable failed %d\n", ret);
+		return ret;
+	}
+
+	res = platform_get_resource(pdev, IORESOURCE_MEM, 0);
+	regs = devm_ioremap_resource(&pdev->dev, res);
+	if (IS_ERR(regs))
+		return PTR_ERR(regs);
+
+	spdif->regmap = devm_regmap_init_mmio(&pdev->dev, regs,
+					    &rk_spdif_regmap_config);
+	if (IS_ERR(spdif->regmap)) {
+		dev_err(&pdev->dev,
+			"Failed to initialise managed register map\n");
+		return PTR_ERR(spdif->regmap);
+	}
+
+	spdif->playback_dma_data.addr = res->start + SPDIF_SMPDR;
+	spdif->playback_dma_data.addr_width = DMA_SLAVE_BUSWIDTH_4_BYTES;
+	spdif->playback_dma_data.maxburst = 4;
+
+	spdif->dev = &pdev->dev;
+	dev_set_drvdata(&pdev->dev, spdif);
+
+	pm_runtime_enable(&pdev->dev);
+	if (!pm_runtime_enabled(&pdev->dev)) {
+		ret = rk_spdif_runtime_resume(&pdev->dev);
+		if (ret)
+			goto err_pm_disable;
+	}
+
+	ret = devm_snd_soc_register_component(&pdev->dev,
+					      &rk_spdif_component,
+					      &rk_spdif_dai, 1);
+	if (ret) {
+		dev_err(&pdev->dev, "Could not register DAI\n");
+		goto err_suspend;
+	}
+
+	ret = snd_dmaengine_pcm_register(&pdev->dev, NULL, 0);
+	if (ret) {
+		dev_err(&pdev->dev, "Could not register PCM\n");
+		goto err_pcm_register;
+	}
+
+	return 0;
+
+err_pcm_register:
+	snd_dmaengine_pcm_unregister(&pdev->dev);
+err_suspend:
+	if (!pm_runtime_status_suspended(&pdev->dev))
+		rk_spdif_runtime_suspend(&pdev->dev);
+err_pm_disable:
+	pm_runtime_disable(&pdev->dev);
+
+	return ret;
+}
+
+static int rk_spdif_remove(struct platform_device *pdev)
+{
+	struct rk_spdif_dev *spdif = dev_get_drvdata(&pdev->dev);
+
+	pm_runtime_disable(&pdev->dev);
+	if (!pm_runtime_status_suspended(&pdev->dev))
+		rk_spdif_runtime_suspend(&pdev->dev);
+
+	clk_disable_unprepare(spdif->mclk);
+	clk_disable_unprepare(spdif->hclk);
+	snd_dmaengine_pcm_unregister(&pdev->dev);
+	snd_soc_unregister_component(&pdev->dev);
+
+	return 0;
+}
+
+static const struct of_device_id rk_spdif_match[] = {
+	{ .compatible = "rockchip,rk3066-spdif", },
+	{},
+};
+MODULE_DEVICE_TABLE(of, rk_spdif_match);
+
+static const struct dev_pm_ops rk_spdif_pm_ops = {
+	SET_RUNTIME_PM_OPS(rk_spdif_runtime_suspend, rk_spdif_runtime_resume,
+			   NULL)
+};
+
+static struct platform_driver rk_spdif_driver = {
+	.probe = rk_spdif_probe,
+	.remove = rk_spdif_remove,
+	.driver = {
+		.name = "rockchip-spdif",
+		.of_match_table = of_match_ptr(rk_spdif_match),
+		.pm = &rk_spdif_pm_ops,
+	},
+};
+module_platform_driver(rk_spdif_driver);
+
+MODULE_DESCRIPTION("ROCKCHIP SPDIF transceiver Interface");
+MODULE_AUTHOR("Sjoerd Simons <sjoerd.simons at collabora.co.uk>");
+MODULE_LICENSE("GPL v2");
diff --git a/sound/soc/rockchip/rockchip_spdif.h b/sound/soc/rockchip/rockchip_spdif.h
new file mode 100644
index 0000000..07f86a2
--- /dev/null
+++ b/sound/soc/rockchip/rockchip_spdif.h
@@ -0,0 +1,63 @@
+/*
+ * ALSA SoC Audio Layer - Rockchip SPDIF transceiver driver
+ *
+ * Copyright (c) 2015 Collabora Ltd.
+ * Author: Sjoerd Simons <sjoerd.simons at collabora.co.uk>
+ *
+ * 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.
+ */
+
+#ifndef _ROCKCHIP_SPDIF_H
+#define _ROCKCHIP_SPDIF_H
+
+/*
+ * CFGR
+ * transfer configuration register
+*/
+#define SPDIF_CFGR_CLK_DIV_SHIFT	(16)
+#define SPDIF_CFGR_CLK_DIV_MASK		(0xff << SPDIF_CFGR_CLK_DIV_SHIFT)
+#define SPDIF_CFGR_CLK_DIV(x)		(x << SPDIF_CFGR_CLK_DIV_SHIFT)
+
+#define SPDIF_CFGR_HALFWORD_SHIFT	2
+#define SPDIF_CFGR_HALFWORD_DISABLE	(0 << SPDIF_CFGR_HALFWORD_SHIFT)
+#define SPDIF_CFGR_HALFWORD_ENABLE	(1 << SPDIF_CFGR_HALFWORD_SHIFT)
+
+#define SPDIF_CFGR_VDW_SHIFT	0
+#define SPDIF_CFGR_VDW(x)	(x << SPDIF_CFGR_VDW_SHIFT)
+#define SDPIF_CFGR_VDW_MASK	(0xf << SPDIF_CFGR_VDW_SHIFT)
+
+#define SPDIF_CFGR_VDW_16	SPDIF_CFGR_VDW(0x00)
+#define SPDIF_CFGR_VDW_20	SPDIF_CFGR_VDW(0x01)
+#define SPDIF_CFGR_VDW_24	SPDIF_CFGR_VDW(0x10)
+
+/*
+ * DMACR
+ * DMA control register
+*/
+#define SPDIF_DMACR_TDE_SHIFT	5
+#define SPDIF_DMACR_TDE_DISABLE	(0 << SPDIF_DMACR_TDE_SHIFT)
+#define SPDIF_DMACR_TDE_ENABLE	(1 << SPDIF_DMACR_TDE_SHIFT)
+
+#define SPDIF_DMACR_TDL_SHIFT	0
+#define SPDIF_DMACR_TDL(x)	((x) << SPDIF_DMACR_TDL_SHIFT)
+#define SPDIF_DMACR_TDL_MASK	(0x1f << SDPIF_DMACR_TDL_SHIFT)
+
+/*
+ * XFER
+ * Transfer control register
+*/
+#define SPDIF_XFER_TXS_SHIFT	0
+#define SPDIF_XFER_TXS_STOP	(0 << SPDIF_XFER_TXS_SHIFT)
+#define SPDIF_XFER_TXS_START	(1 << SPDIF_XFER_TXS_SHIFT)
+
+#define SPDIF_CFGR	(0x0000)
+#define SPDIF_SDBLR	(0x0004)
+#define SPDIF_DMACR	(0x0008)
+#define SPDIF_INTCR	(0x000c)
+#define SPDIF_INTSR	(0x0010)
+#define SPDIF_XFER	(0x0018)
+#define SPDIF_SMPDR	(0x0020)
+
+#endif /* _ROCKCHIP_SPDIF_H */
-- 
2.5.0



From laurent.pinchart at ideasonboard.com  Tue Aug  4 04:22:13 2015
From: laurent.pinchart at ideasonboard.com (Laurent Pinchart)
Date: Tue, 04 Aug 2015 14:22:13 +0300
Subject: [PATCH v3] media: atmel-isi: parse the DT parameters for
 vsync/hsync/pixclock polarity
In-Reply-To: <1438681069-16981-1-git-send-email-josh.wu@atmel.com>
References: <1438681069-16981-1-git-send-email-josh.wu@atmel.com>
Message-ID: <3317317.RTpCstaHHn@avalon>

Hi Josh,

Thank you for the patch.

On Tuesday 04 August 2015 17:37:49 Josh Wu wrote:
> This patch will get the DT parameters of vsync/hsync/pixclock polarity, and
> pass to driver.
> 
> Also add a debug information for test purpose.
> 
> Signed-off-by: Josh Wu <josh.wu at atmel.com>

Reviewed-by: Laurent Pinchart <laurent.pinchart at ideasonboard.com>

> ---
> 
> Changes in v3:
> - add embedded sync dt property support.
> 
> Changes in v2:
> - rewrite the debug message and add pix clock polarity setup thanks to
>   Laurent.
> - update the commit log.
> 
>  drivers/media/platform/soc_camera/atmel-isi.c | 15 +++++++++++++++
>  1 file changed, 15 insertions(+)
> 
> diff --git a/drivers/media/platform/soc_camera/atmel-isi.c
> b/drivers/media/platform/soc_camera/atmel-isi.c index fead841..4efc939
> 100644
> --- a/drivers/media/platform/soc_camera/atmel-isi.c
> +++ b/drivers/media/platform/soc_camera/atmel-isi.c
> @@ -1061,6 +1061,11 @@ static int isi_camera_set_bus_param(struct
> soc_camera_device *icd) if (common_flags & V4L2_MBUS_PCLK_SAMPLE_FALLING)
>  		cfg1 |= ISI_CFG1_PIXCLK_POL_ACTIVE_FALLING;
> 
> +	dev_dbg(icd->parent, "vsync active %s, hsync active %s, sampling on pix
> clock %s edge\n", +		common_flags & V4L2_MBUS_VSYNC_ACTIVE_LOW ? "low" :
> "high",
> +		common_flags & V4L2_MBUS_HSYNC_ACTIVE_LOW ? "low" : "high",
> +		common_flags & V4L2_MBUS_PCLK_SAMPLE_FALLING ? "falling" : "rising");
> +
>  	if (isi->pdata.has_emb_sync)
>  		cfg1 |= ISI_CFG1_EMB_SYNC;
>  	if (isi->pdata.full_mode)
> @@ -1148,6 +1153,16 @@ static int atmel_isi_parse_dt(struct atmel_isi *isi,
>  		return -EINVAL;
>  	}
> 
> +	if (ep.bus.parallel.flags & V4L2_MBUS_HSYNC_ACTIVE_LOW)
> +		isi->pdata.hsync_act_low = true;
> +	if (ep.bus.parallel.flags & V4L2_MBUS_VSYNC_ACTIVE_LOW)
> +		isi->pdata.vsync_act_low = true;
> +	if (ep.bus.parallel.flags & V4L2_MBUS_PCLK_SAMPLE_FALLING)
> +		isi->pdata.pclk_act_falling = true;
> +
> +	if (ep.bus_type == V4L2_MBUS_BT656)
> +		isi->pdata.has_emb_sync = true;
> +
>  	return 0;
>  }

-- 
Regards,

Laurent Pinchart



From yamada.masahiro at socionext.com  Tue Aug  4 04:21:01 2015
From: yamada.masahiro at socionext.com (Masahiro Yamada)
Date: Tue,  4 Aug 2015 20:21:01 +0900
Subject: [PATCH 0/3] Device Tree updates of UniPhier SoCs for Linux 4.3
Message-ID: <1438687264-26538-1-git-send-email-yamada.masahiro@socionext.com>

Hi Olof and Arnd,


Here are a little more updates for device trees for UniPhier SoCs.

Please consider applying this series to your ARM-SOC tree.

Thanks!



Masahiro Yamada (3):
  ARM: dts: UniPhier: add I2C controller device nodes
  ARM: dts: UniPhier: add PH1-Pro5 SoC support
  ARM: dts: UniPhier: add ProXstream2 and PH1-LD6b SoC/board support

 arch/arm/boot/dts/Makefile                  |   3 +-
 arch/arm/boot/dts/uniphier-ph1-ld4-ref.dts  |   8 +
 arch/arm/boot/dts/uniphier-ph1-ld4.dtsi     |  58 ++++++
 arch/arm/boot/dts/uniphier-ph1-ld6b-ref.dts | 105 +++++++++++
 arch/arm/boot/dts/uniphier-ph1-ld6b.dtsi    |  67 +++++++
 arch/arm/boot/dts/uniphier-ph1-pro4-ref.dts |  10 +
 arch/arm/boot/dts/uniphier-ph1-pro4.dtsi    |  82 +++++++++
 arch/arm/boot/dts/uniphier-ph1-pro5.dtsi    | 252 +++++++++++++++++++++++++
 arch/arm/boot/dts/uniphier-ph1-sld3-ref.dts |   9 +
 arch/arm/boot/dts/uniphier-ph1-sld3.dtsi    |  61 +++++++
 arch/arm/boot/dts/uniphier-ph1-sld8-ref.dts |   8 +
 arch/arm/boot/dts/uniphier-ph1-sld8.dtsi    |  58 ++++++
 arch/arm/boot/dts/uniphier-pinctrl.dtsi     |  20 ++
 arch/arm/boot/dts/uniphier-proxstream2.dtsi | 273 ++++++++++++++++++++++++++++
 14 files changed, 1013 insertions(+), 1 deletion(-)
 create mode 100644 arch/arm/boot/dts/uniphier-ph1-ld6b-ref.dts
 create mode 100644 arch/arm/boot/dts/uniphier-ph1-ld6b.dtsi
 create mode 100644 arch/arm/boot/dts/uniphier-ph1-pro5.dtsi
 create mode 100644 arch/arm/boot/dts/uniphier-proxstream2.dtsi

-- 
1.9.1



From yamada.masahiro at socionext.com  Tue Aug  4 04:21:03 2015
From: yamada.masahiro at socionext.com (Masahiro Yamada)
Date: Tue,  4 Aug 2015 20:21:03 +0900
Subject: [PATCH 2/3] ARM: dts: UniPhier: add PH1-Pro5 SoC support
In-Reply-To: <1438687264-26538-1-git-send-email-yamada.masahiro@socionext.com>
References: <1438687264-26538-1-git-send-email-yamada.masahiro@socionext.com>
Message-ID: <1438687264-26538-3-git-send-email-yamada.masahiro@socionext.com>

Initial version of UniPhier PH1-Pro5 device tree.

Signed-off-by: Masahiro Yamada <yamada.masahiro at socionext.com>
---

 arch/arm/boot/dts/uniphier-ph1-pro5.dtsi | 252 +++++++++++++++++++++++++++++++
 1 file changed, 252 insertions(+)
 create mode 100644 arch/arm/boot/dts/uniphier-ph1-pro5.dtsi

diff --git a/arch/arm/boot/dts/uniphier-ph1-pro5.dtsi b/arch/arm/boot/dts/uniphier-ph1-pro5.dtsi
new file mode 100644
index 0000000..59c2b12
--- /dev/null
+++ b/arch/arm/boot/dts/uniphier-ph1-pro5.dtsi
@@ -0,0 +1,252 @@
+/*
+ * Device Tree Source for UniPhier PH1-Pro5 SoC
+ *
+ * Copyright (C) 2015 Masahiro Yamada <yamada.masahiro at socionext.com>
+ *
+ * This file is dual-licensed: you can use it either under the terms
+ * of the GPL or the X11 license, at your option. Note that this dual
+ * licensing only applies to this file, and not this project as a
+ * whole.
+ *
+ *  a) This file is free software; you can redistribute it and/or
+ *     modify it under the terms of the GNU General Public License as
+ *     published by the Free Software Foundation; either version 2 of the
+ *     License, or (at your option) any later version.
+ *
+ *     This file is distributed in the hope that it will be useful,
+ *     but WITHOUT ANY WARRANTY; without even the implied warranty of
+ *     MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ *     GNU General Public License for more details.
+ *
+ * Or, alternatively,
+ *
+ *  b) Permission is hereby granted, free of charge, to any person
+ *     obtaining a copy of this software and associated documentation
+ *     files (the "Software"), to deal in the Software without
+ *     restriction, including without limitation the rights to use,
+ *     copy, modify, merge, publish, distribute, sublicense, and/or
+ *     sell copies of the Software, and to permit persons to whom the
+ *     Software is furnished to do so, subject to the following
+ *     conditions:
+ *
+ *     The above copyright notice and this permission notice shall be
+ *     included in all copies or substantial portions of the Software.
+ *
+ *     THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
+ *     EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES
+ *     OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
+ *     NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT
+ *     HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY,
+ *     WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
+ *     FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR
+ *     OTHER DEALINGS IN THE SOFTWARE.
+ */
+
+/include/ "skeleton.dtsi"
+
+/ {
+	compatible = "socionext,ph1-pro5";
+
+	cpus {
+		#address-cells = <1>;
+		#size-cells = <0>;
+		enable-method = "socionext,uniphier-smp";
+
+		cpu at 0 {
+			device_type = "cpu";
+			compatible = "arm,cortex-a9";
+			reg = <0>;
+		};
+
+		cpu at 1 {
+			device_type = "cpu";
+			compatible = "arm,cortex-a9";
+			reg = <1>;
+		};
+	};
+
+	clocks {
+		arm_timer_clk: arm_timer_clk {
+			#clock-cells = <0>;
+			compatible = "fixed-clock";
+			clock-frequency = <50000000>;
+		};
+
+		uart_clk: uart_clk {
+			#clock-cells = <0>;
+			compatible = "fixed-clock";
+			clock-frequency = <73728000>;
+		};
+
+		i2c_clk: i2c_clk {
+			#clock-cells = <0>;
+			compatible = "fixed-clock";
+			clock-frequency = <50000000>;
+		};
+	};
+
+	soc {
+		compatible = "simple-bus";
+		#address-cells = <1>;
+		#size-cells = <1>;
+		ranges;
+		interrupt-parent = <&intc>;
+
+		extbus: extbus {
+			compatible = "simple-bus";
+			#address-cells = <2>;
+			#size-cells = <1>;
+		};
+
+		serial0: serial at 54006800 {
+			compatible = "socionext,uniphier-uart";
+			status = "disabled";
+			reg = <0x54006800 0x40>;
+			pinctrl-names = "default";
+			pinctrl-0 = <&pinctrl_uart0>;
+			interrupts = <0 33 4>;
+			clocks = <&uart_clk>;
+		};
+
+		serial1: serial at 54006900 {
+			compatible = "socionext,uniphier-uart";
+			status = "disabled";
+			reg = <0x54006900 0x40>;
+			pinctrl-names = "default";
+			pinctrl-0 = <&pinctrl_uart1>;
+			interrupts = <0 35 4>;
+			clocks = <&uart_clk>;
+		};
+
+		serial2: serial at 54006a00 {
+			compatible = "socionext,uniphier-uart";
+			status = "disabled";
+			reg = <0x54006a00 0x40>;
+			pinctrl-names = "default";
+			pinctrl-0 = <&pinctrl_uart2>;
+			interrupts = <0 37 4>;
+			clocks = <&uart_clk>;
+		};
+
+		serial3: serial at 54006b00 {
+			compatible = "socionext,uniphier-uart";
+			status = "disabled";
+			reg = <0x54006b00 0x40>;
+			pinctrl-names = "default";
+			pinctrl-0 = <&pinctrl_uart3>;
+			interrupts = <0 177 4>;
+			clocks = <&uart_clk>;
+		};
+
+		i2c0: i2c at 58780000 {
+			compatible = "socionext,uniphier-fi2c";
+			status = "disabled";
+			reg = <0x58780000 0x80>;
+			#address-cells = <1>;
+			#size-cells = <0>;
+			pinctrl-names = "default";
+			pinctrl-0 = <&pinctrl_i2c0>;
+			interrupts = <0 41 4>;
+			clocks = <&i2c_clk>;
+			clock-frequency = <100000>;
+		};
+
+		i2c1: i2c at 58781000 {
+			compatible = "socionext,uniphier-fi2c";
+			status = "disabled";
+			reg = <0x58781000 0x80>;
+			#address-cells = <1>;
+			#size-cells = <0>;
+			pinctrl-names = "default";
+			pinctrl-0 = <&pinctrl_i2c1>;
+			interrupts = <0 42 4>;
+			clocks = <&i2c_clk>;
+			clock-frequency = <100000>;
+		};
+
+		i2c2: i2c at 58782000 {
+			compatible = "socionext,uniphier-fi2c";
+			status = "disabled";
+			reg = <0x58782000 0x80>;
+			#address-cells = <1>;
+			#size-cells = <0>;
+			pinctrl-names = "default";
+			pinctrl-0 = <&pinctrl_i2c2>;
+			interrupts = <0 43 4>;
+			clocks = <&i2c_clk>;
+			clock-frequency = <100000>;
+		};
+
+		i2c3: i2c at 58783000 {
+			compatible = "socionext,uniphier-fi2c";
+			status = "disabled";
+			reg = <0x58783000 0x80>;
+			#address-cells = <1>;
+			#size-cells = <0>;
+			pinctrl-names = "default";
+			pinctrl-0 = <&pinctrl_i2c3>;
+			interrupts = <0 44 4>;
+			clocks = <&i2c_clk>;
+			clock-frequency = <100000>;
+		};
+
+		/* i2c4 does not exist */
+
+		/* chip-internal connection for DMD */
+		i2c5: i2c at 58785000 {
+			compatible = "socionext,uniphier-fi2c";
+			reg = <0x58785000 0x80>;
+			#address-cells = <1>;
+			#size-cells = <0>;
+			interrupts = <0 25 4>;
+			clocks = <&i2c_clk>;
+			clock-frequency = <400000>;
+		};
+
+		/* chip-internal connection for HDMI */
+		i2c6: i2c at 58786000 {
+			compatible = "socionext,uniphier-fi2c";
+			reg = <0x58786000 0x80>;
+			#address-cells = <1>;
+			#size-cells = <0>;
+			interrupts = <0 26 4>;
+			clocks = <&i2c_clk>;
+			clock-frequency = <400000>;
+		};
+
+		system-bus-controller-misc at 59800000 {
+			compatible = "socionext,uniphier-system-bus-controller-misc",
+				     "syscon";
+			reg = <0x59800000 0x2000>;
+		};
+
+		pinctrl: pinctrl at 5f801000 {
+			compatible = "socionext,ph1-pro5-pinctrl", "syscon";
+			reg = <0x5f801000 0xe00>;
+		};
+
+		timer at 60000200 {
+			compatible = "arm,cortex-a9-global-timer";
+			reg = <0x60000200 0x20>;
+			interrupts = <1 11 0x304>;
+			clocks = <&arm_timer_clk>;
+		};
+
+		timer at 60000600 {
+			compatible = "arm,cortex-a9-twd-timer";
+			reg = <0x60000600 0x20>;
+			interrupts = <1 13 0x304>;
+			clocks = <&arm_timer_clk>;
+		};
+
+		intc: interrupt-controller at 60001000 {
+			compatible = "arm,cortex-a9-gic";
+			#interrupt-cells = <3>;
+			interrupt-controller;
+			reg = <0x60001000 0x1000>,
+			      <0x60000100 0x100>;
+		};
+	};
+};
+
+/include/ "uniphier-pinctrl.dtsi"
-- 
1.9.1



From yamada.masahiro at socionext.com  Tue Aug  4 04:21:02 2015
From: yamada.masahiro at socionext.com (Masahiro Yamada)
Date: Tue,  4 Aug 2015 20:21:02 +0900
Subject: [PATCH 1/3] ARM: dts: UniPhier: add I2C controller device nodes
In-Reply-To: <1438687264-26538-1-git-send-email-yamada.masahiro@socionext.com>
References: <1438687264-26538-1-git-send-email-yamada.masahiro@socionext.com>
Message-ID: <1438687264-26538-2-git-send-email-yamada.masahiro@socionext.com>

Add I2C controller device nodes for PH1-sLD3, PH1-LD4, PH1-sLD8
(FIFO-less I2C) and PH1-Pro4 (FIFO-builtin I2C).

Signed-off-by: Masahiro Yamada <yamada.masahiro at socionext.com>
---

 arch/arm/boot/dts/uniphier-ph1-ld4-ref.dts  |  8 +++
 arch/arm/boot/dts/uniphier-ph1-ld4.dtsi     | 58 ++++++++++++++++++++
 arch/arm/boot/dts/uniphier-ph1-pro4-ref.dts | 10 ++++
 arch/arm/boot/dts/uniphier-ph1-pro4.dtsi    | 82 +++++++++++++++++++++++++++++
 arch/arm/boot/dts/uniphier-ph1-sld3-ref.dts |  9 ++++
 arch/arm/boot/dts/uniphier-ph1-sld3.dtsi    | 61 +++++++++++++++++++++
 arch/arm/boot/dts/uniphier-ph1-sld8-ref.dts |  8 +++
 arch/arm/boot/dts/uniphier-ph1-sld8.dtsi    | 58 ++++++++++++++++++++
 arch/arm/boot/dts/uniphier-pinctrl.dtsi     | 20 +++++++
 9 files changed, 314 insertions(+)

diff --git a/arch/arm/boot/dts/uniphier-ph1-ld4-ref.dts b/arch/arm/boot/dts/uniphier-ph1-ld4-ref.dts
index 7ac053d..5d24c57 100644
--- a/arch/arm/boot/dts/uniphier-ph1-ld4-ref.dts
+++ b/arch/arm/boot/dts/uniphier-ph1-ld4-ref.dts
@@ -65,6 +65,10 @@
 		serial1 = &serial1;
 		serial2 = &serial2;
 		serial3 = &serial3;
+		i2c0 = &i2c0;
+		i2c1 = &i2c1;
+		i2c2 = &i2c2;
+		i2c3 = &i2c3;
 	};
 };
 
@@ -93,6 +97,10 @@
 	status = "okay";
 };
 
+&i2c0 {
+	status = "okay";
+};
+
 &usb0 {
 	status = "okay";
 };
diff --git a/arch/arm/boot/dts/uniphier-ph1-ld4.dtsi b/arch/arm/boot/dts/uniphier-ph1-ld4.dtsi
index 4add90b..a6a185f 100644
--- a/arch/arm/boot/dts/uniphier-ph1-ld4.dtsi
+++ b/arch/arm/boot/dts/uniphier-ph1-ld4.dtsi
@@ -70,6 +70,12 @@
 			compatible = "fixed-clock";
 			clock-frequency = <36864000>;
 		};
+
+		iobus_clk: iobus_clk {
+			#clock-cells = <0>;
+			compatible = "fixed-clock";
+			clock-frequency = <100000000>;
+		};
 	};
 
 	soc {
@@ -129,6 +135,58 @@
 			fifo-size = <64>;
 		};
 
+		i2c0: i2c at 58400000 {
+			compatible = "socionext,uniphier-i2c";
+			status = "disabled";
+			reg = <0x58400000 0x40>;
+			#address-cells = <1>;
+			#size-cells = <0>;
+			pinctrl-names = "default";
+			pinctrl-0 = <&pinctrl_i2c0>;
+			interrupts = <0 41 1>;
+			clocks = <&iobus_clk>;
+			clock-frequency = <100000>;
+		};
+
+		i2c1: i2c at 58480000 {
+			compatible = "socionext,uniphier-i2c";
+			status = "disabled";
+			reg = <0x58480000 0x40>;
+			#address-cells = <1>;
+			#size-cells = <0>;
+			pinctrl-names = "default";
+			pinctrl-0 = <&pinctrl_i2c1>;
+			interrupts = <0 42 1>;
+			clocks = <&iobus_clk>;
+			clock-frequency = <100000>;
+		};
+
+		/* chip-internal connection for DMD */
+		i2c2: i2c at 58500000 {
+			compatible = "socionext,uniphier-i2c";
+			reg = <0x58500000 0x40>;
+			#address-cells = <1>;
+			#size-cells = <0>;
+			pinctrl-names = "default";
+			pinctrl-0 = <&pinctrl_i2c2>;
+			interrupts = <0 43 1>;
+			clocks = <&iobus_clk>;
+			clock-frequency = <400000>;
+		};
+
+		i2c3: i2c at 58580000 {
+			compatible = "socionext,uniphier-i2c";
+			status = "disabled";
+			reg = <0x58580000 0x40>;
+			#address-cells = <1>;
+			#size-cells = <0>;
+			pinctrl-names = "default";
+			pinctrl-0 = <&pinctrl_i2c3>;
+			interrupts = <0 44 1>;
+			clocks = <&iobus_clk>;
+			clock-frequency = <100000>;
+		};
+
 		system-bus-controller-misc at 59800000 {
 			compatible = "socionext,uniphier-system-bus-controller-misc",
 				     "syscon";
diff --git a/arch/arm/boot/dts/uniphier-ph1-pro4-ref.dts b/arch/arm/boot/dts/uniphier-ph1-pro4-ref.dts
index b669d32..26c18ac 100644
--- a/arch/arm/boot/dts/uniphier-ph1-pro4-ref.dts
+++ b/arch/arm/boot/dts/uniphier-ph1-pro4-ref.dts
@@ -65,6 +65,12 @@
 		serial1 = &serial1;
 		serial2 = &serial2;
 		serial3 = &serial3;
+		i2c0 = &i2c0;
+		i2c1 = &i2c1;
+		i2c2 = &i2c2;
+		i2c3 = &i2c3;
+		i2c5 = &i2c5;
+		i2c6 = &i2c6;
 	};
 };
 
@@ -93,6 +99,10 @@
 	status = "okay";
 };
 
+&i2c0 {
+	status = "okay";
+};
+
 &usb2 {
 	status = "okay";
 };
diff --git a/arch/arm/boot/dts/uniphier-ph1-pro4.dtsi b/arch/arm/boot/dts/uniphier-ph1-pro4.dtsi
index d0ca4c8..e8bbc45 100644
--- a/arch/arm/boot/dts/uniphier-ph1-pro4.dtsi
+++ b/arch/arm/boot/dts/uniphier-ph1-pro4.dtsi
@@ -77,6 +77,12 @@
 			compatible = "fixed-clock";
 			clock-frequency = <73728000>;
 		};
+
+		i2c_clk: i2c_clk {
+			#clock-cells = <0>;
+			compatible = "fixed-clock";
+			clock-frequency = <50000000>;
+		};
 	};
 
 	soc {
@@ -136,6 +142,82 @@
 			fifo-size = <64>;
 		};
 
+		i2c0: i2c at 58780000 {
+			compatible = "socionext,uniphier-fi2c";
+			status = "disabled";
+			reg = <0x58780000 0x80>;
+			#address-cells = <1>;
+			#size-cells = <0>;
+			pinctrl-names = "default";
+			pinctrl-0 = <&pinctrl_i2c0>;
+			interrupts = <0 41 4>;
+			clocks = <&i2c_clk>;
+			clock-frequency = <100000>;
+		};
+
+		i2c1: i2c at 58781000 {
+			compatible = "socionext,uniphier-fi2c";
+			status = "disabled";
+			reg = <0x58781000 0x80>;
+			#address-cells = <1>;
+			#size-cells = <0>;
+			pinctrl-names = "default";
+			pinctrl-0 = <&pinctrl_i2c1>;
+			interrupts = <0 42 4>;
+			clocks = <&i2c_clk>;
+			clock-frequency = <100000>;
+		};
+
+		i2c2: i2c at 58782000 {
+			compatible = "socionext,uniphier-fi2c";
+			status = "disabled";
+			reg = <0x58782000 0x80>;
+			#address-cells = <1>;
+			#size-cells = <0>;
+			pinctrl-names = "default";
+			pinctrl-0 = <&pinctrl_i2c2>;
+			interrupts = <0 43 4>;
+			clocks = <&i2c_clk>;
+			clock-frequency = <100000>;
+		};
+
+		i2c3: i2c at 58783000 {
+			compatible = "socionext,uniphier-fi2c";
+			status = "disabled";
+			reg = <0x58783000 0x80>;
+			#address-cells = <1>;
+			#size-cells = <0>;
+			pinctrl-names = "default";
+			pinctrl-0 = <&pinctrl_i2c3>;
+			interrupts = <0 44 4>;
+			clocks = <&i2c_clk>;
+			clock-frequency = <100000>;
+		};
+
+		/* i2c4 does not exist */
+
+		/* chip-internal connection for DMD */
+		i2c5: i2c at 58785000 {
+			compatible = "socionext,uniphier-fi2c";
+			reg = <0x58785000 0x80>;
+			#address-cells = <1>;
+			#size-cells = <0>;
+			interrupts = <0 25 4>;
+			clocks = <&i2c_clk>;
+			clock-frequency = <400000>;
+		};
+
+		/* chip-internal connection for HDMI */
+		i2c6: i2c at 58786000 {
+			compatible = "socionext,uniphier-fi2c";
+			reg = <0x58786000 0x80>;
+			#address-cells = <1>;
+			#size-cells = <0>;
+			interrupts = <0 26 4>;
+			clocks = <&i2c_clk>;
+			clock-frequency = <400000>;
+		};
+
 		system-bus-controller-misc at 59800000 {
 			compatible = "socionext,uniphier-system-bus-controller-misc",
 				     "syscon";
diff --git a/arch/arm/boot/dts/uniphier-ph1-sld3-ref.dts b/arch/arm/boot/dts/uniphier-ph1-sld3-ref.dts
index 48f7361..cb6e9aa 100644
--- a/arch/arm/boot/dts/uniphier-ph1-sld3-ref.dts
+++ b/arch/arm/boot/dts/uniphier-ph1-sld3-ref.dts
@@ -65,6 +65,11 @@
 		serial0 = &serial0;
 		serial1 = &serial1;
 		serial2 = &serial2;
+		i2c0 = &i2c0;
+		i2c1 = &i2c1;
+		i2c2 = &i2c2;
+		i2c3 = &i2c3;
+		i2c4 = &i2c4;
 	};
 };
 
@@ -93,6 +98,10 @@
 	status = "okay";
 };
 
+&i2c0 {
+	status = "okay";
+};
+
 &usb0 {
 	status = "okay";
 };
diff --git a/arch/arm/boot/dts/uniphier-ph1-sld3.dtsi b/arch/arm/boot/dts/uniphier-ph1-sld3.dtsi
index db74457..3cc90cd 100644
--- a/arch/arm/boot/dts/uniphier-ph1-sld3.dtsi
+++ b/arch/arm/boot/dts/uniphier-ph1-sld3.dtsi
@@ -77,6 +77,12 @@
 			compatible = "fixed-clock";
 			clock-frequency = <36864000>;
 		};
+
+		iobus_clk: iobus_clk {
+			#clock-cells = <0>;
+			compatible = "fixed-clock";
+			clock-frequency = <100000000>;
+		};
 	};
 
 	soc {
@@ -141,6 +147,61 @@
 			fifo-size = <64>;
 		};
 
+		i2c0: i2c at 58400000 {
+			compatible = "socionext,uniphier-i2c";
+			status = "disabled";
+			reg = <0x58400000 0x40>;
+			#address-cells = <1>;
+			#size-cells = <0>;
+			interrupts = <0 41 1>;
+			clocks = <&iobus_clk>;
+			clock-frequency = <100000>;
+		};
+
+		i2c1: i2c at 58480000 {
+			compatible = "socionext,uniphier-i2c";
+			status = "disabled";
+			reg = <0x58480000 0x40>;
+			#address-cells = <1>;
+			#size-cells = <0>;
+			interrupts = <0 42 1>;
+			clocks = <&iobus_clk>;
+			clock-frequency = <100000>;
+		};
+
+		i2c2: i2c at 58500000 {
+			compatible = "socionext,uniphier-i2c";
+			status = "disabled";
+			reg = <0x58500000 0x40>;
+			#address-cells = <1>;
+			#size-cells = <0>;
+			interrupts = <0 43 1>;
+			clocks = <&iobus_clk>;
+			clock-frequency = <100000>;
+		};
+
+		i2c3: i2c at 58580000 {
+			compatible = "socionext,uniphier-i2c";
+			status = "disabled";
+			reg = <0x58580000 0x40>;
+			#address-cells = <1>;
+			#size-cells = <0>;
+			interrupts = <0 44 1>;
+			clocks = <&iobus_clk>;
+			clock-frequency = <100000>;
+		};
+
+		/* chip-internal connection for DMD */
+		i2c4: i2c at 58600000 {
+			compatible = "socionext,uniphier-i2c";
+			reg = <0x58600000 0x40>;
+			#address-cells = <1>;
+			#size-cells = <0>;
+			interrupts = <0 45 1>;
+			clocks = <&iobus_clk>;
+			clock-frequency = <400000>;
+		};
+
 		system-bus-controller-misc at 59800000 {
 			compatible = "socionext,uniphier-system-bus-controller-misc",
 				     "syscon";
diff --git a/arch/arm/boot/dts/uniphier-ph1-sld8-ref.dts b/arch/arm/boot/dts/uniphier-ph1-sld8-ref.dts
index 9b5992a..a40a0fb 100644
--- a/arch/arm/boot/dts/uniphier-ph1-sld8-ref.dts
+++ b/arch/arm/boot/dts/uniphier-ph1-sld8-ref.dts
@@ -65,6 +65,10 @@
 		serial1 = &serial1;
 		serial2 = &serial2;
 		serial3 = &serial3;
+		i2c0 = &i2c0;
+		i2c1 = &i2c1;
+		i2c2 = &i2c2;
+		i2c3 = &i2c3;
 	};
 };
 
@@ -93,6 +97,10 @@
 	status = "okay";
 };
 
+&i2c0 {
+	status = "okay";
+};
+
 &usb0 {
 	status = "okay";
 };
diff --git a/arch/arm/boot/dts/uniphier-ph1-sld8.dtsi b/arch/arm/boot/dts/uniphier-ph1-sld8.dtsi
index 3ead910..58067df 100644
--- a/arch/arm/boot/dts/uniphier-ph1-sld8.dtsi
+++ b/arch/arm/boot/dts/uniphier-ph1-sld8.dtsi
@@ -70,6 +70,12 @@
 			compatible = "fixed-clock";
 			clock-frequency = <80000000>;
 		};
+
+		iobus_clk: iobus_clk {
+			#clock-cells = <0>;
+			compatible = "fixed-clock";
+			clock-frequency = <100000000>;
+		};
 	};
 
 	soc {
@@ -129,6 +135,58 @@
 			fifo-size = <64>;
 		};
 
+		i2c0: i2c at 58400000 {
+			compatible = "socionext,uniphier-i2c";
+			status = "disabled";
+			reg = <0x58400000 0x40>;
+			#address-cells = <1>;
+			#size-cells = <0>;
+			pinctrl-names = "default";
+			pinctrl-0 = <&pinctrl_i2c0>;
+			interrupts = <0 41 1>;
+			clocks = <&iobus_clk>;
+			clock-frequency = <100000>;
+		};
+
+		i2c1: i2c at 58480000 {
+			compatible = "socionext,uniphier-i2c";
+			status = "disabled";
+			reg = <0x58480000 0x40>;
+			#address-cells = <1>;
+			#size-cells = <0>;
+			pinctrl-names = "default";
+			pinctrl-0 = <&pinctrl_i2c1>;
+			interrupts = <0 42 1>;
+			clocks = <&iobus_clk>;
+			clock-frequency = <100000>;
+		};
+
+		/* chip-internal connection for DMD */
+		i2c2: i2c at 58500000 {
+			compatible = "socionext,uniphier-i2c";
+			reg = <0x58500000 0x40>;
+			#address-cells = <1>;
+			#size-cells = <0>;
+			pinctrl-names = "default";
+			pinctrl-0 = <&pinctrl_i2c2>;
+			interrupts = <0 43 1>;
+			clocks = <&iobus_clk>;
+			clock-frequency = <400000>;
+		};
+
+		i2c3: i2c at 58580000 {
+			compatible = "socionext,uniphier-i2c";
+			status = "disabled";
+			reg = <0x58580000 0x40>;
+			#address-cells = <1>;
+			#size-cells = <0>;
+			pinctrl-names = "default";
+			pinctrl-0 = <&pinctrl_i2c3>;
+			interrupts = <0 44 1>;
+			clocks = <&iobus_clk>;
+			clock-frequency = <100000>;
+		};
+
 		system-bus-controller-misc at 59800000 {
 			compatible = "socionext,uniphier-system-bus-controller-misc",
 				     "syscon";
diff --git a/arch/arm/boot/dts/uniphier-pinctrl.dtsi b/arch/arm/boot/dts/uniphier-pinctrl.dtsi
index 1b5b4fe..f67445f 100644
--- a/arch/arm/boot/dts/uniphier-pinctrl.dtsi
+++ b/arch/arm/boot/dts/uniphier-pinctrl.dtsi
@@ -43,6 +43,26 @@
  */
 
 &pinctrl {
+	pinctrl_i2c0: i2c0_grp {
+		groups = "i2c0";
+		function = "i2c0";
+	};
+
+	pinctrl_i2c1: i2c1_grp {
+		groups = "i2c1";
+		function = "i2c1";
+	};
+
+	pinctrl_i2c2: i2c2_grp {
+		groups = "i2c2";
+		function = "i2c2";
+	};
+
+	pinctrl_i2c3: i2c3_grp {
+		groups = "i2c3";
+		function = "i2c3";
+	};
+
 	pinctrl_uart0: uart0_grp {
 		groups = "uart0";
 		function = "uart0";
-- 
1.9.1



From yamada.masahiro at socionext.com  Tue Aug  4 04:21:04 2015
From: yamada.masahiro at socionext.com (Masahiro Yamada)
Date: Tue,  4 Aug 2015 20:21:04 +0900
Subject: [PATCH 3/3] ARM: dts: UniPhier: add ProXstream2 and PH1-LD6b
 SoC/board support
In-Reply-To: <1438687264-26538-1-git-send-email-yamada.masahiro@socionext.com>
References: <1438687264-26538-1-git-send-email-yamada.masahiro@socionext.com>
Message-ID: <1438687264-26538-4-git-send-email-yamada.masahiro@socionext.com>

Initial version of DTSI for ProXstream2 and PH1-LD6b and DTS for
PH1-LD6b reference board.

Signed-off-by: Masahiro Yamada <yamada.masahiro at socionext.com>
---

 arch/arm/boot/dts/Makefile                  |   3 +-
 arch/arm/boot/dts/uniphier-ph1-ld6b-ref.dts | 105 +++++++++++
 arch/arm/boot/dts/uniphier-ph1-ld6b.dtsi    |  67 +++++++
 arch/arm/boot/dts/uniphier-proxstream2.dtsi | 273 ++++++++++++++++++++++++++++
 4 files changed, 447 insertions(+), 1 deletion(-)
 create mode 100644 arch/arm/boot/dts/uniphier-ph1-ld6b-ref.dts
 create mode 100644 arch/arm/boot/dts/uniphier-ph1-ld6b.dtsi
 create mode 100644 arch/arm/boot/dts/uniphier-proxstream2.dtsi

diff --git a/arch/arm/boot/dts/Makefile b/arch/arm/boot/dts/Makefile
index 246473a..6eb3f2f 100644
--- a/arch/arm/boot/dts/Makefile
+++ b/arch/arm/boot/dts/Makefile
@@ -645,7 +645,8 @@ dtb-$(CONFIG_ARCH_UNIPHIER) += \
 	uniphier-ph1-sld3-ref.dtb \
 	uniphier-ph1-ld4-ref.dtb \
 	uniphier-ph1-pro4-ref.dtb \
-	uniphier-ph1-sld8-ref.dtb
+	uniphier-ph1-sld8-ref.dtb \
+	uniphier-ph1-ld6b-ref.dtb
 dtb-$(CONFIG_ARCH_VERSATILE) += \
 	versatile-ab.dtb \
 	versatile-pb.dtb
diff --git a/arch/arm/boot/dts/uniphier-ph1-ld6b-ref.dts b/arch/arm/boot/dts/uniphier-ph1-ld6b-ref.dts
new file mode 100644
index 0000000..33963ac
--- /dev/null
+++ b/arch/arm/boot/dts/uniphier-ph1-ld6b-ref.dts
@@ -0,0 +1,105 @@
+/*
+ * Device Tree Source for UniPhier PH1-LD6b Reference Board
+ *
+ * Copyright (C) 2015 Masahiro Yamada <yamada.masahiro at socionext.com>
+ *
+ * This file is dual-licensed: you can use it either under the terms
+ * of the GPL or the X11 license, at your option. Note that this dual
+ * licensing only applies to this file, and not this project as a
+ * whole.
+ *
+ *  a) This file is free software; you can redistribute it and/or
+ *     modify it under the terms of the GNU General Public License as
+ *     published by the Free Software Foundation; either version 2 of the
+ *     License, or (at your option) any later version.
+ *
+ *     This file is distributed in the hope that it will be useful,
+ *     but WITHOUT ANY WARRANTY; without even the implied warranty of
+ *     MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ *     GNU General Public License for more details.
+ *
+ * Or, alternatively,
+ *
+ *  b) Permission is hereby granted, free of charge, to any person
+ *     obtaining a copy of this software and associated documentation
+ *     files (the "Software"), to deal in the Software without
+ *     restriction, including without limitation the rights to use,
+ *     copy, modify, merge, publish, distribute, sublicense, and/or
+ *     sell copies of the Software, and to permit persons to whom the
+ *     Software is furnished to do so, subject to the following
+ *     conditions:
+ *
+ *     The above copyright notice and this permission notice shall be
+ *     included in all copies or substantial portions of the Software.
+ *
+ *     THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
+ *     EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES
+ *     OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
+ *     NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT
+ *     HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY,
+ *     WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
+ *     FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR
+ *     OTHER DEALINGS IN THE SOFTWARE.
+ */
+
+/dts-v1/;
+/include/ "uniphier-ph1-ld6b.dtsi"
+/include/ "uniphier-ref-daughter.dtsi"
+/include/ "uniphier-support-card.dtsi"
+
+/ {
+	model = "UniPhier PH1-LD6b Reference Board";
+	compatible = "socionext,ph1-ld6b-ref", "socionext,ph1-ld6b";
+
+	memory {
+		device_type = "memory";
+		reg = <0x80000000 0x80000000>;
+	};
+
+	chosen {
+		bootargs = "console=ttyS0,115200";
+		stdout-path = &serial0;
+	};
+
+	aliases {
+		serial0 = &serial0;
+		serial1 = &serial1;
+		serial2 = &serial2;
+		i2c0 = &i2c0;
+		i2c1 = &i2c1;
+		i2c2 = &i2c2;
+		i2c3 = &i2c3;
+		i2c4 = &i2c4;
+		i2c5 = &i2c5;
+		i2c6 = &i2c6;
+	};
+};
+
+&extbus {
+	ranges = <0 0x00000000 0x0f000000 0x01000000
+		  1 0x00000000 0x00000000 0x08000000>;
+};
+
+&support_card {
+	ranges = <0x00000000 1 0x03f00000 0x00100000>;
+};
+
+&ethsc {
+	interrupts = <0 50 4>;
+};
+
+&serial0 {
+	status = "okay";
+};
+
+&serial1 {
+	status = "okay";
+};
+
+&serial2 {
+	status = "okay";
+};
+
+&i2c0 {
+	status = "okay";
+};
diff --git a/arch/arm/boot/dts/uniphier-ph1-ld6b.dtsi b/arch/arm/boot/dts/uniphier-ph1-ld6b.dtsi
new file mode 100644
index 0000000..c6499ee
--- /dev/null
+++ b/arch/arm/boot/dts/uniphier-ph1-ld6b.dtsi
@@ -0,0 +1,67 @@
+/*
+ * Device Tree Source for UniPhier PH1-LD6b SoC
+ *
+ * Copyright (C) 2015 Masahiro Yamada <yamada.masahiro at socionext.com>
+ *
+ * This file is dual-licensed: you can use it either under the terms
+ * of the GPL or the X11 license, at your option. Note that this dual
+ * licensing only applies to this file, and not this project as a
+ * whole.
+ *
+ *  a) This file is free software; you can redistribute it and/or
+ *     modify it under the terms of the GNU General Public License as
+ *     published by the Free Software Foundation; either version 2 of the
+ *     License, or (at your option) any later version.
+ *
+ *     This file is distributed in the hope that it will be useful,
+ *     but WITHOUT ANY WARRANTY; without even the implied warranty of
+ *     MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ *     GNU General Public License for more details.
+ *
+ * Or, alternatively,
+ *
+ *  b) Permission is hereby granted, free of charge, to any person
+ *     obtaining a copy of this software and associated documentation
+ *     files (the "Software"), to deal in the Software without
+ *     restriction, including without limitation the rights to use,
+ *     copy, modify, merge, publish, distribute, sublicense, and/or
+ *     sell copies of the Software, and to permit persons to whom the
+ *     Software is furnished to do so, subject to the following
+ *     conditions:
+ *
+ *     The above copyright notice and this permission notice shall be
+ *     included in all copies or substantial portions of the Software.
+ *
+ *     THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
+ *     EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES
+ *     OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
+ *     NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT
+ *     HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY,
+ *     WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
+ *     FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR
+ *     OTHER DEALINGS IN THE SOFTWARE.
+ */
+
+/*
+ * PH1-LD6b consists of two silicon dies: D-chip and A-chip.
+ * The D-chip (digital chip) is the same as the ProXstream2 die.
+ * Reuse the ProXstream2 device tree with some properties overridden.
+ */
+/include/ "uniphier-proxstream2.dtsi"
+
+/ {
+	compatible = "socionext,ph1-ld6b";
+};
+
+/* UART3 unavilable: the pads are not wired to the package balls */
+&serial3 {
+	status = "disabled";
+};
+
+/*
+ * PH1-LD6b and ProXstream2 have completely different packages,
+ * which makes the pinctrl driver unshareable.
+ */
+&pinctrl {
+	compatible = "socionext,ph1-ld6b-pinctrl", "syscon";
+};
diff --git a/arch/arm/boot/dts/uniphier-proxstream2.dtsi b/arch/arm/boot/dts/uniphier-proxstream2.dtsi
new file mode 100644
index 0000000..ccf795a
--- /dev/null
+++ b/arch/arm/boot/dts/uniphier-proxstream2.dtsi
@@ -0,0 +1,273 @@
+/*
+ * Device Tree Source for UniPhier ProXstream2 SoC
+ *
+ * Copyright (C) 2015 Masahiro Yamada <yamada.masahiro at socionext.com>
+ *
+ * This file is dual-licensed: you can use it either under the terms
+ * of the GPL or the X11 license, at your option. Note that this dual
+ * licensing only applies to this file, and not this project as a
+ * whole.
+ *
+ *  a) This file is free software; you can redistribute it and/or
+ *     modify it under the terms of the GNU General Public License as
+ *     published by the Free Software Foundation; either version 2 of the
+ *     License, or (at your option) any later version.
+ *
+ *     This file is distributed in the hope that it will be useful,
+ *     but WITHOUT ANY WARRANTY; without even the implied warranty of
+ *     MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ *     GNU General Public License for more details.
+ *
+ * Or, alternatively,
+ *
+ *  b) Permission is hereby granted, free of charge, to any person
+ *     obtaining a copy of this software and associated documentation
+ *     files (the "Software"), to deal in the Software without
+ *     restriction, including without limitation the rights to use,
+ *     copy, modify, merge, publish, distribute, sublicense, and/or
+ *     sell copies of the Software, and to permit persons to whom the
+ *     Software is furnished to do so, subject to the following
+ *     conditions:
+ *
+ *     The above copyright notice and this permission notice shall be
+ *     included in all copies or substantial portions of the Software.
+ *
+ *     THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
+ *     EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES
+ *     OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
+ *     NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT
+ *     HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY,
+ *     WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
+ *     FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR
+ *     OTHER DEALINGS IN THE SOFTWARE.
+ */
+
+/include/ "skeleton.dtsi"
+
+/ {
+	compatible = "socionext,proxstream2";
+
+	cpus {
+		#address-cells = <1>;
+		#size-cells = <0>;
+		enable-method = "socionext,uniphier-smp";
+
+		cpu at 0 {
+			device_type = "cpu";
+			compatible = "arm,cortex-a9";
+			reg = <0>;
+		};
+
+		cpu at 1 {
+			device_type = "cpu";
+			compatible = "arm,cortex-a9";
+			reg = <1>;
+		};
+
+		cpu at 2 {
+			device_type = "cpu";
+			compatible = "arm,cortex-a9";
+			reg = <2>;
+		};
+
+		cpu at 3 {
+			device_type = "cpu";
+			compatible = "arm,cortex-a9";
+			reg = <3>;
+		};
+	};
+
+	clocks {
+		arm_timer_clk: arm_timer_clk {
+			#clock-cells = <0>;
+			compatible = "fixed-clock";
+			clock-frequency = <50000000>;
+		};
+
+		uart_clk: uart_clk {
+			#clock-cells = <0>;
+			compatible = "fixed-clock";
+			clock-frequency = <88900000>;
+		};
+
+		i2c_clk: i2c_clk {
+			#clock-cells = <0>;
+			compatible = "fixed-clock";
+			clock-frequency = <50000000>;
+		};
+	};
+
+	soc {
+		compatible = "simple-bus";
+		#address-cells = <1>;
+		#size-cells = <1>;
+		ranges;
+		interrupt-parent = <&intc>;
+
+		extbus: extbus {
+			compatible = "simple-bus";
+			#address-cells = <2>;
+			#size-cells = <1>;
+		};
+
+		serial0: serial at 54006800 {
+			compatible = "socionext,uniphier-uart";
+			status = "disabled";
+			reg = <0x54006800 0x40>;
+			pinctrl-names = "default";
+			pinctrl-0 = <&pinctrl_uart0>;
+			interrupts = <0 33 4>;
+			clocks = <&uart_clk>;
+		};
+
+		serial1: serial at 54006900 {
+			compatible = "socionext,uniphier-uart";
+			status = "disabled";
+			reg = <0x54006900 0x40>;
+			pinctrl-names = "default";
+			pinctrl-0 = <&pinctrl_uart1>;
+			interrupts = <0 35 4>;
+			clocks = <&uart_clk>;
+		};
+
+		serial2: serial at 54006a00 {
+			compatible = "socionext,uniphier-uart";
+			status = "disabled";
+			reg = <0x54006a00 0x40>;
+			pinctrl-names = "default";
+			pinctrl-0 = <&pinctrl_uart2>;
+			interrupts = <0 37 4>;
+			clocks = <&uart_clk>;
+		};
+
+		serial3: serial at 54006b00 {
+			compatible = "socionext,uniphier-uart";
+			status = "disabled";
+			reg = <0x54006b00 0x40>;
+			pinctrl-names = "default";
+			pinctrl-0 = <&pinctrl_uart3>;
+			interrupts = <0 177 4>;
+			clocks = <&uart_clk>;
+		};
+
+		i2c0: i2c at 58780000 {
+			compatible = "socionext,uniphier-fi2c";
+			status = "disabled";
+			reg = <0x58780000 0x80>;
+			#address-cells = <1>;
+			#size-cells = <0>;
+			pinctrl-names = "default";
+			pinctrl-0 = <&pinctrl_i2c0>;
+			interrupts = <0 41 4>;
+			clocks = <&i2c_clk>;
+			clock-frequency = <100000>;
+		};
+
+		i2c1: i2c at 58781000 {
+			compatible = "socionext,uniphier-fi2c";
+			status = "disabled";
+			reg = <0x58781000 0x80>;
+			#address-cells = <1>;
+			#size-cells = <0>;
+			pinctrl-names = "default";
+			pinctrl-0 = <&pinctrl_i2c1>;
+			interrupts = <0 42 4>;
+			clocks = <&i2c_clk>;
+			clock-frequency = <100000>;
+		};
+
+		i2c2: i2c at 58782000 {
+			compatible = "socionext,uniphier-fi2c";
+			status = "disabled";
+			reg = <0x58782000 0x80>;
+			#address-cells = <1>;
+			#size-cells = <0>;
+			pinctrl-names = "default";
+			pinctrl-0 = <&pinctrl_i2c2>;
+			interrupts = <0 43 4>;
+			clocks = <&i2c_clk>;
+			clock-frequency = <100000>;
+		};
+
+		i2c3: i2c at 58783000 {
+			compatible = "socionext,uniphier-fi2c";
+			status = "disabled";
+			reg = <0x58783000 0x80>;
+			#address-cells = <1>;
+			#size-cells = <0>;
+			pinctrl-names = "default";
+			pinctrl-0 = <&pinctrl_i2c3>;
+			interrupts = <0 44 4>;
+			clocks = <&i2c_clk>;
+			clock-frequency = <100000>;
+		};
+
+		/* chip-internal connection for DMD */
+		i2c4: i2c at 58784000 {
+			compatible = "socionext,uniphier-fi2c";
+			reg = <0x58784000 0x80>;
+			#address-cells = <1>;
+			#size-cells = <0>;
+			interrupts = <0 45 4>;
+			clocks = <&i2c_clk>;
+			clock-frequency = <400000>;
+		};
+
+		/* chip-internal connection for STM */
+		i2c5: i2c at 58785000 {
+			compatible = "socionext,uniphier-fi2c";
+			reg = <0x58785000 0x80>;
+			#address-cells = <1>;
+			#size-cells = <0>;
+			interrupts = <0 25 4>;
+			clocks = <&i2c_clk>;
+			clock-frequency = <400000>;
+		};
+
+		/* chip-internal connection for HDMI */
+		i2c6: i2c at 58786000 {
+			compatible = "socionext,uniphier-fi2c";
+			reg = <0x58786000 0x80>;
+			#address-cells = <1>;
+			#size-cells = <0>;
+			interrupts = <0 26 4>;
+			clocks = <&i2c_clk>;
+			clock-frequency = <400000>;
+		};
+
+		system-bus-controller-misc at 59800000 {
+			compatible = "socionext,uniphier-system-bus-controller-misc",
+				     "syscon";
+			reg = <0x59800000 0x2000>;
+		};
+
+		pinctrl: pinctrl at 5f801000 {
+			compatible = "socionext,proxstream2-pinctrl", "syscon";
+			reg = <0x5f801000 0xe00>;
+		};
+
+		timer at 60000200 {
+			compatible = "arm,cortex-a9-global-timer";
+			reg = <0x60000200 0x20>;
+			interrupts = <1 11 0x304>;
+			clocks = <&arm_timer_clk>;
+		};
+
+		timer at 60000600 {
+			compatible = "arm,cortex-a9-twd-timer";
+			reg = <0x60000600 0x20>;
+			interrupts = <1 13 0x304>;
+			clocks = <&arm_timer_clk>;
+		};
+
+		intc: interrupt-controller at 60001000 {
+			compatible = "arm,cortex-a9-gic";
+			#interrupt-cells = <3>;
+			interrupt-controller;
+			reg = <0x60001000 0x1000>,
+			      <0x60000100 0x100>;
+		};
+	};
+};
+
+/include/ "uniphier-pinctrl.dtsi"
-- 
1.9.1



From bhupesh.sharma at freescale.com  Tue Aug  4 04:22:09 2015
From: bhupesh.sharma at freescale.com (Sharma Bhupesh)
Date: Tue, 4 Aug 2015 11:22:09 +0000
Subject: [Query] ARM64: Softlockup when using PSCI for secondary CPU_ON
In-Reply-To: <20150804111258.GC7056@leverpostej>
References: <BY1PR0301MB1303EC5AAE8F0B4DAA70D15F82770@BY1PR0301MB1303.namprd03.prod.outlook.com>
 <20150803100248.GA25627@leverpostej>
 <BY1PR0301MB1303B775B1D5D318A64350C582770@BY1PR0301MB1303.namprd03.prod.outlook.com>
 <BY1PR0301MB13035E3B09536F34F4C281CF82770@BY1PR0301MB1303.namprd03.prod.outlook.com>
 <20150804111258.GC7056@leverpostej>
Message-ID: <BY1PR0301MB130325110AF84E5C7D1A1F3182760@BY1PR0301MB1303.namprd03.prod.outlook.com>

Hi Mark,

> From: Mark Rutland [mailto:mark.rutland at arm.com]
> Sent: Tuesday, August 04, 2015 4:43 PM
> 
> Hi,
> 
> > > > Is Linux itself booted at EL1 or EL2?
> > >
> > > UEFI leaves the execution level of the primary core in EL2.
> > > KVM is turned-off in my defconfig, so I am not loading any
> > > hypervisor at
> > > EL2 as of now.
> 
> [...]
> 
> > > > > preempt self-detected stall on CPU { 3}  (t=17194 jiffies g=-267
> > > > > c=-268 q=1)
> > > >
> > > > > INFO: rcu_preempt detected stalls on CPUs/tasks: { 1 2}
> > > > > (detected by 0, t=287104493908 jiffies, g=-267, c=-268, q=2)
> > > >
> > > > It looks like your timekeeping has gone wrong. As mentioned above,
> > > > I'd suspect that CNTVOFF_EL2 is not programmed consistently across
> all CPUs.
> > > >
> > > > Are you able to boot Linux at EL2 instead? Or can you verify that
> > > > CNTVOFF_EL2 is initialised?
> > > >
> > >
> > > Ok, let me check the CNTVOFF_EL2 part then.
> > > I will get back with details soon.
> > >
> >
> > Indeed. Using the following code in the run-time EL3 firmware to
> > correctly set the
> > CNTVOFF_EL2 to zero for secondaries solves the soft-lockup. I took a
> > reference from your u-boot patch (see [1]).
> >
> > +	/* Initialize Generic Timers */
> > +	msr	cntvoff_el2, xzr
> >
> > [1] http://marc.info/?l=u-boot&m=140230240621878&w=2
> 
> That's good to hear!
> 
> However, this implies there are a couple of other issues. It sounds like
> your UEFI Linux Loader doesn't correctly initialise EL2 state, and drops
> EL1N before starting the kernel (or the kernel would have initialised
> CNTVOFF itself).
> 
> PSCI should boot CPUs into the first available non-secure exception
> level, which in this case is EL2, but it sounds like your implementation
> boots them to EL1N instead, which is incorrect and prevents Linux from
> being able to initialise EL2 correctly.
> 
> In the absence of a hypervisor, you should enter the kernel on all CPUs
> at EL2. That means we can configure more EL2 state in the kernel and your
> bootlaoder/firmware needs to do less.
> 
> I would also strongly recommend booting Linux as an EFI application
> rather than using the Linux Loader, as the loader isn't even compliant
> with the Linux boot protocol and hampers Linux booting correctly.

Right. I am planning soon to move to using the Linux EFI application and
the EFI_STUB, rather than relying on the UEFI Linux BDS loader. That
seems to be the next step in the logical direction as the conventional
UEFI BDS Linux Loader doesn't support EFI_STUB layer.

Regards,
Bhupesh




From eddie.huang at mediatek.com  Tue Aug  4 04:44:53 2015
From: eddie.huang at mediatek.com (Eddie Huang)
Date: Tue, 4 Aug 2015 19:44:53 +0800
Subject: [PATCH 2/2] i2c: mediatek: Fixup i2c ack error interrupt handling
In-Reply-To: <1438688693-60275-1-git-send-email-eddie.huang@mediatek.com>
References: <1438688693-60275-1-git-send-email-eddie.huang@mediatek.com>
Message-ID: <1438688693-60275-3-git-send-email-eddie.huang@mediatek.com>

When occur i2c ack error, mtk_i2c_irq is called twice,
first is the ack error interrupt, then the complete interrupt.
i2c interrupt handler should keep the two interrupt value, and only
call complete() for the complete interrupt.

Signed-off-by: Liguo Zhang <liguo.zhang at mediatek.com>
Signed-off-by: Eddie Huang <eddie.huang at mediatek.com>
---
 drivers/i2c/busses/i2c-mt65xx.c |   18 +++++++++++-------
 1 file changed, 11 insertions(+), 7 deletions(-)

diff --git a/drivers/i2c/busses/i2c-mt65xx.c b/drivers/i2c/busses/i2c-mt65xx.c
index 055159d..12ce7f8 100644
--- a/drivers/i2c/busses/i2c-mt65xx.c
+++ b/drivers/i2c/busses/i2c-mt65xx.c
@@ -558,16 +558,20 @@ err_exit:
 static irqreturn_t mtk_i2c_irq(int irqno, void *dev_id)
 {
 	struct mtk_i2c *i2c = dev_id;
-	u16 restart_flag = 0;
+	u16 intr_stat = 0;
 
-	if (i2c->dev_comp->auto_restart)
-		restart_flag = I2C_RS_TRANSFER;
+	intr_stat = readw(i2c->base + OFFSET_INTR_STAT);
+	writew(intr_stat, i2c->base + OFFSET_INTR_STAT);
 
-	i2c->irq_stat = readw(i2c->base + OFFSET_INTR_STAT);
-	writew(restart_flag | I2C_HS_NACKERR | I2C_ACKERR
-		| I2C_TRANSAC_COMP, i2c->base + OFFSET_INTR_STAT);
+	/*
+	 * when occurs i2c ack error, mtk_i2c_irq is called twice,
+	 * first is the ack error interrupt, then the complete interrupt,
+	 * i2c->irq_stat need keep the two interrupt value.
+	 */
+	i2c->irq_stat |= intr_stat;
 
-	complete(&i2c->msg_complete);
+	if (i2c->irq_stat & I2C_TRANSAC_COMP)
+		complete(&i2c->msg_complete);
 
 	return IRQ_HANDLED;
 }
-- 
1.7.9.5



From eddie.huang at mediatek.com  Tue Aug  4 04:44:51 2015
From: eddie.huang at mediatek.com (Eddie Huang)
Date: Tue, 4 Aug 2015 19:44:51 +0800
Subject: [PATCH 0/2] Mediatek I2C fixup  
Message-ID: <1438688693-60275-1-git-send-email-eddie.huang@mediatek.com>

This series provide two patches to optimize mediatek i2c driver.
The first patch will reset dma hardware in init function to make sure
hardware work in good state. The second patch fix i2c interrupt handling
for ACK error. All these patches base on v4.2-rc1.

Eddie Huang (2):
  i2c: mediatek: Reset DMA engine in hardware init function
  i2c: mediatek: Fixup i2c ack error interrupt handling

 drivers/i2c/busses/i2c-mt65xx.c |   28 ++++++++++++++++++++--------
 1 file changed, 20 insertions(+), 8 deletions(-)

-- 
1.7.9.5



From eddie.huang at mediatek.com  Tue Aug  4 04:44:52 2015
From: eddie.huang at mediatek.com (Eddie Huang)
Date: Tue, 4 Aug 2015 19:44:52 +0800
Subject: [PATCH 1/2] i2c: mediatek: Reset DMA engine in hardware init function
In-Reply-To: <1438688693-60275-1-git-send-email-eddie.huang@mediatek.com>
References: <1438688693-60275-1-git-send-email-eddie.huang@mediatek.com>
Message-ID: <1438688693-60275-2-git-send-email-eddie.huang@mediatek.com>

Reset DMA in hardware init function to avoid unknown hardware state
before do any I2C operation.

Signed-off-by: Liguo Zhang <liguo.zhang at mediatek.com>
Signed-off-by: Eddie Huang <eddie.huang at mediatek.com>
---
 drivers/i2c/busses/i2c-mt65xx.c |   10 +++++++++-
 1 file changed, 9 insertions(+), 1 deletion(-)

diff --git a/drivers/i2c/busses/i2c-mt65xx.c b/drivers/i2c/busses/i2c-mt65xx.c
index 9920eef..055159d 100644
--- a/drivers/i2c/busses/i2c-mt65xx.c
+++ b/drivers/i2c/busses/i2c-mt65xx.c
@@ -1,6 +1,8 @@
 /*
  * Copyright (c) 2014 MediaTek Inc.
- * Author: Xudong Chen <xudong.chen at mediatek.com>
+ * Author:
+ *   Xudong Chen <xudong.chen at mediatek.com>
+ *   Liguo Zhang <liguo.zhang at 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
@@ -59,6 +61,7 @@
 #define I2C_DMA_START_EN		0x0001
 #define I2C_DMA_INT_FLAG_NONE		0x0000
 #define I2C_DMA_CLR_FLAG		0x0000
+#define I2C_DMA_HARD_RST		0x0002
 
 #define I2C_DEFAULT_SPEED		100000	/* hz */
 #define MAX_FS_MODE_SPEED		400000
@@ -81,6 +84,7 @@ enum DMA_REGS_OFFSET {
 	OFFSET_INT_FLAG = 0x0,
 	OFFSET_INT_EN = 0x04,
 	OFFSET_EN = 0x08,
+	OFFSET_RST = 0x0c,
 	OFFSET_CON = 0x18,
 	OFFSET_TX_MEM_ADDR = 0x1c,
 	OFFSET_RX_MEM_ADDR = 0x20,
@@ -262,6 +266,10 @@ static void mtk_i2c_init_hw(struct mtk_i2c *i2c)
 		      I2C_CONTROL_CLK_EXT_EN | I2C_CONTROL_DMA_EN;
 	writew(control_reg, i2c->base + OFFSET_CONTROL);
 	writew(I2C_DELAY_LEN, i2c->base + OFFSET_DELAY_LEN);
+
+	writel(I2C_DMA_HARD_RST, i2c->pdmabase + OFFSET_RST);
+	udelay(50);
+	writel(I2C_DMA_CLR_FLAG, i2c->pdmabase + OFFSET_RST);
 }
 
 /*
-- 
1.7.9.5



From marc.zyngier at arm.com  Tue Aug  4 05:06:34 2015
From: marc.zyngier at arm.com (Marc Zyngier)
Date: Tue, 04 Aug 2015 13:06:34 +0100
Subject: [PATCH v4 01/10] irqchip / GIC: Add GIC version support in ACPI
 MADT
In-Reply-To: <1438164539-29256-2-git-send-email-hanjun.guo@linaro.org>
References: <1438164539-29256-1-git-send-email-hanjun.guo@linaro.org>
 <1438164539-29256-2-git-send-email-hanjun.guo@linaro.org>
Message-ID: <55C0AACA.9090001@arm.com>

On 29/07/15 11:08, Hanjun Guo wrote:
> There is a field added in ACPI 6.0 MADT table to indicate the
> GIC version, so parse the table to get its value for later use.
> 
> If GIC version presented in MADT is 0, we need to fallback to
> hardware discovery to get the GIC version.
> 
> In ACPI MADT table there is no compatible strings to indicate
> various irqchips and also ACPI doesn't support irqchips which
> are not compatible with ARM GIC spec, so GIC version can be used
> to load different GIC drivers which is needed for the later patch.
> 
> Signed-off-by: Hanjun Guo <hanjun.guo at linaro.org>
> ---
>  arch/arm64/Kconfig                   |   1 +
>  drivers/irqchip/Kconfig              |   3 +
>  drivers/irqchip/Makefile             |   1 +
>  drivers/irqchip/irq-gic-acpi.c       | 109 +++++++++++++++++++++++++++++++++++
>  include/linux/irqchip/arm-gic-acpi.h |   1 +
>  5 files changed, 115 insertions(+)
>  create mode 100644 drivers/irqchip/irq-gic-acpi.c
> 
> diff --git a/arch/arm64/Kconfig b/arch/arm64/Kconfig
> index 318175f..f2ff61f 100644
> --- a/arch/arm64/Kconfig
> +++ b/arch/arm64/Kconfig
> @@ -16,6 +16,7 @@ config ARM64
>  	select ARM_AMBA
>  	select ARM_ARCH_TIMER
>  	select ARM_GIC
> +	select ARM_GIC_ACPI if ACPI
>  	select AUDIT_ARCH_COMPAT_GENERIC
>  	select ARM_GIC_V2M if PCI_MSI
>  	select ARM_GIC_V3
> diff --git a/drivers/irqchip/Kconfig b/drivers/irqchip/Kconfig
> index 120d815..557ec2f 100644
> --- a/drivers/irqchip/Kconfig
> +++ b/drivers/irqchip/Kconfig
> @@ -47,6 +47,9 @@ config ARM_VIC_NR
>  	  The maximum number of VICs available in the system, for
>  	  power management.
>  
> +config ARM_GIC_ACPI
> +	bool
> +
>  config ATMEL_AIC_IRQ
>  	bool
>  	select GENERIC_IRQ_CHIP
> diff --git a/drivers/irqchip/Makefile b/drivers/irqchip/Makefile
> index 11d08c9..383f421 100644
> --- a/drivers/irqchip/Makefile
> +++ b/drivers/irqchip/Makefile
> @@ -23,6 +23,7 @@ obj-$(CONFIG_ARM_GIC)			+= irq-gic.o irq-gic-common.o
>  obj-$(CONFIG_ARM_GIC_V2M)		+= irq-gic-v2m.o
>  obj-$(CONFIG_ARM_GIC_V3)		+= irq-gic-v3.o irq-gic-common.o
>  obj-$(CONFIG_ARM_GIC_V3_ITS)		+= irq-gic-v3-its.o irq-gic-v3-its-pci-msi.o irq-gic-v3-its-platform-msi.o
> +obj-$(CONFIG_ARM_GIC_ACPI)		+= irq-gic-acpi.o
>  obj-$(CONFIG_ARM_NVIC)			+= irq-nvic.o
>  obj-$(CONFIG_ARM_VIC)			+= irq-vic.o
>  obj-$(CONFIG_ATMEL_AIC_IRQ)		+= irq-atmel-aic-common.o irq-atmel-aic.o
> diff --git a/drivers/irqchip/irq-gic-acpi.c b/drivers/irqchip/irq-gic-acpi.c
> new file mode 100644
> index 0000000..6537b43
> --- /dev/null
> +++ b/drivers/irqchip/irq-gic-acpi.c
> @@ -0,0 +1,109 @@
> +/*
> + * ACPI based support for ARM GIC init
> + *
> + * Copyright (C) 2015, Linaro Ltd.
> + * 	Author: Hanjun Guo <hanjun.guo at linaro.org>
> + *
> + * This program is free software; you can redistribute it and/or modify
> + * it under the terms of the GNU General Public License version 2 as
> + * published by the Free Software Foundation.
> + */
> +
> +#define pr_fmt(fmt) "ACPI: GIC: " fmt
> +
> +#include <linux/acpi.h>
> +#include <linux/init.h>
> +#include <linux/irqchip/arm-gic-acpi.h>
> +#include <linux/irqchip/arm-gic-v3.h>
> +
> +/* GIC version presented in MADT GIC distributor structure */
> +static u8 gic_version __initdata = ACPI_MADT_GIC_VERSION_NONE;
> +
> +static phys_addr_t dist_phy_base __initdata;
> +
> +static int __init
> +acpi_gic_parse_distributor(struct acpi_subtable_header *header,
> +			   const unsigned long end)
> +{
> +	struct acpi_madt_generic_distributor *dist;
> +
> +	dist = (struct acpi_madt_generic_distributor *)header;
> +
> +	if (BAD_MADT_ENTRY(dist, end))
> +		return -EINVAL;
> +
> +	gic_version = dist->version;
> +	dist_phy_base = dist->base_address;
> +	return 0;
> +}
> +
> +static int __init
> +match_gic_redist(struct acpi_subtable_header *header, const unsigned long end)
> +{
> +	return 0;
> +}
> +
> +static bool __init acpi_gic_redist_is_present(void)
> +{
> +	int count;
> +
> +	/* scan MADT table to find if we have redistributor entries */
> +	count  =  acpi_table_parse_madt(ACPI_MADT_TYPE_GENERIC_REDISTRIBUTOR,
> +					match_gic_redist, 0);
> +
> +	/* that's true if we have at least one GIC redistributor entry */
> +	return count > 0;
> +}
> +
> +static int __init acpi_gic_version_init(void)
> +{
> +	int count;
> +	u32 reg;
> +	void __iomem *dist_base;
> +
> +	count = acpi_table_parse_madt(ACPI_MADT_TYPE_GENERIC_DISTRIBUTOR,
> +				      acpi_gic_parse_distributor, 0);
> +
> +	if (count <= 0) {
> +		pr_err("No valid GIC distributor entry exists\n");
> +		return -ENODEV;
> +	}
> +
> +	if (gic_version >= ACPI_MADT_GIC_VERSION_RESERVED) {
> +		pr_err("Invalid GIC version %d in MADT\n", gic_version);
> +		return -EINVAL;
> +	}
> +
> +	/*
> +	 * when the GIC version is 0, we fallback to hardware discovery.
> +	 * this is also needed to keep compatiable with ACPI 5.1,
> +	 * which has no gic_version field in distributor structure and
> +	 * reserved as 0.
> +	 *
> +	 * For hardware discovery, the offset for GICv1/2 and GICv3/4 to
> +	 * get the GIC version is different (0xFE8 for GICv1/2 and 0xFFE8
> +	 * for GICv3/4), so we need to handle it separately.
> +	 */
> +	if (gic_version	== ACPI_MADT_GIC_VERSION_NONE) {
> +		/* it's GICv3/v4 if redistributor is present */
> +		if (acpi_gic_redist_is_present()) {
> +			dist_base = ioremap(dist_phy_base,
> +					    ACPI_GICV3_DIST_MEM_SIZE);
> +			if (!dist_base)
> +				return -ENOMEM;
> +
> +			reg = readl_relaxed(dist_base + GICD_PIDR2) &
> +					    GIC_PIDR2_ARCH_MASK;
> +			if (reg == GIC_PIDR2_ARCH_GICv3)
> +				gic_version = ACPI_MADT_GIC_VERSION_V3;
> +			else
> +				gic_version = ACPI_MADT_GIC_VERSION_V4;

Frankly, why should we care? If there is no redistributor, this is a V2.
If there are redistributors, then it is a V3/V4, and it shouldn't matter
which one this is as the GICv3 driver can find out all by itself. Also,
the GICv4 feature only matter for KVM, which can probe this on its own.

> +
> +			iounmap(dist_base);
> +		} else {
> +			gic_version = ACPI_MADT_GIC_VERSION_V2;
> +		}
> +	}
> +
> +	return 0;
> +}
> diff --git a/include/linux/irqchip/arm-gic-acpi.h b/include/linux/irqchip/arm-gic-acpi.h
> index de3419e..13bc676 100644
> --- a/include/linux/irqchip/arm-gic-acpi.h
> +++ b/include/linux/irqchip/arm-gic-acpi.h
> @@ -19,6 +19,7 @@
>   */
>  #define ACPI_GICV2_DIST_MEM_SIZE	(SZ_4K)
>  #define ACPI_GIC_CPU_IF_MEM_SIZE	(SZ_8K)
> +#define ACPI_GICV3_DIST_MEM_SIZE	(SZ_64K)
>  
>  struct acpi_table_header;
>  
> 

Thanks,

	M.
-- 
Jazz is not dead. It just smells funny...


From christoffer.dall at linaro.org  Tue Aug  4 05:14:11 2015
From: christoffer.dall at linaro.org (Christoffer Dall)
Date: Tue, 4 Aug 2015 14:14:11 +0200
Subject: [PATCH v2 04/10] KVM: arm/arm64: vgic: Allow HW irq to be
 encoded in LR
In-Reply-To: <55AE759C.7090809@arm.com>
References: <1436378202-20224-1-git-send-email-marc.zyngier@arm.com>
 <1436378202-20224-5-git-send-email-marc.zyngier@arm.com>
 <20150717195008.GE14024@cbox> <55AE759C.7090809@arm.com>
Message-ID: <20150804121411.GA29453@cbox>

On Tue, Jul 21, 2015 at 05:38:52PM +0100, Marc Zyngier wrote:
> On 17/07/15 20:50, Christoffer Dall wrote:
> > On Wed, Jul 08, 2015 at 06:56:36PM +0100, Marc Zyngier wrote:
> >> Now that struct vgic_lr supports the LR_HW bit and carries a hwirq
> >> field, we can encode that information into the list registers.
> >>
> >> This patch provides implementations for both GICv2 and GICv3.
> >>
> >> Signed-off-by: Marc Zyngier <marc.zyngier at arm.com>
> >> ---
> >>  include/linux/irqchip/arm-gic-v3.h |  3 +++
> >>  include/linux/irqchip/arm-gic.h    |  3 ++-
> >>  virt/kvm/arm/vgic-v2.c             | 16 +++++++++++++++-
> >>  virt/kvm/arm/vgic-v3.c             | 21 ++++++++++++++++++---
> >>  4 files changed, 38 insertions(+), 5 deletions(-)
> >>
> >> diff --git a/include/linux/irqchip/arm-gic-v3.h b/include/linux/irqchip/arm-gic-v3.h
> >> index ffbc034..cf637d6 100644
> >> --- a/include/linux/irqchip/arm-gic-v3.h
> >> +++ b/include/linux/irqchip/arm-gic-v3.h
> >> @@ -268,9 +268,12 @@
> >>  
> >>  #define ICH_LR_EOI			(1UL << 41)
> >>  #define ICH_LR_GROUP			(1UL << 60)
> >> +#define ICH_LR_HW			(1UL << 61)
> >>  #define ICH_LR_STATE			(3UL << 62)
> >>  #define ICH_LR_PENDING_BIT		(1UL << 62)
> >>  #define ICH_LR_ACTIVE_BIT		(1UL << 63)
> >> +#define ICH_LR_PHYS_ID_SHIFT		32
> >> +#define ICH_LR_PHYS_ID_MASK		(0x3ffUL << ICH_LR_PHYS_ID_SHIFT)
> >>  
> >>  #define ICH_MISR_EOI			(1 << 0)
> >>  #define ICH_MISR_U			(1 << 1)
> >> diff --git a/include/linux/irqchip/arm-gic.h b/include/linux/irqchip/arm-gic.h
> >> index 9de976b..ca88dad 100644
> >> --- a/include/linux/irqchip/arm-gic.h
> >> +++ b/include/linux/irqchip/arm-gic.h
> >> @@ -71,11 +71,12 @@
> >>  
> >>  #define GICH_LR_VIRTUALID		(0x3ff << 0)
> >>  #define GICH_LR_PHYSID_CPUID_SHIFT	(10)
> >> -#define GICH_LR_PHYSID_CPUID		(7 << GICH_LR_PHYSID_CPUID_SHIFT)
> >> +#define GICH_LR_PHYSID_CPUID		(0x3ff << GICH_LR_PHYSID_CPUID_SHIFT)
> >>  #define GICH_LR_STATE			(3 << 28)
> >>  #define GICH_LR_PENDING_BIT		(1 << 28)
> >>  #define GICH_LR_ACTIVE_BIT		(1 << 29)
> >>  #define GICH_LR_EOI			(1 << 19)
> >> +#define GICH_LR_HW			(1 << 31)
> >>  
> >>  #define GICH_VMCR_CTRL_SHIFT		0
> >>  #define GICH_VMCR_CTRL_MASK		(0x21f << GICH_VMCR_CTRL_SHIFT)
> >> diff --git a/virt/kvm/arm/vgic-v2.c b/virt/kvm/arm/vgic-v2.c
> >> index f9b9c7c..8d7b04d 100644
> >> --- a/virt/kvm/arm/vgic-v2.c
> >> +++ b/virt/kvm/arm/vgic-v2.c
> >> @@ -48,6 +48,10 @@ static struct vgic_lr vgic_v2_get_lr(const struct kvm_vcpu *vcpu, int lr)
> >>  		lr_desc.state |= LR_STATE_ACTIVE;
> >>  	if (val & GICH_LR_EOI)
> >>  		lr_desc.state |= LR_EOI_INT;
> >> +	if (val & GICH_LR_HW) {
> >> +		lr_desc.state |= LR_HW;
> >> +		lr_desc.hwirq = (val & GICH_LR_PHYSID_CPUID) >> GICH_LR_PHYSID_CPUID_SHIFT;
> >> +	}
> >>  
> >>  	return lr_desc;
> >>  }
> >> @@ -55,7 +59,9 @@ static struct vgic_lr vgic_v2_get_lr(const struct kvm_vcpu *vcpu, int lr)
> >>  static void vgic_v2_set_lr(struct kvm_vcpu *vcpu, int lr,
> >>  			   struct vgic_lr lr_desc)
> >>  {
> >> -	u32 lr_val = (lr_desc.source << GICH_LR_PHYSID_CPUID_SHIFT) | lr_desc.irq;
> >> +	u32 lr_val;
> >> +
> >> +	lr_val = lr_desc.irq;
> >>  
> >>  	if (lr_desc.state & LR_STATE_PENDING)
> >>  		lr_val |= GICH_LR_PENDING_BIT;
> >> @@ -64,6 +70,14 @@ static void vgic_v2_set_lr(struct kvm_vcpu *vcpu, int lr,
> >>  	if (lr_desc.state & LR_EOI_INT)
> >>  		lr_val |= GICH_LR_EOI;
> >>  
> >> +	if (lr_desc.state & LR_HW) {
> >> +		lr_val |= GICH_LR_HW;
> >> +		lr_val |= (u32)lr_desc.hwirq << GICH_LR_PHYSID_CPUID_SHIFT;
> >> +	}
> >> +
> >> +	if (lr_desc.irq < VGIC_NR_SGIS)
> >> +		lr_val |= (lr_desc.source << GICH_LR_PHYSID_CPUID_SHIFT);
> >> +
> >>  	vcpu->arch.vgic_cpu.vgic_v2.vgic_lr[lr] = lr_val;
> >>  }
> >>  
> >> diff --git a/virt/kvm/arm/vgic-v3.c b/virt/kvm/arm/vgic-v3.c
> >> index dff0602..afbf925 100644
> >> --- a/virt/kvm/arm/vgic-v3.c
> >> +++ b/virt/kvm/arm/vgic-v3.c
> >> @@ -67,6 +67,10 @@ static struct vgic_lr vgic_v3_get_lr(const struct kvm_vcpu *vcpu, int lr)
> >>  		lr_desc.state |= LR_STATE_ACTIVE;
> >>  	if (val & ICH_LR_EOI)
> >>  		lr_desc.state |= LR_EOI_INT;
> >> +	if (val & ICH_LR_HW) {
> >> +		lr_desc.state |= LR_HW;
> >> +		lr_desc.hwirq = (val >> ICH_LR_PHYS_ID_SHIFT) & GENMASK(9, 0);
> >> +	}
> >>  
> >>  	return lr_desc;
> >>  }
> >> @@ -84,10 +88,17 @@ static void vgic_v3_set_lr(struct kvm_vcpu *vcpu, int lr,
> >>  	 * Eventually we want to make this configurable, so we may revisit
> >>  	 * this in the future.
> >>  	 */
> >> -	if (vcpu->kvm->arch.vgic.vgic_model == KVM_DEV_TYPE_ARM_VGIC_V3)
> >> +	switch (vcpu->kvm->arch.vgic.vgic_model) {
> >> +	case KVM_DEV_TYPE_ARM_VGIC_V3:
> >>  		lr_val |= ICH_LR_GROUP;
> >> -	else
> >> -		lr_val |= (u32)lr_desc.source << GICH_LR_PHYSID_CPUID_SHIFT;
> >> +		break;
> >> +	case  KVM_DEV_TYPE_ARM_VGIC_V2:
> >> +		if (lr_desc.irq < VGIC_NR_SGIS)
> >> +			lr_val |= (u32)lr_desc.source << GICH_LR_PHYSID_CPUID_SHIFT;
> > 
> > I forget how this works: Why are we mixing GICH_LR_ stuff with ICH_LR_
> > in the same function?  Aren't we always accessing these registers via
> > the system registers interface from the hypervisor control point of
> > view, regardless of which GIC version the guest sees?
> 
> That's a bit odd indeed, but there's a small trick here:
> 
> - GICv2 has the CPUID as part of the PHYSID field.
> - GICv3 "native" has no CPUID
> - GICv3, when used with a GICv2 guest, puts CPUID as part of the the
> bottom 32bit of the ICH_LRn_EL2 register, which happens to be the VIRTID.
> 
> And that VIRTID, when used with a GICv2 guest, actually contains most of
> the GICH_LR fields. Crucially, CPUID is located at VIRTID[12:10], which
> happens to be GICH_LRn[12:10], exactly where it is on a GICv2.
> 
> Confusing? You bet. Oh, and that subtle difference seems to have been
> removed from the architecture spec. Time to file a bug report.
> 
> > I guess my question here is: Why should this not be
> > ICH_LR_PHYSID_CORE_SHIFT?
> 
> No, because as explained above, the CPUID doesn't belong to PHYSID...
> 
I get it.  Thanks for explanation, you can point me here when I'm going
to ask you again in a year or so.

-Christoffer


From patrice.chotard at st.com  Tue Aug  4 05:23:44 2015
From: patrice.chotard at st.com (Patrice Chotard)
Date: Tue, 4 Aug 2015 14:23:44 +0200
Subject: [PATCH 4/9] usb: host: ehci-st: Simplify return statement
In-Reply-To: <29a173be5ace786d064ae14c02324fee42fee06c.1438678566.git.skarajga@visteon.com>
References: <cover.1438678566.git.skarajga@visteon.com>
 <29a173be5ace786d064ae14c02324fee42fee06c.1438678566.git.skarajga@visteon.com>
Message-ID: <55C0AED0.7080303@st.com>

Hi

On 08/04/2015 11:10 AM, Karajgaonkar, Saurabh (S.) wrote:
> From: Saurabh Karajgaonkar <skarajga at visteon.com>
>
> Replace redundant variable use in return statement.
>
> Signed-off-by: Saurabh Karajgaonkar <skarajga at visteon.com>
> ---
>   drivers/usb/host/ehci-st.c | 7 +------
>   1 file changed, 1 insertion(+), 6 deletions(-)
>
> diff --git a/drivers/usb/host/ehci-st.c b/drivers/usb/host/ehci-st.c
> index 7e4bd39..b7c5cfa 100644
> --- a/drivers/usb/host/ehci-st.c
> +++ b/drivers/usb/host/ehci-st.c
> @@ -54,7 +54,6 @@ static int st_ehci_platform_reset(struct usb_hcd *hcd)
>   	struct platform_device *pdev = to_platform_device(hcd->self.controller);
>   	struct usb_ehci_pdata *pdata = dev_get_platdata(&pdev->dev);
>   	struct ehci_hcd *ehci = hcd_to_ehci(hcd);
> -	int retval;
>   	u32 threshold;
>   
>   	/* Set EHCI packet buffer IN/OUT threshold to 128 bytes */
> @@ -62,11 +61,7 @@ static int st_ehci_platform_reset(struct usb_hcd *hcd)
>   	writel(threshold, hcd->regs + AHB2STBUS_INSREG01);
>   
>   	ehci->caps = hcd->regs + pdata->caps_offset;
> -	retval = ehci_setup(hcd);
> -	if (retval)
> -		return retval;
> -
> -	return 0;
> +	return ehci_setup(hcd);
>   }
>   
>   static int st_ehci_platform_power_on(struct platform_device *dev)


Acked-by: Patrice Chotard <patrice.chotard at st.com>

Thanks

Patrice


From christoffer.dall at linaro.org  Tue Aug  4 05:26:01 2015
From: christoffer.dall at linaro.org (Christoffer Dall)
Date: Tue, 4 Aug 2015 14:26:01 +0200
Subject: [PATCH v2 10/10] KVM: arm/arm64: vgic: Allow non-shared device
 HW interrupts
In-Reply-To: <55AE88E9.1070802@arm.com>
References: <1436378202-20224-1-git-send-email-marc.zyngier@arm.com>
 <1436378202-20224-11-git-send-email-marc.zyngier@arm.com>
 <20150717221521.GH14024@cbox> <55AE88E9.1070802@arm.com>
Message-ID: <20150804122601.GB29453@cbox>

On Tue, Jul 21, 2015 at 07:01:13PM +0100, Marc Zyngier wrote:
> On 17/07/15 23:15, Christoffer Dall wrote:
> > On Wed, Jul 08, 2015 at 06:56:42PM +0100, Marc Zyngier wrote:
> >> So far, the only use of the HW interrupt facility is the timer,
> >> implying that the active state is context-switched for each vcpu,
> >> as the device is is shared across all vcpus.
> >>
> >> This does not work for a device that has been assigned to a VM,
> >> as the guest is entierely in control of that device (the HW is
> >> not shared). In that case, it makes sense to bypass the whole
> >> active state switchint, and only track the deactivation of the
> > 
> > switching
> > 
> >> interrupt.
> >>
> >> Signed-off-by: Marc Zyngier <marc.zyngier at arm.com>
> >> ---
> >>  include/kvm/arm_vgic.h    |  5 ++--
> >>  virt/kvm/arm/arch_timer.c |  2 +-
> >>  virt/kvm/arm/vgic.c       | 62 ++++++++++++++++++++++++++++++++++++-----------
> >>  3 files changed, 52 insertions(+), 17 deletions(-)
> >>
> >> diff --git a/include/kvm/arm_vgic.h b/include/kvm/arm_vgic.h
> >> index 9fd4023..31c987a 100644
> >> --- a/include/kvm/arm_vgic.h
> >> +++ b/include/kvm/arm_vgic.h
> >> @@ -163,7 +163,8 @@ struct irq_phys_map {
> >>  	u32			virt_irq;
> >>  	u32			phys_irq;
> >>  	u32			irq;
> >> -	bool			active;
> >> +	bool			shared;
> >> +	bool			active; /* Only valid if shared */
> >>  };
> >>  
> >>  struct irq_phys_map_entry {
> >> @@ -354,7 +355,7 @@ void vgic_v3_dispatch_sgi(struct kvm_vcpu *vcpu, u64 reg);
> >>  int kvm_vgic_vcpu_pending_irq(struct kvm_vcpu *vcpu);
> >>  int kvm_vgic_vcpu_active_irq(struct kvm_vcpu *vcpu);
> >>  struct irq_phys_map *vgic_map_phys_irq(struct kvm_vcpu *vcpu,
> >> -				       int virt_irq, int irq);
> >> +				       int virt_irq, int irq, bool shared);
> >>  int vgic_unmap_phys_irq(struct kvm_vcpu *vcpu, struct irq_phys_map *map);
> >>  bool vgic_get_phys_irq_active(struct irq_phys_map *map);
> >>  void vgic_set_phys_irq_active(struct irq_phys_map *map, bool active);
> >> diff --git a/virt/kvm/arm/arch_timer.c b/virt/kvm/arm/arch_timer.c
> >> index b9fff78..9544d79 100644
> >> --- a/virt/kvm/arm/arch_timer.c
> >> +++ b/virt/kvm/arm/arch_timer.c
> >> @@ -202,7 +202,7 @@ void kvm_timer_vcpu_reset(struct kvm_vcpu *vcpu,
> >>  	 * Tell the VGIC that the virtual interrupt is tied to a
> >>  	 * physical interrupt. We do that once per VCPU.
> >>  	 */
> >> -	timer->map = vgic_map_phys_irq(vcpu, irq->irq, host_vtimer_irq);
> >> +	timer->map = vgic_map_phys_irq(vcpu, irq->irq, host_vtimer_irq, true);
> >>  	WARN_ON(!timer->map);
> >>  }
> >>  
> >> diff --git a/virt/kvm/arm/vgic.c b/virt/kvm/arm/vgic.c
> >> index 39f9479..3585bb0 100644
> >> --- a/virt/kvm/arm/vgic.c
> >> +++ b/virt/kvm/arm/vgic.c
> >> @@ -1123,18 +1123,21 @@ static void vgic_queue_irq_to_lr(struct kvm_vcpu *vcpu, int irq,
> >>  		map = vgic_irq_map_search(vcpu, irq);
> >>  
> >>  		if (map) {
> >> -			int ret;
> >> -
> >> -			BUG_ON(!map->active);
> >>  			vlr.hwirq = map->phys_irq;
> >>  			vlr.state |= LR_HW;
> >>  			vlr.state &= ~LR_EOI_INT;
> >>  
> >> -			ret = irq_set_irqchip_state(map->irq,
> >> -						    IRQCHIP_STATE_ACTIVE,
> >> -						    true);
> >>  			vgic_irq_set_queued(vcpu, irq);
> >> -			WARN_ON(ret);
> >> +
> >> +			if (map->shared) {
> >> +				int ret;
> >> +
> >> +				BUG_ON(!map->active);
> >> +				ret = irq_set_irqchip_state(map->irq,
> >> +							    IRQCHIP_STATE_ACTIVE,
> >> +							    true);
> >> +				WARN_ON(ret);
> > 
> > do we have any other example of a shared device or is this really simply
> > because the timer hardware is fscking strangely tied to the gic and is a
> > total one-off?
> 
> I don't think of it as a one-off. PMUs could very well be in the same
> category.
> 
> > In the latter case, would it be cleaner to drop this notion of a shared
> > device entirely and put all this logic in the arch timer code instead?
> 
> My initial implementation did exactly that (hence the cut-n-paste crap
> you spotted in patch #6). It wasn't bad, but it did put a lot of GIC
> knowledge inside the timer code, and a few callbacks too many between
> the two subsystems.
> 
> >> +			}
> >>  		}
> >>  	}
> >>  
> >> @@ -1366,21 +1369,37 @@ static bool vgic_process_maintenance(struct kvm_vcpu *vcpu)
> >>  static int vgic_sync_hwirq(struct kvm_vcpu *vcpu, struct vgic_lr vlr)
> >>  {
> >>  	struct irq_phys_map *map;
> >> +	bool active;
> >>  	int ret;
> >>  
> >>  	if (!(vlr.state & LR_HW))
> >>  		return 0;
> >>  
> >>  	map = vgic_irq_map_search(vcpu, vlr.irq);
> >> -	BUG_ON(!map || !map->active);
> >> +	BUG_ON(!map);
> >> +	BUG_ON(map->shared && !map->active);
> >>  
> >>  	ret = irq_get_irqchip_state(map->irq,
> >>  				    IRQCHIP_STATE_ACTIVE,
> >> -				    &map->active);
> >> +				    &active);
> >>  
> >>  	WARN_ON(ret);
> >>  
> >> -	if (map->active) {
> >> +	/*
> >> +	 * For a non-shared interrupt, we have to catter for two
> > 
> > s/catter/cater/ ?
> 
> Yup.
> 
> >> +	 * possible deactivation conditions
> > 
> > conditions:
> > 
> >> +	 *
> >> +	 * - the interrupt is now inactive
> >> +	 * - the interrupt is still active, but is flagged as not
> >> +	 *   queued, indicating another interrupt has fired before we
> >> +	 *   could observe the deactivate.
> > 
> > are these physical or virtual interrupts we are talking about?  I assume
> > virtual, but it would be good to be specific.  It's not like we're going
> > to remember any of this in a little bit.
> 
> There is a massive ambiguity here. It should read:
> - the physical interrupt is now inactive (EOIed from the guest)
> - the physical interrupt is still active, but its virtual counterpart is
> flagged as "not queued", indicating another interrupt has fired between
> the EOI and the guest exit.
> 
> >> +	 */
> >> +	if (!map->shared)
> >> +		return !active || !vgic_irq_is_queued(vcpu, vlr.irq);
> > 
> > if the second part of the disjunction returns true, doesn't this mean
> > we can potentially write the active+pending state in the LR for a HW
> > interrupt, which is not allowed?
> 
> I don't think so. If the physical interrupt has fired, it is because it
> has been EOIed (hence deactivated) first (the active state would
> otherwise prevent it from firing).
> 
> >> +
> >> +	map->active = active;
> >> +
> >> +	if (active) {
> > 
> > should you be doing this for a non-shared interrupt?
> 
> No. A non-shared interrupt is only dealt with by a single VM, so there
> is no need to clear its state. That would actually completely confuse
> both the device and the VM if you did, because you could now inject a
> new interrupt while the previous one is still in progress. Mayhem follows...
> 
> >>  		ret = irq_set_irqchip_state(map->irq,
> >>  					    IRQCHIP_STATE_ACTIVE,
> >>  					    false);
> >> @@ -1523,6 +1542,7 @@ static int vgic_update_irq_pending(struct kvm *kvm, int cpuid,
> >>  	int edge_triggered, level_triggered;
> >>  	int enabled;
> >>  	bool ret = true, can_inject = true;
> >> +	struct irq_phys_map *map;
> >>  
> >>  	spin_lock(&dist->lock);
> >>  
> >> @@ -1569,6 +1589,18 @@ static int vgic_update_irq_pending(struct kvm *kvm, int cpuid,
> >>  		goto out;
> >>  	}
> >>  
> >> +	map = vgic_irq_map_search(vcpu, irq_num);
> >> +	if (map && !map->shared) {
> >> +		/*
> >> +		 * We are told to inject a HW irq, so we have to trust
> >> +		 * the caller that the previous one has been EOIed,
> >> +		 * and that a new one is now active. Clearing the
> >> +		 * queued state will have the effect of making it
> >> +		 * sample-able again.
> >> +		 */
> >> +		vgic_irq_clear_queued(vcpu, irq_num);
> > 
> > see my question above about active+pending
> 
> I hope I convinced you above. I realize there is one thing missing
> though. Userspace shouldn't be allowed to inject a mapped interrupt.
> Ever. I'll fix that.
> 

I think I get it; I think the confusion comes from the fact that all
this depends on the non-shared forwareded interrupts must be configured
with separate deactivate and priority drop (correct?), and since this
support is not in nor is a requirement for this series, it's kind of
hard to understand.

I noticed now that you had in the cover letter that this patch wasn't
intended for merging, but I didn't before...

> >> +	}
> >> +
> >>  	if (!vgic_can_sample_irq(vcpu, irq_num)) {
> >>  		/*
> >>  		 * Level interrupt in progress, will be picked up
> >> @@ -1662,7 +1694,7 @@ static struct list_head *vgic_get_irq_phys_map(struct kvm_vcpu *vcpu,
> >>  }
> >>  
> >>  struct irq_phys_map *vgic_map_phys_irq(struct kvm_vcpu *vcpu,
> >> -				       int virt_irq, int irq)
> >> +				       int virt_irq, int irq, bool shared)
> >>  {
> >>  	struct vgic_dist *dist = &vcpu->kvm->arch.vgic;
> >>  	struct list_head *root = vgic_get_irq_phys_map(vcpu, virt_irq);
> >> @@ -1691,7 +1723,8 @@ struct irq_phys_map *vgic_map_phys_irq(struct kvm_vcpu *vcpu,
> >>  	if (map) {
> >>  		/* Make sure this mapping matches */
> >>  		if (map->phys_irq != phys_irq	||
> >> -		    map->irq      != irq)
> >> +		    map->irq      != irq	||
> >> +		    map->shared   != shared)
> > 
> > this really feels like a BUG() - if we have an existing mapping for the
> > same virtual IRQ, but it's shared in one case and not shared in the
> > other?  Shouldn we even allow the caller to get this far?
> 
> How early do you want to detect it? All we can do is tell the caller to
> bugger off by returning an error (we return NULL at the moment, meaning
> that the caller doesn't get a mapping at all).
> 

fair enough, I hope the caller then has a BUG_ON(mapping == NULL).

-Christoffer


From marc.zyngier at arm.com  Tue Aug  4 05:27:14 2015
From: marc.zyngier at arm.com (Marc Zyngier)
Date: Tue, 04 Aug 2015 13:27:14 +0100
Subject: [PATCH v4 02/10] ACPI / irqchip: Add self-probe infrastructure
 to initialize IRQ controller
In-Reply-To: <1438164539-29256-3-git-send-email-hanjun.guo@linaro.org>
References: <1438164539-29256-1-git-send-email-hanjun.guo@linaro.org>
 <1438164539-29256-3-git-send-email-hanjun.guo@linaro.org>
Message-ID: <55C0AFA2.8050704@arm.com>

On 29/07/15 11:08, Hanjun Guo wrote:
> This self-probe infrastructure works in the similar way as OF,
> but there is some different in the mechanism:
> 
> For DT, the init fn will be called once it finds compatible strings
> in DT,  but for ACPI, we init irqchips by static tables, and in
> static ACPI tables, there are no compatible strings to indicate
> irqchips, but thanks to the GIC version presented in ACPI table,
> we can call the corresponding GIC drivers matching the GIC version
> with this framework.
> 
> This mechanism can also be used for clock declare and may also works
> on x86 for some table parsing too.
> 
> This patch is based on Tomasz Nowicki <tomasz.nowicki at linaro.org>'s
> work.
> 
> Signed-off-by: Hanjun Guo <hanjun.guo at linaro.org>
> ---
>  drivers/irqchip/irq-gic-acpi.c    | 33 +++++++++++++++++++++++++++++++++
>  include/asm-generic/vmlinux.lds.h | 13 +++++++++++++
>  include/linux/acpi.h              | 16 ++++++++++++++++
>  include/linux/irqchip.h           | 13 +++++++++++++
>  include/linux/mod_devicetable.h   |  8 ++++++++
>  5 files changed, 83 insertions(+)
> 
> diff --git a/drivers/irqchip/irq-gic-acpi.c b/drivers/irqchip/irq-gic-acpi.c
> index 6537b43..011468d 100644
> --- a/drivers/irqchip/irq-gic-acpi.c
> +++ b/drivers/irqchip/irq-gic-acpi.c
> @@ -107,3 +107,36 @@ static int __init acpi_gic_version_init(void)
>  
>  	return 0;
>  }
> +
> +/*
> + * This special acpi_table_id is the sentinel at the end of the
> + * acpi_table_id[] array of all irqchips. It is automatically placed at
> + * the end of the array by the linker, thanks to being part of a
> + * special section.
> + */
> +static const struct acpi_table_id
> +irqchip_acpi_match_end __used __section(__irqchip_acpi_table_end);

What is this thing for? Nobody refers to it (I know
drivers/irqchip/irqchip.c has a similar thing, but that's not enough a
reason...).

> +
> +extern struct acpi_table_id __irqchip_acpi_table[];
> +
> +void __init acpi_irqchip_init(void)
> +{
> +	struct acpi_table_id *id;
> +
> +	if (acpi_disabled)
> +		return;
> +
> +	if (acpi_gic_version_init())
> +		return;

This is the only place where we need the version, right? So just get
acpi_gic_version_init to return the version number, and loose the global
variable.

> +
> +	/* scan the irqchip table to match the GIC version and its driver */
> +	for (id = __irqchip_acpi_table; id->id[0]; id++) {
> +		if (gic_version == (u8)id->driver_data) {
> +			acpi_table_parse(id->id,
> +					 (acpi_tbl_table_handler)id->handler);
> +			return;
> +		}
> +	}
> +
> +	pr_err("No matched driver GIC version %d\n", gic_version);
> +}
> diff --git a/include/asm-generic/vmlinux.lds.h b/include/asm-generic/vmlinux.lds.h
> index 8bd374d..625776c 100644
> --- a/include/asm-generic/vmlinux.lds.h
> +++ b/include/asm-generic/vmlinux.lds.h
> @@ -181,6 +181,18 @@
>  #define CPUIDLE_METHOD_OF_TABLES() OF_TABLE(CONFIG_CPU_IDLE, cpuidle_method)
>  #define EARLYCON_OF_TABLES()	OF_TABLE(CONFIG_SERIAL_EARLYCON, earlycon)
>  
> +#ifdef CONFIG_ACPI
> +#define ACPI_TABLE(name)						\
> +	. = ALIGN(8);							\
> +	VMLINUX_SYMBOL(__##name##_acpi_table) = .;			\
> +	*(__##name##_acpi_table)					\
> +	*(__##name##_acpi_table_end)
> +
> +#define IRQCHIP_ACPI_MATCH_TABLE()	ACPI_TABLE(irqchip)
> +#else
> +#define IRQCHIP_ACPI_MATCH_TABLE()
> +#endif
> +
>  #define KERNEL_DTB()							\
>  	STRUCT_ALIGN();							\
>  	VMLINUX_SYMBOL(__dtb_start) = .;				\
> @@ -516,6 +528,7 @@
>  	CPUIDLE_METHOD_OF_TABLES()					\
>  	KERNEL_DTB()							\
>  	IRQCHIP_OF_MATCH_TABLE()					\
> +	IRQCHIP_ACPI_MATCH_TABLE()					\
>  	EARLYCON_TABLE()						\
>  	EARLYCON_OF_TABLES()
>  
> diff --git a/include/linux/acpi.h b/include/linux/acpi.h
> index 0820cb1..04dd0bb 100644
> --- a/include/linux/acpi.h
> +++ b/include/linux/acpi.h
> @@ -829,4 +829,20 @@ static inline struct acpi_device *acpi_get_next_child(struct device *dev,
>  
>  #endif
>  
> +#ifdef CONFIG_ACPI
> +#define ACPI_DECLARE(table, name, table_id, data, fn)			\
> +	static const struct acpi_table_id __acpi_table_##name		\
> +		__used __section(__##table##_acpi_table)		\
> +		 = { .id = table_id,					\
> +		     .handler = (void *)fn,				\
> +		     .driver_data = data }
> +#else
> +#define ACPI_DECLARE(table, name, table_id, data, fn)			\
> +	static const struct acpi_table_id __acpi_table_##name		\
> +		__attribute__((unused))					\
> +		 = { .id = table_id,					\
> +		     .handler = (void *)fn,				\
> +		     .driver_data = data }
> +#endif
> +
>  #endif	/*_LINUX_ACPI_H*/
> diff --git a/include/linux/irqchip.h b/include/linux/irqchip.h
> index 6388873..6b66d3e 100644
> --- a/include/linux/irqchip.h
> +++ b/include/linux/irqchip.h
> @@ -11,6 +11,7 @@
>  #ifndef _LINUX_IRQCHIP_H
>  #define _LINUX_IRQCHIP_H
>  
> +#include <linux/acpi.h>
>  #include <linux/of.h>
>  
>  /*
> @@ -25,6 +26,18 @@
>   */
>  #define IRQCHIP_DECLARE(name, compat, fn) OF_DECLARE_2(irqchip, name, compat, fn)
>  
> +/*
> + * This macro must be used by the different ARM GIC drivers to declare
> + * the association between their version and their initialization function.
> + *
> + * @name: name that must be unique accross all IRQCHIP_ACPI_DECLARE of the
> + * same file.
> + * @gic_version: version of GIC
> + * @fn: initialization function
> + */
> +#define IRQCHIP_ACPI_DECLARE(name, gic_version, fn)	\
> +	ACPI_DECLARE(irqchip, name, ACPI_SIG_MADT, gic_version, fn)

I don't think this is the right approach. The MADT table has a *huge*
number of possible subtables, and none of them is matched by the GIC
version.

What you *really* want is MADT -> GICD -> GIC type. Your ACPI_DECLARE
macro doesn't reflect this at all (you've basically cloned OF, and
that's clearly not good enough).

This probably require an intermediate matching function, ending up with
something like:

#define IRQCHIP_ACPI_DECLARE(name, subtable, version, fn) \
	ACPI_DECLARE(irqchip, name, ACPI_SIG_MADT, match_madt_subtable,\
		subtable, version, fn)

where match_madt_subtable is going to check that a given subtable is
really suitable for a given irqchip. None of that should be GIC
specific, really.

> +
>  #ifdef CONFIG_IRQCHIP
>  void irqchip_init(void);
>  #else
> diff --git a/include/linux/mod_devicetable.h b/include/linux/mod_devicetable.h
> index 34f25b7..105be1f 100644
> --- a/include/linux/mod_devicetable.h
> +++ b/include/linux/mod_devicetable.h
> @@ -193,6 +193,14 @@ struct acpi_device_id {
>  	__u32 cls_msk;
>  };
>  
> +#define ACPI_TABLE_ID_LEN	5
> +
> +struct acpi_table_id {
> +	__u8 id[ACPI_TABLE_ID_LEN];
> +	const void *handler;
> +	kernel_ulong_t driver_data;
> +};
> +
>  #define PNP_ID_LEN	8
>  #define PNP_MAX_DEVICES	8
>  
> 

Thanks,

	M.
-- 
Jazz is not dead. It just smells funny...


From geert+renesas at glider.be  Tue Aug  4 05:28:17 2015
From: geert+renesas at glider.be (Geert Uytterhoeven)
Date: Tue,  4 Aug 2015 14:28:17 +0200
Subject: [PATCH v4 16/16] ARM: shmobile: R-Mobile: Use CPG/MSTP Clock Domain
 attach/detach helpers
In-Reply-To: <1438691297-29235-1-git-send-email-geert+renesas@glider.be>
References: <1438691297-29235-1-git-send-email-geert+renesas@glider.be>
Message-ID: <1438691297-29235-17-git-send-email-geert+renesas@glider.be>

The R-Mobile PM Domain driver manages both power domains and a clock
domain.

The clock domain part is very similar to the CPG/MSTP Clock Domain,
which is used on shmobile SoCs without device power domains, except for
the way how clocks suitable for power management are selected:
  - The former uses the first clock tied to the device through the NULL
    con_id, which is a relic from the legacy pm_clk_notifier-based
    method in drivers/sh/pm_runtime.c,
  - The latter looks for suitable clocks in DT, which is more
    future-proof.

All platforms using this driver are now supported in DT-based ARM
multi-platform builds only, hence switch to using the CPG/MSTP Clock
Domain helpers.

Signed-off-by: Geert Uytterhoeven <geert+renesas at glider.be>
Reviewed-by: Ulf Hansson <ulf.hansson at linaro.org>
---
v4:
  - Add Reviewed-by,

v3:
  - Drop -legacy support, hence this patch depends on r8a7740/sh73a0
    legacy removal,
  - Use "CPG/MSTP Clock Domain" instead of "CPG Clock Domain",

v2:
  - New.
---
 arch/arm/mach-shmobile/pm-rmobile.c | 35 +++--------------------------------
 1 file changed, 3 insertions(+), 32 deletions(-)

diff --git a/arch/arm/mach-shmobile/pm-rmobile.c b/arch/arm/mach-shmobile/pm-rmobile.c
index a5b96b990aea8dfc..89068c8ec50f2c76 100644
--- a/arch/arm/mach-shmobile/pm-rmobile.c
+++ b/arch/arm/mach-shmobile/pm-rmobile.c
@@ -12,6 +12,7 @@
  * License.  See the file "COPYING" in the main directory of this archive
  * for more details.
  */
+#include <linux/clk/shmobile.h>
 #include <linux/console.h>
 #include <linux/delay.h>
 #include <linux/of.h>
@@ -124,36 +125,6 @@ static bool rmobile_pd_active_wakeup(struct device *dev)
 	return true;
 }
 
-static int rmobile_pd_attach_dev(struct generic_pm_domain *domain,
-				 struct device *dev)
-{
-	int error;
-
-	error = pm_clk_create(dev);
-	if (error) {
-		dev_err(dev, "pm_clk_create failed %d\n", error);
-		return error;
-	}
-
-	error = pm_clk_add(dev, NULL);
-	if (error) {
-		dev_err(dev, "pm_clk_add failed %d\n", error);
-		goto fail;
-	}
-
-	return 0;
-
-fail:
-	pm_clk_destroy(dev);
-	return error;
-}
-
-static void rmobile_pd_detach_dev(struct generic_pm_domain *domain,
-				  struct device *dev)
-{
-	pm_clk_destroy(dev);
-}
-
 static void rmobile_init_pm_domain(struct rmobile_pm_domain *rmobile_pd)
 {
 	struct generic_pm_domain *genpd = &rmobile_pd->genpd;
@@ -164,8 +135,8 @@ static void rmobile_init_pm_domain(struct rmobile_pm_domain *rmobile_pd)
 	genpd->dev_ops.active_wakeup	= rmobile_pd_active_wakeup;
 	genpd->power_off		= rmobile_pd_power_down;
 	genpd->power_on			= rmobile_pd_power_up;
-	genpd->attach_dev		= rmobile_pd_attach_dev;
-	genpd->detach_dev		= rmobile_pd_detach_dev;
+	genpd->attach_dev		= cpg_mstp_attach_dev;
+	genpd->detach_dev		= cpg_mstp_detach_dev;
 	__rmobile_pd_power_up(rmobile_pd, false);
 }
 
-- 
1.9.1



From geert+renesas at glider.be  Tue Aug  4 05:28:14 2015
From: geert+renesas at glider.be (Geert Uytterhoeven)
Date: Tue,  4 Aug 2015 14:28:14 +0200
Subject: [PATCH v4 13/16] drivers: sh: Disable legacy default PM Domain on
 emev2
In-Reply-To: <1438691297-29235-1-git-send-email-geert+renesas@glider.be>
References: <1438691297-29235-1-git-send-email-geert+renesas@glider.be>
Message-ID: <1438691297-29235-14-git-send-email-geert+renesas@glider.be>

EMMA Mobile EV2 doesn't have MSTP clocks. All its device drivers manage
clocks explicitly, without relying on Runtime PM, so it doesn't need the
legacy default PM Domain.

Signed-off-by: Geert Uytterhoeven <geert+renesas at glider.be>
Reviewed-by: Ulf Hansson <ulf.hansson at linaro.org>
---
v4:
  - Add Reviewed-by,

v3:
  - New, extracted from "[PATCH v2 12/14] drivers: sh: Stop using
    pm_runtime.c for multi-platform shmobile with genpd".
---
 drivers/sh/pm_runtime.c | 3 +--
 1 file changed, 1 insertion(+), 2 deletions(-)

diff --git a/drivers/sh/pm_runtime.c b/drivers/sh/pm_runtime.c
index d3d1891cda3cf9a8..ad9188138ed56ffb 100644
--- a/drivers/sh/pm_runtime.c
+++ b/drivers/sh/pm_runtime.c
@@ -35,8 +35,7 @@ static struct pm_clk_notifier_block platform_bus_notifier = {
 static int __init sh_pm_runtime_init(void)
 {
 	if (IS_ENABLED(CONFIG_ARCH_SHMOBILE_MULTI)) {
-		if (!of_machine_is_compatible("renesas,emev2") &&
-		    !of_machine_is_compatible("renesas,r7s72100") &&
+		if (!of_machine_is_compatible("renesas,r7s72100") &&
 #ifndef CONFIG_PM_GENERIC_DOMAINS_OF
 		    !of_machine_is_compatible("renesas,r8a73a4") &&
 		    !of_machine_is_compatible("renesas,r8a7740") &&
-- 
1.9.1



From geert+renesas at glider.be  Tue Aug  4 05:28:04 2015
From: geert+renesas at glider.be (Geert Uytterhoeven)
Date: Tue,  4 Aug 2015 14:28:04 +0200
Subject: [PATCH v4 03/16] clk: shmobile: r8a7779: Add CPG/MSTP Clock Domain
 support
In-Reply-To: <1438691297-29235-1-git-send-email-geert+renesas@glider.be>
References: <1438691297-29235-1-git-send-email-geert+renesas@glider.be>
Message-ID: <1438691297-29235-4-git-send-email-geert+renesas@glider.be>

Add Clock Domain support to the R-Car H1 Clock Pulse Generator (CPG)
driver using the generic PM Domain.  This allows to power-manage the
module clocks of SoC devices that are part of the CPG/MSTP Clock Domain
using Runtime PM, or for system suspend/resume.

SoC devices that are part of the CPG/MSTP Clock Domain and can be
power-managed through an MSTP clock should be tagged in DT with a proper
"power-domains" property.

Also update the reg property in the DT binding doc example to match the
actual dtsi, which uses #address-cells and #size-cells == 1, not 2.

Signed-off-by: Geert Uytterhoeven <geert+renesas at glider.be>
Acked-by: Stephen Boyd <sboyd at codeaurora.org>
Reviewed-by: Ulf Hansson <ulf.hansson at linaro.org>
---
v4:
  - Add Reviewed-by,

v3:
  - Add Acked-by,
  - Use "CPG/MSTP Clock Domain" instead of "CPG Clock Domain",

v2:
  - New.
---
 .../bindings/clock/renesas,r8a7779-cpg-clocks.txt  | 30 +++++++++++++++++++---
 drivers/clk/shmobile/clk-r8a7779.c                 |  2 ++
 2 files changed, 28 insertions(+), 4 deletions(-)

diff --git a/Documentation/devicetree/bindings/clock/renesas,r8a7779-cpg-clocks.txt b/Documentation/devicetree/bindings/clock/renesas,r8a7779-cpg-clocks.txt
index ed3c8cb12f4eb699..8c81547c29f568e8 100644
--- a/Documentation/devicetree/bindings/clock/renesas,r8a7779-cpg-clocks.txt
+++ b/Documentation/devicetree/bindings/clock/renesas,r8a7779-cpg-clocks.txt
@@ -1,7 +1,9 @@
 * Renesas R8A7779 Clock Pulse Generator (CPG)
 
 The CPG generates core clocks for the R8A7779. It includes one PLL and
-several fixed ratio dividers
+several fixed ratio dividers.
+The CPG also provides a Clock Domain for SoC devices, in combination with the
+CPG Module Stop (MSTP) Clocks.
 
 Required Properties:
 
@@ -12,16 +14,36 @@ Required Properties:
   - #clock-cells: Must be 1
   - clock-output-names: The names of the clocks. Supported clocks are "plla",
     "z", "zs", "s", "s1", "p", "b", "out".
+  - #power-domain-cells: Must be 0
 
+SoC devices that are part of the CPG/MSTP Clock Domain and can be power-managed
+through an MSTP clock should refer to the CPG device node in their
+"power-domains" property, as documented by the generic PM domain bindings in
+Documentation/devicetree/bindings/power/power_domain.txt.
 
-Example
--------
+
+Examples
+--------
+
+  - CPG device node:
 
 	cpg_clocks: cpg_clocks at ffc80000 {
 		compatible = "renesas,r8a7779-cpg-clocks";
-		reg = <0 0xffc80000 0 0x30>;
+		reg = <0xffc80000 0x30>;
 		clocks = <&extal_clk>;
 		#clock-cells = <1>;
 		clock-output-names = "plla", "z", "zs", "s", "s1", "p",
 		                     "b", "out";
+		#power-domain-cells = <0>;
+	};
+
+
+  - CPG/MSTP Clock Domain member device node:
+
+	sata: sata at fc600000 {
+		compatible = "renesas,sata-r8a7779", "renesas,rcar-sata";
+		reg = <0xfc600000 0x2000>;
+		interrupts = <0 100 IRQ_TYPE_LEVEL_HIGH>;
+		clocks = <&mstp1_clks R8A7779_CLK_SATA>;
+		power-domains = <&cpg_clocks>;
 	};
diff --git a/drivers/clk/shmobile/clk-r8a7779.c b/drivers/clk/shmobile/clk-r8a7779.c
index af297963489f473d..92275c5f2c60303e 100644
--- a/drivers/clk/shmobile/clk-r8a7779.c
+++ b/drivers/clk/shmobile/clk-r8a7779.c
@@ -168,6 +168,8 @@ static void __init r8a7779_cpg_clocks_init(struct device_node *np)
 	}
 
 	of_clk_add_provider(np, of_clk_src_onecell_get, &cpg->data);
+
+	cpg_mstp_add_clk_domain(np);
 }
 CLK_OF_DECLARE(r8a7779_cpg_clks, "renesas,r8a7779-cpg-clocks",
 	       r8a7779_cpg_clocks_init);
-- 
1.9.1



From geert+renesas at glider.be  Tue Aug  4 05:28:02 2015
From: geert+renesas at glider.be (Geert Uytterhoeven)
Date: Tue,  4 Aug 2015 14:28:02 +0200
Subject: [PATCH v4 01/16] clk: shmobile: Add CPG/MSTP Clock Domain support
In-Reply-To: <1438691297-29235-1-git-send-email-geert+renesas@glider.be>
References: <1438691297-29235-1-git-send-email-geert+renesas@glider.be>
Message-ID: <1438691297-29235-2-git-send-email-geert+renesas@glider.be>

Add Clock Domain support to the Clock Pulse Generator (CPG) Module Stop
(MSTP) Clocks driver using the generic PM Domain.  This allows to
power-manage the module clocks of SoC devices that are part of the
CPG/MSTP Clock Domain using Runtime PM, or for system suspend/resume.

SoC devices that are part of the CPG/MSTP Clock Domain and can be
power-managed through an MSTP clock should be tagged in DT with a
proper "power-domains" property.

The CPG/MSTP Clock Domain code will scan such devices for clocks that
are suitable for power-managing the device, by looking for a clock that
is compatible with "renesas,cpg-mstp-clocks".

Signed-off-by: Geert Uytterhoeven <geert+renesas at glider.be>
Acked-by: Laurent Pinchart <laurent.pinchart at ideasonboard.com>
Acked-by: Stephen Boyd <sboyd at codeaurora.org>
Reviewed-by: Ulf Hansson <ulf.hansson at linaro.org>
Reviewed-by: Kevin Hilman <khilman at linaro.org>
---
v4:
  - clk-mstp.c needs to #include <linux/clk.h> due to recent
    <linux/clk*.h> shuffling,

v3:
  - Add Acked-by,
  - Use "CPG/MSTP Clock Domain" instead of "CPG Clock Domain",
  - Drop bogus addition of #includes to clk-rcar-gen2.c,
  - Call pm_clk_destroy() from cpg_mstp_detach_dev() only if
    cpg_mstp_attach_dev() actually added a clock,

v2:
  - Add Acked-by and Reviewed-by,
  - Move core CPG Clock Domain code from the R-Car Gen2 driver to the
    CPG MSTP Clock driver, as it's generic, and can be used on other
    Renesas SoCs that have a CPG/MSTP block,
  - Scan for an MSTP clock instead of using the first clock tied to the
    device (con_id NULL),
  - Extract R-Car Gen2 specifics to a separate patch.
---
 drivers/clk/shmobile/clk-mstp.c | 87 +++++++++++++++++++++++++++++++++++++++++
 include/linux/clk/shmobile.h    | 12 ++++++
 2 files changed, 99 insertions(+)

diff --git a/drivers/clk/shmobile/clk-mstp.c b/drivers/clk/shmobile/clk-mstp.c
index 2d2fe773ac8168f9..b1df7b2f1e970adb 100644
--- a/drivers/clk/shmobile/clk-mstp.c
+++ b/drivers/clk/shmobile/clk-mstp.c
@@ -2,6 +2,7 @@
  * R-Car MSTP clocks
  *
  * Copyright (C) 2013 Ideas On Board SPRL
+ * Copyright (C) 2015 Glider bvba
  *
  * Contact: Laurent Pinchart <laurent.pinchart at ideasonboard.com>
  *
@@ -10,11 +11,16 @@
  * the Free Software Foundation; version 2 of the License.
  */
 
+#include <linux/clk.h>
 #include <linux/clk-provider.h>
 #include <linux/clkdev.h>
+#include <linux/clk/shmobile.h>
+#include <linux/device.h>
 #include <linux/io.h>
 #include <linux/of.h>
 #include <linux/of_address.h>
+#include <linux/pm_clock.h>
+#include <linux/pm_domain.h>
 #include <linux/spinlock.h>
 
 /*
@@ -236,3 +242,84 @@ static void __init cpg_mstp_clocks_init(struct device_node *np)
 	of_clk_add_provider(np, of_clk_src_onecell_get, &group->data);
 }
 CLK_OF_DECLARE(cpg_mstp_clks, "renesas,cpg-mstp-clocks", cpg_mstp_clocks_init);
+
+
+#ifdef CONFIG_PM_GENERIC_DOMAINS_OF
+int cpg_mstp_attach_dev(struct generic_pm_domain *domain, struct device *dev)
+{
+	struct device_node *np = dev->of_node;
+	struct of_phandle_args clkspec;
+	struct clk *clk;
+	int i = 0;
+	int error;
+
+	while (!of_parse_phandle_with_args(np, "clocks", "#clock-cells", i,
+					   &clkspec)) {
+		if (of_device_is_compatible(clkspec.np,
+					    "renesas,cpg-mstp-clocks"))
+			goto found;
+
+		of_node_put(clkspec.np);
+		i++;
+	}
+
+	return 0;
+
+found:
+	clk = of_clk_get_from_provider(&clkspec);
+	of_node_put(clkspec.np);
+
+	if (IS_ERR(clk))
+		return PTR_ERR(clk);
+
+	error = pm_clk_create(dev);
+	if (error) {
+		dev_err(dev, "pm_clk_create failed %d\n", error);
+		goto fail_put;
+	}
+
+	error = pm_clk_add_clk(dev, clk);
+	if (error) {
+		dev_err(dev, "pm_clk_add_clk %pC failed %d\n", clk, error);
+		goto fail_destroy;
+	}
+
+	return 0;
+
+fail_destroy:
+	pm_clk_destroy(dev);
+fail_put:
+	clk_put(clk);
+	return error;
+}
+
+void cpg_mstp_detach_dev(struct generic_pm_domain *domain, struct device *dev)
+{
+	if (!list_empty(&dev->power.subsys_data->clock_list))
+		pm_clk_destroy(dev);
+}
+
+void __init cpg_mstp_add_clk_domain(struct device_node *np)
+{
+	struct generic_pm_domain *pd;
+	u32 ncells;
+
+	if (of_property_read_u32(np, "#power-domain-cells", &ncells)) {
+		pr_warn("%s lacks #power-domain-cells\n", np->full_name);
+		return;
+	}
+
+	pd = kzalloc(sizeof(*pd), GFP_KERNEL);
+	if (!pd)
+		return;
+
+	pd->name = np->name;
+
+	pd->flags = GENPD_FLAG_PM_CLK;
+	pm_genpd_init(pd, &simple_qos_governor, false);
+	pd->attach_dev = cpg_mstp_attach_dev;
+	pd->detach_dev = cpg_mstp_detach_dev;
+
+	of_genpd_add_provider_simple(np, pd);
+}
+#endif /* !CONFIG_PM_GENERIC_DOMAINS_OF */
diff --git a/include/linux/clk/shmobile.h b/include/linux/clk/shmobile.h
index 63a8159c4e64153d..cb19cc1865ca5cfb 100644
--- a/include/linux/clk/shmobile.h
+++ b/include/linux/clk/shmobile.h
@@ -16,8 +16,20 @@
 
 #include <linux/types.h>
 
+struct device;
+struct device_node;
+struct generic_pm_domain;
+
 void r8a7778_clocks_init(u32 mode);
 void r8a7779_clocks_init(u32 mode);
 void rcar_gen2_clocks_init(u32 mode);
 
+#ifdef CONFIG_PM_GENERIC_DOMAINS_OF
+void cpg_mstp_add_clk_domain(struct device_node *np);
+int cpg_mstp_attach_dev(struct generic_pm_domain *domain, struct device *dev);
+void cpg_mstp_detach_dev(struct generic_pm_domain *domain, struct device *dev);
+#else
+static inline void cpg_mstp_add_clk_domain(struct device_node *np) {}
+#endif
+
 #endif
-- 
1.9.1



From geert+renesas at glider.be  Tue Aug  4 05:28:08 2015
From: geert+renesas at glider.be (Geert Uytterhoeven)
Date: Tue,  4 Aug 2015 14:28:08 +0200
Subject: [PATCH v4 07/16] ARM: shmobile: r8a7778 dtsi: Add CPG/MSTP Clock
 Domain
In-Reply-To: <1438691297-29235-1-git-send-email-geert+renesas@glider.be>
References: <1438691297-29235-1-git-send-email-geert+renesas@glider.be>
Message-ID: <1438691297-29235-8-git-send-email-geert+renesas@glider.be>

Add an appropriate "#power-domain-cells" property to the cpg_clocks
device node, to create the CPG/MSTP Clock Domain.

Add "power-domains" properties to all device nodes for devices that are
part of the CPG/MSTP Clock Domain and can be power-managed through an
MSTP clock.  This applies to most on-SoC devices, which have a
one-to-one mapping from SoC device to DT device node.  A notable
exception is the "sound" node, which represents multiple SoC devices,
each having their own MSTP clocks.

Signed-off-by: Geert Uytterhoeven <geert+renesas at glider.be>
Reviewed-by: Ulf Hansson <ulf.hansson at linaro.org>
---
v4:
  - Add Reviewed-by,

v3:
  - Use "CPG/MSTP Clock Domain" instead of "CPG Clock Domain",

v2:
  - New.
---
 arch/arm/boot/dts/r8a7778.dtsi | 22 ++++++++++++++++++++++
 1 file changed, 22 insertions(+)

diff --git a/arch/arm/boot/dts/r8a7778.dtsi b/arch/arm/boot/dts/r8a7778.dtsi
index 7ce9f5fd586504f2..4b1fa9f42ad5457b 100644
--- a/arch/arm/boot/dts/r8a7778.dtsi
+++ b/arch/arm/boot/dts/r8a7778.dtsi
@@ -53,6 +53,7 @@
 		reg = <0xfde00000 0x400>;
 		interrupts = <0 105 IRQ_TYPE_LEVEL_HIGH>;
 		clocks = <&mstp1_clks R8A7778_CLK_ETHER>;
+		power-domains = <&cpg_clocks>;
 		phy-mode = "rmii";
 		#address-cells = <1>;
 		#size-cells = <0>;
@@ -152,6 +153,7 @@
 		reg = <0xffc70000 0x1000>;
 		interrupts = <0 67 IRQ_TYPE_LEVEL_HIGH>;
 		clocks = <&mstp0_clks R8A7778_CLK_I2C0>;
+		power-domains = <&cpg_clocks>;
 		status = "disabled";
 	};
 
@@ -162,6 +164,7 @@
 		reg = <0xffc71000 0x1000>;
 		interrupts = <0 78 IRQ_TYPE_LEVEL_HIGH>;
 		clocks = <&mstp0_clks R8A7778_CLK_I2C1>;
+		power-domains = <&cpg_clocks>;
 		status = "disabled";
 	};
 
@@ -172,6 +175,7 @@
 		reg = <0xffc72000 0x1000>;
 		interrupts = <0 76 IRQ_TYPE_LEVEL_HIGH>;
 		clocks = <&mstp0_clks R8A7778_CLK_I2C2>;
+		power-domains = <&cpg_clocks>;
 		status = "disabled";
 	};
 
@@ -182,6 +186,7 @@
 		reg = <0xffc73000 0x1000>;
 		interrupts = <0 77 IRQ_TYPE_LEVEL_HIGH>;
 		clocks = <&mstp0_clks R8A7778_CLK_I2C3>;
+		power-domains = <&cpg_clocks>;
 		status = "disabled";
 	};
 
@@ -193,6 +198,7 @@
 			     <0 34 IRQ_TYPE_LEVEL_HIGH>;
 		clocks = <&mstp0_clks R8A7778_CLK_TMU0>;
 		clock-names = "fck";
+		power-domains = <&cpg_clocks>;
 
 		#renesas,channels = <3>;
 
@@ -207,6 +213,7 @@
 			     <0 38 IRQ_TYPE_LEVEL_HIGH>;
 		clocks = <&mstp0_clks R8A7778_CLK_TMU1>;
 		clock-names = "fck";
+		power-domains = <&cpg_clocks>;
 
 		#renesas,channels = <3>;
 
@@ -221,6 +228,7 @@
 			     <0 42 IRQ_TYPE_LEVEL_HIGH>;
 		clocks = <&mstp0_clks R8A7778_CLK_TMU2>;
 		clock-names = "fck";
+		power-domains = <&cpg_clocks>;
 
 		#renesas,channels = <3>;
 
@@ -288,6 +296,7 @@
 		interrupts = <0 70 IRQ_TYPE_LEVEL_HIGH>;
 		clocks = <&mstp0_clks R8A7778_CLK_SCIF0>;
 		clock-names = "sci_ick";
+		power-domains = <&cpg_clocks>;
 		status = "disabled";
 	};
 
@@ -297,6 +306,7 @@
 		interrupts = <0 71 IRQ_TYPE_LEVEL_HIGH>;
 		clocks = <&mstp0_clks R8A7778_CLK_SCIF1>;
 		clock-names = "sci_ick";
+		power-domains = <&cpg_clocks>;
 		status = "disabled";
 	};
 
@@ -306,6 +316,7 @@
 		interrupts = <0 72 IRQ_TYPE_LEVEL_HIGH>;
 		clocks = <&mstp0_clks R8A7778_CLK_SCIF2>;
 		clock-names = "sci_ick";
+		power-domains = <&cpg_clocks>;
 		status = "disabled";
 	};
 
@@ -315,6 +326,7 @@
 		interrupts = <0 73 IRQ_TYPE_LEVEL_HIGH>;
 		clocks = <&mstp0_clks R8A7778_CLK_SCIF3>;
 		clock-names = "sci_ick";
+		power-domains = <&cpg_clocks>;
 		status = "disabled";
 	};
 
@@ -324,6 +336,7 @@
 		interrupts = <0 74 IRQ_TYPE_LEVEL_HIGH>;
 		clocks = <&mstp0_clks R8A7778_CLK_SCIF4>;
 		clock-names = "sci_ick";
+		power-domains = <&cpg_clocks>;
 		status = "disabled";
 	};
 
@@ -333,6 +346,7 @@
 		interrupts = <0 75 IRQ_TYPE_LEVEL_HIGH>;
 		clocks = <&mstp0_clks R8A7778_CLK_SCIF5>;
 		clock-names = "sci_ick";
+		power-domains = <&cpg_clocks>;
 		status = "disabled";
 	};
 
@@ -341,6 +355,7 @@
 		reg = <0xffe4e000 0x100>;
 		interrupts = <0 61 IRQ_TYPE_LEVEL_HIGH>;
 		clocks = <&mstp3_clks R8A7778_CLK_MMC>;
+		power-domains = <&cpg_clocks>;
 		status = "disabled";
 	};
 
@@ -349,6 +364,7 @@
 		reg = <0xffe4c000 0x100>;
 		interrupts = <0 87 IRQ_TYPE_LEVEL_HIGH>;
 		clocks = <&mstp3_clks R8A7778_CLK_SDHI0>;
+		power-domains = <&cpg_clocks>;
 		status = "disabled";
 	};
 
@@ -357,6 +373,7 @@
 		reg = <0xffe4d000 0x100>;
 		interrupts = <0 88 IRQ_TYPE_LEVEL_HIGH>;
 		clocks = <&mstp3_clks R8A7778_CLK_SDHI1>;
+		power-domains = <&cpg_clocks>;
 		status = "disabled";
 	};
 
@@ -365,6 +382,7 @@
 		reg = <0xffe4f000 0x100>;
 		interrupts = <0 86 IRQ_TYPE_LEVEL_HIGH>;
 		clocks = <&mstp3_clks R8A7778_CLK_SDHI2>;
+		power-domains = <&cpg_clocks>;
 		status = "disabled";
 	};
 
@@ -373,6 +391,7 @@
 		reg = <0xfffc7000 0x18>;
 		interrupts = <0 63 IRQ_TYPE_LEVEL_HIGH>;
 		clocks = <&mstp0_clks R8A7778_CLK_HSPI>;
+		power-domains = <&cpg_clocks>;
 		#address-cells = <1>;
 		#size-cells = <0>;
 		status = "disabled";
@@ -383,6 +402,7 @@
 		reg = <0xfffc8000 0x18>;
 		interrupts = <0 84 IRQ_TYPE_LEVEL_HIGH>;
 		clocks = <&mstp0_clks R8A7778_CLK_HSPI>;
+		power-domains = <&cpg_clocks>;
 		#address-cells = <1>;
 		#size-cells = <0>;
 		status = "disabled";
@@ -393,6 +413,7 @@
 		reg = <0xfffc6000 0x18>;
 		interrupts = <0 85 IRQ_TYPE_LEVEL_HIGH>;
 		clocks = <&mstp0_clks R8A7778_CLK_HSPI>;
+		power-domains = <&cpg_clocks>;
 		#address-cells = <1>;
 		#size-cells = <0>;
 		status = "disabled";
@@ -419,6 +440,7 @@
 			clocks = <&extal_clk>;
 			clock-output-names = "plla", "pllb", "b",
 					     "out", "p", "s", "s1";
+			#power-domain-cells = <0>;
 		};
 
 		/* Audio clocks; frequencies are set by boards if applicable. */
-- 
1.9.1



From geert+renesas at glider.be  Tue Aug  4 05:28:05 2015
From: geert+renesas at glider.be (Geert Uytterhoeven)
Date: Tue,  4 Aug 2015 14:28:05 +0200
Subject: [PATCH v4 04/16] clk: shmobile: rcar-gen2: Add CPG/MSTP Clock Domain
 support
In-Reply-To: <1438691297-29235-1-git-send-email-geert+renesas@glider.be>
References: <1438691297-29235-1-git-send-email-geert+renesas@glider.be>
Message-ID: <1438691297-29235-5-git-send-email-geert+renesas@glider.be>

Add Clock Domain support to the R-Car Gen2 Clock Pulse Generator (CPG)
driver using the generic PM Domain.  This allows to power-manage the
module clocks of SoC devices that are part of the CPG/MSTP Clock Domain
using Runtime PM, or for system suspend/resume.

SoC devices that are part of the CPG/MSTP Clock Domain and can be
power-managed through an MSTP clock should be tagged in DT with a proper
"power-domains" property.

Signed-off-by: Geert Uytterhoeven <geert+renesas at glider.be>
Acked-by: Stephen Boyd <sboyd at codeaurora.org>
Reviewed-by: Ulf Hansson <ulf.hansson at linaro.org>
---
v4:
  - Add Reviewed-by,

v3:
  - Add Acked-by,
  - Use "CPG/MSTP Clock Domain" instead of "CPG Clock Domain",

v2:
  - Add Acked-by and Reviewed-by,
  - Move core CPG Clock Domain code from the R-Car Gen2 driver to the
    CPG MSTP Clocks driver, as it's generic, and can be used on other
    Renesas SoCs that have a CPG/MSTP block,
  - Scan for an MSTP clock instead of using the first clock tied to the
    device (con_id NULL),
  - Extract R-Car Gen2 specifics from "[PATCH/RFC 1/5] clk: shmobile:
    rcar-gen2: Add CPG Clock Domain support" into this patch.
---
 .../clock/renesas,rcar-gen2-cpg-clocks.txt         | 26 ++++++++++++++++++++--
 drivers/clk/shmobile/clk-rcar-gen2.c               |  2 ++
 2 files changed, 26 insertions(+), 2 deletions(-)

diff --git a/Documentation/devicetree/bindings/clock/renesas,rcar-gen2-cpg-clocks.txt b/Documentation/devicetree/bindings/clock/renesas,rcar-gen2-cpg-clocks.txt
index 56f111bd3e456619..2a9a8edc8f3547b0 100644
--- a/Documentation/devicetree/bindings/clock/renesas,rcar-gen2-cpg-clocks.txt
+++ b/Documentation/devicetree/bindings/clock/renesas,rcar-gen2-cpg-clocks.txt
@@ -2,6 +2,8 @@
 
 The CPG generates core clocks for the R-Car Gen2 SoCs. It includes three PLLs
 and several fixed ratio dividers.
+The CPG also provides a Clock Domain for SoC devices, in combination with the
+CPG Module Stop (MSTP) Clocks.
 
 Required Properties:
 
@@ -20,10 +22,18 @@ Required Properties:
   - clock-output-names: The names of the clocks. Supported clocks are "main",
     "pll0", "pll1", "pll3", "lb", "qspi", "sdh", "sd0", "sd1", "z", "rcan", and
     "adsp"
+  - #power-domain-cells: Must be 0
 
+SoC devices that are part of the CPG/MSTP Clock Domain and can be power-managed
+through an MSTP clock should refer to the CPG device node in their
+"power-domains" property, as documented by the generic PM domain bindings in
+Documentation/devicetree/bindings/power/power_domain.txt.
 
-Example
--------
+
+Examples
+--------
+
+  - CPG device node:
 
 	cpg_clocks: cpg_clocks at e6150000 {
 		compatible = "renesas,r8a7790-cpg-clocks",
@@ -34,4 +44,16 @@ Example
 		clock-output-names = "main", "pll0, "pll1", "pll3",
 				     "lb", "qspi", "sdh", "sd0", "sd1", "z",
 				     "rcan", "adsp";
+		#power-domain-cells = <0>;
+	};
+
+
+  - CPG/MSTP Clock Domain member device node:
+
+	thermal at e61f0000 {
+		compatible = "renesas,thermal-r8a7790", "renesas,rcar-thermal";
+		reg = <0 0xe61f0000 0 0x14>, <0 0xe61f0100 0 0x38>;
+		interrupts = <0 69 IRQ_TYPE_LEVEL_HIGH>;
+		clocks = <&mstp5_clks R8A7790_CLK_THERMAL>;
+		power-domains = <&cpg_clocks>;
 	};
diff --git a/drivers/clk/shmobile/clk-rcar-gen2.c b/drivers/clk/shmobile/clk-rcar-gen2.c
index 9233ebf8cc49f933..745496f7ee9c7402 100644
--- a/drivers/clk/shmobile/clk-rcar-gen2.c
+++ b/drivers/clk/shmobile/clk-rcar-gen2.c
@@ -415,6 +415,8 @@ static void __init rcar_gen2_cpg_clocks_init(struct device_node *np)
 	}
 
 	of_clk_add_provider(np, of_clk_src_onecell_get, &cpg->data);
+
+	cpg_mstp_add_clk_domain(np);
 }
 CLK_OF_DECLARE(rcar_gen2_cpg_clks, "renesas,rcar-gen2-cpg-clocks",
 	       rcar_gen2_cpg_clocks_init);
-- 
1.9.1



From geert+renesas at glider.be  Tue Aug  4 05:28:11 2015
From: geert+renesas at glider.be (Geert Uytterhoeven)
Date: Tue,  4 Aug 2015 14:28:11 +0200
Subject: [PATCH v4 10/16] ARM: shmobile: r8a7791 dtsi: Add CPG/MSTP Clock
 Domain
In-Reply-To: <1438691297-29235-1-git-send-email-geert+renesas@glider.be>
References: <1438691297-29235-1-git-send-email-geert+renesas@glider.be>
Message-ID: <1438691297-29235-11-git-send-email-geert+renesas@glider.be>

Add an appropriate "#power-domain-cells" property to the cpg_clocks
device node, to create the CPG/MSTP Clock Domain.

Add "power-domains" properties to all device nodes for devices that are
part of the CPG/MSTP Clock Domain and can be power-managed through an
MSTP clock.  This applies to most on-SoC devices, which have a
one-to-one mapping from SoC device to DT device node.  Notable
exceptions are the "display" and "sound" nodes, which represent multiple
SoC devices, each having their own MSTP clocks.

Signed-off-by: Geert Uytterhoeven <geert+renesas at glider.be>
Reviewed-by: Ulf Hansson <ulf.hansson at linaro.org>
---
v4:
  - Add "power-domains" properties to recently introduced jpu device
    node,
  - Consistently add "power-domains" properties after clock and dma
    properties,

v3:
  - Use "CPG/MSTP Clock Domain" instead of "CPG Clock Domain",

v2:
  - Add Reviewed-by,
  - Add "power-domains" properties to recently introduced USB-DMAC
    device nodes,
  - Drop adding "power-domains" properties to the GIC device node, as
    adding the INTC_SYS clock is postponed.
---
 arch/arm/boot/dts/r8a7791.dtsi | 88 ++++++++++++++++++++++++++++++++++++++----
 1 file changed, 80 insertions(+), 8 deletions(-)

diff --git a/arch/arm/boot/dts/r8a7791.dtsi b/arch/arm/boot/dts/r8a7791.dtsi
index 1cb6c2d079331d4f..831525dd39a60ad7 100644
--- a/arch/arm/boot/dts/r8a7791.dtsi
+++ b/arch/arm/boot/dts/r8a7791.dtsi
@@ -91,6 +91,7 @@
 		#interrupt-cells = <2>;
 		interrupt-controller;
 		clocks = <&mstp9_clks R8A7791_CLK_GPIO0>;
+		power-domains = <&cpg_clocks>;
 	};
 
 	gpio1: gpio at e6051000 {
@@ -103,6 +104,7 @@
 		#interrupt-cells = <2>;
 		interrupt-controller;
 		clocks = <&mstp9_clks R8A7791_CLK_GPIO1>;
+		power-domains = <&cpg_clocks>;
 	};
 
 	gpio2: gpio at e6052000 {
@@ -115,6 +117,7 @@
 		#interrupt-cells = <2>;
 		interrupt-controller;
 		clocks = <&mstp9_clks R8A7791_CLK_GPIO2>;
+		power-domains = <&cpg_clocks>;
 	};
 
 	gpio3: gpio at e6053000 {
@@ -127,6 +130,7 @@
 		#interrupt-cells = <2>;
 		interrupt-controller;
 		clocks = <&mstp9_clks R8A7791_CLK_GPIO3>;
+		power-domains = <&cpg_clocks>;
 	};
 
 	gpio4: gpio at e6054000 {
@@ -139,6 +143,7 @@
 		#interrupt-cells = <2>;
 		interrupt-controller;
 		clocks = <&mstp9_clks R8A7791_CLK_GPIO4>;
+		power-domains = <&cpg_clocks>;
 	};
 
 	gpio5: gpio at e6055000 {
@@ -151,6 +156,7 @@
 		#interrupt-cells = <2>;
 		interrupt-controller;
 		clocks = <&mstp9_clks R8A7791_CLK_GPIO5>;
+		power-domains = <&cpg_clocks>;
 	};
 
 	gpio6: gpio at e6055400 {
@@ -163,6 +169,7 @@
 		#interrupt-cells = <2>;
 		interrupt-controller;
 		clocks = <&mstp9_clks R8A7791_CLK_GPIO6>;
+		power-domains = <&cpg_clocks>;
 	};
 
 	gpio7: gpio at e6055800 {
@@ -175,6 +182,7 @@
 		#interrupt-cells = <2>;
 		interrupt-controller;
 		clocks = <&mstp9_clks R8A7791_CLK_GPIO7>;
+		power-domains = <&cpg_clocks>;
 	};
 
 	thermal at e61f0000 {
@@ -182,6 +190,7 @@
 		reg = <0 0xe61f0000 0 0x14>, <0 0xe61f0100 0 0x38>;
 		interrupts = <0 69 IRQ_TYPE_LEVEL_HIGH>;
 		clocks = <&mstp5_clks R8A7791_CLK_THERMAL>;
+		power-domains = <&cpg_clocks>;
 	};
 
 	timer {
@@ -199,6 +208,7 @@
 			     <0 143 IRQ_TYPE_LEVEL_HIGH>;
 		clocks = <&mstp1_clks R8A7791_CLK_CMT0>;
 		clock-names = "fck";
+		power-domains = <&cpg_clocks>;
 
 		renesas,channels-mask = <0x60>;
 
@@ -218,6 +228,7 @@
 			     <0 127 IRQ_TYPE_LEVEL_HIGH>;
 		clocks = <&mstp3_clks R8A7791_CLK_CMT1>;
 		clock-names = "fck";
+		power-domains = <&cpg_clocks>;
 
 		renesas,channels-mask = <0xff>;
 
@@ -240,6 +251,7 @@
 			     <0 16 IRQ_TYPE_LEVEL_HIGH>,
 			     <0 17 IRQ_TYPE_LEVEL_HIGH>;
 		clocks = <&mstp4_clks R8A7791_CLK_IRQC>;
+		power-domains = <&cpg_clocks>;
 	};
 
 	dmac0: dma-controller at e6700000 {
@@ -268,6 +280,7 @@
 				"ch12", "ch13", "ch14";
 		clocks = <&mstp2_clks R8A7791_CLK_SYS_DMAC0>;
 		clock-names = "fck";
+		power-domains = <&cpg_clocks>;
 		#dma-cells = <1>;
 		dma-channels = <15>;
 	};
@@ -298,6 +311,7 @@
 				"ch12", "ch13", "ch14";
 		clocks = <&mstp2_clks R8A7791_CLK_SYS_DMAC1>;
 		clock-names = "fck";
+		power-domains = <&cpg_clocks>;
 		#dma-cells = <1>;
 		dma-channels = <15>;
 	};
@@ -326,6 +340,7 @@
 				"ch12";
 		clocks = <&mstp5_clks R8A7791_CLK_AUDIO_DMAC0>;
 		clock-names = "fck";
+		power-domains = <&cpg_clocks>;
 		#dma-cells = <1>;
 		dma-channels = <13>;
 	};
@@ -354,6 +369,7 @@
 				"ch12";
 		clocks = <&mstp5_clks R8A7791_CLK_AUDIO_DMAC1>;
 		clock-names = "fck";
+		power-domains = <&cpg_clocks>;
 		#dma-cells = <1>;
 		dma-channels = <13>;
 	};
@@ -365,6 +381,7 @@
 			      0 109 IRQ_TYPE_LEVEL_HIGH>;
 		interrupt-names = "ch0", "ch1";
 		clocks = <&mstp3_clks R8A7791_CLK_USBDMAC0>;
+		power-domains = <&cpg_clocks>;
 		#dma-cells = <1>;
 		dma-channels = <2>;
 	};
@@ -376,6 +393,7 @@
 			      0 110 IRQ_TYPE_LEVEL_HIGH>;
 		interrupt-names = "ch0", "ch1";
 		clocks = <&mstp3_clks R8A7791_CLK_USBDMAC1>;
+		power-domains = <&cpg_clocks>;
 		#dma-cells = <1>;
 		dma-channels = <2>;
 	};
@@ -388,6 +406,7 @@
 		reg = <0 0xe6508000 0 0x40>;
 		interrupts = <0 287 IRQ_TYPE_LEVEL_HIGH>;
 		clocks = <&mstp9_clks R8A7791_CLK_I2C0>;
+		power-domains = <&cpg_clocks>;
 		status = "disabled";
 	};
 
@@ -398,6 +417,7 @@
 		reg = <0 0xe6518000 0 0x40>;
 		interrupts = <0 288 IRQ_TYPE_LEVEL_HIGH>;
 		clocks = <&mstp9_clks R8A7791_CLK_I2C1>;
+		power-domains = <&cpg_clocks>;
 		status = "disabled";
 	};
 
@@ -408,6 +428,7 @@
 		reg = <0 0xe6530000 0 0x40>;
 		interrupts = <0 286 IRQ_TYPE_LEVEL_HIGH>;
 		clocks = <&mstp9_clks R8A7791_CLK_I2C2>;
+		power-domains = <&cpg_clocks>;
 		status = "disabled";
 	};
 
@@ -418,6 +439,7 @@
 		reg = <0 0xe6540000 0 0x40>;
 		interrupts = <0 290 IRQ_TYPE_LEVEL_HIGH>;
 		clocks = <&mstp9_clks R8A7791_CLK_I2C3>;
+		power-domains = <&cpg_clocks>;
 		status = "disabled";
 	};
 
@@ -428,6 +450,7 @@
 		reg = <0 0xe6520000 0 0x40>;
 		interrupts = <0 19 IRQ_TYPE_LEVEL_HIGH>;
 		clocks = <&mstp9_clks R8A7791_CLK_I2C4>;
+		power-domains = <&cpg_clocks>;
 		status = "disabled";
 	};
 
@@ -439,6 +462,7 @@
 		reg = <0 0xe6528000 0 0x40>;
 		interrupts = <0 20 IRQ_TYPE_LEVEL_HIGH>;
 		clocks = <&mstp9_clks R8A7791_CLK_I2C5>;
+		power-domains = <&cpg_clocks>;
 		status = "disabled";
 	};
 
@@ -452,6 +476,7 @@
 		clocks = <&mstp9_clks R8A7791_CLK_IICDVFS>;
 		dmas = <&dmac0 0x77>, <&dmac0 0x78>;
 		dma-names = "tx", "rx";
+		power-domains = <&cpg_clocks>;
 		status = "disabled";
 	};
 
@@ -464,6 +489,7 @@
 		clocks = <&mstp3_clks R8A7791_CLK_IIC0>;
 		dmas = <&dmac0 0x61>, <&dmac0 0x62>;
 		dma-names = "tx", "rx";
+		power-domains = <&cpg_clocks>;
 		status = "disabled";
 	};
 
@@ -476,6 +502,7 @@
 		clocks = <&mstp3_clks R8A7791_CLK_IIC1>;
 		dmas = <&dmac0 0x65>, <&dmac0 0x66>;
 		dma-names = "tx", "rx";
+		power-domains = <&cpg_clocks>;
 		status = "disabled";
 	};
 
@@ -492,6 +519,7 @@
 		clocks = <&mstp3_clks R8A7791_CLK_MMCIF0>;
 		dmas = <&dmac0 0xd1>, <&dmac0 0xd2>;
 		dma-names = "tx", "rx";
+		power-domains = <&cpg_clocks>;
 		reg-io-width = <4>;
 		status = "disabled";
 		max-frequency = <97500000>;
@@ -504,6 +532,7 @@
 		clocks = <&mstp3_clks R8A7791_CLK_SDHI0>;
 		dmas = <&dmac1 0xcd>, <&dmac1 0xce>;
 		dma-names = "tx", "rx";
+		power-domains = <&cpg_clocks>;
 		status = "disabled";
 	};
 
@@ -514,6 +543,7 @@
 		clocks = <&mstp3_clks R8A7791_CLK_SDHI1>;
 		dmas = <&dmac1 0xc1>, <&dmac1 0xc2>;
 		dma-names = "tx", "rx";
+		power-domains = <&cpg_clocks>;
 		status = "disabled";
 	};
 
@@ -524,6 +554,7 @@
 		clocks = <&mstp3_clks R8A7791_CLK_SDHI2>;
 		dmas = <&dmac1 0xd3>, <&dmac1 0xd4>;
 		dma-names = "tx", "rx";
+		power-domains = <&cpg_clocks>;
 		status = "disabled";
 	};
 
@@ -535,6 +566,7 @@
 		clock-names = "sci_ick";
 		dmas = <&dmac0 0x21>, <&dmac0 0x22>;
 		dma-names = "tx", "rx";
+		power-domains = <&cpg_clocks>;
 		status = "disabled";
 	};
 
@@ -546,6 +578,7 @@
 		clock-names = "sci_ick";
 		dmas = <&dmac0 0x25>, <&dmac0 0x26>;
 		dma-names = "tx", "rx";
+		power-domains = <&cpg_clocks>;
 		status = "disabled";
 	};
 
@@ -557,6 +590,7 @@
 		clock-names = "sci_ick";
 		dmas = <&dmac0 0x27>, <&dmac0 0x28>;
 		dma-names = "tx", "rx";
+		power-domains = <&cpg_clocks>;
 		status = "disabled";
 	};
 
@@ -568,6 +602,7 @@
 		clock-names = "sci_ick";
 		dmas = <&dmac0 0x1b>, <&dmac0 0x1c>;
 		dma-names = "tx", "rx";
+		power-domains = <&cpg_clocks>;
 		status = "disabled";
 	};
 
@@ -579,6 +614,7 @@
 		clock-names = "sci_ick";
 		dmas = <&dmac0 0x1f>, <&dmac0 0x20>;
 		dma-names = "tx", "rx";
+		power-domains = <&cpg_clocks>;
 		status = "disabled";
 	};
 
@@ -590,6 +626,7 @@
 		clock-names = "sci_ick";
 		dmas = <&dmac0 0x23>, <&dmac0 0x24>;
 		dma-names = "tx", "rx";
+		power-domains = <&cpg_clocks>;
 		status = "disabled";
 	};
 
@@ -601,6 +638,7 @@
 		clock-names = "sci_ick";
 		dmas = <&dmac0 0x3d>, <&dmac0 0x3e>;
 		dma-names = "tx", "rx";
+		power-domains = <&cpg_clocks>;
 		status = "disabled";
 	};
 
@@ -612,6 +650,7 @@
 		clock-names = "sci_ick";
 		dmas = <&dmac0 0x19>, <&dmac0 0x1a>;
 		dma-names = "tx", "rx";
+		power-domains = <&cpg_clocks>;
 		status = "disabled";
 	};
 
@@ -623,6 +662,7 @@
 		clock-names = "sci_ick";
 		dmas = <&dmac0 0x1d>, <&dmac0 0x1e>;
 		dma-names = "tx", "rx";
+		power-domains = <&cpg_clocks>;
 		status = "disabled";
 	};
 
@@ -634,6 +674,7 @@
 		clock-names = "sci_ick";
 		dmas = <&dmac0 0x29>, <&dmac0 0x2a>;
 		dma-names = "tx", "rx";
+		power-domains = <&cpg_clocks>;
 		status = "disabled";
 	};
 
@@ -645,6 +686,7 @@
 		clock-names = "sci_ick";
 		dmas = <&dmac0 0x2d>, <&dmac0 0x2e>;
 		dma-names = "tx", "rx";
+		power-domains = <&cpg_clocks>;
 		status = "disabled";
 	};
 
@@ -656,6 +698,7 @@
 		clock-names = "sci_ick";
 		dmas = <&dmac0 0x2b>, <&dmac0 0x2c>;
 		dma-names = "tx", "rx";
+		power-domains = <&cpg_clocks>;
 		status = "disabled";
 	};
 
@@ -667,6 +710,7 @@
 		clock-names = "sci_ick";
 		dmas = <&dmac0 0x2f>, <&dmac0 0x30>;
 		dma-names = "tx", "rx";
+		power-domains = <&cpg_clocks>;
 		status = "disabled";
 	};
 
@@ -678,6 +722,7 @@
 		clock-names = "sci_ick";
 		dmas = <&dmac0 0xfb>, <&dmac0 0xfc>;
 		dma-names = "tx", "rx";
+		power-domains = <&cpg_clocks>;
 		status = "disabled";
 	};
 
@@ -689,6 +734,7 @@
 		clock-names = "sci_ick";
 		dmas = <&dmac0 0xfd>, <&dmac0 0xfe>;
 		dma-names = "tx", "rx";
+		power-domains = <&cpg_clocks>;
 		status = "disabled";
 	};
 
@@ -700,6 +746,7 @@
 		clock-names = "sci_ick";
 		dmas = <&dmac0 0x39>, <&dmac0 0x3a>;
 		dma-names = "tx", "rx";
+		power-domains = <&cpg_clocks>;
 		status = "disabled";
 	};
 
@@ -711,6 +758,7 @@
 		clock-names = "sci_ick";
 		dmas = <&dmac0 0x4d>, <&dmac0 0x4e>;
 		dma-names = "tx", "rx";
+		power-domains = <&cpg_clocks>;
 		status = "disabled";
 	};
 
@@ -722,6 +770,7 @@
 		clock-names = "sci_ick";
 		dmas = <&dmac0 0x3b>, <&dmac0 0x3c>;
 		dma-names = "tx", "rx";
+		power-domains = <&cpg_clocks>;
 		status = "disabled";
 	};
 
@@ -730,6 +779,7 @@
 		reg = <0 0xee700000 0 0x400>;
 		interrupts = <0 162 IRQ_TYPE_LEVEL_HIGH>;
 		clocks = <&mstp8_clks R8A7791_CLK_ETHER>;
+		power-domains = <&cpg_clocks>;
 		phy-mode = "rmii";
 		#address-cells = <1>;
 		#size-cells = <0>;
@@ -741,6 +791,7 @@
 		reg = <0 0xee300000 0 0x2000>;
 		interrupts = <0 105 IRQ_TYPE_LEVEL_HIGH>;
 		clocks = <&mstp8_clks R8A7791_CLK_SATA0>;
+		power-domains = <&cpg_clocks>;
 		status = "disabled";
 	};
 
@@ -749,6 +800,7 @@
 		reg = <0 0xee500000 0 0x2000>;
 		interrupts = <0 106 IRQ_TYPE_LEVEL_HIGH>;
 		clocks = <&mstp8_clks R8A7791_CLK_SATA1>;
+		power-domains = <&cpg_clocks>;
 		status = "disabled";
 	};
 
@@ -757,12 +809,13 @@
 		reg = <0 0xe6590000 0 0x100>;
 		interrupts = <0 107 IRQ_TYPE_LEVEL_HIGH>;
 		clocks = <&mstp7_clks R8A7791_CLK_HSUSB>;
-		renesas,buswait = <4>;
-		phys = <&usb0 1>;
-		phy-names = "usb";
 		dmas = <&usb_dmac0 0>, <&usb_dmac0 1>,
 		       <&usb_dmac1 0>, <&usb_dmac1 1>;
 		dma-names = "ch0", "ch1", "ch2", "ch3";
+		power-domains = <&cpg_clocks>;
+		renesas,buswait = <4>;
+		phys = <&usb0 1>;
+		phy-names = "usb";
 		status = "disabled";
 	};
 
@@ -773,6 +826,7 @@
 		#size-cells = <0>;
 		clocks = <&mstp7_clks R8A7791_CLK_HSUSB>;
 		clock-names = "usbhs";
+		power-domains = <&cpg_clocks>;
 		status = "disabled";
 
 		usb0: usb-channel at 0 {
@@ -787,25 +841,28 @@
 
 	vin0: video at e6ef0000 {
 		compatible = "renesas,vin-r8a7791";
-		clocks = <&mstp8_clks R8A7791_CLK_VIN0>;
 		reg = <0 0xe6ef0000 0 0x1000>;
 		interrupts = <0 188 IRQ_TYPE_LEVEL_HIGH>;
+		clocks = <&mstp8_clks R8A7791_CLK_VIN0>;
+		power-domains = <&cpg_clocks>;
 		status = "disabled";
 	};
 
 	vin1: video at e6ef1000 {
 		compatible = "renesas,vin-r8a7791";
-		clocks = <&mstp8_clks R8A7791_CLK_VIN1>;
 		reg = <0 0xe6ef1000 0 0x1000>;
 		interrupts = <0 189 IRQ_TYPE_LEVEL_HIGH>;
+		clocks = <&mstp8_clks R8A7791_CLK_VIN1>;
+		power-domains = <&cpg_clocks>;
 		status = "disabled";
 	};
 
 	vin2: video at e6ef2000 {
 		compatible = "renesas,vin-r8a7791";
-		clocks = <&mstp8_clks R8A7791_CLK_VIN2>;
 		reg = <0 0xe6ef2000 0 0x1000>;
 		interrupts = <0 190 IRQ_TYPE_LEVEL_HIGH>;
+		clocks = <&mstp8_clks R8A7791_CLK_VIN2>;
+		power-domains = <&cpg_clocks>;
 		status = "disabled";
 	};
 
@@ -814,6 +871,7 @@
 		reg = <0 0xfe928000 0 0x8000>;
 		interrupts = <0 267 IRQ_TYPE_LEVEL_HIGH>;
 		clocks = <&mstp1_clks R8A7791_CLK_VSP1_S>;
+		power-domains = <&cpg_clocks>;
 
 		renesas,has-lut;
 		renesas,has-sru;
@@ -827,6 +885,7 @@
 		reg = <0 0xfe930000 0 0x8000>;
 		interrupts = <0 246 IRQ_TYPE_LEVEL_HIGH>;
 		clocks = <&mstp1_clks R8A7791_CLK_VSP1_DU0>;
+		power-domains = <&cpg_clocks>;
 
 		renesas,has-lif;
 		renesas,has-lut;
@@ -840,6 +899,7 @@
 		reg = <0 0xfe938000 0 0x8000>;
 		interrupts = <0 247 IRQ_TYPE_LEVEL_HIGH>;
 		clocks = <&mstp1_clks R8A7791_CLK_VSP1_DU1>;
+		power-domains = <&cpg_clocks>;
 
 		renesas,has-lif;
 		renesas,has-lut;
@@ -885,6 +945,7 @@
 		clocks = <&mstp9_clks R8A7791_CLK_RCAN0>,
 			 <&cpg_clocks R8A7791_CLK_RCAN>, <&can_clk>;
 		clock-names = "clkp1", "clkp2", "can_clk";
+		power-domains = <&cpg_clocks>;
 		status = "disabled";
 	};
 
@@ -895,6 +956,7 @@
 		clocks = <&mstp9_clks R8A7791_CLK_RCAN1>,
 			 <&cpg_clocks R8A7791_CLK_RCAN>, <&can_clk>;
 		clock-names = "clkp1", "clkp2", "can_clk";
+		power-domains = <&cpg_clocks>;
 		status = "disabled";
 	};
 
@@ -903,6 +965,7 @@
 		reg = <0 0xfe980000 0 0x10300>;
 		interrupts = <0 272 IRQ_TYPE_LEVEL_HIGH>;
 		clocks = <&mstp1_clks R8A7791_CLK_JPU>;
+		power-domains = <&cpg_clocks>;
 	};
 
 	clocks {
@@ -979,6 +1042,7 @@
 			clock-output-names = "main", "pll0", "pll1", "pll3",
 					     "lb", "qspi", "sdh", "sd0", "z",
 					     "rcan", "adsp";
+			#power-domain-cells = <0>;
 		};
 
 		/* Variable factor clocks */
@@ -1361,6 +1425,7 @@
 		clocks = <&mstp9_clks R8A7791_CLK_QSPI_MOD>;
 		dmas = <&dmac0 0x17>, <&dmac0 0x18>;
 		dma-names = "tx", "rx";
+		power-domains = <&cpg_clocks>;
 		num-cs = <1>;
 		#address-cells = <1>;
 		#size-cells = <0>;
@@ -1374,6 +1439,7 @@
 		clocks = <&mstp0_clks R8A7791_CLK_MSIOF0>;
 		dmas = <&dmac0 0x51>, <&dmac0 0x52>;
 		dma-names = "tx", "rx";
+		power-domains = <&cpg_clocks>;
 		#address-cells = <1>;
 		#size-cells = <0>;
 		status = "disabled";
@@ -1386,6 +1452,7 @@
 		clocks = <&mstp2_clks R8A7791_CLK_MSIOF1>;
 		dmas = <&dmac0 0x55>, <&dmac0 0x56>;
 		dma-names = "tx", "rx";
+		power-domains = <&cpg_clocks>;
 		#address-cells = <1>;
 		#size-cells = <0>;
 		status = "disabled";
@@ -1398,6 +1465,7 @@
 		clocks = <&mstp2_clks R8A7791_CLK_MSIOF2>;
 		dmas = <&dmac0 0x41>, <&dmac0 0x42>;
 		dma-names = "tx", "rx";
+		power-domains = <&cpg_clocks>;
 		#address-cells = <1>;
 		#size-cells = <0>;
 		status = "disabled";
@@ -1408,6 +1476,7 @@
 		reg = <0 0xee000000 0 0xc00>;
 		interrupts = <0 101 IRQ_TYPE_LEVEL_HIGH>;
 		clocks = <&mstp3_clks R8A7791_CLK_SSUSB>;
+		power-domains = <&cpg_clocks>;
 		phys = <&usb2 1>;
 		phy-names = "usb";
 		status = "disabled";
@@ -1416,10 +1485,11 @@
 	pci0: pci at ee090000 {
 		compatible = "renesas,pci-r8a7791";
 		device_type = "pci";
-		clocks = <&mstp7_clks R8A7791_CLK_EHCI>;
 		reg = <0 0xee090000 0 0xc00>,
 		      <0 0xee080000 0 0x1100>;
 		interrupts = <0 108 IRQ_TYPE_LEVEL_HIGH>;
+		clocks = <&mstp7_clks R8A7791_CLK_EHCI>;
+		power-domains = <&cpg_clocks>;
 		status = "disabled";
 
 		bus-range = <0 0>;
@@ -1450,10 +1520,11 @@
 	pci1: pci at ee0d0000 {
 		compatible = "renesas,pci-r8a7791";
 		device_type = "pci";
-		clocks = <&mstp7_clks R8A7791_CLK_EHCI>;
 		reg = <0 0xee0d0000 0 0xc00>,
 		      <0 0xee0c0000 0 0x1100>;
 		interrupts = <0 113 IRQ_TYPE_LEVEL_HIGH>;
+		clocks = <&mstp7_clks R8A7791_CLK_EHCI>;
+		power-domains = <&cpg_clocks>;
 		status = "disabled";
 
 		bus-range = <1 1>;
@@ -1503,6 +1574,7 @@
 		interrupt-map = <0 0 0 0 &gic 0 116 IRQ_TYPE_LEVEL_HIGH>;
 		clocks = <&mstp3_clks R8A7791_CLK_PCIEC>, <&pcie_bus_clk>;
 		clock-names = "pcie", "pcie_bus";
+		power-domains = <&cpg_clocks>;
 		status = "disabled";
 	};
 
-- 
1.9.1



From geert+renesas at glider.be  Tue Aug  4 05:28:09 2015
From: geert+renesas at glider.be (Geert Uytterhoeven)
Date: Tue,  4 Aug 2015 14:28:09 +0200
Subject: [PATCH v4 08/16] ARM: shmobile: r8a7779 dtsi: Add CPG/MSTP Clock
 Domain
In-Reply-To: <1438691297-29235-1-git-send-email-geert+renesas@glider.be>
References: <1438691297-29235-1-git-send-email-geert+renesas@glider.be>
Message-ID: <1438691297-29235-9-git-send-email-geert+renesas@glider.be>

Add an appropriate "#power-domain-cells" property to the cpg_clocks
device node, to create the CPG/MSTP Clock Domain.

Add "power-domains" properties to all device nodes for devices that are
part of the CPG/MSTP Clock Domain and can be power-managed through an
MSTP clock.  This applies to most on-SoC devices, which have a
one-to-one mapping from SoC device to DT device node.

Signed-off-by: Geert Uytterhoeven <geert+renesas at glider.be>
Reviewed-by: Ulf Hansson <ulf.hansson at linaro.org>
---
v4:
  - Add Reviewed-by,

v3:
  - Use "CPG/MSTP Clock Domain" instead of "CPG Clock Domain",

v2:
  - New.
---
 arch/arm/boot/dts/r8a7779.dtsi | 23 +++++++++++++++++++++++
 1 file changed, 23 insertions(+)

diff --git a/arch/arm/boot/dts/r8a7779.dtsi b/arch/arm/boot/dts/r8a7779.dtsi
index a2b5430d32575f99..6afa909865b52b71 100644
--- a/arch/arm/boot/dts/r8a7779.dtsi
+++ b/arch/arm/boot/dts/r8a7779.dtsi
@@ -173,6 +173,7 @@
 		reg = <0xffc70000 0x1000>;
 		interrupts = <0 79 IRQ_TYPE_LEVEL_HIGH>;
 		clocks = <&mstp0_clks R8A7779_CLK_I2C0>;
+		power-domains = <&cpg_clocks>;
 		status = "disabled";
 	};
 
@@ -183,6 +184,7 @@
 		reg = <0xffc71000 0x1000>;
 		interrupts = <0 82 IRQ_TYPE_LEVEL_HIGH>;
 		clocks = <&mstp0_clks R8A7779_CLK_I2C1>;
+		power-domains = <&cpg_clocks>;
 		status = "disabled";
 	};
 
@@ -193,6 +195,7 @@
 		reg = <0xffc72000 0x1000>;
 		interrupts = <0 80 IRQ_TYPE_LEVEL_HIGH>;
 		clocks = <&mstp0_clks R8A7779_CLK_I2C2>;
+		power-domains = <&cpg_clocks>;
 		status = "disabled";
 	};
 
@@ -203,6 +206,7 @@
 		reg = <0xffc73000 0x1000>;
 		interrupts = <0 81 IRQ_TYPE_LEVEL_HIGH>;
 		clocks = <&mstp0_clks R8A7779_CLK_I2C3>;
+		power-domains = <&cpg_clocks>;
 		status = "disabled";
 	};
 
@@ -212,6 +216,7 @@
 		interrupts = <0 88 IRQ_TYPE_LEVEL_HIGH>;
 		clocks = <&mstp0_clks R8A7779_CLK_SCIF0>;
 		clock-names = "sci_ick";
+		power-domains = <&cpg_clocks>;
 		status = "disabled";
 	};
 
@@ -221,6 +226,7 @@
 		interrupts = <0 89 IRQ_TYPE_LEVEL_HIGH>;
 		clocks = <&mstp0_clks R8A7779_CLK_SCIF1>;
 		clock-names = "sci_ick";
+		power-domains = <&cpg_clocks>;
 		status = "disabled";
 	};
 
@@ -230,6 +236,7 @@
 		interrupts = <0 90 IRQ_TYPE_LEVEL_HIGH>;
 		clocks = <&mstp0_clks R8A7779_CLK_SCIF2>;
 		clock-names = "sci_ick";
+		power-domains = <&cpg_clocks>;
 		status = "disabled";
 	};
 
@@ -239,6 +246,7 @@
 		interrupts = <0 91 IRQ_TYPE_LEVEL_HIGH>;
 		clocks = <&mstp0_clks R8A7779_CLK_SCIF3>;
 		clock-names = "sci_ick";
+		power-domains = <&cpg_clocks>;
 		status = "disabled";
 	};
 
@@ -248,6 +256,7 @@
 		interrupts = <0 92 IRQ_TYPE_LEVEL_HIGH>;
 		clocks = <&mstp0_clks R8A7779_CLK_SCIF4>;
 		clock-names = "sci_ick";
+		power-domains = <&cpg_clocks>;
 		status = "disabled";
 	};
 
@@ -257,6 +266,7 @@
 		interrupts = <0 93 IRQ_TYPE_LEVEL_HIGH>;
 		clocks = <&mstp0_clks R8A7779_CLK_SCIF5>;
 		clock-names = "sci_ick";
+		power-domains = <&cpg_clocks>;
 		status = "disabled";
 	};
 
@@ -278,6 +288,7 @@
 			     <0 34 IRQ_TYPE_LEVEL_HIGH>;
 		clocks = <&mstp0_clks R8A7779_CLK_TMU0>;
 		clock-names = "fck";
+		power-domains = <&cpg_clocks>;
 
 		#renesas,channels = <3>;
 
@@ -292,6 +303,7 @@
 			     <0 38 IRQ_TYPE_LEVEL_HIGH>;
 		clocks = <&mstp0_clks R8A7779_CLK_TMU1>;
 		clock-names = "fck";
+		power-domains = <&cpg_clocks>;
 
 		#renesas,channels = <3>;
 
@@ -306,6 +318,7 @@
 			     <0 42 IRQ_TYPE_LEVEL_HIGH>;
 		clocks = <&mstp0_clks R8A7779_CLK_TMU2>;
 		clock-names = "fck";
+		power-domains = <&cpg_clocks>;
 
 		#renesas,channels = <3>;
 
@@ -317,6 +330,7 @@
 		reg = <0xfc600000 0x2000>;
 		interrupts = <0 100 IRQ_TYPE_LEVEL_HIGH>;
 		clocks = <&mstp1_clks R8A7779_CLK_SATA>;
+		power-domains = <&cpg_clocks>;
 	};
 
 	sdhi0: sd at ffe4c000 {
@@ -324,6 +338,7 @@
 		reg = <0xffe4c000 0x100>;
 		interrupts = <0 104 IRQ_TYPE_LEVEL_HIGH>;
 		clocks = <&mstp3_clks R8A7779_CLK_SDHI0>;
+		power-domains = <&cpg_clocks>;
 		status = "disabled";
 	};
 
@@ -332,6 +347,7 @@
 		reg = <0xffe4d000 0x100>;
 		interrupts = <0 105 IRQ_TYPE_LEVEL_HIGH>;
 		clocks = <&mstp3_clks R8A7779_CLK_SDHI1>;
+		power-domains = <&cpg_clocks>;
 		status = "disabled";
 	};
 
@@ -340,6 +356,7 @@
 		reg = <0xffe4e000 0x100>;
 		interrupts = <0 107 IRQ_TYPE_LEVEL_HIGH>;
 		clocks = <&mstp3_clks R8A7779_CLK_SDHI2>;
+		power-domains = <&cpg_clocks>;
 		status = "disabled";
 	};
 
@@ -348,6 +365,7 @@
 		reg = <0xffe4f000 0x100>;
 		interrupts = <0 106 IRQ_TYPE_LEVEL_HIGH>;
 		clocks = <&mstp3_clks R8A7779_CLK_SDHI3>;
+		power-domains = <&cpg_clocks>;
 		status = "disabled";
 	};
 
@@ -358,6 +376,7 @@
 		#address-cells = <1>;
 		#size-cells = <0>;
 		clocks = <&mstp0_clks R8A7779_CLK_HSPI>;
+		power-domains = <&cpg_clocks>;
 		status = "disabled";
 	};
 
@@ -368,6 +387,7 @@
 		#address-cells = <1>;
 		#size-cells = <0>;
 		clocks = <&mstp0_clks R8A7779_CLK_HSPI>;
+		power-domains = <&cpg_clocks>;
 		status = "disabled";
 	};
 
@@ -378,6 +398,7 @@
 		#address-cells = <1>;
 		#size-cells = <0>;
 		clocks = <&mstp0_clks R8A7779_CLK_HSPI>;
+		power-domains = <&cpg_clocks>;
 		status = "disabled";
 	};
 
@@ -386,6 +407,7 @@
 		reg = <0 0xfff80000 0 0x40000>;
 		interrupts = <0 31 IRQ_TYPE_LEVEL_HIGH>;
 		clocks = <&mstp1_clks R8A7779_CLK_DU>;
+		power-domains = <&cpg_clocks>;
 		status = "disabled";
 
 		ports {
@@ -427,6 +449,7 @@
 			#clock-cells = <1>;
 			clock-output-names = "plla", "z", "zs", "s",
 					     "s1", "p", "b", "out";
+			#power-domain-cells = <0>;
 		};
 
 		/* Fixed factor clocks */
-- 
1.9.1



From geert+renesas at glider.be  Tue Aug  4 05:28:13 2015
From: geert+renesas at glider.be (Geert Uytterhoeven)
Date: Tue,  4 Aug 2015 14:28:13 +0200
Subject: [PATCH v4 12/16] ARM: shmobile: r8a7794 dtsi: Add CPG/MSTP Clock
 Domain
In-Reply-To: <1438691297-29235-1-git-send-email-geert+renesas@glider.be>
References: <1438691297-29235-1-git-send-email-geert+renesas@glider.be>
Message-ID: <1438691297-29235-13-git-send-email-geert+renesas@glider.be>

Add an appropriate "#power-domain-cells" property to the cpg_clocks
device node, to create the CPG/MSTP Clock Domain.

Add "power-domains" properties to all device nodes for devices that are
part of the CPG/MSTP Clock Domain and can be power-managed through an
MSTP clock.  This applies to most on-SoC devices, which have a
one-to-one mapping from SoC device to DT device node.

Signed-off-by: Geert Uytterhoeven <geert+renesas at glider.be>
Reviewed-by: Ulf Hansson <ulf.hansson at linaro.org>
---
v4:
  - Add "power-domains" properties to recently introduced mmcif0 device
    node,
  - Consistently add "power-domains" properties after clock and dma
    properties,

v3:
  - Use "CPG/MSTP Clock Domain" instead of "CPG Clock Domain",

v2:
  - Add Reviewed-by,
  - Add "power-domains" properties to recently introduced USB-DMAC
    device nodes,
  - Drop adding "power-domains" properties to the GIC device node, as
    adding the INTC_SYS clock is postponed.
---
 arch/arm/boot/dts/r8a7794.dtsi | 29 +++++++++++++++++++++++++++++
 1 file changed, 29 insertions(+)

diff --git a/arch/arm/boot/dts/r8a7794.dtsi b/arch/arm/boot/dts/r8a7794.dtsi
index 43acf185ecc43f40..97c8e9ace5ebee1e 100644
--- a/arch/arm/boot/dts/r8a7794.dtsi
+++ b/arch/arm/boot/dts/r8a7794.dtsi
@@ -57,6 +57,7 @@
 			     <0 143 IRQ_TYPE_LEVEL_HIGH>;
 		clocks = <&mstp1_clks R8A7794_CLK_CMT0>;
 		clock-names = "fck";
+		power-domains = <&cpg_clocks>;
 
 		renesas,channels-mask = <0x60>;
 
@@ -76,6 +77,7 @@
 			     <0 127 IRQ_TYPE_LEVEL_HIGH>;
 		clocks = <&mstp3_clks R8A7794_CLK_CMT1>;
 		clock-names = "fck";
+		power-domains = <&cpg_clocks>;
 
 		renesas,channels-mask = <0xff>;
 
@@ -106,6 +108,7 @@
 			     <0 16 IRQ_TYPE_LEVEL_HIGH>,
 			     <0 17 IRQ_TYPE_LEVEL_HIGH>;
 		clocks = <&mstp4_clks R8A7794_CLK_IRQC>;
+		power-domains = <&cpg_clocks>;
 	};
 
 	pfc: pin-controller at e6060000 {
@@ -140,6 +143,7 @@
 				"ch12", "ch13", "ch14";
 		clocks = <&mstp2_clks R8A7794_CLK_SYS_DMAC0>;
 		clock-names = "fck";
+		power-domains = <&cpg_clocks>;
 		#dma-cells = <1>;
 		dma-channels = <15>;
 	};
@@ -170,6 +174,7 @@
 				"ch12", "ch13", "ch14";
 		clocks = <&mstp2_clks R8A7794_CLK_SYS_DMAC1>;
 		clock-names = "fck";
+		power-domains = <&cpg_clocks>;
 		#dma-cells = <1>;
 		dma-channels = <15>;
 	};
@@ -182,6 +187,7 @@
 		clock-names = "sci_ick";
 		dmas = <&dmac0 0x21>, <&dmac0 0x22>;
 		dma-names = "tx", "rx";
+		power-domains = <&cpg_clocks>;
 		status = "disabled";
 	};
 
@@ -193,6 +199,7 @@
 		clock-names = "sci_ick";
 		dmas = <&dmac0 0x25>, <&dmac0 0x26>;
 		dma-names = "tx", "rx";
+		power-domains = <&cpg_clocks>;
 		status = "disabled";
 	};
 
@@ -204,6 +211,7 @@
 		clock-names = "sci_ick";
 		dmas = <&dmac0 0x27>, <&dmac0 0x28>;
 		dma-names = "tx", "rx";
+		power-domains = <&cpg_clocks>;
 		status = "disabled";
 	};
 
@@ -215,6 +223,7 @@
 		clock-names = "sci_ick";
 		dmas = <&dmac0 0x1b>, <&dmac0 0x1c>;
 		dma-names = "tx", "rx";
+		power-domains = <&cpg_clocks>;
 		status = "disabled";
 	};
 
@@ -226,6 +235,7 @@
 		clock-names = "sci_ick";
 		dmas = <&dmac0 0x1f>, <&dmac0 0x20>;
 		dma-names = "tx", "rx";
+		power-domains = <&cpg_clocks>;
 		status = "disabled";
 	};
 
@@ -237,6 +247,7 @@
 		clock-names = "sci_ick";
 		dmas = <&dmac0 0x23>, <&dmac0 0x24>;
 		dma-names = "tx", "rx";
+		power-domains = <&cpg_clocks>;
 		status = "disabled";
 	};
 
@@ -248,6 +259,7 @@
 		clock-names = "sci_ick";
 		dmas = <&dmac0 0x3d>, <&dmac0 0x3e>;
 		dma-names = "tx", "rx";
+		power-domains = <&cpg_clocks>;
 		status = "disabled";
 	};
 
@@ -259,6 +271,7 @@
 		clock-names = "sci_ick";
 		dmas = <&dmac0 0x19>, <&dmac0 0x1a>;
 		dma-names = "tx", "rx";
+		power-domains = <&cpg_clocks>;
 		status = "disabled";
 	};
 
@@ -270,6 +283,7 @@
 		clock-names = "sci_ick";
 		dmas = <&dmac0 0x1d>, <&dmac0 0x1e>;
 		dma-names = "tx", "rx";
+		power-domains = <&cpg_clocks>;
 		status = "disabled";
 	};
 
@@ -281,6 +295,7 @@
 		clock-names = "sci_ick";
 		dmas = <&dmac0 0x29>, <&dmac0 0x2a>;
 		dma-names = "tx", "rx";
+		power-domains = <&cpg_clocks>;
 		status = "disabled";
 	};
 
@@ -292,6 +307,7 @@
 		clock-names = "sci_ick";
 		dmas = <&dmac0 0x2d>, <&dmac0 0x2e>;
 		dma-names = "tx", "rx";
+		power-domains = <&cpg_clocks>;
 		status = "disabled";
 	};
 
@@ -303,6 +319,7 @@
 		clock-names = "sci_ick";
 		dmas = <&dmac0 0x2b>, <&dmac0 0x2c>;
 		dma-names = "tx", "rx";
+		power-domains = <&cpg_clocks>;
 		status = "disabled";
 	};
 
@@ -314,6 +331,7 @@
 		clock-names = "sci_ick";
 		dmas = <&dmac0 0x2f>, <&dmac0 0x30>;
 		dma-names = "tx", "rx";
+		power-domains = <&cpg_clocks>;
 		status = "disabled";
 	};
 
@@ -325,6 +343,7 @@
 		clock-names = "sci_ick";
 		dmas = <&dmac0 0xfb>, <&dmac0 0xfc>;
 		dma-names = "tx", "rx";
+		power-domains = <&cpg_clocks>;
 		status = "disabled";
 	};
 
@@ -336,6 +355,7 @@
 		clock-names = "sci_ick";
 		dmas = <&dmac0 0xfd>, <&dmac0 0xfe>;
 		dma-names = "tx", "rx";
+		power-domains = <&cpg_clocks>;
 		status = "disabled";
 	};
 
@@ -347,6 +367,7 @@
 		clock-names = "sci_ick";
 		dmas = <&dmac0 0x39>, <&dmac0 0x3a>;
 		dma-names = "tx", "rx";
+		power-domains = <&cpg_clocks>;
 		status = "disabled";
 	};
 
@@ -358,6 +379,7 @@
 		clock-names = "sci_ick";
 		dmas = <&dmac0 0x4d>, <&dmac0 0x4e>;
 		dma-names = "tx", "rx";
+		power-domains = <&cpg_clocks>;
 		status = "disabled";
 	};
 
@@ -369,6 +391,7 @@
 		clock-names = "sci_ick";
 		dmas = <&dmac0 0x3b>, <&dmac0 0x3c>;
 		dma-names = "tx", "rx";
+		power-domains = <&cpg_clocks>;
 		status = "disabled";
 	};
 
@@ -377,6 +400,7 @@
 		reg = <0 0xee700000 0 0x400>;
 		interrupts = <0 162 IRQ_TYPE_LEVEL_HIGH>;
 		clocks = <&mstp8_clks R8A7794_CLK_ETHER>;
+		power-domains = <&cpg_clocks>;
 		phy-mode = "rmii";
 		#address-cells = <1>;
 		#size-cells = <0>;
@@ -390,6 +414,7 @@
 		clocks = <&mstp3_clks R8A7794_CLK_MMCIF0>;
 		dmas = <&dmac0 0xd1>, <&dmac0 0xd2>;
 		dma-names = "tx", "rx";
+		power-domains = <&cpg_clocks>;
 		reg-io-width = <4>;
 		status = "disabled";
 	};
@@ -399,6 +424,7 @@
 		reg = <0 0xee100000 0 0x200>;
 		interrupts = <0 165 IRQ_TYPE_LEVEL_HIGH>;
 		clocks = <&mstp3_clks R8A7794_CLK_SDHI0>;
+		power-domains = <&cpg_clocks>;
 		status = "disabled";
 	};
 
@@ -407,6 +433,7 @@
 		reg = <0 0xee140000 0 0x100>;
 		interrupts = <0 167 IRQ_TYPE_LEVEL_HIGH>;
 		clocks = <&mstp3_clks R8A7794_CLK_SDHI1>;
+		power-domains = <&cpg_clocks>;
 		status = "disabled";
 	};
 
@@ -415,6 +442,7 @@
 		reg = <0 0xee160000 0 0x100>;
 		interrupts = <0 168 IRQ_TYPE_LEVEL_HIGH>;
 		clocks = <&mstp3_clks R8A7794_CLK_SDHI2>;
+		power-domains = <&cpg_clocks>;
 		status = "disabled";
 	};
 
@@ -441,6 +469,7 @@
 			#clock-cells = <1>;
 			clock-output-names = "main", "pll0", "pll1", "pll3",
 					     "lb", "qspi", "sdh", "sd0", "z";
+			#power-domain-cells = <0>;
 		};
 		/* Variable factor clocks */
 		sd2_clk: sd2_clk at e6150078 {
-- 
1.9.1



From geert+renesas at glider.be  Tue Aug  4 05:28:15 2015
From: geert+renesas at glider.be (Geert Uytterhoeven)
Date: Tue,  4 Aug 2015 14:28:15 +0200
Subject: [PATCH v4 14/16] drivers: sh: Disable PM runtime for multi-platform
 ARM with genpd
In-Reply-To: <1438691297-29235-1-git-send-email-geert+renesas@glider.be>
References: <1438691297-29235-1-git-send-email-geert+renesas@glider.be>
Message-ID: <1438691297-29235-15-git-send-email-geert+renesas@glider.be>

If the default PM Domain using PM_CLK is used for PM runtime, the real
Clock Domain cannot be registered from DT later.

Hence do not enable it when running a multi-platform kernel with genpd
support on R-Car or RZ.  The CPG/MSTP Clock Domain driver will take care
of PM runtime management of the module clocks.

Now most multi-platform ARM shmobile platforms (SH-Mobile, R-Mobile,
R-Car, RZ) use DT-based PM Domains to take care of PM runtime management
of the module clocks, simplify the platform logic by replacing the
explicit SoC checks by a single check for the presence of MSTP clocks in
DT.

Backwards-compatiblity with old DTs (mainly for R-Car Gen2) is provided
by checking for the presence of a "#power-domain-cells" property in DT.

The default PM Domain is still needed for:
  - backwards-compatibility with old DTs that lack PM Domain properties,
  - the CONFIG_PM=n case,
  - legacy (non-DT) ARM/shmobile platforms without genpd support
    (r8a7778, r8a7779),
  - legacy SuperH.

Signed-off-by: Geert Uytterhoeven <geert+renesas at glider.be>
Reviewed-by: Ulf Hansson <ulf.hansson at linaro.org>
---
v4:
  - No changes,

v3:
  - The runtime check must stay for the ARM multiplatform CONFIG_PM=n
    case, to prevent the code from running on non-shmobile machines,
  - Provide backwards-compatibility with old DTs,
  - Extract EMMA Mobile EV2 removal into a separate patch,
  - Replace explicit platform checks by a check for the presence of MSTP
    clocks,
  - Drop references to legacy r8a7740/sh73a0, which are gone,
  - Rephrase description,

v2:
  - Add Reviewed-by,
  - Just stop compiling pm_runtime.c instead of using a runtime check,
    as no multi-platform ARM platforms need this anymore.
---
 drivers/sh/pm_runtime.c | 18 +++++-------------
 1 file changed, 5 insertions(+), 13 deletions(-)

diff --git a/drivers/sh/pm_runtime.c b/drivers/sh/pm_runtime.c
index ad9188138ed56ffb..25abd4eb7d102113 100644
--- a/drivers/sh/pm_runtime.c
+++ b/drivers/sh/pm_runtime.c
@@ -35,19 +35,11 @@ static struct pm_clk_notifier_block platform_bus_notifier = {
 static int __init sh_pm_runtime_init(void)
 {
 	if (IS_ENABLED(CONFIG_ARCH_SHMOBILE_MULTI)) {
-		if (!of_machine_is_compatible("renesas,r7s72100") &&
-#ifndef CONFIG_PM_GENERIC_DOMAINS_OF
-		    !of_machine_is_compatible("renesas,r8a73a4") &&
-		    !of_machine_is_compatible("renesas,r8a7740") &&
-		    !of_machine_is_compatible("renesas,sh73a0") &&
-#endif
-		    !of_machine_is_compatible("renesas,r8a7778") &&
-		    !of_machine_is_compatible("renesas,r8a7779") &&
-		    !of_machine_is_compatible("renesas,r8a7790") &&
-		    !of_machine_is_compatible("renesas,r8a7791") &&
-		    !of_machine_is_compatible("renesas,r8a7792") &&
-		    !of_machine_is_compatible("renesas,r8a7793") &&
-		    !of_machine_is_compatible("renesas,r8a7794"))
+		if (!of_find_compatible_node(NULL, NULL,
+					     "renesas,cpg-mstp-clocks"))
+			return 0;
+		if (IS_ENABLED(CONFIG_PM_GENERIC_DOMAINS_OF) &&
+		    of_find_node_with_property(NULL, "#power-domain-cells"))
 			return 0;
 	}
 
-- 
1.9.1



From geert+renesas at glider.be  Tue Aug  4 05:28:03 2015
From: geert+renesas at glider.be (Geert Uytterhoeven)
Date: Tue,  4 Aug 2015 14:28:03 +0200
Subject: [PATCH v4 02/16] clk: shmobile: r8a7778: Add CPG/MSTP Clock Domain
 support
In-Reply-To: <1438691297-29235-1-git-send-email-geert+renesas@glider.be>
References: <1438691297-29235-1-git-send-email-geert+renesas@glider.be>
Message-ID: <1438691297-29235-3-git-send-email-geert+renesas@glider.be>

Add Clock Domain support to the R-Car M1A Clock Pulse Generator (CPG)
driver using the generic PM Domain.  This allows to power-manage the
module clocks of SoC devices that are part of the CPG/MSTP Clock Domain
using Runtime PM, or for system suspend/resume.

SoC devices that are part of the CPG/MSTP Clock Domain and can be
power-managed through an MSTP clock should be tagged in DT with a proper
"power-domains" property.

Signed-off-by: Geert Uytterhoeven <geert+renesas at glider.be>
Acked-by: Stephen Boyd <sboyd at codeaurora.org>
Reviewed-by: Ulf Hansson <ulf.hansson at linaro.org>
---
v4:
  - Add Reviewed-by,

v3:
  - Add Acked-by,
  - Use "CPG/MSTP Clock Domain" instead of "CPG Clock Domain",

v2:
  - New.
---
 .../bindings/clock/renesas,r8a7778-cpg-clocks.txt  | 29 +++++++++++++++++++---
 arch/arm/mach-shmobile/Kconfig                     |  1 +
 drivers/clk/shmobile/clk-r8a7778.c                 |  2 ++
 3 files changed, 29 insertions(+), 3 deletions(-)

diff --git a/Documentation/devicetree/bindings/clock/renesas,r8a7778-cpg-clocks.txt b/Documentation/devicetree/bindings/clock/renesas,r8a7778-cpg-clocks.txt
index 2f3747fdcf1c5305..e4cdaf1cb3333012 100644
--- a/Documentation/devicetree/bindings/clock/renesas,r8a7778-cpg-clocks.txt
+++ b/Documentation/devicetree/bindings/clock/renesas,r8a7778-cpg-clocks.txt
@@ -1,7 +1,9 @@
 * Renesas R8A7778 Clock Pulse Generator (CPG)
 
 The CPG generates core clocks for the R8A7778. It includes two PLLs and
-several fixed ratio dividers
+several fixed ratio dividers.
+The CPG also provides a Clock Domain for SoC devices, in combination with the
+CPG Module Stop (MSTP) Clocks.
 
 Required Properties:
 
@@ -10,10 +12,18 @@ Required Properties:
   - #clock-cells: Must be 1
   - clock-output-names: The names of the clocks. Supported clocks are
     "plla", "pllb", "b", "out", "p", "s", and "s1".
+  - #power-domain-cells: Must be 0
 
+SoC devices that are part of the CPG/MSTP Clock Domain and can be power-managed
+through an MSTP clock should refer to the CPG device node in their
+"power-domains" property, as documented by the generic PM domain bindings in
+Documentation/devicetree/bindings/power/power_domain.txt.
 
-Example
--------
+
+Examples
+--------
+
+  - CPG device node:
 
 	cpg_clocks: cpg_clocks at ffc80000 {
 		compatible = "renesas,r8a7778-cpg-clocks";
@@ -22,4 +32,17 @@ Example
 		clocks = <&extal_clk>;
 		clock-output-names = "plla", "pllb", "b",
 				     "out", "p", "s", "s1";
+		#power-domain-cells = <0>;
+	};
+
+
+  - CPG/MSTP Clock Domain member device node:
+
+	sdhi0: sd at ffe4c000 {
+		compatible = "renesas,sdhi-r8a7778";
+		reg = <0xffe4c000 0x100>;
+		interrupts = <0 87 IRQ_TYPE_LEVEL_HIGH>;
+		clocks = <&mstp3_clks R8A7778_CLK_SDHI0>;
+		power-domains = <&cpg_clocks>;
+		status = "disabled";
 	};
diff --git a/arch/arm/mach-shmobile/Kconfig b/arch/arm/mach-shmobile/Kconfig
index aa38a438af8990ef..5b1f9eca7c871aee 100644
--- a/arch/arm/mach-shmobile/Kconfig
+++ b/arch/arm/mach-shmobile/Kconfig
@@ -4,6 +4,7 @@ config ARCH_SHMOBILE
 
 config PM_RCAR
 	bool
+	select PM_GENERIC_DOMAINS if PM
 
 config PM_RMOBILE
 	bool
diff --git a/drivers/clk/shmobile/clk-r8a7778.c b/drivers/clk/shmobile/clk-r8a7778.c
index e97e28fcfc13d102..87c1d2f2fb57a46c 100644
--- a/drivers/clk/shmobile/clk-r8a7778.c
+++ b/drivers/clk/shmobile/clk-r8a7778.c
@@ -124,6 +124,8 @@ static void __init r8a7778_cpg_clocks_init(struct device_node *np)
 	}
 
 	of_clk_add_provider(np, of_clk_src_onecell_get, &cpg->data);
+
+	cpg_mstp_add_clk_domain(np);
 }
 
 CLK_OF_DECLARE(r8a7778_cpg_clks, "renesas,r8a7778-cpg-clocks",
-- 
1.9.1



From geert+renesas at glider.be  Tue Aug  4 05:28:10 2015
From: geert+renesas at glider.be (Geert Uytterhoeven)
Date: Tue,  4 Aug 2015 14:28:10 +0200
Subject: [PATCH v4 09/16] ARM: shmobile: r8a7790 dtsi: Add CPG/MSTP Clock
 Domain
In-Reply-To: <1438691297-29235-1-git-send-email-geert+renesas@glider.be>
References: <1438691297-29235-1-git-send-email-geert+renesas@glider.be>
Message-ID: <1438691297-29235-10-git-send-email-geert+renesas@glider.be>

Add an appropriate "#power-domain-cells" property to the cpg_clocks
device node, to create the CPG/MSTP Clock Domain.

Add "power-domains" properties to all device nodes for devices that are
part of the CPG/MSTP Clock Domain and can be power-managed through an
MSTP clock.  This applies to most on-SoC devices, which have a
one-to-one mapping from SoC device to DT device node.  Notable
exceptions are the "display" and "sound" nodes, which represent multiple
SoC devices, each having their own MSTP clocks.

Signed-off-by: Geert Uytterhoeven <geert+renesas at glider.be>
Reviewed-by: Ulf Hansson <ulf.hansson at linaro.org>
---
v4:
  - Add "power-domains" properties to recently introduced jpu device
    node,
  - Consistently add "power-domains" properties after clock and dma
    properties,

v3:
  - Add "power-domains" property to recently introduced Ethernet AVB
    device node,
  - Use "CPG/MSTP Clock Domain" instead of "CPG Clock Domain",

v2:
  - Add Reviewed-by,
  - Add "power-domains" properties to recently introduced USB-DMAC
    device nodes,
  - Drop adding "power-domains" properties to the GIC device node, as
    adding the INTC_SYS clock is postponed.
---
 arch/arm/boot/dts/r8a7790.dtsi | 86 +++++++++++++++++++++++++++++++++++++-----
 1 file changed, 77 insertions(+), 9 deletions(-)

diff --git a/arch/arm/boot/dts/r8a7790.dtsi b/arch/arm/boot/dts/r8a7790.dtsi
index 5b2952d5c700fabe..a0b2a79cbfbdf0b4 100644
--- a/arch/arm/boot/dts/r8a7790.dtsi
+++ b/arch/arm/boot/dts/r8a7790.dtsi
@@ -134,6 +134,7 @@
 		#interrupt-cells = <2>;
 		interrupt-controller;
 		clocks = <&mstp9_clks R8A7790_CLK_GPIO0>;
+		power-domains = <&cpg_clocks>;
 	};
 
 	gpio1: gpio at e6051000 {
@@ -146,6 +147,7 @@
 		#interrupt-cells = <2>;
 		interrupt-controller;
 		clocks = <&mstp9_clks R8A7790_CLK_GPIO1>;
+		power-domains = <&cpg_clocks>;
 	};
 
 	gpio2: gpio at e6052000 {
@@ -158,6 +160,7 @@
 		#interrupt-cells = <2>;
 		interrupt-controller;
 		clocks = <&mstp9_clks R8A7790_CLK_GPIO2>;
+		power-domains = <&cpg_clocks>;
 	};
 
 	gpio3: gpio at e6053000 {
@@ -170,6 +173,7 @@
 		#interrupt-cells = <2>;
 		interrupt-controller;
 		clocks = <&mstp9_clks R8A7790_CLK_GPIO3>;
+		power-domains = <&cpg_clocks>;
 	};
 
 	gpio4: gpio at e6054000 {
@@ -182,6 +186,7 @@
 		#interrupt-cells = <2>;
 		interrupt-controller;
 		clocks = <&mstp9_clks R8A7790_CLK_GPIO4>;
+		power-domains = <&cpg_clocks>;
 	};
 
 	gpio5: gpio at e6055000 {
@@ -194,6 +199,7 @@
 		#interrupt-cells = <2>;
 		interrupt-controller;
 		clocks = <&mstp9_clks R8A7790_CLK_GPIO5>;
+		power-domains = <&cpg_clocks>;
 	};
 
 	thermal at e61f0000 {
@@ -201,6 +207,7 @@
 		reg = <0 0xe61f0000 0 0x14>, <0 0xe61f0100 0 0x38>;
 		interrupts = <0 69 IRQ_TYPE_LEVEL_HIGH>;
 		clocks = <&mstp5_clks R8A7790_CLK_THERMAL>;
+		power-domains = <&cpg_clocks>;
 	};
 
 	timer {
@@ -218,6 +225,7 @@
 			     <0 143 IRQ_TYPE_LEVEL_HIGH>;
 		clocks = <&mstp1_clks R8A7790_CLK_CMT0>;
 		clock-names = "fck";
+		power-domains = <&cpg_clocks>;
 
 		renesas,channels-mask = <0x60>;
 
@@ -237,6 +245,7 @@
 			     <0 127 IRQ_TYPE_LEVEL_HIGH>;
 		clocks = <&mstp3_clks R8A7790_CLK_CMT1>;
 		clock-names = "fck";
+		power-domains = <&cpg_clocks>;
 
 		renesas,channels-mask = <0xff>;
 
@@ -253,6 +262,7 @@
 			     <0 2 IRQ_TYPE_LEVEL_HIGH>,
 			     <0 3 IRQ_TYPE_LEVEL_HIGH>;
 		clocks = <&mstp4_clks R8A7790_CLK_IRQC>;
+		power-domains = <&cpg_clocks>;
 	};
 
 	dmac0: dma-controller at e6700000 {
@@ -281,6 +291,7 @@
 				"ch12", "ch13", "ch14";
 		clocks = <&mstp2_clks R8A7790_CLK_SYS_DMAC0>;
 		clock-names = "fck";
+		power-domains = <&cpg_clocks>;
 		#dma-cells = <1>;
 		dma-channels = <15>;
 	};
@@ -311,6 +322,7 @@
 				"ch12", "ch13", "ch14";
 		clocks = <&mstp2_clks R8A7790_CLK_SYS_DMAC1>;
 		clock-names = "fck";
+		power-domains = <&cpg_clocks>;
 		#dma-cells = <1>;
 		dma-channels = <15>;
 	};
@@ -339,6 +351,7 @@
 				"ch12";
 		clocks = <&mstp5_clks R8A7790_CLK_AUDIO_DMAC0>;
 		clock-names = "fck";
+		power-domains = <&cpg_clocks>;
 		#dma-cells = <1>;
 		dma-channels = <13>;
 	};
@@ -367,6 +380,7 @@
 				"ch12";
 		clocks = <&mstp5_clks R8A7790_CLK_AUDIO_DMAC1>;
 		clock-names = "fck";
+		power-domains = <&cpg_clocks>;
 		#dma-cells = <1>;
 		dma-channels = <13>;
 	};
@@ -378,6 +392,7 @@
 			      0 109 IRQ_TYPE_LEVEL_HIGH>;
 		interrupt-names = "ch0", "ch1";
 		clocks = <&mstp3_clks R8A7790_CLK_USBDMAC0>;
+		power-domains = <&cpg_clocks>;
 		#dma-cells = <1>;
 		dma-channels = <2>;
 	};
@@ -389,6 +404,7 @@
 			      0 110 IRQ_TYPE_LEVEL_HIGH>;
 		interrupt-names = "ch0", "ch1";
 		clocks = <&mstp3_clks R8A7790_CLK_USBDMAC1>;
+		power-domains = <&cpg_clocks>;
 		#dma-cells = <1>;
 		dma-channels = <2>;
 	};
@@ -400,6 +416,7 @@
 		reg = <0 0xe6508000 0 0x40>;
 		interrupts = <0 287 IRQ_TYPE_LEVEL_HIGH>;
 		clocks = <&mstp9_clks R8A7790_CLK_I2C0>;
+		power-domains = <&cpg_clocks>;
 		status = "disabled";
 	};
 
@@ -410,6 +427,7 @@
 		reg = <0 0xe6518000 0 0x40>;
 		interrupts = <0 288 IRQ_TYPE_LEVEL_HIGH>;
 		clocks = <&mstp9_clks R8A7790_CLK_I2C1>;
+		power-domains = <&cpg_clocks>;
 		status = "disabled";
 	};
 
@@ -420,6 +438,7 @@
 		reg = <0 0xe6530000 0 0x40>;
 		interrupts = <0 286 IRQ_TYPE_LEVEL_HIGH>;
 		clocks = <&mstp9_clks R8A7790_CLK_I2C2>;
+		power-domains = <&cpg_clocks>;
 		status = "disabled";
 	};
 
@@ -430,6 +449,7 @@
 		reg = <0 0xe6540000 0 0x40>;
 		interrupts = <0 290 IRQ_TYPE_LEVEL_HIGH>;
 		clocks = <&mstp9_clks R8A7790_CLK_I2C3>;
+		power-domains = <&cpg_clocks>;
 		status = "disabled";
 	};
 
@@ -442,6 +462,7 @@
 		clocks = <&mstp3_clks R8A7790_CLK_IIC0>;
 		dmas = <&dmac0 0x61>, <&dmac0 0x62>;
 		dma-names = "tx", "rx";
+		power-domains = <&cpg_clocks>;
 		status = "disabled";
 	};
 
@@ -454,6 +475,7 @@
 		clocks = <&mstp3_clks R8A7790_CLK_IIC1>;
 		dmas = <&dmac0 0x65>, <&dmac0 0x66>;
 		dma-names = "tx", "rx";
+		power-domains = <&cpg_clocks>;
 		status = "disabled";
 	};
 
@@ -466,6 +488,7 @@
 		clocks = <&mstp3_clks R8A7790_CLK_IIC2>;
 		dmas = <&dmac0 0x69>, <&dmac0 0x6a>;
 		dma-names = "tx", "rx";
+		power-domains = <&cpg_clocks>;
 		status = "disabled";
 	};
 
@@ -478,6 +501,7 @@
 		clocks = <&mstp9_clks R8A7790_CLK_IICDVFS>;
 		dmas = <&dmac0 0x77>, <&dmac0 0x78>;
 		dma-names = "tx", "rx";
+		power-domains = <&cpg_clocks>;
 		status = "disabled";
 	};
 
@@ -488,6 +512,7 @@
 		clocks = <&mstp3_clks R8A7790_CLK_MMCIF0>;
 		dmas = <&dmac0 0xd1>, <&dmac0 0xd2>;
 		dma-names = "tx", "rx";
+		power-domains = <&cpg_clocks>;
 		reg-io-width = <4>;
 		status = "disabled";
 		max-frequency = <97500000>;
@@ -500,6 +525,7 @@
 		clocks = <&mstp3_clks R8A7790_CLK_MMCIF1>;
 		dmas = <&dmac0 0xe1>, <&dmac0 0xe2>;
 		dma-names = "tx", "rx";
+		power-domains = <&cpg_clocks>;
 		reg-io-width = <4>;
 		status = "disabled";
 		max-frequency = <97500000>;
@@ -517,6 +543,7 @@
 		clocks = <&mstp3_clks R8A7790_CLK_SDHI0>;
 		dmas = <&dmac1 0xcd>, <&dmac1 0xce>;
 		dma-names = "tx", "rx";
+		power-domains = <&cpg_clocks>;
 		status = "disabled";
 	};
 
@@ -527,6 +554,7 @@
 		clocks = <&mstp3_clks R8A7790_CLK_SDHI1>;
 		dmas = <&dmac1 0xc9>, <&dmac1 0xca>;
 		dma-names = "tx", "rx";
+		power-domains = <&cpg_clocks>;
 		status = "disabled";
 	};
 
@@ -537,6 +565,7 @@
 		clocks = <&mstp3_clks R8A7790_CLK_SDHI2>;
 		dmas = <&dmac1 0xc1>, <&dmac1 0xc2>;
 		dma-names = "tx", "rx";
+		power-domains = <&cpg_clocks>;
 		status = "disabled";
 	};
 
@@ -547,6 +576,7 @@
 		clocks = <&mstp3_clks R8A7790_CLK_SDHI3>;
 		dmas = <&dmac1 0xd3>, <&dmac1 0xd4>;
 		dma-names = "tx", "rx";
+		power-domains = <&cpg_clocks>;
 		status = "disabled";
 	};
 
@@ -558,6 +588,7 @@
 		clock-names = "sci_ick";
 		dmas = <&dmac0 0x21>, <&dmac0 0x22>;
 		dma-names = "tx", "rx";
+		power-domains = <&cpg_clocks>;
 		status = "disabled";
 	};
 
@@ -569,6 +600,7 @@
 		clock-names = "sci_ick";
 		dmas = <&dmac0 0x25>, <&dmac0 0x26>;
 		dma-names = "tx", "rx";
+		power-domains = <&cpg_clocks>;
 		status = "disabled";
 	};
 
@@ -580,6 +612,7 @@
 		clock-names = "sci_ick";
 		dmas = <&dmac0 0x27>, <&dmac0 0x28>;
 		dma-names = "tx", "rx";
+		power-domains = <&cpg_clocks>;
 		status = "disabled";
 	};
 
@@ -591,6 +624,7 @@
 		clock-names = "sci_ick";
 		dmas = <&dmac0 0x3d>, <&dmac0 0x3e>;
 		dma-names = "tx", "rx";
+		power-domains = <&cpg_clocks>;
 		status = "disabled";
 	};
 
@@ -602,6 +636,7 @@
 		clock-names = "sci_ick";
 		dmas = <&dmac0 0x19>, <&dmac0 0x1a>;
 		dma-names = "tx", "rx";
+		power-domains = <&cpg_clocks>;
 		status = "disabled";
 	};
 
@@ -613,6 +648,7 @@
 		clock-names = "sci_ick";
 		dmas = <&dmac0 0x1d>, <&dmac0 0x1e>;
 		dma-names = "tx", "rx";
+		power-domains = <&cpg_clocks>;
 		status = "disabled";
 	};
 
@@ -624,6 +660,7 @@
 		clock-names = "sci_ick";
 		dmas = <&dmac0 0x29>, <&dmac0 0x2a>;
 		dma-names = "tx", "rx";
+		power-domains = <&cpg_clocks>;
 		status = "disabled";
 	};
 
@@ -635,6 +672,7 @@
 		clock-names = "sci_ick";
 		dmas = <&dmac0 0x2d>, <&dmac0 0x2e>;
 		dma-names = "tx", "rx";
+		power-domains = <&cpg_clocks>;
 		status = "disabled";
 	};
 
@@ -646,6 +684,7 @@
 		clock-names = "sci_ick";
 		dmas = <&dmac0 0x39>, <&dmac0 0x3a>;
 		dma-names = "tx", "rx";
+		power-domains = <&cpg_clocks>;
 		status = "disabled";
 	};
 
@@ -657,6 +696,7 @@
 		clock-names = "sci_ick";
 		dmas = <&dmac0 0x4d>, <&dmac0 0x4e>;
 		dma-names = "tx", "rx";
+		power-domains = <&cpg_clocks>;
 		status = "disabled";
 	};
 
@@ -665,6 +705,7 @@
 		reg = <0 0xee700000 0 0x400>;
 		interrupts = <0 162 IRQ_TYPE_LEVEL_HIGH>;
 		clocks = <&mstp8_clks R8A7790_CLK_ETHER>;
+		power-domains = <&cpg_clocks>;
 		phy-mode = "rmii";
 		#address-cells = <1>;
 		#size-cells = <0>;
@@ -676,6 +717,7 @@
 		reg = <0 0xe6800000 0 0x800>, <0 0xee0e8000 0 0x4000>;
 		interrupts = <0 163 IRQ_TYPE_LEVEL_HIGH>;
 		clocks = <&mstp8_clks R8A7790_CLK_ETHERAVB>;
+		power-domains = <&cpg_clocks>;
 		#address-cells = <1>;
 		#size-cells = <0>;
 		status = "disabled";
@@ -686,6 +728,7 @@
 		reg = <0 0xee300000 0 0x2000>;
 		interrupts = <0 105 IRQ_TYPE_LEVEL_HIGH>;
 		clocks = <&mstp8_clks R8A7790_CLK_SATA0>;
+		power-domains = <&cpg_clocks>;
 		status = "disabled";
 	};
 
@@ -694,6 +737,7 @@
 		reg = <0 0xee500000 0 0x2000>;
 		interrupts = <0 106 IRQ_TYPE_LEVEL_HIGH>;
 		clocks = <&mstp8_clks R8A7790_CLK_SATA1>;
+		power-domains = <&cpg_clocks>;
 		status = "disabled";
 	};
 
@@ -702,12 +746,13 @@
 		reg = <0 0xe6590000 0 0x100>;
 		interrupts = <0 107 IRQ_TYPE_LEVEL_HIGH>;
 		clocks = <&mstp7_clks R8A7790_CLK_HSUSB>;
-		renesas,buswait = <4>;
-		phys = <&usb0 1>;
-		phy-names = "usb";
 		dmas = <&usb_dmac0 0>, <&usb_dmac0 1>,
 		       <&usb_dmac1 0>, <&usb_dmac1 1>;
 		dma-names = "ch0", "ch1", "ch2", "ch3";
+		power-domains = <&cpg_clocks>;
+		renesas,buswait = <4>;
+		phys = <&usb0 1>;
+		phy-names = "usb";
 		status = "disabled";
 	};
 
@@ -718,6 +763,7 @@
 		#size-cells = <0>;
 		clocks = <&mstp7_clks R8A7790_CLK_HSUSB>;
 		clock-names = "usbhs";
+		power-domains = <&cpg_clocks>;
 		status = "disabled";
 
 		usb0: usb-channel at 0 {
@@ -732,33 +778,37 @@
 
 	vin0: video at e6ef0000 {
 		compatible = "renesas,vin-r8a7790";
-		clocks = <&mstp8_clks R8A7790_CLK_VIN0>;
 		reg = <0 0xe6ef0000 0 0x1000>;
 		interrupts = <0 188 IRQ_TYPE_LEVEL_HIGH>;
+		clocks = <&mstp8_clks R8A7790_CLK_VIN0>;
+		power-domains = <&cpg_clocks>;
 		status = "disabled";
 	};
 
 	vin1: video at e6ef1000 {
 		compatible = "renesas,vin-r8a7790";
-		clocks = <&mstp8_clks R8A7790_CLK_VIN1>;
 		reg = <0 0xe6ef1000 0 0x1000>;
 		interrupts = <0 189 IRQ_TYPE_LEVEL_HIGH>;
+		clocks = <&mstp8_clks R8A7790_CLK_VIN1>;
+		power-domains = <&cpg_clocks>;
 		status = "disabled";
 	};
 
 	vin2: video at e6ef2000 {
 		compatible = "renesas,vin-r8a7790";
-		clocks = <&mstp8_clks R8A7790_CLK_VIN2>;
 		reg = <0 0xe6ef2000 0 0x1000>;
 		interrupts = <0 190 IRQ_TYPE_LEVEL_HIGH>;
+		clocks = <&mstp8_clks R8A7790_CLK_VIN2>;
+		power-domains = <&cpg_clocks>;
 		status = "disabled";
 	};
 
 	vin3: video at e6ef3000 {
 		compatible = "renesas,vin-r8a7790";
-		clocks = <&mstp8_clks R8A7790_CLK_VIN3>;
 		reg = <0 0xe6ef3000 0 0x1000>;
 		interrupts = <0 191 IRQ_TYPE_LEVEL_HIGH>;
+		clocks = <&mstp8_clks R8A7790_CLK_VIN3>;
+		power-domains = <&cpg_clocks>;
 		status = "disabled";
 	};
 
@@ -767,6 +817,7 @@
 		reg = <0 0xfe920000 0 0x8000>;
 		interrupts = <0 266 IRQ_TYPE_LEVEL_HIGH>;
 		clocks = <&mstp1_clks R8A7790_CLK_VSP1_R>;
+		power-domains = <&cpg_clocks>;
 
 		renesas,has-sru;
 		renesas,#rpf = <5>;
@@ -779,6 +830,7 @@
 		reg = <0 0xfe928000 0 0x8000>;
 		interrupts = <0 267 IRQ_TYPE_LEVEL_HIGH>;
 		clocks = <&mstp1_clks R8A7790_CLK_VSP1_S>;
+		power-domains = <&cpg_clocks>;
 
 		renesas,has-lut;
 		renesas,has-sru;
@@ -792,6 +844,7 @@
 		reg = <0 0xfe930000 0 0x8000>;
 		interrupts = <0 246 IRQ_TYPE_LEVEL_HIGH>;
 		clocks = <&mstp1_clks R8A7790_CLK_VSP1_DU0>;
+		power-domains = <&cpg_clocks>;
 
 		renesas,has-lif;
 		renesas,has-lut;
@@ -805,6 +858,7 @@
 		reg = <0 0xfe938000 0 0x8000>;
 		interrupts = <0 247 IRQ_TYPE_LEVEL_HIGH>;
 		clocks = <&mstp1_clks R8A7790_CLK_VSP1_DU1>;
+		power-domains = <&cpg_clocks>;
 
 		renesas,has-lif;
 		renesas,has-lut;
@@ -859,6 +913,7 @@
 		clocks = <&mstp9_clks R8A7790_CLK_RCAN0>,
 			 <&cpg_clocks R8A7790_CLK_RCAN>, <&can_clk>;
 		clock-names = "clkp1", "clkp2", "can_clk";
+		power-domains = <&cpg_clocks>;
 		status = "disabled";
 	};
 
@@ -869,6 +924,7 @@
 		clocks = <&mstp9_clks R8A7790_CLK_RCAN1>,
 			 <&cpg_clocks R8A7790_CLK_RCAN>, <&can_clk>;
 		clock-names = "clkp1", "clkp2", "can_clk";
+		power-domains = <&cpg_clocks>;
 		status = "disabled";
 	};
 
@@ -877,6 +933,7 @@
 		reg = <0 0xfe980000 0 0x10300>;
 		interrupts = <0 272 IRQ_TYPE_LEVEL_HIGH>;
 		clocks = <&mstp1_clks R8A7790_CLK_JPU>;
+		power-domains = <&cpg_clocks>;
 	};
 
 	clocks {
@@ -953,6 +1010,7 @@
 			clock-output-names = "main", "pll0", "pll1", "pll3",
 					     "lb", "qspi", "sdh", "sd0", "sd1",
 					     "z", "rcan", "adsp";
+			#power-domain-cells = <0>;
 		};
 
 		/* Variable factor clocks */
@@ -1343,6 +1401,7 @@
 		clocks = <&mstp9_clks R8A7790_CLK_QSPI_MOD>;
 		dmas = <&dmac0 0x17>, <&dmac0 0x18>;
 		dma-names = "tx", "rx";
+		power-domains = <&cpg_clocks>;
 		num-cs = <1>;
 		#address-cells = <1>;
 		#size-cells = <0>;
@@ -1356,6 +1415,7 @@
 		clocks = <&mstp0_clks R8A7790_CLK_MSIOF0>;
 		dmas = <&dmac0 0x51>, <&dmac0 0x52>;
 		dma-names = "tx", "rx";
+		power-domains = <&cpg_clocks>;
 		#address-cells = <1>;
 		#size-cells = <0>;
 		status = "disabled";
@@ -1368,6 +1428,7 @@
 		clocks = <&mstp2_clks R8A7790_CLK_MSIOF1>;
 		dmas = <&dmac0 0x55>, <&dmac0 0x56>;
 		dma-names = "tx", "rx";
+		power-domains = <&cpg_clocks>;
 		#address-cells = <1>;
 		#size-cells = <0>;
 		status = "disabled";
@@ -1380,6 +1441,7 @@
 		clocks = <&mstp2_clks R8A7790_CLK_MSIOF2>;
 		dmas = <&dmac0 0x41>, <&dmac0 0x42>;
 		dma-names = "tx", "rx";
+		power-domains = <&cpg_clocks>;
 		#address-cells = <1>;
 		#size-cells = <0>;
 		status = "disabled";
@@ -1392,6 +1454,7 @@
 		clocks = <&mstp2_clks R8A7790_CLK_MSIOF3>;
 		dmas = <&dmac0 0x45>, <&dmac0 0x46>;
 		dma-names = "tx", "rx";
+		power-domains = <&cpg_clocks>;
 		#address-cells = <1>;
 		#size-cells = <0>;
 		status = "disabled";
@@ -1402,6 +1465,7 @@
 		reg = <0 0xee000000 0 0xc00>;
 		interrupts = <0 101 IRQ_TYPE_LEVEL_HIGH>;
 		clocks = <&mstp3_clks R8A7790_CLK_SSUSB>;
+		power-domains = <&cpg_clocks>;
 		phys = <&usb2 1>;
 		phy-names = "usb";
 		status = "disabled";
@@ -1410,10 +1474,11 @@
 	pci0: pci at ee090000 {
 		compatible = "renesas,pci-r8a7790";
 		device_type = "pci";
-		clocks = <&mstp7_clks R8A7790_CLK_EHCI>;
 		reg = <0 0xee090000 0 0xc00>,
 		      <0 0xee080000 0 0x1100>;
 		interrupts = <0 108 IRQ_TYPE_LEVEL_HIGH>;
+		clocks = <&mstp7_clks R8A7790_CLK_EHCI>;
+		power-domains = <&cpg_clocks>;
 		status = "disabled";
 
 		bus-range = <0 0>;
@@ -1444,10 +1509,11 @@
 	pci1: pci at ee0b0000 {
 		compatible = "renesas,pci-r8a7790";
 		device_type = "pci";
-		clocks = <&mstp7_clks R8A7790_CLK_EHCI>;
 		reg = <0 0xee0b0000 0 0xc00>,
 		      <0 0xee0a0000 0 0x1100>;
 		interrupts = <0 112 IRQ_TYPE_LEVEL_HIGH>;
+		clocks = <&mstp7_clks R8A7790_CLK_EHCI>;
+		power-domains = <&cpg_clocks>;
 		status = "disabled";
 
 		bus-range = <1 1>;
@@ -1465,6 +1531,7 @@
 		compatible = "renesas,pci-r8a7790";
 		device_type = "pci";
 		clocks = <&mstp7_clks R8A7790_CLK_EHCI>;
+		power-domains = <&cpg_clocks>;
 		reg = <0 0xee0d0000 0 0xc00>,
 		      <0 0xee0c0000 0 0x1100>;
 		interrupts = <0 113 IRQ_TYPE_LEVEL_HIGH>;
@@ -1517,6 +1584,7 @@
 		interrupt-map = <0 0 0 0 &gic 0 116 IRQ_TYPE_LEVEL_HIGH>;
 		clocks = <&mstp3_clks R8A7790_CLK_PCIEC>, <&pcie_bus_clk>;
 		clock-names = "pcie", "pcie_bus";
+		power-domains = <&cpg_clocks>;
 		status = "disabled";
 	};
 
-- 
1.9.1



From geert+renesas at glider.be  Tue Aug  4 05:28:16 2015
From: geert+renesas at glider.be (Geert Uytterhoeven)
Date: Tue,  4 Aug 2015 14:28:16 +0200
Subject: [PATCH v4 15/16] clk: shmobile: mstp: Consider "zb_clk" suitable for
 power management
In-Reply-To: <1438691297-29235-1-git-send-email-geert+renesas@glider.be>
References: <1438691297-29235-1-git-send-email-geert+renesas@glider.be>
Message-ID: <1438691297-29235-16-git-send-email-geert+renesas@glider.be>

Currently the CPG/MSTP Clock Domain code looks for MSTP clocks to power
manage a device.

Unfortunately, on R-Mobile APE6 (r8a73a4) and SH-Mobile AG5 (sh73a0),
the Bus State Controller (BSC) is not power-managed by an MSTP clock,
but by a plain CPG clock (zb_clk).  Add a special case to handle this,
so the clock is properly managed, and devices connected to the BSC work
as expected.

Signed-off-by: Geert Uytterhoeven <geert+renesas at glider.be>
Reviewed-by: Ulf Hansson <ulf.hansson at linaro.org>
---
v4:
  - Add Reviewed-by,

v3:
  - Use "CPG/MSTP Clock Domain" instead of "CPG Clock Domain",

v2:
  - New.
---
 drivers/clk/shmobile/clk-mstp.c | 4 ++++
 1 file changed, 4 insertions(+)

diff --git a/drivers/clk/shmobile/clk-mstp.c b/drivers/clk/shmobile/clk-mstp.c
index b1df7b2f1e970adb..a117c3f0f257b5e1 100644
--- a/drivers/clk/shmobile/clk-mstp.c
+++ b/drivers/clk/shmobile/clk-mstp.c
@@ -259,6 +259,10 @@ int cpg_mstp_attach_dev(struct generic_pm_domain *domain, struct device *dev)
 					    "renesas,cpg-mstp-clocks"))
 			goto found;
 
+		/* BSC on r8a73a4/sh73a0 uses zb_clk instead of an mstp clock*/
+		if (!strcmp(clkspec.np->name, "zb_clk"))
+			goto found;
+
 		of_node_put(clkspec.np);
 		i++;
 	}
-- 
1.9.1



From geert+renesas at glider.be  Tue Aug  4 05:28:01 2015
From: geert+renesas at glider.be (Geert Uytterhoeven)
Date: Tue,  4 Aug 2015 14:28:01 +0200
Subject: [PATCH v4 00/16] ARM: shmobile: Add CPG/MSTP Clock Domain
Message-ID: <1438691297-29235-1-git-send-email-geert+renesas@glider.be>

	Hi all,

This patch series adds Clock Domain support to the Clock Pulse Generator
(CPG) Module Stop (MSTP) Clocks driver using the generic PM Domain, to
be used on shmobile SoCs without device power domains (R-Car Gen1 and
Gen2, RZ).  This allows to power-manage the module clocks of SoC devices
that are part of the CPG/MSTP Clock Domain using Runtime PM, or for
system suspend/resume, similar to SoCs with device power domains
(SH-Mobile and R-Mobile).

SoC devices that are part of the CPG/MSTP Clock Domain and can be
power-managed through an MSTP clock are tagged in DT with a proper
"power-domains" property, also serving as a visual clue. This applies to
most on-SoC devices, which have a one-to-one mapping from SoC device to
DT device node.  Notable exceptions are "display" and "sound" device
nodes, which represent multiple SoC devices, each having their own MSTP
clocks. Hence drivers for such devices still have to manage their
(multiple module) clocks themselves.

The (MSTP) clock to use for power-management is found by scanning for
clocks that are compatible with "renesas,cpg-mstp-clocks".
In V1, the "first" clock tied to each device (con_id NULL) was used,
being a bit ad-hoc. It was suggested to use the "fck" clock instead,
but this may conflict with DT bindings for devices we don't control
(e.g. GIC-400 plans to mandate "clk" for the clk-name of its single
clock). Looking for real MSTP clocks avoids this problem.

Logically, the CPG/MSTP Clock Domain operates on the SoC CPG/MSTP block.
As there's no single device node in DT representing this block (there
are separate device nodes for the CPG and for the individual MSTP
clocks), I bound the logic to the CPG device node.  Perhaps this is
something we should change for future SoCs?

Finally, the legacy default PM domain hack in drivers/sh/pm_runtime.c
is no longer needed when running an ARM multi-platform kernel on an
shmobile SoC with genpd support. Please note that this hack is still
needed for legacy (SH/ARM) platforms, and for the CONFIG_PM=n case.
Perhaps we should unconditionally enable PM when building shmobile
multi-platform kernels?

Compared to the legacy default PM domain hack, the CPG/MSTP Clock Domain
has several advantages:
  - It only affects on-SoC devices, not all platform devices,
  - It only affects the on-SoC devices we want, as specified in DT,
  - Allmost all module clocks of all on-SoC devices (barring devices
    needed for wake-up) are now gated during s2ram, saving more power.

By adding a small quirk to the CPG/MSTP Clock Domain code, its functions
to attach/detach devices to a PM Domain can be reused by the pm-rmobile
driver, reducing code duplication.

Here's a list of all devices in the CPG/MSTP Clock Domain on r8a7791:

root at koelsch:~# cat /sys/kernel/debug/pm_genpd/pm_genpd_summary
    domain                      status         slaves
           /device                                      runtime status
----------------------------------------------------------------------
cpg_clocks                      on               
    /devices/platform/e61c0000.interrupt-controller     active
    /devices/platform/e60b0000.i2c                      suspended
    /devices/platform/ffca0000.timer                    suspended
    /devices/platform/e6590100.usb-phy                  unsupported
    /devices/platform/e6050000.gpio                     active
    /devices/platform/e6051000.gpio                     active
    /devices/platform/e6052000.gpio                     active
    /devices/platform/e6053000.gpio                     active
    /devices/platform/e6054000.gpio                     active
    /devices/platform/e6055000.gpio                     active
    /devices/platform/e6055400.gpio                     active
    /devices/platform/e6055800.gpio                     active
    /devices/platform/ee090000.pci                      active
    /devices/platform/ee0d0000.pci                      active
    /devices/platform/fe000000.pcie                     unsupported
    /devices/platform/e6700000.dma-controller           active
    /devices/platform/e6720000.dma-controller           active
    /devices/platform/ec700000.dma-controller           active
    /devices/platform/ec720000.dma-controller           suspended
    /devices/platform/e65a0000.dma-controller           suspended
    /devices/platform/e65b0000.dma-controller           suspended
    /devices/platform/e6e60000.serial                   active
    /devices/platform/e6e68000.serial                   active
    /devices/platform/ee300000.sata                     unsupported
    /devices/platform/e6b10000.spi                      suspended
    /devices/platform/e6e20000.spi                      suspended
    /devices/platform/ee700000.ethernet                 active
    /devices/platform/e6530000.i2c                      suspended
    /devices/platform/e6ef1000.video                    suspended
    /devices/platform/e61f0000.thermal                  active
    /devices/platform/ee100000.sd                       active
    /devices/platform/ee140000.sd                       active
    /devices/platform/ee160000.sd                       active
root at koelsch:~# 

Patch overview:
  - Patch 1 adds the core CPG/MSTP Clock Domain code to the CPG MSTP
    driver,
  - Patches 2-5 adds CPG/MSTP Clock Domain driver support for all
    Renesas SoCs that have MSTP clocks, but no device power domains, and
    updates the DT binding documentation accordingly,
  - Patches 6-12 add CPG/MSTP Clock Domains to the dtsi files,
  - Patches 13 and 14 disable the legacy default PM domain hack on all
    ARM multi-platform builds with genpd support, now it's no longer
    needed nor wanted,
  - Patch 15 adds a quirk for r8a73a4 and sh73a0, where the Bus State
    Controller is not power-managed by an MSTP clock, but by a plain
    CPG clock,
  - Patch 16 makes the R-Mobile PM Domain driver use the CPG/MSTP Clock
    Domain attach/detach helpers, as they're more future-proof, and to
    reduce code duplication.

Changes compared to v3 ("[PATCH v3 00/16] ARM: shmobile: Add CPG/MSTP
Clock Domain", https://lkml.org/lkml/2015/7/1/408):
  - clk-mstp.c needs to #include <linux/clk.h> due to recent
    <linux/clk*.h> shuffling,
  - Add "power-domains" properties to recently introduced device nodes
    (jpu, mmcif0),
  - Consistently add "power-domains" properties after clock and dma
    properties,
  - Add Reviewed-by,

Changes compared to v2 ("[PATCH v2 00/14] ARM: shmobile: Add CPG Clock
Domains", https://lkml.org/lkml/2015/5/28/590):
  - Add Acked-by,
  - Use "CPG/MSTP Clock Domain" instead of "CPG Clock Domain",
  - Drop bogus addition of #includes to clk-rcar-gen2.c,
  - Call pm_clk_destroy() from cpg_mstp_detach_dev() only if
    cpg_mstp_attach_dev() actually added a clock,
  - Add "power-domains" property to recently introduced Ethernet AVB
    device node,
  - Add CPG/MSTP Clock Domain to recently introduced r8a7793 SoC,
  - The legacy default PM Domain runtime check must stay for the ARM
    multiplatform CONFIG_PM=n case, to prevent the code from running on
    non-shmobile machines,
  - Provide backwards-compatibility with old DTs (mainly for R-Car
    Gen2),
  - Extract EMMA Mobile EV2 removal into a separate patch,
  - Replace explicit platform checks in the legacy default PM Domain
    code by a check for the presence of MSTP clocks,
  - Drop references to legacy r8a7740/sh73a0, which are gone.

Changes compared to v1 ("[PATCH/RFC 0/5] ARM: shmobile: rcar-gen2: Add
CPG Clock Domain",
https://www.marc.info/?l=linux-pm&m=142670805530085&w=3):
  - Add Acked-by and Reviewed-by.
  - Move core CPG Clock Domain code from the R-Car Gen2 driver to the
    CPG MSTP Clocks driver, as it's generic, and can be used on other
    Renesas SoCs that have a CPG/MSTP block,
  - Scan for an MSTP clock instead of using the first clock tied to the
    device (con_id NULL),
  - Add support for R-Car Gen1 and RZ, in addition to R-Car Gen2,
    allowing to drop the legacy default PM domain hack completely in
    multi-platform builds,
  - Reuse the CPG Clock Domain attach/detach helpers for pm-rmobile.
More detailed change logs are available in the individual patches.

Dependencies:
  - This series is against renesas-devel-20150803-v4.2-rc5 (not
    renesas-drivers-2015-08-04-v4.2-rc5, as that tree has more changes
    to the .dtsi files),
  - As usual when involving clocks and/or PM Domains, there are stringent
    dependencies between the (subsets of) patches:
      - Patches 2-5 depend on patch 1,
      - Patches 6-12 depend on patches 2-5,
      - Patch 14 depends on patches 6-13,
      - Patch 15 depends on patch 1 only,
      - Patch 16 depends on patch 15.

All of this was tested on:
  - r8a73a4/ape6evm,
  - r8a7740/armadillo,
  - r8a7791/koelsch (with and without CONFIG_PM),
  - sh73a0/kzm9g.

Testing on other shmobile platforms (esp. R-Car Gen1 and RZ) would be
appreciated.

I think this series goes best in through Simon's shmobile tree.

Thanks for applying!

Geert Uytterhoeven (16):
  clk: shmobile: Add CPG/MSTP Clock Domain support
  clk: shmobile: r8a7778: Add CPG/MSTP Clock Domain support
  clk: shmobile: r8a7779: Add CPG/MSTP Clock Domain support
  clk: shmobile: rcar-gen2: Add CPG/MSTP Clock Domain support
  clk: shmobile: rz: Add CPG/MSTP Clock Domain support
  ARM: shmobile: r7s72100 dtsi: Add CPG/MSTP Clock Domain
  ARM: shmobile: r8a7778 dtsi: Add CPG/MSTP Clock Domain
  ARM: shmobile: r8a7779 dtsi: Add CPG/MSTP Clock Domain
  ARM: shmobile: r8a7790 dtsi: Add CPG/MSTP Clock Domain
  ARM: shmobile: r8a7791 dtsi: Add CPG/MSTP Clock Domain
  ARM: shmobile: r8a7793 dtsi: Add CPG/MSTP Clock Domain
  ARM: shmobile: r8a7794 dtsi: Add CPG/MSTP Clock Domain
  drivers: sh: Disable legacy default PM Domain on emev2
  drivers: sh: Disable PM runtime for multi-platform ARM with genpd
  clk: shmobile: mstp: Consider "zb_clk" suitable for power management
  ARM: shmobile: R-Mobile: Use CPG/MSTP Clock Domain attach/detach
    helpers

 .../bindings/clock/renesas,r8a7778-cpg-clocks.txt  | 29 ++++++-
 .../bindings/clock/renesas,r8a7779-cpg-clocks.txt  | 30 ++++++-
 .../clock/renesas,rcar-gen2-cpg-clocks.txt         | 26 ++++++-
 .../bindings/clock/renesas,rz-cpg-clocks.txt       | 29 ++++++-
 arch/arm/boot/dts/r7s72100.dtsi                    | 19 +++++
 arch/arm/boot/dts/r8a7778.dtsi                     | 22 ++++++
 arch/arm/boot/dts/r8a7779.dtsi                     | 23 ++++++
 arch/arm/boot/dts/r8a7790.dtsi                     | 86 +++++++++++++++++---
 arch/arm/boot/dts/r8a7791.dtsi                     | 88 +++++++++++++++++++--
 arch/arm/boot/dts/r8a7793.dtsi                     |  7 ++
 arch/arm/boot/dts/r8a7794.dtsi                     | 29 +++++++
 arch/arm/mach-shmobile/Kconfig                     |  2 +
 arch/arm/mach-shmobile/pm-rmobile.c                | 35 +--------
 drivers/clk/shmobile/clk-mstp.c                    | 91 ++++++++++++++++++++++
 drivers/clk/shmobile/clk-r8a7778.c                 |  2 +
 drivers/clk/shmobile/clk-r8a7779.c                 |  2 +
 drivers/clk/shmobile/clk-rcar-gen2.c               |  2 +
 drivers/clk/shmobile/clk-rz.c                      |  3 +
 drivers/sh/pm_runtime.c                            | 19 ++---
 include/linux/clk/shmobile.h                       | 12 +++
 20 files changed, 482 insertions(+), 74 deletions(-)

-- 
1.9.1

Gr{oetje,eeting}s,

						Geert

--
Geert Uytterhoeven -- There's lots of Linux beyond ia32 -- geert at linux-m68k.org

In personal conversations with technical people, I call myself a hacker. But
when I'm talking to journalists I just say "programmer" or something like that.
							    -- Linus Torvalds


From geert+renesas at glider.be  Tue Aug  4 05:28:06 2015
From: geert+renesas at glider.be (Geert Uytterhoeven)
Date: Tue,  4 Aug 2015 14:28:06 +0200
Subject: [PATCH v4 05/16] clk: shmobile: rz: Add CPG/MSTP Clock Domain support
In-Reply-To: <1438691297-29235-1-git-send-email-geert+renesas@glider.be>
References: <1438691297-29235-1-git-send-email-geert+renesas@glider.be>
Message-ID: <1438691297-29235-6-git-send-email-geert+renesas@glider.be>

Add Clock Domain support to the RZ Clock Pulse Generator (CPG) driver
using the generic PM Domain.  This allows to power-manage the module
clocks of SoC devices that are part of the CPG/MSTP Clock Domain using
Runtime PM, or for system suspend/resume.

SoC devices that are part of the CPG/MSTP Clock Domain and can be
power-managed through an MSTP clock should be tagged in DT with a proper
"power-domains" property.

Signed-off-by: Geert Uytterhoeven <geert+renesas at glider.be>
Acked-by: Stephen Boyd <sboyd at codeaurora.org>
Reviewed-by: Ulf Hansson <ulf.hansson at linaro.org>
---
v4:
  - Add Reviewed-by,

v3:
  - Add Acked-by,
  - Use "CPG/MSTP Clock Domain" instead of "CPG Clock Domain",

v2:
  - New.
---
 .../bindings/clock/renesas,rz-cpg-clocks.txt       | 29 ++++++++++++++++++++--
 arch/arm/mach-shmobile/Kconfig                     |  1 +
 drivers/clk/shmobile/clk-rz.c                      |  3 +++
 3 files changed, 31 insertions(+), 2 deletions(-)

diff --git a/Documentation/devicetree/bindings/clock/renesas,rz-cpg-clocks.txt b/Documentation/devicetree/bindings/clock/renesas,rz-cpg-clocks.txt
index b0f7ddb8cdb13750..bb51a33a1fbfbc97 100644
--- a/Documentation/devicetree/bindings/clock/renesas,rz-cpg-clocks.txt
+++ b/Documentation/devicetree/bindings/clock/renesas,rz-cpg-clocks.txt
@@ -2,6 +2,8 @@
 
 The CPG generates core clocks for the RZ SoCs. It includes the PLL, variable
 CPU and GPU clocks, and several fixed ratio dividers.
+The CPG also provides a Clock Domain for SoC devices, in combination with the
+CPG Module Stop (MSTP) Clocks.
 
 Required Properties:
 
@@ -14,10 +16,18 @@ Required Properties:
   - #clock-cells: Must be 1
   - clock-output-names: The names of the clocks. Supported clocks are "pll",
     "i", and "g"
+  - #power-domain-cells: Must be 0
 
+SoC devices that are part of the CPG/MSTP Clock Domain and can be power-managed
+through an MSTP clock should refer to the CPG device node in their
+"power-domains" property, as documented by the generic PM domain bindings in
+Documentation/devicetree/bindings/power/power_domain.txt.
 
-Example
--------
+
+Examples
+--------
+
+  - CPG device node:
 
 	cpg_clocks: cpg_clocks at fcfe0000 {
 		#clock-cells = <1>;
@@ -26,4 +36,19 @@ Example
 		reg = <0xfcfe0000 0x18>;
 		clocks = <&extal_clk>, <&usb_x1_clk>;
 		clock-output-names = "pll", "i", "g";
+		#power-domain-cells = <0>;
+	};
+
+
+  - CPG/MSTP Clock Domain member device node:
+
+	mtu2: timer at fcff0000 {
+		compatible = "renesas,mtu2-r7s72100", "renesas,mtu2";
+		reg = <0xfcff0000 0x400>;
+		interrupts = <0 107 IRQ_TYPE_LEVEL_HIGH>;
+		interrupt-names = "tgi0a";
+		clocks = <&mstp3_clks R7S72100_CLK_MTU2>;
+		clock-names = "fck";
+		power-domains = <&cpg_clocks>;
+		status = "disabled";
 	};
diff --git a/arch/arm/mach-shmobile/Kconfig b/arch/arm/mach-shmobile/Kconfig
index 5b1f9eca7c871aee..926e336d6aeb7181 100644
--- a/arch/arm/mach-shmobile/Kconfig
+++ b/arch/arm/mach-shmobile/Kconfig
@@ -51,6 +51,7 @@ config ARCH_EMEV2
 
 config ARCH_R7S72100
 	bool "RZ/A1H (R7S72100)"
+	select PM_GENERIC_DOMAINS if PM
 	select SYS_SUPPORTS_SH_MTU2
 
 config ARCH_R8A73A4
diff --git a/drivers/clk/shmobile/clk-rz.c b/drivers/clk/shmobile/clk-rz.c
index 7e68e86309625c9e..9766e3cb595fd257 100644
--- a/drivers/clk/shmobile/clk-rz.c
+++ b/drivers/clk/shmobile/clk-rz.c
@@ -10,6 +10,7 @@
  */
 
 #include <linux/clk-provider.h>
+#include <linux/clk/shmobile.h>
 #include <linux/init.h>
 #include <linux/kernel.h>
 #include <linux/of.h>
@@ -99,5 +100,7 @@ static void __init rz_cpg_clocks_init(struct device_node *np)
 	}
 
 	of_clk_add_provider(np, of_clk_src_onecell_get, &cpg->data);
+
+	cpg_mstp_add_clk_domain(np);
 }
 CLK_OF_DECLARE(rz_cpg_clks, "renesas,rz-cpg-clocks", rz_cpg_clocks_init);
-- 
1.9.1



From geert+renesas at glider.be  Tue Aug  4 05:28:07 2015
From: geert+renesas at glider.be (Geert Uytterhoeven)
Date: Tue,  4 Aug 2015 14:28:07 +0200
Subject: [PATCH v4 06/16] ARM: shmobile: r7s72100 dtsi: Add CPG/MSTP Clock
 Domain
In-Reply-To: <1438691297-29235-1-git-send-email-geert+renesas@glider.be>
References: <1438691297-29235-1-git-send-email-geert+renesas@glider.be>
Message-ID: <1438691297-29235-7-git-send-email-geert+renesas@glider.be>

Add an appropriate "#power-domain-cells" property to the cpg_clocks
device node, to create the CPG/MSTP Clock Domain.

Add "power-domains" properties to all device nodes for devices that are
part of the CPG/MSTP Clock Domain and can be power-managed through an
MSTP clock.  This applies to most on-SoC devices, which have a
one-to-one mapping from SoC device to DT device node.

Signed-off-by: Geert Uytterhoeven <geert+renesas at glider.be>
Reviewed-by: Ulf Hansson <ulf.hansson at linaro.org>
---
v4:
  - Add Reviewed-by,

v3:
  - Use "CPG/MSTP Clock Domain" instead of "CPG Clock Domain",

v2:
  - New.
---
 arch/arm/boot/dts/r7s72100.dtsi | 19 +++++++++++++++++++
 1 file changed, 19 insertions(+)

diff --git a/arch/arm/boot/dts/r7s72100.dtsi b/arch/arm/boot/dts/r7s72100.dtsi
index 277e73c110e5d40c..060c32cbd66923ed 100644
--- a/arch/arm/boot/dts/r7s72100.dtsi
+++ b/arch/arm/boot/dts/r7s72100.dtsi
@@ -86,6 +86,7 @@
 			reg = <0xfcfe0000 0x18>;
 			clocks = <&extal_clk>, <&usb_x1_clk>;
 			clock-output-names = "pll", "i", "g";
+			#power-domain-cells = <0>;
 		};
 
 		/* MSTP clocks */
@@ -157,6 +158,7 @@
 			     <0 189 IRQ_TYPE_LEVEL_HIGH>;
 		clocks = <&mstp4_clks R7S72100_CLK_SCIF0>;
 		clock-names = "sci_ick";
+		power-domains = <&cpg_clocks>;
 		status = "disabled";
 	};
 
@@ -169,6 +171,7 @@
 			     <0 193 IRQ_TYPE_LEVEL_HIGH>;
 		clocks = <&mstp4_clks R7S72100_CLK_SCIF1>;
 		clock-names = "sci_ick";
+		power-domains = <&cpg_clocks>;
 		status = "disabled";
 	};
 
@@ -181,6 +184,7 @@
 			     <0 197 IRQ_TYPE_LEVEL_HIGH>;
 		clocks = <&mstp4_clks R7S72100_CLK_SCIF2>;
 		clock-names = "sci_ick";
+		power-domains = <&cpg_clocks>;
 		status = "disabled";
 	};
 
@@ -193,6 +197,7 @@
 			     <0 201 IRQ_TYPE_LEVEL_HIGH>;
 		clocks = <&mstp4_clks R7S72100_CLK_SCIF3>;
 		clock-names = "sci_ick";
+		power-domains = <&cpg_clocks>;
 		status = "disabled";
 	};
 
@@ -205,6 +210,7 @@
 			     <0 205 IRQ_TYPE_LEVEL_HIGH>;
 		clocks = <&mstp4_clks R7S72100_CLK_SCIF4>;
 		clock-names = "sci_ick";
+		power-domains = <&cpg_clocks>;
 		status = "disabled";
 	};
 
@@ -217,6 +223,7 @@
 			     <0 209 IRQ_TYPE_LEVEL_HIGH>;
 		clocks = <&mstp4_clks R7S72100_CLK_SCIF5>;
 		clock-names = "sci_ick";
+		power-domains = <&cpg_clocks>;
 		status = "disabled";
 	};
 
@@ -229,6 +236,7 @@
 			     <0 213 IRQ_TYPE_LEVEL_HIGH>;
 		clocks = <&mstp4_clks R7S72100_CLK_SCIF6>;
 		clock-names = "sci_ick";
+		power-domains = <&cpg_clocks>;
 		status = "disabled";
 	};
 
@@ -241,6 +249,7 @@
 			     <0 217 IRQ_TYPE_LEVEL_HIGH>;
 		clocks = <&mstp4_clks R7S72100_CLK_SCIF7>;
 		clock-names = "sci_ick";
+		power-domains = <&cpg_clocks>;
 		status = "disabled";
 	};
 
@@ -252,6 +261,7 @@
 			     <0 240 IRQ_TYPE_LEVEL_HIGH>;
 		interrupt-names = "error", "rx", "tx";
 		clocks = <&mstp10_clks R7S72100_CLK_SPI0>;
+		power-domains = <&cpg_clocks>;
 		num-cs = <1>;
 		#address-cells = <1>;
 		#size-cells = <0>;
@@ -266,6 +276,7 @@
 			     <0 243 IRQ_TYPE_LEVEL_HIGH>;
 		interrupt-names = "error", "rx", "tx";
 		clocks = <&mstp10_clks R7S72100_CLK_SPI1>;
+		power-domains = <&cpg_clocks>;
 		num-cs = <1>;
 		#address-cells = <1>;
 		#size-cells = <0>;
@@ -280,6 +291,7 @@
 			     <0 246 IRQ_TYPE_LEVEL_HIGH>;
 		interrupt-names = "error", "rx", "tx";
 		clocks = <&mstp10_clks R7S72100_CLK_SPI2>;
+		power-domains = <&cpg_clocks>;
 		num-cs = <1>;
 		#address-cells = <1>;
 		#size-cells = <0>;
@@ -294,6 +306,7 @@
 			     <0 249 IRQ_TYPE_LEVEL_HIGH>;
 		interrupt-names = "error", "rx", "tx";
 		clocks = <&mstp10_clks R7S72100_CLK_SPI3>;
+		power-domains = <&cpg_clocks>;
 		num-cs = <1>;
 		#address-cells = <1>;
 		#size-cells = <0>;
@@ -308,6 +321,7 @@
 			     <0 252 IRQ_TYPE_LEVEL_HIGH>;
 		interrupt-names = "error", "rx", "tx";
 		clocks = <&mstp10_clks R7S72100_CLK_SPI4>;
+		power-domains = <&cpg_clocks>;
 		num-cs = <1>;
 		#address-cells = <1>;
 		#size-cells = <0>;
@@ -338,6 +352,7 @@
 			     <0 164 IRQ_TYPE_LEVEL_HIGH>;
 		clocks = <&mstp9_clks R7S72100_CLK_I2C0>;
 		clock-frequency = <100000>;
+		power-domains = <&cpg_clocks>;
 		status = "disabled";
 	};
 
@@ -356,6 +371,7 @@
 			     <0 172 IRQ_TYPE_LEVEL_HIGH>;
 		clocks = <&mstp9_clks R7S72100_CLK_I2C1>;
 		clock-frequency = <100000>;
+		power-domains = <&cpg_clocks>;
 		status = "disabled";
 	};
 
@@ -374,6 +390,7 @@
 			     <0 180 IRQ_TYPE_LEVEL_HIGH>;
 		clocks = <&mstp9_clks R7S72100_CLK_I2C2>;
 		clock-frequency = <100000>;
+		power-domains = <&cpg_clocks>;
 		status = "disabled";
 	};
 
@@ -392,6 +409,7 @@
 			     <0 188 IRQ_TYPE_LEVEL_HIGH>;
 		clocks = <&mstp9_clks R7S72100_CLK_I2C3>;
 		clock-frequency = <100000>;
+		power-domains = <&cpg_clocks>;
 		status = "disabled";
 	};
 
@@ -402,6 +420,7 @@
 		interrupt-names = "tgi0a";
 		clocks = <&mstp3_clks R7S72100_CLK_MTU2>;
 		clock-names = "fck";
+		power-domains = <&cpg_clocks>;
 		status = "disabled";
 	};
 };
-- 
1.9.1



From geert+renesas at glider.be  Tue Aug  4 05:28:12 2015
From: geert+renesas at glider.be (Geert Uytterhoeven)
Date: Tue,  4 Aug 2015 14:28:12 +0200
Subject: [PATCH v4 11/16] ARM: shmobile: r8a7793 dtsi: Add CPG/MSTP Clock
 Domain
In-Reply-To: <1438691297-29235-1-git-send-email-geert+renesas@glider.be>
References: <1438691297-29235-1-git-send-email-geert+renesas@glider.be>
Message-ID: <1438691297-29235-12-git-send-email-geert+renesas@glider.be>

Add an appropriate "#power-domain-cells" property to the cpg_clocks
device node, to create the CPG/MSTP Clock Domain.

Add "power-domains" properties to all device nodes for devices that are
part of the CPG/MSTP Clock Domain and can be power-managed through an
MSTP clock.  This applies to most on-SoC devices, which have a
one-to-one mapping from SoC device to DT device node.

Signed-off-by: Geert Uytterhoeven <geert+renesas at glider.be>
Reviewed-by: Ulf Hansson <ulf.hansson at linaro.org>
---
v4:
  - Add Reviewed-by,

v3:
  - New.
---
 arch/arm/boot/dts/r8a7793.dtsi | 7 +++++++
 1 file changed, 7 insertions(+)

diff --git a/arch/arm/boot/dts/r8a7793.dtsi b/arch/arm/boot/dts/r8a7793.dtsi
index 3355c487d108360f..c4654047e684ff09 100644
--- a/arch/arm/boot/dts/r8a7793.dtsi
+++ b/arch/arm/boot/dts/r8a7793.dtsi
@@ -68,6 +68,7 @@
 			     <0 143 IRQ_TYPE_LEVEL_HIGH>;
 		clocks = <&mstp1_clks R8A7793_CLK_CMT0>;
 		clock-names = "fck";
+		power-domains = <&cpg_clocks>;
 
 		renesas,channels-mask = <0x60>;
 
@@ -87,6 +88,7 @@
 			     <0 127 IRQ_TYPE_LEVEL_HIGH>;
 		clocks = <&mstp3_clks R8A7793_CLK_CMT1>;
 		clock-names = "fck";
+		power-domains = <&cpg_clocks>;
 
 		renesas,channels-mask = <0xff>;
 
@@ -109,6 +111,7 @@
 			     <0 16 IRQ_TYPE_LEVEL_HIGH>,
 			     <0 17 IRQ_TYPE_LEVEL_HIGH>;
 		clocks = <&mstp4_clks R8A7793_CLK_IRQC>;
+		power-domains = <&cpg_clocks>;
 	};
 
 	scif0: serial at e6e60000 {
@@ -117,6 +120,7 @@
 		interrupts = <0 152 IRQ_TYPE_LEVEL_HIGH>;
 		clocks = <&mstp7_clks R8A7793_CLK_SCIF0>;
 		clock-names = "sci_ick";
+		power-domains = <&cpg_clocks>;
 		status = "disabled";
 	};
 
@@ -126,6 +130,7 @@
 		interrupts = <0 153 IRQ_TYPE_LEVEL_HIGH>;
 		clocks = <&mstp7_clks R8A7793_CLK_SCIF1>;
 		clock-names = "sci_ick";
+		power-domains = <&cpg_clocks>;
 		status = "disabled";
 	};
 
@@ -134,6 +139,7 @@
 		reg = <0 0xee700000 0 0x400>;
 		interrupts = <0 162 IRQ_TYPE_LEVEL_HIGH>;
 		clocks = <&mstp8_clks R8A7793_CLK_ETHER>;
+		power-domains = <&cpg_clocks>;
 		phy-mode = "rmii";
 		#address-cells = <1>;
 		#size-cells = <0>;
@@ -164,6 +170,7 @@
 			clock-output-names = "main", "pll0", "pll1", "pll3",
 					     "lb", "qspi", "sdh", "sd0", "z",
 					     "rcan", "adsp";
+			#power-domain-cells = <0>;
 		};
 
 		/* Variable factor clocks */
-- 
1.9.1



From p.zabel at pengutronix.de  Tue Aug  4 06:02:22 2015
From: p.zabel at pengutronix.de (Philipp Zabel)
Date: Tue,  4 Aug 2015 15:02:22 +0200
Subject: [PATCH 3/3] ARM: imx6: Add clock to OCOTP node
In-Reply-To: <1438693342-605-1-git-send-email-p.zabel@pengutronix.de>
References: <1438693342-605-1-git-send-email-p.zabel@pengutronix.de>
Message-ID: <1438693342-605-3-git-send-email-p.zabel@pengutronix.de>

The OCOTP shadow register space is clocked by the ungated ipg root clock,
but to actually sense the fuses, the On-Chip OTP controller needs a
separate clock.

Signed-off-by: Philipp Zabel <p.zabel at pengutronix.de>
---
 arch/arm/boot/dts/imx6qdl.dtsi | 1 +
 1 file changed, 1 insertion(+)

diff --git a/arch/arm/boot/dts/imx6qdl.dtsi b/arch/arm/boot/dts/imx6qdl.dtsi
index e6d1359..07a5d75 100644
--- a/arch/arm/boot/dts/imx6qdl.dtsi
+++ b/arch/arm/boot/dts/imx6qdl.dtsi
@@ -1015,6 +1015,7 @@
 			ocotp: ocotp at 021bc000 {
 				compatible = "fsl,imx6q-ocotp", "syscon";
 				reg = <0x021bc000 0x4000>;
+				clocks = <&clks IMX6QDL_CLK_IIM>;
 			};
 
 			tzasc at 021d0000 { /* TZASC1 */
-- 
2.1.4



From p.zabel at pengutronix.de  Tue Aug  4 06:02:20 2015
From: p.zabel at pengutronix.de (Philipp Zabel)
Date: Tue,  4 Aug 2015 15:02:20 +0200
Subject: [PATCH 1/3] nvmem: Add i.MX6 OCOTP device tree binding documentation
Message-ID: <1438693342-605-1-git-send-email-p.zabel@pengutronix.de>

This patch documents the i.MX6 OCOTP device tree binding.

Signed-off-by: Philipp Zabel <p.zabel at pengutronix.de>
---
 .../devicetree/bindings/nvmem/imx-ocotp.txt          | 20 ++++++++++++++++++++
 1 file changed, 20 insertions(+)
 create mode 100644 Documentation/devicetree/bindings/nvmem/imx-ocotp.txt

diff --git a/Documentation/devicetree/bindings/nvmem/imx-ocotp.txt b/Documentation/devicetree/bindings/nvmem/imx-ocotp.txt
new file mode 100644
index 0000000..7d9a3fc
--- /dev/null
+++ b/Documentation/devicetree/bindings/nvmem/imx-ocotp.txt
@@ -0,0 +1,20 @@
+Freescale i.MX6 On-Chip OTP Controller (OCOTP) device tree bindings
+
+This binding represents the on-chip eFuse OTP controller found on
+i.MX6Q/D, i.MX6DL/S, i.MX6SL, and i.MX6SX SoCs.
+
+Required properties:
+- compatible: should be one of
+	"fsl,imx6q-ocotp" (i.MX6Q/D/DL/S),
+        "fsl,imx6sl-ocotp" (i.MX6SL), or
+	"fsl,imx6sx-ocotp" (i.MX6SX), followed by "syscon".
+- reg: Should contain the register base and length.
+- clocks: Should contain a phandle pointing to the gated peripheral clock.
+
+Example:
+
+	ocotp: ocotp at 021bc000 {
+		compatible = "fsl,imx6q-ocotp", "syscon";
+		reg = <0x021bc000 0x4000>;
+		clocks = <&clks IMX6QDL_CLK_IIM>;
+	};
-- 
2.1.4



From p.zabel at pengutronix.de  Tue Aug  4 06:02:21 2015
From: p.zabel at pengutronix.de (Philipp Zabel)
Date: Tue,  4 Aug 2015 15:02:21 +0200
Subject: [PATCH 2/3] nvmem: imx-ocotp: Add i.MX6 OCOTP driver
In-Reply-To: <1438693342-605-1-git-send-email-p.zabel@pengutronix.de>
References: <1438693342-605-1-git-send-email-p.zabel@pengutronix.de>
Message-ID: <1438693342-605-2-git-send-email-p.zabel@pengutronix.de>

This driver handles the i.MX On-Chip OTP Controller found in
i.MX6Q/D, i.MX6S/DL, i.MX6SL, and i.MX6SX SoCs. Currently it
just returns the values stored in the shadow registers.

Signed-off-by: Philipp Zabel <p.zabel at pengutronix.de>
---
This patch is based on the v9 "Add simple NVMEM Framework via regmap"
series which can be found here: https://lkml.org/lkml/2015/7/27/342
---
 drivers/nvmem/Kconfig     |  11 ++++
 drivers/nvmem/Makefile    |   2 +
 drivers/nvmem/imx-ocotp.c | 155 ++++++++++++++++++++++++++++++++++++++++++++++
 3 files changed, 168 insertions(+)
 create mode 100644 drivers/nvmem/imx-ocotp.c

diff --git a/drivers/nvmem/Kconfig b/drivers/nvmem/Kconfig
index 8db2978..0b33014 100644
--- a/drivers/nvmem/Kconfig
+++ b/drivers/nvmem/Kconfig
@@ -36,4 +36,15 @@ config NVMEM_SUNXI_SID
 	  This driver can also be built as a module. If so, the module
 	  will be called nvmem_sunxi_sid.
 
+config NVMEM_IMX_OCOTP
+	tristate "i.MX6 On-Chip OTP Controller support"
+	depends on SOC_IMX6
+	help
+	  This is a driver for the On-Chip OTP Controller (OCOTP) available on
+	  i.MX6 SoCs, providing access to 4 Kbits of one-time programmable
+	  eFuses.
+
+	  This driver can also be built as a module. If so, the module
+	  will be called nvmem-imx-ocotp.
+
 endif
diff --git a/drivers/nvmem/Makefile b/drivers/nvmem/Makefile
index 4328b93..b512d77 100644
--- a/drivers/nvmem/Makefile
+++ b/drivers/nvmem/Makefile
@@ -10,3 +10,5 @@ obj-$(CONFIG_QCOM_QFPROM)	+= nvmem_qfprom.o
 nvmem_qfprom-y			:= qfprom.o
 obj-$(CONFIG_NVMEM_SUNXI_SID)	+= nvmem_sunxi_sid.o
 nvmem_sunxi_sid-y		:= sunxi_sid.o
+obj-$(CONFIG_NVMEM_IMX_OCOTP)	+= nvmem-imx-ocotp.o
+nvmem-imx-ocotp-y		:= imx-ocotp.o
diff --git a/drivers/nvmem/imx-ocotp.c b/drivers/nvmem/imx-ocotp.c
new file mode 100644
index 0000000..e918967
--- /dev/null
+++ b/drivers/nvmem/imx-ocotp.c
@@ -0,0 +1,155 @@
+/*
+ * i.MX6 OCOTP fusebox driver
+ *
+ * Copyright (c) 2015 Pengutronix, Philipp Zabel <p.zabel at pengutronix.de>
+ *
+ * Based on the barebox ocotp driver,
+ * Copyright (c) 2010 Baruch Siach <baruch at tkos.co.il>,
+ *	Orex Computed Radiography
+ *
+ * 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.
+ *
+ * http://www.opensource.org/licenses/gpl-license.html
+ * http://www.gnu.org/copyleft/gpl.html
+ */
+
+#include <linux/clk.h>
+#include <linux/device.h>
+#include <linux/io.h>
+#include <linux/module.h>
+#include <linux/nvmem-provider.h>
+#include <linux/of.h>
+#include <linux/of_device.h>
+#include <linux/platform_device.h>
+#include <linux/regmap.h>
+#include <linux/slab.h>
+
+struct ocotp_priv {
+	struct device *dev;
+	void __iomem *base;
+	unsigned int nregs;
+};
+
+static int imx_ocotp_read(void *context, const void *reg, size_t reg_size,
+			  void *val, size_t val_size)
+{
+	struct ocotp_priv *priv = context;
+	unsigned int offset = *(u32 *)reg;
+	unsigned int count;
+	int i;
+	u32 index;
+
+	index = offset >> 2;
+	count = val_size >> 2;
+
+	if (count > (priv->nregs - index))
+		count = priv->nregs - index;
+
+	for (i = index; i < (index + count); i++) {
+		*(u32 *)val = readl(priv->base + 0x400 + i * 0x10);
+		val += 4;
+	}
+
+	return (i - index) * 4;
+}
+
+static int imx_ocotp_write(void *context, const void *data, size_t count)
+{
+	/* Not implemented */
+	return 0;
+}
+
+static struct regmap_bus imx_ocotp_bus = {
+	.read = imx_ocotp_read,
+	.write = imx_ocotp_write,
+	.reg_format_endian_default = REGMAP_ENDIAN_NATIVE,
+	.val_format_endian_default = REGMAP_ENDIAN_NATIVE,
+};
+
+static bool imx_ocotp_writeable_reg(struct device *dev, unsigned int reg)
+{
+	return false;
+}
+
+static struct regmap_config imx_ocotp_regmap_config = {
+	.reg_bits = 32,
+	.val_bits = 32,
+	.reg_stride = 4,
+	.writeable_reg = imx_ocotp_writeable_reg,
+	.name = "imx-ocotp",
+};
+
+static struct nvmem_config imx_ocotp_nvmem_config = {
+	.name = "imx-ocotp",
+	.read_only = true,
+	.owner = THIS_MODULE,
+};
+
+static const struct of_device_id imx_ocotp_dt_ids[] = {
+	{ .compatible = "fsl,imx6q-ocotp",  (void *)128 },
+	{ .compatible = "fsl,imx6sl-ocotp", (void *)32 },
+	{ .compatible = "fsl,imx6sx-ocotp", (void *)128 },
+	{ },
+};
+MODULE_DEVICE_TABLE(of, imx_ocotp_dt_ids);
+
+static int imx_ocotp_probe(struct platform_device *pdev)
+{
+	const struct of_device_id *of_id;
+	struct device *dev = &pdev->dev;
+	struct resource *res;
+	struct regmap *regmap;
+	struct ocotp_priv *priv;
+	struct nvmem_device *nvmem;
+
+	priv = devm_kzalloc(dev, sizeof(*priv), GFP_KERNEL);
+	if (!priv)
+		return -ENOMEM;
+
+	res = platform_get_resource(pdev, IORESOURCE_MEM, 0);
+	priv->base = devm_ioremap_resource(dev, res);
+	if (IS_ERR(priv->base))
+		return PTR_ERR(priv->base);
+
+	of_id = of_match_device(imx_ocotp_dt_ids, dev);
+	priv->nregs = (unsigned int)of_id->data;
+	imx_ocotp_regmap_config.max_register = 4 * priv->nregs - 4;
+
+	regmap = devm_regmap_init(dev, &imx_ocotp_bus, priv,
+				  &imx_ocotp_regmap_config);
+	if (IS_ERR(regmap)) {
+		dev_err(dev, "regmap init failed\n");
+		return PTR_ERR(regmap);
+	}
+	imx_ocotp_nvmem_config.dev = dev;
+	nvmem = nvmem_register(&imx_ocotp_nvmem_config);
+	if (IS_ERR(nvmem))
+		return PTR_ERR(nvmem);
+
+	platform_set_drvdata(pdev, nvmem);
+
+	return 0;
+}
+
+static int imx_ocotp_remove(struct platform_device *pdev)
+{
+	struct nvmem_device *nvmem = platform_get_drvdata(pdev);
+
+	return nvmem_unregister(nvmem);
+}
+
+static struct platform_driver imx_ocotp_driver = {
+	.probe	= imx_ocotp_probe,
+	.remove	= imx_ocotp_remove,
+	.driver = {
+		.name	= "imx_ocotp",
+		.of_match_table = imx_ocotp_dt_ids,
+	},
+};
+module_platform_driver(imx_ocotp_driver);
+
+MODULE_AUTHOR("Philipp Zabel <p.zabel at pengutronix.de>");
+MODULE_DESCRIPTION("i.MX6 OCOTP fuse box driver");
+MODULE_LICENSE("GPL");
-- 
2.1.4



From p.zabel at pengutronix.de  Tue Aug  4 06:02:47 2015
From: p.zabel at pengutronix.de (Philipp Zabel)
Date: Tue, 04 Aug 2015 15:02:47 +0200
Subject: [PATCH v9 0/9] Add simple NVMEM Framework via regmap.
In-Reply-To: <1437995567-11203-1-git-send-email-srinivas.kandagatla@linaro.org>
References: <1437995567-11203-1-git-send-email-srinivas.kandagatla@linaro.org>
Message-ID: <1438693367.3793.29.camel@pengutronix.de>

Hi Srinivas,

Am Montag, den 27.07.2015, 12:12 +0100 schrieb Srinivas Kandagatla:
> Hi Greg/Kevin,
> 
> This patchset adds a new simple NVMEM framework to kernel, and it is tested
> with various drivers like "QCOM thermal sensors", "QCOM cpr driver",
> "begal bone cape manager" and few more on the way.

Tested-by: Philipp Zabel <p.zabel at pengutronix.de>
using the i.MX6 OCOTP shadow register range.

regards
Philipp



From christoffer.dall at linaro.org  Tue Aug  4 06:04:57 2015
From: christoffer.dall at linaro.org (Christoffer Dall)
Date: Tue, 4 Aug 2015 15:04:57 +0200
Subject: [PATCH v3 06/11] KVM: arm/arm64: vgic: Allow dynamic mapping of
 physical/virtual interrupts
In-Reply-To: <1437753309-17989-7-git-send-email-marc.zyngier@arm.com>
References: <1437753309-17989-1-git-send-email-marc.zyngier@arm.com>
 <1437753309-17989-7-git-send-email-marc.zyngier@arm.com>
Message-ID: <20150804130457.GA29335@cbox>

On Fri, Jul 24, 2015 at 04:55:04PM +0100, Marc Zyngier wrote:
> In order to be able to feed physical interrupts to a guest, we need
> to be able to establish the virtual-physical mapping between the two
> worlds.
> 
> The mappings are kept in a set of RCU lists, indexed by virtual interrupts.
> 
> Signed-off-by: Marc Zyngier <marc.zyngier at arm.com>
> ---
>  arch/arm/kvm/arm.c     |   2 +
>  include/kvm/arm_vgic.h |  26 +++++++
>  virt/kvm/arm/vgic.c    | 189 ++++++++++++++++++++++++++++++++++++++++++++++++-
>  3 files changed, 216 insertions(+), 1 deletion(-)
> 
> diff --git a/arch/arm/kvm/arm.c b/arch/arm/kvm/arm.c
> index f1bf418..ce404a5 100644
> --- a/arch/arm/kvm/arm.c
> +++ b/arch/arm/kvm/arm.c
> @@ -125,6 +125,7 @@ int kvm_arch_init_vm(struct kvm *kvm, unsigned long type)
>  	if (ret)
>  		goto out_free_stage2_pgd;
>  
> +	kvm_vgic_early_init(kvm);
>  	kvm_timer_init(kvm);
>  
>  	/* Mark the initial VMID generation invalid */
> @@ -249,6 +250,7 @@ out:
>  
>  void kvm_arch_vcpu_postcreate(struct kvm_vcpu *vcpu)
>  {
> +	kvm_vgic_vcpu_early_init(vcpu);
>  }
>  
>  void kvm_arch_vcpu_free(struct kvm_vcpu *vcpu)
> diff --git a/include/kvm/arm_vgic.h b/include/kvm/arm_vgic.h
> index a881e39..68212a1 100644
> --- a/include/kvm/arm_vgic.h
> +++ b/include/kvm/arm_vgic.h
> @@ -159,6 +159,20 @@ struct vgic_io_device {
>  	struct kvm_io_device dev;
>  };
>  
> +struct irq_phys_map {
> +	u32			virt_irq;
> +	u32			phys_irq;
> +	u32			irq;
> +	bool			deleted;
> +	bool			active;
> +};
> +
> +struct irq_phys_map_entry {
> +	struct list_head	entry;
> +	struct rcu_head		rcu;
> +	struct irq_phys_map	map;
> +};
> +
>  struct vgic_dist {
>  	spinlock_t		lock;
>  	bool			in_kernel;
> @@ -256,6 +270,10 @@ struct vgic_dist {
>  	struct vgic_vm_ops	vm_ops;
>  	struct vgic_io_device	dist_iodev;
>  	struct vgic_io_device	*redist_iodevs;
> +
> +	/* Virtual irq to hwirq mapping */
> +	spinlock_t		irq_phys_map_lock;
> +	struct list_head	irq_phys_map_list;
>  };
>  
>  struct vgic_v2_cpu_if {
> @@ -307,6 +325,9 @@ struct vgic_cpu {
>  		struct vgic_v2_cpu_if	vgic_v2;
>  		struct vgic_v3_cpu_if	vgic_v3;
>  	};
> +
> +	/* Protected by the distributor's irq_phys_map_lock */
> +	struct list_head	irq_phys_map_list;
>  };
>  
>  #define LR_EMPTY	0xff
> @@ -321,8 +342,10 @@ int kvm_vgic_addr(struct kvm *kvm, unsigned long type, u64 *addr, bool write);
>  int kvm_vgic_hyp_init(void);
>  int kvm_vgic_map_resources(struct kvm *kvm);
>  int kvm_vgic_get_max_vcpus(void);
> +void kvm_vgic_early_init(struct kvm *kvm);
>  int kvm_vgic_create(struct kvm *kvm, u32 type);
>  void kvm_vgic_destroy(struct kvm *kvm);
> +void kvm_vgic_vcpu_early_init(struct kvm_vcpu *vcpu);
>  void kvm_vgic_vcpu_destroy(struct kvm_vcpu *vcpu);
>  void kvm_vgic_flush_hwstate(struct kvm_vcpu *vcpu);
>  void kvm_vgic_sync_hwstate(struct kvm_vcpu *vcpu);
> @@ -331,6 +354,9 @@ int kvm_vgic_inject_irq(struct kvm *kvm, int cpuid, unsigned int irq_num,
>  void vgic_v3_dispatch_sgi(struct kvm_vcpu *vcpu, u64 reg);
>  int kvm_vgic_vcpu_pending_irq(struct kvm_vcpu *vcpu);
>  int kvm_vgic_vcpu_active_irq(struct kvm_vcpu *vcpu);
> +struct irq_phys_map *kvm_vgic_map_phys_irq(struct kvm_vcpu *vcpu,
> +					   int virt_irq, int irq);
> +int kvm_vgic_unmap_phys_irq(struct kvm_vcpu *vcpu, struct irq_phys_map *map);
>  
>  #define irqchip_in_kernel(k)	(!!((k)->arch.vgic.in_kernel))
>  #define vgic_initialized(k)	(!!((k)->arch.vgic.nr_cpus))
> diff --git a/virt/kvm/arm/vgic.c b/virt/kvm/arm/vgic.c
> index 5bd1695..c74d929 100644
> --- a/virt/kvm/arm/vgic.c
> +++ b/virt/kvm/arm/vgic.c
> @@ -24,6 +24,7 @@
>  #include <linux/of.h>
>  #include <linux/of_address.h>
>  #include <linux/of_irq.h>
> +#include <linux/rculist.h>
>  #include <linux/uaccess.h>
>  
>  #include <asm/kvm_emulate.h>
> @@ -82,6 +83,8 @@ static void vgic_retire_disabled_irqs(struct kvm_vcpu *vcpu);
>  static void vgic_retire_lr(int lr_nr, int irq, struct kvm_vcpu *vcpu);
>  static struct vgic_lr vgic_get_lr(const struct kvm_vcpu *vcpu, int lr);
>  static void vgic_set_lr(struct kvm_vcpu *vcpu, int lr, struct vgic_lr lr_desc);
> +static struct irq_phys_map *vgic_irq_map_search(struct kvm_vcpu *vcpu,
> +						int virt_irq);
>  
>  static const struct vgic_ops *vgic_ops;
>  static const struct vgic_params *vgic;
> @@ -1583,6 +1586,166 @@ static irqreturn_t vgic_maintenance_handler(int irq, void *data)
>  	return IRQ_HANDLED;
>  }
>  
> +static struct list_head *vgic_get_irq_phys_map_list(struct kvm_vcpu *vcpu,
> +						    int virt_irq)
> +{
> +	if (virt_irq < VGIC_NR_PRIVATE_IRQS)
> +		return &vcpu->arch.vgic_cpu.irq_phys_map_list;
> +	else
> +		return &vcpu->kvm->arch.vgic.irq_phys_map_list;
> +}
> +
> +/**
> + * kvm_vgic_map_phys_irq - map a virtual IRQ to a physical IRQ
> + * @vcpu: The VCPU pointer
> + * @virt_irq: The virtual irq number
> + * @irq: The Linux IRQ number
> + *
> + * Establish a mapping between a guest visible irq (@virt_irq) and a
> + * Linux irq (@irq). On injection, @virt_irq will be associated with
> + * the physical interrupt represented by @irq.
> + *
> + * Returns a valid pointer on success, and an error pointer otherwise
> + */
> +struct irq_phys_map *kvm_vgic_map_phys_irq(struct kvm_vcpu *vcpu,
> +					   int virt_irq, int irq)
> +{
> +	struct vgic_dist *dist = &vcpu->kvm->arch.vgic;
> +	struct list_head *root = vgic_get_irq_phys_map_list(vcpu, virt_irq);
> +	struct irq_phys_map *map;
> +	struct irq_phys_map_entry *entry;
> +	struct irq_desc *desc;
> +	struct irq_data *data;
> +	int phys_irq;
> +
> +	desc = irq_to_desc(irq);
> +	if (!desc) {
> +		kvm_err("kvm_vgic_map_phys_irq: no interrupt descriptor\n");

super over-ridiculous nit:
if you respin you could consider "%s: no...", __FUNC__

> +		return ERR_PTR(-EINVAL);
> +	}
> +
> +	data = irq_desc_get_irq_data(desc);
> +	while (data->parent_data)
> +		data = data->parent_data;
> +
> +	phys_irq = data->hwirq;
> +
> +	/* Create a new mapping */
> +	entry = kzalloc(sizeof(*entry), GFP_KERNEL);
> +	if (!entry)
> +		return ERR_PTR(-ENOMEM);
> +
> +	spin_lock(&dist->irq_phys_map_lock);
> +
> +	/* Try to match an existing mapping */
> +	map = vgic_irq_map_search(vcpu, virt_irq);
> +	if (map) {
> +		/* Make sure this mapping matches */

why do we need to check that it matches?  Is it ever allowed to have
multiple mappings of a virtual interrupt?

> +		if (map->phys_irq != phys_irq	||
> +		    map->irq      != irq)
> +			map = ERR_PTR(-EINVAL);
> +
> +		goto out;

why is this a valid situation?  Shouldn't you return -EEXIST or
something instead?  (that would also simplify the error-checking free
routine below).

If you want it to be valid to map the same virq to irq multiple times
(to free the caller from some bookkeeping, I presume?) then that should
be part of the function documentation, and I think we should add a
"found existing mapping" comment above the goto out statement.

> +	}
> +
> +	map           = &entry->map;
> +	map->virt_irq = virt_irq;
> +	map->phys_irq = phys_irq;
> +	map->irq      = irq;
> +
> +	list_add_tail_rcu(&entry->entry, root);
> +
> +out:
> +	spin_unlock(&dist->irq_phys_map_lock);
> +	/* If we've found a hit in the existing list, free the useless
> +	 * entry */
> +	if (IS_ERR(map) || map != &entry->map)
> +		kfree(entry);
> +	return map;
> +}
> +
> +static struct irq_phys_map *vgic_irq_map_search(struct kvm_vcpu *vcpu,
> +						int virt_irq)
> +{
> +	struct list_head *root = vgic_get_irq_phys_map_list(vcpu, virt_irq);
> +	struct irq_phys_map_entry *entry;
> +	struct irq_phys_map *map;
> +
> +	rcu_read_lock();
> +
> +	list_for_each_entry_rcu(entry, root, entry) {
> +		map = &entry->map;
> +		if (map->virt_irq == virt_irq && !map->deleted) {
> +			rcu_read_unlock();
> +			return map;
> +		}
> +	}
> +
> +	rcu_read_unlock();
> +
> +	return NULL;
> +}
> +
> +static void vgic_free_phys_irq_map_rcu(struct rcu_head *rcu)
> +{
> +	struct irq_phys_map_entry *entry;
> +
> +	entry = container_of(rcu, struct irq_phys_map_entry, rcu);
> +	kfree(entry);
> +}
> +
> +/**
> + * kvm_vgic_unmap_phys_irq - Remove a virtual to physical IRQ mapping
> + * @vcpu: The VCPU pointer
> + * @map: The pointer to a mapping obtained through kvm_vgic_map_phys_irq
> + *
> + * Remove an existing mapping between virtual and physical interrupts.
> + */
> +int kvm_vgic_unmap_phys_irq(struct kvm_vcpu *vcpu, struct irq_phys_map *map)
> +{
> +	struct vgic_dist *dist = &vcpu->kvm->arch.vgic;
> +	struct irq_phys_map_entry *entry;
> +	struct list_head *root;
> +
> +	if (!map)
> +		return -EINVAL;
> +
> +	root = vgic_get_irq_phys_map_list(vcpu, map->virt_irq);
> +
> +	spin_lock(&dist->irq_phys_map_lock);
> +
> +	list_for_each_entry(entry, root, entry) {
> +		if (&entry->map == map && !map->deleted) {
> +			map->deleted = true;

why do you need the 'deleted' flag?  You now search the list only after
holding the lock, so the race I pointed out before doesn't exist
anymore.  Is there an additional issue that the deleted flag is taking
care of?

> +			list_del_rcu(&entry->entry);
> +			call_rcu(&entry->rcu, vgic_free_phys_irq_map_rcu);
> +			break;
> +		}
> +	}
> +
> +	spin_unlock(&dist->irq_phys_map_lock);
> +
> +	return 0;
> +}
> +
> +static void vgic_destroy_irq_phys_map(struct kvm *kvm, struct list_head *root)
> +{
> +	struct vgic_dist *dist = &kvm->arch.vgic;
> +	struct irq_phys_map_entry *entry;
> +
> +	spin_lock(&dist->irq_phys_map_lock);
> +
> +	list_for_each_entry(entry, root, entry) {
> +		if (!entry->map.deleted) {
> +			entry->map.deleted = true;
> +			list_del_rcu(&entry->entry);
> +			call_rcu(&entry->rcu, vgic_free_phys_irq_map_rcu);
> +		}
> +	}
> +
> +	spin_unlock(&dist->irq_phys_map_lock);
> +}
> +
>  void kvm_vgic_vcpu_destroy(struct kvm_vcpu *vcpu)
>  {
>  	struct vgic_cpu *vgic_cpu = &vcpu->arch.vgic_cpu;
> @@ -1591,6 +1754,7 @@ void kvm_vgic_vcpu_destroy(struct kvm_vcpu *vcpu)
>  	kfree(vgic_cpu->active_shared);
>  	kfree(vgic_cpu->pend_act_shared);
>  	kfree(vgic_cpu->vgic_irq_lr_map);
> +	vgic_destroy_irq_phys_map(vcpu->kvm, &vgic_cpu->irq_phys_map_list);
>  	vgic_cpu->pending_shared = NULL;
>  	vgic_cpu->active_shared = NULL;
>  	vgic_cpu->pend_act_shared = NULL;
> @@ -1628,6 +1792,17 @@ static int vgic_vcpu_init_maps(struct kvm_vcpu *vcpu, int nr_irqs)
>  }
>  
>  /**
> + * kvm_vgic_vcpu_early_init - Earliest possible per-vcpu vgic init stage

earliest possible... oh how I love the vgic code.

If you have the energy and context to write a comment in the beginning
of this file describing the init flow, I think that would be useful...

> + *
> + * No memory allocation should be performed here, only static init.
> + */
> +void kvm_vgic_vcpu_early_init(struct kvm_vcpu *vcpu)
> +{
> +	struct vgic_cpu *vgic_cpu = &vcpu->arch.vgic_cpu;
> +	INIT_LIST_HEAD(&vgic_cpu->irq_phys_map_list);
> +}
> +
> +/**
>   * kvm_vgic_get_max_vcpus - Get the maximum number of VCPUs allowed by HW
>   *
>   * The host's GIC naturally limits the maximum amount of VCPUs a guest
> @@ -1664,6 +1839,7 @@ void kvm_vgic_destroy(struct kvm *kvm)
>  	kfree(dist->irq_spi_target);
>  	kfree(dist->irq_pending_on_cpu);
>  	kfree(dist->irq_active_on_cpu);
> +	vgic_destroy_irq_phys_map(kvm, &dist->irq_phys_map_list);
>  	dist->irq_sgi_sources = NULL;
>  	dist->irq_spi_cpu = NULL;
>  	dist->irq_spi_target = NULL;
> @@ -1787,6 +1963,18 @@ static int init_vgic_model(struct kvm *kvm, int type)
>  	return 0;
>  }
>  
> +/**
> + * kvm_vgic_early_init - Earliest possible vgic initialization stage
> + *
> + * No memory allocation should be performed here, only static init.
> + */
> +void kvm_vgic_early_init(struct kvm *kvm)
> +{
> +	spin_lock_init(&kvm->arch.vgic.lock);

so here we're initializing the data structures even before the vgic is
created, right?  So therefore it's safe to move the vgic.lock init up
here?

> +	spin_lock_init(&kvm->arch.vgic.irq_phys_map_lock);
> +	INIT_LIST_HEAD(&kvm->arch.vgic.irq_phys_map_list);
> +}
> +
>  int kvm_vgic_create(struct kvm *kvm, u32 type)
>  {
>  	int i, vcpu_lock_idx = -1, ret;
> @@ -1832,7 +2020,6 @@ int kvm_vgic_create(struct kvm *kvm, u32 type)
>  	if (ret)
>  		goto out_unlock;
>  
> -	spin_lock_init(&kvm->arch.vgic.lock);
>  	kvm->arch.vgic.in_kernel = true;
>  	kvm->arch.vgic.vgic_model = type;
>  	kvm->arch.vgic.vctrl_base = vgic->vctrl_base;
> -- 
> 2.1.4
> 

Thanks,
-Christoffer


From gregory.clement at free-electrons.com  Tue Aug  4 06:08:36 2015
From: gregory.clement at free-electrons.com (Gregory CLEMENT)
Date: Tue, 04 Aug 2015 15:08:36 +0200
Subject: MUSB dual-role on AM335x behaving weirdly
In-Reply-To: <CADYTM3ZF5m++N1NqmOJoH5agbYrzpvSbLnuLVgttxwzdzwmGwQ@mail.gmail.com>
References: <20150514190429.GT24269@saruman.tx.rr.com>	<CADYTM3Zso8bV_8yFyx1-ATbL5AgkKBjvWWR4AsoZUNuLvFe1bQ@mail.gmail.com>	<20150514192125.GU24269@saruman.tx.rr.com>	<CADYTM3bbEAVefFZtivJf5Z+2Q+1zDZEvNhqE5ytsOxDX7hjbdA@mail.gmail.com>	<20150514192946.GV24269@saruman.tx.rr.com>	<CADYTM3Zk2iD8YMj75CoLJn=4kpoXoXEKUWj2QzdXKGCJjtfG2A@mail.gmail.com>	<CADYTM3a1QWnec1D=wT=fgZ-RCXAx_qZYYoFg5gWOy0yT4vovHA@mail.gmail.com>	<20150514212653.GC3338@piout.net>	<CADYTM3baVqoEBdWoQb5JFyGR2_GKm1FHMYWST1YkZV=m=ZdycQ@mail.gmail.com>	<20150526145118.GD26599@saruman.tx.rr.com>	<20150527094205.GO3199@piout.net>	<5594E56B.3040200@free-electrons.com>
 <CADYTM3ZF5m++N1NqmOJoH5agbYrzpvSbLnuLVgttxwzdzwmGwQ@mail.gmail.com>
Message-ID: <55C0B954.3020106@free-electrons.com>

Hi Bin,

On 02/07/2015 19:05, Bin Liu wrote:
> Hi,
> 
> On Thu, Jul 2, 2015 at 2:16 AM, Gregory CLEMENT
> <gregory.clement at free-electrons.com> wrote:
>> Hi Felipe,
>>
>> On 27/05/2015 11:42, Alexandre Belloni wrote:
>>> Hi,
>>>
>>> On 26/05/2015 at 09:51:18 -0500, Felipe Balbi wrote :
>>>> On Thu, May 14, 2015 at 04:36:33PM -0500, Bin Liu wrote:
>>>>> Alexandre,
>>>>>
>>>>> On Thu, May 14, 2015 at 4:26 PM, Alexandre Belloni
>>>>> <alexandre.belloni at free-electrons.com> wrote:
>>>>>> On 14/05/2015 at 16:16:12 -0500, Bin Liu wrote :
>>>>>>> I think I found the root cause of the problem: board design issue - I
>>>>>>> bet the custom board has too much cap on VBUS line. It should be <
>>>>>>> 10uF.
>>>>>>>
>>>>>>
>>>>>> We have a custom board that exhibits the issue but it only has a 100nF
>>>>>> cap on VBUS.
>>>>>
>>>>> Have you measured the VBUS discharging? Is there any way to share your
>>>>> schematics?
>>>>
>>>> Alexandre, any further comments ?
>>>>
>>>
>>> Yeah, I have just got more info.
>>>
>>> This is the relevant part of the schematic:
>>> http://free-electrons.com/~alexandre/usb.png
>>>
>>> The total VBUS capacitance is 200nF and the USB0 pins are connected
>>> directly to the AM3358 pins. U1 is actually not fitted.
>>>
>>> We didn't measure VBUS discharging but we observe the OTG pin sensing
>>> stops when plugging an OTG cable without any device.
>>
>> Do you have any news about this topic?
>>
>>
>> Is there something else that we can do to help solving this issue?
> 
> In the case of CONFIG_USB_MUSB_DUAL_ROLE=y and dr_mode=otg, how is the
> gadget driver configured? It has to be a module not built-in.

Indeed when I configured CONFIG_USB_MUSB_HDRC=m and CONFIG_USB_MUSB_DSPS=m
it worked seamless.


Thanks,

Gregory

> 
> Regards,
> -Bin.
> 
>>
>>
>> Thanks,
>>
>> Gregory
>>
>>
>> --
>> Gregory Clement, Free Electrons
>> Kernel, drivers, real-time and embedded Linux
>> development, consulting, training and support.
>> http://free-electrons.com


-- 
Gregory Clement, Free Electrons
Kernel, drivers, real-time and embedded Linux
development, consulting, training and support.
http://free-electrons.com


From laurent.pinchart at ideasonboard.com  Tue Aug  4 06:16:28 2015
From: laurent.pinchart at ideasonboard.com (Laurent Pinchart)
Date: Tue, 04 Aug 2015 16:16:28 +0300
Subject: [PATCH 05/13] iommu/io-pgtable-arm: Allow appropriate DMA API use
In-Reply-To: <1438608355-7335-6-git-send-email-will.deacon@arm.com>
References: <1438608355-7335-1-git-send-email-will.deacon@arm.com>
 <1438608355-7335-6-git-send-email-will.deacon@arm.com>
Message-ID: <1652248.uq2uhTW4Yd@avalon>

Hi Will and Robin,

Thank you for the patch.

On Monday 03 August 2015 14:25:47 Will Deacon wrote:
> From: Robin Murphy <Robin.Murphy at arm.com>
> 
> Currently, users of the LPAE page table code are (ab)using dma_map_page()
> as a means to flush page table updates for non-coherent IOMMUs. Since
> from the CPU's point of view, creating IOMMU page tables *is* passing
> DMA buffers to a device (the IOMMU's page table walker), there's little
> reason not to use the DMA API correctly.
> 
> Allow IOMMU drivers to opt into DMA API operations for page table
> allocation and updates by providing their appropriate device pointer.
> The expectation is that an LPAE IOMMU should have a full view of system
> memory, so use streaming mappings to avoid unnecessary pressure on
> ZONE_DMA, and treat any DMA translation as a warning sign.

I like the idea of doing this in core code rather than in individual drivers, 
but I believe we're not using the right API. Please see below.

> Signed-off-by: Robin Murphy <robin.murphy at arm.com>
> Signed-off-by: Will Deacon <will.deacon at arm.com>
> ---
>  drivers/iommu/Kconfig          |   3 +-
>  drivers/iommu/io-pgtable-arm.c | 107 +++++++++++++++++++++++++++++---------
>  drivers/iommu/io-pgtable.h     |   3 ++
>  3 files changed, 89 insertions(+), 24 deletions(-)
> 
> diff --git a/drivers/iommu/Kconfig b/drivers/iommu/Kconfig
> index f1fb1d3ccc56..d77a848d50de 100644
> --- a/drivers/iommu/Kconfig
> +++ b/drivers/iommu/Kconfig
> @@ -23,7 +23,8 @@ config IOMMU_IO_PGTABLE
>  config IOMMU_IO_PGTABLE_LPAE
>  	bool "ARMv7/v8 Long Descriptor Format"
>  	select IOMMU_IO_PGTABLE
> -	depends on ARM || ARM64 || COMPILE_TEST
> +	# SWIOTLB guarantees a dma_to_phys() implementation
> +	depends on ARM || ARM64 || (COMPILE_TEST && SWIOTLB)
>  	help
>  	  Enable support for the ARM long descriptor pagetable format.
>  	  This allocator supports 4K/2M/1G, 16K/32M and 64K/512M page
> diff --git a/drivers/iommu/io-pgtable-arm.c b/drivers/iommu/io-pgtable-arm.c
> index 4e460216bd16..28cca8a652f9 100644
> --- a/drivers/iommu/io-pgtable-arm.c
> +++ b/drivers/iommu/io-pgtable-arm.c
> @@ -200,12 +200,76 @@ typedef u64 arm_lpae_iopte;
> 
>  static bool selftest_running = false;
> 
> +static dma_addr_t __arm_lpae_dma_addr(struct device *dev, void *pages)
> +{
> +	return phys_to_dma(dev, virt_to_phys(pages));
> +}
> +
> +static void *__arm_lpae_alloc_pages(size_t size, gfp_t gfp,
> +				    struct io_pgtable_cfg *cfg)
> +{
> +	struct device *dev = cfg->iommu_dev;
> +	dma_addr_t dma;
> +	void *pages = alloc_pages_exact(size, gfp | __GFP_ZERO);
> +
> +	if (!pages)
> +		return NULL;
> +
> +	if (dev) {
> +		dma = dma_map_single(dev, pages, size, DMA_TO_DEVICE);
> +		if (dma_mapping_error(dev, dma))
> +			goto out_free;
> +		/*
> +		 * We depend on the IOMMU being able to work with any physical
> +		 * address directly, so if the DMA layer suggests it can't by
> +		 * giving us back some translation, that bodes very badly...
> +		 */
> +		if (dma != __arm_lpae_dma_addr(dev, pages))
> +			goto out_unmap;

Why do we need to create a mapping at all then ? Because 
dma_sync_single_for_device() requires it ?

> +	}
> +
> +	return pages;
> +
> +out_unmap:
> +	dev_err(dev, "Cannot accommodate DMA translation for IOMMU page
> tables\n");
> +	dma_unmap_single(dev, dma, size, DMA_TO_DEVICE);
> +out_free:
> +	free_pages_exact(pages, size);
> +	return NULL;
> +}
> +
> +static void __arm_lpae_free_pages(void *pages, size_t size,
> +				  struct io_pgtable_cfg *cfg)
> +{
> +	struct device *dev = cfg->iommu_dev;
> +
> +	if (dev)
> +		dma_unmap_single(dev, __arm_lpae_dma_addr(dev, pages),
> +				 size, DMA_TO_DEVICE);
> +	free_pages_exact(pages, size);
> +}
> +
> +static void __arm_lpae_set_pte(arm_lpae_iopte *ptep, arm_lpae_iopte pte,
> +			       struct io_pgtable_cfg *cfg, void *cookie)
> +{
> +	struct device *dev = cfg->iommu_dev;
> +
> +	*ptep = pte;
> +
> +	if (dev)
> +		dma_sync_single_for_device(dev, __arm_lpae_dma_addr(dev, ptep),
> +					   sizeof(pte), DMA_TO_DEVICE);

This is what I believe to be an API abuse. The dma_sync_single_for_device() 
API is meant to pass ownership of a buffer to the device. Unless I'm mistaken, 
once that's done the CPU isn't allowed to touch the buffer anymore until 
dma_sync_single_for_cpu() is called to get ownership of the buffer back. Sure, 
it might work on many ARM systems, but we really should be careful not to use 
APIs as delicate as DMA mapping and cache handling for purposes different than 
what they explicitly allow.

It might be that I'm wrong and that the streaming DMA API allows this exact 
kind of usage, but I haven't found a clear indication of that in the 
documentation. It could also be that all implementations would support it 
today, and that we would then consider it should be explicitly allowed by the 
API. In both cases a documentation patch would be welcome.

> +	else if (cfg->tlb->flush_pgtable)
> +		cfg->tlb->flush_pgtable(ptep, sizeof(pte), cookie);
> +}
> +
>  static int arm_lpae_init_pte(struct arm_lpae_io_pgtable *data,
>  			     unsigned long iova, phys_addr_t paddr,
>  			     arm_lpae_iopte prot, int lvl,
>  			     arm_lpae_iopte *ptep)
>  {
>  	arm_lpae_iopte pte = prot;
> +	struct io_pgtable_cfg *cfg = &data->iop.cfg;
> 
>  	/* We require an unmap first */
>  	if (iopte_leaf(*ptep, lvl)) {
> @@ -213,7 +277,7 @@ static int arm_lpae_init_pte(struct arm_lpae_io_pgtable
> *data, return -EEXIST;
>  	}
> 
> -	if (data->iop.cfg.quirks & IO_PGTABLE_QUIRK_ARM_NS)
> +	if (cfg->quirks & IO_PGTABLE_QUIRK_ARM_NS)
>  		pte |= ARM_LPAE_PTE_NS;
> 
>  	if (lvl == ARM_LPAE_MAX_LEVELS - 1)
> @@ -224,8 +288,7 @@ static int arm_lpae_init_pte(struct arm_lpae_io_pgtable
> *data, pte |= ARM_LPAE_PTE_AF | ARM_LPAE_PTE_SH_IS;
>  	pte |= pfn_to_iopte(paddr >> data->pg_shift, data);
> 
> -	*ptep = pte;
> -	data->iop.cfg.tlb->flush_pgtable(ptep, sizeof(*ptep), data->iop.cookie);
> +	__arm_lpae_set_pte(ptep, pte, cfg, data->iop.cookie);
>  	return 0;
>  }
> 
> @@ -236,12 +299,13 @@ static int __arm_lpae_map(struct arm_lpae_io_pgtable
> *data, unsigned long iova, arm_lpae_iopte *cptep, pte;
>  	void *cookie = data->iop.cookie;
>  	size_t block_size = ARM_LPAE_BLOCK_SIZE(lvl, data);
> +	struct io_pgtable_cfg *cfg = &data->iop.cfg;
> 
>  	/* Find our entry at the current level */
>  	ptep += ARM_LPAE_LVL_IDX(iova, lvl, data);
> 
>  	/* If we can install a leaf entry at this level, then do so */
> -	if (size == block_size && (size & data->iop.cfg.pgsize_bitmap))
> +	if (size == block_size && (size & cfg->pgsize_bitmap))
>  		return arm_lpae_init_pte(data, iova, paddr, prot, lvl, ptep);
> 
>  	/* We can't allocate tables at the final level */
> @@ -251,18 +315,15 @@ static int __arm_lpae_map(struct arm_lpae_io_pgtable
> *data, unsigned long iova, /* Grab a pointer to the next level */
>  	pte = *ptep;
>  	if (!pte) {
> -		cptep = alloc_pages_exact(1UL << data->pg_shift,
> -					 GFP_ATOMIC | __GFP_ZERO);
> +		cptep = __arm_lpae_alloc_pages(1UL << data->pg_shift,
> +					       GFP_ATOMIC, cfg);
>  		if (!cptep)
>  			return -ENOMEM;
> 
> -		data->iop.cfg.tlb->flush_pgtable(cptep, 1UL << data->pg_shift,
> -						 cookie);
>  		pte = __pa(cptep) | ARM_LPAE_PTE_TYPE_TABLE;
> -		if (data->iop.cfg.quirks & IO_PGTABLE_QUIRK_ARM_NS)
> +		if (cfg->quirks & IO_PGTABLE_QUIRK_ARM_NS)
>  			pte |= ARM_LPAE_PTE_NSTABLE;
> -		*ptep = pte;
> -		data->iop.cfg.tlb->flush_pgtable(ptep, sizeof(*ptep), cookie);
> +		__arm_lpae_set_pte(ptep, pte, cfg, cookie);
>  	} else {
>  		cptep = iopte_deref(pte, data);
>  	}
> @@ -347,7 +408,7 @@ static void __arm_lpae_free_pgtable(struct
> arm_lpae_io_pgtable *data, int lvl, __arm_lpae_free_pgtable(data, lvl + 1,
> iopte_deref(pte, data)); }
> 
> -	free_pages_exact(start, table_size);
> +	__arm_lpae_free_pages(start, table_size, &data->iop.cfg);
>  }
> 
>  static void arm_lpae_free_pgtable(struct io_pgtable *iop)
> @@ -366,8 +427,8 @@ static int arm_lpae_split_blk_unmap(struct
> arm_lpae_io_pgtable *data, unsigned long blk_start, blk_end;
>  	phys_addr_t blk_paddr;
>  	arm_lpae_iopte table = 0;
> +	struct io_pgtable_cfg *cfg = &data->iop.cfg;
>  	void *cookie = data->iop.cookie;
> -	const struct iommu_gather_ops *tlb = data->iop.cfg.tlb;
> 
>  	blk_start = iova & ~(blk_size - 1);
>  	blk_end = blk_start + blk_size;
> @@ -393,10 +454,9 @@ static int arm_lpae_split_blk_unmap(struct
> arm_lpae_io_pgtable *data, }
>  	}
> 
> -	*ptep = table;
> -	tlb->flush_pgtable(ptep, sizeof(*ptep), cookie);
> +	__arm_lpae_set_pte(ptep, table, cfg, cookie);
>  	iova &= ~(blk_size - 1);
> -	tlb->tlb_add_flush(iova, blk_size, true, cookie);
> +	cfg->tlb->tlb_add_flush(iova, blk_size, true, cookie);
>  	return size;
>  }
> 
> @@ -418,13 +478,12 @@ static int __arm_lpae_unmap(struct arm_lpae_io_pgtable
> *data,
> 
>  	/* If the size matches this level, we're in the right place */
>  	if (size == blk_size) {
> -		*ptep = 0;
> -		tlb->flush_pgtable(ptep, sizeof(*ptep), cookie);
> +		__arm_lpae_set_pte(ptep, 0, &data->iop.cfg, cookie);
> 
>  		if (!iopte_leaf(pte, lvl)) {
>  			/* Also flush any partial walks */
>  			tlb->tlb_add_flush(iova, size, false, cookie);
> -			tlb->tlb_sync(data->iop.cookie);
> +			tlb->tlb_sync(cookie);
>  			ptep = iopte_deref(pte, data);
>  			__arm_lpae_free_pgtable(data, lvl + 1, ptep);
>  		} else {
> @@ -640,11 +699,12 @@ arm_64_lpae_alloc_pgtable_s1(struct io_pgtable_cfg
> *cfg, void *cookie) cfg->arm_lpae_s1_cfg.mair[1] = 0;
> 
>  	/* Looking good; allocate a pgd */
> -	data->pgd = alloc_pages_exact(data->pgd_size, GFP_KERNEL | __GFP_ZERO);
> +	data->pgd = __arm_lpae_alloc_pages(data->pgd_size, GFP_KERNEL, cfg);
>  	if (!data->pgd)
>  		goto out_free_data;
> 
> -	cfg->tlb->flush_pgtable(data->pgd, data->pgd_size, cookie);
> +	if (cfg->tlb->flush_pgtable)
> +		cfg->tlb->flush_pgtable(data->pgd, data->pgd_size, cookie);
> 
>  	/* TTBRs */
>  	cfg->arm_lpae_s1_cfg.ttbr[0] = virt_to_phys(data->pgd);
> @@ -728,11 +788,12 @@ arm_64_lpae_alloc_pgtable_s2(struct io_pgtable_cfg
> *cfg, void *cookie) cfg->arm_lpae_s2_cfg.vtcr = reg;
> 
>  	/* Allocate pgd pages */
> -	data->pgd = alloc_pages_exact(data->pgd_size, GFP_KERNEL | __GFP_ZERO);
> +	data->pgd = __arm_lpae_alloc_pages(data->pgd_size, GFP_KERNEL, cfg);
>  	if (!data->pgd)
>  		goto out_free_data;
> 
> -	cfg->tlb->flush_pgtable(data->pgd, data->pgd_size, cookie);
> +	if (cfg->tlb->flush_pgtable)
> +		cfg->tlb->flush_pgtable(data->pgd, data->pgd_size, cookie);
> 
>  	/* VTTBR */
>  	cfg->arm_lpae_s2_cfg.vttbr = virt_to_phys(data->pgd);
> diff --git a/drivers/iommu/io-pgtable.h b/drivers/iommu/io-pgtable.h
> index 10e32f69c668..c69529c78914 100644
> --- a/drivers/iommu/io-pgtable.h
> +++ b/drivers/iommu/io-pgtable.h
> @@ -41,6 +41,8 @@ struct iommu_gather_ops {
>   * @ias:           Input address (iova) size, in bits.
>   * @oas:           Output address (paddr) size, in bits.
>   * @tlb:           TLB management callbacks for this set of tables.
> + * @iommu_dev:     The device representing the DMA configuration for the
> + *                 page table walker.
>   */
>  struct io_pgtable_cfg {
>  	#define IO_PGTABLE_QUIRK_ARM_NS	(1 << 0)	/* Set NS bit in PTEs */
> @@ -49,6 +51,7 @@ struct io_pgtable_cfg {
>  	unsigned int			ias;
>  	unsigned int			oas;
>  	const struct iommu_gather_ops	*tlb;
> +	struct device			*iommu_dev;
> 
>  	/* Low-level data specific to the table format */
>  	union {

-- 
Regards,

Laurent Pinchart



From marc.zyngier at arm.com  Tue Aug  4 06:17:18 2015
From: marc.zyngier at arm.com (Marc Zyngier)
Date: Tue, 04 Aug 2015 14:17:18 +0100
Subject: [PATCH v4 06/10] irqchip / GICv3: Add ACPI support for GICv3+
 initialization
In-Reply-To: <1438164539-29256-7-git-send-email-hanjun.guo@linaro.org>
References: <1438164539-29256-1-git-send-email-hanjun.guo@linaro.org>
 <1438164539-29256-7-git-send-email-hanjun.guo@linaro.org>
Message-ID: <55C0BB5E.2080706@arm.com>

On 29/07/15 11:08, Hanjun Guo wrote:
> From: Tomasz Nowicki <tomasz.nowicki at linaro.org>
> 
> With the refator of gic_of_init(), GICv3/4 can be initialized
> by gic_init_bases() with gic distributor base address and gic
> redistributor region(s).
> 
> So get the redistributor region base addresses from MADT GIC
> redistributor subtable, and the distributor base address from
> GICD subtable to init GICv3 irqchip in ACPI way.
> 
> Note: GIC redistributor base address may also be provided in
> GICC structures on systems supporting GICv3 and above if the GIC
> Redistributors are not in the always-on power domain, this
> patch didn't implement such feature yet.
> 
> Signed-off-by: Tomasz Nowicki <tomasz.nowicki at linaro.org>
> [hj: Rework this patch and fix multi issues]
> Signed-off-by: Hanjun Guo <hanjun.guo at linaro.org>
> ---
>  drivers/irqchip/irq-gic-v3.c | 174 +++++++++++++++++++++++++++++++++++++++++--
>  1 file changed, 169 insertions(+), 5 deletions(-)
> 
> diff --git a/drivers/irqchip/irq-gic-v3.c b/drivers/irqchip/irq-gic-v3.c
> index c0b96c6..ebc5604 100644
> --- a/drivers/irqchip/irq-gic-v3.c
> +++ b/drivers/irqchip/irq-gic-v3.c
> @@ -15,6 +15,7 @@
>   * along with this program.  If not, see <http://www.gnu.org/licenses/>.
>   */
>  
> +#include <linux/acpi.h>
>  #include <linux/cpu.h>
>  #include <linux/cpu_pm.h>
>  #include <linux/delay.h>
> @@ -25,6 +26,7 @@
>  #include <linux/percpu.h>
>  #include <linux/slab.h>
>  
> +#include <linux/irqchip/arm-gic-acpi.h>
>  #include <linux/irqchip/arm-gic-v3.h>
>  
>  #include <asm/cputype.h>
> @@ -802,7 +804,8 @@ static int __init gic_init_bases(void __iomem *dist_base,
>  	set_handle_irq(gic_handle_irq);
>  
>  	if (IS_ENABLED(CONFIG_ARM_GIC_V3_ITS) && gic_dist_supports_lpis())
> -		its_init(domain_token, &gic_data.rdists, gic_data.domain);
> +		its_init(irq_domain_token_to_of_node(domain_token),
> +			 &gic_data.rdists, gic_data.domain);

This doesn't make much sense. The first parameter to its_init is indeed
supposed to be an of_node, but what is the point of calling its_init if
you *know* you don't have the necessary topological information to parse
the firmware tables?

I don't see *any* code that is going to parse the ITS table in this
series, so please don't call its_init passing a NULL pointer to it. This
is just gross.

>  
>  	gic_smp_init();
>  	gic_dist_init();
> @@ -818,6 +821,16 @@ out_free:
>  	return err;
>  }
>  
> +static int __init detect_distributor(void __iomem *dist_base)

We do have a naming convention in this file. All functions start with gic_.

> +{
> +	u32 reg = readl_relaxed(dist_base + GICD_PIDR2) & GIC_PIDR2_ARCH_MASK;
> +
> +	if (reg != GIC_PIDR2_ARCH_GICv3 && reg != GIC_PIDR2_ARCH_GICv4)
> +		return -ENODEV;
> +
> +	return 0;
> +}

This function doesn't detect anything, it validates that we have
something sensible. Please rename it to gic_validate_dist_version, or
something similar.

> +
>  #ifdef CONFIG_OF
>  static int __init gic_of_init(struct device_node *node, struct device_node *parent)
>  {
> @@ -825,7 +838,6 @@ static int __init gic_of_init(struct device_node *node, struct device_node *pare
>  	struct redist_region *rdist_regs;
>  	u64 redist_stride;
>  	u32 nr_redist_regions;
> -	u32 reg;
>  	int err, i;
>  
>  	dist_base = of_iomap(node, 0);
> @@ -835,11 +847,10 @@ static int __init gic_of_init(struct device_node *node, struct device_node *pare
>  		return -ENXIO;
>  	}
>  
> -	reg = readl_relaxed(dist_base + GICD_PIDR2) & GIC_PIDR2_ARCH_MASK;
> -	if (reg != GIC_PIDR2_ARCH_GICv3 && reg != GIC_PIDR2_ARCH_GICv4) {
> +	err = detect_distributor(dist_base);
> +	if (err) {
>  		pr_err("%s: no distributor detected, giving up\n",
>  			node->full_name);
> -		err = -ENODEV;
>  		goto out_unmap_dist;
>  	}
>  
> @@ -887,3 +898,156 @@ out_unmap_dist:
>  
>  IRQCHIP_DECLARE(gic_v3, "arm,gic-v3", gic_of_init);
>  #endif
> +
> +#ifdef CONFIG_ACPI
> +static struct redist_region *redist_regs __initdata;
> +static u32 nr_redist_regions __initdata;
> +static phys_addr_t dist_phys_base __initdata;
> +
> +static int __init
> +gic_acpi_register_redist(u64 phys_base, u64 size)

A physical address must use phys_addr_t.

> +{
> +	struct redist_region *redist_regs_new;
> +	void __iomem *redist_base;
> +
> +	redist_regs_new = krealloc(redist_regs,
> +				   sizeof(*redist_regs) * (nr_redist_regions + 1),
> +				   GFP_KERNEL);

NAK. If you have multiple regions, you count them, you allocate the
right number of regions. This will be far more efficient than doing this
realloc dance. It is not like we're not parsing the tables a zillion
times already. Doing it one more time won't hurt.

> +	if (!redist_regs_new) {
> +		pr_err("Couldn't allocate resource for GICR region\n");
> +		return -ENOMEM;
> +	}
> +
> +	redist_regs = redist_regs_new;
> +
> +	redist_base = ioremap(phys_base, size);
> +	if (!redist_base) {
> +		pr_err("Couldn't map GICR region @%llx\n", phys_base);
> +		return -ENOMEM;
> +	}
> +
> +	redist_regs[nr_redist_regions].phys_base = phys_base;
> +	redist_regs[nr_redist_regions].redist_base = redist_base;
> +	nr_redist_regions++;
> +	return 0;
> +}
> +
> +static int __init
> +gic_acpi_parse_madt_redist(struct acpi_subtable_header *header,
> +			const unsigned long end)
> +{
> +	struct acpi_madt_generic_redistributor *redist;
> +
> +	if (BAD_MADT_ENTRY(header, end))
> +		return -EINVAL;
> +
> +	redist = (struct acpi_madt_generic_redistributor *)header;
> +	if (!redist->base_address)
> +		return -EINVAL;
> +
> +	return gic_acpi_register_redist(redist->base_address, redist->length);
> +}
> +
> +static int __init
> +gic_acpi_parse_madt_distributor(struct acpi_subtable_header *header,
> +				const unsigned long end)
> +{

How many versions of gic_acpi_parse_madt_distributor are we going to
get? Why isn't the ACPI parsing in a common file? Why do I have to read
the same code on and on until my eyes bleed?

> +	struct acpi_madt_generic_distributor *dist;
> +
> +	dist = (struct acpi_madt_generic_distributor *)header;
> +
> +	if (BAD_MADT_ENTRY(dist, end))
> +		return -EINVAL;
> +
> +	dist_phys_base = dist->base_address;
> +	return 0;
> +}
> +
> +static int gic_acpi_gsi_desc_populate(struct acpi_gsi_descriptor *data,
> +				      u32 gsi, unsigned int irq_type)
> +{
> +	/*
> +	 * Encode GSI and triggering information the way the GIC likes
> +	 * them.
> +	 */
> +	if (WARN_ON(gsi < 16))
> +		return -EINVAL;
> +
> +	if (gsi >= 32) {
> +		data->param[0] = 0;		/* SPI */
> +		data->param[1] = gsi - 32;
> +		data->param[2] = irq_type;
> +	} else {
> +		data->param[0] = 1; 		/* PPI */
> +		data->param[1] = gsi - 16;
> +		data->param[2] = 0xff << 4 | irq_type;
> +	}
> +
> +	data->param_count = 3;
> +
> +	return 0;
> +}
> +
> +static int __init
> +gic_acpi_init(struct acpi_table_header *table)
> +{
> +	int count, i, err = 0;
> +	void __iomem *dist_base;
> +
> +	/* Get distributor base address */
> +	count = acpi_parse_entries(ACPI_SIG_MADT,
> +				sizeof(struct acpi_table_madt),
> +				gic_acpi_parse_madt_distributor, table,
> +				ACPI_MADT_TYPE_GENERIC_DISTRIBUTOR, 0);
> +	if (count <= 0) {
> +		pr_err("No valid GICD entry exist\n");
> +		return -EINVAL;
> +	} else if (count > 1) {
> +		pr_err("More than one GICD entry detected\n");
> +		return -EINVAL;
> +	}
> +
> +	dist_base = ioremap(dist_phys_base, ACPI_GICV3_DIST_MEM_SIZE);
> +	if (!dist_base) {
> +		pr_err("Unable to map GICD registers\n");
> +		return -ENOMEM;
> +	}
> +
> +	err = detect_distributor(dist_base);
> +	if (err) {
> +		pr_err("No distributor detected at @%p, giving up", dist_base);
> +		goto out_dist_unmap;
> +	}
> +
> +	/* Collect redistributor base addresses */
> +	count = acpi_parse_entries(ACPI_SIG_MADT,
> +			sizeof(struct acpi_table_madt),
> +			gic_acpi_parse_madt_redist, table,
> +			ACPI_MADT_TYPE_GENERIC_REDISTRIBUTOR, 0);
> +	if (count <= 0) {
> +		pr_info("No valid GICR entries exist\n");
> +		err = -EINVAL;
> +		goto out_redist_unmap;
> +	}
> +
> +	err = gic_init_bases(dist_base, redist_regs, nr_redist_regions, 0,
> +			     (void *)ACPI_IRQ_MODEL_GIC);

There is no other global identifier for GICv3? It feels a bit weird to
use the same ID as GICv2 (though probably not harmful as you can't have
both as the same time). What are you planning to use for the ITS then?
You must make sure you have a global namespace.

> +	if (err)
> +		goto out_redist_unmap;
> +
> +	acpi_set_irq_model(ACPI_IRQ_MODEL_GIC, ACPI_IRQ_MODEL_GIC,
> +			   gic_acpi_gsi_desc_populate);
> +	return 0;
> +
> +out_redist_unmap:
> +	for (i = 0; i < nr_redist_regions; i++)
> +		if (redist_regs[i].redist_base)
> +			iounmap(redist_regs[i].redist_base);
> +	kfree(redist_regs);
> +out_dist_unmap:
> +	iounmap(dist_base);
> +	return err;
> +}
> +IRQCHIP_ACPI_DECLARE(gic_v3, ACPI_MADT_GIC_VERSION_V3, gic_acpi_init);
> +IRQCHIP_ACPI_DECLARE(gic_v4, ACPI_MADT_GIC_VERSION_V4, gic_acpi_init);

As mentioned before, this doesn't work.

> +#endif
> 

Thanks,

	M.
-- 
Jazz is not dead. It just smells funny...


From sergei.shtylyov at cogentembedded.com  Tue Aug  4 06:20:17 2015
From: sergei.shtylyov at cogentembedded.com (Sergei Shtylyov)
Date: Tue, 4 Aug 2015 16:20:17 +0300
Subject: [PATCH v4 15/16] clk: shmobile: mstp: Consider "zb_clk" suitable
 for power management
In-Reply-To: <1438691297-29235-16-git-send-email-geert+renesas@glider.be>
References: <1438691297-29235-1-git-send-email-geert+renesas@glider.be>
 <1438691297-29235-16-git-send-email-geert+renesas@glider.be>
Message-ID: <55C0BC11.3030509@cogentembedded.com>

Hello.

On 08/04/2015 03:28 PM, Geert Uytterhoeven wrote:

> Currently the CPG/MSTP Clock Domain code looks for MSTP clocks to power
> manage a device.

> Unfortunately, on R-Mobile APE6 (r8a73a4) and SH-Mobile AG5 (sh73a0),
> the Bus State Controller (BSC) is not power-managed by an MSTP clock,
> but by a plain CPG clock (zb_clk).  Add a special case to handle this,
> so the clock is properly managed, and devices connected to the BSC work
> as expected.

> Signed-off-by: Geert Uytterhoeven <geert+renesas at glider.be>
> Reviewed-by: Ulf Hansson <ulf.hansson at linaro.org>
[...]

> diff --git a/drivers/clk/shmobile/clk-mstp.c b/drivers/clk/shmobile/clk-mstp.c
> index b1df7b2f1e970adb..a117c3f0f257b5e1 100644
> --- a/drivers/clk/shmobile/clk-mstp.c
> +++ b/drivers/clk/shmobile/clk-mstp.c
> @@ -259,6 +259,10 @@ int cpg_mstp_attach_dev(struct generic_pm_domain *domain, struct device *dev)
>   					    "renesas,cpg-mstp-clocks"))
>   			goto found;
>
> +		/* BSC on r8a73a4/sh73a0 uses zb_clk instead of an mstp clock*/

    Please add a space before */.

> +		if (!strcmp(clkspec.np->name, "zb_clk"))
> +			goto found;
> +
>   		of_node_put(clkspec.np);
>   		i++;
>   	}

MBR, Sergei




From marc.zyngier at arm.com  Tue Aug  4 06:37:01 2015
From: marc.zyngier at arm.com (Marc Zyngier)
Date: Tue, 04 Aug 2015 14:37:01 +0100
Subject: [PATCH v4 07/10] irqchip / GICv3 / ACPI: Add GICR support via
 GICC structures
In-Reply-To: <1438164539-29256-8-git-send-email-hanjun.guo@linaro.org>
References: <1438164539-29256-1-git-send-email-hanjun.guo@linaro.org>
 <1438164539-29256-8-git-send-email-hanjun.guo@linaro.org>
Message-ID: <55C0BFFD.3000602@arm.com>

On 29/07/15 11:08, Hanjun Guo wrote:
> On systems supporting GICv3 and above, in MADT GICC structures, the
> field of GICR Base Address holds the 64-bit physical address of the
> associated Redistributor if the GIC Redistributors are not in the
> always-on power domain, so instead of init GICR regions via GIC
> redistributor structure(s), init it with GICR base address in GICC
> structures in that case.
> 
> As GICR base in MADT GICC is another way to indicate the GIC version
> is 3 or 4, add its support to find out the GIC versions.
> 
> Signed-off-by: Hanjun Guo <hanjun.guo at linaro.org>
> ---
>  drivers/irqchip/irq-gic-acpi.c       |  35 ++++++-
>  drivers/irqchip/irq-gic-v3.c         | 197 +++++++++++++++++++++++++++++++----
>  include/linux/irqchip/arm-gic-acpi.h |   2 +
>  3 files changed, 215 insertions(+), 19 deletions(-)
> 
> diff --git a/drivers/irqchip/irq-gic-acpi.c b/drivers/irqchip/irq-gic-acpi.c
> index 95454e3..3e5c8f4 100644
> --- a/drivers/irqchip/irq-gic-acpi.c
> +++ b/drivers/irqchip/irq-gic-acpi.c
> @@ -21,6 +21,11 @@ static u8 gic_version __initdata = ACPI_MADT_GIC_VERSION_NONE;
> 
>  static phys_addr_t dist_phy_base __initdata;
> 
> +u8 __init acpi_gic_version(void)
> +{
> +       return gic_version;
> +}
> +
>  static int __init
>  acpi_gic_parse_distributor(struct acpi_subtable_header *header,
>                            const unsigned long end)
> @@ -38,6 +43,27 @@ acpi_gic_parse_distributor(struct acpi_subtable_header *header,
>  }
> 
>  static int __init
> +gic_acpi_parse_madt_gicc(struct acpi_subtable_header *header,
> +                        const unsigned long end)
> +{
> +       struct acpi_madt_generic_interrupt *gicc;
> +
> +       gicc = (struct acpi_madt_generic_interrupt *)header;
> +
> +       if (BAD_MADT_GICC_ENTRY(gicc, end))
> +               return -EINVAL;
> +
> +       /*
> +        * If GICC is enabled but has no valid gicr base address, then it
> +        * means GICR base is not presented via GICC
> +        */
> +       if ((gicc->flags & ACPI_MADT_ENABLED) && !gicc->gicr_base_address)
> +               return -ENODEV;
> +
> +       return 0;
> +}
> +
> +static int __init
>  match_gic_redist(struct acpi_subtable_header *header, const unsigned long end)
>  {
>         return 0;
> @@ -51,7 +77,14 @@ static bool __init acpi_gic_redist_is_present(void)
>         count  =  acpi_table_parse_madt(ACPI_MADT_TYPE_GENERIC_REDISTRIBUTOR,
>                                         match_gic_redist, 0);
> 
> -       /* that's true if we have at least one GIC redistributor entry */
> +       /* has at least one GIC redistributor entry */
> +       if (count > 0)
> +               return true;
> +
> +       /* else try to find GICR base in GICC entries */
> +       count = acpi_table_parse_madt(ACPI_MADT_TYPE_GENERIC_INTERRUPT,
> +                                     gic_acpi_parse_madt_gicc, 0);
> +
>         return count > 0;
>  }
> 
> diff --git a/drivers/irqchip/irq-gic-v3.c b/drivers/irqchip/irq-gic-v3.c
> index ebc5604..b72ccbb 100644
> --- a/drivers/irqchip/irq-gic-v3.c
> +++ b/drivers/irqchip/irq-gic-v3.c
> @@ -389,9 +389,8 @@ static void __init gic_dist_init(void)
>                 writeq_relaxed(affinity, base + GICD_IROUTER + i * 8);
>  }
> 
> -static int gic_populate_rdist(void)
> +static int gic_populate_rdist_with_regions(u64 mpidr)
>  {
> -       u64 mpidr = cpu_logical_map(smp_processor_id());
>         u64 typer;
>         u32 aff;
>         int i;
> @@ -439,6 +438,34 @@ static int gic_populate_rdist(void)
>                 } while (!(typer & GICR_TYPER_LAST));
>         }
> 
> +       return -ENODEV;
> +}
> +
> +#ifdef CONFIG_ACPI
> +/*
> + * Populate redist when GIC redistributor address is presented in ACPI
> + * MADT GICC entries
> + */
> +static int gic_populate_rdist_with_gicr_base(u64 mpidr);
> +#else
> +static inline int gic_populate_rdist_with_gicr_base(u64 mpidr)
> +{
> +       return -ENODEV;
> +}
> +#endif
> +
> +static int gic_populate_rdist(void)
> +{
> +       u64 mpidr = cpu_logical_map(smp_processor_id());
> +
> +       if (gic_data.nr_redist_regions) {
> +               if (!gic_populate_rdist_with_regions(mpidr))
> +                       return 0;
> +       } else {
> +               if (!gic_populate_rdist_with_gicr_base(mpidr))
> +                       return 0;
> +       }
> +
>         /* We couldn't even deal with ourselves... */
>         WARN(true, "CPU%d: mpidr %llx has no re-distributor!\n",
>              smp_processor_id(), (unsigned long long)mpidr);
> @@ -900,6 +927,16 @@ IRQCHIP_DECLARE(gic_v3, "arm,gic-v3", gic_of_init);
>  #endif
> 
>  #ifdef CONFIG_ACPI
> +
> +struct acpi_gicc_redist {
> +       struct list_head list;
> +       u64 mpidr;
> +       phys_addr_t phys_base;
> +       void __iomem *redist_base;
> +};
> +
> +static LIST_HEAD(redist_list);
> +
>  static struct redist_region *redist_regs __initdata;
>  static u32 nr_redist_regions __initdata;
>  static phys_addr_t dist_phys_base __initdata;
> @@ -932,6 +969,17 @@ gic_acpi_register_redist(u64 phys_base, u64 size)
>         return 0;
>  }
> 
> +static void __init
> +gic_acpi_release_redist_regions(void)
> +{
> +       int i;
> +
> +       for (i = 0; i < nr_redist_regions; i++)
> +               if (redist_regs[i].redist_base)
> +                       iounmap(redist_regs[i].redist_base);
> +       kfree(redist_regs);
> +}
> +
>  static int __init
>  gic_acpi_parse_madt_redist(struct acpi_subtable_header *header,
>                         const unsigned long end)
> @@ -989,9 +1037,130 @@ static int gic_acpi_gsi_desc_populate(struct acpi_gsi_descriptor *data,
>  }
> 
>  static int __init
> +gic_acpi_add_gicc_redist(phys_addr_t phys_base, u64 mpidr)
> +{
> +       struct acpi_gicc_redist *redist;
> +
> +       redist = kzalloc(sizeof(*redist), GFP_KERNEL);
> +       if (!redist)
> +               return -ENOMEM;
> +
> +       redist->mpidr = mpidr;
> +       redist->phys_base = phys_base;
> +
> +       if (acpi_gic_version() == ACPI_MADT_GIC_VERSION_V3)
> +               /* RD_base + SGI_base */
> +               redist->redist_base = ioremap(phys_base, 2 * SZ_64K);
> +       else
> +               /*
> +                * RD_base + SGI_base + VLPI_base,
> +                * we don't map reserved page as it's buggy to access it
> +                */
> +               redist->redist_base = ioremap(phys_base, 3 * SZ_64K);
> +
> +       if (!redist->redist_base) {
> +               kfree(redist);
> +               return -ENOMEM;
> +       }
> +
> +       list_add(&redist->list, &redist_list);
> +       return 0;
> +}
> +
> +static void __init
> +gic_acpi_release_gicc_redist(void)
> +{
> +       struct acpi_gicc_redist *redist, *t;
> +
> +       list_for_each_entry_safe(redist, t, &redist_list, list) {
> +               list_del(&redist->list);
> +               iounmap(redist->redist_base);
> +               kfree(redist);
> +       }
> +}
> +
> +static int __init
> +gic_acpi_parse_madt_gicc(struct acpi_subtable_header *header,
> +                        const unsigned long end)
> +{
> +       struct acpi_madt_generic_interrupt *gicc;
> +
> +       gicc = (struct acpi_madt_generic_interrupt *)header;
> +
> +       if (BAD_MADT_GICC_ENTRY(gicc, end))
> +               return -EINVAL;
> +
> +       /*
> +        * just quietly ingore the disabled CPU(s) and continue
> +        * to find the enabled one(s), if we return error here,
> +        * the scanning will be stopped.
> +        */
> +       if (!(gicc->flags & ACPI_MADT_ENABLED))
> +               return 0;
> +
> +       return gic_acpi_add_gicc_redist(gicc->gicr_base_address,
> +                                       gicc->arm_mpidr);
> +}
> +
> +static int gic_populate_rdist_with_gicr_base(u64 mpidr)
> +{
> +       struct acpi_gicc_redist *redist;
> +       void __iomem *ptr;
> +       u32 reg;
> +
> +       list_for_each_entry(redist, &redist_list, list) {
> +               if (redist->mpidr != mpidr)
> +                       continue;
> +
> +               ptr = redist->redist_base;
> +               reg = readl_relaxed(ptr + GICR_PIDR2) & GIC_PIDR2_ARCH_MASK;
> +               if (reg != GIC_PIDR2_ARCH_GICv3 && reg != GIC_PIDR2_ARCH_GICv4) {
> +                       pr_warn("No redistributor present @%p\n", ptr);
> +                       return -ENODEV;
> +               }
> +
> +               gic_data_rdist_rd_base() = ptr;
> +               gic_data_rdist()->phys_base = redist->phys_base;
> +               pr_info("CPU%d: found redistributor %llx phys base:%pa\n",
> +                       smp_processor_id(),
> +                       (unsigned long long)mpidr,
> +                       &gic_data_rdist()->phys_base);
> +               return 0;
> +       }
> +
> +       return -ENODEV;
> +}
> +
> +static int __init collect_gicr_base(struct acpi_table_header *table)
> +{
> +       int count;
> +
> +       /* Collect redistributor base addresses in GICR entries */
> +       count = acpi_parse_entries(ACPI_SIG_MADT,
> +                       sizeof(struct acpi_table_madt),
> +                       gic_acpi_parse_madt_redist, table,
> +                       ACPI_MADT_TYPE_GENERIC_REDISTRIBUTOR, 0);
> +       if (count > 0)
> +               return 0;
> +
> +       pr_info("No valid GICR entries exist, try GICC entries\n");
> +
> +       /* Collect redistributor base addresses in GICC entries */
> +       count = acpi_parse_entries(ACPI_SIG_MADT,
> +                       sizeof(struct acpi_table_madt),
> +                       gic_acpi_parse_madt_gicc, table,
> +                       ACPI_MADT_TYPE_GENERIC_INTERRUPT, 0);
> +       if (count > 0 && !list_empty(&redist_list))
> +               return 0;
> +
> +       pr_info("No valid GICC entries exist for GICR base\n");
> +       return -ENODEV;
> +}
> +
> +static int __init
>  gic_acpi_init(struct acpi_table_header *table)
>  {
> -       int count, i, err = 0;
> +       int count, err = 0;
>         void __iomem *dist_base;
> 
>         /* Get distributor base address */
> @@ -1020,30 +1189,22 @@ gic_acpi_init(struct acpi_table_header *table)
>         }
> 
>         /* Collect redistributor base addresses */
> -       count = acpi_parse_entries(ACPI_SIG_MADT,
> -                       sizeof(struct acpi_table_madt),
> -                       gic_acpi_parse_madt_redist, table,
> -                       ACPI_MADT_TYPE_GENERIC_REDISTRIBUTOR, 0);
> -       if (count <= 0) {
> -               pr_info("No valid GICR entries exist\n");
> -               err = -EINVAL;
> -               goto out_redist_unmap;
> -       }
> +       if (collect_gicr_base(table))
> +               goto out_release_redist;
> 
>         err = gic_init_bases(dist_base, redist_regs, nr_redist_regions, 0,
>                              (void *)ACPI_IRQ_MODEL_GIC);
>         if (err)
> -               goto out_redist_unmap;
> +               goto out_release_redist;
> 
>         acpi_set_irq_model(ACPI_IRQ_MODEL_GIC, ACPI_IRQ_MODEL_GIC,
>                            gic_acpi_gsi_desc_populate);
>         return 0;
> 
> -out_redist_unmap:
> -       for (i = 0; i < nr_redist_regions; i++)
> -               if (redist_regs[i].redist_base)
> -                       iounmap(redist_regs[i].redist_base);
> -       kfree(redist_regs);
> +out_release_redist:
> +       gic_acpi_release_redist_regions();
> +       if (!list_empty(&redist_list))
> +               gic_acpi_release_gicc_redist();
>  out_dist_unmap:
>         iounmap(dist_base);
>         return err;
> diff --git a/include/linux/irqchip/arm-gic-acpi.h b/include/linux/irqchip/arm-gic-acpi.h
> index 56cd82c..0d43f515 100644
> --- a/include/linux/irqchip/arm-gic-acpi.h
> +++ b/include/linux/irqchip/arm-gic-acpi.h
> @@ -21,5 +21,7 @@
>  #define ACPI_GIC_CPU_IF_MEM_SIZE       (SZ_8K)
>  #define ACPI_GICV3_DIST_MEM_SIZE       (SZ_64K)
> 
> +u8 acpi_gic_version(void);
> +
>  #endif /* CONFIG_ACPI */
>  #endif /* ARM_GIC_ACPI_H_ */
> --
> 1.9.1
> 

This looks absolutely horrid. Why don't you simply populate one region
per redistributor, add a flag to struct redist_region so we know not to
check for GICR_TYPER_LAST but to move on to the next region instead?

We already have all the flexibility you require, please don't invent
stuff that is already there.

Thanks,

	M.
-- 
Jazz is not dead. It just smells funny...


From slash.tmp at free.fr  Tue Aug  4 06:41:22 2015
From: slash.tmp at free.fr (Mason)
Date: Tue, 04 Aug 2015 15:41:22 +0200
Subject: IRQ setup on multicore systems (routing, balancing, etc)
Message-ID: <55C0C102.7050600@free.fr>

Hello everyone,

I have a few very naive questions about interrupts.

How are interrupts set up on multicore systems?

If I write a device tree node for some peripheral, am I supposed
to specify which core each interrupt should be routed to?

On my system, there is a custom interrupt controller, but the ARM
chip also provides a Generic Interrupt Controller (GIC).

Am I supposed to use both, or can I use just the GIC?
(I suspect the answer is very platform-dependent.)

I've seen a lot of articles discussing interrupt "management"
on x86 (with APIC) but my search-foo is failing me for more
generic Linux "Howto set up". Are there good references?

I suppose I should take a look at these?
Documentation/devicetree/bindings/interrupt-controller/*
Documentation/devicetree/bindings/arm/gic.txt


For my own reference:

ARM Generic Interrupt Controller Architecture Specification v1.0 (IHI0048A)
Cortex-A9 MPCore (Revision: r3p0) Technical Reference Manual

Regards.


From christoffer.dall at linaro.org  Tue Aug  4 06:45:09 2015
From: christoffer.dall at linaro.org (Christoffer Dall)
Date: Tue, 4 Aug 2015 15:45:09 +0200
Subject: [PATCH v3 09/11] KVM: arm/arm64: vgic: Prevent userspace
 injection of a mapped interrupt
In-Reply-To: <1437753309-17989-10-git-send-email-marc.zyngier@arm.com>
References: <1437753309-17989-1-git-send-email-marc.zyngier@arm.com>
 <1437753309-17989-10-git-send-email-marc.zyngier@arm.com>
Message-ID: <20150804134509.GB29335@cbox>

On Fri, Jul 24, 2015 at 04:55:07PM +0100, Marc Zyngier wrote:
> Virtual interrupts mapped to a HW interrupt should only be triggered
> from inside the kernel. Otherwise, you could end up confusing the
> kernel (and the GIC's) state machine.
> 
> Rearrange the injection path so that kvm_vgic_inject_irq is
> used for non-mapped interrupts, and kvm_vgic_inject_mapped_irq is
> used for mapped interrupts. The latter should only be called from
> inside the kernel (timer, VFIO).
> 
> Signed-off-by: Marc Zyngier <marc.zyngier at arm.com>
> ---
>  include/kvm/arm_vgic.h |  2 +
>  virt/kvm/arm/vgic.c    | 99 ++++++++++++++++++++++++++++++++++----------------
>  2 files changed, 70 insertions(+), 31 deletions(-)
> 
> diff --git a/include/kvm/arm_vgic.h b/include/kvm/arm_vgic.h
> index 7306b4b..f6bfd79 100644
> --- a/include/kvm/arm_vgic.h
> +++ b/include/kvm/arm_vgic.h
> @@ -351,6 +351,8 @@ void kvm_vgic_flush_hwstate(struct kvm_vcpu *vcpu);
>  void kvm_vgic_sync_hwstate(struct kvm_vcpu *vcpu);
>  int kvm_vgic_inject_irq(struct kvm *kvm, int cpuid, unsigned int irq_num,
>  			bool level);
> +int kvm_vgic_inject_mapped_irq(struct kvm *kvm, int cpuid,
> +			       struct irq_phys_map *map, bool level);
>  void vgic_v3_dispatch_sgi(struct kvm_vcpu *vcpu, u64 reg);
>  int kvm_vgic_vcpu_pending_irq(struct kvm_vcpu *vcpu);
>  int kvm_vgic_vcpu_active_irq(struct kvm_vcpu *vcpu);
> diff --git a/virt/kvm/arm/vgic.c b/virt/kvm/arm/vgic.c
> index 3f7b690..e40ef70 100644
> --- a/virt/kvm/arm/vgic.c
> +++ b/virt/kvm/arm/vgic.c
> @@ -1533,7 +1533,8 @@ static int vgic_validate_injection(struct kvm_vcpu *vcpu, int irq, int level)
>  }
>  
>  static int vgic_update_irq_pending(struct kvm *kvm, int cpuid,
> -				  unsigned int irq_num, bool level)
> +				   struct irq_phys_map *map,
> +				   unsigned int irq_num, bool level)
>  {
>  	struct vgic_dist *dist = &kvm->arch.vgic;
>  	struct kvm_vcpu *vcpu;
> @@ -1541,6 +1542,9 @@ static int vgic_update_irq_pending(struct kvm *kvm, int cpuid,
>  	int enabled;
>  	bool ret = true, can_inject = true;
>  
> +	if (irq_num >= min(kvm->arch.vgic.nr_irqs, 1020))
> +		return -EINVAL;
> +
>  	spin_lock(&dist->lock);
>  
>  	vcpu = kvm_get_vcpu(kvm, cpuid);
> @@ -1603,14 +1607,42 @@ static int vgic_update_irq_pending(struct kvm *kvm, int cpuid,
>  out:
>  	spin_unlock(&dist->lock);
>  
> -	return ret ? cpuid : -EINVAL;
> +	if (!ret) {

don't you mean if (ret) here?  hint: ret is a bool

> +		/* kick the specified vcpu */
> +		kvm_vcpu_kick(kvm_get_vcpu(kvm, cpuid));
> +	}
> +
> +	return 0;

isn't this a change in the internal API?
Before, we would return -EINVAL when ret is false.  Not sure if this
has any consequences though?

> +}
> +
> +static int vgic_lazy_init(struct kvm *kvm)
> +{
> +	int ret = 0;
> +
> +	if (unlikely(!vgic_initialized(kvm))) {
> +		/*
> +		 * We only provide the automatic initialization of the VGIC
> +		 * for the legacy case of a GICv2. Any other type must
> +		 * be explicitly initialized once setup with the respective
> +		 * KVM device call.
> +		 */
> +		if (kvm->arch.vgic.vgic_model != KVM_DEV_TYPE_ARM_VGIC_V2)
> +			return -EBUSY;
> +
> +		mutex_lock(&kvm->lock);
> +		ret = vgic_init(kvm);
> +		mutex_unlock(&kvm->lock);
> +	}
> +
> +	return ret;
>  }
>  
>  /**
>   * kvm_vgic_inject_irq - Inject an IRQ from a device to the vgic
>   * @kvm:     The VM structure pointer
>   * @cpuid:   The CPU for PPIs
> - * @irq_num: The IRQ number that is assigned to the device
> + * @irq_num: The IRQ number that is assigned to the device. This IRQ
> + *           must not be mapped to a HW interrupt.
>   * @level:   Edge-triggered:  true:  to trigger the interrupt
>   *			      false: to ignore the call
>   *	     Level-sensitive  true:  activates an interrupt
> @@ -1623,39 +1655,44 @@ out:
>  int kvm_vgic_inject_irq(struct kvm *kvm, int cpuid, unsigned int irq_num,
>  			bool level)
>  {
> -	int ret = 0;
> -	int vcpu_id;
> -
> -	if (unlikely(!vgic_initialized(kvm))) {
> -		/*
> -		 * We only provide the automatic initialization of the VGIC
> -		 * for the legacy case of a GICv2. Any other type must
> -		 * be explicitly initialized once setup with the respective
> -		 * KVM device call.
> -		 */
> -		if (kvm->arch.vgic.vgic_model != KVM_DEV_TYPE_ARM_VGIC_V2) {
> -			ret = -EBUSY;
> -			goto out;
> -		}
> -		mutex_lock(&kvm->lock);
> -		ret = vgic_init(kvm);
> -		mutex_unlock(&kvm->lock);
> +	struct irq_phys_map *map;
> +	int ret;
>  
> -		if (ret)
> -			goto out;
> -	}
> +	ret = vgic_lazy_init(kvm);
> +	if (ret)
> +		return ret;
>  
> -	if (irq_num >= min(kvm->arch.vgic.nr_irqs, 1020))
> +	map = vgic_irq_map_search(kvm_get_vcpu(kvm, cpuid), irq_num);
> +	if (map)
>  		return -EINVAL;
>  
> -	vcpu_id = vgic_update_irq_pending(kvm, cpuid, irq_num, level);
> -	if (vcpu_id >= 0) {
> -		/* kick the specified vcpu */
> -		kvm_vcpu_kick(kvm_get_vcpu(kvm, vcpu_id));
> -	}
> +	return vgic_update_irq_pending(kvm, cpuid, NULL, irq_num, level);
> +}
>  
> -out:
> -	return ret;
> +/**
> + * kvm_vgic_inject_mapped_irq - Inject a physically mapped IRQ to the vgic
> + * @kvm:     The VM structure pointer
> + * @cpuid:   The CPU for PPIs
> + * @map:     Pointer to a irq_phys_map structure describing the mapping
> + * @level:   Edge-triggered:  true:  to trigger the interrupt
> + *			      false: to ignore the call
> + *	     Level-sensitive  true:  activates an interrupt
> + *			      false: deactivates an interrupt

just noticed this unfortunate use of the words 'activate/deactivate'
here, which is not true, it just raises/lowers the input signal...

> + *
> + * The GIC is not concerned with devices being active-LOW or active-HIGH for
> + * level-sensitive interrupts.  You can think of the level parameter as 1
> + * being HIGH and 0 being LOW and all devices being active-HIGH.
> + */
> +int kvm_vgic_inject_mapped_irq(struct kvm *kvm, int cpuid,
> +			       struct irq_phys_map *map, bool level)
> +{
> +	int ret;
> +
> +	ret = vgic_lazy_init(kvm);
> +	if (ret)
> +		return ret;
> +
> +	return vgic_update_irq_pending(kvm, cpuid, map, map->virt_irq, level);
>  }
>  
>  static irqreturn_t vgic_maintenance_handler(int irq, void *data)
> -- 
> 2.1.4
> 

Thanks,
-Christoffer


From djkurtz at chromium.org  Tue Aug  4 06:46:12 2015
From: djkurtz at chromium.org (Daniel Kurtz)
Date: Tue, 4 Aug 2015 21:46:12 +0800
Subject: [PATCH v6 0/9] Fixes and new clocks support for Mediatek MT8173
In-Reply-To: <1438676218-11310-1-git-send-email-jamesjj.liao@mediatek.com>
References: <1438676218-11310-1-git-send-email-jamesjj.liao@mediatek.com>
Message-ID: <CAGS+omDce5HMT6irZfNA-DpC3xNq1vbJ6jxM_6KT-jYgE5JU0g@mail.gmail.com>

On Tue, Aug 4, 2015 at 4:16 PM, James Liao <jamesjj.liao at mediatek.com> wrote:
> This patchset is based on 4.2-rc2 and [1], and contains minor fixes and
> subsystem clocks support for Mediatek MT8173.
>
> The previous reviews can be found in [2]. The most different from previous
> patchset is rebasing to 4.2-rc2.

For the whole series:

Reviewed-by: Daniel Kurtz <djkurtz at chromium.org>


>
> changes since v5:
> - Rebase to 4.2-rc2.
> - Patch "Fix enabling of critical clocks" had been included in 4.2-rc2,
>   so it need not be included in this patchset.
>
> changes since v4:
> - Add a separated patch to remove unused dpi_ck.
> - Add separated patches to fix clk/mediatek in release 4.2-rc1.
> - Add __init* for initialization data and functions.
> - Rename dummy_clk with oscillator in DT.
> - Remove mtk_clk_register_apmixed_ex(), call mtk_clk_register_ref2usb_tx()
>   directly to register USB clock.
>
> changes since v3:
> - Remove clk_null dependency from root clocks.
> - Use fixed-rate clocks with typical rate to replace clk_null.
> - Separate ref2usb_tx implementation to clk-apmixed.c
> - Use clock-controller as the name of clock providers.
>
> changes since v2:
> - Rebase to 4.2-rc1.
> - Add device tree nodes for subsystem clocks.
> - Fine tune comments of patches.
> - Add __init, __initconst and const to init data and functions.
> - Removed unused code from init functions of subsystem clocks.
>
> changes since v1:
> - Add CA7PLL and CA15PLL as critical clocks.
> - Use the same register descriptor for imgsys, vensys and vencltsys.
> - Generalize apmixedsys special clocks registration.
>
> [1] https://patchwork.kernel.org/patch/6446341/
> [2] http://lists.infradead.org/pipermail/linux-mediatek/2015-July/001800.html
>
> James Liao (9):
>   clk: mediatek: Removed unused dpi_ck clock from MT8173
>   clk: mediatek: Remove unused code from MT8173.
>   clk: mediatek: Add __initdata and __init for data and functions
>   clk: mediatek: Add fixed clocks support for Mediatek SoC.
>   clk: mediatek: Fix rate and dependency of MT8173 clocks
>   dt-bindings: ARM: Mediatek: Document devicetree bindings for clock
>     controllers
>   clk: mediatek: Add subsystem clocks of MT8173
>   clk: mediatek: Add USB clock support in MT8173 APMIXEDSYS
>   arm64: dts: mt8173: Add subsystem clock controller device nodes
>
>  .../bindings/arm/mediatek/mediatek,imgsys.txt      |  22 ++
>  .../bindings/arm/mediatek/mediatek,mmsys.txt       |  22 ++
>  .../bindings/arm/mediatek/mediatek,vdecsys.txt     |  22 ++
>  .../bindings/arm/mediatek/mediatek,vencltsys.txt   |  22 ++
>  .../bindings/arm/mediatek/mediatek,vencsys.txt     |  22 ++
>  arch/arm64/boot/dts/mediatek/mt8173.dtsi           |  37 +++
>  drivers/clk/mediatek/Makefile                      |   2 +-
>  drivers/clk/mediatek/clk-apmixed.c                 | 107 +++++++
>  drivers/clk/mediatek/clk-gate.c                    |   2 +-
>  drivers/clk/mediatek/clk-mt8173.c                  | 335 ++++++++++++++++++++-
>  drivers/clk/mediatek/clk-mtk.c                     |  36 ++-
>  drivers/clk/mediatek/clk-mtk.h                     |  24 +-
>  drivers/clk/mediatek/clk-pll.c                     |   7 +-
>  include/dt-bindings/clock/mt8173-clk.h             | 101 ++++++-
>  14 files changed, 728 insertions(+), 33 deletions(-)
>  create mode 100644 Documentation/devicetree/bindings/arm/mediatek/mediatek,imgsys.txt
>  create mode 100644 Documentation/devicetree/bindings/arm/mediatek/mediatek,mmsys.txt
>  create mode 100644 Documentation/devicetree/bindings/arm/mediatek/mediatek,vdecsys.txt
>  create mode 100644 Documentation/devicetree/bindings/arm/mediatek/mediatek,vencltsys.txt
>  create mode 100644 Documentation/devicetree/bindings/arm/mediatek/mediatek,vencsys.txt
>  create mode 100644 drivers/clk/mediatek/clk-apmixed.c
>
> --
> 1.8.1.1.dirty
>


From horms at verge.net.au  Tue Aug  4 06:48:28 2015
From: horms at verge.net.au (Simon Horman)
Date: Tue, 4 Aug 2015 22:48:28 +0900
Subject: [PATCH v4 00/16] ARM: shmobile: Add CPG/MSTP Clock Domain
In-Reply-To: <1438691297-29235-1-git-send-email-geert+renesas@glider.be>
References: <1438691297-29235-1-git-send-email-geert+renesas@glider.be>
Message-ID: <20150804134824.GA10194@verge.net.au>

Thanks Geert,

I have tentatively queued this up in its own branch,
cpg-mstp-clock-domain-for-v4.3.


From scott.shu at mediatek.com  Tue Aug  4 06:54:16 2015
From: scott.shu at mediatek.com (Scott Shu)
Date: Tue, 4 Aug 2015 21:54:16 +0800
Subject: [PATCH v3 0/8] This series adds SMP support for the MediaTek MT6580.
Message-ID: <1438696464-59858-1-git-send-email-scott.shu@mediatek.com>

This patchset adds support SMP on MediaTek MT6580 Cortex-A7 quad-core SoC.

This is based on v4.2-rc1 and following patch series:
(1) Yingjoe Chen's "Add SMP bringup support for mt65xx socs" [1]
(2) Mars Cheng's "Add mt6580 basic chip support" [2]
(3) Sascha Hauer's "Mediatek SCPSYS power domain support" [3]

The secondary cores are power off as default on MT6580, this change adds
a new enable-method to turn on power to the cores during booting process.

The System Power Manager (SPM) inside the SCPSYS is for the CPU MTCMOS
power domain control. Please check [3] for more information about SCPSYS.

[1] https://lkml.org/lkml/2015/5/16/33
[2] https://lkml.org/lkml/2015/6/30/119
[3] https://lkml.org/lkml/2015/6/9/172

Change in v3:
1. Add CPU power control in SCPSYS driver

Change in v2:
1. Rebase to 4.2-rc1
2. Fix using usleep() in atomic context
3. Put a timeout in cpu power on/off sequence
4. Fix some coding style

Scott Shu (8):
  Document: bindings: DT: Add SMP enable method for MT6580     SoC
    platform
  dt-bindings: soc: Add SCPSYS compatible support for mt6580
  soc: Mediatek: Add SCPSYS CPU power domain driver
  ARM: multi_v7_defconfig: enable INFRACFG and SCPSYS modules
  ARM: mediatek: add smp bringup code for MT6580
  ARM: Mediatek: enable GPT6 on boot up to make arch timer     working
    for MT6580
  ARM: dts: mt6580: Add device nodes to the MT6580 dtsi file
  ARM: dts: mt6580: enable basic SMP bringup for MT6580

 Documentation/devicetree/bindings/arm/cpus.txt     |    1 +
 .../devicetree/bindings/soc/mediatek/scpsys.txt    |    2 +-
 arch/arm/boot/dts/mt6580.dtsi                      |   26 ++
 arch/arm/configs/multi_v7_defconfig                |    2 +
 arch/arm/mach-mediatek/mediatek.c                  |    4 +-
 arch/arm/mach-mediatek/platsmp.c                   |  137 +++++++++++
 drivers/soc/mediatek/mtk-scpsys.c                  |  250 ++++++++++++++++++++
 include/linux/soc/mediatek/scpsys.h                |    9 +
 8 files changed, 429 insertions(+), 2 deletions(-)
 create mode 100644 include/linux/soc/mediatek/scpsys.h

-- 
1.7.9.5



From scott.shu at mediatek.com  Tue Aug  4 06:54:24 2015
From: scott.shu at mediatek.com (Scott Shu)
Date: Tue, 4 Aug 2015 21:54:24 +0800
Subject: [PATCH v3 8/8] ARM: dts: mt6580: enable basic SMP bringup for MT6580
In-Reply-To: <1438696464-59858-1-git-send-email-scott.shu@mediatek.com>
References: <1438696464-59858-1-git-send-email-scott.shu@mediatek.com>
Message-ID: <1438696464-59858-9-git-send-email-scott.shu@mediatek.com>

Add arch timer node to enable arch-timer support. MT6580 firmware
doesn't correctly setup arch-timer frequency and CNTVOFF, add
properties to workaround this.

This set cpu enable-method to enable SMP.

Signed-off-by: Scott Shu <scott.shu at mediatek.com>
---
 arch/arm/boot/dts/mt6580.dtsi |   20 ++++++++++++++++++++
 1 file changed, 20 insertions(+)

diff --git a/arch/arm/boot/dts/mt6580.dtsi b/arch/arm/boot/dts/mt6580.dtsi
index 40957d3..70531b2 100644
--- a/arch/arm/boot/dts/mt6580.dtsi
+++ b/arch/arm/boot/dts/mt6580.dtsi
@@ -25,26 +25,31 @@
 	cpus {
 		#address-cells = <1>;
 		#size-cells = <0>;
+		enable-method = "mediatek,mt6580-smp";
 
 		cpu at 0 {
 			device_type = "cpu";
 			compatible = "arm,cortex-a7";
 			reg = <0x0>;
+			clock-frequency = <1700000000>;
 		};
 		cpu at 1 {
 			device_type = "cpu";
 			compatible = "arm,cortex-a7";
 			reg = <0x1>;
+			clock-frequency = <1700000000>;
 		};
 		cpu at 2 {
 			device_type = "cpu";
 			compatible = "arm,cortex-a7";
 			reg = <0x2>;
+			clock-frequency = <1700000000>;
 		};
 		cpu at 3 {
 			device_type = "cpu";
 			compatible = "arm,cortex-a7";
 			reg = <0x3>;
+			clock-frequency = <1700000000>;
 		};
 
 	};
@@ -67,6 +72,21 @@
 		#clock-cells = <0>;
 	};
 
+	timer {
+		compatible = "arm,armv7-timer";
+		interrupt-parent = <&gic>;
+		interrupts = <GIC_PPI 13 (GIC_CPU_MASK_SIMPLE(4) |
+					  IRQ_TYPE_LEVEL_LOW)>,
+				<GIC_PPI 14 (GIC_CPU_MASK_SIMPLE(4) |
+					  IRQ_TYPE_LEVEL_LOW)>,
+				<GIC_PPI 11 (GIC_CPU_MASK_SIMPLE(4) |
+					  IRQ_TYPE_LEVEL_LOW)>,
+				<GIC_PPI 10 (GIC_CPU_MASK_SIMPLE(4) |
+					  IRQ_TYPE_LEVEL_LOW)>;
+		clock-frequency = <13000000>;
+		arm,cpu-registers-not-fw-configured;
+	};
+
 	scpsys: scpsys at 10006000 {
 		#power-domain-cells = <1>;
 		compatible = "mediatek,mt6580-scpsys";
-- 
1.7.9.5



From scott.shu at mediatek.com  Tue Aug  4 06:54:17 2015
From: scott.shu at mediatek.com (Scott Shu)
Date: Tue, 4 Aug 2015 21:54:17 +0800
Subject: [PATCH v3 1/8] Document: bindings: DT: Add SMP enable method for
 MT6580 SoC platform
In-Reply-To: <1438696464-59858-1-git-send-email-scott.shu@mediatek.com>
References: <1438696464-59858-1-git-send-email-scott.shu@mediatek.com>
Message-ID: <1438696464-59858-2-git-send-email-scott.shu@mediatek.com>

For MT6580 SoC platform, the secondary cores are in powered off state
as default, so compared with MT6589, one new enable method is needed.
This method using the SPM (System Power Manager) inside the SCPSYS to
control the CPU power.

Signed-off-by: Scott Shu <scott.shu at mediatek.com>
---
 Documentation/devicetree/bindings/arm/cpus.txt |    1 +
 1 file changed, 1 insertion(+)

diff --git a/Documentation/devicetree/bindings/arm/cpus.txt b/Documentation/devicetree/bindings/arm/cpus.txt
index d58eb45..66a8f03 100644
--- a/Documentation/devicetree/bindings/arm/cpus.txt
+++ b/Documentation/devicetree/bindings/arm/cpus.txt
@@ -195,6 +195,7 @@ nodes to be present and contain the properties described below.
 			    "marvell,armada-380-smp"
 			    "marvell,armada-390-smp"
 			    "marvell,armada-xp-smp"
+			    "mediatek,mt6580-smp"
 			    "mediatek,mt6589-smp"
 			    "mediatek,mt81xx-tz-smp"
 			    "qcom,gcc-msm8660"
-- 
1.7.9.5



From scott.shu at mediatek.com  Tue Aug  4 06:54:20 2015
From: scott.shu at mediatek.com (Scott Shu)
Date: Tue, 4 Aug 2015 21:54:20 +0800
Subject: [PATCH v3 4/8] ARM: multi_v7_defconfig: enable INFRACFG and SCPSYS
 modules
In-Reply-To: <1438696464-59858-1-git-send-email-scott.shu@mediatek.com>
References: <1438696464-59858-1-git-send-email-scott.shu@mediatek.com>
Message-ID: <1438696464-59858-5-git-send-email-scott.shu@mediatek.com>

The INFRACFG contains various infrastructure registers and the SCPSYS handles
several power management related tasks. Both are needed for SMP and CPU
hotplug on MT6580.

Signed-off-by: Scott Shu <scott.shu at mediatek.com>
---
 arch/arm/configs/multi_v7_defconfig |    2 ++
 1 file changed, 2 insertions(+)

diff --git a/arch/arm/configs/multi_v7_defconfig b/arch/arm/configs/multi_v7_defconfig
index 6d83a1b..c272edd 100644
--- a/arch/arm/configs/multi_v7_defconfig
+++ b/arch/arm/configs/multi_v7_defconfig
@@ -596,6 +596,8 @@ CONFIG_KEYBOARD_NVEC=y
 CONFIG_SERIO_NVEC_PS2=y
 CONFIG_NVEC_POWER=y
 CONFIG_NVEC_PAZ00=y
+CONFIG_MTK_INFRACFG=y
+CONFIG_MTK_SCPSYS=y
 CONFIG_QCOM_GSBI=y
 CONFIG_QCOM_PM=y
 CONFIG_COMMON_CLK_QCOM=y
-- 
1.7.9.5



From scott.shu at mediatek.com  Tue Aug  4 06:54:21 2015
From: scott.shu at mediatek.com (Scott Shu)
Date: Tue, 4 Aug 2015 21:54:21 +0800
Subject: [PATCH v3 5/8] ARM: mediatek: add smp bringup code for MT6580
In-Reply-To: <1438696464-59858-1-git-send-email-scott.shu@mediatek.com>
References: <1438696464-59858-1-git-send-email-scott.shu@mediatek.com>
Message-ID: <1438696464-59858-6-git-send-email-scott.shu@mediatek.com>

Add support for cpu enable-method "mediatek,mt6580-smp" for booting
secondary CPUs on MT6580.

Signed-off-by: Scott Shu <scott.shu at mediatek.com>
---
 arch/arm/mach-mediatek/platsmp.c |  137 ++++++++++++++++++++++++++++++++++++++
 1 file changed, 137 insertions(+)

diff --git a/arch/arm/mach-mediatek/platsmp.c b/arch/arm/mach-mediatek/platsmp.c
index a5bc108..94f7865 100644
--- a/arch/arm/mach-mediatek/platsmp.c
+++ b/arch/arm/mach-mediatek/platsmp.c
@@ -21,10 +21,16 @@
 #include <linux/of_address.h>
 #include <linux/string.h>
 #include <linux/threads.h>
+#include <linux/delay.h>
+#include <asm/cacheflush.h>
+
+#include <linux/soc/mediatek/scpsys.h>
 
 #define MTK_MAX_CPU		8
 #define MTK_SMP_REG_SIZE	0x1000
 
+static DEFINE_SPINLOCK(boot_lock);
+
 struct mtk_smp_boot_info {
 	unsigned long smp_base;
 	unsigned int jump_reg;
@@ -56,6 +62,126 @@ static const struct of_device_id mtk_smp_boot_infos[] __initconst = {
 static void __iomem *mtk_smp_base;
 static const struct mtk_smp_boot_info *mtk_smp_info;
 
+#ifdef CONFIG_HOTPLUG_CPU
+static int mt6580_cpu_kill(unsigned cpu)
+{
+	int ret;
+
+	ret = spm_cpu_mtcmos_off(cpu, 1);
+	if (ret < 0)
+		return 0;
+
+	return 1;
+}
+
+static void mt6580_cpu_die(unsigned int cpu)
+{
+	for (;;)
+		cpu_do_idle();
+}
+#endif
+
+static void write_pen_release(int val)
+{
+	pen_release = val;
+	/* Make sure this is visible to other CPUs */
+	smp_wmb();
+	sync_cache_w(&pen_release);
+}
+
+/*
+ * Refer common "pen" secondary release method
+ */
+static int mt6580_boot_secondary(unsigned int cpu, struct task_struct *idle)
+{
+	unsigned long timeout;
+	int ret;
+
+	/*
+	 * Set synchronisation state between this boot processor
+	 * and the secondary one
+	 */
+	spin_lock(&boot_lock);
+
+	/*
+	 * The secondary processor is waiting to be released from
+	 * the holding pen - release it, then wait for it to flag
+	 * that it has been released by resetting pen_release.
+	 *
+	 * Note that "pen_release" is the hardware CPU ID, whereas
+	 * "cpu" is Linux's internal ID.
+	 */
+	write_pen_release(cpu);
+
+	/*
+	 * CPU power on control by SPM
+	 */
+	ret = spm_cpu_mtcmos_on(cpu);
+	if (ret < 0) {
+		spin_unlock(&boot_lock);
+		return -ENXIO;
+	}
+
+	timeout = jiffies + (1 * HZ);
+	while (time_before(jiffies, timeout)) {
+		/* Read barrier */
+		smp_rmb();
+
+		if (pen_release == -1)
+			break;
+
+		udelay(10);
+	}
+
+	/*
+	 * Now the secondary core is starting up let it run its
+	 * calibrations, then wait for it to finish
+	 */
+	spin_unlock(&boot_lock);
+
+	return (pen_release != -1 ? -ENXIO : 0);
+}
+
+static void mt6580_secondary_init(unsigned int cpu)
+{
+	/*
+	 * Let the primary processor know we're out of the
+	 * pen, then head off into the C entry point
+	 */
+	write_pen_release(-1);
+
+	/*
+	 * Synchronise with the boot thread.
+	 */
+	spin_lock(&boot_lock);
+	spin_unlock(&boot_lock);
+}
+
+#define MT6580_INFRACFG_AO	0x10001000
+#define SW_ROM_PD		BIT(31)
+
+static void __init mt6580_smp_prepare_cpus(unsigned int max_cpus)
+{
+	static void __iomem *infracfg_ao_base;
+
+	infracfg_ao_base = ioremap(MT6580_INFRACFG_AO, 0x1000);
+	if (!infracfg_ao_base) {
+		pr_err("%s: Unable to map I/O memory\n", __func__);
+		return;
+	}
+
+	/* Enable bootrom power down mode */
+	writel_relaxed(readl(infracfg_ao_base + 0x804) | SW_ROM_PD,
+		       infracfg_ao_base + 0x804);
+
+	/* Write the address of slave startup into boot address
+	   register for bootrom power down mode */
+	writel_relaxed(virt_to_phys(secondary_startup_arm),
+		       infracfg_ao_base + 0x800);
+
+	iounmap(infracfg_ao_base);
+}
+
 static int mtk_boot_secondary(unsigned int cpu, struct task_struct *idle)
 {
 	if (!mtk_smp_base)
@@ -142,3 +268,14 @@ static struct smp_operations mt6589_smp_ops __initdata = {
 	.smp_boot_secondary = mtk_boot_secondary,
 };
 CPU_METHOD_OF_DECLARE(mt6589_smp, "mediatek,mt6589-smp", &mt6589_smp_ops);
+
+static struct smp_operations mt6580_smp_ops __initdata = {
+	.smp_prepare_cpus = mt6580_smp_prepare_cpus,
+	.smp_secondary_init = mt6580_secondary_init,
+	.smp_boot_secondary = mt6580_boot_secondary,
+#ifdef CONFIG_HOTPLUG_CPU
+	.cpu_kill = mt6580_cpu_kill,
+	.cpu_die = mt6580_cpu_die,
+#endif
+};
+CPU_METHOD_OF_DECLARE(mt6580_smp, "mediatek,mt6580-smp", &mt6580_smp_ops);
-- 
1.7.9.5



From scott.shu at mediatek.com  Tue Aug  4 06:54:18 2015
From: scott.shu at mediatek.com (Scott Shu)
Date: Tue, 4 Aug 2015 21:54:18 +0800
Subject: [PATCH v3 2/8] dt-bindings: soc: Add SCPSYS compatible support for
 mt6580
In-Reply-To: <1438696464-59858-1-git-send-email-scott.shu@mediatek.com>
References: <1438696464-59858-1-git-send-email-scott.shu@mediatek.com>
Message-ID: <1438696464-59858-3-git-send-email-scott.shu@mediatek.com>

This adds "mediatek,mt6580-scpsys" in the compatible properties of
SCPSYS node for MT6580 SoC.

Signed-off-by: Scott Shu <scott.shu at mediatek.com>
---
 .../devicetree/bindings/soc/mediatek/scpsys.txt    |    2 +-
 1 file changed, 1 insertion(+), 1 deletion(-)

diff --git a/Documentation/devicetree/bindings/soc/mediatek/scpsys.txt b/Documentation/devicetree/bindings/soc/mediatek/scpsys.txt
index c051114..7998bc2 100644
--- a/Documentation/devicetree/bindings/soc/mediatek/scpsys.txt
+++ b/Documentation/devicetree/bindings/soc/mediatek/scpsys.txt
@@ -12,7 +12,7 @@ power/power_domain.txt. It provides the power domains defined in
 include/dt-bindings/power/mt8173-power.h.
 
 Required properties:
-- compatible: Must be "mediatek,mt8173-scpsys"
+- compatible: Must be "mediatek,mt6580-scpsys" or "mediatek,mt8173-scpsys"
 - #power-domain-cells: Must be 1
 - reg: Address range of the SCPSYS unit
 - infracfg: must contain a phandle to the infracfg controller
-- 
1.7.9.5



From scott.shu at mediatek.com  Tue Aug  4 06:54:22 2015
From: scott.shu at mediatek.com (Scott Shu)
Date: Tue, 4 Aug 2015 21:54:22 +0800
Subject: [PATCH v3 6/8] ARM: Mediatek: enable GPT6 on boot up to make arch
 timer working for MT6580
In-Reply-To: <1438696464-59858-1-git-send-email-scott.shu@mediatek.com>
References: <1438696464-59858-1-git-send-email-scott.shu@mediatek.com>
Message-ID: <1438696464-59858-7-git-send-email-scott.shu@mediatek.com>

We enable GTP6 which ungates the arch timer clock.

Signed-off-by: Scott Shu <scott.shu at mediatek.com>
---
 arch/arm/mach-mediatek/mediatek.c |    4 +++-
 1 file changed, 3 insertions(+), 1 deletion(-)

diff --git a/arch/arm/mach-mediatek/mediatek.c b/arch/arm/mach-mediatek/mediatek.c
index 6b38d67..469d332 100644
--- a/arch/arm/mach-mediatek/mediatek.c
+++ b/arch/arm/mach-mediatek/mediatek.c
@@ -28,7 +28,8 @@ static void __init mediatek_timer_init(void)
 {
 	void __iomem *gpt_base = 0;
 
-	if (of_machine_is_compatible("mediatek,mt6589") ||
+	if (of_machine_is_compatible("mediatek,mt6580") ||
+	    of_machine_is_compatible("mediatek,mt6589") ||
 	    of_machine_is_compatible("mediatek,mt8135") ||
 	    of_machine_is_compatible("mediatek,mt8127")) {
 		/* turn on GPT6 which ungates arch timer clocks */
@@ -46,6 +47,7 @@ static void __init mediatek_timer_init(void)
 };
 
 static const char * const mediatek_board_dt_compat[] = {
+	"mediatek,mt6580",
 	"mediatek,mt6589",
 	"mediatek,mt6592",
 	"mediatek,mt8127",
-- 
1.7.9.5



From scott.shu at mediatek.com  Tue Aug  4 06:54:23 2015
From: scott.shu at mediatek.com (Scott Shu)
Date: Tue, 4 Aug 2015 21:54:23 +0800
Subject: [PATCH v3 7/8] ARM: dts: mt6580: Add device nodes to the MT6580 dtsi
 file
In-Reply-To: <1438696464-59858-1-git-send-email-scott.shu@mediatek.com>
References: <1438696464-59858-1-git-send-email-scott.shu@mediatek.com>
Message-ID: <1438696464-59858-8-git-send-email-scott.shu@mediatek.com>

This adds the SCPSYS device node to the MT6580 dtsi file.

Signed-off-by: Scott Shu <scott.shu at mediatek.com>
---
 arch/arm/boot/dts/mt6580.dtsi |    6 ++++++
 1 file changed, 6 insertions(+)

diff --git a/arch/arm/boot/dts/mt6580.dtsi b/arch/arm/boot/dts/mt6580.dtsi
index 06fdf6c..40957d3 100644
--- a/arch/arm/boot/dts/mt6580.dtsi
+++ b/arch/arm/boot/dts/mt6580.dtsi
@@ -67,6 +67,12 @@
 		#clock-cells = <0>;
 	};
 
+	scpsys: scpsys at 10006000 {
+		#power-domain-cells = <1>;
+		compatible = "mediatek,mt6580-scpsys";
+		reg = <0x10006000 0x1000>;
+	};
+
 	timer: timer at 10008000 {
 		compatible = "mediatek,mt6580-timer",
 			     "mediatek,mt6577-timer";
-- 
1.7.9.5



From geert+renesas at glider.be  Tue Aug  4 06:55:15 2015
From: geert+renesas at glider.be (Geert Uytterhoeven)
Date: Tue,  4 Aug 2015 15:55:15 +0200
Subject: [PATCH v2 2/6] ARM: shmobile: r8a7740 dtsi: Add missing "gpio-ranges"
 to gpio node
In-Reply-To: <1438696519-13727-1-git-send-email-geert+renesas@glider.be>
References: <1438696519-13727-1-git-send-email-geert+renesas@glider.be>
Message-ID: <1438696519-13727-3-git-send-email-geert+renesas@glider.be>

If a GPIO driver uses gpiochip_add_pin_range() (which is usually the
case for GPIO/PFC combos), the GPIO hogging mechanism configured from DT
doesn't work:

    requesting hog GPIO lcd0 (chip r8a7740_pfc, offset 176) failed

The actual error code is -517 == -EPROBE_DEFER.

The problem is that PFC+GPIO registration is handled in multiple steps:
  1. pinctrl_register(),
  2. gpiochip_add(),
  3. gpiochip_add_pin_range().

Configuration of the hogs is handled in gpiochip_add():

    gpiochip_add
        of_gpiochip_add
            of_gpiochip_scan_hogs
                gpiod_hog
                    gpiochip_request_own_desc
                        __gpiod_request
                            chip->request
                                pinctrl_request_gpio
                                    pinctrl_get_device_gpio_range

However, at this point the GPIO controller hasn't been added to
pinctrldev_list yet, so the range can't be found, and the operation fails
with -EPROBE_DEFER.

To fix this, add a "gpio-ranges" property to the gpio device node, so
the range is added by of_gpiochip_add_pin_range(), which is called by
of_gpiochip_add() before the call to of_gpiochip_scan_hogs().

Signed-off-by: Geert Uytterhoeven <geert+renesas at glider.be>
Acked-by: Laurent Pinchart <laurent.pinchart at ideasonboard.com>
Acked-by: Linus Walleij <linus.walleij at linaro.org>
---
v2:
  - Add Acked-by.
---
 arch/arm/boot/dts/r8a7740.dtsi | 1 +
 1 file changed, 1 insertion(+)

diff --git a/arch/arm/boot/dts/r8a7740.dtsi b/arch/arm/boot/dts/r8a7740.dtsi
index d84714468cce18df..e14cb1438216e8df 100644
--- a/arch/arm/boot/dts/r8a7740.dtsi
+++ b/arch/arm/boot/dts/r8a7740.dtsi
@@ -291,6 +291,7 @@
 		      <0xe605800c 0x20>;
 		gpio-controller;
 		#gpio-cells = <2>;
+		gpio-ranges = <&pfc 0 0 212>;
 		interrupts-extended =
 			<&irqpin0 0 0>, <&irqpin0 1 0>, <&irqpin0 2 0>, <&irqpin0 3 0>,
 			<&irqpin0 4 0>, <&irqpin0 5 0>, <&irqpin0 6 0>, <&irqpin0 7 0>,
-- 
1.9.1



From geert+renesas at glider.be  Tue Aug  4 06:55:19 2015
From: geert+renesas at glider.be (Geert Uytterhoeven)
Date: Tue,  4 Aug 2015 15:55:19 +0200
Subject: [PATCH v2 6/6] pinctrl: sh-pfc: Confine legacy function GPIOs to SH
In-Reply-To: <1438696519-13727-1-git-send-email-geert+renesas@glider.be>
References: <1438696519-13727-1-git-send-email-geert+renesas@glider.be>
Message-ID: <1438696519-13727-7-git-send-email-geert+renesas@glider.be>

Legacy function GPIOs are no longer used on ARM since commit
a27c5cd1a08cc95c ("sh-pfc: sh73a0: Remove function GPIOs").
Extract its setup code into a separate function, and make all function
GPIO related code and data depend on CONFIG_SUPERH.

Signed-off-by: Geert Uytterhoeven <geert+renesas at glider.be>
Acked-by: Linus Walleij <linus.walleij at linaro.org>
---
Compile-tested on sh using se7724_defconfig.

v2:
  - Add Acked-by,
  - #ifdef out the code instead of introducing helper and dummy
    functions.
---
 drivers/pinctrl/sh-pfc/core.h   | 2 ++
 drivers/pinctrl/sh-pfc/gpio.c   | 7 ++++++-
 drivers/pinctrl/sh-pfc/sh_pfc.h | 2 ++
 3 files changed, 10 insertions(+), 1 deletion(-)

diff --git a/drivers/pinctrl/sh-pfc/core.h b/drivers/pinctrl/sh-pfc/core.h
index 4c3c37bf7161804d..c38ace46d7111b0d 100644
--- a/drivers/pinctrl/sh-pfc/core.h
+++ b/drivers/pinctrl/sh-pfc/core.h
@@ -46,7 +46,9 @@ struct sh_pfc {
 	unsigned int nr_gpio_pins;
 
 	struct sh_pfc_chip *gpio;
+#ifdef CONFIG_SUPERH
 	struct sh_pfc_chip *func;
+#endif
 
 	struct sh_pfc_pinctrl *pinctrl;
 };
diff --git a/drivers/pinctrl/sh-pfc/gpio.c b/drivers/pinctrl/sh-pfc/gpio.c
index e46439030914ad13..685b3c24627daf03 100644
--- a/drivers/pinctrl/sh-pfc/gpio.c
+++ b/drivers/pinctrl/sh-pfc/gpio.c
@@ -261,6 +261,7 @@ static int gpio_pin_setup(struct sh_pfc_chip *chip)
  * Function GPIOs
  */
 
+#ifdef CONFIG_SUPERH
 static int gpio_function_request(struct gpio_chip *gc, unsigned offset)
 {
 	static bool __print_once;
@@ -300,6 +301,7 @@ static int gpio_function_setup(struct sh_pfc_chip *chip)
 
 	return 0;
 }
+#endif
 
 /* -----------------------------------------------------------------------------
  * Register/unregister
@@ -399,6 +401,7 @@ int sh_pfc_register_gpiochip(struct sh_pfc *pfc)
 		}
 	}
 
+#ifdef CONFIG_SUPERH
 	/* Register the function GPIOs chip. */
 	if (pfc->info->nr_func_gpios == 0)
 		return 0;
@@ -408,6 +411,7 @@ int sh_pfc_register_gpiochip(struct sh_pfc *pfc)
 		return PTR_ERR(chip);
 
 	pfc->func = chip;
+#endif /* CONFIG_SUPERH */
 
 	return 0;
 }
@@ -415,7 +419,8 @@ int sh_pfc_register_gpiochip(struct sh_pfc *pfc)
 int sh_pfc_unregister_gpiochip(struct sh_pfc *pfc)
 {
 	gpiochip_remove(&pfc->gpio->gpio_chip);
+#ifdef CONFIG_SUPERH
 	gpiochip_remove(&pfc->func->gpio_chip);
-
+#endif
 	return 0;
 }
diff --git a/drivers/pinctrl/sh-pfc/sh_pfc.h b/drivers/pinctrl/sh-pfc/sh_pfc.h
index 0874cfee6889afa1..1f43bae56065e659 100644
--- a/drivers/pinctrl/sh-pfc/sh_pfc.h
+++ b/drivers/pinctrl/sh-pfc/sh_pfc.h
@@ -138,8 +138,10 @@ struct sh_pfc_soc_info {
 	const struct sh_pfc_function *functions;
 	unsigned int nr_functions;
 
+#ifdef CONFIG_SUPERH
 	const struct pinmux_func *func_gpios;
 	unsigned int nr_func_gpios;
+#endif
 
 	const struct pinmux_cfg_reg *cfg_regs;
 	const struct pinmux_data_reg *data_regs;
-- 
1.9.1



From geert+renesas at glider.be  Tue Aug  4 06:55:18 2015
From: geert+renesas at glider.be (Geert Uytterhoeven)
Date: Tue,  4 Aug 2015 15:55:18 +0200
Subject: [PATCH v2 5/6] pinctrl: sh-pfc: Remove empty gpio_function_free()
In-Reply-To: <1438696519-13727-1-git-send-email-geert+renesas@glider.be>
References: <1438696519-13727-1-git-send-email-geert+renesas@glider.be>
Message-ID: <1438696519-13727-6-git-send-email-geert+renesas@glider.be>

gpio_chip.free() is optional, and can just be left unimplemented.

Signed-off-by: Geert Uytterhoeven <geert+renesas at glider.be>
Acked-by: Laurent Pinchart <laurent.pinchart at ideasonboard.com>
Acked-by: Linus Walleij <linus.walleij at linaro.org>
---
Untested due to lack of hardware (used on sh only).

v2:
  - Add Acked-by.
---
 drivers/pinctrl/sh-pfc/gpio.c | 5 -----
 1 file changed, 5 deletions(-)

diff --git a/drivers/pinctrl/sh-pfc/gpio.c b/drivers/pinctrl/sh-pfc/gpio.c
index b380e3f17b121bbb..e46439030914ad13 100644
--- a/drivers/pinctrl/sh-pfc/gpio.c
+++ b/drivers/pinctrl/sh-pfc/gpio.c
@@ -286,17 +286,12 @@ static int gpio_function_request(struct gpio_chip *gc, unsigned offset)
 	return ret;
 }
 
-static void gpio_function_free(struct gpio_chip *gc, unsigned offset)
-{
-}
-
 static int gpio_function_setup(struct sh_pfc_chip *chip)
 {
 	struct sh_pfc *pfc = chip->pfc;
 	struct gpio_chip *gc = &chip->gpio_chip;
 
 	gc->request = gpio_function_request;
-	gc->free = gpio_function_free;
 
 	gc->label = pfc->info->name;
 	gc->owner = THIS_MODULE;
-- 
1.9.1



From geert+renesas at glider.be  Tue Aug  4 06:55:13 2015
From: geert+renesas at glider.be (Geert Uytterhoeven)
Date: Tue,  4 Aug 2015 15:55:13 +0200
Subject: [PATCH v2 0/6] ARM: shmobile: Move gpio ranges from C code to DT
Message-ID: <1438696519-13727-1-git-send-email-geert+renesas@glider.be>

	Hi Simon, Magnus,

This patch series moves the setup of the GPIO-PFC pin mapping for
Renesas PFC/GPIO combos from C code to DT, and does some cleanups.
The move to DT is needed to make the GPIO hogging mechanism work, cfr.
the discussion following "[PATCH] [RFC] gpio: Retry deferred GPIO
hogging on pin range change" (https://lkml.org/lkml/2015/6/16/455).

The series consists of 3 parts:
  a. Patches 1-3 add the missing "gpio-ranges" properties to the dtsi
     files for all affected SoCs,
  b. Patch 4 disables the C code to set up the mapping on DT platforms
     (it's still needed on SH or ARM-legacy),
  c. Patches 5-6 do a few more cleanups in the sh-pfc gpio code.

Changes compared to v1 ("[PATCH 0/7] ARM: shmobile: Move gpio ranges
from C code to DT",
http://lists.infradead.org/pipermail/linux-arm-kernel/2015-June/353124.html):
  - Add check for CONFIG_OF and pfc->dev->of_node,
  - #ifdef out the code instead of introducing helper and dummy
    functions,
  - Drop "pinctrl: sh-pfc: Move sh_pfc_add_gpiochip() up", as it's no
    longer needed due to the #ifdefs,
  - Add Acked-by.

Dependencies:
  - This series applies against renesas-devel-20150803-v4.2-rc5,
  - Part a must go in first, to avoid regressions,
  - While I didn't notice any bad behavior by having part a only, part b
    should go in immediately after part a. Hence I think it's best if
    Simon can take this one, too.
  - Part c is independent (it doesn't touch the same code), so it can go
    in before or after the other parts, or in parallel.

Given this fixes the LCD on r8a7740/armadillo, which is a regression
introduced by the removal of armadillo-legacy support, I think at least
patch 2 should be queued for v4.3.

Thanks for applying!

Geert Uytterhoeven (6):
  ARM: shmobile: r8a73a4 dtsi: Add missing "gpio-ranges" to gpio node
  ARM: shmobile: r8a7740 dtsi: Add missing "gpio-ranges" to gpio node
  ARM: shmobile: sh73a0 dtsi: Add missing "gpio-ranges" to gpio node
  pinctrl: sh-pfc: Stop calling gpiochip_add_pin_range() on DT platforms
  pinctrl: sh-pfc: Remove empty gpio_function_free()
  pinctrl: sh-pfc: Confine legacy function GPIOs to SH

 arch/arm/boot/dts/r8a73a4.dtsi  |  7 ++++++
 arch/arm/boot/dts/r8a7740.dtsi  |  1 +
 arch/arm/boot/dts/sh73a0.dtsi   |  3 +++
 drivers/pinctrl/sh-pfc/core.h   |  2 ++
 drivers/pinctrl/sh-pfc/gpio.c   | 49 +++++++++++++++++++++++------------------
 drivers/pinctrl/sh-pfc/sh_pfc.h |  2 ++
 6 files changed, 43 insertions(+), 21 deletions(-)

-- 
1.9.1

Gr{oetje,eeting}s,

						Geert

--
Geert Uytterhoeven -- There's lots of Linux beyond ia32 -- geert at linux-m68k.org

In personal conversations with technical people, I call myself a hacker. But
when I'm talking to journalists I just say "programmer" or something like that.
							    -- Linus Torvalds


From geert+renesas at glider.be  Tue Aug  4 06:55:17 2015
From: geert+renesas at glider.be (Geert Uytterhoeven)
Date: Tue,  4 Aug 2015 15:55:17 +0200
Subject: [PATCH v2 4/6] pinctrl: sh-pfc: Stop calling gpiochip_add_pin_range()
 on DT platforms
In-Reply-To: <1438696519-13727-1-git-send-email-geert+renesas@glider.be>
References: <1438696519-13727-1-git-send-email-geert+renesas@glider.be>
Message-ID: <1438696519-13727-5-git-send-email-geert+renesas@glider.be>

On platforms where the PFC/GPIO controller is instantiated from DT, the
mapping between GPIOs and pins is set up using the "gpio-ranges"
property in DT.

Hence stop setting up the mapping from C code on DT platforms.
This code is still used for SH or ARM-legacy platforms.

Signed-off-by: Geert Uytterhoeven <geert+renesas at glider.be>
Acked-by: Linus Walleij <linus.walleij at linaro.org>
---
v2:
  - Add Acked-by,
  - Add check for CONFIG_OF and pfc->dev->of_node.
---
 drivers/pinctrl/sh-pfc/gpio.c | 37 ++++++++++++++++++++++---------------
 1 file changed, 22 insertions(+), 15 deletions(-)

diff --git a/drivers/pinctrl/sh-pfc/gpio.c b/drivers/pinctrl/sh-pfc/gpio.c
index ba353735ecf2be9a..b380e3f17b121bbb 100644
--- a/drivers/pinctrl/sh-pfc/gpio.c
+++ b/drivers/pinctrl/sh-pfc/gpio.c
@@ -379,22 +379,29 @@ int sh_pfc_register_gpiochip(struct sh_pfc *pfc)
 
 	pfc->gpio = chip;
 
-	/* Register the GPIO to pin mappings. As pins with GPIO ports must come
-	 * first in the ranges, skip the pins without GPIO ports by stopping at
-	 * the first range that contains such a pin.
-	 */
-	for (i = 0; i < pfc->nr_ranges; ++i) {
-		const struct sh_pfc_pin_range *range = &pfc->ranges[i];
-
-		if (range->start >= pfc->nr_gpio_pins)
-			break;
+	if (IS_ENABLED(CONFIG_OF) && pfc->dev->of_node)
+		return 0;
 
-		ret = gpiochip_add_pin_range(&chip->gpio_chip,
-					     dev_name(pfc->dev),
-					     range->start, range->start,
-					     range->end - range->start + 1);
-		if (ret < 0)
-			return ret;
+	if (IS_ENABLED(CONFIG_SUPERH) ||
+	    IS_ENABLED(CONFIG_ARCH_SHMOBILE_LEGACY)) {
+		/*
+		 * Register the GPIO to pin mappings. As pins with GPIO ports
+		 * must come first in the ranges, skip the pins without GPIO
+		 * ports by stopping at the first range that contains such a
+		 * pin.
+		 */
+		for (i = 0; i < pfc->nr_ranges; ++i) {
+			const struct sh_pfc_pin_range *range = &pfc->ranges[i];
+
+			if (range->start >= pfc->nr_gpio_pins)
+				break;
+
+			ret = gpiochip_add_pin_range(&chip->gpio_chip,
+				dev_name(pfc->dev), range->start, range->start,
+				range->end - range->start + 1);
+			if (ret < 0)
+				return ret;
+		}
 	}
 
 	/* Register the function GPIOs chip. */
-- 
1.9.1



From geert+renesas at glider.be  Tue Aug  4 06:55:14 2015
From: geert+renesas at glider.be (Geert Uytterhoeven)
Date: Tue,  4 Aug 2015 15:55:14 +0200
Subject: [PATCH v2 1/6] ARM: shmobile: r8a73a4 dtsi: Add missing "gpio-ranges"
 to gpio node
In-Reply-To: <1438696519-13727-1-git-send-email-geert+renesas@glider.be>
References: <1438696519-13727-1-git-send-email-geert+renesas@glider.be>
Message-ID: <1438696519-13727-2-git-send-email-geert+renesas@glider.be>

If a GPIO driver uses gpiochip_add_pin_range() (which is usually the
case for GPIO/PFC combos), the GPIO hogging mechanism configured from DT
doesn't work:

    requesting hog GPIO led1-high (chip r8a73a4_pfc, offset 28) failed

The actual error code is -517 == -EPROBE_DEFER.

The problem is that PFC+GPIO registration is handled in multiple steps:
  1. pinctrl_register(),
  2. gpiochip_add(),
  3. gpiochip_add_pin_range().

Configuration of the hogs is handled in gpiochip_add():

    gpiochip_add
        of_gpiochip_add
            of_gpiochip_scan_hogs
                gpiod_hog
                    gpiochip_request_own_desc
                        __gpiod_request
                            chip->request
                                pinctrl_request_gpio
                                    pinctrl_get_device_gpio_range

However, at this point the GPIO controller hasn't been added to
pinctrldev_list yet, so the range can't be found, and the operation fails
with -EPROBE_DEFER.

To fix this, add a "gpio-ranges" property to the gpio device node, so
the ranges are added by of_gpiochip_add_pin_range(), which is called by
of_gpiochip_add() before the call to of_gpiochip_scan_hogs().

Signed-off-by: Geert Uytterhoeven <geert+renesas at glider.be>
Acked-by: Laurent Pinchart <laurent.pinchart at ideasonboard.com>
Acked-by: Linus Walleij <linus.walleij at linaro.org>
---
v2:
  - Add Acked-by.
---
 arch/arm/boot/dts/r8a73a4.dtsi | 7 +++++++
 1 file changed, 7 insertions(+)

diff --git a/arch/arm/boot/dts/r8a73a4.dtsi b/arch/arm/boot/dts/r8a73a4.dtsi
index 5090d1a8f652e8be..cb4f7b2798fe23be 100644
--- a/arch/arm/boot/dts/r8a73a4.dtsi
+++ b/arch/arm/boot/dts/r8a73a4.dtsi
@@ -207,6 +207,13 @@
 		reg = <0 0xe6050000 0 0x9000>;
 		gpio-controller;
 		#gpio-cells = <2>;
+		gpio-ranges =
+			<&pfc 0 0 31>, <&pfc 32 32 9>,
+			<&pfc 64 64 22>, <&pfc 96 96 31>,
+			<&pfc 128 128 7>, <&pfc 160 160 19>,
+			<&pfc 192 192 31>, <&pfc 224 224 27>,
+			<&pfc 256 256 28>, <&pfc 288 288 21>,
+			<&pfc 320 320 10>;
 		interrupts-extended =
 			<&irqc0  0 0>, <&irqc0  1 0>, <&irqc0  2 0>, <&irqc0  3 0>,
 			<&irqc0  4 0>, <&irqc0  5 0>, <&irqc0  6 0>, <&irqc0  7 0>,
-- 
1.9.1



From geert+renesas at glider.be  Tue Aug  4 06:55:16 2015
From: geert+renesas at glider.be (Geert Uytterhoeven)
Date: Tue,  4 Aug 2015 15:55:16 +0200
Subject: [PATCH v2 3/6] ARM: shmobile: sh73a0 dtsi: Add missing "gpio-ranges"
 to gpio node
In-Reply-To: <1438696519-13727-1-git-send-email-geert+renesas@glider.be>
References: <1438696519-13727-1-git-send-email-geert+renesas@glider.be>
Message-ID: <1438696519-13727-4-git-send-email-geert+renesas@glider.be>

If a GPIO driver uses gpiochip_add_pin_range() (which is usually the
case for GPIO/PFC combos), the GPIO hogging mechanism configured from DT
doesn't work:

    requesting hog GPIO led1-high (chip sh73a0_pfc, offset 20) failed

The actual error code is -517 == -EPROBE_DEFER.

The problem is that PFC+GPIO registration is handled in multiple steps:
  1. pinctrl_register(),
  2. gpiochip_add(),
  3. gpiochip_add_pin_range().

Configuration of the hogs is handled in gpiochip_add():

    gpiochip_add
        of_gpiochip_add
            of_gpiochip_scan_hogs
                gpiod_hog
                    gpiochip_request_own_desc
                        __gpiod_request
                            chip->request
                                pinctrl_request_gpio
                                    pinctrl_get_device_gpio_range

However, at this point the GPIO controller hasn't been added to
pinctrldev_list yet, so the range can't be found, and the operation fails
with -EPROBE_DEFER.

To fix this, add a "gpio-ranges" property to the gpio device node, so
the ranges are added by of_gpiochip_add_pin_range(), which is called by
of_gpiochip_add() before the call to of_gpiochip_scan_hogs().

Signed-off-by: Geert Uytterhoeven <geert+renesas at glider.be>
Acked-by: Laurent Pinchart <laurent.pinchart at ideasonboard.com>
Acked-by: Linus Walleij <linus.walleij at linaro.org>
---
v2:
  - Add Acked-by.
---
 arch/arm/boot/dts/sh73a0.dtsi | 3 +++
 1 file changed, 3 insertions(+)

diff --git a/arch/arm/boot/dts/sh73a0.dtsi b/arch/arm/boot/dts/sh73a0.dtsi
index 11e17c5f26e2cae2..ff7c8f298f30a58d 100644
--- a/arch/arm/boot/dts/sh73a0.dtsi
+++ b/arch/arm/boot/dts/sh73a0.dtsi
@@ -392,6 +392,9 @@
 		      <0xe605801c 0x1c>;
 		gpio-controller;
 		#gpio-cells = <2>;
+		gpio-ranges =
+			<&pfc 0 0 119>, <&pfc 128 128 37>, <&pfc 192 192 91>,
+			<&pfc 288 288 22>;
 		interrupts-extended =
 			<&irqpin0 0 0>, <&irqpin0 1 0>, <&irqpin0 2 0>, <&irqpin0 3 0>,
 			<&irqpin0 4 0>, <&irqpin0 5 0>, <&irqpin0 6 0>, <&irqpin0 7 0>,
-- 
1.9.1



From skarajga at visteon.com  Tue Aug  4 07:01:01 2015
From: skarajga at visteon.com (Karajgaonkar, Saurabh (S.))
Date: Tue, 4 Aug 2015 14:01:01 +0000
Subject: [PATCH v2 0/9] usb: Simplify return statements
Message-ID: <cover.1438695318.git.skarajga@visteon.com>

From: Saurabh Karajgaonkar <skarajga at visteon.com>

This patch series is created using simple_return.cocci coccinelle script.
It replaces the redundant instances where variable is first assigned
return value from a function call and then used in return statement,
by direct function call in the return statement.

Changes for v2:
- corrected indentation issues [Patch 06/09, 08/09, 09/09]
- Patch 04/09 Acked by Patrice Chotard <patrice.chotard at st.com>

Saurabh Karajgaonkar (9):
  usb: phy: phy-mxs-usb: Simplify return statement
  usb: phy: phy-keystone: Simplify return statement
  usb: musb: musb_dsps: Simplify return statement
  usb: host: ehci-st: Simplify return statement
  usb: host: oxu210hp-hcd: Simplify return statement
  usb: host: u132-hcd: Simplify return statement
  usb: host: xhci: Simplify return statement
  usb: serial: mxuport: Simplify return statement
  usb: misc: ftdi-elan: Simplify return statement

 drivers/usb/host/ehci-st.c      |  7 +------
 drivers/usb/host/oxu210hp-hcd.c |  7 +------
 drivers/usb/host/u132-hcd.c     | 35 +++++++++--------------------------
 drivers/usb/host/xhci.c         |  6 +-----
 drivers/usb/misc/ftdi-elan.c    | 12 ++----------
 drivers/usb/musb/musb_dsps.c    |  6 +-----
 drivers/usb/phy/phy-keystone.c  |  6 +-----
 drivers/usb/phy/phy-mxs-usb.c   |  6 +-----
 drivers/usb/serial/mxuport.c    | 10 +++-------
 9 files changed, 20 insertions(+), 75 deletions(-)

-- 
1.9.1


From skarajga at visteon.com  Tue Aug  4 07:01:31 2015
From: skarajga at visteon.com (Karajgaonkar, Saurabh (S.))
Date: Tue, 4 Aug 2015 14:01:31 +0000
Subject: [PATCH v2 1/9] usb: phy: phy-mxs-usb: Simplify return statement
In-Reply-To: <cover.1438695318.git.skarajga@visteon.com>
References: <cover.1438695318.git.skarajga@visteon.com>
Message-ID: <0e24e9030dc43d6191c74039faf79de49e45c191.1438695318.git.skarajga@visteon.com>

From: Saurabh Karajgaonkar <skarajga at visteon.com>

Replace redundant variable use in return statement.

Signed-off-by: Saurabh Karajgaonkar <skarajga at visteon.com>
---
 drivers/usb/phy/phy-mxs-usb.c | 6 +-----
 1 file changed, 1 insertion(+), 5 deletions(-)

diff --git a/drivers/usb/phy/phy-mxs-usb.c b/drivers/usb/phy/phy-mxs-usb.c
index 3fcc048..4d863eb 100644
--- a/drivers/usb/phy/phy-mxs-usb.c
+++ b/drivers/usb/phy/phy-mxs-usb.c
@@ -506,11 +506,7 @@ static int mxs_phy_probe(struct platform_device *pdev)
 
 	device_set_wakeup_capable(&pdev->dev, true);
 
-	ret = usb_add_phy_dev(&mxs_phy->phy);
-	if (ret)
-		return ret;
-
-	return 0;
+	return usb_add_phy_dev(&mxs_phy->phy);
 }
 
 static int mxs_phy_remove(struct platform_device *pdev)
-- 
1.9.1


From skarajga at visteon.com  Tue Aug  4 07:02:03 2015
From: skarajga at visteon.com (Karajgaonkar, Saurabh (S.))
Date: Tue, 4 Aug 2015 14:02:03 +0000
Subject: [PATCH v2 2/9] usb: phy: phy-keystone: Simplify return statement
In-Reply-To: <cover.1438695318.git.skarajga@visteon.com>
References: <cover.1438695318.git.skarajga@visteon.com>
Message-ID: <40402eeb0cd861569faf838efccc1ef4672da83c.1438695318.git.skarajga@visteon.com>

From: Saurabh Karajgaonkar <skarajga at visteon.com>

Replace redundant variable use in return statement.

Signed-off-by: Saurabh Karajgaonkar <skarajga at visteon.com>
---
 drivers/usb/phy/phy-keystone.c | 6 +-----
 1 file changed, 1 insertion(+), 5 deletions(-)

diff --git a/drivers/usb/phy/phy-keystone.c b/drivers/usb/phy/phy-keystone.c
index e0556f7..01d4e4c 100644
--- a/drivers/usb/phy/phy-keystone.c
+++ b/drivers/usb/phy/phy-keystone.c
@@ -96,11 +96,7 @@ static int keystone_usbphy_probe(struct platform_device *pdev)
 
 	platform_set_drvdata(pdev, k_phy);
 
-	ret = usb_add_phy_dev(&k_phy->usb_phy_gen.phy);
-	if (ret)
-		return ret;
-
-	return 0;
+	return usb_add_phy_dev(&k_phy->usb_phy_gen.phy);
 }
 
 static int keystone_usbphy_remove(struct platform_device *pdev)
-- 
1.9.1


From skarajga at visteon.com  Tue Aug  4 07:02:28 2015
From: skarajga at visteon.com (Karajgaonkar, Saurabh (S.))
Date: Tue, 4 Aug 2015 14:02:28 +0000
Subject: [PATCH v2 3/9] usb: musb: musb_dsps: Simplify return statement
In-Reply-To: <cover.1438695318.git.skarajga@visteon.com>
References: <cover.1438695318.git.skarajga@visteon.com>
Message-ID: <0484e5c9da0a2f46386c79115be618f228b42443.1438695318.git.skarajga@visteon.com>

From: Saurabh Karajgaonkar <skarajga at visteon.com>

Replace redundant variable use in return statement.

Signed-off-by: Saurabh Karajgaonkar <skarajga at visteon.com>
---
 drivers/usb/musb/musb_dsps.c | 6 +-----
 1 file changed, 1 insertion(+), 5 deletions(-)

diff --git a/drivers/usb/musb/musb_dsps.c b/drivers/usb/musb/musb_dsps.c
index 1334a3d..a0cfead 100644
--- a/drivers/usb/musb/musb_dsps.c
+++ b/drivers/usb/musb/musb_dsps.c
@@ -482,11 +482,7 @@ static int dsps_musb_init(struct musb *musb)
 		dsps_writeb(musb->mregs, MUSB_BABBLE_CTL, val);
 	}
 
-	ret = dsps_musb_dbg_init(musb, glue);
-	if (ret)
-		return ret;
-
-	return 0;
+	return dsps_musb_dbg_init(musb, glue);
 }
 
 static int dsps_musb_exit(struct musb *musb)
-- 
1.9.1


From marc.zyngier at arm.com  Tue Aug  4 07:02:05 2015
From: marc.zyngier at arm.com (Marc Zyngier)
Date: Tue, 04 Aug 2015 15:02:05 +0100
Subject: [PATCH v4 08/10] ACPI: GIC: Add ACPI helper functions to query
 irq-domain tokens for for GIC MSI and ITS
In-Reply-To: <1438164539-29256-9-git-send-email-hanjun.guo@linaro.org>
References: <1438164539-29256-1-git-send-email-hanjun.guo@linaro.org>
 <1438164539-29256-9-git-send-email-hanjun.guo@linaro.org>
Message-ID: <55C0C5DD.6090607@arm.com>

On 29/07/15 11:08, Hanjun Guo wrote:
> From: Suravee Suthikulpanit <Suravee.Suthikulpanit at amd.com>
> 
> This patch introduces acpi_gic_get_msi_token(), which returns irq-domain
> token that can be used to look up MSI doamin of a device.
> In both GIC MSI and ITS cases, the base_address specified in the GIC MSI
> or GIC ITS structure is used as a token for MSI domain.
> 
> In addition, this patch also provides low-level helper functions to parse
> and query GIC MSI structure and GIC ITS from MADT. Once parsed, it keeps
> a copy of the structure for use in subsequent queries to avoid having
> to map and parse MADT multiple times.
> 
> Signed-off-by: Suravee Suthikulpanit <Suravee.Suthikulpanit at amd.com>
> Signed-off-by: Hanjun Guo <hanjun.guo at linaro.org>
> ---
>  drivers/acpi/Makefile   |   1 +
>  drivers/acpi/acpi_gic.c | 234 ++++++++++++++++++++++++++++++++++++++++++++++++
>  include/acpi/acpi_gic.h |  23 +++++
>  include/linux/acpi.h    |   1 +
>  4 files changed, 259 insertions(+)
>  create mode 100644 drivers/acpi/acpi_gic.c
>  create mode 100644 include/acpi/acpi_gic.h
> 
> diff --git a/drivers/acpi/Makefile b/drivers/acpi/Makefile
> index 8321430..def54b9 100644
> --- a/drivers/acpi/Makefile
> +++ b/drivers/acpi/Makefile
> @@ -54,6 +54,7 @@ acpi-$(CONFIG_ACPI_NUMA)	+= numa.o
>  acpi-$(CONFIG_ACPI_PROCFS_POWER) += cm_sbs.o
>  acpi-y				+= acpi_lpat.o
>  acpi-$(CONFIG_ACPI_GENERIC_GSI) += gsi.o
> +acpi-$(CONFIG_ARM_GIC_ACPI)	+= acpi_gic.o
>  
>  # These are (potentially) separate modules
>  
> diff --git a/drivers/acpi/acpi_gic.c b/drivers/acpi/acpi_gic.c
> new file mode 100644
> index 0000000..11ee4eb
> --- /dev/null
> +++ b/drivers/acpi/acpi_gic.c

I think this is starting badly. If this is GIC specific, it lives in
drivers/irqchip. Nothing in drivers/acpi should be interrupt-controller
specific at all. If there are things you need to expose through the ACPI
layer, add some indirections.

> @@ -0,0 +1,234 @@
> +/*
> + * File: acpi_gic.c
> + *
> + * ACPI helper functions for ARM GIC
> + *
> + * Copyright (C) 2015 Advanced Micro Devices, Inc.
> + * Authors: Suravee Suthikulpanit <suravee.suthikulpanit at amd.com>
> + */
> +
> +#include <linux/acpi.h>
> +#include <linux/init.h>
> +
> +/*
> + * GIC MSI Frame data structures
> + */
> +struct gic_msi_frame_handle {
> +	struct list_head list;
> +	struct acpi_madt_generic_msi_frame frame;
> +};
> +
> +static LIST_HEAD(msi_frame_list);
> +
> +static int acpi_num_msi;
> +
> +/*
> + * GIC ITS data structures
> + */
> +struct gic_its_handle {
> +	struct list_head list;
> +	struct acpi_madt_generic_translator trans;
> +};
> +
> +static LIST_HEAD(its_list);
> +
> +static int acpi_num_its;
> +
> +/*
> + * GIC MSI Frame parsing stuff
> + */
> +inline int acpi_gic_get_num_msi_frame(void)
> +{
> +	return acpi_num_msi;
> +}

Really???

> +
> +static int __init
> +acpi_parse_madt_msi(struct acpi_subtable_header *header,
> +		    const unsigned long end)
> +{
> +	struct gic_msi_frame_handle *h;
> +	struct acpi_madt_generic_msi_frame *frame;
> +
> +	frame = (struct acpi_madt_generic_msi_frame *)header;
> +	if (BAD_MADT_ENTRY(frame, end))
> +		return -EINVAL;
> +
> +	h = kzalloc(sizeof(struct gic_msi_frame_handle *), GFP_KERNEL);
> +	if (!h)
> +		return -ENOMEM;
> +
> +	/** Note:
> +	 * We make a copy of this structure since this code is called
> +	 * prior to acpi_early_init(), which sets the acpi_gbl_permanent_mmap.
> +	 * Therefore, we could not keep just the pointer sincce the memory
> +	 * could be unmapped.
> +	 */
> +	memcpy(&h->frame, frame, sizeof(struct acpi_madt_generic_msi_frame));
> +
> +	list_add(&h->list, &msi_frame_list);
> +
> +	return 0;
> +}
> +
> +int __init acpi_gic_msi_init(struct acpi_table_header *table)
> +{
> +	int ret = 0;
> +
> +	if (acpi_num_msi > 0)
> +		return ret;
> +
> +	ret = acpi_parse_entries(ACPI_SIG_MADT,
> +				 sizeof(struct acpi_table_madt),
> +				 acpi_parse_madt_msi, table,
> +				 ACPI_MADT_TYPE_GENERIC_MSI_FRAME, 0);
> +	if (ret == 0) {
> +		pr_debug("No valid ACPI GIC MSI FRAME exist\n");
> +		return ret;
> +	}
> +
> +	acpi_num_msi = ret;
> +	return 0;
> +}
> +
> +int acpi_gic_get_msi_frame(int index, struct acpi_madt_generic_msi_frame **p)
> +{
> +	int i = 0;
> +	struct gic_msi_frame_handle *m;
> +
> +	if (index >= acpi_num_msi)
> +		return -EINVAL;
> +
> +	list_for_each_entry(m, &msi_frame_list, list) {
> +		if (i == index)
> +			break;
> +		i++;
> +	}
> +
> +	if (i == acpi_num_msi)
> +		return -EINVAL;
> +
> +	*p = &(m->frame);
> +	return  0;
> +}
> +
> +/*
> + * GIC ITS parsing stuff
> + */
> +inline int acpi_gic_get_num_its(void)
> +{
> +	return acpi_num_its;
> +}
> +
> +static int __init
> +acpi_parse_madt_its(struct acpi_subtable_header *header,
> +		    const unsigned long end)
> +{
> +	struct gic_its_handle *h;
> +	struct acpi_madt_generic_translator *trans;
> +
> +	trans = (struct acpi_madt_generic_translator *)header;
> +	if (BAD_MADT_ENTRY(trans, end))
> +		return -EINVAL;
> +
> +	h = kzalloc(sizeof(struct gic_its_handle *), GFP_KERNEL);
> +	if (!h)
> +		return -ENOMEM;
> +
> +	memcpy(&h->trans, trans, sizeof(struct acpi_madt_generic_translator));
> +
> +	list_add(&h->list, &its_list);
> +
> +	return 0;
> +}
> +
> +int __init acpi_gic_madt_gic_its_init(struct acpi_table_header *table)
> +{
> +	int ret = 0;
> +
> +	if (acpi_num_its > 0)
> +		return ret;
> +
> +	ret = acpi_parse_entries(ACPI_SIG_MADT,
> +				 sizeof(struct acpi_table_madt),
> +				 acpi_parse_madt_its, table,
> +				 ACPI_MADT_TYPE_GENERIC_TRANSLATOR, 0);
> +	if (ret == 0) {
> +		pr_debug("No valid ACPI GIC ITS exist\n");
> +		return ret;
> +	}
> +
> +	acpi_num_its = ret;
> +	return 0;
> +}
> +
> +int acpi_gic_get_its(int index, struct acpi_madt_generic_translator **p)
> +{
> +	int i = 0;
> +	struct gic_its_handle *m;
> +
> +	if (index >= acpi_num_its)
> +		return -EINVAL;
> +
> +	list_for_each_entry(m, &its_list, list) {
> +		if (i == index)
> +			break;
> +		i++;
> +	}
> +
> +	if (i == acpi_num_its)
> +		return -EINVAL;
> +
> +	*p = &(m->trans);
> +	return  0;
> +}
> +
> +static void *acpi_gic_msi_token(struct device *dev)
> +{
> +	int err;
> +	struct acpi_madt_generic_msi_frame *msi;
> +
> +	/**
> +	* Since ACPI 5.1 currently does not define
> +	* a way to associate MSI frame ID to a device,
> +	* we can only support single MSI frame (index 0)
> +	* at the moment.
> +	*/
> +	err = acpi_gic_get_msi_frame(0, &msi);
> +	if (err)
> +		return NULL;
> +
> +	return (void *) msi->base_address;
> +}
> +
> +static void *acpi_gic_its_token(struct device *dev)
> +{
> +	int err;
> +	struct acpi_madt_generic_translator *trans;
> +	int its_id = 0;
> +
> +	/**
> +	 * TODO: We need a way to retrieve GIC ITS ID from
> +	 * struct device pointer (in this case, the device
> +	 * would be the PCI host controller.
> +	 *
> +	 * This would be done by the IORT-related code.
> +	 *
> +	 * its_id = get_its_id(dev);
> +	 */
> +
> +	err = acpi_gic_get_its(its_id, &trans);
> +	if (err)
> +		return NULL;
> +
> +	return (void *) trans->base_address;
> +}
> +
> +void *acpi_gic_get_msi_token(struct device *dev)
> +{
> +	void *token = acpi_gic_msi_token(dev);
> +
> +	if (!token)
> +		token = acpi_gic_its_token(dev);
> +
> +	return token;
> +}
> diff --git a/include/acpi/acpi_gic.h b/include/acpi/acpi_gic.h
> new file mode 100644
> index 0000000..34fa475
> --- /dev/null
> +++ b/include/acpi/acpi_gic.h
> @@ -0,0 +1,23 @@
> +/*
> + *  include/acpi/acpi_gic.h
> + *
> + * Copyright (C) 2015 Advanced Micro Devices, Inc.
> + * Authors: Suravee Suthikulpanit <suravee.suthikulpanit at amd.com>
> + */
> +
> +#ifndef __ACPI_GIC_H__
> +#define __ACPI_GIC_H__
> +
> +#ifdef CONFIG_ACPI
> +int acpi_gic_get_num_msi_frame(void);
> +int acpi_gic_msi_init(struct acpi_table_header *table);
> +int acpi_gic_get_msi_frame(int index, struct acpi_madt_generic_msi_frame **p);
> +
> +int acpi_gic_get_num_its(void);
> +int acpi_gic_its_init(struct acpi_table_header *table);
> +int acpi_gic_get_its(int index, struct acpi_madt_generic_translator **p);
> +
> +void *acpi_gic_get_msi_token(struct device *dev);
> +#endif
> +
> +#endif /*__ACPI_GIC_H__*/
> diff --git a/include/linux/acpi.h b/include/linux/acpi.h
> index 04dd0bb..5d58b61 100644
> --- a/include/linux/acpi.h
> +++ b/include/linux/acpi.h
> @@ -44,6 +44,7 @@
>  
>  #include <acpi/acpi_bus.h>
>  #include <acpi/acpi_drivers.h>
> +#include <acpi/acpi_gic.h>

Ah! No.

>  #include <acpi/acpi_numa.h>
>  #include <acpi/acpi_io.h>
>  #include <asm/acpi.h>
> 

Right. Very little of what is above belongs to the ACPI layer. What
would belong here is a generic acpi_get_msi_domain_token(dev) that would
call into a controller-specific function to parse the various tables and
find out which GICv2m frame (or which ITS) is serving the given device.
This would include parsing of the IORT structures if they are available.

For GICv2m, it should be simplistic: just return the domain_token of the
v2m widget. For the ITS, it is slightly more complex, and there should
be some specific backend for that. There is no ACPI support for the ITS
yet, so that shouldn't be your concern at this point in time.

Overall, drivers/acpi should be hardware agnostic (or at least aim for
it), just like drivers/of is.

Thanks,

	M.
-- 
Jazz is not dead. It just smells funny...


From skarajga at visteon.com  Tue Aug  4 07:02:55 2015
From: skarajga at visteon.com (Karajgaonkar, Saurabh (S.))
Date: Tue, 4 Aug 2015 14:02:55 +0000
Subject: [PATCH v2 4/9] usb: host: ehci-st: Simplify return statement
In-Reply-To: <cover.1438695318.git.skarajga@visteon.com>
References: <cover.1438695318.git.skarajga@visteon.com>
Message-ID: <29a173be5ace786d064ae14c02324fee42fee06c.1438695318.git.skarajga@visteon.com>

From: Saurabh Karajgaonkar <skarajga at visteon.com>

Replace redundant variable use in return statement.

Signed-off-by: Saurabh Karajgaonkar <skarajga at visteon.com>
---
 drivers/usb/host/ehci-st.c | 7 +------
 1 file changed, 1 insertion(+), 6 deletions(-)

diff --git a/drivers/usb/host/ehci-st.c b/drivers/usb/host/ehci-st.c
index 7e4bd39..b7c5cfa 100644
--- a/drivers/usb/host/ehci-st.c
+++ b/drivers/usb/host/ehci-st.c
@@ -54,7 +54,6 @@ static int st_ehci_platform_reset(struct usb_hcd *hcd)
 	struct platform_device *pdev = to_platform_device(hcd->self.controller);
 	struct usb_ehci_pdata *pdata = dev_get_platdata(&pdev->dev);
 	struct ehci_hcd *ehci = hcd_to_ehci(hcd);
-	int retval;
 	u32 threshold;
 
 	/* Set EHCI packet buffer IN/OUT threshold to 128 bytes */
@@ -62,11 +61,7 @@ static int st_ehci_platform_reset(struct usb_hcd *hcd)
 	writel(threshold, hcd->regs + AHB2STBUS_INSREG01);
 
 	ehci->caps = hcd->regs + pdata->caps_offset;
-	retval = ehci_setup(hcd);
-	if (retval)
-		return retval;
-
-	return 0;
+	return ehci_setup(hcd);
 }
 
 static int st_ehci_platform_power_on(struct platform_device *dev)
-- 
1.9.1


From skarajga at visteon.com  Tue Aug  4 07:03:20 2015
From: skarajga at visteon.com (Karajgaonkar, Saurabh (S.))
Date: Tue, 4 Aug 2015 14:03:20 +0000
Subject: [PATCH v2 5/9] usb: host: oxu210hp-hcd: Simplify return statement
In-Reply-To: <cover.1438695318.git.skarajga@visteon.com>
References: <cover.1438695318.git.skarajga@visteon.com>
Message-ID: <36c30f52509df9691c70ce6a2b2d0404d50681e9.1438695318.git.skarajga@visteon.com>

From: Saurabh Karajgaonkar <skarajga at visteon.com>

Replace redundant variable use in return statement.

Signed-off-by: Saurabh Karajgaonkar <skarajga at visteon.com>
---
 drivers/usb/host/oxu210hp-hcd.c | 7 +------
 1 file changed, 1 insertion(+), 6 deletions(-)

diff --git a/drivers/usb/host/oxu210hp-hcd.c b/drivers/usb/host/oxu210hp-hcd.c
index 6352f54..fe3bd1c 100644
--- a/drivers/usb/host/oxu210hp-hcd.c
+++ b/drivers/usb/host/oxu210hp-hcd.c
@@ -2670,7 +2670,6 @@ static int oxu_hcd_init(struct usb_hcd *hcd)
 static int oxu_reset(struct usb_hcd *hcd)
 {
 	struct oxu_hcd *oxu = hcd_to_oxu(hcd);
-	int ret;
 
 	spin_lock_init(&oxu->mem_lock);
 	INIT_LIST_HEAD(&oxu->urb_list);
@@ -2696,11 +2695,7 @@ static int oxu_reset(struct usb_hcd *hcd)
 	oxu->hcs_params = readl(&oxu->caps->hcs_params);
 	oxu->sbrn = 0x20;
 
-	ret = oxu_hcd_init(hcd);
-	if (ret)
-		return ret;
-
-	return 0;
+	return oxu_hcd_init(hcd);
 }
 
 static int oxu_run(struct usb_hcd *hcd)
-- 
1.9.1


From skarajga at visteon.com  Tue Aug  4 07:03:45 2015
From: skarajga at visteon.com (Karajgaonkar, Saurabh (S.))
Date: Tue, 4 Aug 2015 14:03:45 +0000
Subject: [PATCH v2 6/9] usb: host: u132-hcd: Simplify return statement
In-Reply-To: <cover.1438695318.git.skarajga@visteon.com>
References: <cover.1438695318.git.skarajga@visteon.com>
Message-ID: <eeeaffff0d32c65c58755078f4a5899763ebb144.1438695318.git.skarajga@visteon.com>

From: Saurabh Karajgaonkar <skarajga at visteon.com>

Replace redundant variable use in return statement.

Signed-off-by: Saurabh Karajgaonkar <skarajga at visteon.com>
---
 drivers/usb/host/u132-hcd.c | 35 +++++++++--------------------------
 1 file changed, 9 insertions(+), 26 deletions(-)

diff --git a/drivers/usb/host/u132-hcd.c b/drivers/usb/host/u132-hcd.c
index d516877..a67bd50 100644
--- a/drivers/usb/host/u132-hcd.c
+++ b/drivers/usb/host/u132-hcd.c
@@ -1542,11 +1542,8 @@ static int u132_periodic_reinit(struct u132 *u132)
 		(fit ^ FIT) | u132->hc_fminterval);
 	if (retval)
 		return retval;
-	retval = u132_write_pcimem(u132, periodicstart,
-		((9 * fi) / 10) & 0x3fff);
-	if (retval)
-		return retval;
-	return 0;
+	return u132_write_pcimem(u132, periodicstart,
+	       ((9 * fi) / 10) & 0x3fff);
 }
 
 static char *hcfs2string(int state)
@@ -2701,28 +2698,18 @@ static int u132_roothub_setportfeature(struct u132 *u132, u16 wValue,
 	if (wIndex == 0 || wIndex > u132->num_ports) {
 		return -EINVAL;
 	} else {
-		int retval;
 		int port_index = wIndex - 1;
 		struct u132_port *port = &u132->port[port_index];
 		port->Status &= ~(1 << wValue);
 		switch (wValue) {
 		case USB_PORT_FEAT_SUSPEND:
-			retval = u132_write_pcimem(u132,
-				roothub.portstatus[port_index], RH_PS_PSS);
-			if (retval)
-				return retval;
-			return 0;
+			return u132_write_pcimem(u132,
+			       roothub.portstatus[port_index], RH_PS_PSS);
 		case USB_PORT_FEAT_POWER:
-			retval = u132_write_pcimem(u132,
-				roothub.portstatus[port_index], RH_PS_PPS);
-			if (retval)
-				return retval;
-			return 0;
+			return u132_write_pcimem(u132,
+			       roothub.portstatus[port_index], RH_PS_PPS);
 		case USB_PORT_FEAT_RESET:
-			retval = u132_roothub_portreset(u132, port_index);
-			if (retval)
-				return retval;
-			return 0;
+			return u132_roothub_portreset(u132, port_index);
 		default:
 			return -EPIPE;
 		}
@@ -2737,7 +2724,6 @@ static int u132_roothub_clearportfeature(struct u132 *u132, u16 wValue,
 	} else {
 		int port_index = wIndex - 1;
 		u32 temp;
-		int retval;
 		struct u132_port *port = &u132->port[port_index];
 		port->Status &= ~(1 << wValue);
 		switch (wValue) {
@@ -2773,11 +2759,8 @@ static int u132_roothub_clearportfeature(struct u132 *u132, u16 wValue,
 		default:
 			return -EPIPE;
 		}
-		retval = u132_write_pcimem(u132, roothub.portstatus[port_index],
-			 temp);
-		if (retval)
-			return retval;
-		return 0;
+		return u132_write_pcimem(u132, roothub.portstatus[port_index],
+		       temp);
 	}
 }
 
-- 
1.9.1


From skarajga at visteon.com  Tue Aug  4 07:04:09 2015
From: skarajga at visteon.com (Karajgaonkar, Saurabh (S.))
Date: Tue, 4 Aug 2015 14:04:09 +0000
Subject: [PATCH v2 7/9] usb: host: xhci: Simplify return statement
In-Reply-To: <cover.1438695318.git.skarajga@visteon.com>
References: <cover.1438695318.git.skarajga@visteon.com>
Message-ID: <894a5080c493f04e059bc159fd5e2d0cf491fd71.1438695318.git.skarajga@visteon.com>

From: Saurabh Karajgaonkar <skarajga at visteon.com>

Replace redundant variable use in return statement.

Signed-off-by: Saurabh Karajgaonkar <skarajga at visteon.com>
---
 drivers/usb/host/xhci.c | 6 +-----
 1 file changed, 1 insertion(+), 5 deletions(-)

diff --git a/drivers/usb/host/xhci.c b/drivers/usb/host/xhci.c
index 526ebc0..19076fa 100644
--- a/drivers/usb/host/xhci.c
+++ b/drivers/usb/host/xhci.c
@@ -4678,7 +4678,6 @@ int xhci_disable_usb3_lpm_timeout(struct usb_hcd *hcd,
 {
 	struct xhci_hcd	*xhci;
 	u16 mel;
-	int ret;
 
 	xhci = hcd_to_xhci(hcd);
 	if (!xhci || !(xhci->quirks & XHCI_LPM_SUPPORT) ||
@@ -4686,10 +4685,7 @@ int xhci_disable_usb3_lpm_timeout(struct usb_hcd *hcd,
 		return 0;
 
 	mel = calculate_max_exit_latency(udev, state, USB3_LPM_DISABLED);
-	ret = xhci_change_max_exit_latency(xhci, udev, mel);
-	if (ret)
-		return ret;
-	return 0;
+	return xhci_change_max_exit_latency(xhci, udev, mel);
 }
 #else /* CONFIG_PM */
 
-- 
1.9.1


From skarajga at visteon.com  Tue Aug  4 07:04:35 2015
From: skarajga at visteon.com (Karajgaonkar, Saurabh (S.))
Date: Tue, 4 Aug 2015 14:04:35 +0000
Subject: [PATCH v2 8/9] usb: serial: mxuport: Simplify return statement
In-Reply-To: <cover.1438695318.git.skarajga@visteon.com>
References: <cover.1438695318.git.skarajga@visteon.com>
Message-ID: <05a5da593419a88886b1e75a0135d7b051b4bb76.1438695318.git.skarajga@visteon.com>

From: Saurabh Karajgaonkar <skarajga at visteon.com>

Replace redundant variable use in return statement.

Signed-off-by: Saurabh Karajgaonkar <skarajga at visteon.com>
---
 drivers/usb/serial/mxuport.c | 10 +++-------
 1 file changed, 3 insertions(+), 7 deletions(-)

diff --git a/drivers/usb/serial/mxuport.c b/drivers/usb/serial/mxuport.c
index 460a406..31a8b47 100644
--- a/drivers/usb/serial/mxuport.c
+++ b/drivers/usb/serial/mxuport.c
@@ -1137,13 +1137,9 @@ static int mxuport_port_probe(struct usb_serial_port *port)
 		return err;
 
 	/* Set interface (RS-232) */
-	err = mxuport_send_ctrl_urb(serial, RQ_VENDOR_SET_INTERFACE,
-				    MX_INT_RS232,
-				    port->port_number);
-	if (err)
-		return err;
-
-	return 0;
+	return mxuport_send_ctrl_urb(serial, RQ_VENDOR_SET_INTERFACE,
+				     MX_INT_RS232,
+				     port->port_number);
 }
 
 static int mxuport_alloc_write_urb(struct usb_serial *serial,
-- 
1.9.1


From skarajga at visteon.com  Tue Aug  4 07:05:03 2015
From: skarajga at visteon.com (Karajgaonkar, Saurabh (S.))
Date: Tue, 4 Aug 2015 14:05:03 +0000
Subject: [PATCH v2 9/9] usb: misc: ftdi-elan: Simplify return statement
In-Reply-To: <cover.1438695318.git.skarajga@visteon.com>
References: <cover.1438695318.git.skarajga@visteon.com>
Message-ID: <f700d830ae520cbf953f9ba76202eb592af3bb81.1438695318.git.skarajga@visteon.com>

From: Saurabh Karajgaonkar <skarajga at visteon.com>

Replace redundant variable use in return statement.

Signed-off-by: Saurabh Karajgaonkar <skarajga at visteon.com>
---
 drivers/usb/misc/ftdi-elan.c | 12 ++----------
 1 file changed, 2 insertions(+), 10 deletions(-)

diff --git a/drivers/usb/misc/ftdi-elan.c b/drivers/usb/misc/ftdi-elan.c
index 8ab1f8f..52c27ca 100644
--- a/drivers/usb/misc/ftdi-elan.c
+++ b/drivers/usb/misc/ftdi-elan.c
@@ -2568,11 +2568,7 @@ static int ftdi_elan_close_controller(struct usb_ftdi *ftdi, int fn)
 					    0x00);
 	if (UxxxStatus)
 		return UxxxStatus;
-	UxxxStatus = ftdi_elan_read_config(ftdi, activePCIfn | reg, 0,
-					   &pcidata);
-	if (UxxxStatus)
-		return UxxxStatus;
-	return 0;
+	return ftdi_elan_read_config(ftdi, activePCIfn | reg, 0, &pcidata);
 }
 
 static int ftdi_elan_found_controller(struct usb_ftdi *ftdi, int fn, int quirk)
@@ -2695,11 +2691,7 @@ static int ftdi_elan_setupOHCI(struct usb_ftdi *ftdi)
 		}
 	}
 	if (ftdi->function > 0) {
-		UxxxStatus = ftdi_elan_setup_controller(ftdi,
-							ftdi->function - 1);
-		if (UxxxStatus)
-			return UxxxStatus;
-		return 0;
+		return ftdi_elan_setup_controller(ftdi,	ftdi->function - 1);
 	} else if (controllers > 0) {
 		return -ENXIO;
 	} else if (unrecognized > 0) {
-- 
1.9.1


From marc.zyngier at arm.com  Tue Aug  4 07:04:53 2015
From: marc.zyngier at arm.com (Marc Zyngier)
Date: Tue, 04 Aug 2015 15:04:53 +0100
Subject: [PATCH v4 09/10] PCI: ACPI: Bind GIC MSI frame to PCI host bridge
In-Reply-To: <1438164539-29256-10-git-send-email-hanjun.guo@linaro.org>
References: <1438164539-29256-1-git-send-email-hanjun.guo@linaro.org>
 <1438164539-29256-10-git-send-email-hanjun.guo@linaro.org>
Message-ID: <55C0C685.4000400@arm.com>

On 29/07/15 11:08, Hanjun Guo wrote:
> From: Suravee Suthikulpanit <Suravee.Suthikulpanit at amd.com>
> 
> This patch introduces pci_host_bridge_acpi_msi_domain(), which queries
> a GIC MSI irq-domain token and use it to retrieve an irq_domain with
> DOMAIN_BUS_PCI_MSI bus type, and bind it to PCI host-bridge.
> 
> Signed-off-by: Suravee Suthikulpanit <Suravee.Suthikulpanit at amd.com>
> Signed-off-by: Hanjun Guo <hanjun.guo at linaro.org>
> ---
>  drivers/pci/pci-acpi.c   | 18 ++++++++++++++++++
>  drivers/pci/probe.c      |  3 +++
>  include/linux/pci-acpi.h |  4 ++++
>  3 files changed, 25 insertions(+)
> 
> diff --git a/drivers/pci/pci-acpi.c b/drivers/pci/pci-acpi.c
> index 314a625..5f11653 100644
> --- a/drivers/pci/pci-acpi.c
> +++ b/drivers/pci/pci-acpi.c
> @@ -9,6 +9,7 @@
>  
>  #include <linux/delay.h>
>  #include <linux/init.h>
> +#include <linux/irqdomain.h>
>  #include <linux/pci.h>
>  #include <linux/pci_hotplug.h>
>  #include <linux/module.h>
> @@ -16,6 +17,7 @@
>  #include <linux/pci-acpi.h>
>  #include <linux/pm_runtime.h>
>  #include <linux/pm_qos.h>
> +#include <acpi/acpi_gic.h>
>  #include "pci.h"
>  
>  /*
> @@ -681,6 +683,22 @@ static bool pci_acpi_bus_match(struct device *dev)
>  	return dev_is_pci(dev);
>  }
>  
> +#ifdef CONFIG_GENERIC_MSI_IRQ_DOMAIN
> +struct irq_domain *pci_host_bridge_acpi_msi_domain(struct pci_bus *bus)
> +{
> +	struct irq_domain *d = NULL;
> +	void *token = acpi_gic_get_msi_token(&bus->dev);

Do you see why I positively *hate* having hardware details in generic
layers? They propagate everywhere...

> +
> +	if (token)
> +		d = irq_find_matching_host(token, DOMAIN_BUS_PCI_MSI);
> +
> +	if (!d)
> +		pr_debug("Fail to find domain for MSI\n");
> +
> +	return d;
> +}
> +#endif /*CONFIG_GENERIC_MSI_IRQ_DOMAIN*/
> +
>  static struct acpi_bus_type acpi_pci_bus = {
>  	.name = "PCI",
>  	.match = pci_acpi_bus_match,
> diff --git a/drivers/pci/probe.c b/drivers/pci/probe.c
> index a7afeac..8c1204c 100644
> --- a/drivers/pci/probe.c
> +++ b/drivers/pci/probe.c
> @@ -12,6 +12,7 @@
>  #include <linux/module.h>
>  #include <linux/cpumask.h>
>  #include <linux/pci-aspm.h>
> +#include <linux/pci-acpi.h>
>  #include <asm-generic/pci-bridge.h>
>  #include "pci.h"
>  
> @@ -670,6 +671,8 @@ static struct irq_domain *pci_host_bridge_msi_domain(struct pci_bus *bus)
>  	 * should be called from here.
>  	 */
>  	d = pci_host_bridge_of_msi_domain(bus);
> +	if (!d)
> +		d = pci_host_bridge_acpi_msi_domain(bus);
>  
>  	return d;
>  }
> diff --git a/include/linux/pci-acpi.h b/include/linux/pci-acpi.h
> index a965efa..766d045 100644
> --- a/include/linux/pci-acpi.h
> +++ b/include/linux/pci-acpi.h
> @@ -77,6 +77,8 @@ static inline void acpiphp_remove_slots(struct pci_bus *bus) { }
>  static inline void acpiphp_check_host_bridge(struct acpi_device *adev) { }
>  #endif
>  
> +struct irq_domain *pci_host_bridge_acpi_msi_domain(struct pci_bus *bus);
> +
>  extern const u8 pci_acpi_dsm_uuid[];
>  #define DEVICE_LABEL_DSM	0x07
>  #define RESET_DELAY_DSM		0x08
> @@ -85,6 +87,8 @@ extern const u8 pci_acpi_dsm_uuid[];
>  #else	/* CONFIG_ACPI */
>  static inline void acpi_pci_add_bus(struct pci_bus *bus) { }
>  static inline void acpi_pci_remove_bus(struct pci_bus *bus) { }
> +static inline struct irq_domain *
> +pci_host_bridge_acpi_msi_domain(struct pci_bus *bus) { return NULL; }
>  #endif	/* CONFIG_ACPI */
>  
>  #ifdef CONFIG_ACPI_APEI
> 

Once you solve the HW abstraction issue, this will be OK.

Thanks,

	M.
-- 
Jazz is not dead. It just smells funny...


From soren.brinkmann at xilinx.com  Tue Aug  4 07:11:45 2015
From: soren.brinkmann at xilinx.com (=?utf-8?B?U8O2cmVu?= Brinkmann)
Date: Tue, 4 Aug 2015 07:11:45 -0700
Subject: [RFCv3 4/4] ARM: zynq: Select ARCH_HAS_RESET_CONTROLLER
In-Reply-To: <1438677481.3793.22.camel@pengutronix.de>
References: <1438305237-18497-1-git-send-email-moritz.fischer@ettus.com>
 <1438305237-18497-5-git-send-email-moritz.fischer@ettus.com>
 <55BB2D39.6000004@xilinx.com>
 <20150731164707.GF2650@xsjsorenbubuntu>
 <1438677481.3793.22.camel@pengutronix.de>
Message-ID: <20150804141145.GH2650@xsjsorenbubuntu>

Hi Philipp,

On Tue, 2015-08-04 at 10:38AM +0200, Philipp Zabel wrote:
> Hi,
> 
> Am Freitag, den 31.07.2015, 09:47 -0700 schrieb S?ren Brinkmann:
> > On Fri, 2015-07-31 at 10:09AM +0200, Michal Simek wrote:
> [...]
> > > Reviewed-by: Michal Simek <michal.simek at xilinx.com>
> > Acked-by: S?ren Brinkmann <soren.brinkmann at xilinx.com>
> 
> I'll assume these apply to the whole series and queue patches 1 and 3.

For me, yes, that was meant for the whole series. Sorry, for not making
that obvious.

	Thanks,
	S?ren


From laurent.pinchart at ideasonboard.com  Tue Aug  4 07:19:57 2015
From: laurent.pinchart at ideasonboard.com (Laurent Pinchart)
Date: Tue, 04 Aug 2015 17:19:57 +0300
Subject: [PATCH v2 6/6] pinctrl: sh-pfc: Confine legacy function GPIOs to
 SH
In-Reply-To: <1438696519-13727-7-git-send-email-geert+renesas@glider.be>
References: <1438696519-13727-1-git-send-email-geert+renesas@glider.be>
 <1438696519-13727-7-git-send-email-geert+renesas@glider.be>
Message-ID: <2553252.oFXfDSh3t2@avalon>

Hi Geert,

Thank you for the patch.

On Tuesday 04 August 2015 15:55:19 Geert Uytterhoeven wrote:
> Legacy function GPIOs are no longer used on ARM since commit
> a27c5cd1a08cc95c ("sh-pfc: sh73a0: Remove function GPIOs").
> Extract its setup code into a separate function, and make all function
> GPIO related code and data depend on CONFIG_SUPERH.
> 
> Signed-off-by: Geert Uytterhoeven <geert+renesas at glider.be>
> Acked-by: Linus Walleij <linus.walleij at linaro.org>

Acked-by: Laurent Pinchart <laurent.pinchart at ideasonboard.com>

We now need a volunteer to port SH to proper pinctrl to remove the function 
GPIOs completely :-)

> ---
> Compile-tested on sh using se7724_defconfig.
> 
> v2:
>   - Add Acked-by,
>   - #ifdef out the code instead of introducing helper and dummy
>     functions.
> ---
>  drivers/pinctrl/sh-pfc/core.h   | 2 ++
>  drivers/pinctrl/sh-pfc/gpio.c   | 7 ++++++-
>  drivers/pinctrl/sh-pfc/sh_pfc.h | 2 ++
>  3 files changed, 10 insertions(+), 1 deletion(-)
> 
> diff --git a/drivers/pinctrl/sh-pfc/core.h b/drivers/pinctrl/sh-pfc/core.h
> index 4c3c37bf7161804d..c38ace46d7111b0d 100644
> --- a/drivers/pinctrl/sh-pfc/core.h
> +++ b/drivers/pinctrl/sh-pfc/core.h
> @@ -46,7 +46,9 @@ struct sh_pfc {
>  	unsigned int nr_gpio_pins;
> 
>  	struct sh_pfc_chip *gpio;
> +#ifdef CONFIG_SUPERH
>  	struct sh_pfc_chip *func;
> +#endif
> 
>  	struct sh_pfc_pinctrl *pinctrl;
>  };
> diff --git a/drivers/pinctrl/sh-pfc/gpio.c b/drivers/pinctrl/sh-pfc/gpio.c
> index e46439030914ad13..685b3c24627daf03 100644
> --- a/drivers/pinctrl/sh-pfc/gpio.c
> +++ b/drivers/pinctrl/sh-pfc/gpio.c
> @@ -261,6 +261,7 @@ static int gpio_pin_setup(struct sh_pfc_chip *chip)
>   * Function GPIOs
>   */
> 
> +#ifdef CONFIG_SUPERH
>  static int gpio_function_request(struct gpio_chip *gc, unsigned offset)
>  {
>  	static bool __print_once;
> @@ -300,6 +301,7 @@ static int gpio_function_setup(struct sh_pfc_chip *chip)
> 
>  	return 0;
>  }
> +#endif
> 
>  /*
> ---------------------------------------------------------------------------
> -- * Register/unregister
> @@ -399,6 +401,7 @@ int sh_pfc_register_gpiochip(struct sh_pfc *pfc)
>  		}
>  	}
> 
> +#ifdef CONFIG_SUPERH
>  	/* Register the function GPIOs chip. */
>  	if (pfc->info->nr_func_gpios == 0)
>  		return 0;
> @@ -408,6 +411,7 @@ int sh_pfc_register_gpiochip(struct sh_pfc *pfc)
>  		return PTR_ERR(chip);
> 
>  	pfc->func = chip;
> +#endif /* CONFIG_SUPERH */
> 
>  	return 0;
>  }
> @@ -415,7 +419,8 @@ int sh_pfc_register_gpiochip(struct sh_pfc *pfc)
>  int sh_pfc_unregister_gpiochip(struct sh_pfc *pfc)
>  {
>  	gpiochip_remove(&pfc->gpio->gpio_chip);
> +#ifdef CONFIG_SUPERH
>  	gpiochip_remove(&pfc->func->gpio_chip);
> -
> +#endif
>  	return 0;
>  }
> diff --git a/drivers/pinctrl/sh-pfc/sh_pfc.h
> b/drivers/pinctrl/sh-pfc/sh_pfc.h index 0874cfee6889afa1..1f43bae56065e659
> 100644
> --- a/drivers/pinctrl/sh-pfc/sh_pfc.h
> +++ b/drivers/pinctrl/sh-pfc/sh_pfc.h
> @@ -138,8 +138,10 @@ struct sh_pfc_soc_info {
>  	const struct sh_pfc_function *functions;
>  	unsigned int nr_functions;
> 
> +#ifdef CONFIG_SUPERH
>  	const struct pinmux_func *func_gpios;
>  	unsigned int nr_func_gpios;
> +#endif
> 
>  	const struct pinmux_cfg_reg *cfg_regs;
>  	const struct pinmux_data_reg *data_regs;

-- 
Regards,

Laurent Pinchart



From gregory.clement at free-electrons.com  Tue Aug  4 07:23:02 2015
From: gregory.clement at free-electrons.com (Gregory CLEMENT)
Date: Tue, 04 Aug 2015 16:23:02 +0200
Subject: MUSB dual-role on AM335x behaving weirdly
In-Reply-To: <55C0B954.3020106@free-electrons.com>
References: <20150514190429.GT24269@saruman.tx.rr.com>	<CADYTM3Zso8bV_8yFyx1-ATbL5AgkKBjvWWR4AsoZUNuLvFe1bQ@mail.gmail.com>	<20150514192125.GU24269@saruman.tx.rr.com>	<CADYTM3bbEAVefFZtivJf5Z+2Q+1zDZEvNhqE5ytsOxDX7hjbdA@mail.gmail.com>	<20150514192946.GV24269@saruman.tx.rr.com>	<CADYTM3Zk2iD8YMj75CoLJn=4kpoXoXEKUWj2QzdXKGCJjtfG2A@mail.gmail.com>	<CADYTM3a1QWnec1D=wT=fgZ-RCXAx_qZYYoFg5gWOy0yT4vovHA@mail.gmail.com>	<20150514212653.GC3338@piout.net>	<CADYTM3baVqoEBdWoQb5JFyGR2_GKm1FHMYWST1YkZV=m=ZdycQ@mail.gmail.com>	<20150526145118.GD26599@saruman.tx.rr.com>	<20150527094205.GO3199@piout.net>	<5594E56B.3040200@free-electrons.com>
 <CADYTM3ZF5m++N1NqmOJoH5agbYrzpvSbLnuLVgttxwzdzwmGwQ@mail.gmail.com>
 <55C0B954.3020106@free-electrons.com>
Message-ID: <55C0CAC6.3020603@free-electrons.com>

Hi again,
On 04/08/2015 15:08, Gregory CLEMENT wrote:
> Hi Bin,
> 
> On 02/07/2015 19:05, Bin Liu wrote:
>> Hi,
>>
>> On Thu, Jul 2, 2015 at 2:16 AM, Gregory CLEMENT
>> <gregory.clement at free-electrons.com> wrote:
>>> Hi Felipe,
>>>
>>> On 27/05/2015 11:42, Alexandre Belloni wrote:
>>>> Hi,
>>>>
>>>> On 26/05/2015 at 09:51:18 -0500, Felipe Balbi wrote :
>>>>> On Thu, May 14, 2015 at 04:36:33PM -0500, Bin Liu wrote:
>>>>>> Alexandre,
>>>>>>
>>>>>> On Thu, May 14, 2015 at 4:26 PM, Alexandre Belloni
>>>>>> <alexandre.belloni at free-electrons.com> wrote:
>>>>>>> On 14/05/2015 at 16:16:12 -0500, Bin Liu wrote :
>>>>>>>> I think I found the root cause of the problem: board design issue - I
>>>>>>>> bet the custom board has too much cap on VBUS line. It should be <
>>>>>>>> 10uF.
>>>>>>>>
>>>>>>>
>>>>>>> We have a custom board that exhibits the issue but it only has a 100nF
>>>>>>> cap on VBUS.
>>>>>>
>>>>>> Have you measured the VBUS discharging? Is there any way to share your
>>>>>> schematics?
>>>>>
>>>>> Alexandre, any further comments ?
>>>>>
>>>>
>>>> Yeah, I have just got more info.
>>>>
>>>> This is the relevant part of the schematic:
>>>> http://free-electrons.com/~alexandre/usb.png
>>>>
>>>> The total VBUS capacitance is 200nF and the USB0 pins are connected
>>>> directly to the AM3358 pins. U1 is actually not fitted.
>>>>
>>>> We didn't measure VBUS discharging but we observe the OTG pin sensing
>>>> stops when plugging an OTG cable without any device.
>>>
>>> Do you have any news about this topic?
>>>
>>>
>>> Is there something else that we can do to help solving this issue?
>>
>> In the case of CONFIG_USB_MUSB_DUAL_ROLE=y and dr_mode=otg, how is the
>> gadget driver configured? It has to be a module not built-in.
> 
> Indeed when I configured CONFIG_USB_MUSB_HDRC=m and CONFIG_USB_MUSB_DSPS=m
> it worked seamless.
> 

Actually it didn't worked. And now sometimes I even received continuously
the following message:

 musb_bus_suspend 2484: trying to suspend as a_wait_vfall while active

Gregory


-- 
Gregory Clement, Free Electrons
Kernel, drivers, real-time and embedded Linux
development, consulting, training and support.
http://free-electrons.com


From marc.zyngier at arm.com  Tue Aug  4 07:23:00 2015
From: marc.zyngier at arm.com (Marc Zyngier)
Date: Tue, 04 Aug 2015 15:23:00 +0100
Subject: [PATCH v4 10/10] irqchip / gicv2m: Introducing gicv2m_acpi_init()
In-Reply-To: <1438164539-29256-11-git-send-email-hanjun.guo@linaro.org>
References: <1438164539-29256-1-git-send-email-hanjun.guo@linaro.org>
 <1438164539-29256-11-git-send-email-hanjun.guo@linaro.org>
Message-ID: <55C0CAC4.3010202@arm.com>

On 29/07/15 11:08, Hanjun Guo wrote:
> From: Suravee Suthikulpanit <Suravee.Suthikulpanit at amd.com>
> 
> This patch introduces gicv2m_acpi_init(), which uses information
> in MADT GIC MSI frames structure to initialize GICv2m driver.
> It also refactors gicv2m_init_one() to handle both DT and ACPI
> initialization path.
> 
> Signed-off-by: Suravee Suthikulpanit <Suravee.Suthikulpanit at amd.com>
> Signed-off-by: Hanjun Guo <hanjun.guo at linaro.org>
> ---
>  drivers/irqchip/irq-gic-v2m.c   | 111 +++++++++++++++++++++++++++++++---------
>  drivers/irqchip/irq-gic.c       |   3 ++
>  include/linux/irqchip/arm-gic.h |   7 +++
>  3 files changed, 98 insertions(+), 23 deletions(-)
> 
> diff --git a/drivers/irqchip/irq-gic-v2m.c b/drivers/irqchip/irq-gic-v2m.c
> index d0fcbf8..c491a08 100644
> --- a/drivers/irqchip/irq-gic-v2m.c
> +++ b/drivers/irqchip/irq-gic-v2m.c
> @@ -15,6 +15,7 @@
>  
>  #define pr_fmt(fmt) "GICv2m: " fmt
>  
> +#include <linux/acpi.h>
>  #include <linux/irq.h>
>  #include <linux/irqdomain.h>
>  #include <linux/kernel.h>
> @@ -211,6 +212,10 @@ static bool is_msi_spi_valid(u32 base, u32 num)
>  	return true;
>  }
>  
> +char gicv2m_domain_name[] = "GICV2M";
> +char gicv2m_pci_msi_domain_name[] = "GICV2M-PCI-MSI";
> +char gicv2m_plat_msi_domain_name[] = "GICV2M-PLAT-MSI";
> +

Can't these be static? Why do we need them?

>  static struct irq_chip gicv2m_pmsi_irq_chip = {
>  	.name			= "pMSI",
>  };
> @@ -224,8 +229,9 @@ static struct msi_domain_info gicv2m_pmsi_domain_info = {
>  	.chip	= &gicv2m_pmsi_irq_chip,
>  };
>  
> -static int __init gicv2m_init_one(struct device_node *node,
> -				  struct irq_domain *parent)
> +static int __init gicv2m_init_one(struct irq_domain *parent,
> +				  u32 *spi_start, u32 *nr_spis,
> +				  struct resource *res, void *token)
>  {
>  	int ret;
>  	struct v2m_data *v2m;
> @@ -237,28 +243,22 @@ static int __init gicv2m_init_one(struct device_node *node,
>  		return -ENOMEM;
>  	}
>  
> -	ret = of_address_to_resource(node, 0, &v2m->res);
> -	if (ret) {
> -		pr_err("Failed to allocate v2m resource.\n");
> -		goto err_free_v2m;
> -	}
> -
> -	v2m->base = ioremap(v2m->res.start, resource_size(&v2m->res));
> +	v2m->base = ioremap(res->start, resource_size(res));
>  	if (!v2m->base) {
>  		pr_err("Failed to map GICv2m resource\n");
>  		ret = -ENOMEM;
>  		goto err_free_v2m;
>  	}
> +	memcpy(&v2m->res, res, sizeof(struct resource));
>  
> -	if (!of_property_read_u32(node, "arm,msi-base-spi", &v2m->spi_start) &&
> -	    !of_property_read_u32(node, "arm,msi-num-spis", &v2m->nr_spis)) {
> -		pr_info("Overriding V2M MSI_TYPER (base:%u, num:%u)\n",
> -			v2m->spi_start, v2m->nr_spis);
> +	if (*spi_start && *nr_spis) {
> +		v2m->spi_start = *spi_start;
> +		v2m->nr_spis = *nr_spis;
>  	} else {
>  		u32 typer = readl_relaxed(v2m->base + V2M_MSI_TYPER);
>  
> -		v2m->spi_start = V2M_MSI_TYPER_BASE_SPI(typer);
> -		v2m->nr_spis = V2M_MSI_TYPER_NUM_SPI(typer);
> +		v2m->spi_start = *spi_start = V2M_MSI_TYPER_BASE_SPI(typer);
> +		v2m->nr_spis = *nr_spis = V2M_MSI_TYPER_NUM_SPI(typer);
>  	}
>  
>  	if (!is_msi_spi_valid(v2m->spi_start, v2m->nr_spis)) {
> @@ -273,7 +273,7 @@ static int __init gicv2m_init_one(struct device_node *node,
>  		goto err_iounmap;
>  	}
>  
> -	inner_domain = irq_domain_add_tree(node, &gicv2m_domain_ops, v2m);
> +	inner_domain = irq_domain_add_tree(token, &gicv2m_domain_ops, v2m);
>  	if (!inner_domain) {
>  		pr_err("Failed to create GICv2m domain\n");
>  		ret = -ENOMEM;
> @@ -282,9 +282,11 @@ static int __init gicv2m_init_one(struct device_node *node,
>  
>  	inner_domain->bus_token = DOMAIN_BUS_NEXUS;
>  	inner_domain->parent = parent;
> -	pci_domain = pci_msi_create_irq_domain(node, &gicv2m_msi_domain_info,
> +	inner_domain->name = gicv2m_domain_name;
> +
> +	pci_domain = pci_msi_create_irq_domain(token, &gicv2m_msi_domain_info,
>  					       inner_domain);
> -	plat_domain = platform_msi_create_irq_domain(node,
> +	plat_domain = platform_msi_create_irq_domain(token,
>  						     &gicv2m_pmsi_domain_info,
>  						     inner_domain);
>  	if (!pci_domain || !plat_domain) {
> @@ -293,11 +295,10 @@ static int __init gicv2m_init_one(struct device_node *node,
>  		goto err_free_domains;
>  	}
>  
> -	spin_lock_init(&v2m->msi_cnt_lock);
> +	pci_domain->name = gicv2m_pci_msi_domain_name;
> +	plat_domain->name = gicv2m_plat_msi_domain_name;
>  
> -	pr_info("Node %s: range[%#lx:%#lx], SPI[%d:%d]\n", node->name,
> -		(unsigned long)v2m->res.start, (unsigned long)v2m->res.end,
> -		v2m->spi_start, (v2m->spi_start + v2m->nr_spis));
> +	spin_lock_init(&v2m->msi_cnt_lock);
>  
>  	return 0;
>  
> @@ -329,15 +330,79 @@ int __init gicv2m_of_init(struct device_node *node, struct irq_domain *parent)
>  
>  	for (child = of_find_matching_node(node, gicv2m_device_id); child;
>  	     child = of_find_matching_node(child, gicv2m_device_id)) {
> +		u32 spi_start = 0, nr_spis = 0;
> +		struct resource res;
> +
>  		if (!of_find_property(child, "msi-controller", NULL))
>  			continue;
>  
> -		ret = gicv2m_init_one(child, parent);
> +		ret = of_address_to_resource(child, 0, &res);
> +		if (ret) {
> +			pr_err("Failed to allocate v2m resource.\n");
> +			break;
> +		}
> +
> +		if (!of_property_read_u32(child, "arm,msi-base-spi", &spi_start) &&
> +		    !of_property_read_u32(child, "arm,msi-num-spis", &nr_spis))
> +			pr_info("Overriding V2M MSI_TYPER (base:%u, num:%u)\n",
> +				spi_start, nr_spis);
> +
> +		ret = gicv2m_init_one(parent, &spi_start, &nr_spis, &res,

If these spi_start and nr_spis pointers passed to gicv2m_init_one are
only for the benefit of printing the message below, just move the
message inside the function...

> +				      child);
>  		if (ret) {
>  			of_node_put(node);
>  			break;
>  		}
> +
> +		pr_info("Node %s: range[%#lx:%#lx], SPI[%d:%d]\n", child->name,
> +			(unsigned long)res.start, (unsigned long)res.end,
> +			spi_start, (spi_start + nr_spis));
>  	}
>  
>  	return ret;
>  }
> +
> +#ifdef CONFIG_ACPI
> +int __init gicv2m_acpi_init(struct acpi_table_header *table,
> +			    struct irq_domain *parent)
> +{
> +	int i, ret;
> +
> +	ret = acpi_gic_msi_init(table);
> +	if (ret)
> +		return ret;
> +
> +	for (i = 0; i < acpi_gic_get_num_msi_frame(); i++) {
> +		struct resource res;
> +		u32 spi_start = 0, nr_spis = 0;
> +		struct acpi_madt_generic_msi_frame *m;
> +
> +		ret = acpi_gic_get_msi_frame(i, &m);
> +		if (ret)
> +			return ret;
> +

All of that should be moved here. And we don't need to build an
intermediate representation. Just build the v2m_data structures as you go.

> +		res.start = m->base_address;
> +		res.end = m->base_address + 0x1000;
> +
> +		if (m->flags & ACPI_MADT_OVERRIDE_SPI_VALUES) {
> +			spi_start = m->spi_base;
> +			nr_spis = m->spi_count;
> +
> +			pr_info("ACPI overriding V2M MSI_TYPER (base:%u, num:%u)\n",
> +				spi_start, nr_spis);
> +		}
> +
> +		ret = gicv2m_init_one(parent, &spi_start, &nr_spis, &res,
> +				      (void *)(m->base_address));
> +		if (ret)
> +			break;
> +
> +		pr_info("MSI frame ID %u: range[%#lx:%#lx], SPI[%d:%d]\n",
> +			m->msi_frame_id,
> +			(unsigned long)res.start, (unsigned long)res.end,
> +			spi_start, (spi_start + nr_spis));
> +	}
> +	return ret;
> +}
> +
> +#endif /* CONFIG_ACPI */
> diff --git a/drivers/irqchip/irq-gic.c b/drivers/irqchip/irq-gic.c
> index bec6b00..531ebbc 100644
> --- a/drivers/irqchip/irq-gic.c
> +++ b/drivers/irqchip/irq-gic.c
> @@ -1159,6 +1159,9 @@ gic_v2_acpi_init(struct acpi_table_header *table)
>  	 */
>  	gic_init_bases(0, -1, dist_base, cpu_base, 0, (void *)ACPI_IRQ_MODEL_GIC);
>  
> +	if (IS_ENABLED(CONFIG_ARM_GIC_V2M))
> +		gicv2m_acpi_init(table, gic_data[0].domain);
> +
>  	acpi_set_irq_model(ACPI_IRQ_MODEL_GIC, ACPI_IRQ_MODEL_GIC,
>  			   gic_acpi_gsi_desc_populate);
>  	return 0;
> diff --git a/include/linux/irqchip/arm-gic.h b/include/linux/irqchip/arm-gic.h
> index 97799b7..27d8196 100644
> --- a/include/linux/irqchip/arm-gic.h
> +++ b/include/linux/irqchip/arm-gic.h
> @@ -109,6 +109,13 @@ static inline void gic_init(unsigned int nr, int start,
>  
>  int gicv2m_of_init(struct device_node *node, struct irq_domain *parent);
>  
> +#ifdef CONFIG_ACPI
> +struct acpi_table_header;
> +
> +int gicv2m_acpi_init(struct acpi_table_header *table,
> +		     struct irq_domain *parent);
> +#endif
> +
>  void gic_send_sgi(unsigned int cpu_id, unsigned int irq);
>  int gic_get_cpu_id(unsigned int cpu);
>  void gic_migrate_target(unsigned int new_cpu_id);
> 

This needs rework to do the parsing of the tables in this driver. Just
expose the domain_token through a function that you register with the
ACPI layer.

Thanks,

	M.
-- 
Jazz is not dead. It just smells funny...


From christoffer.dall at linaro.org  Tue Aug  4 06:56:52 2015
From: christoffer.dall at linaro.org (Christoffer Dall)
Date: Tue, 4 Aug 2015 15:56:52 +0200
Subject: [PATCH v3 10/11] KVM: arm/arm64: timer: Allow the timer to
 control the active state
In-Reply-To: <1437753309-17989-11-git-send-email-marc.zyngier@arm.com>
References: <1437753309-17989-1-git-send-email-marc.zyngier@arm.com>
 <1437753309-17989-11-git-send-email-marc.zyngier@arm.com>
Message-ID: <20150804135652.GC29335@cbox>

On Fri, Jul 24, 2015 at 04:55:08PM +0100, Marc Zyngier wrote:
> In order to remove the crude hack where we sneak the masked bit
> into the timer's control register, make use of the phys_irq_map
> API control the active state of the interrupt.
> 
> This causes some limited changes to allow for potential error
> propagation.
> 
> Signed-off-by: Marc Zyngier <marc.zyngier at arm.com>
> ---
>  arch/arm/kvm/reset.c         |  4 +---
>  arch/arm64/kvm/reset.c       |  4 +---
>  include/kvm/arm_arch_timer.h |  7 +++++--
>  virt/kvm/arm/arch_timer.c    | 29 ++++++++++++++++++++++-------
>  4 files changed, 29 insertions(+), 15 deletions(-)
> 
> diff --git a/arch/arm/kvm/reset.c b/arch/arm/kvm/reset.c
> index f558c07..eeb85858 100644
> --- a/arch/arm/kvm/reset.c
> +++ b/arch/arm/kvm/reset.c
> @@ -77,7 +77,5 @@ int kvm_reset_vcpu(struct kvm_vcpu *vcpu)
>  	kvm_reset_coprocs(vcpu);
>  
>  	/* Reset arch_timer context */
> -	kvm_timer_vcpu_reset(vcpu, cpu_vtimer_irq);
> -
> -	return 0;
> +	return kvm_timer_vcpu_reset(vcpu, cpu_vtimer_irq);
>  }
> diff --git a/arch/arm64/kvm/reset.c b/arch/arm64/kvm/reset.c
> index b4af618..91cf535 100644
> --- a/arch/arm64/kvm/reset.c
> +++ b/arch/arm64/kvm/reset.c
> @@ -121,7 +121,5 @@ int kvm_reset_vcpu(struct kvm_vcpu *vcpu)
>  	kvm_reset_sys_regs(vcpu);
>  
>  	/* Reset timer */
> -	kvm_timer_vcpu_reset(vcpu, cpu_vtimer_irq);
> -
> -	return 0;
> +	return kvm_timer_vcpu_reset(vcpu, cpu_vtimer_irq);
>  }
> diff --git a/include/kvm/arm_arch_timer.h b/include/kvm/arm_arch_timer.h
> index e596675..e1e4d7c 100644
> --- a/include/kvm/arm_arch_timer.h
> +++ b/include/kvm/arm_arch_timer.h
> @@ -52,13 +52,16 @@ struct arch_timer_cpu {
>  
>  	/* Timer IRQ */
>  	const struct kvm_irq_level	*irq;
> +
> +	/* VGIC mapping */
> +	struct irq_phys_map		*map;
>  };
>  
>  int kvm_timer_hyp_init(void);
>  void kvm_timer_enable(struct kvm *kvm);
>  void kvm_timer_init(struct kvm *kvm);
> -void kvm_timer_vcpu_reset(struct kvm_vcpu *vcpu,
> -			  const struct kvm_irq_level *irq);
> +int kvm_timer_vcpu_reset(struct kvm_vcpu *vcpu,
> +			 const struct kvm_irq_level *irq);
>  void kvm_timer_vcpu_init(struct kvm_vcpu *vcpu);
>  void kvm_timer_flush_hwstate(struct kvm_vcpu *vcpu);
>  void kvm_timer_sync_hwstate(struct kvm_vcpu *vcpu);
> diff --git a/virt/kvm/arm/arch_timer.c b/virt/kvm/arm/arch_timer.c
> index 98c95f2..76e38d2 100644
> --- a/virt/kvm/arm/arch_timer.c
> +++ b/virt/kvm/arm/arch_timer.c
> @@ -64,10 +64,10 @@ static void kvm_timer_inject_irq(struct kvm_vcpu *vcpu)
>  	int ret;
>  	struct arch_timer_cpu *timer = &vcpu->arch.timer_cpu;
>  
> -	timer->cntv_ctl |= ARCH_TIMER_CTRL_IT_MASK;
> -	ret = kvm_vgic_inject_irq(vcpu->kvm, vcpu->vcpu_id,
> -				  timer->irq->irq,
> -				  timer->irq->level);
> +	kvm_vgic_set_phys_irq_active(timer->map, true);

actually, I'm not sure I understand the point of setting this boolean?
Is it just a check?  It seems everywhere we find the map in the VGIC
code, we have a BUG_ON(!map->active), so why doesn't (!!map) imply that
it should be marked as active?

Is this again for non-shared devices?

> +	ret = kvm_vgic_inject_mapped_irq(vcpu->kvm, vcpu->vcpu_id,
> +					 timer->map,
> +					 timer->irq->level);
>  	WARN_ON(ret);
>  }
>  
> @@ -117,7 +117,8 @@ bool kvm_timer_should_fire(struct kvm_vcpu *vcpu)
>  	cycle_t cval, now;
>  
>  	if ((timer->cntv_ctl & ARCH_TIMER_CTRL_IT_MASK) ||
> -		!(timer->cntv_ctl & ARCH_TIMER_CTRL_ENABLE))
> +	    !(timer->cntv_ctl & ARCH_TIMER_CTRL_ENABLE) ||
> +	    kvm_vgic_get_phys_irq_active(timer->map))

hmm, maybe this answers my question above.  It is the virtual active
state preventing us to keep injecting the virtual side?

I don't see anything functional wrong with this code though.

Thanks,
-Christoffer


>  		return false;
>  
>  	cval = timer->cntv_cval;
> @@ -184,10 +185,11 @@ void kvm_timer_sync_hwstate(struct kvm_vcpu *vcpu)
>  	timer_arm(timer, ns);
>  }
>  
> -void kvm_timer_vcpu_reset(struct kvm_vcpu *vcpu,
> -			  const struct kvm_irq_level *irq)
> +int kvm_timer_vcpu_reset(struct kvm_vcpu *vcpu,
> +			 const struct kvm_irq_level *irq)
>  {
>  	struct arch_timer_cpu *timer = &vcpu->arch.timer_cpu;
> +	struct irq_phys_map *map;
>  
>  	/*
>  	 * The vcpu timer irq number cannot be determined in
> @@ -196,6 +198,17 @@ void kvm_timer_vcpu_reset(struct kvm_vcpu *vcpu,
>  	 * vcpu timer irq number when the vcpu is reset.
>  	 */
>  	timer->irq = irq;
> +
> +	/*
> +	 * Tell the VGIC that the virtual interrupt is tied to a
> +	 * physical interrupt. We do that once per VCPU.
> +	 */
> +	map = kvm_vgic_map_phys_irq(vcpu, irq->irq, host_vtimer_irq);
> +	if (WARN_ON(IS_ERR(map)))
> +		return PTR_ERR(map);
> +
> +	timer->map = map;
> +	return 0;
>  }
>  
>  void kvm_timer_vcpu_init(struct kvm_vcpu *vcpu)
> @@ -335,6 +348,8 @@ void kvm_timer_vcpu_terminate(struct kvm_vcpu *vcpu)
>  	struct arch_timer_cpu *timer = &vcpu->arch.timer_cpu;
>  
>  	timer_disarm(timer);
> +	if (timer->map)
> +		kvm_vgic_unmap_phys_irq(vcpu, timer->map);
>  }
>  
>  void kvm_timer_enable(struct kvm *kvm)
> -- 
> 2.1.4
> 




From daniel.lezcano at linaro.org  Tue Aug  4 07:26:41 2015
From: daniel.lezcano at linaro.org (Daniel Lezcano)
Date: Tue, 04 Aug 2015 16:26:41 +0200
Subject: [PATCH] ARM/clocksource: use automatic DT probing
In-Reply-To: <1438348470-6656-1-git-send-email-linus.walleij@linaro.org>
References: <1438348470-6656-1-git-send-email-linus.walleij@linaro.org>
Message-ID: <55C0CBA1.9000602@linaro.org>

On 07/31/2015 03:14 PM, Linus Walleij wrote:
> The ARM core kernel already calls clocksource_of_init() so why
> go to all the trouble of locating and probing this node in the
> machine. CLOCKSOURCE_OF_DECLARE() will take care of it in the
> clocksource driver, and thus we can also get rid of the
> dangling header file <linux/clksrc-dbx500-prcmu.h>
>
> Suggested-by: Arnd Bergmann <arndb at linaro.org>
> Signed-off-by: Linus Walleij <linus.walleij at linaro.org>
> ---
> Clocksource maintainers: please ACK this so I can take it through
> ARM SoC with a bunch of other cleanups.

Acked-by: Daniel Lezcano <daniel.lezcano at linaro.org>


Follow Linaro:  <http://www.facebook.com/pages/Linaro> Facebook |
<http://twitter.com/#!/linaroorg> Twitter |
<http://www.linaro.org/linaro-blog/> Blog



From stern at rowland.harvard.edu  Tue Aug  4 07:29:56 2015
From: stern at rowland.harvard.edu (Alan Stern)
Date: Tue, 4 Aug 2015 10:29:56 -0400 (EDT)
Subject: [PATCH v2] usb: ehci-platform: Fix using multiple controllers
 from OF
In-Reply-To: <1438678757-26582-1-git-send-email-albeu@free.fr>
Message-ID: <Pine.LNX.4.44L0.1508041029250.1577-100000@iolanthe.rowland.org>

On Tue, 4 Aug 2015, Alban Bedel wrote:

> When using OF defined controllers the platform data struct is shared
> between all devices, so it can't be used for device specific settings.
> However it is currently used for the OF properties
> needs-reset-on-resume and has-transaction-translator.
> 
> To fix this issue move setting hcd->has_tt to the probe and
> move pdata->reset_on_resume to the private data.
> 
> Signed-off-by: Alban Bedel <albeu at free.fr>
> ---
> Changelog:
> v2: * Use true instead of 1 to set boolean type

Acked-by: Alan Stern <stern at rowland.harvard.edu>



From christoffer.dall at linaro.org  Tue Aug  4 07:32:09 2015
From: christoffer.dall at linaro.org (Christoffer Dall)
Date: Tue, 4 Aug 2015 16:32:09 +0200
Subject: [PATCH v3 11/11] KVM: arm/arm64: vgic: Allow HW interrupts for
 non-shared devices
In-Reply-To: <1437753309-17989-12-git-send-email-marc.zyngier@arm.com>
References: <1437753309-17989-1-git-send-email-marc.zyngier@arm.com>
 <1437753309-17989-12-git-send-email-marc.zyngier@arm.com>
Message-ID: <20150804143209.GD29335@cbox>

On Fri, Jul 24, 2015 at 04:55:09PM +0100, Marc Zyngier wrote:
> So far, the only use of the HW interrupt facility is the timer,
> implying that the active state is context-switched for each vcpu,
> as the device is is shared across all vcpus.
> 
> This does not work for a device that has been assigned to a VM,
> as the guest is entierely in control of that device (the HW is
> not shared). In that case, it makes sense to bypass the whole
> active state switching, and only track the deactivation of the
> interrupt.
> 
> Signed-off-by: Marc Zyngier <marc.zyngier at arm.com>
> ---
>  include/kvm/arm_vgic.h    |  6 ++--
>  virt/kvm/arm/arch_timer.c |  3 +-
>  virt/kvm/arm/vgic.c       | 73 +++++++++++++++++++++++++++++++++++++----------
>  3 files changed, 64 insertions(+), 18 deletions(-)
> 
> diff --git a/include/kvm/arm_vgic.h b/include/kvm/arm_vgic.h
> index f6bfd79..6f0a4e1 100644
> --- a/include/kvm/arm_vgic.h
> +++ b/include/kvm/arm_vgic.h
> @@ -164,7 +164,8 @@ struct irq_phys_map {
>  	u32			phys_irq;
>  	u32			irq;
>  	bool			deleted;
> -	bool			active;
> +	bool			shared;
> +	bool			active; /* Only valid if shared */
>  };
>  
>  struct irq_phys_map_entry {
> @@ -357,7 +358,8 @@ void vgic_v3_dispatch_sgi(struct kvm_vcpu *vcpu, u64 reg);
>  int kvm_vgic_vcpu_pending_irq(struct kvm_vcpu *vcpu);
>  int kvm_vgic_vcpu_active_irq(struct kvm_vcpu *vcpu);
>  struct irq_phys_map *kvm_vgic_map_phys_irq(struct kvm_vcpu *vcpu,
> -					   int virt_irq, int irq);
> +					   int virt_irq, int irq,
> +					   bool shared);
>  int kvm_vgic_unmap_phys_irq(struct kvm_vcpu *vcpu, struct irq_phys_map *map);
>  bool kvm_vgic_get_phys_irq_active(struct irq_phys_map *map);
>  void kvm_vgic_set_phys_irq_active(struct irq_phys_map *map, bool active);
> diff --git a/virt/kvm/arm/arch_timer.c b/virt/kvm/arm/arch_timer.c
> index 76e38d2..db21d8f 100644
> --- a/virt/kvm/arm/arch_timer.c
> +++ b/virt/kvm/arm/arch_timer.c
> @@ -203,7 +203,8 @@ int kvm_timer_vcpu_reset(struct kvm_vcpu *vcpu,
>  	 * Tell the VGIC that the virtual interrupt is tied to a
>  	 * physical interrupt. We do that once per VCPU.
>  	 */
> -	map = kvm_vgic_map_phys_irq(vcpu, irq->irq, host_vtimer_irq);
> +	map = kvm_vgic_map_phys_irq(vcpu, irq->irq,
> +				    host_vtimer_irq, true);
>  	if (WARN_ON(IS_ERR(map)))
>  		return PTR_ERR(map);
>  
> diff --git a/virt/kvm/arm/vgic.c b/virt/kvm/arm/vgic.c
> index e40ef70..5e6b816 100644
> --- a/virt/kvm/arm/vgic.c
> +++ b/virt/kvm/arm/vgic.c
> @@ -1128,19 +1128,25 @@ static void vgic_queue_irq_to_lr(struct kvm_vcpu *vcpu, int irq,
>  		 * active in the physical world. Otherwise the
>  		 * physical interrupt will fire and the guest will
>  		 * exit before processing the virtual interrupt.
> +		 *
> +		 * This is of course only valid for a shared
> +		 * interrupt. A non shared interrupt should already be
> +		 * active.
>  		 */
>  		if (map) {
> -			int ret;
> -
> -			BUG_ON(!map->active);
>  			vlr.hwirq = map->phys_irq;
>  			vlr.state |= LR_HW;
>  			vlr.state &= ~LR_EOI_INT;
>  
> -			ret = irq_set_irqchip_state(map->irq,
> -						    IRQCHIP_STATE_ACTIVE,
> -						    true);
> -			WARN_ON(ret);
> +			if (map->shared) {
> +				int ret;
> +
> +				BUG_ON(!map->active);
> +				ret = irq_set_irqchip_state(map->irq,
> +							    IRQCHIP_STATE_ACTIVE,
> +							    true);
> +				WARN_ON(ret);
> +			}
>  
>  			/*
>  			 * Make sure we're not going to sample this
> @@ -1383,21 +1389,41 @@ static bool vgic_process_maintenance(struct kvm_vcpu *vcpu)
>  static int vgic_sync_hwirq(struct kvm_vcpu *vcpu, struct vgic_lr vlr)
>  {
>  	struct irq_phys_map *map;
> +	bool active;
>  	int ret;
>  
>  	if (!(vlr.state & LR_HW))
>  		return 0;
>  
>  	map = vgic_irq_map_search(vcpu, vlr.irq);
> -	BUG_ON(!map || !map->active);
> +	BUG_ON(!map);
> +	BUG_ON(map->shared && !map->active);
>  
>  	ret = irq_get_irqchip_state(map->irq,
>  				    IRQCHIP_STATE_ACTIVE,
> -				    &map->active);
> +				    &active);
>  
>  	WARN_ON(ret);
>  
> -	if (map->active) {
> +	/*
> +	 * For a non-shared interrupt, we have to cater for two
> +	 * possible deactivation conditions:
> +	 *
> +	 * - the physical interrupt is now inactive (EOIed from the
> +         *   guest)

nit: whitespace funkyness

> +	 * - the physical interrupt is still active, but its virtual
> +	 *   counterpart is flagged as "not queued", indicating another
> +	 *   interrupt has fired between the EOI and the guest exit.
> +	 *
> +	 * Also, we are not reactivating a non-shared interrupt

what does reactivating mean? did you mean deactivate?

> +	 * ourselves. This is always left to the guest.

In which case, add ", because the device is solely owned by the guest."

> +	 */
> +	if (!map->shared)
> +		return !active || !vgic_irq_is_queued(vcpu, vlr.irq);

do you really need the second part of the disjunction?

The effect seems to be that we clear the queued flag once again, and
clear the LR.  If we don't do this, won't we simply pick up the pending
flag next time we're about to run this VCPU and piggy-back on the
existing LR.  Perhaps this is a weird flow though?

> +
> +	map->active = active;
> +
> +	if (active) {
>  		ret = irq_set_irqchip_state(map->irq,
>  					    IRQCHIP_STATE_ACTIVE,
>  					    false);
> @@ -1590,6 +1616,17 @@ static int vgic_update_irq_pending(struct kvm *kvm, int cpuid,
>  		goto out;
>  	}
>  
> +	if (map && !map->shared) {
> +		/*
> +		 * We are told to inject a HW irq, so we have to trust
> +		 * the caller that the previous one has been EOIed,
> +		 * and that a new one is now active. Clearing the
> +		 * queued state will have the effect of making it
> +		 * sample-able again.
> +		 */
> +		vgic_irq_clear_queued(vcpu, irq_num);
> +	}
> +
>  	if (!vgic_can_sample_irq(vcpu, irq_num)) {
>  		/*
>  		 * Level interrupt in progress, will be picked up
> @@ -1720,15 +1757,19 @@ static struct list_head *vgic_get_irq_phys_map_list(struct kvm_vcpu *vcpu,
>   * @vcpu: The VCPU pointer
>   * @virt_irq: The virtual irq number
>   * @irq: The Linux IRQ number
> + * @shared: Indicates if the interrupt has to be context-switched or
> + *          if it is private to a VM
>   *
>   * Establish a mapping between a guest visible irq (@virt_irq) and a
>   * Linux irq (@irq). On injection, @virt_irq will be associated with
> - * the physical interrupt represented by @irq.
> + * the physical interrupt represented by @irq. If @shared is true,
> + * the active state of the interrupt will be context-switched.
>   *
>   * Returns a valid pointer on success, and an error pointer otherwise
>   */
>  struct irq_phys_map *kvm_vgic_map_phys_irq(struct kvm_vcpu *vcpu,
> -					   int virt_irq, int irq)
> +					   int virt_irq, int irq,
> +					   bool shared)
>  {
>  	struct vgic_dist *dist = &vcpu->kvm->arch.vgic;
>  	struct list_head *root = vgic_get_irq_phys_map_list(vcpu, virt_irq);
> @@ -1762,7 +1803,8 @@ struct irq_phys_map *kvm_vgic_map_phys_irq(struct kvm_vcpu *vcpu,
>  	if (map) {
>  		/* Make sure this mapping matches */
>  		if (map->phys_irq != phys_irq	||
> -		    map->irq      != irq)
> +		    map->irq      != irq	||
> +		    map->shared   != shared)
>  			map = ERR_PTR(-EINVAL);
>  
>  		goto out;
> @@ -1772,6 +1814,7 @@ struct irq_phys_map *kvm_vgic_map_phys_irq(struct kvm_vcpu *vcpu,
>  	map->virt_irq = virt_irq;
>  	map->phys_irq = phys_irq;
>  	map->irq      = irq;
> +	map->shared   = shared;
>  
>  	list_add_tail_rcu(&entry->entry, root);
>  
> @@ -1822,7 +1865,7 @@ static void vgic_free_phys_irq_map_rcu(struct rcu_head *rcu)
>   */
>  bool kvm_vgic_get_phys_irq_active(struct irq_phys_map *map)
>  {
> -	BUG_ON(!map);
> +	BUG_ON(!map || !map->shared);
>  	return map->active;
>  }
>  
> @@ -1834,7 +1877,7 @@ bool kvm_vgic_get_phys_irq_active(struct irq_phys_map *map)
>   */
>  void kvm_vgic_set_phys_irq_active(struct irq_phys_map *map, bool active)
>  {
> -	BUG_ON(!map);
> +	BUG_ON(!map || !map->shared);
>  	map->active = active;
>  }
>  
> -- 
> 2.1.4
> 

I think I'm seeing this in the correct light this time around, so this
is functionally looking pretty good to me.

Thanks,
-Christoffer


From christoffer.dall at linaro.org  Tue Aug  4 07:33:46 2015
From: christoffer.dall at linaro.org (Christoffer Dall)
Date: Tue, 4 Aug 2015 16:33:46 +0200
Subject: [PATCH v3 04/11] KVM: arm/arm64: vgic: Allow HW irq to be
 encoded in LR
In-Reply-To: <1437753309-17989-5-git-send-email-marc.zyngier@arm.com>
References: <1437753309-17989-1-git-send-email-marc.zyngier@arm.com>
 <1437753309-17989-5-git-send-email-marc.zyngier@arm.com>
Message-ID: <20150804143346.GE29335@cbox>

On Fri, Jul 24, 2015 at 04:55:02PM +0100, Marc Zyngier wrote:
> Now that struct vgic_lr supports the LR_HW bit and carries a hwirq
> field, we can encode that information into the list registers.
> 
> This patch provides implementations for both GICv2 and GICv3.
> 
> Signed-off-by: Marc Zyngier <marc.zyngier at arm.com>

Reviewed-by: Christoffer Dall <christoffer.dall at linaro.org>


From christoffer.dall at linaro.org  Tue Aug  4 07:33:52 2015
From: christoffer.dall at linaro.org (Christoffer Dall)
Date: Tue, 4 Aug 2015 16:33:52 +0200
Subject: [PATCH v3 07/11] KVM: arm/arm64: vgic: Allow HW interrupts to be
 queued to a guest
In-Reply-To: <1437753309-17989-8-git-send-email-marc.zyngier@arm.com>
References: <1437753309-17989-1-git-send-email-marc.zyngier@arm.com>
 <1437753309-17989-8-git-send-email-marc.zyngier@arm.com>
Message-ID: <20150804143352.GF29335@cbox>

On Fri, Jul 24, 2015 at 04:55:05PM +0100, Marc Zyngier wrote:
> To allow a HW interrupt to be injected into a guest, we lookup the
> guest virtual interrupt in the irq_phys_map list, and if we have
> a match, encode both interrupts in the LR.
> 
> We also mark the interrupt as "active" at the host distributor level.
> 
> On guest EOI on the virtual interrupt, the host interrupt will be
> deactivated.
> 
> Signed-off-by: Marc Zyngier <marc.zyngier at arm.com>

Reviewed-by: Christoffer Dall <christoffer.dall at linaro.org>


From 21cnbao at gmail.com  Tue Aug  4 07:45:25 2015
From: 21cnbao at gmail.com (Barry Song)
Date: Tue,  4 Aug 2015 14:45:25 +0000
Subject: [PATCH 0/7 v2] clk: atlas7: a bind of fixes
Message-ID: <1438699532-13860-1-git-send-email-21cnbao@gmail.com>

-v2: refine commit title according to the feedback of Stephen Boyd

Guo Zeng (5):
  clk: atlas7: add lost pwm unit clks
  clk: atlas7: export mux clks so that consumers can get them
  clk: atlas7: fix the clock tree for bluetooth stuff
  clk: atlas7: fix bit field and its root clk for coresight_tpiu
  clk: atlas7: fix pll missed divide NR in fraction mode

Yibo Cai (2):
  clk: atlas7: fix integer overflow in dto rate calculation
  clk: atlas7: replace dto resolution magic number by macro

 drivers/clk/sirf/clk-atlas7.c | 33 +++++++++++++++++++++------------
 1 file changed, 21 insertions(+), 12 deletions(-)

-- 
1.9.1



From 21cnbao at gmail.com  Tue Aug  4 07:45:26 2015
From: 21cnbao at gmail.com (Barry Song)
Date: Tue,  4 Aug 2015 14:45:26 +0000
Subject: [PATCH 1/7 v2] clk: atlas7: add lost pwm unit clks
In-Reply-To: <1438699532-13860-1-git-send-email-21cnbao@gmail.com>
References: <1438699532-13860-1-git-send-email-21cnbao@gmail.com>
Message-ID: <1438699532-13860-2-git-send-email-21cnbao@gmail.com>

From: Guo Zeng <Guo.Zeng at csr.com>

Signed-off-by: Guo Zeng <Guo.Zeng at csr.com>
Signed-off-by: Barry Song <Baohua.Song at csr.com>
---
 drivers/clk/sirf/clk-atlas7.c | 4 ++++
 1 file changed, 4 insertions(+)

diff --git a/drivers/clk/sirf/clk-atlas7.c b/drivers/clk/sirf/clk-atlas7.c
index db8ab69..a92e7ea 100644
--- a/drivers/clk/sirf/clk-atlas7.c
+++ b/drivers/clk/sirf/clk-atlas7.c
@@ -1174,6 +1174,10 @@ static struct atlas7_unit_init_data unit_list[] __initdata = {
 	{ 135, "thbtm_io", "btm_io", 0, SIRFSOC_CLKC_LEAF_CLK_EN8_SET, 7, &leaf8_gate_lock },
 	{ 136, "btslow", "xinw_fixdiv_btslow", 0, SIRFSOC_CLKC_ROOT_CLK_EN1_SET, 25, &root1_gate_lock },
 	{ 137, "a7ca_btslow", "btslow", 0, SIRFSOC_CLKC_LEAF_CLK_EN8_SET, 0, &leaf8_gate_lock },
+	{ 138 , "pwm_io", "io_mux", 0, SIRFSOC_CLKC_LEAF_CLK_EN0_SET, 0, &leaf0_gate_lock },
+	{ 139 , "pwm_xin", "xin", 0, SIRFSOC_CLKC_LEAF_CLK_EN0_SET, 1, &leaf0_gate_lock },
+	{ 140 , "pwm_xinw", "xinw", 0, SIRFSOC_CLKC_LEAF_CLK_EN0_SET, 2, &leaf0_gate_lock },
+	{ 141 , "thcgum_sys", "sys_mux", 0, SIRFSOC_CLKC_LEAF_CLK_EN0_SET, 3, &leaf0_gate_lock },
 };
 
 static struct clk *atlas7_clks[ARRAY_SIZE(unit_list)];
-- 
1.9.1



From 21cnbao at gmail.com  Tue Aug  4 07:45:27 2015
From: 21cnbao at gmail.com (Barry Song)
Date: Tue,  4 Aug 2015 14:45:27 +0000
Subject: [PATCH 2/7 v2] clk: atlas7: export mux clks so that consumers can get
 them
In-Reply-To: <1438699532-13860-1-git-send-email-21cnbao@gmail.com>
References: <1438699532-13860-1-git-send-email-21cnbao@gmail.com>
Message-ID: <1438699532-13860-3-git-send-email-21cnbao@gmail.com>

From: Guo Zeng <guo.zeng at csr.com>

this patch makes mux clks can be referenced by device drivers.

Signed-off-by: Guo Zeng <guo.zeng at csr.com>
Signed-off-by: Barry Song <Barry.Song at csr.com>
---
 drivers/clk/sirf/clk-atlas7.c | 5 +++--
 1 file changed, 3 insertions(+), 2 deletions(-)

diff --git a/drivers/clk/sirf/clk-atlas7.c b/drivers/clk/sirf/clk-atlas7.c
index a92e7ea..d01dce3 100644
--- a/drivers/clk/sirf/clk-atlas7.c
+++ b/drivers/clk/sirf/clk-atlas7.c
@@ -1180,7 +1180,7 @@ static struct atlas7_unit_init_data unit_list[] __initdata = {
 	{ 141 , "thcgum_sys", "sys_mux", 0, SIRFSOC_CLKC_LEAF_CLK_EN0_SET, 3, &leaf0_gate_lock },
 };
 
-static struct clk *atlas7_clks[ARRAY_SIZE(unit_list)];
+static struct clk *atlas7_clks[ARRAY_SIZE(unit_list) + ARRAY_SIZE(mux_list)];
 
 static int unit_clk_is_enabled(struct clk_hw *hw)
 {
@@ -1613,6 +1613,7 @@ static void __init atlas7_clk_init(struct device_node *np)
 			       sirfsoc_clk_vbase + mux->mux_offset,
 			       mux->shift, mux->width,
 			       mux->mux_flags, NULL);
+		atlas7_clks[ARRAY_SIZE(unit_list) + i] = clk;
 		BUG_ON(!clk);
 	}
 
@@ -1624,7 +1625,7 @@ static void __init atlas7_clk_init(struct device_node *np)
 	}
 
 	clk_data.clks = atlas7_clks;
-	clk_data.clk_num = ARRAY_SIZE(unit_list);
+	clk_data.clk_num = ARRAY_SIZE(unit_list) + ARRAY_SIZE(mux_list);
 
 	ret = of_clk_add_provider(np, of_clk_src_onecell_get, &clk_data);
 	BUG_ON(ret);
-- 
1.9.1



From 21cnbao at gmail.com  Tue Aug  4 07:45:28 2015
From: 21cnbao at gmail.com (Barry Song)
Date: Tue,  4 Aug 2015 14:45:28 +0000
Subject: [PATCH 3/7 v2] clk: atlas7: fix integer overflow in dto rate
 calculation
In-Reply-To: <1438699532-13860-1-git-send-email-21cnbao@gmail.com>
References: <1438699532-13860-1-git-send-email-21cnbao@gmail.com>
Message-ID: <1438699532-13860-4-git-send-email-21cnbao@gmail.com>

From: Yibo Cai <yibo.cai at csr.com>

I cannot believe that I spend quite a lot time in finding this bug.
It seems a pitfall people tend to fall in.

In "int64 = int32 * int32", conversion from 32-bits to 64-bits comes
after the multiplication. So this statement may not work as expected.

Signed-off-by: Yibo Cai <yibo.cai at csr.com>
Signed-off-by: Barry Song <Baohua.Song at csr.com>
---
 drivers/clk/sirf/clk-atlas7.c | 4 ++--
 1 file changed, 2 insertions(+), 2 deletions(-)

diff --git a/drivers/clk/sirf/clk-atlas7.c b/drivers/clk/sirf/clk-atlas7.c
index d01dce3..cf489a5 100644
--- a/drivers/clk/sirf/clk-atlas7.c
+++ b/drivers/clk/sirf/clk-atlas7.c
@@ -519,7 +519,7 @@ static unsigned long dto_clk_recalc_rate(struct clk_hw *hw,
 static long dto_clk_round_rate(struct clk_hw *hw, unsigned long rate,
 	unsigned long *parent_rate)
 {
-	u64 dividend = rate * (1 << 29);
+	u64 dividend = (u64)rate * (1 << 29);
 
 	do_div(dividend, *parent_rate);
 	dividend *= *parent_rate;
@@ -531,7 +531,7 @@ static long dto_clk_round_rate(struct clk_hw *hw, unsigned long rate,
 static int dto_clk_set_rate(struct clk_hw *hw, unsigned long rate,
 	unsigned long parent_rate)
 {
-	u64 dividend = rate * (1 << 29);
+	u64 dividend = (u64)rate * (1 << 29);
 	struct clk_dto *clk = to_dtoclk(hw);
 
 	do_div(dividend, parent_rate);
-- 
1.9.1



From 21cnbao at gmail.com  Tue Aug  4 07:45:29 2015
From: 21cnbao at gmail.com (Barry Song)
Date: Tue,  4 Aug 2015 14:45:29 +0000
Subject: [PATCH 4/7 v2] clk: atlas7: replace dto resolution magic number by
 macro
In-Reply-To: <1438699532-13860-1-git-send-email-21cnbao@gmail.com>
References: <1438699532-13860-1-git-send-email-21cnbao@gmail.com>
Message-ID: <1438699532-13860-5-git-send-email-21cnbao@gmail.com>

From: Yibo Cai <yibo.cai at csr.com>

Signed-off-by: Yibo Cai <yibo.cai at csr.com>
Signed-off-by: Barry Song <Baohua.Song at csr.com>
---
 drivers/clk/sirf/clk-atlas7.c | 13 ++++++++-----
 1 file changed, 8 insertions(+), 5 deletions(-)

diff --git a/drivers/clk/sirf/clk-atlas7.c b/drivers/clk/sirf/clk-atlas7.c
index cf489a5..1000421 100644
--- a/drivers/clk/sirf/clk-atlas7.c
+++ b/drivers/clk/sirf/clk-atlas7.c
@@ -465,6 +465,9 @@ static struct clk_pll clk_sys3pll = {
  *  double resolution mode:fout = fin * finc / 2^29
  *  normal mode:fout = fin * finc / 2^28
  */
+#define DTO_RESL_DOUBLE	(1ULL << 29)
+#define DTO_RESL_NORMAL	(1ULL << 28)
+
 static int dto_clk_is_enabled(struct clk_hw *hw)
 {
 	struct clk_dto *clk = to_dtoclk(hw);
@@ -509,9 +512,9 @@ static unsigned long dto_clk_recalc_rate(struct clk_hw *hw,
 	rate *= finc;
 	if (droff & BIT(0))
 		/* Double resolution off */
-		do_div(rate, 1 << 28);
+		do_div(rate, DTO_RESL_NORMAL);
 	else
-		do_div(rate, 1 << 29);
+		do_div(rate, DTO_RESL_DOUBLE);
 
 	return rate;
 }
@@ -519,11 +522,11 @@ static unsigned long dto_clk_recalc_rate(struct clk_hw *hw,
 static long dto_clk_round_rate(struct clk_hw *hw, unsigned long rate,
 	unsigned long *parent_rate)
 {
-	u64 dividend = (u64)rate * (1 << 29);
+	u64 dividend = rate * DTO_RESL_DOUBLE;
 
 	do_div(dividend, *parent_rate);
 	dividend *= *parent_rate;
-	do_div(dividend, 1 << 29);
+	do_div(dividend, DTO_RESL_DOUBLE);
 
 	return dividend;
 }
@@ -531,7 +534,7 @@ static long dto_clk_round_rate(struct clk_hw *hw, unsigned long rate,
 static int dto_clk_set_rate(struct clk_hw *hw, unsigned long rate,
 	unsigned long parent_rate)
 {
-	u64 dividend = (u64)rate * (1 << 29);
+	u64 dividend = rate * DTO_RESL_DOUBLE;
 	struct clk_dto *clk = to_dtoclk(hw);
 
 	do_div(dividend, parent_rate);
-- 
1.9.1



From 21cnbao at gmail.com  Tue Aug  4 07:45:30 2015
From: 21cnbao at gmail.com (Barry Song)
Date: Tue,  4 Aug 2015 14:45:30 +0000
Subject: [PATCH 5/7 v2] clk: atlas7: fix the clock tree for bluetooth stuff
In-Reply-To: <1438699532-13860-1-git-send-email-21cnbao@gmail.com>
References: <1438699532-13860-1-git-send-email-21cnbao@gmail.com>
Message-ID: <1438699532-13860-6-git-send-email-21cnbao@gmail.com>

From: Guo Zeng <guo.zeng at csr.com>

normally dmac should depends on only one clock, to operate
dmac internal register, but dmac4 is very special case, it
normally dmac should depends on only one clock, to operate
dmac internal register, but dmac4 is very special case, it
depends on two additional clock, the reason is that dmac4
is wrapped in hw into bt a7ca module, and accessing dmac4
internal register would also require that the a7ca_io and
related bt macro io clk also enabled.
here workaround this by setting depend clk into parent of
dmac4, and also related clks, to reflect dependency.
noc_io
    -btm_noc_clk
            -a7ca_io
                    -dmac4_io
                                    -uart6_io
                                    -usp3_io

Signed-off-by: Guo Zeng <guo.zeng at csr.com>
Signed-off-by: Barry Song <Baohua.Song at csr.com>
---
 drivers/clk/sirf/clk-atlas7.c | 8 ++++----
 1 file changed, 4 insertions(+), 4 deletions(-)

diff --git a/drivers/clk/sirf/clk-atlas7.c b/drivers/clk/sirf/clk-atlas7.c
index 1000421..c1788df 100644
--- a/drivers/clk/sirf/clk-atlas7.c
+++ b/drivers/clk/sirf/clk-atlas7.c
@@ -1169,10 +1169,10 @@ static struct atlas7_unit_init_data unit_list[] __initdata = {
 	{ 127, "vss_sdr", "gpum_sdr", 0, SIRFSOC_CLKC_LEAF_CLK_EN7_SET, 1, &leaf7_gate_lock },
 	{ 128, "thgpum_nocr", "gpum_nocr", 0, SIRFSOC_CLKC_LEAF_CLK_EN7_SET, 2, &leaf7_gate_lock },
 	{ 129, "a7ca_btss", "btm_btss", 0, SIRFSOC_CLKC_LEAF_CLK_EN8_SET, 1, &leaf8_gate_lock },
-	{ 130, "dmac4_io", "btm_io", 0, SIRFSOC_CLKC_LEAF_CLK_EN8_SET, 2, &leaf8_gate_lock },
-	{ 131, "uart6_io", "btm_io", 0, SIRFSOC_CLKC_LEAF_CLK_EN8_SET, 3, &leaf8_gate_lock },
-	{ 132, "usp3_io", "btm_io", 0, SIRFSOC_CLKC_LEAF_CLK_EN8_SET, 4, &leaf8_gate_lock },
-	{ 133, "a7ca_io", "btm_io", 0, SIRFSOC_CLKC_LEAF_CLK_EN8_SET, 5, &leaf8_gate_lock },
+	{ 130 , "dmac4_io", "a7ca_io", 0, SIRFSOC_CLKC_LEAF_CLK_EN8_SET, 2, &leaf8_gate_lock },
+	{ 131 , "uart6_io", "dmac4_io", 0, SIRFSOC_CLKC_LEAF_CLK_EN8_SET, 3, &leaf8_gate_lock },
+	{ 132 , "usp3_io", "dmac4_io", 0, SIRFSOC_CLKC_LEAF_CLK_EN8_SET, 4, &leaf8_gate_lock },
+	{ 133 , "a7ca_io", "noc_btm_io", 0, SIRFSOC_CLKC_LEAF_CLK_EN8_SET, 5, &leaf8_gate_lock },
 	{ 134, "noc_btm_io", "btm_io", 0, SIRFSOC_CLKC_LEAF_CLK_EN8_SET, 6, &leaf8_gate_lock },
 	{ 135, "thbtm_io", "btm_io", 0, SIRFSOC_CLKC_LEAF_CLK_EN8_SET, 7, &leaf8_gate_lock },
 	{ 136, "btslow", "xinw_fixdiv_btslow", 0, SIRFSOC_CLKC_ROOT_CLK_EN1_SET, 25, &root1_gate_lock },
-- 
1.9.1



From 21cnbao at gmail.com  Tue Aug  4 07:45:31 2015
From: 21cnbao at gmail.com (Barry Song)
Date: Tue,  4 Aug 2015 14:45:31 +0000
Subject: [PATCH 6/7 v2] clk: atlas7: fix bit field and its root clk for
 coresight_tpiu
In-Reply-To: <1438699532-13860-1-git-send-email-21cnbao@gmail.com>
References: <1438699532-13860-1-git-send-email-21cnbao@gmail.com>
Message-ID: <1438699532-13860-7-git-send-email-21cnbao@gmail.com>

From: Guo Zeng <guo.zeng at csr.com>

bit4 thcpum_cpudiv4_clken 	r/w
thcpum_cpudiv4_clk clock enable (default: 1)
Root clock CPU_CLK must be enabled for this clock to be enabled

bit3 coresight_tpiu_clken 	r/w
coresight_tpiu_clk clock enable (default: 0)
Root clock TPIU_CLK must be enabled for this clock to be enabled

Signed-off-by: Guo Zeng <guo.zeng at csr.com>
Signed-off-by: Barry Song <Baohua.Song at csr.com>
---
 drivers/clk/sirf/clk-atlas7.c | 2 +-
 1 file changed, 1 insertion(+), 1 deletion(-)

diff --git a/drivers/clk/sirf/clk-atlas7.c b/drivers/clk/sirf/clk-atlas7.c
index c1788df..4fc33da 100644
--- a/drivers/clk/sirf/clk-atlas7.c
+++ b/drivers/clk/sirf/clk-atlas7.c
@@ -1164,7 +1164,7 @@ static struct atlas7_unit_init_data unit_list[] __initdata = {
 	{ 122, "spram1_cpudiv2", "cpum_cpu", 0, SIRFSOC_CLKC_LEAF_CLK_EN6_SET, 0, &leaf6_gate_lock },
 	{ 123, "spram2_cpudiv2", "cpum_cpu", 0, SIRFSOC_CLKC_LEAF_CLK_EN6_SET, 1, &leaf6_gate_lock },
 	{ 124, "coresight_cpudiv2", "cpum_cpu", 0, SIRFSOC_CLKC_LEAF_CLK_EN6_SET, 2, &leaf6_gate_lock },
-	{ 125, "thcpum_cpudiv4", "cpum_cpu", 0, SIRFSOC_CLKC_LEAF_CLK_EN6_SET, 3, &leaf6_gate_lock },
+	{ 125 , "coresight_tpiu", "cpum_tpiu", 0, SIRFSOC_CLKC_LEAF_CLK_EN6_SET, 3, &leaf6_gate_lock },
 	{ 126, "graphic_gpu", "gpum_gpu", 0, SIRFSOC_CLKC_LEAF_CLK_EN7_SET, 0, &leaf7_gate_lock },
 	{ 127, "vss_sdr", "gpum_sdr", 0, SIRFSOC_CLKC_LEAF_CLK_EN7_SET, 1, &leaf7_gate_lock },
 	{ 128, "thgpum_nocr", "gpum_nocr", 0, SIRFSOC_CLKC_LEAF_CLK_EN7_SET, 2, &leaf7_gate_lock },
-- 
1.9.1



From 21cnbao at gmail.com  Tue Aug  4 07:45:32 2015
From: 21cnbao at gmail.com (Barry Song)
Date: Tue,  4 Aug 2015 14:45:32 +0000
Subject: [PATCH 7/7] clk: atlas7: fix pll missed divide NR in fraction mode
In-Reply-To: <1438699532-13860-1-git-send-email-21cnbao@gmail.com>
References: <1438699532-13860-1-git-send-email-21cnbao@gmail.com>
Message-ID: <1438699532-13860-8-git-send-email-21cnbao@gmail.com>

From: Guo Zeng <guo.zeng at csr.com>

PLL VCO frequency is given by Fvco = Fref * 2 * NF / NR
in integer-N mode, or by Fvco = Fref * SSN / NR in Spread
Spectrum (fractional-N) mode. Thus fix the missing part
of NR

Signed-off-by: Guo Zeng <guo.zeng at csr.com>
Signed-off-by: Barry Song <Baohua.Song at csr.com>
---
 drivers/clk/sirf/clk-atlas7.c | 1 +
 1 file changed, 1 insertion(+)

diff --git a/drivers/clk/sirf/clk-atlas7.c b/drivers/clk/sirf/clk-atlas7.c
index 4fc33da..19f417c 100644
--- a/drivers/clk/sirf/clk-atlas7.c
+++ b/drivers/clk/sirf/clk-atlas7.c
@@ -358,6 +358,7 @@ static unsigned long pll_clk_recalc_rate(struct clk_hw *hw,
 	if (regctrl0 & SIRFSOC_ABPLL_CTRL0_SSEN) {
 		rate = fin;
 		rate *= 1 << 24;
+		do_div(rate, nr);
 		do_div(rate, (256 * ((ssdiv >> ssdepth) << ssdepth)
 			+ (ssmod << ssdepth)));
 	} else {
-- 
1.9.1



From jslaby at suse.cz  Tue Aug  4 07:40:50 2015
From: jslaby at suse.cz (Jiri Slaby)
Date: Tue,  4 Aug 2015 16:40:50 +0200
Subject: [PATCH 3.12 106/123] clocksource: exynos_mct: Avoid blocking calls in
 the cpu hotplug notifier
In-Reply-To: <fe2a2e06fd8af3a00d18691ffeb2b636f685bee4.1438699154.git.jslaby@suse.cz>
References: <fe2a2e06fd8af3a00d18691ffeb2b636f685bee4.1438699154.git.jslaby@suse.cz>
Message-ID: <e3c69a44b6ce185cd00a85fca03984d17c305338.1438699154.git.jslaby@suse.cz>

From: Damian Eppel <d.eppel at samsung.com>

3.12-stable review patch.  If anyone has any objections, please let me know.

===============

commit 56a94f13919c0db5958611b388e1581b4852f3c9 upstream.

Whilst testing cpu hotplug events on kernel configured with
DEBUG_PREEMPT and DEBUG_ATOMIC_SLEEP we get following BUG message,
caused by calling request_irq() and free_irq() in the context of
hotplug notification (which is in this case atomic context).

[   40.785859] CPU1: Software reset
[   40.786660] BUG: sleeping function called from invalid context at mm/slub.c:1241
[   40.786668] in_atomic(): 1, irqs_disabled(): 128, pid: 0, name: swapper/1
[   40.786678] Preemption disabled at:[<  (null)>]   (null)
[   40.786681]
[   40.786692] CPU: 1 PID: 0 Comm: swapper/1 Not tainted 3.19.0-rc4-00024-g7dca860 #36
[   40.786698] Hardware name: SAMSUNG EXYNOS (Flattened Device Tree)
[   40.786728] [<c0014a00>] (unwind_backtrace) from [<c0011980>] (show_stack+0x10/0x14)
[   40.786747] [<c0011980>] (show_stack) from [<c0449ba0>] (dump_stack+0x70/0xbc)
[   40.786767] [<c0449ba0>] (dump_stack) from [<c00c6124>] (kmem_cache_alloc+0xd8/0x170)
[   40.786785] [<c00c6124>] (kmem_cache_alloc) from [<c005d6f8>] (request_threaded_irq+0x64/0x128)
[   40.786804] [<c005d6f8>] (request_threaded_irq) from [<c0350b8c>] (exynos4_local_timer_setup+0xc0/0x13c)
[   40.786820] [<c0350b8c>] (exynos4_local_timer_setup) from [<c0350ca8>] (exynos4_mct_cpu_notify+0x30/0xa8)
[   40.786838] [<c0350ca8>] (exynos4_mct_cpu_notify) from [<c003b330>] (notifier_call_chain+0x44/0x84)
[   40.786857] [<c003b330>] (notifier_call_chain) from [<c0022fd4>] (__cpu_notify+0x28/0x44)
[   40.786873] [<c0022fd4>] (__cpu_notify) from [<c0013714>] (secondary_start_kernel+0xec/0x150)
[   40.786886] [<c0013714>] (secondary_start_kernel) from [<40008764>] (0x40008764)

Interrupts cannot be requested/freed in the CPU_STARTING/CPU_DYING
notifications which run on the hotplugged cpu with interrupts and
preemption disabled.

To avoid the issue, request the interrupts for all possible cpus in
the boot code. The interrupts are marked NO_AUTOENABLE to avoid a racy
request_irq/disable_irq() sequence. The flag prevents the
request_irq() code from enabling the interrupt immediately.

The interrupt is then enabled in the CPU_STARTING notifier of the
hotplugged cpu and again disabled with disable_irq_nosync() in the
CPU_DYING notifier.

[ tglx: Massaged changelog to match the patch ]

Fixes: 7114cd749a12 ("clocksource: exynos_mct: use (request/free)_irq calls for local timer registration")
Reported-by: Krzysztof Kozlowski <k.kozlowski at samsung.com>
Reviewed-by: Krzysztof Kozlowski <k.kozlowski at samsung.com>
Tested-by: Krzysztof Kozlowski <k.kozlowski at samsung.com>
Tested-by: Marcin Jabrzyk <m.jabrzyk at samsung.com>
Signed-off-by: Damian Eppel <d.eppel at samsung.com>
Cc: m.szyprowski at samsung.com
Cc: kyungmin.park at samsung.com
Cc: daniel.lezcano at linaro.org
Cc: kgene at kernel.org
Cc: linux-arm-kernel at lists.infradead.org
Link: http://lkml.kernel.org/r/1435324984-7328-1-git-send-email-d.eppel at samsung.com
Signed-off-by: Thomas Gleixner <tglx at linutronix.de>
Cc: <stable at vger.kernel.org>
Signed-off-by: Jiri Slaby <jslaby at suse.cz>
---
 drivers/clocksource/exynos_mct.c | 43 ++++++++++++++++++++++++++++------------
 1 file changed, 30 insertions(+), 13 deletions(-)

diff --git a/drivers/clocksource/exynos_mct.c b/drivers/clocksource/exynos_mct.c
index 12fbec743fac..fc0e502022de 100644
--- a/drivers/clocksource/exynos_mct.c
+++ b/drivers/clocksource/exynos_mct.c
@@ -418,15 +418,12 @@ static int exynos4_local_timer_setup(struct clock_event_device *evt)
 	exynos4_mct_write(TICK_BASE_CNT, mevt->base + MCT_L_TCNTB_OFFSET);
 
 	if (mct_int_type == MCT_INT_SPI) {
-		evt->irq = mct_irqs[MCT_L0_IRQ + cpu];
-		if (request_irq(evt->irq, exynos4_mct_tick_isr,
-				IRQF_TIMER | IRQF_NOBALANCING,
-				evt->name, mevt)) {
-			pr_err("exynos-mct: cannot register IRQ %d\n",
-				evt->irq);
+
+		if (evt->irq == -1)
 			return -EIO;
-		}
-		irq_force_affinity(mct_irqs[MCT_L0_IRQ + cpu], cpumask_of(cpu));
+
+		irq_force_affinity(evt->irq, cpumask_of(cpu));
+		enable_irq(evt->irq);
 	} else {
 		enable_percpu_irq(mct_irqs[MCT_L0_IRQ], 0);
 	}
@@ -439,10 +436,12 @@ static int exynos4_local_timer_setup(struct clock_event_device *evt)
 static void exynos4_local_timer_stop(struct clock_event_device *evt)
 {
 	evt->set_mode(CLOCK_EVT_MODE_UNUSED, evt);
-	if (mct_int_type == MCT_INT_SPI)
-		free_irq(evt->irq, this_cpu_ptr(&percpu_mct_tick));
-	else
+	if (mct_int_type == MCT_INT_SPI) {
+		if (evt->irq != -1)
+			disable_irq_nosync(evt->irq);
+	} else {
 		disable_percpu_irq(mct_irqs[MCT_L0_IRQ]);
+	}
 }
 
 static int exynos4_mct_cpu_notify(struct notifier_block *self,
@@ -474,7 +473,7 @@ static struct notifier_block exynos4_mct_cpu_nb = {
 
 static void __init exynos4_timer_resources(struct device_node *np, void __iomem *base)
 {
-	int err;
+	int err, cpu;
 	struct mct_clock_event_device *mevt = this_cpu_ptr(&percpu_mct_tick);
 	struct clk *mct_clk, *tick_clk;
 
@@ -501,7 +500,25 @@ static void __init exynos4_timer_resources(struct device_node *np, void __iomem
 		WARN(err, "MCT: can't request IRQ %d (%d)\n",
 		     mct_irqs[MCT_L0_IRQ], err);
 	} else {
-		irq_set_affinity(mct_irqs[MCT_L0_IRQ], cpumask_of(0));
+		for_each_possible_cpu(cpu) {
+			int mct_irq = mct_irqs[MCT_L0_IRQ + cpu];
+			struct mct_clock_event_device *pcpu_mevt =
+				per_cpu_ptr(&percpu_mct_tick, cpu);
+
+			pcpu_mevt->evt.irq = -1;
+
+			irq_set_status_flags(mct_irq, IRQ_NOAUTOEN);
+			if (request_irq(mct_irq,
+					exynos4_mct_tick_isr,
+					IRQF_TIMER | IRQF_NOBALANCING,
+					pcpu_mevt->name, pcpu_mevt)) {
+				pr_err("exynos-mct: cannot register IRQ (cpu%d)\n",
+									cpu);
+
+				continue;
+			}
+			pcpu_mevt->evt.irq = mct_irq;
+		}
 	}
 
 	err = register_cpu_notifier(&exynos4_mct_cpu_nb);
-- 
2.5.0



From scott.shu at mediatek.com  Tue Aug  4 06:54:19 2015
From: scott.shu at mediatek.com (Scott Shu)
Date: Tue, 4 Aug 2015 21:54:19 +0800
Subject: [PATCH v3 3/8] soc: Mediatek: Add SCPSYS CPU power domain driver
In-Reply-To: <1438696464-59858-1-git-send-email-scott.shu@mediatek.com>
References: <1438696464-59858-1-git-send-email-scott.shu@mediatek.com>
Message-ID: <1438696464-59858-4-git-send-email-scott.shu@mediatek.com>

This adds a CPU power domain driver for the Mediatek SCPSYS unit on
MT6580.

Signed-off-by: Scott Shu <scott.shu at mediatek.com>
---
 drivers/soc/mediatek/mtk-scpsys.c   |  250 +++++++++++++++++++++++++++++++++++
 include/linux/soc/mediatek/scpsys.h |    9 ++
 2 files changed, 259 insertions(+)
 create mode 100644 include/linux/soc/mediatek/scpsys.h

diff --git a/drivers/soc/mediatek/mtk-scpsys.c b/drivers/soc/mediatek/mtk-scpsys.c
index 43a79ed..ca0f2dd 100644
--- a/drivers/soc/mediatek/mtk-scpsys.c
+++ b/drivers/soc/mediatek/mtk-scpsys.c
@@ -15,18 +15,30 @@
 #include <linux/io.h>
 #include <linux/kernel.h>
 #include <linux/mfd/syscon.h>
+#include <linux/of.h>
 #include <linux/of_device.h>
+#include <linux/of_address.h>
 #include <linux/platform_device.h>
 #include <linux/pm_domain.h>
 #include <linux/regmap.h>
 #include <linux/soc/mediatek/infracfg.h>
+#include <linux/soc/mediatek/scpsys.h>
 #include <dt-bindings/power/mt8173-power.h>
 
+#define SPM_POWERON_CONFIG_SET		0x0000
+#define SPM_CA7_CPU0_PWR_CON		0x0200
 #define SPM_VDE_PWR_CON			0x0210
 #define SPM_MFG_PWR_CON			0x0214
+#define SPM_CA7_CPU1_PWR_CON		0x0218
+#define SPM_CA7_CPU2_PWR_CON		0x021c
+#define SPM_CA7_CPU3_PWR_CON		0x0220
 #define SPM_VEN_PWR_CON			0x0230
 #define SPM_ISP_PWR_CON			0x0238
 #define SPM_DIS_PWR_CON			0x023c
+#define SPM_CA7_CPU0_L1_PDN		0x025c
+#define SPM_CA7_CPU1_L1_PDN		0x0264
+#define SPM_CA7_CPU2_L1_PDN		0x026c
+#define SPM_CA7_CPU3_L1_PDN		0x0274
 #define SPM_VEN2_PWR_CON		0x0298
 #define SPM_AUDIO_PWR_CON		0x029c
 #define SPM_MFG_2D_PWR_CON		0x02c0
@@ -34,12 +46,20 @@
 #define SPM_USB_PWR_CON			0x02cc
 #define SPM_PWR_STATUS			0x060c
 #define SPM_PWR_STATUS_2ND		0x0610
+#define SPM_SLEEP_TIMER_STA		0x0720
 
+/* bit definition in SPM_CA7_CPUx_PWR_CON */
 #define PWR_RST_B_BIT			BIT(0)
 #define PWR_ISO_BIT			BIT(1)
 #define PWR_ON_BIT			BIT(2)
 #define PWR_ON_2ND_BIT			BIT(3)
 #define PWR_CLK_DIS_BIT			BIT(4)
+#define SRAM_CKISO_BIT			BIT(5)
+#define SRAM_ISOINT_B_BIT		BIT(6)
+
+/* bit definition in SPM_CA7_CPUx_L1_PDN */
+#define L1_PDN				BIT(0)
+#define L1_PDN_ACK			BIT(8)
 
 #define PWR_STATUS_DISP			BIT(3)
 #define PWR_STATUS_MFG			BIT(4)
@@ -52,6 +72,28 @@
 #define PWR_STATUS_AUDIO		BIT(24)
 #define PWR_STATUS_USB			BIT(25)
 
+#define MT6580_MAX_CPUS			4
+
+#ifdef CONFIG_SMP
+static DEFINE_SPINLOCK(spm_cpu_lock);
+
+static void __iomem *spm_cpu_base;
+
+static const u32 spm_cpu_pwr_con[MT6580_MAX_CPUS] = {
+	SPM_CA7_CPU0_PWR_CON,
+	SPM_CA7_CPU1_PWR_CON,
+	SPM_CA7_CPU2_PWR_CON,
+	SPM_CA7_CPU3_PWR_CON,
+};
+
+static const u32 spm_cpu_l1_pdn[MT6580_MAX_CPUS] = {
+	SPM_CA7_CPU0_L1_PDN,
+	SPM_CA7_CPU1_L1_PDN,
+	SPM_CA7_CPU2_L1_PDN,
+	SPM_CA7_CPU3_L1_PDN,
+};
+#endif
+
 enum clk_id {
 	MT8173_CLK_MM,
 	MT8173_CLK_MFG,
@@ -485,3 +527,211 @@ static struct platform_driver scpsys_drv = {
 };
 
 module_platform_driver_probe(scpsys_drv, scpsys_probe);
+
+#define SPM_REGWR_EN		BIT(0)
+#define SPM_PROJECT_CODE	0x0B16
+
+#ifdef CONFIG_SMP
+int spm_cpu_mtcmos_on(int cpu)
+{
+	unsigned long flags;
+	static u32 spmcpu_pwr_con, spmcpu_l1_pdn;
+	unsigned int cbit, temp;
+	int timeout = 10;
+	int ret = 0;
+
+	temp = (SPM_PROJECT_CODE << 16) | SPM_REGWR_EN;
+	writel_relaxed(temp, spm_cpu_base + SPM_POWERON_CONFIG_SET);
+
+	spmcpu_pwr_con = spm_cpu_pwr_con[cpu];
+	spmcpu_l1_pdn = spm_cpu_l1_pdn[cpu];
+
+	spin_lock_irqsave(&spm_cpu_lock, flags);
+
+	/* Set PWR_ON */
+	temp = readl_relaxed(spm_cpu_base + spmcpu_pwr_con);
+	temp |= PWR_ON_BIT;
+	writel_relaxed(temp, spm_cpu_base + spmcpu_pwr_con);
+
+	/* Wait for charging core power */
+	udelay(1);
+
+	/* Set PWR_ON_2ND */
+	temp = readl_relaxed(spm_cpu_base + spmcpu_pwr_con);
+	temp |= PWR_ON_2ND_BIT;
+	writel_relaxed(temp, spm_cpu_base + spmcpu_pwr_con);
+
+	/* Wait for the power-ack */
+	cbit = BIT(13 - cpu);
+	while (((readl_relaxed(spm_cpu_base + SPM_PWR_STATUS) &
+		 cbit) != cbit) ||
+	       (readl_relaxed(spm_cpu_base + SPM_PWR_STATUS_2ND) &
+		 cbit) != cbit) {
+		if (--timeout == 0) {
+			ret = -ENXIO;
+			goto fail;
+		}
+		udelay(1);
+	}
+
+	temp = readl_relaxed(spm_cpu_base + spmcpu_pwr_con);
+	temp &= ~PWR_ISO_BIT;
+	writel_relaxed(temp, spm_cpu_base + spmcpu_pwr_con);
+
+	/* L1 power on */
+	temp = readl_relaxed(spm_cpu_base + spmcpu_l1_pdn);
+	temp &= ~L1_PDN;
+	writel_relaxed(temp, spm_cpu_base + spmcpu_l1_pdn);
+	timeout = 10;
+	while ((readl_relaxed(spm_cpu_base + spmcpu_l1_pdn) &
+		L1_PDN_ACK) != 0) {
+		if (--timeout == 0) {
+			ret = -ENXIO;
+			goto fail;
+		}
+		udelay(1);
+	}
+
+	/* Wait for memory power ready */
+	udelay(1);
+
+	/* Set SRAM_ISOINT_B */
+	temp = readl_relaxed(spm_cpu_base + spmcpu_pwr_con);
+	temp |= SRAM_ISOINT_B_BIT;
+	writel_relaxed(temp, spm_cpu_base + spmcpu_pwr_con);
+
+	/* Clear SRAM_CKISO */
+	temp = readl_relaxed(spm_cpu_base + spmcpu_pwr_con);
+	temp &= ~SRAM_CKISO_BIT;
+	writel_relaxed(temp, spm_cpu_base + spmcpu_pwr_con);
+
+	/* Clear PWR_CLK_DIS */
+	temp = readl_relaxed(spm_cpu_base + spmcpu_pwr_con);
+	temp &= ~PWR_CLK_DIS_BIT;
+	writel_relaxed(temp, spm_cpu_base + spmcpu_pwr_con);
+
+	/* Set PWR_RST_B to finish power on and reset sequences */
+	temp = readl_relaxed(spm_cpu_base + spmcpu_pwr_con);
+	temp |= PWR_RST_B_BIT;
+	writel_relaxed(temp, spm_cpu_base + spmcpu_pwr_con);
+fail:
+	spin_unlock_irqrestore(&spm_cpu_lock, flags);
+
+	return ret;
+}
+
+int spm_cpu_mtcmos_off(int cpu, bool wfi)
+{
+	unsigned long flags;
+	static u32 spmcpu_pwr_con, spmcpu_l1_pdn;
+	unsigned int cbit, temp;
+	int timeout = 10;
+	int ret = 0;
+
+	temp = (SPM_PROJECT_CODE << 16) | SPM_REGWR_EN;
+	writel_relaxed(temp, spm_cpu_base + SPM_POWERON_CONFIG_SET);
+
+	spmcpu_pwr_con = spm_cpu_pwr_con[cpu];
+	spmcpu_l1_pdn = spm_cpu_l1_pdn[cpu];
+
+	if (wfi) {
+		while ((readl_relaxed(spm_cpu_base + SPM_SLEEP_TIMER_STA) &
+			(1U << (16 + cpu))) == 0) {
+			if (--timeout == 0)
+				return -ENXIO;
+			udelay(1);
+		}
+	}
+
+	spin_lock_irqsave(&spm_cpu_lock, flags);
+
+	/* Set PWR_ISO */
+	temp = readl_relaxed(spm_cpu_base + spmcpu_pwr_con);
+	temp |= PWR_ISO_BIT;
+	writel_relaxed(temp, spm_cpu_base + spmcpu_pwr_con);
+
+	/* Set SRAM_CKISO */
+	temp = readl_relaxed(spm_cpu_base + spmcpu_pwr_con);
+	temp |= SRAM_CKISO_BIT;
+	writel_relaxed(temp, spm_cpu_base + spmcpu_pwr_con);
+
+	/* Clear SRAM_ISOINT_B */
+	temp = readl_relaxed(spm_cpu_base + spmcpu_pwr_con);
+	temp &= ~SRAM_ISOINT_B_BIT;
+	writel_relaxed(temp, spm_cpu_base + spmcpu_pwr_con);
+
+	/* L1 power off */
+	temp = readl_relaxed(spm_cpu_base + spmcpu_l1_pdn);
+	temp |= L1_PDN;
+	writel_relaxed(temp, spm_cpu_base + spmcpu_l1_pdn);
+	timeout = 10;
+	while ((readl_relaxed(spm_cpu_base + spmcpu_l1_pdn) &
+		L1_PDN_ACK) != L1_PDN_ACK) {
+		if (--timeout == 0) {
+			ret = -ENXIO;
+			goto fail;
+		}
+		udelay(1);
+	}
+
+	/* Clear PWR_RST_B */
+	temp = readl_relaxed(spm_cpu_base + spmcpu_pwr_con);
+	temp &= ~PWR_RST_B_BIT;
+	writel_relaxed(temp, spm_cpu_base + spmcpu_pwr_con);
+
+	/* Set PWR_CLK_DIS */
+	temp = readl_relaxed(spm_cpu_base + spmcpu_pwr_con);
+	temp |= PWR_CLK_DIS_BIT;
+	writel_relaxed(temp, spm_cpu_base + spmcpu_pwr_con);
+
+	/* Clear PWR_ON */
+	temp = readl_relaxed(spm_cpu_base + spmcpu_pwr_con);
+	temp &= ~PWR_ON_BIT;
+	writel_relaxed(temp, spm_cpu_base + spmcpu_pwr_con);
+
+	/* Clear PWR_ON_2ND */
+	temp = readl_relaxed(spm_cpu_base + spmcpu_pwr_con);
+	temp &= ~PWR_ON_2ND_BIT;
+	writel_relaxed(temp, spm_cpu_base + spmcpu_pwr_con);
+
+	timeout = 10;
+	cbit = BIT(13 - cpu);
+	while (((readl_relaxed(spm_cpu_base + SPM_PWR_STATUS) & cbit) != 0) ||
+	       ((readl_relaxed(spm_cpu_base + SPM_PWR_STATUS_2ND) &
+		 cbit) != 0)) {
+		if (--timeout == 0) {
+			ret = -ENXIO;
+			goto fail;
+		}
+		udelay(1);
+	}
+fail:
+	spin_unlock_irqrestore(&spm_cpu_lock, flags);
+
+	return ret;
+}
+#endif /* CONFIG_SMP */
+
+static int __init mtk_scpsys_early_init(void)
+{
+	struct device_node *node;
+	struct resource regs;
+
+	node = of_find_compatible_node(NULL, NULL, "mediatek,mt6580-scpsys");
+	if (node) {
+		if (of_address_to_resource(node, 0, &regs) < 0) {
+			pr_err("Failed to get SCPSYS registers\n");
+			return -ENXIO;
+		}
+
+		spm_cpu_base = ioremap_nocache(regs.start,
+					       resource_size(&regs));
+		if (!spm_cpu_base) {
+			pr_err("%s: Unable to map I/O memory\n", __func__);
+			return -ENODEV;
+		}
+	}
+
+	return 0;
+}
+early_initcall(mtk_scpsys_early_init);
diff --git a/include/linux/soc/mediatek/scpsys.h b/include/linux/soc/mediatek/scpsys.h
new file mode 100644
index 0000000..a14b7a3
--- /dev/null
+++ b/include/linux/soc/mediatek/scpsys.h
@@ -0,0 +1,9 @@
+#ifndef __SOC_MEDIATEK_SCPSYS_H
+#define __SOC_MEDIATEK_SCPSYS_H
+
+#include <linux/kernel.h>
+
+int spm_cpu_mtcmos_on(int cpu);
+int spm_cpu_mtcmos_off(int cpu, bool wfi);
+
+#endif
-- 
1.7.9.5



From robin.murphy at arm.com  Tue Aug  4 07:47:13 2015
From: robin.murphy at arm.com (Robin Murphy)
Date: Tue, 04 Aug 2015 15:47:13 +0100
Subject: [PATCH 05/13] iommu/io-pgtable-arm: Allow appropriate DMA API use
In-Reply-To: <1652248.uq2uhTW4Yd@avalon>
References: <1438608355-7335-1-git-send-email-will.deacon@arm.com>
 <1438608355-7335-6-git-send-email-will.deacon@arm.com>
 <1652248.uq2uhTW4Yd@avalon>
Message-ID: <55C0D071.1040104@arm.com>

Hi Laurent,

[ +RMK, as his patch is indirectly involved here ]

On 04/08/15 14:16, Laurent Pinchart wrote:
> Hi Will and Robin,
>
> Thank you for the patch.
>
> On Monday 03 August 2015 14:25:47 Will Deacon wrote:
>> From: Robin Murphy <Robin.Murphy at arm.com>
>>
>> Currently, users of the LPAE page table code are (ab)using dma_map_page()
>> as a means to flush page table updates for non-coherent IOMMUs. Since
>> from the CPU's point of view, creating IOMMU page tables *is* passing
>> DMA buffers to a device (the IOMMU's page table walker), there's little
>> reason not to use the DMA API correctly.
>>
>> Allow IOMMU drivers to opt into DMA API operations for page table
>> allocation and updates by providing their appropriate device pointer.
>> The expectation is that an LPAE IOMMU should have a full view of system
>> memory, so use streaming mappings to avoid unnecessary pressure on
>> ZONE_DMA, and treat any DMA translation as a warning sign.
>
> I like the idea of doing this in core code rather than in individual drivers,
> but I believe we're not using the right API. Please see below.

Perhaps this could have one of my trademark "for now"s - the aim of this 
series is really just to stop the per-driver hacks proliferating, as per 
Russell's comment[1]. I left the semi-artificial DMA==phys restriction 
for expediency, since it follows the current usage and keeps the code 
changes minimal. With this series in place I'd be happy to go back and 
try a full-blown DMA conversion if and when a real need shows up, but I 
think it would significantly complicate all the current software page 
table walking.

>> Signed-off-by: Robin Murphy <robin.murphy at arm.com>
>> Signed-off-by: Will Deacon <will.deacon at arm.com>
>> ---
>>   drivers/iommu/Kconfig          |   3 +-
>>   drivers/iommu/io-pgtable-arm.c | 107 +++++++++++++++++++++++++++++---------
>>   drivers/iommu/io-pgtable.h     |   3 ++
>>   3 files changed, 89 insertions(+), 24 deletions(-)
>>
>> diff --git a/drivers/iommu/Kconfig b/drivers/iommu/Kconfig
>> index f1fb1d3ccc56..d77a848d50de 100644
>> --- a/drivers/iommu/Kconfig
>> +++ b/drivers/iommu/Kconfig
>> @@ -23,7 +23,8 @@ config IOMMU_IO_PGTABLE
>>   config IOMMU_IO_PGTABLE_LPAE
>>   	bool "ARMv7/v8 Long Descriptor Format"
>>   	select IOMMU_IO_PGTABLE
>> -	depends on ARM || ARM64 || COMPILE_TEST
>> +	# SWIOTLB guarantees a dma_to_phys() implementation
>> +	depends on ARM || ARM64 || (COMPILE_TEST && SWIOTLB)
>>   	help
>>   	  Enable support for the ARM long descriptor pagetable format.
>>   	  This allocator supports 4K/2M/1G, 16K/32M and 64K/512M page
>> diff --git a/drivers/iommu/io-pgtable-arm.c b/drivers/iommu/io-pgtable-arm.c
>> index 4e460216bd16..28cca8a652f9 100644
>> --- a/drivers/iommu/io-pgtable-arm.c
>> +++ b/drivers/iommu/io-pgtable-arm.c
>> @@ -200,12 +200,76 @@ typedef u64 arm_lpae_iopte;
>>
>>   static bool selftest_running = false;
>>
>> +static dma_addr_t __arm_lpae_dma_addr(struct device *dev, void *pages)
>> +{
>> +	return phys_to_dma(dev, virt_to_phys(pages));
>> +}
>> +
>> +static void *__arm_lpae_alloc_pages(size_t size, gfp_t gfp,
>> +				    struct io_pgtable_cfg *cfg)
>> +{
>> +	struct device *dev = cfg->iommu_dev;
>> +	dma_addr_t dma;
>> +	void *pages = alloc_pages_exact(size, gfp | __GFP_ZERO);
>> +
>> +	if (!pages)
>> +		return NULL;
>> +
>> +	if (dev) {
>> +		dma = dma_map_single(dev, pages, size, DMA_TO_DEVICE);
>> +		if (dma_mapping_error(dev, dma))
>> +			goto out_free;
>> +		/*
>> +		 * We depend on the IOMMU being able to work with any physical
>> +		 * address directly, so if the DMA layer suggests it can't by
>> +		 * giving us back some translation, that bodes very badly...
>> +		 */
>> +		if (dma != __arm_lpae_dma_addr(dev, pages))
>> +			goto out_unmap;
>
> Why do we need to create a mapping at all then ? Because
> dma_sync_single_for_device() requires it ?

We still need to expose this new table to the device. If we never update 
it, we'll never have reason to call dma_sync_, but we definitely want 
the IOMMU to know there's a page of invalid PTEs there.

>> +	}
>> +
>> +	return pages;
>> +
>> +out_unmap:
>> +	dev_err(dev, "Cannot accommodate DMA translation for IOMMU page
>> tables\n");
>> +	dma_unmap_single(dev, dma, size, DMA_TO_DEVICE);
>> +out_free:
>> +	free_pages_exact(pages, size);
>> +	return NULL;
>> +}
>> +
>> +static void __arm_lpae_free_pages(void *pages, size_t size,
>> +				  struct io_pgtable_cfg *cfg)
>> +{
>> +	struct device *dev = cfg->iommu_dev;
>> +
>> +	if (dev)
>> +		dma_unmap_single(dev, __arm_lpae_dma_addr(dev, pages),
>> +				 size, DMA_TO_DEVICE);
>> +	free_pages_exact(pages, size);
>> +}
>> +
>> +static void __arm_lpae_set_pte(arm_lpae_iopte *ptep, arm_lpae_iopte pte,
>> +			       struct io_pgtable_cfg *cfg, void *cookie)
>> +{
>> +	struct device *dev = cfg->iommu_dev;
>> +
>> +	*ptep = pte;
>> +
>> +	if (dev)
>> +		dma_sync_single_for_device(dev, __arm_lpae_dma_addr(dev, ptep),
>> +					   sizeof(pte), DMA_TO_DEVICE);
>
> This is what I believe to be an API abuse. The dma_sync_single_for_device()
> API is meant to pass ownership of a buffer to the device. Unless I'm mistaken,
> once that's done the CPU isn't allowed to touch the buffer anymore until
> dma_sync_single_for_cpu() is called to get ownership of the buffer back. Sure,
> it might work on many ARM systems, but we really should be careful not to use
> APIs as delicate as DMA mapping and cache handling for purposes different than
> what they explicitly allow.
>
> It might be that I'm wrong and that the streaming DMA API allows this exact
> kind of usage, but I haven't found a clear indication of that in the
> documentation. It could also be that all implementations would support it
> today, and that we would then consider it should be explicitly allowed by the
> API. In both cases a documentation patch would be welcome.

TBH, I was largely going by Russell's Tegra patch, which similarly 
elides any sync_*_for_cpu. In reality, since everything is DMA_TO_DEVICE 
and the IOMMU itself can't modify the page tables[3], I can't think of 
any situation where sync_*_for_cpu would actually do anything.

 From reading this part of DMA-API.txt:

   Notes:  You must do this:

   - Before reading values that have been written by DMA from the device
     (use the DMA_FROM_DEVICE direction)
   - After writing values that will be written to the device using DMA
     (use the DMA_TO_DEVICE) direction
   - before *and* after handing memory to the device if the memory is
     DMA_BIDIRECTIONAL

I would conclude that since a sync using DMA_TO_DEVICE *before* writing 
is not a "must", then it's probably unnecessary.

Robin.

[1]:http://article.gmane.org/gmane.linux.kernel/2005551
[2]:http://article.gmane.org/gmane.linux.ports.tegra/23150
[3]:Yes, there may generally be exceptions to that, but not in the 
context of this code. Unless the Renesas IPMMU does something I don't 
know about?



From moritz.fischer at ettus.com  Tue Aug  4 08:05:36 2015
From: moritz.fischer at ettus.com (Moritz Fischer)
Date: Tue, 4 Aug 2015 08:05:36 -0700
Subject: [RFCv3 1/4] docs: dts: Added documentation for Xilinx Zynq Reset
 Controller bindings.
In-Reply-To: <1438675772.3793.18.camel@pengutronix.de>
References: <1438305237-18497-1-git-send-email-moritz.fischer@ettus.com>
 <1438305237-18497-2-git-send-email-moritz.fischer@ettus.com>
 <1438675772.3793.18.camel@pengutronix.de>
Message-ID: <CAAtXAHeauiD5smAqMbheJWuv4BT-2YqJWOSBjYPq900icpT1Rg@mail.gmail.com>

Hi Philip,

On Tue, Aug 4, 2015 at 1:09 AM, Philipp Zabel <p.zabel at pengutronix.de> wrote:
> Hi Moritz,
>
> Am Donnerstag, den 30.07.2015, 18:13 -0700 schrieb Moritz Fischer:
>> Signed-off-by: Moritz Fischer <moritz.fischer at ettus.com>
>> ---
>>  .../devicetree/bindings/reset/zynq-reset.txt       | 68 ++++++++++++++++++++++
>>  1 file changed, 68 insertions(+)
>>  create mode 100644 Documentation/devicetree/bindings/reset/zynq-reset.txt
>>
>> diff --git a/Documentation/devicetree/bindings/reset/zynq-reset.txt b/Documentation/devicetree/bindings/reset/zynq-reset.txt
>> new file mode 100644
>> index 0000000..498c037a
>> --- /dev/null
>> +++ b/Documentation/devicetree/bindings/reset/zynq-reset.txt
>> @@ -0,0 +1,68 @@
>> +Xilinx Zynq Reset Manager
>> +
>> +The Zynq AP-SoC has several different resets.
>> +
>> +See Chapter 26 of the Zynq TRM (UG585) for more information about Zynq resets.
>> +
>> +Required properties:
>> +- compatible: "xlnx,zynq-reset"
>> +- reg: SLCR offset and size taken via syscon <0x200 0x48>
>> +- syscon: <&slcr>
>> +  This should be a phandle to the Zynq's SLCR register.
>
>                                                  ^ register singular?
Do you want me to resend the entire set, or are you cool with just git
amending the 's' for registers?

> I still think the syscon phandle property is superfluous,
> but I'm fine with keeping it for consistency.

Thanks.
> It could always be made optional later.
>
>> +- #reset-cells: Must be 1
>> +
>> +The Zynq Reset Manager needs to be a childnode of the SLCR.
>> +
>> +Example:
>> +     rstc: rstc at 200 {
>> +             compatible = "xlnx,zynq-reset";
>> +             reg = <0x200 0x48>;
>> +             #reset-cells = <1>;
>> +             syscon = <&slcr>;
>> +     };
>> +
>> +Reset outputs:
>> + 0  : soft reset
>> + 32 : ddr reset
>> + 64 : topsw reset
>> + 96 : dmac reset
>> + 128: usb0 reset
>> + 129: usb1 reset
>> + 160: gem0 reset
>> + 161: gem1 reset
>> + 164: gem0 rx reset
>> + 165: gem1 rx reset
>> + 166: gem0 ref reset
>> + 167: gem1 ref reset
>> + 192: sdio0 reset
>> + 193: sdio1 reset
>> + 196: sdio0 ref reset
>> + 197: sdio1 ref reset
>> + 224: spi0 reset
>> + 225: spi1 reset
>> + 226: spi0 ref reset
>> + 227: spi1 ref reset
>> + 256: can0 reset
>> + 257: can1 reset
>> + 258: can0 ref reset
>> + 259: can1 ref reset
>> + 288: i2c0 reset
>> + 289: i2c1 reset
>> + 320: uart0 reset
>> + 321: uart1 reset
>> + 322: uart0 ref reset
>> + 323: uart1 ref reset
>> + 352: gpio reset
>> + 384: lqspi reset
>> + 385: qspi ref reset
>> + 416: smc reset
>> + 417: smc ref reset
>> + 448: ocm reset
>> + 512: fpga0 out reset
>> + 513: fpga1 out reset
>> + 514: fpga2 out reset
>> + 515: fpga3 out reset
>> + 544: a9 reset 0
>> + 545: a9 reset 1
>> + 552: peri reset
>> +
>
> regards
> Philipp
>

Cheers,

Moritz


From wcohen at redhat.com  Tue Aug  4 08:07:43 2015
From: wcohen at redhat.com (William Cohen)
Date: Tue, 4 Aug 2015 11:07:43 -0400
Subject: [RFC PATCH V2 00/10] ARM64: Uprobe support added
In-Reply-To: <55BF707F.7020208@linaro.org>
References: <cover.1434598237.git.panand@redhat.com>
 <20150803110908.GC10501@arm.com> <55BF7019.9080007@linaro.org>
 <55BF707F.7020208@linaro.org>
Message-ID: <55C0D53F.6080403@redhat.com>

On 08/03/2015 09:45 AM, David Long wrote:
> On 08/03/15 09:43, David Long wrote:
>> On 08/03/15 07:09, Will Deacon wrote:
>>> On Thu, Jun 18, 2015 at 04:58:47AM +0100, Pratyush Anand wrote:
>>>> These patches have been prepared on top of ARM64 kprobe v7 patches [1].
>>>> Keeping as RFC, because kprobe-v7 still need to be ACKed.
>>>
>>> Unfortunately, I've not seen any movement on the kprobes patches
>>> recently,
>>> so this is out of the picture for 4.3.
>>>
>>> Dave: did you plan to respin your series after Steve's comments on v7?
>>>
>>> Will
>>>
>>
>> Catalin's comments last week helped me clarify in my own mind that we
>> should be able to simplfy the register pushing somewhat. Will, does that
>> also make sense to you?
>>
> 
> ^^ That question was aimed at Will Cohen, just to clarify.

Hi Dave,

The suggestion to only save the caller saved registers would make the save and restore code shorter and faster.  There would be cases reduced saved and restore could be visible to systemtap scripts using print_reg() and register() functions such when  a call to a return probed function is followed by a call to a function with a kprobe on entry.  I worry about cases where code is broken (not following the calling conventions maybe assembly code functions) and using a return probe causes things to fail in a different way making it more difficult to diagnose the problem.  There are less than 50 "*.S" files for arm64, but I prefer to minimize the chances that the return probe changes something.

There is room for improvements for the patch.  The magic offset numbers in the save restore code could be eliminated.

-Will

> 
>> So, also taking into consideration Steve's suggestions about
>> reorganizing the asm code, I am now working on a new revision.
>>
>> -dl
>>
> 



From p.zabel at pengutronix.de  Tue Aug  4 08:10:17 2015
From: p.zabel at pengutronix.de (Philipp Zabel)
Date: Tue, 04 Aug 2015 17:10:17 +0200
Subject: [RFCv3 1/4] docs: dts: Added documentation for Xilinx Zynq
 Reset Controller bindings.
In-Reply-To: <CAAtXAHeauiD5smAqMbheJWuv4BT-2YqJWOSBjYPq900icpT1Rg@mail.gmail.com>
References: <1438305237-18497-1-git-send-email-moritz.fischer@ettus.com>
 <1438305237-18497-2-git-send-email-moritz.fischer@ettus.com>
 <1438675772.3793.18.camel@pengutronix.de>
 <CAAtXAHeauiD5smAqMbheJWuv4BT-2YqJWOSBjYPq900icpT1Rg@mail.gmail.com>
Message-ID: <1438701017.3793.45.camel@pengutronix.de>

Hi Moritz,

Am Dienstag, den 04.08.2015, 08:05 -0700 schrieb Moritz Fischer:
> Hi Philip,
> 
> On Tue, Aug 4, 2015 at 1:09 AM, Philipp Zabel <p.zabel at pengutronix.de> wrote:
> > Hi Moritz,
> >
> > Am Donnerstag, den 30.07.2015, 18:13 -0700 schrieb Moritz Fischer:
[...]
> >> +Required properties:
> >> +- compatible: "xlnx,zynq-reset"
> >> +- reg: SLCR offset and size taken via syscon <0x200 0x48>
> >> +- syscon: <&slcr>
> >> +  This should be a phandle to the Zynq's SLCR register.
> >
> >                                                  ^ register singular?
> Do you want me to resend the entire set, or are you cool with just git
> amending the 's' for registers?

Amended and applied, thanks.

regards
Philipp



From linux at arm.linux.org.uk  Tue Aug  4 07:56:42 2015
From: linux at arm.linux.org.uk (Russell King - ARM Linux)
Date: Tue, 4 Aug 2015 15:56:42 +0100
Subject: [PATCH 05/13] iommu/io-pgtable-arm: Allow appropriate DMA API use
In-Reply-To: <55C0D071.1040104@arm.com>
References: <1438608355-7335-1-git-send-email-will.deacon@arm.com>
 <1438608355-7335-6-git-send-email-will.deacon@arm.com>
 <1652248.uq2uhTW4Yd@avalon> <55C0D071.1040104@arm.com>
Message-ID: <20150804145642.GQ7557@n2100.arm.linux.org.uk>

On Tue, Aug 04, 2015 at 03:47:13PM +0100, Robin Murphy wrote:
> Hi Laurent,
> 
> [ +RMK, as his patch is indirectly involved here ]
> 
> On 04/08/15 14:16, Laurent Pinchart wrote:
> >This is what I believe to be an API abuse. The dma_sync_single_for_device()
> >API is meant to pass ownership of a buffer to the device. Unless I'm mistaken,
> >once that's done the CPU isn't allowed to touch the buffer anymore until
> >dma_sync_single_for_cpu() is called to get ownership of the buffer back.

That's what I thought up until recently, but it's not strictly true - see
Documentation/DMA-API.txt which Robin quoted.

> [3]:Yes, there may generally be exceptions to that, but not in the context
> of this code. Unless the Renesas IPMMU does something I don't know about?

If an IOMMU does write to its page tables, then the only way to handle
those is using DMA-coherent memory, either via a coherent mapping or
allocated via dma_alloc_coherent().  The streaming DMA API is wholely
unsuitable for any mapping where both the CPU and DMA device both want
to simultaneously alter the contained data.

-- 
FTTC broadband for 0.8mile line: currently at 10.5Mbps down 400kbps up
according to speedtest.net.


From raghumag at gmail.com  Tue Aug  4 08:24:27 2015
From: raghumag at gmail.com (raghu MG)
Date: Tue, 4 Aug 2015 20:54:27 +0530
Subject: GPIO interrupts on ARMADAXP GP board
Message-ID: <CAG1O52XxwAZgOnd6on_mo+EmPtR1TSiWAfoB2DH658p2tZchqw@mail.gmail.com>

Hello,

I am working on a card which as GPIOs connected to external I/O's. The
board consists of ARMADAXP 78460 host cpu.

Board currently runs Linux-4.1 with modified  armada-xp-gp.dtb for ArmadaXP.
I enabled "orion-gpio" driver to initialize GPIOs as given in armada-xp-mv78460.


The driver while initializing calls irq_domain_add_simple which throws
up following warning
"irq: Cannot allocate irq_descs @ IRQ47, assuming pre-allocated"
The warning repeats for next set(32-63  & 64-66).

Also the GPIO IRQs are not getting listed in cat /proc/interrupts

My understanding is GPIO interrupts are not getting registered . As
per DTS file the following GPIO interrupts should be registered
82,83,84,85,87,88,89,90,91

But none of them are registered nor the irq handler is getting invoked.

Please suggest some fix to this problem.
Regards


From marc.zyngier at arm.com  Tue Aug  4 08:27:03 2015
From: marc.zyngier at arm.com (Marc Zyngier)
Date: Tue, 04 Aug 2015 16:27:03 +0100
Subject: [PATCH v3 06/11] KVM: arm/arm64: vgic: Allow dynamic mapping
 of physical/virtual interrupts
In-Reply-To: <20150804130457.GA29335@cbox>
References: <1437753309-17989-1-git-send-email-marc.zyngier@arm.com>
 <1437753309-17989-7-git-send-email-marc.zyngier@arm.com>
 <20150804130457.GA29335@cbox>
Message-ID: <55C0D9C7.7060707@arm.com>

On 04/08/15 14:04, Christoffer Dall wrote:
> On Fri, Jul 24, 2015 at 04:55:04PM +0100, Marc Zyngier wrote:
>> In order to be able to feed physical interrupts to a guest, we need
>> to be able to establish the virtual-physical mapping between the two
>> worlds.
>>
>> The mappings are kept in a set of RCU lists, indexed by virtual interrupts.
>>
>> Signed-off-by: Marc Zyngier <marc.zyngier at arm.com>
>> ---
>>  arch/arm/kvm/arm.c     |   2 +
>>  include/kvm/arm_vgic.h |  26 +++++++
>>  virt/kvm/arm/vgic.c    | 189 ++++++++++++++++++++++++++++++++++++++++++++++++-
>>  3 files changed, 216 insertions(+), 1 deletion(-)
>>
>> diff --git a/arch/arm/kvm/arm.c b/arch/arm/kvm/arm.c
>> index f1bf418..ce404a5 100644
>> --- a/arch/arm/kvm/arm.c
>> +++ b/arch/arm/kvm/arm.c
>> @@ -125,6 +125,7 @@ int kvm_arch_init_vm(struct kvm *kvm, unsigned long type)
>>       if (ret)
>>               goto out_free_stage2_pgd;
>>
>> +     kvm_vgic_early_init(kvm);
>>       kvm_timer_init(kvm);
>>
>>       /* Mark the initial VMID generation invalid */
>> @@ -249,6 +250,7 @@ out:
>>
>>  void kvm_arch_vcpu_postcreate(struct kvm_vcpu *vcpu)
>>  {
>> +     kvm_vgic_vcpu_early_init(vcpu);
>>  }
>>
>>  void kvm_arch_vcpu_free(struct kvm_vcpu *vcpu)
>> diff --git a/include/kvm/arm_vgic.h b/include/kvm/arm_vgic.h
>> index a881e39..68212a1 100644
>> --- a/include/kvm/arm_vgic.h
>> +++ b/include/kvm/arm_vgic.h
>> @@ -159,6 +159,20 @@ struct vgic_io_device {
>>       struct kvm_io_device dev;
>>  };
>>
>> +struct irq_phys_map {
>> +     u32                     virt_irq;
>> +     u32                     phys_irq;
>> +     u32                     irq;
>> +     bool                    deleted;
>> +     bool                    active;
>> +};
>> +
>> +struct irq_phys_map_entry {
>> +     struct list_head        entry;
>> +     struct rcu_head         rcu;
>> +     struct irq_phys_map     map;
>> +};
>> +
>>  struct vgic_dist {
>>       spinlock_t              lock;
>>       bool                    in_kernel;
>> @@ -256,6 +270,10 @@ struct vgic_dist {
>>       struct vgic_vm_ops      vm_ops;
>>       struct vgic_io_device   dist_iodev;
>>       struct vgic_io_device   *redist_iodevs;
>> +
>> +     /* Virtual irq to hwirq mapping */
>> +     spinlock_t              irq_phys_map_lock;
>> +     struct list_head        irq_phys_map_list;
>>  };
>>
>>  struct vgic_v2_cpu_if {
>> @@ -307,6 +325,9 @@ struct vgic_cpu {
>>               struct vgic_v2_cpu_if   vgic_v2;
>>               struct vgic_v3_cpu_if   vgic_v3;
>>       };
>> +
>> +     /* Protected by the distributor's irq_phys_map_lock */
>> +     struct list_head        irq_phys_map_list;
>>  };
>>
>>  #define LR_EMPTY     0xff
>> @@ -321,8 +342,10 @@ int kvm_vgic_addr(struct kvm *kvm, unsigned long type, u64 *addr, bool write);
>>  int kvm_vgic_hyp_init(void);
>>  int kvm_vgic_map_resources(struct kvm *kvm);
>>  int kvm_vgic_get_max_vcpus(void);
>> +void kvm_vgic_early_init(struct kvm *kvm);
>>  int kvm_vgic_create(struct kvm *kvm, u32 type);
>>  void kvm_vgic_destroy(struct kvm *kvm);
>> +void kvm_vgic_vcpu_early_init(struct kvm_vcpu *vcpu);
>>  void kvm_vgic_vcpu_destroy(struct kvm_vcpu *vcpu);
>>  void kvm_vgic_flush_hwstate(struct kvm_vcpu *vcpu);
>>  void kvm_vgic_sync_hwstate(struct kvm_vcpu *vcpu);
>> @@ -331,6 +354,9 @@ int kvm_vgic_inject_irq(struct kvm *kvm, int cpuid, unsigned int irq_num,
>>  void vgic_v3_dispatch_sgi(struct kvm_vcpu *vcpu, u64 reg);
>>  int kvm_vgic_vcpu_pending_irq(struct kvm_vcpu *vcpu);
>>  int kvm_vgic_vcpu_active_irq(struct kvm_vcpu *vcpu);
>> +struct irq_phys_map *kvm_vgic_map_phys_irq(struct kvm_vcpu *vcpu,
>> +                                        int virt_irq, int irq);
>> +int kvm_vgic_unmap_phys_irq(struct kvm_vcpu *vcpu, struct irq_phys_map *map);
>>
>>  #define irqchip_in_kernel(k) (!!((k)->arch.vgic.in_kernel))
>>  #define vgic_initialized(k)  (!!((k)->arch.vgic.nr_cpus))
>> diff --git a/virt/kvm/arm/vgic.c b/virt/kvm/arm/vgic.c
>> index 5bd1695..c74d929 100644
>> --- a/virt/kvm/arm/vgic.c
>> +++ b/virt/kvm/arm/vgic.c
>> @@ -24,6 +24,7 @@
>>  #include <linux/of.h>
>>  #include <linux/of_address.h>
>>  #include <linux/of_irq.h>
>> +#include <linux/rculist.h>
>>  #include <linux/uaccess.h>
>>
>>  #include <asm/kvm_emulate.h>
>> @@ -82,6 +83,8 @@ static void vgic_retire_disabled_irqs(struct kvm_vcpu *vcpu);
>>  static void vgic_retire_lr(int lr_nr, int irq, struct kvm_vcpu *vcpu);
>>  static struct vgic_lr vgic_get_lr(const struct kvm_vcpu *vcpu, int lr);
>>  static void vgic_set_lr(struct kvm_vcpu *vcpu, int lr, struct vgic_lr lr_desc);
>> +static struct irq_phys_map *vgic_irq_map_search(struct kvm_vcpu *vcpu,
>> +                                             int virt_irq);
>>
>>  static const struct vgic_ops *vgic_ops;
>>  static const struct vgic_params *vgic;
>> @@ -1583,6 +1586,166 @@ static irqreturn_t vgic_maintenance_handler(int irq, void *data)
>>       return IRQ_HANDLED;
>>  }
>>
>> +static struct list_head *vgic_get_irq_phys_map_list(struct kvm_vcpu *vcpu,
>> +                                                 int virt_irq)
>> +{
>> +     if (virt_irq < VGIC_NR_PRIVATE_IRQS)
>> +             return &vcpu->arch.vgic_cpu.irq_phys_map_list;
>> +     else
>> +             return &vcpu->kvm->arch.vgic.irq_phys_map_list;
>> +}
>> +
>> +/**
>> + * kvm_vgic_map_phys_irq - map a virtual IRQ to a physical IRQ
>> + * @vcpu: The VCPU pointer
>> + * @virt_irq: The virtual irq number
>> + * @irq: The Linux IRQ number
>> + *
>> + * Establish a mapping between a guest visible irq (@virt_irq) and a
>> + * Linux irq (@irq). On injection, @virt_irq will be associated with
>> + * the physical interrupt represented by @irq.
>> + *
>> + * Returns a valid pointer on success, and an error pointer otherwise
>> + */
>> +struct irq_phys_map *kvm_vgic_map_phys_irq(struct kvm_vcpu *vcpu,
>> +                                        int virt_irq, int irq)
>> +{
>> +     struct vgic_dist *dist = &vcpu->kvm->arch.vgic;
>> +     struct list_head *root = vgic_get_irq_phys_map_list(vcpu, virt_irq);
>> +     struct irq_phys_map *map;
>> +     struct irq_phys_map_entry *entry;
>> +     struct irq_desc *desc;
>> +     struct irq_data *data;
>> +     int phys_irq;
>> +
>> +     desc = irq_to_desc(irq);
>> +     if (!desc) {
>> +             kvm_err("kvm_vgic_map_phys_irq: no interrupt descriptor\n");
> 
> super over-ridiculous nit:
> if you respin you could consider "%s: no...", __FUNC__

Sure.

> 
>> +             return ERR_PTR(-EINVAL);
>> +     }
>> +
>> +     data = irq_desc_get_irq_data(desc);
>> +     while (data->parent_data)
>> +             data = data->parent_data;
>> +
>> +     phys_irq = data->hwirq;
>> +
>> +     /* Create a new mapping */
>> +     entry = kzalloc(sizeof(*entry), GFP_KERNEL);
>> +     if (!entry)
>> +             return ERR_PTR(-ENOMEM);
>> +
>> +     spin_lock(&dist->irq_phys_map_lock);
>> +
>> +     /* Try to match an existing mapping */
>> +     map = vgic_irq_map_search(vcpu, virt_irq);
>> +     if (map) {
>> +             /* Make sure this mapping matches */
> 
> why do we need to check that it matches?  Is it ever allowed to have
> multiple mappings of a virtual interrupt?
> 

Multiple *different* mappings, no. What you can have though is issuing
requests for the *same* mapping repeatedly. This is what happens with
the timer, for example: kvm_timer_vcpu_reset is going to be called more
than once over the lifetime of a VM, requesting a mapping each time
without necessarily destroying the previous one.

>> +             if (map->phys_irq != phys_irq   ||
>> +                 map->irq      != irq)
>> +                     map = ERR_PTR(-EINVAL);
>> +
>> +             goto out;
> 
> why is this a valid situation?  Shouldn't you return -EEXIST or
> something instead?  (that would also simplify the error-checking free
> routine below).
> 
> If you want it to be valid to map the same virq to irq multiple times
> (to free the caller from some bookkeeping, I presume?) then that should
> be part of the function documentation, and I think we should add a
> "found existing mapping" comment above the goto out statement.

Fair enough. I'll add some comments to that effect.

>> +     }
>> +
>> +     map           = &entry->map;
>> +     map->virt_irq = virt_irq;
>> +     map->phys_irq = phys_irq;
>> +     map->irq      = irq;
>> +
>> +     list_add_tail_rcu(&entry->entry, root);
>> +
>> +out:
>> +     spin_unlock(&dist->irq_phys_map_lock);
>> +     /* If we've found a hit in the existing list, free the useless
>> +      * entry */
>> +     if (IS_ERR(map) || map != &entry->map)
>> +             kfree(entry);
>> +     return map;
>> +}
>> +
>> +static struct irq_phys_map *vgic_irq_map_search(struct kvm_vcpu *vcpu,
>> +                                             int virt_irq)
>> +{
>> +     struct list_head *root = vgic_get_irq_phys_map_list(vcpu, virt_irq);
>> +     struct irq_phys_map_entry *entry;
>> +     struct irq_phys_map *map;
>> +
>> +     rcu_read_lock();
>> +
>> +     list_for_each_entry_rcu(entry, root, entry) {
>> +             map = &entry->map;
>> +             if (map->virt_irq == virt_irq && !map->deleted) {
>> +                     rcu_read_unlock();
>> +                     return map;
>> +             }
>> +     }
>> +
>> +     rcu_read_unlock();
>> +
>> +     return NULL;
>> +}
>> +
>> +static void vgic_free_phys_irq_map_rcu(struct rcu_head *rcu)
>> +{
>> +     struct irq_phys_map_entry *entry;
>> +
>> +     entry = container_of(rcu, struct irq_phys_map_entry, rcu);
>> +     kfree(entry);
>> +}
>> +
>> +/**
>> + * kvm_vgic_unmap_phys_irq - Remove a virtual to physical IRQ mapping
>> + * @vcpu: The VCPU pointer
>> + * @map: The pointer to a mapping obtained through kvm_vgic_map_phys_irq
>> + *
>> + * Remove an existing mapping between virtual and physical interrupts.
>> + */
>> +int kvm_vgic_unmap_phys_irq(struct kvm_vcpu *vcpu, struct irq_phys_map *map)
>> +{
>> +     struct vgic_dist *dist = &vcpu->kvm->arch.vgic;
>> +     struct irq_phys_map_entry *entry;
>> +     struct list_head *root;
>> +
>> +     if (!map)
>> +             return -EINVAL;
>> +
>> +     root = vgic_get_irq_phys_map_list(vcpu, map->virt_irq);
>> +
>> +     spin_lock(&dist->irq_phys_map_lock);
>> +
>> +     list_for_each_entry(entry, root, entry) {
>> +             if (&entry->map == map && !map->deleted) {
>> +                     map->deleted = true;
> 
> why do you need the 'deleted' flag?  You now search the list only after
> holding the lock, so the race I pointed out before doesn't exist
> anymore.  Is there an additional issue that the deleted flag is taking
> care of?

This could still race with a destroy occuring before we take the lock,
and before we get get RCU to do the cleanup (the list would still be
populated).

> 
>> +                     list_del_rcu(&entry->entry);
>> +                     call_rcu(&entry->rcu, vgic_free_phys_irq_map_rcu);
>> +                     break;
>> +             }
>> +     }
>> +
>> +     spin_unlock(&dist->irq_phys_map_lock);
>> +
>> +     return 0;
>> +}
>> +
>> +static void vgic_destroy_irq_phys_map(struct kvm *kvm, struct list_head *root)
>> +{
>> +     struct vgic_dist *dist = &kvm->arch.vgic;
>> +     struct irq_phys_map_entry *entry;
>> +
>> +     spin_lock(&dist->irq_phys_map_lock);
>> +
>> +     list_for_each_entry(entry, root, entry) {
>> +             if (!entry->map.deleted) {
>> +                     entry->map.deleted = true;
>> +                     list_del_rcu(&entry->entry);
>> +                     call_rcu(&entry->rcu, vgic_free_phys_irq_map_rcu);
>> +             }
>> +     }
>> +
>> +     spin_unlock(&dist->irq_phys_map_lock);
>> +}
>> +
>>  void kvm_vgic_vcpu_destroy(struct kvm_vcpu *vcpu)
>>  {
>>       struct vgic_cpu *vgic_cpu = &vcpu->arch.vgic_cpu;
>> @@ -1591,6 +1754,7 @@ void kvm_vgic_vcpu_destroy(struct kvm_vcpu *vcpu)
>>       kfree(vgic_cpu->active_shared);
>>       kfree(vgic_cpu->pend_act_shared);
>>       kfree(vgic_cpu->vgic_irq_lr_map);
>> +     vgic_destroy_irq_phys_map(vcpu->kvm, &vgic_cpu->irq_phys_map_list);
>>       vgic_cpu->pending_shared = NULL;
>>       vgic_cpu->active_shared = NULL;
>>       vgic_cpu->pend_act_shared = NULL;
>> @@ -1628,6 +1792,17 @@ static int vgic_vcpu_init_maps(struct kvm_vcpu *vcpu, int nr_irqs)
>>  }
>>
>>  /**
>> + * kvm_vgic_vcpu_early_init - Earliest possible per-vcpu vgic init stage
> 
> earliest possible... oh how I love the vgic code.
> 

You must be the only one! ;-)

> If you have the energy and context to write a comment in the beginning
> of this file describing the init flow, I think that would be useful...
> 

How about starting with this?

<quote>
There are multiple stages to the vgic initialization, both for the
distributor and the CPU interfaces.

Distributor:

- kvm_vgic_early_init(): initialization of static data that doesn't
depend on any sizing information or emulation type. No allocation is
allowed there.

- vgic_init(): allocation and initialization of the generic data
structures that depend on sizing information (number of CPUs, number of
interrupts). Also initializes the vcpu specific data structures. Can be
executed lazily for GICv2. [to be renamed to kvm_vgic_init??]

CPU Interface:

- kvm_vgic_cpu_early_init(): initialization of static data that doesn't
depend on any sizing information or emulation type. No allocation is
allowed there.
</quote>

I'm sure we can expand it as we go...

>> + *
>> + * No memory allocation should be performed here, only static init.
>> + */
>> +void kvm_vgic_vcpu_early_init(struct kvm_vcpu *vcpu)
>> +{
>> +     struct vgic_cpu *vgic_cpu = &vcpu->arch.vgic_cpu;
>> +     INIT_LIST_HEAD(&vgic_cpu->irq_phys_map_list);
>> +}
>> +
>> +/**
>>   * kvm_vgic_get_max_vcpus - Get the maximum number of VCPUs allowed by HW
>>   *
>>   * The host's GIC naturally limits the maximum amount of VCPUs a guest
>> @@ -1664,6 +1839,7 @@ void kvm_vgic_destroy(struct kvm *kvm)
>>       kfree(dist->irq_spi_target);
>>       kfree(dist->irq_pending_on_cpu);
>>       kfree(dist->irq_active_on_cpu);
>> +     vgic_destroy_irq_phys_map(kvm, &dist->irq_phys_map_list);
>>       dist->irq_sgi_sources = NULL;
>>       dist->irq_spi_cpu = NULL;
>>       dist->irq_spi_target = NULL;
>> @@ -1787,6 +1963,18 @@ static int init_vgic_model(struct kvm *kvm, int type)
>>       return 0;
>>  }
>>
>> +/**
>> + * kvm_vgic_early_init - Earliest possible vgic initialization stage
>> + *
>> + * No memory allocation should be performed here, only static init.
>> + */
>> +void kvm_vgic_early_init(struct kvm *kvm)
>> +{
>> +     spin_lock_init(&kvm->arch.vgic.lock);
> 
> so here we're initializing the data structures even before the vgic is
> created, right?  So therefore it's safe to move the vgic.lock init up
> here?

Yes. The distributor structure is part of the struct kvm, hence safe to
poke early on. This doesn't depend on any form of sizing or emulation
type either.

> 
>> +     spin_lock_init(&kvm->arch.vgic.irq_phys_map_lock);
>> +     INIT_LIST_HEAD(&kvm->arch.vgic.irq_phys_map_list);
>> +}
>> +
>>  int kvm_vgic_create(struct kvm *kvm, u32 type)
>>  {
>>       int i, vcpu_lock_idx = -1, ret;
>> @@ -1832,7 +2020,6 @@ int kvm_vgic_create(struct kvm *kvm, u32 type)
>>       if (ret)
>>               goto out_unlock;
>>
>> -     spin_lock_init(&kvm->arch.vgic.lock);
>>       kvm->arch.vgic.in_kernel = true;
>>       kvm->arch.vgic.vgic_model = type;
>>       kvm->arch.vgic.vctrl_base = vgic->vctrl_base;
>> --
>> 2.1.4
>>
> 
> Thanks,
> -Christoffer
> 

Thanks,

	M.
-- 
Jazz is not dead. It just smells funny...


From kishon at ti.com  Tue Aug  4 08:30:24 2015
From: kishon at ti.com (Kishon Vijay Abraham I)
Date: Tue, 4 Aug 2015 21:00:24 +0530
Subject: [PATCH 01/10] ARM: dts: dra7: Add dt node for PCIe registers in
 sysctrl space
In-Reply-To: <1438702233-8027-1-git-send-email-kishon@ti.com>
References: <1438702233-8027-1-git-send-email-kishon@ti.com>
Message-ID: <1438702233-8027-2-git-send-email-kishon@ti.com>

Add new device tree node for the control module register space where
PCIe registers are present.

Signed-off-by: Kishon Vijay Abraham I <kishon at ti.com>
---
 arch/arm/boot/dts/dra7.dtsi |    5 +++++
 1 file changed, 5 insertions(+)

diff --git a/arch/arm/boot/dts/dra7.dtsi b/arch/arm/boot/dts/dra7.dtsi
index aa6abfc..33c5655 100644
--- a/arch/arm/boot/dts/dra7.dtsi
+++ b/arch/arm/boot/dts/dra7.dtsi
@@ -154,6 +154,11 @@
 					compatible = "syscon";
 					reg = <0x1c04 0x0020>;
 				};
+
+				scm_conf2: scm_conf at 1c24 {
+					compatible = "syscon";
+					reg = <0x1c24 0x0024>;
+				};
 			};
 
 			cm_core_aon: cm_core_aon at 5000 {
-- 
1.7.9.5



From kishon at ti.com  Tue Aug  4 08:30:25 2015
From: kishon at ti.com (Kishon Vijay Abraham I)
Date: Tue, 4 Aug 2015 21:00:25 +0530
Subject: [PATCH 02/10] ARM: dts: dra7: Use "syscon-phy-power" instead of
 "ctrl-module" in SATA PHY node
In-Reply-To: <1438702233-8027-1-git-send-email-kishon@ti.com>
References: <1438702233-8027-1-git-send-email-kishon@ti.com>
Message-ID: <1438702233-8027-3-git-send-email-kishon@ti.com>

Add "syscon-phy-power" property and remove the deprecated "ctrl-module"
property from SATA PHY node. Since "omap_control_sata" note is no longer
used, remove it.

Signed-off-by: Kishon Vijay Abraham I <kishon at ti.com>
---
 arch/arm/boot/dts/dra7.dtsi |   10 +---------
 1 file changed, 1 insertion(+), 9 deletions(-)

diff --git a/arch/arm/boot/dts/dra7.dtsi b/arch/arm/boot/dts/dra7.dtsi
index 33c5655..6854385 100644
--- a/arch/arm/boot/dts/dra7.dtsi
+++ b/arch/arm/boot/dts/dra7.dtsi
@@ -1115,14 +1115,6 @@
 			status = "disabled";
 		};
 
-		omap_control_sata: control-phy at 4a002374 {
-			compatible = "ti,control-phy-pipe3";
-			reg = <0x4a002374 0x4>;
-			reg-names = "power";
-			clocks = <&sys_clkin1>;
-			clock-names = "sysclk";
-		};
-
 		/* OCP2SCP3 */
 		ocp2scp at 4a090000 {
 			compatible = "ti,omap-ocp2scp";
@@ -1137,7 +1129,7 @@
 				      <0x4A096400 0x64>, /* phy_tx */
 				      <0x4A096800 0x40>; /* pll_ctrl */
 				reg-names = "phy_rx", "phy_tx", "pll_ctrl";
-				ctrl-module = <&omap_control_sata>;
+				syscon-phy-power = <&scm_conf 0x374>;
 				clocks = <&sys_clkin1>, <&sata_ref_clk>;
 				clock-names = "sysclk", "refclk";
 				#phy-cells = <0>;
-- 
1.7.9.5



From kishon at ti.com  Tue Aug  4 08:30:23 2015
From: kishon at ti.com (Kishon Vijay Abraham I)
Date: Tue, 4 Aug 2015 21:00:23 +0530
Subject: [PATCH 00/10] ARM: dts: use syscon property instead of ctrl-module
Message-ID: <1438702233-8027-1-git-send-email-kishon@ti.com>

This series is split from [1] to include only the dt patches.

This series is basically to deprecate using ctrl-module property and use
corresponding syscon properties to program the control module registers.

Changes from [1] in PHY patches include
*) series created after applying [2]

Did basic enumeration testing in the below platforms.
*) Tested PCIe, SATA and USB in dra7
*) Tested SATA and USB in omap5
*) Tested USB(dwc3) in am43xx_evm
*) Tested USB(musb) in omap4 panda after including [3]

All the testing was done after applying [4]

[1] -> https://lkml.org/lkml/2015/6/23/189
[2] -> http://www.spinics.net/lists/linux-omap/msg120644.html
[3] -> http://permalink.gmane.org/gmane.linux.kernel/2012427
[4] -> http://permalink.gmane.org/gmane.linux.kernel/2012604

Kishon Vijay Abraham I (10):
  ARM: dts: dra7: Add dt node for PCIe registers in sysctrl space
  ARM: dts: dra7: Use "syscon-phy-power" instead of "ctrl-module" in
    SATA PHY node
  ARM: dts: dra7: Use "syscon-phy-power" and "syscon-pcs" in PCIe PHY
    node
  ARM: dts: dra7: Use "ti,dra7x-usb2-phy2" compatible string for USB2
    PHY2
  ARM: dts: dra7: Use "syscon-phy-power" instead of "ctrl-module" in
    USB PHY node
  ARM: dts: am4372: Use "syscon-phy-power" instead of "ctrl-module" in
    USB PHY node
  ARM: dts: OMAP5: Use "syscon-phy-power" instead of "ctrl-module" in
    USB PHY node
  ARM: dts: OMAP5: Use "syscon-phy-power" instead of "ctrl-module" in
    SATA PHY node
  ARM: dts: omap4: Use "syscon-phy-power" instead of "ctrl-module" in
    USB PHY node
  ARM: dts: omap4: Use "syscon-otghs" instead of "ctrl-module" in USB
    node

 arch/arm/boot/dts/am4372.dtsi |   16 ++--------
 arch/arm/boot/dts/dra7.dtsi   |   69 ++++++++++-------------------------------
 arch/arm/boot/dts/omap4.dtsi  |   16 ++--------
 arch/arm/boot/dts/omap5.dtsi  |   26 ++--------------
 4 files changed, 24 insertions(+), 103 deletions(-)

-- 
1.7.9.5



From kishon at ti.com  Tue Aug  4 08:30:27 2015
From: kishon at ti.com (Kishon Vijay Abraham I)
Date: Tue, 4 Aug 2015 21:00:27 +0530
Subject: [PATCH 04/10] ARM: dts: dra7: Use "ti,
 dra7x-usb2-phy2" compatible string for USB2 PHY2
In-Reply-To: <1438702233-8027-1-git-send-email-kishon@ti.com>
References: <1438702233-8027-1-git-send-email-kishon@ti.com>
Message-ID: <1438702233-8027-5-git-send-email-kishon@ti.com>

The USB2 PHY2 has a different register map compared to USB2 PHY1
to power on/off the PHY. In order to handle it, use the new compatible
string "ti,dra7x-usb2-phy2" for the second instance of USB2 PHY.

Signed-off-by: Kishon Vijay Abraham I <kishon at ti.com>
---
 arch/arm/boot/dts/dra7.dtsi |    2 +-
 1 file changed, 1 insertion(+), 1 deletion(-)

diff --git a/arch/arm/boot/dts/dra7.dtsi b/arch/arm/boot/dts/dra7.dtsi
index 0ebb808..dfefd17 100644
--- a/arch/arm/boot/dts/dra7.dtsi
+++ b/arch/arm/boot/dts/dra7.dtsi
@@ -1234,7 +1234,7 @@
 			};
 
 			usb2_phy2: phy at 4a085000 {
-				compatible = "ti,omap-usb2";
+				compatible = "ti,dra7x-usb2-phy2", "ti,omap-usb2";
 				reg = <0x4a085000 0x400>;
 				ctrl-module = <&omap_control_usb2phy2>;
 				clocks = <&usb_phy2_always_on_clk32k>,
-- 
1.7.9.5



From kishon at ti.com  Tue Aug  4 08:30:26 2015
From: kishon at ti.com (Kishon Vijay Abraham I)
Date: Tue, 4 Aug 2015 21:00:26 +0530
Subject: [PATCH 03/10] ARM: dts: dra7: Use "syscon-phy-power" and "syscon-pcs"
 in PCIe PHY node
In-Reply-To: <1438702233-8027-1-git-send-email-kishon@ti.com>
References: <1438702233-8027-1-git-send-email-kishon@ti.com>
Message-ID: <1438702233-8027-4-git-send-email-kishon@ti.com>

Add "syscon-phy-power" property and "syscon-pcs" property which can
be used to perform the control module initializations and remove
the deprecated "ctrl-module" property from PCIe PHY dt nodes.

Phandle to "sysclk" clock node is also added to the PCIe PHY node
since some of the syscon initializations is based on system clock
frequency.

Since "omap_control_pcie1phy" and "omap_control_pcie2phy" devicetree
nodes are no longer used, remove it.

Signed-off-by: Kishon Vijay Abraham I <kishon at ti.com>
---
 arch/arm/boot/dts/dra7.dtsi |   28 +++++++---------------------
 1 file changed, 7 insertions(+), 21 deletions(-)

diff --git a/arch/arm/boot/dts/dra7.dtsi b/arch/arm/boot/dts/dra7.dtsi
index 6854385..0ebb808 100644
--- a/arch/arm/boot/dts/dra7.dtsi
+++ b/arch/arm/boot/dts/dra7.dtsi
@@ -1140,16 +1140,18 @@
 				reg = <0x4a094000 0x80>, /* phy_rx */
 				      <0x4a094400 0x64>; /* phy_tx */
 				reg-names = "phy_rx", "phy_tx";
-				ctrl-module = <&omap_control_pcie1phy>;
+				syscon-phy-power = <&scm_conf2 0x1c>;
+				syscon-pcs = <&scm_conf2 0x10>;
 				clocks = <&dpll_pcie_ref_ck>,
 					 <&dpll_pcie_ref_m2ldo_ck>,
 					 <&optfclk_pciephy1_32khz>,
 					 <&optfclk_pciephy1_clk>,
 					 <&optfclk_pciephy1_div_clk>,
-					 <&optfclk_pciephy_div>;
+					 <&optfclk_pciephy_div>,
+					 <&sys_clkin1>;
 				clock-names = "dpll_ref", "dpll_ref_m2",
 					      "wkupclk", "refclk",
-					      "div-clk", "phy-div";
+					      "div-clk", "phy-div", "sysclk";
 				#phy-cells = <0>;
 			};
 
@@ -1158,7 +1160,8 @@
 				reg = <0x4a095000 0x80>, /* phy_rx */
 				      <0x4a095400 0x64>; /* phy_tx */
 				reg-names = "phy_rx", "phy_tx";
-				ctrl-module = <&omap_control_pcie2phy>;
+				syscon-phy-power = <&scm_conf2 0x20>;
+				syscon-pcs = <&scm_conf2 0x10>;
 				clocks = <&dpll_pcie_ref_ck>,
 					 <&dpll_pcie_ref_m2ldo_ck>,
 					 <&optfclk_pciephy2_32khz>,
@@ -1183,23 +1186,6 @@
 			ti,hwmods = "sata";
 		};
 
-		omap_control_pcie1phy: control-phy at 0x4a003c40 {
-			compatible = "ti,control-phy-pcie";
-			reg = <0x4a003c40 0x4>, <0x4a003c14 0x4>, <0x4a003c34 0x4>;
-			reg-names = "power", "control_sma", "pcie_pcs";
-			clocks = <&sys_clkin1>;
-			clock-names = "sysclk";
-		};
-
-		omap_control_pcie2phy: control-pcie at 0x4a003c44 {
-			compatible = "ti,control-phy-pcie";
-			reg = <0x4a003c44 0x4>, <0x4a003c14 0x4>, <0x4a003c34 0x4>;
-			reg-names = "power", "control_sma", "pcie_pcs";
-			clocks = <&sys_clkin1>;
-			clock-names = "sysclk";
-			status = "disabled";
-		};
-
 		rtc: rtc at 48838000 {
 			compatible = "ti,am3352-rtc";
 			reg = <0x48838000 0x100>;
-- 
1.7.9.5



From kishon at ti.com  Tue Aug  4 08:30:28 2015
From: kishon at ti.com (Kishon Vijay Abraham I)
Date: Tue, 4 Aug 2015 21:00:28 +0530
Subject: [PATCH 05/10] ARM: dts: dra7: Use "syscon-phy-power" instead of
 "ctrl-module" in USB PHY node
In-Reply-To: <1438702233-8027-1-git-send-email-kishon@ti.com>
References: <1438702233-8027-1-git-send-email-kishon@ti.com>
Message-ID: <1438702233-8027-6-git-send-email-kishon@ti.com>

Add "syscon-phy-power" property and remove the deprecated "ctrl-module"
property from USB PHY devicetree nodes.

Since "omap_control_usb2phy1", "omap_control_usb3phy1" and
"omap_control_usb2phy2" devicetree nodes are no longer used, remove it.

Signed-off-by: Kishon Vijay Abraham I <kishon at ti.com>
---
 arch/arm/boot/dts/dra7.dtsi |   24 +++---------------------
 1 file changed, 3 insertions(+), 21 deletions(-)

diff --git a/arch/arm/boot/dts/dra7.dtsi b/arch/arm/boot/dts/dra7.dtsi
index dfefd17..191ffae 100644
--- a/arch/arm/boot/dts/dra7.dtsi
+++ b/arch/arm/boot/dts/dra7.dtsi
@@ -1195,24 +1195,6 @@
 			clocks = <&sys_32k_ck>;
 		};
 
-		omap_control_usb2phy1: control-phy at 4a002300 {
-			compatible = "ti,control-phy-usb2";
-			reg = <0x4a002300 0x4>;
-			reg-names = "power";
-		};
-
-		omap_control_usb3phy1: control-phy at 4a002370 {
-			compatible = "ti,control-phy-pipe3";
-			reg = <0x4a002370 0x4>;
-			reg-names = "power";
-		};
-
-		omap_control_usb2phy2: control-phy at 0x4a002e74 {
-			compatible = "ti,control-phy-usb2-dra7";
-			reg = <0x4a002e74 0x4>;
-			reg-names = "power";
-		};
-
 		/* OCP2SCP1 */
 		ocp2scp at 4a080000 {
 			compatible = "ti,omap-ocp2scp";
@@ -1225,7 +1207,7 @@
 			usb2_phy1: phy at 4a084000 {
 				compatible = "ti,omap-usb2";
 				reg = <0x4a084000 0x400>;
-				ctrl-module = <&omap_control_usb2phy1>;
+				syscon-phy-power = <&scm_conf 0x300>;
 				clocks = <&usb_phy1_always_on_clk32k>,
 					 <&usb_otg_ss1_refclk960m>;
 				clock-names =	"wkupclk",
@@ -1236,7 +1218,7 @@
 			usb2_phy2: phy at 4a085000 {
 				compatible = "ti,dra7x-usb2-phy2", "ti,omap-usb2";
 				reg = <0x4a085000 0x400>;
-				ctrl-module = <&omap_control_usb2phy2>;
+				syscon-phy-power = <&scm_conf 0xe74>;
 				clocks = <&usb_phy2_always_on_clk32k>,
 					 <&usb_otg_ss2_refclk960m>;
 				clock-names =	"wkupclk",
@@ -1250,7 +1232,7 @@
 				      <0x4a084800 0x64>,
 				      <0x4a084c00 0x40>;
 				reg-names = "phy_rx", "phy_tx", "pll_ctrl";
-				ctrl-module = <&omap_control_usb3phy1>;
+				syscon-phy-power = <&scm_conf 0x370>;
 				clocks = <&usb_phy3_always_on_clk32k>,
 					 <&sys_clkin1>,
 					 <&usb_otg_ss1_refclk960m>;
-- 
1.7.9.5



From kishon at ti.com  Tue Aug  4 08:30:30 2015
From: kishon at ti.com (Kishon Vijay Abraham I)
Date: Tue, 4 Aug 2015 21:00:30 +0530
Subject: [PATCH 07/10] ARM: dts: OMAP5: Use "syscon-phy-power" instead of
 "ctrl-module" in USB PHY node
In-Reply-To: <1438702233-8027-1-git-send-email-kishon@ti.com>
References: <1438702233-8027-1-git-send-email-kishon@ti.com>
Message-ID: <1438702233-8027-8-git-send-email-kishon@ti.com>

Add "syscon-phy-power" property and remove the deprecated "ctrl-module"
property from USB PHY devicetree node.

Since "omap_control_usb2phy" and "omap_control_usb3phy" devicetree nodes
are no longer used, remove it.

Signed-off-by: Kishon Vijay Abraham I <kishon at ti.com>
---
 arch/arm/boot/dts/omap5.dtsi |   16 ++--------------
 1 file changed, 2 insertions(+), 14 deletions(-)

diff --git a/arch/arm/boot/dts/omap5.dtsi b/arch/arm/boot/dts/omap5.dtsi
index c8fd648..f0b6cd6 100644
--- a/arch/arm/boot/dts/omap5.dtsi
+++ b/arch/arm/boot/dts/omap5.dtsi
@@ -848,18 +848,6 @@
 			hw-caps-temp-alert;
 		};
 
-		omap_control_usb2phy: control-phy at 4a002300 {
-			compatible = "ti,control-phy-usb2";
-			reg = <0x4a002300 0x4>;
-			reg-names = "power";
-		};
-
-		omap_control_usb3phy: control-phy at 4a002370 {
-			compatible = "ti,control-phy-pipe3";
-			reg = <0x4a002370 0x4>;
-			reg-names = "power";
-		};
-
 		usb3: omap_dwc3 at 4a020000 {
 			compatible = "ti,dwc3";
 			ti,hwmods = "usb_otg_ss";
@@ -890,7 +878,7 @@
 			usb2_phy: usb2phy at 4a084000 {
 				compatible = "ti,omap-usb2";
 				reg = <0x4a084000 0x7c>;
-				ctrl-module = <&omap_control_usb2phy>;
+				syscon-phy-power = <&scm_conf 0x300>;
 				clocks = <&usb_phy_cm_clk32k>, <&usb_otg_ss_refclk960m>;
 				clock-names = "wkupclk", "refclk";
 				#phy-cells = <0>;
@@ -902,7 +890,7 @@
 				      <0x4a084800 0x64>,
 				      <0x4a084c00 0x40>;
 				reg-names = "phy_rx", "phy_tx", "pll_ctrl";
-				ctrl-module = <&omap_control_usb3phy>;
+				syscon-phy-power = <&scm_conf 0x370>;
 				clocks = <&usb_phy_cm_clk32k>,
 					 <&sys_clkin>,
 					 <&usb_otg_ss_refclk960m>;
-- 
1.7.9.5



From kishon at ti.com  Tue Aug  4 08:30:29 2015
From: kishon at ti.com (Kishon Vijay Abraham I)
Date: Tue, 4 Aug 2015 21:00:29 +0530
Subject: [PATCH 06/10] ARM: dts: am4372: Use "syscon-phy-power" instead of
 "ctrl-module" in USB PHY node
In-Reply-To: <1438702233-8027-1-git-send-email-kishon@ti.com>
References: <1438702233-8027-1-git-send-email-kishon@ti.com>
Message-ID: <1438702233-8027-7-git-send-email-kishon@ti.com>

Add "syscon-phy-power" property and remove the deprecated "ctrl-module"
property from USB PHY device tree node.

Since "am43xx_control_usb2phy1" and "am43xx_control_usb2phy2"
devicetree nodes are no longer used, remove it.

Signed-off-by: Kishon Vijay Abraham I <kishon at ti.com>
---
 arch/arm/boot/dts/am4372.dtsi |   16 ++--------------
 1 file changed, 2 insertions(+), 14 deletions(-)

diff --git a/arch/arm/boot/dts/am4372.dtsi b/arch/arm/boot/dts/am4372.dtsi
index ade28c79..24fa073 100644
--- a/arch/arm/boot/dts/am4372.dtsi
+++ b/arch/arm/boot/dts/am4372.dtsi
@@ -802,18 +802,6 @@
 			status = "disabled";
 		};
 
-		am43xx_control_usb2phy1: control-phy at 44e10620 {
-			compatible = "ti,control-phy-usb2-am437";
-			reg = <0x44e10620 0x4>;
-			reg-names = "power";
-		};
-
-		am43xx_control_usb2phy2: control-phy at 0x44e10628 {
-			compatible = "ti,control-phy-usb2-am437";
-			reg = <0x44e10628 0x4>;
-			reg-names = "power";
-		};
-
 		ocp2scp0: ocp2scp at 483a8000 {
 			compatible = "ti,am437x-ocp2scp", "ti,omap-ocp2scp";
 			#address-cells = <1>;
@@ -824,7 +812,7 @@
 			usb2_phy1: phy at 483a8000 {
 				compatible = "ti,am437x-usb2";
 				reg = <0x483a8000 0x8000>;
-				ctrl-module = <&am43xx_control_usb2phy1>;
+				syscon-phy-power = <&scm_conf 0x620>;
 				clocks = <&usb_phy0_always_on_clk32k>,
 					 <&usb_otg_ss0_refclk960m>;
 				clock-names = "wkupclk", "refclk";
@@ -843,7 +831,7 @@
 			usb2_phy2: phy at 483e8000 {
 				compatible = "ti,am437x-usb2";
 				reg = <0x483e8000 0x8000>;
-				ctrl-module = <&am43xx_control_usb2phy2>;
+				syscon-phy-power = <&scm_conf 0x628>;
 				clocks = <&usb_phy1_always_on_clk32k>,
 					 <&usb_otg_ss1_refclk960m>;
 				clock-names = "wkupclk", "refclk";
-- 
1.7.9.5



From kishon at ti.com  Tue Aug  4 08:30:31 2015
From: kishon at ti.com (Kishon Vijay Abraham I)
Date: Tue, 4 Aug 2015 21:00:31 +0530
Subject: [PATCH 08/10] ARM: dts: OMAP5: Use "syscon-phy-power" instead of
 "ctrl-module" in SATA PHY node
In-Reply-To: <1438702233-8027-1-git-send-email-kishon@ti.com>
References: <1438702233-8027-1-git-send-email-kishon@ti.com>
Message-ID: <1438702233-8027-9-git-send-email-kishon@ti.com>

Add "syscon-phy-power" property and remove the deprecated "ctrl-module"
property from SATA PHY node.

Since "omap_control_sata" devicetree node is no longer used, remove it.

Signed-off-by: Kishon Vijay Abraham I <kishon at ti.com>
---
 arch/arm/boot/dts/omap5.dtsi |   10 +---------
 1 file changed, 1 insertion(+), 9 deletions(-)

diff --git a/arch/arm/boot/dts/omap5.dtsi b/arch/arm/boot/dts/omap5.dtsi
index f0b6cd6..c3ca5b7 100644
--- a/arch/arm/boot/dts/omap5.dtsi
+++ b/arch/arm/boot/dts/omap5.dtsi
@@ -946,14 +946,6 @@
 			#thermal-sensor-cells = <1>;
 		};
 
-		omap_control_sata: control-phy at 4a002374 {
-			compatible = "ti,control-phy-pipe3";
-			reg = <0x4a002374 0x4>;
-			reg-names = "power";
-			clocks = <&sys_clkin>;
-			clock-names = "sysclk";
-		};
-
 		/* OCP2SCP3 */
 		ocp2scp at 4a090000 {
 			compatible = "ti,omap-ocp2scp";
@@ -968,7 +960,7 @@
 				      <0x4A096400 0x64>, /* phy_tx */
 				      <0x4A096800 0x40>; /* pll_ctrl */
 				reg-names = "phy_rx", "phy_tx", "pll_ctrl";
-				ctrl-module = <&omap_control_sata>;
+				syscon-phy-power = <&scm_conf 0x374>;
 				clocks = <&sys_clkin>, <&sata_ref_clk>;
 				clock-names = "sysclk", "refclk";
 				#phy-cells = <0>;
-- 
1.7.9.5



From kishon at ti.com  Tue Aug  4 08:30:32 2015
From: kishon at ti.com (Kishon Vijay Abraham I)
Date: Tue, 4 Aug 2015 21:00:32 +0530
Subject: [PATCH 09/10] ARM: dts: omap4: Use "syscon-phy-power" instead of
 "ctrl-module" in USB PHY node
In-Reply-To: <1438702233-8027-1-git-send-email-kishon@ti.com>
References: <1438702233-8027-1-git-send-email-kishon@ti.com>
Message-ID: <1438702233-8027-10-git-send-email-kishon@ti.com>

Add "syscon-phy-power" property and remove the deprecated "ctrl-module"
property from USB PHY dt node.

Since "omap_control_usb2phy" devicetree node is no longer used,
remove it.

Signed-off-by: Kishon Vijay Abraham I <kishon at ti.com>
---
 arch/arm/boot/dts/omap4.dtsi |    8 +-------
 1 file changed, 1 insertion(+), 7 deletions(-)

diff --git a/arch/arm/boot/dts/omap4.dtsi b/arch/arm/boot/dts/omap4.dtsi
index 7d31c6f..b27634d 100644
--- a/arch/arm/boot/dts/omap4.dtsi
+++ b/arch/arm/boot/dts/omap4.dtsi
@@ -703,7 +703,7 @@
 			usb2_phy: usb2phy at 4a0ad080 {
 				compatible = "ti,omap-usb2";
 				reg = <0x4a0ad080 0x58>;
-				ctrl-module = <&omap_control_usb2phy>;
+				syscon-phy-power = <&scm_conf 0x300>;
 				clocks = <&usb_phy_cm_clk32k>;
 				clock-names = "wkupclk";
 				#phy-cells = <0>;
@@ -854,12 +854,6 @@
 			};
 		};
 
-		omap_control_usb2phy: control-phy at 4a002300 {
-			compatible = "ti,control-phy-usb2";
-			reg = <0x4a002300 0x4>;
-			reg-names = "power";
-		};
-
 		omap_control_usbotg: control-phy at 4a00233c {
 			compatible = "ti,control-phy-otghs";
 			reg = <0x4a00233c 0x4>;
-- 
1.7.9.5



From kishon at ti.com  Tue Aug  4 08:30:33 2015
From: kishon at ti.com (Kishon Vijay Abraham I)
Date: Tue, 4 Aug 2015 21:00:33 +0530
Subject: [PATCH 10/10] ARM: dts: omap4: Use "syscon-otghs" instead of
 "ctrl-module" in USB node
In-Reply-To: <1438702233-8027-1-git-send-email-kishon@ti.com>
References: <1438702233-8027-1-git-send-email-kishon@ti.com>
Message-ID: <1438702233-8027-11-git-send-email-kishon@ti.com>

Add "syscon-otghs" property and remove the deprecated "ctrl-module"
property from MUSB devicetree node.

Since "omap_control_usbotg" devicetree node is no longer used, remove
it.

Signed-off-by: Kishon Vijay Abraham I <kishon at ti.com>
---
 arch/arm/boot/dts/omap4.dtsi |    8 +-------
 1 file changed, 1 insertion(+), 7 deletions(-)

diff --git a/arch/arm/boot/dts/omap4.dtsi b/arch/arm/boot/dts/omap4.dtsi
index b27634d..2fb49a5 100644
--- a/arch/arm/boot/dts/omap4.dtsi
+++ b/arch/arm/boot/dts/omap4.dtsi
@@ -854,12 +854,6 @@
 			};
 		};
 
-		omap_control_usbotg: control-phy at 4a00233c {
-			compatible = "ti,control-phy-otghs";
-			reg = <0x4a00233c 0x4>;
-			reg-names = "otghs_control";
-		};
-
 		usb_otg_hs: usb_otg_hs at 4a0ab000 {
 			compatible = "ti,omap4-musb";
 			reg = <0x4a0ab000 0x7ff>;
@@ -872,7 +866,7 @@
 			multipoint = <1>;
 			num-eps = <16>;
 			ram-bits = <12>;
-			ctrl-module = <&omap_control_usbotg>;
+			syscon-otghs = <&scm_conf 0x33c>;
 		};
 
 		aes: aes at 4b501000 {
-- 
1.7.9.5



From dave.long at linaro.org  Tue Aug  4 08:36:13 2015
From: dave.long at linaro.org (David Long)
Date: Tue, 04 Aug 2015 11:36:13 -0400
Subject: [RFC PATCH V2 00/10] ARM64: Uprobe support added
In-Reply-To: <55C0D53F.6080403@redhat.com>
References: <cover.1434598237.git.panand@redhat.com>
 <20150803110908.GC10501@arm.com> <55BF7019.9080007@linaro.org>
 <55BF707F.7020208@linaro.org> <55C0D53F.6080403@redhat.com>
Message-ID: <55C0DBED.9040100@linaro.org>

On 08/04/15 11:07, William Cohen wrote:
> On 08/03/2015 09:45 AM, David Long wrote:
>> On 08/03/15 09:43, David Long wrote:
>>> On 08/03/15 07:09, Will Deacon wrote:
>>>> On Thu, Jun 18, 2015 at 04:58:47AM +0100, Pratyush Anand wrote:
>>>>> These patches have been prepared on top of ARM64 kprobe v7 patches [1].
>>>>> Keeping as RFC, because kprobe-v7 still need to be ACKed.
>>>>
>>>> Unfortunately, I've not seen any movement on the kprobes patches
>>>> recently,
>>>> so this is out of the picture for 4.3.
>>>>
>>>> Dave: did you plan to respin your series after Steve's comments on v7?
>>>>
>>>> Will
>>>>
>>>
>>> Catalin's comments last week helped me clarify in my own mind that we
>>> should be able to simplfy the register pushing somewhat. Will, does that
>>> also make sense to you?
>>>
>>
>> ^^ That question was aimed at Will Cohen, just to clarify.
>
> Hi Dave,
>
> The suggestion to only save the caller saved registers would make the save and restore code shorter and faster.  There would be cases reduced saved and restore could be visible to systemtap scripts using print_reg() and register() functions such when  a call to a return probed function is followed by a call to a function with a kprobe on entry.  I worry about cases where code is broken (not following the calling conventions maybe assembly code functions) and using a return probe causes things to fail in a different way making it more difficult to diagnose the problem.  There are less than 50 "*.S" files for arm64, but I prefer to minimize the chances that the return probe changes something.
>

We will always have to save all the registers since a pointer to the 
saved ptregs struct is passed down to the kprobes/events processing code 
and used for reporting (or processing in user-written modules) the 
register contents at the probe point.  So we'd only be talking about not 
*restoring* some of the registers.  We're talking about a fairly small 
amount of code now.  It would be nice to get some kind of agreement on 
this ASAP.  In the end I'll have to defer to the subsystem maintainers.

> There is room for improvements for the patch.  The magic offset numbers in the save restore code could be eliminated.
>
> -Will
>
>>
>>> So, also taking into consideration Steve's suggestions about
>>> reorganizing the asm code, I am now working on a new revision.
>>>
>>> -dl
>>>
>>
>

-dl



From broonie at kernel.org  Tue Aug  4 08:36:49 2015
From: broonie at kernel.org (Mark Brown)
Date: Tue, 4 Aug 2015 16:36:49 +0100
Subject: [PATCH v2 0/4] Add SPDIF support for rockchip
In-Reply-To: <1438687099-14282-1-git-send-email-sjoerd.simons@collabora.co.uk>
References: <1438687099-14282-1-git-send-email-sjoerd.simons@collabora.co.uk>
Message-ID: <20150804153649.GP20873@sirena.org.uk>

On Tue, Aug 04, 2015 at 01:18:15PM +0200, Sjoerd Simons wrote:

> Sjoerd Simons (4):
>   ASoC: dt-bindings: add rockchip tranceiver bindings
>   ASoc: rockchip: Add rockchip SPDIF transceiver driver

I only appear to have patch 2 (with the misspelt subject), not the
binding documentation.
-------------- next part --------------
A non-text attachment was scrubbed...
Name: signature.asc
Type: application/pgp-signature
Size: 473 bytes
Desc: Digital signature
URL: <http://lists.infradead.org/pipermail/linux-arm-kernel/attachments/20150804/870592a3/attachment.sig>

From andrew at lunn.ch  Tue Aug  4 08:34:39 2015
From: andrew at lunn.ch (Andrew Lunn)
Date: Tue, 4 Aug 2015 17:34:39 +0200
Subject: Armadaxp GPIO interrupts
In-Reply-To: <CAG1O52Xg88OsifBzmpSdqvC8wQaOW78nC9nnfxugFv1VU1m1LQ@mail.gmail.com>
References: <CAG1O52Xg88OsifBzmpSdqvC8wQaOW78nC9nnfxugFv1VU1m1LQ@mail.gmail.com>
Message-ID: <20150804153439.GA28673@lunn.ch>

On Tue, Aug 04, 2015 at 08:52:17PM +0530, raghu MG wrote:
> Hello,
> 
> I am working on a card which as GPIOs connected to external I/O's. The
> board consists of ARMADAXP 78460 host cpu.
> 
> Board currently runs Linux-4.1 with modified  armada-xp-gp.dtb for ArmadaXP.
> I enabled "orion-gpio" driver to initialize GPIOs as given in
> armada-xp-mv78460.

What kernel configuration are you using? Do you have the same problem
with multi_v7_defconfig and mvebu_v7_defconfig?
 
> The driver while initializing calls irq_domain_add_simple which throws up
> following warning
> "irq: Cannot allocate irq_descs @ IRQ47, assuming pre-allocated"
> The warning repeats for next set(32-63  & 64-66).
>
> Also the GPIO IRQs are not getting listed in cat /proc/interrupts

irq_domain_add_simple() returning an error is fatal for the probe. The
driver will not be loaded, so more than interrupts will be missing,
all the gpios will be missing.

    Andrew


From dave.long at linaro.org  Tue Aug  4 08:43:00 2015
From: dave.long at linaro.org (David Long)
Date: Tue, 04 Aug 2015 11:43:00 -0400
Subject: [RFC PATCH V2 00/10] ARM64: Uprobe support added
In-Reply-To: <55C0D53F.6080403@redhat.com>
References: <cover.1434598237.git.panand@redhat.com>
 <20150803110908.GC10501@arm.com> <55BF7019.9080007@linaro.org>
 <55BF707F.7020208@linaro.org> <55C0D53F.6080403@redhat.com>
Message-ID: <55C0DD84.5010002@linaro.org>

On 08/04/15 11:07, William Cohen wrote:
> On 08/03/2015 09:45 AM, David Long wrote:
>> On 08/03/15 09:43, David Long wrote:
>>> On 08/03/15 07:09, Will Deacon wrote:
>>>> On Thu, Jun 18, 2015 at 04:58:47AM +0100, Pratyush Anand wrote:
>>>>> These patches have been prepared on top of ARM64 kprobe v7 patches [1].
>>>>> Keeping as RFC, because kprobe-v7 still need to be ACKed.
>>>>
>>>> Unfortunately, I've not seen any movement on the kprobes patches
>>>> recently,
>>>> so this is out of the picture for 4.3.
>>>>
>>>> Dave: did you plan to respin your series after Steve's comments on v7?
>>>>
>>>> Will
>>>>
>>>
>>> Catalin's comments last week helped me clarify in my own mind that we
>>> should be able to simplfy the register pushing somewhat. Will, does that
>>> also make sense to you?
>>>
>>
>> ^^ That question was aimed at Will Cohen, just to clarify.
>
> Hi Dave,
>
> The suggestion to only save the caller saved registers would make the save and restore code shorter and faster.  There would be cases reduced saved and restore could be visible to systemtap scripts using print_reg() and register() functions such when  a call to a return probed function is followed by a call to a function with a kprobe on entry.  I worry about cases where code is broken (not following the calling conventions maybe assembly code functions) and using a return probe causes things to fail in a different way making it more difficult to diagnose the problem.  There are less than 50 "*.S" files for arm64, but I prefer to minimize the chances that the return probe changes something.
>

Perhaps the best argument for leaving it as-is is so that user-written 
kprobe modules can alter the values of these registers, although 
specifically altering callee-saved registers on function returnd does 
not sound as useful as say modifying x0.

> There is room for improvements for the patch.  The magic offset numbers in the save restore code could be eliminated.
>
> -Will
>
>>
>>> So, also taking into consideration Steve's suggestions about
>>> reorganizing the asm code, I am now working on a new revision.
>>>
>>> -dl
>>>
>>
>

-dl



From broonie at kernel.org  Tue Aug  4 08:51:48 2015
From: broonie at kernel.org (Mark Brown)
Date: Tue, 4 Aug 2015 16:51:48 +0100
Subject: [RFC PATCH 1/5] spi: introduce flag for memory mapped read
In-Reply-To: <55BEF4AF.5090704@ti.com>
References: <1438072876-16338-1-git-send-email-vigneshr@ti.com>
 <1438072876-16338-2-git-send-email-vigneshr@ti.com>
 <20150731181745.GM20873@sirena.org.uk> <55BEF4AF.5090704@ti.com>
Message-ID: <20150804155148.GR20873@sirena.org.uk>

On Mon, Aug 03, 2015 at 10:27:19AM +0530, Vignesh R wrote:

> @use_mmap_mode: Some SPI controller chips are optimized for interacting
> with serial flash memories. These chips have memory mapped interface,
> through which entire serial flash memory slave can be read/written as if
> though they are physical memories (like RAM). Using this interface,
> flash can be accessed using memcpy() function and the spi controller
> hardware will take care of communicating with serial flash over SPI.
> Setting this flag will indicate the SPI controller driver that the
> spi_message is from mtd layer to read from/write to flash. The SPI
> master driver can then appropriately switch the controller to memory
> mapped interface to read from/write to flash, based on this flag (See
> drivers/spi/spi-ti-qspi.c for example).
> NOTE: If the SPI controller chip lacks memory mapped interface, then the
> driver will ignore this flag and use normal SPI protocol to read
> from/write to flash. Communication with non-flash SPI devices is not
> possible using the memory mapped interface.

I still can't tell from the above what this interface is supposed to do.
It sounds like the use of memory mapped mode is supposed to be
transparent to users, it should just affect how the controller interacts
with the hardware, but if that's the case why do we need to expose it to
users at all?  Shouldn't the driver just use memory mapped mode if it's
faster?
-------------- next part --------------
A non-text attachment was scrubbed...
Name: signature.asc
Type: application/pgp-signature
Size: 473 bytes
Desc: Digital signature
URL: <http://lists.infradead.org/pipermail/linux-arm-kernel/attachments/20150804/381b434f/attachment.sig>

From broonie at kernel.org  Tue Aug  4 08:52:36 2015
From: broonie at kernel.org (Mark Brown)
Date: Tue, 4 Aug 2015 16:52:36 +0100
Subject: [RFC PATCH 4/5] ARM: dts: DRA7: Add memory map region entries
 for qspi
In-Reply-To: <55BEF5D1.1050608@ti.com>
References: <1438072876-16338-1-git-send-email-vigneshr@ti.com>
 <1438072876-16338-5-git-send-email-vigneshr@ti.com>
 <20150731181903.GN20873@sirena.org.uk> <55BEF5D1.1050608@ti.com>
Message-ID: <20150804155236.GS20873@sirena.org.uk>

On Mon, Aug 03, 2015 at 10:32:09AM +0530, Vignesh R wrote:
> On 07/31/2015 11:49 PM, Mark Brown wrote:

> >> -			reg = <0x47900000 0x100>;
> >> +			reg = <0x47900000 0x100>,
> >> +			      <0x30000000 0x3ffffff>;
> >> +			reg-names = "qspi_base", "qspi_mmap";

> > The DT binding document for the controller needs to be extended to
> > document this change in the binding.

> DT bindings are already documented at
> Documentation/devicetree/bindings/spi/ti_qspi.txt. Did you mean to add
> this node as an example in that file?

No, I mean you're changing the binding to add this new memory region -
that new region needs to be added to the documentation.
-------------- next part --------------
A non-text attachment was scrubbed...
Name: signature.asc
Type: application/pgp-signature
Size: 473 bytes
Desc: Digital signature
URL: <http://lists.infradead.org/pipermail/linux-arm-kernel/attachments/20150804/9f6981ad/attachment.sig>

From marc.zyngier at arm.com  Tue Aug  4 09:02:41 2015
From: marc.zyngier at arm.com (Marc Zyngier)
Date: Tue, 04 Aug 2015 17:02:41 +0100
Subject: [PATCH v3 09/11] KVM: arm/arm64: vgic: Prevent userspace injection
 of a mapped interrupt
In-Reply-To: <20150804134509.GB29335@cbox>
References: <1437753309-17989-1-git-send-email-marc.zyngier@arm.com>
 <1437753309-17989-10-git-send-email-marc.zyngier@arm.com>
 <20150804134509.GB29335@cbox>
Message-ID: <55C0E221.6050009@arm.com>

On 04/08/15 14:45, Christoffer Dall wrote:
> On Fri, Jul 24, 2015 at 04:55:07PM +0100, Marc Zyngier wrote:
>> Virtual interrupts mapped to a HW interrupt should only be triggered
>> from inside the kernel. Otherwise, you could end up confusing the
>> kernel (and the GIC's) state machine.
>>
>> Rearrange the injection path so that kvm_vgic_inject_irq is
>> used for non-mapped interrupts, and kvm_vgic_inject_mapped_irq is
>> used for mapped interrupts. The latter should only be called from
>> inside the kernel (timer, VFIO).
>>
>> Signed-off-by: Marc Zyngier <marc.zyngier at arm.com>
>> ---
>>  include/kvm/arm_vgic.h |  2 +
>>  virt/kvm/arm/vgic.c    | 99 ++++++++++++++++++++++++++++++++++----------------
>>  2 files changed, 70 insertions(+), 31 deletions(-)
>>
>> diff --git a/include/kvm/arm_vgic.h b/include/kvm/arm_vgic.h
>> index 7306b4b..f6bfd79 100644
>> --- a/include/kvm/arm_vgic.h
>> +++ b/include/kvm/arm_vgic.h
>> @@ -351,6 +351,8 @@ void kvm_vgic_flush_hwstate(struct kvm_vcpu *vcpu);
>>  void kvm_vgic_sync_hwstate(struct kvm_vcpu *vcpu);
>>  int kvm_vgic_inject_irq(struct kvm *kvm, int cpuid, unsigned int irq_num,
>>  			bool level);
>> +int kvm_vgic_inject_mapped_irq(struct kvm *kvm, int cpuid,
>> +			       struct irq_phys_map *map, bool level);
>>  void vgic_v3_dispatch_sgi(struct kvm_vcpu *vcpu, u64 reg);
>>  int kvm_vgic_vcpu_pending_irq(struct kvm_vcpu *vcpu);
>>  int kvm_vgic_vcpu_active_irq(struct kvm_vcpu *vcpu);
>> diff --git a/virt/kvm/arm/vgic.c b/virt/kvm/arm/vgic.c
>> index 3f7b690..e40ef70 100644
>> --- a/virt/kvm/arm/vgic.c
>> +++ b/virt/kvm/arm/vgic.c
>> @@ -1533,7 +1533,8 @@ static int vgic_validate_injection(struct kvm_vcpu *vcpu, int irq, int level)
>>  }
>>  
>>  static int vgic_update_irq_pending(struct kvm *kvm, int cpuid,
>> -				  unsigned int irq_num, bool level)
>> +				   struct irq_phys_map *map,
>> +				   unsigned int irq_num, bool level)
>>  {
>>  	struct vgic_dist *dist = &kvm->arch.vgic;
>>  	struct kvm_vcpu *vcpu;
>> @@ -1541,6 +1542,9 @@ static int vgic_update_irq_pending(struct kvm *kvm, int cpuid,
>>  	int enabled;
>>  	bool ret = true, can_inject = true;
>>  
>> +	if (irq_num >= min(kvm->arch.vgic.nr_irqs, 1020))
>> +		return -EINVAL;
>> +
>>  	spin_lock(&dist->lock);
>>  
>>  	vcpu = kvm_get_vcpu(kvm, cpuid);
>> @@ -1603,14 +1607,42 @@ static int vgic_update_irq_pending(struct kvm *kvm, int cpuid,
>>  out:
>>  	spin_unlock(&dist->lock);
>>  
>> -	return ret ? cpuid : -EINVAL;
>> +	if (!ret) {
> 
> don't you mean if (ret) here?  hint: ret is a bool

Ouch. Nice catch!

> 
>> +		/* kick the specified vcpu */
>> +		kvm_vcpu_kick(kvm_get_vcpu(kvm, cpuid));
>> +	}
>> +
>> +	return 0;
> 
> isn't this a change in the internal API?
> Before, we would return -EINVAL when ret is false.  Not sure if this
> has any consequences though?

I don't think this is a change in API. Before this patch, we would
either return a vcpuid or -EINVAL. But the error would not be propagated
beyond kvm_vgic_inject_irq, effectively discarding the error code.

Also, it is a bit odd to return an error because the toggling of the
line wasn't significant (like bringing the line down on an
edge-triggered interrupt).

> 
>> +}
>> +
>> +static int vgic_lazy_init(struct kvm *kvm)
>> +{
>> +	int ret = 0;
>> +
>> +	if (unlikely(!vgic_initialized(kvm))) {
>> +		/*
>> +		 * We only provide the automatic initialization of the VGIC
>> +		 * for the legacy case of a GICv2. Any other type must
>> +		 * be explicitly initialized once setup with the respective
>> +		 * KVM device call.
>> +		 */
>> +		if (kvm->arch.vgic.vgic_model != KVM_DEV_TYPE_ARM_VGIC_V2)
>> +			return -EBUSY;
>> +
>> +		mutex_lock(&kvm->lock);
>> +		ret = vgic_init(kvm);
>> +		mutex_unlock(&kvm->lock);
>> +	}
>> +
>> +	return ret;
>>  }
>>  
>>  /**
>>   * kvm_vgic_inject_irq - Inject an IRQ from a device to the vgic
>>   * @kvm:     The VM structure pointer
>>   * @cpuid:   The CPU for PPIs
>> - * @irq_num: The IRQ number that is assigned to the device
>> + * @irq_num: The IRQ number that is assigned to the device. This IRQ
>> + *           must not be mapped to a HW interrupt.
>>   * @level:   Edge-triggered:  true:  to trigger the interrupt
>>   *			      false: to ignore the call
>>   *	     Level-sensitive  true:  activates an interrupt
>> @@ -1623,39 +1655,44 @@ out:
>>  int kvm_vgic_inject_irq(struct kvm *kvm, int cpuid, unsigned int irq_num,
>>  			bool level)
>>  {
>> -	int ret = 0;
>> -	int vcpu_id;
>> -
>> -	if (unlikely(!vgic_initialized(kvm))) {
>> -		/*
>> -		 * We only provide the automatic initialization of the VGIC
>> -		 * for the legacy case of a GICv2. Any other type must
>> -		 * be explicitly initialized once setup with the respective
>> -		 * KVM device call.
>> -		 */
>> -		if (kvm->arch.vgic.vgic_model != KVM_DEV_TYPE_ARM_VGIC_V2) {
>> -			ret = -EBUSY;
>> -			goto out;
>> -		}
>> -		mutex_lock(&kvm->lock);
>> -		ret = vgic_init(kvm);
>> -		mutex_unlock(&kvm->lock);
>> +	struct irq_phys_map *map;
>> +	int ret;
>>  
>> -		if (ret)
>> -			goto out;
>> -	}
>> +	ret = vgic_lazy_init(kvm);
>> +	if (ret)
>> +		return ret;
>>  
>> -	if (irq_num >= min(kvm->arch.vgic.nr_irqs, 1020))
>> +	map = vgic_irq_map_search(kvm_get_vcpu(kvm, cpuid), irq_num);
>> +	if (map)
>>  		return -EINVAL;
>>  
>> -	vcpu_id = vgic_update_irq_pending(kvm, cpuid, irq_num, level);
>> -	if (vcpu_id >= 0) {
>> -		/* kick the specified vcpu */
>> -		kvm_vcpu_kick(kvm_get_vcpu(kvm, vcpu_id));
>> -	}
>> +	return vgic_update_irq_pending(kvm, cpuid, NULL, irq_num, level);
>> +}
>>  
>> -out:
>> -	return ret;
>> +/**
>> + * kvm_vgic_inject_mapped_irq - Inject a physically mapped IRQ to the vgic
>> + * @kvm:     The VM structure pointer
>> + * @cpuid:   The CPU for PPIs
>> + * @map:     Pointer to a irq_phys_map structure describing the mapping
>> + * @level:   Edge-triggered:  true:  to trigger the interrupt
>> + *			      false: to ignore the call
>> + *	     Level-sensitive  true:  activates an interrupt
>> + *			      false: deactivates an interrupt
> 
> just noticed this unfortunate use of the words 'activate/deactivate'
> here, which is not true, it just raises/lowers the input signal...
> 

I'll clean that up.

>> + *
>> + * The GIC is not concerned with devices being active-LOW or active-HIGH for
>> + * level-sensitive interrupts.  You can think of the level parameter as 1
>> + * being HIGH and 0 being LOW and all devices being active-HIGH.
>> + */
>> +int kvm_vgic_inject_mapped_irq(struct kvm *kvm, int cpuid,
>> +			       struct irq_phys_map *map, bool level)
>> +{
>> +	int ret;
>> +
>> +	ret = vgic_lazy_init(kvm);
>> +	if (ret)
>> +		return ret;
>> +
>> +	return vgic_update_irq_pending(kvm, cpuid, map, map->virt_irq, level);
>>  }
>>  
>>  static irqreturn_t vgic_maintenance_handler(int irq, void *data)
>> -- 
>> 2.1.4
>>
> 
> Thanks,
> -Christoffer
> 

Thanks,

	M.
-- 
Jazz is not dead. It just smells funny...


From balbi at ti.com  Tue Aug  4 09:09:48 2015
From: balbi at ti.com (Felipe Balbi)
Date: Tue, 4 Aug 2015 11:09:48 -0500
Subject: [PATCH v5 07/46] usb: dwc3: gadget: add ep capabilities support
In-Reply-To: <1438351258-31578-8-git-send-email-r.baldyga@samsung.com>
References: <1438351258-31578-1-git-send-email-r.baldyga@samsung.com>
 <1438351258-31578-8-git-send-email-r.baldyga@samsung.com>
Message-ID: <20150804160948.GJ23659@saruman.tx.rr.com>

On Fri, Jul 31, 2015 at 04:00:19PM +0200, Robert Baldyga wrote:
> Convert endpoint configuration to new capabilities model.
> 
> Signed-off-by: Robert Baldyga <r.baldyga at samsung.com>
> ---
>  drivers/usb/dwc3/gadget.c | 13 +++++++++++++
>  1 file changed, 13 insertions(+)
> 
> diff --git a/drivers/usb/dwc3/gadget.c b/drivers/usb/dwc3/gadget.c
> index 2feed9e..bd4c3db 100644
> --- a/drivers/usb/dwc3/gadget.c
> +++ b/drivers/usb/dwc3/gadget.c
> @@ -1715,6 +1715,19 @@ static int dwc3_gadget_init_hw_endpoints(struct dwc3 *dwc,
>  				return ret;
>  		}
>  
> +		if (epnum == 0 || epnum == 1) {
> +			dep->endpoint.caps.type_control = true;
> +		} else {
> +			dep->endpoint.caps.type_iso = true;
> +			dep->endpoint.caps.type_bulk = true;
> +			dep->endpoint.caps.type_int = true;
> +		}
> +
> +		if (direction)
> +			dep->endpoint.caps.dir_in = true;
> +		else
> +			dep->endpoint.caps.dir_out = true;

you can avoid the branch for the direction:

		dep->endpoint.caps.dir_in = !!direction;
		dep->endpoint.caps.dir_out = !direction;

-- 
balbi
-------------- next part --------------
A non-text attachment was scrubbed...
Name: signature.asc
Type: application/pgp-signature
Size: 819 bytes
Desc: Digital signature
URL: <http://lists.infradead.org/pipermail/linux-arm-kernel/attachments/20150804/de171f73/attachment-0001.sig>

From srinivas.kandagatla at linaro.org  Tue Aug  4 09:11:26 2015
From: srinivas.kandagatla at linaro.org (Srinivas Kandagatla)
Date: Tue, 04 Aug 2015 17:11:26 +0100
Subject: [PATCH v2 0/3] Add the efuse driver on rockchip platform
In-Reply-To: <55BB3F92.9030701@gmail.com>
References: <1434439665-27781-1-git-send-email-wxt@rock-chips.com>
 <557FE3EA.4000306@i2se.com> <557FEAB2.1040101@linaro.org>
 <557FF50C.10809@rock-chips.com> <55800070.5030509@linaro.org>
 <55826D9D.2060106@i2se.com> <5582816B.5020208@linaro.org>
 <55BB3F92.9030701@gmail.com>
Message-ID: <55C0E42E.3060509@linaro.org>

Hi Shunqian,

Sorry for delay in reply, I was on Holidays..

Thanks for testing.

On 31/07/15 10:27, Shunqian Zheng wrote:
>
> 1. Without the following diff, `hexdump
> /sys/bus/nvmem/devices/rockchip-efuse0/nvmem` is wrong with "INVALID
> ARGUMENT":
>
> +++ b/drivers/nvmem/core.c
> @@ -67,7 +67,7 @@ static ssize_t bin_attr_nvmem_read(struct file *filp,
> struct kobject *kobj,
>          int rc;
>
>          /* Stop the user from reading */
> -       if (pos > nvmem->size)
> +       if (pos > nvmem->size - 1)
>                  return 0;

Yes, this should have been something like this
-       if (pos > nvmem->size)
+       if (pos >= nvmem->size)
                 return 0;

We can send a fix on top of v9 once its merged.

>
>          if (pos + count > nvmem->size)
>
> RK3288-efuse has  32 x 8bit regs, in dts "reg = <0xffb40000 0x20>;"
> Here is the message dump from nvmem_device:
> [    2.158314] nvmem:
> [    2.158314]           name (null)
> [    2.158314]           stride 1
> [    2.158314]           word_size 1
> [    2.158314]           ncells 0
> [    2.158314]           id 0
> [    2.158314]           users 0
> [    2.158314]           size 32
> [    2.158314]           read_only 0
>
> Do you think there is a leak or I'm messing up ?
>
> 2. About the read operation, eFuse data can be read during device
> probe() and cached, OR,
>      read from eFuse when needed every time. I prefer the second one but
> then, the clock of eFuse may be
>      gated. So before/after reading I have to enable/disable clk like :
>            devm_clk_get(dev, "hclk_efuse256");
>      The trouble is I can't find a way to get the "dev" hander in :
>            static int rockchip_efuse_read(void *context, const void
> *reg, size_t reg_size, void *val, size_t val_size)
>      I am appreciated if you can give some advice.


May be you should use regmap_init_mmio_clk() instead of 
regmap_init_mmio() it will take care of clks.

>      Or, do you think it's reasonable to add hooks before/after read in
> nvmem/core.c like :
>            +       before_read(dev, ...);
>                     rc = regmap_raw_read(nvmem->regmap, pos, buf, count);
>            +       after_read(dev, ...);
>


> 3. In the /sys/bus/nvmem/devices/rockchip-efuse0/, there are files:
>           /sys/devices/platform/ffb40000.efuse/rockchip-efuse0 # ls
>           nvmem      of_node    power      subsystem  uevent
>      Do you have a plan to add the nvmem consumers to /sys/ in nvmem
> framework?
yes, Am waiting for the framework to be merged, I have plans to add this 
feature.

>      For example,  in dts defined the "cpu_leakage":
>          efuse: efuse at ffb40000 {
>                  compatible = "rockchip,rk3x-efuse";
>                  reg = <0xffb40000 0x20>;
>                  #address-cells = <1>;
>                  #size-cells = <1>;
>                  clocks = <&cru PCLK_EFUSE256>;
>                  clock-names = "pclk_efuse_256";
>
>                  cpu_leakage: cpu_leakage {
>                          reg = <0x17 0x1>;
>                  };
>          };
>     Then nvmem exposes the "cpu_leakage" file in /sys which can be
> read/write.

--srini


From srinivas.kandagatla at linaro.org  Tue Aug  4 09:12:13 2015
From: srinivas.kandagatla at linaro.org (Srinivas Kandagatla)
Date: Tue, 04 Aug 2015 17:12:13 +0100
Subject: [PATCH v9 0/9] Add simple NVMEM Framework via regmap.
In-Reply-To: <1438693367.3793.29.camel@pengutronix.de>
References: <1437995567-11203-1-git-send-email-srinivas.kandagatla@linaro.org>
 <1438693367.3793.29.camel@pengutronix.de>
Message-ID: <55C0E45D.3020706@linaro.org>



On 04/08/15 14:02, Philipp Zabel wrote:
> Hi Srinivas,
>
> Am Montag, den 27.07.2015, 12:12 +0100 schrieb Srinivas Kandagatla:
>> Hi Greg/Kevin,
>>
>> This patchset adds a new simple NVMEM framework to kernel, and it is tested
>> with various drivers like "QCOM thermal sensors", "QCOM cpr driver",
>> "begal bone cape manager" and few more on the way.
>
> Tested-by: Philipp Zabel <p.zabel at pengutronix.de>
> using the i.MX6 OCOTP shadow register range.
>
Thanks Philipp for the tested-by.

> regards
> Philipp
>


From marc.zyngier at arm.com  Tue Aug  4 09:14:53 2015
From: marc.zyngier at arm.com (Marc Zyngier)
Date: Tue, 04 Aug 2015 17:14:53 +0100
Subject: [PATCH v3 10/11] KVM: arm/arm64: timer: Allow the timer to control
 the active state
In-Reply-To: <20150804135652.GC29335@cbox>
References: <1437753309-17989-1-git-send-email-marc.zyngier@arm.com>
 <1437753309-17989-11-git-send-email-marc.zyngier@arm.com>
 <20150804135652.GC29335@cbox>
Message-ID: <55C0E4FD.6000100@arm.com>

On 04/08/15 14:56, Christoffer Dall wrote:
> On Fri, Jul 24, 2015 at 04:55:08PM +0100, Marc Zyngier wrote:
>> In order to remove the crude hack where we sneak the masked bit
>> into the timer's control register, make use of the phys_irq_map
>> API control the active state of the interrupt.
>>
>> This causes some limited changes to allow for potential error
>> propagation.
>>
>> Signed-off-by: Marc Zyngier <marc.zyngier at arm.com>
>> ---
>>  arch/arm/kvm/reset.c         |  4 +---
>>  arch/arm64/kvm/reset.c       |  4 +---
>>  include/kvm/arm_arch_timer.h |  7 +++++--
>>  virt/kvm/arm/arch_timer.c    | 29 ++++++++++++++++++++++-------
>>  4 files changed, 29 insertions(+), 15 deletions(-)
>>
>> diff --git a/arch/arm/kvm/reset.c b/arch/arm/kvm/reset.c
>> index f558c07..eeb85858 100644
>> --- a/arch/arm/kvm/reset.c
>> +++ b/arch/arm/kvm/reset.c
>> @@ -77,7 +77,5 @@ int kvm_reset_vcpu(struct kvm_vcpu *vcpu)
>>  	kvm_reset_coprocs(vcpu);
>>  
>>  	/* Reset arch_timer context */
>> -	kvm_timer_vcpu_reset(vcpu, cpu_vtimer_irq);
>> -
>> -	return 0;
>> +	return kvm_timer_vcpu_reset(vcpu, cpu_vtimer_irq);
>>  }
>> diff --git a/arch/arm64/kvm/reset.c b/arch/arm64/kvm/reset.c
>> index b4af618..91cf535 100644
>> --- a/arch/arm64/kvm/reset.c
>> +++ b/arch/arm64/kvm/reset.c
>> @@ -121,7 +121,5 @@ int kvm_reset_vcpu(struct kvm_vcpu *vcpu)
>>  	kvm_reset_sys_regs(vcpu);
>>  
>>  	/* Reset timer */
>> -	kvm_timer_vcpu_reset(vcpu, cpu_vtimer_irq);
>> -
>> -	return 0;
>> +	return kvm_timer_vcpu_reset(vcpu, cpu_vtimer_irq);
>>  }
>> diff --git a/include/kvm/arm_arch_timer.h b/include/kvm/arm_arch_timer.h
>> index e596675..e1e4d7c 100644
>> --- a/include/kvm/arm_arch_timer.h
>> +++ b/include/kvm/arm_arch_timer.h
>> @@ -52,13 +52,16 @@ struct arch_timer_cpu {
>>  
>>  	/* Timer IRQ */
>>  	const struct kvm_irq_level	*irq;
>> +
>> +	/* VGIC mapping */
>> +	struct irq_phys_map		*map;
>>  };
>>  
>>  int kvm_timer_hyp_init(void);
>>  void kvm_timer_enable(struct kvm *kvm);
>>  void kvm_timer_init(struct kvm *kvm);
>> -void kvm_timer_vcpu_reset(struct kvm_vcpu *vcpu,
>> -			  const struct kvm_irq_level *irq);
>> +int kvm_timer_vcpu_reset(struct kvm_vcpu *vcpu,
>> +			 const struct kvm_irq_level *irq);
>>  void kvm_timer_vcpu_init(struct kvm_vcpu *vcpu);
>>  void kvm_timer_flush_hwstate(struct kvm_vcpu *vcpu);
>>  void kvm_timer_sync_hwstate(struct kvm_vcpu *vcpu);
>> diff --git a/virt/kvm/arm/arch_timer.c b/virt/kvm/arm/arch_timer.c
>> index 98c95f2..76e38d2 100644
>> --- a/virt/kvm/arm/arch_timer.c
>> +++ b/virt/kvm/arm/arch_timer.c
>> @@ -64,10 +64,10 @@ static void kvm_timer_inject_irq(struct kvm_vcpu *vcpu)
>>  	int ret;
>>  	struct arch_timer_cpu *timer = &vcpu->arch.timer_cpu;
>>  
>> -	timer->cntv_ctl |= ARCH_TIMER_CTRL_IT_MASK;
>> -	ret = kvm_vgic_inject_irq(vcpu->kvm, vcpu->vcpu_id,
>> -				  timer->irq->irq,
>> -				  timer->irq->level);
>> +	kvm_vgic_set_phys_irq_active(timer->map, true);
> 
> actually, I'm not sure I understand the point of setting this boolean?
> Is it just a check?  It seems everywhere we find the map in the VGIC
> code, we have a BUG_ON(!map->active), so why doesn't (!!map) imply that
> it should be marked as active?
> 
> Is this again for non-shared devices?
> 

Setting the boolean here means that the interrupt should be marked
active at the distributor level when the interrupt is injected. This
also allows the timer code to find out when we can inject another
interrupt (by checking that the interrupt is now inactive).

As for the BUG_ON(), this is really some debug stuff to make sure we
have a consistent state.

Non-shared devices are handled separately (and setting the active state
doesn't make much sense, as we expect this to be entirely HW driven).

Do you see anything I should add to make it more clear?

>> +	ret = kvm_vgic_inject_mapped_irq(vcpu->kvm, vcpu->vcpu_id,
>> +					 timer->map,
>> +					 timer->irq->level);
>>  	WARN_ON(ret);
>>  }
>>  
>> @@ -117,7 +117,8 @@ bool kvm_timer_should_fire(struct kvm_vcpu *vcpu)
>>  	cycle_t cval, now;
>>  
>>  	if ((timer->cntv_ctl & ARCH_TIMER_CTRL_IT_MASK) ||
>> -		!(timer->cntv_ctl & ARCH_TIMER_CTRL_ENABLE))
>> +	    !(timer->cntv_ctl & ARCH_TIMER_CTRL_ENABLE) ||
>> +	    kvm_vgic_get_phys_irq_active(timer->map))
> 
> hmm, maybe this answers my question above.  It is the virtual active
> state preventing us to keep injecting the virtual side?
> 

Exactly. This is effectively what the MASK state was doing, now
replicated in SW...

> I don't see anything functional wrong with this code though.
> 
> Thanks,
> -Christoffer
> 
> 
>>  		return false;
>>  
>>  	cval = timer->cntv_cval;
>> @@ -184,10 +185,11 @@ void kvm_timer_sync_hwstate(struct kvm_vcpu *vcpu)
>>  	timer_arm(timer, ns);
>>  }
>>  
>> -void kvm_timer_vcpu_reset(struct kvm_vcpu *vcpu,
>> -			  const struct kvm_irq_level *irq)
>> +int kvm_timer_vcpu_reset(struct kvm_vcpu *vcpu,
>> +			 const struct kvm_irq_level *irq)
>>  {
>>  	struct arch_timer_cpu *timer = &vcpu->arch.timer_cpu;
>> +	struct irq_phys_map *map;
>>  
>>  	/*
>>  	 * The vcpu timer irq number cannot be determined in
>> @@ -196,6 +198,17 @@ void kvm_timer_vcpu_reset(struct kvm_vcpu *vcpu,
>>  	 * vcpu timer irq number when the vcpu is reset.
>>  	 */
>>  	timer->irq = irq;
>> +
>> +	/*
>> +	 * Tell the VGIC that the virtual interrupt is tied to a
>> +	 * physical interrupt. We do that once per VCPU.
>> +	 */
>> +	map = kvm_vgic_map_phys_irq(vcpu, irq->irq, host_vtimer_irq);
>> +	if (WARN_ON(IS_ERR(map)))
>> +		return PTR_ERR(map);
>> +
>> +	timer->map = map;
>> +	return 0;
>>  }
>>  
>>  void kvm_timer_vcpu_init(struct kvm_vcpu *vcpu)
>> @@ -335,6 +348,8 @@ void kvm_timer_vcpu_terminate(struct kvm_vcpu *vcpu)
>>  	struct arch_timer_cpu *timer = &vcpu->arch.timer_cpu;
>>  
>>  	timer_disarm(timer);
>> +	if (timer->map)
>> +		kvm_vgic_unmap_phys_irq(vcpu, timer->map);
>>  }
>>  
>>  void kvm_timer_enable(struct kvm *kvm)
>> -- 
>> 2.1.4
>>
> 
> 

Thanks,

	M.
-- 
Jazz is not dead. It just smells funny...


From eric.auger at linaro.org  Tue Aug  4 09:21:36 2015
From: eric.auger at linaro.org (Eric Auger)
Date: Tue, 04 Aug 2015 18:21:36 +0200
Subject: [PATCH v3 09/11] KVM: arm/arm64: vgic: Prevent userspace injection
 of a mapped interrupt
In-Reply-To: <1437753309-17989-10-git-send-email-marc.zyngier@arm.com>
References: <1437753309-17989-1-git-send-email-marc.zyngier@arm.com>
 <1437753309-17989-10-git-send-email-marc.zyngier@arm.com>
Message-ID: <55C0E690.1090808@linaro.org>

Hi Marc,
On 07/24/2015 05:55 PM, Marc Zyngier wrote:
> Virtual interrupts mapped to a HW interrupt should only be triggered
> from inside the kernel. Otherwise, you could end up confusing the
> kernel (and the GIC's) state machine.
> 
> Rearrange the injection path so that kvm_vgic_inject_irq is
> used for non-mapped interrupts, and kvm_vgic_inject_mapped_irq is
> used for mapped interrupts. The latter should only be called from
> inside the kernel (timer, VFIO).
nit: I would replace VFIO by irqfd.
VFIO just triggers the eventfd/irqfd. This is KVM/irqfd that injects the
virtual irq upon the irqfd signaling and he irqfd adaptation/ARM
currently is implemented in vgic.c
> 
> Signed-off-by: Marc Zyngier <marc.zyngier at arm.com>
> ---
>  include/kvm/arm_vgic.h |  2 +
>  virt/kvm/arm/vgic.c    | 99 ++++++++++++++++++++++++++++++++++----------------
>  2 files changed, 70 insertions(+), 31 deletions(-)
> 
> diff --git a/include/kvm/arm_vgic.h b/include/kvm/arm_vgic.h
> index 7306b4b..f6bfd79 100644
> --- a/include/kvm/arm_vgic.h
> +++ b/include/kvm/arm_vgic.h
> @@ -351,6 +351,8 @@ void kvm_vgic_flush_hwstate(struct kvm_vcpu *vcpu);
>  void kvm_vgic_sync_hwstate(struct kvm_vcpu *vcpu);
>  int kvm_vgic_inject_irq(struct kvm *kvm, int cpuid, unsigned int irq_num,
>  			bool level);
> +int kvm_vgic_inject_mapped_irq(struct kvm *kvm, int cpuid,
> +			       struct irq_phys_map *map, bool level);
>  void vgic_v3_dispatch_sgi(struct kvm_vcpu *vcpu, u64 reg);
>  int kvm_vgic_vcpu_pending_irq(struct kvm_vcpu *vcpu);
>  int kvm_vgic_vcpu_active_irq(struct kvm_vcpu *vcpu);
> diff --git a/virt/kvm/arm/vgic.c b/virt/kvm/arm/vgic.c
> index 3f7b690..e40ef70 100644
> --- a/virt/kvm/arm/vgic.c
> +++ b/virt/kvm/arm/vgic.c
> @@ -1533,7 +1533,8 @@ static int vgic_validate_injection(struct kvm_vcpu *vcpu, int irq, int level)
>  }
>  
>  static int vgic_update_irq_pending(struct kvm *kvm, int cpuid,
> -				  unsigned int irq_num, bool level)
> +				   struct irq_phys_map *map,
> +				   unsigned int irq_num, bool level)
>  {
In vgic_update_irq_pending, I needed to modify the following line and
add the "&& !map".

        if (!vgic_validate_injection(vcpu, irq_num, level) && !map) {

Without that, the level being not properly modeled for level sensitive
forwarded IRQs, the 2d injection fails.

Eric


>  	struct vgic_dist *dist = &kvm->arch.vgic;
>  	struct kvm_vcpu *vcpu;
> @@ -1541,6 +1542,9 @@ static int vgic_update_irq_pending(struct kvm *kvm, int cpuid,
>  	int enabled;
>  	bool ret = true, can_inject = true;
>  
> +	if (irq_num >= min(kvm->arch.vgic.nr_irqs, 1020))
> +		return -EINVAL;
> +
>  	spin_lock(&dist->lock);
>  
>  	vcpu = kvm_get_vcpu(kvm, cpuid);
> @@ -1603,14 +1607,42 @@ static int vgic_update_irq_pending(struct kvm *kvm, int cpuid,
>  out:
>  	spin_unlock(&dist->lock);
>  
> -	return ret ? cpuid : -EINVAL;
> +	if (!ret) {
> +		/* kick the specified vcpu */
> +		kvm_vcpu_kick(kvm_get_vcpu(kvm, cpuid));
> +	}
> +
> +	return 0;
> +}
> +
> +static int vgic_lazy_init(struct kvm *kvm)
> +{
> +	int ret = 0;
> +
> +	if (unlikely(!vgic_initialized(kvm))) {
> +		/*
> +		 * We only provide the automatic initialization of the VGIC
> +		 * for the legacy case of a GICv2. Any other type must
> +		 * be explicitly initialized once setup with the respective
> +		 * KVM device call.
> +		 */
> +		if (kvm->arch.vgic.vgic_model != KVM_DEV_TYPE_ARM_VGIC_V2)
> +			return -EBUSY;
> +
> +		mutex_lock(&kvm->lock);
> +		ret = vgic_init(kvm);
> +		mutex_unlock(&kvm->lock);
> +	}
> +
> +	return ret;
>  }
>  
>  /**
>   * kvm_vgic_inject_irq - Inject an IRQ from a device to the vgic
>   * @kvm:     The VM structure pointer
>   * @cpuid:   The CPU for PPIs
> - * @irq_num: The IRQ number that is assigned to the device
> + * @irq_num: The IRQ number that is assigned to the device. This IRQ
> + *           must not be mapped to a HW interrupt.
>   * @level:   Edge-triggered:  true:  to trigger the interrupt
>   *			      false: to ignore the call
>   *	     Level-sensitive  true:  activates an interrupt
> @@ -1623,39 +1655,44 @@ out:
>  int kvm_vgic_inject_irq(struct kvm *kvm, int cpuid, unsigned int irq_num,
>  			bool level)
>  {
> -	int ret = 0;
> -	int vcpu_id;
> -
> -	if (unlikely(!vgic_initialized(kvm))) {
> -		/*
> -		 * We only provide the automatic initialization of the VGIC
> -		 * for the legacy case of a GICv2. Any other type must
> -		 * be explicitly initialized once setup with the respective
> -		 * KVM device call.
> -		 */
> -		if (kvm->arch.vgic.vgic_model != KVM_DEV_TYPE_ARM_VGIC_V2) {
> -			ret = -EBUSY;
> -			goto out;
> -		}
> -		mutex_lock(&kvm->lock);
> -		ret = vgic_init(kvm);
> -		mutex_unlock(&kvm->lock);
> +	struct irq_phys_map *map;
> +	int ret;
>  
> -		if (ret)
> -			goto out;
> -	}
> +	ret = vgic_lazy_init(kvm);
> +	if (ret)
> +		return ret;
>  
> -	if (irq_num >= min(kvm->arch.vgic.nr_irqs, 1020))
> +	map = vgic_irq_map_search(kvm_get_vcpu(kvm, cpuid), irq_num);
> +	if (map)
>  		return -EINVAL;
>  
> -	vcpu_id = vgic_update_irq_pending(kvm, cpuid, irq_num, level);
> -	if (vcpu_id >= 0) {
> -		/* kick the specified vcpu */
> -		kvm_vcpu_kick(kvm_get_vcpu(kvm, vcpu_id));
> -	}
> +	return vgic_update_irq_pending(kvm, cpuid, NULL, irq_num, level);
> +}
>  
> -out:
> -	return ret;
> +/**
> + * kvm_vgic_inject_mapped_irq - Inject a physically mapped IRQ to the vgic
> + * @kvm:     The VM structure pointer
> + * @cpuid:   The CPU for PPIs
> + * @map:     Pointer to a irq_phys_map structure describing the mapping
> + * @level:   Edge-triggered:  true:  to trigger the interrupt
> + *			      false: to ignore the call
> + *	     Level-sensitive  true:  activates an interrupt
> + *			      false: deactivates an interrupt
> + *
> + * The GIC is not concerned with devices being active-LOW or active-HIGH for
> + * level-sensitive interrupts.  You can think of the level parameter as 1
> + * being HIGH and 0 being LOW and all devices being active-HIGH.
> + */
> +int kvm_vgic_inject_mapped_irq(struct kvm *kvm, int cpuid,
> +			       struct irq_phys_map *map, bool level)
> +{
> +	int ret;
> +
> +	ret = vgic_lazy_init(kvm);
> +	if (ret)
> +		return ret;
> +
> +	return vgic_update_irq_pending(kvm, cpuid, map, map->virt_irq, level);
>  }
>  
>  static irqreturn_t vgic_maintenance_handler(int irq, void *data)
> 



From m-karicheri2 at ti.com  Tue Aug  4 09:35:40 2015
From: m-karicheri2 at ti.com (Murali Karicheri)
Date: Tue, 4 Aug 2015 12:35:40 -0400
Subject: [PATCH] ARM: keystone: add documentation for SoCs and EVMs
Message-ID: <1438706140-3641-1-git-send-email-m-karicheri2@ti.com>

Currently there is no general documentation on Keystone SoCs in the
Linux Documentation folder of the source tree. This patch adds some
essential documentation with links to help users of Keystone Linux and
also provide links to existing documents where necessary.

Signed-off-by: Murali Karicheri <m-karicheri2 at ti.com>
---
 Documentation/arm/keystone/Overview.txt | 73 +++++++++++++++++++++++++++++++++
 1 file changed, 73 insertions(+)
 create mode 100644 Documentation/arm/keystone/Overview.txt

diff --git a/Documentation/arm/keystone/Overview.txt b/Documentation/arm/keystone/Overview.txt
new file mode 100644
index 0000000..f17bc4c
--- /dev/null
+++ b/Documentation/arm/keystone/Overview.txt
@@ -0,0 +1,73 @@
+		TI Keystone Linux Overview
+		--------------------------
+
+Introduction
+------------
+Keystone range of SoCs are based on ARM Cortex-A15 MPCore Processors
+and c66x DSP cores. This document describes essential information required
+for users to run Linux on Keystone based EVMs from Texas Instruments.
+
+Following SoCs  & EVMs are currently supported:-
+
+------------ K2HK SoC and EVM --------------------------------------------------
+
+a.k.a Keystone 2 Hawking/Kepler SoC
+TCI6636K2H & TCI6636K2K: See documentation at
+	http://www.ti.com/product/tci6638k2k
+	http://www.ti.com/product/tci6638k2h
+
+EVM:
+http://www.advantech.com/Support/TI-EVM/EVMK2HX_sd.aspx
+
+------------ K2E SoC and EVM ---------------------------------------------------
+
+a.k.a Keystone 2 Edison SoC
+K2E  -  66AK2E05: See documentation at
+	http://www.ti.com/product/66AK2E05/technicaldocuments
+
+EVM:
+https://www.einfochips.com/index.php/partnerships/texas-instruments/k2e-evm.html
+
+------------ K2L SoC and EVM ---------------------------------------------------
+
+a.k.a Keystone 2 Lamarr SoC
+K2L  -  TCI6630K2L: See documentation at
+	http://www.ti.com/product/TCI6630K2L/technicaldocuments
+EVM:
+https://www.einfochips.com/index.php/partnerships/texas-instruments/k2l-evm.html
+
+Configuration
+-------------
+
+All of the K2 SoCs/EVMs share a common defconfig, keystone_defconfig and same
+image is used to boot on individual EVMs. The platform configuration is
+specified through DTS. Following are the DTS used:-
+	K2HK EVM : k2hk-evm.dts
+	K2E EVM  : k2e-evm.dts
+	K2L EVM  : k2l-evm.dts
+
+The device tree documentation for the keystone machines are located at
+        Documentation/devicetree/bindings/arm/keystone/keystone.txt
+
+Known issues & workaround
+-------------------------
+
+Some of the device drivers used on keystone are re-used from that from
+DaVinci and other TI SoCs. These device drivers may use clock APIs directly.
+Some of the keystone specific drivers such as netcp uses run time power
+management API instead to enable clock. As this API has limitations on
+keystone, following workaround is needed to boot Linux.
+
+   Add 'clk_ignore_unused' to the bootargs env variable in u-boot. Otherwise
+   clock frameworks will try to disable clocks that are unused and disable
+   the hardware. This is because netcp related power domain and clock
+   domains are enabled in u-boot as run time power management API currently
+   doesn't enable clocks for netcp due to a limitation. This workaround is
+   expected to be removed in the future when proper API support becomes
+   available. Until then, this work around is needed.
+
+
+Document Author
+---------------
+Murali Karicheri <m-karicheri2 at ti.com>
+Copyright 2015 Texas Instruments
-- 
1.9.1



From mark.rutland at arm.com  Tue Aug  4 09:27:34 2015
From: mark.rutland at arm.com (Mark Rutland)
Date: Tue,  4 Aug 2015 17:27:34 +0100
Subject: [PATCH] arm64: make ll/sc __cmpxchg_case_##name asm consistent
Message-ID: <1438705654-12583-1-git-send-email-mark.rutland@arm.com>

The ll/sc __cmpxchg_case_##name assembly mostly uses symbolic names for
operands, but in a single case uses %2 to refer to what is otherwise
known as %[v]. This makes the code more painful to read than is
necessary.

Use %[v] instead.

Signed-off-by: Mark Rutland <mark.rutland at arm.com>
Cc: Will Deacon <will.deacon at arm.com>
---
 arch/arm64/include/asm/atomic_ll_sc.h | 2 +-
 1 file changed, 1 insertion(+), 1 deletion(-)

Hi Will,

I spotted this on the arm64 for-next/core branch, it applies atop of "arm64:
atomics: prefetch the destination word for write prior to stxr" from your
armv8.1/lse branch.

Mark.

diff --git a/arch/arm64/include/asm/atomic_ll_sc.h b/arch/arm64/include/asm/atomic_ll_sc.h
index 6671978..b3b5c4a 100644
--- a/arch/arm64/include/asm/atomic_ll_sc.h
+++ b/arch/arm64/include/asm/atomic_ll_sc.h
@@ -181,7 +181,7 @@ __LL_SC_PREFIX(__cmpxchg_case_##name(volatile void *ptr,		\
 	unsigned long tmp, oldval;					\
 									\
 	asm volatile(							\
-	"	prfm	pstl1strm, %2\n"				\
+	"	prfm	pstl1strm, %[v]\n"				\
 	"1:	ldxr" #sz "\t%" #w "[oldval], %[v]\n"			\
 	"	eor	%" #w "[tmp], %" #w "[oldval], %" #w "[old]\n"	\
 	"	cbnz	%" #w "[tmp], 2f\n"				\
-- 
1.9.1



From m-karicheri2 at ti.com  Tue Aug  4 09:36:43 2015
From: m-karicheri2 at ti.com (Murali Karicheri)
Date: Tue, 4 Aug 2015 12:36:43 -0400
Subject: [Resend: PATCH] ARM: keystone: add documentation for SoCs and EVMs
Message-ID: <1438706203-3748-1-git-send-email-m-karicheri2@ti.com>

Currently there is no general documentation on Keystone SoCs in the
Linux Documentation folder of the source tree. This patch adds some
essential documentation with links to help users of Keystone Linux and
also provide links to existing documents where necessary.

Signed-off-by: Murali Karicheri <m-karicheri2 at ti.com>
---
 - Resend copying maintainer for documentation
 Documentation/arm/keystone/Overview.txt | 73 +++++++++++++++++++++++++++++++++
 1 file changed, 73 insertions(+)
 create mode 100644 Documentation/arm/keystone/Overview.txt

diff --git a/Documentation/arm/keystone/Overview.txt b/Documentation/arm/keystone/Overview.txt
new file mode 100644
index 0000000..f17bc4c
--- /dev/null
+++ b/Documentation/arm/keystone/Overview.txt
@@ -0,0 +1,73 @@
+		TI Keystone Linux Overview
+		--------------------------
+
+Introduction
+------------
+Keystone range of SoCs are based on ARM Cortex-A15 MPCore Processors
+and c66x DSP cores. This document describes essential information required
+for users to run Linux on Keystone based EVMs from Texas Instruments.
+
+Following SoCs  & EVMs are currently supported:-
+
+------------ K2HK SoC and EVM --------------------------------------------------
+
+a.k.a Keystone 2 Hawking/Kepler SoC
+TCI6636K2H & TCI6636K2K: See documentation at
+	http://www.ti.com/product/tci6638k2k
+	http://www.ti.com/product/tci6638k2h
+
+EVM:
+http://www.advantech.com/Support/TI-EVM/EVMK2HX_sd.aspx
+
+------------ K2E SoC and EVM ---------------------------------------------------
+
+a.k.a Keystone 2 Edison SoC
+K2E  -  66AK2E05: See documentation at
+	http://www.ti.com/product/66AK2E05/technicaldocuments
+
+EVM:
+https://www.einfochips.com/index.php/partnerships/texas-instruments/k2e-evm.html
+
+------------ K2L SoC and EVM ---------------------------------------------------
+
+a.k.a Keystone 2 Lamarr SoC
+K2L  -  TCI6630K2L: See documentation at
+	http://www.ti.com/product/TCI6630K2L/technicaldocuments
+EVM:
+https://www.einfochips.com/index.php/partnerships/texas-instruments/k2l-evm.html
+
+Configuration
+-------------
+
+All of the K2 SoCs/EVMs share a common defconfig, keystone_defconfig and same
+image is used to boot on individual EVMs. The platform configuration is
+specified through DTS. Following are the DTS used:-
+	K2HK EVM : k2hk-evm.dts
+	K2E EVM  : k2e-evm.dts
+	K2L EVM  : k2l-evm.dts
+
+The device tree documentation for the keystone machines are located at
+        Documentation/devicetree/bindings/arm/keystone/keystone.txt
+
+Known issues & workaround
+-------------------------
+
+Some of the device drivers used on keystone are re-used from that from
+DaVinci and other TI SoCs. These device drivers may use clock APIs directly.
+Some of the keystone specific drivers such as netcp uses run time power
+management API instead to enable clock. As this API has limitations on
+keystone, following workaround is needed to boot Linux.
+
+   Add 'clk_ignore_unused' to the bootargs env variable in u-boot. Otherwise
+   clock frameworks will try to disable clocks that are unused and disable
+   the hardware. This is because netcp related power domain and clock
+   domains are enabled in u-boot as run time power management API currently
+   doesn't enable clocks for netcp due to a limitation. This workaround is
+   expected to be removed in the future when proper API support becomes
+   available. Until then, this work around is needed.
+
+
+Document Author
+---------------
+Murali Karicheri <m-karicheri2 at ti.com>
+Copyright 2015 Texas Instruments
-- 
1.9.1



From julien.grall at citrix.com  Tue Aug  4 09:36:55 2015
From: julien.grall at citrix.com (Julien Grall)
Date: Tue, 4 Aug 2015 17:36:55 +0100
Subject: [Xen-devel] [PATCH 1/8] arm/xen: Remove helpers which are PV
 specific
In-Reply-To: <1438340142.30740.57.camel@citrix.com>
References: <1438095769-2560-1-git-send-email-julien.grall@citrix.com>
 <1438095769-2560-2-git-send-email-julien.grall@citrix.com>
 <alpine.DEB.2.02.1507311142580.11337@kaball.uk.xensource.com>
 <1438340142.30740.57.camel@citrix.com>
Message-ID: <55C0EA27.60608@citrix.com>

Hi,

On 31/07/15 11:55, Ian Campbell wrote:
>>> +/* Only used in PV code. However ARM guest is always assimilated as 
>>> HVM. */
>>                                ^ "However" doesn't make sense here from an
>>                                english grammer point of view.
> 
> "English grammar" :-P
> 
> Sorry. What I really meant to say was that "assimilated" doesn't make sense
> in this context either. I think maybe what was meant is "ARM guests are
> always HVM".

Yes. I will update the commit message too.

Regards,

-- 
Julien Grall


From marc.zyngier at arm.com  Tue Aug  4 09:44:37 2015
From: marc.zyngier at arm.com (Marc Zyngier)
Date: Tue, 04 Aug 2015 17:44:37 +0100
Subject: [PATCH v3 09/11] KVM: arm/arm64: vgic: Prevent userspace injection
 of a mapped interrupt
In-Reply-To: <55C0E690.1090808@linaro.org>
References: <1437753309-17989-1-git-send-email-marc.zyngier@arm.com>
 <1437753309-17989-10-git-send-email-marc.zyngier@arm.com>
 <55C0E690.1090808@linaro.org>
Message-ID: <55C0EBF5.2060708@arm.com>

On 04/08/15 17:21, Eric Auger wrote:
> Hi Marc,
> On 07/24/2015 05:55 PM, Marc Zyngier wrote:
>> Virtual interrupts mapped to a HW interrupt should only be triggered
>> from inside the kernel. Otherwise, you could end up confusing the
>> kernel (and the GIC's) state machine.
>>
>> Rearrange the injection path so that kvm_vgic_inject_irq is
>> used for non-mapped interrupts, and kvm_vgic_inject_mapped_irq is
>> used for mapped interrupts. The latter should only be called from
>> inside the kernel (timer, VFIO).
> nit: I would replace VFIO by irqfd.
> VFIO just triggers the eventfd/irqfd. This is KVM/irqfd that injects the
> virtual irq upon the irqfd signaling and he irqfd adaptation/ARM
> currently is implemented in vgic.c

Ah, thanks for reminding me of the right terminology, I tend to think of
it as one big bag of nasty tricks... ;-)

I'll update the commit message.

>>
>> Signed-off-by: Marc Zyngier <marc.zyngier at arm.com>
>> ---
>>  include/kvm/arm_vgic.h |  2 +
>>  virt/kvm/arm/vgic.c    | 99 ++++++++++++++++++++++++++++++++++----------------
>>  2 files changed, 70 insertions(+), 31 deletions(-)
>>
>> diff --git a/include/kvm/arm_vgic.h b/include/kvm/arm_vgic.h
>> index 7306b4b..f6bfd79 100644
>> --- a/include/kvm/arm_vgic.h
>> +++ b/include/kvm/arm_vgic.h
>> @@ -351,6 +351,8 @@ void kvm_vgic_flush_hwstate(struct kvm_vcpu *vcpu);
>>  void kvm_vgic_sync_hwstate(struct kvm_vcpu *vcpu);
>>  int kvm_vgic_inject_irq(struct kvm *kvm, int cpuid, unsigned int irq_num,
>>  			bool level);
>> +int kvm_vgic_inject_mapped_irq(struct kvm *kvm, int cpuid,
>> +			       struct irq_phys_map *map, bool level);
>>  void vgic_v3_dispatch_sgi(struct kvm_vcpu *vcpu, u64 reg);
>>  int kvm_vgic_vcpu_pending_irq(struct kvm_vcpu *vcpu);
>>  int kvm_vgic_vcpu_active_irq(struct kvm_vcpu *vcpu);
>> diff --git a/virt/kvm/arm/vgic.c b/virt/kvm/arm/vgic.c
>> index 3f7b690..e40ef70 100644
>> --- a/virt/kvm/arm/vgic.c
>> +++ b/virt/kvm/arm/vgic.c
>> @@ -1533,7 +1533,8 @@ static int vgic_validate_injection(struct kvm_vcpu *vcpu, int irq, int level)
>>  }
>>  
>>  static int vgic_update_irq_pending(struct kvm *kvm, int cpuid,
>> -				  unsigned int irq_num, bool level)
>> +				   struct irq_phys_map *map,
>> +				   unsigned int irq_num, bool level)
>>  {
> In vgic_update_irq_pending, I needed to modify the following line and
> add the "&& !map".
> 
>         if (!vgic_validate_injection(vcpu, irq_num, level) && !map) {
> 
> Without that, the level being not properly modeled for level sensitive
> forwarded IRQs, the 2d injection fails.

Ah! Is that because we never see the line being reset to zero, and the
VGIC still sees the line as pending at the distributor level?

Thanks,

	M.
-- 
Jazz is not dead. It just smells funny...


From marc.zyngier at arm.com  Tue Aug  4 10:08:53 2015
From: marc.zyngier at arm.com (Marc Zyngier)
Date: Tue, 04 Aug 2015 18:08:53 +0100
Subject: [PATCH v3 11/11] KVM: arm/arm64: vgic: Allow HW interrupts for
 non-shared devices
In-Reply-To: <20150804143209.GD29335@cbox>
References: <1437753309-17989-1-git-send-email-marc.zyngier@arm.com>
 <1437753309-17989-12-git-send-email-marc.zyngier@arm.com>
 <20150804143209.GD29335@cbox>
Message-ID: <55C0F1A5.1070204@arm.com>

On 04/08/15 15:32, Christoffer Dall wrote:
> On Fri, Jul 24, 2015 at 04:55:09PM +0100, Marc Zyngier wrote:
>> So far, the only use of the HW interrupt facility is the timer,
>> implying that the active state is context-switched for each vcpu,
>> as the device is is shared across all vcpus.
>>
>> This does not work for a device that has been assigned to a VM,
>> as the guest is entierely in control of that device (the HW is
>> not shared). In that case, it makes sense to bypass the whole
>> active state switching, and only track the deactivation of the
>> interrupt.
>>
>> Signed-off-by: Marc Zyngier <marc.zyngier at arm.com>
>> ---
>>  include/kvm/arm_vgic.h    |  6 ++--
>>  virt/kvm/arm/arch_timer.c |  3 +-
>>  virt/kvm/arm/vgic.c       | 73 +++++++++++++++++++++++++++++++++++++----------
>>  3 files changed, 64 insertions(+), 18 deletions(-)
>>
>> diff --git a/include/kvm/arm_vgic.h b/include/kvm/arm_vgic.h
>> index f6bfd79..6f0a4e1 100644
>> --- a/include/kvm/arm_vgic.h
>> +++ b/include/kvm/arm_vgic.h
>> @@ -164,7 +164,8 @@ struct irq_phys_map {
>>  	u32			phys_irq;
>>  	u32			irq;
>>  	bool			deleted;
>> -	bool			active;
>> +	bool			shared;
>> +	bool			active; /* Only valid if shared */
>>  };
>>  
>>  struct irq_phys_map_entry {
>> @@ -357,7 +358,8 @@ void vgic_v3_dispatch_sgi(struct kvm_vcpu *vcpu, u64 reg);
>>  int kvm_vgic_vcpu_pending_irq(struct kvm_vcpu *vcpu);
>>  int kvm_vgic_vcpu_active_irq(struct kvm_vcpu *vcpu);
>>  struct irq_phys_map *kvm_vgic_map_phys_irq(struct kvm_vcpu *vcpu,
>> -					   int virt_irq, int irq);
>> +					   int virt_irq, int irq,
>> +					   bool shared);
>>  int kvm_vgic_unmap_phys_irq(struct kvm_vcpu *vcpu, struct irq_phys_map *map);
>>  bool kvm_vgic_get_phys_irq_active(struct irq_phys_map *map);
>>  void kvm_vgic_set_phys_irq_active(struct irq_phys_map *map, bool active);
>> diff --git a/virt/kvm/arm/arch_timer.c b/virt/kvm/arm/arch_timer.c
>> index 76e38d2..db21d8f 100644
>> --- a/virt/kvm/arm/arch_timer.c
>> +++ b/virt/kvm/arm/arch_timer.c
>> @@ -203,7 +203,8 @@ int kvm_timer_vcpu_reset(struct kvm_vcpu *vcpu,
>>  	 * Tell the VGIC that the virtual interrupt is tied to a
>>  	 * physical interrupt. We do that once per VCPU.
>>  	 */
>> -	map = kvm_vgic_map_phys_irq(vcpu, irq->irq, host_vtimer_irq);
>> +	map = kvm_vgic_map_phys_irq(vcpu, irq->irq,
>> +				    host_vtimer_irq, true);
>>  	if (WARN_ON(IS_ERR(map)))
>>  		return PTR_ERR(map);
>>  
>> diff --git a/virt/kvm/arm/vgic.c b/virt/kvm/arm/vgic.c
>> index e40ef70..5e6b816 100644
>> --- a/virt/kvm/arm/vgic.c
>> +++ b/virt/kvm/arm/vgic.c
>> @@ -1128,19 +1128,25 @@ static void vgic_queue_irq_to_lr(struct kvm_vcpu *vcpu, int irq,
>>  		 * active in the physical world. Otherwise the
>>  		 * physical interrupt will fire and the guest will
>>  		 * exit before processing the virtual interrupt.
>> +		 *
>> +		 * This is of course only valid for a shared
>> +		 * interrupt. A non shared interrupt should already be
>> +		 * active.
>>  		 */
>>  		if (map) {
>> -			int ret;
>> -
>> -			BUG_ON(!map->active);
>>  			vlr.hwirq = map->phys_irq;
>>  			vlr.state |= LR_HW;
>>  			vlr.state &= ~LR_EOI_INT;
>>  
>> -			ret = irq_set_irqchip_state(map->irq,
>> -						    IRQCHIP_STATE_ACTIVE,
>> -						    true);
>> -			WARN_ON(ret);
>> +			if (map->shared) {
>> +				int ret;
>> +
>> +				BUG_ON(!map->active);
>> +				ret = irq_set_irqchip_state(map->irq,
>> +							    IRQCHIP_STATE_ACTIVE,
>> +							    true);
>> +				WARN_ON(ret);
>> +			}
>>  
>>  			/*
>>  			 * Make sure we're not going to sample this
>> @@ -1383,21 +1389,41 @@ static bool vgic_process_maintenance(struct kvm_vcpu *vcpu)
>>  static int vgic_sync_hwirq(struct kvm_vcpu *vcpu, struct vgic_lr vlr)
>>  {
>>  	struct irq_phys_map *map;
>> +	bool active;
>>  	int ret;
>>  
>>  	if (!(vlr.state & LR_HW))
>>  		return 0;
>>  
>>  	map = vgic_irq_map_search(vcpu, vlr.irq);
>> -	BUG_ON(!map || !map->active);
>> +	BUG_ON(!map);
>> +	BUG_ON(map->shared && !map->active);
>>  
>>  	ret = irq_get_irqchip_state(map->irq,
>>  				    IRQCHIP_STATE_ACTIVE,
>> -				    &map->active);
>> +				    &active);
>>  
>>  	WARN_ON(ret);
>>  
>> -	if (map->active) {
>> +	/*
>> +	 * For a non-shared interrupt, we have to cater for two
>> +	 * possible deactivation conditions:
>> +	 *
>> +	 * - the physical interrupt is now inactive (EOIed from the
>> +         *   guest)
> 
> nit: whitespace funkyness
> 
>> +	 * - the physical interrupt is still active, but its virtual
>> +	 *   counterpart is flagged as "not queued", indicating another
>> +	 *   interrupt has fired between the EOI and the guest exit.
>> +	 *
>> +	 * Also, we are not reactivating a non-shared interrupt
> 
> what does reactivating mean? did you mean deactivate?

Deactivate indeed.

>> +	 * ourselves. This is always left to the guest.
> 
> In which case, add ", because the device is solely owned by the guest."

Sure.

>> +	 */
>> +	if (!map->shared)
>> +		return !active || !vgic_irq_is_queued(vcpu, vlr.irq);
> 
> do you really need the second part of the disjunction?
> 
> The effect seems to be that we clear the queued flag once again, and
> clear the LR.  If we don't do this, won't we simply pick up the pending
> flag next time we're about to run this VCPU and piggy-back on the
> existing LR.  Perhaps this is a weird flow though?

Crucially, we free the LR in this case (the set_bit on elrsr_ptr). If we
don't do this, we're indeed going to schedule the vcpu (it has something
to process), but we never allow piggy-backing on level interrupts. We'd
need some special hack to handle this.

I definitely feel more comfortable reporting that the interrupt has been
deactivated (which is the case), and let the normal flow pick up the
next injected interrupt.

> 
>> +
>> +	map->active = active;
>> +
>> +	if (active) {
>>  		ret = irq_set_irqchip_state(map->irq,
>>  					    IRQCHIP_STATE_ACTIVE,
>>  					    false);
>> @@ -1590,6 +1616,17 @@ static int vgic_update_irq_pending(struct kvm *kvm, int cpuid,
>>  		goto out;
>>  	}
>>  
>> +	if (map && !map->shared) {
>> +		/*
>> +		 * We are told to inject a HW irq, so we have to trust
>> +		 * the caller that the previous one has been EOIed,
>> +		 * and that a new one is now active. Clearing the
>> +		 * queued state will have the effect of making it
>> +		 * sample-able again.
>> +		 */
>> +		vgic_irq_clear_queued(vcpu, irq_num);
>> +	}
>> +
>>  	if (!vgic_can_sample_irq(vcpu, irq_num)) {
>>  		/*
>>  		 * Level interrupt in progress, will be picked up
>> @@ -1720,15 +1757,19 @@ static struct list_head *vgic_get_irq_phys_map_list(struct kvm_vcpu *vcpu,
>>   * @vcpu: The VCPU pointer
>>   * @virt_irq: The virtual irq number
>>   * @irq: The Linux IRQ number
>> + * @shared: Indicates if the interrupt has to be context-switched or
>> + *          if it is private to a VM
>>   *
>>   * Establish a mapping between a guest visible irq (@virt_irq) and a
>>   * Linux irq (@irq). On injection, @virt_irq will be associated with
>> - * the physical interrupt represented by @irq.
>> + * the physical interrupt represented by @irq. If @shared is true,
>> + * the active state of the interrupt will be context-switched.
>>   *
>>   * Returns a valid pointer on success, and an error pointer otherwise
>>   */
>>  struct irq_phys_map *kvm_vgic_map_phys_irq(struct kvm_vcpu *vcpu,
>> -					   int virt_irq, int irq)
>> +					   int virt_irq, int irq,
>> +					   bool shared)
>>  {
>>  	struct vgic_dist *dist = &vcpu->kvm->arch.vgic;
>>  	struct list_head *root = vgic_get_irq_phys_map_list(vcpu, virt_irq);
>> @@ -1762,7 +1803,8 @@ struct irq_phys_map *kvm_vgic_map_phys_irq(struct kvm_vcpu *vcpu,
>>  	if (map) {
>>  		/* Make sure this mapping matches */
>>  		if (map->phys_irq != phys_irq	||
>> -		    map->irq      != irq)
>> +		    map->irq      != irq	||
>> +		    map->shared   != shared)
>>  			map = ERR_PTR(-EINVAL);
>>  
>>  		goto out;
>> @@ -1772,6 +1814,7 @@ struct irq_phys_map *kvm_vgic_map_phys_irq(struct kvm_vcpu *vcpu,
>>  	map->virt_irq = virt_irq;
>>  	map->phys_irq = phys_irq;
>>  	map->irq      = irq;
>> +	map->shared   = shared;
>>  
>>  	list_add_tail_rcu(&entry->entry, root);
>>  
>> @@ -1822,7 +1865,7 @@ static void vgic_free_phys_irq_map_rcu(struct rcu_head *rcu)
>>   */
>>  bool kvm_vgic_get_phys_irq_active(struct irq_phys_map *map)
>>  {
>> -	BUG_ON(!map);
>> +	BUG_ON(!map || !map->shared);
>>  	return map->active;
>>  }
>>  
>> @@ -1834,7 +1877,7 @@ bool kvm_vgic_get_phys_irq_active(struct irq_phys_map *map)
>>   */
>>  void kvm_vgic_set_phys_irq_active(struct irq_phys_map *map, bool active)
>>  {
>> -	BUG_ON(!map);
>> +	BUG_ON(!map || !map->shared);
>>  	map->active = active;
>>  }
>>  
>> -- 
>> 2.1.4
>>
> 
> I think I'm seeing this in the correct light this time around, so this
> is functionally looking pretty good to me.
> 
> Thanks,
> -Christoffer
> 

Thanks,

	M.
-- 
Jazz is not dead. It just smells funny...


From ross.zwisler at linux.intel.com  Tue Aug  4 09:53:40 2015
From: ross.zwisler at linux.intel.com (Ross Zwisler)
Date: Tue, 04 Aug 2015 10:53:40 -0600
Subject: [PATCH v3 24/24] pmem: convert to generic memremap
In-Reply-To: <CAPcyv4gCPyXwwgjidaUaNyNe8ZitmwVa-NF7pBT-y3rV4XBUzA@mail.gmail.com>
References: <20150730165155.33962.64121.stgit@dwillia2-desk3.amr.corp.intel.com>
 <20150730165553.33962.20257.stgit@dwillia2-desk3.amr.corp.intel.com>
 <1438622487.9404.2.camel@linux.intel.com>
 <CAPcyv4gCPyXwwgjidaUaNyNe8ZitmwVa-NF7pBT-y3rV4XBUzA@mail.gmail.com>
Message-ID: <1438707220.12666.7.camel@linux.intel.com>

On Mon, 2015-08-03 at 11:01 -0700, Dan Williams wrote:
> On Mon, Aug 3, 2015 at 10:21 AM, Ross Zwisler
> <ross.zwisler at linux.intel.com> wrote:
> > On Thu, 2015-07-30 at 12:55 -0400, Dan Williams wrote:
> >> Update memremap_pmem() to query the architecture for the mapping type of
> >> the given persistent memory range  and then pass those flags to generic
> >> memremap().  arch_memremap_pmem_flags() is provided an address range to
> >> evaluate in the event an arch has a need for different mapping types by
> >> address range.  For example the ACPI NFIT carries EFI mapping types in
> >> its memory range description table.
> >>
> >> Cc: Ross Zwisler <ross.zwisler at linux.intel.com>
> >> Signed-off-by: Dan Williams <dan.j.williams at intel.com>

Reviewed-by: Ross Zwisler <ross.zwisler at linux.intel.com>




From broonie at kernel.org  Tue Aug  4 10:19:31 2015
From: broonie at kernel.org (Mark Brown)
Date: Tue, 4 Aug 2015 18:19:31 +0100
Subject: [PATCH] spi: spi-sun4i, spi-sun6i: Fix bit rate calculation
In-Reply-To: <op.x2pmc5kiltbbtz@localhost>
References: <op.x2pmc5kiltbbtz@localhost>
Message-ID: <20150804171931.GZ20873@sirena.org.uk>

On Sun, Aug 02, 2015 at 12:06:31AM +0200, Hermann Kraus wrote:

> +	u32 speed_hz = tfr->speed_hz ? : spi->max_speed_hz;

You don't need to do this anyway since the framework will always ensure
that speed_hz is set so you can just use it unconditionally but in
general please don't use the ternery operator unless it's adding
something, it's not a legibility triumph.
-------------- next part --------------
A non-text attachment was scrubbed...
Name: signature.asc
Type: application/pgp-signature
Size: 473 bytes
Desc: Digital signature
URL: <http://lists.infradead.org/pipermail/linux-arm-kernel/attachments/20150804/c2012e8d/attachment.sig>

From balbi at ti.com  Tue Aug  4 10:29:33 2015
From: balbi at ti.com (Felipe Balbi)
Date: Tue, 4 Aug 2015 12:29:33 -0500
Subject: [PATCH v5 00/46] usb: gadget: rework ep matching and claiming
 mechanism
In-Reply-To: <1438351258-31578-1-git-send-email-r.baldyga@samsung.com>
References: <1438351258-31578-1-git-send-email-r.baldyga@samsung.com>
Message-ID: <20150804172933.GB9623@saruman.tx.rr.com>

Hi,

On Fri, Jul 31, 2015 at 04:00:12PM +0200, Robert Baldyga wrote:
> Hello,
> 
> This patch series reworks endpoint matching and claiming mechanism in
> epautoconf. From v2 there are couple of new patches adding 'ep_match'
> to usb_gadget_ops and removing chip-specific quirk handling from generic
> code of autoconfig.
> 
> I'm not sure if this patch set isn't too long, as it has 46 patches,
> but I decided to send it as single series to avoid problems with patch
> applying order.
> 
> The aim of whole patchset is to rework epautoconf code to get rid of
> things like name-based endpoint matching and UDC name-based quirks in
> generic code. These needed to do some modifications in framework like
> adding 'endpoint capabilities flags' feature or adding 'match_ep'.
> 
> Following paragraphs contain brief description of what modifications are
> done by particular parts of this patch set:
> 
> Patch (1) introduces new safer endpoint claiming method, basing on new
> 'claimed' flag. It was discussed here [1]. I proposed this solution over
> year ago and it was accepted, but I apparently forgot to send the final
> version of my patch.
> 
> Patches (2-3) add the 'capabilities flags' structure and helper macros.
> This solution is inspired by the 'feature flags' originally proposed
> by Felipe Balbi in 2013 [2], but unfortunately implementation of this
> feature has never been completed.
> 
> Patches (4-36) add' capabilites flags' support to all UDC drivers present
> in the kernel tree. It's needed to be done before replacing old endpoint
> matching mechanism, otherwise UDC drivers which doesn't set 'capabilities
> flags' won't work with new matching function.
> 
> Patch (37) finally replaces old endpoint matching method with the new
> one basing on capabilities flags.
> 
> These changes aims to get rid of code, which guesses endpoint capabilities
> basing on it's name, and introduce new better replacement. In result
> we have better way to describe types and directions supported by each
> endpoint.
> 
> For example the old name-based method didn't allow to have endpoint
> supporing two types of transfers - there were only ability to support
> one or all of endpoint types. The 'capabilities flags' feature supply
> precise, flexible and extensible mechanism of description of endpoint
> hardware limitations, which is desired for proper endpoint matching.
> 
> Patch (38) removes chip-specific quirk from ep_matches() function.
> 
> Patches (39-40) remove code modifying endpoint and descriptor structures
> from ep_matches() function and cleans it up to make it simpler and more
> readable.
> 
> Patch (41) add 'match_ep' callback to usb_gadget_ops and make use of
> it in epautoconf. This callback allows UDC drivers to supply non-standard
> endpoint matching algorithms.
> 
> Patches (42-43) move ep_matches() and find_ep() functions outside
> epautoconf and rename them to usb_gadget_ep_match_desc() and
> gadget_find_ep_by_name(). It's because they may be useful in 'match_ep'
> callbacks in UDC drivers to avoid writing repetitive code.
> 
> Patches (44-46) move chip-specific enpoint matching algorithms from
> generic code of usb_ep_autoconfig_ss() function to UDC controller drivers
> using 'match_ep' callback.
> 
> In the result we have epautoconf source free of chip-specific code, plus
> two new mechanisms allowing to handle non-standard hardware limitations.
> 
> [1] https://lkml.org/lkml/2014/6/16/94
> [2] http://www.spinics.net/lists/linux-usb/msg99662.html

adding these to my testing/next after fixing a few build warnings and
the comment I had on dwc3 patch. Let's hope it just works :-)

-- 
balbi
-------------- next part --------------
A non-text attachment was scrubbed...
Name: signature.asc
Type: application/pgp-signature
Size: 819 bytes
Desc: Digital signature
URL: <http://lists.infradead.org/pipermail/linux-arm-kernel/attachments/20150804/d563ca16/attachment.sig>

From christoffer.dall at linaro.org  Tue Aug  4 10:36:50 2015
From: christoffer.dall at linaro.org (Christoffer Dall)
Date: Tue, 4 Aug 2015 19:36:50 +0200
Subject: [PATCH v3 06/11] KVM: arm/arm64: vgic: Allow dynamic mapping of
 physical/virtual interrupts
In-Reply-To: <55C0D9C7.7060707@arm.com>
References: <1437753309-17989-1-git-send-email-marc.zyngier@arm.com>
 <1437753309-17989-7-git-send-email-marc.zyngier@arm.com>
 <20150804130457.GA29335@cbox> <55C0D9C7.7060707@arm.com>
Message-ID: <20150804173650.GG29335@cbox>

On Tue, Aug 04, 2015 at 04:27:03PM +0100, Marc Zyngier wrote:
> On 04/08/15 14:04, Christoffer Dall wrote:
> > On Fri, Jul 24, 2015 at 04:55:04PM +0100, Marc Zyngier wrote:
> >> In order to be able to feed physical interrupts to a guest, we need
> >> to be able to establish the virtual-physical mapping between the two
> >> worlds.
> >>
> >> The mappings are kept in a set of RCU lists, indexed by virtual interrupts.
> >>
> >> Signed-off-by: Marc Zyngier <marc.zyngier at arm.com>
> >> ---
> >>  arch/arm/kvm/arm.c     |   2 +
> >>  include/kvm/arm_vgic.h |  26 +++++++
> >>  virt/kvm/arm/vgic.c    | 189 ++++++++++++++++++++++++++++++++++++++++++++++++-
> >>  3 files changed, 216 insertions(+), 1 deletion(-)
> >>
> >> diff --git a/arch/arm/kvm/arm.c b/arch/arm/kvm/arm.c
> >> index f1bf418..ce404a5 100644
> >> --- a/arch/arm/kvm/arm.c
> >> +++ b/arch/arm/kvm/arm.c
> >> @@ -125,6 +125,7 @@ int kvm_arch_init_vm(struct kvm *kvm, unsigned long type)
> >>       if (ret)
> >>               goto out_free_stage2_pgd;
> >>
> >> +     kvm_vgic_early_init(kvm);
> >>       kvm_timer_init(kvm);
> >>
> >>       /* Mark the initial VMID generation invalid */
> >> @@ -249,6 +250,7 @@ out:
> >>
> >>  void kvm_arch_vcpu_postcreate(struct kvm_vcpu *vcpu)
> >>  {
> >> +     kvm_vgic_vcpu_early_init(vcpu);
> >>  }
> >>
> >>  void kvm_arch_vcpu_free(struct kvm_vcpu *vcpu)
> >> diff --git a/include/kvm/arm_vgic.h b/include/kvm/arm_vgic.h
> >> index a881e39..68212a1 100644
> >> --- a/include/kvm/arm_vgic.h
> >> +++ b/include/kvm/arm_vgic.h
> >> @@ -159,6 +159,20 @@ struct vgic_io_device {
> >>       struct kvm_io_device dev;
> >>  };
> >>
> >> +struct irq_phys_map {
> >> +     u32                     virt_irq;
> >> +     u32                     phys_irq;
> >> +     u32                     irq;
> >> +     bool                    deleted;
> >> +     bool                    active;
> >> +};
> >> +
> >> +struct irq_phys_map_entry {
> >> +     struct list_head        entry;
> >> +     struct rcu_head         rcu;
> >> +     struct irq_phys_map     map;
> >> +};
> >> +
> >>  struct vgic_dist {
> >>       spinlock_t              lock;
> >>       bool                    in_kernel;
> >> @@ -256,6 +270,10 @@ struct vgic_dist {
> >>       struct vgic_vm_ops      vm_ops;
> >>       struct vgic_io_device   dist_iodev;
> >>       struct vgic_io_device   *redist_iodevs;
> >> +
> >> +     /* Virtual irq to hwirq mapping */
> >> +     spinlock_t              irq_phys_map_lock;
> >> +     struct list_head        irq_phys_map_list;
> >>  };
> >>
> >>  struct vgic_v2_cpu_if {
> >> @@ -307,6 +325,9 @@ struct vgic_cpu {
> >>               struct vgic_v2_cpu_if   vgic_v2;
> >>               struct vgic_v3_cpu_if   vgic_v3;
> >>       };
> >> +
> >> +     /* Protected by the distributor's irq_phys_map_lock */
> >> +     struct list_head        irq_phys_map_list;
> >>  };
> >>
> >>  #define LR_EMPTY     0xff
> >> @@ -321,8 +342,10 @@ int kvm_vgic_addr(struct kvm *kvm, unsigned long type, u64 *addr, bool write);
> >>  int kvm_vgic_hyp_init(void);
> >>  int kvm_vgic_map_resources(struct kvm *kvm);
> >>  int kvm_vgic_get_max_vcpus(void);
> >> +void kvm_vgic_early_init(struct kvm *kvm);
> >>  int kvm_vgic_create(struct kvm *kvm, u32 type);
> >>  void kvm_vgic_destroy(struct kvm *kvm);
> >> +void kvm_vgic_vcpu_early_init(struct kvm_vcpu *vcpu);
> >>  void kvm_vgic_vcpu_destroy(struct kvm_vcpu *vcpu);
> >>  void kvm_vgic_flush_hwstate(struct kvm_vcpu *vcpu);
> >>  void kvm_vgic_sync_hwstate(struct kvm_vcpu *vcpu);
> >> @@ -331,6 +354,9 @@ int kvm_vgic_inject_irq(struct kvm *kvm, int cpuid, unsigned int irq_num,
> >>  void vgic_v3_dispatch_sgi(struct kvm_vcpu *vcpu, u64 reg);
> >>  int kvm_vgic_vcpu_pending_irq(struct kvm_vcpu *vcpu);
> >>  int kvm_vgic_vcpu_active_irq(struct kvm_vcpu *vcpu);
> >> +struct irq_phys_map *kvm_vgic_map_phys_irq(struct kvm_vcpu *vcpu,
> >> +                                        int virt_irq, int irq);
> >> +int kvm_vgic_unmap_phys_irq(struct kvm_vcpu *vcpu, struct irq_phys_map *map);
> >>
> >>  #define irqchip_in_kernel(k) (!!((k)->arch.vgic.in_kernel))
> >>  #define vgic_initialized(k)  (!!((k)->arch.vgic.nr_cpus))
> >> diff --git a/virt/kvm/arm/vgic.c b/virt/kvm/arm/vgic.c
> >> index 5bd1695..c74d929 100644
> >> --- a/virt/kvm/arm/vgic.c
> >> +++ b/virt/kvm/arm/vgic.c
> >> @@ -24,6 +24,7 @@
> >>  #include <linux/of.h>
> >>  #include <linux/of_address.h>
> >>  #include <linux/of_irq.h>
> >> +#include <linux/rculist.h>
> >>  #include <linux/uaccess.h>
> >>
> >>  #include <asm/kvm_emulate.h>
> >> @@ -82,6 +83,8 @@ static void vgic_retire_disabled_irqs(struct kvm_vcpu *vcpu);
> >>  static void vgic_retire_lr(int lr_nr, int irq, struct kvm_vcpu *vcpu);
> >>  static struct vgic_lr vgic_get_lr(const struct kvm_vcpu *vcpu, int lr);
> >>  static void vgic_set_lr(struct kvm_vcpu *vcpu, int lr, struct vgic_lr lr_desc);
> >> +static struct irq_phys_map *vgic_irq_map_search(struct kvm_vcpu *vcpu,
> >> +                                             int virt_irq);
> >>
> >>  static const struct vgic_ops *vgic_ops;
> >>  static const struct vgic_params *vgic;
> >> @@ -1583,6 +1586,166 @@ static irqreturn_t vgic_maintenance_handler(int irq, void *data)
> >>       return IRQ_HANDLED;
> >>  }
> >>
> >> +static struct list_head *vgic_get_irq_phys_map_list(struct kvm_vcpu *vcpu,
> >> +                                                 int virt_irq)
> >> +{
> >> +     if (virt_irq < VGIC_NR_PRIVATE_IRQS)
> >> +             return &vcpu->arch.vgic_cpu.irq_phys_map_list;
> >> +     else
> >> +             return &vcpu->kvm->arch.vgic.irq_phys_map_list;
> >> +}
> >> +
> >> +/**
> >> + * kvm_vgic_map_phys_irq - map a virtual IRQ to a physical IRQ
> >> + * @vcpu: The VCPU pointer
> >> + * @virt_irq: The virtual irq number
> >> + * @irq: The Linux IRQ number
> >> + *
> >> + * Establish a mapping between a guest visible irq (@virt_irq) and a
> >> + * Linux irq (@irq). On injection, @virt_irq will be associated with
> >> + * the physical interrupt represented by @irq.
> >> + *
> >> + * Returns a valid pointer on success, and an error pointer otherwise
> >> + */
> >> +struct irq_phys_map *kvm_vgic_map_phys_irq(struct kvm_vcpu *vcpu,
> >> +                                        int virt_irq, int irq)
> >> +{
> >> +     struct vgic_dist *dist = &vcpu->kvm->arch.vgic;
> >> +     struct list_head *root = vgic_get_irq_phys_map_list(vcpu, virt_irq);
> >> +     struct irq_phys_map *map;
> >> +     struct irq_phys_map_entry *entry;
> >> +     struct irq_desc *desc;
> >> +     struct irq_data *data;
> >> +     int phys_irq;
> >> +
> >> +     desc = irq_to_desc(irq);
> >> +     if (!desc) {
> >> +             kvm_err("kvm_vgic_map_phys_irq: no interrupt descriptor\n");
> > 
> > super over-ridiculous nit:
> > if you respin you could consider "%s: no...", __FUNC__
> 
> Sure.
> 
> > 
> >> +             return ERR_PTR(-EINVAL);
> >> +     }
> >> +
> >> +     data = irq_desc_get_irq_data(desc);
> >> +     while (data->parent_data)
> >> +             data = data->parent_data;
> >> +
> >> +     phys_irq = data->hwirq;
> >> +
> >> +     /* Create a new mapping */
> >> +     entry = kzalloc(sizeof(*entry), GFP_KERNEL);
> >> +     if (!entry)
> >> +             return ERR_PTR(-ENOMEM);
> >> +
> >> +     spin_lock(&dist->irq_phys_map_lock);
> >> +
> >> +     /* Try to match an existing mapping */
> >> +     map = vgic_irq_map_search(vcpu, virt_irq);
> >> +     if (map) {
> >> +             /* Make sure this mapping matches */
> > 
> > why do we need to check that it matches?  Is it ever allowed to have
> > multiple mappings of a virtual interrupt?
> > 
> 
> Multiple *different* mappings, no. What you can have though is issuing
> requests for the *same* mapping repeatedly. This is what happens with
> the timer, for example: kvm_timer_vcpu_reset is going to be called more
> than once over the lifetime of a VM, requesting a mapping each time
> without necessarily destroying the previous one.
> 
> >> +             if (map->phys_irq != phys_irq   ||
> >> +                 map->irq      != irq)
> >> +                     map = ERR_PTR(-EINVAL);
> >> +
> >> +             goto out;
> > 
> > why is this a valid situation?  Shouldn't you return -EEXIST or
> > something instead?  (that would also simplify the error-checking free
> > routine below).
> > 
> > If you want it to be valid to map the same virq to irq multiple times
> > (to free the caller from some bookkeeping, I presume?) then that should
> > be part of the function documentation, and I think we should add a
> > "found existing mapping" comment above the goto out statement.
> 
> Fair enough. I'll add some comments to that effect.
> 

thanks!

> >> +     }
> >> +
> >> +     map           = &entry->map;
> >> +     map->virt_irq = virt_irq;
> >> +     map->phys_irq = phys_irq;
> >> +     map->irq      = irq;
> >> +
> >> +     list_add_tail_rcu(&entry->entry, root);
> >> +
> >> +out:
> >> +     spin_unlock(&dist->irq_phys_map_lock);
> >> +     /* If we've found a hit in the existing list, free the useless
> >> +      * entry */
> >> +     if (IS_ERR(map) || map != &entry->map)
> >> +             kfree(entry);
> >> +     return map;
> >> +}
> >> +
> >> +static struct irq_phys_map *vgic_irq_map_search(struct kvm_vcpu *vcpu,
> >> +                                             int virt_irq)
> >> +{
> >> +     struct list_head *root = vgic_get_irq_phys_map_list(vcpu, virt_irq);
> >> +     struct irq_phys_map_entry *entry;
> >> +     struct irq_phys_map *map;
> >> +
> >> +     rcu_read_lock();
> >> +
> >> +     list_for_each_entry_rcu(entry, root, entry) {
> >> +             map = &entry->map;
> >> +             if (map->virt_irq == virt_irq && !map->deleted) {
> >> +                     rcu_read_unlock();
> >> +                     return map;
> >> +             }
> >> +     }
> >> +
> >> +     rcu_read_unlock();
> >> +
> >> +     return NULL;
> >> +}
> >> +
> >> +static void vgic_free_phys_irq_map_rcu(struct rcu_head *rcu)
> >> +{
> >> +     struct irq_phys_map_entry *entry;
> >> +
> >> +     entry = container_of(rcu, struct irq_phys_map_entry, rcu);
> >> +     kfree(entry);
> >> +}
> >> +
> >> +/**
> >> + * kvm_vgic_unmap_phys_irq - Remove a virtual to physical IRQ mapping
> >> + * @vcpu: The VCPU pointer
> >> + * @map: The pointer to a mapping obtained through kvm_vgic_map_phys_irq
> >> + *
> >> + * Remove an existing mapping between virtual and physical interrupts.
> >> + */
> >> +int kvm_vgic_unmap_phys_irq(struct kvm_vcpu *vcpu, struct irq_phys_map *map)
> >> +{
> >> +     struct vgic_dist *dist = &vcpu->kvm->arch.vgic;
> >> +     struct irq_phys_map_entry *entry;
> >> +     struct list_head *root;
> >> +
> >> +     if (!map)
> >> +             return -EINVAL;
> >> +
> >> +     root = vgic_get_irq_phys_map_list(vcpu, map->virt_irq);
> >> +
> >> +     spin_lock(&dist->irq_phys_map_lock);
> >> +
> >> +     list_for_each_entry(entry, root, entry) {
> >> +             if (&entry->map == map && !map->deleted) {
> >> +                     map->deleted = true;
> > 
> > why do you need the 'deleted' flag?  You now search the list only after
> > holding the lock, so the race I pointed out before doesn't exist
> > anymore.  Is there an additional issue that the deleted flag is taking
> > care of?
> 
> This could still race with a destroy occuring before we take the lock,
> and before we get get RCU to do the cleanup (the list would still be
> populated).
> 

That's not how I understand list_del_rcu; I think it deletes the entry
immediately with the right memory barriers.  It is only the free
operation that happens on rcu sync and can be/is deferred.

So I'm pretty sure that when you search the list after holding the lock,
there is no race.

> > 
> >> +                     list_del_rcu(&entry->entry);
> >> +                     call_rcu(&entry->rcu, vgic_free_phys_irq_map_rcu);
> >> +                     break;
> >> +             }
> >> +     }
> >> +
> >> +     spin_unlock(&dist->irq_phys_map_lock);
> >> +
> >> +     return 0;
> >> +}
> >> +
> >> +static void vgic_destroy_irq_phys_map(struct kvm *kvm, struct list_head *root)
> >> +{
> >> +     struct vgic_dist *dist = &kvm->arch.vgic;
> >> +     struct irq_phys_map_entry *entry;
> >> +
> >> +     spin_lock(&dist->irq_phys_map_lock);
> >> +
> >> +     list_for_each_entry(entry, root, entry) {
> >> +             if (!entry->map.deleted) {
> >> +                     entry->map.deleted = true;
> >> +                     list_del_rcu(&entry->entry);
> >> +                     call_rcu(&entry->rcu, vgic_free_phys_irq_map_rcu);
> >> +             }
> >> +     }
> >> +
> >> +     spin_unlock(&dist->irq_phys_map_lock);
> >> +}
> >> +
> >>  void kvm_vgic_vcpu_destroy(struct kvm_vcpu *vcpu)
> >>  {
> >>       struct vgic_cpu *vgic_cpu = &vcpu->arch.vgic_cpu;
> >> @@ -1591,6 +1754,7 @@ void kvm_vgic_vcpu_destroy(struct kvm_vcpu *vcpu)
> >>       kfree(vgic_cpu->active_shared);
> >>       kfree(vgic_cpu->pend_act_shared);
> >>       kfree(vgic_cpu->vgic_irq_lr_map);
> >> +     vgic_destroy_irq_phys_map(vcpu->kvm, &vgic_cpu->irq_phys_map_list);
> >>       vgic_cpu->pending_shared = NULL;
> >>       vgic_cpu->active_shared = NULL;
> >>       vgic_cpu->pend_act_shared = NULL;
> >> @@ -1628,6 +1792,17 @@ static int vgic_vcpu_init_maps(struct kvm_vcpu *vcpu, int nr_irqs)
> >>  }
> >>
> >>  /**
> >> + * kvm_vgic_vcpu_early_init - Earliest possible per-vcpu vgic init stage
> > 
> > earliest possible... oh how I love the vgic code.
> > 
> 
> You must be the only one! ;-)
> 
> > If you have the energy and context to write a comment in the beginning
> > of this file describing the init flow, I think that would be useful...
> > 
> 
> How about starting with this?
> 
> <quote>
> There are multiple stages to the vgic initialization, both for the
> distributor and the CPU interfaces.
> 
> Distributor:
> 
> - kvm_vgic_early_init(): initialization of static data that doesn't
> depend on any sizing information or emulation type. No allocation is
> allowed there.
> 
> - vgic_init(): allocation and initialization of the generic data
> structures that depend on sizing information (number of CPUs, number of
> interrupts). Also initializes the vcpu specific data structures. Can be
> executed lazily for GICv2. [to be renamed to kvm_vgic_init??]
> 
> CPU Interface:
> 
> - kvm_vgic_cpu_early_init(): initialization of static data that doesn't
> depend on any sizing information or emulation type. No allocation is
> allowed there.
> </quote>
> 
> I'm sure we can expand it as we go...
> 

yes, this is great, it made me feel comfortable with the whole thing.
Thanks!

> >> + *
> >> + * No memory allocation should be performed here, only static init.
> >> + */
> >> +void kvm_vgic_vcpu_early_init(struct kvm_vcpu *vcpu)
> >> +{
> >> +     struct vgic_cpu *vgic_cpu = &vcpu->arch.vgic_cpu;
> >> +     INIT_LIST_HEAD(&vgic_cpu->irq_phys_map_list);
> >> +}
> >> +
> >> +/**
> >>   * kvm_vgic_get_max_vcpus - Get the maximum number of VCPUs allowed by HW
> >>   *
> >>   * The host's GIC naturally limits the maximum amount of VCPUs a guest
> >> @@ -1664,6 +1839,7 @@ void kvm_vgic_destroy(struct kvm *kvm)
> >>       kfree(dist->irq_spi_target);
> >>       kfree(dist->irq_pending_on_cpu);
> >>       kfree(dist->irq_active_on_cpu);
> >> +     vgic_destroy_irq_phys_map(kvm, &dist->irq_phys_map_list);
> >>       dist->irq_sgi_sources = NULL;
> >>       dist->irq_spi_cpu = NULL;
> >>       dist->irq_spi_target = NULL;
> >> @@ -1787,6 +1963,18 @@ static int init_vgic_model(struct kvm *kvm, int type)
> >>       return 0;
> >>  }
> >>
> >> +/**
> >> + * kvm_vgic_early_init - Earliest possible vgic initialization stage
> >> + *
> >> + * No memory allocation should be performed here, only static init.
> >> + */
> >> +void kvm_vgic_early_init(struct kvm *kvm)
> >> +{
> >> +     spin_lock_init(&kvm->arch.vgic.lock);
> > 
> > so here we're initializing the data structures even before the vgic is
> > created, right?  So therefore it's safe to move the vgic.lock init up
> > here?
> 
> Yes. The distributor structure is part of the struct kvm, hence safe to
> poke early on. This doesn't depend on any form of sizing or emulation
> type either.
> 

ok, slight warm fuzzy feeling.

Thanks,
-Christoffer


From christoffer.dall at linaro.org  Tue Aug  4 10:38:07 2015
From: christoffer.dall at linaro.org (Christoffer Dall)
Date: Tue, 4 Aug 2015 19:38:07 +0200
Subject: [PATCH v3 09/11] KVM: arm/arm64: vgic: Prevent userspace
 injection of a mapped interrupt
In-Reply-To: <55C0E221.6050009@arm.com>
References: <1437753309-17989-1-git-send-email-marc.zyngier@arm.com>
 <1437753309-17989-10-git-send-email-marc.zyngier@arm.com>
 <20150804134509.GB29335@cbox> <55C0E221.6050009@arm.com>
Message-ID: <20150804173807.GH29335@cbox>

On Tue, Aug 04, 2015 at 05:02:41PM +0100, Marc Zyngier wrote:
> On 04/08/15 14:45, Christoffer Dall wrote:
> > On Fri, Jul 24, 2015 at 04:55:07PM +0100, Marc Zyngier wrote:
> >> Virtual interrupts mapped to a HW interrupt should only be triggered
> >> from inside the kernel. Otherwise, you could end up confusing the
> >> kernel (and the GIC's) state machine.
> >>
> >> Rearrange the injection path so that kvm_vgic_inject_irq is
> >> used for non-mapped interrupts, and kvm_vgic_inject_mapped_irq is
> >> used for mapped interrupts. The latter should only be called from
> >> inside the kernel (timer, VFIO).
> >>
> >> Signed-off-by: Marc Zyngier <marc.zyngier at arm.com>
> >> ---
> >>  include/kvm/arm_vgic.h |  2 +
> >>  virt/kvm/arm/vgic.c    | 99 ++++++++++++++++++++++++++++++++++----------------
> >>  2 files changed, 70 insertions(+), 31 deletions(-)
> >>
> >> diff --git a/include/kvm/arm_vgic.h b/include/kvm/arm_vgic.h
> >> index 7306b4b..f6bfd79 100644
> >> --- a/include/kvm/arm_vgic.h
> >> +++ b/include/kvm/arm_vgic.h
> >> @@ -351,6 +351,8 @@ void kvm_vgic_flush_hwstate(struct kvm_vcpu *vcpu);
> >>  void kvm_vgic_sync_hwstate(struct kvm_vcpu *vcpu);
> >>  int kvm_vgic_inject_irq(struct kvm *kvm, int cpuid, unsigned int irq_num,
> >>  			bool level);
> >> +int kvm_vgic_inject_mapped_irq(struct kvm *kvm, int cpuid,
> >> +			       struct irq_phys_map *map, bool level);
> >>  void vgic_v3_dispatch_sgi(struct kvm_vcpu *vcpu, u64 reg);
> >>  int kvm_vgic_vcpu_pending_irq(struct kvm_vcpu *vcpu);
> >>  int kvm_vgic_vcpu_active_irq(struct kvm_vcpu *vcpu);
> >> diff --git a/virt/kvm/arm/vgic.c b/virt/kvm/arm/vgic.c
> >> index 3f7b690..e40ef70 100644
> >> --- a/virt/kvm/arm/vgic.c
> >> +++ b/virt/kvm/arm/vgic.c
> >> @@ -1533,7 +1533,8 @@ static int vgic_validate_injection(struct kvm_vcpu *vcpu, int irq, int level)
> >>  }
> >>  
> >>  static int vgic_update_irq_pending(struct kvm *kvm, int cpuid,
> >> -				  unsigned int irq_num, bool level)
> >> +				   struct irq_phys_map *map,
> >> +				   unsigned int irq_num, bool level)
> >>  {
> >>  	struct vgic_dist *dist = &kvm->arch.vgic;
> >>  	struct kvm_vcpu *vcpu;
> >> @@ -1541,6 +1542,9 @@ static int vgic_update_irq_pending(struct kvm *kvm, int cpuid,
> >>  	int enabled;
> >>  	bool ret = true, can_inject = true;
> >>  
> >> +	if (irq_num >= min(kvm->arch.vgic.nr_irqs, 1020))
> >> +		return -EINVAL;
> >> +
> >>  	spin_lock(&dist->lock);
> >>  
> >>  	vcpu = kvm_get_vcpu(kvm, cpuid);
> >> @@ -1603,14 +1607,42 @@ static int vgic_update_irq_pending(struct kvm *kvm, int cpuid,
> >>  out:
> >>  	spin_unlock(&dist->lock);
> >>  
> >> -	return ret ? cpuid : -EINVAL;
> >> +	if (!ret) {
> > 
> > don't you mean if (ret) here?  hint: ret is a bool
> 
> Ouch. Nice catch!
> 
> > 
> >> +		/* kick the specified vcpu */
> >> +		kvm_vcpu_kick(kvm_get_vcpu(kvm, cpuid));
> >> +	}
> >> +
> >> +	return 0;
> > 
> > isn't this a change in the internal API?
> > Before, we would return -EINVAL when ret is false.  Not sure if this
> > has any consequences though?
> 
> I don't think this is a change in API. Before this patch, we would
> either return a vcpuid or -EINVAL. But the error would not be propagated
> beyond kvm_vgic_inject_irq, effectively discarding the error code.
> 
> Also, it is a bit odd to return an error because the toggling of the
> line wasn't significant (like bringing the line down on an
> edge-triggered interrupt).
> 

true, indeed, my brain was too fried to think it through.

(why does coming back from vacation always involve paging in weird vgic
stuff for me?)

> > 
> >> +}
> >> +
> >> +static int vgic_lazy_init(struct kvm *kvm)
> >> +{
> >> +	int ret = 0;
> >> +
> >> +	if (unlikely(!vgic_initialized(kvm))) {
> >> +		/*
> >> +		 * We only provide the automatic initialization of the VGIC
> >> +		 * for the legacy case of a GICv2. Any other type must
> >> +		 * be explicitly initialized once setup with the respective
> >> +		 * KVM device call.
> >> +		 */
> >> +		if (kvm->arch.vgic.vgic_model != KVM_DEV_TYPE_ARM_VGIC_V2)
> >> +			return -EBUSY;
> >> +
> >> +		mutex_lock(&kvm->lock);
> >> +		ret = vgic_init(kvm);
> >> +		mutex_unlock(&kvm->lock);
> >> +	}
> >> +
> >> +	return ret;
> >>  }
> >>  
> >>  /**
> >>   * kvm_vgic_inject_irq - Inject an IRQ from a device to the vgic
> >>   * @kvm:     The VM structure pointer
> >>   * @cpuid:   The CPU for PPIs
> >> - * @irq_num: The IRQ number that is assigned to the device
> >> + * @irq_num: The IRQ number that is assigned to the device. This IRQ
> >> + *           must not be mapped to a HW interrupt.
> >>   * @level:   Edge-triggered:  true:  to trigger the interrupt
> >>   *			      false: to ignore the call
> >>   *	     Level-sensitive  true:  activates an interrupt
> >> @@ -1623,39 +1655,44 @@ out:
> >>  int kvm_vgic_inject_irq(struct kvm *kvm, int cpuid, unsigned int irq_num,
> >>  			bool level)
> >>  {
> >> -	int ret = 0;
> >> -	int vcpu_id;
> >> -
> >> -	if (unlikely(!vgic_initialized(kvm))) {
> >> -		/*
> >> -		 * We only provide the automatic initialization of the VGIC
> >> -		 * for the legacy case of a GICv2. Any other type must
> >> -		 * be explicitly initialized once setup with the respective
> >> -		 * KVM device call.
> >> -		 */
> >> -		if (kvm->arch.vgic.vgic_model != KVM_DEV_TYPE_ARM_VGIC_V2) {
> >> -			ret = -EBUSY;
> >> -			goto out;
> >> -		}
> >> -		mutex_lock(&kvm->lock);
> >> -		ret = vgic_init(kvm);
> >> -		mutex_unlock(&kvm->lock);
> >> +	struct irq_phys_map *map;
> >> +	int ret;
> >>  
> >> -		if (ret)
> >> -			goto out;
> >> -	}
> >> +	ret = vgic_lazy_init(kvm);
> >> +	if (ret)
> >> +		return ret;
> >>  
> >> -	if (irq_num >= min(kvm->arch.vgic.nr_irqs, 1020))
> >> +	map = vgic_irq_map_search(kvm_get_vcpu(kvm, cpuid), irq_num);
> >> +	if (map)
> >>  		return -EINVAL;
> >>  
> >> -	vcpu_id = vgic_update_irq_pending(kvm, cpuid, irq_num, level);
> >> -	if (vcpu_id >= 0) {
> >> -		/* kick the specified vcpu */
> >> -		kvm_vcpu_kick(kvm_get_vcpu(kvm, vcpu_id));
> >> -	}
> >> +	return vgic_update_irq_pending(kvm, cpuid, NULL, irq_num, level);
> >> +}
> >>  
> >> -out:
> >> -	return ret;
> >> +/**
> >> + * kvm_vgic_inject_mapped_irq - Inject a physically mapped IRQ to the vgic
> >> + * @kvm:     The VM structure pointer
> >> + * @cpuid:   The CPU for PPIs
> >> + * @map:     Pointer to a irq_phys_map structure describing the mapping
> >> + * @level:   Edge-triggered:  true:  to trigger the interrupt
> >> + *			      false: to ignore the call
> >> + *	     Level-sensitive  true:  activates an interrupt
> >> + *			      false: deactivates an interrupt
> > 
> > just noticed this unfortunate use of the words 'activate/deactivate'
> > here, which is not true, it just raises/lowers the input signal...
> > 
> 
> I'll clean that up.
> 

Thanks,
-Christoffer


From broonie at kernel.org  Tue Aug  4 10:38:49 2015
From: broonie at kernel.org (Mark Brown)
Date: Tue, 4 Aug 2015 18:38:49 +0100
Subject: next-20150729 build: 2 failures 49 warnings (next-20150729)
In-Reply-To: <20150729124410.GE20130@sirena.org.uk>
References: <E1ZKPJk-0007VU-Fg@optimist> <20150729124410.GE20130@sirena.org.uk>
Message-ID: <20150804173849.GD20873@sirena.org.uk>

On Wed, Jul 29, 2015 at 01:44:10PM +0100, Mark Brown wrote:
> On Wed, Jul 29, 2015 at 12:14:36PM +0100, Build bot for Mark Brown wrote:

> Today's linux-next fails to build an arm64 allmodconfig due to:

> > 	arm64-allmodconfig
> > ../include/linux/platform_device.h:245:1: error: type defaults to 'int' in declaration of 'module_init' [-Werror=implicit-int]
> > ../include/linux/platform_device.h:250:1: error: type defaults to 'int' in declaration of 'module_exit' [-Werror=implicit-int]

> caused by c84e358718a66f76 (soc: Mediatek: Add SCPSYS power domain
> driver) which does not include module.h.  Arguably platform_device.h
> should do that, though it's only an issue if the macro is used so...

This is still breaking the build and the fix should be trivial - is
there any ETA for a fix getting into -next?
-------------- next part --------------
A non-text attachment was scrubbed...
Name: signature.asc
Type: application/pgp-signature
Size: 473 bytes
Desc: Digital signature
URL: <http://lists.infradead.org/pipermail/linux-arm-kernel/attachments/20150804/f3aee19d/attachment.sig>

From christoffer.dall at linaro.org  Tue Aug  4 10:40:27 2015
From: christoffer.dall at linaro.org (Christoffer Dall)
Date: Tue, 4 Aug 2015 19:40:27 +0200
Subject: [PATCH v3 10/11] KVM: arm/arm64: timer: Allow the timer to
 control the active state
In-Reply-To: <55C0E4FD.6000100@arm.com>
References: <1437753309-17989-1-git-send-email-marc.zyngier@arm.com>
 <1437753309-17989-11-git-send-email-marc.zyngier@arm.com>
 <20150804135652.GC29335@cbox> <55C0E4FD.6000100@arm.com>
Message-ID: <20150804174027.GI29335@cbox>

On Tue, Aug 04, 2015 at 05:14:53PM +0100, Marc Zyngier wrote:
> On 04/08/15 14:56, Christoffer Dall wrote:
> > On Fri, Jul 24, 2015 at 04:55:08PM +0100, Marc Zyngier wrote:
> >> In order to remove the crude hack where we sneak the masked bit
> >> into the timer's control register, make use of the phys_irq_map
> >> API control the active state of the interrupt.
> >>
> >> This causes some limited changes to allow for potential error
> >> propagation.
> >>
> >> Signed-off-by: Marc Zyngier <marc.zyngier at arm.com>
> >> ---
> >>  arch/arm/kvm/reset.c         |  4 +---
> >>  arch/arm64/kvm/reset.c       |  4 +---
> >>  include/kvm/arm_arch_timer.h |  7 +++++--
> >>  virt/kvm/arm/arch_timer.c    | 29 ++++++++++++++++++++++-------
> >>  4 files changed, 29 insertions(+), 15 deletions(-)
> >>
> >> diff --git a/arch/arm/kvm/reset.c b/arch/arm/kvm/reset.c
> >> index f558c07..eeb85858 100644
> >> --- a/arch/arm/kvm/reset.c
> >> +++ b/arch/arm/kvm/reset.c
> >> @@ -77,7 +77,5 @@ int kvm_reset_vcpu(struct kvm_vcpu *vcpu)
> >>  	kvm_reset_coprocs(vcpu);
> >>  
> >>  	/* Reset arch_timer context */
> >> -	kvm_timer_vcpu_reset(vcpu, cpu_vtimer_irq);
> >> -
> >> -	return 0;
> >> +	return kvm_timer_vcpu_reset(vcpu, cpu_vtimer_irq);
> >>  }
> >> diff --git a/arch/arm64/kvm/reset.c b/arch/arm64/kvm/reset.c
> >> index b4af618..91cf535 100644
> >> --- a/arch/arm64/kvm/reset.c
> >> +++ b/arch/arm64/kvm/reset.c
> >> @@ -121,7 +121,5 @@ int kvm_reset_vcpu(struct kvm_vcpu *vcpu)
> >>  	kvm_reset_sys_regs(vcpu);
> >>  
> >>  	/* Reset timer */
> >> -	kvm_timer_vcpu_reset(vcpu, cpu_vtimer_irq);
> >> -
> >> -	return 0;
> >> +	return kvm_timer_vcpu_reset(vcpu, cpu_vtimer_irq);
> >>  }
> >> diff --git a/include/kvm/arm_arch_timer.h b/include/kvm/arm_arch_timer.h
> >> index e596675..e1e4d7c 100644
> >> --- a/include/kvm/arm_arch_timer.h
> >> +++ b/include/kvm/arm_arch_timer.h
> >> @@ -52,13 +52,16 @@ struct arch_timer_cpu {
> >>  
> >>  	/* Timer IRQ */
> >>  	const struct kvm_irq_level	*irq;
> >> +
> >> +	/* VGIC mapping */
> >> +	struct irq_phys_map		*map;
> >>  };
> >>  
> >>  int kvm_timer_hyp_init(void);
> >>  void kvm_timer_enable(struct kvm *kvm);
> >>  void kvm_timer_init(struct kvm *kvm);
> >> -void kvm_timer_vcpu_reset(struct kvm_vcpu *vcpu,
> >> -			  const struct kvm_irq_level *irq);
> >> +int kvm_timer_vcpu_reset(struct kvm_vcpu *vcpu,
> >> +			 const struct kvm_irq_level *irq);
> >>  void kvm_timer_vcpu_init(struct kvm_vcpu *vcpu);
> >>  void kvm_timer_flush_hwstate(struct kvm_vcpu *vcpu);
> >>  void kvm_timer_sync_hwstate(struct kvm_vcpu *vcpu);
> >> diff --git a/virt/kvm/arm/arch_timer.c b/virt/kvm/arm/arch_timer.c
> >> index 98c95f2..76e38d2 100644
> >> --- a/virt/kvm/arm/arch_timer.c
> >> +++ b/virt/kvm/arm/arch_timer.c
> >> @@ -64,10 +64,10 @@ static void kvm_timer_inject_irq(struct kvm_vcpu *vcpu)
> >>  	int ret;
> >>  	struct arch_timer_cpu *timer = &vcpu->arch.timer_cpu;
> >>  
> >> -	timer->cntv_ctl |= ARCH_TIMER_CTRL_IT_MASK;
> >> -	ret = kvm_vgic_inject_irq(vcpu->kvm, vcpu->vcpu_id,
> >> -				  timer->irq->irq,
> >> -				  timer->irq->level);
> >> +	kvm_vgic_set_phys_irq_active(timer->map, true);
> > 
> > actually, I'm not sure I understand the point of setting this boolean?
> > Is it just a check?  It seems everywhere we find the map in the VGIC
> > code, we have a BUG_ON(!map->active), so why doesn't (!!map) imply that
> > it should be marked as active?
> > 
> > Is this again for non-shared devices?
> > 
> 
> Setting the boolean here means that the interrupt should be marked
> active at the distributor level when the interrupt is injected. This
> also allows the timer code to find out when we can inject another
> interrupt (by checking that the interrupt is now inactive).
> 
> As for the BUG_ON(), this is really some debug stuff to make sure we
> have a consistent state.
> 
> Non-shared devices are handled separately (and setting the active state
> doesn't make much sense, as we expect this to be entirely HW driven).
> 
> Do you see anything I should add to make it more clear?
> 

no, I'm good with it now, I think adding more commentary etc. will just
confuse people even more... One simply has to understand this part of
the logic.

> >> +	ret = kvm_vgic_inject_mapped_irq(vcpu->kvm, vcpu->vcpu_id,
> >> +					 timer->map,
> >> +					 timer->irq->level);
> >>  	WARN_ON(ret);
> >>  }
> >>  
> >> @@ -117,7 +117,8 @@ bool kvm_timer_should_fire(struct kvm_vcpu *vcpu)
> >>  	cycle_t cval, now;
> >>  
> >>  	if ((timer->cntv_ctl & ARCH_TIMER_CTRL_IT_MASK) ||
> >> -		!(timer->cntv_ctl & ARCH_TIMER_CTRL_ENABLE))
> >> +	    !(timer->cntv_ctl & ARCH_TIMER_CTRL_ENABLE) ||
> >> +	    kvm_vgic_get_phys_irq_active(timer->map))
> > 
> > hmm, maybe this answers my question above.  It is the virtual active
> > state preventing us to keep injecting the virtual side?
> > 
> 
> Exactly. This is effectively what the MASK state was doing, now
> replicated in SW...
> 

ok, in that case:

Reviewed-by: Christoffer Dall <christoffer.dall at linaro.org>


From broonie at kernel.org  Tue Aug  4 10:42:26 2015
From: broonie at kernel.org (Mark Brown)
Date: Tue, 4 Aug 2015 18:42:26 +0100
Subject: [PATCH v4 1/3] dt-binding: spi: Mediatek: Document devicetree
 bindings for spi bus
In-Reply-To: <1438167874-1305-2-git-send-email-leilk.liu@mediatek.com>
References: <1438167874-1305-1-git-send-email-leilk.liu@mediatek.com>
 <1438167874-1305-2-git-send-email-leilk.liu@mediatek.com>
Message-ID: <20150804174226.GE20873@sirena.org.uk>

On Wed, Jul 29, 2015 at 07:04:32PM +0800, Leilk Liu wrote:
> Signed-off-by: Leilk Liu <leilk.liu at mediatek.com>

Please use subject lines reflecting the style for the subsystem so
people can spot if patches are relevant to them.

> +- clocks: phandles to input clocks.
> +
> +- clock-names: tuple listing input clock names.
> +	Required elements: "main"

...and there are no optional values?

> +- pad-select: should specify spi pad used, only required for MT8173.
> +        This value should be 0~3.

What do the values 0-3 mean?  I guess it's the value for some register
or other part of the device, the binding should say so people can go and
check the datasheet, schematic or whatever to figure out what to set.

This property should be optional, not required
-------------- next part --------------
A non-text attachment was scrubbed...
Name: signature.asc
Type: application/pgp-signature
Size: 473 bytes
Desc: Digital signature
URL: <http://lists.infradead.org/pipermail/linux-arm-kernel/attachments/20150804/2584c731/attachment.sig>

From robert.jarzmik at free.fr  Tue Aug  4 09:56:23 2015
From: robert.jarzmik at free.fr (Robert Jarzmik)
Date: Tue, 04 Aug 2015 18:56:23 +0200
Subject: [PATCH v2 0/4] mtd: pxa3xx_nand: rework the timing setup
In-Reply-To: <CAAEAJfBMpQ8nf5aLTUqrCsJkMQbnkQTB1yA5MBiJ6R4h6RgupQ@mail.gmail.com>
 (Ezequiel Garcia's message of "Mon, 3 Aug 2015 10:48:55 -0300")
References: <1436281707-20106-1-git-send-email-antoine.tenart@free-electrons.com>
 <20150717134159.GC10608@kwain> <55A912F0.7080605@vanguardiasur.com.ar>
 <87h9p2is8e.fsf@belgarion.home>
 <CAAEAJfCcdioVQKZs9U3DP6H94BiuQ2qU21DsMKevS5+j+-XEKA@mail.gmail.com>
 <87wpxufw2v.fsf@belgarion.home>
 <CAAEAJfB3caa+DmJN=Pa8brx0uGC11QA29KJb3NQdJjXTgw-yuA@mail.gmail.com>
 <87si81m15m.fsf@belgarion.home>
 <CAAEAJfBMpQ8nf5aLTUqrCsJkMQbnkQTB1yA5MBiJ6R4h6RgupQ@mail.gmail.com>
Message-ID: <87d1z3m1qg.fsf@belgarion.home>

Ezequiel Garcia <ezequiel at vanguardiasur.com.ar> writes:

>>
>> The issue I see is that :
>>  - there is a bug in the clk driver for pxa3xx I introduced (CKEN_AB)

>>  - and shutting down the GCU clock prevents the NAND from working (I can't
>>  explain that one yet)

Ah actually it's even trickier, but it has nothing to do with the GCU clock,
that was a wrong interpretation of the test sequence.

What actually happens is that on the platform I have, the NAND is sharing the
DFI bus with the Static Memory Controller. Now let's see what happens on
boot-up, knowing that my pxa3xx-nand is a module, not builtin :
 - the kernel boots
 - the core clock initializes
 - the ethernet card initializes (it is on the static memory controller)
 - the kernel finishes the boot sequence
   => the NAND clock is unused
   => as such, the core clock framework disables it

And here is the catch : on the next ethernet access, the system bus will be
stalled forever. The reason behind is that because the bootloader left the
"NDCR_ND_ARB_EN" bit enabled, the DFI bus sees the ethernet register access, and
asks for arbitration; as the NAND clock is down, the arbitration never happens,
and the pxa3xx is stalled forever.

The very same thing happens when you load and unload pxa3xx-nand with a platform
where it was loaded with "enable-arbiter" platform-data, and if that platform
has any driver mapped in the SMC address space (0x0 .. 0x14000000).

If you have an opportunity to load/unload a pxa3xx-nand, I'd be glad to have
someone verify this theory.

The first fix comming to my mind would be to :
 - disable the NDCR_ND_ARB_EN in the pxa3xx core bring up
 - keep enablement in pxa3xx-nand
 - ensure it is disabled on the probe error path or remove of pxa3xx-nand

Cheers.

--
Robert

PS: That also means that the fix I posted for CKENA/CKENB inversion should fix
the issues you see.


From horia.geanta at freescale.com  Tue Aug  4 10:55:50 2015
From: horia.geanta at freescale.com (=?UTF-8?Q?Horia_Geant=c4=83?=)
Date: Tue, 4 Aug 2015 20:55:50 +0300
Subject: [BUG?] crypto: caam: little/big endianness on ARM vs PPC
In-Reply-To: <20150615171848.GP7557@n2100.arm.linux.org.uk>
References: <20150615155907.GC7947@pengutronix.de>
 <CALHpu34FHKTHr-2TZ-6Tmctev3WjBVTKfDbr6TYOJiOt+yDvfQ@mail.gmail.com>
 <20150615171848.GP7557@n2100.arm.linux.org.uk>
Message-ID: <55C0FCA6.6070806@freescale.com>

On 6/15/2015 8:18 PM, Russell King - ARM Linux wrote:
> On Mon, Jun 15, 2015 at 06:33:17PM +0200, Jon Nettleton wrote:
>> Funny enough I tackled this problem over the weekend as well.  My
>> approach was to switch the driver over to use the *_relaxed() io
>> functions and then special case the bits missing from the various
>> ARCHs.  Basically adding setbits32 and clrbits32 for !PPC
>> architectures and letting PPC and ARM share a writeq/readq set of
>> functions.  I left the existing LITTLE_ENDIAN special case until I
>> could verify if it was needed, or had been tested.
> 
> I'll follow up here with what I've mentioned elsewhere, and some further
> thoughts.
> 
> I think this shows the dangers of using struct { } to define register
> offsets.  Let's start here:
> 
> /*
>  * caam_job_ring - direct job ring setup
>  * 1-4 possible per instantiation, base + 1000/2000/3000/4000
>  * Padded out to 0x1000
>  */
> struct caam_job_ring {
>         /* Input ring */
>         u64 inpring_base;       /* IRBAx -  Input desc ring baseaddr */
>         u32 rsvd1;
> 
> Apparently, this is a CPU-endian 64-bit value (it's not defined using
> le64 or be64 which would "fix" it's endian.)

The IP in question (CAAM) has different endianness, depending on the
integration on the SoC. Would it be ok to #define a sec64 type which
would translate either to be64 or le64?

> 
> The second question, which comes up in light of the breakage that's
> being reported is: is this really a 64-bit register, or is it a pair
> of 32-bit registers side-by-side?
> 
> The documentation I'm looking at doesn't document the register at
> base + 0x1000, but documents the one at base + 0x1004, and the one
> at 0x1004 is given the name "IRBAR0_LS", which presumably stands
> for "input ring base address register 0, least significant".
> 
> As the code originally stood for PPC, IRBAR0_LS is also at 0x1004,
> but appears to be big endian.
> 
> On ARM, IRBAR0_LS appears at the same address, but is little endian.

In some cases, CAAM endianness does not match CPU endianness (for e.g.
i.MX). We're talking about default endianness here, both for CAAM and
for CPU - no CONFIG_CPU_{BIG,LITTLE}_ENDIAN.
ARCH	CPU	CAAM	SoC
PPC	BIG	BIG	P4080, T4240 etc.
ARM	LITTLE	LITTLE	LS1021A, LS2085A etc.
ARM	LITTLE	BIG	i.MX6, i.MX7, LS1043A

> This is *not* a 64-bit register at all, but is a pair of 32-bit
> registers side by side.  Moreover, readq() should not be used - no
> amount of arch mangling could ever produce a sane readq() which
> coped with this.
> 
> So, the CAAM code is buggy in this regard: using readq() here when
> endian-portability is required is wrong.  It's got to be two 32-bit
> reads or two 32-bit writes in the appropriate endian.
> 
> Also, note that there's a big difference between __raw_readl() and
> readl_relaxed().  readl_relaxed() is always little-endian.  __raw_readl()
> is god-knows-what-the-archtecture-decides endian.  Switching PPC
> drivers from __raw_readl() to readl_relaxed() is really not a good
> idea unless someone from the PPC camp reviews and tests the code.
> 
> So, what I'd suggest is just fixing rd_reg64() and wr_reg64() to do
> the right thing: keeping the two 32-bit words in the same order
> irrespective of the endian-ness, and staying with the __raw_*
> accessors until PPC people can look at this.

Agree that the I/O accessors need to be revisited.
Unfortunately, the proposed change does not work for LE CAAM (LS1021A).
I'll send a fix.

Thanks,
Horia



From vigneshr at ti.com  Tue Aug  4 10:59:52 2015
From: vigneshr at ti.com (R, Vignesh)
Date: Tue, 4 Aug 2015 23:29:52 +0530
Subject: [RFC PATCH 1/5] spi: introduce flag for memory mapped read
In-Reply-To: <20150804155148.GR20873@sirena.org.uk>
References: <1438072876-16338-1-git-send-email-vigneshr@ti.com>
 <1438072876-16338-2-git-send-email-vigneshr@ti.com>
 <20150731181745.GM20873@sirena.org.uk> <55BEF4AF.5090704@ti.com>
 <20150804155148.GR20873@sirena.org.uk>
Message-ID: <55C0FD98.1090107@ti.com>



On 8/4/2015 9:21 PM, Mark Brown wrote:
> On Mon, Aug 03, 2015 at 10:27:19AM +0530, Vignesh R wrote:
> 
>> @use_mmap_mode: Some SPI controller chips are optimized for interacting
>> with serial flash memories. These chips have memory mapped interface,
>> through which entire serial flash memory slave can be read/written as if
>> though they are physical memories (like RAM). Using this interface,
>> flash can be accessed using memcpy() function and the spi controller
>> hardware will take care of communicating with serial flash over SPI.
>> Setting this flag will indicate the SPI controller driver that the
>> spi_message is from mtd layer to read from/write to flash. The SPI
>> master driver can then appropriately switch the controller to memory
>> mapped interface to read from/write to flash, based on this flag (See
>> drivers/spi/spi-ti-qspi.c for example).
>> NOTE: If the SPI controller chip lacks memory mapped interface, then the
>> driver will ignore this flag and use normal SPI protocol to read
>> from/write to flash. Communication with non-flash SPI devices is not
>> possible using the memory mapped interface.
> 
> I still can't tell from the above what this interface is supposed to do.
> It sounds like the use of memory mapped mode is supposed to be
> transparent to users, it should just affect how the controller interacts
> with the hardware, but if that's the case why do we need to expose it to
> users at all?  Shouldn't the driver just use memory mapped mode if it's
> faster?
> 

TI QSPI controller has two blocks:
1. SPI_CORE: This is generic(normal) spi mode. This can be used to
communicate with any SPI devices (serial flashes as well as non-flash
devices like touchscreen).
2. SFI_MM_IF(SPI memory mapped interface): The SFI_MM_IF block only
allows reading and writing to an SPI flash device only. Used to speed up
flash reads. It _cannot_ be used to communicate with non flash devices.
Now, the spi_message that ti-qspi receives in transfer_one() callback
can be from mtd device(in which case SFI_MM_IF can be used) or from any
other non flash SPI device (in which case SFI_MM_IF must not be used
instead SPI_CORE is to be used) but there is no way(is there?) to
distinguish where spi_message is from. Therefore I introduced flag
(use_mmap_mode) to struct spi_message. mtd driver will set flag to true,
this helps the ti-qspi driver to determine that the user is flash device
and thus can do read via SFI_MM_IF. If this flag is not set then the
user is assumed to be non flash SPI driver and will use SPI_CORE block
to communicate.

On the whole, I just need a way to determine that the user is a flash
device in order to switch to memory mapped interface.

Regards
Vignesh


From geert+renesas at glider.be  Tue Aug  4 11:03:08 2015
From: geert+renesas at glider.be (Geert Uytterhoeven)
Date: Tue,  4 Aug 2015 20:03:08 +0200
Subject: [PATCH 3/7] ARM: shmobile: Remove obsolete custom earlyprintk code
In-Reply-To: <1438711392-23763-1-git-send-email-geert+renesas@glider.be>
References: <1438711392-23763-1-git-send-email-geert+renesas@glider.be>
Message-ID: <1438711392-23763-4-git-send-email-geert+renesas@glider.be>

The last caller of shmobile_setup_console() was removed in commit
44d88c754e57a6d9 ("ARM: shmobile: Remove legacy SoC code for R-Mobile
A1").

Signed-off-by: Geert Uytterhoeven <geert+renesas at glider.be>
---
 arch/arm/mach-shmobile/Makefile  |  2 +-
 arch/arm/mach-shmobile/common.h  |  1 -
 arch/arm/mach-shmobile/console.c | 27 ---------------------------
 3 files changed, 1 insertion(+), 29 deletions(-)
 delete mode 100644 arch/arm/mach-shmobile/console.c

diff --git a/arch/arm/mach-shmobile/Makefile b/arch/arm/mach-shmobile/Makefile
index 476de30798d7290b..b02841528e05bbdb 100644
--- a/arch/arm/mach-shmobile/Makefile
+++ b/arch/arm/mach-shmobile/Makefile
@@ -3,7 +3,7 @@
 #
 
 # Common objects
-obj-y				:= timer.o console.o
+obj-y				:= timer.o
 
 # CPU objects
 obj-$(CONFIG_ARCH_SH73A0)	+= setup-sh73a0.o
diff --git a/arch/arm/mach-shmobile/common.h b/arch/arm/mach-shmobile/common.h
index 8d27ec546a35f4b9..ee8fe9e473d72895 100644
--- a/arch/arm/mach-shmobile/common.h
+++ b/arch/arm/mach-shmobile/common.h
@@ -4,7 +4,6 @@
 extern void shmobile_earlytimer_init(void);
 extern void shmobile_init_delay(void);
 struct twd_local_timer;
-extern void shmobile_setup_console(void);
 extern void shmobile_boot_vector(void);
 extern unsigned long shmobile_boot_fn;
 extern unsigned long shmobile_boot_arg;
diff --git a/arch/arm/mach-shmobile/console.c b/arch/arm/mach-shmobile/console.c
deleted file mode 100644
index e329ccbd0a6734f1..0000000000000000
--- a/arch/arm/mach-shmobile/console.c
+++ /dev/null
@@ -1,27 +0,0 @@
-/*
- * SH-Mobile Console
- *
- * Copyright (C) 2010  Magnus Damm
- *
- * 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; version 2 of the License.
- *
- * 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/kernel.h>
-#include <linux/init.h>
-#include <linux/platform_device.h>
-#include <asm/mach/map.h>
-#include "common.h"
-
-void __init shmobile_setup_console(void)
-{
-	parse_early_param();
-
-	/* Let earlyprintk output early console messages */
-	early_platform_driver_probe("earlyprintk", 1, 1);
-}
-- 
1.9.1



From geert+renesas at glider.be  Tue Aug  4 11:03:11 2015
From: geert+renesas at glider.be (Geert Uytterhoeven)
Date: Tue,  4 Aug 2015 20:03:11 +0200
Subject: [PATCH 6/7] ARM: shmobile: Remove obsolete earlytimer registration
In-Reply-To: <1438711392-23763-1-git-send-email-geert+renesas@glider.be>
References: <1438711392-23763-1-git-send-email-geert+renesas@glider.be>
Message-ID: <1438711392-23763-7-git-send-email-geert+renesas@glider.be>

The last caller of shmobile_earlytimer_init() was removed in commit
c99cd90d98a98aa1 ("ARM: shmobile: r8a7779: Remove legacy SoC code").

Signed-off-by: Geert Uytterhoeven <geert+renesas at glider.be>
---
 arch/arm/mach-shmobile/common.h |  1 -
 arch/arm/mach-shmobile/timer.c  | 21 ---------------------
 2 files changed, 22 deletions(-)

diff --git a/arch/arm/mach-shmobile/common.h b/arch/arm/mach-shmobile/common.h
index ee8fe9e473d72895..2a350b48b893a1b6 100644
--- a/arch/arm/mach-shmobile/common.h
+++ b/arch/arm/mach-shmobile/common.h
@@ -1,7 +1,6 @@
 #ifndef __ARCH_MACH_COMMON_H
 #define __ARCH_MACH_COMMON_H
 
-extern void shmobile_earlytimer_init(void);
 extern void shmobile_init_delay(void);
 struct twd_local_timer;
 extern void shmobile_boot_vector(void);
diff --git a/arch/arm/mach-shmobile/timer.c b/arch/arm/mach-shmobile/timer.c
index f1d027aa7a81ac33..c17d4d3881ffc45e 100644
--- a/arch/arm/mach-shmobile/timer.c
+++ b/arch/arm/mach-shmobile/timer.c
@@ -77,24 +77,3 @@ void __init shmobile_init_delay(void)
 			shmobile_setup_delay_hz(max_freq, 2, 4);
 	}
 }
-
-static void __init shmobile_late_time_init(void)
-{
-	/*
-	 * Make sure all compiled-in early timers register themselves.
-	 *
-	 * Run probe() for two "earlytimer" devices, these will be the
-	 * clockevents and clocksource devices respectively. In the event
-	 * that only a clockevents device is available, we -ENODEV on the
-	 * clocksource and the jiffies clocksource is used transparently
-	 * instead. No error handling is necessary here.
-	 */
-	early_platform_driver_register_all("earlytimer");
-	early_platform_driver_probe("earlytimer", 2, 0);
-}
-
-void __init shmobile_earlytimer_init(void)
-{
-	late_time_init = shmobile_late_time_init;
-}
-
-- 
1.9.1



From geert+renesas at glider.be  Tue Aug  4 11:03:05 2015
From: geert+renesas at glider.be (Geert Uytterhoeven)
Date: Tue,  4 Aug 2015 20:03:05 +0200
Subject: [PATCH 0/7] ARM: shmobile: Misc removals
Message-ID: <1438711392-23763-1-git-send-email-geert+renesas@glider.be>

	Hi Simon, Magnus,

This patch series (against renesas-devel-20150804-v4.2-rc5) removes
various header files, source files, declarations and definitions that
are no longer in use.

Dependencies:
  - Patch 1 depends on v3.12,
  - Patches 2-5 depend on the sh73a0/kzm9g and r8a7740/armadillo legacy
    removal, which is in arm-soc/for-next,
  - Patches 6-7 depend on the r8a7779/marzen legacy removal, which is in
    marzen-board-removal-for-v4.3.

Note that I didn't remove the now unused r8a7779_init_pm_domains() et al
yet, as I need to have a closer look on what to retain for R-Car DT SYSC
PM Domains first.

Thanks!

Geert Uytterhoeven (7):
  ARM: shmobile: Remove unused declaration of
    r8a7778_add_standard_devices_dt()
  ARM: shmobile: Remove obsolete sh-gpio.h
  ARM: shmobile: Remove obsolete custom earlyprintk code
  ARM: shmobile: Remove obsolete intc.h
  ARM: shmobile: Remove obsolete legacy PM Domain leftovers
  ARM: shmobile: Remove obsolete earlytimer registration
  ARM: shmobile: Remove obsolete twd_local_timer declaration

 arch/arm/mach-shmobile/Makefile     |   2 +-
 arch/arm/mach-shmobile/common.h     |   3 -
 arch/arm/mach-shmobile/console.c    |  27 ----
 arch/arm/mach-shmobile/intc.h       | 295 ------------------------------------
 arch/arm/mach-shmobile/pm-rmobile.h |   9 --
 arch/arm/mach-shmobile/r8a7778.h    |   1 -
 arch/arm/mach-shmobile/sh-gpio.h    |  29 ----
 arch/arm/mach-shmobile/timer.c      |  21 ---
 8 files changed, 1 insertion(+), 386 deletions(-)
 delete mode 100644 arch/arm/mach-shmobile/console.c
 delete mode 100644 arch/arm/mach-shmobile/intc.h
 delete mode 100644 arch/arm/mach-shmobile/sh-gpio.h

-- 
1.9.1

Gr{oetje,eeting}s,

						Geert

--
Geert Uytterhoeven -- There's lots of Linux beyond ia32 -- geert at linux-m68k.org

In personal conversations with technical people, I call myself a hacker. But
when I'm talking to journalists I just say "programmer" or something like that.
							    -- Linus Torvalds


From geert+renesas at glider.be  Tue Aug  4 11:03:06 2015
From: geert+renesas at glider.be (Geert Uytterhoeven)
Date: Tue,  4 Aug 2015 20:03:06 +0200
Subject: [PATCH 1/7] ARM: shmobile: Remove unused declaration of
 r8a7778_add_standard_devices_dt()
In-Reply-To: <1438711392-23763-1-git-send-email-geert+renesas@glider.be>
References: <1438711392-23763-1-git-send-email-geert+renesas@glider.be>
Message-ID: <1438711392-23763-2-git-send-email-geert+renesas@glider.be>

The actual implementation was removed by commit 40216263d3d0b9b4 ("ARM:
shmobile: Remove unused r8a7778 auxdata and callback") in v3.12.

Signed-off-by: Geert Uytterhoeven <geert+renesas at glider.be>
---
 arch/arm/mach-shmobile/r8a7778.h | 1 -
 1 file changed, 1 deletion(-)

diff --git a/arch/arm/mach-shmobile/r8a7778.h b/arch/arm/mach-shmobile/r8a7778.h
index f64fedb1f2ccb50d..0e77f3f81123a0d3 100644
--- a/arch/arm/mach-shmobile/r8a7778.h
+++ b/arch/arm/mach-shmobile/r8a7778.h
@@ -63,7 +63,6 @@ enum {
 };
 
 extern void r8a7778_add_standard_devices(void);
-extern void r8a7778_add_standard_devices_dt(void);
 extern void r8a7778_add_dt_devices(void);
 
 extern void r8a7778_init_late(void);
-- 
1.9.1



From geert+renesas at glider.be  Tue Aug  4 11:03:10 2015
From: geert+renesas at glider.be (Geert Uytterhoeven)
Date: Tue,  4 Aug 2015 20:03:10 +0200
Subject: [PATCH 5/7] ARM: shmobile: Remove obsolete legacy PM Domain leftovers
In-Reply-To: <1438711392-23763-1-git-send-email-geert+renesas@glider.be>
References: <1438711392-23763-1-git-send-email-geert+renesas@glider.be>
Message-ID: <1438711392-23763-6-git-send-email-geert+renesas@glider.be>

The last users were removed in commit b587288001f05c0e ("ARM: shmobile:
R-Mobile: Remove legacy PM Domain code").

Signed-off-by: Geert Uytterhoeven <geert+renesas at glider.be>
---
 arch/arm/mach-shmobile/pm-rmobile.h | 9 ---------
 1 file changed, 9 deletions(-)

diff --git a/arch/arm/mach-shmobile/pm-rmobile.h b/arch/arm/mach-shmobile/pm-rmobile.h
index 30a4a421ee315b98..8146bb6d7237eafc 100644
--- a/arch/arm/mach-shmobile/pm-rmobile.h
+++ b/arch/arm/mach-shmobile/pm-rmobile.h
@@ -12,10 +12,6 @@
 
 #include <linux/pm_domain.h>
 
-#define DEFAULT_DEV_LATENCY_NS	250000
-
-struct platform_device;
-
 struct rmobile_pm_domain {
 	struct generic_pm_domain genpd;
 	struct dev_power_governor *gov;
@@ -26,9 +22,4 @@ struct rmobile_pm_domain {
 	bool no_debug;
 };
 
-struct pm_domain_device {
-	const char *domain_name;
-	struct platform_device *pdev;
-};
-
 #endif /* PM_RMOBILE_H */
-- 
1.9.1



From geert+renesas at glider.be  Tue Aug  4 11:03:07 2015
From: geert+renesas at glider.be (Geert Uytterhoeven)
Date: Tue,  4 Aug 2015 20:03:07 +0200
Subject: [PATCH 2/7] ARM: shmobile: Remove obsolete sh-gpio.h
In-Reply-To: <1438711392-23763-1-git-send-email-geert+renesas@glider.be>
References: <1438711392-23763-1-git-send-email-geert+renesas@glider.be>
Message-ID: <1438711392-23763-3-git-send-email-geert+renesas@glider.be>

The last user of "sh-gpio.h" was removed in commit 1fa59bda21c7fa36
("ARM: shmobile: Remove legacy board code for Armadillo-800 EVA").

Signed-off-by: Geert Uytterhoeven <geert+renesas at glider.be>
---
 arch/arm/mach-shmobile/sh-gpio.h | 29 -----------------------------
 1 file changed, 29 deletions(-)
 delete mode 100644 arch/arm/mach-shmobile/sh-gpio.h

diff --git a/arch/arm/mach-shmobile/sh-gpio.h b/arch/arm/mach-shmobile/sh-gpio.h
deleted file mode 100644
index 2c4141413db92ebb..0000000000000000
--- a/arch/arm/mach-shmobile/sh-gpio.h
+++ /dev/null
@@ -1,29 +0,0 @@
-/*
- * Generic GPIO API and pinmux table support
- *
- * Copyright (c) 2008  Magnus Damm
- *
- * This file is subject to the terms and conditions of the GNU General Public
- * License.  See the file "COPYING" in the main directory of this archive
- * for more details.
- */
-#ifndef __ASM_ARCH_GPIO_H
-#define __ASM_ARCH_GPIO_H
-
-#include <linux/kernel.h>
-#include <linux/errno.h>
-#include <linux/io.h>
-
-/*
- * FIXME !!
- *
- * current gpio frame work doesn't have
- * the method to control only pull up/down/free.
- * this function should be replaced by correct gpio function
- */
-static inline void __init gpio_direction_none(void __iomem * addr)
-{
-	__raw_writeb(0x00, addr);
-}
-
-#endif /* __ASM_ARCH_GPIO_H */
-- 
1.9.1



From geert+renesas at glider.be  Tue Aug  4 11:03:12 2015
From: geert+renesas at glider.be (Geert Uytterhoeven)
Date: Tue,  4 Aug 2015 20:03:12 +0200
Subject: [PATCH 7/7] ARM: shmobile: Remove obsolete twd_local_timer declaration
In-Reply-To: <1438711392-23763-1-git-send-email-geert+renesas@glider.be>
References: <1438711392-23763-1-git-send-email-geert+renesas@glider.be>
Message-ID: <1438711392-23763-8-git-send-email-geert+renesas@glider.be>

The last user of twd_local_timer was removed in commit c99cd90d98a98aa1
("ARM: shmobile: r8a7779: Remove legacy SoC code").

Signed-off-by: Geert Uytterhoeven <geert+renesas at glider.be>
---
 arch/arm/mach-shmobile/common.h | 1 -
 1 file changed, 1 deletion(-)

diff --git a/arch/arm/mach-shmobile/common.h b/arch/arm/mach-shmobile/common.h
index 2a350b48b893a1b6..0833a6ed02e4a127 100644
--- a/arch/arm/mach-shmobile/common.h
+++ b/arch/arm/mach-shmobile/common.h
@@ -2,7 +2,6 @@
 #define __ARCH_MACH_COMMON_H
 
 extern void shmobile_init_delay(void);
-struct twd_local_timer;
 extern void shmobile_boot_vector(void);
 extern unsigned long shmobile_boot_fn;
 extern unsigned long shmobile_boot_arg;
-- 
1.9.1



From geert+renesas at glider.be  Tue Aug  4 11:03:09 2015
From: geert+renesas at glider.be (Geert Uytterhoeven)
Date: Tue,  4 Aug 2015 20:03:09 +0200
Subject: [PATCH 4/7] ARM: shmobile: Remove obsolete intc.h
In-Reply-To: <1438711392-23763-1-git-send-email-geert+renesas@glider.be>
References: <1438711392-23763-1-git-send-email-geert+renesas@glider.be>
Message-ID: <1438711392-23763-5-git-send-email-geert+renesas@glider.be>

The last user of "intc.h" was removed in commit 9a9863987bf7307f ("ARM:
shmobile: Remove legacy SoC code for SH-Mobile AG5").

Signed-off-by: Geert Uytterhoeven <geert+renesas at glider.be>
---
 arch/arm/mach-shmobile/intc.h | 295 ------------------------------------------
 1 file changed, 295 deletions(-)
 delete mode 100644 arch/arm/mach-shmobile/intc.h

diff --git a/arch/arm/mach-shmobile/intc.h b/arch/arm/mach-shmobile/intc.h
deleted file mode 100644
index 40b2ad4ca5b4f1bb..0000000000000000
--- a/arch/arm/mach-shmobile/intc.h
+++ /dev/null
@@ -1,295 +0,0 @@
-#ifndef __ASM_MACH_INTC_H
-#define __ASM_MACH_INTC_H
-#include <linux/sh_intc.h>
-
-#define INTC_IRQ_PINS_ENUM_16L(p)				\
-	p ## _IRQ0, p ## _IRQ1, p ## _IRQ2, p ## _IRQ3,		\
-	p ## _IRQ4, p ## _IRQ5, p ## _IRQ6, p ## _IRQ7,		\
-	p ## _IRQ8, p ## _IRQ9, p ## _IRQ10, p ## _IRQ11,	\
-	p ## _IRQ12, p ## _IRQ13, p ## _IRQ14, p ## _IRQ15
-
-#define INTC_IRQ_PINS_ENUM_16H(p)				\
-	p ## _IRQ16, p ## _IRQ17, p ## _IRQ18, p ## _IRQ19,	\
-	p ## _IRQ20, p ## _IRQ21, p ## _IRQ22, p ## _IRQ23,	\
-	p ## _IRQ24, p ## _IRQ25, p ## _IRQ26, p ## _IRQ27,	\
-	p ## _IRQ28, p ## _IRQ29, p ## _IRQ30, p ## _IRQ31
-
-#define INTC_IRQ_PINS_VECT_16L(p, vect)				\
-	vect(p ## _IRQ0, 0x0200), vect(p ## _IRQ1, 0x0220),	\
-	vect(p ## _IRQ2, 0x0240), vect(p ## _IRQ3, 0x0260),	\
-	vect(p ## _IRQ4, 0x0280), vect(p ## _IRQ5, 0x02a0),	\
-	vect(p ## _IRQ6, 0x02c0), vect(p ## _IRQ7, 0x02e0),	\
-	vect(p ## _IRQ8, 0x0300), vect(p ## _IRQ9, 0x0320),	\
-	vect(p ## _IRQ10, 0x0340), vect(p ## _IRQ11, 0x0360),	\
-	vect(p ## _IRQ12, 0x0380), vect(p ## _IRQ13, 0x03a0),	\
-	vect(p ## _IRQ14, 0x03c0), vect(p ## _IRQ15, 0x03e0)
-
-#define INTC_IRQ_PINS_VECT_16H(p, vect)				\
-	vect(p ## _IRQ16, 0x3200), vect(p ## _IRQ17, 0x3220),	\
-	vect(p ## _IRQ18, 0x3240), vect(p ## _IRQ19, 0x3260),	\
-	vect(p ## _IRQ20, 0x3280), vect(p ## _IRQ21, 0x32a0),	\
-	vect(p ## _IRQ22, 0x32c0), vect(p ## _IRQ23, 0x32e0),	\
-	vect(p ## _IRQ24, 0x3300), vect(p ## _IRQ25, 0x3320),	\
-	vect(p ## _IRQ26, 0x3340), vect(p ## _IRQ27, 0x3360),	\
-	vect(p ## _IRQ28, 0x3380), vect(p ## _IRQ29, 0x33a0),	\
-	vect(p ## _IRQ30, 0x33c0), vect(p ## _IRQ31, 0x33e0)
-
-#define INTC_IRQ_PINS_MASK_16L(p, base)					\
-	{ base + 0x40, base + 0x60, 8, /* INTMSK00A / INTMSKCLR00A */	\
-	  { p ## _IRQ0, p ## _IRQ1, p ## _IRQ2, p ## _IRQ3,		\
-	    p ## _IRQ4, p ## _IRQ5, p ## _IRQ6, p ## _IRQ7 } },		\
-	{ base + 0x44, base + 0x64, 8, /* INTMSK10A / INTMSKCLR10A */	\
-	  { p ## _IRQ8, p ## _IRQ9, p ## _IRQ10, p ## _IRQ11,		\
-	    p ## _IRQ12, p ## _IRQ13, p ## _IRQ14, p ## _IRQ15 } }
-
-#define INTC_IRQ_PINS_MASK_16H(p, base)					\
-	{ base + 0x48, base + 0x68, 8, /* INTMSK20A / INTMSKCLR20A */	\
-	  { p ## _IRQ16, p ## _IRQ17, p ## _IRQ18, p ## _IRQ19,		\
-	    p ## _IRQ20, p ## _IRQ21, p ## _IRQ22, p ## _IRQ23 } },	\
-	{ base + 0x4c, base + 0x6c, 8, /* INTMSK30A / INTMSKCLR30A */	\
-	  { p ## _IRQ24, p ## _IRQ25, p ## _IRQ26, p ## _IRQ27,		\
-	    p ## _IRQ28, p ## _IRQ29, p ## _IRQ30, p ## _IRQ31 } }
-
-#define INTC_IRQ_PINS_PRIO_16L(p, base)					\
-	{ base + 0x10, 0, 32, 4, /* INTPRI00A */			\
-	  { p ## _IRQ0, p ## _IRQ1, p ## _IRQ2, p ## _IRQ3,		\
-	    p ## _IRQ4, p ## _IRQ5, p ## _IRQ6, p ## _IRQ7 } },		\
-	{ base + 0x14, 0, 32, 4, /* INTPRI10A */			\
-	  { p ## _IRQ8, p ## _IRQ9, p ## _IRQ10, p ## _IRQ11,		\
-	    p ## _IRQ12, p ## _IRQ13, p ## _IRQ14, p ## _IRQ15 } }
-
-#define INTC_IRQ_PINS_PRIO_16H(p, base)					\
-	{ base + 0x18, 0, 32, 4, /* INTPRI20A */			\
-	  { p ## _IRQ16, p ## _IRQ17, p ## _IRQ18, p ## _IRQ19,		\
-	    p ## _IRQ20, p ## _IRQ21, p ## _IRQ22, p ## _IRQ23 } },	\
-	{ base + 0x1c, 0, 32, 4, /* INTPRI30A */			\
-	  { p ## _IRQ24, p ## _IRQ25, p ## _IRQ26, p ## _IRQ27,		\
-	    p ## _IRQ28, p ## _IRQ29, p ## _IRQ30, p ## _IRQ31 } }
-
-#define INTC_IRQ_PINS_SENSE_16L(p, base)				\
-	{ base + 0x00, 32, 4, /* ICR1A */				\
-	  { p ## _IRQ0, p ## _IRQ1, p ## _IRQ2, p ## _IRQ3,		\
-	    p ## _IRQ4, p ## _IRQ5, p ## _IRQ6, p ## _IRQ7 } },		\
-	{ base + 0x04, 32, 4, /* ICR2A */				\
-	  { p ## _IRQ8, p ## _IRQ9, p ## _IRQ10, p ## _IRQ11,		\
-	    p ## _IRQ12, p ## _IRQ13, p ## _IRQ14, p ## _IRQ15 } }
-
-#define INTC_IRQ_PINS_SENSE_16H(p, base)				\
-	{ base + 0x08, 32, 4, /* ICR3A */				\
-	  { p ## _IRQ16, p ## _IRQ17, p ## _IRQ18, p ## _IRQ19,		\
-	    p ## _IRQ20, p ## _IRQ21, p ## _IRQ22, p ## _IRQ23 } },	\
-	{ base + 0x0c, 32, 4, /* ICR4A */				\
-	  { p ## _IRQ24, p ## _IRQ25, p ## _IRQ26, p ## _IRQ27,		\
-	    p ## _IRQ28, p ## _IRQ29, p ## _IRQ30, p ## _IRQ31 } }
-
-#define INTC_IRQ_PINS_ACK_16L(p, base)					\
-	{ base + 0x20, 0, 8, /* INTREQ00A */				\
-	  { p ## _IRQ0, p ## _IRQ1, p ## _IRQ2, p ## _IRQ3,		\
-	    p ## _IRQ4, p ## _IRQ5, p ## _IRQ6, p ## _IRQ7 } },		\
-	{ base + 0x24, 0, 8, /* INTREQ10A */				\
-	  { p ## _IRQ8, p ## _IRQ9, p ## _IRQ10, p ## _IRQ11,		\
-	    p ## _IRQ12, p ## _IRQ13, p ## _IRQ14, p ## _IRQ15 } }
-
-#define INTC_IRQ_PINS_ACK_16H(p, base)					\
-	{ base + 0x28, 0, 8, /* INTREQ20A */				\
-	  { p ## _IRQ16, p ## _IRQ17, p ## _IRQ18, p ## _IRQ19,		\
-	    p ## _IRQ20, p ## _IRQ21, p ## _IRQ22, p ## _IRQ23 } },	\
-	{ base + 0x2c, 0, 8, /* INTREQ30A */				\
-	  { p ## _IRQ24, p ## _IRQ25, p ## _IRQ26, p ## _IRQ27,		\
-	    p ## _IRQ28, p ## _IRQ29, p ## _IRQ30, p ## _IRQ31 } }
-
-#define INTC_IRQ_PINS_16(p, base, vect, str)				\
-									\
-static struct resource p ## _resources[] __initdata = {			\
-	[0] = {								\
-		.start	= base,						\
-		.end	= base + 0x64,					\
-		.flags	= IORESOURCE_MEM,				\
-	},								\
-};									\
-									\
-enum {									\
-	p ## _UNUSED = 0,						\
-	INTC_IRQ_PINS_ENUM_16L(p),					\
-};									\
-									\
-static struct intc_vect p ## _vectors[] __initdata = {			\
-	INTC_IRQ_PINS_VECT_16L(p, vect),				\
-};									\
-									\
-static struct intc_mask_reg p ## _mask_registers[] __initdata = {	\
-	INTC_IRQ_PINS_MASK_16L(p, base),				\
-};									\
-									\
-static struct intc_prio_reg p ## _prio_registers[] __initdata = {	\
-	INTC_IRQ_PINS_PRIO_16L(p, base),				\
-};									\
-									\
-static struct intc_sense_reg p ## _sense_registers[] __initdata = {	\
-	INTC_IRQ_PINS_SENSE_16L(p, base),				\
-};									\
-									\
-static struct intc_mask_reg p ## _ack_registers[] __initdata = {	\
-	INTC_IRQ_PINS_ACK_16L(p, base),					\
-};									\
-									\
-static struct intc_desc p ## _desc __initdata = {			\
-	.name = str,							\
-	.resource = p ## _resources,					\
-	.num_resources = ARRAY_SIZE(p ## _resources),			\
-	.hw = INTC_HW_DESC(p ## _vectors, NULL,				\
-			     p ## _mask_registers, p ## _prio_registers, \
-			     p ## _sense_registers, p ## _ack_registers) \
-}
-
-#define INTC_IRQ_PINS_16H(p, base, vect, str)				\
-									\
-static struct resource p ## _resources[] __initdata = {			\
-	[0] = {								\
-		.start	= base,						\
-		.end	= base + 0x64,					\
-		.flags	= IORESOURCE_MEM,				\
-	},								\
-};									\
-									\
-enum {									\
-	p ## _UNUSED = 0,						\
-	INTC_IRQ_PINS_ENUM_16H(p),					\
-};									\
-									\
-static struct intc_vect p ## _vectors[] __initdata = {			\
-	INTC_IRQ_PINS_VECT_16H(p, vect),				\
-};									\
-									\
-static struct intc_mask_reg p ## _mask_registers[] __initdata = {	\
-	INTC_IRQ_PINS_MASK_16H(p, base),				\
-};									\
-									\
-static struct intc_prio_reg p ## _prio_registers[] __initdata = {	\
-	INTC_IRQ_PINS_PRIO_16H(p, base),				\
-};									\
-									\
-static struct intc_sense_reg p ## _sense_registers[] __initdata = {	\
-	INTC_IRQ_PINS_SENSE_16H(p, base),				\
-};									\
-									\
-static struct intc_mask_reg p ## _ack_registers[] __initdata = {	\
-	INTC_IRQ_PINS_ACK_16H(p, base),					\
-};									\
-									\
-static struct intc_desc p ## _desc __initdata = {			\
-	.name = str,							\
-	.resource = p ## _resources,					\
-	.num_resources = ARRAY_SIZE(p ## _resources),			\
-	.hw = INTC_HW_DESC(p ## _vectors, NULL,				\
-			     p ## _mask_registers, p ## _prio_registers, \
-			     p ## _sense_registers, p ## _ack_registers) \
-}
-
-#define INTC_IRQ_PINS_32(p, base, vect, str)				\
-									\
-static struct resource p ## _resources[] __initdata = {			\
-	[0] = {								\
-		.start	= base,						\
-		.end	= base + 0x6c,					\
-		.flags	= IORESOURCE_MEM,				\
-	},								\
-};									\
-									\
-enum {									\
-	p ## _UNUSED = 0,						\
-	INTC_IRQ_PINS_ENUM_16L(p),					\
-	INTC_IRQ_PINS_ENUM_16H(p),					\
-};									\
-									\
-static struct intc_vect p ## _vectors[] __initdata = {			\
-	INTC_IRQ_PINS_VECT_16L(p, vect),				\
-	INTC_IRQ_PINS_VECT_16H(p, vect),				\
-};									\
-									\
-static struct intc_mask_reg p ## _mask_registers[] __initdata = {	\
-	INTC_IRQ_PINS_MASK_16L(p, base),				\
-	INTC_IRQ_PINS_MASK_16H(p, base),				\
-};									\
-									\
-static struct intc_prio_reg p ## _prio_registers[] __initdata = {	\
-	INTC_IRQ_PINS_PRIO_16L(p, base),				\
-	INTC_IRQ_PINS_PRIO_16H(p, base),				\
-};									\
-									\
-static struct intc_sense_reg p ## _sense_registers[] __initdata = {	\
-	INTC_IRQ_PINS_SENSE_16L(p, base),				\
-	INTC_IRQ_PINS_SENSE_16H(p, base),				\
-};									\
-									\
-static struct intc_mask_reg p ## _ack_registers[] __initdata = {	\
-	INTC_IRQ_PINS_ACK_16L(p, base),					\
-	INTC_IRQ_PINS_ACK_16H(p, base),					\
-};									\
-									\
-static struct intc_desc p ## _desc __initdata = {			\
-	.name = str,							\
-	.resource = p ## _resources,					\
-	.num_resources = ARRAY_SIZE(p ## _resources),			\
-	.hw = INTC_HW_DESC(p ## _vectors, NULL,				\
-			     p ## _mask_registers, p ## _prio_registers, \
-			     p ## _sense_registers, p ## _ack_registers) \
-}
-
-#define INTC_PINT_E_EMPTY
-#define INTC_PINT_E_NONE 0, 0, 0, 0, 0, 0, 0, 0,
-#define INTC_PINT_E(p)							\
-	PINT ## p ## 0, PINT ## p ## 1, PINT ## p ## 2, PINT ## p ## 3,	\
-	PINT ## p ## 4, PINT ## p ## 5, PINT ## p ## 6, PINT ## p ## 7,
-
-#define INTC_PINT_V_NONE
-#define INTC_PINT_V(p, vect)					\
-	vect(PINT ## p ## 0, 0), vect(PINT ## p ## 1, 1),	\
-	vect(PINT ## p ## 2, 2), vect(PINT ## p ## 3, 3),	\
-	vect(PINT ## p ## 4, 4), vect(PINT ## p ## 5, 5),	\
-	vect(PINT ## p ## 6, 6), vect(PINT ## p ## 7, 7),
-
-#define INTC_PINT(p, mask_reg, sense_base, str,				\
-	enums_1, enums_2, enums_3, enums_4,				\
-	vect_1, vect_2, vect_3, vect_4,					\
-	mask_a, mask_b, mask_c, mask_d,					\
-	sense_a, sense_b, sense_c, sense_d)				\
-									\
-enum {									\
-	PINT ## p ## _UNUSED = 0,					\
-	enums_1 enums_2 enums_3 enums_4 				\
-};									\
-									\
-static struct intc_vect p ## _vectors[] __initdata = {			\
-	vect_1 vect_2 vect_3 vect_4					\
-};									\
-									\
-static struct intc_mask_reg p ## _mask_registers[] __initdata = {	\
-	{ mask_reg, 0, 32, /* PINTER */					\
-	  { mask_a mask_b mask_c mask_d } }				\
-};									\
-									\
-static struct intc_sense_reg p ## _sense_registers[] __initdata = {	\
-	{ sense_base + 0x00, 16, 2, /* PINTCR */			\
-	  { sense_a } },						\
-	{ sense_base + 0x04, 16, 2, /* PINTCR */			\
-	  { sense_b } },						\
-	{ sense_base + 0x08, 16, 2, /* PINTCR */			\
-	  { sense_c } },						\
-	{ sense_base + 0x0c, 16, 2, /* PINTCR */			\
-	  { sense_d } },						\
-};									\
-									\
-static struct intc_desc p ## _desc __initdata = {			\
-	.name = str,							\
-	.hw = INTC_HW_DESC(p ## _vectors, NULL,				\
-			     p ## _mask_registers, NULL,		\
-			     p ## _sense_registers, NULL),		\
-}
-
-/* INTCS */
-#define INTCS_VECT_BASE		0x3400
-#define INTCS_VECT(n, vect)	INTC_VECT((n), INTCS_VECT_BASE + (vect))
-#define intcs_evt2irq(evt)	evt2irq(INTCS_VECT_BASE + (evt))
-
-#endif  /* __ASM_MACH_INTC_H */
-- 
1.9.1



From christoffer.dall at linaro.org  Tue Aug  4 11:07:49 2015
From: christoffer.dall at linaro.org (Christoffer Dall)
Date: Tue, 4 Aug 2015 20:07:49 +0200
Subject: [PATCH v3 11/11] KVM: arm/arm64: vgic: Allow HW interrupts for
 non-shared devices
In-Reply-To: <55C0F1A5.1070204@arm.com>
References: <1437753309-17989-1-git-send-email-marc.zyngier@arm.com>
 <1437753309-17989-12-git-send-email-marc.zyngier@arm.com>
 <20150804143209.GD29335@cbox> <55C0F1A5.1070204@arm.com>
Message-ID: <20150804180749.GJ29335@cbox>

On Tue, Aug 04, 2015 at 06:08:53PM +0100, Marc Zyngier wrote:
> On 04/08/15 15:32, Christoffer Dall wrote:
> > On Fri, Jul 24, 2015 at 04:55:09PM +0100, Marc Zyngier wrote:
> >> So far, the only use of the HW interrupt facility is the timer,
> >> implying that the active state is context-switched for each vcpu,
> >> as the device is is shared across all vcpus.
> >>
> >> This does not work for a device that has been assigned to a VM,
> >> as the guest is entierely in control of that device (the HW is
> >> not shared). In that case, it makes sense to bypass the whole
> >> active state switching, and only track the deactivation of the
> >> interrupt.
> >>
> >> Signed-off-by: Marc Zyngier <marc.zyngier at arm.com>
> >> ---
> >>  include/kvm/arm_vgic.h    |  6 ++--
> >>  virt/kvm/arm/arch_timer.c |  3 +-
> >>  virt/kvm/arm/vgic.c       | 73 +++++++++++++++++++++++++++++++++++++----------
> >>  3 files changed, 64 insertions(+), 18 deletions(-)
> >>
> >> diff --git a/include/kvm/arm_vgic.h b/include/kvm/arm_vgic.h
> >> index f6bfd79..6f0a4e1 100644
> >> --- a/include/kvm/arm_vgic.h
> >> +++ b/include/kvm/arm_vgic.h
> >> @@ -164,7 +164,8 @@ struct irq_phys_map {
> >>  	u32			phys_irq;
> >>  	u32			irq;
> >>  	bool			deleted;
> >> -	bool			active;
> >> +	bool			shared;
> >> +	bool			active; /* Only valid if shared */
> >>  };
> >>  
> >>  struct irq_phys_map_entry {
> >> @@ -357,7 +358,8 @@ void vgic_v3_dispatch_sgi(struct kvm_vcpu *vcpu, u64 reg);
> >>  int kvm_vgic_vcpu_pending_irq(struct kvm_vcpu *vcpu);
> >>  int kvm_vgic_vcpu_active_irq(struct kvm_vcpu *vcpu);
> >>  struct irq_phys_map *kvm_vgic_map_phys_irq(struct kvm_vcpu *vcpu,
> >> -					   int virt_irq, int irq);
> >> +					   int virt_irq, int irq,
> >> +					   bool shared);
> >>  int kvm_vgic_unmap_phys_irq(struct kvm_vcpu *vcpu, struct irq_phys_map *map);
> >>  bool kvm_vgic_get_phys_irq_active(struct irq_phys_map *map);
> >>  void kvm_vgic_set_phys_irq_active(struct irq_phys_map *map, bool active);
> >> diff --git a/virt/kvm/arm/arch_timer.c b/virt/kvm/arm/arch_timer.c
> >> index 76e38d2..db21d8f 100644
> >> --- a/virt/kvm/arm/arch_timer.c
> >> +++ b/virt/kvm/arm/arch_timer.c
> >> @@ -203,7 +203,8 @@ int kvm_timer_vcpu_reset(struct kvm_vcpu *vcpu,
> >>  	 * Tell the VGIC that the virtual interrupt is tied to a
> >>  	 * physical interrupt. We do that once per VCPU.
> >>  	 */
> >> -	map = kvm_vgic_map_phys_irq(vcpu, irq->irq, host_vtimer_irq);
> >> +	map = kvm_vgic_map_phys_irq(vcpu, irq->irq,
> >> +				    host_vtimer_irq, true);
> >>  	if (WARN_ON(IS_ERR(map)))
> >>  		return PTR_ERR(map);
> >>  
> >> diff --git a/virt/kvm/arm/vgic.c b/virt/kvm/arm/vgic.c
> >> index e40ef70..5e6b816 100644
> >> --- a/virt/kvm/arm/vgic.c
> >> +++ b/virt/kvm/arm/vgic.c
> >> @@ -1128,19 +1128,25 @@ static void vgic_queue_irq_to_lr(struct kvm_vcpu *vcpu, int irq,
> >>  		 * active in the physical world. Otherwise the
> >>  		 * physical interrupt will fire and the guest will
> >>  		 * exit before processing the virtual interrupt.
> >> +		 *
> >> +		 * This is of course only valid for a shared
> >> +		 * interrupt. A non shared interrupt should already be
> >> +		 * active.
> >>  		 */
> >>  		if (map) {
> >> -			int ret;
> >> -
> >> -			BUG_ON(!map->active);
> >>  			vlr.hwirq = map->phys_irq;
> >>  			vlr.state |= LR_HW;
> >>  			vlr.state &= ~LR_EOI_INT;
> >>  
> >> -			ret = irq_set_irqchip_state(map->irq,
> >> -						    IRQCHIP_STATE_ACTIVE,
> >> -						    true);
> >> -			WARN_ON(ret);
> >> +			if (map->shared) {
> >> +				int ret;
> >> +
> >> +				BUG_ON(!map->active);
> >> +				ret = irq_set_irqchip_state(map->irq,
> >> +							    IRQCHIP_STATE_ACTIVE,
> >> +							    true);
> >> +				WARN_ON(ret);
> >> +			}
> >>  
> >>  			/*
> >>  			 * Make sure we're not going to sample this
> >> @@ -1383,21 +1389,41 @@ static bool vgic_process_maintenance(struct kvm_vcpu *vcpu)
> >>  static int vgic_sync_hwirq(struct kvm_vcpu *vcpu, struct vgic_lr vlr)
> >>  {
> >>  	struct irq_phys_map *map;
> >> +	bool active;
> >>  	int ret;
> >>  
> >>  	if (!(vlr.state & LR_HW))
> >>  		return 0;
> >>  
> >>  	map = vgic_irq_map_search(vcpu, vlr.irq);
> >> -	BUG_ON(!map || !map->active);
> >> +	BUG_ON(!map);
> >> +	BUG_ON(map->shared && !map->active);
> >>  
> >>  	ret = irq_get_irqchip_state(map->irq,
> >>  				    IRQCHIP_STATE_ACTIVE,
> >> -				    &map->active);
> >> +				    &active);
> >>  
> >>  	WARN_ON(ret);
> >>  
> >> -	if (map->active) {
> >> +	/*
> >> +	 * For a non-shared interrupt, we have to cater for two
> >> +	 * possible deactivation conditions:
> >> +	 *
> >> +	 * - the physical interrupt is now inactive (EOIed from the
> >> +         *   guest)
> > 
> > nit: whitespace funkyness
> > 
> >> +	 * - the physical interrupt is still active, but its virtual
> >> +	 *   counterpart is flagged as "not queued", indicating another
> >> +	 *   interrupt has fired between the EOI and the guest exit.
> >> +	 *
> >> +	 * Also, we are not reactivating a non-shared interrupt
> > 
> > what does reactivating mean? did you mean deactivate?
> 
> Deactivate indeed.
> 
> >> +	 * ourselves. This is always left to the guest.
> > 
> > In which case, add ", because the device is solely owned by the guest."
> 
> Sure.
> 
> >> +	 */
> >> +	if (!map->shared)
> >> +		return !active || !vgic_irq_is_queued(vcpu, vlr.irq);
> > 
> > do you really need the second part of the disjunction?
> > 
> > The effect seems to be that we clear the queued flag once again, and
> > clear the LR.  If we don't do this, won't we simply pick up the pending
> > flag next time we're about to run this VCPU and piggy-back on the
> > existing LR.  Perhaps this is a weird flow though?
> 
> Crucially, we free the LR in this case (the set_bit on elrsr_ptr). If we
> don't do this, we're indeed going to schedule the vcpu (it has something
> to process), but we never allow piggy-backing on level interrupts. We'd
> need some special hack to handle this.
> 
> I definitely feel more comfortable reporting that the interrupt has been
> deactivated (which is the case), and let the normal flow pick up the
> next injected interrupt.
> 
Yes, you're right, it's much better this way.

I assume you'll still wait with this stuff until the priority drop / EOI
stuff is in, so I'll do a formal review again once all the dependencies
are there.

But this looks good to me.

-Christoffer


From marc.zyngier at arm.com  Tue Aug  4 11:10:55 2015
From: marc.zyngier at arm.com (Marc Zyngier)
Date: Tue, 04 Aug 2015 19:10:55 +0100
Subject: [PATCH v3 06/11] KVM: arm/arm64: vgic: Allow dynamic mapping
 of physical/virtual interrupts
In-Reply-To: <20150804173650.GG29335@cbox>
References: <1437753309-17989-1-git-send-email-marc.zyngier@arm.com>
 <1437753309-17989-7-git-send-email-marc.zyngier@arm.com>
 <20150804130457.GA29335@cbox> <55C0D9C7.7060707@arm.com>
 <20150804173650.GG29335@cbox>
Message-ID: <55C1002F.6070801@arm.com>

On 04/08/15 18:36, Christoffer Dall wrote:
> On Tue, Aug 04, 2015 at 04:27:03PM +0100, Marc Zyngier wrote:
>> On 04/08/15 14:04, Christoffer Dall wrote:
>>> On Fri, Jul 24, 2015 at 04:55:04PM +0100, Marc Zyngier wrote:
>>>> In order to be able to feed physical interrupts to a guest, we need
>>>> to be able to establish the virtual-physical mapping between the two
>>>> worlds.
>>>>
>>>> The mappings are kept in a set of RCU lists, indexed by virtual interrupts.
>>>>
>>>> Signed-off-by: Marc Zyngier <marc.zyngier at arm.com>
>>>> ---
>>>>  arch/arm/kvm/arm.c     |   2 +
>>>>  include/kvm/arm_vgic.h |  26 +++++++
>>>>  virt/kvm/arm/vgic.c    | 189 ++++++++++++++++++++++++++++++++++++++++++++++++-
>>>>  3 files changed, 216 insertions(+), 1 deletion(-)
>>>>

[...]

>>>> +/**
>>>> + * kvm_vgic_unmap_phys_irq - Remove a virtual to physical IRQ mapping
>>>> + * @vcpu: The VCPU pointer
>>>> + * @map: The pointer to a mapping obtained through kvm_vgic_map_phys_irq
>>>> + *
>>>> + * Remove an existing mapping between virtual and physical interrupts.
>>>> + */
>>>> +int kvm_vgic_unmap_phys_irq(struct kvm_vcpu *vcpu, struct irq_phys_map *map)
>>>> +{
>>>> +     struct vgic_dist *dist = &vcpu->kvm->arch.vgic;
>>>> +     struct irq_phys_map_entry *entry;
>>>> +     struct list_head *root;
>>>> +
>>>> +     if (!map)
>>>> +             return -EINVAL;
>>>> +
>>>> +     root = vgic_get_irq_phys_map_list(vcpu, map->virt_irq);
>>>> +
>>>> +     spin_lock(&dist->irq_phys_map_lock);
>>>> +
>>>> +     list_for_each_entry(entry, root, entry) {
>>>> +             if (&entry->map == map && !map->deleted) {
>>>> +                     map->deleted = true;
>>>
>>> why do you need the 'deleted' flag?  You now search the list only after
>>> holding the lock, so the race I pointed out before doesn't exist
>>> anymore.  Is there an additional issue that the deleted flag is taking
>>> care of?
>>
>> This could still race with a destroy occuring before we take the lock,
>> and before we get get RCU to do the cleanup (the list would still be
>> populated).
>>
> 
> That's not how I understand list_del_rcu; I think it deletes the entry
> immediately with the right memory barriers.  It is only the free
> operation that happens on rcu sync and can be/is deferred.

Indeed. I stupidly though the two were deferred, but reading the code
definitely confirmed your point. I'll get rid of the delete stuff.

Thanks,

	M.
-- 
Jazz is not dead. It just smells funny...


From julien.grall at citrix.com  Tue Aug  4 11:12:46 2015
From: julien.grall at citrix.com (Julien Grall)
Date: Tue, 4 Aug 2015 19:12:46 +0100
Subject: [PATCH v2 2/8] xen: Make clear that swiotlb and biomerge are dealing
 with DMA address
In-Reply-To: <1438711972-18752-1-git-send-email-julien.grall@citrix.com>
References: <1438711972-18752-1-git-send-email-julien.grall@citrix.com>
Message-ID: <1438711972-18752-3-git-send-email-julien.grall@citrix.com>

The swiotlb is required when programming a DMA address on ARM when a
device is not protected by an IOMMU.

In this case, the DMA address should always be equal to the machine address.
For DOM0 memory, Xen ensure it by have an identity mapping between the
guest address and host address. However, when mapping a foreign grant
reference, the 1:1 model doesn't work.

For ARM guest, most of the callers of pfn_to_mfn expects to get a GFN
(Guest Frame Number), i.e a PFN (Page Frame Number) from the Linux point
of view given that all ARM guest are auto-translated.

Even though the name pfn_to_mfn is misleading, we need to ensure that
those caller get a GFN and not by mistake a MFN. In pratical, I haven't
seen error related to this but we should fix it for the sake of
correctness.

In order to fix the implementation of pfn_to_mfn on ARM in a follow-up
patch, we have to introduce new helpers to return the DMA from a PFN and
the invert.

On x86, the new helpers will be an alias of pfn_to_mfn and mfn_to_pfn.

The helpers will be used in swiotlb and xen_biovec_phys_mergeable.

This is necessary in the latter because we have to ensure that the
biovec code will not try to merge a biovec using foreign page and
another using Linux memory.

Lastly, the helper mfn_to_local_pfn has been renamed to dnf_to_local_pfn
given that the only usage was in swiotlb.

Signed-off-by: Julien Grall <julien.grall at citrix.com>
Cc: Stefano Stabellini <stefano.stabellini at eu.citrix.com>
Cc: Russell King <linux at arm.linux.org.uk>
Cc: Konrad Rzeszutek Wilk <konrad.wilk at oracle.com>
Cc: Boris Ostrovsky <boris.ostrovsky at oracle.com>
Cc: David Vrabel <david.vrabel at citrix.com>
Cc: Thomas Gleixner <tglx at linutronix.de>
Cc: Ingo Molnar <mingo at redhat.com>
Cc: "H. Peter Anvin" <hpa at zytor.com>
Cc: x86 at kernel.org
Cc: linux-arm-kernel at lists.infradead.org

---
    Changes in v2:
        - Use bfn (Bus Frame Number) rather than dfn to match the
        proposed terminology for pv-iommu hypercall.
---
 arch/arm/include/asm/xen/page.h | 23 +++++++++++++++++++++--
 arch/arm/xen/mm.c               |  4 ++--
 arch/x86/include/asm/xen/page.h |  8 ++++++--
 drivers/xen/biomerge.c          |  6 +++---
 drivers/xen/swiotlb-xen.c       | 16 ++++++++--------
 5 files changed, 40 insertions(+), 17 deletions(-)

diff --git a/arch/arm/include/asm/xen/page.h b/arch/arm/include/asm/xen/page.h
index 98b1084..bc5e77c 100644
--- a/arch/arm/include/asm/xen/page.h
+++ b/arch/arm/include/asm/xen/page.h
@@ -52,7 +52,26 @@ static inline unsigned long mfn_to_pfn(unsigned long mfn)
 	return mfn;
 }
 
-#define mfn_to_local_pfn(mfn) mfn_to_pfn(mfn)
+/* Pseudo-physical <-> BUS conversion */
+static inline unsigned long pfn_to_bfn(unsigned long pfn)
+{
+	unsigned long mfn;
+
+	if (phys_to_mach.rb_node != NULL) {
+		mfn = __pfn_to_mfn(pfn);
+		if (mfn != INVALID_P2M_ENTRY)
+			return mfn;
+	}
+
+	return pfn;
+}
+
+static inline unsigned long bfn_to_pfn(unsigned long bfn)
+{
+	return bfn;
+}
+
+#define bfn_to_local_pfn(bfn)	bfn_to_pfn(bfn)
 
 /* VIRT <-> MACHINE conversion */
 #define virt_to_mfn(v)		(pfn_to_mfn(virt_to_pfn(v)))
@@ -96,7 +115,7 @@ static inline bool set_phys_to_machine(unsigned long pfn, unsigned long mfn)
 
 bool xen_arch_need_swiotlb(struct device *dev,
 			   unsigned long pfn,
-			   unsigned long mfn);
+			   unsigned long dfn);
 unsigned long xen_get_swiotlb_free_pages(unsigned int order);
 
 #endif /* _ASM_ARM_XEN_PAGE_H */
diff --git a/arch/arm/xen/mm.c b/arch/arm/xen/mm.c
index 03e75fe..12bde72 100644
--- a/arch/arm/xen/mm.c
+++ b/arch/arm/xen/mm.c
@@ -139,9 +139,9 @@ void __xen_dma_sync_single_for_device(struct device *hwdev,
 
 bool xen_arch_need_swiotlb(struct device *dev,
 			   unsigned long pfn,
-			   unsigned long mfn)
+			   unsigned long dfn)
 {
-	return (!hypercall_cflush && (pfn != mfn) && !is_device_dma_coherent(dev));
+	return (!hypercall_cflush && (pfn != dfn) && !is_device_dma_coherent(dev));
 }
 
 int xen_create_contiguous_region(phys_addr_t pstart, unsigned int order,
diff --git a/arch/x86/include/asm/xen/page.h b/arch/x86/include/asm/xen/page.h
index c44a5d5..8ba04b8 100644
--- a/arch/x86/include/asm/xen/page.h
+++ b/arch/x86/include/asm/xen/page.h
@@ -178,6 +178,10 @@ static inline xpaddr_t machine_to_phys(xmaddr_t machine)
 	return XPADDR(PFN_PHYS(mfn_to_pfn(PFN_DOWN(machine.maddr))) | offset);
 }
 
+/* Pseudo-physical <-> Bus conversion */
+#define pfn_to_bfn(pfn)		pfn_to_mfn(pfn)
+#define bfn_to_pfn(bfn)		mfn_to_pfn(bfn)
+
 /*
  * We detect special mappings in one of two ways:
  *  1. If the MFN is an I/O page then Xen will set the m2p entry
@@ -198,7 +202,7 @@ static inline xpaddr_t machine_to_phys(xmaddr_t machine)
  *      require. In all the cases we care about, the FOREIGN_FRAME bit is
  *      masked (e.g., pfn_to_mfn()) so behaviour there is correct.
  */
-static inline unsigned long mfn_to_local_pfn(unsigned long mfn)
+static inline unsigned long bfn_to_local_pfn(unsigned long mfn)
 {
 	unsigned long pfn;
 
@@ -264,7 +268,7 @@ void make_lowmem_page_readwrite(void *vaddr);
 
 static inline bool xen_arch_need_swiotlb(struct device *dev,
 					 unsigned long pfn,
-					 unsigned long mfn)
+					 unsigned long bfn)
 {
 	return false;
 }
diff --git a/drivers/xen/biomerge.c b/drivers/xen/biomerge.c
index 0edb91c..8ae2fc90 100644
--- a/drivers/xen/biomerge.c
+++ b/drivers/xen/biomerge.c
@@ -6,10 +6,10 @@
 bool xen_biovec_phys_mergeable(const struct bio_vec *vec1,
 			       const struct bio_vec *vec2)
 {
-	unsigned long mfn1 = pfn_to_mfn(page_to_pfn(vec1->bv_page));
-	unsigned long mfn2 = pfn_to_mfn(page_to_pfn(vec2->bv_page));
+	unsigned long bfn1 = pfn_to_bfn(page_to_pfn(vec1->bv_page));
+	unsigned long bfn2 = pfn_to_bfn(page_to_pfn(vec2->bv_page));
 
 	return __BIOVEC_PHYS_MERGEABLE(vec1, vec2) &&
-		((mfn1 == mfn2) || ((mfn1+1) == mfn2));
+		((bfn1 == bfn2) || ((bfn1+1) == bfn2));
 }
 EXPORT_SYMBOL(xen_biovec_phys_mergeable);
diff --git a/drivers/xen/swiotlb-xen.c b/drivers/xen/swiotlb-xen.c
index 4c54932..d757a3e 100644
--- a/drivers/xen/swiotlb-xen.c
+++ b/drivers/xen/swiotlb-xen.c
@@ -82,8 +82,8 @@ static u64 start_dma_addr;
  */
 static inline dma_addr_t xen_phys_to_bus(phys_addr_t paddr)
 {
-	unsigned long mfn = pfn_to_mfn(PFN_DOWN(paddr));
-	dma_addr_t dma = (dma_addr_t)mfn << PAGE_SHIFT;
+	unsigned long bfn = pfn_to_bfn(PFN_DOWN(paddr));
+	dma_addr_t dma = (dma_addr_t)bfn << PAGE_SHIFT;
 
 	dma |= paddr & ~PAGE_MASK;
 
@@ -92,7 +92,7 @@ static inline dma_addr_t xen_phys_to_bus(phys_addr_t paddr)
 
 static inline phys_addr_t xen_bus_to_phys(dma_addr_t baddr)
 {
-	unsigned long pfn = mfn_to_pfn(PFN_DOWN(baddr));
+	unsigned long pfn = bfn_to_pfn(PFN_DOWN(baddr));
 	dma_addr_t dma = (dma_addr_t)pfn << PAGE_SHIFT;
 	phys_addr_t paddr = dma;
 
@@ -110,15 +110,15 @@ static int check_pages_physically_contiguous(unsigned long pfn,
 					     unsigned int offset,
 					     size_t length)
 {
-	unsigned long next_mfn;
+	unsigned long next_bfn;
 	int i;
 	int nr_pages;
 
-	next_mfn = pfn_to_mfn(pfn);
+	next_bfn = pfn_to_bfn(pfn);
 	nr_pages = (offset + length + PAGE_SIZE-1) >> PAGE_SHIFT;
 
 	for (i = 1; i < nr_pages; i++) {
-		if (pfn_to_mfn(++pfn) != ++next_mfn)
+		if (pfn_to_bfn(++pfn) != ++next_bfn)
 			return 0;
 	}
 	return 1;
@@ -138,8 +138,8 @@ static inline int range_straddles_page_boundary(phys_addr_t p, size_t size)
 
 static int is_xen_swiotlb_buffer(dma_addr_t dma_addr)
 {
-	unsigned long mfn = PFN_DOWN(dma_addr);
-	unsigned long pfn = mfn_to_local_pfn(mfn);
+	unsigned long bfn = PFN_DOWN(dma_addr);
+	unsigned long pfn = bfn_to_local_pfn(bfn);
 	phys_addr_t paddr;
 
 	/* If the address is outside our domain, it CAN
-- 
2.1.4



From julien.grall at citrix.com  Tue Aug  4 11:12:44 2015
From: julien.grall at citrix.com (Julien Grall)
Date: Tue, 4 Aug 2015 19:12:44 +0100
Subject: [PATCH v2 0/8] Use correctly the Xen memory terminologies in Linux
Message-ID: <1438711972-18752-1-git-send-email-julien.grall@citrix.com>

Hi all,

This patch series aims to use the memory terminologies described in
include/xen/mm.h [1] for Linux xen code.

Linux is using mistakenly MFN when GFN is meant, I suspect this is because the
first support of Xen was for PV. This has brought some misimplementation
of memory helpers on ARM and make the developper confused about the expected
behavior.

For instance, with pfn_to_mfn, we expect to get a MFN based on the name.
Although, if we look at the implementation on x86, it's returning a GFN.
Most of the callers are also using it this way.

The first 2 patches of this series is ARM related in order to remove
PV specific helpers which should not be used and fixing the implementation of
pfn_to_mfn.

The rest of the series is here rename most of the usage in the common code
of MFN to GFN. I also took the opportunity to replace most of the call to
pfn_to_gfn in the common code by page_to_gfn avoid construction such
as pfn_to_gfn(page_to_pfn(...).

Note the one xen-blkfront will be dropped by 64K series [2], I can include it
if necessary.

Major changes in v2:
    - Use bfn rather than dfn for the DMA address
    - Re-introduced pfn_to_mfn for PV guests only
    - Typoes

For all the changes see in each patch.

This series is based on linus's branch. A branch with all the patches
can be found here:
    git://xenbits.xen.org/people/julieng/linux-arm.git branch page-renaming-v2

It was been boot tested on ARM64 and only built for x86 and ARM32.
I would be happy if someone can give a try on x86 as I don't have a x86
box setup with Xen.

Sincerely yours,

[1] http://xenbits.xen.org/gitweb/?p=xen.git;a=commitdiff;h=e758ed14f390342513405dd766e874934573e6cb
[2] https://lkml.org/lkml/2015/7/9/628

Cc: Boris Ostrovsky <boris.ostrovsky at oracle.com>
Cc: David Vrabel <david.vrabel at citrix.com>
Cc: Dmitry Torokhov <dmitry.torokhov at gmail.com>
Cc: Greg Kroah-Hartman <gregkh at linuxfoundation.org>
Cc: "H. Peter Anvin" <hpa at zytor.com>
Cc: Ian Campbell <ian.campbell at citrix.com>
Cc: Ingo Molnar <mingo at redhat.com>
Cc: "James E.J. Bottomley" <JBottomley at odin.com>
Cc: Jean-Christophe Plagniol-Villard <plagnioj at jcrosoft.com>
Cc: Jiri Slaby <jslaby at suse.com>
Cc: Juergen Gross <jgross at suse.com>
Cc: Konrad Rzeszutek Wilk <konrad.wilk at oracle.com>
Cc: linux-api at vger.kernel.org
Cc: linux-arm-kernel at lists.infradead.org
Cc: linux-fbdev at vger.kernel.org
Cc: linux-input at vger.kernel.org
Cc: linuxppc-dev at lists.ozlabs.org
Cc: linux-scsi at vger.kernel.org
Cc: netdev at vger.kernel.org
Cc: "Roger Pau Monn?" <roger.pau at citrix.com>
Cc: Russell King <linux at arm.linux.org.uk>
Cc: Stefano Stabellini <stefano.stabellini at eu.citrix.com>
Cc: Thomas Gleixner <tglx at linutronix.de>
Cc: Tomi Valkeinen <tomi.valkeinen at ti.com>
Cc: Wei Liu <wei.liu2 at citrix.com>
Cc: x86 at kernel.org

Julien Grall (8):
  arm/xen: Remove helpers which are PV specific
  xen: Make clear that swiotlb and biomerge are dealing with DMA address
  arm/xen: implement correctly pfn_to_mfn
  xen: Use the correctly the Xen memory terminologies
  xen/tmem: Use page_to_gfn rather than pfn_to_gfn
  video/xen-fbfront: Further s/MFN/GFN clean-up
  hvc/xen: Further s/MFN/GFN clean-up
  xen/privcmd: Further s/MFN/GFN/ clean-up

 arch/arm/include/asm/xen/page.h         | 44 ++++++++++++++++-----------------
 arch/arm/xen/enlighten.c                | 18 +++++++-------
 arch/arm/xen/mm.c                       |  4 +--
 arch/x86/include/asm/xen/page.h         | 37 +++++++++++++++++++++------
 arch/x86/xen/mmu.c                      | 32 ++++++++++++------------
 arch/x86/xen/smp.c                      |  2 +-
 drivers/block/xen-blkfront.c            |  6 ++---
 drivers/input/misc/xen-kbdfront.c       |  4 +--
 drivers/net/xen-netback/netback.c       |  4 +--
 drivers/net/xen-netfront.c              |  8 +++---
 drivers/scsi/xen-scsifront.c            |  8 +++---
 drivers/tty/hvc/hvc_xen.c               | 18 ++++++--------
 drivers/video/fbdev/xen-fbfront.c       | 20 +++++++--------
 drivers/xen/balloon.c                   |  2 +-
 drivers/xen/biomerge.c                  |  6 ++---
 drivers/xen/events/events_base.c        |  2 +-
 drivers/xen/events/events_fifo.c        |  4 +--
 drivers/xen/gntalloc.c                  |  3 ++-
 drivers/xen/manage.c                    |  2 +-
 drivers/xen/privcmd.c                   | 44 ++++++++++++++++-----------------
 drivers/xen/swiotlb-xen.c               | 16 ++++++------
 drivers/xen/tmem.c                      | 21 ++++++----------
 drivers/xen/xenbus/xenbus_client.c      |  2 +-
 drivers/xen/xenbus/xenbus_dev_backend.c |  2 +-
 drivers/xen/xenbus/xenbus_probe.c       |  8 +++---
 drivers/xen/xlate_mmu.c                 | 18 +++++++-------
 include/uapi/xen/privcmd.h              |  4 +++
 include/xen/page.h                      |  4 +--
 include/xen/xen-ops.h                   | 10 ++++----
 29 files changed, 183 insertions(+), 170 deletions(-)

-- 
2.1.4



From julien.grall at citrix.com  Tue Aug  4 11:12:47 2015
From: julien.grall at citrix.com (Julien Grall)
Date: Tue, 4 Aug 2015 19:12:47 +0100
Subject: [PATCH v2 3/8] arm/xen: implement correctly pfn_to_mfn
In-Reply-To: <1438711972-18752-1-git-send-email-julien.grall@citrix.com>
References: <1438711972-18752-1-git-send-email-julien.grall@citrix.com>
Message-ID: <1438711972-18752-4-git-send-email-julien.grall@citrix.com>

After the commit introducing convertion between DMA and guest address,
all the callers of pfn_to_mfn are expecting to get a GFN (Guest Frame
Number). On ARM, all the guests are auto-translated so the GFN is equal
to the Linux PFN (Pseudo-physical Frame Number).

The current implementation may return an MFN if the caller is passing a
PFN associated to a mapped foreign grant. In pratical, I haven't seen
the problem on running guest but we should fix it for the sake of
correctness.

Correct the implementation by always returning the pfn passed in parameter.

A follow-up patch will take care to rename pfn_to_mfn to a suitable
name.

Signed-off-by: Julien Grall <julien.grall at citrix.com>
Cc: Stefano Stabellini <stefano.stabellini at eu.citrix.com>
Cc: Russell King <linux at arm.linux.org.uk>
Cc: linux-arm-kernel at lists.infradead.org
---
 arch/arm/include/asm/xen/page.h | 8 --------
 1 file changed, 8 deletions(-)

diff --git a/arch/arm/include/asm/xen/page.h b/arch/arm/include/asm/xen/page.h
index bc5e77c..087d86e 100644
--- a/arch/arm/include/asm/xen/page.h
+++ b/arch/arm/include/asm/xen/page.h
@@ -36,14 +36,6 @@ extern struct rb_root phys_to_mach;
 
 static inline unsigned long pfn_to_mfn(unsigned long pfn)
 {
-	unsigned long mfn;
-
-	if (phys_to_mach.rb_node != NULL) {
-		mfn = __pfn_to_mfn(pfn);
-		if (mfn != INVALID_P2M_ENTRY)
-			return mfn;
-	}
-
 	return pfn;
 }
 
-- 
2.1.4



From julien.grall at citrix.com  Tue Aug  4 11:12:48 2015
From: julien.grall at citrix.com (Julien Grall)
Date: Tue, 4 Aug 2015 19:12:48 +0100
Subject: [PATCH v2 4/8] xen: Use the correctly the Xen memory terminologies
In-Reply-To: <1438711972-18752-1-git-send-email-julien.grall@citrix.com>
References: <1438711972-18752-1-git-send-email-julien.grall@citrix.com>
Message-ID: <1438711972-18752-5-git-send-email-julien.grall@citrix.com>

Based on include/xen/mm.h [1], Linux is mistakenly using MFN when GFN
is meant, I suspect this is because the first support for Xen was for
PV. This resulted in some misimplementation of helpers on ARM and
confused developers about the expected behavior.

For instance, with pfn_to_mfn, we expect to get an MFN based on the name.
Although, if we look at the implementation on x86, it's returning a GFN.

For clarity and avoid new confusion, replace any reference to mfn with
gfn in any helpers used by PV drivers. The x86 code will still keep some
reference of pfn_to_mfn but exclusively for PV (a BUG_ON has been added
to ensure this). No changes as been made in the hypercall field, even
though they may be invalid, in order to keep the same as the defintion
in xen repo.

Take also the opportunity to simplify simple construction such
as pfn_to_mfn(page_to_pfn(page)) into page_to_gfn. More complex clean up
will come in follow-up patches.

[1] http://xenbits.xen.org/gitweb/?p=xen.git;a=commitdiff;h=e758ed14f390342513405dd766e874934573e6cb

Signed-off-by: Julien Grall <julien.grall at citrix.com>
Cc: Stefano Stabellini <stefano.stabellini at eu.citrix.com>
Cc: Russell King <linux at arm.linux.org.uk>
Cc: Konrad Rzeszutek Wilk <konrad.wilk at oracle.com>
Cc: Boris Ostrovsky <boris.ostrovsky at oracle.com>
Cc: David Vrabel <david.vrabel at citrix.com>
Cc: Thomas Gleixner <tglx at linutronix.de>
Cc: Ingo Molnar <mingo at redhat.com>
Cc: "H. Peter Anvin" <hpa at zytor.com>
Cc: x86 at kernel.org
Cc: "Roger Pau Monn?" <roger.pau at citrix.com>
Cc: Dmitry Torokhov <dmitry.torokhov at gmail.com>
Cc: Ian Campbell <ian.campbell at citrix.com>
Cc: Wei Liu <wei.liu2 at citrix.com>
Cc: Juergen Gross <jgross at suse.com>
Cc: "James E.J. Bottomley" <JBottomley at odin.com>
Cc: Greg Kroah-Hartman <gregkh at linuxfoundation.org>
Cc: Jiri Slaby <jslaby at suse.com>
Cc: Jean-Christophe Plagniol-Villard <plagnioj at jcrosoft.com>
Cc: Tomi Valkeinen <tomi.valkeinen at ti.com>
Cc: linux-input at vger.kernel.org
Cc: netdev at vger.kernel.org
Cc: linux-scsi at vger.kernel.org
Cc: linuxppc-dev at lists.ozlabs.org
Cc: linux-fbdev at vger.kernel.org
Cc: linux-arm-kernel at lists.infradead.org

---
    Note that I've re-introduced mfn_to_pfn & co only for x86 PV code.
    The helpers contain a BUG_ON to ensure that it's never called for
    auto-translated guests. I did as best as my can to determine whether
    mfn or gfn helpers should be used. Although, I haven't tried to boot
    it.

    It may be possible to do further cleanup in the mmu.c where I found
    some check to auto-translated. I'm not sure why given that the pvmmu
    callback are only used for non-auto translated guest.

    Finally, given those changes, I didn't retain the Reviewed-by/Acked-by.

    Changes in v2:
        - Give directly the URL to the commit rather than the commit ID
        - xenstored_local_init: keep the cast to void *
        - Typoes
        - Keep pfn_to_mfn for x86 and PV-only. The *mfn* helpers are
        used in arch/x86/xen for enlighten.c, mmu.c, p2m.c, setup.c,
        smp.c and mm.c
---
 arch/arm/include/asm/xen/page.h         | 13 +++++++------
 arch/x86/include/asm/xen/page.h         | 33 ++++++++++++++++++++++++++-------
 arch/x86/xen/smp.c                      |  2 +-
 drivers/block/xen-blkfront.c            |  6 +++---
 drivers/input/misc/xen-kbdfront.c       |  4 ++--
 drivers/net/xen-netback/netback.c       |  4 ++--
 drivers/net/xen-netfront.c              |  8 ++++----
 drivers/scsi/xen-scsifront.c            |  8 +++-----
 drivers/tty/hvc/hvc_xen.c               |  5 +++--
 drivers/video/fbdev/xen-fbfront.c       |  4 ++--
 drivers/xen/balloon.c                   |  2 +-
 drivers/xen/events/events_base.c        |  2 +-
 drivers/xen/events/events_fifo.c        |  4 ++--
 drivers/xen/gntalloc.c                  |  3 ++-
 drivers/xen/manage.c                    |  2 +-
 drivers/xen/tmem.c                      |  4 ++--
 drivers/xen/xenbus/xenbus_client.c      |  2 +-
 drivers/xen/xenbus/xenbus_dev_backend.c |  2 +-
 drivers/xen/xenbus/xenbus_probe.c       |  8 +++-----
 include/xen/page.h                      |  4 ++--
 20 files changed, 69 insertions(+), 51 deletions(-)

diff --git a/arch/arm/include/asm/xen/page.h b/arch/arm/include/asm/xen/page.h
index 087d86e..51e5bf1 100644
--- a/arch/arm/include/asm/xen/page.h
+++ b/arch/arm/include/asm/xen/page.h
@@ -34,14 +34,15 @@ typedef struct xpaddr {
 unsigned long __pfn_to_mfn(unsigned long pfn);
 extern struct rb_root phys_to_mach;
 
-static inline unsigned long pfn_to_mfn(unsigned long pfn)
+/* Pseudo-physical <-> Guest conversion */
+static inline unsigned long pfn_to_gfn(unsigned long pfn)
 {
 	return pfn;
 }
 
-static inline unsigned long mfn_to_pfn(unsigned long mfn)
+static inline unsigned long gfn_to_pfn(unsigned long gfn)
 {
-	return mfn;
+	return gfn;
 }
 
 /* Pseudo-physical <-> BUS conversion */
@@ -65,9 +66,9 @@ static inline unsigned long bfn_to_pfn(unsigned long bfn)
 
 #define bfn_to_local_pfn(bfn)	bfn_to_pfn(bfn)
 
-/* VIRT <-> MACHINE conversion */
-#define virt_to_mfn(v)		(pfn_to_mfn(virt_to_pfn(v)))
-#define mfn_to_virt(m)		(__va(mfn_to_pfn(m) << PAGE_SHIFT))
+/* VIRT <-> GUEST conversion */
+#define virt_to_gfn(v)		(pfn_to_gfn(virt_to_pfn(v)))
+#define gfn_to_virt(m)		(__va(gfn_to_pfn(m) << PAGE_SHIFT))
 
 /* Only used in PV code. But ARM guests are always HVM. */
 static inline xmaddr_t arbitrary_virt_to_machine(void *vaddr)
diff --git a/arch/x86/include/asm/xen/page.h b/arch/x86/include/asm/xen/page.h
index 8ba04b8..c2da42f 100644
--- a/arch/x86/include/asm/xen/page.h
+++ b/arch/x86/include/asm/xen/page.h
@@ -103,8 +103,7 @@ static inline unsigned long pfn_to_mfn(unsigned long pfn)
 {
 	unsigned long mfn;
 
-	if (xen_feature(XENFEAT_auto_translated_physmap))
-		return pfn;
+	BUG_ON(xen_feature(XENFEAT_auto_translated_physmap));
 
 	mfn = __pfn_to_mfn(pfn);
 
@@ -149,8 +148,7 @@ static inline unsigned long mfn_to_pfn(unsigned long mfn)
 {
 	unsigned long pfn;
 
-	if (xen_feature(XENFEAT_auto_translated_physmap))
-		return mfn;
+	BUG_ON(xen_feature(XENFEAT_auto_translated_physmap));
 
 	pfn = mfn_to_pfn_no_overrides(mfn);
 	if (__pfn_to_mfn(pfn) != mfn)
@@ -178,9 +176,26 @@ static inline xpaddr_t machine_to_phys(xmaddr_t machine)
 	return XPADDR(PFN_PHYS(mfn_to_pfn(PFN_DOWN(machine.maddr))) | offset);
 }
 
+/* Pseudo-physical <-> Guest conversion */
+static inline unsigned long pfn_to_gfn(unsigned long pfn)
+{
+	if (xen_feature(XENFEAT_auto_translated_physmap))
+		return pfn;
+	else
+		return pfn_to_mfn(pfn);
+}
+
+static inline unsigned long gfn_to_pfn(unsigned long gfn)
+{
+	if (xen_feature(XENFEAT_auto_translated_physmap))
+		return gfn;
+	else
+		return mfn_to_pfn(gfn);
+}
+
 /* Pseudo-physical <-> Bus conversion */
-#define pfn_to_bfn(pfn)		pfn_to_mfn(pfn)
-#define bfn_to_pfn(bfn)		mfn_to_pfn(bfn)
+#define pfn_to_bfn(pfn)		pfn_to_gfn(pfn)
+#define bfn_to_pfn(bfn)		gfn_to_pfn(bfn)
 
 /*
  * We detect special mappings in one of two ways:
@@ -217,9 +232,13 @@ static inline unsigned long bfn_to_local_pfn(unsigned long mfn)
 
 /* VIRT <-> MACHINE conversion */
 #define virt_to_machine(v)	(phys_to_machine(XPADDR(__pa(v))))
-#define virt_to_pfn(v)          (PFN_DOWN(__pa(v)))
 #define virt_to_mfn(v)		(pfn_to_mfn(virt_to_pfn(v)))
 #define mfn_to_virt(m)		(__va(mfn_to_pfn(m) << PAGE_SHIFT))
+#define virt_to_pfn(v)          (PFN_DOWN(__pa(v)))
+
+/* VIRT <-> GUEST conversion */
+#define virt_to_gfn(v)		(pfn_to_gfn(virt_to_pfn(v)))
+#define gfn_to_virt(g)		(__va(gfn_to_pfn(g) << PAGE_SHIFT))
 
 static inline unsigned long pte_mfn(pte_t pte)
 {
diff --git a/arch/x86/xen/smp.c b/arch/x86/xen/smp.c
index 8648438..1e0931b 100644
--- a/arch/x86/xen/smp.c
+++ b/arch/x86/xen/smp.c
@@ -429,7 +429,7 @@ cpu_initialize_context(unsigned int cpu, struct task_struct *idle)
 	}
 #endif
 	ctxt->user_regs.esp = idle->thread.sp0 - sizeof(struct pt_regs);
-	ctxt->ctrlreg[3] = xen_pfn_to_cr3(virt_to_mfn(swapper_pg_dir));
+	ctxt->ctrlreg[3] = xen_pfn_to_cr3(virt_to_gfn(swapper_pg_dir));
 	if (HYPERVISOR_vcpu_op(VCPUOP_initialise, cpu, ctxt))
 		BUG();
 
diff --git a/drivers/block/xen-blkfront.c b/drivers/block/xen-blkfront.c
index 6d89ed3..2e541a4 100644
--- a/drivers/block/xen-blkfront.c
+++ b/drivers/block/xen-blkfront.c
@@ -247,7 +247,7 @@ static struct grant *get_grant(grant_ref_t *gref_head,
                                struct blkfront_info *info)
 {
 	struct grant *gnt_list_entry;
-	unsigned long buffer_mfn;
+	unsigned long buffer_gfn;
 
 	BUG_ON(list_empty(&info->grants));
 	gnt_list_entry = list_first_entry(&info->grants, struct grant,
@@ -266,10 +266,10 @@ static struct grant *get_grant(grant_ref_t *gref_head,
 		BUG_ON(!pfn);
 		gnt_list_entry->pfn = pfn;
 	}
-	buffer_mfn = pfn_to_mfn(gnt_list_entry->pfn);
+	buffer_gfn = pfn_to_gfn(gnt_list_entry->pfn);
 	gnttab_grant_foreign_access_ref(gnt_list_entry->gref,
 	                                info->xbdev->otherend_id,
-	                                buffer_mfn, 0);
+	                                buffer_gfn, 0);
 	return gnt_list_entry;
 }
 
diff --git a/drivers/input/misc/xen-kbdfront.c b/drivers/input/misc/xen-kbdfront.c
index 95599e4..23d0549 100644
--- a/drivers/input/misc/xen-kbdfront.c
+++ b/drivers/input/misc/xen-kbdfront.c
@@ -232,7 +232,7 @@ static int xenkbd_connect_backend(struct xenbus_device *dev,
 	struct xenbus_transaction xbt;
 
 	ret = gnttab_grant_foreign_access(dev->otherend_id,
-	                                  virt_to_mfn(info->page), 0);
+	                                  virt_to_gfn(info->page), 0);
 	if (ret < 0)
 		return ret;
 	info->gref = ret;
@@ -255,7 +255,7 @@ static int xenkbd_connect_backend(struct xenbus_device *dev,
 		goto error_irqh;
 	}
 	ret = xenbus_printf(xbt, dev->nodename, "page-ref", "%lu",
-			    virt_to_mfn(info->page));
+			    virt_to_gfn(info->page));
 	if (ret)
 		goto error_xenbus;
 	ret = xenbus_printf(xbt, dev->nodename, "page-gref", "%u", info->gref);
diff --git a/drivers/net/xen-netback/netback.c b/drivers/net/xen-netback/netback.c
index 7d50711..3b7b7c3 100644
--- a/drivers/net/xen-netback/netback.c
+++ b/drivers/net/xen-netback/netback.c
@@ -314,7 +314,7 @@ static void xenvif_gop_frag_copy(struct xenvif_queue *queue, struct sk_buff *skb
 		} else {
 			copy_gop->source.domid = DOMID_SELF;
 			copy_gop->source.u.gmfn =
-				virt_to_mfn(page_address(page));
+				virt_to_gfn(page_address(page));
 		}
 		copy_gop->source.offset = offset;
 
@@ -1284,7 +1284,7 @@ static void xenvif_tx_build_gops(struct xenvif_queue *queue,
 		queue->tx_copy_ops[*copy_ops].source.offset = txreq.offset;
 
 		queue->tx_copy_ops[*copy_ops].dest.u.gmfn =
-			virt_to_mfn(skb->data);
+			virt_to_gfn(skb->data);
 		queue->tx_copy_ops[*copy_ops].dest.domid = DOMID_SELF;
 		queue->tx_copy_ops[*copy_ops].dest.offset =
 			offset_in_page(skb->data);
diff --git a/drivers/net/xen-netfront.c b/drivers/net/xen-netfront.c
index f948c46..5cdab73 100644
--- a/drivers/net/xen-netfront.c
+++ b/drivers/net/xen-netfront.c
@@ -291,7 +291,7 @@ static void xennet_alloc_rx_buffers(struct netfront_queue *queue)
 		struct sk_buff *skb;
 		unsigned short id;
 		grant_ref_t ref;
-		unsigned long pfn;
+		unsigned long gfn;
 		struct xen_netif_rx_request *req;
 
 		skb = xennet_alloc_one_rx_buffer(queue);
@@ -307,12 +307,12 @@ static void xennet_alloc_rx_buffers(struct netfront_queue *queue)
 		BUG_ON((signed short)ref < 0);
 		queue->grant_rx_ref[id] = ref;
 
-		pfn = page_to_pfn(skb_frag_page(&skb_shinfo(skb)->frags[0]));
+		gfn = page_to_gfn(skb_frag_page(&skb_shinfo(skb)->frags[0]));
 
 		req = RING_GET_REQUEST(&queue->rx, req_prod);
 		gnttab_grant_foreign_access_ref(ref,
 						queue->info->xbdev->otherend_id,
-						pfn_to_mfn(pfn),
+						gfn,
 						0);
 
 		req->id = id;
@@ -431,7 +431,7 @@ static struct xen_netif_tx_request *xennet_make_one_txreq(
 	BUG_ON((signed short)ref < 0);
 
 	gnttab_grant_foreign_access_ref(ref, queue->info->xbdev->otherend_id,
-					page_to_mfn(page), GNTMAP_readonly);
+					page_to_gfn(page), GNTMAP_readonly);
 
 	queue->tx_skbs[id].skb = skb;
 	queue->grant_tx_page[id] = page;
diff --git a/drivers/scsi/xen-scsifront.c b/drivers/scsi/xen-scsifront.c
index fad22ca..cdf00d1 100644
--- a/drivers/scsi/xen-scsifront.c
+++ b/drivers/scsi/xen-scsifront.c
@@ -377,7 +377,6 @@ static int map_data_for_request(struct vscsifrnt_info *info,
 	unsigned int data_len = scsi_bufflen(sc);
 	unsigned int data_grants = 0, seg_grants = 0;
 	struct scatterlist *sg;
-	unsigned long mfn;
 	struct scsiif_request_segment *seg;
 
 	ring_req->nr_segments = 0;
@@ -420,9 +419,8 @@ static int map_data_for_request(struct vscsifrnt_info *info,
 			ref = gnttab_claim_grant_reference(&gref_head);
 			BUG_ON(ref == -ENOSPC);
 
-			mfn = pfn_to_mfn(page_to_pfn(page));
 			gnttab_grant_foreign_access_ref(ref,
-				info->dev->otherend_id, mfn, 1);
+				info->dev->otherend_id, page_to_gfn(page), 1);
 			shadow->gref[ref_cnt] = ref;
 			ring_req->seg[ref_cnt].gref   = ref;
 			ring_req->seg[ref_cnt].offset = (uint16_t)off;
@@ -454,9 +452,9 @@ static int map_data_for_request(struct vscsifrnt_info *info,
 			ref = gnttab_claim_grant_reference(&gref_head);
 			BUG_ON(ref == -ENOSPC);
 
-			mfn = pfn_to_mfn(page_to_pfn(page));
 			gnttab_grant_foreign_access_ref(ref,
-				info->dev->otherend_id, mfn, grant_ro);
+				info->dev->otherend_id, page_to_gfn(page),
+				grant_ro);
 
 			shadow->gref[ref_cnt] = ref;
 			seg->gref   = ref;
diff --git a/drivers/tty/hvc/hvc_xen.c b/drivers/tty/hvc/hvc_xen.c
index a9d837f..efe5124 100644
--- a/drivers/tty/hvc/hvc_xen.c
+++ b/drivers/tty/hvc/hvc_xen.c
@@ -265,7 +265,8 @@ static int xen_pv_console_init(void)
 		return 0;
 	}
 	info->evtchn = xen_start_info->console.domU.evtchn;
-	info->intf = mfn_to_virt(xen_start_info->console.domU.mfn);
+	/* GFN == MFN for PV guest */
+	info->intf = gfn_to_virt(xen_start_info->console.domU.mfn);
 	info->vtermno = HVC_COOKIE;
 
 	spin_lock(&xencons_lock);
@@ -390,7 +391,7 @@ static int xencons_connect_backend(struct xenbus_device *dev,
 	if (IS_ERR(info->hvc))
 		return PTR_ERR(info->hvc);
 	if (xen_pv_domain())
-		mfn = virt_to_mfn(info->intf);
+		mfn = virt_to_gfn(info->intf);
 	else
 		mfn = __pa(info->intf) >> PAGE_SHIFT;
 	ret = gnttab_alloc_grant_references(1, &gref_head);
diff --git a/drivers/video/fbdev/xen-fbfront.c b/drivers/video/fbdev/xen-fbfront.c
index 09dc447..25e3cce 100644
--- a/drivers/video/fbdev/xen-fbfront.c
+++ b/drivers/video/fbdev/xen-fbfront.c
@@ -539,7 +539,7 @@ static int xenfb_remove(struct xenbus_device *dev)
 
 static unsigned long vmalloc_to_mfn(void *address)
 {
-	return pfn_to_mfn(vmalloc_to_pfn(address));
+	return pfn_to_gfn(vmalloc_to_pfn(address));
 }
 
 static void xenfb_init_shared_page(struct xenfb_info *info,
@@ -586,7 +586,7 @@ static int xenfb_connect_backend(struct xenbus_device *dev,
 		goto unbind_irq;
 	}
 	ret = xenbus_printf(xbt, dev->nodename, "page-ref", "%lu",
-			    virt_to_mfn(info->page));
+			    virt_to_gfn(info->page));
 	if (ret)
 		goto error_xenbus;
 	ret = xenbus_printf(xbt, dev->nodename, "event-channel", "%u",
diff --git a/drivers/xen/balloon.c b/drivers/xen/balloon.c
index bf4a23c..5df28cd 100644
--- a/drivers/xen/balloon.c
+++ b/drivers/xen/balloon.c
@@ -441,7 +441,7 @@ static enum bp_state decrease_reservation(unsigned long nr_pages, gfp_t gfp)
 	/* Update direct mapping, invalidate P2M, and add to balloon. */
 	for (i = 0; i < nr_pages; i++) {
 		pfn = frame_list[i];
-		frame_list[i] = pfn_to_mfn(pfn);
+		frame_list[i] = pfn_to_gfn(pfn);
 		page = pfn_to_page(pfn);
 
 #ifdef CONFIG_XEN_HAVE_PVMMU
diff --git a/drivers/xen/events/events_base.c b/drivers/xen/events/events_base.c
index 1495ecc..10fd9c6 100644
--- a/drivers/xen/events/events_base.c
+++ b/drivers/xen/events/events_base.c
@@ -1694,7 +1694,7 @@ void __init xen_init_IRQ(void)
 		struct physdev_pirq_eoi_gmfn eoi_gmfn;
 
 		pirq_eoi_map = (void *)__get_free_page(GFP_KERNEL|__GFP_ZERO);
-		eoi_gmfn.gmfn = virt_to_mfn(pirq_eoi_map);
+		eoi_gmfn.gmfn = virt_to_gfn(pirq_eoi_map);
 		rc = HYPERVISOR_physdev_op(PHYSDEVOP_pirq_eoi_gmfn_v2, &eoi_gmfn);
 		/* TODO: No PVH support for PIRQ EOI */
 		if (rc != 0) {
diff --git a/drivers/xen/events/events_fifo.c b/drivers/xen/events/events_fifo.c
index 6df8aac..2e55e90 100644
--- a/drivers/xen/events/events_fifo.c
+++ b/drivers/xen/events/events_fifo.c
@@ -111,7 +111,7 @@ static int init_control_block(int cpu,
 	for (i = 0; i < EVTCHN_FIFO_MAX_QUEUES; i++)
 		q->head[i] = 0;
 
-	init_control.control_gfn = virt_to_mfn(control_block);
+	init_control.control_gfn = virt_to_gfn(control_block);
 	init_control.offset      = 0;
 	init_control.vcpu        = cpu;
 
@@ -167,7 +167,7 @@ static int evtchn_fifo_setup(struct irq_info *info)
 		/* Mask all events in this page before adding it. */
 		init_array_page(array_page);
 
-		expand_array.array_gfn = virt_to_mfn(array_page);
+		expand_array.array_gfn = virt_to_gfn(array_page);
 
 		ret = HYPERVISOR_event_channel_op(EVTCHNOP_expand_array, &expand_array);
 		if (ret < 0)
diff --git a/drivers/xen/gntalloc.c b/drivers/xen/gntalloc.c
index e53fe19..13e1458 100644
--- a/drivers/xen/gntalloc.c
+++ b/drivers/xen/gntalloc.c
@@ -142,7 +142,8 @@ static int add_grefs(struct ioctl_gntalloc_alloc_gref *op,
 
 		/* Grant foreign access to the page. */
 		rc = gnttab_grant_foreign_access(op->domid,
-			pfn_to_mfn(page_to_pfn(gref->page)), readonly);
+						 page_to_gfn(gref->page),
+						 readonly);
 		if (rc < 0)
 			goto undo;
 		gref_ids[i] = gref->gref_id = rc;
diff --git a/drivers/xen/manage.c b/drivers/xen/manage.c
index d10effe..e12bd36 100644
--- a/drivers/xen/manage.c
+++ b/drivers/xen/manage.c
@@ -80,7 +80,7 @@ static int xen_suspend(void *data)
 	 * is resuming in a new domain.
 	 */
 	si->cancelled = HYPERVISOR_suspend(xen_pv_domain()
-                                           ? virt_to_mfn(xen_start_info)
+                                           ? virt_to_gfn(xen_start_info)
                                            : 0);
 
 	xen_arch_post_suspend(si->cancelled);
diff --git a/drivers/xen/tmem.c b/drivers/xen/tmem.c
index 239738f..28c97ff 100644
--- a/drivers/xen/tmem.c
+++ b/drivers/xen/tmem.c
@@ -131,7 +131,7 @@ static int xen_tmem_new_pool(struct tmem_pool_uuid uuid,
 static int xen_tmem_put_page(u32 pool_id, struct tmem_oid oid,
 			     u32 index, unsigned long pfn)
 {
-	unsigned long gmfn = xen_pv_domain() ? pfn_to_mfn(pfn) : pfn;
+	unsigned long gmfn = pfn_to_gfn(pfn);
 
 	return xen_tmem_op(TMEM_PUT_PAGE, pool_id, oid, index,
 		gmfn, 0, 0, 0);
@@ -140,7 +140,7 @@ static int xen_tmem_put_page(u32 pool_id, struct tmem_oid oid,
 static int xen_tmem_get_page(u32 pool_id, struct tmem_oid oid,
 			     u32 index, unsigned long pfn)
 {
-	unsigned long gmfn = xen_pv_domain() ? pfn_to_mfn(pfn) : pfn;
+	unsigned long gmfn = pfn_to_gfn(pfn);
 
 	return xen_tmem_op(TMEM_GET_PAGE, pool_id, oid, index,
 		gmfn, 0, 0, 0);
diff --git a/drivers/xen/xenbus/xenbus_client.c b/drivers/xen/xenbus/xenbus_client.c
index 9ad3272..daa267a 100644
--- a/drivers/xen/xenbus/xenbus_client.c
+++ b/drivers/xen/xenbus/xenbus_client.c
@@ -380,7 +380,7 @@ int xenbus_grant_ring(struct xenbus_device *dev, void *vaddr,
 
 	for (i = 0; i < nr_pages; i++) {
 		err = gnttab_grant_foreign_access(dev->otherend_id,
-						  virt_to_mfn(vaddr), 0);
+						  virt_to_gfn(vaddr), 0);
 		if (err < 0) {
 			xenbus_dev_fatal(dev, err,
 					 "granting access to ring page");
diff --git a/drivers/xen/xenbus/xenbus_dev_backend.c b/drivers/xen/xenbus/xenbus_dev_backend.c
index b17707e..ee6d9ef 100644
--- a/drivers/xen/xenbus/xenbus_dev_backend.c
+++ b/drivers/xen/xenbus/xenbus_dev_backend.c
@@ -49,7 +49,7 @@ static long xenbus_alloc(domid_t domid)
 		goto out_err;
 
 	gnttab_grant_foreign_access_ref(GNTTAB_RESERVED_XENSTORE, domid,
-			virt_to_mfn(xen_store_interface), 0 /* writable */);
+			virt_to_gfn(xen_store_interface), 0 /* writable */);
 
 	arg.dom = DOMID_SELF;
 	arg.remote_dom = domid;
diff --git a/drivers/xen/xenbus/xenbus_probe.c b/drivers/xen/xenbus/xenbus_probe.c
index 4308fb3..b3870f4 100644
--- a/drivers/xen/xenbus/xenbus_probe.c
+++ b/drivers/xen/xenbus/xenbus_probe.c
@@ -711,9 +711,7 @@ static int __init xenstored_local_init(void)
 	if (!page)
 		goto out_err;
 
-	xen_store_mfn = xen_start_info->store_mfn =
-		pfn_to_mfn(virt_to_phys((void *)page) >>
-			   PAGE_SHIFT);
+	xen_store_mfn = xen_start_info->store_mfn = virt_to_gfn((void *)page);
 
 	/* Next allocate a local port which xenstored can bind to */
 	alloc_unbound.dom        = DOMID_SELF;
@@ -787,12 +785,12 @@ static int __init xenbus_init(void)
 		err = xenstored_local_init();
 		if (err)
 			goto out_error;
-		xen_store_interface = mfn_to_virt(xen_store_mfn);
+		xen_store_interface = gfn_to_virt(xen_store_mfn);
 		break;
 	case XS_PV:
 		xen_store_evtchn = xen_start_info->store_evtchn;
 		xen_store_mfn = xen_start_info->store_mfn;
-		xen_store_interface = mfn_to_virt(xen_store_mfn);
+		xen_store_interface = gfn_to_virt(xen_store_mfn);
 		break;
 	case XS_HVM:
 		err = hvm_get_parameter(HVM_PARAM_STORE_EVTCHN, &v);
diff --git a/include/xen/page.h b/include/xen/page.h
index c5ed20b..e7e1425 100644
--- a/include/xen/page.h
+++ b/include/xen/page.h
@@ -3,9 +3,9 @@
 
 #include <asm/xen/page.h>
 
-static inline unsigned long page_to_mfn(struct page *page)
+static inline unsigned long page_to_gfn(struct page *page)
 {
-	return pfn_to_mfn(page_to_pfn(page));
+	return pfn_to_gfn(page_to_pfn(page));
 }
 
 struct xen_memory_region {
-- 
2.1.4



From julien.grall at citrix.com  Tue Aug  4 11:12:45 2015
From: julien.grall at citrix.com (Julien Grall)
Date: Tue, 4 Aug 2015 19:12:45 +0100
Subject: [PATCH v2 1/8] arm/xen: Remove helpers which are PV specific
In-Reply-To: <1438711972-18752-1-git-send-email-julien.grall@citrix.com>
References: <1438711972-18752-1-git-send-email-julien.grall@citrix.com>
Message-ID: <1438711972-18752-2-git-send-email-julien.grall@citrix.com>

ARM guests are always HVM. The current implementation is assuming a 1:1
mapping which is only true for DOM0 and may not be at all in the future.

Furthermore, all the helpers but arbitrary_virt_to_machine are used in
x86 specific code (or only compiled for).

The helper arbitrary_virt_to_machine is only used in PV specific code.
Therefore we should never call the function.

Add a BUG() in this helper and drop all the others.

Signed-off-by: Julien Grall <julien.grall at citrix.com>
Acked-by: Stefano Stabellini <stefano.stabellini at eu.citrix.com>
Cc: Russell King <linux at arm.linux.org.uk>
Cc: linux-arm-kernel at lists.infradead.org

---
    Changes in v2:
        - Typoes
        - Add Stefano's acked-by
---
 arch/arm/include/asm/xen/page.h | 16 ++--------------
 1 file changed, 2 insertions(+), 14 deletions(-)

diff --git a/arch/arm/include/asm/xen/page.h b/arch/arm/include/asm/xen/page.h
index 1bee8ca..98b1084 100644
--- a/arch/arm/include/asm/xen/page.h
+++ b/arch/arm/include/asm/xen/page.h
@@ -54,26 +54,14 @@ static inline unsigned long mfn_to_pfn(unsigned long mfn)
 
 #define mfn_to_local_pfn(mfn) mfn_to_pfn(mfn)
 
-static inline xmaddr_t phys_to_machine(xpaddr_t phys)
-{
-	unsigned offset = phys.paddr & ~PAGE_MASK;
-	return XMADDR(PFN_PHYS(pfn_to_mfn(PFN_DOWN(phys.paddr))) | offset);
-}
-
-static inline xpaddr_t machine_to_phys(xmaddr_t machine)
-{
-	unsigned offset = machine.maddr & ~PAGE_MASK;
-	return XPADDR(PFN_PHYS(mfn_to_pfn(PFN_DOWN(machine.maddr))) | offset);
-}
 /* VIRT <-> MACHINE conversion */
-#define virt_to_machine(v)	(phys_to_machine(XPADDR(__pa(v))))
 #define virt_to_mfn(v)		(pfn_to_mfn(virt_to_pfn(v)))
 #define mfn_to_virt(m)		(__va(mfn_to_pfn(m) << PAGE_SHIFT))
 
+/* Only used in PV code. But ARM guests are always HVM. */
 static inline xmaddr_t arbitrary_virt_to_machine(void *vaddr)
 {
-	/* TODO: assuming it is mapped in the kernel 1:1 */
-	return virt_to_machine(vaddr);
+	BUG();
 }
 
 /* TODO: this shouldn't be here but it is because the frontend drivers
-- 
2.1.4



From julien.grall at citrix.com  Tue Aug  4 11:12:52 2015
From: julien.grall at citrix.com (Julien Grall)
Date: Tue, 4 Aug 2015 19:12:52 +0100
Subject: [PATCH v2 8/8] xen/privcmd: Further s/MFN/GFN/ clean-up
In-Reply-To: <1438711972-18752-1-git-send-email-julien.grall@citrix.com>
References: <1438711972-18752-1-git-send-email-julien.grall@citrix.com>
Message-ID: <1438711972-18752-9-git-send-email-julien.grall@citrix.com>

The privcmd code is mixing the usage of GFN and MFN within the same
functions which make the code difficult to understand when you only work
with auto-translated guests.

The privcmd driver is only dealing with GFN so replace all the mention
of MFN into GFN.

The ioctl structure used to map foreign change has been left unchanged
given that the userspace is using it. Nonetheless, add a comment to
explain the expected value within the "mfn" field.

Signed-off-by: Julien Grall <julien.grall at citrix.com>
Reviewed-by: David Vrabel <david.vrabel at citrix.com>
Cc: Stefano Stabellini <stefano.stabellini at eu.citrix.com>
Cc: Russell King <linux at arm.linux.org.uk>
Cc: Konrad Rzeszutek Wilk <konrad.wilk at oracle.com>
Cc: Boris Ostrovsky <boris.ostrovsky at oracle.com>
Cc: Thomas Gleixner <tglx at linutronix.de>
Cc: Ingo Molnar <mingo at redhat.com>
Cc: "H. Peter Anvin" <hpa at zytor.com>
Cc: x86 at kernel.org
Cc: linux-arm-kernel at lists.infradead.org
Cc: linux-api at vger.kernel.org

---
    Changes in v2:
        - Add David's reviewed-by
---
 arch/arm/xen/enlighten.c   | 18 +++++++++---------
 arch/x86/xen/mmu.c         | 32 ++++++++++++++++----------------
 drivers/xen/privcmd.c      | 44 ++++++++++++++++++++++----------------------
 drivers/xen/xlate_mmu.c    | 18 +++++++++---------
 include/uapi/xen/privcmd.h |  4 ++++
 include/xen/xen-ops.h      | 10 +++++-----
 6 files changed, 65 insertions(+), 61 deletions(-)

diff --git a/arch/arm/xen/enlighten.c b/arch/arm/xen/enlighten.c
index 6c09cc4..a8b8806 100644
--- a/arch/arm/xen/enlighten.c
+++ b/arch/arm/xen/enlighten.c
@@ -56,35 +56,35 @@ static __read_mostly unsigned int xen_events_irq;
 
 static __initdata struct device_node *xen_node;
 
-int xen_remap_domain_mfn_array(struct vm_area_struct *vma,
+int xen_remap_domain_gfn_array(struct vm_area_struct *vma,
 			       unsigned long addr,
-			       xen_pfn_t *mfn, int nr,
+			       xen_pfn_t *gfn, int nr,
 			       int *err_ptr, pgprot_t prot,
 			       unsigned domid,
 			       struct page **pages)
 {
-	return xen_xlate_remap_gfn_array(vma, addr, mfn, nr, err_ptr,
+	return xen_xlate_remap_gfn_array(vma, addr, gfn, nr, err_ptr,
 					 prot, domid, pages);
 }
-EXPORT_SYMBOL_GPL(xen_remap_domain_mfn_array);
+EXPORT_SYMBOL_GPL(xen_remap_domain_gfn_array);
 
 /* Not used by XENFEAT_auto_translated guests. */
-int xen_remap_domain_mfn_range(struct vm_area_struct *vma,
+int xen_remap_domain_gfn_range(struct vm_area_struct *vma,
                               unsigned long addr,
-                              xen_pfn_t mfn, int nr,
+                              xen_pfn_t gfn, int nr,
                               pgprot_t prot, unsigned domid,
                               struct page **pages)
 {
 	return -ENOSYS;
 }
-EXPORT_SYMBOL_GPL(xen_remap_domain_mfn_range);
+EXPORT_SYMBOL_GPL(xen_remap_domain_gfn_range);
 
-int xen_unmap_domain_mfn_range(struct vm_area_struct *vma,
+int xen_unmap_domain_gfn_range(struct vm_area_struct *vma,
 			       int nr, struct page **pages)
 {
 	return xen_xlate_unmap_gfn_range(vma, nr, pages);
 }
-EXPORT_SYMBOL_GPL(xen_unmap_domain_mfn_range);
+EXPORT_SYMBOL_GPL(xen_unmap_domain_gfn_range);
 
 static void xen_percpu_init(void)
 {
diff --git a/arch/x86/xen/mmu.c b/arch/x86/xen/mmu.c
index dd151b2..87db1ff 100644
--- a/arch/x86/xen/mmu.c
+++ b/arch/x86/xen/mmu.c
@@ -2465,9 +2465,9 @@ static int remap_area_mfn_pte_fn(pte_t *ptep, pgtable_t token,
 	return 0;
 }
 
-static int do_remap_mfn(struct vm_area_struct *vma,
+static int do_remap_gfn(struct vm_area_struct *vma,
 			unsigned long addr,
-			xen_pfn_t *mfn, int nr,
+			xen_pfn_t *gfn, int nr,
 			int *err_ptr, pgprot_t prot,
 			unsigned domid,
 			struct page **pages)
@@ -2483,14 +2483,14 @@ static int do_remap_mfn(struct vm_area_struct *vma,
 	if (xen_feature(XENFEAT_auto_translated_physmap)) {
 #ifdef CONFIG_XEN_PVH
 		/* We need to update the local page tables and the xen HAP */
-		return xen_xlate_remap_gfn_array(vma, addr, mfn, nr, err_ptr,
+		return xen_xlate_remap_gfn_array(vma, addr, gfn, nr, err_ptr,
 						 prot, domid, pages);
 #else
 		return -EINVAL;
 #endif
         }
 
-	rmd.mfn = mfn;
+	rmd.mfn = gfn;
 	rmd.prot = prot;
 	/* We use the err_ptr to indicate if there we are doing a contigious
 	 * mapping or a discontigious mapping. */
@@ -2518,8 +2518,8 @@ static int do_remap_mfn(struct vm_area_struct *vma,
 						    batch_left, &done, domid);
 
 			/*
-			 * @err_ptr may be the same buffer as @mfn, so
-			 * only clear it after each chunk of @mfn is
+			 * @err_ptr may be the same buffer as @gfn, so
+			 * only clear it after each chunk of @gfn is
 			 * used.
 			 */
 			if (err_ptr) {
@@ -2549,19 +2549,19 @@ out:
 	return err < 0 ? err : mapped;
 }
 
-int xen_remap_domain_mfn_range(struct vm_area_struct *vma,
+int xen_remap_domain_gfn_range(struct vm_area_struct *vma,
 			       unsigned long addr,
-			       xen_pfn_t mfn, int nr,
+			       xen_pfn_t gfn, int nr,
 			       pgprot_t prot, unsigned domid,
 			       struct page **pages)
 {
-	return do_remap_mfn(vma, addr, &mfn, nr, NULL, prot, domid, pages);
+	return do_remap_gfn(vma, addr, &gfn, nr, NULL, prot, domid, pages);
 }
-EXPORT_SYMBOL_GPL(xen_remap_domain_mfn_range);
+EXPORT_SYMBOL_GPL(xen_remap_domain_gfn_range);
 
-int xen_remap_domain_mfn_array(struct vm_area_struct *vma,
+int xen_remap_domain_gfn_array(struct vm_area_struct *vma,
 			       unsigned long addr,
-			       xen_pfn_t *mfn, int nr,
+			       xen_pfn_t *gfn, int nr,
 			       int *err_ptr, pgprot_t prot,
 			       unsigned domid, struct page **pages)
 {
@@ -2570,13 +2570,13 @@ int xen_remap_domain_mfn_array(struct vm_area_struct *vma,
 	 * cause of "wrong memory was mapped in".
 	 */
 	BUG_ON(err_ptr == NULL);
-	return do_remap_mfn(vma, addr, mfn, nr, err_ptr, prot, domid, pages);
+	return do_remap_gfn(vma, addr, gfn, nr, err_ptr, prot, domid, pages);
 }
-EXPORT_SYMBOL_GPL(xen_remap_domain_mfn_array);
+EXPORT_SYMBOL_GPL(xen_remap_domain_gfn_array);
 
 
 /* Returns: 0 success */
-int xen_unmap_domain_mfn_range(struct vm_area_struct *vma,
+int xen_unmap_domain_gfn_range(struct vm_area_struct *vma,
 			       int numpgs, struct page **pages)
 {
 	if (!pages || !xen_feature(XENFEAT_auto_translated_physmap))
@@ -2588,4 +2588,4 @@ int xen_unmap_domain_mfn_range(struct vm_area_struct *vma,
 	return -EINVAL;
 #endif
 }
-EXPORT_SYMBOL_GPL(xen_unmap_domain_mfn_range);
+EXPORT_SYMBOL_GPL(xen_unmap_domain_gfn_range);
diff --git a/drivers/xen/privcmd.c b/drivers/xen/privcmd.c
index 5a29616..c6deb87 100644
--- a/drivers/xen/privcmd.c
+++ b/drivers/xen/privcmd.c
@@ -193,16 +193,16 @@ static int traverse_pages_block(unsigned nelem, size_t size,
 	return ret;
 }
 
-struct mmap_mfn_state {
+struct mmap_gfn_state {
 	unsigned long va;
 	struct vm_area_struct *vma;
 	domid_t domain;
 };
 
-static int mmap_mfn_range(void *data, void *state)
+static int mmap_gfn_range(void *data, void *state)
 {
 	struct privcmd_mmap_entry *msg = data;
-	struct mmap_mfn_state *st = state;
+	struct mmap_gfn_state *st = state;
 	struct vm_area_struct *vma = st->vma;
 	int rc;
 
@@ -216,7 +216,7 @@ static int mmap_mfn_range(void *data, void *state)
 	    ((msg->va+(msg->npages<<PAGE_SHIFT)) > vma->vm_end))
 		return -EINVAL;
 
-	rc = xen_remap_domain_mfn_range(vma,
+	rc = xen_remap_domain_gfn_range(vma,
 					msg->va & PAGE_MASK,
 					msg->mfn, msg->npages,
 					vma->vm_page_prot,
@@ -236,7 +236,7 @@ static long privcmd_ioctl_mmap(void __user *udata)
 	struct vm_area_struct *vma;
 	int rc;
 	LIST_HEAD(pagelist);
-	struct mmap_mfn_state state;
+	struct mmap_gfn_state state;
 
 	/* We only support privcmd_ioctl_mmap_batch for auto translated. */
 	if (xen_feature(XENFEAT_auto_translated_physmap))
@@ -273,7 +273,7 @@ static long privcmd_ioctl_mmap(void __user *udata)
 
 	rc = traverse_pages(mmapcmd.num, sizeof(struct privcmd_mmap_entry),
 			    &pagelist,
-			    mmap_mfn_range, &state);
+			    mmap_gfn_range, &state);
 
 
 out_up:
@@ -299,18 +299,18 @@ struct mmap_batch_state {
 	int global_error;
 	int version;
 
-	/* User-space mfn array to store errors in the second pass for V1. */
-	xen_pfn_t __user *user_mfn;
+	/* User-space gfn array to store errors in the second pass for V1. */
+	xen_pfn_t __user *user_gfn;
 	/* User-space int array to store errors in the second pass for V2. */
 	int __user *user_err;
 };
 
-/* auto translated dom0 note: if domU being created is PV, then mfn is
- * mfn(addr on bus). If it's auto xlated, then mfn is pfn (input to HAP).
+/* auto translated dom0 note: if domU being created is PV, then gfn is
+ * mfn(addr on bus). If it's auto xlated, then gfn is pfn (input to HAP).
  */
 static int mmap_batch_fn(void *data, int nr, void *state)
 {
-	xen_pfn_t *mfnp = data;
+	xen_pfn_t *gfnp = data;
 	struct mmap_batch_state *st = state;
 	struct vm_area_struct *vma = st->vma;
 	struct page **pages = vma->vm_private_data;
@@ -321,8 +321,8 @@ static int mmap_batch_fn(void *data, int nr, void *state)
 		cur_pages = &pages[st->index];
 
 	BUG_ON(nr < 0);
-	ret = xen_remap_domain_mfn_array(st->vma, st->va & PAGE_MASK, mfnp, nr,
-					 (int *)mfnp, st->vma->vm_page_prot,
+	ret = xen_remap_domain_gfn_array(st->vma, st->va & PAGE_MASK, gfnp, nr,
+					 (int *)gfnp, st->vma->vm_page_prot,
 					 st->domain, cur_pages);
 
 	/* Adjust the global_error? */
@@ -347,22 +347,22 @@ static int mmap_return_error(int err, struct mmap_batch_state *st)
 
 	if (st->version == 1) {
 		if (err) {
-			xen_pfn_t mfn;
+			xen_pfn_t gfn;
 
-			ret = get_user(mfn, st->user_mfn);
+			ret = get_user(gfn, st->user_gfn);
 			if (ret < 0)
 				return ret;
 			/*
 			 * V1 encodes the error codes in the 32bit top
-			 * nibble of the mfn (with its known
+			 * nibble of the gfn (with its known
 			 * limitations vis-a-vis 64 bit callers).
 			 */
-			mfn |= (err == -ENOENT) ?
+			gfn |= (err == -ENOENT) ?
 				PRIVCMD_MMAPBATCH_PAGED_ERROR :
 				PRIVCMD_MMAPBATCH_MFN_ERROR;
-			return __put_user(mfn, st->user_mfn++);
+			return __put_user(gfn, st->user_gfn++);
 		} else
-			st->user_mfn++;
+			st->user_gfn++;
 	} else { /* st->version == 2 */
 		if (err)
 			return __put_user(err, st->user_err++);
@@ -388,7 +388,7 @@ static int mmap_return_errors(void *data, int nr, void *state)
 	return 0;
 }
 
-/* Allocate pfns that are then mapped with gmfns from foreign domid. Update
+/* Allocate pfns that are then mapped with gfns from foreign domid. Update
  * the vma with the page info to use later.
  * Returns: 0 if success, otherwise -errno
  */
@@ -526,7 +526,7 @@ static long privcmd_ioctl_mmap_batch(void __user *udata, int version)
 
 	if (state.global_error) {
 		/* Write back errors in second pass. */
-		state.user_mfn = (xen_pfn_t *)m.arr;
+		state.user_gfn = (xen_pfn_t *)m.arr;
 		state.user_err = m.err;
 		ret = traverse_pages_block(m.num, sizeof(xen_pfn_t),
 					   &pagelist, mmap_return_errors, &state);
@@ -587,7 +587,7 @@ static void privcmd_close(struct vm_area_struct *vma)
 	if (!xen_feature(XENFEAT_auto_translated_physmap) || !numpgs || !pages)
 		return;
 
-	rc = xen_unmap_domain_mfn_range(vma, numpgs, pages);
+	rc = xen_unmap_domain_gfn_range(vma, numpgs, pages);
 	if (rc == 0)
 		free_xenballooned_pages(numpgs, pages);
 	else
diff --git a/drivers/xen/xlate_mmu.c b/drivers/xen/xlate_mmu.c
index 58a5389..cff2387 100644
--- a/drivers/xen/xlate_mmu.c
+++ b/drivers/xen/xlate_mmu.c
@@ -38,8 +38,8 @@
 #include <xen/interface/xen.h>
 #include <xen/interface/memory.h>
 
-/* map fgmfn of domid to lpfn in the current domain */
-static int map_foreign_page(unsigned long lpfn, unsigned long fgmfn,
+/* map fgfn of domid to lpfn in the current domain */
+static int map_foreign_page(unsigned long lpfn, unsigned long fgfn,
 			    unsigned int domid)
 {
 	int rc;
@@ -49,7 +49,7 @@ static int map_foreign_page(unsigned long lpfn, unsigned long fgmfn,
 		.size = 1,
 		.space = XENMAPSPACE_gmfn_foreign,
 	};
-	xen_ulong_t idx = fgmfn;
+	xen_ulong_t idx = fgfn;
 	xen_pfn_t gpfn = lpfn;
 	int err = 0;
 
@@ -62,13 +62,13 @@ static int map_foreign_page(unsigned long lpfn, unsigned long fgmfn,
 }
 
 struct remap_data {
-	xen_pfn_t *fgmfn; /* foreign domain's gmfn */
+	xen_pfn_t *fgfn; /* foreign domain's gfn */
 	pgprot_t prot;
 	domid_t  domid;
 	struct vm_area_struct *vma;
 	int index;
 	struct page **pages;
-	struct xen_remap_mfn_info *info;
+	struct xen_remap_gfn_info *info;
 	int *err_ptr;
 	int mapped;
 };
@@ -82,20 +82,20 @@ static int remap_pte_fn(pte_t *ptep, pgtable_t token, unsigned long addr,
 	pte_t pte = pte_mkspecial(pfn_pte(pfn, info->prot));
 	int rc;
 
-	rc = map_foreign_page(pfn, *info->fgmfn, info->domid);
+	rc = map_foreign_page(pfn, *info->fgfn, info->domid);
 	*info->err_ptr++ = rc;
 	if (!rc) {
 		set_pte_at(info->vma->vm_mm, addr, ptep, pte);
 		info->mapped++;
 	}
-	info->fgmfn++;
+	info->fgfn++;
 
 	return 0;
 }
 
 int xen_xlate_remap_gfn_array(struct vm_area_struct *vma,
 			      unsigned long addr,
-			      xen_pfn_t *mfn, int nr,
+			      xen_pfn_t *gfn, int nr,
 			      int *err_ptr, pgprot_t prot,
 			      unsigned domid,
 			      struct page **pages)
@@ -108,7 +108,7 @@ int xen_xlate_remap_gfn_array(struct vm_area_struct *vma,
 	   x86 PVOPS */
 	BUG_ON(!((vma->vm_flags & (VM_PFNMAP | VM_IO)) == (VM_PFNMAP | VM_IO)));
 
-	data.fgmfn = mfn;
+	data.fgfn = gfn;
 	data.prot  = prot;
 	data.domid = domid;
 	data.vma   = vma;
diff --git a/include/uapi/xen/privcmd.h b/include/uapi/xen/privcmd.h
index a853168..7ddeeda 100644
--- a/include/uapi/xen/privcmd.h
+++ b/include/uapi/xen/privcmd.h
@@ -44,6 +44,10 @@ struct privcmd_hypercall {
 
 struct privcmd_mmap_entry {
 	__u64 va;
+	/*
+	 * This should be a GFN. It's not possible to change the name because
+	 * it's exposed to the user-space.
+	 */
 	__u64 mfn;
 	__u64 npages;
 };
diff --git a/include/xen/xen-ops.h b/include/xen/xen-ops.h
index 0ce4f32..e4e214a 100644
--- a/include/xen/xen-ops.h
+++ b/include/xen/xen-ops.h
@@ -30,7 +30,7 @@ void xen_destroy_contiguous_region(phys_addr_t pstart, unsigned int order);
 struct vm_area_struct;
 
 /*
- * xen_remap_domain_mfn_array() - map an array of foreign frames
+ * xen_remap_domain_gfn_array() - map an array of foreign frames
  * @vma:     VMA to map the pages into
  * @addr:    Address at which to map the pages
  * @gfn:     Array of GFNs to map
@@ -46,14 +46,14 @@ struct vm_area_struct;
  * Returns the number of successfully mapped frames, or a -ve error
  * code.
  */
-int xen_remap_domain_mfn_array(struct vm_area_struct *vma,
+int xen_remap_domain_gfn_array(struct vm_area_struct *vma,
 			       unsigned long addr,
 			       xen_pfn_t *gfn, int nr,
 			       int *err_ptr, pgprot_t prot,
 			       unsigned domid,
 			       struct page **pages);
 
-/* xen_remap_domain_mfn_range() - map a range of foreign frames
+/* xen_remap_domain_gfn_range() - map a range of foreign frames
  * @vma:     VMA to map the pages into
  * @addr:    Address at which to map the pages
  * @gfn:     First GFN to map.
@@ -65,12 +65,12 @@ int xen_remap_domain_mfn_array(struct vm_area_struct *vma,
  * Returns the number of successfully mapped frames, or a -ve error
  * code.
  */
-int xen_remap_domain_mfn_range(struct vm_area_struct *vma,
+int xen_remap_domain_gfn_range(struct vm_area_struct *vma,
 			       unsigned long addr,
 			       xen_pfn_t gfn, int nr,
 			       pgprot_t prot, unsigned domid,
 			       struct page **pages);
-int xen_unmap_domain_mfn_range(struct vm_area_struct *vma,
+int xen_unmap_domain_gfn_range(struct vm_area_struct *vma,
 			       int numpgs, struct page **pages);
 int xen_xlate_remap_gfn_array(struct vm_area_struct *vma,
 			      unsigned long addr,
-- 
2.1.4



From adam.yh.lee at gmail.com  Tue Aug  4 11:15:47 2015
From: adam.yh.lee at gmail.com (Adam YH Lee)
Date: Tue,  4 Aug 2015 11:15:47 -0700
Subject: [V4] [TWL4030 MADC] Correction and clean-up
Message-ID: <1438712148-27004-1-git-send-email-adam.yh.lee@gmail.com>

The V4 of this patch addresses issues raised by Jonathan [1].

"iio_device_register" call should be the last call in the probe.
All regulators should be configured before that call.

Remove devm_regulator_put as it is not necessary. "devm_allocators"
(devm_regulator_get, in this case) does device removal as well as error
handling.

[1] http://www.spinics.net/lists/linux-omap/msg120871.html

Adam YH Lee (1):
  [TWL4030 MADC] Fix ADC[3:6] readings

 drivers/iio/adc/twl4030-madc.c | 34 ++++++++++++++++++++++++++++++++++
 1 file changed, 34 insertions(+)

-- 
2.1.4



From adam.yh.lee at gmail.com  Tue Aug  4 11:15:48 2015
From: adam.yh.lee at gmail.com (Adam YH Lee)
Date: Tue,  4 Aug 2015 11:15:48 -0700
Subject: [V4] [TWL4030 MADC] Fix ADC[3:6] readings
In-Reply-To: <1438712148-27004-1-git-send-email-adam.yh.lee@gmail.com>
References: <1438712148-27004-1-git-send-email-adam.yh.lee@gmail.com>
Message-ID: <1438712148-27004-2-git-send-email-adam.yh.lee@gmail.com>

MADC[3:6] reads incorrect values without these two following changes:

- enable the 3v1 bias regulator for ADC[3:6]
- configure ADC[3:6] lines as input, not as USB

Signed-off-by: Adam YH Lee <adam.yh.lee at gmail.com>
---
 drivers/iio/adc/twl4030-madc.c | 34 ++++++++++++++++++++++++++++++++++
 1 file changed, 34 insertions(+)

diff --git a/drivers/iio/adc/twl4030-madc.c b/drivers/iio/adc/twl4030-madc.c
index 94c5f05..8c58498 100644
--- a/drivers/iio/adc/twl4030-madc.c
+++ b/drivers/iio/adc/twl4030-madc.c
@@ -45,13 +45,18 @@
 #include <linux/types.h>
 #include <linux/gfp.h>
 #include <linux/err.h>
+#include <linux/regulator/consumer.h>
 
 #include <linux/iio/iio.h>
 
+#define TWL4030_USB_SEL_MADC_MCPC	(1<<3)
+#define TWL4030_USB_CARKIT_ANA_CTRL	0xBB
+
 /**
  * struct twl4030_madc_data - a container for madc info
  * @dev:		Pointer to device structure for madc
  * @lock:		Mutex protecting this data structure
+ * @regulator:		Pointer to bias regulator for madc
  * @requests:		Array of request struct corresponding to SW1, SW2 and RT
  * @use_second_irq:	IRQ selection (main or co-processor)
  * @imr:		Interrupt mask register of MADC
@@ -60,6 +65,7 @@
 struct twl4030_madc_data {
 	struct device *dev;
 	struct mutex lock;	/* mutex protecting this data structure */
+	struct regulator *usb3v1;
 	struct twl4030_madc_request requests[TWL4030_MADC_NUM_METHODS];
 	bool use_second_irq;
 	u8 imr;
@@ -842,6 +848,32 @@ static int twl4030_madc_probe(struct platform_device *pdev)
 	}
 	twl4030_madc = madc;
 
+	/* Configure MADC[3:6] */
+	ret = twl_i2c_read_u8(TWL_MODULE_USB, &regval,
+			TWL4030_USB_CARKIT_ANA_CTRL);
+	if (ret) {
+		dev_err(&pdev->dev, "unable to read reg CARKIT_ANA_CTRL  0x%X\n",
+				TWL4030_USB_CARKIT_ANA_CTRL);
+		goto err_i2c;
+	}
+	regval |= TWL4030_USB_SEL_MADC_MCPC;
+	ret = twl_i2c_write_u8(TWL_MODULE_USB, regval,
+				 TWL4030_USB_CARKIT_ANA_CTRL);
+	if (ret) {
+		dev_err(&pdev->dev, "unable to write reg CARKIT_ANA_CTRL 0x%X\n",
+				TWL4030_USB_CARKIT_ANA_CTRL);
+		goto err_i2c;
+	}
+
+	/* Enable 3v1 bias regulator for MADC[3:6] */
+	madc->usb3v1 = devm_regulator_get(madc->dev, "vusb3v1");
+	if (IS_ERR(madc->usb3v1))
+		return -ENODEV;
+
+	ret = regulator_enable(madc->usb3v1);
+	if (ret)
+		dev_err(madc->dev, "could not enable 3v1 bias regulator\n");
+
 	ret = iio_device_register(iio_dev);
 	if (ret) {
 		dev_err(&pdev->dev, "could not register iio device\n");
@@ -867,6 +899,8 @@ static int twl4030_madc_remove(struct platform_device *pdev)
 	twl4030_madc_set_current_generator(madc, 0, 0);
 	twl4030_madc_set_power(madc, 0);
 
+	regulator_disable(madc->usb3v1);
+
 	return 0;
 }
 
-- 
2.1.4



From adam.yh.lee at gmail.com  Tue Aug  4 11:19:25 2015
From: adam.yh.lee at gmail.com (Adam Lee)
Date: Tue, 4 Aug 2015 11:19:25 -0700
Subject: [V3] [TWL4030 MADC] Fix ADC[3:6] readings
In-Reply-To: <55BE4B75.9090708@kernel.org>
References: <1437439755-30618-1-git-send-email-adam.yh.lee@gmail.com>
 <55BE4B75.9090708@kernel.org>
Message-ID: <CAFeBWL7myKYF6wROibHNtZ+eT4eoFp6C0meCA3P0sttoPxyJqw@mail.gmail.com>

Hello Jonathan, thanks for your comment.

Just submitted V4 with corrections:

1. regulator configuration is now done before iio_device_register
2. devm_regulator_put has been removed as it is not necessary

Let me know!

Adam

On Sun, Aug 2, 2015 at 9:55 AM, Jonathan Cameron <jic23 at kernel.org> wrote:
> On 21/07/15 01:49, Adam YH Lee wrote:
>> MADC[3:6] reads incorrect values without these two following changes:
>>
>> - enable the 3v1 bias regulator for ADC[3:6]
>> - configure ADC[3:6] lines as input, not as USB
>>
>> Signed-off-by: Adam YH Lee <adam.yh.lee at gmail.com>
>> ---
>>  drivers/iio/adc/twl4030-madc.c | 36 ++++++++++++++++++++++++++++++++++++
>>  1 file changed, 36 insertions(+)
>>
>> diff --git a/drivers/iio/adc/twl4030-madc.c b/drivers/iio/adc/twl4030-madc.c
>> index 94c5f05..ae33eba 100644
>> --- a/drivers/iio/adc/twl4030-madc.c
>> +++ b/drivers/iio/adc/twl4030-madc.c
>> @@ -45,13 +45,18 @@
>>  #include <linux/types.h>
>>  #include <linux/gfp.h>
>>  #include <linux/err.h>
>> +#include <linux/regulator/consumer.h>
>>
>>  #include <linux/iio/iio.h>
>>
>> +#define TWL4030_USB_SEL_MADC_MCPC    (1<<3)
>> +#define TWL4030_USB_CARKIT_ANA_CTRL  0xBB
>> +
>>  /**
>>   * struct twl4030_madc_data - a container for madc info
>>   * @dev:             Pointer to device structure for madc
>>   * @lock:            Mutex protecting this data structure
>> + * @regulator:               Pointer to bias regulator for madc
>>   * @requests:                Array of request struct corresponding to SW1, SW2 and RT
>>   * @use_second_irq:  IRQ selection (main or co-processor)
>>   * @imr:             Interrupt mask register of MADC
>> @@ -60,6 +65,7 @@
>>  struct twl4030_madc_data {
>>       struct device *dev;
>>       struct mutex lock;      /* mutex protecting this data structure */
>> +     struct regulator *usb3v1;
>>       struct twl4030_madc_request requests[TWL4030_MADC_NUM_METHODS];
>>       bool use_second_irq;
>>       u8 imr;
>> @@ -848,6 +854,33 @@ static int twl4030_madc_probe(struct platform_device *pdev)
>>               goto err_i2c;
>>       }
>>
> At this point in the driver the userspace (an in kernel) interfaces to read
> from the device are exposed. Thus if you need this stuff set up right, it
> wants to be done before the iio_device_register call.
>> +     /* Configure MADC[3:6] */
>> +     ret = twl_i2c_read_u8(TWL_MODULE_USB, &regval,
>> +                     TWL4030_USB_CARKIT_ANA_CTRL);
>> +     if (ret) {
>> +             dev_err(&pdev->dev, "unable to read reg CARKIT_ANA_CTRL  0x%X\n",
>> +                             TWL4030_USB_CARKIT_ANA_CTRL);
>> +             goto err_i2c;
>> +     }
>> +     regval |= TWL4030_USB_SEL_MADC_MCPC;
>> +     ret = twl_i2c_write_u8(TWL_MODULE_USB, regval,
>> +                              TWL4030_USB_CARKIT_ANA_CTRL);
>> +     if (ret) {
>> +             dev_err(&pdev->dev, "unable to write reg CARKIT_ANA_CTRL 0x%X\n",
>> +                             TWL4030_USB_CARKIT_ANA_CTRL);
>> +             goto err_i2c;
>> +     }
>> +
>> +
>> +     /* Enable 3v1 bias regulator for MADC[3:6] */
>> +     madc->usb3v1 = devm_regulator_get(madc->dev, "vusb3v1");
>> +     if (IS_ERR(madc->usb3v1))
>> +             return -ENODEV;
>> +
>> +     ret = regulator_enable(madc->usb3v1);
>> +     if (ret)
>> +             dev_err(madc->dev, "could not enable 3v1 bias regulator\n");
>> +
>>       return 0;
>>
>>  err_i2c:
>> @@ -867,6 +900,9 @@ static int twl4030_madc_remove(struct platform_device *pdev)
>>       twl4030_madc_set_current_generator(madc, 0, 0);
>>       twl4030_madc_set_power(madc, 0);
>>
>> +     regulator_disable(madc->usb3v1);
>> +     devm_regulator_put(madc->usb3v1);
> The whole point of devm_ allocators (or in this case _gets) is that when
> the driver is removed they are cleaned up automatically.  Hence you don't
> need them in your remove call.  Obviously it also clears up the error
> handling in probe as well.
>> +
>>       return 0;
>>  }
>>
>>
>


From balbi at ti.com  Tue Aug  4 11:30:59 2015
From: balbi at ti.com (Felipe Balbi)
Date: Tue, 4 Aug 2015 13:30:59 -0500
Subject: [PATCH v5 40/46] usb: gadget: epautoconf: rework ep_matches()
 function
In-Reply-To: <1438351258-31578-41-git-send-email-r.baldyga@samsung.com>
References: <1438351258-31578-1-git-send-email-r.baldyga@samsung.com>
 <1438351258-31578-41-git-send-email-r.baldyga@samsung.com>
Message-ID: <20150804183059.GC9623@saruman.tx.rr.com>

On Fri, Jul 31, 2015 at 04:00:52PM +0200, Robert Baldyga wrote:
> Rework ep_matches() function to make it shorter and more readable.
> 
> Signed-off-by: Robert Baldyga <r.baldyga at samsung.com>

this regresses at least mass storage. How did you test it ? I'll keep
all patches up to this one, please fix the problem, rebase on
testing/next and resend the remaining patches.

cheers

-- 
balbi
-------------- next part --------------
A non-text attachment was scrubbed...
Name: signature.asc
Type: application/pgp-signature
Size: 819 bytes
Desc: Digital signature
URL: <http://lists.infradead.org/pipermail/linux-arm-kernel/attachments/20150804/640cca5b/attachment.sig>

From agross at codeaurora.org  Tue Aug  4 11:48:22 2015
From: agross at codeaurora.org (Andy Gross)
Date: Tue, 4 Aug 2015 13:48:22 -0500
Subject: [PATCH 02/18] firmware: qcom_scm-32: replace open-coded call to
 __cpuc_flush_dcache_area()
In-Reply-To: <E1ZJhWZ-00043Z-Ft@rmk-PC.arm.linux.org.uk>
References: <20150727122824.GH7557@n2100.arm.linux.org.uk>
 <E1ZJhWZ-00043Z-Ft@rmk-PC.arm.linux.org.uk>
Message-ID: <20150804184822.GA10826@qualcomm.com>

On Mon, Jul 27, 2015 at 01:28:55PM +0100, Russell King wrote:
> Signed-off-by: Russell King <rmk+kernel at arm.linux.org.uk>
> ---

Acked-by: Andy Gross <agross at codeaurora.org>

-- 
Qualcomm Innovation Center, Inc.
The Qualcomm Innovation Center, Inc. is a member of the Code Aurora Forum,
a Linux Foundation Collaborative Project



From sboyd at codeaurora.org  Tue Aug  4 11:50:56 2015
From: sboyd at codeaurora.org (Stephen Boyd)
Date: Tue, 04 Aug 2015 11:50:56 -0700
Subject: [PATCH 02/18] firmware: qcom_scm-32: replace open-coded call
 to __cpuc_flush_dcache_area()
In-Reply-To: <E1ZJhWZ-00043Z-Ft@rmk-PC.arm.linux.org.uk>
References: <20150727122824.GH7557@n2100.arm.linux.org.uk>
 <E1ZJhWZ-00043Z-Ft@rmk-PC.arm.linux.org.uk>
Message-ID: <55C10990.3090707@codeaurora.org>

On 07/27/2015 05:28 AM, Russell King wrote:
> Signed-off-by: Russell King <rmk+kernel at arm.linux.org.uk>
> ---

Thanks!

Reviewed-by: Stephen Boyd <sboyd at codeaurora.org>

>   arch/arm/include/asm/cacheflush.h | 17 +++++++++++++++++
>   drivers/firmware/qcom_scm-32.c    |  4 +---
>   2 files changed, 18 insertions(+), 3 deletions(-)
>
> diff --git a/arch/arm/include/asm/cacheflush.h b/arch/arm/include/asm/cacheflush.h
> index c5230a44eeca..d5525bfc7e3e 100644
> --- a/arch/arm/include/asm/cacheflush.h
> +++ b/arch/arm/include/asm/cacheflush.h
> @@ -502,4 +502,21 @@ static inline void set_kernel_text_ro(void) { }
>   void flush_uprobe_xol_access(struct page *page, unsigned long uaddr,
>   			     void *kaddr, unsigned long len);
>   
> +/**
> + * secure_flush_area - ensure coherency across the secure boundary
> + * @addr: virtual address
> + * @size: size of region
> + *
> + * Ensure that the specified area of memory is coherent across the secure
> + * boundary from the non-secure side.  This is used when calling secure
> + * firmware where the secure firmware does not ensure coherency.
> + */
> +static inline void secure_flush_area(const void *addr, size_t size)
> +{
> +	phys_addr_t phys = __pa(addr);
> +
> +	__cpuc_flush_dcache_area((void *)addr, size);
> +	outer_flush_range(phys, phys + size);
> +}
> +
>   #endif
> diff --git a/drivers/firmware/qcom_scm-32.c b/drivers/firmware/qcom_scm-32.c
> index 1bd6f9c34331..29e6850665eb 100644
> --- a/drivers/firmware/qcom_scm-32.c
> +++ b/drivers/firmware/qcom_scm-32.c
> @@ -24,7 +24,6 @@
>   #include <linux/err.h>
>   #include <linux/qcom_scm.h>
>   
> -#include <asm/outercache.h>
>   #include <asm/cacheflush.h>
>   
>   #include "qcom_scm.h"
> @@ -219,8 +218,7 @@ static int __qcom_scm_call(const struct qcom_scm_command *cmd)
>   	 * Flush the command buffer so that the secure world sees
>   	 * the correct data.
>   	 */
> -	__cpuc_flush_dcache_area((void *)cmd, cmd->len);
> -	outer_flush_range(cmd_addr, cmd_addr + cmd->len);
> +	secure_flush_area(cmd, cmd->len);
>   
>   	ret = smc(cmd_addr);
>   	if (ret < 0)

-- 
Qualcomm Innovation Center, Inc. is a member of Code Aurora Forum,
a Linux Foundation Collaborative Project



From will.deacon at arm.com  Tue Aug  4 12:03:33 2015
From: will.deacon at arm.com (Will Deacon)
Date: Tue,  4 Aug 2015 20:03:33 +0100
Subject: [PATCH] arm64: mm: ensure patched kernel text is fetched from PoC
Message-ID: <1438715013-4625-1-git-send-email-will.deacon@arm.com>

The arm64 booting document requires that the bootloader has cleaned the
kernel image to the PoC. However, when a CPU re-enters the kernel due to
either a CPU hotplug "on" event or resuming from a low-power state (e.g.
cpuidle), the kernel text may in-fact be dirty at the PoU due to things
like alternative patching or even module loading.

Thanks to I-cache speculation with the MMU off, stale instructions could
be fetched prior to enabling the MMU, potentially leading to crashes
when executing regions of code that have been modified at runtime.

This patch addresses the issue by ensuring that the local I-cache is
invalidated immediately after a CPU has enabled its MMU but before
jumping out of the identity mapping. Any stale instructions fetched from
the PoC will then be discarded and refetched correctly from the PoU.

Tested-by: Mark Rutland <mark.rutland at arm.com>
Signed-off-by: Will Deacon <will.deacon at arm.com>
---
 arch/arm64/kernel/head.S  | 8 ++++++++
 arch/arm64/kernel/sleep.S | 8 ++++++++
 arch/arm64/mm/proc.S      | 1 -
 3 files changed, 16 insertions(+), 1 deletion(-)

diff --git a/arch/arm64/kernel/head.S b/arch/arm64/kernel/head.S
index 3a0654173997..a055be6125cf 100644
--- a/arch/arm64/kernel/head.S
+++ b/arch/arm64/kernel/head.S
@@ -634,5 +634,13 @@ __enable_mmu:
 	isb
 	msr	sctlr_el1, x0
 	isb
+	/*
+	 * Invalidate the local I-cache so that any instructions fetched
+	 * speculatively from the PoC are discarded, since they may have
+	 * been dynamically patched at the PoU.
+	 */
+	ic	iallu
+	dsb	nsh
+	isb
 	br	x27
 ENDPROC(__enable_mmu)
diff --git a/arch/arm64/kernel/sleep.S b/arch/arm64/kernel/sleep.S
index 5686a3ae3940..38d37c539a30 100644
--- a/arch/arm64/kernel/sleep.S
+++ b/arch/arm64/kernel/sleep.S
@@ -133,6 +133,14 @@ ENTRY(cpu_resume_mmu)
 	ldr	x3, =cpu_resume_after_mmu
 	msr	sctlr_el1, x0		// restore sctlr_el1
 	isb
+	/*
+	 * Invalidate the local I-cache so that any instructions fetched
+	 * speculatively from the PoC are discarded, since they may have
+	 * been dynamically patched at the PoU.
+	 */
+	ic	iallu
+	dsb	nsh
+	isb
 	br	x3			// global jump to virtual address
 ENDPROC(cpu_resume_mmu)
 	.popsection
diff --git a/arch/arm64/mm/proc.S b/arch/arm64/mm/proc.S
index eff4f627358a..716c673cbd8e 100644
--- a/arch/arm64/mm/proc.S
+++ b/arch/arm64/mm/proc.S
@@ -146,7 +146,6 @@ ENDPROC(cpu_do_switch_mm)
  *	value of the SCTLR_EL1 register.
  */
 ENTRY(__cpu_setup)
-	ic	iallu				// I+BTB cache invalidate
 	tlbi	vmalle1is			// invalidate I + D TLBs
 	dsb	ish
 
-- 
2.1.4



From matthias.bgg at gmail.com  Tue Aug  4 12:12:54 2015
From: matthias.bgg at gmail.com (Matthias Brugger)
Date: Tue, 04 Aug 2015 21:12:54 +0200
Subject: next-20150729 build: 2 failures 49 warnings (next-20150729)
In-Reply-To: <20150804173849.GD20873@sirena.org.uk>
References: <E1ZKPJk-0007VU-Fg@optimist>
 <20150729124410.GE20130@sirena.org.uk> <20150804173849.GD20873@sirena.org.uk>
Message-ID: <17C303E7-B358-486E-9E0F-83CF58F28481@gmail.com>



On August 4, 2015 7:38:49 PM CEST, Mark Brown <broonie at kernel.org> wrote:
>On Wed, Jul 29, 2015 at 01:44:10PM +0100, Mark Brown wrote:
>> On Wed, Jul 29, 2015 at 12:14:36PM +0100, Build bot for Mark Brown
>wrote:
>
>> Today's linux-next fails to build an arm64 allmodconfig due to:
>
>> > 	arm64-allmodconfig
>> > ../include/linux/platform_device.h:245:1: error: type defaults to
>'int' in declaration of 'module_init' [-Werror=implicit-int]
>> > ../include/linux/platform_device.h:250:1: error: type defaults to
>'int' in declaration of 'module_exit' [-Werror=implicit-int]
>
>> caused by c84e358718a66f76 (soc: Mediatek: Add SCPSYS power domain
>> driver) which does not include module.h.  Arguably platform_device.h
>> should do that, though it's only an issue if the macro is used so...
>
>This is still breaking the build and the fix should be trivial - is
>there any ETA for a fix getting into -next?

I send a fix to arm at kernel.org but no reply yet. (sorry I'm not in front of a computer so I can't send you the link right now).

I will send a pull request tomorrow, let's see if that helps...

Matthias



From santosh.shilimkar at oracle.com  Tue Aug  4 12:14:53 2015
From: santosh.shilimkar at oracle.com (santosh shilimkar)
Date: Tue, 4 Aug 2015 12:14:53 -0700
Subject: [Resend: PATCH] ARM: keystone: add documentation for SoCs and EVMs
In-Reply-To: <1438706203-3748-1-git-send-email-m-karicheri2@ti.com>
References: <1438706203-3748-1-git-send-email-m-karicheri2@ti.com>
Message-ID: <55C10F2D.9050805@oracle.com>

On 8/4/2015 9:36 AM, Murali Karicheri wrote:
> Currently there is no general documentation on Keystone SoCs in the
> Linux Documentation folder of the source tree. This patch adds some
> essential documentation with links to help users of Keystone Linux and
> also provide links to existing documents where necessary.
>
> Signed-off-by: Murali Karicheri <m-karicheri2 at ti.com>
> ---
Good writeup Murali. This will be handy.
I can queue this up via arm-soc for 4.3 if the doc maintainers are
happy with it.

Thanks !!

Regards,
Santosh


From ijc at hellion.org.uk  Tue Aug  4 12:25:55 2015
From: ijc at hellion.org.uk (Ian Campbell)
Date: Tue,  4 Aug 2015 20:25:55 +0100
Subject: [PATCH net] net: thunderx: remove effective "default y" from Kconfig
 if ARCH_THUNDER=y
Message-ID: <1438716355-11515-1-git-send-email-ijc@hellion.org.uk>

As well as for kernels built only for ThunderX ARCH_THUNDERX is also enabled
for kernels which support multiple platforms (such as distro kernels). Thus
"default ARCH_THUNDER" is inappropriate.

I believe default m is equally frowned upon, so remove the line completely
rather than "default m if ARCH_THUNDER".

Signed-off-by: Ian Campbell <ijc at hellion.org.uk>
Cc: Sunil Goutham <sgoutham at cavium.com>
Cc: Robert Richter <rric at kernel.org>
Cc: Derek Chickles <derek.chickles at caviumnetworks.com>
Cc: Satanand Burla <satananda.burla at caviumnetworks.com>
Cc: Felix Manlunas <felix.manlunas at caviumnetworks.com>
Cc: Raghu Vatsavayi <raghu.vatsavayi at caviumnetworks.com>
Cc: Arnd Bergmann <arnd at arndb.de>
Cc: linux-arm-kernel at lists.infradead.org
Cc: netdev at vger.kernel.org
Cc: linux-kernel at vger.kernel.org
---
 drivers/net/ethernet/cavium/Kconfig | 3 ---
 1 file changed, 3 deletions(-)

diff --git a/drivers/net/ethernet/cavium/Kconfig b/drivers/net/ethernet/cavium/Kconfig
index 3584420..9b35d14 100644
--- a/drivers/net/ethernet/cavium/Kconfig
+++ b/drivers/net/ethernet/cavium/Kconfig
@@ -16,7 +16,6 @@ if NET_VENDOR_CAVIUM
 config THUNDER_NIC_PF
 	tristate "Thunder Physical function driver"
 	depends on 64BIT
-	default ARCH_THUNDER
 	select THUNDER_NIC_BGX
 	---help---
 	  This driver supports Thunder's NIC physical function.
@@ -29,14 +28,12 @@ config THUNDER_NIC_PF
 config THUNDER_NIC_VF
 	tristate "Thunder Virtual function driver"
 	depends on 64BIT
-	default ARCH_THUNDER
 	---help---
 	  This driver supports Thunder's NIC virtual function
 
 config	THUNDER_NIC_BGX
 	tristate "Thunder MAC interface driver (BGX)"
 	depends on 64BIT
-	default ARCH_THUNDER
 	select PHYLIB
 	select MDIO_OCTEON
 	---help---
-- 
2.1.4



From m-karicheri2 at ti.com  Tue Aug  4 12:30:49 2015
From: m-karicheri2 at ti.com (Murali Karicheri)
Date: Tue, 4 Aug 2015 15:30:49 -0400
Subject: [Resend: PATCH] ARM: keystone: add documentation for SoCs and EVMs
In-Reply-To: <55C10F2D.9050805@oracle.com>
References: <1438706203-3748-1-git-send-email-m-karicheri2@ti.com>
 <55C10F2D.9050805@oracle.com>
Message-ID: <55C112E9.6020709@ti.com>

On 08/04/2015 03:14 PM, santosh shilimkar wrote:
> On 8/4/2015 9:36 AM, Murali Karicheri wrote:
>> Currently there is no general documentation on Keystone SoCs in the
>> Linux Documentation folder of the source tree. This patch adds some
>> essential documentation with links to help users of Keystone Linux and
>> also provide links to existing documents where necessary.
>>
>> Signed-off-by: Murali Karicheri <m-karicheri2 at ti.com>
>> ---
> Good writeup Murali. This will be handy.
> I can queue this up via arm-soc for 4.3 if the doc maintainers are
> happy with it.
>
> Thanks !!
>
> Regards,
> Santosh
>
>
Santosh,

Thanks. BTW, there is one more DTS update for netcp from Wingman which 
will be posted soon. FYI. Also one from me as there is a OSR clock 
missing in K2L netcp binding.

-- 
Murali Karicheri
Linux Kernel, Keystone


From balbi at ti.com  Tue Aug  4 12:32:57 2015
From: balbi at ti.com (Felipe Balbi)
Date: Tue, 4 Aug 2015 14:32:57 -0500
Subject: MUSB dual-role on AM335x behaving weirdly
In-Reply-To: <55C0CAC6.3020603@free-electrons.com>
References: <CADYTM3Zk2iD8YMj75CoLJn=4kpoXoXEKUWj2QzdXKGCJjtfG2A@mail.gmail.com>
 <CADYTM3a1QWnec1D=wT=fgZ-RCXAx_qZYYoFg5gWOy0yT4vovHA@mail.gmail.com>
 <20150514212653.GC3338@piout.net>
 <CADYTM3baVqoEBdWoQb5JFyGR2_GKm1FHMYWST1YkZV=m=ZdycQ@mail.gmail.com>
 <20150526145118.GD26599@saruman.tx.rr.com>
 <20150527094205.GO3199@piout.net>
 <5594E56B.3040200@free-electrons.com>
 <CADYTM3ZF5m++N1NqmOJoH5agbYrzpvSbLnuLVgttxwzdzwmGwQ@mail.gmail.com>
 <55C0B954.3020106@free-electrons.com>
 <55C0CAC6.3020603@free-electrons.com>
Message-ID: <20150804193257.GF9623@saruman.tx.rr.com>

On Tue, Aug 04, 2015 at 04:23:02PM +0200, Gregory CLEMENT wrote:
> Hi again,
> On 04/08/2015 15:08, Gregory CLEMENT wrote:
> > Hi Bin,
> > 
> > On 02/07/2015 19:05, Bin Liu wrote:
> >> Hi,
> >>
> >> On Thu, Jul 2, 2015 at 2:16 AM, Gregory CLEMENT
> >> <gregory.clement at free-electrons.com> wrote:
> >>> Hi Felipe,
> >>>
> >>> On 27/05/2015 11:42, Alexandre Belloni wrote:
> >>>> Hi,
> >>>>
> >>>> On 26/05/2015 at 09:51:18 -0500, Felipe Balbi wrote :
> >>>>> On Thu, May 14, 2015 at 04:36:33PM -0500, Bin Liu wrote:
> >>>>>> Alexandre,
> >>>>>>
> >>>>>> On Thu, May 14, 2015 at 4:26 PM, Alexandre Belloni
> >>>>>> <alexandre.belloni at free-electrons.com> wrote:
> >>>>>>> On 14/05/2015 at 16:16:12 -0500, Bin Liu wrote :
> >>>>>>>> I think I found the root cause of the problem: board design issue - I
> >>>>>>>> bet the custom board has too much cap on VBUS line. It should be <
> >>>>>>>> 10uF.
> >>>>>>>>
> >>>>>>>
> >>>>>>> We have a custom board that exhibits the issue but it only has a 100nF
> >>>>>>> cap on VBUS.
> >>>>>>
> >>>>>> Have you measured the VBUS discharging? Is there any way to share your
> >>>>>> schematics?
> >>>>>
> >>>>> Alexandre, any further comments ?
> >>>>>
> >>>>
> >>>> Yeah, I have just got more info.
> >>>>
> >>>> This is the relevant part of the schematic:
> >>>> http://free-electrons.com/~alexandre/usb.png
> >>>>
> >>>> The total VBUS capacitance is 200nF and the USB0 pins are connected
> >>>> directly to the AM3358 pins. U1 is actually not fitted.
> >>>>
> >>>> We didn't measure VBUS discharging but we observe the OTG pin sensing
> >>>> stops when plugging an OTG cable without any device.
> >>>
> >>> Do you have any news about this topic?
> >>>
> >>>
> >>> Is there something else that we can do to help solving this issue?
> >>
> >> In the case of CONFIG_USB_MUSB_DUAL_ROLE=y and dr_mode=otg, how is the
> >> gadget driver configured? It has to be a module not built-in.
> > 
> > Indeed when I configured CONFIG_USB_MUSB_HDRC=m and CONFIG_USB_MUSB_DSPS=m
> > it worked seamless.
> > 
> 
> Actually it didn't worked. And now sometimes I even received continuously
> the following message:
> 
>  musb_bus_suspend 2484: trying to suspend as a_wait_vfall while active

this is likely because your VBUS hasn't dropped below 0.8V fast enough.

I could only trigger this message in that situation. Use a scope to poke
at VBUS and see how long is takes to reach 0.8V, this could all be cause
by too much capacitance on VBUS line.

cheers

-- 
balbi
-------------- next part --------------
A non-text attachment was scrubbed...
Name: signature.asc
Type: application/pgp-signature
Size: 819 bytes
Desc: Digital signature
URL: <http://lists.infradead.org/pipermail/linux-arm-kernel/attachments/20150804/2369ce05/attachment.sig>

From sboyd at codeaurora.org  Tue Aug  4 12:34:39 2015
From: sboyd at codeaurora.org (Stephen Boyd)
Date: Tue, 04 Aug 2015 12:34:39 -0700
Subject: [PATCH v3 1/2] clk: rockchip: add pclk_pd_pmu to the list of
 rk3288 critical clocks
In-Reply-To: <1588782.u2WKR6eVuV@diego>
References: <1438670487-27598-1-git-send-email-hl@rock-chips.com>
 <1588782.u2WKR6eVuV@diego>
Message-ID: <55C113CF.2000601@codeaurora.org>

On 08/04/2015 01:54 AM, Heiko St?bner wrote:
> Hi,
>
> Am Dienstag, 4. August 2015, 14:41:26 schrieb Lin Huang:
>
> I guess this patch then would need a
>
> From: Heiko Stuebner <heiko at sntech.de>
>
> at this point to override the author then.

Sounds right. Please resend the patch properly. Also, is there a 2/2? I 
never got it.

-- 
Qualcomm Innovation Center, Inc. is a member of Code Aurora Forum,
a Linux Foundation Collaborative Project



From heiko at sntech.de  Tue Aug  4 12:40:16 2015
From: heiko at sntech.de (Heiko =?ISO-8859-1?Q?St=FCbner?=)
Date: Tue, 04 Aug 2015 21:40:16 +0200
Subject: [PATCH v3 1/2] clk: rockchip: add pclk_pd_pmu to the list of
 rk3288 critical clocks
In-Reply-To: <55C113CF.2000601@codeaurora.org>
References: <1438670487-27598-1-git-send-email-hl@rock-chips.com>
 <1588782.u2WKR6eVuV@diego> <55C113CF.2000601@codeaurora.org>
Message-ID: <10063547.S7PvqCkF78@diego>

Am Dienstag, 4. August 2015, 12:34:39 schrieb Stephen Boyd:
> On 08/04/2015 01:54 AM, Heiko St?bner wrote:
> > Hi,
> > 
> > Am Dienstag, 4. August 2015, 14:41:26 schrieb Lin Huang:
> > 
> > I guess this patch then would need a
> > 
> > From: Heiko Stuebner <heiko at sntech.de>
> > 
> > at this point to override the author then.
> 
> Sounds right. Please resend the patch properly. Also, is there a 2/2? I
> never got it.

Patch 2/2 is a pinctrl change, that actually depends in this patch.
Improved clock-handling in the pinctrl driver caused the pd_pmu clock to get 
deactivated.

So, perhaps it might be even better to get an Ack from the clock maintainer 
and merge both patches through the pinctrl tree?


In which case Linus Walleij should also be included as recipient of this patch 
when resending.


From sboyd at codeaurora.org  Tue Aug  4 12:44:33 2015
From: sboyd at codeaurora.org (Stephen Boyd)
Date: Tue, 04 Aug 2015 12:44:33 -0700
Subject: [PATCH v3 1/2] clk: rockchip: add pclk_pd_pmu to the list of
 rk3288 critical clocks
In-Reply-To: <10063547.S7PvqCkF78@diego>
References: <1438670487-27598-1-git-send-email-hl@rock-chips.com>
 <1588782.u2WKR6eVuV@diego> <55C113CF.2000601@codeaurora.org>
 <10063547.S7PvqCkF78@diego>
Message-ID: <55C11621.1000609@codeaurora.org>

On 08/04/2015 12:40 PM, Heiko St?bner wrote:
> Am Dienstag, 4. August 2015, 12:34:39 schrieb Stephen Boyd:
>> On 08/04/2015 01:54 AM, Heiko St?bner wrote:
>>> Hi,
>>>
>>> Am Dienstag, 4. August 2015, 14:41:26 schrieb Lin Huang:
>>>
>>> I guess this patch then would need a
>>>
>>> From: Heiko Stuebner <heiko at sntech.de>
>>>
>>> at this point to override the author then.
>> Sounds right. Please resend the patch properly. Also, is there a 2/2? I
>> never got it.
> Patch 2/2 is a pinctrl change, that actually depends in this patch.
> Improved clock-handling in the pinctrl driver caused the pd_pmu clock to get
> deactivated.
>
> So, perhaps it might be even better to get an Ack from the clock maintainer
> and merge both patches through the pinctrl tree?
>
>
> In which case Linus Walleij should also be included as recipient of this patch
> when resending.

Ok that's fine. We can ack it and you can take it through pinctrl if needed.

-- 
Qualcomm Innovation Center, Inc. is a member of Code Aurora Forum,
a Linux Foundation Collaborative Project



From jchandra at broadcom.com  Tue Aug  4 13:53:38 2015
From: jchandra at broadcom.com (Jayachandran C)
Date: Wed, 5 Aug 2015 02:23:38 +0530
Subject: [PATCH v4 1/3] PCI: generic: remove dependency on hw_pci
Message-ID: <1438721620-15493-1-git-send-email-jchandra@broadcom.com>

The current code in pci-host-generic.c uses pci_common_init_dev()
from arm architecture to do some part of the PCI setup, and this
prevents it from being used with arm64 architecture.

The part of pci_common_init_dev() that is really needed by
pci-host-generic.c is very limited and can be done in the same
file without using hw_pci API of ARM. The ARM platform requires
a pci_sys_data as sysdata for the PCI bus, this can be handled by
setting up gen_pci to have a pci_sys_data variable as the first
element.

Signed-off-by: Jayachandran C <jchandra at broadcom.com>
Acked-by: Lorenzo Pieralisi <lorenzo.pieralisi at arm.com>
Tested-by: Lorenzo Pieralisi <lorenzo.pieralisi at arm.com>
Tested-by: Pavel Fedin <p.fedin at samsung.com>
---
Here's v4 of the patchset.
v3-v4
 - Changes for comments by Lorenzo Pieralisi/Will Deacon
  - add PCI_REASSIGN_ALL_BUS flag if not probe only
  - split setup-irq.o into another patch
  - minor clean up of commit messages

v2-v3
 - rebase to 4.2-rc
 - fix PCI_PROBE_ONLY check before calling pcie configure
 - added a comment above sysdata
 - updated the commit message

v1->v2
 - Address comments from Arnd Bergmann and Lorenzo Pieralisi
    - move contents of gen_pci_init to gen_pci_probe
    - assign resources only when !probe_only
 - tested on ARM32 with qemu option -M virt

Notes:
 - passing a zeroed out pci_sys_data for ARM looks ok, but I haven't
   tested it on ARM.
 - tested it on ARM64 fast model
 - Any information on how this can be tested on arm is welcome.
 - There is only one ifdef, and that can be removed when arm64 gets
   a sysdata, or when arm loses its sysdata.
 drivers/pci/host/pci-host-generic.c | 55 ++++++++++++++++++++++++-------------
 1 file changed, 36 insertions(+), 19 deletions(-)

diff --git a/drivers/pci/host/pci-host-generic.c b/drivers/pci/host/pci-host-generic.c
index ba46e58..53703e3 100644
--- a/drivers/pci/host/pci-host-generic.c
+++ b/drivers/pci/host/pci-host-generic.c
@@ -38,7 +38,15 @@ struct gen_pci_cfg_windows {
 	const struct gen_pci_cfg_bus_ops	*ops;
 };
 
+/*
+ * ARM needs platform specific pci_sys_data as the sysdata for PCI.
+ * We add the sys as the first field below to handle this. sys will
+ * set to 0, so that the pci functions in do the right thing.
+ */
 struct gen_pci {
+#ifdef CONFIG_ARM
+	struct pci_sys_data			sys;
+#endif
 	struct pci_host_bridge			host;
 	struct gen_pci_cfg_windows		cfg;
 	struct list_head			resources;
@@ -48,8 +56,7 @@ static void __iomem *gen_pci_map_cfg_bus_cam(struct pci_bus *bus,
 					     unsigned int devfn,
 					     int where)
 {
-	struct pci_sys_data *sys = bus->sysdata;
-	struct gen_pci *pci = sys->private_data;
+	struct gen_pci *pci = bus->sysdata;
 	resource_size_t idx = bus->number - pci->cfg.bus_range->start;
 
 	return pci->cfg.win[idx] + ((devfn << 8) | where);
@@ -64,8 +71,7 @@ static void __iomem *gen_pci_map_cfg_bus_ecam(struct pci_bus *bus,
 					      unsigned int devfn,
 					      int where)
 {
-	struct pci_sys_data *sys = bus->sysdata;
-	struct gen_pci *pci = sys->private_data;
+	struct gen_pci *pci = bus->sysdata;
 	resource_size_t idx = bus->number - pci->cfg.bus_range->start;
 
 	return pci->cfg.win[idx] + ((devfn << 12) | where);
@@ -198,13 +204,6 @@ static int gen_pci_parse_map_cfg_windows(struct gen_pci *pci)
 	return 0;
 }
 
-static int gen_pci_setup(int nr, struct pci_sys_data *sys)
-{
-	struct gen_pci *pci = sys->private_data;
-	list_splice_init(&pci->resources, &sys->resources);
-	return 1;
-}
-
 static int gen_pci_probe(struct platform_device *pdev)
 {
 	int err;
@@ -214,13 +213,7 @@ static int gen_pci_probe(struct platform_device *pdev)
 	struct device *dev = &pdev->dev;
 	struct device_node *np = dev->of_node;
 	struct gen_pci *pci = devm_kzalloc(dev, sizeof(*pci), GFP_KERNEL);
-	struct hw_pci hw = {
-		.nr_controllers	= 1,
-		.private_data	= (void **)&pci,
-		.setup		= gen_pci_setup,
-		.map_irq	= of_irq_parse_and_map_pci,
-		.ops		= &gen_pci_ops,
-	};
+	struct pci_bus *bus;
 
 	if (!pci)
 		return -ENOMEM;
@@ -258,7 +251,31 @@ static int gen_pci_probe(struct platform_device *pdev)
 		return err;
 	}
 
-	pci_common_init_dev(dev, &hw);
+	/* do not reassign resource if probe only */
+	if (!pci_has_flag(PCI_PROBE_ONLY))
+		pci_add_flags(PCI_REASSIGN_ALL_RSRC | PCI_REASSIGN_ALL_BUS);
+
+	bus = pci_scan_root_bus(dev, 0, &gen_pci_ops, pci, &pci->resources);
+	if (!bus) {
+		dev_err(dev, "Scanning rootbus failed");
+		return -ENODEV;
+	}
+
+	pci_fixup_irqs(pci_common_swizzle, of_irq_parse_and_map_pci);
+
+	if (!pci_has_flag(PCI_PROBE_ONLY)) {
+		pci_bus_size_bridges(bus);
+		pci_bus_assign_resources(bus);
+	}
+	pci_bus_add_devices(bus);
+
+	/* Configure PCI Express settings */
+	if (!pci_has_flag(PCI_PROBE_ONLY)) {
+		struct pci_bus *child;
+
+		list_for_each_entry(child, &bus->children, node)
+			pcie_bus_configure_settings(child);
+	}
 	return 0;
 }
 
-- 
1.9.1



From jchandra at broadcom.com  Tue Aug  4 13:53:39 2015
From: jchandra at broadcom.com (Jayachandran C)
Date: Wed, 5 Aug 2015 02:23:39 +0530
Subject: [PATCH v4 2/3] PCI: Add setup-irq.o when compiling for arm64
In-Reply-To: <1438721620-15493-1-git-send-email-jchandra@broadcom.com>
References: <1438721620-15493-1-git-send-email-jchandra@broadcom.com>
Message-ID: <1438721620-15493-2-git-send-email-jchandra@broadcom.com>

ARM64 requires setup-irq.o to provide pci_fixup_irqs() implementation.
We are adding this now to support the pci-host-generic host controller,
but we enable it for ARM64 PCI so that other host controllers can use
this as well.

Signed-off-by: Jayachandran C <jchandra at broadcom.com>
---
 drivers/pci/Makefile | 1 +
 1 file changed, 1 insertion(+)

diff --git a/drivers/pci/Makefile b/drivers/pci/Makefile
index 73e4af4..be3f631 100644
--- a/drivers/pci/Makefile
+++ b/drivers/pci/Makefile
@@ -33,6 +33,7 @@ obj-$(CONFIG_PCI_IOV) += iov.o
 #
 obj-$(CONFIG_ALPHA) += setup-irq.o
 obj-$(CONFIG_ARM) += setup-irq.o
+obj-$(CONFIG_ARM64) += setup-irq.o
 obj-$(CONFIG_UNICORE32) += setup-irq.o
 obj-$(CONFIG_SUPERH) += setup-irq.o
 obj-$(CONFIG_MIPS) += setup-irq.o
-- 
1.9.1



From jchandra at broadcom.com  Tue Aug  4 13:53:40 2015
From: jchandra at broadcom.com (Jayachandran C)
Date: Wed, 5 Aug 2015 02:23:40 +0530
Subject: [PATCH v4 3/3] PCI: generic: add arm64 support
In-Reply-To: <1438721620-15493-1-git-send-email-jchandra@broadcom.com>
References: <1438721620-15493-1-git-send-email-jchandra@broadcom.com>
Message-ID: <1438721620-15493-3-git-send-email-jchandra@broadcom.com>

Make pci-host-generic driver (kernel option PCI_HOST_GENERIC) available
on arm64.

Signed-off-by: Jayachandran C <jchandra at broadcom.com>
---
 drivers/pci/host/Kconfig | 2 +-
 1 file changed, 1 insertion(+), 1 deletion(-)

diff --git a/drivers/pci/host/Kconfig b/drivers/pci/host/Kconfig
index c132bdd..675c2d1 100644
--- a/drivers/pci/host/Kconfig
+++ b/drivers/pci/host/Kconfig
@@ -53,7 +53,7 @@ config PCI_RCAR_GEN2_PCIE
 
 config PCI_HOST_GENERIC
 	bool "Generic PCI host controller"
-	depends on ARM && OF
+	depends on (ARM || ARM64) && OF
 	help
 	  Say Y here if you want to support a simple generic PCI host
 	  controller, such as the one emulated by kvmtool.
-- 
1.9.1



From laurent.pinchart at ideasonboard.com  Tue Aug  4 13:54:27 2015
From: laurent.pinchart at ideasonboard.com (Laurent Pinchart)
Date: Tue, 04 Aug 2015 23:54:27 +0300
Subject: [PATCH 05/13] iommu/io-pgtable-arm: Allow appropriate DMA API use
In-Reply-To: <20150804145642.GQ7557@n2100.arm.linux.org.uk>
References: <1438608355-7335-1-git-send-email-will.deacon@arm.com>
 <55C0D071.1040104@arm.com> <20150804145642.GQ7557@n2100.arm.linux.org.uk>
Message-ID: <1987558.GfG8OCqzMM@avalon>

Hi Russell,

On Tuesday 04 August 2015 15:56:42 Russell King - ARM Linux wrote:
> On Tue, Aug 04, 2015 at 03:47:13PM +0100, Robin Murphy wrote:
> > Hi Laurent,
> > 
> > [ +RMK, as his patch is indirectly involved here ]
> > 
> > On 04/08/15 14:16, Laurent Pinchart wrote:
> >> This is what I believe to be an API abuse. The
> >> dma_sync_single_for_device()
> >> API is meant to pass ownership of a buffer to the device. Unless I'm
> >> mistaken, once that's done the CPU isn't allowed to touch the buffer
> >> anymore until dma_sync_single_for_cpu() is called to get ownership of
> >> the buffer back.
>
> That's what I thought up until recently, but it's not strictly true - see
> Documentation/DMA-API.txt which Robin quoted.

I find the documentation slightly unclear on this topic. I have nothing 
against updating it to state that the sync functions ensure visibility of the 
data to the device or CPU instead of transferring ownership if that's the 
general understanding of how the API work (or should work). This would of 
course need to be carefully reviewed to ensure that the current implementation 
really works that way across all architectures, or at least that it can be 
made to work that way.

> > [3]:Yes, there may generally be exceptions to that, but not in the context
> > of this code. Unless the Renesas IPMMU does something I don't know about?
> 
> If an IOMMU does write to its page tables, then the only way to handle
> those is using DMA-coherent memory, either via a coherent mapping or
> allocated via dma_alloc_coherent().  The streaming DMA API is wholely
> unsuitable for any mapping where both the CPU and DMA device both want
> to simultaneously alter the contained data.

-- 
Regards,

Laurent Pinchart





From d-gerlach at ti.com  Tue Aug  4 13:58:41 2015
From: d-gerlach at ti.com (Dave Gerlach)
Date: Tue, 4 Aug 2015 15:58:41 -0500
Subject: [PATCH v2 3/3] soc: ti: Add wkup_m3_ipc driver
In-Reply-To: <20150720061559.GX17550@atomide.com>
References: <1437166592-25378-1-git-send-email-d-gerlach@ti.com>
 <1437166592-25378-4-git-send-email-d-gerlach@ti.com>
 <20150720061559.GX17550@atomide.com>
Message-ID: <55C12781.1070007@ti.com>

On 07/20/2015 01:16 AM, Tony Lindgren wrote:
> * Dave Gerlach <d-gerlach at ti.com> [150717 13:59]:
>> +
>> +/* Public functions */
> ...
>> +EXPORT_SYMBOL_GPL(wkup_m3_set_mem_type);
>> +EXPORT_SYMBOL_GPL(wkup_m3_set_resume_address);
>> +EXPORT_SYMBOL_GPL(wkup_m3_request_pm_status);
>> +EXPORT_SYMBOL_GPL(wkup_m3_prepare_low_power);
>> +EXPORT_SYMBOL_GPL(wkup_m3_finish_low_power);
>
> I think you can avoid exporting these SoC specific functions
> by just exporting wkup_m3_request() and wkup_m3_free() type
> functions with a data structure containing the necessary
> function pointers.

Ok thanks for the comment, I can try that change out, I agree it 
probably isn't necessary to export so much.

Regards,
Dave

>
> Regards,
>
> Tony
>



From public_timo.s at silentcreek.de  Tue Aug  4 14:08:01 2015
From: public_timo.s at silentcreek.de (Timo Sigurdsson)
Date: Tue,  4 Aug 2015 23:08:01 +0200
Subject: [PATCH v2] ARM: dts: sunxi: Raise minimum CPU voltage for sun7i-a20
 to meet SoC specifications
Message-ID: <1438722481-2302-1-git-send-email-public_timo.s@silentcreek.de>

sun7i-a20.dtsi contains a cpufreq operating point at 0.9 volts. The minimum
CPU voltage for the Allwinner A20 SoC, however, is 1.0 volts. Thus, raise
the voltage for the lowest operating point to 1.0 volts in order to stay
within the SoC specifications. It is an undervolted setting that isn't
stable across all SoCs and boards out there.

Signed-off-by: Timo Sigurdsson <public_timo.s at silentcreek.de>
---
Changes since v1:

- Fixed checkpatch warnings
- Changed the commit message and title to clarify that this is not a board-specific issue, but rather a limitation by the SoC  
---
 arch/arm/boot/dts/sun7i-a20.dtsi | 2 +-
 1 file changed, 1 insertion(+), 1 deletion(-)

diff --git a/arch/arm/boot/dts/sun7i-a20.dtsi b/arch/arm/boot/dts/sun7i-a20.dtsi
index 6a63f30..f5f384c 100644
--- a/arch/arm/boot/dts/sun7i-a20.dtsi
+++ b/arch/arm/boot/dts/sun7i-a20.dtsi
@@ -107,7 +107,7 @@
 				720000	1200000
 				528000	1100000
 				312000	1000000
-				144000	900000
+				144000	1000000
 				>;
 			#cooling-cells = <2>;
 			cooling-min-level = <0>;
-- 
2.1.4



From hdegoede at redhat.com  Tue Aug  4 14:25:53 2015
From: hdegoede at redhat.com (Hans de Goede)
Date: Tue,  4 Aug 2015 23:25:53 +0200
Subject: [PATCH] musb: sunxi: Ignore VBus errors in host-only mode
Message-ID: <1438723553-4136-1-git-send-email-hdegoede@redhat.com>

For some unclear reason sometimes we get VBus errors in host-only mode,
even though we do not have any vbus-detection then. Ignore these.

Signed-off-by: Hans de Goede <hdegoede at redhat.com>
---
 drivers/usb/musb/sunxi.c | 4 ++++
 1 file changed, 4 insertions(+)

diff --git a/drivers/usb/musb/sunxi.c b/drivers/usb/musb/sunxi.c
index f9f6304..34ce5df 100644
--- a/drivers/usb/musb/sunxi.c
+++ b/drivers/usb/musb/sunxi.c
@@ -194,6 +194,10 @@ static irqreturn_t sunxi_musb_interrupt(int irq, void *__hci)
 		musb_writeb(musb->mregs, MUSB_FADDR, 0);
 	}
 
+	/*  Ignore Vbus errors when in host only mode */
+	if (musb->port_mode == MUSB_PORT_MODE_HOST)
+		musb->int_usb &= ~MUSB_INTR_VBUSERROR;
+
 	musb->int_tx = readw(musb->mregs + SUNXI_MUSB_INTRTX);
 	if (musb->int_tx)
 		writew(musb->int_tx, musb->mregs + SUNXI_MUSB_INTRTX);
-- 
2.4.3



From horms+renesas at verge.net.au  Tue Aug  4 14:30:48 2015
From: horms+renesas at verge.net.au (Simon Horman)
Date: Wed,  5 Aug 2015 06:30:48 +0900
Subject: [PATCH] ARM: shmobile: Add silk device tree bindings documentation
Message-ID: <1438723848-14812-1-git-send-email-horms+renesas@verge.net.au>

Add Silk Device tree bindings Documentation, listing it as a supported board.

This allows to use checkpatch to validate DTSes referring to the Silk board.

Signed-off-by: Simon Horman <horms+renesas at verge.net.au>
---
 Documentation/devicetree/bindings/arm/shmobile.txt | 2 ++
 1 file changed, 2 insertions(+)

diff --git a/Documentation/devicetree/bindings/arm/shmobile.txt b/Documentation/devicetree/bindings/arm/shmobile.txt
index c4f19b2e7dd9..f3f96b5a7418 100644
--- a/Documentation/devicetree/bindings/arm/shmobile.txt
+++ b/Documentation/devicetree/bindings/arm/shmobile.txt
@@ -57,6 +57,8 @@ Boards:
     compatible = "renesas,lager", "renesas,r8a7790"
   - Marzen
     compatible = "renesas,marzen", "renesas,r8a7779"
+  - Silk
+    compatible = "renesas,silk", "renesas,r8a7794";
 
 Note: Reference Device Tree Implementations are temporary implementations
       to ease the migration from platform devices to Device Tree, and are
-- 
2.1.4



From hdegoede at redhat.com  Tue Aug  4 14:30:09 2015
From: hdegoede at redhat.com (Hans de Goede)
Date: Tue,  4 Aug 2015 23:30:09 +0200
Subject: [PATCH] ARM: dts: sun4i: Enable otg in host only mode on Jesurun Q5
Message-ID: <1438723809-9010-1-git-send-email-hdegoede@redhat.com>

The Jesurun Q5 has the musb hooked up to an usb-a receptacle, enable it
in host-only mode.

Signed-off-by: Hans de Goede <hdegoede at redhat.com>
---
 arch/arm/boot/dts/sun4i-a10-jesurun-q5.dts | 15 +++++++++++++++
 1 file changed, 15 insertions(+)

diff --git a/arch/arm/boot/dts/sun4i-a10-jesurun-q5.dts b/arch/arm/boot/dts/sun4i-a10-jesurun-q5.dts
index dc2f2ae..7afc7a6 100644
--- a/arch/arm/boot/dts/sun4i-a10-jesurun-q5.dts
+++ b/arch/arm/boot/dts/sun4i-a10-jesurun-q5.dts
@@ -156,6 +156,10 @@
 	status = "okay";
 };
 
+&otg_sram {
+	status = "okay";
+};
+
 &pio {
 	emac_power_pin_q5: emac_power_pin at 0 {
 		allwinner,pins = "PH19";
@@ -172,6 +176,11 @@
 	};
 };
 
+&reg_usb0_vbus {
+	regulator-boot-on;
+	status = "okay";
+};
+
 &reg_usb1_vbus {
 	status = "okay";
 };
@@ -186,7 +195,13 @@
 	status = "okay";
 };
 
+&usb_otg {
+	dr_mode = "host";
+	status = "okay";
+};
+
 &usbphy {
+	usb0_vbus-supply = <&reg_usb0_vbus>;
 	usb1_vbus-supply = <&reg_usb1_vbus>;
 	usb2_vbus-supply = <&reg_usb2_vbus>;
 	status = "okay";
-- 
2.4.3



From balbi at ti.com  Tue Aug  4 14:35:53 2015
From: balbi at ti.com (Felipe Balbi)
Date: Tue, 4 Aug 2015 16:35:53 -0500
Subject: [PATCH] musb: sunxi: Ignore VBus errors in host-only mode
In-Reply-To: <1438723553-4136-1-git-send-email-hdegoede@redhat.com>
References: <1438723553-4136-1-git-send-email-hdegoede@redhat.com>
Message-ID: <20150804213553.GI9623@saruman.tx.rr.com>

On Tue, Aug 04, 2015 at 11:25:53PM +0200, Hans de Goede wrote:
> For some unclear reason sometimes we get VBus errors in host-only mode,
> even though we do not have any vbus-detection then. Ignore these.
> 
> Signed-off-by: Hans de Goede <hdegoede at redhat.com>
> ---
>  drivers/usb/musb/sunxi.c | 4 ++++
>  1 file changed, 4 insertions(+)
> 
> diff --git a/drivers/usb/musb/sunxi.c b/drivers/usb/musb/sunxi.c
> index f9f6304..34ce5df 100644
> --- a/drivers/usb/musb/sunxi.c
> +++ b/drivers/usb/musb/sunxi.c
> @@ -194,6 +194,10 @@ static irqreturn_t sunxi_musb_interrupt(int irq, void *__hci)
>  		musb_writeb(musb->mregs, MUSB_FADDR, 0);
>  	}
>  
> +	/*  Ignore Vbus errors when in host only mode */
> +	if (musb->port_mode == MUSB_PORT_MODE_HOST)
> +		musb->int_usb &= ~MUSB_INTR_VBUSERROR;

check with a scope if VBUS is really dropping. Host does VBUS detection
indeed, at a minimum, for overcurrent protection. You might have
something causing VBUS to drop and that something needs to be found,
rather than masked.

-- 
balbi
-------------- next part --------------
A non-text attachment was scrubbed...
Name: signature.asc
Type: application/pgp-signature
Size: 819 bytes
Desc: Digital signature
URL: <http://lists.infradead.org/pipermail/linux-arm-kernel/attachments/20150804/4dbbb53a/attachment.sig>

From mark.rutland at arm.com  Tue Aug  4 14:45:23 2015
From: mark.rutland at arm.com (Mark Rutland)
Date: Tue, 4 Aug 2015 22:45:23 +0100
Subject: [PATCH] arm64: mm: ensure patched kernel text is fetched from PoC
In-Reply-To: <1438715013-4625-1-git-send-email-will.deacon@arm.com>
References: <1438715013-4625-1-git-send-email-will.deacon@arm.com>
Message-ID: <20150804214522.GA14625@leverpostej>

Hi Will,

I assume that you meant PoU rather than PoC in the subject.

On Tue, Aug 04, 2015 at 08:03:33PM +0100, Will Deacon wrote:
> The arm64 booting document requires that the bootloader has cleaned the
> kernel image to the PoC. However, when a CPU re-enters the kernel due to
> either a CPU hotplug "on" event or resuming from a low-power state (e.g.
> cpuidle), the kernel text may in-fact be dirty at the PoU due to things
> like alternative patching or even module loading.
> 
> Thanks to I-cache speculation with the MMU off, stale instructions could
> be fetched prior to enabling the MMU, potentially leading to crashes
> when executing regions of code that have been modified at runtime.
> 
> This patch addresses the issue by ensuring that the local I-cache is
> invalidated immediately after a CPU has enabled its MMU but before
> jumping out of the identity mapping. Any stale instructions fetched from
> the PoC will then be discarded and refetched correctly from the PoU.

It may be worth mentioning that none of the instructions executed up to
this point will have been patched, so we know that they have remained
clean to the PoC. Otherwise we'd need to flush those to the PoC
explicitly.

Other than the typo in the subject, this looks good to me. With that
fixed:

Reviewed-by: Mark Rutland <mark.rutland at arm.com>

Thanks,
Mark.

> 
> Tested-by: Mark Rutland <mark.rutland at arm.com>
> Signed-off-by: Will Deacon <will.deacon at arm.com>
> ---
>  arch/arm64/kernel/head.S  | 8 ++++++++
>  arch/arm64/kernel/sleep.S | 8 ++++++++
>  arch/arm64/mm/proc.S      | 1 -
>  3 files changed, 16 insertions(+), 1 deletion(-)
> 
> diff --git a/arch/arm64/kernel/head.S b/arch/arm64/kernel/head.S
> index 3a0654173997..a055be6125cf 100644
> --- a/arch/arm64/kernel/head.S
> +++ b/arch/arm64/kernel/head.S
> @@ -634,5 +634,13 @@ __enable_mmu:
>  	isb
>  	msr	sctlr_el1, x0
>  	isb
> +	/*
> +	 * Invalidate the local I-cache so that any instructions fetched
> +	 * speculatively from the PoC are discarded, since they may have
> +	 * been dynamically patched at the PoU.
> +	 */
> +	ic	iallu
> +	dsb	nsh
> +	isb
>  	br	x27
>  ENDPROC(__enable_mmu)
> diff --git a/arch/arm64/kernel/sleep.S b/arch/arm64/kernel/sleep.S
> index 5686a3ae3940..38d37c539a30 100644
> --- a/arch/arm64/kernel/sleep.S
> +++ b/arch/arm64/kernel/sleep.S
> @@ -133,6 +133,14 @@ ENTRY(cpu_resume_mmu)
>  	ldr	x3, =cpu_resume_after_mmu
>  	msr	sctlr_el1, x0		// restore sctlr_el1
>  	isb
> +	/*
> +	 * Invalidate the local I-cache so that any instructions fetched
> +	 * speculatively from the PoC are discarded, since they may have
> +	 * been dynamically patched at the PoU.
> +	 */
> +	ic	iallu
> +	dsb	nsh
> +	isb
>  	br	x3			// global jump to virtual address
>  ENDPROC(cpu_resume_mmu)
>  	.popsection
> diff --git a/arch/arm64/mm/proc.S b/arch/arm64/mm/proc.S
> index eff4f627358a..716c673cbd8e 100644
> --- a/arch/arm64/mm/proc.S
> +++ b/arch/arm64/mm/proc.S
> @@ -146,7 +146,6 @@ ENDPROC(cpu_do_switch_mm)
>   *	value of the SCTLR_EL1 register.
>   */
>  ENTRY(__cpu_setup)
> -	ic	iallu				// I+BTB cache invalidate
>  	tlbi	vmalle1is			// invalidate I + D TLBs
>  	dsb	ish
>  
> -- 
> 2.1.4
> 


From bhelgaas at google.com  Tue Aug  4 14:53:48 2015
From: bhelgaas at google.com (Bjorn Helgaas)
Date: Tue, 04 Aug 2015 16:53:48 -0500
Subject: [PATCH v5 0/9] ARM: PCI: kill pcibios_msi_controller()
Message-ID: <20150804214234.9189.42548.stgit@bhelgaas-glaptop2.roam.corp.google.com>

The first 5 patches here are essentially the same as Lorenzo's v4 posting
at
http://lkml.kernel.org/1438169598-24490-1-git-send-email-lorenzo.pieralisi at arm.com

I added some at the end to fix what look like some X-Gene bugs to me, and
to make X-Gene use pci_scan_root_bus_msi() like the other drivers that use
msi_controller.

v4->v5 changes:
- Declare pci_scan_root_bus_msi() in drivers/pci/pci.h instead of
  include/linux/pci.h.  I like the idea, but I hope we can replace this and
  other "scan_root_bus" interfaces with a single, more-generic interface,
  so I'd rather not expose this one widely.
- Split "kill pcibios_msi_controller" into several patches.  My intent was
  to make it easier to review; I don't think I made any actual code
  changes.  I did drop Marc's ack because I fiddled with stuff enough
  that I wasn't comfortable keeping it.
- I added of_node_put() after of_parse_phandle() in MVEBU and X-Gene.
  I'm not an OF guy, so tell me if this is the wrong thing.
- I changed a couple X-Gene OF "msi-parent" things to match (I think) what
  MVEBU does.  Again, tell me if I got this wrong.
- I used pci_scan_root_bus_msi() in X-Gene to follow what Lorenzo already
  did in DesignWare and Xilinx.

---

Lorenzo Pieralisi (5):
      ARM/PCI: Replace panic with WARN messages on failures
      PCI: Add pci_scan_root_bus_msi()
      ARM/PCI, designware, xilinx: Use pci_scan_root_bus_msi()
      ARM/PCI: Remove msi_controller from struct pci_sys_data
      PCI/MSI: Remove unused pcibios_msi_controller() hook

Bjorn Helgaas (4):
      PCI: Drop references acquired by of_parse_phandle()
      PCI: xgene: Set msi_controller->dev to platform_device, not pci_bus
      PCI: xgene: Look for OF "msi-parent" in host controller, not root bus
      PCI: xgene: Use pci_scan_root_bus_msi()


 arch/arm/include/asm/mach/pci.h    |    5 -----
 arch/arm/kernel/bios32.c           |   27 +++++++++------------------
 drivers/pci/host/pci-mvebu.c       |    1 +
 drivers/pci/host/pci-xgene.c       |   26 +++++++++++++-------------
 drivers/pci/host/pcie-designware.c |    6 +++---
 drivers/pci/host/pcie-xilinx.c     |    5 ++---
 drivers/pci/msi.c                  |   17 +----------------
 drivers/pci/pci.h                  |    5 +++++
 drivers/pci/probe.c                |   14 ++++++++++++--
 9 files changed, 46 insertions(+), 60 deletions(-)


From bhelgaas at google.com  Tue Aug  4 14:53:57 2015
From: bhelgaas at google.com (Bjorn Helgaas)
Date: Tue, 04 Aug 2015 16:53:57 -0500
Subject: [PATCH v5 1/9] ARM/PCI: Replace panic with WARN messages on failures
In-Reply-To: <20150804214234.9189.42548.stgit@bhelgaas-glaptop2.roam.corp.google.com>
References: <20150804214234.9189.42548.stgit@bhelgaas-glaptop2.roam.corp.google.com>
Message-ID: <20150804215357.9189.11942.stgit@bhelgaas-glaptop2.roam.corp.google.com>

From: Lorenzo Pieralisi <lorenzo.pieralisi at arm.com>

In the ARM PCI bios32 layer, failures to dynamically allocate pci_sys_data
for a PCI bus, or a PCI bus scan failure have to be considered serious
warnings but they should not trigger a system panic so that at least the
system is given a chance to be debugged.

This patch replaces the panic statements with WARN() messages to improve
error reporting in the ARM PCI bios32 layer.

Signed-off-by: Lorenzo Pieralisi <lorenzo.pieralisi at arm.com>
Signed-off-by: Bjorn Helgaas <bhelgaas at google.com>
Acked-by: Marc Zyngier <marc.zyngier at arm.com>
CC: Russell King <linux at arm.linux.org.uk>
CC: Marc Zyngier <marc.zyngier at arm.com>
---
 arch/arm/kernel/bios32.c |   10 ++++++----
 1 file changed, 6 insertions(+), 4 deletions(-)

diff --git a/arch/arm/kernel/bios32.c b/arch/arm/kernel/bios32.c
index bf370bc..4e95260 100644
--- a/arch/arm/kernel/bios32.c
+++ b/arch/arm/kernel/bios32.c
@@ -459,8 +459,8 @@ static void pcibios_init_hw(struct device *parent, struct hw_pci *hw,
 
 	for (nr = busnr = 0; nr < hw->nr_controllers; nr++) {
 		sys = kzalloc(sizeof(struct pci_sys_data), GFP_KERNEL);
-		if (!sys)
-			panic("PCI: unable to allocate sys data!");
+		if (WARN(!sys, "PCI: unable to allocate sys data!"))
+			break;
 
 #ifdef CONFIG_PCI_MSI
 		sys->msi_ctrl = hw->msi_ctrl;
@@ -489,8 +489,10 @@ static void pcibios_init_hw(struct device *parent, struct hw_pci *hw,
 				sys->bus = pci_scan_root_bus(parent, sys->busnr,
 						hw->ops, sys, &sys->resources);
 
-			if (!sys->bus)
-				panic("PCI: unable to scan bus!");
+			if (WARN(!sys->bus, "PCI: unable to scan bus!")) {
+				kfree(sys);
+				break;
+			}
 
 			busnr = sys->bus->busn_res.end + 1;
 



From bhelgaas at google.com  Tue Aug  4 14:54:04 2015
From: bhelgaas at google.com (Bjorn Helgaas)
Date: Tue, 04 Aug 2015 16:54:04 -0500
Subject: [PATCH v5 2/9] PCI: Add pci_scan_root_bus_msi()
In-Reply-To: <20150804214234.9189.42548.stgit@bhelgaas-glaptop2.roam.corp.google.com>
References: <20150804214234.9189.42548.stgit@bhelgaas-glaptop2.roam.corp.google.com>
Message-ID: <20150804215404.9189.41823.stgit@bhelgaas-glaptop2.roam.corp.google.com>

From: Lorenzo Pieralisi <lorenzo.pieralisi at arm.com>

Add a pci_scan_root_bus_msi() interface so an arch can specify the MSI
controller up front.  This removes the need for a pcibios callback to set
the MSI controller later.

This is not exported because I'd like to replace the variety of "scan root
bus" interfaces with a single, more extensible interface that can handle
the MSI controller, domain, pci_ops, resources, etc.  I hope this interface
is temporary.

[bhelgaas: changelog, split into separate patch, move to drivers/pci/pci.h]
Suggested-by: Russell King <linux at arm.linux.org.uk>
Signed-off-by: Lorenzo Pieralisi <lorenzo.pieralisi at arm.com>
Signed-off-by: Bjorn Helgaas <bhelgaas at google.com>
---
 drivers/pci/pci.h   |    5 +++++
 drivers/pci/probe.c |   14 ++++++++++++--
 2 files changed, 17 insertions(+), 2 deletions(-)

diff --git a/drivers/pci/pci.h b/drivers/pci/pci.h
index 4ff0ff1..1d4c95c 100644
--- a/drivers/pci/pci.h
+++ b/drivers/pci/pci.h
@@ -223,6 +223,11 @@ enum pci_bar_type {
 	pci_bar_mem64,		/* A 64-bit memory BAR */
 };
 
+struct pci_bus *pci_scan_root_bus_msi(struct device *parent, int bus,
+				      struct pci_ops *ops, void *sysdata,
+				      struct list_head *resources,
+				      struct msi_controller *msi);
+
 bool pci_bus_read_dev_vendor_id(struct pci_bus *bus, int devfn, u32 *pl,
 				int crs_timeout);
 int pci_setup_device(struct pci_dev *dev);
diff --git a/drivers/pci/probe.c b/drivers/pci/probe.c
index cefd636..9ff4df0 100644
--- a/drivers/pci/probe.c
+++ b/drivers/pci/probe.c
@@ -2096,8 +2096,9 @@ void pci_bus_release_busn_res(struct pci_bus *b)
 			res, ret ? "can not be" : "is");
 }
 
-struct pci_bus *pci_scan_root_bus(struct device *parent, int bus,
-		struct pci_ops *ops, void *sysdata, struct list_head *resources)
+struct pci_bus *pci_scan_root_bus_msi(struct device *parent, int bus,
+		struct pci_ops *ops, void *sysdata,
+		struct list_head *resources, struct msi_controller *msi)
 {
 	struct resource_entry *window;
 	bool found = false;
@@ -2114,6 +2115,8 @@ struct pci_bus *pci_scan_root_bus(struct device *parent, int bus,
 	if (!b)
 		return NULL;
 
+	b->msi = msi;
+
 	if (!found) {
 		dev_info(&b->dev,
 		 "No busn resource found for root bus, will use [bus %02x-ff]\n",
@@ -2128,6 +2131,13 @@ struct pci_bus *pci_scan_root_bus(struct device *parent, int bus,
 
 	return b;
 }
+
+struct pci_bus *pci_scan_root_bus(struct device *parent, int bus,
+		struct pci_ops *ops, void *sysdata, struct list_head *resources)
+{
+	return pci_scan_root_bus_msi(parent, bus, ops, sysdata, resources,
+				     NULL);
+}
 EXPORT_SYMBOL(pci_scan_root_bus);
 
 struct pci_bus *pci_scan_bus(int bus, struct pci_ops *ops,



From bhelgaas at google.com  Tue Aug  4 14:54:11 2015
From: bhelgaas at google.com (Bjorn Helgaas)
Date: Tue, 04 Aug 2015 16:54:11 -0500
Subject: [PATCH v5 3/9] ARM/PCI, designware,
 xilinx: Use pci_scan_root_bus_msi()
In-Reply-To: <20150804214234.9189.42548.stgit@bhelgaas-glaptop2.roam.corp.google.com>
References: <20150804214234.9189.42548.stgit@bhelgaas-glaptop2.roam.corp.google.com>
Message-ID: <20150804215411.9189.53901.stgit@bhelgaas-glaptop2.roam.corp.google.com>

From: Lorenzo Pieralisi <lorenzo.pieralisi at arm.com>

ARM previously stored the msi_controller pointer in its sysdata, struct
pci_sys_data, and implemented pcibios_msi_controller() to retrieve it.
That made PCI host controller drivers specific to ARM because they had to
put the msi_controller pointer in the ARM-specific pci_sys_data.

There is now a generic mechanism, pci_scan_root_bus_msi(), for giving the
msi_controller pointer to the PCI core.  Use this for all ARM systems and
for the DesignWare and Xilinx PCI host controller drivers.

This removes an ARM dependency from the DesignWare, DRA7xx, EXYNOS, i.MX6,
Keystone, Layerscape, SPEAr13xx, and Xilinx drivers.

[bhelgaas: changelog, split into separate patch]
Suggested-by: Russell King <linux at arm.linux.org.uk>
Signed-off-by: Lorenzo Pieralisi <lorenzo.pieralisi at arm.com>
Signed-off-by: Bjorn Helgaas <bhelgaas at google.com>
CC: Pratyush Anand <pratyush.anand at gmail.com>
CC: Arnd Bergmann <arnd at arndb.de>
CC: Jingoo Han <jingoohan1 at gmail.com>
CC: Simon Horman <horms at verge.net.au>
CC: Russell King <linux at arm.linux.org.uk>
CC: Thomas Petazzoni <thomas.petazzoni at free-electrons.com>
CC: Thierry Reding <thierry.reding at gmail.com>
CC: Michal Simek <michal.simek at xilinx.com>
CC: Marc Zyngier <marc.zyngier at arm.com>
---
 arch/arm/include/asm/mach/pci.h    |    2 --
 arch/arm/kernel/bios32.c           |    5 +++--
 drivers/pci/host/pcie-designware.c |    6 +++---
 drivers/pci/host/pcie-xilinx.c     |    5 ++---
 4 files changed, 8 insertions(+), 10 deletions(-)

diff --git a/arch/arm/include/asm/mach/pci.h b/arch/arm/include/asm/mach/pci.h
index 28b9bb3..c074e7a 100644
--- a/arch/arm/include/asm/mach/pci.h
+++ b/arch/arm/include/asm/mach/pci.h
@@ -19,9 +19,7 @@ struct pci_bus;
 struct device;
 
 struct hw_pci {
-#ifdef CONFIG_PCI_MSI
 	struct msi_controller *msi_ctrl;
-#endif
 	struct pci_ops	*ops;
 	int		nr_controllers;
 	void		**private_data;
diff --git a/arch/arm/kernel/bios32.c b/arch/arm/kernel/bios32.c
index 4e95260..283bc1c 100644
--- a/arch/arm/kernel/bios32.c
+++ b/arch/arm/kernel/bios32.c
@@ -486,8 +486,9 @@ static void pcibios_init_hw(struct device *parent, struct hw_pci *hw,
 			if (hw->scan)
 				sys->bus = hw->scan(nr, sys);
 			else
-				sys->bus = pci_scan_root_bus(parent, sys->busnr,
-						hw->ops, sys, &sys->resources);
+				sys->bus = pci_scan_root_bus_msi(parent,
+					sys->busnr, hw->ops, sys,
+					&sys->resources, hw->msi_ctrl);
 
 			if (WARN(!sys->bus, "PCI: unable to scan bus!")) {
 				kfree(sys);
diff --git a/drivers/pci/host/pcie-designware.c b/drivers/pci/host/pcie-designware.c
index 69486be..bd0aeec 100644
--- a/drivers/pci/host/pcie-designware.c
+++ b/drivers/pci/host/pcie-designware.c
@@ -526,7 +526,6 @@ int dw_pcie_host_init(struct pcie_port *pp)
 
 #ifdef CONFIG_PCI_MSI
 	dw_pcie_msi_chip.dev = pp->dev;
-	dw_pci.msi_ctrl = &dw_pcie_msi_chip;
 #endif
 
 	dw_pci.nr_controllers = 1;
@@ -708,8 +707,9 @@ static struct pci_bus *dw_pcie_scan_bus(int nr, struct pci_sys_data *sys)
 	struct pcie_port *pp = sys_to_pcie(sys);
 
 	pp->root_bus_nr = sys->busnr;
-	bus = pci_scan_root_bus(pp->dev, sys->busnr,
-				  &dw_pcie_ops, sys, &sys->resources);
+	bus = pci_scan_root_bus_msi(pp->dev, sys->busnr, &dw_pcie_ops, sys,
+				    &sys->resources, &dw_pcie_msi_chip);
+
 	if (!bus)
 		return NULL;
 
diff --git a/drivers/pci/host/pcie-xilinx.c b/drivers/pci/host/pcie-xilinx.c
index f1a06a0..526807d 100644
--- a/drivers/pci/host/pcie-xilinx.c
+++ b/drivers/pci/host/pcie-xilinx.c
@@ -647,8 +647,8 @@ static struct pci_bus *xilinx_pcie_scan_bus(int nr, struct pci_sys_data *sys)
 	struct pci_bus *bus;
 
 	port->root_busno = sys->busnr;
-	bus = pci_scan_root_bus(port->dev, sys->busnr, &xilinx_pcie_ops,
-				sys, &sys->resources);
+	bus = pci_scan_root_bus_msi(port->dev, sys->busnr, &xilinx_pcie_ops,
+				sys, &sys->resources, &xilinx_pcie_msi_chip);
 
 	return bus;
 }
@@ -847,7 +847,6 @@ static int xilinx_pcie_probe(struct platform_device *pdev)
 
 #ifdef CONFIG_PCI_MSI
 	xilinx_pcie_msi_chip.dev = port->dev;
-	hw.msi_ctrl = &xilinx_pcie_msi_chip;
 #endif
 	pci_common_init_dev(dev, &hw);
 



From bhelgaas at google.com  Tue Aug  4 14:54:28 2015
From: bhelgaas at google.com (Bjorn Helgaas)
Date: Tue, 04 Aug 2015 16:54:28 -0500
Subject: [PATCH v5 5/9] PCI/MSI: Remove unused pcibios_msi_controller() hook
In-Reply-To: <20150804214234.9189.42548.stgit@bhelgaas-glaptop2.roam.corp.google.com>
References: <20150804214234.9189.42548.stgit@bhelgaas-glaptop2.roam.corp.google.com>
Message-ID: <20150804215428.9189.60846.stgit@bhelgaas-glaptop2.roam.corp.google.com>

From: Lorenzo Pieralisi <lorenzo.pieralisi at arm.com>

The pcibios_msi_controller() hook was only implemented by ARM, and it sets
pci_bus->msi now, so it doesn't need this hook anymore.

Remove the unused pcibios_msi_controller() hook.

[bhelgaas: changelog, split into separate patch]
Signed-off-by: Lorenzo Pieralisi <lorenzo.pieralisi at arm.com>
Signed-off-by: Bjorn Helgaas <bhelgaas at google.com>
---
 drivers/pci/msi.c |   17 +----------------
 1 file changed, 1 insertion(+), 16 deletions(-)

diff --git a/drivers/pci/msi.c b/drivers/pci/msi.c
index f66be868..0d20142 100644
--- a/drivers/pci/msi.c
+++ b/drivers/pci/msi.c
@@ -77,24 +77,9 @@ static void pci_msi_teardown_msi_irqs(struct pci_dev *dev)
 
 /* Arch hooks */
 
-struct msi_controller * __weak pcibios_msi_controller(struct pci_dev *dev)
-{
-	return NULL;
-}
-
-static struct msi_controller *pci_msi_controller(struct pci_dev *dev)
-{
-	struct msi_controller *msi_ctrl = dev->bus->msi;
-
-	if (msi_ctrl)
-		return msi_ctrl;
-
-	return pcibios_msi_controller(dev);
-}
-
 int __weak arch_setup_msi_irq(struct pci_dev *dev, struct msi_desc *desc)
 {
-	struct msi_controller *chip = pci_msi_controller(dev);
+	struct msi_controller *chip = dev->bus->msi;
 	int err;
 
 	if (!chip || !chip->setup_irq)



From bhelgaas at google.com  Tue Aug  4 14:54:35 2015
From: bhelgaas at google.com (Bjorn Helgaas)
Date: Tue, 04 Aug 2015 16:54:35 -0500
Subject: [PATCH v5 6/9] PCI: Drop references acquired by of_parse_phandle()
In-Reply-To: <20150804214234.9189.42548.stgit@bhelgaas-glaptop2.roam.corp.google.com>
References: <20150804214234.9189.42548.stgit@bhelgaas-glaptop2.roam.corp.google.com>
Message-ID: <20150804215435.9189.94410.stgit@bhelgaas-glaptop2.roam.corp.google.com>

of_parse_phandle() returns a device_node pointer with the refcount
incremented.  We should dispose of this reference when we're finished.

Drop the reference acquired by of_parse_phandle().

Signed-off-by: Bjorn Helgaas <bhelgaas at google.com>
---
 drivers/pci/host/pci-mvebu.c |    1 +
 drivers/pci/host/pci-xgene.c |    1 +
 2 files changed, 2 insertions(+)

diff --git a/drivers/pci/host/pci-mvebu.c b/drivers/pci/host/pci-mvebu.c
index 70aa095..67ec5e1 100644
--- a/drivers/pci/host/pci-mvebu.c
+++ b/drivers/pci/host/pci-mvebu.c
@@ -879,6 +879,7 @@ static void mvebu_pcie_msi_enable(struct mvebu_pcie *pcie)
 		return;
 
 	pcie->msi = of_pci_find_msi_chip_by_node(msi_node);
+	of_node_put(msi_node);
 
 	if (pcie->msi)
 		pcie->msi->dev = &pcie->pdev->dev;
diff --git a/drivers/pci/host/pci-xgene.c b/drivers/pci/host/pci-xgene.c
index a9dfb70..4c2fb1f 100644
--- a/drivers/pci/host/pci-xgene.c
+++ b/drivers/pci/host/pci-xgene.c
@@ -514,6 +514,7 @@ static int xgene_pcie_msi_enable(struct pci_bus *bus)
 	if (!bus->msi)
 		return -ENODEV;
 
+	of_node_put(msi_node);
 	bus->msi->dev = &bus->dev;
 	return 0;
 }



From bhelgaas at google.com  Tue Aug  4 14:54:42 2015
From: bhelgaas at google.com (Bjorn Helgaas)
Date: Tue, 04 Aug 2015 16:54:42 -0500
Subject: [PATCH v5 7/9] PCI: xgene: Set msi_controller->dev to
 platform_device, not pci_bus
In-Reply-To: <20150804214234.9189.42548.stgit@bhelgaas-glaptop2.roam.corp.google.com>
References: <20150804214234.9189.42548.stgit@bhelgaas-glaptop2.roam.corp.google.com>
Message-ID: <20150804215442.9189.83038.stgit@bhelgaas-glaptop2.roam.corp.google.com>

Other users of struct msi_controller set msi->dev to the platform_device of
the PCI host controller, not the device of the pci_bus for the root bus.

Set X-Gene's msi_controller->dev to the PCI host controller platform_device
as other platforms do.

Signed-off-by: Bjorn Helgaas <bhelgaas at google.com>
---
 drivers/pci/host/pci-xgene.c |    7 ++++---
 1 file changed, 4 insertions(+), 3 deletions(-)

diff --git a/drivers/pci/host/pci-xgene.c b/drivers/pci/host/pci-xgene.c
index 4c2fb1f..5e0d6de 100644
--- a/drivers/pci/host/pci-xgene.c
+++ b/drivers/pci/host/pci-xgene.c
@@ -501,7 +501,8 @@ static int xgene_pcie_setup(struct xgene_pcie_port *port,
 	return 0;
 }
 
-static int xgene_pcie_msi_enable(struct pci_bus *bus)
+static int xgene_pcie_msi_enable(struct xgene_pcie_port *port,
+				 struct pci_bus *bus)
 {
 	struct device_node *msi_node;
 
@@ -515,7 +516,7 @@ static int xgene_pcie_msi_enable(struct pci_bus *bus)
 		return -ENODEV;
 
 	of_node_put(msi_node);
-	bus->msi->dev = &bus->dev;
+	bus->msi->dev = &port->dev;
 	return 0;
 }
 
@@ -560,7 +561,7 @@ static int xgene_pcie_probe_bridge(struct platform_device *pdev)
 		return -ENOMEM;
 
 	if (IS_ENABLED(CONFIG_PCI_MSI))
-		if (xgene_pcie_msi_enable(bus))
+		if (xgene_pcie_msi_enable(port, bus))
 			dev_info(port->dev, "failed to enable MSI\n");
 
 	pci_scan_child_bus(bus);



From bhelgaas at google.com  Tue Aug  4 14:54:57 2015
From: bhelgaas at google.com (Bjorn Helgaas)
Date: Tue, 04 Aug 2015 16:54:57 -0500
Subject: [PATCH v5 9/9] PCI: xgene: Use pci_scan_root_bus_msi()
In-Reply-To: <20150804214234.9189.42548.stgit@bhelgaas-glaptop2.roam.corp.google.com>
References: <20150804214234.9189.42548.stgit@bhelgaas-glaptop2.roam.corp.google.com>
Message-ID: <20150804215457.9189.27595.stgit@bhelgaas-glaptop2.roam.corp.google.com>

Previously there was no way to specify the MSI controller when creating a
new PCI root bus, so we had to create the bus, set its MSI controller, then
scan the bus.  With the new pci_scan_root_bus_msi() interface, we can
specify the MSI controller up front and get rid of that intermediate step.

Look up the MSI controller first, then use pci_scan_root_bus_msi() to
create and scan the root PCI bus.

Signed-off-by: Bjorn Helgaas <bhelgaas at google.com>
---
 drivers/pci/host/pci-xgene.c |   23 +++++++++++------------
 1 file changed, 11 insertions(+), 12 deletions(-)

diff --git a/drivers/pci/host/pci-xgene.c b/drivers/pci/host/pci-xgene.c
index 3cb58a3..514f41b 100644
--- a/drivers/pci/host/pci-xgene.c
+++ b/drivers/pci/host/pci-xgene.c
@@ -68,6 +68,7 @@
 struct xgene_pcie_port {
 	struct device_node	*node;
 	struct device		*dev;
+	struct msi_controller	*msi;
 	struct clk		*clk;
 	void __iomem		*csr_base;
 	void __iomem		*cfg_base;
@@ -501,8 +502,7 @@ static int xgene_pcie_setup(struct xgene_pcie_port *port,
 	return 0;
 }
 
-static int xgene_pcie_msi_enable(struct xgene_pcie_port *port,
-				 struct pci_bus *bus)
+static int xgene_pcie_msi_enable(struct xgene_pcie_port *port)
 {
 	struct device_node *msi_node;
 
@@ -510,12 +510,12 @@ static int xgene_pcie_msi_enable(struct xgene_pcie_port *port,
 	if (!msi_node)
 		return -ENODEV;
 
-	bus->msi = of_pci_find_msi_chip_by_node(msi_node);
-	if (!bus->msi)
+	port->msi = of_pci_find_msi_chip_by_node(msi_node);
+	if (!port->msi)
 		return -ENODEV;
 
 	of_node_put(msi_node);
-	bus->msi->dev = &port->dev;
+	port->msi->dev = &port->dev;
 	return 0;
 }
 
@@ -554,16 +554,15 @@ static int xgene_pcie_probe_bridge(struct platform_device *pdev)
 	if (ret)
 		return ret;
 
-	bus = pci_create_root_bus(&pdev->dev, 0,
-					&xgene_pcie_ops, port, &res);
-	if (!bus)
-		return -ENOMEM;
-
 	if (IS_ENABLED(CONFIG_PCI_MSI))
-		if (xgene_pcie_msi_enable(port, bus))
+		if (xgene_pcie_msi_enable(port))
 			dev_info(port->dev, "failed to enable MSI\n");
 
-	pci_scan_child_bus(bus);
+	bus = pci_scan_root_bus_msi(&pdev->dev, 0, &xgene_pcie_ops, port,
+				    &res, port->msi);
+	if (!bus)
+		return -ENOMEM;
+
 	pci_assign_unassigned_bus_resources(bus);
 	pci_bus_add_devices(bus);
 



From hdegoede at redhat.com  Tue Aug  4 15:05:02 2015
From: hdegoede at redhat.com (Hans de Goede)
Date: Wed, 5 Aug 2015 00:05:02 +0200
Subject: [PATCH] musb: sunxi: Ignore VBus errors in host-only mode
In-Reply-To: <20150804213553.GI9623@saruman.tx.rr.com>
References: <1438723553-4136-1-git-send-email-hdegoede@redhat.com>
 <20150804213553.GI9623@saruman.tx.rr.com>
Message-ID: <55C1370E.1000805@redhat.com>

Hi,

On 08/04/2015 11:35 PM, Felipe Balbi wrote:
> On Tue, Aug 04, 2015 at 11:25:53PM +0200, Hans de Goede wrote:
>> For some unclear reason sometimes we get VBus errors in host-only mode,
>> even though we do not have any vbus-detection then. Ignore these.
>>
>> Signed-off-by: Hans de Goede <hdegoede at redhat.com>
>> ---
>>   drivers/usb/musb/sunxi.c | 4 ++++
>>   1 file changed, 4 insertions(+)
>>
>> diff --git a/drivers/usb/musb/sunxi.c b/drivers/usb/musb/sunxi.c
>> index f9f6304..34ce5df 100644
>> --- a/drivers/usb/musb/sunxi.c
>> +++ b/drivers/usb/musb/sunxi.c
>> @@ -194,6 +194,10 @@ static irqreturn_t sunxi_musb_interrupt(int irq, void *__hci)
>>   		musb_writeb(musb->mregs, MUSB_FADDR, 0);
>>   	}
>>
>> +	/*  Ignore Vbus errors when in host only mode */
>> +	if (musb->port_mode == MUSB_PORT_MODE_HOST)
>> +		musb->int_usb &= ~MUSB_INTR_VBUSERROR;
>
> check with a scope if VBUS is really dropping. Host does VBUS detection
> indeed, at a minimum, for overcurrent protection. You might have
> something causing VBUS to drop and that something needs to be found,
> rather than masked.

The boards in question do not have any vbus detection, the usb-phy on
allwinner boards do not have a vbus sense pin, instead a gpio is used
in designs which use otg. Designs which use host-only mode typically
do not have any form of vbus detection at all. In this case we always
report vbus as being valid to the musb core, so I've no idea why
the musb core is still generating vbus errors.

Regards,

Hans


From bhelgaas at google.com  Tue Aug  4 14:54:20 2015
From: bhelgaas at google.com (Bjorn Helgaas)
Date: Tue, 04 Aug 2015 16:54:20 -0500
Subject: [PATCH v5 4/9] ARM/PCI: Remove msi_controller from struct pci_sys_data
In-Reply-To: <20150804214234.9189.42548.stgit@bhelgaas-glaptop2.roam.corp.google.com>
References: <20150804214234.9189.42548.stgit@bhelgaas-glaptop2.roam.corp.google.com>
Message-ID: <20150804215420.9189.22914.stgit@bhelgaas-glaptop2.roam.corp.google.com>

From: Lorenzo Pieralisi <lorenzo.pieralisi at arm.com>

ARM now uses pci_bus->msi to store the msi_controller pointer, so we don't
need to save it in struct pci_sys_data, and we don't need to implement
pcibios_msi_controller() to get it out of pci_sys_data.

Remove msi_controller from struct pci_sys_data and
pcibios_msi_controller().

[bhelgaas: changelog, split into separate patch]
Signed-off-by: Lorenzo Pieralisi <lorenzo.pieralisi at arm.com>
Signed-off-by: Bjorn Helgaas <bhelgaas at google.com>
---
 arch/arm/include/asm/mach/pci.h |    3 ---
 arch/arm/kernel/bios32.c        |   12 ------------
 2 files changed, 15 deletions(-)

diff --git a/arch/arm/include/asm/mach/pci.h b/arch/arm/include/asm/mach/pci.h
index c074e7a..8857d28 100644
--- a/arch/arm/include/asm/mach/pci.h
+++ b/arch/arm/include/asm/mach/pci.h
@@ -40,9 +40,6 @@ struct hw_pci {
  * Per-controller structure
  */
 struct pci_sys_data {
-#ifdef CONFIG_PCI_MSI
-	struct msi_controller *msi_ctrl;
-#endif
 	struct list_head node;
 	int		busnr;		/* primary bus number			*/
 	u64		mem_offset;	/* bus->cpu memory mapping offset	*/
diff --git a/arch/arm/kernel/bios32.c b/arch/arm/kernel/bios32.c
index 283bc1c..874e182 100644
--- a/arch/arm/kernel/bios32.c
+++ b/arch/arm/kernel/bios32.c
@@ -18,15 +18,6 @@
 
 static int debug_pci;
 
-#ifdef CONFIG_PCI_MSI
-struct msi_controller *pcibios_msi_controller(struct pci_dev *dev)
-{
-	struct pci_sys_data *sysdata = dev->bus->sysdata;
-
-	return sysdata->msi_ctrl;
-}
-#endif
-
 /*
  * We can't use pci_get_device() here since we are
  * called from interrupt context.
@@ -462,9 +453,6 @@ static void pcibios_init_hw(struct device *parent, struct hw_pci *hw,
 		if (WARN(!sys, "PCI: unable to allocate sys data!"))
 			break;
 
-#ifdef CONFIG_PCI_MSI
-		sys->msi_ctrl = hw->msi_ctrl;
-#endif
 		sys->busnr   = busnr;
 		sys->swizzle = hw->swizzle;
 		sys->map_irq = hw->map_irq;



From bhelgaas at google.com  Tue Aug  4 14:54:50 2015
From: bhelgaas at google.com (Bjorn Helgaas)
Date: Tue, 04 Aug 2015 16:54:50 -0500
Subject: [PATCH v5 8/9] PCI: xgene: Look for OF "msi-parent" in host
 controller, not root bus
In-Reply-To: <20150804214234.9189.42548.stgit@bhelgaas-glaptop2.roam.corp.google.com>
References: <20150804214234.9189.42548.stgit@bhelgaas-glaptop2.roam.corp.google.com>
Message-ID: <20150804215450.9189.61176.stgit@bhelgaas-glaptop2.roam.corp.google.com>

Look for the "msi-parent" in the PCI host controller OF node, not the root
bus OF node.  This makes it the same as MVEBU.

Signed-off-by: Bjorn Helgaas <bhelgaas at google.com>
---
 drivers/pci/host/pci-xgene.c |    3 +--
 1 file changed, 1 insertion(+), 2 deletions(-)

diff --git a/drivers/pci/host/pci-xgene.c b/drivers/pci/host/pci-xgene.c
index 5e0d6de..3cb58a3 100644
--- a/drivers/pci/host/pci-xgene.c
+++ b/drivers/pci/host/pci-xgene.c
@@ -506,8 +506,7 @@ static int xgene_pcie_msi_enable(struct xgene_pcie_port *port,
 {
 	struct device_node *msi_node;
 
-	msi_node = of_parse_phandle(bus->dev.of_node,
-					"msi-parent", 0);
+	msi_node = of_parse_phandle(port->dev.of_node, "msi-parent", 0);
 	if (!msi_node)
 		return -ENODEV;
 



From laurent.pinchart at ideasonboard.com  Tue Aug  4 15:50:45 2015
From: laurent.pinchart at ideasonboard.com (Laurent Pinchart)
Date: Wed, 05 Aug 2015 01:50:45 +0300
Subject: [PATCH v3 0/5] iommu/arm-smmu: add support for non-pci devices
In-Reply-To: <20150728124847.GL29209@arm.com>
References: <1437463833-16112-1-git-send-email-thunder.leizhen@huawei.com>
 <55AE1F2F.3090106@arm.com> <20150728124847.GL29209@arm.com>
Message-ID: <2351780.FdaR8mZqKs@avalon>

Hi Will,

On Tuesday 28 July 2015 13:48:47 Will Deacon wrote:
> On Tue, Jul 21, 2015 at 11:30:07AM +0100, Robin Murphy wrote:
> > On 21/07/15 08:30, Zhen Lei wrote:
> > > Changelog:
> > > v2 -> v3:
> > > 1. add support for pci device hotplug, which missed in patch v2.
> > > 2. only support #iommu-cells = <1>, add corresponding description in
> > > arm,smmu-v3.txt. 3. add function find_smmu_by_device which extracted
> > > from find_smmu_by_node, to resolve> > 
> > >     the problem mentioned by Robin Murphy in [PATCH v2 7/9].
> > >     Additionally:
> > >     +    platform_set_drvdata(pdev, smmu);       //Patch v2
> > >     +	dev->archdata.iommu = smmu;             //Patch v3, dev =
> > >     &pdev->dev
> > 
> > I didn't give any Reviewed-by tags, much less to revised patches that
> > I've not even looked at yet; please see section 13 of
> > Documentation/SubmittingPatches for what the Reviewed-by tag means.
> 
> That said, it would be great if you could review the patches anyway ;)
> 
> Also, it looks like this is all based on Laurent's IOMMU probe deferral
> series which hasn't seen any movement for a while.
> 
> Laurent: are you planning to repost that, or is it worth us picking up
> the original version and bashing it into shape ourselves?

I'd really appreciate if you could take it where I left it and get into shape 
for upstream. I have no time to work on IOMMU at the moment I'm afraid :-( 
I'll try to review patches though.

-- 
Regards,

Laurent Pinchart



From heiko at sntech.de  Tue Aug  4 15:50:39 2015
From: heiko at sntech.de (Heiko =?ISO-8859-1?Q?St=FCbner?=)
Date: Wed, 05 Aug 2015 00:50:39 +0200
Subject: [PATCH v3 1/3] ARM: rockchip: rename osc_switch_to_32k variable
Message-ID: <2128609.Kb18M8K28F@diego>

The variable name is misleading, as the deep suspend mode always switches
the main supplying clock to the 32kHz source. Additionally the main
oscillator remain running in some cases, which this var indicates.

So rename it to osc_disable to clarity.

Signed-off-by: Heiko Stuebner <heiko at sntech.de>
---
 arch/arm/mach-rockchip/pm.c | 4 ++--
 1 file changed, 2 insertions(+), 2 deletions(-)

diff --git a/arch/arm/mach-rockchip/pm.c b/arch/arm/mach-rockchip/pm.c
index 892bace..2ca1170 100644
--- a/arch/arm/mach-rockchip/pm.c
+++ b/arch/arm/mach-rockchip/pm.c
@@ -96,7 +96,7 @@ static bool rk3288_slp_disable_osc(void)
 static void rk3288_slp_mode_set(int level)
 {
 	u32 mode_set, mode_set1;
-	bool osc_switch_to_32k = rk3288_slp_disable_osc();
+	bool osc_disable = rk3288_slp_disable_osc();
 
 	regmap_read(sgrf_regmap, RK3288_SGRF_CPU_CON0, &rk3288_sgrf_cpu_con0);
 	regmap_read(sgrf_regmap, RK3288_SGRF_SOC_CON0, &rk3288_sgrf_soc_con0);
@@ -140,7 +140,7 @@ static void rk3288_slp_mode_set(int level)
 			    BIT(PMU_DDR1IO_RET_EN) | BIT(PMU_DDR0IO_RET_EN) |
 			    BIT(PMU_ALIVE_USE_LF) | BIT(PMU_PLL_PD_EN);
 
-		if (osc_switch_to_32k)
+		if (osc_disable)
 			mode_set |= BIT(PMU_OSC_24M_DIS);
 
 		mode_set1 |= BIT(PMU_CLR_ALIVE) | BIT(PMU_CLR_BUS) |
-- 
2.1.4




From heiko at sntech.de  Tue Aug  4 15:51:16 2015
From: heiko at sntech.de (Heiko =?ISO-8859-1?Q?St=FCbner?=)
Date: Wed, 05 Aug 2015 00:51:16 +0200
Subject: [PATCH v3 2/3] ARM: rockchip: set correct stabilization thresholds in
 suspend
In-Reply-To: <2128609.Kb18M8K28F@diego>
References: <2128609.Kb18M8K28F@diego>
Message-ID: <1709899.JJDRtF09u7@diego>

Currently the stabilization thresholds for the oscillator and external pmu
are statically set to 30ms based on a 32kHz clock rate. This leaves out the
case when we don't switch to the 32kHz clock when only entering the shallow
suspend mode where the logic keeps running.

So, set the correct threshold after we have determined if we switch to the
32kHz clock or stay with the 24MHz one. Also set the oscillator-
stabilization to 0 if it is kept running during suspend, as it of course
does not need to stabilize then.

Reported-by: Chris Zhong <zyw at rock-chips.com>
Signed-off-by: Heiko Stuebner <heiko at sntech.de>
---
changes since v2:
- describe 32kHz vs 24MHz
- don't wait for oscillator stabilization if it's still running,
  as explained by Chris Zhong in v2
changes since v1:
- 24MHz oriented threshold is only needed in shallow suspend, the deep
  suspend always switches to 32kHz and only leaves the 24MHz oscillator
  running if needed for stuff like usb wakeup

 arch/arm/mach-rockchip/pm.c | 22 +++++++++++++++++++---
 arch/arm/mach-rockchip/pm.h |  4 ----
 2 files changed, 19 insertions(+), 7 deletions(-)

diff --git a/arch/arm/mach-rockchip/pm.c b/arch/arm/mach-rockchip/pm.c
index 2ca1170..c11a30b 100644
--- a/arch/arm/mach-rockchip/pm.c
+++ b/arch/arm/mach-rockchip/pm.c
@@ -145,6 +145,19 @@ static void rk3288_slp_mode_set(int level)
 
 		mode_set1 |= BIT(PMU_CLR_ALIVE) | BIT(PMU_CLR_BUS) |
 			     BIT(PMU_CLR_PERI) | BIT(PMU_CLR_DMA);
+
+		/*
+		 * In deep suspend we use PMU_PMU_USE_LF to let the rk3288
+		 * switch its main clock supply to the alternative 32kHz
+		 * source. Therefore set 30ms on a 32kHz clock for pmic
+		 * stabilization. Similar 30ms on 24MHz for the other
+		 * mode below.
+		 */
+		regmap_write(pmu_regmap, RK3288_PMU_STABL_CNT, 32 * 30);
+
+		/* only wait for stabilization, if we turned the osc off */
+		regmap_write(pmu_regmap, RK3288_PMU_OSC_CNT,
+					 osc_disable ? 32 * 30 : 0);
 	} else {
 		/*
 		 * arm off, logic normal
@@ -152,6 +165,12 @@ static void rk3288_slp_mode_set(int level)
 		 * wakeup will be error
 		 */
 		mode_set |= BIT(PMU_CLK_CORE_SRC_GATE_EN);
+
+		/* 30ms on a 24MHz clock for pmic stabilization */
+		regmap_write(pmu_regmap, RK3288_PMU_STABL_CNT, 24000 * 30);
+
+		/* oscillator is still running, so no need to wait */
+		regmap_write(pmu_regmap, RK3288_PMU_OSC_CNT, 0);
 	}
 
 	regmap_write(pmu_regmap, RK3288_PMU_PWRMODE_CON, mode_set);
@@ -262,9 +281,6 @@ static int rk3288_suspend_init(struct device_node *np)
 	memcpy(rk3288_bootram_base, rockchip_slp_cpu_resume,
 	       rk3288_bootram_sz);
 
-	regmap_write(pmu_regmap, RK3288_PMU_OSC_CNT, OSC_STABL_CNT_THRESH);
-	regmap_write(pmu_regmap, RK3288_PMU_STABL_CNT, PMU_STABL_CNT_THRESH);
-
 	return 0;
 }
 
diff --git a/arch/arm/mach-rockchip/pm.h b/arch/arm/mach-rockchip/pm.h
index b6494c2..8a55ee2 100644
--- a/arch/arm/mach-rockchip/pm.h
+++ b/arch/arm/mach-rockchip/pm.h
@@ -62,10 +62,6 @@ static inline void rockchip_suspend_init(void)
 /* PMU_WAKEUP_CFG1 bits */
 #define PMU_ARMINT_WAKEUP_EN		BIT(0)
 
-/* wait 30ms for OSC stable and 30ms for pmic stable */
-#define OSC_STABL_CNT_THRESH	(32 * 30)
-#define PMU_STABL_CNT_THRESH	(32 * 30)
-
 enum rk3288_pwr_mode_con {
 	PMU_PWR_MODE_EN = 0,
 	PMU_CLK_CORE_SRC_GATE_EN,
-- 
2.1.4




From heiko at sntech.de  Tue Aug  4 15:51:43 2015
From: heiko at sntech.de (Heiko =?ISO-8859-1?Q?St=FCbner?=)
Date: Wed, 05 Aug 2015 00:51:43 +0200
Subject: [PATCH v3 3/3] ARM: rockchip: enable PMU_GPIOINT_WAKEUP_EN when
 entering shallow suspend
In-Reply-To: <2128609.Kb18M8K28F@diego>
References: <2128609.Kb18M8K28F@diego>
Message-ID: <1544453.8uqOvAiDmD@diego>

PMU_GPIOINT_WAKEUP_EN seems needed when entering the shallow suspend
(with logic staying on) but does not seem to be needed for the deep
suspend for unknown reasons.
Testing revealed that this setting really is necessary to reliably
resume the veyron devices from suspend.

Reported-by: Chris Zhong <zyw at rock-chips.com>
Signed-off-by: Heiko Stuebner <heiko at sntech.de>
---
 arch/arm/mach-rockchip/pm.c | 9 ++++++---
 arch/arm/mach-rockchip/pm.h | 1 +
 2 files changed, 7 insertions(+), 3 deletions(-)

diff --git a/arch/arm/mach-rockchip/pm.c b/arch/arm/mach-rockchip/pm.c
index c11a30b..156cd23 100644
--- a/arch/arm/mach-rockchip/pm.c
+++ b/arch/arm/mach-rockchip/pm.c
@@ -123,9 +123,6 @@ static void rk3288_slp_mode_set(int level)
 	regmap_write(sgrf_regmap, RK3288_SGRF_FAST_BOOT_ADDR,
 		     rk3288_bootram_phy);
 
-	regmap_write(pmu_regmap, RK3288_PMU_WAKEUP_CFG1,
-		     PMU_ARMINT_WAKEUP_EN);
-
 	mode_set = BIT(PMU_GLOBAL_INT_DISABLE) | BIT(PMU_L2FLUSH_EN) |
 		   BIT(PMU_SREF0_ENTER_EN) | BIT(PMU_SREF1_ENTER_EN) |
 		   BIT(PMU_DDR0_GATING_EN) | BIT(PMU_DDR1_GATING_EN) |
@@ -146,6 +143,9 @@ static void rk3288_slp_mode_set(int level)
 		mode_set1 |= BIT(PMU_CLR_ALIVE) | BIT(PMU_CLR_BUS) |
 			     BIT(PMU_CLR_PERI) | BIT(PMU_CLR_DMA);
 
+		regmap_write(pmu_regmap, RK3288_PMU_WAKEUP_CFG1,
+			     PMU_ARMINT_WAKEUP_EN);
+
 		/*
 		 * In deep suspend we use PMU_PMU_USE_LF to let the rk3288
 		 * switch its main clock supply to the alternative 32kHz
@@ -166,6 +166,9 @@ static void rk3288_slp_mode_set(int level)
 		 */
 		mode_set |= BIT(PMU_CLK_CORE_SRC_GATE_EN);
 
+		regmap_write(pmu_regmap, RK3288_PMU_WAKEUP_CFG1,
+			     PMU_ARMINT_WAKEUP_EN | PMU_GPIOINT_WAKEUP_EN);
+
 		/* 30ms on a 24MHz clock for pmic stabilization */
 		regmap_write(pmu_regmap, RK3288_PMU_STABL_CNT, 24000 * 30);
 
diff --git a/arch/arm/mach-rockchip/pm.h b/arch/arm/mach-rockchip/pm.h
index 8a55ee2..b5af26f 100644
--- a/arch/arm/mach-rockchip/pm.h
+++ b/arch/arm/mach-rockchip/pm.h
@@ -61,6 +61,7 @@ static inline void rockchip_suspend_init(void)
 
 /* PMU_WAKEUP_CFG1 bits */
 #define PMU_ARMINT_WAKEUP_EN		BIT(0)
+#define PMU_GPIOINT_WAKEUP_EN		BIT(3)
 
 enum rk3288_pwr_mode_con {
 	PMU_PWR_MODE_EN = 0,
-- 
2.1.4




From balbi at ti.com  Tue Aug  4 15:57:22 2015
From: balbi at ti.com (Felipe Balbi)
Date: Tue, 4 Aug 2015 17:57:22 -0500
Subject: [PATCH] musb: sunxi: Ignore VBus errors in host-only mode
In-Reply-To: <55C1370E.1000805@redhat.com>
References: <1438723553-4136-1-git-send-email-hdegoede@redhat.com>
 <20150804213553.GI9623@saruman.tx.rr.com>
 <55C1370E.1000805@redhat.com>
Message-ID: <20150804225722.GA6802@saruman.tx.rr.com>

Hi,

On Wed, Aug 05, 2015 at 12:05:02AM +0200, Hans de Goede wrote:
> Hi,
> 
> On 08/04/2015 11:35 PM, Felipe Balbi wrote:
> >On Tue, Aug 04, 2015 at 11:25:53PM +0200, Hans de Goede wrote:
> >>For some unclear reason sometimes we get VBus errors in host-only mode,
> >>even though we do not have any vbus-detection then. Ignore these.
> >>
> >>Signed-off-by: Hans de Goede <hdegoede at redhat.com>
> >>---
> >>  drivers/usb/musb/sunxi.c | 4 ++++
> >>  1 file changed, 4 insertions(+)
> >>
> >>diff --git a/drivers/usb/musb/sunxi.c b/drivers/usb/musb/sunxi.c
> >>index f9f6304..34ce5df 100644
> >>--- a/drivers/usb/musb/sunxi.c
> >>+++ b/drivers/usb/musb/sunxi.c
> >>@@ -194,6 +194,10 @@ static irqreturn_t sunxi_musb_interrupt(int irq, void *__hci)
> >>  		musb_writeb(musb->mregs, MUSB_FADDR, 0);
> >>  	}
> >>
> >>+	/*  Ignore Vbus errors when in host only mode */
> >>+	if (musb->port_mode == MUSB_PORT_MODE_HOST)
> >>+		musb->int_usb &= ~MUSB_INTR_VBUSERROR;
> >
> >check with a scope if VBUS is really dropping. Host does VBUS detection
> >indeed, at a minimum, for overcurrent protection. You might have
> >something causing VBUS to drop and that something needs to be found,
> >rather than masked.
> 
> The boards in question do not have any vbus detection, the usb-phy on
> allwinner boards do not have a vbus sense pin, instead a gpio is used
> in designs which use otg. Designs which use host-only mode typically
> do not have any form of vbus detection at all. In this case we always
> report vbus as being valid to the musb core, so I've no idea why
> the musb core is still generating vbus errors.

PHY must tell MUSB about VBUS level using either ULPI or UTMI+. I'd
check to see if the PHY is at fault, at least.

-- 
balbi
-------------- next part --------------
A non-text attachment was scrubbed...
Name: signature.asc
Type: application/pgp-signature
Size: 819 bytes
Desc: Digital signature
URL: <http://lists.infradead.org/pipermail/linux-arm-kernel/attachments/20150804/573864e2/attachment.sig>

From bhelgaas at google.com  Tue Aug  4 15:58:12 2015
From: bhelgaas at google.com (Bjorn Helgaas)
Date: Tue, 4 Aug 2015 17:58:12 -0500
Subject: [PATCH v5 7/9] PCI: xgene: Set msi_controller->dev to
 platform_device, not pci_bus
In-Reply-To: <20150804215442.9189.83038.stgit@bhelgaas-glaptop2.roam.corp.google.com>
References: <20150804214234.9189.42548.stgit@bhelgaas-glaptop2.roam.corp.google.com>
 <20150804215442.9189.83038.stgit@bhelgaas-glaptop2.roam.corp.google.com>
Message-ID: <20150804225812.GD17327@google.com>

On Tue, Aug 04, 2015 at 04:54:42PM -0500, Bjorn Helgaas wrote:
> Other users of struct msi_controller set msi->dev to the platform_device of
> the PCI host controller, not the device of the pci_bus for the root bus.
> 
> Set X-Gene's msi_controller->dev to the PCI host controller platform_device
> as other platforms do.
> 
> Signed-off-by: Bjorn Helgaas <bhelgaas at google.com>
> ---
>  drivers/pci/host/pci-xgene.c |    7 ++++---
>  1 file changed, 4 insertions(+), 3 deletions(-)
> 
> diff --git a/drivers/pci/host/pci-xgene.c b/drivers/pci/host/pci-xgene.c
> index 4c2fb1f..5e0d6de 100644
> --- a/drivers/pci/host/pci-xgene.c
> +++ b/drivers/pci/host/pci-xgene.c
> @@ -501,7 +501,8 @@ static int xgene_pcie_setup(struct xgene_pcie_port *port,
>  	return 0;
>  }
>  
> -static int xgene_pcie_msi_enable(struct pci_bus *bus)
> +static int xgene_pcie_msi_enable(struct xgene_pcie_port *port,
> +				 struct pci_bus *bus)
>  {
>  	struct device_node *msi_node;
>  
> @@ -515,7 +516,7 @@ static int xgene_pcie_msi_enable(struct pci_bus *bus)
>  		return -ENODEV;
>  
>  	of_node_put(msi_node);
> -	bus->msi->dev = &bus->dev;
> +	bus->msi->dev = &port->dev;

Thomas, the surrounding code here and in mvebu_pcie_msi_enable() looks like
this:

  pcie->msi = of_pci_find_msi_chip_by_node(msi_node);
  pcie->msi->dev = &pcie->pdev->dev;

It seems sort of strange to search for a struct msi_controller, then set
the "dev" field inside it.  This code isn't really the owner of the
msi_controller, and it seems like in principle at least, the
of_pci_find_msi_chip_by_node() interface could be used by several clients.
Then it's not clear which one of them should update msi->dev.

It would make more sense to me if the caller of of_pci_msi_chip_add() set
the msi->dev field.  But I don't know whether that's feasible.  I don't
even know what msi->dev is used for.

Bjorn


From bhelgaas at google.com  Tue Aug  4 16:00:50 2015
From: bhelgaas at google.com (Bjorn Helgaas)
Date: Tue, 4 Aug 2015 18:00:50 -0500
Subject: [PATCH v5 0/9] ARM: PCI: kill pcibios_msi_controller()
In-Reply-To: <20150804214234.9189.42548.stgit@bhelgaas-glaptop2.roam.corp.google.com>
References: <20150804214234.9189.42548.stgit@bhelgaas-glaptop2.roam.corp.google.com>
Message-ID: <20150804230050.GE17327@google.com>

On Tue, Aug 04, 2015 at 04:53:48PM -0500, Bjorn Helgaas wrote:
> The first 5 patches here are essentially the same as Lorenzo's v4 posting
> at
> http://lkml.kernel.org/1438169598-24490-1-git-send-email-lorenzo.pieralisi at arm.com
> 
> I added some at the end to fix what look like some X-Gene bugs to me, and
> to make X-Gene use pci_scan_root_bus_msi() like the other drivers that use
> msi_controller.
> 
> v4->v5 changes:
> - Declare pci_scan_root_bus_msi() in drivers/pci/pci.h instead of
>   include/linux/pci.h.  I like the idea, but I hope we can replace this and
>   other "scan_root_bus" interfaces with a single, more-generic interface,
>   so I'd rather not expose this one widely.

This is one thing I screwed up already.  pci_scan_root_bus_msi() can't be
declared in drivers/pci/pci.h because that's not visible to
arch/arm/kernel/bios32.c.

In case anybody wants to try it, I updated the branch here:
https://git.kernel.org/cgit/linux/kernel/git/helgaas/pci.git/log/?h=pci/enumeration


From linux at arm.linux.org.uk  Tue Aug  4 16:01:53 2015
From: linux at arm.linux.org.uk (Russell King - ARM Linux)
Date: Wed, 5 Aug 2015 00:01:53 +0100
Subject: [PATCH v2] drm/i2c: tda998x: Fix bad checksum of the HDMI AVI
 infoframe
In-Reply-To: <20150804080557.58244c7c@armhf>
References: <E1ZK5bb-00079F-WC@bombadil.infradead.org>
 <20150804080557.58244c7c@armhf>
Message-ID: <20150804230153.GT7557@n2100.arm.linux.org.uk>

On Tue, Aug 04, 2015 at 08:05:57AM +0200, Jean-Francois Moine wrote:
> On Tue, 28 Jul 2015 15:59:17 +0200
> Jean-Francois Moine <moinejf at free.fr> wrote:
> 
> > Using hdmi_avi_infoframe_pack() to create the AVI infoframe calculates
> > the checksum of the frame and breaks the second calculation which is
> > done in tda998x_write_if(). Then the HDMI AVI frame is wrong and
> > the display device does not handle correctly the video frames.
> > 
> > Fixes: 8c7a075da9f7980c ("use drm_hdmi_avi_infoframe_from_display_mode()")
> > Signed-off-by: Jean-Francois Moine <moinejf at free.fr>
> 
> Ping!

I applied the patch a while back (July 17th to be exact) and in the queue
to be sent - I'll update the commit message prior to doing that.  Thanks.

-- 
FTTC broadband for 0.8mile line: currently at 10.5Mbps down 400kbps up
according to speedtest.net.


From santosh.shilimkar at oracle.com  Tue Aug  4 16:09:27 2015
From: santosh.shilimkar at oracle.com (santosh.shilimkar at oracle.com)
Date: Tue, 04 Aug 2015 16:09:27 -0700
Subject: [Resend: PATCH] ARM: keystone: add documentation for SoCs and EVMs
In-Reply-To: <55C112E9.6020709@ti.com>
References: <1438706203-3748-1-git-send-email-m-karicheri2@ti.com>
 <55C10F2D.9050805@oracle.com> <55C112E9.6020709@ti.com>
Message-ID: <55C14627.4090901@oracle.com>

On 8/4/15 12:30 PM, Murali Karicheri wrote:
> On 08/04/2015 03:14 PM, santosh shilimkar wrote:
>> On 8/4/2015 9:36 AM, Murali Karicheri wrote:
>>> Currently there is no general documentation on Keystone SoCs in the
>>> Linux Documentation folder of the source tree. This patch adds some
>>> essential documentation with links to help users of Keystone Linux and
>>> also provide links to existing documents where necessary.
>>>
>>> Signed-off-by: Murali Karicheri <m-karicheri2 at ti.com>
>>> ---
>> Good writeup Murali. This will be handy.
>> I can queue this up via arm-soc for 4.3 if the doc maintainers are
>> happy with it.
>>
>> Thanks !!
>>

>
> Thanks. BTW, there is one more DTS update for netcp from Wingman which
> will be posted soon. FYI. Also one from me as there is a OSR clock
> missing in K2L netcp binding.
>
Sounds good. Thanks for the note.

Regards,
Santosh


From boris.ostrovsky at oracle.com  Tue Aug  4 16:16:45 2015
From: boris.ostrovsky at oracle.com (Boris Ostrovsky)
Date: Tue, 04 Aug 2015 19:16:45 -0400
Subject: [PATCH v2 4/8] xen: Use the correctly the Xen memory terminologies
In-Reply-To: <1438711972-18752-5-git-send-email-julien.grall@citrix.com>
References: <1438711972-18752-1-git-send-email-julien.grall@citrix.com>
 <1438711972-18752-5-git-send-email-julien.grall@citrix.com>
Message-ID: <55C147DD.7000600@oracle.com>

On 08/04/2015 02:12 PM, Julien Grall wrote:
>   
>   /*
>    * We detect special mappings in one of two ways:
> @@ -217,9 +232,13 @@ static inline unsigned long bfn_to_local_pfn(unsigned long mfn)
>   
>   /* VIRT <-> MACHINE conversion */
>   #define virt_to_machine(v)	(phys_to_machine(XPADDR(__pa(v))))
> -#define virt_to_pfn(v)          (PFN_DOWN(__pa(v)))
>   #define virt_to_mfn(v)		(pfn_to_mfn(virt_to_pfn(v)))
>   #define mfn_to_virt(m)		(__va(mfn_to_pfn(m) << PAGE_SHIFT))
> +#define virt_to_pfn(v)          (PFN_DOWN(__pa(v)))

This looks like unnecessary change.


> diff --git a/drivers/video/fbdev/xen-fbfront.c b/drivers/video/fbdev/xen-fbfront.c
> index 09dc447..25e3cce 100644
> --- a/drivers/video/fbdev/xen-fbfront.c
> +++ b/drivers/video/fbdev/xen-fbfront.c
> @@ -539,7 +539,7 @@ static int xenfb_remove(struct xenbus_device *dev)
>   
>   static unsigned long vmalloc_to_mfn(void *address)
>   {
> -	return pfn_to_mfn(vmalloc_to_pfn(address));
> +	return pfn_to_gfn(vmalloc_to_pfn(address));
>   }

Are you sure? This will return vmalloc_to_pfn(address)).


-boris


From lina.iyer at linaro.org  Tue Aug  4 16:35:30 2015
From: lina.iyer at linaro.org (Lina Iyer)
Date: Tue,  4 Aug 2015 17:35:30 -0600
Subject: [PATCH 0/9] ARM: PM / Domains: Generic PM domains for CPUs/Clusters
Message-ID: <1438731339-58317-1-git-send-email-lina.iyer@linaro.org>

Changes since RFC v2 [2]:

- Fix memory not released on error in pm_genpd_add_subdomain()
- Reworded commit texts and documentation
- Add Documentation for CPU PM domain and device tree
- Clean up CPU PD initialization code
- Add runtime PM support for CPU idle and hotplug instead of notifications
- Allow platform drivers to register for CPU PD callbacks 
- Send CPU_PM notifications for cluster from the common code.
- Not including platform code as part of this series. Will submit separately.
- Rebased on top of linux-next
- Minor fix to comment in CPU_PM

Changes since RFC v1 [1]:

- Address review comments on v1.
- Incorporate Kevin's arch/arm/domain.c changes
- Drop drivers/base/power/cpu_domain.c
- Rebase on top of linux-next (to date)
- Reference implementation added.

This patchset fashions CPU clusters as generic PM domains. CPUs in most new
SOCs are grouped together as clusters, along with some supporting hardware,
GIC, L2 caches etc. When the CPUs in the cluster are powered off, these
hardware may also be powered off.

Generic PM domain  framework provides the necessary backend to build a cluster
hierarchy through devices, domains and nested domains. When devices and
sub-domains of a genpd are suspended, the genpd may also be suspended and
resumed before the first of the devices resumes. This works well for devices
and domains that operate in process context.

CPU idle operates with IRQs disabled. IRQs are disabled early in the CPU idle
operation and therefore any activity related to CPU's idle cannot sleep. The
cluster hardware has to support atomic operations if they are to be powered
on/off, along with the CPU. The limitation in using genpd framework for cluster
idle, is that genpd inherently uses mutexes for locking PM domains during
runtime suspend and resume and therefore may sleep during these operations. If
this limitation were to be removed, CPU clusters can be represented as devices
attached to a PM domain and when the CPUs are in runtime idle, the PM domain
can also be suspended.

The approach here is simple, allow genpd domains to specify the type of locking
the domain would use. A genpd that can suspend and resume in an IRQ safe
context, would initialize a spinlock as the genpd lock instead of a mutex.
Therefore, IRQ safe devices may initiate a genpd suspend when the last active
device goes idle. In a CPU domain, the last CPU powering down, may now program
the domain hardware to suspend, when the CPU enters idle. Thus when all the
CPUs are in idle, the domain and therefore the caches, VFP, GIC, Coresight,
power controller and other peripheral hardware may also be in a low power
state. This can save a considerable amount of runtime power.

The ARM common code defines generic PM domains for all domains that are
compatible with arm,pd. CPUs that are consumers of those domains are attached
to the genpd. When the last of the CPU notifies runtime PM of suspend, the
genpd may also be suspended. The common code currently notifies CPU_PM of
cpu_cluster_pm_enter and cpu_cluster_pm_exit, when any CPU resumes from idle.

With the help of __init section macro, platform drivers may register their
platform specific handlers for the domain power on/off callback. Match is made
when a domain provider with the same compatible flag and supporting arm,pd is
found in the DT. The common code will relay genpd power_on and power_off
callbacks to the platform for architecture specific operations.

Thanks,
Lina

[1]. http://www.spinics.net/lists/arm-kernel/msg423430.html
[2]. http://lists.infradead.org/pipermail/linux-arm-kernel/2015-June/352787.html

Lina Iyer (9):
  PM / Domains: Allocate memory outside domain locks
  PM / Domains: Remove dev->driver check for runtime PM
  PM / Domains: Support IRQ safe PM domains
  kernel/cpu_pm: fix cpu_cluster_pm_exit comment
  ARM: common: Introduce PM domains for CPUs/clusters
  ARM: domain: Add platform handlers for CPU PM domains
  ARM: cpuidle: Add runtime PM support for CPU idle
  ARM64: smp: Add runtime PM support for CPU hotplug
  ARM: smp: Add runtime PM support for CPU hotplug

 Documentation/arm/cpu-domains.txt                  |  75 +++++++
 .../devicetree/bindings/arm/cpudomains.txt         |  23 ++
 Documentation/power/devices.txt                    |  11 +-
 arch/arm/common/Makefile                           |   1 +
 arch/arm/common/domains.c                          | 203 ++++++++++++++++++
 arch/arm/include/asm/arm-pd.h                      |  30 +++
 arch/arm/kernel/smp.c                              |  18 +-
 arch/arm64/kernel/smp.c                            |  16 ++
 drivers/base/power/domain.c                        | 232 +++++++++++++++------
 drivers/cpuidle/cpuidle-arm.c                      |  10 +
 include/asm-generic/vmlinux.lds.h                  |   2 +
 include/linux/pm_domain.h                          |  11 +-
 kernel/cpu_pm.c                                    |   2 +-
 13 files changed, 571 insertions(+), 63 deletions(-)
 create mode 100644 Documentation/arm/cpu-domains.txt
 create mode 100644 Documentation/devicetree/bindings/arm/cpudomains.txt
 create mode 100644 arch/arm/common/domains.c
 create mode 100644 arch/arm/include/asm/arm-pd.h

-- 
2.1.4



From lina.iyer at linaro.org  Tue Aug  4 16:35:31 2015
From: lina.iyer at linaro.org (Lina Iyer)
Date: Tue,  4 Aug 2015 17:35:31 -0600
Subject: [PATCH 1/9] PM / Domains: Allocate memory outside domain locks
In-Reply-To: <1438731339-58317-1-git-send-email-lina.iyer@linaro.org>
References: <1438731339-58317-1-git-send-email-lina.iyer@linaro.org>
Message-ID: <1438731339-58317-2-git-send-email-lina.iyer@linaro.org>

In preparation for supporting IRQ-safe domains, allocate domain data
outside the domain locks. These functions are not called in an atomic
context, so we can always allocate memory using GFP_KERNEL. By
allocating memory before the locks, we can safely lock the domain using
spinlocks instead of mutexes.

Cc: Ulf Hansson <ulf.hansson at linaro.org>
Cc: Rafael J. Wysocki <rjw at rjwysocki.net>
Cc: Kevin Hilman <khilman at linaro.org>
Cc: Geert Uytterhoeven <geert at linux-m68k.org>
Cc: Krzysztof Koz?owski <k.kozlowski at samsung.com>
Signed-off-by: Lina Iyer <lina.iyer at linaro.org>
---
 drivers/base/power/domain.c | 30 +++++++++++++++---------------
 1 file changed, 15 insertions(+), 15 deletions(-)

diff --git a/drivers/base/power/domain.c b/drivers/base/power/domain.c
index 7666a1c..5fd1306 100644
--- a/drivers/base/power/domain.c
+++ b/drivers/base/power/domain.c
@@ -1382,13 +1382,17 @@ int pm_genpd_remove_device(struct generic_pm_domain *genpd,
 int pm_genpd_add_subdomain(struct generic_pm_domain *genpd,
 			   struct generic_pm_domain *subdomain)
 {
-	struct gpd_link *link;
+	struct gpd_link *link, *itr;
 	int ret = 0;
 
 	if (IS_ERR_OR_NULL(genpd) || IS_ERR_OR_NULL(subdomain)
 	    || genpd == subdomain)
 		return -EINVAL;
 
+	link = kzalloc(sizeof(*link), GFP_KERNEL);
+	if (!link)
+		return -ENOMEM;
+
 	mutex_lock(&genpd->lock);
 	mutex_lock_nested(&subdomain->lock, SINGLE_DEPTH_NESTING);
 
@@ -1398,18 +1402,13 @@ int pm_genpd_add_subdomain(struct generic_pm_domain *genpd,
 		goto out;
 	}
 
-	list_for_each_entry(link, &genpd->master_links, master_node) {
-		if (link->slave == subdomain && link->master == genpd) {
+	list_for_each_entry(itr, &genpd->master_links, master_node) {
+		if (itr->slave == subdomain && itr->master == genpd) {
 			ret = -EINVAL;
 			goto out;
 		}
 	}
 
-	link = kzalloc(sizeof(*link), GFP_KERNEL);
-	if (!link) {
-		ret = -ENOMEM;
-		goto out;
-	}
 	link->master = genpd;
 	list_add_tail(&link->master_node, &genpd->master_links);
 	link->slave = subdomain;
@@ -1420,7 +1419,8 @@ int pm_genpd_add_subdomain(struct generic_pm_domain *genpd,
  out:
 	mutex_unlock(&subdomain->lock);
 	mutex_unlock(&genpd->lock);
-
+	if (ret)
+		kfree(link);
 	return ret;
 }
 
@@ -1511,17 +1511,17 @@ int pm_genpd_attach_cpuidle(struct generic_pm_domain *genpd, int state)
 	if (IS_ERR_OR_NULL(genpd) || state < 0)
 		return -EINVAL;
 
+	cpuidle_data = kzalloc(sizeof(*cpuidle_data), GFP_KERNEL);
+	if (!cpuidle_data)
+		return -ENOMEM;
+
 	mutex_lock(&genpd->lock);
 
 	if (genpd->cpuidle_data) {
 		ret = -EEXIST;
-		goto out;
-	}
-	cpuidle_data = kzalloc(sizeof(*cpuidle_data), GFP_KERNEL);
-	if (!cpuidle_data) {
-		ret = -ENOMEM;
-		goto out;
+		goto err_drv;
 	}
+
 	cpuidle_drv = cpuidle_driver_ref();
 	if (!cpuidle_drv) {
 		ret = -ENODEV;
-- 
2.1.4



From lina.iyer at linaro.org  Tue Aug  4 16:35:32 2015
From: lina.iyer at linaro.org (Lina Iyer)
Date: Tue,  4 Aug 2015 17:35:32 -0600
Subject: [PATCH 2/9] PM / Domains: Remove dev->driver check for runtime PM
In-Reply-To: <1438731339-58317-1-git-send-email-lina.iyer@linaro.org>
References: <1438731339-58317-1-git-send-email-lina.iyer@linaro.org>
Message-ID: <1438731339-58317-3-git-send-email-lina.iyer@linaro.org>

Remove check for driver of a device, for runtime PM. Device may be
suspended without an explicit driver. This check seems to be vestigial
and incorrect in the current context.

Reviewed-by: Krzysztof Kozlowski <k.kozlowski at samsung.com>
Signed-off-by: Kevin Hilman <khilman at linaro.org>
Signed-off-by: Lina Iyer <lina.iyer at linaro.org>
---
 drivers/base/power/domain.c | 3 +--
 1 file changed, 1 insertion(+), 2 deletions(-)

diff --git a/drivers/base/power/domain.c b/drivers/base/power/domain.c
index 5fd1306..ef8d19f 100644
--- a/drivers/base/power/domain.c
+++ b/drivers/base/power/domain.c
@@ -394,8 +394,7 @@ static int pm_genpd_poweroff(struct generic_pm_domain *genpd)
 		if (stat > PM_QOS_FLAGS_NONE)
 			return -EBUSY;
 
-		if (pdd->dev->driver && (!pm_runtime_suspended(pdd->dev)
-		    || pdd->dev->power.irq_safe))
+		if (!pm_runtime_suspended(pdd->dev) || pdd->dev->power.irq_safe)
 			not_suspended++;
 	}
 
-- 
2.1.4



From lina.iyer at linaro.org  Tue Aug  4 16:35:34 2015
From: lina.iyer at linaro.org (Lina Iyer)
Date: Tue,  4 Aug 2015 17:35:34 -0600
Subject: [PATCH 4/9] kernel/cpu_pm: fix cpu_cluster_pm_exit comment
In-Reply-To: <1438731339-58317-1-git-send-email-lina.iyer@linaro.org>
References: <1438731339-58317-1-git-send-email-lina.iyer@linaro.org>
Message-ID: <1438731339-58317-5-git-send-email-lina.iyer@linaro.org>

cpu_cluster_pm_exit() must be sent after cpu_cluster_pm_enter() has been
sent for the cluster and before any cpu_pm_exit() notifications are sent
for any CPU.

Cc: Nicolas Pitre <nicolas.pitre at linaro.org>
Signed-off-by: Lina Iyer <lina.iyer at linaro.org>
---
 kernel/cpu_pm.c | 2 +-
 1 file changed, 1 insertion(+), 1 deletion(-)

diff --git a/kernel/cpu_pm.c b/kernel/cpu_pm.c
index 9656a3c..009cc9a 100644
--- a/kernel/cpu_pm.c
+++ b/kernel/cpu_pm.c
@@ -180,7 +180,7 @@ EXPORT_SYMBOL_GPL(cpu_cluster_pm_enter);
  * low power state that may have caused some blocks in the same power domain
  * to reset.
  *
- * Must be called after cpu_pm_exit has been called on all cpus in the power
+ * Must be called after cpu_cluster_pm_enter has been called for the power
  * domain, and before cpu_pm_exit has been called on any cpu in the power
  * domain. Notified drivers can include VFP co-processor, interrupt controller
  * and its PM extensions, local CPU timers context save/restore which
-- 
2.1.4



From lina.iyer at linaro.org  Tue Aug  4 16:35:33 2015
From: lina.iyer at linaro.org (Lina Iyer)
Date: Tue,  4 Aug 2015 17:35:33 -0600
Subject: [PATCH 3/9] PM / Domains: Support IRQ safe PM domains
In-Reply-To: <1438731339-58317-1-git-send-email-lina.iyer@linaro.org>
References: <1438731339-58317-1-git-send-email-lina.iyer@linaro.org>
Message-ID: <1438731339-58317-4-git-send-email-lina.iyer@linaro.org>

Generic Power Domains currently support turning on/off only in process
context. This prevents the usage of PM domains for domains that could be
powered on/off in a context where IRQs are disabled. Many such domains
exist today and do not get powered off, when the IRQ safe devices in
that domain are powered off, because of this limitation.

However, not all domains can operate in IRQ safe contexts. Genpd
therefore, has to support both cases where the domain may or may not
operate in IRQ safe contexts. Configuring genpd to use an appropriate
lock for that domain, would allow domains that have IRQ safe devices to
runtime suspend and resume, in atomic context.

To achieve domain specific locking, set the domain's ->flag to
GENPD_FLAG_IRQ_SAFE while defining the domain. This indicates that genpd
should use a spinlock instead of a mutex for locking the domain. Locking
is abstracted through genpd_lock() and genpd_unlock() functions that use
the flag to determine the appropriate lock to be used for that domain.
Domains that have lower latency to suspend and resume and can operate
with IRQs disabled may now be able to save power, when the component
devices and sub-domains are idle at runtime.

The restriction this imposes on the domain hierarchy is that sub-domains
and all devices in the IRQ safe domain's hierarchy also have to be IRQ
safe, so that we dont try to lock a mutex, while holding a spinlock.
Non-IRQ safe domains may continue to have devices and sub-domains that
may or may not be IRQ safe.

Cc: Ulf Hansson <ulf.hansson at linaro.org>
Cc: Kevin Hilman <khilman at linaro.org>
Cc: Rafael J. Wysocki <rjw at rjwysocki.net>
Cc: Geert Uytterhoeven <geert at linux-m68k.org>
Cc: Krzysztof Koz?owski <k.kozlowski at samsung.com>
Signed-off-by: Lina Iyer <lina.iyer at linaro.org>
---
 Documentation/power/devices.txt |  11 ++-
 drivers/base/power/domain.c     | 201 +++++++++++++++++++++++++++++++---------
 include/linux/pm_domain.h       |  11 ++-
 3 files changed, 178 insertions(+), 45 deletions(-)

diff --git a/Documentation/power/devices.txt b/Documentation/power/devices.txt
index 8ba6625..6d8318c 100644
--- a/Documentation/power/devices.txt
+++ b/Documentation/power/devices.txt
@@ -607,7 +607,16 @@ individually.  Instead, a set of devices sharing a power resource can be put
 into a low-power state together at the same time by turning off the shared
 power resource.  Of course, they also need to be put into the full-power state
 together, by turning the shared power resource on.  A set of devices with this
-property is often referred to as a power domain.
+property is often referred to as a power domain. A power domain may also be
+nested inside another power domain.
+
+Devices, by default, operate in process context and if a device can operate in
+IRQ safe context, has to be explicitly set as IRQ safe. Power domains by
+default, operate in process context but could have devices that are IRQ safe.
+Such power domains cannot be powered on/off during runtime PM. On the other
+hand, an IRQ safe PM domain that can be powered on/off and suspend or resumed
+in an atomic context, may contain IRQ safe devices. Such domains may only
+contain IRQ safe devices or IRQ safe sub-domains.
 
 Support for power domains is provided through the pm_domain field of struct
 device.  This field is a pointer to an object of type struct dev_pm_domain,
diff --git a/drivers/base/power/domain.c b/drivers/base/power/domain.c
index ef8d19f..221feb0 100644
--- a/drivers/base/power/domain.c
+++ b/drivers/base/power/domain.c
@@ -53,6 +53,74 @@
 static LIST_HEAD(gpd_list);
 static DEFINE_MUTEX(gpd_list_lock);
 
+static inline int genpd_lock_noirq(struct generic_pm_domain *genpd,
+					unsigned int subclass)
+	__acquires(&genpd->slock)
+{
+	unsigned long flags;
+
+	if (subclass > 0)
+		spin_lock_irqsave_nested(&genpd->slock, flags, subclass);
+	else
+		spin_lock_irqsave(&genpd->slock, flags);
+
+	genpd->lock_flags = flags;
+	return 0;
+}
+
+static inline void genpd_unlock_noirq(struct generic_pm_domain *genpd)
+	__releases(&genpd->slock)
+{
+	spin_unlock_irqrestore(&genpd->slock, genpd->lock_flags);
+}
+
+static inline int genpd_lock_irq(struct generic_pm_domain *genpd,
+					unsigned int subclass)
+	__acquires(&genpd->mlock)
+{
+	if (subclass > 0)
+		mutex_lock_nested(&genpd->mlock, subclass);
+	else
+		mutex_lock(&genpd->mlock);
+	return 0;
+}
+
+static inline int genpd_lock_interruptible_irq(struct generic_pm_domain *genpd)
+	__acquires(&genpd->mlock)
+{
+	return mutex_lock_interruptible(&genpd->mlock);
+}
+
+static inline void genpd_unlock_irq(struct generic_pm_domain *genpd)
+	__releases(&genpd->mlock)
+{
+	mutex_unlock(&genpd->mlock);
+}
+
+static inline int genpd_lock(struct generic_pm_domain *genpd)
+{
+	return genpd->irq_safe ? genpd_lock_noirq(genpd, 0)
+			: genpd_lock_irq(genpd, 0);
+}
+
+static inline int genpd_lock_nested(struct generic_pm_domain *genpd)
+{
+	return genpd->irq_safe ? genpd_lock_noirq(genpd, SINGLE_DEPTH_NESTING)
+			: genpd_lock_irq(genpd, SINGLE_DEPTH_NESTING);
+}
+
+static inline int genpd_lock_interruptible(struct generic_pm_domain *genpd)
+{
+	return genpd->irq_safe ? genpd_lock_noirq(genpd, 0)
+			: genpd_lock_interruptible_irq(genpd);
+}
+
+static inline void genpd_unlock(struct generic_pm_domain *genpd)
+{
+	return genpd->irq_safe ? genpd_unlock_noirq(genpd)
+			: genpd_unlock_irq(genpd);
+}
+
 static struct generic_pm_domain *pm_genpd_lookup_name(const char *domain_name)
 {
 	struct generic_pm_domain *genpd = NULL, *gpd;
@@ -273,9 +341,9 @@ int pm_genpd_poweron(struct generic_pm_domain *genpd)
 {
 	int ret;
 
-	mutex_lock(&genpd->lock);
+	genpd_lock(genpd);
 	ret = __pm_genpd_poweron(genpd);
-	mutex_unlock(&genpd->lock);
+	genpd_unlock(genpd);
 	return ret;
 }
 
@@ -335,9 +403,9 @@ static int genpd_dev_pm_qos_notifier(struct notifier_block *nb,
 		spin_unlock_irq(&dev->power.lock);
 
 		if (!IS_ERR(genpd)) {
-			mutex_lock(&genpd->lock);
+			genpd_lock(genpd);
 			genpd->max_off_time_changed = true;
-			mutex_unlock(&genpd->lock);
+			genpd_unlock(genpd);
 		}
 
 		dev = dev->parent;
@@ -394,7 +462,13 @@ static int pm_genpd_poweroff(struct generic_pm_domain *genpd)
 		if (stat > PM_QOS_FLAGS_NONE)
 			return -EBUSY;
 
-		if (!pm_runtime_suspended(pdd->dev) || pdd->dev->power.irq_safe)
+		/*
+		 * We do not want to power off the domain if the device is
+		 * not suspended or an IRQ safe device is part of this
+		 * non-IRQ safe domain.
+		 */
+		if (!pm_runtime_suspended(pdd->dev) ||
+			(pdd->dev->power.irq_safe && !genpd->irq_safe))
 			not_suspended++;
 	}
 
@@ -460,9 +534,9 @@ static void genpd_power_off_work_fn(struct work_struct *work)
 
 	genpd = container_of(work, struct generic_pm_domain, power_off_work);
 
-	mutex_lock(&genpd->lock);
+	genpd_lock(genpd);
 	pm_genpd_poweroff(genpd);
-	mutex_unlock(&genpd->lock);
+	genpd_unlock(genpd);
 }
 
 /**
@@ -500,17 +574,19 @@ static int pm_genpd_runtime_suspend(struct device *dev)
 	}
 
 	/*
-	 * If power.irq_safe is set, this routine will be run with interrupts
-	 * off, so it can't use mutexes.
+	 * If power.irq_safe is set, this routine may be run with
+	 * IRQ disabled, so suspend only if the power domain is
+	 * irq_safe.
 	 */
-	if (dev->power.irq_safe)
+	if (dev->power.irq_safe && !genpd->irq_safe)
 		return 0;
 
-	mutex_lock(&genpd->lock);
+	genpd_lock(genpd);
+
 	genpd->in_progress++;
 	pm_genpd_poweroff(genpd);
 	genpd->in_progress--;
-	mutex_unlock(&genpd->lock);
+	genpd_unlock(genpd);
 
 	return 0;
 }
@@ -535,15 +611,18 @@ static int pm_genpd_runtime_resume(struct device *dev)
 	if (IS_ERR(genpd))
 		return -EINVAL;
 
-	/* If power.irq_safe, the PM domain is never powered off. */
-	if (dev->power.irq_safe) {
+	/*
+	 * As we dont power off a non IRQ safe domain, which holds
+	 * an IRQ safe device, we dont need to restore power to it.
+	 */
+	if (dev->power.irq_safe && !genpd->irq_safe) {
 		timed = false;
 		goto out;
 	}
 
-	mutex_lock(&genpd->lock);
+	genpd_lock(genpd);
 	ret = __pm_genpd_poweron(genpd);
-	mutex_unlock(&genpd->lock);
+	genpd_unlock(genpd);
 
 	if (ret)
 		return ret;
@@ -743,14 +822,14 @@ static int pm_genpd_prepare(struct device *dev)
 	if (resume_needed(dev, genpd))
 		pm_runtime_resume(dev);
 
-	mutex_lock(&genpd->lock);
+	genpd_lock(genpd);
 
 	if (genpd->prepared_count++ == 0) {
 		genpd->suspended_count = 0;
 		genpd->suspend_power_off = genpd->status == GPD_STATE_POWER_OFF;
 	}
 
-	mutex_unlock(&genpd->lock);
+	genpd_unlock(genpd);
 
 	if (genpd->suspend_power_off) {
 		pm_runtime_put_noidle(dev);
@@ -768,12 +847,12 @@ static int pm_genpd_prepare(struct device *dev)
 
 	ret = pm_generic_prepare(dev);
 	if (ret) {
-		mutex_lock(&genpd->lock);
+		genpd_lock(genpd);
 
 		if (--genpd->prepared_count == 0)
 			genpd->suspend_power_off = false;
 
-		mutex_unlock(&genpd->lock);
+		genpd_unlock(genpd);
 		pm_runtime_enable(dev);
 	}
 
@@ -1130,13 +1209,13 @@ static void pm_genpd_complete(struct device *dev)
 	if (IS_ERR(genpd))
 		return;
 
-	mutex_lock(&genpd->lock);
+	genpd_lock(genpd);
 
 	run_complete = !genpd->suspend_power_off;
 	if (--genpd->prepared_count == 0)
 		genpd->suspend_power_off = false;
 
-	mutex_unlock(&genpd->lock);
+	genpd_unlock(genpd);
 
 	if (run_complete) {
 		pm_generic_complete(dev);
@@ -1280,11 +1359,17 @@ int __pm_genpd_add_device(struct generic_pm_domain *genpd, struct device *dev,
 	if (IS_ERR_OR_NULL(genpd) || IS_ERR_OR_NULL(dev))
 		return -EINVAL;
 
+	if (genpd->irq_safe && !dev->power.irq_safe) {
+		dev_err(dev,
+			"Devices in an IRQ safe domain have to be IRQ safe.\n");
+		return -EINVAL;
+	}
+
 	gpd_data = genpd_alloc_dev_data(dev, genpd, td);
 	if (IS_ERR(gpd_data))
 		return PTR_ERR(gpd_data);
 
-	mutex_lock(&genpd->lock);
+	genpd_lock(genpd);
 
 	if (genpd->prepared_count > 0) {
 		ret = -EAGAIN;
@@ -1301,7 +1386,7 @@ int __pm_genpd_add_device(struct generic_pm_domain *genpd, struct device *dev,
 	list_add_tail(&gpd_data->base.list_node, &genpd->dev_list);
 
  out:
-	mutex_unlock(&genpd->lock);
+	genpd_unlock(genpd);
 
 	if (ret)
 		genpd_free_dev_data(dev, gpd_data);
@@ -1345,7 +1430,7 @@ int pm_genpd_remove_device(struct generic_pm_domain *genpd,
 	gpd_data = to_gpd_data(pdd);
 	dev_pm_qos_remove_notifier(dev, &gpd_data->nb);
 
-	mutex_lock(&genpd->lock);
+	genpd_lock(genpd);
 
 	if (genpd->prepared_count > 0) {
 		ret = -EAGAIN;
@@ -1360,14 +1445,14 @@ int pm_genpd_remove_device(struct generic_pm_domain *genpd,
 
 	list_del_init(&pdd->list_node);
 
-	mutex_unlock(&genpd->lock);
+	genpd_unlock(genpd);
 
 	genpd_free_dev_data(dev, gpd_data);
 
 	return 0;
 
  out:
-	mutex_unlock(&genpd->lock);
+	genpd_unlock(genpd);
 	dev_pm_qos_add_notifier(dev, &gpd_data->nb);
 
 	return ret;
@@ -1388,12 +1473,24 @@ int pm_genpd_add_subdomain(struct generic_pm_domain *genpd,
 	    || genpd == subdomain)
 		return -EINVAL;
 
+	/*
+	 * If the domain can be powered on/off in an IRQ safe
+	 * context, ensure that the subdomain can also be
+	 * powered on/off in that context.
+	 */
+	if (genpd->irq_safe && !subdomain->irq_safe) {
+		WARN("Sub-domain (%s) in an IRQ-safe domain (%s)"
+				"have to be IRQ safe\n",
+				subdomain->name, genpd->name);
+		return -EINVAL;
+	}
+
 	link = kzalloc(sizeof(*link), GFP_KERNEL);
 	if (!link)
 		return -ENOMEM;
 
-	mutex_lock(&genpd->lock);
-	mutex_lock_nested(&subdomain->lock, SINGLE_DEPTH_NESTING);
+	genpd_lock(genpd);
+	genpd_lock_nested(subdomain);
 
 	if (genpd->status == GPD_STATE_POWER_OFF
 	    &&  subdomain->status != GPD_STATE_POWER_OFF) {
@@ -1416,8 +1513,8 @@ int pm_genpd_add_subdomain(struct generic_pm_domain *genpd,
 		genpd_sd_counter_inc(genpd);
 
  out:
-	mutex_unlock(&subdomain->lock);
-	mutex_unlock(&genpd->lock);
+	genpd_unlock(subdomain);
+	genpd_unlock(genpd);
 	if (ret)
 		kfree(link);
 	return ret;
@@ -1466,13 +1563,13 @@ int pm_genpd_remove_subdomain(struct generic_pm_domain *genpd,
 	if (IS_ERR_OR_NULL(genpd) || IS_ERR_OR_NULL(subdomain))
 		return -EINVAL;
 
-	mutex_lock(&genpd->lock);
+	genpd_lock(genpd);
 
 	list_for_each_entry(link, &genpd->master_links, master_node) {
 		if (link->slave != subdomain)
 			continue;
 
-		mutex_lock_nested(&subdomain->lock, SINGLE_DEPTH_NESTING);
+		genpd_lock_nested(subdomain);
 
 		list_del(&link->master_node);
 		list_del(&link->slave_node);
@@ -1480,13 +1577,13 @@ int pm_genpd_remove_subdomain(struct generic_pm_domain *genpd,
 		if (subdomain->status != GPD_STATE_POWER_OFF)
 			genpd_sd_counter_dec(genpd);
 
-		mutex_unlock(&subdomain->lock);
+		genpd_unlock(subdomain);
 
 		ret = 0;
 		break;
 	}
 
-	mutex_unlock(&genpd->lock);
+	genpd_unlock(genpd);
 
 	return ret;
 }
@@ -1510,11 +1607,17 @@ int pm_genpd_attach_cpuidle(struct generic_pm_domain *genpd, int state)
 	if (IS_ERR_OR_NULL(genpd) || state < 0)
 		return -EINVAL;
 
+	if (genpd->irq_safe) {
+		WARN("Domain %s is IRQ safe, cannot attach to cpuidle\n",
+				genpd->name);
+		return -EINVAL;
+	}
+
 	cpuidle_data = kzalloc(sizeof(*cpuidle_data), GFP_KERNEL);
 	if (!cpuidle_data)
 		return -ENOMEM;
 
-	mutex_lock(&genpd->lock);
+	genpd_lock(genpd);
 
 	if (genpd->cpuidle_data) {
 		ret = -EEXIST;
@@ -1541,7 +1644,7 @@ int pm_genpd_attach_cpuidle(struct generic_pm_domain *genpd, int state)
 	genpd_recalc_cpu_exit_latency(genpd);
 
  out:
-	mutex_unlock(&genpd->lock);
+	genpd_unlock(genpd);
 	return ret;
 
  err:
@@ -1578,7 +1681,7 @@ int pm_genpd_detach_cpuidle(struct generic_pm_domain *genpd)
 	if (IS_ERR_OR_NULL(genpd))
 		return -EINVAL;
 
-	mutex_lock(&genpd->lock);
+	genpd_lock(genpd);
 
 	cpuidle_data = genpd->cpuidle_data;
 	if (!cpuidle_data) {
@@ -1596,7 +1699,7 @@ int pm_genpd_detach_cpuidle(struct generic_pm_domain *genpd)
 	kfree(cpuidle_data);
 
  out:
-	mutex_unlock(&genpd->lock);
+	genpd_unlock(genpd);
 	return ret;
 }
 
@@ -1657,6 +1760,17 @@ static int pm_genpd_default_restore_state(struct device *dev)
 	return cb ? cb(dev) : 0;
 }
 
+static void genpd_lock_init(struct generic_pm_domain *genpd)
+{
+	if (genpd->flags & GENPD_FLAG_IRQ_SAFE) {
+		spin_lock_init(&genpd->slock);
+		genpd->irq_safe = true;
+	} else {
+		mutex_init(&genpd->mlock);
+		genpd->irq_safe = false;
+	}
+}
+
 /**
  * pm_genpd_init - Initialize a generic I/O PM domain object.
  * @genpd: PM domain object to initialize.
@@ -1672,7 +1786,7 @@ void pm_genpd_init(struct generic_pm_domain *genpd,
 	INIT_LIST_HEAD(&genpd->master_links);
 	INIT_LIST_HEAD(&genpd->slave_links);
 	INIT_LIST_HEAD(&genpd->dev_list);
-	mutex_init(&genpd->lock);
+	genpd_lock_init(genpd);
 	genpd->gov = gov;
 	INIT_WORK(&genpd->power_off_work, genpd_power_off_work_fn);
 	genpd->in_progress = 0;
@@ -2067,7 +2181,7 @@ static int pm_genpd_summary_one(struct seq_file *s,
 	struct gpd_link *link;
 	int ret;
 
-	ret = mutex_lock_interruptible(&genpd->lock);
+	ret = genpd_lock_interruptible(genpd);
 	if (ret)
 		return -ERESTARTSYS;
 
@@ -2087,7 +2201,8 @@ static int pm_genpd_summary_one(struct seq_file *s,
 	}
 
 	list_for_each_entry(pm_data, &genpd->dev_list, list_node) {
-		kobj_path = kobject_get_path(&pm_data->dev->kobj, GFP_KERNEL);
+		kobj_path = kobject_get_path(&pm_data->dev->kobj,
+				genpd->irq_safe ? GFP_ATOMIC : GFP_KERNEL);
 		if (kobj_path == NULL)
 			continue;
 
@@ -2098,7 +2213,7 @@ static int pm_genpd_summary_one(struct seq_file *s,
 
 	seq_puts(s, "\n");
 exit:
-	mutex_unlock(&genpd->lock);
+	genpd_unlock(genpd);
 
 	return 0;
 }
diff --git a/include/linux/pm_domain.h b/include/linux/pm_domain.h
index b2725e6..dc7cb53 100644
--- a/include/linux/pm_domain.h
+++ b/include/linux/pm_domain.h
@@ -16,9 +16,11 @@
 #include <linux/of.h>
 #include <linux/notifier.h>
 #include <linux/cpuidle.h>
+#include <linux/spinlock.h>
 
 /* Defines used for the flags field in the struct generic_pm_domain */
 #define GENPD_FLAG_PM_CLK	(1U << 0) /* PM domain uses PM clk */
+#define GENPD_FLAG_IRQ_SAFE	(1U << 1) /* PM domain operates in atomic */
 
 enum gpd_status {
 	GPD_STATE_ACTIVE = 0,	/* PM domain is active */
@@ -49,7 +51,6 @@ struct generic_pm_domain {
 	struct list_head master_links;	/* Links with PM domain as a master */
 	struct list_head slave_links;	/* Links with PM domain as a slave */
 	struct list_head dev_list;	/* List of devices */
-	struct mutex lock;
 	struct dev_power_governor *gov;
 	struct work_struct power_off_work;
 	const char *name;
@@ -74,6 +75,14 @@ struct generic_pm_domain {
 	void (*detach_dev)(struct generic_pm_domain *domain,
 			   struct device *dev);
 	unsigned int flags;		/* Bit field of configs for genpd */
+	bool irq_safe;
+	union {
+		struct mutex mlock;
+		struct {
+			spinlock_t slock;
+			unsigned long lock_flags;
+		};
+	};
 };
 
 static inline struct generic_pm_domain *pd_to_genpd(struct dev_pm_domain *pd)
-- 
2.1.4



From lina.iyer at linaro.org  Tue Aug  4 16:35:35 2015
From: lina.iyer at linaro.org (Lina Iyer)
Date: Tue,  4 Aug 2015 17:35:35 -0600
Subject: [PATCH 5/9] ARM: common: Introduce PM domains for CPUs/clusters
In-Reply-To: <1438731339-58317-1-git-send-email-lina.iyer@linaro.org>
References: <1438731339-58317-1-git-send-email-lina.iyer@linaro.org>
Message-ID: <1438731339-58317-6-git-send-email-lina.iyer@linaro.org>

Define and add Generic PM domains (genpd) for ARM CPU clusters. Many new
SoCs group CPUs as clusters. Clusters share common resources like GIC,
power rail, caches, VFP, Coresight etc. When all CPUs in the cluster are
idle, these shared resources may also be put in their idle state.

The idle time between the last CPU entering idle and a CPU resuming
execution is an opportunity for these shared resources to be powered
down. Generic PM domain provides a framework for defining such power
domains and attach devices to the domain. When the devices in the domain
are idle at runtime, the domain would also be suspended and resumed
before the first of the devices resume execution.

We define a generic PM domain for each cluster and attach CPU devices in
the cluster to that PM domain. The DT definitions for the SoC describe
this relationship. Genpd callbacks for power_on and power_off can then
be used to power up/down the shared resources for the domain.

Cc: Stephen Boyd <sboyd at codeaurora.org>
Cc: Kevin Hilman <khilman at linaro.org>
Cc: Ulf Hansson <ulf.hansson at linaro.org>
Cc: Catalin Marinas <catalin.marinas at arm.com>
Cc: Daniel Lezcano <daniel.lezcano at linaro.org>
Cc: Mark Rutland <mark.rutland at arm.com>
Cc: Lorenzo Pieralisi <lorenzo.pieralisi at arm.com>
Signed-off-by: Kevin Hilman <khilman at linaro.org>
Signed-off-by: Lina Iyer <lina.iyer at linaro.org>
---
 Documentation/arm/cpu-domains.txt                  |  49 ++++++
 .../devicetree/bindings/arm/cpudomains.txt         |  23 +++
 arch/arm/common/Makefile                           |   1 +
 arch/arm/common/domains.c                          | 166 +++++++++++++++++++++
 4 files changed, 239 insertions(+)
 create mode 100644 Documentation/arm/cpu-domains.txt
 create mode 100644 Documentation/devicetree/bindings/arm/cpudomains.txt
 create mode 100644 arch/arm/common/domains.c

diff --git a/Documentation/arm/cpu-domains.txt b/Documentation/arm/cpu-domains.txt
new file mode 100644
index 0000000..3e535b7
--- /dev/null
+++ b/Documentation/arm/cpu-domains.txt
@@ -0,0 +1,49 @@
+CPU Clusters and PM domain
+
+Newer ARM CPUs are grouped in a SoC as clusters. A cluster in addition to the
+CPUs may have caches, GIC, VFP and architecture specific power controller to
+power the cluster. A cluster may also be nested in another cluster, the
+hierarchy of which is depicted in the device tree. CPUIdle frameworks enables
+the CPUs to determine the sleep time and enter low power state to save power
+during periods of idle. CPUs in a cluster may enter and exit idle state
+independently. During the time when all the CPUs are in idle state, the
+cluster can safely be in idle state as well. When the last of the CPUs is
+powered off as a result of idle, the cluster may also be powered down, but the
+domain must be powered on before the first of the CPUs in the cluster resumes
+execution.
+
+ARM SoCs can power down the CPU and resume execution in a few uSecs and the
+domain that powers the CPU cluster also have comparable idle latencies. The
+ARM CPU WFI signal is used as a hardware trigger for the cluster hardware to
+enter their idle state. The hardware can be programmed in advance to put the
+cluster in the desired idle state befitting the wakeup latency requested by
+the CPUs. When all the CPUs in a cluster have executed their WFI instruction,
+the state machine for the power controller may put the cluster components in
+their power down or idle state. Generally, the domains would power on with the
+hardware sensing the CPU's interrupts. The domains may however, need to be
+reconfigured by the CPU to remain active, until the last CPU is ready to enter
+idle again. To power down a cluster, it is generally required to power down
+all the CPUs. The caches would also need to be flushed. The hardware state of
+some of the components may need to be saved and restored when powered back on.
+SoC vendors may also have hardware specific configuration that must be done
+before the cluster can be powered off. When the cluster is powered off,
+notifications may be sent out to other SoC components to scale down or even
+power off their resources.
+
+Power management domains represent relationship of devices and their power
+controllers. They are represented in the DT as domain consumers and providers.
+A device may have a domain provider and a domain provider may support multiple
+domain consumers. Domains like clusters, may also be nested inside one
+another. A domain that has no active consumer, may be powered off and any
+resuming consumer would trigger the domain back to active. Parent domains may
+be powered off when the child domains are powered off. ARM CPU cluster can be
+fashioned as a PM domain. When the CPU devices are powered off, the PM domain
+may be powered off.
+
+The code in Generic PM domains handles the hierarchy of devices, domains and
+the reference counting of objects leading to last man down and first man up.
+The ARM CPU domains common code defines PM domains for each CPU cluster and
+attaches the domains' CPU devices to as specified in the DT. This happens
+automatically at kernel init, when the domain is specified as compatible with
+"arm,pd". Powering on/off the common cluster hardware would also be done when
+the PM domain is runtime suspended or resumed.
diff --git a/Documentation/devicetree/bindings/arm/cpudomains.txt b/Documentation/devicetree/bindings/arm/cpudomains.txt
new file mode 100644
index 0000000..d945861
--- /dev/null
+++ b/Documentation/devicetree/bindings/arm/cpudomains.txt
@@ -0,0 +1,23 @@
+ARM CPU Power domains
+
+The device tree allows describing of CPU power domains in a SoC. In ARM SoC,
+CPUs may be grouped as clusters. A cluster may have CPUs, GIC, Coresight,
+caches, VFP and power controller and other peripheral hardware. Generally,
+when the CPUs in the cluster are idle/suspended, the shared resources may also
+be suspended and resumed before any of the CPUs resume execution.
+
+CPUs are the defined as the PM domain consumers and there is a PM domain
+provider for the CPUs. Bindings for generic PM domains (genpd) is described in
+[1].
+
+The ARM CPU PM domain follows the same binding convention as any generic PM
+domain. Additional binding properties are -
+
+- compatible:
+	Usage: required
+	Value type: <string>
+	Definition: Must also have
+			"arm,pd"
+		inorder to initialize the genpd provider as ARM CPU PM domain.
+
+[1]. Documentation/devicetree/bindings/power/power_domain.txt
diff --git a/arch/arm/common/Makefile b/arch/arm/common/Makefile
index 6ee5959..e2e2c63 100644
--- a/arch/arm/common/Makefile
+++ b/arch/arm/common/Makefile
@@ -18,3 +18,4 @@ AFLAGS_vlock.o			:= -march=armv7-a
 obj-$(CONFIG_TI_PRIV_EDMA)	+= edma.o
 obj-$(CONFIG_BL_SWITCHER)	+= bL_switcher.o
 obj-$(CONFIG_BL_SWITCHER_DUMMY_IF) += bL_switcher_dummy_if.o
+obj-$(CONFIG_PM_GENERIC_DOMAINS) += domains.o
diff --git a/arch/arm/common/domains.c b/arch/arm/common/domains.c
new file mode 100644
index 0000000..15981e9
--- /dev/null
+++ b/arch/arm/common/domains.c
@@ -0,0 +1,166 @@
+/*
+ * ARM CPU Generic PM Domain.
+ *
+ * Copyright (C) 2015 Linaro Ltd.
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License version 2 as
+ * published by the Free Software Foundation.
+ */
+
+#include <linux/kernel.h>
+#include <linux/module.h>
+#include <linux/cpu_pm.h>
+#include <linux/device.h>
+#include <linux/of_platform.h>
+#include <linux/platform_device.h>
+#include <linux/pm_domain.h>
+#include <linux/pm_runtime.h>
+#include <linux/slab.h>
+
+#define NAME_MAX 36
+
+struct arm_pm_domain {
+	struct generic_pm_domain genpd;
+};
+
+static inline
+struct arm_pm_domain *to_arm_pd(struct generic_pm_domain *d)
+{
+	return container_of(d, struct arm_pm_domain, genpd);
+}
+
+static int arm_pd_power_down(struct generic_pm_domain *genpd)
+{
+	/*
+	 * Notify CPU PM domain power down
+	 * TODO: Call the notificated directly from here.
+	 */
+	cpu_cluster_pm_enter();
+
+	return 0;
+}
+
+static int arm_pd_power_up(struct generic_pm_domain *genpd)
+{
+	/* Notify CPU PM domain power up */
+	cpu_cluster_pm_exit();
+
+	return 0;
+}
+
+static void __init run_cpu(void *unused)
+{
+	struct device *cpu_dev = get_cpu_device(smp_processor_id());
+
+	/* We are running, increment the usage count */
+	pm_runtime_get_noresume(cpu_dev);
+}
+
+static int __init arm_domain_cpu_init(void)
+{
+	int cpuid, ret;
+
+	/* Find any CPU nodes with a phandle to this power domain */
+	for_each_possible_cpu(cpuid) {
+		struct device *cpu_dev;
+		struct of_phandle_args pd_args;
+
+		cpu_dev = get_cpu_device(cpuid);
+		if (!cpu_dev) {
+			pr_warn("%s: Unable to get device for CPU%d\n",
+					__func__, cpuid);
+			return -ENODEV;
+		}
+
+		/*
+		 * We are only interested in CPUs that can be attached to
+		 * PM domains that are arm,pd compatible.
+		 */
+		ret = of_parse_phandle_with_args(cpu_dev->of_node,
+				"power-domains", "#power-domain-cells",
+				0, &pd_args);
+		if (ret) {
+			dev_dbg(cpu_dev,
+				"%s: Did not find a valid PM domain\n",
+					__func__);
+			continue;
+		}
+
+		if (!of_device_is_compatible(pd_args.np, "arm,pd")) {
+			dev_dbg(cpu_dev, "%s: does not have an ARM PD\n",
+					__func__);
+			continue;
+		}
+
+		if (cpu_online(cpuid)) {
+			pm_runtime_set_active(cpu_dev);
+			/*
+			 * Execute the below on that 'cpu' to ensure that the
+			 * reference counting is correct. Its possible that
+			 * while this code is executing, the 'cpu' may be
+			 * powered down, but we may incorrectly increment the
+			 * usage. By executing the get_cpu on the 'cpu',
+			 * we can ensure that the 'cpu' and its usage count are
+			 * matched.
+			 */
+			smp_call_function_single(cpuid, run_cpu, NULL, true);
+		} else {
+			pm_runtime_set_suspended(cpu_dev);
+		}
+		pm_runtime_irq_safe(cpu_dev);
+		pm_runtime_enable(cpu_dev);
+
+		/*
+		 * We attempt to attach the device to genpd again. We would
+		 * have failed in our earlier attempt to attach to the domain
+		 * provider as the CPU device would not have been IRQ safe,
+		 * while the domain is defined as IRQ safe. IRQ safe domains
+		 * can only have IRQ safe devices.
+		 */
+		ret = genpd_dev_pm_attach(cpu_dev);
+		if (ret) {
+			dev_warn(cpu_dev,
+				"%s: Unable to attach to power-domain: %d\n",
+				__func__, ret);
+			pm_runtime_disable(cpu_dev);
+		}
+	}
+
+	return 0;
+}
+
+static int __init arm_domain_init(void)
+{
+	struct device_node *np;
+	int count = 0;
+
+	for_each_compatible_node(np, NULL, "arm,pd") {
+		struct arm_pm_domain *pd;
+
+		if (!of_device_is_available(np))
+			continue;
+
+		pd = kzalloc(sizeof(*pd), GFP_KERNEL);
+		if (!pd)
+			return -ENOMEM;
+
+		pd->genpd.name = kstrndup(np->name, NAME_MAX, GFP_KERNEL);
+		pd->genpd.power_off = arm_pd_power_down;
+		pd->genpd.power_on = arm_pd_power_up;
+		pd->genpd.flags |= GENPD_FLAG_IRQ_SAFE;
+
+		pr_debug("adding %s as generic power domain.\n", np->full_name);
+		pm_genpd_init(&pd->genpd, &simple_qos_governor, false);
+		of_genpd_add_provider_simple(np, &pd->genpd);
+
+		count++;
+	}
+
+	/* We have ARM PD(s), attach CPUs to their domain */
+	if (count)
+		return arm_domain_cpu_init();
+
+	return 0;
+}
+device_initcall(arm_domain_init);
-- 
2.1.4



From lina.iyer at linaro.org  Tue Aug  4 16:35:38 2015
From: lina.iyer at linaro.org (Lina Iyer)
Date: Tue,  4 Aug 2015 17:35:38 -0600
Subject: [PATCH 8/9] ARM64: smp: Add runtime PM support for CPU hotplug
In-Reply-To: <1438731339-58317-1-git-send-email-lina.iyer@linaro.org>
References: <1438731339-58317-1-git-send-email-lina.iyer@linaro.org>
Message-ID: <1438731339-58317-9-git-send-email-lina.iyer@linaro.org>

Enable runtime PM for CPU devices. Do a runtime get of the CPU device
when the CPU is hotplugged in and runtime put of the CPU device when the
CPU is hotplugged off. When all the CPUs in a domain are hotplugged off,
the domain may also be powered off and cluster_pm_enter/exit()
notifications are be sent out.

Cc: Catalin Marinas <catalin.marinas at arm.com>
Cc: Mark Rutland <mark.rutland at arm.com>
Cc: Lorenzo Pieralisi <lorenzo.pieralisi at arm.com>
Signed-off-by: Lina Iyer <lina.iyer at linaro.org>
---
 arch/arm64/kernel/smp.c | 16 ++++++++++++++++
 1 file changed, 16 insertions(+)

diff --git a/arch/arm64/kernel/smp.c b/arch/arm64/kernel/smp.c
index dbdaacd..fbeeffa 100644
--- a/arch/arm64/kernel/smp.c
+++ b/arch/arm64/kernel/smp.c
@@ -135,6 +135,7 @@ asmlinkage void secondary_start_kernel(void)
 {
 	struct mm_struct *mm = &init_mm;
 	unsigned int cpu = smp_processor_id();
+	struct device *cpu_dev;
 
 	/*
 	 * All kernel threads share the same mm context; grab a
@@ -185,6 +186,11 @@ asmlinkage void secondary_start_kernel(void)
 	local_irq_enable();
 	local_async_enable();
 
+	/* We are running, enable runtime PM for the CPU. */
+	cpu_dev = get_cpu_device(cpu);
+	if (cpu_dev)
+		pm_runtime_get_sync(cpu_dev);
+
 	/*
 	 * OK, it's off to the idle thread for us
 	 */
@@ -219,6 +225,9 @@ int __cpu_disable(void)
 	unsigned int cpu = smp_processor_id();
 	int ret;
 
+	/* We dont need the CPU device anymore. */
+	pm_runtime_put_sync(get_cpu_device(cpu));
+
 	ret = op_cpu_disable(cpu);
 	if (ret)
 		return ret;
@@ -293,6 +302,13 @@ void cpu_die(void)
 {
 	unsigned int cpu = smp_processor_id();
 
+	/*
+	 * We dont need the CPU device anymore.
+	 * Lets do this before IRQs are disabled to allow
+	 * runtime PM to suspend the domain as well.
+	 */
+	pm_runtime_put_sync(get_cpu_device(cpu));
+
 	idle_task_exit();
 
 	local_irq_disable();
-- 
2.1.4



From lina.iyer at linaro.org  Tue Aug  4 16:35:37 2015
From: lina.iyer at linaro.org (Lina Iyer)
Date: Tue,  4 Aug 2015 17:35:37 -0600
Subject: [PATCH 7/9] ARM: cpuidle: Add runtime PM support for CPU idle
In-Reply-To: <1438731339-58317-1-git-send-email-lina.iyer@linaro.org>
References: <1438731339-58317-1-git-send-email-lina.iyer@linaro.org>
Message-ID: <1438731339-58317-8-git-send-email-lina.iyer@linaro.org>

Notify runtime PM when the CPU is going to be powered off in the idle
state. This allows for runtime PM suspend/resume of the CPU as well as
its  PM domain.

Cc: Daniel Lezcano <daniel.lezcano at linaro.org>
Cc: Lorenzo Pieralisi <lorenzo.pieralisi at arm.com>
Signed-off-by: Lina Iyer <lina.iyer at linaro.org>
---
 drivers/cpuidle/cpuidle-arm.c | 10 ++++++++++
 1 file changed, 10 insertions(+)

diff --git a/drivers/cpuidle/cpuidle-arm.c b/drivers/cpuidle/cpuidle-arm.c
index 545069d..ca118ed 100644
--- a/drivers/cpuidle/cpuidle-arm.c
+++ b/drivers/cpuidle/cpuidle-arm.c
@@ -11,12 +11,14 @@
 
 #define pr_fmt(fmt) "CPUidle arm: " fmt
 
+#include <linux/cpu.h>
 #include <linux/cpuidle.h>
 #include <linux/cpumask.h>
 #include <linux/cpu_pm.h>
 #include <linux/kernel.h>
 #include <linux/module.h>
 #include <linux/of.h>
+#include <linux/pm_runtime.h>
 #include <linux/slab.h>
 
 #include <asm/cpuidle.h>
@@ -37,6 +39,7 @@ static int arm_enter_idle_state(struct cpuidle_device *dev,
 				struct cpuidle_driver *drv, int idx)
 {
 	int ret;
+	struct device *cpu_dev = get_cpu_device(dev->cpu);
 
 	if (!idx) {
 		cpu_do_idle();
@@ -46,12 +49,19 @@ static int arm_enter_idle_state(struct cpuidle_device *dev,
 	ret = cpu_pm_enter();
 	if (!ret) {
 		/*
+		* Notify runtime PM as well of this cpu powering down
+		* TODO: Merge CPU_PM and runtime PM.
+		*/
+		pm_runtime_put_sync(cpu_dev);
+
+		/*
 		 * Pass idle state index to cpu_suspend which in turn will
 		 * call the CPU ops suspend protocol with idle index as a
 		 * parameter.
 		 */
 		arm_cpuidle_suspend(idx);
 
+		pm_runtime_get_sync(cpu_dev);
 		cpu_pm_exit();
 	}
 
-- 
2.1.4



From lina.iyer at linaro.org  Tue Aug  4 16:35:39 2015
From: lina.iyer at linaro.org (Lina Iyer)
Date: Tue,  4 Aug 2015 17:35:39 -0600
Subject: [PATCH 9/9] ARM: smp: Add runtime PM support for CPU hotplug
In-Reply-To: <1438731339-58317-1-git-send-email-lina.iyer@linaro.org>
References: <1438731339-58317-1-git-send-email-lina.iyer@linaro.org>
Message-ID: <1438731339-58317-10-git-send-email-lina.iyer@linaro.org>

Enable runtime PM for CPU devices. Do a runtime get of the CPU device
when the CPU is hotplugged in and a runtime put of the CPU device when
the CPU is hotplugged off. When all the CPUs in a domain are hotplugged
off, the domain may also be powered off and cluster_pm_enter/exit()
notifications are be sent out.

Cc: Catalin Marinas <catalin.marinas at arm.com>
Cc: Mark Rutland <mark.rutland at arm.com>
Cc: Lorenzo Pieralisi <lorenzo.pieralisi at arm.com>
Signed-off-by: Lina Iyer <lina.iyer at linaro.org>
---
 arch/arm/kernel/smp.c | 18 +++++++++++++++++-
 1 file changed, 17 insertions(+), 1 deletion(-)

diff --git a/arch/arm/kernel/smp.c b/arch/arm/kernel/smp.c
index 0496b48..1d614b8 100644
--- a/arch/arm/kernel/smp.c
+++ b/arch/arm/kernel/smp.c
@@ -27,6 +27,7 @@
 #include <linux/completion.h>
 #include <linux/cpufreq.h>
 #include <linux/irq_work.h>
+#include <linux/pm_runtime.h>
 
 #include <linux/atomic.h>
 #include <asm/smp.h>
@@ -137,7 +138,6 @@ int __cpu_up(unsigned int cpu, struct task_struct *idle)
 		pr_err("CPU%u: failed to boot: %d\n", cpu, ret);
 	}
 
-
 	memset(&secondary_data, 0, sizeof(secondary_data));
 	return ret;
 }
@@ -205,6 +205,9 @@ int __cpu_disable(void)
 	unsigned int cpu = smp_processor_id();
 	int ret;
 
+	/* We dont need the CPU device anymore. */
+	pm_runtime_put_sync(get_cpu_device(cpu));
+
 	ret = platform_cpu_disable(cpu);
 	if (ret)
 		return ret;
@@ -272,6 +275,13 @@ void __ref cpu_die(void)
 {
 	unsigned int cpu = smp_processor_id();
 
+	/*
+	 * We dont need the CPU device anymore.
+	 * Lets do this before IRQs are disabled to allow
+	 * runtime PM to suspend the domain as well.
+	 */
+	pm_runtime_put_sync(get_cpu_device(cpu));
+
 	idle_task_exit();
 
 	local_irq_disable();
@@ -352,6 +362,7 @@ asmlinkage void secondary_start_kernel(void)
 {
 	struct mm_struct *mm = &init_mm;
 	unsigned int cpu;
+	struct device *cpu_dev;
 
 	/*
 	 * The identity mapping is uncached (strongly ordered), so
@@ -401,6 +412,11 @@ asmlinkage void secondary_start_kernel(void)
 	local_irq_enable();
 	local_fiq_enable();
 
+	/* We are running, enable runtime PM for the CPU. */
+	cpu_dev = get_cpu_device(cpu);
+	if (cpu_dev)
+		pm_runtime_get_sync(cpu_dev);
+
 	/*
 	 * OK, it's off to the idle thread for us
 	 */
-- 
2.1.4



From lina.iyer at linaro.org  Tue Aug  4 16:35:36 2015
From: lina.iyer at linaro.org (Lina Iyer)
Date: Tue,  4 Aug 2015 17:35:36 -0600
Subject: [PATCH 6/9] ARM: domain: Add platform handlers for CPU PM domains
In-Reply-To: <1438731339-58317-1-git-send-email-lina.iyer@linaro.org>
References: <1438731339-58317-1-git-send-email-lina.iyer@linaro.org>
Message-ID: <1438731339-58317-7-git-send-email-lina.iyer@linaro.org>

In addition to the common power up/down actions of CPU PM domain core,
platforms may have additional configuration before the CPU domain can be
powered off or considered active. Allow platform drivers to register
handlers for CPU PM domains.

Platform drivers may register their callbacks against a compatible
string defined by their PM domain provider device node in the DT. At
domain init, the platform driver can initialize the platform specific
genpd attributes. The init callback would need to return successfully,
for the platform power_on/off handlers to be registered with the CPU PM
domain.

The code uses __init section to reduce memory needed for platform
handlers and therefore can be freed after the driver is initialized, a
desirable outcome for single kernel image.

Cc: Rob Herring <robh at kernel.org>
Cc: Stephen Boyd <sboyd at codeaurora.org>
Cc: Kevin Hilman <khilman at linaro.org>
Cc: Ulf Hansson <ulf.hansson at linaro.org>
Cc: Catalin Marinas <catalin.marinas at arm.com>
Cc: Mark Rutland <mark.rutland at arm.com>
Cc: Lorenzo Pieralisi <lorenzo.pieralisi at arm.com>
Signed-off-by: Lina Iyer <lina.iyer at linaro.org>
---
 Documentation/arm/cpu-domains.txt | 26 ++++++++++++++++++++++++++
 arch/arm/common/domains.c         | 37 +++++++++++++++++++++++++++++++++++++
 arch/arm/include/asm/arm-pd.h     | 30 ++++++++++++++++++++++++++++++
 include/asm-generic/vmlinux.lds.h |  2 ++
 4 files changed, 95 insertions(+)
 create mode 100644 arch/arm/include/asm/arm-pd.h

diff --git a/Documentation/arm/cpu-domains.txt b/Documentation/arm/cpu-domains.txt
index 3e535b7..a0b98f3 100644
--- a/Documentation/arm/cpu-domains.txt
+++ b/Documentation/arm/cpu-domains.txt
@@ -47,3 +47,29 @@ attaches the domains' CPU devices to as specified in the DT. This happens
 automatically at kernel init, when the domain is specified as compatible with
 "arm,pd". Powering on/off the common cluster hardware would also be done when
 the PM domain is runtime suspended or resumed.
+
+SoCs may have additional configuration for the CPU PM domain. The ARM code
+provides a way for the platform driver to add those properties to the genpd
+before the genpd object is initialized. Additionally, platform driver may also
+register for CPU domain power_on/power_off callbacks.
+
+Platform drivers may register the callbacks using the __init section macro
+ARM_PD_METHOD_OF_DECLARE. The callbacks in of_arm_pd_ops, can be specified
+against a compatible flag for the domain provider.
+
+Callback for platform drivers -
+
+int (*init)(struct device_node *dn, struct generic_pm_domain *d)
+The init() callback is called before the generic PM domain is registered with
+the GenPD framework. The device node is provided to identify the domain that
+is being initialized. The init function must return 0, in order for the
+power_on and power_off callbacks to be registered with the CPU PD framework.
+
+int (*power_on)(struct generic_pm_domain *d);
+The power_on() callback is called when the first CPU in the cluster is ready
+to resume execution. The domain may be considered active at this point.
+
+int (*power_off)(struct generic_pm_domain *d);
+The power_off() callback is called when the last CPU in the cluster enters
+idle. The domain may be configured to power off and wait for a CPU's wakeup
+interrupt.
diff --git a/arch/arm/common/domains.c b/arch/arm/common/domains.c
index 15981e9..bbffeed 100644
--- a/arch/arm/common/domains.c
+++ b/arch/arm/common/domains.c
@@ -18,12 +18,19 @@
 #include <linux/pm_runtime.h>
 #include <linux/slab.h>
 
+#include <asm/arm-pd.h>
+
 #define NAME_MAX 36
 
 struct arm_pm_domain {
 	struct generic_pm_domain genpd;
+	struct of_arm_pd_ops platform_ops;
 };
 
+extern struct of_arm_pd_method __arm_pd_method_of_table[];
+static const struct of_arm_pd_method __arm_pd_method_of_table_sentinel
+	__used __section(__arm_pd_method_of_table_end);
+
 static inline
 struct arm_pm_domain *to_arm_pd(struct generic_pm_domain *d)
 {
@@ -32,20 +39,30 @@ struct arm_pm_domain *to_arm_pd(struct generic_pm_domain *d)
 
 static int arm_pd_power_down(struct generic_pm_domain *genpd)
 {
+	struct arm_pm_domain *pd = to_arm_pd(genpd);
+
 	/*
 	 * Notify CPU PM domain power down
 	 * TODO: Call the notificated directly from here.
 	 */
 	cpu_cluster_pm_enter();
 
+	if (pd->platform_ops.power_off)
+		return pd->platform_ops.power_off(genpd);
+
 	return 0;
 }
 
 static int arm_pd_power_up(struct generic_pm_domain *genpd)
 {
+	struct arm_pm_domain *pd = to_arm_pd(genpd);
+
 	/* Notify CPU PM domain power up */
 	cpu_cluster_pm_exit();
 
+	if (pd->platform_ops.power_on)
+		return pd->platform_ops.power_on(genpd);
+
 	return 0;
 }
 
@@ -134,6 +151,7 @@ static int __init arm_domain_init(void)
 {
 	struct device_node *np;
 	int count = 0;
+	struct of_arm_pd_method *m = __arm_pd_method_of_table;
 
 	for_each_compatible_node(np, NULL, "arm,pd") {
 		struct arm_pm_domain *pd;
@@ -145,6 +163,25 @@ static int __init arm_domain_init(void)
 		if (!pd)
 			return -ENOMEM;
 
+		/* Invoke platform initialization for the PM domain */
+		for (; m->handle; m++) {
+			int ret;
+
+			if (of_device_is_compatible(np, m->handle)) {
+				ret = m->ops->init(np, &pd->genpd);
+				if (!ret) {
+					pr_debug("CPU PD ops found for %s\n",
+							m->handle);
+					pd->platform_ops.power_on =
+						m->ops->power_on;
+					pd->platform_ops.power_off =
+						m->ops->power_off;
+				}
+				break;
+			}
+		}
+
+		/* Initialize rest of CPU PM domain specifics */
 		pd->genpd.name = kstrndup(np->name, NAME_MAX, GFP_KERNEL);
 		pd->genpd.power_off = arm_pd_power_down;
 		pd->genpd.power_on = arm_pd_power_up;
diff --git a/arch/arm/include/asm/arm-pd.h b/arch/arm/include/asm/arm-pd.h
new file mode 100644
index 0000000..fc44abf
--- /dev/null
+++ b/arch/arm/include/asm/arm-pd.h
@@ -0,0 +1,30 @@
+/*
+ * linux/arch/arm/include/asm/arm-pd.h
+ *
+ * Copyright (C) 2015 Linaro Ltd.
+ *
+ * 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.
+ */
+
+#ifndef __ARM_PD_H__
+#define __ARM_PD_H__
+
+struct of_arm_pd_ops {
+	int (*init)(struct device_node *dn, struct generic_pm_domain *d);
+	int (*power_on)(struct generic_pm_domain *d);
+	int (*power_off)(struct generic_pm_domain *d);
+};
+
+struct of_arm_pd_method {
+	const char *handle;
+	struct of_arm_pd_ops *ops;
+};
+
+#define ARM_PD_METHOD_OF_DECLARE(_name, _handle, _ops)	\
+	static const struct of_arm_pd_method __arm_pd_method_of_table_##_name \
+	__used __section(__arm_pd_method_of_table)		\
+	= { .handle = _handle, .ops = _ops }
+
+#endif /* __ARM_PD_H__ */
diff --git a/include/asm-generic/vmlinux.lds.h b/include/asm-generic/vmlinux.lds.h
index 8bd374d..bd97a69 100644
--- a/include/asm-generic/vmlinux.lds.h
+++ b/include/asm-generic/vmlinux.lds.h
@@ -179,6 +179,7 @@
 #define RESERVEDMEM_OF_TABLES()	OF_TABLE(CONFIG_OF_RESERVED_MEM, reservedmem)
 #define CPU_METHOD_OF_TABLES()	OF_TABLE(CONFIG_SMP, cpu_method)
 #define CPUIDLE_METHOD_OF_TABLES() OF_TABLE(CONFIG_CPU_IDLE, cpuidle_method)
+#define ARM_PD_METHOD_OF_TABLES() OF_TABLE(CONFIG_PM_GENERIC_DOMAINS, arm_pd_method)
 #define EARLYCON_OF_TABLES()	OF_TABLE(CONFIG_SERIAL_EARLYCON, earlycon)
 
 #define KERNEL_DTB()							\
@@ -514,6 +515,7 @@
 	IOMMU_OF_TABLES()						\
 	CPU_METHOD_OF_TABLES()						\
 	CPUIDLE_METHOD_OF_TABLES()					\
+	ARM_PD_METHOD_OF_TABLES()					\
 	KERNEL_DTB()							\
 	IRQCHIP_OF_MATCH_TABLE()					\
 	EARLYCON_TABLE()						\
-- 
2.1.4



From bhelgaas at google.com  Tue Aug  4 16:49:56 2015
From: bhelgaas at google.com (Bjorn Helgaas)
Date: Tue, 4 Aug 2015 18:49:56 -0500
Subject: [PATCH v4 1/3] PCI: generic: remove dependency on hw_pci
In-Reply-To: <1438721620-15493-1-git-send-email-jchandra@broadcom.com>
References: <1438721620-15493-1-git-send-email-jchandra@broadcom.com>
Message-ID: <20150804234956.GF17327@google.com>

On Wed, Aug 05, 2015 at 02:23:38AM +0530, Jayachandran C wrote:
> The current code in pci-host-generic.c uses pci_common_init_dev()
> from arm architecture to do some part of the PCI setup, and this
> prevents it from being used with arm64 architecture.
> 
> The part of pci_common_init_dev() that is really needed by
> pci-host-generic.c is very limited and can be done in the same
> file without using hw_pci API of ARM. The ARM platform requires
> a pci_sys_data as sysdata for the PCI bus, this can be handled by
> setting up gen_pci to have a pci_sys_data variable as the first
> element.
> 
> Signed-off-by: Jayachandran C <jchandra at broadcom.com>
> Acked-by: Lorenzo Pieralisi <lorenzo.pieralisi at arm.com>
> Tested-by: Lorenzo Pieralisi <lorenzo.pieralisi at arm.com>
> Tested-by: Pavel Fedin <p.fedin at samsung.com>

I applied all three of these to my pci/enumeration branch for v4.3.

I made a few changes, the most important being to call
pcie_bus_configure_settings() before pci_bus_add_devices(), because drivers
may claim devices in pci_bus_add_devices(), and the PCI core shouldn't
touch devices after drivers claim them.

I dropped the acks and tested-by because of that change, but I'll happily
add them back if Lorenzo and Pavel confirm.  The patches are here if you
want to review/test them:

https://git.kernel.org/cgit/linux/kernel/git/helgaas/pci.git/log/?h=pci/enumeration

I'm sure the other patches on that branch will need some tweaks, too, so I
don't have any problem with updating these.

Bjorn


From horms at verge.net.au  Tue Aug  4 17:55:37 2015
From: horms at verge.net.au (Simon Horman)
Date: Wed, 5 Aug 2015 09:55:37 +0900
Subject: [PATCH 0/7] ARM: shmobile: Misc removals
In-Reply-To: <1438711392-23763-1-git-send-email-geert+renesas@glider.be>
References: <1438711392-23763-1-git-send-email-geert+renesas@glider.be>
Message-ID: <20150805005537.GA20726@verge.net.au>

On Tue, Aug 04, 2015 at 08:03:05PM +0200, Geert Uytterhoeven wrote:
> 	Hi Simon, Magnus,
> 
> This patch series (against renesas-devel-20150804-v4.2-rc5) removes
> various header files, source files, declarations and definitions that
> are no longer in use.
> 
> Dependencies:
>   - Patch 1 depends on v3.12,
>   - Patches 2-5 depend on the sh73a0/kzm9g and r8a7740/armadillo legacy
>     removal, which is in arm-soc/for-next,
>   - Patches 6-7 depend on the r8a7779/marzen legacy removal, which is in
>     marzen-board-removal-for-v4.3.
> 
> Note that I didn't remove the now unused r8a7779_init_pm_domains() et al
> yet, as I need to have a closer look on what to retain for R-Car DT SYSC
> PM Domains first.
> 
> Thanks!

Thanks, I have tentatively queued these up for v4.4 as I feel
that the bottom of our stack of patches at a fresh cycle is
the best place for these kinds of cleanups.


From horms at verge.net.au  Tue Aug  4 17:55:41 2015
From: horms at verge.net.au (Simon Horman)
Date: Wed, 5 Aug 2015 09:55:41 +0900
Subject: [PATCH v2 0/6] ARM: shmobile: Move gpio ranges from C code to DT
In-Reply-To: <1438696519-13727-1-git-send-email-geert+renesas@glider.be>
References: <1438696519-13727-1-git-send-email-geert+renesas@glider.be>
Message-ID: <20150805005540.GB20726@verge.net.au>

Hi Geert,

On Tue, Aug 04, 2015 at 03:55:13PM +0200, Geert Uytterhoeven wrote:
> 	Hi Simon, Magnus,
> 
> This patch series moves the setup of the GPIO-PFC pin mapping for
> Renesas PFC/GPIO combos from C code to DT, and does some cleanups.
> The move to DT is needed to make the GPIO hogging mechanism work, cfr.
> the discussion following "[PATCH] [RFC] gpio: Retry deferred GPIO
> hogging on pin range change" (https://lkml.org/lkml/2015/6/16/455).
> 
> The series consists of 3 parts:
>   a. Patches 1-3 add the missing "gpio-ranges" properties to the dtsi
>      files for all affected SoCs,
>   b. Patch 4 disables the C code to set up the mapping on DT platforms
>      (it's still needed on SH or ARM-legacy),
>   c. Patches 5-6 do a few more cleanups in the sh-pfc gpio code.
> 
> Changes compared to v1 ("[PATCH 0/7] ARM: shmobile: Move gpio ranges
> from C code to DT",
> http://lists.infradead.org/pipermail/linux-arm-kernel/2015-June/353124.html):
>   - Add check for CONFIG_OF and pfc->dev->of_node,
>   - #ifdef out the code instead of introducing helper and dummy
>     functions,
>   - Drop "pinctrl: sh-pfc: Move sh_pfc_add_gpiochip() up", as it's no
>     longer needed due to the #ifdefs,
>   - Add Acked-by.
> 
> Dependencies:
>   - This series applies against renesas-devel-20150803-v4.2-rc5,
>   - Part a must go in first, to avoid regressions,
>   - While I didn't notice any bad behavior by having part a only, part b
>     should go in immediately after part a. Hence I think it's best if
>     Simon can take this one, too.
>   - Part c is independent (it doesn't touch the same code), so it can go
>     in before or after the other parts, or in parallel.
> 
> Given this fixes the LCD on r8a7740/armadillo, which is a regression
> introduced by the removal of armadillo-legacy support, I think at least
> patch 2 should be queued for v4.3.
> 
> Thanks for applying!
> 
> Geert Uytterhoeven (6):
>   ARM: shmobile: r8a73a4 dtsi: Add missing "gpio-ranges" to gpio node
>   ARM: shmobile: r8a7740 dtsi: Add missing "gpio-ranges" to gpio node
>   ARM: shmobile: sh73a0 dtsi: Add missing "gpio-ranges" to gpio node
>   pinctrl: sh-pfc: Stop calling gpiochip_add_pin_range() on DT platforms
>   pinctrl: sh-pfc: Remove empty gpio_function_free()
>   pinctrl: sh-pfc: Confine legacy function GPIOs to SH

Where possible I prefer not to apply non-DTS/DTSI patches on top of
DTS/DTSI patches, I believe this is in keeping with how the ARM SoC
maintainers like things handled.  With this in mind I have done the following:

1. Queued up the DTSI patches (patches 1 - 3) for v4.3 in my dt branch.
   I intend for this to turn up in next soon.
2. Queued up for pinctrl patches (patches 4 - 6) for v4.4 in a pinctrl patch.
   I intend for these to be present in the renesas devel branch but
   not in next until after the release of v4.3-rc1. I would also be
   happy to drop them and let Linus Walleij take these patches for v4.4,
   assuming patches 1 - 3 are accepted for v4.3.


From horms at verge.net.au  Tue Aug  4 17:55:44 2015
From: horms at verge.net.au (Simon Horman)
Date: Wed, 5 Aug 2015 09:55:44 +0900
Subject: [PATCH v4 00/16] ARM: shmobile: Add CPG/MSTP Clock Domain
In-Reply-To: <20150804134824.GA10194@verge.net.au>
References: <1438691297-29235-1-git-send-email-geert+renesas@glider.be>
 <20150804134824.GA10194@verge.net.au>
Message-ID: <20150805005543.GC20726@verge.net.au>

On Tue, Aug 04, 2015 at 10:48:28PM +0900, Simon Horman wrote:
> Thanks Geert,
> 
> I have tentatively queued this up in its own branch,
> cpg-mstp-clock-domain-for-v4.3.

Where possible I prefer not to apply non-DTS/DTSI patches on top of
DTS/DTSI patches, I believe this is in keeping with how the ARM SoC
maintainers like things handled.  With this in mind I have shuffled things
around a little, the result is:

1. The following are (still) queued up for v4.3 in their own
   cpg-mstp-clock-domain-for-v4.3 branch:

   clk: shmobile: Add CPG/MSTP Clock Domain support
   clk: shmobile: r8a7778: Add CPG/MSTP Clock Domain support
   clk: shmobile: r8a7779: Add CPG/MSTP Clock Domain support
   clk: shmobile: rcar-gen2: Add CPG/MSTP Clock Domain support
   clk: shmobile: rz: Add CPG/MSTP Clock Domain support
   ARM: shmobile: r7s72100 dtsi: Add CPG/MSTP Clock Domain
   ARM: shmobile: r8a7778 dtsi: Add CPG/MSTP Clock Domain
   ARM: shmobile: r8a7779 dtsi: Add CPG/MSTP Clock Domain
   ARM: shmobile: r8a7790 dtsi: Add CPG/MSTP Clock Domain
   ARM: shmobile: r8a7791 dtsi: Add CPG/MSTP Clock Domain
   ARM: shmobile: r8a7793 dtsi: Add CPG/MSTP Clock Domain
   ARM: shmobile: r8a7794 dtsi: Add CPG/MSTP Clock Domain

2. The following are now queued up for v4.3 in a separate
   sh-drivers-for-v4.3 branch. That branch is on top of the
   cpg-mstp-clock-domain-for-v4.3 branch and I intend to send it directly
   to Linus if/when a v4.3-rc has been released with the patches
   listed in 1. present.

   drivers: sh: Disable legacy default PM Domain on emev2
   drivers: sh: Disable PM runtime for multi-platform ARM with genpd

3. I have deferred the remaining two patches, listed below, for v4.4.
   they currently reside in cpg-mstp-clock-domain-for-v4.4. That
   branch is based on the sh-drivers-for-v4.3 branch.

   clk: shmobile: mstp: Consider "zb_clk" suitable for power management
   ARM: shmobile: R-Mobile: Use CPG/MSTP Clock Domain attach/detach helpers


This means that the last two patches will disappear from next until
after v4.3-rc1 is released but they, along with all the other patches,
will be present in the renesas devel branch.


From wangzhou1 at hisilicon.com  Tue Aug  4 18:40:50 2015
From: wangzhou1 at hisilicon.com (Zhou Wang)
Date: Wed, 5 Aug 2015 09:40:50 +0800
Subject: [PATCH v5 2/5] PCI: designware: Add ARM64 support
In-Reply-To: <55C09694.30506@arm.com>
References: <1437794486-21134-1-git-send-email-wangzhou1@hisilicon.com>
 <1437794486-21134-3-git-send-email-wangzhou1@hisilicon.com>
 <55B71F75.5030907@hisilicon.com> <55C0872E.9060507@arm.com>
 <EE11001F9E5DDD47B7634E2F8A612F2E01D719E9@lhreml503-mbs>
 <55C09694.30506@arm.com>
Message-ID: <55C169A2.10900@hisilicon.com>

On 2015/8/4 18:40, James Morse wrote:
> On 04/08/15 11:23, Gabriele Paoloni wrote:
>> Hi James
>>
>> Please see "[PATCH v6] PCI: Store PCIe bus address in struct of_pci_range"
>>
>> I think if you apply this patch your problem should be solved...
>>
>> If you follow the discussion you see that this patch is going to be part 
>> of the next designware patchset...
> 
> Yes I just spotted that series after continuing through my email backlog.
> 
>> Wang Zhou said "You need apply Gabriele's patch before applying this patch."
>> but he didn't specify which one and obviously this patch should have been part
>> of the patch-set
> 
> I assumed he meant your patch 1 in the same series, (given the reply was to
> patch 2).
> 
> With the '[PATCH v6] PCI: Store PCIe bus address in struct of_pci_range'
> applied before patches and 1 and 2 of this series - pcie on the
> 'Freescale i.MX6 Quad SABRE Lite Board' works fine.
> 
> I can rescan the bus, load firmware, list nearby APs, and even get MSIs
> coming from the card.
> 
> Tested-by: James Morse <james.morse at arm.com>
> 
> 
> 
> James
> 
> .
>

Hi James,

Many thanks for your help to test!

I need apologize for not giving a clear message. What I mean is applying
Gab's '[PATCH v6] PCI: Store PCIe bus address in struct of_pci_range'.
I am very sorry for wasting your time :(

Above Gab's patch will be merged in my next series. Hope that will make
thing clearer.

It is good that these patches work fine on your board! Hope we can get
more tests on other ARM32 boards.

Thanks again,
Zhou

.



From gregory.0xf0 at gmail.com  Tue Aug  4 18:43:28 2015
From: gregory.0xf0 at gmail.com (Gregory Fong)
Date: Tue,  4 Aug 2015 18:43:28 -0700
Subject: [PATCH] ARM: BCM: Enable ARM erratum 798181 for BRCMSTB
Message-ID: <1438739008-16718-1-git-send-email-gregory.0xf0@gmail.com>

Commit 04fcab32d3fa1d3f6afe97e0ab431c5572e07a2c ("ARM: 8111/1: Enable
erratum 798181 for Broadcom Brahma-B15") enables this erratum for
affected Broadcom Brahma-B15 CPUs when CONFIG_ARM_ERRATA_798181=y.
Let's make sure that config option is actually set.

Signed-off-by: Gregory Fong <gregory.0xf0 at gmail.com>
---
 arch/arm/mach-bcm/Kconfig | 1 +
 1 file changed, 1 insertion(+)

diff --git a/arch/arm/mach-bcm/Kconfig b/arch/arm/mach-bcm/Kconfig
index 0ac9e4b3..eed8746 100644
--- a/arch/arm/mach-bcm/Kconfig
+++ b/arch/arm/mach-bcm/Kconfig
@@ -140,6 +140,7 @@ config ARCH_BCM_63XX
 config ARCH_BRCMSTB
 	bool "Broadcom BCM7XXX based boards" if ARCH_MULTI_V7
 	select ARM_GIC
+	select ARM_ERRATA_798181 if SMP
 	select HAVE_ARM_ARCH_TIMER
 	select BRCMSTB_GISB_ARB
 	select BRCMSTB_L2_IRQ
-- 
1.9.1



From alexandre.belloni at free-electrons.com  Tue Aug  4 18:46:11 2015
From: alexandre.belloni at free-electrons.com (Alexandre Belloni)
Date: Wed, 5 Aug 2015 03:46:11 +0200
Subject: [PATCH] rtc: mt6397: implement suspend/resume function in
 rtc-mt6397 driver
In-Reply-To: <1438267994-13934-1-git-send-email-henryc.chen@mediatek.com>
References: <1438267994-13934-1-git-send-email-henryc.chen@mediatek.com>
Message-ID: <20150805014611.GY3486@piout.net>

On 30/07/2015 at 22:53:14 +0800, Henry Chen wrote :
> Implement the suspend/resume function in order to control rtc's irq_wake flag and handle as wakeup source.
> 
> Signed-off-by: Henry Chen <henryc.chen at mediatek.com>
> ---
>  drivers/rtc/rtc-mt6397.c | 26 ++++++++++++++++++++++++++
>  1 file changed, 26 insertions(+)
> 
Applied, thanks.

-- 
Alexandre Belloni, Free Electrons
Embedded Linux, Kernel and Android engineering
http://free-electrons.com


From peter.chen at freescale.com  Tue Aug  4 18:25:51 2015
From: peter.chen at freescale.com (Peter Chen)
Date: Wed, 5 Aug 2015 09:25:51 +0800
Subject: [PATCH v2 06/10] usb: chipidea: add ahb burst configuration
 interface
In-Reply-To: <CAL_JsqJn16OvfL_Ggf1wSi2XkJkjDMrmuRit3q8eVY5bNp8oYw@mail.gmail.com>
References: <1438577238-10153-1-git-send-email-peter.chen@freescale.com>
 <1438577238-10153-7-git-send-email-peter.chen@freescale.com>
 <CAL_JsqJn16OvfL_Ggf1wSi2XkJkjDMrmuRit3q8eVY5bNp8oYw@mail.gmail.com>
Message-ID: <20150805012550.GG25143@shlinux2>

On Mon, Aug 03, 2015 at 09:04:27AM -0500, Rob Herring wrote:
> On Sun, Aug 2, 2015 at 11:47 PM, Peter Chen <peter.chen at freescale.com> wrote:
> > The users can change it through dts or platform data if they
> > want to change the default value.
> >
> > Signed-off-by: Peter Chen <peter.chen at freescale.com>
> > ---
> >  drivers/usb/chipidea/bits.h  |  3 +++
> >  drivers/usb/chipidea/core.c  | 14 ++++++++++++++
> >  include/linux/usb/chipidea.h |  2 ++
> >  3 files changed, 19 insertions(+)
> >
> > diff --git a/drivers/usb/chipidea/bits.h b/drivers/usb/chipidea/bits.h
> > index 831a8f6..462ad02 100644
> > --- a/drivers/usb/chipidea/bits.h
> > +++ b/drivers/usb/chipidea/bits.h
> > @@ -25,6 +25,9 @@
> >  #define VERSION                      (0xF << 25)
> >  #define CIVERSION            (0x7 << 29)
> >
> > +/* SBUSCFG */
> > +#define AHBBRST_MASK           0x7
> > +
> >  /* HCCPARAMS */
> >  #define HCCPARAMS_LEN         BIT(17)
> >
> > diff --git a/drivers/usb/chipidea/core.c b/drivers/usb/chipidea/core.c
> > index 38bd036..f60cbf6 100644
> > --- a/drivers/usb/chipidea/core.c
> > +++ b/drivers/usb/chipidea/core.c
> > @@ -439,6 +439,9 @@ void ci_platform_configure(struct ci_hdrc *ci)
> >
> >         hw_write(ci, OP_USBCMD, 0xff0000, ci->platdata->itc_setting << 16);
> >
> > +       if (ci->platdata->flags & CI_HDRC_OVERRIDE_AHB_BURST)
> > +               hw_write_id_reg(ci, ID_SBUSCFG, AHBBRST_MASK,
> > +                       ci->platdata->ahb_burst_config);
> >  }
> >
> >  /**
> > @@ -647,6 +650,17 @@ static int ci_get_platdata(struct device *dev,
> >                 }
> >         }
> >
> > +       if (of_find_property(dev->of_node, "ahb-burst-config", NULL)) {
> > +               ret = of_property_read_u32(dev->of_node, "ahb-burst-config",
> > +                       &platdata->ahb_burst_config);
> > +               if (ret) {
> > +                       dev_err(dev,
> > +                               "failed to get ahb-burst-config\n");
> > +                       return ret;
> > +               }
> > +               platdata->flags |= CI_HDRC_OVERRIDE_AHB_BURST;
> > +       }
> > +
> 
> This can be simplified to:
> 
> ret = of_property_read_u32(dev->of_node, "ahb-burst-config",
> &platdata->ahb_burst_config);
> if (!ret)
>   platdata->flags |= CI_HDRC_OVERRIDE_AHB_BURST;
> 
> The error condition can't really happen.
> 

Why the error condition can't really happen? If the value of
this property at dts is invalid, we would like return error.

For non-exist property, it is normal case; for invalid property,
we would like return error, and quit.

-- 

Best Regards,
Peter Chen


From wenyou.yang at atmel.com  Tue Aug  4 19:35:28 2015
From: wenyou.yang at atmel.com (Wenyou Yang)
Date: Wed, 5 Aug 2015 10:35:28 +0800
Subject: [PATCH v2 0/2] add a new driver to support SAMA5D4 watchdog timer
Message-ID: <1438742130-2089-1-git-send-email-wenyou.yang@atmel.com>

Hello,

Thank for Guenter's advice, add a new driver to support SAMA5D4 watchdog timer.

Because the watchdog WDT_MR register can be written more than once, its work
mechanism is different from the previous one. Open the device file to enable
the watchdog hardware, close to disable it, and ping it from the user space
directly to keep it alive.

Best Regards,
Wenyou Yang

Wenyou Yang (2):
  drivers: watchdog: add a driver to support SAMA5D4 watchdog timer
  Documentation: dt: binding: atmel-sama5d4-wdt: for SAMA5D4 watchdog
    driver

 .../bindings/watchdog/atmel-sama5d4-wdt.txt        |   35 +++
 drivers/watchdog/Kconfig                           |    9 +
 drivers/watchdog/Makefile                          |    1 +
 drivers/watchdog/at91sam9_wdt.h                    |    4 +
 drivers/watchdog/atmel_wdt.c                       |  290 ++++++++++++++++++++
 5 files changed, 339 insertions(+)
 create mode 100644 Documentation/devicetree/bindings/watchdog/atmel-sama5d4-wdt.txt
 create mode 100644 drivers/watchdog/atmel_wdt.c

-- 
1.7.9.5



From wenyou.yang at atmel.com  Tue Aug  4 19:35:29 2015
From: wenyou.yang at atmel.com (Wenyou Yang)
Date: Wed, 5 Aug 2015 10:35:29 +0800
Subject: [PATCH v2 1/2] drivers: watchdog: add a driver to support SAMA5D4
 watchdog timer
In-Reply-To: <1438742130-2089-1-git-send-email-wenyou.yang@atmel.com>
References: <1438742130-2089-1-git-send-email-wenyou.yang@atmel.com>
Message-ID: <1438742130-2089-2-git-send-email-wenyou.yang@atmel.com>

>From SAMA5D4, the watchdog timer is upgrated with a new feature,
which is describled as in the datasheet, "WDT_MR can be written
until a LOCKMR command is issued in WDT_CR".
That is to say, as long as the bootstrap and u-boot don't issue
a LOCKMR command, WDT_MR can be written more than once in the driver.

So the SAMA5D4 watchdog driver's implementation is different from
the previous: the user application open the device file to enable
the watchdog timer hardware, and close to disable it, and set the
watchdog timer timeout by seting WDV and WDD fields of WDT_MR register,
and ping the watchdog by issuing WDRSTT command to WDT_CR register
with hard-coded key.

Signed-off-by: Wenyou Yang <wenyou.yang at atmel.com>
---
 drivers/watchdog/Kconfig        |    9 ++
 drivers/watchdog/Makefile       |    1 +
 drivers/watchdog/at91sam9_wdt.h |    4 +
 drivers/watchdog/atmel_wdt.c    |  290 +++++++++++++++++++++++++++++++++++++++
 4 files changed, 304 insertions(+)
 create mode 100644 drivers/watchdog/atmel_wdt.c

diff --git a/drivers/watchdog/Kconfig b/drivers/watchdog/Kconfig
index e5e7c55..4425813 100644
--- a/drivers/watchdog/Kconfig
+++ b/drivers/watchdog/Kconfig
@@ -152,6 +152,15 @@ config ARM_SP805_WATCHDOG
 	  ARM Primecell SP805 Watchdog timer. This will reboot your system when
 	  the timeout is reached.
 
+config ATMEL_WATCHDOG
+	tristate "Atmel SAMA5D4 Watchdog Timer"
+	depends on ARCH_AT91
+	select WATCHDOG_CORE
+	help
+	  Atmel watchdog timer embedded into SAMA5D4 chips. Its Watchdog Timer
+	  Mode Register(WDT_MR) can be written more than once.
+	  This will reboot your system when the timeout is reached.
+
 config AT91RM9200_WATCHDOG
 	tristate "AT91RM9200 watchdog"
 	depends on SOC_AT91RM9200 && MFD_SYSCON
diff --git a/drivers/watchdog/Makefile b/drivers/watchdog/Makefile
index 5c19294..c24a8fc 100644
--- a/drivers/watchdog/Makefile
+++ b/drivers/watchdog/Makefile
@@ -30,6 +30,7 @@ obj-$(CONFIG_USBPCWATCHDOG) += pcwd_usb.o
 
 # ARM Architecture
 obj-$(CONFIG_ARM_SP805_WATCHDOG) += sp805_wdt.o
+obj-$(CONFIG_ATMEL_WATCHDOG) += atmel_wdt.o
 obj-$(CONFIG_AT91RM9200_WATCHDOG) += at91rm9200_wdt.o
 obj-$(CONFIG_AT91SAM9X_WATCHDOG) += at91sam9_wdt.o
 obj-$(CONFIG_CADENCE_WATCHDOG) += cadence_wdt.o
diff --git a/drivers/watchdog/at91sam9_wdt.h b/drivers/watchdog/at91sam9_wdt.h
index c6fbb2e6..79add4f 100644
--- a/drivers/watchdog/at91sam9_wdt.h
+++ b/drivers/watchdog/at91sam9_wdt.h
@@ -22,11 +22,15 @@
 
 #define AT91_WDT_MR		0x04			/* Watchdog Mode Register */
 #define		AT91_WDT_WDV		(0xfff << 0)		/* Counter Value */
+#define			AT91_WDT_WDV_MSK	(0xfff)
+#define			AT91_WDT_WDV_(x)	(((x) & AT91_WDT_WDV_MSK) << 0)
 #define		AT91_WDT_WDFIEN		(1     << 12)		/* Fault Interrupt Enable */
 #define		AT91_WDT_WDRSTEN	(1     << 13)		/* Reset Processor */
 #define		AT91_WDT_WDRPROC	(1     << 14)		/* Timer Restart */
 #define		AT91_WDT_WDDIS		(1     << 15)		/* Watchdog Disable */
 #define		AT91_WDT_WDD		(0xfff << 16)		/* Delta Value */
+#define			AT91_WDT_WDD_MSK	(0xfff)
+#define			AT91_WDT_WDD_(x)	(((x) & AT91_WDT_WDD_MSK) << 16)
 #define		AT91_WDT_WDDBGHLT	(1     << 28)		/* Debug Halt */
 #define		AT91_WDT_WDIDLEHLT	(1     << 29)		/* Idle Halt */
 
diff --git a/drivers/watchdog/atmel_wdt.c b/drivers/watchdog/atmel_wdt.c
new file mode 100644
index 0000000..e1cdc84
--- /dev/null
+++ b/drivers/watchdog/atmel_wdt.c
@@ -0,0 +1,290 @@
+/*
+ * Driver for Atmel SAMA5D4 Watchdog Timer
+ *
+ * Copyright (C) 2015 Atmel Corporation
+ *
+ * Licensed under GPLv2.
+ */
+
+#include <linux/kernel.h>
+#include <linux/module.h>
+#include <linux/interrupt.h>
+#include <linux/io.h>
+#include <linux/of.h>
+#include <linux/of_irq.h>
+#include <linux/platform_device.h>
+#include <linux/watchdog.h>
+#include <linux/reboot.h>
+
+#include "at91sam9_wdt.h"
+
+/* minimum and maximum watchdog timeout, in seconds */
+#define MIN_WDT_TIMEOUT		1
+#define MAX_WDT_TIMEOUT		16
+#define WDT_DEFAULT_TIMEOUT	MAX_WDT_TIMEOUT
+
+#define WDT_MAX_WDV		0xFFF
+
+#define WDT_SEC2TICKS(s)	((s) ? (((s) << 8) - 1) : 0)
+
+struct atmel_wdt {
+	struct watchdog_device	wdd;
+	void __iomem		*reg_base;
+	u32	config;
+};
+
+static int wdt_timeout = WDT_DEFAULT_TIMEOUT;
+static bool nowayout = WATCHDOG_NOWAYOUT;
+
+module_param(wdt_timeout, int, 0);
+MODULE_PARM_DESC(wdt_timeout,
+	"Watchdog wdt_timeout in seconds. (default = "
+	__MODULE_STRING(WDT_DEFAULT_TIMEOUT) ")");
+
+module_param(nowayout, bool, 0);
+MODULE_PARM_DESC(nowayout,
+	"Watchdog cannot be stopped once started (default="
+	__MODULE_STRING(WATCHDOG_NOWAYOUT) ")");
+
+#define wdt_read(wdt, field) \
+	readl_relaxed((wdt)->reg_base + (field))
+
+#define wdt_write(wtd, field, val) \
+	writel_relaxed((val), (wdt)->reg_base + (field))
+
+static int atmel_wdt_start(struct watchdog_device *wdd)
+{
+	struct atmel_wdt *wdt = watchdog_get_drvdata(wdd);
+	u32 reg;
+
+	reg = wdt_read(wdt, AT91_WDT_MR);
+	reg &= ~AT91_WDT_WDDIS;
+	wdt_write(wdt, AT91_WDT_MR, reg);
+
+	return 0;
+}
+
+static int atmel_wdt_stop(struct watchdog_device *wdd)
+{
+	struct atmel_wdt *wdt = watchdog_get_drvdata(wdd);
+	u32 reg;
+
+	reg = wdt_read(wdt, AT91_WDT_MR);
+	reg |= AT91_WDT_WDDIS;
+	wdt_write(wdt, AT91_WDT_MR, reg);
+
+	return 0;
+}
+
+static int atmel_wdt_ping(struct watchdog_device *wdd)
+{
+	struct atmel_wdt *wdt = watchdog_get_drvdata(wdd);
+
+	wdt_write(wdt, AT91_WDT_CR, AT91_WDT_KEY | AT91_WDT_WDRSTT);
+
+	return 0;
+}
+
+static int atmel_wdt_set_timeout(struct watchdog_device *wdd,
+				 unsigned int timeout)
+{
+	struct atmel_wdt *wdt = watchdog_get_drvdata(wdd);
+	u32 reg, value;
+
+	value = WDT_SEC2TICKS(timeout);
+	if (value > WDT_MAX_WDV)
+		return -EINVAL;
+
+	reg = wdt_read(wdt, AT91_WDT_MR);
+	reg &= ~AT91_WDT_WDV;
+	reg &= ~AT91_WDT_WDD;
+	reg |= AT91_WDT_WDV_(value);
+	reg |= AT91_WDT_WDD_(value);
+	wdt_write(wdt, AT91_WDT_MR, reg);
+
+	wdd->timeout = timeout;
+
+	return 0;
+}
+
+static const struct watchdog_info atmel_wdt_info = {
+	.options = WDIOF_SETTIMEOUT | WDIOF_MAGICCLOSE | WDIOF_KEEPALIVEPING,
+	.firmware_version = 0,
+	.identity = "Atmel SAMA5D4 Watchdog",
+};
+
+static struct watchdog_ops atmel_wdt_ops = {
+	.owner = THIS_MODULE,
+	.start = atmel_wdt_start,
+	.stop = atmel_wdt_stop,
+	.ping = atmel_wdt_ping,
+	.set_timeout = atmel_wdt_set_timeout,
+};
+
+static irqreturn_t atmel_wdt_irq_handler(int irq, void *dev_id)
+{
+	struct atmel_wdt *wdt = platform_get_drvdata(dev_id);
+
+	if (wdt_read(wdt, AT91_WDT_SR)) {
+		pr_crit("Atmel Watchdog Software Reset\n");
+		emergency_restart();
+		pr_crit("Reboot didn't ?????\n");
+	}
+
+	return IRQ_HANDLED;
+}
+
+static int of_atmel_wdt_init(struct device_node *np, struct atmel_wdt *wdt)
+{
+	const char *tmp;
+
+	wdt->config = AT91_WDT_WDDIS;
+
+	if (!of_property_read_string(np, "atmel,watchdog-type", &tmp) &&
+	    !strcmp(tmp, "software"))
+		wdt->config |= AT91_WDT_WDFIEN;
+	else
+		wdt->config |= AT91_WDT_WDRSTEN;
+
+	if (of_property_read_bool(np, "atmel,idle-halt"))
+		wdt->config |= AT91_WDT_WDIDLEHLT;
+
+	if (of_property_read_bool(np, "atmel,dbg-halt"))
+		wdt->config |= AT91_WDT_WDDBGHLT;
+
+	return 0;
+}
+
+static int atmel_wdt_init(struct atmel_wdt *wdt)
+{
+	struct watchdog_device *wdd = &wdt->wdd;
+	u32 value, timeout;
+
+	timeout = WDT_SEC2TICKS(wdd->timeout);
+	if (timeout > WDT_MAX_WDV)
+		return -1;
+
+	/*
+	 * Because the fields WDV and WDD must not be modified when the WDDIS
+	 * bit is set, so clear the WDDIS bit before writing the WDT_MR.
+	 */
+	value = wdt_read(wdt, AT91_WDT_MR);
+	value &= ~AT91_WDT_WDDIS;
+	wdt_write(wdt, AT91_WDT_MR, value);
+
+	value = wdt->config;
+	value |= AT91_WDT_WDD_(timeout);
+	value |= AT91_WDT_WDV_(timeout);
+
+	wdt_write(wdt, AT91_WDT_MR, value);
+
+	return 0;
+}
+
+static int atmel_wdt_probe(struct platform_device *pdev)
+{
+	struct watchdog_device *wdd;
+	struct atmel_wdt *wdt;
+	struct resource *res;
+	void __iomem *regs;
+	int ret, irq = -1;
+
+	wdt = devm_kzalloc(&pdev->dev, sizeof(*wdt), GFP_KERNEL);
+	if (!wdt)
+		return -ENOMEM;
+
+	wdd = &wdt->wdd;
+	wdd->timeout = wdt_timeout;
+	wdd->info = &atmel_wdt_info;
+	wdd->ops = &atmel_wdt_ops;
+	wdd->min_timeout = MIN_WDT_TIMEOUT;
+	wdd->max_timeout = MAX_WDT_TIMEOUT;
+
+	watchdog_set_drvdata(wdd, wdt);
+
+	res = platform_get_resource(pdev, IORESOURCE_MEM, 0);
+	regs = devm_ioremap_resource(&pdev->dev, res);
+	if (IS_ERR(regs))
+		return PTR_ERR(regs);
+
+	wdt->reg_base = regs;
+
+	if (pdev->dev.of_node) {
+		irq = irq_of_parse_and_map(pdev->dev.of_node, 0);
+		if (!irq)
+			dev_warn(&pdev->dev, "the IRQ NOT specify from DT\n");
+
+		ret = of_atmel_wdt_init(pdev->dev.of_node, wdt);
+		if (ret)
+			return ret;
+	}
+
+	if ((wdt->config & AT91_WDT_WDFIEN) && (irq >= 0)) {
+		ret = devm_request_irq(&pdev->dev, irq, atmel_wdt_irq_handler,
+				       0, pdev->name, pdev);
+		if (ret) {
+			dev_err(&pdev->dev,
+				"cannot register interrupt handler\n");
+			return ret;
+		}
+	}
+
+	ret = watchdog_init_timeout(wdd, wdt_timeout, &pdev->dev);
+	if (ret) {
+		dev_err(&pdev->dev, "unable to set timeout value\n");
+		return ret;
+	}
+
+	ret = atmel_wdt_init(wdt);
+	if (ret)
+		return ret;
+
+	watchdog_set_nowayout(wdd, nowayout);
+
+	ret = watchdog_register_device(wdd);
+	if (ret) {
+		dev_err(&pdev->dev, "failed to register watchdog device\n");
+		return ret;
+	}
+
+	platform_set_drvdata(pdev, wdt);
+
+	dev_info(&pdev->dev, "initialized (timeout = %d sec, nowayout = %d)\n",
+		 wdt_timeout, nowayout);
+
+	return 0;
+}
+
+static int atmel_wdt_remove(struct platform_device *pdev)
+{
+	struct atmel_wdt *wdt = platform_get_drvdata(pdev);
+
+	atmel_wdt_stop(&wdt->wdd);
+
+	watchdog_unregister_device(&wdt->wdd);
+
+	dev_info(&pdev->dev, "removed wdt\n");
+
+	return 0;
+}
+
+static const struct of_device_id atmel_wdt_of_match[] = {
+	{ .compatible = "atmel,sama5d4-wdt", },
+	{ },
+};
+MODULE_DEVICE_TABLE(of, atmel_wdt_of_match);
+
+static struct platform_driver atmel_wdt_driver = {
+	.probe		= atmel_wdt_probe,
+	.remove		= atmel_wdt_remove,
+	.driver		= {
+		.name	= "atmel-wdt",
+		.of_match_table = atmel_wdt_of_match,
+	},
+};
+module_platform_driver(atmel_wdt_driver);
+
+MODULE_ALIAS("platform:atmel-wdt");
+MODULE_AUTHOR("Atmel Corporation");
+MODULE_DESCRIPTION("Atmel SAMA5D4 Watchdog Timer driver");
+MODULE_LICENSE("GPL v2");
-- 
1.7.9.5



From wenyou.yang at atmel.com  Tue Aug  4 19:35:30 2015
From: wenyou.yang at atmel.com (Wenyou Yang)
Date: Wed, 5 Aug 2015 10:35:30 +0800
Subject: [PATCH v2 2/2] Documentation: dt: binding: atmel-sama5d4-wdt: for
 SAMA5D4 watchdog driver
In-Reply-To: <1438742130-2089-1-git-send-email-wenyou.yang@atmel.com>
References: <1438742130-2089-1-git-send-email-wenyou.yang@atmel.com>
Message-ID: <1438742130-2089-3-git-send-email-wenyou.yang@atmel.com>

The compatible "atmel,sama5d4-wdt" supports the SAMA5D4 watchdog driver
and the watchdog's WDT_MR register can be written more than once.

Signed-off-by: Wenyou Yang <wenyou.yang at atmel.com>
---
 .../bindings/watchdog/atmel-sama5d4-wdt.txt        |   35 ++++++++++++++++++++
 1 file changed, 35 insertions(+)
 create mode 100644 Documentation/devicetree/bindings/watchdog/atmel-sama5d4-wdt.txt

diff --git a/Documentation/devicetree/bindings/watchdog/atmel-sama5d4-wdt.txt b/Documentation/devicetree/bindings/watchdog/atmel-sama5d4-wdt.txt
new file mode 100644
index 0000000..f7cc7c0
--- /dev/null
+++ b/Documentation/devicetree/bindings/watchdog/atmel-sama5d4-wdt.txt
@@ -0,0 +1,35 @@
+* Atmel SAMA5D4 Watchdog Timer (WDT) Controller
+
+Required properties:
+- compatible: "atmel,sama5d4-wdt"
+- reg: base physical address and length of memory mapped region.
+
+Optional properties:
+- timeout-sec: watchdog timeout value (in seconds).
+- interrupts: interrupt number to the CPU.
+- atmel,watchdog-type: should be "hardware" or "software".
+	"hardware": enable watchdog fault reset. A watchdog fault triggers
+		    watchdog reset.
+	"software": enable watchdog fault interrupt. A watchdog fault asserts
+		    watchdog interrupt.
+- atmel,idle-halt: present if you want to stop the watchdog when the CPU is
+		   in idle state.
+	CAUTION: This property should be used with care, it actually makes the
+	watchdog not counting when the CPU is in idle state, therefore the
+	watchdog reset time depends on mean CPU usage and will not reset at all
+	if the CPU stop working while it is in idle state, which is probably
+	not what you want.
+- atmel,dbg-halt: present if you want to stop the watchdog when the CPU is
+		  in debug state.
+
+Example:
+	watchdog at fc068640 {
+		compatible = "atmel,sama5d4-wdt";
+		reg = <0xfc068640 0x10>;
+		interrupts = <4 IRQ_TYPE_LEVEL_HIGH 5>;
+		timeout-sec = <10>;
+		atmel,watchdog-type = "hardware";
+		atmel,dbg-halt;
+		atmel,idle-halt;
+		status = "okay";
+	};
-- 
1.7.9.5



From 21cnbao at gmail.com  Tue Aug  4 20:22:14 2015
From: 21cnbao at gmail.com (Barry Song)
Date: Wed,  5 Aug 2015 03:22:14 +0000
Subject: [PATCH] pinctrl: atlas7: clear ugly branch statements for pull and
 drivestrength
Message-ID: <1438744934-15395-1-git-send-email-21cnbao@gmail.com>

From: Wei Chen <Wei.Chen at csr.com>

To set/get atlas7 pull & drive strength, we use lots of if/else
to check pad type. But except mask value or immediate value, all
actions in these conditional branches are the same.
So we use predefined pull info table and drive strength table
to reduce these redundancy code.

Signed-off-by: Wei Chen <Wei.Chen at csr.com>
Signed-off-by: Barry Song <Baohua.Song at csr.com>
---
 drivers/pinctrl/sirf/pinctrl-atlas7.c | 193 +++++++++++++++++-----------------
 1 file changed, 94 insertions(+), 99 deletions(-)

diff --git a/drivers/pinctrl/sirf/pinctrl-atlas7.c b/drivers/pinctrl/sirf/pinctrl-atlas7.c
index d16e629..9df0c5f 100644
--- a/drivers/pinctrl/sirf/pinctrl-atlas7.c
+++ b/drivers/pinctrl/sirf/pinctrl-atlas7.c
@@ -3510,11 +3510,19 @@ struct atlas7_pinctrl_data atlas7_ioc_data = {
 	.confs_cnt = ARRAY_SIZE(atlas7_ioc_pad_confs),
 };
 
+/* Simple map data structure */
 struct map_data {
 	u8 idx;
 	u8 data;
 };
 
+/**
+ * struct atlas7_pull_info - Atlas7 Pad pull info
+ * @type:The type of this Pad.
+ * @mask:The mas value of this pin's pull bits.
+ * @v2s: The map of pull register value to pull status.
+ * @s2v: The map of pull status to pull register value.
+ */
 struct atlas7_pull_info {
 	u8 pad_type;
 	u8 mask;
@@ -3597,6 +3605,65 @@ static const struct atlas7_pull_info atlas7_pull_map[] = {
 	{ PAD_T_AD, PANGD_PULL_MASK, pangd_pull_v2s, pangd_pull_s2v },
 };
 
+/**
+ * struct atlas7_ds_ma_info - Atlas7 Pad DriveStrength & currents info
+ * @ma:		The Drive Strength in current value .
+ * @ds_16st:	The correspond raw value of 16st pad.
+ * @ds_4we:	The correspond raw value of 4we pad.
+ * @ds_0204m31:	The correspond raw value of 0204m31 pad.
+ * @ds_0610m31:	The correspond raw value of 0610m31 pad.
+ */
+struct atlas7_ds_ma_info {
+	u32 ma;
+	u32 ds_16st;
+	u32 ds_4we;
+	u32 ds_0204m31;
+	u32 ds_0610m31;
+};
+
+static const struct atlas7_ds_ma_info atlas7_ma2ds_map[] = {
+	{ 2, DS_16ST_0, DS_4WE_0, DS_M31_0, DS_NULL },
+	{ 4, DS_16ST_1, DS_NULL, DS_M31_1, DS_NULL },
+	{ 6, DS_16ST_2, DS_NULL, DS_NULL, DS_M31_0 },
+	{ 8, DS_16ST_3, DS_4WE_1, DS_NULL, DS_NULL },
+	{ 10, DS_16ST_4, DS_NULL, DS_NULL, DS_M31_1 },
+	{ 12, DS_16ST_5, DS_NULL, DS_NULL, DS_NULL },
+	{ 14, DS_16ST_6, DS_NULL, DS_NULL, DS_NULL },
+	{ 16, DS_16ST_7, DS_4WE_2, DS_NULL, DS_NULL },
+	{ 18, DS_16ST_8, DS_NULL, DS_NULL, DS_NULL },
+	{ 20, DS_16ST_9, DS_NULL, DS_NULL, DS_NULL },
+	{ 22, DS_16ST_10, DS_NULL, DS_NULL, DS_NULL },
+	{ 24, DS_16ST_11, DS_NULL, DS_NULL, DS_NULL },
+	{ 26, DS_16ST_12, DS_NULL, DS_NULL, DS_NULL },
+	{ 28, DS_16ST_13, DS_4WE_3, DS_NULL, DS_NULL },
+	{ 30, DS_16ST_14, DS_NULL, DS_NULL, DS_NULL },
+	{ 32, DS_16ST_15, DS_NULL, DS_NULL, DS_NULL },
+};
+
+/**
+ * struct atlas7_ds_info - Atlas7 Pad DriveStrength info
+ * @type:		The type of this Pad.
+ * @mask:		The mask value of this pin's pull bits.
+ * @imval:		The immediate value of drives trength register.
+ */
+struct atlas7_ds_info {
+	u8 type;
+	u8 mask;
+	u8 imval;
+	u8 reserved;
+};
+
+static const struct atlas7_ds_info atlas7_ds_map[] = {
+	{ PAD_T_4WE_PD, DS_2BIT_MASK, DS_2BIT_IM_VAL },
+	{ PAD_T_4WE_PU, DS_2BIT_MASK, DS_2BIT_IM_VAL },
+	{ PAD_T_16ST, DS_4BIT_MASK, DS_4BIT_IM_VAL },
+	{ PAD_T_M31_0204_PD, DS_1BIT_MASK, DS_1BIT_IM_VAL },
+	{ PAD_T_M31_0204_PU, DS_1BIT_MASK, DS_1BIT_IM_VAL },
+	{ PAD_T_M31_0610_PD, DS_1BIT_MASK, DS_1BIT_IM_VAL },
+	{ PAD_T_M31_0610_PU, DS_1BIT_MASK, DS_1BIT_IM_VAL },
+	{ PAD_T_AD, DS_NULL, DS_NULL },
+};
+
 static inline u32 atlas7_pin_to_bank(u32 pin)
 {
 	return (pin >= ATLAS7_PINCTRL_BANK_0_PINS) ? 1 : 0;
@@ -3799,70 +3866,27 @@ static int atlas7_pmx_set_mux(struct pinctrl_dev *pctldev,
 	return 0;
 }
 
-struct atlas7_ds_info {
-	u32 ma;
-	u32 ds_16st;
-	u32 ds_4we;
-	u32 ds_0204m31;
-	u32 ds_0610m31;
-};
-
-const struct atlas7_ds_info atlas7_ds_map[] = {
-	{ 2, DS_16ST_0, DS_4WE_0, DS_M31_0, DS_NULL},
-	{ 4, DS_16ST_1, DS_NULL, DS_M31_1, DS_NULL},
-	{ 6, DS_16ST_2, DS_NULL, DS_NULL, DS_M31_0},
-	{ 8, DS_16ST_3, DS_4WE_1, DS_NULL, DS_NULL},
-	{ 10, DS_16ST_4, DS_NULL, DS_NULL, DS_M31_1},
-	{ 12, DS_16ST_5, DS_NULL, DS_NULL, DS_NULL},
-	{ 14, DS_16ST_6, DS_NULL, DS_NULL, DS_NULL},
-	{ 16, DS_16ST_7, DS_4WE_2, DS_NULL, DS_NULL},
-	{ 18, DS_16ST_8, DS_NULL, DS_NULL, DS_NULL},
-	{ 20, DS_16ST_9, DS_NULL, DS_NULL, DS_NULL},
-	{ 22, DS_16ST_10, DS_NULL, DS_NULL, DS_NULL},
-	{ 24, DS_16ST_11, DS_NULL, DS_NULL, DS_NULL},
-	{ 26, DS_16ST_12, DS_NULL, DS_NULL, DS_NULL},
-	{ 28, DS_16ST_13, DS_4WE_3, DS_NULL, DS_NULL},
-	{ 30, DS_16ST_14, DS_NULL, DS_NULL, DS_NULL},
-	{ 32, DS_16ST_15, DS_NULL, DS_NULL, DS_NULL},
-};
-
 static u32 convert_current_to_drive_strength(u32 type, u32 ma)
 {
 	int idx;
 
-	for (idx = 0; idx < ARRAY_SIZE(atlas7_ds_map); idx++) {
-		if (atlas7_ds_map[idx].ma != ma)
+	for (idx = 0; idx < ARRAY_SIZE(atlas7_ma2ds_map); idx++) {
+		if (atlas7_ma2ds_map[idx].ma != ma)
 			continue;
 
 		if (type == PAD_T_4WE_PD || type == PAD_T_4WE_PU)
-			return atlas7_ds_map[idx].ds_4we;
+			return atlas7_ma2ds_map[idx].ds_4we;
 		else if (type == PAD_T_16ST)
-			return atlas7_ds_map[idx].ds_16st;
+			return atlas7_ma2ds_map[idx].ds_16st;
 		else if (type == PAD_T_M31_0204_PD || type == PAD_T_M31_0204_PU)
-			return atlas7_ds_map[idx].ds_0204m31;
+			return atlas7_ma2ds_map[idx].ds_0204m31;
 		else if (type == PAD_T_M31_0610_PD || type == PAD_T_M31_0610_PU)
-			return atlas7_ds_map[idx].ds_0610m31;
+			return atlas7_ma2ds_map[idx].ds_0610m31;
 	}
 
 	return DS_NULL;
 }
 
-static u32 altas7_pinctrl_get_pull_sel(struct atlas7_pmx *pmx, u32 pin)
-{
-	struct atlas7_pad_config *conf = &pmx->pctl_data->confs[pin];
-	const struct atlas7_pull_info *pull_info;
-	int bank;
-	unsigned long regv;
-
-	bank = atlas7_pin_to_bank(pin);
-	pull_info = &atlas7_pull_map[conf->type];
-
-	regv = readl(pmx->regs[bank] + conf->pupd_reg);
-	regv = (regv >> conf->pupd_bit) & pull_info->mask;
-
-	return pull_info->v2s[regv].data;
-}
-
 static int altas7_pinctrl_set_pull_sel(struct pinctrl_dev *pctldev,
 					u32 pin, u32 sel)
 {
@@ -3871,19 +3895,17 @@ static int altas7_pinctrl_set_pull_sel(struct pinctrl_dev *pctldev,
 	const struct atlas7_pull_info *pull_info;
 	u32 bank;
 	unsigned long regv;
-	void __iomem *pull_sel_reg, *pull_clr_reg;
+	void __iomem *pull_sel_reg;
 
 	bank = atlas7_pin_to_bank(pin);
 	pull_info = &atlas7_pull_map[conf->type];
-
 	pull_sel_reg = pmx->regs[bank] + conf->pupd_reg;
-	pull_clr_reg = CLR_REG(pull_sel_reg);
 
 	/* Retrieve correspond register value from table by sel */
 	regv = pull_info->s2v[sel].data & pull_info->mask;
 
 	/* Clear & Set new value to pull register */
-	writel(pull_info->mask << conf->pupd_bit, pull_clr_reg);
+	writel(pull_info->mask << conf->pupd_bit, CLR_REG(pull_sel_reg));
 	writel(regv << conf->pupd_bit, pull_sel_reg);
 
 	pr_debug("PIN_CFG ### SET PIN#%d PULL SELECTOR:%d == OK ####\n",
@@ -3896,43 +3918,25 @@ static int __altas7_pinctrl_set_drive_strength_sel(struct pinctrl_dev *pctldev,
 {
 	struct atlas7_pmx *pmx = pinctrl_dev_get_drvdata(pctldev);
 	struct atlas7_pad_config *conf = &pmx->pctl_data->confs[pin];
-	u32 type = conf->type;
-	u32 shift = conf->drvstr_bit;
-	u32 bank = atlas7_pin_to_bank(pin);
-	void __iomem *ds_sel_reg, *ds_clr_reg;
-
-	ds_sel_reg = pmx->regs[bank] + conf->drvstr_reg;
-	ds_clr_reg = CLR_REG(ds_sel_reg);
-	if (type == PAD_T_4WE_PD || type == PAD_T_4WE_PU) {
-		if (sel & (~DS_2BIT_MASK))
-			goto unsupport;
-
-		writel(DS_2BIT_IM_VAL << shift, ds_clr_reg);
-		writel(sel << shift, ds_sel_reg);
-
-		return 0;
-	} else if (type == PAD_T_16ST) {
-		if (sel & (~DS_4BIT_MASK))
-			goto unsupport;
+	const struct atlas7_ds_info *ds_info;
+	u32 bank;
+	void __iomem *ds_sel_reg;
 
-		writel(DS_4BIT_IM_VAL << shift, ds_clr_reg);
-		writel(sel << shift, ds_sel_reg);
+	ds_info = &atlas7_ds_map[conf->type];
+	if (sel & (~(ds_info->mask)))
+		goto unsupport;
 
-		return 0;
-	} else if (type == PAD_T_M31_0204_PD ||	type == PAD_T_M31_0204_PU ||
-		type == PAD_T_M31_0610_PD || type == PAD_T_M31_0610_PU) {
-		if (sel & (~DS_1BIT_MASK))
-			goto unsupport;
+	bank = atlas7_pin_to_bank(pin);
+	ds_sel_reg = pmx->regs[bank] + conf->drvstr_reg;
 
-		writel(DS_1BIT_IM_VAL << shift, ds_clr_reg);
-		writel(sel << shift, ds_sel_reg);
+	writel(ds_info->imval << conf->drvstr_bit, CLR_REG(ds_sel_reg));
+	writel(sel << conf->drvstr_bit, ds_sel_reg);
 
-		return 0;
-	}
+	return 0;
 
 unsupport:
 	pr_err("Pad#%d type[%d] doesn't support ds code[%d]!\n",
-		pin, type, sel);
+		pin, conf->type, sel);
 	return -ENOTSUPP;
 }
 
@@ -4185,6 +4189,8 @@ static int atlas7_pinmux_suspend_noirq(struct device *dev)
 	struct atlas7_pmx *pmx = dev_get_drvdata(dev);
 	struct atlas7_pad_status *status;
 	struct atlas7_pad_config *conf;
+	const struct atlas7_ds_info *ds_info;
+	const struct atlas7_pull_info *pull_info;
 	int idx;
 	u32 bank;
 	unsigned long regv;
@@ -4212,27 +4218,16 @@ save_ds_sel:
 			goto save_pull_sel;
 
 		/* Save Drive Strength selector */
+		ds_info = &atlas7_ds_map[conf->type];
 		regv = readl(pmx->regs[bank] + conf->drvstr_reg);
-		if (PAD_T_4WE_PD == conf->type || PAD_T_4WE_PU == conf->type)
-			status->dstr = (regv >> conf->drvstr_bit) &
-					DS_2BIT_MASK;
-		else if (PAD_T_16ST == conf->type)
-			status->dstr = (regv >> conf->drvstr_bit) &
-					DS_4BIT_MASK;
-		else if (PAD_T_M31_0204_PD == conf->type ||
-			PAD_T_M31_0204_PU == conf->type ||
-			PAD_T_M31_0610_PD == conf->type ||
-			PAD_T_M31_0610_PU == conf->type)
-			status->dstr = (regv >> conf->drvstr_bit) &
-					DS_1BIT_MASK;
+		status->dstr = (regv >> conf->drvstr_bit) & ds_info->mask;
 
 save_pull_sel:
 		/* Save Pull selector */
+		pull_info = &atlas7_pull_map[conf->type];
 		regv = readl(pmx->regs[bank] + conf->pupd_reg);
-		status->pull = altas7_pinctrl_get_pull_sel(pmx, idx);
-		pr_debug("idx %d %p %x: %x %x %x\n", idx,
-				pmx->regs[bank], conf->mux_reg,
-				status->func, status->pull, status->dstr);
+		regv = (regv >> conf->pupd_bit) & pull_info->mask;
+		status->pull = pull_info->v2s[regv].data;
 	}
 
 	/*
-- 
2.3.5



From ranjit.waghmode at xilinx.com  Tue Aug  4 22:01:15 2015
From: ranjit.waghmode at xilinx.com (Ranjit Abhimanyu Waghmode)
Date: Wed, 5 Aug 2015 05:01:15 +0000
Subject: [LINUX RFC 1/2] mtd: spi-nor: add dual parallel mode support
In-Reply-To: <20150803160829.GX20873@sirena.org.uk>
References: <1438592707-30713-1-git-send-email-ranjit.waghmode@xilinx.com>
 <1438592707-30713-2-git-send-email-ranjit.waghmode@xilinx.com>
 <20150803160829.GX20873@sirena.org.uk>
Message-ID: <7CFCFE83B8145347A1D424EC939F1C3C01492420@XAP-PVEXMBX01.xlnx.xilinx.com>

Hi Mark,

> -----Original Message-----
> From: Mark Brown [mailto:broonie at kernel.org]
> Sent: Monday, August 03, 2015 9:38 PM
> To: Ranjit Abhimanyu Waghmode
> Cc: dwmw2 at infradead.org; computersforpeace at gmail.com; Michal Simek;
> Soren Brinkmann; zajec5 at gmail.com; ben at decadent.org.uk; marex at denx.de;
> b32955 at freescale.com; knut.wohlrab at de.bosch.com; juhosg at openwrt.org;
> beanhuo at micron.com; linux-mtd at lists.infradead.org; linux-
> kernel at vger.kernel.org; linux-spi at vger.kernel.org; linux-arm-
> kernel at lists.infradead.org; Harini Katakam; Punnaiah Choudary Kalluri; Ranjit
> Abhimanyu Waghmode; ran27jit at gmail.com
> Subject: Re: [LINUX RFC 1/2] mtd: spi-nor: add dual parallel mode support
> 
> On Mon, Aug 03, 2015 at 02:35:06PM +0530, Ranjit Waghmode wrote:
> 
> >  drivers/mtd/devices/m25p80.c  |  1 +
> >  drivers/mtd/spi-nor/spi-nor.c | 92 ++++++++++++++++++++++++++++++++++--
> -------
> >  include/linux/mtd/spi-nor.h   |  3 ++
> >  include/linux/spi/spi.h       |  2 +
> >  4 files changed, 79 insertions(+), 19 deletions(-)
> 
> You need to at least split this into two patches, one adding a new SPI interface
> and another using it in MTD.  Probably the MTD core and driver changes need
> splitting too.  Please see SubmittingPatches for discussion of splitting things.
> 

I will split and resend the same.

> > diff --git a/include/linux/spi/spi.h b/include/linux/spi/spi.h index
> > d673072..8dec349 100644
> > --- a/include/linux/spi/spi.h
> > +++ b/include/linux/spi/spi.h
> > @@ -355,6 +355,8 @@ struct spi_master {
> >  #define SPI_MASTER_NO_TX	BIT(2)		/* can't do buffer write */
> >  #define SPI_MASTER_MUST_RX      BIT(3)		/* requires rx */
> >  #define SPI_MASTER_MUST_TX      BIT(4)		/* requires tx */
> > +#define SPI_MASTER_DATA_STRIPE		BIT(7)		/* support
> data stripe */
> > +#define SPI_MASTER_BOTH_CS		BIT(8)		/* enable both
> chips */
> 
> This is really not adequate description for a new API, I can't tell what "data
> stripe" is supposed to mean at all and I've got at best a vague idea what "both
> chips" really means.  This means other developers won't be able to tell how to
> use or implement these flags either, and it means I can't really review this.  You
> need to provide more information here, both in the code and in the commit
> message.
> 

I'm sorry about that. I have added description in cover letter, but will add more information about the same here too.

> I'd also expect some handling in the core for these, for example error handling if
> they can't be supported.

Will update and send you the updated version.

Thanks,
Ranjit


From raghumag at gmail.com  Tue Aug  4 22:07:08 2015
From: raghumag at gmail.com (raghu MG)
Date: Wed, 5 Aug 2015 10:37:08 +0530
Subject: Armadaxp GPIO interrupts
In-Reply-To: <20150804153439.GA28673@lunn.ch>
References: <CAG1O52Xg88OsifBzmpSdqvC8wQaOW78nC9nnfxugFv1VU1m1LQ@mail.gmail.com>
 <20150804153439.GA28673@lunn.ch>
Message-ID: <CAG1O52W2Gy_6_DfewtUqoK_J+Y=KwVGyygNaPu2xyPM_ZkLfcQ@mail.gmail.com>

Hi Andrew,

Thanks for your quick response,dont mind for the delay(India,US timings).
I checked with both multi_v7_defconfig & mvebu_v7_defconfig , the result is same
"irq: Cannot allocate irq_descs @ IRQ47, assuming pre-allocated"

Pasting here the GPIO driver probe debug statements

armada-xp-pinctrl f1018000.pin-ctrl: registered pinctrl driver
drivers/gpio/gpio-mvebu.c mvebu_gpio_probe 680
mvebu_gpio_probe 682 match->name=
mvebu_gpio_probe 683 match->compatible=marvell,orion-gpio
drivers/gpio/gpio-mvebu.c mvebu_gpio_probe 727
drivers/gpio/gpio-mvebu.c mvebu_gpio_probe 734 res->start=f1018100
mvchip->membase=cf8c0100
drivers/gpio/gpio-mvebu.c mvebu_gpio_probe 747 soc_variant=1
drivers/gpio/gpio-mvebu.c mvebu_gpio_probe 785
drivers/gpio/gpio-mvebu.c mvebu_gpio_probe 788
drivers/gpio/gpio-mvebu.c mvebu_gpio_probe 805
drivers/gpio/gpio-mvebu.c mvebu_gpio_probe 840
drivers/gpio/gpio-mvebu.c mvebu_gpio_probe 844 mvchip->irqbase=47
irq: Cannot allocate irq_descs @ IRQ47, assuming pre-allocated
drivers/gpio/gpio-mvebu.c mvebu_gpio_probe 850 mvchip->domain->name=(null)
drivers/gpio/gpio-mvebu.c mvebu_gpio_probe 859
drivers/gpio/gpio-mvebu.c mvebu_gpio_probe 680
mvebu_gpio_probe 682 match->name=
mvebu_gpio_probe 683 match->compatible=marvell,orion-gpio
drivers/gpio/gpio-mvebu.c mvebu_gpio_probe 727
drivers/gpio/gpio-mvebu.c mvebu_gpio_probe 734 res->start=f1018140
mvchip->membase=cf8c2140
drivers/gpio/gpio-mvebu.c mvebu_gpio_probe 747 soc_variant=1
drivers/gpio/gpio-mvebu.c mvebu_gpio_probe 785
drivers/gpio/gpio-mvebu.c mvebu_gpio_probe 788
drivers/gpio/gpio-mvebu.c mvebu_gpio_probe 805
drivers/gpio/gpio-mvebu.c mvebu_gpio_probe 840
drivers/gpio/gpio-mvebu.c mvebu_gpio_probe 844 mvchip->irqbase=79
irq: Cannot allocate irq_descs @ IRQ79, assuming pre-allocated
drivers/gpio/gpio-mvebu.c mvebu_gpio_probe 850 mvchip->domain->name=(null)
drivers/gpio/gpio-mvebu.c mvebu_gpio_probe 859
drivers/gpio/gpio-mvebu.c mvebu_gpio_probe 680
mvebu_gpio_probe 682 match->name=
mvebu_gpio_probe 683 match->compatible=marvell,orion-gpio
drivers/gpio/gpio-mvebu.c mvebu_gpio_probe 727
drivers/gpio/gpio-mvebu.c mvebu_gpio_probe 734 res->start=f1018180
mvchip->membase=cf8c4180
drivers/gpio/gpio-mvebu.c mvebu_gpio_probe 747 soc_variant=1
drivers/gpio/gpio-mvebu.c mvebu_gpio_probe 785
drivers/gpio/gpio-mvebu.c mvebu_gpio_probe 788
drivers/gpio/gpio-mvebu.c mvebu_gpio_probe 805
drivers/gpio/gpio-mvebu.c mvebu_gpio_probe 840
drivers/gpio/gpio-mvebu.c mvebu_gpio_probe 844 mvchip->irqbase=111
irq: Cannot allocate irq_descs @ IRQ111, assuming pre-allocated
drivers/gpio/gpio-mvebu.c mvebu_gpio_probe 850 mvchip->domain->name=(null)
drivers/gpio/gpio-mvebu.c mvebu_gpio_probe 859



I will try to dig in more information in the probe & irq_domain_add_simple


On Tue, Aug 4, 2015 at 9:04 PM, Andrew Lunn <andrew at lunn.ch> wrote:
> On Tue, Aug 04, 2015 at 08:52:17PM +0530, raghu MG wrote:
>> Hello,
>>
>> I am working on a card which as GPIOs connected to external I/O's. The
>> board consists of ARMADAXP 78460 host cpu.
>>
>> Board currently runs Linux-4.1 with modified  armada-xp-gp.dtb for ArmadaXP.
>> I enabled "orion-gpio" driver to initialize GPIOs as given in
>> armada-xp-mv78460.
>
> What kernel configuration are you using? Do you have the same problem
> with multi_v7_defconfig and mvebu_v7_defconfig?
>
>> The driver while initializing calls irq_domain_add_simple which throws up
>> following warning
>> "irq: Cannot allocate irq_descs @ IRQ47, assuming pre-allocated"
>> The warning repeats for next set(32-63  & 64-66).
>>
>> Also the GPIO IRQs are not getting listed in cat /proc/interrupts
>
> irq_domain_add_simple() returning an error is fatal for the probe. The
> driver will not be loaded, so more than interrupts will be missing,
> all the gpios will be missing.
>
>     Andrew


From hramrach at gmail.com  Tue Aug  4 22:21:00 2015
From: hramrach at gmail.com (Michal Suchanek)
Date: Wed, 5 Aug 2015 07:21:00 +0200
Subject: [RFC PATCH 1/5] spi: introduce flag for memory mapped read
In-Reply-To: <55C0FD98.1090107@ti.com>
References: <1438072876-16338-1-git-send-email-vigneshr@ti.com>
 <1438072876-16338-2-git-send-email-vigneshr@ti.com>
 <20150731181745.GM20873@sirena.org.uk>
 <55BEF4AF.5090704@ti.com> <20150804155148.GR20873@sirena.org.uk>
 <55C0FD98.1090107@ti.com>
Message-ID: <CAOMqctThys1C3vw7u8UU6iX8c9EDCWowaWg5F1O3i3X-w7KQhA@mail.gmail.com>

Hello,

On 4 August 2015 at 19:59, R, Vignesh <vigneshr at ti.com> wrote:
>
>
> On 8/4/2015 9:21 PM, Mark Brown wrote:
>> On Mon, Aug 03, 2015 at 10:27:19AM +0530, Vignesh R wrote:
>>
>>> @use_mmap_mode: Some SPI controller chips are optimized for interacting
>>> with serial flash memories. These chips have memory mapped interface,
>>> through which entire serial flash memory slave can be read/written as if
>>> though they are physical memories (like RAM). Using this interface,
>>> flash can be accessed using memcpy() function and the spi controller
>>> hardware will take care of communicating with serial flash over SPI.
>>> Setting this flag will indicate the SPI controller driver that the
>>> spi_message is from mtd layer to read from/write to flash. The SPI
>>> master driver can then appropriately switch the controller to memory
>>> mapped interface to read from/write to flash, based on this flag (See
>>> drivers/spi/spi-ti-qspi.c for example).
>>> NOTE: If the SPI controller chip lacks memory mapped interface, then the
>>> driver will ignore this flag and use normal SPI protocol to read
>>> from/write to flash. Communication with non-flash SPI devices is not
>>> possible using the memory mapped interface.
>>
>> I still can't tell from the above what this interface is supposed to do.
>> It sounds like the use of memory mapped mode is supposed to be
>> transparent to users, it should just affect how the controller interacts
>> with the hardware, but if that's the case why do we need to expose it to
>> users at all?  Shouldn't the driver just use memory mapped mode if it's
>> faster?
>>
>
> TI QSPI controller has two blocks:
> 1. SPI_CORE: This is generic(normal) spi mode. This can be used to
> communicate with any SPI devices (serial flashes as well as non-flash
> devices like touchscreen).
> 2. SFI_MM_IF(SPI memory mapped interface): The SFI_MM_IF block only
> allows reading and writing to an SPI flash device only. Used to speed up
> flash reads. It _cannot_ be used to communicate with non flash devices.
> Now, the spi_message that ti-qspi receives in transfer_one() callback
> can be from mtd device(in which case SFI_MM_IF can be used) or from any
> other non flash SPI device (in which case SFI_MM_IF must not be used
> instead SPI_CORE is to be used) but there is no way(is there?) to
> distinguish where spi_message is from. Therefore I introduced flag
> (use_mmap_mode) to struct spi_message. mtd driver will set flag to true,
> this helps the ti-qspi driver to determine that the user is flash device
> and thus can do read via SFI_MM_IF. If this flag is not set then the
> user is assumed to be non flash SPI driver and will use SPI_CORE block
> to communicate.
>
> On the whole, I just need a way to determine that the user is a flash
> device in order to switch to memory mapped interface.
>

Maybe it can be set on the SPI slave rather than each message.

Thanks

Michal


From vinod.koul at intel.com  Tue Aug  4 22:26:12 2015
From: vinod.koul at intel.com (Vinod Koul)
Date: Wed, 5 Aug 2015 10:56:12 +0530
Subject: [PATCH v2 1/2] dmaengine: Add an enum for the dmaengine
 alignment constraints
In-Reply-To: <1437381693-18948-1-git-send-email-maxime.ripard@free-electrons.com>
References: <1437381693-18948-1-git-send-email-maxime.ripard@free-electrons.com>
Message-ID: <20150805052612.GN11789@localhost>

On Mon, Jul 20, 2015 at 10:41:32AM +0200, Maxime Ripard wrote:
> Most drivers need to set constraints on the buffer alignment for async tx
> operations. However, even though it is documented, some drivers either use
> a defined constant that is not matching what the alignment variable expects
> (like DMA_BUSWIDTH_* constants) or fill the alignment in bytes instead of
> power of two.
> 
> Add a new enum for these alignments that matches what the framework
> expects, and convert the drivers to it.

Applied, thanks

-- 
~Vinod



From vinod.koul at intel.com  Tue Aug  4 22:26:56 2015
From: vinod.koul at intel.com (Vinod Koul)
Date: Wed, 5 Aug 2015 10:56:56 +0530
Subject: [PATCH v2 2/2] dmaengine: hdmac: Add memset capabilities
In-Reply-To: <1437381778-19108-1-git-send-email-maxime.ripard@free-electrons.com>
References: <1437381778-19108-1-git-send-email-maxime.ripard@free-electrons.com>
Message-ID: <20150805052656.GO11789@localhost>

On Mon, Jul 20, 2015 at 10:42:58AM +0200, Maxime Ripard wrote:
> Just like for the XDMAC, the SoCs that embed the HDMAC don't have any kind
> of GPU, and need to accelerate a few framebuffer-related operations through
> their DMA controller.
> 
> However, unlike the XDMAC, the HDMAC doesn't have the memset capability
> built-in. That can be easily emulated though, by doing a transfer with a
> fixed adress on the variable that holds the value we want to set.
typo  ^^^^^^^^

Applied, with typo fixed

-- 
~Vinod



From rnayak at codeaurora.org  Tue Aug  4 22:28:15 2015
From: rnayak at codeaurora.org (Rajendra Nayak)
Date: Wed, 05 Aug 2015 10:58:15 +0530
Subject: [PATCH v7 01/13] clk: qcom: Add support for GDSCs
In-Reply-To: <20150731162240.GG6519@usrtlx11787.corpusers.net>
References: <1438076046-4706-1-git-send-email-rnayak@codeaurora.org>
 <1438076046-4706-2-git-send-email-rnayak@codeaurora.org>
 <20150731162240.GG6519@usrtlx11787.corpusers.net>
Message-ID: <55C19EEF.40505@codeaurora.org>

[]..

>> +int gdsc_register(struct device *dev, struct gdsc **scs, size_t num,
>> +		  struct regmap *regmap)
>> +{
>> +	int i, ret;
>> +	struct genpd_onecell_data *data;
>> +
>> +	data = devm_kzalloc(dev, sizeof(*data), GFP_KERNEL);
>> +	if (!data)
>> +		return -ENOMEM;
>> +
>> +	data->domains = devm_kcalloc(dev, num, sizeof(*data->domains),
>> +				     GFP_KERNEL);
>> +	if (!data->domains)
>> +		return -ENOMEM;
>> +
>> +	data->num_domains = num;
>> +	for (i = 0; i < num; i++) {
>> +		if (!scs[i])
>> +			continue;
>> +		scs[i]->regmap = regmap;
>> +		ret = gdsc_init(scs[i]);
>> +		if (ret)
>> +			return ret;
>
> By this time we have disabled the HW control and here we just leave it
> as that, do you expect any interesting consequences of this?
> Or do we just not care (this shouldn't happen anyways).

The only cases where this could happen are when the regmap apis fail,
which ideally should not if the data passed is correct. Besides if
regmap apis do end up failing, the one which disables HW control would
probably fail as well?

>
>> +		data->domains[i] = &scs[i]->pd;
>> +	}
>> +
>> +	return of_genpd_add_provider_onecell(dev->of_node, data);
>> +}
>> +
>> +void gdsc_unregister(struct device *dev)
>> +{
>> +	of_genpd_del_provider(dev->of_node);
>> +}
>> diff --git a/drivers/clk/qcom/gdsc.h b/drivers/clk/qcom/gdsc.h
> [..]
>> +#ifdef CONFIG_QCOM_GDSC
>> +int gdsc_register(struct device *, struct gdsc **, size_t n, struct regmap *);
>> +void gdsc_unregister(struct device *);
>> +#else
>> +static inline int gdsc_register(struct device *d, struct gdsc **g, size_t n,
>> +				struct regmap *r)
>> +{
>> +	return -ENOSYS;
>
> This will cause qcom_cc_really_probe() to abort and unregister both its
> resets and clocks. I think you should just pretend that everything went
> fine and return 0...

qcom_cc_really_probe() ends up calling gdsc_register() only in cases
there are valid gdscs to be registered..

from drivers/clk/qcom/common.c
--
if (desc->gdscs && desc->num_gdscs)
	gdsc_register(...
--

..in which case I guess its fair to expect the platform with valid gdscs
to be registered has CONFIG_QCOM_GDSC enabled, and pretending everything
went fine might not be the right thing to do?


From vinod.koul at intel.com  Tue Aug  4 22:30:28 2015
From: vinod.koul at intel.com (Vinod Koul)
Date: Wed, 5 Aug 2015 11:00:28 +0530
Subject: [PATCH 0/2] dmaengine: Add scatter-gathered memset support
In-Reply-To: <1436177964-19380-1-git-send-email-maxime.ripard@free-electrons.com>
References: <1436177964-19380-1-git-send-email-maxime.ripard@free-electrons.com>
Message-ID: <20150805053028.GP11789@localhost>

On Mon, Jul 06, 2015 at 12:19:22PM +0200, Maxime Ripard wrote:
> Hi Vinod,
> 
> Here is a patch serie that adds a new dmaengine operation for
> scatter-gathered memset.
> 
> Indeed, doing a memset over a discontiguous buffer is quite
> inefficient at the moment, since you have to create and submit each
> chunk separately, which might result in a huge list of transfers,
> while some controllers can handle that just fine.

Applied, thanks

-- 
~Vinod



From rnayak at codeaurora.org  Tue Aug  4 22:31:16 2015
From: rnayak at codeaurora.org (Rajendra Nayak)
Date: Wed, 05 Aug 2015 11:01:16 +0530
Subject: [PATCH v7 01/13] clk: qcom: Add support for GDSCs
In-Reply-To: <20150803192427.GA7096@codeaurora.org>
References: <1438076046-4706-1-git-send-email-rnayak@codeaurora.org>
 <1438076046-4706-2-git-send-email-rnayak@codeaurora.org>
 <20150803192427.GA7096@codeaurora.org>
Message-ID: <55C19FA4.4070402@codeaurora.org>



On 08/04/2015 12:54 AM, Stephen Boyd wrote:
> On 07/28, Rajendra Nayak wrote:
>> +
>> +#define PWR_ON_MASK		BIT(31)
>> +#define EN_REST_WAIT_MASK	GENMASK(23, 20)
>> +#define EN_FEW_WAIT_MASK	GENMASK(19, 16)
>> +#define CLK_DIS_WAIT_MASK	GENMASK(15, 12)
>
> This trips up some static checker...
>
> drivers/clk/qcom/gdsc.c:234:53: warning: cast truncates bits from
> constant value (fffffffffff006 becomes fffff006)
>
> So I think we can use GENMASK_ULL here instead.

Sure. btw, what static checker is this? I did not see it with sparse.


From vigneshr at ti.com  Tue Aug  4 22:35:17 2015
From: vigneshr at ti.com (Vignesh R)
Date: Wed, 5 Aug 2015 11:05:17 +0530
Subject: [RFC PATCH 1/5] spi: introduce flag for memory mapped read
In-Reply-To: <CAOMqctThys1C3vw7u8UU6iX8c9EDCWowaWg5F1O3i3X-w7KQhA@mail.gmail.com>
References: <1438072876-16338-1-git-send-email-vigneshr@ti.com>
 <1438072876-16338-2-git-send-email-vigneshr@ti.com>
 <20150731181745.GM20873@sirena.org.uk> <55BEF4AF.5090704@ti.com>
 <20150804155148.GR20873@sirena.org.uk> <55C0FD98.1090107@ti.com>
 <CAOMqctThys1C3vw7u8UU6iX8c9EDCWowaWg5F1O3i3X-w7KQhA@mail.gmail.com>
Message-ID: <55C1A095.8000509@ti.com>



On 08/05/2015 10:51 AM, Michal Suchanek wrote:
> Hello,
> 
> On 4 August 2015 at 19:59, R, Vignesh <vigneshr at ti.com> wrote:
>>
>>
>> On 8/4/2015 9:21 PM, Mark Brown wrote:
>>> On Mon, Aug 03, 2015 at 10:27:19AM +0530, Vignesh R wrote:
>>>
>>>> @use_mmap_mode: Some SPI controller chips are optimized for interacting
>>>> with serial flash memories. These chips have memory mapped interface,
>>>> through which entire serial flash memory slave can be read/written as if
>>>> though they are physical memories (like RAM). Using this interface,
>>>> flash can be accessed using memcpy() function and the spi controller
>>>> hardware will take care of communicating with serial flash over SPI.
>>>> Setting this flag will indicate the SPI controller driver that the
>>>> spi_message is from mtd layer to read from/write to flash. The SPI
>>>> master driver can then appropriately switch the controller to memory
>>>> mapped interface to read from/write to flash, based on this flag (See
>>>> drivers/spi/spi-ti-qspi.c for example).
>>>> NOTE: If the SPI controller chip lacks memory mapped interface, then the
>>>> driver will ignore this flag and use normal SPI protocol to read
>>>> from/write to flash. Communication with non-flash SPI devices is not
>>>> possible using the memory mapped interface.
>>>
>>> I still can't tell from the above what this interface is supposed to do.
>>> It sounds like the use of memory mapped mode is supposed to be
>>> transparent to users, it should just affect how the controller interacts
>>> with the hardware, but if that's the case why do we need to expose it to
>>> users at all?  Shouldn't the driver just use memory mapped mode if it's
>>> faster?
>>>
>>
>> TI QSPI controller has two blocks:
>> 1. SPI_CORE: This is generic(normal) spi mode. This can be used to
>> communicate with any SPI devices (serial flashes as well as non-flash
>> devices like touchscreen).
>> 2. SFI_MM_IF(SPI memory mapped interface): The SFI_MM_IF block only
>> allows reading and writing to an SPI flash device only. Used to speed up
>> flash reads. It _cannot_ be used to communicate with non flash devices.
>> Now, the spi_message that ti-qspi receives in transfer_one() callback
>> can be from mtd device(in which case SFI_MM_IF can be used) or from any
>> other non flash SPI device (in which case SFI_MM_IF must not be used
>> instead SPI_CORE is to be used) but there is no way(is there?) to
>> distinguish where spi_message is from. Therefore I introduced flag
>> (use_mmap_mode) to struct spi_message. mtd driver will set flag to true,
>> this helps the ti-qspi driver to determine that the user is flash device
>> and thus can do read via SFI_MM_IF. If this flag is not set then the
>> user is assumed to be non flash SPI driver and will use SPI_CORE block
>> to communicate.
>>
>> On the whole, I just need a way to determine that the user is a flash
>> device in order to switch to memory mapped interface.
>>
> 
> Maybe it can be set on the SPI slave rather than each message.

You mean to add flag to spi_device struct? That's ok for me.

-- 
Regards
Vignesh


From hramrach at gmail.com  Tue Aug  4 22:57:40 2015
From: hramrach at gmail.com (Michal Suchanek)
Date: Wed, 5 Aug 2015 07:57:40 +0200
Subject: [RFC PATCH 1/5] spi: introduce flag for memory mapped read
In-Reply-To: <55C1A095.8000509@ti.com>
References: <1438072876-16338-1-git-send-email-vigneshr@ti.com>
 <1438072876-16338-2-git-send-email-vigneshr@ti.com>
 <20150731181745.GM20873@sirena.org.uk>
 <55BEF4AF.5090704@ti.com> <20150804155148.GR20873@sirena.org.uk>
 <55C0FD98.1090107@ti.com>
 <CAOMqctThys1C3vw7u8UU6iX8c9EDCWowaWg5F1O3i3X-w7KQhA@mail.gmail.com>
 <55C1A095.8000509@ti.com>
Message-ID: <CAOMqctS=E-MgPYC_eHSFM0FVtbKufs4LthpMGOeAGQ4k1MvT3Q@mail.gmail.com>

On 5 August 2015 at 07:35, Vignesh R <vigneshr at ti.com> wrote:
>
>
> On 08/05/2015 10:51 AM, Michal Suchanek wrote:
>> Hello,
>>
>> On 4 August 2015 at 19:59, R, Vignesh <vigneshr at ti.com> wrote:
>>>
>>>
>>> On 8/4/2015 9:21 PM, Mark Brown wrote:
>>>> On Mon, Aug 03, 2015 at 10:27:19AM +0530, Vignesh R wrote:
>>>>

>>>
>>> TI QSPI controller has two blocks:
>>> 1. SPI_CORE: This is generic(normal) spi mode. This can be used to
>>> communicate with any SPI devices (serial flashes as well as non-flash
>>> devices like touchscreen).
>>> 2. SFI_MM_IF(SPI memory mapped interface): The SFI_MM_IF block only
>>> allows reading and writing to an SPI flash device only. Used to speed up
>>> flash reads. It _cannot_ be used to communicate with non flash devices.
>>> Now, the spi_message that ti-qspi receives in transfer_one() callback
>>> can be from mtd device(in which case SFI_MM_IF can be used) or from any
>>> other non flash SPI device (in which case SFI_MM_IF must not be used
>>> instead SPI_CORE is to be used) but there is no way(is there?) to
>>> distinguish where spi_message is from. Therefore I introduced flag
>>> (use_mmap_mode) to struct spi_message. mtd driver will set flag to true,
>>> this helps the ti-qspi driver to determine that the user is flash device
>>> and thus can do read via SFI_MM_IF. If this flag is not set then the
>>> user is assumed to be non flash SPI driver and will use SPI_CORE block
>>> to communicate.
>>>
>>> On the whole, I just need a way to determine that the user is a flash
>>> device in order to switch to memory mapped interface.
>>>
>>
>> Maybe it can be set on the SPI slave rather than each message.
>
> You mean to add flag to spi_device struct? That's ok for me.
>

There are already mode flags so you can just add one more.

Thanks

Michal


From linux at roeck-us.net  Tue Aug  4 23:14:26 2015
From: linux at roeck-us.net (Guenter Roeck)
Date: Tue, 04 Aug 2015 23:14:26 -0700
Subject: [PATCH v2 1/2] drivers: watchdog: add a driver to support SAMA5D4
 watchdog timer
In-Reply-To: <1438742130-2089-2-git-send-email-wenyou.yang@atmel.com>
References: <1438742130-2089-1-git-send-email-wenyou.yang@atmel.com>
 <1438742130-2089-2-git-send-email-wenyou.yang@atmel.com>
Message-ID: <55C1A9C2.5070808@roeck-us.net>

On 08/04/2015 07:35 PM, Wenyou Yang wrote:
>>From SAMA5D4, the watchdog timer is upgrated with a new feature,
> which is describled as in the datasheet, "WDT_MR can be written
> until a LOCKMR command is issued in WDT_CR".
> That is to say, as long as the bootstrap and u-boot don't issue
> a LOCKMR command, WDT_MR can be written more than once in the driver.
>
> So the SAMA5D4 watchdog driver's implementation is different from
> the previous: the user application open the device file to enable

Which previous ? Please let the reader know which one you refer to.

> the watchdog timer hardware, and close to disable it, and set the
> watchdog timer timeout by seting WDV and WDD fields of WDT_MR register,
> and ping the watchdog by issuing WDRSTT command to WDT_CR register
> with hard-coded key.
>
> Signed-off-by: Wenyou Yang <wenyou.yang at atmel.com>
> ---
>   drivers/watchdog/Kconfig        |    9 ++
>   drivers/watchdog/Makefile       |    1 +
>   drivers/watchdog/at91sam9_wdt.h |    4 +
>   drivers/watchdog/atmel_wdt.c    |  290 +++++++++++++++++++++++++++++++++++++++
>   4 files changed, 304 insertions(+)
>   create mode 100644 drivers/watchdog/atmel_wdt.c
>
> diff --git a/drivers/watchdog/Kconfig b/drivers/watchdog/Kconfig
> index e5e7c55..4425813 100644
> --- a/drivers/watchdog/Kconfig
> +++ b/drivers/watchdog/Kconfig
> @@ -152,6 +152,15 @@ config ARM_SP805_WATCHDOG
>   	  ARM Primecell SP805 Watchdog timer. This will reboot your system when
>   	  the timeout is reached.
>
> +config ATMEL_WATCHDOG
> +	tristate "Atmel SAMA5D4 Watchdog Timer"
> +	depends on ARCH_AT91
> +	select WATCHDOG_CORE
> +	help
> +	  Atmel watchdog timer embedded into SAMA5D4 chips. Its Watchdog Timer
> +	  Mode Register(WDT_MR) can be written more than once.
> +	  This will reboot your system when the timeout is reached.
> +

ATMEL is highly generic. Can you find a more specific name ?
If this is part of the AT91 family, it could be something
like AT91SAMAD54, for example.

Same goes for the driver name.

>   config AT91RM9200_WATCHDOG
>   	tristate "AT91RM9200 watchdog"
>   	depends on SOC_AT91RM9200 && MFD_SYSCON
> diff --git a/drivers/watchdog/Makefile b/drivers/watchdog/Makefile
> index 5c19294..c24a8fc 100644
> --- a/drivers/watchdog/Makefile
> +++ b/drivers/watchdog/Makefile
> @@ -30,6 +30,7 @@ obj-$(CONFIG_USBPCWATCHDOG) += pcwd_usb.o
>
>   # ARM Architecture
>   obj-$(CONFIG_ARM_SP805_WATCHDOG) += sp805_wdt.o
> +obj-$(CONFIG_ATMEL_WATCHDOG) += atmel_wdt.o
>   obj-$(CONFIG_AT91RM9200_WATCHDOG) += at91rm9200_wdt.o
>   obj-$(CONFIG_AT91SAM9X_WATCHDOG) += at91sam9_wdt.o
>   obj-$(CONFIG_CADENCE_WATCHDOG) += cadence_wdt.o
> diff --git a/drivers/watchdog/at91sam9_wdt.h b/drivers/watchdog/at91sam9_wdt.h
> index c6fbb2e6..79add4f 100644
> --- a/drivers/watchdog/at91sam9_wdt.h
> +++ b/drivers/watchdog/at91sam9_wdt.h
> @@ -22,11 +22,15 @@
>
>   #define AT91_WDT_MR		0x04			/* Watchdog Mode Register */
>   #define		AT91_WDT_WDV		(0xfff << 0)		/* Counter Value */
> +#define			AT91_WDT_WDV_MSK	(0xfff)

The ( ) is not necessary. AT91_WDT_WDV is already used as mask.
You should not need a second one.

> +#define			AT91_WDT_WDV_(x)	(((x) & AT91_WDT_WDV_MSK) << 0)

Please no '_' at the end of the macro name; find another name that isn't
as close to AT91_WDT_WDV.

>   #define		AT91_WDT_WDFIEN		(1     << 12)		/* Fault Interrupt Enable */
>   #define		AT91_WDT_WDRSTEN	(1     << 13)		/* Reset Processor */
>   #define		AT91_WDT_WDRPROC	(1     << 14)		/* Timer Restart */
>   #define		AT91_WDT_WDDIS		(1     << 15)		/* Watchdog Disable */
>   #define		AT91_WDT_WDD		(0xfff << 16)		/* Delta Value */
> +#define			AT91_WDT_WDD_MSK	(0xfff)

( ) is unnecessary. Also, AT91_WDT_WDD is already used as mask.
No need to specify a second one.

> +#define			AT91_WDT_WDD_(x)	(((x) & AT91_WDT_WDD_MSK) << 16)

Again, please no '_' at the end of the macro name.

>   #define		AT91_WDT_WDDBGHLT	(1     << 28)		/* Debug Halt */
>   #define		AT91_WDT_WDIDLEHLT	(1     << 29)		/* Idle Halt */
>
> diff --git a/drivers/watchdog/atmel_wdt.c b/drivers/watchdog/atmel_wdt.c
> new file mode 100644
> index 0000000..e1cdc84
> --- /dev/null
> +++ b/drivers/watchdog/atmel_wdt.c
> @@ -0,0 +1,290 @@
> +/*
> + * Driver for Atmel SAMA5D4 Watchdog Timer
> + *
> + * Copyright (C) 2015 Atmel Corporation
> + *
> + * Licensed under GPLv2.
> + */
> +
> +#include <linux/kernel.h>
> +#include <linux/module.h>
> +#include <linux/interrupt.h>
> +#include <linux/io.h>
> +#include <linux/of.h>
> +#include <linux/of_irq.h>
> +#include <linux/platform_device.h>
> +#include <linux/watchdog.h>
> +#include <linux/reboot.h>

Please use alphabetic order for include files. That makes
it easier to find files, and simplifies later additions.

> +
> +#include "at91sam9_wdt.h"
> +
> +/* minimum and maximum watchdog timeout, in seconds */
> +#define MIN_WDT_TIMEOUT		1
> +#define MAX_WDT_TIMEOUT		16
> +#define WDT_DEFAULT_TIMEOUT	MAX_WDT_TIMEOUT
> +
> +#define WDT_MAX_WDV		0xFFF
> +
> +#define WDT_SEC2TICKS(s)	((s) ? (((s) << 8) - 1) : 0)
> +
> +struct atmel_wdt {
> +	struct watchdog_device	wdd;
> +	void __iomem		*reg_base;
> +	u32	config;
> +};
> +
> +static int wdt_timeout = WDT_DEFAULT_TIMEOUT;
> +static bool nowayout = WATCHDOG_NOWAYOUT;
> +
> +module_param(wdt_timeout, int, 0);
> +MODULE_PARM_DESC(wdt_timeout,
> +	"Watchdog wdt_timeout in seconds. (default = "
> +	__MODULE_STRING(WDT_DEFAULT_TIMEOUT) ")");
> +
> +module_param(nowayout, bool, 0);
> +MODULE_PARM_DESC(nowayout,
> +	"Watchdog cannot be stopped once started (default="
> +	__MODULE_STRING(WATCHDOG_NOWAYOUT) ")");
> +
> +#define wdt_read(wdt, field) \
> +	readl_relaxed((wdt)->reg_base + (field))
> +
> +#define wdt_write(wtd, field, val) \
> +	writel_relaxed((val), (wdt)->reg_base + (field))
> +
> +static int atmel_wdt_start(struct watchdog_device *wdd)
> +{
> +	struct atmel_wdt *wdt = watchdog_get_drvdata(wdd);
> +	u32 reg;
> +
> +	reg = wdt_read(wdt, AT91_WDT_MR);
> +	reg &= ~AT91_WDT_WDDIS;
> +	wdt_write(wdt, AT91_WDT_MR, reg);
> +
> +	return 0;
> +}
> +
> +static int atmel_wdt_stop(struct watchdog_device *wdd)
> +{
> +	struct atmel_wdt *wdt = watchdog_get_drvdata(wdd);
> +	u32 reg;
> +
> +	reg = wdt_read(wdt, AT91_WDT_MR);
> +	reg |= AT91_WDT_WDDIS;
> +	wdt_write(wdt, AT91_WDT_MR, reg);
> +
> +	return 0;
> +}
> +
> +static int atmel_wdt_ping(struct watchdog_device *wdd)
> +{
> +	struct atmel_wdt *wdt = watchdog_get_drvdata(wdd);
> +
> +	wdt_write(wdt, AT91_WDT_CR, AT91_WDT_KEY | AT91_WDT_WDRSTT);
> +
> +	return 0;
> +}
> +
> +static int atmel_wdt_set_timeout(struct watchdog_device *wdd,
> +				 unsigned int timeout)
> +{
> +	struct atmel_wdt *wdt = watchdog_get_drvdata(wdd);
> +	u32 reg, value;
> +
> +	value = WDT_SEC2TICKS(timeout);
> +	if (value > WDT_MAX_WDV)
> +		return -EINVAL;
> +
Unnecessary check.

> +	reg = wdt_read(wdt, AT91_WDT_MR);
> +	reg &= ~AT91_WDT_WDV;
> +	reg &= ~AT91_WDT_WDD;
> +	reg |= AT91_WDT_WDV_(value);
> +	reg |= AT91_WDT_WDD_(value);
> +	wdt_write(wdt, AT91_WDT_MR, reg);
> +
> +	wdd->timeout = timeout;
> +
> +	return 0;
> +}
> +
> +static const struct watchdog_info atmel_wdt_info = {
> +	.options = WDIOF_SETTIMEOUT | WDIOF_MAGICCLOSE | WDIOF_KEEPALIVEPING,
> +	.firmware_version = 0,
> +	.identity = "Atmel SAMA5D4 Watchdog",
> +};
> +
> +static struct watchdog_ops atmel_wdt_ops = {
> +	.owner = THIS_MODULE,
> +	.start = atmel_wdt_start,
> +	.stop = atmel_wdt_stop,
> +	.ping = atmel_wdt_ping,
> +	.set_timeout = atmel_wdt_set_timeout,
> +};
> +
> +static irqreturn_t atmel_wdt_irq_handler(int irq, void *dev_id)
> +{
> +	struct atmel_wdt *wdt = platform_get_drvdata(dev_id);
> +
> +	if (wdt_read(wdt, AT91_WDT_SR)) {
> +		pr_crit("Atmel Watchdog Software Reset\n");
> +		emergency_restart();
> +		pr_crit("Reboot didn't ?????\n");
> +	}
> +
> +	return IRQ_HANDLED;
> +}
> +
> +static int of_atmel_wdt_init(struct device_node *np, struct atmel_wdt *wdt)
> +{
> +	const char *tmp;
> +
> +	wdt->config = AT91_WDT_WDDIS;
> +
> +	if (!of_property_read_string(np, "atmel,watchdog-type", &tmp) &&
> +	    !strcmp(tmp, "software"))
> +		wdt->config |= AT91_WDT_WDFIEN;
> +	else
> +		wdt->config |= AT91_WDT_WDRSTEN;
> +
> +	if (of_property_read_bool(np, "atmel,idle-halt"))
> +		wdt->config |= AT91_WDT_WDIDLEHLT;
> +
> +	if (of_property_read_bool(np, "atmel,dbg-halt"))
> +		wdt->config |= AT91_WDT_WDDBGHLT;
> +
> +	return 0;
> +}
> +
> +static int atmel_wdt_init(struct atmel_wdt *wdt)
> +{
> +	struct watchdog_device *wdd = &wdt->wdd;
> +	u32 value, timeout;
> +
> +	timeout = WDT_SEC2TICKS(wdd->timeout);
> +	if (timeout > WDT_MAX_WDV)
> +		return -1;
> +

Unnecessary range check.

> +	/*
> +	 * Because the fields WDV and WDD must not be modified when the WDDIS
> +	 * bit is set, so clear the WDDIS bit before writing the WDT_MR.
> +	 */
> +	value = wdt_read(wdt, AT91_WDT_MR);
> +	value &= ~AT91_WDT_WDDIS;
> +	wdt_write(wdt, AT91_WDT_MR, value);
> +
> +	value = wdt->config;
> +	value |= AT91_WDT_WDD_(timeout);
> +	value |= AT91_WDT_WDV_(timeout);
> +
> +	wdt_write(wdt, AT91_WDT_MR, value);
> +
> +	return 0;
> +}
> +
> +static int atmel_wdt_probe(struct platform_device *pdev)
> +{
> +	struct watchdog_device *wdd;
> +	struct atmel_wdt *wdt;
> +	struct resource *res;
> +	void __iomem *regs;
> +	int ret, irq = -1;
> +
> +	wdt = devm_kzalloc(&pdev->dev, sizeof(*wdt), GFP_KERNEL);
> +	if (!wdt)
> +		return -ENOMEM;
> +
> +	wdd = &wdt->wdd;
> +	wdd->timeout = wdt_timeout;
> +	wdd->info = &atmel_wdt_info;
> +	wdd->ops = &atmel_wdt_ops;
> +	wdd->min_timeout = MIN_WDT_TIMEOUT;
> +	wdd->max_timeout = MAX_WDT_TIMEOUT;
> +
> +	watchdog_set_drvdata(wdd, wdt);
> +
> +	res = platform_get_resource(pdev, IORESOURCE_MEM, 0);
> +	regs = devm_ioremap_resource(&pdev->dev, res);
> +	if (IS_ERR(regs))
> +		return PTR_ERR(regs);
> +
> +	wdt->reg_base = regs;
> +
> +	if (pdev->dev.of_node) {
> +		irq = irq_of_parse_and_map(pdev->dev.of_node, 0);
> +		if (!irq)
> +			dev_warn(&pdev->dev, "the IRQ NOT specify from DT\n");

"failed to get IRQ from DT" would be a better message.
This leaves irq set to 0 in the error case, and cause the code below
to request an interrupt.

> +
> +		ret = of_atmel_wdt_init(pdev->dev.of_node, wdt);
> +		if (ret)
> +			return ret;
> +	}
> +
> +	if ((wdt->config & AT91_WDT_WDFIEN) && (irq >= 0)) {

Second ( ) is unnecessary.

> +		ret = devm_request_irq(&pdev->dev, irq, atmel_wdt_irq_handler,
> +				       0, pdev->name, pdev);
> +		if (ret) {
> +			dev_err(&pdev->dev,
> +				"cannot register interrupt handler\n");
> +			return ret;
> +		}
> +	}
> +
> +	ret = watchdog_init_timeout(wdd, wdt_timeout, &pdev->dev);
> +	if (ret) {
> +		dev_err(&pdev->dev, "unable to set timeout value\n");
> +		return ret;

I would suggest to set the default timeout in this case, as done by other drivers.

> +	}
> +
> +	ret = atmel_wdt_init(wdt);
> +	if (ret)
> +		return ret;
> +
> +	watchdog_set_nowayout(wdd, nowayout);
> +
> +	ret = watchdog_register_device(wdd);
> +	if (ret) {
> +		dev_err(&pdev->dev, "failed to register watchdog device\n");
> +		return ret;
> +	}
> +
> +	platform_set_drvdata(pdev, wdt);
> +
> +	dev_info(&pdev->dev, "initialized (timeout = %d sec, nowayout = %d)\n",
> +		 wdt_timeout, nowayout);
> +
> +	return 0;
> +}
> +
> +static int atmel_wdt_remove(struct platform_device *pdev)
> +{
> +	struct atmel_wdt *wdt = platform_get_drvdata(pdev);
> +
> +	atmel_wdt_stop(&wdt->wdd);
> +
> +	watchdog_unregister_device(&wdt->wdd);
> +
> +	dev_info(&pdev->dev, "removed wdt\n");
> +
Unnecessary message.

> +	return 0;
> +}
> +
> +static const struct of_device_id atmel_wdt_of_match[] = {
> +	{ .compatible = "atmel,sama5d4-wdt", },
> +	{ },
> +};
> +MODULE_DEVICE_TABLE(of, atmel_wdt_of_match);
> +
> +static struct platform_driver atmel_wdt_driver = {
> +	.probe		= atmel_wdt_probe,
> +	.remove		= atmel_wdt_remove,
> +	.driver		= {
> +		.name	= "atmel-wdt",
> +		.of_match_table = atmel_wdt_of_match,
> +	},
> +};
> +module_platform_driver(atmel_wdt_driver);
> +
> +MODULE_ALIAS("platform:atmel-wdt");
> +MODULE_AUTHOR("Atmel Corporation");
> +MODULE_DESCRIPTION("Atmel SAMA5D4 Watchdog Timer driver");
> +MODULE_LICENSE("GPL v2");
>



From vaibhav.hiremath at linaro.org  Tue Aug  4 23:29:01 2015
From: vaibhav.hiremath at linaro.org (Vaibhav Hiremath)
Date: Wed, 05 Aug 2015 11:59:01 +0530
Subject: [PATCH-v5 4/5] Documentation: binding: add sclk adjustment
 properties to i2c-pxa
In-Reply-To: <20150727141152.GC15004@beef>
References: <1437482466-16126-1-git-send-email-vaibhav.hiremath@linaro.org>
 <1437482466-16126-5-git-send-email-vaibhav.hiremath@linaro.org>
 <20150727141152.GC15004@beef>
Message-ID: <55C1AD2D.90109@linaro.org>



On Monday 27 July 2015 07:41 PM, Matt Porter wrote:
> On Tue, Jul 21, 2015 at 06:11:05PM +0530, Vaibhav Hiremath wrote:
>> With addition of PXA910 family of devices, the TWSI module supports
>> new feature which allows us to adjust SCLK. i2c-pxa driver takes input
>> configuration in nsec and converts it to respective bit-fields,
>>
>>   - i2c-sclk-low-time-ns : SCLK low time (tlow)
>>     This property is used along with mode selection.
>>   - i2c-sclk-high-time-ns : SCLK high time (thigh)
>>   - i2c-start-hold-time-ns : Used in case of high speed mode for start bit
>>     hold/setup wait counter.
>>   - i2c-stop-hold-time-ns : Used in case of high speed mode for stop bit
>>     hold/setup wait counter.
>>   - i2c-sda-hold-time-ns : Used to calculate hold/setup wait counter for
>>     standard and fast mode.
>
> Again, these should have a mrvl prefix..very specific to this PXA
> controller.
>

Sorry for delayed response, was down with health issue for week.

Coming back to your comment,

No, they are not Marvell specific. If you refer back to my V1, we
discussed about it and concluded that we should use generic property
here.
There are quite a few drivers using same properties for similar purpose.

Thanks,
Vaibhav


From vaibhav.hiremath at linaro.org  Tue Aug  4 23:34:25 2015
From: vaibhav.hiremath at linaro.org (Vaibhav Hiremath)
Date: Wed, 05 Aug 2015 12:04:25 +0530
Subject: [PATCH-v5 1/5] Documentation: binding: add new property
 'disable_after_xfer' to i2c-pxa
In-Reply-To: <20150727140911.GB15004@beef>
References: <1437482466-16126-1-git-send-email-vaibhav.hiremath@linaro.org>
 <1437482466-16126-2-git-send-email-vaibhav.hiremath@linaro.org>
 <20150727140911.GB15004@beef>
Message-ID: <55C1AE71.3010700@linaro.org>



On Monday 27 July 2015 07:39 PM, Matt Porter wrote:
> On Tue, Jul 21, 2015 at 06:11:02PM +0530, Vaibhav Hiremath wrote:
>> Driver will now supports enable/disable across msg xfer, which user
>> can control it by new DT property -
>>
>> i2c-disable-after-xfer : If set, driver will disable I2C module after msg
>>   xfer and enable it back before xfer.
>
> If this is a new property specific to this Marvell part, it needs
> the vendor prefix as in mrvl,i2c-disable-after-xfer
>

We discussed about this, I think in V1 or V2. Decided to use generic
name, as feature (in turn property) could be used by other drivers as
well.

> Or, it couldn't hurt to start an i2c.txt for generic i2c bindings
> and store it there as this and others later in this series would
> reasonably apply to other controllers.
>

Yeah, we could start i2c.txt, probably better to have separate new
patch all together.


Thanks,
Vaibhav


From vaibhav.hiremath at linaro.org  Tue Aug  4 23:39:42 2015
From: vaibhav.hiremath at linaro.org (Vaibhav Hiremath)
Date: Wed, 05 Aug 2015 12:09:42 +0530
Subject: [PATCH 2/4] mfd: devicetree: bindings: Add clock subdevice node
 information
In-Reply-To: <CAL_Jsq+BuhbHgnYi6HfAJx986vtDuUJzbxBRgivX9pF1GhUSvQ@mail.gmail.com>
References: <1437476823-3358-1-git-send-email-vaibhav.hiremath@linaro.org>
 <1437476823-3358-3-git-send-email-vaibhav.hiremath@linaro.org>
 <CAJKOXPeUJ-7je67q+9X1_FcFiczoQ6rqwMAoPLswapFEmqGGVg@mail.gmail.com>
 <55BAA17F.1070305@codeaurora.org>
 <CAL_Jsq+BuhbHgnYi6HfAJx986vtDuUJzbxBRgivX9pF1GhUSvQ@mail.gmail.com>
Message-ID: <55C1AFAE.3000500@linaro.org>



On Friday 31 July 2015 03:51 AM, Rob Herring wrote:
> On Thu, Jul 30, 2015 at 5:13 PM, Stephen Boyd <sboyd at codeaurora.org> wrote:
>> On 07/22/2015 10:08 PM, Krzysztof Kozlowski wrote:
>>>
>>> 2015-07-21 20:07 GMT+09:00 Vaibhav Hiremath <vaibhav.hiremath at linaro.org>:
>>>>
>>>> This patch updates the binding documentation for optional
>>>> clocks node and related information for buffered 32KHz clock.
>>>>
>>>> Signed-off-by: Vaibhav Hiremath <vaibhav.hiremath at linaro.org>
>>>> ---
>>>>    Documentation/devicetree/bindings/mfd/88pm800.txt | 28
>>>> +++++++++++++++++++++++
>>>>    1 file changed, 28 insertions(+)
>>>
>>> +Cc Stephen Boyd (clocks)
>>>
>>> We had a discussion whether clock bindings should be put in MFD
>>> bindings documentation or into separate file in bindings/clock but
>>> either way is fine for me:
>>
>>
>> No patch? :)
>>
>> I think Rob has been pushing for MFDs to document everything within one
>> file, but either way is fine from clk perspective.
>
> I don't recall that exactly. I did say that child bindings need to
> point back to the MFD binding. So this is fine with me:
>
> Acked-by: Rob Herring <robh at kernel.org>
>

Thanks Rob for the ack.

Can this be queued now (for next merge window)?

Thanks,
Vaibhav




From sjoerd.simons at collabora.co.uk  Tue Aug  4 23:42:01 2015
From: sjoerd.simons at collabora.co.uk (Sjoerd Simons)
Date: Wed, 05 Aug 2015 08:42:01 +0200
Subject: [PATCH v2 0/4] Add SPDIF support for rockchip
In-Reply-To: <20150804153649.GP20873@sirena.org.uk>
References: <1438687099-14282-1-git-send-email-sjoerd.simons@collabora.co.uk>
 <20150804153649.GP20873@sirena.org.uk>
Message-ID: <1438756921.27576.4.camel@collabora.co.uk>

On Tue, 2015-08-04 at 16:36 +0100, Mark Brown wrote:
> On Tue, Aug 04, 2015 at 01:18:15PM +0200, Sjoerd Simons wrote:
> 
> > Sjoerd Simons (4):
> >   ASoC: dt-bindings: add rockchip tranceiver bindings
> >   ASoc: rockchip: Add rockchip SPDIF transceiver driver
> 
> I only appear to have patch 2 (with the misspelt subject), not the
> binding documentation.

Applogies, Send that patch specifically to you now.

Seems get_maintainers.pl didn't include you in the list (nor the other
asoc maintainers in the list), I guess it might be good to add
Documentation/devicetree/bindings/sounds/ to the ASoC file list in
MAINTAINTERS ?

-- 
Sjoerd Simons
Collabora Ltd.


From s.hauer at pengutronix.de  Tue Aug  4 23:46:05 2015
From: s.hauer at pengutronix.de (Sascha Hauer)
Date: Wed, 5 Aug 2015 08:46:05 +0200
Subject: [PATCH v6 7/9] clk: mediatek: Add subsystem clocks of MT8173
In-Reply-To: <1438676218-11310-8-git-send-email-jamesjj.liao@mediatek.com>
References: <1438676218-11310-1-git-send-email-jamesjj.liao@mediatek.com>
 <1438676218-11310-8-git-send-email-jamesjj.liao@mediatek.com>
Message-ID: <20150805064605.GZ18700@pengutronix.de>

On Tue, Aug 04, 2015 at 04:16:56PM +0800, James Liao wrote:
> Most multimedia subsystem clocks will be accessed by multiple
> drivers, so it's a better way to manage these clocks in CCF.
> This patch adds clock support for MM, IMG, VDEC, VENC and VENC_LT
> subsystems.
> 
> Signed-off-by: James Liao <jamesjj.liao at mediatek.com>
> ---
>  drivers/clk/mediatek/clk-mt8173.c      | 267 +++++++++++++++++++++++++++++++++
>  include/dt-bindings/clock/mt8173-clk.h |  97 +++++++++++-
>  2 files changed, 361 insertions(+), 3 deletions(-)
> 
> diff --git a/drivers/clk/mediatek/clk-mt8173.c b/drivers/clk/mediatek/clk-mt8173.c
> index f37ace6..05335e5 100644
> --- a/drivers/clk/mediatek/clk-mt8173.c
> +++ b/drivers/clk/mediatek/clk-mt8173.c
> @@ -25,6 +25,10 @@ static DEFINE_SPINLOCK(mt8173_clk_lock);
>  static const struct mtk_fixed_clk fixed_clks[] __initconst = {
>  	FIXED_CLK(CLK_TOP_CLKPH_MCK_O, "clkph_mck_o", "clk26m", 400 * MHZ),
>  	FIXED_CLK(CLK_TOP_USB_SYSPLL_125M, "usb_syspll_125m", "clk26m", 125 * MHZ),
> +	FIXED_CLK(CLK_TOP_DSI0_DIG, "dsi0_dig", "clk26m", 130 * MHZ),
> +	FIXED_CLK(CLK_TOP_DSI1_DIG, "dsi1_dig", "clk26m", 130 * MHZ),
> +	FIXED_CLK(CLK_TOP_LVDS_PXL, "lvds_pxl", "lvdspll", 148.5 * MHZ),
> +	FIXED_CLK(CLK_TOP_LVDS_CTS, "lvds_cts", "lvdspll", 51.975 * MHZ),

I would expect 51975 * KHZ here to avoid fractional numbers. Probably
gcc calculates that during compile time so this will work as expected,
still I'm not sure this is good style to use fractional numbers here.

Anyway, on my system lvdspll is running at 150MHz. Are you sure there is
a clock derived from this running at 148.5MHz? Is it really correct to
use a fixed clock here or should it rather be lvdspll directly?

Sascha


-- 
Pengutronix e.K.                           |                             |
Industrial Linux Solutions                 | http://www.pengutronix.de/  |
Peiner Str. 6-8, 31137 Hildesheim, Germany | Phone: +49-5121-206917-0    |
Amtsgericht Hildesheim, HRA 2686           | Fax:   +49-5121-206917-5555 |


From geert at linux-m68k.org  Tue Aug  4 23:48:13 2015
From: geert at linux-m68k.org (Geert Uytterhoeven)
Date: Wed, 5 Aug 2015 08:48:13 +0200
Subject: [PATCH] ARM: shmobile: Add silk device tree bindings documentation
In-Reply-To: <1438723848-14812-1-git-send-email-horms+renesas@verge.net.au>
References: <1438723848-14812-1-git-send-email-horms+renesas@verge.net.au>
Message-ID: <CAMuHMdWqi0ck9A-QyjAOkAHVQYnfU0tqpFYERZbgjqc6dLJ12Q@mail.gmail.com>

On Tue, Aug 4, 2015 at 11:30 PM, Simon Horman
<horms+renesas at verge.net.au> wrote:
> Add Silk Device tree bindings Documentation, listing it as a supported board.
>
> This allows to use checkpatch to validate DTSes referring to the Silk board.
>
> Signed-off-by: Simon Horman <horms+renesas at verge.net.au>

Acked-by: Geert Uytterhoeven <geert+renesas at glider.be>

Gr{oetje,eeting}s,

                        Geert

--
Geert Uytterhoeven -- There's lots of Linux beyond ia32 -- geert at linux-m68k.org

In personal conversations with technical people, I call myself a hacker. But
when I'm talking to journalists I just say "programmer" or something like that.
                                -- Linus Torvalds


From geert at linux-m68k.org  Tue Aug  4 23:51:56 2015
From: geert at linux-m68k.org (Geert Uytterhoeven)
Date: Wed, 5 Aug 2015 08:51:56 +0200
Subject: [PATCH v2 0/6] ARM: shmobile: Move gpio ranges from C code to DT
In-Reply-To: <20150805005540.GB20726@verge.net.au>
References: <1438696519-13727-1-git-send-email-geert+renesas@glider.be>
 <20150805005540.GB20726@verge.net.au>
Message-ID: <CAMuHMdW5mAdmCVh91QwwwBxRD_Bd+wgiE7ijXH43=JqKe6aM=g@mail.gmail.com>

Hi Simon,

On Wed, Aug 5, 2015 at 2:55 AM, Simon Horman <horms at verge.net.au> wrote:
> On Tue, Aug 04, 2015 at 03:55:13PM +0200, Geert Uytterhoeven wrote:
>> This patch series moves the setup of the GPIO-PFC pin mapping for
>> Renesas PFC/GPIO combos from C code to DT, and does some cleanups.
>> The move to DT is needed to make the GPIO hogging mechanism work, cfr.
>> the discussion following "[PATCH] [RFC] gpio: Retry deferred GPIO
>> hogging on pin range change" (https://lkml.org/lkml/2015/6/16/455).
>>
>> The series consists of 3 parts:
>>   a. Patches 1-3 add the missing "gpio-ranges" properties to the dtsi
>>      files for all affected SoCs,
>>   b. Patch 4 disables the C code to set up the mapping on DT platforms
>>      (it's still needed on SH or ARM-legacy),
>>   c. Patches 5-6 do a few more cleanups in the sh-pfc gpio code.
>>
>> Changes compared to v1 ("[PATCH 0/7] ARM: shmobile: Move gpio ranges
>> from C code to DT",
>> http://lists.infradead.org/pipermail/linux-arm-kernel/2015-June/353124.html):
>>   - Add check for CONFIG_OF and pfc->dev->of_node,
>>   - #ifdef out the code instead of introducing helper and dummy
>>     functions,
>>   - Drop "pinctrl: sh-pfc: Move sh_pfc_add_gpiochip() up", as it's no
>>     longer needed due to the #ifdefs,
>>   - Add Acked-by.
>>
>> Dependencies:
>>   - This series applies against renesas-devel-20150803-v4.2-rc5,
>>   - Part a must go in first, to avoid regressions,
>>   - While I didn't notice any bad behavior by having part a only, part b
>>     should go in immediately after part a. Hence I think it's best if
>>     Simon can take this one, too.
>>   - Part c is independent (it doesn't touch the same code), so it can go
>>     in before or after the other parts, or in parallel.
>>
>> Given this fixes the LCD on r8a7740/armadillo, which is a regression
>> introduced by the removal of armadillo-legacy support, I think at least
>> patch 2 should be queued for v4.3.
>>
>> Thanks for applying!
>>
>> Geert Uytterhoeven (6):
>>   ARM: shmobile: r8a73a4 dtsi: Add missing "gpio-ranges" to gpio node
>>   ARM: shmobile: r8a7740 dtsi: Add missing "gpio-ranges" to gpio node
>>   ARM: shmobile: sh73a0 dtsi: Add missing "gpio-ranges" to gpio node
>>   pinctrl: sh-pfc: Stop calling gpiochip_add_pin_range() on DT platforms
>>   pinctrl: sh-pfc: Remove empty gpio_function_free()
>>   pinctrl: sh-pfc: Confine legacy function GPIOs to SH
>
> Where possible I prefer not to apply non-DTS/DTSI patches on top of
> DTS/DTSI patches, I believe this is in keeping with how the ARM SoC

Ugh, that means I have to put a few more DT patches in my queue on the
fast track...

> maintainers like things handled.  With this in mind I have done the following:
>
> 1. Queued up the DTSI patches (patches 1 - 3) for v4.3 in my dt branch.
>    I intend for this to turn up in next soon.
> 2. Queued up for pinctrl patches (patches 4 - 6) for v4.4 in a pinctrl patch.
>    I intend for these to be present in the renesas devel branch but
>    not in next until after the release of v4.3-rc1. I would also be
>    happy to drop them and let Linus Walleij take these patches for v4.4,
>    assuming patches 1 - 3 are accepted for v4.3.

Thanks, that sounds fine to me!

Gr{oetje,eeting}s,

                        Geert

--
Geert Uytterhoeven -- There's lots of Linux beyond ia32 -- geert at linux-m68k.org

In personal conversations with technical people, I call myself a hacker. But
when I'm talking to journalists I just say "programmer" or something like that.
                                -- Linus Torvalds


From s.hauer at pengutronix.de  Tue Aug  4 23:53:41 2015
From: s.hauer at pengutronix.de (Sascha Hauer)
Date: Wed, 5 Aug 2015 08:53:41 +0200
Subject: [PATCH v6 5/9] clk: mediatek: Fix rate and dependency of MT8173
 clocks
In-Reply-To: <1438676218-11310-6-git-send-email-jamesjj.liao@mediatek.com>
References: <1438676218-11310-1-git-send-email-jamesjj.liao@mediatek.com>
 <1438676218-11310-6-git-send-email-jamesjj.liao@mediatek.com>
Message-ID: <20150805065341.GA18700@pengutronix.de>

On Tue, Aug 04, 2015 at 04:16:54PM +0800, James Liao wrote:
> Remove the dependency from clk_null, and give all root clocks a
> typical rate, include clkph_mck_o, usb_syspll_125m and hdmitx_dig_cts.
> 
> dpi_ck was removed due to no clock reference to it.
> 
> Replace parent clock of infra_cpum with cpum_ck, which is an external
> clock and can be defined in the device tree.
> 
> Signed-off-by: James Liao <jamesjj.liao at mediatek.com>
> ---
>  drivers/clk/mediatek/clk-mt8173.c | 12 ++++++------
>  1 file changed, 6 insertions(+), 6 deletions(-)
> 
> diff --git a/drivers/clk/mediatek/clk-mt8173.c b/drivers/clk/mediatek/clk-mt8173.c
> index 361fe32..f37ace6 100644
> --- a/drivers/clk/mediatek/clk-mt8173.c
> +++ b/drivers/clk/mediatek/clk-mt8173.c
> @@ -22,10 +22,9 @@
>  
>  static DEFINE_SPINLOCK(mt8173_clk_lock);
>  
> -static const struct mtk_fixed_factor root_clk_alias[] __initconst = {
> -	FACTOR(CLK_TOP_CLKPH_MCK_O, "clkph_mck_o", "clk_null", 1, 1),
> -	FACTOR(CLK_TOP_USB_SYSPLL_125M, "usb_syspll_125m", "clk_null", 1, 1),
> -	FACTOR(CLK_TOP_HDMITX_DIG_CTS, "hdmitx_dig_cts", "clk_null", 1, 1),
> +static const struct mtk_fixed_clk fixed_clks[] __initconst = {
> +	FIXED_CLK(CLK_TOP_CLKPH_MCK_O, "clkph_mck_o", "clk26m", 400 * MHZ),
> +	FIXED_CLK(CLK_TOP_USB_SYSPLL_125M, "usb_syspll_125m", "clk26m", 125 * MHZ),

Hm, it seems you hide PLLs in fixed factor clock. Are you sure that
there is a PLL in the system generating 125MHz from 26MHz which is in no
way configurable? Or is this really some clock derived from the syspll
as the clock name suggests?

Sascha

-- 
Pengutronix e.K.                           |                             |
Industrial Linux Solutions                 | http://www.pengutronix.de/  |
Peiner Str. 6-8, 31137 Hildesheim, Germany | Phone: +49-5121-206917-0    |
Amtsgericht Hildesheim, HRA 2686           | Fax:   +49-5121-206917-5555 |


From geert at linux-m68k.org  Tue Aug  4 23:58:29 2015
From: geert at linux-m68k.org (Geert Uytterhoeven)
Date: Wed, 5 Aug 2015 08:58:29 +0200
Subject: [PATCH v4 00/16] ARM: shmobile: Add CPG/MSTP Clock Domain
In-Reply-To: <20150805005543.GC20726@verge.net.au>
References: <1438691297-29235-1-git-send-email-geert+renesas@glider.be>
 <20150804134824.GA10194@verge.net.au>
 <20150805005543.GC20726@verge.net.au>
Message-ID: <CAMuHMdUFjgVWBc0hdm_L0Z0Os1OT8H4NzwQyQTGZQt8Bu7-9PQ@mail.gmail.com>

Hi Simon,

On Wed, Aug 5, 2015 at 2:55 AM, Simon Horman <horms at verge.net.au> wrote:
> On Tue, Aug 04, 2015 at 10:48:28PM +0900, Simon Horman wrote:
>> I have tentatively queued this up in its own branch,
>> cpg-mstp-clock-domain-for-v4.3.
>
> Where possible I prefer not to apply non-DTS/DTSI patches on top of
> DTS/DTSI patches, I believe this is in keeping with how the ARM SoC
> maintainers like things handled.  With this in mind I have shuffled things
> around a little, the result is:
>
> 1. The following are (still) queued up for v4.3 in their own
>    cpg-mstp-clock-domain-for-v4.3 branch:
>
>    clk: shmobile: Add CPG/MSTP Clock Domain support
>    clk: shmobile: r8a7778: Add CPG/MSTP Clock Domain support
>    clk: shmobile: r8a7779: Add CPG/MSTP Clock Domain support
>    clk: shmobile: rcar-gen2: Add CPG/MSTP Clock Domain support
>    clk: shmobile: rz: Add CPG/MSTP Clock Domain support
>    ARM: shmobile: r7s72100 dtsi: Add CPG/MSTP Clock Domain
>    ARM: shmobile: r8a7778 dtsi: Add CPG/MSTP Clock Domain
>    ARM: shmobile: r8a7779 dtsi: Add CPG/MSTP Clock Domain
>    ARM: shmobile: r8a7790 dtsi: Add CPG/MSTP Clock Domain
>    ARM: shmobile: r8a7791 dtsi: Add CPG/MSTP Clock Domain
>    ARM: shmobile: r8a7793 dtsi: Add CPG/MSTP Clock Domain
>    ARM: shmobile: r8a7794 dtsi: Add CPG/MSTP Clock Domain

OK.

> 2. The following are now queued up for v4.3 in a separate
>    sh-drivers-for-v4.3 branch. That branch is on top of the
>    cpg-mstp-clock-domain-for-v4.3 branch and I intend to send it directly
>    to Linus if/when a v4.3-rc has been released with the patches
>    listed in 1. present.
>
>    drivers: sh: Disable legacy default PM Domain on emev2
>    drivers: sh: Disable PM runtime for multi-platform ARM with genpd

OK

> 3. I have deferred the remaining two patches, listed below, for v4.4.
>    they currently reside in cpg-mstp-clock-domain-for-v4.4. That
>    branch is based on the sh-drivers-for-v4.3 branch.
>
>    clk: shmobile: mstp: Consider "zb_clk" suitable for power management
>    ARM: shmobile: R-Mobile: Use CPG/MSTP Clock Domain attach/detach helpers
>
> This means that the last two patches will disappear from next until
> after v4.3-rc1 is released but they, along with all the other patches,
> will be present in the renesas devel branch.

OK.

Note that as the last two depend on patch 1 only, you could e.g. queue
them up in group 1, between the clk and dtsi patches.
But it's up to you to reconsider.
I'm happy as-is, as the last two patches are just a code duplication clean up.

Thanks!

Gr{oetje,eeting}s,

                        Geert

--
Geert Uytterhoeven -- There's lots of Linux beyond ia32 -- geert at linux-m68k.org

In personal conversations with technical people, I call myself a hacker. But
when I'm talking to journalists I just say "programmer" or something like that.
                                -- Linus Torvalds


From 21cnbao at gmail.com  Wed Aug  5 00:15:08 2015
From: 21cnbao at gmail.com (Barry Song)
Date: Wed, 5 Aug 2015 15:15:08 +0800
Subject: [GIT PULL] CSR SiRFSoC DT for 4.3
Message-ID: <CAGsJ_4yxiytb3bUVsG5jTWKQdY7xE8HKBz7Og_Se=mB_cr3ZEQ@mail.gmail.com>

Hi Arnd, Kevin, Olof,

The following changes since commit bc0195aad0daa2ad5b0d76cce22b167bc3435590:

  Linux 4.2-rc2 (2015-07-12 15:10:30 -0700)

are available in the git repository at:

  git://git.kernel.org/pub/scm/linux/kernel/git/baohua/linux.git
tags/sirf-dts-for-4.3

for you to fetch changes up to 2cd212427fa9cbf19c1f353d6e14b959e8f112f7:

  ARM: dts: atlas7: add a GPIO key for rearview button (2015-08-05
22:44:21 +0800)

----------------------------------------------------------------
ARM: sirf: dts update for 4.3

some missed dt nodes or props for sirf dts for 4.3.
Among them:
- G2D
- PWM
- JPEG
- Multimedia
- PMU(performance monitor unit)
- GMAC
- SDR(software digital radio) and its DMA
- pinmux for NAND
- GPIO key

----------------------------------------------------------------
Andy Sun (1):
      ARM: dts: atlas7: add a GPIO key for rearview button

Dongli Li (1):
      ARM: dts: atlas7: add lost G2D node

Guo Zeng (1):
      ARM: dts: atlas7: add lost PWM node

Huayi Li (1):
      ARM: dts: atlas7: put pinctl property to get pinmux for NAND

Lily.Li (1):
      ARM: dts: atlas7: add lost jpeg node

Qipan Li (1):
      ARM: dts: atlas7: add alias name for spi device

Xiaofeng Fei (1):
      ARM: dts: atlas7: add multimedia codec node

Ye He (2):
      ARM: dts: atlas7: add performance monitor unit node
      ARM: dts: atlas7: add lost gmac node

Yonghui Zhang (1):
      ARM: dts: atlas7: add software digital radio nodes and its DMA channels

 arch/arm/boot/dts/atlas7-evb.dts |   18 +++++++
 arch/arm/boot/dts/atlas7.dtsi    |   97 ++++++++++++++++++++++++++++++++++++--
 2 files changed, 111 insertions(+), 4 deletions(-)

-barry


From djkurtz at chromium.org  Wed Aug  5 00:26:29 2015
From: djkurtz at chromium.org (Daniel Kurtz)
Date: Wed, 5 Aug 2015 15:26:29 +0800
Subject: [PATCH v6 7/9] clk: mediatek: Add subsystem clocks of MT8173
In-Reply-To: <20150805064605.GZ18700@pengutronix.de>
References: <1438676218-11310-1-git-send-email-jamesjj.liao@mediatek.com>
 <1438676218-11310-8-git-send-email-jamesjj.liao@mediatek.com>
 <20150805064605.GZ18700@pengutronix.de>
Message-ID: <CAGS+omDmgxO9jHaPRb1hXO7fMRE=CnH=WNP3DeMm1axBswK_Aw@mail.gmail.com>

On Wed, Aug 5, 2015 at 2:46 PM, Sascha Hauer <s.hauer at pengutronix.de> wrote:
> On Tue, Aug 04, 2015 at 04:16:56PM +0800, James Liao wrote:
>> Most multimedia subsystem clocks will be accessed by multiple
>> drivers, so it's a better way to manage these clocks in CCF.
>> This patch adds clock support for MM, IMG, VDEC, VENC and VENC_LT
>> subsystems.
>>
>> Signed-off-by: James Liao <jamesjj.liao at mediatek.com>
>> ---
>>  drivers/clk/mediatek/clk-mt8173.c      | 267 +++++++++++++++++++++++++++++++++
>>  include/dt-bindings/clock/mt8173-clk.h |  97 +++++++++++-
>>  2 files changed, 361 insertions(+), 3 deletions(-)
>>
>> diff --git a/drivers/clk/mediatek/clk-mt8173.c b/drivers/clk/mediatek/clk-mt8173.c
>> index f37ace6..05335e5 100644
>> --- a/drivers/clk/mediatek/clk-mt8173.c
>> +++ b/drivers/clk/mediatek/clk-mt8173.c
>> @@ -25,6 +25,10 @@ static DEFINE_SPINLOCK(mt8173_clk_lock);
>>  static const struct mtk_fixed_clk fixed_clks[] __initconst = {
>>       FIXED_CLK(CLK_TOP_CLKPH_MCK_O, "clkph_mck_o", "clk26m", 400 * MHZ),
>>       FIXED_CLK(CLK_TOP_USB_SYSPLL_125M, "usb_syspll_125m", "clk26m", 125 * MHZ),
>> +     FIXED_CLK(CLK_TOP_DSI0_DIG, "dsi0_dig", "clk26m", 130 * MHZ),
>> +     FIXED_CLK(CLK_TOP_DSI1_DIG, "dsi1_dig", "clk26m", 130 * MHZ),
>> +     FIXED_CLK(CLK_TOP_LVDS_PXL, "lvds_pxl", "lvdspll", 148.5 * MHZ),
>> +     FIXED_CLK(CLK_TOP_LVDS_CTS, "lvds_cts", "lvdspll", 51.975 * MHZ),
>
> I would expect 51975 * KHZ here to avoid fractional numbers. Probably
> gcc calculates that during compile time so this will work as expected,
> still I'm not sure this is good style to use fractional numbers here.

I thought this looked a bit strange too, but for what its worth, these
two evaluate correctly:

localhost ~ # cat /sys/kernel/debug/clk/clk_summary  | grep lvds
    lvdspll                               0            0   149999878
       0 0
       lvds_pxl                           0            0   148500000
       0 0
       lvds_cts                           0            0    51975000
       0 0

>
> Anyway, on my system lvdspll is running at 150MHz. Are you sure there is
> a clock derived from this running at 148.5MHz? Is it really correct to
> use a fixed clock here or should it rather be lvdspll directly?

I agree it does look strange to have a 51.975 MHz and 148.5 MHz clocks
with a 150 MHz PLL as their parent...  However, I'm not sure how much
this matters?  I think the idea here was that these frequencies are
best effort "nominal" clock values provided by Mediatek "designers".
The important point is that for the hardware to generate these either
of these clocks, lvdspll must be enabled.

-Dan


> Sascha
>
>
> --
> Pengutronix e.K.                           |                             |
> Industrial Linux Solutions                 | http://www.pengutronix.de/  |
> Peiner Str. 6-8, 31137 Hildesheim, Germany | Phone: +49-5121-206917-0    |
> Amtsgericht Hildesheim, HRA 2686           | Fax:   +49-5121-206917-5555 |


From maitysanchayan at gmail.com  Wed Aug  5 00:27:43 2015
From: maitysanchayan at gmail.com (maitysanchayan at gmail.com)
Date: Wed, 5 Aug 2015 12:57:43 +0530
Subject: [PATCH v2 3/4] touchscreen: colibri-vf50-ts: Add touchscreen
 support for Colibri VF50
In-Reply-To: <20150803210409.GG38878@dtor-ws>
References: <cover.1437058481.git.maitysanchayan@gmail.com>
 <26748bd9a7bde7c2304b6b971f1150bb575e4938.1437058481.git.maitysanchayan@gmail.com>
 <20150717234242.GJ39282@dtor-ws>
 <40d7c372e64c7f25b7df3e48930386de@agner.ch>
 <20150721172044.GC39076@dtor-ws>
 <20150803152544.GA9716@Sanchayan-Arch.toradex.int>
 <20150803210409.GG38878@dtor-ws>
Message-ID: <20150805072742.GB2497@Sanchayan-Arch.toradex.int>

Hello Dmitry,

On 15-08-03 14:04:09, Dmitry Torokhov wrote:
> Hi Sanchayan,
> 
> On Mon, Aug 03, 2015 at 08:55:44PM +0530, maitysanchayan at gmail.com wrote:
> > Hello Dmitry,
> > 
> > On 15-07-21 10:20:44, Dmitry Torokhov wrote:
> > > Hi Stefan,
> > > 
> > > On Tue, Jul 21, 2015 at 04:43:36PM +0200, Stefan Agner wrote:
> > > > Hi Dmitry,
> > > > 
> > > > As the original author of the driver I have some remarks to your review
> > > > 
> > > > On 2015-07-18 01:42, Dmitry Torokhov wrote:
> > > > >> +		/*
> > > > >> +		 * If touch pressure is too low, stop measuring and reenable
> > > > >> +		 * touch detection
> > > > >> +		 */
> > > > >> +		if (val_p < min_pressure || val_p > 2000)
> > > > >> +			break;
> > > > 
> > > > This is where the modules touch pressure is used to stop the measurement
> > > > process and switch back to interrupt mode. See my remarks at the end.
> > > > 
> > > > >> +
> > > > >> +		/*
> > > > >> +		 * The pressure may not be enough for the first x and the
> > > > >> +		 * second y measurement, but, the pressure is ok when the
> > > > >> +		 * driver is doing the third and fourth measurement. To
> > > > >> +		 * take care of this, we drop the first measurement always.
> > > > >> +		 */
> > > > >> +		if (discard_val_on_start) {
> > > > >> +			discard_val_on_start = false;
> > > > >> +		} else {
> > > > >> +			/*
> > > > >> +			 * Report touch position and sleep for
> > > > >> +			 * next measurement
> > > > >> +			 */
> > > > >> +			input_report_abs(vf50_ts->ts_input,
> > > > >> +					ABS_X, VF_ADC_MAX - val_x);
> > > > >> +			input_report_abs(vf50_ts->ts_input,
> > > > >> +					ABS_Y, VF_ADC_MAX - val_y);
> > > > >> +			input_report_abs(vf50_ts->ts_input,
> > > > >> +					ABS_PRESSURE, val_p);
> > > > >> +			input_report_key(vf50_ts->ts_input, BTN_TOUCH, 1);
> > > > >> +			input_sync(vf50_ts->ts_input);
> > > > >> +		}
> > > > >> +
> > > > >> +		msleep(10);
> > > > >> +	}
> > > > >> +
> > > > >> +	/* Report no more touch, reenable touch detection */
> > > > >> +	input_report_abs(vf50_ts->ts_input, ABS_PRESSURE, 0);
> > > > >> +	input_report_key(vf50_ts->ts_input, BTN_TOUCH, 0);
> > > > >> +	input_sync(vf50_ts->ts_input);
> > > > >> +
> > > > >> +	vf50_ts_enable_touch_detection(vf50_ts);
> > > > >> +
> > > > >> +	/* Wait for the pull-up to be stable on high */
> > > > >> +	msleep(10);
> > > > >> +
> > > > >> +	/* Reenable IRQ to detect touch */
> > > > >> +	enable_irq(vf50_ts->pen_irq);
> > > > >> +
> > > > >> +	dev_dbg(dev, "Reenabled touch detection interrupt\n");
> > > > >> +}
> > > > >> +
> > > > >> +static irqreturn_t vf50_ts_touched(int irq, void *dev_id)
> > > > >> +{
> > > > >> +	struct vf50_touch_device *vf50_ts = (struct vf50_touch_device *)dev_id;
> > > > >> +	struct device *dev = &vf50_ts->pdev->dev;
> > > > >> +
> > > > >> +	dev_dbg(dev, "Touch detected, start worker thread\n");
> > > > >> +
> > > > >> +	disable_irq_nosync(irq);
> > > > >> +
> > > > >> +	/* Disable the touch detection plates */
> > > > >> +	gpiod_set_value(vf50_ts->gpio_ym, 0);
> > > > >> +
> > > > >> +	/* Let the platform mux to default state in order to mux as ADC */
> > > > >> +	pinctrl_pm_select_default_state(dev);
> > > > >> +
> > > > >> +	queue_work(vf50_ts->ts_workqueue, &vf50_ts->ts_work);
> > > > > 
> > > > > If you convert this to a threaded interrupt you won't need to
> > > > > disable/reenable interrupt or queue work. You should also be able to use
> > > > > gpiod_set_value_cansleep() extending the range of ways the controller
> > > > > could be connected to systems.
> > > > > 
> > > > 
> > > > I'm not sure if a threaded interrupt is the right thing here. While the
> > > > pen is on the touchscreen (which can be for several seconds)
> > > > measurements have to be made in a continuous loop. Is it ok for a
> > > > threaded interrupt to run that long?
> > > 
> > > Yes, why not? Threaded interrupt is simply a kernel thread that is woken
> > > when hard interrupt handler tells it to wake up. Very similar to
> > > interrupt + work queue, except that the kernel manages interactions
> > > properly for you. There are several drivers in kernel that do that, for
> > > example auo-pixcir-ts.c or tsc2007.c
> > > 
> > > > 
> > > > I'm also not sure if it is really safe to _not_ disable the pen down
> > > > GPIO interrupt. If we get a interrupt while measuring, we should ignore
> > > > that interrupt.
> > > 
> > > The interrupt management core (you'll have to annotate it as
> > > IRQF_ONESHOT) will make sure it stays masked properly until the threaded
> > > handler completes so you do not need to disable it explicitly.
> > 
> > After working some more on threaded irq implementation, if IRQ_ONESHOT
> > flag is used while requesting threaded irq, on entering the IRQ handler
> > the vf610_gpio_irq_mask is not called and vf610_gpio_irq_unmask is not
> > called on exiting the thread function, not something we expected.
> > 
> > In contrast, using explicit disable_irq_nosync and enable_irq in the IRQ
> > handler and thread respectively results in the respective mask and unmask
> > function being called.
> > 
> > The vf610_gpio_irq_*mask functions are in the gpio driver for Vybrid in
> > drivers/gpio/gpio-vf610.c.
> 
> Well, for edge interrupts we normally do not mask/unmask IRQ as we
> expect the controller to latch onto the state and not re-raise intil
> interrupt is acked and I believe goes through edge condition again.
> For level-triggered IRQs we do mask the interrupt line. See
> kernel/irq/handle.c::handle_level_irq() and handle_edge_irq().

Thank you very much for pointing me in the right direction. While using
threaded irqs we notice two different bugs which seem to have been there
for a while. One related to pinmux and other with gpio driver for Vybrid
in how it handled the irq's.

Will send out a new version with the changes incoporated. The GPIO driver
fix will be send in a separate patch by my colleague.

Thanks & Regards,
Sanchayan.


From s.hauer at pengutronix.de  Wed Aug  5 00:31:17 2015
From: s.hauer at pengutronix.de (Sascha Hauer)
Date: Wed, 5 Aug 2015 09:31:17 +0200
Subject: [RFC PATCH 0/3] New Atmel PIO4 pinctrl/gpio driver
In-Reply-To: <1438355290-28255-1-git-send-email-ludovic.desroches@atmel.com>
References: <1438355290-28255-1-git-send-email-ludovic.desroches@atmel.com>
Message-ID: <20150805073117.GP5161@pengutronix.de>

On Fri, Jul 31, 2015 at 05:08:07PM +0200, Ludovic Desroches wrote:
> Hi,
> 
> Following our discussion, I send an RFC version of my driver. RFC because it is
> not totally achieved, some cleanup and feature addition is needed.
> 
> At least, we could discuss about the 'core' part. I have used the pinmux
> property as Mediatek driver. Patch 3 is the internal dt files we are using.

As you can imagine I am fine with the binding, so I can add my acked-by
once you send a non-RFC version.

The only thing I never understood is what's so special about GPIOs that
they have to bypass the pinctrl framework and instead a gpio_request
magically translates a gpio into a pin. Wouldn't it make sense to at
least add the pins in their GPIO mode to
arch/arm/boot/dts/sama5d2-pinfunc.h?

Sascha

-- 
Pengutronix e.K.                           |                             |
Industrial Linux Solutions                 | http://www.pengutronix.de/  |
Peiner Str. 6-8, 31137 Hildesheim, Germany | Phone: +49-5121-206917-0    |
Amtsgericht Hildesheim, HRA 2686           | Fax:   +49-5121-206917-5555 |


From eric.auger at linaro.org  Wed Aug  5 00:32:09 2015
From: eric.auger at linaro.org (Eric Auger)
Date: Wed, 05 Aug 2015 09:32:09 +0200
Subject: [PATCH v3 09/11] KVM: arm/arm64: vgic: Prevent userspace injection
 of a mapped interrupt
In-Reply-To: <55C0EBF5.2060708@arm.com>
References: <1437753309-17989-1-git-send-email-marc.zyngier@arm.com>
 <1437753309-17989-10-git-send-email-marc.zyngier@arm.com>
 <55C0E690.1090808@linaro.org> <55C0EBF5.2060708@arm.com>
Message-ID: <55C1BBF9.2060004@linaro.org>

Hi Marc,
On 08/04/2015 06:44 PM, Marc Zyngier wrote:
> On 04/08/15 17:21, Eric Auger wrote:
>> Hi Marc,
>> On 07/24/2015 05:55 PM, Marc Zyngier wrote:
>>> Virtual interrupts mapped to a HW interrupt should only be triggered
>>> from inside the kernel. Otherwise, you could end up confusing the
>>> kernel (and the GIC's) state machine.
>>>
>>> Rearrange the injection path so that kvm_vgic_inject_irq is
>>> used for non-mapped interrupts, and kvm_vgic_inject_mapped_irq is
>>> used for mapped interrupts. The latter should only be called from
>>> inside the kernel (timer, VFIO).
>> nit: I would replace VFIO by irqfd.
>> VFIO just triggers the eventfd/irqfd. This is KVM/irqfd that injects the
>> virtual irq upon the irqfd signaling and he irqfd adaptation/ARM
>> currently is implemented in vgic.c
> 
> Ah, thanks for reminding me of the right terminology, I tend to think of
> it as one big bag of nasty tricks... ;-)
> 
> I'll update the commit message.
> 
>>>
>>> Signed-off-by: Marc Zyngier <marc.zyngier at arm.com>
>>> ---
>>>  include/kvm/arm_vgic.h |  2 +
>>>  virt/kvm/arm/vgic.c    | 99 ++++++++++++++++++++++++++++++++++----------------
>>>  2 files changed, 70 insertions(+), 31 deletions(-)
>>>
>>> diff --git a/include/kvm/arm_vgic.h b/include/kvm/arm_vgic.h
>>> index 7306b4b..f6bfd79 100644
>>> --- a/include/kvm/arm_vgic.h
>>> +++ b/include/kvm/arm_vgic.h
>>> @@ -351,6 +351,8 @@ void kvm_vgic_flush_hwstate(struct kvm_vcpu *vcpu);
>>>  void kvm_vgic_sync_hwstate(struct kvm_vcpu *vcpu);
>>>  int kvm_vgic_inject_irq(struct kvm *kvm, int cpuid, unsigned int irq_num,
>>>  			bool level);
>>> +int kvm_vgic_inject_mapped_irq(struct kvm *kvm, int cpuid,
>>> +			       struct irq_phys_map *map, bool level);
>>>  void vgic_v3_dispatch_sgi(struct kvm_vcpu *vcpu, u64 reg);
>>>  int kvm_vgic_vcpu_pending_irq(struct kvm_vcpu *vcpu);
>>>  int kvm_vgic_vcpu_active_irq(struct kvm_vcpu *vcpu);
>>> diff --git a/virt/kvm/arm/vgic.c b/virt/kvm/arm/vgic.c
>>> index 3f7b690..e40ef70 100644
>>> --- a/virt/kvm/arm/vgic.c
>>> +++ b/virt/kvm/arm/vgic.c
>>> @@ -1533,7 +1533,8 @@ static int vgic_validate_injection(struct kvm_vcpu *vcpu, int irq, int level)
>>>  }
>>>  
>>>  static int vgic_update_irq_pending(struct kvm *kvm, int cpuid,
>>> -				  unsigned int irq_num, bool level)
>>> +				   struct irq_phys_map *map,
>>> +				   unsigned int irq_num, bool level)
>>>  {
>> In vgic_update_irq_pending, I needed to modify the following line and
>> add the "&& !map".
>>
>>         if (!vgic_validate_injection(vcpu, irq_num, level) && !map) {
>>
>> Without that, the level being not properly modeled for level sensitive
>> forwarded IRQs, the 2d injection fails.
> 
> Ah! Is that because we never see the line being reset to zero, and the
> VGIC still sees the line as pending at the distributor level?
yes indeed

Eric
> 
> Thanks,
> 
> 	M.
> 



From s.hauer at pengutronix.de  Wed Aug  5 00:36:45 2015
From: s.hauer at pengutronix.de (Sascha Hauer)
Date: Wed, 5 Aug 2015 09:36:45 +0200
Subject: [PATCH v6 7/9] clk: mediatek: Add subsystem clocks of MT8173
In-Reply-To: <CAGS+omDmgxO9jHaPRb1hXO7fMRE=CnH=WNP3DeMm1axBswK_Aw@mail.gmail.com>
References: <1438676218-11310-1-git-send-email-jamesjj.liao@mediatek.com>
 <1438676218-11310-8-git-send-email-jamesjj.liao@mediatek.com>
 <20150805064605.GZ18700@pengutronix.de>
 <CAGS+omDmgxO9jHaPRb1hXO7fMRE=CnH=WNP3DeMm1axBswK_Aw@mail.gmail.com>
Message-ID: <20150805073645.GB18700@pengutronix.de>

On Wed, Aug 05, 2015 at 03:26:29PM +0800, Daniel Kurtz wrote:
> On Wed, Aug 5, 2015 at 2:46 PM, Sascha Hauer <s.hauer at pengutronix.de> wrote:
> > On Tue, Aug 04, 2015 at 04:16:56PM +0800, James Liao wrote:
> >> Most multimedia subsystem clocks will be accessed by multiple
> >> drivers, so it's a better way to manage these clocks in CCF.
> >> This patch adds clock support for MM, IMG, VDEC, VENC and VENC_LT
> >> subsystems.
> >>
> >> Signed-off-by: James Liao <jamesjj.liao at mediatek.com>
> >> ---
> >>  drivers/clk/mediatek/clk-mt8173.c      | 267 +++++++++++++++++++++++++++++++++
> >>  include/dt-bindings/clock/mt8173-clk.h |  97 +++++++++++-
> >>  2 files changed, 361 insertions(+), 3 deletions(-)
> >>
> >> diff --git a/drivers/clk/mediatek/clk-mt8173.c b/drivers/clk/mediatek/clk-mt8173.c
> >> index f37ace6..05335e5 100644
> >> --- a/drivers/clk/mediatek/clk-mt8173.c
> >> +++ b/drivers/clk/mediatek/clk-mt8173.c
> >> @@ -25,6 +25,10 @@ static DEFINE_SPINLOCK(mt8173_clk_lock);
> >>  static const struct mtk_fixed_clk fixed_clks[] __initconst = {
> >>       FIXED_CLK(CLK_TOP_CLKPH_MCK_O, "clkph_mck_o", "clk26m", 400 * MHZ),
> >>       FIXED_CLK(CLK_TOP_USB_SYSPLL_125M, "usb_syspll_125m", "clk26m", 125 * MHZ),
> >> +     FIXED_CLK(CLK_TOP_DSI0_DIG, "dsi0_dig", "clk26m", 130 * MHZ),
> >> +     FIXED_CLK(CLK_TOP_DSI1_DIG, "dsi1_dig", "clk26m", 130 * MHZ),
> >> +     FIXED_CLK(CLK_TOP_LVDS_PXL, "lvds_pxl", "lvdspll", 148.5 * MHZ),
> >> +     FIXED_CLK(CLK_TOP_LVDS_CTS, "lvds_cts", "lvdspll", 51.975 * MHZ),
> >
> > I would expect 51975 * KHZ here to avoid fractional numbers. Probably
> > gcc calculates that during compile time so this will work as expected,
> > still I'm not sure this is good style to use fractional numbers here.
> 
> I thought this looked a bit strange too, but for what its worth, these
> two evaluate correctly:
> 
> localhost ~ # cat /sys/kernel/debug/clk/clk_summary  | grep lvds
>     lvdspll                               0            0   149999878
>        0 0
>        lvds_pxl                           0            0   148500000
>        0 0
>        lvds_cts                           0            0    51975000
>        0 0
> 
> >
> > Anyway, on my system lvdspll is running at 150MHz. Are you sure there is
> > a clock derived from this running at 148.5MHz? Is it really correct to
> > use a fixed clock here or should it rather be lvdspll directly?
> 
> I agree it does look strange to have a 51.975 MHz and 148.5 MHz clocks
> with a 150 MHz PLL as their parent...  However, I'm not sure how much
> this matters?  I think the idea here was that these frequencies are
> best effort "nominal" clock values provided by Mediatek "designers".
> The important point is that for the hardware to generate these either
> of these clocks, lvdspll must be enabled.

This assumes that the lvdspll always runs at frequency the designers
thought that might be a good value. Should we really provide wrong clock
values when on some board for whatever reason the lvdspll is configured
for a different frequency?

sascha

-- 
Pengutronix e.K.                           |                             |
Industrial Linux Solutions                 | http://www.pengutronix.de/  |
Peiner Str. 6-8, 31137 Hildesheim, Germany | Phone: +49-5121-206917-0    |
Amtsgericht Hildesheim, HRA 2686           | Fax:   +49-5121-206917-5555 |


From Haibo.Chen at freescale.com  Wed Aug  5 00:39:29 2015
From: Haibo.Chen at freescale.com (Chen Bough)
Date: Wed, 5 Aug 2015 07:39:29 +0000
Subject: [PATCH v3 1/6] mmc: sdhci-esdhc-imx: add imx7d support and
 support HS400
In-Reply-To: <20150803120932.GB24870@shlinux1.ap.freescale.net>
References: <1438160637-28061-1-git-send-email-haibo.chen@freescale.com>
 <1438160637-28061-2-git-send-email-haibo.chen@freescale.com>
 <20150731141507.GB27806@shlinux1.ap.freescale.net>
 <BY1PR03MB13889195F33D0010E6759D309A880@BY1PR03MB1388.namprd03.prod.outlook.com>
 <20150803120932.GB24870@shlinux1.ap.freescale.net>
Message-ID: <BY1PR03MB13888A2D2946E6B41EBFFFE19A750@BY1PR03MB1388.namprd03.prod.outlook.com>



> -----Original Message-----
> From: Dong Aisheng [mailto:aisheng.dong at freescale.com]
> Sent: Monday, August 03, 2015 8:10 PM
> To: Chen Haibo-B51421
> Cc: robh+dt at kernel.org; pawel.moll at arm.com; mark.rutland at arm.com;
> ijc+devicetree at hellion.org.uk; galak at codeaurora.org; shawnguo at kernel.org;
> kernel at pengutronix.de; linux at arm.linux.org.uk; ulf.hansson at linaro.org;
> johan.derycke at barco.com; Estevam Fabio-R49496; devicetree at vger.kernel.org;
> linux-kernel at vger.kernel.org; linux-arm-kernel at lists.infradead.org;
> linux-mmc at vger.kernel.org
> Subject: Re: [PATCH v3 1/6] mmc: sdhci-esdhc-imx: add imx7d support and
> support HS400
> 
> On Sun, Aug 02, 2015 at 04:59:04PM +0800, Chen Haibo-B51421 wrote:
> >
> >
> > > -----Original Message-----
> > > From: Dong Aisheng [mailto:aisheng.dong at freescale.com]
> > > Sent: Friday, July 31, 2015 10:15 PM
> > > To: Chen Haibo-B51421
> > > Cc: robh+dt at kernel.org; pawel.moll at arm.com; mark.rutland at arm.com;
> > > ijc+devicetree at hellion.org.uk; galak at codeaurora.org;
> > > ijc+shawnguo at kernel.org;
> > > kernel at pengutronix.de; linux at arm.linux.org.uk;
> > > ulf.hansson at linaro.org; johan.derycke at barco.com; Estevam
> > > Fabio-R49496; Dong Aisheng-B29396; devicetree at vger.kernel.org;
> > > linux-kernel at vger.kernel.org; linux-arm- kernel at lists.infradead.org;
> > > linux-mmc at vger.kernel.org
> > > Subject: Re: [PATCH v3 1/6] mmc: sdhci-esdhc-imx: add imx7d support
> > > and support HS400
> > >
> > > On Wed, Jul 29, 2015 at 05:03:52PM +0800, Haibo Chen wrote:
> > > > The imx7d usdhc is derived from imx6sx, the difference is that
> > > > imx7d support HS400.
> > > >
> > > > So introduce a new compatible string for imx7d and add HS400
> > > > support for imx7d usdhc.
> > > >
> > > > Signed-off-by: Haibo Chen <haibo.chen at freescale.com>
> > > > ---
> > > >  drivers/mmc/host/sdhci-esdhc-imx.c | 66
> > > > ++++++++++++++++++++++++++++++++++++++
> > > >  1 file changed, 66 insertions(+)
> > > >
> > > > diff --git a/drivers/mmc/host/sdhci-esdhc-imx.c
> > > > b/drivers/mmc/host/sdhci-esdhc-imx.c
> > > > index c6b9f64..b441eed 100644
> > > > --- a/drivers/mmc/host/sdhci-esdhc-imx.c
> > > > +++ b/drivers/mmc/host/sdhci-esdhc-imx.c
> > > > @@ -44,6 +44,7 @@
> > > >  #define  ESDHC_MIX_CTRL_EXE_TUNE	(1 << 22)
> > > >  #define  ESDHC_MIX_CTRL_SMPCLK_SEL	(1 << 23)
> > > >  #define  ESDHC_MIX_CTRL_FBCLK_SEL	(1 << 25)
> > > > +#define  ESDHC_MIX_CTRL_HS400_EN	(1 << 26)
> > > >  /* Bits 3 and 6 are not SDHCI standard definitions */
> > > >  #define  ESDHC_MIX_CTRL_SDHCI_MASK	0xb7
> > > >  /* Tuning bits */
> > > > @@ -60,6 +61,16 @@
> > > >  #define  ESDHC_TUNE_CTRL_MIN		0
> > > >  #define  ESDHC_TUNE_CTRL_MAX		((1 << 7) - 1)
> > > >
> > > > +/* strobe dll register */
> > > > +#define ESDHC_STROBE_DLL_CTRL		0x70
> > > > +#define ESDHC_STROBE_DLL_CTRL_ENABLE	(1 << 0)
> > > > +#define ESDHC_STROBE_DLL_CTRL_RESET	(1 << 1)
> > > > +#define ESDHC_STROBE_DLL_CTRL_SLV_DLY_TARGET_SHIFT	3
> > > > +
> > > > +#define ESDHC_STROBE_DLL_STATUS		0x74
> > > > +#define ESDHC_STROBE_DLL_STS_REF_LOCK	(1 << 1)
> > > > +#define ESDHC_STROBE_DLL_STS_SLV_LOCK	0x1
> > > > +
> > > >  #define ESDHC_TUNING_CTRL		0xcc
> > > >  #define ESDHC_STD_TUNING_EN		(1 << 24)
> > > >  /* NOTE: the minimum valid tuning start tap for mx6sl is 1 */ @@
> > > > -120,6 +131,8 @@
> > > >  #define ESDHC_FLAG_ERR004536		BIT(7)
> > > >  /* The IP supports HS200 mode */
> > > >  #define ESDHC_FLAG_HS200		BIT(8)
> > > > +/* The IP supports HS400 mode */
> > > > +#define ESDHC_FLAG_SUP_HS400		BIT(9)
> > > >
> > > >  struct esdhc_soc_data {
> > > >  	u32 flags;
> > > > @@ -156,6 +169,12 @@ static struct esdhc_soc_data usdhc_imx6sx_data
> = {
> > > >  			| ESDHC_FLAG_HAVE_CAP1 | ESDHC_FLAG_HS200,  };
> > > >
> > > > +static struct esdhc_soc_data usdhc_imx7d_data = {
> > > > +	.flags = ESDHC_FLAG_USDHC | ESDHC_FLAG_STD_TUNING
> > > > +			| ESDHC_FLAG_HAVE_CAP1 | ESDHC_FLAG_HS200
> > > > +			| ESDHC_FLAG_SUP_HS400,
> > > > +};
> > > > +
> > > >  struct pltfm_imx_data {
> > > >  	u32 scratchpad;
> > > >  	struct pinctrl *pinctrl;
> > > > @@ -199,6 +218,7 @@ static const struct of_device_id
> > > > imx_esdhc_dt_ids[]
> > > = {
> > > >  	{ .compatible = "fsl,imx6sx-usdhc", .data =
> &usdhc_imx6sx_data, },
> > > >  	{ .compatible = "fsl,imx6sl-usdhc", .data =
> &usdhc_imx6sl_data, },
> > > >  	{ .compatible = "fsl,imx6q-usdhc", .data =
> &usdhc_imx6q_data, },
> > > > +	{ .compatible = "fsl,imx7d-usdhc", .data =
> &usdhc_imx7d_data, },
> > > >  	{ /* sentinel */ }
> > > >  };
> > > >  MODULE_DEVICE_TABLE(of, imx_esdhc_dt_ids); @@ -274,6 +294,10 @@
> > > > static u32 esdhc_readl_le(struct sdhci_host *host, int reg)
> > > >  				val = SDHCI_SUPPORT_DDR50 |
> SDHCI_SUPPORT_SDR104
> > > >  					| SDHCI_SUPPORT_SDR50
> > > >  					| SDHCI_USE_SDR50_TUNING;
> > > > +
> > > > +			/* imx7d does not have a support_hs400 register,
> fake
> > > one */
> > >
> > > You could remove this line.
> > > It's bit, not register and i think no need such comment.
> > >
> > > > +			if (imx_data->socdata->flags &
> ESDHC_FLAG_SUP_HS400)
> > > > +				val |= SDHCI_SUPPORT_HS400;
> > > >  		}
> > > >  	}
> > > >
> > > > @@ -774,6 +798,7 @@ static int esdhc_change_pinstate(struct
> > > > sdhci_host
> > > *host,
> > > >  		break;
> > > >  	case MMC_TIMING_UHS_SDR104:
> > > >  	case MMC_TIMING_MMC_HS200:
> > > > +	case MMC_TIMING_MMC_HS400:
> > > >  		pinctrl = imx_data->pins_200mhz;
> > > >  		break;
> > > >  	default:
> > > > @@ -784,6 +809,30 @@ static int esdhc_change_pinstate(struct
> > > > sdhci_host
> > > *host,
> > > >  	return pinctrl_select_state(imx_data->pinctrl, pinctrl);  }
> > > >
> > > > +static void esdhc_set_strobe_dll(struct sdhci_host *host)
> > >
> > > It would be good if we can add some comments for this function for
> > > better understand.
> > >
> >
> > [haibo] okay, I will add comments here.
> >
> > > > +{
> > > > +	u32 v;
> > > > +
> > > > +	/* force a reset on strobe dll */
> > > > +	writel(ESDHC_STROBE_DLL_CTRL_RESET, host->ioaddr +
> > > ESDHC_STROBE_DLL_CTRL);
> > > > +	/*
> > > > +	 * enable strobe dll ctrl and adjust the delay target
> > > > +	 * for the uSDHC loopback read clock
> > > > +	 */
> > > > +	v = ESDHC_STROBE_DLL_CTRL_ENABLE |
> > > > +		(7 << ESDHC_STROBE_DLL_CTRL_SLV_DLY_TARGET_SHIFT);
> > > > +	writel(v, host->ioaddr + ESDHC_STROBE_DLL_CTRL);
> > > > +	/* wait 1us to make sure strobe dll status register stable */
> > > > +	udelay(1);
> > > > +	v = readl(host->ioaddr + ESDHC_STROBE_DLL_STATUS);
> > > > +	if (!(v & ESDHC_STROBE_DLL_STS_REF_LOCK))
> > > > +		dev_warn(mmc_dev(host->mmc),
> > > > +			"warning! HS400 strobe DLL status REF not
> lock!\n");
> > > > +	if (!(v & ESDHC_STROBE_DLL_STS_SLV_LOCK))
> > > > +		dev_warn(mmc_dev(host->mmc),
> > > > +			"warning! HS400 strobe DLL status SLV not
> lock!\n"); }
> > > > +
> > > >  static void esdhc_set_uhs_signaling(struct sdhci_host *host,
> > > > unsigned
> > > > timing)  {
> > > >  	struct sdhci_pltfm_host *pltfm_host = sdhci_priv(host); @@
> > > > -795,7
> > > > +844,13 @@ static void esdhc_set_uhs_signaling(struct sdhci_host
> > > > +*host,
> > > unsigned timing)
> > > >  	case MMC_TIMING_UHS_SDR25:
> > > >  	case MMC_TIMING_UHS_SDR50:
> > > >  	case MMC_TIMING_UHS_SDR104:
> > > > +		break;
> > > >  	case MMC_TIMING_MMC_HS200:
> > > > +		/* disable ddr mode and disable HS400 mode */
> > > > +		writel(readl(host->ioaddr + ESDHC_MIX_CTRL) &
> > > > +			~(ESDHC_MIX_CTRL_DDREN | ESDHC_MIX_CTRL_HS400_EN),
> > > > +			host->ioaddr + ESDHC_MIX_CTRL);
> > > > +		imx_data->is_ddr = 0;
> > > >  		break;
> > > >  	case MMC_TIMING_UHS_DDR50:
> > > >  	case MMC_TIMING_MMC_DDR52:
> > > > @@ -813,6 +868,14 @@ static void esdhc_set_uhs_signaling(struct
> > > sdhci_host *host, unsigned timing)
> > > >  			writel(v, host->ioaddr + ESDHC_DLL_CTRL);
> > > >  		}
> > > >  		break;
> > > > +	case MMC_TIMING_MMC_HS400:
> > > > +		writel(readl(host->ioaddr + ESDHC_MIX_CTRL) |
> > > > +				ESDHC_MIX_CTRL_DDREN |
> ESDHC_MIX_CTRL_HS400_EN,
> > > > +				host->ioaddr + ESDHC_MIX_CTRL);
> > > > +		imx_data->is_ddr = 1;
> > > > +		if (host->clock == 200000000)
> > >
> > > I can't remember, but could this be a range required by SoC?
> >
> > [haibo]we should set strobe_dll only when the host clock is 200MHz. For
> other condition, no need to do this.
> >
> 
> It is not quite make sense for only 200Mhz clock here.
> 
> First, shall we check host->mmc->actual_clock instead of host->clock?
> That is the real clock frequency the controller is working on.
> 
> 
> Second, even MMC core requests to set 200Mhz clock for HS400, the real
> clock controller working on may be less than 200Mhz which depends on the
> uSDHC root clock capability.
> e.g. it may be 192Mhz if the parent is 384Mhz or less.
> If that, do we need call strobe_dll too?
> 

[haibo] according to IC team feedback, when we use HS400 mode in high frequency, like:
close to 200Mhz, including 192Mhz, we should call strobe_dll. When the eMMC clock is around
100Mhz, like 98Mhz, no need to call strobe_dll, I have test this, eMMC can read normally.

When the card clock become higher, each clock cycle becomes shorter. When each clock cycle is short
enough, the time delay between CLK and strobe_data_clock maybe larger than one clock cycle, so the CLk
and strobe_data_clock misaligned,  then read error shows up. (here CLK means the clock host supply to card,
and strobe_data_clock means the clock generated by device which feedback to host for data read in HS400 mode).

So can we call strobe_dll when the card clock is over 100Mhz? 


> Can you check above two concerns?
> 
> Regards
> Dong Aisheng
> 
> > >
> > > > +			esdhc_set_strobe_dll(host);
> > > > +		break;
> > > >  	}
> > > >
> > > >  	esdhc_change_pinstate(host, timing); @@ -1100,6 +1163,9 @@
> > > > static int sdhci_esdhc_imx_probe(struct platform_device *pdev)
> > > >  	if (imx_data->socdata->flags & ESDHC_FLAG_ERR004536)
> > > >  		host->quirks |= SDHCI_QUIRK_BROKEN_ADMA;
> > > >
> > > > +	if (imx_data->socdata->flags & ESDHC_FLAG_SUP_HS400)
> > > > +		host->quirks2 |= SDHCI_QUIRK2_CAPS_BIT63_FOR_HS400;
> > > > +
> > > >  	if (of_id)
> > > >  		err = sdhci_esdhc_imx_probe_dt(pdev, host, imx_data);
> > > >  	else
> > > > --
> > > > 1.9.1
> > > >
> > >
> > > Regards
> > > Dong Aisheng


From olof at lixom.net  Wed Aug  5 00:41:31 2015
From: olof at lixom.net (Olof Johansson)
Date: Wed, 5 Aug 2015 09:41:31 +0200
Subject: [PATCHv5 0/5] arm/arm64: Unify PSCI client support
In-Reply-To: <20150803143703.GH10501@arm.com>
References: <1438353980-7611-1-git-send-email-mark.rutland@arm.com>
 <20150803143703.GH10501@arm.com>
Message-ID: <CAOesGMh9Lx=eVTzSQcU63ttLWX8St5T5cFDDKozO4nmvoqU0Lw@mail.gmail.com>

Hi,

On Mon, Aug 3, 2015 at 4:37 PM, Will Deacon <will.deacon at arm.com> wrote:
> Hi all,
>
> On Fri, Jul 31, 2015 at 03:46:15PM +0100, Mark Rutland wrote:
>> This series unifies the 32-bit and 64-bit PSCI client code, moving the bulk of
>> the FW invocation and probing out to a common location in drivers/firmware. The
>> bulk of the PSCI 0.2 cleanups have hit mainline now, so this is just the
>> unification portion.
>>
>> This results in a reasonable saving in terms of lines of code, and will allow
>> for PSCI 1.0 support to be unified form the beginning, avoiding further
>> duplication.
>>
>> Since v4 [1]:
>> * Apply Rob Herring's ack
>> * Rebase to v4.2-rc2 to handle a trivial conflict
>> * Reorder the series to keep arch/arm patches together
>> Since v3 [2]:
>> * Drop the PSCI 0.2 patches as they're in mainline
>> * s/__pa/virt_to_idmap/ from Grygorii Strashko
>> * Use macros for Calxeda CPU_SUSPEND parameters
>>
>> Russell, are you happy with the arch/arm patches? If so, are you happy for them
>> to go via another tree, or would you prefer that I set up a stable branch for
>> merging?
>>
>> I was under the impression that you had already taken Grygorii's patch but I
>> couldn't spot it in any branches. I can drop that if you already have it.
>
> I've been looking at merging this, but it's a tad fiddly touching all of
> arm, arm64 and drivers. One way to do it would be:
>
>   (1) I create a branch containing patches 1,2 and 5 based on -rc2 and
>       merge that into the arm64/for-next/core branch. There's a minor
>       conflict, but it's easy to resolve.
>
>   (2) I create another branch, which is just the branch merged in (1) +
>       patches 3 and 4 on top. I send a pull request for that to rmk.
>
>   (3) Torvalds will get the minor conflict resolved in (1) when he merges
>       the arm and arm64 trees.
>
> If we're not comfortable with (3), then the whole lot could go via
> arm-soc instead (including the conflict resolution).
>
> Russell, Olof, any preferences?

Wouldn't it be easiest to just get acks on patch 3 and 4 and just
merge it all through your tree?


-Olof


From djkurtz at chromium.org  Wed Aug  5 00:41:49 2015
From: djkurtz at chromium.org (Daniel Kurtz)
Date: Wed, 5 Aug 2015 15:41:49 +0800
Subject: [PATCH v6 7/9] clk: mediatek: Add subsystem clocks of MT8173
In-Reply-To: <20150805073645.GB18700@pengutronix.de>
References: <1438676218-11310-1-git-send-email-jamesjj.liao@mediatek.com>
 <1438676218-11310-8-git-send-email-jamesjj.liao@mediatek.com>
 <20150805064605.GZ18700@pengutronix.de>
 <CAGS+omDmgxO9jHaPRb1hXO7fMRE=CnH=WNP3DeMm1axBswK_Aw@mail.gmail.com>
 <20150805073645.GB18700@pengutronix.de>
Message-ID: <CAGS+omAFpWHO5w22Lq5fF6aXxf0bWi0KG7OB4u-FEFNUxPiceA@mail.gmail.com>

On Wed, Aug 5, 2015 at 3:36 PM, Sascha Hauer <s.hauer at pengutronix.de> wrote:
> On Wed, Aug 05, 2015 at 03:26:29PM +0800, Daniel Kurtz wrote:
>> On Wed, Aug 5, 2015 at 2:46 PM, Sascha Hauer <s.hauer at pengutronix.de> wrote:
>> > On Tue, Aug 04, 2015 at 04:16:56PM +0800, James Liao wrote:
>> >> Most multimedia subsystem clocks will be accessed by multiple
>> >> drivers, so it's a better way to manage these clocks in CCF.
>> >> This patch adds clock support for MM, IMG, VDEC, VENC and VENC_LT
>> >> subsystems.
>> >>
>> >> Signed-off-by: James Liao <jamesjj.liao at mediatek.com>
>> >> ---
>> >>  drivers/clk/mediatek/clk-mt8173.c      | 267 +++++++++++++++++++++++++++++++++
>> >>  include/dt-bindings/clock/mt8173-clk.h |  97 +++++++++++-
>> >>  2 files changed, 361 insertions(+), 3 deletions(-)
>> >>
>> >> diff --git a/drivers/clk/mediatek/clk-mt8173.c b/drivers/clk/mediatek/clk-mt8173.c
>> >> index f37ace6..05335e5 100644
>> >> --- a/drivers/clk/mediatek/clk-mt8173.c
>> >> +++ b/drivers/clk/mediatek/clk-mt8173.c
>> >> @@ -25,6 +25,10 @@ static DEFINE_SPINLOCK(mt8173_clk_lock);
>> >>  static const struct mtk_fixed_clk fixed_clks[] __initconst = {
>> >>       FIXED_CLK(CLK_TOP_CLKPH_MCK_O, "clkph_mck_o", "clk26m", 400 * MHZ),
>> >>       FIXED_CLK(CLK_TOP_USB_SYSPLL_125M, "usb_syspll_125m", "clk26m", 125 * MHZ),
>> >> +     FIXED_CLK(CLK_TOP_DSI0_DIG, "dsi0_dig", "clk26m", 130 * MHZ),
>> >> +     FIXED_CLK(CLK_TOP_DSI1_DIG, "dsi1_dig", "clk26m", 130 * MHZ),
>> >> +     FIXED_CLK(CLK_TOP_LVDS_PXL, "lvds_pxl", "lvdspll", 148.5 * MHZ),
>> >> +     FIXED_CLK(CLK_TOP_LVDS_CTS, "lvds_cts", "lvdspll", 51.975 * MHZ),
>> >
>> > I would expect 51975 * KHZ here to avoid fractional numbers. Probably
>> > gcc calculates that during compile time so this will work as expected,
>> > still I'm not sure this is good style to use fractional numbers here.
>>
>> I thought this looked a bit strange too, but for what its worth, these
>> two evaluate correctly:
>>
>> localhost ~ # cat /sys/kernel/debug/clk/clk_summary  | grep lvds
>>     lvdspll                               0            0   149999878
>>        0 0
>>        lvds_pxl                           0            0   148500000
>>        0 0
>>        lvds_cts                           0            0    51975000
>>        0 0
>>
>> >
>> > Anyway, on my system lvdspll is running at 150MHz. Are you sure there is
>> > a clock derived from this running at 148.5MHz? Is it really correct to
>> > use a fixed clock here or should it rather be lvdspll directly?
>>
>> I agree it does look strange to have a 51.975 MHz and 148.5 MHz clocks
>> with a 150 MHz PLL as their parent...  However, I'm not sure how much
>> this matters?  I think the idea here was that these frequencies are
>> best effort "nominal" clock values provided by Mediatek "designers".
>> The important point is that for the hardware to generate these either
>> of these clocks, lvdspll must be enabled.
>
> This assumes that the lvdspll always runs at frequency the designers
> thought that might be a good value. Should we really provide wrong clock
> values when on some board for whatever reason the lvdspll is configured
> for a different frequency?

Do you have an alternative suggestion for estimating the frequency of
a non-software controllable or measurable hardware clock?

Or can we land this series and update the frequency via some future
patch if and when that other board arrives which may have a different
frequency - and there is some reason to care what that frequency
actually is?

-Dan

>
> sascha
>
> --
> Pengutronix e.K.                           |                             |
> Industrial Linux Solutions                 | http://www.pengutronix.de/  |
> Peiner Str. 6-8, 31137 Hildesheim, Germany | Phone: +49-5121-206917-0    |
> Amtsgericht Hildesheim, HRA 2686           | Fax:   +49-5121-206917-5555 |


From s.hauer at pengutronix.de  Wed Aug  5 00:50:58 2015
From: s.hauer at pengutronix.de (Sascha Hauer)
Date: Wed, 5 Aug 2015 09:50:58 +0200
Subject: [PATCH v6 7/9] clk: mediatek: Add subsystem clocks of MT8173
In-Reply-To: <CAGS+omAFpWHO5w22Lq5fF6aXxf0bWi0KG7OB4u-FEFNUxPiceA@mail.gmail.com>
References: <1438676218-11310-1-git-send-email-jamesjj.liao@mediatek.com>
 <1438676218-11310-8-git-send-email-jamesjj.liao@mediatek.com>
 <20150805064605.GZ18700@pengutronix.de>
 <CAGS+omDmgxO9jHaPRb1hXO7fMRE=CnH=WNP3DeMm1axBswK_Aw@mail.gmail.com>
 <20150805073645.GB18700@pengutronix.de>
 <CAGS+omAFpWHO5w22Lq5fF6aXxf0bWi0KG7OB4u-FEFNUxPiceA@mail.gmail.com>
Message-ID: <20150805075058.GC18700@pengutronix.de>

On Wed, Aug 05, 2015 at 03:41:49PM +0800, Daniel Kurtz wrote:
> On Wed, Aug 5, 2015 at 3:36 PM, Sascha Hauer <s.hauer at pengutronix.de> wrote:
> > On Wed, Aug 05, 2015 at 03:26:29PM +0800, Daniel Kurtz wrote:
> >> On Wed, Aug 5, 2015 at 2:46 PM, Sascha Hauer <s.hauer at pengutronix.de> wrote:
> >> > On Tue, Aug 04, 2015 at 04:16:56PM +0800, James Liao wrote:
> >> >> Most multimedia subsystem clocks will be accessed by multiple
> >> >> drivers, so it's a better way to manage these clocks in CCF.
> >> >> This patch adds clock support for MM, IMG, VDEC, VENC and VENC_LT
> >> >> subsystems.
> >> >>
> >> >> Signed-off-by: James Liao <jamesjj.liao at mediatek.com>
> >> >> ---
> >> >>  drivers/clk/mediatek/clk-mt8173.c      | 267 +++++++++++++++++++++++++++++++++
> >> >>  include/dt-bindings/clock/mt8173-clk.h |  97 +++++++++++-
> >> >>  2 files changed, 361 insertions(+), 3 deletions(-)
> >> >>
> >> >> diff --git a/drivers/clk/mediatek/clk-mt8173.c b/drivers/clk/mediatek/clk-mt8173.c
> >> >> index f37ace6..05335e5 100644
> >> >> --- a/drivers/clk/mediatek/clk-mt8173.c
> >> >> +++ b/drivers/clk/mediatek/clk-mt8173.c
> >> >> @@ -25,6 +25,10 @@ static DEFINE_SPINLOCK(mt8173_clk_lock);
> >> >>  static const struct mtk_fixed_clk fixed_clks[] __initconst = {
> >> >>       FIXED_CLK(CLK_TOP_CLKPH_MCK_O, "clkph_mck_o", "clk26m", 400 * MHZ),
> >> >>       FIXED_CLK(CLK_TOP_USB_SYSPLL_125M, "usb_syspll_125m", "clk26m", 125 * MHZ),
> >> >> +     FIXED_CLK(CLK_TOP_DSI0_DIG, "dsi0_dig", "clk26m", 130 * MHZ),
> >> >> +     FIXED_CLK(CLK_TOP_DSI1_DIG, "dsi1_dig", "clk26m", 130 * MHZ),
> >> >> +     FIXED_CLK(CLK_TOP_LVDS_PXL, "lvds_pxl", "lvdspll", 148.5 * MHZ),
> >> >> +     FIXED_CLK(CLK_TOP_LVDS_CTS, "lvds_cts", "lvdspll", 51.975 * MHZ),
> >> >
> >> > I would expect 51975 * KHZ here to avoid fractional numbers. Probably
> >> > gcc calculates that during compile time so this will work as expected,
> >> > still I'm not sure this is good style to use fractional numbers here.
> >>
> >> I thought this looked a bit strange too, but for what its worth, these
> >> two evaluate correctly:
> >>
> >> localhost ~ # cat /sys/kernel/debug/clk/clk_summary  | grep lvds
> >>     lvdspll                               0            0   149999878
> >>        0 0
> >>        lvds_pxl                           0            0   148500000
> >>        0 0
> >>        lvds_cts                           0            0    51975000
> >>        0 0
> >>
> >> >
> >> > Anyway, on my system lvdspll is running at 150MHz. Are you sure there is
> >> > a clock derived from this running at 148.5MHz? Is it really correct to
> >> > use a fixed clock here or should it rather be lvdspll directly?
> >>
> >> I agree it does look strange to have a 51.975 MHz and 148.5 MHz clocks
> >> with a 150 MHz PLL as their parent...  However, I'm not sure how much
> >> this matters?  I think the idea here was that these frequencies are
> >> best effort "nominal" clock values provided by Mediatek "designers".
> >> The important point is that for the hardware to generate these either
> >> of these clocks, lvdspll must be enabled.
> >
> > This assumes that the lvdspll always runs at frequency the designers
> > thought that might be a good value. Should we really provide wrong clock
> > values when on some board for whatever reason the lvdspll is configured
> > for a different frequency?
> 
> Do you have an alternative suggestion for estimating the frequency of
> a non-software controllable or measurable hardware clock?

What's the problem with using lvdspll directly? The consumers of these
clocks should be able to cope with the deviation between nomial
frequency and actual frequency.

Sascha

-- 
Pengutronix e.K.                           |                             |
Industrial Linux Solutions                 | http://www.pengutronix.de/  |
Peiner Str. 6-8, 31137 Hildesheim, Germany | Phone: +49-5121-206917-0    |
Amtsgericht Hildesheim, HRA 2686           | Fax:   +49-5121-206917-5555 |


From rogerq at ti.com  Wed Aug  5 00:55:16 2015
From: rogerq at ti.com (Roger Quadros)
Date: Wed, 5 Aug 2015 10:55:16 +0300
Subject: [PATCH 01/10] ARM: dts: dra7: Add dt node for PCIe registers
 in sysctrl space
In-Reply-To: <1438702233-8027-2-git-send-email-kishon@ti.com>
References: <1438702233-8027-1-git-send-email-kishon@ti.com>
 <1438702233-8027-2-git-send-email-kishon@ti.com>
Message-ID: <55C1C164.80507@ti.com>

On 04/08/15 18:30, Kishon Vijay Abraham I wrote:
> Add new device tree node for the control module register space where
> PCIe registers are present.
> 
> Signed-off-by: Kishon Vijay Abraham I <kishon at ti.com>

Acked-by: Roger Quadros <rogerq at ti.com>

cheers,
-roger

> ---
>  arch/arm/boot/dts/dra7.dtsi |    5 +++++
>  1 file changed, 5 insertions(+)
> 
> diff --git a/arch/arm/boot/dts/dra7.dtsi b/arch/arm/boot/dts/dra7.dtsi
> index aa6abfc..33c5655 100644
> --- a/arch/arm/boot/dts/dra7.dtsi
> +++ b/arch/arm/boot/dts/dra7.dtsi
> @@ -154,6 +154,11 @@
>  					compatible = "syscon";
>  					reg = <0x1c04 0x0020>;
>  				};
> +
> +				scm_conf2: scm_conf at 1c24 {
> +					compatible = "syscon";
> +					reg = <0x1c24 0x0024>;
> +				};
>  			};
>  
>  			cm_core_aon: cm_core_aon at 5000 {
> 


From rogerq at ti.com  Wed Aug  5 00:55:42 2015
From: rogerq at ti.com (Roger Quadros)
Date: Wed, 5 Aug 2015 10:55:42 +0300
Subject: [PATCH 02/10] ARM: dts: dra7: Use "syscon-phy-power" instead
 of "ctrl-module" in SATA PHY node
In-Reply-To: <1438702233-8027-3-git-send-email-kishon@ti.com>
References: <1438702233-8027-1-git-send-email-kishon@ti.com>
 <1438702233-8027-3-git-send-email-kishon@ti.com>
Message-ID: <55C1C17E.9050306@ti.com>

On 04/08/15 18:30, Kishon Vijay Abraham I wrote:
> Add "syscon-phy-power" property and remove the deprecated "ctrl-module"
> property from SATA PHY node. Since "omap_control_sata" note is no longer
> used, remove it.
> 
> Signed-off-by: Kishon Vijay Abraham I <kishon at ti.com>

Acked-by: Roger Quadros <rogerq at ti.com>

cheers,
-roger

> ---
>  arch/arm/boot/dts/dra7.dtsi |   10 +---------
>  1 file changed, 1 insertion(+), 9 deletions(-)
> 
> diff --git a/arch/arm/boot/dts/dra7.dtsi b/arch/arm/boot/dts/dra7.dtsi
> index 33c5655..6854385 100644
> --- a/arch/arm/boot/dts/dra7.dtsi
> +++ b/arch/arm/boot/dts/dra7.dtsi
> @@ -1115,14 +1115,6 @@
>  			status = "disabled";
>  		};
>  
> -		omap_control_sata: control-phy at 4a002374 {
> -			compatible = "ti,control-phy-pipe3";
> -			reg = <0x4a002374 0x4>;
> -			reg-names = "power";
> -			clocks = <&sys_clkin1>;
> -			clock-names = "sysclk";
> -		};
> -
>  		/* OCP2SCP3 */
>  		ocp2scp at 4a090000 {
>  			compatible = "ti,omap-ocp2scp";
> @@ -1137,7 +1129,7 @@
>  				      <0x4A096400 0x64>, /* phy_tx */
>  				      <0x4A096800 0x40>; /* pll_ctrl */
>  				reg-names = "phy_rx", "phy_tx", "pll_ctrl";
> -				ctrl-module = <&omap_control_sata>;
> +				syscon-phy-power = <&scm_conf 0x374>;
>  				clocks = <&sys_clkin1>, <&sata_ref_clk>;
>  				clock-names = "sysclk", "refclk";
>  				#phy-cells = <0>;
> 


From rogerq at ti.com  Wed Aug  5 00:56:43 2015
From: rogerq at ti.com (Roger Quadros)
Date: Wed, 5 Aug 2015 10:56:43 +0300
Subject: [PATCH 05/10] ARM: dts: dra7: Use "syscon-phy-power" instead
 of "ctrl-module" in USB PHY node
In-Reply-To: <1438702233-8027-6-git-send-email-kishon@ti.com>
References: <1438702233-8027-1-git-send-email-kishon@ti.com>
 <1438702233-8027-6-git-send-email-kishon@ti.com>
Message-ID: <55C1C1BB.3060600@ti.com>

On 04/08/15 18:30, Kishon Vijay Abraham I wrote:
> Add "syscon-phy-power" property and remove the deprecated "ctrl-module"
> property from USB PHY devicetree nodes.
> 
> Since "omap_control_usb2phy1", "omap_control_usb3phy1" and
> "omap_control_usb2phy2" devicetree nodes are no longer used, remove it.

s/it/them

> 
> Signed-off-by: Kishon Vijay Abraham I <kishon at ti.com>

Acked-by: Roger Quadros <rogerq at ti.com>

cheers,
-roger

> ---
>  arch/arm/boot/dts/dra7.dtsi |   24 +++---------------------
>  1 file changed, 3 insertions(+), 21 deletions(-)
> 
> diff --git a/arch/arm/boot/dts/dra7.dtsi b/arch/arm/boot/dts/dra7.dtsi
> index dfefd17..191ffae 100644
> --- a/arch/arm/boot/dts/dra7.dtsi
> +++ b/arch/arm/boot/dts/dra7.dtsi
> @@ -1195,24 +1195,6 @@
>  			clocks = <&sys_32k_ck>;
>  		};
>  
> -		omap_control_usb2phy1: control-phy at 4a002300 {
> -			compatible = "ti,control-phy-usb2";
> -			reg = <0x4a002300 0x4>;
> -			reg-names = "power";
> -		};
> -
> -		omap_control_usb3phy1: control-phy at 4a002370 {
> -			compatible = "ti,control-phy-pipe3";
> -			reg = <0x4a002370 0x4>;
> -			reg-names = "power";
> -		};
> -
> -		omap_control_usb2phy2: control-phy at 0x4a002e74 {
> -			compatible = "ti,control-phy-usb2-dra7";
> -			reg = <0x4a002e74 0x4>;
> -			reg-names = "power";
> -		};
> -
>  		/* OCP2SCP1 */
>  		ocp2scp at 4a080000 {
>  			compatible = "ti,omap-ocp2scp";
> @@ -1225,7 +1207,7 @@
>  			usb2_phy1: phy at 4a084000 {
>  				compatible = "ti,omap-usb2";
>  				reg = <0x4a084000 0x400>;
> -				ctrl-module = <&omap_control_usb2phy1>;
> +				syscon-phy-power = <&scm_conf 0x300>;
>  				clocks = <&usb_phy1_always_on_clk32k>,
>  					 <&usb_otg_ss1_refclk960m>;
>  				clock-names =	"wkupclk",
> @@ -1236,7 +1218,7 @@
>  			usb2_phy2: phy at 4a085000 {
>  				compatible = "ti,dra7x-usb2-phy2", "ti,omap-usb2";
>  				reg = <0x4a085000 0x400>;
> -				ctrl-module = <&omap_control_usb2phy2>;
> +				syscon-phy-power = <&scm_conf 0xe74>;
>  				clocks = <&usb_phy2_always_on_clk32k>,
>  					 <&usb_otg_ss2_refclk960m>;
>  				clock-names =	"wkupclk",
> @@ -1250,7 +1232,7 @@
>  				      <0x4a084800 0x64>,
>  				      <0x4a084c00 0x40>;
>  				reg-names = "phy_rx", "phy_tx", "pll_ctrl";
> -				ctrl-module = <&omap_control_usb3phy1>;
> +				syscon-phy-power = <&scm_conf 0x370>;
>  				clocks = <&usb_phy3_always_on_clk32k>,
>  					 <&sys_clkin1>,
>  					 <&usb_otg_ss1_refclk960m>;
> 


From rogerq at ti.com  Wed Aug  5 00:58:02 2015
From: rogerq at ti.com (Roger Quadros)
Date: Wed, 5 Aug 2015 10:58:02 +0300
Subject: [PATCH 06/10] ARM: dts: am4372: Use "syscon-phy-power" instead
 of "ctrl-module" in USB PHY node
In-Reply-To: <1438702233-8027-7-git-send-email-kishon@ti.com>
References: <1438702233-8027-1-git-send-email-kishon@ti.com>
 <1438702233-8027-7-git-send-email-kishon@ti.com>
Message-ID: <55C1C20A.5070003@ti.com>

On 04/08/15 18:30, Kishon Vijay Abraham I wrote:
> Add "syscon-phy-power" property and remove the deprecated "ctrl-module"
> property from USB PHY device tree node.
> 
> Since "am43xx_control_usb2phy1" and "am43xx_control_usb2phy2"
> devicetree nodes are no longer used, remove it.
> 
> Signed-off-by: Kishon Vijay Abraham I <kishon at ti.com>

Acked-by: Roger Quadros <rogerq at ti.com>

cheers,
-roger

> ---
>  arch/arm/boot/dts/am4372.dtsi |   16 ++--------------
>  1 file changed, 2 insertions(+), 14 deletions(-)
> 
> diff --git a/arch/arm/boot/dts/am4372.dtsi b/arch/arm/boot/dts/am4372.dtsi
> index ade28c79..24fa073 100644
> --- a/arch/arm/boot/dts/am4372.dtsi
> +++ b/arch/arm/boot/dts/am4372.dtsi
> @@ -802,18 +802,6 @@
>  			status = "disabled";
>  		};
>  
> -		am43xx_control_usb2phy1: control-phy at 44e10620 {
> -			compatible = "ti,control-phy-usb2-am437";
> -			reg = <0x44e10620 0x4>;
> -			reg-names = "power";
> -		};
> -
> -		am43xx_control_usb2phy2: control-phy at 0x44e10628 {
> -			compatible = "ti,control-phy-usb2-am437";
> -			reg = <0x44e10628 0x4>;
> -			reg-names = "power";
> -		};
> -
>  		ocp2scp0: ocp2scp at 483a8000 {
>  			compatible = "ti,am437x-ocp2scp", "ti,omap-ocp2scp";
>  			#address-cells = <1>;
> @@ -824,7 +812,7 @@
>  			usb2_phy1: phy at 483a8000 {
>  				compatible = "ti,am437x-usb2";
>  				reg = <0x483a8000 0x8000>;
> -				ctrl-module = <&am43xx_control_usb2phy1>;
> +				syscon-phy-power = <&scm_conf 0x620>;
>  				clocks = <&usb_phy0_always_on_clk32k>,
>  					 <&usb_otg_ss0_refclk960m>;
>  				clock-names = "wkupclk", "refclk";
> @@ -843,7 +831,7 @@
>  			usb2_phy2: phy at 483e8000 {
>  				compatible = "ti,am437x-usb2";
>  				reg = <0x483e8000 0x8000>;
> -				ctrl-module = <&am43xx_control_usb2phy2>;
> +				syscon-phy-power = <&scm_conf 0x628>;
>  				clocks = <&usb_phy1_always_on_clk32k>,
>  					 <&usb_otg_ss1_refclk960m>;
>  				clock-names = "wkupclk", "refclk";
> 


From djkurtz at chromium.org  Wed Aug  5 00:58:03 2015
From: djkurtz at chromium.org (Daniel Kurtz)
Date: Wed, 5 Aug 2015 15:58:03 +0800
Subject: [PATCH v6 7/9] clk: mediatek: Add subsystem clocks of MT8173
In-Reply-To: <20150805075058.GC18700@pengutronix.de>
References: <1438676218-11310-1-git-send-email-jamesjj.liao@mediatek.com>
 <1438676218-11310-8-git-send-email-jamesjj.liao@mediatek.com>
 <20150805064605.GZ18700@pengutronix.de>
 <CAGS+omDmgxO9jHaPRb1hXO7fMRE=CnH=WNP3DeMm1axBswK_Aw@mail.gmail.com>
 <20150805073645.GB18700@pengutronix.de>
 <CAGS+omAFpWHO5w22Lq5fF6aXxf0bWi0KG7OB4u-FEFNUxPiceA@mail.gmail.com>
 <20150805075058.GC18700@pengutronix.de>
Message-ID: <CAGS+omAjME7Rw9CASFbhPidLrhkxmKh91G5mZpHwdQHBN6wJmg@mail.gmail.com>

On Wed, Aug 5, 2015 at 3:50 PM, Sascha Hauer <s.hauer at pengutronix.de> wrote:
> On Wed, Aug 05, 2015 at 03:41:49PM +0800, Daniel Kurtz wrote:
>> On Wed, Aug 5, 2015 at 3:36 PM, Sascha Hauer <s.hauer at pengutronix.de> wrote:
>> > On Wed, Aug 05, 2015 at 03:26:29PM +0800, Daniel Kurtz wrote:
>> >> On Wed, Aug 5, 2015 at 2:46 PM, Sascha Hauer <s.hauer at pengutronix.de> wrote:
>> >> > On Tue, Aug 04, 2015 at 04:16:56PM +0800, James Liao wrote:
>> >> >> Most multimedia subsystem clocks will be accessed by multiple
>> >> >> drivers, so it's a better way to manage these clocks in CCF.
>> >> >> This patch adds clock support for MM, IMG, VDEC, VENC and VENC_LT
>> >> >> subsystems.
>> >> >>
>> >> >> Signed-off-by: James Liao <jamesjj.liao at mediatek.com>
>> >> >> ---
>> >> >>  drivers/clk/mediatek/clk-mt8173.c      | 267 +++++++++++++++++++++++++++++++++
>> >> >>  include/dt-bindings/clock/mt8173-clk.h |  97 +++++++++++-
>> >> >>  2 files changed, 361 insertions(+), 3 deletions(-)
>> >> >>
>> >> >> diff --git a/drivers/clk/mediatek/clk-mt8173.c b/drivers/clk/mediatek/clk-mt8173.c
>> >> >> index f37ace6..05335e5 100644
>> >> >> --- a/drivers/clk/mediatek/clk-mt8173.c
>> >> >> +++ b/drivers/clk/mediatek/clk-mt8173.c
>> >> >> @@ -25,6 +25,10 @@ static DEFINE_SPINLOCK(mt8173_clk_lock);
>> >> >>  static const struct mtk_fixed_clk fixed_clks[] __initconst = {
>> >> >>       FIXED_CLK(CLK_TOP_CLKPH_MCK_O, "clkph_mck_o", "clk26m", 400 * MHZ),
>> >> >>       FIXED_CLK(CLK_TOP_USB_SYSPLL_125M, "usb_syspll_125m", "clk26m", 125 * MHZ),
>> >> >> +     FIXED_CLK(CLK_TOP_DSI0_DIG, "dsi0_dig", "clk26m", 130 * MHZ),
>> >> >> +     FIXED_CLK(CLK_TOP_DSI1_DIG, "dsi1_dig", "clk26m", 130 * MHZ),
>> >> >> +     FIXED_CLK(CLK_TOP_LVDS_PXL, "lvds_pxl", "lvdspll", 148.5 * MHZ),
>> >> >> +     FIXED_CLK(CLK_TOP_LVDS_CTS, "lvds_cts", "lvdspll", 51.975 * MHZ),
>> >> >
>> >> > I would expect 51975 * KHZ here to avoid fractional numbers. Probably
>> >> > gcc calculates that during compile time so this will work as expected,
>> >> > still I'm not sure this is good style to use fractional numbers here.
>> >>
>> >> I thought this looked a bit strange too, but for what its worth, these
>> >> two evaluate correctly:
>> >>
>> >> localhost ~ # cat /sys/kernel/debug/clk/clk_summary  | grep lvds
>> >>     lvdspll                               0            0   149999878
>> >>        0 0
>> >>        lvds_pxl                           0            0   148500000
>> >>        0 0
>> >>        lvds_cts                           0            0    51975000
>> >>        0 0
>> >>
>> >> >
>> >> > Anyway, on my system lvdspll is running at 150MHz. Are you sure there is
>> >> > a clock derived from this running at 148.5MHz? Is it really correct to
>> >> > use a fixed clock here or should it rather be lvdspll directly?
>> >>
>> >> I agree it does look strange to have a 51.975 MHz and 148.5 MHz clocks
>> >> with a 150 MHz PLL as their parent...  However, I'm not sure how much
>> >> this matters?  I think the idea here was that these frequencies are
>> >> best effort "nominal" clock values provided by Mediatek "designers".
>> >> The important point is that for the hardware to generate these either
>> >> of these clocks, lvdspll must be enabled.
>> >
>> > This assumes that the lvdspll always runs at frequency the designers
>> > thought that might be a good value. Should we really provide wrong clock
>> > values when on some board for whatever reason the lvdspll is configured
>> > for a different frequency?
>>
>> Do you have an alternative suggestion for estimating the frequency of
>> a non-software controllable or measurable hardware clock?
>
> What's the problem with using lvdspll directly? The consumers of these
> clocks should be able to cope with the deviation between nomial
> frequency and actual frequency.

Oh, I'm totally fine with that too.  Although I think the way James
has it better models the hardware.

> Sascha
>
> --
> Pengutronix e.K.                           |                             |
> Industrial Linux Solutions                 | http://www.pengutronix.de/  |
> Peiner Str. 6-8, 31137 Hildesheim, Germany | Phone: +49-5121-206917-0    |
> Amtsgericht Hildesheim, HRA 2686           | Fax:   +49-5121-206917-5555 |


From rogerq at ti.com  Wed Aug  5 00:58:43 2015
From: rogerq at ti.com (Roger Quadros)
Date: Wed, 5 Aug 2015 10:58:43 +0300
Subject: [PATCH 07/10] ARM: dts: OMAP5: Use "syscon-phy-power" instead
 of "ctrl-module" in USB PHY node
In-Reply-To: <1438702233-8027-8-git-send-email-kishon@ti.com>
References: <1438702233-8027-1-git-send-email-kishon@ti.com>
 <1438702233-8027-8-git-send-email-kishon@ti.com>
Message-ID: <55C1C233.4010102@ti.com>

On 04/08/15 18:30, Kishon Vijay Abraham I wrote:
> Add "syscon-phy-power" property and remove the deprecated "ctrl-module"
> property from USB PHY devicetree node.
> 
> Since "omap_control_usb2phy" and "omap_control_usb3phy" devicetree nodes
> are no longer used, remove it.
> 
> Signed-off-by: Kishon Vijay Abraham I <kishon at ti.com>

Acked-by: Roger Quadros <rogerq at ti.com>

cheers,
-roger

> ---
>  arch/arm/boot/dts/omap5.dtsi |   16 ++--------------
>  1 file changed, 2 insertions(+), 14 deletions(-)
> 
> diff --git a/arch/arm/boot/dts/omap5.dtsi b/arch/arm/boot/dts/omap5.dtsi
> index c8fd648..f0b6cd6 100644
> --- a/arch/arm/boot/dts/omap5.dtsi
> +++ b/arch/arm/boot/dts/omap5.dtsi
> @@ -848,18 +848,6 @@
>  			hw-caps-temp-alert;
>  		};
>  
> -		omap_control_usb2phy: control-phy at 4a002300 {
> -			compatible = "ti,control-phy-usb2";
> -			reg = <0x4a002300 0x4>;
> -			reg-names = "power";
> -		};
> -
> -		omap_control_usb3phy: control-phy at 4a002370 {
> -			compatible = "ti,control-phy-pipe3";
> -			reg = <0x4a002370 0x4>;
> -			reg-names = "power";
> -		};
> -
>  		usb3: omap_dwc3 at 4a020000 {
>  			compatible = "ti,dwc3";
>  			ti,hwmods = "usb_otg_ss";
> @@ -890,7 +878,7 @@
>  			usb2_phy: usb2phy at 4a084000 {
>  				compatible = "ti,omap-usb2";
>  				reg = <0x4a084000 0x7c>;
> -				ctrl-module = <&omap_control_usb2phy>;
> +				syscon-phy-power = <&scm_conf 0x300>;
>  				clocks = <&usb_phy_cm_clk32k>, <&usb_otg_ss_refclk960m>;
>  				clock-names = "wkupclk", "refclk";
>  				#phy-cells = <0>;
> @@ -902,7 +890,7 @@
>  				      <0x4a084800 0x64>,
>  				      <0x4a084c00 0x40>;
>  				reg-names = "phy_rx", "phy_tx", "pll_ctrl";
> -				ctrl-module = <&omap_control_usb3phy>;
> +				syscon-phy-power = <&scm_conf 0x370>;
>  				clocks = <&usb_phy_cm_clk32k>,
>  					 <&sys_clkin>,
>  					 <&usb_otg_ss_refclk960m>;
> 


From rogerq at ti.com  Wed Aug  5 00:59:39 2015
From: rogerq at ti.com (Roger Quadros)
Date: Wed, 5 Aug 2015 10:59:39 +0300
Subject: [PATCH 08/10] ARM: dts: OMAP5: Use "syscon-phy-power" instead
 of "ctrl-module" in SATA PHY node
In-Reply-To: <1438702233-8027-9-git-send-email-kishon@ti.com>
References: <1438702233-8027-1-git-send-email-kishon@ti.com>
 <1438702233-8027-9-git-send-email-kishon@ti.com>
Message-ID: <55C1C26B.4040809@ti.com>

On 04/08/15 18:30, Kishon Vijay Abraham I wrote:
> Add "syscon-phy-power" property and remove the deprecated "ctrl-module"
> property from SATA PHY node.
> 
> Since "omap_control_sata" devicetree node is no longer used, remove it.
> 
> Signed-off-by: Kishon Vijay Abraham I <kishon at ti.com>

Acked-by: Roger Quadros <rogerq at ti.com>

cheers,
-roger

> ---
>  arch/arm/boot/dts/omap5.dtsi |   10 +---------
>  1 file changed, 1 insertion(+), 9 deletions(-)
> 
> diff --git a/arch/arm/boot/dts/omap5.dtsi b/arch/arm/boot/dts/omap5.dtsi
> index f0b6cd6..c3ca5b7 100644
> --- a/arch/arm/boot/dts/omap5.dtsi
> +++ b/arch/arm/boot/dts/omap5.dtsi
> @@ -946,14 +946,6 @@
>  			#thermal-sensor-cells = <1>;
>  		};
>  
> -		omap_control_sata: control-phy at 4a002374 {
> -			compatible = "ti,control-phy-pipe3";
> -			reg = <0x4a002374 0x4>;
> -			reg-names = "power";
> -			clocks = <&sys_clkin>;
> -			clock-names = "sysclk";
> -		};
> -
>  		/* OCP2SCP3 */
>  		ocp2scp at 4a090000 {
>  			compatible = "ti,omap-ocp2scp";
> @@ -968,7 +960,7 @@
>  				      <0x4A096400 0x64>, /* phy_tx */
>  				      <0x4A096800 0x40>; /* pll_ctrl */
>  				reg-names = "phy_rx", "phy_tx", "pll_ctrl";
> -				ctrl-module = <&omap_control_sata>;
> +				syscon-phy-power = <&scm_conf 0x374>;
>  				clocks = <&sys_clkin>, <&sata_ref_clk>;
>  				clock-names = "sysclk", "refclk";
>  				#phy-cells = <0>;
> 


From rogerq at ti.com  Wed Aug  5 01:01:22 2015
From: rogerq at ti.com (Roger Quadros)
Date: Wed, 5 Aug 2015 11:01:22 +0300
Subject: [PATCH 09/10] ARM: dts: omap4: Use "syscon-phy-power" instead
 of "ctrl-module" in USB PHY node
In-Reply-To: <1438702233-8027-10-git-send-email-kishon@ti.com>
References: <1438702233-8027-1-git-send-email-kishon@ti.com>
 <1438702233-8027-10-git-send-email-kishon@ti.com>
Message-ID: <55C1C2D2.1080200@ti.com>

On 04/08/15 18:30, Kishon Vijay Abraham I wrote:
> Add "syscon-phy-power" property and remove the deprecated "ctrl-module"
> property from USB PHY dt node.
> 
> Since "omap_control_usb2phy" devicetree node is no longer used,
> remove it.
> 
> Signed-off-by: Kishon Vijay Abraham I <kishon at ti.com>

Acked-by: Roger Quadros <rogerq at ti.com>

cheers,
-roger

> ---
>  arch/arm/boot/dts/omap4.dtsi |    8 +-------
>  1 file changed, 1 insertion(+), 7 deletions(-)
> 
> diff --git a/arch/arm/boot/dts/omap4.dtsi b/arch/arm/boot/dts/omap4.dtsi
> index 7d31c6f..b27634d 100644
> --- a/arch/arm/boot/dts/omap4.dtsi
> +++ b/arch/arm/boot/dts/omap4.dtsi
> @@ -703,7 +703,7 @@
>  			usb2_phy: usb2phy at 4a0ad080 {
>  				compatible = "ti,omap-usb2";
>  				reg = <0x4a0ad080 0x58>;
> -				ctrl-module = <&omap_control_usb2phy>;
> +				syscon-phy-power = <&scm_conf 0x300>;
>  				clocks = <&usb_phy_cm_clk32k>;
>  				clock-names = "wkupclk";
>  				#phy-cells = <0>;
> @@ -854,12 +854,6 @@
>  			};
>  		};
>  
> -		omap_control_usb2phy: control-phy at 4a002300 {
> -			compatible = "ti,control-phy-usb2";
> -			reg = <0x4a002300 0x4>;
> -			reg-names = "power";
> -		};
> -
>  		omap_control_usbotg: control-phy at 4a00233c {
>  			compatible = "ti,control-phy-otghs";
>  			reg = <0x4a00233c 0x4>;
> 


From aisheng.dong at freescale.com  Wed Aug  5 00:53:19 2015
From: aisheng.dong at freescale.com (Dong Aisheng)
Date: Wed, 5 Aug 2015 15:53:19 +0800
Subject: [PATCH v3 1/6] mmc: sdhci-esdhc-imx: add imx7d support and
 support HS400
In-Reply-To: <BY1PR03MB13888A2D2946E6B41EBFFFE19A750@BY1PR03MB1388.namprd03.prod.outlook.com>
References: <1438160637-28061-1-git-send-email-haibo.chen@freescale.com>
 <1438160637-28061-2-git-send-email-haibo.chen@freescale.com>
 <20150731141507.GB27806@shlinux1.ap.freescale.net>
 <BY1PR03MB13889195F33D0010E6759D309A880@BY1PR03MB1388.namprd03.prod.outlook.com>
 <20150803120932.GB24870@shlinux1.ap.freescale.net>
 <BY1PR03MB13888A2D2946E6B41EBFFFE19A750@BY1PR03MB1388.namprd03.prod.outlook.com>
Message-ID: <20150805075318.GF24870@shlinux1.ap.freescale.net>

On Wed, Aug 05, 2015 at 03:39:29PM +0800, Chen Haibo-B51421 wrote:
> 
> 
> > -----Original Message-----
> > From: Dong Aisheng [mailto:aisheng.dong at freescale.com]
> > Sent: Monday, August 03, 2015 8:10 PM
> > To: Chen Haibo-B51421
> > Cc: robh+dt at kernel.org; pawel.moll at arm.com; mark.rutland at arm.com;
> > ijc+devicetree at hellion.org.uk; galak at codeaurora.org; shawnguo at kernel.org;
> > kernel at pengutronix.de; linux at arm.linux.org.uk; ulf.hansson at linaro.org;
> > johan.derycke at barco.com; Estevam Fabio-R49496; devicetree at vger.kernel.org;
> > linux-kernel at vger.kernel.org; linux-arm-kernel at lists.infradead.org;
> > linux-mmc at vger.kernel.org
> > Subject: Re: [PATCH v3 1/6] mmc: sdhci-esdhc-imx: add imx7d support and
> > support HS400
> > 
> > On Sun, Aug 02, 2015 at 04:59:04PM +0800, Chen Haibo-B51421 wrote:
> > >
> > >
> > > > -----Original Message-----
> > > > From: Dong Aisheng [mailto:aisheng.dong at freescale.com]
> > > > Sent: Friday, July 31, 2015 10:15 PM
> > > > To: Chen Haibo-B51421
> > > > Cc: robh+dt at kernel.org; pawel.moll at arm.com; mark.rutland at arm.com;
> > > > ijc+devicetree at hellion.org.uk; galak at codeaurora.org;
> > > > ijc+shawnguo at kernel.org;
> > > > kernel at pengutronix.de; linux at arm.linux.org.uk;
> > > > ulf.hansson at linaro.org; johan.derycke at barco.com; Estevam
> > > > Fabio-R49496; Dong Aisheng-B29396; devicetree at vger.kernel.org;
> > > > linux-kernel at vger.kernel.org; linux-arm- kernel at lists.infradead.org;
> > > > linux-mmc at vger.kernel.org
> > > > Subject: Re: [PATCH v3 1/6] mmc: sdhci-esdhc-imx: add imx7d support
> > > > and support HS400
> > > >
> > > > On Wed, Jul 29, 2015 at 05:03:52PM +0800, Haibo Chen wrote:
> > > > > The imx7d usdhc is derived from imx6sx, the difference is that
> > > > > imx7d support HS400.
> > > > >
> > > > > So introduce a new compatible string for imx7d and add HS400
> > > > > support for imx7d usdhc.
> > > > >
> > > > > Signed-off-by: Haibo Chen <haibo.chen at freescale.com>
> > > > > ---
> > > > >  drivers/mmc/host/sdhci-esdhc-imx.c | 66
> > > > > ++++++++++++++++++++++++++++++++++++++
> > > > >  1 file changed, 66 insertions(+)
> > > > >
> > > > > diff --git a/drivers/mmc/host/sdhci-esdhc-imx.c
> > > > > b/drivers/mmc/host/sdhci-esdhc-imx.c
> > > > > index c6b9f64..b441eed 100644
> > > > > --- a/drivers/mmc/host/sdhci-esdhc-imx.c
> > > > > +++ b/drivers/mmc/host/sdhci-esdhc-imx.c
> > > > > @@ -44,6 +44,7 @@
> > > > >  #define  ESDHC_MIX_CTRL_EXE_TUNE	(1 << 22)
> > > > >  #define  ESDHC_MIX_CTRL_SMPCLK_SEL	(1 << 23)
> > > > >  #define  ESDHC_MIX_CTRL_FBCLK_SEL	(1 << 25)
> > > > > +#define  ESDHC_MIX_CTRL_HS400_EN	(1 << 26)
> > > > >  /* Bits 3 and 6 are not SDHCI standard definitions */
> > > > >  #define  ESDHC_MIX_CTRL_SDHCI_MASK	0xb7
> > > > >  /* Tuning bits */
> > > > > @@ -60,6 +61,16 @@
> > > > >  #define  ESDHC_TUNE_CTRL_MIN		0
> > > > >  #define  ESDHC_TUNE_CTRL_MAX		((1 << 7) - 1)
> > > > >
> > > > > +/* strobe dll register */
> > > > > +#define ESDHC_STROBE_DLL_CTRL		0x70
> > > > > +#define ESDHC_STROBE_DLL_CTRL_ENABLE	(1 << 0)
> > > > > +#define ESDHC_STROBE_DLL_CTRL_RESET	(1 << 1)
> > > > > +#define ESDHC_STROBE_DLL_CTRL_SLV_DLY_TARGET_SHIFT	3
> > > > > +
> > > > > +#define ESDHC_STROBE_DLL_STATUS		0x74
> > > > > +#define ESDHC_STROBE_DLL_STS_REF_LOCK	(1 << 1)
> > > > > +#define ESDHC_STROBE_DLL_STS_SLV_LOCK	0x1
> > > > > +
> > > > >  #define ESDHC_TUNING_CTRL		0xcc
> > > > >  #define ESDHC_STD_TUNING_EN		(1 << 24)
> > > > >  /* NOTE: the minimum valid tuning start tap for mx6sl is 1 */ @@
> > > > > -120,6 +131,8 @@
> > > > >  #define ESDHC_FLAG_ERR004536		BIT(7)
> > > > >  /* The IP supports HS200 mode */
> > > > >  #define ESDHC_FLAG_HS200		BIT(8)
> > > > > +/* The IP supports HS400 mode */
> > > > > +#define ESDHC_FLAG_SUP_HS400		BIT(9)
> > > > >
> > > > >  struct esdhc_soc_data {
> > > > >  	u32 flags;
> > > > > @@ -156,6 +169,12 @@ static struct esdhc_soc_data usdhc_imx6sx_data
> > = {
> > > > >  			| ESDHC_FLAG_HAVE_CAP1 | ESDHC_FLAG_HS200,  };
> > > > >
> > > > > +static struct esdhc_soc_data usdhc_imx7d_data = {
> > > > > +	.flags = ESDHC_FLAG_USDHC | ESDHC_FLAG_STD_TUNING
> > > > > +			| ESDHC_FLAG_HAVE_CAP1 | ESDHC_FLAG_HS200
> > > > > +			| ESDHC_FLAG_SUP_HS400,
> > > > > +};
> > > > > +
> > > > >  struct pltfm_imx_data {
> > > > >  	u32 scratchpad;
> > > > >  	struct pinctrl *pinctrl;
> > > > > @@ -199,6 +218,7 @@ static const struct of_device_id
> > > > > imx_esdhc_dt_ids[]
> > > > = {
> > > > >  	{ .compatible = "fsl,imx6sx-usdhc", .data =
> > &usdhc_imx6sx_data, },
> > > > >  	{ .compatible = "fsl,imx6sl-usdhc", .data =
> > &usdhc_imx6sl_data, },
> > > > >  	{ .compatible = "fsl,imx6q-usdhc", .data =
> > &usdhc_imx6q_data, },
> > > > > +	{ .compatible = "fsl,imx7d-usdhc", .data =
> > &usdhc_imx7d_data, },
> > > > >  	{ /* sentinel */ }
> > > > >  };
> > > > >  MODULE_DEVICE_TABLE(of, imx_esdhc_dt_ids); @@ -274,6 +294,10 @@
> > > > > static u32 esdhc_readl_le(struct sdhci_host *host, int reg)
> > > > >  				val = SDHCI_SUPPORT_DDR50 |
> > SDHCI_SUPPORT_SDR104
> > > > >  					| SDHCI_SUPPORT_SDR50
> > > > >  					| SDHCI_USE_SDR50_TUNING;
> > > > > +
> > > > > +			/* imx7d does not have a support_hs400 register,
> > fake
> > > > one */
> > > >
> > > > You could remove this line.
> > > > It's bit, not register and i think no need such comment.
> > > >
> > > > > +			if (imx_data->socdata->flags &
> > ESDHC_FLAG_SUP_HS400)
> > > > > +				val |= SDHCI_SUPPORT_HS400;
> > > > >  		}
> > > > >  	}
> > > > >
> > > > > @@ -774,6 +798,7 @@ static int esdhc_change_pinstate(struct
> > > > > sdhci_host
> > > > *host,
> > > > >  		break;
> > > > >  	case MMC_TIMING_UHS_SDR104:
> > > > >  	case MMC_TIMING_MMC_HS200:
> > > > > +	case MMC_TIMING_MMC_HS400:
> > > > >  		pinctrl = imx_data->pins_200mhz;
> > > > >  		break;
> > > > >  	default:
> > > > > @@ -784,6 +809,30 @@ static int esdhc_change_pinstate(struct
> > > > > sdhci_host
> > > > *host,
> > > > >  	return pinctrl_select_state(imx_data->pinctrl, pinctrl);  }
> > > > >
> > > > > +static void esdhc_set_strobe_dll(struct sdhci_host *host)
> > > >
> > > > It would be good if we can add some comments for this function for
> > > > better understand.
> > > >
> > >
> > > [haibo] okay, I will add comments here.
> > >
> > > > > +{
> > > > > +	u32 v;
> > > > > +
> > > > > +	/* force a reset on strobe dll */
> > > > > +	writel(ESDHC_STROBE_DLL_CTRL_RESET, host->ioaddr +
> > > > ESDHC_STROBE_DLL_CTRL);
> > > > > +	/*
> > > > > +	 * enable strobe dll ctrl and adjust the delay target
> > > > > +	 * for the uSDHC loopback read clock
> > > > > +	 */
> > > > > +	v = ESDHC_STROBE_DLL_CTRL_ENABLE |
> > > > > +		(7 << ESDHC_STROBE_DLL_CTRL_SLV_DLY_TARGET_SHIFT);
> > > > > +	writel(v, host->ioaddr + ESDHC_STROBE_DLL_CTRL);
> > > > > +	/* wait 1us to make sure strobe dll status register stable */
> > > > > +	udelay(1);
> > > > > +	v = readl(host->ioaddr + ESDHC_STROBE_DLL_STATUS);
> > > > > +	if (!(v & ESDHC_STROBE_DLL_STS_REF_LOCK))
> > > > > +		dev_warn(mmc_dev(host->mmc),
> > > > > +			"warning! HS400 strobe DLL status REF not
> > lock!\n");
> > > > > +	if (!(v & ESDHC_STROBE_DLL_STS_SLV_LOCK))
> > > > > +		dev_warn(mmc_dev(host->mmc),
> > > > > +			"warning! HS400 strobe DLL status SLV not
> > lock!\n"); }
> > > > > +
> > > > >  static void esdhc_set_uhs_signaling(struct sdhci_host *host,
> > > > > unsigned
> > > > > timing)  {
> > > > >  	struct sdhci_pltfm_host *pltfm_host = sdhci_priv(host); @@
> > > > > -795,7
> > > > > +844,13 @@ static void esdhc_set_uhs_signaling(struct sdhci_host
> > > > > +*host,
> > > > unsigned timing)
> > > > >  	case MMC_TIMING_UHS_SDR25:
> > > > >  	case MMC_TIMING_UHS_SDR50:
> > > > >  	case MMC_TIMING_UHS_SDR104:
> > > > > +		break;
> > > > >  	case MMC_TIMING_MMC_HS200:
> > > > > +		/* disable ddr mode and disable HS400 mode */
> > > > > +		writel(readl(host->ioaddr + ESDHC_MIX_CTRL) &
> > > > > +			~(ESDHC_MIX_CTRL_DDREN | ESDHC_MIX_CTRL_HS400_EN),
> > > > > +			host->ioaddr + ESDHC_MIX_CTRL);
> > > > > +		imx_data->is_ddr = 0;
> > > > >  		break;
> > > > >  	case MMC_TIMING_UHS_DDR50:
> > > > >  	case MMC_TIMING_MMC_DDR52:
> > > > > @@ -813,6 +868,14 @@ static void esdhc_set_uhs_signaling(struct
> > > > sdhci_host *host, unsigned timing)
> > > > >  			writel(v, host->ioaddr + ESDHC_DLL_CTRL);
> > > > >  		}
> > > > >  		break;
> > > > > +	case MMC_TIMING_MMC_HS400:
> > > > > +		writel(readl(host->ioaddr + ESDHC_MIX_CTRL) |
> > > > > +				ESDHC_MIX_CTRL_DDREN |
> > ESDHC_MIX_CTRL_HS400_EN,
> > > > > +				host->ioaddr + ESDHC_MIX_CTRL);
> > > > > +		imx_data->is_ddr = 1;
> > > > > +		if (host->clock == 200000000)
> > > >
> > > > I can't remember, but could this be a range required by SoC?
> > >
> > > [haibo]we should set strobe_dll only when the host clock is 200MHz. For
> > other condition, no need to do this.
> > >
> > 
> > It is not quite make sense for only 200Mhz clock here.
> > 
> > First, shall we check host->mmc->actual_clock instead of host->clock?
> > That is the real clock frequency the controller is working on.
> > 
> > 
> > Second, even MMC core requests to set 200Mhz clock for HS400, the real
> > clock controller working on may be less than 200Mhz which depends on the
> > uSDHC root clock capability.
> > e.g. it may be 192Mhz if the parent is 384Mhz or less.
> > If that, do we need call strobe_dll too?
> > 
> 
> [haibo] according to IC team feedback, when we use HS400 mode in high frequency, like:
> close to 200Mhz, including 192Mhz, we should call strobe_dll. When the eMMC clock is around
> 100Mhz, like 98Mhz, no need to call strobe_dll, I have test this, eMMC can read normally.
> 
> When the card clock become higher, each clock cycle becomes shorter. When each clock cycle is short
> enough, the time delay between CLK and strobe_data_clock maybe larger than one clock cycle, so the CLk
> and strobe_data_clock misaligned,  then read error shows up. (here CLK means the clock host supply to card,
> and strobe_data_clock means the clock generated by device which feedback to host for data read in HS400 mode).
> 
> So can we call strobe_dll when the card clock is over 100Mhz? 
> 

Yes, i'm okay with it.
You could define a macro for it like:
/* a higher clock frequency than this rate requires strobe dll control */
#define ESDHC_STROBE_DLL_CLK_FREQ	100000000
if (host->mmc->actual_clock > ESDHC_STROBE_DLL_CLK_FREQ)
	strobe_dll();

You can also get this as a separate function call which seems better.

Regards
Dong Aisheng

> 
> > Can you check above two concerns?
> > 
> > Regards
> > Dong Aisheng
> > 
> > > >
> > > > > +			esdhc_set_strobe_dll(host);
> > > > > +		break;
> > > > >  	}
> > > > >
> > > > >  	esdhc_change_pinstate(host, timing); @@ -1100,6 +1163,9 @@
> > > > > static int sdhci_esdhc_imx_probe(struct platform_device *pdev)
> > > > >  	if (imx_data->socdata->flags & ESDHC_FLAG_ERR004536)
> > > > >  		host->quirks |= SDHCI_QUIRK_BROKEN_ADMA;
> > > > >
> > > > > +	if (imx_data->socdata->flags & ESDHC_FLAG_SUP_HS400)
> > > > > +		host->quirks2 |= SDHCI_QUIRK2_CAPS_BIT63_FOR_HS400;
> > > > > +
> > > > >  	if (of_id)
> > > > >  		err = sdhci_esdhc_imx_probe_dt(pdev, host, imx_data);
> > > > >  	else
> > > > > --
> > > > > 1.9.1
> > > > >
> > > >
> > > > Regards
> > > > Dong Aisheng


From rogerq at ti.com  Wed Aug  5 01:02:45 2015
From: rogerq at ti.com (Roger Quadros)
Date: Wed, 5 Aug 2015 11:02:45 +0300
Subject: [PATCH 10/10] ARM: dts: omap4: Use "syscon-otghs" instead of
 "ctrl-module" in USB node
In-Reply-To: <1438702233-8027-11-git-send-email-kishon@ti.com>
References: <1438702233-8027-1-git-send-email-kishon@ti.com>
 <1438702233-8027-11-git-send-email-kishon@ti.com>
Message-ID: <55C1C325.5040703@ti.com>

Kishon,

On 04/08/15 18:30, Kishon Vijay Abraham I wrote:
> Add "syscon-otghs" property and remove the deprecated "ctrl-module"
> property from MUSB devicetree node.
> 
> Since "omap_control_usbotg" devicetree node is no longer used, remove
> it.
> 
> Signed-off-by: Kishon Vijay Abraham I <kishon at ti.com>
> ---
>  arch/arm/boot/dts/omap4.dtsi |    8 +-------
>  1 file changed, 1 insertion(+), 7 deletions(-)
> 
> diff --git a/arch/arm/boot/dts/omap4.dtsi b/arch/arm/boot/dts/omap4.dtsi
> index b27634d..2fb49a5 100644
> --- a/arch/arm/boot/dts/omap4.dtsi
> +++ b/arch/arm/boot/dts/omap4.dtsi
> @@ -854,12 +854,6 @@
>  			};
>  		};
>  
> -		omap_control_usbotg: control-phy at 4a00233c {
> -			compatible = "ti,control-phy-otghs";
> -			reg = <0x4a00233c 0x4>;
> -			reg-names = "otghs_control";
> -		};
> -
>  		usb_otg_hs: usb_otg_hs at 4a0ab000 {
>  			compatible = "ti,omap4-musb";
>  			reg = <0x4a0ab000 0x7ff>;
> @@ -872,7 +866,7 @@
>  			multipoint = <1>;
>  			num-eps = <16>;
>  			ram-bits = <12>;
> -			ctrl-module = <&omap_control_usbotg>;
> +			syscon-otghs = <&scm_conf 0x33c>;

All other properties were of the format "syscon-phy-foo".
Why use a different format here?

Other than that

Acked-by: Roger Quadros <rogerq at ti.com>

cheers,
-roger


>  		};
>  
>  		aes: aes at 4b501000 {
> 


From maitysanchayan at gmail.com  Wed Aug  5 01:00:45 2015
From: maitysanchayan at gmail.com (maitysanchayan at gmail.com)
Date: Wed, 5 Aug 2015 13:30:45 +0530
Subject: [PATCH] iio: adc: vf610: Add IIO buffer support for Vybrid ADC
In-Reply-To: <BN3PR0301MB12191A12387C829F111B612BF5760@BN3PR0301MB1219.namprd03.prod.outlook.com>
References: <cover.1438610517.git.maitysanchayan@gmail.com>
 <1f11be7d7bc1c3fcebf7d0bcf274f1fcbef35999.1438610517.git.maitysanchayan@gmail.com>
 <BN3PR0301MB12191A12387C829F111B612BF5760@BN3PR0301MB1219.namprd03.prod.outlook.com>
Message-ID: <20150805080044.GB17211@Sanchayan-Arch.toradex.int>

Hello,

On 15-08-04 03:18:46, Duan Andy wrote:
> From: Sanchayan Maity <maitysanchayan at gmail.com> Sent: Monday, August 03, 2015 11:10 PM
> > To: jic23 at kernel.org; linux-iio at vger.kernel.org
> > Cc: stefan at agner.ch; Duan Fugang-B38611; hofrat at osadl.org;
> > sanjeev_sharma at mentor.com; Estevam Fabio-R49496; knaack.h at gmx.de;
> > lars at metafoo.de; pmeerw at pmeerw.net; antoine.tenart at free-electrons.com;
> > linux-kernel at vger.kernel.org; linux-arm-kernel at lists.infradead.org;
> > Sanchayan Maity
> > Subject: [PATCH] iio: adc: vf610: Add IIO buffer support for Vybrid ADC
> > 
> > This patch adds support for IIO buffer to the Vybrid ADC driver.
> > IIO triggered buffer infrastructure along with iio sysfs trigger is used
> > to leverage continuous sampling support provided by the ADC block.
> > 
> > Signed-off-by: Sanchayan Maity <maitysanchayan at gmail.com>
> > ---
> >  drivers/iio/adc/Kconfig     |   4 ++
> >  drivers/iio/adc/vf610_adc.c | 122
> > +++++++++++++++++++++++++++++++++++++++++---
> >  2 files changed, 120 insertions(+), 6 deletions(-)
> > 
> > diff --git a/drivers/iio/adc/Kconfig b/drivers/iio/adc/Kconfig index
> > 7c55658..4661241 100644
> > --- a/drivers/iio/adc/Kconfig
> > +++ b/drivers/iio/adc/Kconfig
> > @@ -337,6 +337,10 @@ config TWL6030_GPADC  config VF610_ADC
> >  	tristate "Freescale vf610 ADC driver"
> >  	depends on OF
> > +	select IIO_BUFFER
> > +	select IIO_TRIGGER
> > +	select IIO_SYSFS_TRIGGER
> > +	select IIO_TRIGGERED_BUFFER
> >  	help
> >  	  Say yes here to support for Vybrid board analog-to-digital
> > converter.
> >  	  Since the IP is used for i.MX6SLX, the driver also support
> > i.MX6SLX.
> > diff --git a/drivers/iio/adc/vf610_adc.c b/drivers/iio/adc/vf610_adc.c
> > index 23b8fb9..af72b9a 100644
> > --- a/drivers/iio/adc/vf610_adc.c
> > +++ b/drivers/iio/adc/vf610_adc.c
> > @@ -34,8 +34,11 @@
> >  #include <linux/err.h>
> > 
> >  #include <linux/iio/iio.h>
> > +#include <linux/iio/buffer.h>
> >  #include <linux/iio/sysfs.h>
> > -#include <linux/iio/driver.h>
> > +#include <linux/iio/trigger.h>
> > +#include <linux/iio/trigger_consumer.h> #include
> > +<linux/iio/triggered_buffer.h>
> > 
> >  /* This will be the driver name the kernel reports */  #define
> > DRIVER_NAME "vf610-adc"
> > @@ -170,6 +173,7 @@ struct vf610_adc {
> >  	u32 sample_freq_avail[5];
> > 
> >  	struct completion completion;
> > +	u16 *buffer;
> >  };
> > 
> >  static const u32 vf610_hw_avgs[] = { 1, 4, 8, 16, 32 }; @@ -505,12
> > +509,22 @@ static const struct iio_chan_spec_ext_info vf610_ext_info[] =
> > {
> >  	.info_mask_shared_by_type = BIT(IIO_CHAN_INFO_SCALE) |	\
> >  				BIT(IIO_CHAN_INFO_SAMP_FREQ),	\
> >  	.ext_info = vf610_ext_info,				\
> > +	.address = (_idx),				\
> > +	.scan_index = (_idx),			\
> > +	.scan_type.sign = 'u',			\
> > +	.scan_type.realbits = 12,		\
> > +	.scan_type.storagebits = 16,	\
> >  }
> > 
> >  #define VF610_ADC_TEMPERATURE_CHAN(_idx, _chan_type) {	\
> >  	.type = (_chan_type),	\
> >  	.channel = (_idx),		\
> >  	.info_mask_separate = BIT(IIO_CHAN_INFO_PROCESSED),	\
> > +	.address = (_idx),						\
> > +	.scan_index = (_idx),					\
> > +	.scan_type.sign = 'u',					\
> > +	.scan_type.realbits = 12,				\
> > +	.scan_type.storagebits = 16,			\
> >  }
> > 
> >  static const struct iio_chan_spec vf610_adc_iio_channels[] = { @@ -531,6
> > +545,7 @@ static const struct iio_chan_spec vf610_adc_iio_channels[] = {
> >  	VF610_ADC_CHAN(14, IIO_VOLTAGE),
> >  	VF610_ADC_CHAN(15, IIO_VOLTAGE),
> >  	VF610_ADC_TEMPERATURE_CHAN(26, IIO_TEMP),
> > +	IIO_CHAN_SOFT_TIMESTAMP(32),
> >  	/* sentinel */
> >  };
> > 
> > @@ -559,13 +574,21 @@ static int vf610_adc_read_data(struct vf610_adc
> > *info)
> > 
> >  static irqreturn_t vf610_adc_isr(int irq, void *dev_id)  {
> > -	struct vf610_adc *info = (struct vf610_adc *)dev_id;
> > +	struct iio_dev *indio_dev = (struct iio_dev *)dev_id;
> > +	struct vf610_adc *info = iio_priv(indio_dev);
> >  	int coco;
> > 
> >  	coco = readl(info->regs + VF610_REG_ADC_HS);
> >  	if (coco & VF610_ADC_HS_COCO0) {
> >  		info->value = vf610_adc_read_data(info);
> > -		complete(&info->completion);
> > +		if (iio_buffer_enabled(indio_dev)) {
> > +			info->buffer[0] = info->value;
> > +			writel(0, info->regs + VF610_REG_ADC_HS);
> The register is read only. After ADC_Rn is read, the coco bit is cleared.

Right. This crept in from a different implementation which I was trying with
PDB and perhaps a wrong interpretation of the TRM.

Will fix.

Regards,
Sanchayan.

(snip)


From rogerq at ti.com  Wed Aug  5 01:08:38 2015
From: rogerq at ti.com (Roger Quadros)
Date: Wed, 5 Aug 2015 11:08:38 +0300
Subject: [PATCH 10/10] ARM: dts: omap4: Use "syscon-otghs" instead of
 "ctrl-module" in USB node
In-Reply-To: <55C1C325.5040703@ti.com>
References: <1438702233-8027-1-git-send-email-kishon@ti.com>
 <1438702233-8027-11-git-send-email-kishon@ti.com> <55C1C325.5040703@ti.com>
Message-ID: <55C1C486.6050202@ti.com>

On 05/08/15 11:02, Roger Quadros wrote:
> Kishon,
> 
> On 04/08/15 18:30, Kishon Vijay Abraham I wrote:
>> Add "syscon-otghs" property and remove the deprecated "ctrl-module"
>> property from MUSB devicetree node.
>>
>> Since "omap_control_usbotg" devicetree node is no longer used, remove
>> it.
>>
>> Signed-off-by: Kishon Vijay Abraham I <kishon at ti.com>
>> ---
>>  arch/arm/boot/dts/omap4.dtsi |    8 +-------
>>  1 file changed, 1 insertion(+), 7 deletions(-)
>>
>> diff --git a/arch/arm/boot/dts/omap4.dtsi b/arch/arm/boot/dts/omap4.dtsi
>> index b27634d..2fb49a5 100644
>> --- a/arch/arm/boot/dts/omap4.dtsi
>> +++ b/arch/arm/boot/dts/omap4.dtsi
>> @@ -854,12 +854,6 @@
>>  			};
>>  		};
>>  
>> -		omap_control_usbotg: control-phy at 4a00233c {
>> -			compatible = "ti,control-phy-otghs";
>> -			reg = <0x4a00233c 0x4>;
>> -			reg-names = "otghs_control";
>> -		};
>> -
>>  		usb_otg_hs: usb_otg_hs at 4a0ab000 {
>>  			compatible = "ti,omap4-musb";
>>  			reg = <0x4a0ab000 0x7ff>;
>> @@ -872,7 +866,7 @@
>>  			multipoint = <1>;
>>  			num-eps = <16>;
>>  			ram-bits = <12>;
>> -			ctrl-module = <&omap_control_usbotg>;
>> +			syscon-otghs = <&scm_conf 0x33c>;
> 
> All other properties were of the format "syscon-phy-foo".
> Why use a different format here?
> 

Ah, looks like we don't have a dedicated phy driver for this?
We will need to add a PHY driver I guess then and handle this register
in that driver rather than in the musb driver.

cheers,
-roger
> 
> 
>>  		};
>>  
>>  		aes: aes at 4b501000 {
>>
> --
> To unsubscribe from this list: send the line "unsubscribe linux-omap" in
> the body of a message to majordomo at vger.kernel.org
> More majordomo info at  http://vger.kernel.org/majordomo-info.html
> 


From slash.tmp at free.fr  Wed Aug  5 01:40:01 2015
From: slash.tmp at free.fr (Mason)
Date: Wed, 05 Aug 2015 10:40:01 +0200
Subject: IRQ setup on multicore systems (routing, balancing, etc)
In-Reply-To: <55C0C102.7050600@free.fr>
References: <55C0C102.7050600@free.fr>
Message-ID: <55C1CBE1.1040009@free.fr>

On 04/08/2015 15:41, Mason wrote:

> I have a few very naive questions about interrupts.
> 
> How are interrupts set up on multicore systems?
> 
> If I write a device tree node for some peripheral, am I supposed
> to specify which core each interrupt should be routed to?
> 
> On my system, there is a custom interrupt controller, but the ARM
> chip also provides a Generic Interrupt Controller (GIC).
> 
> Am I supposed to use both, or can I use just the GIC?
> (I suspect the answer is very platform-dependent.)
> 
> I've seen a lot of articles discussing interrupt "management"
> on x86 (with APIC) but my search-foo is failing me for more
> generic Linux "Howto set up". Are there good references?
> 
> I suppose I should take a look at these?
> Documentation/devicetree/bindings/interrupt-controller/*
> Documentation/devicetree/bindings/arm/gic.txt
> 
> 
> For my own reference:
> 
> ARM Generic Interrupt Controller Architecture Specification v1.0 (IHI0048A)
> Cortex-A9 MPCore (Revision: r3p0) Technical Reference Manual

This thread seems relevant:

[RFC] ARM: Let GIC to route IRQs to any allowed CPUs
http://thread.gmane.org/gmane.linux.ports.arm.kernel/102251

Russell's answer particularly so:
http://article.gmane.org/gmane.linux.ports.arm.kernel/102289

On 2011-01-12, Russell King wrote:

> There's quite a bit of history behind interrupt balancing across CPU
> cores, and it's not a simple issue to get to grips with.
> 
> I believe the x86 kernel uses software to balance interrupts across the
> cores using an algorithm in the kernel.  This tries to distribute the
> interrupts between the cores.  When this was tried on ARM, although it
> moved interrupts around the cores, it was no better than having all
> interrupts routed to one core.
> 
> On x86 they now do away with their kernel algorithm, and instead run a
> boot-time utility (irqbalance) which does a one-time distribution of
> interrupts across the cores.  The idea is that it is more important to
> keep an interrupt handler running on the same core than it is to
> constantly switch it between the cores.
> 
> If a handler keeps switching between the cores, you have to migrate cache
> lines between the cores, which adds to the cache coherency traffic, and
> on x86 results in a reduction in performance.
> 
> So, with all that in mind, when I was sorting out the initial SMP merging,
> I tried out various algorithms for automatic interrupt distribution, and
> never got any of them to work satisfactorily.  In light of discussions with
> x86 folk, particularly Arjan van de Ven, I decided not to merge any of them
> and leave it as a matter for userspace policy to control how interrupts are
> distributed to the cores - just like the majority of x86 platforms now do.
> 
> AFAIK, there's nothing stopping anyone running 'irqbalance' (the x86
> utility) on ARM - it should just be accessing procfs files.  See
> http://irqbalance.org/ for more information on the program, and on the
> issues surrounding IRQ distribution in SMP systems.

Regards.



From Wenyou.Yang at atmel.com  Wed Aug  5 01:45:50 2015
From: Wenyou.Yang at atmel.com (Yang, Wenyou)
Date: Wed, 5 Aug 2015 08:45:50 +0000
Subject: [PATCH v2 1/2] drivers: watchdog: add a driver to support
 SAMA5D4 watchdog timer
In-Reply-To: <55C1A9C2.5070808@roeck-us.net>
References: <1438742130-2089-1-git-send-email-wenyou.yang@atmel.com>
 <1438742130-2089-2-git-send-email-wenyou.yang@atmel.com>
 <55C1A9C2.5070808@roeck-us.net>
Message-ID: <B256D81BAE5131468A838E5D7A243641C9F86B81@penmbx01>

Hi Guenter,

Thank you very much for your review.

I will send a new version to resolve them.

> -----Original Message-----
> From: Guenter Roeck [mailto:linux at roeck-us.net]
> Sent: 2015?8?5? 14:14
> To: Yang, Wenyou; wim at iguana.be; robh+dt at kernel.org; pawel.moll at arm.com;
> mark.rutland at arm.com; ijc+devicetree at hellion.org.uk; galak at codeaurora.org
> Cc: sylvain.rochet at finsecur.com; Ferre, Nicolas; boris.brezillon at free-
> electrons.com; devicetree at vger.kernel.org; linux-kernel at vger.kernel.org; linux-
> watchdog at vger.kernel.org; linux-arm-kernel at lists.infradead.org
> Subject: Re: [PATCH v2 1/2] drivers: watchdog: add a driver to support SAMA5D4
> watchdog timer
> 
> On 08/04/2015 07:35 PM, Wenyou Yang wrote:
> >>From SAMA5D4, the watchdog timer is upgrated with a new feature,
> > which is describled as in the datasheet, "WDT_MR can be written until
> > a LOCKMR command is issued in WDT_CR".
> > That is to say, as long as the bootstrap and u-boot don't issue a
> > LOCKMR command, WDT_MR can be written more than once in the driver.
> >
> > So the SAMA5D4 watchdog driver's implementation is different from the
> > previous: the user application open the device file to enable
> 
> Which previous ? Please let the reader know which one you refer to.
> 
> > the watchdog timer hardware, and close to disable it, and set the
> > watchdog timer timeout by seting WDV and WDD fields of WDT_MR
> > register, and ping the watchdog by issuing WDRSTT command to WDT_CR
> > register with hard-coded key.
> >
> > Signed-off-by: Wenyou Yang <wenyou.yang at atmel.com>
> > ---
> >   drivers/watchdog/Kconfig        |    9 ++
> >   drivers/watchdog/Makefile       |    1 +
> >   drivers/watchdog/at91sam9_wdt.h |    4 +
> >   drivers/watchdog/atmel_wdt.c    |  290
> +++++++++++++++++++++++++++++++++++++++
> >   4 files changed, 304 insertions(+)
> >   create mode 100644 drivers/watchdog/atmel_wdt.c
> >
> > diff --git a/drivers/watchdog/Kconfig b/drivers/watchdog/Kconfig index
> > e5e7c55..4425813 100644
> > --- a/drivers/watchdog/Kconfig
> > +++ b/drivers/watchdog/Kconfig
> > @@ -152,6 +152,15 @@ config ARM_SP805_WATCHDOG
> >   	  ARM Primecell SP805 Watchdog timer. This will reboot your system
> when
> >   	  the timeout is reached.
> >
> > +config ATMEL_WATCHDOG
> > +	tristate "Atmel SAMA5D4 Watchdog Timer"
> > +	depends on ARCH_AT91
> > +	select WATCHDOG_CORE
> > +	help
> > +	  Atmel watchdog timer embedded into SAMA5D4 chips. Its Watchdog
> Timer
> > +	  Mode Register(WDT_MR) can be written more than once.
> > +	  This will reboot your system when the timeout is reached.
> > +
> 
> ATMEL is highly generic. Can you find a more specific name ?
> If this is part of the AT91 family, it could be something like AT91SAMAD54, for
> example.
> 
> Same goes for the driver name.
> 
> >   config AT91RM9200_WATCHDOG
> >   	tristate "AT91RM9200 watchdog"
> >   	depends on SOC_AT91RM9200 && MFD_SYSCON diff --git
> > a/drivers/watchdog/Makefile b/drivers/watchdog/Makefile index
> > 5c19294..c24a8fc 100644
> > --- a/drivers/watchdog/Makefile
> > +++ b/drivers/watchdog/Makefile
> > @@ -30,6 +30,7 @@ obj-$(CONFIG_USBPCWATCHDOG) += pcwd_usb.o
> >
> >   # ARM Architecture
> >   obj-$(CONFIG_ARM_SP805_WATCHDOG) += sp805_wdt.o
> > +obj-$(CONFIG_ATMEL_WATCHDOG) += atmel_wdt.o
> >   obj-$(CONFIG_AT91RM9200_WATCHDOG) += at91rm9200_wdt.o
> >   obj-$(CONFIG_AT91SAM9X_WATCHDOG) += at91sam9_wdt.o
> >   obj-$(CONFIG_CADENCE_WATCHDOG) += cadence_wdt.o diff --git
> > a/drivers/watchdog/at91sam9_wdt.h b/drivers/watchdog/at91sam9_wdt.h
> > index c6fbb2e6..79add4f 100644
> > --- a/drivers/watchdog/at91sam9_wdt.h
> > +++ b/drivers/watchdog/at91sam9_wdt.h
> > @@ -22,11 +22,15 @@
> >
> >   #define AT91_WDT_MR		0x04			/* Watchdog
> Mode Register */
> >   #define		AT91_WDT_WDV		(0xfff << 0)		/*
> Counter Value */
> > +#define			AT91_WDT_WDV_MSK	(0xfff)
> 
> The ( ) is not necessary. AT91_WDT_WDV is already used as mask.
> You should not need a second one.
> 
> > +#define			AT91_WDT_WDV_(x)	(((x) &
> AT91_WDT_WDV_MSK) << 0)
> 
> Please no '_' at the end of the macro name; find another name that isn't as close to
> AT91_WDT_WDV.
> 
> >   #define		AT91_WDT_WDFIEN		(1     << 12)		/*
> Fault Interrupt Enable */
> >   #define		AT91_WDT_WDRSTEN	(1     << 13)		/*
> Reset Processor */
> >   #define		AT91_WDT_WDRPROC	(1     << 14)		/*
> Timer Restart */
> >   #define		AT91_WDT_WDDIS		(1     << 15)		/*
> Watchdog Disable */
> >   #define		AT91_WDT_WDD		(0xfff << 16)		/*
> Delta Value */
> > +#define			AT91_WDT_WDD_MSK	(0xfff)
> 
> ( ) is unnecessary. Also, AT91_WDT_WDD is already used as mask.
> No need to specify a second one.
> 
> > +#define			AT91_WDT_WDD_(x)	(((x) &
> AT91_WDT_WDD_MSK) << 16)
> 
> Again, please no '_' at the end of the macro name.
> 
> >   #define		AT91_WDT_WDDBGHLT	(1     << 28)		/*
> Debug Halt */
> >   #define		AT91_WDT_WDIDLEHLT	(1     << 29)		/*
> Idle Halt */
> >
> > diff --git a/drivers/watchdog/atmel_wdt.c
> > b/drivers/watchdog/atmel_wdt.c new file mode 100644 index
> > 0000000..e1cdc84
> > --- /dev/null
> > +++ b/drivers/watchdog/atmel_wdt.c
> > @@ -0,0 +1,290 @@
> > +/*
> > + * Driver for Atmel SAMA5D4 Watchdog Timer
> > + *
> > + * Copyright (C) 2015 Atmel Corporation
> > + *
> > + * Licensed under GPLv2.
> > + */
> > +
> > +#include <linux/kernel.h>
> > +#include <linux/module.h>
> > +#include <linux/interrupt.h>
> > +#include <linux/io.h>
> > +#include <linux/of.h>
> > +#include <linux/of_irq.h>
> > +#include <linux/platform_device.h>
> > +#include <linux/watchdog.h>
> > +#include <linux/reboot.h>
> 
> Please use alphabetic order for include files. That makes it easier to find files, and
> simplifies later additions.
> 
> > +
> > +#include "at91sam9_wdt.h"
> > +
> > +/* minimum and maximum watchdog timeout, in seconds */
> > +#define MIN_WDT_TIMEOUT		1
> > +#define MAX_WDT_TIMEOUT		16
> > +#define WDT_DEFAULT_TIMEOUT	MAX_WDT_TIMEOUT
> > +
> > +#define WDT_MAX_WDV		0xFFF
> > +
> > +#define WDT_SEC2TICKS(s)	((s) ? (((s) << 8) - 1) : 0)
> > +
> > +struct atmel_wdt {
> > +	struct watchdog_device	wdd;
> > +	void __iomem		*reg_base;
> > +	u32	config;
> > +};
> > +
> > +static int wdt_timeout = WDT_DEFAULT_TIMEOUT; static bool nowayout =
> > +WATCHDOG_NOWAYOUT;
> > +
> > +module_param(wdt_timeout, int, 0);
> > +MODULE_PARM_DESC(wdt_timeout,
> > +	"Watchdog wdt_timeout in seconds. (default = "
> > +	__MODULE_STRING(WDT_DEFAULT_TIMEOUT) ")");
> > +
> > +module_param(nowayout, bool, 0);
> > +MODULE_PARM_DESC(nowayout,
> > +	"Watchdog cannot be stopped once started (default="
> > +	__MODULE_STRING(WATCHDOG_NOWAYOUT) ")");
> > +
> > +#define wdt_read(wdt, field) \
> > +	readl_relaxed((wdt)->reg_base + (field))
> > +
> > +#define wdt_write(wtd, field, val) \
> > +	writel_relaxed((val), (wdt)->reg_base + (field))
> > +
> > +static int atmel_wdt_start(struct watchdog_device *wdd) {
> > +	struct atmel_wdt *wdt = watchdog_get_drvdata(wdd);
> > +	u32 reg;
> > +
> > +	reg = wdt_read(wdt, AT91_WDT_MR);
> > +	reg &= ~AT91_WDT_WDDIS;
> > +	wdt_write(wdt, AT91_WDT_MR, reg);
> > +
> > +	return 0;
> > +}
> > +
> > +static int atmel_wdt_stop(struct watchdog_device *wdd) {
> > +	struct atmel_wdt *wdt = watchdog_get_drvdata(wdd);
> > +	u32 reg;
> > +
> > +	reg = wdt_read(wdt, AT91_WDT_MR);
> > +	reg |= AT91_WDT_WDDIS;
> > +	wdt_write(wdt, AT91_WDT_MR, reg);
> > +
> > +	return 0;
> > +}
> > +
> > +static int atmel_wdt_ping(struct watchdog_device *wdd) {
> > +	struct atmel_wdt *wdt = watchdog_get_drvdata(wdd);
> > +
> > +	wdt_write(wdt, AT91_WDT_CR, AT91_WDT_KEY |
> AT91_WDT_WDRSTT);
> > +
> > +	return 0;
> > +}
> > +
> > +static int atmel_wdt_set_timeout(struct watchdog_device *wdd,
> > +				 unsigned int timeout)
> > +{
> > +	struct atmel_wdt *wdt = watchdog_get_drvdata(wdd);
> > +	u32 reg, value;
> > +
> > +	value = WDT_SEC2TICKS(timeout);
> > +	if (value > WDT_MAX_WDV)
> > +		return -EINVAL;
> > +
> Unnecessary check.
> 
> > +	reg = wdt_read(wdt, AT91_WDT_MR);
> > +	reg &= ~AT91_WDT_WDV;
> > +	reg &= ~AT91_WDT_WDD;
> > +	reg |= AT91_WDT_WDV_(value);
> > +	reg |= AT91_WDT_WDD_(value);
> > +	wdt_write(wdt, AT91_WDT_MR, reg);
> > +
> > +	wdd->timeout = timeout;
> > +
> > +	return 0;
> > +}
> > +
> > +static const struct watchdog_info atmel_wdt_info = {
> > +	.options = WDIOF_SETTIMEOUT | WDIOF_MAGICCLOSE |
> WDIOF_KEEPALIVEPING,
> > +	.firmware_version = 0,
> > +	.identity = "Atmel SAMA5D4 Watchdog", };
> > +
> > +static struct watchdog_ops atmel_wdt_ops = {
> > +	.owner = THIS_MODULE,
> > +	.start = atmel_wdt_start,
> > +	.stop = atmel_wdt_stop,
> > +	.ping = atmel_wdt_ping,
> > +	.set_timeout = atmel_wdt_set_timeout, };
> > +
> > +static irqreturn_t atmel_wdt_irq_handler(int irq, void *dev_id) {
> > +	struct atmel_wdt *wdt = platform_get_drvdata(dev_id);
> > +
> > +	if (wdt_read(wdt, AT91_WDT_SR)) {
> > +		pr_crit("Atmel Watchdog Software Reset\n");
> > +		emergency_restart();
> > +		pr_crit("Reboot didn't ?????\n");
> > +	}
> > +
> > +	return IRQ_HANDLED;
> > +}
> > +
> > +static int of_atmel_wdt_init(struct device_node *np, struct atmel_wdt
> > +*wdt) {
> > +	const char *tmp;
> > +
> > +	wdt->config = AT91_WDT_WDDIS;
> > +
> > +	if (!of_property_read_string(np, "atmel,watchdog-type", &tmp) &&
> > +	    !strcmp(tmp, "software"))
> > +		wdt->config |= AT91_WDT_WDFIEN;
> > +	else
> > +		wdt->config |= AT91_WDT_WDRSTEN;
> > +
> > +	if (of_property_read_bool(np, "atmel,idle-halt"))
> > +		wdt->config |= AT91_WDT_WDIDLEHLT;
> > +
> > +	if (of_property_read_bool(np, "atmel,dbg-halt"))
> > +		wdt->config |= AT91_WDT_WDDBGHLT;
> > +
> > +	return 0;
> > +}
> > +
> > +static int atmel_wdt_init(struct atmel_wdt *wdt) {
> > +	struct watchdog_device *wdd = &wdt->wdd;
> > +	u32 value, timeout;
> > +
> > +	timeout = WDT_SEC2TICKS(wdd->timeout);
> > +	if (timeout > WDT_MAX_WDV)
> > +		return -1;
> > +
> 
> Unnecessary range check.
> 
> > +	/*
> > +	 * Because the fields WDV and WDD must not be modified when the
> WDDIS
> > +	 * bit is set, so clear the WDDIS bit before writing the WDT_MR.
> > +	 */
> > +	value = wdt_read(wdt, AT91_WDT_MR);
> > +	value &= ~AT91_WDT_WDDIS;
> > +	wdt_write(wdt, AT91_WDT_MR, value);
> > +
> > +	value = wdt->config;
> > +	value |= AT91_WDT_WDD_(timeout);
> > +	value |= AT91_WDT_WDV_(timeout);
> > +
> > +	wdt_write(wdt, AT91_WDT_MR, value);
> > +
> > +	return 0;
> > +}
> > +
> > +static int atmel_wdt_probe(struct platform_device *pdev) {
> > +	struct watchdog_device *wdd;
> > +	struct atmel_wdt *wdt;
> > +	struct resource *res;
> > +	void __iomem *regs;
> > +	int ret, irq = -1;
> > +
> > +	wdt = devm_kzalloc(&pdev->dev, sizeof(*wdt), GFP_KERNEL);
> > +	if (!wdt)
> > +		return -ENOMEM;
> > +
> > +	wdd = &wdt->wdd;
> > +	wdd->timeout = wdt_timeout;
> > +	wdd->info = &atmel_wdt_info;
> > +	wdd->ops = &atmel_wdt_ops;
> > +	wdd->min_timeout = MIN_WDT_TIMEOUT;
> > +	wdd->max_timeout = MAX_WDT_TIMEOUT;
> > +
> > +	watchdog_set_drvdata(wdd, wdt);
> > +
> > +	res = platform_get_resource(pdev, IORESOURCE_MEM, 0);
> > +	regs = devm_ioremap_resource(&pdev->dev, res);
> > +	if (IS_ERR(regs))
> > +		return PTR_ERR(regs);
> > +
> > +	wdt->reg_base = regs;
> > +
> > +	if (pdev->dev.of_node) {
> > +		irq = irq_of_parse_and_map(pdev->dev.of_node, 0);
> > +		if (!irq)
> > +			dev_warn(&pdev->dev, "the IRQ NOT specify from DT\n");
> 
> "failed to get IRQ from DT" would be a better message.
> This leaves irq set to 0 in the error case, and cause the code below to request an
> interrupt.
> 
> > +
> > +		ret = of_atmel_wdt_init(pdev->dev.of_node, wdt);
> > +		if (ret)
> > +			return ret;
> > +	}
> > +
> > +	if ((wdt->config & AT91_WDT_WDFIEN) && (irq >= 0)) {
> 
> Second ( ) is unnecessary.
> 
> > +		ret = devm_request_irq(&pdev->dev, irq, atmel_wdt_irq_handler,
> > +				       0, pdev->name, pdev);
> > +		if (ret) {
> > +			dev_err(&pdev->dev,
> > +				"cannot register interrupt handler\n");
> > +			return ret;
> > +		}
> > +	}
> > +
> > +	ret = watchdog_init_timeout(wdd, wdt_timeout, &pdev->dev);
> > +	if (ret) {
> > +		dev_err(&pdev->dev, "unable to set timeout value\n");
> > +		return ret;
> 
> I would suggest to set the default timeout in this case, as done by other drivers.
> 
> > +	}
> > +
> > +	ret = atmel_wdt_init(wdt);
> > +	if (ret)
> > +		return ret;
> > +
> > +	watchdog_set_nowayout(wdd, nowayout);
> > +
> > +	ret = watchdog_register_device(wdd);
> > +	if (ret) {
> > +		dev_err(&pdev->dev, "failed to register watchdog device\n");
> > +		return ret;
> > +	}
> > +
> > +	platform_set_drvdata(pdev, wdt);
> > +
> > +	dev_info(&pdev->dev, "initialized (timeout = %d sec, nowayout = %d)\n",
> > +		 wdt_timeout, nowayout);
> > +
> > +	return 0;
> > +}
> > +
> > +static int atmel_wdt_remove(struct platform_device *pdev) {
> > +	struct atmel_wdt *wdt = platform_get_drvdata(pdev);
> > +
> > +	atmel_wdt_stop(&wdt->wdd);
> > +
> > +	watchdog_unregister_device(&wdt->wdd);
> > +
> > +	dev_info(&pdev->dev, "removed wdt\n");
> > +
> Unnecessary message.
> 
> > +	return 0;
> > +}
> > +
> > +static const struct of_device_id atmel_wdt_of_match[] = {
> > +	{ .compatible = "atmel,sama5d4-wdt", },
> > +	{ },
> > +};
> > +MODULE_DEVICE_TABLE(of, atmel_wdt_of_match);
> > +
> > +static struct platform_driver atmel_wdt_driver = {
> > +	.probe		= atmel_wdt_probe,
> > +	.remove		= atmel_wdt_remove,
> > +	.driver		= {
> > +		.name	= "atmel-wdt",
> > +		.of_match_table = atmel_wdt_of_match,
> > +	},
> > +};
> > +module_platform_driver(atmel_wdt_driver);
> > +
> > +MODULE_ALIAS("platform:atmel-wdt");
> > +MODULE_AUTHOR("Atmel Corporation");
> > +MODULE_DESCRIPTION("Atmel SAMA5D4 Watchdog Timer driver");
> > +MODULE_LICENSE("GPL v2");
> >

Best Regards,
Wenyou Yang

From vaibhav.hiremath at linaro.org  Wed Aug  5 01:45:59 2015
From: vaibhav.hiremath at linaro.org (Vaibhav Hiremath)
Date: Wed, 05 Aug 2015 14:15:59 +0530
Subject: [PATCH-v2 2/2] regulator: 88pm800: Add support for configuration
 of dual phase on BUCK1
In-Reply-To: <CAJKOXPcMd9VvfA48kaBa0BYeHAfHTu6MzAbQv0HuRy9wbgz0wg@mail.gmail.com>
References: <1437495782-15767-1-git-send-email-vaibhav.hiremath@linaro.org>	<1437495782-15767-3-git-send-email-vaibhav.hiremath@linaro.org>
 <CAJKOXPcMd9VvfA48kaBa0BYeHAfHTu6MzAbQv0HuRy9wbgz0wg@mail.gmail.com>
Message-ID: <55C1CD47.3060400@linaro.org>



On Thursday 23 July 2015 10:21 AM, Krzysztof Kozlowski wrote:
> 2015-07-22 1:23 GMT+09:00 Vaibhav Hiremath <vaibhav.hiremath at linaro.org>:
>> 88PM860 device supports dual phase mode on BUCK1 output.
>> In normal usecase, BUCK1A and BUCK1B operates independently with 3A
>> capacity. And they both can work as a dual phase providing 6A capacity.
>>
>> This patch updates the regulator driver to read the respective
>> DT property and enable dual-phase mode on BUCK1.
>>
>> Note that, this is init time (one time) initialization.
>>

Sorry for delayed response, was on bed rest almost for week.

>> Signed-off-by: Vaibhav Hiremath <vaibhav.hiremath at linaro.org>
>> ---
>>   drivers/regulator/88pm800.c | 31 +++++++++++++++++++++++++++++++
>>   include/linux/mfd/88pm80x.h |  3 +++
>>   2 files changed, 34 insertions(+)
>
> Don't you need to update the constraints also? I think the BUCK1
> regulator has fixed constraint of 3 A:
>    PM800_BUCK(buck1, BUCK1, BUCK_ENA, 0, 3000000, buck1_volt_range, 0x55),
> and now it can handle 6 A.
>

Actually, BUCK1A and BUCK1B both combined together provide 6A capacity.
And as discussed earlier, we need board change for this.

I am quite not sure.

Should I read the property and update the constraint runtime during
probe?


>>
>> diff --git a/drivers/regulator/88pm800.c b/drivers/regulator/88pm800.c
>> index e846e4c..1bf2b35 100644
>> --- a/drivers/regulator/88pm800.c
>> +++ b/drivers/regulator/88pm800.c
>> @@ -267,6 +267,31 @@ static struct pm800_regulator_info pm860_regulator_info[] = {
>>          PM800_LDO(ldo20, LDO20, LDO_ENA1_3, 3, 10000, ldo_volt_table2),
>>   };
>>
>> +static int pm800_regulator_init(struct platform_device *pdev)
>> +{
>> +       struct pm800_regulators *pm800_data = platform_get_drvdata(pdev);
>> +       struct pm80x_chip *chip = pm800_data->chip;
>> +       int ret;
>
> 'ret' is used only in if statement below. I don't have strong feelings
> but can you move it there to limit its scope or always return 'ret'
> (after initializing to '0'). To me this would be more readable.
>

OK, will fix in V3.

I will wait to close on constraint discussion above.

Thanks,
Vaibhav

> Best regards,
> Krzysztof
>
>> +
>> +       /* Currently only supported on 88pm860 device */
>> +       if (chip->type != CHIP_PM860)
>> +               return 0;
>> +
>> +       if (of_property_read_bool(pdev->dev.of_node,
>> +                               "marvell,88pm860-buck1-dualphase-en")) {
>> +               ret = regmap_update_bits(chip->subchip->regmap_power,
>> +                                       PM860_BUCK1_MISC,
>> +                                       BUCK1_DUAL_PHASE_SEL,
>> +                                       BUCK1_DUAL_PHASE_SEL);
>> +               if (ret) {
>> +                       dev_err(chip->dev, "failed to set dual-pase mode %d\n", ret);
>> +                       return ret;
>> +               }
>> +       }
>> +
>> +       return 0;
>> +}
>> +
>>   static int pm800_regulator_probe(struct platform_device *pdev)
>>   {
>>          struct pm80x_chip *chip = dev_get_drvdata(pdev->dev.parent);
>> @@ -336,6 +361,12 @@ static int pm800_regulator_probe(struct platform_device *pdev)
>>                  }
>>          }
>>
>> +       ret = pm800_regulator_init(pdev);
>> +       if (ret) {
>> +               dev_err(&pdev->dev, "failed to init 88pm800 regulator device\n");
>> +               return ret;
>> +       }
>> +
>>          return 0;
>>   }
>>
>> diff --git a/include/linux/mfd/88pm80x.h b/include/linux/mfd/88pm80x.h
>> index a92d173..05d9bad 100644
>> --- a/include/linux/mfd/88pm80x.h
>> +++ b/include/linux/mfd/88pm80x.h
>> @@ -295,6 +295,9 @@ enum {
>>   #define PM860_BUCK4_MISC2              (0x82)
>>   #define PM860_BUCK4_FULL_DRV           BIT(2)
>>
>> +#define PM860_BUCK1_MISC               (0x8E)
>> +#define BUCK1_DUAL_PHASE_SEL           BIT(2)
>> +
>>   struct pm80x_rtc_pdata {
>>          int             vrtc;
>>          int             rtc_wakeup;
>> --
>> 1.9.1
>>
>>
>> _______________________________________________
>> linux-arm-kernel mailing list
>> linux-arm-kernel at lists.infradead.org
>> http://lists.infradead.org/mailman/listinfo/linux-arm-kernel


From vaibhav.hiremath at linaro.org  Wed Aug  5 01:47:53 2015
From: vaibhav.hiremath at linaro.org (Vaibhav Hiremath)
Date: Wed, 05 Aug 2015 14:17:53 +0530
Subject: [PATCH-v2 2/2] regulator: 88pm800: Add support for configuration
 of dual phase on BUCK1
In-Reply-To: <20150723155432.GV3436@x1>
References: <1437495782-15767-1-git-send-email-vaibhav.hiremath@linaro.org>
 <1437495782-15767-3-git-send-email-vaibhav.hiremath@linaro.org>
 <20150723155432.GV3436@x1>
Message-ID: <55C1CDB9.5010106@linaro.org>



On Thursday 23 July 2015 09:24 PM, Lee Jones wrote:
> On Tue, 21 Jul 2015, Vaibhav Hiremath wrote:
>
>> 88PM860 device supports dual phase mode on BUCK1 output.
>> In normal usecase, BUCK1A and BUCK1B operates independently with 3A
>> capacity. And they both can work as a dual phase providing 6A capacity.
>>
>> This patch updates the regulator driver to read the respective
>> DT property and enable dual-phase mode on BUCK1.
>>
>> Note that, this is init time (one time) initialization.
>>
>> Signed-off-by: Vaibhav Hiremath <vaibhav.hiremath at linaro.org>
>> ---
>>   drivers/regulator/88pm800.c | 31 +++++++++++++++++++++++++++++++
>>   include/linux/mfd/88pm80x.h |  3 +++
>>   2 files changed, 34 insertions(+)
>
> [...]
>
>> diff --git a/include/linux/mfd/88pm80x.h b/include/linux/mfd/88pm80x.h
>> index a92d173..05d9bad 100644
>> --- a/include/linux/mfd/88pm80x.h
>> +++ b/include/linux/mfd/88pm80x.h
>> @@ -295,6 +295,9 @@ enum {
>>   #define PM860_BUCK4_MISC2		(0x82)
>>   #define PM860_BUCK4_FULL_DRV		BIT(2)
>>
>> +#define PM860_BUCK1_MISC		(0x8E)
>
> Why the over-bracketing?
>

No specific reason, just wanted to be consistent with other definitions
in the file.

Anyway, will remove it in V3.

Thanks,
Vaibhav


From vaibhav.hiremath at linaro.org  Wed Aug  5 01:49:05 2015
From: vaibhav.hiremath at linaro.org (Vaibhav Hiremath)
Date: Wed, 05 Aug 2015 14:19:05 +0530
Subject: [PATCH-v2 1/2] mfd: devicetree: bindings: 88pm800: Add DT property
 for dual phase enable
In-Reply-To: <20150723155322.GU3436@x1>
References: <1437495782-15767-1-git-send-email-vaibhav.hiremath@linaro.org>
 <1437495782-15767-2-git-send-email-vaibhav.hiremath@linaro.org>
 <20150723155322.GU3436@x1>
Message-ID: <55C1CE01.7030607@linaro.org>



On Thursday 23 July 2015 09:23 PM, Lee Jones wrote:
> On Tue, 21 Jul 2015, Vaibhav Hiremath wrote:
>
>> 88PM860 family of device supports dual phase mode on BUCK1 supply
>> providing total 6A capacity.
>> Note that by default they operate independently with 3A capacity.
>>
>> This patch updates the devicetree binding with DT property
>> to enable dual-phase mode on BUCK1.
>>
>> Signed-off-by: Vaibhav Hiremath <vaibhav.hiremath at linaro.org>
>> ---
>>   Documentation/devicetree/bindings/mfd/88pm800.txt | 6 ++++++
>>   1 file changed, 6 insertions(+)
>>
>> diff --git a/Documentation/devicetree/bindings/mfd/88pm800.txt b/Documentation/devicetree/bindings/mfd/88pm800.txt
>> index dec842f..2c82fcb 100644
>> --- a/Documentation/devicetree/bindings/mfd/88pm800.txt
>> +++ b/Documentation/devicetree/bindings/mfd/88pm800.txt
>> @@ -9,6 +9,12 @@ Required parent device properties:
>>   - #interrupt-cells 	: should be 1.
>>   			  The cell is the 88pm80x local IRQ number
>>
>> +Optional properties :
>> +- marvell,88pm860-buck1-dualphase-en  : If set, enable dual phase on BUCK1,
>> +  providing 6A capacity.
>> +  Without this both BUCK1A and BUCK1B operates independently with 3A capacity.
>> +  (This property is only applicable to 88PM860)
>
> You need to get Mark Brown to Ack this.
>

Mark,

Ay update on this patch?

Thanks,
Vaibhav


From wsa at the-dreams.de  Wed Aug  5 01:49:18 2015
From: wsa at the-dreams.de (Wolfram Sang)
Date: Wed, 5 Aug 2015 10:49:18 +0200
Subject: [PATCH-v5 1/5] Documentation: binding: add new property
 'disable_after_xfer' to i2c-pxa
In-Reply-To: <55C1AE71.3010700@linaro.org>
References: <1437482466-16126-1-git-send-email-vaibhav.hiremath@linaro.org>
 <1437482466-16126-2-git-send-email-vaibhav.hiremath@linaro.org>
 <20150727140911.GB15004@beef> <55C1AE71.3010700@linaro.org>
Message-ID: <20150805084917.GA1523@katana>


> Yeah, we could start i2c.txt, probably better to have separate new
> patch all together.

I will start such a file today as part of the i2c slave framework
update which introduces flags to the reg property. Will post to the i2c
list this week.

-------------- next part --------------
A non-text attachment was scrubbed...
Name: signature.asc
Type: application/pgp-signature
Size: 819 bytes
Desc: Digital signature
URL: <http://lists.infradead.org/pipermail/linux-arm-kernel/attachments/20150805/6af38758/attachment.sig>

From s.hauer at pengutronix.de  Wed Aug  5 01:50:34 2015
From: s.hauer at pengutronix.de (Sascha Hauer)
Date: Wed, 5 Aug 2015 10:50:34 +0200
Subject: [PATCH v3 3/8] soc: Mediatek: Add SCPSYS CPU power domain driver
In-Reply-To: <1438696464-59858-4-git-send-email-scott.shu@mediatek.com>
References: <1438696464-59858-1-git-send-email-scott.shu@mediatek.com>
 <1438696464-59858-4-git-send-email-scott.shu@mediatek.com>
Message-ID: <20150805085034.GG18700@pengutronix.de>

On Tue, Aug 04, 2015 at 09:54:19PM +0800, Scott Shu wrote:
> This adds a CPU power domain driver for the Mediatek SCPSYS unit on
> MT6580.
> 
> Signed-off-by: Scott Shu <scott.shu at mediatek.com>
> ---
>  drivers/soc/mediatek/mtk-scpsys.c   |  250 +++++++++++++++++++++++++++++++++++
>  include/linux/soc/mediatek/scpsys.h |    9 ++
>  2 files changed, 259 insertions(+)
>  create mode 100644 include/linux/soc/mediatek/scpsys.h
> 
> diff --git a/drivers/soc/mediatek/mtk-scpsys.c b/drivers/soc/mediatek/mtk-scpsys.c
> index 43a79ed..ca0f2dd 100644
> --- a/drivers/soc/mediatek/mtk-scpsys.c
> +++ b/drivers/soc/mediatek/mtk-scpsys.c
> @@ -15,18 +15,30 @@
>  #include <linux/io.h>
>  #include <linux/kernel.h>
>  #include <linux/mfd/syscon.h>
> +#include <linux/of.h>
>  #include <linux/of_device.h>
> +#include <linux/of_address.h>
>  #include <linux/platform_device.h>
>  #include <linux/pm_domain.h>
>  #include <linux/regmap.h>
>  #include <linux/soc/mediatek/infracfg.h>
> +#include <linux/soc/mediatek/scpsys.h>
>  #include <dt-bindings/power/mt8173-power.h>
>  
> +#define SPM_POWERON_CONFIG_SET		0x0000
> +#define SPM_CA7_CPU0_PWR_CON		0x0200
>  #define SPM_VDE_PWR_CON			0x0210
>  #define SPM_MFG_PWR_CON			0x0214
> +#define SPM_CA7_CPU1_PWR_CON		0x0218
> +#define SPM_CA7_CPU2_PWR_CON		0x021c
> +#define SPM_CA7_CPU3_PWR_CON		0x0220
>  #define SPM_VEN_PWR_CON			0x0230
>  #define SPM_ISP_PWR_CON			0x0238
>  #define SPM_DIS_PWR_CON			0x023c
> +#define SPM_CA7_CPU0_L1_PDN		0x025c
> +#define SPM_CA7_CPU1_L1_PDN		0x0264
> +#define SPM_CA7_CPU2_L1_PDN		0x026c
> +#define SPM_CA7_CPU3_L1_PDN		0x0274
>  #define SPM_VEN2_PWR_CON		0x0298
>  #define SPM_AUDIO_PWR_CON		0x029c
>  #define SPM_MFG_2D_PWR_CON		0x02c0
> @@ -34,12 +46,20 @@
>  #define SPM_USB_PWR_CON			0x02cc
>  #define SPM_PWR_STATUS			0x060c
>  #define SPM_PWR_STATUS_2ND		0x0610
> +#define SPM_SLEEP_TIMER_STA		0x0720
>  
> +/* bit definition in SPM_CA7_CPUx_PWR_CON */
>  #define PWR_RST_B_BIT			BIT(0)
>  #define PWR_ISO_BIT			BIT(1)
>  #define PWR_ON_BIT			BIT(2)
>  #define PWR_ON_2ND_BIT			BIT(3)
>  #define PWR_CLK_DIS_BIT			BIT(4)
> +#define SRAM_CKISO_BIT			BIT(5)
> +#define SRAM_ISOINT_B_BIT		BIT(6)
> +
> +/* bit definition in SPM_CA7_CPUx_L1_PDN */
> +#define L1_PDN				BIT(0)
> +#define L1_PDN_ACK			BIT(8)
>  
>  #define PWR_STATUS_DISP			BIT(3)
>  #define PWR_STATUS_MFG			BIT(4)
> @@ -52,6 +72,28 @@
>  #define PWR_STATUS_AUDIO		BIT(24)
>  #define PWR_STATUS_USB			BIT(25)
>  
> +#define MT6580_MAX_CPUS			4
> +
> +#ifdef CONFIG_SMP
> +static DEFINE_SPINLOCK(spm_cpu_lock);
> +
> +static void __iomem *spm_cpu_base;
> +
> +static const u32 spm_cpu_pwr_con[MT6580_MAX_CPUS] = {
> +	SPM_CA7_CPU0_PWR_CON,
> +	SPM_CA7_CPU1_PWR_CON,
> +	SPM_CA7_CPU2_PWR_CON,
> +	SPM_CA7_CPU3_PWR_CON,
> +};
> +
> +static const u32 spm_cpu_l1_pdn[MT6580_MAX_CPUS] = {
> +	SPM_CA7_CPU0_L1_PDN,
> +	SPM_CA7_CPU1_L1_PDN,
> +	SPM_CA7_CPU2_L1_PDN,
> +	SPM_CA7_CPU3_L1_PDN,
> +};
> +#endif
> +
>  enum clk_id {
>  	MT8173_CLK_MM,
>  	MT8173_CLK_MFG,
> @@ -485,3 +527,211 @@ static struct platform_driver scpsys_drv = {
>  };
>  
>  module_platform_driver_probe(scpsys_drv, scpsys_probe);
> +
> +#define SPM_REGWR_EN		BIT(0)
> +#define SPM_PROJECT_CODE	0x0B16
> +
> +#ifdef CONFIG_SMP
> +int spm_cpu_mtcmos_on(int cpu)

The idea was that the code that the current driver has in
scpsys_power_on/scpsys_power_off is shared with this function. If we
don't do this then it indeed doesn't make much sense to put it into the
same file.

>From what I see we would need to change the prototype to something like

static int __scpsys_power_on(struct scp_domain_data *)

(maybe with some additional base addresses and stuff)

struct scp_domain_data would additionally need sram_isoint_b and sram_ckiso
members.

Sascha

-- 
Pengutronix e.K.                           |                             |
Industrial Linux Solutions                 | http://www.pengutronix.de/  |
Peiner Str. 6-8, 31137 Hildesheim, Germany | Phone: +49-5121-206917-0    |
Amtsgericht Hildesheim, HRA 2686           | Fax:   +49-5121-206917-5555 |


From alexandre.belloni at free-electrons.com  Wed Aug  5 01:50:44 2015
From: alexandre.belloni at free-electrons.com (Alexandre Belloni)
Date: Wed, 5 Aug 2015 10:50:44 +0200
Subject: [PATCH v3 2/2] doc: dt: add documentation for nxp,lpc1788-rtc
In-Reply-To: <20150727133720.GA15004@beef>
References: <1436635730-15617-1-git-send-email-manabian@gmail.com>
 <1436635730-15617-3-git-send-email-manabian@gmail.com>
 <20150727133720.GA15004@beef>
Message-ID: <20150805085044.GC3486@piout.net>

Hi,

On 27/07/2015 at 09:37:20 -0400, Matt Porter wrote :
> > +Required properties:
> > +- compatible	: must contain "nxp,lpc1788-rtc"
> > +- reg		: Specifies base physical address and size of the registers.
> > +- interrupts	: A single interrupt specifier.
> > +- clocks	: Must contain entries for rtc and register clock
> 
> "Must contain clock specifiers for rtc and register clock" ?
> 

I fixed it up in the patch.

-- 
Alexandre Belloni, Free Electrons
Embedded Linux, Kernel and Android engineering
http://free-electrons.com


From vaibhav.hiremath at linaro.org  Wed Aug  5 01:51:26 2015
From: vaibhav.hiremath at linaro.org (Vaibhav Hiremath)
Date: Wed, 05 Aug 2015 14:21:26 +0530
Subject: [PATCH-v5 5/5] i2c: pxa: Add ILCR (tLow & tHigh) configuration
 support
In-Reply-To: <1437482466-16126-6-git-send-email-vaibhav.hiremath@linaro.org>
References: <1437482466-16126-1-git-send-email-vaibhav.hiremath@linaro.org>
 <1437482466-16126-6-git-send-email-vaibhav.hiremath@linaro.org>
Message-ID: <55C1CE8E.9000601@linaro.org>



On Tuesday 21 July 2015 06:11 PM, Vaibhav Hiremath wrote:
> With addition of PXA910 family of devices, the TWSI module supports
> SCL clock adjustment using ILCR register.
>
> This patch enables the control and configuration of ICLR through DT
> properties,
>
> i2c-sclk-high-time-ns:
>    SCLK high time (tHigh), for standard/fast/high speed mode
> i2c-sclk-low-time-ns:
>    SCLK low time (tLow), for standard/fast/high speed mode
>
> Note that in case of standard and fast mod, the tLow and tHigh counters
> are same, and software will use tLow value.
>
> Also, brought up devm_clk_get() fn above i2c_pxa_probe_dt(), as it
> uses clk rate for timing calculations.
>
> Signed-off-by: Vaibhav Hiremath <vaibhav.hiremath at linaro.org>
> Signed-off-by: Jett.Zhou <jtzhou at marvell.com>
> Signed-off-by: Yi Zhang <yizhang at marvell.com>
> ---
>   drivers/i2c/busses/i2c-pxa.c | 69 ++++++++++++++++++++++++++++++++++++++++----
>   1 file changed, 63 insertions(+), 6 deletions(-)
>

Robert,

It would be helpful if you can test this patch-series and confirm that
it now fixes the NULL pointer deference issue.

Thanks,
Vaibhav


From vaibhav.hiremath at linaro.org  Wed Aug  5 01:53:32 2015
From: vaibhav.hiremath at linaro.org (Vaibhav Hiremath)
Date: Wed, 05 Aug 2015 14:23:32 +0530
Subject: [PATCH 1/4] mfd: 88pm800: Update the header file with 32K clk
 related macros
In-Reply-To: <20150723155233.GT3436@x1>
References: <1437476823-3358-1-git-send-email-vaibhav.hiremath@linaro.org>
 <1437476823-3358-2-git-send-email-vaibhav.hiremath@linaro.org>
 <20150723155233.GT3436@x1>
Message-ID: <55C1CF0C.1010805@linaro.org>



On Thursday 23 July 2015 09:22 PM, Lee Jones wrote:
> On Tue, 21 Jul 2015, Vaibhav Hiremath wrote:
>
>> Update header file with required macros for 32KHz buffered clock
>> output of 88PM800 family of device.
>> These macros will be used in clk provider driver.
>>
>> Signed-off-by: Vaibhav Hiremath <vaibhav.hiremath at linaro.org>
>> ---
>>   include/linux/mfd/88pm80x.h | 12 ++++++++++++
>>   1 file changed, 12 insertions(+)
>>
>> diff --git a/include/linux/mfd/88pm80x.h b/include/linux/mfd/88pm80x.h
>> index 05d9bad..680e4eb 100644
>> --- a/include/linux/mfd/88pm80x.h
>> +++ b/include/linux/mfd/88pm80x.h
>> @@ -91,6 +91,7 @@ enum {
>>   /* Referance and low power registers */
>>   #define PM800_LOW_POWER1		(0x20)
>>   #define PM800_LOW_POWER2		(0x21)
>> +#define PM800_LOW_POWER2_XO_LJ_EN	BIT(5)
>>
>>   #define PM800_LOW_POWER_CONFIG3		(0x22)
>>   #define PM800_LDOBK_FREEZE		BIT(7)
>> @@ -138,6 +139,13 @@ enum {
>>   #define PM800_ALARM			BIT(5)
>>   #define PM800_RTC1_USE_XO		BIT(7)
>>
>> +#define PM800_32K_OUTX_SEL_MASK		(0x3)
>> +/* 32KHz clk output sel mode */
>> +#define PM800_32K_OUTX_SEL_ZERO		(0x0)
>> +#define PM800_32K_OUTX_SEL_INT_32KHZ	(0x1)
>> +#define PM800_32K_OUTX_SEL_XO_32KHZ	(0x2)
>> +#define PM800_32K_OUTX_SEL_HIZ		(0x3)
>
> Why do these need to be in brackets?
>

No specific reason, just made it consistent with other definitions in
the file.

I will fix in V2.

Thanks,
Vaibhav


From geert+renesas at glider.be  Wed Aug  5 01:58:04 2015
From: geert+renesas at glider.be (Geert Uytterhoeven)
Date: Wed,  5 Aug 2015 10:58:04 +0200
Subject: [PATCH v4 0/6] ARM: shmobile: r8a7740/sh73a0 DT Cache Handling
Message-ID: <1438765090-823-1-git-send-email-geert+renesas@glider.be>

	Hi Simon, Magnus,

This patch series add L1 and L2 cache descriptions to DT for r8a7740 and
sh73a0, and migrates the shmobile DT-based generic r8a7740 and
armadillo legacy platforms from calling l2x0_of_init() to the generic
l2c OF initialization.

Note that the conversion to the generic l2c OF initialization is not
done yet for sh73a0, as this initializes the L2 cache earlier, breaking
the (fragile) sh73a0 secondary CPU bringup code.

Also note that this conversion should be done on r8a7778, and r8a7779,
too.

Changes compared to v3 ("[PATCH v3 0/6] ARM: l2c / shmobile: r8a7740 : Shared
Override",
http://lists.infradead.org/pipermail/linux-arm-kernel/2015-May/340636.html):
  - "l2c: Add support for the "arm,shared-override" property" was split
    off into an independent patch, and is now queued for v4.3 in
    arm/for-next,
  - Dropped armadillo legacy migration, as it no longer exists,
  - Added sh73a0 L1 and L2 DT cache description.

Changes compared to v2 ("[PATCH v2 0/5] ARM: shmobile: r8a7740/armadillo:
Migrate to generic l2c OF",
http://www.spinics.net/lists/devicetree/msg68176.html):
  - Add DT support for Shared Override,
  - Setting Shared Override is done only if CMA is not available (as
    Russell claims it's not needed if CMA is available),
  - Use 0/~0 in machine_desc.l2c_aux_{val,mask}, as DT now supports
    "arm,shared-override".

Changes compared to v1:
  - Fix interrupt reference in DT,
  - Describe L2 better in DT,
  - Keep only {,~}L2C_AUX_CTRL_SHARED_OVERRIDE in
    machine_desc.l2c_aux_{val,mask}, as there's no DT property for
    this.
  - Add L1 cache to DT.

Dependencies:
  - This series applies to renesas-devel-20150805-v4.2-rc5,
  - Patch 2 depends on patch 1,
  - Patch 4 depends on patch 2,
  - Patch 5 depends on patch 1 and on "ARM: 8395/1: l2c: Add support for
    the "arm,shared-override" property" in arm/for-next,
  - Patch 6 depends on patch 5.

Given C code patches depending on DT patches in the same branch are
frowned upon, I think it would be best if patch 1 (and patch 3, if
anyone thinks we may fix the secondary CPU bringup issue during the next
3 months) are queued for v4.3. The other patches can be queued for
2016^H^H^H^Hv4.4.

I've been running this on r8a7740/armadillo and sh73a0/kzm9g during the
past 9 months.

Thanks!

Geert Uytterhoeven (6):
  ARM: shmobile: r8a7740 dtsi: Add L2 cache-controller node
  ARM: shmobile: r8a7740 dtsi: Add L1 cache information to CPU node
  ARM: shmobile: sh73a0 dtsi: Add L2 cache-controller node
  ARM: shmobile: sh73a0 dtsi: Add L1 cache information to CPU nodes
  ARM: shmobile: r8a7740: Migrate to generic l2c OF initialization
  ARM: shmobile: r8a7740: Remove mapping of L2 cache controller
    registers

 arch/arm/boot/dts/r8a7740.dtsi         | 25 +++++++++++++++++++++++++
 arch/arm/boot/dts/sh73a0.dtsi          | 34 ++++++++++++++++++++++++++++++++++
 arch/arm/mach-shmobile/setup-r8a7740.c | 18 ++----------------
 3 files changed, 61 insertions(+), 16 deletions(-)

-- 
1.9.1

Gr{oetje,eeting}s,

						Geert

--
Geert Uytterhoeven -- There's lots of Linux beyond ia32 -- geert at linux-m68k.org

In personal conversations with technical people, I call myself a hacker. But
when I'm talking to journalists I just say "programmer" or something like that.
							    -- Linus Torvalds


From maitysanchayan at gmail.com  Wed Aug  5 01:55:48 2015
From: maitysanchayan at gmail.com (Sanchayan Maity)
Date: Wed,  5 Aug 2015 14:25:48 +0530
Subject: [PATCH v3 0/3] Add support for touchscreen on Colibri VF50
Message-ID: <cover.1438763030.git.maitysanchayan@gmail.com>

Hello,

The patchset adds support for 4 wire touchscreen on Toradex Colibri
VF50 modules. Patches are tested on top of shawn's for-next branch.

Changes since v2:
1. Fix pin multiplexing for pins in idle state. Configuration of the
pen detect pull up viz. PTA19__GPIO_9 resulted in generation of pen
irq's on a continuous basis.
2. Fix pinmux of the ADC pins as per the recommended pinmux in TRM.
3. Use a threaded irq handler instead of a irq handler plus workqueue
approach.
4. Use a low level trigger with oneshot flag specifier instead of the
previous falling edge triggered irq's. This coupled with the fix in
point 1 fixes the previous continuous spurious irq generation bug.
5. Change/fix the TS measurement logic to account for the fact that
iio_channel_read_raw might actually return an error. To be more
specific use break instead of continue and take care to close the
FET's in case of channel read error.
6. Drop the first patch "Add io-channel-cells property for ADC node"
as it has already been applied.
7. Move the iio channel get call again at the start. Having it in
the end resulted in crashes sometimes when iio was not probed and
the ts device got probed and opened earlier.

Changes since v1:
1. Fix/drop comments
2. Use an inline function for multiple gpiod_get calls in probe
3. Remove the pull up in the pinmux specified in DT for touchctrl_gpios
4. Add the io-channel-cells property before status property.
5. Add GPIOLIB as dependency in the Kconfig file

Version 2 of the patchset can be found here
https://www.mail-archive.com/linux-input at vger.kernel.org/msg18090.html

Version 1 of the patchset can be found here
https://lkml.org/lkml/2015/6/30/103

Thank you very much for the feedback till now.

Regards,
Sanchayan.

Sanchayan Maity (3):
  ARM: dts: vf500-colibri: Add device tree node for touchscreen support
  input: Add DT binding documentation for Colibri VF50 touchscreen
  touchscreen: colibri-vf50-ts: Add touchscreen support for Colibri VF50

 .../bindings/input/touchscreen/colibri-vf50-ts.txt |  32 ++
 arch/arm/boot/dts/vf500-colibri-eval-v3.dts        |   4 +
 arch/arm/boot/dts/vf500-colibri.dtsi               |  45 +++
 drivers/input/touchscreen/Kconfig                  |  12 +
 drivers/input/touchscreen/Makefile                 |   1 +
 drivers/input/touchscreen/colibri-vf50-ts.c        | 404 +++++++++++++++++++++
 6 files changed, 498 insertions(+)
 create mode 100644 Documentation/devicetree/bindings/input/touchscreen/colibri-vf50-ts.txt
 create mode 100644 drivers/input/touchscreen/colibri-vf50-ts.c

-- 
2.5.0



From maitysanchayan at gmail.com  Wed Aug  5 01:55:49 2015
From: maitysanchayan at gmail.com (Sanchayan Maity)
Date: Wed,  5 Aug 2015 14:25:49 +0530
Subject: [PATCH v3 1/3] ARM: dts: vf500-colibri: Add device tree node for
 touchscreen support
In-Reply-To: <cover.1438763030.git.maitysanchayan@gmail.com>
References: <cover.1438763030.git.maitysanchayan@gmail.com>
Message-ID: <e9d1b665cd52473b973d07f90f96bf8d53ab19aa.1438763030.git.maitysanchayan@gmail.com>

Add device tree node for touchscreen support on Colibri VF50. The
touchscreen functionality on VF50 uses the ADC channels of Vybrid
and some GPIOs. Also add pinctrl nodes for proper pinmux.

Signed-off-by: Sanchayan Maity <maitysanchayan at gmail.com>
---
 arch/arm/boot/dts/vf500-colibri-eval-v3.dts |  4 +++
 arch/arm/boot/dts/vf500-colibri.dtsi        | 45 +++++++++++++++++++++++++++++
 2 files changed, 49 insertions(+)

diff --git a/arch/arm/boot/dts/vf500-colibri-eval-v3.dts b/arch/arm/boot/dts/vf500-colibri-eval-v3.dts
index 7fc782c..14c0b00 100644
--- a/arch/arm/boot/dts/vf500-colibri-eval-v3.dts
+++ b/arch/arm/boot/dts/vf500-colibri-eval-v3.dts
@@ -15,3 +15,7 @@
 	model = "Toradex Colibri VF50 on Colibri Evaluation Board";
 	compatible = "toradex,vf500-colibri_vf50-on-eval", "toradex,vf500-colibri_vf50", "fsl,vf500";
 };
+
+&touchscreen {
+	status = "okay";
+};
diff --git a/arch/arm/boot/dts/vf500-colibri.dtsi b/arch/arm/boot/dts/vf500-colibri.dtsi
index cee34a3..6e795f3 100644
--- a/arch/arm/boot/dts/vf500-colibri.dtsi
+++ b/arch/arm/boot/dts/vf500-colibri.dtsi
@@ -17,4 +17,49 @@
 	memory {
 		reg = <0x80000000 0x8000000>;
 	};
+
+	touchscreen: vf50-touchscreen {
+		compatible = "toradex,vf50-touchscreen";
+		io-channels = <&adc1 0>,<&adc0 0>,
+				<&adc0 1>,<&adc1 2>;
+		xp-gpios = <&gpio0 13 GPIO_ACTIVE_LOW>;
+		xm-gpios = <&gpio2 29 GPIO_ACTIVE_HIGH>;
+		yp-gpios = <&gpio0 12 GPIO_ACTIVE_LOW>;
+		ym-gpios = <&gpio0 4 GPIO_ACTIVE_HIGH>;
+		pen-detect-gpios = <&gpio0 8 GPIO_ACTIVE_HIGH>;
+		pinctrl-names = "idle","default","gpios";
+		pinctrl-0 = <&pinctrl_touchctrl_idle>;
+		pinctrl-1 = <&pinctrl_touchctrl_default>;
+		pinctrl-2 = <&pinctrl_touchctrl_gpios>;
+		status = "disabled";
+	};
+};
+
+&iomuxc {
+	vf610-colibri {
+		pinctrl_touchctrl_idle: touchctrl_idle {
+			fsl,pins = <
+				VF610_PAD_PTA18__GPIO_8		0x006d
+				VF610_PAD_PTA19__GPIO_9		0x006c
+				>;
+		};
+
+		pinctrl_touchctrl_default: touchctrl_default {
+			fsl,pins = <
+				VF610_PAD_PTA18__ADC0_SE0	0x0040
+				VF610_PAD_PTA19__ADC0_SE1	0x0040
+				VF610_PAD_PTA16__ADC1_SE0	0x0040
+				VF610_PAD_PTB2__ADC1_SE2	0x0040
+				>;
+		};
+
+		pinctrl_touchctrl_gpios: touchctrl_gpios {
+			fsl,pins = <
+				VF610_PAD_PTA23__GPIO_13	0x22e9
+				VF610_PAD_PTB23__GPIO_93	0x22e9
+				VF610_PAD_PTA22__GPIO_12	0x22e9
+				VF610_PAD_PTA11__GPIO_4		0x22e9
+				>;
+		};
+	};
 };
-- 
2.5.0



From maitysanchayan at gmail.com  Wed Aug  5 01:55:51 2015
From: maitysanchayan at gmail.com (Sanchayan Maity)
Date: Wed,  5 Aug 2015 14:25:51 +0530
Subject: [PATCH v3 3/3] touchscreen: colibri-vf50-ts: Add touchscreen support
 for Colibri VF50
In-Reply-To: <cover.1438763030.git.maitysanchayan@gmail.com>
References: <cover.1438763030.git.maitysanchayan@gmail.com>
Message-ID: <bb234514d6921c3d184930d78e7822381c481b79.1438763030.git.maitysanchayan@gmail.com>

The Colibri Vybrid VF50 module supports 4-wire touchscreens using
FETs and ADC inputs. This driver uses the IIO consumer interface
and relies on the vf610_adc driver based on the IIO framework.

Signed-off-by: Sanchayan Maity <maitysanchayan at gmail.com>
---
 drivers/input/touchscreen/Kconfig           |  12 +
 drivers/input/touchscreen/Makefile          |   1 +
 drivers/input/touchscreen/colibri-vf50-ts.c | 404 ++++++++++++++++++++++++++++
 3 files changed, 417 insertions(+)
 create mode 100644 drivers/input/touchscreen/colibri-vf50-ts.c

diff --git a/drivers/input/touchscreen/Kconfig b/drivers/input/touchscreen/Kconfig
index 80f6386..28948ca 100644
--- a/drivers/input/touchscreen/Kconfig
+++ b/drivers/input/touchscreen/Kconfig
@@ -1027,4 +1027,16 @@ config TOUCHSCREEN_ZFORCE
 	  To compile this driver as a module, choose M here: the
 	  module will be called zforce_ts.
 
+config TOUCHSCREEN_COLIBRI_VF50
+	tristate "Toradex Colibri on board touchscreen driver"
+	depends on GPIOLIB && IIO && VF610_ADC
+	help
+	  Say Y here if you have a Colibri VF50 and plan to use
+	  the on-board provided 4-wire touchscreen driver.
+
+	  If unsure, say N.
+
+	  To compile this driver as a module, choose M here: the
+	  module will be called colibri_vf50_ts.
+
 endif
diff --git a/drivers/input/touchscreen/Makefile b/drivers/input/touchscreen/Makefile
index 44deea7..93746a0 100644
--- a/drivers/input/touchscreen/Makefile
+++ b/drivers/input/touchscreen/Makefile
@@ -84,3 +84,4 @@ obj-$(CONFIG_TOUCHSCREEN_W90X900)	+= w90p910_ts.o
 obj-$(CONFIG_TOUCHSCREEN_SX8654)	+= sx8654.o
 obj-$(CONFIG_TOUCHSCREEN_TPS6507X)	+= tps6507x-ts.o
 obj-$(CONFIG_TOUCHSCREEN_ZFORCE)	+= zforce_ts.o
+obj-$(CONFIG_TOUCHSCREEN_COLIBRI_VF50)	+= colibri-vf50-ts.o
diff --git a/drivers/input/touchscreen/colibri-vf50-ts.c b/drivers/input/touchscreen/colibri-vf50-ts.c
new file mode 100644
index 0000000..d7bc91a
--- /dev/null
+++ b/drivers/input/touchscreen/colibri-vf50-ts.c
@@ -0,0 +1,404 @@
+/* Copyright 2015 Toradex AG
+ *
+ * Toradex Colibri VF50 Touchscreen driver
+ *
+ * Originally authored by Stefan Agner for 3.0 kernel
+ *
+ * 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.
+ */
+
+#include <linux/delay.h>
+#include <linux/err.h>
+#include <linux/gpio.h>
+#include <linux/iio/consumer.h>
+#include <linux/iio/types.h>
+#include <linux/input.h>
+#include <linux/interrupt.h>
+#include <linux/kernel.h>
+#include <linux/module.h>
+#include <linux/pinctrl/consumer.h>
+#include <linux/platform_device.h>
+#include <linux/slab.h>
+#include <linux/types.h>
+
+#define DRIVER_NAME "colibri-vf50-ts"
+#define DRV_VERSION "1.0"
+
+#define VF_ADC_MAX ((1 << 12) - 1)
+
+#define COLI_TOUCH_MIN_DELAY_US 1000
+#define COLI_TOUCH_MAX_DELAY_US 2000
+
+static int min_pressure = 200;
+
+struct vf50_touch_device {
+	struct platform_device	*pdev;
+	struct input_dev	*ts_input;
+	struct iio_channel	*channels;
+	struct gpio_desc *gpio_xp;
+	struct gpio_desc *gpio_xm;
+	struct gpio_desc *gpio_yp;
+	struct gpio_desc *gpio_ym;
+	struct gpio_desc *gpio_pen_detect;
+	int pen_irq;
+	bool stop_touchscreen;
+};
+
+/*
+ * Enables given plates and measures touch parameters using ADC
+ */
+static int adc_ts_measure(struct iio_channel *channel,
+		  struct gpio_desc *plate_p, struct gpio_desc *plate_m)
+{
+	int i, value = 0, val = 0;
+	int ret;
+
+	gpiod_set_value(plate_p, 1);
+	gpiod_set_value(plate_m, 1);
+
+	usleep_range(COLI_TOUCH_MIN_DELAY_US, COLI_TOUCH_MAX_DELAY_US);
+
+	for (i = 0; i < 5; i++) {
+		ret = iio_read_channel_raw(channel, &val);
+		if (ret < 0) {
+			value = ret;
+			goto error_iio_read;
+		}
+
+		value += val;
+	}
+
+	value /= 5;
+
+error_iio_read:
+	gpiod_set_value(plate_p, 0);
+	gpiod_set_value(plate_m, 0);
+
+	return value;
+}
+
+/*
+ * Enable touch detection using falling edge detection on XM
+ */
+static void vf50_ts_enable_touch_detection(struct vf50_touch_device *vf50_ts)
+{
+	/* Enable plate YM (needs to be strong GND, high active) */
+	gpiod_set_value(vf50_ts->gpio_ym, 1);
+
+	/*
+	 * Let the platform mux to idle state in order to enable
+	 * Pull-Up on GPIO
+	 */
+	pinctrl_pm_select_idle_state(&vf50_ts->pdev->dev);
+}
+
+/*
+ * ADC touch screen sampling bottom half irq handler
+ */
+static irqreturn_t vf50_ts_irq_bh(int irq, void *private)
+{
+	struct vf50_touch_device *vf50_ts = (struct vf50_touch_device *)private;
+	struct device *dev = &vf50_ts->pdev->dev;
+	int val_x, val_y, val_z1, val_z2, val_p = 0;
+	bool discard_val_on_start = true;
+
+	/* Disable the touch detection plates */
+	gpiod_set_value(vf50_ts->gpio_ym, 0);
+
+	/* Let the platform mux to default state in order to mux as ADC */
+	pinctrl_pm_select_default_state(dev);
+
+	while (!vf50_ts->stop_touchscreen) {
+		/* X-Direction */
+		val_x = adc_ts_measure(&vf50_ts->channels[0],
+				vf50_ts->gpio_xp, vf50_ts->gpio_xm);
+		if (val_x < 0)
+			break;
+
+		/* Y-Direction */
+		val_y = adc_ts_measure(&vf50_ts->channels[1],
+				vf50_ts->gpio_yp, vf50_ts->gpio_ym);
+		if (val_y < 0)
+			break;
+
+		/*
+		 * Touch pressure
+		 * Measure on XP/YM
+		 */
+		val_z1 = adc_ts_measure(&vf50_ts->channels[2],
+				vf50_ts->gpio_yp, vf50_ts->gpio_xm);
+		if (val_z1 < 0)
+			break;
+		val_z2 = adc_ts_measure(&vf50_ts->channels[3],
+				vf50_ts->gpio_yp, vf50_ts->gpio_xm);
+		if (val_z2 < 0)
+			break;
+
+		/* Validate signal (avoid calculation using noise) */
+		if (val_z1 > 64 && val_x > 64) {
+			/*
+			 * Calculate resistance between the plates
+			 * lower resistance means higher pressure
+			 */
+			int r_x = (1000 * val_x) / VF_ADC_MAX;
+
+			val_p = (r_x * val_z2) / val_z1 - r_x;
+
+		} else {
+			val_p = 2000;
+		}
+
+		val_p = 2000 - val_p;
+		dev_dbg(dev, "Measured values: x: %d, y: %d, z1: %d, z2: %d, "
+			"p: %d\n", val_x, val_y, val_z1, val_z2, val_p);
+
+		/*
+		 * If touch pressure is too low, stop measuring and reenable
+		 * touch detection
+		 */
+		if (val_p < min_pressure || val_p > 2000)
+			break;
+
+		/*
+		 * The pressure may not be enough for the first x and the
+		 * second y measurement, but, the pressure is ok when the
+		 * driver is doing the third and fourth measurement. To
+		 * take care of this, we drop the first measurement always.
+		 */
+		if (discard_val_on_start) {
+			discard_val_on_start = false;
+		} else {
+			/*
+			 * Report touch position and sleep for
+			 * next measurement
+			 */
+			input_report_abs(vf50_ts->ts_input,
+					ABS_X, VF_ADC_MAX - val_x);
+			input_report_abs(vf50_ts->ts_input,
+					ABS_Y, VF_ADC_MAX - val_y);
+			input_report_abs(vf50_ts->ts_input,
+					ABS_PRESSURE, val_p);
+			input_report_key(vf50_ts->ts_input, BTN_TOUCH, 1);
+			input_sync(vf50_ts->ts_input);
+		}
+
+		msleep(10);
+	}
+
+	/* Report no more touch, reenable touch detection */
+	input_report_abs(vf50_ts->ts_input, ABS_PRESSURE, 0);
+	input_report_key(vf50_ts->ts_input, BTN_TOUCH, 0);
+	input_sync(vf50_ts->ts_input);
+
+	vf50_ts_enable_touch_detection(vf50_ts);
+
+	/* Wait for the pull-up to be stable on high */
+	msleep(10);
+
+	return IRQ_HANDLED;
+}
+
+static int vf50_ts_open(struct input_dev *dev_input)
+{
+	int ret;
+	struct vf50_touch_device *touchdev = input_get_drvdata(dev_input);
+	struct device *dev = &touchdev->pdev->dev;
+
+	dev_dbg(dev, "Input device %s opened, starting touch detection\n",
+			dev_input->name);
+
+	touchdev->stop_touchscreen = false;
+
+	ret = gpiod_direction_output(touchdev->gpio_xp, 0);
+	if (ret) {
+		dev_err(dev, "Could not set gpio xp as output %d\n", ret);
+		return ret;
+	}
+
+	ret = gpiod_direction_output(touchdev->gpio_xm, 0);
+	if (ret) {
+		dev_err(dev, "Could not set gpio xm as output %d\n", ret);
+		return ret;
+	}
+
+	ret = gpiod_direction_output(touchdev->gpio_yp, 0);
+	if (ret) {
+		dev_err(dev, "Could not set gpio yp as output %d\n", ret);
+		return ret;
+	}
+
+	ret = gpiod_direction_output(touchdev->gpio_ym, 0);
+	if (ret) {
+		dev_err(dev, "Could not set gpio ym as output %d\n", ret);
+		return ret;
+	}
+
+	ret = gpiod_direction_input(touchdev->gpio_pen_detect);
+	if (ret) {
+		dev_err(dev,
+			"Could not set gpio pen detect as input %d\n", ret);
+		return ret;
+	}
+
+	/* Mux detection before request IRQ, wait for pull-up to settle */
+	vf50_ts_enable_touch_detection(touchdev);
+	msleep(10);
+
+	return 0;
+}
+
+static void vf50_ts_close(struct input_dev *dev_input)
+{
+	struct vf50_touch_device *touchdev = input_get_drvdata(dev_input);
+	struct device *dev = &touchdev->pdev->dev;
+
+	touchdev->stop_touchscreen = true;
+
+	dev_dbg(dev, "Input device %s closed, disable touch detection\n",
+		dev_input->name);
+}
+
+static inline int vf50_ts_get_gpiod(struct device *dev,
+			struct gpio_desc **gpio_d, const char *con_id)
+{
+	int ret;
+
+	*gpio_d = devm_gpiod_get(dev, con_id);
+	if (IS_ERR(*gpio_d)) {
+		ret = PTR_ERR(*gpio_d);
+		dev_err(dev, "Could not get gpio_%s %d\n", con_id, ret);
+		return ret;
+	}
+
+	return 0;
+}
+
+static int vf50_ts_probe(struct platform_device *pdev)
+{
+	struct input_dev *input;
+	struct iio_channel *channels;
+	struct device *dev = &pdev->dev;
+	struct vf50_touch_device *touchdev;
+	int ret;
+
+	channels = iio_channel_get_all(dev);
+	if (IS_ERR(channels))
+		return PTR_ERR(channels);
+
+	touchdev = devm_kzalloc(dev, sizeof(*touchdev), GFP_KERNEL);
+	if (touchdev == NULL) {
+		ret = -ENOMEM;
+		goto error_release_channels;
+	}
+
+	input = devm_input_allocate_device(dev);
+	if (!input) {
+		dev_err(dev, "Failed to allocate TS input device\n");
+		ret = -ENOMEM;
+		goto error_release_channels;
+	}
+
+	platform_set_drvdata(pdev, touchdev);
+
+	touchdev->pdev = pdev;
+	touchdev->channels = channels;
+
+	input->name = DRIVER_NAME;
+	input->id.bustype = BUS_HOST;
+	input->dev.parent = dev;
+	input->open = vf50_ts_open;
+	input->close = vf50_ts_close;
+
+	_set_bit(EV_ABS, input->evbit);
+	_set_bit(EV_KEY, input->evbit);
+	_set_bit(BTN_TOUCH, input->keybit);
+	input_set_abs_params(input, ABS_X, 0, VF_ADC_MAX, 0, 0);
+	input_set_abs_params(input, ABS_Y, 0, VF_ADC_MAX, 0, 0);
+	input_set_abs_params(input, ABS_PRESSURE, 0, VF_ADC_MAX, 0, 0);
+
+	touchdev->ts_input = input;
+	input_set_drvdata(input, touchdev);
+	ret = input_register_device(input);
+	if (ret) {
+		dev_err(dev, "Failed to register input device\n");
+		goto error_release_channels;
+	}
+
+	ret = vf50_ts_get_gpiod(dev, &touchdev->gpio_xp, "xp");
+	if (ret)
+		goto error_release_channels;
+
+	ret = vf50_ts_get_gpiod(dev, &touchdev->gpio_xm, "xm");
+	if (ret)
+		goto error_release_channels;
+
+	ret = vf50_ts_get_gpiod(dev, &touchdev->gpio_yp, "yp");
+	if (ret)
+		goto error_release_channels;
+
+	ret = vf50_ts_get_gpiod(dev, &touchdev->gpio_ym, "ym");
+	if (ret)
+		goto error_release_channels;
+
+	ret = vf50_ts_get_gpiod(dev, &touchdev->gpio_pen_detect,
+				"pen-detect");
+	if (ret)
+		goto error_release_channels;
+
+	touchdev->pen_irq = gpiod_to_irq(touchdev->gpio_pen_detect);
+	if (touchdev->pen_irq < 0) {
+		ret = touchdev->pen_irq;
+		dev_err(dev, "Unable to get IRQ for GPIO\n");
+		goto error_release_channels;
+	}
+
+	ret = devm_request_threaded_irq(dev, touchdev->pen_irq, NULL,
+			vf50_ts_irq_bh, IRQF_TRIGGER_LOW | IRQF_ONESHOT,
+			"vf50 touch", touchdev);
+	if (ret < 0) {
+		dev_err(dev, "Unable to request IRQ %d\n", touchdev->pen_irq);
+		goto error_release_channels;
+	}
+
+	return 0;
+
+error_release_channels:
+	iio_channel_release_all(channels);
+	return ret;
+}
+
+static int vf50_ts_remove(struct platform_device *pdev)
+{
+	struct vf50_touch_device *touchdev = platform_get_drvdata(pdev);
+
+	iio_channel_release_all(touchdev->channels);
+
+	return 0;
+}
+
+static const struct of_device_id vf50_touch_of_match[] = {
+	{ .compatible = "toradex,vf50-touchscreen", },
+	{ }
+};
+MODULE_DEVICE_TABLE(of, vf50_touch_of_match);
+
+static struct platform_driver vf50_touch_driver = {
+	.driver = {
+		.name = "toradex,vf50_touchctrl",
+		.of_match_table = vf50_touch_of_match,
+	},
+	.probe = vf50_ts_probe,
+	.remove = vf50_ts_remove,
+};
+
+module_platform_driver(vf50_touch_driver);
+
+module_param(min_pressure, int, 0600);
+MODULE_PARM_DESC(min_pressure, "Minimum pressure for touch detection");
+MODULE_AUTHOR("Sanchayan Maity");
+MODULE_DESCRIPTION("Colibri VF50 Touchscreen driver");
+MODULE_LICENSE("GPL v2");
+MODULE_VERSION(DRV_VERSION);
-- 
2.5.0



From maitysanchayan at gmail.com  Wed Aug  5 01:55:50 2015
From: maitysanchayan at gmail.com (Sanchayan Maity)
Date: Wed,  5 Aug 2015 14:25:50 +0530
Subject: [PATCH v3 2/3] input: Add DT binding documentation for Colibri VF50
 touchscreen
In-Reply-To: <cover.1438763030.git.maitysanchayan@gmail.com>
References: <cover.1438763030.git.maitysanchayan@gmail.com>
Message-ID: <02b69355beb87bd1087d9df76d82fa0aeb161d61.1438763030.git.maitysanchayan@gmail.com>

This adds device tree binding documentation for the Colibri VF50
touchscreen driver.

Signed-off-by: Sanchayan Maity <maitysanchayan at gmail.com>
---
 .../bindings/input/touchscreen/colibri-vf50-ts.txt | 32 ++++++++++++++++++++++
 1 file changed, 32 insertions(+)
 create mode 100644 Documentation/devicetree/bindings/input/touchscreen/colibri-vf50-ts.txt

diff --git a/Documentation/devicetree/bindings/input/touchscreen/colibri-vf50-ts.txt b/Documentation/devicetree/bindings/input/touchscreen/colibri-vf50-ts.txt
new file mode 100644
index 0000000..3e0efac
--- /dev/null
+++ b/Documentation/devicetree/bindings/input/touchscreen/colibri-vf50-ts.txt
@@ -0,0 +1,32 @@
+* Toradex Colibri VF50 Touchscreen driver
+
+Required Properties:
+- compatible must be toradex,vf50-touchctrl
+- io-channels: adc channels being used by the Colibri VF50 module
+- xp-gpios: FET gate driver for input of X+
+- xm-gpios: FET gate driver for input of X-
+- yp-gpios: FET gate driver for input of Y+
+- ym-gpios: FET gate driver for input of Y-
+- pen-detect-gpios: GPIO for pen detect irq
+- pinctrl-names: "idle", "default", "gpios"
+- pinctrl-0: pinctrl node for idle state gpio pinmux
+- pinctrl-1: pinctrl node for touch detection state pinmux
+- pinctrl-2: pinctrl node for gpios functioning as FET gate drivers
+
+Example:
+
+	touchctrl: vf50_touchctrl {
+		compatible = "toradex,vf50-touchctrl";
+		io-channels = <&adc1 0>,<&adc0 0>,
+				<&adc0 1>,<&adc1 2>;
+		xp-gpios = <&gpio0 13 GPIO_ACTIVE_LOW>;
+		xm-gpios = <&gpio2 29 GPIO_ACTIVE_HIGH>;
+		yp-gpios = <&gpio0 12 GPIO_ACTIVE_LOW>;
+		ym-gpios = <&gpio0 4 GPIO_ACTIVE_HIGH>;
+		pen-detect-gpios = <&gpio0 8 GPIO_ACTIVE_HIGH>;
+		pinctrl-names = "idle","default","gpios";
+		pinctrl-0 = <&pinctrl_touchctrl_idle>;
+		pinctrl-1 = <&pinctrl_touchctrl_default>;
+		pinctrl-2 = <&pinctrl_touchctrl_gpios>;
+		status = "disabled";
+	};
-- 
2.5.0



From wenyou.yang at atmel.com  Wed Aug  5 01:57:21 2015
From: wenyou.yang at atmel.com (Wenyou Yang)
Date: Wed, 5 Aug 2015 16:57:21 +0800
Subject: [PATCH v3 1/2] drivers: watchdog: add a driver to support SAMA5D4
 watchdog timer
In-Reply-To: <1438765043-11030-1-git-send-email-wenyou.yang@atmel.com>
References: <1438765043-11030-1-git-send-email-wenyou.yang@atmel.com>
Message-ID: <1438765043-11030-2-git-send-email-wenyou.yang@atmel.com>

>From SAMA5D4, the watchdog timer is upgrated with a new feature,
which is describled as in the datasheet, "WDT_MR can be written
until a LOCKMR command is issued in WDT_CR".
That is to say, as long as the bootstrap and u-boot don't issue
a LOCKMR command, WDT_MR can be written more than once in the driver.

So the SAMA5D4 watchdog driver's implementation is different from
the at91sam9260 watchdog driver implemented in file at91sam9_wdt.c.
The user application open the device file to enable the watchdog timer
hardware, and close to disable it, and set the watchdog timer timeout
by seting WDV and WDD fields of WDT_MR register, and ping the watchdog
by issuing WDRSTT command to WDT_CR register with hard-coded key.

Signed-off-by: Wenyou Yang <wenyou.yang at atmel.com>
---
 drivers/watchdog/Kconfig            |    9 ++
 drivers/watchdog/Makefile           |    1 +
 drivers/watchdog/at91_sama5d4_wdt.c |  279 +++++++++++++++++++++++++++++++++++
 drivers/watchdog/at91sam9_wdt.h     |    2 +
 4 files changed, 291 insertions(+)
 create mode 100644 drivers/watchdog/at91_sama5d4_wdt.c

diff --git a/drivers/watchdog/Kconfig b/drivers/watchdog/Kconfig
index e5e7c55..4ce8346 100644
--- a/drivers/watchdog/Kconfig
+++ b/drivers/watchdog/Kconfig
@@ -152,6 +152,15 @@ config ARM_SP805_WATCHDOG
 	  ARM Primecell SP805 Watchdog timer. This will reboot your system when
 	  the timeout is reached.
 
+config AT91_SAMA5D4_WATCHDOG
+	tristate "Atmel SAMA5D4 Watchdog Timer"
+	depends on ARCH_AT91
+	select WATCHDOG_CORE
+	help
+	  Atmel SAMA5D4 watchdog timer is embedded into SAMA5D4 chips.
+	  Its Watchdog Timer Mode Register can be written more than once.
+	  This will reboot your system when the timeout is reached.
+
 config AT91RM9200_WATCHDOG
 	tristate "AT91RM9200 watchdog"
 	depends on SOC_AT91RM9200 && MFD_SYSCON
diff --git a/drivers/watchdog/Makefile b/drivers/watchdog/Makefile
index 5c19294..c57569c 100644
--- a/drivers/watchdog/Makefile
+++ b/drivers/watchdog/Makefile
@@ -30,6 +30,7 @@ obj-$(CONFIG_USBPCWATCHDOG) += pcwd_usb.o
 
 # ARM Architecture
 obj-$(CONFIG_ARM_SP805_WATCHDOG) += sp805_wdt.o
+obj-$(CONFIG_AT91_SAMA5D4_WATCHDOG) += at91_sama5d4_wdt.o
 obj-$(CONFIG_AT91RM9200_WATCHDOG) += at91rm9200_wdt.o
 obj-$(CONFIG_AT91SAM9X_WATCHDOG) += at91sam9_wdt.o
 obj-$(CONFIG_CADENCE_WATCHDOG) += cadence_wdt.o
diff --git a/drivers/watchdog/at91_sama5d4_wdt.c b/drivers/watchdog/at91_sama5d4_wdt.c
new file mode 100644
index 0000000..f2e1995
--- /dev/null
+++ b/drivers/watchdog/at91_sama5d4_wdt.c
@@ -0,0 +1,279 @@
+/*
+ * Driver for Atmel SAMA5D4 Watchdog Timer
+ *
+ * Copyright (C) 2015 Atmel Corporation
+ *
+ * Licensed under GPLv2.
+ */
+
+#include <linux/interrupt.h>
+#include <linux/io.h>
+#include <linux/kernel.h>
+#include <linux/module.h>
+#include <linux/of.h>
+#include <linux/of_irq.h>
+#include <linux/platform_device.h>
+#include <linux/reboot.h>
+#include <linux/watchdog.h>
+
+#include "at91sam9_wdt.h"
+
+/* minimum and maximum watchdog timeout, in seconds */
+#define MIN_WDT_TIMEOUT		1
+#define MAX_WDT_TIMEOUT		16
+#define WDT_DEFAULT_TIMEOUT	MAX_WDT_TIMEOUT
+
+#define WDT_SEC2TICKS(s)	((s) ? (((s) << 8) - 1) : 0)
+
+struct atmel_wdt {
+	struct watchdog_device	wdd;
+	void __iomem		*reg_base;
+	u32	config;
+};
+
+static int wdt_timeout = WDT_DEFAULT_TIMEOUT;
+static bool nowayout = WATCHDOG_NOWAYOUT;
+
+module_param(wdt_timeout, int, 0);
+MODULE_PARM_DESC(wdt_timeout,
+	"Watchdog wdt_timeout in seconds. (default = "
+	__MODULE_STRING(WDT_DEFAULT_TIMEOUT) ")");
+
+module_param(nowayout, bool, 0);
+MODULE_PARM_DESC(nowayout,
+	"Watchdog cannot be stopped once started (default="
+	__MODULE_STRING(WATCHDOG_NOWAYOUT) ")");
+
+#define wdt_read(wdt, field) \
+	readl_relaxed((wdt)->reg_base + (field))
+
+#define wdt_write(wtd, field, val) \
+	writel_relaxed((val), (wdt)->reg_base + (field))
+
+static int atmel_wdt_start(struct watchdog_device *wdd)
+{
+	struct atmel_wdt *wdt = watchdog_get_drvdata(wdd);
+	u32 reg;
+
+	reg = wdt_read(wdt, AT91_WDT_MR);
+	reg &= ~AT91_WDT_WDDIS;
+	wdt_write(wdt, AT91_WDT_MR, reg);
+
+	return 0;
+}
+
+static int atmel_wdt_stop(struct watchdog_device *wdd)
+{
+	struct atmel_wdt *wdt = watchdog_get_drvdata(wdd);
+	u32 reg;
+
+	reg = wdt_read(wdt, AT91_WDT_MR);
+	reg |= AT91_WDT_WDDIS;
+	wdt_write(wdt, AT91_WDT_MR, reg);
+
+	return 0;
+}
+
+static int atmel_wdt_ping(struct watchdog_device *wdd)
+{
+	struct atmel_wdt *wdt = watchdog_get_drvdata(wdd);
+
+	wdt_write(wdt, AT91_WDT_CR, AT91_WDT_KEY | AT91_WDT_WDRSTT);
+
+	return 0;
+}
+
+static int atmel_wdt_set_timeout(struct watchdog_device *wdd,
+				 unsigned int timeout)
+{
+	struct atmel_wdt *wdt = watchdog_get_drvdata(wdd);
+	u32 value = WDT_SEC2TICKS(timeout);
+	u32 reg;
+
+	reg = wdt_read(wdt, AT91_WDT_MR);
+	reg &= ~AT91_WDT_WDV;
+	reg &= ~AT91_WDT_WDD;
+	reg |= AT91_WDT_SET_WDV(value);
+	reg |= AT91_WDT_SET_WDD(value);
+	wdt_write(wdt, AT91_WDT_MR, reg);
+
+	wdd->timeout = timeout;
+
+	return 0;
+}
+
+static const struct watchdog_info atmel_wdt_info = {
+	.options = WDIOF_SETTIMEOUT | WDIOF_MAGICCLOSE | WDIOF_KEEPALIVEPING,
+	.firmware_version = 0,
+	.identity = "Atmel SAMA5D4 Watchdog",
+};
+
+static struct watchdog_ops atmel_wdt_ops = {
+	.owner = THIS_MODULE,
+	.start = atmel_wdt_start,
+	.stop = atmel_wdt_stop,
+	.ping = atmel_wdt_ping,
+	.set_timeout = atmel_wdt_set_timeout,
+};
+
+static irqreturn_t atmel_wdt_irq_handler(int irq, void *dev_id)
+{
+	struct atmel_wdt *wdt = platform_get_drvdata(dev_id);
+
+	if (wdt_read(wdt, AT91_WDT_SR)) {
+		pr_crit("Atmel Watchdog Software Reset\n");
+		emergency_restart();
+		pr_crit("Reboot didn't ?????\n");
+	}
+
+	return IRQ_HANDLED;
+}
+
+static int of_atmel_wdt_init(struct device_node *np, struct atmel_wdt *wdt)
+{
+	const char *tmp;
+
+	wdt->config = AT91_WDT_WDDIS;
+
+	if (!of_property_read_string(np, "atmel,watchdog-type", &tmp) &&
+	    !strcmp(tmp, "software"))
+		wdt->config |= AT91_WDT_WDFIEN;
+	else
+		wdt->config |= AT91_WDT_WDRSTEN;
+
+	if (of_property_read_bool(np, "atmel,idle-halt"))
+		wdt->config |= AT91_WDT_WDIDLEHLT;
+
+	if (of_property_read_bool(np, "atmel,dbg-halt"))
+		wdt->config |= AT91_WDT_WDDBGHLT;
+
+	return 0;
+}
+
+static int atmel_wdt_init(struct atmel_wdt *wdt)
+{
+	struct watchdog_device *wdd = &wdt->wdd;
+	u32 value = WDT_SEC2TICKS(wdd->timeout);
+	u32 reg;
+
+	/*
+	 * Because the fields WDV and WDD must not be modified when the WDDIS
+	 * bit is set, so clear the WDDIS bit before writing the WDT_MR.
+	 */
+	reg = wdt_read(wdt, AT91_WDT_MR);
+	reg &= ~AT91_WDT_WDDIS;
+	wdt_write(wdt, AT91_WDT_MR, reg);
+
+	reg = wdt->config;
+	reg |= AT91_WDT_SET_WDD(value);
+	reg |= AT91_WDT_SET_WDV(value);
+
+	wdt_write(wdt, AT91_WDT_MR, reg);
+
+	return 0;
+}
+
+static int atmel_wdt_probe(struct platform_device *pdev)
+{
+	struct watchdog_device *wdd;
+	struct atmel_wdt *wdt;
+	struct resource *res;
+	void __iomem *regs;
+	int ret, irq = -1;
+
+	wdt = devm_kzalloc(&pdev->dev, sizeof(*wdt), GFP_KERNEL);
+	if (!wdt)
+		return -ENOMEM;
+
+	wdd = &wdt->wdd;
+	wdd->timeout = wdt_timeout;
+	wdd->info = &atmel_wdt_info;
+	wdd->ops = &atmel_wdt_ops;
+	wdd->min_timeout = MIN_WDT_TIMEOUT;
+	wdd->max_timeout = MAX_WDT_TIMEOUT;
+
+	watchdog_set_drvdata(wdd, wdt);
+
+	res = platform_get_resource(pdev, IORESOURCE_MEM, 0);
+	regs = devm_ioremap_resource(&pdev->dev, res);
+	if (IS_ERR(regs))
+		return PTR_ERR(regs);
+
+	wdt->reg_base = regs;
+
+	if (pdev->dev.of_node) {
+		irq = irq_of_parse_and_map(pdev->dev.of_node, 0);
+		if (!irq)
+			dev_warn(&pdev->dev, "failed to get IRQ from DT\n");
+
+		ret = of_atmel_wdt_init(pdev->dev.of_node, wdt);
+		if (ret)
+			return ret;
+	}
+
+	if ((wdt->config & AT91_WDT_WDFIEN) && irq > 0) {
+		ret = devm_request_irq(&pdev->dev, irq, atmel_wdt_irq_handler,
+				       0, pdev->name, pdev);
+		if (ret) {
+			dev_err(&pdev->dev,
+				"cannot register interrupt handler\n");
+			return ret;
+		}
+	}
+
+	ret = watchdog_init_timeout(wdd, wdt_timeout, &pdev->dev);
+	if (ret) {
+		dev_err(&pdev->dev, "unable to set timeout value\n");
+		return ret;
+	}
+
+	ret = atmel_wdt_init(wdt);
+	if (ret)
+		return ret;
+
+	watchdog_set_nowayout(wdd, nowayout);
+
+	ret = watchdog_register_device(wdd);
+	if (ret) {
+		dev_err(&pdev->dev, "failed to register watchdog device\n");
+		return ret;
+	}
+
+	platform_set_drvdata(pdev, wdt);
+
+	dev_info(&pdev->dev, "initialized (timeout = %d sec, nowayout = %d)\n",
+		 wdt_timeout, nowayout);
+
+	return 0;
+}
+
+static int atmel_wdt_remove(struct platform_device *pdev)
+{
+	struct atmel_wdt *wdt = platform_get_drvdata(pdev);
+
+	atmel_wdt_stop(&wdt->wdd);
+
+	watchdog_unregister_device(&wdt->wdd);
+
+	return 0;
+}
+
+static const struct of_device_id atmel_wdt_of_match[] = {
+	{ .compatible = "atmel,sama5d4-wdt", },
+	{ },
+};
+MODULE_DEVICE_TABLE(of, atmel_wdt_of_match);
+
+static struct platform_driver atmel_wdt_driver = {
+	.probe		= atmel_wdt_probe,
+	.remove		= atmel_wdt_remove,
+	.driver		= {
+		.name	= "sama5d4 wdt",
+		.of_match_table = atmel_wdt_of_match,
+	},
+};
+module_platform_driver(atmel_wdt_driver);
+
+MODULE_AUTHOR("Atmel Corporation");
+MODULE_DESCRIPTION("Atmel SAMA5D4 Watchdog Timer driver");
+MODULE_LICENSE("GPL v2");
diff --git a/drivers/watchdog/at91sam9_wdt.h b/drivers/watchdog/at91sam9_wdt.h
index c6fbb2e6..b79a83b 100644
--- a/drivers/watchdog/at91sam9_wdt.h
+++ b/drivers/watchdog/at91sam9_wdt.h
@@ -22,11 +22,13 @@
 
 #define AT91_WDT_MR		0x04			/* Watchdog Mode Register */
 #define		AT91_WDT_WDV		(0xfff << 0)		/* Counter Value */
+#define			AT91_WDT_SET_WDV(x)	((x) & AT91_WDT_WDV)
 #define		AT91_WDT_WDFIEN		(1     << 12)		/* Fault Interrupt Enable */
 #define		AT91_WDT_WDRSTEN	(1     << 13)		/* Reset Processor */
 #define		AT91_WDT_WDRPROC	(1     << 14)		/* Timer Restart */
 #define		AT91_WDT_WDDIS		(1     << 15)		/* Watchdog Disable */
 #define		AT91_WDT_WDD		(0xfff << 16)		/* Delta Value */
+#define			AT91_WDT_SET_WDD(x)	(((x) << 16) & AT91_WDT_WDD)
 #define		AT91_WDT_WDDBGHLT	(1     << 28)		/* Debug Halt */
 #define		AT91_WDT_WDIDLEHLT	(1     << 29)		/* Idle Halt */
 
-- 
1.7.9.5



From wenyou.yang at atmel.com  Wed Aug  5 01:57:22 2015
From: wenyou.yang at atmel.com (Wenyou Yang)
Date: Wed, 5 Aug 2015 16:57:22 +0800
Subject: [PATCH v3 2/2] Documentation: dt: binding: atmel-sama5d4-wdt: for
 SAMA5D4 watchdog driver
In-Reply-To: <1438765043-11030-1-git-send-email-wenyou.yang@atmel.com>
References: <1438765043-11030-1-git-send-email-wenyou.yang@atmel.com>
Message-ID: <1438765043-11030-3-git-send-email-wenyou.yang@atmel.com>

The compatible "atmel,sama5d4-wdt" supports the SAMA5D4 watchdog driver
and the watchdog's WDT_MR register can be written more than once.

Signed-off-by: Wenyou Yang <wenyou.yang at atmel.com>
---
 .../bindings/watchdog/atmel-sama5d4-wdt.txt        |   35 ++++++++++++++++++++
 1 file changed, 35 insertions(+)
 create mode 100644 Documentation/devicetree/bindings/watchdog/atmel-sama5d4-wdt.txt

diff --git a/Documentation/devicetree/bindings/watchdog/atmel-sama5d4-wdt.txt b/Documentation/devicetree/bindings/watchdog/atmel-sama5d4-wdt.txt
new file mode 100644
index 0000000..f7cc7c0
--- /dev/null
+++ b/Documentation/devicetree/bindings/watchdog/atmel-sama5d4-wdt.txt
@@ -0,0 +1,35 @@
+* Atmel SAMA5D4 Watchdog Timer (WDT) Controller
+
+Required properties:
+- compatible: "atmel,sama5d4-wdt"
+- reg: base physical address and length of memory mapped region.
+
+Optional properties:
+- timeout-sec: watchdog timeout value (in seconds).
+- interrupts: interrupt number to the CPU.
+- atmel,watchdog-type: should be "hardware" or "software".
+	"hardware": enable watchdog fault reset. A watchdog fault triggers
+		    watchdog reset.
+	"software": enable watchdog fault interrupt. A watchdog fault asserts
+		    watchdog interrupt.
+- atmel,idle-halt: present if you want to stop the watchdog when the CPU is
+		   in idle state.
+	CAUTION: This property should be used with care, it actually makes the
+	watchdog not counting when the CPU is in idle state, therefore the
+	watchdog reset time depends on mean CPU usage and will not reset at all
+	if the CPU stop working while it is in idle state, which is probably
+	not what you want.
+- atmel,dbg-halt: present if you want to stop the watchdog when the CPU is
+		  in debug state.
+
+Example:
+	watchdog at fc068640 {
+		compatible = "atmel,sama5d4-wdt";
+		reg = <0xfc068640 0x10>;
+		interrupts = <4 IRQ_TYPE_LEVEL_HIGH 5>;
+		timeout-sec = <10>;
+		atmel,watchdog-type = "hardware";
+		atmel,dbg-halt;
+		atmel,idle-halt;
+		status = "okay";
+	};
-- 
1.7.9.5



From vaibhav.hiremath at linaro.org  Wed Aug  5 02:07:50 2015
From: vaibhav.hiremath at linaro.org (Vaibhav Hiremath)
Date: Wed, 05 Aug 2015 14:37:50 +0530
Subject: [PATCH 4/4] mfd: 88pm800: Add support for clk subdevice
In-Reply-To: <20150723155008.GS3436@x1>
References: <1437476823-3358-1-git-send-email-vaibhav.hiremath@linaro.org>
 <1437476823-3358-5-git-send-email-vaibhav.hiremath@linaro.org>
 <20150723155008.GS3436@x1>
Message-ID: <55C1D266.5090804@linaro.org>



On Thursday 23 July 2015 09:20 PM, Lee Jones wrote:
> On Tue, 21 Jul 2015, Vaibhav Hiremath wrote:
>
>> This patch adds mfd_cell/clk-subdevice for 88PM800 MFD
>> (and family of devices).
>>
>> Signed-off-by: Vaibhav Hiremath <vaibhav.hiremath at linaro.org>
>> ---
>>   drivers/mfd/88pm800.c | 25 +++++++++++++++++++++++++
>>   1 file changed, 25 insertions(+)
>>
>> diff --git a/drivers/mfd/88pm800.c b/drivers/mfd/88pm800.c
>> index f104a32..9723eac 100644
>> --- a/drivers/mfd/88pm800.c
>> +++ b/drivers/mfd/88pm800.c
>> @@ -173,6 +173,14 @@ static const struct mfd_cell regulator_devs[] = {
>>   	},
>>   };
>>
>> +static struct mfd_cell clk_devs[] = {
>> +	{
>> +	 .name = "88pm80x-clk",
>> +	 .of_compatible = "marvell,88pm800-clk",
>> +	 .id = -1,
>> +	},
>> +};
>
> Why does each device in 88pm800.c have it's own mfd_cell?
>

Probably, the author of the driver can comment on this. I have cc'ed
all of them.

But looking at the driver it looks like, except onkey and regulator all
other devices need per-initialization. For example,

in case of clock,

static int device_clk_init(struct pm80x_chip *chip)
{
         if (chip->type == CHIP_PM800)
                 clk_devs[0].name = "88pm800-clk";
         else if (chip->type == CHIP_PM860)
                 clk_devs[0].name = "88pm860-clk";

         return mfd_add_devices(chip->dev, 0, &clk_devs[0],
                               ARRAY_SIZE(clk_devs), NULL, 0, NULL);
}



> Take the opportunity to correct the tabbing in the remainder of the
> file.  Make that fix-up patch 1 of this set.  Then fixup this patch.
>

Ok, I will.

Thanks,
Vaibhav


From will.deacon at arm.com  Wed Aug  5 02:16:08 2015
From: will.deacon at arm.com (Will Deacon)
Date: Wed, 5 Aug 2015 10:16:08 +0100
Subject: [PATCH] arm64: mm: ensure patched kernel text is fetched from PoC
In-Reply-To: <20150804214522.GA14625@leverpostej>
References: <1438715013-4625-1-git-send-email-will.deacon@arm.com>
 <20150804214522.GA14625@leverpostej>
Message-ID: <20150805091607.GA6092@arm.com>

On Tue, Aug 04, 2015 at 10:45:23PM +0100, Mark Rutland wrote:
> I assume that you meant PoU rather than PoC in the subject.

Oops, well spotted!

> On Tue, Aug 04, 2015 at 08:03:33PM +0100, Will Deacon wrote:
> > The arm64 booting document requires that the bootloader has cleaned the
> > kernel image to the PoC. However, when a CPU re-enters the kernel due to
> > either a CPU hotplug "on" event or resuming from a low-power state (e.g.
> > cpuidle), the kernel text may in-fact be dirty at the PoU due to things
> > like alternative patching or even module loading.
> > 
> > Thanks to I-cache speculation with the MMU off, stale instructions could
> > be fetched prior to enabling the MMU, potentially leading to crashes
> > when executing regions of code that have been modified at runtime.
> > 
> > This patch addresses the issue by ensuring that the local I-cache is
> > invalidated immediately after a CPU has enabled its MMU but before
> > jumping out of the identity mapping. Any stale instructions fetched from
> > the PoC will then be discarded and refetched correctly from the PoU.
> 
> It may be worth mentioning that none of the instructions executed up to
> this point will have been patched, so we know that they have remained
> clean to the PoC. Otherwise we'd need to flush those to the PoC
> explicitly.

I'll add something to the log.

> Reviewed-by: Mark Rutland <mark.rutland at arm.com>

Cheers,

Will


From will.deacon at arm.com  Wed Aug  5 02:23:19 2015
From: will.deacon at arm.com (Will Deacon)
Date: Wed, 5 Aug 2015 10:23:19 +0100
Subject: [PATCH v4 1/3] PCI: generic: remove dependency on hw_pci
In-Reply-To: <20150804234956.GF17327@google.com>
References: <1438721620-15493-1-git-send-email-jchandra@broadcom.com>
 <20150804234956.GF17327@google.com>
Message-ID: <20150805092318.GB6092@arm.com>

On Wed, Aug 05, 2015 at 12:49:56AM +0100, Bjorn Helgaas wrote:
> On Wed, Aug 05, 2015 at 02:23:38AM +0530, Jayachandran C wrote:
> > The current code in pci-host-generic.c uses pci_common_init_dev()
> > from arm architecture to do some part of the PCI setup, and this
> > prevents it from being used with arm64 architecture.
> > 
> > The part of pci_common_init_dev() that is really needed by
> > pci-host-generic.c is very limited and can be done in the same
> > file without using hw_pci API of ARM. The ARM platform requires
> > a pci_sys_data as sysdata for the PCI bus, this can be handled by
> > setting up gen_pci to have a pci_sys_data variable as the first
> > element.
> > 
> > Signed-off-by: Jayachandran C <jchandra at broadcom.com>
> > Acked-by: Lorenzo Pieralisi <lorenzo.pieralisi at arm.com>
> > Tested-by: Lorenzo Pieralisi <lorenzo.pieralisi at arm.com>
> > Tested-by: Pavel Fedin <p.fedin at samsung.com>
> 
> I applied all three of these to my pci/enumeration branch for v4.3.
> 
> I made a few changes, the most important being to call
> pcie_bus_configure_settings() before pci_bus_add_devices(), because drivers
> may claim devices in pci_bus_add_devices(), and the PCI core shouldn't
> touch devices after drivers claim them.
> 
> I dropped the acks and tested-by because of that change, but I'll happily
> add them back if Lorenzo and Pavel confirm.  The patches are here if you
> want to review/test them:
> 
> https://git.kernel.org/cgit/linux/kernel/git/helgaas/pci.git/log/?h=pci/enumeration
> 
> I'm sure the other patches on that branch will need some tweaks, too, so I
> don't have any problem with updating these.

Excellent, thanks Bjorn! Marc and I will take these for a spin in
conjunction with tip/irq/core and the arm64 queue.

That said, I just tried to build this and it fails to compile the x-gene
PCI host driver. Fixup below.

Will

--->8

diff --git a/drivers/pci/host/pci-xgene.c b/drivers/pci/host/pci-xgene.c
index 514f41b86c49..57ac0c7108a8 100644
--- a/drivers/pci/host/pci-xgene.c
+++ b/drivers/pci/host/pci-xgene.c
@@ -506,7 +506,7 @@ static int xgene_pcie_msi_enable(struct xgene_pcie_port *port)
 {
 	struct device_node *msi_node;
 
-	msi_node = of_parse_phandle(port->dev.of_node, "msi-parent", 0);
+	msi_node = of_parse_phandle(port->dev->of_node, "msi-parent", 0);
 	if (!msi_node)
 		return -ENODEV;
 


From will.deacon at arm.com  Wed Aug  5 02:25:34 2015
From: will.deacon at arm.com (Will Deacon)
Date: Wed, 5 Aug 2015 10:25:34 +0100
Subject: [PATCH v4 1/3] PCI: generic: remove dependency on hw_pci
In-Reply-To: <20150805092318.GB6092@arm.com>
References: <1438721620-15493-1-git-send-email-jchandra@broadcom.com>
 <20150804234956.GF17327@google.com> <20150805092318.GB6092@arm.com>
Message-ID: <20150805092533.GC6092@arm.com>

On Wed, Aug 05, 2015 at 10:23:18AM +0100, Will Deacon wrote:
> That said, I just tried to build this and it fails to compile the x-gene
> PCI host driver. Fixup below.

Wait, there's more!

Will

--->8

diff --git a/drivers/pci/host/pci-xgene.c b/drivers/pci/host/pci-xgene.c
index 514f41b86c49..8ab3bd098424 100644
--- a/drivers/pci/host/pci-xgene.c
+++ b/drivers/pci/host/pci-xgene.c
@@ -506,7 +506,7 @@ static int xgene_pcie_msi_enable(struct xgene_pcie_port *port)
 {
 	struct device_node *msi_node;
 
-	msi_node = of_parse_phandle(port->dev.of_node, "msi-parent", 0);
+	msi_node = of_parse_phandle(port->dev->of_node, "msi-parent", 0);
 	if (!msi_node)
 		return -ENODEV;
 
@@ -515,7 +515,7 @@ static int xgene_pcie_msi_enable(struct xgene_pcie_port *port)
 		return -ENODEV;
 
 	of_node_put(msi_node);
-	port->msi->dev = &port->dev;
+	port->msi->dev = port->dev;
 	return 0;
 }
 



From sudeep.holla at arm.com  Wed Aug  5 02:34:12 2015
From: sudeep.holla at arm.com (Sudeep Holla)
Date: Wed, 05 Aug 2015 10:34:12 +0100
Subject: [PATCH v4 1/6] ARM: shmobile: r8a7740 dtsi: Add L2
 cache-controller node
In-Reply-To: <1438765090-823-2-git-send-email-geert+renesas@glider.be>
References: <1438765090-823-1-git-send-email-geert+renesas@glider.be>
 <1438765090-823-2-git-send-email-geert+renesas@glider.be>
Message-ID: <55C1D894.8070302@arm.com>



On 05/08/15 09:58, Geert Uytterhoeven wrote:
> Add the missing L2 cache-controller node. This will allow migration to
> the generic l2c OF initialization.
>
> The L2 cache is an ARM L2C-310 (r3p1-150rel0), of size 256 KiB (32 KiB x
> 8 ways).
>
> Signed-off-by: Geert Uytterhoeven <geert+renesas at glider.be>
> ---
> v4:
>    - Commit eeedcea69e927857 ("ARM: 8395/1: l2c: Add support for the
>      "arm,shared-override" property") is queued for 4.3 in arm/for-next,
>
> v3:
>    - Add "arm,shared-override",
>
> v2:
>    - Fix interrupt (should be 3 cells, not 1),
>    - Describe cache better.
> ---
>   arch/arm/boot/dts/r8a7740.dtsi | 16 ++++++++++++++++
>   1 file changed, 16 insertions(+)
>
> diff --git a/arch/arm/boot/dts/r8a7740.dtsi b/arch/arm/boot/dts/r8a7740.dtsi
> index d84714468cce18df..ddef5b1c68fa06b3 100644
> --- a/arch/arm/boot/dts/r8a7740.dtsi
> +++ b/arch/arm/boot/dts/r8a7740.dtsi
> @@ -37,6 +37,22 @@
>   		      <0xc2000000 0x1000>;
>   	};
>
> +	L2: cache-controller {
> +		compatible = "arm,pl310-cache";
> +		reg = <0xf0100000 0x1000>;
> +		interrupts = <0 84 IRQ_TYPE_LEVEL_HIGH>;
> +		power-domains = <&pd_a3sm>;
> +		arm,data-latency = <3 3 3>;
> +		arm,tag-latency = <2 2 2>;
> +		arm,shared-override;
> +		cache-unified;
> +		cache-level = <2>;
> +		cache-size = <0x40000>;
> +		cache-sets = <1024>;
> +		cache-block-size = <32>;
> +		cache-line-size = <32>;

Any particular reason whey you need all this cache-* properties ? Is
something broken on these SoCs ? We should be able to get most of these
information from the SoC(reading some registers). It's good to avoid
passing them via DT if they can be discovered from hardware.

Regards,
Sudeep


From olof at lixom.net  Wed Aug  5 01:36:50 2015
From: olof at lixom.net (Olof Johansson)
Date: Wed, 5 Aug 2015 10:36:50 +0200
Subject: [GIT PULL] Second Round of Renesas ARM Based SoC Defconfig
 Updates for v4.3
In-Reply-To: <cover.1438215768.git.horms+renesas@verge.net.au>
References: <cover.1438215768.git.horms+renesas@verge.net.au>
Message-ID: <20150805083650.GA6390@localhost>

On Thu, Jul 30, 2015 at 09:23:50AM +0900, Simon Horman wrote:
> Hi Olof, Hi Kevin, Hi Arnd,
> 
> Please consider these second round of Renesas ARM based SoC defconfig updates for v4.3.
> 
> This pull request is based on the previous round of
> such requests, tagged as renesas-defconfig-for-v4.3,
> which I have already sent a pull-request for.
> 
> 
> The following changes since commit 821e79cb5686695f0adaef61587a184e953a937e:
> 
>   ARM: shmobile: Remove marzen_defconfig (2015-07-17 08:29:45 +0900)
> 
> are available in the git repository at:
> 
>   git://git.kernel.org/pub/scm/linux/kernel/git/horms/renesas.git tags/renesas-defconfig2-for-v4.3
> 
> for you to fetch changes up to 4055a722d260ca30610fc52238d0aa49ff5bffa9:
> 
>   ARM: shmobile: Enable fixed voltage regulator in shmobile_defconfig (2015-07-28 09:27:00 +0900)

Merged, thanks.


-Olof


From olof at lixom.net  Wed Aug  5 01:46:46 2015
From: olof at lixom.net (Olof Johansson)
Date: Wed, 5 Aug 2015 10:46:46 +0200
Subject: [GIT PULL] qcom dt changes for 4.3
In-Reply-To: <1438290997-17503-1-git-send-email-agross@codeaurora.org>
References: <1438290997-17503-1-git-send-email-agross@codeaurora.org>
Message-ID: <20150805084646.GE6390@localhost>

On Thu, Jul 30, 2015 at 04:16:37PM -0500, Andy Gross wrote:
> The following changes since commit d770e558e21961ad6cfdf0ff7df0eb5d7d4f0754:
> 
>   Linux 4.2-rc1 (2015-07-05 11:01:52 -0700)
> 
> are available in the git repository at:
> 
>   git://codeaurora.org/quic/kernel/agross-msm.git tags/qcom-dt-for-4.3
> 
> for you to fetch changes up to baff39e6708e099261bac73a46377cffc9257388:
> 
>   ARM: dts: qs600: Add real regulators to sdcc (2015-07-28 14:57:47 -0500)

Merged, thanks.


-Olof


From olof at lixom.net  Wed Aug  5 01:50:39 2015
From: olof at lixom.net (Olof Johansson)
Date: Wed, 5 Aug 2015 10:50:39 +0200
Subject: [GIT PULL] qcom arm64 dt changes for 4.3
In-Reply-To: <1438291023-17573-1-git-send-email-agross@codeaurora.org>
References: <1438291023-17573-1-git-send-email-agross@codeaurora.org>
Message-ID: <20150805085039.GG6390@localhost>

On Thu, Jul 30, 2015 at 04:17:03PM -0500, Andy Gross wrote:
> The following changes since commit d770e558e21961ad6cfdf0ff7df0eb5d7d4f0754:
> 
>   Linux 4.2-rc1 (2015-07-05 11:01:52 -0700)
> 
> are available in the git repository at:
> 
>   git://codeaurora.org/quic/kernel/agross-msm.git tags/qcom-arm64-for-4.3
> 
> for you to fetch changes up to 9943230c8860178a6f6409f0ba19167c0a46a71b:
> 
>   arm64: dts: qcom: Add apq8016-sbc board LED's related device nodes (2015-07-28 16:19:13 -0500)

Merged, thanks.


-Olof


From olof at lixom.net  Wed Aug  5 01:46:56 2015
From: olof at lixom.net (Olof Johansson)
Date: Wed, 5 Aug 2015 10:46:56 +0200
Subject: [GIT PULL] qcom defconfig changes for 4.3
In-Reply-To: <1438291007-17536-1-git-send-email-agross@codeaurora.org>
References: <1438291007-17536-1-git-send-email-agross@codeaurora.org>
Message-ID: <20150805084656.GF6390@localhost>

On Thu, Jul 30, 2015 at 04:16:47PM -0500, Andy Gross wrote:
> The following changes since commit d770e558e21961ad6cfdf0ff7df0eb5d7d4f0754:
> 
>   Linux 4.2-rc1 (2015-07-05 11:01:52 -0700)
> 
> are available in the git repository at:
> 
>   git://codeaurora.org/quic/kernel/agross-msm.git tags/qcom-defconfig-for-4.3
> 
> for you to fetch changes up to 142f2610d525c23afa5ba5e4e535504bea8b04b9:
> 
>   ARM: qcom_defconfig: Enable options for KS8851 ethernet (2015-07-24 14:51:32 -0500)

Merged, thanks.


-Olof


From olof at lixom.net  Wed Aug  5 02:00:16 2015
From: olof at lixom.net (Olof Johansson)
Date: Wed, 5 Aug 2015 11:00:16 +0200
Subject: [GIT PULL] Xilinx ZynqMP DT changes for v4.3
In-Reply-To: <55BB369F.4080100@monstr.eu>
References: <55BB369F.4080100@monstr.eu>
Message-ID: <20150805090016.GI6390@localhost>

On Fri, Jul 31, 2015 at 10:49:35AM +0200, Michal Simek wrote:
> Hi,
> 
> please pull these ARM64 DT patches to your tree.
> 
> Thanks,
> Michal
> 
> 
> The following changes since commit d770e558e21961ad6cfdf0ff7df0eb5d7d4f0754:
> 
>   Linux 4.2-rc1 (2015-07-05 11:01:52 -0700)
> 
> are available in the git repository at:
> 
>   https://github.com/Xilinx/linux-xlnx.git tags/zynqmp-dt-for-4.3
> 
> for you to fetch changes up to f49310dc62f68ae9f905f9a1e42224fa23867f47:
> 
>   ARM64: zynqmp: Move SPI nodes to the right location (2015-07-31
> 10:46:34 +0200)
> 
> ----------------------------------------------------------------
> arm: Xilinx ZynqMP dt patches for v4.3
> 
> - Add SATA, GPIO, CAN, SMMU, USB, SPI, I2C, watchdog and sdhci for zynqmp
> - Sort nodes in dtsi

You seem to sort these alphabetically. We normally encourage sorting by unit
address instead. Was there some reason you chose alphabetical?


-Olof



From olof at lixom.net  Wed Aug  5 01:53:44 2015
From: olof at lixom.net (Olof Johansson)
Date: Wed, 5 Aug 2015 10:53:44 +0200
Subject: [GIT PULL] Xilinx Zynq changes for v4.3
In-Reply-To: <55BB31E8.7040806@monstr.eu>
References: <55BB31E8.7040806@monstr.eu>
Message-ID: <20150805085344.GH6390@localhost>

Hi,

On Fri, Jul 31, 2015 at 10:29:28AM +0200, Michal Simek wrote:
> Hi,
> 
> please pull these SoC changes to your tree.
> 
> Thanks,
> Michal
> 
> The following changes since commit d770e558e21961ad6cfdf0ff7df0eb5d7d4f0754:
> 
>   Linux 4.2-rc1 (2015-07-05 11:01:52 -0700)
> 
> are available in the git repository at:
> 
>   https://github.com/Xilinx/linux-xlnx.git tags/zynq-soc-for-4.3
> 
> for you to fetch changes up to e4a9288942392965bd5cfad93d9996b83c0dc4a6:
> 
>   ARM: zynq: reserve space for jump target in secondary trampoline
> (2015-07-31 10:24:41 +0200)

Merged, however:

> Arun Chandran (1):
>       ARM: zynq: Fix earlyprintk in big endian mode
> 
> Masahiro Yamada (1):
>       clk: zynq: remove redundant $(CONFIG_ARCH_ZYNQ) in Makefile

This should have gone through the clk tree. Seems small and simple enough that
I'll take it, but please send patches through appropriate maintainers.

(Adding Mike and Stephen on cc so they know about it).


-Olof



From olof at lixom.net  Wed Aug  5 02:10:08 2015
From: olof at lixom.net (Olof Johansson)
Date: Wed, 5 Aug 2015 11:10:08 +0200
Subject: [GIT PULL] ARM: mvebu: soc changes for v4.3
In-Reply-To: <55BB3CF3.7050000@free-electrons.com>
References: <55BB3CF3.7050000@free-electrons.com>
Message-ID: <20150805091008.GK6390@localhost>

On Fri, Jul 31, 2015 at 11:16:35AM +0200, Gregory CLEMENT wrote:
> Hi,
> 
> Here is the first pull request for soc change for mvebu for v4.3
> 
> Gregory
> 
> The following changes since commit d770e558e21961ad6cfdf0ff7df0eb5d7d4f0754:
> 
>   Linux 4.2-rc1 (2015-07-05 11:01:52 -0700)
> 
> are available in the git repository at:
> 
>   git://git.infradead.org/linux-mvebu.git tags/mvebu-soc-4.3-1
> 
> for you to fetch changes up to 482d638f98cc626bf01d4c9f6d6d35fc77d630c8:
> 
>   ARM: mvebu: Warn about the wake-up sources not taken into account in suspend (2015-07-28 11:40:47 +0200)

Merged, thanks.


-Olof


From olof at lixom.net  Wed Aug  5 02:11:28 2015
From: olof at lixom.net (Olof Johansson)
Date: Wed, 5 Aug 2015 11:11:28 +0200
Subject: [GIT PULL] ARM: mvebu: dt changes for v4.3 #2
In-Reply-To: <55BB3FAE.1020907@free-electrons.com>
References: <55BB3FAE.1020907@free-electrons.com>
Message-ID: <20150805091128.GL6390@localhost>

Hi,


On Fri, Jul 31, 2015 at 11:28:14AM +0200, Gregory CLEMENT wrote:
> Hi,
> 
> Here is the second pull request for cleanup for mvebu for v4.3
> 
> Gregory
> 
> The following changes since commit 7e5308be4c0747e328d03f3daa46aaa5eaf7714f:
> 
>   ARM: mvebu: update EEPROM description of Armada 388 GP (2015-07-09 15:28:08 +0200)
> 
> are available in the git repository at:
> 
>   git://git.infradead.org/linux-mvebu.git tags/mvebu-dt-4.3-2
> 
> for you to fetch changes up to dc57844a736f10bf3799d63d7c0d0efc29b1ad7d:
> 
>   ARM: dts: orion5x: add buffalo linkstation ls-wtgl (2015-07-25 16:19:20 +0200)

Merged, thanks.


One tip:

> 
>  arch/arm/boot/dts/Makefile                       |   1 +
>  arch/arm/boot/dts/orion5x-linkstation-lswtgl.dts | 273 ++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
>  2 files changed, 274 insertions(+)
>  create mode 100644 arch/arm/boot/dts/orion5x-linkstation-lswtgl.dts

If you redirect "git request-pull" to a file (or even pipe it through cat
instead of straight onto your terminal) it'll default to ~78 character lines
instead of the width of your terminal.


-Olof


From wenyou.yang at atmel.com  Wed Aug  5 01:57:20 2015
From: wenyou.yang at atmel.com (Wenyou Yang)
Date: Wed, 5 Aug 2015 16:57:20 +0800
Subject: [PATCH v3 0/2] add a new driver to support SAMA5D4 watchdog timer
Message-ID: <1438765043-11030-1-git-send-email-wenyou.yang@atmel.com>

Hello,

Because the watchdog WDT_MR register can be written more than once,
its work mechanism is different from the at91sam9260 watchdog driver.
Open the device file to enable the watchdog hardware, close to disable it,
and ping it from the user space directly to keep it alive.

Thank for Guenter's review, the version 2.0 changes are listed as below.

Changes from v2.0
 1./ Use a specific driver name, at91_sama5d4_wdt.c.
 2./ Remove '-' at the end of macro name and unnecessary check.
 3./ Use alphabetic order for include files.

Wenyou Yang (2):
  drivers: watchdog: add a driver to support SAMA5D4 watchdog timer
  Documentation: dt: binding: atmel-sama5d4-wdt: for SAMA5D4 watchdog
    driver

 .../bindings/watchdog/atmel-sama5d4-wdt.txt        |   35 +++
 drivers/watchdog/Kconfig                           |    9 +
 drivers/watchdog/Makefile                          |    1 +
 drivers/watchdog/at91_sama5d4_wdt.c                |  279 ++++++++++++++++++++
 drivers/watchdog/at91sam9_wdt.h                    |    2 +
 5 files changed, 326 insertions(+)
 create mode 100644 Documentation/devicetree/bindings/watchdog/atmel-sama5d4-wdt.txt
 create mode 100644 drivers/watchdog/at91_sama5d4_wdt.c

-- 
1.7.9.5



From geert+renesas at glider.be  Wed Aug  5 01:58:07 2015
From: geert+renesas at glider.be (Geert Uytterhoeven)
Date: Wed,  5 Aug 2015 10:58:07 +0200
Subject: [PATCH v4 3/6] ARM: shmobile: sh73a0 dtsi: Add L2 cache-controller
 node
In-Reply-To: <1438765090-823-1-git-send-email-geert+renesas@glider.be>
References: <1438765090-823-1-git-send-email-geert+renesas@glider.be>
Message-ID: <1438765090-823-4-git-send-email-geert+renesas@glider.be>

Add the missing L2 cache-controller node. This will allow migration to
the generic l2c OF initialization.

The L2 cache is an ARM L2C-310 (r3p1), of size 512 KiB (64 KiB x 8
ways).

Signed-off-by: Geert Uytterhoeven <geert+renesas at glider.be>
---
v4:
  - New,
  - Commit eeedcea69e927857 ("ARM: 8395/1: l2c: Add support for the
    "arm,shared-override" property") is queued for 4.3 in arm/for-next.
---
 arch/arm/boot/dts/sh73a0.dtsi | 16 ++++++++++++++++
 1 file changed, 16 insertions(+)

diff --git a/arch/arm/boot/dts/sh73a0.dtsi b/arch/arm/boot/dts/sh73a0.dtsi
index 11e17c5f26e2cae2..e84fce5e4090f4ab 100644
--- a/arch/arm/boot/dts/sh73a0.dtsi
+++ b/arch/arm/boot/dts/sh73a0.dtsi
@@ -53,6 +53,22 @@
 		      <0xf0000100 0x100>;
 	};
 
+	L2: cache-controller {
+		compatible = "arm,pl310-cache";
+		reg = <0xf0100000 0x1000>;
+		interrupts = <0 44 IRQ_TYPE_LEVEL_HIGH>;
+		power-domains = <&pd_a3sm>;
+		arm,data-latency = <3 3 3>;
+		arm,tag-latency = <2 2 2>;
+		arm,shared-override;
+		cache-unified;
+		cache-level = <2>;
+		cache-size = <0x80000>;
+		cache-sets = <2048>;
+		cache-block-size = <32>;
+		cache-line-size = <32>;
+	};
+
 	sbsc2: memory-controller at fb400000 {
 		compatible = "renesas,sbsc-sh73a0";
 		reg = <0xfb400000 0x400>;
-- 
1.9.1



From olof at lixom.net  Wed Aug  5 02:12:11 2015
From: olof at lixom.net (Olof Johansson)
Date: Wed, 5 Aug 2015 11:12:11 +0200
Subject: [GIT PULL] ARM: mvebu: config changes for v4.3 #2
In-Reply-To: <55BB4240.1060008@free-electrons.com>
References: <55BB4240.1060008@free-electrons.com>
Message-ID: <20150805091211.GM6390@localhost>

On Fri, Jul 31, 2015 at 11:39:12AM +0200, Gregory CLEMENT wrote:
> Hi,
> 
> Here is the second pull request for config change for mvebu for v4.3
> 
> Gregory
> 
> The following changes since commit adfe5f267dd005d0bbe8d71820a7fa38945d08bd:
> 
>   ARM: mvebu: update mvebu_v7_defconfig with features needed for Armada 388 GP (2015-07-09 15:32:55 +0200)
> 
> are available in the git repository at:
> 
>   git://git.infradead.org/linux-mvebu.git tags/mvebu-config-4.3-2
> 
> for you to fetch changes up to 9e07b491bc004259e42739ecd7483ab5a0b8b150:
> 
>   ARM: defconfig: orion5x: add DT support (2015-07-25 16:21:06 +0200)

Merged, thanks.


-Olof


From olof at lixom.net  Wed Aug  5 02:13:08 2015
From: olof at lixom.net (Olof Johansson)
Date: Wed, 5 Aug 2015 11:13:08 +0200
Subject: [PATCH] soc: mediatek: Fix SCPSYS compilation
In-Reply-To: <1438354993-21098-1-git-send-email-matthias.bgg@gmail.com>
References: <1438354993-21098-1-git-send-email-matthias.bgg@gmail.com>
Message-ID: <20150805091308.GN6390@localhost>

On Fri, Jul 31, 2015 at 05:03:13PM +0200, Matthias Brugger wrote:
> SCPSYS driver misses the module.h include which makes it fail
> when compiling with allmodconf.
> 
> This patch fixes this.
> 
> Signed-off-by: Matthias Brugger <matthias.bgg at gmail.com>
> Acked-by: Sascha Hauer <s.hauer at pengutronix.de>

Applied, thanks.


-Olof



From geert+renesas at glider.be  Wed Aug  5 01:58:09 2015
From: geert+renesas at glider.be (Geert Uytterhoeven)
Date: Wed,  5 Aug 2015 10:58:09 +0200
Subject: [PATCH v4 5/6] ARM: shmobile: r8a7740: Migrate to generic l2c OF
 initialization
In-Reply-To: <1438765090-823-1-git-send-email-geert+renesas@glider.be>
References: <1438765090-823-1-git-send-email-geert+renesas@glider.be>
Message-ID: <1438765090-823-6-git-send-email-geert+renesas@glider.be>

Migrate the generic r8a7740 platform from calling l2x0_of_init() to the
generic l2c OF initialization.

Signed-off-by: Geert Uytterhoeven <geert+renesas at glider.be>
---
v4:
  - This depends on commit eeedcea69e927857 ("ARM: 8395/1: l2c: Add
    support for the "arm,shared-override" property"), which is queued
    for 4.3 in arm/for-next,

v3:
  - Use 0/~0 now DT supports "arm,shared-override",

v2:
  - Keep only {,~}L2C_AUX_CTRL_SHARED_OVERRIDE.
---
 arch/arm/mach-shmobile/setup-r8a7740.c | 6 ++----
 1 file changed, 2 insertions(+), 4 deletions(-)

diff --git a/arch/arm/mach-shmobile/setup-r8a7740.c b/arch/arm/mach-shmobile/setup-r8a7740.c
index 0c8f80c5b04df34d..7b16c12e3f816f7f 100644
--- a/arch/arm/mach-shmobile/setup-r8a7740.c
+++ b/arch/arm/mach-shmobile/setup-r8a7740.c
@@ -110,10 +110,6 @@ static void __init r8a7740_generic_init(void)
 {
 	r8a7740_meram_workaround();
 
-#ifdef CONFIG_CACHE_L2X0
-	/* Shared attribute override enable, 32K*8way */
-	l2x0_init(IOMEM(0xf0002000), 0x00400000, 0xc20f0fff);
-#endif
 	of_platform_populate(NULL, of_default_bus_match_table, NULL, NULL);
 }
 
@@ -123,6 +119,8 @@ static const char *const r8a7740_boards_compat_dt[] __initconst = {
 };
 
 DT_MACHINE_START(R8A7740_DT, "Generic R8A7740 (Flattened Device Tree)")
+	.l2c_aux_val	= 0,
+	.l2c_aux_mask	= ~0,
 	.map_io		= r8a7740_map_io,
 	.init_early	= shmobile_init_delay,
 	.init_irq	= r8a7740_init_irq_of,
-- 
1.9.1



From geert+renesas at glider.be  Wed Aug  5 01:58:08 2015
From: geert+renesas at glider.be (Geert Uytterhoeven)
Date: Wed,  5 Aug 2015 10:58:08 +0200
Subject: [PATCH v4 4/6] ARM: shmobile: sh73a0 dtsi: Add L1 cache information
 to CPU nodes
In-Reply-To: <1438765090-823-1-git-send-email-geert+renesas@glider.be>
References: <1438765090-823-1-git-send-email-geert+renesas@glider.be>
Message-ID: <1438765090-823-5-git-send-email-geert+renesas@glider.be>

Describe the L1 caches in the CPU nodes:
  - L1 instruction cache: 32 KiB (8 KiB x 4 ways) per CPU,
  - L1 data cache: 32 KiB (8 KiB x 4 ways) per CPU.

Add links to the L2 cache.

Signed-off-by: Geert Uytterhoeven <geert+renesas at glider.be>
---
v4:
  - New.
---
 arch/arm/boot/dts/sh73a0.dtsi | 18 ++++++++++++++++++
 1 file changed, 18 insertions(+)

diff --git a/arch/arm/boot/dts/sh73a0.dtsi b/arch/arm/boot/dts/sh73a0.dtsi
index e84fce5e4090f4ab..34f45023d1d29ed0 100644
--- a/arch/arm/boot/dts/sh73a0.dtsi
+++ b/arch/arm/boot/dts/sh73a0.dtsi
@@ -28,6 +28,15 @@
 			reg = <0>;
 			clock-frequency = <1196000000>;
 			power-domains = <&pd_a2sl>;
+			i-cache-size = <0x8000>;
+			i-cache-sets = <256>;
+			i-cache-block-size = <32>;
+			i-cache-line-size = <32>;
+			d-cache-size = <0x8000>;
+			d-cache-sets = <256>;
+			d-cache-block-size = <32>;
+			d-cache-line-size = <32>;
+			next-level-cache = <&L2>;
 		};
 		cpu at 1 {
 			device_type = "cpu";
@@ -35,6 +44,15 @@
 			reg = <1>;
 			clock-frequency = <1196000000>;
 			power-domains = <&pd_a2sl>;
+			i-cache-size = <0x8000>;
+			i-cache-sets = <256>;
+			i-cache-block-size = <32>;
+			i-cache-line-size = <32>;
+			d-cache-size = <0x8000>;
+			d-cache-sets = <256>;
+			d-cache-block-size = <32>;
+			d-cache-line-size = <32>;
+			next-level-cache = <&L2>;
 		};
 	};
 
-- 
1.9.1



From olof at lixom.net  Wed Aug  5 02:05:57 2015
From: olof at lixom.net (Olof Johansson)
Date: Wed, 5 Aug 2015 11:05:57 +0200
Subject: [GIT PULL] Xilinx Zynq DT changes for v4.3
In-Reply-To: <55BB3806.7080806@monstr.eu>
References: <55BB3806.7080806@monstr.eu>
Message-ID: <20150805090557.GJ6390@localhost>

On Fri, Jul 31, 2015 at 10:55:34AM +0200, Michal Simek wrote:
> Hi,
> 
> please pull these zynq DT changes to your tree.
> 
> Thanks,
> Michal
> 
> The following changes since commit d770e558e21961ad6cfdf0ff7df0eb5d7d4f0754:
> 
>   Linux 4.2-rc1 (2015-07-05 11:01:52 -0700)
> 
> are available in the git repository at:
> 
>   https://github.com/Xilinx/linux-xlnx.git tags/zynq-dt-for-4.3
> 
> for you to fetch changes up to b76da4d8758995437a831748dfca6f64a0e31c95:
> 
>   ARM: zynq: DT: Add zc702 pushbuttons to DT as gpio-keys (2015-07-31
> 10:50:06 +0200)

Merged, thanks.


-Olof


From geert+renesas at glider.be  Wed Aug  5 01:58:06 2015
From: geert+renesas at glider.be (Geert Uytterhoeven)
Date: Wed,  5 Aug 2015 10:58:06 +0200
Subject: [PATCH v4 2/6] ARM: shmobile: r8a7740 dtsi: Add L1 cache information
 to CPU node
In-Reply-To: <1438765090-823-1-git-send-email-geert+renesas@glider.be>
References: <1438765090-823-1-git-send-email-geert+renesas@glider.be>
Message-ID: <1438765090-823-3-git-send-email-geert+renesas@glider.be>

Describe the L1 cache in the CPU node:
  - L1 instruction cache: 32 KiB (8 KiB x 4 ways),
  - L1 data cache: 32 KiB (8 KiB x 4 ways).

Add a link to the L2 cache.

Signed-off-by: Geert Uytterhoeven <geert+renesas at glider.be>
---
v4:
  - No changes,

v3:
  - No changes,

v2:
  - New.
---
 arch/arm/boot/dts/r8a7740.dtsi | 9 +++++++++
 1 file changed, 9 insertions(+)

diff --git a/arch/arm/boot/dts/r8a7740.dtsi b/arch/arm/boot/dts/r8a7740.dtsi
index ddef5b1c68fa06b3..3aaab195132bfc2c 100644
--- a/arch/arm/boot/dts/r8a7740.dtsi
+++ b/arch/arm/boot/dts/r8a7740.dtsi
@@ -26,6 +26,15 @@
 			reg = <0x0>;
 			clock-frequency = <800000000>;
 			power-domains = <&pd_a3sm>;
+			i-cache-size = <0x8000>;
+			i-cache-sets = <256>;
+			i-cache-block-size = <32>;
+			i-cache-line-size = <32>;
+			d-cache-size = <0x8000>;
+			d-cache-sets = <256>;
+			d-cache-block-size = <32>;
+			d-cache-line-size = <32>;
+			next-level-cache = <&L2>;
 		};
 	};
 
-- 
1.9.1



From geert+renesas at glider.be  Wed Aug  5 01:58:10 2015
From: geert+renesas at glider.be (Geert Uytterhoeven)
Date: Wed,  5 Aug 2015 10:58:10 +0200
Subject: [PATCH v4 6/6] ARM: shmobile: r8a7740: Remove mapping of L2 cache
 controller registers
In-Reply-To: <1438765090-823-1-git-send-email-geert+renesas@glider.be>
References: <1438765090-823-1-git-send-email-geert+renesas@glider.be>
Message-ID: <1438765090-823-7-git-send-email-geert+renesas@glider.be>

Now all r8a7740-based platforms have been migrated to the generic l2c OF
initialization, it's no longer needed to map the L2 cache controller
registers from .map_io().

Signed-off-by: Geert Uytterhoeven <geert+renesas at glider.be>
---
v4:
  - No changes,

v3:
  - No changes,

v2:
  - No changes.
---
 arch/arm/mach-shmobile/setup-r8a7740.c | 12 ------------
 1 file changed, 12 deletions(-)

diff --git a/arch/arm/mach-shmobile/setup-r8a7740.c b/arch/arm/mach-shmobile/setup-r8a7740.c
index 7b16c12e3f816f7f..496569f9d578b863 100644
--- a/arch/arm/mach-shmobile/setup-r8a7740.c
+++ b/arch/arm/mach-shmobile/setup-r8a7740.c
@@ -38,18 +38,6 @@ static struct map_desc r8a7740_io_desc[] __initdata = {
 		.length		= 160 << 20,
 		.type		= MT_DEVICE_NONSHARED
 	},
-#ifdef CONFIG_CACHE_L2X0
-	/*
-	 * for l2x0_init()
-	 * 0xf0100000-0xf0101000 -> 0xf0002000-0xf0003000
-	 */
-	{
-		.virtual	= 0xf0002000,
-		.pfn		= __phys_to_pfn(0xf0100000),
-		.length		= PAGE_SIZE,
-		.type		= MT_DEVICE_NONSHARED
-	},
-#endif
 };
 
 static void __init r8a7740_map_io(void)
-- 
1.9.1



From geert+renesas at glider.be  Wed Aug  5 01:58:05 2015
From: geert+renesas at glider.be (Geert Uytterhoeven)
Date: Wed,  5 Aug 2015 10:58:05 +0200
Subject: [PATCH v4 1/6] ARM: shmobile: r8a7740 dtsi: Add L2 cache-controller
 node
In-Reply-To: <1438765090-823-1-git-send-email-geert+renesas@glider.be>
References: <1438765090-823-1-git-send-email-geert+renesas@glider.be>
Message-ID: <1438765090-823-2-git-send-email-geert+renesas@glider.be>

Add the missing L2 cache-controller node. This will allow migration to
the generic l2c OF initialization.

The L2 cache is an ARM L2C-310 (r3p1-150rel0), of size 256 KiB (32 KiB x
8 ways).

Signed-off-by: Geert Uytterhoeven <geert+renesas at glider.be>
---
v4:
  - Commit eeedcea69e927857 ("ARM: 8395/1: l2c: Add support for the
    "arm,shared-override" property") is queued for 4.3 in arm/for-next,

v3:
  - Add "arm,shared-override",

v2:
  - Fix interrupt (should be 3 cells, not 1),
  - Describe cache better.
---
 arch/arm/boot/dts/r8a7740.dtsi | 16 ++++++++++++++++
 1 file changed, 16 insertions(+)

diff --git a/arch/arm/boot/dts/r8a7740.dtsi b/arch/arm/boot/dts/r8a7740.dtsi
index d84714468cce18df..ddef5b1c68fa06b3 100644
--- a/arch/arm/boot/dts/r8a7740.dtsi
+++ b/arch/arm/boot/dts/r8a7740.dtsi
@@ -37,6 +37,22 @@
 		      <0xc2000000 0x1000>;
 	};
 
+	L2: cache-controller {
+		compatible = "arm,pl310-cache";
+		reg = <0xf0100000 0x1000>;
+		interrupts = <0 84 IRQ_TYPE_LEVEL_HIGH>;
+		power-domains = <&pd_a3sm>;
+		arm,data-latency = <3 3 3>;
+		arm,tag-latency = <2 2 2>;
+		arm,shared-override;
+		cache-unified;
+		cache-level = <2>;
+		cache-size = <0x40000>;
+		cache-sets = <1024>;
+		cache-block-size = <32>;
+		cache-line-size = <32>;
+	};
+
 	dbsc3: memory-controller at fe400000 {
 		compatible = "renesas,dbsc3-r8a7740";
 		reg = <0xfe400000 0x400>;
-- 
1.9.1



From vaibhav.hiremath at linaro.org  Wed Aug  5 02:41:32 2015
From: vaibhav.hiremath at linaro.org (Vaibhav Hiremath)
Date: Wed, 05 Aug 2015 15:11:32 +0530
Subject: [PATCH-v5 1/5] Documentation: binding: add new property
 'disable_after_xfer' to i2c-pxa
In-Reply-To: <20150805084917.GA1523@katana>
References: <1437482466-16126-1-git-send-email-vaibhav.hiremath@linaro.org>
 <1437482466-16126-2-git-send-email-vaibhav.hiremath@linaro.org>
 <20150727140911.GB15004@beef> <55C1AE71.3010700@linaro.org>
 <20150805084917.GA1523@katana>
Message-ID: <55C1DA4C.6040700@linaro.org>



On Wednesday 05 August 2015 02:19 PM, Wolfram Sang wrote:
> I will start such a file today as part of the i2c slave framework
> update which introduces flags to the reg property. Will post to the i2c
> list this week.

Great and thanks for taking this.

I believe, better to wait for your patch and then rebase my patch-
series against it. right?

Request to review the this patch-series, so that I can incorporate all
comments in V6.

Thanks,
Vaibhav


From olof at lixom.net  Wed Aug  5 02:34:57 2015
From: olof at lixom.net (Olof Johansson)
Date: Wed, 5 Aug 2015 11:34:57 +0200
Subject: [PATCH] ARM: davinci: cp_intc: use IRQCHIP_SKIP_SET_WAKE instead
 of irq_set_wake callback
In-Reply-To: <1438443236-30206-1-git-send-email-nsekhar@ti.com>
References: <1435941754-21102-1-git-send-email-sudeep.holla@arm.com>
 <1438443236-30206-1-git-send-email-nsekhar@ti.com>
Message-ID: <20150805093457.GO6390@localhost>

On Sat, Aug 01, 2015 at 09:03:56PM +0530, Sekhar Nori wrote:
> From: Sudeep Holla <sudeep.holla at arm.com>
> 
> Commit 60f96b41f71d ("genirq: Add IRQCHIP_SKIP_SET_WAKE flag")
> introduced a new flag to skip the irq_set_wake callback in the irqchip
> core to avoid adding dummy irq_set_wake in the irqchip implementations.
> 
> This patch removes the dummy callback and sets the IRQCHIP_SKIP_SET_WAKE
> flags.
> 
> Cc: Sekhar Nori <nsekhar at ti.com>
> Cc: Kevin Hilman <khilman at deeprootsystems.com>
> Signed-off-by: Sudeep Holla <sudeep.holla at arm.com>
> Signed-off-by: Sekhar Nori <nsekhar at ti.com>
> ---
> ARM-SoC, can you please apply this patch directly?
> I do not have any other patches queued, so not sending
> a pull request.

Merged, thanks.


-Olof



From marc.zyngier at arm.com  Wed Aug  5 02:44:09 2015
From: marc.zyngier at arm.com (Marc Zyngier)
Date: Wed, 05 Aug 2015 10:44:09 +0100
Subject: [PATCH v3 09/11] KVM: arm/arm64: vgic: Prevent userspace injection
 of a mapped interrupt
In-Reply-To: <55C1BBF9.2060004@linaro.org>
References: <1437753309-17989-1-git-send-email-marc.zyngier@arm.com>
 <1437753309-17989-10-git-send-email-marc.zyngier@arm.com>
 <55C0E690.1090808@linaro.org> <55C0EBF5.2060708@arm.com>
 <55C1BBF9.2060004@linaro.org>
Message-ID: <55C1DAE9.1050609@arm.com>

On 05/08/15 08:32, Eric Auger wrote:
> Hi Marc,
> On 08/04/2015 06:44 PM, Marc Zyngier wrote:
>> On 04/08/15 17:21, Eric Auger wrote:
>>> Hi Marc,
>>> On 07/24/2015 05:55 PM, Marc Zyngier wrote:
>>>> Virtual interrupts mapped to a HW interrupt should only be triggered
>>>> from inside the kernel. Otherwise, you could end up confusing the
>>>> kernel (and the GIC's) state machine.
>>>>
>>>> Rearrange the injection path so that kvm_vgic_inject_irq is
>>>> used for non-mapped interrupts, and kvm_vgic_inject_mapped_irq is
>>>> used for mapped interrupts. The latter should only be called from
>>>> inside the kernel (timer, VFIO).
>>> nit: I would replace VFIO by irqfd.
>>> VFIO just triggers the eventfd/irqfd. This is KVM/irqfd that injects the
>>> virtual irq upon the irqfd signaling and he irqfd adaptation/ARM
>>> currently is implemented in vgic.c
>>
>> Ah, thanks for reminding me of the right terminology, I tend to think of
>> it as one big bag of nasty tricks... ;-)
>>
>> I'll update the commit message.
>>
>>>>
>>>> Signed-off-by: Marc Zyngier <marc.zyngier at arm.com>
>>>> ---
>>>>  include/kvm/arm_vgic.h |  2 +
>>>>  virt/kvm/arm/vgic.c    | 99 ++++++++++++++++++++++++++++++++++----------------
>>>>  2 files changed, 70 insertions(+), 31 deletions(-)
>>>>
>>>> diff --git a/include/kvm/arm_vgic.h b/include/kvm/arm_vgic.h
>>>> index 7306b4b..f6bfd79 100644
>>>> --- a/include/kvm/arm_vgic.h
>>>> +++ b/include/kvm/arm_vgic.h
>>>> @@ -351,6 +351,8 @@ void kvm_vgic_flush_hwstate(struct kvm_vcpu *vcpu);
>>>>  void kvm_vgic_sync_hwstate(struct kvm_vcpu *vcpu);
>>>>  int kvm_vgic_inject_irq(struct kvm *kvm, int cpuid, unsigned int irq_num,
>>>>  			bool level);
>>>> +int kvm_vgic_inject_mapped_irq(struct kvm *kvm, int cpuid,
>>>> +			       struct irq_phys_map *map, bool level);
>>>>  void vgic_v3_dispatch_sgi(struct kvm_vcpu *vcpu, u64 reg);
>>>>  int kvm_vgic_vcpu_pending_irq(struct kvm_vcpu *vcpu);
>>>>  int kvm_vgic_vcpu_active_irq(struct kvm_vcpu *vcpu);
>>>> diff --git a/virt/kvm/arm/vgic.c b/virt/kvm/arm/vgic.c
>>>> index 3f7b690..e40ef70 100644
>>>> --- a/virt/kvm/arm/vgic.c
>>>> +++ b/virt/kvm/arm/vgic.c
>>>> @@ -1533,7 +1533,8 @@ static int vgic_validate_injection(struct kvm_vcpu *vcpu, int irq, int level)
>>>>  }
>>>>  
>>>>  static int vgic_update_irq_pending(struct kvm *kvm, int cpuid,
>>>> -				  unsigned int irq_num, bool level)
>>>> +				   struct irq_phys_map *map,
>>>> +				   unsigned int irq_num, bool level)
>>>>  {
>>> In vgic_update_irq_pending, I needed to modify the following line and
>>> add the "&& !map".
>>>
>>>         if (!vgic_validate_injection(vcpu, irq_num, level) && !map) {
>>>
>>> Without that, the level being not properly modeled for level sensitive
>>> forwarded IRQs, the 2d injection fails.
>>
>> Ah! Is that because we never see the line being reset to zero, and the
>> VGIC still sees the line as pending at the distributor level?
> yes indeed

Then it is a bigger problem we need to solve, and your solution just
papers over the issue.

The main problem is that irqfd is essentially an edge-triggered
signalling. Fire and forget. Given that we're dealing with a level
triggered interrupt, we end up with the interrupt still marked as
pending (nobody took the signal down).

The usual way to get out of that mess in is to evaluate the state of the
level on EOI. But we can't trap on EOI for a HW interrupt.

So it raises the question: should we instead consider the HW pending
state instead of the software one for mapped interrupts? It is
expensive, but it feels more correct.

Thoughts?

	M.
-- 
Jazz is not dead. It just smells funny...


From olof at lixom.net  Wed Aug  5 01:40:34 2015
From: olof at lixom.net (Olof Johansson)
Date: Wed, 5 Aug 2015 10:40:34 +0200
Subject: [PATCH v3] ARM: at91/soc: add basic support for new sama5d2 SoC
In-Reply-To: <1438276332-11094-1-git-send-email-nicolas.ferre@atmel.com>
References: <1438276332-11094-1-git-send-email-nicolas.ferre@atmel.com>
Message-ID: <20150805084034.GC6390@localhost>

On Thu, Jul 30, 2015 at 07:12:12PM +0200, Nicolas Ferre wrote:
> Add Kconfig entries, header file changes and addition to the documentation.
> The early debug infrastructure is also added for easy development.
> 
> Signed-off-by: Ludovic Desroches <ludovic.desroches at atmel.com>
> Signed-off-by: Nicolas Ferre <nicolas.ferre at atmel.com>
> Acked-by: Alexandre Belloni <alexandre.belloni at free-electrons.com>
> ---
> Arnd, Olof, Kevin,
> 
> I'm re-sending this patch as a single one targeted to you as I don't
> have more material for the "soc" of AT91 yet. So I would like you to take
> it out of a Pull-request.
> Alexandre may build one in the coming weeks though.

Applied, thanks.


-Olof


From olof at lixom.net  Wed Aug  5 01:40:55 2015
From: olof at lixom.net (Olof Johansson)
Date: Wed, 5 Aug 2015 10:40:55 +0200
Subject: [PATCH] ARM: at91: at91_dt_defconfig: enable ISI and ov2640
 support
In-Reply-To: <1438276699-11861-1-git-send-email-nicolas.ferre@atmel.com>
References: <1438276699-11861-1-git-send-email-nicolas.ferre@atmel.com>
Message-ID: <20150805084055.GD6390@localhost>

On Thu, Jul 30, 2015 at 07:18:19PM +0200, Nicolas Ferre wrote:
> From: Josh Wu <josh.wu at atmel.com>
> 
> Add Atmel-isi and ov2640 driver in defconfig
> 
> Signed-off-by: Josh Wu <josh.wu at atmel.com>
> [nicolas.ferre at atmel.com: make SOC_CAMERA_OV2640 selected as a module]
> Signed-off-by: Nicolas Ferre <nicolas.ferre at atmel.com>
> ---
> Arnd, Olof, Kevin,
> 
> This is the only "defconfig" patch that I have for now. Can you please take it
> for 4.3?

applied, thanks.


-Olof


From olof at lixom.net  Wed Aug  5 01:40:00 2015
From: olof at lixom.net (Olof Johansson)
Date: Wed, 5 Aug 2015 10:40:00 +0200
Subject: [GIT PULL] at91: dt for 4.3 #1
In-Reply-To: <1438275657-10769-1-git-send-email-nicolas.ferre@atmel.com>
References: <1438275657-10769-1-git-send-email-nicolas.ferre@atmel.com>
Message-ID: <20150805084000.GB6390@localhost>

On Thu, Jul 30, 2015 at 07:00:57PM +0200, Nicolas Ferre wrote:
> Arnd, Olof, Kevin,
> 
> This is the first batch of DT changes for 4.3. The main part of it is the
> addition of a new SoC in the sama5 family: the sama5d2. Here is its product
> .dtsi and the associated sama5d2 Xplained board description.
> I'll send the little C code part of it in another pull-request or as a single
> separated patch as I don't have other material on the "at91-4.3-soc" branch for
> now...
> 
> Thanks, best regards,
> 
> The following changes since commit bc0195aad0daa2ad5b0d76cce22b167bc3435590:
> 
>   Linux 4.2-rc2 (2015-07-12 15:10:30 -0700)
> 
> are available in the git repository at:
> 
>   git://git.kernel.org/pub/scm/linux/kernel/git/nferre/linux-at91.git tags/at91-dt
> 
> for you to fetch changes up to 22b5a0f7bc07ac4b4e4aab9a7f8cf2521819c1c4:
> 
>   ARM: at91/dt: add minimal sama5d2 Xplained board (2015-07-30 18:44:44 +0200)

Merged, thanks.

Also, congrats on getting basic mainline support merged by the time
the part is actually announced and available. I wish more vendors would
follow your lead.


-Olof


From stefano.stabellini at eu.citrix.com  Wed Aug  5 02:49:15 2015
From: stefano.stabellini at eu.citrix.com (Stefano Stabellini)
Date: Wed, 5 Aug 2015 10:49:15 +0100
Subject: [PATCH v2 2/8] xen: Make clear that swiotlb and biomerge are
 dealing with DMA address
In-Reply-To: <1438711972-18752-3-git-send-email-julien.grall@citrix.com>
References: <1438711972-18752-1-git-send-email-julien.grall@citrix.com>
 <1438711972-18752-3-git-send-email-julien.grall@citrix.com>
Message-ID: <alpine.DEB.2.02.1508051041060.11337@kaball.uk.xensource.com>

On Tue, 4 Aug 2015, Julien Grall wrote:
> The swiotlb is required when programming a DMA address on ARM when a
> device is not protected by an IOMMU.
> 
> In this case, the DMA address should always be equal to the machine address.
> For DOM0 memory, Xen ensure it by have an identity mapping between the
> guest address and host address. However, when mapping a foreign grant
> reference, the 1:1 model doesn't work.
> 
> For ARM guest, most of the callers of pfn_to_mfn expects to get a GFN
> (Guest Frame Number), i.e a PFN (Page Frame Number) from the Linux point
> of view given that all ARM guest are auto-translated.
> 
> Even though the name pfn_to_mfn is misleading, we need to ensure that
> those caller get a GFN and not by mistake a MFN. In pratical, I haven't
> seen error related to this but we should fix it for the sake of
> correctness.
> 
> In order to fix the implementation of pfn_to_mfn on ARM in a follow-up
> patch, we have to introduce new helpers to return the DMA from a PFN and
> the invert.
> 
> On x86, the new helpers will be an alias of pfn_to_mfn and mfn_to_pfn.
> 
> The helpers will be used in swiotlb and xen_biovec_phys_mergeable.
> 
> This is necessary in the latter because we have to ensure that the
> biovec code will not try to merge a biovec using foreign page and
> another using Linux memory.
> 
> Lastly, the helper mfn_to_local_pfn has been renamed to dnf_to_local_pfn
                                                          ^ please update


> given that the only usage was in swiotlb.
> 
> Signed-off-by: Julien Grall <julien.grall at citrix.com>
> Cc: Stefano Stabellini <stefano.stabellini at eu.citrix.com>
> Cc: Russell King <linux at arm.linux.org.uk>
> Cc: Konrad Rzeszutek Wilk <konrad.wilk at oracle.com>
> Cc: Boris Ostrovsky <boris.ostrovsky at oracle.com>
> Cc: David Vrabel <david.vrabel at citrix.com>
> Cc: Thomas Gleixner <tglx at linutronix.de>
> Cc: Ingo Molnar <mingo at redhat.com>
> Cc: "H. Peter Anvin" <hpa at zytor.com>
> Cc: x86 at kernel.org
> Cc: linux-arm-kernel at lists.infradead.org
> 
> ---
>     Changes in v2:
>         - Use bfn (Bus Frame Number) rather than dfn to match the
>         proposed terminology for pv-iommu hypercall.
> ---
>  arch/arm/include/asm/xen/page.h | 23 +++++++++++++++++++++--
>  arch/arm/xen/mm.c               |  4 ++--
>  arch/x86/include/asm/xen/page.h |  8 ++++++--
>  drivers/xen/biomerge.c          |  6 +++---
>  drivers/xen/swiotlb-xen.c       | 16 ++++++++--------
>  5 files changed, 40 insertions(+), 17 deletions(-)
> 
> diff --git a/arch/arm/include/asm/xen/page.h b/arch/arm/include/asm/xen/page.h
> index 98b1084..bc5e77c 100644
> --- a/arch/arm/include/asm/xen/page.h
> +++ b/arch/arm/include/asm/xen/page.h
> @@ -52,7 +52,26 @@ static inline unsigned long mfn_to_pfn(unsigned long mfn)
>  	return mfn;
>  }
>  
> -#define mfn_to_local_pfn(mfn) mfn_to_pfn(mfn)
> +/* Pseudo-physical <-> BUS conversion */
> +static inline unsigned long pfn_to_bfn(unsigned long pfn)
> +{
> +	unsigned long mfn;
> +
> +	if (phys_to_mach.rb_node != NULL) {
> +		mfn = __pfn_to_mfn(pfn);
> +		if (mfn != INVALID_P2M_ENTRY)
> +			return mfn;
> +	}
> +
> +	return pfn;
> +}
> +
> +static inline unsigned long bfn_to_pfn(unsigned long bfn)
> +{
> +	return bfn;
> +}
> +
> +#define bfn_to_local_pfn(bfn)	bfn_to_pfn(bfn)
>  
>  /* VIRT <-> MACHINE conversion */
>  #define virt_to_mfn(v)		(pfn_to_mfn(virt_to_pfn(v)))
> @@ -96,7 +115,7 @@ static inline bool set_phys_to_machine(unsigned long pfn, unsigned long mfn)
>  
>  bool xen_arch_need_swiotlb(struct device *dev,
>  			   unsigned long pfn,
> -			   unsigned long mfn);
> +			   unsigned long dfn);
>  unsigned long xen_get_swiotlb_free_pages(unsigned int order);

You missed a bunch of dfn->bfn renamings.

Aside from those and the commit message error:

Reviewed-by: Stefano Stabellini <stefano.stabellini at eu.citrix.com>


>  #endif /* _ASM_ARM_XEN_PAGE_H */
> diff --git a/arch/arm/xen/mm.c b/arch/arm/xen/mm.c
> index 03e75fe..12bde72 100644
> --- a/arch/arm/xen/mm.c
> +++ b/arch/arm/xen/mm.c
> @@ -139,9 +139,9 @@ void __xen_dma_sync_single_for_device(struct device *hwdev,
>  
>  bool xen_arch_need_swiotlb(struct device *dev,
>  			   unsigned long pfn,
> -			   unsigned long mfn)
> +			   unsigned long dfn)
>  {
> -	return (!hypercall_cflush && (pfn != mfn) && !is_device_dma_coherent(dev));
> +	return (!hypercall_cflush && (pfn != dfn) && !is_device_dma_coherent(dev));
>  }
>  
>  int xen_create_contiguous_region(phys_addr_t pstart, unsigned int order,
> diff --git a/arch/x86/include/asm/xen/page.h b/arch/x86/include/asm/xen/page.h
> index c44a5d5..8ba04b8 100644
> --- a/arch/x86/include/asm/xen/page.h
> +++ b/arch/x86/include/asm/xen/page.h
> @@ -178,6 +178,10 @@ static inline xpaddr_t machine_to_phys(xmaddr_t machine)
>  	return XPADDR(PFN_PHYS(mfn_to_pfn(PFN_DOWN(machine.maddr))) | offset);
>  }
>  
> +/* Pseudo-physical <-> Bus conversion */
> +#define pfn_to_bfn(pfn)		pfn_to_mfn(pfn)
> +#define bfn_to_pfn(bfn)		mfn_to_pfn(bfn)
> +
>  /*
>   * We detect special mappings in one of two ways:
>   *  1. If the MFN is an I/O page then Xen will set the m2p entry
> @@ -198,7 +202,7 @@ static inline xpaddr_t machine_to_phys(xmaddr_t machine)
>   *      require. In all the cases we care about, the FOREIGN_FRAME bit is
>   *      masked (e.g., pfn_to_mfn()) so behaviour there is correct.
>   */
> -static inline unsigned long mfn_to_local_pfn(unsigned long mfn)
> +static inline unsigned long bfn_to_local_pfn(unsigned long mfn)
>  {
>  	unsigned long pfn;
>  
> @@ -264,7 +268,7 @@ void make_lowmem_page_readwrite(void *vaddr);
>  
>  static inline bool xen_arch_need_swiotlb(struct device *dev,
>  					 unsigned long pfn,
> -					 unsigned long mfn)
> +					 unsigned long bfn)
>  {
>  	return false;
>  }
> diff --git a/drivers/xen/biomerge.c b/drivers/xen/biomerge.c
> index 0edb91c..8ae2fc90 100644
> --- a/drivers/xen/biomerge.c
> +++ b/drivers/xen/biomerge.c
> @@ -6,10 +6,10 @@
>  bool xen_biovec_phys_mergeable(const struct bio_vec *vec1,
>  			       const struct bio_vec *vec2)
>  {
> -	unsigned long mfn1 = pfn_to_mfn(page_to_pfn(vec1->bv_page));
> -	unsigned long mfn2 = pfn_to_mfn(page_to_pfn(vec2->bv_page));
> +	unsigned long bfn1 = pfn_to_bfn(page_to_pfn(vec1->bv_page));
> +	unsigned long bfn2 = pfn_to_bfn(page_to_pfn(vec2->bv_page));
>  
>  	return __BIOVEC_PHYS_MERGEABLE(vec1, vec2) &&
> -		((mfn1 == mfn2) || ((mfn1+1) == mfn2));
> +		((bfn1 == bfn2) || ((bfn1+1) == bfn2));
>  }
>  EXPORT_SYMBOL(xen_biovec_phys_mergeable);
> diff --git a/drivers/xen/swiotlb-xen.c b/drivers/xen/swiotlb-xen.c
> index 4c54932..d757a3e 100644
> --- a/drivers/xen/swiotlb-xen.c
> +++ b/drivers/xen/swiotlb-xen.c
> @@ -82,8 +82,8 @@ static u64 start_dma_addr;
>   */
>  static inline dma_addr_t xen_phys_to_bus(phys_addr_t paddr)
>  {
> -	unsigned long mfn = pfn_to_mfn(PFN_DOWN(paddr));
> -	dma_addr_t dma = (dma_addr_t)mfn << PAGE_SHIFT;
> +	unsigned long bfn = pfn_to_bfn(PFN_DOWN(paddr));
> +	dma_addr_t dma = (dma_addr_t)bfn << PAGE_SHIFT;
>  
>  	dma |= paddr & ~PAGE_MASK;
>  
> @@ -92,7 +92,7 @@ static inline dma_addr_t xen_phys_to_bus(phys_addr_t paddr)
>  
>  static inline phys_addr_t xen_bus_to_phys(dma_addr_t baddr)
>  {
> -	unsigned long pfn = mfn_to_pfn(PFN_DOWN(baddr));
> +	unsigned long pfn = bfn_to_pfn(PFN_DOWN(baddr));
>  	dma_addr_t dma = (dma_addr_t)pfn << PAGE_SHIFT;
>  	phys_addr_t paddr = dma;
>  
> @@ -110,15 +110,15 @@ static int check_pages_physically_contiguous(unsigned long pfn,
>  					     unsigned int offset,
>  					     size_t length)
>  {
> -	unsigned long next_mfn;
> +	unsigned long next_bfn;
>  	int i;
>  	int nr_pages;
>  
> -	next_mfn = pfn_to_mfn(pfn);
> +	next_bfn = pfn_to_bfn(pfn);
>  	nr_pages = (offset + length + PAGE_SIZE-1) >> PAGE_SHIFT;
>  
>  	for (i = 1; i < nr_pages; i++) {
> -		if (pfn_to_mfn(++pfn) != ++next_mfn)
> +		if (pfn_to_bfn(++pfn) != ++next_bfn)
>  			return 0;
>  	}
>  	return 1;
> @@ -138,8 +138,8 @@ static inline int range_straddles_page_boundary(phys_addr_t p, size_t size)
>  
>  static int is_xen_swiotlb_buffer(dma_addr_t dma_addr)
>  {
> -	unsigned long mfn = PFN_DOWN(dma_addr);
> -	unsigned long pfn = mfn_to_local_pfn(mfn);
> +	unsigned long bfn = PFN_DOWN(dma_addr);
> +	unsigned long pfn = bfn_to_local_pfn(bfn);
>  	phys_addr_t paddr;
>  
>  	/* If the address is outside our domain, it CAN
> -- 
> 2.1.4
> 


From stefano.stabellini at eu.citrix.com  Wed Aug  5 02:52:45 2015
From: stefano.stabellini at eu.citrix.com (Stefano Stabellini)
Date: Wed, 5 Aug 2015 10:52:45 +0100
Subject: [PATCH v2 3/8] arm/xen: implement correctly pfn_to_mfn
In-Reply-To: <1438711972-18752-4-git-send-email-julien.grall@citrix.com>
References: <1438711972-18752-1-git-send-email-julien.grall@citrix.com>
 <1438711972-18752-4-git-send-email-julien.grall@citrix.com>
Message-ID: <alpine.DEB.2.02.1508051050330.11337@kaball.uk.xensource.com>

On Tue, 4 Aug 2015, Julien Grall wrote:
> After the commit introducing convertion between DMA and guest address,
                                                                  ^ addresses

> all the callers of pfn_to_mfn are expecting to get a GFN (Guest Frame
> Number). On ARM, all the guests are auto-translated so the GFN is equal
> to the Linux PFN (Pseudo-physical Frame Number).
> 
> The current implementation may return an MFN if the caller is passing a
> PFN associated to a mapped foreign grant. In pratical, I haven't seen
                                               ^ practice


> the problem on running guest but we should fix it for the sake of
> correctness.
> 
> Correct the implementation by always returning the pfn passed in parameter.
> 
> A follow-up patch will take care to rename pfn_to_mfn to a suitable
> name.
> 
> Signed-off-by: Julien Grall <julien.grall at citrix.com>
> Cc: Stefano Stabellini <stefano.stabellini at eu.citrix.com>
> Cc: Russell King <linux at arm.linux.org.uk>
> Cc: linux-arm-kernel at lists.infradead.org

Reviewed-by: Stefano Stabellini <stefano.stabellini at eu.citrix.com>


>  arch/arm/include/asm/xen/page.h | 8 --------
>  1 file changed, 8 deletions(-)
> 
> diff --git a/arch/arm/include/asm/xen/page.h b/arch/arm/include/asm/xen/page.h
> index bc5e77c..087d86e 100644
> --- a/arch/arm/include/asm/xen/page.h
> +++ b/arch/arm/include/asm/xen/page.h
> @@ -36,14 +36,6 @@ extern struct rb_root phys_to_mach;
>  
>  static inline unsigned long pfn_to_mfn(unsigned long pfn)
>  {
> -	unsigned long mfn;
> -
> -	if (phys_to_mach.rb_node != NULL) {
> -		mfn = __pfn_to_mfn(pfn);
> -		if (mfn != INVALID_P2M_ENTRY)
> -			return mfn;
> -	}
> -
>  	return pfn;
>  }
>  
> -- 
> 2.1.4
> 


From sudeep.holla at arm.com  Wed Aug  5 02:59:27 2015
From: sudeep.holla at arm.com (Sudeep Holla)
Date: Wed, 05 Aug 2015 10:59:27 +0100
Subject: [PATCH v6 0/8] ARM64: juno: add SCPI mailbox protocol, clock
 and CPUFreq support
In-Reply-To: <1438364591-1144-1-git-send-email-sudeep.holla@arm.com>
References: <1438364591-1144-1-git-send-email-sudeep.holla@arm.com>
Message-ID: <55C1DE7F.5040002@arm.com>

Hi Olof,

On 31/07/15 18:43, Sudeep Holla wrote:
> Hi ARM-SoC guys,
>
> It has been on the list for a while and have got all the necessary
> ACKs. Can you please pull this series for v4.3 ?
>

Can you pull this patch series directly from the mail or do you prefer
pull-request ?

Regards,
Sudeep


From tony at atomide.com  Wed Aug  5 03:00:09 2015
From: tony at atomide.com (Tony Lindgren)
Date: Wed, 5 Aug 2015 03:00:09 -0700
Subject: [PATCH 0/4] omap: Fix broken pbias device creation
In-Reply-To: <55B89590.6000109@ti.com>
References: <1437999401-3519-1-git-send-email-kishon@ti.com>
 <55B89590.6000109@ti.com>
Message-ID: <20150805100009.GY16878@atomide.com>

* Grygorii Strashko <grygorii.strashko at ti.com> [150729 02:01]:
> On 07/27/2015 03:16 PM, Kishon Vijay Abraham I wrote:
> >pbias device creation got broken once SCM cleanup got merged.
> >This patch series re-enables device creation by adding
> >"simple-bus" in the compatible property of the syscon
> >dt node.
> >
> >validated this series in DRA72, OMAP4 PANDA and OMAP5 UEVM
> >boards.
> >
> >Kishon Vijay Abraham I (4):
> >   ARM: dts: omap24xx: Fix broken pbias device creation
> >   ARM: dts: OMAP4: Fix broken pbias device creation
> >   ARM: dts: OMAP5: Fix broken pbias device creation
> >   ARM: dts: dra7: Fix broken pbias device creation
> >
> >  arch/arm/boot/dts/dra7.dtsi     |    2 +-
> >  arch/arm/boot/dts/omap2430.dtsi |    3 ++-
> >  arch/arm/boot/dts/omap4.dtsi    |    3 ++-
> >  arch/arm/boot/dts/omap5.dtsi    |    3 ++-
> >  4 files changed, 7 insertions(+), 4 deletions(-)
> >
> 
> For dra7-evm:
> Tested-by: Grygorii Strashko <grygorii.strashko at ti.com>

Applying all into omap-for-v4.2fixes-v2 thanks.

Tony


From pbrobinson at gmail.com  Wed Aug  5 03:01:01 2015
From: pbrobinson at gmail.com (Peter Robinson)
Date: Wed, 5 Aug 2015 11:01:01 +0100
Subject: arm kernel oops in highmem.c with 4.2
Message-ID: <CALeDE9Ox3=sh3AXQ0NUG6BBfU5i5YrMY=LDpcTHQWqz2=60F2g@mail.gmail.com>

Hi All,

On Fedora 23 with recent 4.2 kernels we're seeing a crash (below) in
highmem.c on a fairly regular occurrence across a number of different
SoCs, I've seen it with at least AllWinner A20, i.MX6Q, Tegra2 and 124
with both a LPAE and non LPAE kernel, seen it happen when doing a
number of different things but regenerating a initrd, applying updates
(dnf/yum) and starting X are all pretty good triggers.

I've not seen anyone else report anything similar so I'm wondering if
anyone can give me some assistance and direction in getting to the
bottom of this.

Peter

[71751.658105] ------------[ cut here ]------------
[71751.658153] kernel BUG at arch/arm/mm/highmem.c:114!
[71751.658176] Internal error: Oops - BUG: 0 [#1] SMP ARM
[71751.658200] Modules linked in: fuse ofpart snd_soc_tegra30_i2s
snd_soc_tegra_pcm m25p80 spi_nor mtd snd_hda_codec_hdmi uvcvideo
videobuf2_vmalloc videobuf2_memops videobuf2_core v4l2_common videodev
snd_usb_audio snd_usbmidi_lib media snd_rawmidi snd_hda_tegra
snd_soc_rt5640 snd_soc_tegra_rt5640 snd_soc_tegra_utils snd_hda_codec
snd_soc_rl6231 snd_hda_core snd_hwdep snd_soc_tegra30_ahub
snd_soc_core snd_compress snd_pcm_dmaengine ac97_bus snd_seq
snd_seq_device snd_pcm snd_timer snd soundcore tegra_soctherm r8169
nouveau lm90 mii at24 i2c_algo_bit spi_tegra114 ttm tegra_devfreq nfsd
uas usb_storage mmc_block as3722_regulator ehci_tegra gpio_keys
phy_tegra_usb sdhci_tegra sdhci_pltfm sdhci mmc_core ahci_tegra
libahci_platform rtc_tegra i2c_tegra tegra_drm drm_kms_helper
syscopyarea sysfillrect sysimgblt
[71751.659048]  drm host1x
[71751.659099] CPU: 0 PID: 7723 Comm: applydeltarpm Not tainted
4.2.0-0.rc5.git0.1.fc23.armv7hl #1
[71751.659122] Hardware name: NVIDIA Tegra SoC (Flattened Device Tree)
[71751.659148] task: e3482280 ti: e33a8000 task.ti: e33a8000
[71751.659189] PC is at __kunmap_atomic+0x54/0x178
[71751.659222] LR is at copy_page_to_iter+0x15c/0x258
[71751.659246] pc : [<c0222f84>]    lr : [<c052dcf0>]    psr: 800d0013
               sp : e33a9e58  ip : 0000000c  fp : 014791d4
[71751.659269] r10: e33a9f0c  r9 : e33a9f14  r8 : 00001000
[71751.659290] r7 : ffee0000  r6 : 00000000  r5 : c0d48554  r4 : ffedf000
[71751.659310] r3 : fffff000  r2 : fff00000  r1 : 2d84a000  r0 : ffedf000
[71751.659335] Flags: Nzcv  IRQs on  FIQs on  Mode SVC_32  ISA ARM  Segment user
[71751.659360] Control: 10c5387d  Table: ab7fc06a  DAC: 00000015
[71751.659385] Process applydeltarpm (pid: 7723, stack limit = 0xe33a8220)
[71751.659406] Stack: (0xe33a9e58 to 0xe33aa000)
[71751.659428] 9e40:
    e33a9f0c 0000152c
[71751.659454] 9e60: 00000000 c052dcf0 ef43fd1c ffedf000 00001000
00000002 e3451e40 dcc22164
[71751.659482] 9e80: ef43fd1c 00000000 00001000 e33a9f28 0000052c
c032ad54 00000008 00000002
[71751.659506] 9ea0: e33a9f14 00000001 00000000 dcc22078 e3451ea8
00000004 0000f51e 00000000
[71751.659528] 9ec0: ecc67c38 c08d8fd4 c0514dcc c02a6040 ec856e88
00000000 ee5a8480 e3451e40
[71751.659548] 9ee0: 00000000 e33a9f88 00002000 c020fae4 e33a8000
00000000 00000000 c037fe88
[71751.659571] 9f00: 00002000 c020fae4 e33a8000 01478ca8 00002000
00000000 0000052c 00001ad4
[71751.659593] 9f20: e33a9f0c 00000001 e3451e40 00000000 00001ad4
00000000 00000000 00000000
[71751.659615] 9f40: 00000000 00000000 00da0d20 01478ca8 e3451e40
e33a9f88 00002000 c0380550
[71751.659638] 9f60: e3451e40 01478ca8 00002000 e3451e40 e3451e40
01478ca8 00002000 c020fae4
[71751.659660] 9f80: e33a8000 c0380e04 00001ad4 00000000 00002000
01434260 01478ca8 00002000
[71751.659682] 9fa0: 00000003 c020f960 01434260 01478ca8 0000000d
01478ca8 00002000 01478c78
[71751.659706] 9fc0: 01434260 01478ca8 00002000 00000003 00001ad4
00000000 00024000 00000000
[71751.659729] 9fe0: 00000000 be984f14 00015724 b6e435b0 600f0010
0000000d 00000000 00000000
[71751.659782] [<c0222f84>] (__kunmap_atomic) from [<c052dcf0>]
(copy_page_to_iter+0x15c/0x258)
[71751.659822] [<c052dcf0>] (copy_page_to_iter) from [<c032ad54>]
(generic_file_read_iter+0x370/0x5dc)
[71751.659857] [<c032ad54>] (generic_file_read_iter) from [<c037fe88>]
(__vfs_read+0xb0/0xd8)
[71751.659885] [<c037fe88>] (__vfs_read) from [<c0380550>] (vfs_read+0x8c/0x13c)
[71751.659906] [<c0380550>] (vfs_read) from [<c0380e04>] (SyS_read+0x48/0x88)
[71751.659938] [<c0380e04>] (SyS_read) from [<c020f960>]
(ret_fast_syscall+0x0/0x3c)
[71751.659965] Code: e1a03603 e0632002 e1540002 0a000000 (e7f001f2)
[71751.659992] ---[ end trace 701c1dbef773d4cc ]---
[71756.135495] ------------[ cut here ]------------
[71756.135540] kernel BUG at arch/arm/mm/highmem.c:114!
[71756.135562] Internal error: Oops - BUG: 0 [#2] SMP ARM
[71756.135582] Modules linked in: fuse ofpart snd_soc_tegra30_i2s
snd_soc_tegra_pcm m25p80 spi_nor mtd snd_hda_codec_hdmi uvcvideo
videobuf2_vmalloc videobuf2_memops videobuf2_core v4l2_common videodev
snd_usb_audio snd_usbmidi_lib media snd_rawmidi snd_hda_tegra
snd_soc_rt5640 snd_soc_tegra_rt5640 snd_soc_tegra_utils snd_hda_codec
snd_soc_rl6231 snd_hda_core snd_hwdep snd_soc_tegra30_ahub
snd_soc_core snd_compress snd_pcm_dmaengine ac97_bus snd_seq
snd_seq_device snd_pcm snd_timer snd soundcore tegra_soctherm r8169
nouveau lm90 mii at24 i2c_algo_bit spi_tegra114 ttm tegra_devfreq nfsd
uas usb_storage mmc_block as3722_regulator ehci_tegra gpio_keys
phy_tegra_usb sdhci_tegra sdhci_pltfm sdhci mmc_core ahci_tegra
libahci_platform rtc_tegra i2c_tegra tegra_drm drm_kms_helper
syscopyarea sysfillrect sysimgblt
[71756.136307]  drm host1x
[71756.136347] CPU: 1 PID: 7707 Comm: dnf Tainted: G      D
4.2.0-0.rc5.git0.1.fc23.armv7hl #1
[71756.136365] Hardware name: NVIDIA Tegra SoC (Flattened Device Tree)
[71756.136386] task: ea187300 ti: e3386000 task.ti: e3386000
[71756.136439] PC is at __kunmap_atomic+0x54/0x178
[71756.136470] LR is at copy_page_to_iter+0x15c/0x258
[71756.136490] pc : [<c0222f84>]    lr : [<c052dcf0>]    psr: 800d0013
               sp : e3387e58  ip : 000000ef  fp : be81f8a4
[71756.136511] r10: e3387f0c  r9 : e3387f14  r8 : 000002cc
[71756.136530] r7 : ffecf2cc  r6 : 00000000  r5 : c0d48554  r4 : ffecf000
[71756.136545] r3 : 0000f000  r2 : ffef0000  r1 : 2d856000  r0 : ffecf000
[71756.136567] Flags: Nzcv  IRQs on  FIQs on  Mode SVC_32  ISA ARM  Segment user
[71756.136587] Control: 10c5387d  Table: a33cc06a  DAC: 00000015
[71756.136605] Process dnf (pid: 7707, stack limit = 0xe3386220)
[71756.136620] Stack: (0xe3387e58 to 0xe3388000)
[71756.136638] 7e40:
    e3387f0c 000002cc
[71756.136660] 7e60: 00000000 c052dcf0 ef4047c0 ffecf000 000002cc
00000041 ea5a5300 dcc98184
[71756.136682] 7e80: ef4047c0 00000000 000002cc e3387f28 00000000
c032ad54 edfb61c0 c04b6784
[71756.136703] 7ea0: e3387f14 00000040 00000000 dcc98098 ea5a5368
00000042 000412cb 00000000
[71756.136724] 7ec0: 00000000 00000000 ee5b8180 0000b661 edfb6208
00000000 edfb61c0 ea5a5300
[71756.136744] 7ee0: 00000000 e3387f88 00000800 c020fae4 e3386000
00000000 00000004 c037fe88
[71756.136762] 7f00: 00000800 c020fae4 e3386000 be81f8a4 00000800
00000000 00000000 00000800
[71756.136781] 7f20: e3387f0c 00000001 ea5a5300 00000000 00041000
00000000 00000000 00000000
[71756.136803] 7f40: 00000000 00000000 dcc98098 be81f8a4 ea5a5300
e3387f88 00000800 c0380550
[71756.136821] 7f60: ea5a5300 be81f8a4 00000800 ea5a5300 ea5a5302
be81f8a4 00000800 c020fae4
[71756.136841] 7f80: e3386000 c0380e04 00041000 00000000 00000800
be81f8a4 800cb0b8 00000015
[71756.136861] 7fa0: 00000003 c020f960 be81f8a4 800cb0b8 00000015
be81f8a4 00000800 b84c5a6d
[71756.136879] 7fc0: be81f8a4 800cb0b8 00000015 00000003 00000001
b6f97c80 7fe6d3e8 00000004
[71756.136899] 7fe0: 00000000 be81f850 b6f94860 b6d0cad8 800f0010
00000015 00000000 00000000
[71756.136944] [<c0222f84>] (__kunmap_atomic) from [<c052dcf0>]
(copy_page_to_iter+0x15c/0x258)
[71756.136985] [<c052dcf0>] (copy_page_to_iter) from [<c032ad54>]
(generic_file_read_iter+0x370/0x5dc)
[71756.137020] [<c032ad54>] (generic_file_read_iter) from [<c037fe88>]
(__vfs_read+0xb0/0xd8)
[71756.137045] [<c037fe88>] (__vfs_read) from [<c0380550>] (vfs_read+0x8c/0x13c)
[71756.137069] [<c0380550>] (vfs_read) from [<c0380e04>] (SyS_read+0x48/0x88)
[71756.137102] [<c0380e04>] (SyS_read) from [<c020f960>]
(ret_fast_syscall+0x0/0x3c)
[71756.137127] Code: e1a03603 e0632002 e1540002 0a000000 (e7f001f2)
[71756.137151] ---[ end trace 701c1dbef773d4cd ]---


From linux at arm.linux.org.uk  Wed Aug  5 02:44:30 2015
From: linux at arm.linux.org.uk (Russell King - ARM Linux)
Date: Wed, 5 Aug 2015 10:44:30 +0100
Subject: [PATCH v3 5/8] ARM: mediatek: add smp bringup code for MT6580
In-Reply-To: <1438696464-59858-6-git-send-email-scott.shu@mediatek.com>
References: <1438696464-59858-1-git-send-email-scott.shu@mediatek.com>
 <1438696464-59858-6-git-send-email-scott.shu@mediatek.com>
Message-ID: <20150805094429.GU7557@n2100.arm.linux.org.uk>

On Tue, Aug 04, 2015 at 09:54:21PM +0800, Scott Shu wrote:
> Add support for cpu enable-method "mediatek,mt6580-smp" for booting
> secondary CPUs on MT6580.

If you have CPU power domain support, and you power up and power down the
CPUs, why do you need the boot_lock and pen_release stuff?  Isn't keeping
the power off on a CPU sufficient to prevent it entering the kernel?

-- 
FTTC broadband for 0.8mile line: currently at 10.5Mbps down 400kbps up
according to speedtest.net.


From linux at arm.linux.org.uk  Wed Aug  5 03:07:01 2015
From: linux at arm.linux.org.uk (Russell King - ARM Linux)
Date: Wed, 5 Aug 2015 11:07:01 +0100
Subject: arm kernel oops in highmem.c with 4.2
In-Reply-To: <CALeDE9Ox3=sh3AXQ0NUG6BBfU5i5YrMY=LDpcTHQWqz2=60F2g@mail.gmail.com>
References: <CALeDE9Ox3=sh3AXQ0NUG6BBfU5i5YrMY=LDpcTHQWqz2=60F2g@mail.gmail.com>
Message-ID: <20150805100701.GV7557@n2100.arm.linux.org.uk>

On Wed, Aug 05, 2015 at 11:01:01AM +0100, Peter Robinson wrote:
> Hi All,
> 
> On Fedora 23 with recent 4.2 kernels we're seeing a crash (below) in
> highmem.c on a fairly regular occurrence across a number of different
> SoCs, I've seen it with at least AllWinner A20, i.MX6Q, Tegra2 and 124
> with both a LPAE and non LPAE kernel, seen it happen when doing a
> number of different things but regenerating a initrd, applying updates
> (dnf/yum) and starting X are all pretty good triggers.

I've yet to see any problems with mainline 4.2-rc5 kernels on any of my
iMX6 platforms, which includes initramfs regeneration, apt-get updates
and X.

> [71751.658105] ------------[ cut here ]------------
> [71751.658153] kernel BUG at arch/arm/mm/highmem.c:114!

Well, in mainline kernels, the BUG is on line 113, not line 114.  So at
least this file is modified from mainline kernels.  Maybe the problem is
caused by patches applied to Fedora kernels?

-- 
FTTC broadband for 0.8mile line: currently at 10.5Mbps down 400kbps up
according to speedtest.net.


From stefano.stabellini at eu.citrix.com  Wed Aug  5 03:07:56 2015
From: stefano.stabellini at eu.citrix.com (Stefano Stabellini)
Date: Wed, 5 Aug 2015 11:07:56 +0100
Subject: [PATCH v2 4/8] xen: Use the correctly the Xen memory terminologies
In-Reply-To: <55C147DD.7000600@oracle.com>
References: <1438711972-18752-1-git-send-email-julien.grall@citrix.com>
 <1438711972-18752-5-git-send-email-julien.grall@citrix.com>
 <55C147DD.7000600@oracle.com>
Message-ID: <alpine.DEB.2.02.1508051106420.11337@kaball.uk.xensource.com>

On Tue, 4 Aug 2015, Boris Ostrovsky wrote:
> On 08/04/2015 02:12 PM, Julien Grall wrote:
> >     /*
> >    * We detect special mappings in one of two ways:
> > @@ -217,9 +232,13 @@ static inline unsigned long bfn_to_local_pfn(unsigned
> > long mfn)
> >     /* VIRT <-> MACHINE conversion */
> >   #define virt_to_machine(v)	(phys_to_machine(XPADDR(__pa(v))))
> > -#define virt_to_pfn(v)          (PFN_DOWN(__pa(v)))
> >   #define virt_to_mfn(v)		(pfn_to_mfn(virt_to_pfn(v)))
> >   #define mfn_to_virt(m)		(__va(mfn_to_pfn(m) << PAGE_SHIFT))
> > +#define virt_to_pfn(v)          (PFN_DOWN(__pa(v)))
> 
> This looks like unnecessary change.
> 
> 
> > diff --git a/drivers/video/fbdev/xen-fbfront.c
> > b/drivers/video/fbdev/xen-fbfront.c
> > index 09dc447..25e3cce 100644
> > --- a/drivers/video/fbdev/xen-fbfront.c
> > +++ b/drivers/video/fbdev/xen-fbfront.c
> > @@ -539,7 +539,7 @@ static int xenfb_remove(struct xenbus_device *dev)
> >     static unsigned long vmalloc_to_mfn(void *address)
> >   {
> > -	return pfn_to_mfn(vmalloc_to_pfn(address));
> > +	return pfn_to_gfn(vmalloc_to_pfn(address));
> >   }
> 
> Are you sure? This will return vmalloc_to_pfn(address)).

I think that is OK: there is no behavioural change here.


From stefano.stabellini at eu.citrix.com  Wed Aug  5 03:08:55 2015
From: stefano.stabellini at eu.citrix.com (Stefano Stabellini)
Date: Wed, 5 Aug 2015 11:08:55 +0100
Subject: [PATCH v2 4/8] xen: Use the correctly the Xen memory terminologies
In-Reply-To: <1438711972-18752-5-git-send-email-julien.grall@citrix.com>
References: <1438711972-18752-1-git-send-email-julien.grall@citrix.com>
 <1438711972-18752-5-git-send-email-julien.grall@citrix.com>
Message-ID: <alpine.DEB.2.02.1508051108100.11337@kaball.uk.xensource.com>

On Tue, 4 Aug 2015, Julien Grall wrote:
> Based on include/xen/mm.h [1], Linux is mistakenly using MFN when GFN
> is meant, I suspect this is because the first support for Xen was for
> PV. This resulted in some misimplementation of helpers on ARM and
> confused developers about the expected behavior.
> 
> For instance, with pfn_to_mfn, we expect to get an MFN based on the name.
> Although, if we look at the implementation on x86, it's returning a GFN.
> 
> For clarity and avoid new confusion, replace any reference to mfn with
> gfn in any helpers used by PV drivers. The x86 code will still keep some
> reference of pfn_to_mfn but exclusively for PV (a BUG_ON has been added
> to ensure this). No changes as been made in the hypercall field, even
> though they may be invalid, in order to keep the same as the defintion
> in xen repo.
> 
> Take also the opportunity to simplify simple construction such
> as pfn_to_mfn(page_to_pfn(page)) into page_to_gfn. More complex clean up
> will come in follow-up patches.
> 
> [1] http://xenbits.xen.org/gitweb/?p=xen.git;a=commitdiff;h=e758ed14f390342513405dd766e874934573e6cb
> 
> Signed-off-by: Julien Grall <julien.grall at citrix.com>
> Cc: Stefano Stabellini <stefano.stabellini at eu.citrix.com>
> Cc: Russell King <linux at arm.linux.org.uk>
> Cc: Konrad Rzeszutek Wilk <konrad.wilk at oracle.com>
> Cc: Boris Ostrovsky <boris.ostrovsky at oracle.com>
> Cc: David Vrabel <david.vrabel at citrix.com>
> Cc: Thomas Gleixner <tglx at linutronix.de>
> Cc: Ingo Molnar <mingo at redhat.com>
> Cc: "H. Peter Anvin" <hpa at zytor.com>
> Cc: x86 at kernel.org
> Cc: "Roger Pau Monn?" <roger.pau at citrix.com>
> Cc: Dmitry Torokhov <dmitry.torokhov at gmail.com>
> Cc: Ian Campbell <ian.campbell at citrix.com>
> Cc: Wei Liu <wei.liu2 at citrix.com>
> Cc: Juergen Gross <jgross at suse.com>
> Cc: "James E.J. Bottomley" <JBottomley at odin.com>
> Cc: Greg Kroah-Hartman <gregkh at linuxfoundation.org>
> Cc: Jiri Slaby <jslaby at suse.com>
> Cc: Jean-Christophe Plagniol-Villard <plagnioj at jcrosoft.com>
> Cc: Tomi Valkeinen <tomi.valkeinen at ti.com>
> Cc: linux-input at vger.kernel.org
> Cc: netdev at vger.kernel.org
> Cc: linux-scsi at vger.kernel.org
> Cc: linuxppc-dev at lists.ozlabs.org
> Cc: linux-fbdev at vger.kernel.org
> Cc: linux-arm-kernel at lists.infradead.org

Aside from the x86 bits:

Reviewed-by: Stefano Stabellini <stefano.stabellini at eu.citrix.com>


>     Note that I've re-introduced mfn_to_pfn & co only for x86 PV code.
>     The helpers contain a BUG_ON to ensure that it's never called for
>     auto-translated guests. I did as best as my can to determine whether
>     mfn or gfn helpers should be used. Although, I haven't tried to boot
>     it.
> 
>     It may be possible to do further cleanup in the mmu.c where I found
>     some check to auto-translated. I'm not sure why given that the pvmmu
>     callback are only used for non-auto translated guest.
> 
>     Finally, given those changes, I didn't retain the Reviewed-by/Acked-by.
> 
>     Changes in v2:
>         - Give directly the URL to the commit rather than the commit ID
>         - xenstored_local_init: keep the cast to void *
>         - Typoes
>         - Keep pfn_to_mfn for x86 and PV-only. The *mfn* helpers are
>         used in arch/x86/xen for enlighten.c, mmu.c, p2m.c, setup.c,
>         smp.c and mm.c
> ---
>  arch/arm/include/asm/xen/page.h         | 13 +++++++------
>  arch/x86/include/asm/xen/page.h         | 33 ++++++++++++++++++++++++++-------
>  arch/x86/xen/smp.c                      |  2 +-
>  drivers/block/xen-blkfront.c            |  6 +++---
>  drivers/input/misc/xen-kbdfront.c       |  4 ++--
>  drivers/net/xen-netback/netback.c       |  4 ++--
>  drivers/net/xen-netfront.c              |  8 ++++----
>  drivers/scsi/xen-scsifront.c            |  8 +++-----
>  drivers/tty/hvc/hvc_xen.c               |  5 +++--
>  drivers/video/fbdev/xen-fbfront.c       |  4 ++--
>  drivers/xen/balloon.c                   |  2 +-
>  drivers/xen/events/events_base.c        |  2 +-
>  drivers/xen/events/events_fifo.c        |  4 ++--
>  drivers/xen/gntalloc.c                  |  3 ++-
>  drivers/xen/manage.c                    |  2 +-
>  drivers/xen/tmem.c                      |  4 ++--
>  drivers/xen/xenbus/xenbus_client.c      |  2 +-
>  drivers/xen/xenbus/xenbus_dev_backend.c |  2 +-
>  drivers/xen/xenbus/xenbus_probe.c       |  8 +++-----
>  include/xen/page.h                      |  4 ++--
>  20 files changed, 69 insertions(+), 51 deletions(-)
> 
> diff --git a/arch/arm/include/asm/xen/page.h b/arch/arm/include/asm/xen/page.h
> index 087d86e..51e5bf1 100644
> --- a/arch/arm/include/asm/xen/page.h
> +++ b/arch/arm/include/asm/xen/page.h
> @@ -34,14 +34,15 @@ typedef struct xpaddr {
>  unsigned long __pfn_to_mfn(unsigned long pfn);
>  extern struct rb_root phys_to_mach;
>  
> -static inline unsigned long pfn_to_mfn(unsigned long pfn)
> +/* Pseudo-physical <-> Guest conversion */
> +static inline unsigned long pfn_to_gfn(unsigned long pfn)
>  {
>  	return pfn;
>  }
>  
> -static inline unsigned long mfn_to_pfn(unsigned long mfn)
> +static inline unsigned long gfn_to_pfn(unsigned long gfn)
>  {
> -	return mfn;
> +	return gfn;
>  }
>  
>  /* Pseudo-physical <-> BUS conversion */
> @@ -65,9 +66,9 @@ static inline unsigned long bfn_to_pfn(unsigned long bfn)
>  
>  #define bfn_to_local_pfn(bfn)	bfn_to_pfn(bfn)
>  
> -/* VIRT <-> MACHINE conversion */
> -#define virt_to_mfn(v)		(pfn_to_mfn(virt_to_pfn(v)))
> -#define mfn_to_virt(m)		(__va(mfn_to_pfn(m) << PAGE_SHIFT))
> +/* VIRT <-> GUEST conversion */
> +#define virt_to_gfn(v)		(pfn_to_gfn(virt_to_pfn(v)))
> +#define gfn_to_virt(m)		(__va(gfn_to_pfn(m) << PAGE_SHIFT))
>  
>  /* Only used in PV code. But ARM guests are always HVM. */
>  static inline xmaddr_t arbitrary_virt_to_machine(void *vaddr)
> diff --git a/arch/x86/include/asm/xen/page.h b/arch/x86/include/asm/xen/page.h
> index 8ba04b8..c2da42f 100644
> --- a/arch/x86/include/asm/xen/page.h
> +++ b/arch/x86/include/asm/xen/page.h
> @@ -103,8 +103,7 @@ static inline unsigned long pfn_to_mfn(unsigned long pfn)
>  {
>  	unsigned long mfn;
>  
> -	if (xen_feature(XENFEAT_auto_translated_physmap))
> -		return pfn;
> +	BUG_ON(xen_feature(XENFEAT_auto_translated_physmap));
>  
>  	mfn = __pfn_to_mfn(pfn);
>  
> @@ -149,8 +148,7 @@ static inline unsigned long mfn_to_pfn(unsigned long mfn)
>  {
>  	unsigned long pfn;
>  
> -	if (xen_feature(XENFEAT_auto_translated_physmap))
> -		return mfn;
> +	BUG_ON(xen_feature(XENFEAT_auto_translated_physmap));
>  
>  	pfn = mfn_to_pfn_no_overrides(mfn);
>  	if (__pfn_to_mfn(pfn) != mfn)
> @@ -178,9 +176,26 @@ static inline xpaddr_t machine_to_phys(xmaddr_t machine)
>  	return XPADDR(PFN_PHYS(mfn_to_pfn(PFN_DOWN(machine.maddr))) | offset);
>  }
>  
> +/* Pseudo-physical <-> Guest conversion */
> +static inline unsigned long pfn_to_gfn(unsigned long pfn)
> +{
> +	if (xen_feature(XENFEAT_auto_translated_physmap))
> +		return pfn;
> +	else
> +		return pfn_to_mfn(pfn);
> +}
> +
> +static inline unsigned long gfn_to_pfn(unsigned long gfn)
> +{
> +	if (xen_feature(XENFEAT_auto_translated_physmap))
> +		return gfn;
> +	else
> +		return mfn_to_pfn(gfn);
> +}
> +
>  /* Pseudo-physical <-> Bus conversion */
> -#define pfn_to_bfn(pfn)		pfn_to_mfn(pfn)
> -#define bfn_to_pfn(bfn)		mfn_to_pfn(bfn)
> +#define pfn_to_bfn(pfn)		pfn_to_gfn(pfn)
> +#define bfn_to_pfn(bfn)		gfn_to_pfn(bfn)
>  
>  /*
>   * We detect special mappings in one of two ways:
> @@ -217,9 +232,13 @@ static inline unsigned long bfn_to_local_pfn(unsigned long mfn)
>  
>  /* VIRT <-> MACHINE conversion */
>  #define virt_to_machine(v)	(phys_to_machine(XPADDR(__pa(v))))
> -#define virt_to_pfn(v)          (PFN_DOWN(__pa(v)))
>  #define virt_to_mfn(v)		(pfn_to_mfn(virt_to_pfn(v)))
>  #define mfn_to_virt(m)		(__va(mfn_to_pfn(m) << PAGE_SHIFT))
> +#define virt_to_pfn(v)          (PFN_DOWN(__pa(v)))
> +
> +/* VIRT <-> GUEST conversion */
> +#define virt_to_gfn(v)		(pfn_to_gfn(virt_to_pfn(v)))
> +#define gfn_to_virt(g)		(__va(gfn_to_pfn(g) << PAGE_SHIFT))
>  
>  static inline unsigned long pte_mfn(pte_t pte)
>  {
> diff --git a/arch/x86/xen/smp.c b/arch/x86/xen/smp.c
> index 8648438..1e0931b 100644
> --- a/arch/x86/xen/smp.c
> +++ b/arch/x86/xen/smp.c
> @@ -429,7 +429,7 @@ cpu_initialize_context(unsigned int cpu, struct task_struct *idle)
>  	}
>  #endif
>  	ctxt->user_regs.esp = idle->thread.sp0 - sizeof(struct pt_regs);
> -	ctxt->ctrlreg[3] = xen_pfn_to_cr3(virt_to_mfn(swapper_pg_dir));
> +	ctxt->ctrlreg[3] = xen_pfn_to_cr3(virt_to_gfn(swapper_pg_dir));
>  	if (HYPERVISOR_vcpu_op(VCPUOP_initialise, cpu, ctxt))
>  		BUG();
>  
> diff --git a/drivers/block/xen-blkfront.c b/drivers/block/xen-blkfront.c
> index 6d89ed3..2e541a4 100644
> --- a/drivers/block/xen-blkfront.c
> +++ b/drivers/block/xen-blkfront.c
> @@ -247,7 +247,7 @@ static struct grant *get_grant(grant_ref_t *gref_head,
>                                 struct blkfront_info *info)
>  {
>  	struct grant *gnt_list_entry;
> -	unsigned long buffer_mfn;
> +	unsigned long buffer_gfn;
>  
>  	BUG_ON(list_empty(&info->grants));
>  	gnt_list_entry = list_first_entry(&info->grants, struct grant,
> @@ -266,10 +266,10 @@ static struct grant *get_grant(grant_ref_t *gref_head,
>  		BUG_ON(!pfn);
>  		gnt_list_entry->pfn = pfn;
>  	}
> -	buffer_mfn = pfn_to_mfn(gnt_list_entry->pfn);
> +	buffer_gfn = pfn_to_gfn(gnt_list_entry->pfn);
>  	gnttab_grant_foreign_access_ref(gnt_list_entry->gref,
>  	                                info->xbdev->otherend_id,
> -	                                buffer_mfn, 0);
> +	                                buffer_gfn, 0);
>  	return gnt_list_entry;
>  }
>  
> diff --git a/drivers/input/misc/xen-kbdfront.c b/drivers/input/misc/xen-kbdfront.c
> index 95599e4..23d0549 100644
> --- a/drivers/input/misc/xen-kbdfront.c
> +++ b/drivers/input/misc/xen-kbdfront.c
> @@ -232,7 +232,7 @@ static int xenkbd_connect_backend(struct xenbus_device *dev,
>  	struct xenbus_transaction xbt;
>  
>  	ret = gnttab_grant_foreign_access(dev->otherend_id,
> -	                                  virt_to_mfn(info->page), 0);
> +	                                  virt_to_gfn(info->page), 0);
>  	if (ret < 0)
>  		return ret;
>  	info->gref = ret;
> @@ -255,7 +255,7 @@ static int xenkbd_connect_backend(struct xenbus_device *dev,
>  		goto error_irqh;
>  	}
>  	ret = xenbus_printf(xbt, dev->nodename, "page-ref", "%lu",
> -			    virt_to_mfn(info->page));
> +			    virt_to_gfn(info->page));
>  	if (ret)
>  		goto error_xenbus;
>  	ret = xenbus_printf(xbt, dev->nodename, "page-gref", "%u", info->gref);
> diff --git a/drivers/net/xen-netback/netback.c b/drivers/net/xen-netback/netback.c
> index 7d50711..3b7b7c3 100644
> --- a/drivers/net/xen-netback/netback.c
> +++ b/drivers/net/xen-netback/netback.c
> @@ -314,7 +314,7 @@ static void xenvif_gop_frag_copy(struct xenvif_queue *queue, struct sk_buff *skb
>  		} else {
>  			copy_gop->source.domid = DOMID_SELF;
>  			copy_gop->source.u.gmfn =
> -				virt_to_mfn(page_address(page));
> +				virt_to_gfn(page_address(page));
>  		}
>  		copy_gop->source.offset = offset;
>  
> @@ -1284,7 +1284,7 @@ static void xenvif_tx_build_gops(struct xenvif_queue *queue,
>  		queue->tx_copy_ops[*copy_ops].source.offset = txreq.offset;
>  
>  		queue->tx_copy_ops[*copy_ops].dest.u.gmfn =
> -			virt_to_mfn(skb->data);
> +			virt_to_gfn(skb->data);
>  		queue->tx_copy_ops[*copy_ops].dest.domid = DOMID_SELF;
>  		queue->tx_copy_ops[*copy_ops].dest.offset =
>  			offset_in_page(skb->data);
> diff --git a/drivers/net/xen-netfront.c b/drivers/net/xen-netfront.c
> index f948c46..5cdab73 100644
> --- a/drivers/net/xen-netfront.c
> +++ b/drivers/net/xen-netfront.c
> @@ -291,7 +291,7 @@ static void xennet_alloc_rx_buffers(struct netfront_queue *queue)
>  		struct sk_buff *skb;
>  		unsigned short id;
>  		grant_ref_t ref;
> -		unsigned long pfn;
> +		unsigned long gfn;
>  		struct xen_netif_rx_request *req;
>  
>  		skb = xennet_alloc_one_rx_buffer(queue);
> @@ -307,12 +307,12 @@ static void xennet_alloc_rx_buffers(struct netfront_queue *queue)
>  		BUG_ON((signed short)ref < 0);
>  		queue->grant_rx_ref[id] = ref;
>  
> -		pfn = page_to_pfn(skb_frag_page(&skb_shinfo(skb)->frags[0]));
> +		gfn = page_to_gfn(skb_frag_page(&skb_shinfo(skb)->frags[0]));
>  
>  		req = RING_GET_REQUEST(&queue->rx, req_prod);
>  		gnttab_grant_foreign_access_ref(ref,
>  						queue->info->xbdev->otherend_id,
> -						pfn_to_mfn(pfn),
> +						gfn,
>  						0);
>  
>  		req->id = id;
> @@ -431,7 +431,7 @@ static struct xen_netif_tx_request *xennet_make_one_txreq(
>  	BUG_ON((signed short)ref < 0);
>  
>  	gnttab_grant_foreign_access_ref(ref, queue->info->xbdev->otherend_id,
> -					page_to_mfn(page), GNTMAP_readonly);
> +					page_to_gfn(page), GNTMAP_readonly);
>  
>  	queue->tx_skbs[id].skb = skb;
>  	queue->grant_tx_page[id] = page;
> diff --git a/drivers/scsi/xen-scsifront.c b/drivers/scsi/xen-scsifront.c
> index fad22ca..cdf00d1 100644
> --- a/drivers/scsi/xen-scsifront.c
> +++ b/drivers/scsi/xen-scsifront.c
> @@ -377,7 +377,6 @@ static int map_data_for_request(struct vscsifrnt_info *info,
>  	unsigned int data_len = scsi_bufflen(sc);
>  	unsigned int data_grants = 0, seg_grants = 0;
>  	struct scatterlist *sg;
> -	unsigned long mfn;
>  	struct scsiif_request_segment *seg;
>  
>  	ring_req->nr_segments = 0;
> @@ -420,9 +419,8 @@ static int map_data_for_request(struct vscsifrnt_info *info,
>  			ref = gnttab_claim_grant_reference(&gref_head);
>  			BUG_ON(ref == -ENOSPC);
>  
> -			mfn = pfn_to_mfn(page_to_pfn(page));
>  			gnttab_grant_foreign_access_ref(ref,
> -				info->dev->otherend_id, mfn, 1);
> +				info->dev->otherend_id, page_to_gfn(page), 1);
>  			shadow->gref[ref_cnt] = ref;
>  			ring_req->seg[ref_cnt].gref   = ref;
>  			ring_req->seg[ref_cnt].offset = (uint16_t)off;
> @@ -454,9 +452,9 @@ static int map_data_for_request(struct vscsifrnt_info *info,
>  			ref = gnttab_claim_grant_reference(&gref_head);
>  			BUG_ON(ref == -ENOSPC);
>  
> -			mfn = pfn_to_mfn(page_to_pfn(page));
>  			gnttab_grant_foreign_access_ref(ref,
> -				info->dev->otherend_id, mfn, grant_ro);
> +				info->dev->otherend_id, page_to_gfn(page),
> +				grant_ro);
>  
>  			shadow->gref[ref_cnt] = ref;
>  			seg->gref   = ref;
> diff --git a/drivers/tty/hvc/hvc_xen.c b/drivers/tty/hvc/hvc_xen.c
> index a9d837f..efe5124 100644
> --- a/drivers/tty/hvc/hvc_xen.c
> +++ b/drivers/tty/hvc/hvc_xen.c
> @@ -265,7 +265,8 @@ static int xen_pv_console_init(void)
>  		return 0;
>  	}
>  	info->evtchn = xen_start_info->console.domU.evtchn;
> -	info->intf = mfn_to_virt(xen_start_info->console.domU.mfn);
> +	/* GFN == MFN for PV guest */
> +	info->intf = gfn_to_virt(xen_start_info->console.domU.mfn);
>  	info->vtermno = HVC_COOKIE;
>  
>  	spin_lock(&xencons_lock);
> @@ -390,7 +391,7 @@ static int xencons_connect_backend(struct xenbus_device *dev,
>  	if (IS_ERR(info->hvc))
>  		return PTR_ERR(info->hvc);
>  	if (xen_pv_domain())
> -		mfn = virt_to_mfn(info->intf);
> +		mfn = virt_to_gfn(info->intf);
>  	else
>  		mfn = __pa(info->intf) >> PAGE_SHIFT;
>  	ret = gnttab_alloc_grant_references(1, &gref_head);
> diff --git a/drivers/video/fbdev/xen-fbfront.c b/drivers/video/fbdev/xen-fbfront.c
> index 09dc447..25e3cce 100644
> --- a/drivers/video/fbdev/xen-fbfront.c
> +++ b/drivers/video/fbdev/xen-fbfront.c
> @@ -539,7 +539,7 @@ static int xenfb_remove(struct xenbus_device *dev)
>  
>  static unsigned long vmalloc_to_mfn(void *address)
>  {
> -	return pfn_to_mfn(vmalloc_to_pfn(address));
> +	return pfn_to_gfn(vmalloc_to_pfn(address));
>  }
>  
>  static void xenfb_init_shared_page(struct xenfb_info *info,
> @@ -586,7 +586,7 @@ static int xenfb_connect_backend(struct xenbus_device *dev,
>  		goto unbind_irq;
>  	}
>  	ret = xenbus_printf(xbt, dev->nodename, "page-ref", "%lu",
> -			    virt_to_mfn(info->page));
> +			    virt_to_gfn(info->page));
>  	if (ret)
>  		goto error_xenbus;
>  	ret = xenbus_printf(xbt, dev->nodename, "event-channel", "%u",
> diff --git a/drivers/xen/balloon.c b/drivers/xen/balloon.c
> index bf4a23c..5df28cd 100644
> --- a/drivers/xen/balloon.c
> +++ b/drivers/xen/balloon.c
> @@ -441,7 +441,7 @@ static enum bp_state decrease_reservation(unsigned long nr_pages, gfp_t gfp)
>  	/* Update direct mapping, invalidate P2M, and add to balloon. */
>  	for (i = 0; i < nr_pages; i++) {
>  		pfn = frame_list[i];
> -		frame_list[i] = pfn_to_mfn(pfn);
> +		frame_list[i] = pfn_to_gfn(pfn);
>  		page = pfn_to_page(pfn);
>  
>  #ifdef CONFIG_XEN_HAVE_PVMMU
> diff --git a/drivers/xen/events/events_base.c b/drivers/xen/events/events_base.c
> index 1495ecc..10fd9c6 100644
> --- a/drivers/xen/events/events_base.c
> +++ b/drivers/xen/events/events_base.c
> @@ -1694,7 +1694,7 @@ void __init xen_init_IRQ(void)
>  		struct physdev_pirq_eoi_gmfn eoi_gmfn;
>  
>  		pirq_eoi_map = (void *)__get_free_page(GFP_KERNEL|__GFP_ZERO);
> -		eoi_gmfn.gmfn = virt_to_mfn(pirq_eoi_map);
> +		eoi_gmfn.gmfn = virt_to_gfn(pirq_eoi_map);
>  		rc = HYPERVISOR_physdev_op(PHYSDEVOP_pirq_eoi_gmfn_v2, &eoi_gmfn);
>  		/* TODO: No PVH support for PIRQ EOI */
>  		if (rc != 0) {
> diff --git a/drivers/xen/events/events_fifo.c b/drivers/xen/events/events_fifo.c
> index 6df8aac..2e55e90 100644
> --- a/drivers/xen/events/events_fifo.c
> +++ b/drivers/xen/events/events_fifo.c
> @@ -111,7 +111,7 @@ static int init_control_block(int cpu,
>  	for (i = 0; i < EVTCHN_FIFO_MAX_QUEUES; i++)
>  		q->head[i] = 0;
>  
> -	init_control.control_gfn = virt_to_mfn(control_block);
> +	init_control.control_gfn = virt_to_gfn(control_block);
>  	init_control.offset      = 0;
>  	init_control.vcpu        = cpu;
>  
> @@ -167,7 +167,7 @@ static int evtchn_fifo_setup(struct irq_info *info)
>  		/* Mask all events in this page before adding it. */
>  		init_array_page(array_page);
>  
> -		expand_array.array_gfn = virt_to_mfn(array_page);
> +		expand_array.array_gfn = virt_to_gfn(array_page);
>  
>  		ret = HYPERVISOR_event_channel_op(EVTCHNOP_expand_array, &expand_array);
>  		if (ret < 0)
> diff --git a/drivers/xen/gntalloc.c b/drivers/xen/gntalloc.c
> index e53fe19..13e1458 100644
> --- a/drivers/xen/gntalloc.c
> +++ b/drivers/xen/gntalloc.c
> @@ -142,7 +142,8 @@ static int add_grefs(struct ioctl_gntalloc_alloc_gref *op,
>  
>  		/* Grant foreign access to the page. */
>  		rc = gnttab_grant_foreign_access(op->domid,
> -			pfn_to_mfn(page_to_pfn(gref->page)), readonly);
> +						 page_to_gfn(gref->page),
> +						 readonly);
>  		if (rc < 0)
>  			goto undo;
>  		gref_ids[i] = gref->gref_id = rc;
> diff --git a/drivers/xen/manage.c b/drivers/xen/manage.c
> index d10effe..e12bd36 100644
> --- a/drivers/xen/manage.c
> +++ b/drivers/xen/manage.c
> @@ -80,7 +80,7 @@ static int xen_suspend(void *data)
>  	 * is resuming in a new domain.
>  	 */
>  	si->cancelled = HYPERVISOR_suspend(xen_pv_domain()
> -                                           ? virt_to_mfn(xen_start_info)
> +                                           ? virt_to_gfn(xen_start_info)
>                                             : 0);
>  
>  	xen_arch_post_suspend(si->cancelled);
> diff --git a/drivers/xen/tmem.c b/drivers/xen/tmem.c
> index 239738f..28c97ff 100644
> --- a/drivers/xen/tmem.c
> +++ b/drivers/xen/tmem.c
> @@ -131,7 +131,7 @@ static int xen_tmem_new_pool(struct tmem_pool_uuid uuid,
>  static int xen_tmem_put_page(u32 pool_id, struct tmem_oid oid,
>  			     u32 index, unsigned long pfn)
>  {
> -	unsigned long gmfn = xen_pv_domain() ? pfn_to_mfn(pfn) : pfn;
> +	unsigned long gmfn = pfn_to_gfn(pfn);
>  
>  	return xen_tmem_op(TMEM_PUT_PAGE, pool_id, oid, index,
>  		gmfn, 0, 0, 0);
> @@ -140,7 +140,7 @@ static int xen_tmem_put_page(u32 pool_id, struct tmem_oid oid,
>  static int xen_tmem_get_page(u32 pool_id, struct tmem_oid oid,
>  			     u32 index, unsigned long pfn)
>  {
> -	unsigned long gmfn = xen_pv_domain() ? pfn_to_mfn(pfn) : pfn;
> +	unsigned long gmfn = pfn_to_gfn(pfn);
>  
>  	return xen_tmem_op(TMEM_GET_PAGE, pool_id, oid, index,
>  		gmfn, 0, 0, 0);
> diff --git a/drivers/xen/xenbus/xenbus_client.c b/drivers/xen/xenbus/xenbus_client.c
> index 9ad3272..daa267a 100644
> --- a/drivers/xen/xenbus/xenbus_client.c
> +++ b/drivers/xen/xenbus/xenbus_client.c
> @@ -380,7 +380,7 @@ int xenbus_grant_ring(struct xenbus_device *dev, void *vaddr,
>  
>  	for (i = 0; i < nr_pages; i++) {
>  		err = gnttab_grant_foreign_access(dev->otherend_id,
> -						  virt_to_mfn(vaddr), 0);
> +						  virt_to_gfn(vaddr), 0);
>  		if (err < 0) {
>  			xenbus_dev_fatal(dev, err,
>  					 "granting access to ring page");
> diff --git a/drivers/xen/xenbus/xenbus_dev_backend.c b/drivers/xen/xenbus/xenbus_dev_backend.c
> index b17707e..ee6d9ef 100644
> --- a/drivers/xen/xenbus/xenbus_dev_backend.c
> +++ b/drivers/xen/xenbus/xenbus_dev_backend.c
> @@ -49,7 +49,7 @@ static long xenbus_alloc(domid_t domid)
>  		goto out_err;
>  
>  	gnttab_grant_foreign_access_ref(GNTTAB_RESERVED_XENSTORE, domid,
> -			virt_to_mfn(xen_store_interface), 0 /* writable */);
> +			virt_to_gfn(xen_store_interface), 0 /* writable */);
>  
>  	arg.dom = DOMID_SELF;
>  	arg.remote_dom = domid;
> diff --git a/drivers/xen/xenbus/xenbus_probe.c b/drivers/xen/xenbus/xenbus_probe.c
> index 4308fb3..b3870f4 100644
> --- a/drivers/xen/xenbus/xenbus_probe.c
> +++ b/drivers/xen/xenbus/xenbus_probe.c
> @@ -711,9 +711,7 @@ static int __init xenstored_local_init(void)
>  	if (!page)
>  		goto out_err;
>  
> -	xen_store_mfn = xen_start_info->store_mfn =
> -		pfn_to_mfn(virt_to_phys((void *)page) >>
> -			   PAGE_SHIFT);
> +	xen_store_mfn = xen_start_info->store_mfn = virt_to_gfn((void *)page);
>  
>  	/* Next allocate a local port which xenstored can bind to */
>  	alloc_unbound.dom        = DOMID_SELF;
> @@ -787,12 +785,12 @@ static int __init xenbus_init(void)
>  		err = xenstored_local_init();
>  		if (err)
>  			goto out_error;
> -		xen_store_interface = mfn_to_virt(xen_store_mfn);
> +		xen_store_interface = gfn_to_virt(xen_store_mfn);
>  		break;
>  	case XS_PV:
>  		xen_store_evtchn = xen_start_info->store_evtchn;
>  		xen_store_mfn = xen_start_info->store_mfn;
> -		xen_store_interface = mfn_to_virt(xen_store_mfn);
> +		xen_store_interface = gfn_to_virt(xen_store_mfn);
>  		break;
>  	case XS_HVM:
>  		err = hvm_get_parameter(HVM_PARAM_STORE_EVTCHN, &v);
> diff --git a/include/xen/page.h b/include/xen/page.h
> index c5ed20b..e7e1425 100644
> --- a/include/xen/page.h
> +++ b/include/xen/page.h
> @@ -3,9 +3,9 @@
>  
>  #include <asm/xen/page.h>
>  
> -static inline unsigned long page_to_mfn(struct page *page)
> +static inline unsigned long page_to_gfn(struct page *page)
>  {
> -	return pfn_to_mfn(page_to_pfn(page));
> +	return pfn_to_gfn(page_to_pfn(page));
>  }
>  
>  struct xen_memory_region {
> -- 
> 2.1.4
> 

From pbrobinson at gmail.com  Wed Aug  5 03:13:07 2015
From: pbrobinson at gmail.com (Peter Robinson)
Date: Wed, 5 Aug 2015 11:13:07 +0100
Subject: arm kernel oops in highmem.c with 4.2
In-Reply-To: <20150805100701.GV7557@n2100.arm.linux.org.uk>
References: <CALeDE9Ox3=sh3AXQ0NUG6BBfU5i5YrMY=LDpcTHQWqz2=60F2g@mail.gmail.com>
 <20150805100701.GV7557@n2100.arm.linux.org.uk>
Message-ID: <CALeDE9PXF=gQCaBCiHpHy2nXOooQOmsCQvSgOv+wQw3mta=P6A@mail.gmail.com>

On Wed, Aug 5, 2015 at 11:07 AM, Russell King - ARM Linux
<linux at arm.linux.org.uk> wrote:
> On Wed, Aug 05, 2015 at 11:01:01AM +0100, Peter Robinson wrote:
>> Hi All,
>>
>> On Fedora 23 with recent 4.2 kernels we're seeing a crash (below) in
>> highmem.c on a fairly regular occurrence across a number of different
>> SoCs, I've seen it with at least AllWinner A20, i.MX6Q, Tegra2 and 124
>> with both a LPAE and non LPAE kernel, seen it happen when doing a
>> number of different things but regenerating a initrd, applying updates
>> (dnf/yum) and starting X are all pretty good triggers.
>
> I've yet to see any problems with mainline 4.2-rc5 kernels on any of my
> iMX6 platforms, which includes initramfs regeneration, apt-get updates
> and X.
>
>> [71751.658105] ------------[ cut here ]------------
>> [71751.658153] kernel BUG at arch/arm/mm/highmem.c:114!
>
> Well, in mainline kernels, the BUG is on line 113, not line 114.  So at
> least this file is modified from mainline kernels.  Maybe the problem is
> caused by patches applied to Fedora kernels?

We apply a crash driver patch [1] which has been there forever (long
enough that I'd forgotten it) but other than that for arm kernels we
currently don't apply any arm specific patches in 4.2.

Peter

[1] http://pkgs.fedoraproject.org/cgit/kernel.git/tree/crash-driver.patch


From s.hauer at pengutronix.de  Wed Aug  5 03:20:39 2015
From: s.hauer at pengutronix.de (Sascha Hauer)
Date: Wed, 5 Aug 2015 12:20:39 +0200
Subject: [PATCH 2/3] thermal: Add Mediatek thermal controller support
In-Reply-To: <CAGS+omAsTBMhfLPs5V68Ou1E5WXnQzZ3_E5+9qCCbAja3dgY-w@mail.gmail.com>
References: <1437465566-16299-1-git-send-email-s.hauer@pengutronix.de>
 <1437465566-16299-3-git-send-email-s.hauer@pengutronix.de>
 <CAGS+omAsTBMhfLPs5V68Ou1E5WXnQzZ3_E5+9qCCbAja3dgY-w@mail.gmail.com>
Message-ID: <20150805102039.GH18700@pengutronix.de>

On Tue, Jul 21, 2015 at 11:13:22PM +0800, Daniel Kurtz wrote:
> Hi Sascha,
> 
> Review comments inline...
> 
> > + *
> > + * This converts the raw ADC value to mcelsius using the SoC specific
> > + * calibration constants
> > + */
> > +static int raw_to_mcelsius(struct mtk_thermal *mt, u32 raw)
> > +{
> > +       s32 format_1, format_2, format_3, format_4;
> 
> The formula would be easier to follow with better variable names than
> "format_X".
> 
> > +       s32 xtoomt;
> 
> What does "xtoomt" mean?
> 
> > +       s32 gain;
> > +
> > +       raw &= 0xfff;
> > +
> > +       gain = (10000 + mt->adc_ge);
> 
> no outer ()
> 
> > +
> > +       xtoomt = ((((mt->vts + 3350 - mt->adc_oe) * 10000) / 4096) * 10000) /
> > +               gain;
> > +
> > +       format_1 = ((mt->degc_cali * 10) >> 1);
> 
> When doing computations, I think "A / 2" is preferred over "A >> 1".
> Also, no outer ().
> 
> > +       format_2 = (raw - mt->adc_oe);
> > +       format_3 = (((((format_2) * 10000) >> 12) * 10000) / gain) - xtoomt;
> 
> This is just:
>   format_3 = ((((raw - mt->vts - 3350) * 10000) / 4096) * 10000) / gain;
> 
> No wonder mt->adc_oe = 512-512 = 0... it just cancels itself out here, anyway.
> 
> > +       format_3 = format_3 * 15 / 18;
> 
> Of course we should multiply by 15/18!
> What is going on here?  Why this magic 5/6 ratio?
> 
> > +       format_4 = ((format_3 * 100) / (165 + mt->o_slope));
> 
> no outer ()
> 
> > +       format_4 = format_4 - (format_4 << 1);
> 
> Hmm...
>  A = X - 2*X;
> otherwise known as:
>  A = -X;
> 
> > +       return (format_1 + format_4) * 100;
> 
> Or just:
>   return (format_1 - format_4) * 100;

I must admit I took this calculation from the original driver and never
looked at it. Simplifying this further this goes down to:

static int raw_to_mcelsius(struct mtk_thermal *mt, u32 raw)
{
	return mt->calib_b + mt->calib_a * (raw & 0xfff);
}

with calib_a = -123 and calib_b = 465124.

I'll address this and the other comments in v2.

Sascha

-- 
Pengutronix e.K.                           |                             |
Industrial Linux Solutions                 | http://www.pengutronix.de/  |
Peiner Str. 6-8, 31137 Hildesheim, Germany | Phone: +49-5121-206917-0    |
Amtsgericht Hildesheim, HRA 2686           | Fax:   +49-5121-206917-5555 |


From tony at atomide.com  Wed Aug  5 03:22:34 2015
From: tony at atomide.com (Tony Lindgren)
Date: Wed, 5 Aug 2015 03:22:34 -0700
Subject: [PATCH 0/3] ARM: multi_v7_defconfig: Enable more OMAP family
 platforms
In-Reply-To: <1428614121-3374-1-git-send-email-nm@ti.com>
References: <1428614121-3374-1-git-send-email-nm@ti.com>
Message-ID: <20150805102234.GZ16878@atomide.com>

Ping, looks like these are still pending. Probably should be
applied directly by the arm-soc maintainers.

Regards,

Tony

* Nishanth Menon <nm at ti.com> [150409 14:17]:
> Hi,
> 
> As of next-20150409 tag, the following platforms (I have access
> to) report failures for AM437x-sk and legacy beaglebone (white).
> omap2plus_defconfig boots up fine on these platforms.
> 
> So, the basic minimum stuff I could pickup to fix up beaglebone-white
> and am437x-sk.
> 
> This series is still missing the magic sauce for LDP - will try to
> track that down later as well.
> 
> This series is based on next-20150409
> 
> multi_v7_defconfig (as on next-20150409)
>  1:                     am335x-evm: BOOT: PASS: am335x-evm.txt
>  2:                      am335x-sk: BOOT: PASS: am335x-sk.txt
>  3:                     am3517-evm: BOOT: PASS: am3517-evm.txt
>  4:                      am37x-evm: BOOT: PASS: am37x-evm.txt
>  5:                      am437x-sk: BOOT: FAIL: am437x-sk.txt
>  6:                    am43xx-epos: BOOT: PASS: am43xx-epos.txt
>  7:                   am43xx-gpevm: BOOT: PASS: am43xx-gpevm.txt
>  8:                 BeagleBoard-XM: BOOT: PASS: beagleboard.txt
>  9:            beagleboard-vanilla: BOOT: PASS: beagleboard-vanilla.txt
> 10:               beaglebone-black: BOOT: PASS: beaglebone-black.txt
> 11:                     beaglebone: BOOT: FAIL: beaglebone.txt
> 12:                     craneboard: BOOT: PASS: craneboard.txt
> 13:                     dra72x-evm: BOOT: PASS: dra72x-evm.txt
> 14:                     dra7xx-evm: BOOT: PASS: dra7xx-evm.txt
> 15:         OMAP3430-Labrador(LDP): BOOT: FAIL: ldp.txt
> 16:                           n900: BOOT: PASS: n900.txt
> 17:                      omap5-evm: BOOT: PASS: omap5-evm.txt
> 18:                  pandaboard-es: BOOT: PASS: pandaboard-es.txt
> 19:             pandaboard-vanilla: BOOT: PASS: pandaboard-vanilla.txt
> 20:                        sdp3430: BOOT: PASS: sdp3430.txt
> 21:                        sdp4430: BOOT: PASS: sdp4430.txt
> 
> After this series:
>  1:                     am335x-evm: BOOT: PASS: am335x-evm.txt
>  2:                     am3517-evm: BOOT: PASS: am3517-evm.txt
>  3:                      am37x-evm: BOOT: PASS: am37x-evm.txt
>  4:                      am437x-sk: BOOT: PASS: am437x-sk.txt
>  5:                    am43xx-epos: BOOT: PASS: am43xx-epos.txt
>  6:                   am43xx-gpevm: BOOT: PASS: am43xx-gpevm.txt
>  7:                 BeagleBoard-XM: BOOT: PASS: beagleboard.txt
>  8:            beagleboard-vanilla: BOOT: PASS: beagleboard-vanilla.txt
>  9:               beaglebone-black: BOOT: PASS: beaglebone-black.txt
> 10:                     beaglebone: BOOT: PASS: beaglebone.txt
> 11:                     craneboard: BOOT: PASS: craneboard.txt
> 12:                     dra72x-evm: BOOT: PASS: dra72x-evm.txt
> 13:                     dra7xx-evm: BOOT: PASS: dra7xx-evm.txt
> 14:         OMAP3430-Labrador(LDP): BOOT: FAIL: ldp.txt
> 15:                           n900: BOOT: PASS: n900.txt
> 16:                      omap5-evm: BOOT: PASS: omap5-evm.txt
> 17:                  pandaboard-es: BOOT: PASS: pandaboard-es.txt
> 18:             pandaboard-vanilla: BOOT: PASS: pandaboard-vanilla.txt
> 19:                        sdp3430: BOOT: PASS: sdp3430.txt
> 20:                        sdp4430: BOOT: PASS: sdp4430.txt
> TOTAL = 20 boards, Booted Boards = 19, No Boot boards = 1
> 
> Nishanth Menon (3):
>   ARM: multi_v7_defconfig: Enable beaglebone PMIC TPS65217
>   ARM: multi_v7_defconfig: Enable AM437x PMIC TPS65218
>   ARM: multi_v7_defconfig: Enable generic SoC internal OMAP regulators
> 
>  arch/arm/configs/multi_v7_defconfig |    6 ++++++
>  1 file changed, 6 insertions(+)
> 
> Regards,
> Nishanth Menon
> -- 
> 1.7.9.5
> 
> --
> To unsubscribe from this list: send the line "unsubscribe linux-omap" in
> the body of a message to majordomo at vger.kernel.org
> More majordomo info at  http://vger.kernel.org/majordomo-info.html
> 


From sudeep.holla at arm.com  Wed Aug  5 03:22:51 2015
From: sudeep.holla at arm.com (Sudeep Holla)
Date: Wed, 05 Aug 2015 11:22:51 +0100
Subject: [GIT PULL] ARM64: juno: SCPI and dependent drivers for v4.3
Message-ID: <55C1E3FB.5090309@arm.com>

Hi Olof,


Here is the first pull request for SCPI, clock and cpufreq support on
ARM64 Juno development platform for v4.3

Regards,
Sudeep

The following changes since commit d770e558e21961ad6cfdf0ff7df0eb5d7d4f0754:

    Linux 4.2-rc1 (2015-07-05 11:01:52 -0700)

are available in the git repository at:

    git://linux-arm.org/linux-skn.git juno_dvfs

for you to fetch changes up to a42b1bbf7bf9a2a1fa4b0deff66581b83541b819:

    arm64: dts: add clock support for all the cpus (2015-08-05 11:03:09 
+0100)

----------------------------------------------------------------
Sudeep Holla (8):
        Documentation: add DT binding for ARM System Control and Power 
Interface(SCPI) protocol
        firmware: add support for ARM System Control and Power 
Interface(SCPI) protocol
        clk: add support for clocks provided by SCP(System Control 
Processor)
        clk: scpi: add support for cpufreq virtual device
        cpufreq: arm_big_little: add SCPI interface driver
        arm64: dts: add SRAM, MHU mailbox and SCPI support on Juno
        arm64: dts: add CPU topology on Juno
        arm64: dts: add clock support for all the cpus

   Documentation/devicetree/bindings/arm/arm,scpi.txt | 150 +++
   MAINTAINERS                                        |  10 +
   arch/arm64/boot/dts/arm/juno-base.dtsi             |  54 ++
   arch/arm64/boot/dts/arm/juno-r1.dts                |  32 +
   arch/arm64/boot/dts/arm/juno.dts                   |  32 +
   drivers/clk/Kconfig                                |  10 +
   drivers/clk/Makefile                               |   1 +
   drivers/clk/clk-scpi.c                             | 325 +++++++
   drivers/cpufreq/Kconfig.arm                        |   9 +
   drivers/cpufreq/Makefile                           |   1 +
   drivers/cpufreq/scpi-cpufreq.c                     | 124 +++
   drivers/firmware/Kconfig                           |  19 +
   drivers/firmware/Makefile                          |   1 +
   drivers/firmware/arm_scpi.c                        | 711 +++++++++++++
   include/linux/scpi_protocol.h                      |  61 ++
   15 files changed, 1540 insertions(+)
   create mode 100644 Documentation/devicetree/bindings/arm/arm,scpi.txt
   create mode 100644 drivers/clk/clk-scpi.c
   create mode 100644 drivers/cpufreq/scpi-cpufreq.c
   create mode 100644 drivers/firmware/arm_scpi.c
   create mode 100644 include/linux/scpi_protocol.h



From drinkcat at chromium.org  Wed Aug  5 03:24:05 2015
From: drinkcat at chromium.org (Nicolas Boichat)
Date: Wed, 5 Aug 2015 18:24:05 +0800
Subject: [PATCH 1/3] spi: bitbang: Replace spinlock by mutex when calling
 chipselect
In-Reply-To: <20150804105957.GI20873@sirena.org.uk>
References: <1438668598-6678-1-git-send-email-drinkcat@chromium.org>
 <20150804105957.GI20873@sirena.org.uk>
Message-ID: <CANMq1KB2zxPPCbxh4K-REUgp-83s=MPcGRjz-p1fK1PQMzyLdw@mail.gmail.com>

On Tue, Aug 4, 2015 at 6:59 PM, Mark Brown <broonie at kernel.org> wrote:
> On Tue, Aug 04, 2015 at 02:09:56PM +0800, Nicolas Boichat wrote:
[snip]
>> Actually, I'm not sure if I understand the existing code: why are we not
>> waiting for busy to go down to 0, then call chipselect, instead of not calling
>> it at all if the bus happens to be busy when we setup the device? With the
>> current approach, it would be easy to just use an unconditional mutex_lock.
>
> We shouldn't be blocking waiting for the bus to become free, that's not
> how the interface works.

Noted.

>> Also, is it harmful to deactivate the newly setup device in spi_bitbang_setup,
>> even if the bus is busy with another device? chipselect should be independent
>> for each device (or is it not?). So I'm not clear why we need any locking at
>> all...
>
> If you assert chip select on one device while another device is still
> being interacted with then the new device will see the traffic for the
> old device and become confused.

Here in spi_bitbang_setup, we do:
bitbang->chipselect(spi, BITBANG_CS_INACTIVE);
That is, we make sure that the current device is _not_ selected.

Looking a bit more into this, the issue here is that some drivers use
chipselect to chip select individual devices separately, while, on
others, the above command unselects all devices (which is a bad idea
if the bus is currently transferring data...). So, in short, it's
probably better not to touch this code.

>> Anyway, this patch series does not change the existing behaviour, applies on
>> top of broonie-sound/for-next, and, along with the 2 follow-up patches, was
>> compile-tested on x86-64/arm (allyesconfig) and ppc44x (defconfig+SPI driver),
>> and runtime-tested on an arm platform.
>
> I'm not seeing enough analysis in the commit log of what's being locked
> and why - I don't fully understand what the busy stuff is for either
> (not that I've looked at the code in detail just now) but I think that's
> going to be the key thing here.

Regarding deleting prepare/unprepare and moving the lock into transfer_one.

spi.c:__spi_pump_messages, which calls these functions, does the following:
 - If no more messages need to be sent, call unprepare_transfer_hardware
 - If messages need to be sent:
   + call prepare_transfer_hardware
   + call prepare_message (NULL for bitbang)
   + call transfer_one_message

I don't think it makes a big difference if we set busy (or hold a
mutex) in prepare/unprepare, or we just do it in transfer_one_message,
since chipselect is only set in transfer_one_message, and is
deselected at the end of the function anyway (in most cases, and if
it's not, it will be selected again at the next transfer anyway).

Anyway, the "safer" way to fix this would be to keep the
prepare/unprepare functions, busy variable, and just protect it with a
mutex instead of a spinlock...

Thanks.

Best,


From tony at atomide.com  Wed Aug  5 03:28:40 2015
From: tony at atomide.com (Tony Lindgren)
Date: Wed, 5 Aug 2015 03:28:40 -0700
Subject: [PATCH v2 1/3] mailbox/omap: Add ti, mbox-send-noirq quirk to fix
 AM33xx CPU Idle
In-Reply-To: <1437166592-25378-2-git-send-email-d-gerlach@ti.com>
References: <1437166592-25378-1-git-send-email-d-gerlach@ti.com>
 <1437166592-25378-2-git-send-email-d-gerlach@ti.com>
Message-ID: <20150805102840.GA16878@atomide.com>

* Dave Gerlach <d-gerlach at ti.com> [150717 13:59]:
> --- a/Documentation/devicetree/bindings/mailbox/omap-mailbox.txt
> +++ b/Documentation/devicetree/bindings/mailbox/omap-mailbox.txt
> @@ -75,6 +75,14 @@ data that represent the following:
>      Cell #3 (usr_id)  - mailbox user id for identifying the interrupt line
>                          associated with generating a tx/rx fifo interrupt.
>  
> +Optional Properties:
> +--------------------
> +- ti,mbox-send-noirq:   Quirk flag to allow the client user of this sub-mailbox
> +                        to send messages without triggering a Tx ready interrupt,
> +                        and to control the Tx ticker. Should be used only on
> +                        sub-mailboxes used to communicate with WkupM3 remote
> +                        processor on AM33xx/AM43xx SoCs.
> +

Hmm can't you do this just by setting a flag in the device driver
based on the compatible string?

Regards,

Tony


From pawel.moll at arm.com  Wed Aug  5 03:29:34 2015
From: pawel.moll at arm.com (Pawel Moll)
Date: Wed, 05 Aug 2015 11:29:34 +0100
Subject: [PATCH 1/3] clk: versatile: Switch to assigned clock parents
In-Reply-To: <55BFAB11.7080600@codeaurora.org>
References: <55BBB2FC.9030102@codeaurora.org>
 <1438386285-5070-1-git-send-email-sboyd@codeaurora.org>
 <1438386285-5070-2-git-send-email-sboyd@codeaurora.org>
 <1438610480.2142.14.camel@arm.com> <55BFAB11.7080600@codeaurora.org>
Message-ID: <1438770574.2142.80.camel@arm.com>

On Mon, 2015-08-03 at 18:55 +0100, Stephen Boyd wrote:
> On 08/03/2015 07:01 AM, Pawel Moll wrote:
> > On Sat, 2015-08-01 at 00:44 +0100, Stephen Boyd wrote:
> >> @@ -179,6 +124,15 @@ static void __init clk_sp810_of_setup(struct device_node *node)
> >>   		sp810->timerclken[i].channel = i;
> >>   		sp810->timerclken[i].hw.init = &init;
> >>   
> >> +		/*
> >> +		 * If DT isn't setting the parent, force it to be
> >> +		 * the 1 MHz clock without going through the framework.
> >> +		 * We do this before clk_register() so that it can determine
> >> +		 * the parent and setup the tree properly.
> >> +		 */
> >> +		if (deprecated)
> >> +			init.ops->set_parent(&sp810->timerclken[i].hw, 1);
> >> +
> >>   		sp810->timerclken[i].clk = clk_register(NULL,
> >>   				&sp810->timerclken[i].hw);
> >>   		WARN_ON(IS_ERR(sp810->timerclken[i].clk));
> > So that's one thing I've got a (small) problem here...
> >
> > The above change assumes that SP810 always have 32kHz clock on input 0
> > and 1MHz clock on input 1. Yes, this is how it made on VExpress, but it
> > doesn't have to be the case. The magic picking up the faster clock was
> > added to handle all possible cases.
> >
> > The bottom line is: if all we care is VExpress than it works, but it's
> > still a hack. Personally I don't like it, however I won't nak the patch
> > because of this.
> 
> All current dts files in the kernel tree have 1MHz on input 1, so we 
> make this change here to set the parent to input 1 if there isn't an 
> assigned-clock-parents property.

That's what I said - all VE platforms known to me will work, because
they all have the clocks wired up the same way. And I still don't like
code in a "generic SP810 driver" assuming this. Call me what you
want ;-)

> Presumably new dts files should have 
> the new property so that things work properly. 

Sure, no argument here.

> I tried to find the 
> binding document, but it doesn't look to exist, so I didn't have 
> anything to update.

Right, that's probably my fault. The sp810 nodes appeared in the VE
trees very early (in terms of the "DT era"), when we weren't so strict
about documentation. So far, it would be fairly simple, something like
the text below - feel free to take it, mend it, extend it with your
changes and include in the series:

Thanks!

Pawel

8<-------------------------

SP810 System Controller
-----------------------

Required properties:

- compatible:	standard compatible string for a Primecell peripheral,
		see Documentation/devicetree/bindings/arm/primecell.txt
		for more details
		should be: "arm,sp810", "arm,primecell"

- reg:		standard registers property, physical address and size
		of the control registers

- clock-names:	from the common clock bindings, for more details see
		Documentation/devicetree/bindings/clock/clock-bindings.txt;
		should be: "refclk", "timclk", "apb_pclk"

- clocks:	from the common clock bindings, phandle and clock
		specifier pairs for the entries of clock-names property

- #clock-cells:	from the common clock bindings;
		should be: <1>

- clock-output-names:	from the common clock bindings;
		should be: "timerclken0", "timerclken1", "timerclken2", "timerclken3"

Example:
	sysctl at 020000 {
		compatible = "arm,sp810", "arm,primecell";
		reg = <0x020000 0x1000>;
		clocks = <&v2m_refclk32khz>, <&v2m_refclk1mhz>,	<&smbclk>;
		clock-names = "refclk", "timclk", "apb_pclk";
		#clock-cells = <1>;
		clock-output-names = "timerclken0", "timerclken1", "timerclken2", "timerclken3";
	};



From tony at atomide.com  Wed Aug  5 03:31:55 2015
From: tony at atomide.com (Tony Lindgren)
Date: Wed, 5 Aug 2015 03:31:55 -0700
Subject: [PATCH 4/4] ARM: dts: AM4372: Add the wkup_m3_ipc node
In-Reply-To: <1437167284-25659-5-git-send-email-d-gerlach@ti.com>
References: <1437167284-25659-1-git-send-email-d-gerlach@ti.com>
 <1437167284-25659-5-git-send-email-d-gerlach@ti.com>
Message-ID: <20150805103155.GB16878@atomide.com>

* Dave Gerlach <d-gerlach at ti.com> [150717 14:10]:
> From: Suman Anna <s-anna at ti.com>
> 
> Add the Wakeup M3 IPC device node for the wkup_m3_ipc driver on
> AM4372 SoC. This node uses the IPC registers, part of the Control
> Module, and is therefore added as a child of the scm node.

Applying the last two patches in this series into omap-for-v4.3/dt
thanks.

Probably the send-no-irq quirk you can do in the driver based
on the compatible flag like I suggested in the related mailbox
thread so not applying those until that's been discussed.

Regards,

Tony


From julien.grall at citrix.com  Wed Aug  5 03:31:09 2015
From: julien.grall at citrix.com (Julien Grall)
Date: Wed, 5 Aug 2015 11:31:09 +0100
Subject: [PATCH v2 2/8] xen: Make clear that swiotlb and biomerge are
 dealing with DMA address
In-Reply-To: <alpine.DEB.2.02.1508051041060.11337@kaball.uk.xensource.com>
References: <1438711972-18752-1-git-send-email-julien.grall@citrix.com>
 <1438711972-18752-3-git-send-email-julien.grall@citrix.com>
 <alpine.DEB.2.02.1508051041060.11337@kaball.uk.xensource.com>
Message-ID: <55C1E5ED.10103@citrix.com>

Hi Stefano,

On 05/08/15 10:49, Stefano Stabellini wrote:
>>  /* VIRT <-> MACHINE conversion */
>>  #define virt_to_mfn(v)		(pfn_to_mfn(virt_to_pfn(v)))
>> @@ -96,7 +115,7 @@ static inline bool set_phys_to_machine(unsigned long pfn, unsigned long mfn)
>>  
>>  bool xen_arch_need_swiotlb(struct device *dev,
>>  			   unsigned long pfn,
>> -			   unsigned long mfn);
>> +			   unsigned long dfn);
>>  unsigned long xen_get_swiotlb_free_pages(unsigned int order);
> 
> You missed a bunch of dfn->bfn renamings.

Sorry, I forgot to double check that before sending the patch. I will
fix it in the next version.

> Aside from those and the commit message error:
> 
> Reviewed-by: Stefano Stabellini <stefano.stabellini at eu.citrix.com>

Thank you!

Regards,

-- 
Julien Grall


From haibo.chen at freescale.com  Wed Aug  5 03:38:36 2015
From: haibo.chen at freescale.com (Haibo Chen)
Date: Wed, 5 Aug 2015 18:38:36 +0800
Subject: [PATCH v4 0/6] mmc: imx: a few fixes and new feature
Message-ID: <1438771122-8601-1-git-send-email-haibo.chen@freescale.com>

Changes for v4:
-Call esdhc_set_strobe_dll() only when device clock is over 100MHz in HS400 mode.
-Add detail description of tuning-step.
-Change to default watermark level and burst length for all imx SoC, not only imx7d.

Haibo Chen (6):
  mmc: sdhci-esdhc-imx: add imx7d support and support HS400
  mmc: sdhci-esdhc-imx: add tuning-step seting support
  mmc: sdhci-esdhc-imx: add compatible string in bingding doc
  ARM: dts: imx7d-sdb: add eMMC5.0 support
  mmc: sdhci-esdhc-imx: change default watermark level and burst length
  mmc: sdhci-esdhc-imx: set back the burst_length_enable bit to 1

 .../devicetree/bindings/mmc/fsl-imx-esdhc.txt      |   6 ++
 arch/arm/boot/dts/imx7d-sdb.dts                    |  13 +++
 drivers/mmc/host/sdhci-esdhc-imx.c                 | 109 ++++++++++++++++++++-
 include/linux/platform_data/mmc-esdhc-imx.h        |   1 +
 4 files changed, 128 insertions(+), 1 deletion(-)

-- 
1.9.1



From haibo.chen at freescale.com  Wed Aug  5 03:38:37 2015
From: haibo.chen at freescale.com (Haibo Chen)
Date: Wed, 5 Aug 2015 18:38:37 +0800
Subject: [PATCH v4 1/6] mmc: sdhci-esdhc-imx: add imx7d support and support
 HS400
In-Reply-To: <1438771122-8601-1-git-send-email-haibo.chen@freescale.com>
References: <1438771122-8601-1-git-send-email-haibo.chen@freescale.com>
Message-ID: <1438771122-8601-2-git-send-email-haibo.chen@freescale.com>

The imx7d usdhc is derived from imx6sx, the difference is that
imx7d support HS400.

So introduce a new compatible string for imx7d and add HS400
support for imx7d usdhc.

Signed-off-by: Haibo Chen <haibo.chen at freescale.com>
---
 drivers/mmc/host/sdhci-esdhc-imx.c | 81 ++++++++++++++++++++++++++++++++++++++
 1 file changed, 81 insertions(+)

diff --git a/drivers/mmc/host/sdhci-esdhc-imx.c b/drivers/mmc/host/sdhci-esdhc-imx.c
index c6b9f64..48f009c 100644
--- a/drivers/mmc/host/sdhci-esdhc-imx.c
+++ b/drivers/mmc/host/sdhci-esdhc-imx.c
@@ -44,6 +44,7 @@
 #define  ESDHC_MIX_CTRL_EXE_TUNE	(1 << 22)
 #define  ESDHC_MIX_CTRL_SMPCLK_SEL	(1 << 23)
 #define  ESDHC_MIX_CTRL_FBCLK_SEL	(1 << 25)
+#define  ESDHC_MIX_CTRL_HS400_EN	(1 << 26)
 /* Bits 3 and 6 are not SDHCI standard definitions */
 #define  ESDHC_MIX_CTRL_SDHCI_MASK	0xb7
 /* Tuning bits */
@@ -60,6 +61,16 @@
 #define  ESDHC_TUNE_CTRL_MIN		0
 #define  ESDHC_TUNE_CTRL_MAX		((1 << 7) - 1)
 
+/* strobe dll register */
+#define ESDHC_STROBE_DLL_CTRL		0x70
+#define ESDHC_STROBE_DLL_CTRL_ENABLE	(1 << 0)
+#define ESDHC_STROBE_DLL_CTRL_RESET	(1 << 1)
+#define ESDHC_STROBE_DLL_CTRL_SLV_DLY_TARGET_SHIFT	3
+
+#define ESDHC_STROBE_DLL_STATUS		0x74
+#define ESDHC_STROBE_DLL_STS_REF_LOCK	(1 << 1)
+#define ESDHC_STROBE_DLL_STS_SLV_LOCK	0x1
+
 #define ESDHC_TUNING_CTRL		0xcc
 #define ESDHC_STD_TUNING_EN		(1 << 24)
 /* NOTE: the minimum valid tuning start tap for mx6sl is 1 */
@@ -120,6 +131,11 @@
 #define ESDHC_FLAG_ERR004536		BIT(7)
 /* The IP supports HS200 mode */
 #define ESDHC_FLAG_HS200		BIT(8)
+/* The IP supports HS400 mode */
+#define ESDHC_FLAG_HS400		BIT(9)
+
+/* A higher clock ferquency than this rate requires strobell dll control */
+#define ESDHC_STROBE_DLL_CLK_FREQ	100000000
 
 struct esdhc_soc_data {
 	u32 flags;
@@ -156,6 +172,12 @@ static struct esdhc_soc_data usdhc_imx6sx_data = {
 			| ESDHC_FLAG_HAVE_CAP1 | ESDHC_FLAG_HS200,
 };
 
+static struct esdhc_soc_data usdhc_imx7d_data = {
+	.flags = ESDHC_FLAG_USDHC | ESDHC_FLAG_STD_TUNING
+			| ESDHC_FLAG_HAVE_CAP1 | ESDHC_FLAG_HS200
+			| ESDHC_FLAG_HS400,
+};
+
 struct pltfm_imx_data {
 	u32 scratchpad;
 	struct pinctrl *pinctrl;
@@ -199,6 +221,7 @@ static const struct of_device_id imx_esdhc_dt_ids[] = {
 	{ .compatible = "fsl,imx6sx-usdhc", .data = &usdhc_imx6sx_data, },
 	{ .compatible = "fsl,imx6sl-usdhc", .data = &usdhc_imx6sl_data, },
 	{ .compatible = "fsl,imx6q-usdhc", .data = &usdhc_imx6q_data, },
+	{ .compatible = "fsl,imx7d-usdhc", .data = &usdhc_imx7d_data, },
 	{ /* sentinel */ }
 };
 MODULE_DEVICE_TABLE(of, imx_esdhc_dt_ids);
@@ -274,6 +297,9 @@ static u32 esdhc_readl_le(struct sdhci_host *host, int reg)
 				val = SDHCI_SUPPORT_DDR50 | SDHCI_SUPPORT_SDR104
 					| SDHCI_SUPPORT_SDR50
 					| SDHCI_USE_SDR50_TUNING;
+
+			if (imx_data->socdata->flags & ESDHC_FLAG_HS400)
+				val |= SDHCI_SUPPORT_HS400;
 		}
 	}
 
@@ -774,6 +800,7 @@ static int esdhc_change_pinstate(struct sdhci_host *host,
 		break;
 	case MMC_TIMING_UHS_SDR104:
 	case MMC_TIMING_MMC_HS200:
+	case MMC_TIMING_MMC_HS400:
 		pinctrl = imx_data->pins_200mhz;
 		break;
 	default:
@@ -784,6 +811,44 @@ static int esdhc_change_pinstate(struct sdhci_host *host,
 	return pinctrl_select_state(imx_data->pinctrl, pinctrl);
 }
 
+/*
+ * For HS400 eMMC, there is a data_strobe line, this signal is generated
+ * by the device and used for data output and CRC status response output
+ * in HS400 mode. The frequency of this signal follows the frequency of
+ * CLK generated by host. Host receive the data which is aligned to the
+ * edge of data_strobe line. Due to the time delay between CLK line and
+ * data_strobe line, if the delay time is larger than one clock cycle,
+ * then CLK and data_strobe line will misaligned, read error shows up.
+ * So when the CLK is higher than 100MHz, each clock cycle is short enough,
+ * host should config the delay target.
+ */
+static void esdhc_set_strobe_dll(struct sdhci_host *host)
+{
+	u32 v;
+
+	if (host->mmc->actual_clock > ESDHC_STROBE_DLL_CLK_FREQ) {
+		/* force a reset on strobe dll */
+		writel(ESDHC_STROBE_DLL_CTRL_RESET,
+			host->ioaddr + ESDHC_STROBE_DLL_CTRL);
+		/*
+		 * enable strobe dll ctrl and adjust the delay target
+		 * for the uSDHC loopback read clock
+		 */
+		v = ESDHC_STROBE_DLL_CTRL_ENABLE |
+			(7 << ESDHC_STROBE_DLL_CTRL_SLV_DLY_TARGET_SHIFT);
+		writel(v, host->ioaddr + ESDHC_STROBE_DLL_CTRL);
+		/* wait 1us to make sure strobe dll status register stable */
+		udelay(1);
+		v = readl(host->ioaddr + ESDHC_STROBE_DLL_STATUS);
+		if (!(v & ESDHC_STROBE_DLL_STS_REF_LOCK))
+			dev_warn(mmc_dev(host->mmc),
+				"warning! HS400 strobe DLL status REF not lock!\n");
+		if (!(v & ESDHC_STROBE_DLL_STS_SLV_LOCK))
+			dev_warn(mmc_dev(host->mmc),
+				"warning! HS400 strobe DLL status SLV not lock!\n");
+	}
+}
+
 static void esdhc_set_uhs_signaling(struct sdhci_host *host, unsigned timing)
 {
 	struct sdhci_pltfm_host *pltfm_host = sdhci_priv(host);
@@ -795,7 +860,13 @@ static void esdhc_set_uhs_signaling(struct sdhci_host *host, unsigned timing)
 	case MMC_TIMING_UHS_SDR25:
 	case MMC_TIMING_UHS_SDR50:
 	case MMC_TIMING_UHS_SDR104:
+		break;
 	case MMC_TIMING_MMC_HS200:
+		/* disable ddr mode and disable HS400 mode */
+		writel(readl(host->ioaddr + ESDHC_MIX_CTRL) &
+			~(ESDHC_MIX_CTRL_DDREN | ESDHC_MIX_CTRL_HS400_EN),
+			host->ioaddr + ESDHC_MIX_CTRL);
+		imx_data->is_ddr = 0;
 		break;
 	case MMC_TIMING_UHS_DDR50:
 	case MMC_TIMING_MMC_DDR52:
@@ -813,6 +884,13 @@ static void esdhc_set_uhs_signaling(struct sdhci_host *host, unsigned timing)
 			writel(v, host->ioaddr + ESDHC_DLL_CTRL);
 		}
 		break;
+	case MMC_TIMING_MMC_HS400:
+		writel(readl(host->ioaddr + ESDHC_MIX_CTRL) |
+				ESDHC_MIX_CTRL_DDREN | ESDHC_MIX_CTRL_HS400_EN,
+				host->ioaddr + ESDHC_MIX_CTRL);
+		imx_data->is_ddr = 1;
+		esdhc_set_strobe_dll(host);
+		break;
 	}
 
 	esdhc_change_pinstate(host, timing);
@@ -1100,6 +1178,9 @@ static int sdhci_esdhc_imx_probe(struct platform_device *pdev)
 	if (imx_data->socdata->flags & ESDHC_FLAG_ERR004536)
 		host->quirks |= SDHCI_QUIRK_BROKEN_ADMA;
 
+	if (imx_data->socdata->flags & ESDHC_FLAG_HS400)
+		host->quirks2 |= SDHCI_QUIRK2_CAPS_BIT63_FOR_HS400;
+
 	if (of_id)
 		err = sdhci_esdhc_imx_probe_dt(pdev, host, imx_data);
 	else
-- 
1.9.1



From haibo.chen at freescale.com  Wed Aug  5 03:38:39 2015
From: haibo.chen at freescale.com (Haibo Chen)
Date: Wed, 5 Aug 2015 18:38:39 +0800
Subject: [PATCH v4 3/6] mmc: sdhci-esdhc-imx: add compatible string in
 bingding doc
In-Reply-To: <1438771122-8601-1-git-send-email-haibo.chen@freescale.com>
References: <1438771122-8601-1-git-send-email-haibo.chen@freescale.com>
Message-ID: <1438771122-8601-4-git-send-email-haibo.chen@freescale.com>

Add a required property "fsl,imx7d-usdhc" in binding doc.
Add an optional property "fsl,tuning-step" in binding doc.

Signed-off-by: Haibo Chen <haibo.chen at freescale.com>
---
 Documentation/devicetree/bindings/mmc/fsl-imx-esdhc.txt | 6 ++++++
 1 file changed, 6 insertions(+)

diff --git a/Documentation/devicetree/bindings/mmc/fsl-imx-esdhc.txt b/Documentation/devicetree/bindings/mmc/fsl-imx-esdhc.txt
index 211e778..dca56d6 100644
--- a/Documentation/devicetree/bindings/mmc/fsl-imx-esdhc.txt
+++ b/Documentation/devicetree/bindings/mmc/fsl-imx-esdhc.txt
@@ -15,6 +15,7 @@ Required properties:
 	       "fsl,imx6q-usdhc"
 	       "fsl,imx6sl-usdhc"
 	       "fsl,imx6sx-usdhc"
+	       "fsl,imx7d-usdhc"
 
 Optional properties:
 - fsl,wp-controller : Indicate to use controller internal write protection
@@ -27,6 +28,11 @@ Optional properties:
   transparent level shifters on the outputs of the controller. Two cells are
   required, first cell specifies minimum slot voltage (mV), second cell
   specifies maximum slot voltage (mV). Several ranges could be specified.
+- fsl,tuning-step: Specify the increasing delay cell steps in tuning procedure.
+  The uSDHC use one delay cell as default increasing step to do tuning process.
+  This property allows user to change the tuning step to more than one delay
+  cells which is useful for some special boards or cards when the default
+  tuning step can't find the proper delay window within limited tuning retries.
 
 Examples:
 
-- 
1.9.1



From haibo.chen at freescale.com  Wed Aug  5 03:38:38 2015
From: haibo.chen at freescale.com (Haibo Chen)
Date: Wed, 5 Aug 2015 18:38:38 +0800
Subject: [PATCH v4 2/6] mmc: sdhci-esdhc-imx: add tuning-step seting support
In-Reply-To: <1438771122-8601-1-git-send-email-haibo.chen@freescale.com>
References: <1438771122-8601-1-git-send-email-haibo.chen@freescale.com>
Message-ID: <1438771122-8601-3-git-send-email-haibo.chen@freescale.com>

tuning-step is the delay cell steps in tuning procedure. The default value
of tuning-step is 1. Some boards or cards need another value to pass the
tuning procedure. For example, imx7d-sdb board need the tuning-step value
as 2, otherwise it can't pass the tuning procedure.

So this patch add the tuning-step setting in driver, so that user can set
the tuning-step value in dts.

Signed-off-by: Haibo Chen <haibo.chen at freescale.com>
---
 drivers/mmc/host/sdhci-esdhc-imx.c          | 9 +++++++++
 include/linux/platform_data/mmc-esdhc-imx.h | 1 +
 2 files changed, 10 insertions(+)

diff --git a/drivers/mmc/host/sdhci-esdhc-imx.c b/drivers/mmc/host/sdhci-esdhc-imx.c
index 48f009c..803d24f 100644
--- a/drivers/mmc/host/sdhci-esdhc-imx.c
+++ b/drivers/mmc/host/sdhci-esdhc-imx.c
@@ -75,6 +75,7 @@
 #define ESDHC_STD_TUNING_EN		(1 << 24)
 /* NOTE: the minimum valid tuning start tap for mx6sl is 1 */
 #define ESDHC_TUNING_START_TAP		0x1
+#define ESDHC_TUNING_STEP_SHIFT		16
 
 /* pinctrl state */
 #define ESDHC_PINCTRL_STATE_100MHZ	"state_100mhz"
@@ -474,6 +475,7 @@ static void esdhc_writew_le(struct sdhci_host *host, u16 val, int reg)
 		} else if (imx_data->socdata->flags & ESDHC_FLAG_STD_TUNING) {
 			u32 v = readl(host->ioaddr + SDHCI_ACMD12_ERR);
 			u32 m = readl(host->ioaddr + ESDHC_MIX_CTRL);
+			u32 tuning_ctrl;
 			if (val & SDHCI_CTRL_TUNED_CLK) {
 				v |= ESDHC_MIX_CTRL_SMPCLK_SEL;
 			} else {
@@ -484,6 +486,11 @@ static void esdhc_writew_le(struct sdhci_host *host, u16 val, int reg)
 			if (val & SDHCI_CTRL_EXEC_TUNING) {
 				v |= ESDHC_MIX_CTRL_EXE_TUNE;
 				m |= ESDHC_MIX_CTRL_FBCLK_SEL;
+				tuning_ctrl = readl(host->ioaddr + ESDHC_TUNING_CTRL);
+				tuning_ctrl |= ESDHC_STD_TUNING_EN | ESDHC_TUNING_START_TAP;
+				if (imx_data->boarddata.tuning_step)
+					tuning_ctrl |= imx_data->boarddata.tuning_step << ESDHC_TUNING_STEP_SHIFT;
+					writel(tuning_ctrl, host->ioaddr + ESDHC_TUNING_CTRL);
 			} else {
 				v &= ~ESDHC_MIX_CTRL_EXE_TUNE;
 			}
@@ -964,6 +971,8 @@ sdhci_esdhc_imx_probe_dt(struct platform_device *pdev,
 	if (gpio_is_valid(boarddata->wp_gpio))
 		boarddata->wp_type = ESDHC_WP_GPIO;
 
+	of_property_read_u32(np, "fsl,tuning-step", &boarddata->tuning_step);
+
 	if (of_find_property(np, "no-1-8-v", NULL))
 		boarddata->support_vsel = false;
 	else
diff --git a/include/linux/platform_data/mmc-esdhc-imx.h b/include/linux/platform_data/mmc-esdhc-imx.h
index e1571ef..95ccab3 100644
--- a/include/linux/platform_data/mmc-esdhc-imx.h
+++ b/include/linux/platform_data/mmc-esdhc-imx.h
@@ -45,5 +45,6 @@ struct esdhc_platform_data {
 	int max_bus_width;
 	bool support_vsel;
 	unsigned int delay_line;
+	unsigned int tuning_step;       /* The delay cell steps in tuning procedure */
 };
 #endif /* __ASM_ARCH_IMX_ESDHC_H */
-- 
1.9.1



From zyw at rock-chips.com  Wed Aug  5 03:36:06 2015
From: zyw at rock-chips.com (Chris Zhong)
Date: Wed, 05 Aug 2015 18:36:06 +0800
Subject: [PATCH v3 1/3] ARM: rockchip: rename osc_switch_to_32k variable
In-Reply-To: <2128609.Kb18M8K28F@diego>
References: <2128609.Kb18M8K28F@diego>
Message-ID: <55C1E716.4010901@rock-chips.com>



On 08/05/2015 06:50 AM, Heiko St?bner wrote:
> The variable name is misleading, as the deep suspend mode always switches
> the main supplying clock to the 32kHz source. Additionally the main
> oscillator remain running in some cases, which this var indicates.
>
> So rename it to osc_disable to clarity.
>
> Signed-off-by: Heiko Stuebner <heiko at sntech.de>
> ---
>   arch/arm/mach-rockchip/pm.c | 4 ++--
>   1 file changed, 2 insertions(+), 2 deletions(-)
>
> diff --git a/arch/arm/mach-rockchip/pm.c b/arch/arm/mach-rockchip/pm.c
> index 892bace..2ca1170 100644
> --- a/arch/arm/mach-rockchip/pm.c
> +++ b/arch/arm/mach-rockchip/pm.c
> @@ -96,7 +96,7 @@ static bool rk3288_slp_disable_osc(void)
>   static void rk3288_slp_mode_set(int level)
>   {
>   	u32 mode_set, mode_set1;
> -	bool osc_switch_to_32k = rk3288_slp_disable_osc();
> +	bool osc_disable = rk3288_slp_disable_osc();
>   
>   	regmap_read(sgrf_regmap, RK3288_SGRF_CPU_CON0, &rk3288_sgrf_cpu_con0);
>   	regmap_read(sgrf_regmap, RK3288_SGRF_SOC_CON0, &rk3288_sgrf_soc_con0);
> @@ -140,7 +140,7 @@ static void rk3288_slp_mode_set(int level)
>   			    BIT(PMU_DDR1IO_RET_EN) | BIT(PMU_DDR0IO_RET_EN) |
>   			    BIT(PMU_ALIVE_USE_LF) | BIT(PMU_PLL_PD_EN);
>   
> -		if (osc_switch_to_32k)
> +		if (osc_disable)
>   			mode_set |= BIT(PMU_OSC_24M_DIS);
>   
>   		mode_set1 |= BIT(PMU_CLR_ALIVE) | BIT(PMU_CLR_BUS) |
Reviewed-by: Chris Zhong <zyw at rock-chips.com>
Tested-by: Chris Zhong <zyw at rock-chips.com>


From haibo.chen at freescale.com  Wed Aug  5 03:38:40 2015
From: haibo.chen at freescale.com (Haibo Chen)
Date: Wed, 5 Aug 2015 18:38:40 +0800
Subject: [PATCH v4 4/6] ARM: dts: imx7d-sdb: add eMMC5.0 support
In-Reply-To: <1438771122-8601-1-git-send-email-haibo.chen@freescale.com>
References: <1438771122-8601-1-git-send-email-haibo.chen@freescale.com>
Message-ID: <1438771122-8601-5-git-send-email-haibo.chen@freescale.com>

imx7d-sdb board has a eMMC5.0 on usdhc3. This eMMC support HS400.
This patch add usdhc3 support for HS400

Signed-off-by: Haibo Chen <haibo.chen at freescale.com>
---
 arch/arm/boot/dts/imx7d-sdb.dts | 13 +++++++++++++
 1 file changed, 13 insertions(+)

diff --git a/arch/arm/boot/dts/imx7d-sdb.dts b/arch/arm/boot/dts/imx7d-sdb.dts
index fdd1d7c..8059458 100644
--- a/arch/arm/boot/dts/imx7d-sdb.dts
+++ b/arch/arm/boot/dts/imx7d-sdb.dts
@@ -241,6 +241,19 @@
 	status = "okay";
 };
 
+&usdhc3 {
+	pinctrl-names = "default", "state_100mhz", "state_200mhz";
+	pinctrl-0 = <&pinctrl_usdhc3>;
+	pinctrl-1 = <&pinctrl_usdhc3_100mhz>;
+	pinctrl-2 = <&pinctrl_usdhc3_200mhz>;
+	assigned-clocks = <&clks IMX7D_USDHC3_ROOT_CLK>;
+	assigned-clock-rates = <400000000>;
+	bus-width = <8>;
+	fsl,tuning-step = <2>;
+	non-removable;
+	status = "okay";
+};
+
 &iomuxc {
 	pinctrl-names = "default";
 	pinctrl-0 = <&pinctrl_hog>;
-- 
1.9.1



From haibo.chen at freescale.com  Wed Aug  5 03:38:41 2015
From: haibo.chen at freescale.com (Haibo Chen)
Date: Wed, 5 Aug 2015 18:38:41 +0800
Subject: [PATCH v4 5/6] mmc: sdhci-esdhc-imx: change default watermark level
 and burst length
In-Reply-To: <1438771122-8601-1-git-send-email-haibo.chen@freescale.com>
References: <1438771122-8601-1-git-send-email-haibo.chen@freescale.com>
Message-ID: <1438771122-8601-6-git-send-email-haibo.chen@freescale.com>

By default, for all imx SoC types, the watermark level is 16, and the
burst length is 8. But if the SDIO/SD/MMC I/O speed is fast enough,
this default watermark level and burst length will be the performance
bottleneck.

For example, i.MX7D support eMMC HS400 mode, this mode can run in 8 bit,
200MHZ DDR mode. So the I/O speed improve a lot compare to SD3.0.
The default burst length is 8, if we don't change this value, in
HS400 mode, when we do eMMC read operation, we can find that the
clock signal will stop for a period of time. This means the speed
of data moving on AHB bus is slower than I/O speed. So we should
improve the speed of data moving on AHB bus.

This patch set the default burst length as 16, and set the default
watermark level as 64. The test result is the clock signal has
no stop during the eMMC HS400 operation.

Signed-off-by: Haibo Chen <haibo.chen at freescale.com>
---
 drivers/mmc/host/sdhci-esdhc-imx.c | 3 ++-
 1 file changed, 2 insertions(+), 1 deletion(-)

diff --git a/drivers/mmc/host/sdhci-esdhc-imx.c b/drivers/mmc/host/sdhci-esdhc-imx.c
index 803d24f..97aa944 100644
--- a/drivers/mmc/host/sdhci-esdhc-imx.c
+++ b/drivers/mmc/host/sdhci-esdhc-imx.c
@@ -1160,7 +1160,8 @@ static int sdhci_esdhc_imx_probe(struct platform_device *pdev)
 	 * to something insane.  Change it back here.
 	 */
 	if (esdhc_is_usdhc(imx_data)) {
-		writel(0x08100810, host->ioaddr + ESDHC_WTMK_LVL);
+		writel(0x10401040, host->ioaddr + ESDHC_WTMK_LVL);
+
 		host->quirks2 |= SDHCI_QUIRK2_PRESET_VALUE_BROKEN;
 		host->mmc->caps |= MMC_CAP_1_8V_DDR;
 
-- 
1.9.1



From tony at atomide.com  Wed Aug  5 03:40:43 2015
From: tony at atomide.com (Tony Lindgren)
Date: Wed, 5 Aug 2015 03:40:43 -0700
Subject: [PATCH 2/2] ARM: dts: am57xx-evm: Add 'gpios' property with
 gpio2_8
In-Reply-To: <1438090750-11604-3-git-send-email-kishon@ti.com>
References: <1438090750-11604-1-git-send-email-kishon@ti.com>
 <1438090750-11604-3-git-send-email-kishon@ti.com>
Message-ID: <20150805104043.GD16878@atomide.com>

* Kishon Vijay Abraham I <kishon at ti.com> [150728 06:42]:
> gpio2_8 is connected to the PCIe_RESETn line and it has to be driven low
> in order to reset the PCIe cards. So added gpios property to pcie
> dt node.
> 
> Signed-off-by: Kishon Vijay Abraham I <kishon at ti.com>

This should not conflict with the device tree changes I'm queuing
for v4.3 merge window, so please feel free to queue with the PCIe
driver changes:

Acked-by: Tony Lindgren <tony at atomide.com>


From LW at KARO-electronics.de  Wed Aug  5 03:40:30 2015
From: LW at KARO-electronics.de (Lothar =?UTF-8?B?V2HDn21hbm4=?=)
Date: Wed, 5 Aug 2015 12:40:30 +0200
Subject: [PATCH v3 1/2] drivers: watchdog: add a driver to support
 SAMA5D4 watchdog timer
In-Reply-To: <1438765043-11030-2-git-send-email-wenyou.yang@atmel.com>
References: <1438765043-11030-1-git-send-email-wenyou.yang@atmel.com>
 <1438765043-11030-2-git-send-email-wenyou.yang@atmel.com>
Message-ID: <20150805124030.6e73b975@ipc1.ka-ro>

Hi,

> From SAMA5D4, the watchdog timer is upgrated with a new feature,
> which is describled as in the datasheet, "WDT_MR can be written
> until a LOCKMR command is issued in WDT_CR".
> That is to say, as long as the bootstrap and u-boot don't issue
> a LOCKMR command, WDT_MR can be written more than once in the driver.
> 
> So the SAMA5D4 watchdog driver's implementation is different from
> the at91sam9260 watchdog driver implemented in file at91sam9_wdt.c.
> The user application open the device file to enable the watchdog timer
> hardware, and close to disable it, and set the watchdog timer timeout
> by seting WDV and WDD fields of WDT_MR register, and ping the watchdog
> by issuing WDRSTT command to WDT_CR register with hard-coded key.
> 
> Signed-off-by: Wenyou Yang <wenyou.yang at atmel.com>
> ---
>  drivers/watchdog/Kconfig            |    9 ++
>  drivers/watchdog/Makefile           |    1 +
>  drivers/watchdog/at91_sama5d4_wdt.c |  279 +++++++++++++++++++++++++++++++++++
>  drivers/watchdog/at91sam9_wdt.h     |    2 +
>  4 files changed, 291 insertions(+)
>  create mode 100644 drivers/watchdog/at91_sama5d4_wdt.c
> 
> diff --git a/drivers/watchdog/Kconfig b/drivers/watchdog/Kconfig
> index e5e7c55..4ce8346 100644
> --- a/drivers/watchdog/Kconfig
> +++ b/drivers/watchdog/Kconfig
> @@ -152,6 +152,15 @@ config ARM_SP805_WATCHDOG
>  	  ARM Primecell SP805 Watchdog timer. This will reboot your system when
>  	  the timeout is reached.
>  
> +config AT91_SAMA5D4_WATCHDOG
> +	tristate "Atmel SAMA5D4 Watchdog Timer"
> +	depends on ARCH_AT91
> +	select WATCHDOG_CORE
> +	help
> +	  Atmel SAMA5D4 watchdog timer is embedded into SAMA5D4 chips.
> +	  Its Watchdog Timer Mode Register can be written more than once.
> +	  This will reboot your system when the timeout is reached.
> +
>  config AT91RM9200_WATCHDOG
>  	tristate "AT91RM9200 watchdog"
>  	depends on SOC_AT91RM9200 && MFD_SYSCON
> diff --git a/drivers/watchdog/Makefile b/drivers/watchdog/Makefile
> index 5c19294..c57569c 100644
> --- a/drivers/watchdog/Makefile
> +++ b/drivers/watchdog/Makefile
> @@ -30,6 +30,7 @@ obj-$(CONFIG_USBPCWATCHDOG) += pcwd_usb.o
>  
>  # ARM Architecture
>  obj-$(CONFIG_ARM_SP805_WATCHDOG) += sp805_wdt.o
> +obj-$(CONFIG_AT91_SAMA5D4_WATCHDOG) += at91_sama5d4_wdt.o
consistency? Other AT91 entries don't have an '_' between 'AT91' and
the remainder of the Kconfig name.

>  obj-$(CONFIG_AT91RM9200_WATCHDOG) += at91rm9200_wdt.o
>  obj-$(CONFIG_AT91SAM9X_WATCHDOG) += at91sam9_wdt.o
[...]
> +static irqreturn_t atmel_wdt_irq_handler(int irq, void *dev_id)
> +{
> +	struct atmel_wdt *wdt = platform_get_drvdata(dev_id);
> +
> +	if (wdt_read(wdt, AT91_WDT_SR)) {
> +		pr_crit("Atmel Watchdog Software Reset\n");
> +		emergency_restart();
> +		pr_crit("Reboot didn't ?????\n");
>
Reboot didn't what? 'succeed' perhaps?

> +static const struct of_device_id atmel_wdt_of_match[] = {
> +	{ .compatible = "atmel,sama5d4-wdt", },
> +	{ },
The empty initializer must always be the last element of the array, so
there is no point in having a trailing ',' (whose purpose is to
facilitate adding more entries after the last one).
Without the comma there will be a compile error if (e.g. due to a
badly resolved merge conflict) an additional entry would be added after
the stop marker. With the comma after the stop marker any trailing
entries would silently be ignored.


Lothar Wa?mann
-- 
___________________________________________________________

Ka-Ro electronics GmbH | Pascalstra?e 22 | D - 52076 Aachen
Phone: +49 2408 1402-0 | Fax: +49 2408 1402-10
Gesch?ftsf?hrer: Matthias Kaussen
Handelsregistereintrag: Amtsgericht Aachen, HRB 4996

www.karo-electronics.de | info at karo-electronics.de
___________________________________________________________


From zyw at rock-chips.com  Wed Aug  5 03:41:14 2015
From: zyw at rock-chips.com (Chris Zhong)
Date: Wed, 05 Aug 2015 18:41:14 +0800
Subject: [PATCH v3 2/3] ARM: rockchip: set correct stabilization thresholds
 in suspend
In-Reply-To: <1709899.JJDRtF09u7@diego>
References: <2128609.Kb18M8K28F@diego> <1709899.JJDRtF09u7@diego>
Message-ID: <55C1E84A.9050501@rock-chips.com>



On 08/05/2015 06:51 AM, Heiko St?bner wrote:
> Currently the stabilization thresholds for the oscillator and external pmu
> are statically set to 30ms based on a 32kHz clock rate. This leaves out the
> case when we don't switch to the 32kHz clock when only entering the shallow
> suspend mode where the logic keeps running.
>
> So, set the correct threshold after we have determined if we switch to the
> 32kHz clock or stay with the 24MHz one. Also set the oscillator-
> stabilization to 0 if it is kept running during suspend, as it of course
> does not need to stabilize then.
>
> Reported-by: Chris Zhong <zyw at rock-chips.com>
> Signed-off-by: Heiko Stuebner <heiko at sntech.de>
> ---
> changes since v2:
> - describe 32kHz vs 24MHz
> - don't wait for oscillator stabilization if it's still running,
>    as explained by Chris Zhong in v2
> changes since v1:
> - 24MHz oriented threshold is only needed in shallow suspend, the deep
>    suspend always switches to 32kHz and only leaves the 24MHz oscillator
>    running if needed for stuff like usb wakeup
>
>   arch/arm/mach-rockchip/pm.c | 22 +++++++++++++++++++---
>   arch/arm/mach-rockchip/pm.h |  4 ----
>   2 files changed, 19 insertions(+), 7 deletions(-)
>
> diff --git a/arch/arm/mach-rockchip/pm.c b/arch/arm/mach-rockchip/pm.c
> index 2ca1170..c11a30b 100644
> --- a/arch/arm/mach-rockchip/pm.c
> +++ b/arch/arm/mach-rockchip/pm.c
> @@ -145,6 +145,19 @@ static void rk3288_slp_mode_set(int level)
>   
>   		mode_set1 |= BIT(PMU_CLR_ALIVE) | BIT(PMU_CLR_BUS) |
>   			     BIT(PMU_CLR_PERI) | BIT(PMU_CLR_DMA);
> +
> +		/*
> +		 * In deep suspend we use PMU_PMU_USE_LF to let the rk3288
> +		 * switch its main clock supply to the alternative 32kHz
> +		 * source. Therefore set 30ms on a 32kHz clock for pmic
> +		 * stabilization. Similar 30ms on 24MHz for the other
> +		 * mode below.
> +		 */
> +		regmap_write(pmu_regmap, RK3288_PMU_STABL_CNT, 32 * 30);
> +
> +		/* only wait for stabilization, if we turned the osc off */
> +		regmap_write(pmu_regmap, RK3288_PMU_OSC_CNT,
> +					 osc_disable ? 32 * 30 : 0);
>   	} else {
>   		/*
>   		 * arm off, logic normal
> @@ -152,6 +165,12 @@ static void rk3288_slp_mode_set(int level)
>   		 * wakeup will be error
>   		 */
>   		mode_set |= BIT(PMU_CLK_CORE_SRC_GATE_EN);
> +
> +		/* 30ms on a 24MHz clock for pmic stabilization */
> +		regmap_write(pmu_regmap, RK3288_PMU_STABL_CNT, 24000 * 30);
> +
> +		/* oscillator is still running, so no need to wait */
> +		regmap_write(pmu_regmap, RK3288_PMU_OSC_CNT, 0);
>   	}
>   
>   	regmap_write(pmu_regmap, RK3288_PMU_PWRMODE_CON, mode_set);
> @@ -262,9 +281,6 @@ static int rk3288_suspend_init(struct device_node *np)
>   	memcpy(rk3288_bootram_base, rockchip_slp_cpu_resume,
>   	       rk3288_bootram_sz);
>   
> -	regmap_write(pmu_regmap, RK3288_PMU_OSC_CNT, OSC_STABL_CNT_THRESH);
> -	regmap_write(pmu_regmap, RK3288_PMU_STABL_CNT, PMU_STABL_CNT_THRESH);
> -
>   	return 0;
>   }
>   
> diff --git a/arch/arm/mach-rockchip/pm.h b/arch/arm/mach-rockchip/pm.h
> index b6494c2..8a55ee2 100644
> --- a/arch/arm/mach-rockchip/pm.h
> +++ b/arch/arm/mach-rockchip/pm.h
> @@ -62,10 +62,6 @@ static inline void rockchip_suspend_init(void)
>   /* PMU_WAKEUP_CFG1 bits */
>   #define PMU_ARMINT_WAKEUP_EN		BIT(0)
>   
> -/* wait 30ms for OSC stable and 30ms for pmic stable */
> -#define OSC_STABL_CNT_THRESH	(32 * 30)
> -#define PMU_STABL_CNT_THRESH	(32 * 30)
> -
>   enum rk3288_pwr_mode_con {
>   	PMU_PWR_MODE_EN = 0,
>   	PMU_CLK_CORE_SRC_GATE_EN,
Reviewed-by: Chris Zhong <zyw at rock-chips.com>
Tested-by: Chris Zhong <zyw at rock-chips.com>


From tony at atomide.com  Wed Aug  5 03:43:56 2015
From: tony at atomide.com (Tony Lindgren)
Date: Wed, 5 Aug 2015 03:43:56 -0700
Subject: [PATCH 00/11] omap_hsmmc: voltage switching and tuning
In-Reply-To: <1438242394-25599-1-git-send-email-kishon@ti.com>
References: <1438242394-25599-1-git-send-email-kishon@ti.com>
Message-ID: <20150805104355.GE16878@atomide.com>

* Kishon Vijay Abraham I <kishon at ti.com> [150730 00:49]:
> Patch series implements voltage switching and tuning for omap_hsmmc
> driver.
> 
> Did basic read/write test in J6, J6 Eco, Beagle-x15, AM437x EVM,
> Beaglebone black, OMAP5 uEVM and OMAP4 PANDA.

Your tests are missing omap3?

I suggest you add some omap3 tests in general as otherwise you are
only testing a subset of the driver features and completely missing
things like rutnime PM and save and restore for the deeper idle
states.

Regards,

Ton


From geert at linux-m68k.org  Wed Aug  5 03:44:10 2015
From: geert at linux-m68k.org (Geert Uytterhoeven)
Date: Wed, 5 Aug 2015 12:44:10 +0200
Subject: [PATCH v4 1/6] ARM: shmobile: r8a7740 dtsi: Add L2
 cache-controller node
In-Reply-To: <55C1D894.8070302@arm.com>
References: <1438765090-823-1-git-send-email-geert+renesas@glider.be>
 <1438765090-823-2-git-send-email-geert+renesas@glider.be>
 <55C1D894.8070302@arm.com>
Message-ID: <CAMuHMdXdEV+41mH338bDbazzqOErDLQkBUAj2+uVX4Wupn1ABQ@mail.gmail.com>

Hi Sudeep,

On Wed, Aug 5, 2015 at 11:34 AM, Sudeep Holla <sudeep.holla at arm.com> wrote:
> On 05/08/15 09:58, Geert Uytterhoeven wrote:
>> Add the missing L2 cache-controller node. This will allow migration to
>> the generic l2c OF initialization.
>>
>> The L2 cache is an ARM L2C-310 (r3p1-150rel0), of size 256 KiB (32 KiB x
>> 8 ways).
>>
>> Signed-off-by: Geert Uytterhoeven <geert+renesas at glider.be>

>> diff --git a/arch/arm/boot/dts/r8a7740.dtsi
>> b/arch/arm/boot/dts/r8a7740.dtsi
>> index d84714468cce18df..ddef5b1c68fa06b3 100644
>> --- a/arch/arm/boot/dts/r8a7740.dtsi
>> +++ b/arch/arm/boot/dts/r8a7740.dtsi
>> @@ -37,6 +37,22 @@
>>                       <0xc2000000 0x1000>;
>>         };
>>
>> +       L2: cache-controller {
>> +               compatible = "arm,pl310-cache";
>> +               reg = <0xf0100000 0x1000>;
>> +               interrupts = <0 84 IRQ_TYPE_LEVEL_HIGH>;
>> +               power-domains = <&pd_a3sm>;
>> +               arm,data-latency = <3 3 3>;
>> +               arm,tag-latency = <2 2 2>;
>> +               arm,shared-override;
>> +               cache-unified;
>> +               cache-level = <2>;
>> +               cache-size = <0x40000>;
>> +               cache-sets = <1024>;
>> +               cache-block-size = <32>;
>> +               cache-line-size = <32>;
>
>
> Any particular reason whey you need all this cache-* properties ? Is

To describe the cache as good as possible.

> something broken on these SoCs ? We should be able to get most of these
> information from the SoC(reading some registers). It's good to avoid
> passing them via DT if they can be discovered from hardware.

So we have all these documented properties in
Documentation/devicetree/bindings/arm/l2cc.txt, but they're not meant to
be used?

Gr{oetje,eeting}s,

                        Geert

--
Geert Uytterhoeven -- There's lots of Linux beyond ia32 -- geert at linux-m68k.org

In personal conversations with technical people, I call myself a hacker. But
when I'm talking to journalists I just say "programmer" or something like that.
                                -- Linus Torvalds


From will.deacon at arm.com  Wed Aug  5 03:45:24 2015
From: will.deacon at arm.com (Will Deacon)
Date: Wed, 5 Aug 2015 11:45:24 +0100
Subject: [PATCH v3 0/5] iommu/arm-smmu: add support for non-pci devices
In-Reply-To: <2351780.FdaR8mZqKs@avalon>
References: <1437463833-16112-1-git-send-email-thunder.leizhen@huawei.com>
 <55AE1F2F.3090106@arm.com> <20150728124847.GL29209@arm.com>
 <2351780.FdaR8mZqKs@avalon>
Message-ID: <20150805104524.GD6092@arm.com>

On Tue, Aug 04, 2015 at 11:50:45PM +0100, Laurent Pinchart wrote:
> Hi Will,

Hi Laurent,

> On Tuesday 28 July 2015 13:48:47 Will Deacon wrote:
> > On Tue, Jul 21, 2015 at 11:30:07AM +0100, Robin Murphy wrote:
> > > On 21/07/15 08:30, Zhen Lei wrote:
> > > > Changelog:
> > > > v2 -> v3:
> > > > 1. add support for pci device hotplug, which missed in patch v2.
> > > > 2. only support #iommu-cells = <1>, add corresponding description in
> > > > arm,smmu-v3.txt. 3. add function find_smmu_by_device which extracted
> > > > from find_smmu_by_node, to resolve> > 
> > > >     the problem mentioned by Robin Murphy in [PATCH v2 7/9].
> > > >     Additionally:
> > > >     +    platform_set_drvdata(pdev, smmu);       //Patch v2
> > > >     +	dev->archdata.iommu = smmu;             //Patch v3, dev =
> > > >     &pdev->dev
> > > 
> > > I didn't give any Reviewed-by tags, much less to revised patches that
> > > I've not even looked at yet; please see section 13 of
> > > Documentation/SubmittingPatches for what the Reviewed-by tag means.
> > 
> > That said, it would be great if you could review the patches anyway ;)
> > 
> > Also, it looks like this is all based on Laurent's IOMMU probe deferral
> > series which hasn't seen any movement for a while.
> > 
> > Laurent: are you planning to repost that, or is it worth us picking up
> > the original version and bashing it into shape ourselves?
> 
> I'd really appreciate if you could take it where I left it and get into shape 
> for upstream. I have no time to work on IOMMU at the moment I'm afraid :-( 

No problem at all. It will probably be Robin doing most of the hacking,
since he's the platform_device guy and I'm the PCI guy in the office at
the moment :)

I think he's also currently got a rebased version of your series with
some changes on top, so stay tuned.

> I'll try to review patches though.

That would certainly be appreciated, cheers!

Will


From shubhrajyoti.datta at gmail.com  Wed Aug  5 03:46:44 2015
From: shubhrajyoti.datta at gmail.com (Shubhrajyoti Datta)
Date: Wed, 5 Aug 2015 16:16:44 +0530
Subject: [PATCH-v5 2/5] i2c: pxa: enable/disable i2c module across msg xfer
In-Reply-To: <1437482466-16126-3-git-send-email-vaibhav.hiremath@linaro.org>
References: <1437482466-16126-1-git-send-email-vaibhav.hiremath@linaro.org>
 <1437482466-16126-3-git-send-email-vaibhav.hiremath@linaro.org>
Message-ID: <CAKfKVtGzDjgHzy70aa0d2W=ROMcxVzerg-qpuB9e4PaGKPpMTQ@mail.gmail.com>

hi ,
On Tue, Jul 21, 2015 at 6:11 PM, Vaibhav Hiremath
<vaibhav.hiremath at linaro.org> wrote:
> From: Yi Zhang <yizhang at marvell.com>
>
> Enable i2c module/unit before transmission and disable when it
> finishes.
>
> why?
> It's because the i2c bus may be disturbed if the slave device,
> typically a touch, powers on.

Why should that be an issue?
Is it an errata.

In which mode it is an issue slave / master or both?

>
> As we do not want to break slave mode support, this patch introduces
> DT property to control disable of the I2C module after xfer in master
> mode of operation.
>
> i2c-disable-after-xfer : If set, driver will disable I2C module after
> msg xfer
>
> Signed-off-by: Yi Zhang <yizhang at marvell.com>
> Signed-off-by: Vaibhav Hiremath <vaibhav.hiremath at linaro.org>
> ---


From julien.grall at citrix.com  Wed Aug  5 03:51:01 2015
From: julien.grall at citrix.com (Julien Grall)
Date: Wed, 5 Aug 2015 11:51:01 +0100
Subject: [PATCH v2 4/8] xen: Use the correctly the Xen memory terminologies
In-Reply-To: <55C147DD.7000600@oracle.com>
References: <1438711972-18752-1-git-send-email-julien.grall@citrix.com>
 <1438711972-18752-5-git-send-email-julien.grall@citrix.com>
 <55C147DD.7000600@oracle.com>
Message-ID: <55C1EA95.5060504@citrix.com>

Hi Boris,

On 05/08/15 00:16, Boris Ostrovsky wrote:
> On 08/04/2015 02:12 PM, Julien Grall wrote:
>>     /*
>>    * We detect special mappings in one of two ways:
>> @@ -217,9 +232,13 @@ static inline unsigned long
>> bfn_to_local_pfn(unsigned long mfn)
>>     /* VIRT <-> MACHINE conversion */
>>   #define virt_to_machine(v)    (phys_to_machine(XPADDR(__pa(v))))
>> -#define virt_to_pfn(v)          (PFN_DOWN(__pa(v)))
>>   #define virt_to_mfn(v)        (pfn_to_mfn(virt_to_pfn(v)))
>>   #define mfn_to_virt(m)        (__va(mfn_to_pfn(m) << PAGE_SHIFT))
>> +#define virt_to_pfn(v)          (PFN_DOWN(__pa(v)))
> 
> This looks like unnecessary change.

Right, I made the mistake when I re-introduced virt_to_mfn in this
version. It was dropped in the previous one.

>> diff --git a/drivers/video/fbdev/xen-fbfront.c
>> b/drivers/video/fbdev/xen-fbfront.c
>> index 09dc447..25e3cce 100644
>> --- a/drivers/video/fbdev/xen-fbfront.c
>> +++ b/drivers/video/fbdev/xen-fbfront.c
>> @@ -539,7 +539,7 @@ static int xenfb_remove(struct xenbus_device *dev)
>>     static unsigned long vmalloc_to_mfn(void *address)
>>   {
>> -    return pfn_to_mfn(vmalloc_to_pfn(address));
>> +    return pfn_to_gfn(vmalloc_to_pfn(address));
>>   }
> 
> Are you sure? This will return vmalloc_to_pfn(address)).

I guess you mean vmalloc_to_mfn will return vmalloc_to_pfn?

If so, it will be only the case on auto-translated case (because pfn ==
gfn). In the case of PV, the mfn will be returned.

Although, this function is misnamed. It's fixed in a follow-up patch
(see #6) because it's required more renaming than this function. I
didn't want to add such changes within this patch.

Regards,

-- 
Julien Grall


From jassisinghbrar at gmail.com  Wed Aug  5 03:52:01 2015
From: jassisinghbrar at gmail.com (Jassi Brar)
Date: Wed, 5 Aug 2015 16:22:01 +0530
Subject: [RFC PATCH 0/3] mailbox: hisilicon: add mailbox driver
In-Reply-To: <1438564390-28111-1-git-send-email-leo.yan@linaro.org>
References: <1438564390-28111-1-git-send-email-leo.yan@linaro.org>
Message-ID: <CABb+yY0-RQ80q92EBsuBoYpjxW5zR=nXr+j3zCXw3wKkCf33OQ@mail.gmail.com>

On Mon, Aug 3, 2015 at 6:43 AM, Leo Yan <leo.yan at linaro.org> wrote:
> This patch series is to implement Hisilicon's mailbox driver and enable
> the mailbox controller on Hi6220.
>
Cool.

> The Hisilicon mailbox supports up to 32 channels. Each channel is
> unidirectional with a maximum message size of 8 words. I/O is performed
> using register access (there is no DMA) and the cell raises an interrupt
> when messages are received.
>
FYI, none of other platforms has mailbox with DMA. 8-word deep fifo,
RX interrupt
and optional TX interrupt is pretty common. So cool still.

> For easily extending for Hisilicon series SoCs (SoCs may have difference
> for register's definition with each other), so firstly implement common
> mailbox driver; this common mailbox driver provides three mainly
> functionality:
>
>  - help register channels into framework;
>  - hook low level callback functions for register's operations;
>  - Enhance rx channel's message queue, which is based on the code in
>    drivers/mailbox/omap-mailbox.c.
>
Not cool.
 Please don't reinvent the wheel by having platform specific
implementation of the mailbox api. Which vendor doesn't plan to roll
out new SoCs, and hence variations of mailbox controllers?  The OMAP
stack predates the common api, and was actually supposed to be
converted over eventually. Please implement just the
drivers/mailbox/hi6220-mailbox.c (preferably by the name of the
mailbox controller, if any)

Thanks.


From haibo.chen at freescale.com  Wed Aug  5 03:38:42 2015
From: haibo.chen at freescale.com (Haibo Chen)
Date: Wed, 5 Aug 2015 18:38:42 +0800
Subject: [PATCH v4 6/6] mmc: sdhci-esdhc-imx: set back the burst_length_enable
 bit to 1
In-Reply-To: <1438771122-8601-1-git-send-email-haibo.chen@freescale.com>
References: <1438771122-8601-1-git-send-email-haibo.chen@freescale.com>
Message-ID: <1438771122-8601-7-git-send-email-haibo.chen@freescale.com>

Currently we find that if a usdhc is choosed to boot system, then ROM
code will set the burst length enable bit of this usdhc as 0.

This will make performance drop a lot if this usdhc's burst length is
configed. So this patch set back the burst_length_enable bit as 1,
which is the default value, and means burst length is enabled for INCR.

Signed-off-by: Haibo Chen <haibo.chen at freescale.com>
---
 drivers/mmc/host/sdhci-esdhc-imx.c | 16 ++++++++++++++++
 1 file changed, 16 insertions(+)

diff --git a/drivers/mmc/host/sdhci-esdhc-imx.c b/drivers/mmc/host/sdhci-esdhc-imx.c
index 97aa944..3334762 100644
--- a/drivers/mmc/host/sdhci-esdhc-imx.c
+++ b/drivers/mmc/host/sdhci-esdhc-imx.c
@@ -32,6 +32,7 @@
 #include "sdhci-esdhc.h"
 
 #define	ESDHC_CTRL_D3CD			0x08
+#define ESDHC_BURST_LEN_EN_INCR		(1 << 27)
 /* VENDOR SPEC register */
 #define ESDHC_VENDOR_SPEC		0xc0
 #define  ESDHC_VENDOR_SPEC_SDIO_QUIRK	(1 << 1)
@@ -1165,6 +1166,21 @@ static int sdhci_esdhc_imx_probe(struct platform_device *pdev)
 		host->quirks2 |= SDHCI_QUIRK2_PRESET_VALUE_BROKEN;
 		host->mmc->caps |= MMC_CAP_1_8V_DDR;
 
+		/*
+		 * ROM code will change the bit burst_length_enable setting
+		 * to zero if this usdhc is choosed to boot system. Change
+		 * it back here, otherwise it will impact the performance a
+		 * lot. This bit is used to enable/disable the burst length
+		 * for the external AHB2AXI bridge, it's usefully especially
+		 * for INCR transfer because without burst length indicator,
+		 * the AHB2AXI bridge does not know the burst length in
+		 * advance. And without burst length indicator, AHB INCR
+		 * transfer can only be converted to singles on the AXI side.
+		 */
+		writel(readl(host->ioaddr + SDHCI_HOST_CONTROL)
+			| ESDHC_BURST_LEN_EN_INCR,
+			host->ioaddr + SDHCI_HOST_CONTROL);
+
 		if (!(imx_data->socdata->flags & ESDHC_FLAG_HS200))
 			host->quirks2 |= SDHCI_QUIRK2_BROKEN_HS200;
 
-- 
1.9.1



From zyw at rock-chips.com  Wed Aug  5 03:51:59 2015
From: zyw at rock-chips.com (Chris Zhong)
Date: Wed, 05 Aug 2015 18:51:59 +0800
Subject: [PATCH v3 3/3] ARM: rockchip: enable PMU_GPIOINT_WAKEUP_EN when
 entering shallow suspend
In-Reply-To: <1544453.8uqOvAiDmD@diego>
References: <2128609.Kb18M8K28F@diego> <1544453.8uqOvAiDmD@diego>
Message-ID: <55C1EACF.1060702@rock-chips.com>



On 08/05/2015 06:51 AM, Heiko St?bner wrote:
> PMU_GPIOINT_WAKEUP_EN seems needed when entering the shallow suspend
> (with logic staying on) but does not seem to be needed for the deep
> suspend for unknown reasons.
> Testing revealed that this setting really is necessary to reliably
> resume the veyron devices from suspend.
>
> Reported-by: Chris Zhong <zyw at rock-chips.com>
> Signed-off-by: Heiko Stuebner <heiko at sntech.de>
> ---
>   arch/arm/mach-rockchip/pm.c | 9 ++++++---
>   arch/arm/mach-rockchip/pm.h | 1 +
>   2 files changed, 7 insertions(+), 3 deletions(-)
>
> diff --git a/arch/arm/mach-rockchip/pm.c b/arch/arm/mach-rockchip/pm.c
> index c11a30b..156cd23 100644
> --- a/arch/arm/mach-rockchip/pm.c
> +++ b/arch/arm/mach-rockchip/pm.c
> @@ -123,9 +123,6 @@ static void rk3288_slp_mode_set(int level)
>   	regmap_write(sgrf_regmap, RK3288_SGRF_FAST_BOOT_ADDR,
>   		     rk3288_bootram_phy);
>   
> -	regmap_write(pmu_regmap, RK3288_PMU_WAKEUP_CFG1,
> -		     PMU_ARMINT_WAKEUP_EN);
> -
>   	mode_set = BIT(PMU_GLOBAL_INT_DISABLE) | BIT(PMU_L2FLUSH_EN) |
>   		   BIT(PMU_SREF0_ENTER_EN) | BIT(PMU_SREF1_ENTER_EN) |
>   		   BIT(PMU_DDR0_GATING_EN) | BIT(PMU_DDR1_GATING_EN) |
> @@ -146,6 +143,9 @@ static void rk3288_slp_mode_set(int level)
>   		mode_set1 |= BIT(PMU_CLR_ALIVE) | BIT(PMU_CLR_BUS) |
>   			     BIT(PMU_CLR_PERI) | BIT(PMU_CLR_DMA);
>   
> +		regmap_write(pmu_regmap, RK3288_PMU_WAKEUP_CFG1,
> +			     PMU_ARMINT_WAKEUP_EN);
> +
>   		/*
>   		 * In deep suspend we use PMU_PMU_USE_LF to let the rk3288
>   		 * switch its main clock supply to the alternative 32kHz
> @@ -166,6 +166,9 @@ static void rk3288_slp_mode_set(int level)
>   		 */
>   		mode_set |= BIT(PMU_CLK_CORE_SRC_GATE_EN);
>   
> +		regmap_write(pmu_regmap, RK3288_PMU_WAKEUP_CFG1,
> +			     PMU_ARMINT_WAKEUP_EN | PMU_GPIOINT_WAKEUP_EN);
> +
>   		/* 30ms on a 24MHz clock for pmic stabilization */
>   		regmap_write(pmu_regmap, RK3288_PMU_STABL_CNT, 24000 * 30);
>   
> diff --git a/arch/arm/mach-rockchip/pm.h b/arch/arm/mach-rockchip/pm.h
> index 8a55ee2..b5af26f 100644
> --- a/arch/arm/mach-rockchip/pm.h
> +++ b/arch/arm/mach-rockchip/pm.h
> @@ -61,6 +61,7 @@ static inline void rockchip_suspend_init(void)
>   
>   /* PMU_WAKEUP_CFG1 bits */
>   #define PMU_ARMINT_WAKEUP_EN		BIT(0)
> +#define PMU_GPIOINT_WAKEUP_EN		BIT(3)
>   
>   enum rk3288_pwr_mode_con {
>   	PMU_PWR_MODE_EN = 0,
>
Reviewed-by: Chris Zhong <zyw at rock-chips.com>
Tested-by: Chris Zhong <zyw at rock-chips.com>



From laurent.pinchart at ideasonboard.com  Wed Aug  5 03:53:35 2015
From: laurent.pinchart at ideasonboard.com (Laurent Pinchart)
Date: Wed, 05 Aug 2015 13:53:35 +0300
Subject: [PATCH v3 0/5] iommu/arm-smmu: add support for non-pci devices
In-Reply-To: <20150805104524.GD6092@arm.com>
References: <1437463833-16112-1-git-send-email-thunder.leizhen@huawei.com>
 <2351780.FdaR8mZqKs@avalon> <20150805104524.GD6092@arm.com>
Message-ID: <2055191.Tg39UMkbi6@avalon>

Hi Will,

On Wednesday 05 August 2015 11:45:24 Will Deacon wrote:
> On Tue, Aug 04, 2015 at 11:50:45PM +0100, Laurent Pinchart wrote:
> > On Tuesday 28 July 2015 13:48:47 Will Deacon wrote:
> >> On Tue, Jul 21, 2015 at 11:30:07AM +0100, Robin Murphy wrote:
> >>> On 21/07/15 08:30, Zhen Lei wrote:
> >>>> Changelog:
> >>>> v2 -> v3:
> >>>> 1. add support for pci device hotplug, which missed in patch v2.
> >>>> 2. only support #iommu-cells = <1>, add corresponding description in
> >>>> arm,smmu-v3.txt. 3. add function find_smmu_by_device which extracted
> >>>> from find_smmu_by_node, to resolve> >
> >>>> 
> >>>>     the problem mentioned by Robin Murphy in [PATCH v2 7/9].
> >>>>     Additionally:
> >>>>     +    platform_set_drvdata(pdev, smmu);       //Patch v2
> >>>>     +	dev->archdata.iommu = smmu;             //Patch v3, dev =
> >>>>     &pdev->dev
> >>> 
> >>> I didn't give any Reviewed-by tags, much less to revised patches that
> >>> I've not even looked at yet; please see section 13 of
> >>> Documentation/SubmittingPatches for what the Reviewed-by tag means.
> >> 
> >> That said, it would be great if you could review the patches anyway ;)
> >> 
> >> Also, it looks like this is all based on Laurent's IOMMU probe deferral
> >> series which hasn't seen any movement for a while.
> >> 
> >> Laurent: are you planning to repost that, or is it worth us picking up
> >> the original version and bashing it into shape ourselves?
> > 
> > I'd really appreciate if you could take it where I left it and get into
> > shape for upstream. I have no time to work on IOMMU at the moment I'm
> > afraid :-(
>
> No problem at all. It will probably be Robin doing most of the hacking,
> since he's the platform_device guy and I'm the PCI guy in the office at
> the moment :)
> 
> I think he's also currently got a rebased version of your series with
> some changes on top, so stay tuned.

Great ! As they say here, paljon kiitoksia (yes, Finnish can be used on 
mailing lists for other purposes than cursing ;-)).

> > I'll try to review patches though.
> 
> That would certainly be appreciated, cheers!

-- 
Regards,

Laurent Pinchart



From christoffer.dall at linaro.org  Wed Aug  5 03:53:45 2015
From: christoffer.dall at linaro.org (Christoffer Dall)
Date: Wed, 5 Aug 2015 12:53:45 +0200
Subject: [PATCH v3 09/11] KVM: arm/arm64: vgic: Prevent userspace
 injection of a mapped interrupt
In-Reply-To: <55C1DAE9.1050609@arm.com>
References: <1437753309-17989-1-git-send-email-marc.zyngier@arm.com>
 <1437753309-17989-10-git-send-email-marc.zyngier@arm.com>
 <55C0E690.1090808@linaro.org> <55C0EBF5.2060708@arm.com>
 <55C1BBF9.2060004@linaro.org> <55C1DAE9.1050609@arm.com>
Message-ID: <20150805105345.GA4657@cbox>

On Wed, Aug 05, 2015 at 10:44:09AM +0100, Marc Zyngier wrote:
> On 05/08/15 08:32, Eric Auger wrote:
> > Hi Marc,
> > On 08/04/2015 06:44 PM, Marc Zyngier wrote:
> >> On 04/08/15 17:21, Eric Auger wrote:
> >>> Hi Marc,
> >>> On 07/24/2015 05:55 PM, Marc Zyngier wrote:
> >>>> Virtual interrupts mapped to a HW interrupt should only be triggered
> >>>> from inside the kernel. Otherwise, you could end up confusing the
> >>>> kernel (and the GIC's) state machine.
> >>>>
> >>>> Rearrange the injection path so that kvm_vgic_inject_irq is
> >>>> used for non-mapped interrupts, and kvm_vgic_inject_mapped_irq is
> >>>> used for mapped interrupts. The latter should only be called from
> >>>> inside the kernel (timer, VFIO).
> >>> nit: I would replace VFIO by irqfd.
> >>> VFIO just triggers the eventfd/irqfd. This is KVM/irqfd that injects the
> >>> virtual irq upon the irqfd signaling and he irqfd adaptation/ARM
> >>> currently is implemented in vgic.c
> >>
> >> Ah, thanks for reminding me of the right terminology, I tend to think of
> >> it as one big bag of nasty tricks... ;-)
> >>
> >> I'll update the commit message.
> >>
> >>>>
> >>>> Signed-off-by: Marc Zyngier <marc.zyngier at arm.com>
> >>>> ---
> >>>>  include/kvm/arm_vgic.h |  2 +
> >>>>  virt/kvm/arm/vgic.c    | 99 ++++++++++++++++++++++++++++++++++----------------
> >>>>  2 files changed, 70 insertions(+), 31 deletions(-)
> >>>>
> >>>> diff --git a/include/kvm/arm_vgic.h b/include/kvm/arm_vgic.h
> >>>> index 7306b4b..f6bfd79 100644
> >>>> --- a/include/kvm/arm_vgic.h
> >>>> +++ b/include/kvm/arm_vgic.h
> >>>> @@ -351,6 +351,8 @@ void kvm_vgic_flush_hwstate(struct kvm_vcpu *vcpu);
> >>>>  void kvm_vgic_sync_hwstate(struct kvm_vcpu *vcpu);
> >>>>  int kvm_vgic_inject_irq(struct kvm *kvm, int cpuid, unsigned int irq_num,
> >>>>  			bool level);
> >>>> +int kvm_vgic_inject_mapped_irq(struct kvm *kvm, int cpuid,
> >>>> +			       struct irq_phys_map *map, bool level);
> >>>>  void vgic_v3_dispatch_sgi(struct kvm_vcpu *vcpu, u64 reg);
> >>>>  int kvm_vgic_vcpu_pending_irq(struct kvm_vcpu *vcpu);
> >>>>  int kvm_vgic_vcpu_active_irq(struct kvm_vcpu *vcpu);
> >>>> diff --git a/virt/kvm/arm/vgic.c b/virt/kvm/arm/vgic.c
> >>>> index 3f7b690..e40ef70 100644
> >>>> --- a/virt/kvm/arm/vgic.c
> >>>> +++ b/virt/kvm/arm/vgic.c
> >>>> @@ -1533,7 +1533,8 @@ static int vgic_validate_injection(struct kvm_vcpu *vcpu, int irq, int level)
> >>>>  }
> >>>>  
> >>>>  static int vgic_update_irq_pending(struct kvm *kvm, int cpuid,
> >>>> -				  unsigned int irq_num, bool level)
> >>>> +				   struct irq_phys_map *map,
> >>>> +				   unsigned int irq_num, bool level)
> >>>>  {
> >>> In vgic_update_irq_pending, I needed to modify the following line and
> >>> add the "&& !map".
> >>>
> >>>         if (!vgic_validate_injection(vcpu, irq_num, level) && !map) {
> >>>
> >>> Without that, the level being not properly modeled for level sensitive
> >>> forwarded IRQs, the 2d injection fails.
> >>
> >> Ah! Is that because we never see the line being reset to zero, and the
> >> VGIC still sees the line as pending at the distributor level?
> > yes indeed
> 
> Then it is a bigger problem we need to solve, and your solution just
> papers over the issue.
> 
> The main problem is that irqfd is essentially an edge-triggered
> signalling. Fire and forget. Given that we're dealing with a level
> triggered interrupt, we end up with the interrupt still marked as
> pending (nobody took the signal down).
> 
> The usual way to get out of that mess in is to evaluate the state of the
> level on EOI. But we can't trap on EOI for a HW interrupt.
> 
> So it raises the question: should we instead consider the HW pending
> state instead of the software one for mapped interrupts? It is
> expensive, but it feels more correct.
> 
I thought we already covered this at LCA.  For mapped interrupts
(forwarded) we should never consider the software pending state, because
that state is managed by the hardware.  Or am I confusing concepts here?

Thanks,
-Christoffer


From javier at osg.samsung.com  Wed Aug  5 03:53:20 2015
From: javier at osg.samsung.com (Javier Martinez Canillas)
Date: Wed, 5 Aug 2015 12:53:20 +0200
Subject: [PATCH 1/2] mfd: s2mps11: Add manual shutdown method for Odroid
 XU3
In-Reply-To: <1438605447-6836-2-git-send-email-k.kozlowski.k@gmail.com>
References: <1438605447-6836-1-git-send-email-k.kozlowski.k@gmail.com>
 <1438605447-6836-2-git-send-email-k.kozlowski.k@gmail.com>
Message-ID: <55C1EB20.3040400@osg.samsung.com>

Hello Krzysztof,

On 08/03/2015 02:37 PM, Krzysztof Kozlowski wrote:
> On Odroid XU3 board (with S2MPS11 PMIC) the PWRHOLD bit in CTRL1
> register must be manually set to 0 before initiating power off sequence.
> 
> One of usual power down methods for Exynos based devices looks like:
> 1. PWRHOLD pin of PMIC is connected to PSHOLD of Exynos.
> 2. Exynos holds up this pin during system operation.
> 3. ACOKB pin of PMIC is pulled up to VBATT and optionally to pin in
>    other device.
> 4. When PWRHOLD/PSHOLD goes low, the PMIC will turn off the power if
>    ACOKB goes high.
> 
> On Odroid XU3 family the difference is in (3) - the ACOKB is grounded.
> This means that PMIC must manually set PWRHOLD field to low and then
> wait for signal from Application Processor (the usual change in
> PWRHOLD/PSHOLD pin will actually cut off the power).
>

Is nice to finally have an explanation about why this is needed.
 
> The patch adds respective binding allowing Odroid XU3 device to be
> powered off.
> 
> Signed-off-by: Krzysztof Kozlowski <k.kozlowski.k at gmail.com>
> Reported-by: Anand Moon <linux.amoon at gmail.com>
> 
> ---
> 
> Patch is losely based on patch in Hardkernel repository [0] and previous
> work of Anand Moon [1].
> 
> [0] https://github.com/hardkernel/linux/commit/6897e62ba328bd1c8c095d918101863250cd73e7
> [1] http://www.spinics.net/lists/linux-samsung-soc/msg45959.html
> ---
>  Documentation/devicetree/bindings/mfd/s2mps11.txt |  4 +++
>  drivers/mfd/sec-core.c                            | 31 +++++++++++++++++++++++
>  include/linux/mfd/samsung/core.h                  |  2 ++
>  include/linux/mfd/samsung/s2mps11.h               |  1 +
>  4 files changed, 38 insertions(+)
>

The patch looks good to me.

Reviewed-by: Javier Martinez Canillas <javier at osg.samsung.com>

Best regards,
-- 
Javier Martinez Canillas
Open Source Group
Samsung Research America


From tony at atomide.com  Wed Aug  5 03:54:00 2015
From: tony at atomide.com (Tony Lindgren)
Date: Wed, 5 Aug 2015 03:54:00 -0700
Subject: [PATCH 0/7] ARM: dts: MMC fixes for DRA7 based boards
In-Reply-To: <1438244020-4244-1-git-send-email-kishon@ti.com>
References: <1438244020-4244-1-git-send-email-kishon@ti.com>
Message-ID: <20150805105400.GF16878@atomide.com>

* Kishon Vijay Abraham I <kishon at ti.com> [150730 01:16]:
> Miscellaneous fixes in dts files for MMC device tree nodes.
> 
> Did basic read/write test in J6, J6 Eco and Beagle-x15
> 
> Balaji T K (1):
>   ARM: dts: dra7-evm: add evm_3v3_sd regulator
> 
> Kishon Vijay Abraham I (5):
>   ARM: dts: dra72-evm: add evm_3v3_sd regulator
>   ARM: dts: dra72-evm: Set max clock frequency of MMC1 and MMC2
>   ARM: dts: am57xx-beagle-x15: mmc1: remove redundant pbias-supply
>     property
>   ARM: dts: dra7-evm: Fix spurious card insert/removal interrupt
>   ARM: dts: dra72-evm: Fix spurious card insert/removal interrupt
> 
> Nishanth Menon (1):
>   ARM: dts: dra7-evm: Add MMCSD card removal GPIO
> 
>  arch/arm/boot/dts/am57xx-beagle-x15.dts |    1 -
>  arch/arm/boot/dts/dra7-evm.dts          |   18 +++++++++++++++++-
>  arch/arm/boot/dts/dra72-evm.dts         |   16 ++++++++++++++--
>  3 files changed, 31 insertions(+), 4 deletions(-)

Thanks applying all these into omap-for-v4.3/dt.

Tony


From javier at osg.samsung.com  Wed Aug  5 03:54:30 2015
From: javier at osg.samsung.com (Javier Martinez Canillas)
Date: Wed, 5 Aug 2015 12:54:30 +0200
Subject: [PATCH 2/2] ARM: dts: Fix power off method on exynos5422-odroidxu3
In-Reply-To: <1438605447-6836-3-git-send-email-k.kozlowski.k@gmail.com>
References: <1438605447-6836-1-git-send-email-k.kozlowski.k@gmail.com>
 <1438605447-6836-3-git-send-email-k.kozlowski.k@gmail.com>
Message-ID: <55C1EB66.4030706@osg.samsung.com>

Hello Krzysztof,

On 08/03/2015 02:37 PM, Krzysztof Kozlowski wrote:
> The Odroid XU3 family boards have ACOKB pin of PMIC grounded, instead of
> pulled up as usual. This means that PMIC must manually set PWRHOLD field
> in its CTRL1 register to low before initiating power down.
> 
> This fixes Odroid XU3 powering off:
> [   25.966053] reboot: Power down
> [   25.967679] Power down.
> [   26.070174] Power down failed, please power off system manually.
> 
> Signed-off-by: Krzysztof Kozlowski <k.kozlowski.k at gmail.com>
> Reported-by: Anand Moon <linux.amoon at gmail.com>
> ---
>  arch/arm/boot/dts/exynos5422-odroidxu3-common.dtsi | 1 +
>  1 file changed, 1 insertion(+)
> 
> diff --git a/arch/arm/boot/dts/exynos5422-odroidxu3-common.dtsi b/arch/arm/boot/dts/exynos5422-odroidxu3-common.dtsi
> index 1565667e6f69..48cecc8cf26e 100644
> --- a/arch/arm/boot/dts/exynos5422-odroidxu3-common.dtsi
> +++ b/arch/arm/boot/dts/exynos5422-odroidxu3-common.dtsi
> @@ -159,6 +159,7 @@
>  		s2mps11,buck2-ramp-enable = <1>;
>  		s2mps11,buck3-ramp-enable = <1>;
>  		s2mps11,buck4-ramp-enable = <1>;
> +		samsung,s2mps11-acokb-ground;
>  
>  		interrupt-parent = <&gpx0>;
>  		interrupts = <4 IRQ_TYPE_EDGE_FALLING>;
> 

Reviewed-by: Javier Martinez Canillas <javier at osg.samsung.com>

Best regards,
-- 
Javier Martinez Canillas
Open Source Group
Samsung Research America


From sudeep.holla at arm.com  Wed Aug  5 03:58:04 2015
From: sudeep.holla at arm.com (Sudeep Holla)
Date: Wed, 05 Aug 2015 11:58:04 +0100
Subject: [PATCH v4 1/6] ARM: shmobile: r8a7740 dtsi: Add L2
 cache-controller node
In-Reply-To: <CAMuHMdXdEV+41mH338bDbazzqOErDLQkBUAj2+uVX4Wupn1ABQ@mail.gmail.com>
References: <1438765090-823-1-git-send-email-geert+renesas@glider.be>	<1438765090-823-2-git-send-email-geert+renesas@glider.be>	<55C1D894.8070302@arm.com>
 <CAMuHMdXdEV+41mH338bDbazzqOErDLQkBUAj2+uVX4Wupn1ABQ@mail.gmail.com>
Message-ID: <55C1EC3C.9000407@arm.com>

Hi Geert,

On 05/08/15 11:44, Geert Uytterhoeven wrote:
> Hi Sudeep,
>
> On Wed, Aug 5, 2015 at 11:34 AM, Sudeep Holla <sudeep.holla at arm.com> wrote:
>> On 05/08/15 09:58, Geert Uytterhoeven wrote:
>>> Add the missing L2 cache-controller node. This will allow migration to
>>> the generic l2c OF initialization.
>>>
>>> The L2 cache is an ARM L2C-310 (r3p1-150rel0), of size 256 KiB (32 KiB x
>>> 8 ways).
>>>
>>> Signed-off-by: Geert Uytterhoeven <geert+renesas at glider.be>
>
>>> diff --git a/arch/arm/boot/dts/r8a7740.dtsi
>>> b/arch/arm/boot/dts/r8a7740.dtsi
>>> index d84714468cce18df..ddef5b1c68fa06b3 100644
>>> --- a/arch/arm/boot/dts/r8a7740.dtsi
>>> +++ b/arch/arm/boot/dts/r8a7740.dtsi
>>> @@ -37,6 +37,22 @@
>>>                        <0xc2000000 0x1000>;
>>>          };
>>>
>>> +       L2: cache-controller {
>>> +               compatible = "arm,pl310-cache";
>>> +               reg = <0xf0100000 0x1000>;
>>> +               interrupts = <0 84 IRQ_TYPE_LEVEL_HIGH>;
>>> +               power-domains = <&pd_a3sm>;
>>> +               arm,data-latency = <3 3 3>;
>>> +               arm,tag-latency = <2 2 2>;
>>> +               arm,shared-override;
>>> +               cache-unified;
>>> +               cache-level = <2>;
>>> +               cache-size = <0x40000>;
>>> +               cache-sets = <1024>;
>>> +               cache-block-size = <32>;
>>> +               cache-line-size = <32>;
>>
>>
>> Any particular reason whey you need all this cache-* properties ? Is
>
> To describe the cache as good as possible.
>

Why if you can probe it ? IMO DT is mostly useful to describe things
that can't be probed/discovered using hardware.

>> something broken on these SoCs ? We should be able to get most of these
>> information from the SoC(reading some registers). It's good to avoid
>> passing them via DT if they can be discovered from hardware.
>
> So we have all these documented properties in
> Documentation/devicetree/bindings/arm/l2cc.txt, but they're not meant to
> be used?
>

No I didn't mean that, I just wanted to know if they can't be probed due
to some hardware issue. It would avoid issues with wrong DTs especially
if they are not so easy to upgrade.

Regards,
Sudeep


From will.deacon at arm.com  Wed Aug  5 04:09:30 2015
From: will.deacon at arm.com (Will Deacon)
Date: Wed, 5 Aug 2015 12:09:30 +0100
Subject: [PATCHv5 0/5] arm/arm64: Unify PSCI client support
In-Reply-To: <CAOesGMh9Lx=eVTzSQcU63ttLWX8St5T5cFDDKozO4nmvoqU0Lw@mail.gmail.com>
References: <1438353980-7611-1-git-send-email-mark.rutland@arm.com>
 <20150803143703.GH10501@arm.com>
 <CAOesGMh9Lx=eVTzSQcU63ttLWX8St5T5cFDDKozO4nmvoqU0Lw@mail.gmail.com>
Message-ID: <20150805110930.GE6092@arm.com>

On Wed, Aug 05, 2015 at 08:41:31AM +0100, Olof Johansson wrote:
> On Mon, Aug 3, 2015 at 4:37 PM, Will Deacon <will.deacon at arm.com> wrote:
> > On Fri, Jul 31, 2015 at 03:46:15PM +0100, Mark Rutland wrote:
> >> This series unifies the 32-bit and 64-bit PSCI client code, moving the bulk of
> >> the FW invocation and probing out to a common location in drivers/firmware. The
> >> bulk of the PSCI 0.2 cleanups have hit mainline now, so this is just the
> >> unification portion.
> >>
> >> This results in a reasonable saving in terms of lines of code, and will allow
> >> for PSCI 1.0 support to be unified form the beginning, avoiding further
> >> duplication.
> >>
> >> Since v4 [1]:
> >> * Apply Rob Herring's ack
> >> * Rebase to v4.2-rc2 to handle a trivial conflict
> >> * Reorder the series to keep arch/arm patches together
> >> Since v3 [2]:
> >> * Drop the PSCI 0.2 patches as they're in mainline
> >> * s/__pa/virt_to_idmap/ from Grygorii Strashko
> >> * Use macros for Calxeda CPU_SUSPEND parameters
> >>
> >> Russell, are you happy with the arch/arm patches? If so, are you happy for them
> >> to go via another tree, or would you prefer that I set up a stable branch for
> >> merging?
> >>
> >> I was under the impression that you had already taken Grygorii's patch but I
> >> couldn't spot it in any branches. I can drop that if you already have it.
> >
> > I've been looking at merging this, but it's a tad fiddly touching all of
> > arm, arm64 and drivers. One way to do it would be:
> >
> >   (1) I create a branch containing patches 1,2 and 5 based on -rc2 and
> >       merge that into the arm64/for-next/core branch. There's a minor
> >       conflict, but it's easy to resolve.
> >
> >   (2) I create another branch, which is just the branch merged in (1) +
> >       patches 3 and 4 on top. I send a pull request for that to rmk.
> >
> >   (3) Torvalds will get the minor conflict resolved in (1) when he merges
> >       the arm and arm64 trees.
> >
> > If we're not comfortable with (3), then the whole lot could go via
> > arm-soc instead (including the conflict resolution).
> >
> > Russell, Olof, any preferences?
> 
> Wouldn't it be easiest to just get acks on patch 3 and 4 and just
> merge it all through your tree?

That would work if Russell is ok with it (it needs his acks).

Russell: would you prefer to ack 3+4 and have me take them via the arm64
tree or instead have me send you a pull request with a conflict resolution
for Torvalds? Yet another option is to postpone the arch/arm/ part to
4.4.

Will


From linux at arm.linux.org.uk  Wed Aug  5 04:27:13 2015
From: linux at arm.linux.org.uk (Russell King - ARM Linux)
Date: Wed, 5 Aug 2015 12:27:13 +0100
Subject: arm kernel oops in highmem.c with 4.2
In-Reply-To: <CALeDE9PXF=gQCaBCiHpHy2nXOooQOmsCQvSgOv+wQw3mta=P6A@mail.gmail.com>
References: <CALeDE9Ox3=sh3AXQ0NUG6BBfU5i5YrMY=LDpcTHQWqz2=60F2g@mail.gmail.com>
 <20150805100701.GV7557@n2100.arm.linux.org.uk>
 <CALeDE9PXF=gQCaBCiHpHy2nXOooQOmsCQvSgOv+wQw3mta=P6A@mail.gmail.com>
Message-ID: <20150805112713.GY7557@n2100.arm.linux.org.uk>

On Wed, Aug 05, 2015 at 11:13:07AM +0100, Peter Robinson wrote:
> On Wed, Aug 5, 2015 at 11:07 AM, Russell King - ARM Linux
> <linux at arm.linux.org.uk> wrote:
> > On Wed, Aug 05, 2015 at 11:01:01AM +0100, Peter Robinson wrote:
> >> Hi All,
> >>
> >> On Fedora 23 with recent 4.2 kernels we're seeing a crash (below) in
> >> highmem.c on a fairly regular occurrence across a number of different
> >> SoCs, I've seen it with at least AllWinner A20, i.MX6Q, Tegra2 and 124
> >> with both a LPAE and non LPAE kernel, seen it happen when doing a
> >> number of different things but regenerating a initrd, applying updates
> >> (dnf/yum) and starting X are all pretty good triggers.
> >
> > I've yet to see any problems with mainline 4.2-rc5 kernels on any of my
> > iMX6 platforms, which includes initramfs regeneration, apt-get updates
> > and X.
> >
> >> [71751.658105] ------------[ cut here ]------------
> >> [71751.658153] kernel BUG at arch/arm/mm/highmem.c:114!
> >
> > Well, in mainline kernels, the BUG is on line 113, not line 114.  So at
> > least this file is modified from mainline kernels.  Maybe the problem is
> > caused by patches applied to Fedora kernels?
> 
> We apply a crash driver patch [1] which has been there forever (long
> enough that I'd forgotten it) but other than that for arm kernels we
> currently don't apply any arm specific patches in 4.2.

It helps if I look at 4.2 rather than an older kernel :)

However, I've checked that I have DEBUG_HIGHMEM enabled, which I do, and
I'm unable to reproduce this here.  My kernels are built with gcc 4.7.4.

What it looks like from your oops is that the address which was passed
in was 0xffedf000, but the address we calculated via the following for
the current index was 0xfff00000:

type = kmap_atomic_idx();
idx = type + KM_TYPE_NR * smp_processor_id();
__fix_to_virt(idx)

Doing a bit of maths... the address 0xffedf000 corresponds to a fixmap
index of... (0xffeff000 - 0xffedf000) >> 12 = 32.  KM_TYPE_NR is 16 on
ARM, so the mapping was created by CPU 2, and type was zero.

On unmap, 0xfff00000 gives... (0xffeff000 - 0xfff00000) >> 12 = -1.
That suggests we're on CPU 0, and type is -1 - in other words, there
are no atomically mapped mappings on CPU 0.

Since kmap_atomic() disables preemption and page faults, how did your
kernel migrate this thread from CPU 2 to CPU 0... and I can't see how
that happened.

-- 
FTTC broadband for 0.8mile line: currently at 10.5Mbps down 400kbps up
according to speedtest.net.


From appana.durga.rao at xilinx.com  Wed Aug  5 04:35:25 2015
From: appana.durga.rao at xilinx.com (Kedareswara rao Appana)
Date: Wed, 5 Aug 2015 17:05:25 +0530
Subject: [PATCH v8] dmaengine: Add Xilinx AXI Direct Memory Access Engine
 driver support
Message-ID: <1438774525-26824-1-git-send-email-appanad@xilinx.com>

This is the driver for the AXI Direct Memory Access (AXI DMA)
core, which is a soft Xilinx IP core that provides high-
bandwidth direct memory access between memory and AXI4-Stream
type target peripherals.

Signed-off-by: Srikanth Thokala <sthokal at xilinx.com>
Signed-off-by: Kedareswara rao Appana <appanad at xilinx.com>
---
The deivce tree doc got applied in the slave-dmaengine.git.

Changes in v8:
- Updated the SG handling as suggested by Nicolae Rosia.
- Removed the unnecessary xilinx_dma_channel_set_config API the properties
  in this API is not being used by the driver.
Changes in v7:
- Updated license in the driver as suggested by Paul.
- Corrected return value in is_idle funtion.
Changes in v6:
- Fixed Odd indention in the Kconfig.
- used GFP_NOWAIT instead of GFP_KERNEL during the desc allocation
- Calculated residue in the tx_status instead of complete_descriptor.
- Update copy right to 2015.
- Modified spin_lock handling moved the spin_lock to the appropriate functions
(instead of xilinx_dma_start_transfer doing it xilinx_dma_issue_pending api).
- device_control and declare slave caps updated as per newer APi's.
Changes in v5:
- Modified the xilinx_dma.h header file location to the 
  include/linux/dma/xilinx_dma.h
Changes in v4:
- Add direction field to DMA descriptor structure and removed from
  channel structure to avoid duplication.
- Check for DMA idle condition before changing the configuration.
- Residue is being calculated in complete_descriptor() and is reported
  to slave driver.
Changes in v3:
- Rebased on 3.16-rc7
Changes in v2:
- Simplified the logic to set SOP and APP words in prep_slave_sg().
- Corrected function description comments to match the return type.
- Fixed some minor comments as suggested by Andy.

 drivers/dma/Kconfig             |   13 +
 drivers/dma/xilinx/Makefile     |    1 +
 drivers/dma/xilinx/xilinx_dma.c | 1179 +++++++++++++++++++++++++++++++++++++++
 3 files changed, 1193 insertions(+)
 create mode 100644 drivers/dma/xilinx/xilinx_dma.c

diff --git a/drivers/dma/Kconfig b/drivers/dma/Kconfig
index 88d474b..5e95f07 100644
--- a/drivers/dma/Kconfig
+++ b/drivers/dma/Kconfig
@@ -507,4 +507,17 @@ config QCOM_BAM_DMA
 	  Enable support for the QCOM BAM DMA controller.  This controller
 	  provides DMA capabilities for a variety of on-chip devices.
 
+config XILINX_DMA
+        tristate "Xilinx AXI DMA Engine"
+        depends on (ARCH_ZYNQ || MICROBLAZE)
+        select DMA_ENGINE
+        help
+          Enable support for Xilinx AXI DMA Soft IP.
+
+          This engine provides high-bandwidth direct memory access
+          between memory and AXI4-Stream type target peripherals.
+          It has two stream interfaces/channels, Memory Mapped to
+          Stream (MM2S) and Stream to Memory Mapped (S2MM) for the
+          data transfers.
+
 endif
diff --git a/drivers/dma/xilinx/Makefile b/drivers/dma/xilinx/Makefile
index 3c4e9f2..6224a49 100644
--- a/drivers/dma/xilinx/Makefile
+++ b/drivers/dma/xilinx/Makefile
@@ -1 +1,2 @@
 obj-$(CONFIG_XILINX_VDMA) += xilinx_vdma.o
+obj-$(CONFIG_XILINX_DMA) += xilinx_dma.o
diff --git a/drivers/dma/xilinx/xilinx_dma.c b/drivers/dma/xilinx/xilinx_dma.c
new file mode 100644
index 0000000..a9be197
--- /dev/null
+++ b/drivers/dma/xilinx/xilinx_dma.c
@@ -0,0 +1,1179 @@
+/*
+ * DMA driver for Xilinx DMA Engine
+ *
+ * Copyright (C) 2010 - 2015 Xilinx, Inc. All rights reserved.
+ *
+ * Based on the Freescale DMA driver.
+ *
+ * Description:
+ *  The AXI DMA, is a soft IP, which provides high-bandwidth Direct Memory
+ *  Access between memory and AXI4-Stream-type target peripherals. It can be
+ *  configured to have one channel or two channels and if configured as two
+ *  channels, one is to transmit data from memory to a device and another is
+ *  to receive from a device.
+ *
+ * This 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.
+ */
+
+#include <linux/bitops.h>
+#include <linux/dma/xilinx_dma.h>
+#include <linux/init.h>
+#include <linux/interrupt.h>
+#include <linux/io.h>
+#include <linux/module.h>
+#include <linux/of_address.h>
+#include <linux/of_dma.h>
+#include <linux/of_irq.h>
+#include <linux/of_platform.h>
+#include <linux/slab.h>
+
+#include "../dmaengine.h"
+
+/* Register Offsets */
+#define XILINX_DMA_REG_CONTROL		0x00
+#define XILINX_DMA_REG_STATUS		0x04
+#define XILINX_DMA_REG_CURDESC		0x08
+#define XILINX_DMA_REG_TAILDESC		0x10
+#define XILINX_DMA_REG_SRCADDR		0x18
+#define XILINX_DMA_REG_DSTADDR		0x20
+#define XILINX_DMA_REG_BTT		0x28
+
+/* Channel/Descriptor Offsets */
+#define XILINX_DMA_MM2S_CTRL_OFFSET	0x00
+#define XILINX_DMA_S2MM_CTRL_OFFSET	0x30
+
+/* General register bits definitions */
+#define XILINX_DMA_CR_RUNSTOP_MASK	BIT(0)
+#define XILINX_DMA_CR_RESET_MASK	BIT(2)
+
+#define XILINX_DMA_CR_DELAY_SHIFT	24
+#define XILINX_DMA_CR_COALESCE_SHIFT	16
+
+#define XILINX_DMA_CR_DELAY_MAX		GENMASK(7, 0)
+#define XILINX_DMA_CR_COALESCE_MAX	GENMASK(7, 0)
+
+#define XILINX_DMA_SR_HALTED_MASK	BIT(0)
+#define XILINX_DMA_SR_IDLE_MASK		BIT(1)
+
+#define XILINX_DMA_XR_IRQ_IOC_MASK	BIT(12)
+#define XILINX_DMA_XR_IRQ_DELAY_MASK	BIT(13)
+#define XILINX_DMA_XR_IRQ_ERROR_MASK	BIT(14)
+#define XILINX_DMA_XR_IRQ_ALL_MASK	GENMASK(14, 12)
+
+/* BD definitions */
+#define XILINX_DMA_BD_STS_ALL_MASK	GENMASK(31, 28)
+#define XILINX_DMA_BD_SOP		BIT(27)
+#define XILINX_DMA_BD_EOP		BIT(26)
+
+/* Hw specific definitions */
+#define XILINX_DMA_MAX_CHANS_PER_DEVICE	0x2
+#define XILINX_DMA_MAX_TRANS_LEN	GENMASK(22, 0)
+
+/* Delay loop counter to prevent hardware failure */
+#define XILINX_DMA_LOOP_COUNT		1000000
+
+/* Maximum number of Descriptors */
+#define XILINX_DMA_NUM_DESCS		255
+#define XILINX_DMA_COALESCE_MAX		255
+#define XILINX_DMA_NUM_APP_WORDS	5
+
+/**
+ * struct xilinx_dma_desc_hw - Hardware Descriptor
+ * @next_desc: Next Descriptor Pointer @0x00
+ * @pad1: Reserved @0x04
+ * @buf_addr: Buffer address @0x08
+ * @pad2: Reserved @0x0C
+ * @pad3: Reserved @0x10
+ * @pad4: Reserved @0x14
+ * @control: Control field @0x18
+ * @status: Status field @0x1C
+ * @app: APP Fields @0x20 - 0x30
+ */
+struct xilinx_dma_desc_hw {
+	u32 next_desc;
+	u32 pad1;
+	u32 buf_addr;
+	u32 pad2;
+	u32 pad3;
+	u32 pad4;
+	u32 control;
+	u32 status;
+	u32 app[XILINX_DMA_NUM_APP_WORDS];
+} __aligned(64);
+
+/**
+ * struct xilinx_dma_tx_segment - Descriptor segment
+ * @hw: Hardware descriptor
+ * @node: Node in the descriptor segments list
+ * @phys: Physical address of segment
+ */
+struct xilinx_dma_tx_segment {
+	struct xilinx_dma_desc_hw hw;
+	struct list_head node;
+	dma_addr_t phys;
+} __aligned(64);
+
+/**
+ * struct xilinx_dma_tx_descriptor - Per Transaction structure
+ * @async_tx: Async transaction descriptor
+ * @segments: TX segments list
+ * @node: Node in the channel descriptors list
+ * @direction: Transfer direction
+ */
+struct xilinx_dma_tx_descriptor {
+	struct dma_async_tx_descriptor async_tx;
+	struct list_head segments;
+	struct list_head node;
+	enum dma_transfer_direction direction;
+};
+
+/**
+ * struct xilinx_dma_chan - Driver specific DMA channel structure
+ * @xdev: Driver specific device structure
+ * @ctrl_offset: Control registers offset
+ * @ctrl_reg: Control register value
+ * @lock: Descriptor operation lock
+ * @pending_list: Descriptors waiting
+ * @active_list: Descriptors ready to submit
+ * @done_list: Complete descriptors
+ * @free_seg_list: Free descriptors
+ * @common: DMA common channel
+ * @seg_v: Statically allocated segments base
+ * @seg_p: Physical allocated segments base
+ * @dev: The dma device
+ * @irq: Channel IRQ
+ * @id: Channel ID
+ * @has_sg: Support scatter transfers
+ * @idle: Check for channel idle
+ * @err: Channel has errors
+ * @tasklet: Cleanup work after irq
+ * @residue: Residue
+ * @desc_pendingcount: Descriptor pending count
+ */
+struct xilinx_dma_chan {
+	struct xilinx_dma_device *xdev;
+	u32 ctrl_offset;
+	u32 ctrl_reg;
+	spinlock_t lock;
+	struct list_head pending_list;
+	struct list_head done_list;
+	struct list_head active_list;
+	struct list_head free_seg_list;
+	struct dma_chan common;
+	struct xilinx_dma_tx_segment *seg_v;
+	dma_addr_t seg_p;
+	struct device *dev;
+	int irq;
+	int id;
+	bool has_sg;
+	bool idle;
+	int err;
+	struct tasklet_struct tasklet;
+	u32 residue;
+	u32 desc_pendingcount;
+};
+
+/**
+ * struct xilinx_dma_device - DMA device structure
+ * @regs: I/O mapped base address
+ * @dev: Device Structure
+ * @common: DMA device structure
+ * @chan: Driver specific DMA channel
+ * @has_sg: Specifies whether Scatter-Gather is present or not
+ */
+struct xilinx_dma_device {
+	void __iomem *regs;
+	struct device *dev;
+	struct dma_device common;
+	struct xilinx_dma_chan *chan[XILINX_DMA_MAX_CHANS_PER_DEVICE];
+	bool has_sg;
+};
+
+/* Macros */
+#define to_xilinx_chan(chan) \
+	container_of(chan, struct xilinx_dma_chan, common)
+#define to_dma_tx_descriptor(tx) \
+	container_of(tx, struct xilinx_dma_tx_descriptor, async_tx)
+
+/* IO accessors */
+static inline void dma_write(struct xilinx_dma_chan *chan, u32 reg, u32 value)
+{
+	iowrite32(value, chan->xdev->regs + reg);
+}
+
+static inline u32 dma_read(struct xilinx_dma_chan *chan, u32 reg)
+{
+	return ioread32(chan->xdev->regs + reg);
+}
+
+static inline u32 dma_ctrl_read(struct xilinx_dma_chan *chan, u32 reg)
+{
+	return dma_read(chan, chan->ctrl_offset + reg);
+}
+
+static inline void dma_ctrl_write(struct xilinx_dma_chan *chan, u32 reg,
+				  u32 value)
+{
+	dma_write(chan, chan->ctrl_offset + reg, value);
+}
+
+/* -----------------------------------------------------------------------------
+ * Descriptors and segments alloc and free
+ */
+
+/**
+ * xilinx_dma_alloc_tx_segment - Allocate transaction segment
+ * @chan: Driver specific dma channel
+ *
+ * Return: The allocated segment on success and NULL on failure.
+ */
+static struct xilinx_dma_tx_segment *
+xilinx_dma_alloc_tx_segment(struct xilinx_dma_chan *chan)
+{
+	struct xilinx_dma_tx_segment *segment = NULL;
+	unsigned long flags;
+
+	spin_lock_irqsave(&chan->lock, flags);
+	if (!list_empty(&chan->free_seg_list)) {
+		segment = list_first_entry(&chan->free_seg_list,
+					   struct xilinx_dma_tx_segment,
+					   node);
+		list_del(&segment->node);
+	}
+	spin_unlock_irqrestore(&chan->lock, flags);
+
+	return segment;
+}
+
+/**
+ * xilinx_dma_clean_hw_desc - Clean hardware descriptor
+ * @hw: HW descriptor to clean
+ */
+static void xilinx_dma_clean_hw_desc(struct xilinx_dma_desc_hw *hw)
+{
+	u32 next_desc = hw->next_desc;
+
+	memset(hw, 0, sizeof(struct xilinx_dma_desc_hw));
+
+	hw->next_desc = next_desc;
+}
+
+/**
+ * xilinx_dma_free_tx_segment - Free transaction segment
+ * @chan: Driver specific dma channel
+ * @segment: dma transaction segment
+ */
+static void xilinx_dma_free_tx_segment(struct xilinx_dma_chan *chan,
+				       struct xilinx_dma_tx_segment *segment)
+{
+	xilinx_dma_clean_hw_desc(&segment->hw);
+
+	list_add_tail(&segment->node, &chan->free_seg_list);
+}
+
+/**
+ * xilinx_dma_tx_descriptor - Allocate transaction descriptor
+ * @chan: Driver specific dma channel
+ *
+ * Return: The allocated descriptor on success and NULL on failure.
+ */
+static struct xilinx_dma_tx_descriptor *
+xilinx_dma_alloc_tx_descriptor(struct xilinx_dma_chan *chan)
+{
+	struct xilinx_dma_tx_descriptor *desc;
+
+	desc = kzalloc(sizeof(*desc), GFP_NOWAIT);
+	if (!desc)
+		return NULL;
+
+	INIT_LIST_HEAD(&desc->segments);
+
+	return desc;
+}
+
+/**
+ * xilinx_dma_free_tx_descriptor - Free transaction descriptor
+ * @chan: Driver specific dma channel
+ * @desc: dma transaction descriptor
+ */
+static void
+xilinx_dma_free_tx_descriptor(struct xilinx_dma_chan *chan,
+			      struct xilinx_dma_tx_descriptor *desc)
+{
+	struct xilinx_dma_tx_segment *segment, *next;
+
+	if (!desc)
+		return;
+
+	list_for_each_entry_safe(segment, next, &desc->segments, node) {
+		list_del(&segment->node);
+		xilinx_dma_free_tx_segment(chan, segment);
+	}
+
+	kfree(desc);
+}
+
+/**
+ * xilinx_dma_alloc_chan_resources - Allocate channel resources
+ * @dchan: DMA channel
+ *
+ * Return: '0' on success and failure value on error
+ */
+static int xilinx_dma_alloc_chan_resources(struct dma_chan *dchan)
+{
+	struct xilinx_dma_chan *chan = to_xilinx_chan(dchan);
+	int i;
+
+	/* Allocate the buffer descriptors. */
+	chan->seg_v = dma_zalloc_coherent(chan->dev,
+					  sizeof(*chan->seg_v) *
+					  XILINX_DMA_NUM_DESCS,
+					  &chan->seg_p, GFP_KERNEL);
+	if (!chan->seg_v) {
+		dev_err(chan->dev,
+			"unable to allocate channel %d descriptors\n",
+			chan->id);
+		return -ENOMEM;
+	}
+
+	for (i = 0; i < XILINX_DMA_NUM_DESCS; i++) {
+		chan->seg_v[i].hw.next_desc =
+				chan->seg_p + sizeof(*chan->seg_v) *
+				((i + 1) % XILINX_DMA_NUM_DESCS);
+		chan->seg_v[i].phys =
+				chan->seg_p + sizeof(*chan->seg_v) * i;
+		list_add_tail(&chan->seg_v[i].node, &chan->free_seg_list);
+	}
+
+	dma_cookie_init(dchan);
+
+	/* Enable interrupts */
+	chan->ctrl_reg |= XILINX_DMA_XR_IRQ_ALL_MASK;
+	dma_ctrl_write(chan, XILINX_DMA_REG_CONTROL, chan->ctrl_reg);
+
+	return 0;
+}
+
+/**
+ * xilinx_dma_free_desc_list - Free descriptors list
+ * @chan: Driver specific dma channel
+ * @list: List to parse and delete the descriptor
+ */
+static void xilinx_dma_free_desc_list(struct xilinx_dma_chan *chan,
+				      struct list_head *list)
+{
+	struct xilinx_dma_tx_descriptor *desc, *next;
+
+	list_for_each_entry_safe(desc, next, list, node) {
+		list_del(&desc->node);
+		xilinx_dma_free_tx_descriptor(chan, desc);
+	}
+}
+
+/**
+ * xilinx_dma_free_descriptors - Free channel descriptors
+ * @chan: Driver specific dma channel
+ */
+static void xilinx_dma_free_descriptors(struct xilinx_dma_chan *chan)
+{
+	unsigned long flags;
+
+	spin_lock_irqsave(&chan->lock, flags);
+
+	xilinx_dma_free_desc_list(chan, &chan->pending_list);
+	xilinx_dma_free_desc_list(chan, &chan->done_list);
+	xilinx_dma_free_desc_list(chan, &chan->active_list);
+
+	spin_unlock_irqrestore(&chan->lock, flags);
+}
+
+/**
+ * xilinx_dma_free_chan_resources - Free channel resources
+ * @dchan: DMA channel
+ */
+static void xilinx_dma_free_chan_resources(struct dma_chan *dchan)
+{
+	struct xilinx_dma_chan *chan = to_xilinx_chan(dchan);
+
+	xilinx_dma_free_descriptors(chan);
+
+	dma_free_coherent(chan->dev,
+			  sizeof(*chan->seg_v) * XILINX_DMA_NUM_DESCS,
+			  chan->seg_v, chan->seg_p);
+}
+
+/**
+ * xilinx_dma_chan_desc_cleanup - Clean channel descriptors
+ * @chan: Driver specific dma channel
+ */
+static void xilinx_dma_chan_desc_cleanup(struct xilinx_dma_chan *chan)
+{
+	struct xilinx_dma_tx_descriptor *desc;
+	unsigned long flags;
+
+	spin_lock_irqsave(&chan->lock, flags);
+
+	while (!list_empty(&chan->done_list)) {
+		dma_async_tx_callback callback;
+		void *callback_param;
+
+		desc = list_first_entry(&chan->done_list,
+			struct xilinx_dma_tx_descriptor, node);
+
+		/* Remove from the list of running transactions */
+		list_del(&desc->node);
+
+		/* Run the link descriptor callback function */
+		callback = desc->async_tx.callback;
+		callback_param = desc->async_tx.callback_param;
+		if (callback) {
+			spin_unlock_irqrestore(&chan->lock, flags);
+			callback(callback_param);
+			spin_lock_irqsave(&chan->lock, flags);
+		}
+
+		/* Run any dependencies, then free the descriptor */
+		dma_run_dependencies(&desc->async_tx);
+		xilinx_dma_free_tx_descriptor(chan, desc);
+	}
+
+	spin_unlock_irqrestore(&chan->lock, flags);
+}
+
+/**
+ * xilinx_dma_tx_status - Get dma transaction status
+ * @dchan: DMA channel
+ * @cookie: Transaction identifier
+ * @txstate: Transaction state
+ *
+ * Return: DMA transaction status
+ */
+static enum dma_status xilinx_dma_tx_status(struct dma_chan *dchan,
+					    dma_cookie_t cookie,
+					    struct dma_tx_state *txstate)
+{
+	struct xilinx_dma_chan *chan = to_xilinx_chan(dchan);
+	struct xilinx_dma_tx_descriptor *desc;
+	struct xilinx_dma_tx_segment *segment;
+	struct xilinx_dma_desc_hw *hw;
+	enum dma_status ret;
+	unsigned long flags;
+	u32 residue;
+
+	ret = dma_cookie_status(dchan, cookie, txstate);
+	if (ret == DMA_COMPLETE || !txstate)
+		return ret;
+
+	desc = list_last_entry(&chan->active_list,
+			       struct xilinx_dma_tx_descriptor, node);
+
+	spin_lock_irqsave(&chan->lock, flags);
+	if (chan->has_sg) {
+		while (!list_empty(&desc->segments)) {
+			segment = list_first_entry(&desc->segments,
+					struct xilinx_dma_tx_segment, node);
+			hw = &segment->hw;
+			residue += (hw->control - hw->status) &
+				   XILINX_DMA_MAX_TRANS_LEN;
+		}
+	}
+
+	chan->residue = residue;
+	dma_set_residue(txstate, chan->residue);
+	spin_unlock_irqrestore(&chan->lock, flags);
+
+	return ret;
+}
+
+/**
+ * xilinx_dma_halt - Halt DMA channel
+ * @chan: Driver specific DMA channel
+ */
+static void xilinx_dma_halt(struct xilinx_dma_chan *chan)
+{
+	int loop = XILINX_DMA_LOOP_COUNT;
+
+	chan->ctrl_reg &= ~XILINX_DMA_CR_RUNSTOP_MASK;
+	dma_ctrl_write(chan, XILINX_DMA_REG_CONTROL, chan->ctrl_reg);
+
+	/* Wait for the hardware to halt */
+	do {
+		if (dma_ctrl_read(chan, XILINX_DMA_REG_STATUS) &
+			XILINX_DMA_SR_HALTED_MASK)
+			break;
+	} while (loop--);
+
+	if (!loop) {
+		dev_err(chan->dev, "Cannot stop channel %p: %x\n",
+			chan, dma_ctrl_read(chan, XILINX_DMA_REG_STATUS));
+		chan->err = true;
+	}
+}
+
+/**
+ * xilinx_dma_start - Start DMA channel
+ * @chan: Driver specific DMA channel
+ */
+static void xilinx_dma_start(struct xilinx_dma_chan *chan)
+{
+	int loop = XILINX_DMA_LOOP_COUNT;
+
+	chan->ctrl_reg |= XILINX_DMA_CR_RUNSTOP_MASK;
+	dma_ctrl_write(chan, XILINX_DMA_REG_CONTROL, chan->ctrl_reg);
+
+	/* Wait for the hardware to start */
+	do {
+		if (!dma_ctrl_read(chan, XILINX_DMA_REG_STATUS) &
+			XILINX_DMA_SR_HALTED_MASK)
+			break;
+	} while (loop--);
+
+	if (!loop) {
+		dev_err(chan->dev, "Cannot start channel %p: %x\n",
+			 chan, dma_ctrl_read(chan, XILINX_DMA_REG_STATUS));
+		chan->err = true;
+	}
+}
+
+/**
+ * xilinx_dma_start_transfer - Starts DMA transfer
+ * @chan: Driver specific channel struct pointer
+ */
+static void xilinx_dma_start_transfer(struct xilinx_dma_chan *chan)
+{
+	struct xilinx_dma_tx_descriptor *head_desc, *tail_desc;
+	struct xilinx_dma_tx_segment *tail_segment;
+
+	if (chan->err)
+		return;
+
+	if (list_empty(&chan->pending_list))
+		return;
+
+	if (!chan->idle)
+		return;
+
+	head_desc = list_first_entry(&chan->pending_list,
+				     struct xilinx_dma_tx_descriptor, node);
+	tail_desc = list_last_entry(&chan->pending_list,
+				    struct xilinx_dma_tx_descriptor, node);
+	tail_segment = list_last_entry(&tail_desc->segments,
+				       struct xilinx_dma_tx_segment, node);
+
+	if (chan->desc_pendingcount <= XILINX_DMA_COALESCE_MAX) {
+		chan->ctrl_reg &= ~XILINX_DMA_CR_COALESCE_MAX;
+		chan->ctrl_reg |= chan->desc_pendingcount <<
+				  XILINX_DMA_CR_COALESCE_SHIFT;
+		dma_ctrl_write(chan, XILINX_DMA_REG_CONTROL, chan->ctrl_reg);
+	}
+
+	if (chan->has_sg)
+		dma_ctrl_write(chan, XILINX_DMA_REG_CURDESC,
+			       head_desc->async_tx.phys);
+
+	xilinx_dma_start(chan);
+
+	if (chan->err)
+		return;
+
+	/* Start the transfer */
+	if (chan->has_sg) {
+		dma_ctrl_write(chan, XILINX_DMA_REG_TAILDESC,
+			       tail_segment->phys);
+	} else {
+		struct xilinx_dma_tx_segment *segment;
+		struct xilinx_dma_desc_hw *hw;
+
+		segment = list_first_entry(&head_desc->segments,
+					   struct xilinx_dma_tx_segment, node);
+		hw = &segment->hw;
+
+		if (head_desc->direction == DMA_MEM_TO_DEV)
+			dma_ctrl_write(chan, XILINX_DMA_REG_SRCADDR,
+				       hw->buf_addr);
+		else
+			dma_ctrl_write(chan, XILINX_DMA_REG_DSTADDR,
+				       hw->buf_addr);
+
+		/* Start the transfer */
+		dma_ctrl_write(chan, XILINX_DMA_REG_BTT,
+			       hw->control & XILINX_DMA_MAX_TRANS_LEN);
+	}
+
+	list_splice_tail_init(&chan->pending_list, &chan->active_list);
+	chan->desc_pendingcount = 0;
+	chan->idle = false;
+}
+
+/**
+ * xilinx_dma_issue_pending - Issue pending transactions
+ * @dchan: DMA channel
+ */
+static void xilinx_dma_issue_pending(struct dma_chan *dchan)
+{
+	struct xilinx_dma_chan *chan = to_xilinx_chan(dchan);
+	unsigned long flags;
+
+	spin_lock_irqsave(&chan->lock, flags);
+	xilinx_dma_start_transfer(chan);
+	spin_unlock_irqrestore(&chan->lock, flags);
+}
+
+/**
+ * xilinx_dma_complete_descriptor - Mark the active descriptor as complete
+ * @chan : xilinx DMA channel
+ */
+static void xilinx_dma_complete_descriptor(struct xilinx_dma_chan *chan)
+{
+	struct xilinx_dma_tx_descriptor *desc, *next;
+
+	if (list_empty(&chan->active_list))
+		return;
+
+	list_for_each_entry_safe(desc, next, &chan->active_list, node) {
+		list_del(&desc->node);
+		dma_cookie_complete(&desc->async_tx);
+		list_add_tail(&desc->node, &chan->done_list);
+	}
+}
+
+/**
+ * xilinx_dma_reset - Reset DMA channel
+ * @chan: Driver specific DMA channel
+ *
+ * Return: '0' on success and failure value on error
+ */
+static int xilinx_dma_chan_reset(struct xilinx_dma_chan *chan)
+{
+	int loop = XILINX_DMA_LOOP_COUNT;
+	u32 tmp;
+
+	chan->ctrl_reg = dma_ctrl_read(chan, XILINX_DMA_REG_CONTROL);
+	dma_ctrl_write(chan, XILINX_DMA_REG_CONTROL, chan->ctrl_reg |
+		       XILINX_DMA_CR_RESET_MASK);
+
+	tmp = dma_ctrl_read(chan, XILINX_DMA_REG_CONTROL) &
+	      XILINX_DMA_CR_RESET_MASK;
+
+	/* Wait for the hardware to finish reset */
+	do {
+		tmp = dma_ctrl_read(chan, XILINX_DMA_REG_CONTROL) &
+		      XILINX_DMA_CR_RESET_MASK;
+	} while (loop-- && tmp);
+
+	if (!loop) {
+		dev_err(chan->dev, "reset timeout, cr %x, sr %x\n",
+			dma_ctrl_read(chan, XILINX_DMA_REG_CONTROL),
+			dma_ctrl_read(chan, XILINX_DMA_REG_STATUS));
+		return -EBUSY;
+	}
+
+	chan->err = false;
+
+	return 0;
+}
+
+/**
+ * xilinx_dma_irq_handler - DMA Interrupt handler
+ * @irq: IRQ number
+ * @data: Pointer to the Xilinx DMA channel structure
+ *
+ * Return: IRQ_HANDLED/IRQ_NONE
+ */
+static irqreturn_t xilinx_dma_irq_handler(int irq, void *data)
+{
+	struct xilinx_dma_chan *chan = data;
+	u32 status;
+
+	/* Read the status and ack the interrupts. */
+	status = dma_ctrl_read(chan, XILINX_DMA_REG_STATUS);
+	if (!(status & XILINX_DMA_XR_IRQ_ALL_MASK))
+		return IRQ_NONE;
+
+	dma_ctrl_write(chan, XILINX_DMA_REG_STATUS,
+		       status & XILINX_DMA_XR_IRQ_ALL_MASK);
+
+	if (status & XILINX_DMA_XR_IRQ_ERROR_MASK) {
+		dev_err(chan->dev,
+			"Channel %p has errors %x, cdr %x tdr %x\n",
+			chan, dma_ctrl_read(chan, XILINX_DMA_REG_STATUS),
+			dma_ctrl_read(chan, XILINX_DMA_REG_CURDESC),
+			dma_ctrl_read(chan, XILINX_DMA_REG_TAILDESC));
+		chan->err = true;
+	}
+
+	/*
+	 * Device takes too long to do the transfer when user requires
+	 * responsiveness
+	 */
+	if (status & XILINX_DMA_XR_IRQ_DELAY_MASK)
+		dev_dbg(chan->dev, "Inter-packet latency too long\n");
+
+	if (status & XILINX_DMA_XR_IRQ_IOC_MASK) {
+		spin_lock(&chan->lock);
+		xilinx_dma_complete_descriptor(chan);
+		chan->idle = true;
+		xilinx_dma_start_transfer(chan);
+		spin_unlock(&chan->lock);
+	}
+
+	tasklet_schedule(&chan->tasklet);
+	return IRQ_HANDLED;
+}
+
+/**
+ * xilinx_dma_do_tasklet - Schedule completion tasklet
+ * @data: Pointer to the Xilinx dma channel structure
+ */
+static void xilinx_dma_do_tasklet(unsigned long data)
+{
+	struct xilinx_dma_chan *chan = (struct xilinx_dma_chan *)data;
+
+	xilinx_dma_chan_desc_cleanup(chan);
+}
+
+/**
+ * append_desc_queue - Queuing descriptor
+ * @chan: Driver specific dma channel
+ * @desc: dma transaction descriptor
+ */
+static void append_desc_queue(struct xilinx_dma_chan *chan,
+			      struct xilinx_dma_tx_descriptor *desc)
+{
+	struct xilinx_dma_tx_segment *tail_segment;
+	struct xilinx_dma_tx_descriptor *tail_desc;
+
+	if (list_empty(&chan->pending_list))
+		goto append;
+
+	/*
+	 * Add the hardware descriptor to the chain of hardware descriptors
+	 * that already exists in memory.
+	 */
+	tail_desc = list_last_entry(&chan->pending_list,
+				    struct xilinx_dma_tx_descriptor, node);
+	tail_segment = list_last_entry(&tail_desc->segments,
+				       struct xilinx_dma_tx_segment, node);
+	tail_segment->hw.next_desc = (u32)desc->async_tx.phys;
+
+	/*
+	 * Add the software descriptor and all children to the list
+	 * of pending transactions
+	 */
+append:
+	list_add_tail(&desc->node, &chan->pending_list);
+	chan->desc_pendingcount++;
+
+	if (unlikely(chan->desc_pendingcount > XILINX_DMA_COALESCE_MAX)) {
+		dev_dbg(chan->dev, "desc pendingcount is too high\n");
+		chan->desc_pendingcount = XILINX_DMA_COALESCE_MAX;
+		BUG();
+	}
+}
+
+/**
+ * xilinx_dma_tx_submit - Submit DMA transaction
+ * @tx: Async transaction descriptor
+ *
+ * Return: cookie value on success and failure value on error
+ */
+static dma_cookie_t xilinx_dma_tx_submit(struct dma_async_tx_descriptor *tx)
+{
+	struct xilinx_dma_tx_descriptor *desc = to_dma_tx_descriptor(tx);
+	struct xilinx_dma_chan *chan = to_xilinx_chan(tx->chan);
+	dma_cookie_t cookie;
+	unsigned long flags;
+	int err;
+
+	if (chan->err) {
+		/*
+		 * If reset fails, need to hard reset the system.
+		 * Channel is no longer functional
+		 */
+		err = xilinx_dma_chan_reset(chan);
+		if (err < 0)
+			return err;
+	}
+
+	spin_lock_irqsave(&chan->lock, flags);
+
+	cookie = dma_cookie_assign(tx);
+
+	/* Put this transaction onto the tail of the pending queue */
+	append_desc_queue(chan, desc);
+
+	spin_unlock_irqrestore(&chan->lock, flags);
+
+	return cookie;
+}
+
+/**
+ * xilinx_dma_prep_slave_sg - prepare descriptors for a DMA_SLAVE transaction
+ * @dchan: DMA channel
+ * @sgl: scatterlist to transfer to/from
+ * @sg_len: number of entries in @scatterlist
+ * @direction: DMA direction
+ * @flags: transfer ack flags
+ * @context: APP words of the descriptor
+ *
+ * Return: Async transaction descriptor on success and NULL on failure
+ */
+static struct dma_async_tx_descriptor *xilinx_dma_prep_slave_sg(
+	struct dma_chan *dchan, struct scatterlist *sgl, unsigned int sg_len,
+	enum dma_transfer_direction direction, unsigned long flags,
+	void *context)
+{
+	struct xilinx_dma_chan *chan = to_xilinx_chan(dchan);
+	struct xilinx_dma_tx_descriptor *desc;
+	struct xilinx_dma_tx_segment *segment;
+	u32 *app_w = (u32 *)context;
+	struct scatterlist *sg;
+	size_t copy, sg_used;
+	int i;
+
+	if (!is_slave_direction(direction))
+		return NULL;
+
+	/* Allocate a transaction descriptor. */
+	desc = xilinx_dma_alloc_tx_descriptor(chan);
+	if (!desc)
+		return NULL;
+
+	desc->direction = direction;
+	dma_async_tx_descriptor_init(&desc->async_tx, &chan->common);
+	desc->async_tx.tx_submit = xilinx_dma_tx_submit;
+
+	/* Build transactions using information in the scatter gather list */
+	for_each_sg(sgl, sg, sg_len, i) {
+		sg_used = 0;
+
+		/* Loop until the entire scatterlist entry is used */
+		while (sg_used < sg_dma_len(sg)) {
+			struct xilinx_dma_desc_hw *hw;
+
+			/* Get a free segment */
+			segment = xilinx_dma_alloc_tx_segment(chan);
+			if (!segment)
+				goto error;
+
+			/*
+			 * Calculate the maximum number of bytes to transfer,
+			 * making sure it is less than the hw limit
+			 */
+			copy = min_t(size_t, sg_dma_len(sg) - sg_used,
+				     XILINX_DMA_MAX_TRANS_LEN);
+			hw = &segment->hw;
+
+			/* Fill in the descriptor */
+			hw->buf_addr = sg_dma_address(sg) + sg_used;
+
+			hw->control = copy;
+
+			if (direction == DMA_MEM_TO_DEV) {
+				if (app_w)
+					memcpy(hw->app, app_w, sizeof(u32) *
+					       XILINX_DMA_NUM_APP_WORDS);
+			}
+
+			sg_used += copy;
+
+			/*
+			 * Insert the segment into the descriptor segments
+			 * list.
+			 */
+			list_add_tail(&segment->node, &desc->segments);
+		}
+	}
+
+	segment = list_first_entry(&desc->segments,
+				   struct xilinx_dma_tx_segment, node);
+	desc->async_tx.phys = segment->phys;
+
+	/* For the last DMA_MEM_TO_DEV transfer, set EOP */
+	if (direction == DMA_MEM_TO_DEV) {
+		segment->hw.control |= XILINX_DMA_BD_SOP;
+		segment = list_last_entry(&desc->segments,
+					  struct xilinx_dma_tx_segment,
+					  node);
+		segment->hw.control |= XILINX_DMA_BD_EOP;
+	}
+
+	return &desc->async_tx;
+
+error:
+	xilinx_dma_free_tx_descriptor(chan, desc);
+	return NULL;
+}
+
+/**
+ * xilinx_dma_terminate_all - Halt the channel and free descriptors
+ * @dchan: DMA Channel pointer
+ *
+ * Return: '0' always
+ */
+static int xilinx_dma_terminate_all(struct dma_chan *dchan)
+{
+	struct xilinx_dma_chan *chan = to_xilinx_chan(dchan);
+
+	/* Halt the DMA engine */
+	xilinx_dma_halt(chan);
+
+	/* Remove and free all of the descriptors in the lists */
+	xilinx_dma_free_descriptors(chan);
+
+	return 0;
+}
+
+/**
+ * xilinx_dma_chan_remove - Per Channel remove function
+ * @chan: Driver specific DMA channel
+ */
+static void xilinx_dma_chan_remove(struct xilinx_dma_chan *chan)
+{
+	/* Disable interrupts */
+	chan->ctrl_reg &= ~XILINX_DMA_XR_IRQ_ALL_MASK;
+	dma_ctrl_write(chan, XILINX_DMA_REG_CONTROL, chan->ctrl_reg);
+
+	if (chan->irq > 0)
+		free_irq(chan->irq, chan);
+
+	tasklet_kill(&chan->tasklet);
+
+	list_del(&chan->common.device_node);
+}
+
+/**
+ * xilinx_dma_chan_probe - Per Channel Probing
+ * It get channel features from the device tree entry and
+ * initialize special channel handling routines
+ *
+ * @xdev: Driver specific device structure
+ * @node: Device node
+ *
+ * Return: '0' on success and failure value on error
+ */
+static int xilinx_dma_chan_probe(struct xilinx_dma_device *xdev,
+				 struct device_node *node)
+{
+	struct xilinx_dma_chan *chan;
+	int err;
+	bool has_dre;
+	u32 value, width = 0;
+
+	/* alloc channel */
+	chan = devm_kzalloc(xdev->dev, sizeof(*chan), GFP_KERNEL);
+	if (!chan)
+		return -ENOMEM;
+
+	chan->dev = xdev->dev;
+	chan->xdev = xdev;
+	chan->has_sg = xdev->has_sg;
+	chan->desc_pendingcount = 0x0;
+
+	has_dre = of_property_read_bool(node, "xlnx,include-dre");
+
+	err = of_property_read_u32(node, "xlnx,datawidth", &value);
+	if (err) {
+		dev_err(xdev->dev, "unable to read datawidth property");
+		return err;
+	}
+
+	width = value >> 3; /* Convert bits to bytes */
+
+	/* If data width is greater than 8 bytes, DRE is not in hw */
+	if (width > 8)
+		has_dre = false;
+
+	if (!has_dre)
+		xdev->common.copy_align = fls(width - 1);
+
+	if (of_device_is_compatible(node, "xlnx,axi-dma-mm2s-channel")) {
+		chan->id = 0;
+		chan->ctrl_offset = XILINX_DMA_MM2S_CTRL_OFFSET;
+	} else if (of_device_is_compatible(node, "xlnx,axi-dma-s2mm-channel")) {
+		chan->id = 1;
+		chan->ctrl_offset = XILINX_DMA_S2MM_CTRL_OFFSET;
+	} else {
+		dev_err(xdev->dev, "Invalid channel compatible node\n");
+		return -EINVAL;
+	}
+
+	xdev->chan[chan->id] = chan;
+
+	/* Initialize the channel */
+	err = xilinx_dma_chan_reset(chan);
+	if (err) {
+		dev_err(xdev->dev, "Reset channel failed\n");
+		return err;
+	}
+
+	spin_lock_init(&chan->lock);
+	INIT_LIST_HEAD(&chan->pending_list);
+	INIT_LIST_HEAD(&chan->done_list);
+	INIT_LIST_HEAD(&chan->active_list);
+	INIT_LIST_HEAD(&chan->free_seg_list);
+
+	chan->common.device = &xdev->common;
+
+	/* find the IRQ line, if it exists in the device tree */
+	chan->irq = irq_of_parse_and_map(node, 0);
+	err = request_irq(chan->irq, xilinx_dma_irq_handler,
+			  IRQF_SHARED,
+			  "xilinx-dma-controller", chan);
+	if (err) {
+		dev_err(xdev->dev, "unable to request IRQ %d\n", chan->irq);
+		return err;
+	}
+
+	/* Initialize the tasklet */
+	tasklet_init(&chan->tasklet, xilinx_dma_do_tasklet,
+		     (unsigned long)chan);
+
+	/* Add the channel to DMA device channel list */
+	list_add_tail(&chan->common.device_node, &xdev->common.channels);
+
+	chan->idle = true;
+
+	return 0;
+}
+
+/**
+ * of_dma_xilinx_xlate - Translation function
+ * @dma_spec: Pointer to DMA specifier as found in the device tree
+ * @ofdma: Pointer to DMA controller data
+ *
+ * Return: DMA channel pointer on success and NULL on error
+ */
+static struct dma_chan *of_dma_xilinx_xlate(struct of_phandle_args *dma_spec,
+					    struct of_dma *ofdma)
+{
+	struct xilinx_dma_device *xdev = ofdma->of_dma_data;
+	int chan_id = dma_spec->args[0];
+
+	if (chan_id >= XILINX_DMA_MAX_CHANS_PER_DEVICE)
+		return NULL;
+
+	return dma_get_slave_channel(&xdev->chan[chan_id]->common);
+}
+
+/**
+ * xilinx_dma_probe - Driver probe function
+ * @pdev: Pointer to the platform_device structure
+ *
+ * Return: '0' on success and failure value on error
+ */
+static int xilinx_dma_probe(struct platform_device *pdev)
+{
+	struct xilinx_dma_device *xdev;
+	struct device_node *child, *node;
+	struct resource *res;
+	int i, ret;
+
+	xdev = devm_kzalloc(&pdev->dev, sizeof(*xdev), GFP_KERNEL);
+	if (!xdev)
+		return -ENOMEM;
+
+	xdev->dev = &(pdev->dev);
+	INIT_LIST_HEAD(&xdev->common.channels);
+
+	node = pdev->dev.of_node;
+
+	/* Map the registers */
+	res = platform_get_resource(pdev, IORESOURCE_MEM, 0);
+	xdev->regs = devm_ioremap_resource(&pdev->dev, res);
+	if (IS_ERR(xdev->regs))
+		return PTR_ERR(xdev->regs);
+
+	/* Check if SG is enabled */
+	xdev->has_sg = of_property_read_bool(node, "xlnx,include-sg");
+
+	/* Axi DMA only do slave transfers */
+	dma_cap_set(DMA_SLAVE, xdev->common.cap_mask);
+	dma_cap_set(DMA_PRIVATE, xdev->common.cap_mask);
+	xdev->common.device_prep_slave_sg = xilinx_dma_prep_slave_sg;
+	xdev->common.device_terminate_all = xilinx_dma_terminate_all;
+	xdev->common.device_issue_pending = xilinx_dma_issue_pending;
+	xdev->common.device_alloc_chan_resources =
+		xilinx_dma_alloc_chan_resources;
+	xdev->common.device_free_chan_resources =
+		xilinx_dma_free_chan_resources;
+	xdev->common.device_tx_status = xilinx_dma_tx_status;
+	xdev->common.directions = BIT(DMA_DEV_TO_MEM) | BIT(DMA_MEM_TO_DEV);
+	xdev->common.residue_granularity = DMA_RESIDUE_GRANULARITY_SEGMENT;
+	xdev->common.dev = &pdev->dev;
+
+	platform_set_drvdata(pdev, xdev);
+
+	for_each_child_of_node(node, child) {
+		ret = xilinx_dma_chan_probe(xdev, child);
+		if (ret) {
+			dev_err(&pdev->dev, "Probing channels failed\n");
+			goto free_chan_resources;
+		}
+	}
+
+	dma_async_device_register(&xdev->common);
+
+	ret = of_dma_controller_register(node, of_dma_xilinx_xlate, xdev);
+	if (ret) {
+		dev_err(&pdev->dev, "Unable to register DMA to DT\n");
+		dma_async_device_unregister(&xdev->common);
+		goto free_chan_resources;
+	}
+
+	dev_info(&pdev->dev, "Xilinx AXI DMA Engine driver Probed!!\n");
+
+	return 0;
+
+free_chan_resources:
+	for (i = 0; i < XILINX_DMA_MAX_CHANS_PER_DEVICE; i++)
+		if (xdev->chan[i])
+			xilinx_dma_chan_remove(xdev->chan[i]);
+
+	return ret;
+}
+
+/**
+ * xilinx_dma_remove - Driver remove function
+ * @pdev: Pointer to the platform_device structure
+ *
+ * Return: Always '0'
+ */
+static int xilinx_dma_remove(struct platform_device *pdev)
+{
+	struct xilinx_dma_device *xdev = platform_get_drvdata(pdev);
+	int i;
+
+	of_dma_controller_free(pdev->dev.of_node);
+	dma_async_device_unregister(&xdev->common);
+
+	for (i = 0; i < XILINX_DMA_MAX_CHANS_PER_DEVICE; i++)
+		if (xdev->chan[i])
+			xilinx_dma_chan_remove(xdev->chan[i]);
+
+	return 0;
+}
+
+static const struct of_device_id xilinx_dma_of_match[] = {
+	{ .compatible = "xlnx,axi-dma-1.00.a",},
+	{}
+};
+MODULE_DEVICE_TABLE(of, xilinx_dma_of_match);
+
+static struct platform_driver xilinx_dma_driver = {
+	.driver = {
+		.name = "xilinx-dma",
+		.of_match_table = xilinx_dma_of_match,
+	},
+	.probe = xilinx_dma_probe,
+	.remove = xilinx_dma_remove,
+};
+
+module_platform_driver(xilinx_dma_driver);
+
+MODULE_AUTHOR("Xilinx, Inc.");
+MODULE_DESCRIPTION("Xilinx DMA driver");
+MODULE_LICENSE("GPL");
-- 
2.1.2



From anurag.kumar.vulisha at xilinx.com  Wed Aug  5 04:47:37 2015
From: anurag.kumar.vulisha at xilinx.com (Anurag Kumar Vulisha)
Date: Wed, 5 Aug 2015 17:17:37 +0530
Subject: [PATCH] dmaengine: vdma: Add 64 bit addressing support to the driver
Message-ID: <1438775257-3511-1-git-send-email-anuragku@xilinx.com>

This patch adds the 64 bit addressing support to the vdma driver.

Signed-off-by: Anurag Kumar Vulisha <anuragku at xilinx.com>
---
 drivers/dma/Kconfig              |    2 +-
 drivers/dma/xilinx/xilinx_vdma.c |   36 ++++++++++++++++++++++++++++++------
 2 files changed, 31 insertions(+), 7 deletions(-)

diff --git a/drivers/dma/Kconfig b/drivers/dma/Kconfig
index bda2cb0..a7cd0a8 100644
--- a/drivers/dma/Kconfig
+++ b/drivers/dma/Kconfig
@@ -398,7 +398,7 @@ config FSL_EDMA
 
 config XILINX_VDMA
 	tristate "Xilinx AXI VDMA Engine"
-	depends on (ARCH_ZYNQ || MICROBLAZE)
+	depends on (ARCH_ZYNQ || MICROBLAZE || ARM64)
 	select DMA_ENGINE
 	help
 	  Enable support for Xilinx AXI VDMA Soft IP.
diff --git a/drivers/dma/xilinx/xilinx_vdma.c b/drivers/dma/xilinx/xilinx_vdma.c
index d8434d4..3dcbd29 100644
--- a/drivers/dma/xilinx/xilinx_vdma.c
+++ b/drivers/dma/xilinx/xilinx_vdma.c
@@ -98,7 +98,11 @@
 #define XILINX_VDMA_FRMDLY_STRIDE_FRMDLY_SHIFT	24
 #define XILINX_VDMA_FRMDLY_STRIDE_STRIDE_SHIFT	0
 
+#if defined(CONFIG_PHYS_ADDR_T_64BIT)
+#define XILINX_VDMA_REG_START_ADDRESS(n)	(0x000c + 8 * (n))
+#else
 #define XILINX_VDMA_REG_START_ADDRESS(n)	(0x000c + 4 * (n))
+#endif
 
 /* HW specific definitions */
 #define XILINX_VDMA_MAX_CHANS_PER_DEVICE	0x2
@@ -143,16 +147,16 @@
  * @next_desc: Next Descriptor Pointer @0x00
  * @pad1: Reserved @0x04
  * @buf_addr: Buffer address @0x08
- * @pad2: Reserved @0x0C
- * @vsize: Vertical Size @0x10
- * @hsize: Horizontal Size @0x14
+ * @pad2: Reserved @0x10
+ * @vsize: Vertical Size @0x14
+ * @hsize: Horizontal Size @0x18
  * @stride: Number of bytes between the first
- *	    pixels of each horizontal line @0x18
+ *	    pixels of each horizontal line @0x1C
  */
 struct xilinx_vdma_desc_hw {
 	u32 next_desc;
 	u32 pad1;
-	u32 buf_addr;
+	u64 buf_addr;
 	u32 pad2;
 	u32 vsize;
 	u32 hsize;
@@ -272,6 +276,20 @@ static inline void vdma_desc_write(struct xilinx_vdma_chan *chan, u32 reg,
 	vdma_write(chan, chan->desc_offset + reg, value);
 }
 
+#if defined(CONFIG_PHYS_ADDR_T_64BIT)
+static inline void vdma_desc_write_64(struct xilinx_vdma_chan *chan, u32 reg,
+				 u64 value)
+{
+	/* Write the lsb 32 bits*/
+	writel(lower_32_bits(value),
+			chan->xdev->regs + chan->desc_offset + reg);
+
+	/* Write the msb 32 bits */
+	writel(upper_32_bits(value),
+			chan->xdev->regs + chan->desc_offset + reg + 4);
+}
+#endif
+
 static inline u32 vdma_ctrl_read(struct xilinx_vdma_chan *chan, u32 reg)
 {
 	return vdma_read(chan, chan->ctrl_offset + reg);
@@ -700,9 +718,15 @@ static void xilinx_vdma_start_transfer(struct xilinx_vdma_chan *chan)
 		int i = 0;
 
 		list_for_each_entry(segment, &desc->segments, node) {
-			vdma_desc_write(chan,
+#if defined(CONFIG_PHYS_ADDR_T_64BIT)
+			vdma_desc_write_64(chan,
 					XILINX_VDMA_REG_START_ADDRESS(i++),
 					segment->hw.buf_addr);
+#else
+			vdma_desc_write(chan,
+					XILINX_VDMA_REG_START_ADDRESS(i++),
+					(u32)segment->hw.buf_addr);
+#endif
 			last = segment;
 		}
 
-- 
1.7.4



From eric.auger at linaro.org  Wed Aug  5 04:47:27 2015
From: eric.auger at linaro.org (Eric Auger)
Date: Wed, 05 Aug 2015 13:47:27 +0200
Subject: [PATCH v3 09/11] KVM: arm/arm64: vgic: Prevent userspace injection
 of a mapped interrupt
In-Reply-To: <20150805105345.GA4657@cbox>
References: <1437753309-17989-1-git-send-email-marc.zyngier@arm.com>
 <1437753309-17989-10-git-send-email-marc.zyngier@arm.com>
 <55C0E690.1090808@linaro.org> <55C0EBF5.2060708@arm.com>
 <55C1BBF9.2060004@linaro.org> <55C1DAE9.1050609@arm.com>
 <20150805105345.GA4657@cbox>
Message-ID: <55C1F7CF.5070904@linaro.org>

On 08/05/2015 12:53 PM, Christoffer Dall wrote:
> On Wed, Aug 05, 2015 at 10:44:09AM +0100, Marc Zyngier wrote:
>> On 05/08/15 08:32, Eric Auger wrote:
>>> Hi Marc,
>>> On 08/04/2015 06:44 PM, Marc Zyngier wrote:
>>>> On 04/08/15 17:21, Eric Auger wrote:
>>>>> Hi Marc,
>>>>> On 07/24/2015 05:55 PM, Marc Zyngier wrote:
>>>>>> Virtual interrupts mapped to a HW interrupt should only be triggered
>>>>>> from inside the kernel. Otherwise, you could end up confusing the
>>>>>> kernel (and the GIC's) state machine.
>>>>>>
>>>>>> Rearrange the injection path so that kvm_vgic_inject_irq is
>>>>>> used for non-mapped interrupts, and kvm_vgic_inject_mapped_irq is
>>>>>> used for mapped interrupts. The latter should only be called from
>>>>>> inside the kernel (timer, VFIO).
>>>>> nit: I would replace VFIO by irqfd.
>>>>> VFIO just triggers the eventfd/irqfd. This is KVM/irqfd that injects the
>>>>> virtual irq upon the irqfd signaling and he irqfd adaptation/ARM
>>>>> currently is implemented in vgic.c
>>>>
>>>> Ah, thanks for reminding me of the right terminology, I tend to think of
>>>> it as one big bag of nasty tricks... ;-)
>>>>
>>>> I'll update the commit message.
>>>>
>>>>>>
>>>>>> Signed-off-by: Marc Zyngier <marc.zyngier at arm.com>
>>>>>> ---
>>>>>>  include/kvm/arm_vgic.h |  2 +
>>>>>>  virt/kvm/arm/vgic.c    | 99 ++++++++++++++++++++++++++++++++++----------------
>>>>>>  2 files changed, 70 insertions(+), 31 deletions(-)
>>>>>>
>>>>>> diff --git a/include/kvm/arm_vgic.h b/include/kvm/arm_vgic.h
>>>>>> index 7306b4b..f6bfd79 100644
>>>>>> --- a/include/kvm/arm_vgic.h
>>>>>> +++ b/include/kvm/arm_vgic.h
>>>>>> @@ -351,6 +351,8 @@ void kvm_vgic_flush_hwstate(struct kvm_vcpu *vcpu);
>>>>>>  void kvm_vgic_sync_hwstate(struct kvm_vcpu *vcpu);
>>>>>>  int kvm_vgic_inject_irq(struct kvm *kvm, int cpuid, unsigned int irq_num,
>>>>>>  			bool level);
>>>>>> +int kvm_vgic_inject_mapped_irq(struct kvm *kvm, int cpuid,
>>>>>> +			       struct irq_phys_map *map, bool level);
>>>>>>  void vgic_v3_dispatch_sgi(struct kvm_vcpu *vcpu, u64 reg);
>>>>>>  int kvm_vgic_vcpu_pending_irq(struct kvm_vcpu *vcpu);
>>>>>>  int kvm_vgic_vcpu_active_irq(struct kvm_vcpu *vcpu);
>>>>>> diff --git a/virt/kvm/arm/vgic.c b/virt/kvm/arm/vgic.c
>>>>>> index 3f7b690..e40ef70 100644
>>>>>> --- a/virt/kvm/arm/vgic.c
>>>>>> +++ b/virt/kvm/arm/vgic.c
>>>>>> @@ -1533,7 +1533,8 @@ static int vgic_validate_injection(struct kvm_vcpu *vcpu, int irq, int level)
>>>>>>  }
>>>>>>  
>>>>>>  static int vgic_update_irq_pending(struct kvm *kvm, int cpuid,
>>>>>> -				  unsigned int irq_num, bool level)
>>>>>> +				   struct irq_phys_map *map,
>>>>>> +				   unsigned int irq_num, bool level)
>>>>>>  {
>>>>> In vgic_update_irq_pending, I needed to modify the following line and
>>>>> add the "&& !map".
>>>>>
>>>>>         if (!vgic_validate_injection(vcpu, irq_num, level) && !map) {
>>>>>
>>>>> Without that, the level being not properly modeled for level sensitive
>>>>> forwarded IRQs, the 2d injection fails.
>>>>
>>>> Ah! Is that because we never see the line being reset to zero, and the
>>>> VGIC still sees the line as pending at the distributor level?
>>> yes indeed
>>
>> Then it is a bigger problem we need to solve, and your solution just
>> papers over the issue.
>>
>> The main problem is that irqfd is essentially an edge-triggered
>> signalling. Fire and forget. Given that we're dealing with a level
>> triggered interrupt, we end up with the interrupt still marked as
>> pending (nobody took the signal down).
this does not really relate to irqfd: irqfd also comes with the concept
of resamplefd. in case the IRQ is not forwarded, this is the
irqfd_resampler_ack function that toggles the IRQ down (eventfd.c). Its
execution is triggered in vgic_process_maintenance. With forwarding the
EOI is not trappable anymore so this disappears.


>> The usual way to get out of that mess in is to evaluate the state of the
>> level on EOI. But we can't trap on EOI for a HW interrupt.
>>
>> So it raises the question: should we instead consider the HW pending
>> state instead of the software one for mapped interrupts? It is
>> expensive, but it feels more correct.
>>
> I thought we already covered this at LCA.  For mapped interrupts
> (forwarded) we should never consider the software pending state, because
> that state is managed by the hardware.  Or am I confusing concepts here?

Yes we discussed we should bypass most of the SW states.

in my previous integration I proposed a patch "KVM: arm: vgic: fix state
machine for forwarded IRQ". What's wrong with the below approach?


    Fix multiple injection of level sensitive forwarded IRQs.
    With current code, the second injection fails since the
    state bitmaps are not reset (process_maintenance is not
    called anymore).

    New implementation follows those principles:
    - A forwarded IRQ only can be sampled when it is pending
    - when queueing the IRQ (programming the LR), the pending state
      is removed as for edge sensitive IRQs
    - an injection of a forwarded IRQ is considered always valid since
      coming from the HW and level always is 1.

Eric

> 
> Thanks,
> -Christoffer
> 



From broonie at kernel.org  Wed Aug  5 04:50:13 2015
From: broonie at kernel.org (Mark Brown)
Date: Wed, 5 Aug 2015 12:50:13 +0100
Subject: [RFC PATCH 1/5] spi: introduce flag for memory mapped read
In-Reply-To: <55C0FD98.1090107@ti.com>
References: <1438072876-16338-1-git-send-email-vigneshr@ti.com>
 <1438072876-16338-2-git-send-email-vigneshr@ti.com>
 <20150731181745.GM20873@sirena.org.uk> <55BEF4AF.5090704@ti.com>
 <20150804155148.GR20873@sirena.org.uk> <55C0FD98.1090107@ti.com>
Message-ID: <20150805115013.GJ20873@sirena.org.uk>

On Tue, Aug 04, 2015 at 11:29:52PM +0530, R, Vignesh wrote:
> On 8/4/2015 9:21 PM, Mark Brown wrote:
> > On Mon, Aug 03, 2015 at 10:27:19AM +0530, Vignesh R wrote:

> > I still can't tell from the above what this interface is supposed to do.
> > It sounds like the use of memory mapped mode is supposed to be
> > transparent to users, it should just affect how the controller interacts
> > with the hardware, but if that's the case why do we need to expose it to
> > users at all?  Shouldn't the driver just use memory mapped mode if it's
> > faster?

> 2. SFI_MM_IF(SPI memory mapped interface): The SFI_MM_IF block only
> allows reading and writing to an SPI flash device only. Used to speed up
> flash reads. It _cannot_ be used to communicate with non flash devices.
> Now, the spi_message that ti-qspi receives in transfer_one() callback
> can be from mtd device(in which case SFI_MM_IF can be used) or from any
> other non flash SPI device (in which case SFI_MM_IF must not be used
> instead SPI_CORE is to be used) but there is no way(is there?) to
> distinguish where spi_message is from. Therefore I introduced flag
> (use_mmap_mode) to struct spi_message. mtd driver will set flag to true,
> this helps the ti-qspi driver to determine that the user is flash device
> and thus can do read via SFI_MM_IF. If this flag is not set then the
> user is assumed to be non flash SPI driver and will use SPI_CORE block
> to communicate.

So if you're trying to do this you need to document it adequately so
that other people can understand what it is supposed to do and how to
use and implement it.  People can't really tell how the interface is
supposed to work based on what was in the patch and the above isn't
really helping.  For example, how does this change or restrict what the
contents of the spi_message are?

> On the whole, I just need a way to determine that the user is a flash
> device in order to switch to memory mapped interface.

As far as I can tell you want to set a per spi_message flag saying that
the message is a flash read command?  If that's what this is trying to
do then why do you need to set the flag at all?  If the message is in a
clearly defined format and it's more efficient to use this mmap mode
then surely the driver can just recognise that the format is approprate
and switch into mmap mode without being explicitly told - I'm not clear
what the flag adds here.
-------------- next part --------------
A non-text attachment was scrubbed...
Name: signature.asc
Type: application/pgp-signature
Size: 473 bytes
Desc: Digital signature
URL: <http://lists.infradead.org/pipermail/linux-arm-kernel/attachments/20150805/1f75d591/attachment.sig>

From bhelgaas at google.com  Wed Aug  5 04:51:47 2015
From: bhelgaas at google.com (Bjorn Helgaas)
Date: Wed, 5 Aug 2015 06:51:47 -0500
Subject: [PATCH v4 1/3] PCI: generic: remove dependency on hw_pci
In-Reply-To: <20150805092533.GC6092@arm.com>
References: <1438721620-15493-1-git-send-email-jchandra@broadcom.com>
 <20150804234956.GF17327@google.com> <20150805092318.GB6092@arm.com>
 <20150805092533.GC6092@arm.com>
Message-ID: <CAErSpo5g0VGeQeHArys+h_6eQuQnV+dH+bHBaLmJC1EdA-q4Hw@mail.gmail.com>

On Wed, Aug 5, 2015 at 4:25 AM, Will Deacon <will.deacon at arm.com> wrote:
> On Wed, Aug 05, 2015 at 10:23:18AM +0100, Will Deacon wrote:
>> That said, I just tried to build this and it fails to compile the x-gene
>> PCI host driver. Fixup below.
>
> Wait, there's more!

Thanks!  I fixed these two and updated pci/enumeration.  But the 0-day
build also found this:

commit: cc44fbb49d995ad2348d530300abf7877105094f [4/13] ARM/PCI,
designware, xilinx: Use pci_scan_root_bus_msi()
   drivers/built-in.o: In function `dw_msi_setup_irq':
>> :(.text+0x2a3c8): undefined reference to `pci_write_msi_msg'

I don't see the problem there yet, and I'm going on vacation until
Monday, so I won't be able to do anything with this until then.

Bjorn


> diff --git a/drivers/pci/host/pci-xgene.c b/drivers/pci/host/pci-xgene.c
> index 514f41b86c49..8ab3bd098424 100644
> --- a/drivers/pci/host/pci-xgene.c
> +++ b/drivers/pci/host/pci-xgene.c
> @@ -506,7 +506,7 @@ static int xgene_pcie_msi_enable(struct xgene_pcie_port *port)
>  {
>         struct device_node *msi_node;
>
> -       msi_node = of_parse_phandle(port->dev.of_node, "msi-parent", 0);
> +       msi_node = of_parse_phandle(port->dev->of_node, "msi-parent", 0);
>         if (!msi_node)
>                 return -ENODEV;
>
> @@ -515,7 +515,7 @@ static int xgene_pcie_msi_enable(struct xgene_pcie_port *port)
>                 return -ENODEV;
>
>         of_node_put(msi_node);
> -       port->msi->dev = &port->dev;
> +       port->msi->dev = port->dev;
>         return 0;
>  }
>
>


From gregory.clement at free-electrons.com  Wed Aug  5 04:53:23 2015
From: gregory.clement at free-electrons.com (Gregory CLEMENT)
Date: Wed, 05 Aug 2015 13:53:23 +0200
Subject: [GIT PULL] ARM: mvebu: dt changes for v4.3 #2
In-Reply-To: <20150805091128.GL6390@localhost>
References: <55BB3FAE.1020907@free-electrons.com>
 <20150805091128.GL6390@localhost>
Message-ID: <55C1F933.2010500@free-electrons.com>

Hi Olof,


> One tip:
> 
>>
>>  arch/arm/boot/dts/Makefile                       |   1 +
>>  arch/arm/boot/dts/orion5x-linkstation-lswtgl.dts | 273 ++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
>>  2 files changed, 274 insertions(+)
>>  create mode 100644 arch/arm/boot/dts/orion5x-linkstation-lswtgl.dts
> 
> If you redirect "git request-pull" to a file (or even pipe it through cat
> instead of straight onto your terminal) it'll default to ~78 character lines
> instead of the width of your terminal.
> 

Thanks for the tip!

Gregory

> 
> -Olof
> 


-- 
Gregory Clement, Free Electrons
Kernel, drivers, real-time and embedded Linux
development, consulting, training and support.
http://free-electrons.com


From shawnguo at kernel.org  Wed Aug  5 04:57:02 2015
From: shawnguo at kernel.org (Shawn Guo)
Date: Wed, 5 Aug 2015 19:57:02 +0800
Subject: [PATCH,v3 2/3] ARM: dts: ls1021a: Add the eTSEC controller nodes
In-Reply-To: <1438094636-20421-2-git-send-email-claudiu.manoil@freescale.com>
References: <20150727142816.GP12927@tiger>
 <1438094636-20421-1-git-send-email-claudiu.manoil@freescale.com>
 <1438094636-20421-2-git-send-email-claudiu.manoil@freescale.com>
Message-ID: <20150805115702.GI12927@tiger>

On Tue, Jul 28, 2015 at 05:43:55PM +0300, Claudiu Manoil wrote:
> Add basic support for all the eTSEC controllers on the
> ls1021a SoC.  Second interrupt group register blocks
> and their corresponding Rx/Tx/Err interrupt sources are
> included as well for each eTSEC node.
> 
> Signed-off-by: Alison Wang <alison.wang at freescale.com>
> Signed-off-by: Claudiu Manoil <claudiu.manoil at freescale.com>

Applied both with a minor change below.

> ---
> v2: various findings, added 2nd interrupt group;
> v3: addressed findings from Shawn Guo -
>     - initial patch split in soc, boards and bindings patches;
>     - removed redundant all zero local-mac-address;
>     - subject prefix;
> 
>  arch/arm/boot/dts/ls1021a.dtsi | 88 ++++++++++++++++++++++++++++++++++++++++++
>  1 file changed, 88 insertions(+)
> 
> diff --git a/arch/arm/boot/dts/ls1021a.dtsi b/arch/arm/boot/dts/ls1021a.dtsi
> index 1b306c7..0638cda 100644
> --- a/arch/arm/boot/dts/ls1021a.dtsi
> +++ b/arch/arm/boot/dts/ls1021a.dtsi
> @@ -59,6 +59,9 @@
>  		serial3 = &lpuart3;
>  		serial4 = &lpuart4;
>  		serial5 = &lpuart5;
> +		ethernet0 = &enet0;
> +		ethernet1 = &enet1;
> +		ethernet2 = &enet2;

I moved these above serial to keep them sort alphabetically.

Shawn

>  		sysclk = &sysclk;
>  	};
>  
> @@ -391,6 +394,91 @@
>  			reg = <0x0 0x2d24000 0x0 0x4000>;
>  		};
>  
> +		enet0: ethernet at 2d10000 {
> +			compatible = "fsl,etsec2";
> +			device_type = "network";
> +			#address-cells = <2>;
> +			#size-cells = <2>;
> +			interrupt-parent = <&gic>;
> +			model = "eTSEC";
> +			fsl,magic-packet;
> +			ranges;
> +
> +			queue-group at 2d10000 {
> +				#address-cells = <2>;
> +				#size-cells = <2>;
> +				reg = <0x0 0x2d10000 0x0 0x1000>;
> +				interrupts = <GIC_SPI 144 IRQ_TYPE_LEVEL_HIGH>,
> +					<GIC_SPI 145 IRQ_TYPE_LEVEL_HIGH>,
> +					<GIC_SPI 146 IRQ_TYPE_LEVEL_HIGH>;
> +			};
> +
> +			queue-group at 2d14000  {
> +				#address-cells = <2>;
> +				#size-cells = <2>;
> +				reg = <0x0 0x2d14000 0x0 0x1000>;
> +				interrupts = <GIC_SPI 147 IRQ_TYPE_LEVEL_HIGH>,
> +					<GIC_SPI 148 IRQ_TYPE_LEVEL_HIGH>,
> +					<GIC_SPI 149 IRQ_TYPE_LEVEL_HIGH>;
> +			};
> +		};
> +
> +		enet1: ethernet at 2d50000 {
> +			compatible = "fsl,etsec2";
> +			device_type = "network";
> +			#address-cells = <2>;
> +			#size-cells = <2>;
> +			interrupt-parent = <&gic>;
> +			model = "eTSEC";
> +			ranges;
> +
> +			queue-group at 2d50000  {
> +				#address-cells = <2>;
> +				#size-cells = <2>;
> +				reg = <0x0 0x2d50000 0x0 0x1000>;
> +				interrupts = <GIC_SPI 150 IRQ_TYPE_LEVEL_HIGH>,
> +					<GIC_SPI 152 IRQ_TYPE_LEVEL_HIGH>,
> +					<GIC_SPI 153 IRQ_TYPE_LEVEL_HIGH>;
> +			};
> +
> +			queue-group at 2d54000  {
> +				#address-cells = <2>;
> +				#size-cells = <2>;
> +				reg = <0x0 0x2d54000 0x0 0x1000>;
> +				interrupts = <GIC_SPI 154 IRQ_TYPE_LEVEL_HIGH>,
> +					<GIC_SPI 155 IRQ_TYPE_LEVEL_HIGH>,
> +					<GIC_SPI 156 IRQ_TYPE_LEVEL_HIGH>;
> +			};
> +		};
> +
> +		enet2: ethernet at 2d90000 {
> +			compatible = "fsl,etsec2";
> +			device_type = "network";
> +			#address-cells = <2>;
> +			#size-cells = <2>;
> +			interrupt-parent = <&gic>;
> +			model = "eTSEC";
> +			ranges;
> +
> +			queue-group at 2d90000  {
> +				#address-cells = <2>;
> +				#size-cells = <2>;
> +				reg = <0x0 0x2d90000 0x0 0x1000>;
> +				interrupts = <GIC_SPI 157 IRQ_TYPE_LEVEL_HIGH>,
> +					<GIC_SPI 158 IRQ_TYPE_LEVEL_HIGH>,
> +					<GIC_SPI 159 IRQ_TYPE_LEVEL_HIGH>;
> +			};
> +
> +			queue-group at 2d94000  {
> +				#address-cells = <2>;
> +				#size-cells = <2>;
> +				reg = <0x0 0x2d94000 0x0 0x1000>;
> +				interrupts = <GIC_SPI 160 IRQ_TYPE_LEVEL_HIGH>,
> +					<GIC_SPI 161 IRQ_TYPE_LEVEL_HIGH>,
> +					<GIC_SPI 162 IRQ_TYPE_LEVEL_HIGH>;
> +			};
> +		};
> +
>  		usb at 8600000 {
>  			compatible = "fsl-usb2-dr-v2.5", "fsl-usb2-dr";
>  			reg = <0x0 0x8600000 0x0 0x1000>;
> -- 
> 1.7.11.7
> 
> 
> _______________________________________________
> linux-arm-kernel mailing list
> linux-arm-kernel at lists.infradead.org
> http://lists.infradead.org/mailman/listinfo/linux-arm-kernel
> 


From shawnguo at kernel.org  Wed Aug  5 04:59:50 2015
From: shawnguo at kernel.org (Shawn Guo)
Date: Wed, 5 Aug 2015 19:59:50 +0800
Subject: [PATCH v2] ARM: dts: vf-colibri: define stdout-path property
In-Reply-To: <0af90d47043467591155c16f621cc1da@agner.ch>
References: <1436971817-28523-1-git-send-email-stefan@agner.ch>
 <0af90d47043467591155c16f621cc1da@agner.ch>
Message-ID: <20150805115950.GJ12927@tiger>

On Thu, Jul 30, 2015 at 06:43:29PM +0200, Stefan Agner wrote:
> Hi Shawn,
> 
> Did you notice this change? Just asking since you applied some other
> changes already...

Just applied.  Sorry for the delay.

Shawn

> 
> --
> Stefan
> 
> On 2015-07-15 16:50, Stefan Agner wrote:
> > Define Vybrid's UART0, connected to the Colibri pinout UART_A, as
> > standard output.
> > 
> > Signed-off-by: Stefan Agner <stefan at agner.ch>
> > ---
> >  arch/arm/boot/dts/vf-colibri-eval-v3.dtsi | 2 +-
> >  1 file changed, 1 insertion(+), 1 deletion(-)
> > 
> > diff --git a/arch/arm/boot/dts/vf-colibri-eval-v3.dtsi
> > b/arch/arm/boot/dts/vf-colibri-eval-v3.dtsi
> > index 77e1a45..2ce6fe5 100644
> > --- a/arch/arm/boot/dts/vf-colibri-eval-v3.dtsi
> > +++ b/arch/arm/boot/dts/vf-colibri-eval-v3.dtsi
> > @@ -9,7 +9,7 @@
> >  
> >  / {
> >  	chosen {
> > -		bootargs = "console=ttyLP0,115200";
> > +		stdout-path = "serial0:115200n8";
> >  	};
> >  
> >  	clk16m: clk16m {
> 
> 
> _______________________________________________
> linux-arm-kernel mailing list
> linux-arm-kernel at lists.infradead.org
> http://lists.infradead.org/mailman/listinfo/linux-arm-kernel
> 


From broonie at kernel.org  Wed Aug  5 04:59:51 2015
From: broonie at kernel.org (Mark Brown)
Date: Wed, 5 Aug 2015 12:59:51 +0100
Subject: [PATCH v2 0/4] Add SPDIF support for rockchip
In-Reply-To: <1438756921.27576.4.camel@collabora.co.uk>
References: <1438687099-14282-1-git-send-email-sjoerd.simons@collabora.co.uk>
 <20150804153649.GP20873@sirena.org.uk>
 <1438756921.27576.4.camel@collabora.co.uk>
Message-ID: <20150805115951.GK20873@sirena.org.uk>

On Wed, Aug 05, 2015 at 08:42:01AM +0200, Sjoerd Simons wrote:
> On Tue, 2015-08-04 at 16:36 +0100, Mark Brown wrote:

> > I only appear to have patch 2 (with the misspelt subject), not the
> > binding documentation.

> Applogies, Send that patch specifically to you now.

And I deleted it unread because it was just some random off list patch
with no context.  :(

> Seems get_maintainers.pl didn't include you in the list (nor the other
> asoc maintainers in the list), I guess it might be good to add
> Documentation/devicetree/bindings/sounds/ to the ASoC file list in
> MAINTAINTERS ?

Please follow the process covered in SubmittingPatches for making kernel
changes, but note that there's generic sound drivers as well as ASoC
ones.

In general it is a very bad idea to rely on get_maintainers, it is prone
to both false positives and missing relevant people.  It can be useful
to look at but you need to think about what it's telling you.  In this
case it should be fairly easy to tell that you ought to send the binding
documentation along with the driver.
-------------- next part --------------
A non-text attachment was scrubbed...
Name: signature.asc
Type: application/pgp-signature
Size: 473 bytes
Desc: Digital signature
URL: <http://lists.infradead.org/pipermail/linux-arm-kernel/attachments/20150805/1b4a4ea0/attachment.sig>

From shawnguo at kernel.org  Wed Aug  5 05:10:32 2015
From: shawnguo at kernel.org (Shawn Guo)
Date: Wed, 5 Aug 2015 20:10:32 +0800
Subject: [PATCH v5 0/6] add device tree support for mxc rtc
In-Reply-To: <1437946673-7402-1-git-send-email-tremyfr@gmail.com>
References: <1437946673-7402-1-git-send-email-tremyfr@gmail.com>
Message-ID: <20150805121032.GK12927@tiger>

On Sun, Jul 26, 2015 at 11:37:47PM +0200, Philippe Reynes wrote:
> Philippe Reynes (6):
>   imx31: add a second rtc clock

clk: imx: ...

>   imx35: define two clocks for rtc

clk: imx35: ...

>   rtc: mxc: use a second rtc clock
>   dt-binding: document the binding for mxc rtc
>   rtc: mxc: add support of device tree
>   imx27: dt: add support of internal rtc

ARM: dts: imx27: ...

Applied all with above minor changes on subject prefix.

Shawn


From maitysanchayan at gmail.com  Wed Aug  5 05:10:18 2015
From: maitysanchayan at gmail.com (Sanchayan Maity)
Date: Wed,  5 Aug 2015 17:40:18 +0530
Subject: [PATCH v2] Add continuous sampling with IIO buffers for Vybrid
Message-ID: <cover.1438775572.git.maitysanchayan@gmail.com>

Hello,

This patch adds support for continuous sampling provided by the
ADC block on Vybrid by leveraging the IIO triggered buffer and
IIO sysfs trigger infrastructure.

The patch has been tested on Colibri VF50 and VF61 on shawn's
tree for-next branch with the patches [1] and [2] applied.

The below script was used for testing.

#!/bin/sh
echo 0 > /sys/bus/iio/devices/iio:device0/scan_elements/in_voltage8_en
echo 0 > /sys/bus/iio/devices/iio:device0/scan_elements/in_voltage9_en
echo 1 > /sys/bus/iio/devices/iio:device0/scan_elements/in_temp_en
echo 1 > /sys/bus/iio/devices/iio:device0/scan_elements/in_timestamp_en
echo 0 > /sys/bus/iio/devices/iio_sysfs_trigger/add_trigger
/home/root/generic_buffer -n 4003b000.adc -t sysfstrig0 -l 512 -c 10
echo 0 > /sys/bus/iio/devices/iio:device0/scan_elements/in_timestamp_en
echo 0 > /sys/bus/iio/devices/iio:device0/scan_elements/in_temp_en
echo 0 > /sys/bus/iio/devices/iio:device0/scan_elements/in_voltage8_en
echo 0 > /sys/bus/iio/devices/iio:device0/scan_elements/in_voltage9_en

Feedback and comments are most welcome.

Changes since v2:
1. Use a fixed size buffer instead of kmalloc allocated during update
scan mode
2. Remove a write to read only register ADC_HS (COCO bit)

Version 1 patch can be found here
http://www.spinics.net/lists/linux-iio/msg20053.html

[1]. https://lkml.org/lkml/2015/5/27/350
[2]. https://lkml.org/lkml/2015/7/14/395

Had some additional queries.

On shawn's tree, using imx_v6_v7_defconfig and running the above
script on VF50 gives me the following trace:

[  199.976662] INFO: rcu_sched self-detected stall on CPU
[  199.982015]  0: (2600 ticks this GP) idle=181/140000000000002/0 softirq=14591/14591 fqs=0
[  199.990406]   (t=2600 jiffies g=11024 c=11023 q=20)
[  199.995430] rcu_sched kthread starved for 2600 jiffies! g11024 c11023 f0x0
[  200.002523] Task dump for CPU 0:
[  200.005830] generic_buffer  R running      0   414    413 0x00000002
[  200.012370] Backtrace:
[  200.014974] [<80013708>] (dump_backtrace) from [<800138fc>] (show_stack+0x18/0x1c)
[  200.022665]  r7:80ae0f40 r6:80b374e8 r5:0000019d r4:85fdd080
[  200.028578] [<800138e4>] (show_stack) from [<800557bc>] (sched_show_task+0x11c/0x22c)
[  200.036555] [<800556a0>] (sched_show_task) from [<80057efc>] (dump_cpu_task+0x34/0x44)
[  200.044596]  r6:80000193 r5:80ae0f40 r4:00000000
[  200.049432] [<80057ec8>] (dump_cpu_task) from [<800820f8>] (rcu_dump_cpu_stacks+0x8c/0xd0)
[  200.057821]  r5:80ae0f40 r4:00000000
[  200.061563] [<8008206c>] (rcu_dump_cpu_stacks) from [<80085b88>] (rcu_check_callbacks+0x4dc/0x854)
[  200.070655]  r9:80ae0f40 r8:0720b000 r7:80ad09cc r6:80ae0f40 r5:80acd600 r4:87cd8600
[  200.078701] [<800856ac>] (rcu_check_callbacks) from [<80088820>] (update_process_times+0x40/0x6c)
[  200.087699]  r10:87cd5fc0 r9:8009a180 r8:80aedb80 r7:0000002e r6:8764c12d r5:00000000
[  200.095800]  r4:85fdd080
[  200.098462] [<800887e0>] (update_process_times) from [<8009a17c>] (tick_sched_handle.isra.19+0x4c/0x50)
[  200.108049]  r5:85e85d40 r4:87cd5fc0
[  200.111822] [<8009a130>] (tick_sched_handle.isra.19) from [<8009a1e4>] (tick_sched_timer+0x64/0xb0)
[  200.121098] [<8009a180>] (tick_sched_timer) from [<80089220>] (__hrtimer_run_queues+0xc4/0x1cc)
[  200.129989]  r7:0000002e r6:87649b3a r5:87cd5d00 r4:87cd5c80
[  200.135915] [<8008915c>] (__hrtimer_run_queues) from [<80089950>] (hrtimer_interrupt+0xc8/0x21c)
[  200.144898]  r10:87cd5d38 r9:87cd5d58 r8:87cd5c80 r7:87cd5cc0 r6:ffffffff r5:7fffffff
[  200.153061]  r4:00000003
[  200.155752] [<80089888>] (hrtimer_interrupt) from [<8054dcd0>] (gt_clockevent_interrupt+0x48/0x74)
[  200.164905]  r10:85e85f80 r9:87806000 r8:00000010 r7:87817b40 r6:87808100 r5:87cdab40
[  200.173082]  r4:00000001
[  200.175758] [<8054dc88>] (gt_clockevent_interrupt) from [<8007cab0>] (handle_percpu_devid_irq+0x8c/0xac)
[  200.185442]  r5:80aedd20 r4:87cdab40
[  200.189215] [<8007ca24>] (handle_percpu_devid_irq) from [<800786e4>] (generic_handle_irq+0x30/0x44)
[  200.198460]  r9:87806000 r8:00000001 r7:85e85e30 r6:80ad0b30 r5:00000010 r4:00000010
[  200.206567] [<800786b4>] (generic_handle_irq) from [<80078a08>] (__handle_domain_irq+0x6c/0xe8)
[  200.215455]  r5:00000010 r4:80acb5fc
[  200.219219] [<8007899c>] (__handle_domain_irq) from [<80009560>] (gic_handle_irq+0x28/0x68)
[  200.227759]  r9:87806000 r8:00000001 r7:88002100 r6:80ad0ca8 r5:8800210c r4:85e85d40
[  200.235861] [<80009538>] (gic_handle_irq) from [<80014564>] (__irq_svc+0x44/0x5c)
[  200.243526] Exception stack(0x85e85d40 to 0x85e85d88)
[  200.248720] 5d40: 00000001 85fdd548 00000000 85fdd080 00000202 00000000 80ad0b30 80ad0080
[  200.257104] 5d60: 00000001 87806000 85e85f80 85e85dcc 80c9f5d0 85e85d88 8006b5a0 8002ff80
[  200.265468] 5d80: 60000113 ffffffff
[  200.269056]  r7:85e85d74 r6:ffffffff r5:60000113 r4:8002ff80
[  200.274995] [<8002fec8>] (__do_softirq) from [<800304c8>] (irq_exit+0xc4/0x138)
[  200.282486]  r10:85e85f80 r9:87806000 r8:00000001 r7:00000000 r6:80ad0b30 r5:00000000
[  200.290660]  r4:80acb5fc
[  200.293345] [<80030404>] (irq_exit) from [<80078a10>] (__handle_domain_irq+0x74/0xe8)
[  200.301367]  r5:00000000 r4:80acb5fc
[  200.305135] [<8007899c>] (__handle_domain_irq) from [<80009560>] (gic_handle_irq+0x28/0x68)
[  200.313680]  r9:85efc60c r8:85e4bc00 r7:88002100 r6:80ad0ca8 r5:8800210c r4:85e85e30
[  200.321777] [<80009538>] (gic_handle_irq) from [<80014564>] (__irq_svc+0x44/0x5c)
[  200.329442] Exception stack(0x85e85e30 to 0x85e85e78)
[  200.334628] 5e20:                                     00000001 85fdd548 00000000 85fdd080
[  200.343010] 5e40: 00000001 803ce7c8 85e4bc00 00000000 85e4bc00 85efc60c 85e85f80 85e85e84
[  200.351384] 5e60: 80c9f5d0 85e85e78 8006b5a0 803ce7e8 60000013 ffffffff
[  200.358131]  r7:85e85e64 r6:ffffffff r5:60000013 r4:803ce7e8
[  200.364087] [<803ce7c8>] (dev_attr_store) from [<801739a0>] (sysfs_kf_write+0x54/0x58)
[  200.372217] [<8017394c>] (sysfs_kf_write) from [<80172b60>] (kernfs_fop_write+0xc4/0x1a8)
[  200.380579]  r7:00000000 r6:00000000 r5:00000001 r4:85efc600
[  200.386518] [<80172a9c>] (kernfs_fop_write) from [<80104f10>] (__vfs_write+0x2c/0xe0)
[  200.394535]  r10:00000000 r9:85e84000 r8:8000fc84 r7:85e85f80 r6:76fa3000 r5:85e85f80
[  200.402696]  r4:85fb2500
[  200.405376] [<80104ee4>] (__vfs_write) from [<801057b4>] (vfs_write+0x98/0x16c)
[  200.412865]  r8:8000fc84 r7:85e85f80 r6:76fa3000 r5:00000001 r4:85fb2500
[  200.419878] [<8010571c>] (vfs_write) from [<80106028>] (SyS_write+0x4c/0xa8)
[  200.427072]  r8:8000fc84 r7:00000001 r6:76fa3000 r5:85fb2500 r4:85fb2500
[  200.434099] [<80105fdc>] (SyS_write) from [<8000faa0>] (ret_fast_syscall+0x0/0x54)
[  200.441848]  r7:00000004 r6:76fa3000 r5:00000001 r4:002be960

On shawn's tree, using our own defconfig it all works fine.

The RCU related configs in imx_v6_v7_defconfig are:
# RCU Subsystem
CONFIG_TREE_RCU=y
# CONFIG_RCU_EXPERT is not set
CONFIG_SRCU=y
# CONFIG_TASKS_RCU is not set
CONFIG_RCU_STALL_COMMON=y
# CONFIG_TREE_RCU_TRACE is not set
# CONFIG_RCU_NOCB_CPU is not set
# CONFIG_RCU_EXPEDITE_BOOT is not set
# RCU Debugging
CONFIG_PROVE_RCU=y
# CONFIG_PROVE_RCU_REPEATEDLY is not set
# CONFIG_SPARSE_RCU_POINTER is not set
# CONFIG_RCU_TORTURE_TEST is not set
CONFIG_RCU_CPU_STALL_TIMEOUT=21
CONFIG_RCU_CPU_STALL_INFO=y
# CONFIG_RCU_TRACE is not set
# CONFIG_RCU_EQS_DEBUG is not set

The RCU related configs in our own defconfig are:
# RCU Subsystem
CONFIG_TINY_RCU=y
CONFIG_SRCU=y
# CONFIG_TASKS_RCU is not set
# CONFIG_RCU_STALL_COMMON is not set
# CONFIG_TREE_RCU_TRACE is not set
CONFIG_RCU_KTHREAD_PRIO=0
# RCU Debugging
# CONFIG_SPARSE_RCU_POINTER is not set
# CONFIG_RCU_TORTURE_TEST is not set
# CONFIG_RCU_TRACE is not set

With the above second set of configs I do not encounter any problems.

I do not have any knowledge on the RCU front, can someone also comment
with regards to that? Am I doing something wrong in the driver?
My guess would be those RCU STALL configs?

Thanks & Regards,
Sanchayan Maity.

Sanchayan Maity (1):
  iio: adc: vf610: Add IIO buffer support for Vybrid ADC

 drivers/iio/adc/Kconfig     |   4 ++
 drivers/iio/adc/vf610_adc.c | 107 +++++++++++++++++++++++++++++++++++++++++---
 2 files changed, 105 insertions(+), 6 deletions(-)

-- 
2.5.0



From maitysanchayan at gmail.com  Wed Aug  5 05:10:19 2015
From: maitysanchayan at gmail.com (Sanchayan Maity)
Date: Wed,  5 Aug 2015 17:40:19 +0530
Subject: [PATCH v2] iio: adc: vf610: Add IIO buffer support for Vybrid ADC
In-Reply-To: <cover.1438775572.git.maitysanchayan@gmail.com>
References: <cover.1438775572.git.maitysanchayan@gmail.com>
Message-ID: <1bb1f290da601bbda41875a92ba6e983b423d7b0.1438775572.git.maitysanchayan@gmail.com>

This patch adds support for IIO buffer to the Vybrid ADC driver.
IIO triggered buffer infrastructure along with iio sysfs trigger
is used to leverage continuous sampling support provided by the
ADC block.

Signed-off-by: Sanchayan Maity <maitysanchayan at gmail.com>
---
 drivers/iio/adc/Kconfig     |   4 ++
 drivers/iio/adc/vf610_adc.c | 107 +++++++++++++++++++++++++++++++++++++++++---
 2 files changed, 105 insertions(+), 6 deletions(-)

diff --git a/drivers/iio/adc/Kconfig b/drivers/iio/adc/Kconfig
index 7c55658..4661241 100644
--- a/drivers/iio/adc/Kconfig
+++ b/drivers/iio/adc/Kconfig
@@ -337,6 +337,10 @@ config TWL6030_GPADC
 config VF610_ADC
 	tristate "Freescale vf610 ADC driver"
 	depends on OF
+	select IIO_BUFFER
+	select IIO_TRIGGER
+	select IIO_SYSFS_TRIGGER
+	select IIO_TRIGGERED_BUFFER
 	help
 	  Say yes here to support for Vybrid board analog-to-digital converter.
 	  Since the IP is used for i.MX6SLX, the driver also support i.MX6SLX.
diff --git a/drivers/iio/adc/vf610_adc.c b/drivers/iio/adc/vf610_adc.c
index 23b8fb9..97cb2ed 100644
--- a/drivers/iio/adc/vf610_adc.c
+++ b/drivers/iio/adc/vf610_adc.c
@@ -34,8 +34,11 @@
 #include <linux/err.h>
 
 #include <linux/iio/iio.h>
+#include <linux/iio/buffer.h>
 #include <linux/iio/sysfs.h>
-#include <linux/iio/driver.h>
+#include <linux/iio/trigger.h>
+#include <linux/iio/trigger_consumer.h>
+#include <linux/iio/triggered_buffer.h>
 
 /* This will be the driver name the kernel reports */
 #define DRIVER_NAME "vf610-adc"
@@ -170,6 +173,7 @@ struct vf610_adc {
 	u32 sample_freq_avail[5];
 
 	struct completion completion;
+	u16 buffer[2];
 };
 
 static const u32 vf610_hw_avgs[] = { 1, 4, 8, 16, 32 };
@@ -505,12 +509,22 @@ static const struct iio_chan_spec_ext_info vf610_ext_info[] = {
 	.info_mask_shared_by_type = BIT(IIO_CHAN_INFO_SCALE) |	\
 				BIT(IIO_CHAN_INFO_SAMP_FREQ),	\
 	.ext_info = vf610_ext_info,				\
+	.address = (_idx),				\
+	.scan_index = (_idx),			\
+	.scan_type.sign = 'u',			\
+	.scan_type.realbits = 12,		\
+	.scan_type.storagebits = 16,	\
 }
 
 #define VF610_ADC_TEMPERATURE_CHAN(_idx, _chan_type) {	\
 	.type = (_chan_type),	\
 	.channel = (_idx),		\
 	.info_mask_separate = BIT(IIO_CHAN_INFO_PROCESSED),	\
+	.address = (_idx),						\
+	.scan_index = (_idx),					\
+	.scan_type.sign = 'u',					\
+	.scan_type.realbits = 12,				\
+	.scan_type.storagebits = 16,			\
 }
 
 static const struct iio_chan_spec vf610_adc_iio_channels[] = {
@@ -531,6 +545,7 @@ static const struct iio_chan_spec vf610_adc_iio_channels[] = {
 	VF610_ADC_CHAN(14, IIO_VOLTAGE),
 	VF610_ADC_CHAN(15, IIO_VOLTAGE),
 	VF610_ADC_TEMPERATURE_CHAN(26, IIO_TEMP),
+	IIO_CHAN_SOFT_TIMESTAMP(32),
 	/* sentinel */
 };
 
@@ -559,13 +574,20 @@ static int vf610_adc_read_data(struct vf610_adc *info)
 
 static irqreturn_t vf610_adc_isr(int irq, void *dev_id)
 {
-	struct vf610_adc *info = (struct vf610_adc *)dev_id;
+	struct iio_dev *indio_dev = (struct iio_dev *)dev_id;
+	struct vf610_adc *info = iio_priv(indio_dev);
 	int coco;
 
 	coco = readl(info->regs + VF610_REG_ADC_HS);
 	if (coco & VF610_ADC_HS_COCO0) {
 		info->value = vf610_adc_read_data(info);
-		complete(&info->completion);
+		if (iio_buffer_enabled(indio_dev)) {
+			info->buffer[0] = info->value;
+			iio_push_to_buffers_with_timestamp(indio_dev,
+					info->buffer, iio_get_time_ns());
+			iio_trigger_notify_done(indio_dev->trig);
+		} else
+			complete(&info->completion);
 	}
 
 	return IRQ_HANDLED;
@@ -612,6 +634,9 @@ static int vf610_read_raw(struct iio_dev *indio_dev,
 	switch (mask) {
 	case IIO_CHAN_INFO_RAW:
 	case IIO_CHAN_INFO_PROCESSED:
+		if (iio_buffer_enabled(indio_dev))
+			return -EBUSY;
+
 		mutex_lock(&indio_dev->mlock);
 		reinit_completion(&info->completion);
 
@@ -694,6 +719,68 @@ static int vf610_write_raw(struct iio_dev *indio_dev,
 	return -EINVAL;
 }
 
+static int vf610_adc_buffer_postenable(struct iio_dev *indio_dev)
+{
+	struct vf610_adc *info = iio_priv(indio_dev);
+	unsigned int channel;
+	int ret;
+	int val;
+
+	ret = iio_triggered_buffer_postenable(indio_dev);
+	if (ret)
+		return ret;
+
+	val = readl(info->regs + VF610_REG_ADC_GC);
+	val |= VF610_ADC_ADCON;
+	writel(val, info->regs + VF610_REG_ADC_GC);
+
+	channel = find_first_bit(indio_dev->active_scan_mask,
+						indio_dev->masklength);
+
+	val = VF610_ADC_ADCHC(channel);
+	val |= VF610_ADC_AIEN;
+
+	writel(val, info->regs + VF610_REG_ADC_HC0);
+
+	return 0;
+}
+
+static int vf610_adc_buffer_postdisable(struct iio_dev *indio_dev)
+{
+	struct vf610_adc *info = iio_priv(indio_dev);
+	unsigned int hc_cfg = 0;
+	int val;
+
+	val = readl(info->regs + VF610_REG_ADC_GC);
+	val &= ~VF610_ADC_ADCON;
+	writel(val, info->regs + VF610_REG_ADC_GC);
+
+	hc_cfg |= VF610_ADC_CONV_DISABLE;
+	hc_cfg &= ~VF610_ADC_AIEN;
+
+	writel(hc_cfg, info->regs + VF610_REG_ADC_HC0);
+
+	return 0;
+}
+
+static const struct iio_buffer_setup_ops iio_triggered_buffer_setup_ops = {
+	.postenable = &vf610_adc_buffer_postenable,
+	.predisable = &iio_triggered_buffer_predisable,
+	.postdisable = &vf610_adc_buffer_postdisable,
+	.validate_scan_mask = &iio_validate_scan_mask_onehot,
+};
+
+static int vf610_adc_buffer_init(struct iio_dev *indio_dev)
+{
+	return iio_triggered_buffer_setup(indio_dev, &iio_pollfunc_store_time,
+		NULL, &iio_triggered_buffer_setup_ops);
+}
+
+static void vf610_adc_buffer_remove(struct iio_dev *indio_dev)
+{
+	iio_triggered_buffer_cleanup(indio_dev);
+}
+
 static int vf610_adc_reg_access(struct iio_dev *indio_dev,
 			unsigned reg, unsigned writeval,
 			unsigned *readval)
@@ -753,7 +840,7 @@ static int vf610_adc_probe(struct platform_device *pdev)
 
 	ret = devm_request_irq(info->dev, irq,
 				vf610_adc_isr, 0,
-				dev_name(&pdev->dev), info);
+				dev_name(&pdev->dev), indio_dev);
 	if (ret < 0) {
 		dev_err(&pdev->dev, "failed requesting irq, irq = %d\n", irq);
 		return ret;
@@ -806,15 +893,22 @@ static int vf610_adc_probe(struct platform_device *pdev)
 	vf610_adc_cfg_init(info);
 	vf610_adc_hw_init(info);
 
+	ret = vf610_adc_buffer_init(indio_dev);
+	if (ret < 0) {
+		dev_err(&pdev->dev, "Couldn't initialise the buffer\n");
+		goto error_iio_device_register;
+	}
+
 	ret = iio_device_register(indio_dev);
 	if (ret) {
 		dev_err(&pdev->dev, "Couldn't register the device.\n");
-		goto error_iio_device_register;
+		goto error_adc_buffer_init;
 	}
 
 	return 0;
 
-
+error_adc_buffer_init:
+	vf610_adc_buffer_remove(indio_dev);
 error_iio_device_register:
 	clk_disable_unprepare(info->clk);
 error_adc_clk_enable:
@@ -829,6 +923,7 @@ static int vf610_adc_remove(struct platform_device *pdev)
 	struct vf610_adc *info = iio_priv(indio_dev);
 
 	iio_device_unregister(indio_dev);
+	vf610_adc_buffer_remove(indio_dev);
 	regulator_disable(info->vref);
 	clk_disable_unprepare(info->clk);
 
-- 
2.5.0



From boris.ostrovsky at oracle.com  Wed Aug  5 05:19:32 2015
From: boris.ostrovsky at oracle.com (Boris Ostrovsky)
Date: Wed, 05 Aug 2015 08:19:32 -0400
Subject: [PATCH v2 4/8] xen: Use the correctly the Xen memory terminologies
In-Reply-To: <55C1EA95.5060504@citrix.com>
References: <1438711972-18752-1-git-send-email-julien.grall@citrix.com>
 <1438711972-18752-5-git-send-email-julien.grall@citrix.com>
 <55C147DD.7000600@oracle.com> <55C1EA95.5060504@citrix.com>
Message-ID: <55C1FF54.8060409@oracle.com>

On 08/05/2015 06:51 AM, Julien Grall wrote:
>
>>> diff --git a/drivers/video/fbdev/xen-fbfront.c
>>> b/drivers/video/fbdev/xen-fbfront.c
>>> index 09dc447..25e3cce 100644
>>> --- a/drivers/video/fbdev/xen-fbfront.c
>>> +++ b/drivers/video/fbdev/xen-fbfront.c
>>> @@ -539,7 +539,7 @@ static int xenfb_remove(struct xenbus_device *dev)
>>>      static unsigned long vmalloc_to_mfn(void *address)
>>>    {
>>> -    return pfn_to_mfn(vmalloc_to_pfn(address));
>>> +    return pfn_to_gfn(vmalloc_to_pfn(address));
>>>    }
>> Are you sure? This will return vmalloc_to_pfn(address)).
> I guess you mean vmalloc_to_mfn will return vmalloc_to_pfn?
>
> If so, it will be only the case on auto-translated case (because pfn ==
> gfn). In the case of PV, the mfn will be returned.

How will mfn be returned on PV when pfn_to_gfn() is an identity function?

static inline unsigned long pfn_to_gfn(unsigned long pfn)
  {
      return pfn;
  }


-boris

>
> Although, this function is misnamed. It's fixed in a follow-up patch
> (see #6) because it's required more renaming than this function. I
> didn't want to add such changes within this patch.
>
> Regards,
>



From tomeu.vizoso at collabora.com  Wed Aug  5 05:22:20 2015
From: tomeu.vizoso at collabora.com (Tomeu Vizoso)
Date: Wed,  5 Aug 2015 14:22:20 +0200
Subject: [PATCH] ARM: ux500: fix typo in regulator names
Message-ID: <1438777340-27511-1-git-send-email-tomeu.vizoso@collabora.com>

Apparently an extra _reg suffix was appended to the end of the names of
regulators ab8500_ext2_reg and ab8500_ext3_reg.

Signed-off-by: Tomeu Vizoso <tomeu.vizoso at collabora.com>
---
 arch/arm/boot/dts/ste-snowball.dts | 4 ++--
 1 file changed, 2 insertions(+), 2 deletions(-)

diff --git a/arch/arm/boot/dts/ste-snowball.dts b/arch/arm/boot/dts/ste-snowball.dts
index 32a5ccb14e7e..07c0e346942c 100644
--- a/arch/arm/boot/dts/ste-snowball.dts
+++ b/arch/arm/boot/dts/ste-snowball.dts
@@ -360,11 +360,11 @@
 						regulator-name = "ab8500-ext-supply1";
 					};
 
-					ab8500_ext2_reg_reg: ab8500_ext2 {
+					ab8500_ext2_reg: ab8500_ext2 {
 						regulator-name = "ab8500-ext-supply2";
 					};
 
-					ab8500_ext3_reg_reg: ab8500_ext3 {
+					ab8500_ext3_reg: ab8500_ext3 {
 						regulator-name = "ab8500-ext-supply3";
 					};
 				};
-- 
2.4.3



From julien.grall at citrix.com  Wed Aug  5 05:33:32 2015
From: julien.grall at citrix.com (Julien Grall)
Date: Wed, 5 Aug 2015 13:33:32 +0100
Subject: [Xen-devel] [PATCH v2 4/8] xen: Use the correctly the Xen memory
 terminologies
In-Reply-To: <55C1FF54.8060409@oracle.com>
References: <1438711972-18752-1-git-send-email-julien.grall@citrix.com>
 <1438711972-18752-5-git-send-email-julien.grall@citrix.com>
 <55C147DD.7000600@oracle.com> <55C1EA95.5060504@citrix.com>
 <55C1FF54.8060409@oracle.com>
Message-ID: <55C2029C.9030705@citrix.com>

On 05/08/15 13:19, Boris Ostrovsky wrote:
> On 08/05/2015 06:51 AM, Julien Grall wrote:
>>
>>>> diff --git a/drivers/video/fbdev/xen-fbfront.c
>>>> b/drivers/video/fbdev/xen-fbfront.c
>>>> index 09dc447..25e3cce 100644
>>>> --- a/drivers/video/fbdev/xen-fbfront.c
>>>> +++ b/drivers/video/fbdev/xen-fbfront.c
>>>> @@ -539,7 +539,7 @@ static int xenfb_remove(struct xenbus_device *dev)
>>>>      static unsigned long vmalloc_to_mfn(void *address)
>>>>    {
>>>> -    return pfn_to_mfn(vmalloc_to_pfn(address));
>>>> +    return pfn_to_gfn(vmalloc_to_pfn(address));
>>>>    }
>>> Are you sure? This will return vmalloc_to_pfn(address)).
>> I guess you mean vmalloc_to_mfn will return vmalloc_to_pfn?
>>
>> If so, it will be only the case on auto-translated case (because pfn ==
>> gfn). In the case of PV, the mfn will be returned.
> 
> How will mfn be returned on PV when pfn_to_gfn() is an identity function?
> 
> static inline unsigned long pfn_to_gfn(unsigned long pfn)
>  {
>      return pfn;
>  }

The identity function is only for ARM guest which are always
auto-translated (arch/arm/include/asm/xen/page.h).

The x86 version contains a check if the guest is auto-translated or not
(arch/x86/include/asm/xen/page.):

static inline unsigned long pfn_to_gfn(unsigned long pfn)
{
        if (xen_feature(XENFEAT_auto_translated_physmap))
                return pfn;
        else
                return pfn_to_mfn(pfn);
}

Regards,

-- 
Julien Grall


From hanjun.guo at linaro.org  Wed Aug  5 05:40:01 2015
From: hanjun.guo at linaro.org (Hanjun Guo)
Date: Wed, 05 Aug 2015 20:40:01 +0800
Subject: [PATCH v4 01/10] irqchip / GIC: Add GIC version support in ACPI
 MADT
In-Reply-To: <55C0AACA.9090001@arm.com>
References: <1438164539-29256-1-git-send-email-hanjun.guo@linaro.org>
 <1438164539-29256-2-git-send-email-hanjun.guo@linaro.org>
 <55C0AACA.9090001@arm.com>
Message-ID: <55C20421.7060708@linaro.org>

On 08/04/2015 08:06 PM, Marc Zyngier wrote:
> On 29/07/15 11:08, Hanjun Guo wrote:
>> There is a field added in ACPI 6.0 MADT table to indicate the
>> GIC version, so parse the table to get its value for later use.
>>
>> If GIC version presented in MADT is 0, we need to fallback to
>> hardware discovery to get the GIC version.
>>
>> In ACPI MADT table there is no compatible strings to indicate
>> various irqchips and also ACPI doesn't support irqchips which
>> are not compatible with ARM GIC spec, so GIC version can be used
>> to load different GIC drivers which is needed for the later patch.
>>
>> Signed-off-by: Hanjun Guo <hanjun.guo at linaro.org>
>> ---
>>   arch/arm64/Kconfig                   |   1 +
>>   drivers/irqchip/Kconfig              |   3 +
>>   drivers/irqchip/Makefile             |   1 +
>>   drivers/irqchip/irq-gic-acpi.c       | 109 +++++++++++++++++++++++++++++++++++
>>   include/linux/irqchip/arm-gic-acpi.h |   1 +
>>   5 files changed, 115 insertions(+)
>>   create mode 100644 drivers/irqchip/irq-gic-acpi.c
>>
>> diff --git a/arch/arm64/Kconfig b/arch/arm64/Kconfig
>> index 318175f..f2ff61f 100644
>> --- a/arch/arm64/Kconfig
>> +++ b/arch/arm64/Kconfig
>> @@ -16,6 +16,7 @@ config ARM64
>>   	select ARM_AMBA
>>   	select ARM_ARCH_TIMER
>>   	select ARM_GIC
>> +	select ARM_GIC_ACPI if ACPI
>>   	select AUDIT_ARCH_COMPAT_GENERIC
>>   	select ARM_GIC_V2M if PCI_MSI
>>   	select ARM_GIC_V3
>> diff --git a/drivers/irqchip/Kconfig b/drivers/irqchip/Kconfig
>> index 120d815..557ec2f 100644
>> --- a/drivers/irqchip/Kconfig
>> +++ b/drivers/irqchip/Kconfig
>> @@ -47,6 +47,9 @@ config ARM_VIC_NR
>>   	  The maximum number of VICs available in the system, for
>>   	  power management.
>>
>> +config ARM_GIC_ACPI
>> +	bool
>> +
>>   config ATMEL_AIC_IRQ
>>   	bool
>>   	select GENERIC_IRQ_CHIP
>> diff --git a/drivers/irqchip/Makefile b/drivers/irqchip/Makefile
>> index 11d08c9..383f421 100644
>> --- a/drivers/irqchip/Makefile
>> +++ b/drivers/irqchip/Makefile
>> @@ -23,6 +23,7 @@ obj-$(CONFIG_ARM_GIC)			+= irq-gic.o irq-gic-common.o
>>   obj-$(CONFIG_ARM_GIC_V2M)		+= irq-gic-v2m.o
>>   obj-$(CONFIG_ARM_GIC_V3)		+= irq-gic-v3.o irq-gic-common.o
>>   obj-$(CONFIG_ARM_GIC_V3_ITS)		+= irq-gic-v3-its.o irq-gic-v3-its-pci-msi.o irq-gic-v3-its-platform-msi.o
>> +obj-$(CONFIG_ARM_GIC_ACPI)		+= irq-gic-acpi.o
>>   obj-$(CONFIG_ARM_NVIC)			+= irq-nvic.o
>>   obj-$(CONFIG_ARM_VIC)			+= irq-vic.o
>>   obj-$(CONFIG_ATMEL_AIC_IRQ)		+= irq-atmel-aic-common.o irq-atmel-aic.o
>> diff --git a/drivers/irqchip/irq-gic-acpi.c b/drivers/irqchip/irq-gic-acpi.c
>> new file mode 100644
>> index 0000000..6537b43
>> --- /dev/null
>> +++ b/drivers/irqchip/irq-gic-acpi.c
>> @@ -0,0 +1,109 @@
>> +/*
>> + * ACPI based support for ARM GIC init
>> + *
>> + * Copyright (C) 2015, Linaro Ltd.
>> + * 	Author: Hanjun Guo <hanjun.guo at linaro.org>
>> + *
>> + * This program is free software; you can redistribute it and/or modify
>> + * it under the terms of the GNU General Public License version 2 as
>> + * published by the Free Software Foundation.
>> + */
>> +
>> +#define pr_fmt(fmt) "ACPI: GIC: " fmt
>> +
>> +#include <linux/acpi.h>
>> +#include <linux/init.h>
>> +#include <linux/irqchip/arm-gic-acpi.h>
>> +#include <linux/irqchip/arm-gic-v3.h>
>> +
>> +/* GIC version presented in MADT GIC distributor structure */
>> +static u8 gic_version __initdata = ACPI_MADT_GIC_VERSION_NONE;
>> +
>> +static phys_addr_t dist_phy_base __initdata;
>> +
>> +static int __init
>> +acpi_gic_parse_distributor(struct acpi_subtable_header *header,
>> +			   const unsigned long end)
>> +{
>> +	struct acpi_madt_generic_distributor *dist;
>> +
>> +	dist = (struct acpi_madt_generic_distributor *)header;
>> +
>> +	if (BAD_MADT_ENTRY(dist, end))
>> +		return -EINVAL;
>> +
>> +	gic_version = dist->version;
>> +	dist_phy_base = dist->base_address;
>> +	return 0;
>> +}
>> +
>> +static int __init
>> +match_gic_redist(struct acpi_subtable_header *header, const unsigned long end)
>> +{
>> +	return 0;
>> +}
>> +
>> +static bool __init acpi_gic_redist_is_present(void)
>> +{
>> +	int count;
>> +
>> +	/* scan MADT table to find if we have redistributor entries */
>> +	count  =  acpi_table_parse_madt(ACPI_MADT_TYPE_GENERIC_REDISTRIBUTOR,
>> +					match_gic_redist, 0);
>> +
>> +	/* that's true if we have at least one GIC redistributor entry */
>> +	return count > 0;
>> +}
>> +
>> +static int __init acpi_gic_version_init(void)
>> +{
>> +	int count;
>> +	u32 reg;
>> +	void __iomem *dist_base;
>> +
>> +	count = acpi_table_parse_madt(ACPI_MADT_TYPE_GENERIC_DISTRIBUTOR,
>> +				      acpi_gic_parse_distributor, 0);
>> +
>> +	if (count <= 0) {
>> +		pr_err("No valid GIC distributor entry exists\n");
>> +		return -ENODEV;
>> +	}
>> +
>> +	if (gic_version >= ACPI_MADT_GIC_VERSION_RESERVED) {
>> +		pr_err("Invalid GIC version %d in MADT\n", gic_version);
>> +		return -EINVAL;
>> +	}
>> +
>> +	/*
>> +	 * when the GIC version is 0, we fallback to hardware discovery.
>> +	 * this is also needed to keep compatiable with ACPI 5.1,
>> +	 * which has no gic_version field in distributor structure and
>> +	 * reserved as 0.
>> +	 *
>> +	 * For hardware discovery, the offset for GICv1/2 and GICv3/4 to
>> +	 * get the GIC version is different (0xFE8 for GICv1/2 and 0xFFE8
>> +	 * for GICv3/4), so we need to handle it separately.
>> +	 */
>> +	if (gic_version	== ACPI_MADT_GIC_VERSION_NONE) {
>> +		/* it's GICv3/v4 if redistributor is present */
>> +		if (acpi_gic_redist_is_present()) {
>> +			dist_base = ioremap(dist_phy_base,
>> +					    ACPI_GICV3_DIST_MEM_SIZE);
>> +			if (!dist_base)
>> +				return -ENOMEM;
>> +
>> +			reg = readl_relaxed(dist_base + GICD_PIDR2) &
>> +					    GIC_PIDR2_ARCH_MASK;
>> +			if (reg == GIC_PIDR2_ARCH_GICv3)
>> +				gic_version = ACPI_MADT_GIC_VERSION_V3;
>> +			else
>> +				gic_version = ACPI_MADT_GIC_VERSION_V4;
>
> Frankly, why should we care? If there is no redistributor, this is a V2.
> If there are redistributors, then it is a V3/V4, and it shouldn't matter
> which one this is as the GICv3 driver can find out all by itself. Also,
> the GICv4 feature only matter for KVM, which can probe this on its own.

For hardware discovery, it works.

I use the gic_version in later patch to ioremap physical base address of
GICR (which 2 or 4 64k pages), but I can get it from register in later
patch then remove the code above.

For gic version in GICD subtable, we must consider V4 as firmware may
just present ACPI_MADT_GIC_VERSION_V4 as the GIC version, that's why
we need to match V4 in the GICv3 driver.

Thanks
Hanjun


From hramrach at gmail.com  Wed Aug  5 05:40:01 2015
From: hramrach at gmail.com (Michal Suchanek)
Date: Wed, 5 Aug 2015 14:40:01 +0200
Subject: [RFC PATCH 1/5] spi: introduce flag for memory mapped read
In-Reply-To: <20150805115013.GJ20873@sirena.org.uk>
References: <1438072876-16338-1-git-send-email-vigneshr@ti.com>
 <1438072876-16338-2-git-send-email-vigneshr@ti.com>
 <20150731181745.GM20873@sirena.org.uk>
 <55BEF4AF.5090704@ti.com> <20150804155148.GR20873@sirena.org.uk>
 <55C0FD98.1090107@ti.com> <20150805115013.GJ20873@sirena.org.uk>
Message-ID: <CAOMqctQXwcHyiWBwtugSDSE_k65qrNfrwnhjQMDJkLoJMmGzUw@mail.gmail.com>

On 5 August 2015 at 13:50, Mark Brown <broonie at kernel.org> wrote:
> On Tue, Aug 04, 2015 at 11:29:52PM +0530, R, Vignesh wrote:
>> On 8/4/2015 9:21 PM, Mark Brown wrote:
>> > On Mon, Aug 03, 2015 at 10:27:19AM +0530, Vignesh R wrote:
>
>> > I still can't tell from the above what this interface is supposed to do.
>> > It sounds like the use of memory mapped mode is supposed to be
>> > transparent to users, it should just affect how the controller interacts
>> > with the hardware, but if that's the case why do we need to expose it to
>> > users at all?  Shouldn't the driver just use memory mapped mode if it's
>> > faster?
>
>> 2. SFI_MM_IF(SPI memory mapped interface): The SFI_MM_IF block only
>> allows reading and writing to an SPI flash device only. Used to speed up
>> flash reads. It _cannot_ be used to communicate with non flash devices.
>> Now, the spi_message that ti-qspi receives in transfer_one() callback
>> can be from mtd device(in which case SFI_MM_IF can be used) or from any
>> other non flash SPI device (in which case SFI_MM_IF must not be used
>> instead SPI_CORE is to be used) but there is no way(is there?) to
>> distinguish where spi_message is from. Therefore I introduced flag
>> (use_mmap_mode) to struct spi_message. mtd driver will set flag to true,
>> this helps the ti-qspi driver to determine that the user is flash device
>> and thus can do read via SFI_MM_IF. If this flag is not set then the
>> user is assumed to be non flash SPI driver and will use SPI_CORE block
>> to communicate.
>
> So if you're trying to do this you need to document it adequately so
> that other people can understand what it is supposed to do and how to
> use and implement it.  People can't really tell how the interface is
> supposed to work based on what was in the patch and the above isn't
> really helping.  For example, how does this change or restrict what the
> contents of the spi_message are?
>
>> On the whole, I just need a way to determine that the user is a flash
>> device in order to switch to memory mapped interface.
>
> As far as I can tell you want to set a per spi_message flag saying that
> the message is a flash read command?  If that's what this is trying to
> do then why do you need to set the flag at all?  If the message is in a
> clearly defined format and it's more efficient to use this mmap mode
> then surely the driver can just recognise that the format is approprate
> and switch into mmap mode without being explicitly told - I'm not clear
> what the flag adds here.

ehm, the read command is just one byte.

I don't think sending 03 or other random byte as the first byte of a
SPI transfer can be used as reliable detection that we are talking to
a SPI flash memory.

Thanks

Michal


From vaibhav.hiremath at linaro.org  Wed Aug  5 05:42:09 2015
From: vaibhav.hiremath at linaro.org (Vaibhav Hiremath)
Date: Wed, 05 Aug 2015 18:12:09 +0530
Subject: [PATCH-v5 2/5] i2c: pxa: enable/disable i2c module across msg xfer
In-Reply-To: <CAKfKVtGzDjgHzy70aa0d2W=ROMcxVzerg-qpuB9e4PaGKPpMTQ@mail.gmail.com>
References: <1437482466-16126-1-git-send-email-vaibhav.hiremath@linaro.org>	<1437482466-16126-3-git-send-email-vaibhav.hiremath@linaro.org>
 <CAKfKVtGzDjgHzy70aa0d2W=ROMcxVzerg-qpuB9e4PaGKPpMTQ@mail.gmail.com>
Message-ID: <55C204A1.3060206@linaro.org>



On Wednesday 05 August 2015 04:16 PM, Shubhrajyoti Datta wrote:
> hi ,
> On Tue, Jul 21, 2015 at 6:11 PM, Vaibhav Hiremath
> <vaibhav.hiremath at linaro.org> wrote:
>> From: Yi Zhang <yizhang at marvell.com>
>>
>> Enable i2c module/unit before transmission and disable when it
>> finishes.
>>
>> why?
>> It's because the i2c bus may be disturbed if the slave device,
>> typically a touch, powers on.
>
> Why should that be an issue?
> Is it an errata.
>

Not I am aware of.

> In which mode it is an issue slave / master or both?
>

since it talks about touch, I expect it to be master mode.

Thanks,
Vaibhav


From broonie at kernel.org  Wed Aug  5 05:44:12 2015
From: broonie at kernel.org (Mark Brown)
Date: Wed, 5 Aug 2015 13:44:12 +0100
Subject: [RFC PATCH 1/5] spi: introduce flag for memory mapped read
In-Reply-To: <CAOMqctQXwcHyiWBwtugSDSE_k65qrNfrwnhjQMDJkLoJMmGzUw@mail.gmail.com>
References: <1438072876-16338-1-git-send-email-vigneshr@ti.com>
 <1438072876-16338-2-git-send-email-vigneshr@ti.com>
 <20150731181745.GM20873@sirena.org.uk> <55BEF4AF.5090704@ti.com>
 <20150804155148.GR20873@sirena.org.uk> <55C0FD98.1090107@ti.com>
 <20150805115013.GJ20873@sirena.org.uk>
 <CAOMqctQXwcHyiWBwtugSDSE_k65qrNfrwnhjQMDJkLoJMmGzUw@mail.gmail.com>
Message-ID: <20150805124412.GN20873@sirena.org.uk>

On Wed, Aug 05, 2015 at 02:40:01PM +0200, Michal Suchanek wrote:
> On 5 August 2015 at 13:50, Mark Brown <broonie at kernel.org> wrote:

> > As far as I can tell you want to set a per spi_message flag saying that
> > the message is a flash read command?  If that's what this is trying to
> > do then why do you need to set the flag at all?  If the message is in a
> > clearly defined format and it's more efficient to use this mmap mode
> > then surely the driver can just recognise that the format is approprate
> > and switch into mmap mode without being explicitly told - I'm not clear
> > what the flag adds here.

> ehm, the read command is just one byte.

> I don't think sending 03 or other random byte as the first byte of a
> SPI transfer can be used as reliable detection that we are talking to
> a SPI flash memory.

Why care - if something is physically in the same format as a flash read
command how would a device be able to tell that it wasn't actually a
flash read command?  The signals sent on the bus are going to be
identical anyway.
-------------- next part --------------
A non-text attachment was scrubbed...
Name: signature.asc
Type: application/pgp-signature
Size: 473 bytes
Desc: Digital signature
URL: <http://lists.infradead.org/pipermail/linux-arm-kernel/attachments/20150805/25ee6ec8/attachment.sig>

From boris.ostrovsky at oracle.com  Wed Aug  5 05:44:03 2015
From: boris.ostrovsky at oracle.com (Boris Ostrovsky)
Date: Wed, 05 Aug 2015 08:44:03 -0400
Subject: [Xen-devel] [PATCH v2 4/8] xen: Use the correctly the Xen memory
 terminologies
In-Reply-To: <55C2029C.9030705@citrix.com>
References: <1438711972-18752-1-git-send-email-julien.grall@citrix.com>	<1438711972-18752-5-git-send-email-julien.grall@citrix.com>	<55C147DD.7000600@oracle.com>
 <55C1EA95.5060504@citrix.com> <55C1FF54.8060409@oracle.com>
 <55C2029C.9030705@citrix.com>
Message-ID: <55C20513.2070407@oracle.com>

On 08/05/2015 08:33 AM, Julien Grall wrote:
> On 05/08/15 13:19, Boris Ostrovsky wrote:
>> On 08/05/2015 06:51 AM, Julien Grall wrote:
>>>>> diff --git a/drivers/video/fbdev/xen-fbfront.c
>>>>> b/drivers/video/fbdev/xen-fbfront.c
>>>>> index 09dc447..25e3cce 100644
>>>>> --- a/drivers/video/fbdev/xen-fbfront.c
>>>>> +++ b/drivers/video/fbdev/xen-fbfront.c
>>>>> @@ -539,7 +539,7 @@ static int xenfb_remove(struct xenbus_device *dev)
>>>>>       static unsigned long vmalloc_to_mfn(void *address)
>>>>>     {
>>>>> -    return pfn_to_mfn(vmalloc_to_pfn(address));
>>>>> +    return pfn_to_gfn(vmalloc_to_pfn(address));
>>>>>     }
>>>> Are you sure? This will return vmalloc_to_pfn(address)).
>>> I guess you mean vmalloc_to_mfn will return vmalloc_to_pfn?
>>>
>>> If so, it will be only the case on auto-translated case (because pfn ==
>>> gfn). In the case of PV, the mfn will be returned.
>> How will mfn be returned on PV when pfn_to_gfn() is an identity function?
>>
>> static inline unsigned long pfn_to_gfn(unsigned long pfn)
>>   {
>>       return pfn;
>>   }
> The identity function is only for ARM guest which are always
> auto-translated (arch/arm/include/asm/xen/page.h).
>
> The x86 version contains a check if the guest is auto-translated or not
> (arch/x86/include/asm/xen/page.):
>
> static inline unsigned long pfn_to_gfn(unsigned long pfn)
> {
>          if (xen_feature(XENFEAT_auto_translated_physmap))
>                  return pfn;
>          else
>                  return pfn_to_mfn(pfn);
> }

Of course --- I was looking at the top of the patch and didn't realize 
it was ARM changes. Sorry for the noise.

-boris


From hramrach at gmail.com  Wed Aug  5 05:56:09 2015
From: hramrach at gmail.com (Michal Suchanek)
Date: Wed, 5 Aug 2015 14:56:09 +0200
Subject: [RFC PATCH 1/5] spi: introduce flag for memory mapped read
In-Reply-To: <20150805124412.GN20873@sirena.org.uk>
References: <1438072876-16338-1-git-send-email-vigneshr@ti.com>
 <1438072876-16338-2-git-send-email-vigneshr@ti.com>
 <20150731181745.GM20873@sirena.org.uk>
 <55BEF4AF.5090704@ti.com> <20150804155148.GR20873@sirena.org.uk>
 <55C0FD98.1090107@ti.com> <20150805115013.GJ20873@sirena.org.uk>
 <CAOMqctQXwcHyiWBwtugSDSE_k65qrNfrwnhjQMDJkLoJMmGzUw@mail.gmail.com>
 <20150805124412.GN20873@sirena.org.uk>
Message-ID: <CAOMqctS9Y5FxpUCCJew6+cnjH5iTvbzkH3g-8yrXs4OuS2pSGA@mail.gmail.com>

On 5 August 2015 at 14:44, Mark Brown <broonie at kernel.org> wrote:
> On Wed, Aug 05, 2015 at 02:40:01PM +0200, Michal Suchanek wrote:
>> On 5 August 2015 at 13:50, Mark Brown <broonie at kernel.org> wrote:
>
>> > As far as I can tell you want to set a per spi_message flag saying that
>> > the message is a flash read command?  If that's what this is trying to
>> > do then why do you need to set the flag at all?  If the message is in a
>> > clearly defined format and it's more efficient to use this mmap mode
>> > then surely the driver can just recognise that the format is approprate
>> > and switch into mmap mode without being explicitly told - I'm not clear
>> > what the flag adds here.
>
>> ehm, the read command is just one byte.
>
>> I don't think sending 03 or other random byte as the first byte of a
>> SPI transfer can be used as reliable detection that we are talking to
>> a SPI flash memory.
>
> Why care - if something is physically in the same format as a flash read
> command how would a device be able to tell that it wasn't actually a
> flash read command?  The signals sent on the bus are going to be
> identical anyway.

Not only must the command be the same but also the response must be tha same.

The flash chip responds by sending arbitrary amount of data. Given
that transfer_one gets only the part that sends the read command and
the part to do the actual read may or may not follow this is getting a
bit hairy. Add in dummy bytes due to fast-read lag and page write
wrap-around and you get something that you definitely do not want
unless you are really sure that there is a flash memory on the other
end of the wire.

Thanks

Michal


From shawnguo at kernel.org  Wed Aug  5 05:56:50 2015
From: shawnguo at kernel.org (Shawn Guo)
Date: Wed, 5 Aug 2015 20:56:50 +0800
Subject: [PATCH v2 2/4] ARM: imx6ul: add fec MAC refrence clock and phy
 fixup init
In-Reply-To: <1438068642-6876-3-git-send-email-b38611@freescale.com>
References: <1438068642-6876-1-git-send-email-b38611@freescale.com>
 <1438068642-6876-3-git-send-email-b38611@freescale.com>
Message-ID: <20150805125650.GL12927@tiger>

On Tue, Jul 28, 2015 at 03:30:40PM +0800, Fugang Duan wrote:
> Add FEC MAC refrence clock init.
> Add phy fixup init for i.MX6ul 14x14 evk board that installs KSZ8081 phy.
> For the phy, there needs extra phy fixup for MII and RMII mode.
> 
> Signed-off-by: Fugang Duan <b38611 at freescale.com>
> ---
>  arch/arm/mach-imx/mach-imx6ul.c | 43 +++++++++++++++++++++++++++++++++++++++++
>  1 file changed, 43 insertions(+)
> 
> diff --git a/arch/arm/mach-imx/mach-imx6ul.c b/arch/arm/mach-imx/mach-imx6ul.c
> index f206506..0d81152 100644
> --- a/arch/arm/mach-imx/mach-imx6ul.c
> +++ b/arch/arm/mach-imx/mach-imx6ul.c
> @@ -7,11 +7,53 @@
>   */
>  #include <linux/irqchip.h>
>  #include <linux/of_platform.h>
> +#include <linux/mfd/syscon.h>
> +#include <linux/mfd/syscon/imx6q-iomuxc-gpr.h>
> +#include <linux/micrel_phy.h>

'm' should go above 'o', right?  I fixed the ordering and applied the
whole series.

Shawn

> +#include <linux/phy.h>
> +#include <linux/regmap.h>
>  #include <asm/mach/arch.h>
>  #include <asm/mach/map.h>
>  
>  #include "common.h"
>  
> +static void __init imx6ul_enet_clk_init(void)
> +{
> +	struct regmap *gpr;
> +
> +	gpr = syscon_regmap_lookup_by_compatible("fsl,imx6ul-iomuxc-gpr");
> +	if (!IS_ERR(gpr))
> +		regmap_update_bits(gpr, IOMUXC_GPR1, IMX6UL_GPR1_ENET_CLK_DIR,
> +				   IMX6UL_GPR1_ENET_CLK_OUTPUT);
> +	else
> +		pr_err("failed to find fsl,imx6ul-iomux-gpr regmap\n");
> +
> +}
> +
> +static int ksz8081_phy_fixup(struct phy_device *dev)
> +{
> +	if (dev && dev->interface == PHY_INTERFACE_MODE_MII) {
> +		phy_write(dev, 0x1f, 0x8110);
> +		phy_write(dev, 0x16, 0x201);
> +	} else if (dev && dev->interface == PHY_INTERFACE_MODE_RMII) {
> +		phy_write(dev, 0x1f, 0x8190);
> +		phy_write(dev, 0x16, 0x202);
> +	}
> +
> +	return 0;
> +}
> +
> +static void __init imx6ul_enet_phy_init(void)
> +{
> +	phy_register_fixup_for_uid(PHY_ID_KSZ8081, 0xffffffff, ksz8081_phy_fixup);
> +}
> +
> +static inline void imx6ul_enet_init(void)
> +{
> +	imx6ul_enet_clk_init();
> +	imx6ul_enet_phy_init();
> +}
> +
>  static void __init imx6ul_init_machine(void)
>  {
>  	struct device *parent;
> @@ -21,6 +63,7 @@ static void __init imx6ul_init_machine(void)
>  		pr_warn("failed to initialize soc device\n");
>  
>  	of_platform_populate(NULL, of_default_bus_match_table, NULL, NULL);
> +	imx6ul_enet_init();
>  	imx_anatop_init();
>  }
>  
> -- 
> 1.9.1
> 
> 
> _______________________________________________
> linux-arm-kernel mailing list
> linux-arm-kernel at lists.infradead.org
> http://lists.infradead.org/mailman/listinfo/linux-arm-kernel
> 


From marc.zyngier at arm.com  Wed Aug  5 05:57:14 2015
From: marc.zyngier at arm.com (Marc Zyngier)
Date: Wed, 05 Aug 2015 13:57:14 +0100
Subject: [PATCH v4 01/10] irqchip / GIC: Add GIC version support in ACPI
 MADT
In-Reply-To: <55C20421.7060708@linaro.org>
References: <1438164539-29256-1-git-send-email-hanjun.guo@linaro.org>
 <1438164539-29256-2-git-send-email-hanjun.guo@linaro.org>
 <55C0AACA.9090001@arm.com> <55C20421.7060708@linaro.org>
Message-ID: <55C2082A.7000508@arm.com>

On 05/08/15 13:40, Hanjun Guo wrote:
> On 08/04/2015 08:06 PM, Marc Zyngier wrote:
>> On 29/07/15 11:08, Hanjun Guo wrote:
>>> There is a field added in ACPI 6.0 MADT table to indicate the
>>> GIC version, so parse the table to get its value for later use.
>>>
>>> If GIC version presented in MADT is 0, we need to fallback to
>>> hardware discovery to get the GIC version.
>>>
>>> In ACPI MADT table there is no compatible strings to indicate
>>> various irqchips and also ACPI doesn't support irqchips which
>>> are not compatible with ARM GIC spec, so GIC version can be used
>>> to load different GIC drivers which is needed for the later patch.
>>>
>>> Signed-off-by: Hanjun Guo <hanjun.guo at linaro.org>
>>> ---
>>>   arch/arm64/Kconfig                   |   1 +
>>>   drivers/irqchip/Kconfig              |   3 +
>>>   drivers/irqchip/Makefile             |   1 +
>>>   drivers/irqchip/irq-gic-acpi.c       | 109 +++++++++++++++++++++++++++++++++++
>>>   include/linux/irqchip/arm-gic-acpi.h |   1 +
>>>   5 files changed, 115 insertions(+)
>>>   create mode 100644 drivers/irqchip/irq-gic-acpi.c
>>>
>>> diff --git a/arch/arm64/Kconfig b/arch/arm64/Kconfig
>>> index 318175f..f2ff61f 100644
>>> --- a/arch/arm64/Kconfig
>>> +++ b/arch/arm64/Kconfig
>>> @@ -16,6 +16,7 @@ config ARM64
>>>   	select ARM_AMBA
>>>   	select ARM_ARCH_TIMER
>>>   	select ARM_GIC
>>> +	select ARM_GIC_ACPI if ACPI
>>>   	select AUDIT_ARCH_COMPAT_GENERIC
>>>   	select ARM_GIC_V2M if PCI_MSI
>>>   	select ARM_GIC_V3
>>> diff --git a/drivers/irqchip/Kconfig b/drivers/irqchip/Kconfig
>>> index 120d815..557ec2f 100644
>>> --- a/drivers/irqchip/Kconfig
>>> +++ b/drivers/irqchip/Kconfig
>>> @@ -47,6 +47,9 @@ config ARM_VIC_NR
>>>   	  The maximum number of VICs available in the system, for
>>>   	  power management.
>>>
>>> +config ARM_GIC_ACPI
>>> +	bool
>>> +
>>>   config ATMEL_AIC_IRQ
>>>   	bool
>>>   	select GENERIC_IRQ_CHIP
>>> diff --git a/drivers/irqchip/Makefile b/drivers/irqchip/Makefile
>>> index 11d08c9..383f421 100644
>>> --- a/drivers/irqchip/Makefile
>>> +++ b/drivers/irqchip/Makefile
>>> @@ -23,6 +23,7 @@ obj-$(CONFIG_ARM_GIC)			+= irq-gic.o irq-gic-common.o
>>>   obj-$(CONFIG_ARM_GIC_V2M)		+= irq-gic-v2m.o
>>>   obj-$(CONFIG_ARM_GIC_V3)		+= irq-gic-v3.o irq-gic-common.o
>>>   obj-$(CONFIG_ARM_GIC_V3_ITS)		+= irq-gic-v3-its.o irq-gic-v3-its-pci-msi.o irq-gic-v3-its-platform-msi.o
>>> +obj-$(CONFIG_ARM_GIC_ACPI)		+= irq-gic-acpi.o
>>>   obj-$(CONFIG_ARM_NVIC)			+= irq-nvic.o
>>>   obj-$(CONFIG_ARM_VIC)			+= irq-vic.o
>>>   obj-$(CONFIG_ATMEL_AIC_IRQ)		+= irq-atmel-aic-common.o irq-atmel-aic.o
>>> diff --git a/drivers/irqchip/irq-gic-acpi.c b/drivers/irqchip/irq-gic-acpi.c
>>> new file mode 100644
>>> index 0000000..6537b43
>>> --- /dev/null
>>> +++ b/drivers/irqchip/irq-gic-acpi.c
>>> @@ -0,0 +1,109 @@
>>> +/*
>>> + * ACPI based support for ARM GIC init
>>> + *
>>> + * Copyright (C) 2015, Linaro Ltd.
>>> + * 	Author: Hanjun Guo <hanjun.guo at linaro.org>
>>> + *
>>> + * This program is free software; you can redistribute it and/or modify
>>> + * it under the terms of the GNU General Public License version 2 as
>>> + * published by the Free Software Foundation.
>>> + */
>>> +
>>> +#define pr_fmt(fmt) "ACPI: GIC: " fmt
>>> +
>>> +#include <linux/acpi.h>
>>> +#include <linux/init.h>
>>> +#include <linux/irqchip/arm-gic-acpi.h>
>>> +#include <linux/irqchip/arm-gic-v3.h>
>>> +
>>> +/* GIC version presented in MADT GIC distributor structure */
>>> +static u8 gic_version __initdata = ACPI_MADT_GIC_VERSION_NONE;
>>> +
>>> +static phys_addr_t dist_phy_base __initdata;
>>> +
>>> +static int __init
>>> +acpi_gic_parse_distributor(struct acpi_subtable_header *header,
>>> +			   const unsigned long end)
>>> +{
>>> +	struct acpi_madt_generic_distributor *dist;
>>> +
>>> +	dist = (struct acpi_madt_generic_distributor *)header;
>>> +
>>> +	if (BAD_MADT_ENTRY(dist, end))
>>> +		return -EINVAL;
>>> +
>>> +	gic_version = dist->version;
>>> +	dist_phy_base = dist->base_address;
>>> +	return 0;
>>> +}
>>> +
>>> +static int __init
>>> +match_gic_redist(struct acpi_subtable_header *header, const unsigned long end)
>>> +{
>>> +	return 0;
>>> +}
>>> +
>>> +static bool __init acpi_gic_redist_is_present(void)
>>> +{
>>> +	int count;
>>> +
>>> +	/* scan MADT table to find if we have redistributor entries */
>>> +	count  =  acpi_table_parse_madt(ACPI_MADT_TYPE_GENERIC_REDISTRIBUTOR,
>>> +					match_gic_redist, 0);
>>> +
>>> +	/* that's true if we have at least one GIC redistributor entry */
>>> +	return count > 0;
>>> +}
>>> +
>>> +static int __init acpi_gic_version_init(void)
>>> +{
>>> +	int count;
>>> +	u32 reg;
>>> +	void __iomem *dist_base;
>>> +
>>> +	count = acpi_table_parse_madt(ACPI_MADT_TYPE_GENERIC_DISTRIBUTOR,
>>> +				      acpi_gic_parse_distributor, 0);
>>> +
>>> +	if (count <= 0) {
>>> +		pr_err("No valid GIC distributor entry exists\n");
>>> +		return -ENODEV;
>>> +	}
>>> +
>>> +	if (gic_version >= ACPI_MADT_GIC_VERSION_RESERVED) {
>>> +		pr_err("Invalid GIC version %d in MADT\n", gic_version);
>>> +		return -EINVAL;
>>> +	}
>>> +
>>> +	/*
>>> +	 * when the GIC version is 0, we fallback to hardware discovery.
>>> +	 * this is also needed to keep compatiable with ACPI 5.1,
>>> +	 * which has no gic_version field in distributor structure and
>>> +	 * reserved as 0.
>>> +	 *
>>> +	 * For hardware discovery, the offset for GICv1/2 and GICv3/4 to
>>> +	 * get the GIC version is different (0xFE8 for GICv1/2 and 0xFFE8
>>> +	 * for GICv3/4), so we need to handle it separately.
>>> +	 */
>>> +	if (gic_version	== ACPI_MADT_GIC_VERSION_NONE) {
>>> +		/* it's GICv3/v4 if redistributor is present */
>>> +		if (acpi_gic_redist_is_present()) {
>>> +			dist_base = ioremap(dist_phy_base,
>>> +					    ACPI_GICV3_DIST_MEM_SIZE);
>>> +			if (!dist_base)
>>> +				return -ENOMEM;
>>> +
>>> +			reg = readl_relaxed(dist_base + GICD_PIDR2) &
>>> +					    GIC_PIDR2_ARCH_MASK;
>>> +			if (reg == GIC_PIDR2_ARCH_GICv3)
>>> +				gic_version = ACPI_MADT_GIC_VERSION_V3;
>>> +			else
>>> +				gic_version = ACPI_MADT_GIC_VERSION_V4;
>>
>> Frankly, why should we care? If there is no redistributor, this is a V2.
>> If there are redistributors, then it is a V3/V4, and it shouldn't matter
>> which one this is as the GICv3 driver can find out all by itself. Also,
>> the GICv4 feature only matter for KVM, which can probe this on its own.
> 
> For hardware discovery, it works.
> 
> I use the gic_version in later patch to ioremap physical base address of
> GICR (which 2 or 4 64k pages), but I can get it from register in later
> patch then remove the code above.
> 
> For gic version in GICD subtable, we must consider V4 as firmware may
> just present ACPI_MADT_GIC_VERSION_V4 as the GIC version, that's why
> we need to match V4 in the GICv3 driver.

My point is: the GICv3 driver doesn't give a damn. At all. And it
shouldn't! The *only* difference is the size of the redistributor, and
this can be worked out *inside the GIC driver* by looking at:

- GICR_PIDR2.ArchRev (and not GICD_PIDR2)
- GICR_TYPER.VLPIS

Whatever the firmware says is absolutely irrelevant, and even if we
needed to override what the HW reports (because it is broken), we can
implement it as a quirk inside the driver itself, without any of this
ioremap dance that doesn't even do the right thing.

So to "we must consider V4", my answer is no. Certainly not at this
location.

Thanks,

	M.
-- 
Jazz is not dead. It just smells funny...


From shawnguo at kernel.org  Wed Aug  5 06:01:16 2015
From: shawnguo at kernel.org (Shawn Guo)
Date: Wed, 5 Aug 2015 21:01:16 +0800
Subject: [PATCH v3 1/2] watchdog: imx2_wdt: add external reset support
 via 'ext-reset-output' dt prop
In-Reply-To: <1438097230-2653-2-git-send-email-tharvey@gateworks.com>
References: <1433448960-9257-2-git-send-email-tharvey@gateworks.com>
 <1438097230-2653-1-git-send-email-tharvey@gateworks.com>
 <1438097230-2653-2-git-send-email-tharvey@gateworks.com>
Message-ID: <20150805130115.GM12927@tiger>

On Tue, Jul 28, 2015 at 08:27:09AM -0700, Tim Harvey wrote:
> The IMX6 watchdog supports assertion of a signal (WDOG_B) which
> can be pinmux'd to an external pin. This is typically used for boards that
> have PMIC's in control of the IMX6 power rails. In fact, failure to use
> such an external reset on boards with external PMIC's can result in various
> hangs due to the IMX6 not being fully reset [1] as well as the board failing
> to reset because its PMIC has not been reset to provide adequate voltage for
> the CPU when coming out of reset at 800Mhz.
> 
> This uses a new device-tree property 'ext-reset-output' to indicate the
> board has such a reset and to cause the watchdog to be configured to assert
> WDOG_B instead of an internal reset both on a watchdog timeout and in
> system_restart.
> 
> [1] http://lists.infradead.org/pipermail/linux-arm-kernel/2015-March/333689.html
> 
> Cc: Lucas Stach <l.stach at pengutronix.de>
> Signed-off-by: Tim Harvey <tharvey at gateworks.com>

Acked-by: Shawn Guo <shawnguo at kernel.org>


From hanjun.guo at linaro.org  Wed Aug  5 06:11:31 2015
From: hanjun.guo at linaro.org (Hanjun Guo)
Date: Wed, 05 Aug 2015 21:11:31 +0800
Subject: [PATCH v4 01/10] irqchip / GIC: Add GIC version support in ACPI
 MADT
In-Reply-To: <55C2082A.7000508@arm.com>
References: <1438164539-29256-1-git-send-email-hanjun.guo@linaro.org>
 <1438164539-29256-2-git-send-email-hanjun.guo@linaro.org>
 <55C0AACA.9090001@arm.com> <55C20421.7060708@linaro.org>
 <55C2082A.7000508@arm.com>
Message-ID: <55C20B83.10808@linaro.org>

On 08/05/2015 08:57 PM, Marc Zyngier wrote:
> On 05/08/15 13:40, Hanjun Guo wrote:
>> On 08/04/2015 08:06 PM, Marc Zyngier wrote:
>>> On 29/07/15 11:08, Hanjun Guo wrote:
>>>> There is a field added in ACPI 6.0 MADT table to indicate the
>>>> GIC version, so parse the table to get its value for later use.
>>>>
>>>> If GIC version presented in MADT is 0, we need to fallback to
>>>> hardware discovery to get the GIC version.
>>>>
>>>> In ACPI MADT table there is no compatible strings to indicate
>>>> various irqchips and also ACPI doesn't support irqchips which
>>>> are not compatible with ARM GIC spec, so GIC version can be used
>>>> to load different GIC drivers which is needed for the later patch.
>>>>
>>>> Signed-off-by: Hanjun Guo <hanjun.guo at linaro.org>
>>>> ---
>>>>    arch/arm64/Kconfig                   |   1 +
>>>>    drivers/irqchip/Kconfig              |   3 +
>>>>    drivers/irqchip/Makefile             |   1 +
>>>>    drivers/irqchip/irq-gic-acpi.c       | 109 +++++++++++++++++++++++++++++++++++
>>>>    include/linux/irqchip/arm-gic-acpi.h |   1 +
>>>>    5 files changed, 115 insertions(+)
>>>>    create mode 100644 drivers/irqchip/irq-gic-acpi.c
>>>>
>>>> diff --git a/arch/arm64/Kconfig b/arch/arm64/Kconfig
>>>> index 318175f..f2ff61f 100644
>>>> --- a/arch/arm64/Kconfig
>>>> +++ b/arch/arm64/Kconfig
>>>> @@ -16,6 +16,7 @@ config ARM64
>>>>    	select ARM_AMBA
>>>>    	select ARM_ARCH_TIMER
>>>>    	select ARM_GIC
>>>> +	select ARM_GIC_ACPI if ACPI
>>>>    	select AUDIT_ARCH_COMPAT_GENERIC
>>>>    	select ARM_GIC_V2M if PCI_MSI
>>>>    	select ARM_GIC_V3
>>>> diff --git a/drivers/irqchip/Kconfig b/drivers/irqchip/Kconfig
>>>> index 120d815..557ec2f 100644
>>>> --- a/drivers/irqchip/Kconfig
>>>> +++ b/drivers/irqchip/Kconfig
>>>> @@ -47,6 +47,9 @@ config ARM_VIC_NR
>>>>    	  The maximum number of VICs available in the system, for
>>>>    	  power management.
>>>>
>>>> +config ARM_GIC_ACPI
>>>> +	bool
>>>> +
>>>>    config ATMEL_AIC_IRQ
>>>>    	bool
>>>>    	select GENERIC_IRQ_CHIP
>>>> diff --git a/drivers/irqchip/Makefile b/drivers/irqchip/Makefile
>>>> index 11d08c9..383f421 100644
>>>> --- a/drivers/irqchip/Makefile
>>>> +++ b/drivers/irqchip/Makefile
>>>> @@ -23,6 +23,7 @@ obj-$(CONFIG_ARM_GIC)			+= irq-gic.o irq-gic-common.o
>>>>    obj-$(CONFIG_ARM_GIC_V2M)		+= irq-gic-v2m.o
>>>>    obj-$(CONFIG_ARM_GIC_V3)		+= irq-gic-v3.o irq-gic-common.o
>>>>    obj-$(CONFIG_ARM_GIC_V3_ITS)		+= irq-gic-v3-its.o irq-gic-v3-its-pci-msi.o irq-gic-v3-its-platform-msi.o
>>>> +obj-$(CONFIG_ARM_GIC_ACPI)		+= irq-gic-acpi.o
>>>>    obj-$(CONFIG_ARM_NVIC)			+= irq-nvic.o
>>>>    obj-$(CONFIG_ARM_VIC)			+= irq-vic.o
>>>>    obj-$(CONFIG_ATMEL_AIC_IRQ)		+= irq-atmel-aic-common.o irq-atmel-aic.o
>>>> diff --git a/drivers/irqchip/irq-gic-acpi.c b/drivers/irqchip/irq-gic-acpi.c
>>>> new file mode 100644
>>>> index 0000000..6537b43
>>>> --- /dev/null
>>>> +++ b/drivers/irqchip/irq-gic-acpi.c
>>>> @@ -0,0 +1,109 @@
>>>> +/*
>>>> + * ACPI based support for ARM GIC init
>>>> + *
>>>> + * Copyright (C) 2015, Linaro Ltd.
>>>> + * 	Author: Hanjun Guo <hanjun.guo at linaro.org>
>>>> + *
>>>> + * This program is free software; you can redistribute it and/or modify
>>>> + * it under the terms of the GNU General Public License version 2 as
>>>> + * published by the Free Software Foundation.
>>>> + */
>>>> +
>>>> +#define pr_fmt(fmt) "ACPI: GIC: " fmt
>>>> +
>>>> +#include <linux/acpi.h>
>>>> +#include <linux/init.h>
>>>> +#include <linux/irqchip/arm-gic-acpi.h>
>>>> +#include <linux/irqchip/arm-gic-v3.h>
>>>> +
>>>> +/* GIC version presented in MADT GIC distributor structure */
>>>> +static u8 gic_version __initdata = ACPI_MADT_GIC_VERSION_NONE;
>>>> +
>>>> +static phys_addr_t dist_phy_base __initdata;
>>>> +
>>>> +static int __init
>>>> +acpi_gic_parse_distributor(struct acpi_subtable_header *header,
>>>> +			   const unsigned long end)
>>>> +{
>>>> +	struct acpi_madt_generic_distributor *dist;
>>>> +
>>>> +	dist = (struct acpi_madt_generic_distributor *)header;
>>>> +
>>>> +	if (BAD_MADT_ENTRY(dist, end))
>>>> +		return -EINVAL;
>>>> +
>>>> +	gic_version = dist->version;
>>>> +	dist_phy_base = dist->base_address;
>>>> +	return 0;
>>>> +}
>>>> +
>>>> +static int __init
>>>> +match_gic_redist(struct acpi_subtable_header *header, const unsigned long end)
>>>> +{
>>>> +	return 0;
>>>> +}
>>>> +
>>>> +static bool __init acpi_gic_redist_is_present(void)
>>>> +{
>>>> +	int count;
>>>> +
>>>> +	/* scan MADT table to find if we have redistributor entries */
>>>> +	count  =  acpi_table_parse_madt(ACPI_MADT_TYPE_GENERIC_REDISTRIBUTOR,
>>>> +					match_gic_redist, 0);
>>>> +
>>>> +	/* that's true if we have at least one GIC redistributor entry */
>>>> +	return count > 0;
>>>> +}
>>>> +
>>>> +static int __init acpi_gic_version_init(void)
>>>> +{
>>>> +	int count;
>>>> +	u32 reg;
>>>> +	void __iomem *dist_base;
>>>> +
>>>> +	count = acpi_table_parse_madt(ACPI_MADT_TYPE_GENERIC_DISTRIBUTOR,
>>>> +				      acpi_gic_parse_distributor, 0);
>>>> +
>>>> +	if (count <= 0) {
>>>> +		pr_err("No valid GIC distributor entry exists\n");
>>>> +		return -ENODEV;
>>>> +	}
>>>> +
>>>> +	if (gic_version >= ACPI_MADT_GIC_VERSION_RESERVED) {
>>>> +		pr_err("Invalid GIC version %d in MADT\n", gic_version);
>>>> +		return -EINVAL;
>>>> +	}
>>>> +
>>>> +	/*
>>>> +	 * when the GIC version is 0, we fallback to hardware discovery.
>>>> +	 * this is also needed to keep compatiable with ACPI 5.1,
>>>> +	 * which has no gic_version field in distributor structure and
>>>> +	 * reserved as 0.
>>>> +	 *
>>>> +	 * For hardware discovery, the offset for GICv1/2 and GICv3/4 to
>>>> +	 * get the GIC version is different (0xFE8 for GICv1/2 and 0xFFE8
>>>> +	 * for GICv3/4), so we need to handle it separately.
>>>> +	 */
>>>> +	if (gic_version	== ACPI_MADT_GIC_VERSION_NONE) {
>>>> +		/* it's GICv3/v4 if redistributor is present */
>>>> +		if (acpi_gic_redist_is_present()) {
>>>> +			dist_base = ioremap(dist_phy_base,
>>>> +					    ACPI_GICV3_DIST_MEM_SIZE);
>>>> +			if (!dist_base)
>>>> +				return -ENOMEM;
>>>> +
>>>> +			reg = readl_relaxed(dist_base + GICD_PIDR2) &
>>>> +					    GIC_PIDR2_ARCH_MASK;
>>>> +			if (reg == GIC_PIDR2_ARCH_GICv3)
>>>> +				gic_version = ACPI_MADT_GIC_VERSION_V3;
>>>> +			else
>>>> +				gic_version = ACPI_MADT_GIC_VERSION_V4;
>>>
>>> Frankly, why should we care? If there is no redistributor, this is a V2.
>>> If there are redistributors, then it is a V3/V4, and it shouldn't matter
>>> which one this is as the GICv3 driver can find out all by itself. Also,
>>> the GICv4 feature only matter for KVM, which can probe this on its own.
>>
>> For hardware discovery, it works.
>>
>> I use the gic_version in later patch to ioremap physical base address of
>> GICR (which 2 or 4 64k pages), but I can get it from register in later
>> patch then remove the code above.
>>
>> For gic version in GICD subtable, we must consider V4 as firmware may
>> just present ACPI_MADT_GIC_VERSION_V4 as the GIC version, that's why
>> we need to match V4 in the GICv3 driver.
>
> My point is: the GICv3 driver doesn't give a damn. At all. And it
> shouldn't! The *only* difference is the size of the redistributor, and
> this can be worked out *inside the GIC driver* by looking at:
>
> - GICR_PIDR2.ArchRev (and not GICD_PIDR2)
> - GICR_TYPER.VLPIS
>
> Whatever the firmware says is absolutely irrelevant, and even if we
> needed to override what the HW reports (because it is broken), we can
> implement it as a quirk inside the driver itself, without any of this
> ioremap dance that doesn't even do the right thing.
>
> So to "we must consider V4", my answer is no. Certainly not at this
> location.

Sorry, I didn't make it clear. what I mean is that when GIC version
is presented as V4, we can match the GICv3 driver with it, and
everything will be the same in the driver itself.

Thanks
Hanjun


From hanjun.guo at linaro.org  Wed Aug  5 06:24:42 2015
From: hanjun.guo at linaro.org (Hanjun Guo)
Date: Wed, 05 Aug 2015 21:24:42 +0800
Subject: [PATCH v4 02/10] ACPI / irqchip: Add self-probe infrastructure
 to initialize IRQ controller
In-Reply-To: <55C0AFA2.8050704@arm.com>
References: <1438164539-29256-1-git-send-email-hanjun.guo@linaro.org>
 <1438164539-29256-3-git-send-email-hanjun.guo@linaro.org>
 <55C0AFA2.8050704@arm.com>
Message-ID: <55C20E9A.7000906@linaro.org>

Hi Marc,

On 08/04/2015 08:27 PM, Marc Zyngier wrote:
> On 29/07/15 11:08, Hanjun Guo wrote:
>> This self-probe infrastructure works in the similar way as OF,
>> but there is some different in the mechanism:
>>
>> For DT, the init fn will be called once it finds compatible strings
>> in DT,  but for ACPI, we init irqchips by static tables, and in
>> static ACPI tables, there are no compatible strings to indicate
>> irqchips, but thanks to the GIC version presented in ACPI table,
>> we can call the corresponding GIC drivers matching the GIC version
>> with this framework.
>>
>> This mechanism can also be used for clock declare and may also works
>> on x86 for some table parsing too.
>>
>> This patch is based on Tomasz Nowicki <tomasz.nowicki at linaro.org>'s
>> work.
>>
>> Signed-off-by: Hanjun Guo <hanjun.guo at linaro.org>
>> ---
>>   drivers/irqchip/irq-gic-acpi.c    | 33 +++++++++++++++++++++++++++++++++
>>   include/asm-generic/vmlinux.lds.h | 13 +++++++++++++
>>   include/linux/acpi.h              | 16 ++++++++++++++++
>>   include/linux/irqchip.h           | 13 +++++++++++++
>>   include/linux/mod_devicetable.h   |  8 ++++++++
>>   5 files changed, 83 insertions(+)
>>
>> diff --git a/drivers/irqchip/irq-gic-acpi.c b/drivers/irqchip/irq-gic-acpi.c
>> index 6537b43..011468d 100644
>> --- a/drivers/irqchip/irq-gic-acpi.c
>> +++ b/drivers/irqchip/irq-gic-acpi.c
>> @@ -107,3 +107,36 @@ static int __init acpi_gic_version_init(void)
>>
>>   	return 0;
>>   }
>> +
>> +/*
>> + * This special acpi_table_id is the sentinel at the end of the
>> + * acpi_table_id[] array of all irqchips. It is automatically placed at
>> + * the end of the array by the linker, thanks to being part of a
>> + * special section.
>> + */
>> +static const struct acpi_table_id
>> +irqchip_acpi_match_end __used __section(__irqchip_acpi_table_end);
>
> What is this thing for? Nobody refers to it (I know
> drivers/irqchip/irqchip.c has a similar thing, but that's not enough a
> reason...).

If I'm not mistaken, this is for proper section termination, please
see below:

/* scan the irqchip table to match the GIC version and its driver */
for (id = __irqchip_acpi_table; id->id[0]; id++) {
...
}

Then irqchip_acpi_match_end will be the end of the table section,
which will terminate the scanning.

>
>> +
>> +extern struct acpi_table_id __irqchip_acpi_table[];
>> +
>> +void __init acpi_irqchip_init(void)
>> +{
>> +	struct acpi_table_id *id;
>> +
>> +	if (acpi_disabled)
>> +		return;
>> +
>> +	if (acpi_gic_version_init())
>> +		return;
>
> This is the only place where we need the version, right? So just get
> acpi_gic_version_init to return the version number, and loose the global
> variable.

The global variable is still needed because we need to get the GIC
version when scanning the MADT tables, we can't return the table value
directly in acpi_table_parse_madt() at now.

>
>> +
>> +	/* scan the irqchip table to match the GIC version and its driver */
>> +	for (id = __irqchip_acpi_table; id->id[0]; id++) {
>> +		if (gic_version == (u8)id->driver_data) {
>> +			acpi_table_parse(id->id,
>> +					 (acpi_tbl_table_handler)id->handler);
>> +			return;
>> +		}
>> +	}
>> +
>> +	pr_err("No matched driver GIC version %d\n", gic_version);
>> +}
>> diff --git a/include/asm-generic/vmlinux.lds.h b/include/asm-generic/vmlinux.lds.h
>> index 8bd374d..625776c 100644
>> --- a/include/asm-generic/vmlinux.lds.h
>> +++ b/include/asm-generic/vmlinux.lds.h
>> @@ -181,6 +181,18 @@
>>   #define CPUIDLE_METHOD_OF_TABLES() OF_TABLE(CONFIG_CPU_IDLE, cpuidle_method)
>>   #define EARLYCON_OF_TABLES()	OF_TABLE(CONFIG_SERIAL_EARLYCON, earlycon)
>>
>> +#ifdef CONFIG_ACPI
>> +#define ACPI_TABLE(name)						\
>> +	. = ALIGN(8);							\
>> +	VMLINUX_SYMBOL(__##name##_acpi_table) = .;			\
>> +	*(__##name##_acpi_table)					\
>> +	*(__##name##_acpi_table_end)
>> +
>> +#define IRQCHIP_ACPI_MATCH_TABLE()	ACPI_TABLE(irqchip)
>> +#else
>> +#define IRQCHIP_ACPI_MATCH_TABLE()
>> +#endif
>> +
>>   #define KERNEL_DTB()							\
>>   	STRUCT_ALIGN();							\
>>   	VMLINUX_SYMBOL(__dtb_start) = .;				\
>> @@ -516,6 +528,7 @@
>>   	CPUIDLE_METHOD_OF_TABLES()					\
>>   	KERNEL_DTB()							\
>>   	IRQCHIP_OF_MATCH_TABLE()					\
>> +	IRQCHIP_ACPI_MATCH_TABLE()					\
>>   	EARLYCON_TABLE()						\
>>   	EARLYCON_OF_TABLES()
>>
>> diff --git a/include/linux/acpi.h b/include/linux/acpi.h
>> index 0820cb1..04dd0bb 100644
>> --- a/include/linux/acpi.h
>> +++ b/include/linux/acpi.h
>> @@ -829,4 +829,20 @@ static inline struct acpi_device *acpi_get_next_child(struct device *dev,
>>
>>   #endif
>>
>> +#ifdef CONFIG_ACPI
>> +#define ACPI_DECLARE(table, name, table_id, data, fn)			\
>> +	static const struct acpi_table_id __acpi_table_##name		\
>> +		__used __section(__##table##_acpi_table)		\
>> +		 = { .id = table_id,					\
>> +		     .handler = (void *)fn,				\
>> +		     .driver_data = data }
>> +#else
>> +#define ACPI_DECLARE(table, name, table_id, data, fn)			\
>> +	static const struct acpi_table_id __acpi_table_##name		\
>> +		__attribute__((unused))					\
>> +		 = { .id = table_id,					\
>> +		     .handler = (void *)fn,				\
>> +		     .driver_data = data }
>> +#endif
>> +
>>   #endif	/*_LINUX_ACPI_H*/
>> diff --git a/include/linux/irqchip.h b/include/linux/irqchip.h
>> index 6388873..6b66d3e 100644
>> --- a/include/linux/irqchip.h
>> +++ b/include/linux/irqchip.h
>> @@ -11,6 +11,7 @@
>>   #ifndef _LINUX_IRQCHIP_H
>>   #define _LINUX_IRQCHIP_H
>>
>> +#include <linux/acpi.h>
>>   #include <linux/of.h>
>>
>>   /*
>> @@ -25,6 +26,18 @@
>>    */
>>   #define IRQCHIP_DECLARE(name, compat, fn) OF_DECLARE_2(irqchip, name, compat, fn)
>>
>> +/*
>> + * This macro must be used by the different ARM GIC drivers to declare
>> + * the association between their version and their initialization function.
>> + *
>> + * @name: name that must be unique accross all IRQCHIP_ACPI_DECLARE of the
>> + * same file.
>> + * @gic_version: version of GIC
>> + * @fn: initialization function
>> + */
>> +#define IRQCHIP_ACPI_DECLARE(name, gic_version, fn)	\
>> +	ACPI_DECLARE(irqchip, name, ACPI_SIG_MADT, gic_version, fn)
>
> I don't think this is the right approach. The MADT table has a *huge*
> number of possible subtables, and none of them is matched by the GIC
> version.
>
> What you *really* want is MADT -> GICD -> GIC type. Your ACPI_DECLARE
> macro doesn't reflect this at all (you've basically cloned OF, and
> that's clearly not good enough).
>
> This probably require an intermediate matching function, ending up with
> something like:
>
> #define IRQCHIP_ACPI_DECLARE(name, subtable, version, fn) \
> 	ACPI_DECLARE(irqchip, name, ACPI_SIG_MADT, match_madt_subtable,\
> 		subtable, version, fn)
>
> where match_madt_subtable is going to check that a given subtable is
> really suitable for a given irqchip. None of that should be GIC
> specific, really.

I'm little confused here, in the previous patch, the gic version is
stored, so we only need to match the GIC driver with the gic version.

In the GIC dirver itself, we will match the madt subtable to find
information we need to init the GIC, so I'm not sure why
match_madt_subtable in the ACPI_DECLARE, I think I missed something,
please correct me.

Thanks
Hanjun


From hdegoede at redhat.com  Wed Aug  5 06:30:36 2015
From: hdegoede at redhat.com (Hans de Goede)
Date: Wed, 5 Aug 2015 15:30:36 +0200
Subject: [PATCH] musb: sunxi: Ignore VBus errors in host-only mode
In-Reply-To: <20150804225722.GA6802@saruman.tx.rr.com>
References: <1438723553-4136-1-git-send-email-hdegoede@redhat.com>
 <20150804213553.GI9623@saruman.tx.rr.com> <55C1370E.1000805@redhat.com>
 <20150804225722.GA6802@saruman.tx.rr.com>
Message-ID: <55C20FFC.4060808@redhat.com>

Hi,

On 05-08-15 00:57, Felipe Balbi wrote:
> Hi,
>
> On Wed, Aug 05, 2015 at 12:05:02AM +0200, Hans de Goede wrote:
>> Hi,
>>
>> On 08/04/2015 11:35 PM, Felipe Balbi wrote:
>>> On Tue, Aug 04, 2015 at 11:25:53PM +0200, Hans de Goede wrote:
>>>> For some unclear reason sometimes we get VBus errors in host-only mode,
>>>> even though we do not have any vbus-detection then. Ignore these.
>>>>
>>>> Signed-off-by: Hans de Goede <hdegoede at redhat.com>
>>>> ---
>>>>   drivers/usb/musb/sunxi.c | 4 ++++
>>>>   1 file changed, 4 insertions(+)
>>>>
>>>> diff --git a/drivers/usb/musb/sunxi.c b/drivers/usb/musb/sunxi.c
>>>> index f9f6304..34ce5df 100644
>>>> --- a/drivers/usb/musb/sunxi.c
>>>> +++ b/drivers/usb/musb/sunxi.c
>>>> @@ -194,6 +194,10 @@ static irqreturn_t sunxi_musb_interrupt(int irq, void *__hci)
>>>>   		musb_writeb(musb->mregs, MUSB_FADDR, 0);
>>>>   	}
>>>>
>>>> +	/*  Ignore Vbus errors when in host only mode */
>>>> +	if (musb->port_mode == MUSB_PORT_MODE_HOST)
>>>> +		musb->int_usb &= ~MUSB_INTR_VBUSERROR;
>>>
>>> check with a scope if VBUS is really dropping. Host does VBUS detection
>>> indeed, at a minimum, for overcurrent protection. You might have
>>> something causing VBUS to drop and that something needs to be found,
>>> rather than masked.
>>
>> The boards in question do not have any vbus detection, the usb-phy on
>> allwinner boards do not have a vbus sense pin, instead a gpio is used
>> in designs which use otg. Designs which use host-only mode typically
>> do not have any form of vbus detection at all. In this case we always
>> report vbus as being valid to the musb core, so I've no idea why
>> the musb core is still generating vbus errors.
>
> PHY must tell MUSB about VBUS level using either ULPI or UTMI+. I'd
> check to see if the PHY is at fault, at least.

Right, and the phy code has:

                 if (data->id_det_gpio) {
                         /* OTG mode, force ISCR and cable state updates */
                         data->id_det = -1;
                         data->vbus_det = -1;
                         queue_delayed_work(system_wq, &data->detect, 0);
                 } else {
                         /* Host only mode */
                         sun4i_usb_phy0_set_id_detect(_phy, 0);
                         sun4i_usb_phy0_set_vbus_detect(_phy, 1);
                 }

Where we enter the host only path (no id-pin in host only mode) and
then sun4i_usb_phy0_set_vbus_detect updates the ISCR register of
the phy to make it report vbus valid. I've done an mmio-dump of
the iscr register while running Linux, and this code does the right
thing.

I agree with you that this is weird, but atm I see no other way
to fix this then the submitted patch.

Regards,

Hans


>


From kishon at ti.com  Wed Aug  5 06:43:49 2015
From: kishon at ti.com (Kishon Vijay Abraham I)
Date: Wed, 5 Aug 2015 19:13:49 +0530
Subject: [PATCH] ARM: omap2plus_defconfig: make PCF857x built-in
Message-ID: <1438782229-25118-1-git-send-email-kishon@ti.com>

One of the lines from PCF857x is connected to the vdd line of MMC1
in DRA74x and DRA72x EVMs and is modelled as a regulator. If PCF857x
is not made as built-in, the regulator_get in omap_hsmmc fails making
it difficult to use MMC1 as rootfs.

Make PCF857x built-in.

Signed-off-by: Kishon Vijay Abraham I <kishon at ti.com>
Signed-off-by: Sekhar Nori <nsekhar at ti.com>
---
 arch/arm/configs/omap2plus_defconfig |    2 +-
 1 file changed, 1 insertion(+), 1 deletion(-)

diff --git a/arch/arm/configs/omap2plus_defconfig b/arch/arm/configs/omap2plus_defconfig
index ac521e7..7cedfe9 100644
--- a/arch/arm/configs/omap2plus_defconfig
+++ b/arch/arm/configs/omap2plus_defconfig
@@ -236,7 +236,7 @@ CONFIG_SSI_PROTOCOL=m
 CONFIG_PINCTRL_SINGLE=y
 CONFIG_DEBUG_GPIO=y
 CONFIG_GPIO_SYSFS=y
-CONFIG_GPIO_PCF857X=m
+CONFIG_GPIO_PCF857X=y
 CONFIG_GPIO_TWL4030=y
 CONFIG_GPIO_PALMAS=y
 CONFIG_W1=m
-- 
1.7.9.5



From shawnguo at kernel.org  Wed Aug  5 06:46:03 2015
From: shawnguo at kernel.org (Shawn Guo)
Date: Wed, 5 Aug 2015 21:46:03 +0800
Subject: [PATCH v5 2/2] ARM: dts: add property for maximum ADC clock
 frequencies
In-Reply-To: <f598169164aaacc28292d8ccc6afb32d@agner.ch>
References: <1432730872-14325-1-git-send-email-stefan@agner.ch>
 <1432730872-14325-3-git-send-email-stefan@agner.ch>
 <557477BE.5050108@kernel.org>
 <f598169164aaacc28292d8ccc6afb32d@agner.ch>
Message-ID: <20150805134603.GN12927@tiger>

On Mon, Aug 03, 2015 at 02:22:30PM +0200, Stefan Agner wrote:
> Hi Shawn,
> 
> I guess this will go through your tree? Haven't seen it appear on imx/dt
> so far...

Sorry.  I missed it.  Please use my kernel.org mailbox, which I'm using
for kernel maintenance now.

Applied, thanks.

Shawn

> 
> --
> Stefan
> 
> On 2015-06-07 18:56, Jonathan Cameron wrote:
> > On 27/05/15 13:47, Stefan Agner wrote:
> >> The ADC clock frequency is limited depending on modes used. Add
> >> device tree property which allow to set the mode used and the
> >> maximum frequency ratings for the instance. These allows to
> >> set the ADC clock to a frequency which is within specification
> >> according to the actual mode used.
> >>
> >> Acked-by: Fugang Duan <B38611 at freescale.com>
> >> Signed-off-by: Stefan Agner <stefan at agner.ch>
> > I'm happy to take this via IIO if people want me to, otherwise give
> > it's connection to the previous patch that I just applied,
> > 
> > Acked-by: Jonathan Cameron <jic23 at kernel.org>
> > 
> >> ---
> >>  arch/arm/boot/dts/vfxxx.dtsi | 4 ++++
> >>  1 file changed, 4 insertions(+)
> >>
> >> diff --git a/arch/arm/boot/dts/vfxxx.dtsi b/arch/arm/boot/dts/vfxxx.dtsi
> >> index a29c7ce..c6609bd 100644
> >> --- a/arch/arm/boot/dts/vfxxx.dtsi
> >> +++ b/arch/arm/boot/dts/vfxxx.dtsi
> >> @@ -189,6 +189,8 @@
> >>  				clocks = <&clks VF610_CLK_ADC0>;
> >>  				clock-names = "adc";
> >>  				status = "disabled";
> >> +				fsl,adck-max-frequency = <30000000>, <40000000>,
> >> +							<20000000>;
> >>  			};
> >>
> >>  			wdoga5: wdog at 4003e000 {
> >> @@ -387,6 +389,8 @@
> >>  				clocks = <&clks VF610_CLK_ADC1>;
> >>  				clock-names = "adc";
> >>  				status = "disabled";
> >> +				fsl,adck-max-frequency = <30000000>, <40000000>,
> >> +							<20000000>;
> >>  			};
> >>
> >>  			esdhc1: esdhc at 400b2000 {
> >>
> 
> 
> _______________________________________________
> linux-arm-kernel mailing list
> linux-arm-kernel at lists.infradead.org
> http://lists.infradead.org/mailman/listinfo/linux-arm-kernel
> 


From christoffer.dall at linaro.org  Wed Aug  5 06:47:54 2015
From: christoffer.dall at linaro.org (Christoffer Dall)
Date: Wed, 5 Aug 2015 15:47:54 +0200
Subject: [PATCH v3 09/11] KVM: arm/arm64: vgic: Prevent userspace
 injection of a mapped interrupt
In-Reply-To: <55C1F7CF.5070904@linaro.org>
References: <1437753309-17989-1-git-send-email-marc.zyngier@arm.com>
 <1437753309-17989-10-git-send-email-marc.zyngier@arm.com>
 <55C0E690.1090808@linaro.org> <55C0EBF5.2060708@arm.com>
 <55C1BBF9.2060004@linaro.org> <55C1DAE9.1050609@arm.com>
 <20150805105345.GA4657@cbox> <55C1F7CF.5070904@linaro.org>
Message-ID: <20150805134754.GB4657@cbox>

On Wed, Aug 05, 2015 at 01:47:27PM +0200, Eric Auger wrote:
> On 08/05/2015 12:53 PM, Christoffer Dall wrote:
> > On Wed, Aug 05, 2015 at 10:44:09AM +0100, Marc Zyngier wrote:
> >> On 05/08/15 08:32, Eric Auger wrote:
> >>> Hi Marc,
> >>> On 08/04/2015 06:44 PM, Marc Zyngier wrote:
> >>>> On 04/08/15 17:21, Eric Auger wrote:
> >>>>> Hi Marc,
> >>>>> On 07/24/2015 05:55 PM, Marc Zyngier wrote:
> >>>>>> Virtual interrupts mapped to a HW interrupt should only be triggered
> >>>>>> from inside the kernel. Otherwise, you could end up confusing the
> >>>>>> kernel (and the GIC's) state machine.
> >>>>>>
> >>>>>> Rearrange the injection path so that kvm_vgic_inject_irq is
> >>>>>> used for non-mapped interrupts, and kvm_vgic_inject_mapped_irq is
> >>>>>> used for mapped interrupts. The latter should only be called from
> >>>>>> inside the kernel (timer, VFIO).
> >>>>> nit: I would replace VFIO by irqfd.
> >>>>> VFIO just triggers the eventfd/irqfd. This is KVM/irqfd that injects the
> >>>>> virtual irq upon the irqfd signaling and he irqfd adaptation/ARM
> >>>>> currently is implemented in vgic.c
> >>>>
> >>>> Ah, thanks for reminding me of the right terminology, I tend to think of
> >>>> it as one big bag of nasty tricks... ;-)
> >>>>
> >>>> I'll update the commit message.
> >>>>
> >>>>>>
> >>>>>> Signed-off-by: Marc Zyngier <marc.zyngier at arm.com>
> >>>>>> ---
> >>>>>>  include/kvm/arm_vgic.h |  2 +
> >>>>>>  virt/kvm/arm/vgic.c    | 99 ++++++++++++++++++++++++++++++++++----------------
> >>>>>>  2 files changed, 70 insertions(+), 31 deletions(-)
> >>>>>>
> >>>>>> diff --git a/include/kvm/arm_vgic.h b/include/kvm/arm_vgic.h
> >>>>>> index 7306b4b..f6bfd79 100644
> >>>>>> --- a/include/kvm/arm_vgic.h
> >>>>>> +++ b/include/kvm/arm_vgic.h
> >>>>>> @@ -351,6 +351,8 @@ void kvm_vgic_flush_hwstate(struct kvm_vcpu *vcpu);
> >>>>>>  void kvm_vgic_sync_hwstate(struct kvm_vcpu *vcpu);
> >>>>>>  int kvm_vgic_inject_irq(struct kvm *kvm, int cpuid, unsigned int irq_num,
> >>>>>>  			bool level);
> >>>>>> +int kvm_vgic_inject_mapped_irq(struct kvm *kvm, int cpuid,
> >>>>>> +			       struct irq_phys_map *map, bool level);
> >>>>>>  void vgic_v3_dispatch_sgi(struct kvm_vcpu *vcpu, u64 reg);
> >>>>>>  int kvm_vgic_vcpu_pending_irq(struct kvm_vcpu *vcpu);
> >>>>>>  int kvm_vgic_vcpu_active_irq(struct kvm_vcpu *vcpu);
> >>>>>> diff --git a/virt/kvm/arm/vgic.c b/virt/kvm/arm/vgic.c
> >>>>>> index 3f7b690..e40ef70 100644
> >>>>>> --- a/virt/kvm/arm/vgic.c
> >>>>>> +++ b/virt/kvm/arm/vgic.c
> >>>>>> @@ -1533,7 +1533,8 @@ static int vgic_validate_injection(struct kvm_vcpu *vcpu, int irq, int level)
> >>>>>>  }
> >>>>>>  
> >>>>>>  static int vgic_update_irq_pending(struct kvm *kvm, int cpuid,
> >>>>>> -				  unsigned int irq_num, bool level)
> >>>>>> +				   struct irq_phys_map *map,
> >>>>>> +				   unsigned int irq_num, bool level)
> >>>>>>  {
> >>>>> In vgic_update_irq_pending, I needed to modify the following line and
> >>>>> add the "&& !map".
> >>>>>
> >>>>>         if (!vgic_validate_injection(vcpu, irq_num, level) && !map) {
> >>>>>
> >>>>> Without that, the level being not properly modeled for level sensitive
> >>>>> forwarded IRQs, the 2d injection fails.
> >>>>
> >>>> Ah! Is that because we never see the line being reset to zero, and the
> >>>> VGIC still sees the line as pending at the distributor level?
> >>> yes indeed
> >>
> >> Then it is a bigger problem we need to solve, and your solution just
> >> papers over the issue.
> >>
> >> The main problem is that irqfd is essentially an edge-triggered
> >> signalling. Fire and forget. Given that we're dealing with a level
> >> triggered interrupt, we end up with the interrupt still marked as
> >> pending (nobody took the signal down).
> this does not really relate to irqfd: irqfd also comes with the concept
> of resamplefd. in case the IRQ is not forwarded, this is the
> irqfd_resampler_ack function that toggles the IRQ down (eventfd.c). Its
> execution is triggered in vgic_process_maintenance. With forwarding the
> EOI is not trappable anymore so this disappears.
> 
> 
> >> The usual way to get out of that mess in is to evaluate the state of the
> >> level on EOI. But we can't trap on EOI for a HW interrupt.
> >>
> >> So it raises the question: should we instead consider the HW pending
> >> state instead of the software one for mapped interrupts? It is
> >> expensive, but it feels more correct.
> >>
> > I thought we already covered this at LCA.  For mapped interrupts
> > (forwarded) we should never consider the software pending state, because
> > that state is managed by the hardware.  Or am I confusing concepts here?
> 
> Yes we discussed we should bypass most of the SW states.
> 
> in my previous integration I proposed a patch "KVM: arm: vgic: fix state
> machine for forwarded IRQ". What's wrong with the below approach?
> 
> 
>     Fix multiple injection of level sensitive forwarded IRQs.
>     With current code, the second injection fails since the
>     state bitmaps are not reset (process_maintenance is not
>     called anymore).
> 
>     New implementation follows those principles:
>     - A forwarded IRQ only can be sampled when it is pending
>     - when queueing the IRQ (programming the LR), the pending state
>       is removed as for edge sensitive IRQs
>     - an injection of a forwarded IRQ is considered always valid since
>       coming from the HW and level always is 1.
> 
I don't see anything wrong, and I thought this was what we discussed.

-Christoffer


From hanjun.guo at linaro.org  Wed Aug  5 07:00:41 2015
From: hanjun.guo at linaro.org (Hanjun Guo)
Date: Wed, 05 Aug 2015 22:00:41 +0800
Subject: [PATCH v4 06/10] irqchip / GICv3: Add ACPI support for GICv3+
 initialization
In-Reply-To: <55C0BB5E.2080706@arm.com>
References: <1438164539-29256-1-git-send-email-hanjun.guo@linaro.org>
 <1438164539-29256-7-git-send-email-hanjun.guo@linaro.org>
 <55C0BB5E.2080706@arm.com>
Message-ID: <55C21709.3070907@linaro.org>

On 08/04/2015 09:17 PM, Marc Zyngier wrote:
> On 29/07/15 11:08, Hanjun Guo wrote:
>> From: Tomasz Nowicki <tomasz.nowicki at linaro.org>
>>
>> With the refator of gic_of_init(), GICv3/4 can be initialized
>> by gic_init_bases() with gic distributor base address and gic
>> redistributor region(s).
>>
>> So get the redistributor region base addresses from MADT GIC
>> redistributor subtable, and the distributor base address from
>> GICD subtable to init GICv3 irqchip in ACPI way.
>>
>> Note: GIC redistributor base address may also be provided in
>> GICC structures on systems supporting GICv3 and above if the GIC
>> Redistributors are not in the always-on power domain, this
>> patch didn't implement such feature yet.
>>
>> Signed-off-by: Tomasz Nowicki <tomasz.nowicki at linaro.org>
>> [hj: Rework this patch and fix multi issues]
>> Signed-off-by: Hanjun Guo <hanjun.guo at linaro.org>
>> ---
>>   drivers/irqchip/irq-gic-v3.c | 174 +++++++++++++++++++++++++++++++++++++++++--
>>   1 file changed, 169 insertions(+), 5 deletions(-)
>>
>> diff --git a/drivers/irqchip/irq-gic-v3.c b/drivers/irqchip/irq-gic-v3.c
>> index c0b96c6..ebc5604 100644
>> --- a/drivers/irqchip/irq-gic-v3.c
>> +++ b/drivers/irqchip/irq-gic-v3.c
>> @@ -15,6 +15,7 @@
>>    * along with this program.  If not, see <http://www.gnu.org/licenses/>.
>>    */
>>
>> +#include <linux/acpi.h>
>>   #include <linux/cpu.h>
>>   #include <linux/cpu_pm.h>
>>   #include <linux/delay.h>
>> @@ -25,6 +26,7 @@
>>   #include <linux/percpu.h>
>>   #include <linux/slab.h>
>>
>> +#include <linux/irqchip/arm-gic-acpi.h>
>>   #include <linux/irqchip/arm-gic-v3.h>
>>
>>   #include <asm/cputype.h>
>> @@ -802,7 +804,8 @@ static int __init gic_init_bases(void __iomem *dist_base,
>>   	set_handle_irq(gic_handle_irq);
>>
>>   	if (IS_ENABLED(CONFIG_ARM_GIC_V3_ITS) && gic_dist_supports_lpis())
>> -		its_init(domain_token, &gic_data.rdists, gic_data.domain);
>> +		its_init(irq_domain_token_to_of_node(domain_token),
>> +			 &gic_data.rdists, gic_data.domain);
>
> This doesn't make much sense. The first parameter to its_init is indeed
> supposed to be an of_node, but what is the point of calling its_init if
> you *know* you don't have the necessary topological information to parse
> the firmware tables?
>
> I don't see *any* code that is going to parse the ITS table in this
> series, so please don't call its_init passing a NULL pointer to it. This
> is just gross.

OK, the ITS ACPI code is in later patch which combined with IORT. How
about moving it to the GIC of init code temporary?

>
>>
>>   	gic_smp_init();
>>   	gic_dist_init();
>> @@ -818,6 +821,16 @@ out_free:
>>   	return err;
>>   }
>>
>> +static int __init detect_distributor(void __iomem *dist_base)
>
> We do have a naming convention in this file. All functions start with gic_.
>
>> +{
>> +	u32 reg = readl_relaxed(dist_base + GICD_PIDR2) & GIC_PIDR2_ARCH_MASK;
>> +
>> +	if (reg != GIC_PIDR2_ARCH_GICv3 && reg != GIC_PIDR2_ARCH_GICv4)
>> +		return -ENODEV;
>> +
>> +	return 0;
>> +}
>
> This function doesn't detect anything, it validates that we have
> something sensible. Please rename it to gic_validate_dist_version, or
> something similar.

Ok.

>
>> +
>>   #ifdef CONFIG_OF
>>   static int __init gic_of_init(struct device_node *node, struct device_node *parent)
>>   {
>> @@ -825,7 +838,6 @@ static int __init gic_of_init(struct device_node *node, struct device_node *pare
>>   	struct redist_region *rdist_regs;
>>   	u64 redist_stride;
>>   	u32 nr_redist_regions;
>> -	u32 reg;
>>   	int err, i;
>>
>>   	dist_base = of_iomap(node, 0);
>> @@ -835,11 +847,10 @@ static int __init gic_of_init(struct device_node *node, struct device_node *pare
>>   		return -ENXIO;
>>   	}
>>
>> -	reg = readl_relaxed(dist_base + GICD_PIDR2) & GIC_PIDR2_ARCH_MASK;
>> -	if (reg != GIC_PIDR2_ARCH_GICv3 && reg != GIC_PIDR2_ARCH_GICv4) {
>> +	err = detect_distributor(dist_base);
>> +	if (err) {
>>   		pr_err("%s: no distributor detected, giving up\n",
>>   			node->full_name);
>> -		err = -ENODEV;
>>   		goto out_unmap_dist;
>>   	}
>>
>> @@ -887,3 +898,156 @@ out_unmap_dist:
>>
>>   IRQCHIP_DECLARE(gic_v3, "arm,gic-v3", gic_of_init);
>>   #endif
>> +
>> +#ifdef CONFIG_ACPI
>> +static struct redist_region *redist_regs __initdata;
>> +static u32 nr_redist_regions __initdata;
>> +static phys_addr_t dist_phys_base __initdata;
>> +
>> +static int __init
>> +gic_acpi_register_redist(u64 phys_base, u64 size)
>
> A physical address must use phys_addr_t.

OK.

>
>> +{
>> +	struct redist_region *redist_regs_new;
>> +	void __iomem *redist_base;
>> +
>> +	redist_regs_new = krealloc(redist_regs,
>> +				   sizeof(*redist_regs) * (nr_redist_regions + 1),
>> +				   GFP_KERNEL);
>
> NAK. If you have multiple regions, you count them, you allocate the
> right number of regions. This will be far more efficient than doing this
> realloc dance. It is not like we're not parsing the tables a zillion
> times already. Doing it one more time won't hurt.

Agreed, will update in next version.

>
>> +	if (!redist_regs_new) {
>> +		pr_err("Couldn't allocate resource for GICR region\n");
>> +		return -ENOMEM;
>> +	}
>> +
>> +	redist_regs = redist_regs_new;
>> +
>> +	redist_base = ioremap(phys_base, size);
>> +	if (!redist_base) {
>> +		pr_err("Couldn't map GICR region @%llx\n", phys_base);
>> +		return -ENOMEM;
>> +	}
>> +
>> +	redist_regs[nr_redist_regions].phys_base = phys_base;
>> +	redist_regs[nr_redist_regions].redist_base = redist_base;
>> +	nr_redist_regions++;
>> +	return 0;
>> +}
>> +
>> +static int __init
>> +gic_acpi_parse_madt_redist(struct acpi_subtable_header *header,
>> +			const unsigned long end)
>> +{
>> +	struct acpi_madt_generic_redistributor *redist;
>> +
>> +	if (BAD_MADT_ENTRY(header, end))
>> +		return -EINVAL;
>> +
>> +	redist = (struct acpi_madt_generic_redistributor *)header;
>> +	if (!redist->base_address)
>> +		return -EINVAL;
>> +
>> +	return gic_acpi_register_redist(redist->base_address, redist->length);
>> +}
>> +
>> +static int __init
>> +gic_acpi_parse_madt_distributor(struct acpi_subtable_header *header,
>> +				const unsigned long end)
>> +{
>
> How many versions of gic_acpi_parse_madt_distributor are we going to
> get? Why isn't the ACPI parsing in a common file? Why do I have to read
> the same code on and on until my eyes bleed?

I will try to move it to common file irq-gic-acpi.c.

>
>> +	struct acpi_madt_generic_distributor *dist;
>> +
>> +	dist = (struct acpi_madt_generic_distributor *)header;
>> +
>> +	if (BAD_MADT_ENTRY(dist, end))
>> +		return -EINVAL;
>> +
>> +	dist_phys_base = dist->base_address;
>> +	return 0;
>> +}
>> +
>> +static int gic_acpi_gsi_desc_populate(struct acpi_gsi_descriptor *data,
>> +				      u32 gsi, unsigned int irq_type)
>> +{
>> +	/*
>> +	 * Encode GSI and triggering information the way the GIC likes
>> +	 * them.
>> +	 */
>> +	if (WARN_ON(gsi < 16))
>> +		return -EINVAL;
>> +
>> +	if (gsi >= 32) {
>> +		data->param[0] = 0;		/* SPI */
>> +		data->param[1] = gsi - 32;
>> +		data->param[2] = irq_type;
>> +	} else {
>> +		data->param[0] = 1; 		/* PPI */
>> +		data->param[1] = gsi - 16;
>> +		data->param[2] = 0xff << 4 | irq_type;
>> +	}
>> +
>> +	data->param_count = 3;
>> +
>> +	return 0;
>> +}
>> +
>> +static int __init
>> +gic_acpi_init(struct acpi_table_header *table)
>> +{
>> +	int count, i, err = 0;
>> +	void __iomem *dist_base;
>> +
>> +	/* Get distributor base address */
>> +	count = acpi_parse_entries(ACPI_SIG_MADT,
>> +				sizeof(struct acpi_table_madt),
>> +				gic_acpi_parse_madt_distributor, table,
>> +				ACPI_MADT_TYPE_GENERIC_DISTRIBUTOR, 0);
>> +	if (count <= 0) {
>> +		pr_err("No valid GICD entry exist\n");
>> +		return -EINVAL;
>> +	} else if (count > 1) {
>> +		pr_err("More than one GICD entry detected\n");
>> +		return -EINVAL;
>> +	}
>> +
>> +	dist_base = ioremap(dist_phys_base, ACPI_GICV3_DIST_MEM_SIZE);
>> +	if (!dist_base) {
>> +		pr_err("Unable to map GICD registers\n");
>> +		return -ENOMEM;
>> +	}
>> +
>> +	err = detect_distributor(dist_base);
>> +	if (err) {
>> +		pr_err("No distributor detected at @%p, giving up", dist_base);
>> +		goto out_dist_unmap;
>> +	}
>> +
>> +	/* Collect redistributor base addresses */
>> +	count = acpi_parse_entries(ACPI_SIG_MADT,
>> +			sizeof(struct acpi_table_madt),
>> +			gic_acpi_parse_madt_redist, table,
>> +			ACPI_MADT_TYPE_GENERIC_REDISTRIBUTOR, 0);
>> +	if (count <= 0) {
>> +		pr_info("No valid GICR entries exist\n");
>> +		err = -EINVAL;
>> +		goto out_redist_unmap;
>> +	}
>> +
>> +	err = gic_init_bases(dist_base, redist_regs, nr_redist_regions, 0,
>> +			     (void *)ACPI_IRQ_MODEL_GIC);
>
> There is no other global identifier for GICv3? It feels a bit weird to
> use the same ID as GICv2 (though probably not harmful as you can't have
> both as the same time). What are you planning to use for the ITS then?
> You must make sure you have a global namespace.

I will use the ITS physical base address as the token for ITS, maybe I
can use the GICD physical base address here instead?

>
>> +	if (err)
>> +		goto out_redist_unmap;
>> +
>> +	acpi_set_irq_model(ACPI_IRQ_MODEL_GIC, ACPI_IRQ_MODEL_GIC,
>> +			   gic_acpi_gsi_desc_populate);
>> +	return 0;
>> +
>> +out_redist_unmap:
>> +	for (i = 0; i < nr_redist_regions; i++)
>> +		if (redist_regs[i].redist_base)
>> +			iounmap(redist_regs[i].redist_base);
>> +	kfree(redist_regs);
>> +out_dist_unmap:
>> +	iounmap(dist_base);
>> +	return err;
>> +}
>> +IRQCHIP_ACPI_DECLARE(gic_v3, ACPI_MADT_GIC_VERSION_V3, gic_acpi_init);
>> +IRQCHIP_ACPI_DECLARE(gic_v4, ACPI_MADT_GIC_VERSION_V4, gic_acpi_init);
>
> As mentioned before, this doesn't work.

hmm, I think we need more discussion for this one, but we need to match
V4 for GICv3 drivers, and everything will be the same in the dirver
as I said before.

Thanks
Hanjun


From shawnguo at kernel.org  Wed Aug  5 07:08:14 2015
From: shawnguo at kernel.org (Shawn Guo)
Date: Wed, 5 Aug 2015 22:08:14 +0800
Subject: [PATCH v2 00/10] USB: chipidea misc patches
In-Reply-To: <1438577238-10153-1-git-send-email-peter.chen@freescale.com>
References: <1438577238-10153-1-git-send-email-peter.chen@freescale.com>
Message-ID: <20150805140813.GO12927@tiger>

On Mon, Aug 03, 2015 at 12:47:08PM +0800, Peter Chen wrote:
> Hi all,
> 
> In this series, I add several new interfaces for chipidea driver,
> they are mainly for system configuration adjustment. The USB
> performance may be improved with these configuration changing,
> but each vendor driver owner needs to consult with your IC
> owner which configuration parameters are suitable for your system
> before changing it, and only change it if necessary.
> 
> The other changes are for imx, it shows how imx uses these interfaces.
> Shawn, the patch [5/10] and [9/10] are dts changes, help to review it
> please.

Ping me, after driver and bindings are accepted.  Then I will pick up
the dts changes.

Shawn


From hanjun.guo at linaro.org  Wed Aug  5 07:11:22 2015
From: hanjun.guo at linaro.org (Hanjun Guo)
Date: Wed, 05 Aug 2015 22:11:22 +0800
Subject: [PATCH v4 07/10] irqchip / GICv3 / ACPI: Add GICR support via
 GICC structures
In-Reply-To: <55C0BFFD.3000602@arm.com>
References: <1438164539-29256-1-git-send-email-hanjun.guo@linaro.org>
 <1438164539-29256-8-git-send-email-hanjun.guo@linaro.org>
 <55C0BFFD.3000602@arm.com>
Message-ID: <55C2198A.5060001@linaro.org>

On 08/04/2015 09:37 PM, Marc Zyngier wrote:
> On 29/07/15 11:08, Hanjun Guo wrote:
>> On systems supporting GICv3 and above, in MADT GICC structures, the
>> field of GICR Base Address holds the 64-bit physical address of the
>> associated Redistributor if the GIC Redistributors are not in the
>> always-on power domain, so instead of init GICR regions via GIC
>> redistributor structure(s), init it with GICR base address in GICC
>> structures in that case.
>>
>> As GICR base in MADT GICC is another way to indicate the GIC version
>> is 3 or 4, add its support to find out the GIC versions.
>>
>> Signed-off-by: Hanjun Guo <hanjun.guo at linaro.org>
>> ---
>>   drivers/irqchip/irq-gic-acpi.c       |  35 ++++++-
>>   drivers/irqchip/irq-gic-v3.c         | 197 +++++++++++++++++++++++++++++++----
>>   include/linux/irqchip/arm-gic-acpi.h |   2 +
>>   3 files changed, 215 insertions(+), 19 deletions(-)
>>
>> diff --git a/drivers/irqchip/irq-gic-acpi.c b/drivers/irqchip/irq-gic-acpi.c
>> index 95454e3..3e5c8f4 100644
>> --- a/drivers/irqchip/irq-gic-acpi.c
>> +++ b/drivers/irqchip/irq-gic-acpi.c
>> @@ -21,6 +21,11 @@ static u8 gic_version __initdata = ACPI_MADT_GIC_VERSION_NONE;
>>
>>   static phys_addr_t dist_phy_base __initdata;
>>
>> +u8 __init acpi_gic_version(void)
>> +{
>> +       return gic_version;
>> +}
>> +
>>   static int __init
>>   acpi_gic_parse_distributor(struct acpi_subtable_header *header,
>>                             const unsigned long end)
>> @@ -38,6 +43,27 @@ acpi_gic_parse_distributor(struct acpi_subtable_header *header,
>>   }
>>
>>   static int __init
>> +gic_acpi_parse_madt_gicc(struct acpi_subtable_header *header,
>> +                        const unsigned long end)
>> +{
>> +       struct acpi_madt_generic_interrupt *gicc;
>> +
>> +       gicc = (struct acpi_madt_generic_interrupt *)header;
>> +
>> +       if (BAD_MADT_GICC_ENTRY(gicc, end))
>> +               return -EINVAL;
>> +
>> +       /*
>> +        * If GICC is enabled but has no valid gicr base address, then it
>> +        * means GICR base is not presented via GICC
>> +        */
>> +       if ((gicc->flags & ACPI_MADT_ENABLED) && !gicc->gicr_base_address)
>> +               return -ENODEV;
>> +
>> +       return 0;
>> +}
>> +
>> +static int __init
>>   match_gic_redist(struct acpi_subtable_header *header, const unsigned long end)
>>   {
>>          return 0;
>> @@ -51,7 +77,14 @@ static bool __init acpi_gic_redist_is_present(void)
>>          count  =  acpi_table_parse_madt(ACPI_MADT_TYPE_GENERIC_REDISTRIBUTOR,
>>                                          match_gic_redist, 0);
>>
>> -       /* that's true if we have at least one GIC redistributor entry */
>> +       /* has at least one GIC redistributor entry */
>> +       if (count > 0)
>> +               return true;
>> +
>> +       /* else try to find GICR base in GICC entries */
>> +       count = acpi_table_parse_madt(ACPI_MADT_TYPE_GENERIC_INTERRUPT,
>> +                                     gic_acpi_parse_madt_gicc, 0);
>> +
>>          return count > 0;
>>   }
>>
>> diff --git a/drivers/irqchip/irq-gic-v3.c b/drivers/irqchip/irq-gic-v3.c
>> index ebc5604..b72ccbb 100644
>> --- a/drivers/irqchip/irq-gic-v3.c
>> +++ b/drivers/irqchip/irq-gic-v3.c
>> @@ -389,9 +389,8 @@ static void __init gic_dist_init(void)
>>                  writeq_relaxed(affinity, base + GICD_IROUTER + i * 8);
>>   }
>>
>> -static int gic_populate_rdist(void)
>> +static int gic_populate_rdist_with_regions(u64 mpidr)
>>   {
>> -       u64 mpidr = cpu_logical_map(smp_processor_id());
>>          u64 typer;
>>          u32 aff;
>>          int i;
>> @@ -439,6 +438,34 @@ static int gic_populate_rdist(void)
>>                  } while (!(typer & GICR_TYPER_LAST));
>>          }
>>
>> +       return -ENODEV;
>> +}
>> +
>> +#ifdef CONFIG_ACPI
>> +/*
>> + * Populate redist when GIC redistributor address is presented in ACPI
>> + * MADT GICC entries
>> + */
>> +static int gic_populate_rdist_with_gicr_base(u64 mpidr);
>> +#else
>> +static inline int gic_populate_rdist_with_gicr_base(u64 mpidr)
>> +{
>> +       return -ENODEV;
>> +}
>> +#endif
>> +
>> +static int gic_populate_rdist(void)
>> +{
>> +       u64 mpidr = cpu_logical_map(smp_processor_id());
>> +
>> +       if (gic_data.nr_redist_regions) {
>> +               if (!gic_populate_rdist_with_regions(mpidr))
>> +                       return 0;
>> +       } else {
>> +               if (!gic_populate_rdist_with_gicr_base(mpidr))
>> +                       return 0;
>> +       }
>> +
>>          /* We couldn't even deal with ourselves... */
>>          WARN(true, "CPU%d: mpidr %llx has no re-distributor!\n",
>>               smp_processor_id(), (unsigned long long)mpidr);
>> @@ -900,6 +927,16 @@ IRQCHIP_DECLARE(gic_v3, "arm,gic-v3", gic_of_init);
>>   #endif
>>
>>   #ifdef CONFIG_ACPI
>> +
>> +struct acpi_gicc_redist {
>> +       struct list_head list;
>> +       u64 mpidr;
>> +       phys_addr_t phys_base;
>> +       void __iomem *redist_base;
>> +};
>> +
>> +static LIST_HEAD(redist_list);
>> +
>>   static struct redist_region *redist_regs __initdata;
>>   static u32 nr_redist_regions __initdata;
>>   static phys_addr_t dist_phys_base __initdata;
>> @@ -932,6 +969,17 @@ gic_acpi_register_redist(u64 phys_base, u64 size)
>>          return 0;
>>   }
>>
>> +static void __init
>> +gic_acpi_release_redist_regions(void)
>> +{
>> +       int i;
>> +
>> +       for (i = 0; i < nr_redist_regions; i++)
>> +               if (redist_regs[i].redist_base)
>> +                       iounmap(redist_regs[i].redist_base);
>> +       kfree(redist_regs);
>> +}
>> +
>>   static int __init
>>   gic_acpi_parse_madt_redist(struct acpi_subtable_header *header,
>>                          const unsigned long end)
>> @@ -989,9 +1037,130 @@ static int gic_acpi_gsi_desc_populate(struct acpi_gsi_descriptor *data,
>>   }
>>
>>   static int __init
>> +gic_acpi_add_gicc_redist(phys_addr_t phys_base, u64 mpidr)
>> +{
>> +       struct acpi_gicc_redist *redist;
>> +
>> +       redist = kzalloc(sizeof(*redist), GFP_KERNEL);
>> +       if (!redist)
>> +               return -ENOMEM;
>> +
>> +       redist->mpidr = mpidr;
>> +       redist->phys_base = phys_base;
>> +
>> +       if (acpi_gic_version() == ACPI_MADT_GIC_VERSION_V3)
>> +               /* RD_base + SGI_base */
>> +               redist->redist_base = ioremap(phys_base, 2 * SZ_64K);
>> +       else
>> +               /*
>> +                * RD_base + SGI_base + VLPI_base,
>> +                * we don't map reserved page as it's buggy to access it
>> +                */
>> +               redist->redist_base = ioremap(phys_base, 3 * SZ_64K);
>> +
>> +       if (!redist->redist_base) {
>> +               kfree(redist);
>> +               return -ENOMEM;
>> +       }
>> +
>> +       list_add(&redist->list, &redist_list);
>> +       return 0;
>> +}
>> +
>> +static void __init
>> +gic_acpi_release_gicc_redist(void)
>> +{
>> +       struct acpi_gicc_redist *redist, *t;
>> +
>> +       list_for_each_entry_safe(redist, t, &redist_list, list) {
>> +               list_del(&redist->list);
>> +               iounmap(redist->redist_base);
>> +               kfree(redist);
>> +       }
>> +}
>> +
>> +static int __init
>> +gic_acpi_parse_madt_gicc(struct acpi_subtable_header *header,
>> +                        const unsigned long end)
>> +{
>> +       struct acpi_madt_generic_interrupt *gicc;
>> +
>> +       gicc = (struct acpi_madt_generic_interrupt *)header;
>> +
>> +       if (BAD_MADT_GICC_ENTRY(gicc, end))
>> +               return -EINVAL;
>> +
>> +       /*
>> +        * just quietly ingore the disabled CPU(s) and continue
>> +        * to find the enabled one(s), if we return error here,
>> +        * the scanning will be stopped.
>> +        */
>> +       if (!(gicc->flags & ACPI_MADT_ENABLED))
>> +               return 0;
>> +
>> +       return gic_acpi_add_gicc_redist(gicc->gicr_base_address,
>> +                                       gicc->arm_mpidr);
>> +}
>> +
>> +static int gic_populate_rdist_with_gicr_base(u64 mpidr)
>> +{
>> +       struct acpi_gicc_redist *redist;
>> +       void __iomem *ptr;
>> +       u32 reg;
>> +
>> +       list_for_each_entry(redist, &redist_list, list) {
>> +               if (redist->mpidr != mpidr)
>> +                       continue;
>> +
>> +               ptr = redist->redist_base;
>> +               reg = readl_relaxed(ptr + GICR_PIDR2) & GIC_PIDR2_ARCH_MASK;
>> +               if (reg != GIC_PIDR2_ARCH_GICv3 && reg != GIC_PIDR2_ARCH_GICv4) {
>> +                       pr_warn("No redistributor present @%p\n", ptr);
>> +                       return -ENODEV;
>> +               }
>> +
>> +               gic_data_rdist_rd_base() = ptr;
>> +               gic_data_rdist()->phys_base = redist->phys_base;
>> +               pr_info("CPU%d: found redistributor %llx phys base:%pa\n",
>> +                       smp_processor_id(),
>> +                       (unsigned long long)mpidr,
>> +                       &gic_data_rdist()->phys_base);
>> +               return 0;
>> +       }
>> +
>> +       return -ENODEV;
>> +}
>> +
>> +static int __init collect_gicr_base(struct acpi_table_header *table)
>> +{
>> +       int count;
>> +
>> +       /* Collect redistributor base addresses in GICR entries */
>> +       count = acpi_parse_entries(ACPI_SIG_MADT,
>> +                       sizeof(struct acpi_table_madt),
>> +                       gic_acpi_parse_madt_redist, table,
>> +                       ACPI_MADT_TYPE_GENERIC_REDISTRIBUTOR, 0);
>> +       if (count > 0)
>> +               return 0;
>> +
>> +       pr_info("No valid GICR entries exist, try GICC entries\n");
>> +
>> +       /* Collect redistributor base addresses in GICC entries */
>> +       count = acpi_parse_entries(ACPI_SIG_MADT,
>> +                       sizeof(struct acpi_table_madt),
>> +                       gic_acpi_parse_madt_gicc, table,
>> +                       ACPI_MADT_TYPE_GENERIC_INTERRUPT, 0);
>> +       if (count > 0 && !list_empty(&redist_list))
>> +               return 0;
>> +
>> +       pr_info("No valid GICC entries exist for GICR base\n");
>> +       return -ENODEV;
>> +}
>> +
>> +static int __init
>>   gic_acpi_init(struct acpi_table_header *table)
>>   {
>> -       int count, i, err = 0;
>> +       int count, err = 0;
>>          void __iomem *dist_base;
>>
>>          /* Get distributor base address */
>> @@ -1020,30 +1189,22 @@ gic_acpi_init(struct acpi_table_header *table)
>>          }
>>
>>          /* Collect redistributor base addresses */
>> -       count = acpi_parse_entries(ACPI_SIG_MADT,
>> -                       sizeof(struct acpi_table_madt),
>> -                       gic_acpi_parse_madt_redist, table,
>> -                       ACPI_MADT_TYPE_GENERIC_REDISTRIBUTOR, 0);
>> -       if (count <= 0) {
>> -               pr_info("No valid GICR entries exist\n");
>> -               err = -EINVAL;
>> -               goto out_redist_unmap;
>> -       }
>> +       if (collect_gicr_base(table))
>> +               goto out_release_redist;
>>
>>          err = gic_init_bases(dist_base, redist_regs, nr_redist_regions, 0,
>>                               (void *)ACPI_IRQ_MODEL_GIC);
>>          if (err)
>> -               goto out_redist_unmap;
>> +               goto out_release_redist;
>>
>>          acpi_set_irq_model(ACPI_IRQ_MODEL_GIC, ACPI_IRQ_MODEL_GIC,
>>                             gic_acpi_gsi_desc_populate);
>>          return 0;
>>
>> -out_redist_unmap:
>> -       for (i = 0; i < nr_redist_regions; i++)
>> -               if (redist_regs[i].redist_base)
>> -                       iounmap(redist_regs[i].redist_base);
>> -       kfree(redist_regs);
>> +out_release_redist:
>> +       gic_acpi_release_redist_regions();
>> +       if (!list_empty(&redist_list))
>> +               gic_acpi_release_gicc_redist();
>>   out_dist_unmap:
>>          iounmap(dist_base);
>>          return err;
>> diff --git a/include/linux/irqchip/arm-gic-acpi.h b/include/linux/irqchip/arm-gic-acpi.h
>> index 56cd82c..0d43f515 100644
>> --- a/include/linux/irqchip/arm-gic-acpi.h
>> +++ b/include/linux/irqchip/arm-gic-acpi.h
>> @@ -21,5 +21,7 @@
>>   #define ACPI_GIC_CPU_IF_MEM_SIZE       (SZ_8K)
>>   #define ACPI_GICV3_DIST_MEM_SIZE       (SZ_64K)
>>
>> +u8 acpi_gic_version(void);
>> +
>>   #endif /* CONFIG_ACPI */
>>   #endif /* ARM_GIC_ACPI_H_ */
>> --
>> 1.9.1
>>
>
> This looks absolutely horrid. Why don't you simply populate one region
> per redistributor, add a flag to struct redist_region so we know not to
> check for GICR_TYPER_LAST but to move on to the next region instead?

There is no regions in GICC structures, and only have the GICR base
address for each CPU, I think we can't figure out which GICR bases
are belonging to a GICR region.

So do you mean populate each GICR base as a region, and use the
existing infrastructure ?

Thanks
Hanjun


From mporter at konsulko.com  Wed Aug  5 07:20:11 2015
From: mporter at konsulko.com (Matt Porter)
Date: Wed, 5 Aug 2015 10:20:11 -0400
Subject: [PATCH-v5 1/5] Documentation: binding: add new property
 'disable_after_xfer' to i2c-pxa
In-Reply-To: <55C1AE71.3010700@linaro.org>
References: <1437482466-16126-1-git-send-email-vaibhav.hiremath@linaro.org>
 <1437482466-16126-2-git-send-email-vaibhav.hiremath@linaro.org>
 <20150727140911.GB15004@beef> <55C1AE71.3010700@linaro.org>
Message-ID: <20150805142011.GC23173@beef>

On Wed, Aug 05, 2015 at 12:04:25PM +0530, Vaibhav Hiremath wrote:
> 
> 
> On Monday 27 July 2015 07:39 PM, Matt Porter wrote:
> >On Tue, Jul 21, 2015 at 06:11:02PM +0530, Vaibhav Hiremath wrote:
> >>Driver will now supports enable/disable across msg xfer, which user
> >>can control it by new DT property -
> >>
> >>i2c-disable-after-xfer : If set, driver will disable I2C module after msg
> >>  xfer and enable it back before xfer.
> >
> >If this is a new property specific to this Marvell part, it needs
> >the vendor prefix as in mrvl,i2c-disable-after-xfer
> >
> 
> We discussed about this, I think in V1 or V2. Decided to use generic
> name, as feature (in turn property) could be used by other drivers as
> well.

Ahh, ok, thanks...coming in too late on this one. :)

> >Or, it couldn't hurt to start an i2c.txt for generic i2c bindings
> >and store it there as this and others later in this series would
> >reasonably apply to other controllers.
> >
> 
> Yeah, we could start i2c.txt, probably better to have separate new
> patch all together.

Great, yes, I've always found it hard to follow i2c generic bindings
since they aren't defined in a clear place like other similar hardware
(e.g. SPI).

-Matt


From vaibhav.hiremath at linaro.org  Wed Aug  5 07:24:33 2015
From: vaibhav.hiremath at linaro.org (Vaibhav Hiremath)
Date: Wed, 05 Aug 2015 19:54:33 +0530
Subject: [PATCH-v5 1/5] Documentation: binding: add new property
 'disable_after_xfer' to i2c-pxa
In-Reply-To: <20150805142011.GC23173@beef>
References: <1437482466-16126-1-git-send-email-vaibhav.hiremath@linaro.org>
 <1437482466-16126-2-git-send-email-vaibhav.hiremath@linaro.org>
 <20150727140911.GB15004@beef> <55C1AE71.3010700@linaro.org>
 <20150805142011.GC23173@beef>
Message-ID: <55C21CA1.9040108@linaro.org>



On Wednesday 05 August 2015 07:50 PM, Matt Porter wrote:
> On Wed, Aug 05, 2015 at 12:04:25PM +0530, Vaibhav Hiremath wrote:
>>
>>
>> On Monday 27 July 2015 07:39 PM, Matt Porter wrote:
>>> On Tue, Jul 21, 2015 at 06:11:02PM +0530, Vaibhav Hiremath wrote:
>>>> Driver will now supports enable/disable across msg xfer, which user
>>>> can control it by new DT property -
>>>>
>>>> i2c-disable-after-xfer : If set, driver will disable I2C module after msg
>>>>   xfer and enable it back before xfer.
>>>
>>> If this is a new property specific to this Marvell part, it needs
>>> the vendor prefix as in mrvl,i2c-disable-after-xfer
>>>
>>
>> We discussed about this, I think in V1 or V2. Decided to use generic
>> name, as feature (in turn property) could be used by other drivers as
>> well.
>
> Ahh, ok, thanks...coming in too late on this one. :)
>
>>> Or, it couldn't hurt to start an i2c.txt for generic i2c bindings
>>> and store it there as this and others later in this series would
>>> reasonably apply to other controllers.
>>>
>>
>> Yeah, we could start i2c.txt, probably better to have separate new
>> patch all together.
>
> Great, yes, I've always found it hard to follow i2c generic bindings
> since they aren't defined in a clear place like other similar hardware
> (e.g. SPI).
>

Wolfram has already owned up on creating i2c.txt for generic properties.
So, we will be soon close to others.

And thanks for your comments.
Please let me know if you have any other comments on patch-series, so
that I can incorporate it in next version.

Thanks,
Vaibhav


From mporter at konsulko.com  Wed Aug  5 07:24:49 2015
From: mporter at konsulko.com (Matt Porter)
Date: Wed, 5 Aug 2015 10:24:49 -0400
Subject: [PATCH-v5 1/5] Documentation: binding: add new property
 'disable_after_xfer' to i2c-pxa
In-Reply-To: <20150805084917.GA1523@katana>
References: <1437482466-16126-1-git-send-email-vaibhav.hiremath@linaro.org>
 <1437482466-16126-2-git-send-email-vaibhav.hiremath@linaro.org>
 <20150727140911.GB15004@beef> <55C1AE71.3010700@linaro.org>
 <20150805084917.GA1523@katana>
Message-ID: <20150805142449.GD23173@beef>

On Wed, Aug 05, 2015 at 10:49:18AM +0200, Wolfram Sang wrote:
> 
> > Yeah, we could start i2c.txt, probably better to have separate new
> > patch all together.
> 
> I will start such a file today as part of the i2c slave framework
> update which introduces flags to the reg property. Will post to the i2c
> list this week.
> 

That sounds great, Wolfram, that will be a nice improvement for the
binding docs.

Thanks,
Matt

-------------- next part --------------
A non-text attachment was scrubbed...
Name: signature.asc
Type: application/pgp-signature
Size: 819 bytes
Desc: Digital signature
URL: <http://lists.infradead.org/pipermail/linux-arm-kernel/attachments/20150805/abf4d5c3/attachment.sig>

From kishon at ti.com  Wed Aug  5 07:25:17 2015
From: kishon at ti.com (Kishon Vijay Abraham I)
Date: Wed, 5 Aug 2015 19:55:17 +0530
Subject: [PATCH 10/10] ARM: dts: omap4: Use "syscon-otghs" instead of
 "ctrl-module" in USB node
In-Reply-To: <55C1C486.6050202@ti.com>
References: <1438702233-8027-1-git-send-email-kishon@ti.com>
 <1438702233-8027-11-git-send-email-kishon@ti.com> <55C1C325.5040703@ti.com>
 <55C1C486.6050202@ti.com>
Message-ID: <55C21CCD.6050101@ti.com>

Hi Roger,

On Wednesday 05 August 2015 01:38 PM, Roger Quadros wrote:
> On 05/08/15 11:02, Roger Quadros wrote:
>> Kishon,
>>
>> On 04/08/15 18:30, Kishon Vijay Abraham I wrote:
>>> Add "syscon-otghs" property and remove the deprecated "ctrl-module"
>>> property from MUSB devicetree node.
>>>
>>> Since "omap_control_usbotg" devicetree node is no longer used, remove
>>> it.
>>>
>>> Signed-off-by: Kishon Vijay Abraham I <kishon at ti.com>
>>> ---
>>>  arch/arm/boot/dts/omap4.dtsi |    8 +-------
>>>  1 file changed, 1 insertion(+), 7 deletions(-)
>>>
>>> diff --git a/arch/arm/boot/dts/omap4.dtsi b/arch/arm/boot/dts/omap4.dtsi
>>> index b27634d..2fb49a5 100644
>>> --- a/arch/arm/boot/dts/omap4.dtsi
>>> +++ b/arch/arm/boot/dts/omap4.dtsi
>>> @@ -854,12 +854,6 @@
>>>  			};
>>>  		};
>>>  
>>> -		omap_control_usbotg: control-phy at 4a00233c {
>>> -			compatible = "ti,control-phy-otghs";
>>> -			reg = <0x4a00233c 0x4>;
>>> -			reg-names = "otghs_control";
>>> -		};
>>> -
>>>  		usb_otg_hs: usb_otg_hs at 4a0ab000 {
>>>  			compatible = "ti,omap4-musb";
>>>  			reg = <0x4a0ab000 0x7ff>;
>>> @@ -872,7 +866,7 @@
>>>  			multipoint = <1>;
>>>  			num-eps = <16>;
>>>  			ram-bits = <12>;
>>> -			ctrl-module = <&omap_control_usbotg>;
>>> +			syscon-otghs = <&scm_conf 0x33c>;
>>
>> All other properties were of the format "syscon-phy-foo".
>> Why use a different format here?
>>
> 
> Ah, looks like we don't have a dedicated phy driver for this?
> We will need to add a PHY driver I guess then and handle this register
> in that driver rather than in the musb driver.

I was explaining in the other thread to Tony on why this shouldn't be done in a
PHY driver [1].

Thanks
Kishon

[1] -> https://lkml.org/lkml/2015/8/5/455


From Liviu.Dudau at arm.com  Wed Aug  5 07:28:09 2015
From: Liviu.Dudau at arm.com (Liviu Dudau)
Date: Wed,  5 Aug 2015 15:28:09 +0100
Subject: [PATCH 1/4] drm: arm: Add DT bindings documentation for HDLCD driver.
In-Reply-To: <1438784892-27888-1-git-send-email-Liviu.Dudau@arm.com>
References: <1438784892-27888-1-git-send-email-Liviu.Dudau@arm.com>
Message-ID: <1438784892-27888-2-git-send-email-Liviu.Dudau@arm.com>

Cc: Rob Herring <robh+dt at kernel.org>
Cc: Pawel Moll <pawel.moll at arm.com>
Cc: Mark Rutland <mark.rutland at arm.com>
Cc: Ian Campbell <ijc+devicetree at hellion.org.uk>
Cc: Kumar Gala <galak at codeaurora.org>

Signed-off-by: Liviu Dudau <Liviu.Dudau at arm.com>
---
 .../devicetree/bindings/drm/arm/arm,hdlcd.txt      | 74 ++++++++++++++++++++++
 1 file changed, 74 insertions(+)
 create mode 100644 Documentation/devicetree/bindings/drm/arm/arm,hdlcd.txt

diff --git a/Documentation/devicetree/bindings/drm/arm/arm,hdlcd.txt b/Documentation/devicetree/bindings/drm/arm/arm,hdlcd.txt
new file mode 100644
index 0000000..b57f1b9
--- /dev/null
+++ b/Documentation/devicetree/bindings/drm/arm/arm,hdlcd.txt
@@ -0,0 +1,74 @@
+ARM HDLCD
+
+This is a display controller found on several development platforms produced
+by ARM Ltd and in more modern of its' Fast Models. The HDLCD is an RGB
+streamer that reads the data from a framebuffer and sends it to a single
+digital encoder (DVI or HDMI).
+
+Required properties:
+  - compatible: "arm,hdlcd"
+  - reg: Physical base address and length of the controller's registers.
+    If a second pair of address and length values is present this specifies
+    the presence of a DMA coherent memory area that the HDLCD can use as
+    framebuffer instead of normal CMA memory.
+  - interrupts: One interrupt used by the display controller to notify the
+    interrupt controller when any of the interrupt sources programmed in
+    the interrupt mask register have activated.
+  - clocks: A list of phandle + clock-specifier pairs, one for each
+    entry in 'clock-names'.
+  - clock-names: A list of clock names. For HDLD it should contain:
+      - "pxlclk" for the clock feeding the output PLL of the controller.
+  - port: The HDLCD connection to an encoder chip. The connection is modelled
+    using the OF graph bindings specified in Documentation/devicetree/bindings/graph.txt.
+
+
+Example:
+
+/ {
+	...
+
+	hdlcd at 2b000000 {
+		compatible = "arm,hdlcd";
+		reg = <0 0x2b000000 0 0x1000>;
+		interrupts = <GIC_SPI 85 IRQ_TYPE_LEVEL_HIGH>;
+		clocks = <&oscclk5>;
+		clock-names = "pxlclk";
+		port {
+			hdlcd_output: endpoint at 0 {
+				remote-endpoint = <&hdmi_enc_input>;
+			};
+		};
+	};
+
+	/* HDMI encoder on I2C bus */
+	i2c at 7ffa0000 {
+		....
+		hdmi-transmitter at 70 {
+			compatible = ".....";
+			reg = <0x70>;
+			video-ports = <0x234501>;
+			port at 0 {
+				hdmi_enc_input: endpoint {
+					remote-endpoint = <&hdlcd_output>;
+				};
+
+				hdmi_enc_output: endpoint {
+					remote-endpoint = <&hdmi_1_port>;
+				};
+			};
+		};
+
+	};
+
+	hdmi1: connector at 1 {
+		compatible = "hdmi-connector";
+		type = "a";
+		port {
+			hdmi_1_port: endpoint {
+				remote-endpoint = <&hdmi_enc_output>;
+			};
+		};
+	};
+
+	...
+};
-- 
2.4.6



From Liviu.Dudau at arm.com  Wed Aug  5 07:28:11 2015
From: Liviu.Dudau at arm.com (Liviu Dudau)
Date: Wed,  5 Aug 2015 15:28:11 +0100
Subject: [PATCH 3/4] arm64: Juno: Add HDLCD support to the Juno boards.
In-Reply-To: <1438784892-27888-1-git-send-email-Liviu.Dudau@arm.com>
References: <1438784892-27888-1-git-send-email-Liviu.Dudau@arm.com>
Message-ID: <1438784892-27888-4-git-send-email-Liviu.Dudau@arm.com>

ARM's Juno board has two HDLCD controllers, each linked to an NXP
TDA19988 HDMI transmitter that provides output encoding. Add them
to the device tree.

Signed-off-by: Liviu Dudau <Liviu.Dudau at arm.com>
---
 arch/arm64/boot/dts/arm/juno-base.dtsi | 70 +++++++++++++++++++++++++++++++++-
 1 file changed, 68 insertions(+), 2 deletions(-)

diff --git a/arch/arm64/boot/dts/arm/juno-base.dtsi b/arch/arm64/boot/dts/arm/juno-base.dtsi
index c624208..a12a2b1 100644
--- a/arch/arm64/boot/dts/arm/juno-base.dtsi
+++ b/arch/arm64/boot/dts/arm/juno-base.dtsi
@@ -118,6 +118,34 @@
 		clock-names = "apb_pclk";
 	};
 
+	hdlcd at 7ff50000 {
+		compatible = "arm,hdlcd";
+		reg = <0 0x7ff50000 0 0x1000>;
+		interrupts = <GIC_SPI 93 IRQ_TYPE_LEVEL_HIGH>;
+		clocks = <&scpi_clk 4>;
+		clock-names = "pxlclk";
+
+		port {
+			hdlcd1_output: endpoint at 0 {
+				remote-endpoint = <&tda998x_1_input>;
+			};
+		};
+	};
+
+	hdlcd at 7ff60000 {
+		compatible = "arm,hdlcd";
+		reg = <0 0x7ff60000 0 0x1000>;
+		interrupts = <GIC_SPI 85 IRQ_TYPE_LEVEL_HIGH>;
+		clocks = <&scpi_clk 4>;
+		clock-names = "pxlclk";
+
+		port {
+			hdlcd0_output: endpoint at 0 {
+				remote-endpoint = <&tda998x_0_input>;
+			};
+		};
+	};
+
 	soc_uart0: uart at 7ff80000 {
 		compatible = "arm,pl011", "arm,primecell";
 		reg = <0x0 0x7ff80000 0x0 0x1000>;
@@ -136,14 +164,32 @@
 		i2c-sda-hold-time-ns = <500>;
 		clocks = <&soc_smc50mhz>;
 
-		dvi0: dvi-transmitter at 70 {
+		hdmi-transmitter at 70 {
 			compatible = "nxp,tda998x";
 			reg = <0x70>;
+			port {
+				tda998x_0_input: endpoint at 0 {
+					remote-endpoint = <&hdlcd0_output>;
+				};
+
+				tda998x_0_output: endpoint at 1 {
+					remote-endpoint = <&hdmi0_connector_output>;
+				};
+			};
 		};
 
-		dvi1: dvi-transmitter at 71 {
+		hdmi-transmitter at 71 {
 			compatible = "nxp,tda998x";
 			reg = <0x71>;
+			port {
+				tda998x_1_input: endpoint at 0 {
+					remote-endpoint = <&hdlcd1_output>;
+				};
+
+				tda998x_1_output: endpoint at 1 {
+					remote-endpoint = <&hdmi1_connector_output>;
+				};
+			};
 		};
 	};
 
@@ -177,6 +223,26 @@
 		      <0x00000008 0x80000000 0x1 0x80000000>;
 	};
 
+	hdmi0: connector at 0 {
+		compatible = "hdmi-connector";
+		type = "a";
+		port {
+			hdmi0_connector_output: endpoint {
+				remote-endpoint = <&tda998x_0_output>;
+			};
+		};
+	};
+
+	hdmi1: connector at 1 {
+		compatible = "hdmi-connector";
+		type = "a";
+		port {
+			hdmi1_connector_output: endpoint {
+				remote-endpoint = <&tda998x_1_output>;
+			};
+		};
+	};
+
 	smb {
 		compatible = "simple-bus";
 		#address-cells = <2>;
-- 
2.4.6



From Liviu.Dudau at arm.com  Wed Aug  5 07:28:08 2015
From: Liviu.Dudau at arm.com (Liviu Dudau)
Date: Wed,  5 Aug 2015 15:28:08 +0100
Subject: [PATCH 0/4] drm: Add support for the ARM HDLCD display controller
Message-ID: <1438784892-27888-1-git-send-email-Liviu.Dudau@arm.com>

This series adds support for ARM's HDLCD display controller found in Juno
and ARM TC2 Coretile. The HDLCD outputs an RGB stream that feeds into a
single digital encoder (DVI or HDMI).

This series depends on Sudeep Holla's series that introduces support for
SCPI[1] on Juno.

Only the Juno functionality has been tested as the TC2 Coretile require
a working SiI9022 driver for VExpress that is not subject of this patchset.

This is my first driver for the DRM subsystem and as such probably contains
misuses of the APIs that I will be glad to correct if pointed out.

Best regards,
Liviu


[1] http://lists.infradead.org/pipermail/linux-arm-kernel/2015-August/362219.html

Liviu Dudau (4):
  drm: arm: Add DT bindings documentation for HDLCD driver.
  drm: Add support for ARM's HDLCD controller.
  arm64: Juno: Add HDLCD support to the Juno boards.
  MAINTAINERS: Add Liviu Dudau as maintainer for ARM HDLCD driver.

 .../devicetree/bindings/drm/arm/arm,hdlcd.txt      |  74 ++++
 MAINTAINERS                                        |   6 +
 arch/arm64/boot/dts/arm/juno-base.dtsi             |  70 ++-
 drivers/gpu/drm/Kconfig                            |   2 +
 drivers/gpu/drm/Makefile                           |   1 +
 drivers/gpu/drm/arm/Kconfig                        |  20 +
 drivers/gpu/drm/arm/Makefile                       |   2 +
 drivers/gpu/drm/arm/hdlcd_crtc.c                   | 265 +++++++++++
 drivers/gpu/drm/arm/hdlcd_drv.c                    | 490 +++++++++++++++++++++
 drivers/gpu/drm/arm/hdlcd_drv.h                    |  51 +++
 drivers/gpu/drm/arm/hdlcd_regs.h                   |  87 ++++
 11 files changed, 1066 insertions(+), 2 deletions(-)
 create mode 100644 Documentation/devicetree/bindings/drm/arm/arm,hdlcd.txt
 create mode 100644 drivers/gpu/drm/arm/Kconfig
 create mode 100644 drivers/gpu/drm/arm/Makefile
 create mode 100644 drivers/gpu/drm/arm/hdlcd_crtc.c
 create mode 100644 drivers/gpu/drm/arm/hdlcd_drv.c
 create mode 100644 drivers/gpu/drm/arm/hdlcd_drv.h
 create mode 100644 drivers/gpu/drm/arm/hdlcd_regs.h

-- 
2.4.6



From Liviu.Dudau at arm.com  Wed Aug  5 07:28:10 2015
From: Liviu.Dudau at arm.com (Liviu Dudau)
Date: Wed,  5 Aug 2015 15:28:10 +0100
Subject: [PATCH 2/4] drm: Add support for ARM's HDLCD controller.
In-Reply-To: <1438784892-27888-1-git-send-email-Liviu.Dudau@arm.com>
References: <1438784892-27888-1-git-send-email-Liviu.Dudau@arm.com>
Message-ID: <1438784892-27888-3-git-send-email-Liviu.Dudau@arm.com>

The HDLCD controller is a display controller that supports resolutions
up to 4096x4096 pixels. It is present on various development boards
produced by ARM Ltd and emulated by the latest Fast Models from the
company.

Cc: David Airlie <airlied at linux.ie>
Cc: Robin Murphy <robin.murphy at arm.com>

Signed-off-by: Liviu Dudau <Liviu.Dudau at arm.com>
---
 drivers/gpu/drm/Kconfig          |   2 +
 drivers/gpu/drm/Makefile         |   1 +
 drivers/gpu/drm/arm/Kconfig      |  20 ++
 drivers/gpu/drm/arm/Makefile     |   2 +
 drivers/gpu/drm/arm/hdlcd_crtc.c | 265 +++++++++++++++++++++
 drivers/gpu/drm/arm/hdlcd_drv.c  | 490 +++++++++++++++++++++++++++++++++++++++
 drivers/gpu/drm/arm/hdlcd_drv.h  |  51 ++++
 drivers/gpu/drm/arm/hdlcd_regs.h |  87 +++++++
 8 files changed, 918 insertions(+)
 create mode 100644 drivers/gpu/drm/arm/Kconfig
 create mode 100644 drivers/gpu/drm/arm/Makefile
 create mode 100644 drivers/gpu/drm/arm/hdlcd_crtc.c
 create mode 100644 drivers/gpu/drm/arm/hdlcd_drv.c
 create mode 100644 drivers/gpu/drm/arm/hdlcd_drv.h
 create mode 100644 drivers/gpu/drm/arm/hdlcd_regs.h

diff --git a/drivers/gpu/drm/Kconfig b/drivers/gpu/drm/Kconfig
index c46ca31..f819db0 100644
--- a/drivers/gpu/drm/Kconfig
+++ b/drivers/gpu/drm/Kconfig
@@ -88,6 +88,8 @@ config DRM_TDFX
 	  Choose this option if you have a 3dfx Banshee or Voodoo3 (or later),
 	  graphics card.  If M is selected, the module will be called tdfx.
 
+source "drivers/gpu/drm/arm/Kconfig"
+
 config DRM_R128
 	tristate "ATI Rage 128"
 	depends on DRM && PCI
diff --git a/drivers/gpu/drm/Makefile b/drivers/gpu/drm/Makefile
index 5713d05..2ce474e 100644
--- a/drivers/gpu/drm/Makefile
+++ b/drivers/gpu/drm/Makefile
@@ -32,6 +32,7 @@ CFLAGS_drm_trace_points.o := -I$(src)
 
 obj-$(CONFIG_DRM)	+= drm.o
 obj-$(CONFIG_DRM_MIPI_DSI) += drm_mipi_dsi.o
+obj-$(CONFIG_DRM_ARM)	+= arm/
 obj-$(CONFIG_DRM_TTM)	+= ttm/
 obj-$(CONFIG_DRM_TDFX)	+= tdfx/
 obj-$(CONFIG_DRM_R128)	+= r128/
diff --git a/drivers/gpu/drm/arm/Kconfig b/drivers/gpu/drm/arm/Kconfig
new file mode 100644
index 0000000..9590d8e
--- /dev/null
+++ b/drivers/gpu/drm/arm/Kconfig
@@ -0,0 +1,20 @@
+config DRM_ARM
+	bool "ARM Ltd. drivers"
+	depends on DRM && OF && (ARM || ARM64)
+	select DMA_CMA
+	select DRM_KMS_HELPER
+	select DRM_KMS_CMA_HELPER
+	select DRM_GEM_CMA_HELPER
+	help
+	  Choose this option to select drivers for ARM's devices
+
+config DRM_HDLCD
+	tristate "ARM HDLCD"
+	depends on DRM_ARM
+	depends on COMMON_CLK
+	select COMMON_CLK_SCPI
+	help
+	  Choose this option if you have an ARM High Definition Colour LCD
+	  controller.
+
+	  If M is selected the module will be called hdlcd.
diff --git a/drivers/gpu/drm/arm/Makefile b/drivers/gpu/drm/arm/Makefile
new file mode 100644
index 0000000..89dcb7b
--- /dev/null
+++ b/drivers/gpu/drm/arm/Makefile
@@ -0,0 +1,2 @@
+hdlcd-y := hdlcd_drv.o hdlcd_crtc.o
+obj-$(CONFIG_DRM_HDLCD)	+= hdlcd.o
diff --git a/drivers/gpu/drm/arm/hdlcd_crtc.c b/drivers/gpu/drm/arm/hdlcd_crtc.c
new file mode 100644
index 0000000..8081238
--- /dev/null
+++ b/drivers/gpu/drm/arm/hdlcd_crtc.c
@@ -0,0 +1,265 @@
+/*
+ * Copyright (C) 2013-2015 ARM Limited
+ * Author: Liviu Dudau <Liviu.Dudau at arm.com>
+ *
+ * This file is subject to the terms and conditions of the GNU General Public
+ * License.  See the file COPYING in the main directory of this archive
+ * for more details.
+ *
+ *  Implementation of a CRTC class for the HDLCD driver.
+ */
+
+#include <drm/drmP.h>
+#include <drm/drm_crtc.h>
+#include <drm/drm_crtc_helper.h>
+#include <drm/drm_fb_helper.h>
+#include <drm/drm_fb_cma_helper.h>
+#include <drm/drm_gem_cma_helper.h>
+#include <drm/drm_of.h>
+#include <drm/drm_plane_helper.h>
+#include <linux/clk.h>
+#include <linux/of_graph.h>
+#include <linux/platform_data/simplefb.h>
+
+#include "hdlcd_drv.h"
+#include "hdlcd_regs.h"
+
+/*
+ * The HDLCD controller is a dumb RGB streamer that gets connected to
+ * a single HDMI transmitter or in the case of the ARM Models it gets
+ * emulated by the software that does the actual rendering.
+ *
+ */
+static void hdlcd_crtc_destroy(struct drm_crtc *crtc)
+{
+	struct hdlcd_drm_private *hdlcd = crtc_to_hdlcd_priv(crtc);
+
+	of_node_put(hdlcd->crtc.port);
+	drm_crtc_cleanup(crtc);
+}
+
+void hdlcd_set_scanout(struct hdlcd_drm_private *hdlcd)
+{
+	struct drm_framebuffer *fb = hdlcd->crtc.primary->fb;
+	struct drm_gem_cma_object *gem;
+	unsigned int depth, bpp;
+	dma_addr_t scanout_start;
+
+	drm_fb_get_bpp_depth(fb->pixel_format, &depth, &bpp);
+	gem = drm_fb_cma_get_gem_obj(fb, 0);
+
+	scanout_start = gem->paddr + fb->offsets[0] +
+		(hdlcd->crtc.y * fb->pitches[0]) + (hdlcd->crtc.x * bpp/8);
+
+	hdlcd_write(hdlcd, HDLCD_REG_FB_BASE, scanout_start);
+}
+
+static int hdlcd_crtc_page_flip(struct drm_crtc *crtc,
+			struct drm_framebuffer *fb,
+			struct drm_pending_vblank_event *event,
+			uint32_t flags)
+{
+	struct hdlcd_drm_private *hdlcd = crtc_to_hdlcd_priv(crtc);
+
+	if (hdlcd->dpms == DRM_MODE_DPMS_ON) {
+		/* don't schedule any page flipping if one is in progress */
+		if (hdlcd->event)
+			return -EBUSY;
+
+		hdlcd->event = event;
+		drm_vblank_get(crtc->dev, 0);
+	}
+
+	crtc->primary->fb = fb;
+
+	if (hdlcd->dpms != DRM_MODE_DPMS_ON) {
+		unsigned long flags;
+
+		/* not active, update registers immediately */
+		hdlcd_set_scanout(hdlcd);
+		spin_lock_irqsave(&crtc->dev->event_lock, flags);
+		if (event)
+			drm_send_vblank_event(crtc->dev, 0, event);
+		spin_unlock_irqrestore(&crtc->dev->event_lock, flags);
+	}
+
+	return 0;
+}
+
+static const struct drm_crtc_funcs hdlcd_crtc_funcs = {
+	.destroy	= hdlcd_crtc_destroy,
+	.set_config	= drm_crtc_helper_set_config,
+	.page_flip	= hdlcd_crtc_page_flip,
+};
+
+static void hdlcd_crtc_dpms(struct drm_crtc *crtc, int mode)
+{
+	struct hdlcd_drm_private *hdlcd = crtc_to_hdlcd_priv(crtc);
+
+	hdlcd->dpms = mode;
+	if (mode == DRM_MODE_DPMS_ON)
+		hdlcd_write(hdlcd, HDLCD_REG_COMMAND, 1);
+	else
+		hdlcd_write(hdlcd, HDLCD_REG_COMMAND, 0);
+}
+
+static bool hdlcd_crtc_mode_fixup(struct drm_crtc *crtc,
+			const struct drm_display_mode *mode,
+			struct drm_display_mode *adjusted_mode)
+{
+	return true;
+}
+
+static void hdlcd_crtc_prepare(struct drm_crtc *crtc)
+{
+	hdlcd_crtc_dpms(crtc, DRM_MODE_DPMS_OFF);
+}
+
+static void hdlcd_crtc_commit(struct drm_crtc *crtc)
+{
+	drm_vblank_post_modeset(crtc->dev, 0);
+	hdlcd_crtc_dpms(crtc, DRM_MODE_DPMS_ON);
+}
+
+static struct simplefb_format supported_formats[] = SIMPLEFB_FORMATS;
+
+static int hdlcd_crtc_colour_set(struct hdlcd_drm_private *hdlcd,
+				uint32_t pixel_format)
+{
+	unsigned int depth, bpp;
+	unsigned int default_color = 0x00000000;
+	struct simplefb_format *format = NULL;
+	int i;
+
+#ifdef HDLCD_SHOW_UNDERRUN
+	default_color = 0x00ff0000;	/* show underruns in red */
+#endif
+
+	/* Calculate each colour's number of bits */
+	drm_fb_get_bpp_depth(pixel_format, &depth, &bpp);
+
+	for (i = 0; i < ARRAY_SIZE(supported_formats); i++) {
+		if (supported_formats[i].fourcc == pixel_format)
+			format = &supported_formats[i];
+	}
+
+	if (!format) {
+		DRM_ERROR("Format not supported: 0x%x\n", pixel_format);
+		return -EINVAL;
+	}
+
+	/* HDLCD uses 'bytes per pixel' */
+	bpp = (bpp + 7) / 8;
+	hdlcd_write(hdlcd, HDLCD_REG_PIXEL_FORMAT, (bpp - 1) << 3);
+
+	/*
+	 * The format of the HDLCD_REG_<color>_SELECT register is:
+	 *   - bits[23:16] - default value for that color component
+	 *   - bits[11:8]  - number of bits to extract for each color component
+	 *   - bits[4:0]   - index of the lowest bit to extract
+	 *
+	 * The default color value is used when bits[11:8] read zero, when the
+	 * pixel is outside the visible frame area or when there is a
+	 * buffer underrun.
+	 */
+	hdlcd_write(hdlcd, HDLCD_REG_RED_SELECT, default_color |
+		format->red.offset | (format->red.length & 0xf) << 8);
+	hdlcd_write(hdlcd, HDLCD_REG_GREEN_SELECT, default_color |
+		format->green.offset | (format->green.length & 0xf) << 8);
+	hdlcd_write(hdlcd, HDLCD_REG_BLUE_SELECT, default_color |
+		format->blue.offset | (format->blue.length & 0xf) << 8);
+
+	return 0;
+}
+
+static int hdlcd_crtc_mode_set(struct drm_crtc *crtc,
+			struct drm_display_mode *mode,
+			struct drm_display_mode *adjusted_mode,
+			int x, int y, struct drm_framebuffer *oldfb)
+{
+	struct hdlcd_drm_private *hdlcd = crtc_to_hdlcd_priv(crtc);
+	unsigned int depth, bpp, polarities, line_length, err;
+
+	drm_vblank_pre_modeset(crtc->dev, 0);
+
+	polarities = HDLCD_POLARITY_DATAEN | HDLCD_POLARITY_DATA;
+
+	if (adjusted_mode->flags & DRM_MODE_FLAG_PHSYNC)
+		polarities |= HDLCD_POLARITY_HSYNC;
+	if (adjusted_mode->flags & DRM_MODE_FLAG_PVSYNC)
+		polarities |= HDLCD_POLARITY_VSYNC;
+
+	drm_fb_get_bpp_depth(crtc->primary->fb->pixel_format, &depth, &bpp);
+	/* switch to the more useful 'bytes per pixel' HDLCD needs */
+	bpp = (bpp + 7) / 8;
+	line_length = crtc->primary->fb->width * bpp;
+
+	/* Allow max number of outstanding requests and largest burst size */
+	hdlcd_write(hdlcd, HDLCD_REG_BUS_OPTIONS,
+		    HDLCD_BUS_MAX_OUTSTAND | HDLCD_BUS_BURST_16);
+
+	hdlcd_write(hdlcd, HDLCD_REG_FB_LINE_LENGTH, line_length);
+	hdlcd_write(hdlcd, HDLCD_REG_FB_LINE_COUNT,
+				crtc->primary->fb->height - 1);
+	hdlcd_write(hdlcd, HDLCD_REG_FB_LINE_PITCH, line_length);
+	hdlcd_write(hdlcd, HDLCD_REG_V_BACK_PORCH,
+				mode->vtotal - mode->vsync_end - 1);
+	hdlcd_write(hdlcd, HDLCD_REG_V_FRONT_PORCH,
+				mode->vsync_start - mode->vdisplay - 1);
+	hdlcd_write(hdlcd, HDLCD_REG_V_SYNC,
+				mode->vsync_end - mode->vsync_start - 1);
+	hdlcd_write(hdlcd, HDLCD_REG_V_DATA, mode->vdisplay - 1);
+	hdlcd_write(hdlcd, HDLCD_REG_H_BACK_PORCH,
+				mode->htotal - mode->hsync_end - 1);
+	hdlcd_write(hdlcd, HDLCD_REG_H_FRONT_PORCH,
+				mode->hsync_start - mode->hdisplay - 1);
+	hdlcd_write(hdlcd, HDLCD_REG_H_SYNC,
+				mode->hsync_end - mode->hsync_start - 1);
+	hdlcd_write(hdlcd, HDLCD_REG_H_DATA, mode->hdisplay - 1);
+	hdlcd_write(hdlcd, HDLCD_REG_POLARITIES, polarities);
+
+	err = hdlcd_crtc_colour_set(hdlcd, crtc->primary->fb->pixel_format);
+	if (err)
+		return err;
+
+	clk_prepare(hdlcd->clk);
+	clk_set_rate(hdlcd->clk, mode->crtc_clock * 1000);
+	clk_enable(hdlcd->clk);
+
+	hdlcd_set_scanout(hdlcd);
+
+	return 0;
+}
+
+static void hdlcd_crtc_load_lut(struct drm_crtc *crtc)
+{
+}
+
+static const struct drm_crtc_helper_funcs hdlcd_crtc_helper_funcs = {
+	.dpms		= hdlcd_crtc_dpms,
+	.mode_fixup	= hdlcd_crtc_mode_fixup,
+	.prepare	= hdlcd_crtc_prepare,
+	.commit		= hdlcd_crtc_commit,
+	.mode_set	= hdlcd_crtc_mode_set,
+	.load_lut	= hdlcd_crtc_load_lut,
+};
+
+int hdlcd_setup_crtc(struct drm_device *dev)
+{
+	struct hdlcd_drm_private *hdlcd = dev->dev_private;
+	int ret;
+
+	hdlcd->crtc.port = of_graph_get_next_endpoint(dev->platformdev->dev.of_node, NULL);
+	if (!hdlcd->crtc.port)
+		return -ENXIO;
+
+	ret = drm_crtc_init(dev, &hdlcd->crtc, &hdlcd_crtc_funcs);
+	if (ret < 0) {
+		of_node_put(hdlcd->crtc.port);
+		return ret;
+	}
+
+	drm_crtc_helper_add(&hdlcd->crtc, &hdlcd_crtc_helper_funcs);
+	return 0;
+}
+
diff --git a/drivers/gpu/drm/arm/hdlcd_drv.c b/drivers/gpu/drm/arm/hdlcd_drv.c
new file mode 100644
index 0000000..322a429
--- /dev/null
+++ b/drivers/gpu/drm/arm/hdlcd_drv.c
@@ -0,0 +1,490 @@
+/*
+ * Copyright (C) 2013-2015 ARM Limited
+ * Author: Liviu Dudau <Liviu.Dudau at arm.com>
+ *
+ * This file is subject to the terms and conditions of the GNU General Public
+ * License.  See the file COPYING in the main directory of this archive
+ * for more details.
+ *
+ *  ARM HDLCD Driver
+ */
+
+#include <linux/module.h>
+#include <linux/spinlock.h>
+#include <linux/clk.h>
+#include <linux/component.h>
+#include <linux/of_graph.h>
+
+#include <drm/drmP.h>
+#include <drm/drm_crtc.h>
+#include <drm/drm_crtc_helper.h>
+#include <drm/drm_fb_helper.h>
+#include <drm/drm_fb_cma_helper.h>
+#include <drm/drm_gem_cma_helper.h>
+#include <drm/drm_of.h>
+
+#include "hdlcd_drv.h"
+#include "hdlcd_regs.h"
+
+static void hdlcd_setup_mode_config(struct drm_device *dev);
+
+static int compare_dev(struct device *dev, void *data)
+{
+	return dev->of_node == data;
+}
+
+static int hdlcd_unload(struct drm_device *dev)
+{
+	struct hdlcd_drm_private *hdlcd = dev->dev_private;
+
+	drm_kms_helper_poll_fini(dev);
+	if (hdlcd->fbdev)
+		drm_fbdev_cma_fini(hdlcd->fbdev);
+
+	component_unbind_all(dev->dev, dev);
+
+	drm_vblank_cleanup(dev);
+	drm_mode_config_cleanup(dev);
+
+	drm_irq_uninstall(dev);
+
+	if (!IS_ERR(hdlcd->clk))
+		clk_put(hdlcd->clk);
+
+	dma_release_declared_memory(dev->dev);
+	platform_set_drvdata(dev->platformdev, NULL);
+	dev->dev_private = NULL;
+
+	return 0;
+}
+
+static int hdlcd_load(struct drm_device *dev, unsigned long flags)
+{
+	struct platform_device *pdev = dev->platformdev;
+	struct hdlcd_drm_private *hdlcd;
+	struct resource *res;
+	u32 version;
+	int ret;
+
+	hdlcd = devm_kzalloc(dev->dev, sizeof(*hdlcd), GFP_KERNEL);
+	if (!hdlcd)
+		return -ENOMEM;
+
+#ifdef CONFIG_DEBUG_FS
+	atomic_set(&hdlcd->buffer_underrun_count, 0);
+	atomic_set(&hdlcd->bus_error_count, 0);
+	atomic_set(&hdlcd->vsync_count, 0);
+	atomic_set(&hdlcd->dma_end_count, 0);
+#endif
+	platform_set_drvdata(pdev, dev);
+	dev->dev_private = hdlcd;
+
+	res = platform_get_resource(pdev, IORESOURCE_MEM, 0);
+	hdlcd->mmio = devm_ioremap_resource(&pdev->dev, res);
+	if (IS_ERR(hdlcd->mmio)) {
+		DRM_ERROR("failed to map control registers area\n");
+		ret = PTR_ERR(hdlcd->mmio);
+		goto fail;
+	}
+
+	version = hdlcd_read(hdlcd, HDLCD_REG_VERSION);
+	if ((version & HDLCD_PRODUCT_MASK) != HDLCD_PRODUCT_ID) {
+		DRM_ERROR("unknown product id: 0x%x\n", version);
+		ret = -EINVAL;
+		goto fail;
+	}
+	DRM_INFO("found ARM HDLCD version r%dp%d\n",
+		(version & HDLCD_VERSION_MAJOR_MASK) >> 8,
+		version & HDLCD_VERSION_MINOR_MASK);
+
+	/* Get the optional coherent memory resource */
+	res = platform_get_resource(pdev, IORESOURCE_MEM, 1);
+	if (res) {
+		ret = dma_declare_coherent_memory(dev->dev, res->start, res->start,
+					resource_size(res), DMA_MEMORY_MAP);
+		if ((ret & DMA_MEMORY_MAP) == 0) {
+			DRM_ERROR("failed to declare coherent device memory\n");
+			ret = -ENXIO;
+			goto fail;
+		}
+	}
+
+	hdlcd_setup_mode_config(dev);
+
+	hdlcd->clk = clk_get(dev->dev, "pxlclk");
+	if (IS_ERR(hdlcd->clk)) {
+		ret = PTR_ERR(hdlcd->clk);
+		goto fail;
+	}
+
+	ret = hdlcd_setup_crtc(dev);
+	if (ret < 0) {
+		DRM_ERROR("failed to create crtc\n");
+		goto fail;
+	}
+
+	ret = component_bind_all(dev->dev, dev);
+	if (ret) {
+		DRM_ERROR("Failed to bind all components\n");
+		goto fail;
+	}
+
+	drm_kms_helper_poll_init(dev);
+	drm_mode_config_reset(dev);
+
+	ret = drm_irq_install(dev, platform_get_irq(pdev, 0));
+	if (ret < 0) {
+		DRM_ERROR("failed to install IRQ handler\n");
+		goto fail;
+	}
+
+	dev->irq_enabled = true;
+	dev->vblank_disable_allowed = true;
+
+	ret = drm_vblank_init(dev, dev->mode_config.num_crtc);
+	if (ret < 0) {
+		DRM_ERROR("failed to initialise vblank\n");
+		goto fail;
+	}
+	hdlcd->fbdev = drm_fbdev_cma_init(dev, 32,
+					dev->mode_config.num_crtc,
+					dev->mode_config.num_connector);
+
+	if (IS_ERR(hdlcd->fbdev)) {
+		DRM_ERROR("failed to initialise fbdev buffer\n");
+		ret = PTR_ERR(hdlcd->fbdev);
+		hdlcd->fbdev = NULL;
+		goto fail;
+	}
+
+	return 0;
+
+fail:
+	hdlcd_unload(dev);
+
+	return ret;
+}
+
+static void hdlcd_fb_output_poll_changed(struct drm_device *dev)
+{
+	struct hdlcd_drm_private *hdlcd = dev->dev_private;
+
+	if (hdlcd->fbdev) {
+		drm_fbdev_cma_hotplug_event(hdlcd->fbdev);
+	}
+}
+
+static const struct drm_mode_config_funcs hdlcd_mode_config_funcs = {
+	.fb_create = drm_fb_cma_create,
+	.output_poll_changed = hdlcd_fb_output_poll_changed,
+};
+
+static void hdlcd_setup_mode_config(struct drm_device *dev)
+{
+	drm_mode_config_init(dev);
+	dev->mode_config.min_width = 0;
+	dev->mode_config.min_height = 0;
+	dev->mode_config.max_width = HDLCD_MAX_XRES;
+	dev->mode_config.max_height = HDLCD_MAX_YRES;
+	dev->mode_config.funcs = &hdlcd_mode_config_funcs;
+}
+
+static void hdlcd_preclose(struct drm_device *dev, struct drm_file *file)
+{
+}
+
+static void hdlcd_lastclose(struct drm_device *dev)
+{
+	struct hdlcd_drm_private *hdlcd = dev->dev_private;
+
+	drm_fbdev_cma_restore_mode(hdlcd->fbdev);
+}
+
+static irqreturn_t hdlcd_irq(int irq, void *arg)
+{
+	struct drm_device *dev = arg;
+	struct hdlcd_drm_private *hdlcd = dev->dev_private;
+	unsigned long irq_status;
+
+	irq_status = hdlcd_read(hdlcd, HDLCD_REG_INT_STATUS);
+
+#ifdef CONFIG_DEBUG_FS
+	if (irq_status & HDLCD_INTERRUPT_UNDERRUN) {
+		atomic_inc(&hdlcd->buffer_underrun_count);
+	}
+	if (irq_status & HDLCD_INTERRUPT_DMA_END) {
+		atomic_inc(&hdlcd->dma_end_count);
+	}
+	if (irq_status & HDLCD_INTERRUPT_BUS_ERROR) {
+		atomic_inc(&hdlcd->bus_error_count);
+	}
+	if (irq_status & HDLCD_INTERRUPT_VSYNC) {
+		atomic_inc(&hdlcd->vsync_count);
+	}
+#endif
+	if (irq_status & HDLCD_INTERRUPT_VSYNC) {
+		struct drm_pending_vblank_event *event;
+		unsigned long flags;
+
+		hdlcd_set_scanout(hdlcd);
+
+		drm_handle_vblank(dev, 0);
+
+		spin_lock_irqsave(&dev->event_lock, flags);
+		if (hdlcd->event) {
+			event = hdlcd->event;
+			hdlcd->event = NULL;
+			drm_send_vblank_event(dev, 0, event);
+			drm_vblank_put(dev, 0);
+		}
+		spin_unlock_irqrestore(&dev->event_lock, flags);
+	}
+
+	/* acknowledge interrupt(s) */
+	hdlcd_write(hdlcd, HDLCD_REG_INT_CLEAR, irq_status);
+
+	return IRQ_HANDLED;
+}
+
+static void hdlcd_irq_preinstall(struct drm_device *dev)
+{
+	struct hdlcd_drm_private *hdlcd = dev->dev_private;
+	/* Ensure interrupts are disabled */
+	hdlcd_write(hdlcd, HDLCD_REG_INT_MASK, 0);
+	hdlcd_write(hdlcd, HDLCD_REG_INT_CLEAR, ~0);
+}
+
+static int hdlcd_irq_postinstall(struct drm_device *dev)
+{
+#ifdef CONFIG_DEBUG_FS
+	struct hdlcd_drm_private *hdlcd = dev->dev_private;
+	unsigned long irq_mask = hdlcd_read(hdlcd, HDLCD_REG_INT_MASK);
+
+	/* enable debug interrupts */
+	irq_mask |= HDLCD_DEBUG_INT_MASK;
+
+	hdlcd_write(hdlcd, HDLCD_REG_INT_MASK, irq_mask);
+#endif
+	return 0;
+}
+
+static void hdlcd_irq_uninstall(struct drm_device *dev)
+{
+	struct hdlcd_drm_private *hdlcd = dev->dev_private;
+	/* disable all the interrupts that we might have enabled */
+	unsigned long irq_mask = hdlcd_read(hdlcd, HDLCD_REG_INT_MASK);
+
+#ifdef CONFIG_DEBUG_FS
+	/* disable debug interrupts */
+	irq_mask &= ~HDLCD_DEBUG_INT_MASK;
+#endif
+
+	/* disable vsync interrupts */
+	irq_mask &= ~HDLCD_INTERRUPT_VSYNC;
+
+	hdlcd_write(hdlcd, HDLCD_REG_INT_MASK, irq_mask);
+}
+
+static int hdlcd_enable_vblank(struct drm_device *dev, int crtc)
+{
+	struct hdlcd_drm_private *hdlcd = dev->dev_private;
+	unsigned int mask = hdlcd_read(hdlcd, HDLCD_REG_INT_MASK);
+
+	hdlcd_write(hdlcd, HDLCD_REG_INT_MASK, mask | HDLCD_INTERRUPT_VSYNC);
+
+	return 0;
+}
+
+static void hdlcd_disable_vblank(struct drm_device *dev, int crtc)
+{
+	struct hdlcd_drm_private *hdlcd = dev->dev_private;
+	unsigned int mask = hdlcd_read(hdlcd, HDLCD_REG_INT_MASK);
+
+	hdlcd_write(hdlcd, HDLCD_REG_INT_MASK, mask & ~HDLCD_INTERRUPT_VSYNC);
+}
+
+#ifdef CONFIG_DEBUG_FS
+static int hdlcd_show_underrun_count(struct seq_file *m, void *arg)
+{
+	struct drm_info_node *node = (struct drm_info_node *)m->private;
+	struct drm_device *dev = node->minor->dev;
+	struct hdlcd_drm_private *hdlcd = dev->dev_private;
+
+	seq_printf(m, "underrun : %d\n", atomic_read(&hdlcd->buffer_underrun_count));
+	seq_printf(m, "dma_end  : %d\n", atomic_read(&hdlcd->dma_end_count));
+	seq_printf(m, "bus_error: %d\n", atomic_read(&hdlcd->bus_error_count));
+	seq_printf(m, "vsync    : %d\n", atomic_read(&hdlcd->vsync_count));
+	return 0;
+}
+
+static struct drm_info_list hdlcd_debugfs_list[] = {
+	{ "interrupt_count", hdlcd_show_underrun_count, 0 },
+};
+
+static int hdlcd_debugfs_init(struct drm_minor *minor)
+{
+	return drm_debugfs_create_files(hdlcd_debugfs_list,
+		ARRAY_SIZE(hdlcd_debugfs_list),	minor->debugfs_root, minor);
+}
+
+static void hdlcd_debugfs_cleanup(struct drm_minor *minor)
+{
+	drm_debugfs_remove_files(hdlcd_debugfs_list,
+		ARRAY_SIZE(hdlcd_debugfs_list), minor);
+}
+#endif
+
+static const struct file_operations fops = {
+	.owner		= THIS_MODULE,
+	.open		= drm_open,
+	.release	= drm_release,
+	.unlocked_ioctl	= drm_ioctl,
+#ifdef CONFIG_COMPAT
+	.compat_ioctl	= drm_compat_ioctl,
+#endif
+	.poll		= drm_poll,
+	.read		= drm_read,
+	.llseek		= no_llseek,
+	.mmap		= drm_gem_cma_mmap,
+};
+
+static struct drm_driver hdlcd_driver = {
+	.driver_features	= DRIVER_HAVE_IRQ | DRIVER_GEM |
+					DRIVER_MODESET | DRIVER_PRIME,
+	.load			= hdlcd_load,
+	.unload			= hdlcd_unload,
+	.preclose		= hdlcd_preclose,
+	.lastclose		= hdlcd_lastclose,
+	.irq_handler		= hdlcd_irq,
+	.irq_preinstall		= hdlcd_irq_preinstall,
+	.irq_postinstall	= hdlcd_irq_postinstall,
+	.irq_uninstall		= hdlcd_irq_uninstall,
+	.get_vblank_counter	= drm_vblank_count,
+	.enable_vblank		= hdlcd_enable_vblank,
+	.disable_vblank		= hdlcd_disable_vblank,
+	.gem_free_object	= drm_gem_cma_free_object,
+	.gem_vm_ops		= &drm_gem_cma_vm_ops,
+	.dumb_create		= drm_gem_cma_dumb_create,
+	.dumb_map_offset	= drm_gem_cma_dumb_map_offset,
+	.dumb_destroy		= drm_gem_dumb_destroy,
+	.prime_handle_to_fd	= drm_gem_prime_handle_to_fd,
+	.prime_fd_to_handle	= drm_gem_prime_fd_to_handle,
+	.gem_prime_export	= drm_gem_prime_export,
+	.gem_prime_import	= drm_gem_prime_import,
+	.gem_prime_get_sg_table	= drm_gem_cma_prime_get_sg_table,
+	.gem_prime_vmap		= drm_gem_cma_prime_vmap,
+	.gem_prime_vunmap	= drm_gem_cma_prime_vunmap,
+	.gem_prime_mmap		= drm_gem_cma_prime_mmap,
+#ifdef CONFIG_DEBUG_FS
+	.debugfs_init		= hdlcd_debugfs_init,
+	.debugfs_cleanup	= hdlcd_debugfs_cleanup,
+#endif
+	.fops			= &fops,
+	.name			= "hdlcd",
+	.desc			= "ARM HDLCD Controller DRM",
+	.date			= "20130505",
+	.major			= 1,
+	.minor			= 0,
+};
+
+static int hdlcd_add_components(struct device *dev, struct master *master)
+{
+	struct device_node *port, *ep = NULL;
+	int ret = -ENXIO;
+
+	if (!dev->of_node)
+		return -ENODEV;
+
+	do {
+		ep = of_graph_get_next_endpoint(dev->of_node, ep);
+		if (!ep)
+			break;
+
+		if (!of_device_is_available(ep)) {
+			of_node_put(ep);
+			continue;
+		}
+
+		port = of_graph_get_remote_port_parent(ep);
+		of_node_put(ep);
+		if (!port || !of_device_is_available(port)) {
+			of_node_put(port);
+			continue;
+		}
+
+		ret = component_master_add_child(master, compare_dev, port);
+		of_node_put(port);
+	} while (1);
+
+	return ret;
+}
+
+static int hdlcd_drm_bind(struct device *dev)
+{
+	return drm_platform_init(&hdlcd_driver, to_platform_device(dev));
+}
+
+static void hdlcd_drm_unbind(struct device *dev)
+{
+	drm_put_dev(dev_get_drvdata(dev));
+}
+
+static const struct component_master_ops hdlcd_master_ops = {
+	.add_components	= hdlcd_add_components,
+	.bind		= hdlcd_drm_bind,
+	.unbind		= hdlcd_drm_unbind,
+};
+
+static int hdlcd_probe(struct platform_device *pdev)
+{
+	return component_master_add(&pdev->dev, &hdlcd_master_ops);
+}
+
+static int hdlcd_remove(struct platform_device *pdev)
+{
+	component_master_del(&pdev->dev, &hdlcd_master_ops);
+	return 0;
+}
+
+static const struct of_device_id  hdlcd_of_match[] = {
+	{ .compatible	= "arm,hdlcd" },
+	{},
+};
+MODULE_DEVICE_TABLE(of, hdlcd_of_match);
+
+static struct platform_driver hdlcd_platform_driver = {
+	.probe		= hdlcd_probe,
+	.remove		= hdlcd_remove,
+	.driver	= {
+		.name		= "hdlcd",
+		.owner		= THIS_MODULE,
+		.of_match_table	= hdlcd_of_match,
+	},
+};
+
+static int __init hdlcd_init(void)
+{
+	int err = platform_driver_register(&hdlcd_platform_driver);
+
+#ifdef HDLCD_COUNT_BUFFERUNDERRUNS
+	if (!err)
+		hdlcd_underrun_init();
+#endif
+
+	return err;
+}
+
+static void __exit hdlcd_exit(void)
+{
+#ifdef HDLCD_COUNT_BUFFERUNDERRUNS
+	hdlcd_underrun_close();
+#endif
+	platform_driver_unregister(&hdlcd_platform_driver);
+}
+
+module_init(hdlcd_init);
+module_exit(hdlcd_exit);
+
+MODULE_AUTHOR("Liviu Dudau");
+MODULE_DESCRIPTION("ARM HDLCD DRM driver");
+MODULE_LICENSE("GPL v2");
diff --git a/drivers/gpu/drm/arm/hdlcd_drv.h b/drivers/gpu/drm/arm/hdlcd_drv.h
new file mode 100644
index 0000000..31866fc
--- /dev/null
+++ b/drivers/gpu/drm/arm/hdlcd_drv.h
@@ -0,0 +1,51 @@
+/*
+ *  ARM HDLCD Controller register definition
+ */
+
+#ifndef __HDLCD_DRV_H__
+#define __HDLCD_DRV_H__
+
+struct hdlcd_drm_private {
+	void __iomem			*mmio;
+	struct clk			*clk;
+	struct drm_fbdev_cma		*fbdev;
+	struct drm_framebuffer		*fb;
+	struct drm_pending_vblank_event	*event;
+	struct drm_crtc			crtc;
+#ifdef CONFIG_DEBUG_FS
+	atomic_t buffer_underrun_count;
+	atomic_t bus_error_count;
+	atomic_t vsync_count;
+	atomic_t dma_end_count;
+#endif
+	int dpms;
+};
+
+#define crtc_to_hdlcd_priv(x)	container_of(x, struct hdlcd_drm_private, crtc)
+
+static inline void
+hdlcd_write(struct hdlcd_drm_private *hdlcd, unsigned int reg, u32 value)
+{
+	writel(value, hdlcd->mmio + reg);
+}
+
+static inline u32 hdlcd_read(struct hdlcd_drm_private *hdlcd, unsigned int reg)
+{
+	return readl(hdlcd->mmio + reg);
+}
+
+/*
+ * Developers using HDLCD may wish to enable these settings if
+ * display disruption is apparent and you suspect HDLCD
+ * access to RAM may be starved.
+ *
+ * Turn HDLCD default color to red instead of default black so
+ * that it's easier to see data underruns (compared to other
+ * visual disruptions)
+ */
+/* #define HDLCD_SHOW_UNDERRUN */
+
+int hdlcd_setup_crtc(struct drm_device *dev);
+void hdlcd_set_scanout(struct hdlcd_drm_private *hdlcd);
+
+#endif /* __HDLCD_DRV_H__ */
diff --git a/drivers/gpu/drm/arm/hdlcd_regs.h b/drivers/gpu/drm/arm/hdlcd_regs.h
new file mode 100644
index 0000000..66799eb
--- /dev/null
+++ b/drivers/gpu/drm/arm/hdlcd_regs.h
@@ -0,0 +1,87 @@
+/*
+ * Copyright (C) 2013,2014 ARM Limited
+ *
+ * This file is subject to the terms and conditions of the GNU General Public
+ * License.  See the file COPYING in the main directory of this archive
+ * for more details.
+ *
+ *  ARM HDLCD Controller register definition
+ */
+
+#ifndef __HDLCD_REGS_H__
+#define __HDLCD_REGS_H__
+
+/* register offsets */
+#define HDLCD_REG_VERSION		0x0000	/* ro */
+#define HDLCD_REG_INT_RAWSTAT		0x0010	/* rw */
+#define HDLCD_REG_INT_CLEAR		0x0014	/* wo */
+#define HDLCD_REG_INT_MASK		0x0018	/* rw */
+#define HDLCD_REG_INT_STATUS		0x001c	/* ro */
+#define HDLCD_REG_FB_BASE		0x0100	/* rw */
+#define HDLCD_REG_FB_LINE_LENGTH	0x0104	/* rw */
+#define HDLCD_REG_FB_LINE_COUNT		0x0108	/* rw */
+#define HDLCD_REG_FB_LINE_PITCH		0x010c	/* rw */
+#define HDLCD_REG_BUS_OPTIONS		0x0110	/* rw */
+#define HDLCD_REG_V_SYNC		0x0200	/* rw */
+#define HDLCD_REG_V_BACK_PORCH		0x0204	/* rw */
+#define HDLCD_REG_V_DATA		0x0208	/* rw */
+#define HDLCD_REG_V_FRONT_PORCH		0x020c	/* rw */
+#define HDLCD_REG_H_SYNC		0x0210	/* rw */
+#define HDLCD_REG_H_BACK_PORCH		0x0214	/* rw */
+#define HDLCD_REG_H_DATA		0x0218	/* rw */
+#define HDLCD_REG_H_FRONT_PORCH		0x021c	/* rw */
+#define HDLCD_REG_POLARITIES		0x0220	/* rw */
+#define HDLCD_REG_COMMAND		0x0230	/* rw */
+#define HDLCD_REG_PIXEL_FORMAT		0x0240	/* rw */
+#define HDLCD_REG_RED_SELECT		0x0244	/* rw */
+#define HDLCD_REG_GREEN_SELECT		0x0248	/* rw */
+#define HDLCD_REG_BLUE_SELECT		0x024c	/* rw */
+
+/* version */
+#define HDLCD_PRODUCT_ID		0x1CDC0000
+#define HDLCD_PRODUCT_MASK		0xFFFF0000
+#define HDLCD_VERSION_MAJOR_MASK	0x0000FF00
+#define HDLCD_VERSION_MINOR_MASK	0x000000FF
+
+/* interrupts */
+#define HDLCD_INTERRUPT_DMA_END		(1 << 0)
+#define HDLCD_INTERRUPT_BUS_ERROR	(1 << 1)
+#define HDLCD_INTERRUPT_VSYNC		(1 << 2)
+#define HDLCD_INTERRUPT_UNDERRUN	(1 << 3)
+#define HDLCD_DEBUG_INT_MASK		(HDLCD_INTERRUPT_DMA_END |  \
+					HDLCD_INTERRUPT_BUS_ERROR | \
+					HDLCD_INTERRUPT_UNDERRUN)
+
+/* polarities */
+#define HDLCD_POLARITY_VSYNC		(1 << 0)
+#define HDLCD_POLARITY_HSYNC		(1 << 1)
+#define HDLCD_POLARITY_DATAEN		(1 << 2)
+#define HDLCD_POLARITY_DATA		(1 << 3)
+#define HDLCD_POLARITY_PIXELCLK		(1 << 4)
+
+/* commands */
+#define HDLCD_COMMAND_DISABLE		(0 << 0)
+#define HDLCD_COMMAND_ENABLE		(1 << 0)
+
+/* pixel format */
+#define HDLCD_PIXEL_FMT_LITTLE_ENDIAN	(0 << 31)
+#define HDLCD_PIXEL_FMT_BIG_ENDIAN	(1 << 31)
+#define HDLCD_BYTES_PER_PIXEL_MASK	(3 << 3)
+
+/* bus options */
+#define HDLCD_BUS_BURST_MASK		0x01f
+#define HDLCD_BUS_MAX_OUTSTAND		0xf00
+#define HDLCD_BUS_BURST_NONE		(0 << 0)
+#define HDLCD_BUS_BURST_1		(1 << 0)
+#define HDLCD_BUS_BURST_2		(1 << 1)
+#define HDLCD_BUS_BURST_4		(1 << 2)
+#define HDLCD_BUS_BURST_8		(1 << 3)
+#define HDLCD_BUS_BURST_16		(1 << 4)
+
+/* Max resolution supported is 4096x4096, 32bpp */
+#define HDLCD_MAX_XRES			4096
+#define HDLCD_MAX_YRES			4096
+
+#define NR_PALETTE			256
+
+#endif /* __HDLCD_REGS_H__ */
-- 
2.4.6



From julien.grall at citrix.com  Wed Aug  5 07:30:11 2015
From: julien.grall at citrix.com (Julien Grall)
Date: Wed, 5 Aug 2015 15:30:11 +0100
Subject: [Xen-devel] [PATCH v2 02/20] xen: Introduce a function to split
 a Linux page into Xen page
In-Reply-To: <55B20F1F.60902@citrix.com>
References: <1436474552-31789-1-git-send-email-julien.grall@citrix.com>
 <1436474552-31789-3-git-send-email-julien.grall@citrix.com>
 <55B205FB.5080209@citrix.com> <55B20B56.7020605@citrix.com>
 <55B20F1F.60902@citrix.com>
Message-ID: <55C21DF3.2090201@citrix.com>

Hi David,

On 24/07/15 11:10, David Vrabel wrote:
> On 24/07/15 10:54, Julien Grall wrote:
>> On 24/07/15 10:31, David Vrabel wrote:
>>> On 09/07/15 21:42, Julien Grall wrote:
>>>> The Xen interface is always using 4KB page. This means that a Linux page
>>>> may be split across multiple Xen page when the page granularity is not
>>>> the same.
>>>>
>>>> This helper will break down a Linux page into 4KB chunk and call the
>>>> helper on each of them.
>>> [...]
>>>> --- a/include/xen/page.h
>>>> +++ b/include/xen/page.h
>>>> @@ -39,4 +39,24 @@ struct xen_memory_region xen_extra_mem[XEN_EXTRA_MEM_MAX_REGIONS];
>>>>  
>>>>  extern unsigned long xen_released_pages;
>>>>  
>>>> +typedef int (*xen_pfn_fn_t)(struct page *page, unsigned long pfn, void *data);
>>>> +
>>>> +/* Break down the page in 4KB granularity and call fn foreach xen pfn */
>>>> +static inline int xen_apply_to_page(struct page *page, xen_pfn_fn_t fn,
>>>> +				    void *data)
>>>
>>> I think this should be outlined (unless you have measurements that
>>> support making it inlined).
>>
>> I don't have any performance measurements. Although, when Linux is using
>> 4KB page granularity, the loop in this helper will be dropped by the
>> helper. The code would look like:
>>
>> unsigned long pfn = xen_page_to_pfn(page);
>>
>> ret = fn(page, fn, data);
>> if (ret)
>>   return ret;
>>
>> The compiler could even inline the callback (fn). So it drops 2
>> functions call.
> 
> Ok, keep it inlined.
> 
>>> Also perhaps make it
>>>
>>> int xen_for_each_gfn(struct page *page,
>>>                      xen_gfn_fn_t fn, void *data);
>>
>> gfn standing for Guest Frame Number right?
> 
> Yes.  This suggestion is just changing the name to make it more obvious
> what it does.

Thinking more about this suggestion. The callback (fn) is getting a 4K
PFN in parameter and not a GFN.

This is because the balloon code seems to require having a 4K PFN in
hand in few places. For instance XENMEM_populate_physmap and
HYPERVISOR_update_va_mapping.

Although, I'm not sure to understand the difference between GMFN, and
GPFN in the hypercall doc.

Regards,

-- 
Julien Grall


From robh at kernel.org  Wed Aug  5 07:45:22 2015
From: robh at kernel.org (Rob Herring)
Date: Wed, 5 Aug 2015 09:45:22 -0500
Subject: [PATCH 6/9] ARM: domain: Add platform handlers for CPU PM domains
In-Reply-To: <1438731339-58317-7-git-send-email-lina.iyer@linaro.org>
References: <1438731339-58317-1-git-send-email-lina.iyer@linaro.org>
 <1438731339-58317-7-git-send-email-lina.iyer@linaro.org>
Message-ID: <CAL_JsqKWekSGiFbZz6++3ibAzY_8Y6+0nOBQinFVw4cBk6JvEw@mail.gmail.com>

On Tue, Aug 4, 2015 at 6:35 PM, Lina Iyer <lina.iyer at linaro.org> wrote:
> In addition to the common power up/down actions of CPU PM domain core,
> platforms may have additional configuration before the CPU domain can be
> powered off or considered active. Allow platform drivers to register
> handlers for CPU PM domains.
>
> Platform drivers may register their callbacks against a compatible
> string defined by their PM domain provider device node in the DT. At
> domain init, the platform driver can initialize the platform specific
> genpd attributes. The init callback would need to return successfully,
> for the platform power_on/off handlers to be registered with the CPU PM
> domain.
>
> The code uses __init section to reduce memory needed for platform
> handlers and therefore can be freed after the driver is initialized, a
> desirable outcome for single kernel image.

[...]

> diff --git a/arch/arm/include/asm/arm-pd.h b/arch/arm/include/asm/arm-pd.h
> new file mode 100644
> index 0000000..fc44abf
> --- /dev/null
> +++ b/arch/arm/include/asm/arm-pd.h
> @@ -0,0 +1,30 @@
> +/*
> + * linux/arch/arm/include/asm/arm-pd.h
> + *
> + * Copyright (C) 2015 Linaro Ltd.
> + *
> + * 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.
> + */
> +
> +#ifndef __ARM_PD_H__
> +#define __ARM_PD_H__
> +
> +struct of_arm_pd_ops {
> +       int (*init)(struct device_node *dn, struct generic_pm_domain *d);
> +       int (*power_on)(struct generic_pm_domain *d);
> +       int (*power_off)(struct generic_pm_domain *d);
> +};
> +
> +struct of_arm_pd_method {
> +       const char *handle;
> +       struct of_arm_pd_ops *ops;
> +};
> +
> +#define ARM_PD_METHOD_OF_DECLARE(_name, _handle, _ops) \
> +       static const struct of_arm_pd_method __arm_pd_method_of_table_##_name \
> +       __used __section(__arm_pd_method_of_table)              \
> +       = { .handle = _handle, .ops = _ops }

AFAICT, you are not using this in this series. You should add it when
you have a user.

Ideally, we keep some amount of uniformity across various *_OF_DECLARE
which is why we have OF_DECLARE_1 and OF_DECLARE_2. This makes all the
sections just arrays of struct of_device_id. Not all users follow
this, but most do. So instead of putting the ops in here, platforms
can provide a function callback which can then set the ops. Then you
also don't need the .init() ops function as the callback function can
do any initialization too.

Rob


From Suzuki.Poulose at arm.com  Wed Aug  5 07:58:51 2015
From: Suzuki.Poulose at arm.com (Suzuki K. Poulose)
Date: Wed, 05 Aug 2015 15:58:51 +0100
Subject: [RFC PATCH 05/10] arm64: Keep track of CPU feature registers
In-Reply-To: <1437731037-25795-6-git-send-email-suzuki.poulose@arm.com>
References: <1437731037-25795-1-git-send-email-suzuki.poulose@arm.com>
 <1437731037-25795-6-git-send-email-suzuki.poulose@arm.com>
Message-ID: <55C224AB.8020402@arm.com>

On 24/07/15 10:43, Suzuki K. Poulose wrote:
> From: "Suzuki K. Poulose" <suzuki.poulose at arm.com>
>
> This patch adds an infrastructure to keep track of the CPU feature
> registers on the system. This patch also consolidates the cpuinfo
> SANITY checks which ensures that we don't have conflicting feature
> supports across the CPUs.
>
> Each register has a set of feature bits defined by the architecture.
> We define the following attributes:
>
>   1) strict - If strict matching is required for the field across the
>      all the CPUs for SANITY checks.
>   2) visible - If the field is exposed to the userspace (See documentation
>      for more details).
>
> The default 'safe' value for the feature is also defined, which will be
> used:
>   1) To set the value for a 'discrete' feature with conflicting values.
>   2) To set the value for an 'invisible' feature for the userspace.
>
> The infrastructure keeps track of the following values for a feature
> register:
>   - user visible value
>   - system wide safe value
>
> Signed-off-by: Suzuki K. Poulose <suzuki.poulose at arm.com>
> ---
>   arch/arm64/include/asm/cpu.h |  149 ++++++++++++++++
>   arch/arm64/kernel/cpuinfo.c  |  399 ++++++++++++++++++++++++++++++++++++++----
>   2 files changed, 511 insertions(+), 37 deletions(-)
>
> diff --git a/arch/arm64/include/asm/cpu.h b/arch/arm64/include/asm/cpu.h
> index a34de72..c7b0b89 100644
> --- a/arch/arm64/include/asm/cpu.h
> +++ b/arch/arm64/include/asm/cpu.h
...
> diff --git a/arch/arm64/kernel/cpuinfo.c b/arch/arm64/kernel/cpuinfo.c
> index a13468b..ae2a37f 100644
> --- a/arch/arm64/kernel/cpuinfo.c
> +++ b/arch/arm64/kernel/cpuinfo.c
> @@ -31,6 +31,207 @@
>   #include <linux/sched.h>
>   #include <linux/smp.h>
>
...
> -#define CHECK_MASK(field, mask, boot, cur, cpu) \
> -       check_reg_mask(#field, mask, (boot)->reg_ ## field, (cur)->reg_ ## field, cpu)
> -
> -#define CHECK(field, boot, cur, cpu) \
> -       CHECK_MASK(field, ~0ULL, boot, cur, cpu)
> +#define CHECK_CPUINFO(field)                                                           \
> +       ({                                                                              \
> +               int __rc = 0;                                                           \
> +               struct arm64_ftr_reg *__regp = get_arm64_sys_reg(sys_ ## field);        \
> +               if (__regp) {                                                           \
> +                       __rc = check_reg_mask(__regp,                                   \
> +                                               (boot)->reg_ ## field,                  \
> +                                               (cur)->reg_ ## field, cpu);             \
> +                       update_cpu_ftr_reg(__regp, cur->reg_ ## field, cpu);            \
> +               }                                                                       \
> +               __rc;                                                                   \
> +       })
>
>   /*
>    * Verify that CPUs don't have unexpected differences that will cause problems.
> @@ -123,17 +448,17 @@ static void cpuinfo_sanity_check(struct cpuinfo_arm64 *cur)
>           * caches should look identical. Userspace JITs will make use of
>           * *minLine.
>           */
> -       diff |= CHECK_MASK(ctr, 0xffff3fff, boot, cur, cpu);
> +       diff |= CHECK_CPUINFO(ctr);
>
>          /*
>           * Userspace may perform DC ZVA instructions. Mismatched block sizes
>           * could result in too much or too little memory being zeroed if a
>           * process is preempted and migrated between CPUs.
>           */
> -       diff |= CHECK(dczid, boot, cur, cpu);
> +       diff |= CHECK_CPUINFO(dczid);
>
>          /* If different, timekeeping will be broken (especially with KVM) */
> -       diff |= CHECK(cntfrq, boot, cur, cpu);
> +       diff |= CHECK_CPUINFO(cntfrq);
>
>          /*
>           * The kernel uses self-hosted debug features and expects CPUs to
> @@ -141,15 +466,15 @@ static void cpuinfo_sanity_check(struct cpuinfo_arm64 *cur)
>           * and BRPs to be identical.
>           * ID_AA64DFR1 is currently RES0.
>           */
> -       diff |= CHECK(id_aa64dfr0, boot, cur, cpu);
> -       diff |= CHECK(id_aa64dfr1, boot, cur, cpu);
> +       diff |= CHECK_CPUINFO(id_aa64dfr0);
> +       diff |= CHECK_CPUINFO(id_aa64dfr1);
>
>          /*
>           * Even in big.LITTLE, processors should be identical instruction-set
>           * wise.
>           */
> -       diff |= CHECK(id_aa64isar0, boot, cur, cpu);
> -       diff |= CHECK(id_aa64isar1, boot, cur, cpu);
> +       diff |= CHECK_CPUINFO(id_aa64isar0);
> +       diff |= CHECK_CPUINFO(id_aa64isar1);
>
>          /*
>           * Differing PARange support is fine as long as all peripherals and
> @@ -157,42 +482,42 @@ static void cpuinfo_sanity_check(struct cpuinfo_arm64 *cur)
>           * Linux should not care about secure memory.
>           * ID_AA64MMFR1 is currently RES0.
>           */
> -       diff |= CHECK_MASK(id_aa64mmfr0, 0xffffffffffff0ff0, boot, cur, cpu);
> -       diff |= CHECK(id_aa64mmfr1, boot, cur, cpu);
> +       diff |= CHECK_CPUINFO(id_aa64mmfr0);
> +       diff |= CHECK_CPUINFO(id_aa64mmfr1);
>
>          /*
>           * EL3 is not our concern.
>           * ID_AA64PFR1 is currently RES0.
>           */
> -       diff |= CHECK_MASK(id_aa64pfr0, 0xffffffffffff0fff, boot, cur, cpu);
> -       diff |= CHECK(id_aa64pfr1, boot, cur, cpu);
> +       diff |= CHECK_CPUINFO(id_aa64pfr0);
> +       diff |= CHECK_CPUINFO(id_aa64pfr1);
>
>          /*
>           * If we have AArch32, we care about 32-bit features for compat. These
>           * registers should be RES0 otherwise.
>           */
> -       diff |= CHECK(id_dfr0, boot, cur, cpu);
> -       diff |= CHECK(id_isar0, boot, cur, cpu);
> -       diff |= CHECK(id_isar1, boot, cur, cpu);
> -       diff |= CHECK(id_isar2, boot, cur, cpu);
> -       diff |= CHECK(id_isar3, boot, cur, cpu);
> -       diff |= CHECK(id_isar4, boot, cur, cpu);
> -       diff |= CHECK(id_isar5, boot, cur, cpu);
> +       diff |= CHECK_CPUINFO(id_dfr0);
> +       diff |= CHECK_CPUINFO(id_isar0);
> +       diff |= CHECK_CPUINFO(id_isar1);
> +       diff |= CHECK_CPUINFO(id_isar2);
> +       diff |= CHECK_CPUINFO(id_isar3);
> +       diff |= CHECK_CPUINFO(id_isar4);
> +       diff |= CHECK_CPUINFO(id_isar5);
>          /*
>           * Regardless of the value of the AuxReg field, the AIFSR, ADFSR, and
>           * ACTLR formats could differ across CPUs and therefore would have to
>           * be trapped for virtualization anyway.
>           */
> -       diff |= CHECK_MASK(id_mmfr0, 0xff0fffff, boot, cur, cpu);
> -       diff |= CHECK(id_mmfr1, boot, cur, cpu);
> -       diff |= CHECK(id_mmfr2, boot, cur, cpu);
> -       diff |= CHECK(id_mmfr3, boot, cur, cpu);
> -       diff |= CHECK(id_pfr0, boot, cur, cpu);
> -       diff |= CHECK(id_pfr1, boot, cur, cpu);
> +       diff |= CHECK_CPUINFO(id_mmfr0);
> +       diff |= CHECK_CPUINFO(id_mmfr1);
> +       diff |= CHECK_CPUINFO(id_mmfr2);
> +       diff |= CHECK_CPUINFO(id_mmfr3);
> +       diff |= CHECK_CPUINFO(id_pfr0);
> +       diff |= CHECK_CPUINFO(id_pfr1);
>
> -       diff |= CHECK(mvfr0, boot, cur, cpu);
> -       diff |= CHECK(mvfr1, boot, cur, cpu);
> -       diff |= CHECK(mvfr2, boot, cur, cpu);
> +       diff |= CHECK_CPUINFO(mvfr0);
> +       diff |= CHECK_CPUINFO(mvfr1);
> +       diff |= CHECK_CPUINFO(mvfr2);
>
>          /*
>           * Mismatched CPU features are a recipe for disaster. Don't even
> @@ -239,7 +564,7 @@ static void __cpuinfo_store_cpu(struct cpuinfo_arm64 *info)
>          cpuinfo_detect_icache_policy(info);
>
>          check_local_cpu_errata();
> -       check_local_cpu_features();
> +       cpuinfo_sanity_check(info);
These two changes shouldn't be there, I have fixed it locally.
>          update_cpu_features(info);
>   }
>
> @@ -247,13 +572,13 @@ void cpuinfo_store_cpu(void)
>   {
>          struct cpuinfo_arm64 *info = this_cpu_ptr(&cpu_data);
>          __cpuinfo_store_cpu(info);
> -       cpuinfo_sanity_check(info);
As above, this line should be retained here.
>   }
>
>   void __init cpuinfo_store_boot_cpu(void)
>   {
>          struct cpuinfo_arm64 *info = &per_cpu(cpu_data, 0);
>          __cpuinfo_store_cpu(info);
> +       init_cpu_ftrs(info);

Thanks
Suzuki



From kishon at ti.com  Wed Aug  5 08:00:52 2015
From: kishon at ti.com (Kishon Vijay Abraham I)
Date: Wed, 5 Aug 2015 20:30:52 +0530
Subject: [PATCH 00/11] omap_hsmmc: voltage switching and tuning
In-Reply-To: <20150805104355.GE16878@atomide.com>
References: <1438242394-25599-1-git-send-email-kishon@ti.com>
 <20150805104355.GE16878@atomide.com>
Message-ID: <55C22524.5050304@ti.com>

Hi,

On Wednesday 05 August 2015 04:13 PM, Tony Lindgren wrote:
> * Kishon Vijay Abraham I <kishon at ti.com> [150730 00:49]:
>> Patch series implements voltage switching and tuning for omap_hsmmc
>> driver.
>>
>> Did basic read/write test in J6, J6 Eco, Beagle-x15, AM437x EVM,
>> Beaglebone black, OMAP5 uEVM and OMAP4 PANDA.
> 
> Your tests are missing omap3?

I don't have one at my disposal :-( I'll try to find one and add omap3 tests.
> 
> I suggest you add some omap3 tests in general as otherwise you are
> only testing a subset of the driver features and completely missing
> things like rutnime PM and save and restore for the deeper idle
> states.

yeah, I'll do those tests and re-post the series.

Thanks
Kishon



From raghumag at gmail.com  Wed Aug  5 08:02:57 2015
From: raghumag at gmail.com (raghu MG)
Date: Wed, 5 Aug 2015 20:32:57 +0530
Subject: Armadaxp GPIO interrupts
In-Reply-To: <20150804153439.GA28673@lunn.ch>
References: <CAG1O52Xg88OsifBzmpSdqvC8wQaOW78nC9nnfxugFv1VU1m1LQ@mail.gmail.com>
 <20150804153439.GA28673@lunn.ch>
Message-ID: <CAG1O52XtYJho9M4TggtvzdY8HnXhpjkX79FFKRQMyyw=KhgSgQ@mail.gmail.com>

Hi Andrew,

The issue I found was  irq_alloc_descs is called twice
1st time inside   mvebu_gpio_probe & 2nd time inside irq_domain_add_simple.

The warning is thrown up when irq_alloc_descs is called 2nd
time(irq_domain_add_simple) & bitmap_find_next_zero_area gives new
value of start which is not equal to irq & the following condition
returns with error.

irq_alloc_descs(....)
.................
....................
..............
start = bitmap_find_next_zero_area(
allocated_irqs, IRQ_BITMAP_BITS,
                                           from, cnt, 0);
ret=-EEXIST;
if (irq >=0 && start != irq){
                goto err;
        }
...........................
................
err:
       mutex_unlock(&sparse_irq_lock);
        return ret;


I could bypass the error/warning by giving calling
irq_domain_add_simple(np, mvchip->chip.ngpio,
                                               0,
                                               &irq_domain_simple_ops,
                                               mvchip);
I  passed zero instead of mvchip->irqbase as first_irq .
The warning is not appearing.& I think driver is registered in kernel.

But driver & gpio entry is not found in /proc/interrupts.

The GPIO ISR is not getting invoked by driver.
But I wrote a simple module where I register simple handler & then
both mvebu_gpio_irq_handler & modules registered handler is called.

My doubt is whether the gpio-driver in the kernel needs bit more
tweaking to suit the board & devices connected to gpio.

I would appreciate bit of guidance here

On Tue, Aug 4, 2015 at 9:04 PM, Andrew Lunn <andrew at lunn.ch> wrote:
> On Tue, Aug 04, 2015 at 08:52:17PM +0530, raghu MG wrote:
>> Hello,
>>
>> I am working on a card which as GPIOs connected to external I/O's. The
>> board consists of ARMADAXP 78460 host cpu.
>>
>> Board currently runs Linux-4.1 with modified  armada-xp-gp.dtb for ArmadaXP.
>> I enabled "orion-gpio" driver to initialize GPIOs as given in
>> armada-xp-mv78460.
>
> What kernel configuration are you using? Do you have the same problem
> with multi_v7_defconfig and mvebu_v7_defconfig?
>
>> The driver while initializing calls irq_domain_add_simple which throws up
>> following warning
>> "irq: Cannot allocate irq_descs @ IRQ47, assuming pre-allocated"
>> The warning repeats for next set(32-63  & 64-66).
>>
>> Also the GPIO IRQs are not getting listed in cat /proc/interrupts
>
> irq_domain_add_simple() returning an error is fatal for the probe. The
> driver will not be loaded, so more than interrupts will be missing,
> all the gpios will be missing.
>
>     Andrew


From monstr at monstr.eu  Wed Aug  5 08:03:03 2015
From: monstr at monstr.eu (Michal Simek)
Date: Wed, 5 Aug 2015 17:03:03 +0200
Subject: [GIT PULL] Xilinx ZynqMP DT changes for v4.3
In-Reply-To: <20150805090016.GI6390@localhost>
References: <55BB369F.4080100@monstr.eu> <20150805090016.GI6390@localhost>
Message-ID: <55C225A7.9050704@monstr.eu>

Hi Olof,

On 08/05/2015 11:00 AM, Olof Johansson wrote:
> On Fri, Jul 31, 2015 at 10:49:35AM +0200, Michal Simek wrote:
>> Hi,
>>
>> please pull these ARM64 DT patches to your tree.
>>
>> Thanks,
>> Michal
>>
>>
>> The following changes since commit d770e558e21961ad6cfdf0ff7df0eb5d7d4f0754:
>>
>>   Linux 4.2-rc1 (2015-07-05 11:01:52 -0700)
>>
>> are available in the git repository at:
>>
>>   https://github.com/Xilinx/linux-xlnx.git tags/zynqmp-dt-for-4.3
>>
>> for you to fetch changes up to f49310dc62f68ae9f905f9a1e42224fa23867f47:
>>
>>   ARM64: zynqmp: Move SPI nodes to the right location (2015-07-31
>> 10:46:34 +0200)
>>
>> ----------------------------------------------------------------
>> arm: Xilinx ZynqMP dt patches for v4.3
>>
>> - Add SATA, GPIO, CAN, SMMU, USB, SPI, I2C, watchdog and sdhci for zynqmp
>> - Sort nodes in dtsi
> 
> You seem to sort these alphabetically. We normally encourage sorting by unit
> address instead. Was there some reason you chose alphabetical?

Normally if you look for something you can't remember addresses but you
remember names that's why this sorting is more natural at least for me.

I have checked APM/EXYNOS/Juno/SPR for example (and probably others) and
there is no order at all.
If this is any strict requirement to sort nodes by addresses I am happy
to send patch on the top of this series to fix it. That's why please let
me know.

There are other questions what to do with clocks for example - having
them on the bus like it is done for us and Cavium/Exynos/Seattle or
having separate node on the bus like APM.
Using soc node is another question.

I know that Grant wanted to update any guide which should cover these
stuff but I am not aware if we have any doc which describe it.

Thanks,
Michal

-- 
Michal Simek, Ing. (M.Eng), OpenPGP -> KeyID: FE3D1F91
w: www.monstr.eu p: +42-0-721842854
Maintainer of Linux kernel - Microblaze cpu - http://www.monstr.eu/fdt/
Maintainer of Linux kernel - Xilinx Zynq ARM architecture
Microblaze U-BOOT custodian and responsible for u-boot arm zynq platform


-------------- next part --------------
A non-text attachment was scrubbed...
Name: signature.asc
Type: application/pgp-signature
Size: 198 bytes
Desc: OpenPGP digital signature
URL: <http://lists.infradead.org/pipermail/linux-arm-kernel/attachments/20150805/8e2493c0/attachment.sig>

From linux at roeck-us.net  Wed Aug  5 08:04:52 2015
From: linux at roeck-us.net (Guenter Roeck)
Date: Wed, 05 Aug 2015 08:04:52 -0700
Subject: [PATCH v3 1/2] drivers: watchdog: add a driver to support SAMA5D4
 watchdog timer
In-Reply-To: <1438765043-11030-2-git-send-email-wenyou.yang@atmel.com>
References: <1438765043-11030-1-git-send-email-wenyou.yang@atmel.com>
 <1438765043-11030-2-git-send-email-wenyou.yang@atmel.com>
Message-ID: <55C22614.6090901@roeck-us.net>

On 08/05/2015 01:57 AM, Wenyou Yang wrote:
>>From SAMA5D4, the watchdog timer is upgrated with a new feature,
> which is describled as in the datasheet, "WDT_MR can be written
> until a LOCKMR command is issued in WDT_CR".
> That is to say, as long as the bootstrap and u-boot don't issue
> a LOCKMR command, WDT_MR can be written more than once in the driver.
>
> So the SAMA5D4 watchdog driver's implementation is different from
> the at91sam9260 watchdog driver implemented in file at91sam9_wdt.c.
> The user application open the device file to enable the watchdog timer
> hardware, and close to disable it, and set the watchdog timer timeout
> by seting WDV and WDD fields of WDT_MR register, and ping the watchdog
> by issuing WDRSTT command to WDT_CR register with hard-coded key.
>
> Signed-off-by: Wenyou Yang <wenyou.yang at atmel.com>
> ---
>   drivers/watchdog/Kconfig            |    9 ++
>   drivers/watchdog/Makefile           |    1 +
>   drivers/watchdog/at91_sama5d4_wdt.c |  279 +++++++++++++++++++++++++++++++++++
>   drivers/watchdog/at91sam9_wdt.h     |    2 +
>   4 files changed, 291 insertions(+)
>   create mode 100644 drivers/watchdog/at91_sama5d4_wdt.c
>
> diff --git a/drivers/watchdog/Kconfig b/drivers/watchdog/Kconfig
> index e5e7c55..4ce8346 100644
> --- a/drivers/watchdog/Kconfig
> +++ b/drivers/watchdog/Kconfig
> @@ -152,6 +152,15 @@ config ARM_SP805_WATCHDOG
>   	  ARM Primecell SP805 Watchdog timer. This will reboot your system when
>   	  the timeout is reached.
>
> +config AT91_SAMA5D4_WATCHDOG

Looking into the chip ordering documentation. The chip goes by ATSAMA5D4,
while the other chips go by AT91SAM9xxx.

So I think ATSAMA5D4 would be better (same for the driver name).

Couple of additional nitpicks below.

Thanks,
Guenter

> +	tristate "Atmel SAMA5D4 Watchdog Timer"
> +	depends on ARCH_AT91
> +	select WATCHDOG_CORE
> +	help
> +	  Atmel SAMA5D4 watchdog timer is embedded into SAMA5D4 chips.
> +	  Its Watchdog Timer Mode Register can be written more than once.
> +	  This will reboot your system when the timeout is reached.
> +
>   config AT91RM9200_WATCHDOG
>   	tristate "AT91RM9200 watchdog"
>   	depends on SOC_AT91RM9200 && MFD_SYSCON
> diff --git a/drivers/watchdog/Makefile b/drivers/watchdog/Makefile
> index 5c19294..c57569c 100644
> --- a/drivers/watchdog/Makefile
> +++ b/drivers/watchdog/Makefile
> @@ -30,6 +30,7 @@ obj-$(CONFIG_USBPCWATCHDOG) += pcwd_usb.o
>
>   # ARM Architecture
>   obj-$(CONFIG_ARM_SP805_WATCHDOG) += sp805_wdt.o
> +obj-$(CONFIG_AT91_SAMA5D4_WATCHDOG) += at91_sama5d4_wdt.o
>   obj-$(CONFIG_AT91RM9200_WATCHDOG) += at91rm9200_wdt.o
>   obj-$(CONFIG_AT91SAM9X_WATCHDOG) += at91sam9_wdt.o
>   obj-$(CONFIG_CADENCE_WATCHDOG) += cadence_wdt.o
> diff --git a/drivers/watchdog/at91_sama5d4_wdt.c b/drivers/watchdog/at91_sama5d4_wdt.c
> new file mode 100644
> index 0000000..f2e1995
> --- /dev/null
> +++ b/drivers/watchdog/at91_sama5d4_wdt.c
> @@ -0,0 +1,279 @@
> +/*
> + * Driver for Atmel SAMA5D4 Watchdog Timer
> + *
> + * Copyright (C) 2015 Atmel Corporation
> + *
> + * Licensed under GPLv2.
> + */
> +
> +#include <linux/interrupt.h>
> +#include <linux/io.h>
> +#include <linux/kernel.h>
> +#include <linux/module.h>
> +#include <linux/of.h>
> +#include <linux/of_irq.h>
> +#include <linux/platform_device.h>
> +#include <linux/reboot.h>
> +#include <linux/watchdog.h>
> +
> +#include "at91sam9_wdt.h"
> +
> +/* minimum and maximum watchdog timeout, in seconds */
> +#define MIN_WDT_TIMEOUT		1
> +#define MAX_WDT_TIMEOUT		16
> +#define WDT_DEFAULT_TIMEOUT	MAX_WDT_TIMEOUT
> +
> +#define WDT_SEC2TICKS(s)	((s) ? (((s) << 8) - 1) : 0)
> +
> +struct atmel_wdt {

If you don't mind, please use "sama5d4" as prefix here and for function names.

> +	struct watchdog_device	wdd;
> +	void __iomem		*reg_base;
> +	u32	config;
> +};
> +
> +static int wdt_timeout = WDT_DEFAULT_TIMEOUT;
> +static bool nowayout = WATCHDOG_NOWAYOUT;
> +
> +module_param(wdt_timeout, int, 0);
> +MODULE_PARM_DESC(wdt_timeout,
> +	"Watchdog wdt_timeout in seconds. (default = "
> +	__MODULE_STRING(WDT_DEFAULT_TIMEOUT) ")");
> +
> +module_param(nowayout, bool, 0);
> +MODULE_PARM_DESC(nowayout,
> +	"Watchdog cannot be stopped once started (default="
> +	__MODULE_STRING(WATCHDOG_NOWAYOUT) ")");
> +
> +#define wdt_read(wdt, field) \
> +	readl_relaxed((wdt)->reg_base + (field))
> +
> +#define wdt_write(wtd, field, val) \
> +	writel_relaxed((val), (wdt)->reg_base + (field))
> +
> +static int atmel_wdt_start(struct watchdog_device *wdd)
> +{
> +	struct atmel_wdt *wdt = watchdog_get_drvdata(wdd);
> +	u32 reg;
> +
> +	reg = wdt_read(wdt, AT91_WDT_MR);
> +	reg &= ~AT91_WDT_WDDIS;
> +	wdt_write(wdt, AT91_WDT_MR, reg);
> +
> +	return 0;
> +}
> +
> +static int atmel_wdt_stop(struct watchdog_device *wdd)
> +{
> +	struct atmel_wdt *wdt = watchdog_get_drvdata(wdd);
> +	u32 reg;
> +
> +	reg = wdt_read(wdt, AT91_WDT_MR);
> +	reg |= AT91_WDT_WDDIS;
> +	wdt_write(wdt, AT91_WDT_MR, reg);
> +
> +	return 0;
> +}
> +
> +static int atmel_wdt_ping(struct watchdog_device *wdd)
> +{
> +	struct atmel_wdt *wdt = watchdog_get_drvdata(wdd);
> +
> +	wdt_write(wdt, AT91_WDT_CR, AT91_WDT_KEY | AT91_WDT_WDRSTT);
> +
> +	return 0;
> +}
> +
> +static int atmel_wdt_set_timeout(struct watchdog_device *wdd,
> +				 unsigned int timeout)
> +{
> +	struct atmel_wdt *wdt = watchdog_get_drvdata(wdd);
> +	u32 value = WDT_SEC2TICKS(timeout);
> +	u32 reg;
> +
> +	reg = wdt_read(wdt, AT91_WDT_MR);
> +	reg &= ~AT91_WDT_WDV;
> +	reg &= ~AT91_WDT_WDD;
> +	reg |= AT91_WDT_SET_WDV(value);
> +	reg |= AT91_WDT_SET_WDD(value);
> +	wdt_write(wdt, AT91_WDT_MR, reg);
> +
> +	wdd->timeout = timeout;
> +
> +	return 0;
> +}
> +
> +static const struct watchdog_info atmel_wdt_info = {
> +	.options = WDIOF_SETTIMEOUT | WDIOF_MAGICCLOSE | WDIOF_KEEPALIVEPING,
> +	.firmware_version = 0,

Unnecessary initialization.

> +	.identity = "Atmel SAMA5D4 Watchdog",
> +};
> +
> +static struct watchdog_ops atmel_wdt_ops = {
> +	.owner = THIS_MODULE,
> +	.start = atmel_wdt_start,
> +	.stop = atmel_wdt_stop,
> +	.ping = atmel_wdt_ping,
> +	.set_timeout = atmel_wdt_set_timeout,
> +};
> +
> +static irqreturn_t atmel_wdt_irq_handler(int irq, void *dev_id)
> +{
> +	struct atmel_wdt *wdt = platform_get_drvdata(dev_id);
> +
> +	if (wdt_read(wdt, AT91_WDT_SR)) {
> +		pr_crit("Atmel Watchdog Software Reset\n");
> +		emergency_restart();
> +		pr_crit("Reboot didn't ?????\n");
> +	}
> +
> +	return IRQ_HANDLED;
> +}
> +
> +static int of_atmel_wdt_init(struct device_node *np, struct atmel_wdt *wdt)
> +{
> +	const char *tmp;
> +
> +	wdt->config = AT91_WDT_WDDIS;
> +
> +	if (!of_property_read_string(np, "atmel,watchdog-type", &tmp) &&
> +	    !strcmp(tmp, "software"))
> +		wdt->config |= AT91_WDT_WDFIEN;
> +	else
> +		wdt->config |= AT91_WDT_WDRSTEN;
> +
> +	if (of_property_read_bool(np, "atmel,idle-halt"))
> +		wdt->config |= AT91_WDT_WDIDLEHLT;
> +
> +	if (of_property_read_bool(np, "atmel,dbg-halt"))
> +		wdt->config |= AT91_WDT_WDDBGHLT;
> +
> +	return 0;
> +}
> +
> +static int atmel_wdt_init(struct atmel_wdt *wdt)
> +{
> +	struct watchdog_device *wdd = &wdt->wdd;
> +	u32 value = WDT_SEC2TICKS(wdd->timeout);
> +	u32 reg;
> +
> +	/*
> +	 * Because the fields WDV and WDD must not be modified when the WDDIS
> +	 * bit is set, so clear the WDDIS bit before writing the WDT_MR.
> +	 */
> +	reg = wdt_read(wdt, AT91_WDT_MR);
> +	reg &= ~AT91_WDT_WDDIS;
> +	wdt_write(wdt, AT91_WDT_MR, reg);
> +
> +	reg = wdt->config;
> +	reg |= AT91_WDT_SET_WDD(value);
> +	reg |= AT91_WDT_SET_WDV(value);
> +
> +	wdt_write(wdt, AT91_WDT_MR, reg);
> +
> +	return 0;
> +}
> +
> +static int atmel_wdt_probe(struct platform_device *pdev)
> +{
> +	struct watchdog_device *wdd;
> +	struct atmel_wdt *wdt;
> +	struct resource *res;
> +	void __iomem *regs;
> +	int ret, irq = -1;

Might as well use irq = 0 here for consistency.

> +
> +	wdt = devm_kzalloc(&pdev->dev, sizeof(*wdt), GFP_KERNEL);
> +	if (!wdt)
> +		return -ENOMEM;
> +
> +	wdd = &wdt->wdd;
> +	wdd->timeout = wdt_timeout;
> +	wdd->info = &atmel_wdt_info;
> +	wdd->ops = &atmel_wdt_ops;
> +	wdd->min_timeout = MIN_WDT_TIMEOUT;
> +	wdd->max_timeout = MAX_WDT_TIMEOUT;
> +
> +	watchdog_set_drvdata(wdd, wdt);
> +
> +	res = platform_get_resource(pdev, IORESOURCE_MEM, 0);
> +	regs = devm_ioremap_resource(&pdev->dev, res);
> +	if (IS_ERR(regs))
> +		return PTR_ERR(regs);
> +
> +	wdt->reg_base = regs;
> +
> +	if (pdev->dev.of_node) {
> +		irq = irq_of_parse_and_map(pdev->dev.of_node, 0);
> +		if (!irq)
> +			dev_warn(&pdev->dev, "failed to get IRQ from DT\n");
> +
> +		ret = of_atmel_wdt_init(pdev->dev.of_node, wdt);
> +		if (ret)
> +			return ret;
> +	}
> +
> +	if ((wdt->config & AT91_WDT_WDFIEN) && irq > 0) {

... then you can check " ... && irq" here.

> +		ret = devm_request_irq(&pdev->dev, irq, atmel_wdt_irq_handler,
> +				       0, pdev->name, pdev);
> +		if (ret) {
> +			dev_err(&pdev->dev,
> +				"cannot register interrupt handler\n");
> +			return ret;
> +		}
> +	}
> +
> +	ret = watchdog_init_timeout(wdd, wdt_timeout, &pdev->dev);
> +	if (ret) {
> +		dev_err(&pdev->dev, "unable to set timeout value\n");
> +		return ret;
> +	}
> +
> +	ret = atmel_wdt_init(wdt);
> +	if (ret)
> +		return ret;
> +
> +	watchdog_set_nowayout(wdd, nowayout);
> +
> +	ret = watchdog_register_device(wdd);
> +	if (ret) {
> +		dev_err(&pdev->dev, "failed to register watchdog device\n");
> +		return ret;
> +	}
> +
> +	platform_set_drvdata(pdev, wdt);
> +
> +	dev_info(&pdev->dev, "initialized (timeout = %d sec, nowayout = %d)\n",
> +		 wdt_timeout, nowayout);
> +
> +	return 0;
> +}
> +
> +static int atmel_wdt_remove(struct platform_device *pdev)
> +{
> +	struct atmel_wdt *wdt = platform_get_drvdata(pdev);
> +
> +	atmel_wdt_stop(&wdt->wdd);
> +
> +	watchdog_unregister_device(&wdt->wdd);
> +
> +	return 0;
> +}
> +
> +static const struct of_device_id atmel_wdt_of_match[] = {
> +	{ .compatible = "atmel,sama5d4-wdt", },
> +	{ },
> +};
> +MODULE_DEVICE_TABLE(of, atmel_wdt_of_match);
> +
> +static struct platform_driver atmel_wdt_driver = {
> +	.probe		= atmel_wdt_probe,
> +	.remove		= atmel_wdt_remove,
> +	.driver		= {
> +		.name	= "sama5d4 wdt",
> +		.of_match_table = atmel_wdt_of_match,
> +	},
> +};
> +module_platform_driver(atmel_wdt_driver);
> +
> +MODULE_AUTHOR("Atmel Corporation");
> +MODULE_DESCRIPTION("Atmel SAMA5D4 Watchdog Timer driver");
> +MODULE_LICENSE("GPL v2");
> diff --git a/drivers/watchdog/at91sam9_wdt.h b/drivers/watchdog/at91sam9_wdt.h
> index c6fbb2e6..b79a83b 100644
> --- a/drivers/watchdog/at91sam9_wdt.h
> +++ b/drivers/watchdog/at91sam9_wdt.h
> @@ -22,11 +22,13 @@
>
>   #define AT91_WDT_MR		0x04			/* Watchdog Mode Register */
>   #define		AT91_WDT_WDV		(0xfff << 0)		/* Counter Value */
> +#define			AT91_WDT_SET_WDV(x)	((x) & AT91_WDT_WDV)
>   #define		AT91_WDT_WDFIEN		(1     << 12)		/* Fault Interrupt Enable */
>   #define		AT91_WDT_WDRSTEN	(1     << 13)		/* Reset Processor */
>   #define		AT91_WDT_WDRPROC	(1     << 14)		/* Timer Restart */
>   #define		AT91_WDT_WDDIS		(1     << 15)		/* Watchdog Disable */
>   #define		AT91_WDT_WDD		(0xfff << 16)		/* Delta Value */
> +#define			AT91_WDT_SET_WDD(x)	(((x) << 16) & AT91_WDT_WDD)
>   #define		AT91_WDT_WDDBGHLT	(1     << 28)		/* Debug Halt */
>   #define		AT91_WDT_WDIDLEHLT	(1     << 29)		/* Idle Halt */
>
>



From kishon at ti.com  Wed Aug  5 08:06:25 2015
From: kishon at ti.com (Kishon Vijay Abraham I)
Date: Wed, 5 Aug 2015 20:36:25 +0530
Subject: [PATCH 0/7] ARM: dts: MMC fixes for DRA7 based boards
In-Reply-To: <20150805105400.GF16878@atomide.com>
References: <1438244020-4244-1-git-send-email-kishon@ti.com>
 <20150805105400.GF16878@atomide.com>
Message-ID: <55C22671.1060906@ti.com>

Hi,

On Wednesday 05 August 2015 04:24 PM, Tony Lindgren wrote:
> * Kishon Vijay Abraham I <kishon at ti.com> [150730 01:16]:
>> Miscellaneous fixes in dts files for MMC device tree nodes.
>>
>> Did basic read/write test in J6, J6 Eco and Beagle-x15
>>
>> Balaji T K (1):
>>   ARM: dts: dra7-evm: add evm_3v3_sd regulator
>>
>> Kishon Vijay Abraham I (5):
>>   ARM: dts: dra72-evm: add evm_3v3_sd regulator
>>   ARM: dts: dra72-evm: Set max clock frequency of MMC1 and MMC2
>>   ARM: dts: am57xx-beagle-x15: mmc1: remove redundant pbias-supply
>>     property
>>   ARM: dts: dra7-evm: Fix spurious card insert/removal interrupt
>>   ARM: dts: dra72-evm: Fix spurious card insert/removal interrupt
>>
>> Nishanth Menon (1):
>>   ARM: dts: dra7-evm: Add MMCSD card removal GPIO
>>
>>  arch/arm/boot/dts/am57xx-beagle-x15.dts |    1 -
>>  arch/arm/boot/dts/dra7-evm.dts          |   18 +++++++++++++++++-
>>  arch/arm/boot/dts/dra72-evm.dts         |   16 ++++++++++++++--
>>  3 files changed, 31 insertions(+), 4 deletions(-)
> 
> Thanks applying all these into omap-for-v4.3/dt.

Thanks. Please take [1] one too.

[1] -> https://lkml.org/lkml/2015/8/5/443

Thanks
Kishon


From gregory.clement at free-electrons.com  Wed Aug  5 08:26:25 2015
From: gregory.clement at free-electrons.com (Gregory CLEMENT)
Date: Wed, 05 Aug 2015 17:26:25 +0200
Subject: [PATCH 7/7] ARM: redo TTBR setup code for LPAE
In-Reply-To: <E1YpwbQ-0000wm-Jx@rmk-PC.arm.linux.org.uk>
References: <20150506103000.GF2067@n2100.arm.linux.org.uk>
 <E1YpwbQ-0000wm-Jx@rmk-PC.arm.linux.org.uk>
Message-ID: <55C22B21.8000700@free-electrons.com>

Hi Russell,

On 06/05/2015 12:30, Russell King wrote:
> Re-engineer the LPAE TTBR setup code.  Rather than passing some shifted
> address in order to fit in a CPU register, pass either a full physical
> address (in the case of r4, r5 for TTBR0) or a PFN (for TTBR1).
> 
> This removes the ARCH_PGD_SHIFT hack, and the last dangerous user of
> cpu_set_ttbr() in the secondary CPU startup code path (which was there
> to re-set TTBR1 to the appropriate high physical address space on
> Keystone2.

It seems that since the merge of this commit the secondary CPUs on
Armada XP failed to come online in Big Endian (my configuration is
mvebu_v7_defconfig+CONFIG_CPU_BIG_ENDIAN=y). Once I found that this
commit introduced the regression I also tested but with LPAE but I
had the same result: only the first CPU boot.

I don't know if there is something wrong with this patch or if it
reveals something which was wrong in the Armada XP port.

At a point I suspected something around the change in the
get_arch_pgd function but I didn't find anything useful.

Any guidance would be greatly appreciate.

Thanks,

Gregory



> 
> Signed-off-by: Russell King <rmk+kernel at arm.linux.org.uk>
> ---
>  arch/arm/include/asm/memory.h    | 16 ---------------
>  arch/arm/include/asm/proc-fns.h  |  7 -------
>  arch/arm/include/asm/smp.h       |  2 +-
>  arch/arm/kernel/head-nommu.S     |  2 +-
>  arch/arm/kernel/head.S           | 42 +++++++++++++++++++++++++++++-----------
>  arch/arm/kernel/smp.c            | 10 ++++++----
>  arch/arm/mach-keystone/platsmp.c | 13 -------------
>  arch/arm/mm/proc-v7-2level.S     |  6 +++---
>  arch/arm/mm/proc-v7-3level.S     | 14 +++++---------
>  arch/arm/mm/proc-v7.S            | 26 ++++++++++++-------------
>  10 files changed, 60 insertions(+), 78 deletions(-)
> 
> diff --git a/arch/arm/include/asm/memory.h b/arch/arm/include/asm/memory.h
> index 184def0e1652..3a72d69b3255 100644
> --- a/arch/arm/include/asm/memory.h
> +++ b/arch/arm/include/asm/memory.h
> @@ -18,8 +18,6 @@
>  #include <linux/types.h>
>  #include <linux/sizes.h>
>  
> -#include <asm/cache.h>
> -
>  #ifdef CONFIG_NEED_MACH_MEMORY_H
>  #include <mach/memory.h>
>  #endif
> @@ -133,20 +131,6 @@
>  #define phys_to_page(phys)	(pfn_to_page(__phys_to_pfn(phys)))
>  
>  /*
> - * Minimum guaranted alignment in pgd_alloc().  The page table pointers passed
> - * around in head.S and proc-*.S are shifted by this amount, in order to
> - * leave spare high bits for systems with physical address extension.  This
> - * does not fully accomodate the 40-bit addressing capability of ARM LPAE, but
> - * gives us about 38-bits or so.
> - */
> -#ifdef CONFIG_ARM_LPAE
> -#define ARCH_PGD_SHIFT		L1_CACHE_SHIFT
> -#else
> -#define ARCH_PGD_SHIFT		0
> -#endif
> -#define ARCH_PGD_MASK		((1 << ARCH_PGD_SHIFT) - 1)
> -
> -/*
>   * PLAT_PHYS_OFFSET is the offset (from zero) of the start of physical
>   * memory.  This is used for XIP and NoMMU kernels, and on platforms that don't
>   * have CONFIG_ARM_PATCH_PHYS_VIRT. Assembly code must always use
> diff --git a/arch/arm/include/asm/proc-fns.h b/arch/arm/include/asm/proc-fns.h
> index 5324c1112f3a..8877ad5ffe10 100644
> --- a/arch/arm/include/asm/proc-fns.h
> +++ b/arch/arm/include/asm/proc-fns.h
> @@ -125,13 +125,6 @@ extern void cpu_resume(void);
>  		ttbr;						\
>  	})
>  
> -#define cpu_set_ttbr(nr, val)					\
> -	do {							\
> -		u64 ttbr = val;					\
> -		__asm__("mcrr	p15, " #nr ", %Q0, %R0, c2"	\
> -			: : "r" (ttbr));			\
> -	} while (0)
> -
>  #define cpu_get_pgd()	\
>  	({						\
>  		u64 pg = cpu_get_ttbr(0);		\
> diff --git a/arch/arm/include/asm/smp.h b/arch/arm/include/asm/smp.h
> index 18f5a554134f..487aa08f31ee 100644
> --- a/arch/arm/include/asm/smp.h
> +++ b/arch/arm/include/asm/smp.h
> @@ -61,7 +61,7 @@ asmlinkage void secondary_start_kernel(void);
>  struct secondary_data {
>  	union {
>  		unsigned long mpu_rgn_szr;
> -		unsigned long pgdir;
> +		u64 pgdir;
>  	};
>  	unsigned long swapper_pg_dir;
>  	void *stack;
> diff --git a/arch/arm/kernel/head-nommu.S b/arch/arm/kernel/head-nommu.S
> index aebfbf79a1a3..84da14b7cd04 100644
> --- a/arch/arm/kernel/head-nommu.S
> +++ b/arch/arm/kernel/head-nommu.S
> @@ -123,7 +123,7 @@ ENTRY(secondary_startup)
>  ENDPROC(secondary_startup)
>  
>  ENTRY(__secondary_switched)
> -	ldr	sp, [r7, #8]			@ set up the stack pointer
> +	ldr	sp, [r7, #12]			@ set up the stack pointer
>  	mov	fp, #0
>  	b	secondary_start_kernel
>  ENDPROC(__secondary_switched)
> diff --git a/arch/arm/kernel/head.S b/arch/arm/kernel/head.S
> index 3637973a9708..7304b4c44b52 100644
> --- a/arch/arm/kernel/head.S
> +++ b/arch/arm/kernel/head.S
> @@ -131,13 +131,30 @@ ENTRY(stext)
>  	 * The following calls CPU specific code in a position independent
>  	 * manner.  See arch/arm/mm/proc-*.S for details.  r10 = base of
>  	 * xxx_proc_info structure selected by __lookup_processor_type
> -	 * above.  On return, the CPU will be ready for the MMU to be
> -	 * turned on, and r0 will hold the CPU control register value.
> +	 * above.
> +	 *
> +	 * The processor init function will be called with:
> +	 *  r1 - machine type
> +	 *  r2 - boot data (atags/dt) pointer
> +	 *  r4 - translation table base (low word)
> +	 *  r5 - translation table base (high word, if LPAE)
> +	 *  r8 - translation table base 1 (pfn if LPAE)
> +	 *  r9 - cpuid
> +	 *  r13 - virtual address for __enable_mmu -> __turn_mmu_on
> +	 *
> +	 * On return, the CPU will be ready for the MMU to be turned on,
> +	 * r0 will hold the CPU control register value, r1, r2, r4, and
> +	 * r9 will be preserved.  r5 will also be preserved if LPAE.
>  	 */
>  	ldr	r13, =__mmap_switched		@ address to jump to after
>  						@ mmu has been enabled
>  	adr	lr, BSYM(1f)			@ return (PIC) address
> +#ifdef CONFIG_ARM_LPAE
> +	mov	r5, #0				@ high TTBR0
> +	mov	r8, r4, lsr #12			@ TTBR1 is swapper_pg_dir pfn
> +#else
>  	mov	r8, r4				@ set TTBR1 to swapper_pg_dir
> +#endif
>  	ldr	r12, [r10, #PROCINFO_INITFUNC]
>  	add	r12, r12, r10
>  	ret	r12
> @@ -158,7 +175,7 @@ ENDPROC(stext)
>   *
>   * Returns:
>   *  r0, r3, r5-r7 corrupted
> - *  r4 = page table (see ARCH_PGD_SHIFT in asm/memory.h)
> + *  r4 = physical page table address
>   */
>  __create_page_tables:
>  	pgtbl	r4, r8				@ page table address
> @@ -333,7 +350,6 @@ __create_page_tables:
>  #endif
>  #ifdef CONFIG_ARM_LPAE
>  	sub	r4, r4, #0x1000		@ point to the PGD table
> -	mov	r4, r4, lsr #ARCH_PGD_SHIFT
>  #endif
>  	ret	lr
>  ENDPROC(__create_page_tables)
> @@ -381,9 +397,9 @@ ENTRY(secondary_startup)
>  	adr	r4, __secondary_data
>  	ldmia	r4, {r5, r7, r12}		@ address to jump to after
>  	sub	lr, r4, r5			@ mmu has been enabled
> -	ldr	r4, [r7, lr]			@ get secondary_data.pgdir
> -	add	r7, r7, #4
> -	ldr	r8, [r7, lr]			@ get secondary_data.swapper_pg_dir
> +	add	r3, r7, lr
> +	ldrd	r4, [r3, #0]			@ get secondary_data.pgdir
> +	ldr	r8, [r3, #8]			@ get secondary_data.swapper_pg_dir
>  	adr	lr, BSYM(__enable_mmu)		@ return address
>  	mov	r13, r12			@ __secondary_switched address
>  	ldr	r12, [r10, #PROCINFO_INITFUNC]
> @@ -397,7 +413,7 @@ ENDPROC(secondary_startup_arm)
>  	 * r6  = &secondary_data
>  	 */
>  ENTRY(__secondary_switched)
> -	ldr	sp, [r7, #4]			@ get secondary_data.stack
> +	ldr	sp, [r7, #12]			@ get secondary_data.stack
>  	mov	fp, #0
>  	b	secondary_start_kernel
>  ENDPROC(__secondary_switched)
> @@ -416,12 +432,14 @@ __secondary_data:
>  /*
>   * Setup common bits before finally enabling the MMU.  Essentially
>   * this is just loading the page table pointer and domain access
> - * registers.
> + * registers.  All these registers need to be preserved by the
> + * processor setup function (or set in the case of r0)
>   *
>   *  r0  = cp#15 control register
>   *  r1  = machine ID
>   *  r2  = atags or dtb pointer
> - *  r4  = page table (see ARCH_PGD_SHIFT in asm/memory.h)
> + *  r4  = TTBR pointer (low word)
> + *  r5  = TTBR pointer (high word if LPAE)
>   *  r9  = processor ID
>   *  r13 = *virtual* address to jump to upon completion
>   */
> @@ -440,7 +458,9 @@ __enable_mmu:
>  #ifdef CONFIG_CPU_ICACHE_DISABLE
>  	bic	r0, r0, #CR_I
>  #endif
> -#ifndef CONFIG_ARM_LPAE
> +#ifdef CONFIG_ARM_LPAE
> +	mcrr	p15, 0, r4, r5, c2		@ load TTBR0
> +#else
>  	mov	r5, #(domain_val(DOMAIN_USER, DOMAIN_MANAGER) | \
>  		      domain_val(DOMAIN_KERNEL, DOMAIN_MANAGER) | \
>  		      domain_val(DOMAIN_TABLE, DOMAIN_MANAGER) | \
> diff --git a/arch/arm/kernel/smp.c b/arch/arm/kernel/smp.c
> index cca5b8758185..90dfbedfbfb8 100644
> --- a/arch/arm/kernel/smp.c
> +++ b/arch/arm/kernel/smp.c
> @@ -86,9 +86,11 @@ void __init smp_set_ops(struct smp_operations *ops)
>  
>  static unsigned long get_arch_pgd(pgd_t *pgd)
>  {
> -	phys_addr_t pgdir = virt_to_idmap(pgd);
> -	BUG_ON(pgdir & ARCH_PGD_MASK);
> -	return pgdir >> ARCH_PGD_SHIFT;
> +#ifdef CONFIG_ARM_LPAE
> +	return __phys_to_pfn(virt_to_phys(pgd));
> +#else
> +	return virt_to_phys(pgd);
> +#endif
>  }
>  
>  int __cpu_up(unsigned int cpu, struct task_struct *idle)
> @@ -108,7 +110,7 @@ int __cpu_up(unsigned int cpu, struct task_struct *idle)
>  #endif
>  
>  #ifdef CONFIG_MMU
> -	secondary_data.pgdir = get_arch_pgd(idmap_pgd);
> +	secondary_data.pgdir = virt_to_phys(idmap_pgd);
>  	secondary_data.swapper_pg_dir = get_arch_pgd(swapper_pg_dir);
>  #endif
>  	sync_cache_w(&secondary_data);
> diff --git a/arch/arm/mach-keystone/platsmp.c b/arch/arm/mach-keystone/platsmp.c
> index 5f46a7cf907b..4bbb18463bfd 100644
> --- a/arch/arm/mach-keystone/platsmp.c
> +++ b/arch/arm/mach-keystone/platsmp.c
> @@ -39,19 +39,6 @@ static int keystone_smp_boot_secondary(unsigned int cpu,
>  	return error;
>  }
>  
> -#ifdef CONFIG_ARM_LPAE
> -static void __cpuinit keystone_smp_secondary_initmem(unsigned int cpu)
> -{
> -	pgd_t *pgd0 = pgd_offset_k(0);
> -	cpu_set_ttbr(1, __pa(pgd0) + TTBR1_OFFSET);
> -	local_flush_tlb_all();
> -}
> -#else
> -static inline void __cpuinit keystone_smp_secondary_initmem(unsigned int cpu)
> -{}
> -#endif
> -
>  struct smp_operations keystone_smp_ops __initdata = {
>  	.smp_boot_secondary	= keystone_smp_boot_secondary,
> -	.smp_secondary_init     = keystone_smp_secondary_initmem,
>  };
> diff --git a/arch/arm/mm/proc-v7-2level.S b/arch/arm/mm/proc-v7-2level.S
> index 10405b8d31af..fa385140715f 100644
> --- a/arch/arm/mm/proc-v7-2level.S
> +++ b/arch/arm/mm/proc-v7-2level.S
> @@ -148,10 +148,10 @@ ENDPROC(cpu_v7_set_pte_ext)
>  	 * Macro for setting up the TTBRx and TTBCR registers.
>  	 * - \ttb0 and \ttb1 updated with the corresponding flags.
>  	 */
> -	.macro	v7_ttb_setup, zero, ttbr0, ttbr1, tmp
> +	.macro	v7_ttb_setup, zero, ttbr0l, ttbr0h, ttbr1, tmp
>  	mcr	p15, 0, \zero, c2, c0, 2	@ TTB control register
> -	ALT_SMP(orr	\ttbr0, \ttbr0, #TTB_FLAGS_SMP)
> -	ALT_UP(orr	\ttbr0, \ttbr0, #TTB_FLAGS_UP)
> +	ALT_SMP(orr	\ttbr0l, \ttbr0l, #TTB_FLAGS_SMP)
> +	ALT_UP(orr	\ttbr0l, \ttbr0l, #TTB_FLAGS_UP)
>  	ALT_SMP(orr	\ttbr1, \ttbr1, #TTB_FLAGS_SMP)
>  	ALT_UP(orr	\ttbr1, \ttbr1, #TTB_FLAGS_UP)
>  	mcr	p15, 0, \ttbr1, c2, c0, 1	@ load TTB1
> diff --git a/arch/arm/mm/proc-v7-3level.S b/arch/arm/mm/proc-v7-3level.S
> index d3daed0ae0ad..5e5720e8bc5f 100644
> --- a/arch/arm/mm/proc-v7-3level.S
> +++ b/arch/arm/mm/proc-v7-3level.S
> @@ -126,11 +126,10 @@ ENDPROC(cpu_v7_set_pte_ext)
>  	 * Macro for setting up the TTBRx and TTBCR registers.
>  	 * - \ttbr1 updated.
>  	 */
> -	.macro	v7_ttb_setup, zero, ttbr0, ttbr1, tmp
> +	.macro	v7_ttb_setup, zero, ttbr0l, ttbr0h, ttbr1, tmp
>  	ldr	\tmp, =swapper_pg_dir		@ swapper_pg_dir virtual address
> -	mov	\tmp, \tmp, lsr #ARCH_PGD_SHIFT
> -	cmp	\ttbr1, \tmp			@ PHYS_OFFSET > PAGE_OFFSET?
> -	mrc	p15, 0, \tmp, c2, c0, 2		@ TTB control register
> +	cmp	\ttbr1, \tmp, lsr #12		@ PHYS_OFFSET > PAGE_OFFSET?
> +	mrc	p15, 0, \tmp, c2, c0, 2		@ TTB control egister
>  	orr	\tmp, \tmp, #TTB_EAE
>  	ALT_SMP(orr	\tmp, \tmp, #TTB_FLAGS_SMP)
>  	ALT_UP(orr	\tmp, \tmp, #TTB_FLAGS_UP)
> @@ -143,13 +142,10 @@ ENDPROC(cpu_v7_set_pte_ext)
>  	 */
>  	orrls	\tmp, \tmp, #TTBR1_SIZE				@ TTBCR.T1SZ
>  	mcr	p15, 0, \tmp, c2, c0, 2				@ TTBCR
> -	mov	\tmp, \ttbr1, lsr #(32 - ARCH_PGD_SHIFT)	@ upper bits
> -	mov	\ttbr1, \ttbr1, lsl #ARCH_PGD_SHIFT		@ lower bits
> +	mov	\tmp, \ttbr1, lsr #20
> +	mov	\ttbr1, \ttbr1, lsl #12
>  	addls	\ttbr1, \ttbr1, #TTBR1_OFFSET
>  	mcrr	p15, 1, \ttbr1, \tmp, c2			@ load TTBR1
> -	mov	\tmp, \ttbr0, lsr #(32 - ARCH_PGD_SHIFT)	@ upper bits
> -	mov	\ttbr0, \ttbr0, lsl #ARCH_PGD_SHIFT		@ lower bits
> -	mcrr	p15, 0, \ttbr0, \tmp, c2			@ load TTBR0
>  	.endm
>  
>  	/*
> diff --git a/arch/arm/mm/proc-v7.S b/arch/arm/mm/proc-v7.S
> index 3d1054f11a8a..873230912894 100644
> --- a/arch/arm/mm/proc-v7.S
> +++ b/arch/arm/mm/proc-v7.S
> @@ -343,9 +343,9 @@ __v7_setup:
>  	and	r10, r0, #0xff000000		@ ARM?
>  	teq	r10, #0x41000000
>  	bne	3f
> -	and	r5, r0, #0x00f00000		@ variant
> +	and	r3, r0, #0x00f00000		@ variant
>  	and	r6, r0, #0x0000000f		@ revision
> -	orr	r6, r6, r5, lsr #20-4		@ combine variant and revision
> +	orr	r6, r6, r3, lsr #20-4		@ combine variant and revision
>  	ubfx	r0, r0, #4, #12			@ primary part number
>  
>  	/* Cortex-A8 Errata */
> @@ -354,7 +354,7 @@ __v7_setup:
>  	bne	2f
>  #if defined(CONFIG_ARM_ERRATA_430973) && !defined(CONFIG_ARCH_MULTIPLATFORM)
>  
> -	teq	r5, #0x00100000			@ only present in r1p*
> +	teq	r3, #0x00100000			@ only present in r1p*
>  	mrceq	p15, 0, r10, c1, c0, 1		@ read aux control register
>  	orreq	r10, r10, #(1 << 6)		@ set IBE to 1
>  	mcreq	p15, 0, r10, c1, c0, 1		@ write aux control register
> @@ -395,7 +395,7 @@ __v7_setup:
>  	mcreq	p15, 0, r10, c15, c0, 1		@ write diagnostic register
>  #endif
>  #ifdef CONFIG_ARM_ERRATA_743622
> -	teq	r5, #0x00200000			@ only present in r2p*
> +	teq	r3, #0x00200000			@ only present in r2p*
>  	mrceq	p15, 0, r10, c15, c0, 1		@ read diagnostic register
>  	orreq	r10, r10, #1 << 6		@ set bit #6
>  	mcreq	p15, 0, r10, c15, c0, 1		@ write diagnostic register
> @@ -425,10 +425,10 @@ __v7_setup:
>  	mcr	p15, 0, r10, c7, c5, 0		@ I+BTB cache invalidate
>  #ifdef CONFIG_MMU
>  	mcr	p15, 0, r10, c8, c7, 0		@ invalidate I + D TLBs
> -	v7_ttb_setup r10, r4, r8, r5		@ TTBCR, TTBRx setup
> -	ldr	r5, =PRRR			@ PRRR
> +	v7_ttb_setup r10, r4, r5, r8, r3	@ TTBCR, TTBRx setup
> +	ldr	r3, =PRRR			@ PRRR
>  	ldr	r6, =NMRR			@ NMRR
> -	mcr	p15, 0, r5, c10, c2, 0		@ write PRRR
> +	mcr	p15, 0, r3, c10, c2, 0		@ write PRRR
>  	mcr	p15, 0, r6, c10, c2, 1		@ write NMRR
>  #endif
>  	dsb					@ Complete invalidations
> @@ -437,22 +437,22 @@ __v7_setup:
>  	and	r0, r0, #(0xf << 12)		@ ThumbEE enabled field
>  	teq	r0, #(1 << 12)			@ check if ThumbEE is present
>  	bne	1f
> -	mov	r5, #0
> -	mcr	p14, 6, r5, c1, c0, 0		@ Initialize TEEHBR to 0
> +	mov	r3, #0
> +	mcr	p14, 6, r3, c1, c0, 0		@ Initialize TEEHBR to 0
>  	mrc	p14, 6, r0, c0, c0, 0		@ load TEECR
>  	orr	r0, r0, #1			@ set the 1st bit in order to
>  	mcr	p14, 6, r0, c0, c0, 0		@ stop userspace TEEHBR access
>  1:
>  #endif
> -	adr	r5, v7_crval
> -	ldmia	r5, {r5, r6}
> +	adr	r3, v7_crval
> +	ldmia	r3, {r3, r6}
>   ARM_BE8(orr	r6, r6, #1 << 25)		@ big-endian page tables
>  #ifdef CONFIG_SWP_EMULATE
> -	orr     r5, r5, #(1 << 10)              @ set SW bit in "clear"
> +	orr     r3, r3, #(1 << 10)              @ set SW bit in "clear"
>  	bic     r6, r6, #(1 << 10)              @ clear it in "mmuset"
>  #endif
>     	mrc	p15, 0, r0, c1, c0, 0		@ read control register
> -	bic	r0, r0, r5			@ clear bits them
> +	bic	r0, r0, r3			@ clear bits them
>  	orr	r0, r0, r6			@ set them
>   THUMB(	orr	r0, r0, #1 << 30	)	@ Thumb exceptions
>  	ret	lr				@ return to head.S:__ret
> 


-- 
Gregory Clement, Free Electrons
Kernel, drivers, real-time and embedded Linux
development, consulting, training and support.
http://free-electrons.com


From olof at lixom.net  Wed Aug  5 08:26:27 2015
From: olof at lixom.net (Olof Johansson)
Date: Wed, 5 Aug 2015 17:26:27 +0200
Subject: [patch 00/11] ARM: Interrupt cleanups and API change preparation
In-Reply-To: <20150713090726.316699641@linutronix.de>
References: <20150713090726.316699641@linutronix.de>
Message-ID: <20150805152627.GA31397@localhost>

On Mon, Jul 13, 2015 at 08:28:58PM -0000, Thomas Gleixner wrote:
> The following patch series contains the following changes:
> 
>     - Consolidation of chained interrupt handler setup/removal
> 
>     - Switch to functions which avoid a redundant interrupt
>       descriptor lookup
> 
>     - Preparation of interrupt flow handlers for the 'irq' argument
>       removal
> 
> The series has no dependencies and is also available as a git branch
> for your convenience:
> 
>  git://git.kernel.org/pub/scm/linux/kernel/git/tip/tip.git irq/arm
> 
> If you want me to carry the patches in the irq/core branch of tip,
> please let me know.

I've now merged this into next/cleanup in arm-soc (for 4.3).

Thanks!


-Olof


From Liviu.Dudau at arm.com  Wed Aug  5 07:28:12 2015
From: Liviu.Dudau at arm.com (Liviu Dudau)
Date: Wed,  5 Aug 2015 15:28:12 +0100
Subject: [PATCH 4/4] MAINTAINERS: Add Liviu Dudau as maintainer for ARM HDLCD
 driver.
In-Reply-To: <1438784892-27888-1-git-send-email-Liviu.Dudau@arm.com>
References: <1438784892-27888-1-git-send-email-Liviu.Dudau@arm.com>
Message-ID: <1438784892-27888-5-git-send-email-Liviu.Dudau@arm.com>

Update MAINTAINERS file for HDLCD driver.

Cc: Andrew Morton <akpm at linux-foundation.org>
Cc: Arnd Bergmann <arnd at arndb.de>
Cc: Mauro Carvalho Chehab <mchehab at osg.samsung.com>
Cc: Greg KH <gregkh at linuxfoundation.org>
Cc: Joe Perches <joe at perches.com>
Cc: Jiri Slaby <jslaby at suse.com>

Signed-off-by: Liviu Dudau <Liviu.Dudau at arm.com>
---
 MAINTAINERS | 6 ++++++
 1 file changed, 6 insertions(+)

diff --git a/MAINTAINERS b/MAINTAINERS
index 443dc62..084818e 100644
--- a/MAINTAINERS
+++ b/MAINTAINERS
@@ -790,6 +790,12 @@ S:	Maintained
 F:	drivers/video/fbdev/arcfb.c
 F:	drivers/video/fbdev/core/fb_defio.c
 
+ARM HDLCD DRM DRIVER
+M:	Liviu Dudau <liviu.dudau at arm.com>
+S:	Maintained
+F:	drivers/gpu/drm/arm/
+F:	Documentation/devicetree/bindings/arm/arm,hdlcd.txt
+
 ARM MFM AND FLOPPY DRIVERS
 M:	Ian Molton <spyro at f2s.com>
 S:	Maintained
-- 
2.4.6



From s-anna at ti.com  Wed Aug  5 08:32:30 2015
From: s-anna at ti.com (Suman Anna)
Date: Wed, 5 Aug 2015 10:32:30 -0500
Subject: [PATCH v2 1/3] mailbox/omap: Add ti,mbox-send-noirq quirk to
 fix AM33xx CPU Idle
In-Reply-To: <20150805102840.GA16878@atomide.com>
References: <1437166592-25378-1-git-send-email-d-gerlach@ti.com>
 <1437166592-25378-2-git-send-email-d-gerlach@ti.com>
 <20150805102840.GA16878@atomide.com>
Message-ID: <55C22C8E.3000506@ti.com>

Hi Tony,

On 08/05/2015 05:28 AM, Tony Lindgren wrote:
> * Dave Gerlach <d-gerlach at ti.com> [150717 13:59]:
>> --- a/Documentation/devicetree/bindings/mailbox/omap-mailbox.txt
>> +++ b/Documentation/devicetree/bindings/mailbox/omap-mailbox.txt
>> @@ -75,6 +75,14 @@ data that represent the following:
>>      Cell #3 (usr_id)  - mailbox user id for identifying the interrupt line
>>                          associated with generating a tx/rx fifo interrupt.
>>  
>> +Optional Properties:
>> +--------------------
>> +- ti,mbox-send-noirq:   Quirk flag to allow the client user of this sub-mailbox
>> +                        to send messages without triggering a Tx ready interrupt,
>> +                        and to control the Tx ticker. Should be used only on
>> +                        sub-mailboxes used to communicate with WkupM3 remote
>> +                        processor on AM33xx/AM43xx SoCs.
>> +
> 
> Hmm can't you do this just by setting a flag in the device driver
> based on the compatible string?

We can't because there can be other users like PRUSS which will use a
sub-mailbox in a regular fashion. The compatible serves the IP and there
can be multiple sub-mailboxes underneath it, and this quirk is needed
only on the one that's used by the WkupM3.

Jassi,
Do you have any comments on this?

regards
Suman


From david.vrabel at citrix.com  Wed Aug  5 08:50:33 2015
From: david.vrabel at citrix.com (David Vrabel)
Date: Wed, 5 Aug 2015 16:50:33 +0100
Subject: [Xen-devel] [PATCH v2 02/20] xen: Introduce a function to split
 a Linux page into Xen page
In-Reply-To: <55C21DF3.2090201@citrix.com>
References: <1436474552-31789-1-git-send-email-julien.grall@citrix.com>
 <1436474552-31789-3-git-send-email-julien.grall@citrix.com>
 <55B205FB.5080209@citrix.com> <55B20B56.7020605@citrix.com>
 <55B20F1F.60902@citrix.com> <55C21DF3.2090201@citrix.com>
Message-ID: <55C230C9.7060506@citrix.com>

On 05/08/15 15:30, Julien Grall wrote:
> Hi David,
> 
> On 24/07/15 11:10, David Vrabel wrote:
>> On 24/07/15 10:54, Julien Grall wrote:
>>> On 24/07/15 10:31, David Vrabel wrote:
>>>> On 09/07/15 21:42, Julien Grall wrote:
>>>>> The Xen interface is always using 4KB page. This means that a Linux page
>>>>> may be split across multiple Xen page when the page granularity is not
>>>>> the same.
>>>>>
>>>>> This helper will break down a Linux page into 4KB chunk and call the
>>>>> helper on each of them.
>>>> [...]
>>>>> --- a/include/xen/page.h
>>>>> +++ b/include/xen/page.h
>>>>> @@ -39,4 +39,24 @@ struct xen_memory_region xen_extra_mem[XEN_EXTRA_MEM_MAX_REGIONS];
>>>>>  
>>>>>  extern unsigned long xen_released_pages;
>>>>>  
>>>>> +typedef int (*xen_pfn_fn_t)(struct page *page, unsigned long pfn, void *data);
>>>>> +
>>>>> +/* Break down the page in 4KB granularity and call fn foreach xen pfn */
>>>>> +static inline int xen_apply_to_page(struct page *page, xen_pfn_fn_t fn,
>>>>> +				    void *data)
>>>>
>>>> I think this should be outlined (unless you have measurements that
>>>> support making it inlined).
>>>
>>> I don't have any performance measurements. Although, when Linux is using
>>> 4KB page granularity, the loop in this helper will be dropped by the
>>> helper. The code would look like:
>>>
>>> unsigned long pfn = xen_page_to_pfn(page);
>>>
>>> ret = fn(page, fn, data);
>>> if (ret)
>>>   return ret;
>>>
>>> The compiler could even inline the callback (fn). So it drops 2
>>> functions call.
>>
>> Ok, keep it inlined.
>>
>>>> Also perhaps make it
>>>>
>>>> int xen_for_each_gfn(struct page *page,
>>>>                      xen_gfn_fn_t fn, void *data);
>>>
>>> gfn standing for Guest Frame Number right?
>>
>> Yes.  This suggestion is just changing the name to make it more obvious
>> what it does.
> 
> Thinking more about this suggestion. The callback (fn) is getting a 4K
> PFN in parameter and not a GFN.

I would like only APIs that deal with 64 KiB PFNs and 4 KiB GFNs.  I
think having a 4 KiB "PFN" is confusing.

Can you rework this xen_for_each_gfn() to pass GFNs to fn, instead?

> This is because the balloon code seems to require having a 4K PFN in
> hand in few places. For instance XENMEM_populate_physmap and
> HYPERVISOR_update_va_mapping.

Ug. For an auto-xlate guest frame-list needs GFNs, for a PV guest
XENMEM_populate_physmap does want PFNs (so it can fill in the M2P).

Perhaps in increase_reservation:

if (auto-xlate)
   frame_list[i] = page_to_gfn(page);
   /* Or whatever per-GFN loop you need. */
else
   frame_list[i] = page_to_pfn(page);

update_va_mapping takes VAs (e.g, __va(pfn << PAGE_SHIFT) could be
page_to_virt(page).

Sorry for being so picky here, but the inconsistency of terminology and
API misuse is already confusing and I don't want to see it get worse.

David

> 
> Although, I'm not sure to understand the difference between GMFN, and
> GPFN in the hypercall doc.
> 
> Regards,
> 



From avienamo at nvidia.com  Wed Aug  5 08:50:31 2015
From: avienamo at nvidia.com (Aapo Vienamo)
Date: Wed, 5 Aug 2015 18:50:31 +0300
Subject: [BUG] arm: kgdb: patch_text() in kgdb_arch_set_breakpoint() may sleep
Message-ID: <55C230C7.2000909@nvidia.com>

Hi,

The breakpoint setting code in arch/arm/kernel/kgdb.c calls
patch_text(), which ends up trying to sleep while in interrupt context.
The bug was introduced by commit: 23a4e40 arm: kgdb: Handle read-only
text / modules. The resulting behavior is "BUG: scheduling while
atomic..." when setting a breakpoint in kgdb. This was tested on an
Nvidia Jetson TK1 board with 4.2.0-rc5-next-20150805 kernel.

Regards,
Aapo Vienamo


From linux at arm.linux.org.uk  Wed Aug  5 09:01:12 2015
From: linux at arm.linux.org.uk (Russell King - ARM Linux)
Date: Wed, 5 Aug 2015 17:01:12 +0100
Subject: [PATCH 7/7] ARM: redo TTBR setup code for LPAE
In-Reply-To: <55C22B21.8000700@free-electrons.com>
References: <20150506103000.GF2067@n2100.arm.linux.org.uk>
 <E1YpwbQ-0000wm-Jx@rmk-PC.arm.linux.org.uk>
 <55C22B21.8000700@free-electrons.com>
Message-ID: <20150805160112.GZ7557@n2100.arm.linux.org.uk>

On Wed, Aug 05, 2015 at 05:26:25PM +0200, Gregory CLEMENT wrote:
> It seems that since the merge of this commit the secondary CPUs on
> Armada XP failed to come online in Big Endian (my configuration is
> mvebu_v7_defconfig+CONFIG_CPU_BIG_ENDIAN=y).

That's probably because I don't test big endian at all, never have done,
and I suspect never will as I've never had systems using BE.  So, I regard
BE as something of a troublesome untestable burden on kernel development.
(And I've always regarded BE to be an abomination.)  In short, I loath
big endian, which really doesn't bode well for me not constantly cocking
it up...

My guess is that it all comes down to much of the new code expecting the
value in r4/r5 to be the least significant 32bits in r4 and the most
significant 32bits in r5.  However, in the secondary code, we load this
using ldrd, which on BE probably reverses that.

> Once I found that this commit introduced the regression I also tested
> but with LPAE but I had the same result: only the first CPU boot.

Not surprising.  I guess BE would need the two registers to mcrr reversing
if they were a 64-bit value loaded with ldrd.

The simple answer may just be to swap r4/r5 after the ldrd.  Trying to do
something different is likely to get into very troublesome problems,
ensuring that r5 doesn't get overwritten (eg, the code which loads the
domain access register would have to switch to a different register -
maybe r4? - but then that needs to be dependent on LE or BE...) and we're
really not going to end up with lots of conditional register usage just
because of annoying BE differences scattered throughout the code.

-- 
FTTC broadband for 0.8mile line: currently at 10.5Mbps down 400kbps up
according to speedtest.net.


From julien.grall at citrix.com  Wed Aug  5 09:06:14 2015
From: julien.grall at citrix.com (Julien Grall)
Date: Wed, 5 Aug 2015 17:06:14 +0100
Subject: [Xen-devel] [PATCH v2 02/20] xen: Introduce a function to split
 a Linux page into Xen page
In-Reply-To: <55C230C9.7060506@citrix.com>
References: <1436474552-31789-1-git-send-email-julien.grall@citrix.com>
 <1436474552-31789-3-git-send-email-julien.grall@citrix.com>
 <55B205FB.5080209@citrix.com> <55B20B56.7020605@citrix.com>
 <55B20F1F.60902@citrix.com> <55C21DF3.2090201@citrix.com>
 <55C230C9.7060506@citrix.com>
Message-ID: <55C23476.8020104@citrix.com>

On 05/08/15 16:50, David Vrabel wrote:
>>>>> Also perhaps make it
>>>>>
>>>>> int xen_for_each_gfn(struct page *page,
>>>>>                      xen_gfn_fn_t fn, void *data);
>>>>
>>>> gfn standing for Guest Frame Number right?
>>>
>>> Yes.  This suggestion is just changing the name to make it more obvious
>>> what it does.
>>
>> Thinking more about this suggestion. The callback (fn) is getting a 4K
>> PFN in parameter and not a GFN.
> 
> I would like only APIs that deal with 64 KiB PFNs and 4 KiB GFNs.  I
> think having a 4 KiB "PFN" is confusing.

I agree with that. Note that helpers splitting Linux page in 4K chunk
such as gnttab_for_each_grant (see patch #3) and this one may still have
the concept of 4K "PFN" for internal purpose.

> Can you rework this xen_for_each_gfn() to pass GFNs to fn, instead?

I will do.

> 
>> This is because the balloon code seems to require having a 4K PFN in
>> hand in few places. For instance XENMEM_populate_physmap and
>> HYPERVISOR_update_va_mapping.
> 
> Ug. For an auto-xlate guest frame-list needs GFNs, for a PV guest
> XENMEM_populate_physmap does want PFNs (so it can fill in the M2P).
> 
> Perhaps in increase_reservation:
> 
> if (auto-xlate)
>    frame_list[i] = page_to_gfn(page);
>    /* Or whatever per-GFN loop you need. */
> else
>    frame_list[i] = page_to_pfn(page);
> 
> update_va_mapping takes VAs (e.g, __va(pfn << PAGE_SHIFT) could be
> page_to_virt(page).

I though about a similar approach but I wanted to keep the code generic,
i.e support the splitting even for non auto-translated guest. Hence the
implementation xen_apply_to_page.

Anyway, I will see to do what you suggest.

> Sorry for being so picky here, but the inconsistency of terminology and
> API misuse is already confusing and I don't want to see it get worse.

No worry, I'm happy to rework this code to be able to drop the 4K PFN
concept.

Regards,

-- 
Julien Grall


From marc.zyngier at arm.com  Wed Aug  5 09:11:37 2015
From: marc.zyngier at arm.com (Marc Zyngier)
Date: Wed, 05 Aug 2015 17:11:37 +0100
Subject: [PATCH v4 1/2] arm64: KVM: Optimize arm64 skip 30-50% vfp/simd
 save/restore on exits
In-Reply-To: <1437082178-11039-2-git-send-email-m.smarduch@samsung.com>
References: <1437082178-11039-1-git-send-email-m.smarduch@samsung.com>
 <1437082178-11039-2-git-send-email-m.smarduch@samsung.com>
Message-ID: <55C235B9.3000800@arm.com>

On 16/07/15 22:29, Mario Smarduch wrote:
> This patch only saves and restores FP/SIMD registers on Guest access. To do
> this cptr_el2 FP/SIMD trap is set on Guest entry and later checked on exit.
> lmbench, hackbench show significant improvements, for 30-50% exits FP/SIMD
> context is not saved/restored
> 
> Signed-off-by: Mario Smarduch <m.smarduch at samsung.com>

So this patch seems to break 32bit guests on arm64.  I've had a look,
squashed a few bugs that I dangerously overlooked during the review, but
it still doesn't work (it doesn't crash anymore, but I get random
illegal VFP instructions in 32bit guests).

I'd be glad if someone could eyeball the following patch and tell me
what's going wrong. If we don't find the root cause quickly enough, I'll
have to drop the series from -next, and that'd be a real shame.

Thanks,

	M.

commit 5777dc55fbc170426a85e00c26002dd5a795cfa5
Author: Marc Zyngier <marc.zyngier at arm.com>
Date:   Wed Aug 5 16:53:01 2015 +0100

    KVM: arm64: NOTAFIX: Prevent crash when 32bit guest uses VFP

    Since we switch FPSIMD in a lazy way, access to FPEXC32_EL2
    must be guarded by skip_fpsimd_state. Otherwise, all hell
    break loose.

    Also, FPEXC32_EL2 must be restored when we trap to EL2 to
    enable floating point.

    Note that while it prevents the host from catching fire, the
    guest still doesn't work properly, and I don't understand why just
    yet.

    Not-really-signed-off-by: Marc Zyngier <marc.zyngier at arm.com>

diff --git a/arch/arm64/kvm/hyp.S b/arch/arm64/kvm/hyp.S
index c8e0c70..b53ec5d 100644
--- a/arch/arm64/kvm/hyp.S
+++ b/arch/arm64/kvm/hyp.S
@@ -431,10 +431,12 @@
 	add	x3, x2, #CPU_SYSREG_OFFSET(DACR32_EL2)
 	mrs	x4, dacr32_el2
 	mrs	x5, ifsr32_el2
-	mrs	x6, fpexc32_el2
 	stp	x4, x5, [x3]
-	str	x6, [x3, #16]

+	skip_fpsimd_state x8, 3f
+	mrs	x6, fpexc32_el2
+	str	x6, [x3, #16]
+3:
 	skip_debug_state x8, 2f
 	mrs	x7, dbgvcr32_el2
 	str	x7, [x3, #24]
@@ -461,10 +463,8 @@

 	add	x3, x2, #CPU_SYSREG_OFFSET(DACR32_EL2)
 	ldp	x4, x5, [x3]
-	ldr	x6, [x3, #16]
 	msr	dacr32_el2, x4
 	msr	ifsr32_el2, x5
-	msr	fpexc32_el2, x6

 	skip_debug_state x8, 2f
 	ldr	x7, [x3, #24]
@@ -669,12 +669,14 @@ __restore_debug:
 	ret

 __save_fpsimd:
+	skip_fpsimd_state x3, 1f
 	save_fpsimd
-	ret
+1:	ret

 __restore_fpsimd:
+	skip_fpsimd_state x3, 1f
 	restore_fpsimd
-	ret
+1:	ret

 switch_to_guest_fpsimd:
 	push	x4, lr
@@ -682,6 +684,7 @@ switch_to_guest_fpsimd:
 	mrs	x2, cptr_el2
 	bic	x2, x2, #CPTR_EL2_TFP
 	msr	cptr_el2, x2
+	isb

 	mrs	x0, tpidr_el2

@@ -692,6 +695,10 @@ switch_to_guest_fpsimd:
 	add	x2, x0, #VCPU_CONTEXT
 	bl __restore_fpsimd

+	skip_32bit_state x3, 1f
+	ldr	x4, [x2, #CPU_SYSREG_OFFSET(FPEXC32_EL2)]
+	msr	fpexc32_el2, x4
+1:
 	pop	x4, lr
 	pop	x2, x3
 	pop	x0, x1
@@ -754,9 +761,7 @@ __kvm_vcpu_return:
 	add	x2, x0, #VCPU_CONTEXT

 	save_guest_regs
-	skip_fpsimd_state x3, 1f
 	bl __save_fpsimd
-1:
 	bl __save_sysregs

 	skip_debug_state x3, 1f
@@ -777,9 +782,7 @@ __kvm_vcpu_return:
 	kern_hyp_va x2

 	bl __restore_sysregs
-	skip_fpsimd_state x3, 1f
 	bl __restore_fpsimd
-1:
 	/* Clear FPSIMD and Trace trapping */
 	msr     cptr_el2, xzr


-- 
Jazz is not dead. It just smells funny...


From will.deacon at arm.com  Wed Aug  5 09:24:52 2015
From: will.deacon at arm.com (Will Deacon)
Date: Wed, 5 Aug 2015 17:24:52 +0100
Subject: [PATCH 05/13] iommu/io-pgtable-arm: Allow appropriate DMA API use
In-Reply-To: <1987558.GfG8OCqzMM@avalon>
References: <1438608355-7335-1-git-send-email-will.deacon@arm.com>
 <55C0D071.1040104@arm.com>
 <20150804145642.GQ7557@n2100.arm.linux.org.uk>
 <1987558.GfG8OCqzMM@avalon>
Message-ID: <20150805162452.GH6092@arm.com>

Hi Laurent,

On Tue, Aug 04, 2015 at 09:54:27PM +0100, Laurent Pinchart wrote:
> On Tuesday 04 August 2015 15:56:42 Russell King - ARM Linux wrote:
> > On Tue, Aug 04, 2015 at 03:47:13PM +0100, Robin Murphy wrote:
> > > On 04/08/15 14:16, Laurent Pinchart wrote:
> > >> This is what I believe to be an API abuse. The
> > >> dma_sync_single_for_device()
> > >> API is meant to pass ownership of a buffer to the device. Unless I'm
> > >> mistaken, once that's done the CPU isn't allowed to touch the buffer
> > >> anymore until dma_sync_single_for_cpu() is called to get ownership of
> > >> the buffer back.
> >
> > That's what I thought up until recently, but it's not strictly true - see
> > Documentation/DMA-API.txt which Robin quoted.
> 
> I find the documentation slightly unclear on this topic. I have nothing 
> against updating it to state that the sync functions ensure visibility of the 
> data to the device or CPU instead of transferring ownership if that's the 
> general understanding of how the API work (or should work). This would of 
> course need to be carefully reviewed to ensure that the current implementation 
> really works that way across all architectures, or at least that it can be 
> made to work that way.

I was hoping to send this lot off to Joerg tomorrow morning, since it's
removing a hack from the io-pgtable users before it has chance to spread
further. This use of the API is certainly ok on arm and arm64 (where
these drivers currently run) and I don't see why it wouldn't work for
any IOMMU that treats the page tables as read-only. Once we start getting
into hardware access/dirty bits, then the streaming-DMA API is a lost
cause but I would expect those systems to be using SVM with the CPU page
tables anyway and therefore be cache-coherent.

I agree that the Documentation isn't brilliant, but that could be addressed
in a separate patch (especially since I don't think it would be merged
via the iommu tree).

Is that alright?

Will


From andrew at lunn.ch  Wed Aug  5 09:21:55 2015
From: andrew at lunn.ch (Andrew Lunn)
Date: Wed, 5 Aug 2015 18:21:55 +0200
Subject: Armadaxp GPIO interrupts
In-Reply-To: <CAG1O52VQPpeGkA8bqYbPMTiT9Mua1yHi3H3osqJsHqm-RRKzow@mail.gmail.com>
References: <CAG1O52Xg88OsifBzmpSdqvC8wQaOW78nC9nnfxugFv1VU1m1LQ@mail.gmail.com>
 <20150804153439.GA28673@lunn.ch>
 <CAG1O52W2Gy_6_DfewtUqoK_J+Y=KwVGyygNaPu2xyPM_ZkLfcQ@mail.gmail.com>
 <CAG1O52VQPpeGkA8bqYbPMTiT9Mua1yHi3H3osqJsHqm-RRKzow@mail.gmail.com>
Message-ID: <20150805162155.GE32760@lunn.ch>

On Wed, Aug 05, 2015 at 08:31:27PM +0530, raghu MG wrote:
> Hi Andrew,
> 
> The issue I found was  irq_alloc_descs is called twice
> 1st time inside   mvebu_gpio_probe & 2nd time inside irq_domain_add_simple.

So i'm somewhat confused. I just tested on my Kirkwood and 370
platforms, and an Armada XP WRT1900AC using 4.2.0-rc5, all which use
the same gpio driver.

They boot fine, the gpio driver is loaded, and the interrupt for the
gpio connected to a button are listed in /proc/interrupts. The
gpio-key driver is also able to use the gpio and the input-events
program does show events when i press the button.

So what is different with your platform?

   Andrew


From lina.iyer at linaro.org  Wed Aug  5 09:32:36 2015
From: lina.iyer at linaro.org (Lina Iyer)
Date: Wed,  5 Aug 2015 10:32:36 -0600
Subject: [PATCH RFC 00/10] qcom: 8084: Cluster idle support
In-Reply-To: <438731339-58317-1-git-send-email-lina.iyer@linaro.org>
References: <438731339-58317-1-git-send-email-lina.iyer@linaro.org>
Message-ID: <1438792366-2737-1-git-send-email-lina.iyer@linaro.org>

This patchset add support to power down the L2 and the PM domain for the CPU
subsystem on Qualcomm's APQ8084. Only 8084 is supported at this time, because
the firmware for chipsets prior to 8084 (8074, 8064) will allow the domain to
be powered off only when running as a single core system. That is, all
secondary cores must be hotplugged off. With 8084, a new feature in the
firmware allows any core to be the last core to enter power down state. The
state of the L2 power controller will be carried as an argument by the last
CPU, when entering SCM.

This patchset extensively uses the changes to GenPD and the CPU PM domain
introduced by [1]. Also under discussion on the mailing list, is the hwspinlock
changes that are part of this series.

I have tested this on 8084. But invalidating cache causes a system hang and is
under investigation. This patchset at this time is only provided as a proof of
concept for using CPU PM domains.

Thanks,
Lina

[1]. http://www.spinics.net/lists/arm-kernel/msg437091.html

Lina Iyer (10):
  drivers: qcom: spm: Support cache SPMs
  drivers: qcom: spm: Add 8084 L2 SPM register data
  drivers: qcom: spm: Enable runtime suspend/resume of CPU PM domain
  arm: dts: Add L2 power-controller device bindings for APQ8084
  arm: dts: Add power domain device bindings for APQ8084
  drivers: qcom: Enable genpd on selecting QCOM_PM
  hwspinlock: Introduce raw capability for hwspinlocks
  hwspinlock: qcom: Lock #7 is special lock, uses dynamic proc_id
  drivers: qcom: spm: Use hwspinlock to serialize entry into SCM
  arm: dts: qcom: Add TCSR mutex device bindings for APQ8084

 .../devicetree/bindings/arm/msm/qcom,saw2.txt      |   1 +
 Documentation/hwspinlock.txt                       |  16 +++
 arch/arm/boot/dts/qcom-apq8084.dtsi                |  21 +++-
 drivers/hwspinlock/hwspinlock_core.c               |  75 +++++++-----
 drivers/hwspinlock/hwspinlock_internal.h           |   6 +
 drivers/hwspinlock/qcom_hwspinlock.c               |  22 +++-
 drivers/soc/qcom/Kconfig                           |   5 +
 drivers/soc/qcom/spm.c                             | 130 ++++++++++++++++++---
 include/linux/hwspinlock.h                         |  41 +++++++
 9 files changed, 264 insertions(+), 53 deletions(-)

-- 
2.1.4



From lina.iyer at linaro.org  Wed Aug  5 09:32:37 2015
From: lina.iyer at linaro.org (Lina Iyer)
Date: Wed,  5 Aug 2015 10:32:37 -0600
Subject: [PATCH RFC 01/10] drivers: qcom: spm: Support cache SPMs
In-Reply-To: <1438792366-2737-1-git-send-email-lina.iyer@linaro.org>
References: <438731339-58317-1-git-send-email-lina.iyer@linaro.org>
 <1438792366-2737-1-git-send-email-lina.iyer@linaro.org>
Message-ID: <1438792366-2737-2-git-send-email-lina.iyer@linaro.org>

Recognize cache SPM devices defined in the DT and configure the
corresponding SPM hardware. SPM controllers for L2 controls the cache's
idle low power state and may also be used to turn off the CPU power
rail.

Cc: Stephen Boyd <sboyd at codeaurora.org>
Cc: Andy Gross <agross at codeaurora.org>
Signed-off-by: Lina Iyer <lina.iyer at linaro.org>
---
 drivers/soc/qcom/spm.c | 45 ++++++++++++++++++++++++++++++---------------
 1 file changed, 30 insertions(+), 15 deletions(-)

diff --git a/drivers/soc/qcom/spm.c b/drivers/soc/qcom/spm.c
index b04b05a..9f5edaa27 100644
--- a/drivers/soc/qcom/spm.c
+++ b/drivers/soc/qcom/spm.c
@@ -115,6 +115,7 @@ static const struct spm_reg_data spm_reg_8064_cpu = {
 };
 
 static DEFINE_PER_CPU(struct spm_driver_data *, cpu_spm_drv);
+static struct spm_driver_data *domain_spm;
 
 typedef int (*idle_fn)(int);
 static DEFINE_PER_CPU(idle_fn*, qcom_idle_ops);
@@ -283,13 +284,18 @@ CPUIDLE_METHOD_OF_DECLARE(qcom_idle_v1, "qcom,kpss-acc-v1", &qcom_cpuidle_ops);
 CPUIDLE_METHOD_OF_DECLARE(qcom_idle_v2, "qcom,kpss-acc-v2", &qcom_cpuidle_ops);
 
 static struct spm_driver_data *spm_get_drv(struct platform_device *pdev,
-		int *spm_cpu)
+		int *index, bool *is_domain_spm)
 {
 	struct spm_driver_data *drv = NULL;
 	struct device_node *cpu_node, *saw_node;
 	int cpu;
 	bool found;
 
+	drv = devm_kzalloc(&pdev->dev, sizeof(*drv), GFP_KERNEL);
+	if (!drv)
+		return ERR_PTR(-ENOMEM);
+
+	/* Check for a CPU SPM, if found we are done */
 	for_each_possible_cpu(cpu) {
 		cpu_node = of_cpu_device_node_get(cpu);
 		if (!cpu_node)
@@ -302,11 +308,14 @@ static struct spm_driver_data *spm_get_drv(struct platform_device *pdev,
 			break;
 	}
 
-	if (found) {
-		drv = devm_kzalloc(&pdev->dev, sizeof(*drv), GFP_KERNEL);
-		if (drv)
-			*spm_cpu = cpu;
-	}
+	/* 
+	 * If found, we have a CPU SPM, if not,
+	 * we have a cache SPM
+	 */
+	if (found)
+		*index = cpu;
+
+	*is_domain_spm = !found;
 
 	return drv;
 }
@@ -327,21 +336,22 @@ static int spm_dev_probe(struct platform_device *pdev)
 	struct resource *res;
 	const struct of_device_id *match_id;
 	void __iomem *addr;
-	int cpu;
+	int index;
+	bool is_domain_spm;
 
-	drv = spm_get_drv(pdev, &cpu);
-	if (!drv)
-		return -EINVAL;
+	match_id = of_match_node(spm_match_table, pdev->dev.of_node);
+	if (!match_id)
+		return -ENODEV;
+
+	drv = spm_get_drv(pdev, &index, &is_domain_spm);
+	if (IS_ERR(drv))
+		return PTR_ERR(drv);
 
 	res = platform_get_resource(pdev, IORESOURCE_MEM, 0);
 	drv->reg_base = devm_ioremap_resource(&pdev->dev, res);
 	if (IS_ERR(drv->reg_base))
 		return PTR_ERR(drv->reg_base);
 
-	match_id = of_match_node(spm_match_table, pdev->dev.of_node);
-	if (!match_id)
-		return -ENODEV;
-
 	drv->reg_data = match_id->data;
 
 	/* Write the SPM sequences first.. */
@@ -366,8 +376,13 @@ static int spm_dev_probe(struct platform_device *pdev)
 	/* Set up Standby as the default low power mode */
 	spm_set_low_power_mode(drv, PM_SLEEP_MODE_STBY);
 
-	per_cpu(cpu_spm_drv, cpu) = drv;
+	/* We are ready to use the CPU/Cache SPM. */
+	if (is_domain_spm)
+		domain_spm = drv;
+	else
+		per_cpu(cpu_spm_drv, index) = drv;
 
+	dev_dbg(&pdev->dev, "SPM device probed.\n");
 	return 0;
 }
 
-- 
2.1.4



From lina.iyer at linaro.org  Wed Aug  5 09:32:38 2015
From: lina.iyer at linaro.org (Lina Iyer)
Date: Wed,  5 Aug 2015 10:32:38 -0600
Subject: [PATCH RFC 02/10] drivers: qcom: spm: Add 8084 L2 SPM register data
In-Reply-To: <1438792366-2737-1-git-send-email-lina.iyer@linaro.org>
References: <438731339-58317-1-git-send-email-lina.iyer@linaro.org>
 <1438792366-2737-1-git-send-email-lina.iyer@linaro.org>
Message-ID: <1438792366-2737-3-git-send-email-lina.iyer@linaro.org>

Add register data and configure L2 SAW to support voltage control and L2
idle states for QCOM APQ8084 SoC.

Signed-off-by: Lina Iyer <lina.iyer at linaro.org>
---
 .../devicetree/bindings/arm/msm/qcom,saw2.txt         |  1 +
 drivers/soc/qcom/spm.c                                | 19 +++++++++++++++++++
 2 files changed, 20 insertions(+)

diff --git a/Documentation/devicetree/bindings/arm/msm/qcom,saw2.txt b/Documentation/devicetree/bindings/arm/msm/qcom,saw2.txt
index ae4afc6..91430ff 100644
--- a/Documentation/devicetree/bindings/arm/msm/qcom,saw2.txt
+++ b/Documentation/devicetree/bindings/arm/msm/qcom,saw2.txt
@@ -27,6 +27,7 @@ PROPERTIES
 			"qcom,apq8064-saw2-v1.1-cpu"
 			"qcom,msm8974-saw2-v2.1-cpu"
 			"qcom,apq8084-saw2-v2.1-cpu"
+			"qcom,apq8084-saw2-v2.1-l2"
 
 - reg:
 	Usage: required
diff --git a/drivers/soc/qcom/spm.c b/drivers/soc/qcom/spm.c
index 9f5edaa27..efbf5e5 100644
--- a/drivers/soc/qcom/spm.c
+++ b/drivers/soc/qcom/spm.c
@@ -78,6 +78,8 @@ static const u8 spm_reg_offset_v2_1[SPM_REG_NR] = {
 	[SPM_REG_SPM_CTL]	= 0x30,
 	[SPM_REG_DLY]		= 0x34,
 	[SPM_REG_SEQ_ENTRY]	= 0x80,
+	[SPM_REG_PMIC_DATA_0]	= 0x40,
+	[SPM_REG_PMIC_DATA_1]	= 0x44,
 };
 
 /* SPM register data for 8974, 8084 */
@@ -92,6 +94,20 @@ static const struct spm_reg_data spm_reg_8974_8084_cpu  = {
 	.start_index[PM_SLEEP_MODE_SPC] = 3,
 };
 
+static const struct spm_reg_data spm_reg_8084_l2  = {
+	.reg_offset = spm_reg_offset_v2_1,
+	.spm_cfg = 0x14,
+	.spm_dly = 0x3C102800,
+	.pmic_data[0] = 0x02030080,
+	.pmic_data[1] = 0x00030000,
+	.seq = { 0x1F, 0x00, 0x20, 0x03, 0x22, 0x00, 0x0F, 0x00, 0x10, 0x22,
+		0x12, 0x32, 0x60, 0x70, 0x80, 0xB0, 0x11, 0x42, 0x03, 0x01,
+		0xB0, 0x78, 0x80, 0x12, 0x22, 0x44, 0x50, 0x3B, 0x60, 0x02,
+		0x32, 0x50, 0x0F },
+	.start_index[PM_SLEEP_MODE_STBY] = 0,
+	.start_index[PM_SLEEP_MODE_SPC] = 7,
+};
+
 static const u8 spm_reg_offset_v1_1[SPM_REG_NR] = {
 	[SPM_REG_CFG]		= 0x08,
 	[SPM_REG_SPM_CTL]	= 0x20,
@@ -186,6 +202,7 @@ static int qcom_cpu_spc(int cpu)
 	struct spm_driver_data *drv = per_cpu(cpu_spm_drv, cpu);
 
 	spm_set_low_power_mode(drv, PM_SLEEP_MODE_SPC);
+
 	ret = cpu_suspend(0, qcom_pm_collapse);
 	/*
 	 * ARM common code executes WFI without calling into our driver and
@@ -327,6 +344,8 @@ static const struct of_device_id spm_match_table[] = {
 	  .data = &spm_reg_8974_8084_cpu },
 	{ .compatible = "qcom,apq8064-saw2-v1.1-cpu",
 	  .data = &spm_reg_8064_cpu },
+	{ .compatible = "qcom,apq8084-saw2-v2.1-l2",
+	  .data = &spm_reg_8084_l2 },
 	{ },
 };
 
-- 
2.1.4



From lina.iyer at linaro.org  Wed Aug  5 09:32:39 2015
From: lina.iyer at linaro.org (Lina Iyer)
Date: Wed,  5 Aug 2015 10:32:39 -0600
Subject: [PATCH RFC 03/10] drivers: qcom: spm: Enable runtime suspend/resume
 of CPU PM domain
In-Reply-To: <1438792366-2737-1-git-send-email-lina.iyer@linaro.org>
References: <438731339-58317-1-git-send-email-lina.iyer@linaro.org>
 <1438792366-2737-1-git-send-email-lina.iyer@linaro.org>
Message-ID: <1438792366-2737-4-git-send-email-lina.iyer@linaro.org>

On APQ8084 QCOM SoC's, the CPUs are powered by a single rail controlled
by the L2 cache power controller (L2 SPM). The L2 power domain supplies
power to all the CPUs and L2. It is safe to power down the domain when
all the CPUs and the L2 are powered down.

Powering down of the domain is done through the finite state machine on
the L2 SAW. The L2 SPM can be configured to enter an idle state, when
all CPUs enter their idle state. The L2 SPM state machine would turn off
the cache and possibly power off the power domain as well. The SPM also
guarantees that the h/w is ready for the CPU to resume, when woken up by
an interrupt.

Define a cluster that holds the SPM and possibly other common cluster
elements. The L2 SAW is also the genpd domain provider and the CPUs are
the devices attached to the domain. When CPUIdle powers down each CPU,
the ARM domain framework would callback to notify that the domain may be
powered off. Configure the L2 SPM at that time to flush the L2 cache and
turn off the CPU power rail.

Signed-off-by: Lina Iyer <lina.iyer at linaro.org>
---
 drivers/soc/qcom/spm.c | 40 +++++++++++++++++++++++++++++++++++++++-
 1 file changed, 39 insertions(+), 1 deletion(-)

diff --git a/drivers/soc/qcom/spm.c b/drivers/soc/qcom/spm.c
index efbf5e5..b6d75db 100644
--- a/drivers/soc/qcom/spm.c
+++ b/drivers/soc/qcom/spm.c
@@ -24,8 +24,11 @@
 #include <linux/platform_device.h>
 #include <linux/cpuidle.h>
 #include <linux/cpu_pm.h>
+#include <linux/pm_domain.h>
 #include <linux/qcom_scm.h>
 
+#include <asm/arm-pd.h>
+#include <asm/cacheflush.h>
 #include <asm/cpuidle.h>
 #include <asm/proc-fns.h>
 #include <asm/suspend.h>
@@ -132,6 +135,7 @@ static const struct spm_reg_data spm_reg_8064_cpu = {
 
 static DEFINE_PER_CPU(struct spm_driver_data *, cpu_spm_drv);
 static struct spm_driver_data *domain_spm;
+static int l2_flush_flag;
 
 typedef int (*idle_fn)(int);
 static DEFINE_PER_CPU(idle_fn*, qcom_idle_ops);
@@ -187,7 +191,14 @@ static void spm_set_low_power_mode(struct spm_driver_data *drv,
 
 static int qcom_pm_collapse(unsigned long int unused)
 {
-	qcom_scm_cpu_power_down(QCOM_SCM_CPU_PWR_DOWN_L2_ON);
+	/*
+	 * Flush the non-secure cache for Krait processors.
+	 * SCM will flush the secure cache.
+	 */
+	if (l2_flush_flag == QCOM_SCM_CPU_PWR_DOWN_L2_OFF)
+		flush_cache_all();
+
+	qcom_scm_cpu_power_down(l2_flush_flag);
 
 	/*
 	 * Returns here only if there was a pending interrupt and we did not
@@ -300,6 +311,33 @@ static struct cpuidle_ops qcom_cpuidle_ops __initdata = {
 CPUIDLE_METHOD_OF_DECLARE(qcom_idle_v1, "qcom,kpss-acc-v1", &qcom_cpuidle_ops);
 CPUIDLE_METHOD_OF_DECLARE(qcom_idle_v2, "qcom,kpss-acc-v2", &qcom_cpuidle_ops);
 
+static int pd_init(struct device_node *dn, struct generic_pm_domain *domain)
+{
+	return 0;
+}
+
+static int pd_power_on(struct generic_pm_domain *domain)
+{
+	l2_flush_flag = QCOM_SCM_CPU_PWR_DOWN_L2_ON;
+	spm_set_low_power_mode(domain_spm, PM_SLEEP_MODE_STBY);
+	return 0;
+}
+
+static int pd_power_off(struct generic_pm_domain *domain)
+{
+	l2_flush_flag = QCOM_SCM_CPU_PWR_DOWN_L2_OFF;
+	spm_set_low_power_mode(domain_spm, PM_SLEEP_MODE_SPC);
+	return 0;
+}
+
+static struct of_arm_pd_ops pd_ops __initdata = {
+	.init = pd_init,
+	.power_on = pd_power_on,
+	.power_off = pd_power_off,
+};
+
+ARM_PD_METHOD_OF_DECLARE(qcom_cpu_pd, "qcom,apq8084-saw2-v2.1-l2", &pd_ops);
+
 static struct spm_driver_data *spm_get_drv(struct platform_device *pdev,
 		int *index, bool *is_domain_spm)
 {
-- 
2.1.4



From lina.iyer at linaro.org  Wed Aug  5 09:32:40 2015
From: lina.iyer at linaro.org (Lina Iyer)
Date: Wed,  5 Aug 2015 10:32:40 -0600
Subject: [PATCH RFC 04/10] arm: dts: Add L2 power-controller device bindings
 for APQ8084
In-Reply-To: <1438792366-2737-1-git-send-email-lina.iyer@linaro.org>
References: <438731339-58317-1-git-send-email-lina.iyer@linaro.org>
 <1438792366-2737-1-git-send-email-lina.iyer@linaro.org>
Message-ID: <1438792366-2737-5-git-send-email-lina.iyer@linaro.org>

Add power controller (SAW) device nodes for L2 caches. L2 SAW enable L2
to enter idle states and be powered off. Also, on 8084 the L2 SAW may be
used to regulate the active voltage for the cpu and L2.

Signed-off-by: Lina Iyer <lina.iyer at linaro.org>
---
 arch/arm/boot/dts/qcom-apq8084.dtsi | 4 ++--
 1 file changed, 2 insertions(+), 2 deletions(-)

diff --git a/arch/arm/boot/dts/qcom-apq8084.dtsi b/arch/arm/boot/dts/qcom-apq8084.dtsi
index 7084010..900ef1f 100644
--- a/arch/arm/boot/dts/qcom-apq8084.dtsi
+++ b/arch/arm/boot/dts/qcom-apq8084.dtsi
@@ -59,7 +59,7 @@
 		};
 
 		L2: l2-cache {
-			compatible = "qcom,arch-cache";
+			compatible = "cache";
 			cache-level = <2>;
 			qcom,saw = <&saw_l2>;
 		};
@@ -183,7 +183,7 @@
 		};
 
 		saw_l2: power-controller at f9012000 {
-			compatible = "qcom,saw2";
+			compatible = "qcom,apq8084-saw2-v2.1-l2", "qcom,saw2";
 			reg = <0xf9012000 0x1000>;
 			regulator;
 		};
-- 
2.1.4



From lina.iyer at linaro.org  Wed Aug  5 09:32:44 2015
From: lina.iyer at linaro.org (Lina Iyer)
Date: Wed,  5 Aug 2015 10:32:44 -0600
Subject: [PATCH RFC 08/10] hwspinlock: qcom: Lock #7 is special lock,
 uses dynamic proc_id
In-Reply-To: <1438792366-2737-1-git-send-email-lina.iyer@linaro.org>
References: <438731339-58317-1-git-send-email-lina.iyer@linaro.org>
 <1438792366-2737-1-git-send-email-lina.iyer@linaro.org>
Message-ID: <1438792366-2737-9-git-send-email-lina.iyer@linaro.org>

Hwspinlocks are widely used between processors in an SoC, and also
between elevation levels within in the same processor.  QCOM SoC's use
hwspinlock to serialize entry into a low power mode when the context
switches from Linux to secure monitor.

Lock #7 has been assigned for this purpose. In order to differentiate
between one cpu core holding a lock while another cpu is contending for
the same lock, the proc id written into the lock is (128 + cpu id). This
makes it unique value among the cpu cores and therefore when a core
locks the hwspinlock, other cores would wait for the lock to be released
since they would have a different proc id.  This value is specific for
the lock #7 only.

Declare lock #7 as raw capable, so the hwspinlock framework would not
enfore acquiring a s/w spinlock before acquiring the hwspinlock.

Cc: Jeffrey Hugo <jhugo at codeaurora.org>
Cc: Bjorn Andersson <bjorn.andersson at sonymobile.com>
Cc: Andy Gross <agross at codeaurora.org>
Signed-off-by: Lina Iyer <lina.iyer at linaro.org>
---
 drivers/hwspinlock/qcom_hwspinlock.c | 22 +++++++++++++++++-----
 1 file changed, 17 insertions(+), 5 deletions(-)

diff --git a/drivers/hwspinlock/qcom_hwspinlock.c b/drivers/hwspinlock/qcom_hwspinlock.c
index c752447..573f0dd 100644
--- a/drivers/hwspinlock/qcom_hwspinlock.c
+++ b/drivers/hwspinlock/qcom_hwspinlock.c
@@ -25,16 +25,26 @@
 
 #include "hwspinlock_internal.h"
 
-#define QCOM_MUTEX_APPS_PROC_ID	1
-#define QCOM_MUTEX_NUM_LOCKS	32
+#define QCOM_MUTEX_APPS_PROC_ID		1
+#define QCOM_MUTEX_CPUIDLE_OFFSET	128
+#define QCOM_CPUIDLE_LOCK		7
+#define QCOM_MUTEX_NUM_LOCKS		32
+
+static inline u32 __qcom_get_proc_id(struct hwspinlock *lock)
+{
+	return hwspin_lock_get_id(lock) == QCOM_CPUIDLE_LOCK ?
+			(QCOM_MUTEX_CPUIDLE_OFFSET + smp_processor_id()) :
+			QCOM_MUTEX_APPS_PROC_ID;
+}
 
 static int qcom_hwspinlock_trylock(struct hwspinlock *lock)
 {
 	struct regmap_field *field = lock->priv;
 	u32 lock_owner;
 	int ret;
+	u32 proc_id = __qcom_get_proc_id(lock);
 
-	ret = regmap_field_write(field, QCOM_MUTEX_APPS_PROC_ID);
+	ret = regmap_field_write(field, proc_id);
 	if (ret)
 		return ret;
 
@@ -42,7 +52,7 @@ static int qcom_hwspinlock_trylock(struct hwspinlock *lock)
 	if (ret)
 		return ret;
 
-	return lock_owner == QCOM_MUTEX_APPS_PROC_ID;
+	return lock_owner == proc_id;
 }
 
 static void qcom_hwspinlock_unlock(struct hwspinlock *lock)
@@ -57,7 +67,7 @@ static void qcom_hwspinlock_unlock(struct hwspinlock *lock)
 		return;
 	}
 
-	if (lock_owner != QCOM_MUTEX_APPS_PROC_ID) {
+	if (lock_owner != __qcom_get_proc_id(lock)) {
 		pr_err("%s: spinlock not owned by us (actual owner is %d)\n",
 				__func__, lock_owner);
 	}
@@ -129,6 +139,8 @@ static int qcom_hwspinlock_probe(struct platform_device *pdev)
 							     regmap, field);
 	}
 
+	bank->lock[QCOM_CPUIDLE_LOCK].hwcaps = HWL_CAP_ALLOW_RAW;
+
 	pm_runtime_enable(&pdev->dev);
 
 	ret = hwspin_lock_register(bank, &pdev->dev, &qcom_hwspinlock_ops,
-- 
2.1.4



From lina.iyer at linaro.org  Wed Aug  5 09:32:43 2015
From: lina.iyer at linaro.org (Lina Iyer)
Date: Wed,  5 Aug 2015 10:32:43 -0600
Subject: [PATCH RFC 07/10] hwspinlock: Introduce raw capability for hwspinlocks
In-Reply-To: <1438792366-2737-1-git-send-email-lina.iyer@linaro.org>
References: <438731339-58317-1-git-send-email-lina.iyer@linaro.org>
 <1438792366-2737-1-git-send-email-lina.iyer@linaro.org>
Message-ID: <1438792366-2737-8-git-send-email-lina.iyer@linaro.org>

The hwspinlock framework, uses a s/w spin lock around the hw spinlock to
ensure that only process acquires the lock at any time. This is the most
general use case. A special case is where a hwspinlock may be acquired
in Linux and a remote entity may release the lock. In such a case, the
s/w spinlock may never be unlocked as Linux would never call
hwspin_unlock on the hwlock.

This special case is needed for serializing the processor across context
switches from Linux to firmware. Multiple cores may enter cpu idle and
would switch context to firmware to power off. A cpu holding the
hwspinlock would cause other cpus to wait to acquire the lock, until the
lock is released by the firmware. The last core to power down per Linux
has the correct state of the shared resources and should be the one
considered by the firmware. However, a cpu may be stuck handling FIQs
and therefore the last man view of Linux and the firmware may differ. A
hwspinlock avoids this problem by serializing the entry from Linux to
firmware.

Introduce hwcaps member for hwspinlock_device. The hwcaps represents the
hw capability of each hwlock. The platform driver is responsible for
specifying this capability for each lock in the bank. A lock that has
HWL_CAP_ALLOW_RAW set, would indicate to the framework, the capability
for ensure locking correctness in the platform. Since no sw spinlock
guards the hwspinlock, it is the responsibility of the platform driver
to ensure that an unique value is written to the hwspinlock to ensure
locking correctness.

Drivers may use hwspin_trylock_raw() and hwspin_unlock_raw() api to lock
and unlock a hwlock with raw capability.

Cc: Jeffrey Hugo <jhugo at codeaurora.org>
Cc: Ohad Ben-Cohen <ohad at wizery.com>
Cc: Andy Gross <agross at codeaurora.org>
Signed-off-by: Lina Iyer <lina.iyer at linaro.org>
---
 Documentation/hwspinlock.txt             | 16 +++++++
 drivers/hwspinlock/hwspinlock_core.c     | 75 +++++++++++++++++++-------------
 drivers/hwspinlock/hwspinlock_internal.h |  6 +++
 include/linux/hwspinlock.h               | 41 +++++++++++++++++
 4 files changed, 108 insertions(+), 30 deletions(-)

diff --git a/Documentation/hwspinlock.txt b/Documentation/hwspinlock.txt
index 61c1ee9..4fd3f55 100644
--- a/Documentation/hwspinlock.txt
+++ b/Documentation/hwspinlock.txt
@@ -132,6 +132,15 @@ independent, drivers.
      notably -EBUSY if the hwspinlock was already taken).
      The function will never sleep.
 
+  int hwspin_trylock_raw(struct hwspinlock *hwlock);
+   - attempt to lock a previously-assigned hwspinlock, but immediately fail if
+     it is already taken. The lock must have been declared by the platform
+     drv code with raw capability support.
+     Returns 0 on success and an appropriate error code otherwise (most
+     notably -EBUSY if the hwspinlock was already taken).
+     This function does not use a sw spinlock around the hwlock. The
+     responsiblity of the lock is guaranteed by the platform code.
+
   void hwspin_unlock(struct hwspinlock *hwlock);
    - unlock a previously-locked hwspinlock. Always succeed, and can be called
      from any context (the function never sleeps). Note: code should _never_
@@ -154,6 +163,13 @@ independent, drivers.
      and the state of the local interrupts is restored to the state saved at
      the given flags. This function will never sleep.
 
+  void hwspin_unlock_raw(struct hwspinlock *hwlock);
+   - unlock a previously-locked hwspinlock. Always succeed, and can be called
+     from any context (the function never sleeps). Note: code should _never_
+     unlock an hwspinlock which is already unlocked (there is no protection
+     against this). The platform driver must support raw capability for this
+     hwlock.
+
   int hwspin_lock_get_id(struct hwspinlock *hwlock);
    - retrieve id number of a given hwspinlock. This is needed when an
      hwspinlock is dynamically assigned: before it can be used to achieve
diff --git a/drivers/hwspinlock/hwspinlock_core.c b/drivers/hwspinlock/hwspinlock_core.c
index 52f708b..0d2baa3 100644
--- a/drivers/hwspinlock/hwspinlock_core.c
+++ b/drivers/hwspinlock/hwspinlock_core.c
@@ -80,7 +80,10 @@ static DEFINE_MUTEX(hwspinlock_tree_lock);
  * whether he wants their previous state to be saved. It is up to the user
  * to choose the appropriate @mode of operation, exactly the same way users
  * should decide between spin_trylock, spin_trylock_irq and
- * spin_trylock_irqsave.
+ * spin_trylock_irqsave and even no spinlock, if the hwspinlock is always
+ * acquired in an interrupt disabled context. The platform driver that
+ * registers such a lock, would explicity specify the capability for the
+ * lock with the HWL_CAP_ALLOW_RAW capability flag.
  *
  * Returns 0 if we successfully locked the hwspinlock or -EBUSY if
  * the hwspinlock was already taken.
@@ -92,6 +95,7 @@ int __hwspin_trylock(struct hwspinlock *hwlock, int mode, unsigned long *flags)
 
 	BUG_ON(!hwlock);
 	BUG_ON(!flags && mode == HWLOCK_IRQSTATE);
+	BUG_ON((hwlock->hwcaps & HWL_CAP_ALLOW_RAW) && (mode != HWLOCK_NOLOCK));
 
 	/*
 	 * This spin_lock{_irq, _irqsave} serves three purposes:
@@ -106,32 +110,36 @@ int __hwspin_trylock(struct hwspinlock *hwlock, int mode, unsigned long *flags)
 	 *    problems with hwspinlock usage (e.g. scheduler checks like
 	 *    'scheduling while atomic' etc.)
 	 */
-	if (mode == HWLOCK_IRQSTATE)
-		ret = spin_trylock_irqsave(&hwlock->lock, *flags);
-	else if (mode == HWLOCK_IRQ)
-		ret = spin_trylock_irq(&hwlock->lock);
-	else
-		ret = spin_trylock(&hwlock->lock);
-
-	/* is lock already taken by another context on the local cpu ? */
-	if (!ret)
-		return -EBUSY;
-
-	/* try to take the hwspinlock device */
-	ret = hwlock->bank->ops->trylock(hwlock);
-
-	/* if hwlock is already taken, undo spin_trylock_* and exit */
-	if (!ret) {
+	if (mode != HWLOCK_NOLOCK) {
 		if (mode == HWLOCK_IRQSTATE)
-			spin_unlock_irqrestore(&hwlock->lock, *flags);
+			ret = spin_trylock_irqsave(&hwlock->lock, *flags);
 		else if (mode == HWLOCK_IRQ)
-			spin_unlock_irq(&hwlock->lock);
+			ret = spin_trylock_irq(&hwlock->lock);
 		else
-			spin_unlock(&hwlock->lock);
+			ret = spin_trylock(&hwlock->lock);
 
-		return -EBUSY;
+		/* is lock already taken by another context on the local cpu? */
+		if (!ret)
+			return -EBUSY;
+	}
+
+	/* try to take the hwspinlock device */
+	ret = hwlock->bank->ops->trylock(hwlock);
+
+	if (mode != HWLOCK_NOLOCK) {
+		/* if hwlock is already taken, undo spin_trylock_* and exit */
+		if (!ret) {
+			if (mode == HWLOCK_IRQSTATE)
+				spin_unlock_irqrestore(&hwlock->lock, *flags);
+			else if (mode == HWLOCK_IRQ)
+				spin_unlock_irq(&hwlock->lock);
+			else
+				spin_unlock(&hwlock->lock);
+		}
 	}
 
+	if (!ret)
+		return -EBUSY;
 	/*
 	 * We can be sure the other core's memory operations
 	 * are observable to us only _after_ we successfully take
@@ -223,7 +231,10 @@ EXPORT_SYMBOL_GPL(__hwspin_lock_timeout);
  * if yes, whether he wants their previous state to be restored. It is up
  * to the user to choose the appropriate @mode of operation, exactly the
  * same way users decide between spin_unlock, spin_unlock_irq and
- * spin_unlock_irqrestore.
+ * spin_unlock_irqrestore and even no spinlock, if the hwspinlock is always
+ * acquired in an interrupt disabled context. The platform driver that
+ * registers such a lock, would explicity specify the capability for the
+ * lock with the HWL_CAP_ALLOW_RAW capability flag.
  *
  * The function will never sleep.
  */
@@ -231,6 +242,7 @@ void __hwspin_unlock(struct hwspinlock *hwlock, int mode, unsigned long *flags)
 {
 	BUG_ON(!hwlock);
 	BUG_ON(!flags && mode == HWLOCK_IRQSTATE);
+	BUG_ON((hwlock->hwcaps & HWL_CAP_ALLOW_RAW) && (mode != HWLOCK_NOLOCK));
 
 	/*
 	 * We must make sure that memory operations (both reads and writes),
@@ -248,13 +260,15 @@ void __hwspin_unlock(struct hwspinlock *hwlock, int mode, unsigned long *flags)
 
 	hwlock->bank->ops->unlock(hwlock);
 
-	/* Undo the spin_trylock{_irq, _irqsave} called while locking */
-	if (mode == HWLOCK_IRQSTATE)
-		spin_unlock_irqrestore(&hwlock->lock, *flags);
-	else if (mode == HWLOCK_IRQ)
-		spin_unlock_irq(&hwlock->lock);
-	else
-		spin_unlock(&hwlock->lock);
+	if (mode != HWLOCK_NOLOCK) {
+		/* Undo the spin_trylock{_irq, _irqsave} called while locking */
+		if (mode == HWLOCK_IRQSTATE)
+			spin_unlock_irqrestore(&hwlock->lock, *flags);
+		else if (mode == HWLOCK_IRQ)
+			spin_unlock_irq(&hwlock->lock);
+		else
+			spin_unlock(&hwlock->lock);
+	}
 }
 EXPORT_SYMBOL_GPL(__hwspin_unlock);
 
@@ -421,7 +435,8 @@ int hwspin_lock_register(struct hwspinlock_device *bank, struct device *dev,
 	for (i = 0; i < num_locks; i++) {
 		hwlock = &bank->lock[i];
 
-		spin_lock_init(&hwlock->lock);
+		if (!(hwlock->hwcaps & HWL_CAP_ALLOW_RAW))
+			spin_lock_init(&hwlock->lock);
 		hwlock->bank = bank;
 
 		ret = hwspin_lock_register_single(hwlock, base_id + i);
diff --git a/drivers/hwspinlock/hwspinlock_internal.h b/drivers/hwspinlock/hwspinlock_internal.h
index d26f78b..24a4d79 100644
--- a/drivers/hwspinlock/hwspinlock_internal.h
+++ b/drivers/hwspinlock/hwspinlock_internal.h
@@ -21,6 +21,9 @@
 #include <linux/spinlock.h>
 #include <linux/device.h>
 
+/* hwspinlock capability properties */
+#define HWL_CAP_ALLOW_RAW	BIT(1)
+
 struct hwspinlock_device;
 
 /**
@@ -44,11 +47,14 @@ struct hwspinlock_ops {
  * @bank: the hwspinlock_device structure which owns this lock
  * @lock: initialized and used by hwspinlock core
  * @priv: private data, owned by the underlying platform-specific hwspinlock drv
+ * @hwcaps: hardware capablity, like raw lock, that does not need s/w spinlock
+ * around the hwspinlock.
  */
 struct hwspinlock {
 	struct hwspinlock_device *bank;
 	spinlock_t lock;
 	void *priv;
+	int hwcaps;
 };
 
 /**
diff --git a/include/linux/hwspinlock.h b/include/linux/hwspinlock.h
index 859d673..f173352 100644
--- a/include/linux/hwspinlock.h
+++ b/include/linux/hwspinlock.h
@@ -24,6 +24,7 @@
 /* hwspinlock mode argument */
 #define HWLOCK_IRQSTATE	0x01	/* Disable interrupts, save state */
 #define HWLOCK_IRQ	0x02	/* Disable interrupts, don't save state */
+#define HWLOCK_NOLOCK	0xFF	/* Dont take any lock */
 
 struct device;
 struct device_node;
@@ -196,6 +197,27 @@ static inline int hwspin_trylock(struct hwspinlock *hwlock)
 }
 
 /**
+ * hwspin_trylock_raw() - attempt to lock a specific hwspinlock without s/w
+ * spinlocks
+ * @hwlock: the hwspinlock which we want to trylock
+ *
+ * This function attempts to lock the hwspinlock without acquiring a s/w
+ * spinlock. The function will return failure if the lock is already taken.
+ *
+ * The function can only be used on a hwlock that has been initialized with
+ * raw capability by the platform drv.
+ *
+ * The function is expected to be called in an interrupt disabled context.
+ *
+ * Returns 0 if we successfully locked the hwspinlock, -EBUSY if the hwspinlock
+ * is already taken.
+ */
+static inline int hwspin_trylock_raw(struct hwspinlock *hwlock)
+{
+	return __hwspin_trylock(hwlock, HWLOCK_NOLOCK, NULL);
+}
+
+/**
  * hwspin_lock_timeout_irqsave() - lock hwspinlock, with timeout, disable irqs
  * @hwlock: the hwspinlock to be locked
  * @to: timeout value in msecs
@@ -317,4 +339,23 @@ static inline void hwspin_unlock(struct hwspinlock *hwlock)
 	__hwspin_unlock(hwlock, 0, NULL);
 }
 
+/**
+ * hwspin_unlock_raw() - unlock hwspinlock
+ * @hwlock: a previously acquired hwspinlock which we want to unlock
+ *
+ * This function will unlock a specific hwspinlock that was acquired using the
+ * hwspin_trylock_raw() call.
+ *
+ * The function can only be used on a hwlock that has been initialized with
+ * raw capability by the platform drv.
+ *
+ * @hwlock must be already locked (e.g. by hwspin_trylock()) before calling
+ * this function: it is a bug to call unlock on a @hwlock that is already
+ * unlocked.
+ */
+static inline void hwspin_unlock_raw(struct hwspinlock *hwlock)
+{
+	__hwspin_unlock(hwlock, HWLOCK_NOLOCK, NULL);
+}
+
 #endif /* __LINUX_HWSPINLOCK_H */
-- 
2.1.4



From lina.iyer at linaro.org  Wed Aug  5 09:32:42 2015
From: lina.iyer at linaro.org (Lina Iyer)
Date: Wed,  5 Aug 2015 10:32:42 -0600
Subject: [PATCH RFC 06/10] drivers: qcom: Enable genpd on selecting QCOM_PM
In-Reply-To: <1438792366-2737-1-git-send-email-lina.iyer@linaro.org>
References: <438731339-58317-1-git-send-email-lina.iyer@linaro.org>
 <1438792366-2737-1-git-send-email-lina.iyer@linaro.org>
Message-ID: <1438792366-2737-7-git-send-email-lina.iyer@linaro.org>

Enable PM_CPU_DOMAIN and its PM_GENERIC_DOMAINS dependenciesd to provide
cpu domain support for QCOM SoCs.

Signed-off-by: Lina Iyer <lina.iyer at linaro.org>
---
 drivers/soc/qcom/Kconfig | 4 ++++
 1 file changed, 4 insertions(+)

diff --git a/drivers/soc/qcom/Kconfig b/drivers/soc/qcom/Kconfig
index ba47b70..b6c2e5d 100644
--- a/drivers/soc/qcom/Kconfig
+++ b/drivers/soc/qcom/Kconfig
@@ -14,6 +14,10 @@ config QCOM_PM
 	bool "Qualcomm Power Management"
 	depends on ARCH_QCOM && !ARM64
 	select QCOM_SCM
+	select ARM_CPU_SUSPEND
+	select PM_GENERIC_DOMAINS
+	select PM_GENERIC_DOMAINS_SLEEP
+	select PM_GENERIC_DOMAINS_OF
 	help
 	  QCOM Platform specific power driver to manage cores and L2 low power
 	  modes. It interface with various system drivers to put the cores in
-- 
2.1.4



From lina.iyer at linaro.org  Wed Aug  5 09:32:41 2015
From: lina.iyer at linaro.org (Lina Iyer)
Date: Wed,  5 Aug 2015 10:32:41 -0600
Subject: [PATCH RFC 05/10] arm: dts: Add power domain device bindings for
 APQ8084
In-Reply-To: <1438792366-2737-1-git-send-email-lina.iyer@linaro.org>
References: <438731339-58317-1-git-send-email-lina.iyer@linaro.org>
 <1438792366-2737-1-git-send-email-lina.iyer@linaro.org>
Message-ID: <1438792366-2737-6-git-send-email-lina.iyer@linaro.org>

Define L2 SAW as the power domain provider and individual cpus are the
power domain consumers.

Signed-off-by: Lina Iyer <lina.iyer at linaro.org>
---
 arch/arm/boot/dts/qcom-apq8084.dtsi | 8 +++++++-
 1 file changed, 7 insertions(+), 1 deletion(-)

diff --git a/arch/arm/boot/dts/qcom-apq8084.dtsi b/arch/arm/boot/dts/qcom-apq8084.dtsi
index 900ef1f..4a61f8d 100644
--- a/arch/arm/boot/dts/qcom-apq8084.dtsi
+++ b/arch/arm/boot/dts/qcom-apq8084.dtsi
@@ -23,6 +23,7 @@
 			qcom,acc = <&acc0>;
 			qcom,saw = <&saw0>;
 			cpu-idle-states = <&CPU_SPC>;
+			power-domains = <&saw_l2>;
 		};
 
 		cpu at 1 {
@@ -34,6 +35,7 @@
 			qcom,acc = <&acc1>;
 			qcom,saw = <&saw1>;
 			cpu-idle-states = <&CPU_SPC>;
+			power-domains = <&saw_l2>;
 		};
 
 		cpu at 2 {
@@ -45,6 +47,7 @@
 			qcom,acc = <&acc2>;
 			qcom,saw = <&saw2>;
 			cpu-idle-states = <&CPU_SPC>;
+			power-domains = <&saw_l2>;
 		};
 
 		cpu at 3 {
@@ -56,6 +59,7 @@
 			qcom,acc = <&acc3>;
 			qcom,saw = <&saw3>;
 			cpu-idle-states = <&CPU_SPC>;
+			power-domains = <&saw_l2>;
 		};
 
 		L2: l2-cache {
@@ -183,9 +187,11 @@
 		};
 
 		saw_l2: power-controller at f9012000 {
-			compatible = "qcom,apq8084-saw2-v2.1-l2", "qcom,saw2";
+			compatible = "qcom,apq8084-saw2-v2.1-l2", "qcom,saw2",
+					 "arm,pd";
 			reg = <0xf9012000 0x1000>;
 			regulator;
+			#power-domain-cells = <0>;
 		};
 
 		acc0: clock-controller at f9088000 {
-- 
2.1.4



From lina.iyer at linaro.org  Wed Aug  5 09:32:46 2015
From: lina.iyer at linaro.org (Lina Iyer)
Date: Wed,  5 Aug 2015 10:32:46 -0600
Subject: [PATCH RFC 10/10] arm: dts: qcom: Add TCSR mutex device bindings for
 APQ8084
In-Reply-To: <1438792366-2737-1-git-send-email-lina.iyer@linaro.org>
References: <438731339-58317-1-git-send-email-lina.iyer@linaro.org>
 <1438792366-2737-1-git-send-email-lina.iyer@linaro.org>
Message-ID: <1438792366-2737-11-git-send-email-lina.iyer@linaro.org>

Add device binding for hwspinlock support on QCOM 8084 SoCs.

Signed-off-by: Lina Iyer <lina.iyer at linaro.org>
---
 arch/arm/boot/dts/qcom-apq8084.dtsi | 11 +++++++++++
 1 file changed, 11 insertions(+)

diff --git a/arch/arm/boot/dts/qcom-apq8084.dtsi b/arch/arm/boot/dts/qcom-apq8084.dtsi
index 4a61f8d..2a08741 100644
--- a/arch/arm/boot/dts/qcom-apq8084.dtsi
+++ b/arch/arm/boot/dts/qcom-apq8084.dtsi
@@ -286,5 +286,16 @@
 			interrupt-controller;
 			#interrupt-cells = <4>;
 		};
+
+		tcsr_mutex_regs: syscon at fd484000{
+			compatible = "syscon";
+			reg = <0xfd484000 0x20000>;
+		};
+
+		tcsr_mutex: hwlock {
+			compatible = "qcom,tcsr-mutex";
+			syscon = <&tcsr_mutex_regs 0 0x80>;
+			#hwlock-cells = <1>;
+		};
 	};
 };
-- 
2.1.4



From lina.iyer at linaro.org  Wed Aug  5 09:32:45 2015
From: lina.iyer at linaro.org (Lina Iyer)
Date: Wed,  5 Aug 2015 10:32:45 -0600
Subject: [PATCH RFC 09/10] drivers: qcom: spm: Use hwspinlock to serialize
 entry into SCM
In-Reply-To: <1438792366-2737-1-git-send-email-lina.iyer@linaro.org>
References: <438731339-58317-1-git-send-email-lina.iyer@linaro.org>
 <1438792366-2737-1-git-send-email-lina.iyer@linaro.org>
Message-ID: <1438792366-2737-10-git-send-email-lina.iyer@linaro.org>

When the last CPU enters idle, the state of L2 is determined and the
power controller for the L2 is programmed to power down. The power
controllers' state machine is only triggered when all the CPUs have
executed their WFI instruction. Multiple CPUs may enter SCM to power
down at the same time. Linux identifies the last man down and determines
the state of the cluster, but an FIQ could have kept another CPU busy.
The last CPU to enter SCM may not be the last CPU as determined by
Linux. So the state of the cluster would not be correctly relayed to the
SCM. To ensure that the last CPU in Linux is the same in SCM, serialize
the entry into SCM. Linux is responsible for flushing non-secure L2,
while SCM flushes only the secure lines of L2. Invalidation for secure
and non-secure L2 is done by the SCM when the first CPU resumes from
idle.

An example of the last man race -

Say there are two cores powering down - CoreA and CoreB

CoreA enters idle is not the last core and about to call into SCM
CoreB enters idle and is the last core, determines L2 should be flushed
CoreB receives an FIQ and gets busy handling the FIQ
CoreA has an pending IRQ, bails out of SCM and cpuidle
CoreB is still busy
CoreA enters cpuidle again and now is the last core
CoreA determines L2 should *not* be flushed and calls SCM
CoreB finishes FIQ, enters SCM with a stale L2 state (L2 to be flushed)
SCM records L2 as flushed and invalidates L2 when a core comes up.

To avoid this race, serialize all entry from Linux to SCM for cpuidle. A
hwspinlock is locked by Linux and released by the SCM when the context
switches to Secure. This way, the last man view of both Linux and SCM,
match with that of the L2 power controller configuration. A raw
hwspinlock would not use s/w spinlocks around the hwspinlock.
Since there is no possiblity of preemption in cpuidle, it is safe to
use the raw variant of the hwspinlock.

Signed-off-by: Lina Iyer <lina.iyer at linaro.org>
---
 drivers/soc/qcom/Kconfig |  1 +
 drivers/soc/qcom/spm.c   | 26 ++++++++++++++++++++++++++
 2 files changed, 27 insertions(+)

diff --git a/drivers/soc/qcom/Kconfig b/drivers/soc/qcom/Kconfig
index b6c2e5d..cb50efb 100644
--- a/drivers/soc/qcom/Kconfig
+++ b/drivers/soc/qcom/Kconfig
@@ -18,6 +18,7 @@ config QCOM_PM
 	select PM_GENERIC_DOMAINS
 	select PM_GENERIC_DOMAINS_SLEEP
 	select PM_GENERIC_DOMAINS_OF
+	select HWSPINLOCK_QCOM
 	help
 	  QCOM Platform specific power driver to manage cores and L2 low power
 	  modes. It interface with various system drivers to put the cores in
diff --git a/drivers/soc/qcom/spm.c b/drivers/soc/qcom/spm.c
index b6d75db..bd09514 100644
--- a/drivers/soc/qcom/spm.c
+++ b/drivers/soc/qcom/spm.c
@@ -26,6 +26,8 @@
 #include <linux/cpu_pm.h>
 #include <linux/pm_domain.h>
 #include <linux/qcom_scm.h>
+#include <linux/pm_domain.h>
+#include <linux/hwspinlock.h>
 
 #include <asm/arm-pd.h>
 #include <asm/cacheflush.h>
@@ -38,6 +40,7 @@
 #define SPM_CTL_INDEX		0x7f
 #define SPM_CTL_INDEX_SHIFT	4
 #define SPM_CTL_EN		BIT(0)
+#define QCOM_PC_HWLOCK		7
 
 enum pm_sleep_mode {
 	PM_SLEEP_MODE_STBY,
@@ -139,6 +142,7 @@ static int l2_flush_flag;
 
 typedef int (*idle_fn)(int);
 static DEFINE_PER_CPU(idle_fn*, qcom_idle_ops);
+static struct hwspinlock *remote_lock;
 
 static inline void spm_register_write(struct spm_driver_data *drv,
 					enum spm_reg reg, u32 val)
@@ -198,6 +202,24 @@ static int qcom_pm_collapse(unsigned long int unused)
 	if (l2_flush_flag == QCOM_SCM_CPU_PWR_DOWN_L2_OFF)
 		flush_cache_all();
 
+	/*
+	 * Wait and acquire the hwspin lock to synchronize
+	 * the entry into SCM. The view of the last core in Linux
+	 * should be same for SCM so the l2_flush_flag is correct.
+	 *
+	 * * IMPORTANT *
+	 * 1. SCM unlocks this lock.
+	 * 2. We do not want to call api that would spinlock before
+	 *    acquiring the hwspin lock. It will not be unlocked.
+	 *    So call raw variant
+	 * 3. Every core needs to acquire this lock and the entry into
+	 *    SCM would be serialized after this point.
+	 */
+	if (remote_lock) {
+		while (hwspin_trylock_raw(remote_lock))
+			;
+	}
+
 	qcom_scm_cpu_power_down(l2_flush_flag);
 
 	/*
@@ -439,6 +461,10 @@ static int spm_dev_probe(struct platform_device *pdev)
 	else
 		per_cpu(cpu_spm_drv, index) = drv;
 
+	/* Initialize hwspinlock, to serialize entry into secure */
+	if (!remote_lock && of_match_node(cache_spm_table, pdev->dev.of_node))
+		remote_lock = hwspin_lock_request_specific(QCOM_PC_HWLOCK);
+
 	dev_dbg(&pdev->dev, "SPM device probed.\n");
 	return 0;
 }
-- 
2.1.4



From lina.iyer at linaro.org  Wed Aug  5 09:38:00 2015
From: lina.iyer at linaro.org (Lina Iyer)
Date: Wed, 5 Aug 2015 10:38:00 -0600
Subject: [PATCH 6/9] ARM: domain: Add platform handlers for CPU PM domains
In-Reply-To: <CAL_JsqKWekSGiFbZz6++3ibAzY_8Y6+0nOBQinFVw4cBk6JvEw@mail.gmail.com>
References: <1438731339-58317-1-git-send-email-lina.iyer@linaro.org>
 <1438731339-58317-7-git-send-email-lina.iyer@linaro.org>
 <CAL_JsqKWekSGiFbZz6++3ibAzY_8Y6+0nOBQinFVw4cBk6JvEw@mail.gmail.com>
Message-ID: <20150805163759.GA52339@linaro.org>

On Wed, Aug 05 2015 at 08:45 -0600, Rob Herring wrote:
>On Tue, Aug 4, 2015 at 6:35 PM, Lina Iyer <lina.iyer at linaro.org> wrote:
>> In addition to the common power up/down actions of CPU PM domain core,
>> platforms may have additional configuration before the CPU domain can be
>> powered off or considered active. Allow platform drivers to register
>> handlers for CPU PM domains.
>>
>> Platform drivers may register their callbacks against a compatible
>> string defined by their PM domain provider device node in the DT. At
>> domain init, the platform driver can initialize the platform specific
>> genpd attributes. The init callback would need to return successfully,
>> for the platform power_on/off handlers to be registered with the CPU PM
>> domain.
>>
>> The code uses __init section to reduce memory needed for platform
>> handlers and therefore can be freed after the driver is initialized, a
>> desirable outcome for single kernel image.
>
>[...]
>
>> diff --git a/arch/arm/include/asm/arm-pd.h b/arch/arm/include/asm/arm-pd.h
>> new file mode 100644
>> index 0000000..fc44abf
>> --- /dev/null
>> +++ b/arch/arm/include/asm/arm-pd.h
>> @@ -0,0 +1,30 @@
>> +/*
>> + * linux/arch/arm/include/asm/arm-pd.h
>> + *
>> + * Copyright (C) 2015 Linaro Ltd.
>> + *
>> + * 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.
>> + */
>> +
>> +#ifndef __ARM_PD_H__
>> +#define __ARM_PD_H__
>> +
>> +struct of_arm_pd_ops {
>> +       int (*init)(struct device_node *dn, struct generic_pm_domain *d);
>> +       int (*power_on)(struct generic_pm_domain *d);
>> +       int (*power_off)(struct generic_pm_domain *d);
>> +};
>> +
>> +struct of_arm_pd_method {
>> +       const char *handle;
>> +       struct of_arm_pd_ops *ops;
>> +};
>> +
>> +#define ARM_PD_METHOD_OF_DECLARE(_name, _handle, _ops) \
>> +       static const struct of_arm_pd_method __arm_pd_method_of_table_##_name \
>> +       __used __section(__arm_pd_method_of_table)              \
>> +       = { .handle = _handle, .ops = _ops }
>
>AFAICT, you are not using this in this series. You should add it when
>you have a user.
>
Sorry, I had a last minute change of heart about some commit text and 
could not get to send the complete series yesterday. I tried to send the
rest of the patches, the one that uses this macro, as in-reply-to but
that did not work for some reason.

Anyways, you are Cc'd in the driver series.

>Ideally, we keep some amount of uniformity across various *_OF_DECLARE
>which is why we have OF_DECLARE_1 and OF_DECLARE_2. This makes all the
>sections just arrays of struct of_device_id. Not all users follow
>this, but most do. So instead of putting the ops in here, platforms
>can provide a function callback which can then set the ops. Then you
>also don't need the .init() ops function as the callback function can
>do any initialization too.
>
Okay, will look into that.

>Rob
Thanks for your time Rob.

-- Lina


From agross at codeaurora.org  Wed Aug  5 09:38:37 2015
From: agross at codeaurora.org (Andy Gross)
Date: Wed, 5 Aug 2015 11:38:37 -0500
Subject: [PATCH RFC 06/10] drivers: qcom: Enable genpd on selecting QCOM_PM
In-Reply-To: <1438792366-2737-7-git-send-email-lina.iyer@linaro.org>
References: <438731339-58317-1-git-send-email-lina.iyer@linaro.org>
 <1438792366-2737-1-git-send-email-lina.iyer@linaro.org>
 <1438792366-2737-7-git-send-email-lina.iyer@linaro.org>
Message-ID: <20150805163837.GB14198@qualcomm.com>

On Wed, Aug 05, 2015 at 10:32:42AM -0600, Lina Iyer wrote:
> Enable PM_CPU_DOMAIN and its PM_GENERIC_DOMAINS dependenciesd to provide
> cpu domain support for QCOM SoCs.

Fix dependencies <sic>

> 
> Signed-off-by: Lina Iyer <lina.iyer at linaro.org>
> ---
>  drivers/soc/qcom/Kconfig | 4 ++++
>  1 file changed, 4 insertions(+)
> 
> diff --git a/drivers/soc/qcom/Kconfig b/drivers/soc/qcom/Kconfig
> index ba47b70..b6c2e5d 100644
> --- a/drivers/soc/qcom/Kconfig
> +++ b/drivers/soc/qcom/Kconfig
> @@ -14,6 +14,10 @@ config QCOM_PM
>  	bool "Qualcomm Power Management"
>  	depends on ARCH_QCOM && !ARM64
>  	select QCOM_SCM
> +	select ARM_CPU_SUSPEND
> +	select PM_GENERIC_DOMAINS
> +	select PM_GENERIC_DOMAINS_SLEEP
> +	select PM_GENERIC_DOMAINS_OF
>  	help
>  	  QCOM Platform specific power driver to manage cores and L2 low power
>  	  modes. It interface with various system drivers to put the cores in
> -- 
> 2.1.4
> 

-- 
Qualcomm Innovation Center, Inc.
The Qualcomm Innovation Center, Inc. is a member of the Code Aurora Forum,
a Linux Foundation Collaborative Project



From Varun.Sethi at freescale.com  Wed Aug  5 09:39:33 2015
From: Varun.Sethi at freescale.com (Varun Sethi)
Date: Wed, 5 Aug 2015 16:39:33 +0000
Subject: [PATCH 2/3] Docs: dt: Add PCI MSI map bindings
In-Reply-To: <1437670365-20704-3-git-send-email-mark.rutland@arm.com>
References: <1437670365-20704-1-git-send-email-mark.rutland@arm.com>
 <1437670365-20704-3-git-send-email-mark.rutland@arm.com>
Message-ID: <BN1PR0301MB06277FDA6EB34E77B557CA75EA750@BN1PR0301MB0627.namprd03.prod.outlook.com>

Hi Mark
Thanks for the patch. Please find my comment inline.

Regards
Varun

> -----Original Message-----
> From: iommu-bounces at lists.linux-foundation.org [mailto:iommu-
> bounces at lists.linux-foundation.org] On Behalf Of Mark Rutland
> Sent: Thursday, July 23, 2015 10:23 PM
> To: devicetree at vger.kernel.org
> Cc: Mark Rutland; lorenzo.pieralisi at arm.com; arnd at arndb.de;
> marc.zyngier at arm.com; will.deacon at arm.com; linux-
> kernel at vger.kernel.org; ddaney at caviumnetworks.com; iommu at lists.linux-
> foundation.org; tirumalesh.chalamarla at caviumnetworks.com;
> laurent.pinchart at ideasonboard.com; thunder.leizhen at huawei.com;
> treding at nvidia.com; linux-arm-kernel at lists.infradead.org;
> majun258 at huawei.com
> Subject: [PATCH 2/3] Docs: dt: Add PCI MSI map bindings
> 
> Currently msi-parent is used by a few bindings to describe the relationship
> between a PCI root complex and a single MSI controller, but this property
> does not have a generic binding document.
> 
> Additionally, msi-parent is insufficient to describe more complex
> relationships between MSI controllers and devices under a root complex,
> where devices may be able to target multiple MSI controllers, or where MSI
> controllers use (non-probeable) sideband information to distinguish devices.
> 
> This patch adds a generic binding for mapping PCI devices to MSI controllers.
> This document covers msi-parent, and a new msi-map property (specific to
> PCI*) which may be used to map devices (identified by their Requester ID) to
> sideband data for each MSI controller that they may target.
> 
> Signed-off-by: Mark Rutland <mark.rutland at arm.com>
> ---
>  Documentation/devicetree/bindings/pci/pci-msi.txt | 220
> ++++++++++++++++++++++
>  1 file changed, 220 insertions(+)
>  create mode 100644 Documentation/devicetree/bindings/pci/pci-msi.txt
> 
> diff --git a/Documentation/devicetree/bindings/pci/pci-msi.txt
> b/Documentation/devicetree/bindings/pci/pci-msi.txt
> new file mode 100644
> index 0000000..9b3cc81
> --- /dev/null
> +++ b/Documentation/devicetree/bindings/pci/pci-msi.txt
> @@ -0,0 +1,220 @@
> +This document describes the generic device tree binding for describing
> +the relationship between PCI devices and MSI controllers.
> +
> +Each PCI device under a root complex is uniquely identified by its
> +Requester ID (AKA RID). A Requester ID is a triplet of a Bus number,
> +Device number, and Function number.
> +
> +For the purpose of this document, when treated as a numeric value, a
> +RID is formatted such that:
> +
> +* Bits [15:8] are the Bus number.
> +* Bits [7:3] are the Device number.
> +* Bits [2:0] are the Function number.
> +* Any other bits required for padding must be zero.
> +
> +MSIs may be distinguished in part through the use of sideband data
> +accompanying writes. In the case of PCI devices, this sideband data may
> +be derived from the Requester ID. A mechanism is required to associate
> +a device with both the MSI controllers it can address, and the sideband
> +data that will be associated with its writes to those controllers.
> +
> +For generic MSI bindings, see
> +Documentation/devicetree/bindings/interrupt-controller/msi.txt.
> +
> +
> +PCI root complex
> +================
> +
> +Optional properties
> +-------------------
> +
> +- msi-map: Maps a Requester ID to an MSI controller and associated
> +  msi-specifier data. The property is an arbitrary number of tuples of
> +  (rid-base,msi-controller,msi-base,length), where:
[varun] How would we account for hot plug PCI devices and SR-IOV use cases, with the rid base and length?  How do we take in to account for a PCIe bridge, while setting up the requestor ID base and length?

> +
> +  * rid-base is a single cell describing the first RID matched by the entry.
> +
> +  * msi-controller is a single phandle to an MSI controller
> +
> +  * msi-base is an msi-specifier describing the msi-specifier produced for the
> +    first RID matched by the entry.
> +
> +  * length is a single cell describing how many consecutive RIDs are matched
> +    following the rid-base.
> +
> +  Any RID r in the interval [rid-base, rid-base + length) is associated
> + with  the listed msi-controller, with the msi-specifier (r - rid-base + msi-
> base).
> +
> +- msi-map-mask: A mask to be applied to each Requester ID prior to
> +being mapped
> +  to an msi-specifier per the msi-map property.
> +
[varun] Can you please elaborate on a use case, where this would help. 



> +- msi-parent: Describes the MSI parent of the root complex itself.
> +Where
> +  the root complex and MSI controller do not pass sideband data with
> +MSI
> +  writes, this property may be used to describe the MSI controller(s)
> +  used by PCI devices under the root complex, if defined as such in the
> +  binding for the root complex.
> +
> +
> +Example (1)
> +===========
> +
> +/ {
> +	#address-cells = <1>;
> +	#size-cells = <1>;
> +
> +	msi: msi-controller at a {
> +		reg = <0xa 0x1>;
> +		compatible = "vendor,some-controller";
> +		msi-controller;
> +		#msi-cells = <1>;
> +	};
> +
> +	pci: pci at f {
> +		reg = <0xf 0x1>;
> +		compatible = "vendor,pcie-root-complex";
> +		device_type = "pci";
> +
> +		/*
> +		 * The sideband data provided to the MSI controller is
> +		 * the RID, identity-mapped.
> +		 */
> +		msi-map = <0x0 &msi_a 0x0 0x10000>,
> +	};
> +};
> +
> +
> +Example (2)
> +===========
> +
> +/ {
> +	#address-cells = <1>;
> +	#size-cells = <1>;
> +
> +	msi: msi-controller at a {
> +		reg = <0xa 0x1>;
> +		compatible = "vendor,some-controller";
> +		msi-controller;
> +		#msi-cells = <1>;
> +	};
> +
> +	pci: pci at f {
> +		reg = <0xf 0x1>;
> +		compatible = "vendor,pcie-root-complex";
> +		device_type = "pci";
> +
> +		/*
> +		 * The sideband data provided to the MSI controller is
> +		 * the RID, masked to only the device and function bits.
> +		 */
> +		msi-map = <0x0 &msi_a 0x0 0x100>,
> +		msi-map-mask = <0xff>
> +	};
> +};
> +
> +
> +Example (3)
> +===========
> +
> +/ {
> +	#address-cells = <1>;
> +	#size-cells = <1>;
> +
> +	msi: msi-controller at a {
> +		reg = <0xa 0x1>;
> +		compatible = "vendor,some-controller";
> +		msi-controller;
> +		#msi-cells = <1>;
> +	};
> +
> +	pci: pci at f {
> +		reg = <0xf 0x1>;
> +		compatible = "vendor,pcie-root-complex";
> +		device_type = "pci";
> +
> +		/*
> +		 * The sideband data provided to the MSI controller is
> +		 * the RID, but the high bit of the bus number is
> +		 * ignored.
> +		 */
> +		msi-map = <0x0000 &msi 0x0000 0x8000>,
> +			  <0x8000 &msi 0x0000 0x8000>;
> +	};
> +};
> +
> +
> +Example (4)
> +===========
> +
> +/ {
> +	#address-cells = <1>;
> +	#size-cells = <1>;
> +
> +	msi: msi-controller at a {
> +		reg = <0xa 0x1>;
> +		compatible = "vendor,some-controller";
> +		msi-controller;
> +		#msi-cells = <1>;
> +	};
> +
> +	pci: pci at f {
> +		reg = <0xf 0x1>;
> +		compatible = "vendor,pcie-root-complex";
> +		device_type = "pci";
> +
> +		/*
> +		 * The sideband data provided to the MSI controller is
> +		 * the RID, but the high bit of the bus number is
> +		 * negated.
> +		 */
> +		msi-map = <0x0000 &msi 0x8000 0x8000>,
> +			  <0x8000 &msi 0x0000 0x8000>;
> +	};
> +};
> +
> +
> +Example (5)
> +===========
> +
> +/ {
> +	#address-cells = <1>;
> +	#size-cells = <1>;
> +
> +	msi_a: msi-controller at a {
> +		reg = <0xa 0x1>;
> +		compatible = "vendor,some-controller";
> +		msi-controller;
> +		#msi-cells = <1>;
> +	};
> +
> +	msi_b: msi-controller at b {
> +		reg = <0xb 0x1>;
> +		compatible = "vendor,some-controller";
> +		msi-controller;
> +		#msi-cells = <1>;
> +	};
> +
> +	msi_c: msi-controller at c {
> +		reg = <0xc 0x1>;
> +		compatible = "vendor,some-controller";
> +		msi-controller;
> +		#msi-cells = <1>;
> +	};
> +
> +	pci: pci at c {
> +		reg = <0xf 0x1>;
> +		compatible = "vendor,pcie-root-complex";
> +		device_type = "pci";
> +
> +		/*
> +		 * The sideband data provided to MSI controller a is the
> +		 * RID, but the high bit of the bus number is negated.
> +		 * The sideband data provided to MSI controller b is the
> +		 * RID, identity-mapped.
> +		 * MSI controller c is not addressable.
> +		 */
> +		msi-map = <0x0000 &msi_a 0x8000 0x08000>,
> +			  <0x8000 &msi_a 0x0000 0x08000>,
> +			  <0x0000 &msi_b 0x0000 0x10000>;
> +	};
> +};
> --
> 1.9.1
> 
> _______________________________________________
> iommu mailing list
> iommu at lists.linux-foundation.org
> https://lists.linuxfoundation.org/mailman/listinfo/iommu


From matthias.bgg at gmail.com  Wed Aug  5 09:47:03 2015
From: matthias.bgg at gmail.com (Matthias Brugger)
Date: Wed, 05 Aug 2015 18:47:03 +0200
Subject: [PATCH v3 5/8] ARM: mediatek: add smp bringup code for MT6580
In-Reply-To: <1438696464-59858-6-git-send-email-scott.shu@mediatek.com>
References: <1438696464-59858-1-git-send-email-scott.shu@mediatek.com>
 <1438696464-59858-6-git-send-email-scott.shu@mediatek.com>
Message-ID: <1801910.hz53dYUgta@ubix>

On Tuesday, August 04, 2015 09:54:21 PM Scott Shu wrote:
> Add support for cpu enable-method "mediatek,mt6580-smp" for booting
> secondary CPUs on MT6580.
> 
> Signed-off-by: Scott Shu <scott.shu at mediatek.com>
> ---
>  arch/arm/mach-mediatek/platsmp.c |  137
> ++++++++++++++++++++++++++++++++++++++ 1 file changed, 137 insertions(+)
> 
> diff --git a/arch/arm/mach-mediatek/platsmp.c
> b/arch/arm/mach-mediatek/platsmp.c index a5bc108..94f7865 100644
> --- a/arch/arm/mach-mediatek/platsmp.c
> +++ b/arch/arm/mach-mediatek/platsmp.c
> @@ -21,10 +21,16 @@
>  #include <linux/of_address.h>
>  #include <linux/string.h>
>  #include <linux/threads.h>
> +#include <linux/delay.h>
> +#include <asm/cacheflush.h>
> +
> +#include <linux/soc/mediatek/scpsys.h>
> 
>  #define MTK_MAX_CPU		8
>  #define MTK_SMP_REG_SIZE	0x1000
> 
> +static DEFINE_SPINLOCK(boot_lock);
> +
>  struct mtk_smp_boot_info {
>  	unsigned long smp_base;
>  	unsigned int jump_reg;
> @@ -56,6 +62,126 @@ static const struct of_device_id mtk_smp_boot_infos[]
> __initconst = { static void __iomem *mtk_smp_base;
>  static const struct mtk_smp_boot_info *mtk_smp_info;
> 
> +#ifdef CONFIG_HOTPLUG_CPU
> +static int mt6580_cpu_kill(unsigned cpu)
> +{
> +	int ret;
> +
> +	ret = spm_cpu_mtcmos_off(cpu, 1);

is this function ever called with wfi == 0?

> +	if (ret < 0)
> +		return 0;
> +
> +	return 1;
> +}
> +
> +static void mt6580_cpu_die(unsigned int cpu)
> +{
> +	for (;;)
> +		cpu_do_idle();
> +}
> +#endif
> +
> +static void write_pen_release(int val)
> +{
> +	pen_release = val;
> +	/* Make sure this is visible to other CPUs */
> +	smp_wmb();
> +	sync_cache_w(&pen_release);
> +}
> +
> +/*
> + * Refer common "pen" secondary release method
> + */
> +static int mt6580_boot_secondary(unsigned int cpu, struct task_struct
> *idle) +{
> +	unsigned long timeout;
> +	int ret;
> +
> +	/*
> +	 * Set synchronisation state between this boot processor
> +	 * and the secondary one
> +	 */
> +	spin_lock(&boot_lock);
> +
> +	/*
> +	 * The secondary processor is waiting to be released from
> +	 * the holding pen - release it, then wait for it to flag
> +	 * that it has been released by resetting pen_release.
> +	 *
> +	 * Note that "pen_release" is the hardware CPU ID, whereas
> +	 * "cpu" is Linux's internal ID.
> +	 */
> +	write_pen_release(cpu);
> +
> +	/*
> +	 * CPU power on control by SPM
> +	 */
> +	ret = spm_cpu_mtcmos_on(cpu);
> +	if (ret < 0) {
> +		spin_unlock(&boot_lock);
> +		return -ENXIO;
> +	}
> +
> +	timeout = jiffies + (1 * HZ);
> +	while (time_before(jiffies, timeout)) {
> +		/* Read barrier */
> +		smp_rmb();
> +
> +		if (pen_release == -1)
> +			break;
> +
> +		udelay(10);
> +	}
> +
> +	/*
> +	 * Now the secondary core is starting up let it run its
> +	 * calibrations, then wait for it to finish
> +	 */
> +	spin_unlock(&boot_lock);
> +
> +	return (pen_release != -1 ? -ENXIO : 0);
> +}
> +
> +static void mt6580_secondary_init(unsigned int cpu)
> +{
> +	/*
> +	 * Let the primary processor know we're out of the
> +	 * pen, then head off into the C entry point
> +	 */
> +	write_pen_release(-1);
> +
> +	/*
> +	 * Synchronise with the boot thread.
> +	 */
> +	spin_lock(&boot_lock);
> +	spin_unlock(&boot_lock);
> +}
> +
> +#define MT6580_INFRACFG_AO	0x10001000
> +#define SW_ROM_PD		BIT(31)

Please put the defines on the beginning of the file.
SW_ROM_PD bit is the same on other SoCs? I wasn't able to reveal that from the 
data sheets. If this is MT6580 only, the define should be renamed.

> +
> +static void __init mt6580_smp_prepare_cpus(unsigned int max_cpus)
> +{
> +	static void __iomem *infracfg_ao_base;
> +
> +	infracfg_ao_base = ioremap(MT6580_INFRACFG_AO, 0x1000);
> +	if (!infracfg_ao_base) {
> +		pr_err("%s: Unable to map I/O memory\n", __func__);
> +		return;
> +	}
> +
> +	/* Enable bootrom power down mode */
> +	writel_relaxed(readl(infracfg_ao_base + 0x804) | SW_ROM_PD,
> +		       infracfg_ao_base + 0x804);

Please use a define for the offset.
I prefer to not cascade reads and writes but to use a temporary variable. But 
if this is fine with the kernel coding style (I doubt, but I'm not sure) then 
this is fine.

> +
> +	/* Write the address of slave startup into boot address
> +	   register for bootrom power down mode */
> +	writel_relaxed(virt_to_phys(secondary_startup_arm),
> +		       infracfg_ao_base + 0x800);
> +
> +	iounmap(infracfg_ao_base);
> +}
> +
>  static int mtk_boot_secondary(unsigned int cpu, struct task_struct *idle)
>  {
>  	if (!mtk_smp_base)
> @@ -142,3 +268,14 @@ static struct smp_operations mt6589_smp_ops __initdata
> = { .smp_boot_secondary = mtk_boot_secondary,
>  };
>  CPU_METHOD_OF_DECLARE(mt6589_smp, "mediatek,mt6589-smp", &mt6589_smp_ops);
> +
> +static struct smp_operations mt6580_smp_ops __initdata = {
> +	.smp_prepare_cpus = mt6580_smp_prepare_cpus,
> +	.smp_secondary_init = mt6580_secondary_init,
> +	.smp_boot_secondary = mt6580_boot_secondary,
> +#ifdef CONFIG_HOTPLUG_CPU
> +	.cpu_kill = mt6580_cpu_kill,
> +	.cpu_die = mt6580_cpu_die,
> +#endif
> +};
> +CPU_METHOD_OF_DECLARE(mt6580_smp, "mediatek,mt6580-smp", &mt6580_smp_ops);



From xerofoify at gmail.com  Wed Aug  5 09:48:23 2015
From: xerofoify at gmail.com (Nicholas Krause)
Date: Wed,  5 Aug 2015 12:48:23 -0400
Subject: [PATCH] kvm:arm:Fix error handling in the function vgic_v3_probe
Message-ID: <1438793303-30228-1-git-send-email-xerofoify@gmail.com>

This fixes the error handling in the function vgic_v3_probe
for when calling the function kvm_register_device_ops to check
if the call to this function has returned a error code and if
so jump to the label out with goto to cleanup no longer required
resources used by the function vgic_v3_probe before returning the
error code from the call to kvm_register_device_ops to the caller
of the function vgic_v3_probe.

Signed-off-by: Nicholas Krause <xerofoify at gmail.com>
---
 virt/kvm/arm/vgic-v3.c | 10 +++++++---
 1 file changed, 7 insertions(+), 3 deletions(-)

diff --git a/virt/kvm/arm/vgic-v3.c b/virt/kvm/arm/vgic-v3.c
index dff0602..5102aa2 100644
--- a/virt/kvm/arm/vgic-v3.c
+++ b/virt/kvm/arm/vgic-v3.c
@@ -264,12 +264,16 @@ int vgic_v3_probe(struct device_node *vgic_node,
 	} else {
 		vgic->vcpu_base = vcpu_res.start;
 		vgic->can_emulate_gicv2 = true;
-		kvm_register_device_ops(&kvm_arm_vgic_v2_ops,
-					KVM_DEV_TYPE_ARM_VGIC_V2);
+		ret = kvm_register_device_ops(&kvm_arm_vgic_v2_ops,
+					      KVM_DEV_TYPE_ARM_VGIC_V2);
+		if (ret)
+			goto out;
 	}
 	if (vgic->vcpu_base == 0)
 		kvm_info("disabling GICv2 emulation\n");
-	kvm_register_device_ops(&kvm_arm_vgic_v3_ops, KVM_DEV_TYPE_ARM_VGIC_V3);
+	ret = kvm_register_device_ops(&kvm_arm_vgic_v3_ops, KVM_DEV_TYPE_ARM_VGIC_V3);
+	if (ret)
+		goto out;
 
 	vgic->vctrl_base = NULL;
 	vgic->type = VGIC_V3;
-- 
2.1.4



From mark.rutland at arm.com  Wed Aug  5 09:51:20 2015
From: mark.rutland at arm.com (Mark Rutland)
Date: Wed, 5 Aug 2015 17:51:20 +0100
Subject: [PATCH 1/3] Docs: dt: add generic MSI bindings
In-Reply-To: <1437670365-20704-2-git-send-email-mark.rutland@arm.com>
References: <1437670365-20704-1-git-send-email-mark.rutland@arm.com>
 <1437670365-20704-2-git-send-email-mark.rutland@arm.com>
Message-ID: <20150805165120.GB28849@leverpostej>

Rob,

Do you have any objections to this, or are you happy to take this patch?

There's a user of this binding (the GICv3 ITS) queued for v4.3 already in
the tip tree, so either we either need to be ok with this binding or we
need to rework that before v4.3.

Marc, can I take it from your use of the binding that you are happy to
provide your ack?

Thanks,
Mark.

On Thu, Jul 23, 2015 at 05:52:43PM +0100, Mark Rutland wrote:
> Currently msi-parent is used in a couple of drivers despite being fairly
> underspecified. This patch adds a generic binding for MSIs (including
> the existing msi-parent property) enabling the description of platform
> devices capable of using MSIs.
> 
> While MSIs are primarily distinguished by doorbell and payload, some MSI
> controllers (e.g. the GICv3 ITS) also use side-band information
> accompanying the write to identify the master which originated the MSI,
> to allow for sandboxing. This sideband information is non-probeable and
> needs to be described in the DT. Other MSI controllers may have
> additional configuration details which need to be described per-master.
> 
> This patch adds a generic msi-parent binding document, extending the
> de-facto standard with a new (optional) #msi-cells which can be used to
> express any per-master configuration and/or sideband data. This is
> sufficient to describe non-hotpluggable devices.
> 
> For busses where sideband data may be derived from some bus-specific
> master ID scheme, other properties will be required to describe the
> mapping.
> 
> Signed-off-by: Mark Rutland <mark.rutland at arm.com>
> ---
>  .../bindings/interrupt-controller/msi.txt          | 135 +++++++++++++++++++++
>  1 file changed, 135 insertions(+)
>  create mode 100644 Documentation/devicetree/bindings/interrupt-controller/msi.txt
> 
> diff --git a/Documentation/devicetree/bindings/interrupt-controller/msi.txt b/Documentation/devicetree/bindings/interrupt-controller/msi.txt
> new file mode 100644
> index 0000000..c60c034
> --- /dev/null
> +++ b/Documentation/devicetree/bindings/interrupt-controller/msi.txt
> @@ -0,0 +1,135 @@
> +This document describes the generic device tree binding for MSI controllers and
> +their master(s).
> +
> +Message Signaled Interrupts (MSIs) are a class of interrupts generated by a
> +write to an MMIO address.
> +
> +MSIs were originally specified by PCI (and are used with PCIe), but may also be
> +used with other busses, and hence a mechanism is required to relate devices on
> +those busses to the MSI controllers which they are capable of using,
> +potentially including additional information.
> +
> +MSIs are distinguished by some combination of:
> +
> +- The doorbell (the MMIO address written to).
> +  
> +  Devices may be configured by software to write to arbitrary doorbells which
> +  they can address. An MSI controller may feature a number of doorbells.
> +
> +- The payload (the value written to the doorbell).
> +  
> +  Devices may be configured to write an arbitrary payload chosen by software.
> +  MSI controllers may have restrictions on permitted payloads.
> +
> +- Sideband information accompanying the write.
> +  
> +  Typically this is neither configurable nor probeable, and depends on the path
> +  taken through the memory system (i.e. it is a property of the combination of
> +  MSI controller and device rather than a property of either in isolation).
> +
> +
> +MSI controllers:
> +================
> +
> +An MSI controller signals interrupts to a CPU when a write is made to an MMIO
> +address by some master. An MSI controller may feature a number of doorbells.
> +
> +Required properties:
> +--------------------
> +
> +- msi-controller: Identifies the node as an MSI controller.
> +
> +Optional properties:
> +--------------------
> +
> +- #msi-cells: The number of cells in an msi-specifier, required if not zero.
> +
> +  Typically this will encode information related to sideband data, and will
> +  not encode doorbells or payloads as these can be configured dynamically.
> +
> +  The meaning of the msi-specifier is defined by the device tree binding of
> +  the specific MSI controller. 
> +
> +
> +MSI clients
> +===========
> +
> +MSI clients are devices which generate MSIs. For each MSI they wish to
> +generate, the doorbell and payload may be configured, though sideband
> +information may not be configurable.
> +
> +Required properties:
> +--------------------
> +
> +- msi-parent: A list of phandle + msi-specifier pairs, one for each MSI
> +  controller which the device is capable of using.
> +
> +  This property is unordered, and MSIs may be allocated from any combination of
> +  MSI controllers listed in the msi-parent property.
> +
> +  If a device has restrictions on the allocation of MSIs, these restrictions
> +  must be described with additional properties.
> +
> +  When #msi-cells is non-zero, busses with an msi-parent will require
> +  additional properties to describe the relationship between devices on the bus
> +  and the set of MSIs they can potentially generate.
> +
> +
> +Example
> +=======
> +
> +/ {
> +	#address-cells = <1>;
> +	#size-cells = <1>;
> +
> +	msi_a: msi-controller at a {
> +		reg = <0xa 0xf00>;
> +		compatible = "vendor-a,some-controller";
> +		msi-controller;
> +		/* No sideband data, so #msi-cells omitted */
> +	};
> +
> +	msi_b: msi-controller at b {
> +		reg = <0xb 0xf00>;
> +		compatible = "vendor-b,another-controller";
> +		msi-controller;
> +		/* Each device has some unique ID */
> +		#msi-cells = <1>;
> +	};
> +
> +	msi_c: msi-controller at c {
> +		reg = <0xb 0xf00>;
> +		compatible = "vendor-b,another-controller";
> +		msi-controller;
> +		/* Each device has some unique ID */
> +		#msi-cells = <1>;
> +	};
> +
> +	dev at 0 {
> +		reg = <0x0 0xf00>;
> +		compatible = "vendor-c,some-device";
> +
> +		/* Can only generate MSIs to msi_a */
> +		msi-parent = <&msi_a>;
> +	};
> +
> +	dev at 1 {
> +		reg = <0x1 0xf00>;
> +		compatible = "vendor-c,some-device";
> +
> +		/* 
> +		 * Can generate MSIs to either A or B.
> +		 */
> +		msi-parent = <&msi_a>, <&msi_b 0x17>;
> +	};
> +
> +	dev at 2 {
> +		reg = <0x2 0xf00>;
> +		compatible = "vendor-c,some-device";
> +		/*
> +		 * Has different IDs at each MSI controller.
> +		 * Can generate MSIs to all of the MSI controllers.
> +		 */
> +		msi-parent = <&msi_a>, <&msi_b 0x17>, <&msi_c 0x53>;
> +	};
> +};
> -- 
> 1.9.1
> 


From dmitry.torokhov at gmail.com  Wed Aug  5 09:52:25 2015
From: dmitry.torokhov at gmail.com (Dmitry Torokhov)
Date: Wed, 5 Aug 2015 09:52:25 -0700
Subject: [PATCH v2 4/8] xen: Use the correctly the Xen memory terminologies
In-Reply-To: <alpine.DEB.2.02.1508051108100.11337@kaball.uk.xensource.com>
References: <1438711972-18752-1-git-send-email-julien.grall@citrix.com>
 <1438711972-18752-5-git-send-email-julien.grall@citrix.com>
 <alpine.DEB.2.02.1508051108100.11337@kaball.uk.xensource.com>
Message-ID: <20150805165225.GC3603@dtor-ws>

On Wed, Aug 05, 2015 at 11:08:55AM +0100, Stefano Stabellini wrote:
> On Tue, 4 Aug 2015, Julien Grall wrote:
> > Based on include/xen/mm.h [1], Linux is mistakenly using MFN when GFN
> > is meant, I suspect this is because the first support for Xen was for
> > PV. This resulted in some misimplementation of helpers on ARM and
> > confused developers about the expected behavior.
> > 
> > For instance, with pfn_to_mfn, we expect to get an MFN based on the name.
> > Although, if we look at the implementation on x86, it's returning a GFN.
> > 
> > For clarity and avoid new confusion, replace any reference to mfn with
> > gfn in any helpers used by PV drivers. The x86 code will still keep some
> > reference of pfn_to_mfn but exclusively for PV (a BUG_ON has been added
> > to ensure this). No changes as been made in the hypercall field, even
> > though they may be invalid, in order to keep the same as the defintion
> > in xen repo.
> > 
> > Take also the opportunity to simplify simple construction such
> > as pfn_to_mfn(page_to_pfn(page)) into page_to_gfn. More complex clean up
> > will come in follow-up patches.
> > 
> > [1] http://xenbits.xen.org/gitweb/?p=xen.git;a=commitdiff;h=e758ed14f390342513405dd766e874934573e6cb
> > 
> > Signed-off-by: Julien Grall <julien.grall at citrix.com>
> > Cc: Stefano Stabellini <stefano.stabellini at eu.citrix.com>
> > Cc: Russell King <linux at arm.linux.org.uk>
> > Cc: Konrad Rzeszutek Wilk <konrad.wilk at oracle.com>
> > Cc: Boris Ostrovsky <boris.ostrovsky at oracle.com>
> > Cc: David Vrabel <david.vrabel at citrix.com>
> > Cc: Thomas Gleixner <tglx at linutronix.de>
> > Cc: Ingo Molnar <mingo at redhat.com>
> > Cc: "H. Peter Anvin" <hpa at zytor.com>
> > Cc: x86 at kernel.org
> > Cc: "Roger Pau Monn?" <roger.pau at citrix.com>
> > Cc: Dmitry Torokhov <dmitry.torokhov at gmail.com>
> > Cc: Ian Campbell <ian.campbell at citrix.com>
> > Cc: Wei Liu <wei.liu2 at citrix.com>
> > Cc: Juergen Gross <jgross at suse.com>
> > Cc: "James E.J. Bottomley" <JBottomley at odin.com>
> > Cc: Greg Kroah-Hartman <gregkh at linuxfoundation.org>
> > Cc: Jiri Slaby <jslaby at suse.com>
> > Cc: Jean-Christophe Plagniol-Villard <plagnioj at jcrosoft.com>
> > Cc: Tomi Valkeinen <tomi.valkeinen at ti.com>
> > Cc: linux-input at vger.kernel.org
> > Cc: netdev at vger.kernel.org
> > Cc: linux-scsi at vger.kernel.org
> > Cc: linuxppc-dev at lists.ozlabs.org
> > Cc: linux-fbdev at vger.kernel.org
> > Cc: linux-arm-kernel at lists.infradead.org
> 
> Aside from the x86 bits:
> 
> Reviewed-by: Stefano Stabellini <stefano.stabellini at eu.citrix.com>

Not really important, but just in case anyone waits for my ack on input
bits:

Acked-by: Dmitry Torokhov <dmitry.torokhov at gmail.com>

Thanks.

-- 
Dmitry


From gregory.clement at free-electrons.com  Wed Aug  5 09:54:00 2015
From: gregory.clement at free-electrons.com (Gregory CLEMENT)
Date: Wed, 05 Aug 2015 18:54:00 +0200
Subject: [PATCH v2] ARM: dts: Convert Linkstation Mini to Device Tree
In-Reply-To: <1438027893.15635.41.camel@dolka.fr>
References: <1436885641.7145.9.camel@dolka.fr>	
 <20150718185238.GH17961@lunn.ch> <55B396A1.1090509@free-electrons.com>
 <1438027893.15635.41.camel@dolka.fr>
Message-ID: <55C23FA8.9030504@free-electrons.com>

Hi Benjamin,

On 27/07/2015 22:11, Benjamin Cama wrote:
> Hi Gr?gory,
> 
> Le samedi 25 juillet 2015 ? 16:01 +0200, Gregory CLEMENT a ?crit :
>> On 18/07/2015 20:52, Andrew Lunn wrote:
>>> On Tue, Jul 14, 2015 at 04:54:01PM +0200, Benjamin Cama wrote:
>>>> The name of the file better reflects the manufacturer's device name
>>>> (LS-WSGL) than the original (lsmini), which exists in a kirkwood version
>>>> too.
>>>>
>>>> Signed-off-by: Benjamin Cama <benoar at dolka.fr>
>>>> ---
>>>> Alexey, Thomas,
>>>>
>>>> I need your approval to change the license, as Jason and Andrew
>>>> suggested using dual licensing. Do you agree with it?
>>>>
>>>> The changes since the first version are:
>>>> * the license change;
>>>> * the more precise attribution to Alexey;
>>>> * gpio keys are now named, even if I find them not to be the good ones;
>>>>   at least they fit with the old numbers and the recently submitted
>>>>   LS-WSXL scheme;
>>>> * added "earlyprintk" to the command-line
>>>>
>>>> I did not rename the leds to be like LS-WSXL, as they are a bit
>>>> different. I also did not take time to look at the NOR flash layout to
>>>> separate uboot from the config (that must be all there is in these
>>>> 256KB).
>>>>
>>>> Hope the patch is OK like that. Sorry for the long delay, I spent quite
>>>> some time on the IRQ0 fix, and did not have so much of it lately???
>>>>
>>>>  arch/arm/boot/dts/Makefile           |   3 +-
>>>>  arch/arm/boot/dts/orion5x-lswsgl.dts | 276 ++++++++++++++++++++++++++++++++++
>>>>  arch/arm/mach-orion5x/Kconfig        |   6 +-
>>>>  arch/arm/mach-orion5x/lsmini-setup.c | 280 -----------------------------------
>>>>  4 files changed, 281 insertions(+), 284 deletions(-)
>>>>  create mode 100644 arch/arm/boot/dts/orion5x-lswsgl.dts
>>>>  delete mode 100644 arch/arm/mach-orion5x/lsmini-setup.c
>>>>
>>>> diff --git a/arch/arm/boot/dts/Makefile b/arch/arm/boot/dts/Makefile
>>>> index 992736b..bd5ad2f 100644
>>>> --- a/arch/arm/boot/dts/Makefile
>>>> +++ b/arch/arm/boot/dts/Makefile
>>>> @@ -441,7 +441,8 @@ dtb-$(CONFIG_ARCH_ORION5X) += \
>>>>  > > > 	> > > orion5x-lacie-d2-network.dtb \
>>>>  > > > 	> > > orion5x-lacie-ethernet-disk-mini-v2.dtb \
>>>>  > > > 	> > > orion5x-maxtor-shared-storage-2.dtb \
>>>> -> > > 	> > > orion5x-rd88f5182-nas.dtb
>>>> +> > > 	> > > orion5x-rd88f5182-nas.dtb \
>>>> +> > > 	> > > orion5x-lswsgl.dtb
>>>
>>> Hi Benjamin
>>>
>>> Please keep these in alphabetical order.
>>>
>>> Other than that:
>>>
>>> Acked-by: Andrew Lunn <andrew at lunn.ch>
>>
>> With the Acked-by from  Andrew Lunn I am ready to apply your patch.
>> However for the device tree I need the acked-by from Thomas Petazzoni but I
>> am sure he will give it as he already agreed for the armada-*.dts* files.
>>
>> I am not sure we need the formal acked-by from Alexey because the dts is
>> not based on a dts written by him.
> 
> It's just that I took all the devices definition from his .c; to me, it
> counts as derived work, but IANAL.

For me it is still the decription of the hardware not an derivated work.
Andrew what is your opinion on it?

But if we consider it as a derivated work then we need Alexey acked-by soon,
or going back to GPL only license.

> 
>> When you will send the v3 with the alphabetical order fixed and the acked-by
>> from Thomas Petazzoni I will apply it on the mvebu branches.
> 
> Thanks.
> 
>> In this v3, could you also remove  the reference to lsmini-setup.o in
>> arch/arm/mach-orion5x/Makefile ?
> 
> Yes, I spotted that lately.
> 
> Still, I am struggling with some more mistakes: the kernel boot with
> everything included, but for some reason it cannot boot with an initrd.
> At first, I got an ?INITRD: [?] overlaps in-use memory region -
> disabling initrd? that disappeared when removing the memory node from
> the dts. But I cannot reproduce it since, and now I sometimes get told
> that the initrd is corrupt, sometimes it isn't taken into account? my
> way of tweaking my configs and not being strict enough in keeping them
> around leads to a nightmare tracking this problem.
> 
> I now learned that I need CONFIG_ARM_ATAG_DTB_COMPAT to get the
> bootloader command-line and initrd address, but sometimes it mess with
> my setup. I have very weird behavior regarding console output
> (sometimes working, sometimes only with earlyprintk) and options around
> dtb/ATAGS. I am trying to sort this out.

I think we had similar issue on the Mirabox when we use the uImage. How do
you build the uImage, the value of LOADADRR is sensible.

> 
> BTW, during orion5x conversion to DT (for boards that support it),
> tag_fixup_mem32 was lost. It should not be needed as
> arch/arm/boot/compressed/atags_to_fdt.c:atags_to_fdt ditches zero-sized
> memory banks, and mines don't have anything above PAGE_MASK, but maybe
> it happens on some strange boards. I noticed it while looking at my
> overlapping memory regions bug.

Well I would be tempt by saying that if nobody complains about it, then
there is no problem :)

I also wants to warn you that usually we don't take any new code after the
-rc6 which should be release this week-end. After this then the code will
be a candidate for the 4.4 kernel.


Thanks,

Gregory

-- 
Gregory Clement, Free Electrons
Kernel, drivers, real-time and embedded Linux
development, consulting, training and support.
http://free-electrons.com


From l.stach at pengutronix.de  Wed Aug  5 09:54:37 2015
From: l.stach at pengutronix.de (Lucas Stach)
Date: Wed,  5 Aug 2015 18:54:37 +0200
Subject: [PATCH] ARM: imx6: correct i.MX6 PCIe interrupt routing
Message-ID: <1438793677-19153-1-git-send-email-l.stach@pengutronix.de>

The PCIe interrupts are also routed through the GPC. This has been
missed from the conversion to stacked IRQ domains as the PCIe
controller uses an explicit interrupt map and thus doesn't inherit
the SoC global interrupt parent.

Signed-off-by: Lucas Stach <l.stach at pengutronix.de>
---
This commit does not change the i.MX6SX PCIe node, as PCIe isn't
functional in mainline on this SoC and the DT node needs a major
rewrite to account for the specifics of this SoC anyway.
---
 arch/arm/boot/dts/imx6qdl.dtsi | 8 ++++----
 1 file changed, 4 insertions(+), 4 deletions(-)

diff --git a/arch/arm/boot/dts/imx6qdl.dtsi b/arch/arm/boot/dts/imx6qdl.dtsi
index e6d13592080d..b57033e8c633 100644
--- a/arch/arm/boot/dts/imx6qdl.dtsi
+++ b/arch/arm/boot/dts/imx6qdl.dtsi
@@ -181,10 +181,10 @@
 			interrupt-names = "msi";
 			#interrupt-cells = <1>;
 			interrupt-map-mask = <0 0 0 0x7>;
-			interrupt-map = <0 0 0 1 &intc GIC_SPI 123 IRQ_TYPE_LEVEL_HIGH>,
-			                <0 0 0 2 &intc GIC_SPI 122 IRQ_TYPE_LEVEL_HIGH>,
-			                <0 0 0 3 &intc GIC_SPI 121 IRQ_TYPE_LEVEL_HIGH>,
-			                <0 0 0 4 &intc GIC_SPI 120 IRQ_TYPE_LEVEL_HIGH>;
+			interrupt-map = <0 0 0 1 &gpc GIC_SPI 123 IRQ_TYPE_LEVEL_HIGH>,
+			                <0 0 0 2 &gpc GIC_SPI 122 IRQ_TYPE_LEVEL_HIGH>,
+			                <0 0 0 3 &gpc GIC_SPI 121 IRQ_TYPE_LEVEL_HIGH>,
+			                <0 0 0 4 &gpc GIC_SPI 120 IRQ_TYPE_LEVEL_HIGH>;
 			clocks = <&clks IMX6QDL_CLK_PCIE_AXI>,
 				 <&clks IMX6QDL_CLK_LVDS1_GATE>,
 				 <&clks IMX6QDL_CLK_PCIE_REF_125M>;
-- 
2.4.6



From tchalamarla at caviumnetworks.com  Wed Aug  5 09:54:28 2015
From: tchalamarla at caviumnetworks.com (Tirumalesh Chalamarla)
Date: Wed, 5 Aug 2015 09:54:28 -0700
Subject: [PATCH V2] iommu/arm-smmu-v2: ThunderX mis-extends 64bit registers
Message-ID: <1438793668-15597-1-git-send-email-tchalamarla@caviumnetworks.com>

The SMMU architecture defines two different behaviors when 64-bit
registers are written with 32-bit writes.  The first behavior causes
zero extension into the upper 32-bits.  The second behavior splits a
64-bit register into "normal" 32-bit register pairs.

On some buggy implementations, registers incorrectly zero extended
when they should instead behave as normal 32-bit register pairs.

Signed-off-by: Tirumalesh Chalamarla <tchalamarla at caviumnetworks.com>
---

Changes from V1:
	- Introduced smmu_writeq

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

diff --git a/drivers/iommu/arm-smmu.c b/drivers/iommu/arm-smmu.c
index 66a803b..0912c78 100644
--- a/drivers/iommu/arm-smmu.c
+++ b/drivers/iommu/arm-smmu.c
@@ -69,6 +69,18 @@
 		((smmu->options & ARM_SMMU_OPT_SECURE_CFG_ACCESS)	\
 			? 0x400 : 0))
 
+#ifdef CONFIG_64BIT
+#define smmu_writeq(reg64, addr)	writeq_relaxed((reg64), (addr))
+#else
+#define smmu_writeq(reg64, addr)				\
+	do {							\
+		u64 __val = (reg64);				\
+		void __iomem *__addr = (addr);			\
+		writel_relaxed(__val >> 32, __addr + 4);	\
+		writel_relaxed(__val, __addr);			\
+	} while (0)
+#endif
+
 /* Configuration registers */
 #define ARM_SMMU_GR0_sCR0		0x0
 #define sCR0_CLIENTPD			(1 << 0)
@@ -226,7 +238,7 @@
 #define TTBCR2_SEP_SHIFT		15
 #define TTBCR2_SEP_UPSTREAM		(0x7 << TTBCR2_SEP_SHIFT)
 
-#define TTBRn_HI_ASID_SHIFT            16
+#define TTBRn_ASID_SHIFT		48
 
 #define FSR_MULTI			(1 << 31)
 #define FSR_SS				(1 << 30)
@@ -762,22 +774,17 @@ static void arm_smmu_init_context_bank(struct arm_smmu_domain *smmu_domain,
 
 	/* TTBRs */
 	if (stage1) {
-		reg = pgtbl_cfg->arm_lpae_s1_cfg.ttbr[0];
-		writel_relaxed(reg, cb_base + ARM_SMMU_CB_TTBR0_LO);
-		reg = pgtbl_cfg->arm_lpae_s1_cfg.ttbr[0] >> 32;
-		reg |= ARM_SMMU_CB_ASID(cfg) << TTBRn_HI_ASID_SHIFT;
-		writel_relaxed(reg, cb_base + ARM_SMMU_CB_TTBR0_HI);
-
-		reg = pgtbl_cfg->arm_lpae_s1_cfg.ttbr[1];
-		writel_relaxed(reg, cb_base + ARM_SMMU_CB_TTBR1_LO);
-		reg = pgtbl_cfg->arm_lpae_s1_cfg.ttbr[1] >> 32;
-		reg |= ARM_SMMU_CB_ASID(cfg) << TTBRn_HI_ASID_SHIFT;
-		writel_relaxed(reg, cb_base + ARM_SMMU_CB_TTBR1_HI);
+		u64 reg64 = pgtbl_cfg->arm_lpae_s1_cfg.ttbr[0];
+
+		reg64 |= ((u64)ARM_SMMU_CB_ASID(cfg)) << TTBRn_ASID_SHIFT;
+		smmu_writeq(reg64, cb_base + ARM_SMMU_CB_TTBR0_LO);
+
+		reg64 = pgtbl_cfg->arm_lpae_s1_cfg.ttbr[1];
+		reg64 |= ((u64)ARM_SMMU_CB_ASID(cfg)) << TTBRn_ASID_SHIFT;
+		smmu_writeq(reg64, cb_base + ARM_SMMU_CB_TTBR1_LO);
 	} else {
-		reg = pgtbl_cfg->arm_lpae_s2_cfg.vttbr;
-		writel_relaxed(reg, cb_base + ARM_SMMU_CB_TTBR0_LO);
-		reg = pgtbl_cfg->arm_lpae_s2_cfg.vttbr >> 32;
-		writel_relaxed(reg, cb_base + ARM_SMMU_CB_TTBR0_HI);
+		u64 reg64 = pgtbl_cfg->arm_lpae_s2_cfg.vttbr;
+		smmu_writeq(reg64, cb_base + ARM_SMMU_CB_TTBR0_LO);
 	}
 
 	/* TTBCR */
@@ -1236,10 +1243,8 @@ static phys_addr_t arm_smmu_iova_to_phys_hard(struct iommu_domain *domain,
 		u32 reg = iova & ~0xfff;
 		writel_relaxed(reg, cb_base + ARM_SMMU_CB_ATS1PR_LO);
 	} else {
-		u32 reg = iova & ~0xfff;
-		writel_relaxed(reg, cb_base + ARM_SMMU_CB_ATS1PR_LO);
-		reg = ((u64)iova & ~0xfff) >> 32;
-		writel_relaxed(reg, cb_base + ARM_SMMU_CB_ATS1PR_HI);
+		u64 reg64 = iova & ~0xfff;
+		smmu_writeq(reg64, cb_base + ARM_SMMU_CB_ATS1PR_LO);
 	}
 
 	if (readl_poll_timeout_atomic(cb_base + ARM_SMMU_CB_ATSR, tmp,
-- 
2.1.0



From pbonzini at redhat.com  Wed Aug  5 09:59:05 2015
From: pbonzini at redhat.com (Paolo Bonzini)
Date: Wed, 5 Aug 2015 18:59:05 +0200
Subject: [PATCH] kvm:arm:Fix error handling in the function vgic_v3_probe
In-Reply-To: <1438793303-30228-1-git-send-email-xerofoify@gmail.com>
References: <1438793303-30228-1-git-send-email-xerofoify@gmail.com>
Message-ID: <55C240D9.5060900@redhat.com>



On 05/08/2015 18:48, Nicholas Krause wrote:
> This fixes the error handling in the function vgic_v3_probe
> for when calling the function kvm_register_device_ops to check
> if the call to this function has returned a error code and if
> so jump to the label out with goto to cleanup no longer required
> resources used by the function vgic_v3_probe before returning the
> error code from the call to kvm_register_device_ops to the caller
> of the function vgic_v3_probe.
> 
> Signed-off-by: Nicholas Krause <xerofoify at gmail.com>
> ---
>  virt/kvm/arm/vgic-v3.c | 10 +++++++---
>  1 file changed, 7 insertions(+), 3 deletions(-)
> 
> diff --git a/virt/kvm/arm/vgic-v3.c b/virt/kvm/arm/vgic-v3.c
> index dff0602..5102aa2 100644
> --- a/virt/kvm/arm/vgic-v3.c
> +++ b/virt/kvm/arm/vgic-v3.c
> @@ -264,12 +264,16 @@ int vgic_v3_probe(struct device_node *vgic_node,
>  	} else {
>  		vgic->vcpu_base = vcpu_res.start;
>  		vgic->can_emulate_gicv2 = true;
> -		kvm_register_device_ops(&kvm_arm_vgic_v2_ops,
> -					KVM_DEV_TYPE_ARM_VGIC_V2);
> +		ret = kvm_register_device_ops(&kvm_arm_vgic_v2_ops,
> +					      KVM_DEV_TYPE_ARM_VGIC_V2);
> +		if (ret)
> +			goto out;
>  	}
>  	if (vgic->vcpu_base == 0)
>  		kvm_info("disabling GICv2 emulation\n");
> -	kvm_register_device_ops(&kvm_arm_vgic_v3_ops, KVM_DEV_TYPE_ARM_VGIC_V3);
> +	ret = kvm_register_device_ops(&kvm_arm_vgic_v3_ops, KVM_DEV_TYPE_ARM_VGIC_V3);
> +	if (ret)
> +		goto out;
>  
>  	vgic->vctrl_base = NULL;
>  	vgic->type = VGIC_V3;
> 

This really should never happen.  Perhaps kvm_register_device_ops should
instead return void, and WARN() when it currently returns an error.

Paolo


From andrew at lunn.ch  Wed Aug  5 10:00:02 2015
From: andrew at lunn.ch (Andrew Lunn)
Date: Wed, 5 Aug 2015 19:00:02 +0200
Subject: [PATCH v2] ARM: dts: Convert Linkstation Mini to Device Tree
In-Reply-To: <55C23FA8.9030504@free-electrons.com>
References: <1436885641.7145.9.camel@dolka.fr> <20150718185238.GH17961@lunn.ch>
 <55B396A1.1090509@free-electrons.com>
 <1438027893.15635.41.camel@dolka.fr>
 <55C23FA8.9030504@free-electrons.com>
Message-ID: <20150805170002.GF32760@lunn.ch>

> >> I am not sure we need the formal acked-by from Alexey because the dts is
> >> not based on a dts written by him.
> > 
> > It's just that I took all the devices definition from his .c; to me, it
> > counts as derived work, but IANAL.
> 
> For me it is still the decription of the hardware not an derivated work.
> Andrew what is your opinion on it?

Also, IANAL, but GPL "TERMS AND CONDITIONS" part 0 says:

      The "Program", below, refers to any such program or work, and a
      "work based on the Program" means either the Program or any
      derivative work under copyright law: that is to say, a work
      containing the Program or a portion of it, either verbatim or
      with modifications and/or translated into another language.

DT is a language, so i think we are on shaky ground if we did not
consider the possibility it is a derived work.

	 Andrew


From xerofoify at gmail.com  Wed Aug  5 10:07:18 2015
From: xerofoify at gmail.com (nick)
Date: Wed, 05 Aug 2015 13:07:18 -0400
Subject: [PATCH] kvm:arm:Fix error handling in the function vgic_v3_probe
In-Reply-To: <55C240D9.5060900@redhat.com>
References: <1438793303-30228-1-git-send-email-xerofoify@gmail.com>
 <55C240D9.5060900@redhat.com>
Message-ID: <55C242C6.6060200@gmail.com>



On 2015-08-05 12:59 PM, Paolo Bonzini wrote:
> 
> 
> On 05/08/2015 18:48, Nicholas Krause wrote:
>> This fixes the error handling in the function vgic_v3_probe
>> for when calling the function kvm_register_device_ops to check
>> if the call to this function has returned a error code and if
>> so jump to the label out with goto to cleanup no longer required
>> resources used by the function vgic_v3_probe before returning the
>> error code from the call to kvm_register_device_ops to the caller
>> of the function vgic_v3_probe.
>>
>> Signed-off-by: Nicholas Krause <xerofoify at gmail.com>
>> ---
>>  virt/kvm/arm/vgic-v3.c | 10 +++++++---
>>  1 file changed, 7 insertions(+), 3 deletions(-)
>>
>> diff --git a/virt/kvm/arm/vgic-v3.c b/virt/kvm/arm/vgic-v3.c
>> index dff0602..5102aa2 100644
>> --- a/virt/kvm/arm/vgic-v3.c
>> +++ b/virt/kvm/arm/vgic-v3.c
>> @@ -264,12 +264,16 @@ int vgic_v3_probe(struct device_node *vgic_node,
>>  	} else {
>>  		vgic->vcpu_base = vcpu_res.start;
>>  		vgic->can_emulate_gicv2 = true;
>> -		kvm_register_device_ops(&kvm_arm_vgic_v2_ops,
>> -					KVM_DEV_TYPE_ARM_VGIC_V2);
>> +		ret = kvm_register_device_ops(&kvm_arm_vgic_v2_ops,
>> +					      KVM_DEV_TYPE_ARM_VGIC_V2);
>> +		if (ret)
>> +			goto out;
>>  	}
>>  	if (vgic->vcpu_base == 0)
>>  		kvm_info("disabling GICv2 emulation\n");
>> -	kvm_register_device_ops(&kvm_arm_vgic_v3_ops, KVM_DEV_TYPE_ARM_VGIC_V3);
>> +	ret = kvm_register_device_ops(&kvm_arm_vgic_v3_ops, KVM_DEV_TYPE_ARM_VGIC_V3);
>> +	if (ret)
>> +		goto out;
>>  
>>  	vgic->vctrl_base = NULL;
>>  	vgic->type = VGIC_V3;
>>
> 
> This really should never happen.  Perhaps kvm_register_device_ops should
> instead return void, and WARN() when it currently returns an error.
> 
> Paolo
> 
Paolo,
I would like to do what you want but after tracing the callers of this function I found
this structure and wasn't sure if it can handle void function pointers.
static const struct of_device_id vgic_ids[] = {
        { .compatible = "arm,cortex-a15-gic",   .data = vgic_v2_probe, },
        { .compatible = "arm,cortex-a7-gic",    .data = vgic_v2_probe, },
        { .compatible = "arm,gic-400",          .data = vgic_v2_probe, },
        { .compatible = "arm,gic-v3",           .data = vgic_v3_probe, },
        {},
};
If this structure of function pointers can handle function pointers with a return type of 
void I will be glad to do what you request otherwise this would require a major rewrite
of kvm arm subsystem for a very simple bug fix.
Cheers,
Nick


From linux at arm.linux.org.uk  Wed Aug  5 10:09:20 2015
From: linux at arm.linux.org.uk (Russell King - ARM Linux)
Date: Wed, 5 Aug 2015 18:09:20 +0100
Subject: [PATCH v2] drm/i2c: tda998x: Fix bad checksum of the HDMI AVI
 infoframe
In-Reply-To: <20150804230153.GT7557@n2100.arm.linux.org.uk>
References: <E1ZK5bb-00079F-WC@bombadil.infradead.org>
 <20150804080557.58244c7c@armhf>
 <20150804230153.GT7557@n2100.arm.linux.org.uk>
Message-ID: <20150805170920.GA7557@n2100.arm.linux.org.uk>

On Wed, Aug 05, 2015 at 12:01:53AM +0100, Russell King - ARM Linux wrote:
> On Tue, Aug 04, 2015 at 08:05:57AM +0200, Jean-Francois Moine wrote:
> > On Tue, 28 Jul 2015 15:59:17 +0200
> > Jean-Francois Moine <moinejf at free.fr> wrote:
> > 
> > > Using hdmi_avi_infoframe_pack() to create the AVI infoframe calculates
> > > the checksum of the frame and breaks the second calculation which is
> > > done in tda998x_write_if(). Then the HDMI AVI frame is wrong and
> > > the display device does not handle correctly the video frames.
> > > 
> > > Fixes: 8c7a075da9f7980c ("use drm_hdmi_avi_infoframe_from_display_mode()")
> > > Signed-off-by: Jean-Francois Moine <moinejf at free.fr>
> > 
> > Ping!
> 
> I applied the patch a while back (July 17th to be exact) and in the queue
> to be sent - I'll update the commit message prior to doing that.  Thanks.

I've been able to get my hands on an AV amp, and I was hoping to use
that to validate things like the info frames.  Having investigated
today, while I'm able to get information from it, it's not as complete
as I'd like - for example, it gives me for the AVI:

	82 02 0D 12 28 08 1F 00 00 00 00 00 00 00 00 00

which is the CEA-861-D AVI, not the HDMI AVI (it's missing the checksum
between bytes 2 and 3).  Even more unfortunate is that it accepts the
transmitted AVI frame whether or not the checksum is valid.  However,
the AV amp reports that it sends the AVI frame onto the TV with a correct
checksum:

	82 02 0D 0E 12 28 08 1F ...

What this means is that I now have a way to read the various control
packets on HDMI, but not with their checksums, and no way to validate
whether the checksums are correct.

-- 
FTTC broadband for 0.8mile line: currently at 10.5Mbps down 400kbps up
according to speedtest.net.


From f.fainelli at gmail.com  Wed Aug  5 10:11:52 2015
From: f.fainelli at gmail.com (Florian Fainelli)
Date: Wed, 05 Aug 2015 10:11:52 -0700
Subject: [PATCH] ARM: BCM: Enable ARM erratum 798181 for BRCMSTB
In-Reply-To: <1438739008-16718-1-git-send-email-gregory.0xf0@gmail.com>
References: <1438739008-16718-1-git-send-email-gregory.0xf0@gmail.com>
Message-ID: <55C243D8.8050704@gmail.com>

On 04/08/15 18:43, Gregory Fong wrote:
> Commit 04fcab32d3fa1d3f6afe97e0ab431c5572e07a2c ("ARM: 8111/1: Enable
> erratum 798181 for Broadcom Brahma-B15") enables this erratum for
> affected Broadcom Brahma-B15 CPUs when CONFIG_ARM_ERRATA_798181=y.
> Let's make sure that config option is actually set.
> 
> Signed-off-by: Gregory Fong <gregory.0xf0 at gmail.com>

Applied, to soc/next, thanks!
-- 
Florian


From f.fainelli at gmail.com  Wed Aug  5 10:14:40 2015
From: f.fainelli at gmail.com (Florian Fainelli)
Date: Wed, 05 Aug 2015 10:14:40 -0700
Subject: [PATCH 1/2] MAINTAINERS: Add myself as a bcm2835 co-maintainer.
In-Reply-To: <1437594937-28583-1-git-send-email-eric@anholt.net>
References: <1437594937-28583-1-git-send-email-eric@anholt.net>
Message-ID: <55C24480.7080102@gmail.com>

On 22/07/15 12:55, Eric Anholt wrote:
> The current maintainers have limited free time to work on the
> architecture, and I'm motivated to do so for my work on graphics for
> Broadcom.  Arnd and Florian suggested to me that this might be the way
> forward.
> 
> Signed-off-by: Eric Anholt <eric at anholt.net>

Applied to maintainers/next with Stephen's Ack at
github.com/Broadcom/stblinux, will submit this shortly with other
Broadcom SoC changes, thanks!

> ---
>  MAINTAINERS | 1 +
>  1 file changed, 1 insertion(+)
> 
> diff --git a/MAINTAINERS b/MAINTAINERS
> index 2d3d55c..1c51379 100644
> --- a/MAINTAINERS
> +++ b/MAINTAINERS
> @@ -2217,6 +2217,7 @@ F:	drivers/clocksource/bcm_kona_timer.c
>  BROADCOM BCM2835 ARM ARCHITECTURE
>  M:	Stephen Warren <swarren at wwwdotorg.org>
>  M:	Lee Jones <lee at kernel.org>
> +M:	Eric Anholt <eric at anholt.net>
>  L:	linux-rpi-kernel at lists.infradead.org (moderated for non-subscribers)
>  T:	git git://git.kernel.org/pub/scm/linux/kernel/git/rpi/linux-rpi.git
>  S:	Maintained
> 


-- 
Florian


From f.fainelli at gmail.com  Wed Aug  5 10:15:12 2015
From: f.fainelli at gmail.com (Florian Fainelli)
Date: Wed, 05 Aug 2015 10:15:12 -0700
Subject: [PATCH 2/2] MAINTAINERS: Explicitly add linux-arm-kernel for
 bcm2835
In-Reply-To: <1437594937-28583-2-git-send-email-eric@anholt.net>
References: <1437594937-28583-1-git-send-email-eric@anholt.net>
 <1437594937-28583-2-git-send-email-eric@anholt.net>
Message-ID: <55C244A0.1060101@gmail.com>

On 22/07/15 12:55, Eric Anholt wrote:
> get_maintainers.pl would list linux-arm-kernel for most bcm2835
> changes because it's under arch/arm, but might not for other bcm2835
> drivers.  Most ARM architectures appear to list linux-arm-kernel as an
> appropriate list as well.
> 
> Signed-off-by: Eric Anholt <eric at anholt.net>
> Suggested-by: Stephen Warren <swarren at wwwdotorg.org>

Also applied, thanks!
-- 
Florian


From matthias.bgg at gmail.com  Wed Aug  5 10:24:56 2015
From: matthias.bgg at gmail.com (Matthias Brugger)
Date: Wed, 05 Aug 2015 19:24:56 +0200
Subject: [PATCH] ARM64: dts: mt6795: enable basic SMP bringup for MT6795
In-Reply-To: <1438656457-60278-1-git-send-email-scott.shu@mediatek.com>
References: <1438656457-60278-1-git-send-email-scott.shu@mediatek.com>
Message-ID: <3934554.inAhhRLsAY@ubix>

On Tuesday, August 04, 2015 10:47:37 AM Scott Shu wrote:
> This patch adds support SMP on MediaTek MT6795 Cortex-A53 Octa-core SoC.

applied to v4.2-next/arm64-2

> 
> The patch is based on v4.2-rc1 and following patch series:
> (1) Mars Cheng's "Add mt6795 basic chip support" [1]
> 
> [1] https://lkml.org/lkml/2015/7/14/63

Please this extra information below the "---" as this should not show up in 
the commit message.

Thanks,
Matthias

> 
> Signed-off-by: Scott Shu <scott.shu at mediatek.com>
> ---
>  arch/arm64/boot/dts/mediatek/mt6795.dtsi |   13 +++++++++++++
>  1 file changed, 13 insertions(+)
> 
> diff --git a/arch/arm64/boot/dts/mediatek/mt6795.dtsi
> b/arch/arm64/boot/dts/mediatek/mt6795.dtsi index da200e7..c85659d 100644
> --- a/arch/arm64/boot/dts/mediatek/mt6795.dtsi
> +++ b/arch/arm64/boot/dts/mediatek/mt6795.dtsi
> @@ -20,6 +20,11 @@
>  	#address-cells = <2>;
>  	#size-cells = <2>;
> 
> +	psci {
> +		compatible = "arm,psci-0.2";
> +		method = "smc";
> +	};
> +
>  	cpus {
>  		#address-cells = <1>;
>  		#size-cells = <0>;
> @@ -27,48 +32,56 @@
>  		cpu0: cpu at 0 {
>  			device_type = "cpu";
>  			compatible = "arm,cortex-a53";
> +			enable-method = "psci";
>  			reg = <0x000>;
>  		};
> 
>  		cpu1: cpu at 1 {
>  			device_type = "cpu";
>  			compatible = "arm,cortex-a53";
> +			enable-method = "psci";
>  			reg = <0x001>;
>  		};
> 
>  		cpu2: cpu at 2 {
>  			device_type = "cpu";
>  			compatible = "arm,cortex-a53";
> +			enable-method = "psci";
>  			reg = <0x002>;
>  		};
> 
>  		cpu3: cpu at 3 {
>  			device_type = "cpu";
>  			compatible = "arm,cortex-a53";
> +			enable-method = "psci";
>  			reg = <0x003>;
>  		};
> 
>  		cpu4: cpu at 100 {
>  			device_type = "cpu";
>  			compatible = "arm,cortex-a53";
> +			enable-method = "psci";
>  			reg = <0x100>;
>  		};
> 
>  		cpu5: cpu at 101 {
>  			device_type = "cpu";
>  			compatible = "arm,cortex-a53";
> +			enable-method = "psci";
>  			reg = <0x101>;
>  		};
> 
>  		cpu6: cpu at 102 {
>  			device_type = "cpu";
>  			compatible = "arm,cortex-a53";
> +			enable-method = "psci";
>  			reg = <0x102>;
>  		};
> 
>  		cpu7: cpu at 103 {
>  			device_type = "cpu";
>  			compatible = "arm,cortex-a53";
> +			enable-method = "psci";
>  			reg = <0x103>;
>  		};
>  	};



From wei.liu2 at citrix.com  Wed Aug  5 10:01:23 2015
From: wei.liu2 at citrix.com (Wei Liu)
Date: Wed, 5 Aug 2015 18:01:23 +0100
Subject: [PATCH v2 4/8] xen: Use the correctly the Xen memory terminologies
In-Reply-To: <1438711972-18752-5-git-send-email-julien.grall@citrix.com>
References: <1438711972-18752-1-git-send-email-julien.grall@citrix.com>
 <1438711972-18752-5-git-send-email-julien.grall@citrix.com>
Message-ID: <20150805170123.GB14224@zion.uk.xensource.com>

On Tue, Aug 04, 2015 at 07:12:48PM +0100, Julien Grall wrote:
[...]
> diff --git a/drivers/net/xen-netback/netback.c b/drivers/net/xen-netback/netback.c
> index 7d50711..3b7b7c3 100644
> --- a/drivers/net/xen-netback/netback.c
> +++ b/drivers/net/xen-netback/netback.c
> @@ -314,7 +314,7 @@ static void xenvif_gop_frag_copy(struct xenvif_queue *queue, struct sk_buff *skb
>  		} else {
>  			copy_gop->source.domid = DOMID_SELF;
>  			copy_gop->source.u.gmfn =
> -				virt_to_mfn(page_address(page));
> +				virt_to_gfn(page_address(page));
>  		}
>  		copy_gop->source.offset = offset;
>  
> @@ -1284,7 +1284,7 @@ static void xenvif_tx_build_gops(struct xenvif_queue *queue,
>  		queue->tx_copy_ops[*copy_ops].source.offset = txreq.offset;
>  
>  		queue->tx_copy_ops[*copy_ops].dest.u.gmfn =
> -			virt_to_mfn(skb->data);
> +			virt_to_gfn(skb->data);
>  		queue->tx_copy_ops[*copy_ops].dest.domid = DOMID_SELF;
>  		queue->tx_copy_ops[*copy_ops].dest.offset =
>  			offset_in_page(skb->data);

Acked-by: Wei Liu <wei.liu2 at citrix.com>


From f.fainelli at gmail.com  Wed Aug  5 10:44:41 2015
From: f.fainelli at gmail.com (Florian Fainelli)
Date: Wed,  5 Aug 2015 10:44:41 -0700
Subject: [GIT PULL] Broadcom Device Tree changes for 4.3 (part 2)
Message-ID: <1438796683-18581-1-git-send-email-f.fainelli@gmail.com>

The following changes since commit ee224e175e9d837b3d572e863ac96109b58707ac:

  Merge tag 'mvebu-dt-4.3-2' of git://git.infradead.org/linux-mvebu into next/dt (2015-08-05 11:10:30 +0200)

are available in the git repository at:

  http://github.com/broadcom/stblinux tags/arm-soc/for-4.3/dts-part2

for you to fetch changes up to 62c5fd2c319ae72e82abc3de689d8a8a4df5a3e9:

  ARM: dts: brcmstb: add BCM7445 GPIO nodes (2015-08-05 10:20:23 -0700)

----------------------------------------------------------------
This pull requests contains the following changes:

- Hauke enables additional I and D cache line prefetching for the BCM5301X L2
  cache controller (PL310)

- Felix adds the Cortex-A9 PMU DT nodes to allow profiling on BCM53101X

- Gregory adds L2 interrupt controllers and GPIO nodes to the reference BCM7445
  Device Tree include file

----------------------------------------------------------------
Felix Fietkau (1):
      ARM: BCM5301X: Add profiling support

Gregory Fong (1):
      ARM: dts: brcmstb: add BCM7445 GPIO nodes

Hauke Mehrtens (1):
      ARM: BCM5301X: activate some additional options in pl310 cache controller

 arch/arm/boot/dts/bcm5301x.dtsi | 10 +++++++++
 arch/arm/boot/dts/bcm7445.dtsi  | 50 +++++++++++++++++++++++++++++++++++++++++
 2 files changed, 60 insertions(+)


From f.fainelli at gmail.com  Wed Aug  5 10:44:42 2015
From: f.fainelli at gmail.com (Florian Fainelli)
Date: Wed,  5 Aug 2015 10:44:42 -0700
Subject: [GIT PULL] Broadcom MAINTAINERS file updates for 4.3
In-Reply-To: <1438796683-18581-1-git-send-email-f.fainelli@gmail.com>
References: <1438796683-18581-1-git-send-email-f.fainelli@gmail.com>
Message-ID: <1438796683-18581-2-git-send-email-f.fainelli@gmail.com>

The following changes since commit d770e558e21961ad6cfdf0ff7df0eb5d7d4f0754:

  Linux 4.2-rc1 (2015-07-05 11:01:52 -0700)

are available in the git repository at:

  http://github.com/broadcom/stblinux tags/arm-soc/for-4.3/maintainers

for you to fetch changes up to 824811293538f5cafaa6d19e3458a13eafa92a32:

  MAINTAINERS: Explicitly add linux-arm-kernel for bcm2835 (2015-08-05 10:14:00 -0700)

----------------------------------------------------------------
This pull request contains the following changes to the MAINTAINERS file:

- Add Eric Anholt as a 3rd maintainer for the Raspberry Pi platform code/drivers
- Add linux-arm-kernel for all bcm2835 related drivers

----------------------------------------------------------------
Eric Anholt (2):
      MAINTAINERS: Add myself as a bcm2835 co-maintainer.
      MAINTAINERS: Explicitly add linux-arm-kernel for bcm2835

 MAINTAINERS | 2 ++
 1 file changed, 2 insertions(+)


From linux at arm.linux.org.uk  Wed Aug  5 10:53:03 2015
From: linux at arm.linux.org.uk (Russell King - ARM Linux)
Date: Wed, 5 Aug 2015 18:53:03 +0100
Subject: [PATCH 3/4] arm64: Juno: Add HDLCD support to the Juno boards.
In-Reply-To: <1438784892-27888-4-git-send-email-Liviu.Dudau@arm.com>
References: <1438784892-27888-1-git-send-email-Liviu.Dudau@arm.com>
 <1438784892-27888-4-git-send-email-Liviu.Dudau@arm.com>
Message-ID: <20150805175303.GB7557@n2100.arm.linux.org.uk>

On Wed, Aug 05, 2015 at 03:28:11PM +0100, Liviu Dudau wrote:
> +		hdmi-transmitter at 71 {
>  			compatible = "nxp,tda998x";
>  			reg = <0x71>;
> +			port {
> +				tda998x_1_input: endpoint at 0 {
> +					remote-endpoint = <&hdlcd1_output>;
> +				};
> +
> +				tda998x_1_output: endpoint at 1 {
> +					remote-endpoint = <&hdmi1_connector_output>;
> +				};
> +			};

This isn't compliant with the TDA998x binding, and is very likely to
screw Jean's work on adding audio support.  See emails on lakml and
Documentation/devicetree/bindings/drm/i2c/tda998x.txt (which looks
like it needs updating to include the ports stuff.)

Also, the whole question of representing connectors in a DRM model is
yet to be established.  Yes, DT should describe the hardware, but we
don't yet know _how_ to describe physical connectors with stuff
implemented on top of DRM yet, and we have nothing that makes use of
this.

Also note that ePAPR requires a reg= property if you specify a
unit-address (the bit after the @ sign) so the above is non-compliant
with ePAPR as well.

-- 
FTTC broadband for 0.8mile line: currently at 10.5Mbps down 400kbps up
according to speedtest.net.


From sboyd at codeaurora.org  Wed Aug  5 10:56:38 2015
From: sboyd at codeaurora.org (Stephen Boyd)
Date: Wed, 05 Aug 2015 10:56:38 -0700
Subject: [PATCH 1/3] clk: versatile: Switch to assigned clock parents
In-Reply-To: <1438770574.2142.80.camel@arm.com>
References: <55BBB2FC.9030102@codeaurora.org>
 <1438386285-5070-1-git-send-email-sboyd@codeaurora.org>
 <1438386285-5070-2-git-send-email-sboyd@codeaurora.org>
 <1438610480.2142.14.camel@arm.com> <55BFAB11.7080600@codeaurora.org>
 <1438770574.2142.80.camel@arm.com>
Message-ID: <55C24E56.3020004@codeaurora.org>

On 08/05/2015 03:29 AM, Pawel Moll wrote:
>
> Right, that's probably my fault. The sp810 nodes appeared in the VE
> trees very early (in terms of the "DT era"), when we weren't so strict
> about documentation. So far, it would be fairly simple, something like
> the text below - feel free to take it, mend it, extend it with your
> changes and include in the series:
>
> Thanks!

Great! Can you please provide your signed-off-by? I can make it up into 
a patch with some commit text that either you or I provide and throw it 
into the series.

-- 
Qualcomm Innovation Center, Inc. is a member of Code Aurora Forum,
a Linux Foundation Collaborative Project



From catalin.marinas at arm.com  Wed Aug  5 10:57:53 2015
From: catalin.marinas at arm.com (Catalin Marinas)
Date: Wed, 5 Aug 2015 18:57:53 +0100
Subject: [PATCH 07/13] arm64: KVM: VHE: Patch out use of HVC
In-Reply-To: <1436372356-30410-8-git-send-email-marc.zyngier@arm.com>
References: <1436372356-30410-1-git-send-email-marc.zyngier@arm.com>
 <1436372356-30410-8-git-send-email-marc.zyngier@arm.com>
Message-ID: <20150805175752.GF24073@e104818-lin.cambridge.arm.com>

On Wed, Jul 08, 2015 at 05:19:10PM +0100, Marc Zyngier wrote:
> --- /dev/null
> +++ b/arch/arm64/kvm/vhe-macros.h
> @@ -0,0 +1,36 @@
> +/*
> + * Copyright (C) 2015 - ARM Ltd
> + * Author: Marc Zyngier <marc.zyngier at arm.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.
> + *
> + * You should have received a copy of the GNU General Public License
> + * along with this program.  If not, see <http://www.gnu.org/licenses/>.
> + */
> +
> +#ifndef __ARM64_VHE_MACROS_H__
> +#define __ARM64_VHE_MACROS_H__
> +
> +#include <asm/alternative.h>
> +#include <asm/cpufeature.h>
> +
> +#ifdef __ASSEMBLY__
> +
> +/* Hack to allow stringification of macros... */
> +#define __S__(a,args...)	__stringify(a, ##args)
> +#define _S_(a,args...)		__S__(a, args)
> +
> +.macro ifnvhe nonvhe vhe
> +	alternative_insn	"\nonvhe", "\vhe", ARM64_HAS_VIRT_HOST_EXTN
> +.endm

I always found the alternative_insn tricks hard to read but with
Daniel's patch queued in -next it gets slightly better. If you are not
targeting 4.3, could you do something like (untested):

.macro	vhe_if_not
	alternative_if_not ARM64_HAS_VIRT_HOST_EXTN
.endm

.macro	vhe_else
	alternative_else CONFIG_ARM64_VHE
.endm

.macro	vhe_endif
	alternative_endif CONFIG_ARM64_VHE
.endm


The kvm_call_hyp, for example, would become:

ENTRY(kvm_call_hyp)
vhe_if_not
	hvc	#0
	ret
vhe_else
	nop
	push	lr, xzr
vhe_endif


Or you can even ignore defining new vhe_* macros altogether and just use
"alternative_if_not ARM64_HAS_VIRT_HOST_EXTN" directly (more to type)
but you may be able to avoid a vhe-macros.h file.

-- 
Catalin


From sre at kernel.org  Wed Aug  5 11:04:19 2015
From: sre at kernel.org (Sebastian Reichel)
Date: Wed, 5 Aug 2015 20:04:19 +0200
Subject: [PATCH v2 1/2] power: reset: at91: add sama5d3 reset function
In-Reply-To: <55B72EEA.5020600@atmel.com>
References: <1437384726-24927-1-git-send-email-josh.wu@atmel.com>
 <20150720164241.GA5930@earth> <55B72EEA.5020600@atmel.com>
Message-ID: <20150805180419.GA11315@earth>

Hi Nicolas,

On Tue, Jul 28, 2015 at 09:27:38AM +0200, Nicolas Ferre wrote:
> >> This patch introduces a new compatible string: "atmel,sama5d3-rstc" and
> >> new reset function for sama5d3 and later chips.
> > 
> > queued.
> 
> As my Device Tree changes depend on this modification,
> we can synchronize in tree ways:

Sorry for the delay.

> 1/ you provide me a stable branch so that I can pull it before applying
> my changes that can go through arm-soc.
> 
> 2/ you let me take the driver's modifications with me and the two
> patches of the series would go through arm-soc.
>
> 3/ you take the second patch of my series with my Acked-by tag and carry
> both of them up to Linus' tree.

I would be fine with all solutions, but 2/ would also require
you handling another patch. I think your option 4/ is the best:

> Okay, so to ease synchronization, I take this one with me through
> arm-soc and add the old compatibility string as a fallback => the
> newer will be used when merged...

FWIW:

Acked-By: Sebastian Reichel <sre at kernel.org>

-- Sebastian
-------------- next part --------------
A non-text attachment was scrubbed...
Name: signature.asc
Type: application/pgp-signature
Size: 819 bytes
Desc: Digital signature
URL: <http://lists.infradead.org/pipermail/linux-arm-kernel/attachments/20150805/b46ff934/attachment.sig>

From sre at kernel.org  Wed Aug  5 11:11:38 2015
From: sre at kernel.org (Sebastian Reichel)
Date: Wed, 5 Aug 2015 20:11:38 +0200
Subject: [PATCH 01/23] Documentation: dt: atmel-at91: add clocks to
 system timer, rstc and shdwc
In-Reply-To: <1438335599-3301-2-git-send-email-alexandre.belloni@free-electrons.com>
References: <1438335599-3301-1-git-send-email-alexandre.belloni@free-electrons.com>
 <1438335599-3301-2-git-send-email-alexandre.belloni@free-electrons.com>
Message-ID: <20150805181137.GB11315@earth>

Hi,

On Fri, Jul 31, 2015 at 11:39:37AM +0200, Alexandre Belloni wrote:
> The system timer (at91rm9200), the reset controller and the shutdown
> controller need an input clock. This is the slow clock and they will not
> function without it.
> 
> Also fix the shutdown controller example.

Acked-By: Sebastian Reichel <sre at kernel.org>

-- Sebastian
-------------- next part --------------
A non-text attachment was scrubbed...
Name: signature.asc
Type: application/pgp-signature
Size: 819 bytes
Desc: Digital signature
URL: <http://lists.infradead.org/pipermail/linux-arm-kernel/attachments/20150805/7c1a4099/attachment.sig>

From sre at kernel.org  Wed Aug  5 11:22:20 2015
From: sre at kernel.org (Sebastian Reichel)
Date: Wed, 5 Aug 2015 20:22:20 +0200
Subject: [PATCH 18/23] power/reset: at91-reset: get and use slow clock
In-Reply-To: <1438335599-3301-19-git-send-email-alexandre.belloni@free-electrons.com>
References: <1438335599-3301-1-git-send-email-alexandre.belloni@free-electrons.com>
 <1438335599-3301-19-git-send-email-alexandre.belloni@free-electrons.com>
Message-ID: <20150805182220.GC11315@earth>

Hi,

On Fri, Jul 31, 2015 at 11:39:54AM +0200, Alexandre Belloni wrote:
> Commit dca1a4b5ff6e ("clk: at91: keep slow clk enabled to prevent system
> hang") added a workaround for the slow clock as it is not properly handled
> by its users.
> 
> Get and use the slow clock as it is necessary for the at91 reset
> controller.

You call clk_prepare_enable during probe without a matching
clk_disable_unprepare on module removal.

-- Sebastian
-------------- next part --------------
A non-text attachment was scrubbed...
Name: signature.asc
Type: application/pgp-signature
Size: 819 bytes
Desc: Digital signature
URL: <http://lists.infradead.org/pipermail/linux-arm-kernel/attachments/20150805/c9c0c0ac/attachment.sig>

From sre at kernel.org  Wed Aug  5 11:22:54 2015
From: sre at kernel.org (Sebastian Reichel)
Date: Wed, 5 Aug 2015 20:22:54 +0200
Subject: [PATCH 19/23] power/reset: at91-poweroff: get and use slow clock
In-Reply-To: <1438335599-3301-20-git-send-email-alexandre.belloni@free-electrons.com>
References: <1438335599-3301-1-git-send-email-alexandre.belloni@free-electrons.com>
 <1438335599-3301-20-git-send-email-alexandre.belloni@free-electrons.com>
Message-ID: <20150805182253.GD11315@earth>

Hi,

On Fri, Jul 31, 2015 at 11:39:55AM +0200, Alexandre Belloni wrote:
> Commit dca1a4b5ff6e ("clk: at91: keep slow clk enabled to prevent system
> hang") added a workaround for the slow clock as it is not properly handled
> by its users.
> 
> Get and use the slow clock as it is necessary for the at91 shutdown
> controller.

You call clk_prepare_enable during probe without a matching
clk_disable_unprepare on module removal.

-- Sebastian
-------------- next part --------------
A non-text attachment was scrubbed...
Name: signature.asc
Type: application/pgp-signature
Size: 819 bytes
Desc: Digital signature
URL: <http://lists.infradead.org/pipermail/linux-arm-kernel/attachments/20150805/245dc99a/attachment.sig>

From matthias.bgg at gmail.com  Wed Aug  5 11:44:11 2015
From: matthias.bgg at gmail.com (Matthias Brugger)
Date: Wed, 05 Aug 2015 20:44:11 +0200
Subject: [PATCH v3 0/5] Add SMP bringup support for mt65xx socs
In-Reply-To: <1436851111-2369-1-git-send-email-yingjoe.chen@mediatek.com>
References: <1436851111-2369-1-git-send-email-yingjoe.chen@mediatek.com>
Message-ID: <4831607.pyCH8elj8i@ubix>

On Tuesday, July 14, 2015 01:18:26 PM Yingjoe Chen wrote:
> This series add SMP brinup support for MediaTek SoCs. This is based
> on v4.2-rc1 and Matthias' next branch (for dts parts).
> 
> There are similar but different SMP bringup up methods on MediaTek
> mt65xx and mt81xx. On MT8135 & MT8127, system boots with a trustzone
> firmware. Others, like MT6589, doesn't have trustzone, and run kernel
> directly in secure world.
> 
> Patch 1 enable arch timer support.
> Patch 2,3 add support for cpu enable-method "mediatek,mt6589-smp" and
> "mediatek,mt81xx-tz-smp", which support Mediatek SMP bringup for non-TZ
> and TZ platform.
> Patch 4,5 finally enable SMP bringup for mt8135 and mt8127.
> 
> Changes in v3:
> - The first 2 patches in v2 are merged in v4.2-rc1.
> - Patch 3~4 in v2 are moved to another series [1]
> - platsmp.c changes based on Stephen's suggestion
> - Change cpu enable-method name to "mediatek,mt6589-smp"
> 
> Changes in v2:
> - Fix boot issue for THUMB2 kernel.
> - Not enable GPT_CLK_EVT when setup to fix GPT spurious interrupt issue
> - Change platsmp.c according to Matthias' suggestion
> http://lists.infradead.org/pipermail/linux-mediatek/2015-May/000714.html
> 
> v1:
> http://lists.infradead.org/pipermail/linux-mediatek/2015-May/000528.html
> 
> [1]
> http://lists.infradead.org/pipermail/linux-mediatek/2015-July/001544.html
> 
> Matthias Brugger (1):
>   ARM: mediatek: enable gpt6 on boot up to make arch timer working
> 
> Yingjoe Chen (4):
>   devicetree: bindings: add new SMP enable method Mediatek SoC
>   ARM: mediatek: add smp bringup code
>   ARM: dts: mt8135: enable basic SMP bringup for mt8135
>   ARM: dts: mt8127: enable basic SMP bringup for mt8127
> 
>  Documentation/devicetree/bindings/arm/cpus.txt |   2 +
>  arch/arm/boot/dts/mt8127.dtsi                  |  16 +++
>  arch/arm/boot/dts/mt8135.dtsi                  |  16 +++
>  arch/arm/mach-mediatek/Makefile                |   3 +
>  arch/arm/mach-mediatek/mediatek.c              |  27 +++++
>  arch/arm/mach-mediatek/platsmp.c               | 144
> +++++++++++++++++++++++++ 6 files changed, 208 insertions(+)
>  create mode 100644 arch/arm/mach-mediatek/platsmp.c

Applied to v4.2-next/soc-2 and v4.2-next/dts-2 

Thanks,
Matthias


From f.fainelli at gmail.com  Wed Aug  5 10:44:43 2015
From: f.fainelli at gmail.com (Florian Fainelli)
Date: Wed,  5 Aug 2015 10:44:43 -0700
Subject: [GIT PULL] Broadcom SoC changes for 4.3 (part 2)
In-Reply-To: <1438796683-18581-1-git-send-email-f.fainelli@gmail.com>
References: <1438796683-18581-1-git-send-email-f.fainelli@gmail.com>
Message-ID: <1438796683-18581-3-git-send-email-f.fainelli@gmail.com>

The following changes since commit 39aa437e18cac7acae55481ed73feea0de497399:

  Merge branch 'queue/irq/arm' of git://git.kernel.org/pub/scm/linux/kernel/git/tip/tip into next/cleanup (2015-08-05 17:24:11 +0200)

are available in the git repository at:

  http://github.com/broadcom/stblinux tags/arm-soc/for-4.3/soc-part2

for you to fetch changes up to 661e59d30168331e5e1c7386d23ea8fd14965270:

  ARM: BCM: Enable ARM erratum 798181 for BRCMSTB (2015-08-05 10:30:59 -0700)

----------------------------------------------------------------
This pull request contains the following changes:

- Gregory updates the BRCMSTB Kconfig to select the ARM erratum 798181 which
  affects the chips covered by this platform

----------------------------------------------------------------
Gregory Fong (1):
      ARM: BCM: Enable ARM erratum 798181 for BRCMSTB

 arch/arm/mach-bcm/Kconfig | 1 +
 1 file changed, 1 insertion(+)


From Liviu.Dudau at arm.com  Wed Aug  5 12:03:12 2015
From: Liviu.Dudau at arm.com (Liviu Dudau)
Date: Wed, 5 Aug 2015 20:03:12 +0100
Subject: [PATCH 3/4] arm64: Juno: Add HDLCD support to the Juno boards.
In-Reply-To: <20150805175303.GB7557@n2100.arm.linux.org.uk>
References: <1438784892-27888-1-git-send-email-Liviu.Dudau@arm.com>
 <1438784892-27888-4-git-send-email-Liviu.Dudau@arm.com>
 <20150805175303.GB7557@n2100.arm.linux.org.uk>
Message-ID: <20150805190312.GA31066@e106497-lin.cambridge.arm.com>

On Wed, Aug 05, 2015 at 06:53:03PM +0100, Russell King - ARM Linux wrote:
> On Wed, Aug 05, 2015 at 03:28:11PM +0100, Liviu Dudau wrote:
> > +		hdmi-transmitter at 71 {
> >  			compatible = "nxp,tda998x";
> >  			reg = <0x71>;
> > +			port {
> > +				tda998x_1_input: endpoint at 0 {
> > +					remote-endpoint = <&hdlcd1_output>;
> > +				};
> > +
> > +				tda998x_1_output: endpoint at 1 {
> > +					remote-endpoint = <&hdmi1_connector_output>;
> > +				};
> > +			};

Hi Russell,

Thanks for reviewing this, I will integrate your comments in the
next revision.

> 
> This isn't compliant with the TDA998x binding, and is very likely to
> screw Jean's work on adding audio support.  See emails on lakml and
> Documentation/devicetree/bindings/drm/i2c/tda998x.txt (which looks
> like it needs updating to include the ports stuff.)

I have to confess that I am not entirely up to speed with the TDA19988
situation at the moment. Andrew Jackson was dealing with that and
working with Jean to get that in the upstream, but his contract has
ended and he has moved to other things. While I did get through a
(limited) set of patches that Jean has sent around, I'm a bit confused
about the latest state of play. Is there an authoritative source from
where I can grab the patches that are going to be in 4.3? Otherwise,
as far as the current patchset base (4.2-rc2) is concerned, I am
compliant with the bindings if you ignore the port subnode (see further
below). I am happy to update the patchset to match what is going into
mainline, but just reading the emails in the mailing list I'm not
exactly sure on the sequencing of things here.

> 
> Also, the whole question of representing connectors in a DRM model is
> yet to be established.  Yes, DT should describe the hardware, but we
> don't yet know _how_ to describe physical connectors with stuff
> implemented on top of DRM yet, and we have nothing that makes use of
> this.

Please help me understand the current situation: you have added
support for components that the video drivers can use and the bindings
for that are described in Documentation/devicetree/bindings/media/video-interfaces.txt.
According to that document my patch should be compliant once I add the
reg= property. Is that something that cannot be used with tda998x driver
or is there any other reason why you think the patch is not compliant?

If you are referring to connecting an encoder with a HDMI connector, I
have tested that and it seems to work, although my situation is simple
because there are no options in my setup: one HDLCD connects to one TDA19988
which connects to one HDMI output.

> 
> Also note that ePAPR requires a reg= property if you specify a
> unit-address (the bit after the @ sign) so the above is non-compliant
> with ePAPR as well.

Thanks, I will add the reg property.

Best regards,
Liviu

> 
> -- 
> FTTC broadband for 0.8mile line: currently at 10.5Mbps down 400kbps up
> according to speedtest.net.
> 

-- 
====================
| I would like to |
| fix the world,  |
| but they're not |
| giving me the   |
 \ source code!  /
  ---------------
    ?\_(?)_/?



From robert.jarzmik at free.fr  Wed Aug  5 12:11:17 2015
From: robert.jarzmik at free.fr (Robert Jarzmik)
Date: Wed, 05 Aug 2015 21:11:17 +0200
Subject: [PATCH-v5 5/5] i2c: pxa: Add ILCR (tLow & tHigh) configuration
 support
In-Reply-To: <55C1CE8E.9000601@linaro.org> (Vaibhav Hiremath's message of
 "Wed, 05 Aug 2015 14:21:26 +0530")
References: <1437482466-16126-1-git-send-email-vaibhav.hiremath@linaro.org>
 <1437482466-16126-6-git-send-email-vaibhav.hiremath@linaro.org>
 <55C1CE8E.9000601@linaro.org>
Message-ID: <87h9odlfe2.fsf@belgarion.home>

Vaibhav Hiremath <vaibhav.hiremath at linaro.org> writes:

> Robert,
>
> It would be helpful if you can test this patch-series and confirm that
> it now fixes the NULL pointer deference issue.
>
> Thanks,
> Vaibhav
Hi Vaibhav,

My next slot is probably this comming Sunday. I'll do the test and report.

Cheers.

-- 
Robert


From lina.iyer at linaro.org  Wed Aug  5 12:23:41 2015
From: lina.iyer at linaro.org (Lina Iyer)
Date: Wed, 5 Aug 2015 13:23:41 -0600
Subject: [PATCH 6/9] ARM: domain: Add platform handlers for CPU PM domains
In-Reply-To: <CAL_JsqKWekSGiFbZz6++3ibAzY_8Y6+0nOBQinFVw4cBk6JvEw@mail.gmail.com>
References: <1438731339-58317-1-git-send-email-lina.iyer@linaro.org>
 <1438731339-58317-7-git-send-email-lina.iyer@linaro.org>
 <CAL_JsqKWekSGiFbZz6++3ibAzY_8Y6+0nOBQinFVw4cBk6JvEw@mail.gmail.com>
Message-ID: <20150805192341.GB52339@linaro.org>

On Wed, Aug 05 2015 at 08:45 -0600, Rob Herring wrote:
>On Tue, Aug 4, 2015 at 6:35 PM, Lina Iyer <lina.iyer at linaro.org> wrote:
>> In addition to the common power up/down actions of CPU PM domain core,
>> platforms may have additional configuration before the CPU domain can be
>> powered off or considered active. Allow platform drivers to register
>> handlers for CPU PM domains.
>>
>> Platform drivers may register their callbacks against a compatible
>> string defined by their PM domain provider device node in the DT. At
>> domain init, the platform driver can initialize the platform specific
>> genpd attributes. The init callback would need to return successfully,
>> for the platform power_on/off handlers to be registered with the CPU PM
>> domain.
>>
>> The code uses __init section to reduce memory needed for platform
>> handlers and therefore can be freed after the driver is initialized, a
>> desirable outcome for single kernel image.
>
>[...]
>
>> diff --git a/arch/arm/include/asm/arm-pd.h b/arch/arm/include/asm/arm-pd.h
>> new file mode 100644
>> index 0000000..fc44abf

[...]

>> +#define ARM_PD_METHOD_OF_DECLARE(_name, _handle, _ops) \
>> +       static const struct of_arm_pd_method __arm_pd_method_of_table_##_name \
>> +       __used __section(__arm_pd_method_of_table)              \
>> +       = { .handle = _handle, .ops = _ops }
>
>AFAICT, you are not using this in this series. You should add it when
>you have a user.
>
>Ideally, we keep some amount of uniformity across various *_OF_DECLARE
>which is why we have OF_DECLARE_1 and OF_DECLARE_2. This makes all the
>sections just arrays of struct of_device_id. Not all users follow
>this, but most do. So instead of putting the ops in here, platforms
>can provide a function callback which can then set the ops. Then you
>also don't need the .init() ops function as the callback function can
>do any initialization too.
>
I looked through these and I can switch over to _OF_DECLARE() without any
issues, but using OF_DECLARE_1 or OF_DECLARE_2 is pretty limiting.

If I could set up my own function type for the .data member, then its a
lot more easier on the code. Like this -

typedef int (*arm_pd_init)(struct device_node *dn, struct
		generic_pm_domain *genpd, struct of_arm_pd_ops *ops);

 #define ARM_PD_METHOD_OF_DECLARE(name, compat, fn)     \
	        _OF_DECLARE(arm_pd, name, compat, fn, arm_pd_init)

Its still in the of_device_id array.

Is that acceptable?

Thanks,
Lina


From ezequiel at vanguardiasur.com.ar  Wed Aug  5 12:26:55 2015
From: ezequiel at vanguardiasur.com.ar (Ezequiel Garcia)
Date: Wed, 5 Aug 2015 16:26:55 -0300
Subject: [PATCH v4 0/2] NXP SPIFI driver for LPC18xx/43xx familiy
In-Reply-To: <1436473147-31063-1-git-send-email-manabian@gmail.com>
References: <1436473147-31063-1-git-send-email-manabian@gmail.com>
Message-ID: <CAAEAJfCnD9acd_iBawbYUbmKDsV=yqoQ6QuoneBK-u-qBELa2w@mail.gmail.com>

Brian,

Mind if I ping you on this one?

On 9 July 2015 at 17:19, Joachim Eastwood <manabian at gmail.com> wrote:
> This patch set adds a SPI-NOR driver for the NXP SPI Flash (SPIFI)
> controller that can be found on newer NXP MCUs. For example on the
> LPC18xx and LPC43xx familiy.
>
> NXP SPIFI is a specialized SPI interface for serial Flash devices.
> It supports one Flash device with 1-, 2- and 4-bits width in SPI
> mode 0 or 3. The controller operates in either command or memory
> mode. In memory mode the Flash is made accessible for the CPU as
> normal memory.
>
> This version fix a bug in the write function discovered during
> testing with JFFS2.
>
> Changes since v3:
>  - fix bug in write function
>  - rebase on 4.2-rc1
>
> Changes since v2:
>  - default to auto detection unless chip is specified
>  - update doc with reference to jedec,spi-nor.txt
>
> Changes since v1:
>  - use readb_poll_timeout instead of open coding
>  - cache current mode (memory/command)
>  - depend on HAS_IOMEM
>  - removed stray white space
>  - removed leftover debug print
>
> Joachim Eastwood (2):
>   mtd: spi-nor: add driver for NXP SPI Flash Interface (SPIFI)
>   doc: dt: add documentation for nxp,lpc1773-spifi
>
>  .../devicetree/bindings/mtd/nxp-spifi.txt          |  58 +++
>  drivers/mtd/spi-nor/Kconfig                        |  11 +
>  drivers/mtd/spi-nor/Makefile                       |   1 +
>  drivers/mtd/spi-nor/nxp-spifi.c                    | 494 +++++++++++++++++++++
>  4 files changed, 564 insertions(+)
>  create mode 100644 Documentation/devicetree/bindings/mtd/nxp-spifi.txt
>  create mode 100644 drivers/mtd/spi-nor/nxp-spifi.c
>
> --
> 1.8.0
>



-- 
Ezequiel Garc?a, VanguardiaSur
www.vanguardiasur.com.ar


From mturquette at baylibre.com  Wed Aug  5 12:27:48 2015
From: mturquette at baylibre.com (Michael Turquette)
Date: Wed, 05 Aug 2015 12:27:48 -0700
Subject: [PATCH v2 3/9] arm: twr-k70f120m: clock driver for Kinetis SoC
In-Reply-To: <alpine.LNX.2.00.1508011647140.32078@localhost.localdomain>
References: <1435667250-28299-1-git-send-email-pawelo@king.net.pl>
 <alpine.LNX.2.00.1507042327490.1296@localhost.localdomain>
 <20150724034229.642.88156@quantum>
 <alpine.LNX.2.00.1507262211470.28341@localhost.localdomain>
 <20150728160347.642.31950@quantum>
 <alpine.LNX.2.00.1507282201220.2619@localhost.localdomain>
 <20150729230517.642.66061@quantum>
 <alpine.LNX.2.00.1507302326500.20387@localhost.localdomain>
 <20150801005810.23791.8199@quantum>
 <alpine.LNX.2.00.1508011647140.32078@localhost.localdomain>
Message-ID: <20150805192748.23791.32178@quantum>

Quoting Paul Osmialowski (2015-08-01 08:27:30)
> 
> Hi Mike,
> 
> On Fri, 31 Jul 2015, Michael Turquette wrote:
> 
> > Quoting Paul Osmialowski (2015-07-30 14:40:48)
> > > Hi Mike,
> > > 
> > > I encountered some trouble while I tried to implement code fitting to DTS 
> > > that you proposed. SIM_CLKDIVx are SIM device registers, not MCG. 
> > > Therefore, in MCG device code I won't be able to figure out clock rate 
> > > for outputed clocks unles I try to access SIM registers from MCG driver - 
> > 
> > Right, the MCG driver will only know the rates of the clocks that it
> > outputs, namely:
> > 
> > MCGIRCLK
> > MCGFFCLK
> > MCGOUTCLK
> > MCGFLLCLK
> > MCGPLL0CLK
> > MCGPLL1CLK
> > 
> > The naming scheme in the TRM is a bit unfortunate; it looks like some of
> > the clock outputs coming out of SIM also retain the MCG* names.
> 
> I wonder if I really need to implement support for all of these clocks 
> while to run Linux on this board reference 2.6 kernel uses only MCGOUTCLK 
> (and for this, it never considers FLL as a source). 
> I can also provide support for MCGPLL0CLK and MCGPLL1CLK as well since 
> their rates are computed as a byproduct while determining rate of 
> MCGOUTCLK. I may define constants for all of them in related header file, 
> but I'm thinking about leaving most of implementations as TBD - otherwise 
> I doubt I'll be ever able to test that my driver fully works.

You do not need to implement support for everything in your driver if
you don't want to, but DT binding descriptions are supposed to a stable
ABI. Why not make clock-cells == 1 and sleep better at night knowing
that you can grow the number of clocks you expose in the mcg node?

As kernel developers it is our job to write code that allows for restful
sleep.

> 
> > 
> > Why is clock-cells zero? I think the MCG block outputs all of the clocks
> > that I listed above? As such they should be addressable as <&mcg N> by
> > any downstream users.
> > 
> 
> Ok, will be 1, to distinguish between MCGOUTCLK, MCGPLL0CLK, MCGPLL1CLK.

Great.

> 
> 
> > >                         reg = <0x40064000 0x14>;
> > >                         clocks = <&osc0>, <&osc1>, <&rtc>;
> > >                         clock-names = "osc0", "osc1", "rtc";
> > 
> > Are the oscN and rtc clocks modeled as fixed-rate clocks in DT?
> > 
> 
> Yes, I skipped the part above soc during copy-paste.
> 
> > It looks like the SIM block should also consume:
> > 
> > MCGFLLCLK
> > MCGIRCLK
> > MCGFFCLK
> > MCGPLL0CLK
> > MCGPLL1CLK
> > OSC0ERCLK
> > OSC1ERCLK
> > OSC032KCLK
> > RTCCLK (I made that name up)
> > 
> > The mcg clocks should come out of the mcg node. It looks like you
> > already modeled oscN and rtc clocks, which is great. There are some
> > gates after these clocks (e.g. OSC0ERCLK). I wonder if those gates are
> > actually in the osc IP block or if they actually live in SIM. More on
> > that below...
> > 
> > Well they certainly can be exposed if you need them to be. If a device
> > driver wants to get the core clock and set it's rate then it should be
> > able to with something like <&sim CORE_CLK>.
> > 
> 
> Ok, the user of the clock does not relly need to know whether it is clock 
> device or a clock gate - fortunately, I already learnt how to implement 
> such thing.
> 
> > > 
> > > Also note that fec (ethernet device) driver is connected directly to osc0 
> > > (though clock gate, you can see this CG attached to osc0 on the diagram 
> > > too) - to control this gate I need to access SIM device registers, so it 
> > > should be covered by the same fsl,kinetis-sim driver.
> > 
> > Do you mean the SIM_SOPT2 register? It looks like the connection is not
> > "direct", as the osc0 signal feeds into the SIM block and the gate there
> > controls it.  Perhaps the diagram is incorrect by placing the CG block
> > inside osc0? It looks like you correctly modeled this relationship in
> > the sim node.
> 
> In order to enable network device, bit 0 of SIM_SCGC2 must be set for RMII 
> mode to work, and according to what I see on the page 228 of the reference
> manual, it is osc0 clock behind this gate.
> 
> In the context of network device, I would need to read SIM_SOPT2 to 
> determine clock source for IEEE 1588 timestamp while implementing PTP 
> support - which currently I don't have in my plans, network device can do 
> without it.

OK, I'll leave all of that stuff in your hands. The bindings are looking
good and when the day comes for you to add more depth to your clock
driver then it won't require breaking backwards compatibility with
existing/deployed dtb blobs.

Regards,
Mike

> 
> Thanks,
> Paul
> 
> > 
> > Besides my annoying questions above this binding is starting to shape up
> > very well. Thanks for your patience!
> > 
> > Regards,
> > Mike
> > 
> > > 
> > > On Wed, 29 Jul 2015, Michael Turquette wrote:
> > > 
> > > > Quoting Paul Osmialowski (2015-07-28 13:30:17)
> > > > > Hi Mike,
> > > > > 
> > > > > My trouble is that now I'm dealing with two conradictory opinions on how 
> > > > > this driver should be written. The one you presented in your previous post 
> > > > > assumes that there will be a header file with defines shared between the 
> > > > > clock driver and DTS, also with clock gating details hidden behind some 
> > > > > additional level of indirection, e.g.:
> > > > > 
> > > > > clocks = <&sim SIM_SCGC4_UART1_CLK>;
> > > > > 
> > > > > Note that I've been through this at the very beginning, though the names 
> > > > > I used have been bit different, e.g.:
> > > > > 
> > > > > #define KINETIS_CG_UART1       KINETIS_MKCG(3, 11)     /* SIM_SCGC4[11] */
> > > > > 
> > > > > This was rejected with a comment by Arnd:
> > > > > 
> > > > > Instead of using a triple indirection here, just put the tuples
> > > > > in the DT directly using #clock-cells=<2>, and get rid of both this
> > > > > header file and the dt-bindings/clock/kinetis-mcg.h file.
> > > > 
> > > > Arnd, are you OK with my type of binding description now that I
> > > > explained it with some examples?
> > > > 
> > > > > 
> > > > > So I dropped all of these includes and started to use magic numbers (as 
> > > > > you put it). Now I need to go one way or another or even go the third way: 
> > > > > extend #clock-cells to <3> and address it like: <&sim parent_clock_id 
> > > > > scgc_register_number bit_index_number>.
> > > > 
> > > > Paul,
> > > > 
> > > > >From my understanding the DT folks do not like register-level or
> > > > bit-level details going into DT. It is better to handle the clock
> > > > signals as abstract resources and link a provider and consumer with a
> > > > simple phandle plus an index representing that abstract resource (i.e.
> > > > the clock output signal).
> > > > 
> > > > > 
> > > > > Reading your previous post I'm starting to feel that it would bring me 
> > > > > closer to final acceptance if I stick to what you proposed in that post 
> > > > > (I'm really grateful to you for writting so huge chunk of DTS for me!), so 
> > > > > I'll probably adopt that.
> > > > > 
> > > > > You're right about my "get things up and running" attitude - currently I 
> > > > > want to develop things extensively (cover as much subsystems as 
> > > > > possible) and then at some stage switch to intensive approach. This board 
> > > > > is a somewhat huge monster (for a Cortex-M4 SoC) and there will be a lot 
> > > > > of coding opportunity in this field in the future.
> > > > 
> > > > I'm happy to take clock drivers and add my Reviewed-by to .dts files
> > > > that make use of fixed-rate and fixed-factor clocks as an interim
> > > > solution.  Of course it will be best to get The Real Thing merged
> > > > upstream asap, but this is something I've done before to help get new
> > > > platform upstream before and I'm fine to do it again.
> > > > 
> > > > With that said, Devicetree bindings are allegedly a stable ABI that
> > > > cannot be broken. So let's make sure that any Kinetis clock binding
> > > > description is in good shape before merging it. The rest can follow on
> > > > later if it needs to.
> > > > 
> > > > Regards,
> > > > Mike
> > > > 
> > > > > 
> > > > > Thanks,
> > > > > Paul
> > > > > 
> > > > > On Tue, 28 Jul 2015, Michael Turquette wrote:
> > > > > 
> > > > > > Quoting Paul Osmialowski (2015-07-26 13:24:08)
> > > > > > > Hi Mike,
> > > > > > > 
> > > > > > > Thank you for spending time on this and pointing me into the right 
> > > > > > > direction. I'm wondering about going even further with it. Assuming that I 
> > > > > > 
> > > > > > Hi Paul,
> > > > > > 
> > > > > > No problem! And thanks for the quick turnaround on your patches so far.
> > > > > > 
> > > > > > > know everything about my board, I can skip run-time discovery phase (note 
> > > > > > > that the original driver was designed for other Kinetis-based boards too) 
> > > > > > > and move everything into DTS, somewhat like this:
> > > > > > > 
> > > > > > > / {
> > > > > > >         osc0: clock {
> > > > > > >                 compatible = "fixed-clock";
> > > > > > >                 #clock-cells = <0>;
> > > > > > >                 clock-frequency = <50000000>;
> > > > > > >         };
> > > > > > > 
> > > > > > >         osc1: clock {
> > > > > > >                 compatible = "fixed-clock";
> > > > > > >                 #clock-cells = <0>;
> > > > > > >                 clock-frequency = <12000000>;
> > > > > > >         };
> > > > > > > 
> > > > > > >         rtc: clock {
> > > > > > >                 compatible = "fixed-clock";
> > > > > > >                 #clock-cells = <0>;
> > > > > > >                 clock-frequency = <32768>;
> > > > > > >         };
> > > > > > > 
> > > > > > >         mcgout: clock {
> > > > > > >                 compatible = "fixed-factor-clock";
> > > > > > >                 #clock-cells = <0>;
> > > > > > >                 clocks = <&osc0>;
> > > > > > >                 clock-mult = <12>;
> > > > > > >                 clock-div = <5>;
> > > > > > >         };
> > > > > > 
> > > > > > I think this is a step backwards.
> > > > > > 
> > > > > > Did you look at the qcom clock binding and read the email where I
> > > > > > detailed how that binding works?
> > > > > > 
> > > > > > The point of that type of binding is to not shove per-clock data into
> > > > > > DT, but instead to declare every clock controller IP block (e.g. the
> > > > > > device) as well as every board-level clock (e.g. as osc that feeds into
> > > > > > your mcu). Once these "clock providers" are enumerated in DT, then we
> > > > > > create linkage between the clock providers and the clock consumers by
> > > > > > using phandles + an index. Linux device drivers tap into this by using
> > > > > > clk_get() and using the "clock-names" property from DT.
> > > > > > 
> > > > > > Put another way: we mostly use DT to model "devices". That is open to
> > > > > > interpretation for but for clock-related stuff we typically interpret
> > > > > > the clock controller as the device, not the individual clock outputs
> > > > > > coming out of the controller.
> > > > > > 
> > > > > > Note that a clock controller IP block may be both a provider and a
> > > > > > consumer.  I/O controllers are a very common type of consumer (e.g. USB
> > > > > > host controller, MMC controller, GPU, etc).
> > > > > > 
> > > > > > Additionally, from my reading of the reference manual, mcgout is defined
> > > > > > as:
> > > > > > 
> > > > > > """
> > > > > > MCG output of either IRC, MCGFLLCLK MCGPLL0CLK,
> > > > > > MCGPLL1CLK, or MCG's external reference clock that
> > > > > > sources the core, system, bus, FlexBus, and flash clock. It is
> > > > > > also an option for the debug trace clock.
> > > > > > """
> > > > > > 
> > > > > > So why is it listed here as a fixed-factor clock? Is it not a
> > > > > > multiplexer? Also, why is it listed here at all? Please take another
> > > > > > look at the qcom binding example I linked to in my previous mail.
> > > > > > 
> > > > > > > 
> > > > > > >         core: clock {
> > > > > > >                 compatible = "fixed-factor-clock";
> > > > > > >                 #clock-cells = <0>;
> > > > > > >                 clocks = <&mcgout>;
> > > > > > >                 clock-mult = <1>;
> > > > > > >                 clock-div = <1>;
> > > > > > >         };
> > > > > > > 
> > > > > > >         bus: clock {
> > > > > > >                 compatible = "fixed-factor-clock";
> > > > > > >                 #clock-cells = <0>;
> > > > > > >                 clocks = <&mcgout>;
> > > > > > >                 clock-mult = <1>;
> > > > > > >                 clock-div = <2>;
> > > > > > 
> > > > > > These are actually not fixed dividers but programmable dividers. You can
> > > > > > probably use drivers/clk/clk-divider.c for these. I'm fine with using
> > > > > > fixed-dividers for the initial merge just to get things up and running
> > > > > > if that is your strategy, but you'll need to revisit them later on when
> > > > > > you need more flexible support for other boards.
> > > > > > 
> > > > > > Again, I'm not sure why these clocks are enumerated in DT. Why not just
> > > > > > enumerate your mcg clock controller and your sim clock controller? If
> > > > > > you want to be a perfectionist then it appears that there is an osc
> > > > > > clock controller upstream from the mcg controller as well ;-)
> > > > > > 
> > > > > > It occurs to me that maybe you are trying to use fixed-factor clocks so
> > > > > > that you can program a sane default rate? We use the
> > > > > > assigned-clock-rates property for that. Note that this value is a
> > > > > > property of some device which *consumes* the clock, not the clock
> > > > > > controller or the clock output itself.
> > > > > > 
> > > > > > >         };
> > > > > > > 
> > > > > > >         soc {
> > > > > > >                 cmu at 0x40047000 {
> > > > > > >                         compatible = "fsl,kinetis-gate-clock";
> > > > > > >                         reg = <0x40047000 0x1100>;
> > > > > > > 
> > > > > > >                         mcg_core_gate: clock-gate {
> > > > > > >                                 clocks = <&core>;
> > > > > > >                                 #clock-cells = <2>;
> > > > > > >                         };
> > > > > > > 
> > > > > > >                         mcg_bus_gate: clock-gate {
> > > > > > >                                 clocks = <&bus>;
> > > > > > >                                 #clock-cells = <2>;
> > > > > > >                         };
> > > > > > > 
> > > > > > >                         osc0_erclk_gate: clock-gate {
> > > > > > >                                 clocks = <&osc0>;
> > > > > > >                                 #clock-cells = <2>;
> > > > > > >                         };
> > > > > > >                 };
> > > > > > > 
> > > > > > >                 uart0: serial at 4006a000 {
> > > > > > >                         compatible = "fsl,kinetis-lpuart";
> > > > > > >                         reg = <0x4006a000 0x1000>;
> > > > > > >                         interrupts = <45>, <46>;
> > > > > > >                         interrupt-names = "uart-stat", "uart-err";
> > > > > > >                         clocks = <&mcg_core_gate 3 10>;
> > > > > > 
> > > > > > Magic numbers are not good. dtc has been able to use preprocessor macros
> > > > > > for a while now which means we can use constants instead of magic
> > > > > > numbers. Please look at the shared header in the qcom binding for an
> > > > > > example.
> > > > > > 
> > > > > > >                         clock-names = "ipg";
> > > > > > >                         dmas = <&edma 0 2>;
> > > > > > >                         dma-names = "rx";
> > > > > > >                         status = "disabled";
> > > > > > >                 };
> > > > > > >         };
> > > > > > > };
> > > > > > > 
> > > > > > > As you can see, mcg part is not required anymore.
> > > > > > 
> > > > > > I think the mcg should be required. The mcg is a real IP block on your
> > > > > > SoC, according to my reading of your technical reference manual. Just
> > > > > > because you can model a few of its output clocks in dts does not mean
> > > > > > that you should.
> > > > > > 
> > > > > > I did a quick grep and didn't find "cmu" anywhere in the reference
> > > > > > manual.
> > > > > > 
> > > > > > > 
> > > > > > > I guess that the approach above would require split into soc-specific and 
> > > > > > > board-specific part (as I said, dividers arrangement is something board 
> > > > > > > specific), but I wonder what you thing about this proposal.
> > > > > > 
> > > > > > Splitting is good. Chip-specific stuff can go into the chip-specific
> > > > > > dtsi file. The board-level (osc) stuff can go into the individual board
> > > > > > files. The ultimate goal is to make it trivial to add new boards.
> > > > > > 
> > > > > > Regards,
> > > > > > Mike
> > > > > > 
> > > > > > > 
> > > > > > > Thanks,
> > > > > > > Paul
> > > > > > > 
> > > > > > > On Thu, 23 Jul 2015, Michael Turquette wrote:
> > > > > > > 
> > > > > > > > Quoting Paul Osmialowski (2015-07-04 14:50:03)
> > > > > > > > > Hi Arnd,
> > > > > > > > > 
> > > > > > > > > I'm attaching excerpt from Kinetis reference manual that may make 
> > > > > > > > > situation clearer.
> > > > > > > > 
> > > > > > > > Hi Paul,
> > > > > > > > 
> > > > > > > > Can you please post the patch in the body of the email instead of an
> > > > > > > > attachment? It makes it easier to review. Another small nitpick is that
> > > > > > > > the $SUBJECT for this patch might be better off as something like:
> > > > > > > > 
> > > > > > > > clk: mcg and sim clock drivers for twr-k70f120m Kinetis SoC
> > > > > > > > 
> > > > > > > > At least it helps me find the patch I care about when skimming the
> > > > > > > > series ;-)
> > > > > > > > 
> > > > > > > > > 
> > > > > > > > > These MCG and SIM registers are used only to determine configuration 
> > > > > > > > > (clock fixed rates and clock signal origins) at run time.
> > > > > > > > > 
> > > > > > > > > Namely, the real MCGOUTCLK source (in the middle) which is the parent for 
> > > > > > > > > core clock (CCLK) and peripheral clock (PCLK) is determined at run time by 
> > > > > > > > > reading MCG registers, let me quote commit message from Emcraft git repo:
> > > > > > > > > 
> > > > > > > > >       * Determine in run-time what oscillator module (OSC0 or OSC1) is used
> > > > > > > > >      as clock source for the main PLL.
> > > > > > > > 
> > > > > > > > According to [0] there are three options: a 32k RTC osc clock and osc0
> > > > > > > > both feed into a mux. You should model this 32k clock with the
> > > > > > > > fixed-rate binding.
> > > > > > > > 
> > > > > > > > >       * When OSC1 is selected, assume its frequency to be 12 MHz on all
> > > > > > > > >      boards (there is a 12 MHz oscillator on XTAL1/EXTAL1 on K70-SOM and
> > > > > > > > >      TWR-K70F120M boards).
> > > > > > > > > 
> > > > > > > > > In my .dts I'm trying to possibly follow real clock hierarchy, but to go 
> > > > > > > > > anywhere behind MCGOUTCLK would require ability to rewrite .dtb e.g. by 
> > > > > > > > > U-boot. But that's too demanding for any potential users of this BSP. So 
> > > > > > > > > let's asume that MCGOUTCLK is the root clock and a parent for CCLK and 
> > > > > > > > > PCLK.
> > > > > > > > 
> > > > > > > > I'm confused. The point of device tree is to solve problems like this;
> > > > > > > > i.e. board-specific differences such as different oscillator
> > > > > > > > frequencies.
> > > > > > > > 
> > > > > > > > OSC0 and OSC1 should each be a fixed-rate clock in your board-specific
> > > > > > > > TWR-K70F120M DTS (not a chip-specific file). They do not belong in the
> > > > > > > > cmu node, and they should use the "fixed-clock" binding. The 32k RTC osc
> > > > > > > > can probably go in your chip-specific .dtsi as a fixed-rate clock since
> > > > > > > > it appears to mandated in the reference manual[0].
> > > > > > > > 
> > > > > > > > These three fixed-rate clocks are your root clock nodes. Customers only
> > > > > > > > need to worry about this if they spin a board, and then they will need
> > > > > > > > to populate the frequencies of OSC0 and OSC1 in their board-specific
> > > > > > > > .dts.
> > > > > > > > 
> > > > > > > > Please break clk-kinetis.c into two files:
> > > > > > > > drivers/clk/kinetis/clk-mcg.c
> > > > > > > > drivers/clk/kinetis/clk-sim.c
> > > > > > > > 
> > > > > > > > Below is what your binding/dts should look like:
> > > > > > > > 
> > > > > > > > {
> > > > > > > >       osc0: clock {
> > > > > > > >               compatible = "fixed-clock";
> > > > > > > >               #clock-cells = <0>;
> > > > > > > >               clock-frequency = <50000000>;
> > > > > > > >       };
> > > > > > > > 
> > > > > > > >       osc1: clock {
> > > > > > > >               compatible = "fixed-clock";
> > > > > > > >               #clock-cells = <0>;
> > > > > > > >               clock-frequency = <12000000>;
> > > > > > > >       };
> > > > > > > > 
> > > > > > > >       rtc: clock {
> > > > > > > >               compatible = "fixed-clock";
> > > > > > > >               #clock-cells = <0>;
> > > > > > > >               clock-frequency = <32768>;
> > > > > > > >       };
> > > > > > > > 
> > > > > > > >       soc: soc {
> > > > > > > >               mcg: clock-controller at 40064000 {
> > > > > > > >                       compatible = "fsl,kinetis-mcg";
> > > > > > > >                       clock-cells = <1>;
> > > > > > > >                       reg = <0x40064000 0x14>;
> > > > > > > >                       clocks = <&osc0>, <&osc1>, <&rtc>;
> > > > > > > >                       clock-names = "osc0", "osc1", "rtc";
> > > > > > > >               };
> > > > > > > > 
> > > > > > > >               sim: clock-controller at 40047000 {
> > > > > > > >                       compatible = "fsl,kinetis-sim";
> > > > > > > >                       clock-cells = <1>;
> > > > > > > >                       reg = <0x40047000 0x1100>;
> > > > > > > >                       clocks = <&mcg MCG_MCGOUTCLK_DIV1>, <&mcg MCG_MCGOUTCLK_DIV2>, <&mcg MCG_MCGOUTCLK_DIV3> <&mcg MCG_MCGOUTCLK_DIV4>;
> > > > > > > >                       clock-names = "core", "bus", "flexbus", "flash";
> > > > > > > >               };
> > > > > > > >       };
> > > > > > > > 
> > > > > > > >       uart0: serial at 4006a000 {
> > > > > > > >               compatible = "fsl,kinetis-lpuart";
> > > > > > > >               reg = <0x4006a000 0x1000>;
> > > > > > > >               clocks = <&sim SIM_SCGC4_UART1_CLK>;
> > > > > > > >               clock-names = "gate";
> > > > > > > >       };
> > > > > > > > 
> > > > > > > > I removed the interrupts and dma stuff from the uart0 node for clarity.
> > > > > > > > The above is the only style of binding that I have been accepting for
> > > > > > > > some time; first declare the clock controller and establish its register
> > > > > > > > space, and then consumers can consume clocks by providing the phandle to
> > > > > > > > the controller plus an offset corresponding to a unique clock. The
> > > > > > > > clock-names property makes it really easy to use with the clkdev stuff
> > > > > > > > (e.g. clk_get()).
> > > > > > > > 
> > > > > > > > I've covered this before on the mailing list so here is a link
> > > > > > > > describing how the qcom bindings do it in detail:
> > > > > > > > 
> > > > > > > > http://lkml.kernel.org/r/<20150416192014.19585.9663 at quantum>
> > > > > > > > 
> > > > > > > > Technically you could encode the same bits as sub-nodes of the mcg and
> > > > > > > > sim nodes, but the shared header is how the magic happens with the
> > > > > > > > driver so it's best to keep the clock controller binding small and
> > > > > > > > light.
> > > > > > > > 
> > > > > > > > I think this means you can also get rid of kinetis_of_clk_get_name and
> > > > > > > > kinetis_clk_gate_get but my brain is tired so I'll leave that as an
> > > > > > > > exercise to the reader.
> > > > > > > > 
> > > > > > > > [0] http://cache.freescale.com/files/microcontrollers/doc/ref_manual/K70P256M150SF3RM.pdf
> > > > > > > > 
> > > > > > > > Regards,
> > > > > > > > Mike
> > > > > > > > 
> > > > > > > > > 
> > > > > > > > > In my most recent version I added OSC0ERCLK explicitly as one more root 
> > > > > > > > > clock, since it is also used directly (through CG reg. 1 bit 0) by 
> > > > > > > > > Freescale fec network device whose in-tree driver I'm trying to make 
> > > > > > > > > usable for Kinetis.
> > > > > > > > > 
> > > > > > > > > On Sat, 4 Jul 2015, Arnd Bergmann wrote:
> > > > > > > > > 
> > > > > > > > > > On Friday 03 July 2015 00:08:27 Thomas Gleixner wrote:
> > > > > > > > > >> On Thu, 2 Jul 2015, Paul Osmialowski wrote:
> > > > > > > > > >>> On Thu, 2 Jul 2015, Arnd Bergmann wrote:
> > > > > > > > > >>>
> > > > > > > > > >>>> I wonder if you could move out the fixed rate clocks into their own
> > > > > > > > > >>>> nodes. Are they actually controlled by the same block? If they are
> > > > > > > > > >>>> just fixed, you can use the normal binding for fixed rate clocks
> > > > > > > > > >>>> and only describe the clocks that are related to the driver.
> > > > > > > > > >>>
> > > > > > > > > >>> In my view having these clocks grouped together looks more convincing. After
> > > > > > > > > >>> all, they all share the same I/O regs in order to read configuration.
> > > > > > > > > >>
> > > > > > > > > >> The fact that they share a register is not making them a group. That's
> > > > > > > > > >> just a HW design decision and you need to deal with that by protecting
> > > > > > > > > >> the register access, but not by trying to group them artificially at
> > > > > > > > > >> the functional level.
> > > > > > > > > >
> > > > > > > > > > I'd disagree with that: The clock controller is the device that owns the
> > > > > > > > > > registers and that should be one node in DT, as Paul's first version does.
> > > > > > > > > >
> > > > > > > > > > The part I'm still struggling with is understanding how the fixed-rate
> > > > > > > > > > clocks are controlled through those registers. If they are indeed configured
> > > > > > > > > > through the registers, the name is probably wrong and should be changed
> > > > > > > > > > to whatever kind of non-fixed clock this is.
> > > > > > > > > >
> > > > > > > > > >       Arnd
> > > > > > > > > >
> > > > > > > > > 
> > > > > > > > > _______________________________________________
> > > > > > > > > linux-arm-kernel mailing list
> > > > > > > > > linux-arm-kernel at lists.infradead.org
> > > > > > > > > http://lists.infradead.org/mailman/listinfo/linux-arm-kernel
> > > > > > > > 
> > > > > > > --
> > > > > > > To unsubscribe from this list: send the line "unsubscribe linux-kernel" in
> > > > > > > the body of a message to majordomo at vger.kernel.org
> > > > > > > More majordomo info at  http://vger.kernel.org/majordomo-info.html
> > > > > > > Please read the FAQ at  http://www.tux.org/lkml/
> > > > > > 
> > > > > --
> > > > > To unsubscribe from this list: send the line "unsubscribe linux-kernel" in
> > > > > the body of a message to majordomo at vger.kernel.org
> > > > > More majordomo info at  http://vger.kernel.org/majordomo-info.html
> > > > > Please read the FAQ at  http://www.tux.org/lkml/
> > > > 
> > > --
> > > To unsubscribe from this list: send the line "unsubscribe linux-kernel" in
> > > the body of a message to majordomo at vger.kernel.org
> > > More majordomo info at  http://vger.kernel.org/majordomo-info.html
> > > Please read the FAQ at  http://www.tux.org/lkml/
> > 
> --
> To unsubscribe from this list: send the line "unsubscribe linux-kernel" in
> the body of a message to majordomo at vger.kernel.org
> More majordomo info at  http://vger.kernel.org/majordomo-info.html
> Please read the FAQ at  http://www.tux.org/lkml/


From moritz.fischer at ettus.com  Wed Aug  5 12:43:15 2015
From: moritz.fischer at ettus.com (Moritz Fischer)
Date: Wed, 5 Aug 2015 12:43:15 -0700
Subject: [RFCv3 1/4] docs: dts: Added documentation for Xilinx Zynq Reset
 Controller bindings.
In-Reply-To: <1438701017.3793.45.camel@pengutronix.de>
References: <1438305237-18497-1-git-send-email-moritz.fischer@ettus.com>
 <1438305237-18497-2-git-send-email-moritz.fischer@ettus.com>
 <1438675772.3793.18.camel@pengutronix.de>
 <CAAtXAHeauiD5smAqMbheJWuv4BT-2YqJWOSBjYPq900icpT1Rg@mail.gmail.com>
 <1438701017.3793.45.camel@pengutronix.de>
Message-ID: <CAAtXAHfJF-5PAgCc4ZC71omc_ye6L4qa2ks2E1BdoSXxDzZu1A@mail.gmail.com>

Michal,

On Tue, Aug 4, 2015 at 8:10 AM, Philipp Zabel <p.zabel at pengutronix.de> wrote:
> Hi Moritz,
>
> Am Dienstag, den 04.08.2015, 08:05 -0700 schrieb Moritz Fischer:
>> Hi Philip,
>>
>> On Tue, Aug 4, 2015 at 1:09 AM, Philipp Zabel <p.zabel at pengutronix.de> wrote:
>> > Hi Moritz,
>> >
>> > Am Donnerstag, den 30.07.2015, 18:13 -0700 schrieb Moritz Fischer:
> [...]
>> >> +Required properties:
>> >> +- compatible: "xlnx,zynq-reset"
>> >> +- reg: SLCR offset and size taken via syscon <0x200 0x48>
>> >> +- syscon: <&slcr>
>> >> +  This should be a phandle to the Zynq's SLCR register.
>> >
>> >                                                  ^ register singular?
>> Do you want me to resend the entire set, or are you cool with just git
>> amending the 's' for registers?
>
> Amended and applied, thanks.

Will you take 4/4 and 2/4 via your tree?
>
> regards
> Philipp
>

Thanks,

Moritz


From stuart.yoder at freescale.com  Wed Aug  5 12:53:59 2015
From: stuart.yoder at freescale.com (Stuart Yoder)
Date: Wed, 5 Aug 2015 19:53:59 +0000
Subject: [PATCH 2/3] Docs: dt: Add PCI MSI map bindings
In-Reply-To: <CALRxmdA32xiSX7DDKAJPLR8=bh_9j-6MN124u4KjYGRT8bAKNg@mail.gmail.com>
References: <1437670365-20704-1-git-send-email-mark.rutland@arm.com>
 <1437670365-20704-3-git-send-email-mark.rutland@arm.com>
 <CALRxmdA32xiSX7DDKAJPLR8=bh_9j-6MN124u4KjYGRT8bAKNg@mail.gmail.com>
Message-ID: <CY1PR0301MB07486794749E499F71BDFCD287750@CY1PR0301MB0748.namprd03.prod.outlook.com>

> From: Mark Rutland <mark.rutland at arm.com>
> Date: Thu, Jul 23, 2015 at 11:52 AM

[cut]

> diff --git a/Documentation/devicetree/bindings/pci/pci-msi.txt
> b/Documentation/devicetree/bindings/pci/pci-msi.txt
> new file mode 100644
> index 0000000..9b3cc81
> --- /dev/null
> +++ b/Documentation/devicetree/bindings/pci/pci-msi.txt
> @@ -0,0 +1,220 @@
> +This document describes the generic device tree binding for describing the
> +relationship between PCI devices and MSI controllers.
> +
> +Each PCI device under a root complex is uniquely identified by its Requester ID
> +(AKA RID). A Requester ID is a triplet of a Bus number, Device number, and
> +Function number.
> +
> +For the purpose of this document, when treated as a numeric value, a RID is
> +formatted such that:
> +
> +* Bits [15:8] are the Bus number.
> +* Bits [7:3] are the Device number.
> +* Bits [2:0] are the Function number.
> +* Any other bits required for padding must be zero.
> +
> +MSIs may be distinguished in part through the use of sideband data accompanying
> +writes. In the case of PCI devices, this sideband data may be derived from the
> +Requester ID. A mechanism is required to associate a device with both the MSI
> +controllers it can address, and the sideband data that will be associated with
> +its writes to those controllers.
> +
> +For generic MSI bindings, see
> +Documentation/devicetree/bindings/interrupt-controller/msi.txt.
> +
> +
> +PCI root complex
> +================
> +
> +Optional properties
> +-------------------
> +
> +- msi-map: Maps a Requester ID to an MSI controller and associated
> +  msi-specifier data. The property is an arbitrary number of tuples of
> +  (rid-base,msi-controller,msi-base,length), where:
> +
> +  * rid-base is a single cell describing the first RID matched by the entry.
> +
> +  * msi-controller is a single phandle to an MSI controller
> +
> +  * msi-base is an msi-specifier describing the msi-specifier produced for the
> +    first RID matched by the entry.
> +
> +  * length is a single cell describing how many consecutive RIDs are matched
> +    following the rid-base.
> +
> +  Any RID r in the interval [rid-base, rid-base + length) is associated with
> +  the listed msi-controller, with the msi-specifier (r - rid-base + msi-base).
> +
> +- msi-map-mask: A mask to be applied to each Requester ID prior to being mapped
> +  to an msi-specifier per the msi-map property.

Can we extend the msi-map-mask definition to say:  "A mask value of 0x0 is valid
and indicates that no RIDs are _currently_ mapped to any msi-specifier."

We have an SoC with a programmable hardware table in the PCI controller that maps
requester ID to stream ID, so the overall msi-map (and iommu-map) definition fit
into that scheme.  But, we would like to be able make the RID->stream-ID mapping
decision _lazily_, in Linux, based on actual usage of PCI devices.

      pcie at 3600000 {
              compatible = "fsl,ls2085a-pcie", "snps,dw-pcie";
              device_type = "pci";
              ...
              msi-map = <0x0 &msi_a 0x7 4>,
              msi-map-mask = <0x0>
      };

That specifies the there are 4 stream IDs starting at stream ID 0x7, 
but the requester ID's are not mapped (because the mask is 0x0).
This tells the PCI controller driver that there are 4 msi-specifiers
(e.g. stream IDs) available and what they are.

(same definition would apply to the iommu-map-mask)

Thanks,
Stuart

From khilman at kernel.org  Wed Aug  5 13:27:53 2015
From: khilman at kernel.org (Kevin Hilman)
Date: Wed, 5 Aug 2015 13:27:53 -0700
Subject: next-20150729 build: 2 failures 49 warnings (next-20150729)
In-Reply-To: <17C303E7-B358-486E-9E0F-83CF58F28481@gmail.com>
References: <E1ZKPJk-0007VU-Fg@optimist> <20150729124410.GE20130@sirena.org.uk>
 <20150804173849.GD20873@sirena.org.uk>
 <17C303E7-B358-486E-9E0F-83CF58F28481@gmail.com>
Message-ID: <CAMAWPa8n2fdAQFU+D6tm1e1Bv=uNKUimpB1OQjym6Nea-yhwWg@mail.gmail.com>

On Tue, Aug 4, 2015 at 12:12 PM, Matthias Brugger
<matthias.bgg at gmail.com> wrote:
>
>
> On August 4, 2015 7:38:49 PM CEST, Mark Brown <broonie at kernel.org> wrote:
>>On Wed, Jul 29, 2015 at 01:44:10PM +0100, Mark Brown wrote:
>>> On Wed, Jul 29, 2015 at 12:14:36PM +0100, Build bot for Mark Brown
>>wrote:
>>
>>> Today's linux-next fails to build an arm64 allmodconfig due to:
>>
>>> >    arm64-allmodconfig
>>> > ../include/linux/platform_device.h:245:1: error: type defaults to
>>'int' in declaration of 'module_init' [-Werror=implicit-int]
>>> > ../include/linux/platform_device.h:250:1: error: type defaults to
>>'int' in declaration of 'module_exit' [-Werror=implicit-int]
>>
>>> caused by c84e358718a66f76 (soc: Mediatek: Add SCPSYS power domain
>>> driver) which does not include module.h.  Arguably platform_device.h
>>> should do that, though it's only an issue if the macro is used so...
>>
>>This is still breaking the build and the fix should be trivial - is
>>there any ETA for a fix getting into -next?
>
> I send a fix to arm at kernel.org but no reply yet. (sorry I'm not in front of a computer so I can't send you the link right now).
>
> I will send a pull request tomorrow, let's see if that helps...

Fix was applied today.

Kevin


From gregkh at linuxfoundation.org  Wed Aug  5 13:45:31 2015
From: gregkh at linuxfoundation.org (Greg Kroah-Hartman)
Date: Wed, 5 Aug 2015 13:45:31 -0700
Subject: [PATCH 22/23] misc: atmel_tclib: get and use slow clock
In-Reply-To: <1438335599-3301-23-git-send-email-alexandre.belloni@free-electrons.com>
References: <1438335599-3301-1-git-send-email-alexandre.belloni@free-electrons.com>
 <1438335599-3301-23-git-send-email-alexandre.belloni@free-electrons.com>
Message-ID: <20150805204531.GA9784@kroah.com>

On Fri, Jul 31, 2015 at 11:39:58AM +0200, Alexandre Belloni wrote:
> From: Boris Brezillon <boris.brezillon at free-electrons.com>
> 
> Commit dca1a4b5ff6e ("clk: at91: keep slow clk enabled to prevent system
> hang") added a workaround for the slow clock as it is not properly handled
> by its users.
> 
> Get and use the slow clock as it is necessary for the timer counters.
> 
> Signed-off-by: Boris Brezillon <boris.brezillon at free-electrons.com>
> Signed-off-by: Alexandre Belloni <alexandre.belloni at free-electrons.com>
> ---
> Cc: Daniel Lezcano <daniel.lezcano at linaro.org>
> Cc: Thomas Gleixner <tglx at linutronix.de>
> Cc: Arnd Bergmann <arnd at arndb.de>
> Cc: Greg Kroah-Hartman <gregkh at linuxfoundation.org>
> Cc: Thierry Reding <thierry.reding at gmail.com>
> Cc: linux-pwm at vger.kernel.org
>  drivers/clocksource/tcb_clksrc.c |  8 ++++++++
>  drivers/misc/atmel_tclib.c       |  4 ++++
>  drivers/pwm/pwm-atmel-tcb.c      | 23 ++++++++++++++++-------
>  include/linux/atmel_tc.h         |  1 +
>  4 files changed, 29 insertions(+), 7 deletions(-)
> 

Acked-by: Greg Kroah-Hartman <gregkh at linuxfoundation.org>


From Shenwei.Wang at freescale.com  Wed Aug  5 14:11:19 2015
From: Shenwei.Wang at freescale.com (Shenwei Wang)
Date: Wed, 5 Aug 2015 21:11:19 +0000
Subject: [PATCH v3 1/1] misc: sram: add dev_pm_ops to support module power
 gate
In-Reply-To: <1438272681-29338-1-git-send-email-shenwei.wang@freescale.com>
References: <1438272681-29338-1-git-send-email-shenwei.wang@freescale.com>
Message-ID: <CY1PR0301MB0843E511B3A98E7EADDD25D483750@CY1PR0301MB0843.namprd03.prod.outlook.com>

Ping.

Shenwei

> -----Original Message-----
> From: linux-arm-kernel [mailto:linux-arm-kernel-bounces at lists.infradead.org] On
> Behalf Of Shenwei Wang
> Sent: 2015?7?30? 11:11
> To: gregkh at linuxfoundation.org; arnd at arndb.de
> Cc: Huang Yongcai-B20788; linux-arm-kernel at lists.infradead.org
> Subject: [PATCH v3 1/1] misc: sram: add dev_pm_ops to support module power
> gate
> 
> When system goes into low power states like SUSPEND_MEM and HIBERNATION,
> the hardware IP block may be powered off to reduce the power consumption.
> This power down will lost all the data inside the ram. This patch added the
> dev_pm_ops and implemented two callbacks: suspend_noirq and resume_noirq,
> which will save the data in the on-chip-ram right before power down and restore
> it after system resumes.
> 
> A new property string named "can-power-gate" is added to the devicetree
> bindings too.
> 
> Signed-off-by: Shenwei Wang <shenwei.wang at freescale.com>
> Signed-off-by: Anson Huang <b20788 at freescale.com>
> ---
> Change log:
> 
> PATCH v3
> 	Removed the unnecessary clk_enable/clk_disable.
> 
> PATCH v2
> 	Use vmalloc to allocate the SRAM backup memory.
> 	Code clean up.
> 
>  Documentation/devicetree/bindings/misc/sram.txt |  2 ++
>  drivers/misc/sram.c                             | 42
> +++++++++++++++++++++++++
>  2 files changed, 44 insertions(+)
> 
> diff --git a/Documentation/devicetree/bindings/misc/sram.txt
> b/Documentation/devicetree/bindings/misc/sram.txt
> index 36cbe5a..1170086 100644
> --- a/Documentation/devicetree/bindings/misc/sram.txt
> +++ b/Documentation/devicetree/bindings/misc/sram.txt
> @@ -33,6 +33,8 @@ Optional properties in the area nodes:
> 
>  - compatible : standard definition, should contain a vendor specific string
>                 in the form <vendor>,[<device>-]<usage>
> +- can-power-gate: a property to tell the driver that the sram can support
> +		power gate
> 
>  Example:
> 
> diff --git a/drivers/misc/sram.c b/drivers/misc/sram.c index 15c33cc..db9f1fa
> 100644
> --- a/drivers/misc/sram.c
> +++ b/drivers/misc/sram.c
> @@ -30,7 +30,9 @@
> 
>  struct sram_dev {
>  	struct device *dev;
> +	void *power_off_save;
>  	void __iomem *virt_base;
> +	u32 size;
> 
>  	struct gen_pool *pool;
>  	struct clk *clk;
> @@ -156,6 +158,33 @@ static int sram_reserve_regions(struct sram_dev
> *sram, struct resource *res)
>  	return ret;
>  }
> 
> +static int sram_suspend_noirq(struct device *dev) {
> +	struct platform_device *pdev = to_platform_device(dev);
> +	struct sram_dev *sram = platform_get_drvdata(pdev);
> +
> +	if (!sram->power_off_save)
> +		return 0;
> +
> +	/* Save necessary regs */
> +	memcpy(sram->power_off_save, sram->virt_base, sram->size);
> +
> +	return 0;
> +}
> +
> +static int sram_resume_noirq(struct device *dev) {
> +	struct platform_device *pdev = to_platform_device(dev);
> +	struct sram_dev *sram = platform_get_drvdata(pdev);
> +
> +	if (!sram->power_off_save)
> +		return 0;
> +
> +	memcpy(sram->virt_base, sram->power_off_save, sram->size);
> +
> +	return 0;
> +}
> +
>  static int sram_probe(struct platform_device *pdev)  {
>  	struct sram_dev *sram;
> @@ -176,6 +205,7 @@ static int sram_probe(struct platform_device *pdev)
>  	}
> 
>  	size = resource_size(res);
> +	sram->size = size;
> 
>  	if (!devm_request_mem_region(sram->dev, res->start, size, pdev->name)) {
>  		dev_err(sram->dev, "could not request region for resource\n"); @@
> -203,6 +233,9 @@ static int sram_probe(struct platform_device *pdev)
> 
>  	platform_set_drvdata(pdev, sram);
> 
> +	if (of_property_read_bool(pdev->dev.of_node, "can-power-gate"))
> +		sram->power_off_save = vmalloc(size);
> +
>  	dev_dbg(sram->dev, "SRAM pool: %zu KiB @ 0x%p\n",
>  		gen_pool_size(sram->pool) / 1024, sram->virt_base);
> 
> @@ -219,6 +252,9 @@ static int sram_remove(struct platform_device *pdev)
>  	if (sram->clk)
>  		clk_disable_unprepare(sram->clk);
> 
> +	if (sram->power_off_save)
> +		vfree(sram->power_off_save);
> +
>  	return 0;
>  }
> 
> @@ -229,10 +265,16 @@ static const struct of_device_id sram_dt_ids[] = {  };
> #endif
> 
> +static const struct dev_pm_ops sram_pm_ops = {
> +	.suspend_noirq = sram_suspend_noirq,
> +	.resume_noirq = sram_resume_noirq,
> +};
> +
>  static struct platform_driver sram_driver = {
>  	.driver = {
>  		.name = "sram",
>  		.of_match_table = of_match_ptr(sram_dt_ids),
> +		.pm	= &sram_pm_ops,
>  	},
>  	.probe = sram_probe,
>  	.remove = sram_remove,
> --
> 2.5.0.rc2
> 
> 
> 
> _______________________________________________
> linux-arm-kernel mailing list
> linux-arm-kernel at lists.infradead.org
> http://lists.infradead.org/mailman/listinfo/linux-arm-kernel

From linux at arm.linux.org.uk  Wed Aug  5 14:48:54 2015
From: linux at arm.linux.org.uk (Russell King - ARM Linux)
Date: Wed, 5 Aug 2015 22:48:54 +0100
Subject: [PATCH 3/4] arm64: Juno: Add HDLCD support to the Juno boards.
In-Reply-To: <20150805190312.GA31066@e106497-lin.cambridge.arm.com>
References: <1438784892-27888-1-git-send-email-Liviu.Dudau@arm.com>
 <1438784892-27888-4-git-send-email-Liviu.Dudau@arm.com>
 <20150805175303.GB7557@n2100.arm.linux.org.uk>
 <20150805190312.GA31066@e106497-lin.cambridge.arm.com>
Message-ID: <20150805214854.GC7557@n2100.arm.linux.org.uk>

On Wed, Aug 05, 2015 at 08:03:12PM +0100, Liviu Dudau wrote:
> I have to confess that I am not entirely up to speed with the TDA19988
> situation at the moment. Andrew Jackson was dealing with that and
> working with Jean to get that in the upstream, but his contract has
> ended and he has moved to other things.

Umm, I'm the maintainer for TDA998x:

NXP TDA998X DRM DRIVER
M:      Russell King <rmk+kernel at arm.linux.org.uk>
S:      Supported
F:      drivers/gpu/drm/i2c/tda998x_drv.c
F:      include/drm/i2c/tda998x.h

It would be nice if people worked with the actual maintainers of things
rather than random other people...

> > Also, the whole question of representing connectors in a DRM model is
> > yet to be established.  Yes, DT should describe the hardware, but we
> > don't yet know _how_ to describe physical connectors with stuff
> > implemented on top of DRM yet, and we have nothing that makes use of
> > this.
> 
> Please help me understand the current situation: you have added
> support for components that the video drivers can use and the bindings
> for that are described in Documentation/devicetree/bindings/media/video-interfaces.txt.

No.  I added the component helpers, which are entirely firmware agnostic.
The media bindings were created by others, and through development done
by Pengutronix, they were factored out of media into common DT code and
re-used for the IMX DRM driver.  The binding document which describes
that work is not the one you refer to above, but this one:

Documentation/devicetree/bindings/graph.txt

This started them as a basis for DRM drivers on ARM - but it's never been
officially "adopted" as a method to describe DRM drivers - it's only what
some drivers are using.  It ought to be nailed down as a way to ensure
inter-operability between components though, but no one has really made
that decision.

> According to that document my patch should be compliant once I add the
> reg= property. Is that something that cannot be used with tda998x driver
> or is there any other reason why you think the patch is not compliant?

Jean's proposal to add audio support to the TDA998x driver does it via
this change to the binding spec:

+Optional nodes:
+
+  - port: up to three ports.
+       The ports are defined according to [1].
+
+    Video port.
+       There may be only one video port.
+       This one must contain the following property:
+
+       - port-type: must be "rgb"
+
+       and may contain the optional property:
+
+       - reg: 24 bits value which defines how the video controller
+               output is wired to the TDA998x input (video pins)
+               When absent, the default value is <0x230145>.
+
+    Audio ports.
+       There may be one or two audio ports.
+       These ones must contain the following properties:
+
+       - port-type: must be "i2s" or "spdif"
+
+       - reg: 8 bits value which defines how the audio controller
+               output is wired to the TDA998x input (audio pins)
+
+[1] Documentation/devicetree/bindings/graph.txt

(That's not a particularly precise definition, but it's what we have at
the moment.)

> If you are referring to connecting an encoder with a HDMI connector, I
> have tested that and it seems to work, although my situation is simple
> because there are no options in my setup: one HDLCD connects to one
> TDA19988 which connects to one HDMI output.

Right now, the TDA998x will ignore the additional information, but that
won't be the case with Jean's audio work (see the above binding
information.)

-- 
FTTC broadband for 0.8mile line: currently at 10.5Mbps down 400kbps up
according to speedtest.net.


From linux at arm.linux.org.uk  Wed Aug  5 15:26:46 2015
From: linux at arm.linux.org.uk (Russell King - ARM Linux)
Date: Wed, 5 Aug 2015 23:26:46 +0100
Subject: [PATCH v3 3/5] ARM: mediatek: add smp bringup code
In-Reply-To: <1436851111-2369-4-git-send-email-yingjoe.chen@mediatek.com>
References: <1436851111-2369-1-git-send-email-yingjoe.chen@mediatek.com>
 <1436851111-2369-4-git-send-email-yingjoe.chen@mediatek.com>
Message-ID: <20150805222646.GA4699@n2100.arm.linux.org.uk>

On Tue, Jul 14, 2015 at 01:18:29PM +0800, Yingjoe Chen wrote:
> +static void __init __mtk_smp_prepare_cpus(unsigned int max_cpus, int trustzone)
> +{
> +	int i, num;
> +	const struct of_device_id *infos;
> +
> +	if (trustzone) {
> +		num = ARRAY_SIZE(mtk_tz_smp_boot_infos);
> +		infos = mtk_tz_smp_boot_infos;
> +	} else {
> +		num = ARRAY_SIZE(mtk_smp_boot_infos);
> +		infos = mtk_smp_boot_infos;
> +	}
> +
> +	/* Find smp boot info for this SoC */
> +	for (i = 0; i < num; i++) {
> +		if (of_machine_is_compatible(infos[i].compatible)) {
> +			mtk_smp_info = infos[i].data;
> +			break;
> +		}
> +	}
> +
> +	if (!mtk_smp_info) {
> +		pr_err("%s: Device is not supported\n", __func__);
> +		return;
> +	}
> +
> +	if (trustzone) {
> +		if (memblock_reserve(mtk_smp_info->smp_base, MTK_SMP_REG_SIZE)) {

Strong NAK.

This is _FAR_ too late to be calling memblock_reserve().  You won't be
reserving memory as you think you are (it's already handed over to the
kernel's allocators by this stage.)

-- 
FTTC broadband for 0.8mile line: currently at 10.5Mbps down 400kbps up
according to speedtest.net.


From linux at arm.linux.org.uk  Wed Aug  5 15:31:15 2015
From: linux at arm.linux.org.uk (Russell King - ARM Linux)
Date: Wed, 5 Aug 2015 23:31:15 +0100
Subject: [PATCH v3 0/5] Add SMP bringup support for mt65xx socs
In-Reply-To: <4831607.pyCH8elj8i@ubix>
References: <1436851111-2369-1-git-send-email-yingjoe.chen@mediatek.com>
 <4831607.pyCH8elj8i@ubix>
Message-ID: <20150805223115.GD7557@n2100.arm.linux.org.uk>

On Wed, Aug 05, 2015 at 08:44:11PM +0200, Matthias Brugger wrote:
> On Tuesday, July 14, 2015 01:18:26 PM Yingjoe Chen wrote:
> > This series add SMP brinup support for MediaTek SoCs. This is based
> > on v4.2-rc1 and Matthias' next branch (for dts parts).
> > 
> > There are similar but different SMP bringup up methods on MediaTek
> > mt65xx and mt81xx. On MT8135 & MT8127, system boots with a trustzone
> > firmware. Others, like MT6589, doesn't have trustzone, and run kernel
> > directly in secure world.
> > 
> > Patch 1 enable arch timer support.
> > Patch 2,3 add support for cpu enable-method "mediatek,mt6589-smp" and
> > "mediatek,mt81xx-tz-smp", which support Mediatek SMP bringup for non-TZ
> > and TZ platform.
> > Patch 4,5 finally enable SMP bringup for mt8135 and mt8127.
> > 
> > Changes in v3:
> > - The first 2 patches in v2 are merged in v4.2-rc1.
> > - Patch 3~4 in v2 are moved to another series [1]
> > - platsmp.c changes based on Stephen's suggestion
> > - Change cpu enable-method name to "mediatek,mt6589-smp"
> > 
> > Changes in v2:
> > - Fix boot issue for THUMB2 kernel.
> > - Not enable GPT_CLK_EVT when setup to fix GPT spurious interrupt issue
> > - Change platsmp.c according to Matthias' suggestion
> > http://lists.infradead.org/pipermail/linux-mediatek/2015-May/000714.html
> > 
> > v1:
> > http://lists.infradead.org/pipermail/linux-mediatek/2015-May/000528.html
> > 
> > [1]
> > http://lists.infradead.org/pipermail/linux-mediatek/2015-July/001544.html
> > 
> > Matthias Brugger (1):
> >   ARM: mediatek: enable gpt6 on boot up to make arch timer working
> > 
> > Yingjoe Chen (4):
> >   devicetree: bindings: add new SMP enable method Mediatek SoC
> >   ARM: mediatek: add smp bringup code
> >   ARM: dts: mt8135: enable basic SMP bringup for mt8135
> >   ARM: dts: mt8127: enable basic SMP bringup for mt8127
> > 
> >  Documentation/devicetree/bindings/arm/cpus.txt |   2 +
> >  arch/arm/boot/dts/mt8127.dtsi                  |  16 +++
> >  arch/arm/boot/dts/mt8135.dtsi                  |  16 +++
> >  arch/arm/mach-mediatek/Makefile                |   3 +
> >  arch/arm/mach-mediatek/mediatek.c              |  27 +++++
> >  arch/arm/mach-mediatek/platsmp.c               | 144
> > +++++++++++++++++++++++++ 6 files changed, 208 insertions(+)
> >  create mode 100644 arch/arm/mach-mediatek/platsmp.c
> 
> Applied to v4.2-next/soc-2 and v4.2-next/dts-2 

I've just NAK'd one of the patches in this set; I don't tend to even see
mediatek patches normally, as they all head into my junk mailfolder
because mediatek's mail server setup is truely abysmal (it has broken
reverse DNS - the DNS positively says that the mail server is not a
legit owner of the name it claims to be.)

The problem is that this patch series uses memblock_reserve() way after
the memory has been transitioned out of memblock's control, so actually
this has no effect.

I've seen a number of patches doing this.  I'm not sure what's soo friggin
hard for people to understand: memblock is about the EARLY stages of
getting the system up and running.  Once the memory has been handed
over to the kernel's memory management, memblock MUST NOT BE USED to
reserve memory.

There is one place, and one place only in the ARM kernel where
memblock_reserve() is possible, and that's in the ->reserve machine
callback.  NOWHERE ELSE is permissible.

-- 
FTTC broadband for 0.8mile line: currently at 10.5Mbps down 400kbps up
according to speedtest.net.


From ariel at vanguardiasur.com.ar  Wed Aug  5 16:03:16 2015
From: ariel at vanguardiasur.com.ar (Ariel D'Alessandro)
Date: Wed, 05 Aug 2015 20:03:16 -0300
Subject: [PATCH 1/2] pwm: NXP LPC18xx PWM/SCT driver
In-Reply-To: <CAAEAJfDaA-NC2qTpGBxGZrs2dsQbDkrAENXHO9txvG+k5qsmKA@mail.gmail.com>
References: <1437972345-16444-1-git-send-email-ariel@vanguardiasur.com.ar>	<1437972345-16444-2-git-send-email-ariel@vanguardiasur.com.ar>
 <CAAEAJfDaA-NC2qTpGBxGZrs2dsQbDkrAENXHO9txvG+k5qsmKA@mail.gmail.com>
Message-ID: <55C29634.8030300@vanguardiasur.com.ar>



El 28/07/15 a las 16:48, Ezequiel Garcia escibi?:
> Ariel,
> 
> On 27 July 2015 at 01:45, Ariel D'Alessandro <ariel at vanguardiasur.com.ar> wrote:
>> This commit adds support for NXP LPC18xx PWM/SCT.
>>
>> NXP LPC SoCs family, which includes LPC18xx/LPC43xx, provides a State
>> Configurable Timer (SCT) which can be configured as a Pulse Width Modulator.
>> Other SoCs in that family may share the same hardware.
>>
>> The PWM supports a total of 16 channels, but only 15 can be simultaneously
>> requested. There's only one period, global to all the channels, thus PWM driver
>> will refuse setting different values to it.
>>
>> Signed-off-by: Ariel D'Alessandro <ariel at vanguardiasur.com.ar>
>> ---
>>  drivers/pwm/Kconfig       |  12 ++
>>  drivers/pwm/Makefile      |   1 +
>>  drivers/pwm/pwm-lpc18xx.c | 459 ++++++++++++++++++++++++++++++++++++++++++++++
>>  3 files changed, 472 insertions(+)
>>  create mode 100644 drivers/pwm/pwm-lpc18xx.c
>>
>> diff --git a/drivers/pwm/Kconfig b/drivers/pwm/Kconfig
>> index b1541f4..2c7635c 100644
>> --- a/drivers/pwm/Kconfig
>> +++ b/drivers/pwm/Kconfig
>> @@ -173,6 +173,18 @@ config PWM_LP3943
>>           To compile this driver as a module, choose M here: the module
>>           will be called pwm-lp3943.
>>
>> +config PWM_LPC18XX
>> +       tristate "LPC18xx/43xx PWM support"
>> +       depends on ARCH_LPC18XX
>> +       help
>> +         Generic PWM framework driver for NXP LPC18xx PWM/SCT which
>> +         supports 16 channels.
>> +         A maximum of 15 channels can be requested simultaneously and
>> +         must have the same period.
>> +
>> +         To compile this driver as a module, choose M here: the module
>> +         will be called pwm-lpc18xx.
>> +
>>  config PWM_LPC32XX
>>         tristate "LPC32XX PWM support"
>>         depends on ARCH_LPC32XX
>> diff --git a/drivers/pwm/Makefile b/drivers/pwm/Makefile
>> index ec50eb5..986b286 100644
>> --- a/drivers/pwm/Makefile
>> +++ b/drivers/pwm/Makefile
>> @@ -14,6 +14,7 @@ obj-$(CONFIG_PWM_IMG)         += pwm-img.o
>>  obj-$(CONFIG_PWM_IMX)          += pwm-imx.o
>>  obj-$(CONFIG_PWM_JZ4740)       += pwm-jz4740.o
>>  obj-$(CONFIG_PWM_LP3943)       += pwm-lp3943.o
>> +obj-$(CONFIG_PWM_LPC18XX)      += pwm-lpc18xx.o
>>  obj-$(CONFIG_PWM_LPC32XX)      += pwm-lpc32xx.o
>>  obj-$(CONFIG_PWM_LPSS)         += pwm-lpss.o
>>  obj-$(CONFIG_PWM_LPSS_PCI)     += pwm-lpss-pci.o
>> diff --git a/drivers/pwm/pwm-lpc18xx.c b/drivers/pwm/pwm-lpc18xx.c
>> new file mode 100644
>> index 0000000..77b5e74
>> --- /dev/null
>> +++ b/drivers/pwm/pwm-lpc18xx.c
>> @@ -0,0 +1,459 @@
>> +/*
>> + * NXP LPC18xx Pulse Width Modulator driver
>> + *
>> + * Copyright (c) 2015 Ariel D'Alessandro <ariel at vanguardiasur.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.
>> + *
>> + * Notes
>> + * =====
>> + * NXP LPC18xx provides a State Configurable Timer (SCT) which can be configured
>> + * as a Pulse Width Modulator.
>> + *
>> + * SCT supports 16 outputs, 16 events and 16 registers. Each event will be
>> + * triggered when its related register matches the SCT counter value, and it
>> + * will set or clear a selected output.
>> + *
>> + * One of the events is preselected to generate the period, thus the maximum
>> + * number of simultaneous channels is limited to 15. Notice that period is
>> + * global to all the channels, thus PWM driver will refuse setting different
>> + * values to it.
>> + */
>> +
>> +#include <linux/clk.h>
>> +#include <linux/err.h>
>> +#include <linux/io.h>
>> +#include <linux/module.h>
>> +#include <linux/platform_device.h>
>> +#include <linux/pwm.h>
>> +
>> +/* LPC18xx SCT registers */
>> +#define LPC18XX_PWM_CONFIG             0x000
>> +#define LPC18XX_PWM_CONFIG_UNIFY       BIT(0)
>> +#define LPC18XX_PWM_CONFIG_NORELOAD    BIT(7)
>> +
>> +#define LPC18XX_PWM_CTRL               0x004
>> +#define LPC18XX_PWM_CTRL_HALT          BIT(2)
>> +#define LPC18XX_PWM_BIDIR              BIT(4)
>> +#define LPC18XX_PWM_PRE_SHIFT          5
>> +#define LPC18XX_PWM_PRE_MASK           (0xff << LPC18XX_PWM_PRE_SHIFT)
>> +#define LPC18XX_PWM_PRE(x)             (x << LPC18XX_PWM_PRE_SHIFT)
>> +
>> +#define LPC18XX_PWM_LIMIT              0x008
>> +
>> +#define LPC18XX_PWM_RES_BASE           0x058
>> +#define LPC18XX_PWM_RES_SHIFT(_ch)     (_ch * 2)
>> +#define LPC18XX_PWM_RES(_ch, _action)  (_action << LPC18XX_PWM_RES_SHIFT(_ch))
>> +#define LPC18XX_PWM_RES_MASK(_ch)      (0x3 << LPC18XX_PWM_RES_SHIFT(_ch))
>> +
>> +#define LPC18XX_PWM_MATCH_BASE         0x100
>> +#define LPC18XX_PWM_MATCH(_ch)         (LPC18XX_PWM_MATCH_BASE + _ch * 4)
>> +
>> +#define LPC18XX_PWM_MATCHREL_BASE      0x200
>> +#define LPC18XX_PWM_MATCHREL(_ch)      (LPC18XX_PWM_MATCHREL_BASE + _ch * 4)
>> +
>> +#define LPC18XX_PWM_EVSTATEMSK_BASE    0x300
>> +#define LPC18XX_PWM_EVSTATEMSK(_ch)    (LPC18XX_PWM_EVSTATEMSK_BASE + _ch * 8)
>> +#define LPC18XX_PWM_EVSTATEMSK_ALL     0xffffffff
>> +
>> +#define LPC18XX_PWM_EVCTRL_BASE                0x304
>> +#define LPC18XX_PWM_EVCTRL(_ch)                (LPC18XX_PWM_EVCTRL_BASE + _ch * 8)
>> +
> 
> I think some of these are not channels (you are passing duty_event
> to them) and so you shouldn't call the argument "_ch".

Right.

> 
>> +#define LPC18XX_PWM_EVCTRL_MATCH(_ch)  _ch
>> +
>> +#define LPC18XX_PWM_EVCTRL_COMB_SHIFT  12
>> +#define LPC18XX_PWM_EVCTRL_COMB_MATCH  (0x1 << LPC18XX_PWM_EVCTRL_COMB_SHIFT)
>> +
>> +#define LPC18XX_PWM_OUTPUTSET_BASE     0x500
>> +#define LPC18XX_PWM_OUTPUTSET(_ch)     (LPC18XX_PWM_OUTPUTSET_BASE + _ch * 8)
>> +
>> +#define LPC18XX_PWM_OUTPUTCL_BASE      0x504
>> +#define LPC18XX_PWM_OUTPUTCL(_ch)      (LPC18XX_PWM_OUTPUTCL_BASE + _ch * 8)
>> +
>> +/* LPC18xx SCT unified counter */
>> +#define LPC18XX_PWM_TIMER_MAX          0xffffffff
>> +
>> +/* LPC18xx SCT events */
>> +#define LPC18XX_PWM_EVENT_PERIOD       0
>> +#define LPC18XX_PWM_EVENT_MAX          16
>> +
>> +/* SCT conflict resolution */
>> +enum lpc18xx_pwm_res_action {
>> +       LPC18XX_PWM_RES_NONE    = 0x0,
>> +       LPC18XX_PWM_RES_SET     = 0x1,
>> +       LPC18XX_PWM_RES_CLEAR   = 0x2,
>> +       LPC18XX_PWM_RES_TOGGLE  = 0x3,
>> +};
>> +
>> +struct lpc18xx_pwm_data {
>> +       unsigned int            duty_event;
>> +};
>> +
>> +struct lpc18xx_pwm_chip {
>> +       struct device           *dev;
>> +       struct pwm_chip         chip;
>> +       void __iomem            *base;
>> +       struct clk              *pwm_clk;
>> +       unsigned long           clk_rate;
>> +       unsigned int            period_ns;
>> +       unsigned int            min_period_ns;
>> +       unsigned int            max_period_ns;
>> +       unsigned int            period_event;
>> +       unsigned long           event_map;
>> +       struct mutex            res_lock;
>> +       struct mutex            period_lock;
>> +};
>> +
>> +static inline struct lpc18xx_pwm_chip *to_lpc18xx_pwm_chip(
>> +                                                       struct pwm_chip *chip)
>> +{
>> +       return container_of(chip, struct lpc18xx_pwm_chip, chip);
>> +}
>> +
>> +static inline void lpc18xx_pwm_writel(struct lpc18xx_pwm_chip *lpc18xx_pwm,
>> +                                     u32 reg, u32 val)
>> +{
>> +       writel(val, lpc18xx_pwm->base + reg);
>> +}
>> +
>> +static inline u32 lpc18xx_pwm_readl(struct lpc18xx_pwm_chip *lpc18xx_pwm,
>> +                                   u32 reg)
>> +{
>> +       return readl(lpc18xx_pwm->base + reg);
>> +}
>> +
>> +static void lpc18xx_pwm_set_conflict_res(struct lpc18xx_pwm_chip *lpc18xx_pwm,
>> +                                        struct pwm_device *pwm,
>> +                                        enum lpc18xx_pwm_res_action action)
>> +{
>> +       u32 val;
>> +
>> +       mutex_lock(&lpc18xx_pwm->res_lock);
>> +
>> +       /*
>> +        * Simultaneous set and clear may happen on an output, that is the case
>> +        * when duty_ns == period_ns. LPC18xx SCT allows to set a conflict
>> +        * resolution action to be taken in such a case.
>> +        */
>> +       val = lpc18xx_pwm_readl(lpc18xx_pwm, LPC18XX_PWM_RES_BASE);
>> +       val &= ~LPC18XX_PWM_RES_MASK(pwm->hwpwm);
>> +       val |= LPC18XX_PWM_RES(pwm->hwpwm, action);
>> +       lpc18xx_pwm_writel(lpc18xx_pwm, LPC18XX_PWM_RES_BASE, val);
>> +
>> +       mutex_unlock(&lpc18xx_pwm->res_lock);
>> +}
>> +
>> +static void lpc18xx_pwm_config_period(struct pwm_chip *chip, int period_ns)
>> +{
>> +       struct lpc18xx_pwm_chip *lpc18xx_pwm = to_lpc18xx_pwm_chip(chip);
>> +       u64 val;
>> +
>> +       val = (u64)period_ns * lpc18xx_pwm->clk_rate;
>> +       do_div(val, NSEC_PER_SEC);
>> +
>> +       lpc18xx_pwm_writel(lpc18xx_pwm,
>> +                          LPC18XX_PWM_MATCH(lpc18xx_pwm->period_event),
>> +                          (u32)val);
>> +
>> +       lpc18xx_pwm_writel(lpc18xx_pwm,
>> +                          LPC18XX_PWM_MATCHREL(lpc18xx_pwm->period_event),
>> +                          (u32)val);
>> +}
>> +
>> +static void lpc18xx_pwm_config_duty(struct pwm_chip *chip,
>> +                                   struct pwm_device *pwm, int duty_ns)
>> +{
>> +       struct lpc18xx_pwm_chip *lpc18xx_pwm = to_lpc18xx_pwm_chip(chip);
>> +       struct lpc18xx_pwm_data *lpc18xx_data = pwm_get_chip_data(pwm);
>> +       u64 val;
>> +
>> +       val = (u64)duty_ns * lpc18xx_pwm->clk_rate;
>> +       do_div(val, NSEC_PER_SEC);
>> +
>> +       lpc18xx_pwm_writel(lpc18xx_pwm,
>> +                          LPC18XX_PWM_MATCH(lpc18xx_data->duty_event),
>> +                          (u32)val);
>> +
>> +       lpc18xx_pwm_writel(lpc18xx_pwm,
>> +                          LPC18XX_PWM_MATCHREL(lpc18xx_data->duty_event),
>> +                          (u32)val);
>> +}
>> +
>> +static int lpc18xx_pwm_config(struct pwm_chip *chip, struct pwm_device *pwm,
>> +                             int duty_ns, int period_ns)
>> +{
>> +       struct lpc18xx_pwm_chip *lpc18xx_pwm = to_lpc18xx_pwm_chip(chip);
>> +       int i;
>> +
>> +       if (period_ns < lpc18xx_pwm->min_period_ns ||
>> +           period_ns > lpc18xx_pwm->max_period_ns) {
>> +               dev_err(chip->dev, "period %d not in range\n", period_ns);
>> +               return -ERANGE;
>> +       }
>> +
>> +       mutex_lock(&lpc18xx_pwm->period_lock);
>> +
>> +       /*
>> +        * The PWM supports only a single period for all PWM channels, therefore
>> +        * incompatible changes need to be refused.
>> +        */
>> +       if (lpc18xx_pwm->period_ns && lpc18xx_pwm->period_ns != period_ns) {
>> +               dev_err(chip->dev, "conflicting period requested for PWM %u\n",
>> +                       pwm->hwpwm);
>> +               mutex_unlock(&lpc18xx_pwm->period_lock);
>> +               return -EBUSY;
>> +       }
>> +
>> +       if (!lpc18xx_pwm->period_ns) {
>> +               lpc18xx_pwm->period_ns = period_ns;
> 
> You set the period_ns, which is constrained to be a global period
> for all channels.
> 
> However, you are not clearing this. So there's no way to change the period.
> I believe you should allow to change the period if there's only a single
> channel enabled.
> 
> Thus, only forbid when changing the period of a channel that hasn't
> requested period change.

OK. I'm sending patchset v2 with these modifications.

> 
>> +               for (i = 0; i < chip->npwm; i++) {
>> +                       pwm_set_period(&chip->pwms[i], period_ns);
>> +               }
>> +               lpc18xx_pwm_config_period(chip, period_ns);
>> +       }
>> +
>> +       mutex_unlock(&lpc18xx_pwm->period_lock);
>> +
>> +       lpc18xx_pwm_config_duty(chip, pwm, duty_ns);
>> +
>> +       return 0;
>> +}
>> +
>> +static int lpc18xx_pwm_set_polarity(struct pwm_chip *chip,
>> +                                   struct pwm_device *pwm,
>> +                                   enum pwm_polarity polarity)
>> +{
>> +       return 0;
>> +}
>> +
>> +static int lpc18xx_pwm_enable(struct pwm_chip *chip, struct pwm_device *pwm)
>> +{
>> +       struct lpc18xx_pwm_chip *lpc18xx_pwm = to_lpc18xx_pwm_chip(chip);
>> +       struct lpc18xx_pwm_data *lpc18xx_data = pwm_get_chip_data(pwm);
>> +       enum lpc18xx_pwm_res_action res_action;
>> +       unsigned int set_event, clear_event;
>> +
>> +       lpc18xx_pwm_writel(lpc18xx_pwm,
>> +                          LPC18XX_PWM_EVCTRL(lpc18xx_data->duty_event),
>> +                          LPC18XX_PWM_EVCTRL_MATCH(lpc18xx_data->duty_event) |
>> +                          LPC18XX_PWM_EVCTRL_COMB_MATCH);
>> +
>> +       lpc18xx_pwm_writel(lpc18xx_pwm,
>> +                          LPC18XX_PWM_EVSTATEMSK(lpc18xx_data->duty_event),
>> +                          LPC18XX_PWM_EVSTATEMSK_ALL);
>> +
>> +       if (pwm->polarity == PWM_POLARITY_NORMAL) {
>> +               set_event = lpc18xx_pwm->period_event;
>> +               clear_event = lpc18xx_data->duty_event;
>> +               res_action = LPC18XX_PWM_RES_SET;
>> +       } else {
>> +               set_event = lpc18xx_data->duty_event;
>> +               clear_event = lpc18xx_pwm->period_event;
>> +               res_action = LPC18XX_PWM_RES_CLEAR;
>> +       }
>> +
>> +       lpc18xx_pwm_writel(lpc18xx_pwm, LPC18XX_PWM_OUTPUTSET(pwm->hwpwm),
>> +                          BIT(set_event));
>> +       lpc18xx_pwm_writel(lpc18xx_pwm, LPC18XX_PWM_OUTPUTCL(pwm->hwpwm),
>> +                          BIT(clear_event));
>> +       lpc18xx_pwm_set_conflict_res(lpc18xx_pwm, pwm, res_action);
>> +
>> +       return 0;
>> +}
>> +
>> +static void lpc18xx_pwm_disable(struct pwm_chip *chip, struct pwm_device *pwm)
>> +{
>> +       struct lpc18xx_pwm_chip *lpc18xx_pwm = to_lpc18xx_pwm_chip(chip);
>> +       struct lpc18xx_pwm_data *lpc18xx_data = pwm_get_chip_data(pwm);
>> +
>> +       lpc18xx_pwm_writel(lpc18xx_pwm,
>> +                          LPC18XX_PWM_EVCTRL(lpc18xx_data->duty_event), 0);
>> +       lpc18xx_pwm_writel(lpc18xx_pwm, LPC18XX_PWM_OUTPUTSET(pwm->hwpwm), 0);
>> +       lpc18xx_pwm_writel(lpc18xx_pwm, LPC18XX_PWM_OUTPUTCL(pwm->hwpwm), 0);
>> +}
>> +
>> +static int lpc18xx_pwm_request(struct pwm_chip *chip, struct pwm_device *pwm)
>> +{
>> +       struct lpc18xx_pwm_chip *lpc18xx_pwm = to_lpc18xx_pwm_chip(chip);
>> +       struct lpc18xx_pwm_data *lpc18xx_data = pwm_get_chip_data(pwm);
>> +       unsigned long event;
>> +
>> +       event = find_first_zero_bit(&lpc18xx_pwm->event_map,
>> +                                   LPC18XX_PWM_EVENT_MAX);
>> +
>> +       if (event >= LPC18XX_PWM_EVENT_MAX) {
>> +               dev_err(lpc18xx_pwm->dev,
>> +                       "maximum number of simultaneous channels reached\n");
>> +               return -EBUSY;
>> +       };
>> +
>> +       set_bit(event, &lpc18xx_pwm->event_map);
>> +       lpc18xx_data->duty_event = event;
>> +
>> +       return 0;
>> +}
>> +
>> +static void lpc18xx_pwm_free(struct pwm_chip *chip, struct pwm_device *pwm)
>> +{
>> +       struct lpc18xx_pwm_chip *lpc18xx_pwm = to_lpc18xx_pwm_chip(chip);
>> +       struct lpc18xx_pwm_data *lpc18xx_data = pwm_get_chip_data(pwm);
>> +
>> +       lpc18xx_pwm_disable(chip, pwm);
>> +       clear_bit(lpc18xx_data->duty_event, &lpc18xx_pwm->event_map);
>> +}
>> +
>> +static const struct pwm_ops lpc18xx_pwm_ops = {
>> +       .config         = lpc18xx_pwm_config,
>> +       .set_polarity   = lpc18xx_pwm_set_polarity,
>> +       .enable         = lpc18xx_pwm_enable,
>> +       .disable        = lpc18xx_pwm_disable,
>> +       .request        = lpc18xx_pwm_request,
>> +       .free           = lpc18xx_pwm_free,
>> +       .owner          = THIS_MODULE,
>> +};
>> +
>> +static const struct of_device_id lpc18xx_pwm_of_match[] = {
>> +       { .compatible = "nxp,lpc1850-pwm" },
>> +       {}
>> +};
>> +MODULE_DEVICE_TABLE(of, lpc18xx_pwm_of_match);
>> +
>> +static int lpc18xx_pwm_probe(struct platform_device *pdev)
>> +{
>> +       struct lpc18xx_pwm_chip *lpc18xx_pwm;
>> +       struct pwm_device *pwm;
>> +       struct resource *res;
>> +       int ret, i;
>> +       u64 val;
>> +
>> +       lpc18xx_pwm = devm_kzalloc(&pdev->dev, sizeof(*lpc18xx_pwm),
>> +                                  GFP_KERNEL);
>> +       if (!lpc18xx_pwm)
>> +               return -ENOMEM;
>> +
>> +       lpc18xx_pwm->dev = &pdev->dev;
>> +
>> +       res = platform_get_resource(pdev, IORESOURCE_MEM, 0);
>> +       lpc18xx_pwm->base = devm_ioremap_resource(&pdev->dev, res);
>> +       if (IS_ERR(lpc18xx_pwm->base))
>> +               return PTR_ERR(lpc18xx_pwm->base);
>> +
>> +       lpc18xx_pwm->pwm_clk = devm_clk_get(&pdev->dev, "pwm");
>> +       if (IS_ERR(lpc18xx_pwm->pwm_clk)) {
>> +               dev_err(&pdev->dev, "failed to get pwm clock\n");
>> +               return PTR_ERR(lpc18xx_pwm->pwm_clk);
>> +       }
>> +
>> +       ret = clk_prepare_enable(lpc18xx_pwm->pwm_clk);
>> +       if (ret < 0) {
>> +               dev_err(&pdev->dev, "could not prepare or enable pwm clock\n");
>> +               return ret;
>> +       }
>> +
>> +       lpc18xx_pwm->clk_rate = clk_get_rate(lpc18xx_pwm->pwm_clk);
>> +
>> +       mutex_init(&lpc18xx_pwm->res_lock);
>> +       mutex_init(&lpc18xx_pwm->period_lock);
>> +
>> +       val = (u64)NSEC_PER_SEC * LPC18XX_PWM_TIMER_MAX;
>> +       do_div(val, lpc18xx_pwm->clk_rate);
>> +       lpc18xx_pwm->max_period_ns = val;
>> +
>> +       val = (u64)NSEC_PER_SEC;
>> +       do_div(val, lpc18xx_pwm->clk_rate);
>> +       lpc18xx_pwm->min_period_ns = val;
>> +
>> +       lpc18xx_pwm->chip.dev = &pdev->dev;
>> +       lpc18xx_pwm->chip.ops = &lpc18xx_pwm_ops;
>> +       lpc18xx_pwm->chip.base = -1;
>> +       lpc18xx_pwm->chip.npwm = 16;
>> +       lpc18xx_pwm->chip.of_xlate = of_pwm_xlate_with_flags;
>> +       lpc18xx_pwm->chip.of_pwm_n_cells = 3;
>> +
>> +       /* SCT counter must be in unify (32 bit) mode */
>> +       lpc18xx_pwm_writel(lpc18xx_pwm, LPC18XX_PWM_CONFIG,
>> +                          LPC18XX_PWM_CONFIG_UNIFY);
>> +
>> +       /*
>> +        * Everytime the timer counter reaches the period value, the related
>> +        * event will be triggered and the counter reset to 0.
>> +        */
>> +       set_bit(LPC18XX_PWM_EVENT_PERIOD, &lpc18xx_pwm->event_map);
>> +       lpc18xx_pwm->period_event = LPC18XX_PWM_EVENT_PERIOD;
>> +
>> +       lpc18xx_pwm_writel(lpc18xx_pwm,
>> +                          LPC18XX_PWM_EVSTATEMSK(lpc18xx_pwm->period_event),
>> +                          LPC18XX_PWM_EVSTATEMSK_ALL);
>> +
>> +       val = LPC18XX_PWM_EVCTRL_MATCH(lpc18xx_pwm->period_event) |
>> +             LPC18XX_PWM_EVCTRL_COMB_MATCH;
>> +       lpc18xx_pwm_writel(lpc18xx_pwm,
>> +                          LPC18XX_PWM_EVCTRL(lpc18xx_pwm->period_event), val);
>> +
>> +       lpc18xx_pwm_writel(lpc18xx_pwm, LPC18XX_PWM_LIMIT,
>> +                          BIT(lpc18xx_pwm->period_event));
>> +
>> +       ret = pwmchip_add(&lpc18xx_pwm->chip);
>> +       if (ret < 0) {
>> +               dev_err(&pdev->dev, "pwmchip_add failed: %d\n", ret);
>> +               goto disable_pwmclk;
>> +       }
>> +
>> +       for (i = 0; i < lpc18xx_pwm->chip.npwm; i++) {
>> +               pwm = &lpc18xx_pwm->chip.pwms[i];
>> +               pwm->chip_data = devm_kzalloc(lpc18xx_pwm->dev,
>> +                                             sizeof(struct lpc18xx_pwm_data),
>> +                                             GFP_KERNEL);
>> +               if (!pwm->chip_data) {
>> +                       ret = -ENOMEM;
>> +                       goto remove_pwmchip;
>> +               }
>> +       }
>> +
>> +       platform_set_drvdata(pdev, lpc18xx_pwm);
>> +
>> +       val = lpc18xx_pwm_readl(lpc18xx_pwm, LPC18XX_PWM_CTRL);
>> +       val &= ~LPC18XX_PWM_BIDIR;
>> +       val &= ~LPC18XX_PWM_CTRL_HALT;
>> +       val &= ~LPC18XX_PWM_PRE_MASK;
>> +       val |= LPC18XX_PWM_PRE(0);
>> +       lpc18xx_pwm_writel(lpc18xx_pwm, LPC18XX_PWM_CTRL, val);
>> +
>> +       return 0;
>> +
>> +remove_pwmchip:
>> +       pwmchip_remove(&lpc18xx_pwm->chip);
>> +disable_pwmclk:
>> +       clk_disable_unprepare(lpc18xx_pwm->pwm_clk);
>> +       return ret;
>> +}
>> +
>> +static int lpc18xx_pwm_remove(struct platform_device *pdev)
>> +{
>> +       struct lpc18xx_pwm_chip *lpc18xx_pwm = platform_get_drvdata(pdev);
>> +       u32 val;
>> +
>> +       val = lpc18xx_pwm_readl(lpc18xx_pwm, LPC18XX_PWM_CTRL);
>> +       lpc18xx_pwm_writel(lpc18xx_pwm, LPC18XX_PWM_CTRL,
>> +                          val | LPC18XX_PWM_CTRL_HALT);
>> +
>> +       clk_disable_unprepare(lpc18xx_pwm->pwm_clk);
>> +
>> +       return pwmchip_remove(&lpc18xx_pwm->chip);
>> +}
>> +
>> +static struct platform_driver lpc18xx_pwm_driver = {
>> +       .driver = {
>> +               .name = "lpc18xx-pwm",
>> +               .of_match_table = lpc18xx_pwm_of_match,
>> +       },
>> +       .probe = lpc18xx_pwm_probe,
>> +       .remove = lpc18xx_pwm_remove,
>> +};
>> +module_platform_driver(lpc18xx_pwm_driver);
>> +
>> +MODULE_AUTHOR("Ariel D'Alessandro <ariel at vanguardiasur.com.ar>");
>> +MODULE_DESCRIPTION("NXP LPC18xx PWM driver");
>> +MODULE_LICENSE("GPL v2");
>> --
>> 1.9.1
>>
> 
> 
> 


From ariel at vanguardiasur.com.ar  Wed Aug  5 16:13:00 2015
From: ariel at vanguardiasur.com.ar (Ariel D'Alessandro)
Date: Wed, 05 Aug 2015 20:13:00 -0300
Subject: [PATCH 2/2] DT: pwm: Add NXP LPC18xx PWM/SCT binding documentation
In-Reply-To: <CAAEAJfBjr2wxn-x1RiEj+ezoHA0aWNqCFfpYLM3RzhTrnHDyWw@mail.gmail.com>
References: <1437972345-16444-1-git-send-email-ariel@vanguardiasur.com.ar>	<1437972345-16444-3-git-send-email-ariel@vanguardiasur.com.ar>	<CAGhQ9Vyy+oUAWm0q2+NV0D9RVf5qyED8Tn54-cGzbDc-EZR4yw@mail.gmail.com>	<CAAEAJfApE8=cAue-bc5xPD_XAtV8qzur12C4okF-uLJ-__reBA@mail.gmail.com>	<CAGhQ9VwudkK=bo5Qk79O7fmdEEm1KEWxUhLO14ucCJ+FbhqQqw@mail.gmail.com>	<CAAEAJfA22JA0AWB1FCiDVYEy5BqasDror_Ejpd=b3s14BWpORw@mail.gmail.com>	<CAGhQ9VyCNrH_J6rP+L+6OkV-PCgemOzhznuFRg07YxPpLX_nig@mail.gmail.com>
 <CAAEAJfBjr2wxn-x1RiEj+ezoHA0aWNqCFfpYLM3RzhTrnHDyWw@mail.gmail.com>
Message-ID: <55C2987C.2000109@vanguardiasur.com.ar>

Ezequiel, Joachim:

El 31/07/15 a las 15:09, Ezequiel Garcia escibi?:
> Joachim,
> 
> On 30 July 2015 at 20:30, Joachim  Eastwood <manabian at gmail.com> wrote:
>> On 29 July 2015 at 15:47, Ezequiel Garcia <ezequiel at vanguardiasur.com.ar> wrote:
>>> +devicetree guys
>>>
>>> On 28 July 2015 at 20:22, Joachim  Eastwood <manabian at gmail.com> wrote:
>>>> On 29 July 2015 at 00:45, Ezequiel Garcia <ezequiel at vanguardiasur.com.ar> wrote:
>>>>> On 28 July 2015 at 19:37, Joachim  Eastwood <manabian at gmail.com> wrote:
>>>>>> On 27 July 2015 at 06:45, Ariel D'Alessandro <ariel at vanguardiasur.com.ar> wrote:
>>>>>>> Add the devicetree binding document for NXP LPC18xx PWM/SCT.
>>>>>>>
>>>>>>> Signed-off-by: Ariel D'Alessandro <ariel at vanguardiasur.com.ar>
>>>>>>> ---
>>>>>>>  .../devicetree/bindings/pwm/lpc1850-pwm.txt          | 20 ++++++++++++++++++++
>>>>>>>  1 file changed, 20 insertions(+)
>>>>>>>  create mode 100644 Documentation/devicetree/bindings/pwm/lpc1850-pwm.txt
>>>>>>>
>>>>>>> diff --git a/Documentation/devicetree/bindings/pwm/lpc1850-pwm.txt b/Documentation/devicetree/bindings/pwm/lpc1850-pwm.txt
>>>>>>> new file mode 100644
>>>>>>> index 0000000..3055429
>>>>>>> --- /dev/null
>>>>>>> +++ b/Documentation/devicetree/bindings/pwm/lpc1850-pwm.txt
>>>>>>> @@ -0,0 +1,20 @@
>>>>>>> +* NXP LPC18xx Pulse Width Modulator driver
>>>>>>> +
>>>>>>> +Required properties:
>>>>>>> +  - compatible: Should be "nxp,lpc1850-pwm"
>>>>>>> +  - reg: Should contain physical base address and length of pwm registers.
>>>>>>> +  - clocks: Must contain an entry for each entry in clock-names.
>>>>>>> +    See ../clock/clock-bindings.txt for details.
>>>>>>> +  - clock-names: Must include the following entries.
>>>>>>> +    - pwm: PWM operating clock.
>>>>>>> +  - #pwm-cells: Should be 3. See pwm.txt in this directory for the description
>>>>>>> +    of the cells format.
>>>>>>> +
>>>>>>> +Example:
>>>>>>> +  pwm: pwm at 40000000 {
>>>>>>> +    compatible = "nxp,lpc1850-pwm";
>>>>>>
>>>>>> I would prefer "nxp,lpc1850-sct" for a couple of reasons. SCT is the
>>>>>> name of hardware block as described in the user manual and while PWM
>>>>>> is the most obvious usage for this block on Linux, the hardware is not
>>>>>> limited to just doing that. So as a bit of future proofing if someone
>>>>>> wants to use this block for more than PWM I would prefer SCT.
>>>>>>
>>>>>
>>>>> Shouldn't we use something like "nxp,lpc1850-sct-pwm"?
>>>>>
>>>>> Sounds like the word PWM should be in the compatible as it describes
>>>>> not only the device, but the device used in a certain way.
>>>>>
>>>>> Otherwise, how would we use "nxp,lpc1850-sct" to distinguish a PWM from
>>>>> e.g. a clocksource/clockevents (we can also use SCT for that)?
>>>>
>>>> I not sure how to best handle dt bindings with such flexible hardware blocks.
>>>>
>>>> But are you suggestion to have multiple drivers for the same hw block?
>>>> ie.: "nxp,lpc1850-sct-pwm" for PWM and for example
>>>> "nxp,lpc1850-sct-clocksource" for clocksource and then use/enable one
>>>> or the other.
>>>>
>>>
>>> Yup, I'm suggesting just that. If the hardware is capable, I can't see
>>> why we can't have different drivers for it.
>>
>> Well, I think it would be nice if we could have one driver per hw
>> block. But then you need a way to select whether you want to use the
>> counter in the SCT block for PWM or, for example, clocksource. Sort of
>> mode selection I guess.
>>
>> But then again if someone has some very custom and application
>> specific usage for the SCT block that maybe better served by a
>> standalone driver anyway.
>>
> 
> Technically speaking, I believe we can use "nxp,lpc1850-sct" to expose
> both a PWM interface and a clocksource in a single driver. Not too
> clean, though.
> 
> Alternatively, we should be able to have a multifunction device (MFD) to mux
> the SCT resources to be consumed by different kind of drivers.
> 
> Given there's no counter API to feed SCT, and given we use the other
> timer hw block to feed clocksource and clockevents for the LPC18/43xx,
> I think currently the simplest choice is to have "nxp,lpc1850-sct-pwm"
> describing this PWM SCT driver.
> 
> If we later want to change completely the PWM SCT driver, we can do
> that without any bindings change.
> 
>> So for now I am fine with "nxp,lpc1850-sct-pwm". I shouldn't be too
>> hard to change the bindings if we see other users of this block, I
>> believe.
>>
> 
> Well, that would break DT backward compatibility, so it's not an ideal.
> Like I said, "nxp,lpc1850-sct-pwm" seems to be specific enough to
> describe this driver.
> 
> I'd like to know what Thierry thinks here.
> 

OK then. Until we have a better idea, I'll set the compatible string to
"nxp,lpc1850-sct-pwm".


From leo.yan at linaro.org  Wed Aug  5 16:17:43 2015
From: leo.yan at linaro.org (Leo Yan)
Date: Thu, 6 Aug 2015 07:17:43 +0800
Subject: [RFC PATCH 0/3] mailbox: hisilicon: add mailbox driver
In-Reply-To: <CABb+yY0-RQ80q92EBsuBoYpjxW5zR=nXr+j3zCXw3wKkCf33OQ@mail.gmail.com>
References: <1438564390-28111-1-git-send-email-leo.yan@linaro.org>
 <CABb+yY0-RQ80q92EBsuBoYpjxW5zR=nXr+j3zCXw3wKkCf33OQ@mail.gmail.com>
Message-ID: <20150805231743.GB6880@leoy-linaro>

Hi Jassi,

Thanks for review.

On Wed, Aug 05, 2015 at 04:22:01PM +0530, Jassi Brar wrote:
> On Mon, Aug 3, 2015 at 6:43 AM, Leo Yan <leo.yan at linaro.org> wrote:

[...]

> > For easily extending for Hisilicon series SoCs (SoCs may have difference
> > for register's definition with each other), so firstly implement common
> > mailbox driver; this common mailbox driver provides three mainly
> > functionality:
> >
> >  - help register channels into framework;
> >  - hook low level callback functions for register's operations;
> >  - Enhance rx channel's message queue, which is based on the code in
> >    drivers/mailbox/omap-mailbox.c.
> >
> Not cool.
>  Please don't reinvent the wheel by having platform specific
> implementation of the mailbox api. Which vendor doesn't plan to roll
> out new SoCs, and hence variations of mailbox controllers?  The OMAP
> stack predates the common api, and was actually supposed to be
> converted over eventually. Please implement just the
> drivers/mailbox/hi6220-mailbox.c (preferably by the name of the
> mailbox controller, if any)

Understood. Here i have one question, the rx channel's message queue is
looks like a common mechanism and can be added into framework file
mailbox.c, then Soc driver file can _ONLY_ focus on register level's
operations. If so, the common driver in this patch also is unnecessary.

Do you suggest to use upper method to rework patches? Or just think
it's okay to implement rx channel's message queue in hi6220-mailbox.c?

Thanks,
Leo Yan


From dianders at chromium.org  Wed Aug  5 16:45:50 2015
From: dianders at chromium.org (Doug Anderson)
Date: Wed, 5 Aug 2015 16:45:50 -0700
Subject: [PATCH v3 1/3] ARM: rockchip: rename osc_switch_to_32k variable
In-Reply-To: <2128609.Kb18M8K28F@diego>
References: <2128609.Kb18M8K28F@diego>
Message-ID: <CAD=FV=V57vrP-6pzRf5+5FwvHnm0OL9ztyHoeQKOASzz8pPrPg@mail.gmail.com>

Heiko,

On Tue, Aug 4, 2015 at 3:50 PM, Heiko St?bner <heiko at sntech.de> wrote:
> The variable name is misleading, as the deep suspend mode always switches
> the main supplying clock to the 32kHz source. Additionally the main
> oscillator remain running in some cases, which this var indicates.
>
> So rename it to osc_disable to clarity.
>
> Signed-off-by: Heiko Stuebner <heiko at sntech.de>
> ---
>  arch/arm/mach-rockchip/pm.c | 4 ++--
>  1 file changed, 2 insertions(+), 2 deletions(-)

Reviewed-by: Douglas Anderson <dianders at chromium.org>


From k.kozlowski at samsung.com  Wed Aug  5 16:58:56 2015
From: k.kozlowski at samsung.com (Krzysztof Kozlowski)
Date: Thu, 06 Aug 2015 08:58:56 +0900
Subject: [PATCH-v2 2/2] regulator: 88pm800: Add support for configuration
 of dual phase on BUCK1
In-Reply-To: <55C1CD47.3060400@linaro.org>
References: <1437495782-15767-1-git-send-email-vaibhav.hiremath@linaro.org>
 <1437495782-15767-3-git-send-email-vaibhav.hiremath@linaro.org>
 <CAJKOXPcMd9VvfA48kaBa0BYeHAfHTu6MzAbQv0HuRy9wbgz0wg@mail.gmail.com>
 <55C1CD47.3060400@linaro.org>
Message-ID: <55C2A340.6020809@samsung.com>

On 05.08.2015 17:45, Vaibhav Hiremath wrote:
> 
> 
> On Thursday 23 July 2015 10:21 AM, Krzysztof Kozlowski wrote:
>> 2015-07-22 1:23 GMT+09:00 Vaibhav Hiremath <vaibhav.hiremath at linaro.org>:
>>> 88PM860 device supports dual phase mode on BUCK1 output.
>>> In normal usecase, BUCK1A and BUCK1B operates independently with 3A
>>> capacity. And they both can work as a dual phase providing 6A capacity.
>>>
>>> This patch updates the regulator driver to read the respective
>>> DT property and enable dual-phase mode on BUCK1.
>>>
>>> Note that, this is init time (one time) initialization.
>>>
> 
> Sorry for delayed response, was on bed rest almost for week.
> 
>>> Signed-off-by: Vaibhav Hiremath <vaibhav.hiremath at linaro.org>
>>> ---
>>>   drivers/regulator/88pm800.c | 31 +++++++++++++++++++++++++++++++
>>>   include/linux/mfd/88pm80x.h |  3 +++
>>>   2 files changed, 34 insertions(+)
>>
>> Don't you need to update the constraints also? I think the BUCK1
>> regulator has fixed constraint of 3 A:
>>    PM800_BUCK(buck1, BUCK1, BUCK_ENA, 0, 3000000, buck1_volt_range,
>> 0x55),
>> and now it can handle 6 A.
>>
> 
> Actually, BUCK1A and BUCK1B both combined together provide 6A capacity.
> And as discussed earlier, we need board change for this.
> 
> I am quite not sure.

AFAIU the regulator driver creates one BUCK1 regulator with constraints
3 A. However after your change the regulator will handle up to 6 A.

This means that constraints set by driver are wrong.

Additionally I can't find BUCK1A and BUCK1B regulators. Driver provides
only BUCK1.

> 
> Should I read the property and update the constraint runtime during
> probe?

Driver should provide real constraints. Find the proper way to do this.

The pm800_regulator_info[] array is not const so you can change it in
whatever way you want (although it should be const for existing driver
because regulator core accepts const and passing it to driver_data is
not necessary).

Best regards,
Krzysztof

> 
> 
>>>
>>> diff --git a/drivers/regulator/88pm800.c b/drivers/regulator/88pm800.c
>>> index e846e4c..1bf2b35 100644
>>> --- a/drivers/regulator/88pm800.c
>>> +++ b/drivers/regulator/88pm800.c
>>> @@ -267,6 +267,31 @@ static struct pm800_regulator_info
>>> pm860_regulator_info[] = {
>>>          PM800_LDO(ldo20, LDO20, LDO_ENA1_3, 3, 10000, ldo_volt_table2),
>>>   };
>>>
>>> +static int pm800_regulator_init(struct platform_device *pdev)
>>> +{
>>> +       struct pm800_regulators *pm800_data =
>>> platform_get_drvdata(pdev);
>>> +       struct pm80x_chip *chip = pm800_data->chip;
>>> +       int ret;
>>
>> 'ret' is used only in if statement below. I don't have strong feelings
>> but can you move it there to limit its scope or always return 'ret'
>> (after initializing to '0'). To me this would be more readable.
>>
> 
> OK, will fix in V3.
> 
> I will wait to close on constraint discussion above.
> 
> Thanks,
> Vaibhav
> 
>> Best regards,
>> Krzysztof
>>
>>> +
>>> +       /* Currently only supported on 88pm860 device */
>>> +       if (chip->type != CHIP_PM860)
>>> +               return 0;
>>> +
>>> +       if (of_property_read_bool(pdev->dev.of_node,
>>> +                               "marvell,88pm860-buck1-dualphase-en")) {
>>> +               ret = regmap_update_bits(chip->subchip->regmap_power,
>>> +                                       PM860_BUCK1_MISC,
>>> +                                       BUCK1_DUAL_PHASE_SEL,
>>> +                                       BUCK1_DUAL_PHASE_SEL);
>>> +               if (ret) {
>>> +                       dev_err(chip->dev, "failed to set dual-pase
>>> mode %d\n", ret);
>>> +                       return ret;
>>> +               }
>>> +       }
>>> +
>>> +       return 0;
>>> +}
>>> +
>>>   static int pm800_regulator_probe(struct platform_device *pdev)
>>>   {
>>>          struct pm80x_chip *chip = dev_get_drvdata(pdev->dev.parent);
>>> @@ -336,6 +361,12 @@ static int pm800_regulator_probe(struct
>>> platform_device *pdev)
>>>                  }
>>>          }
>>>
>>> +       ret = pm800_regulator_init(pdev);
>>> +       if (ret) {
>>> +               dev_err(&pdev->dev, "failed to init 88pm800 regulator
>>> device\n");
>>> +               return ret;
>>> +       }
>>> +
>>>          return 0;
>>>   }
>>>
>>> diff --git a/include/linux/mfd/88pm80x.h b/include/linux/mfd/88pm80x.h
>>> index a92d173..05d9bad 100644
>>> --- a/include/linux/mfd/88pm80x.h
>>> +++ b/include/linux/mfd/88pm80x.h
>>> @@ -295,6 +295,9 @@ enum {
>>>   #define PM860_BUCK4_MISC2              (0x82)
>>>   #define PM860_BUCK4_FULL_DRV           BIT(2)
>>>
>>> +#define PM860_BUCK1_MISC               (0x8E)
>>> +#define BUCK1_DUAL_PHASE_SEL           BIT(2)
>>> +
>>>   struct pm80x_rtc_pdata {
>>>          int             vrtc;
>>>          int             rtc_wakeup;
>>> -- 
>>> 1.9.1
>>>
>>>
>>> _______________________________________________
>>> linux-arm-kernel mailing list
>>> linux-arm-kernel at lists.infradead.org
>>> http://lists.infradead.org/mailman/listinfo/linux-arm-kernel
> 



From gregkh at linuxfoundation.org  Wed Aug  5 17:27:37 2015
From: gregkh at linuxfoundation.org (Greg Kroah-Hartman)
Date: Wed, 5 Aug 2015 17:27:37 -0700
Subject: [PATCH v3 13/24] visorbus: switch from ioremap_cache to memremap
In-Reply-To: <20150730165451.33962.48793.stgit@dwillia2-desk3.amr.corp.intel.com>
References: <20150730165155.33962.64121.stgit@dwillia2-desk3.amr.corp.intel.com>
 <20150730165451.33962.48793.stgit@dwillia2-desk3.amr.corp.intel.com>
Message-ID: <20150806002737.GA25628@kroah.com>

On Thu, Jul 30, 2015 at 12:54:51PM -0400, Dan Williams wrote:
> In preparation for deprecating ioremap_cache() convert its usage in
> visorbus to memremap.
> 
> Cc: Benjamin Romer <benjamin.romer at unisys.com>
> Cc: David Kershner <david.kershner at unisys.com>
> Signed-off-by: Dan Williams <dan.j.williams at intel.com>
> ---
>  drivers/staging/unisys/visorbus/visorchannel.c |   16 +++++++++-------
>  drivers/staging/unisys/visorbus/visorchipset.c |   17 +++++++++--------
>  2 files changed, 18 insertions(+), 15 deletions(-)
> 

Acked-by: Greg Kroah-Hartman <gregkh at linuxfoundation.org>


From alexey at kopytko.ru  Wed Aug  5 17:33:12 2015
From: alexey at kopytko.ru (Alexey Kopytko)
Date: Thu, 6 Aug 2015 09:33:12 +0900
Subject: [PATCH v2] ARM: dts: Convert Linkstation Mini to Device Tree
In-Reply-To: <55C23FA8.9030504@free-electrons.com>
References: <1436885641.7145.9.camel@dolka.fr> <20150718185238.GH17961@lunn.ch>
 <55B396A1.1090509@free-electrons.com>
 <1438027893.15635.41.camel@dolka.fr>
 <55C23FA8.9030504@free-electrons.com>
Message-ID: <CAO10ksyxsZ=Xv4iPn4uSjTC1z9D6dR9hZq6Mk7yuMJhFin9ZhA@mail.gmail.com>

On Thu, Aug 6, 2015 at 1:54 AM, Gregory CLEMENT
<gregory.clement at free-electrons.com> wrote:

>>> With the Acked-by from  Andrew Lunn I am ready to apply your patch.
>>> However for the device tree I need the acked-by from Thomas Petazzoni but I
>>> am sure he will give it as he already agreed for the armada-*.dts* files.
>>>
>>> I am not sure we need the formal acked-by from Alexey because the dts is
>>> not based on a dts written by him.
>>
>> It's just that I took all the devices definition from his .c; to me, it
>> counts as derived work, but IANAL.
>
> For me it is still the decription of the hardware not an derivated work.
> Andrew what is your opinion on it?
>
> But if we consider it as a derivated work then we need Alexey acked-by soon,
> or going back to GPL only license.
>

Since the patch touches files I had a part creating, the patch itself
is clearly a derivative work. Therefore, without further ado...

Acked-by: Alexey Kopytko <alexey at kopytko.ru>


Thanks,

-Alexey


From horms at verge.net.au  Wed Aug  5 17:35:12 2015
From: horms at verge.net.au (Simon Horman)
Date: Thu, 6 Aug 2015 09:35:12 +0900
Subject: [PATCH v4 0/6] ARM: shmobile: r8a7740/sh73a0 DT Cache Handling
In-Reply-To: <1438765090-823-1-git-send-email-geert+renesas@glider.be>
References: <1438765090-823-1-git-send-email-geert+renesas@glider.be>
Message-ID: <20150806003511.GB17231@verge.net.au>

Hi Geert,

On Wed, Aug 05, 2015 at 10:58:04AM +0200, Geert Uytterhoeven wrote:
> 	Hi Simon, Magnus,
> 
> This patch series add L1 and L2 cache descriptions to DT for r8a7740 and
> sh73a0, and migrates the shmobile DT-based generic r8a7740 and
> armadillo legacy platforms from calling l2x0_of_init() to the generic
> l2c OF initialization.
> 
> Note that the conversion to the generic l2c OF initialization is not
> done yet for sh73a0, as this initializes the L2 cache earlier, breaking
> the (fragile) sh73a0 secondary CPU bringup code.
> 
> Also note that this conversion should be done on r8a7778, and r8a7779,
> too.
> 
> Changes compared to v3 ("[PATCH v3 0/6] ARM: l2c / shmobile: r8a7740 : Shared
> Override",
> http://lists.infradead.org/pipermail/linux-arm-kernel/2015-May/340636.html):
>   - "l2c: Add support for the "arm,shared-override" property" was split
>     off into an independent patch, and is now queued for v4.3 in
>     arm/for-next,
>   - Dropped armadillo legacy migration, as it no longer exists,
>   - Added sh73a0 L1 and L2 DT cache description.
> 
> Changes compared to v2 ("[PATCH v2 0/5] ARM: shmobile: r8a7740/armadillo:
> Migrate to generic l2c OF",
> http://www.spinics.net/lists/devicetree/msg68176.html):
>   - Add DT support for Shared Override,
>   - Setting Shared Override is done only if CMA is not available (as
>     Russell claims it's not needed if CMA is available),
>   - Use 0/~0 in machine_desc.l2c_aux_{val,mask}, as DT now supports
>     "arm,shared-override".
> 
> Changes compared to v1:
>   - Fix interrupt reference in DT,
>   - Describe L2 better in DT,
>   - Keep only {,~}L2C_AUX_CTRL_SHARED_OVERRIDE in
>     machine_desc.l2c_aux_{val,mask}, as there's no DT property for
>     this.
>   - Add L1 cache to DT.
> 
> Dependencies:
>   - This series applies to renesas-devel-20150805-v4.2-rc5,
>   - Patch 2 depends on patch 1,
>   - Patch 4 depends on patch 2,
>   - Patch 5 depends on patch 1 and on "ARM: 8395/1: l2c: Add support for
>     the "arm,shared-override" property" in arm/for-next,
>   - Patch 6 depends on patch 5.
> 
> Given C code patches depending on DT patches in the same branch are
> frowned upon, I think it would be best if patch 1 (and patch 3, if
> anyone thinks we may fix the secondary CPU bringup issue during the next
> 3 months) are queued for v4.3. The other patches can be queued for
> 2016^H^H^H^Hv4.4.

Sorry for surprising you with that merge-order requirement.

Unfortunately I am not comfortable with taking patch 1 for v4.3 because:
1. Its now very late in the cycle
2. There now seems to be some discussion around it.

I think I am happy to take the other patches for v4.4, now. But perhaps
I should wait for the discussion around patch 1 to conclude first?


From horms at verge.net.au  Wed Aug  5 17:37:51 2015
From: horms at verge.net.au (Simon Horman)
Date: Thu, 6 Aug 2015 09:37:51 +0900
Subject: [PATCH] ARM: shmobile: Add silk device tree bindings documentation
In-Reply-To: <1438723848-14812-1-git-send-email-horms+renesas@verge.net.au>
References: <1438723848-14812-1-git-send-email-horms+renesas@verge.net.au>
Message-ID: <20150806003751.GC17231@verge.net.au>

On Wed, Aug 05, 2015 at 06:30:48AM +0900, Simon Horman wrote:
> Add Silk Device tree bindings Documentation, listing it as a supported board.
> 
> This allows to use checkpatch to validate DTSes referring to the Silk board.
> 
> Signed-off-by: Simon Horman <horms+renesas at verge.net.au>

Thanks, I have queued this up for v4.4 rather than as a fix for v4.3
as it doesn't have any run or build time effect.

> ---
>  Documentation/devicetree/bindings/arm/shmobile.txt | 2 ++
>  1 file changed, 2 insertions(+)
> 
> diff --git a/Documentation/devicetree/bindings/arm/shmobile.txt b/Documentation/devicetree/bindings/arm/shmobile.txt
> index c4f19b2e7dd9..f3f96b5a7418 100644
> --- a/Documentation/devicetree/bindings/arm/shmobile.txt
> +++ b/Documentation/devicetree/bindings/arm/shmobile.txt
> @@ -57,6 +57,8 @@ Boards:
>      compatible = "renesas,lager", "renesas,r8a7790"
>    - Marzen
>      compatible = "renesas,marzen", "renesas,r8a7779"
> +  - Silk
> +    compatible = "renesas,silk", "renesas,r8a7794";
>  
>  Note: Reference Device Tree Implementations are temporary implementations
>        to ease the migration from platform devices to Device Tree, and are
> -- 
> 2.1.4
> 


From timur at codeaurora.org  Wed Aug  5 17:46:03 2015
From: timur at codeaurora.org (Timur Tabi)
Date: Wed, 5 Aug 2015 17:46:03 -0700
Subject: [PATCH v3 15/31] arm64: SMP support
In-Reply-To: <1347035226-18649-16-git-send-email-catalin.marinas@arm.com>
References: <1347035226-18649-1-git-send-email-catalin.marinas@arm.com>
 <1347035226-18649-16-git-send-email-catalin.marinas@arm.com>
Message-ID: <CAOZdJXVoDJM3y2mnKO+91yf2EHogKfMjumjhhi85REAfhcJM=Q@mail.gmail.com>

Catalin,

I know this patch is three years old, but I have a question about it:

On Fri, Sep 7, 2012 at 9:26 AM, Catalin Marinas <catalin.marinas at arm.com> wrote:
> +static void ipi_cpu_stop(unsigned int cpu)
> +{
> +       if (system_state == SYSTEM_BOOTING ||
> +           system_state == SYSTEM_RUNNING) {
> +               raw_spin_lock(&stop_lock);
> +               pr_crit("CPU%u: stopping\n", cpu);
> +               dump_stack();
> +               raw_spin_unlock(&stop_lock);
> +       }
> +
> +       set_cpu_online(cpu, false);
> +
> +       local_fiq_disable();
> +       local_irq_disable();
> +
> +       while (1)
> +               cpu_relax();
> +}

Why do you display a message and dump the stack when a CPU is stopped?
 I ask because emergency_restart() calls this function, and so
whenever I want to do an "emergency" reboot, it dumps the stack for
each core.  On an ARM64 system with lots of cores, this produces a ton
of output.  That makes emergency_restart() almost useless.

-- 
Qualcomm Innovation Center, Inc.
The Qualcomm Innovation Center, Inc. is a member of the Code Aurora Forum,
a Linux Foundation Collaborative Project.


From horms at verge.net.au  Wed Aug  5 17:47:14 2015
From: horms at verge.net.au (Simon Horman)
Date: Thu, 6 Aug 2015 09:47:14 +0900
Subject: [PATCH v2 0/2] Add R8A7794 GPIO DT support
In-Reply-To: <6388101.Drn6rL87rl@wasted.cogentembedded.com>
References: <6388101.Drn6rL87rl@wasted.cogentembedded.com>
Message-ID: <20150806004714.GD17231@verge.net.au>

On Tue, Aug 04, 2015 at 12:36:27AM +0300, Sergei Shtylyov wrote:
> Hello.
> 
>    Here's the set of 2 patches against Simon Horman's 'renesas.git' repo,
> 'renesas-devel-20150803-v4.2-rc5' tag. Here we add the GPIO device tree support
> for the R8A7794 SoC.
> 
> [1/2] ARM: shmobile: r8a7794: add GPIO clocks
> [2/2] ARM: shmobile: r8a7794: add GPIO DT support

Thanks, I have queued these up for v4.4.


From horms at verge.net.au  Wed Aug  5 17:50:30 2015
From: horms at verge.net.au (Simon Horman)
Date: Thu, 6 Aug 2015 09:50:30 +0900
Subject: [PATCH v4 00/16] ARM: shmobile: Add CPG/MSTP Clock Domain
In-Reply-To: <CAMuHMdUFjgVWBc0hdm_L0Z0Os1OT8H4NzwQyQTGZQt8Bu7-9PQ@mail.gmail.com>
References: <1438691297-29235-1-git-send-email-geert+renesas@glider.be>
 <20150804134824.GA10194@verge.net.au>
 <20150805005543.GC20726@verge.net.au>
 <CAMuHMdUFjgVWBc0hdm_L0Z0Os1OT8H4NzwQyQTGZQt8Bu7-9PQ@mail.gmail.com>
Message-ID: <20150806005029.GE17231@verge.net.au>

On Wed, Aug 05, 2015 at 08:58:29AM +0200, Geert Uytterhoeven wrote:
> Hi Simon,
> 
> On Wed, Aug 5, 2015 at 2:55 AM, Simon Horman <horms at verge.net.au> wrote:
> > On Tue, Aug 04, 2015 at 10:48:28PM +0900, Simon Horman wrote:
> >> I have tentatively queued this up in its own branch,
> >> cpg-mstp-clock-domain-for-v4.3.
> >
> > Where possible I prefer not to apply non-DTS/DTSI patches on top of
> > DTS/DTSI patches, I believe this is in keeping with how the ARM SoC
> > maintainers like things handled.  With this in mind I have shuffled things
> > around a little, the result is:
> >
> > 1. The following are (still) queued up for v4.3 in their own
> >    cpg-mstp-clock-domain-for-v4.3 branch:
> >
> >    clk: shmobile: Add CPG/MSTP Clock Domain support
> >    clk: shmobile: r8a7778: Add CPG/MSTP Clock Domain support
> >    clk: shmobile: r8a7779: Add CPG/MSTP Clock Domain support
> >    clk: shmobile: rcar-gen2: Add CPG/MSTP Clock Domain support
> >    clk: shmobile: rz: Add CPG/MSTP Clock Domain support
> >    ARM: shmobile: r7s72100 dtsi: Add CPG/MSTP Clock Domain
> >    ARM: shmobile: r8a7778 dtsi: Add CPG/MSTP Clock Domain
> >    ARM: shmobile: r8a7779 dtsi: Add CPG/MSTP Clock Domain
> >    ARM: shmobile: r8a7790 dtsi: Add CPG/MSTP Clock Domain
> >    ARM: shmobile: r8a7791 dtsi: Add CPG/MSTP Clock Domain
> >    ARM: shmobile: r8a7793 dtsi: Add CPG/MSTP Clock Domain
> >    ARM: shmobile: r8a7794 dtsi: Add CPG/MSTP Clock Domain
> 
> OK.
> 
> > 2. The following are now queued up for v4.3 in a separate
> >    sh-drivers-for-v4.3 branch. That branch is on top of the
> >    cpg-mstp-clock-domain-for-v4.3 branch and I intend to send it directly
> >    to Linus if/when a v4.3-rc has been released with the patches
> >    listed in 1. present.
> >
> >    drivers: sh: Disable legacy default PM Domain on emev2
> >    drivers: sh: Disable PM runtime for multi-platform ARM with genpd
> 
> OK
> 
> > 3. I have deferred the remaining two patches, listed below, for v4.4.
> >    they currently reside in cpg-mstp-clock-domain-for-v4.4. That
> >    branch is based on the sh-drivers-for-v4.3 branch.
> >
> >    clk: shmobile: mstp: Consider "zb_clk" suitable for power management
> >    ARM: shmobile: R-Mobile: Use CPG/MSTP Clock Domain attach/detach helpers
> >
> > This means that the last two patches will disappear from next until
> > after v4.3-rc1 is released but they, along with all the other patches,
> > will be present in the renesas devel branch.
> 
> OK.
> 
> Note that as the last two depend on patch 1 only, you could e.g. queue
> them up in group 1, between the clk and dtsi patches.
> But it's up to you to reconsider.
> I'm happy as-is, as the last two patches are just a code duplication clean up.

Thanks, and sorry for not realising that.

For now I will keep things as-is because I would like to stabilise my
branches.


From shunqian.zheng at gmail.com  Wed Aug  5 18:10:00 2015
From: shunqian.zheng at gmail.com (Shunqian Zheng)
Date: Thu, 06 Aug 2015 09:10:00 +0800
Subject: [PATCH v2 0/3] Add the efuse driver on rockchip platform
In-Reply-To: <55C0E42E.3060509@linaro.org>
References: <1434439665-27781-1-git-send-email-wxt@rock-chips.com>
 <557FE3EA.4000306@i2se.com> <557FEAB2.1040101@linaro.org>
 <557FF50C.10809@rock-chips.com> <55800070.5030509@linaro.org>
 <55826D9D.2060106@i2se.com> <5582816B.5020208@linaro.org>
 <55BB3F92.9030701@gmail.com> <55C0E42E.3060509@linaro.org>
Message-ID: <55C2B3E8.2070000@gmail.com>



On 2015?08?05? 00:11, Srinivas Kandagatla wrote:
> Hi Shunqian,
>
> Sorry for delay in reply, I was on Holidays..
>
> Thanks for testing.
>
> On 31/07/15 10:27, Shunqian Zheng wrote:
>>
>> 1. Without the following diff, `hexdump
>> /sys/bus/nvmem/devices/rockchip-efuse0/nvmem` is wrong with "INVALID
>> ARGUMENT":
>>
>> +++ b/drivers/nvmem/core.c
>> @@ -67,7 +67,7 @@ static ssize_t bin_attr_nvmem_read(struct file *filp,
>> struct kobject *kobj,
>>          int rc;
>>
>>          /* Stop the user from reading */
>> -       if (pos > nvmem->size)
>> +       if (pos > nvmem->size - 1)
>>                  return 0;
>
> Yes, this should have been something like this
> -       if (pos > nvmem->size)
> +       if (pos >= nvmem->size)
>                 return 0;
>
> We can send a fix on top of v9 once its merged.
>
>>
>>          if (pos + count > nvmem->size)
>>
>> RK3288-efuse has  32 x 8bit regs, in dts "reg = <0xffb40000 0x20>;"
>> Here is the message dump from nvmem_device:
>> [    2.158314] nvmem:
>> [    2.158314]           name (null)
>> [    2.158314]           stride 1
>> [    2.158314]           word_size 1
>> [    2.158314]           ncells 0
>> [    2.158314]           id 0
>> [    2.158314]           users 0
>> [    2.158314]           size 32
>> [    2.158314]           read_only 0
>>
>> Do you think there is a leak or I'm messing up ?
>>
>> 2. About the read operation, eFuse data can be read during device
>> probe() and cached, OR,
>>      read from eFuse when needed every time. I prefer the second one but
>> then, the clock of eFuse may be
>>      gated. So before/after reading I have to enable/disable clk like :
>>            devm_clk_get(dev, "hclk_efuse256");
>>      The trouble is I can't find a way to get the "dev" hander in :
>>            static int rockchip_efuse_read(void *context, const void
>> *reg, size_t reg_size, void *val, size_t val_size)
>>      I am appreciated if you can give some advice.
>
>
> May be you should use regmap_init_mmio_clk() instead of 
> regmap_init_mmio() it will take care of clks.
Thank you for you reply.
Although the regmap_init_mmio_clk() and it's series interface deal with 
the clks, but
MMIO uses its own regmap_bus{}, while the eFuse of RK3X need special 
read/write
callback functions.

I still can't find a good way to resolve this. Can you help?

Shunqian
>
>>      Or, do you think it's reasonable to add hooks before/after read in
>> nvmem/core.c like :
>>            +       before_read(dev, ...);
>>                     rc = regmap_raw_read(nvmem->regmap, pos, buf, 
>> count);
>>            +       after_read(dev, ...);
>>
>
>
>> 3. In the /sys/bus/nvmem/devices/rockchip-efuse0/, there are files:
>>           /sys/devices/platform/ffb40000.efuse/rockchip-efuse0 # ls
>>           nvmem      of_node    power      subsystem  uevent
>>      Do you have a plan to add the nvmem consumers to /sys/ in nvmem
>> framework?
> yes, Am waiting for the framework to be merged, I have plans to add 
> this feature.
>
>>      For example,  in dts defined the "cpu_leakage":
>>          efuse: efuse at ffb40000 {
>>                  compatible = "rockchip,rk3x-efuse";
>>                  reg = <0xffb40000 0x20>;
>>                  #address-cells = <1>;
>>                  #size-cells = <1>;
>>                  clocks = <&cru PCLK_EFUSE256>;
>>                  clock-names = "pclk_efuse_256";
>>
>>                  cpu_leakage: cpu_leakage {
>>                          reg = <0x17 0x1>;
>>                  };
>>          };
>>     Then nvmem exposes the "cpu_leakage" file in /sys which can be
>> read/write.
>
> --srini



From sboyd at codeaurora.org  Wed Aug  5 18:27:24 2015
From: sboyd at codeaurora.org (Stephen Boyd)
Date: Wed, 05 Aug 2015 18:27:24 -0700
Subject: [PATCH v5 2/2] firmware: qcom: scm: Add support for ARM64 SoCs
In-Reply-To: <1430249038-30987-2-git-send-email-galak@codeaurora.org>
References: <1430249038-30987-1-git-send-email-galak@codeaurora.org>
 <1430249038-30987-2-git-send-email-galak@codeaurora.org>
Message-ID: <55C2B7FC.5090402@codeaurora.org>

On 04/28/2015 12:23 PM, Kumar Gala wrote:
> +
> +int __qcom_scm_call_armv8_64(u64 x0, u64 x1, u64 x2, u64 x3, u64 x4, u64 x5,
> +				u64 *ret1, u64 *ret2, u64 *ret3)
> +{
> +	register u64 r0 asm("r0") = x0;
> +	register u64 r1 asm("r1") = x1;
> +	register u64 r2 asm("r2") = x2;
> +	register u64 r3 asm("r3") = x3;
> +	register u64 r4 asm("r4") = x4;
> +	register u64 r5 asm("r5") = x5;

This should set x6 to 0.

     register u32 r6 asm("r6") = 0;

for example.

> +
> +	do {
> +		asm volatile(
> +			__asmeq("%0", "x0")
> +			__asmeq("%1", "x1")
> +			__asmeq("%2", "x2")
> +			__asmeq("%3", "x3")
> +			__asmeq("%4", "x0")
> +			__asmeq("%5", "x1")
> +			__asmeq("%6", "x2")
> +			__asmeq("%7", "x3")
> +			__asmeq("%8", "x4")
> +			__asmeq("%9", "x5")

And then the asmeq thing here for x6.

> +#ifdef REQUIRES_SEC
> +			".arch_extension sec\n"
> +#endif
> +			"smc	#0\n"
> +			: "=r" (r0), "=r" (r1), "=r" (r2), "=r" (r3)
> +			: "r" (r0), "r" (r1), "r" (r2), "r" (r3), "r" (r4),
> +			  "r" (r5)

And add x6 as an input here.

> +			: "x6", "x7", "x8", "x9", "x10", "x11", "x12", "x13",

and remove x6 as a clobber.

> +			  "x14", "x15", "x16", "x17");
> +	} while (r0 == QCOM_SCM_INTERRUPTED);
> +
> +	if (ret1)
> +		*ret1 = r1;
> +	if (ret2)
> +		*ret2 = r2;
> +	if (ret3)
> +		*ret3 = r3;
> +
> +	return r0;
> +}
> +
> +int __qcom_scm_call_armv8_32(u32 w0, u32 w1, u32 w2, u32 w3, u32 w4, u32 w5,
> +				u64 *ret1, u64 *ret2, u64 *ret3)
> +{
> +	register u32 r0 asm("r0") = w0;
> +	register u32 r1 asm("r1") = w1;
> +	register u32 r2 asm("r2") = w2;
> +	register u32 r3 asm("r3") = w3;
> +	register u32 r4 asm("r4") = w4;
> +	register u32 r5 asm("r5") = w5;

This needs to set r6 to 0 as well

     register u32 r6 asm("r6") = 0;

for example.

> +
> +	do {
> +		asm volatile(
> +			__asmeq("%0", "x0")
> +			__asmeq("%1", "x1")
> +			__asmeq("%2", "x2")
> +			__asmeq("%3", "x3")
> +			__asmeq("%4", "x0")
> +			__asmeq("%5", "x1")
> +			__asmeq("%6", "x2")
> +			__asmeq("%7", "x3")
> +			__asmeq("%8", "x4")
> +			__asmeq("%9", "x5")

And then another asmeq thing here for x6.

> +#ifdef REQUIRES_SEC
> +			".arch_extension sec\n"
> +#endif
> +			"smc	#0\n"
> +			: "=r" (r0), "=r" (r1), "=r" (r2), "=r" (r3)
> +			: "r" (r0), "r" (r1), "r" (r2), "r" (r3), "r" (r4),
> +			  "r" (r5)

And then add r6 here as an input

> +			: "x6", "x7", "x8", "x9", "x10", "x11", "x12", "x13",

And remove r6 from the clobber.

> +			"x14", "x15", "x16", "x17");
> +
> +	} while (r0 == QCOM_SCM_INTERRUPTED);
> +
> +	if (ret1)
> +		*ret1 = r1;
> +	if (ret2)
> +		*ret2 = r2;
> +	if (ret3)
> +		*ret3 = r3;
> +
> +	return r0;
> +}
> +
>

Here's a totally untested patch for that.

Signed-off-by: Stephen Boyd <sboyd at codeaurora.org>
----8<-----

diff --git a/drivers/firmware/qcom_scm-64.c b/drivers/firmware/qcom_scm-64.c
index a95fd9b5d576..8f7e65ff524c 100644
--- a/drivers/firmware/qcom_scm-64.c
+++ b/drivers/firmware/qcom_scm-64.c
@@ -114,6 +114,7 @@ int __qcom_scm_call_armv8_64(u64 x0, u64 x1, u64 x2, u64 x3, u64 x4, u64 x5,
  	register u64 r3 asm("r3") = x3;
  	register u64 r4 asm("r4") = x4;
  	register u64 r5 asm("r5") = x5;
+	register u64 r6 asm("r5") = 0;
  
  	do {
  		asm volatile(
@@ -127,14 +128,15 @@ int __qcom_scm_call_armv8_64(u64 x0, u64 x1, u64 x2, u64 x3, u64 x4, u64 x5,
  			__asmeq("%7", "x3")
  			__asmeq("%8", "x4")
  			__asmeq("%9", "x5")
+			__asmeq("%10", "x6")
  #ifdef REQUIRES_SEC
  			".arch_extension sec\n"
  #endif
  			"smc	#0\n"
  			: "=r" (r0), "=r" (r1), "=r" (r2), "=r" (r3)
  			: "r" (r0), "r" (r1), "r" (r2), "r" (r3), "r" (r4),
-			  "r" (r5)
-			: "x6", "x7", "x8", "x9", "x10", "x11", "x12", "x13",
+			  "r" (r5), "r" (r6)
+			: "x7", "x8", "x9", "x10", "x11", "x12", "x13",
  			  "x14", "x15", "x16", "x17");
  	} while (r0 == QCOM_SCM_INTERRUPTED);
  
@@ -157,6 +159,7 @@ int __qcom_scm_call_armv8_32(u32 w0, u32 w1, u32 w2, u32 w3, u32 w4, u32 w5,
  	register u32 r3 asm("r3") = w3;
  	register u32 r4 asm("r4") = w4;
  	register u32 r5 asm("r5") = w5;
+	register u32 r6 asm("r6") = 0;
  
  	do {
  		asm volatile(
@@ -170,14 +173,15 @@ int __qcom_scm_call_armv8_32(u32 w0, u32 w1, u32 w2, u32 w3, u32 w4, u32 w5,
  			__asmeq("%7", "x3")
  			__asmeq("%8", "x4")
  			__asmeq("%9", "x5")
+			__asmeq("%10", "x6")
  #ifdef REQUIRES_SEC
  			".arch_extension sec\n"
  #endif
  			"smc	#0\n"
  			: "=r" (r0), "=r" (r1), "=r" (r2), "=r" (r3)
  			: "r" (r0), "r" (r1), "r" (r2), "r" (r3), "r" (r4),
-			  "r" (r5)
-			: "x6", "x7", "x8", "x9", "x10", "x11", "x12", "x13",
+			  "r" (r5), "r" (r6)
+			: "x7", "x8", "x9", "x10", "x11", "x12", "x13",
  			"x14", "x15", "x16", "x17");
  
  	} while (r0 == QCOM_SCM_INTERRUPTED);

-- 
Qualcomm Innovation Center, Inc. is a member of Code Aurora Forum,
a Linux Foundation Collaborative Project



From sboyd at codeaurora.org  Wed Aug  5 18:27:29 2015
From: sboyd at codeaurora.org (Stephen Boyd)
Date: Wed, 05 Aug 2015 18:27:29 -0700
Subject: [PATCH v1 4/7] ARM: dts: apq8064: Add MDP support
In-Reply-To: <1438088049-17479-1-git-send-email-srinivas.kandagatla@linaro.org>
References: <1438087956-17307-1-git-send-email-srinivas.kandagatla@linaro.org>
 <1438088049-17479-1-git-send-email-srinivas.kandagatla@linaro.org>
Message-ID: <55C2B801.1030806@codeaurora.org>

On 07/28/2015 05:54 AM, Srinivas Kandagatla wrote:
> @@ -618,5 +633,77 @@
>   			compatible = "qcom,tcsr-apq8064", "syscon";
>   			reg = <0x1a400000 0x100>;
>   		};
> +
> +		hdmi: qcom,hdmi-tx at 4a00000 {
> +			compatible = "qcom,hdmi-tx-8960";
> +			reg-names = "core_physical";
> +			reg = <0x04a00000 0x1000>;
> +			interrupts = <GIC_SPI 79 0>;
> +			clock-names =
> +			    "core_clk",
> +			    "master_iface_clk",
> +			    "slave_iface_clk";
> +			clocks =
> +			    <&mmcc HDMI_APP_CLK>,
> +			    <&mmcc HDMI_M_AHB_CLK>,
> +			    <&mmcc HDMI_S_AHB_CLK>;
> +			qcom,hdmi-tx-ddc-clk = <&tlmm_pinmux 70 GPIO_ACTIVE_HIGH>;
> +			qcom,hdmi-tx-ddc-data = <&tlmm_pinmux 71 GPIO_ACTIVE_HIGH>;
> +			qcom,hdmi-tx-hpd = <&tlmm_pinmux 72 GPIO_ACTIVE_HIGH>;

These should use standard "-gpios" syntax. Please fix the binding/driver.

> +			pinctrl-names = "default";
> +			pinctrl-0 = <&hdmi_pinctrl>;
> +		};
> +
> +		gpu: qcom,adreno-3xx at 4300000 {
> +			compatible = "qcom,adreno-3xx";
> +			reg = <0x04300000 0x20000>;
> +			reg-names = "kgsl_3d0_reg_memory";
> +			interrupts = <GIC_SPI 80 0>;
> +			interrupt-names = "kgsl_3d0_irq";
> +			clock-names =
> +			    "core_clk",
> +			    "iface_clk",
> +			    "mem_clk",
> +			    "mem_iface_clk";

Please drop "_clk" and fix driver code as we've done for all other drivers.

> +			clocks =
> +			    <&mmcc GFX3D_CLK>,
> +			    <&mmcc GFX3D_AHB_CLK>,
> +			    <&mmcc GFX3D_AXI_CLK>,
> +			    <&mmcc MMSS_IMEM_AHB_CLK>;
> +			qcom,chipid = <0x03020002>;
> +			qcom,gpu-pwrlevels {
> +				compatible = "qcom,gpu-pwrlevels";
> +				qcom,gpu-pwrlevel at 0 {
> +					qcom,gpu-freq = <450000000>;
> +				};
> +				qcom,gpu-pwrlevel at 1 {
> +					qcom,gpu-freq = <27000000>;
> +				};
> +			};

These should be OPPs. I see in the cover-letter we're asking to ignore 
this part of the binding. When is the binding and driver going to be 
fixed? The dts has been out of tree for quite some time and I assume 
work has been progressing on the driver even without this dts being in 
mainline so it doesn't make sense how pushing half-baked dts upstream is 
going to help. In fact, it's going to make things worse if someone 
complains that we're not maintaining backwards compatibility and then 
have to hack up driver code to work both ways. At which point there's 
practically zero incentive to change anything in the binding or driver. 
It's better to fix the driver now and avoid these sorts of problems 
entirely.

-- 
Qualcomm Innovation Center, Inc. is a member of Code Aurora Forum,
a Linux Foundation Collaborative Project



From shawnguo at kernel.org  Wed Aug  5 18:28:32 2015
From: shawnguo at kernel.org (Shawn Guo)
Date: Thu, 6 Aug 2015 09:28:32 +0800
Subject: [PATCH] ARM: imx6: correct i.MX6 PCIe interrupt routing
In-Reply-To: <1438793677-19153-1-git-send-email-l.stach@pengutronix.de>
References: <1438793677-19153-1-git-send-email-l.stach@pengutronix.de>
Message-ID: <20150806012832.GP12927@tiger>

On Wed, Aug 05, 2015 at 06:54:37PM +0200, Lucas Stach wrote:
> The PCIe interrupts are also routed through the GPC. This has been
> missed from the conversion to stacked IRQ domains as the PCIe
> controller uses an explicit interrupt map and thus doesn't inherit
> the SoC global interrupt parent.
> 
> Signed-off-by: Lucas Stach <l.stach at pengutronix.de>

So this is a fix and need copy stable?

Shawn

> ---
> This commit does not change the i.MX6SX PCIe node, as PCIe isn't
> functional in mainline on this SoC and the DT node needs a major
> rewrite to account for the specifics of this SoC anyway.
> ---
>  arch/arm/boot/dts/imx6qdl.dtsi | 8 ++++----
>  1 file changed, 4 insertions(+), 4 deletions(-)
> 
> diff --git a/arch/arm/boot/dts/imx6qdl.dtsi b/arch/arm/boot/dts/imx6qdl.dtsi
> index e6d13592080d..b57033e8c633 100644
> --- a/arch/arm/boot/dts/imx6qdl.dtsi
> +++ b/arch/arm/boot/dts/imx6qdl.dtsi
> @@ -181,10 +181,10 @@
>  			interrupt-names = "msi";
>  			#interrupt-cells = <1>;
>  			interrupt-map-mask = <0 0 0 0x7>;
> -			interrupt-map = <0 0 0 1 &intc GIC_SPI 123 IRQ_TYPE_LEVEL_HIGH>,
> -			                <0 0 0 2 &intc GIC_SPI 122 IRQ_TYPE_LEVEL_HIGH>,
> -			                <0 0 0 3 &intc GIC_SPI 121 IRQ_TYPE_LEVEL_HIGH>,
> -			                <0 0 0 4 &intc GIC_SPI 120 IRQ_TYPE_LEVEL_HIGH>;
> +			interrupt-map = <0 0 0 1 &gpc GIC_SPI 123 IRQ_TYPE_LEVEL_HIGH>,
> +			                <0 0 0 2 &gpc GIC_SPI 122 IRQ_TYPE_LEVEL_HIGH>,
> +			                <0 0 0 3 &gpc GIC_SPI 121 IRQ_TYPE_LEVEL_HIGH>,
> +			                <0 0 0 4 &gpc GIC_SPI 120 IRQ_TYPE_LEVEL_HIGH>;
>  			clocks = <&clks IMX6QDL_CLK_PCIE_AXI>,
>  				 <&clks IMX6QDL_CLK_LVDS1_GATE>,
>  				 <&clks IMX6QDL_CLK_PCIE_REF_125M>;
> -- 
> 2.4.6
> 
> 
> _______________________________________________
> linux-arm-kernel mailing list
> linux-arm-kernel at lists.infradead.org
> http://lists.infradead.org/mailman/listinfo/linux-arm-kernel
> 


From sboyd at codeaurora.org  Wed Aug  5 18:44:13 2015
From: sboyd at codeaurora.org (Stephen Boyd)
Date: Wed, 05 Aug 2015 18:44:13 -0700
Subject: [PATCH 5/7] clk: atlas7: fix the clock tree for bluetooth stuff
In-Reply-To: <CAGsJ_4wg1+5KrwTJRzE-iaSTvgvgFrM6cDyUTL16gx6Hk+tdPw@mail.gmail.com>
References: <1438064845-17894-1-git-send-email-21cnbao@gmail.com>
 <1438064845-17894-6-git-send-email-21cnbao@gmail.com>
 <55B7FD22.10609@codeaurora.org>
 <CAGsJ_4wg1+5KrwTJRzE-iaSTvgvgFrM6cDyUTL16gx6Hk+tdPw@mail.gmail.com>
Message-ID: <55C2BBED.4050608@codeaurora.org>

On 07/29/2015 07:52 AM, Barry Song wrote:
> 2015-07-29 6:07 GMT+08:00 Stephen Boyd <sboyd at codeaurora.org>:
>> On 07/27/2015 11:27 PM, Barry Song wrote:
>>> From: Guo Zeng <guo.zeng at csr.com>
>>>
>>> normally dmac should depends on only one clock, to operate
>>> dmac internal register, but dmac4 is very special case, it
>>> normally dmac should depends on only one clock, to operate
>>> dmac internal register, but dmac4 is very special case, it
>> The sentence is duplicated twice here
>>
>>> depends on two additional clock, the reason is that dmac4
>>> is wrapped in hw into bt a7ca module, and accessing dmac4
>>> internal register would also require that the a7ca_io and
>>> related bt macro io clk also enabled.
>>> here workaround this by setting depend clk into parent of
>>> dmac4, and also related clks, to reflect dependency.
>> We don't put clocks as parents of other clocks just because the child
>> depends on the parent to be accessed. It isn't very clear from the
>> description, but it sounds like a7ca_io is just another clock that the
>> bluetooth driver needs to control? We want to express the true clk
>> hierarchy, not some psuedo dependency tree.
>>
> Stephen, generically i agree the codes should be a map of real
> hardware connection. here the problem is real hardware connection is
> very much difficult for its drivers implementation and these clocks
> are buggy designed in HW. they are not a tree, they are a "network".
>
> see attached diagram(hope LKML will not reject the attachment), we are
> not a tree,  that means btm_noc_clk depends on btm_io_clk, a7ca_io_clk
> depends on btm_io_clk, dmac4_io_clk depends on btm_noc_clk,
> a7ca_io_clk and btm_noc_clk....
> usp3_io_clk depends on uart6_io_clk, dmac4_io_clk, btm_noc_clk,
> a7ca_io_clk and btm_noc_clk.
>
> so in the driver, we have a choice as below:
> in uart6 driver, we take all of the clocks.
> in dmac4 driver, we take all of btm_noc_clk, a7ca_io_clk and btm_noc_clk.
> ...
> what a ugly code! that is what we did before.
>
> so here, we moved to do a not-real clock tree,  that means
> we makes
> 1.btm_io_clk the parent of btm_noc_clk
> 2. btm_noc_clk the parent of a7ca_io_clk
> 3. a7ca_io_clk the parent of dmac4_io_clk
> ...
>
> but it doesn't break any dependency of these clocks, and make all
> clients driver as clean as a simple tree.
> i strongly think we should keep this "workaround", otherwise, we have
> many pain in all of the related drivers.
>
>

Thanks for the nice PNG. It seems like you have a typical bus topology 
where UART and USP need to go through DMAC and the Data NOC to get out 
on the system bus. btm_io_clk is the true parent of all the clocks.

I can only guess that A7CA is some sort of device that you have to go 
through from the CPU side to access the UART, USP, and DMAC hardware 
blocks. Is that right? Can you please describe what each of these blocks 
do and if there are linux drivers for them?

One way to model this would be to make UART and USP children of the DMAC 
hardware block. And then make a driver/device up for the NOC and have 
the DMAC be a child of the NOC device. Then the NOC would probe and be 
runtime PM enabled to turn on the btm_noc_clk whenever it or its 
children are enabled. Then the DMAC device would do the same thing, but 
with the dmac4_io_clk, and the UART and USP devices would get the 
uart6_io_clk and usp3_io_clk respectively and enable/disable them when 
the device is active.

That leaves us with the a7ca_io_clk, which is really just the clock for 
a bus that register read/writes go through. In designs I've seen, I 
usually left that clock under the control of each individual device that 
sits on the bus. So in this case, the DMAC, USP and UART device drivers 
would all need to get the a7ca_io_clk as their "interface" clock and 
make sure to enable or disable it whenever the driver wants to 
read/write the registers. I'm not sure if something else is done on the 
APB for you, but that may be all that's necessary.

This actually points out a big problem we have right now in Linux, which 
is the lack of proper power management for the type of bus topology you 
see in embedded systems. Some of the genpd work going on may also be 
another solution to this problem, where we could group multiple devices 
into generic power domains that know to turn on 2 or 3 of the clocks. 
For example, the DMAC, USP, and UART device could all be in the APB 
power domain so that the a7ca_io_clk is enabled whenever one of those 
devices is active. And there could be another power domain for the NOC 
that encompasses all devices that are sitting on that NOC.

Long story short, solving these sorts of problems in the clk framework 
is typically the easy route that people take, although it's the wrong 
route. We're not expressing these sorts of complicated bus topologies in 
the clk framework. We're only expressing the clk tree (which is already 
quite complicated enough). Your drivers can still be simple, but don't 
make it more complicated than it has to be in the clk framework for that.

-- 
Qualcomm Innovation Center, Inc. is a member of Code Aurora Forum,
a Linux Foundation Collaborative Project



From leilk.liu at mediatek.com  Wed Aug  5 18:45:40 2015
From: leilk.liu at mediatek.com (leilk liu)
Date: Thu, 6 Aug 2015 09:45:40 +0800
Subject: [PATCH v4 1/3] dt-binding: spi: Mediatek: Document devicetree
 bindings for spi bus
In-Reply-To: <20150804174226.GE20873@sirena.org.uk>
References: <1438167874-1305-1-git-send-email-leilk.liu@mediatek.com>
 <1438167874-1305-2-git-send-email-leilk.liu@mediatek.com>
 <20150804174226.GE20873@sirena.org.uk>
Message-ID: <1438825540.2163.5.camel@mhfsdcap03>

On Tue, 2015-08-04 at 18:42 +0100, Mark Brown wrote:
> On Wed, Jul 29, 2015 at 07:04:32PM +0800, Leilk Liu wrote:
> > Signed-off-by: Leilk Liu <leilk.liu at mediatek.com>
> 
> Please use subject lines reflecting the style for the subsystem so
> people can spot if patches are relevant to them.
> 

OK, I will change the title to "spi: Mediatek: Document devicetree
bindings for spi bus".

> > +- clocks: phandles to input clocks.
> > +
> > +- clock-names: tuple listing input clock names.
> > +	Required elements: "main"
> 
> ...and there are no optional values?
> 

clock tree provides some source clocks, CLK_PERI_SPI0 is the default
one. I will support optional values on the next version.

> > +- pad-select: should specify spi pad used, only required for MT8173.
> > +        This value should be 0~3.
> 
> What do the values 0-3 mean?  I guess it's the value for some register
> or other part of the device, the binding should say so people can go and
> check the datasheet, schematic or whatever to figure out what to set.
> 
> This property should be optional, not required

OK, I will explain what the values 0-3 mean.




From dianders at chromium.org  Wed Aug  5 18:54:06 2015
From: dianders at chromium.org (Doug Anderson)
Date: Wed, 5 Aug 2015 18:54:06 -0700
Subject: [PATCH v3 2/3] ARM: rockchip: set correct stabilization
 thresholds in suspend
In-Reply-To: <1709899.JJDRtF09u7@diego>
References: <2128609.Kb18M8K28F@diego>
	<1709899.JJDRtF09u7@diego>
Message-ID: <CAD=FV=VWehNnr-NaZy=m7p-ciXi1ACpwb0Wr2nDLSrjvZT-oUQ@mail.gmail.com>

Heiko,

On Tue, Aug 4, 2015 at 3:51 PM, Heiko St?bner <heiko at sntech.de> wrote:
> Currently the stabilization thresholds for the oscillator and external pmu
> are statically set to 30ms based on a 32kHz clock rate. This leaves out the
> case when we don't switch to the 32kHz clock when only entering the shallow
> suspend mode where the logic keeps running.
>
> So, set the correct threshold after we have determined if we switch to the
> 32kHz clock or stay with the 24MHz one. Also set the oscillator-
> stabilization to 0 if it is kept running during suspend, as it of course
> does not need to stabilize then.
>
> Reported-by: Chris Zhong <zyw at rock-chips.com>
> Signed-off-by: Heiko Stuebner <heiko at sntech.de>
> ---
> changes since v2:
> - describe 32kHz vs 24MHz
> - don't wait for oscillator stabilization if it's still running,
>   as explained by Chris Zhong in v2
> changes since v1:
> - 24MHz oriented threshold is only needed in shallow suspend, the deep
>   suspend always switches to 32kHz and only leaves the 24MHz oscillator
>   running if needed for stuff like usb wakeup
>
>  arch/arm/mach-rockchip/pm.c | 22 +++++++++++++++++++---
>  arch/arm/mach-rockchip/pm.h |  4 ----
>  2 files changed, 19 insertions(+), 7 deletions(-)
>
> diff --git a/arch/arm/mach-rockchip/pm.c b/arch/arm/mach-rockchip/pm.c
> index 2ca1170..c11a30b 100644
> --- a/arch/arm/mach-rockchip/pm.c
> +++ b/arch/arm/mach-rockchip/pm.c
> @@ -145,6 +145,19 @@ static void rk3288_slp_mode_set(int level)
>
>                 mode_set1 |= BIT(PMU_CLR_ALIVE) | BIT(PMU_CLR_BUS) |
>                              BIT(PMU_CLR_PERI) | BIT(PMU_CLR_DMA);
> +
> +               /*
> +                * In deep suspend we use PMU_PMU_USE_LF to let the rk3288
> +                * switch its main clock supply to the alternative 32kHz
> +                * source. Therefore set 30ms on a 32kHz clock for pmic
> +                * stabilization. Similar 30ms on 24MHz for the other
> +                * mode below.
> +                */
> +               regmap_write(pmu_regmap, RK3288_PMU_STABL_CNT, 32 * 30);

Took me a little while to parse the comment, but it looks right.
Basically we need 30ms for PMIC stabilization both here and in the
other mode.  That is programmed as 32 * 30 here and 2400 * 30 there.
...and we know we're on 32k clock because of PMU_PMU_USE_LF.

Reviewed-by: Douglas Anderson <dianders at chromium.org>


From dianders at chromium.org  Wed Aug  5 18:55:52 2015
From: dianders at chromium.org (Doug Anderson)
Date: Wed, 5 Aug 2015 18:55:52 -0700
Subject: [PATCH v3 3/3] ARM: rockchip: enable PMU_GPIOINT_WAKEUP_EN when
 entering shallow suspend
In-Reply-To: <1544453.8uqOvAiDmD@diego>
References: <2128609.Kb18M8K28F@diego>
	<1544453.8uqOvAiDmD@diego>
Message-ID: <CAD=FV=W0L_0iM+15BAUfTA2ij5Ac90aVW9JZYyDhHMDNT2ZUMg@mail.gmail.com>

Heiko,

On Tue, Aug 4, 2015 at 3:51 PM, Heiko St?bner <heiko at sntech.de> wrote:
> PMU_GPIOINT_WAKEUP_EN seems needed when entering the shallow suspend
> (with logic staying on) but does not seem to be needed for the deep
> suspend for unknown reasons.
> Testing revealed that this setting really is necessary to reliably
> resume the veyron devices from suspend.
>
> Reported-by: Chris Zhong <zyw at rock-chips.com>
> Signed-off-by: Heiko Stuebner <heiko at sntech.de>
> ---
>  arch/arm/mach-rockchip/pm.c | 9 ++++++---
>  arch/arm/mach-rockchip/pm.h | 1 +
>  2 files changed, 7 insertions(+), 3 deletions(-)

Very odd, but OK by me...  Hopefully we'll eventually end up being
able to use deep suspend on mainline.  That'd be nice, wouldn't it?

Reviewed-by: Douglas Anderson <dianders at chromium.org>


From Wenyou.Yang at atmel.com  Wed Aug  5 19:09:00 2015
From: Wenyou.Yang at atmel.com (Yang, Wenyou)
Date: Thu, 6 Aug 2015 02:09:00 +0000
Subject: [PATCH v3 1/2] drivers: watchdog: add a driver to support
 SAMA5D4 watchdog timer
In-Reply-To: <20150805124030.6e73b975@ipc1.ka-ro>
References: <1438765043-11030-1-git-send-email-wenyou.yang@atmel.com>
 <1438765043-11030-2-git-send-email-wenyou.yang@atmel.com>
 <20150805124030.6e73b975@ipc1.ka-ro>
Message-ID: <B256D81BAE5131468A838E5D7A243641C9F87310@penmbx01>

Hi Lothar,

Thank you for your review.

> -----Original Message-----
> From: Lothar Wa?mann [mailto:LW at KARO-electronics.de]
> Sent: 2015?8?5? 18:41
> To: Yang, Wenyou
> Cc: wim at iguana.be; robh+dt at kernel.org; pawel.moll at arm.com;
> mark.rutland at arm.com; ijc+devicetree at hellion.org.uk; galak at codeaurora.org;
> boris.brezillon at free-electrons.com; linux-watchdog at vger.kernel.org;
> devicetree at vger.kernel.org; sylvain.rochet at finsecur.com; Ferre, Nicolas; linux-
> kernel at vger.kernel.org; linux-arm-kernel at lists.infradead.org
> Subject: Re: [PATCH v3 1/2] drivers: watchdog: add a driver to support SAMA5D4
> watchdog timer
> 
> Hi,
> 
> > From SAMA5D4, the watchdog timer is upgrated with a new feature, which
> > is describled as in the datasheet, "WDT_MR can be written until a
> > LOCKMR command is issued in WDT_CR".
> > That is to say, as long as the bootstrap and u-boot don't issue a
> > LOCKMR command, WDT_MR can be written more than once in the driver.
> >
> > So the SAMA5D4 watchdog driver's implementation is different from the
> > at91sam9260 watchdog driver implemented in file at91sam9_wdt.c.
> > The user application open the device file to enable the watchdog timer
> > hardware, and close to disable it, and set the watchdog timer timeout
> > by seting WDV and WDD fields of WDT_MR register, and ping the watchdog
> > by issuing WDRSTT command to WDT_CR register with hard-coded key.
> >
> > Signed-off-by: Wenyou Yang <wenyou.yang at atmel.com>
> > ---
> >  drivers/watchdog/Kconfig            |    9 ++
> >  drivers/watchdog/Makefile           |    1 +
> >  drivers/watchdog/at91_sama5d4_wdt.c |  279
> +++++++++++++++++++++++++++++++++++
> >  drivers/watchdog/at91sam9_wdt.h     |    2 +
> >  4 files changed, 291 insertions(+)
> >  create mode 100644 drivers/watchdog/at91_sama5d4_wdt.c
> >
> > diff --git a/drivers/watchdog/Kconfig b/drivers/watchdog/Kconfig index
> > e5e7c55..4ce8346 100644
> > --- a/drivers/watchdog/Kconfig
> > +++ b/drivers/watchdog/Kconfig
> > @@ -152,6 +152,15 @@ config ARM_SP805_WATCHDOG
> >  	  ARM Primecell SP805 Watchdog timer. This will reboot your system
> when
> >  	  the timeout is reached.
> >
> > +config AT91_SAMA5D4_WATCHDOG
> > +	tristate "Atmel SAMA5D4 Watchdog Timer"
> > +	depends on ARCH_AT91
> > +	select WATCHDOG_CORE
> > +	help
> > +	  Atmel SAMA5D4 watchdog timer is embedded into SAMA5D4 chips.
> > +	  Its Watchdog Timer Mode Register can be written more than once.
> > +	  This will reboot your system when the timeout is reached.
> > +
> >  config AT91RM9200_WATCHDOG
> >  	tristate "AT91RM9200 watchdog"
> >  	depends on SOC_AT91RM9200 && MFD_SYSCON diff --git
> > a/drivers/watchdog/Makefile b/drivers/watchdog/Makefile index
> > 5c19294..c57569c 100644
> > --- a/drivers/watchdog/Makefile
> > +++ b/drivers/watchdog/Makefile
> > @@ -30,6 +30,7 @@ obj-$(CONFIG_USBPCWATCHDOG) += pcwd_usb.o
> >
> >  # ARM Architecture
> >  obj-$(CONFIG_ARM_SP805_WATCHDOG) += sp805_wdt.o
> > +obj-$(CONFIG_AT91_SAMA5D4_WATCHDOG) += at91_sama5d4_wdt.o
> consistency? Other AT91 entries don't have an '_' between 'AT91' and the
> remainder of the Kconfig name.
Accept, Remove the prefix AT91_ , use the chip name directly, SAMA5D4 in next verison.

> 
> >  obj-$(CONFIG_AT91RM9200_WATCHDOG) += at91rm9200_wdt.ovi 
> >  obj-$(CONFIG_AT91SAM9X_WATCHDOG) += at91sam9_wdt.o
> [...]
> > +static irqreturn_t atmel_wdt_irq_handler(int irq, void *dev_id) {
> > +	struct atmel_wdt *wdt = platform_get_drvdata(dev_id);
> > +
> > +	if (wdt_read(wdt, AT91_WDT_SR)) {
> > +		pr_crit("Atmel Watchdog Software Reset\n");
> > +		emergency_restart();
> > +		pr_crit("Reboot didn't ?????\n");
> >
> Reboot didn't what? 'succeed' perhaps?
Replace it with 'succeed' in next version. 

> 
> > +static const struct of_device_id atmel_wdt_of_match[] = {
> > +	{ .compatible = "atmel,sama5d4-wdt", },
> > +	{ },
> The empty initializer must always be the last element of the array, so there is no
> point in having a trailing ',' (whose purpose is to facilitate adding more entries after
> the last one).
> Without the comma there will be a compile error if (e.g. due to a badly resolved
> merge conflict) an additional entry would be added after the stop marker. With the
> comma after the stop marker any trailing entries would silently be ignored.
Remove this comma in next version.

> 
> 
> Lothar Wa?mann
> --
> ___________________________________________________________
> 
> Ka-Ro electronics GmbH | Pascalstra?e 22 | D - 52076 Aachen
> Phone: +49 2408 1402-0 | Fax: +49 2408 1402-10
> Gesch?ftsf?hrer: Matthias Kaussen
> Handelsregistereintrag: Amtsgericht Aachen, HRB 4996
> 
> www.karo-electronics.de | info at karo-electronics.de
> ___________________________________________________________

Best Regards,
Wenyou 

From Wenyou.Yang at atmel.com  Wed Aug  5 19:14:00 2015
From: Wenyou.Yang at atmel.com (Yang, Wenyou)
Date: Thu, 6 Aug 2015 02:14:00 +0000
Subject: [PATCH v3 1/2] drivers: watchdog: add a driver to support
 SAMA5D4 watchdog timer
In-Reply-To: <55C22614.6090901@roeck-us.net>
References: <1438765043-11030-1-git-send-email-wenyou.yang@atmel.com>
 <1438765043-11030-2-git-send-email-wenyou.yang@atmel.com>
 <55C22614.6090901@roeck-us.net>
Message-ID: <B256D81BAE5131468A838E5D7A243641C9F87321@penmbx01>

Hi Guenter,

Thank you for your review.

> -----Original Message-----
> From: Guenter Roeck [mailto:linux at roeck-us.net]
> Sent: 2015?8?5? 23:05
> To: Yang, Wenyou; wim at iguana.be; robh+dt at kernel.org; pawel.moll at arm.com;
> mark.rutland at arm.com; ijc+devicetree at hellion.org.uk; galak at codeaurora.org
> Cc: sylvain.rochet at finsecur.com; Ferre, Nicolas; boris.brezillon at free-
> electrons.com; devicetree at vger.kernel.org; linux-kernel at vger.kernel.org; linux-
> watchdog at vger.kernel.org; linux-arm-kernel at lists.infradead.org
> Subject: Re: [PATCH v3 1/2] drivers: watchdog: add a driver to support SAMA5D4
> watchdog timer
> 
> On 08/05/2015 01:57 AM, Wenyou Yang wrote:
> >>From SAMA5D4, the watchdog timer is upgrated with a new feature,
> > which is describled as in the datasheet, "WDT_MR can be written until
> > a LOCKMR command is issued in WDT_CR".
> > That is to say, as long as the bootstrap and u-boot don't issue a
> > LOCKMR command, WDT_MR can be written more than once in the driver.
> >
> > So the SAMA5D4 watchdog driver's implementation is different from the
> > at91sam9260 watchdog driver implemented in file at91sam9_wdt.c.
> > The user application open the device file to enable the watchdog timer
> > hardware, and close to disable it, and set the watchdog timer timeout
> > by seting WDV and WDD fields of WDT_MR register, and ping the watchdog
> > by issuing WDRSTT command to WDT_CR register with hard-coded key.
> >
> > Signed-off-by: Wenyou Yang <wenyou.yang at atmel.com>
> > ---
> >   drivers/watchdog/Kconfig            |    9 ++
> >   drivers/watchdog/Makefile           |    1 +
> >   drivers/watchdog/at91_sama5d4_wdt.c |  279
> +++++++++++++++++++++++++++++++++++
> >   drivers/watchdog/at91sam9_wdt.h     |    2 +
> >   4 files changed, 291 insertions(+)
> >   create mode 100644 drivers/watchdog/at91_sama5d4_wdt.c
> >
> > diff --git a/drivers/watchdog/Kconfig b/drivers/watchdog/Kconfig index
> > e5e7c55..4ce8346 100644
> > --- a/drivers/watchdog/Kconfig
> > +++ b/drivers/watchdog/Kconfig
> > @@ -152,6 +152,15 @@ config ARM_SP805_WATCHDOG
> >   	  ARM Primecell SP805 Watchdog timer. This will reboot your system
> when
> >   	  the timeout is reached.
> >
> > +config AT91_SAMA5D4_WATCHDOG
> 
> Looking into the chip ordering documentation. The chip goes by ATSAMA5D4,
> while the other chips go by AT91SAM9xxx.
> 
> So I think ATSAMA5D4 would be better (same for the driver name).
Use SAMA5D4 directly, the chip name.

> 
> Couple of additional nitpicks below.
I will change it in the next version, thanks.

> 
> Thanks,
> Guenter
> 
> > +	tristate "Atmel SAMA5D4 Watchdog Timer"
> > +	depends on ARCH_AT91
> > +	select WATCHDOG_CORE
> > +	help
> > +	  Atmel SAMA5D4 watchdog timer is embedded into SAMA5D4 chips.
> > +	  Its Watchdog Timer Mode Register can be written more than once.
> > +	  This will reboot your system when the timeout is reached.
> > +
> >   config AT91RM9200_WATCHDOG
> >   	tristate "AT91RM9200 watchdog"
> >   	depends on SOC_AT91RM9200 && MFD_SYSCON diff --git
> > a/drivers/watchdog/Makefile b/drivers/watchdog/Makefile index
> > 5c19294..c57569c 100644
> > --- a/drivers/watchdog/Makefile
> > +++ b/drivers/watchdog/Makefile
> > @@ -30,6 +30,7 @@ obj-$(CONFIG_USBPCWATCHDOG) += pcwd_usb.o
> >
> >   # ARM Architecture
> >   obj-$(CONFIG_ARM_SP805_WATCHDOG) += sp805_wdt.o
> > +obj-$(CONFIG_AT91_SAMA5D4_WATCHDOG) += at91_sama5d4_wdt.o
> >   obj-$(CONFIG_AT91RM9200_WATCHDOG) += at91rm9200_wdt.o
> >   obj-$(CONFIG_AT91SAM9X_WATCHDOG) += at91sam9_wdt.o
> >   obj-$(CONFIG_CADENCE_WATCHDOG) += cadence_wdt.o diff --git
> > a/drivers/watchdog/at91_sama5d4_wdt.c
> > b/drivers/watchdog/at91_sama5d4_wdt.c
> > new file mode 100644
> > index 0000000..f2e1995
> > --- /dev/null
> > +++ b/drivers/watchdog/at91_sama5d4_wdt.c
> > @@ -0,0 +1,279 @@
> > +/*
> > + * Driver for Atmel SAMA5D4 Watchdog Timer
> > + *
> > + * Copyright (C) 2015 Atmel Corporation
> > + *
> > + * Licensed under GPLv2.
> > + */
> > +
> > +#include <linux/interrupt.h>
> > +#include <linux/io.h>
> > +#include <linux/kernel.h>
> > +#include <linux/module.h>
> > +#include <linux/of.h>
> > +#include <linux/of_irq.h>
> > +#include <linux/platform_device.h>
> > +#include <linux/reboot.h>
> > +#include <linux/watchdog.h>
> > +
> > +#include "at91sam9_wdt.h"
> > +
> > +/* minimum and maximum watchdog timeout, in seconds */
> > +#define MIN_WDT_TIMEOUT		1
> > +#define MAX_WDT_TIMEOUT		16
> > +#define WDT_DEFAULT_TIMEOUT	MAX_WDT_TIMEOUT
> > +
> > +#define WDT_SEC2TICKS(s)	((s) ? (((s) << 8) - 1) : 0)
> > +
> > +struct atmel_wdt {
> 
> If you don't mind, please use "sama5d4" as prefix here and for function names.
> 
> > +	struct watchdog_device	wdd;
> > +	void __iomem		*reg_base;
> > +	u32	config;
> > +};
> > +
> > +static int wdt_timeout = WDT_DEFAULT_TIMEOUT; static bool nowayout =
> > +WATCHDOG_NOWAYOUT;
> > +
> > +module_param(wdt_timeout, int, 0);
> > +MODULE_PARM_DESC(wdt_timeout,
> > +	"Watchdog wdt_timeout in seconds. (default = "
> > +	__MODULE_STRING(WDT_DEFAULT_TIMEOUT) ")");
> > +
> > +module_param(nowayout, bool, 0);
> > +MODULE_PARM_DESC(nowayout,
> > +	"Watchdog cannot be stopped once started (default="
> > +	__MODULE_STRING(WATCHDOG_NOWAYOUT) ")");
> > +
> > +#define wdt_read(wdt, field) \
> > +	readl_relaxed((wdt)->reg_base + (field))
> > +
> > +#define wdt_write(wtd, field, val) \
> > +	writel_relaxed((val), (wdt)->reg_base + (field))
> > +
> > +static int atmel_wdt_start(struct watchdog_device *wdd) {
> > +	struct atmel_wdt *wdt = watchdog_get_drvdata(wdd);
> > +	u32 reg;
> > +
> > +	reg = wdt_read(wdt, AT91_WDT_MR);
> > +	reg &= ~AT91_WDT_WDDIS;
> > +	wdt_write(wdt, AT91_WDT_MR, reg);
> > +
> > +	return 0;
> > +}
> > +
> > +static int atmel_wdt_stop(struct watchdog_device *wdd) {
> > +	struct atmel_wdt *wdt = watchdog_get_drvdata(wdd);
> > +	u32 reg;
> > +
> > +	reg = wdt_read(wdt, AT91_WDT_MR);
> > +	reg |= AT91_WDT_WDDIS;
> > +	wdt_write(wdt, AT91_WDT_MR, reg);
> > +
> > +	return 0;
> > +}
> > +
> > +static int atmel_wdt_ping(struct watchdog_device *wdd) {
> > +	struct atmel_wdt *wdt = watchdog_get_drvdata(wdd);
> > +
> > +	wdt_write(wdt, AT91_WDT_CR, AT91_WDT_KEY |
> AT91_WDT_WDRSTT);
> > +
> > +	return 0;
> > +}
> > +
> > +static int atmel_wdt_set_timeout(struct watchdog_device *wdd,
> > +				 unsigned int timeout)
> > +{
> > +	struct atmel_wdt *wdt = watchdog_get_drvdata(wdd);
> > +	u32 value = WDT_SEC2TICKS(timeout);
> > +	u32 reg;
> > +
> > +	reg = wdt_read(wdt, AT91_WDT_MR);
> > +	reg &= ~AT91_WDT_WDV;
> > +	reg &= ~AT91_WDT_WDD;
> > +	reg |= AT91_WDT_SET_WDV(value);
> > +	reg |= AT91_WDT_SET_WDD(value);
> > +	wdt_write(wdt, AT91_WDT_MR, reg);
> > +
> > +	wdd->timeout = timeout;
> > +
> > +	return 0;
> > +}
> > +
> > +static const struct watchdog_info atmel_wdt_info = {
> > +	.options = WDIOF_SETTIMEOUT | WDIOF_MAGICCLOSE |
> WDIOF_KEEPALIVEPING,
> > +	.firmware_version = 0,
> 
> Unnecessary initialization.
> 
> > +	.identity = "Atmel SAMA5D4 Watchdog", };
> > +
> > +static struct watchdog_ops atmel_wdt_ops = {
> > +	.owner = THIS_MODULE,
> > +	.start = atmel_wdt_start,
> > +	.stop = atmel_wdt_stop,
> > +	.ping = atmel_wdt_ping,
> > +	.set_timeout = atmel_wdt_set_timeout, };
> > +
> > +static irqreturn_t atmel_wdt_irq_handler(int irq, void *dev_id) {
> > +	struct atmel_wdt *wdt = platform_get_drvdata(dev_id);
> > +
> > +	if (wdt_read(wdt, AT91_WDT_SR)) {
> > +		pr_crit("Atmel Watchdog Software Reset\n");
> > +		emergency_restart();
> > +		pr_crit("Reboot didn't ?????\n");
> > +	}
> > +
> > +	return IRQ_HANDLED;
> > +}
> > +
> > +static int of_atmel_wdt_init(struct device_node *np, struct atmel_wdt
> > +*wdt) {
> > +	const char *tmp;
> > +
> > +	wdt->config = AT91_WDT_WDDIS;
> > +
> > +	if (!of_property_read_string(np, "atmel,watchdog-type", &tmp) &&
> > +	    !strcmp(tmp, "software"))
> > +		wdt->config |= AT91_WDT_WDFIEN;
> > +	else
> > +		wdt->config |= AT91_WDT_WDRSTEN;
> > +
> > +	if (of_property_read_bool(np, "atmel,idle-halt"))
> > +		wdt->config |= AT91_WDT_WDIDLEHLT;
> > +
> > +	if (of_property_read_bool(np, "atmel,dbg-halt"))
> > +		wdt->config |= AT91_WDT_WDDBGHLT;
> > +
> > +	return 0;
> > +}
> > +
> > +static int atmel_wdt_init(struct atmel_wdt *wdt) {
> > +	struct watchdog_device *wdd = &wdt->wdd;
> > +	u32 value = WDT_SEC2TICKS(wdd->timeout);
> > +	u32 reg;
> > +
> > +	/*
> > +	 * Because the fields WDV and WDD must not be modified when the
> WDDIS
> > +	 * bit is set, so clear the WDDIS bit before writing the WDT_MR.
> > +	 */
> > +	reg = wdt_read(wdt, AT91_WDT_MR);
> > +	reg &= ~AT91_WDT_WDDIS;
> > +	wdt_write(wdt, AT91_WDT_MR, reg);
> > +
> > +	reg = wdt->config;
> > +	reg |= AT91_WDT_SET_WDD(value);
> > +	reg |= AT91_WDT_SET_WDV(value);
> > +
> > +	wdt_write(wdt, AT91_WDT_MR, reg);
> > +
> > +	return 0;
> > +}
> > +
> > +static int atmel_wdt_probe(struct platform_device *pdev) {
> > +	struct watchdog_device *wdd;
> > +	struct atmel_wdt *wdt;
> > +	struct resource *res;
> > +	void __iomem *regs;
> > +	int ret, irq = -1;
> 
> Might as well use irq = 0 here for consistency.
> 
> > +
> > +	wdt = devm_kzalloc(&pdev->dev, sizeof(*wdt), GFP_KERNEL);
> > +	if (!wdt)
> > +		return -ENOMEM;
> > +
> > +	wdd = &wdt->wdd;
> > +	wdd->timeout = wdt_timeout;
> > +	wdd->info = &atmel_wdt_info;
> > +	wdd->ops = &atmel_wdt_ops;
> > +	wdd->min_timeout = MIN_WDT_TIMEOUT;
> > +	wdd->max_timeout = MAX_WDT_TIMEOUT;
> > +
> > +	watchdog_set_drvdata(wdd, wdt);
> > +
> > +	res = platform_get_resource(pdev, IORESOURCE_MEM, 0);
> > +	regs = devm_ioremap_resource(&pdev->dev, res);
> > +	if (IS_ERR(regs))
> > +		return PTR_ERR(regs);
> > +
> > +	wdt->reg_base = regs;
> > +
> > +	if (pdev->dev.of_node) {
> > +		irq = irq_of_parse_and_map(pdev->dev.of_node, 0);
> > +		if (!irq)
> > +			dev_warn(&pdev->dev, "failed to get IRQ from DT\n");
> > +
> > +		ret = of_atmel_wdt_init(pdev->dev.of_node, wdt);
> > +		if (ret)
> > +			return ret;
> > +	}
> > +
> > +	if ((wdt->config & AT91_WDT_WDFIEN) && irq > 0) {
> 
> ... then you can check " ... && irq" here.
> 
> > +		ret = devm_request_irq(&pdev->dev, irq, atmel_wdt_irq_handler,
> > +				       0, pdev->name, pdev);
> > +		if (ret) {
> > +			dev_err(&pdev->dev,
> > +				"cannot register interrupt handler\n");
> > +			return ret;
> > +		}
> > +	}
> > +
> > +	ret = watchdog_init_timeout(wdd, wdt_timeout, &pdev->dev);
> > +	if (ret) {
> > +		dev_err(&pdev->dev, "unable to set timeout value\n");
> > +		return ret;
> > +	}
> > +
> > +	ret = atmel_wdt_init(wdt);
> > +	if (ret)
> > +		return ret;
> > +
> > +	watchdog_set_nowayout(wdd, nowayout);
> > +
> > +	ret = watchdog_register_device(wdd);
> > +	if (ret) {
> > +		dev_err(&pdev->dev, "failed to register watchdog device\n");
> > +		return ret;
> > +	}
> > +
> > +	platform_set_drvdata(pdev, wdt);
> > +
> > +	dev_info(&pdev->dev, "initialized (timeout = %d sec, nowayout = %d)\n",
> > +		 wdt_timeout, nowayout);
> > +
> > +	return 0;
> > +}
> > +
> > +static int atmel_wdt_remove(struct platform_device *pdev) {
> > +	struct atmel_wdt *wdt = platform_get_drvdata(pdev);
> > +
> > +	atmel_wdt_stop(&wdt->wdd);
> > +
> > +	watchdog_unregister_device(&wdt->wdd);
> > +
> > +	return 0;
> > +}
> > +
> > +static const struct of_device_id atmel_wdt_of_match[] = {
> > +	{ .compatible = "atmel,sama5d4-wdt", },
> > +	{ },
> > +};
> > +MODULE_DEVICE_TABLE(of, atmel_wdt_of_match);
> > +
> > +static struct platform_driver atmel_wdt_driver = {
> > +	.probe		= atmel_wdt_probe,
> > +	.remove		= atmel_wdt_remove,
> > +	.driver		= {
> > +		.name	= "sama5d4 wdt",
> > +		.of_match_table = atmel_wdt_of_match,
> > +	},
> > +};
> > +module_platform_driver(atmel_wdt_driver);
> > +
> > +MODULE_AUTHOR("Atmel Corporation");
> > +MODULE_DESCRIPTION("Atmel SAMA5D4 Watchdog Timer driver");
> > +MODULE_LICENSE("GPL v2");
> > diff --git a/drivers/watchdog/at91sam9_wdt.h
> > b/drivers/watchdog/at91sam9_wdt.h index c6fbb2e6..b79a83b 100644
> > --- a/drivers/watchdog/at91sam9_wdt.h
> > +++ b/drivers/watchdog/at91sam9_wdt.h
> > @@ -22,11 +22,13 @@
> >
> >   #define AT91_WDT_MR		0x04			/* Watchdog
> Mode Register */
> >   #define		AT91_WDT_WDV		(0xfff << 0)		/*
> Counter Value */
> > +#define			AT91_WDT_SET_WDV(x)	((x) &
> AT91_WDT_WDV)
> >   #define		AT91_WDT_WDFIEN		(1     << 12)		/*
> Fault Interrupt Enable */
> >   #define		AT91_WDT_WDRSTEN	(1     << 13)		/*
> Reset Processor */
> >   #define		AT91_WDT_WDRPROC	(1     << 14)		/*
> Timer Restart */
> >   #define		AT91_WDT_WDDIS		(1     << 15)		/*
> Watchdog Disable */
> >   #define		AT91_WDT_WDD		(0xfff << 16)		/*
> Delta Value */
> > +#define			AT91_WDT_SET_WDD(x)	(((x) << 16) &
> AT91_WDT_WDD)
> >   #define		AT91_WDT_WDDBGHLT	(1     << 28)		/*
> Debug Halt */
> >   #define		AT91_WDT_WDIDLEHLT	(1     << 29)		/*
> Idle Halt */
> >
> >
Best Regards,
Wenyou Yang

From axel.lin at ingics.com  Wed Aug  5 19:16:34 2015
From: axel.lin at ingics.com (Axel Lin)
Date: Thu, 06 Aug 2015 10:16:34 +0800
Subject: [PATCH RFT] ata: ahci_brcmstb: Fix misuse of IS_ENABLED
Message-ID: <1438827394.19066.1.camel@ingics.com>

While IS_ENABLED() is perfectly fine for CONFIG_* symbols, it is not
for other symbols such as __BIG_ENDIAN that is provided directly by
the compiler.

Signed-off-by: Axel Lin <axel.lin at ingics.com>
---
Hi,
I don't have a big endian machine to test this, so I'd appreciate if
someone can review and test this patch.

A similar misuse of IS_ENABLED is reported and fixed in:
https://git.kernel.org/cgit/linux/kernel/git/torvalds/linux.git/commit/drivers/dma/mv_xor.c?id=0ec9ebc706fbd394bc233d87ac7aaad1c4f3ab54

 drivers/ata/ahci_brcmstb.c | 18 ++++++++++--------
 1 file changed, 10 insertions(+), 8 deletions(-)

diff --git a/drivers/ata/ahci_brcmstb.c b/drivers/ata/ahci_brcmstb.c
index 42b6cf4..fc6413f 100644
--- a/drivers/ata/ahci_brcmstb.c
+++ b/drivers/ata/ahci_brcmstb.c
@@ -92,19 +92,21 @@ static inline u32 brcm_sata_readreg(void __iomem *addr)
 	 * Other architectures (e.g., ARM) either do not support big endian, or
 	 * else leave I/O in little endian mode.
 	 */
-	if (IS_ENABLED(CONFIG_MIPS) && IS_ENABLED(__BIG_ENDIAN))
-		return __raw_readl(addr);
-	else
-		return readl_relaxed(addr);
+#if defined(__BIG_ENDIAN) && IS_ENABLED(CONFIG_MIPS)
+	return __raw_readl(addr);
+#else
+	return readl_relaxed(addr);
+#endif
 }
 
 static inline void brcm_sata_writereg(u32 val, void __iomem *addr)
 {
 	/* See brcm_sata_readreg() comments */
-	if (IS_ENABLED(CONFIG_MIPS) && IS_ENABLED(__BIG_ENDIAN))
-		__raw_writel(val, addr);
-	else
-		writel_relaxed(val, addr);
+#if defined(__BIG_ENDIAN) && IS_ENABLED(CONFIG_MIPS)
+	__raw_writel(val, addr);
+#else
+	writel_relaxed(val, addr);
+#endif
 }
 
 static void brcm_sata_phy_enable(struct brcm_ahci_priv *priv, int port)
-- 
2.1.0





From ariel at vanguardiasur.com.ar  Wed Aug  5 19:31:45 2015
From: ariel at vanguardiasur.com.ar (Ariel D'Alessandro)
Date: Wed,  5 Aug 2015 23:31:45 -0300
Subject: [PATCH v2 0/2] Add support for NXP LPC18xx PWM/SCT
Message-ID: <1438828307-14641-1-git-send-email-ariel@vanguardiasur.com.ar>

This patch series adds support for NXP LPC18xx PWM/SCT.

NXP LPC SoCs family, which includes LPC18xx/LPC43xx, provides a State
Configurable Timer (SCT) which can be configured as a Pulse Width Modulator.
Other SoCs in that family may share the same hardware.

Patchset is based on tag next-20150723 of the linux-next repository.
It has been successfully tested on a Hitex LPC4350 Evaluation Board.

Changes since v1:
* Added "sct" in DT compatible string and driver's name.
* Allowed period changes when there's only one channel requested.

Ariel D'Alessandro (2):
  pwm: NXP LPC18xx PWM/SCT driver
  DT: pwm: Add NXP LPC18xx PWM/SCT binding documentation

 .../devicetree/bindings/pwm/lpc1850-sct-pwm.txt    |  20 +
 drivers/pwm/Kconfig                                |  12 +
 drivers/pwm/Makefile                               |   1 +
 drivers/pwm/pwm-lpc18xx-sct.c                      | 465 +++++++++++++++++++++
 4 files changed, 498 insertions(+)
 create mode 100644 Documentation/devicetree/bindings/pwm/lpc1850-sct-pwm.txt
 create mode 100644 drivers/pwm/pwm-lpc18xx-sct.c

-- 
1.9.1



From ariel at vanguardiasur.com.ar  Wed Aug  5 19:31:46 2015
From: ariel at vanguardiasur.com.ar (Ariel D'Alessandro)
Date: Wed,  5 Aug 2015 23:31:46 -0300
Subject: [PATCH v2 1/2] pwm: NXP LPC18xx PWM/SCT driver
In-Reply-To: <1438828307-14641-1-git-send-email-ariel@vanguardiasur.com.ar>
References: <1438828307-14641-1-git-send-email-ariel@vanguardiasur.com.ar>
Message-ID: <1438828307-14641-2-git-send-email-ariel@vanguardiasur.com.ar>

This commit adds support for NXP LPC18xx PWM/SCT.

NXP LPC SoCs family, which includes LPC18xx/LPC43xx, provides a State
Configurable Timer (SCT) which can be configured as a Pulse Width
Modulator. Other SoCs in that family may share the same hardware.

The PWM supports a total of 16 channels, but only 15 can be simultaneously
requested. There's only one period, global to all the channels, thus PWM
driver will refuse setting different values to it, unless there's only one
channel requested.

Signed-off-by: Ariel D'Alessandro <ariel at vanguardiasur.com.ar>
---
 drivers/pwm/Kconfig           |  12 ++
 drivers/pwm/Makefile          |   1 +
 drivers/pwm/pwm-lpc18xx-sct.c | 465 ++++++++++++++++++++++++++++++++++++++++++
 3 files changed, 478 insertions(+)
 create mode 100644 drivers/pwm/pwm-lpc18xx-sct.c

diff --git a/drivers/pwm/Kconfig b/drivers/pwm/Kconfig
index b1541f4..ac8b0e9 100644
--- a/drivers/pwm/Kconfig
+++ b/drivers/pwm/Kconfig
@@ -173,6 +173,18 @@ config PWM_LP3943
 	  To compile this driver as a module, choose M here: the module
 	  will be called pwm-lp3943.
 
+config PWM_LPC18XX_SCT
+	tristate "LPC18xx/43xx PWM/SCT support"
+	depends on ARCH_LPC18XX
+	help
+	  Generic PWM framework driver for NXP LPC18xx PWM/SCT which
+	  supports 16 channels.
+	  A maximum of 15 channels can be requested simultaneously and
+	  must have the same period.
+
+	  To compile this driver as a module, choose M here: the module
+	  will be called pwm-lpc18xx-sct.
+
 config PWM_LPC32XX
 	tristate "LPC32XX PWM support"
 	depends on ARCH_LPC32XX
diff --git a/drivers/pwm/Makefile b/drivers/pwm/Makefile
index ec50eb5..cd9abef 100644
--- a/drivers/pwm/Makefile
+++ b/drivers/pwm/Makefile
@@ -14,6 +14,7 @@ obj-$(CONFIG_PWM_IMG)		+= pwm-img.o
 obj-$(CONFIG_PWM_IMX)		+= pwm-imx.o
 obj-$(CONFIG_PWM_JZ4740)	+= pwm-jz4740.o
 obj-$(CONFIG_PWM_LP3943)	+= pwm-lp3943.o
+obj-$(CONFIG_PWM_LPC18XX_SCT)	+= pwm-lpc18xx-sct.o
 obj-$(CONFIG_PWM_LPC32XX)	+= pwm-lpc32xx.o
 obj-$(CONFIG_PWM_LPSS)		+= pwm-lpss.o
 obj-$(CONFIG_PWM_LPSS_PCI)	+= pwm-lpss-pci.o
diff --git a/drivers/pwm/pwm-lpc18xx-sct.c b/drivers/pwm/pwm-lpc18xx-sct.c
new file mode 100644
index 0000000..3e541fa
--- /dev/null
+++ b/drivers/pwm/pwm-lpc18xx-sct.c
@@ -0,0 +1,465 @@
+/*
+ * NXP LPC18xx State Configurable Timer - Pulse Width Modulator driver
+ *
+ * Copyright (c) 2015 Ariel D'Alessandro <ariel at vanguardiasur.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.
+ *
+ * Notes
+ * =====
+ * NXP LPC18xx provides a State Configurable Timer (SCT) which can be configured
+ * as a Pulse Width Modulator.
+ *
+ * SCT supports 16 outputs, 16 events and 16 registers. Each event will be
+ * triggered when its related register matches the SCT counter value, and it
+ * will set or clear a selected output.
+ *
+ * One of the events is preselected to generate the period, thus the maximum
+ * number of simultaneous channels is limited to 15. Notice that period is
+ * global to all the channels, thus PWM driver will refuse setting different
+ * values to it, unless there's only one channel requested.
+ */
+
+#include <linux/clk.h>
+#include <linux/err.h>
+#include <linux/io.h>
+#include <linux/module.h>
+#include <linux/platform_device.h>
+#include <linux/pwm.h>
+
+/* LPC18xx SCT registers */
+#define LPC18XX_PWM_CONFIG		0x000
+#define LPC18XX_PWM_CONFIG_UNIFY	BIT(0)
+#define LPC18XX_PWM_CONFIG_NORELOAD	BIT(7)
+
+#define LPC18XX_PWM_CTRL		0x004
+#define LPC18XX_PWM_CTRL_HALT		BIT(2)
+#define LPC18XX_PWM_BIDIR		BIT(4)
+#define LPC18XX_PWM_PRE_SHIFT		5
+#define LPC18XX_PWM_PRE_MASK		(0xff << LPC18XX_PWM_PRE_SHIFT)
+#define LPC18XX_PWM_PRE(x)		(x << LPC18XX_PWM_PRE_SHIFT)
+
+#define LPC18XX_PWM_LIMIT		0x008
+
+#define LPC18XX_PWM_RES_BASE		0x058
+#define LPC18XX_PWM_RES_SHIFT(_ch)	(_ch * 2)
+#define LPC18XX_PWM_RES(_ch, _action)	(_action << LPC18XX_PWM_RES_SHIFT(_ch))
+#define LPC18XX_PWM_RES_MASK(_ch)	(0x3 << LPC18XX_PWM_RES_SHIFT(_ch))
+
+#define LPC18XX_PWM_MATCH_BASE		0x100
+#define LPC18XX_PWM_MATCH(_ch)		(LPC18XX_PWM_MATCH_BASE + _ch * 4)
+
+#define LPC18XX_PWM_MATCHREL_BASE	0x200
+#define LPC18XX_PWM_MATCHREL(_ch)	(LPC18XX_PWM_MATCHREL_BASE + _ch * 4)
+
+#define LPC18XX_PWM_EVSTATEMSK_BASE	0x300
+#define LPC18XX_PWM_EVSTATEMSK(_ch)	(LPC18XX_PWM_EVSTATEMSK_BASE + _ch * 8)
+#define LPC18XX_PWM_EVSTATEMSK_ALL	0xffffffff
+
+#define LPC18XX_PWM_EVCTRL_BASE		0x304
+#define LPC18XX_PWM_EVCTRL(_ev)		(LPC18XX_PWM_EVCTRL_BASE + _ev * 8)
+
+#define LPC18XX_PWM_EVCTRL_MATCH(_ch)	_ch
+
+#define LPC18XX_PWM_EVCTRL_COMB_SHIFT	12
+#define LPC18XX_PWM_EVCTRL_COMB_MATCH	(0x1 << LPC18XX_PWM_EVCTRL_COMB_SHIFT)
+
+#define LPC18XX_PWM_OUTPUTSET_BASE	0x500
+#define LPC18XX_PWM_OUTPUTSET(_ch)	(LPC18XX_PWM_OUTPUTSET_BASE + _ch * 8)
+
+#define LPC18XX_PWM_OUTPUTCL_BASE	0x504
+#define LPC18XX_PWM_OUTPUTCL(_ch)	(LPC18XX_PWM_OUTPUTCL_BASE + _ch * 8)
+
+/* LPC18xx SCT unified counter */
+#define LPC18XX_PWM_TIMER_MAX		0xffffffff
+
+/* LPC18xx SCT events */
+#define LPC18XX_PWM_EVENT_PERIOD	0
+#define LPC18XX_PWM_EVENT_MAX		16
+
+/* SCT conflict resolution */
+enum lpc18xx_pwm_res_action {
+	LPC18XX_PWM_RES_NONE	= 0x0,
+	LPC18XX_PWM_RES_SET	= 0x1,
+	LPC18XX_PWM_RES_CLEAR	= 0x2,
+	LPC18XX_PWM_RES_TOGGLE	= 0x3,
+};
+
+struct lpc18xx_pwm_data {
+	unsigned int		duty_event;
+};
+
+struct lpc18xx_pwm_chip {
+	struct device		*dev;
+	struct pwm_chip		chip;
+	void __iomem		*base;
+	struct clk		*pwm_clk;
+	unsigned long		clk_rate;
+	unsigned int		period_ns;
+	unsigned int		min_period_ns;
+	unsigned int		max_period_ns;
+	unsigned int		period_event;
+	unsigned long		event_map;
+	struct mutex            res_lock;
+	struct mutex            period_lock;
+};
+
+static inline struct lpc18xx_pwm_chip *to_lpc18xx_pwm_chip(
+							struct pwm_chip *chip)
+{
+	return container_of(chip, struct lpc18xx_pwm_chip, chip);
+}
+
+static inline void lpc18xx_pwm_writel(struct lpc18xx_pwm_chip *lpc18xx_pwm,
+				      u32 reg, u32 val)
+{
+	writel(val, lpc18xx_pwm->base + reg);
+}
+
+static inline u32 lpc18xx_pwm_readl(struct lpc18xx_pwm_chip *lpc18xx_pwm,
+				    u32 reg)
+{
+	return readl(lpc18xx_pwm->base + reg);
+}
+
+static void lpc18xx_pwm_set_conflict_res(struct lpc18xx_pwm_chip *lpc18xx_pwm,
+					 struct pwm_device *pwm,
+					 enum lpc18xx_pwm_res_action action)
+{
+	u32 val;
+
+	mutex_lock(&lpc18xx_pwm->res_lock);
+
+	/*
+	 * Simultaneous set and clear may happen on an output, that is the case
+	 * when duty_ns == period_ns. LPC18xx SCT allows to set a conflict
+	 * resolution action to be taken in such a case.
+	 */
+	val = lpc18xx_pwm_readl(lpc18xx_pwm, LPC18XX_PWM_RES_BASE);
+	val &= ~LPC18XX_PWM_RES_MASK(pwm->hwpwm);
+	val |= LPC18XX_PWM_RES(pwm->hwpwm, action);
+	lpc18xx_pwm_writel(lpc18xx_pwm, LPC18XX_PWM_RES_BASE, val);
+
+	mutex_unlock(&lpc18xx_pwm->res_lock);
+}
+
+static void lpc18xx_pwm_config_period(struct pwm_chip *chip, int period_ns)
+{
+	struct lpc18xx_pwm_chip *lpc18xx_pwm = to_lpc18xx_pwm_chip(chip);
+	u64 val;
+
+	val = (u64)period_ns * lpc18xx_pwm->clk_rate;
+	do_div(val, NSEC_PER_SEC);
+
+	lpc18xx_pwm_writel(lpc18xx_pwm,
+			   LPC18XX_PWM_MATCH(lpc18xx_pwm->period_event),
+			   (u32)val - 1);
+
+	lpc18xx_pwm_writel(lpc18xx_pwm,
+			   LPC18XX_PWM_MATCHREL(lpc18xx_pwm->period_event),
+			   (u32)val - 1);
+}
+
+static void lpc18xx_pwm_config_duty(struct pwm_chip *chip,
+				    struct pwm_device *pwm, int duty_ns)
+{
+	struct lpc18xx_pwm_chip *lpc18xx_pwm = to_lpc18xx_pwm_chip(chip);
+	struct lpc18xx_pwm_data *lpc18xx_data = pwm_get_chip_data(pwm);
+	u64 val;
+
+	val = (u64)duty_ns * lpc18xx_pwm->clk_rate;
+	do_div(val, NSEC_PER_SEC);
+
+	lpc18xx_pwm_writel(lpc18xx_pwm,
+			   LPC18XX_PWM_MATCH(lpc18xx_data->duty_event),
+			   (u32)val);
+
+	lpc18xx_pwm_writel(lpc18xx_pwm,
+			   LPC18XX_PWM_MATCHREL(lpc18xx_data->duty_event),
+			   (u32)val);
+}
+
+static int lpc18xx_pwm_config(struct pwm_chip *chip, struct pwm_device *pwm,
+			      int duty_ns, int period_ns)
+{
+	struct lpc18xx_pwm_chip *lpc18xx_pwm = to_lpc18xx_pwm_chip(chip);
+	int requested_events, i;
+
+	if (period_ns < lpc18xx_pwm->min_period_ns ||
+	    period_ns > lpc18xx_pwm->max_period_ns) {
+		dev_err(chip->dev, "period %d not in range\n", period_ns);
+		return -ERANGE;
+	}
+
+	mutex_lock(&lpc18xx_pwm->period_lock);
+
+	requested_events = bitmap_weight(&lpc18xx_pwm->event_map,
+					 LPC18XX_PWM_EVENT_MAX);
+
+	/*
+	 * The PWM supports only a single period for all PWM channels.
+	 * Once the period is set, it can only be changed if no more than one
+	 * channel is requested at that moment.
+	 */
+	if (requested_events > 2 && lpc18xx_pwm->period_ns != period_ns &&
+	    lpc18xx_pwm->period_ns) {
+		dev_err(chip->dev, "conflicting period requested for PWM %u\n",
+			pwm->hwpwm);
+		mutex_unlock(&lpc18xx_pwm->period_lock);
+		return -EBUSY;
+	}
+
+	if ((requested_events <= 2 && lpc18xx_pwm->period_ns != period_ns) ||
+	    !lpc18xx_pwm->period_ns) {
+		lpc18xx_pwm->period_ns = period_ns;
+		for (i = 0; i < chip->npwm; i++)
+			pwm_set_period(&chip->pwms[i], period_ns);
+		lpc18xx_pwm_config_period(chip, period_ns);
+	}
+
+	mutex_unlock(&lpc18xx_pwm->period_lock);
+
+	lpc18xx_pwm_config_duty(chip, pwm, duty_ns);
+
+	return 0;
+}
+
+static int lpc18xx_pwm_set_polarity(struct pwm_chip *chip,
+				    struct pwm_device *pwm,
+				    enum pwm_polarity polarity)
+{
+	return 0;
+}
+
+static int lpc18xx_pwm_enable(struct pwm_chip *chip, struct pwm_device *pwm)
+{
+	struct lpc18xx_pwm_chip *lpc18xx_pwm = to_lpc18xx_pwm_chip(chip);
+	struct lpc18xx_pwm_data *lpc18xx_data = pwm_get_chip_data(pwm);
+	enum lpc18xx_pwm_res_action res_action;
+	unsigned int set_event, clear_event;
+
+	lpc18xx_pwm_writel(lpc18xx_pwm,
+			   LPC18XX_PWM_EVCTRL(lpc18xx_data->duty_event),
+			   LPC18XX_PWM_EVCTRL_MATCH(lpc18xx_data->duty_event) |
+			   LPC18XX_PWM_EVCTRL_COMB_MATCH);
+
+	lpc18xx_pwm_writel(lpc18xx_pwm,
+			   LPC18XX_PWM_EVSTATEMSK(lpc18xx_data->duty_event),
+			   LPC18XX_PWM_EVSTATEMSK_ALL);
+
+	if (pwm->polarity == PWM_POLARITY_NORMAL) {
+		set_event = lpc18xx_pwm->period_event;
+		clear_event = lpc18xx_data->duty_event;
+		res_action = LPC18XX_PWM_RES_SET;
+	} else {
+		set_event = lpc18xx_data->duty_event;
+		clear_event = lpc18xx_pwm->period_event;
+		res_action = LPC18XX_PWM_RES_CLEAR;
+	}
+
+	lpc18xx_pwm_writel(lpc18xx_pwm, LPC18XX_PWM_OUTPUTSET(pwm->hwpwm),
+			   BIT(set_event));
+	lpc18xx_pwm_writel(lpc18xx_pwm, LPC18XX_PWM_OUTPUTCL(pwm->hwpwm),
+			   BIT(clear_event));
+	lpc18xx_pwm_set_conflict_res(lpc18xx_pwm, pwm, res_action);
+
+	return 0;
+}
+
+static void lpc18xx_pwm_disable(struct pwm_chip *chip, struct pwm_device *pwm)
+{
+	struct lpc18xx_pwm_chip *lpc18xx_pwm = to_lpc18xx_pwm_chip(chip);
+	struct lpc18xx_pwm_data *lpc18xx_data = pwm_get_chip_data(pwm);
+
+	lpc18xx_pwm_writel(lpc18xx_pwm,
+			   LPC18XX_PWM_EVCTRL(lpc18xx_data->duty_event), 0);
+	lpc18xx_pwm_writel(lpc18xx_pwm, LPC18XX_PWM_OUTPUTSET(pwm->hwpwm), 0);
+	lpc18xx_pwm_writel(lpc18xx_pwm, LPC18XX_PWM_OUTPUTCL(pwm->hwpwm), 0);
+}
+
+static int lpc18xx_pwm_request(struct pwm_chip *chip, struct pwm_device *pwm)
+{
+	struct lpc18xx_pwm_chip *lpc18xx_pwm = to_lpc18xx_pwm_chip(chip);
+	struct lpc18xx_pwm_data *lpc18xx_data = pwm_get_chip_data(pwm);
+	unsigned long event;
+
+	event = find_first_zero_bit(&lpc18xx_pwm->event_map,
+				    LPC18XX_PWM_EVENT_MAX);
+
+	if (event >= LPC18XX_PWM_EVENT_MAX) {
+		dev_err(lpc18xx_pwm->dev,
+			"maximum number of simultaneous channels reached\n");
+		return -EBUSY;
+	};
+
+	set_bit(event, &lpc18xx_pwm->event_map);
+	lpc18xx_data->duty_event = event;
+	lpc18xx_pwm_config_duty(chip, pwm, pwm_get_duty_cycle(pwm));
+
+	return 0;
+}
+
+static void lpc18xx_pwm_free(struct pwm_chip *chip, struct pwm_device *pwm)
+{
+	struct lpc18xx_pwm_chip *lpc18xx_pwm = to_lpc18xx_pwm_chip(chip);
+	struct lpc18xx_pwm_data *lpc18xx_data = pwm_get_chip_data(pwm);
+
+	pwm_disable(pwm);
+	pwm_set_duty_cycle(pwm, 0);
+	clear_bit(lpc18xx_data->duty_event, &lpc18xx_pwm->event_map);
+}
+
+static const struct pwm_ops lpc18xx_pwm_ops = {
+	.config		= lpc18xx_pwm_config,
+	.set_polarity	= lpc18xx_pwm_set_polarity,
+	.enable		= lpc18xx_pwm_enable,
+	.disable	= lpc18xx_pwm_disable,
+	.request	= lpc18xx_pwm_request,
+	.free		= lpc18xx_pwm_free,
+	.owner		= THIS_MODULE,
+};
+
+static const struct of_device_id lpc18xx_pwm_of_match[] = {
+	{ .compatible = "nxp,lpc1850-sct-pwm" },
+	{}
+};
+MODULE_DEVICE_TABLE(of, lpc18xx_pwm_of_match);
+
+static int lpc18xx_pwm_probe(struct platform_device *pdev)
+{
+	struct lpc18xx_pwm_chip *lpc18xx_pwm;
+	struct pwm_device *pwm;
+	struct resource *res;
+	int ret, i;
+	u64 val;
+
+	lpc18xx_pwm = devm_kzalloc(&pdev->dev, sizeof(*lpc18xx_pwm),
+				   GFP_KERNEL);
+	if (!lpc18xx_pwm)
+		return -ENOMEM;
+
+	lpc18xx_pwm->dev = &pdev->dev;
+
+	res = platform_get_resource(pdev, IORESOURCE_MEM, 0);
+	lpc18xx_pwm->base = devm_ioremap_resource(&pdev->dev, res);
+	if (IS_ERR(lpc18xx_pwm->base))
+		return PTR_ERR(lpc18xx_pwm->base);
+
+	lpc18xx_pwm->pwm_clk = devm_clk_get(&pdev->dev, "pwm");
+	if (IS_ERR(lpc18xx_pwm->pwm_clk)) {
+		dev_err(&pdev->dev, "failed to get pwm clock\n");
+		return PTR_ERR(lpc18xx_pwm->pwm_clk);
+	}
+
+	ret = clk_prepare_enable(lpc18xx_pwm->pwm_clk);
+	if (ret < 0) {
+		dev_err(&pdev->dev, "could not prepare or enable pwm clock\n");
+		return ret;
+	}
+
+	lpc18xx_pwm->clk_rate = clk_get_rate(lpc18xx_pwm->pwm_clk);
+
+	mutex_init(&lpc18xx_pwm->res_lock);
+	mutex_init(&lpc18xx_pwm->period_lock);
+
+	val = (u64)NSEC_PER_SEC * LPC18XX_PWM_TIMER_MAX;
+	do_div(val, lpc18xx_pwm->clk_rate);
+	lpc18xx_pwm->max_period_ns = val;
+
+	lpc18xx_pwm->min_period_ns = DIV_ROUND_UP(NSEC_PER_SEC,
+						  lpc18xx_pwm->clk_rate);
+
+	lpc18xx_pwm->chip.dev = &pdev->dev;
+	lpc18xx_pwm->chip.ops = &lpc18xx_pwm_ops;
+	lpc18xx_pwm->chip.base = -1;
+	lpc18xx_pwm->chip.npwm = 16;
+	lpc18xx_pwm->chip.of_xlate = of_pwm_xlate_with_flags;
+	lpc18xx_pwm->chip.of_pwm_n_cells = 3;
+
+	/* SCT counter must be in unify (32 bit) mode */
+	lpc18xx_pwm_writel(lpc18xx_pwm, LPC18XX_PWM_CONFIG,
+			   LPC18XX_PWM_CONFIG_UNIFY);
+
+	/*
+	 * Everytime the timer counter reaches the period value, the related
+	 * event will be triggered and the counter reset to 0.
+	 */
+	set_bit(LPC18XX_PWM_EVENT_PERIOD, &lpc18xx_pwm->event_map);
+	lpc18xx_pwm->period_event = LPC18XX_PWM_EVENT_PERIOD;
+
+	lpc18xx_pwm_writel(lpc18xx_pwm,
+			   LPC18XX_PWM_EVSTATEMSK(lpc18xx_pwm->period_event),
+			   LPC18XX_PWM_EVSTATEMSK_ALL);
+
+	val = LPC18XX_PWM_EVCTRL_MATCH(lpc18xx_pwm->period_event) |
+	      LPC18XX_PWM_EVCTRL_COMB_MATCH;
+	lpc18xx_pwm_writel(lpc18xx_pwm,
+			   LPC18XX_PWM_EVCTRL(lpc18xx_pwm->period_event), val);
+
+	lpc18xx_pwm_writel(lpc18xx_pwm, LPC18XX_PWM_LIMIT,
+			   BIT(lpc18xx_pwm->period_event));
+
+	ret = pwmchip_add(&lpc18xx_pwm->chip);
+	if (ret < 0) {
+		dev_err(&pdev->dev, "pwmchip_add failed: %d\n", ret);
+		goto disable_pwmclk;
+	}
+
+	for (i = 0; i < lpc18xx_pwm->chip.npwm; i++) {
+		pwm = &lpc18xx_pwm->chip.pwms[i];
+		pwm->chip_data = devm_kzalloc(lpc18xx_pwm->dev,
+					      sizeof(struct lpc18xx_pwm_data),
+					      GFP_KERNEL);
+		if (!pwm->chip_data) {
+			ret = -ENOMEM;
+			goto remove_pwmchip;
+		}
+	}
+
+	platform_set_drvdata(pdev, lpc18xx_pwm);
+
+	val = lpc18xx_pwm_readl(lpc18xx_pwm, LPC18XX_PWM_CTRL);
+	val &= ~LPC18XX_PWM_BIDIR;
+	val &= ~LPC18XX_PWM_CTRL_HALT;
+	val &= ~LPC18XX_PWM_PRE_MASK;
+	val |= LPC18XX_PWM_PRE(0);
+	lpc18xx_pwm_writel(lpc18xx_pwm, LPC18XX_PWM_CTRL, val);
+
+	return 0;
+
+remove_pwmchip:
+	pwmchip_remove(&lpc18xx_pwm->chip);
+disable_pwmclk:
+	clk_disable_unprepare(lpc18xx_pwm->pwm_clk);
+	return ret;
+}
+
+static int lpc18xx_pwm_remove(struct platform_device *pdev)
+{
+	struct lpc18xx_pwm_chip *lpc18xx_pwm = platform_get_drvdata(pdev);
+	u32 val;
+
+	val = lpc18xx_pwm_readl(lpc18xx_pwm, LPC18XX_PWM_CTRL);
+	lpc18xx_pwm_writel(lpc18xx_pwm, LPC18XX_PWM_CTRL,
+			   val | LPC18XX_PWM_CTRL_HALT);
+
+	clk_disable_unprepare(lpc18xx_pwm->pwm_clk);
+
+	return pwmchip_remove(&lpc18xx_pwm->chip);
+}
+
+static struct platform_driver lpc18xx_pwm_driver = {
+	.driver = {
+		.name = "lpc18xx-sct-pwm",
+		.of_match_table = lpc18xx_pwm_of_match,
+	},
+	.probe = lpc18xx_pwm_probe,
+	.remove = lpc18xx_pwm_remove,
+};
+module_platform_driver(lpc18xx_pwm_driver);
+
+MODULE_AUTHOR("Ariel D'Alessandro <ariel at vanguardiasur.com.ar>");
+MODULE_DESCRIPTION("NXP LPC18xx PWM driver");
+MODULE_LICENSE("GPL v2");
-- 
1.9.1



From ariel at vanguardiasur.com.ar  Wed Aug  5 19:31:47 2015
From: ariel at vanguardiasur.com.ar (Ariel D'Alessandro)
Date: Wed,  5 Aug 2015 23:31:47 -0300
Subject: [PATCH v2 2/2] DT: pwm: Add NXP LPC18xx PWM/SCT binding documentation
In-Reply-To: <1438828307-14641-1-git-send-email-ariel@vanguardiasur.com.ar>
References: <1438828307-14641-1-git-send-email-ariel@vanguardiasur.com.ar>
Message-ID: <1438828307-14641-3-git-send-email-ariel@vanguardiasur.com.ar>

Add the devicetree binding document for NXP LPC18xx PWM/SCT.

Signed-off-by: Ariel D'Alessandro <ariel at vanguardiasur.com.ar>
---
 .../devicetree/bindings/pwm/lpc1850-sct-pwm.txt      | 20 ++++++++++++++++++++
 1 file changed, 20 insertions(+)
 create mode 100644 Documentation/devicetree/bindings/pwm/lpc1850-sct-pwm.txt

diff --git a/Documentation/devicetree/bindings/pwm/lpc1850-sct-pwm.txt b/Documentation/devicetree/bindings/pwm/lpc1850-sct-pwm.txt
new file mode 100644
index 0000000..36e49d4
--- /dev/null
+++ b/Documentation/devicetree/bindings/pwm/lpc1850-sct-pwm.txt
@@ -0,0 +1,20 @@
+* NXP LPC18xx State Configurable Timer - Pulse Width Modulator driver
+
+Required properties:
+  - compatible: Should be "nxp,lpc1850-sct-pwm"
+  - reg: Should contain physical base address and length of pwm registers.
+  - clocks: Must contain an entry for each entry in clock-names.
+    See ../clock/clock-bindings.txt for details.
+  - clock-names: Must include the following entries.
+    - pwm: PWM operating clock.
+  - #pwm-cells: Should be 3. See pwm.txt in this directory for the description
+    of the cells format.
+
+Example:
+  pwm: pwm at 40000000 {
+    compatible = "nxp,lpc1850-sct-pwm";
+    reg = <0x40000000 0x1000>;
+    clocks =<&ccu1 CLK_CPU_SCT>;
+    clock-names = "pwm";
+    #pwm-cells = <3>;
+  };
-- 
1.9.1



From scott.shu at mediatek.com  Wed Aug  5 19:59:02 2015
From: scott.shu at mediatek.com (Scott Shu)
Date: Thu, 6 Aug 2015 10:59:02 +0800
Subject: [PATCH v3 3/8] soc: Mediatek: Add SCPSYS CPU power domain driver
In-Reply-To: <20150805085034.GG18700@pengutronix.de>
References: <1438696464-59858-1-git-send-email-scott.shu@mediatek.com>
 <1438696464-59858-4-git-send-email-scott.shu@mediatek.com>
 <20150805085034.GG18700@pengutronix.de>
Message-ID: <1438829942.9435.24.camel@mtkswgap22>

On Wed, 2015-08-05 at 10:50 +0200, Sascha Hauer wrote:
> On Tue, Aug 04, 2015 at 09:54:19PM +0800, Scott Shu wrote:
> > This adds a CPU power domain driver for the Mediatek SCPSYS unit on
> > MT6580.
> > 
> > Signed-off-by: Scott Shu <scott.shu at mediatek.com>
> > ---
> >  drivers/soc/mediatek/mtk-scpsys.c   |  250 +++++++++++++++++++++++++++++++++++
> >  include/linux/soc/mediatek/scpsys.h |    9 ++
> >  2 files changed, 259 insertions(+)
> >  create mode 100644 include/linux/soc/mediatek/scpsys.h
> > 
> > diff --git a/drivers/soc/mediatek/mtk-scpsys.c b/drivers/soc/mediatek/mtk-scpsys.c
> > index 43a79ed..ca0f2dd 100644
> > --- a/drivers/soc/mediatek/mtk-scpsys.c
> > +++ b/drivers/soc/mediatek/mtk-scpsys.c
> > @@ -15,18 +15,30 @@
> >  #include <linux/io.h>
> >  #include <linux/kernel.h>
> >  #include <linux/mfd/syscon.h>
> > +#include <linux/of.h>
> >  #include <linux/of_device.h>
> > +#include <linux/of_address.h>
> >  #include <linux/platform_device.h>
> >  #include <linux/pm_domain.h>
> >  #include <linux/regmap.h>
> >  #include <linux/soc/mediatek/infracfg.h>
> > +#include <linux/soc/mediatek/scpsys.h>
> >  #include <dt-bindings/power/mt8173-power.h>
> >  
> > +#define SPM_POWERON_CONFIG_SET		0x0000
> > +#define SPM_CA7_CPU0_PWR_CON		0x0200
> >  #define SPM_VDE_PWR_CON			0x0210
> >  #define SPM_MFG_PWR_CON			0x0214
> > +#define SPM_CA7_CPU1_PWR_CON		0x0218
> > +#define SPM_CA7_CPU2_PWR_CON		0x021c
> > +#define SPM_CA7_CPU3_PWR_CON		0x0220
> >  #define SPM_VEN_PWR_CON			0x0230
> >  #define SPM_ISP_PWR_CON			0x0238
> >  #define SPM_DIS_PWR_CON			0x023c
> > +#define SPM_CA7_CPU0_L1_PDN		0x025c
> > +#define SPM_CA7_CPU1_L1_PDN		0x0264
> > +#define SPM_CA7_CPU2_L1_PDN		0x026c
> > +#define SPM_CA7_CPU3_L1_PDN		0x0274
> >  #define SPM_VEN2_PWR_CON		0x0298
> >  #define SPM_AUDIO_PWR_CON		0x029c
> >  #define SPM_MFG_2D_PWR_CON		0x02c0
> > @@ -34,12 +46,20 @@
> >  #define SPM_USB_PWR_CON			0x02cc
> >  #define SPM_PWR_STATUS			0x060c
> >  #define SPM_PWR_STATUS_2ND		0x0610
> > +#define SPM_SLEEP_TIMER_STA		0x0720
> >  
> > +/* bit definition in SPM_CA7_CPUx_PWR_CON */
> >  #define PWR_RST_B_BIT			BIT(0)
> >  #define PWR_ISO_BIT			BIT(1)
> >  #define PWR_ON_BIT			BIT(2)
> >  #define PWR_ON_2ND_BIT			BIT(3)
> >  #define PWR_CLK_DIS_BIT			BIT(4)
> > +#define SRAM_CKISO_BIT			BIT(5)
> > +#define SRAM_ISOINT_B_BIT		BIT(6)
> > +
> > +/* bit definition in SPM_CA7_CPUx_L1_PDN */
> > +#define L1_PDN				BIT(0)
> > +#define L1_PDN_ACK			BIT(8)
> >  
> >  #define PWR_STATUS_DISP			BIT(3)
> >  #define PWR_STATUS_MFG			BIT(4)
> > @@ -52,6 +72,28 @@
> >  #define PWR_STATUS_AUDIO		BIT(24)
> >  #define PWR_STATUS_USB			BIT(25)
> >  
> > +#define MT6580_MAX_CPUS			4
> > +
> > +#ifdef CONFIG_SMP
> > +static DEFINE_SPINLOCK(spm_cpu_lock);
> > +
> > +static void __iomem *spm_cpu_base;
> > +
> > +static const u32 spm_cpu_pwr_con[MT6580_MAX_CPUS] = {
> > +	SPM_CA7_CPU0_PWR_CON,
> > +	SPM_CA7_CPU1_PWR_CON,
> > +	SPM_CA7_CPU2_PWR_CON,
> > +	SPM_CA7_CPU3_PWR_CON,
> > +};
> > +
> > +static const u32 spm_cpu_l1_pdn[MT6580_MAX_CPUS] = {
> > +	SPM_CA7_CPU0_L1_PDN,
> > +	SPM_CA7_CPU1_L1_PDN,
> > +	SPM_CA7_CPU2_L1_PDN,
> > +	SPM_CA7_CPU3_L1_PDN,
> > +};
> > +#endif
> > +
> >  enum clk_id {
> >  	MT8173_CLK_MM,
> >  	MT8173_CLK_MFG,
> > @@ -485,3 +527,211 @@ static struct platform_driver scpsys_drv = {
> >  };
> >  
> >  module_platform_driver_probe(scpsys_drv, scpsys_probe);
> > +
> > +#define SPM_REGWR_EN		BIT(0)
> > +#define SPM_PROJECT_CODE	0x0B16
> > +
> > +#ifdef CONFIG_SMP
> > +int spm_cpu_mtcmos_on(int cpu)
> 
> The idea was that the code that the current driver has in
> scpsys_power_on/scpsys_power_off is shared with this function. If we
> don't do this then it indeed doesn't make much sense to put it into the
> same file.
> 
> From what I see we would need to change the prototype to something like
> 
> static int __scpsys_power_on(struct scp_domain_data *)
> 
> (maybe with some additional base addresses and stuff)
> 
> struct scp_domain_data would additionally need sram_isoint_b and sram_ckiso
> members.
> 
> Sascha
> 
Hi Sascha,
   The CPU power sequence is quite different with the others, as
described below.

* Non-CPU
   1) Set PWR_ON_BIT, PWR_ON_2ND_BIT
   2) Wait PWR_ACK
   3) Clear PWR_CLK_DIS_BIT
   4) Clear PWR_ISO_BIT
   5) Set PWR_RST_B_BIT
   6) Clear SRAM_PDN
   7) Wait SRAM_PDN_ACK
* CPU
   1) Set PWR_ON_BIT, PWR_ON_2ND_BIT
   2) Wait PWR_ACK
   3) Clear PWR_ISO_BIT
   4) Clear L1_PDN to power on L1
   5) Wait L1_PDN_ACK
   6) Set SRAM_ISOINT_B
   7) Clear SRAM_CKISO
   8) Clear PWR_CLK_DIS
   9) Set PWR_RST_B
For multi-cluster SoC, the cluster power sequence is also different.

Please think if this is a good idea if we integrate the CPU support into
the scpsys_power_on()? Based on the readability and compatible
considerations, we provide this patch. 
Thanks
Scott



From robh at kernel.org  Wed Aug  5 20:01:01 2015
From: robh at kernel.org (Rob Herring)
Date: Wed, 5 Aug 2015 22:01:01 -0500
Subject: [PATCH 6/9] ARM: domain: Add platform handlers for CPU PM domains
In-Reply-To: <20150805192341.GB52339@linaro.org>
References: <1438731339-58317-1-git-send-email-lina.iyer@linaro.org>
 <1438731339-58317-7-git-send-email-lina.iyer@linaro.org>
 <CAL_JsqKWekSGiFbZz6++3ibAzY_8Y6+0nOBQinFVw4cBk6JvEw@mail.gmail.com>
 <20150805192341.GB52339@linaro.org>
Message-ID: <CAL_JsqJ_AK6M5WmyFrGVLtpGg=MdAafxX=1873Je_uB_sQkpiA@mail.gmail.com>

On Wed, Aug 5, 2015 at 2:23 PM, Lina Iyer <lina.iyer at linaro.org> wrote:
> On Wed, Aug 05 2015 at 08:45 -0600, Rob Herring wrote:
>>
>> On Tue, Aug 4, 2015 at 6:35 PM, Lina Iyer <lina.iyer at linaro.org> wrote:
>>>
>>> In addition to the common power up/down actions of CPU PM domain core,
>>> platforms may have additional configuration before the CPU domain can be
>>> powered off or considered active. Allow platform drivers to register
>>> handlers for CPU PM domains.
>>>
>>> Platform drivers may register their callbacks against a compatible
>>> string defined by their PM domain provider device node in the DT. At
>>> domain init, the platform driver can initialize the platform specific
>>> genpd attributes. The init callback would need to return successfully,
>>> for the platform power_on/off handlers to be registered with the CPU PM
>>> domain.
>>>
>>> The code uses __init section to reduce memory needed for platform
>>> handlers and therefore can be freed after the driver is initialized, a
>>> desirable outcome for single kernel image.
>>
>>
>> [...]
>>
>>> diff --git a/arch/arm/include/asm/arm-pd.h
>>> b/arch/arm/include/asm/arm-pd.h
>>> new file mode 100644
>>> index 0000000..fc44abf
>
>
> [...]
>
>>> +#define ARM_PD_METHOD_OF_DECLARE(_name, _handle, _ops) \
>>> +       static const struct of_arm_pd_method
>>> __arm_pd_method_of_table_##_name \
>>> +       __used __section(__arm_pd_method_of_table)              \
>>> +       = { .handle = _handle, .ops = _ops }
>>
>>
>> AFAICT, you are not using this in this series. You should add it when
>> you have a user.
>>
>> Ideally, we keep some amount of uniformity across various *_OF_DECLARE
>> which is why we have OF_DECLARE_1 and OF_DECLARE_2. This makes all the
>> sections just arrays of struct of_device_id. Not all users follow
>> this, but most do. So instead of putting the ops in here, platforms
>> can provide a function callback which can then set the ops. Then you
>> also don't need the .init() ops function as the callback function can
>> do any initialization too.
>>
> I looked through these and I can switch over to _OF_DECLARE() without any
> issues, but using OF_DECLARE_1 or OF_DECLARE_2 is pretty limiting.

Well yes, but then we only want to use it for things that will never
use the driver model.

> If I could set up my own function type for the .data member, then its a
> lot more easier on the code. Like this -
>
> typedef int (*arm_pd_init)(struct device_node *dn, struct
>                 generic_pm_domain *genpd, struct of_arm_pd_ops *ops);

You alloc the genpd struct just before calling init. You can just as
easily have the platform specific code call an allocation function and
a function to set the ops functions. This is more inline with how a
driver would work when registering with a subsystem. I also don't
think "arm,pd" is a good compatible string to be matching on. I'll
comment on that more in patch 5.

Rob


From f.fainelli at gmail.com  Wed Aug  5 20:12:10 2015
From: f.fainelli at gmail.com (Florian Fainelli)
Date: Wed, 05 Aug 2015 20:12:10 -0700
Subject: [PATCH RFT] ata: ahci_brcmstb: Fix misuse of IS_ENABLED
In-Reply-To: <1438827394.19066.1.camel@ingics.com>
References: <1438827394.19066.1.camel@ingics.com>
Message-ID: <55C2D08A.1040408@gmail.com>

Le 08/05/15 19:16, Axel Lin a ?crit :
> While IS_ENABLED() is perfectly fine for CONFIG_* symbols, it is not
> for other symbols such as __BIG_ENDIAN that is provided directly by
> the compiler.
> 
> Signed-off-by: Axel Lin <axel.lin at ingics.com>
> ---
> Hi,
> I don't have a big endian machine to test this, so I'd appreciate if
> someone can review and test this patch.
> 
> A similar misuse of IS_ENABLED is reported and fixed in:
> https://git.kernel.org/cgit/linux/kernel/git/torvalds/linux.git/commit/drivers/dma/mv_xor.c?id=0ec9ebc706fbd394bc233d87ac7aaad1c4f3ab54

Would not CONFIG_CPU_BIG_ENDIAN be more appropriate here? On MIPS at
least, this is what gets set when selecting a big-endian kernel.

Thanks!

> 
>  drivers/ata/ahci_brcmstb.c | 18 ++++++++++--------
>  1 file changed, 10 insertions(+), 8 deletions(-)
> 
> diff --git a/drivers/ata/ahci_brcmstb.c b/drivers/ata/ahci_brcmstb.c
> index 42b6cf4..fc6413f 100644
> --- a/drivers/ata/ahci_brcmstb.c
> +++ b/drivers/ata/ahci_brcmstb.c
> @@ -92,19 +92,21 @@ static inline u32 brcm_sata_readreg(void __iomem *addr)
>  	 * Other architectures (e.g., ARM) either do not support big endian, or
>  	 * else leave I/O in little endian mode.
>  	 */
> -	if (IS_ENABLED(CONFIG_MIPS) && IS_ENABLED(__BIG_ENDIAN))
> -		return __raw_readl(addr);
> -	else
> -		return readl_relaxed(addr);
> +#if defined(__BIG_ENDIAN) && IS_ENABLED(CONFIG_MIPS)
> +	return __raw_readl(addr);
> +#else
> +	return readl_relaxed(addr);
> +#endif
>  }
>  
>  static inline void brcm_sata_writereg(u32 val, void __iomem *addr)
>  {
>  	/* See brcm_sata_readreg() comments */
> -	if (IS_ENABLED(CONFIG_MIPS) && IS_ENABLED(__BIG_ENDIAN))
> -		__raw_writel(val, addr);
> -	else
> -		writel_relaxed(val, addr);
> +#if defined(__BIG_ENDIAN) && IS_ENABLED(CONFIG_MIPS)
> +	__raw_writel(val, addr);
> +#else
> +	writel_relaxed(val, addr);
> +#endif
>  }
>  
>  static void brcm_sata_phy_enable(struct brcm_ahci_priv *priv, int port)
> 


-- 
Florian


From robherring2 at gmail.com  Wed Aug  5 20:14:51 2015
From: robherring2 at gmail.com (Rob Herring)
Date: Wed, 5 Aug 2015 22:14:51 -0500
Subject: [PATCH 5/9] ARM: common: Introduce PM domains for CPUs/clusters
In-Reply-To: <1438731339-58317-6-git-send-email-lina.iyer@linaro.org>
References: <1438731339-58317-1-git-send-email-lina.iyer@linaro.org>
 <1438731339-58317-6-git-send-email-lina.iyer@linaro.org>
Message-ID: <CAL_JsqK67=DTtjZwwnonObLDjLbahkREfm0RvyXVV95bhR-d4Q@mail.gmail.com>

On Tue, Aug 4, 2015 at 6:35 PM, Lina Iyer <lina.iyer at linaro.org> wrote:
> Define and add Generic PM domains (genpd) for ARM CPU clusters. Many new
> SoCs group CPUs as clusters. Clusters share common resources like GIC,
> power rail, caches, VFP, Coresight etc. When all CPUs in the cluster are
> idle, these shared resources may also be put in their idle state.
>
> The idle time between the last CPU entering idle and a CPU resuming
> execution is an opportunity for these shared resources to be powered
> down. Generic PM domain provides a framework for defining such power
> domains and attach devices to the domain. When the devices in the domain
> are idle at runtime, the domain would also be suspended and resumed
> before the first of the devices resume execution.
>
> We define a generic PM domain for each cluster and attach CPU devices in
> the cluster to that PM domain. The DT definitions for the SoC describe
> this relationship. Genpd callbacks for power_on and power_off can then
> be used to power up/down the shared resources for the domain.

[...]

> +ARM CPU Power domains
> +
> +The device tree allows describing of CPU power domains in a SoC. In ARM SoC,
> +CPUs may be grouped as clusters. A cluster may have CPUs, GIC, Coresight,
> +caches, VFP and power controller and other peripheral hardware. Generally,
> +when the CPUs in the cluster are idle/suspended, the shared resources may also
> +be suspended and resumed before any of the CPUs resume execution.
> +
> +CPUs are the defined as the PM domain consumers and there is a PM domain
> +provider for the CPUs. Bindings for generic PM domains (genpd) is described in
> +[1].
> +
> +The ARM CPU PM domain follows the same binding convention as any generic PM
> +domain. Additional binding properties are -
> +
> +- compatible:
> +       Usage: required
> +       Value type: <string>
> +       Definition: Must also have
> +                       "arm,pd"
> +               inorder to initialize the genpd provider as ARM CPU PM domain.

A compatible string should represent a particular h/w block. If it is
generic, it should represent some sort of standard programming
interface (e.g, AHCI, EHCI, etc.). This doesn't seem to be either and
is rather just a mapping of what "driver" you want to use.

I would expect that identifying a cpu's or cluster's power domain
would be done by a phandle between the cpu/cluster node and power
domain node. But I've not really looked at the power domain bindings
so who knows.

Rob


From punnaiah.choudary.kalluri at xilinx.com  Wed Aug  5 20:19:32 2015
From: punnaiah.choudary.kalluri at xilinx.com (Punnaiah Choudary Kalluri)
Date: Thu, 6 Aug 2015 08:49:32 +0530
Subject: [PATCH v4 1/2] Documentation: dt: Add Xilinx zynqmp dma device tree
 binding documentation
Message-ID: <1438831173-8761-1-git-send-email-punnaia@xilinx.com>

Device-tree binding documentation for Xilinx zynqmp dma engine used in
Zynq UltraScale+ MPSoC.

Signed-off-by: Punnaiah Choudary Kalluri <punnaia at xilinx.com>
---
Changes in v4:
- None
Changes in v3:
- None
Changes in v2:
- None
---
 .../devicetree/bindings/dma/xilinx/zynqmp_dma.txt  |   61 ++++++++++++++++++++
 1 files changed, 61 insertions(+), 0 deletions(-)
 create mode 100644 Documentation/devicetree/bindings/dma/xilinx/zynqmp_dma.txt

diff --git a/Documentation/devicetree/bindings/dma/xilinx/zynqmp_dma.txt b/Documentation/devicetree/bindings/dma/xilinx/zynqmp_dma.txt
new file mode 100644
index 0000000..e4f92b9
--- /dev/null
+++ b/Documentation/devicetree/bindings/dma/xilinx/zynqmp_dma.txt
@@ -0,0 +1,61 @@
+Xilinx ZynqMP DMA engine, it does support memory to memory transfers,
+memory to device and device to memory transfers. It also has flow
+control and rate control support for slave/peripheral dma access.
+
+Required properties:
+- compatible: Should be "xlnx,zynqmp-dma-1.0"
+- #dma-cells: Should be <1>, a single cell holding a line request number
+- reg: Memory map for module access
+- interrupt-parent: Interrupt controller the interrupt is routed through
+- interrupts: Should contain DMA channel interrupt
+- xlnx,bus-width: AXI buswidth in bits. Should contain 128 or 64
+
+Optional properties:
+- xlnx,include-sg: Indicates the controller to operate in simple or scatter
+		   gather dma mode
+- xlnx,ratectrl: Scheduling interval in terms of clock cycles for
+		 source AXI transaction
+- xlnx,overfetch: Tells whether the channel is allowed to over fetch the data
+- xlnx,src-issue: Number of AXI outstanding transactions on source side
+- xlnx,desc-axi-cohrnt: Tells whether the AXI transactions generated for the
+			descriptor read are marked Non-coherent
+- xlnx,src-axi-cohrnt: Tells whether the AXI transactions generated for the
+			source descriptor payload are marked Non-coherent
+- xlnx,dst-axi-cohrnt: Tells whether the AXI transactions generated for the
+			dst descriptor payload are marked Non-coherent
+- xlnx,desc-axi-qos: AXI QOS bits to be used for descriptor fetch
+- xlnx,src-axi-qos: AXI QOS bits to be used for data read
+- xlnx,dst-axi-qos: AXI QOS bits to be used for data write
+- xlnx,desc-axi-cache: AXI cache bits to be used for descriptor fetch.
+- xlnx,desc-axi-cache: AXI cache bits to be used for data read
+- xlnx,desc-axi-cache: AXI cache bits to be used for data write
+- xlnx,src-burst-len: AXI length for data read. Support only power of 2 values
+		      i.e 1,2,4,8 and 16
+- xlnx,dst-burst-len: AXI length for data write. Support only power of 2 values
+		      i.e 1,2,4,8 and 16
+
+Example:
+++++++++
+fpd_dma_chan1: dma at FD500000 {
+	compatible = "xlnx,zynqmp-dma-1.0";
+	reg = <0x0 0xFD500000 0x1000>;
+	#dma_cells = <1>;
+	interrupt-parent = <&gic>;
+	interrupts = <0 117 4>;
+	xlnx,bus-width = <128>;
+	xlnx,include-sg;
+	xlnx,overfetch;
+	xlnx,ratectrl = <0>;
+	xlnx,src-issue = <16>;
+	xlnx,desc-axi-cohrnt;
+	xlnx,src-axi-cohrnt;
+	xlnx,dst-axi-cohrnt;
+	xlnx,desc-axi-qos = <0>;
+	xlnx,desc-axi-cache = <0>;
+	xlnx,src-axi-qos = <0>;
+	xlnx,src-axi-cache = <2>;
+	xlnx,dst-axi-qos = <0>;
+	xlnx,dst-axi-cache = <2>;
+	xlnx,src-burst-len = <4>;
+	xlnx,dst-burst-len = <4>;
+};
-- 
1.7.4



From punnaiah.choudary.kalluri at xilinx.com  Wed Aug  5 20:19:33 2015
From: punnaiah.choudary.kalluri at xilinx.com (Punnaiah Choudary Kalluri)
Date: Thu, 6 Aug 2015 08:49:33 +0530
Subject: [PATCH v4 2/2] dma: Add Xilinx zynqmp dma engine driver support
In-Reply-To: <1438831173-8761-1-git-send-email-punnaia@xilinx.com>
References: <1438831173-8761-1-git-send-email-punnaia@xilinx.com>
Message-ID: <1438831173-8761-2-git-send-email-punnaia@xilinx.com>

Added the basic driver for zynqmp dma engine used in Zynq
UltraScale+ MPSoC. The initial release of this driver supports
only memory to memory transfers.

Signed-off-by: Punnaiah Choudary Kalluri <punnaia at xilinx.com>
---
Changes in v4:
- Modified the defines to start with ZYNQMP_DMA perfix
- Changed the zynqmp_dma_alloc_chan_resources to return number of
  allocated descriptors
- Changed the zynqmp_dma_device variable name
- Released the locks before calling user callback
- freeup irq in zynqmp_dma_chan_remove function.
Changes in v3:
- Modified the zynqmp_dma_chan_is_idle function return type to bool
Changes in v2:
- Corrected the function header documentation
- Framework expects bus-width value in bytes. so, fixed it
- Removed magic numbers for bus-width
---
 drivers/dma/Kconfig             |    6 +
 drivers/dma/xilinx/Makefile     |    1 +
 drivers/dma/xilinx/zynqmp_dma.c | 1247 +++++++++++++++++++++++++++++++++++++++
 3 files changed, 1254 insertions(+), 0 deletions(-)
 create mode 100644 drivers/dma/xilinx/zynqmp_dma.c

diff --git a/drivers/dma/Kconfig b/drivers/dma/Kconfig
index 88d474b..e0bd309 100644
--- a/drivers/dma/Kconfig
+++ b/drivers/dma/Kconfig
@@ -425,6 +425,12 @@ config XILINX_VDMA
 	  channels, Memory Mapped to Stream (MM2S) and Stream to
 	  Memory Mapped (S2MM) for the data transfers.
 
+config XILINX_ZYNQMP_DMA
+	tristate "Xilinx ZynqMP DMA Engine"
+	select DMA_ENGINE
+	help
+	  Enable support for Xilinx ZynqMP DMA engine in Zynq UltraScale+ MPSoC.
+
 config DMA_SUN6I
 	tristate "Allwinner A31 SoCs DMA support"
 	depends on MACH_SUN6I || MACH_SUN8I || COMPILE_TEST
diff --git a/drivers/dma/xilinx/Makefile b/drivers/dma/xilinx/Makefile
index 3c4e9f2..95469dc 100644
--- a/drivers/dma/xilinx/Makefile
+++ b/drivers/dma/xilinx/Makefile
@@ -1 +1,2 @@
 obj-$(CONFIG_XILINX_VDMA) += xilinx_vdma.o
+obj-$(CONFIG_XILINX_ZYNQMP_DMA) += zynqmp_dma.o
diff --git a/drivers/dma/xilinx/zynqmp_dma.c b/drivers/dma/xilinx/zynqmp_dma.c
new file mode 100644
index 0000000..93c51ac
--- /dev/null
+++ b/drivers/dma/xilinx/zynqmp_dma.c
@@ -0,0 +1,1247 @@
+/*
+ * DMA driver for Xilinx ZynqMP DMA Engine
+ *
+ * Copyright (C) 2015 Xilinx, Inc. All rights reserved.
+ *
+ * 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.
+ */
+
+#include <linux/bitops.h>
+#include <linux/dma-mapping.h>
+#include <linux/dmaengine.h>
+#include <linux/dmapool.h>
+#include <linux/init.h>
+#include <linux/interrupt.h>
+#include <linux/io.h>
+#include <linux/module.h>
+#include <linux/of_address.h>
+#include <linux/of_dma.h>
+#include <linux/of_irq.h>
+#include <linux/of_platform.h>
+#include <linux/slab.h>
+
+#include "../dmaengine.h"
+
+/* Register Offsets */
+#define ZYNQMP_DMA_ISR			0x100
+#define ZYNQMP_DMA_IMR			0x104
+#define ZYNQMP_DMA_IER			0x108
+#define ZYNQMP_DMA_IDS			0x10C
+#define ZYNQMP_DMA_CTRL0		0x110
+#define ZYNQMP_DMA_CTRL1		0x114
+#define ZYNQMP_DMA_STATUS		0x11C
+#define ZYNQMP_DMA_DATA_ATTR		0x120
+#define ZYNQMP_DMA_DSCR_ATTR		0x124
+#define ZYNQMP_DMA_SRC_DSCR_WRD0	0x128
+#define ZYNQMP_DMA_SRC_DSCR_WRD1	0x12C
+#define ZYNQMP_DMA_SRC_DSCR_WRD2	0x130
+#define ZYNQMP_DMA_SRC_DSCR_WRD3	0x134
+#define ZYNQMP_DMA_DST_DSCR_WRD0	0x138
+#define ZYNQMP_DMA_DST_DSCR_WRD1	0x13C
+#define ZYNQMP_DMA_DST_DSCR_WRD2	0x140
+#define ZYNQMP_DMA_DST_DSCR_WRD3	0x144
+#define ZYNQMP_DMA_SRC_START_LSB	0x158
+#define ZYNQMP_DMA_SRC_START_MSB	0x15C
+#define ZYNQMP_DMA_DST_START_LSB	0x160
+#define ZYNQMP_DMA_DST_START_MSB	0x164
+#define ZYNQMP_DMA_TOTAL_BYTE		0x188
+#define ZYNQMP_DMA_RATE_CTRL		0x18C
+#define ZYNQMP_DMA_IRQ_SRC_ACCT		0x190
+#define ZYNQMP_DMA_IRQ_DST_ACCT		0x194
+#define ZYNQMP_DMA_CTRL2		0x200
+
+/* Interrupt registers bit field definitions */
+#define ZYNQMP_DMA_DONE			BIT(10)
+#define ZYNQMP_DMA_AXI_WR_DATA		BIT(9)
+#define ZYNQMP_DMA_AXI_RD_DATA		BIT(8)
+#define ZYNQMP_DMA_AXI_RD_DST_DSCR	BIT(7)
+#define ZYNQMP_DMA_AXI_RD_SRC_DSCR	BIT(6)
+#define ZYNQMP_DMA_IRQ_DST_ACCT_ERR	BIT(5)
+#define ZYNQMP_DMA_IRQ_SRC_ACCT_ERR	BIT(4)
+#define ZYNQMP_DMA_BYTE_CNT_OVRFL	BIT(3)
+#define ZYNQMP_DMA_DST_DSCR_DONE	BIT(2)
+#define ZYNQMP_DMA_INV_APB		BIT(0)
+
+/* Control 0 register bit field definitions */
+#define ZYNQMP_DMA_OVR_FETCH		BIT(7)
+#define ZYNQMP_DMA_POINT_TYPE_SG	BIT(6)
+#define ZYNQMP_DMA_RATE_CTRL_EN		BIT(3)
+
+/* Control 1 register bit field definitions */
+#define ZYNQMP_DMA_SRC_ISSUE		GENMASK(4, 0)
+
+/* Channel status register bit field definitions */
+#define ZYNQMP_DMA_STATUS_BUSY		0x2
+
+/* Data Attribute register bit field definitions */
+#define ZYNQMP_DMA_ARBURST		GENMASK(27, 26)
+#define ZYNQMP_DMA_ARCACHE		GENMASK(25, 22)
+#define ZYNQMP_DMA_ARCACHE_OFST		22
+#define ZYNQMP_DMA_ARQOS		GENMASK(21, 18)
+#define ZYNQMP_DMA_ARQOS_OFST		18
+#define ZYNQMP_DMA_ARLEN		GENMASK(17, 14)
+#define ZYNQMP_DMA_ARLEN_OFST		14
+#define ZYNQMP_DMA_AWBURST		GENMASK(13, 12)
+#define ZYNQMP_DMA_AWCACHE		GENMASK(11, 8)
+#define ZYNQMP_DMA_AWCACHE_OFST		8
+#define ZYNQMP_DMA_AWQOS		GENMASK(7, 4)
+#define ZYNQMP_DMA_AWQOS_OFST		4
+#define ZYNQMP_DMA_AWLEN		GENMASK(3, 0)
+#define ZYNQMP_DMA_AWLEN_OFST		0
+
+/* Descriptor Attribute register bit field definitions */
+#define ZYNQMP_DMA_AXCOHRNT		BIT(8)
+#define ZYNQMP_DMA_AXCACHE		GENMASK(7, 4)
+#define ZYNQMP_DMA_AXCACHE_OFST		4
+#define ZYNQMP_DMA_AXQOS		GENMASK(3, 0)
+#define ZYNQMP_DMA_AXQOS_OFST		0
+
+/* Control register 2 bit field definitions */
+#define ZYNQMP_DMA_ENABLE		BIT(0)
+
+/* Buffer Descriptor definitions */
+#define ZYNQMP_DMA_DESC_CTRL_STOP	0x10
+#define ZYNQMP_DMA_DESC_CTRL_COMP_INT	0x4
+#define ZYNQMP_DMA_DESC_CTRL_SIZE_256	0x2
+#define ZYNQMP_DMA_DESC_CTRL_COHRNT	0x1
+
+/* Interrupt Mask specific definitions */
+#define ZYNQMP_DMA_INT_ERR	(ZYNQMP_DMA_AXI_RD_DATA | \
+				 ZYNQMP_DMA_AXI_WR_DATA | \
+				 ZYNQMP_DMA_AXI_RD_DST_DSCR | \
+				 ZYNQMP_DMA_AXI_RD_SRC_DSCR | \
+				 ZYNQMP_DMA_INV_APB)
+#define ZYNQMP_DMA_INT_OVRFL	(ZYNQMP_DMA_BYTE_CNT_OVRFL | \
+				 ZYNQMP_DMA_IRQ_SRC_ACCT_ERR | \
+				 ZYNQMP_DMA_IRQ_DST_ACCT_ERR)
+#define ZYNQMP_DMA_INT_DONE	(ZYNQMP_DMA_DONE | ZYNQMP_DMA_DST_DSCR_DONE)
+#define ZYNQMP_DMA_INT_EN_DEFAULT_MASK	(ZYNQMP_DMA_INT_DONE | \
+					 ZYNQMP_DMA_INT_ERR | \
+					 ZYNQMP_DMA_INT_OVRFL | \
+					 ZYNQMP_DMA_DST_DSCR_DONE)
+
+/* Max number of descriptors per channel */
+#define ZYNQMP_DMA_NUM_DESCS		32
+
+/* Max transfer size per descriptor */
+#define ZYNQMP_DMA_MAX_TRANS_LEN	0x40000000
+
+/* Reset values for data attributes */
+#define ZYNQMP_DMA_ARCACHE_RST_VAL	0x2
+#define ZYNQMP_DMA_ARLEN_RST_VAL	0xF
+#define ZYNQMP_DMA_AWCACHE_RST_VAL	0x2
+#define ZYNQMP_DMA_AWLEN_RST_VAL	0xF
+
+#define ZYNQMP_DMA_SRC_ISSUE_RST_VAL	0x1F
+
+#define ZYNQMP_DMA_IDS_DEFAULT_MASK	0xFFF
+
+/* Bus width in bits */
+#define ZYNQMP_DMA_BUS_WIDTH_64		64
+#define ZYNQMP_DMA_BUS_WIDTH_128	128
+
+#define ZYNQMP_DMA_DESC_SIZE(chan)	(chan->desc_size)
+
+#define to_chan(chan)		container_of(chan, struct zynqmp_dma_chan, \
+					     common)
+#define tx_to_desc(tx)		container_of(tx, struct zynqmp_dma_desc_sw, \
+					     async_tx)
+
+/**
+ * struct zynqmp_dma_desc_ll - Hw linked list descriptor
+ * @addr: Buffer address
+ * @size: Size of the buffer
+ * @ctrl: Control word
+ * @nxtdscraddr: Next descriptor base address
+ * @rsvd: Reserved field and for Hw internal use.
+ */
+struct zynqmp_dma_desc_ll {
+	u64 addr;
+	u32 size;
+	u32 ctrl;
+	u64 nxtdscraddr;
+	u64 rsvd;
+}; __aligned(64)
+
+/**
+ * struct zynqmp_dma_chan - Driver specific DMA channel structure
+ * @zdev: Driver specific device structure
+ * @regs: Control registers offset
+ * @lock: Descriptor operation lock
+ * @pending_list: Descriptors waiting
+ * @free_list: Descriptors free
+ * @active_list: Descriptors active
+ * @sw_desc_pool: SW descriptor pool
+ * @done_list: Complete descriptors
+ * @common: DMA common channel
+ * @desc_pool_v: Statically allocated descriptor base
+ * @desc_pool_p: Physical allocated descriptor base
+ * @desc_free_cnt: Descriptor available count
+ * @dev: The dma device
+ * @irq: Channel IRQ
+ * @has_sg: Support scatter gather transfers
+ * @ovrfetch: Overfetch status
+ * @ratectrl: Rate control value
+ * @tasklet: Cleanup work after irq
+ * @src_issue: Out standing transactions on source
+ * @dst_issue: Out standing transactions on destination
+ * @desc_size: Size of the low level descriptor
+ * @err: Channel has errors
+ * @bus_width: Bus width
+ * @desc_axi_cohrnt: Descriptor axi coherent status
+ * @desc_axi_cache: Descriptor axi cache attribute
+ * @desc_axi_qos: Descriptor axi qos attribute
+ * @src_axi_cohrnt: Source data axi coherent status
+ * @src_axi_cache: Source data axi cache attribute
+ * @src_axi_qos: Source data axi qos attribute
+ * @dst_axi_cohrnt: Dest data axi coherent status
+ * @dst_axi_cache: Dest data axi cache attribute
+ * @dst_axi_qos: Dest data axi qos attribute
+ * @src_burst_len: Source burst length
+ * @dst_burst_len: Dest burst length
+ */
+struct zynqmp_dma_chan {
+	struct zynqmp_dma_device *zdev;
+	void __iomem *regs;
+	spinlock_t lock;
+	struct list_head pending_list;
+	struct list_head free_list;
+	struct list_head active_list;
+	struct zynqmp_dma_desc_sw *sw_desc_pool;
+	struct list_head done_list;
+	struct dma_chan common;
+	void *desc_pool_v;
+	dma_addr_t desc_pool_p;
+	u32 desc_free_cnt;
+	struct device *dev;
+	int irq;
+	bool has_sg;
+	bool ovrfetch;
+	u32 ratectrl;
+	struct tasklet_struct tasklet;
+	u32 src_issue;
+	u32 dst_issue;
+	u32 desc_size;
+	bool err;
+	u32 bus_width;
+	u32 desc_axi_cohrnt;
+	u32 desc_axi_cache;
+	u32 desc_axi_qos;
+	u32 src_axi_cohrnt;
+	u32 src_axi_cache;
+	u32 src_axi_qos;
+	u32 dst_axi_cohrnt;
+	u32 dst_axi_cache;
+	u32 dst_axi_qos;
+	u32 src_burst_len;
+	u32 dst_burst_len;
+};
+
+/**
+ * struct zynqmp_dma_desc_sw - Per Transaction structure
+ * @src: Source address for simple mode dma
+ * @dst: Destination address for simple mode dma
+ * @len: Transfer length for simple mode dma
+ * @node: Node in the channel descriptor list
+ * @tx_list: List head for the current transfer
+ * @async_tx: Async transaction descriptor
+ * @src_v: Virtual address of the src descriptor
+ * @src_p: Physical address of the src descriptor
+ * @dst_v: Virtual address of the dst descriptor
+ * @dst_p: Physical address of the dst descriptor
+ */
+struct zynqmp_dma_desc_sw {
+	u64 src;
+	u64 dst;
+	u32 len;
+	struct list_head node;
+	struct list_head tx_list;
+	struct dma_async_tx_descriptor async_tx;
+	struct zynqmp_dma_desc_ll *src_v;
+	dma_addr_t src_p;
+	struct zynqmp_dma_desc_ll *dst_v;
+	dma_addr_t dst_p;
+};
+
+/**
+ * struct zynqmp_dma_device - DMA device structure
+ * @dev: Device Structure
+ * @common: DMA device structure
+ * @chan: Driver specific DMA channel
+ */
+struct zynqmp_dma_device {
+	struct device *dev;
+	struct dma_device common;
+	struct zynqmp_dma_chan *chan;
+};
+
+/**
+ * zynqmp_dma_chan_is_idle - Provides the channel idle status
+ * @chan: ZynqMP DMA DMA channel pointer
+ *
+ * Return: 'true' if the channel is idle otherwise 'false'
+ */
+static bool zynqmp_dma_chan_is_idle(struct zynqmp_dma_chan *chan)
+{
+	u32 regval;
+
+	regval = readl(chan->regs + ZYNQMP_DMA_STATUS);
+	if (regval & ZYNQMP_DMA_STATUS_BUSY)
+		return false;
+
+	return true;
+}
+
+/**
+ * zynqmp_dma_update_desc_to_ctrlr - Updates descriptor to the controller
+ * @chan: ZynqMP DMA DMA channel pointer
+ * @desc: Transaction descriptor pointer
+ */
+static void zynqmp_dma_update_desc_to_ctrlr(struct zynqmp_dma_chan *chan,
+				      struct zynqmp_dma_desc_sw *desc)
+{
+	dma_addr_t addr;
+
+	addr = desc->src_p;
+	writel(addr, chan->regs + ZYNQMP_DMA_SRC_START_LSB);
+	writel(upper_32_bits(addr), chan->regs + ZYNQMP_DMA_SRC_START_MSB);
+	addr = desc->dst_p;
+	writel(addr, chan->regs + ZYNQMP_DMA_DST_START_LSB);
+	writel(upper_32_bits(addr), chan->regs + ZYNQMP_DMA_DST_START_MSB);
+}
+
+/**
+ * zynqmp_dma_desc_config_eod - Mark the descriptor as end descriptor
+ * @chan: ZynqMP DMA channel pointer
+ * @desc: Hw descriptor pointer
+ */
+static void zynqmp_dma_desc_config_eod(struct zynqmp_dma_chan *chan, void *desc)
+{
+	struct zynqmp_dma_desc_ll *hw = (struct zynqmp_dma_desc_ll *)desc;
+
+	hw->ctrl |= ZYNQMP_DMA_DESC_CTRL_STOP;
+	hw++;
+	hw->ctrl |= ZYNQMP_DMA_DESC_CTRL_COMP_INT | ZYNQMP_DMA_DESC_CTRL_STOP;
+}
+
+/**
+ * zynqmp_dma_config_simple_desc - Configure the transfer parameters
+ * @chan: ZynqMP DMA channel pointer
+ * @src: Source buffer address
+ * @dst: Destination buffer address
+ * @len: Transfer length
+ */
+static void zynqmp_dma_config_simple_desc(struct zynqmp_dma_chan *chan,
+					  dma_addr_t src, dma_addr_t dst,
+					  size_t len)
+{
+	u32 val;
+
+	writel(src, chan->regs + ZYNQMP_DMA_SRC_DSCR_WRD0);
+	writel(upper_32_bits(src), chan->regs + ZYNQMP_DMA_SRC_DSCR_WRD1);
+	writel(len, chan->regs + ZYNQMP_DMA_SRC_DSCR_WRD2);
+
+	if (chan->src_axi_cohrnt)
+		writel(ZYNQMP_DMA_DESC_CTRL_COHRNT,
+			chan->regs + ZYNQMP_DMA_SRC_DSCR_WRD3);
+	else
+		writel(0, chan->regs + ZYNQMP_DMA_SRC_DSCR_WRD3);
+
+	writel(dst, chan->regs + ZYNQMP_DMA_DST_DSCR_WRD0);
+	writel(upper_32_bits(dst), chan->regs + ZYNQMP_DMA_DST_DSCR_WRD1);
+	writel(len, chan->regs + ZYNQMP_DMA_DST_DSCR_WRD2);
+
+	if (chan->dst_axi_cohrnt)
+		val = ZYNQMP_DMA_DESC_CTRL_COHRNT |
+			ZYNQMP_DMA_DESC_CTRL_COMP_INT;
+	else
+		val = ZYNQMP_DMA_DESC_CTRL_COMP_INT;
+	writel(val, chan->regs + ZYNQMP_DMA_DST_DSCR_WRD3);
+}
+
+/**
+ * zynqmp_dma_config_sg_ll_desc - Configure the linked list descriptor
+ * @chan: ZynqMP DMA channel pointer
+ * @sdesc: Hw descriptor pointer
+ * @src: Source buffer address
+ * @dst: Destination buffer address
+ * @len: Transfer length
+ * @prev: Previous hw descriptor pointer
+ */
+static void zynqmp_dma_config_sg_ll_desc(struct zynqmp_dma_chan *chan,
+				   struct zynqmp_dma_desc_ll *sdesc,
+				   dma_addr_t src, dma_addr_t dst, size_t len,
+				   struct zynqmp_dma_desc_ll *prev)
+{
+	struct zynqmp_dma_desc_ll *ddesc = sdesc + 1;
+
+	sdesc->size = ddesc->size = len;
+	sdesc->addr = src;
+	ddesc->addr = dst;
+
+	sdesc->ctrl = ddesc->ctrl = ZYNQMP_DMA_DESC_CTRL_SIZE_256;
+	if (chan->src_axi_cohrnt)
+		sdesc->ctrl |= ZYNQMP_DMA_DESC_CTRL_COHRNT;
+	else
+		ddesc->ctrl |= ZYNQMP_DMA_DESC_CTRL_COHRNT;
+
+	if (prev) {
+		dma_addr_t addr = chan->desc_pool_p +
+			((dma_addr_t)sdesc - (dma_addr_t)chan->desc_pool_v);
+		ddesc = prev + 1;
+		prev->nxtdscraddr = addr;
+		ddesc->nxtdscraddr = addr + ZYNQMP_DMA_DESC_SIZE(chan);
+	}
+}
+
+/**
+ * zynqmp_dma_init - Initialize the channel
+ * @chan: ZynqMP DMA channel pointer
+ */
+static void zynqmp_dma_init(struct zynqmp_dma_chan *chan)
+{
+	u32 val;
+
+	writel(ZYNQMP_DMA_IDS_DEFAULT_MASK, chan->regs + ZYNQMP_DMA_IDS);
+	val = readl(chan->regs + ZYNQMP_DMA_ISR);
+	writel(val, chan->regs + ZYNQMP_DMA_ISR);
+	writel(0x0, chan->regs + ZYNQMP_DMA_TOTAL_BYTE);
+
+	val = readl(chan->regs + ZYNQMP_DMA_CTRL1);
+	if (chan->src_issue)
+		val = (val & ~ZYNQMP_DMA_SRC_ISSUE) | chan->src_issue;
+	writel(val, chan->regs + ZYNQMP_DMA_CTRL1);
+
+	val = 0;
+	if (chan->ovrfetch)
+		val |= ZYNQMP_DMA_OVR_FETCH;
+	if (chan->has_sg)
+		val |= ZYNQMP_DMA_POINT_TYPE_SG;
+	if (chan->ratectrl) {
+		val |= ZYNQMP_DMA_RATE_CTRL_EN;
+		writel(chan->ratectrl, chan->regs + ZYNQMP_DMA_RATE_CTRL);
+	}
+	writel(val, chan->regs + ZYNQMP_DMA_CTRL0);
+
+	val = 0;
+	if (chan->desc_axi_cohrnt)
+		val |= ZYNQMP_DMA_AXCOHRNT;
+	val |= chan->desc_axi_cache;
+	val =  (val & ~ZYNQMP_DMA_AXCACHE) |
+		(chan->desc_axi_cache << ZYNQMP_DMA_AXCACHE_OFST);
+	val |= chan->desc_axi_qos;
+	val =  (val & ~ZYNQMP_DMA_AXQOS) |
+		(chan->desc_axi_qos << ZYNQMP_DMA_AXQOS_OFST);
+	writel(val, chan->regs + ZYNQMP_DMA_DSCR_ATTR);
+
+	val = readl(chan->regs + ZYNQMP_DMA_DATA_ATTR);
+	val = (val & ~ZYNQMP_DMA_ARCACHE) |
+		(chan->src_axi_cache << ZYNQMP_DMA_ARCACHE_OFST);
+	val = (val & ~ZYNQMP_DMA_AWCACHE) |
+		(chan->dst_axi_cache << ZYNQMP_DMA_AWCACHE_OFST);
+	val = (val & ~ZYNQMP_DMA_ARQOS) |
+		(chan->src_axi_qos << ZYNQMP_DMA_ARQOS_OFST);
+	val = (val & ~ZYNQMP_DMA_AWQOS) |
+		(chan->dst_axi_qos << ZYNQMP_DMA_AWQOS_OFST);
+	val = (val & ~ZYNQMP_DMA_ARLEN) |
+		(chan->src_burst_len << ZYNQMP_DMA_ARLEN_OFST);
+	val = (val & ~ZYNQMP_DMA_AWLEN) |
+		(chan->dst_burst_len << ZYNQMP_DMA_AWLEN_OFST);
+	writel(val, chan->regs + ZYNQMP_DMA_DATA_ATTR);
+
+	/* Clearing the interrupt account rgisters */
+	val = readl(chan->regs + ZYNQMP_DMA_IRQ_SRC_ACCT);
+	val = readl(chan->regs + ZYNQMP_DMA_IRQ_DST_ACCT);
+}
+
+/**
+ * zynqmp_dma_tx_submit - Submit DMA transaction
+ * @tx: Async transaction descriptor pointer
+ *
+ * Return: cookie value
+ */
+static dma_cookie_t zynqmp_dma_tx_submit(struct dma_async_tx_descriptor *tx)
+{
+	struct zynqmp_dma_chan *chan = to_chan(tx->chan);
+	struct zynqmp_dma_desc_sw *desc = NULL, *new;
+	dma_cookie_t cookie;
+
+	new = tx_to_desc(tx);
+	spin_lock_bh(&chan->lock);
+	cookie = dma_cookie_assign(tx);
+	if (!list_empty(&chan->pending_list) && chan->has_sg) {
+		desc = list_last_entry(&chan->pending_list,
+				     struct zynqmp_dma_desc_sw, node);
+		if (!list_empty(&desc->tx_list))
+			desc = list_last_entry(&desc->tx_list,
+					       struct zynqmp_dma_desc_sw, node);
+		desc->src_v->nxtdscraddr = new->src_p;
+		desc->src_v->ctrl &= ~ZYNQMP_DMA_DESC_CTRL_STOP;
+		desc->dst_v->nxtdscraddr = new->dst_p;
+		desc->dst_v->ctrl &= ~ZYNQMP_DMA_DESC_CTRL_STOP;
+	}
+	list_add_tail(&new->node, &chan->pending_list);
+	spin_unlock_bh(&chan->lock);
+
+	return cookie;
+}
+
+/**
+ * zynqmp_dma_get_descriptor - Get the sw descriptor from the pool
+ * @chan: ZynqMP DMA channel pointer
+ *
+ * Return: The sw descriptor
+ */
+static struct zynqmp_dma_desc_sw *
+zynqmp_dma_get_descriptor(struct zynqmp_dma_chan *chan)
+{
+	struct zynqmp_dma_desc_sw *desc;
+
+	spin_lock_bh(&chan->lock);
+	desc = list_first_entry(&chan->free_list, struct zynqmp_dma_desc_sw,
+				 node);
+	list_del(&desc->node);
+	spin_unlock_bh(&chan->lock);
+
+	INIT_LIST_HEAD(&desc->tx_list);
+	/* Clear the src and dst descriptor memory */
+	if (chan->has_sg) {
+		memset((void *)desc->src_v, 0, ZYNQMP_DMA_DESC_SIZE(chan));
+		memset((void *)desc->dst_v, 0, ZYNQMP_DMA_DESC_SIZE(chan));
+	}
+
+	return desc;
+}
+
+/**
+ * zynqmp_dma_free_descriptor - Issue pending transactions
+ * @chan: ZynqMP DMA channel pointer
+ * @sdesc: Transaction descriptor pointer
+ */
+static void zynqmp_dma_free_descriptor(struct zynqmp_dma_chan *chan,
+				 struct zynqmp_dma_desc_sw *sdesc)
+{
+	struct zynqmp_dma_desc_sw *child, *next;
+
+	chan->desc_free_cnt++;
+	list_add_tail(&sdesc->node, &chan->free_list);
+	list_for_each_entry_safe(child, next, &sdesc->tx_list, node) {
+		chan->desc_free_cnt++;
+		list_move_tail(&child->node, &chan->free_list);
+	}
+}
+
+/**
+ * zynqmp_dma_free_desc_list - Free descriptors list
+ * @chan: ZynqMP DMA channel pointer
+ * @list: List to parse and delete the descriptor
+ */
+static void zynqmp_dma_free_desc_list(struct zynqmp_dma_chan *chan,
+				      struct list_head *list)
+{
+	struct zynqmp_dma_desc_sw *desc, *next;
+
+	list_for_each_entry_safe(desc, next, list, node)
+		zynqmp_dma_free_descriptor(chan, desc);
+}
+
+/**
+ * zynqmp_dma_alloc_chan_resources - Allocate channel resources
+ * @dchan: DMA channel
+ *
+ * Return: Number of descriptors on success and failure value on error
+ */
+static int zynqmp_dma_alloc_chan_resources(struct dma_chan *dchan)
+{
+	struct zynqmp_dma_chan *chan = to_chan(dchan);
+	struct zynqmp_dma_desc_sw *desc;
+	int i;
+
+	chan->sw_desc_pool = kzalloc(sizeof(*desc) * ZYNQMP_DMA_NUM_DESCS,
+				     GFP_KERNEL);
+	if (!chan->sw_desc_pool)
+		return -ENOMEM;
+
+	chan->desc_free_cnt = ZYNQMP_DMA_NUM_DESCS;
+
+	INIT_LIST_HEAD(&chan->free_list);
+
+	for (i = 0; i < ZYNQMP_DMA_NUM_DESCS; i++) {
+		desc = chan->sw_desc_pool + i;
+		dma_async_tx_descriptor_init(&desc->async_tx, &chan->common);
+		desc->async_tx.tx_submit = zynqmp_dma_tx_submit;
+		async_tx_ack(&desc->async_tx);
+		list_add_tail(&desc->node, &chan->free_list);
+	}
+
+	if (!chan->has_sg)
+		return 0;
+
+	chan->desc_pool_v = dma_zalloc_coherent(chan->dev,
+				(2 * chan->desc_size * ZYNQMP_DMA_NUM_DESCS),
+				&chan->desc_pool_p, GFP_KERNEL);
+	if (!chan->desc_pool_v)
+		return -ENOMEM;
+
+	for (i = 0; i < ZYNQMP_DMA_NUM_DESCS; i++) {
+		desc = chan->sw_desc_pool + i;
+		desc->src_v = (struct zynqmp_dma_desc_ll *) (chan->desc_pool_v +
+					(i * ZYNQMP_DMA_DESC_SIZE(chan) * 2));
+		desc->dst_v = (struct zynqmp_dma_desc_ll *) (desc->src_v + 1);
+		desc->src_p = chan->desc_pool_p +
+				(i * ZYNQMP_DMA_DESC_SIZE(chan) * 2);
+		desc->dst_p = desc->src_p + ZYNQMP_DMA_DESC_SIZE(chan);
+	}
+
+	return ZYNQMP_DMA_NUM_DESCS;
+}
+
+/**
+ * zynqmp_dma_start - Start DMA channel
+ * @chan: ZynqMP DMA channel pointer
+ */
+static void zynqmp_dma_start(struct zynqmp_dma_chan *chan)
+{
+	writel(ZYNQMP_DMA_INT_EN_DEFAULT_MASK, chan->regs + ZYNQMP_DMA_IER);
+	writel(0, chan->regs + ZYNQMP_DMA_TOTAL_BYTE);
+	writel(ZYNQMP_DMA_ENABLE, chan->regs + ZYNQMP_DMA_CTRL2);
+}
+
+/**
+ * zynqmp_dma_handle_ovfl_int - Process the overflow interrupt
+ * @chan: ZynqMP DMA channel pointer
+ * @status: Interrupt status value
+ */
+static void zynqmp_dma_handle_ovfl_int(struct zynqmp_dma_chan *chan, u32 status)
+{
+	u32 val;
+
+	if (status & ZYNQMP_DMA_BYTE_CNT_OVRFL) {
+		val = readl(chan->regs + ZYNQMP_DMA_TOTAL_BYTE);
+		writel(0, chan->regs + ZYNQMP_DMA_TOTAL_BYTE);
+	}
+	if (status & ZYNQMP_DMA_IRQ_DST_ACCT_ERR)
+		val = readl(chan->regs + ZYNQMP_DMA_IRQ_DST_ACCT);
+	if (status & ZYNQMP_DMA_IRQ_SRC_ACCT_ERR)
+		val = readl(chan->regs + ZYNQMP_DMA_IRQ_SRC_ACCT);
+}
+
+/**
+ * zynqmp_dma_start_transfer - Initiate the new transfer
+ * @chan: ZynqMP DMA channel pointer
+ */
+static void zynqmp_dma_start_transfer(struct zynqmp_dma_chan *chan)
+{
+	struct zynqmp_dma_desc_sw *desc;
+
+	if (!zynqmp_dma_chan_is_idle(chan))
+		return;
+
+	desc = list_first_entry_or_null(&chan->pending_list,
+					struct zynqmp_dma_desc_sw, node);
+	if (!desc)
+		return;
+
+	if (chan->has_sg)
+		list_splice_tail_init(&chan->pending_list, &chan->active_list);
+	else
+		list_move_tail(&desc->node, &chan->active_list);
+
+	if (chan->has_sg)
+		zynqmp_dma_update_desc_to_ctrlr(chan, desc);
+	else
+		zynqmp_dma_config_simple_desc(chan, desc->src, desc->dst,
+					      desc->len);
+	zynqmp_dma_start(chan);
+}
+
+
+/**
+ * zynqmp_dma_chan_desc_cleanup - Cleanup the completed descriptors
+ * @chan: ZynqMP DMA channel
+ */
+static void zynqmp_dma_chan_desc_cleanup(struct zynqmp_dma_chan *chan)
+{
+	struct zynqmp_dma_desc_sw *desc, *next;
+
+	list_for_each_entry_safe(desc, next, &chan->done_list, node) {
+		dma_async_tx_callback callback;
+		void *callback_param;
+
+		list_del(&desc->node);
+
+		callback = desc->async_tx.callback;
+		callback_param = desc->async_tx.callback_param;
+		if (callback) {
+			if (in_interrupt())
+				spin_unlock_bh(&chan->lock);
+			else
+				spin_unlock(&chan->lock);
+
+			callback(callback_param);
+
+			if (in_interrupt())
+				spin_lock_bh(&chan->lock);
+			else
+				spin_lock(&chan->lock);
+		}
+
+		/* Run any dependencies, then free the descriptor */
+		dma_run_dependencies(&desc->async_tx);
+		zynqmp_dma_free_descriptor(chan, desc);
+	}
+}
+
+/**
+ * zynqmp_dma_complete_descriptor - Mark the active descriptor as complete
+ * @chan: ZynqMP DMA channel pointer
+ */
+static void zynqmp_dma_complete_descriptor(struct zynqmp_dma_chan *chan)
+{
+	struct zynqmp_dma_desc_sw *desc;
+
+	desc = list_first_entry_or_null(&chan->active_list,
+					struct zynqmp_dma_desc_sw, node);
+	if (!desc)
+		return;
+	list_del(&desc->node);
+	dma_cookie_complete(&desc->async_tx);
+	list_add_tail(&desc->node, &chan->done_list);
+}
+
+/**
+ * zynqmp_dma_issue_pending - Issue pending transactions
+ * @dchan: DMA channel pointer
+ */
+static void zynqmp_dma_issue_pending(struct dma_chan *dchan)
+{
+	struct zynqmp_dma_chan *chan = to_chan(dchan);
+
+	spin_lock_bh(&chan->lock);
+	zynqmp_dma_start_transfer(chan);
+	spin_unlock_bh(&chan->lock);
+}
+
+/**
+ * zynqmp_dma_free_chan_resources - Free channel resources
+ * @dchan: DMA channel pointer
+ */
+static void zynqmp_dma_free_chan_resources(struct dma_chan *dchan)
+{
+	struct zynqmp_dma_chan *chan = to_chan(dchan);
+
+	spin_lock_bh(&chan->lock);
+
+	zynqmp_dma_free_desc_list(chan, &chan->active_list);
+	zynqmp_dma_free_desc_list(chan, &chan->done_list);
+	zynqmp_dma_free_desc_list(chan, &chan->pending_list);
+
+	spin_unlock_bh(&chan->lock);
+	if (chan->has_sg)
+		dma_free_coherent(chan->dev,
+			(2 * ZYNQMP_DMA_DESC_SIZE(chan) * ZYNQMP_DMA_NUM_DESCS),
+			chan->desc_pool_v, chan->desc_pool_p);
+	kfree(chan->sw_desc_pool);
+}
+
+/**
+ * zynqmp_dma_tx_status - Get dma transaction status
+ * @dchan: DMA channel pointer
+ * @cookie: Transaction identifier
+ * @txstate: Transaction state
+ *
+ * Return: DMA transaction status
+ */
+static enum dma_status zynqmp_dma_tx_status(struct dma_chan *dchan,
+				      dma_cookie_t cookie,
+				      struct dma_tx_state *txstate)
+{
+	return dma_cookie_status(dchan, cookie, txstate);
+}
+
+/**
+ * zynqmp_dma_reset - Reset the channel
+ * @chan: ZynqMP DMA channel pointer
+ */
+static void zynqmp_dma_reset(struct zynqmp_dma_chan *chan)
+{
+	writel(ZYNQMP_DMA_IDS_DEFAULT_MASK, chan->regs + ZYNQMP_DMA_IDS);
+
+	zynqmp_dma_complete_descriptor(chan);
+	zynqmp_dma_chan_desc_cleanup(chan);
+
+	zynqmp_dma_free_desc_list(chan, &chan->active_list);
+	zynqmp_dma_free_desc_list(chan, &chan->done_list);
+	zynqmp_dma_free_desc_list(chan, &chan->pending_list);
+	zynqmp_dma_init(chan);
+}
+
+/**
+ * zynqmp_dma_irq_handler - ZynqMP DMA Interrupt handler
+ * @irq: IRQ number
+ * @data: Pointer to the ZynqMP DMA channel structure
+ *
+ * Return: IRQ_HANDLED/IRQ_NONE
+ */
+static irqreturn_t zynqmp_dma_irq_handler(int irq, void *data)
+{
+	struct zynqmp_dma_chan *chan = (struct zynqmp_dma_chan *)data;
+	u32 isr, imr, status;
+	irqreturn_t ret = IRQ_NONE;
+
+	isr = readl(chan->regs + ZYNQMP_DMA_ISR);
+	imr = readl(chan->regs + ZYNQMP_DMA_IMR);
+	status = isr & ~imr;
+	writel(isr, chan->regs + ZYNQMP_DMA_ISR);
+	if (status & ZYNQMP_DMA_INT_DONE) {
+		writel(ZYNQMP_DMA_INT_DONE, chan->regs + ZYNQMP_DMA_IDS);
+		tasklet_schedule(&chan->tasklet);
+		ret = IRQ_HANDLED;
+	}
+
+	if (status & ZYNQMP_DMA_INT_ERR) {
+		chan->err = true;
+		writel(ZYNQMP_DMA_INT_ERR, chan->regs + ZYNQMP_DMA_IDS);
+		tasklet_schedule(&chan->tasklet);
+		dev_err(chan->dev, "Channel %p has has errors\n", chan);
+		ret = IRQ_HANDLED;
+	}
+
+	if (status & ZYNQMP_DMA_INT_OVRFL) {
+		writel(ZYNQMP_DMA_INT_OVRFL, chan->regs + ZYNQMP_DMA_IDS);
+		zynqmp_dma_handle_ovfl_int(chan, status);
+		dev_info(chan->dev, "Channel %p overflow interrupt\n", chan);
+		ret = IRQ_HANDLED;
+	}
+
+	return ret;
+}
+
+/**
+ * zynqmp_dma_do_tasklet - Schedule completion tasklet
+ * @data: Pointer to the ZynqMP DMA channel structure
+ */
+static void zynqmp_dma_do_tasklet(unsigned long data)
+{
+	struct zynqmp_dma_chan *chan = (struct zynqmp_dma_chan *)data;
+	u32 count;
+
+	spin_lock(&chan->lock);
+
+	if (chan->err) {
+		zynqmp_dma_reset(chan);
+		chan->err = false;
+		goto unlock;
+	}
+
+	if (zynqmp_dma_chan_is_idle(chan))
+		zynqmp_dma_start_transfer(chan);
+	else
+		writel(ZYNQMP_DMA_INT_DONE, chan->regs + ZYNQMP_DMA_IER);
+
+	count = readl(chan->regs + ZYNQMP_DMA_IRQ_DST_ACCT);
+	while (count) {
+		zynqmp_dma_complete_descriptor(chan);
+		zynqmp_dma_chan_desc_cleanup(chan);
+		count--;
+	}
+
+unlock:
+	spin_unlock(&chan->lock);
+}
+
+/**
+ * zynqmp_dma_device_terminate_all - Aborts all transfers on a channel
+ * @dchan: DMA channel pointer
+ *
+ * Return: Always '0'
+ */
+static int zynqmp_dma_device_terminate_all(struct dma_chan *dchan)
+{
+	struct zynqmp_dma_chan *chan = to_chan(dchan);
+
+	spin_lock_bh(&chan->lock);
+	zynqmp_dma_reset(chan);
+	spin_unlock_bh(&chan->lock);
+
+	return 0;
+}
+
+/**
+ * zynqmp_dma_prep_memcpy - prepare descriptors for memcpy transaction
+ * @dchan: DMA channel
+ * @dma_dst: Destination buffer address
+ * @dma_src: Source buffer address
+ * @len: Transfer length
+ * @flags: transfer ack flags
+ *
+ * Return: Async transaction descriptor on success and NULL on failure
+ */
+static struct dma_async_tx_descriptor *zynqmp_dma_prep_memcpy(
+				struct dma_chan *dchan, dma_addr_t dma_dst,
+				dma_addr_t dma_src, size_t len, ulong flags)
+{
+	struct zynqmp_dma_chan *chan;
+	struct zynqmp_dma_desc_sw *new, *first = NULL;
+	void *desc = NULL, *prev = NULL;
+	size_t copy;
+	u32 desc_cnt;
+
+	chan = to_chan(dchan);
+
+	if ((len > ZYNQMP_DMA_MAX_TRANS_LEN) && !chan->has_sg)
+		return NULL;
+
+	desc_cnt = DIV_ROUND_UP(len, ZYNQMP_DMA_MAX_TRANS_LEN);
+
+	spin_lock_bh(&chan->lock);
+	if ((desc_cnt > chan->desc_free_cnt) && chan->has_sg) {
+		spin_unlock_bh(&chan->lock);
+		dev_dbg(chan->dev, "chan %p descs are not available\n", chan);
+		return NULL;
+	}
+	chan->desc_free_cnt = chan->desc_free_cnt - desc_cnt;
+	spin_unlock_bh(&chan->lock);
+
+	do {
+		new = zynqmp_dma_get_descriptor(chan);
+		copy = min_t(size_t, len, ZYNQMP_DMA_MAX_TRANS_LEN);
+		if (chan->has_sg) {
+			desc = (struct zynqmp_dma_desc_ll *)new->src_v;
+			zynqmp_dma_config_sg_ll_desc(chan, desc, dma_src,
+						     dma_dst, copy, prev);
+		} else {
+			new->src = dma_src;
+			new->dst = dma_dst;
+			new->len = len;
+		}
+
+		prev = desc;
+		len -= copy;
+		dma_src += copy;
+		dma_dst += copy;
+		if (!first)
+			first = new;
+		else
+			list_add_tail(&new->node, &first->tx_list);
+	} while (len);
+
+	if (chan->has_sg)
+		zynqmp_dma_desc_config_eod(chan, desc);
+
+	first->async_tx.flags = flags;
+	return &first->async_tx;
+}
+
+/**
+ * zynqmp_dma_prep_slave_sg - prepare descriptors for a memory sg transaction
+ * @dchan: DMA channel
+ * @dst_sg: Destination scatter list
+ * @dst_sg_len: Number of entries in destination scatter list
+ * @src_sg: Source scatter list
+ * @src_sg_len: Number of entries in source scatter list
+ * @flags: transfer ack flags
+ *
+ * Return: Async transaction descriptor on success and NULL on failure
+ */
+static struct dma_async_tx_descriptor *zynqmp_dma_prep_sg(
+			struct dma_chan *dchan, struct scatterlist *dst_sg,
+			unsigned int dst_sg_len, struct scatterlist *src_sg,
+			unsigned int src_sg_len, unsigned long flags)
+{
+	struct zynqmp_dma_desc_sw *new, *first = NULL;
+	struct zynqmp_dma_chan *chan = to_chan(dchan);
+	void *desc = NULL, *prev = NULL;
+	size_t len, dst_avail, src_avail;
+	dma_addr_t dma_dst, dma_src;
+	u32 desc_cnt = 0, i;
+	struct scatterlist *sg;
+
+	if (!chan->has_sg)
+		return NULL;
+
+	for_each_sg(src_sg, sg, src_sg_len, i)
+		desc_cnt += DIV_ROUND_UP(sg_dma_len(sg),
+					 ZYNQMP_DMA_MAX_TRANS_LEN);
+
+	spin_lock_bh(&chan->lock);
+	if (desc_cnt > chan->desc_free_cnt) {
+		spin_unlock_bh(&chan->lock);
+		dev_dbg(chan->dev, "chan %p descs are not available\n", chan);
+		return NULL;
+	}
+	chan->desc_free_cnt = chan->desc_free_cnt - desc_cnt;
+	spin_unlock_bh(&chan->lock);
+
+	dst_avail = sg_dma_len(dst_sg);
+	src_avail = sg_dma_len(src_sg);
+
+	/* Run until we are out of scatterlist entries */
+	while (true) {
+		/* Allocate and populate the descriptor */
+		new = zynqmp_dma_get_descriptor(chan);
+		desc = (struct zynqmp_dma_desc_ll *)new->src_v;
+		len = min_t(size_t, src_avail, dst_avail);
+		len = min_t(size_t, len, ZYNQMP_DMA_MAX_TRANS_LEN);
+		if (len == 0)
+			goto fetch;
+		dma_dst = sg_dma_address(dst_sg) + sg_dma_len(dst_sg) -
+			dst_avail;
+		dma_src = sg_dma_address(src_sg) + sg_dma_len(src_sg) -
+			src_avail;
+
+		zynqmp_dma_config_sg_ll_desc(chan, desc, dma_src, dma_dst,
+					     len, prev);
+		prev = desc;
+		dst_avail -= len;
+		src_avail -= len;
+
+		if (!first)
+			first = new;
+		else
+			list_add_tail(&new->node, &first->tx_list);
+fetch:
+		/* Fetch the next dst scatterlist entry */
+		if (dst_avail == 0) {
+			if (dst_sg_len == 0)
+				break;
+			dst_sg = sg_next(dst_sg);
+			if (dst_sg == NULL)
+				break;
+			dst_sg_len--;
+			dst_avail = sg_dma_len(dst_sg);
+		}
+		/* Fetch the next src scatterlist entry */
+		if (src_avail == 0) {
+			if (src_sg_len == 0)
+				break;
+			src_sg = sg_next(src_sg);
+			if (src_sg == NULL)
+				break;
+			src_sg_len--;
+			src_avail = sg_dma_len(src_sg);
+		}
+	}
+
+	zynqmp_dma_desc_config_eod(chan, desc);
+	first->async_tx.flags = flags;
+	return &first->async_tx;
+}
+
+/**
+ * zynqmp_dma_chan_remove - Channel remove function
+ * @chan: ZynqMP DMA channel pointer
+ */
+static void zynqmp_dma_chan_remove(struct zynqmp_dma_chan *chan)
+{
+	if (!chan)
+		return;
+
+	devm_free_irq(chan->zdev->dev, chan->irq, chan);
+	tasklet_kill(&chan->tasklet);
+	list_del(&chan->common.device_node);
+}
+
+/**
+ * zynqmp_dma_chan_probe - Per Channel Probing
+ * @zdev: Driver specific device structure
+ * @pdev: Pointer to the platform_device structure
+ *
+ * Return: '0' on success and failure value on error
+ */
+static int zynqmp_dma_chan_probe(struct zynqmp_dma_device *zdev,
+			   struct platform_device *pdev)
+{
+	struct zynqmp_dma_chan *chan;
+	struct resource *res;
+	struct device_node *node = pdev->dev.of_node;
+	int err;
+
+	chan = devm_kzalloc(zdev->dev, sizeof(*chan), GFP_KERNEL);
+	if (!chan)
+		return -ENOMEM;
+	chan->dev = zdev->dev;
+	chan->zdev = zdev;
+
+	res = platform_get_resource(pdev, IORESOURCE_MEM, 0);
+	chan->regs = devm_ioremap_resource(&pdev->dev, res);
+	if (IS_ERR(chan->regs))
+		return PTR_ERR(chan->regs);
+
+	chan->bus_width = ZYNQMP_DMA_BUS_WIDTH_64;
+	chan->src_issue = ZYNQMP_DMA_SRC_ISSUE_RST_VAL;
+	chan->dst_burst_len = ZYNQMP_DMA_AWLEN_RST_VAL;
+	chan->src_burst_len = ZYNQMP_DMA_ARLEN_RST_VAL;
+	chan->dst_axi_cache = ZYNQMP_DMA_AWCACHE_RST_VAL;
+	chan->src_axi_cache = ZYNQMP_DMA_ARCACHE_RST_VAL;
+	err = of_property_read_u32(node, "xlnx,bus-width", &chan->bus_width);
+	if ((err < 0) && ((chan->bus_width != ZYNQMP_DMA_BUS_WIDTH_64) ||
+			  (chan->bus_width != ZYNQMP_DMA_BUS_WIDTH_128))) {
+		dev_err(zdev->dev, "invalid bus-width value");
+		return err;
+	}
+	chan->has_sg = of_property_read_bool(node, "xlnx,include-sg");
+	chan->ovrfetch = of_property_read_bool(node, "xlnx,overfetch");
+	chan->desc_axi_cohrnt =
+			of_property_read_bool(node, "xlnx,desc-axi-cohrnt");
+	chan->src_axi_cohrnt =
+			of_property_read_bool(node, "xlnx,src-axi-cohrnt");
+	chan->dst_axi_cohrnt =
+			of_property_read_bool(node, "xlnx,dst-axi-cohrnt");
+
+	of_property_read_u32(node, "xlnx,desc-axi-qos", &chan->desc_axi_qos);
+	of_property_read_u32(node, "xlnx,desc-axi-cache",
+			     &chan->desc_axi_cache);
+	of_property_read_u32(node, "xlnx,src-axi-qos", &chan->src_axi_qos);
+	of_property_read_u32(node, "xlnx,src-axi-cache", &chan->src_axi_cache);
+	of_property_read_u32(node, "xlnx,dst-axi-qos", &chan->dst_axi_qos);
+	of_property_read_u32(node, "xlnx,dst-axi-cache", &chan->dst_axi_cache);
+	of_property_read_u32(node, "xlnx,src-burst-len", &chan->src_burst_len);
+	of_property_read_u32(node, "xlnx,dst-burst-len", &chan->dst_burst_len);
+	of_property_read_u32(node, "xlnx,ratectrl", &chan->ratectrl);
+	of_property_read_u32(node, "xlnx,src-issue", &chan->src_issue);
+
+	zdev->chan = chan;
+	tasklet_init(&chan->tasklet, zynqmp_dma_do_tasklet, (ulong)chan);
+	spin_lock_init(&chan->lock);
+	INIT_LIST_HEAD(&chan->active_list);
+	INIT_LIST_HEAD(&chan->pending_list);
+	INIT_LIST_HEAD(&chan->done_list);
+	INIT_LIST_HEAD(&chan->free_list);
+
+	dma_cookie_init(&chan->common);
+	chan->common.device = &zdev->common;
+	list_add_tail(&chan->common.device_node, &zdev->common.channels);
+
+	zynqmp_dma_init(chan);
+	chan->irq = platform_get_irq(pdev, 0);
+	if (chan->irq < 0)
+		return -ENXIO;
+	err = devm_request_irq(&pdev->dev, chan->irq, zynqmp_dma_irq_handler, 0,
+			       "zynqmp-dma", chan);
+	if (err)
+		return err;
+
+	chan->desc_size = sizeof(struct zynqmp_dma_desc_ll);
+	return 0;
+}
+
+/**
+ * of_zynqmp_dma_xlate - Translation function
+ * @dma_spec: Pointer to DMA specifier as found in the device tree
+ * @ofdma: Pointer to DMA controller data
+ *
+ * Return: DMA channel pointer on success and NULL on error
+ */
+static struct dma_chan *of_zynqmp_dma_xlate(struct of_phandle_args *dma_spec,
+					    struct of_dma *ofdma)
+{
+	struct zynqmp_dma_device *zdev = ofdma->of_dma_data;
+
+	return dma_get_slave_channel(&zdev->chan->common);
+}
+
+/**
+ * zynqmp_dma_probe - Driver probe function
+ * @pdev: Pointer to the platform_device structure
+ *
+ * Return: '0' on success and failure value on error
+ */
+static int zynqmp_dma_probe(struct platform_device *pdev)
+{
+	struct zynqmp_dma_device *zdev;
+	struct dma_device *p;
+	int ret;
+
+	zdev = devm_kzalloc(&pdev->dev, sizeof(*zdev), GFP_KERNEL);
+	if (!zdev)
+		return -ENOMEM;
+
+	zdev->dev = &pdev->dev;
+	INIT_LIST_HEAD(&zdev->common.channels);
+
+	dma_set_mask(&pdev->dev, DMA_BIT_MASK(44));
+	dma_cap_set(DMA_SG, zdev->common.cap_mask);
+	dma_cap_set(DMA_MEMCPY, zdev->common.cap_mask);
+
+	p = &zdev->common;
+	p->device_prep_dma_sg = zynqmp_dma_prep_sg;
+	p->device_prep_dma_memcpy = zynqmp_dma_prep_memcpy;
+	p->device_terminate_all = zynqmp_dma_device_terminate_all;
+	p->device_issue_pending = zynqmp_dma_issue_pending;
+	p->device_alloc_chan_resources = zynqmp_dma_alloc_chan_resources;
+	p->device_free_chan_resources = zynqmp_dma_free_chan_resources;
+	p->device_tx_status = zynqmp_dma_tx_status;
+	p->dev = &pdev->dev;
+
+	platform_set_drvdata(pdev, zdev);
+
+	ret = zynqmp_dma_chan_probe(zdev, pdev);
+	if (ret) {
+		dev_err(&pdev->dev, "Probing channel failed\n");
+		goto free_chan_resources;
+	}
+
+	p->dst_addr_widths = zdev->chan->bus_width / 8;
+	p->src_addr_widths = zdev->chan->bus_width / 8;
+
+	dma_async_device_register(&zdev->common);
+
+	ret = of_dma_controller_register(pdev->dev.of_node,
+					 of_zynqmp_dma_xlate, zdev);
+	if (ret) {
+		dev_err(&pdev->dev, "Unable to register DMA to DT\n");
+		dma_async_device_unregister(&zdev->common);
+		goto free_chan_resources;
+	}
+
+	dev_info(&pdev->dev, "ZynqMP DMA driver Probe success\n");
+
+	return 0;
+
+free_chan_resources:
+	zynqmp_dma_chan_remove(zdev->chan);
+	return ret;
+}
+
+/**
+ * zynqmp_dma_remove - Driver remove function
+ * @pdev: Pointer to the platform_device structure
+ *
+ * Return: Always '0'
+ */
+static int zynqmp_dma_remove(struct platform_device *pdev)
+{
+	struct zynqmp_dma_device *zdev = platform_get_drvdata(pdev);
+
+	of_dma_controller_free(pdev->dev.of_node);
+	dma_async_device_unregister(&zdev->common);
+
+	zynqmp_dma_chan_remove(zdev->chan);
+
+	return 0;
+}
+
+static const struct of_device_id zynqmp_dma_of_match[] = {
+	{ .compatible = "xlnx,zynqmp-dma-1.0", },
+	{}
+};
+MODULE_DEVICE_TABLE(of, zynqmp_dma_of_match);
+
+static struct platform_driver zynqmp_dma_driver = {
+	.driver = {
+		.name = "xilinx-zynqmp-dma",
+		.of_match_table = zynqmp_dma_of_match,
+	},
+	.probe = zynqmp_dma_probe,
+	.remove = zynqmp_dma_remove,
+};
+
+module_platform_driver(zynqmp_dma_driver);
+
+MODULE_AUTHOR("Xilinx, Inc.");
+MODULE_DESCRIPTION("Xilinx ZynqMP DMA driver");
+MODULE_LICENSE("GPL");
-- 
1.7.4



From agross at codeaurora.org  Wed Aug  5 20:30:17 2015
From: agross at codeaurora.org (Andy Gross)
Date: Wed, 5 Aug 2015 22:30:17 -0500
Subject: [PATCH v5 2/2] firmware: qcom: scm: Add support for ARM64 SoCs
In-Reply-To: <55C2B7FC.5090402@codeaurora.org>
References: <1430249038-30987-1-git-send-email-galak@codeaurora.org>
 <1430249038-30987-2-git-send-email-galak@codeaurora.org>
 <55C2B7FC.5090402@codeaurora.org>
Message-ID: <20150806033017.GB11996@qualcomm.com>

On Wed, Aug 05, 2015 at 06:27:24PM -0700, Stephen Boyd wrote:
> On 04/28/2015 12:23 PM, Kumar Gala wrote:
> >+
> >+int __qcom_scm_call_armv8_64(u64 x0, u64 x1, u64 x2, u64 x3, u64 x4, u64 x5,
> >+				u64 *ret1, u64 *ret2, u64 *ret3)
> >+{
> >+	register u64 r0 asm("r0") = x0;
> >+	register u64 r1 asm("r1") = x1;
> >+	register u64 r2 asm("r2") = x2;
> >+	register u64 r3 asm("r3") = x3;
> >+	register u64 r4 asm("r4") = x4;
> >+	register u64 r5 asm("r5") = x5;
> 
> This should set x6 to 0.
> 
>     register u32 r6 asm("r6") = 0;
> 
> for example.
> 
> >+
> >+	do {
> >+		asm volatile(
> >+			__asmeq("%0", "x0")
> >+			__asmeq("%1", "x1")
> >+			__asmeq("%2", "x2")
> >+			__asmeq("%3", "x3")
> >+			__asmeq("%4", "x0")
> >+			__asmeq("%5", "x1")
> >+			__asmeq("%6", "x2")
> >+			__asmeq("%7", "x3")
> >+			__asmeq("%8", "x4")
> >+			__asmeq("%9", "x5")
> 
> And then the asmeq thing here for x6.
> 
> >+#ifdef REQUIRES_SEC
> >+			".arch_extension sec\n"
> >+#endif
> >+			"smc	#0\n"
> >+			: "=r" (r0), "=r" (r1), "=r" (r2), "=r" (r3)
> >+			: "r" (r0), "r" (r1), "r" (r2), "r" (r3), "r" (r4),
> >+			  "r" (r5)
> 
> And add x6 as an input here.
> 
> >+			: "x6", "x7", "x8", "x9", "x10", "x11", "x12", "x13",
> 
> and remove x6 as a clobber.
> 
> >+			  "x14", "x15", "x16", "x17");
> >+	} while (r0 == QCOM_SCM_INTERRUPTED);
> >+
> >+	if (ret1)
> >+		*ret1 = r1;
> >+	if (ret2)
> >+		*ret2 = r2;
> >+	if (ret3)
> >+		*ret3 = r3;
> >+
> >+	return r0;
> >+}
> >+
> >+int __qcom_scm_call_armv8_32(u32 w0, u32 w1, u32 w2, u32 w3, u32 w4, u32 w5,
> >+				u64 *ret1, u64 *ret2, u64 *ret3)
> >+{
> >+	register u32 r0 asm("r0") = w0;
> >+	register u32 r1 asm("r1") = w1;
> >+	register u32 r2 asm("r2") = w2;
> >+	register u32 r3 asm("r3") = w3;
> >+	register u32 r4 asm("r4") = w4;
> >+	register u32 r5 asm("r5") = w5;
> 
> This needs to set r6 to 0 as well
> 
>     register u32 r6 asm("r6") = 0;
> 
> for example.
> 
> >+
> >+	do {
> >+		asm volatile(
> >+			__asmeq("%0", "x0")
> >+			__asmeq("%1", "x1")
> >+			__asmeq("%2", "x2")
> >+			__asmeq("%3", "x3")
> >+			__asmeq("%4", "x0")
> >+			__asmeq("%5", "x1")
> >+			__asmeq("%6", "x2")
> >+			__asmeq("%7", "x3")
> >+			__asmeq("%8", "x4")
> >+			__asmeq("%9", "x5")
> 
> And then another asmeq thing here for x6.
> 
> >+#ifdef REQUIRES_SEC
> >+			".arch_extension sec\n"
> >+#endif
> >+			"smc	#0\n"
> >+			: "=r" (r0), "=r" (r1), "=r" (r2), "=r" (r3)
> >+			: "r" (r0), "r" (r1), "r" (r2), "r" (r3), "r" (r4),
> >+			  "r" (r5)
> 
> And then add r6 here as an input
> 
> >+			: "x6", "x7", "x8", "x9", "x10", "x11", "x12", "x13",
> 
> And remove r6 from the clobber.
> 
> >+			"x14", "x15", "x16", "x17");
> >+
> >+	} while (r0 == QCOM_SCM_INTERRUPTED);
> >+
> >+	if (ret1)
> >+		*ret1 = r1;
> >+	if (ret2)
> >+		*ret2 = r2;
> >+	if (ret3)
> >+		*ret3 = r3;
> >+
> >+	return r0;
> >+}
> >+
> >
> 
> Here's a totally untested patch for that.
> 
> Signed-off-by: Stephen Boyd <sboyd at codeaurora.org>
> ----8<-----
> 
> diff --git a/drivers/firmware/qcom_scm-64.c b/drivers/firmware/qcom_scm-64.c
> index a95fd9b5d576..8f7e65ff524c 100644
> --- a/drivers/firmware/qcom_scm-64.c
> +++ b/drivers/firmware/qcom_scm-64.c
> @@ -114,6 +114,7 @@ int __qcom_scm_call_armv8_64(u64 x0, u64 x1, u64 x2, u64 x3, u64 x4, u64 x5,
>  	register u64 r3 asm("r3") = x3;
>  	register u64 r4 asm("r4") = x4;
>  	register u64 r5 asm("r5") = x5;
> +	register u64 r6 asm("r5") = 0;
>  	do {
>  		asm volatile(
> @@ -127,14 +128,15 @@ int __qcom_scm_call_armv8_64(u64 x0, u64 x1, u64 x2, u64 x3, u64 x4, u64 x5,
>  			__asmeq("%7", "x3")
>  			__asmeq("%8", "x4")
>  			__asmeq("%9", "x5")
> +			__asmeq("%10", "x6")
>  #ifdef REQUIRES_SEC
>  			".arch_extension sec\n"
>  #endif
>  			"smc	#0\n"
>  			: "=r" (r0), "=r" (r1), "=r" (r2), "=r" (r3)
>  			: "r" (r0), "r" (r1), "r" (r2), "r" (r3), "r" (r4),
> -			  "r" (r5)
> -			: "x6", "x7", "x8", "x9", "x10", "x11", "x12", "x13",
> +			  "r" (r5), "r" (r6)
> +			: "x7", "x8", "x9", "x10", "x11", "x12", "x13",
>  			  "x14", "x15", "x16", "x17");
>  	} while (r0 == QCOM_SCM_INTERRUPTED);
> @@ -157,6 +159,7 @@ int __qcom_scm_call_armv8_32(u32 w0, u32 w1, u32 w2, u32 w3, u32 w4, u32 w5,
>  	register u32 r3 asm("r3") = w3;
>  	register u32 r4 asm("r4") = w4;
>  	register u32 r5 asm("r5") = w5;
> +	register u32 r6 asm("r6") = 0;
>  	do {
>  		asm volatile(
> @@ -170,14 +173,15 @@ int __qcom_scm_call_armv8_32(u32 w0, u32 w1, u32 w2, u32 w3, u32 w4, u32 w5,
>  			__asmeq("%7", "x3")
>  			__asmeq("%8", "x4")
>  			__asmeq("%9", "x5")
> +			__asmeq("%10", "x6")
>  #ifdef REQUIRES_SEC
>  			".arch_extension sec\n"
>  #endif
>  			"smc	#0\n"
>  			: "=r" (r0), "=r" (r1), "=r" (r2), "=r" (r3)
>  			: "r" (r0), "r" (r1), "r" (r2), "r" (r3), "r" (r4),
> -			  "r" (r5)
> -			: "x6", "x7", "x8", "x9", "x10", "x11", "x12", "x13",
> +			  "r" (r5), "r" (r6)
> +			: "x7", "x8", "x9", "x10", "x11", "x12", "x13",
>  			"x14", "x15", "x16", "x17");
>  	} while (r0 == QCOM_SCM_INTERRUPTED);
> 
> -- 

Stephen, I'll incorporate this in the next version.  Thanks!

-- 
Qualcomm Innovation Center, Inc.
The Qualcomm Innovation Center, Inc. is a member of the Code Aurora Forum,
a Linux Foundation Collaborative Project



From axel.lin at ingics.com  Wed Aug  5 21:28:18 2015
From: axel.lin at ingics.com (Axel Lin)
Date: Thu, 06 Aug 2015 12:28:18 +0800
Subject: [PATCH v2] ata: ahci_brcmstb: Fix misuse of IS_ENABLED
Message-ID: <1438835298.28215.1.camel@ingics.com>

While IS_ENABLED() is perfectly fine for CONFIG_* symbols, it is not
for other symbols such as __BIG_ENDIAN that is provided directly by
the compiler.

Switch to use CONFIG_CPU_BIG_ENDIAN instead of __BIG_ENDIAN.

Signed-off-by: Axel Lin <axel.lin at ingics.com>
---
v2:
Based on Florian's comment:
Switch to use CONFIG_CPU_BIG_ENDIAN instead of __BIG_ENDIAN.

 drivers/ata/ahci_brcmstb.c | 4 ++--
 1 file changed, 2 insertions(+), 2 deletions(-)

diff --git a/drivers/ata/ahci_brcmstb.c b/drivers/ata/ahci_brcmstb.c
index 42b6cf4..14b7305 100644
--- a/drivers/ata/ahci_brcmstb.c
+++ b/drivers/ata/ahci_brcmstb.c
@@ -92,7 +92,7 @@ static inline u32 brcm_sata_readreg(void __iomem *addr)
 	 * Other architectures (e.g., ARM) either do not support big endian, or
 	 * else leave I/O in little endian mode.
 	 */
-	if (IS_ENABLED(CONFIG_MIPS) && IS_ENABLED(__BIG_ENDIAN))
+	if (IS_ENABLED(CONFIG_MIPS) && IS_ENABLED(CONFIG_CPU_BIG_ENDIAN))
 		return __raw_readl(addr);
 	else
 		return readl_relaxed(addr);
@@ -101,7 +101,7 @@ static inline u32 brcm_sata_readreg(void __iomem *addr)
 static inline void brcm_sata_writereg(u32 val, void __iomem *addr)
 {
 	/* See brcm_sata_readreg() comments */
-	if (IS_ENABLED(CONFIG_MIPS) && IS_ENABLED(__BIG_ENDIAN))
+	if (IS_ENABLED(CONFIG_MIPS) && IS_ENABLED(CONFIG_CPU_BIG_ENDIAN))
 		__raw_writel(val, addr);
 	else
 		writel_relaxed(val, addr);
-- 
2.1.0





From michal.simek at xilinx.com  Wed Aug  5 21:54:23 2015
From: michal.simek at xilinx.com (Michal Simek)
Date: Thu, 6 Aug 2015 06:54:23 +0200
Subject: [RFCv3 1/4] docs: dts: Added documentation for Xilinx Zynq Reset
 Controller bindings.
In-Reply-To: <CAAtXAHfJF-5PAgCc4ZC71omc_ye6L4qa2ks2E1BdoSXxDzZu1A@mail.gmail.com>
References: <1438305237-18497-1-git-send-email-moritz.fischer@ettus.com>
 <1438305237-18497-2-git-send-email-moritz.fischer@ettus.com>
 <1438675772.3793.18.camel@pengutronix.de>
 <CAAtXAHeauiD5smAqMbheJWuv4BT-2YqJWOSBjYPq900icpT1Rg@mail.gmail.com>
 <1438701017.3793.45.camel@pengutronix.de>
 <CAAtXAHfJF-5PAgCc4ZC71omc_ye6L4qa2ks2E1BdoSXxDzZu1A@mail.gmail.com>
Message-ID: <55C2E87F.7060502@xilinx.com>

On 08/05/2015 09:43 PM, Moritz Fischer wrote:
> Michal,
> 
> On Tue, Aug 4, 2015 at 8:10 AM, Philipp Zabel <p.zabel at pengutronix.de> wrote:
>> Hi Moritz,
>>
>> Am Dienstag, den 04.08.2015, 08:05 -0700 schrieb Moritz Fischer:
>>> Hi Philip,
>>>
>>> On Tue, Aug 4, 2015 at 1:09 AM, Philipp Zabel <p.zabel at pengutronix.de> wrote:
>>>> Hi Moritz,
>>>>
>>>> Am Donnerstag, den 30.07.2015, 18:13 -0700 schrieb Moritz Fischer:
>> [...]
>>>>> +Required properties:
>>>>> +- compatible: "xlnx,zynq-reset"
>>>>> +- reg: SLCR offset and size taken via syscon <0x200 0x48>
>>>>> +- syscon: <&slcr>
>>>>> +  This should be a phandle to the Zynq's SLCR register.
>>>>
>>>>                                                  ^ register singular?
>>> Do you want me to resend the entire set, or are you cool with just git
>>> amending the 's' for registers?
>>
>> Amended and applied, thanks.
> 
> Will you take 4/4 and 2/4 via your tree?

Applied to zynq/dt and zynq/soc.

Thanks,
Michal



From wenyou.yang at atmel.com  Wed Aug  5 21:59:28 2015
From: wenyou.yang at atmel.com (Wenyou Yang)
Date: Thu, 6 Aug 2015 12:59:28 +0800
Subject: [PATCH v4 0/2] add a new driver to support SAMA5D4 watchdog timer
Message-ID: <1438837170-4518-1-git-send-email-wenyou.yang@atmel.com>

Hello,

Because the watchdog WDT_MR register can be written more than once,
its work mechanism is different from the at91sam9260 watchdog driver.
Open the device file to enable the watchdog hardware, close to disable it,
and ping it from the user space directly to keep it alive.

Changes from v3.0
 1./ Change the driver name to 'sama5d4_wdt' for more acceptable.
 2./ Change the prefix of function name and struct name
     from 'atmel_' to 'sama5d4_', and others.

Changes from v2.0
 1./ Use a specific driver name, at91_sama5d4_wdt.c.
 2./ Remove '-' at the end of macro name and unnecessary check.
 3./ Use alphabetic order for include files.

Wenyou Yang (2):
  drivers: watchdog: add a driver to support SAMA5D4 watchdog timer
  Documentation: dt: binding: atmel-sama5d4-wdt: for SAMA5D4 watchdog
    driver

 .../bindings/watchdog/atmel-sama5d4-wdt.txt        |   35 +++
 drivers/watchdog/Kconfig                           |    9 +
 drivers/watchdog/Makefile                          |    1 +
 drivers/watchdog/at91sam9_wdt.h                    |    2 +
 drivers/watchdog/sama5d4_wdt.c                     |  279 ++++++++++++++++++++
 5 files changed, 326 insertions(+)
 create mode 100644 Documentation/devicetree/bindings/watchdog/atmel-sama5d4-wdt.txt
 create mode 100644 drivers/watchdog/sama5d4_wdt.c

-- 
1.7.9.5



From wenyou.yang at atmel.com  Wed Aug  5 21:59:29 2015
From: wenyou.yang at atmel.com (Wenyou Yang)
Date: Thu, 6 Aug 2015 12:59:29 +0800
Subject: [PATCH v4 1/2] drivers: watchdog: add a driver to support SAMA5D4
 watchdog timer
In-Reply-To: <1438837170-4518-1-git-send-email-wenyou.yang@atmel.com>
References: <1438837170-4518-1-git-send-email-wenyou.yang@atmel.com>
Message-ID: <1438837170-4518-2-git-send-email-wenyou.yang@atmel.com>

>From SAMA5D4, the watchdog timer is upgrated with a new feature,
which is describled as in the datasheet, "WDT_MR can be written
until a LOCKMR command is issued in WDT_CR".
That is to say, as long as the bootstrap and u-boot don't issue
a LOCKMR command, WDT_MR can be written more than once in the driver.

So the SAMA5D4 watchdog driver's implementation is different from
the at91sam9260 watchdog driver implemented in file at91sam9_wdt.c.
The user application open the device file to enable the watchdog timer
hardware, and close to disable it, and set the watchdog timer timeout
by seting WDV and WDD fields of WDT_MR register, and ping the watchdog
by issuing WDRSTT command to WDT_CR register with hard-coded key.

Signed-off-by: Wenyou Yang <wenyou.yang at atmel.com>
---
 drivers/watchdog/Kconfig        |    9 ++
 drivers/watchdog/Makefile       |    1 +
 drivers/watchdog/at91sam9_wdt.h |    2 +
 drivers/watchdog/sama5d4_wdt.c  |  279 +++++++++++++++++++++++++++++++++++++++
 4 files changed, 291 insertions(+)
 create mode 100644 drivers/watchdog/sama5d4_wdt.c

diff --git a/drivers/watchdog/Kconfig b/drivers/watchdog/Kconfig
index e5e7c55..47ad39a 100644
--- a/drivers/watchdog/Kconfig
+++ b/drivers/watchdog/Kconfig
@@ -167,6 +167,15 @@ config AT91SAM9X_WATCHDOG
 	  Watchdog timer embedded into AT91SAM9X and AT91CAP9 chips. This will
 	  reboot your system when the timeout is reached.
 
+config SAMA5D4_WATCHDOG
+	tristate "Atmel SAMA5D4 Watchdog Timer"
+	depends on ARCH_AT91
+	select WATCHDOG_CORE
+	help
+	  Atmel SAMA5D4 watchdog timer is embedded into SAMA5D4 chips.
+	  Its Watchdog Timer Mode Register can be written more than once.
+	  This will reboot your system when the timeout is reached.
+
 config CADENCE_WATCHDOG
 	tristate "Cadence Watchdog Timer"
 	select WATCHDOG_CORE
diff --git a/drivers/watchdog/Makefile b/drivers/watchdog/Makefile
index 5c19294..f24b820 100644
--- a/drivers/watchdog/Makefile
+++ b/drivers/watchdog/Makefile
@@ -41,6 +41,7 @@ obj-$(CONFIG_IXP4XX_WATCHDOG) += ixp4xx_wdt.o
 obj-$(CONFIG_KS8695_WATCHDOG) += ks8695_wdt.o
 obj-$(CONFIG_S3C2410_WATCHDOG) += s3c2410_wdt.o
 obj-$(CONFIG_SA1100_WATCHDOG) += sa1100_wdt.o
+obj-$(CONFIG_SAMA5D4_WATCHDOG) += sama5d4_wdt.o
 obj-$(CONFIG_DW_WATCHDOG) += dw_wdt.o
 obj-$(CONFIG_EP93XX_WATCHDOG) += ep93xx_wdt.o
 obj-$(CONFIG_PNX4008_WATCHDOG) += pnx4008_wdt.o
diff --git a/drivers/watchdog/at91sam9_wdt.h b/drivers/watchdog/at91sam9_wdt.h
index c6fbb2e6..b79a83b 100644
--- a/drivers/watchdog/at91sam9_wdt.h
+++ b/drivers/watchdog/at91sam9_wdt.h
@@ -22,11 +22,13 @@
 
 #define AT91_WDT_MR		0x04			/* Watchdog Mode Register */
 #define		AT91_WDT_WDV		(0xfff << 0)		/* Counter Value */
+#define			AT91_WDT_SET_WDV(x)	((x) & AT91_WDT_WDV)
 #define		AT91_WDT_WDFIEN		(1     << 12)		/* Fault Interrupt Enable */
 #define		AT91_WDT_WDRSTEN	(1     << 13)		/* Reset Processor */
 #define		AT91_WDT_WDRPROC	(1     << 14)		/* Timer Restart */
 #define		AT91_WDT_WDDIS		(1     << 15)		/* Watchdog Disable */
 #define		AT91_WDT_WDD		(0xfff << 16)		/* Delta Value */
+#define			AT91_WDT_SET_WDD(x)	(((x) << 16) & AT91_WDT_WDD)
 #define		AT91_WDT_WDDBGHLT	(1     << 28)		/* Debug Halt */
 #define		AT91_WDT_WDIDLEHLT	(1     << 29)		/* Idle Halt */
 
diff --git a/drivers/watchdog/sama5d4_wdt.c b/drivers/watchdog/sama5d4_wdt.c
new file mode 100644
index 0000000..db67c7e
--- /dev/null
+++ b/drivers/watchdog/sama5d4_wdt.c
@@ -0,0 +1,279 @@
+/*
+ * Driver for Atmel SAMA5D4 Watchdog Timer
+ *
+ * Copyright (C) 2015 Atmel Corporation
+ *
+ * Licensed under GPLv2.
+ */
+
+#include <linux/interrupt.h>
+#include <linux/io.h>
+#include <linux/kernel.h>
+#include <linux/module.h>
+#include <linux/of.h>
+#include <linux/of_irq.h>
+#include <linux/platform_device.h>
+#include <linux/reboot.h>
+#include <linux/watchdog.h>
+
+#include "at91sam9_wdt.h"
+
+/* minimum and maximum watchdog timeout, in seconds */
+#define	MIN_WDT_TIMEOUT		1
+#define	MAX_WDT_TIMEOUT		16
+#define	WDT_DEFAULT_TIMEOUT	MAX_WDT_TIMEOUT
+
+#define	WDT_SEC2TICKS(s)	((s) ? (((s) << 8) - 1) : 0)
+
+struct sama5d4_wdt {
+	struct watchdog_device	wdd;
+	void __iomem		*reg_base;
+	u32	config;
+};
+
+static int wdt_timeout = WDT_DEFAULT_TIMEOUT;
+static bool nowayout = WATCHDOG_NOWAYOUT;
+
+module_param(wdt_timeout, int, 0);
+MODULE_PARM_DESC(wdt_timeout,
+	"Watchdog timeout in seconds. (default = "
+	__MODULE_STRING(WDT_DEFAULT_TIMEOUT) ")");
+
+module_param(nowayout, bool, 0);
+MODULE_PARM_DESC(nowayout,
+	"Watchdog cannot be stopped once started (default="
+	__MODULE_STRING(WATCHDOG_NOWAYOUT) ")");
+
+#define wdt_read(wdt, field) \
+	readl_relaxed((wdt)->reg_base + (field))
+
+#define wdt_write(wtd, field, val) \
+	writel_relaxed((val), (wdt)->reg_base + (field))
+
+static int sama5d4_wdt_start(struct watchdog_device *wdd)
+{
+	struct sama5d4_wdt *wdt = watchdog_get_drvdata(wdd);
+	u32 reg;
+
+	reg = wdt_read(wdt, AT91_WDT_MR);
+	reg &= ~AT91_WDT_WDDIS;
+	wdt_write(wdt, AT91_WDT_MR, reg);
+
+	return 0;
+}
+
+static int sama5d4_wdt_stop(struct watchdog_device *wdd)
+{
+	struct sama5d4_wdt *wdt = watchdog_get_drvdata(wdd);
+	u32 reg;
+
+	reg = wdt_read(wdt, AT91_WDT_MR);
+	reg |= AT91_WDT_WDDIS;
+	wdt_write(wdt, AT91_WDT_MR, reg);
+
+	return 0;
+}
+
+static int sama5d4_wdt_ping(struct watchdog_device *wdd)
+{
+	struct sama5d4_wdt *wdt = watchdog_get_drvdata(wdd);
+
+	wdt_write(wdt, AT91_WDT_CR, AT91_WDT_KEY | AT91_WDT_WDRSTT);
+
+	return 0;
+}
+
+static int sama5d4_wdt_set_timeout(struct watchdog_device *wdd,
+				 unsigned int timeout)
+{
+	struct sama5d4_wdt *wdt = watchdog_get_drvdata(wdd);
+	u32 value = WDT_SEC2TICKS(timeout);
+	u32 reg;
+
+	reg = wdt_read(wdt, AT91_WDT_MR);
+	reg &= ~AT91_WDT_WDV;
+	reg &= ~AT91_WDT_WDD;
+	reg |= AT91_WDT_SET_WDV(value);
+	reg |= AT91_WDT_SET_WDD(value);
+	wdt_write(wdt, AT91_WDT_MR, reg);
+
+	wdd->timeout = timeout;
+
+	return 0;
+}
+
+static const struct watchdog_info sama5d4_wdt_info = {
+	.options = WDIOF_SETTIMEOUT | WDIOF_MAGICCLOSE | WDIOF_KEEPALIVEPING,
+	.identity = "Atmel SAMA5D4 Watchdog"
+};
+
+static struct watchdog_ops sama5d4_wdt_ops = {
+	.owner = THIS_MODULE,
+	.start = sama5d4_wdt_start,
+	.stop = sama5d4_wdt_stop,
+	.ping = sama5d4_wdt_ping,
+	.set_timeout = sama5d4_wdt_set_timeout
+};
+
+static irqreturn_t sama5d4_wdt_irq_handler(int irq, void *dev_id)
+{
+	struct sama5d4_wdt *wdt = platform_get_drvdata(dev_id);
+
+	if (wdt_read(wdt, AT91_WDT_SR)) {
+		pr_crit("Atmel Watchdog Software Reset\n");
+		emergency_restart();
+		pr_crit("Reboot didn't succeed\n");
+	}
+
+	return IRQ_HANDLED;
+}
+
+static int of_sama5d4_wdt_init(struct device_node *np, struct sama5d4_wdt *wdt)
+{
+	const char *tmp;
+
+	wdt->config = AT91_WDT_WDDIS;
+
+	if (!of_property_read_string(np, "atmel,watchdog-type", &tmp) &&
+	    !strcmp(tmp, "software"))
+		wdt->config |= AT91_WDT_WDFIEN;
+	else
+		wdt->config |= AT91_WDT_WDRSTEN;
+
+	if (of_property_read_bool(np, "atmel,idle-halt"))
+		wdt->config |= AT91_WDT_WDIDLEHLT;
+
+	if (of_property_read_bool(np, "atmel,dbg-halt"))
+		wdt->config |= AT91_WDT_WDDBGHLT;
+
+	return 0;
+}
+
+static int sama5d4_wdt_init(struct sama5d4_wdt *wdt)
+{
+	struct watchdog_device *wdd = &wdt->wdd;
+	u32 value = WDT_SEC2TICKS(wdd->timeout);
+	u32 reg;
+
+	/*
+	 * Because the fields WDV and WDD must not be modified when the WDDIS
+	 * bit is set, so clear the WDDIS bit before writing the WDT_MR.
+	 */
+	reg = wdt_read(wdt, AT91_WDT_MR);
+	reg &= ~AT91_WDT_WDDIS;
+	wdt_write(wdt, AT91_WDT_MR, reg);
+
+	reg = wdt->config;
+	reg |= AT91_WDT_SET_WDD(value);
+	reg |= AT91_WDT_SET_WDV(value);
+
+	wdt_write(wdt, AT91_WDT_MR, reg);
+
+	return 0;
+}
+
+static int sama5d4_wdt_probe(struct platform_device *pdev)
+{
+	struct watchdog_device *wdd;
+	struct sama5d4_wdt *wdt;
+	struct resource *res;
+	void __iomem *regs;
+	u32 irq = 0;
+	int ret;
+
+	wdt = devm_kzalloc(&pdev->dev, sizeof(*wdt), GFP_KERNEL);
+	if (!wdt)
+		return -ENOMEM;
+
+	wdd = &wdt->wdd;
+	wdd->timeout = wdt_timeout;
+	wdd->info = &sama5d4_wdt_info;
+	wdd->ops = &sama5d4_wdt_ops;
+	wdd->min_timeout = MIN_WDT_TIMEOUT;
+	wdd->max_timeout = MAX_WDT_TIMEOUT;
+
+	watchdog_set_drvdata(wdd, wdt);
+
+	res = platform_get_resource(pdev, IORESOURCE_MEM, 0);
+	regs = devm_ioremap_resource(&pdev->dev, res);
+	if (IS_ERR(regs))
+		return PTR_ERR(regs);
+
+	wdt->reg_base = regs;
+
+	if (pdev->dev.of_node) {
+		irq = irq_of_parse_and_map(pdev->dev.of_node, 0);
+		if (!irq)
+			dev_warn(&pdev->dev, "failed to get IRQ from DT\n");
+
+		ret = of_sama5d4_wdt_init(pdev->dev.of_node, wdt);
+		if (ret)
+			return ret;
+	}
+
+	if ((wdt->config & AT91_WDT_WDFIEN) && irq) {
+		ret = devm_request_irq(&pdev->dev, irq, sama5d4_wdt_irq_handler,
+				       0, pdev->name, pdev);
+		if (ret) {
+			dev_err(&pdev->dev,
+				"cannot register interrupt handler\n");
+			return ret;
+		}
+	}
+
+	ret = watchdog_init_timeout(wdd, wdt_timeout, &pdev->dev);
+	if (ret) {
+		dev_err(&pdev->dev, "unable to set timeout value\n");
+		return ret;
+	}
+
+	ret = sama5d4_wdt_init(wdt);
+	if (ret)
+		return ret;
+
+	watchdog_set_nowayout(wdd, nowayout);
+
+	ret = watchdog_register_device(wdd);
+	if (ret) {
+		dev_err(&pdev->dev, "failed to register watchdog device\n");
+		return ret;
+	}
+
+	platform_set_drvdata(pdev, wdt);
+
+	dev_info(&pdev->dev, "initialized (timeout = %d sec, nowayout = %d)\n",
+		 wdt_timeout, nowayout);
+
+	return 0;
+}
+
+static int sama5d4_wdt_remove(struct platform_device *pdev)
+{
+	struct sama5d4_wdt *wdt = platform_get_drvdata(pdev);
+
+	sama5d4_wdt_stop(&wdt->wdd);
+
+	watchdog_unregister_device(&wdt->wdd);
+
+	return 0;
+}
+
+static const struct of_device_id sama5d4_wdt_of_match[] = {
+	{ .compatible = "atmel,sama5d4-wdt", },
+	{ }
+};
+MODULE_DEVICE_TABLE(of, sama5d4_wdt_of_match);
+
+static struct platform_driver sama5d4_wdt_driver = {
+	.probe		= sama5d4_wdt_probe,
+	.remove		= sama5d4_wdt_remove,
+	.driver		= {
+		.name	= "sama5d4_wdt",
+		.of_match_table = sama5d4_wdt_of_match,
+	}
+};
+module_platform_driver(sama5d4_wdt_driver);
+
+MODULE_AUTHOR("Atmel Corporation");
+MODULE_DESCRIPTION("Atmel SAMA5D4 Watchdog Timer driver");
+MODULE_LICENSE("GPL v2");
-- 
1.7.9.5



From wenyou.yang at atmel.com  Wed Aug  5 21:59:30 2015
From: wenyou.yang at atmel.com (Wenyou Yang)
Date: Thu, 6 Aug 2015 12:59:30 +0800
Subject: [PATCH v4 2/2] Documentation: dt: binding: atmel-sama5d4-wdt: for
 SAMA5D4 watchdog driver
In-Reply-To: <1438837170-4518-1-git-send-email-wenyou.yang@atmel.com>
References: <1438837170-4518-1-git-send-email-wenyou.yang@atmel.com>
Message-ID: <1438837170-4518-3-git-send-email-wenyou.yang@atmel.com>

The compatible "atmel,sama5d4-wdt" supports the SAMA5D4 watchdog driver
and the watchdog's WDT_MR register can be written more than once.

Signed-off-by: Wenyou Yang <wenyou.yang at atmel.com>
---
 .../bindings/watchdog/atmel-sama5d4-wdt.txt        |   35 ++++++++++++++++++++
 1 file changed, 35 insertions(+)
 create mode 100644 Documentation/devicetree/bindings/watchdog/atmel-sama5d4-wdt.txt

diff --git a/Documentation/devicetree/bindings/watchdog/atmel-sama5d4-wdt.txt b/Documentation/devicetree/bindings/watchdog/atmel-sama5d4-wdt.txt
new file mode 100644
index 0000000..f7cc7c0
--- /dev/null
+++ b/Documentation/devicetree/bindings/watchdog/atmel-sama5d4-wdt.txt
@@ -0,0 +1,35 @@
+* Atmel SAMA5D4 Watchdog Timer (WDT) Controller
+
+Required properties:
+- compatible: "atmel,sama5d4-wdt"
+- reg: base physical address and length of memory mapped region.
+
+Optional properties:
+- timeout-sec: watchdog timeout value (in seconds).
+- interrupts: interrupt number to the CPU.
+- atmel,watchdog-type: should be "hardware" or "software".
+	"hardware": enable watchdog fault reset. A watchdog fault triggers
+		    watchdog reset.
+	"software": enable watchdog fault interrupt. A watchdog fault asserts
+		    watchdog interrupt.
+- atmel,idle-halt: present if you want to stop the watchdog when the CPU is
+		   in idle state.
+	CAUTION: This property should be used with care, it actually makes the
+	watchdog not counting when the CPU is in idle state, therefore the
+	watchdog reset time depends on mean CPU usage and will not reset at all
+	if the CPU stop working while it is in idle state, which is probably
+	not what you want.
+- atmel,dbg-halt: present if you want to stop the watchdog when the CPU is
+		  in debug state.
+
+Example:
+	watchdog at fc068640 {
+		compatible = "atmel,sama5d4-wdt";
+		reg = <0xfc068640 0x10>;
+		interrupts = <4 IRQ_TYPE_LEVEL_HIGH 5>;
+		timeout-sec = <10>;
+		atmel,watchdog-type = "hardware";
+		atmel,dbg-halt;
+		atmel,idle-halt;
+		status = "okay";
+	};
-- 
1.7.9.5



From vaibhav.hiremath at linaro.org  Wed Aug  5 22:45:54 2015
From: vaibhav.hiremath at linaro.org (Vaibhav Hiremath)
Date: Thu, 06 Aug 2015 11:15:54 +0530
Subject: [PATCH-v5 5/5] i2c: pxa: Add ILCR (tLow & tHigh) configuration
 support
In-Reply-To: <87h9odlfe2.fsf@belgarion.home>
References: <1437482466-16126-1-git-send-email-vaibhav.hiremath@linaro.org>	<1437482466-16126-6-git-send-email-vaibhav.hiremath@linaro.org>	<55C1CE8E.9000601@linaro.org>
 <87h9odlfe2.fsf@belgarion.home>
Message-ID: <55C2F492.1090202@linaro.org>



On Thursday 06 August 2015 12:41 AM, Robert Jarzmik wrote:
> My next slot is probably this comming Sunday. I'll do the test and report

Thanks a lot.

Thanks,
Vaibhav


From raghumag at gmail.com  Wed Aug  5 22:54:36 2015
From: raghumag at gmail.com (raghu MG)
Date: Thu, 6 Aug 2015 11:24:36 +0530
Subject: Armadaxp GPIO interrupts
In-Reply-To: <20150805162155.GE32760@lunn.ch>
References: <CAG1O52Xg88OsifBzmpSdqvC8wQaOW78nC9nnfxugFv1VU1m1LQ@mail.gmail.com>
 <20150804153439.GA28673@lunn.ch>
 <CAG1O52W2Gy_6_DfewtUqoK_J+Y=KwVGyygNaPu2xyPM_ZkLfcQ@mail.gmail.com>
 <CAG1O52VQPpeGkA8bqYbPMTiT9Mua1yHi3H3osqJsHqm-RRKzow@mail.gmail.com>
 <20150805162155.GE32760@lunn.ch>
Message-ID: <CAG1O52WPFfm+XGk01iUVWLu=-Dm7bcDVmhv3P8iQDH+HHjsLUA@mail.gmail.com>

Hi Andrew,

My platform/board is ATCA carrier card which is getting interface to I/O card.
The I/O card is hot-pluggable  or Jack-in or Jack out.
Also I/O card consists of hot-plugable SFP interface.
These events are triggered using GPIO's

So the events the carrier card recieves are
1) If I/O card is either Jacked-in or Jacked-out ,respective GPIO
pin-x triggers an event
2) If SFP is pushed into I/O card the respective GPIO pin-y triggers an event.




Another observation about  "irq: Cannot allocate irq_descs @ IRQ47/79/111".
This is warning & irq_descs are already allocated , the overall
initialization/probe function doesn't get effected.
mvebu_gpio_irq_handler is only called if I register a another handler
at irq=82/83/84/85/87/88/89/90/92. I am registering this handler using
minimal kernel module.
My understanding of Linux IRQ/interrupt mechanism is limited to
request_irq, but registering domain & then IRQ is bit not clear.

Regards
Raghu




On Wed, Aug 5, 2015 at 9:51 PM, Andrew Lunn <andrew at lunn.ch> wrote:
> On Wed, Aug 05, 2015 at 08:31:27PM +0530, raghu MG wrote:
>> Hi Andrew,
>>
>> The issue I found was  irq_alloc_descs is called twice
>> 1st time inside   mvebu_gpio_probe & 2nd time inside irq_domain_add_simple.
>
> So i'm somewhat confused. I just tested on my Kirkwood and 370
> platforms, and an Armada XP WRT1900AC using 4.2.0-rc5, all which use
> the same gpio driver.
>
> They boot fine, the gpio driver is loaded, and the interrupt for the
> gpio connected to a button are listed in /proc/interrupts. The
> gpio-key driver is also able to use the gpio and the input-events
> program does show events when i press the button.
>
> So what is different with your platform?
>
>    Andrew


From vaibhav.hiremath at linaro.org  Wed Aug  5 23:03:56 2015
From: vaibhav.hiremath at linaro.org (Vaibhav Hiremath)
Date: Thu, 06 Aug 2015 11:33:56 +0530
Subject: [PATCH-v2 2/2] regulator: 88pm800: Add support for configuration
 of dual phase on BUCK1
In-Reply-To: <55C2A340.6020809@samsung.com>
References: <1437495782-15767-1-git-send-email-vaibhav.hiremath@linaro.org>
 <1437495782-15767-3-git-send-email-vaibhav.hiremath@linaro.org>
 <CAJKOXPcMd9VvfA48kaBa0BYeHAfHTu6MzAbQv0HuRy9wbgz0wg@mail.gmail.com>
 <55C1CD47.3060400@linaro.org> <55C2A340.6020809@samsung.com>
Message-ID: <55C2F8CC.1010308@linaro.org>



On Thursday 06 August 2015 05:28 AM, Krzysztof Kozlowski wrote:
> On 05.08.2015 17:45, Vaibhav Hiremath wrote:
>>
>>
>> On Thursday 23 July 2015 10:21 AM, Krzysztof Kozlowski wrote:
>>> 2015-07-22 1:23 GMT+09:00 Vaibhav Hiremath <vaibhav.hiremath at linaro.org>:
>>>> 88PM860 device supports dual phase mode on BUCK1 output.
>>>> In normal usecase, BUCK1A and BUCK1B operates independently with 3A
>>>> capacity. And they both can work as a dual phase providing 6A capacity.
>>>>
>>>> This patch updates the regulator driver to read the respective
>>>> DT property and enable dual-phase mode on BUCK1.
>>>>
>>>> Note that, this is init time (one time) initialization.
>>>>
>>
>> Sorry for delayed response, was on bed rest almost for week.
>>
>>>> Signed-off-by: Vaibhav Hiremath <vaibhav.hiremath at linaro.org>
>>>> ---
>>>>    drivers/regulator/88pm800.c | 31 +++++++++++++++++++++++++++++++
>>>>    include/linux/mfd/88pm80x.h |  3 +++
>>>>    2 files changed, 34 insertions(+)
>>>
>>> Don't you need to update the constraints also? I think the BUCK1
>>> regulator has fixed constraint of 3 A:
>>>     PM800_BUCK(buck1, BUCK1, BUCK_ENA, 0, 3000000, buck1_volt_range,
>>> 0x55),
>>> and now it can handle 6 A.
>>>
>>
>> Actually, BUCK1A and BUCK1B both combined together provide 6A capacity.
>> And as discussed earlier, we need board change for this.
>>
>> I am quite not sure.
>
> AFAIU the regulator driver creates one BUCK1 regulator with constraints
> 3 A. However after your change the regulator will handle up to 6 A.
>
> This means that constraints set by driver are wrong.
>
> Additionally I can't find BUCK1A and BUCK1B regulators. Driver provides
> only BUCK1.
>

My patch does add BUCK1A and BUCK1B, please refer to the PATCH[4/5] of
earlier series, which is accepted.

https://patchwork.kernel.org/patch/6810461/


>>
>> Should I read the property and update the constraint runtime during
>> probe?
>
> Driver should provide real constraints. Find the proper way to do this.
>
> The pm800_regulator_info[] array is not const so you can change it in
> whatever way you want (although it should be const for existing driver
> because regulator core accepts const and passing it to driver_data is
> not necessary).
>


Probably that is the only way to handle this.

how about,

As you mentioned, pm800_regulator_info[] is not constant, so I can 
update the constraint before regulator_register() and also do not
register BUCK1B, if dual phase is enabled.

So in summary,

if (dual phase is enabled)
{
	Update constraint of BUCK1 to 6A
	and do not register BUCK1B
} else {
	register both BUCK1A and BUCK1B with default constraint of 3A.
}

Thanks,
Vaibhav


From k.kozlowski at samsung.com  Wed Aug  5 23:06:21 2015
From: k.kozlowski at samsung.com (Krzysztof Kozlowski)
Date: Thu, 06 Aug 2015 15:06:21 +0900
Subject: [PATCH-v2 2/2] regulator: 88pm800: Add support for configuration
 of dual phase on BUCK1
In-Reply-To: <55C2F8CC.1010308@linaro.org>
References: <1437495782-15767-1-git-send-email-vaibhav.hiremath@linaro.org>
 <1437495782-15767-3-git-send-email-vaibhav.hiremath@linaro.org>
 <CAJKOXPcMd9VvfA48kaBa0BYeHAfHTu6MzAbQv0HuRy9wbgz0wg@mail.gmail.com>
 <55C1CD47.3060400@linaro.org> <55C2A340.6020809@samsung.com>
 <55C2F8CC.1010308@linaro.org>
Message-ID: <55C2F95D.3060608@samsung.com>

On 06.08.2015 15:03, Vaibhav Hiremath wrote:
> 
> 
> On Thursday 06 August 2015 05:28 AM, Krzysztof Kozlowski wrote:
>> On 05.08.2015 17:45, Vaibhav Hiremath wrote:
>>>
>>>
>>> On Thursday 23 July 2015 10:21 AM, Krzysztof Kozlowski wrote:
>>>> 2015-07-22 1:23 GMT+09:00 Vaibhav Hiremath
>>>> <vaibhav.hiremath at linaro.org>:
>>>>> 88PM860 device supports dual phase mode on BUCK1 output.
>>>>> In normal usecase, BUCK1A and BUCK1B operates independently with 3A
>>>>> capacity. And they both can work as a dual phase providing 6A
>>>>> capacity.
>>>>>
>>>>> This patch updates the regulator driver to read the respective
>>>>> DT property and enable dual-phase mode on BUCK1.
>>>>>
>>>>> Note that, this is init time (one time) initialization.
>>>>>
>>>
>>> Sorry for delayed response, was on bed rest almost for week.
>>>
>>>>> Signed-off-by: Vaibhav Hiremath <vaibhav.hiremath at linaro.org>
>>>>> ---
>>>>>    drivers/regulator/88pm800.c | 31 +++++++++++++++++++++++++++++++
>>>>>    include/linux/mfd/88pm80x.h |  3 +++
>>>>>    2 files changed, 34 insertions(+)
>>>>
>>>> Don't you need to update the constraints also? I think the BUCK1
>>>> regulator has fixed constraint of 3 A:
>>>>     PM800_BUCK(buck1, BUCK1, BUCK_ENA, 0, 3000000, buck1_volt_range,
>>>> 0x55),
>>>> and now it can handle 6 A.
>>>>
>>>
>>> Actually, BUCK1A and BUCK1B both combined together provide 6A capacity.
>>> And as discussed earlier, we need board change for this.
>>>
>>> I am quite not sure.
>>
>> AFAIU the regulator driver creates one BUCK1 regulator with constraints
>> 3 A. However after your change the regulator will handle up to 6 A.
>>
>> This means that constraints set by driver are wrong.
>>
>> Additionally I can't find BUCK1A and BUCK1B regulators. Driver provides
>> only BUCK1.
>>
> 
> My patch does add BUCK1A and BUCK1B, please refer to the PATCH[4/5] of
> earlier series, which is accepted.
> 
> https://patchwork.kernel.org/patch/6810461/

Indeed.

> 
> 
>>>
>>> Should I read the property and update the constraint runtime during
>>> probe?
>>
>> Driver should provide real constraints. Find the proper way to do this.
>>
>> The pm800_regulator_info[] array is not const so you can change it in
>> whatever way you want (although it should be const for existing driver
>> because regulator core accepts const and passing it to driver_data is
>> not necessary).
>>
> 
> 
> Probably that is the only way to handle this.
> 
> how about,
> 
> As you mentioned, pm800_regulator_info[] is not constant, so I can
> update the constraint before regulator_register() and also do not
> register BUCK1B, if dual phase is enabled.
> 
> So in summary,
> 
> if (dual phase is enabled)
> {
>     Update constraint of BUCK1 to 6A
>     and do not register BUCK1B
> } else {
>     register both BUCK1A and BUCK1B with default constraint of 3A.
> }

This idea looks good to me.

Best regards,
Krzysztof



From s.hauer at pengutronix.de  Wed Aug  5 23:19:18 2015
From: s.hauer at pengutronix.de (Sascha Hauer)
Date: Thu, 6 Aug 2015 08:19:18 +0200
Subject: [PATCH v3 5/8] ARM: mediatek: add smp bringup code for MT6580
In-Reply-To: <1801910.hz53dYUgta@ubix>
References: <1438696464-59858-1-git-send-email-scott.shu@mediatek.com>
 <1438696464-59858-6-git-send-email-scott.shu@mediatek.com>
 <1801910.hz53dYUgta@ubix>
Message-ID: <20150806061918.GK18700@pengutronix.de>

On Wed, Aug 05, 2015 at 06:47:03PM +0200, Matthias Brugger wrote:
> On Tuesday, August 04, 2015 09:54:21 PM Scott Shu wrote:
> > Add support for cpu enable-method "mediatek,mt6580-smp" for booting
> > secondary CPUs on MT6580.
> > 
> > Signed-off-by: Scott Shu <scott.shu at mediatek.com>
> > ---
> >  arch/arm/mach-mediatek/platsmp.c |  137
> > ++++++++++++++++++++++++++++++++++++++ 1 file changed, 137 insertions(+)
> > +
> > +static void __init mt6580_smp_prepare_cpus(unsigned int max_cpus)
> > +{
> > +	static void __iomem *infracfg_ao_base;
> > +
> > +	infracfg_ao_base = ioremap(MT6580_INFRACFG_AO, 0x1000);
> > +	if (!infracfg_ao_base) {
> > +		pr_err("%s: Unable to map I/O memory\n", __func__);
> > +		return;
> > +	}
> > +
> > +	/* Enable bootrom power down mode */
> > +	writel_relaxed(readl(infracfg_ao_base + 0x804) | SW_ROM_PD,
> > +		       infracfg_ao_base + 0x804);
> 
> Please use a define for the offset.
> I prefer to not cascade reads and writes but to use a temporary variable. But 
> if this is fine with the kernel coding style (I doubt, but I'm not sure) then 
> this is fine.

For what it's worth I also prefer

	val = readl(infracfg_ao_base + 0x804);
	val |= SW_ROM_PD:
	writel_relaxed(val, infracfg_ao_base + 0x804);

I find this better readable. I don't think though that there's common
agreement that this style is better.

Sascha

-- 
Pengutronix e.K.                           |                             |
Industrial Linux Solutions                 | http://www.pengutronix.de/  |
Peiner Str. 6-8, 31137 Hildesheim, Germany | Phone: +49-5121-206917-0    |
Amtsgericht Hildesheim, HRA 2686           | Fax:   +49-5121-206917-5555 |


From b20788 at freescale.com  Thu Aug  6 07:13:56 2015
From: b20788 at freescale.com (Anson Huang)
Date: Thu, 6 Aug 2015 22:13:56 +0800
Subject: [PATCH] clk: imx: increase AXI clock rate to 264MHz for i.MX6UL
Message-ID: <1438870436-16061-1-git-send-email-b20788@freescale.com>

On i.MX6UL, AXI clock rate's design target is 264MHz, but by default
it is only set to 198MHz which is NOT good enough for performance,
this patch increases AXI clock rate from 198MHz to 264MHz to meet
the design target, this is done by switching its parent clock
"periph" from 396MHz PFD to 528MHz PLL.

Signed-off-by: Anson Huang <b20788 at freescale.com>
---
 drivers/clk/imx/clk-imx6ul.c | 18 ++++++++++++++++++
 1 file changed, 18 insertions(+)

diff --git a/drivers/clk/imx/clk-imx6ul.c b/drivers/clk/imx/clk-imx6ul.c
index aaa3665..01718d0 100644
--- a/drivers/clk/imx/clk-imx6ul.c
+++ b/drivers/clk/imx/clk-imx6ul.c
@@ -407,6 +407,24 @@ static void __init imx6ul_clocks_init(struct device_node *ccm_node)
 	clk_data.clk_num = ARRAY_SIZE(clks);
 	of_clk_add_provider(np, of_clk_src_onecell_get, &clk_data);
 
+	/*
+	 * Lower the AHB clock rate before changing the parent clock source,
+	 * as AHB clock rate can NOT be higher than 133MHz, but its parent
+	 * will be switched from 396MHz PFD to 528MHz PLL in order to increase
+	 * AXI clock rate, so we need to lower AHB rate first to make sure at
+	 * any time, AHB rate is <= 133MHz.
+	 */
+	clk_set_rate(clks[IMX6UL_CLK_AHB], 99000000);
+
+	/* Change periph_pre clock to pll2_bus to adjust AXI rate to 264MHz */
+	clk_set_parent(clks[IMX6UL_CLK_PERIPH_CLK2_SEL], clks[IMX6UL_CLK_PLL3_USB_OTG]);
+	clk_set_parent(clks[IMX6UL_CLK_PERIPH], clks[IMX6UL_CLK_PERIPH_CLK2]);
+	clk_set_parent(clks[IMX6UL_CLK_PERIPH_PRE], clks[IMX6UL_CLK_PLL2_BUS]);
+	clk_set_parent(clks[IMX6UL_CLK_PERIPH], clks[IMX6UL_CLK_PERIPH_PRE]);
+
+	/* Make sure AHB rate is 132MHz  */
+	clk_set_rate(clks[IMX6UL_CLK_AHB], 132000000);
+
 	/* set perclk to from OSC */
 	clk_set_parent(clks[IMX6UL_CLK_PERCLK_SEL], clks[IMX6UL_CLK_OSC]);
 
-- 
1.9.1



From tony at atomide.com  Wed Aug  5 23:29:23 2015
From: tony at atomide.com (Tony Lindgren)
Date: Wed, 5 Aug 2015 23:29:23 -0700
Subject: [PATCH v2 1/3] mailbox/omap: Add ti, mbox-send-noirq quirk to fix
 AM33xx CPU Idle
In-Reply-To: <55C22C8E.3000506@ti.com>
References: <1437166592-25378-1-git-send-email-d-gerlach@ti.com>
 <1437166592-25378-2-git-send-email-d-gerlach@ti.com>
 <20150805102840.GA16878@atomide.com> <55C22C8E.3000506@ti.com>
Message-ID: <20150806062923.GN16878@atomide.com>

* Suman Anna <s-anna at ti.com> [150805 08:35]:
> Hi Tony,
> 
> On 08/05/2015 05:28 AM, Tony Lindgren wrote:
> > * Dave Gerlach <d-gerlach at ti.com> [150717 13:59]:
> >> --- a/Documentation/devicetree/bindings/mailbox/omap-mailbox.txt
> >> +++ b/Documentation/devicetree/bindings/mailbox/omap-mailbox.txt
> >> @@ -75,6 +75,14 @@ data that represent the following:
> >>      Cell #3 (usr_id)  - mailbox user id for identifying the interrupt line
> >>                          associated with generating a tx/rx fifo interrupt.
> >>  
> >> +Optional Properties:
> >> +--------------------
> >> +- ti,mbox-send-noirq:   Quirk flag to allow the client user of this sub-mailbox
> >> +                        to send messages without triggering a Tx ready interrupt,
> >> +                        and to control the Tx ticker. Should be used only on
> >> +                        sub-mailboxes used to communicate with WkupM3 remote
> >> +                        processor on AM33xx/AM43xx SoCs.
> >> +
> > 
> > Hmm can't you do this just by setting a flag in the device driver
> > based on the compatible string?
> 
> We can't because there can be other users like PRUSS which will use a
> sub-mailbox in a regular fashion. The compatible serves the IP and there
> can be multiple sub-mailboxes underneath it, and this quirk is needed
> only on the one that's used by the WkupM3.

OK

> Do you have any comments on this?

Up to you guys then to figure out what property is used for it then.

Regards,

Tony


From tony at atomide.com  Wed Aug  5 23:48:21 2015
From: tony at atomide.com (Tony Lindgren)
Date: Wed, 5 Aug 2015 23:48:21 -0700
Subject: [PATCH 00/11] omap_hsmmc: voltage switching and tuning
In-Reply-To: <55C22524.5050304@ti.com>
References: <1438242394-25599-1-git-send-email-kishon@ti.com>
 <20150805104355.GE16878@atomide.com> <55C22524.5050304@ti.com>
Message-ID: <20150806064821.GO16878@atomide.com>

* Kishon Vijay Abraham I <kishon at ti.com> [150805 08:03]:
> Hi,
> 
> On Wednesday 05 August 2015 04:13 PM, Tony Lindgren wrote:
> > * Kishon Vijay Abraham I <kishon at ti.com> [150730 00:49]:
> >> Patch series implements voltage switching and tuning for omap_hsmmc
> >> driver.
> >>
> >> Did basic read/write test in J6, J6 Eco, Beagle-x15, AM437x EVM,
> >> Beaglebone black, OMAP5 uEVM and OMAP4 PANDA.
> > 
> > Your tests are missing omap3?
> 
> I don't have one at my disposal :-( I'll try to find one and add omap3 tests.

Great :) Beagle xm is a good one to test the USB PHY stuff on
and also MMC. Having USB cable connected or EHCI loaded blocks the PM
though, so NFSroot is not very usable for testing on it.

If you want to test PM over NFSroot, boards with the smsc911x known
to work with PM  are at least omap3-evm-37xx.dts and
logicpd-torpedo-37xx-devkit.dts.  Since you tinker with the USB PHYs,
torpedo has MUSB working the same way as the beagle boards, EVM I
think can be modified that way but by default has diffent PHY.

Also overo tobi boards work with PM but only for retntion idle and
not off idle, and map3-sbc-t3517.dts probably can be made to work
with PM but I have mine as a gateway and have not been able to test
with it.

Probably also zoom3 boards with later processor boards can be made
to work, the LDP has early omap34xx variants and can't be made to
work reliably.

I don't have omap3-lilly, but I'd assume that can also be made
to work with PM if not already working.

> > I suggest you add some omap3 tests in general as otherwise you are
> > only testing a subset of the driver features and completely missing
> > things like rutnime PM and save and restore for the deeper idle
> > states.
> 
> yeah, I'll do those tests and re-post the series.

Thanks!

Tony


From k.kozlowski at samsung.com  Thu Aug  6 00:08:04 2015
From: k.kozlowski at samsung.com (Krzysztof Kozlowski)
Date: Thu, 06 Aug 2015 16:08:04 +0900
Subject: [RFC PATCH v4 1/9] mmc: dw_mmc: Add external dma interface support
In-Reply-To: <1438843491-23853-1-git-send-email-shawn.lin@rock-chips.com>
References: <1438843469-23807-1-git-send-email-shawn.lin@rock-chips.com>
 <1438843491-23853-1-git-send-email-shawn.lin@rock-chips.com>
Message-ID: <55C307D4.1020209@samsung.com>

On 06.08.2015 15:44, Shawn Lin wrote:
> DesignWare MMC Controller can supports two types of DMA
> mode: external dma and internal dma. We get a RK312x platform
> integrated dw_mmc and ARM pl330 dma controller. This patch add
> edmac ops to support these platforms. I've tested it on RK312x
> platform with edmac mode and RK3288 platform with idmac mode.
> 
> Signed-off-by: Shawn Lin <shawn.lin at rock-chips.com>
> 
> ---
> 
> Changes in v4:
> - remove "host->trans_mode" and use "host->use_dma" to indicate
>   transfer mode.
> - remove all bt-bindings' changes since we don't need new properities.
> - check transfer mode at runtime by reading HCON reg
> - spilt defconfig changes for each sub-architecture
> - fix the title of cover letter

How did you fixed the title? It is still empty :)
	Subject: [RFC PATCH v4 0/9]

> - reuse some code for reducing code size
> 
> Changes in v3:
> - choose transfer mode at runtime
> - remove all CONFIG_MMC_DW_IDMAC config option
> - add supports-idmac property for some platforms
> 
> Changes in v2:
> - Fix typo of dev_info msg
> - remove unused dmach from declaration of dw_mci_dma_slave
> 
>  drivers/mmc/host/Kconfig        |  11 +-
>  drivers/mmc/host/dw_mmc-pltfm.c |   2 +
>  drivers/mmc/host/dw_mmc.c       | 258 ++++++++++++++++++++++++++++++++--------
>  include/linux/mmc/dw_mmc.h      |  27 ++++-
>  4 files changed, 232 insertions(+), 66 deletions(-)
> 
> diff --git a/drivers/mmc/host/Kconfig b/drivers/mmc/host/Kconfig
> index 6a0f9c7..a86c0eb 100644
> --- a/drivers/mmc/host/Kconfig
> +++ b/drivers/mmc/host/Kconfig
> @@ -607,15 +607,7 @@ config MMC_DW
>  	help
>  	  This selects support for the Synopsys DesignWare Mobile Storage IP
>  	  block, this provides host support for SD and MMC interfaces, in both
> -	  PIO and external DMA modes.
> -
> -config MMC_DW_IDMAC
> -	bool "Internal DMAC interface"
> -	depends on MMC_DW
> -	help
> -	  This selects support for the internal DMAC block within the Synopsys
> -	  Designware Mobile Storage IP block. This disables the external DMA
> -	  interface.
> +	  PIO, internal DMA mode and external DMA modes.
>  
>  config MMC_DW_PLTFM
>  	tristate "Synopsys Designware MCI Support as platform device"
> @@ -644,7 +636,6 @@ config MMC_DW_K3
>  	tristate "K3 specific extensions for Synopsys DW Memory Card Interface"
>  	depends on MMC_DW
>  	select MMC_DW_PLTFM
> -	select MMC_DW_IDMAC
>  	help
>  	  This selects support for Hisilicon K3 SoC specific extensions to the
>  	  Synopsys DesignWare Memory Card Interface driver. Select this option
> diff --git a/drivers/mmc/host/dw_mmc-pltfm.c b/drivers/mmc/host/dw_mmc-pltfm.c
> index ec6dbcd..7e1d13b 100644
> --- a/drivers/mmc/host/dw_mmc-pltfm.c
> +++ b/drivers/mmc/host/dw_mmc-pltfm.c
> @@ -59,6 +59,8 @@ int dw_mci_pltfm_register(struct platform_device *pdev,
>  	host->pdata = pdev->dev.platform_data;
>  
>  	regs = platform_get_resource(pdev, IORESOURCE_MEM, 0);
> +	/* Get registers' physical base address */
> +	host->phy_regs = (void *)(regs->start);
>  	host->regs = devm_ioremap_resource(&pdev->dev, regs);
>  	if (IS_ERR(host->regs))
>  		return PTR_ERR(host->regs);
> diff --git a/drivers/mmc/host/dw_mmc.c b/drivers/mmc/host/dw_mmc.c
> index 40e9d8e..5d6cdff 100644
> --- a/drivers/mmc/host/dw_mmc.c
> +++ b/drivers/mmc/host/dw_mmc.c
> @@ -56,7 +56,7 @@
>  #define DW_MCI_FREQ_MAX	200000000	/* unit: HZ */
>  #define DW_MCI_FREQ_MIN	400000		/* unit: HZ */
>  
> -#ifdef CONFIG_MMC_DW_IDMAC
> +
>  #define IDMAC_INT_CLR		(SDMMC_IDMAC_INT_AI | SDMMC_IDMAC_INT_NI | \
>  				 SDMMC_IDMAC_INT_CES | SDMMC_IDMAC_INT_DU | \
>  				 SDMMC_IDMAC_INT_FBE | SDMMC_IDMAC_INT_RI | \
> @@ -99,7 +99,6 @@ struct idmac_desc {
>  
>  	__le32		des3;	/* buffer 2 physical address */
>  };
> -#endif /* CONFIG_MMC_DW_IDMAC */
>  
>  static bool dw_mci_reset(struct dw_mci *host);
>  static bool dw_mci_ctrl_reset(struct dw_mci *host, u32 reset);
> @@ -403,7 +402,6 @@ static int dw_mci_get_dma_dir(struct mmc_data *data)
>  		return DMA_FROM_DEVICE;
>  }
>  
> -#ifdef CONFIG_MMC_DW_IDMAC
>  static void dw_mci_dma_cleanup(struct dw_mci *host)
>  {
>  	struct mmc_data *data = host->data;
> @@ -441,12 +439,21 @@ static void dw_mci_idmac_stop_dma(struct dw_mci *host)
>  	mci_writel(host, BMOD, temp);
>  }
>  
> -static void dw_mci_idmac_complete_dma(struct dw_mci *host)
> +static void dw_mci_dmac_complete_dma(void *arg)
>  {
> +	struct dw_mci *host = arg;

Why changing the argument to void*?

Best regards,
Krzysztof

>  	struct mmc_data *data = host->data;
>  
>  	dev_vdbg(host->dev, "DMA complete\n");
>  
> +	if (host->use_dma == TRANS_MODE_EDMAC)
> +		if (data && (data->flags & MMC_DATA_READ))
> +			/* Invalidate cache after read */
> +			dma_sync_sg_for_cpu(mmc_dev(host->cur_slot->mmc),
> +					    data->sg,
> +					    data->sg_len,
> +					    DMA_FROM_DEVICE);
> +
>  	host->dma_ops->cleanup(host);




From jh80.chung at samsung.com  Thu Aug  6 00:08:02 2015
From: jh80.chung at samsung.com (Jaehoon Chung)
Date: Thu, 06 Aug 2015 16:08:02 +0900
Subject: [RFC PATCH v4 0/9]
In-Reply-To: <1438843469-23807-1-git-send-email-shawn.lin@rock-chips.com>
References: <1438843469-23807-1-git-send-email-shawn.lin@rock-chips.com>
Message-ID: <55C307D2.7020501@samsung.com>

Hi, Shawn.

I remembered that Krzysztof has mentioned "Fix the title of cover letter."
Your cover letter's title is nothing.. "[RFC PATCH v4 0/9] " ??
[RFC PATCH v4 0/9] your title...

Best Regards,
Jaehoon Chung

On 08/06/2015 03:44 PM, Shawn Lin wrote:
> Add external dma support for Synopsys MSHC
> 
> Synopsys DesignWare mobile storage host controller supports three
> types of transfer mode: pio, internal dma and external dma. However,
> dw_mmc can only supports pio and internal dma now. Thus some platforms
> using dw-mshc integrated with generic dma can't work in dma mode. So we
> submit this patch to achieve it.
> 
> And the config option, CONFIG_MMC_DW_IDMAC, was added by Will Newton
> (commit:f95f3850) for the first version of dw_mmc and never be touched since
> then. At that time dt-bindings hadn't been introduced into dw_mmc yet means
> we should select CONFIG_MMC_DW_IDMAC to enable internal dma mode at compile
> time. Nowadays, device-tree helps us to support a variety of boards with one
> kernel. That's why we need to remove it and decide the transfer mode by reading
> dw_mmc's HCON reg at runtime.
> 
> This RFC patch needs lots of ACKs. I know it's hard, but it does need someone
> to make the running.
> 
> Patch does the following things:
> - remove CONFIG_MMC_DW_IDMAC config option
> - add bindings for edmac used by synopsys-dw-mshc
>   at runtime
> - add edmac support for synopsys-dw-mshc
> 
> Patch is based on next of git://git.linaro.org/people/ulf.hansson/mmc
> 
> 
> Changes in v4:
> - remove "host->trans_mode" and use "host->use_dma" to indicate
>   transfer mode.
> - remove all bt-bindings' changes since we don't need new properities.
> - check transfer mode at runtime by reading HCON reg
> - spilt defconfig changes for each sub-architecture
> - fix the title of cover letter
> - reuse some code for reducing code size
> 
> Changes in v3:
> - choose transfer mode at runtime
> - remove all CONFIG_MMC_DW_IDMAC config option
> - add supports-idmac property for some platforms
> 
> Changes in v2:
> - Fix typo of dev_info msg
> - remove unused dmach from declaration of dw_mci_dma_slave
> 
> Shawn Lin (9):
>   mmc: dw_mmc: Add external dma interface support
>   Documentation: synopsys-dw-mshc: add bindings for idmac and edmac
>   mips: pistachio_defconfig: remove CONFIG_MMC_DW_IDMAC
>   arc: axs10x_defconfig: remove CONFIG_MMC_DW_IDMAC
>   arm: exynos_defconfig: remove CONFIG_MMC_DW_IDMAC
>   arm: hisi_defconfig: remove CONFIG_MMC_DW_IDMAC
>   arm: lpc18xx_defconfig: remove CONFIG_MMC_DW_IDMAC
>   arm: multi_v7_defconfig: remove CONFIG_MMC_DW_IDMAC
>   arm: zx_defconfig: remove CONFIG_MMC_DW_IDMAC
> 
>  .../devicetree/bindings/mmc/synopsys-dw-mshc.txt   |  25 ++
>  arch/arc/configs/axs101_defconfig                  |   1 -
>  arch/arc/configs/axs103_defconfig                  |   1 -
>  arch/arc/configs/axs103_smp_defconfig              |   1 -
>  arch/arm/configs/exynos_defconfig                  |   1 -
>  arch/arm/configs/hisi_defconfig                    |   1 -
>  arch/arm/configs/lpc18xx_defconfig                 |   1 -
>  arch/arm/configs/multi_v7_defconfig                |   1 -
>  arch/arm/configs/zx_defconfig                      |   1 -
>  arch/mips/configs/pistachio_defconfig              |   1 -
>  drivers/mmc/host/Kconfig                           |  11 +-
>  drivers/mmc/host/dw_mmc-pltfm.c                    |   2 +
>  drivers/mmc/host/dw_mmc.c                          | 258 +++++++++++++++++----
>  include/linux/mmc/dw_mmc.h                         |  27 ++-
>  14 files changed, 257 insertions(+), 75 deletions(-)
> 



From k.kozlowski at samsung.com  Thu Aug  6 00:08:56 2015
From: k.kozlowski at samsung.com (Krzysztof Kozlowski)
Date: Thu, 06 Aug 2015 16:08:56 +0900
Subject: [RFC PATCH v4 5/9] arm: exynos_defconfig: remove
 CONFIG_MMC_DW_IDMAC
In-Reply-To: <1438843539-24017-1-git-send-email-shawn.lin@rock-chips.com>
References: <1438843469-23807-1-git-send-email-shawn.lin@rock-chips.com>
 <1438843539-24017-1-git-send-email-shawn.lin@rock-chips.com>
Message-ID: <55C30808.1020704@samsung.com>

On 06.08.2015 15:45, Shawn Lin wrote:
> DesignWare MMC Controller's transfer mode should be decided
> at runtime instead of compile-time. So we remove this config
> option and read dw_mmc's register to select DMA master.
> 
> Signed-off-by: Shawn Lin <shawn.lin at rock-chips.com>
> ---
> 
> Changes in v4: None
> Changes in v3: None
> Changes in v2: None
> 
>  arch/arm/configs/exynos_defconfig | 1 -
>  1 file changed, 1 deletion(-)

Acked-by: Krzysztof Kozlowski <k.kozlowski at samsung.com>

Best regards,
Krzysztof



From takahiro.akashi at linaro.org  Thu Aug  6 00:09:49 2015
From: takahiro.akashi at linaro.org (AKASHI Takahiro)
Date: Thu, 06 Aug 2015 16:09:49 +0900
Subject: [v2 2/5] arm64: kdump: implement machine_crash_shutdown()
In-Reply-To: <553A1E62.9030400@arm.com>
References: <1429861989-8417-1-git-send-email-takahiro.akashi@linaro.org>
 <1429861989-8417-3-git-send-email-takahiro.akashi@linaro.org>
 <20150424103900.GF29183@leverpostej> <553A1E62.9030400@arm.com>
Message-ID: <55C3083D.1000306@linaro.org>

Marc, Mark

Sorry for not revisiting your comment below for a while.

On 04/24/2015 07:43 PM, Marc Zyngier wrote:
> On 24/04/15 11:39, Mark Rutland wrote:
>> On Fri, Apr 24, 2015 at 08:53:05AM +0100, AKASHI Takahiro wrote:
>>> kdump calls machine_crash_shutdown() to shut down non-boot cpus and
>>> save per-cpu general-purpose registers before restarting the crash dump
>>> kernel. See kernel_kexec().
>>> ipi_cpu_stop() is used and a bit modified to support this behavior.
>>>
>>> Signed-off-by: AKASHI Takahiro <takahiro.akashi at linaro.org>
>>> ---
>>>   arch/arm64/include/asm/kexec.h    |   34 ++++++++++++++++++++++-
>>>   arch/arm64/kernel/machine_kexec.c |   55 ++++++++++++++++++++++++++++++++++++-
>>>   arch/arm64/kernel/smp.c           |   12 ++++++--
>>>   3 files changed, 97 insertions(+), 4 deletions(-)
>>>
>>> diff --git a/arch/arm64/include/asm/kexec.h b/arch/arm64/include/asm/kexec.h
>>> index 3530ff5..eaf3fcb 100644
>>> --- a/arch/arm64/include/asm/kexec.h
>>> +++ b/arch/arm64/include/asm/kexec.h
>>> @@ -30,6 +30,8 @@
>>>
>>>   #if !defined(__ASSEMBLY__)
>>>
>>> +extern bool in_crash_kexec;
>>> +
>>>   /**
>>>    * crash_setup_regs() - save registers for the panic kernel
>>>    *
>>> @@ -40,7 +42,37 @@
>>>   static inline void crash_setup_regs(struct pt_regs *newregs,
>>>   				    struct pt_regs *oldregs)
>>>   {
>>> -	/* Empty routine needed to avoid build errors. */
>>> +	if (oldregs) {
>>> +		memcpy(newregs, oldregs, sizeof(*newregs));
>>> +	} else {
>>> +		__asm__ __volatile__ (
>>> +			"stp	 x0,   x1, [%3]\n\t"
>>
>> Why the tabs?
>>
>> Please use #16 * N as the offset for consistency with entry.S, with 0
>> for the first N.
>>
>> [...]
>>
>>> +static void machine_kexec_mask_interrupts(void)
>>> +{
>>> +	unsigned int i;
>>> +	struct irq_desc *desc;
>>> +
>>> +	for_each_irq_desc(i, desc) {
>>> +		struct irq_chip *chip;
>>> +
>>> +		chip = irq_desc_get_chip(desc);
>>> +		if (!chip)
>>> +			continue;
>>> +
>>> +		if (chip->irq_eoi && irqd_irq_inprogress(&desc->irq_data))
>>> +			chip->irq_eoi(&desc->irq_data);
>>> +
>>> +		if (chip->irq_mask)
>>> +			chip->irq_mask(&desc->irq_data);
>>> +
>>> +		if (chip->irq_disable && !irqd_irq_disabled(&desc->irq_data))
>>> +			chip->irq_disable(&desc->irq_data);
>>> +	}
>>> +}
>>
>> I'm surprised that this isn't left to the irqchip driver init code in
>> the crash kernel. For all we know this state could be corrupt anyway.
>
> Indeed, parsing the irqdesc list is a recipe for disaster. Who knows
> which locks have been taken or simply corrupted, pointers nuked...
>
>> Is there any reason we can't get the GIC driver to nuke all of this at
>> probe time?

Is it just enough to remove kexec_mask_interrupts() and add gic_eoi_irq()
at the beginning of gic_cpu_init() in irq-gic.c and irq-gic-v3.c?

> This feels like the better option. I can cook a patch or two for that.

If you do, that will be much better :)

BTW, in arm-gic-v3.h, GICD_CTRL_ARE_NS is defined as
     (1U << 4)
but should it be 5?
(I'm referring to the page 8-415 in IHI0069A.)

Thanks,
-Takahiro AKASHI

> Thanks,
>
> 	M.
>


From geert at linux-m68k.org  Thu Aug  6 00:17:38 2015
From: geert at linux-m68k.org (Geert Uytterhoeven)
Date: Thu, 6 Aug 2015 09:17:38 +0200
Subject: [PATCH v4 0/6] ARM: shmobile: r8a7740/sh73a0 DT Cache Handling
In-Reply-To: <20150806003511.GB17231@verge.net.au>
References: <1438765090-823-1-git-send-email-geert+renesas@glider.be>
 <20150806003511.GB17231@verge.net.au>
Message-ID: <CAMuHMdW5D2LGA=3+JDiAUhVtPmxk3ZJhAx3=JXFuAHBAgU_NTw@mail.gmail.com>

On Thu, Aug 6, 2015 at 2:35 AM, Simon Horman <horms at verge.net.au> wrote:
> On Wed, Aug 05, 2015 at 10:58:04AM +0200, Geert Uytterhoeven wrote:
>> This patch series add L1 and L2 cache descriptions to DT for r8a7740 and
>> sh73a0, and migrates the shmobile DT-based generic r8a7740 and
>> armadillo legacy platforms from calling l2x0_of_init() to the generic
>> l2c OF initialization.

>> Dependencies:
>>   - This series applies to renesas-devel-20150805-v4.2-rc5,
>>   - Patch 2 depends on patch 1,
>>   - Patch 4 depends on patch 2,

Sorry, "... on patch 3".

>>   - Patch 5 depends on patch 1 and on "ARM: 8395/1: l2c: Add support for
>>     the "arm,shared-override" property" in arm/for-next,
>>   - Patch 6 depends on patch 5.
>>
>> Given C code patches depending on DT patches in the same branch are
>> frowned upon, I think it would be best if patch 1 (and patch 3, if
>> anyone thinks we may fix the secondary CPU bringup issue during the next
>> 3 months) are queued for v4.3. The other patches can be queued for
>> 2016^H^H^H^Hv4.4.
>
> Sorry for surprising you with that merge-order requirement.

In theory it sounds fine, as DT and code are independent.
Moving functionality from C to DT is something different...

> Unfortunately I am not comfortable with taking patch 1 for v4.3 because:
> 1. Its now very late in the cycle

I understand.

> 2. There now seems to be some discussion around it.

Yeah, that's what v4s are for...

Let's wait and see if/when it settles...

> I think I am happy to take the other patches for v4.4, now. But perhaps
> I should wait for the discussion around patch 1 to conclude first?

Which other patches? Patch 3 has the same issue as patch 1. And all
the rest depends on patch 1 or patch 3... So there's nothing left to
apply yet...

Gr{oetje,eeting}s,

                        Geert

--
Geert Uytterhoeven -- There's lots of Linux beyond ia32 -- geert at linux-m68k.org

In personal conversations with technical people, I call myself a hacker. But
when I'm talking to journalists I just say "programmer" or something like that.
                                -- Linus Torvalds


From geert at linux-m68k.org  Thu Aug  6 00:21:34 2015
From: geert at linux-m68k.org (Geert Uytterhoeven)
Date: Thu, 6 Aug 2015 09:21:34 +0200
Subject: [PATCH v2 0/2] Add R8A7794 GPIO DT support
In-Reply-To: <20150806004714.GD17231@verge.net.au>
References: <6388101.Drn6rL87rl@wasted.cogentembedded.com>
 <20150806004714.GD17231@verge.net.au>
Message-ID: <CAMuHMdV5F2JL6_OhPY3y7WZn_pfG_ufRUe9NA+2C-CGLtVxVaw@mail.gmail.com>

On Thu, Aug 6, 2015 at 2:47 AM, Simon Horman <horms at verge.net.au> wrote:
> On Tue, Aug 04, 2015 at 12:36:27AM +0300, Sergei Shtylyov wrote:
>>    Here's the set of 2 patches against Simon Horman's 'renesas.git' repo,
>> 'renesas-devel-20150803-v4.2-rc5' tag. Here we add the GPIO device tree support
>> for the R8A7794 SoC.
>>
>> [1/2] ARM: shmobile: r8a7794: add GPIO clocks
>> [2/2] ARM: shmobile: r8a7794: add GPIO DT support
>
> Thanks, I have queued these up for v4.4.

Woops, Since CPG/MSTP support is in, GPIO won't work, as the nodes
lack "power-domains" properties.

Gr{oetje,eeting}s,

                        Geert

--
Geert Uytterhoeven -- There's lots of Linux beyond ia32 -- geert at linux-m68k.org

In personal conversations with technical people, I call myself a hacker. But
when I'm talking to journalists I just say "programmer" or something like that.
                                -- Linus Torvalds


From eddie.huang at mediatek.com  Thu Aug  6 00:22:09 2015
From: eddie.huang at mediatek.com (Eddie Huang)
Date: Thu, 6 Aug 2015 15:22:09 +0800
Subject: [PATCH v2 0/2] Mediatek I2C fixup 
Message-ID: <1438845731-17805-1-git-send-email-eddie.huang@mediatek.com>

This series provide two patches to optimize mediatek i2c driver.
The first patch will reset dma hardware in init function to make sure
hardware work in good state. The second patch fix i2c interrupt handling
for ACK error. All these patches base on 4.2-rc1.

Change in v2:
Fix multi-transfer fail bug - in mtk_i2c_irq(), call complete()
if get I2C_RS_TRANSFER interrupt

Eddie Huang (2):
  i2c: mediatek: Reset DMA engine in hardware init function
  i2c: mediatek: Fixup i2c ack error interrupt handling

 drivers/i2c/busses/i2c-mt65xx.c |   21 +++++++++++++++++----
 1 file changed, 17 insertions(+), 4 deletions(-)

-- 
1.7.9.5



From geert at linux-m68k.org  Thu Aug  6 00:22:45 2015
From: geert at linux-m68k.org (Geert Uytterhoeven)
Date: Thu, 6 Aug 2015 09:22:45 +0200
Subject: [PATCH v2 2/2] ARM: shmobile: r8a7794: add GPIO DT support
In-Reply-To: <2762710.QvQ3jKvG4A@wasted.cogentembedded.com>
References: <6388101.Drn6rL87rl@wasted.cogentembedded.com>
 <2762710.QvQ3jKvG4A@wasted.cogentembedded.com>
Message-ID: <CAMuHMdUuHtmZfd7vei0qdP9n_gvd6C1xBbDWkkSdPRTrTPxiOg@mail.gmail.com>

Hi Sergei,

On Mon, Aug 3, 2015 at 11:39 PM, Sergei Shtylyov
<sergei.shtylyov at cogentembedded.com> wrote:
> Describe GPIO[0-6] controllers in the R8A7794 device tree.
>
> Based on original patch by Hisashi Nakamura <hisashi.nakamura.ak at renesas.com>.
>
> Signed-off-by: Sergei Shtylyov <sergei.shtylyov at cogentembedded.com>
> Acked-by: Geert Uytterhoeven <geert+renesas at glider.be>

As CPG/MSTP Clock Domain support is in, I have to withdraw my Acked-by.

> Index: renesas/arch/arm/boot/dts/r8a7794.dtsi
> ===================================================================
> --- renesas.orig/arch/arm/boot/dts/r8a7794.dtsi
> +++ renesas/arch/arm/boot/dts/r8a7794.dtsi
> @@ -50,6 +50,90 @@
>                 interrupts = <1 9 (GIC_CPU_MASK_SIMPLE(2) | IRQ_TYPE_LEVEL_HIGH)>;
>         };
>
> +       gpio0: gpio at e6050000 {
> +               compatible = "renesas,gpio-r8a7794", "renesas,gpio-rcar";
> +               reg = <0 0xe6050000 0 0x50>;
> +               interrupts = <0 4 IRQ_TYPE_LEVEL_HIGH>;
> +               #gpio-cells = <2>;
> +               gpio-controller;
> +               gpio-ranges = <&pfc 0 0 32>;
> +               #interrupt-cells = <2>;
> +               interrupt-controller;
> +               clocks = <&mstp9_clks R8A7794_CLK_GPIO0>;

Missing "power-domains = <&cpg_clocks>;"

> +       };

Same comment for the other gpio device nodes.

Gr{oetje,eeting}s,

                        Geert

--
Geert Uytterhoeven -- There's lots of Linux beyond ia32 -- geert at linux-m68k.org

In personal conversations with technical people, I call myself a hacker. But
when I'm talking to journalists I just say "programmer" or something like that.
                                -- Linus Torvalds


From eddie.huang at mediatek.com  Thu Aug  6 00:22:11 2015
From: eddie.huang at mediatek.com (Eddie Huang)
Date: Thu, 6 Aug 2015 15:22:11 +0800
Subject: [PATCH v2 2/2] i2c: mediatek: Fixup i2c ack error interrupt handling
In-Reply-To: <1438845731-17805-1-git-send-email-eddie.huang@mediatek.com>
References: <1438845731-17805-1-git-send-email-eddie.huang@mediatek.com>
Message-ID: <1438845731-17805-3-git-send-email-eddie.huang@mediatek.com>

When occur i2c ack error, i2c controller generate two interrupts,
first is the ack error interrupt, then the complete interrupt.
i2c interrupt handler should keep the two interrupt value, and only
call complete() for the complete interrupt.

Signed-off-by: Liguo Zhang <liguo.zhang at mediatek.com>
Signed-off-by: Eddie Huang <eddie.huang at mediatek.com>
---
 drivers/i2c/busses/i2c-mt65xx.c |   15 +++++++++++----
 1 file changed, 11 insertions(+), 4 deletions(-)

diff --git a/drivers/i2c/busses/i2c-mt65xx.c b/drivers/i2c/busses/i2c-mt65xx.c
index e28ad4c..c02e6c0 100644
--- a/drivers/i2c/busses/i2c-mt65xx.c
+++ b/drivers/i2c/busses/i2c-mt65xx.c
@@ -557,15 +557,22 @@ static irqreturn_t mtk_i2c_irq(int irqno, void *dev_id)
 {
 	struct mtk_i2c *i2c = dev_id;
 	u16 restart_flag = 0;
+	u16 intr_stat;
 
 	if (i2c->dev_comp->auto_restart)
 		restart_flag = I2C_RS_TRANSFER;
 
-	i2c->irq_stat = readw(i2c->base + OFFSET_INTR_STAT);
-	writew(restart_flag | I2C_HS_NACKERR | I2C_ACKERR
-		| I2C_TRANSAC_COMP, i2c->base + OFFSET_INTR_STAT);
+	intr_stat = readw(i2c->base + OFFSET_INTR_STAT);
+	writew(intr_stat, i2c->base + OFFSET_INTR_STAT);
 
-	complete(&i2c->msg_complete);
+	/*
+	 * when occurs ack error, i2c controller generate two interrupts
+	 * first is the ack error interrupt, then the complete interrupt
+	 * i2c->irq_stat need keep the two interrupt value.
+	 */
+	i2c->irq_stat |= intr_stat;
+	if (i2c->irq_stat & (I2C_TRANSAC_COMP | restart_flag))
+		complete(&i2c->msg_complete);
 
 	return IRQ_HANDLED;
 }
-- 
1.7.9.5



From eddie.huang at mediatek.com  Thu Aug  6 00:22:10 2015
From: eddie.huang at mediatek.com (Eddie Huang)
Date: Thu, 6 Aug 2015 15:22:10 +0800
Subject: [PATCH v2 1/2] i2c: mediatek: Reset DMA engine in hardware init
 function
In-Reply-To: <1438845731-17805-1-git-send-email-eddie.huang@mediatek.com>
References: <1438845731-17805-1-git-send-email-eddie.huang@mediatek.com>
Message-ID: <1438845731-17805-2-git-send-email-eddie.huang@mediatek.com>

Reset DMA in hardware init function to avoid unknown hardware state
before do any I2C operation.

Signed-off-by: Liguo Zhang <liguo.zhang at mediatek.com>
Signed-off-by: Eddie Huang <eddie.huang at mediatek.com>
---
 drivers/i2c/busses/i2c-mt65xx.c |    6 ++++++
 1 file changed, 6 insertions(+)

diff --git a/drivers/i2c/busses/i2c-mt65xx.c b/drivers/i2c/busses/i2c-mt65xx.c
index 9920eef..e28ad4c 100644
--- a/drivers/i2c/busses/i2c-mt65xx.c
+++ b/drivers/i2c/busses/i2c-mt65xx.c
@@ -59,6 +59,7 @@
 #define I2C_DMA_START_EN		0x0001
 #define I2C_DMA_INT_FLAG_NONE		0x0000
 #define I2C_DMA_CLR_FLAG		0x0000
+#define I2C_DMA_HARD_RST		0x0002
 
 #define I2C_DEFAULT_SPEED		100000	/* hz */
 #define MAX_FS_MODE_SPEED		400000
@@ -81,6 +82,7 @@ enum DMA_REGS_OFFSET {
 	OFFSET_INT_FLAG = 0x0,
 	OFFSET_INT_EN = 0x04,
 	OFFSET_EN = 0x08,
+	OFFSET_RST = 0x0c,
 	OFFSET_CON = 0x18,
 	OFFSET_TX_MEM_ADDR = 0x1c,
 	OFFSET_RX_MEM_ADDR = 0x20,
@@ -262,6 +264,10 @@ static void mtk_i2c_init_hw(struct mtk_i2c *i2c)
 		      I2C_CONTROL_CLK_EXT_EN | I2C_CONTROL_DMA_EN;
 	writew(control_reg, i2c->base + OFFSET_CONTROL);
 	writew(I2C_DELAY_LEN, i2c->base + OFFSET_DELAY_LEN);
+
+	writel(I2C_DMA_HARD_RST, i2c->pdmabase + OFFSET_RST);
+	udelay(50);
+	writel(I2C_DMA_CLR_FLAG, i2c->pdmabase + OFFSET_RST);
 }
 
 /*
-- 
1.7.9.5



From jh80.chung at samsung.com  Thu Aug  6 00:33:42 2015
From: jh80.chung at samsung.com (Jaehoon Chung)
Date: Thu, 06 Aug 2015 16:33:42 +0900
Subject: [RFC PATCH v4 0/9]
In-Reply-To: <55C30D52.6040802@rock-chips.com>
References: <1438843469-23807-1-git-send-email-shawn.lin@rock-chips.com>
 <55C307D2.7020501@samsung.com> <55C30D52.6040802@rock-chips.com>
Message-ID: <55C30DD6.8020802@samsung.com>

On 08/06/2015 04:31 PM, Shawn Lin wrote:
> ? 2015/8/6 15:08, Jaehoon Chung ??:
>> Hi, Shawn.
>>
>> I remembered that Krzysztof has mentioned "Fix the title of cover letter."
>> Your cover letter's title is nothing.. "[RFC PATCH v4 0/9] " ??
>> [RFC PATCH v4 0/9] your title...
>  Sorry, I forgot it, and will fix in next version...

No problem :) 
At next time,  add the title at your cover-letter, plz.

Best Regards,
Jaehoon Chung

> 
>> Best Regards,
>> Jaehoon Chung
>>
>> On 08/06/2015 03:44 PM, Shawn Lin wrote:
>>> Add external dma support for Synopsys MSHC
>>>
>>> Synopsys DesignWare mobile storage host controller supports three
>>> types of transfer mode: pio, internal dma and external dma. However,
>>> dw_mmc can only supports pio and internal dma now. Thus some platforms
>>> using dw-mshc integrated with generic dma can't work in dma mode. So we
>>> submit this patch to achieve it.
>>>
>>> And the config option, CONFIG_MMC_DW_IDMAC, was added by Will Newton
>>> (commit:f95f3850) for the first version of dw_mmc and never be touched since
>>> then. At that time dt-bindings hadn't been introduced into dw_mmc yet means
>>> we should select CONFIG_MMC_DW_IDMAC to enable internal dma mode at compile
>>> time. Nowadays, device-tree helps us to support a variety of boards with one
>>> kernel. That's why we need to remove it and decide the transfer mode by reading
>>> dw_mmc's HCON reg at runtime.
>>>
>>> This RFC patch needs lots of ACKs. I know it's hard, but it does need someone
>>> to make the running.
>>>
>>> Patch does the following things:
>>> - remove CONFIG_MMC_DW_IDMAC config option
>>> - add bindings for edmac used by synopsys-dw-mshc
>>>    at runtime
>>> - add edmac support for synopsys-dw-mshc
>>>
>>> Patch is based on next of git://git.linaro.org/people/ulf.hansson/mmc
>>>
>>>
>>> Changes in v4:
>>> - remove "host->trans_mode" and use "host->use_dma" to indicate
>>>    transfer mode.
>>> - remove all bt-bindings' changes since we don't need new properities.
>>> - check transfer mode at runtime by reading HCON reg
>>> - spilt defconfig changes for each sub-architecture
>>> - fix the title of cover letter
>>> - reuse some code for reducing code size
>>>
>>> Changes in v3:
>>> - choose transfer mode at runtime
>>> - remove all CONFIG_MMC_DW_IDMAC config option
>>> - add supports-idmac property for some platforms
>>>
>>> Changes in v2:
>>> - Fix typo of dev_info msg
>>> - remove unused dmach from declaration of dw_mci_dma_slave
>>>
>>> Shawn Lin (9):
>>>    mmc: dw_mmc: Add external dma interface support
>>>    Documentation: synopsys-dw-mshc: add bindings for idmac and edmac
>>>    mips: pistachio_defconfig: remove CONFIG_MMC_DW_IDMAC
>>>    arc: axs10x_defconfig: remove CONFIG_MMC_DW_IDMAC
>>>    arm: exynos_defconfig: remove CONFIG_MMC_DW_IDMAC
>>>    arm: hisi_defconfig: remove CONFIG_MMC_DW_IDMAC
>>>    arm: lpc18xx_defconfig: remove CONFIG_MMC_DW_IDMAC
>>>    arm: multi_v7_defconfig: remove CONFIG_MMC_DW_IDMAC
>>>    arm: zx_defconfig: remove CONFIG_MMC_DW_IDMAC
>>>
>>>   .../devicetree/bindings/mmc/synopsys-dw-mshc.txt   |  25 ++
>>>   arch/arc/configs/axs101_defconfig                  |   1 -
>>>   arch/arc/configs/axs103_defconfig                  |   1 -
>>>   arch/arc/configs/axs103_smp_defconfig              |   1 -
>>>   arch/arm/configs/exynos_defconfig                  |   1 -
>>>   arch/arm/configs/hisi_defconfig                    |   1 -
>>>   arch/arm/configs/lpc18xx_defconfig                 |   1 -
>>>   arch/arm/configs/multi_v7_defconfig                |   1 -
>>>   arch/arm/configs/zx_defconfig                      |   1 -
>>>   arch/mips/configs/pistachio_defconfig              |   1 -
>>>   drivers/mmc/host/Kconfig                           |  11 +-
>>>   drivers/mmc/host/dw_mmc-pltfm.c                    |   2 +
>>>   drivers/mmc/host/dw_mmc.c                          | 258 +++++++++++++++++----
>>>   include/linux/mmc/dw_mmc.h                         |  27 ++-
>>>   14 files changed, 257 insertions(+), 75 deletions(-)
>>>
>>
>>
>>
> 
> 



From k.kozlowski at samsung.com  Thu Aug  6 00:37:43 2015
From: k.kozlowski at samsung.com (Krzysztof Kozlowski)
Date: Thu, 06 Aug 2015 16:37:43 +0900
Subject: [RFC PATCH v4 1/9] mmc: dw_mmc: Add external dma interface support
In-Reply-To: <55C30C1C.6070801@rock-chips.com>
References: <1438843469-23807-1-git-send-email-shawn.lin@rock-chips.com>
 <1438843491-23853-1-git-send-email-shawn.lin@rock-chips.com>
 <55C307D4.1020209@samsung.com> <55C30C1C.6070801@rock-chips.com>
Message-ID: <55C30EC7.7010604@samsung.com>

On 06.08.2015 16:26, Shawn Lin wrote:
> ? 2015/8/6 15:08, Krzysztof Kozlowski ??:
>> On 06.08.2015 15:44, Shawn Lin wrote:
>>> DesignWare MMC Controller can supports two types of DMA
>>> mode: external dma and internal dma. We get a RK312x platform
>>> integrated dw_mmc and ARM pl330 dma controller. This patch add
>>> edmac ops to support these platforms. I've tested it on RK312x
>>> platform with edmac mode and RK3288 platform with idmac mode.
>>>
>>> Signed-off-by: Shawn Lin <shawn.lin at rock-chips.com>
>>>
>>> ---
>>>
>>> Changes in v4:
>>> - remove "host->trans_mode" and use "host->use_dma" to indicate
>>>    transfer mode.
>>> - remove all bt-bindings' changes since we don't need new properities.
>>> - check transfer mode at runtime by reading HCON reg
>>> - spilt defconfig changes for each sub-architecture
>>> - fix the title of cover letter
>> How did you fixed the title? It is still empty :)
>>     Subject: [RFC PATCH v4 0/9]
>   I mentioned that in ChangeLog-v4 but unfortunately I forgot it.
>   Thanks, Krzysztof.  I will be more careful and add it for next version.
> 
>>
>>> - reuse some code for reducing code size
>>>
>>> Changes in v3:
>>> - choose transfer mode at runtime
>>> - remove all CONFIG_MMC_DW_IDMAC config option
>>> - add supports-idmac property for some platforms
>>>
>>> Changes in v2:
>>> - Fix typo of dev_info msg
>>> - remove unused dmach from declaration of dw_mci_dma_slave
>>>
>>>   drivers/mmc/host/Kconfig        |  11 +-
>>>   drivers/mmc/host/dw_mmc-pltfm.c |   2 +
>>>   drivers/mmc/host/dw_mmc.c       | 258
>>> ++++++++++++++++++++++++++++++++--------
>>>   include/linux/mmc/dw_mmc.h      |  27 ++++-
>>>   4 files changed, 232 insertions(+), 66 deletions(-)
>>>
>>> diff --git a/drivers/mmc/host/Kconfig b/drivers/mmc/host/Kconfig
>>> index 6a0f9c7..a86c0eb 100644
>>> --- a/drivers/mmc/host/Kconfig
>>> +++ b/drivers/mmc/host/Kconfig
>>> @@ -607,15 +607,7 @@ config MMC_DW
>>>       help
>>>         This selects support for the Synopsys DesignWare Mobile
>>> Storage IP
>>>         block, this provides host support for SD and MMC interfaces,
>>> in both
>>> -      PIO and external DMA modes.
>>> -
>>> -config MMC_DW_IDMAC
>>> -    bool "Internal DMAC interface"
>>> -    depends on MMC_DW
>>> -    help
>>> -      This selects support for the internal DMAC block within the
>>> Synopsys
>>> -      Designware Mobile Storage IP block. This disables the external
>>> DMA
>>> -      interface.
>>> +      PIO, internal DMA mode and external DMA modes.
>>>     config MMC_DW_PLTFM
>>>       tristate "Synopsys Designware MCI Support as platform device"
>>> @@ -644,7 +636,6 @@ config MMC_DW_K3
>>>       tristate "K3 specific extensions for Synopsys DW Memory Card
>>> Interface"
>>>       depends on MMC_DW
>>>       select MMC_DW_PLTFM
>>> -    select MMC_DW_IDMAC
>>>       help
>>>         This selects support for Hisilicon K3 SoC specific extensions
>>> to the
>>>         Synopsys DesignWare Memory Card Interface driver. Select this
>>> option
>>> diff --git a/drivers/mmc/host/dw_mmc-pltfm.c
>>> b/drivers/mmc/host/dw_mmc-pltfm.c
>>> index ec6dbcd..7e1d13b 100644
>>> --- a/drivers/mmc/host/dw_mmc-pltfm.c
>>> +++ b/drivers/mmc/host/dw_mmc-pltfm.c
>>> @@ -59,6 +59,8 @@ int dw_mci_pltfm_register(struct platform_device
>>> *pdev,
>>>       host->pdata = pdev->dev.platform_data;
>>>         regs = platform_get_resource(pdev, IORESOURCE_MEM, 0);
>>> +    /* Get registers' physical base address */
>>> +    host->phy_regs = (void *)(regs->start);
>>>       host->regs = devm_ioremap_resource(&pdev->dev, regs);
>>>       if (IS_ERR(host->regs))
>>>           return PTR_ERR(host->regs);
>>> diff --git a/drivers/mmc/host/dw_mmc.c b/drivers/mmc/host/dw_mmc.c
>>> index 40e9d8e..5d6cdff 100644
>>> --- a/drivers/mmc/host/dw_mmc.c
>>> +++ b/drivers/mmc/host/dw_mmc.c
>>> @@ -56,7 +56,7 @@
>>>   #define DW_MCI_FREQ_MAX    200000000    /* unit: HZ */
>>>   #define DW_MCI_FREQ_MIN    400000        /* unit: HZ */
>>>   -#ifdef CONFIG_MMC_DW_IDMAC
>>> +
>>>   #define IDMAC_INT_CLR        (SDMMC_IDMAC_INT_AI |
>>> SDMMC_IDMAC_INT_NI | \
>>>                    SDMMC_IDMAC_INT_CES | SDMMC_IDMAC_INT_DU | \
>>>                    SDMMC_IDMAC_INT_FBE | SDMMC_IDMAC_INT_RI | \
>>> @@ -99,7 +99,6 @@ struct idmac_desc {
>>>         __le32        des3;    /* buffer 2 physical address */
>>>   };
>>> -#endif /* CONFIG_MMC_DW_IDMAC */
>>>     static bool dw_mci_reset(struct dw_mci *host);
>>>   static bool dw_mci_ctrl_reset(struct dw_mci *host, u32 reset);
>>> @@ -403,7 +402,6 @@ static int dw_mci_get_dma_dir(struct mmc_data *data)
>>>           return DMA_FROM_DEVICE;
>>>   }
>>>   -#ifdef CONFIG_MMC_DW_IDMAC
>>>   static void dw_mci_dma_cleanup(struct dw_mci *host)
>>>   {
>>>       struct mmc_data *data = host->data;
>>> @@ -441,12 +439,21 @@ static void dw_mci_idmac_stop_dma(struct dw_mci
>>> *host)
>>>       mci_writel(host, BMOD, temp);
>>>   }
>>>   -static void dw_mci_idmac_complete_dma(struct dw_mci *host)
>>> +static void dw_mci_dmac_complete_dma(void *arg)
>>>   {
>>> +    struct dw_mci *host = arg;
>> Why changing the argument to void*?
> 
> This function will be used as callback hook of dmaengine, and the
> prototype is
> "typedef void (*dma_async_tx_callback)(void *dma_async_param);".
> w/o this change, we meet a warning  for incompatible pointer case.

Thanks for clarifying.

Best regards,
Krzysztof



From shawnguo at kernel.org  Thu Aug  6 00:41:34 2015
From: shawnguo at kernel.org (Shawn Guo)
Date: Thu, 6 Aug 2015 15:41:34 +0800
Subject: [PATCH] ARM: dts: imx6sx: correct property name for wakeup source
In-Reply-To: <1438783075-15133-1-git-send-email-b20788@freescale.com>
References: <1438783075-15133-1-git-send-email-b20788@freescale.com>
Message-ID: <20150806074134.GA9847@tiger>

On Wed, Aug 05, 2015 at 09:57:55PM +0800, Anson Huang wrote:
> Commit(def56bb input: snvs_pwrkey: use "wakeup-source"
> as deivce tree property name) replaces the property name
> of "wakeup" with "wakeup-source", update this change
> in i.MX6SX dtsi accordingly.
> 
> Signed-off-by: Anson Huang <b20788 at freescale.com>

For arch/arm/ patches, please remember to copy linux-arm-kernel.

Applied, thanks.

> ---
>  arch/arm/boot/dts/imx6sx.dtsi | 2 +-
>  1 file changed, 1 insertion(+), 1 deletion(-)
> 
> diff --git a/arch/arm/boot/dts/imx6sx.dtsi b/arch/arm/boot/dts/imx6sx.dtsi
> index e391d63..dc7eaae 100644
> --- a/arch/arm/boot/dts/imx6sx.dtsi
> +++ b/arch/arm/boot/dts/imx6sx.dtsi
> @@ -686,7 +686,7 @@
>  					regmap = <&snvs>;
>  					interrupts = <GIC_SPI 4 IRQ_TYPE_LEVEL_HIGH>;
>  					linux,keycode = <KEY_POWER>;
> -					wakeup;
> +					wakeup-source;
>  				};
>  			};
>  
> -- 
> 1.9.1
> 


From marc.zyngier at arm.com  Thu Aug  6 00:56:18 2015
From: marc.zyngier at arm.com (Marc Zyngier)
Date: Thu, 06 Aug 2015 08:56:18 +0100
Subject: [PATCH 1/3] Docs: dt: add generic MSI bindings
In-Reply-To: <20150805165120.GB28849@leverpostej>
References: <1437670365-20704-1-git-send-email-mark.rutland@arm.com>
 <1437670365-20704-2-git-send-email-mark.rutland@arm.com>
 <20150805165120.GB28849@leverpostej>
Message-ID: <55C31322.1000608@arm.com>

On 05/08/15 17:51, Mark Rutland wrote:
> Rob,
> 
> Do you have any objections to this, or are you happy to take this patch?
> 
> There's a user of this binding (the GICv3 ITS) queued for v4.3 already in
> the tip tree, so either we either need to be ok with this binding or we
> need to rework that before v4.3.
> 
> Marc, can I take it from your use of the binding that you are happy to
> provide your ack?

Definitely.

Acked-by: Marc Zyngier <marc.zyngier at arm.com>

	M.
-- 
Jazz is not dead. It just smells funny...


From shawnguo at kernel.org  Thu Aug  6 00:57:23 2015
From: shawnguo at kernel.org (Shawn Guo)
Date: Thu, 6 Aug 2015 15:57:23 +0800
Subject: [PATCH V2] ARM: imx: add cpuidle support for i.mx6ul
In-Reply-To: <1438711164-9106-1-git-send-email-b20788@freescale.com>
References: <1438711164-9106-1-git-send-email-b20788@freescale.com>
Message-ID: <20150806075723.GB9847@tiger>

On Wed, Aug 05, 2015 at 01:59:24AM +0800, Anson Huang wrote:
> This patch introduces an independent cpuidle driver for
> i.MX6UL, totally 3 levels of cpuidle are supported as below:
> 
> 1. ARM WFI;
> 2. SOC in WAIT mode;
> 3. SOC in WAIT mode + ARM power off.
> 
> Signed-off-by: Anson Huang <b20788 at freescale.com>

>From what I've seen, it's almost identical to cpuidle-imx6sx driver.
We should consider to share the driver code rather than creating another
one with a lot of duplicating code.

Shawn

> ---
> change from V1:
> 	remove CPUIDLE_FLAG_TIMER_STOP flag as i.MX6UL does
> NOT use local timer.
>  arch/arm/mach-imx/Makefile         |   1 +
>  arch/arm/mach-imx/cpuidle-imx6ul.c | 105 +++++++++++++++++++++++++++++++++++++
>  arch/arm/mach-imx/cpuidle.h        |   5 ++
>  arch/arm/mach-imx/mach-imx6ul.c    |   8 +++
>  4 files changed, 119 insertions(+)
>  create mode 100644 arch/arm/mach-imx/cpuidle-imx6ul.c
> 
> diff --git a/arch/arm/mach-imx/Makefile b/arch/arm/mach-imx/Makefile
> index fb689d8..1d7df9c 100644
> --- a/arch/arm/mach-imx/Makefile
> +++ b/arch/arm/mach-imx/Makefile
> @@ -28,6 +28,7 @@ obj-$(CONFIG_SOC_IMX5) += cpuidle-imx5.o
>  obj-$(CONFIG_SOC_IMX6Q) += cpuidle-imx6q.o
>  obj-$(CONFIG_SOC_IMX6SL) += cpuidle-imx6sl.o
>  obj-$(CONFIG_SOC_IMX6SX) += cpuidle-imx6sx.o
> +obj-$(CONFIG_SOC_IMX6UL) += cpuidle-imx6ul.o
>  endif
>  
>  ifdef CONFIG_SND_IMX_SOC
> diff --git a/arch/arm/mach-imx/cpuidle-imx6ul.c b/arch/arm/mach-imx/cpuidle-imx6ul.c
> new file mode 100644
> index 0000000..27ab28a
> --- /dev/null
> +++ b/arch/arm/mach-imx/cpuidle-imx6ul.c
> @@ -0,0 +1,105 @@
> +/*
> + * Copyright (C) 2015 Freescale Semiconductor, Inc.
> + *
> + * This program is free software; you can redistribute it and/or modify
> + * it under the terms of the GNU General Public License version 2 as
> + * published by the Free Software Foundation.
> + */
> +
> +#include <linux/cpuidle.h>
> +#include <linux/cpu_pm.h>
> +#include <linux/module.h>
> +#include <asm/cacheflush.h>
> +#include <asm/cpuidle.h>
> +#include <asm/suspend.h>
> +
> +#include "common.h"
> +#include "cpuidle.h"
> +
> +static int imx6ul_idle_finish(unsigned long val)
> +{
> +	flush_cache_all();
> +	cpu_do_idle();
> +
> +	return 0;
> +}
> +
> +static int imx6ul_enter_wait(struct cpuidle_device *dev,
> +			    struct cpuidle_driver *drv, int index)
> +{
> +	imx6_set_lpm(WAIT_UNCLOCKED);
> +
> +	switch (index) {
> +	case 1:
> +		cpu_do_idle();
> +		break;
> +	case 2:
> +		imx6_enable_rbc(true);
> +		imx_gpc_set_arm_power_in_lpm(true);
> +		imx_set_cpu_jump(0, v7_cpu_resume);
> +		/* Need to notify there is a cpu pm operation. */
> +		cpu_pm_enter();
> +		cpu_cluster_pm_enter();
> +
> +		cpu_suspend(0, imx6ul_idle_finish);
> +
> +		cpu_cluster_pm_exit();
> +		cpu_pm_exit();
> +		imx_gpc_set_arm_power_in_lpm(false);
> +		imx6_enable_rbc(false);
> +		break;
> +	default:
> +		break;
> +	}
> +
> +	imx6_set_lpm(WAIT_CLOCKED);
> +
> +	return index;
> +}
> +
> +static struct cpuidle_driver imx6ul_cpuidle_driver = {
> +	.name = "imx6ul_cpuidle",
> +	.owner = THIS_MODULE,
> +	.states = {
> +		/* WFI */
> +		ARM_CPUIDLE_WFI_STATE,
> +		/* WAIT */
> +		{
> +			.exit_latency = 50,
> +			.target_residency = 75,
> +			.enter = imx6ul_enter_wait,
> +			.name = "WAIT",
> +			.desc = "Clock off",
> +		},
> +		/* WAIT + ARM power off  */
> +		{
> +			/*
> +			 * ARM gating 31us * 5 + RBC clear 65us
> +			 * and some margin for SW execution, here set it
> +			 * to 300us.
> +			 */
> +			.exit_latency = 300,
> +			.target_residency = 500,
> +			.enter = imx6ul_enter_wait,
> +			.name = "LOW-POWER-IDLE",
> +			.desc = "ARM power off",
> +		},
> +	},
> +	.state_count = 3,
> +	.safe_state_index = 0,
> +};
> +
> +int __init imx6ul_cpuidle_init(void)
> +{
> +	imx6_enable_rbc(false);
> +	/*
> +	 * set ARM power up/down timing to the fastest,
> +	 * sw2iso and sw can be set to one 32K cycle = 31us
> +	 * except for power up sw2iso which need to be
> +	 * larger than LDO ramp up time.
> +	 */
> +	imx_gpc_set_arm_power_up_timing(2, 1);
> +	imx_gpc_set_arm_power_down_timing(1, 1);
> +
> +	return cpuidle_register(&imx6ul_cpuidle_driver, NULL);
> +}
> diff --git a/arch/arm/mach-imx/cpuidle.h b/arch/arm/mach-imx/cpuidle.h
> index f914012..4dcf71d 100644
> --- a/arch/arm/mach-imx/cpuidle.h
> +++ b/arch/arm/mach-imx/cpuidle.h
> @@ -15,6 +15,7 @@ extern int imx5_cpuidle_init(void);
>  extern int imx6q_cpuidle_init(void);
>  extern int imx6sl_cpuidle_init(void);
>  extern int imx6sx_cpuidle_init(void);
> +extern int imx6ul_cpuidle_init(void);
>  #else
>  static inline int imx5_cpuidle_init(void)
>  {
> @@ -32,4 +33,8 @@ static inline int imx6sx_cpuidle_init(void)
>  {
>  	return 0;
>  }
> +static inline int imx6ul_cpuidle_init(void)
> +{
> +	return 0;
> +}
>  #endif
> diff --git a/arch/arm/mach-imx/mach-imx6ul.c b/arch/arm/mach-imx/mach-imx6ul.c
> index f206506..0f4b95c 100644
> --- a/arch/arm/mach-imx/mach-imx6ul.c
> +++ b/arch/arm/mach-imx/mach-imx6ul.c
> @@ -11,6 +11,7 @@
>  #include <asm/mach/map.h>
>  
>  #include "common.h"
> +#include "cpuidle.h"
>  
>  static void __init imx6ul_init_machine(void)
>  {
> @@ -29,6 +30,12 @@ static void __init imx6ul_init_irq(void)
>  	imx_init_revision_from_anatop();
>  	imx_src_init();
>  	irqchip_init();
> +	imx6_pm_ccm_init("fsl,imx6ul-ccm");
> +}
> +
> +static void __init imx6ul_init_late(void)
> +{
> +	imx6ul_cpuidle_init();
>  }
>  
>  static const char *imx6ul_dt_compat[] __initconst = {
> @@ -40,4 +47,5 @@ DT_MACHINE_START(IMX6UL, "Freescale i.MX6 Ultralite (Device Tree)")
>  	.init_irq	= imx6ul_init_irq,
>  	.init_machine	= imx6ul_init_machine,
>  	.dt_compat	= imx6ul_dt_compat,
> +	.init_late	= imx6ul_init_late,
>  MACHINE_END
> -- 
> 1.9.1
> 


From wangzhou1 at hisilicon.com  Thu Aug  6 01:09:19 2015
From: wangzhou1 at hisilicon.com (Zhou Wang)
Date: Thu, 6 Aug 2015 16:09:19 +0800
Subject: [PATCH v6 6/6] MAINTAINERS: Add pcie-hisi maintainer
In-Reply-To: <1438848559-232109-1-git-send-email-wangzhou1@hisilicon.com>
References: <1438848559-232109-1-git-send-email-wangzhou1@hisilicon.com>
Message-ID: <1438848559-232109-7-git-send-email-wangzhou1@hisilicon.com>

Signed-off-by: Zhou Wang <wangzhou1 at hisilicon.com>
---
 MAINTAINERS | 7 +++++++
 1 file changed, 7 insertions(+)

diff --git a/MAINTAINERS b/MAINTAINERS
index 8133cef..7cd8e47 100644
--- a/MAINTAINERS
+++ b/MAINTAINERS
@@ -7854,6 +7854,13 @@ S:	Maintained
 F:	Documentation/devicetree/bindings/pci/xgene-pci-msi.txt
 F:	drivers/pci/host/pci-xgene-msi.c
 
+PCIE DRIVER FOR HISILICON
+M:	Zhou Wang <wangzhou1 at hisilicon.com>
+L:	linux-pci at vger.kernel.org
+S:	Maintained
+F:	Documentation/devicetree/bindings/pci/hisilicon-pcie.txt
+F:	drivers/pci/host/pcie-hisi.c
+
 PCMCIA SUBSYSTEM
 P:	Linux PCMCIA Team
 L:	linux-pcmcia at lists.infradead.org
-- 
1.9.1



From wangzhou1 at hisilicon.com  Thu Aug  6 01:09:18 2015
From: wangzhou1 at hisilicon.com (Zhou Wang)
Date: Thu, 6 Aug 2015 16:09:18 +0800
Subject: [PATCH v6 5/6] Documentation: DT: Add HiSilicon PCIe host binding
In-Reply-To: <1438848559-232109-1-git-send-email-wangzhou1@hisilicon.com>
References: <1438848559-232109-1-git-send-email-wangzhou1@hisilicon.com>
Message-ID: <1438848559-232109-6-git-send-email-wangzhou1@hisilicon.com>

This patch adds related DTS binding document for HiSilicon PCIe host driver.

Signed-off-by: Zhou Wang <wangzhou1 at hisilicon.com>
---
 .../devicetree/bindings/pci/hisilicon-pcie.txt     | 46 ++++++++++++++++++++++
 1 file changed, 46 insertions(+)
 create mode 100644 Documentation/devicetree/bindings/pci/hisilicon-pcie.txt

diff --git a/Documentation/devicetree/bindings/pci/hisilicon-pcie.txt b/Documentation/devicetree/bindings/pci/hisilicon-pcie.txt
new file mode 100644
index 0000000..2afc9d1
--- /dev/null
+++ b/Documentation/devicetree/bindings/pci/hisilicon-pcie.txt
@@ -0,0 +1,46 @@
+HiSilicon PCIe host bridge DT description
+
+HiSilicon PCIe host controller is based on Designware PCI core.
+It shares common functions with PCIe Designware core driver and inherits
+common properties defined in
+Documentation/devicetree/bindings/pci/designware-pci.txt.
+
+Additional properties are described here:
+
+Required properties:
+- compatible: Should contain "hisilicon,hip05-pcie".
+- reg: Should contain rc_dbi, subctrl, config registers location and length.
+- reg-names: Must include the following entries:
+  "rc_dbi": controller configuration registers;
+  "subctrl": whole PCIe hosts configuration registers;
+  "config": PCIe configuration space registers.
+- msi-parent: Should be its_pcie which is an ITS receiving MSI interrupts.
+- port-id: Should be 0, 1, 2 or 3.
+
+Optional properties:
+- status: Either "ok" or "disabled".
+- dma-coherent: Present if DMA operations are coherent.
+
+Example:
+	pcie at 0xb0080000 {
+		compatible = "hisilicon,hip05-pcie", "snps,dw-pcie";
+		reg = <0 0xb0080000 0 0x10000>, <0 0xb0000000 0 0x10000>,
+		      <0x220 0x00000000 0 0x2000>;
+		reg-names = "rc_dbi", "subctrl", "config";
+		bus-range = <0  15>;
+		msi-parent = <&its_pcie>;
+		#address-cells = <3>;
+		#size-cells = <2>;
+		device_type = "pci";
+		dma-coherent;
+		ranges = <0x82000000 0 0x00000000 0x220 0x00000000 0 0x10000000>;
+		num-lanes = <8>;
+		port-id = <1>;
+		#interrupts-cells = <1>;
+		interrupts-map-mask = <0xf800 0 0 7>;
+		interrupts-map = <0x0 0 0 1 &mbigen_pcie 1 10
+				  0x0 0 0 2 &mbigen_pcie 2 11
+				  0x0 0 0 3 &mbigen_pcie 3 12
+				  0x0 0 0 4 &mbigen_pcie 4 13>;
+		status = "ok";
+	};
-- 
1.9.1



From wangzhou1 at hisilicon.com  Thu Aug  6 01:09:13 2015
From: wangzhou1 at hisilicon.com (Zhou Wang)
Date: Thu, 6 Aug 2015 16:09:13 +0800
Subject: [PATCH v6 0/6] PCI: hisi: Add PCIe host support for HiSilicon SoC
 Hip05
Message-ID: <1438848559-232109-1-git-send-email-wangzhou1@hisilicon.com>

This patchset adds PCIe host support for HiSilicon SoC Hip05. The PCIe hosts
use PCIe IP core from Synopsys, So this driver is base on designware PCIe driver.

Hip05 is an ARMv8 architecture SoC. It should be able to use ARM64 PCIe API in
designeware PCIe driver. So this patch also adds ARM64 support for designware
pcie.

This patchset is based on v4.2-rc1.

Change from v5:
- Merge 1/6 in this series, discussion about this can be found in [1]

Change from v4:
- Change the author of 1/5 to Gabriele.
- Modify problems in 3/5 pointed by Bjorn.
- Modify spelling problems in 4/5.

Change from v3:
- Change 1/5 to what Gabriele suggested.
- Use win->__res.start to get *_mod_base in 2/5, this fix a bug in v3 series.

Change from v2:
- Move struct pci_dev *dev and struct pci_sys_data *sys in
  pcibios_align_resource in 1/5.
- Add Gabriele's codes in 2/5 which delete unnecessary information parse and
  use of_pci_get_host_bridge_resources for both ARM32 and ARM64.
- Add maintainer patch 5/5.

Change from RFC v1:
- Add 1/4 patch by Arnd which removes align_resource callback in ARM
  pcibios_align_resource.
- Change head file in pcie-designware from asm/hardirq.h to linux/hardirq.h.
- Set pp->root_bus_nr = 0 in dra7xx, exynos, imx6, keystone, layerscape,
  spear13xx.
- Remove unnecessary parentheses of some macros in pcie-hisi.
- Use macro to replace some magic values.
- Merge two loops together and add some comments about it in context_config
  function in pcie-hisi.
- Modify some value of items in pcie node example in binding document. 

Change from RFC:
- delete dw_pcie_setup, dw_pcie_scan_bus, dw_pcie_map_irq and struct hw_pci,
  merge related operations into dw_pcie_host_init.

Link of v5:
- http://www.spinics.net/lists/devicetree/msg87959.html
Link of v4:
- http://www.spinics.net/lists/arm-kernel/msg433050.html
Link of v3:
- http://www.spinics.net/lists/linux-pci/msg42539.html
Link of v2:
- http://www.spinics.net/lists/linux-pci/msg41844.html
Link of RFC v1:
- http://www.spinics.net/lists/linux-pci/msg41305.html
Link of RFC:
- http://www.spinics.net/lists/linux-pci/msg40434.html

[1] http://lists.infradead.org/pipermail/linux-arm-kernel/2015-July/359741.html

Zhou Wang (4):
  PCI: designware: Add ARM64 support
  PCI: hisi: Add PCIe host support for HiSilicon SoC Hip05
  Documentation: DT: Add HiSilicon PCIe host binding
  MAINTAINERS: Add pcie-hisi maintainer

gabriele paoloni (2):
  PCI: designware: move calculation of bus addresses to DRA7xx
  ARM/PCI: remove align_resource in pci_sys_data

 .../devicetree/bindings/pci/hisilicon-pcie.txt     |  46 ++++
 MAINTAINERS                                        |   7 +
 arch/arm/include/asm/mach/pci.h                    |   5 -
 arch/arm/kernel/bios32.c                           |  12 +-
 drivers/pci/host/Kconfig                           |   8 +
 drivers/pci/host/Makefile                          |   1 +
 drivers/pci/host/pci-dra7xx.c                      |  14 ++
 drivers/pci/host/pci-exynos.c                      |   2 +-
 drivers/pci/host/pci-imx6.c                        |   2 +-
 drivers/pci/host/pci-keystone-dw.c                 |   2 +-
 drivers/pci/host/pci-keystone.c                    |   2 +-
 drivers/pci/host/pci-layerscape.c                  |   2 +-
 drivers/pci/host/pcie-designware.c                 | 236 ++++++-------------
 drivers/pci/host/pcie-designware.h                 |  14 +-
 drivers/pci/host/pcie-hisi.c                       | 254 +++++++++++++++++++++
 drivers/pci/host/pcie-spear13xx.c                  |   2 +-
 16 files changed, 425 insertions(+), 184 deletions(-)
 create mode 100644 Documentation/devicetree/bindings/pci/hisilicon-pcie.txt
 create mode 100644 drivers/pci/host/pcie-hisi.c

-- 
1.9.1



From wangzhou1 at hisilicon.com  Thu Aug  6 01:09:14 2015
From: wangzhou1 at hisilicon.com (Zhou Wang)
Date: Thu, 6 Aug 2015 16:09:14 +0800
Subject: [PATCH v6 1/6] PCI: designware: move calculation of bus addresses to
 DRA7xx
In-Reply-To: <1438848559-232109-1-git-send-email-wangzhou1@hisilicon.com>
References: <1438848559-232109-1-git-send-email-wangzhou1@hisilicon.com>
Message-ID: <1438848559-232109-2-git-send-email-wangzhou1@hisilicon.com>

From: gabriele paoloni <gabriele.paoloni at huawei.com>

Commit f4c55c5a3f7f "PCI: designware: Program ATU with untranslated
address" added the calculation of PCI BUS addresses in designware,
storing them in new fields added in "struct pcie_port". This
calculation is done for every designware user even if is only
applicable to DRA7xx.
This patch moves the calculation of the bus addresses to the DRA7xx
driver and is needed to allow the rework of designware to use
the new DT parsing API.

Signed-off-by: Gabriele Paoloni <gabriele.paoloni at huawei.com>
Signed-off-by: Zhou Wang <wangzhou1 at hisilicon.com>
---
 drivers/pci/host/pci-dra7xx.c      | 13 +++++++++++++
 drivers/pci/host/pcie-designware.c | 15 ++++-----------
 2 files changed, 17 insertions(+), 11 deletions(-)

diff --git a/drivers/pci/host/pci-dra7xx.c b/drivers/pci/host/pci-dra7xx.c
index 80db09e..18ae7ff 100644
--- a/drivers/pci/host/pci-dra7xx.c
+++ b/drivers/pci/host/pci-dra7xx.c
@@ -61,6 +61,7 @@
 
 #define	PCIECTRL_DRA7XX_CONF_PHY_CS			0x010C
 #define	LINK_UP						BIT(16)
+#define	CPU_TO_BUS_ADDR					0x0FFFFFFF
 
 struct dra7xx_pcie {
 	void __iomem		*base;
@@ -139,6 +140,18 @@ static void dra7xx_pcie_enable_interrupts(struct pcie_port *pp)
 static void dra7xx_pcie_host_init(struct pcie_port *pp)
 {
 	dw_pcie_setup_rc(pp);
+
+	if (pp->io_mod_base)
+		pp->io_mod_base &= CPU_TO_BUS_ADDR;
+
+	if (pp->mem_mod_base)
+		pp->mem_mod_base &= CPU_TO_BUS_ADDR;
+
+	if (pp->cfg0_mod_base) {
+		pp->cfg0_mod_base &= CPU_TO_BUS_ADDR;
+		pp->cfg1_mod_base &= CPU_TO_BUS_ADDR;
+	}
+
 	dra7xx_pcie_establish_link(pp);
 	if (IS_ENABLED(CONFIG_PCI_MSI))
 		dw_pcie_msi_init(pp);
diff --git a/drivers/pci/host/pcie-designware.c b/drivers/pci/host/pcie-designware.c
index 69486be..c5d407c 100644
--- a/drivers/pci/host/pcie-designware.c
+++ b/drivers/pci/host/pcie-designware.c
@@ -366,14 +366,10 @@ int dw_pcie_host_init(struct pcie_port *pp)
 	struct of_pci_range range;
 	struct of_pci_range_parser parser;
 	struct resource *cfg_res;
-	u32 val, na, ns;
+	u32 val, ns;
 	const __be32 *addrp;
 	int i, index, ret;
 
-	/* Find the address cell size and the number of cells in order to get
-	 * the untranslated address.
-	 */
-	of_property_read_u32(np, "#address-cells", &na);
 	ns = of_n_size_cells(np);
 
 	cfg_res = platform_get_resource_byname(pdev, IORESOURCE_MEM, "config");
@@ -416,8 +412,7 @@ int dw_pcie_host_init(struct pcie_port *pp)
 			pp->io_base = range.cpu_addr;
 
 			/* Find the untranslated IO space address */
-			pp->io_mod_base = of_read_number(parser.range -
-							 parser.np + na, ns);
+			pp->io_mod_base = range.cpu_addr;
 		}
 		if (restype == IORESOURCE_MEM) {
 			of_pci_range_to_resource(&range, np, &pp->mem);
@@ -426,8 +421,7 @@ int dw_pcie_host_init(struct pcie_port *pp)
 			pp->mem_bus_addr = range.pci_addr;
 
 			/* Find the untranslated MEM space address */
-			pp->mem_mod_base = of_read_number(parser.range -
-							  parser.np + na, ns);
+			pp->mem_mod_base = range.cpu_addr;
 		}
 		if (restype == 0) {
 			of_pci_range_to_resource(&range, np, &pp->cfg);
@@ -437,8 +431,7 @@ int dw_pcie_host_init(struct pcie_port *pp)
 			pp->cfg1_base = pp->cfg.start + pp->cfg0_size;
 
 			/* Find the untranslated configuration space address */
-			pp->cfg0_mod_base = of_read_number(parser.range -
-							   parser.np + na, ns);
+			pp->cfg0_mod_base = range.cpu_addr;
 			pp->cfg1_mod_base = pp->cfg0_mod_base +
 					    pp->cfg0_size;
 		}
-- 
1.9.1



From wangzhou1 at hisilicon.com  Thu Aug  6 01:09:16 2015
From: wangzhou1 at hisilicon.com (Zhou Wang)
Date: Thu, 6 Aug 2015 16:09:16 +0800
Subject: [PATCH v6 3/6] PCI: designware: Add ARM64 support
In-Reply-To: <1438848559-232109-1-git-send-email-wangzhou1@hisilicon.com>
References: <1438848559-232109-1-git-send-email-wangzhou1@hisilicon.com>
Message-ID: <1438848559-232109-4-git-send-email-wangzhou1@hisilicon.com>

This patch tries to unify ARM32 and ARM64 PCIe in designware driver. Delete
function dw_pcie_setup, dw_pcie_scan_bus, dw_pcie_map_irq and struct hw_pci,
move related operations to dw_pcie_host_init.

In past, we use:
pci_common_init_dev
	-> pcibios_init_hw
		-> hw->scan (dw_pcie_scan_bus)
to pass 0 to root_bus_nr in struct pcie_port. This patch set pp->root_bus_nr = 0
in each PCIe host driver which is based on pcie-designware.

This patch also try to use of_pci_get_host_bridge_resources for ARM32 and ARM64
according to the suggestion for Gabriele[1]

Finally this patch reverts commit f4c55c5a3f7f "PCI: designware: Program ATU
with untranslated address" based on 1/6 in this series. we delete *_mod_base in
pcie-designware. This was discussed in [2]

I have compiled the driver with multi_v7_defconfig. However, I don't have
ARM32 PCIe related board to do test. It will be appreciated if someone could
help to test it.

Signed-off-by: Zhou Wang <wangzhou1 at hisilicon.com>
Signed-off-by: Gabriele Paoloni <gabriele.paoloni at huawei.com>
Signed-off-by: Arnd Bergmann <arnd at arndb.de>

[1] http://www.spinics.net/lists/linux-pci/msg42194.html
[2] http://www.spinics.net/lists/arm-kernel/msg436779.html
---
 drivers/pci/host/pci-dra7xx.c      |  15 +--
 drivers/pci/host/pci-exynos.c      |   2 +-
 drivers/pci/host/pci-imx6.c        |   2 +-
 drivers/pci/host/pci-keystone-dw.c |   2 +-
 drivers/pci/host/pci-keystone.c    |   2 +-
 drivers/pci/host/pci-layerscape.c  |   2 +-
 drivers/pci/host/pcie-designware.c | 229 ++++++++++++-------------------------
 drivers/pci/host/pcie-designware.h |  14 +--
 drivers/pci/host/pcie-spear13xx.c  |   2 +-
 9 files changed, 95 insertions(+), 175 deletions(-)

diff --git a/drivers/pci/host/pci-dra7xx.c b/drivers/pci/host/pci-dra7xx.c
index 18ae7ff..1268c69 100644
--- a/drivers/pci/host/pci-dra7xx.c
+++ b/drivers/pci/host/pci-dra7xx.c
@@ -141,15 +141,15 @@ static void dra7xx_pcie_host_init(struct pcie_port *pp)
 {
 	dw_pcie_setup_rc(pp);
 
-	if (pp->io_mod_base)
-		pp->io_mod_base &= CPU_TO_BUS_ADDR;
+	if (pp->io_base)
+		pp->io_base &= CPU_TO_BUS_ADDR;
 
-	if (pp->mem_mod_base)
-		pp->mem_mod_base &= CPU_TO_BUS_ADDR;
+	if (pp->mem_base)
+		pp->mem_base &= CPU_TO_BUS_ADDR;
 
-	if (pp->cfg0_mod_base) {
-		pp->cfg0_mod_base &= CPU_TO_BUS_ADDR;
-		pp->cfg1_mod_base &= CPU_TO_BUS_ADDR;
+	if (pp->cfg0_base) {
+		pp->cfg0_base &= CPU_TO_BUS_ADDR;
+		pp->cfg1_base &= CPU_TO_BUS_ADDR;
 	}
 
 	dra7xx_pcie_establish_link(pp);
@@ -288,6 +288,7 @@ static int __init dra7xx_add_pcie_port(struct dra7xx_pcie *dra7xx,
 
 	pp = &dra7xx->pp;
 	pp->dev = dev;
+	pp->root_bus_nr = 0;
 	pp->ops = &dra7xx_pcie_host_ops;
 
 	pp->irq = platform_get_irq(pdev, 1);
diff --git a/drivers/pci/host/pci-exynos.c b/drivers/pci/host/pci-exynos.c
index f9f468d..9771bb0 100644
--- a/drivers/pci/host/pci-exynos.c
+++ b/drivers/pci/host/pci-exynos.c
@@ -530,7 +530,7 @@ static int __init exynos_add_pcie_port(struct pcie_port *pp,
 		}
 	}
 
-	pp->root_bus_nr = -1;
+	pp->root_bus_nr = 0;
 	pp->ops = &exynos_pcie_host_ops;
 
 	ret = dw_pcie_host_init(pp);
diff --git a/drivers/pci/host/pci-imx6.c b/drivers/pci/host/pci-imx6.c
index 233a196..bec256c 100644
--- a/drivers/pci/host/pci-imx6.c
+++ b/drivers/pci/host/pci-imx6.c
@@ -551,7 +551,7 @@ static int __init imx6_add_pcie_port(struct pcie_port *pp,
 		}
 	}
 
-	pp->root_bus_nr = -1;
+	pp->root_bus_nr = 0;
 	pp->ops = &imx6_pcie_host_ops;
 
 	ret = dw_pcie_host_init(pp);
diff --git a/drivers/pci/host/pci-keystone-dw.c b/drivers/pci/host/pci-keystone-dw.c
index f34892e..b1e4135 100644
--- a/drivers/pci/host/pci-keystone-dw.c
+++ b/drivers/pci/host/pci-keystone-dw.c
@@ -327,7 +327,7 @@ static void ks_dw_pcie_clear_dbi_mode(void __iomem *reg_virt)
 void ks_dw_pcie_setup_rc_app_regs(struct keystone_pcie *ks_pcie)
 {
 	struct pcie_port *pp = &ks_pcie->pp;
-	u32 start = pp->mem.start, end = pp->mem.end;
+	u32 start = pp->mem->start, end = pp->mem->end;
 	int i, tr_size;
 
 	/* Disable BARs for inbound access */
diff --git a/drivers/pci/host/pci-keystone.c b/drivers/pci/host/pci-keystone.c
index 734da58..8113832 100644
--- a/drivers/pci/host/pci-keystone.c
+++ b/drivers/pci/host/pci-keystone.c
@@ -309,7 +309,7 @@ static int __init ks_add_pcie_port(struct keystone_pcie *ks_pcie,
 			return ret;
 	}
 
-	pp->root_bus_nr = -1;
+	pp->root_bus_nr = 0;
 	pp->ops = &keystone_pcie_host_ops;
 	ret = ks_dw_pcie_host_init(ks_pcie, ks_pcie->msi_intc_np);
 	if (ret) {
diff --git a/drivers/pci/host/pci-layerscape.c b/drivers/pci/host/pci-layerscape.c
index b2328ea1..79ff08c 100644
--- a/drivers/pci/host/pci-layerscape.c
+++ b/drivers/pci/host/pci-layerscape.c
@@ -106,7 +106,7 @@ static int ls_add_pcie_port(struct ls_pcie *pcie)
 	pp = &pcie->pp;
 	pp->dev = pcie->dev;
 	pp->dbi_base = pcie->dbi;
-	pp->root_bus_nr = -1;
+	pp->root_bus_nr = 0;
 	pp->ops = &ls_pcie_host_ops;
 
 	ret = dw_pcie_host_init(pp);
diff --git a/drivers/pci/host/pcie-designware.c b/drivers/pci/host/pcie-designware.c
index c5d407c..e71a88e 100644
--- a/drivers/pci/host/pcie-designware.c
+++ b/drivers/pci/host/pcie-designware.c
@@ -11,6 +11,7 @@
  * published by the Free Software Foundation.
  */
 
+#include <linux/hardirq.h>
 #include <linux/irq.h>
 #include <linux/irqdomain.h>
 #include <linux/kernel.h>
@@ -69,16 +70,7 @@
 #define PCIE_ATU_FUNC(x)		(((x) & 0x7) << 16)
 #define PCIE_ATU_UPPER_TARGET		0x91C
 
-static struct hw_pci dw_pci;
-
-static unsigned long global_io_offset;
-
-static inline struct pcie_port *sys_to_pcie(struct pci_sys_data *sys)
-{
-	BUG_ON(!sys->private_data);
-
-	return sys->private_data;
-}
+static struct pci_ops dw_pcie_ops;
 
 int dw_pcie_cfg_read(void __iomem *addr, int where, int size, u32 *val)
 {
@@ -255,7 +247,7 @@ static void dw_pcie_msi_set_irq(struct pcie_port *pp, int irq)
 static int assign_irq(int no_irqs, struct msi_desc *desc, int *pos)
 {
 	int irq, pos0, i;
-	struct pcie_port *pp = sys_to_pcie(desc->dev->bus->sysdata);
+	struct pcie_port *pp = desc->dev->bus->sysdata;
 
 	pos0 = bitmap_find_free_region(pp->msi_irq_in_use, MAX_MSI_IRQS,
 				       order_base_2(no_irqs));
@@ -298,7 +290,7 @@ static int dw_msi_setup_irq(struct msi_controller *chip, struct pci_dev *pdev,
 {
 	int irq, pos;
 	struct msi_msg msg;
-	struct pcie_port *pp = sys_to_pcie(pdev->bus->sysdata);
+	struct pcie_port *pp = pdev->bus->sysdata;
 
 	if (desc->msi_attrib.is_msix)
 		return -EINVAL;
@@ -327,7 +319,7 @@ static void dw_msi_teardown_irq(struct msi_controller *chip, unsigned int irq)
 {
 	struct irq_data *data = irq_get_irq_data(irq);
 	struct msi_desc *msi = irq_data_get_msi(data);
-	struct pcie_port *pp = sys_to_pcie(msi->dev->bus->sysdata);
+	struct pcie_port *pp = msi->dev->bus->sysdata;
 
 	clear_irq_range(pp, irq, 1, data->hwirq);
 }
@@ -363,14 +355,12 @@ int dw_pcie_host_init(struct pcie_port *pp)
 {
 	struct device_node *np = pp->dev->of_node;
 	struct platform_device *pdev = to_platform_device(pp->dev);
-	struct of_pci_range range;
-	struct of_pci_range_parser parser;
+	struct pci_bus *bus;
 	struct resource *cfg_res;
-	u32 val, ns;
-	const __be32 *addrp;
-	int i, index, ret;
-
-	ns = of_n_size_cells(np);
+	LIST_HEAD(res);
+	u32 val;
+	int i, ret;
+	struct resource_entry *win;
 
 	cfg_res = platform_get_resource_byname(pdev, IORESOURCE_MEM, "config");
 	if (cfg_res) {
@@ -378,85 +368,60 @@ int dw_pcie_host_init(struct pcie_port *pp)
 		pp->cfg1_size = resource_size(cfg_res)/2;
 		pp->cfg0_base = cfg_res->start;
 		pp->cfg1_base = cfg_res->start + pp->cfg0_size;
-
-		/* Find the untranslated configuration space address */
-		index = of_property_match_string(np, "reg-names", "config");
-		addrp = of_get_address(np, index, NULL, NULL);
-		pp->cfg0_mod_base = of_read_number(addrp, ns);
-		pp->cfg1_mod_base = pp->cfg0_mod_base + pp->cfg0_size;
 	} else {
 		dev_err(pp->dev, "missing *config* reg space\n");
 	}
 
-	if (of_pci_range_parser_init(&parser, np)) {
-		dev_err(pp->dev, "missing ranges property\n");
-		return -EINVAL;
-	}
+	ret = of_pci_get_host_bridge_resources(np, 0, 0xff, &res, &pp->io_base);
+	if (ret)
+		return ret;
 
 	/* Get the I/O and memory ranges from DT */
-	for_each_of_pci_range(&parser, &range) {
-		unsigned long restype = range.flags & IORESOURCE_TYPE_BITS;
-
-		if (restype == IORESOURCE_IO) {
-			of_pci_range_to_resource(&range, np, &pp->io);
-			pp->io.name = "I/O";
-			pp->io.start = max_t(resource_size_t,
-					     PCIBIOS_MIN_IO,
-					     range.pci_addr + global_io_offset);
-			pp->io.end = min_t(resource_size_t,
-					   IO_SPACE_LIMIT,
-					   range.pci_addr + range.size
-					   + global_io_offset - 1);
-			pp->io_size = resource_size(&pp->io);
-			pp->io_bus_addr = range.pci_addr;
-			pp->io_base = range.cpu_addr;
-
-			/* Find the untranslated IO space address */
-			pp->io_mod_base = range.cpu_addr;
-		}
-		if (restype == IORESOURCE_MEM) {
-			of_pci_range_to_resource(&range, np, &pp->mem);
-			pp->mem.name = "MEM";
-			pp->mem_size = resource_size(&pp->mem);
-			pp->mem_bus_addr = range.pci_addr;
-
-			/* Find the untranslated MEM space address */
-			pp->mem_mod_base = range.cpu_addr;
-		}
-		if (restype == 0) {
-			of_pci_range_to_resource(&range, np, &pp->cfg);
-			pp->cfg0_size = resource_size(&pp->cfg)/2;
-			pp->cfg1_size = resource_size(&pp->cfg)/2;
-			pp->cfg0_base = pp->cfg.start;
-			pp->cfg1_base = pp->cfg.start + pp->cfg0_size;
-
-			/* Find the untranslated configuration space address */
-			pp->cfg0_mod_base = range.cpu_addr;
-			pp->cfg1_mod_base = pp->cfg0_mod_base +
-					    pp->cfg0_size;
+	resource_list_for_each_entry(win, &res) {
+		switch (resource_type(win->res)) {
+		case IORESOURCE_IO:
+			pp->io = win->res;
+			pp->io->name = "I/O";
+			pp->io_size = resource_size(pp->io);
+			pp->io_bus_addr = pp->io->start - win->offset;
+			ret = pci_remap_iospace(pp->io, pp->io_base);
+			if (ret) {
+				dev_warn(pp->dev, "error %d: failed to map resource %pR\n",
+					 ret, pp->io);
+				continue;
+			}
+			break;
+		case IORESOURCE_MEM:
+			pp->mem = win->res;
+			pp->mem->name = "MEM";
+			pp->mem_size = resource_size(pp->mem);
+			pp->mem_bus_addr = pp->mem->start - win->offset;
+			break;
+		case 0:
+			pp->cfg = win->res;
+			pp->cfg0_size = resource_size(pp->cfg)/2;
+			pp->cfg1_size = resource_size(pp->cfg)/2;
+			pp->cfg0_base = pp->cfg->start;
+			pp->cfg1_base = pp->cfg->start + pp->cfg0_size;
+			break;
+		case IORESOURCE_BUS:
+			pp->busn = win->res;
+			break;
+		default:
+			continue;
 		}
 	}
 
-	ret = of_pci_parse_bus_range(np, &pp->busn);
-	if (ret < 0) {
-		pp->busn.name = np->name;
-		pp->busn.start = 0;
-		pp->busn.end = 0xff;
-		pp->busn.flags = IORESOURCE_BUS;
-		dev_dbg(pp->dev, "failed to parse bus-range property: %d, using default %pR\n",
-			ret, &pp->busn);
-	}
-
 	if (!pp->dbi_base) {
-		pp->dbi_base = devm_ioremap(pp->dev, pp->cfg.start,
-					resource_size(&pp->cfg));
+		pp->dbi_base = devm_ioremap(pp->dev, pp->cfg->start,
+					resource_size(pp->cfg));
 		if (!pp->dbi_base) {
 			dev_err(pp->dev, "error with ioremap\n");
 			return -ENOMEM;
 		}
 	}
 
-	pp->mem_base = pp->mem.start;
+	pp->mem_base = pp->mem->start;
 
 	if (!pp->va_cfg0_base) {
 		pp->va_cfg0_base = devm_ioremap(pp->dev, pp->cfg0_base,
@@ -505,7 +470,7 @@ int dw_pcie_host_init(struct pcie_port *pp)
 
 	if (!pp->ops->rd_other_conf)
 		dw_pcie_prog_outbound_atu(pp, PCIE_ATU_REGION_INDEX1,
-					  PCIE_ATU_TYPE_MEM, pp->mem_mod_base,
+					  PCIE_ATU_TYPE_MEM, pp->mem_base,
 					  pp->mem_bus_addr, pp->mem_size);
 
 	dw_pcie_wr_own_conf(pp, PCI_BASE_ADDRESS_0, 4, 0);
@@ -517,15 +482,29 @@ int dw_pcie_host_init(struct pcie_port *pp)
 	val |= PORT_LOGIC_SPEED_CHANGE;
 	dw_pcie_wr_own_conf(pp, PCIE_LINK_WIDTH_SPEED_CONTROL, 4, val);
 
-#ifdef CONFIG_PCI_MSI
+	bus = pci_create_root_bus(pp->dev, pp->root_bus_nr, &dw_pcie_ops,
+				  pp, &res);
+	if (!bus)
+		return -ENOMEM;
+
+#ifdef CONFIG_GENERIC_MSI_IRQ_DOMAIN
+	bus->msi = container_of(&pp->irq_domain, struct msi_controller, domain);
+#else
 	dw_pcie_msi_chip.dev = pp->dev;
-	dw_pci.msi_ctrl = &dw_pcie_msi_chip;
+	bus->msi = &dw_pcie_msi_chip;
 #endif
 
-	dw_pci.nr_controllers = 1;
-	dw_pci.private_data = (void **)&pp;
+	pci_scan_child_bus(bus);
+	if (pp->ops->scan_bus)
+		pp->ops->scan_bus(pp);
+
+#ifdef CONFIG_ARM
+	/* support old dtbs that incorrectly describe IRQs */
+	pci_fixup_irqs(pci_common_swizzle, of_irq_parse_and_map_pci);
+#endif
 
-	pci_common_init_dev(pp->dev, &dw_pci);
+	pci_assign_unassigned_bus_resources(bus);
+	pci_bus_add_devices(bus);
 
 	return 0;
 }
@@ -544,12 +523,12 @@ static int dw_pcie_rd_other_conf(struct pcie_port *pp, struct pci_bus *bus,
 
 	if (bus->parent->number == pp->root_bus_nr) {
 		type = PCIE_ATU_TYPE_CFG0;
-		cpu_addr = pp->cfg0_mod_base;
+		cpu_addr = pp->cfg0_base;
 		cfg_size = pp->cfg0_size;
 		va_cfg_base = pp->va_cfg0_base;
 	} else {
 		type = PCIE_ATU_TYPE_CFG1;
-		cpu_addr = pp->cfg1_mod_base;
+		cpu_addr = pp->cfg1_base;
 		cfg_size = pp->cfg1_size;
 		va_cfg_base = pp->va_cfg1_base;
 	}
@@ -559,7 +538,7 @@ static int dw_pcie_rd_other_conf(struct pcie_port *pp, struct pci_bus *bus,
 				  busdev, cfg_size);
 	ret = dw_pcie_cfg_read(va_cfg_base + address, where, size, val);
 	dw_pcie_prog_outbound_atu(pp, PCIE_ATU_REGION_INDEX0,
-				  PCIE_ATU_TYPE_IO, pp->io_mod_base,
+				  PCIE_ATU_TYPE_IO, pp->io_base,
 				  pp->io_bus_addr, pp->io_size);
 
 	return ret;
@@ -579,12 +558,12 @@ static int dw_pcie_wr_other_conf(struct pcie_port *pp, struct pci_bus *bus,
 
 	if (bus->parent->number == pp->root_bus_nr) {
 		type = PCIE_ATU_TYPE_CFG0;
-		cpu_addr = pp->cfg0_mod_base;
+		cpu_addr = pp->cfg0_base;
 		cfg_size = pp->cfg0_size;
 		va_cfg_base = pp->va_cfg0_base;
 	} else {
 		type = PCIE_ATU_TYPE_CFG1;
-		cpu_addr = pp->cfg1_mod_base;
+		cpu_addr = pp->cfg1_base;
 		cfg_size = pp->cfg1_size;
 		va_cfg_base = pp->va_cfg1_base;
 	}
@@ -594,7 +573,7 @@ static int dw_pcie_wr_other_conf(struct pcie_port *pp, struct pci_bus *bus,
 				  busdev, cfg_size);
 	ret = dw_pcie_cfg_write(va_cfg_base + address, where, size, val);
 	dw_pcie_prog_outbound_atu(pp, PCIE_ATU_REGION_INDEX0,
-				  PCIE_ATU_TYPE_IO, pp->io_mod_base,
+				  PCIE_ATU_TYPE_IO, pp->io_base,
 				  pp->io_bus_addr, pp->io_size);
 
 	return ret;
@@ -626,7 +605,7 @@ static int dw_pcie_valid_config(struct pcie_port *pp,
 static int dw_pcie_rd_conf(struct pci_bus *bus, u32 devfn, int where,
 			int size, u32 *val)
 {
-	struct pcie_port *pp = sys_to_pcie(bus->sysdata);
+	struct pcie_port *pp = bus->sysdata;
 	int ret;
 
 	if (dw_pcie_valid_config(pp, bus, PCI_SLOT(devfn)) == 0) {
@@ -650,7 +629,7 @@ static int dw_pcie_rd_conf(struct pci_bus *bus, u32 devfn, int where,
 static int dw_pcie_wr_conf(struct pci_bus *bus, u32 devfn,
 			int where, int size, u32 val)
 {
-	struct pcie_port *pp = sys_to_pcie(bus->sysdata);
+	struct pcie_port *pp = bus->sysdata;
 	int ret;
 
 	if (dw_pcie_valid_config(pp, bus, PCI_SLOT(devfn)) == 0)
@@ -674,62 +653,6 @@ static struct pci_ops dw_pcie_ops = {
 	.write = dw_pcie_wr_conf,
 };
 
-static int dw_pcie_setup(int nr, struct pci_sys_data *sys)
-{
-	struct pcie_port *pp;
-
-	pp = sys_to_pcie(sys);
-
-	if (global_io_offset < SZ_1M && pp->io_size > 0) {
-		sys->io_offset = global_io_offset - pp->io_bus_addr;
-		pci_ioremap_io(global_io_offset, pp->io_base);
-		global_io_offset += SZ_64K;
-		pci_add_resource_offset(&sys->resources, &pp->io,
-					sys->io_offset);
-	}
-
-	sys->mem_offset = pp->mem.start - pp->mem_bus_addr;
-	pci_add_resource_offset(&sys->resources, &pp->mem, sys->mem_offset);
-	pci_add_resource(&sys->resources, &pp->busn);
-
-	return 1;
-}
-
-static struct pci_bus *dw_pcie_scan_bus(int nr, struct pci_sys_data *sys)
-{
-	struct pci_bus *bus;
-	struct pcie_port *pp = sys_to_pcie(sys);
-
-	pp->root_bus_nr = sys->busnr;
-	bus = pci_scan_root_bus(pp->dev, sys->busnr,
-				  &dw_pcie_ops, sys, &sys->resources);
-	if (!bus)
-		return NULL;
-
-	if (bus && pp->ops->scan_bus)
-		pp->ops->scan_bus(pp);
-
-	return bus;
-}
-
-static int dw_pcie_map_irq(const struct pci_dev *dev, u8 slot, u8 pin)
-{
-	struct pcie_port *pp = sys_to_pcie(dev->bus->sysdata);
-	int irq;
-
-	irq = of_irq_parse_and_map_pci(dev, slot, pin);
-	if (!irq)
-		irq = pp->irq;
-
-	return irq;
-}
-
-static struct hw_pci dw_pci = {
-	.setup		= dw_pcie_setup,
-	.scan		= dw_pcie_scan_bus,
-	.map_irq	= dw_pcie_map_irq,
-};
-
 void dw_pcie_setup_rc(struct pcie_port *pp)
 {
 	u32 val;
diff --git a/drivers/pci/host/pcie-designware.h b/drivers/pci/host/pcie-designware.h
index d0bbd27..264c969 100644
--- a/drivers/pci/host/pcie-designware.h
+++ b/drivers/pci/host/pcie-designware.h
@@ -27,25 +27,21 @@ struct pcie_port {
 	u8			root_bus_nr;
 	void __iomem		*dbi_base;
 	u64			cfg0_base;
-	u64			cfg0_mod_base;
 	void __iomem		*va_cfg0_base;
 	u32			cfg0_size;
 	u64			cfg1_base;
-	u64			cfg1_mod_base;
 	void __iomem		*va_cfg1_base;
 	u32			cfg1_size;
-	u64			io_base;
-	u64			io_mod_base;
+	resource_size_t		io_base;
 	phys_addr_t		io_bus_addr;
 	u32			io_size;
 	u64			mem_base;
-	u64			mem_mod_base;
 	phys_addr_t		mem_bus_addr;
 	u32			mem_size;
-	struct resource		cfg;
-	struct resource		io;
-	struct resource		mem;
-	struct resource		busn;
+	struct resource		*cfg;
+	struct resource		*io;
+	struct resource		*mem;
+	struct resource		*busn;
 	int			irq;
 	u32			lanes;
 	struct pcie_host_ops	*ops;
diff --git a/drivers/pci/host/pcie-spear13xx.c b/drivers/pci/host/pcie-spear13xx.c
index c49fbdc..03eb204 100644
--- a/drivers/pci/host/pcie-spear13xx.c
+++ b/drivers/pci/host/pcie-spear13xx.c
@@ -286,7 +286,7 @@ static int spear13xx_add_pcie_port(struct pcie_port *pp,
 		return ret;
 	}
 
-	pp->root_bus_nr = -1;
+	pp->root_bus_nr = 0;
 	pp->ops = &spear13xx_pcie_host_ops;
 
 	ret = dw_pcie_host_init(pp);
-- 
1.9.1



From linux at roeck-us.net  Thu Aug  6 01:05:27 2015
From: linux at roeck-us.net (Guenter Roeck)
Date: Thu, 06 Aug 2015 01:05:27 -0700
Subject: [PATCH v4 1/2] drivers: watchdog: add a driver to support SAMA5D4
 watchdog timer
In-Reply-To: <1438837170-4518-2-git-send-email-wenyou.yang@atmel.com>
References: <1438837170-4518-1-git-send-email-wenyou.yang@atmel.com>
 <1438837170-4518-2-git-send-email-wenyou.yang@atmel.com>
Message-ID: <55C31547.2040207@roeck-us.net>

On 08/05/2015 09:59 PM, Wenyou Yang wrote:
>>From SAMA5D4, the watchdog timer is upgrated with a new feature,
> which is describled as in the datasheet, "WDT_MR can be written
> until a LOCKMR command is issued in WDT_CR".
> That is to say, as long as the bootstrap and u-boot don't issue
> a LOCKMR command, WDT_MR can be written more than once in the driver.
>
> So the SAMA5D4 watchdog driver's implementation is different from
> the at91sam9260 watchdog driver implemented in file at91sam9_wdt.c.
> The user application open the device file to enable the watchdog timer
> hardware, and close to disable it, and set the watchdog timer timeout
> by seting WDV and WDD fields of WDT_MR register, and ping the watchdog
> by issuing WDRSTT command to WDT_CR register with hard-coded key.
>
> Signed-off-by: Wenyou Yang <wenyou.yang at atmel.com>
> ---
[ ... ]
> +
> +/* minimum and maximum watchdog timeout, in seconds */
> +#define	MIN_WDT_TIMEOUT		1
> +#define	MAX_WDT_TIMEOUT		16
> +#define	WDT_DEFAULT_TIMEOUT	MAX_WDT_TIMEOUT
> +
> +#define	WDT_SEC2TICKS(s)	((s) ? (((s) << 8) - 1) : 0)
> +

Why did you replace the spaces after #define with tabs ?
I understand this is done in the at91.h file, but that is bad enough,
it doesn't add any value, and I don't see a reason to do it here.

> +
> +	if ((wdt->config & AT91_WDT_WDFIEN) && irq) {
> +		ret = devm_request_irq(&pdev->dev, irq, sama5d4_wdt_irq_handler,
> +				       0, pdev->name, pdev);

I just realized - this interrupt is registered with flags set to 0,
while in the at91sam driver the flags are "IRQF_SHARED | IRQF_IRQPOLL |
IRQF_NO_SUSPEND". Is this different with the new SOC ?

Thanks,
Guenter



From marc.zyngier at arm.com  Thu Aug  6 01:06:26 2015
From: marc.zyngier at arm.com (Marc Zyngier)
Date: Thu, 06 Aug 2015 09:06:26 +0100
Subject: [PATCH] kvm:arm:Fix error handling in the function vgic_v3_probe
In-Reply-To: <55C242C6.6060200@gmail.com>
References: <1438793303-30228-1-git-send-email-xerofoify@gmail.com>
 <55C240D9.5060900@redhat.com> <55C242C6.6060200@gmail.com>
Message-ID: <55C31582.4000809@arm.com>

On 05/08/15 18:07, nick wrote:
> 
> 
> On 2015-08-05 12:59 PM, Paolo Bonzini wrote:
>>
>>
>> On 05/08/2015 18:48, Nicholas Krause wrote:
>>> This fixes the error handling in the function vgic_v3_probe
>>> for when calling the function kvm_register_device_ops to check
>>> if the call to this function has returned a error code and if
>>> so jump to the label out with goto to cleanup no longer required
>>> resources used by the function vgic_v3_probe before returning the
>>> error code from the call to kvm_register_device_ops to the caller
>>> of the function vgic_v3_probe.
>>>
>>> Signed-off-by: Nicholas Krause <xerofoify at gmail.com>
>>> ---
>>>  virt/kvm/arm/vgic-v3.c | 10 +++++++---
>>>  1 file changed, 7 insertions(+), 3 deletions(-)
>>>
>>> diff --git a/virt/kvm/arm/vgic-v3.c b/virt/kvm/arm/vgic-v3.c
>>> index dff0602..5102aa2 100644
>>> --- a/virt/kvm/arm/vgic-v3.c
>>> +++ b/virt/kvm/arm/vgic-v3.c
>>> @@ -264,12 +264,16 @@ int vgic_v3_probe(struct device_node *vgic_node,
>>>  	} else {
>>>  		vgic->vcpu_base = vcpu_res.start;
>>>  		vgic->can_emulate_gicv2 = true;
>>> -		kvm_register_device_ops(&kvm_arm_vgic_v2_ops,
>>> -					KVM_DEV_TYPE_ARM_VGIC_V2);
>>> +		ret = kvm_register_device_ops(&kvm_arm_vgic_v2_ops,
>>> +					      KVM_DEV_TYPE_ARM_VGIC_V2);
>>> +		if (ret)
>>> +			goto out;
>>>  	}
>>>  	if (vgic->vcpu_base == 0)
>>>  		kvm_info("disabling GICv2 emulation\n");
>>> -	kvm_register_device_ops(&kvm_arm_vgic_v3_ops, KVM_DEV_TYPE_ARM_VGIC_V3);
>>> +	ret = kvm_register_device_ops(&kvm_arm_vgic_v3_ops, KVM_DEV_TYPE_ARM_VGIC_V3);
>>> +	if (ret)
>>> +		goto out;
>>>  
>>>  	vgic->vctrl_base = NULL;
>>>  	vgic->type = VGIC_V3;
>>>
>>
>> This really should never happen.  Perhaps kvm_register_device_ops should
>> instead return void, and WARN() when it currently returns an error.
>>
>> Paolo
>>
> Paolo,
> I would like to do what you want but after tracing the callers of this function I found
> this structure and wasn't sure if it can handle void function pointers.
> static const struct of_device_id vgic_ids[] = {
>         { .compatible = "arm,cortex-a15-gic",   .data = vgic_v2_probe, },
>         { .compatible = "arm,cortex-a7-gic",    .data = vgic_v2_probe, },
>         { .compatible = "arm,gic-400",          .data = vgic_v2_probe, },
>         { .compatible = "arm,gic-v3",           .data = vgic_v3_probe, },
>         {},
> };
> If this structure of function pointers can handle function pointers with a return type of 
> void I will be glad to do what you request otherwise this would require a major rewrite
> of kvm arm subsystem for a very simple bug fix.

Just like Paolo said, the error you report should never happen, and
would be caught by a WARN_ON() the first time anyone boots the kernel.
Also, failing to register the device ops results in not being able to
instantiate a VGIC. No harm done. I really don't understand why you want
to rewrite the probe functions.

There is plenty of things that could use a major rewrite in KVM/ARM, but
this is just not one of them.

Thanks,

	M.
-- 
Jazz is not dead. It just smells funny...


From l.stach at pengutronix.de  Thu Aug  6 01:11:30 2015
From: l.stach at pengutronix.de (Lucas Stach)
Date: Thu, 06 Aug 2015 10:11:30 +0200
Subject: [PATCH] ARM: imx6: correct i.MX6 PCIe interrupt routing
In-Reply-To: <20150806012832.GP12927@tiger>
References: <1438793677-19153-1-git-send-email-l.stach@pengutronix.de>
 <20150806012832.GP12927@tiger>
Message-ID: <1438848690.24317.3.camel@pengutronix.de>

Am Donnerstag, den 06.08.2015, 09:28 +0800 schrieb Shawn Guo:
> On Wed, Aug 05, 2015 at 06:54:37PM +0200, Lucas Stach wrote:
> > The PCIe interrupts are also routed through the GPC. This has been
> > missed from the conversion to stacked IRQ domains as the PCIe
> > controller uses an explicit interrupt map and thus doesn't inherit
> > the SoC global interrupt parent.
> > 
> > Signed-off-by: Lucas Stach <l.stach at pengutronix.de>
> 
> So this is a fix and need copy stable?
> 
I'm a bit on the fence with this. It only fixes PCIe wake-up and I'm not
aware of anyone using this functionality and haven't seen any bug
reports yet.

On the other hand it is a clear fix and has practically zero chances for
regressions, so yes please add stable 4.0+ to this.

Thanks,
Lucas

> Shawn
> 
> > ---
> > This commit does not change the i.MX6SX PCIe node, as PCIe isn't
> > functional in mainline on this SoC and the DT node needs a major
> > rewrite to account for the specifics of this SoC anyway.
> > ---
> >  arch/arm/boot/dts/imx6qdl.dtsi | 8 ++++----
> >  1 file changed, 4 insertions(+), 4 deletions(-)
> > 
> > diff --git a/arch/arm/boot/dts/imx6qdl.dtsi b/arch/arm/boot/dts/imx6qdl.dtsi
> > index e6d13592080d..b57033e8c633 100644
> > --- a/arch/arm/boot/dts/imx6qdl.dtsi
> > +++ b/arch/arm/boot/dts/imx6qdl.dtsi
> > @@ -181,10 +181,10 @@
> >  			interrupt-names = "msi";
> >  			#interrupt-cells = <1>;
> >  			interrupt-map-mask = <0 0 0 0x7>;
> > -			interrupt-map = <0 0 0 1 &intc GIC_SPI 123 IRQ_TYPE_LEVEL_HIGH>,
> > -			                <0 0 0 2 &intc GIC_SPI 122 IRQ_TYPE_LEVEL_HIGH>,
> > -			                <0 0 0 3 &intc GIC_SPI 121 IRQ_TYPE_LEVEL_HIGH>,
> > -			                <0 0 0 4 &intc GIC_SPI 120 IRQ_TYPE_LEVEL_HIGH>;
> > +			interrupt-map = <0 0 0 1 &gpc GIC_SPI 123 IRQ_TYPE_LEVEL_HIGH>,
> > +			                <0 0 0 2 &gpc GIC_SPI 122 IRQ_TYPE_LEVEL_HIGH>,
> > +			                <0 0 0 3 &gpc GIC_SPI 121 IRQ_TYPE_LEVEL_HIGH>,
> > +			                <0 0 0 4 &gpc GIC_SPI 120 IRQ_TYPE_LEVEL_HIGH>;
> >  			clocks = <&clks IMX6QDL_CLK_PCIE_AXI>,
> >  				 <&clks IMX6QDL_CLK_LVDS1_GATE>,
> >  				 <&clks IMX6QDL_CLK_PCIE_REF_125M>;
> > -- 
> > 2.4.6
> > 
> > 
> > _______________________________________________
> > linux-arm-kernel mailing list
> > linux-arm-kernel at lists.infradead.org
> > http://lists.infradead.org/mailman/listinfo/linux-arm-kernel
> > 
> 
> _______________________________________________
> linux-arm-kernel mailing list
> linux-arm-kernel at lists.infradead.org
> http://lists.infradead.org/mailman/listinfo/linux-arm-kernel

-- 
Pengutronix e.K.             | Lucas Stach                 |
Industrial Linux Solutions   | http://www.pengutronix.de/  |



From Wenyou.Yang at atmel.com  Thu Aug  6 01:18:52 2015
From: Wenyou.Yang at atmel.com (Yang, Wenyou)
Date: Thu, 6 Aug 2015 08:18:52 +0000
Subject: [PATCH v4 1/2] drivers: watchdog: add a driver to support
 SAMA5D4 watchdog timer
In-Reply-To: <55C31547.2040207@roeck-us.net>
References: <1438837170-4518-1-git-send-email-wenyou.yang@atmel.com>
 <1438837170-4518-2-git-send-email-wenyou.yang@atmel.com>
 <55C31547.2040207@roeck-us.net>
Message-ID: <B256D81BAE5131468A838E5D7A243641C9F875EB@penmbx01>

Hi Guenter,

Thank you for your correct.

> -----Original Message-----
> From: Guenter Roeck [mailto:linux at roeck-us.net]
> Sent: 2015?8?6? 16:05
> To: Yang, Wenyou; wim at iguana.be; robh+dt at kernel.org; pawel.moll at arm.com;
> mark.rutland at arm.com; ijc+devicetree at hellion.org.uk; galak at codeaurora.org
> Cc: sylvain.rochet at finsecur.com; Ferre, Nicolas; boris.brezillon at free-
> electrons.com; devicetree at vger.kernel.org; linux-kernel at vger.kernel.org; linux-
> watchdog at vger.kernel.org; linux-arm-kernel at lists.infradead.org
> Subject: Re: [PATCH v4 1/2] drivers: watchdog: add a driver to support SAMA5D4
> watchdog timer
> 
> On 08/05/2015 09:59 PM, Wenyou Yang wrote:
> >>From SAMA5D4, the watchdog timer is upgrated with a new feature,
> > which is describled as in the datasheet, "WDT_MR can be written until
> > a LOCKMR command is issued in WDT_CR".
> > That is to say, as long as the bootstrap and u-boot don't issue a
> > LOCKMR command, WDT_MR can be written more than once in the driver.
> >
> > So the SAMA5D4 watchdog driver's implementation is different from the
> > at91sam9260 watchdog driver implemented in file at91sam9_wdt.c.
> > The user application open the device file to enable the watchdog timer
> > hardware, and close to disable it, and set the watchdog timer timeout
> > by seting WDV and WDD fields of WDT_MR register, and ping the watchdog
> > by issuing WDRSTT command to WDT_CR register with hard-coded key.
> >
> > Signed-off-by: Wenyou Yang <wenyou.yang at atmel.com>
> > ---
> [ ... ]
> > +
> > +/* minimum and maximum watchdog timeout, in seconds */
> > +#define	MIN_WDT_TIMEOUT		1
> > +#define	MAX_WDT_TIMEOUT		16
> > +#define	WDT_DEFAULT_TIMEOUT	MAX_WDT_TIMEOUT
> > +
> > +#define	WDT_SEC2TICKS(s)	((s) ? (((s) << 8) - 1) : 0)
> > +
> 
> Why did you replace the spaces after #define with tabs ?
> I understand this is done in the at91.h file, but that is bad enough, it doesn't add
> any value, and I don't see a reason to do it here.
Accepted, Using spaces, not tabs.

> 
> > +
> > +	if ((wdt->config & AT91_WDT_WDFIEN) && irq) {
> > +		ret = devm_request_irq(&pdev->dev, irq,
> sama5d4_wdt_irq_handler,
> > +				       0, pdev->name, pdev);
> 
> I just realized - this interrupt is registered with flags set to 0, while in the at91sam
> driver the flags are "IRQF_SHARED | IRQF_IRQPOLL | IRQF_NO_SUSPEND". Is
> this different with the new SOC ?
No, it is same. It is my carelessness.

> 
> Thanks,
> Guenter


Best Regards,
Wenyou Yang


From wangzhou1 at hisilicon.com  Thu Aug  6 01:09:15 2015
From: wangzhou1 at hisilicon.com (Zhou Wang)
Date: Thu, 6 Aug 2015 16:09:15 +0800
Subject: [PATCH v6 2/6] ARM/PCI: remove align_resource in pci_sys_data
In-Reply-To: <1438848559-232109-1-git-send-email-wangzhou1@hisilicon.com>
References: <1438848559-232109-1-git-send-email-wangzhou1@hisilicon.com>
Message-ID: <1438848559-232109-3-git-send-email-wangzhou1@hisilicon.com>

From: gabriele paoloni <gabriele.paoloni at huawei.com>

This patch is needed in order to unify the PCIe designware framework for ARM and
ARM64 architectures. In the PCIe designware unification process we are calling
pci_create_root_bus() passing a "sysdata" parameter that is the same for both
ARM and ARM64 and is of type "struct pcie_port*". In the ARM case this will
cause a problem with the function pcibios_align_resource(); in fact this will
cast "dev->sysdata" to "struct pci_sys_data*", whereas designware had passed a
"struct pcie_port*" pointer.

This patch solves the issue by removing "align_resource" from "pci_sys_data"
struct and defining a static global function pointer in "bios32.c"

Signed-off-by: Gabriele Paoloni <gabriele.paoloni at huawei.com>
---
 arch/arm/include/asm/mach/pci.h |  5 -----
 arch/arm/kernel/bios32.c        | 12 ++++++++----
 2 files changed, 8 insertions(+), 9 deletions(-)

diff --git a/arch/arm/include/asm/mach/pci.h b/arch/arm/include/asm/mach/pci.h
index 28b9bb3..8a4e4de 100644
--- a/arch/arm/include/asm/mach/pci.h
+++ b/arch/arm/include/asm/mach/pci.h
@@ -58,11 +58,6 @@ struct pci_sys_data {
 					/* IRQ mapping				*/
 	int		(*map_irq)(const struct pci_dev *, u8, u8);
 					/* Resource alignement requirements	*/
-	resource_size_t (*align_resource)(struct pci_dev *dev,
-					  const struct resource *res,
-					  resource_size_t start,
-					  resource_size_t size,
-					  resource_size_t align);
 	void		*private_data;	/* platform controller private data	*/
 };
 
diff --git a/arch/arm/kernel/bios32.c b/arch/arm/kernel/bios32.c
index fcbbbb1..4cdc64d 100644
--- a/arch/arm/kernel/bios32.c
+++ b/arch/arm/kernel/bios32.c
@@ -17,6 +17,11 @@
 #include <asm/mach/pci.h>
 
 static int debug_pci;
+static resource_size_t (*align_resource)(struct pci_dev *dev,
+		  const struct resource *res,
+		  resource_size_t start,
+		  resource_size_t size,
+		  resource_size_t align) = NULL;
 
 #ifdef CONFIG_PCI_MSI
 struct msi_controller *pcibios_msi_controller(struct pci_dev *dev)
@@ -468,7 +473,7 @@ static void pcibios_init_hw(struct device *parent, struct hw_pci *hw,
 		sys->busnr   = busnr;
 		sys->swizzle = hw->swizzle;
 		sys->map_irq = hw->map_irq;
-		sys->align_resource = hw->align_resource;
+		align_resource = hw->align_resource;
 		INIT_LIST_HEAD(&sys->resources);
 
 		if (hw->private_data)
@@ -589,7 +594,6 @@ resource_size_t pcibios_align_resource(void *data, const struct resource *res,
 				resource_size_t size, resource_size_t align)
 {
 	struct pci_dev *dev = data;
-	struct pci_sys_data *sys = dev->sysdata;
 	resource_size_t start = res->start;
 
 	if (res->flags & IORESOURCE_IO && start & 0x300)
@@ -597,8 +601,8 @@ resource_size_t pcibios_align_resource(void *data, const struct resource *res,
 
 	start = (start + align - 1) & ~(align - 1);
 
-	if (sys->align_resource)
-		return sys->align_resource(dev, res, start, size, align);
+	if (align_resource)
+		return align_resource(dev, res, start, size, align);
 
 	return start;
 }
-- 
1.9.1



From oliver+list at schinagl.nl  Thu Aug  6 01:22:59 2015
From: oliver+list at schinagl.nl (Olliver Schinagl)
Date: Thu, 06 Aug 2015 10:22:59 +0200
Subject: [linux-sunxi] [PATCH] musb: sunxi: Ignore VBus errors in host-only
 mode
In-Reply-To: <1438723553-4136-1-git-send-email-hdegoede@redhat.com>
References: <1438723553-4136-1-git-send-email-hdegoede@redhat.com>
Message-ID: <55C31963.2010701@schinagl.nl>

Hey Hans,

I've tried getting your musb stuff working on a cubietruck, but i don't 
seem to see this patch on your linux-sunxi/sunxi-wip branch on github? 
Is your github branch fully functional at the moment?

What I have done so far, is build the kernel using sunxi_defconfig and 
enabled USB_MUSB_SUNXI with its dependancies (musb isn't enabled there 
by default): USB_SUPPORT [=y] && USB_MUSB_HDRC [=y] && ARCH_SUNXI [=y] 
&& NOP_USB_XCEIV [=y] && PHY_SUN4I_USB [=y] && EXTCON [=y] && 
GENERIC_PHY [=y]  Selects: SUNXI_SRAM [=y]

I changed the dts from dr_mode='otg' to dr_mode='host', a) we only need 
host mode anyway (the id pin isn't properly connected) and b) I got an 
error about an known dr_mode before and this was the quick and easy way.

Dmesg produces the following related to musb.

[    1.691062] usb_phy_generic.0.auto supply vcc not found, using dummy 
regulator
[    1.691445] musb-hdrc: ConfigData=0xde (UTMI-8, dyn FIFOs, bulk 
combine, bulk split, HB-ISO Rx, HB-ISO Tx, SoftConn)
[    1.691453] musb-hdrc: MHDRC RTL version 0.0
[    1.691467] musb-hdrc: 11/11 max ep, 5184/8192 memory
[    1.691543] musb-hdrc musb-hdrc.1.auto: MUSB HDRC host driver
[    1.691553] musb-hdrc musb-hdrc.1.auto: new USB bus registered, 
assigned bus number 5
[    1.692470] hub 5-0:1.0: USB hub found
[    1.692529] hub 5-0:1.0: 1 port detected
[    1.699956] sunxi-rtc 1c20d00.rtc: setting system clock to 2015-08-06 
07:59:08 UTC (1438847948)
[    1.704733] usb0-vbus: disabling
[    1.765695] ldo4: disabling
[    1.808351] ldo3: disabling
[    1.848769] vcc5v0: disabling
[    1.848774] vcc3v0: disabling

The usb_phy_generic missing shouldn't be too bad? But the usb0-vbus 
being disabled obviously might be related to the musb port not working? 
What causes this though? I went through all the musb patch series mails 
but don't recall seing anything special being needed.

If there are fixes missing in the sunxi-next stuff that could explain 
this, could you be so kind and push your latest work so I can try it? 
Thanks Hans!

Olliver

On 04-08-15 23:25, Hans de Goede wrote:
> For some unclear reason sometimes we get VBus errors in host-only mode,
> even though we do not have any vbus-detection then. Ignore these.
>
> Signed-off-by: Hans de Goede <hdegoede at redhat.com>
> ---
>   drivers/usb/musb/sunxi.c | 4 ++++
>   1 file changed, 4 insertions(+)
>
> diff --git a/drivers/usb/musb/sunxi.c b/drivers/usb/musb/sunxi.c
> index f9f6304..34ce5df 100644
> --- a/drivers/usb/musb/sunxi.c
> +++ b/drivers/usb/musb/sunxi.c
> @@ -194,6 +194,10 @@ static irqreturn_t sunxi_musb_interrupt(int irq, void *__hci)
>   		musb_writeb(musb->mregs, MUSB_FADDR, 0);
>   	}
>   
> +	/*  Ignore Vbus errors when in host only mode */
> +	if (musb->port_mode == MUSB_PORT_MODE_HOST)
> +		musb->int_usb &= ~MUSB_INTR_VBUSERROR;
> +
>   	musb->int_tx = readw(musb->mregs + SUNXI_MUSB_INTRTX);
>   	if (musb->int_tx)
>   		writew(musb->int_tx, musb->mregs + SUNXI_MUSB_INTRTX);



From jamesjj.liao at mediatek.com  Thu Aug  6 01:23:51 2015
From: jamesjj.liao at mediatek.com (James Liao)
Date: Thu, 6 Aug 2015 16:23:51 +0800
Subject: [PATCH v6 7/9] clk: mediatek: Add subsystem clocks of MT8173
In-Reply-To: <20150805064605.GZ18700@pengutronix.de>
References: <1438676218-11310-1-git-send-email-jamesjj.liao@mediatek.com>
 <1438676218-11310-8-git-send-email-jamesjj.liao@mediatek.com>
 <20150805064605.GZ18700@pengutronix.de>
Message-ID: <1438849431.27884.9.camel@mtksdaap41>

Hi Sascha,

On Wed, 2015-08-05 at 08:46 +0200, Sascha Hauer wrote:
> On Tue, Aug 04, 2015 at 04:16:56PM +0800, James Liao wrote:
> >  static const struct mtk_fixed_clk fixed_clks[] __initconst = {
> >  	FIXED_CLK(CLK_TOP_CLKPH_MCK_O, "clkph_mck_o", "clk26m", 400 * MHZ),
> >  	FIXED_CLK(CLK_TOP_USB_SYSPLL_125M, "usb_syspll_125m", "clk26m", 125 * MHZ),
> > +	FIXED_CLK(CLK_TOP_DSI0_DIG, "dsi0_dig", "clk26m", 130 * MHZ),
> > +	FIXED_CLK(CLK_TOP_DSI1_DIG, "dsi1_dig", "clk26m", 130 * MHZ),
> > +	FIXED_CLK(CLK_TOP_LVDS_PXL, "lvds_pxl", "lvdspll", 148.5 * MHZ),
> > +	FIXED_CLK(CLK_TOP_LVDS_CTS, "lvds_cts", "lvdspll", 51.975 * MHZ),
> 
> I would expect 51975 * KHZ here to avoid fractional numbers. Probably
> gcc calculates that during compile time so this will work as expected,
> still I'm not sure this is good style to use fractional numbers here.

As I know all constants will be calculated in compile time, so there
should be no difference between 51.975 * MHZ and 51975 * KHz. 

> Anyway, on my system lvdspll is running at 150MHz. Are you sure there is
> a clock derived from this running at 148.5MHz? Is it really correct to
> use a fixed clock here or should it rather be lvdspll directly?

Here is the clock hierarchy between lvdspll and lvds_pxl:

            --------       AD_VPLL_DPIX_CK  --------   lvds_pxl  -----
           |        |--------------------->|        |---------->|
           |        |                      | cksys  |           |
LVDSPLL -->| LVDSTX |                      | buffer |           | MMSYS
           |        | AD_LVDSTX_CLKDIG_CTS | test   |  lvds_cts |
           |        |--------------------->|        |---------->|
            --------                        --------             -----

Some clocks and blocks are not modeled into CCF. But we prefer to enable
lvdspll before enabling lvds_pxl. So I modeled lvds_pxl (and lvds_cts)
as a fixed-rate clock with a source from lvdspll.

The frequency of these fixed-rate clocks (such as 148.5 MHz) are typical
rate. In fact, we don't care about the actual rate of these clocks. We
just care about the enable / disable sequence of them.


Best regards,

James




From olof at lixom.net  Thu Aug  6 00:28:27 2015
From: olof at lixom.net (Olof Johansson)
Date: Thu, 6 Aug 2015 09:28:27 +0200
Subject: [PATCH 0/9] LPC18xx DTS changes for 4.3 part2
In-Reply-To: <1438295067-24407-1-git-send-email-manabian@gmail.com>
References: <1438295067-24407-1-git-send-email-manabian@gmail.com>
Message-ID: <20150806072827.GA22787@localhost>

On Fri, Jul 31, 2015 at 12:24:18AM +0200, Joachim Eastwood wrote:
> Here is some more LPC18xx dts changes for v4.3. This is the dts
> changes for the drivers that will go in for v4.3. Note that the
> USB phy driver is not in next yet, but is queued on Kishon's phy
> next repo.
> 
> Changes include:
> 
>  - Add USB OTG phy, PL111 LCD controller and PL172 memory
>    controller nodes to lpc18xx.dtsi
> 
>  - Enable USB0 on EA4357 Dev Kit
> 
>  - Add static memory devices on EA4357 Dev Kit
> 
>  - Enable UART0 pinmux and Ethernet on Hitex Eval Board
>    from Ariel D'Alessandro
> 
>  - Add static memory devices on Hitex Eval Board
> 
> Changes are also available in the git repository at:
> 
>   https://github.com/manabian/linux-lpc.git tags/lpc18xx_dts_for_4.3-part2

Thanks, I missed the pull request until I had already applied them directly.

Feel free to use the standard git request-pull format in the future. :)


-Olof



From olof at lixom.net  Thu Aug  6 00:32:17 2015
From: olof at lixom.net (Olof Johansson)
Date: Thu, 6 Aug 2015 09:32:17 +0200
Subject: [GIT PULL] Xilinx ZynqMP DT changes for v4.3
In-Reply-To: <55C225A7.9050704@monstr.eu>
References: <55BB369F.4080100@monstr.eu> <20150805090016.GI6390@localhost>
 <55C225A7.9050704@monstr.eu>
Message-ID: <20150806073217.GB22787@localhost>

On Wed, Aug 05, 2015 at 05:03:03PM +0200, Michal Simek wrote:
> Hi Olof,
> 
> On 08/05/2015 11:00 AM, Olof Johansson wrote:
> > On Fri, Jul 31, 2015 at 10:49:35AM +0200, Michal Simek wrote:
> >> Hi,
> >>
> >> please pull these ARM64 DT patches to your tree.
> >>
> >> Thanks,
> >> Michal
> >>
> >>
> >> The following changes since commit d770e558e21961ad6cfdf0ff7df0eb5d7d4f0754:
> >>
> >>   Linux 4.2-rc1 (2015-07-05 11:01:52 -0700)
> >>
> >> are available in the git repository at:
> >>
> >>   https://github.com/Xilinx/linux-xlnx.git tags/zynqmp-dt-for-4.3
> >>
> >> for you to fetch changes up to f49310dc62f68ae9f905f9a1e42224fa23867f47:
> >>
> >>   ARM64: zynqmp: Move SPI nodes to the right location (2015-07-31
> >> 10:46:34 +0200)
> >>
> >> ----------------------------------------------------------------
> >> arm: Xilinx ZynqMP dt patches for v4.3
> >>
> >> - Add SATA, GPIO, CAN, SMMU, USB, SPI, I2C, watchdog and sdhci for zynqmp
> >> - Sort nodes in dtsi
> > 
> > You seem to sort these alphabetically. We normally encourage sorting by unit
> > address instead. Was there some reason you chose alphabetical?
> 
> Normally if you look for something you can't remember addresses but you
> remember names that's why this sorting is more natural at least for me.

Main purpose of sorting tends to be to avoid having add-add conflicts by new
entries going into different parts of the file. If different files are sorted
differently (but see below), it's hard for contributors to figure out where
they should add stuff.

> I have checked APM/EXYNOS/Juno/SPR for example (and probably others) and
> there is no order at all.

Yeah, it's in pretty bad shape. There have been some efforts to fix sorting in
the past, but it tends to degrade over time. I suspect part of this is due to
some patches lacking enough context such that the tools apply them to the wrong
part of the file. In other cases it's just neglect or forgetfulness.

> If this is any strict requirement to sort nodes by addresses I am happy
> to send patch on the top of this series to fix it. That's why please let
> me know.

It's not a strict requirement, it's just that when others have made efforts to
sort they have done so by unitid instead.

I'll merge this branch, it's probably not worth it to follow up with another
reshuffle. As you say, most other files are in even worse shape so it's
a losing battle.

> There are other questions what to do with clocks for example - having
> them on the bus like it is done for us and Cavium/Exynos/Seattle or
> having separate node on the bus like APM.
> Using soc node is another question.
> 
> I know that Grant wanted to update any guide which should cover these
> stuff but I am not aware if we have any doc which describe it.

Sounds like a suitable topic for one of many DT sessions at conferences around
the world these days, if you're attending any. It's usually easier to corner
people at those and hash things out.


-Olof


From olof at lixom.net  Thu Aug  6 01:10:00 2015
From: olof at lixom.net (Olof Johansson)
Date: Thu, 6 Aug 2015 10:10:00 +0200
Subject: [GIT PULL v2] Renesas ARM Based SoC Marzen Board Removal for v4.3
In-Reply-To: <cover.1438581659.git.horms+renesas@verge.net.au>
References: <cover.1438581659.git.horms+renesas@verge.net.au>
Message-ID: <20150806081000.GA16520@localhost>

On Mon, Aug 03, 2015 at 03:04:55PM +0900, Simon Horman wrote:
> Hi Olof, Hi Kevin, Hi Arnd,
> 
> Please consider these Renesas ARM based SoC marzen board removal for v4.3.
> 
> 
> This series removes legacy r8a7779 SoC and marzen board code.
> It aims to do do so in a way that does not introduce feature regressions
> when when booting the r8a7779/marzen board using shmobile_defconfig,
> which provides for booting using multiplatform, a scenario which previously
> used board code to provide some features including SMP.
> 
> Because of the above this series modifies SoC and DT files,
> and then removes code. And because of that it was not entirely clear to
> me which branch it should go into, so I have provided it in a stand-alone
> branch.
> 
> Unfortunately this branch has a number of minor conflicts with the "Renesas
> ARM Based SoC Cleanup for v4.3", tagged as renesas-cleanup-for-v4.3, which
> you have previously pulled.
> 
> A resolution to those conflicts can be found in the
> renesas-next-20150730-v4.2-rc1 tag of the renesas tree.
> 
> On a more positive note, I believe this to well over 8000 lines of legacy
> code removed in this cycle :)
> 
> 
> Changes between v1 and v2:
> 
> * As requested by Olof: Do not include defconfig updates;
>   these will be handled separately
> 
> 
> The following changes since commit d770e558e21961ad6cfdf0ff7df0eb5d7d4f0754:
> 
>   Linux 4.2-rc1 (2015-07-05 11:01:52 -0700)
> 
> are available in the git repository at:
> 
>   git://git.kernel.org/pub/scm/linux/kernel/git/horms/renesas.git tags/renesas-marzen-board-removal-for-v4.3

Merged, but it was a messy one and it's awkward to diff with your proposed
resolution due to other differences.

Please double-check that I resolved things correctly. Thanks!


-Olof


From olof at lixom.net  Thu Aug  6 01:10:52 2015
From: olof at lixom.net (Olof Johansson)
Date: Thu, 6 Aug 2015 10:10:52 +0200
Subject: [PATCH 1/2] ARM: ux500: add an SMP enablement type and move cpu
 nodes
In-Reply-To: <1438586801-30115-1-git-send-email-linus.walleij@linaro.org>
References: <1438586801-30115-1-git-send-email-linus.walleij@linaro.org>
Message-ID: <20150806081052.GB16520@localhost>

On Mon, Aug 03, 2015 at 09:26:41AM +0200, Linus Walleij wrote:
> The "cpus" node cannot be inside the "soc" node, while this
> works for the CoreSight blocks, the early boot code will look
> for "cpus" directly under the root node, so this is a hard
> convention. So move the CPU nodes.
> 
> Augment the "reg" property to match what is actually in the
> hardware: 0x300 and 0x301 respectively.
> 
> Then add an SMP enablement type to be used by the SMP init
> code, "ste,dbx500-smp".
> 
> Signed-off-by: Linus Walleij <linus.walleij at linaro.org>
> ---
> Hi ARM SoC people: please apply this as a fix for v4.2
> as it is prerequisite for 2/2 which is a more proper fix
> for the secondary CPU boot regression addressed by the
> fixed remappings patch.

Applied, thanks.


-Olof


From olof at lixom.net  Thu Aug  6 01:11:30 2015
From: olof at lixom.net (Olof Johansson)
Date: Thu, 6 Aug 2015 10:11:30 +0200
Subject: [PATCH 2/2] ARM: ux500: simplify secondary CPU boot
In-Reply-To: <1438586812-30164-1-git-send-email-linus.walleij@linaro.org>
References: <1438586812-30164-1-git-send-email-linus.walleij@linaro.org>
Message-ID: <20150806081130.GC16520@localhost>

On Mon, Aug 03, 2015 at 09:26:52AM +0200, Linus Walleij wrote:
> This removes a lot of ancient cruft from the Ux500 SMP boot.
> Instead of the pen grab/release, just point the ROM to
> secondary_boot() and start the second CPU there, then send
> the IPI.
> 
> Use our own SMP enable method. This enables us to remove the
> last static mapping and get both CPUs booting properly.
> 
> Tested this and it just works.
> 
> Signed-off-by: Linus Walleij <linus.walleij at linaro.org>
> ---
> Hi ARM SoC folks: please apply this to fixes for v4.2. I was
> intending it for v4.3 but we might as well just kill off the
> legacy boot method right now so we do not need to restore any
> static maps and undo the cleanup (which would be just as
> invasive).

It's a bit late in the cycle for that. I'll apply it in cleanup for 4.3 though.


-Olof


From wangzhou1 at hisilicon.com  Thu Aug  6 01:09:15 2015
From: wangzhou1 at hisilicon.com (Zhou Wang)
Date: Thu, 6 Aug 2015 16:09:15 +0800
Subject: [PATCH v6 2/6] ARM/PCI: remove align_resource in pci_sys_data
In-Reply-To: <1438848559-232109-1-git-send-email-wangzhou1@hisilicon.com>
References: <1438848559-232109-1-git-send-email-wangzhou1@hisilicon.com>
Message-ID: <1438848559-232109-3-git-send-email-wangzhou1@hisilicon.com>

From: gabriele paoloni <gabriele.paoloni at huawei.com>

This patch is needed in order to unify the PCIe designware framework for ARM and
ARM64 architectures. In the PCIe designware unification process we are calling
pci_create_root_bus() passing a "sysdata" parameter that is the same for both
ARM and ARM64 and is of type "struct pcie_port*". In the ARM case this will
cause a problem with the function pcibios_align_resource(); in fact this will
cast "dev->sysdata" to "struct pci_sys_data*", whereas designware had passed a
"struct pcie_port*" pointer.

This patch solves the issue by removing "align_resource" from "pci_sys_data"
struct and defining a static global function pointer in "bios32.c"

Signed-off-by: Gabriele Paoloni <gabriele.paoloni at huawei.com>
---
 arch/arm/include/asm/mach/pci.h |  5 -----
 arch/arm/kernel/bios32.c        | 12 ++++++++----
 2 files changed, 8 insertions(+), 9 deletions(-)

diff --git a/arch/arm/include/asm/mach/pci.h b/arch/arm/include/asm/mach/pci.h
index 28b9bb3..8a4e4de 100644
--- a/arch/arm/include/asm/mach/pci.h
+++ b/arch/arm/include/asm/mach/pci.h
@@ -58,11 +58,6 @@ struct pci_sys_data {
 					/* IRQ mapping				*/
 	int		(*map_irq)(const struct pci_dev *, u8, u8);
 					/* Resource alignement requirements	*/
-	resource_size_t (*align_resource)(struct pci_dev *dev,
-					  const struct resource *res,
-					  resource_size_t start,
-					  resource_size_t size,
-					  resource_size_t align);
 	void		*private_data;	/* platform controller private data	*/
 };
 
diff --git a/arch/arm/kernel/bios32.c b/arch/arm/kernel/bios32.c
index fcbbbb1..4cdc64d 100644
--- a/arch/arm/kernel/bios32.c
+++ b/arch/arm/kernel/bios32.c
@@ -17,6 +17,11 @@
 #include <asm/mach/pci.h>
 
 static int debug_pci;
+static resource_size_t (*align_resource)(struct pci_dev *dev,
+		  const struct resource *res,
+		  resource_size_t start,
+		  resource_size_t size,
+		  resource_size_t align) = NULL;
 
 #ifdef CONFIG_PCI_MSI
 struct msi_controller *pcibios_msi_controller(struct pci_dev *dev)
@@ -468,7 +473,7 @@ static void pcibios_init_hw(struct device *parent, struct hw_pci *hw,
 		sys->busnr   = busnr;
 		sys->swizzle = hw->swizzle;
 		sys->map_irq = hw->map_irq;
-		sys->align_resource = hw->align_resource;
+		align_resource = hw->align_resource;
 		INIT_LIST_HEAD(&sys->resources);
 
 		if (hw->private_data)
@@ -589,7 +594,6 @@ resource_size_t pcibios_align_resource(void *data, const struct resource *res,
 				resource_size_t size, resource_size_t align)
 {
 	struct pci_dev *dev = data;
-	struct pci_sys_data *sys = dev->sysdata;
 	resource_size_t start = res->start;
 
 	if (res->flags & IORESOURCE_IO && start & 0x300)
@@ -597,8 +601,8 @@ resource_size_t pcibios_align_resource(void *data, const struct resource *res,
 
 	start = (start + align - 1) & ~(align - 1);
 
-	if (sys->align_resource)
-		return sys->align_resource(dev, res, start, size, align);
+	if (align_resource)
+		return align_resource(dev, res, start, size, align);
 
 	return start;
 }
-- 
1.9.1



From wangzhou1 at hisilicon.com  Thu Aug  6 01:09:17 2015
From: wangzhou1 at hisilicon.com (Zhou Wang)
Date: Thu, 6 Aug 2015 16:09:17 +0800
Subject: [PATCH v6 4/6] PCI: hisi: Add PCIe host support for HiSilicon SoC
 Hip05
In-Reply-To: <1438848559-232109-1-git-send-email-wangzhou1@hisilicon.com>
References: <1438848559-232109-1-git-send-email-wangzhou1@hisilicon.com>
Message-ID: <1438848559-232109-5-git-send-email-wangzhou1@hisilicon.com>

This patch adds PCIe host support for HiSilicon SoC Hip05.

Signed-off-by: Zhou Wang <wangzhou1 at hisilicon.com>
---
 drivers/pci/host/Kconfig     |   8 ++
 drivers/pci/host/Makefile    |   1 +
 drivers/pci/host/pcie-hisi.c | 254 +++++++++++++++++++++++++++++++++++++++++++
 3 files changed, 263 insertions(+)
 create mode 100644 drivers/pci/host/pcie-hisi.c

diff --git a/drivers/pci/host/Kconfig b/drivers/pci/host/Kconfig
index c132bdd..cd2b80b 100644
--- a/drivers/pci/host/Kconfig
+++ b/drivers/pci/host/Kconfig
@@ -145,4 +145,12 @@ config PCIE_IPROC_BCMA
 	  Say Y here if you want to use the Broadcom iProc PCIe controller
 	  through the BCMA bus interface
 
+config PCI_HISI
+	depends on OF && ARM64
+	bool "HiSilicon SoC HIP05 PCIe controller"
+	select PCIEPORTBUS
+	select PCIE_DW
+	help
+	  Say Y here if you want PCIe controller support on HiSilicon HIP05 SoC
+
 endmenu
diff --git a/drivers/pci/host/Makefile b/drivers/pci/host/Makefile
index 140d66f..ea1dbf2 100644
--- a/drivers/pci/host/Makefile
+++ b/drivers/pci/host/Makefile
@@ -17,3 +17,4 @@ obj-$(CONFIG_PCI_VERSATILE) += pci-versatile.o
 obj-$(CONFIG_PCIE_IPROC) += pcie-iproc.o
 obj-$(CONFIG_PCIE_IPROC_PLATFORM) += pcie-iproc-platform.o
 obj-$(CONFIG_PCIE_IPROC_BCMA) += pcie-iproc-bcma.o
+obj-$(CONFIG_PCI_HISI) += pcie-hisi.o
diff --git a/drivers/pci/host/pcie-hisi.c b/drivers/pci/host/pcie-hisi.c
new file mode 100644
index 0000000..7dcacf1
--- /dev/null
+++ b/drivers/pci/host/pcie-hisi.c
@@ -0,0 +1,254 @@
+/*
+ * PCIe host controller driver for HiSilicon Hip05 SoC
+ *
+ * Copyright (C) 2015 HiSilicon Co., Ltd. http://www.hisilicon.com
+ *
+ * Author: Zhou Wang <wangzhou1 at hisilicon.com>
+ *         Dacai Zhu <zhudacai at hisilicon.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.
+ */
+#include <linux/interrupt.h>
+#include <linux/irqdomain.h>
+#include <linux/module.h>
+#include <linux/of.h>
+#include <linux/of_pci.h>
+#include <linux/platform_device.h>
+
+#include "pcie-designware.h"
+
+#define PCIE_SUBCTRL_MODE_REG                           0x2800
+#define PCIE_SUBCTRL_SYS_STATE4_REG                     0x6818
+#define PCIE_SLV_DBI_MODE                               0x0
+#define PCIE_SLV_SYSCTRL_MODE                           0x1
+#define PCIE_SLV_CONTENT_MODE                           0x2
+#define PCIE_SLV_MSI_ASID                               0x10
+#define PCIE_LTSSM_LINKUP_STATE                         0x11
+#define PCIE_LTSSM_STATE_MASK                           0x3F
+#define PCIE_MSI_ASID_ENABLE                            (0x1 << 12)
+#define PCIE_MSI_ASID_VALUE                             (0x1 << 16)
+#define PCIE_MSI_TRANS_ENABLE                           (0x1 << 12)
+#define PCIE_MSI_TRANS_REG                              0x1c8
+#define PCIE_MSI_LOW_ADDRESS                            0x1b4
+#define PCIE_MSI_HIGH_ADDRESS                           0x1c4
+#define PCIE_MSI_ADDRESS_VAL                            0xb7010040
+
+#define to_hisi_pcie(x)	container_of(x, struct hisi_pcie, pp)
+
+struct hisi_pcie {
+	void __iomem *subctrl_base;
+	void __iomem *reg_base;
+	struct msi_controller *msi;
+	u32 port_id;
+	struct pcie_port pp;
+};
+
+static inline void hisi_pcie_subctrl_writel(struct hisi_pcie *pcie,
+					    u32 val, u32 reg)
+{
+	writel(val, pcie->subctrl_base + reg);
+}
+
+static inline u32 hisi_pcie_subctrl_readl(struct hisi_pcie *pcie, u32 reg)
+{
+	return readl(pcie->subctrl_base + reg);
+}
+
+static inline void hisi_pcie_apb_writel(struct hisi_pcie *pcie,
+					u32 val, u32 reg)
+{
+	writel(val, pcie->reg_base + reg);
+}
+
+static inline u32 hisi_pcie_apb_readl(struct hisi_pcie *pcie, u32 reg)
+{
+	return readl(pcie->reg_base + reg);
+}
+
+/*
+ * Change mode to indicate the same reg_base to base of PCIe host configure
+ * registers, base of RC configure space or base of vmid/asid context table
+ */
+static void hisi_pcie_change_apb_mode(struct hisi_pcie *pcie, u32 mode)
+{
+	u32 val;
+	u32 bit_mask;
+	u32 bit_shift;
+	u32 port_id = pcie->port_id;
+	u32 reg = PCIE_SUBCTRL_MODE_REG + 0x100 * port_id;
+
+	if ((port_id == 1) || (port_id == 2)) {
+		bit_mask = 0xc;
+		bit_shift = 0x2;
+	} else {
+		bit_mask = 0x6;
+		bit_shift = 0x1;
+	}
+
+	val = hisi_pcie_subctrl_readl(pcie, reg);
+	val = (val & (~bit_mask)) | (mode << bit_shift);
+	hisi_pcie_subctrl_writel(pcie, val, reg);
+}
+
+/* Configure vmid/asid table in PCIe host */
+static void hisi_pcie_config_context(struct hisi_pcie *pcie)
+{
+	int i;
+
+	hisi_pcie_change_apb_mode(pcie, PCIE_SLV_CONTENT_MODE);
+
+	/*
+	 * init vmid and asid tables for all PCIe devices as 0
+	 * vmid table: 0 ~ 0x3ff, asid table: 0x400 ~ 0x7ff
+	 */
+	for (i = 0; i < 0x800; i++)
+		hisi_pcie_apb_writel(pcie, 0x0, i * 4);
+
+	hisi_pcie_change_apb_mode(pcie, PCIE_SLV_SYSCTRL_MODE);
+
+	hisi_pcie_apb_writel(pcie, PCIE_MSI_ADDRESS_VAL, PCIE_MSI_LOW_ADDRESS);
+	hisi_pcie_apb_writel(pcie, 0x0, PCIE_MSI_HIGH_ADDRESS);
+	hisi_pcie_apb_writel(pcie, PCIE_MSI_ASID_ENABLE | PCIE_MSI_ASID_VALUE,
+			     PCIE_SLV_MSI_ASID);
+	hisi_pcie_apb_writel(pcie, PCIE_MSI_TRANS_ENABLE, PCIE_MSI_TRANS_REG);
+
+	hisi_pcie_change_apb_mode(pcie, PCIE_SLV_DBI_MODE);
+}
+
+static int hisi_pcie_link_up(struct pcie_port *pp)
+{
+	u32 val;
+	struct hisi_pcie *hisi_pcie = to_hisi_pcie(pp);
+
+	val = hisi_pcie_subctrl_readl(hisi_pcie, PCIE_SUBCTRL_SYS_STATE4_REG +
+				      0x100 * hisi_pcie->port_id);
+
+	return ((val & PCIE_LTSSM_STATE_MASK) == PCIE_LTSSM_LINKUP_STATE);
+}
+
+static
+int hisi_pcie_msi_host_init(struct pcie_port *pp, struct msi_controller *chip)
+{
+	struct device_node *msi_node;
+	struct irq_domain *irq_domain;
+	struct device_node *np = pp->dev->of_node;
+
+	msi_node = of_parse_phandle(np, "msi-parent", 0);
+	if (!msi_node) {
+		dev_err(pp->dev, "failed to find msi-parent\n");
+		return -ENODEV;
+	}
+
+	irq_domain = irq_find_host(msi_node);
+	if (!irq_domain) {
+		dev_err(pp->dev, "failed to find irq domain\n");
+		return -ENODEV;
+	}
+
+	pp->irq_domain = irq_domain;
+
+	return 0;
+}
+
+static struct pcie_host_ops hisi_pcie_host_ops = {
+	.link_up = hisi_pcie_link_up,
+	.msi_host_init = hisi_pcie_msi_host_init,
+};
+
+static int __init hisi_add_pcie_port(struct pcie_port *pp,
+				     struct platform_device *pdev)
+{
+	int ret;
+	u32 port_id;
+	struct resource busn;
+	struct hisi_pcie *hisi_pcie = to_hisi_pcie(pp);
+
+	if (of_property_read_u32(pdev->dev.of_node, "port-id", &port_id)) {
+		dev_err(&pdev->dev, "failed to read port-id\n");
+		return -EINVAL;
+	}
+	if (port_id > 3) {
+		dev_err(&pdev->dev, "Invalid port-id: %d\n", port_id);
+		return -EINVAL;
+	}
+
+	hisi_pcie->port_id = port_id;
+
+	if (of_pci_parse_bus_range(pdev->dev.of_node, &busn)) {
+		dev_err(&pdev->dev, "failed to parse bus-ranges\n");
+		return -EINVAL;
+	}
+
+	pp->root_bus_nr = busn.start;
+	pp->ops = &hisi_pcie_host_ops;
+
+	hisi_pcie_config_context(hisi_pcie);
+
+	ret = dw_pcie_host_init(pp);
+	if (ret) {
+		dev_err(&pdev->dev, "failed to initialize host\n");
+		return ret;
+	}
+
+	return 0;
+}
+
+static int __init hisi_pcie_probe(struct platform_device *pdev)
+{
+	struct hisi_pcie *hisi_pcie;
+	struct pcie_port *pp;
+	struct resource *reg;
+	struct resource *subctrl;
+	int ret;
+
+	hisi_pcie = devm_kzalloc(&pdev->dev, sizeof(*hisi_pcie), GFP_KERNEL);
+	if (!hisi_pcie)
+		return -ENOMEM;
+
+	pp = &hisi_pcie->pp;
+	pp->dev = &pdev->dev;
+
+	subctrl = platform_get_resource_byname(pdev, IORESOURCE_MEM, "subctrl");
+	hisi_pcie->subctrl_base = devm_ioremap_nocache(&pdev->dev,
+					subctrl->start, resource_size(subctrl));
+	if (IS_ERR(hisi_pcie->subctrl_base)) {
+		dev_err(pp->dev, "cannot get subctrl base\n");
+		return PTR_ERR(hisi_pcie->subctrl_base);
+	}
+
+	reg = platform_get_resource_byname(pdev, IORESOURCE_MEM, "rc_dbi");
+	hisi_pcie->reg_base = devm_ioremap_resource(&pdev->dev, reg);
+	if (IS_ERR(hisi_pcie->reg_base)) {
+		dev_err(pp->dev, "cannot get rc_dbi base\n");
+		return PTR_ERR(hisi_pcie->reg_base);
+	}
+
+	hisi_pcie->pp.dbi_base = hisi_pcie->reg_base;
+
+	ret = hisi_add_pcie_port(pp, pdev);
+	if (ret)
+		return ret;
+
+	platform_set_drvdata(pdev, hisi_pcie);
+
+	return 0;
+}
+
+static const struct of_device_id hisi_pcie_of_match[] = {
+	{.compatible = "hisilicon,hip05-pcie",},
+	{},
+};
+
+MODULE_DEVICE_TABLE(of, hisi_pcie_of_match);
+
+static struct platform_driver hisi_pcie_driver = {
+	.probe  = hisi_pcie_probe,
+	.driver = {
+		   .name = "hisi-pcie",
+		   .of_match_table = hisi_pcie_of_match,
+	},
+};
+
+module_platform_driver(hisi_pcie_driver);
-- 
1.9.1



From olof at lixom.net  Thu Aug  6 01:13:10 2015
From: olof at lixom.net (Olof Johansson)
Date: Thu, 6 Aug 2015 10:13:10 +0200
Subject: [GIT PULL] Allwinner defconfig changes for 4.3
In-Reply-To: <20150803094347.GA17185@lukather>
References: <20150803094347.GA17185@lukather>
Message-ID: <20150806081310.GE16520@localhost>

On Mon, Aug 03, 2015 at 11:43:47AM +0200, Maxime Ripard wrote:
> Hi Arnd, Kevin, Olof,
> 
> Please pull the following defconfig patches for the 4.3 merge window.
> 
> Thanks!
> Maxime
> 
> The following changes since commit bc0195aad0daa2ad5b0d76cce22b167bc3435590:
> 
>   Linux 4.2-rc2 (2015-07-12 15:10:30 -0700)
> 
> are available in the git repository at:
> 
>   https://git.kernel.org/pub/scm/linux/kernel/git/mripard/linux.git tags/sunxi-defconfig-for-4.3
> 
> for you to fetch changes up to 8faf3554cb7a83413f9dfbe1a3420a81c52efe47:
> 
>   ARM: multi_v7_defconfig: Enable Allwinner P2WI, PWM, DMA_SUN6I, cryptodev (2015-07-31 20:01:24 +0200)

Merged, thanks.


-Olof


From olof at lixom.net  Thu Aug  6 01:16:07 2015
From: olof at lixom.net (Olof Johansson)
Date: Thu, 6 Aug 2015 10:16:07 +0200
Subject: [PATCH 2/2] arm64: Enable Marvell Berlin SoC family in defconfig
In-Reply-To: <1438629886-6390-3-git-send-email-sebastian.hesselbarth@gmail.com>
References: <1438629886-6390-1-git-send-email-sebastian.hesselbarth@gmail.com>
 <1438629886-6390-3-git-send-email-sebastian.hesselbarth@gmail.com>
Message-ID: <20150806081607.GG16520@localhost>

On Mon, Aug 03, 2015 at 09:24:46PM +0200, Sebastian Hesselbarth wrote:
> From: Jisheng Zhang <jszhang at marvell.com>
> 
> Enable Marvell Berlin SoC family in arm64 defconfig.
> 
> Signed-off-by: Jisheng Zhang <jszhang at marvell.com>
> Signed-off-by: Sebastian Hesselbarth <sebastian.hesselbarth at gmail.com>
> ---
> Also discussed with Olof on IRC, this is the defconfig changes singled
> out from Jisheng's original patch.

Applied, thanks.


-Olof


From jamesjj.liao at mediatek.com  Thu Aug  6 01:35:32 2015
From: jamesjj.liao at mediatek.com (James Liao)
Date: Thu, 6 Aug 2015 16:35:32 +0800
Subject: [PATCH v6 5/9] clk: mediatek: Fix rate and dependency of MT8173
 clocks
In-Reply-To: <20150805065341.GA18700@pengutronix.de>
References: <1438676218-11310-1-git-send-email-jamesjj.liao@mediatek.com>
 <1438676218-11310-6-git-send-email-jamesjj.liao@mediatek.com>
 <20150805065341.GA18700@pengutronix.de>
Message-ID: <1438850132.27884.17.camel@mtksdaap41>

Hi Sascha,

On Wed, 2015-08-05 at 08:53 +0200, Sascha Hauer wrote:
> On Tue, Aug 04, 2015 at 04:16:54PM +0800, James Liao wrote:
> > -static const struct mtk_fixed_factor root_clk_alias[] __initconst = {
> > -	FACTOR(CLK_TOP_CLKPH_MCK_O, "clkph_mck_o", "clk_null", 1, 1),
> > -	FACTOR(CLK_TOP_USB_SYSPLL_125M, "usb_syspll_125m", "clk_null", 1, 1),
> > -	FACTOR(CLK_TOP_HDMITX_DIG_CTS, "hdmitx_dig_cts", "clk_null", 1, 1),
> > +static const struct mtk_fixed_clk fixed_clks[] __initconst = {
> > +	FIXED_CLK(CLK_TOP_CLKPH_MCK_O, "clkph_mck_o", "clk26m", 400 * MHZ),
> > +	FIXED_CLK(CLK_TOP_USB_SYSPLL_125M, "usb_syspll_125m", "clk26m", 125 * MHZ),
> 
> Hm, it seems you hide PLLs in fixed factor clock. Are you sure that
> there is a PLL in the system generating 125MHz from 26MHz which is in no
> way configurable? Or is this really some clock derived from the syspll
> as the clock name suggests?

According to the datasheet from our clock designer, usb_syspll_125m is
the output clock of an analog macro which is named SSUSB_PHY, and its
input clock is AD_CLK26M_CK.

SSUSB_PHY is not the same as general PLLs such as MAINPLL. So I don't
treat it as a configurable PLL but a fixed clock with the typical rate
125 MHz.


Best regards,

James



From olof at lixom.net  Thu Aug  6 01:15:14 2015
From: olof at lixom.net (Olof Johansson)
Date: Thu, 6 Aug 2015 10:15:14 +0200
Subject: [PATCH 1/2] arm64: Enable Marvell Berlin SoC family in Kconfig
In-Reply-To: <1438629886-6390-2-git-send-email-sebastian.hesselbarth@gmail.com>
References: <1438629886-6390-1-git-send-email-sebastian.hesselbarth@gmail.com>
 <1438629886-6390-2-git-send-email-sebastian.hesselbarth@gmail.com>
Message-ID: <20150806081514.GF16520@localhost>

On Mon, Aug 03, 2015 at 09:24:45PM +0200, Sebastian Hesselbarth wrote:
> From: Jisheng Zhang <jszhang at marvell.com>
> 
> This patch introduces ARCH_BERLIN to enable Marvell Berlin SoC family in
> Kconfig.
> 
> Signed-off-by: Jisheng Zhang <jszhang at marvell.com>
> Signed-off-by: Sebastian Hesselbarth <sebastian.hesselbarth at gmail.com>
> ---
> As discussed with Olof on IRC, this is Jisheng's Kconfig patch for
> ARM64 Berlin. Olof agreed to rework this to finally land in
> Kconfig.platforms, i.e. after
>   eed6b3eb20b9 ("arm64: Split out platform options to separate Kconfig")

Applied, thanks.


-Olof


From olof at lixom.net  Thu Aug  6 01:12:36 2015
From: olof at lixom.net (Olof Johansson)
Date: Thu, 6 Aug 2015 10:12:36 +0200
Subject: [GIT PULL] Allwinner DT changes for 4.3
In-Reply-To: <20150803094143.GA16612@lukather>
References: <20150803094143.GA16612@lukather>
Message-ID: <20150806081236.GD16520@localhost>

On Mon, Aug 03, 2015 at 11:41:43AM +0200, Maxime Ripard wrote:
> Hi Arnd, Kevin, Olof,
> 
> Here is the DT changes for the 4.3 merge window.
> 
> I'll be in holidays for the three next weeks, so this is probably
> going to be my last "feature" pull request for the 4.3 merge window.
> 
> Thanks!
> Maxime
> 
> 
> The following changes since commit d770e558e21961ad6cfdf0ff7df0eb5d7d4f0754:
> 
>   Linux 4.2-rc1 (2015-07-05 11:01:52 -0700)
> 
> are available in the git repository at:
> 
>   https://git.kernel.org/pub/scm/linux/kernel/git/mripard/linux.git tags/sunxi-dt-for-4.3
> 
> for you to fetch changes up to 60018d027d792bdfe9d98c83a470fa2cdd6a0e1a:
> 
>   ARM: dts: sun7i: Change cubietruck wifi enable pin to use mmc-pwrseq (2015-08-01 11:25:11 +0200)

Merged, thanks!


-Olof


From wenyou.yang at atmel.com  Thu Aug  6 01:34:13 2015
From: wenyou.yang at atmel.com (Wenyou Yang)
Date: Thu, 6 Aug 2015 16:34:13 +0800
Subject: [PATCH v5 0/2] add a new driver to support SAMA5D4 watchdog timer
Message-ID: <1438850055-30104-1-git-send-email-wenyou.yang@atmel.com>

Hello,

Because the watchdog WDT_MR register can be written more than once,
its work mechanism is different from the at91sam9260 watchdog driver.
Open the device file to enable the watchdog hardware, close to disable it,
and ping it from the user space directly to keep it alive.

Changes from v4.0
 1./ Fix interrupt register function flags argument.
 2./ Replace the tabs after #define with spaces.

Changes from v3.0
 1./ Change the driver name to 'sama5d4_wdt' for more acceptable.
 2./ Change the prefix of function name and struct name
     from 'atmel_' to 'sama5d4_', and others.

Changes from v2.0
 1./ Use a specific driver name, at91_sama5d4_wdt.c.
 2./ Remove '-' at the end of macro name and unnecessary check.
 3./ Use alphabetic order for include files.

Wenyou Yang (2):
  drivers: watchdog: add a driver to support SAMA5D4 watchdog timer
  Documentation: dt: binding: atmel-sama5d4-wdt: for SAMA5D4 watchdog
    driver

 .../bindings/watchdog/atmel-sama5d4-wdt.txt        |   35 +++
 drivers/watchdog/Kconfig                           |    9 +
 drivers/watchdog/Makefile                          |    1 +
 drivers/watchdog/at91sam9_wdt.h                    |    2 +
 drivers/watchdog/sama5d4_wdt.c                     |  280 ++++++++++++++++++++
 5 files changed, 327 insertions(+)
 create mode 100644 Documentation/devicetree/bindings/watchdog/atmel-sama5d4-wdt.txt
 create mode 100644 drivers/watchdog/sama5d4_wdt.c

-- 
1.7.9.5



From sudeep.holla at arm.com  Thu Aug  6 01:42:47 2015
From: sudeep.holla at arm.com (Sudeep Holla)
Date: Thu, 06 Aug 2015 09:42:47 +0100
Subject: [PATCH v6 0/8] ARM64: juno: add SCPI mailbox protocol, clock
 and CPUFreq support
In-Reply-To: <55C1DE7F.5040002@arm.com>
References: <1438364591-1144-1-git-send-email-sudeep.holla@arm.com>
 <55C1DE7F.5040002@arm.com>
Message-ID: <55C31E07.4090307@arm.com>

Hi Olof,

On 05/08/15 10:59, Sudeep Holla wrote:
> Hi Olof,
>
> On 31/07/15 18:43, Sudeep Holla wrote:
>> Hi ARM-SoC guys,
>>
>> It has been on the list for a while and have got all the necessary
>> ACKs. Can you please pull this series for v4.3 ?
>>
>
> Can you pull this patch series directly from the mail or do you prefer
> pull-request ?
>

Any issue with this series ? Let me know. I did send a pull request also
but I haven't got any response so far. Sorry for the nag.

Regards,
Sudeep


From wenyou.yang at atmel.com  Thu Aug  6 01:34:14 2015
From: wenyou.yang at atmel.com (Wenyou Yang)
Date: Thu, 6 Aug 2015 16:34:14 +0800
Subject: [PATCH v5 1/2] drivers: watchdog: add a driver to support SAMA5D4
 watchdog timer
In-Reply-To: <1438850055-30104-1-git-send-email-wenyou.yang@atmel.com>
References: <1438850055-30104-1-git-send-email-wenyou.yang@atmel.com>
Message-ID: <1438850055-30104-2-git-send-email-wenyou.yang@atmel.com>

>From SAMA5D4, the watchdog timer is upgrated with a new feature,
which is describled as in the datasheet, "WDT_MR can be written
until a LOCKMR command is issued in WDT_CR".
That is to say, as long as the bootstrap and u-boot don't issue
a LOCKMR command, WDT_MR can be written more than once in the driver.

So the SAMA5D4 watchdog driver's implementation is different from
the at91sam9260 watchdog driver implemented in file at91sam9_wdt.c.
The user application open the device file to enable the watchdog timer
hardware, and close to disable it, and set the watchdog timer timeout
by seting WDV and WDD fields of WDT_MR register, and ping the watchdog
by issuing WDRSTT command to WDT_CR register with hard-coded key.

Signed-off-by: Wenyou Yang <wenyou.yang at atmel.com>
---
 drivers/watchdog/Kconfig        |    9 ++
 drivers/watchdog/Makefile       |    1 +
 drivers/watchdog/at91sam9_wdt.h |    2 +
 drivers/watchdog/sama5d4_wdt.c  |  280 +++++++++++++++++++++++++++++++++++++++
 4 files changed, 292 insertions(+)
 create mode 100644 drivers/watchdog/sama5d4_wdt.c

diff --git a/drivers/watchdog/Kconfig b/drivers/watchdog/Kconfig
index e5e7c55..47ad39a 100644
--- a/drivers/watchdog/Kconfig
+++ b/drivers/watchdog/Kconfig
@@ -167,6 +167,15 @@ config AT91SAM9X_WATCHDOG
 	  Watchdog timer embedded into AT91SAM9X and AT91CAP9 chips. This will
 	  reboot your system when the timeout is reached.
 
+config SAMA5D4_WATCHDOG
+	tristate "Atmel SAMA5D4 Watchdog Timer"
+	depends on ARCH_AT91
+	select WATCHDOG_CORE
+	help
+	  Atmel SAMA5D4 watchdog timer is embedded into SAMA5D4 chips.
+	  Its Watchdog Timer Mode Register can be written more than once.
+	  This will reboot your system when the timeout is reached.
+
 config CADENCE_WATCHDOG
 	tristate "Cadence Watchdog Timer"
 	select WATCHDOG_CORE
diff --git a/drivers/watchdog/Makefile b/drivers/watchdog/Makefile
index 5c19294..f24b820 100644
--- a/drivers/watchdog/Makefile
+++ b/drivers/watchdog/Makefile
@@ -41,6 +41,7 @@ obj-$(CONFIG_IXP4XX_WATCHDOG) += ixp4xx_wdt.o
 obj-$(CONFIG_KS8695_WATCHDOG) += ks8695_wdt.o
 obj-$(CONFIG_S3C2410_WATCHDOG) += s3c2410_wdt.o
 obj-$(CONFIG_SA1100_WATCHDOG) += sa1100_wdt.o
+obj-$(CONFIG_SAMA5D4_WATCHDOG) += sama5d4_wdt.o
 obj-$(CONFIG_DW_WATCHDOG) += dw_wdt.o
 obj-$(CONFIG_EP93XX_WATCHDOG) += ep93xx_wdt.o
 obj-$(CONFIG_PNX4008_WATCHDOG) += pnx4008_wdt.o
diff --git a/drivers/watchdog/at91sam9_wdt.h b/drivers/watchdog/at91sam9_wdt.h
index c6fbb2e6..b79a83b 100644
--- a/drivers/watchdog/at91sam9_wdt.h
+++ b/drivers/watchdog/at91sam9_wdt.h
@@ -22,11 +22,13 @@
 
 #define AT91_WDT_MR		0x04			/* Watchdog Mode Register */
 #define		AT91_WDT_WDV		(0xfff << 0)		/* Counter Value */
+#define			AT91_WDT_SET_WDV(x)	((x) & AT91_WDT_WDV)
 #define		AT91_WDT_WDFIEN		(1     << 12)		/* Fault Interrupt Enable */
 #define		AT91_WDT_WDRSTEN	(1     << 13)		/* Reset Processor */
 #define		AT91_WDT_WDRPROC	(1     << 14)		/* Timer Restart */
 #define		AT91_WDT_WDDIS		(1     << 15)		/* Watchdog Disable */
 #define		AT91_WDT_WDD		(0xfff << 16)		/* Delta Value */
+#define			AT91_WDT_SET_WDD(x)	(((x) << 16) & AT91_WDT_WDD)
 #define		AT91_WDT_WDDBGHLT	(1     << 28)		/* Debug Halt */
 #define		AT91_WDT_WDIDLEHLT	(1     << 29)		/* Idle Halt */
 
diff --git a/drivers/watchdog/sama5d4_wdt.c b/drivers/watchdog/sama5d4_wdt.c
new file mode 100644
index 0000000..a412215
--- /dev/null
+++ b/drivers/watchdog/sama5d4_wdt.c
@@ -0,0 +1,280 @@
+/*
+ * Driver for Atmel SAMA5D4 Watchdog Timer
+ *
+ * Copyright (C) 2015 Atmel Corporation
+ *
+ * Licensed under GPLv2.
+ */
+
+#include <linux/interrupt.h>
+#include <linux/io.h>
+#include <linux/kernel.h>
+#include <linux/module.h>
+#include <linux/of.h>
+#include <linux/of_irq.h>
+#include <linux/platform_device.h>
+#include <linux/reboot.h>
+#include <linux/watchdog.h>
+
+#include "at91sam9_wdt.h"
+
+/* minimum and maximum watchdog timeout, in seconds */
+#define MIN_WDT_TIMEOUT		1
+#define MAX_WDT_TIMEOUT		16
+#define WDT_DEFAULT_TIMEOUT	MAX_WDT_TIMEOUT
+
+#define WDT_SEC2TICKS(s)	((s) ? (((s) << 8) - 1) : 0)
+
+struct sama5d4_wdt {
+	struct watchdog_device	wdd;
+	void __iomem		*reg_base;
+	u32	config;
+};
+
+static int wdt_timeout = WDT_DEFAULT_TIMEOUT;
+static bool nowayout = WATCHDOG_NOWAYOUT;
+
+module_param(wdt_timeout, int, 0);
+MODULE_PARM_DESC(wdt_timeout,
+	"Watchdog timeout in seconds. (default = "
+	__MODULE_STRING(WDT_DEFAULT_TIMEOUT) ")");
+
+module_param(nowayout, bool, 0);
+MODULE_PARM_DESC(nowayout,
+	"Watchdog cannot be stopped once started (default="
+	__MODULE_STRING(WATCHDOG_NOWAYOUT) ")");
+
+#define wdt_read(wdt, field) \
+	readl_relaxed((wdt)->reg_base + (field))
+
+#define wdt_write(wtd, field, val) \
+	writel_relaxed((val), (wdt)->reg_base + (field))
+
+static int sama5d4_wdt_start(struct watchdog_device *wdd)
+{
+	struct sama5d4_wdt *wdt = watchdog_get_drvdata(wdd);
+	u32 reg;
+
+	reg = wdt_read(wdt, AT91_WDT_MR);
+	reg &= ~AT91_WDT_WDDIS;
+	wdt_write(wdt, AT91_WDT_MR, reg);
+
+	return 0;
+}
+
+static int sama5d4_wdt_stop(struct watchdog_device *wdd)
+{
+	struct sama5d4_wdt *wdt = watchdog_get_drvdata(wdd);
+	u32 reg;
+
+	reg = wdt_read(wdt, AT91_WDT_MR);
+	reg |= AT91_WDT_WDDIS;
+	wdt_write(wdt, AT91_WDT_MR, reg);
+
+	return 0;
+}
+
+static int sama5d4_wdt_ping(struct watchdog_device *wdd)
+{
+	struct sama5d4_wdt *wdt = watchdog_get_drvdata(wdd);
+
+	wdt_write(wdt, AT91_WDT_CR, AT91_WDT_KEY | AT91_WDT_WDRSTT);
+
+	return 0;
+}
+
+static int sama5d4_wdt_set_timeout(struct watchdog_device *wdd,
+				 unsigned int timeout)
+{
+	struct sama5d4_wdt *wdt = watchdog_get_drvdata(wdd);
+	u32 value = WDT_SEC2TICKS(timeout);
+	u32 reg;
+
+	reg = wdt_read(wdt, AT91_WDT_MR);
+	reg &= ~AT91_WDT_WDV;
+	reg &= ~AT91_WDT_WDD;
+	reg |= AT91_WDT_SET_WDV(value);
+	reg |= AT91_WDT_SET_WDD(value);
+	wdt_write(wdt, AT91_WDT_MR, reg);
+
+	wdd->timeout = timeout;
+
+	return 0;
+}
+
+static const struct watchdog_info sama5d4_wdt_info = {
+	.options = WDIOF_SETTIMEOUT | WDIOF_MAGICCLOSE | WDIOF_KEEPALIVEPING,
+	.identity = "Atmel SAMA5D4 Watchdog"
+};
+
+static struct watchdog_ops sama5d4_wdt_ops = {
+	.owner = THIS_MODULE,
+	.start = sama5d4_wdt_start,
+	.stop = sama5d4_wdt_stop,
+	.ping = sama5d4_wdt_ping,
+	.set_timeout = sama5d4_wdt_set_timeout
+};
+
+static irqreturn_t sama5d4_wdt_irq_handler(int irq, void *dev_id)
+{
+	struct sama5d4_wdt *wdt = platform_get_drvdata(dev_id);
+
+	if (wdt_read(wdt, AT91_WDT_SR)) {
+		pr_crit("Atmel Watchdog Software Reset\n");
+		emergency_restart();
+		pr_crit("Reboot didn't succeed\n");
+	}
+
+	return IRQ_HANDLED;
+}
+
+static int of_sama5d4_wdt_init(struct device_node *np, struct sama5d4_wdt *wdt)
+{
+	const char *tmp;
+
+	wdt->config = AT91_WDT_WDDIS;
+
+	if (!of_property_read_string(np, "atmel,watchdog-type", &tmp) &&
+	    !strcmp(tmp, "software"))
+		wdt->config |= AT91_WDT_WDFIEN;
+	else
+		wdt->config |= AT91_WDT_WDRSTEN;
+
+	if (of_property_read_bool(np, "atmel,idle-halt"))
+		wdt->config |= AT91_WDT_WDIDLEHLT;
+
+	if (of_property_read_bool(np, "atmel,dbg-halt"))
+		wdt->config |= AT91_WDT_WDDBGHLT;
+
+	return 0;
+}
+
+static int sama5d4_wdt_init(struct sama5d4_wdt *wdt)
+{
+	struct watchdog_device *wdd = &wdt->wdd;
+	u32 value = WDT_SEC2TICKS(wdd->timeout);
+	u32 reg;
+
+	/*
+	 * Because the fields WDV and WDD must not be modified when the WDDIS
+	 * bit is set, so clear the WDDIS bit before writing the WDT_MR.
+	 */
+	reg = wdt_read(wdt, AT91_WDT_MR);
+	reg &= ~AT91_WDT_WDDIS;
+	wdt_write(wdt, AT91_WDT_MR, reg);
+
+	reg = wdt->config;
+	reg |= AT91_WDT_SET_WDD(value);
+	reg |= AT91_WDT_SET_WDV(value);
+
+	wdt_write(wdt, AT91_WDT_MR, reg);
+
+	return 0;
+}
+
+static int sama5d4_wdt_probe(struct platform_device *pdev)
+{
+	struct watchdog_device *wdd;
+	struct sama5d4_wdt *wdt;
+	struct resource *res;
+	void __iomem *regs;
+	u32 irq = 0;
+	int ret;
+
+	wdt = devm_kzalloc(&pdev->dev, sizeof(*wdt), GFP_KERNEL);
+	if (!wdt)
+		return -ENOMEM;
+
+	wdd = &wdt->wdd;
+	wdd->timeout = wdt_timeout;
+	wdd->info = &sama5d4_wdt_info;
+	wdd->ops = &sama5d4_wdt_ops;
+	wdd->min_timeout = MIN_WDT_TIMEOUT;
+	wdd->max_timeout = MAX_WDT_TIMEOUT;
+
+	watchdog_set_drvdata(wdd, wdt);
+
+	res = platform_get_resource(pdev, IORESOURCE_MEM, 0);
+	regs = devm_ioremap_resource(&pdev->dev, res);
+	if (IS_ERR(regs))
+		return PTR_ERR(regs);
+
+	wdt->reg_base = regs;
+
+	if (pdev->dev.of_node) {
+		irq = irq_of_parse_and_map(pdev->dev.of_node, 0);
+		if (!irq)
+			dev_warn(&pdev->dev, "failed to get IRQ from DT\n");
+
+		ret = of_sama5d4_wdt_init(pdev->dev.of_node, wdt);
+		if (ret)
+			return ret;
+	}
+
+	if ((wdt->config & AT91_WDT_WDFIEN) && irq) {
+		ret = devm_request_irq(&pdev->dev, irq, sama5d4_wdt_irq_handler,
+				       IRQF_SHARED | IRQF_IRQPOLL |
+				       IRQF_NO_SUSPEND, pdev->name, pdev);
+		if (ret) {
+			dev_err(&pdev->dev,
+				"cannot register interrupt handler\n");
+			return ret;
+		}
+	}
+
+	ret = watchdog_init_timeout(wdd, wdt_timeout, &pdev->dev);
+	if (ret) {
+		dev_err(&pdev->dev, "unable to set timeout value\n");
+		return ret;
+	}
+
+	ret = sama5d4_wdt_init(wdt);
+	if (ret)
+		return ret;
+
+	watchdog_set_nowayout(wdd, nowayout);
+
+	ret = watchdog_register_device(wdd);
+	if (ret) {
+		dev_err(&pdev->dev, "failed to register watchdog device\n");
+		return ret;
+	}
+
+	platform_set_drvdata(pdev, wdt);
+
+	dev_info(&pdev->dev, "initialized (timeout = %d sec, nowayout = %d)\n",
+		 wdt_timeout, nowayout);
+
+	return 0;
+}
+
+static int sama5d4_wdt_remove(struct platform_device *pdev)
+{
+	struct sama5d4_wdt *wdt = platform_get_drvdata(pdev);
+
+	sama5d4_wdt_stop(&wdt->wdd);
+
+	watchdog_unregister_device(&wdt->wdd);
+
+	return 0;
+}
+
+static const struct of_device_id sama5d4_wdt_of_match[] = {
+	{ .compatible = "atmel,sama5d4-wdt", },
+	{ }
+};
+MODULE_DEVICE_TABLE(of, sama5d4_wdt_of_match);
+
+static struct platform_driver sama5d4_wdt_driver = {
+	.probe		= sama5d4_wdt_probe,
+	.remove		= sama5d4_wdt_remove,
+	.driver		= {
+		.name	= "sama5d4_wdt",
+		.of_match_table = sama5d4_wdt_of_match,
+	}
+};
+module_platform_driver(sama5d4_wdt_driver);
+
+MODULE_AUTHOR("Atmel Corporation");
+MODULE_DESCRIPTION("Atmel SAMA5D4 Watchdog Timer driver");
+MODULE_LICENSE("GPL v2");
-- 
1.7.9.5



From wenyou.yang at atmel.com  Thu Aug  6 01:34:15 2015
From: wenyou.yang at atmel.com (Wenyou Yang)
Date: Thu, 6 Aug 2015 16:34:15 +0800
Subject: [PATCH v5 2/2] Documentation: dt: binding: atmel-sama5d4-wdt: for
 SAMA5D4 watchdog driver
In-Reply-To: <1438850055-30104-1-git-send-email-wenyou.yang@atmel.com>
References: <1438850055-30104-1-git-send-email-wenyou.yang@atmel.com>
Message-ID: <1438850055-30104-3-git-send-email-wenyou.yang@atmel.com>

The compatible "atmel,sama5d4-wdt" supports the SAMA5D4 watchdog driver
and the watchdog's WDT_MR register can be written more than once.

Signed-off-by: Wenyou Yang <wenyou.yang at atmel.com>
---
 .../bindings/watchdog/atmel-sama5d4-wdt.txt        |   35 ++++++++++++++++++++
 1 file changed, 35 insertions(+)
 create mode 100644 Documentation/devicetree/bindings/watchdog/atmel-sama5d4-wdt.txt

diff --git a/Documentation/devicetree/bindings/watchdog/atmel-sama5d4-wdt.txt b/Documentation/devicetree/bindings/watchdog/atmel-sama5d4-wdt.txt
new file mode 100644
index 0000000..f7cc7c0
--- /dev/null
+++ b/Documentation/devicetree/bindings/watchdog/atmel-sama5d4-wdt.txt
@@ -0,0 +1,35 @@
+* Atmel SAMA5D4 Watchdog Timer (WDT) Controller
+
+Required properties:
+- compatible: "atmel,sama5d4-wdt"
+- reg: base physical address and length of memory mapped region.
+
+Optional properties:
+- timeout-sec: watchdog timeout value (in seconds).
+- interrupts: interrupt number to the CPU.
+- atmel,watchdog-type: should be "hardware" or "software".
+	"hardware": enable watchdog fault reset. A watchdog fault triggers
+		    watchdog reset.
+	"software": enable watchdog fault interrupt. A watchdog fault asserts
+		    watchdog interrupt.
+- atmel,idle-halt: present if you want to stop the watchdog when the CPU is
+		   in idle state.
+	CAUTION: This property should be used with care, it actually makes the
+	watchdog not counting when the CPU is in idle state, therefore the
+	watchdog reset time depends on mean CPU usage and will not reset at all
+	if the CPU stop working while it is in idle state, which is probably
+	not what you want.
+- atmel,dbg-halt: present if you want to stop the watchdog when the CPU is
+		  in debug state.
+
+Example:
+	watchdog at fc068640 {
+		compatible = "atmel,sama5d4-wdt";
+		reg = <0xfc068640 0x10>;
+		interrupts = <4 IRQ_TYPE_LEVEL_HIGH 5>;
+		timeout-sec = <10>;
+		atmel,watchdog-type = "hardware";
+		atmel,dbg-halt;
+		atmel,idle-halt;
+		status = "okay";
+	};
-- 
1.7.9.5



From shawnguo at kernel.org  Thu Aug  6 01:46:12 2015
From: shawnguo at kernel.org (Shawn Guo)
Date: Thu, 6 Aug 2015 16:46:12 +0800
Subject: [PATCH] ARM: imx6: correct i.MX6 PCIe interrupt routing
In-Reply-To: <1438848690.24317.3.camel@pengutronix.de>
References: <1438793677-19153-1-git-send-email-l.stach@pengutronix.de>
 <20150806012832.GP12927@tiger>
 <1438848690.24317.3.camel@pengutronix.de>
Message-ID: <20150806084612.GF9847@tiger>

On Thu, Aug 06, 2015 at 10:11:30AM +0200, Lucas Stach wrote:
> Am Donnerstag, den 06.08.2015, 09:28 +0800 schrieb Shawn Guo:
> > On Wed, Aug 05, 2015 at 06:54:37PM +0200, Lucas Stach wrote:
> > > The PCIe interrupts are also routed through the GPC. This has been
> > > missed from the conversion to stacked IRQ domains as the PCIe
> > > controller uses an explicit interrupt map and thus doesn't inherit
> > > the SoC global interrupt parent.
> > > 
> > > Signed-off-by: Lucas Stach <l.stach at pengutronix.de>
> > 
> > So this is a fix and need copy stable?
> > 
> I'm a bit on the fence with this. It only fixes PCIe wake-up and I'm not
> aware of anyone using this functionality and haven't seen any bug
> reports yet.
> 
> On the other hand it is a clear fix and has practically zero chances for
> regressions, so yes please add stable 4.0+ to this.

Applied as a fix, thanks.


From tony at atomide.com  Thu Aug  6 01:48:13 2015
From: tony at atomide.com (Tony Lindgren)
Date: Thu, 6 Aug 2015 01:48:13 -0700
Subject: [PATCH 10/10] ARM: dts: omap4: Use "syscon-otghs" instead of
 "ctrl-module" in USB node
In-Reply-To: <55C21CCD.6050101@ti.com>
References: <1438702233-8027-1-git-send-email-kishon@ti.com>
 <1438702233-8027-11-git-send-email-kishon@ti.com>
 <55C1C325.5040703@ti.com> <55C1C486.6050202@ti.com>
 <55C21CCD.6050101@ti.com>
Message-ID: <20150806084812.GC4215@atomide.com>

* Kishon Vijay Abraham I <kishon at ti.com> [150805 07:28]:
> Hi Roger,
> 
> On Wednesday 05 August 2015 01:38 PM, Roger Quadros wrote:
> > On 05/08/15 11:02, Roger Quadros wrote:
> >> Kishon,
> >>
> >> On 04/08/15 18:30, Kishon Vijay Abraham I wrote:
> >>> Add "syscon-otghs" property and remove the deprecated "ctrl-module"
> >>> property from MUSB devicetree node.
> >>>
> >>> Since "omap_control_usbotg" devicetree node is no longer used, remove
> >>> it.
> >>>
> >>> Signed-off-by: Kishon Vijay Abraham I <kishon at ti.com>
> >>> ---
> >>>  arch/arm/boot/dts/omap4.dtsi |    8 +-------
> >>>  1 file changed, 1 insertion(+), 7 deletions(-)
> >>>
> >>> diff --git a/arch/arm/boot/dts/omap4.dtsi b/arch/arm/boot/dts/omap4.dtsi
> >>> index b27634d..2fb49a5 100644
> >>> --- a/arch/arm/boot/dts/omap4.dtsi
> >>> +++ b/arch/arm/boot/dts/omap4.dtsi
> >>> @@ -854,12 +854,6 @@
> >>>  			};
> >>>  		};
> >>>  
> >>> -		omap_control_usbotg: control-phy at 4a00233c {
> >>> -			compatible = "ti,control-phy-otghs";
> >>> -			reg = <0x4a00233c 0x4>;
> >>> -			reg-names = "otghs_control";
> >>> -		};
> >>> -
> >>>  		usb_otg_hs: usb_otg_hs at 4a0ab000 {
> >>>  			compatible = "ti,omap4-musb";
> >>>  			reg = <0x4a0ab000 0x7ff>;
> >>> @@ -872,7 +866,7 @@
> >>>  			multipoint = <1>;
> >>>  			num-eps = <16>;
> >>>  			ram-bits = <12>;
> >>> -			ctrl-module = <&omap_control_usbotg>;
> >>> +			syscon-otghs = <&scm_conf 0x33c>;
> >>
> >> All other properties were of the format "syscon-phy-foo".
> >> Why use a different format here?
> >>
> > 
> > Ah, looks like we don't have a dedicated phy driver for this?
> > We will need to add a PHY driver I guess then and handle this register
> > in that driver rather than in the musb driver.
> 
> I was explaining in the other thread to Tony on why this shouldn't be done in a
> PHY driver [1].

And I just suggested thhere that it should be in the drivers/phy/phy-omap-usb2.c
PHY driver instead of the MUSB driver.

Regards,

Tony 
 
> [1] -> https://lkml.org/lkml/2015/8/5/455


From monstr at monstr.eu  Thu Aug  6 01:53:21 2015
From: monstr at monstr.eu (Michal Simek)
Date: Thu, 6 Aug 2015 10:53:21 +0200
Subject: [GIT PULL] Xilinx ZynqMP DT changes for v4.3
In-Reply-To: <20150806073217.GB22787@localhost>
References: <55BB369F.4080100@monstr.eu> <20150805090016.GI6390@localhost>
 <55C225A7.9050704@monstr.eu> <20150806073217.GB22787@localhost>
Message-ID: <55C32081.5090402@monstr.eu>

On 08/06/2015 09:32 AM, Olof Johansson wrote:
> On Wed, Aug 05, 2015 at 05:03:03PM +0200, Michal Simek wrote:
>> Hi Olof,
>>
>> On 08/05/2015 11:00 AM, Olof Johansson wrote:
>>> On Fri, Jul 31, 2015 at 10:49:35AM +0200, Michal Simek wrote:
>>>> Hi,
>>>>
>>>> please pull these ARM64 DT patches to your tree.
>>>>
>>>> Thanks,
>>>> Michal
>>>>
>>>>
>>>> The following changes since commit d770e558e21961ad6cfdf0ff7df0eb5d7d4f0754:
>>>>
>>>>   Linux 4.2-rc1 (2015-07-05 11:01:52 -0700)
>>>>
>>>> are available in the git repository at:
>>>>
>>>>   https://github.com/Xilinx/linux-xlnx.git tags/zynqmp-dt-for-4.3
>>>>
>>>> for you to fetch changes up to f49310dc62f68ae9f905f9a1e42224fa23867f47:
>>>>
>>>>   ARM64: zynqmp: Move SPI nodes to the right location (2015-07-31
>>>> 10:46:34 +0200)
>>>>
>>>> ----------------------------------------------------------------
>>>> arm: Xilinx ZynqMP dt patches for v4.3
>>>>
>>>> - Add SATA, GPIO, CAN, SMMU, USB, SPI, I2C, watchdog and sdhci for zynqmp
>>>> - Sort nodes in dtsi
>>>
>>> You seem to sort these alphabetically. We normally encourage sorting by unit
>>> address instead. Was there some reason you chose alphabetical?
>>
>> Normally if you look for something you can't remember addresses but you
>> remember names that's why this sorting is more natural at least for me.
> 
> Main purpose of sorting tends to be to avoid having add-add conflicts by new
> entries going into different parts of the file. If different files are sorted
> differently (but see below), it's hard for contributors to figure out where
> they should add stuff.

This should be filtered by maintainers. I wasn't too strict for Zynq
mostly for historical reasons but ZynqMP is different case because we
have more time for doing this.
It means just doesn't matter which sorting is used. It is just necessary
to keep eyes on it. Also if you have sorting based on addresses or by
names it is pretty visible for newcomers to see the style and follow it.
If there is a mess they just follow the mess.


>> I have checked APM/EXYNOS/Juno/SPR for example (and probably others) and
>> there is no order at all.
> 
> Yeah, it's in pretty bad shape. There have been some efforts to fix sorting in
> the past, but it tends to degrade over time. I suspect part of this is due to
> some patches lacking enough context such that the tools apply them to the wrong
> part of the file. In other cases it's just neglect or forgetfulness.

I would like to sort zynq too alphabetically because as I said it is
more natural for me. Will you accept these changes?


>> If this is any strict requirement to sort nodes by addresses I am happy
>> to send patch on the top of this series to fix it. That's why please let
>> me know.
> 
> It's not a strict requirement, it's just that when others have made efforts to
> sort they have done so by unitid instead.
> 
> I'll merge this branch, it's probably not worth it to follow up with another
> reshuffle. As you say, most other files are in even worse shape so it's
> a losing battle.

Thanks.

> 
>> There are other questions what to do with clocks for example - having
>> them on the bus like it is done for us and Cavium/Exynos/Seattle or
>> having separate node on the bus like APM.
>> Using soc node is another question.
>>
>> I know that Grant wanted to update any guide which should cover these
>> stuff but I am not aware if we have any doc which describe it.
> 
> Sounds like a suitable topic for one of many DT sessions at conferences around
> the world these days, if you're attending any. It's usually easier to corner
> people at those and hash things out.

I will be in valley next month and maybe also at Linaro connect and will
probably go to KS. Definitely cleanup up this mess is interesting topic
for me.
I think that will be the best what we have done at KS at Edinburgh to
have ARM specific session to target wider audience and cleanup these
things. People tend to copy each other and if we have mess in the main
repo then this mess is just propagated down.

Another thing what we have found recently in zynq reset patch is syscon
usage in connection to using child nodes if you should explicitely
reference syscon or add dependency based on position that syscon is
parent all the time.

Definitely all these DT things should be discussed in person between arm
platform maintainers and having session somewhere will be great.

BTW: have 2 more small patches for adding reset controller. Can I send
another PR or wait for one more release?

Thanks,
Michal

-- 
Michal Simek, Ing. (M.Eng), OpenPGP -> KeyID: FE3D1F91
w: www.monstr.eu p: +42-0-721842854
Maintainer of Linux kernel - Microblaze cpu - http://www.monstr.eu/fdt/
Maintainer of Linux kernel - Xilinx Zynq ARM architecture
Microblaze U-BOOT custodian and responsible for u-boot arm zynq platform


-------------- next part --------------
A non-text attachment was scrubbed...
Name: signature.asc
Type: application/pgp-signature
Size: 198 bytes
Desc: OpenPGP digital signature
URL: <http://lists.infradead.org/pipermail/linux-arm-kernel/attachments/20150806/b0d5fdc1/attachment.sig>

From s.hauer at pengutronix.de  Thu Aug  6 01:53:54 2015
From: s.hauer at pengutronix.de (Sascha Hauer)
Date: Thu, 6 Aug 2015 10:53:54 +0200
Subject: [PATCH v6 7/9] clk: mediatek: Add subsystem clocks of MT8173
In-Reply-To: <1438849431.27884.9.camel@mtksdaap41>
References: <1438676218-11310-1-git-send-email-jamesjj.liao@mediatek.com>
 <1438676218-11310-8-git-send-email-jamesjj.liao@mediatek.com>
 <20150805064605.GZ18700@pengutronix.de>
 <1438849431.27884.9.camel@mtksdaap41>
Message-ID: <20150806085354.GN18700@pengutronix.de>

On Thu, Aug 06, 2015 at 04:23:51PM +0800, James Liao wrote:
> Hi Sascha,
> 
> On Wed, 2015-08-05 at 08:46 +0200, Sascha Hauer wrote:
> > On Tue, Aug 04, 2015 at 04:16:56PM +0800, James Liao wrote:
> > >  static const struct mtk_fixed_clk fixed_clks[] __initconst = {
> > >  	FIXED_CLK(CLK_TOP_CLKPH_MCK_O, "clkph_mck_o", "clk26m", 400 * MHZ),
> > >  	FIXED_CLK(CLK_TOP_USB_SYSPLL_125M, "usb_syspll_125m", "clk26m", 125 * MHZ),
> > > +	FIXED_CLK(CLK_TOP_DSI0_DIG, "dsi0_dig", "clk26m", 130 * MHZ),
> > > +	FIXED_CLK(CLK_TOP_DSI1_DIG, "dsi1_dig", "clk26m", 130 * MHZ),
> > > +	FIXED_CLK(CLK_TOP_LVDS_PXL, "lvds_pxl", "lvdspll", 148.5 * MHZ),
> > > +	FIXED_CLK(CLK_TOP_LVDS_CTS, "lvds_cts", "lvdspll", 51.975 * MHZ),
> > 
> > I would expect 51975 * KHZ here to avoid fractional numbers. Probably
> > gcc calculates that during compile time so this will work as expected,
> > still I'm not sure this is good style to use fractional numbers here.
> 
> As I know all constants will be calculated in compile time, so there
> should be no difference between 51.975 * MHZ and 51975 * KHz. 
> 
> > Anyway, on my system lvdspll is running at 150MHz. Are you sure there is
> > a clock derived from this running at 148.5MHz? Is it really correct to
> > use a fixed clock here or should it rather be lvdspll directly?
> 
> Here is the clock hierarchy between lvdspll and lvds_pxl:
> 
>             --------       AD_VPLL_DPIX_CK  --------   lvds_pxl  -----
>            |        |--------------------->|        |---------->|
>            |        |                      | cksys  |           |
> LVDSPLL -->| LVDSTX |                      | buffer |           | MMSYS
>            |        | AD_LVDSTX_CLKDIG_CTS | test   |  lvds_cts |
>            |        |--------------------->|        |---------->|
>             --------                        --------             -----
> 
> Some clocks and blocks are not modeled into CCF. But we prefer to enable
> lvdspll before enabling lvds_pxl. So I modeled lvds_pxl (and lvds_cts)
> as a fixed-rate clock with a source from lvdspll.
> 
> The frequency of these fixed-rate clocks (such as 148.5 MHz) are typical
> rate. In fact, we don't care about the actual rate of these clocks. We
> just care about the enable / disable sequence of them.

Please either use the real rate or 0 (along with a explaining why). Using
a frequency with four to five significant digits makes me think that the
actual rate is very important.

Sascha

-- 
Pengutronix e.K.                           |                             |
Industrial Linux Solutions                 | http://www.pengutronix.de/  |
Peiner Str. 6-8, 31137 Hildesheim, Germany | Phone: +49-5121-206917-0    |
Amtsgericht Hildesheim, HRA 2686           | Fax:   +49-5121-206917-5555 |


From jamesjj.liao at mediatek.com  Thu Aug  6 02:00:44 2015
From: jamesjj.liao at mediatek.com (James Liao)
Date: Thu, 6 Aug 2015 17:00:44 +0800
Subject: [PATCH v6 7/9] clk: mediatek: Add subsystem clocks of MT8173
In-Reply-To: <20150806085354.GN18700@pengutronix.de>
References: <1438676218-11310-1-git-send-email-jamesjj.liao@mediatek.com>
 <1438676218-11310-8-git-send-email-jamesjj.liao@mediatek.com>
 <20150805064605.GZ18700@pengutronix.de>
 <1438849431.27884.9.camel@mtksdaap41>
 <20150806085354.GN18700@pengutronix.de>
Message-ID: <1438851644.27884.21.camel@mtksdaap41>

Hi Sascha,

On Thu, 2015-08-06 at 10:53 +0200, Sascha Hauer wrote:
> On Thu, Aug 06, 2015 at 04:23:51PM +0800, James Liao wrote:
> > On Wed, 2015-08-05 at 08:46 +0200, Sascha Hauer wrote:
> > > On Tue, Aug 04, 2015 at 04:16:56PM +0800, James Liao wrote:
> > > >  static const struct mtk_fixed_clk fixed_clks[] __initconst = {
> > > >  	FIXED_CLK(CLK_TOP_CLKPH_MCK_O, "clkph_mck_o", "clk26m", 400 * MHZ),
> > > >  	FIXED_CLK(CLK_TOP_USB_SYSPLL_125M, "usb_syspll_125m", "clk26m", 125 * MHZ),
> > > > +	FIXED_CLK(CLK_TOP_DSI0_DIG, "dsi0_dig", "clk26m", 130 * MHZ),
> > > > +	FIXED_CLK(CLK_TOP_DSI1_DIG, "dsi1_dig", "clk26m", 130 * MHZ),
> > > > +	FIXED_CLK(CLK_TOP_LVDS_PXL, "lvds_pxl", "lvdspll", 148.5 * MHZ),
> > > > +	FIXED_CLK(CLK_TOP_LVDS_CTS, "lvds_cts", "lvdspll", 51.975 * MHZ),
> > > 
> > > I would expect 51975 * KHZ here to avoid fractional numbers. Probably
> > > gcc calculates that during compile time so this will work as expected,
> > > still I'm not sure this is good style to use fractional numbers here.
> > 
> > As I know all constants will be calculated in compile time, so there
> > should be no difference between 51.975 * MHZ and 51975 * KHz. 
> > 
> > > Anyway, on my system lvdspll is running at 150MHz. Are you sure there is
> > > a clock derived from this running at 148.5MHz? Is it really correct to
> > > use a fixed clock here or should it rather be lvdspll directly?
> > 
> > Here is the clock hierarchy between lvdspll and lvds_pxl:
> > 
> >             --------       AD_VPLL_DPIX_CK  --------   lvds_pxl  -----
> >            |        |--------------------->|        |---------->|
> >            |        |                      | cksys  |           |
> > LVDSPLL -->| LVDSTX |                      | buffer |           | MMSYS
> >            |        | AD_LVDSTX_CLKDIG_CTS | test   |  lvds_cts |
> >            |        |--------------------->|        |---------->|
> >             --------                        --------             -----
> > 
> > Some clocks and blocks are not modeled into CCF. But we prefer to enable
> > lvdspll before enabling lvds_pxl. So I modeled lvds_pxl (and lvds_cts)
> > as a fixed-rate clock with a source from lvdspll.
> > 
> > The frequency of these fixed-rate clocks (such as 148.5 MHz) are typical
> > rate. In fact, we don't care about the actual rate of these clocks. We
> > just care about the enable / disable sequence of them.
> 
> Please either use the real rate or 0 (along with a explaining why). Using
> a frequency with four to five significant digits makes me think that the
> actual rate is very important.

Oops, your suggestion is much different from Daniel's.

Daniel, could you help to comment about how we model these clocks?


Best regards,

James




From broonie at kernel.org  Thu Aug  6 02:02:02 2015
From: broonie at kernel.org (Mark Brown)
Date: Thu, 6 Aug 2015 10:02:02 +0100
Subject: [RFC PATCH 1/5] spi: introduce flag for memory mapped read
In-Reply-To: <CAOMqctS9Y5FxpUCCJew6+cnjH5iTvbzkH3g-8yrXs4OuS2pSGA@mail.gmail.com>
References: <1438072876-16338-1-git-send-email-vigneshr@ti.com>
 <1438072876-16338-2-git-send-email-vigneshr@ti.com>
 <20150731181745.GM20873@sirena.org.uk> <55BEF4AF.5090704@ti.com>
 <20150804155148.GR20873@sirena.org.uk> <55C0FD98.1090107@ti.com>
 <20150805115013.GJ20873@sirena.org.uk>
 <CAOMqctQXwcHyiWBwtugSDSE_k65qrNfrwnhjQMDJkLoJMmGzUw@mail.gmail.com>
 <20150805124412.GN20873@sirena.org.uk>
 <CAOMqctS9Y5FxpUCCJew6+cnjH5iTvbzkH3g-8yrXs4OuS2pSGA@mail.gmail.com>
Message-ID: <20150806090202.GO20873@sirena.org.uk>

On Wed, Aug 05, 2015 at 02:56:09PM +0200, Michal Suchanek wrote:
> On 5 August 2015 at 14:44, Mark Brown <broonie at kernel.org> wrote:
> > On Wed, Aug 05, 2015 at 02:40:01PM +0200, Michal Suchanek wrote:

> >> I don't think sending 03 or other random byte as the first byte of a
> >> SPI transfer can be used as reliable detection that we are talking to
> >> a SPI flash memory.

> > Why care - if something is physically in the same format as a flash read
> > command how would a device be able to tell that it wasn't actually a
> > flash read command?  The signals sent on the bus are going to be
> > identical anyway.

> Not only must the command be the same but also the response must be tha same.

What difference would that make?  The caller is sending a single SPI
operation and this is a user visible thing...

> The flash chip responds by sending arbitrary amount of data. Given
> that transfer_one gets only the part that sends the read command and
> the part to do the actual read may or may not follow this is getting a
> bit hairy. Add in dummy bytes due to fast-read lag and page write
> wrap-around and you get something that you definitely do not want
> unless you are really sure that there is a flash memory on the other
> end of the wire.

So if you're doing this you may have a good reason to implement
transfer_one_message() instead.  Or perhaps implement it in the core and
provide operations to do the map and unmap.  And of course if this sort
of requirement exists that's an obvious thing that must be documented
in the interfaces but isn't.

We need a lot more thought about the interface here, the lack of any
explanation of what the interface is supposed to be and the fact that
all questions about it are being answered in terms of describing the
specific system are both a bit worrying.
-------------- next part --------------
A non-text attachment was scrubbed...
Name: signature.asc
Type: application/pgp-signature
Size: 473 bytes
Desc: Digital signature
URL: <http://lists.infradead.org/pipermail/linux-arm-kernel/attachments/20150806/08a8a314/attachment.sig>

From viresh.kumar at linaro.org  Thu Aug  6 02:11:13 2015
From: viresh.kumar at linaro.org (Viresh Kumar)
Date: Thu,  6 Aug 2015 14:41:13 +0530
Subject: [PATCH] ARM/EP93xx/timer: Migrate to new 'set-state' interface
Message-ID: <744dca162a7626694770a9f51457566a33c3e08f.1438852023.git.viresh.kumar@linaro.org>

Migrate EP93xx driver to the new 'set-state' interface provided by
clockevents core, the earlier 'set-mode' interface is marked obsolete
now.

This also enables us to implement callbacks for new states of clockevent
devices, for example: ONESHOT_STOPPED.

Signed-off-by: Viresh Kumar <viresh.kumar at linaro.org>
---
Linus,

All other clockevent drivers are migrated to the new interface and yours
was left as it adapted generic clockevents framework just now.

Probably Olof can apply it directly to ARM SoC tree..

 arch/arm/mach-ep93xx/timer-ep93xx.c | 17 ++++++++++-------
 1 file changed, 10 insertions(+), 7 deletions(-)

diff --git a/arch/arm/mach-ep93xx/timer-ep93xx.c b/arch/arm/mach-ep93xx/timer-ep93xx.c
index ac48ac1fd16d..e5f791145bd0 100644
--- a/arch/arm/mach-ep93xx/timer-ep93xx.c
+++ b/arch/arm/mach-ep93xx/timer-ep93xx.c
@@ -86,19 +86,22 @@ static int ep93xx_clkevt_set_next_event(unsigned long next,
 }
 
 
-static void ep93xx_clkevt_set_mode(enum clock_event_mode mode,
-				   struct clock_event_device *evt)
+static int ep93xx_clkevt_shutdown(struct clock_event_device *evt)
 {
 	/* Disable timer */
 	writel(0, EP93XX_TIMER3_CONTROL);
+
+	return 0;
 }
 
 static struct clock_event_device ep93xx_clockevent = {
-	.name		= "timer1",
-	.features	= CLOCK_EVT_FEAT_ONESHOT,
-	.set_mode	= ep93xx_clkevt_set_mode,
-	.set_next_event	= ep93xx_clkevt_set_next_event,
-	.rating		= 300,
+	.name			= "timer1",
+	.features		= CLOCK_EVT_FEAT_ONESHOT,
+	.set_state_shutdown	= ep93xx_clkevt_shutdown,
+	.set_state_oneshot	= ep93xx_clkevt_shutdown,
+	.tick_resume		= ep93xx_clkevt_shutdown,
+	.set_next_event		= ep93xx_clkevt_set_next_event,
+	.rating			= 300,
 };
 
 static irqreturn_t ep93xx_timer_interrupt(int irq, void *dev_id)
-- 
2.4.0



From djkurtz at chromium.org  Thu Aug  6 02:13:21 2015
From: djkurtz at chromium.org (Daniel Kurtz)
Date: Thu, 6 Aug 2015 17:13:21 +0800
Subject: [PATCH v6 7/9] clk: mediatek: Add subsystem clocks of MT8173
In-Reply-To: <1438851644.27884.21.camel@mtksdaap41>
References: <1438676218-11310-1-git-send-email-jamesjj.liao@mediatek.com>
 <1438676218-11310-8-git-send-email-jamesjj.liao@mediatek.com>
 <20150805064605.GZ18700@pengutronix.de> <1438849431.27884.9.camel@mtksdaap41>
 <20150806085354.GN18700@pengutronix.de> <1438851644.27884.21.camel@mtksdaap41>
Message-ID: <CAGS+omAAYZyZJ4+eSdu2jmwThvHg1YpVoehui_cqNp4A5fURWg@mail.gmail.com>

On Thu, Aug 6, 2015 at 5:00 PM, James Liao <jamesjj.liao at mediatek.com> wrote:
> Hi Sascha,
>
> On Thu, 2015-08-06 at 10:53 +0200, Sascha Hauer wrote:
>> On Thu, Aug 06, 2015 at 04:23:51PM +0800, James Liao wrote:
>> > On Wed, 2015-08-05 at 08:46 +0200, Sascha Hauer wrote:
>> > > On Tue, Aug 04, 2015 at 04:16:56PM +0800, James Liao wrote:
>> > > >  static const struct mtk_fixed_clk fixed_clks[] __initconst = {
>> > > >         FIXED_CLK(CLK_TOP_CLKPH_MCK_O, "clkph_mck_o", "clk26m", 400 * MHZ),
>> > > >         FIXED_CLK(CLK_TOP_USB_SYSPLL_125M, "usb_syspll_125m", "clk26m", 125 * MHZ),
>> > > > +       FIXED_CLK(CLK_TOP_DSI0_DIG, "dsi0_dig", "clk26m", 130 * MHZ),
>> > > > +       FIXED_CLK(CLK_TOP_DSI1_DIG, "dsi1_dig", "clk26m", 130 * MHZ),
>> > > > +       FIXED_CLK(CLK_TOP_LVDS_PXL, "lvds_pxl", "lvdspll", 148.5 * MHZ),
>> > > > +       FIXED_CLK(CLK_TOP_LVDS_CTS, "lvds_cts", "lvdspll", 51.975 * MHZ),
>> > >
>> > > I would expect 51975 * KHZ here to avoid fractional numbers. Probably
>> > > gcc calculates that during compile time so this will work as expected,
>> > > still I'm not sure this is good style to use fractional numbers here.
>> >
>> > As I know all constants will be calculated in compile time, so there
>> > should be no difference between 51.975 * MHZ and 51975 * KHz.
>> >
>> > > Anyway, on my system lvdspll is running at 150MHz. Are you sure there is
>> > > a clock derived from this running at 148.5MHz? Is it really correct to
>> > > use a fixed clock here or should it rather be lvdspll directly?
>> >
>> > Here is the clock hierarchy between lvdspll and lvds_pxl:
>> >
>> >             --------       AD_VPLL_DPIX_CK  --------   lvds_pxl  -----
>> >            |        |--------------------->|        |---------->|
>> >            |        |                      | cksys  |           |
>> > LVDSPLL -->| LVDSTX |                      | buffer |           | MMSYS
>> >            |        | AD_LVDSTX_CLKDIG_CTS | test   |  lvds_cts |
>> >            |        |--------------------->|        |---------->|
>> >             --------                        --------             -----
>> >
>> > Some clocks and blocks are not modeled into CCF. But we prefer to enable
>> > lvdspll before enabling lvds_pxl. So I modeled lvds_pxl (and lvds_cts)
>> > as a fixed-rate clock with a source from lvdspll.
>> >
>> > The frequency of these fixed-rate clocks (such as 148.5 MHz) are typical
>> > rate. In fact, we don't care about the actual rate of these clocks. We
>> > just care about the enable / disable sequence of them.
>>
>> Please either use the real rate or 0 (along with a explaining why). Using
>> a frequency with four to five significant digits makes me think that the
>> actual rate is very important.
>
> Oops, your suggestion is much different from Daniel's.
>
> Daniel, could you help to comment about how we model these clocks?

First of all, for clocks where the rate doesn't matter, it doesn't
matters to what rate we set the clock.

As for the color of our shed, "the designer says these are the typical
rates" sounds good enough to me for a "real rate", so I prefer using
the rates in James' patch.

If not sure what Sascha's concern is, but if he insists on 0, I'm fine
with that too.

-Dan


From s.hauer at pengutronix.de  Thu Aug  6 01:59:36 2015
From: s.hauer at pengutronix.de (Sascha Hauer)
Date: Thu, 6 Aug 2015 10:59:36 +0200
Subject: [PATCH v6 5/9] clk: mediatek: Fix rate and dependency of MT8173
 clocks
In-Reply-To: <1438850132.27884.17.camel@mtksdaap41>
References: <1438676218-11310-1-git-send-email-jamesjj.liao@mediatek.com>
 <1438676218-11310-6-git-send-email-jamesjj.liao@mediatek.com>
 <20150805065341.GA18700@pengutronix.de>
 <1438850132.27884.17.camel@mtksdaap41>
Message-ID: <20150806085936.GO18700@pengutronix.de>

On Thu, Aug 06, 2015 at 04:35:32PM +0800, James Liao wrote:
> Hi Sascha,
> 
> On Wed, 2015-08-05 at 08:53 +0200, Sascha Hauer wrote:
> > On Tue, Aug 04, 2015 at 04:16:54PM +0800, James Liao wrote:
> > > -static const struct mtk_fixed_factor root_clk_alias[] __initconst = {
> > > -	FACTOR(CLK_TOP_CLKPH_MCK_O, "clkph_mck_o", "clk_null", 1, 1),
> > > -	FACTOR(CLK_TOP_USB_SYSPLL_125M, "usb_syspll_125m", "clk_null", 1, 1),
> > > -	FACTOR(CLK_TOP_HDMITX_DIG_CTS, "hdmitx_dig_cts", "clk_null", 1, 1),
> > > +static const struct mtk_fixed_clk fixed_clks[] __initconst = {
> > > +	FIXED_CLK(CLK_TOP_CLKPH_MCK_O, "clkph_mck_o", "clk26m", 400 * MHZ),
> > > +	FIXED_CLK(CLK_TOP_USB_SYSPLL_125M, "usb_syspll_125m", "clk26m", 125 * MHZ),
> > 
> > Hm, it seems you hide PLLs in fixed factor clock. Are you sure that
> > there is a PLL in the system generating 125MHz from 26MHz which is in no
> > way configurable? Or is this really some clock derived from the syspll
> > as the clock name suggests?
> 
> According to the datasheet from our clock designer, usb_syspll_125m is
> the output clock of an analog macro which is named SSUSB_PHY, and its
> input clock is AD_CLK26M_CK.
> 
> SSUSB_PHY is not the same as general PLLs such as MAINPLL. So I don't
> treat it as a configurable PLL but a fixed clock with the typical rate
> 125 MHz.

Ok then.

Sascha

-- 
Pengutronix e.K.                           |                             |
Industrial Linux Solutions                 | http://www.pengutronix.de/  |
Peiner Str. 6-8, 31137 Hildesheim, Germany | Phone: +49-5121-206917-0    |
Amtsgericht Hildesheim, HRA 2686           | Fax:   +49-5121-206917-5555 |


From b20788 at freescale.com  Thu Aug  6 09:56:22 2015
From: b20788 at freescale.com (Anson Huang)
Date: Fri, 7 Aug 2015 00:56:22 +0800
Subject: [PATCH V3] ARM: imx: add cpuidle support for i.mx6ul
Message-ID: <1438880182-6260-1-git-send-email-b20788@freescale.com>

This patch adds cpuidle support for i.MX6UL,
it shares cpuidle driver with i.MX6SX, total
3 levels of cpuidle are supported as below:

1. ARM WFI;
2. SOC in WAIT mode;
3. SOC in WAIT mode + ARM power off.

Signed-off-by: Anson Huang <b20788 at freescale.com>
---
I am NOT sure if using cpu_is_xxx() here to distinguish i.MX6UL
from i.MX6SX is good enough, as I saw many other patches
are trying to avoid using such cpu_is_xxx() API.

Obviously we have many other ways to identify if the ARM core
is a Cortex-A9 or Cortex-A7, they have different L2 cache implemented,
so cache operation is different.

Please advise if you have better idea about this point, thanks!

 arch/arm/mach-imx/cpuidle-imx6sx.c | 8 +++++++-
 arch/arm/mach-imx/mach-imx6ul.c    | 9 +++++++++
 2 files changed, 16 insertions(+), 1 deletion(-)

diff --git a/arch/arm/mach-imx/cpuidle-imx6sx.c b/arch/arm/mach-imx/cpuidle-imx6sx.c
index 3c6672b..e1ce40c 100644
--- a/arch/arm/mach-imx/cpuidle-imx6sx.c
+++ b/arch/arm/mach-imx/cpuidle-imx6sx.c
@@ -1,5 +1,5 @@
 /*
- * Copyright (C) 2014 Freescale Semiconductor, Inc.
+ * Copyright (C) 2014-2015 Freescale Semiconductor, Inc.
  *
  * This program is free software; you can redistribute it and/or modify
  * it under the terms of the GNU General Public License version 2 as
@@ -9,14 +9,20 @@
 #include <linux/cpuidle.h>
 #include <linux/cpu_pm.h>
 #include <linux/module.h>
+#include <asm/cacheflush.h>
 #include <asm/cpuidle.h>
 #include <asm/suspend.h>
 
 #include "common.h"
 #include "cpuidle.h"
+#include "hardware.h"
 
 static int imx6sx_idle_finish(unsigned long val)
 {
+	/* flush internal L2 cache if necessary */
+	if (cpu_is_imx6ul())
+		flush_cache_all();
+
 	cpu_do_idle();
 
 	return 0;
diff --git a/arch/arm/mach-imx/mach-imx6ul.c b/arch/arm/mach-imx/mach-imx6ul.c
index f206506..3fe37ab 100644
--- a/arch/arm/mach-imx/mach-imx6ul.c
+++ b/arch/arm/mach-imx/mach-imx6ul.c
@@ -11,6 +11,7 @@
 #include <asm/mach/map.h>
 
 #include "common.h"
+#include "cpuidle.h"
 
 static void __init imx6ul_init_machine(void)
 {
@@ -29,6 +30,13 @@ static void __init imx6ul_init_irq(void)
 	imx_init_revision_from_anatop();
 	imx_src_init();
 	irqchip_init();
+	imx6_pm_ccm_init("fsl,imx6ul-ccm");
+}
+
+static void __init imx6ul_init_late(void)
+{
+	/* share cpuidle driver with i.MX6SX */
+	imx6sx_cpuidle_init();
 }
 
 static const char *imx6ul_dt_compat[] __initconst = {
@@ -40,4 +48,5 @@ DT_MACHINE_START(IMX6UL, "Freescale i.MX6 Ultralite (Device Tree)")
 	.init_irq	= imx6ul_init_irq,
 	.init_machine	= imx6ul_init_machine,
 	.dt_compat	= imx6ul_dt_compat,
+	.init_late	= imx6ul_init_late,
 MACHINE_END
-- 
1.9.1



From Govindraj.Raja at imgtec.com  Thu Aug  6 02:05:52 2015
From: Govindraj.Raja at imgtec.com (Govindraj Raja)
Date: Thu, 6 Aug 2015 09:05:52 +0000
Subject: [RFC PATCH v4 3/9] mips: pistachio_defconfig: remove
 CONFIG_MMC_DW_IDMAC
In-Reply-To: <1438843515-23935-1-git-send-email-shawn.lin@rock-chips.com>
References: <1438843469-23807-1-git-send-email-shawn.lin@rock-chips.com>
 <1438843515-23935-1-git-send-email-shawn.lin@rock-chips.com>
Message-ID: <4BF5E8683E87FC4DA89822A5A3EB60CB6F2001@hhmail02.hh.imgtec.org>



> -----Original Message-----
> From: Shawn Lin [mailto:shawn.lin at rock-chips.com]
> Sent: 06 August 2015 07:45 AM
> To: jh80.chung at samsung.com; ulf.hansson at linaro.org
> Cc: heiko at sntech.de; dianders at chromium.org; Vineet.Gupta1 at synopsys.com;
> Wei Xu; Joachim Eastwood; Alexey Brodkin; Kukjin Kim; Krzysztof Kozlowski;
> Russell King; Jun Nie; Ralf Baechle; Govindraj Raja; linux-arm-
> kernel at lists.infradead.org; linux-samsung-soc at vger.kernel.org; linux-
> mips at linux-mips.org; linux-mmc at vger.kernel.org; linux-
> kernel at vger.kernel.org; linux-rockchip at lists.infradead.org;
> devicetree at vger.kernel.org; Shawn Lin
> Subject: [RFC PATCH v4 3/9] mips: pistachio_defconfig: remove
> CONFIG_MMC_DW_IDMAC
> 
> DesignWare MMC Controller's transfer mode should be decided at runtime
> instead of compile-time. So we remove this config option and read dw_mmc's
> register to select DMA master.
> 
> Signed-off-by: Shawn Lin <shawn.lin at rock-chips.com>
> ---
> 
> Changes in v4: None
> Changes in v3: None
> Changes in v2: None
> 
>  arch/mips/configs/pistachio_defconfig | 1 -
>  1 file changed, 1 deletion(-)

Acked-by: Govindraj Raja <govindraj.raja at imgtec.com>

--
Thanks,
Govindraj.R




From 21cnbao at gmail.com  Thu Aug  6 02:53:16 2015
From: 21cnbao at gmail.com (Barry Song)
Date: Thu, 6 Aug 2015 17:53:16 +0800
Subject: [PATCH 5/7] clk: atlas7: fix the clock tree for bluetooth stuff
In-Reply-To: <55C2BBED.4050608@codeaurora.org>
References: <1438064845-17894-1-git-send-email-21cnbao@gmail.com>
 <1438064845-17894-6-git-send-email-21cnbao@gmail.com>
 <55B7FD22.10609@codeaurora.org>
 <CAGsJ_4wg1+5KrwTJRzE-iaSTvgvgFrM6cDyUTL16gx6Hk+tdPw@mail.gmail.com>
 <55C2BBED.4050608@codeaurora.org>
Message-ID: <CAGsJ_4xVfN88Sp5LdtakndSkHucfm-c9p2jkizvCb_qhOnj0hw@mail.gmail.com>

2015-08-06 9:44 GMT+08:00 Stephen Boyd <sboyd at codeaurora.org>:
> On 07/29/2015 07:52 AM, Barry Song wrote:
>>
>> 2015-07-29 6:07 GMT+08:00 Stephen Boyd <sboyd at codeaurora.org>:
>>>
>>> On 07/27/2015 11:27 PM, Barry Song wrote:
>>>>
>>>> From: Guo Zeng <guo.zeng at csr.com>
>>>>
>>>> normally dmac should depends on only one clock, to operate
>>>> dmac internal register, but dmac4 is very special case, it
>>>> normally dmac should depends on only one clock, to operate
>>>> dmac internal register, but dmac4 is very special case, it
>>>
>>> The sentence is duplicated twice here
>>>
>>>> depends on two additional clock, the reason is that dmac4
>>>> is wrapped in hw into bt a7ca module, and accessing dmac4
>>>> internal register would also require that the a7ca_io and
>>>> related bt macro io clk also enabled.
>>>> here workaround this by setting depend clk into parent of
>>>> dmac4, and also related clks, to reflect dependency.
>>>
>>> We don't put clocks as parents of other clocks just because the child
>>> depends on the parent to be accessed. It isn't very clear from the
>>> description, but it sounds like a7ca_io is just another clock that the
>>> bluetooth driver needs to control? We want to express the true clk
>>> hierarchy, not some psuedo dependency tree.
>>>
>> Stephen, generically i agree the codes should be a map of real
>> hardware connection. here the problem is real hardware connection is
>> very much difficult for its drivers implementation and these clocks
>> are buggy designed in HW. they are not a tree, they are a "network".
>>
>> see attached diagram(hope LKML will not reject the attachment), we are
>> not a tree,  that means btm_noc_clk depends on btm_io_clk, a7ca_io_clk
>> depends on btm_io_clk, dmac4_io_clk depends on btm_noc_clk,
>> a7ca_io_clk and btm_noc_clk....
>> usp3_io_clk depends on uart6_io_clk, dmac4_io_clk, btm_noc_clk,
>> a7ca_io_clk and btm_noc_clk.
>>
>> so in the driver, we have a choice as below:
>> in uart6 driver, we take all of the clocks.
>> in dmac4 driver, we take all of btm_noc_clk, a7ca_io_clk and btm_noc_clk.
>> ...
>> what a ugly code! that is what we did before.
>>
>> so here, we moved to do a not-real clock tree,  that means
>> we makes
>> 1.btm_io_clk the parent of btm_noc_clk
>> 2. btm_noc_clk the parent of a7ca_io_clk
>> 3. a7ca_io_clk the parent of dmac4_io_clk
>> ...
>>
>> but it doesn't break any dependency of these clocks, and make all
>> clients driver as clean as a simple tree.
>> i strongly think we should keep this "workaround", otherwise, we have
>> many pain in all of the related drivers.
>>
>>
>
> Thanks for the nice PNG. It seems like you have a typical bus topology where

i feel very happy you can read this diagram carefully, then we can do
some deeper discussion.

> UART and USP need to go through DMAC and the Data NOC to get out on the
> system bus.

actually only uart6 and usp3 need to go through DMAC and the Data NOC
to get out on the
system bus. so you know how painful it is to change uart and usp
drivers to only put some
strange clocks for one node, but keep others nodes have normal clock tree?

the code might be as below:
https://git.kernel.org/cgit/linux/kernel/git/torvalds/linux.git/commit/?id=52bec4ed4ef83f1a14dbcfd1a97e35f77c6e261e

but after moving to this clock workaround we are talking about, we
reverted the above patch:
https://git.kernel.org/cgit/linux/kernel/git/torvalds/linux.git/commit/?id=4b8038dca0c0ccf5e4689cc4fbbbf4f3728304be

we got a beautiful uart driver.

> btm_io_clk is the true parent of all the clocks

right, btm_io_clk is the true parent of all the clocks

>
> I can only guess that A7CA is some sort of device that you have to go
> through from the CPU side to access the UART, USP, and DMAC hardware blocks.
> Is that right? Can you please describe what each of these blocks do and if
> there are linux drivers for them?

a7ca is bluetooth module embedded in the chip.
uart, usp(can be a general serial port), dmac have linux drivers in:
1. drivers/tty/serial/sirfsoc_uart.c
2. drivers/dma/sirf-dma.c

>
> One way to model this would be to make UART and USP children of the DMAC
> hardware block. And then make a driver/device up for the NOC and have the
> DMAC be a child of the NOC device. Then the NOC would probe and be runtime
> PM enabled to turn on the btm_noc_clk whenever it or its children are
> enabled. Then the DMAC device would do the same thing, but with the
> dmac4_io_clk, and the UART and USP devices would get the uart6_io_clk and
> usp3_io_clk respectively and enable/disable them when the device is active.
>
> That leaves us with the a7ca_io_clk, which is really just the clock for a
> bus that register read/writes go through. In designs I've seen, I usually
> left that clock under the control of each individual device that sits on the
> bus. So in this case, the DMAC, USP and UART device drivers would all need
> to get the a7ca_io_clk as their "interface" clock and make sure to enable or
> disable it whenever the driver wants to read/write the registers. I'm not
> sure if something else is done on the APB for you, but that may be all
> that's necessary.
>
> This actually points out a big problem we have right now in Linux, which is
> the lack of proper power management for the type of bus topology you see in
> embedded systems. Some of the genpd work going on may also be another
> solution to this problem, where we could group multiple devices into generic
> power domains that know to turn on 2 or 3 of the clocks. For example, the
> DMAC, USP, and UART device could all be in the APB power domain so that the
> a7ca_io_clk is enabled whenever one of those devices is active. And there
> could be another power domain for the NOC that encompasses all devices that
> are sitting on that NOC.
>
> Long story short, solving these sorts of problems in the clk framework is
> typically the easy route that people take, although it's the wrong route.
> We're not expressing these sorts of complicated bus topologies in the clk
> framework. We're only expressing the clk tree (which is already quite
> complicated enough). Your drivers can still be simple, but don't make it
> more complicated than it has to be in the clk framework for that.
>

it does explain the current situation well. but how painful it is to
express this kind of bus in any driver subsystem.
for exmaple, to access usp3, clocks in the whole topo should be open.
but it seems the whole topo should not
be visible to the client driver like uart/dmac4.

if we stand in the position of dmac4, it only needs to know its clock
should be enabled, why it needs to know
the complex topo in the complex bus?

so the below two are both wrong

1. take many clocks in the uart, dmac driver
2. ignore the topo and "simulate" one simple clk tree

if we have to choice one, i prefer it is 2.

-barry


From catalin.marinas at arm.com  Thu Aug  6 02:56:21 2015
From: catalin.marinas at arm.com (Catalin Marinas)
Date: Thu, 6 Aug 2015 10:56:21 +0100
Subject: [PATCH v3 15/31] arm64: SMP support
In-Reply-To: <CAOZdJXVoDJM3y2mnKO+91yf2EHogKfMjumjhhi85REAfhcJM=Q@mail.gmail.com>
References: <1347035226-18649-1-git-send-email-catalin.marinas@arm.com>
 <1347035226-18649-16-git-send-email-catalin.marinas@arm.com>
 <CAOZdJXVoDJM3y2mnKO+91yf2EHogKfMjumjhhi85REAfhcJM=Q@mail.gmail.com>
Message-ID: <20150806095621.GB17691@e104818-lin.cambridge.arm.com>

On Wed, Aug 05, 2015 at 05:46:03PM -0700, Timur Tabi wrote:
> Catalin,
> 
> I know this patch is three years old, but I have a question about it:
> 
> On Fri, Sep 7, 2012 at 9:26 AM, Catalin Marinas <catalin.marinas at arm.com> wrote:
> > +static void ipi_cpu_stop(unsigned int cpu)
> > +{
> > +       if (system_state == SYSTEM_BOOTING ||
> > +           system_state == SYSTEM_RUNNING) {
> > +               raw_spin_lock(&stop_lock);
> > +               pr_crit("CPU%u: stopping\n", cpu);
> > +               dump_stack();
> > +               raw_spin_unlock(&stop_lock);
> > +       }
> > +
> > +       set_cpu_online(cpu, false);
> > +
> > +       local_fiq_disable();
> > +       local_irq_disable();
> > +
> > +       while (1)
> > +               cpu_relax();
> > +}
> 
> Why do you display a message and dump the stack when a CPU is stopped?
>  I ask because emergency_restart() calls this function, and so
> whenever I want to do an "emergency" reboot, it dumps the stack for
> each core.  On an ARM64 system with lots of cores, this produces a ton
> of output.  That makes emergency_restart() almost useless.

This code was inherited from arch/arm which initially was always dumping
the stack but it later gained the system_state check. Unless it's useful
to anyone for debugging purposes, I'm ok with removing it.

-- 
Catalin


From linux at roeck-us.net  Thu Aug  6 02:59:47 2015
From: linux at roeck-us.net (Guenter Roeck)
Date: Thu, 06 Aug 2015 02:59:47 -0700
Subject: [PATCH v5 1/2] drivers: watchdog: add a driver to support SAMA5D4
 watchdog timer
In-Reply-To: <1438850055-30104-2-git-send-email-wenyou.yang@atmel.com>
References: <1438850055-30104-1-git-send-email-wenyou.yang@atmel.com>
 <1438850055-30104-2-git-send-email-wenyou.yang@atmel.com>
Message-ID: <55C33013.6020002@roeck-us.net>

Hi,

On 08/06/2015 01:34 AM, Wenyou Yang wrote:
>>From SAMA5D4, the watchdog timer is upgrated with a new feature,

Where does the additional ">" come from ?

> which is describled as in the datasheet, "WDT_MR can be written
> until a LOCKMR command is issued in WDT_CR".
> That is to say, as long as the bootstrap and u-boot don't issue
> a LOCKMR command, WDT_MR can be written more than once in the driver.
>
> So the SAMA5D4 watchdog driver's implementation is different from
> the at91sam9260 watchdog driver implemented in file at91sam9_wdt.c.
> The user application open the device file to enable the watchdog timer
> hardware, and close to disable it, and set the watchdog timer timeout
> by seting WDV and WDD fields of WDT_MR register, and ping the watchdog
> by issuing WDRSTT command to WDT_CR register with hard-coded key.
>
> Signed-off-by: Wenyou Yang <wenyou.yang at atmel.com>
> ---
>   drivers/watchdog/Kconfig        |    9 ++
>   drivers/watchdog/Makefile       |    1 +
>   drivers/watchdog/at91sam9_wdt.h |    2 +
>   drivers/watchdog/sama5d4_wdt.c  |  280 +++++++++++++++++++++++++++++++++++++++
>   4 files changed, 292 insertions(+)
>   create mode 100644 drivers/watchdog/sama5d4_wdt.c
>
> diff --git a/drivers/watchdog/Kconfig b/drivers/watchdog/Kconfig
> index e5e7c55..47ad39a 100644
> --- a/drivers/watchdog/Kconfig
> +++ b/drivers/watchdog/Kconfig
> @@ -167,6 +167,15 @@ config AT91SAM9X_WATCHDOG
>   	  Watchdog timer embedded into AT91SAM9X and AT91CAP9 chips. This will
>   	  reboot your system when the timeout is reached.
>
> +config SAMA5D4_WATCHDOG
> +	tristate "Atmel SAMA5D4 Watchdog Timer"
> +	depends on ARCH_AT91
> +	select WATCHDOG_CORE
> +	help
> +	  Atmel SAMA5D4 watchdog timer is embedded into SAMA5D4 chips.
> +	  Its Watchdog Timer Mode Register can be written more than once.
> +	  This will reboot your system when the timeout is reached.
> +
>   config CADENCE_WATCHDOG
>   	tristate "Cadence Watchdog Timer"
>   	select WATCHDOG_CORE
> diff --git a/drivers/watchdog/Makefile b/drivers/watchdog/Makefile
> index 5c19294..f24b820 100644
> --- a/drivers/watchdog/Makefile
> +++ b/drivers/watchdog/Makefile
> @@ -41,6 +41,7 @@ obj-$(CONFIG_IXP4XX_WATCHDOG) += ixp4xx_wdt.o
>   obj-$(CONFIG_KS8695_WATCHDOG) += ks8695_wdt.o
>   obj-$(CONFIG_S3C2410_WATCHDOG) += s3c2410_wdt.o
>   obj-$(CONFIG_SA1100_WATCHDOG) += sa1100_wdt.o
> +obj-$(CONFIG_SAMA5D4_WATCHDOG) += sama5d4_wdt.o
>   obj-$(CONFIG_DW_WATCHDOG) += dw_wdt.o
>   obj-$(CONFIG_EP93XX_WATCHDOG) += ep93xx_wdt.o
>   obj-$(CONFIG_PNX4008_WATCHDOG) += pnx4008_wdt.o
> diff --git a/drivers/watchdog/at91sam9_wdt.h b/drivers/watchdog/at91sam9_wdt.h
> index c6fbb2e6..b79a83b 100644
> --- a/drivers/watchdog/at91sam9_wdt.h
> +++ b/drivers/watchdog/at91sam9_wdt.h
> @@ -22,11 +22,13 @@
>
>   #define AT91_WDT_MR		0x04			/* Watchdog Mode Register */
>   #define		AT91_WDT_WDV		(0xfff << 0)		/* Counter Value */
> +#define			AT91_WDT_SET_WDV(x)	((x) & AT91_WDT_WDV)
>   #define		AT91_WDT_WDFIEN		(1     << 12)		/* Fault Interrupt Enable */
>   #define		AT91_WDT_WDRSTEN	(1     << 13)		/* Reset Processor */
>   #define		AT91_WDT_WDRPROC	(1     << 14)		/* Timer Restart */
>   #define		AT91_WDT_WDDIS		(1     << 15)		/* Watchdog Disable */
>   #define		AT91_WDT_WDD		(0xfff << 16)		/* Delta Value */
> +#define			AT91_WDT_SET_WDD(x)	(((x) << 16) & AT91_WDT_WDD)
>   #define		AT91_WDT_WDDBGHLT	(1     << 28)		/* Debug Halt */
>   #define		AT91_WDT_WDIDLEHLT	(1     << 29)		/* Idle Halt */
>
> diff --git a/drivers/watchdog/sama5d4_wdt.c b/drivers/watchdog/sama5d4_wdt.c
> new file mode 100644
> index 0000000..a412215
> --- /dev/null
> +++ b/drivers/watchdog/sama5d4_wdt.c
> @@ -0,0 +1,280 @@
> +/*
> + * Driver for Atmel SAMA5D4 Watchdog Timer
> + *
> + * Copyright (C) 2015 Atmel Corporation
> + *
> + * Licensed under GPLv2.
> + */
> +
> +#include <linux/interrupt.h>
> +#include <linux/io.h>
> +#include <linux/kernel.h>
> +#include <linux/module.h>
> +#include <linux/of.h>
> +#include <linux/of_irq.h>
> +#include <linux/platform_device.h>
> +#include <linux/reboot.h>
> +#include <linux/watchdog.h>
> +
> +#include "at91sam9_wdt.h"
> +
> +/* minimum and maximum watchdog timeout, in seconds */
> +#define MIN_WDT_TIMEOUT		1
> +#define MAX_WDT_TIMEOUT		16
> +#define WDT_DEFAULT_TIMEOUT	MAX_WDT_TIMEOUT
> +
> +#define WDT_SEC2TICKS(s)	((s) ? (((s) << 8) - 1) : 0)
> +
> +struct sama5d4_wdt {
> +	struct watchdog_device	wdd;
> +	void __iomem		*reg_base;
> +	u32	config;
> +};
> +
> +static int wdt_timeout = WDT_DEFAULT_TIMEOUT;
> +static bool nowayout = WATCHDOG_NOWAYOUT;
> +
> +module_param(wdt_timeout, int, 0);
> +MODULE_PARM_DESC(wdt_timeout,
> +	"Watchdog timeout in seconds. (default = "
> +	__MODULE_STRING(WDT_DEFAULT_TIMEOUT) ")");
> +
> +module_param(nowayout, bool, 0);
> +MODULE_PARM_DESC(nowayout,
> +	"Watchdog cannot be stopped once started (default="
> +	__MODULE_STRING(WATCHDOG_NOWAYOUT) ")");
> +
> +#define wdt_read(wdt, field) \
> +	readl_relaxed((wdt)->reg_base + (field))
> +
> +#define wdt_write(wtd, field, val) \
> +	writel_relaxed((val), (wdt)->reg_base + (field))
> +
> +static int sama5d4_wdt_start(struct watchdog_device *wdd)
> +{
> +	struct sama5d4_wdt *wdt = watchdog_get_drvdata(wdd);
> +	u32 reg;
> +
> +	reg = wdt_read(wdt, AT91_WDT_MR);
> +	reg &= ~AT91_WDT_WDDIS;
> +	wdt_write(wdt, AT91_WDT_MR, reg);
> +
> +	return 0;
> +}
> +
> +static int sama5d4_wdt_stop(struct watchdog_device *wdd)
> +{
> +	struct sama5d4_wdt *wdt = watchdog_get_drvdata(wdd);
> +	u32 reg;
> +
> +	reg = wdt_read(wdt, AT91_WDT_MR);
> +	reg |= AT91_WDT_WDDIS;
> +	wdt_write(wdt, AT91_WDT_MR, reg);
> +
> +	return 0;
> +}
> +
> +static int sama5d4_wdt_ping(struct watchdog_device *wdd)
> +{
> +	struct sama5d4_wdt *wdt = watchdog_get_drvdata(wdd);
> +
> +	wdt_write(wdt, AT91_WDT_CR, AT91_WDT_KEY | AT91_WDT_WDRSTT);
> +
> +	return 0;
> +}
> +
> +static int sama5d4_wdt_set_timeout(struct watchdog_device *wdd,
> +				 unsigned int timeout)
> +{
> +	struct sama5d4_wdt *wdt = watchdog_get_drvdata(wdd);
> +	u32 value = WDT_SEC2TICKS(timeout);
> +	u32 reg;
> +
> +	reg = wdt_read(wdt, AT91_WDT_MR);
> +	reg &= ~AT91_WDT_WDV;
> +	reg &= ~AT91_WDT_WDD;
> +	reg |= AT91_WDT_SET_WDV(value);
> +	reg |= AT91_WDT_SET_WDD(value);
> +	wdt_write(wdt, AT91_WDT_MR, reg);
> +
> +	wdd->timeout = timeout;
> +
> +	return 0;
> +}
> +
> +static const struct watchdog_info sama5d4_wdt_info = {
> +	.options = WDIOF_SETTIMEOUT | WDIOF_MAGICCLOSE | WDIOF_KEEPALIVEPING,
> +	.identity = "Atmel SAMA5D4 Watchdog"
> +};
> +
> +static struct watchdog_ops sama5d4_wdt_ops = {
> +	.owner = THIS_MODULE,
> +	.start = sama5d4_wdt_start,
> +	.stop = sama5d4_wdt_stop,
> +	.ping = sama5d4_wdt_ping,
> +	.set_timeout = sama5d4_wdt_set_timeout

You made another silent change in v4: You dropped the comma here,
and above after .identity. Now, while it makes sense to have no comma
after "{ }", it does make sense to have the comma here, because it
avoids unnecessary conflicts and build errors later on if a member
is added at the end of the list. Please add those commas back in.

Also, please stop making silent changes like this. You are making
it really hard to review your code - now I'll have to go through
it line by line again and compare it with your earlier patches to see
if you made any other unannounced changes.

Thanks,
Guenter



From hramrach at gmail.com  Thu Aug  6 03:01:37 2015
From: hramrach at gmail.com (Michal Suchanek)
Date: Thu, 6 Aug 2015 12:01:37 +0200
Subject: [RFC PATCH 1/5] spi: introduce flag for memory mapped read
In-Reply-To: <20150806090202.GO20873@sirena.org.uk>
References: <1438072876-16338-1-git-send-email-vigneshr@ti.com>
 <1438072876-16338-2-git-send-email-vigneshr@ti.com>
 <20150731181745.GM20873@sirena.org.uk>
 <55BEF4AF.5090704@ti.com> <20150804155148.GR20873@sirena.org.uk>
 <55C0FD98.1090107@ti.com> <20150805115013.GJ20873@sirena.org.uk>
 <CAOMqctQXwcHyiWBwtugSDSE_k65qrNfrwnhjQMDJkLoJMmGzUw@mail.gmail.com>
 <20150805124412.GN20873@sirena.org.uk>
 <CAOMqctS9Y5FxpUCCJew6+cnjH5iTvbzkH3g-8yrXs4OuS2pSGA@mail.gmail.com>
 <20150806090202.GO20873@sirena.org.uk>
Message-ID: <CAOMqctQZRZ4zG_yYy=CeX3DX4NVNWN1COP4Q-2YvMun9xYOA7g@mail.gmail.com>

On 6 August 2015 at 11:02, Mark Brown <broonie at kernel.org> wrote:
> On Wed, Aug 05, 2015 at 02:56:09PM +0200, Michal Suchanek wrote:
>> On 5 August 2015 at 14:44, Mark Brown <broonie at kernel.org> wrote:
>> > On Wed, Aug 05, 2015 at 02:40:01PM +0200, Michal Suchanek wrote:
>
>> >> I don't think sending 03 or other random byte as the first byte of a
>> >> SPI transfer can be used as reliable detection that we are talking to
>> >> a SPI flash memory.
>
>> > Why care - if something is physically in the same format as a flash read
>> > command how would a device be able to tell that it wasn't actually a
>> > flash read command?  The signals sent on the bus are going to be
>> > identical anyway.
>
>> Not only must the command be the same but also the response must be tha same.
>
> What difference would that make?  The caller is sending a single SPI
> operation and this is a user visible thing...
>
>> The flash chip responds by sending arbitrary amount of data. Given
>> that transfer_one gets only the part that sends the read command and
>> the part to do the actual read may or may not follow this is getting a
>> bit hairy. Add in dummy bytes due to fast-read lag and page write
>> wrap-around and you get something that you definitely do not want
>> unless you are really sure that there is a flash memory on the other
>> end of the wire.
>
> So if you're doing this you may have a good reason to implement
> transfer_one_message() instead.  Or perhaps implement it in the core and
> provide operations to do the map and unmap.  And of course if this sort
> of requirement exists that's an obvious thing that must be documented
> in the interfaces but isn't.
>
> We need a lot more thought about the interface here, the lack of any
> explanation of what the interface is supposed to be and the fact that
> all questions about it are being answered in terms of describing the
> specific system are both a bit worrying.

Disclaimer: I am not familiar with the hardware for which this patch
adds support.

However, I am familiar m25p80.c and as I understand it the controller
is basically supposed to implement m25p80.c in hardware when this flag
is set.

If I was using m25p80.c to talk to anything but an actual flash chip
it would get me quite worried.

Thanks

Michal


From s.hauer at pengutronix.de  Thu Aug  6 03:03:11 2015
From: s.hauer at pengutronix.de (Sascha Hauer)
Date: Thu, 6 Aug 2015 12:03:11 +0200
Subject: [PATCH v3 3/8] soc: Mediatek: Add SCPSYS CPU power domain driver
In-Reply-To: <1438829942.9435.24.camel@mtkswgap22>
References: <1438696464-59858-1-git-send-email-scott.shu@mediatek.com>
 <1438696464-59858-4-git-send-email-scott.shu@mediatek.com>
 <20150805085034.GG18700@pengutronix.de>
 <1438829942.9435.24.camel@mtkswgap22>
Message-ID: <20150806100311.GP18700@pengutronix.de>

On Thu, Aug 06, 2015 at 10:59:02AM +0800, Scott Shu wrote:
> On Wed, 2015-08-05 at 10:50 +0200, Sascha Hauer wrote:
> > don't do this then it indeed doesn't make much sense to put it into the
> > same file.
> > 
> > From what I see we would need to change the prototype to something like
> > 
> > static int __scpsys_power_on(struct scp_domain_data *)
> > 
> > (maybe with some additional base addresses and stuff)
> > 
> > struct scp_domain_data would additionally need sram_isoint_b and sram_ckiso
> > members.
> > 
> > Sascha
> > 
> Hi Sascha,
>    The CPU power sequence is quite different with the others, as
> described below.
> 
> * Non-CPU
>    1) Set PWR_ON_BIT, PWR_ON_2ND_BIT
>    2) Wait PWR_ACK
>    3) Clear PWR_CLK_DIS_BIT
>    4) Clear PWR_ISO_BIT
>    5) Set PWR_RST_B_BIT
>    6) Clear SRAM_PDN
>    7) Wait SRAM_PDN_ACK
> * CPU
>    1) Set PWR_ON_BIT, PWR_ON_2ND_BIT
>    2) Wait PWR_ACK
>    3) Clear PWR_ISO_BIT
>    4) Clear L1_PDN to power on L1
>    5) Wait L1_PDN_ACK
>    6) Set SRAM_ISOINT_B
>    7) Clear SRAM_CKISO
>    8) Clear PWR_CLK_DIS
>    9) Set PWR_RST_B
> For multi-cluster SoC, the cluster power sequence is also different.
> 
> Please think if this is a good idea if we integrate the CPU support into
> the scpsys_power_on()? Based on the readability and compatible
> considerations, we provide this patch.

Maybe it's best if you go back to the v1 layout and put your scpsys code
to arch/arm/mach-mediatek/. While I think it's possible to share some
more code I am not sure anymore if this buys us something. We'll know in
the future.

Sascha


-- 
Pengutronix e.K.                           |                             |
Industrial Linux Solutions                 | http://www.pengutronix.de/  |
Peiner Str. 6-8, 31137 Hildesheim, Germany | Phone: +49-5121-206917-0    |
Amtsgericht Hildesheim, HRA 2686           | Fax:   +49-5121-206917-5555 |


From Liviu.Dudau at arm.com  Thu Aug  6 03:16:37 2015
From: Liviu.Dudau at arm.com (Liviu Dudau)
Date: Thu, 6 Aug 2015 11:16:37 +0100
Subject: [PATCH 3/4] arm64: Juno: Add HDLCD support to the Juno boards.
In-Reply-To: <20150805214854.GC7557@n2100.arm.linux.org.uk>
References: <1438784892-27888-1-git-send-email-Liviu.Dudau@arm.com>
 <1438784892-27888-4-git-send-email-Liviu.Dudau@arm.com>
 <20150805175303.GB7557@n2100.arm.linux.org.uk>
 <20150805190312.GA31066@e106497-lin.cambridge.arm.com>
 <20150805214854.GC7557@n2100.arm.linux.org.uk>
Message-ID: <20150806101637.GI20890@e106497-lin.cambridge.arm.com>

On Wed, Aug 05, 2015 at 10:48:54PM +0100, Russell King - ARM Linux wrote:
> On Wed, Aug 05, 2015 at 08:03:12PM +0100, Liviu Dudau wrote:
> > I have to confess that I am not entirely up to speed with the TDA19988
> > situation at the moment. Andrew Jackson was dealing with that and
> > working with Jean to get that in the upstream, but his contract has
> > ended and he has moved to other things.
> 
> Umm, I'm the maintainer for TDA998x:
> 
> NXP TDA998X DRM DRIVER
> M:      Russell King <rmk+kernel at arm.linux.org.uk>
> S:      Supported
> F:      drivers/gpu/drm/i2c/tda998x_drv.c
> F:      include/drm/i2c/tda998x.h
> 
> It would be nice if people worked with the actual maintainers of things
> rather than random other people...

Sorry, it was my mistake, I have blindly followed the get_maintainers.pl
generated list of email rather than engage my brain and realise that part
of the patch also affects TDA19988 driver.

> 
> > > Also, the whole question of representing connectors in a DRM model is
> > > yet to be established.  Yes, DT should describe the hardware, but we
> > > don't yet know _how_ to describe physical connectors with stuff
> > > implemented on top of DRM yet, and we have nothing that makes use of
> > > this.
> > 
> > Please help me understand the current situation: you have added
> > support for components that the video drivers can use and the bindings
> > for that are described in Documentation/devicetree/bindings/media/video-interfaces.txt.
> 
> No.  I added the component helpers, which are entirely firmware agnostic.
> The media bindings were created by others, and through development done
> by Pengutronix, they were factored out of media into common DT code and
> re-used for the IMX DRM driver.  The binding document which describes
> that work is not the one you refer to above, but this one:
> 
> Documentation/devicetree/bindings/graph.txt
> 
> This started them as a basis for DRM drivers on ARM - but it's never been
> officially "adopted" as a method to describe DRM drivers - it's only what
> some drivers are using.  It ought to be nailed down as a way to ensure
> inter-operability between components though, but no one has really made
> that decision.

OK, I'm interested on whom do I need to talk to in order for the official
"adoption" to happen here. 

> 
> > According to that document my patch should be compliant once I add the
> > reg= property. Is that something that cannot be used with tda998x driver
> > or is there any other reason why you think the patch is not compliant?
> 
> Jean's proposal to add audio support to the TDA998x driver does it via
> this change to the binding spec:
> 
> +Optional nodes:
> +
> +  - port: up to three ports.
> +       The ports are defined according to [1].
> +
> +    Video port.
> +       There may be only one video port.
> +       This one must contain the following property:
> +
> +       - port-type: must be "rgb"
> +
> +       and may contain the optional property:
> +
> +       - reg: 24 bits value which defines how the video controller
> +               output is wired to the TDA998x input (video pins)
> +               When absent, the default value is <0x230145>.
> +
> +    Audio ports.
> +       There may be one or two audio ports.
> +       These ones must contain the following properties:
> +
> +       - port-type: must be "i2s" or "spdif"
> +
> +       - reg: 8 bits value which defines how the audio controller
> +               output is wired to the TDA998x input (audio pins)
> +
> +[1] Documentation/devicetree/bindings/graph.txt
> 
> (That's not a particularly precise definition, but it's what we have at
> the moment.)
> 
> > If you are referring to connecting an encoder with a HDMI connector, I
> > have tested that and it seems to work, although my situation is simple
> > because there are no options in my setup: one HDLCD connects to one
> > TDA19988 which connects to one HDMI output.
> 
> Right now, the TDA998x will ignore the additional information, but that
> won't be the case with Jean's audio work (see the above binding
> information.)

Yes, I have seen that patchset. I will apply it to my tree and send an
updated version with the port-type property when I send v2.

Best regards,
Liviu

> 
> -- 
> FTTC broadband for 0.8mile line: currently at 10.5Mbps down 400kbps up
> according to speedtest.net.
> 

-- 
====================
| I would like to |
| fix the world,  |
| but they're not |
| giving me the   |
 \ source code!  /
  ---------------
    ?\_(?)_/?



From s.hauer at pengutronix.de  Thu Aug  6 03:20:59 2015
From: s.hauer at pengutronix.de (Sascha Hauer)
Date: Thu, 6 Aug 2015 12:20:59 +0200
Subject: [PATCH v6 7/9] clk: mediatek: Add subsystem clocks of MT8173
In-Reply-To: <CAGS+omAAYZyZJ4+eSdu2jmwThvHg1YpVoehui_cqNp4A5fURWg@mail.gmail.com>
References: <1438676218-11310-1-git-send-email-jamesjj.liao@mediatek.com>
 <1438676218-11310-8-git-send-email-jamesjj.liao@mediatek.com>
 <20150805064605.GZ18700@pengutronix.de>
 <1438849431.27884.9.camel@mtksdaap41>
 <20150806085354.GN18700@pengutronix.de>
 <1438851644.27884.21.camel@mtksdaap41>
 <CAGS+omAAYZyZJ4+eSdu2jmwThvHg1YpVoehui_cqNp4A5fURWg@mail.gmail.com>
Message-ID: <20150806102059.GQ18700@pengutronix.de>

On Thu, Aug 06, 2015 at 05:13:21PM +0800, Daniel Kurtz wrote:
> On Thu, Aug 6, 2015 at 5:00 PM, James Liao <jamesjj.liao at mediatek.com> wrote:
> > Hi Sascha,
> >
> > On Thu, 2015-08-06 at 10:53 +0200, Sascha Hauer wrote:
> >> On Thu, Aug 06, 2015 at 04:23:51PM +0800, James Liao wrote:
> >> > On Wed, 2015-08-05 at 08:46 +0200, Sascha Hauer wrote:
> >> > > On Tue, Aug 04, 2015 at 04:16:56PM +0800, James Liao wrote:
> >> > > >  static const struct mtk_fixed_clk fixed_clks[] __initconst = {
> >> > > >         FIXED_CLK(CLK_TOP_CLKPH_MCK_O, "clkph_mck_o", "clk26m", 400 * MHZ),
> >> > > >         FIXED_CLK(CLK_TOP_USB_SYSPLL_125M, "usb_syspll_125m", "clk26m", 125 * MHZ),
> >> > > > +       FIXED_CLK(CLK_TOP_DSI0_DIG, "dsi0_dig", "clk26m", 130 * MHZ),
> >> > > > +       FIXED_CLK(CLK_TOP_DSI1_DIG, "dsi1_dig", "clk26m", 130 * MHZ),
> >> > > > +       FIXED_CLK(CLK_TOP_LVDS_PXL, "lvds_pxl", "lvdspll", 148.5 * MHZ),
> >> > > > +       FIXED_CLK(CLK_TOP_LVDS_CTS, "lvds_cts", "lvdspll", 51.975 * MHZ),
> >> > >
> >> > > I would expect 51975 * KHZ here to avoid fractional numbers. Probably
> >> > > gcc calculates that during compile time so this will work as expected,
> >> > > still I'm not sure this is good style to use fractional numbers here.
> >> >
> >> > As I know all constants will be calculated in compile time, so there
> >> > should be no difference between 51.975 * MHZ and 51975 * KHz.
> >> >
> >> > > Anyway, on my system lvdspll is running at 150MHz. Are you sure there is
> >> > > a clock derived from this running at 148.5MHz? Is it really correct to
> >> > > use a fixed clock here or should it rather be lvdspll directly?
> >> >
> >> > Here is the clock hierarchy between lvdspll and lvds_pxl:
> >> >
> >> >             --------       AD_VPLL_DPIX_CK  --------   lvds_pxl  -----
> >> >            |        |--------------------->|        |---------->|
> >> >            |        |                      | cksys  |           |
> >> > LVDSPLL -->| LVDSTX |                      | buffer |           | MMSYS
> >> >            |        | AD_LVDSTX_CLKDIG_CTS | test   |  lvds_cts |
> >> >            |        |--------------------->|        |---------->|
> >> >             --------                        --------             -----
> >> >
> >> > Some clocks and blocks are not modeled into CCF. But we prefer to enable
> >> > lvdspll before enabling lvds_pxl. So I modeled lvds_pxl (and lvds_cts)
> >> > as a fixed-rate clock with a source from lvdspll.
> >> >
> >> > The frequency of these fixed-rate clocks (such as 148.5 MHz) are typical
> >> > rate. In fact, we don't care about the actual rate of these clocks. We
> >> > just care about the enable / disable sequence of them.
> >>
> >> Please either use the real rate or 0 (along with a explaining why). Using
> >> a frequency with four to five significant digits makes me think that the
> >> actual rate is very important.
> >
> > Oops, your suggestion is much different from Daniel's.
> >
> > Daniel, could you help to comment about how we model these clocks?
> 
> First of all, for clocks where the rate doesn't matter, it doesn't
> matters to what rate we set the clock.
> 
> As for the color of our shed, "the designer says these are the typical
> rates" sounds good enough to me for a "real rate", so I prefer using
> the rates in James' patch.
> 
> If not sure what Sascha's concern is, but if he insists on 0, I'm fine
> with that too.

I only find it confusing. I'd expect either the correct rate or an
obviously dummy rate. Whatever we choose a comment explaining the
background would really help here. Otherwise we won't know later
whether this 148.5 MHz rate was introduced because a) The consumers
depend on this rate being reported, b) It really is the correct rate or
c) we don't care about the rate.

Sascha

-- 
Pengutronix e.K.                           |                             |
Industrial Linux Solutions                 | http://www.pengutronix.de/  |
Peiner Str. 6-8, 31137 Hildesheim, Germany | Phone: +49-5121-206917-0    |
Amtsgericht Hildesheim, HRA 2686           | Fax:   +49-5121-206917-5555 |


From linux at arm.linux.org.uk  Thu Aug  6 03:22:25 2015
From: linux at arm.linux.org.uk (Russell King - ARM Linux)
Date: Thu, 6 Aug 2015 11:22:25 +0100
Subject: [RFC PATCH 1/5] spi: introduce flag for memory mapped read
In-Reply-To: <CAOMqctQZRZ4zG_yYy=CeX3DX4NVNWN1COP4Q-2YvMun9xYOA7g@mail.gmail.com>
References: <20150731181745.GM20873@sirena.org.uk> <55BEF4AF.5090704@ti.com>
 <20150804155148.GR20873@sirena.org.uk> <55C0FD98.1090107@ti.com>
 <20150805115013.GJ20873@sirena.org.uk>
 <CAOMqctQXwcHyiWBwtugSDSE_k65qrNfrwnhjQMDJkLoJMmGzUw@mail.gmail.com>
 <20150805124412.GN20873@sirena.org.uk>
 <CAOMqctS9Y5FxpUCCJew6+cnjH5iTvbzkH3g-8yrXs4OuS2pSGA@mail.gmail.com>
 <20150806090202.GO20873@sirena.org.uk>
 <CAOMqctQZRZ4zG_yYy=CeX3DX4NVNWN1COP4Q-2YvMun9xYOA7g@mail.gmail.com>
Message-ID: <20150806102225.GI7576@n2100.arm.linux.org.uk>

On Thu, Aug 06, 2015 at 12:01:37PM +0200, Michal Suchanek wrote:
> Disclaimer: I am not familiar with the hardware for which this patch
> adds support.
> 
> However, I am familiar m25p80.c and as I understand it the controller
> is basically supposed to implement m25p80.c in hardware when this flag
> is set.

That, to me, sounds like what you have is:

---m25p80 specific interface--->SPI bus--->m25p80 device

Where the m25p80 specific interface does not expose direct access to the
SPI bus?

If that's the case, then maybe you should consider whether using the SPI
bus infrastructure is really the best way forward.  Would it make more
sense instead to adopt a different software structure, something more
high-level like:

     +-------------------------------------------+
     |          m25p80 high-level driver         |
     +----------------------+--------------------+
     |   SPI m25p80 driver  |                    |
     +----------------------+                    |
     |      SPI layer       |  Special driver    |
     +----------------------+                    |
     |    SPI bus driver    |                    |
     +----------------------+--------------------+
     |     SPI hardware     |  Special hardware  |
     +----------------------+--------------------+

Rather than what you seem to be trying to do, which seems to be:

     +----------------------+
     |   SPI m25p80 driver  |
     +----------------------+
     |      SPI layer       |
     +----------------------+
     |  Translation driver  |
     +----------------------+
     |   Special hardware   |
     +----------------------+

where this requires M25P80 specific hacks to be introduced into the SPI
layer so that you can communicate additional information between the SPI
M25P80 driver and the translation driver.

-- 
FTTC broadband for 0.8mile line: currently at 10.5Mbps down 400kbps up
according to speedtest.net.


From Wenyou.Yang at atmel.com  Thu Aug  6 03:22:45 2015
From: Wenyou.Yang at atmel.com (Yang, Wenyou)
Date: Thu, 6 Aug 2015 10:22:45 +0000
Subject: [PATCH v5 1/2] drivers: watchdog: add a driver to support
 SAMA5D4 watchdog timer
In-Reply-To: <55C33013.6020002@roeck-us.net>
References: <1438850055-30104-1-git-send-email-wenyou.yang@atmel.com>
 <1438850055-30104-2-git-send-email-wenyou.yang@atmel.com>
 <55C33013.6020002@roeck-us.net>
Message-ID: <B256D81BAE5131468A838E5D7A243641C9F87788@penmbx01>

Hi Guenter,

> -----Original Message-----
> From: Guenter Roeck [mailto:linux at roeck-us.net]
> Sent: 2015?8?6? 18:00
> To: Yang, Wenyou; wim at iguana.be; robh+dt at kernel.org; pawel.moll at arm.com;
> mark.rutland at arm.com; ijc+devicetree at hellion.org.uk; galak at codeaurora.org
> Cc: sylvain.rochet at finsecur.com; Ferre, Nicolas; boris.brezillon at free-
> electrons.com; devicetree at vger.kernel.org; linux-kernel at vger.kernel.org; linux-
> watchdog at vger.kernel.org; linux-arm-kernel at lists.infradead.org
> Subject: Re: [PATCH v5 1/2] drivers: watchdog: add a driver to support SAMA5D4
> watchdog timer
> 
> Hi,
> 
> On 08/06/2015 01:34 AM, Wenyou Yang wrote:
> >>From SAMA5D4, the watchdog timer is upgrated with a new feature,
> 
> Where does the additional ">" come from ?
I don't know why, but it isn't inclusive in my received mail.

> 
> > which is describled as in the datasheet, "WDT_MR can be written until
> > a LOCKMR command is issued in WDT_CR".
> > That is to say, as long as the bootstrap and u-boot don't issue a
> > LOCKMR command, WDT_MR can be written more than once in the driver.
> >
> > So the SAMA5D4 watchdog driver's implementation is different from the
> > at91sam9260 watchdog driver implemented in file at91sam9_wdt.c.
> > The user application open the device file to enable the watchdog timer
> > hardware, and close to disable it, and set the watchdog timer timeout
> > by seting WDV and WDD fields of WDT_MR register, and ping the watchdog
> > by issuing WDRSTT command to WDT_CR register with hard-coded key.
> >
> > Signed-off-by: Wenyou Yang <wenyou.yang at atmel.com>
> > ---
> >   drivers/watchdog/Kconfig        |    9 ++
> >   drivers/watchdog/Makefile       |    1 +
> >   drivers/watchdog/at91sam9_wdt.h |    2 +
> >   drivers/watchdog/sama5d4_wdt.c  |  280
> +++++++++++++++++++++++++++++++++++++++
> >   4 files changed, 292 insertions(+)
> >   create mode 100644 drivers/watchdog/sama5d4_wdt.c
> >
> > diff --git a/drivers/watchdog/Kconfig b/drivers/watchdog/Kconfig index
> > e5e7c55..47ad39a 100644
> > --- a/drivers/watchdog/Kconfig
> > +++ b/drivers/watchdog/Kconfig
> > @@ -167,6 +167,15 @@ config AT91SAM9X_WATCHDOG
> >   	  Watchdog timer embedded into AT91SAM9X and AT91CAP9 chips. This
> will
> >   	  reboot your system when the timeout is reached.
> >
> > +config SAMA5D4_WATCHDOG
> > +	tristate "Atmel SAMA5D4 Watchdog Timer"
> > +	depends on ARCH_AT91
> > +	select WATCHDOG_CORE
> > +	help
> > +	  Atmel SAMA5D4 watchdog timer is embedded into SAMA5D4 chips.
> > +	  Its Watchdog Timer Mode Register can be written more than once.
> > +	  This will reboot your system when the timeout is reached.
> > +
> >   config CADENCE_WATCHDOG
> >   	tristate "Cadence Watchdog Timer"
> >   	select WATCHDOG_CORE
> > diff --git a/drivers/watchdog/Makefile b/drivers/watchdog/Makefile
> > index 5c19294..f24b820 100644
> > --- a/drivers/watchdog/Makefile
> > +++ b/drivers/watchdog/Makefile
> > @@ -41,6 +41,7 @@ obj-$(CONFIG_IXP4XX_WATCHDOG) += ixp4xx_wdt.o
> >   obj-$(CONFIG_KS8695_WATCHDOG) += ks8695_wdt.o
> >   obj-$(CONFIG_S3C2410_WATCHDOG) += s3c2410_wdt.o
> >   obj-$(CONFIG_SA1100_WATCHDOG) += sa1100_wdt.o
> > +obj-$(CONFIG_SAMA5D4_WATCHDOG) += sama5d4_wdt.o
> >   obj-$(CONFIG_DW_WATCHDOG) += dw_wdt.o
> >   obj-$(CONFIG_EP93XX_WATCHDOG) += ep93xx_wdt.o
> >   obj-$(CONFIG_PNX4008_WATCHDOG) += pnx4008_wdt.o diff --git
> > a/drivers/watchdog/at91sam9_wdt.h b/drivers/watchdog/at91sam9_wdt.h
> > index c6fbb2e6..b79a83b 100644
> > --- a/drivers/watchdog/at91sam9_wdt.h
> > +++ b/drivers/watchdog/at91sam9_wdt.h
> > @@ -22,11 +22,13 @@
> >
> >   #define AT91_WDT_MR		0x04			/* Watchdog
> Mode Register */
> >   #define		AT91_WDT_WDV		(0xfff << 0)		/*
> Counter Value */
> > +#define			AT91_WDT_SET_WDV(x)	((x) &
> AT91_WDT_WDV)
> >   #define		AT91_WDT_WDFIEN		(1     << 12)		/*
> Fault Interrupt Enable */
> >   #define		AT91_WDT_WDRSTEN	(1     << 13)		/*
> Reset Processor */
> >   #define		AT91_WDT_WDRPROC	(1     << 14)		/*
> Timer Restart */
> >   #define		AT91_WDT_WDDIS		(1     << 15)		/*
> Watchdog Disable */
> >   #define		AT91_WDT_WDD		(0xfff << 16)		/*
> Delta Value */
> > +#define			AT91_WDT_SET_WDD(x)	(((x) << 16) &
> AT91_WDT_WDD)
> >   #define		AT91_WDT_WDDBGHLT	(1     << 28)		/*
> Debug Halt */
> >   #define		AT91_WDT_WDIDLEHLT	(1     << 29)		/*
> Idle Halt */
> >
> > diff --git a/drivers/watchdog/sama5d4_wdt.c
> > b/drivers/watchdog/sama5d4_wdt.c new file mode 100644 index
> > 0000000..a412215
> > --- /dev/null
> > +++ b/drivers/watchdog/sama5d4_wdt.c
> > @@ -0,0 +1,280 @@
> > +/*
> > + * Driver for Atmel SAMA5D4 Watchdog Timer
> > + *
> > + * Copyright (C) 2015 Atmel Corporation
> > + *
> > + * Licensed under GPLv2.
> > + */
> > +
> > +#include <linux/interrupt.h>
> > +#include <linux/io.h>
> > +#include <linux/kernel.h>
> > +#include <linux/module.h>
> > +#include <linux/of.h>
> > +#include <linux/of_irq.h>
> > +#include <linux/platform_device.h>
> > +#include <linux/reboot.h>
> > +#include <linux/watchdog.h>
> > +
> > +#include "at91sam9_wdt.h"
> > +
> > +/* minimum and maximum watchdog timeout, in seconds */
> > +#define MIN_WDT_TIMEOUT		1
> > +#define MAX_WDT_TIMEOUT		16
> > +#define WDT_DEFAULT_TIMEOUT	MAX_WDT_TIMEOUT
> > +
> > +#define WDT_SEC2TICKS(s)	((s) ? (((s) << 8) - 1) : 0)
> > +
> > +struct sama5d4_wdt {
> > +	struct watchdog_device	wdd;
> > +	void __iomem		*reg_base;
> > +	u32	config;
> > +};
> > +
> > +static int wdt_timeout = WDT_DEFAULT_TIMEOUT; static bool nowayout =
> > +WATCHDOG_NOWAYOUT;
> > +
> > +module_param(wdt_timeout, int, 0);
> > +MODULE_PARM_DESC(wdt_timeout,
> > +	"Watchdog timeout in seconds. (default = "
> > +	__MODULE_STRING(WDT_DEFAULT_TIMEOUT) ")");
> > +
> > +module_param(nowayout, bool, 0);
> > +MODULE_PARM_DESC(nowayout,
> > +	"Watchdog cannot be stopped once started (default="
> > +	__MODULE_STRING(WATCHDOG_NOWAYOUT) ")");
> > +
> > +#define wdt_read(wdt, field) \
> > +	readl_relaxed((wdt)->reg_base + (field))
> > +
> > +#define wdt_write(wtd, field, val) \
> > +	writel_relaxed((val), (wdt)->reg_base + (field))
> > +
> > +static int sama5d4_wdt_start(struct watchdog_device *wdd) {
> > +	struct sama5d4_wdt *wdt = watchdog_get_drvdata(wdd);
> > +	u32 reg;
> > +
> > +	reg = wdt_read(wdt, AT91_WDT_MR);
> > +	reg &= ~AT91_WDT_WDDIS;
> > +	wdt_write(wdt, AT91_WDT_MR, reg);
> > +
> > +	return 0;
> > +}
> > +
> > +static int sama5d4_wdt_stop(struct watchdog_device *wdd) {
> > +	struct sama5d4_wdt *wdt = watchdog_get_drvdata(wdd);
> > +	u32 reg;
> > +
> > +	reg = wdt_read(wdt, AT91_WDT_MR);
> > +	reg |= AT91_WDT_WDDIS;
> > +	wdt_write(wdt, AT91_WDT_MR, reg);
> > +
> > +	return 0;
> > +}
> > +
> > +static int sama5d4_wdt_ping(struct watchdog_device *wdd) {
> > +	struct sama5d4_wdt *wdt = watchdog_get_drvdata(wdd);
> > +
> > +	wdt_write(wdt, AT91_WDT_CR, AT91_WDT_KEY |
> AT91_WDT_WDRSTT);
> > +
> > +	return 0;
> > +}
> > +
> > +static int sama5d4_wdt_set_timeout(struct watchdog_device *wdd,
> > +				 unsigned int timeout)
> > +{
> > +	struct sama5d4_wdt *wdt = watchdog_get_drvdata(wdd);
> > +	u32 value = WDT_SEC2TICKS(timeout);
> > +	u32 reg;
> > +
> > +	reg = wdt_read(wdt, AT91_WDT_MR);
> > +	reg &= ~AT91_WDT_WDV;
> > +	reg &= ~AT91_WDT_WDD;
> > +	reg |= AT91_WDT_SET_WDV(value);
> > +	reg |= AT91_WDT_SET_WDD(value);
> > +	wdt_write(wdt, AT91_WDT_MR, reg);
> > +
> > +	wdd->timeout = timeout;
> > +
> > +	return 0;
> > +}
> > +
> > +static const struct watchdog_info sama5d4_wdt_info = {
> > +	.options = WDIOF_SETTIMEOUT | WDIOF_MAGICCLOSE |
> WDIOF_KEEPALIVEPING,
> > +	.identity = "Atmel SAMA5D4 Watchdog"
> > +};
> > +
> > +static struct watchdog_ops sama5d4_wdt_ops = {
> > +	.owner = THIS_MODULE,
> > +	.start = sama5d4_wdt_start,
> > +	.stop = sama5d4_wdt_stop,
> > +	.ping = sama5d4_wdt_ping,
> > +	.set_timeout = sama5d4_wdt_set_timeout
> 
> You made another silent change in v4: You dropped the comma here, and above
> after .identity. Now, while it makes sense to have no comma after "{ }", it does
> make sense to have the comma here, because it avoids unnecessary conflicts
> and build errors later on if a member is added at the end of the list. Please add
> those commas back in.
I will add those commas back in.

> 
> Also, please stop making silent changes like this. You are making it really hard to
> review your code - now I'll have to go through it line by line again and compare it
> with your earlier patches to see if you made any other unannounced changes.
Sorry for silent changes. 
I will double check it more careful before submitting the patch. 

> 
> Thanks,
> Guenter

Best Regards,
Wenyou Yang

From wenyou.yang at atmel.com  Thu Aug  6 03:15:46 2015
From: wenyou.yang at atmel.com (Wenyou Yang)
Date: Thu, 6 Aug 2015 18:15:46 +0800
Subject: [PATCH v6 0/2] add a new driver to support SAMA5D4 watchdog timer
Message-ID: <1438856146-2459-1-git-send-email-wenyou.yang@atmel.com>

Hello,

Because the watchdog WDT_MR register can be written more than once,
its work mechanism is different from the at91sam9260 watchdog driver.
Open the device file to enable the watchdog hardware, close to disable it,
and ping it from the user space directly to keep it alive.

Changes from v5.0
 1./ Add the commas back in after last member for structure variables,
     sama5d4_wdt_info and sama5d4_wdt_ops.

Changes from v4.0
 1./ Fix interrupt register function flags argument.
 2./ Replace the tabs after #define with spaces.

Changes from v3.0
 1./ Change the driver name to 'sama5d4_wdt' for more acceptable.
 2./ Change the prefix of function name and struct name
     from 'atmel_' to 'sama5d4_', and others.

Changes from v2.0
 1./ Use a specific driver name, at91_sama5d4_wdt.c.
 2./ Remove '-' at the end of macro name and unnecessary check.
 3./ Use alphabetic order for include files.


Wenyou Yang (2):
  drivers: watchdog: add a driver to support SAMA5D4 watchdog timer
  Documentation: dt: binding: atmel-sama5d4-wdt: for SAMA5D4 watchdog
    driver

 .../bindings/watchdog/atmel-sama5d4-wdt.txt        |   35 +++
 drivers/watchdog/Kconfig                           |    9 +
 drivers/watchdog/Makefile                          |    1 +
 drivers/watchdog/at91sam9_wdt.h                    |    2 +
 drivers/watchdog/sama5d4_wdt.c                     |  280 ++++++++++++++++++++
 5 files changed, 327 insertions(+)
 create mode 100644 Documentation/devicetree/bindings/watchdog/atmel-sama5d4-wdt.txt
 create mode 100644 drivers/watchdog/sama5d4_wdt.c

-- 
1.7.9.5



From rnayak at codeaurora.org  Thu Aug  6 03:31:45 2015
From: rnayak at codeaurora.org (Rajendra Nayak)
Date: Thu, 06 Aug 2015 16:01:45 +0530
Subject: [PATCH v7 12/13] clk: qcom: gdsc: Add GDSCs in apq8084 MMCC
In-Reply-To: <55BB8C40.507@mm-sol.com>
References: <1438076046-4706-1-git-send-email-rnayak@codeaurora.org>
 <1438076046-4706-13-git-send-email-rnayak@codeaurora.org>
 <55BB8C40.507@mm-sol.com>
Message-ID: <55C33791.6010506@codeaurora.org>



On 07/31/2015 08:24 PM, Stanimir Varbanov wrote:
>
> <snip>
>
>>
>> +static struct gdsc venus0_gdsc = {
>> +	.gdscr = 0x1024,
>> +	.pd = {
>> +		.name = "venus0",
>> +	},
>> +	.pwrsts = PWRSTS_OFF_ON,
>> +	.con_ids = { NULL },
>> +};
>> +
>
> Rajendra, according to downstream kernel apq8084 has second instance of
> gdsc i.e. venus1_gdsc, is that correct?

Stan, it does seem like there are 3 instances of venus gdscs', venus0,
venus0_core0 and venus0_core1. I will add the missing ones when I
repost,thanks.


From yamada.masahiro at socionext.com  Thu Aug  6 03:37:44 2015
From: yamada.masahiro at socionext.com (Masahiro Yamada)
Date: Thu,  6 Aug 2015 19:37:44 +0900
Subject: [PATCH v2 0/4] Device Tree updates of UniPhier SoCs for Linux 4.3
Message-ID: <1438857468-9740-1-git-send-email-yamada.masahiro@socionext.com>

Hi Olof and Arnd,

Here are a little more updates for device trees for UniPhier SoCs.

Please consider applying this series to your ARM-SOC tree.

Thanks!

Changes in v2:
  - insert 2/4 to fix build error

Masahiro Yamada (4):
  ARM: dts: UniPhier: add I2C controller device nodes
  ARM: dts: UniPhier: add reference daughter board
  ARM: dts: UniPhier: add PH1-Pro5 SoC support
  ARM: dts: UniPhier: add ProXstream2 and PH1-LD6b SoC/board support

 arch/arm/boot/dts/Makefile                   |   3 +-
 arch/arm/boot/dts/uniphier-ph1-ld4-ref.dts   |   9 +
 arch/arm/boot/dts/uniphier-ph1-ld4.dtsi      |  58 ++++++
 arch/arm/boot/dts/uniphier-ph1-ld6b-ref.dts  | 105 +++++++++++
 arch/arm/boot/dts/uniphier-ph1-ld6b.dtsi     |  67 +++++++
 arch/arm/boot/dts/uniphier-ph1-pro4-ref.dts  |  11 ++
 arch/arm/boot/dts/uniphier-ph1-pro4.dtsi     |  82 ++++++++
 arch/arm/boot/dts/uniphier-ph1-pro5.dtsi     | 252 +++++++++++++++++++++++++
 arch/arm/boot/dts/uniphier-ph1-sld3-ref.dts  |  10 +
 arch/arm/boot/dts/uniphier-ph1-sld3.dtsi     |  61 ++++++
 arch/arm/boot/dts/uniphier-ph1-sld8-ref.dts  |   9 +
 arch/arm/boot/dts/uniphier-ph1-sld8.dtsi     |  58 ++++++
 arch/arm/boot/dts/uniphier-pinctrl.dtsi      |  20 ++
 arch/arm/boot/dts/uniphier-proxstream2.dtsi  | 273 +++++++++++++++++++++++++++
 arch/arm/boot/dts/uniphier-ref-daughter.dtsi |  50 +++++
 15 files changed, 1067 insertions(+), 1 deletion(-)
 create mode 100644 arch/arm/boot/dts/uniphier-ph1-ld6b-ref.dts
 create mode 100644 arch/arm/boot/dts/uniphier-ph1-ld6b.dtsi
 create mode 100644 arch/arm/boot/dts/uniphier-ph1-pro5.dtsi
 create mode 100644 arch/arm/boot/dts/uniphier-proxstream2.dtsi
 create mode 100644 arch/arm/boot/dts/uniphier-ref-daughter.dtsi

-- 
1.9.1



From yamada.masahiro at socionext.com  Thu Aug  6 03:37:46 2015
From: yamada.masahiro at socionext.com (Masahiro Yamada)
Date: Thu,  6 Aug 2015 19:37:46 +0900
Subject: [PATCH v2 2/4] ARM: dts: UniPhier: add reference daughter board
In-Reply-To: <1438857468-9740-1-git-send-email-yamada.masahiro@socionext.com>
References: <1438857468-9740-1-git-send-email-yamada.masahiro@socionext.com>
Message-ID: <1438857468-9740-3-git-send-email-yamada.masahiro@socionext.com>

This is used as a base board for reference core modules.

Signed-off-by: Masahiro Yamada <yamada.masahiro at socionext.com>
---
 arch/arm/boot/dts/uniphier-ph1-ld4-ref.dts   |  1 +
 arch/arm/boot/dts/uniphier-ph1-pro4-ref.dts  |  1 +
 arch/arm/boot/dts/uniphier-ph1-sld3-ref.dts  |  1 +
 arch/arm/boot/dts/uniphier-ph1-sld8-ref.dts  |  1 +
 arch/arm/boot/dts/uniphier-ref-daughter.dtsi | 50 ++++++++++++++++++++++++++++
 5 files changed, 54 insertions(+)
 create mode 100644 arch/arm/boot/dts/uniphier-ref-daughter.dtsi

diff --git a/arch/arm/boot/dts/uniphier-ph1-ld4-ref.dts b/arch/arm/boot/dts/uniphier-ph1-ld4-ref.dts
index 5d24c57..bfd3bb8 100644
--- a/arch/arm/boot/dts/uniphier-ph1-ld4-ref.dts
+++ b/arch/arm/boot/dts/uniphier-ph1-ld4-ref.dts
@@ -44,6 +44,7 @@
 
 /dts-v1/;
 /include/ "uniphier-ph1-ld4.dtsi"
+/include/ "uniphier-ref-daughter.dtsi"
 /include/ "uniphier-support-card.dtsi"
 
 / {
diff --git a/arch/arm/boot/dts/uniphier-ph1-pro4-ref.dts b/arch/arm/boot/dts/uniphier-ph1-pro4-ref.dts
index 26c18ac..69a5b7d 100644
--- a/arch/arm/boot/dts/uniphier-ph1-pro4-ref.dts
+++ b/arch/arm/boot/dts/uniphier-ph1-pro4-ref.dts
@@ -44,6 +44,7 @@
 
 /dts-v1/;
 /include/ "uniphier-ph1-pro4.dtsi"
+/include/ "uniphier-ref-daughter.dtsi"
 /include/ "uniphier-support-card.dtsi"
 
 / {
diff --git a/arch/arm/boot/dts/uniphier-ph1-sld3-ref.dts b/arch/arm/boot/dts/uniphier-ph1-sld3-ref.dts
index cb6e9aa..1a440f8 100644
--- a/arch/arm/boot/dts/uniphier-ph1-sld3-ref.dts
+++ b/arch/arm/boot/dts/uniphier-ph1-sld3-ref.dts
@@ -44,6 +44,7 @@
 
 /dts-v1/;
 /include/ "uniphier-ph1-sld3.dtsi"
+/include/ "uniphier-ref-daughter.dtsi"
 /include/ "uniphier-support-card.dtsi"
 
 / {
diff --git a/arch/arm/boot/dts/uniphier-ph1-sld8-ref.dts b/arch/arm/boot/dts/uniphier-ph1-sld8-ref.dts
index a40a0fb..955d417 100644
--- a/arch/arm/boot/dts/uniphier-ph1-sld8-ref.dts
+++ b/arch/arm/boot/dts/uniphier-ph1-sld8-ref.dts
@@ -44,6 +44,7 @@
 
 /dts-v1/;
 /include/ "uniphier-ph1-sld8.dtsi"
+/include/ "uniphier-ref-daughter.dtsi"
 /include/ "uniphier-support-card.dtsi"
 
 / {
diff --git a/arch/arm/boot/dts/uniphier-ref-daughter.dtsi b/arch/arm/boot/dts/uniphier-ref-daughter.dtsi
new file mode 100644
index 0000000..3d29d28
--- /dev/null
+++ b/arch/arm/boot/dts/uniphier-ref-daughter.dtsi
@@ -0,0 +1,50 @@
+/*
+ * Device Tree Source for UniPhier Reference Daughter Board
+ *
+ * Copyright (C) 2015 Masahiro Yamada <yamada.masahiro at socionext.com>
+ *
+ * This file is dual-licensed: you can use it either under the terms
+ * of the GPL or the X11 license, at your option. Note that this dual
+ * licensing only applies to this file, and not this project as a
+ * whole.
+ *
+ *  a) This file is free software; you can redistribute it and/or
+ *     modify it under the terms of the GNU General Public License as
+ *     published by the Free Software Foundation; either version 2 of the
+ *     License, or (at your option) any later version.
+ *
+ *     This file is distributed in the hope that it will be useful,
+ *     but WITHOUT ANY WARRANTY; without even the implied warranty of
+ *     MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ *     GNU General Public License for more details.
+ *
+ * Or, alternatively,
+ *
+ *  b) Permission is hereby granted, free of charge, to any person
+ *     obtaining a copy of this software and associated documentation
+ *     files (the "Software"), to deal in the Software without
+ *     restriction, including without limitation the rights to use,
+ *     copy, modify, merge, publish, distribute, sublicense, and/or
+ *     sell copies of the Software, and to permit persons to whom the
+ *     Software is furnished to do so, subject to the following
+ *     conditions:
+ *
+ *     The above copyright notice and this permission notice shall be
+ *     included in all copies or substantial portions of the Software.
+ *
+ *     THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
+ *     EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES
+ *     OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
+ *     NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT
+ *     HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY,
+ *     WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
+ *     FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR
+ *     OTHER DEALINGS IN THE SOFTWARE.
+ */
+
+&i2c0 {
+	eeprom {
+		compatible = "microchip,24lc128";
+		reg = <0x50>;
+	};
+};
-- 
1.9.1



From yamada.masahiro at socionext.com  Thu Aug  6 03:37:45 2015
From: yamada.masahiro at socionext.com (Masahiro Yamada)
Date: Thu,  6 Aug 2015 19:37:45 +0900
Subject: [PATCH v2 1/4] ARM: dts: UniPhier: add I2C controller device nodes
In-Reply-To: <1438857468-9740-1-git-send-email-yamada.masahiro@socionext.com>
References: <1438857468-9740-1-git-send-email-yamada.masahiro@socionext.com>
Message-ID: <1438857468-9740-2-git-send-email-yamada.masahiro@socionext.com>

Add I2C controller device nodes for PH1-sLD3, PH1-LD4, PH1-sLD8
(FIFO-less I2C) and PH1-Pro4 (FIFO-builtin I2C).

Signed-off-by: Masahiro Yamada <yamada.masahiro at socionext.com>
---
 arch/arm/boot/dts/uniphier-ph1-ld4-ref.dts  |  8 +++
 arch/arm/boot/dts/uniphier-ph1-ld4.dtsi     | 58 ++++++++++++++++++++
 arch/arm/boot/dts/uniphier-ph1-pro4-ref.dts | 10 ++++
 arch/arm/boot/dts/uniphier-ph1-pro4.dtsi    | 82 +++++++++++++++++++++++++++++
 arch/arm/boot/dts/uniphier-ph1-sld3-ref.dts |  9 ++++
 arch/arm/boot/dts/uniphier-ph1-sld3.dtsi    | 61 +++++++++++++++++++++
 arch/arm/boot/dts/uniphier-ph1-sld8-ref.dts |  8 +++
 arch/arm/boot/dts/uniphier-ph1-sld8.dtsi    | 58 ++++++++++++++++++++
 arch/arm/boot/dts/uniphier-pinctrl.dtsi     | 20 +++++++
 9 files changed, 314 insertions(+)

diff --git a/arch/arm/boot/dts/uniphier-ph1-ld4-ref.dts b/arch/arm/boot/dts/uniphier-ph1-ld4-ref.dts
index 7ac053d..5d24c57 100644
--- a/arch/arm/boot/dts/uniphier-ph1-ld4-ref.dts
+++ b/arch/arm/boot/dts/uniphier-ph1-ld4-ref.dts
@@ -65,6 +65,10 @@
 		serial1 = &serial1;
 		serial2 = &serial2;
 		serial3 = &serial3;
+		i2c0 = &i2c0;
+		i2c1 = &i2c1;
+		i2c2 = &i2c2;
+		i2c3 = &i2c3;
 	};
 };
 
@@ -93,6 +97,10 @@
 	status = "okay";
 };
 
+&i2c0 {
+	status = "okay";
+};
+
 &usb0 {
 	status = "okay";
 };
diff --git a/arch/arm/boot/dts/uniphier-ph1-ld4.dtsi b/arch/arm/boot/dts/uniphier-ph1-ld4.dtsi
index 4add90b..a6a185f 100644
--- a/arch/arm/boot/dts/uniphier-ph1-ld4.dtsi
+++ b/arch/arm/boot/dts/uniphier-ph1-ld4.dtsi
@@ -70,6 +70,12 @@
 			compatible = "fixed-clock";
 			clock-frequency = <36864000>;
 		};
+
+		iobus_clk: iobus_clk {
+			#clock-cells = <0>;
+			compatible = "fixed-clock";
+			clock-frequency = <100000000>;
+		};
 	};
 
 	soc {
@@ -129,6 +135,58 @@
 			fifo-size = <64>;
 		};
 
+		i2c0: i2c at 58400000 {
+			compatible = "socionext,uniphier-i2c";
+			status = "disabled";
+			reg = <0x58400000 0x40>;
+			#address-cells = <1>;
+			#size-cells = <0>;
+			pinctrl-names = "default";
+			pinctrl-0 = <&pinctrl_i2c0>;
+			interrupts = <0 41 1>;
+			clocks = <&iobus_clk>;
+			clock-frequency = <100000>;
+		};
+
+		i2c1: i2c at 58480000 {
+			compatible = "socionext,uniphier-i2c";
+			status = "disabled";
+			reg = <0x58480000 0x40>;
+			#address-cells = <1>;
+			#size-cells = <0>;
+			pinctrl-names = "default";
+			pinctrl-0 = <&pinctrl_i2c1>;
+			interrupts = <0 42 1>;
+			clocks = <&iobus_clk>;
+			clock-frequency = <100000>;
+		};
+
+		/* chip-internal connection for DMD */
+		i2c2: i2c at 58500000 {
+			compatible = "socionext,uniphier-i2c";
+			reg = <0x58500000 0x40>;
+			#address-cells = <1>;
+			#size-cells = <0>;
+			pinctrl-names = "default";
+			pinctrl-0 = <&pinctrl_i2c2>;
+			interrupts = <0 43 1>;
+			clocks = <&iobus_clk>;
+			clock-frequency = <400000>;
+		};
+
+		i2c3: i2c at 58580000 {
+			compatible = "socionext,uniphier-i2c";
+			status = "disabled";
+			reg = <0x58580000 0x40>;
+			#address-cells = <1>;
+			#size-cells = <0>;
+			pinctrl-names = "default";
+			pinctrl-0 = <&pinctrl_i2c3>;
+			interrupts = <0 44 1>;
+			clocks = <&iobus_clk>;
+			clock-frequency = <100000>;
+		};
+
 		system-bus-controller-misc at 59800000 {
 			compatible = "socionext,uniphier-system-bus-controller-misc",
 				     "syscon";
diff --git a/arch/arm/boot/dts/uniphier-ph1-pro4-ref.dts b/arch/arm/boot/dts/uniphier-ph1-pro4-ref.dts
index b669d32..26c18ac 100644
--- a/arch/arm/boot/dts/uniphier-ph1-pro4-ref.dts
+++ b/arch/arm/boot/dts/uniphier-ph1-pro4-ref.dts
@@ -65,6 +65,12 @@
 		serial1 = &serial1;
 		serial2 = &serial2;
 		serial3 = &serial3;
+		i2c0 = &i2c0;
+		i2c1 = &i2c1;
+		i2c2 = &i2c2;
+		i2c3 = &i2c3;
+		i2c5 = &i2c5;
+		i2c6 = &i2c6;
 	};
 };
 
@@ -93,6 +99,10 @@
 	status = "okay";
 };
 
+&i2c0 {
+	status = "okay";
+};
+
 &usb2 {
 	status = "okay";
 };
diff --git a/arch/arm/boot/dts/uniphier-ph1-pro4.dtsi b/arch/arm/boot/dts/uniphier-ph1-pro4.dtsi
index d0ca4c8..e8bbc45 100644
--- a/arch/arm/boot/dts/uniphier-ph1-pro4.dtsi
+++ b/arch/arm/boot/dts/uniphier-ph1-pro4.dtsi
@@ -77,6 +77,12 @@
 			compatible = "fixed-clock";
 			clock-frequency = <73728000>;
 		};
+
+		i2c_clk: i2c_clk {
+			#clock-cells = <0>;
+			compatible = "fixed-clock";
+			clock-frequency = <50000000>;
+		};
 	};
 
 	soc {
@@ -136,6 +142,82 @@
 			fifo-size = <64>;
 		};
 
+		i2c0: i2c at 58780000 {
+			compatible = "socionext,uniphier-fi2c";
+			status = "disabled";
+			reg = <0x58780000 0x80>;
+			#address-cells = <1>;
+			#size-cells = <0>;
+			pinctrl-names = "default";
+			pinctrl-0 = <&pinctrl_i2c0>;
+			interrupts = <0 41 4>;
+			clocks = <&i2c_clk>;
+			clock-frequency = <100000>;
+		};
+
+		i2c1: i2c at 58781000 {
+			compatible = "socionext,uniphier-fi2c";
+			status = "disabled";
+			reg = <0x58781000 0x80>;
+			#address-cells = <1>;
+			#size-cells = <0>;
+			pinctrl-names = "default";
+			pinctrl-0 = <&pinctrl_i2c1>;
+			interrupts = <0 42 4>;
+			clocks = <&i2c_clk>;
+			clock-frequency = <100000>;
+		};
+
+		i2c2: i2c at 58782000 {
+			compatible = "socionext,uniphier-fi2c";
+			status = "disabled";
+			reg = <0x58782000 0x80>;
+			#address-cells = <1>;
+			#size-cells = <0>;
+			pinctrl-names = "default";
+			pinctrl-0 = <&pinctrl_i2c2>;
+			interrupts = <0 43 4>;
+			clocks = <&i2c_clk>;
+			clock-frequency = <100000>;
+		};
+
+		i2c3: i2c at 58783000 {
+			compatible = "socionext,uniphier-fi2c";
+			status = "disabled";
+			reg = <0x58783000 0x80>;
+			#address-cells = <1>;
+			#size-cells = <0>;
+			pinctrl-names = "default";
+			pinctrl-0 = <&pinctrl_i2c3>;
+			interrupts = <0 44 4>;
+			clocks = <&i2c_clk>;
+			clock-frequency = <100000>;
+		};
+
+		/* i2c4 does not exist */
+
+		/* chip-internal connection for DMD */
+		i2c5: i2c at 58785000 {
+			compatible = "socionext,uniphier-fi2c";
+			reg = <0x58785000 0x80>;
+			#address-cells = <1>;
+			#size-cells = <0>;
+			interrupts = <0 25 4>;
+			clocks = <&i2c_clk>;
+			clock-frequency = <400000>;
+		};
+
+		/* chip-internal connection for HDMI */
+		i2c6: i2c at 58786000 {
+			compatible = "socionext,uniphier-fi2c";
+			reg = <0x58786000 0x80>;
+			#address-cells = <1>;
+			#size-cells = <0>;
+			interrupts = <0 26 4>;
+			clocks = <&i2c_clk>;
+			clock-frequency = <400000>;
+		};
+
 		system-bus-controller-misc at 59800000 {
 			compatible = "socionext,uniphier-system-bus-controller-misc",
 				     "syscon";
diff --git a/arch/arm/boot/dts/uniphier-ph1-sld3-ref.dts b/arch/arm/boot/dts/uniphier-ph1-sld3-ref.dts
index 48f7361..cb6e9aa 100644
--- a/arch/arm/boot/dts/uniphier-ph1-sld3-ref.dts
+++ b/arch/arm/boot/dts/uniphier-ph1-sld3-ref.dts
@@ -65,6 +65,11 @@
 		serial0 = &serial0;
 		serial1 = &serial1;
 		serial2 = &serial2;
+		i2c0 = &i2c0;
+		i2c1 = &i2c1;
+		i2c2 = &i2c2;
+		i2c3 = &i2c3;
+		i2c4 = &i2c4;
 	};
 };
 
@@ -93,6 +98,10 @@
 	status = "okay";
 };
 
+&i2c0 {
+	status = "okay";
+};
+
 &usb0 {
 	status = "okay";
 };
diff --git a/arch/arm/boot/dts/uniphier-ph1-sld3.dtsi b/arch/arm/boot/dts/uniphier-ph1-sld3.dtsi
index db74457..3cc90cd 100644
--- a/arch/arm/boot/dts/uniphier-ph1-sld3.dtsi
+++ b/arch/arm/boot/dts/uniphier-ph1-sld3.dtsi
@@ -77,6 +77,12 @@
 			compatible = "fixed-clock";
 			clock-frequency = <36864000>;
 		};
+
+		iobus_clk: iobus_clk {
+			#clock-cells = <0>;
+			compatible = "fixed-clock";
+			clock-frequency = <100000000>;
+		};
 	};
 
 	soc {
@@ -141,6 +147,61 @@
 			fifo-size = <64>;
 		};
 
+		i2c0: i2c at 58400000 {
+			compatible = "socionext,uniphier-i2c";
+			status = "disabled";
+			reg = <0x58400000 0x40>;
+			#address-cells = <1>;
+			#size-cells = <0>;
+			interrupts = <0 41 1>;
+			clocks = <&iobus_clk>;
+			clock-frequency = <100000>;
+		};
+
+		i2c1: i2c at 58480000 {
+			compatible = "socionext,uniphier-i2c";
+			status = "disabled";
+			reg = <0x58480000 0x40>;
+			#address-cells = <1>;
+			#size-cells = <0>;
+			interrupts = <0 42 1>;
+			clocks = <&iobus_clk>;
+			clock-frequency = <100000>;
+		};
+
+		i2c2: i2c at 58500000 {
+			compatible = "socionext,uniphier-i2c";
+			status = "disabled";
+			reg = <0x58500000 0x40>;
+			#address-cells = <1>;
+			#size-cells = <0>;
+			interrupts = <0 43 1>;
+			clocks = <&iobus_clk>;
+			clock-frequency = <100000>;
+		};
+
+		i2c3: i2c at 58580000 {
+			compatible = "socionext,uniphier-i2c";
+			status = "disabled";
+			reg = <0x58580000 0x40>;
+			#address-cells = <1>;
+			#size-cells = <0>;
+			interrupts = <0 44 1>;
+			clocks = <&iobus_clk>;
+			clock-frequency = <100000>;
+		};
+
+		/* chip-internal connection for DMD */
+		i2c4: i2c at 58600000 {
+			compatible = "socionext,uniphier-i2c";
+			reg = <0x58600000 0x40>;
+			#address-cells = <1>;
+			#size-cells = <0>;
+			interrupts = <0 45 1>;
+			clocks = <&iobus_clk>;
+			clock-frequency = <400000>;
+		};
+
 		system-bus-controller-misc at 59800000 {
 			compatible = "socionext,uniphier-system-bus-controller-misc",
 				     "syscon";
diff --git a/arch/arm/boot/dts/uniphier-ph1-sld8-ref.dts b/arch/arm/boot/dts/uniphier-ph1-sld8-ref.dts
index 9b5992a..a40a0fb 100644
--- a/arch/arm/boot/dts/uniphier-ph1-sld8-ref.dts
+++ b/arch/arm/boot/dts/uniphier-ph1-sld8-ref.dts
@@ -65,6 +65,10 @@
 		serial1 = &serial1;
 		serial2 = &serial2;
 		serial3 = &serial3;
+		i2c0 = &i2c0;
+		i2c1 = &i2c1;
+		i2c2 = &i2c2;
+		i2c3 = &i2c3;
 	};
 };
 
@@ -93,6 +97,10 @@
 	status = "okay";
 };
 
+&i2c0 {
+	status = "okay";
+};
+
 &usb0 {
 	status = "okay";
 };
diff --git a/arch/arm/boot/dts/uniphier-ph1-sld8.dtsi b/arch/arm/boot/dts/uniphier-ph1-sld8.dtsi
index 3ead910..58067df 100644
--- a/arch/arm/boot/dts/uniphier-ph1-sld8.dtsi
+++ b/arch/arm/boot/dts/uniphier-ph1-sld8.dtsi
@@ -70,6 +70,12 @@
 			compatible = "fixed-clock";
 			clock-frequency = <80000000>;
 		};
+
+		iobus_clk: iobus_clk {
+			#clock-cells = <0>;
+			compatible = "fixed-clock";
+			clock-frequency = <100000000>;
+		};
 	};
 
 	soc {
@@ -129,6 +135,58 @@
 			fifo-size = <64>;
 		};
 
+		i2c0: i2c at 58400000 {
+			compatible = "socionext,uniphier-i2c";
+			status = "disabled";
+			reg = <0x58400000 0x40>;
+			#address-cells = <1>;
+			#size-cells = <0>;
+			pinctrl-names = "default";
+			pinctrl-0 = <&pinctrl_i2c0>;
+			interrupts = <0 41 1>;
+			clocks = <&iobus_clk>;
+			clock-frequency = <100000>;
+		};
+
+		i2c1: i2c at 58480000 {
+			compatible = "socionext,uniphier-i2c";
+			status = "disabled";
+			reg = <0x58480000 0x40>;
+			#address-cells = <1>;
+			#size-cells = <0>;
+			pinctrl-names = "default";
+			pinctrl-0 = <&pinctrl_i2c1>;
+			interrupts = <0 42 1>;
+			clocks = <&iobus_clk>;
+			clock-frequency = <100000>;
+		};
+
+		/* chip-internal connection for DMD */
+		i2c2: i2c at 58500000 {
+			compatible = "socionext,uniphier-i2c";
+			reg = <0x58500000 0x40>;
+			#address-cells = <1>;
+			#size-cells = <0>;
+			pinctrl-names = "default";
+			pinctrl-0 = <&pinctrl_i2c2>;
+			interrupts = <0 43 1>;
+			clocks = <&iobus_clk>;
+			clock-frequency = <400000>;
+		};
+
+		i2c3: i2c at 58580000 {
+			compatible = "socionext,uniphier-i2c";
+			status = "disabled";
+			reg = <0x58580000 0x40>;
+			#address-cells = <1>;
+			#size-cells = <0>;
+			pinctrl-names = "default";
+			pinctrl-0 = <&pinctrl_i2c3>;
+			interrupts = <0 44 1>;
+			clocks = <&iobus_clk>;
+			clock-frequency = <100000>;
+		};
+
 		system-bus-controller-misc at 59800000 {
 			compatible = "socionext,uniphier-system-bus-controller-misc",
 				     "syscon";
diff --git a/arch/arm/boot/dts/uniphier-pinctrl.dtsi b/arch/arm/boot/dts/uniphier-pinctrl.dtsi
index 1b5b4fe..f67445f 100644
--- a/arch/arm/boot/dts/uniphier-pinctrl.dtsi
+++ b/arch/arm/boot/dts/uniphier-pinctrl.dtsi
@@ -43,6 +43,26 @@
  */
 
 &pinctrl {
+	pinctrl_i2c0: i2c0_grp {
+		groups = "i2c0";
+		function = "i2c0";
+	};
+
+	pinctrl_i2c1: i2c1_grp {
+		groups = "i2c1";
+		function = "i2c1";
+	};
+
+	pinctrl_i2c2: i2c2_grp {
+		groups = "i2c2";
+		function = "i2c2";
+	};
+
+	pinctrl_i2c3: i2c3_grp {
+		groups = "i2c3";
+		function = "i2c3";
+	};
+
 	pinctrl_uart0: uart0_grp {
 		groups = "uart0";
 		function = "uart0";
-- 
1.9.1



From yamada.masahiro at socionext.com  Thu Aug  6 03:37:47 2015
From: yamada.masahiro at socionext.com (Masahiro Yamada)
Date: Thu,  6 Aug 2015 19:37:47 +0900
Subject: [PATCH v2 3/4] ARM: dts: UniPhier: add PH1-Pro5 SoC support
In-Reply-To: <1438857468-9740-1-git-send-email-yamada.masahiro@socionext.com>
References: <1438857468-9740-1-git-send-email-yamada.masahiro@socionext.com>
Message-ID: <1438857468-9740-4-git-send-email-yamada.masahiro@socionext.com>

Initial version of UniPhier PH1-Pro5 device tree.

Signed-off-by: Masahiro Yamada <yamada.masahiro at socionext.com>
---
 arch/arm/boot/dts/uniphier-ph1-pro5.dtsi | 252 +++++++++++++++++++++++++++++++
 1 file changed, 252 insertions(+)
 create mode 100644 arch/arm/boot/dts/uniphier-ph1-pro5.dtsi

diff --git a/arch/arm/boot/dts/uniphier-ph1-pro5.dtsi b/arch/arm/boot/dts/uniphier-ph1-pro5.dtsi
new file mode 100644
index 0000000..59c2b12
--- /dev/null
+++ b/arch/arm/boot/dts/uniphier-ph1-pro5.dtsi
@@ -0,0 +1,252 @@
+/*
+ * Device Tree Source for UniPhier PH1-Pro5 SoC
+ *
+ * Copyright (C) 2015 Masahiro Yamada <yamada.masahiro at socionext.com>
+ *
+ * This file is dual-licensed: you can use it either under the terms
+ * of the GPL or the X11 license, at your option. Note that this dual
+ * licensing only applies to this file, and not this project as a
+ * whole.
+ *
+ *  a) This file is free software; you can redistribute it and/or
+ *     modify it under the terms of the GNU General Public License as
+ *     published by the Free Software Foundation; either version 2 of the
+ *     License, or (at your option) any later version.
+ *
+ *     This file is distributed in the hope that it will be useful,
+ *     but WITHOUT ANY WARRANTY; without even the implied warranty of
+ *     MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ *     GNU General Public License for more details.
+ *
+ * Or, alternatively,
+ *
+ *  b) Permission is hereby granted, free of charge, to any person
+ *     obtaining a copy of this software and associated documentation
+ *     files (the "Software"), to deal in the Software without
+ *     restriction, including without limitation the rights to use,
+ *     copy, modify, merge, publish, distribute, sublicense, and/or
+ *     sell copies of the Software, and to permit persons to whom the
+ *     Software is furnished to do so, subject to the following
+ *     conditions:
+ *
+ *     The above copyright notice and this permission notice shall be
+ *     included in all copies or substantial portions of the Software.
+ *
+ *     THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
+ *     EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES
+ *     OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
+ *     NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT
+ *     HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY,
+ *     WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
+ *     FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR
+ *     OTHER DEALINGS IN THE SOFTWARE.
+ */
+
+/include/ "skeleton.dtsi"
+
+/ {
+	compatible = "socionext,ph1-pro5";
+
+	cpus {
+		#address-cells = <1>;
+		#size-cells = <0>;
+		enable-method = "socionext,uniphier-smp";
+
+		cpu at 0 {
+			device_type = "cpu";
+			compatible = "arm,cortex-a9";
+			reg = <0>;
+		};
+
+		cpu at 1 {
+			device_type = "cpu";
+			compatible = "arm,cortex-a9";
+			reg = <1>;
+		};
+	};
+
+	clocks {
+		arm_timer_clk: arm_timer_clk {
+			#clock-cells = <0>;
+			compatible = "fixed-clock";
+			clock-frequency = <50000000>;
+		};
+
+		uart_clk: uart_clk {
+			#clock-cells = <0>;
+			compatible = "fixed-clock";
+			clock-frequency = <73728000>;
+		};
+
+		i2c_clk: i2c_clk {
+			#clock-cells = <0>;
+			compatible = "fixed-clock";
+			clock-frequency = <50000000>;
+		};
+	};
+
+	soc {
+		compatible = "simple-bus";
+		#address-cells = <1>;
+		#size-cells = <1>;
+		ranges;
+		interrupt-parent = <&intc>;
+
+		extbus: extbus {
+			compatible = "simple-bus";
+			#address-cells = <2>;
+			#size-cells = <1>;
+		};
+
+		serial0: serial at 54006800 {
+			compatible = "socionext,uniphier-uart";
+			status = "disabled";
+			reg = <0x54006800 0x40>;
+			pinctrl-names = "default";
+			pinctrl-0 = <&pinctrl_uart0>;
+			interrupts = <0 33 4>;
+			clocks = <&uart_clk>;
+		};
+
+		serial1: serial at 54006900 {
+			compatible = "socionext,uniphier-uart";
+			status = "disabled";
+			reg = <0x54006900 0x40>;
+			pinctrl-names = "default";
+			pinctrl-0 = <&pinctrl_uart1>;
+			interrupts = <0 35 4>;
+			clocks = <&uart_clk>;
+		};
+
+		serial2: serial at 54006a00 {
+			compatible = "socionext,uniphier-uart";
+			status = "disabled";
+			reg = <0x54006a00 0x40>;
+			pinctrl-names = "default";
+			pinctrl-0 = <&pinctrl_uart2>;
+			interrupts = <0 37 4>;
+			clocks = <&uart_clk>;
+		};
+
+		serial3: serial at 54006b00 {
+			compatible = "socionext,uniphier-uart";
+			status = "disabled";
+			reg = <0x54006b00 0x40>;
+			pinctrl-names = "default";
+			pinctrl-0 = <&pinctrl_uart3>;
+			interrupts = <0 177 4>;
+			clocks = <&uart_clk>;
+		};
+
+		i2c0: i2c at 58780000 {
+			compatible = "socionext,uniphier-fi2c";
+			status = "disabled";
+			reg = <0x58780000 0x80>;
+			#address-cells = <1>;
+			#size-cells = <0>;
+			pinctrl-names = "default";
+			pinctrl-0 = <&pinctrl_i2c0>;
+			interrupts = <0 41 4>;
+			clocks = <&i2c_clk>;
+			clock-frequency = <100000>;
+		};
+
+		i2c1: i2c at 58781000 {
+			compatible = "socionext,uniphier-fi2c";
+			status = "disabled";
+			reg = <0x58781000 0x80>;
+			#address-cells = <1>;
+			#size-cells = <0>;
+			pinctrl-names = "default";
+			pinctrl-0 = <&pinctrl_i2c1>;
+			interrupts = <0 42 4>;
+			clocks = <&i2c_clk>;
+			clock-frequency = <100000>;
+		};
+
+		i2c2: i2c at 58782000 {
+			compatible = "socionext,uniphier-fi2c";
+			status = "disabled";
+			reg = <0x58782000 0x80>;
+			#address-cells = <1>;
+			#size-cells = <0>;
+			pinctrl-names = "default";
+			pinctrl-0 = <&pinctrl_i2c2>;
+			interrupts = <0 43 4>;
+			clocks = <&i2c_clk>;
+			clock-frequency = <100000>;
+		};
+
+		i2c3: i2c at 58783000 {
+			compatible = "socionext,uniphier-fi2c";
+			status = "disabled";
+			reg = <0x58783000 0x80>;
+			#address-cells = <1>;
+			#size-cells = <0>;
+			pinctrl-names = "default";
+			pinctrl-0 = <&pinctrl_i2c3>;
+			interrupts = <0 44 4>;
+			clocks = <&i2c_clk>;
+			clock-frequency = <100000>;
+		};
+
+		/* i2c4 does not exist */
+
+		/* chip-internal connection for DMD */
+		i2c5: i2c at 58785000 {
+			compatible = "socionext,uniphier-fi2c";
+			reg = <0x58785000 0x80>;
+			#address-cells = <1>;
+			#size-cells = <0>;
+			interrupts = <0 25 4>;
+			clocks = <&i2c_clk>;
+			clock-frequency = <400000>;
+		};
+
+		/* chip-internal connection for HDMI */
+		i2c6: i2c at 58786000 {
+			compatible = "socionext,uniphier-fi2c";
+			reg = <0x58786000 0x80>;
+			#address-cells = <1>;
+			#size-cells = <0>;
+			interrupts = <0 26 4>;
+			clocks = <&i2c_clk>;
+			clock-frequency = <400000>;
+		};
+
+		system-bus-controller-misc at 59800000 {
+			compatible = "socionext,uniphier-system-bus-controller-misc",
+				     "syscon";
+			reg = <0x59800000 0x2000>;
+		};
+
+		pinctrl: pinctrl at 5f801000 {
+			compatible = "socionext,ph1-pro5-pinctrl", "syscon";
+			reg = <0x5f801000 0xe00>;
+		};
+
+		timer at 60000200 {
+			compatible = "arm,cortex-a9-global-timer";
+			reg = <0x60000200 0x20>;
+			interrupts = <1 11 0x304>;
+			clocks = <&arm_timer_clk>;
+		};
+
+		timer at 60000600 {
+			compatible = "arm,cortex-a9-twd-timer";
+			reg = <0x60000600 0x20>;
+			interrupts = <1 13 0x304>;
+			clocks = <&arm_timer_clk>;
+		};
+
+		intc: interrupt-controller at 60001000 {
+			compatible = "arm,cortex-a9-gic";
+			#interrupt-cells = <3>;
+			interrupt-controller;
+			reg = <0x60001000 0x1000>,
+			      <0x60000100 0x100>;
+		};
+	};
+};
+
+/include/ "uniphier-pinctrl.dtsi"
-- 
1.9.1



From yamada.masahiro at socionext.com  Thu Aug  6 03:37:48 2015
From: yamada.masahiro at socionext.com (Masahiro Yamada)
Date: Thu,  6 Aug 2015 19:37:48 +0900
Subject: [PATCH v2 4/4] ARM: dts: UniPhier: add ProXstream2 and PH1-LD6b
 SoC/board support
In-Reply-To: <1438857468-9740-1-git-send-email-yamada.masahiro@socionext.com>
References: <1438857468-9740-1-git-send-email-yamada.masahiro@socionext.com>
Message-ID: <1438857468-9740-5-git-send-email-yamada.masahiro@socionext.com>

Initial version of DTSI for ProXstream2 and PH1-LD6b and DTS for
PH1-LD6b reference board.

Signed-off-by: Masahiro Yamada <yamada.masahiro at socionext.com>
---
 arch/arm/boot/dts/Makefile                  |   3 +-
 arch/arm/boot/dts/uniphier-ph1-ld6b-ref.dts | 105 +++++++++++
 arch/arm/boot/dts/uniphier-ph1-ld6b.dtsi    |  67 +++++++
 arch/arm/boot/dts/uniphier-proxstream2.dtsi | 273 ++++++++++++++++++++++++++++
 4 files changed, 447 insertions(+), 1 deletion(-)
 create mode 100644 arch/arm/boot/dts/uniphier-ph1-ld6b-ref.dts
 create mode 100644 arch/arm/boot/dts/uniphier-ph1-ld6b.dtsi
 create mode 100644 arch/arm/boot/dts/uniphier-proxstream2.dtsi

diff --git a/arch/arm/boot/dts/Makefile b/arch/arm/boot/dts/Makefile
index 246473a..6eb3f2f 100644
--- a/arch/arm/boot/dts/Makefile
+++ b/arch/arm/boot/dts/Makefile
@@ -645,7 +645,8 @@ dtb-$(CONFIG_ARCH_UNIPHIER) += \
 	uniphier-ph1-sld3-ref.dtb \
 	uniphier-ph1-ld4-ref.dtb \
 	uniphier-ph1-pro4-ref.dtb \
-	uniphier-ph1-sld8-ref.dtb
+	uniphier-ph1-sld8-ref.dtb \
+	uniphier-ph1-ld6b-ref.dtb
 dtb-$(CONFIG_ARCH_VERSATILE) += \
 	versatile-ab.dtb \
 	versatile-pb.dtb
diff --git a/arch/arm/boot/dts/uniphier-ph1-ld6b-ref.dts b/arch/arm/boot/dts/uniphier-ph1-ld6b-ref.dts
new file mode 100644
index 0000000..33963ac
--- /dev/null
+++ b/arch/arm/boot/dts/uniphier-ph1-ld6b-ref.dts
@@ -0,0 +1,105 @@
+/*
+ * Device Tree Source for UniPhier PH1-LD6b Reference Board
+ *
+ * Copyright (C) 2015 Masahiro Yamada <yamada.masahiro at socionext.com>
+ *
+ * This file is dual-licensed: you can use it either under the terms
+ * of the GPL or the X11 license, at your option. Note that this dual
+ * licensing only applies to this file, and not this project as a
+ * whole.
+ *
+ *  a) This file is free software; you can redistribute it and/or
+ *     modify it under the terms of the GNU General Public License as
+ *     published by the Free Software Foundation; either version 2 of the
+ *     License, or (at your option) any later version.
+ *
+ *     This file is distributed in the hope that it will be useful,
+ *     but WITHOUT ANY WARRANTY; without even the implied warranty of
+ *     MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ *     GNU General Public License for more details.
+ *
+ * Or, alternatively,
+ *
+ *  b) Permission is hereby granted, free of charge, to any person
+ *     obtaining a copy of this software and associated documentation
+ *     files (the "Software"), to deal in the Software without
+ *     restriction, including without limitation the rights to use,
+ *     copy, modify, merge, publish, distribute, sublicense, and/or
+ *     sell copies of the Software, and to permit persons to whom the
+ *     Software is furnished to do so, subject to the following
+ *     conditions:
+ *
+ *     The above copyright notice and this permission notice shall be
+ *     included in all copies or substantial portions of the Software.
+ *
+ *     THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
+ *     EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES
+ *     OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
+ *     NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT
+ *     HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY,
+ *     WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
+ *     FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR
+ *     OTHER DEALINGS IN THE SOFTWARE.
+ */
+
+/dts-v1/;
+/include/ "uniphier-ph1-ld6b.dtsi"
+/include/ "uniphier-ref-daughter.dtsi"
+/include/ "uniphier-support-card.dtsi"
+
+/ {
+	model = "UniPhier PH1-LD6b Reference Board";
+	compatible = "socionext,ph1-ld6b-ref", "socionext,ph1-ld6b";
+
+	memory {
+		device_type = "memory";
+		reg = <0x80000000 0x80000000>;
+	};
+
+	chosen {
+		bootargs = "console=ttyS0,115200";
+		stdout-path = &serial0;
+	};
+
+	aliases {
+		serial0 = &serial0;
+		serial1 = &serial1;
+		serial2 = &serial2;
+		i2c0 = &i2c0;
+		i2c1 = &i2c1;
+		i2c2 = &i2c2;
+		i2c3 = &i2c3;
+		i2c4 = &i2c4;
+		i2c5 = &i2c5;
+		i2c6 = &i2c6;
+	};
+};
+
+&extbus {
+	ranges = <0 0x00000000 0x0f000000 0x01000000
+		  1 0x00000000 0x00000000 0x08000000>;
+};
+
+&support_card {
+	ranges = <0x00000000 1 0x03f00000 0x00100000>;
+};
+
+&ethsc {
+	interrupts = <0 50 4>;
+};
+
+&serial0 {
+	status = "okay";
+};
+
+&serial1 {
+	status = "okay";
+};
+
+&serial2 {
+	status = "okay";
+};
+
+&i2c0 {
+	status = "okay";
+};
diff --git a/arch/arm/boot/dts/uniphier-ph1-ld6b.dtsi b/arch/arm/boot/dts/uniphier-ph1-ld6b.dtsi
new file mode 100644
index 0000000..c6499ee
--- /dev/null
+++ b/arch/arm/boot/dts/uniphier-ph1-ld6b.dtsi
@@ -0,0 +1,67 @@
+/*
+ * Device Tree Source for UniPhier PH1-LD6b SoC
+ *
+ * Copyright (C) 2015 Masahiro Yamada <yamada.masahiro at socionext.com>
+ *
+ * This file is dual-licensed: you can use it either under the terms
+ * of the GPL or the X11 license, at your option. Note that this dual
+ * licensing only applies to this file, and not this project as a
+ * whole.
+ *
+ *  a) This file is free software; you can redistribute it and/or
+ *     modify it under the terms of the GNU General Public License as
+ *     published by the Free Software Foundation; either version 2 of the
+ *     License, or (at your option) any later version.
+ *
+ *     This file is distributed in the hope that it will be useful,
+ *     but WITHOUT ANY WARRANTY; without even the implied warranty of
+ *     MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ *     GNU General Public License for more details.
+ *
+ * Or, alternatively,
+ *
+ *  b) Permission is hereby granted, free of charge, to any person
+ *     obtaining a copy of this software and associated documentation
+ *     files (the "Software"), to deal in the Software without
+ *     restriction, including without limitation the rights to use,
+ *     copy, modify, merge, publish, distribute, sublicense, and/or
+ *     sell copies of the Software, and to permit persons to whom the
+ *     Software is furnished to do so, subject to the following
+ *     conditions:
+ *
+ *     The above copyright notice and this permission notice shall be
+ *     included in all copies or substantial portions of the Software.
+ *
+ *     THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
+ *     EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES
+ *     OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
+ *     NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT
+ *     HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY,
+ *     WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
+ *     FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR
+ *     OTHER DEALINGS IN THE SOFTWARE.
+ */
+
+/*
+ * PH1-LD6b consists of two silicon dies: D-chip and A-chip.
+ * The D-chip (digital chip) is the same as the ProXstream2 die.
+ * Reuse the ProXstream2 device tree with some properties overridden.
+ */
+/include/ "uniphier-proxstream2.dtsi"
+
+/ {
+	compatible = "socionext,ph1-ld6b";
+};
+
+/* UART3 unavilable: the pads are not wired to the package balls */
+&serial3 {
+	status = "disabled";
+};
+
+/*
+ * PH1-LD6b and ProXstream2 have completely different packages,
+ * which makes the pinctrl driver unshareable.
+ */
+&pinctrl {
+	compatible = "socionext,ph1-ld6b-pinctrl", "syscon";
+};
diff --git a/arch/arm/boot/dts/uniphier-proxstream2.dtsi b/arch/arm/boot/dts/uniphier-proxstream2.dtsi
new file mode 100644
index 0000000..ccf795a
--- /dev/null
+++ b/arch/arm/boot/dts/uniphier-proxstream2.dtsi
@@ -0,0 +1,273 @@
+/*
+ * Device Tree Source for UniPhier ProXstream2 SoC
+ *
+ * Copyright (C) 2015 Masahiro Yamada <yamada.masahiro at socionext.com>
+ *
+ * This file is dual-licensed: you can use it either under the terms
+ * of the GPL or the X11 license, at your option. Note that this dual
+ * licensing only applies to this file, and not this project as a
+ * whole.
+ *
+ *  a) This file is free software; you can redistribute it and/or
+ *     modify it under the terms of the GNU General Public License as
+ *     published by the Free Software Foundation; either version 2 of the
+ *     License, or (at your option) any later version.
+ *
+ *     This file is distributed in the hope that it will be useful,
+ *     but WITHOUT ANY WARRANTY; without even the implied warranty of
+ *     MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ *     GNU General Public License for more details.
+ *
+ * Or, alternatively,
+ *
+ *  b) Permission is hereby granted, free of charge, to any person
+ *     obtaining a copy of this software and associated documentation
+ *     files (the "Software"), to deal in the Software without
+ *     restriction, including without limitation the rights to use,
+ *     copy, modify, merge, publish, distribute, sublicense, and/or
+ *     sell copies of the Software, and to permit persons to whom the
+ *     Software is furnished to do so, subject to the following
+ *     conditions:
+ *
+ *     The above copyright notice and this permission notice shall be
+ *     included in all copies or substantial portions of the Software.
+ *
+ *     THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
+ *     EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES
+ *     OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
+ *     NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT
+ *     HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY,
+ *     WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
+ *     FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR
+ *     OTHER DEALINGS IN THE SOFTWARE.
+ */
+
+/include/ "skeleton.dtsi"
+
+/ {
+	compatible = "socionext,proxstream2";
+
+	cpus {
+		#address-cells = <1>;
+		#size-cells = <0>;
+		enable-method = "socionext,uniphier-smp";
+
+		cpu at 0 {
+			device_type = "cpu";
+			compatible = "arm,cortex-a9";
+			reg = <0>;
+		};
+
+		cpu at 1 {
+			device_type = "cpu";
+			compatible = "arm,cortex-a9";
+			reg = <1>;
+		};
+
+		cpu at 2 {
+			device_type = "cpu";
+			compatible = "arm,cortex-a9";
+			reg = <2>;
+		};
+
+		cpu at 3 {
+			device_type = "cpu";
+			compatible = "arm,cortex-a9";
+			reg = <3>;
+		};
+	};
+
+	clocks {
+		arm_timer_clk: arm_timer_clk {
+			#clock-cells = <0>;
+			compatible = "fixed-clock";
+			clock-frequency = <50000000>;
+		};
+
+		uart_clk: uart_clk {
+			#clock-cells = <0>;
+			compatible = "fixed-clock";
+			clock-frequency = <88900000>;
+		};
+
+		i2c_clk: i2c_clk {
+			#clock-cells = <0>;
+			compatible = "fixed-clock";
+			clock-frequency = <50000000>;
+		};
+	};
+
+	soc {
+		compatible = "simple-bus";
+		#address-cells = <1>;
+		#size-cells = <1>;
+		ranges;
+		interrupt-parent = <&intc>;
+
+		extbus: extbus {
+			compatible = "simple-bus";
+			#address-cells = <2>;
+			#size-cells = <1>;
+		};
+
+		serial0: serial at 54006800 {
+			compatible = "socionext,uniphier-uart";
+			status = "disabled";
+			reg = <0x54006800 0x40>;
+			pinctrl-names = "default";
+			pinctrl-0 = <&pinctrl_uart0>;
+			interrupts = <0 33 4>;
+			clocks = <&uart_clk>;
+		};
+
+		serial1: serial at 54006900 {
+			compatible = "socionext,uniphier-uart";
+			status = "disabled";
+			reg = <0x54006900 0x40>;
+			pinctrl-names = "default";
+			pinctrl-0 = <&pinctrl_uart1>;
+			interrupts = <0 35 4>;
+			clocks = <&uart_clk>;
+		};
+
+		serial2: serial at 54006a00 {
+			compatible = "socionext,uniphier-uart";
+			status = "disabled";
+			reg = <0x54006a00 0x40>;
+			pinctrl-names = "default";
+			pinctrl-0 = <&pinctrl_uart2>;
+			interrupts = <0 37 4>;
+			clocks = <&uart_clk>;
+		};
+
+		serial3: serial at 54006b00 {
+			compatible = "socionext,uniphier-uart";
+			status = "disabled";
+			reg = <0x54006b00 0x40>;
+			pinctrl-names = "default";
+			pinctrl-0 = <&pinctrl_uart3>;
+			interrupts = <0 177 4>;
+			clocks = <&uart_clk>;
+		};
+
+		i2c0: i2c at 58780000 {
+			compatible = "socionext,uniphier-fi2c";
+			status = "disabled";
+			reg = <0x58780000 0x80>;
+			#address-cells = <1>;
+			#size-cells = <0>;
+			pinctrl-names = "default";
+			pinctrl-0 = <&pinctrl_i2c0>;
+			interrupts = <0 41 4>;
+			clocks = <&i2c_clk>;
+			clock-frequency = <100000>;
+		};
+
+		i2c1: i2c at 58781000 {
+			compatible = "socionext,uniphier-fi2c";
+			status = "disabled";
+			reg = <0x58781000 0x80>;
+			#address-cells = <1>;
+			#size-cells = <0>;
+			pinctrl-names = "default";
+			pinctrl-0 = <&pinctrl_i2c1>;
+			interrupts = <0 42 4>;
+			clocks = <&i2c_clk>;
+			clock-frequency = <100000>;
+		};
+
+		i2c2: i2c at 58782000 {
+			compatible = "socionext,uniphier-fi2c";
+			status = "disabled";
+			reg = <0x58782000 0x80>;
+			#address-cells = <1>;
+			#size-cells = <0>;
+			pinctrl-names = "default";
+			pinctrl-0 = <&pinctrl_i2c2>;
+			interrupts = <0 43 4>;
+			clocks = <&i2c_clk>;
+			clock-frequency = <100000>;
+		};
+
+		i2c3: i2c at 58783000 {
+			compatible = "socionext,uniphier-fi2c";
+			status = "disabled";
+			reg = <0x58783000 0x80>;
+			#address-cells = <1>;
+			#size-cells = <0>;
+			pinctrl-names = "default";
+			pinctrl-0 = <&pinctrl_i2c3>;
+			interrupts = <0 44 4>;
+			clocks = <&i2c_clk>;
+			clock-frequency = <100000>;
+		};
+
+		/* chip-internal connection for DMD */
+		i2c4: i2c at 58784000 {
+			compatible = "socionext,uniphier-fi2c";
+			reg = <0x58784000 0x80>;
+			#address-cells = <1>;
+			#size-cells = <0>;
+			interrupts = <0 45 4>;
+			clocks = <&i2c_clk>;
+			clock-frequency = <400000>;
+		};
+
+		/* chip-internal connection for STM */
+		i2c5: i2c at 58785000 {
+			compatible = "socionext,uniphier-fi2c";
+			reg = <0x58785000 0x80>;
+			#address-cells = <1>;
+			#size-cells = <0>;
+			interrupts = <0 25 4>;
+			clocks = <&i2c_clk>;
+			clock-frequency = <400000>;
+		};
+
+		/* chip-internal connection for HDMI */
+		i2c6: i2c at 58786000 {
+			compatible = "socionext,uniphier-fi2c";
+			reg = <0x58786000 0x80>;
+			#address-cells = <1>;
+			#size-cells = <0>;
+			interrupts = <0 26 4>;
+			clocks = <&i2c_clk>;
+			clock-frequency = <400000>;
+		};
+
+		system-bus-controller-misc at 59800000 {
+			compatible = "socionext,uniphier-system-bus-controller-misc",
+				     "syscon";
+			reg = <0x59800000 0x2000>;
+		};
+
+		pinctrl: pinctrl at 5f801000 {
+			compatible = "socionext,proxstream2-pinctrl", "syscon";
+			reg = <0x5f801000 0xe00>;
+		};
+
+		timer at 60000200 {
+			compatible = "arm,cortex-a9-global-timer";
+			reg = <0x60000200 0x20>;
+			interrupts = <1 11 0x304>;
+			clocks = <&arm_timer_clk>;
+		};
+
+		timer at 60000600 {
+			compatible = "arm,cortex-a9-twd-timer";
+			reg = <0x60000600 0x20>;
+			interrupts = <1 13 0x304>;
+			clocks = <&arm_timer_clk>;
+		};
+
+		intc: interrupt-controller at 60001000 {
+			compatible = "arm,cortex-a9-gic";
+			#interrupt-cells = <3>;
+			interrupt-controller;
+			reg = <0x60001000 0x1000>,
+			      <0x60000100 0x100>;
+		};
+	};
+};
+
+/include/ "uniphier-pinctrl.dtsi"
-- 
1.9.1



From rnayak at codeaurora.org  Thu Aug  6 03:37:41 2015
From: rnayak at codeaurora.org (Rajendra Nayak)
Date: Thu,  6 Aug 2015 16:07:41 +0530
Subject: [PATCH v8 00/13] qcom: Add support for GDSCs
Message-ID: <1438857474-20262-1-git-send-email-rnayak@codeaurora.org>

GDSCs (Global Distributed Switch Controllers) control switches
that supply power to an on-chip power domain and hence can be
programmed in SW to safely power collapse and restore power to the
respective PDs. They are part of a considerable number of recent QCOM
SoCs (This series adds support for msm8974, msm8916 and apq8084 devices)
and are part of the Clock control block.

The series implements support for GDSC using the genpd framework
modelling these as SW controllable power domains and uses PM clocks
to control clocks within the gdsc.

* Client drivers which plan to use GDSC can refer to
  Documentation/devicetree/bindings/power/power_domain.txt to know
  how to hook up the power domain for the device through DT
* Runtime PM specific documentation can be found in
  Documentation/power/runtime_pm.txt
* Patches are based of 4.2-rc5

Tested with and without CONFIG_PM on db8074, IFC6540 and
db410c (arm64)

Changes since v7:
* used of_clk_get_from_provider() instead of a con_id based clk_get()
This is based on an offlist discussion with Stephen.
* Moved the clock control patches to the end of the series, to enable
the rest of the gdsc support patches (1 to 10) to get merged if
clock control needs more discussions
* Added missing gdscs' from mmcc apq8084 (pointed to by Stan)

Changes since v6:
* removed hardcoded con_ids, now part of gdsc struct
* other minor review fixes

Changes since v5:
* Added support to manage clocks with !CONFIG_PM
* Added RET/OFF support
* Added support to assert/deassert reset while the GDSC is ON

Changes since v4:
* Added clock control support using PM clocks
* Included WA to enable an RCG (needed for Oxili gdsc in 8916)

Changes since v3:
* static inline'd gdsc_register/unregister stubs
* error check fixes in gdsc_register
* dropped oxili_gdsc for 8916 as its broken and needs additional
WA's not part of this series
* split dts and driver changes into seperate patches

Changes since v2:
* gdsc_unregister added
* gdsc_register/unregister introduced in patch 1/6

Changes since v1:
* added err checks for regmap apis
* added gdsc_register() in gdsc.c

Rajendra Nayak (9):
  clk: qcom: gdsc: Prepare common clk probe to register gdscs
  clk: qcom: gdsc: Add support for Memory RET/OFF
  clk: qcom: gdsc: Add support for ON only state
  clk: qcom: gdsc: Add GDSCs in msm8916 GCC
  clk: qcom: gdsc: Add GDSCs in apq8084 GCC
  arm: dts: qcom: Add #power-domain-cells property
  clk: qcom: gdsc: Use PM clocks to control gdsc clocks
  clk: qcom: gdsc: Enable an RCG before turing on the gdsc
  clk: qcom: gdsc: Manage clocks with !CONFIG_PM

Stephane Viau (1):
  clk: qcom: gdsc: Add GDSCs in apq8084 MMCC

Stephen Boyd (3):
  clk: qcom: Add support for GDSCs
  clk: qcom: gdsc: Add GDSCs in msm8974 GCC
  clk: qcom: gdsc: Add GDSCs in msm8974 MMCC

 arch/arm/boot/dts/qcom-apq8084.dtsi           |   1 +
 arch/arm/boot/dts/qcom-msm8974.dtsi           |   2 +
 arch/arm64/boot/dts/qcom/msm8916.dtsi         |   1 +
 drivers/clk/qcom/Kconfig                      |   9 +
 drivers/clk/qcom/Makefile                     |   1 +
 drivers/clk/qcom/common.c                     |  16 +-
 drivers/clk/qcom/common.h                     |   2 +
 drivers/clk/qcom/gcc-apq8084.c                |  42 +++
 drivers/clk/qcom/gcc-msm8916.c                |  52 ++++
 drivers/clk/qcom/gcc-msm8974.c                |  15 +
 drivers/clk/qcom/gdsc.c                       | 379 ++++++++++++++++++++++++++
 drivers/clk/qcom/gdsc.h                       |  87 ++++++
 drivers/clk/qcom/mmcc-apq8084.c               |  86 +++++-
 drivers/clk/qcom/mmcc-msm8974.c               |  72 +++++
 include/dt-bindings/clock/qcom,gcc-apq8084.h  |   6 +
 include/dt-bindings/clock/qcom,gcc-msm8916.h  |   8 +
 include/dt-bindings/clock/qcom,gcc-msm8974.h  |   3 +
 include/dt-bindings/clock/qcom,mmcc-apq8084.h |  10 +
 include/dt-bindings/clock/qcom,mmcc-msm8974.h |   8 +
 19 files changed, 798 insertions(+), 2 deletions(-)
 create mode 100644 drivers/clk/qcom/gdsc.c
 create mode 100644 drivers/clk/qcom/gdsc.h

-- 
QUALCOMM INDIA, on behalf of Qualcomm Innovation Center, Inc. is a member
of Code Aurora Forum, hosted by The Linux Foundation



From rnayak at codeaurora.org  Thu Aug  6 03:37:43 2015
From: rnayak at codeaurora.org (Rajendra Nayak)
Date: Thu,  6 Aug 2015 16:07:43 +0530
Subject: [PATCH v8 02/13] clk: qcom: gdsc: Prepare common clk probe to
 register gdscs
In-Reply-To: <1438857474-20262-1-git-send-email-rnayak@codeaurora.org>
References: <1438857474-20262-1-git-send-email-rnayak@codeaurora.org>
Message-ID: <1438857474-20262-3-git-send-email-rnayak@codeaurora.org>

The common clk probe registers a clk provider and a reset controller.
Update it to register a genpd provider using the gdsc data provided
by each platform.

Signed-off-by: Rajendra Nayak <rnayak at codeaurora.org>
---
 drivers/clk/qcom/common.c | 15 ++++++++++++++-
 drivers/clk/qcom/common.h |  2 ++
 2 files changed, 16 insertions(+), 1 deletion(-)

diff --git a/drivers/clk/qcom/common.c b/drivers/clk/qcom/common.c
index f7101e3..a319aa8 100644
--- a/drivers/clk/qcom/common.c
+++ b/drivers/clk/qcom/common.c
@@ -21,6 +21,7 @@
 #include "clk-rcg.h"
 #include "clk-regmap.h"
 #include "reset.h"
+#include "gdsc.h"
 
 struct qcom_cc {
 	struct qcom_reset_controller reset;
@@ -120,8 +121,19 @@ int qcom_cc_really_probe(struct platform_device *pdev,
 
 	ret = reset_controller_register(&reset->rcdev);
 	if (ret)
-		of_clk_del_provider(dev->of_node);
+		goto err_reset;
 
+	if (desc->gdscs && desc->num_gdscs) {
+		ret = gdsc_register(dev, desc->gdscs, desc->num_gdscs, regmap);
+		if (ret)
+			goto err_pd;
+	}
+
+	return 0;
+err_pd:
+	reset_controller_unregister(&reset->rcdev);
+err_reset:
+	of_clk_del_provider(dev->of_node);
 	return ret;
 }
 EXPORT_SYMBOL_GPL(qcom_cc_really_probe);
@@ -140,6 +152,7 @@ EXPORT_SYMBOL_GPL(qcom_cc_probe);
 
 void qcom_cc_remove(struct platform_device *pdev)
 {
+	gdsc_unregister(&pdev->dev);
 	of_clk_del_provider(pdev->dev.of_node);
 	reset_controller_unregister(platform_get_drvdata(pdev));
 }
diff --git a/drivers/clk/qcom/common.h b/drivers/clk/qcom/common.h
index 7a0e737..2892b71f 100644
--- a/drivers/clk/qcom/common.h
+++ b/drivers/clk/qcom/common.h
@@ -28,6 +28,8 @@ struct qcom_cc_desc {
 	size_t num_clks;
 	const struct qcom_reset_map *resets;
 	size_t num_resets;
+	struct gdsc **gdscs;
+	size_t num_gdscs;
 };
 
 extern const struct freq_tbl *qcom_find_freq(const struct freq_tbl *f,
-- 
QUALCOMM INDIA, on behalf of Qualcomm Innovation Center, Inc. is a member
of Code Aurora Forum, hosted by The Linux Foundation



From rnayak at codeaurora.org  Thu Aug  6 03:37:42 2015
From: rnayak at codeaurora.org (Rajendra Nayak)
Date: Thu,  6 Aug 2015 16:07:42 +0530
Subject: [PATCH v8 01/13] clk: qcom: Add support for GDSCs
In-Reply-To: <1438857474-20262-1-git-send-email-rnayak@codeaurora.org>
References: <1438857474-20262-1-git-send-email-rnayak@codeaurora.org>
Message-ID: <1438857474-20262-2-git-send-email-rnayak@codeaurora.org>

From: Stephen Boyd <sboyd at codeaurora.org>

GDSCs (Global Distributed Switch Controllers) are responsible for
safely collapsing and restoring power to peripherals in the SoC.
These are best modelled as power domains using genpd and given
the registers are scattered throughout the clock controller register
space, its best to have the support added through the clock driver.

Signed-off-by: Stephen Boyd <sboyd at codeaurora.org>
Signed-off-by: Rajendra Nayak <rnayak at codeaurora.org>
---
 drivers/clk/qcom/Kconfig  |   4 ++
 drivers/clk/qcom/Makefile |   1 +
 drivers/clk/qcom/gdsc.c   | 171 ++++++++++++++++++++++++++++++++++++++++++++++
 drivers/clk/qcom/gdsc.h   |  46 +++++++++++++
 4 files changed, 222 insertions(+)
 create mode 100644 drivers/clk/qcom/gdsc.c
 create mode 100644 drivers/clk/qcom/gdsc.h

diff --git a/drivers/clk/qcom/Kconfig b/drivers/clk/qcom/Kconfig
index 59d1666..d3a695b 100644
--- a/drivers/clk/qcom/Kconfig
+++ b/drivers/clk/qcom/Kconfig
@@ -39,6 +39,10 @@ config IPQ_LCC_806X
 	  Say Y if you want to use audio devices such as i2s, pcm,
 	  S/PDIF, etc.
 
+config QCOM_GDSC
+	bool
+	select PM_GENERIC_DOMAINS if PM
+
 config MSM_GCC_8660
 	tristate "MSM8660 Global Clock Controller"
 	depends on COMMON_CLK_QCOM
diff --git a/drivers/clk/qcom/Makefile b/drivers/clk/qcom/Makefile
index 50b337a..fe62523 100644
--- a/drivers/clk/qcom/Makefile
+++ b/drivers/clk/qcom/Makefile
@@ -9,6 +9,7 @@ clk-qcom-y += clk-branch.o
 clk-qcom-y += clk-regmap-divider.o
 clk-qcom-y += clk-regmap-mux.o
 clk-qcom-y += reset.o
+clk-qcom-$(CONFIG_QCOM_GDSC) += gdsc.o
 
 obj-$(CONFIG_APQ_GCC_8084) += gcc-apq8084.o
 obj-$(CONFIG_APQ_MMCC_8084) += mmcc-apq8084.o
diff --git a/drivers/clk/qcom/gdsc.c b/drivers/clk/qcom/gdsc.c
new file mode 100644
index 0000000..469b4c4
--- /dev/null
+++ b/drivers/clk/qcom/gdsc.c
@@ -0,0 +1,171 @@
+/*
+ * Copyright (c) 2015, The Linux Foundation. All rights reserved.
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License version 2 and
+ * only 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/bitops.h>
+#include <linux/delay.h>
+#include <linux/err.h>
+#include <linux/jiffies.h>
+#include <linux/kernel.h>
+#include <linux/pm_domain.h>
+#include <linux/regmap.h>
+#include <linux/slab.h>
+#include "gdsc.h"
+
+#define PWR_ON_MASK		BIT(31)
+#define EN_REST_WAIT_MASK	GENMASK_ULL(23, 20)
+#define EN_FEW_WAIT_MASK	GENMASK_ULL(19, 16)
+#define CLK_DIS_WAIT_MASK	GENMASK_ULL(15, 12)
+#define SW_OVERRIDE_MASK	BIT(2)
+#define HW_CONTROL_MASK		BIT(1)
+#define SW_COLLAPSE_MASK	BIT(0)
+
+/* Wait 2^n CXO cycles between all states. Here, n=2 (4 cycles). */
+#define EN_REST_WAIT_VAL	(0x2 << 20)
+#define EN_FEW_WAIT_VAL		(0x8 << 16)
+#define CLK_DIS_WAIT_VAL	(0x2 << 12)
+
+#define TIMEOUT_US		100
+
+#define domain_to_gdsc(domain) container_of(domain, struct gdsc, pd)
+
+static int gdsc_is_enabled(struct gdsc *sc)
+{
+	u32 val;
+	int ret;
+
+	ret = regmap_read(sc->regmap, sc->gdscr, &val);
+	if (ret)
+		return ret;
+
+	return !!(val & PWR_ON_MASK);
+}
+
+static int gdsc_toggle_logic(struct gdsc *sc, bool en)
+{
+	int ret;
+	u32 val = en ? 0 : SW_COLLAPSE_MASK;
+	u32 check = en ? PWR_ON_MASK : 0;
+	unsigned long timeout;
+
+	ret = regmap_update_bits(sc->regmap, sc->gdscr, SW_COLLAPSE_MASK, val);
+	if (ret)
+		return ret;
+
+	timeout = jiffies + usecs_to_jiffies(TIMEOUT_US);
+	do {
+		ret = regmap_read(sc->regmap, sc->gdscr, &val);
+		if (ret)
+			return ret;
+
+		if ((val & PWR_ON_MASK) == check)
+			return 0;
+	} while (time_before(jiffies, timeout));
+
+	ret = regmap_read(sc->regmap, sc->gdscr, &val);
+	if (ret)
+		return ret;
+
+	if ((val & PWR_ON_MASK) == check)
+		return 0;
+
+	return -ETIMEDOUT;
+}
+
+static int gdsc_enable(struct generic_pm_domain *domain)
+{
+	struct gdsc *sc = domain_to_gdsc(domain);
+	int ret;
+
+	ret = gdsc_toggle_logic(sc, true);
+	if (ret)
+		return ret;
+	/*
+	 * If clocks to this power domain were already on, they will take an
+	 * additional 4 clock cycles to re-enable after the power domain is
+	 * enabled. Delay to account for this. A delay is also needed to ensure
+	 * clocks are not enabled within 400ns of enabling power to the
+	 * memories.
+	 */
+	udelay(1);
+
+	return 0;
+}
+
+static int gdsc_disable(struct generic_pm_domain *domain)
+{
+	struct gdsc *sc = domain_to_gdsc(domain);
+
+	return gdsc_toggle_logic(sc, false);
+}
+
+static int gdsc_init(struct gdsc *sc)
+{
+	u32 mask, val;
+	int on, ret;
+
+	/*
+	 * Disable HW trigger: collapse/restore occur based on registers writes.
+	 * Disable SW override: Use hardware state-machine for sequencing.
+	 * Configure wait time between states.
+	 */
+	mask = HW_CONTROL_MASK | SW_OVERRIDE_MASK |
+	       EN_REST_WAIT_MASK | EN_FEW_WAIT_MASK | CLK_DIS_WAIT_MASK;
+	val = EN_REST_WAIT_VAL | EN_FEW_WAIT_VAL | CLK_DIS_WAIT_VAL;
+	ret = regmap_update_bits(sc->regmap, sc->gdscr, mask, val);
+	if (ret)
+		return ret;
+
+	on = gdsc_is_enabled(sc);
+	if (on < 0)
+		return on;
+
+	sc->pd.power_off = gdsc_disable;
+	sc->pd.power_on = gdsc_enable;
+	pm_genpd_init(&sc->pd, NULL, !on);
+
+	return 0;
+}
+
+int gdsc_register(struct device *dev, struct gdsc **scs, size_t num,
+		  struct regmap *regmap)
+{
+	int i, ret;
+	struct genpd_onecell_data *data;
+
+	data = devm_kzalloc(dev, sizeof(*data), GFP_KERNEL);
+	if (!data)
+		return -ENOMEM;
+
+	data->domains = devm_kcalloc(dev, num, sizeof(*data->domains),
+				     GFP_KERNEL);
+	if (!data->domains)
+		return -ENOMEM;
+
+	data->num_domains = num;
+	for (i = 0; i < num; i++) {
+		if (!scs[i])
+			continue;
+		scs[i]->regmap = regmap;
+		ret = gdsc_init(scs[i]);
+		if (ret)
+			return ret;
+		data->domains[i] = &scs[i]->pd;
+	}
+
+	return of_genpd_add_provider_onecell(dev->of_node, data);
+}
+
+void gdsc_unregister(struct device *dev)
+{
+	of_genpd_del_provider(dev->of_node);
+}
diff --git a/drivers/clk/qcom/gdsc.h b/drivers/clk/qcom/gdsc.h
new file mode 100644
index 0000000..f578a0c
--- /dev/null
+++ b/drivers/clk/qcom/gdsc.h
@@ -0,0 +1,46 @@
+/*
+ * Copyright (c) 2015, The Linux Foundation. All rights reserved.
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License version 2 and
+ * only 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.
+ */
+
+#ifndef __QCOM_GDSC_H__
+#define __QCOM_GDSC_H__
+
+#include <linux/err.h>
+#include <linux/pm_domain.h>
+
+struct regmap;
+
+/**
+ * struct gdsc - Globally Distributed Switch Controller
+ * @pd: generic power domain
+ * @regmap: regmap for MMIO accesses
+ * @gdscr: gsdc control register
+ */
+struct gdsc {
+	struct generic_pm_domain	pd;
+	struct regmap			*regmap;
+	unsigned int			gdscr;
+};
+
+#ifdef CONFIG_QCOM_GDSC
+int gdsc_register(struct device *, struct gdsc **, size_t n, struct regmap *);
+void gdsc_unregister(struct device *);
+#else
+static inline int gdsc_register(struct device *d, struct gdsc **g, size_t n,
+				struct regmap *r)
+{
+	return -ENOSYS;
+}
+
+static inline void gdsc_unregister(struct device *d) {};
+#endif /* CONFIG_QCOM_GDSC */
+#endif /* __QCOM_GDSC_H__ */
-- 
QUALCOMM INDIA, on behalf of Qualcomm Innovation Center, Inc. is a member
of Code Aurora Forum, hosted by The Linux Foundation



From rnayak at codeaurora.org  Thu Aug  6 03:37:44 2015
From: rnayak at codeaurora.org (Rajendra Nayak)
Date: Thu,  6 Aug 2015 16:07:44 +0530
Subject: [PATCH v8 03/13] clk: qcom: gdsc: Add support for Memory RET/OFF
In-Reply-To: <1438857474-20262-1-git-send-email-rnayak@codeaurora.org>
References: <1438857474-20262-1-git-send-email-rnayak@codeaurora.org>
Message-ID: <1438857474-20262-4-git-send-email-rnayak@codeaurora.org>

Along with the GDSC power switch, there is additional control
to either retain all memory (core and peripheral) within a given
powerdomain or to turn them off while the GDSC is powered down.
Add support for these by modelling a RET state where all
memory is retained and an OFF state where all memory gets turned
off.
The controls provided are granular enough to be able to support
various differnt levels of RET states, like a 'shallow RET' with all memory
retained and a 'deep RET' with some memory retained while some others
are lost. The current patch does not support this and considers
just one RET state where all memory is retained. Futher work, if
needed can support multiple different levels of RET state.

Signed-off-by: Rajendra Nayak <rnayak at codeaurora.org>
---
 drivers/clk/qcom/gdsc.c | 33 +++++++++++++++++++++++++++++++++
 drivers/clk/qcom/gdsc.h | 13 +++++++++++++
 2 files changed, 46 insertions(+)

diff --git a/drivers/clk/qcom/gdsc.c b/drivers/clk/qcom/gdsc.c
index 469b4c4..e6bbb76 100644
--- a/drivers/clk/qcom/gdsc.c
+++ b/drivers/clk/qcom/gdsc.c
@@ -34,6 +34,9 @@
 #define EN_FEW_WAIT_VAL		(0x8 << 16)
 #define CLK_DIS_WAIT_VAL	(0x2 << 12)
 
+#define RETAIN_MEM		BIT(14)
+#define RETAIN_PERIPH		BIT(13)
+
 #define TIMEOUT_US		100
 
 #define domain_to_gdsc(domain) container_of(domain, struct gdsc, pd)
@@ -81,6 +84,24 @@ static int gdsc_toggle_logic(struct gdsc *sc, bool en)
 	return -ETIMEDOUT;
 }
 
+static inline void gdsc_force_mem_on(struct gdsc *sc)
+{
+	int i;
+	u32 mask = RETAIN_MEM | RETAIN_PERIPH;
+
+	for (i = 0; i < sc->cxc_count; i++)
+		regmap_update_bits(sc->regmap, sc->cxcs[i], mask, mask);
+}
+
+static inline void gdsc_clear_mem_on(struct gdsc *sc)
+{
+	int i;
+	u32 mask = RETAIN_MEM | RETAIN_PERIPH;
+
+	for (i = 0; i < sc->cxc_count; i++)
+		regmap_update_bits(sc->regmap, sc->cxcs[i], mask, 0);
+}
+
 static int gdsc_enable(struct generic_pm_domain *domain)
 {
 	struct gdsc *sc = domain_to_gdsc(domain);
@@ -89,6 +110,10 @@ static int gdsc_enable(struct generic_pm_domain *domain)
 	ret = gdsc_toggle_logic(sc, true);
 	if (ret)
 		return ret;
+
+	if (sc->pwrsts & PWRSTS_OFF)
+		gdsc_force_mem_on(sc);
+
 	/*
 	 * If clocks to this power domain were already on, they will take an
 	 * additional 4 clock cycles to re-enable after the power domain is
@@ -105,6 +130,9 @@ static int gdsc_disable(struct generic_pm_domain *domain)
 {
 	struct gdsc *sc = domain_to_gdsc(domain);
 
+	if (sc->pwrsts & PWRSTS_OFF)
+		gdsc_clear_mem_on(sc);
+
 	return gdsc_toggle_logic(sc, false);
 }
 
@@ -129,6 +157,11 @@ static int gdsc_init(struct gdsc *sc)
 	if (on < 0)
 		return on;
 
+	if (on || (sc->pwrsts & PWRSTS_RET))
+		gdsc_force_mem_on(sc);
+	else
+		gdsc_clear_mem_on(sc);
+
 	sc->pd.power_off = gdsc_disable;
 	sc->pd.power_on = gdsc_enable;
 	pm_genpd_init(&sc->pd, NULL, !on);
diff --git a/drivers/clk/qcom/gdsc.h b/drivers/clk/qcom/gdsc.h
index f578a0c..0ff251a 100644
--- a/drivers/clk/qcom/gdsc.h
+++ b/drivers/clk/qcom/gdsc.h
@@ -19,16 +19,29 @@
 
 struct regmap;
 
+/* Powerdomain allowable state bitfields */
+#define PWRSTS_OFF		BIT(0)
+#define PWRSTS_RET		BIT(1)
+#define PWRSTS_ON		BIT(2)
+#define PWRSTS_OFF_ON		(PWRSTS_OFF | PWRSTS_ON)
+#define PWRSTS_RET_ON		(PWRSTS_RET | PWRSTS_ON)
+
 /**
  * struct gdsc - Globally Distributed Switch Controller
  * @pd: generic power domain
  * @regmap: regmap for MMIO accesses
  * @gdscr: gsdc control register
+ * @cxcs: offsets of branch registers to toggle mem/periph bits in
+ * @cxc_count: number of @cxcs
+ * @pwrsts: Possible powerdomain power states
  */
 struct gdsc {
 	struct generic_pm_domain	pd;
 	struct regmap			*regmap;
 	unsigned int			gdscr;
+	unsigned int			*cxcs;
+	unsigned int			cxc_count;
+	const u8			pwrsts;
 };
 
 #ifdef CONFIG_QCOM_GDSC
-- 
QUALCOMM INDIA, on behalf of Qualcomm Innovation Center, Inc. is a member
of Code Aurora Forum, hosted by The Linux Foundation



From rnayak at codeaurora.org  Thu Aug  6 03:37:45 2015
From: rnayak at codeaurora.org (Rajendra Nayak)
Date: Thu,  6 Aug 2015 16:07:45 +0530
Subject: [PATCH v8 04/13] clk: qcom: gdsc: Add support for ON only state
In-Reply-To: <1438857474-20262-1-git-send-email-rnayak@codeaurora.org>
References: <1438857474-20262-1-git-send-email-rnayak@codeaurora.org>
Message-ID: <1438857474-20262-5-git-send-email-rnayak@codeaurora.org>

Certain devices can have GDSCs' which support ON as the only state.
They can't be power collapsed to either hit RET or OFF.
The clients drivers for these GDSCs' however would expect the state
of the core to be reset following a GDSC disable and re-enable.
To do this assert/deassert reset lines every time the client
driver would request the GDSC to be powered on/off instead.

Signed-off-by: Rajendra Nayak <rnayak at codeaurora.org>
---
 drivers/clk/qcom/common.c |  3 ++-
 drivers/clk/qcom/gdsc.c   | 35 ++++++++++++++++++++++++++++++++++-
 drivers/clk/qcom/gdsc.h   | 11 ++++++++++-
 3 files changed, 46 insertions(+), 3 deletions(-)

diff --git a/drivers/clk/qcom/common.c b/drivers/clk/qcom/common.c
index a319aa8..4bc87e1 100644
--- a/drivers/clk/qcom/common.c
+++ b/drivers/clk/qcom/common.c
@@ -124,7 +124,8 @@ int qcom_cc_really_probe(struct platform_device *pdev,
 		goto err_reset;
 
 	if (desc->gdscs && desc->num_gdscs) {
-		ret = gdsc_register(dev, desc->gdscs, desc->num_gdscs, regmap);
+		ret = gdsc_register(dev, desc->gdscs, desc->num_gdscs,
+				    &reset->rcdev, regmap);
 		if (ret)
 			goto err_pd;
 	}
diff --git a/drivers/clk/qcom/gdsc.c b/drivers/clk/qcom/gdsc.c
index e6bbb76..da9fad8 100644
--- a/drivers/clk/qcom/gdsc.c
+++ b/drivers/clk/qcom/gdsc.c
@@ -18,6 +18,7 @@
 #include <linux/kernel.h>
 #include <linux/pm_domain.h>
 #include <linux/regmap.h>
+#include <linux/reset-controller.h>
 #include <linux/slab.h>
 #include "gdsc.h"
 
@@ -84,6 +85,24 @@ static int gdsc_toggle_logic(struct gdsc *sc, bool en)
 	return -ETIMEDOUT;
 }
 
+static inline int gdsc_deassert_reset(struct gdsc *sc)
+{
+	int i;
+
+	for (i = 0; i < sc->reset_count; i++)
+		sc->rcdev->ops->deassert(sc->rcdev, sc->resets[i]);
+	return 0;
+}
+
+static inline int gdsc_assert_reset(struct gdsc *sc)
+{
+	int i;
+
+	for (i = 0; i < sc->reset_count; i++)
+		sc->rcdev->ops->assert(sc->rcdev, sc->resets[i]);
+	return 0;
+}
+
 static inline void gdsc_force_mem_on(struct gdsc *sc)
 {
 	int i;
@@ -107,6 +126,9 @@ static int gdsc_enable(struct generic_pm_domain *domain)
 	struct gdsc *sc = domain_to_gdsc(domain);
 	int ret;
 
+	if (sc->pwrsts == PWRSTS_ON)
+		return gdsc_deassert_reset(sc);
+
 	ret = gdsc_toggle_logic(sc, true);
 	if (ret)
 		return ret;
@@ -130,6 +152,9 @@ static int gdsc_disable(struct generic_pm_domain *domain)
 {
 	struct gdsc *sc = domain_to_gdsc(domain);
 
+	if (sc->pwrsts == PWRSTS_ON)
+		return gdsc_assert_reset(sc);
+
 	if (sc->pwrsts & PWRSTS_OFF)
 		gdsc_clear_mem_on(sc);
 
@@ -153,6 +178,13 @@ static int gdsc_init(struct gdsc *sc)
 	if (ret)
 		return ret;
 
+	/* Force gdsc ON if only ON state is supported */
+	if (sc->pwrsts == PWRSTS_ON) {
+		ret = gdsc_toggle_logic(sc, true);
+		if (ret)
+			return ret;
+	}
+
 	on = gdsc_is_enabled(sc);
 	if (on < 0)
 		return on;
@@ -170,7 +202,7 @@ static int gdsc_init(struct gdsc *sc)
 }
 
 int gdsc_register(struct device *dev, struct gdsc **scs, size_t num,
-		  struct regmap *regmap)
+		  struct reset_controller_dev *rcdev, struct regmap *regmap)
 {
 	int i, ret;
 	struct genpd_onecell_data *data;
@@ -189,6 +221,7 @@ int gdsc_register(struct device *dev, struct gdsc **scs, size_t num,
 		if (!scs[i])
 			continue;
 		scs[i]->regmap = regmap;
+		scs[i]->rcdev = rcdev;
 		ret = gdsc_init(scs[i]);
 		if (ret)
 			return ret;
diff --git a/drivers/clk/qcom/gdsc.h b/drivers/clk/qcom/gdsc.h
index 0ff251a..5ded268 100644
--- a/drivers/clk/qcom/gdsc.h
+++ b/drivers/clk/qcom/gdsc.h
@@ -18,6 +18,7 @@
 #include <linux/pm_domain.h>
 
 struct regmap;
+struct reset_controller_dev;
 
 /* Powerdomain allowable state bitfields */
 #define PWRSTS_OFF		BIT(0)
@@ -34,6 +35,9 @@ struct regmap;
  * @cxcs: offsets of branch registers to toggle mem/periph bits in
  * @cxc_count: number of @cxcs
  * @pwrsts: Possible powerdomain power states
+ * @resets: ids of resets associated with this gdsc
+ * @reset_count: number of @resets
+ * @rcdev: reset controller
  */
 struct gdsc {
 	struct generic_pm_domain	pd;
@@ -42,13 +46,18 @@ struct gdsc {
 	unsigned int			*cxcs;
 	unsigned int			cxc_count;
 	const u8			pwrsts;
+	struct reset_controller_dev	*rcdev;
+	unsigned int			*resets;
+	unsigned int			reset_count;
 };
 
 #ifdef CONFIG_QCOM_GDSC
-int gdsc_register(struct device *, struct gdsc **, size_t n, struct regmap *);
+int gdsc_register(struct device *, struct gdsc **, size_t n,
+		  struct reset_controller_dev *, struct regmap *);
 void gdsc_unregister(struct device *);
 #else
 static inline int gdsc_register(struct device *d, struct gdsc **g, size_t n,
+				struct reset_controller_dev *rcdev,
 				struct regmap *r)
 {
 	return -ENOSYS;
-- 
QUALCOMM INDIA, on behalf of Qualcomm Innovation Center, Inc. is a member
of Code Aurora Forum, hosted by The Linux Foundation



From rnayak at codeaurora.org  Thu Aug  6 03:37:46 2015
From: rnayak at codeaurora.org (Rajendra Nayak)
Date: Thu,  6 Aug 2015 16:07:46 +0530
Subject: [PATCH v8 05/13] clk: qcom: gdsc: Add GDSCs in msm8916 GCC
In-Reply-To: <1438857474-20262-1-git-send-email-rnayak@codeaurora.org>
References: <1438857474-20262-1-git-send-email-rnayak@codeaurora.org>
Message-ID: <1438857474-20262-6-git-send-email-rnayak@codeaurora.org>

Add all data for the GDSCs which are part of msm8916 GCC block.

Signed-off-by: Rajendra Nayak <rnayak at codeaurora.org>
---
 drivers/clk/qcom/Kconfig                     |  1 +
 drivers/clk/qcom/gcc-msm8916.c               | 51 ++++++++++++++++++++++++++++
 include/dt-bindings/clock/qcom,gcc-msm8916.h |  8 +++++
 3 files changed, 60 insertions(+)

diff --git a/drivers/clk/qcom/Kconfig b/drivers/clk/qcom/Kconfig
index d3a695b..abec45a 100644
--- a/drivers/clk/qcom/Kconfig
+++ b/drivers/clk/qcom/Kconfig
@@ -53,6 +53,7 @@ config MSM_GCC_8660
 
 config MSM_GCC_8916
 	tristate "MSM8916 Global Clock Controller"
+	select QCOM_GDSC
 	depends on COMMON_CLK_QCOM
 	help
 	  Support for the global clock controller on msm8916 devices.
diff --git a/drivers/clk/qcom/gcc-msm8916.c b/drivers/clk/qcom/gcc-msm8916.c
index c66f7bc..10ba745 100644
--- a/drivers/clk/qcom/gcc-msm8916.c
+++ b/drivers/clk/qcom/gcc-msm8916.c
@@ -31,6 +31,7 @@
 #include "clk-rcg.h"
 #include "clk-branch.h"
 #include "reset.h"
+#include "gdsc.h"
 
 enum {
 	P_XO,
@@ -2562,6 +2563,46 @@ static struct clk_branch gcc_venus0_vcodec0_clk = {
 	},
 };
 
+static struct gdsc venus_gdsc = {
+	.gdscr = 0x4c018,
+	.pd = {
+		.name = "venus",
+	},
+	.pwrsts = PWRSTS_OFF_ON,
+};
+
+static struct gdsc mdss_gdsc = {
+	.gdscr = 0x4d078,
+	.pd = {
+		.name = "mdss",
+	},
+	.pwrsts = PWRSTS_OFF_ON,
+};
+
+static struct gdsc jpeg_gdsc = {
+	.gdscr = 0x5701c,
+	.pd = {
+		.name = "jpeg",
+	},
+	.pwrsts = PWRSTS_OFF_ON,
+};
+
+static struct gdsc vfe_gdsc = {
+	.gdscr = 0x58034,
+	.pd = {
+		.name = "vfe",
+	},
+	.pwrsts = PWRSTS_OFF_ON,
+};
+
+static struct gdsc oxili_gdsc = {
+	.gdscr = 0x5901c,
+	.pd = {
+		.name = "oxili",
+	},
+	.pwrsts = PWRSTS_OFF_ON,
+};
+
 static struct clk_regmap *gcc_msm8916_clocks[] = {
 	[GPLL0] = &gpll0.clkr,
 	[GPLL0_VOTE] = &gpll0_vote,
@@ -2703,6 +2744,14 @@ static struct clk_regmap *gcc_msm8916_clocks[] = {
 	[GCC_VENUS0_VCODEC0_CLK] = &gcc_venus0_vcodec0_clk.clkr,
 };
 
+static struct gdsc *gcc_msm8916_gdscs[] = {
+	[VENUS_GDSC] = &venus_gdsc,
+	[MDSS_GDSC] = &mdss_gdsc,
+	[JPEG_GDSC] = &jpeg_gdsc,
+	[VFE_GDSC] = &vfe_gdsc,
+	[OXILI_GDSC] = &oxili_gdsc,
+};
+
 static const struct qcom_reset_map gcc_msm8916_resets[] = {
 	[GCC_BLSP1_BCR] = { 0x01000 },
 	[GCC_BLSP1_QUP1_BCR] = { 0x02000 },
@@ -2810,6 +2859,8 @@ static const struct qcom_cc_desc gcc_msm8916_desc = {
 	.num_clks = ARRAY_SIZE(gcc_msm8916_clocks),
 	.resets = gcc_msm8916_resets,
 	.num_resets = ARRAY_SIZE(gcc_msm8916_resets),
+	.gdscs = gcc_msm8916_gdscs,
+	.num_gdscs = ARRAY_SIZE(gcc_msm8916_gdscs),
 };
 
 static const struct of_device_id gcc_msm8916_match_table[] = {
diff --git a/include/dt-bindings/clock/qcom,gcc-msm8916.h b/include/dt-bindings/clock/qcom,gcc-msm8916.h
index e430f64..11566c5 100644
--- a/include/dt-bindings/clock/qcom,gcc-msm8916.h
+++ b/include/dt-bindings/clock/qcom,gcc-msm8916.h
@@ -153,4 +153,12 @@
 #define GCC_VENUS0_AXI_CLK			136
 #define GCC_VENUS0_VCODEC0_CLK			137
 
+/* Indexes for GDSCs */
+#define BIMC_GDSC				0
+#define VENUS_GDSC				1
+#define MDSS_GDSC				2
+#define JPEG_GDSC				3
+#define VFE_GDSC				4
+#define OXILI_GDSC				5
+
 #endif
-- 
QUALCOMM INDIA, on behalf of Qualcomm Innovation Center, Inc. is a member
of Code Aurora Forum, hosted by The Linux Foundation



From rnayak at codeaurora.org  Thu Aug  6 03:37:47 2015
From: rnayak at codeaurora.org (Rajendra Nayak)
Date: Thu,  6 Aug 2015 16:07:47 +0530
Subject: [PATCH v8 06/13] clk: qcom: gdsc: Add GDSCs in msm8974 GCC
In-Reply-To: <1438857474-20262-1-git-send-email-rnayak@codeaurora.org>
References: <1438857474-20262-1-git-send-email-rnayak@codeaurora.org>
Message-ID: <1438857474-20262-7-git-send-email-rnayak@codeaurora.org>

From: Stephen Boyd <sboyd at codeaurora.org>

There's just one GDSC as part of the msm8974 GCC block.

Signed-off-by: Stephen Boyd <sboyd at codeaurora.org>
Signed-off-by: Rajendra Nayak <rnayak at codeaurora.org>
---
 drivers/clk/qcom/Kconfig                     |  1 +
 drivers/clk/qcom/gcc-msm8974.c               | 15 +++++++++++++++
 include/dt-bindings/clock/qcom,gcc-msm8974.h |  3 +++
 3 files changed, 19 insertions(+)

diff --git a/drivers/clk/qcom/Kconfig b/drivers/clk/qcom/Kconfig
index abec45a..a6fcb1d 100644
--- a/drivers/clk/qcom/Kconfig
+++ b/drivers/clk/qcom/Kconfig
@@ -88,6 +88,7 @@ config MSM_MMCC_8960
 
 config MSM_GCC_8974
 	tristate "MSM8974 Global Clock Controller"
+	select QCOM_GDSC
 	depends on COMMON_CLK_QCOM
 	help
 	  Support for the global clock controller on msm8974 devices.
diff --git a/drivers/clk/qcom/gcc-msm8974.c b/drivers/clk/qcom/gcc-msm8974.c
index c39d098..2c3c26f 100644
--- a/drivers/clk/qcom/gcc-msm8974.c
+++ b/drivers/clk/qcom/gcc-msm8974.c
@@ -31,6 +31,7 @@
 #include "clk-rcg.h"
 #include "clk-branch.h"
 #include "reset.h"
+#include "gdsc.h"
 
 enum {
 	P_XO,
@@ -2431,6 +2432,14 @@ static struct clk_branch gcc_usb_hsic_system_clk = {
 	},
 };
 
+static struct gdsc usb_hs_hsic_gdsc = {
+	.gdscr = 0x404,
+	.pd = {
+		.name = "usb_hs_hsic",
+	},
+	.pwrsts = PWRSTS_OFF_ON,
+};
+
 static struct clk_regmap *gcc_msm8974_clocks[] = {
 	[GPLL0] = &gpll0.clkr,
 	[GPLL0_VOTE] = &gpll0_vote,
@@ -2660,6 +2669,10 @@ static const struct qcom_reset_map gcc_msm8974_resets[] = {
 	[GCC_VENUS_RESTART] = { 0x1740 },
 };
 
+static struct gdsc *gcc_msm8974_gdscs[] = {
+	[USB_HS_HSIC_GDSC] = &usb_hs_hsic_gdsc,
+};
+
 static const struct regmap_config gcc_msm8974_regmap_config = {
 	.reg_bits	= 32,
 	.reg_stride	= 4,
@@ -2674,6 +2687,8 @@ static const struct qcom_cc_desc gcc_msm8974_desc = {
 	.num_clks = ARRAY_SIZE(gcc_msm8974_clocks),
 	.resets = gcc_msm8974_resets,
 	.num_resets = ARRAY_SIZE(gcc_msm8974_resets),
+	.gdscs = gcc_msm8974_gdscs,
+	.num_gdscs = ARRAY_SIZE(gcc_msm8974_gdscs),
 };
 
 static const struct of_device_id gcc_msm8974_match_table[] = {
diff --git a/include/dt-bindings/clock/qcom,gcc-msm8974.h b/include/dt-bindings/clock/qcom,gcc-msm8974.h
index 51e51c8..81d32f6 100644
--- a/include/dt-bindings/clock/qcom,gcc-msm8974.h
+++ b/include/dt-bindings/clock/qcom,gcc-msm8974.h
@@ -321,4 +321,7 @@
 #define GCC_SDCC1_CDCCAL_SLEEP_CLK				304
 #define GCC_SDCC1_CDCCAL_FF_CLK					305
 
+/* gdscs */
+#define USB_HS_HSIC_GDSC					0
+
 #endif
-- 
QUALCOMM INDIA, on behalf of Qualcomm Innovation Center, Inc. is a member
of Code Aurora Forum, hosted by The Linux Foundation



From rnayak at codeaurora.org  Thu Aug  6 03:37:48 2015
From: rnayak at codeaurora.org (Rajendra Nayak)
Date: Thu,  6 Aug 2015 16:07:48 +0530
Subject: [PATCH v8 07/13] clk: qcom: gdsc: Add GDSCs in msm8974 MMCC
In-Reply-To: <1438857474-20262-1-git-send-email-rnayak@codeaurora.org>
References: <1438857474-20262-1-git-send-email-rnayak@codeaurora.org>
Message-ID: <1438857474-20262-8-git-send-email-rnayak@codeaurora.org>

From: Stephen Boyd <sboyd at codeaurora.org>

Add the GDSC instances that exist as part of msm8974 MMCC block

Signed-off-by: Stephen Boyd <sboyd at codeaurora.org>
Signed-off-by: Rajendra Nayak <rnayak at codeaurora.org>
---
 drivers/clk/qcom/Kconfig                      |  1 +
 drivers/clk/qcom/mmcc-msm8974.c               | 72 +++++++++++++++++++++++++++
 include/dt-bindings/clock/qcom,mmcc-msm8974.h |  8 +++
 3 files changed, 81 insertions(+)

diff --git a/drivers/clk/qcom/Kconfig b/drivers/clk/qcom/Kconfig
index a6fcb1d..edab172 100644
--- a/drivers/clk/qcom/Kconfig
+++ b/drivers/clk/qcom/Kconfig
@@ -98,6 +98,7 @@ config MSM_GCC_8974
 config MSM_MMCC_8974
 	tristate "MSM8974 Multimedia Clock Controller"
 	select MSM_GCC_8974
+	select QCOM_GDSC
 	depends on COMMON_CLK_QCOM
 	help
 	  Support for the multimedia clock controller on msm8974 devices.
diff --git a/drivers/clk/qcom/mmcc-msm8974.c b/drivers/clk/qcom/mmcc-msm8974.c
index 07f4cc1..0b95063 100644
--- a/drivers/clk/qcom/mmcc-msm8974.c
+++ b/drivers/clk/qcom/mmcc-msm8974.c
@@ -31,6 +31,7 @@
 #include "clk-rcg.h"
 #include "clk-branch.h"
 #include "reset.h"
+#include "gdsc.h"
 
 enum {
 	P_XO,
@@ -2349,6 +2350,66 @@ static struct pll_config mmpll3_config = {
 	.aux_output_mask = BIT(1),
 };
 
+static struct gdsc venus0_gdsc = {
+	.gdscr = 0x1024,
+	.cxcs = (unsigned int []){ 0x1028 },
+	.cxc_count = 1,
+	.resets = (unsigned int []){ VENUS0_RESET },
+	.reset_count = 1,
+	.pd = {
+		.name = "venus0",
+	},
+	.pwrsts = PWRSTS_ON,
+};
+
+static struct gdsc mdss_gdsc = {
+	.gdscr = 0x2304,
+	.cxcs = (unsigned int []){ 0x231c, 0x2320 },
+	.cxc_count = 2,
+	.pd = {
+		.name = "mdss",
+	},
+	.pwrsts = PWRSTS_RET_ON,
+};
+
+static struct gdsc camss_jpeg_gdsc = {
+	.gdscr = 0x35a4,
+	.cxcs = (unsigned int []){ 0x35a8, 0x35ac, 0x35b0 },
+	.cxc_count = 3,
+	.pd = {
+		.name = "camss_jpeg",
+	},
+	.pwrsts = PWRSTS_OFF_ON,
+};
+
+static struct gdsc camss_vfe_gdsc = {
+	.gdscr = 0x36a4,
+	.cxcs = (unsigned int []){ 0x36a8, 0x36ac, 0x3704, 0x3714, 0x36b0 },
+	.cxc_count = 5,
+	.pd = {
+		.name = "camss_vfe",
+	},
+	.pwrsts = PWRSTS_OFF_ON,
+};
+
+static struct gdsc oxili_gdsc = {
+	.gdscr = 0x4024,
+	.cxcs = (unsigned int []){ 0x4028 },
+	.cxc_count = 1,
+	.pd = {
+		.name = "oxili",
+	},
+	.pwrsts = PWRSTS_OFF_ON,
+};
+
+static struct gdsc oxilicx_gdsc = {
+	.gdscr = 0x4034,
+	.pd = {
+		.name = "oxilicx",
+	},
+	.pwrsts = PWRSTS_OFF_ON,
+};
+
 static struct clk_regmap *mmcc_msm8974_clocks[] = {
 	[MMSS_AHB_CLK_SRC] = &mmss_ahb_clk_src.clkr,
 	[MMSS_AXI_CLK_SRC] = &mmss_axi_clk_src.clkr,
@@ -2525,6 +2586,15 @@ static const struct qcom_reset_map mmcc_msm8974_resets[] = {
 	[OCMEMNOC_RESET] = { 0x50b0 },
 };
 
+static struct gdsc *mmcc_msm8974_gdscs[] = {
+	[VENUS0_GDSC] = &venus0_gdsc,
+	[MDSS_GDSC] = &mdss_gdsc,
+	[CAMSS_JPEG_GDSC] = &camss_jpeg_gdsc,
+	[CAMSS_VFE_GDSC] = &camss_vfe_gdsc,
+	[OXILI_GDSC] = &oxili_gdsc,
+	[OXILICX_GDSC] = &oxilicx_gdsc,
+};
+
 static const struct regmap_config mmcc_msm8974_regmap_config = {
 	.reg_bits	= 32,
 	.reg_stride	= 4,
@@ -2539,6 +2609,8 @@ static const struct qcom_cc_desc mmcc_msm8974_desc = {
 	.num_clks = ARRAY_SIZE(mmcc_msm8974_clocks),
 	.resets = mmcc_msm8974_resets,
 	.num_resets = ARRAY_SIZE(mmcc_msm8974_resets),
+	.gdscs = mmcc_msm8974_gdscs,
+	.num_gdscs = ARRAY_SIZE(mmcc_msm8974_gdscs),
 };
 
 static const struct of_device_id mmcc_msm8974_match_table[] = {
diff --git a/include/dt-bindings/clock/qcom,mmcc-msm8974.h b/include/dt-bindings/clock/qcom,mmcc-msm8974.h
index 032ed87..28651e5 100644
--- a/include/dt-bindings/clock/qcom,mmcc-msm8974.h
+++ b/include/dt-bindings/clock/qcom,mmcc-msm8974.h
@@ -158,4 +158,12 @@
 #define SPDM_RM_AXI					141
 #define SPDM_RM_OCMEMNOC				142
 
+/* gdscs */
+#define VENUS0_GDSC					0
+#define MDSS_GDSC					1
+#define CAMSS_JPEG_GDSC					2
+#define CAMSS_VFE_GDSC					3
+#define OXILI_GDSC					4
+#define OXILICX_GDSC					5
+
 #endif
-- 
QUALCOMM INDIA, on behalf of Qualcomm Innovation Center, Inc. is a member
of Code Aurora Forum, hosted by The Linux Foundation



From rnayak at codeaurora.org  Thu Aug  6 03:37:49 2015
From: rnayak at codeaurora.org (Rajendra Nayak)
Date: Thu,  6 Aug 2015 16:07:49 +0530
Subject: [PATCH v8 08/13] clk: qcom: gdsc: Add GDSCs in apq8084 GCC
In-Reply-To: <1438857474-20262-1-git-send-email-rnayak@codeaurora.org>
References: <1438857474-20262-1-git-send-email-rnayak@codeaurora.org>
Message-ID: <1438857474-20262-9-git-send-email-rnayak@codeaurora.org>

Add the GDSC instances that exist as part of apq8084 GCC block

Signed-off-by: Rajendra Nayak <rnayak at codeaurora.org>
---
 drivers/clk/qcom/Kconfig                     |  1 +
 drivers/clk/qcom/gcc-apq8084.c               | 42 ++++++++++++++++++++++++++++
 include/dt-bindings/clock/qcom,gcc-apq8084.h |  6 ++++
 3 files changed, 49 insertions(+)

diff --git a/drivers/clk/qcom/Kconfig b/drivers/clk/qcom/Kconfig
index edab172..fe00dd6 100644
--- a/drivers/clk/qcom/Kconfig
+++ b/drivers/clk/qcom/Kconfig
@@ -7,6 +7,7 @@ config COMMON_CLK_QCOM
 
 config APQ_GCC_8084
 	tristate "APQ8084 Global Clock Controller"
+	select QCOM_GDSC
 	depends on COMMON_CLK_QCOM
 	help
 	  Support for the global clock controller on apq8084 devices.
diff --git a/drivers/clk/qcom/gcc-apq8084.c b/drivers/clk/qcom/gcc-apq8084.c
index 54a756b9..91c6bd9c 100644
--- a/drivers/clk/qcom/gcc-apq8084.c
+++ b/drivers/clk/qcom/gcc-apq8084.c
@@ -31,6 +31,7 @@
 #include "clk-rcg.h"
 #include "clk-branch.h"
 #include "reset.h"
+#include "gdsc.h"
 
 enum {
 	P_XO,
@@ -3253,6 +3254,38 @@ static struct clk_branch gcc_usb_hsic_system_clk = {
 	},
 };
 
+static struct gdsc usb_hs_hsic_gdsc = {
+	.gdscr = 0x404,
+	.pd = {
+		.name = "usb_hs_hsic",
+	},
+	.pwrsts = PWRSTS_OFF_ON,
+};
+
+static struct gdsc pcie0_gdsc = {
+	.gdscr = 0x1ac4,
+	.pd = {
+		.name = "pcie0",
+	},
+	.pwrsts = PWRSTS_OFF_ON,
+};
+
+static struct gdsc pcie1_gdsc = {
+	.gdscr = 0x1b44,
+	.pd = {
+		.name = "pcie1",
+	},
+	.pwrsts = PWRSTS_OFF_ON,
+};
+
+static struct gdsc usb30_gdsc = {
+	.gdscr = 0x1e84,
+	.pd = {
+		.name = "usb30",
+	},
+	.pwrsts = PWRSTS_OFF_ON,
+};
+
 static struct clk_regmap *gcc_apq8084_clocks[] = {
 	[GPLL0] = &gpll0.clkr,
 	[GPLL0_VOTE] = &gpll0_vote,
@@ -3446,6 +3479,13 @@ static struct clk_regmap *gcc_apq8084_clocks[] = {
 	[GCC_USB_HSIC_SYSTEM_CLK] = &gcc_usb_hsic_system_clk.clkr,
 };
 
+static struct gdsc *gcc_apq8084_gdscs[] = {
+	[USB_HS_HSIC_GDSC] = &usb_hs_hsic_gdsc,
+	[PCIE0_GDSC] = &pcie0_gdsc,
+	[PCIE1_GDSC] = &pcie1_gdsc,
+	[USB30_GDSC] = &usb30_gdsc,
+};
+
 static const struct qcom_reset_map gcc_apq8084_resets[] = {
 	[GCC_SYSTEM_NOC_BCR] = { 0x0100 },
 	[GCC_CONFIG_NOC_BCR] = { 0x0140 },
@@ -3554,6 +3594,8 @@ static const struct qcom_cc_desc gcc_apq8084_desc = {
 	.num_clks = ARRAY_SIZE(gcc_apq8084_clocks),
 	.resets = gcc_apq8084_resets,
 	.num_resets = ARRAY_SIZE(gcc_apq8084_resets),
+	.gdscs = gcc_apq8084_gdscs,
+	.num_gdscs = ARRAY_SIZE(gcc_apq8084_gdscs),
 };
 
 static const struct of_device_id gcc_apq8084_match_table[] = {
diff --git a/include/dt-bindings/clock/qcom,gcc-apq8084.h b/include/dt-bindings/clock/qcom,gcc-apq8084.h
index 2c0da56..5aa7ebe 100644
--- a/include/dt-bindings/clock/qcom,gcc-apq8084.h
+++ b/include/dt-bindings/clock/qcom,gcc-apq8084.h
@@ -348,4 +348,10 @@
 #define GCC_PCIE_1_PIPE_CLK				331
 #define GCC_PCIE_1_SLV_AXI_CLK				332
 
+/* gdscs */
+#define USB_HS_HSIC_GDSC				0
+#define PCIE0_GDSC					1
+#define PCIE1_GDSC					2
+#define USB30_GDSC					3
+
 #endif
-- 
QUALCOMM INDIA, on behalf of Qualcomm Innovation Center, Inc. is a member
of Code Aurora Forum, hosted by The Linux Foundation



From rnayak at codeaurora.org  Thu Aug  6 03:37:50 2015
From: rnayak at codeaurora.org (Rajendra Nayak)
Date: Thu,  6 Aug 2015 16:07:50 +0530
Subject: [PATCH v8 09/13] clk: qcom: gdsc: Add GDSCs in apq8084 MMCC
In-Reply-To: <1438857474-20262-1-git-send-email-rnayak@codeaurora.org>
References: <1438857474-20262-1-git-send-email-rnayak@codeaurora.org>
Message-ID: <1438857474-20262-10-git-send-email-rnayak@codeaurora.org>

From: Stephane Viau <sviau at codeaurora.org>

Add the GDSC instances that exist as part of apq8084 MMCC block.

Signed-off-by: Stephane Viau <sviau at codeaurora.org>
Signed-off-by: Rajendra Nayak <rnayak at codeaurora.org>
---
 drivers/clk/qcom/Kconfig                      |  1 +
 drivers/clk/qcom/mmcc-apq8084.c               | 86 ++++++++++++++++++++++++++-
 include/dt-bindings/clock/qcom,mmcc-apq8084.h | 10 ++++
 3 files changed, 96 insertions(+), 1 deletion(-)

diff --git a/drivers/clk/qcom/Kconfig b/drivers/clk/qcom/Kconfig
index fe00dd6..47b988f 100644
--- a/drivers/clk/qcom/Kconfig
+++ b/drivers/clk/qcom/Kconfig
@@ -17,6 +17,7 @@ config APQ_GCC_8084
 config APQ_MMCC_8084
 	tristate "APQ8084 Multimedia Clock Controller"
 	select APQ_GCC_8084
+	select QCOM_GDSC
 	depends on COMMON_CLK_QCOM
 	help
 	  Support for the multimedia clock controller on apq8084 devices.
diff --git a/drivers/clk/qcom/mmcc-apq8084.c b/drivers/clk/qcom/mmcc-apq8084.c
index 1b17df2..6498eaa 100644
--- a/drivers/clk/qcom/mmcc-apq8084.c
+++ b/drivers/clk/qcom/mmcc-apq8084.c
@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 2014, The Linux Foundation. All rights reserved.
+ * Copyright (c) 2014-2015, The Linux Foundation. All rights reserved.
  *
  * This software is licensed under the terms of the GNU General Public
  * License version 2, as published by the Free Software Foundation, and
@@ -26,6 +26,7 @@
 #include "clk-rcg.h"
 #include "clk-branch.h"
 #include "reset.h"
+#include "gdsc.h"
 
 enum {
 	P_XO,
@@ -3077,6 +3078,76 @@ static const struct pll_config mmpll3_config = {
 	.aux_output_mask = BIT(1),
 };
 
+static struct gdsc venus0_gdsc = {
+	.gdscr = 0x1024,
+	.pd = {
+		.name = "venus0",
+	},
+	.pwrsts = PWRSTS_OFF_ON,
+};
+
+static struct gdsc venus0_core0_gdsc = {
+	.gdscr = 0x1040,
+	.pd = {
+		.name = "venus0_core0",
+	},
+	.pwrsts = PWRSTS_OFF_ON,
+};
+
+static struct gdsc venus0_core1_gdsc = {
+	.gdscr = 0x1044,
+	.pd = {
+		.name = "venus0_core1",
+	},
+	.pwrsts = PWRSTS_OFF_ON,
+};
+
+static struct gdsc mdss_gdsc = {
+	.gdscr = 0x2304,
+	.cxcs = (unsigned int []){ 0x231c, 0x2320 },
+	.cxc_count = 2,
+	.pd = {
+		.name = "mdss",
+	},
+	.pwrsts = PWRSTS_OFF_ON,
+};
+
+static struct gdsc camss_jpeg_gdsc = {
+	.gdscr = 0x35a4,
+	.pd = {
+		.name = "camss_jpeg",
+	},
+	.pwrsts = PWRSTS_OFF_ON,
+};
+
+static struct gdsc camss_vfe_gdsc = {
+	.gdscr = 0x36a4,
+	.cxcs = (unsigned int []){ 0x36a8, 0x36ac, 0x36b0 },
+	.cxc_count = 3,
+	.pd = {
+		.name = "camss_vfe",
+	},
+	.pwrsts = PWRSTS_OFF_ON,
+};
+
+static struct gdsc oxili_gdsc = {
+	.gdscr = 0x4024,
+	.cxcs = (unsigned int []){ 0x4028 },
+	.cxc_count = 1,
+	.pd = {
+		.name = "oxili",
+	},
+	.pwrsts = PWRSTS_OFF_ON,
+};
+
+static struct gdsc oxilicx_gdsc = {
+	.gdscr = 0x4034,
+	.pd = {
+		.name = "oxilicx",
+	},
+	.pwrsts = PWRSTS_OFF_ON,
+};
+
 static struct clk_regmap *mmcc_apq8084_clocks[] = {
 	[MMSS_AHB_CLK_SRC] = &mmss_ahb_clk_src.clkr,
 	[MMSS_AXI_CLK_SRC] = &mmss_axi_clk_src.clkr,
@@ -3294,6 +3365,17 @@ static const struct qcom_reset_map mmcc_apq8084_resets[] = {
 	[MMSSNOCAXI_RESET] = { 0x5060 },
 };
 
+static struct gdsc *mmcc_apq8084_gdscs[] = {
+	[VENUS0_GDSC] = &venus0_gdsc,
+	[VENUS0_CORE0_GDSC] = &venus0_core0_gdsc,
+	[VENUS0_CORE1_GDSC] = &venus0_core1_gdsc,
+	[MDSS_GDSC] = &mdss_gdsc,
+	[CAMSS_JPEG_GDSC] = &camss_jpeg_gdsc,
+	[CAMSS_VFE_GDSC] = &camss_vfe_gdsc,
+	[OXILI_GDSC] = &oxili_gdsc,
+	[OXILICX_GDSC] = &oxilicx_gdsc,
+};
+
 static const struct regmap_config mmcc_apq8084_regmap_config = {
 	.reg_bits	= 32,
 	.reg_stride	= 4,
@@ -3308,6 +3390,8 @@ static const struct qcom_cc_desc mmcc_apq8084_desc = {
 	.num_clks = ARRAY_SIZE(mmcc_apq8084_clocks),
 	.resets = mmcc_apq8084_resets,
 	.num_resets = ARRAY_SIZE(mmcc_apq8084_resets),
+	.gdscs = mmcc_apq8084_gdscs,
+	.num_gdscs = ARRAY_SIZE(mmcc_apq8084_gdscs),
 };
 
 static const struct of_device_id mmcc_apq8084_match_table[] = {
diff --git a/include/dt-bindings/clock/qcom,mmcc-apq8084.h b/include/dt-bindings/clock/qcom,mmcc-apq8084.h
index d72b5b3..03861e3 100644
--- a/include/dt-bindings/clock/qcom,mmcc-apq8084.h
+++ b/include/dt-bindings/clock/qcom,mmcc-apq8084.h
@@ -180,4 +180,14 @@
 #define VPU_SLEEP_CLK			163
 #define VPU_VDP_CLK			164
 
+/* GDSCs */
+#define VENUS0_GDSC			0
+#define VENUS0_CORE0_GDSC		1
+#define VENUS0_CORE1_GDSC		2
+#define MDSS_GDSC			3
+#define CAMSS_JPEG_GDSC			4
+#define CAMSS_VFE_GDSC			5
+#define OXILI_GDSC			6
+#define OXILICX_GDSC			7
+
 #endif
-- 
QUALCOMM INDIA, on behalf of Qualcomm Innovation Center, Inc. is a member
of Code Aurora Forum, hosted by The Linux Foundation



From rnayak at codeaurora.org  Thu Aug  6 03:37:51 2015
From: rnayak at codeaurora.org (Rajendra Nayak)
Date: Thu,  6 Aug 2015 16:07:51 +0530
Subject: [PATCH v8 10/13] arm: dts: qcom: Add #power-domain-cells property
In-Reply-To: <1438857474-20262-1-git-send-email-rnayak@codeaurora.org>
References: <1438857474-20262-1-git-send-email-rnayak@codeaurora.org>
Message-ID: <1438857474-20262-11-git-send-email-rnayak@codeaurora.org>

msm8974 has gcc and mmcc nodes, and apq8084 has a gcc node which
implement gdsc powerdomains. Add the #power-domain-cells property
to them.

Signed-off-by: Rajendra Nayak <rnayak at codeaurora.org>
---
 arch/arm/boot/dts/qcom-apq8084.dtsi   | 1 +
 arch/arm/boot/dts/qcom-msm8974.dtsi   | 2 ++
 arch/arm64/boot/dts/qcom/msm8916.dtsi | 1 +
 3 files changed, 4 insertions(+)

diff --git a/arch/arm/boot/dts/qcom-apq8084.dtsi b/arch/arm/boot/dts/qcom-apq8084.dtsi
index 7084010..1cdb568 100644
--- a/arch/arm/boot/dts/qcom-apq8084.dtsi
+++ b/arch/arm/boot/dts/qcom-apq8084.dtsi
@@ -221,6 +221,7 @@
 			compatible = "qcom,gcc-apq8084";
 			#clock-cells = <1>;
 			#reset-cells = <1>;
+			#power-domain-cells = <1>;
 			reg = <0xfc400000 0x4000>;
 		};
 
diff --git a/arch/arm/boot/dts/qcom-msm8974.dtsi b/arch/arm/boot/dts/qcom-msm8974.dtsi
index 37b47b5..8a2dfa6 100644
--- a/arch/arm/boot/dts/qcom-msm8974.dtsi
+++ b/arch/arm/boot/dts/qcom-msm8974.dtsi
@@ -217,6 +217,7 @@
 			compatible = "qcom,gcc-msm8974";
 			#clock-cells = <1>;
 			#reset-cells = <1>;
+			#power-domain-cells = <1>;
 			reg = <0xfc400000 0x4000>;
 		};
 
@@ -224,6 +225,7 @@
 			compatible = "qcom,mmcc-msm8974";
 			#clock-cells = <1>;
 			#reset-cells = <1>;
+			#power-domain-cells = <1>;
 			reg = <0xfd8c0000 0x6000>;
 		};
 
diff --git a/arch/arm64/boot/dts/qcom/msm8916.dtsi b/arch/arm64/boot/dts/qcom/msm8916.dtsi
index 0f49ebd..3b0645a 100644
--- a/arch/arm64/boot/dts/qcom/msm8916.dtsi
+++ b/arch/arm64/boot/dts/qcom/msm8916.dtsi
@@ -120,6 +120,7 @@
 			compatible = "qcom,gcc-msm8916";
 			#clock-cells = <1>;
 			#reset-cells = <1>;
+			#power-domain-cells = <1>;
 			reg = <0x1800000 0x80000>;
 		};
 
-- 
QUALCOMM INDIA, on behalf of Qualcomm Innovation Center, Inc. is a member
of Code Aurora Forum, hosted by The Linux Foundation



From rnayak at codeaurora.org  Thu Aug  6 03:37:52 2015
From: rnayak at codeaurora.org (Rajendra Nayak)
Date: Thu,  6 Aug 2015 16:07:52 +0530
Subject: [PATCH v8 11/13] clk: qcom: gdsc: Use PM clocks to control gdsc clocks
In-Reply-To: <1438857474-20262-1-git-send-email-rnayak@codeaurora.org>
References: <1438857474-20262-1-git-send-email-rnayak@codeaurora.org>
Message-ID: <1438857474-20262-12-git-send-email-rnayak@codeaurora.org>

The devices within a gdsc power domain, quite often have additional
clocks to be turned on/off along with the power domain itself.
Once the drivers for these devices are converted to use runtime PM,
it would be possible to remove all clock handling from the drivers if
the gdsc driver can handle it.
Use PM clocks to add support for this. A list of clock ids specified
per gdsc would be the clocks turned on/off on every device start/stop
callbacks.

Signed-off-by: Rajendra Nayak <rnayak at codeaurora.org>
---
 drivers/clk/qcom/gdsc.c | 58 +++++++++++++++++++++++++++++++++++++++++++++++++
 drivers/clk/qcom/gdsc.h |  7 ++++++
 2 files changed, 65 insertions(+)

diff --git a/drivers/clk/qcom/gdsc.c b/drivers/clk/qcom/gdsc.c
index da9fad8..ec1dfb5 100644
--- a/drivers/clk/qcom/gdsc.c
+++ b/drivers/clk/qcom/gdsc.c
@@ -12,10 +12,12 @@
  */
 
 #include <linux/bitops.h>
+#include <linux/clk.h>
 #include <linux/delay.h>
 #include <linux/err.h>
 #include <linux/jiffies.h>
 #include <linux/kernel.h>
+#include <linux/pm_clock.h>
 #include <linux/pm_domain.h>
 #include <linux/regmap.h>
 #include <linux/reset-controller.h>
@@ -161,6 +163,59 @@ static int gdsc_disable(struct generic_pm_domain *domain)
 	return gdsc_toggle_logic(sc, false);
 }
 
+static inline bool match(unsigned int id, unsigned int *ids, unsigned int count)
+{
+	int i;
+
+	for (i = 0; i < count; i++)
+		if (id == ids[i])
+			return true;
+	return false;
+}
+
+static int gdsc_attach(struct generic_pm_domain *domain, struct device *dev)
+{
+	int ret, i = 0, j = 0;
+	struct gdsc *sc = domain_to_gdsc(domain);
+	struct of_phandle_args clkspec;
+	struct device_node *np = dev->of_node;
+
+	if (!sc->clock_count)
+		return 0;
+
+	ret = pm_clk_create(dev);
+	if (ret) {
+		dev_dbg(dev, "pm_clk_create failed %d\n", ret);
+		return ret;
+	}
+
+	sc->clks = devm_kcalloc(dev, sc->clock_count, sizeof(sc->clks),
+				       GFP_KERNEL);
+	if (!sc->clks)
+		return -ENOMEM;
+
+	while (!of_parse_phandle_with_args(np, "clocks", "#clock-cells", i,
+					   &clkspec)) {
+		if (match(clkspec.args[0], sc->clocks, sc->clock_count)) {
+			sc->clks[j] = of_clk_get_from_provider(&clkspec);
+			pm_clk_add_clk(dev, sc->clks[j]);
+			j++;
+		}
+		i++;
+	}
+	return 0;
+};
+
+static void gdsc_detach(struct generic_pm_domain *domain, struct device *dev)
+{
+	struct gdsc *sc = domain_to_gdsc(domain);
+
+	if (!sc->clock_count)
+		return;
+
+	pm_clk_destroy(dev);
+};
+
 static int gdsc_init(struct gdsc *sc)
 {
 	u32 mask, val;
@@ -196,6 +251,9 @@ static int gdsc_init(struct gdsc *sc)
 
 	sc->pd.power_off = gdsc_disable;
 	sc->pd.power_on = gdsc_enable;
+	sc->pd.attach_dev = gdsc_attach;
+	sc->pd.detach_dev = gdsc_detach;
+	sc->pd.flags = GENPD_FLAG_PM_CLK;
 	pm_genpd_init(&sc->pd, NULL, !on);
 
 	return 0;
diff --git a/drivers/clk/qcom/gdsc.h b/drivers/clk/qcom/gdsc.h
index 5ded268..2fdb332 100644
--- a/drivers/clk/qcom/gdsc.h
+++ b/drivers/clk/qcom/gdsc.h
@@ -17,6 +17,7 @@
 #include <linux/err.h>
 #include <linux/pm_domain.h>
 
+struct clk;
 struct regmap;
 struct reset_controller_dev;
 
@@ -38,6 +39,9 @@ struct reset_controller_dev;
  * @resets: ids of resets associated with this gdsc
  * @reset_count: number of @resets
  * @rcdev: reset controller
+ * @clocks: ids of clocks associated with the gdsc
+ * @clock_count: number of @clocks
+ * @clks: clock pointers to gdsc clocks
  */
 struct gdsc {
 	struct generic_pm_domain	pd;
@@ -49,6 +53,9 @@ struct gdsc {
 	struct reset_controller_dev	*rcdev;
 	unsigned int			*resets;
 	unsigned int			reset_count;
+	unsigned int			*clocks;
+	unsigned int			clock_count;
+	struct clk			**clks;
 };
 
 #ifdef CONFIG_QCOM_GDSC
-- 
QUALCOMM INDIA, on behalf of Qualcomm Innovation Center, Inc. is a member
of Code Aurora Forum, hosted by The Linux Foundation



From rnayak at codeaurora.org  Thu Aug  6 03:37:53 2015
From: rnayak at codeaurora.org (Rajendra Nayak)
Date: Thu,  6 Aug 2015 16:07:53 +0530
Subject: [PATCH v8 12/13] clk: qcom: gdsc: Enable an RCG before turing on the
 gdsc
In-Reply-To: <1438857474-20262-1-git-send-email-rnayak@codeaurora.org>
References: <1438857474-20262-1-git-send-email-rnayak@codeaurora.org>
Message-ID: <1438857474-20262-13-git-send-email-rnayak@codeaurora.org>

Some gdsc instances require a certain root clock (RCG) to be turned on
*before* the power domain itself can be turned on. Handle this as part
of the gdsc enable/disable callbacks.

Signed-off-by: Rajendra Nayak <rnayak at codeaurora.org>
---
 drivers/clk/qcom/gcc-msm8916.c |  1 +
 drivers/clk/qcom/gdsc.c        | 14 ++++++++++++--
 drivers/clk/qcom/gdsc.h        |  4 ++++
 3 files changed, 17 insertions(+), 2 deletions(-)

diff --git a/drivers/clk/qcom/gcc-msm8916.c b/drivers/clk/qcom/gcc-msm8916.c
index 10ba745..bb34345 100644
--- a/drivers/clk/qcom/gcc-msm8916.c
+++ b/drivers/clk/qcom/gcc-msm8916.c
@@ -2601,6 +2601,7 @@ static struct gdsc oxili_gdsc = {
 		.name = "oxili",
 	},
 	.pwrsts = PWRSTS_OFF_ON,
+	.root_clock = GFX3D_CLK_SRC,
 };
 
 static struct clk_regmap *gcc_msm8916_clocks[] = {
diff --git a/drivers/clk/qcom/gdsc.c b/drivers/clk/qcom/gdsc.c
index ec1dfb5..20965fc 100644
--- a/drivers/clk/qcom/gdsc.c
+++ b/drivers/clk/qcom/gdsc.c
@@ -131,6 +131,9 @@ static int gdsc_enable(struct generic_pm_domain *domain)
 	if (sc->pwrsts == PWRSTS_ON)
 		return gdsc_deassert_reset(sc);
 
+	if (sc->root_clk)
+		clk_prepare_enable(sc->root_clk);
+
 	ret = gdsc_toggle_logic(sc, true);
 	if (ret)
 		return ret;
@@ -152,6 +155,7 @@ static int gdsc_enable(struct generic_pm_domain *domain)
 
 static int gdsc_disable(struct generic_pm_domain *domain)
 {
+	int ret;
 	struct gdsc *sc = domain_to_gdsc(domain);
 
 	if (sc->pwrsts == PWRSTS_ON)
@@ -160,7 +164,12 @@ static int gdsc_disable(struct generic_pm_domain *domain)
 	if (sc->pwrsts & PWRSTS_OFF)
 		gdsc_clear_mem_on(sc);
 
-	return gdsc_toggle_logic(sc, false);
+	ret = gdsc_toggle_logic(sc, false);
+
+	if (sc->root_clk)
+		clk_disable_unprepare(sc->root_clk);
+
+	return ret;
 }
 
 static inline bool match(unsigned int id, unsigned int *ids, unsigned int count)
@@ -200,7 +209,8 @@ static int gdsc_attach(struct generic_pm_domain *domain, struct device *dev)
 			sc->clks[j] = of_clk_get_from_provider(&clkspec);
 			pm_clk_add_clk(dev, sc->clks[j]);
 			j++;
-		}
+		} else if (clkspec.args[0] == sc->root_clock)
+			sc->root_clk = of_clk_get_from_provider(&clkspec);
 		i++;
 	}
 	return 0;
diff --git a/drivers/clk/qcom/gdsc.h b/drivers/clk/qcom/gdsc.h
index 2fdb332..0b958a6 100644
--- a/drivers/clk/qcom/gdsc.h
+++ b/drivers/clk/qcom/gdsc.h
@@ -42,6 +42,8 @@ struct reset_controller_dev;
  * @clocks: ids of clocks associated with the gdsc
  * @clock_count: number of @clocks
  * @clks: clock pointers to gdsc clocks
+ * @root_clock: id of the root clock to be enabled
+ * @root_clk: root clk pointer
  */
 struct gdsc {
 	struct generic_pm_domain	pd;
@@ -56,6 +58,8 @@ struct gdsc {
 	unsigned int			*clocks;
 	unsigned int			clock_count;
 	struct clk			**clks;
+	unsigned int			root_clock;
+	struct clk			*root_clk;
 };
 
 #ifdef CONFIG_QCOM_GDSC
-- 
QUALCOMM INDIA, on behalf of Qualcomm Innovation Center, Inc. is a member
of Code Aurora Forum, hosted by The Linux Foundation



From rnayak at codeaurora.org  Thu Aug  6 03:37:54 2015
From: rnayak at codeaurora.org (Rajendra Nayak)
Date: Thu,  6 Aug 2015 16:07:54 +0530
Subject: [PATCH v8 13/13] clk: qcom: gdsc: Manage clocks with !CONFIG_PM
In-Reply-To: <1438857474-20262-1-git-send-email-rnayak@codeaurora.org>
References: <1438857474-20262-1-git-send-email-rnayak@codeaurora.org>
Message-ID: <1438857474-20262-14-git-send-email-rnayak@codeaurora.org>

With CONFIG_PM disabled, turn the devices clocks on during
driver binding to the device, and turn them off when the
driver is unbound from the device. Platforms can specify
all the clocks that need to be managed in !CONFIG_PM case
using qcom_pm_add_notifier().

The use of pm_clk_add_notifier() isn't appropriate here since we need
to only manage clocks with valid power domain associations done via
DT, instead of what pm_clk_add_notifier() does, which is manage clocks
for all on SoC/off SoC devices associating all of them to a dummy power
domain instead

Signed-off-by: Rajendra Nayak <rnayak at codeaurora.org>
---
 drivers/clk/qcom/gdsc.c | 74 +++++++++++++++++++++++++++++++++++++++++++++++++
 drivers/clk/qcom/gdsc.h |  8 ++++++
 2 files changed, 82 insertions(+)

diff --git a/drivers/clk/qcom/gdsc.c b/drivers/clk/qcom/gdsc.c
index 20965fc..afc0b15 100644
--- a/drivers/clk/qcom/gdsc.c
+++ b/drivers/clk/qcom/gdsc.c
@@ -17,6 +17,7 @@
 #include <linux/err.h>
 #include <linux/jiffies.h>
 #include <linux/kernel.h>
+#include <linux/platform_device.h>
 #include <linux/pm_clock.h>
 #include <linux/pm_domain.h>
 #include <linux/regmap.h>
@@ -303,3 +304,76 @@ void gdsc_unregister(struct device *dev)
 {
 	of_genpd_del_provider(dev->of_node);
 }
+
+#ifndef CONFIG_PM
+static void enable_clock(struct of_phandle_args *clkspec)
+{
+	struct clk *clk;
+
+	clk = of_clk_get_from_provider(clkspec);
+	if (!IS_ERR(clk)) {
+		clk_prepare_enable(clk);
+		clk_put(clk);
+	}
+}
+
+static void disable_clock(struct of_phandle_args *clkspec)
+{
+	struct clk *clk;
+
+	clk = of_clk_get_from_provider(clkspec);
+	if (!IS_ERR(clk)) {
+		clk_disable_unprepare(clk);
+		clk_put(clk);
+	}
+}
+
+static int clk_notify(struct notifier_block *nb, unsigned long action,
+		      void *data)
+{
+	int sz, i = 0;
+	struct device *dev = data;
+	struct gdsc_notifier_block *gdsc_nb;
+	struct of_phandle_args clkspec;
+	struct device_node *np = dev->of_node;
+
+	if (!of_find_property(dev->of_node, "power-domains", &sz))
+		return 0;
+
+	gdsc_nb = container_of(nb, struct gdsc_notifier_block, nb);
+
+	if (!gdsc_nb->clock_count)
+		return 0;
+
+	switch (action) {
+	case BUS_NOTIFY_BIND_DRIVER:
+		while (!of_parse_phandle_with_args(np, "clocks", "#clock-cells",
+						   i, &clkspec)) {
+			if (match(clkspec.args[0], gdsc_nb->clocks,
+				  gdsc_nb->clock_count))
+				enable_clock(&clkspec);
+			i++;
+		}
+		break;
+	case BUS_NOTIFY_UNBOUND_DRIVER:
+		while (!of_parse_phandle_with_args(np, "clocks", "#clock-cells",
+						   i, &clkspec)) {
+			if (match(clkspec.args[0], gdsc_nb->clocks,
+				  gdsc_nb->clock_count))
+				disable_clock(&clkspec);
+			i++;
+		}
+		break;
+	}
+	return 0;
+}
+
+void qcom_pm_add_notifier(struct gdsc_notifier_block *gdsc_nb)
+{
+	if (!gdsc_nb)
+		return;
+
+	gdsc_nb->nb.notifier_call = clk_notify,
+	bus_register_notifier(&platform_bus_type, &gdsc_nb->nb);
+}
+#endif
diff --git a/drivers/clk/qcom/gdsc.h b/drivers/clk/qcom/gdsc.h
index 0b958a6..b0a36ed 100644
--- a/drivers/clk/qcom/gdsc.h
+++ b/drivers/clk/qcom/gdsc.h
@@ -76,4 +76,12 @@ static inline int gdsc_register(struct device *d, struct gdsc **g, size_t n,
 
 static inline void gdsc_unregister(struct device *d) {};
 #endif /* CONFIG_QCOM_GDSC */
+#ifndef CONFIG_PM
+struct gdsc_notifier_block {
+	struct notifier_block nb;
+	unsigned int	*clocks;
+	unsigned int	clock_count;
+};
+void qcom_pm_add_notifier(struct gdsc_notifier_block *);
+#endif /* !CONFIG_PM */
 #endif /* __QCOM_GDSC_H__ */
-- 
QUALCOMM INDIA, on behalf of Qualcomm Innovation Center, Inc. is a member
of Code Aurora Forum, hosted by The Linux Foundation



From tony at atomide.com  Thu Aug  6 03:40:31 2015
From: tony at atomide.com (Tony Lindgren)
Date: Thu, 6 Aug 2015 03:40:31 -0700
Subject: [GIT PULL] omap pbias regulator regression fixes against v4.2-rc5
Message-ID: <20150806104031.GE4215@atomide.com>

The following changes since commit 9908ac3daa3da2d236b5406b95d0865ddb8b29c4:

  ARM: dts: Correct audio input route & set mic bias for am335x-pepper (2015-07-15 03:03:01 -0700)

are available in the git repository at:

  git://git.kernel.org/pub/scm/linux/kernel/git/tmlind/linux-omap tags/omap-for-v4.2/fixes-rc5

for you to fetch changes up to cd4556733b30cc363adc7b1cea3bffa7e2dd0c7c:

  ARM: dts: dra7: Fix broken pbias device creation (2015-08-05 03:04:07 -0700)

----------------------------------------------------------------
Few trivial omap MMC regression fixes for card voltages where
the syscon areas for PBIAS regulator were missing "simple-bus"
that prevents probing of the children in the mapped region.

This probably was not noticed earlier as the bootloader has
already configured the regulator for the card in the slot.

----------------------------------------------------------------
Kishon Vijay Abraham I (4):
      ARM: dts: omap243x: Fix broken pbias device creation
      ARM: dts: OMAP4: Fix broken pbias device creation
      ARM: dts: OMAP5: Fix broken pbias device creation
      ARM: dts: dra7: Fix broken pbias device creation

 arch/arm/boot/dts/dra7.dtsi     | 2 +-
 arch/arm/boot/dts/omap2430.dtsi | 3 ++-
 arch/arm/boot/dts/omap4.dtsi    | 3 ++-
 arch/arm/boot/dts/omap5.dtsi    | 3 ++-
 4 files changed, 7 insertions(+), 4 deletions(-)


From tony at atomide.com  Thu Aug  6 03:45:16 2015
From: tony at atomide.com (Tony Lindgren)
Date: Thu, 6 Aug 2015 03:45:16 -0700
Subject: [GIT PULL] omap dts changes for v4.3 merge window, part 3
Message-ID: <20150806104516.GF4215@atomide.com>

The following changes since commit f5887fe5d14181aef0653ab04f60988252d42461:

  ARM: OMAP2+: Add custom abort handler for t410 (2015-07-23 22:33:19 -0700)

are available in the git repository at:

  git://git.kernel.org/pub/scm/linux/kernel/git/tmlind/linux-omap tags/omap-for-v4.3/dt-pt3

for you to fetch changes up to ed05637c30e6d13e5793aab64d6a6e57e30228af:

  ARM: dts: omap3-devkit8000: Add ADS7846 Touchscreen support (2015-08-06 02:43:09 -0700)

----------------------------------------------------------------
Omap device tree changes for v4.3 merge window. Pretty much all
just trivial additions to configure devices for various SoCs and
boards:

- Updates for omap3-devkit8000 board support

- M3 coprosessor, regulator, mux, RTC and eMMC updates for am437x

- MMC, regmap, mux and dwc3 updates for dra7 and omap5

----------------------------------------------------------------
Anthoine Bourgeois (7):
      ARM: dts: omap3-devkit8000: Add user button support
      ARM: dts: omap3-devkit8000: Add PMU stat support
      ARM: dts: omap3-devkit8000: Add keymap support
      ARM: dts: omap3-devkit8000: Add S-video output support
      ARM: dts: omap3-devkit8000: Add DSS' DVI support
      ARM: dts: omap3-devkit8000: add LCD panels
      ARM: dts: omap3-devkit8000: Add ADS7846 Touchscreen support

Balaji T K (1):
      ARM: dts: dra7-evm: add evm_3v3_sd regulator

Dave Gerlach (2):
      ARM: dts: am43xx: Introduce MUX_MODE9 for pinctrl
      ARM: dts: am437x-gp-evm: Add regulator-always-on and regulator-boot-on for RTC DCDCs

Felipe Balbi (1):
      ARM: dts: am4372: Add named interrupt property for dwc3

Keerthy (1):
      ARM: dts: AM4372: Reorder the rtc compatible string

Kishon Vijay Abraham I (5):
      ARM: dts: dra72-evm: add evm_3v3_sd regulator
      ARM: dts: dra72-evm: Set max clock frequency of MMC1 and MMC2
      ARM: dts: am57xx-beagle-x15: mmc1: remove redundant pbias-supply property
      ARM: dts: dra7-evm: Fix spurious card insert/removal interrupt
      ARM: dts: dra72-evm: Fix spurious card insert/removal interrupt

Nishanth Menon (1):
      ARM: dts: dra7-evm: Add MMCSD card removal GPIO

Roger Quadros (7):
      ARM: dts: omap5: Add named interrupt property for dwc3
      ARM: dts: dra7: Add named interrupt property for dwc3
      ARM: dts: dra7: Remove ctrl_core and ctrl_general nodes
      ARM: dts: dra7: fix pinmux at 1400 resource length
      ARM: dts: dra7: Add scm_conf at 1c04 node
      ARM: dts: am437x-gp-evm: Add gpio-hog for configuring eMMC/NAND driver
      ARM: dts: am437x-gp-evm: Add eMMC support

Suman Anna (2):
      ARM: dts: AM33xx: Add the wkup_m3_ipc node
      ARM: dts: AM4372: Add the wkup_m3_ipc node

 arch/arm/boot/dts/Makefile                         |   2 +
 arch/arm/boot/dts/am33xx.dtsi                      |   8 +
 arch/arm/boot/dts/am4372.dtsi                      |  24 +-
 arch/arm/boot/dts/am437x-gp-evm.dts                |  76 ++++-
 arch/arm/boot/dts/am57xx-beagle-x15.dts            |   1 -
 arch/arm/boot/dts/dra7-evm.dts                     |  18 +-
 arch/arm/boot/dts/dra7.dtsi                        |  38 ++-
 arch/arm/boot/dts/dra72-evm.dts                    |  16 +-
 arch/arm/boot/dts/dra74x.dtsi                      |   7 +-
 arch/arm/boot/dts/omap3-devkit8000-common.dtsi     | 369 +++++++++++++++++++++
 arch/arm/boot/dts/omap3-devkit8000-lcd-common.dtsi |  73 ++++
 arch/arm/boot/dts/omap3-devkit8000-lcd43.dts       |  37 +++
 arch/arm/boot/dts/omap3-devkit8000-lcd70.dts       |  37 +++
 arch/arm/boot/dts/omap3-devkit8000.dts             | 191 +----------
 arch/arm/boot/dts/omap5.dtsi                       |   7 +-
 include/dt-bindings/pinctrl/am43xx.h               |   1 +
 16 files changed, 695 insertions(+), 210 deletions(-)
 create mode 100644 arch/arm/boot/dts/omap3-devkit8000-common.dtsi
 create mode 100644 arch/arm/boot/dts/omap3-devkit8000-lcd-common.dtsi
 create mode 100644 arch/arm/boot/dts/omap3-devkit8000-lcd43.dts
 create mode 100644 arch/arm/boot/dts/omap3-devkit8000-lcd70.dts


From broonie at kernel.org  Thu Aug  6 04:00:18 2015
From: broonie at kernel.org (Mark Brown)
Date: Thu, 6 Aug 2015 12:00:18 +0100
Subject: [RFC PATCH 1/5] spi: introduce flag for memory mapped read
In-Reply-To: <20150806102225.GI7576@n2100.arm.linux.org.uk>
References: <55BEF4AF.5090704@ti.com> <20150804155148.GR20873@sirena.org.uk>
 <55C0FD98.1090107@ti.com> <20150805115013.GJ20873@sirena.org.uk>
 <CAOMqctQXwcHyiWBwtugSDSE_k65qrNfrwnhjQMDJkLoJMmGzUw@mail.gmail.com>
 <20150805124412.GN20873@sirena.org.uk>
 <CAOMqctS9Y5FxpUCCJew6+cnjH5iTvbzkH3g-8yrXs4OuS2pSGA@mail.gmail.com>
 <20150806090202.GO20873@sirena.org.uk>
 <CAOMqctQZRZ4zG_yYy=CeX3DX4NVNWN1COP4Q-2YvMun9xYOA7g@mail.gmail.com>
 <20150806102225.GI7576@n2100.arm.linux.org.uk>
Message-ID: <20150806110018.GS20873@sirena.org.uk>

On Thu, Aug 06, 2015 at 11:22:25AM +0100, Russell King - ARM Linux wrote:

> If that's the case, then maybe you should consider whether using the SPI
> bus infrastructure is really the best way forward.  Would it make more
> sense instead to adopt a different software structure, something more
> high-level like:

>      +-------------------------------------------+
>      |          m25p80 high-level driver         |
>      +----------------------+--------------------+
>      |   SPI m25p80 driver  |                    |
>      +----------------------+                    |
>      |      SPI layer       |  Special driver    |
>      +----------------------+                    |
>      |    SPI bus driver    |                    |
>      +----------------------+--------------------+
>      |     SPI hardware     |  Special hardware  |
>      +----------------------+--------------------+

Yes, that's what's been talked about before - for some of these devices
they're sufficiently flash specialist that we just don't bother exposing
a SPI interface at all though AIUI they could be persuaded to do it.  It
isn't entirely clear that we want exactly that split, if the devices are
reasonable SPI controllers we will want to handle the case where they
have flash and non-flash devices on the same bus.  For that there is
going to be some generalisable work possible for managing switching
between memory mapped and SPI modes where those are mutually exclusive,
especially if the switch between them isn't free.
-------------- next part --------------
A non-text attachment was scrubbed...
Name: signature.asc
Type: application/pgp-signature
Size: 473 bytes
Desc: Digital signature
URL: <http://lists.infradead.org/pipermail/linux-arm-kernel/attachments/20150806/c5de998c/attachment.sig>

From julien.grall at citrix.com  Thu Aug  6 04:00:30 2015
From: julien.grall at citrix.com (Julien Grall)
Date: Thu, 6 Aug 2015 12:00:30 +0100
Subject: [Xen-devel] [PATCH v2 4/8] xen: Use the correctly the Xen memory
 terminologies
In-Reply-To: <1438711972-18752-5-git-send-email-julien.grall@citrix.com>
References: <1438711972-18752-1-git-send-email-julien.grall@citrix.com>
 <1438711972-18752-5-git-send-email-julien.grall@citrix.com>
Message-ID: <55C33E4E.4050704@citrix.com>

Hi,


On 04/08/15 19:12, Julien Grall wrote:
> diff --git a/include/xen/page.h b/include/xen/page.h
> index c5ed20b..e7e1425 100644
> --- a/include/xen/page.h
> +++ b/include/xen/page.h
> @@ -3,9 +3,9 @@
>  
>  #include <asm/xen/page.h>
>  
> -static inline unsigned long page_to_mfn(struct page *page)
> +static inline unsigned long page_to_gfn(struct page *page)
>  {
> -	return pfn_to_mfn(page_to_pfn(page));
> +	return pfn_to_gfn(page_to_pfn(page));
>  }

I've just noticed that there is a function gfn_to_page used for KVM.

Maybe I should rename page_to_gfn to xen_page_to_gfn to avoid confusion
with KVM one?

Regards,

-- 
Julien Grall


From hramrach at gmail.com  Thu Aug  6 04:02:29 2015
From: hramrach at gmail.com (Michal Suchanek)
Date: Thu, 6 Aug 2015 13:02:29 +0200
Subject: [RFC PATCH 1/5] spi: introduce flag for memory mapped read
In-Reply-To: <20150806102225.GI7576@n2100.arm.linux.org.uk>
References: <20150731181745.GM20873@sirena.org.uk> <55BEF4AF.5090704@ti.com>
 <20150804155148.GR20873@sirena.org.uk> <55C0FD98.1090107@ti.com>
 <20150805115013.GJ20873@sirena.org.uk>
 <CAOMqctQXwcHyiWBwtugSDSE_k65qrNfrwnhjQMDJkLoJMmGzUw@mail.gmail.com>
 <20150805124412.GN20873@sirena.org.uk>
 <CAOMqctS9Y5FxpUCCJew6+cnjH5iTvbzkH3g-8yrXs4OuS2pSGA@mail.gmail.com>
 <20150806090202.GO20873@sirena.org.uk>
 <CAOMqctQZRZ4zG_yYy=CeX3DX4NVNWN1COP4Q-2YvMun9xYOA7g@mail.gmail.com>
 <20150806102225.GI7576@n2100.arm.linux.org.uk>
Message-ID: <CAOMqctSp7CorcVeZYm10cFnOKXG4F7MskkhZaXbV+9diUbfRdg@mail.gmail.com>

On 6 August 2015 at 12:22, Russell King - ARM Linux
<linux at arm.linux.org.uk> wrote:
> On Thu, Aug 06, 2015 at 12:01:37PM +0200, Michal Suchanek wrote:
>> Disclaimer: I am not familiar with the hardware for which this patch
>> adds support.
>>
>> However, I am familiar m25p80.c and as I understand it the controller
>> is basically supposed to implement m25p80.c in hardware when this flag
>> is set.
>
> That, to me, sounds like what you have is:
>
> ---m25p80 specific interface--->SPI bus--->m25p80 device
>
> Where the m25p80 specific interface does not expose direct access to the
> SPI bus?

The m25p80 specific hardware interface is presumably optional so you
can use it or not. The description is a bit vague, though.

In fsl-qspi the driver does not make it optional. I am not sure that
controller can be used for non-m25p80 slaves.


>
> If that's the case, then maybe you should consider whether using the SPI
> bus infrastructure is really the best way forward.  Would it make more
> sense instead to adopt a different software structure, something more
> high-level like:
>
>      +-------------------------------------------+
>      |          m25p80 high-level driver      =spi-nor   |
>      +----------------------+--------------------+
>      |   SPI m25p80 driver  |                    |
>      +----------------------+                    |
>      |      SPI layer       |  Special driver    =fsl-qspi|
>      +----------------------+                    |
>      |    SPI bus driver    |                    |
>      +----------------------+--------------------+
>      |     SPI hardware     |  Special hardware  |
>      +----------------------+--------------------+
>

Thanks

Michal


From t-kristo at ti.com  Thu Aug  6 04:08:22 2015
From: t-kristo at ti.com (Tero Kristo)
Date: Thu, 6 Aug 2015 14:08:22 +0300
Subject: [GIT PULL] omap clock dts changes for v4.3 merge window
Message-ID: <55C34026.20101@ti.com>

The following changes since commit bc0195aad0daa2ad5b0d76cce22b167bc3435590:

   Linux 4.2-rc2 (2015-07-12 15:10:30 -0700)

are available in the git repository at:

   https://github.com/t-kristo/linux-pm.git for-4.3/ti-clk-dt

for you to fetch changes up to dff8a207815a605872dfc5bffc1bae1cad29d87c:

   ARM: dts: am4372: Set the default clock rate for dpll_clksel_mac_clk 
clock (2015-07-31 12:13:18 +0300)

----------------------------------------------------------------
Keerthy (2):
       ARM: dts: AM437X: add dpll_clksel_mac_clk node
       ARM: dts: am4372: Set the default clock rate for 
dpll_clksel_mac_clk clock

  arch/arm/boot/dts/am4372.dtsi        |    7 +++++--
  arch/arm/boot/dts/am43xx-clocks.dtsi |    9 +++++++++
  drivers/clk/ti/clk-43xx.c            |    1 +
  3 files changed, 15 insertions(+), 2 deletions(-)


From stefano.stabellini at eu.citrix.com  Thu Aug  6 04:06:00 2015
From: stefano.stabellini at eu.citrix.com (Stefano Stabellini)
Date: Thu, 6 Aug 2015 12:06:00 +0100
Subject: [Xen-devel] [PATCH v2 4/8] xen: Use the correctly the Xen memory
 terminologies
In-Reply-To: <55C33E4E.4050704@citrix.com>
References: <1438711972-18752-1-git-send-email-julien.grall@citrix.com>
 <1438711972-18752-5-git-send-email-julien.grall@citrix.com>
 <55C33E4E.4050704@citrix.com>
Message-ID: <alpine.DEB.2.02.1508061205190.11337@kaball.uk.xensource.com>

On Thu, 6 Aug 2015, Julien Grall wrote:
> Hi,
> 
> 
> On 04/08/15 19:12, Julien Grall wrote:
> > diff --git a/include/xen/page.h b/include/xen/page.h
> > index c5ed20b..e7e1425 100644
> > --- a/include/xen/page.h
> > +++ b/include/xen/page.h
> > @@ -3,9 +3,9 @@
> >  
> >  #include <asm/xen/page.h>
> >  
> > -static inline unsigned long page_to_mfn(struct page *page)
> > +static inline unsigned long page_to_gfn(struct page *page)
> >  {
> > -	return pfn_to_mfn(page_to_pfn(page));
> > +	return pfn_to_gfn(page_to_pfn(page));
> >  }
> 
> I've just noticed that there is a function gfn_to_page used for KVM.
> 
> Maybe I should rename page_to_gfn to xen_page_to_gfn to avoid confusion
> with KVM one?

Yeah, prepending xen would help to avoid namespace pollution.


From heiko at sntech.de  Thu Aug  6 04:10:55 2015
From: heiko at sntech.de (Heiko =?ISO-8859-1?Q?St=FCbner?=)
Date: Thu, 06 Aug 2015 13:10:55 +0200
Subject: [PATCH v3 3/3] ARM: rockchip: enable PMU_GPIOINT_WAKEUP_EN when
 entering shallow suspend
In-Reply-To: <CAD=FV=W0L_0iM+15BAUfTA2ij5Ac90aVW9JZYyDhHMDNT2ZUMg@mail.gmail.com>
References: <2128609.Kb18M8K28F@diego> <1544453.8uqOvAiDmD@diego>
 <CAD=FV=W0L_0iM+15BAUfTA2ij5Ac90aVW9JZYyDhHMDNT2ZUMg@mail.gmail.com>
Message-ID: <3564263.VnOXW7qXSg@diego>

Am Mittwoch, 5. August 2015, 18:55:52 schrieb Doug Anderson:
> Heiko,
> 
> On Tue, Aug 4, 2015 at 3:51 PM, Heiko St?bner <heiko at sntech.de> wrote:
> > PMU_GPIOINT_WAKEUP_EN seems needed when entering the shallow suspend
> > (with logic staying on) but does not seem to be needed for the deep
> > suspend for unknown reasons.
> > Testing revealed that this setting really is necessary to reliably
> > resume the veyron devices from suspend.
> > 
> > Reported-by: Chris Zhong <zyw at rock-chips.com>
> > Signed-off-by: Heiko Stuebner <heiko at sntech.de>
> > ---
> > 
> >  arch/arm/mach-rockchip/pm.c | 9 ++++++---
> >  arch/arm/mach-rockchip/pm.h | 1 +
> >  2 files changed, 7 insertions(+), 3 deletions(-)
> 
> Very odd, but OK by me...

Hopefully we'll get an explaination from the ic-people soon-ish.


> Hopefully we'll eventually end up being
> able to use deep suspend on mainline.  That'd be nice, wouldn't it?

hehe ... yep, one of the big remaining projects :-)


From heiko at sntech.de  Thu Aug  6 04:11:49 2015
From: heiko at sntech.de (Heiko =?ISO-8859-1?Q?St=FCbner?=)
Date: Thu, 06 Aug 2015 13:11:49 +0200
Subject: [PATCH v3 1/3] ARM: rockchip: rename osc_switch_to_32k variable
In-Reply-To: <2128609.Kb18M8K28F@diego>
References: <2128609.Kb18M8K28F@diego>
Message-ID: <39971049.CiZJKWC18V@diego>

Am Mittwoch, 5. August 2015, 00:50:39 schrieb Heiko St?bner:
> The variable name is misleading, as the deep suspend mode always switches
> the main supplying clock to the 32kHz source. Additionally the main
> oscillator remain running in some cases, which this var indicates.
> 
> So rename it to osc_disable to clarity.
> 
> Signed-off-by: Heiko Stuebner <heiko at sntech.de>

applied all 3 patches with Chris' and Doug's tags to my soc branch


From gregory.clement at free-electrons.com  Thu Aug  6 04:14:48 2015
From: gregory.clement at free-electrons.com (Gregory CLEMENT)
Date: Thu, 06 Aug 2015 13:14:48 +0200
Subject: [PATCH 7/7] ARM: redo TTBR setup code for LPAE
In-Reply-To: <20150805160112.GZ7557@n2100.arm.linux.org.uk>
References: <20150506103000.GF2067@n2100.arm.linux.org.uk>
 <E1YpwbQ-0000wm-Jx@rmk-PC.arm.linux.org.uk>
 <55C22B21.8000700@free-electrons.com>
 <20150805160112.GZ7557@n2100.arm.linux.org.uk>
Message-ID: <55C341A8.5040504@free-electrons.com>

On 05/08/2015 18:01, Russell King - ARM Linux wrote:
> On Wed, Aug 05, 2015 at 05:26:25PM +0200, Gregory CLEMENT wrote:
>> It seems that since the merge of this commit the secondary CPUs on
>> Armada XP failed to come online in Big Endian (my configuration is
>> mvebu_v7_defconfig+CONFIG_CPU_BIG_ENDIAN=y).
> 
> That's probably because I don't test big endian at all, never have done,
> and I suspect never will as I've never had systems using BE.  So, I regard
> BE as something of a troublesome untestable burden on kernel development.
> (And I've always regarded BE to be an abomination.)  In short, I loath
> big endian, which really doesn't bode well for me not constantly cocking
> it up...
> 
> My guess is that it all comes down to much of the new code expecting the
> value in r4/r5 to be the least significant 32bits in r4 and the most
> significant 32bits in r5.  However, in the secondary code, we load this
> using ldrd, which on BE probably reverses that.

Thanks for the explanation.

> 
>> Once I found that this commit introduced the regression I also tested
>> but with LPAE but I had the same result: only the first CPU boot.
> 
> Not surprising.  I guess BE would need the two registers to mcrr reversing
> if they were a 64-bit value loaded with ldrd.
> 
> The simple answer may just be to swap r4/r5 after the ldrd.  

I tried this and it fixed the issue.
I will send a patch shortly and if you agree I will submit it to your
patch system.

Thanks,

Gregory


-- 
Gregory Clement, Free Electrons
Kernel, drivers, real-time and embedded Linux
development, consulting, training and support.
http://free-electrons.com


From julien.grall at citrix.com  Thu Aug  6 04:17:36 2015
From: julien.grall at citrix.com (Julien Grall)
Date: Thu, 6 Aug 2015 12:17:36 +0100
Subject: [Xen-devel] [PATCH v2 4/8] xen: Use the correctly the Xen memory
 terminologies
In-Reply-To: <alpine.DEB.2.02.1508061205190.11337@kaball.uk.xensource.com>
References: <1438711972-18752-1-git-send-email-julien.grall@citrix.com>
 <1438711972-18752-5-git-send-email-julien.grall@citrix.com>
 <55C33E4E.4050704@citrix.com>
 <alpine.DEB.2.02.1508061205190.11337@kaball.uk.xensource.com>
Message-ID: <55C34250.3040801@citrix.com>

On 06/08/15 12:06, Stefano Stabellini wrote:
> On Thu, 6 Aug 2015, Julien Grall wrote:
>> Hi,
>>
>>
>> On 04/08/15 19:12, Julien Grall wrote:
>>> diff --git a/include/xen/page.h b/include/xen/page.h
>>> index c5ed20b..e7e1425 100644
>>> --- a/include/xen/page.h
>>> +++ b/include/xen/page.h
>>> @@ -3,9 +3,9 @@
>>>  
>>>  #include <asm/xen/page.h>
>>>  
>>> -static inline unsigned long page_to_mfn(struct page *page)
>>> +static inline unsigned long page_to_gfn(struct page *page)
>>>  {
>>> -	return pfn_to_mfn(page_to_pfn(page));
>>> +	return pfn_to_gfn(page_to_pfn(page));
>>>  }
>>
>> I've just noticed that there is a function gfn_to_page used for KVM.
>>
>> Maybe I should rename page_to_gfn to xen_page_to_gfn to avoid confusion
>> with KVM one?
> 
> Yeah, prepending xen would help to avoid namespace pollution.

Will do. May I keep your Reviewed-by for this mechanical change?

Regards,

-- 
Julien Grall


From broonie at kernel.org  Thu Aug  6 04:23:53 2015
From: broonie at kernel.org (Mark Brown)
Date: Thu, 6 Aug 2015 12:23:53 +0100
Subject: [RFC PATCH 1/5] spi: introduce flag for memory mapped read
In-Reply-To: <CAOMqctQZRZ4zG_yYy=CeX3DX4NVNWN1COP4Q-2YvMun9xYOA7g@mail.gmail.com>
References: <20150731181745.GM20873@sirena.org.uk> <55BEF4AF.5090704@ti.com>
 <20150804155148.GR20873@sirena.org.uk> <55C0FD98.1090107@ti.com>
 <20150805115013.GJ20873@sirena.org.uk>
 <CAOMqctQXwcHyiWBwtugSDSE_k65qrNfrwnhjQMDJkLoJMmGzUw@mail.gmail.com>
 <20150805124412.GN20873@sirena.org.uk>
 <CAOMqctS9Y5FxpUCCJew6+cnjH5iTvbzkH3g-8yrXs4OuS2pSGA@mail.gmail.com>
 <20150806090202.GO20873@sirena.org.uk>
 <CAOMqctQZRZ4zG_yYy=CeX3DX4NVNWN1COP4Q-2YvMun9xYOA7g@mail.gmail.com>
Message-ID: <20150806112353.GT20873@sirena.org.uk>

On Thu, Aug 06, 2015 at 12:01:37PM +0200, Michal Suchanek wrote:

> However, I am familiar m25p80.c and as I understand it the controller
> is basically supposed to implement m25p80.c in hardware when this flag
> is set.

But what in concrete terms is that supposed to mean?  It's currently
just an essentially undocumented flag on a message rather than something
operating at the level of a flash chip.  That's pretty much where
Russell's comments come from.

> If I was using m25p80.c to talk to anything but an actual flash chip
> it would get me quite worried.

Sure, but at the end of the day it's just emitting standard SPI messages
which don't know anything about flash.  If those messages are a sensible
interface here then why bother with the flag, we can just pattern match
on the format of the message.  If that doesn't work then probably this
isn't a great interface and a separate, application specific interface
makes more sense.
-------------- next part --------------
A non-text attachment was scrubbed...
Name: signature.asc
Type: application/pgp-signature
Size: 473 bytes
Desc: Digital signature
URL: <http://lists.infradead.org/pipermail/linux-arm-kernel/attachments/20150806/3c0b0c61/attachment.sig>

From gregory.clement at free-electrons.com  Thu Aug  6 04:27:32 2015
From: gregory.clement at free-electrons.com (Gregory CLEMENT)
Date: Thu,  6 Aug 2015 13:27:32 +0200
Subject: [PATCH] ARM: Fix the secondary_startup function in Big Endian case
Message-ID: <1438860452-6347-1-git-send-email-gregory.clement@free-electrons.com>

Since the commit "b2c3e38a5471 ARM: redo TTBR setup code for LPAE",
the setup code had been reworked. As a result the secondary CPUs
failed to come online in Big Endian.

As explained by Russell, the new code expected the value in r4/r5 to
be the least significant 32bits in r4 and the most significant 32bits
in r5. However, in the secondary code, we load this using ldrd, which
on BE reverses that.

This patch swap r4/r5 after the ldrd. It is done using the xor
instructions in order to not use a temporary register.

Signed-off-by: Gregory CLEMENT <gregory.clement at free-electrons.com>
---
 arch/arm/kernel/head.S | 3 +++
 1 file changed, 3 insertions(+)

diff --git a/arch/arm/kernel/head.S b/arch/arm/kernel/head.S
index bd755d97e459..75cbcf34c2e9 100644
--- a/arch/arm/kernel/head.S
+++ b/arch/arm/kernel/head.S
@@ -399,6 +399,9 @@ ENTRY(secondary_startup)
 	sub	lr, r4, r5			@ mmu has been enabled
 	add	r3, r7, lr
 	ldrd	r4, [r3, #0]			@ get secondary_data.pgdir
+ARM_BE8(eor	r4, r4, r5)			@ swap r5 and r4 in BE
+ARM_BE8(eor	r5, r4, r5)			@ it can be done in 3 step
+ARM_BE8(eor	r4, r4, r5)			@ without using an temp reg
 	ldr	r8, [r3, #8]			@ get secondary_data.swapper_pg_dir
 	badr	lr, __enable_mmu		@ return address
 	mov	r13, r12			@ __secondary_switched address
-- 
2.1.0



From hramrach at gmail.com  Thu Aug  6 04:42:32 2015
From: hramrach at gmail.com (Michal Suchanek)
Date: Thu, 6 Aug 2015 13:42:32 +0200
Subject: [RFC PATCH 1/5] spi: introduce flag for memory mapped read
In-Reply-To: <20150806112353.GT20873@sirena.org.uk>
References: <20150731181745.GM20873@sirena.org.uk> <55BEF4AF.5090704@ti.com>
 <20150804155148.GR20873@sirena.org.uk> <55C0FD98.1090107@ti.com>
 <20150805115013.GJ20873@sirena.org.uk>
 <CAOMqctQXwcHyiWBwtugSDSE_k65qrNfrwnhjQMDJkLoJMmGzUw@mail.gmail.com>
 <20150805124412.GN20873@sirena.org.uk>
 <CAOMqctS9Y5FxpUCCJew6+cnjH5iTvbzkH3g-8yrXs4OuS2pSGA@mail.gmail.com>
 <20150806090202.GO20873@sirena.org.uk>
 <CAOMqctQZRZ4zG_yYy=CeX3DX4NVNWN1COP4Q-2YvMun9xYOA7g@mail.gmail.com>
 <20150806112353.GT20873@sirena.org.uk>
Message-ID: <CAOMqctQKc6f5Mbe_CSd-ghguUfZvf6v_BRvYxQJVqPne73iESA@mail.gmail.com>

On 6 August 2015 at 13:23, Mark Brown <broonie at kernel.org> wrote:
> On Thu, Aug 06, 2015 at 12:01:37PM +0200, Michal Suchanek wrote:
>
>> However, I am familiar m25p80.c and as I understand it the controller
>> is basically supposed to implement m25p80.c in hardware when this flag
>> is set.
>
> But what in concrete terms is that supposed to mean?  It's currently
> just an essentially undocumented flag on a message rather than something
> operating at the level of a flash chip.  That's pretty much where
> Russell's comments come from.
>
>> If I was using m25p80.c to talk to anything but an actual flash chip
>> it would get me quite worried.
>
> Sure, but at the end of the day it's just emitting standard SPI messages
> which don't know anything about flash.  If those messages are a sensible
> interface here then why bother with the flag, we can just pattern match
> on the format of the message.  If that doesn't work then probably this
> isn't a great interface and a separate, application specific interface
> makes more sense.

The messages are sensible interface for communicating with a device
that interprets a particular part of the mesasge as address and
another particular part of the message as command and sends same
amount of junk before reply as the flash chip would. If your device
happens to send reply immediately part of it is trashed. If it happens
to interpret address differently the data ends up in random part of
your memory. So no, that is not something you can autodetect.

At the end of the day you have valid SPI messages but the m25p80 layer
adds interpretation to those messages which may not always give
correct result.

On the other hand, if you ever get to m25p80 or spi-nor you can assume
any message you send goes to a flash chip and insist that the
controller uses the flash-specific interface.

If there is possibility of connecting different kind of devices to
multiple chipselects on the same master then you probably want to
select this option per message or per slave.

Thanks

Michal


From christoffer.dall at linaro.org  Thu Aug  6 04:54:36 2015
From: christoffer.dall at linaro.org (Christoffer Dall)
Date: Thu, 6 Aug 2015 13:54:36 +0200
Subject: [PATCH v4 1/2] arm64: KVM: Optimize arm64 skip 30-50% vfp/simd
 save/restore on exits
In-Reply-To: <55C235B9.3000800@arm.com>
References: <1437082178-11039-1-git-send-email-m.smarduch@samsung.com>
 <1437082178-11039-2-git-send-email-m.smarduch@samsung.com>
 <55C235B9.3000800@arm.com>
Message-ID: <20150806115436.GC4657@cbox>

On Wed, Aug 05, 2015 at 05:11:37PM +0100, Marc Zyngier wrote:
> On 16/07/15 22:29, Mario Smarduch wrote:
> > This patch only saves and restores FP/SIMD registers on Guest access. To do
> > this cptr_el2 FP/SIMD trap is set on Guest entry and later checked on exit.
> > lmbench, hackbench show significant improvements, for 30-50% exits FP/SIMD
> > context is not saved/restored
> > 
> > Signed-off-by: Mario Smarduch <m.smarduch at samsung.com>
> 
> So this patch seems to break 32bit guests on arm64.  I've had a look,
> squashed a few bugs that I dangerously overlooked during the review, but
> it still doesn't work (it doesn't crash anymore, but I get random
> illegal VFP instructions in 32bit guests).
> 
> I'd be glad if someone could eyeball the following patch and tell me
> what's going wrong. If we don't find the root cause quickly enough, I'll
> have to drop the series from -next, and that'd be a real shame.
> 
> Thanks,
> 
> 	M.
> 
> commit 5777dc55fbc170426a85e00c26002dd5a795cfa5
> Author: Marc Zyngier <marc.zyngier at arm.com>
> Date:   Wed Aug 5 16:53:01 2015 +0100
> 
>     KVM: arm64: NOTAFIX: Prevent crash when 32bit guest uses VFP
> 
>     Since we switch FPSIMD in a lazy way, access to FPEXC32_EL2
>     must be guarded by skip_fpsimd_state. Otherwise, all hell
>     break loose.
> 
>     Also, FPEXC32_EL2 must be restored when we trap to EL2 to
>     enable floating point.
> 
>     Note that while it prevents the host from catching fire, the
>     guest still doesn't work properly, and I don't understand why just
>     yet.
> 
>     Not-really-signed-off-by: Marc Zyngier <marc.zyngier at arm.com>
> 
> diff --git a/arch/arm64/kvm/hyp.S b/arch/arm64/kvm/hyp.S
> index c8e0c70..b53ec5d 100644
> --- a/arch/arm64/kvm/hyp.S
> +++ b/arch/arm64/kvm/hyp.S
> @@ -431,10 +431,12 @@
>  	add	x3, x2, #CPU_SYSREG_OFFSET(DACR32_EL2)
>  	mrs	x4, dacr32_el2
>  	mrs	x5, ifsr32_el2
> -	mrs	x6, fpexc32_el2
>  	stp	x4, x5, [x3]
> -	str	x6, [x3, #16]
> 
> +	skip_fpsimd_state x8, 3f
> +	mrs	x6, fpexc32_el2
> +	str	x6, [x3, #16]
> +3:
>  	skip_debug_state x8, 2f
>  	mrs	x7, dbgvcr32_el2
>  	str	x7, [x3, #24]
> @@ -461,10 +463,8 @@
> 
>  	add	x3, x2, #CPU_SYSREG_OFFSET(DACR32_EL2)
>  	ldp	x4, x5, [x3]
> -	ldr	x6, [x3, #16]
>  	msr	dacr32_el2, x4
>  	msr	ifsr32_el2, x5
> -	msr	fpexc32_el2, x6
> 
>  	skip_debug_state x8, 2f
>  	ldr	x7, [x3, #24]
> @@ -669,12 +669,14 @@ __restore_debug:
>  	ret
> 
>  __save_fpsimd:
> +	skip_fpsimd_state x3, 1f
>  	save_fpsimd
> -	ret
> +1:	ret
> 
>  __restore_fpsimd:
> +	skip_fpsimd_state x3, 1f
>  	restore_fpsimd
> -	ret
> +1:	ret
> 
>  switch_to_guest_fpsimd:
>  	push	x4, lr
> @@ -682,6 +684,7 @@ switch_to_guest_fpsimd:
>  	mrs	x2, cptr_el2
>  	bic	x2, x2, #CPTR_EL2_TFP
>  	msr	cptr_el2, x2
> +	isb

ah, EL2 accesses themselves trap too, ouch.

> 
>  	mrs	x0, tpidr_el2
> 
> @@ -692,6 +695,10 @@ switch_to_guest_fpsimd:
>  	add	x2, x0, #VCPU_CONTEXT
>  	bl __restore_fpsimd
> 
> +	skip_32bit_state x3, 1f
> +	ldr	x4, [x2, #CPU_SYSREG_OFFSET(FPEXC32_EL2)]
> +	msr	fpexc32_el2, x4
> +1:

wait, it looks like you're missing a store of the host fpsimd state in
the switch_to_guest_fpsimd situation.

It think this would be easier to follow if the aarch32 FP registers were
handled as part of the __save_fpsimd  and __restore_fpsimd routines
instead.


Does this help anything?

Otherwise, I assume you've tested thoroughly between something like
v4.2-rc2 and this patch, so that you're sure we didn't have the 32-bit
processed crash before?

Thanks,
-Christoffer

>  	pop	x4, lr
>  	pop	x2, x3
>  	pop	x0, x1
> @@ -754,9 +761,7 @@ __kvm_vcpu_return:
>  	add	x2, x0, #VCPU_CONTEXT
> 
>  	save_guest_regs
> -	skip_fpsimd_state x3, 1f
>  	bl __save_fpsimd
> -1:
>  	bl __save_sysregs
> 
>  	skip_debug_state x3, 1f
> @@ -777,9 +782,7 @@ __kvm_vcpu_return:
>  	kern_hyp_va x2
> 
>  	bl __restore_sysregs
> -	skip_fpsimd_state x3, 1f
>  	bl __restore_fpsimd
> -1:
>  	/* Clear FPSIMD and Trace trapping */
>  	msr     cptr_el2, xzr
> 
> 
> -- 
> Jazz is not dead. It just smells funny...


From pbonzini at redhat.com  Thu Aug  6 05:00:55 2015
From: pbonzini at redhat.com (Paolo Bonzini)
Date: Thu, 6 Aug 2015 14:00:55 +0200
Subject: [PATCH] kvm:arm:Fix error handling in the function vgic_v3_probe
In-Reply-To: <55C31582.4000809@arm.com>
References: <1438793303-30228-1-git-send-email-xerofoify@gmail.com>
 <55C240D9.5060900@redhat.com> <55C242C6.6060200@gmail.com>
 <55C31582.4000809@arm.com>
Message-ID: <55C34C77.7090303@redhat.com>



On 06/08/2015 10:06, Marc Zyngier wrote:
> > If this structure of function pointers can handle function pointers with a return type of 
> > void I will be glad to do what you request otherwise this would require a major rewrite
> > of kvm arm subsystem for a very simple bug fix.
> 
> Just like Paolo said, the error you report should never happen, and
> would be caught by a WARN_ON() the first time anyone boots the kernel.
> Also, failing to register the device ops results in not being able to
> instantiate a VGIC. No harm done. I really don't understand why you want
> to rewrite the probe functions.

I think he just misunderstood my suggestion.  I didn't suggest making
the probe functions return void.  I suggested that
kvm_register_device_ops return void.

Paolo


From p.fedin at samsung.com  Thu Aug  6 05:06:32 2015
From: p.fedin at samsung.com (Pavel Fedin)
Date: Thu, 06 Aug 2015 15:06:32 +0300
Subject: [PATCH v3 0/7] KVM: arm/arm64: gsi routing support
In-Reply-To: <1438615889-10892-1-git-send-email-eric.auger@linaro.org>
References: <1438615889-10892-1-git-send-email-eric.auger@linaro.org>
Message-ID: <002401d0d040$5667c530$03374f90$@samsung.com>

Tested-by: Pavel Fedin <p.fedin at samsung.com>

Kind regards,
Pavel Fedin
Expert Engineer
Samsung Electronics Research center Russia

> -----Original Message-----
> From: Eric Auger [mailto:eric.auger at linaro.org]
> Sent: Monday, August 03, 2015 6:31 PM
> To: eric.auger at st.com; eric.auger at linaro.org; linux-arm-kernel at lists.infradead.org;
> kvmarm at lists.cs.columbia.edu; kvm at vger.kernel.org; christoffer.dall at linaro.org;
> marc.zyngier at arm.com
> Cc: linux-kernel at vger.kernel.org; patches at linaro.org; pbonzini at redhat.com;
> andre.przywara at arm.com; p.fedin at samsung.com
> Subject: [PATCH v3 0/7] KVM: arm/arm64: gsi routing support
> 
> With the advent of GICv3 ITS in-kernel emulation, KVM GSI routing
> appears to be requested. More specifically MSI routing is needed.
> irqchip routing does not sound to be really useful on arm but usage of
> MSI routing also mandates to integrate irqchip routing. The initial
> implementation of irqfd on arm must be upgraded with the integration
> of kvm irqchip.c code and the implementation of its standard hooks
> in the architecture specific part.
> 
> In case KVM_SET_GSI_ROUTING ioctl is not called, a default routing
> table with flat irqchip routing entries is built enabling to inject gsi
> corresponding to the SPI indexes seen by the guest.
> 
> As soon as KVM_SET_GSI_ROUTING is called, user-space overwrites this
> default routing table and is responsible for building the whole routing
> table.
> 
> for arm/arm64 KVM_SET_GSI_ROUTING has a limited support:
> - only applies to KVM_IRQFD and not to KVM_IRQ_LINE
> 
> - irqchip routing was tested on Calxeda midway (VFIO with irqfd)
>   with and without explicit routing
> - MSI routing without GICv3 ITS was tested using APM Xgene-I
>   (qemu VIRTIO-PCI vhost-net without gsi_direct_mapping).
> - MSI routing with GICv3 ITS is *NOT* tested.
> 
> Code can be found at
https://git.linaro.org/people/eric.auger/linux.git/shortlog/refs/heads/v4.2-rc4-
> gsi-routing-v3
> 
> It applies on Andre's [PATCH v2 00/15] KVM: arm64: GICv3 ITS emulation
> (http://lists.infradead.org/pipermail/linux-arm-kernel/2015-July/355727.html)
> 
> History:
> v2 -> v3:
> - eventually got rid of KVM_IRQ_ROUTING_EXTENDED_MSI new type at user
>   api level and use KVM_MSI_VALID_DEVID flag instead
> - remove usage of KVM_IRQ_ROUTING_EXTENDED_MSI type at kernel level too.
> - propagate user flags downto the kernel to make sure the userspace
>   correctly set devid in GICv3 ITS case (still under discussion)
> 
> v1 -> v2:
> - user API changed:
>   x devid id passed in kvm_irq_routing_msi
>   x kept the new routing entry type: KVM_IRQ_ROUTING_EXTENDED_MSI
> - kvm_host.h: adopt Andre's proposal to replace the msi_msg by a struct
>   composed of the msi_msg and devid in kvm_kernel_irq_routing_entry
> - Fix bug reported by Pavel: Added KVM_IRQ_ROUTING_EXTENDED_MSI handling
>   in eventfd.c
> - added vgic_v2m_inject_msi in vgic-v2-emul.c as suggested by Andre
> - fix bug reported by Andre: bad setting of msi.flags and msi.devid
>   in kvm_send_userspace_msi
> - avoid injecting reserved IRQ numbers in vgic_irqfd_set_irq
> 
> RFC -> PATCH:
> - clearly state limited support on arm/arm64:
>   KVM_IRQ_LINE not impacted by GSI routing
> - add default routing table feature (new patch file)
> - changed uapi to use padding field area
> - reword api.txt
> 
> Eric Auger (7):
>   KVM: api: pass the devid in the msi routing entry
>   KVM: kvm_host: add devid in kvm_kernel_irq_routing_entry
>   KVM: irqchip: convey devid to kvm_set_msi
>   KVM: arm/arm64: enable irqchip routing
>   KVM: arm/arm64: build a default routing table
>   KVM: arm/arm64: enable MSI routing
>   KVM: arm: enable KVM_SIGNAL_MSI and MSI routing
> 
>  Documentation/virtual/kvm/api.txt |  35 ++++++++++---
>  arch/arm/include/asm/kvm_host.h   |   2 +
>  arch/arm/kvm/Kconfig              |   3 ++
>  arch/arm/kvm/Makefile             |   2 +-
>  arch/arm64/include/asm/kvm_host.h |   1 +
>  arch/arm64/kvm/Kconfig            |   2 +
>  arch/arm64/kvm/Makefile           |   2 +-
>  include/kvm/arm_vgic.h            |   2 -
>  include/linux/kvm_host.h          |   8 ++-
>  include/uapi/linux/kvm.h          |   5 +-
>  virt/kvm/arm/vgic-v2-emul.c       |  16 ++++++
>  virt/kvm/arm/vgic.c               | 107 ++++++++++++++++++++++++++++++--------
>  virt/kvm/irqchip.c                |   8 ++-
>  13 files changed, 158 insertions(+), 35 deletions(-)
> 
> --
> 1.9.1



From christoffer.dall at linaro.org  Thu Aug  6 05:08:50 2015
From: christoffer.dall at linaro.org (Christoffer Dall)
Date: Thu, 6 Aug 2015 14:08:50 +0200
Subject: [PATCH] kvm:arm:Fix error handling in the function vgic_v3_probe
In-Reply-To: <55C34C77.7090303@redhat.com>
References: <1438793303-30228-1-git-send-email-xerofoify@gmail.com>
 <55C240D9.5060900@redhat.com> <55C242C6.6060200@gmail.com>
 <55C31582.4000809@arm.com> <55C34C77.7090303@redhat.com>
Message-ID: <20150806120850.GD4657@cbox>

On Thu, Aug 06, 2015 at 02:00:55PM +0200, Paolo Bonzini wrote:
> 
> 
> On 06/08/2015 10:06, Marc Zyngier wrote:
> > > If this structure of function pointers can handle function pointers with a return type of 
> > > void I will be glad to do what you request otherwise this would require a major rewrite
> > > of kvm arm subsystem for a very simple bug fix.
> > 
> > Just like Paolo said, the error you report should never happen, and
> > would be caught by a WARN_ON() the first time anyone boots the kernel.
> > Also, failing to register the device ops results in not being able to
> > instantiate a VGIC. No harm done. I really don't understand why you want
> > to rewrite the probe functions.
> 
> I think he just misunderstood my suggestion.  I didn't suggest making
> the probe functions return void.  I suggested that
> kvm_register_device_ops return void.
> 
s390 seems to actually deal with the return value of this function and
fail to init KVM at all if it fails, but on the other hand, this
function only fails if you're doing something truly stupid and
internal-to-kvm incoherent, so I think it's fair to just do a WARN_ON()
or even BUG_ON() and make the register function a void.

-Christoffer


From vigneshr at ti.com  Thu Aug  6 05:25:23 2015
From: vigneshr at ti.com (Vignesh R)
Date: Thu, 6 Aug 2015 17:55:23 +0530
Subject: [RFC PATCH 1/5] spi: introduce flag for memory mapped read
In-Reply-To: <20150806102225.GI7576@n2100.arm.linux.org.uk>
References: <20150731181745.GM20873@sirena.org.uk> <55BEF4AF.5090704@ti.com>
 <20150804155148.GR20873@sirena.org.uk> <55C0FD98.1090107@ti.com>
 <20150805115013.GJ20873@sirena.org.uk>
 <CAOMqctQXwcHyiWBwtugSDSE_k65qrNfrwnhjQMDJkLoJMmGzUw@mail.gmail.com>
 <20150805124412.GN20873@sirena.org.uk>
 <CAOMqctS9Y5FxpUCCJew6+cnjH5iTvbzkH3g-8yrXs4OuS2pSGA@mail.gmail.com>
 <20150806090202.GO20873@sirena.org.uk>
 <CAOMqctQZRZ4zG_yYy=CeX3DX4NVNWN1COP4Q-2YvMun9xYOA7g@mail.gmail.com>
 <20150806102225.GI7576@n2100.arm.linux.org.uk>
Message-ID: <55C35233.2000105@ti.com>



On 08/06/2015 03:52 PM, Russell King - ARM Linux wrote:
> On Thu, Aug 06, 2015 at 12:01:37PM +0200, Michal Suchanek wrote:
>> Disclaimer: I am not familiar with the hardware for which this patch
>> adds support.
>>
>> However, I am familiar m25p80.c and as I understand it the controller
>> is basically supposed to implement m25p80.c in hardware when this flag
>> is set.
> 
> That, to me, sounds like what you have is:
> 
> ---m25p80 specific interface--->SPI bus--->m25p80 device
> 
> Where the m25p80 specific interface does not expose direct access to the
> SPI bus?
> 

Let me give overview of ti-qspi controller:

There are two interfaces in the controller, one exposes direct access to
SPI bus and the other doesn't. It is possible to dynamically switch
between these ports by writing to QSPI_SPI_SWITCH_REG.

The two interface are [1]:
1) Generic SPI interface: (config port): with this interface, ti-qspi
controller can communicate with *any* spi device (flash and non-flash).
This interface is provides direct access to SPI bus.

2) SPI memory mapped interface (memory mapped port): This is m25p80
specific interface which can be use to read data from flash.
But if the flash has to be configured to some particular mode like QUAD
READ MODE, then the controller needs to be put in to config port to read
and modify serial flash's config register and then switch to memory
mapped port in order to read data stored on flash.

For example on DRA74 evm, if a 64 MB flash is connected as a slave,
entire flash memory is visible from 0x5C000000 to 0x5FFFFFFF L3_MAIN
address. In order to read using memory mapped port following will be the
sequence:

1.Write to flash config register via config port to switch to QUAD MODE
(or any mode that flash supports).
2. Populate QSPI_SPI_SETUP_REGx with flash read command, number of
address bytes to use and dummy bytes required.
3. Switch to memory mapped port by writing to QSPI_SPI_SWITCH_REG.
4. Now, its possible to perform read from 0x5C000000 to 0x5FFFFFFF using
memcpy. The qspi controller hardware will communicate over SPI bus and
get the data. This data is directly sent to RAM via SoC's interconnect.

Advantages of memory mapped port are: improved read performance,
MEM_TO_MEM DMA support can be added (ti-qspi hardware as such does not
provide DMA events).

Advantages of config port: can be used to communicate with *any* SPI
device, provides direct read/write access to SPI bus.

On the whole following are my requirements:
1. to be able to communicate with non -flash SPI devices via config port
( this functionality is supported by current driver, I dont want to
break it). Or pump any spi_message on to SPI bus directly.
2. take advantage of memory mapped port in order to increase read
throughput( and use dma in future) when the slave is a m25p80 type flash.
3. handle m25p80 as well as other slave on multiple chipselects.

I just need to know whether the user that requested the transfer is
m25p80 driver. If yes, ti-qspi driver can take advantage of memory
mapped interface, else just use config port to access SPI bus directly.

Writing separate driver based on spi-nor framework to interface with
m25p80 is not an option because, I would lose the ability to interface
with non-flash devices.

The spi_message that is received in transfer_one_message() is too
generic to imply the slave device that is on the other side of the wire.
IMO, the read command does not imply that the slave is m25p80 flash
(besides the read opcodes vary across vendors of m25p80 and across modes).

As Michal suggested, adding a flag to spi_device to distinguish whether
the slave is a m25p80 flash type will help spi master to handle
optimizations specific to m25p80s while being generic enough to handle
all other spi devices. Is that ok? Is there any other way to imply what
slave as at the other end?

[1] TRM: http://www.ti.com/lit/ug/spruhz6/spruhz6.pdf 24.5.4 QSPI
Functional Description
-- 
Regards
Vignesh


From marc.zyngier at arm.com  Thu Aug  6 05:46:31 2015
From: marc.zyngier at arm.com (Marc Zyngier)
Date: Thu, 06 Aug 2015 13:46:31 +0100
Subject: [PATCH v4 1/2] arm64: KVM: Optimize arm64 skip 30-50% vfp/simd
 save/restore on exits
In-Reply-To: <20150806115436.GC4657@cbox>
References: <1437082178-11039-1-git-send-email-m.smarduch@samsung.com>
 <1437082178-11039-2-git-send-email-m.smarduch@samsung.com>
 <55C235B9.3000800@arm.com> <20150806115436.GC4657@cbox>
Message-ID: <55C35727.6060208@arm.com>

Hi Christoffer,

On 06/08/15 12:54, Christoffer Dall wrote:
> On Wed, Aug 05, 2015 at 05:11:37PM +0100, Marc Zyngier wrote:
>> On 16/07/15 22:29, Mario Smarduch wrote:
>>> This patch only saves and restores FP/SIMD registers on Guest access. To do
>>> this cptr_el2 FP/SIMD trap is set on Guest entry and later checked on exit.
>>> lmbench, hackbench show significant improvements, for 30-50% exits FP/SIMD
>>> context is not saved/restored
>>>
>>> Signed-off-by: Mario Smarduch <m.smarduch at samsung.com>
>>
>> So this patch seems to break 32bit guests on arm64.  I've had a look,
>> squashed a few bugs that I dangerously overlooked during the review, but
>> it still doesn't work (it doesn't crash anymore, but I get random
>> illegal VFP instructions in 32bit guests).
>>
>> I'd be glad if someone could eyeball the following patch and tell me
>> what's going wrong. If we don't find the root cause quickly enough, I'll
>> have to drop the series from -next, and that'd be a real shame.
>>
>> Thanks,
>>
>> 	M.
>>
>> commit 5777dc55fbc170426a85e00c26002dd5a795cfa5
>> Author: Marc Zyngier <marc.zyngier at arm.com>
>> Date:   Wed Aug 5 16:53:01 2015 +0100
>>
>>     KVM: arm64: NOTAFIX: Prevent crash when 32bit guest uses VFP
>>
>>     Since we switch FPSIMD in a lazy way, access to FPEXC32_EL2
>>     must be guarded by skip_fpsimd_state. Otherwise, all hell
>>     break loose.
>>
>>     Also, FPEXC32_EL2 must be restored when we trap to EL2 to
>>     enable floating point.
>>
>>     Note that while it prevents the host from catching fire, the
>>     guest still doesn't work properly, and I don't understand why just
>>     yet.
>>
>>     Not-really-signed-off-by: Marc Zyngier <marc.zyngier at arm.com>
>>
>> diff --git a/arch/arm64/kvm/hyp.S b/arch/arm64/kvm/hyp.S
>> index c8e0c70..b53ec5d 100644
>> --- a/arch/arm64/kvm/hyp.S
>> +++ b/arch/arm64/kvm/hyp.S
>> @@ -431,10 +431,12 @@
>>  	add	x3, x2, #CPU_SYSREG_OFFSET(DACR32_EL2)
>>  	mrs	x4, dacr32_el2
>>  	mrs	x5, ifsr32_el2
>> -	mrs	x6, fpexc32_el2
>>  	stp	x4, x5, [x3]
>> -	str	x6, [x3, #16]
>>
>> +	skip_fpsimd_state x8, 3f
>> +	mrs	x6, fpexc32_el2
>> +	str	x6, [x3, #16]
>> +3:
>>  	skip_debug_state x8, 2f
>>  	mrs	x7, dbgvcr32_el2
>>  	str	x7, [x3, #24]
>> @@ -461,10 +463,8 @@
>>
>>  	add	x3, x2, #CPU_SYSREG_OFFSET(DACR32_EL2)
>>  	ldp	x4, x5, [x3]
>> -	ldr	x6, [x3, #16]
>>  	msr	dacr32_el2, x4
>>  	msr	ifsr32_el2, x5
>> -	msr	fpexc32_el2, x6
>>
>>  	skip_debug_state x8, 2f
>>  	ldr	x7, [x3, #24]
>> @@ -669,12 +669,14 @@ __restore_debug:
>>  	ret
>>
>>  __save_fpsimd:
>> +	skip_fpsimd_state x3, 1f
>>  	save_fpsimd
>> -	ret
>> +1:	ret
>>
>>  __restore_fpsimd:
>> +	skip_fpsimd_state x3, 1f
>>  	restore_fpsimd
>> -	ret
>> +1:	ret
>>
>>  switch_to_guest_fpsimd:
>>  	push	x4, lr
>> @@ -682,6 +684,7 @@ switch_to_guest_fpsimd:
>>  	mrs	x2, cptr_el2
>>  	bic	x2, x2, #CPTR_EL2_TFP
>>  	msr	cptr_el2, x2
>> +	isb
> 
> ah, EL2 accesses themselves trap too, ouch.

Yeah, the FP architecture has all kind of nasty tricks like this.

>>
>>  	mrs	x0, tpidr_el2
>>
>> @@ -692,6 +695,10 @@ switch_to_guest_fpsimd:
>>  	add	x2, x0, #VCPU_CONTEXT
>>  	bl __restore_fpsimd
>>
>> +	skip_32bit_state x3, 1f
>> +	ldr	x4, [x2, #CPU_SYSREG_OFFSET(FPEXC32_EL2)]
>> +	msr	fpexc32_el2, x4
>> +1:
> 
> wait, it looks like you're missing a store of the host fpsimd state in
> the switch_to_guest_fpsimd situation.

A store of FPEXC32_EL2 for the host? No, this register has no
significance whatsoever for a 64bit host. Its sole purpose is to
accommodate a 32bit guest (see D7.2.31). Or are you thinking of
something else?

> It think this would be easier to follow if the aarch32 FP registers were
> handled as part of the __save_fpsimd  and __restore_fpsimd routines
> instead.

Maybe. This code needs some rework...

> Does this help anything?

Not really, sorry... :-(

> Otherwise, I assume you've tested thoroughly between something like
> v4.2-rc2 and this patch, so that you're sure we didn't have the 32-bit
> processed crash before?

Without the lazy switching, we seem to be rock solid. With lazy
switching, I get these illegal instructions, always on VFP ops. My
current thinking is that it has something to do with CPACR_EL1, and the
fact that the 32bit kernel turns it VFP on/off all the time.

/me puzzled...

	M.
-- 
Jazz is not dead. It just smells funny...


From gregory.clement at free-electrons.com  Thu Aug  6 06:07:03 2015
From: gregory.clement at free-electrons.com (Gregory CLEMENT)
Date: Thu, 06 Aug 2015 15:07:03 +0200
Subject: [PATCH v2] ARM: dts: Convert Linkstation Mini to Device Tree
In-Reply-To: <CAO10ksyxsZ=Xv4iPn4uSjTC1z9D6dR9hZq6Mk7yuMJhFin9ZhA@mail.gmail.com>
References: <1436885641.7145.9.camel@dolka.fr>	<20150718185238.GH17961@lunn.ch>	<55B396A1.1090509@free-electrons.com>	<1438027893.15635.41.camel@dolka.fr>	<55C23FA8.9030504@free-electrons.com>
 <CAO10ksyxsZ=Xv4iPn4uSjTC1z9D6dR9hZq6Mk7yuMJhFin9ZhA@mail.gmail.com>
Message-ID: <55C35BF7.1090105@free-electrons.com>

Hi Alexey,

On 06/08/2015 02:33, Alexey Kopytko wrote:
> On Thu, Aug 6, 2015 at 1:54 AM, Gregory CLEMENT
> <gregory.clement at free-electrons.com> wrote:
> 
>>>> With the Acked-by from  Andrew Lunn I am ready to apply your patch.
>>>> However for the device tree I need the acked-by from Thomas Petazzoni but I
>>>> am sure he will give it as he already agreed for the armada-*.dts* files.
>>>>
>>>> I am not sure we need the formal acked-by from Alexey because the dts is
>>>> not based on a dts written by him.
>>>
>>> It's just that I took all the devices definition from his .c; to me, it
>>> counts as derived work, but IANAL.
>>
>> For me it is still the decription of the hardware not an derivated work.
>> Andrew what is your opinion on it?
>>
>> But if we consider it as a derivated work then we need Alexey acked-by soon,
>> or going back to GPL only license.
>>
> 
> Since the patch touches files I had a part creating, the patch itself
> is clearly a derivative work. Therefore, without further ado...
> 
> Acked-by: Alexey Kopytko <alexey at kopytko.ru>


Thanks for your acked-by it will allow us to move forward,

Gregory


-- 
Gregory Clement, Free Electrons
Kernel, drivers, real-time and embedded Linux
development, consulting, training and support.
http://free-electrons.com


From xerofoify at gmail.com  Thu Aug  6 06:16:45 2015
From: xerofoify at gmail.com (nick)
Date: Thu, 06 Aug 2015 09:16:45 -0400
Subject: [PATCH] kvm:arm:Fix error handling in the function vgic_v3_probe
In-Reply-To: <55C34C77.7090303@redhat.com>
References: <1438793303-30228-1-git-send-email-xerofoify@gmail.com>
 <55C240D9.5060900@redhat.com> <55C242C6.6060200@gmail.com>
 <55C31582.4000809@arm.com> <55C34C77.7090303@redhat.com>
Message-ID: <55C35E3D.9000708@gmail.com>



On 2015-08-06 08:00 AM, Paolo Bonzini wrote:
> 
> 
> On 06/08/2015 10:06, Marc Zyngier wrote:
>>> If this structure of function pointers can handle function pointers with a return type of 
>>> void I will be glad to do what you request otherwise this would require a major rewrite
>>> of kvm arm subsystem for a very simple bug fix.
>>
>> Just like Paolo said, the error you report should never happen, and
>> would be caught by a WARN_ON() the first time anyone boots the kernel.
>> Also, failing to register the device ops results in not being able to
>> instantiate a VGIC. No harm done. I really don't understand why you want
>> to rewrite the probe functions.
> 
> I think he just misunderstood my suggestion.  I didn't suggest making
> the probe functions return void.  I suggested that
> kvm_register_device_ops return void.
> 
> Paolo
> 
Unfortunately the other maintainer is right in the s390 kvm subsystem uses the return value of the call to 
kvm_register_device_ops. However we could do something like a WARN_ON if kvm_register_device_ops fails in 
callers that never are required to never use it's return value.
Sorry about the Misunderstanding as I misread your suggestion.
Nick


From ralf at linux-mips.org  Thu Aug  6 06:17:36 2015
From: ralf at linux-mips.org (Ralf Baechle)
Date: Thu, 6 Aug 2015 15:17:36 +0200
Subject: [RFC PATCH v4 3/9] mips: pistachio_defconfig: remove
 CONFIG_MMC_DW_IDMAC
In-Reply-To: <1438843515-23935-1-git-send-email-shawn.lin@rock-chips.com>
References: <1438843469-23807-1-git-send-email-shawn.lin@rock-chips.com>
 <1438843515-23935-1-git-send-email-shawn.lin@rock-chips.com>
Message-ID: <20150806131736.GE7055@linux-mips.org>

On Thu, Aug 06, 2015 at 02:45:15PM +0800, Shawn Lin wrote:

>  arch/mips/configs/pistachio_defconfig | 1 -

Acked-by: Ralf Baechle <ralf at linux-mips.org>

  Ralf


From andrew at lunn.ch  Thu Aug  6 06:29:26 2015
From: andrew at lunn.ch (Andrew Lunn)
Date: Thu, 6 Aug 2015 15:29:26 +0200
Subject: Armadaxp GPIO interrupts
In-Reply-To: <CAG1O52WPFfm+XGk01iUVWLu=-Dm7bcDVmhv3P8iQDH+HHjsLUA@mail.gmail.com>
References: <CAG1O52Xg88OsifBzmpSdqvC8wQaOW78nC9nnfxugFv1VU1m1LQ@mail.gmail.com>
 <20150804153439.GA28673@lunn.ch>
 <CAG1O52W2Gy_6_DfewtUqoK_J+Y=KwVGyygNaPu2xyPM_ZkLfcQ@mail.gmail.com>
 <CAG1O52VQPpeGkA8bqYbPMTiT9Mua1yHi3H3osqJsHqm-RRKzow@mail.gmail.com>
 <20150805162155.GE32760@lunn.ch>
 <CAG1O52WPFfm+XGk01iUVWLu=-Dm7bcDVmhv3P8iQDH+HHjsLUA@mail.gmail.com>
Message-ID: <20150806132926.GB19896@lunn.ch>

> mvebu_gpio_irq_handler is only called if I register a another handler
> at irq=82/83/84/85/87/88/89/90/92. I am registering this handler using
> minimal kernel module.

This is totally wrong. The gpio driver needs these interrupts, and
will register a chained interrupt handle for these. Don't mess around
with them. Here is the code in the driver:

        /* Setup the interrupt handlers. Each chip can have up to 4
         * interrupt handlers, with each handler dealing with 8 GPIO
         * pins. */
        for (i = 0; i < 4; i++) {
                int irq = platform_get_irq(pdev, i);

                if (irq < 0)
                        continue;
                irq_set_handler_data(irq, mvchip);
                irq_set_chained_handler(irq, mvebu_gpio_irq_handler);
        }

	Andrew


From b.zolnierkie at samsung.com  Thu Aug  6 06:41:48 2015
From: b.zolnierkie at samsung.com (Bartlomiej Zolnierkiewicz)
Date: Thu, 06 Aug 2015 15:41:48 +0200
Subject: [PATCH v4 0/6] cpufreq: use generic cpufreq drivers for Exynos4x12
 platform
Message-ID: <1438868514-8814-1-git-send-email-b.zolnierkie@samsung.com>

Hi,

This patch series removes the use of Exynos4x12 specific support
from cpufreq-exynos driver and enables the use of cpufreq-dt driver
for this platform.

This patch series has been tested on Exynos4412 based Odroid-U3 and
Trats2 boards.

Depends on:
- next-20150806 branch of linux-next kernel tree
- "[PATCH V3 00/16] OPP: Add code to support operating-points-v2 bindings"
  (http://www.spinics.net/lists/arm-kernel/msg435408.html)

Changes since v3
(http://thread.gmane.org/gmane.linux.power-management.general/63464):
- rebased on top of next-20150806 branch of linux-next kernel tree
- made ARCH_EXYNOS config option select thermal support
- made scaling_boost_freqs sysfs attribute available only when boost
  support is enabled
- added Acked-by tag from Viresh to patches #3, #4 and #5
- added Tested-by tag from Tobias to patches #2-5
- added Reviewed-by tag from Krzysztof to patch #4

Changes since v2
(http://thread.gmane.org/gmane.linux.kernel.samsung-soc/46653):
- rebased on top of next-20150730 branch of linux-next kernel tree
- ported over V3 of opp-v2 bindings support patch series
- put cpu0 nodes in alphabetical order in dts files
- added Reviewed-by tags from Javier and Krzysztof
- added Acked-by tag from Sylwester

Changes since v1
(http://thread.gmane.org/gmane.linux.kernel.samsung-soc/44361):
- rebased on top of next-20150629 branch of linux-next kernel tree
- rebased on top of Exynos5250 cpufreq-dt support patch series
- fixed if-statement in exynos4_clk_init() (noticed by Tobias Jakobi)
- ported over opp-v2 bindings (requested by Viresh Kumar)

Best regards,
--
Bartlomiej Zolnierkiewicz
Samsung R&D Institute Poland
Samsung Electronics


Bartlomiej Zolnierkiewicz (6):
  cpufreq: make scaling_boost_freqs sysfs attr available when boost is
    enabled
  clk: samsung: exynos4x12: add cpu clock configuration data and
    instantiate cpu clock
  ARM: dts: Exynos4x12: add CPU OPP and regulator supply property
  ARM: Exynos: switch to using generic cpufreq driver for Exynos4x12
  cpufreq: exynos: remove Exynos4x12 specific cpufreq driver support
  cpufreq: remove no longer needed CPU_FREQ_BOOST_SW config option

 arch/arm/boot/dts/exynos4212.dtsi               |  81 ++++++++
 arch/arm/boot/dts/exynos4412-odroid-common.dtsi |   4 +
 arch/arm/boot/dts/exynos4412-origen.dts         |   4 +
 arch/arm/boot/dts/exynos4412-trats2.dts         |   4 +
 arch/arm/boot/dts/exynos4412.dtsi               |  83 +++++++++
 arch/arm/mach-exynos/Kconfig                    |   2 +
 arch/arm/mach-exynos/exynos.c                   |   2 +
 drivers/clk/samsung/clk-exynos4.c               |  50 +++++
 drivers/cpufreq/Kconfig                         |   4 -
 drivers/cpufreq/Kconfig.arm                     |  38 ----
 drivers/cpufreq/Makefile                        |   2 -
 drivers/cpufreq/cpufreq-dt.c                    |   3 +
 drivers/cpufreq/exynos-cpufreq.c                | 236 ------------------------
 drivers/cpufreq/exynos-cpufreq.h                |  72 --------
 drivers/cpufreq/exynos4x12-cpufreq.c            | 236 ------------------------
 drivers/cpufreq/freq_table.c                    |  10 +-
 include/linux/cpufreq.h                         |   1 +
 17 files changed, 241 insertions(+), 591 deletions(-)
 delete mode 100644 drivers/cpufreq/exynos-cpufreq.c
 delete mode 100644 drivers/cpufreq/exynos-cpufreq.h
 delete mode 100644 drivers/cpufreq/exynos4x12-cpufreq.c

-- 
1.9.1



From b.zolnierkie at samsung.com  Thu Aug  6 06:41:49 2015
From: b.zolnierkie at samsung.com (Bartlomiej Zolnierkiewicz)
Date: Thu, 06 Aug 2015 15:41:49 +0200
Subject: [PATCH v4 1/6] cpufreq: make scaling_boost_freqs sysfs attr available
 when boost is enabled
In-Reply-To: <1438868514-8814-1-git-send-email-b.zolnierkie@samsung.com>
References: <1438868514-8814-1-git-send-email-b.zolnierkie@samsung.com>
Message-ID: <1438868514-8814-2-git-send-email-b.zolnierkie@samsung.com>

Add cpufreq_boost_enabled_generic_attr table and use it in
cpufreq-dt driver instead of cpufreq_generic_attr one when
boost support is enabled.  As a result scaling_boost_freqs
sysfs attribute is available when cpufreq-dt driver is
used and boost support is enabled.

Cc: Viresh Kumar <viresh.kumar at linaro.org>
Cc: Thomas Abraham <thomas.ab at samsung.com>
Cc: Javier Martinez Canillas <javier at osg.samsung.com>
Cc: Krzysztof Kozlowski <k.kozlowski at samsung.com>
Signed-off-by: Bartlomiej Zolnierkiewicz <b.zolnierkie at samsung.com>
---
 drivers/cpufreq/cpufreq-dt.c | 3 +++
 drivers/cpufreq/freq_table.c | 7 +++++++
 include/linux/cpufreq.h      | 1 +
 3 files changed, 11 insertions(+)

diff --git a/drivers/cpufreq/cpufreq-dt.c b/drivers/cpufreq/cpufreq-dt.c
index b9259ab..7b091c0 100644
--- a/drivers/cpufreq/cpufreq-dt.c
+++ b/drivers/cpufreq/cpufreq-dt.c
@@ -182,6 +182,8 @@ try_again:
 	return ret;
 }
 
+static struct cpufreq_driver dt_cpufreq_driver;
+
 static int cpufreq_init(struct cpufreq_policy *policy)
 {
 	struct cpufreq_frequency_table *freq_table;
@@ -336,6 +338,7 @@ static int cpufreq_init(struct cpufreq_policy *policy)
 		ret = cpufreq_enable_boost_support();
 		if (ret)
 			goto out_free_cpufreq_table;
+		dt_cpufreq_driver.attr = cpufreq_boost_enabled_generic_attr;
 	}
 
 	policy->cpuinfo.transition_latency = transition_latency;
diff --git a/drivers/cpufreq/freq_table.c b/drivers/cpufreq/freq_table.c
index a8f1daf..5a00a09 100644
--- a/drivers/cpufreq/freq_table.c
+++ b/drivers/cpufreq/freq_table.c
@@ -300,6 +300,13 @@ struct freq_attr *cpufreq_generic_attr[] = {
 };
 EXPORT_SYMBOL_GPL(cpufreq_generic_attr);
 
+struct freq_attr *cpufreq_boost_enabled_generic_attr[] = {
+	&cpufreq_freq_attr_scaling_available_freqs,
+	&cpufreq_freq_attr_scaling_boost_freqs,
+	NULL,
+};
+EXPORT_SYMBOL_GPL(cpufreq_boost_enabled_generic_attr);
+
 int cpufreq_table_validate_and_show(struct cpufreq_policy *policy,
 				      struct cpufreq_frequency_table *table)
 {
diff --git a/include/linux/cpufreq.h b/include/linux/cpufreq.h
index 95f0186..25937ff 100644
--- a/include/linux/cpufreq.h
+++ b/include/linux/cpufreq.h
@@ -610,6 +610,7 @@ struct cpufreq_frequency_table *cpufreq_frequency_get_table(unsigned int cpu);
 /* the following are really really optional */
 extern struct freq_attr cpufreq_freq_attr_scaling_available_freqs;
 extern struct freq_attr *cpufreq_generic_attr[];
+extern struct freq_attr *cpufreq_boost_enabled_generic_attr[];
 int cpufreq_table_validate_and_show(struct cpufreq_policy *policy,
 				      struct cpufreq_frequency_table *table);
 
-- 
1.9.1



From b.zolnierkie at samsung.com  Thu Aug  6 06:41:50 2015
From: b.zolnierkie at samsung.com (Bartlomiej Zolnierkiewicz)
Date: Thu, 06 Aug 2015 15:41:50 +0200
Subject: [PATCH v4 2/6] clk: samsung: exynos4x12: add cpu clock configuration
 data and instantiate cpu clock
In-Reply-To: <1438868514-8814-1-git-send-email-b.zolnierkie@samsung.com>
References: <1438868514-8814-1-git-send-email-b.zolnierkie@samsung.com>
Message-ID: <1438868514-8814-3-git-send-email-b.zolnierkie@samsung.com>

With the addition of the new Samsung specific cpu-clock type, the
arm clock can be represented as a cpu-clock type. Add the CPU clock
configuration data and instantiate the CPU clock type for Exynos4x12.

Based on the earlier work by Thomas Abraham.

Cc: Tomasz Figa <tomasz.figa at gmail.com>
Cc: Michael Turquette <mturquette at baylibre.com>
Cc: Thomas Abraham <thomas.ab at samsung.com>
Reviewed-by: Javier Martinez Canillas <javier at osg.samsung.com>
Reviewed-by: Krzysztof Kozlowski <k.kozlowski at samsung.com>
Acked-by: Sylwester Nawrocki <s.nawrocki at samsung.com>
Tested-by: Tobias Jakobi <tjakobi at math.uni-bielefeld.de>
Signed-off-by: Bartlomiej Zolnierkiewicz <b.zolnierkie at samsung.com>
---
 drivers/clk/samsung/clk-exynos4.c | 50 +++++++++++++++++++++++++++++++++++++++
 1 file changed, 50 insertions(+)

diff --git a/drivers/clk/samsung/clk-exynos4.c b/drivers/clk/samsung/clk-exynos4.c
index 251f48d..7f370d3 100644
--- a/drivers/clk/samsung/clk-exynos4.c
+++ b/drivers/clk/samsung/clk-exynos4.c
@@ -1398,6 +1398,45 @@ static const struct exynos_cpuclk_cfg_data e4210_armclk_d[] __initconst = {
 	{  0 },
 };
 
+static const struct exynos_cpuclk_cfg_data e4212_armclk_d[] __initconst = {
+	{ 1500000, E4210_CPU_DIV0(2, 1, 6, 0, 7, 3), E4210_CPU_DIV1(2, 6), },
+	{ 1400000, E4210_CPU_DIV0(2, 1, 6, 0, 7, 3), E4210_CPU_DIV1(2, 6), },
+	{ 1300000, E4210_CPU_DIV0(2, 1, 5, 0, 7, 3), E4210_CPU_DIV1(2, 5), },
+	{ 1200000, E4210_CPU_DIV0(2, 1, 5, 0, 7, 3), E4210_CPU_DIV1(2, 5), },
+	{ 1100000, E4210_CPU_DIV0(2, 1, 4, 0, 6, 3), E4210_CPU_DIV1(2, 4), },
+	{ 1000000, E4210_CPU_DIV0(1, 1, 4, 0, 5, 2), E4210_CPU_DIV1(2, 4), },
+	{  900000, E4210_CPU_DIV0(1, 1, 3, 0, 5, 2), E4210_CPU_DIV1(2, 3), },
+	{  800000, E4210_CPU_DIV0(1, 1, 3, 0, 5, 2), E4210_CPU_DIV1(2, 3), },
+	{  700000, E4210_CPU_DIV0(1, 1, 3, 0, 4, 2), E4210_CPU_DIV1(2, 3), },
+	{  600000, E4210_CPU_DIV0(1, 1, 3, 0, 4, 2), E4210_CPU_DIV1(2, 3), },
+	{  500000, E4210_CPU_DIV0(1, 1, 3, 0, 4, 2), E4210_CPU_DIV1(2, 3), },
+	{  400000, E4210_CPU_DIV0(1, 1, 3, 0, 4, 2), E4210_CPU_DIV1(2, 3), },
+	{  300000, E4210_CPU_DIV0(1, 1, 2, 0, 4, 2), E4210_CPU_DIV1(2, 3), },
+	{  200000, E4210_CPU_DIV0(1, 1, 1, 0, 3, 1), E4210_CPU_DIV1(2, 3), },
+	{  0 },
+};
+
+#define E4412_CPU_DIV1(cores, hpm, copy)				\
+		(((cores) << 8) | ((hpm) << 4) | ((copy) << 0))
+
+static const struct exynos_cpuclk_cfg_data e4412_armclk_d[] __initconst = {
+	{ 1500000, E4210_CPU_DIV0(2, 1, 6, 0, 7, 3), E4412_CPU_DIV1(7, 0, 6), },
+	{ 1400000, E4210_CPU_DIV0(2, 1, 6, 0, 7, 3), E4412_CPU_DIV1(6, 0, 6), },
+	{ 1300000, E4210_CPU_DIV0(2, 1, 5, 0, 7, 3), E4412_CPU_DIV1(6, 0, 5), },
+	{ 1200000, E4210_CPU_DIV0(2, 1, 5, 0, 7, 3), E4412_CPU_DIV1(5, 0, 5), },
+	{ 1100000, E4210_CPU_DIV0(2, 1, 4, 0, 6, 3), E4412_CPU_DIV1(5, 0, 4), },
+	{ 1000000, E4210_CPU_DIV0(1, 1, 4, 0, 5, 2), E4412_CPU_DIV1(4, 0, 4), },
+	{  900000, E4210_CPU_DIV0(1, 1, 3, 0, 5, 2), E4412_CPU_DIV1(4, 0, 3), },
+	{  800000, E4210_CPU_DIV0(1, 1, 3, 0, 5, 2), E4412_CPU_DIV1(3, 0, 3), },
+	{  700000, E4210_CPU_DIV0(1, 1, 3, 0, 4, 2), E4412_CPU_DIV1(3, 0, 3), },
+	{  600000, E4210_CPU_DIV0(1, 1, 3, 0, 4, 2), E4412_CPU_DIV1(2, 0, 3), },
+	{  500000, E4210_CPU_DIV0(1, 1, 3, 0, 4, 2), E4412_CPU_DIV1(2, 0, 3), },
+	{  400000, E4210_CPU_DIV0(1, 1, 3, 0, 4, 2), E4412_CPU_DIV1(1, 0, 3), },
+	{  300000, E4210_CPU_DIV0(1, 1, 2, 0, 4, 2), E4412_CPU_DIV1(1, 0, 3), },
+	{  200000, E4210_CPU_DIV0(1, 1, 1, 0, 3, 1), E4412_CPU_DIV1(0, 0, 3), },
+	{  0 },
+};
+
 /* register exynos4 clocks */
 static void __init exynos4_clk_init(struct device_node *np,
 				    enum exynos4_soc soc)
@@ -1491,6 +1530,17 @@ static void __init exynos4_clk_init(struct device_node *np,
 		samsung_clk_register_fixed_factor(ctx,
 			exynos4x12_fixed_factor_clks,
 			ARRAY_SIZE(exynos4x12_fixed_factor_clks));
+		if (of_machine_is_compatible("samsung,exynos4412")) {
+			exynos_register_cpu_clock(ctx, CLK_ARM_CLK, "armclk",
+				mout_core_p4x12[0], mout_core_p4x12[1], 0x14200,
+				e4412_armclk_d, ARRAY_SIZE(e4412_armclk_d),
+				CLK_CPU_NEEDS_DEBUG_ALT_DIV | CLK_CPU_HAS_DIV1);
+		} else {
+			exynos_register_cpu_clock(ctx, CLK_ARM_CLK, "armclk",
+				mout_core_p4x12[0], mout_core_p4x12[1], 0x14200,
+				e4212_armclk_d, ARRAY_SIZE(e4212_armclk_d),
+				CLK_CPU_NEEDS_DEBUG_ALT_DIV | CLK_CPU_HAS_DIV1);
+		}
 	}
 
 	samsung_clk_register_alias(ctx, exynos4_aliases,
-- 
1.9.1



From b.zolnierkie at samsung.com  Thu Aug  6 06:41:51 2015
From: b.zolnierkie at samsung.com (Bartlomiej Zolnierkiewicz)
Date: Thu, 06 Aug 2015 15:41:51 +0200
Subject: [PATCH v4 3/6] ARM: dts: Exynos4x12: add CPU OPP and regulator supply
 property
In-Reply-To: <1438868514-8814-1-git-send-email-b.zolnierkie@samsung.com>
References: <1438868514-8814-1-git-send-email-b.zolnierkie@samsung.com>
Message-ID: <1438868514-8814-4-git-send-email-b.zolnierkie@samsung.com>

For Exynos4x12 platforms, add CPU operating points (using
opp-v2 bindings) and CPU regulator supply properties for
migrating from Exynos specific cpufreq driver to using
generic cpufreq driver.

Based on the earlier work by Thomas Abraham.

Cc: Kukjin Kim <kgene.kim at samsung.com>
Cc: Doug Anderson <dianders at chromium.org>
Cc: Andreas Faerber <afaerber at suse.de>
Cc: Thomas Abraham <thomas.ab at samsung.com>
Reviewed-by: Javier Martinez Canillas <javier at osg.samsung.com>
Reviewed-by: Krzysztof Kozlowski <k.kozlowski at samsung.com>
Acked-by: Viresh Kumar <viresh.kumar at linaro.org>
Tested-by: Tobias Jakobi <tjakobi at math.uni-bielefeld.de>
Signed-off-by: Bartlomiej Zolnierkiewicz <b.zolnierkie at samsung.com>
---
 arch/arm/boot/dts/exynos4212.dtsi               | 81 ++++++++++++++++++++++++
 arch/arm/boot/dts/exynos4412-odroid-common.dtsi |  4 ++
 arch/arm/boot/dts/exynos4412-origen.dts         |  4 ++
 arch/arm/boot/dts/exynos4412-trats2.dts         |  4 ++
 arch/arm/boot/dts/exynos4412.dtsi               | 83 +++++++++++++++++++++++++
 5 files changed, 176 insertions(+)

diff --git a/arch/arm/boot/dts/exynos4212.dtsi b/arch/arm/boot/dts/exynos4212.dtsi
index d9c8efee..5389011 100644
--- a/arch/arm/boot/dts/exynos4212.dtsi
+++ b/arch/arm/boot/dts/exynos4212.dtsi
@@ -30,6 +30,9 @@
 			device_type = "cpu";
 			compatible = "arm,cortex-a9";
 			reg = <0xA00>;
+			clocks = <&clock CLK_ARM_CLK>;
+			clock-names = "cpu";
+			operating-points-v2 = <&cpu0_opp_table>;
 			cooling-min-level = <13>;
 			cooling-max-level = <7>;
 			#cooling-cells = <2>; /* min followed by max */
@@ -39,6 +42,84 @@
 			device_type = "cpu";
 			compatible = "arm,cortex-a9";
 			reg = <0xA01>;
+			operating-points-v2 = <&cpu0_opp_table>;
+		};
+	};
+
+	cpu0_opp_table: opp_table0 {
+		compatible = "operating-points-v2";
+		opp-shared;
+
+		opp00 {
+			opp-hz = /bits/ 64 <200000000>;
+			opp-microvolt = <900000>;
+			clock-latency-ns = <200000>;
+		};
+		opp01 {
+			opp-hz = /bits/ 64 <300000000>;
+			opp-microvolt = <900000>;
+			clock-latency-ns = <200000>;
+		};
+		opp02 {
+			opp-hz = /bits/ 64 <400000000>;
+			opp-microvolt = <925000>;
+			clock-latency-ns = <200000>;
+		};
+		opp03 {
+			opp-hz = /bits/ 64 <500000000>;
+			opp-microvolt = <950000>;
+			clock-latency-ns = <200000>;
+		};
+		opp04 {
+			opp-hz = /bits/ 64 <600000000>;
+			opp-microvolt = <975000>;
+			clock-latency-ns = <200000>;
+		};
+		opp05 {
+			opp-hz = /bits/ 64 <700000000>;
+			opp-microvolt = <987500>;
+			clock-latency-ns = <200000>;
+		};
+		opp06 {
+			opp-hz = /bits/ 64 <800000000>;
+			opp-microvolt = <1000000>;
+			clock-latency-ns = <200000>;
+		};
+		opp07 {
+			opp-hz = /bits/ 64 <900000000>;
+			opp-microvolt = <1037500>;
+			clock-latency-ns = <200000>;
+		};
+		opp08 {
+			opp-hz = /bits/ 64 <1000000000>;
+			opp-microvolt = <1087500>;
+			clock-latency-ns = <200000>;
+		};
+		opp09 {
+			opp-hz = /bits/ 64 <1100000000>;
+			opp-microvolt = <1137500>;
+			clock-latency-ns = <200000>;
+		};
+		opp10 {
+			opp-hz = /bits/ 64 <1200000000>;
+			opp-microvolt = <1187500>;
+			clock-latency-ns = <200000>;
+		};
+		opp11 {
+			opp-hz = /bits/ 64 <1300000000>;
+			opp-microvolt = <1250000>;
+			clock-latency-ns = <200000>;
+		};
+		opp12 {
+			opp-hz = /bits/ 64 <1400000000>;
+			opp-microvolt = <1287500>;
+			clock-latency-ns = <200000>;
+		};
+		opp13 {
+			opp-hz = /bits/ 64 <1500000000>;
+			opp-microvolt = <1350000>;
+			clock-latency-ns = <200000>;
+			turbo-mode;
 		};
 	};
 };
diff --git a/arch/arm/boot/dts/exynos4412-odroid-common.dtsi b/arch/arm/boot/dts/exynos4412-odroid-common.dtsi
index ca7d168..db52841 100644
--- a/arch/arm/boot/dts/exynos4412-odroid-common.dtsi
+++ b/arch/arm/boot/dts/exynos4412-odroid-common.dtsi
@@ -107,6 +107,10 @@
 	};
 };
 
+&cpu0 {
+	cpu0-supply = <&buck2_reg>;
+};
+
 /* RSTN signal for eMMC */
 &sd1_cd {
 	samsung,pin-pud = <0>;
diff --git a/arch/arm/boot/dts/exynos4412-origen.dts b/arch/arm/boot/dts/exynos4412-origen.dts
index 84c7631..9d528af 100644
--- a/arch/arm/boot/dts/exynos4412-origen.dts
+++ b/arch/arm/boot/dts/exynos4412-origen.dts
@@ -78,6 +78,10 @@
 	};
 };
 
+&cpu0 {
+	cpu0-supply = <&buck2_reg>;
+};
+
 &fimd {
 	pinctrl-0 = <&lcd_clk &lcd_data24 &pwm1_out>;
 	pinctrl-names = "default";
diff --git a/arch/arm/boot/dts/exynos4412-trats2.dts b/arch/arm/boot/dts/exynos4412-trats2.dts
index 8848400..2a1ebb7 100644
--- a/arch/arm/boot/dts/exynos4412-trats2.dts
+++ b/arch/arm/boot/dts/exynos4412-trats2.dts
@@ -288,6 +288,10 @@
 	status = "okay";
 };
 
+&cpu0 {
+	cpu0-supply = <&buck2_reg>;
+};
+
 &csis_0 {
 	status = "okay";
 	vddcore-supply = <&ldo8_reg>;
diff --git a/arch/arm/boot/dts/exynos4412.dtsi b/arch/arm/boot/dts/exynos4412.dtsi
index b78ada7..ca0e3c1 100644
--- a/arch/arm/boot/dts/exynos4412.dtsi
+++ b/arch/arm/boot/dts/exynos4412.dtsi
@@ -30,6 +30,9 @@
 			device_type = "cpu";
 			compatible = "arm,cortex-a9";
 			reg = <0xA00>;
+			clocks = <&clock CLK_ARM_CLK>;
+			clock-names = "cpu";
+			operating-points-v2 = <&cpu0_opp_table>;
 			cooling-min-level = <13>;
 			cooling-max-level = <7>;
 			#cooling-cells = <2>; /* min followed by max */
@@ -39,18 +42,98 @@
 			device_type = "cpu";
 			compatible = "arm,cortex-a9";
 			reg = <0xA01>;
+			operating-points-v2 = <&cpu0_opp_table>;
 		};
 
 		cpu at A02 {
 			device_type = "cpu";
 			compatible = "arm,cortex-a9";
 			reg = <0xA02>;
+			operating-points-v2 = <&cpu0_opp_table>;
 		};
 
 		cpu at A03 {
 			device_type = "cpu";
 			compatible = "arm,cortex-a9";
 			reg = <0xA03>;
+			operating-points-v2 = <&cpu0_opp_table>;
+		};
+	};
+
+	cpu0_opp_table: opp_table0 {
+		compatible = "operating-points-v2";
+		opp-shared;
+
+		opp00 {
+			opp-hz = /bits/ 64 <200000000>;
+			opp-microvolt = <900000>;
+			clock-latency-ns = <200000>;
+		};
+		opp01 {
+			opp-hz = /bits/ 64 <300000000>;
+			opp-microvolt = <900000>;
+			clock-latency-ns = <200000>;
+		};
+		opp02 {
+			opp-hz = /bits/ 64 <400000000>;
+			opp-microvolt = <925000>;
+			clock-latency-ns = <200000>;
+		};
+		opp03 {
+			opp-hz = /bits/ 64 <500000000>;
+			opp-microvolt = <950000>;
+			clock-latency-ns = <200000>;
+		};
+		opp04 {
+			opp-hz = /bits/ 64 <600000000>;
+			opp-microvolt = <975000>;
+			clock-latency-ns = <200000>;
+		};
+		opp05 {
+			opp-hz = /bits/ 64 <700000000>;
+			opp-microvolt = <987500>;
+			clock-latency-ns = <200000>;
+		};
+		opp06 {
+			opp-hz = /bits/ 64 <800000000>;
+			opp-microvolt = <1000000>;
+			clock-latency-ns = <200000>;
+		};
+		opp07 {
+			opp-hz = /bits/ 64 <900000000>;
+			opp-microvolt = <1037500>;
+			clock-latency-ns = <200000>;
+		};
+		opp08 {
+			opp-hz = /bits/ 64 <1000000000>;
+			opp-microvolt = <1087500>;
+			clock-latency-ns = <200000>;
+		};
+		opp09 {
+			opp-hz = /bits/ 64 <1100000000>;
+			opp-microvolt = <1137500>;
+			clock-latency-ns = <200000>;
+		};
+		opp10 {
+			opp-hz = /bits/ 64 <1200000000>;
+			opp-microvolt = <1187500>;
+			clock-latency-ns = <200000>;
+		};
+		opp11 {
+			opp-hz = /bits/ 64 <1300000000>;
+			opp-microvolt = <1250000>;
+			clock-latency-ns = <200000>;
+		};
+		opp12 {
+			opp-hz = /bits/ 64 <1400000000>;
+			opp-microvolt = <1287500>;
+			clock-latency-ns = <200000>;
+		};
+		opp13 {
+			opp-hz = /bits/ 64 <1500000000>;
+			opp-microvolt = <1350000>;
+			clock-latency-ns = <200000>;
+			turbo-mode;
 		};
 	};
 
-- 
1.9.1



From b.zolnierkie at samsung.com  Thu Aug  6 06:41:52 2015
From: b.zolnierkie at samsung.com (Bartlomiej Zolnierkiewicz)
Date: Thu, 06 Aug 2015 15:41:52 +0200
Subject: [PATCH v4 4/6] ARM: Exynos: switch to using generic cpufreq driver for
 Exynos4x12
In-Reply-To: <1438868514-8814-1-git-send-email-b.zolnierkie@samsung.com>
References: <1438868514-8814-1-git-send-email-b.zolnierkie@samsung.com>
Message-ID: <1438868514-8814-5-git-send-email-b.zolnierkie@samsung.com>

The new CPU clock type allows the use of generic CPUfreq driver.
Switch Exynos4x12 to using generic cpufreq driver.

Previously (when exynos-cpufreq driver was used with boost
functionality) ARM_EXYNOS_CPU_FREQ_BOOST_SW config option
(which enabled boost functionality) selected EXYNOS_THERMAL
one.  After switching Exynos4x12 platforms to use cpufreq-dt
driver boost support is enabled in the cpufreq-dt driver
itself (because there are turbo OPPs defined in the board's
DTS file).  However we still would like to allow enabling
boost support only if thermal support is also enabled for
Exynos platforms.  To achieve this make ARCH_EXYNOS config
option select THERMAL and EXYNOS_THERMAL ones.

Please also note that the switch to use the generic cpufreq-dt
driver fixes the minor issue present with the old code (support
for 'boost' mode in the exynos-cpufreq driver was enabled for
all supported SoCs even though 'boost' frequency was provided
only for Exynos4x12 ones).

Cc: Tomasz Figa <tomasz.figa at gmail.com>
Cc: Kukjin Kim <kgene.kim at samsung.com>
Cc: Thomas Abraham <thomas.ab at samsung.com>
Cc: Javier Martinez Canillas <javier at osg.samsung.com>
Reviewed-by: Krzysztof Kozlowski <k.kozlowski at samsung.com>
Acked-by: Viresh Kumar <viresh.kumar at linaro.org>
Tested-by: Tobias Jakobi <tjakobi at math.uni-bielefeld.de>
Signed-off-by: Bartlomiej Zolnierkiewicz <b.zolnierkie at samsung.com>
---
 arch/arm/mach-exynos/Kconfig  | 2 ++
 arch/arm/mach-exynos/exynos.c | 2 ++
 2 files changed, 4 insertions(+)

diff --git a/arch/arm/mach-exynos/Kconfig b/arch/arm/mach-exynos/Kconfig
index 4c4858c..143e332 100644
--- a/arch/arm/mach-exynos/Kconfig
+++ b/arch/arm/mach-exynos/Kconfig
@@ -25,6 +25,8 @@ menuconfig ARCH_EXYNOS
 	select S5P_DEV_MFC
 	select SRAM
 	select MFD_SYSCON
+	select THERMAL
+	select EXYNOS_THERMAL
 	help
 	  Support for SAMSUNG EXYNOS SoCs (EXYNOS4/5)
 
diff --git a/arch/arm/mach-exynos/exynos.c b/arch/arm/mach-exynos/exynos.c
index 77ac021..1c47aee 100644
--- a/arch/arm/mach-exynos/exynos.c
+++ b/arch/arm/mach-exynos/exynos.c
@@ -227,6 +227,8 @@ static void __init exynos_init_irq(void)
 static const struct of_device_id exynos_cpufreq_matches[] = {
 	{ .compatible = "samsung,exynos3250", .data = "cpufreq-dt" },
 	{ .compatible = "samsung,exynos4210", .data = "cpufreq-dt" },
+	{ .compatible = "samsung,exynos4212", .data = "cpufreq-dt" },
+	{ .compatible = "samsung,exynos4412", .data = "cpufreq-dt" },
 	{ .compatible = "samsung,exynos5250", .data = "cpufreq-dt" },
 	{ /* sentinel */ }
 };
-- 
1.9.1



From b.zolnierkie at samsung.com  Thu Aug  6 06:41:53 2015
From: b.zolnierkie at samsung.com (Bartlomiej Zolnierkiewicz)
Date: Thu, 06 Aug 2015 15:41:53 +0200
Subject: [PATCH v4 5/6] cpufreq: exynos: remove Exynos4x12 specific cpufreq
 driver support
In-Reply-To: <1438868514-8814-1-git-send-email-b.zolnierkie@samsung.com>
References: <1438868514-8814-1-git-send-email-b.zolnierkie@samsung.com>
Message-ID: <1438868514-8814-6-git-send-email-b.zolnierkie@samsung.com>

Exynos4x12 based platforms have switched over to use generic
cpufreq driver for cpufreq functionality.  So the Exynos
specific cpufreq support for these platforms can be removed.

Also once Exynos4x12 based platforms support have been removed
the shared exynos-cpufreq driver is no longer needed and can
be deleted.

Based on the earlier work by Thomas Abraham.

Cc: Viresh Kumar <viresh.kumar at linaro.org>
Cc: Thomas Abraham <thomas.ab at samsung.com>
Reviewed-by: Javier Martinez Canillas <javier at osg.samsung.com>
Reviewed-by: Krzysztof Kozlowski <k.kozlowski at samsung.com>
Acked-by: Viresh Kumar <viresh.kumar at linaro.org>
Tested-by: Tobias Jakobi <tjakobi at math.uni-bielefeld.de>
Signed-off-by: Bartlomiej Zolnierkiewicz <b.zolnierkie at samsung.com>
---
 drivers/cpufreq/Kconfig.arm          |  38 ------
 drivers/cpufreq/Makefile             |   2 -
 drivers/cpufreq/exynos-cpufreq.c     | 236 -----------------------------------
 drivers/cpufreq/exynos-cpufreq.h     |  72 -----------
 drivers/cpufreq/exynos4x12-cpufreq.c | 236 -----------------------------------
 5 files changed, 584 deletions(-)
 delete mode 100644 drivers/cpufreq/exynos-cpufreq.c
 delete mode 100644 drivers/cpufreq/exynos-cpufreq.h
 delete mode 100644 drivers/cpufreq/exynos4x12-cpufreq.c

diff --git a/drivers/cpufreq/Kconfig.arm b/drivers/cpufreq/Kconfig.arm
index 9ab6388c1..8a24bd8 100644
--- a/drivers/cpufreq/Kconfig.arm
+++ b/drivers/cpufreq/Kconfig.arm
@@ -24,44 +24,6 @@ config ARM_VEXPRESS_SPC_CPUFREQ
           This add the CPUfreq driver support for Versatile Express
 	  big.LITTLE platforms using SPC for power management.
 
-
-config ARM_EXYNOS_CPUFREQ
-	tristate "SAMSUNG EXYNOS CPUfreq Driver"
-	depends on CPU_EXYNOS4210 || SOC_EXYNOS4212 || SOC_EXYNOS4412 || SOC_EXYNOS5250
-	depends on THERMAL
-	help
-	  This adds the CPUFreq driver for Samsung EXYNOS platforms.
-	  Supported SoC versions are:
-	     Exynos4210, Exynos4212, Exynos4412, and Exynos5250.
-
-	  If in doubt, say N.
-
-config ARM_EXYNOS4X12_CPUFREQ
-	bool "SAMSUNG EXYNOS4x12"
-	depends on SOC_EXYNOS4212 || SOC_EXYNOS4412
-	depends on ARM_EXYNOS_CPUFREQ
-	default y
-	help
-	  This adds the CPUFreq driver for Samsung EXYNOS4X12
-	  SoC (EXYNOS4212 or EXYNOS4412).
-
-	  If in doubt, say N.
-
-config ARM_EXYNOS_CPU_FREQ_BOOST_SW
-	bool "EXYNOS Frequency Overclocking - Software"
-	depends on ARM_EXYNOS_CPUFREQ && THERMAL
-	select CPU_FREQ_BOOST_SW
-	select EXYNOS_THERMAL
-	help
-	  This driver supports software managed overclocking (BOOST).
-	  It allows usage of special frequencies for Samsung Exynos
-	  processors if thermal conditions are appropriate.
-
-	  It requires, for safe operation, thermal framework with properly
-	  defined trip points.
-
-	  If in doubt, say N.
-
 config ARM_EXYNOS5440_CPUFREQ
 	tristate "SAMSUNG EXYNOS5440"
 	depends on SOC_EXYNOS5440
diff --git a/drivers/cpufreq/Makefile b/drivers/cpufreq/Makefile
index 6414958..bbc4a9f 100644
--- a/drivers/cpufreq/Makefile
+++ b/drivers/cpufreq/Makefile
@@ -53,8 +53,6 @@ obj-$(CONFIG_ARM_DT_BL_CPUFREQ)		+= arm_big_little_dt.o
 obj-$(CONFIG_ARCH_DAVINCI)		+= davinci-cpufreq.o
 obj-$(CONFIG_UX500_SOC_DB8500)		+= dbx500-cpufreq.o
 obj-$(CONFIG_ARM_EXYNOS_CPUFREQ)	+= arm-exynos-cpufreq.o
-arm-exynos-cpufreq-y					:= exynos-cpufreq.o
-arm-exynos-cpufreq-$(CONFIG_ARM_EXYNOS4X12_CPUFREQ)	+= exynos4x12-cpufreq.o
 obj-$(CONFIG_ARM_EXYNOS5440_CPUFREQ)	+= exynos5440-cpufreq.o
 obj-$(CONFIG_ARM_HIGHBANK_CPUFREQ)	+= highbank-cpufreq.o
 obj-$(CONFIG_ARM_HISI_ACPU_CPUFREQ)	+= hisi-acpu-cpufreq.o
diff --git a/drivers/cpufreq/exynos-cpufreq.c b/drivers/cpufreq/exynos-cpufreq.c
deleted file mode 100644
index 567a6ab..0000000
--- a/drivers/cpufreq/exynos-cpufreq.c
+++ /dev/null
@@ -1,236 +0,0 @@
-/*
- * Copyright (c) 2010-2011 Samsung Electronics Co., Ltd.
- *		http://www.samsung.com
- *
- * EXYNOS - CPU frequency scaling support for EXYNOS series
- *
- * This program is free software; you can redistribute it and/or modify
- * it under the terms of the GNU General Public License version 2 as
- * published by the Free Software Foundation.
-*/
-
-#include <linux/kernel.h>
-#include <linux/module.h>
-#include <linux/err.h>
-#include <linux/clk.h>
-#include <linux/io.h>
-#include <linux/slab.h>
-#include <linux/regulator/consumer.h>
-#include <linux/cpufreq.h>
-#include <linux/platform_device.h>
-#include <linux/of.h>
-#include <linux/cpu_cooling.h>
-#include <linux/cpu.h>
-
-#include "exynos-cpufreq.h"
-
-static struct exynos_dvfs_info *exynos_info;
-static struct thermal_cooling_device *cdev;
-static struct regulator *arm_regulator;
-static unsigned int locking_frequency;
-
-static int exynos_cpufreq_get_index(unsigned int freq)
-{
-	struct cpufreq_frequency_table *freq_table = exynos_info->freq_table;
-	struct cpufreq_frequency_table *pos;
-
-	cpufreq_for_each_entry(pos, freq_table)
-		if (pos->frequency == freq)
-			break;
-
-	if (pos->frequency == CPUFREQ_TABLE_END)
-		return -EINVAL;
-
-	return pos - freq_table;
-}
-
-static int exynos_cpufreq_scale(unsigned int target_freq)
-{
-	struct cpufreq_frequency_table *freq_table = exynos_info->freq_table;
-	unsigned int *volt_table = exynos_info->volt_table;
-	struct cpufreq_policy *policy = cpufreq_cpu_get(0);
-	unsigned int arm_volt, safe_arm_volt = 0;
-	unsigned int mpll_freq_khz = exynos_info->mpll_freq_khz;
-	struct device *dev = exynos_info->dev;
-	unsigned int old_freq;
-	int index, old_index;
-	int ret = 0;
-
-	old_freq = policy->cur;
-
-	/*
-	 * The policy max have been changed so that we cannot get proper
-	 * old_index with cpufreq_frequency_table_target(). Thus, ignore
-	 * policy and get the index from the raw frequency table.
-	 */
-	old_index = exynos_cpufreq_get_index(old_freq);
-	if (old_index < 0) {
-		ret = old_index;
-		goto out;
-	}
-
-	index = exynos_cpufreq_get_index(target_freq);
-	if (index < 0) {
-		ret = index;
-		goto out;
-	}
-
-	/*
-	 * ARM clock source will be changed APLL to MPLL temporary
-	 * To support this level, need to control regulator for
-	 * required voltage level
-	 */
-	if (exynos_info->need_apll_change != NULL) {
-		if (exynos_info->need_apll_change(old_index, index) &&
-		   (freq_table[index].frequency < mpll_freq_khz) &&
-		   (freq_table[old_index].frequency < mpll_freq_khz))
-			safe_arm_volt = volt_table[exynos_info->pll_safe_idx];
-	}
-	arm_volt = volt_table[index];
-
-	/* When the new frequency is higher than current frequency */
-	if ((target_freq > old_freq) && !safe_arm_volt) {
-		/* Firstly, voltage up to increase frequency */
-		ret = regulator_set_voltage(arm_regulator, arm_volt, arm_volt);
-		if (ret) {
-			dev_err(dev, "failed to set cpu voltage to %d\n",
-				arm_volt);
-			return ret;
-		}
-	}
-
-	if (safe_arm_volt) {
-		ret = regulator_set_voltage(arm_regulator, safe_arm_volt,
-				      safe_arm_volt);
-		if (ret) {
-			dev_err(dev, "failed to set cpu voltage to %d\n",
-				safe_arm_volt);
-			return ret;
-		}
-	}
-
-	exynos_info->set_freq(old_index, index);
-
-	/* When the new frequency is lower than current frequency */
-	if ((target_freq < old_freq) ||
-	   ((target_freq > old_freq) && safe_arm_volt)) {
-		/* down the voltage after frequency change */
-		ret = regulator_set_voltage(arm_regulator, arm_volt,
-				arm_volt);
-		if (ret) {
-			dev_err(dev, "failed to set cpu voltage to %d\n",
-				arm_volt);
-			goto out;
-		}
-	}
-
-out:
-	cpufreq_cpu_put(policy);
-
-	return ret;
-}
-
-static int exynos_target(struct cpufreq_policy *policy, unsigned int index)
-{
-	return exynos_cpufreq_scale(exynos_info->freq_table[index].frequency);
-}
-
-static int exynos_cpufreq_cpu_init(struct cpufreq_policy *policy)
-{
-	policy->clk = exynos_info->cpu_clk;
-	policy->suspend_freq = locking_frequency;
-	return cpufreq_generic_init(policy, exynos_info->freq_table, 100000);
-}
-
-static struct cpufreq_driver exynos_driver = {
-	.flags		= CPUFREQ_STICKY | CPUFREQ_NEED_INITIAL_FREQ_CHECK,
-	.verify		= cpufreq_generic_frequency_table_verify,
-	.target_index	= exynos_target,
-	.get		= cpufreq_generic_get,
-	.init		= exynos_cpufreq_cpu_init,
-	.name		= "exynos_cpufreq",
-	.attr		= cpufreq_generic_attr,
-#ifdef CONFIG_ARM_EXYNOS_CPU_FREQ_BOOST_SW
-	.boost_supported = true,
-#endif
-#ifdef CONFIG_PM
-	.suspend	= cpufreq_generic_suspend,
-#endif
-};
-
-static int exynos_cpufreq_probe(struct platform_device *pdev)
-{
-	struct device_node *cpu0;
-	int ret = -EINVAL;
-
-	exynos_info = kzalloc(sizeof(*exynos_info), GFP_KERNEL);
-	if (!exynos_info)
-		return -ENOMEM;
-
-	exynos_info->dev = &pdev->dev;
-
-	if (of_machine_is_compatible("samsung,exynos4212")) {
-		exynos_info->type = EXYNOS_SOC_4212;
-		ret = exynos4x12_cpufreq_init(exynos_info);
-	} else if (of_machine_is_compatible("samsung,exynos4412")) {
-		exynos_info->type = EXYNOS_SOC_4412;
-		ret = exynos4x12_cpufreq_init(exynos_info);
-	} else {
-		pr_err("%s: Unknown SoC type\n", __func__);
-		ret = -ENODEV;
-	}
-
-	if (ret)
-		goto err_vdd_arm;
-
-	if (exynos_info->set_freq == NULL) {
-		dev_err(&pdev->dev, "No set_freq function (ERR)\n");
-		ret = -EINVAL;
-		goto err_vdd_arm;
-	}
-
-	arm_regulator = regulator_get(NULL, "vdd_arm");
-	if (IS_ERR(arm_regulator)) {
-		dev_err(&pdev->dev, "failed to get resource vdd_arm\n");
-		ret = -EINVAL;
-		goto err_vdd_arm;
-	}
-
-	/* Done here as we want to capture boot frequency */
-	locking_frequency = clk_get_rate(exynos_info->cpu_clk) / 1000;
-
-	ret = cpufreq_register_driver(&exynos_driver);
-	if (ret)
-		goto err_cpufreq_reg;
-
-	cpu0 = of_get_cpu_node(0, NULL);
-	if (!cpu0) {
-		pr_err("failed to find cpu0 node\n");
-		return 0;
-	}
-
-	if (of_find_property(cpu0, "#cooling-cells", NULL)) {
-		cdev = of_cpufreq_cooling_register(cpu0,
-						   cpu_present_mask);
-		if (IS_ERR(cdev))
-			pr_err("running cpufreq without cooling device: %ld\n",
-			       PTR_ERR(cdev));
-	}
-
-	return 0;
-
-err_cpufreq_reg:
-	dev_err(&pdev->dev, "failed to register cpufreq driver\n");
-	regulator_put(arm_regulator);
-err_vdd_arm:
-	kfree(exynos_info);
-	return ret;
-}
-
-static struct platform_driver exynos_cpufreq_platdrv = {
-	.driver = {
-		.name	= "exynos-cpufreq",
-	},
-	.probe = exynos_cpufreq_probe,
-};
-module_platform_driver(exynos_cpufreq_platdrv);
diff --git a/drivers/cpufreq/exynos-cpufreq.h b/drivers/cpufreq/exynos-cpufreq.h
deleted file mode 100644
index a359db7..0000000
--- a/drivers/cpufreq/exynos-cpufreq.h
+++ /dev/null
@@ -1,72 +0,0 @@
-/*
- * Copyright (c) 2010 Samsung Electronics Co., Ltd.
- *		http://www.samsung.com
- *
- * EXYNOS - CPUFreq support
- *
- * 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.
-*/
-
-enum cpufreq_level_index {
-	L0, L1, L2, L3, L4,
-	L5, L6, L7, L8, L9,
-	L10, L11, L12, L13, L14,
-	L15, L16, L17, L18, L19,
-	L20,
-};
-
-enum exynos_soc_type {
-	EXYNOS_SOC_4212,
-	EXYNOS_SOC_4412,
-};
-
-#define APLL_FREQ(f, a0, a1, a2, a3, a4, a5, a6, a7, b0, b1, b2, m, p, s) \
-	{ \
-		.freq = (f) * 1000, \
-		.clk_div_cpu0 = ((a0) | (a1) << 4 | (a2) << 8 | (a3) << 12 | \
-			(a4) << 16 | (a5) << 20 | (a6) << 24 | (a7) << 28), \
-		.clk_div_cpu1 = (b0 << 0 | b1 << 4 | b2 << 8), \
-		.mps = ((m) << 16 | (p) << 8 | (s)), \
-	}
-
-struct apll_freq {
-	unsigned int freq;
-	u32 clk_div_cpu0;
-	u32 clk_div_cpu1;
-	u32 mps;
-};
-
-struct exynos_dvfs_info {
-	enum exynos_soc_type type;
-	struct device	*dev;
-	unsigned long	mpll_freq_khz;
-	unsigned int	pll_safe_idx;
-	struct clk	*cpu_clk;
-	unsigned int	*volt_table;
-	struct cpufreq_frequency_table	*freq_table;
-	void (*set_freq)(unsigned int, unsigned int);
-	bool (*need_apll_change)(unsigned int, unsigned int);
-	void __iomem	*cmu_regs;
-};
-
-#ifdef CONFIG_ARM_EXYNOS4X12_CPUFREQ
-extern int exynos4x12_cpufreq_init(struct exynos_dvfs_info *);
-#else
-static inline int exynos4x12_cpufreq_init(struct exynos_dvfs_info *info)
-{
-	return -EOPNOTSUPP;
-}
-#endif
-
-#define EXYNOS4_CLKSRC_CPU			0x14200
-#define EXYNOS4_CLKMUX_STATCPU			0x14400
-
-#define EXYNOS4_CLKDIV_CPU			0x14500
-#define EXYNOS4_CLKDIV_CPU1			0x14504
-#define EXYNOS4_CLKDIV_STATCPU			0x14600
-#define EXYNOS4_CLKDIV_STATCPU1			0x14604
-
-#define EXYNOS4_CLKSRC_CPU_MUXCORE_SHIFT	(16)
-#define EXYNOS4_CLKMUX_STATCPU_MUXCORE_MASK	(0x7 << EXYNOS4_CLKSRC_CPU_MUXCORE_SHIFT)
diff --git a/drivers/cpufreq/exynos4x12-cpufreq.c b/drivers/cpufreq/exynos4x12-cpufreq.c
deleted file mode 100644
index 9e78a85..0000000
--- a/drivers/cpufreq/exynos4x12-cpufreq.c
+++ /dev/null
@@ -1,236 +0,0 @@
-/*
- * Copyright (c) 2010-2012 Samsung Electronics Co., Ltd.
- *		http://www.samsung.com
- *
- * EXYNOS4X12 - CPU frequency scaling support
- *
- * This program is free software; you can redistribute it and/or modify
- * it under the terms of the GNU General Public License version 2 as
- * published by the Free Software Foundation.
-*/
-
-#include <linux/module.h>
-#include <linux/kernel.h>
-#include <linux/err.h>
-#include <linux/clk.h>
-#include <linux/io.h>
-#include <linux/slab.h>
-#include <linux/cpufreq.h>
-#include <linux/of.h>
-#include <linux/of_address.h>
-
-#include "exynos-cpufreq.h"
-
-static struct clk *cpu_clk;
-static struct clk *moutcore;
-static struct clk *mout_mpll;
-static struct clk *mout_apll;
-static struct exynos_dvfs_info *cpufreq;
-
-static unsigned int exynos4x12_volt_table[] = {
-	1350000, 1287500, 1250000, 1187500, 1137500, 1087500, 1037500,
-	1000000,  987500,  975000,  950000,  925000,  900000,  900000
-};
-
-static struct cpufreq_frequency_table exynos4x12_freq_table[] = {
-	{CPUFREQ_BOOST_FREQ, L0, 1500 * 1000},
-	{0, L1, 1400 * 1000},
-	{0, L2, 1300 * 1000},
-	{0, L3, 1200 * 1000},
-	{0, L4, 1100 * 1000},
-	{0, L5, 1000 * 1000},
-	{0, L6,  900 * 1000},
-	{0, L7,  800 * 1000},
-	{0, L8,  700 * 1000},
-	{0, L9,  600 * 1000},
-	{0, L10, 500 * 1000},
-	{0, L11, 400 * 1000},
-	{0, L12, 300 * 1000},
-	{0, L13, 200 * 1000},
-	{0, 0, CPUFREQ_TABLE_END},
-};
-
-static struct apll_freq *apll_freq_4x12;
-
-static struct apll_freq apll_freq_4212[] = {
-	/*
-	 * values:
-	 * freq
-	 * clock divider for CORE, COREM0, COREM1, PERIPH, ATB, PCLK_DBG, APLL, CORE2
-	 * clock divider for COPY, HPM, RESERVED
-	 * PLL M, P, S
-	 */
-	APLL_FREQ(1500, 0, 3, 7, 0, 6, 1, 2, 0, 6, 2, 0, 250, 4, 0),
-	APLL_FREQ(1400, 0, 3, 7, 0, 6, 1, 2, 0, 6, 2, 0, 175, 3, 0),
-	APLL_FREQ(1300, 0, 3, 7, 0, 5, 1, 2, 0, 5, 2, 0, 325, 6, 0),
-	APLL_FREQ(1200, 0, 3, 7, 0, 5, 1, 2, 0, 5, 2, 0, 200, 4, 0),
-	APLL_FREQ(1100, 0, 3, 6, 0, 4, 1, 2, 0, 4, 2, 0, 275, 6, 0),
-	APLL_FREQ(1000, 0, 2, 5, 0, 4, 1, 1, 0, 4, 2, 0, 125, 3, 0),
-	APLL_FREQ(900,  0, 2, 5, 0, 3, 1, 1, 0, 3, 2, 0, 150, 4, 0),
-	APLL_FREQ(800,  0, 2, 5, 0, 3, 1, 1, 0, 3, 2, 0, 100, 3, 0),
-	APLL_FREQ(700,  0, 2, 4, 0, 3, 1, 1, 0, 3, 2, 0, 175, 3, 1),
-	APLL_FREQ(600,  0, 2, 4, 0, 3, 1, 1, 0, 3, 2, 0, 200, 4, 1),
-	APLL_FREQ(500,  0, 2, 4, 0, 3, 1, 1, 0, 3, 2, 0, 125, 3, 1),
-	APLL_FREQ(400,  0, 2, 4, 0, 3, 1, 1, 0, 3, 2, 0, 100, 3, 1),
-	APLL_FREQ(300,  0, 2, 4, 0, 2, 1, 1, 0, 3, 2, 0, 200, 4, 2),
-	APLL_FREQ(200,  0, 1, 3, 0, 1, 1, 1, 0, 3, 2, 0, 100, 3, 2),
-};
-
-static struct apll_freq apll_freq_4412[] = {
-	/*
-	 * values:
-	 * freq
-	 * clock divider for CORE, COREM0, COREM1, PERIPH, ATB, PCLK_DBG, APLL, CORE2
-	 * clock divider for COPY, HPM, CORES
-	 * PLL M, P, S
-	 */
-	APLL_FREQ(1500, 0, 3, 7, 0, 6, 1, 2, 0, 6, 0, 7, 250, 4, 0),
-	APLL_FREQ(1400, 0, 3, 7, 0, 6, 1, 2, 0, 6, 0, 6, 175, 3, 0),
-	APLL_FREQ(1300, 0, 3, 7, 0, 5, 1, 2, 0, 5, 0, 6, 325, 6, 0),
-	APLL_FREQ(1200, 0, 3, 7, 0, 5, 1, 2, 0, 5, 0, 5, 200, 4, 0),
-	APLL_FREQ(1100, 0, 3, 6, 0, 4, 1, 2, 0, 4, 0, 5, 275, 6, 0),
-	APLL_FREQ(1000, 0, 2, 5, 0, 4, 1, 1, 0, 4, 0, 4, 125, 3, 0),
-	APLL_FREQ(900,  0, 2, 5, 0, 3, 1, 1, 0, 3, 0, 4, 150, 4, 0),
-	APLL_FREQ(800,  0, 2, 5, 0, 3, 1, 1, 0, 3, 0, 3, 100, 3, 0),
-	APLL_FREQ(700,  0, 2, 4, 0, 3, 1, 1, 0, 3, 0, 3, 175, 3, 1),
-	APLL_FREQ(600,  0, 2, 4, 0, 3, 1, 1, 0, 3, 0, 2, 200, 4, 1),
-	APLL_FREQ(500,  0, 2, 4, 0, 3, 1, 1, 0, 3, 0, 2, 125, 3, 1),
-	APLL_FREQ(400,  0, 2, 4, 0, 3, 1, 1, 0, 3, 0, 1, 100, 3, 1),
-	APLL_FREQ(300,  0, 2, 4, 0, 2, 1, 1, 0, 3, 0, 1, 200, 4, 2),
-	APLL_FREQ(200,  0, 1, 3, 0, 1, 1, 1, 0, 3, 0, 0, 100, 3, 2),
-};
-
-static void exynos4x12_set_clkdiv(unsigned int div_index)
-{
-	unsigned int tmp;
-
-	/* Change Divider - CPU0 */
-
-	tmp = apll_freq_4x12[div_index].clk_div_cpu0;
-
-	__raw_writel(tmp, cpufreq->cmu_regs + EXYNOS4_CLKDIV_CPU);
-
-	while (__raw_readl(cpufreq->cmu_regs + EXYNOS4_CLKDIV_STATCPU)
-	       & 0x11111111)
-		cpu_relax();
-
-	/* Change Divider - CPU1 */
-	tmp = apll_freq_4x12[div_index].clk_div_cpu1;
-
-	__raw_writel(tmp, cpufreq->cmu_regs + EXYNOS4_CLKDIV_CPU1);
-
-	do {
-		cpu_relax();
-		tmp = __raw_readl(cpufreq->cmu_regs + EXYNOS4_CLKDIV_STATCPU1);
-	} while (tmp != 0x0);
-}
-
-static void exynos4x12_set_apll(unsigned int index)
-{
-	unsigned int tmp, freq = apll_freq_4x12[index].freq;
-
-	/* MUX_CORE_SEL = MPLL, ARMCLK uses MPLL for lock time */
-	clk_set_parent(moutcore, mout_mpll);
-
-	do {
-		cpu_relax();
-		tmp = (__raw_readl(cpufreq->cmu_regs + EXYNOS4_CLKMUX_STATCPU)
-			>> EXYNOS4_CLKSRC_CPU_MUXCORE_SHIFT);
-		tmp &= 0x7;
-	} while (tmp != 0x2);
-
-	clk_set_rate(mout_apll, freq * 1000);
-
-	/* MUX_CORE_SEL = APLL */
-	clk_set_parent(moutcore, mout_apll);
-
-	do {
-		cpu_relax();
-		tmp = __raw_readl(cpufreq->cmu_regs + EXYNOS4_CLKMUX_STATCPU);
-		tmp &= EXYNOS4_CLKMUX_STATCPU_MUXCORE_MASK;
-	} while (tmp != (0x1 << EXYNOS4_CLKSRC_CPU_MUXCORE_SHIFT));
-}
-
-static void exynos4x12_set_frequency(unsigned int old_index,
-				  unsigned int new_index)
-{
-	if (old_index > new_index) {
-		exynos4x12_set_clkdiv(new_index);
-		exynos4x12_set_apll(new_index);
-	} else if (old_index < new_index) {
-		exynos4x12_set_apll(new_index);
-		exynos4x12_set_clkdiv(new_index);
-	}
-}
-
-int exynos4x12_cpufreq_init(struct exynos_dvfs_info *info)
-{
-	struct device_node *np;
-	unsigned long rate;
-
-	/*
-	 * HACK: This is a temporary workaround to get access to clock
-	 * controller registers directly and remove static mappings and
-	 * dependencies on platform headers. It is necessary to enable
-	 * Exynos multi-platform support and will be removed together with
-	 * this whole driver as soon as Exynos gets migrated to use
-	 * cpufreq-dt driver.
-	 */
-	np = of_find_compatible_node(NULL, NULL, "samsung,exynos4412-clock");
-	if (!np) {
-		pr_err("%s: failed to find clock controller DT node\n",
-			__func__);
-		return -ENODEV;
-	}
-
-	info->cmu_regs = of_iomap(np, 0);
-	if (!info->cmu_regs) {
-		pr_err("%s: failed to map CMU registers\n", __func__);
-		return -EFAULT;
-	}
-
-	cpu_clk = clk_get(NULL, "armclk");
-	if (IS_ERR(cpu_clk))
-		return PTR_ERR(cpu_clk);
-
-	moutcore = clk_get(NULL, "moutcore");
-	if (IS_ERR(moutcore))
-		goto err_moutcore;
-
-	mout_mpll = clk_get(NULL, "mout_mpll");
-	if (IS_ERR(mout_mpll))
-		goto err_mout_mpll;
-
-	rate = clk_get_rate(mout_mpll) / 1000;
-
-	mout_apll = clk_get(NULL, "mout_apll");
-	if (IS_ERR(mout_apll))
-		goto err_mout_apll;
-
-	if (info->type == EXYNOS_SOC_4212)
-		apll_freq_4x12 = apll_freq_4212;
-	else
-		apll_freq_4x12 = apll_freq_4412;
-
-	info->mpll_freq_khz = rate;
-	/* 800Mhz */
-	info->pll_safe_idx = L7;
-	info->cpu_clk = cpu_clk;
-	info->volt_table = exynos4x12_volt_table;
-	info->freq_table = exynos4x12_freq_table;
-	info->set_freq = exynos4x12_set_frequency;
-
-	cpufreq = info;
-
-	return 0;
-
-err_mout_apll:
-	clk_put(mout_mpll);
-err_mout_mpll:
-	clk_put(moutcore);
-err_moutcore:
-	clk_put(cpu_clk);
-
-	pr_debug("%s: failed initialization\n", __func__);
-	return -EINVAL;
-}
-- 
1.9.1



From b.zolnierkie at samsung.com  Thu Aug  6 06:41:54 2015
From: b.zolnierkie at samsung.com (Bartlomiej Zolnierkiewicz)
Date: Thu, 06 Aug 2015 15:41:54 +0200
Subject: [PATCH v4 6/6] cpufreq: remove no longer needed CPU_FREQ_BOOST_SW
 config option
In-Reply-To: <1438868514-8814-1-git-send-email-b.zolnierkie@samsung.com>
References: <1438868514-8814-1-git-send-email-b.zolnierkie@samsung.com>
Message-ID: <1438868514-8814-7-git-send-email-b.zolnierkie@samsung.com>

Remove no longer needed CPU_FREQ_BOOST_SW config option.

Cc: Viresh Kumar <viresh.kumar at linaro.org>
Cc: Thomas Abraham <thomas.ab at samsung.com>
Cc: Javier Martinez Canillas <javier at osg.samsung.com>
Cc: Krzysztof Kozlowski <k.kozlowski at samsung.com>
Signed-off-by: Bartlomiej Zolnierkiewicz <b.zolnierkie at samsung.com>
---
 drivers/cpufreq/Kconfig      | 4 ----
 drivers/cpufreq/freq_table.c | 3 ---
 2 files changed, 7 deletions(-)

diff --git a/drivers/cpufreq/Kconfig b/drivers/cpufreq/Kconfig
index 659879a..aacc0ef 100644
--- a/drivers/cpufreq/Kconfig
+++ b/drivers/cpufreq/Kconfig
@@ -21,10 +21,6 @@ if CPU_FREQ
 config CPU_FREQ_GOV_COMMON
 	bool
 
-config CPU_FREQ_BOOST_SW
-	bool
-	depends on THERMAL
-
 config CPU_FREQ_STAT
 	tristate "CPU frequency translation statistics"
 	default y
diff --git a/drivers/cpufreq/freq_table.c b/drivers/cpufreq/freq_table.c
index 5a00a09..2c6a325 100644
--- a/drivers/cpufreq/freq_table.c
+++ b/drivers/cpufreq/freq_table.c
@@ -293,9 +293,6 @@ EXPORT_SYMBOL_GPL(cpufreq_freq_attr_scaling_boost_freqs);
 
 struct freq_attr *cpufreq_generic_attr[] = {
 	&cpufreq_freq_attr_scaling_available_freqs,
-#ifdef CONFIG_CPU_FREQ_BOOST_SW
-	&cpufreq_freq_attr_scaling_boost_freqs,
-#endif
 	NULL,
 };
 EXPORT_SYMBOL_GPL(cpufreq_generic_attr);
-- 
1.9.1



From ykk at rock-chips.com  Thu Aug  6 06:49:07 2015
From: ykk at rock-chips.com (Yakir Yang)
Date: Thu,  6 Aug 2015 08:49:07 -0500
Subject: [RFC PATCH 0/8] Add Analogix Core Display Port Driver
Message-ID: <1438868947-22132-1-git-send-email-ykk@rock-chips.com>

Hi all,
   Samsung exynos and Rockchip rk3288 almost share same dp controller,
so I split the common code out, then rk3288 and exynos can re-used the
same dp core driver. Cause I can't find the exact IP name of exynos dp
controller, so I decide to name dp core driver with "analogix" which I
find in rk3288 eDP TRM ;)

Beyond that, there are three light registers setting differents bewteen
exynos and rk3288.
1. RK3288 have five special pll resigters which not indicata in exynos
   dp controller.
2. The address of DP_PHY_PD(dp phy power manager register) are different
   between rk3288 and exynos.
3. Rk3288 and exynos have different setting with AUX_HW_RETRY_CTL(dp debug
   register).

My series patches can be divider into two parts: One for spliting the
analogix_dp code from exynos dp driver. Another are trying to add rk3288
dp driver support.

Best regards,
- Yakir


Yakir Yang (8):
  drm: exynos/dp: fix code style
  drm: exynos/dp: convert to drm bridge mode
  drm: bridge: analogix_dp: split exynos dp driver to bridge dir
  drm: rockchip/dp: add rockchip platform dp driver
  drm: bridge/analogix_dp: add platform device type support
  drm: bridge: analogix_dp: add some rk3288 special registers setting
  drm: bridge: analogix_dp: try force hpd after plug in lookup failed
  drm: bridge/analogix_dp: expand the delay time for hpd detect

 drivers/gpu/drm/bridge/Kconfig                     |    5 +
 drivers/gpu/drm/bridge/Makefile                    |    1 +
 drivers/gpu/drm/bridge/analogix_dp_core.c          | 1397 +++++++++++++++++++
 drivers/gpu/drm/bridge/analogix_dp_core.h          |  287 ++++
 drivers/gpu/drm/bridge/analogix_dp_reg.c           | 1295 ++++++++++++++++++
 .../exynos_dp_reg.h => bridge/analogix_dp_reg.h}   |  272 ++--
 drivers/gpu/drm/exynos/Kconfig                     |    5 +-
 drivers/gpu/drm/exynos/Makefile                    |    2 +-
 drivers/gpu/drm/exynos/analogix_dp-exynos.c        |  241 ++++
 drivers/gpu/drm/exynos/exynos_dp_core.c            | 1416 --------------------
 drivers/gpu/drm/exynos/exynos_dp_core.h            |  282 ----
 drivers/gpu/drm/exynos/exynos_dp_reg.c             |  100 +-
 drivers/gpu/drm/rockchip/Kconfig                   |   10 +
 drivers/gpu/drm/rockchip/Makefile                  |    1 +
 drivers/gpu/drm/rockchip/analogix_dp-rockchip.c    |  420 ++++++
 include/drm/bridge/analogix_dp.h                   |   28 +
 16 files changed, 3880 insertions(+), 1882 deletions(-)
 create mode 100644 drivers/gpu/drm/bridge/analogix_dp_core.c
 create mode 100644 drivers/gpu/drm/bridge/analogix_dp_core.h
 create mode 100644 drivers/gpu/drm/bridge/analogix_dp_reg.c
 rename drivers/gpu/drm/{exynos/exynos_dp_reg.h => bridge/analogix_dp_reg.h} (62%)
 create mode 100644 drivers/gpu/drm/exynos/analogix_dp-exynos.c
 delete mode 100644 drivers/gpu/drm/exynos/exynos_dp_core.c
 delete mode 100644 drivers/gpu/drm/exynos/exynos_dp_core.h
 create mode 100644 drivers/gpu/drm/rockchip/analogix_dp-rockchip.c
 create mode 100644 include/drm/bridge/analogix_dp.h

-- 
2.1.2




From linux at arm.linux.org.uk  Thu Aug  6 06:51:29 2015
From: linux at arm.linux.org.uk (Russell King - ARM Linux)
Date: Thu, 6 Aug 2015 14:51:29 +0100
Subject: [RFC PATCH 1/5] spi: introduce flag for memory mapped read
In-Reply-To: <55C35233.2000105@ti.com>
References: <20150804155148.GR20873@sirena.org.uk> <55C0FD98.1090107@ti.com>
 <20150805115013.GJ20873@sirena.org.uk>
 <CAOMqctQXwcHyiWBwtugSDSE_k65qrNfrwnhjQMDJkLoJMmGzUw@mail.gmail.com>
 <20150805124412.GN20873@sirena.org.uk>
 <CAOMqctS9Y5FxpUCCJew6+cnjH5iTvbzkH3g-8yrXs4OuS2pSGA@mail.gmail.com>
 <20150806090202.GO20873@sirena.org.uk>
 <CAOMqctQZRZ4zG_yYy=CeX3DX4NVNWN1COP4Q-2YvMun9xYOA7g@mail.gmail.com>
 <20150806102225.GI7576@n2100.arm.linux.org.uk>
 <55C35233.2000105@ti.com>
Message-ID: <20150806135129.GJ7576@n2100.arm.linux.org.uk>

On Thu, Aug 06, 2015 at 05:55:23PM +0530, Vignesh R wrote:
> On the whole following are my requirements:
> 1. to be able to communicate with non -flash SPI devices via config port
> ( this functionality is supported by current driver, I dont want to
> break it). Or pump any spi_message on to SPI bus directly.
> 2. take advantage of memory mapped port in order to increase read
> throughput( and use dma in future) when the slave is a m25p80 type flash.
> 3. handle m25p80 as well as other slave on multiple chipselects.
> 
> I just need to know whether the user that requested the transfer is
> m25p80 driver. If yes, ti-qspi driver can take advantage of memory
> mapped interface, else just use config port to access SPI bus directly.

The problem with this approach is that it's an abomination.  It's adding
a SPI-user specific hack which is detected by a specific driver.  That's
really not sane - what happens when we have lots of these kinds of "I'm
an X SPI-user" with drivers detecting that?  It's not maintainable in the
long term.

Yes, your requirements _today_ seem simple and easy, but you're only
thinking about today, not tomorrow when you've moved on and someone else
has to maintain the mess left behind (or delete it from mainline because
they're sick of dealing with a hack.)

> The spi_message that is received in transfer_one_message() is too
> generic to imply the slave device that is on the other side of the wire.
> IMO, the read command does not imply that the slave is m25p80 flash
> (besides the read opcodes vary across vendors of m25p80 and across modes).

I can see both sides of the argument.

Mark is saying: if the SPI driver detects that the message to be transmitted
is a read command followed by the appropriate number of dummy bytes, and
then the data being read _and_ it's using quad-mode access, and the hardware
generates _exactly_ that in hardware using the memory mapped mode, there is
no reason _not_ to use the hardware to achieve that SPI transaction.  The
bus activity will be identical to what happens when the SPI controller is
used manually to achieve that bus sequence.

You're saying: but the documentation says you can't use it for anything
except m25p80.  If you look at 24.5.4.1.2, it tells you what the SFI
generates on the bus, which is:

1. CS active
2. Read command byte sent
3. 1-4 address bytes sent
4. 0-3 dummy bytes sent
5. data bytes read from bus
6. CS inactive

So, Mark's point is "if we can detect a transaction which fits _that_
bus activity, there's no reason not to use this acceleration for the
transaction."

What you're failing to counter with is: we don't have enough information
in the SPI driver to know how many dummy bytes there are between the
address bytes and the data read from the bus.

The M25P80 driver just appends additional bytes to the message to
achieve this:

        struct m25p *flash = nor->priv;
        unsigned int dummy = nor->read_dummy;

        /* convert the dummy cycles to the number of bytes */
        dummy /= 8;

        flash->command[0] = nor->read_opcode;
        m25p_addr2cmd(nor, from, flash->command);

        t[0].tx_buf = flash->command;
        t[0].len = m25p_cmdsz(nor) + dummy;
        spi_message_add_tail(&t[0], &m);

The reason that the number of dummy bytes can't be detected is because
it's all hidden in the first transaction as the total number of bytes to
be transmitted - and the dummy bytes are uninitialised, so you can't
make any assumptions what value they are.  There is no way for the SPI
driver to know whether these dummy bytes are dummy bytes or whether they
have an effect on the targetted device.

I think that comprehensively rules out Mark's idea with the SPI core as
it stands today: there is no way for the SPI driver to reliably detect
a message like a SFI read command by parsing the SPI transmitted message
prior to sending it as we can never be sure whether there are dummy bytes
to be transmitted.

What may make more sense from the SPI point of view is to communicate to
all SPI drivers how many dummy bytes are to be transferred.  I'm not fully
up on SPI, but maybe something like this:

	t[0].tx_buf = flash->command;
	t[0].len = m25p_cmdsz(nor);
	spi_message_add_tail(&t[0], &m);
	t[1].tx_buf = dummy_buffer;
	t[1].len = dummy;
	t[1].dummy = 1;
	spi_message_add_tail(&t[1], &m);

This way, we're describing the transfer to the SPI core, and explicitly
indicating that there are some dummy bytes.  The SPI driver can then
tell that these are dummy bytes, and if the SPI message consists of:

- transmit 2 to 5 bytes where the first byte is a recognised read command
- transmit 0 to 3 dummy bytes
- read some bytes

then it can make use of the SFI mode to accelerate the operation.

This would not be a hack to the SPI code: we're describing to the SPI
code what we want to achieve in terms of the activity on the bus, and
providing that level of description then allows the SPI driver to make
informed decisions on whether it can handle the transfer using some
non-standard feature.

-- 
FTTC broadband for 0.8mile line: currently at 10.5Mbps down 400kbps up
according to speedtest.net.


From gabriele.paoloni at huawei.com  Thu Aug  6 06:52:35 2015
From: gabriele.paoloni at huawei.com (Gabriele Paoloni)
Date: Thu, 6 Aug 2015 13:52:35 +0000
Subject: [PATCH v6] PCI: Store PCIe bus address in struct of_pci_range
In-Reply-To: <EE11001F9E5DDD47B7634E2F8A612F2E01D719D1@lhreml503-mbs>
References: <1438010223-124422-1-git-send-email-gabriele.paoloni@huawei.com>
 <20150729172053.GE31170@google.com>
 <EE11001F9E5DDD47B7634E2F8A612F2E01D6F350@lhreml503-mbs>
 <CAL_JsqKs11-sXQTdBD+ZjbVYFWUHBARTW9q5MF1hCXUhZ+nWLQ@mail.gmail.com>
 <EE11001F9E5DDD47B7634E2F8A612F2E01D6F94A@lhreml503-mbs>
 <20150730161447.GG9640@google.com>
 <EE11001F9E5DDD47B7634E2F8A612F2E01D6FB3B@lhreml503-mbs>
 <20150730171445.GI9640@google.com>
 <EE11001F9E5DDD47B7634E2F8A612F2E01D6FC15@lhreml503-mbs>
 <CAL_Jsq+aQVakaZf4xo7sxnVyTmPR+HJ-9ByyS6OYJ0PHDYOwmg@mail.gmail.com>
 <EE11001F9E5DDD47B7634E2F8A612F2E01D70589@lhreml503-mbs>
 <55BB8CC6.1080203@ti.com>
 <CAL_JsqJqjiWVaKs-3ghQ1EBQzRRQ38GzkMV+FELPj53bSF-yXQ@mail.gmail.com>
 <EE11001F9E5DDD47B7634E2F8A612F2E01D712E7@lhreml503-mbs>
 <7F6386B4-D2F5-4840-AC72-F8C76CBC3B94@gmail.com>
 <EE11001F9E5DDD47B7634E2F8A612F2E01D719D1@lhreml503-mbs>
Message-ID: <EE11001F9E5DDD47B7634E2F8A612F2E01D72CFE@lhreml503-mbs>

Hi all

This patch has now been moved in "[PATCH v6 1/6] PCI: designware: move calculation of bus addresses to DRA7xx"

commit "f4c55c5a3f7f (PCI: designware: Program ATU with untranslated address)" has been reverted in
"[PATCH v6 3/6] PCI: designware: Add ARM64 support"

Gab

> -----Original Message-----
> From: linux-pci-owner at vger.kernel.org [mailto:linux-pci-
> owner at vger.kernel.org] On Behalf Of Gabriele Paoloni
> Sent: Tuesday, August 04, 2015 11:12 AM
> To: Jingoo Han
> Cc: Rob Herring; Kishon Vijay Abraham I; Bjorn Helgaas; arnd at arndb.de;
> lorenzo.pieralisi at arm.com; Wangzhou (B); robh+dt at kernel.org;
> james.morse at arm.com; Liviu.Dudau at arm.com; linux-pci at vger.kernel.org;
> linux-arm-kernel at lists.infradead.org; devicetree at vger.kernel.org;
> Yuanzhichang; Zhudacai; zhangjukuo; qiuzhenfa; Liguozhu (Kenneth);
> Pratyush Anand; Arnd Bergmann
> Subject: RE: [PATCH v6] PCI: Store PCIe bus address in struct
> of_pci_range
> 
> 
> 
> > -----Original Message-----
> > From: Jingoo Han [mailto:jingoohan1 at gmail.com]
> > Sent: Tuesday, August 04, 2015 5:20 AM
> > To: Gabriele Paoloni
> > Cc: Rob Herring; Kishon Vijay Abraham I; Bjorn Helgaas; arnd at arndb.de;
> > lorenzo.pieralisi at arm.com; Wangzhou (B); robh+dt at kernel.org;
> > james.morse at arm.com; Liviu.Dudau at arm.com; linux-pci at vger.kernel.org;
> > linux-arm-kernel at lists.infradead.org; devicetree at vger.kernel.org;
> > Yuanzhichang; Zhudacai; zhangjukuo; qiuzhenfa; Liguozhu (Kenneth);
> > Pratyush Anand; Arnd Bergmann; jingoohan1 at gmail.com
> > Subject: Re: [PATCH v6] PCI: Store PCIe bus address in struct
> > of_pci_range
> >
> > On 2015. 8. 3., at PM 8:18, Gabriele Paoloni
> > <gabriele.paoloni at huawei.com> wrote:
> > >
> > > Rob, Kishon what about the following solution?....
> > >
> > > ---
> > > drivers/pci/host/pci-dra7xx.c      | 12 ++++++++++++
> > > drivers/pci/host/pcie-designware.c |  9 +++------
> >
> > Hi Paoloni,
> >
> > OK, it looks good.
> > I want you to revert the following patch.
> >
> > commit "f4c55c5a3f7f (PCI: designware: Program ATU with untranslated
> > address)"
> >
> > Would you remove all '*_mode_base's?
> 
> Hi Jingoo Han,
> 
> If I reverted the commit, in order to get designware working, dra7
> should mask directly the CPU addresses stored in pp->cfg0_base,
> pp->cfg1_base, pp->mem_base and pp->io_base.
> 
> The masking would happen at this point:
> http://lxr.free-electrons.com/source/drivers/pci/host/pcie-
> designware.c#L493
> 
> Now:
> - I see that pp->cfg<0/1>_base are used in devm_ioremap before that
>   point and nowhere else, so they should be ok.
> - pp->mem_base is used in dw_pcie_setup_rc(); dw_pcie_setup_rc() is
> called
>   in dra7xx_pcie_host_init()...so here I should move the masking after
>   dw_pcie_setup() retuned, but I think it should be ok
> - pp->io_base is used in pci_ioremap_io() in dw_pcie_setup(). Now
> currently
>   in designware this is called by pci_bios_init_hw(); this is after the
>   masking....so here we would have a the wrong value passed
> 
> Said that if you look at "[PATCH v5 2/5] PCI: designware: Add ARM64
> support",
> that is the patchset where this patch is needed, you can see that
> dw_pcie_setup() is removed and pp->io_base is used in
> pci_remap_iospace() before
> the masking would happen in dra7xx_pcie_host_init()...so for this
> patchset we
> should be good to revert the commit.
> 
> I propose to add a new patch in the patchset "[PATCH v5 0/5] PCI: hisi:
> Add PCIe
> host support for HiSilicon SoC Hip05" as the one I just posted in this
> thread (this would not revert the commit but just moves the masking to
> dra7xx)
> 
> I would revert the commit in "[PATCH v5 2/5] PCI: designware: Add ARM64
> support"
> together with the rest of designware rework.
> 
> So we would have always a working version of designware...
> 
> Are you ok with this?
> 
> >
> > Best regards,
> > Jingoo Han
> >
> > > 2 files changed, 15 insertions(+), 6 deletions(-)
> > >
> > > diff --git a/drivers/pci/host/pci-dra7xx.c b/drivers/pci/host/pci-
> > dra7xx.c
> > > index 80db09e..bb2635f 100644
> > > --- a/drivers/pci/host/pci-dra7xx.c
> > > +++ b/drivers/pci/host/pci-dra7xx.c
> > > @@ -61,6 +61,7 @@
> > >
> > > #define    PCIECTRL_DRA7XX_CONF_PHY_CS            0x010C
> > > #define    LINK_UP                        BIT(16)
> > > +#define CPU_TO_BUS_ADDR             0x0FFFFFFF
> > >
> > > struct dra7xx_pcie {
> > >    void __iomem        *base;
> > > @@ -138,6 +139,17 @@ static void
> dra7xx_pcie_enable_interrupts(struct
> > pcie_port *pp)
> > >
> > > static void dra7xx_pcie_host_init(struct pcie_port *pp)
> > > {
> > > +    if (pp->io_mod_base)
> > > +        pp->io_mod_base &= CPU_TO_BUS_ADDR;
> > > +
> > > +    if (pp->mem_mod_base)
> > > +        pp->mem_mod_base &= CPU_TO_BUS_ADDR;
> > > +
> > > +    if (pp->cfg0_mod_base) {
> > > +        pp->cfg0_mod_base &= CPU_TO_BUS_ADDR;
> > > +        pp->cfg1_mod_base &= CPU_TO_BUS_ADDR;
> > > +    }
> > > +
> > >    dw_pcie_setup_rc(pp);
> > >    dra7xx_pcie_establish_link(pp);
> > >    if (IS_ENABLED(CONFIG_PCI_MSI))
> > > diff --git a/drivers/pci/host/pcie-designware.c
> > b/drivers/pci/host/pcie-designware.c
> > > index 69486be..06c682b 100644
> > > --- a/drivers/pci/host/pcie-designware.c
> > > +++ b/drivers/pci/host/pcie-designware.c
> > > @@ -416,8 +416,7 @@ int dw_pcie_host_init(struct pcie_port *pp)
> > >            pp->io_base = range.cpu_addr;
> > >
> > >            /* Find the untranslated IO space address */
> > > -            pp->io_mod_base = of_read_number(parser.range -
> > > -                             parser.np + na, ns);
> > > +            pp->io_mod_base = range.cpu_addr;;
> > >        }
> > >        if (restype == IORESOURCE_MEM) {
> > >            of_pci_range_to_resource(&range, np, &pp->mem);
> > > @@ -426,8 +425,7 @@ int dw_pcie_host_init(struct pcie_port *pp)
> > >            pp->mem_bus_addr = range.pci_addr;
> > >
> > >            /* Find the untranslated MEM space address */
> > > -            pp->mem_mod_base = of_read_number(parser.range -
> > > -                              parser.np + na, ns);
> > > +            pp->mem_mod_base = range.cpu_addr;
> > >        }
> > >        if (restype == 0) {
> > >            of_pci_range_to_resource(&range, np, &pp->cfg);
> > > @@ -437,8 +435,7 @@ int dw_pcie_host_init(struct pcie_port *pp)
> > >            pp->cfg1_base = pp->cfg.start + pp->cfg0_size;
> > >
> > >            /* Find the untranslated configuration space address */
> > > -            pp->cfg0_mod_base = of_read_number(parser.range -
> > > -                               parser.np + na, ns);
> > > +            pp->cfg0_mod_base = range.cpu_addr;
> > >            pp->cfg1_mod_base = pp->cfg0_mod_base +
> > >                        pp->cfg0_size;
> > >        }
> > > --
> > > 1.9.1
> > >
> > >
> > >> -----Original Message-----
> > >> From: linux-pci-owner at vger.kernel.org [mailto:linux-pci-
> > >> owner at vger.kernel.org] On Behalf Of Rob Herring
> > >> Sent: Friday, July 31, 2015 5:53 PM
> > >> To: Kishon Vijay Abraham I
> > >> Cc: Gabriele Paoloni; Bjorn Helgaas; arnd at arndb.de;
> > >> lorenzo.pieralisi at arm.com; Wangzhou (B); robh+dt at kernel.org;
> > >> james.morse at arm.com; Liviu.Dudau at arm.com; linux-
> pci at vger.kernel.org;
> > >> linux-arm-kernel at lists.infradead.org; devicetree at vger.kernel.org;
> > >> Yuanzhichang; Zhudacai; zhangjukuo; qiuzhenfa; Liguozhu (Kenneth);
> > >> Jingoo Han; Pratyush Anand; Arnd Bergmann
> > >> Subject: Re: [PATCH v6] PCI: Store PCIe bus address in struct
> > >> of_pci_range
> > >>
> > >> On Fri, Jul 31, 2015 at 9:57 AM, Kishon Vijay Abraham I
> > <kishon at ti.com>
> > >> wrote:
> > >>> +Arnd
> > >>>
> > >>> Hi,
> > >>>
> > >>>> On Friday 31 July 2015 07:55 PM, Gabriele Paoloni wrote:
> > >>>> [+cc Kishon]
> > >>>>
> > >>>>> -----Original Message-----
> > >>>>> From: linux-pci-owner at vger.kernel.org [mailto:linux-pci-
> > >>>>> owner at vger.kernel.org] On Behalf Of Rob Herring
> > >>>>> Sent: Thursday, July 30, 2015 9:42 PM
> > >>>>> To: Gabriele Paoloni
> > >>>>> Cc: Bjorn Helgaas; arnd at arndb.de; lorenzo.pieralisi at arm.com;
> > >> Wangzhou
> > >>>>> (B); robh+dt at kernel.org; james.morse at arm.com;
> Liviu.Dudau at arm.com;
> > >>>>> linux-pci at vger.kernel.org; linux-arm-kernel at lists.infradead.org;
> > >>>>> devicetree at vger.kernel.org; Yuanzhichang; Zhudacai; zhangjukuo;
> > >>>>> qiuzhenfa; Liguozhu (Kenneth); Jingoo Han; Pratyush Anand
> > >>>>> Subject: Re: [PATCH v6] PCI: Store PCIe bus address in struct
> > >>>>> of_pci_range
> > >>>>>
> > >>>>> On Thu, Jul 30, 2015 at 12:34 PM, Gabriele Paoloni
> > >>>>> <gabriele.paoloni at huawei.com> wrote:
> > >>>>>>> -----Original Message-----
> > >>>>>>> From: Bjorn Helgaas [mailto:bhelgaas at google.com]
> > >>>>>>> Sent: 30 July 2015 18:15
> > >>>>>>> On Thu, Jul 30, 2015 at 04:50:55PM +0000, Gabriele Paoloni
> > wrote:
> > >>>>>>>>> -----Original Message-----
> > >>>>>>>>> From: linux-pci-owner at vger.kernel.org [mailto:linux-pci-
> > >>>>>>>>> owner at vger.kernel.org] On Behalf Of Bjorn Helgaas
> > >>>>>>>>> Sent: Thursday, July 30, 2015 5:15 PM
> > >>>>>>>>> On Thu, Jul 30, 2015 at 01:52:13PM +0000, Gabriele Paoloni
> > >> wrote:
> > >>>>>
> > >>>>> [...]
> > >>>>>
> > >>>>>>>>>> I don?t think we should rely on [CPU] addresses...what if
> > the
> > >>>>>>>>> intermediate
> > >>>>>>>>>> translation layer changes the lower significant bits of
> the
> > >>>>> "bus
> > >>>>>>>>> address"
> > >>>>>>>>>> to translate into a cpu address?
> > >>>>>>>>>
> > >>>>>>>>> Is it really a possiblity that the lower bits could be
> > changed?
> > >>>>>>>>
> > >>>>>>>> I've checked all the current deignware users DTs except
> "pci-
> > >>>>>>> layerscape"
> > >>>>>>>> that I could not find:
> > >>>>>>>> spear1310.dtsi
> > >>>>>>>> spear1340.dtsi
> > >>>>>>>> dra7.dtsi
> > >>>>>>>> imx6qdl.dtsi
> > >>>>>>>> imx6sx.dtsi
> > >>>>>>>> keystone.dtsi
> > >>>>>>>> exynos5440.dtsi
> > >>>>>>>>
> > >>>>>>>> None of them modifies the lower bits. To be more precise the
> > >> only
> > >>>>> guy
> > >>>>>>>> that provides another translation layer is "dra7.dtsi":
> > >>>>>>>> axi0
> > >>>>>>>> http://lxr.free-
> > >>>>> electrons.com/source/arch/arm/boot/dts/dra7.dtsi#L207
> > >>>>>>>>
> > >>>>>>>> axi1
> > >>>>>>>> http://lxr.free-
> > >>>>> electrons.com/source/arch/arm/boot/dts/dra7.dtsi#L241
> > >>>>>>>>
> > >>>>>>>> For this case masking the top 4bits (bits28 to 31) should
> make
> > >> the
> > >>>>> job.
> > >>>>>
> > >>>>> IMO, we should just fix this case. After further study, I don't
> > >> think
> > >>>>> this is a DW issue, but rather an SOC integration issue.
> > >>>>>
> > >>>>> I believe you can just fixup the address in the pp->ops-
> > >host_init
> > >> hook.
> > >>>>
> > >>>> Yes I guess that I could just assign pp->(*)_mod_base to the CPU
> > >> address
> > >>>> in DW and mask it out in dra7xx_pcie_host_init()...
> > >>>>
> > >>>> Kishon, would you be ok with that?
> > >>>
> > >>> Initially I was using *base-mask* property from dt. Me and Arnd
> > >> (cc'ed) had
> > >>> this discussion [1] before we decided the current approach. It'll
> > be
> > >> good to
> > >>> check with Arnd too.
> > >>>
> > >>> [1] ->  http://lists.infradead.org/pipermail/linux-arm-
> kernel/2014-
> > >> May/253528.html
> > >>
> > >> The problem I have here is the use of ranges does not necessarily
> > mean
> > >> fewer address bits are available. It can be used just for
> > convenience
> > >> of not putting the full address into every node's reg property.
> And
> > >> vice versa, there are probably plenty of cases where we have the
> > full
> > >> address in the nodes, but really only some of the address bits are
> > >> decoded at the IP block. Whether the address bits are present is
> > >> rarely cared about or known by s/w folks until you hit a problem
> > like
> > >> this. Given this is an isolated case ATM, I would fix it in an
> > >> isolated way. It does not affect the binding and could be changed
> in
> > >> the kernel later if this becomes a common need.
> > >>
> > >> Rob
> > >> --
> > >> To unsubscribe from this list: send the line "unsubscribe linux-
> pci"
> > in
> > >> the body of a message to majordomo at vger.kernel.org
> > >> More majordomo info at  http://vger.kernel.org/majordomo-info.html
> ????????+-???w??????ir(???}????j:+v????zZ+??zf?
> ?????i??z?????????f

From linux at arm.linux.org.uk  Thu Aug  6 06:52:58 2015
From: linux at arm.linux.org.uk (Russell King - ARM Linux)
Date: Thu, 6 Aug 2015 14:52:58 +0100
Subject: [PATCH] ARM: Fix the secondary_startup function in Big Endian case
In-Reply-To: <1438860452-6347-1-git-send-email-gregory.clement@free-electrons.com>
References: <1438860452-6347-1-git-send-email-gregory.clement@free-electrons.com>
Message-ID: <20150806135258.GE7557@n2100.arm.linux.org.uk>

On Thu, Aug 06, 2015 at 01:27:32PM +0200, Gregory CLEMENT wrote:
> Since the commit "b2c3e38a5471 ARM: redo TTBR setup code for LPAE",
> the setup code had been reworked. As a result the secondary CPUs
> failed to come online in Big Endian.
> 
> As explained by Russell, the new code expected the value in r4/r5 to
> be the least significant 32bits in r4 and the most significant 32bits
> in r5. However, in the secondary code, we load this using ldrd, which
> on BE reverses that.
> 
> This patch swap r4/r5 after the ldrd. It is done using the xor
> instructions in order to not use a temporary register.

Patch looks good to me, thanks.

-- 
FTTC broadband for 0.8mile line: currently at 10.5Mbps down 400kbps up
according to speedtest.net.


From ykk at rock-chips.com  Thu Aug  6 06:58:38 2015
From: ykk at rock-chips.com (Yakir Yang)
Date: Thu, 6 Aug 2015 21:58:38 +0800
Subject: [RFC PATCH 1/8] drm: exynos/dp: fix code style
In-Reply-To: <1438868947-22132-1-git-send-email-ykk@rock-chips.com>
References: <1438868947-22132-1-git-send-email-ykk@rock-chips.com>
Message-ID: <55C3680E.30705@rock-chips.com>


make checkpatch.pl script happy

Signed-off-by: Yakir Yang <ykk at rock-chips.com>
---
  drivers/gpu/drm/exynos/exynos_dp_core.c | 224 
++++++++++++++++----------------
  drivers/gpu/drm/exynos/exynos_dp_core.h |  53 ++++----
  drivers/gpu/drm/exynos/exynos_dp_reg.c  | 100 +++++++-------
  3 files changed, 185 insertions(+), 192 deletions(-)

diff --git a/drivers/gpu/drm/exynos/exynos_dp_core.c 
b/drivers/gpu/drm/exynos/exynos_dp_core.c
index 172b800..a8097a4 100644
--- a/drivers/gpu/drm/exynos/exynos_dp_core.c
+++ b/drivers/gpu/drm/exynos/exynos_dp_core.c
@@ -114,8 +114,8 @@ static int exynos_dp_read_edid(struct 
exynos_dp_device *dp)

      /* Read Extension Flag, Number of 128-byte EDID extension blocks */
      retval = exynos_dp_read_byte_from_i2c(dp, I2C_EDID_DEVICE_ADDR,
-                EDID_EXTENSION_FLAG,
-                &extend_block);
+                          EDID_EXTENSION_FLAG,
+                          &extend_block);
      if (retval)
          return retval;

@@ -123,10 +123,11 @@ static int exynos_dp_read_edid(struct 
exynos_dp_device *dp)
          dev_dbg(dp->dev, "EDID data includes a single extension!\n");

          /* Read EDID data */
-        retval = exynos_dp_read_bytes_from_i2c(dp, I2C_EDID_DEVICE_ADDR,
-                        EDID_HEADER_PATTERN,
-                        EDID_BLOCK_LENGTH,
-                        &edid[EDID_HEADER_PATTERN]);
+        retval =
+        exynos_dp_read_bytes_from_i2c(dp, I2C_EDID_DEVICE_ADDR,
+                          EDID_HEADER_PATTERN,
+                          EDID_BLOCK_LENGTH,
+                          &edid[EDID_HEADER_PATTERN]);
          if (retval != 0) {
              dev_err(dp->dev, "EDID Read failed!\n");
              return -EIO;
@@ -138,11 +139,11 @@ static int exynos_dp_read_edid(struct 
exynos_dp_device *dp)
          }

          /* Read additional EDID data */
-        retval = exynos_dp_read_bytes_from_i2c(dp,
-                I2C_EDID_DEVICE_ADDR,
-                EDID_BLOCK_LENGTH,
-                EDID_BLOCK_LENGTH,
-                &edid[EDID_BLOCK_LENGTH]);
+        retval =
+        exynos_dp_read_bytes_from_i2c(dp, I2C_EDID_DEVICE_ADDR,
+                          EDID_BLOCK_LENGTH,
+                          EDID_BLOCK_LENGTH,
+                          &edid[EDID_BLOCK_LENGTH]);
          if (retval != 0) {
              dev_err(dp->dev, "EDID Read failed!\n");
              return -EIO;
@@ -154,24 +155,22 @@ static int exynos_dp_read_edid(struct 
exynos_dp_device *dp)
          }

          exynos_dp_read_byte_from_dpcd(dp, DP_TEST_REQUEST,
-                    &test_vector);
+                          &test_vector);
          if (test_vector & DP_TEST_LINK_EDID_READ) {
-            exynos_dp_write_byte_to_dpcd(dp,
-                DP_TEST_EDID_CHECKSUM,
+            exynos_dp_write_byte_to_dpcd(
+                dp, DP_TEST_EDID_CHECKSUM,
                  edid[EDID_BLOCK_LENGTH + EDID_CHECKSUM]);
-            exynos_dp_write_byte_to_dpcd(dp,
-                DP_TEST_RESPONSE,
+            exynos_dp_write_byte_to_dpcd(
+                dp, DP_TEST_RESPONSE,
                  DP_TEST_EDID_CHECKSUM_WRITE);
          }
      } else {
          dev_info(dp->dev, "EDID data does not include any extensions.\n");

          /* Read EDID data */
-        retval = exynos_dp_read_bytes_from_i2c(dp,
-                I2C_EDID_DEVICE_ADDR,
-                EDID_HEADER_PATTERN,
-                EDID_BLOCK_LENGTH,
-                &edid[EDID_HEADER_PATTERN]);
+        retval = exynos_dp_read_bytes_from_i2c(
+                dp, I2C_EDID_DEVICE_ADDR, EDID_HEADER_PATTERN,
+                EDID_BLOCK_LENGTH, &edid[EDID_HEADER_PATTERN]);
          if (retval != 0) {
              dev_err(dp->dev, "EDID Read failed!\n");
              return -EIO;
@@ -182,16 +181,15 @@ static int exynos_dp_read_edid(struct 
exynos_dp_device *dp)
              return -EIO;
          }

-        exynos_dp_read_byte_from_dpcd(dp,
-            DP_TEST_REQUEST,
-            &test_vector);
+        exynos_dp_read_byte_from_dpcd(dp, DP_TEST_REQUEST,
+                          &test_vector);
          if (test_vector & DP_TEST_LINK_EDID_READ) {
-            exynos_dp_write_byte_to_dpcd(dp,
-                DP_TEST_EDID_CHECKSUM,
-                edid[EDID_CHECKSUM]);
-            exynos_dp_write_byte_to_dpcd(dp,
-                DP_TEST_RESPONSE,
-                DP_TEST_EDID_CHECKSUM_WRITE);
+            exynos_dp_write_byte_to_dpcd(
+                    dp, DP_TEST_EDID_CHECKSUM,
+                    edid[EDID_CHECKSUM]);
+            exynos_dp_write_byte_to_dpcd(
+                    dp, DP_TEST_RESPONSE,
+                    DP_TEST_EDID_CHECKSUM_WRITE);
          }
      }

@@ -206,8 +204,7 @@ static int exynos_dp_handle_edid(struct 
exynos_dp_device *dp)
      int retval;

      /* Read DPCD DP_DPCD_REV~RECEIVE_PORT1_CAP_1 */
-    retval = exynos_dp_read_bytes_from_dpcd(dp, DP_DPCD_REV,
-                12, buf);
+    retval = exynos_dp_read_bytes_from_dpcd(dp, DP_DPCD_REV, 12, buf);
      if (retval)
          return retval;

@@ -222,19 +219,21 @@ static int exynos_dp_handle_edid(struct 
exynos_dp_device *dp)
  }

  static void exynos_dp_enable_rx_to_enhanced_mode(struct 
exynos_dp_device *dp,
-                        bool enable)
+                         bool enable)
  {
      u8 data;

      exynos_dp_read_byte_from_dpcd(dp, DP_LANE_COUNT_SET, &data);

      if (enable)
-        exynos_dp_write_byte_to_dpcd(dp, DP_LANE_COUNT_SET,
-            DP_LANE_COUNT_ENHANCED_FRAME_EN |
-            DPCD_LANE_COUNT_SET(data));
+        exynos_dp_write_byte_to_dpcd(
+                    dp, DP_LANE_COUNT_SET,
+                    DP_LANE_COUNT_ENHANCED_FRAME_EN |
+                    DPCD_LANE_COUNT_SET(data));
      else
-        exynos_dp_write_byte_to_dpcd(dp, DP_LANE_COUNT_SET,
-            DPCD_LANE_COUNT_SET(data));
+        exynos_dp_write_byte_to_dpcd(
+                    dp, DP_LANE_COUNT_SET,
+                    DPCD_LANE_COUNT_SET(data));
  }

  static int exynos_dp_is_enhanced_mode_available(struct 
exynos_dp_device *dp)
@@ -261,13 +260,12 @@ static void exynos_dp_training_pattern_dis(struct 
exynos_dp_device *dp)
  {
      exynos_dp_set_training_pattern(dp, DP_NONE);

-    exynos_dp_write_byte_to_dpcd(dp,
-        DP_TRAINING_PATTERN_SET,
-        DP_TRAINING_PATTERN_DISABLE);
+    exynos_dp_write_byte_to_dpcd(dp, DP_TRAINING_PATTERN_SET,
+                     DP_TRAINING_PATTERN_DISABLE);
  }

  static void exynos_dp_set_lane_lane_pre_emphasis(struct 
exynos_dp_device *dp,
-                    int pre_emphasis, int lane)
+                         int pre_emphasis, int lane)
  {
      switch (lane) {
      case 0:
@@ -307,15 +305,14 @@ static int exynos_dp_link_start(struct 
exynos_dp_device *dp)
      /* Setup RX configuration */
      buf[0] = dp->link_train.link_rate;
      buf[1] = dp->link_train.lane_count;
-    retval = exynos_dp_write_bytes_to_dpcd(dp, DP_LINK_BW_SET,
-                2, buf);
+    retval = exynos_dp_write_bytes_to_dpcd(dp, DP_LINK_BW_SET, 2, buf);
      if (retval)
          return retval;

      /* Set TX pre-emphasis to minimum */
      for (lane = 0; lane < lane_count; lane++)
-        exynos_dp_set_lane_lane_pre_emphasis(dp,
-            PRE_EMPHASIS_LEVEL_0, lane);
+        exynos_dp_set_lane_lane_pre_emphasis(dp, PRE_EMPHASIS_LEVEL_0,
+                             lane);

      /* Wait for PLL lock */
      pll_tries = 0;
@@ -333,9 +330,9 @@ static int exynos_dp_link_start(struct 
exynos_dp_device *dp)
      exynos_dp_set_training_pattern(dp, TRAINING_PTN1);

      /* Set RX training pattern */
-    retval = exynos_dp_write_byte_to_dpcd(dp,
-            DP_TRAINING_PATTERN_SET,
-            DP_LINK_SCRAMBLING_DISABLE | DP_TRAINING_PATTERN_1);
+    retval = exynos_dp_write_byte_to_dpcd(dp, DP_TRAINING_PATTERN_SET,
+                          DP_LINK_SCRAMBLING_DISABLE |
+                          DP_TRAINING_PATTERN_1);
      if (retval)
          return retval;

@@ -344,7 +341,7 @@ static int exynos_dp_link_start(struct 
exynos_dp_device *dp)
                  DP_TRAIN_VOLTAGE_SWING_LEVEL_0;

      retval = exynos_dp_write_bytes_to_dpcd(dp, DP_TRAINING_LANE0_SET,
-            lane_count, buf);
+                           lane_count, buf);

      return retval;
  }
@@ -352,7 +349,7 @@ static int exynos_dp_link_start(struct 
exynos_dp_device *dp)
  static unsigned char exynos_dp_get_lane_status(u8 link_status[2], int 
lane)
  {
      int shift = (lane & 1) * 4;
-    u8 link_value = link_status[lane>>1];
+    u8 link_value = link_status[lane >> 1];

      return (link_value >> shift) & 0xf;
  }
@@ -371,7 +368,7 @@ static int exynos_dp_clock_recovery_ok(u8 
link_status[2], int lane_count)
  }

  static int exynos_dp_channel_eq_ok(u8 link_status[2], u8 link_align,
-                int lane_count)
+                   int lane_count)
  {
      int lane;
      u8 lane_status;
@@ -390,10 +387,10 @@ static int exynos_dp_channel_eq_ok(u8 
link_status[2], u8 link_align,
  }

  static unsigned char exynos_dp_get_adjust_request_voltage(u8 
adjust_request[2],
-                            int lane)
+                              int lane)
  {
      int shift = (lane & 1) * 4;
-    u8 link_value = adjust_request[lane>>1];
+    u8 link_value = adjust_request[lane >> 1];

      return (link_value >> shift) & 0x3;
  }
@@ -403,13 +400,13 @@ static unsigned char 
exynos_dp_get_adjust_request_pre_emphasis(
                      int lane)
  {
      int shift = (lane & 1) * 4;
-    u8 link_value = adjust_request[lane>>1];
+    u8 link_value = adjust_request[lane >> 1];

      return ((link_value >> shift) & 0xc) >> 2;
  }

  static void exynos_dp_set_lane_link_training(struct exynos_dp_device *dp,
-                    u8 training_lane_set, int lane)
+                         u8 training_lane_set, int lane)
  {
      switch (lane) {
      case 0:
@@ -465,7 +462,7 @@ static void exynos_dp_reduce_link_rate(struct 
exynos_dp_device *dp)
  }

  static void exynos_dp_get_adjust_training_lane(struct exynos_dp_device 
*dp,
-                    u8 adjust_request[2])
+                           u8 adjust_request[2])
  {
      int lane, lane_count;
      u8 voltage_swing, pre_emphasis, training_lane;
@@ -498,13 +495,13 @@ static int exynos_dp_process_clock_recovery(struct 
exynos_dp_device *dp)

      lane_count = dp->link_train.lane_count;

-    retval =  exynos_dp_read_bytes_from_dpcd(dp,
-            DP_LANE0_1_STATUS, 2, link_status);
+    retval =  exynos_dp_read_bytes_from_dpcd(dp, DP_LANE0_1_STATUS,
+                         2, link_status);
      if (retval)
          return retval;

-    retval =  exynos_dp_read_bytes_from_dpcd(dp,
-            DP_ADJUST_REQUEST_LANE0_1, 2, adjust_request);
+    retval =  exynos_dp_read_bytes_from_dpcd(dp, DP_ADJUST_REQUEST_LANE0_1,
+                         2, adjust_request);
      if (retval)
          return retval;

@@ -512,8 +509,8 @@ static int exynos_dp_process_clock_recovery(struct 
exynos_dp_device *dp)
          /* set training pattern 2 for EQ */
          exynos_dp_set_training_pattern(dp, TRAINING_PTN2);

-        retval = exynos_dp_write_byte_to_dpcd(dp,
-                DP_TRAINING_PATTERN_SET,
+        retval = exynos_dp_write_byte_to_dpcd(
+                dp, DP_TRAINING_PATTERN_SET,
                  DP_LINK_SCRAMBLING_DISABLE |
                  DP_TRAINING_PATTERN_2);
          if (retval)
@@ -527,8 +524,9 @@ static int exynos_dp_process_clock_recovery(struct 
exynos_dp_device *dp)
                              dp, lane);
              voltage_swing = exynos_dp_get_adjust_request_voltage(
                              adjust_request, lane);
-            pre_emphasis = exynos_dp_get_adjust_request_pre_emphasis(
-                            adjust_request, lane);
+            pre_emphasis =
+                exynos_dp_get_adjust_request_pre_emphasis(
+                        adjust_request, lane);

              if (DPCD_VOLTAGE_SWING_GET(training_lane) ==
                      voltage_swing &&
@@ -551,11 +549,11 @@ static int exynos_dp_process_clock_recovery(struct 
exynos_dp_device *dp)
      exynos_dp_get_adjust_training_lane(dp, adjust_request);

      for (lane = 0; lane < lane_count; lane++)
-        exynos_dp_set_lane_link_training(dp,
-            dp->link_train.training_lane[lane], lane);
+        exynos_dp_set_lane_link_training(
+                dp, dp->link_train.training_lane[lane], lane);

-    retval = exynos_dp_write_bytes_to_dpcd(dp,
-            DP_TRAINING_LANE0_SET, lane_count,
+    retval = exynos_dp_write_bytes_to_dpcd(
+            dp, DP_TRAINING_LANE0_SET, lane_count,
              dp->link_train.training_lane);
      if (retval)
          return retval;
@@ -573,8 +571,8 @@ static int 
exynos_dp_process_equalizer_training(struct exynos_dp_device *dp)

      lane_count = dp->link_train.lane_count;

-    retval = exynos_dp_read_bytes_from_dpcd(dp,
-            DP_LANE0_1_STATUS, 2, link_status);
+    retval = exynos_dp_read_bytes_from_dpcd(dp, DP_LANE0_1_STATUS,
+                        2, link_status);
      if (retval)
          return retval;

@@ -583,13 +581,13 @@ static int 
exynos_dp_process_equalizer_training(struct exynos_dp_device *dp)
          return -EIO;
      }

-    retval = exynos_dp_read_bytes_from_dpcd(dp,
-            DP_ADJUST_REQUEST_LANE0_1, 2, adjust_request);
+    retval = exynos_dp_read_bytes_from_dpcd(dp, DP_ADJUST_REQUEST_LANE0_1,
+                        2, adjust_request);
      if (retval)
          return retval;

-    retval = exynos_dp_read_byte_from_dpcd(dp,
-            DP_LANE_ALIGN_STATUS_UPDATED, &link_align);
+    retval = exynos_dp_read_byte_from_dpcd(
+            dp, DP_LANE_ALIGN_STATUS_UPDATED, &link_align);
      if (retval)
          return retval;

@@ -628,17 +626,18 @@ static int 
exynos_dp_process_equalizer_training(struct exynos_dp_device *dp)
      }

      for (lane = 0; lane < lane_count; lane++)
-        exynos_dp_set_lane_link_training(dp,
-            dp->link_train.training_lane[lane], lane);
+        exynos_dp_set_lane_link_training(
+                dp, dp->link_train.training_lane[lane], lane);

      retval = exynos_dp_write_bytes_to_dpcd(dp, DP_TRAINING_LANE0_SET,
-            lane_count, dp->link_train.training_lane);
+                           lane_count,
+                           dp->link_train.training_lane);

      return retval;
  }

  static void exynos_dp_get_max_rx_bandwidth(struct exynos_dp_device *dp,
-                    u8 *bandwidth)
+                       u8 *bandwidth)
  {
      u8 data;

@@ -651,7 +650,7 @@ static void exynos_dp_get_max_rx_bandwidth(struct 
exynos_dp_device *dp,
  }

  static void exynos_dp_get_max_rx_lane_count(struct exynos_dp_device *dp,
-                    u8 *lane_count)
+                        u8 *lane_count)
  {
      u8 data;

@@ -664,8 +663,8 @@ static void exynos_dp_get_max_rx_lane_count(struct 
exynos_dp_device *dp,
  }

  static void exynos_dp_init_training(struct exynos_dp_device *dp,
-            enum link_lane_count_type max_lane,
-            enum link_rate_type max_rate)
+                    enum link_lane_count_type max_lane,
+                    enum link_rate_type max_rate)
  {
      /*
       * MACRO_RST must be applied after the PLL_LOCK to avoid
@@ -678,7 +677,7 @@ static void exynos_dp_init_training(struct 
exynos_dp_device *dp,
      exynos_dp_get_max_rx_lane_count(dp, &dp->link_train.lane_count);

      if ((dp->link_train.link_rate != LINK_RATE_1_62GBPS) &&
-       (dp->link_train.link_rate != LINK_RATE_2_70GBPS)) {
+        (dp->link_train.link_rate != LINK_RATE_2_70GBPS)) {
          dev_err(dp->dev, "Rx Max Link Rate is abnormal :%x !\n",
              dp->link_train.link_rate);
          dp->link_train.link_rate = LINK_RATE_1_62GBPS;
@@ -738,8 +737,7 @@ static int exynos_dp_sw_link_training(struct 
exynos_dp_device *dp)
  }

  static int exynos_dp_set_link_train(struct exynos_dp_device *dp,
-                u32 count,
-                u32 bwtype)
+                    u32 count, u32 bwtype)
  {
      int i;
      int retval;
@@ -830,21 +828,19 @@ static void exynos_dp_enable_scramble(struct 
exynos_dp_device *dp, bool enable)
      if (enable) {
          exynos_dp_enable_scrambling(dp);

-        exynos_dp_read_byte_from_dpcd(dp,
-            DP_TRAINING_PATTERN_SET,
-            &data);
-        exynos_dp_write_byte_to_dpcd(dp,
-            DP_TRAINING_PATTERN_SET,
+        exynos_dp_read_byte_from_dpcd(dp, DP_TRAINING_PATTERN_SET,
+                          &data);
+        exynos_dp_write_byte_to_dpcd(
+            dp, DP_TRAINING_PATTERN_SET,
              (u8)(data & ~DP_LINK_SCRAMBLING_DISABLE));
      } else {
          exynos_dp_disable_scrambling(dp);

-        exynos_dp_read_byte_from_dpcd(dp,
-            DP_TRAINING_PATTERN_SET,
-            &data);
-        exynos_dp_write_byte_to_dpcd(dp,
-            DP_TRAINING_PATTERN_SET,
-            (u8)(data | DP_LINK_SCRAMBLING_DISABLE));
+        exynos_dp_read_byte_from_dpcd(dp, DP_TRAINING_PATTERN_SET,
+                          &data);
+        exynos_dp_write_byte_to_dpcd(
+                dp, DP_TRAINING_PATTERN_SET,
+                (u8)(data | DP_LINK_SCRAMBLING_DISABLE));
      }
  }

@@ -915,7 +911,7 @@ static void exynos_dp_commit(struct 
exynos_drm_display *display)
      }

      ret = exynos_dp_set_link_train(dp, dp->video_info->lane_count,
-                    dp->video_info->link_rate);
+                       dp->video_info->link_rate);
      if (ret) {
          dev_err(dp->dev, "unable to do link train\n");
          return;
@@ -1004,7 +1000,7 @@ static struct drm_connector_helper_funcs 
exynos_dp_connector_helper_funcs = {

  /* returns the number of bridges attached */
  static int exynos_drm_attach_lcd_bridge(struct exynos_dp_device *dp,
-        struct drm_encoder *encoder)
+                    struct drm_encoder *encoder)
  {
      int ret;

@@ -1020,7 +1016,7 @@ static int exynos_drm_attach_lcd_bridge(struct 
exynos_dp_device *dp,
  }

  static int exynos_dp_create_connector(struct exynos_drm_display *display,
-                struct drm_encoder *encoder)
+                      struct drm_encoder *encoder)
  {
      struct exynos_dp_device *dp = display_to_dp(display);
      struct drm_connector *connector = &dp->connector;
@@ -1038,7 +1034,8 @@ static int exynos_dp_create_connector(struct 
exynos_drm_display *display,
      connector->polled = DRM_CONNECTOR_POLL_HPD;

      ret = drm_connector_init(dp->drm_dev, connector,
-            &exynos_dp_connector_funcs, DRM_MODE_CONNECTOR_eDP);
+                 &exynos_dp_connector_funcs,
+                 DRM_MODE_CONNECTOR_eDP);
      if (ret) {
          DRM_ERROR("Failed to initialize connector with drm\n");
          return ret;
@@ -1148,8 +1145,8 @@ static struct video_info 
*exynos_dp_dt_parse_pdata(struct device *dev)
      struct device_node *dp_node = dev->of_node;
      struct video_info *dp_video_config;

-    dp_video_config = devm_kzalloc(dev,
-                sizeof(*dp_video_config), GFP_KERNEL);
+    dp_video_config = devm_kzalloc(dev, sizeof(*dp_video_config),
+                       GFP_KERNEL);
      if (!dp_video_config)
          return ERR_PTR(-ENOMEM);

@@ -1163,37 +1160,37 @@ static struct video_info 
*exynos_dp_dt_parse_pdata(struct device *dev)
          of_property_read_bool(dp_node, "interlaced");

      if (of_property_read_u32(dp_node, "samsung,color-space",
-                &dp_video_config->color_space)) {
+                 &dp_video_config->color_space)) {
          dev_err(dev, "failed to get color-space\n");
          return ERR_PTR(-EINVAL);
      }

      if (of_property_read_u32(dp_node, "samsung,dynamic-range",
-                &dp_video_config->dynamic_range)) {
+                 &dp_video_config->dynamic_range)) {
          dev_err(dev, "failed to get dynamic-range\n");
          return ERR_PTR(-EINVAL);
      }

      if (of_property_read_u32(dp_node, "samsung,ycbcr-coeff",
-                &dp_video_config->ycbcr_coeff)) {
+                 &dp_video_config->ycbcr_coeff)) {
          dev_err(dev, "failed to get ycbcr-coeff\n");
          return ERR_PTR(-EINVAL);
      }

      if (of_property_read_u32(dp_node, "samsung,color-depth",
-                &dp_video_config->color_depth)) {
+                 &dp_video_config->color_depth)) {
          dev_err(dev, "failed to get color-depth\n");
          return ERR_PTR(-EINVAL);
      }

      if (of_property_read_u32(dp_node, "samsung,link-rate",
-                &dp_video_config->link_rate)) {
+                 &dp_video_config->link_rate)) {
          dev_err(dev, "failed to get link-rate\n");
          return ERR_PTR(-EINVAL);
      }

      if (of_property_read_u32(dp_node, "samsung,lane-count",
-                &dp_video_config->lane_count)) {
+                 &dp_video_config->lane_count)) {
          dev_err(dev, "failed to get lane-count\n");
          return ERR_PTR(-EINVAL);
      }
@@ -1206,7 +1203,7 @@ static int exynos_dp_dt_parse_panel(struct 
exynos_dp_device *dp)
      int ret;

      ret = of_get_videomode(dp->dev->of_node, &dp->priv.vm,
-            OF_USE_NATIVE_MODE);
+                   OF_USE_NATIVE_MODE);
      if (ret) {
          DRM_ERROR("failed: of_get_videomode() : %d\n", ret);
          return ret;
@@ -1302,7 +1299,7 @@ static int exynos_dp_bind(struct device *dev, 
struct device *master, void *data)
      exynos_dp_init_dp(dp);

      ret = devm_request_irq(&pdev->dev, dp->irq, exynos_dp_irq_handler,
-            irq_flags, "exynos-dp", dp);
+                   irq_flags, "exynos-dp", dp);
      if (ret) {
          dev_err(&pdev->dev, "failed to request irq\n");
          return ret;
@@ -1315,7 +1312,7 @@ static int exynos_dp_bind(struct device *dev, 
struct device *master, void *data)
  }

  static void exynos_dp_unbind(struct device *dev, struct device *master,
-                void *data)
+                 void *data)
  {
      struct exynos_dp_device *dp = dev_get_drvdata(dev);

@@ -1334,7 +1331,7 @@ static int exynos_dp_probe(struct platform_device 
*pdev)
      struct exynos_dp_device *dp;

      dp = devm_kzalloc(&pdev->dev, sizeof(struct exynos_dp_device),
-                GFP_KERNEL);
+              GFP_KERNEL);
      if (!dp)
          return -ENOMEM;

@@ -1358,8 +1355,9 @@ static int exynos_dp_probe(struct platform_device 
*pdev)
              of_node_put(bridge_node);
              if (!dp->bridge)
                  return -EPROBE_DEFER;
-        } else
+        } else {
              return -EPROBE_DEFER;
+        }
      }

      return component_add(&pdev->dev, &exynos_dp_ops);
diff --git a/drivers/gpu/drm/exynos/exynos_dp_core.h 
b/drivers/gpu/drm/exynos/exynos_dp_core.h
index a4e7996..c321ad5 100644
--- a/drivers/gpu/drm/exynos/exynos_dp_core.h
+++ b/drivers/gpu/drm/exynos/exynos_dp_core.h
@@ -180,8 +180,8 @@ void exynos_dp_config_interrupt(struct 
exynos_dp_device *dp);
  enum pll_status exynos_dp_get_pll_lock_status(struct exynos_dp_device 
*dp);
  void exynos_dp_set_pll_power_down(struct exynos_dp_device *dp, bool 
enable);
  void exynos_dp_set_analog_power_down(struct exynos_dp_device *dp,
-                enum analog_power_block block,
-                bool enable);
+                     enum analog_power_block block,
+                     bool enable);
  void exynos_dp_init_analog_func(struct exynos_dp_device *dp);
  void exynos_dp_init_hpd(struct exynos_dp_device *dp);
  enum dp_irq_type exynos_dp_get_irq_type(struct exynos_dp_device *dp);
@@ -192,50 +192,50 @@ int exynos_dp_get_plug_in_status(struct 
exynos_dp_device *dp);
  void exynos_dp_enable_sw_function(struct exynos_dp_device *dp);
  int exynos_dp_start_aux_transaction(struct exynos_dp_device *dp);
  int exynos_dp_write_byte_to_dpcd(struct exynos_dp_device *dp,
-                unsigned int reg_addr,
-                unsigned char data);
+                 unsigned int reg_addr,
+                 unsigned char data);
  int exynos_dp_read_byte_from_dpcd(struct exynos_dp_device *dp,
-                unsigned int reg_addr,
-                unsigned char *data);
+                  unsigned int reg_addr,
+                  unsigned char *data);
  int exynos_dp_write_bytes_to_dpcd(struct exynos_dp_device *dp,
-                unsigned int reg_addr,
-                unsigned int count,
-                unsigned char data[]);
+                  unsigned int reg_addr,
+                  unsigned int count,
+                  unsigned char data[]);
  int exynos_dp_read_bytes_from_dpcd(struct exynos_dp_device *dp,
-                unsigned int reg_addr,
-                unsigned int count,
-                unsigned char data[]);
+                   unsigned int reg_addr,
+                   unsigned int count,
+                   unsigned char data[]);
  int exynos_dp_select_i2c_device(struct exynos_dp_device *dp,
                  unsigned int device_addr,
                  unsigned int reg_addr);
  int exynos_dp_read_byte_from_i2c(struct exynos_dp_device *dp,
-                unsigned int device_addr,
-                unsigned int reg_addr,
-                unsigned int *data);
+                 unsigned int device_addr,
+                 unsigned int reg_addr,
+                 unsigned int *data);
  int exynos_dp_read_bytes_from_i2c(struct exynos_dp_device *dp,
-                unsigned int device_addr,
-                unsigned int reg_addr,
-                unsigned int count,
-                unsigned char edid[]);
+                  unsigned int device_addr,
+                  unsigned int reg_addr,
+                  unsigned int count,
+                  unsigned char edid[]);
  void exynos_dp_set_link_bandwidth(struct exynos_dp_device *dp, u32 
bwtype);
  void exynos_dp_get_link_bandwidth(struct exynos_dp_device *dp, u32 
*bwtype);
  void exynos_dp_set_lane_count(struct exynos_dp_device *dp, u32 count);
  void exynos_dp_get_lane_count(struct exynos_dp_device *dp, u32 *count);
  void exynos_dp_enable_enhanced_mode(struct exynos_dp_device *dp, bool 
enable);
  void exynos_dp_set_training_pattern(struct exynos_dp_device *dp,
-                 enum pattern_set pattern);
+                    enum pattern_set pattern);
  void exynos_dp_set_lane0_pre_emphasis(struct exynos_dp_device *dp, u32 
level);
  void exynos_dp_set_lane1_pre_emphasis(struct exynos_dp_device *dp, u32 
level);
  void exynos_dp_set_lane2_pre_emphasis(struct exynos_dp_device *dp, u32 
level);
  void exynos_dp_set_lane3_pre_emphasis(struct exynos_dp_device *dp, u32 
level);
  void exynos_dp_set_lane0_link_training(struct exynos_dp_device *dp,
-                u32 training_lane);
+                       u32 training_lane);
  void exynos_dp_set_lane1_link_training(struct exynos_dp_device *dp,
-                u32 training_lane);
+                       u32 training_lane);
  void exynos_dp_set_lane2_link_training(struct exynos_dp_device *dp,
-                u32 training_lane);
+                       u32 training_lane);
  void exynos_dp_set_lane3_link_training(struct exynos_dp_device *dp,
-                u32 training_lane);
+                       u32 training_lane);
  u32 exynos_dp_get_lane0_link_training(struct exynos_dp_device *dp);
  u32 exynos_dp_get_lane1_link_training(struct exynos_dp_device *dp);
  u32 exynos_dp_get_lane2_link_training(struct exynos_dp_device *dp);
@@ -246,9 +246,8 @@ void exynos_dp_init_video(struct exynos_dp_device *dp);
  void exynos_dp_set_video_color_format(struct exynos_dp_device *dp);
  int exynos_dp_is_slave_video_stream_clock_on(struct exynos_dp_device *dp);
  void exynos_dp_set_video_cr_mn(struct exynos_dp_device *dp,
-            enum clock_recovery_m_value_type type,
-            u32 m_value,
-            u32 n_value);
+                   enum clock_recovery_m_value_type type,
+                   u32 m_value, u32 n_value);
  void exynos_dp_set_video_timing_mode(struct exynos_dp_device *dp, u32 
type);
  void exynos_dp_enable_video_master(struct exynos_dp_device *dp, bool 
enable);
  void exynos_dp_start_video(struct exynos_dp_device *dp);
diff --git a/drivers/gpu/drm/exynos/exynos_dp_reg.c 
b/drivers/gpu/drm/exynos/exynos_dp_reg.c
index c1f87a2..9aa483d 100644
--- a/drivers/gpu/drm/exynos/exynos_dp_reg.c
+++ b/drivers/gpu/drm/exynos/exynos_dp_reg.c
@@ -202,8 +202,8 @@ void exynos_dp_set_pll_power_down(struct 
exynos_dp_device *dp, bool enable)
  }

  void exynos_dp_set_analog_power_down(struct exynos_dp_device *dp,
-                enum analog_power_block block,
-                bool enable)
+                     enum analog_power_block block,
+                     bool enable)
  {
      u32 reg;

@@ -399,8 +399,8 @@ void exynos_dp_init_aux(struct exynos_dp_device *dp)
      exynos_dp_reset_aux(dp);

      /* Disable AUX transaction H/W retry */
-    reg = AUX_BIT_PERIOD_EXPECTED_DELAY(3) | AUX_HW_RETRY_COUNT_SEL(0)|
-        AUX_HW_RETRY_INTERVAL_600_MICROSECONDS;
+    reg = AUX_BIT_PERIOD_EXPECTED_DELAY(3) | AUX_HW_RETRY_COUNT_SEL(0) |
+          AUX_HW_RETRY_INTERVAL_600_MICROSECONDS;
      writel(reg, dp->reg_base + EXYNOS_DP_AUX_HW_RETRY_CTL);

      /* Receive AUX Channel DEFER commands equal to DEFFER_COUNT*64 */
@@ -483,8 +483,8 @@ int exynos_dp_start_aux_transaction(struct 
exynos_dp_device *dp)
  }

  int exynos_dp_write_byte_to_dpcd(struct exynos_dp_device *dp,
-                unsigned int reg_addr,
-                unsigned char data)
+                 unsigned int reg_addr,
+                 unsigned char data)
  {
      u32 reg;
      int i;
@@ -519,17 +519,16 @@ int exynos_dp_write_byte_to_dpcd(struct 
exynos_dp_device *dp,
          retval = exynos_dp_start_aux_transaction(dp);
          if (retval == 0)
              break;
-        else
-            dev_dbg(dp->dev, "%s: Aux Transaction fail!\n",
-                __func__);
+
+        dev_dbg(dp->dev, "%s: Aux Transaction fail!\n", __func__);
      }

      return retval;
  }

  int exynos_dp_read_byte_from_dpcd(struct exynos_dp_device *dp,
-                unsigned int reg_addr,
-                unsigned char *data)
+                  unsigned int reg_addr,
+                  unsigned char *data)
  {
      u32 reg;
      int i;
@@ -560,9 +559,8 @@ int exynos_dp_read_byte_from_dpcd(struct 
exynos_dp_device *dp,
          retval = exynos_dp_start_aux_transaction(dp);
          if (retval == 0)
              break;
-        else
-            dev_dbg(dp->dev, "%s: Aux Transaction fail!\n",
-                __func__);
+
+        dev_dbg(dp->dev, "%s: Aux Transaction fail!\n", __func__);
      }

      /* Read data buffer */
@@ -573,9 +571,9 @@ int exynos_dp_read_byte_from_dpcd(struct 
exynos_dp_device *dp,
  }

  int exynos_dp_write_bytes_to_dpcd(struct exynos_dp_device *dp,
-                unsigned int reg_addr,
-                unsigned int count,
-                unsigned char data[])
+                  unsigned int reg_addr,
+                  unsigned int count,
+                  unsigned char data[])
  {
      u32 reg;
      unsigned int start_offset;
@@ -625,9 +623,9 @@ int exynos_dp_write_bytes_to_dpcd(struct 
exynos_dp_device *dp,
              retval = exynos_dp_start_aux_transaction(dp);
              if (retval == 0)
                  break;
-            else
-                dev_dbg(dp->dev, "%s: Aux Transaction fail!\n",
-                    __func__);
+
+            dev_dbg(dp->dev, "%s: Aux Transaction fail!\n",
+                __func__);
          }

          start_offset += cur_data_count;
@@ -637,9 +635,9 @@ int exynos_dp_write_bytes_to_dpcd(struct 
exynos_dp_device *dp,
  }

  int exynos_dp_read_bytes_from_dpcd(struct exynos_dp_device *dp,
-                unsigned int reg_addr,
-                unsigned int count,
-                unsigned char data[])
+                   unsigned int reg_addr,
+                   unsigned int count,
+                   unsigned char data[])
  {
      u32 reg;
      unsigned int start_offset;
@@ -683,9 +681,9 @@ int exynos_dp_read_bytes_from_dpcd(struct 
exynos_dp_device *dp,
              retval = exynos_dp_start_aux_transaction(dp);
              if (retval == 0)
                  break;
-            else
-                dev_dbg(dp->dev, "%s: Aux Transaction fail!\n",
-                    __func__);
+
+            dev_dbg(dp->dev, "%s: Aux Transaction fail!\n",
+                __func__);
          }

          for (cur_data_idx = 0; cur_data_idx < cur_data_count;
@@ -736,9 +734,9 @@ int exynos_dp_select_i2c_device(struct 
exynos_dp_device *dp,
  }

  int exynos_dp_read_byte_from_i2c(struct exynos_dp_device *dp,
-                unsigned int device_addr,
-                unsigned int reg_addr,
-                unsigned int *data)
+                 unsigned int device_addr,
+                 unsigned int reg_addr,
+                 unsigned int *data)
  {
      u32 reg;
      int i;
@@ -767,9 +765,8 @@ int exynos_dp_read_byte_from_i2c(struct 
exynos_dp_device *dp,
          retval = exynos_dp_start_aux_transaction(dp);
          if (retval == 0)
              break;
-        else
-            dev_dbg(dp->dev, "%s: Aux Transaction fail!\n",
-                __func__);
+
+        dev_dbg(dp->dev, "%s: Aux Transaction fail!\n", __func__);
      }

      /* Read data */
@@ -780,10 +777,10 @@ int exynos_dp_read_byte_from_i2c(struct 
exynos_dp_device *dp,
  }

  int exynos_dp_read_bytes_from_i2c(struct exynos_dp_device *dp,
-                unsigned int device_addr,
-                unsigned int reg_addr,
-                unsigned int count,
-                unsigned char edid[])
+                  unsigned int device_addr,
+                  unsigned int reg_addr,
+                  unsigned int count,
+                  unsigned char edid[])
  {
      u32 reg;
      unsigned int i, j;
@@ -807,8 +804,8 @@ int exynos_dp_read_bytes_from_i2c(struct 
exynos_dp_device *dp,
               * request without sending address
               */
              if (!defer)
-                retval = exynos_dp_select_i2c_device(dp,
-                        device_addr, reg_addr + i);
+                retval = exynos_dp_select_i2c_device(
+                        dp, device_addr, reg_addr + i);
              else
                  defer = 0;

@@ -828,15 +825,14 @@ int exynos_dp_read_bytes_from_i2c(struct 
exynos_dp_device *dp,
                  retval = exynos_dp_start_aux_transaction(dp);
                  if (retval == 0)
                      break;
-                else
-                    dev_dbg(dp->dev,
-                        "%s: Aux Transaction fail!\n",
-                        __func__);
+
+                dev_dbg(dp->dev, "%s: Aux Transaction fail!\n",
+                    __func__);
              }
              /* Check if Rx sends defer */
              reg = readl(dp->reg_base + EXYNOS_DP_AUX_RX_COMM);
              if (reg == AUX_RX_COMM_AUX_DEFER ||
-                reg == AUX_RX_COMM_I2C_DEFER) {
+                reg == AUX_RX_COMM_I2C_DEFER) {
                  dev_err(dp->dev, "Defer: %d\n\n", reg);
                  defer = 1;
              }
@@ -901,7 +897,7 @@ void exynos_dp_enable_enhanced_mode(struct 
exynos_dp_device *dp, bool enable)
  }

  void exynos_dp_set_training_pattern(struct exynos_dp_device *dp,
-                 enum pattern_set pattern)
+                    enum pattern_set pattern)
  {
      u32 reg;

@@ -974,7 +970,7 @@ void exynos_dp_set_lane3_pre_emphasis(struct 
exynos_dp_device *dp, u32 level)
  }

  void exynos_dp_set_lane0_link_training(struct exynos_dp_device *dp,
-                    u32 training_lane)
+                       u32 training_lane)
  {
      u32 reg;

@@ -983,7 +979,7 @@ void exynos_dp_set_lane0_link_training(struct 
exynos_dp_device *dp,
  }

  void exynos_dp_set_lane1_link_training(struct exynos_dp_device *dp,
-                    u32 training_lane)
+                       u32 training_lane)
  {
      u32 reg;

@@ -992,7 +988,7 @@ void exynos_dp_set_lane1_link_training(struct 
exynos_dp_device *dp,
  }

  void exynos_dp_set_lane2_link_training(struct exynos_dp_device *dp,
-                    u32 training_lane)
+                       u32 training_lane)
  {
      u32 reg;

@@ -1001,7 +997,7 @@ void exynos_dp_set_lane2_link_training(struct 
exynos_dp_device *dp,
  }

  void exynos_dp_set_lane3_link_training(struct exynos_dp_device *dp,
-                    u32 training_lane)
+                       u32 training_lane)
  {
      u32 reg;

@@ -1125,9 +1121,9 @@ int 
exynos_dp_is_slave_video_stream_clock_on(struct exynos_dp_device *dp)
  }

  void exynos_dp_set_video_cr_mn(struct exynos_dp_device *dp,
-        enum clock_recovery_m_value_type type,
-        u32 m_value,
-        u32 n_value)
+                   enum clock_recovery_m_value_type type,
+                   u32 m_value,
+                   u32 n_value)
  {
      u32 reg;

@@ -1221,7 +1217,7 @@ void exynos_dp_config_video_slave_mode(struct 
exynos_dp_device *dp)
      u32 reg;

      reg = readl(dp->reg_base + EXYNOS_DP_FUNC_EN_1);
-    reg &= ~(MASTER_VID_FUNC_EN_N|SLAVE_VID_FUNC_EN_N);
+    reg &= ~(MASTER_VID_FUNC_EN_N | SLAVE_VID_FUNC_EN_N);
      reg |= MASTER_VID_FUNC_EN_N;
      writel(reg, dp->reg_base + EXYNOS_DP_FUNC_EN_1);

-- 
2.1.2




From vbabka at suse.cz  Thu Aug  6 07:00:33 2015
From: vbabka at suse.cz (Vlastimil Babka)
Date: Thu, 6 Aug 2015 16:00:33 +0200
Subject: [PATCH V6 2/6] mm: mlock: Add new mlock system call
In-Reply-To: <1438184575-10537-3-git-send-email-emunson@akamai.com>
References: <1438184575-10537-1-git-send-email-emunson@akamai.com>
 <1438184575-10537-3-git-send-email-emunson@akamai.com>
Message-ID: <55C36881.8050301@suse.cz>

On 07/29/2015 05:42 PM, Eric B Munson wrote:
> With the refactored mlock code, introduce a new system call for mlock.
> The new call will allow the user to specify what lock states are being
> added.  mlock2 is trivial at the moment, but a follow on patch will add
> a new mlock state making it useful.
>
> Signed-off-by: Eric B Munson <emunson at akamai.com>
> Cc: Michal Hocko <mhocko at suse.cz>
> Cc: Vlastimil Babka <vbabka at suse.cz>

Acked-by: Vlastimil Babka <vbabka at suse.cz>



From scott.shu at mediatek.com  Thu Aug  6 07:00:37 2015
From: scott.shu at mediatek.com (Scott Shu)
Date: Thu, 6 Aug 2015 22:00:37 +0800
Subject: [PATCH v3 5/8] ARM: mediatek: add smp bringup code for MT6580
In-Reply-To: <1801910.hz53dYUgta@ubix>
References: <1438696464-59858-1-git-send-email-scott.shu@mediatek.com>
 <1438696464-59858-6-git-send-email-scott.shu@mediatek.com>
 <1801910.hz53dYUgta@ubix>
Message-ID: <1438869637.1900.6.camel@mtkswgap22>

On Wed, 2015-08-05 at 18:47 +0200, Matthias Brugger wrote:
> On Tuesday, August 04, 2015 09:54:21 PM Scott Shu wrote:
> > Add support for cpu enable-method "mediatek,mt6580-smp" for booting
> > secondary CPUs on MT6580.
> > 
> > Signed-off-by: Scott Shu <scott.shu at mediatek.com>
> > ---
> >  arch/arm/mach-mediatek/platsmp.c |  137
> > ++++++++++++++++++++++++++++++++++++++ 1 file changed, 137 insertions(+)
> > 
> > diff --git a/arch/arm/mach-mediatek/platsmp.c
> > b/arch/arm/mach-mediatek/platsmp.c index a5bc108..94f7865 100644
> > --- a/arch/arm/mach-mediatek/platsmp.c
> > +++ b/arch/arm/mach-mediatek/platsmp.c
> > @@ -21,10 +21,16 @@
> >  #include <linux/of_address.h>
> >  #include <linux/string.h>
> >  #include <linux/threads.h>
> > +#include <linux/delay.h>
> > +#include <asm/cacheflush.h>
> > +
> > +#include <linux/soc/mediatek/scpsys.h>
> > 
> >  #define MTK_MAX_CPU		8
> >  #define MTK_SMP_REG_SIZE	0x1000
> > 
> > +static DEFINE_SPINLOCK(boot_lock);
> > +
> >  struct mtk_smp_boot_info {
> >  	unsigned long smp_base;
> >  	unsigned int jump_reg;
> > @@ -56,6 +62,126 @@ static const struct of_device_id mtk_smp_boot_infos[]
> > __initconst = { static void __iomem *mtk_smp_base;
> >  static const struct mtk_smp_boot_info *mtk_smp_info;
> > 
> > +#ifdef CONFIG_HOTPLUG_CPU
> > +static int mt6580_cpu_kill(unsigned cpu)
> > +{
> > +	int ret;
> > +
> > +	ret = spm_cpu_mtcmos_off(cpu, 1);
> 
> is this function ever called with wfi == 0?

Yes, wfi == 0 at MT6582 "special" dual-core platform, but for MT6580,
wfi is always 1.

> > +	if (ret < 0)
> > +		return 0;
> > +
> > +	return 1;
> > +}
> > +
> > +static void mt6580_cpu_die(unsigned int cpu)
> > +{
> > +	for (;;)
> > +		cpu_do_idle();
> > +}
> > +#endif
> > +
> > +static void write_pen_release(int val)
> > +{
> > +	pen_release = val;
> > +	/* Make sure this is visible to other CPUs */
> > +	smp_wmb();
> > +	sync_cache_w(&pen_release);
> > +}
> > +
> > +/*
> > + * Refer common "pen" secondary release method
> > + */
> > +static int mt6580_boot_secondary(unsigned int cpu, struct task_struct
> > *idle) +{
> > +	unsigned long timeout;
> > +	int ret;
> > +
> > +	/*
> > +	 * Set synchronisation state between this boot processor
> > +	 * and the secondary one
> > +	 */
> > +	spin_lock(&boot_lock);
> > +
> > +	/*
> > +	 * The secondary processor is waiting to be released from
> > +	 * the holding pen - release it, then wait for it to flag
> > +	 * that it has been released by resetting pen_release.
> > +	 *
> > +	 * Note that "pen_release" is the hardware CPU ID, whereas
> > +	 * "cpu" is Linux's internal ID.
> > +	 */
> > +	write_pen_release(cpu);
> > +
> > +	/*
> > +	 * CPU power on control by SPM
> > +	 */
> > +	ret = spm_cpu_mtcmos_on(cpu);
> > +	if (ret < 0) {
> > +		spin_unlock(&boot_lock);
> > +		return -ENXIO;
> > +	}
> > +
> > +	timeout = jiffies + (1 * HZ);
> > +	while (time_before(jiffies, timeout)) {
> > +		/* Read barrier */
> > +		smp_rmb();
> > +
> > +		if (pen_release == -1)
> > +			break;
> > +
> > +		udelay(10);
> > +	}
> > +
> > +	/*
> > +	 * Now the secondary core is starting up let it run its
> > +	 * calibrations, then wait for it to finish
> > +	 */
> > +	spin_unlock(&boot_lock);
> > +
> > +	return (pen_release != -1 ? -ENXIO : 0);
> > +}
> > +
> > +static void mt6580_secondary_init(unsigned int cpu)
> > +{
> > +	/*
> > +	 * Let the primary processor know we're out of the
> > +	 * pen, then head off into the C entry point
> > +	 */
> > +	write_pen_release(-1);
> > +
> > +	/*
> > +	 * Synchronise with the boot thread.
> > +	 */
> > +	spin_lock(&boot_lock);
> > +	spin_unlock(&boot_lock);
> > +}
> > +
> > +#define MT6580_INFRACFG_AO	0x10001000
> > +#define SW_ROM_PD		BIT(31)
> 
> Please put the defines on the beginning of the file.
> SW_ROM_PD bit is the same on other SoCs? I wasn't able to reveal that from the 
> data sheets. If this is MT6580 only, the define should be renamed.
> 

OK, fixed in next version. 

> > +
> > +static void __init mt6580_smp_prepare_cpus(unsigned int max_cpus)
> > +{
> > +	static void __iomem *infracfg_ao_base;
> > +
> > +	infracfg_ao_base = ioremap(MT6580_INFRACFG_AO, 0x1000);
> > +	if (!infracfg_ao_base) {
> > +		pr_err("%s: Unable to map I/O memory\n", __func__);
> > +		return;
> > +	}
> > +
> > +	/* Enable bootrom power down mode */
> > +	writel_relaxed(readl(infracfg_ao_base + 0x804) | SW_ROM_PD,
> > +		       infracfg_ao_base + 0x804);
> 
> Please use a define for the offset.
> I prefer to not cascade reads and writes but to use a temporary variable. But 
> if this is fine with the kernel coding style (I doubt, but I'm not sure) then 
> this is fine.
> 

OK, fixed in next version. 

Thanks,
Scott
> > +
> > +	/* Write the address of slave startup into boot address
> > +	   register for bootrom power down mode */
> > +	writel_relaxed(virt_to_phys(secondary_startup_arm),
> > +		       infracfg_ao_base + 0x800);
> > +
> > +	iounmap(infracfg_ao_base);
> > +}
> > +
> >  static int mtk_boot_secondary(unsigned int cpu, struct task_struct *idle)
> >  {
> >  	if (!mtk_smp_base)
> > @@ -142,3 +268,14 @@ static struct smp_operations mt6589_smp_ops __initdata
> > = { .smp_boot_secondary = mtk_boot_secondary,
> >  };
> >  CPU_METHOD_OF_DECLARE(mt6589_smp, "mediatek,mt6589-smp", &mt6589_smp_ops);
> > +
> > +static struct smp_operations mt6580_smp_ops __initdata = {
> > +	.smp_prepare_cpus = mt6580_smp_prepare_cpus,
> > +	.smp_secondary_init = mt6580_secondary_init,
> > +	.smp_boot_secondary = mt6580_boot_secondary,
> > +#ifdef CONFIG_HOTPLUG_CPU
> > +	.cpu_kill = mt6580_cpu_kill,
> > +	.cpu_die = mt6580_cpu_die,
> > +#endif
> > +};
> > +CPU_METHOD_OF_DECLARE(mt6580_smp, "mediatek,mt6580-smp", &mt6580_smp_ops);
> 




From gregory.clement at free-electrons.com  Thu Aug  6 07:01:26 2015
From: gregory.clement at free-electrons.com (Gregory CLEMENT)
Date: Thu, 06 Aug 2015 16:01:26 +0200
Subject: [PATCH] ARM: Fix the secondary_startup function in Big Endian case
In-Reply-To: <20150806135258.GE7557@n2100.arm.linux.org.uk>
References: <1438860452-6347-1-git-send-email-gregory.clement@free-electrons.com>
 <20150806135258.GE7557@n2100.arm.linux.org.uk>
Message-ID: <55C368B6.4030501@free-electrons.com>

On 06/08/2015 15:52, Russell King - ARM Linux wrote:
> On Thu, Aug 06, 2015 at 01:27:32PM +0200, Gregory CLEMENT wrote:
>> Since the commit "b2c3e38a5471 ARM: redo TTBR setup code for LPAE",
>> the setup code had been reworked. As a result the secondary CPUs
>> failed to come online in Big Endian.
>>
>> As explained by Russell, the new code expected the value in r4/r5 to
>> be the least significant 32bits in r4 and the most significant 32bits
>> in r5. However, in the secondary code, we load this using ldrd, which
>> on BE reverses that.
>>
>> This patch swap r4/r5 after the ldrd. It is done using the xor
>> instructions in order to not use a temporary register.
> 
> Patch looks good to me, thanks.
> 
So I am going to submit it to your patch system and in the same
time I will fix the typo in my comment:

- @ it can be done in 3 step
- @ without using an temp reg
+ @ it can be done in 3 steps
+ @ without using a temp reg.


Thanks,

Gregory


-- 
Gregory Clement, Free Electrons
Kernel, drivers, real-time and embedded Linux
development, consulting, training and support.
http://free-electrons.com


From ykk at rock-chips.com  Thu Aug  6 07:04:26 2015
From: ykk at rock-chips.com (Yakir Yang)
Date: Thu,  6 Aug 2015 09:04:26 -0500
Subject: [RFC PATCH 1/8] drm: exynos/dp: fix code style
In-Reply-To: <1438868947-22132-1-git-send-email-ykk@rock-chips.com>
References: <1438868947-22132-1-git-send-email-ykk@rock-chips.com>
Message-ID: <1438869866-23028-1-git-send-email-ykk@rock-chips.com>

make checkpatch.pl script happy

Signed-off-by: Yakir Yang <ykk at rock-chips.com>
---
 drivers/gpu/drm/exynos/exynos_dp_core.c | 224 ++++++++++++++++----------------
 drivers/gpu/drm/exynos/exynos_dp_core.h |  53 ++++----
 drivers/gpu/drm/exynos/exynos_dp_reg.c  | 100 +++++++-------
 3 files changed, 185 insertions(+), 192 deletions(-)

diff --git a/drivers/gpu/drm/exynos/exynos_dp_core.c b/drivers/gpu/drm/exynos/exynos_dp_core.c
index 172b800..a8097a4 100644
--- a/drivers/gpu/drm/exynos/exynos_dp_core.c
+++ b/drivers/gpu/drm/exynos/exynos_dp_core.c
@@ -114,8 +114,8 @@ static int exynos_dp_read_edid(struct exynos_dp_device *dp)
 
 	/* Read Extension Flag, Number of 128-byte EDID extension blocks */
 	retval = exynos_dp_read_byte_from_i2c(dp, I2C_EDID_DEVICE_ADDR,
-				EDID_EXTENSION_FLAG,
-				&extend_block);
+					      EDID_EXTENSION_FLAG,
+					      &extend_block);
 	if (retval)
 		return retval;
 
@@ -123,10 +123,11 @@ static int exynos_dp_read_edid(struct exynos_dp_device *dp)
 		dev_dbg(dp->dev, "EDID data includes a single extension!\n");
 
 		/* Read EDID data */
-		retval = exynos_dp_read_bytes_from_i2c(dp, I2C_EDID_DEVICE_ADDR,
-						EDID_HEADER_PATTERN,
-						EDID_BLOCK_LENGTH,
-						&edid[EDID_HEADER_PATTERN]);
+		retval =
+		exynos_dp_read_bytes_from_i2c(dp, I2C_EDID_DEVICE_ADDR,
+					      EDID_HEADER_PATTERN,
+					      EDID_BLOCK_LENGTH,
+					      &edid[EDID_HEADER_PATTERN]);
 		if (retval != 0) {
 			dev_err(dp->dev, "EDID Read failed!\n");
 			return -EIO;
@@ -138,11 +139,11 @@ static int exynos_dp_read_edid(struct exynos_dp_device *dp)
 		}
 
 		/* Read additional EDID data */
-		retval = exynos_dp_read_bytes_from_i2c(dp,
-				I2C_EDID_DEVICE_ADDR,
-				EDID_BLOCK_LENGTH,
-				EDID_BLOCK_LENGTH,
-				&edid[EDID_BLOCK_LENGTH]);
+		retval =
+		exynos_dp_read_bytes_from_i2c(dp, I2C_EDID_DEVICE_ADDR,
+					      EDID_BLOCK_LENGTH,
+					      EDID_BLOCK_LENGTH,
+					      &edid[EDID_BLOCK_LENGTH]);
 		if (retval != 0) {
 			dev_err(dp->dev, "EDID Read failed!\n");
 			return -EIO;
@@ -154,24 +155,22 @@ static int exynos_dp_read_edid(struct exynos_dp_device *dp)
 		}
 
 		exynos_dp_read_byte_from_dpcd(dp, DP_TEST_REQUEST,
-					&test_vector);
+					      &test_vector);
 		if (test_vector & DP_TEST_LINK_EDID_READ) {
-			exynos_dp_write_byte_to_dpcd(dp,
-				DP_TEST_EDID_CHECKSUM,
+			exynos_dp_write_byte_to_dpcd(
+				dp, DP_TEST_EDID_CHECKSUM,
 				edid[EDID_BLOCK_LENGTH + EDID_CHECKSUM]);
-			exynos_dp_write_byte_to_dpcd(dp,
-				DP_TEST_RESPONSE,
+			exynos_dp_write_byte_to_dpcd(
+				dp, DP_TEST_RESPONSE,
 				DP_TEST_EDID_CHECKSUM_WRITE);
 		}
 	} else {
 		dev_info(dp->dev, "EDID data does not include any extensions.\n");
 
 		/* Read EDID data */
-		retval = exynos_dp_read_bytes_from_i2c(dp,
-				I2C_EDID_DEVICE_ADDR,
-				EDID_HEADER_PATTERN,
-				EDID_BLOCK_LENGTH,
-				&edid[EDID_HEADER_PATTERN]);
+		retval = exynos_dp_read_bytes_from_i2c(
+				dp, I2C_EDID_DEVICE_ADDR, EDID_HEADER_PATTERN,
+				EDID_BLOCK_LENGTH, &edid[EDID_HEADER_PATTERN]);
 		if (retval != 0) {
 			dev_err(dp->dev, "EDID Read failed!\n");
 			return -EIO;
@@ -182,16 +181,15 @@ static int exynos_dp_read_edid(struct exynos_dp_device *dp)
 			return -EIO;
 		}
 
-		exynos_dp_read_byte_from_dpcd(dp,
-			DP_TEST_REQUEST,
-			&test_vector);
+		exynos_dp_read_byte_from_dpcd(dp, DP_TEST_REQUEST,
+					      &test_vector);
 		if (test_vector & DP_TEST_LINK_EDID_READ) {
-			exynos_dp_write_byte_to_dpcd(dp,
-				DP_TEST_EDID_CHECKSUM,
-				edid[EDID_CHECKSUM]);
-			exynos_dp_write_byte_to_dpcd(dp,
-				DP_TEST_RESPONSE,
-				DP_TEST_EDID_CHECKSUM_WRITE);
+			exynos_dp_write_byte_to_dpcd(
+					dp, DP_TEST_EDID_CHECKSUM,
+					edid[EDID_CHECKSUM]);
+			exynos_dp_write_byte_to_dpcd(
+					dp, DP_TEST_RESPONSE,
+					DP_TEST_EDID_CHECKSUM_WRITE);
 		}
 	}
 
@@ -206,8 +204,7 @@ static int exynos_dp_handle_edid(struct exynos_dp_device *dp)
 	int retval;
 
 	/* Read DPCD DP_DPCD_REV~RECEIVE_PORT1_CAP_1 */
-	retval = exynos_dp_read_bytes_from_dpcd(dp, DP_DPCD_REV,
-				12, buf);
+	retval = exynos_dp_read_bytes_from_dpcd(dp, DP_DPCD_REV, 12, buf);
 	if (retval)
 		return retval;
 
@@ -222,19 +219,21 @@ static int exynos_dp_handle_edid(struct exynos_dp_device *dp)
 }
 
 static void exynos_dp_enable_rx_to_enhanced_mode(struct exynos_dp_device *dp,
-						bool enable)
+						 bool enable)
 {
 	u8 data;
 
 	exynos_dp_read_byte_from_dpcd(dp, DP_LANE_COUNT_SET, &data);
 
 	if (enable)
-		exynos_dp_write_byte_to_dpcd(dp, DP_LANE_COUNT_SET,
-			DP_LANE_COUNT_ENHANCED_FRAME_EN |
-			DPCD_LANE_COUNT_SET(data));
+		exynos_dp_write_byte_to_dpcd(
+					dp, DP_LANE_COUNT_SET,
+					DP_LANE_COUNT_ENHANCED_FRAME_EN |
+					DPCD_LANE_COUNT_SET(data));
 	else
-		exynos_dp_write_byte_to_dpcd(dp, DP_LANE_COUNT_SET,
-			DPCD_LANE_COUNT_SET(data));
+		exynos_dp_write_byte_to_dpcd(
+					dp, DP_LANE_COUNT_SET,
+					DPCD_LANE_COUNT_SET(data));
 }
 
 static int exynos_dp_is_enhanced_mode_available(struct exynos_dp_device *dp)
@@ -261,13 +260,12 @@ static void exynos_dp_training_pattern_dis(struct exynos_dp_device *dp)
 {
 	exynos_dp_set_training_pattern(dp, DP_NONE);
 
-	exynos_dp_write_byte_to_dpcd(dp,
-		DP_TRAINING_PATTERN_SET,
-		DP_TRAINING_PATTERN_DISABLE);
+	exynos_dp_write_byte_to_dpcd(dp, DP_TRAINING_PATTERN_SET,
+				     DP_TRAINING_PATTERN_DISABLE);
 }
 
 static void exynos_dp_set_lane_lane_pre_emphasis(struct exynos_dp_device *dp,
-					int pre_emphasis, int lane)
+						 int pre_emphasis, int lane)
 {
 	switch (lane) {
 	case 0:
@@ -307,15 +305,14 @@ static int exynos_dp_link_start(struct exynos_dp_device *dp)
 	/* Setup RX configuration */
 	buf[0] = dp->link_train.link_rate;
 	buf[1] = dp->link_train.lane_count;
-	retval = exynos_dp_write_bytes_to_dpcd(dp, DP_LINK_BW_SET,
-				2, buf);
+	retval = exynos_dp_write_bytes_to_dpcd(dp, DP_LINK_BW_SET, 2, buf);
 	if (retval)
 		return retval;
 
 	/* Set TX pre-emphasis to minimum */
 	for (lane = 0; lane < lane_count; lane++)
-		exynos_dp_set_lane_lane_pre_emphasis(dp,
-			PRE_EMPHASIS_LEVEL_0, lane);
+		exynos_dp_set_lane_lane_pre_emphasis(dp, PRE_EMPHASIS_LEVEL_0,
+						     lane);
 
 	/* Wait for PLL lock */
 	pll_tries = 0;
@@ -333,9 +330,9 @@ static int exynos_dp_link_start(struct exynos_dp_device *dp)
 	exynos_dp_set_training_pattern(dp, TRAINING_PTN1);
 
 	/* Set RX training pattern */
-	retval = exynos_dp_write_byte_to_dpcd(dp,
-			DP_TRAINING_PATTERN_SET,
-			DP_LINK_SCRAMBLING_DISABLE | DP_TRAINING_PATTERN_1);
+	retval = exynos_dp_write_byte_to_dpcd(dp, DP_TRAINING_PATTERN_SET,
+					      DP_LINK_SCRAMBLING_DISABLE |
+					      DP_TRAINING_PATTERN_1);
 	if (retval)
 		return retval;
 
@@ -344,7 +341,7 @@ static int exynos_dp_link_start(struct exynos_dp_device *dp)
 			    DP_TRAIN_VOLTAGE_SWING_LEVEL_0;
 
 	retval = exynos_dp_write_bytes_to_dpcd(dp, DP_TRAINING_LANE0_SET,
-			lane_count, buf);
+					       lane_count, buf);
 
 	return retval;
 }
@@ -352,7 +349,7 @@ static int exynos_dp_link_start(struct exynos_dp_device *dp)
 static unsigned char exynos_dp_get_lane_status(u8 link_status[2], int lane)
 {
 	int shift = (lane & 1) * 4;
-	u8 link_value = link_status[lane>>1];
+	u8 link_value = link_status[lane >> 1];
 
 	return (link_value >> shift) & 0xf;
 }
@@ -371,7 +368,7 @@ static int exynos_dp_clock_recovery_ok(u8 link_status[2], int lane_count)
 }
 
 static int exynos_dp_channel_eq_ok(u8 link_status[2], u8 link_align,
-				int lane_count)
+				   int lane_count)
 {
 	int lane;
 	u8 lane_status;
@@ -390,10 +387,10 @@ static int exynos_dp_channel_eq_ok(u8 link_status[2], u8 link_align,
 }
 
 static unsigned char exynos_dp_get_adjust_request_voltage(u8 adjust_request[2],
-							int lane)
+							  int lane)
 {
 	int shift = (lane & 1) * 4;
-	u8 link_value = adjust_request[lane>>1];
+	u8 link_value = adjust_request[lane >> 1];
 
 	return (link_value >> shift) & 0x3;
 }
@@ -403,13 +400,13 @@ static unsigned char exynos_dp_get_adjust_request_pre_emphasis(
 					int lane)
 {
 	int shift = (lane & 1) * 4;
-	u8 link_value = adjust_request[lane>>1];
+	u8 link_value = adjust_request[lane >> 1];
 
 	return ((link_value >> shift) & 0xc) >> 2;
 }
 
 static void exynos_dp_set_lane_link_training(struct exynos_dp_device *dp,
-					u8 training_lane_set, int lane)
+					     u8 training_lane_set, int lane)
 {
 	switch (lane) {
 	case 0:
@@ -465,7 +462,7 @@ static void exynos_dp_reduce_link_rate(struct exynos_dp_device *dp)
 }
 
 static void exynos_dp_get_adjust_training_lane(struct exynos_dp_device *dp,
-					u8 adjust_request[2])
+					       u8 adjust_request[2])
 {
 	int lane, lane_count;
 	u8 voltage_swing, pre_emphasis, training_lane;
@@ -498,13 +495,13 @@ static int exynos_dp_process_clock_recovery(struct exynos_dp_device *dp)
 
 	lane_count = dp->link_train.lane_count;
 
-	retval =  exynos_dp_read_bytes_from_dpcd(dp,
-			DP_LANE0_1_STATUS, 2, link_status);
+	retval =  exynos_dp_read_bytes_from_dpcd(dp, DP_LANE0_1_STATUS,
+						 2, link_status);
 	if (retval)
 		return retval;
 
-	retval =  exynos_dp_read_bytes_from_dpcd(dp,
-			DP_ADJUST_REQUEST_LANE0_1, 2, adjust_request);
+	retval =  exynos_dp_read_bytes_from_dpcd(dp, DP_ADJUST_REQUEST_LANE0_1,
+						 2, adjust_request);
 	if (retval)
 		return retval;
 
@@ -512,8 +509,8 @@ static int exynos_dp_process_clock_recovery(struct exynos_dp_device *dp)
 		/* set training pattern 2 for EQ */
 		exynos_dp_set_training_pattern(dp, TRAINING_PTN2);
 
-		retval = exynos_dp_write_byte_to_dpcd(dp,
-				DP_TRAINING_PATTERN_SET,
+		retval = exynos_dp_write_byte_to_dpcd(
+				dp, DP_TRAINING_PATTERN_SET,
 				DP_LINK_SCRAMBLING_DISABLE |
 				DP_TRAINING_PATTERN_2);
 		if (retval)
@@ -527,8 +524,9 @@ static int exynos_dp_process_clock_recovery(struct exynos_dp_device *dp)
 							dp, lane);
 			voltage_swing = exynos_dp_get_adjust_request_voltage(
 							adjust_request, lane);
-			pre_emphasis = exynos_dp_get_adjust_request_pre_emphasis(
-							adjust_request, lane);
+			pre_emphasis =
+				exynos_dp_get_adjust_request_pre_emphasis(
+						adjust_request, lane);
 
 			if (DPCD_VOLTAGE_SWING_GET(training_lane) ==
 					voltage_swing &&
@@ -551,11 +549,11 @@ static int exynos_dp_process_clock_recovery(struct exynos_dp_device *dp)
 	exynos_dp_get_adjust_training_lane(dp, adjust_request);
 
 	for (lane = 0; lane < lane_count; lane++)
-		exynos_dp_set_lane_link_training(dp,
-			dp->link_train.training_lane[lane], lane);
+		exynos_dp_set_lane_link_training(
+				dp, dp->link_train.training_lane[lane], lane);
 
-	retval = exynos_dp_write_bytes_to_dpcd(dp,
-			DP_TRAINING_LANE0_SET, lane_count,
+	retval = exynos_dp_write_bytes_to_dpcd(
+			dp, DP_TRAINING_LANE0_SET, lane_count,
 			dp->link_train.training_lane);
 	if (retval)
 		return retval;
@@ -573,8 +571,8 @@ static int exynos_dp_process_equalizer_training(struct exynos_dp_device *dp)
 
 	lane_count = dp->link_train.lane_count;
 
-	retval = exynos_dp_read_bytes_from_dpcd(dp,
-			DP_LANE0_1_STATUS, 2, link_status);
+	retval = exynos_dp_read_bytes_from_dpcd(dp, DP_LANE0_1_STATUS,
+						2, link_status);
 	if (retval)
 		return retval;
 
@@ -583,13 +581,13 @@ static int exynos_dp_process_equalizer_training(struct exynos_dp_device *dp)
 		return -EIO;
 	}
 
-	retval = exynos_dp_read_bytes_from_dpcd(dp,
-			DP_ADJUST_REQUEST_LANE0_1, 2, adjust_request);
+	retval = exynos_dp_read_bytes_from_dpcd(dp, DP_ADJUST_REQUEST_LANE0_1,
+						2, adjust_request);
 	if (retval)
 		return retval;
 
-	retval = exynos_dp_read_byte_from_dpcd(dp,
-			DP_LANE_ALIGN_STATUS_UPDATED, &link_align);
+	retval = exynos_dp_read_byte_from_dpcd(
+			dp, DP_LANE_ALIGN_STATUS_UPDATED, &link_align);
 	if (retval)
 		return retval;
 
@@ -628,17 +626,18 @@ static int exynos_dp_process_equalizer_training(struct exynos_dp_device *dp)
 	}
 
 	for (lane = 0; lane < lane_count; lane++)
-		exynos_dp_set_lane_link_training(dp,
-			dp->link_train.training_lane[lane], lane);
+		exynos_dp_set_lane_link_training(
+				dp, dp->link_train.training_lane[lane], lane);
 
 	retval = exynos_dp_write_bytes_to_dpcd(dp, DP_TRAINING_LANE0_SET,
-			lane_count, dp->link_train.training_lane);
+					       lane_count,
+					       dp->link_train.training_lane);
 
 	return retval;
 }
 
 static void exynos_dp_get_max_rx_bandwidth(struct exynos_dp_device *dp,
-					u8 *bandwidth)
+					   u8 *bandwidth)
 {
 	u8 data;
 
@@ -651,7 +650,7 @@ static void exynos_dp_get_max_rx_bandwidth(struct exynos_dp_device *dp,
 }
 
 static void exynos_dp_get_max_rx_lane_count(struct exynos_dp_device *dp,
-					u8 *lane_count)
+					    u8 *lane_count)
 {
 	u8 data;
 
@@ -664,8 +663,8 @@ static void exynos_dp_get_max_rx_lane_count(struct exynos_dp_device *dp,
 }
 
 static void exynos_dp_init_training(struct exynos_dp_device *dp,
-			enum link_lane_count_type max_lane,
-			enum link_rate_type max_rate)
+				    enum link_lane_count_type max_lane,
+				    enum link_rate_type max_rate)
 {
 	/*
 	 * MACRO_RST must be applied after the PLL_LOCK to avoid
@@ -678,7 +677,7 @@ static void exynos_dp_init_training(struct exynos_dp_device *dp,
 	exynos_dp_get_max_rx_lane_count(dp, &dp->link_train.lane_count);
 
 	if ((dp->link_train.link_rate != LINK_RATE_1_62GBPS) &&
-	   (dp->link_train.link_rate != LINK_RATE_2_70GBPS)) {
+	    (dp->link_train.link_rate != LINK_RATE_2_70GBPS)) {
 		dev_err(dp->dev, "Rx Max Link Rate is abnormal :%x !\n",
 			dp->link_train.link_rate);
 		dp->link_train.link_rate = LINK_RATE_1_62GBPS;
@@ -738,8 +737,7 @@ static int exynos_dp_sw_link_training(struct exynos_dp_device *dp)
 }
 
 static int exynos_dp_set_link_train(struct exynos_dp_device *dp,
-				u32 count,
-				u32 bwtype)
+				    u32 count, u32 bwtype)
 {
 	int i;
 	int retval;
@@ -830,21 +828,19 @@ static void exynos_dp_enable_scramble(struct exynos_dp_device *dp, bool enable)
 	if (enable) {
 		exynos_dp_enable_scrambling(dp);
 
-		exynos_dp_read_byte_from_dpcd(dp,
-			DP_TRAINING_PATTERN_SET,
-			&data);
-		exynos_dp_write_byte_to_dpcd(dp,
-			DP_TRAINING_PATTERN_SET,
+		exynos_dp_read_byte_from_dpcd(dp, DP_TRAINING_PATTERN_SET,
+					      &data);
+		exynos_dp_write_byte_to_dpcd(
+			dp, DP_TRAINING_PATTERN_SET,
 			(u8)(data & ~DP_LINK_SCRAMBLING_DISABLE));
 	} else {
 		exynos_dp_disable_scrambling(dp);
 
-		exynos_dp_read_byte_from_dpcd(dp,
-			DP_TRAINING_PATTERN_SET,
-			&data);
-		exynos_dp_write_byte_to_dpcd(dp,
-			DP_TRAINING_PATTERN_SET,
-			(u8)(data | DP_LINK_SCRAMBLING_DISABLE));
+		exynos_dp_read_byte_from_dpcd(dp, DP_TRAINING_PATTERN_SET,
+					      &data);
+		exynos_dp_write_byte_to_dpcd(
+				dp, DP_TRAINING_PATTERN_SET,
+				(u8)(data | DP_LINK_SCRAMBLING_DISABLE));
 	}
 }
 
@@ -915,7 +911,7 @@ static void exynos_dp_commit(struct exynos_drm_display *display)
 	}
 
 	ret = exynos_dp_set_link_train(dp, dp->video_info->lane_count,
-					dp->video_info->link_rate);
+				       dp->video_info->link_rate);
 	if (ret) {
 		dev_err(dp->dev, "unable to do link train\n");
 		return;
@@ -1004,7 +1000,7 @@ static struct drm_connector_helper_funcs exynos_dp_connector_helper_funcs = {
 
 /* returns the number of bridges attached */
 static int exynos_drm_attach_lcd_bridge(struct exynos_dp_device *dp,
-		struct drm_encoder *encoder)
+					struct drm_encoder *encoder)
 {
 	int ret;
 
@@ -1020,7 +1016,7 @@ static int exynos_drm_attach_lcd_bridge(struct exynos_dp_device *dp,
 }
 
 static int exynos_dp_create_connector(struct exynos_drm_display *display,
-				struct drm_encoder *encoder)
+				      struct drm_encoder *encoder)
 {
 	struct exynos_dp_device *dp = display_to_dp(display);
 	struct drm_connector *connector = &dp->connector;
@@ -1038,7 +1034,8 @@ static int exynos_dp_create_connector(struct exynos_drm_display *display,
 	connector->polled = DRM_CONNECTOR_POLL_HPD;
 
 	ret = drm_connector_init(dp->drm_dev, connector,
-			&exynos_dp_connector_funcs, DRM_MODE_CONNECTOR_eDP);
+				 &exynos_dp_connector_funcs,
+				 DRM_MODE_CONNECTOR_eDP);
 	if (ret) {
 		DRM_ERROR("Failed to initialize connector with drm\n");
 		return ret;
@@ -1148,8 +1145,8 @@ static struct video_info *exynos_dp_dt_parse_pdata(struct device *dev)
 	struct device_node *dp_node = dev->of_node;
 	struct video_info *dp_video_config;
 
-	dp_video_config = devm_kzalloc(dev,
-				sizeof(*dp_video_config), GFP_KERNEL);
+	dp_video_config = devm_kzalloc(dev, sizeof(*dp_video_config),
+				       GFP_KERNEL);
 	if (!dp_video_config)
 		return ERR_PTR(-ENOMEM);
 
@@ -1163,37 +1160,37 @@ static struct video_info *exynos_dp_dt_parse_pdata(struct device *dev)
 		of_property_read_bool(dp_node, "interlaced");
 
 	if (of_property_read_u32(dp_node, "samsung,color-space",
-				&dp_video_config->color_space)) {
+				 &dp_video_config->color_space)) {
 		dev_err(dev, "failed to get color-space\n");
 		return ERR_PTR(-EINVAL);
 	}
 
 	if (of_property_read_u32(dp_node, "samsung,dynamic-range",
-				&dp_video_config->dynamic_range)) {
+				 &dp_video_config->dynamic_range)) {
 		dev_err(dev, "failed to get dynamic-range\n");
 		return ERR_PTR(-EINVAL);
 	}
 
 	if (of_property_read_u32(dp_node, "samsung,ycbcr-coeff",
-				&dp_video_config->ycbcr_coeff)) {
+				 &dp_video_config->ycbcr_coeff)) {
 		dev_err(dev, "failed to get ycbcr-coeff\n");
 		return ERR_PTR(-EINVAL);
 	}
 
 	if (of_property_read_u32(dp_node, "samsung,color-depth",
-				&dp_video_config->color_depth)) {
+				 &dp_video_config->color_depth)) {
 		dev_err(dev, "failed to get color-depth\n");
 		return ERR_PTR(-EINVAL);
 	}
 
 	if (of_property_read_u32(dp_node, "samsung,link-rate",
-				&dp_video_config->link_rate)) {
+				 &dp_video_config->link_rate)) {
 		dev_err(dev, "failed to get link-rate\n");
 		return ERR_PTR(-EINVAL);
 	}
 
 	if (of_property_read_u32(dp_node, "samsung,lane-count",
-				&dp_video_config->lane_count)) {
+				 &dp_video_config->lane_count)) {
 		dev_err(dev, "failed to get lane-count\n");
 		return ERR_PTR(-EINVAL);
 	}
@@ -1206,7 +1203,7 @@ static int exynos_dp_dt_parse_panel(struct exynos_dp_device *dp)
 	int ret;
 
 	ret = of_get_videomode(dp->dev->of_node, &dp->priv.vm,
-			OF_USE_NATIVE_MODE);
+			       OF_USE_NATIVE_MODE);
 	if (ret) {
 		DRM_ERROR("failed: of_get_videomode() : %d\n", ret);
 		return ret;
@@ -1302,7 +1299,7 @@ static int exynos_dp_bind(struct device *dev, struct device *master, void *data)
 	exynos_dp_init_dp(dp);
 
 	ret = devm_request_irq(&pdev->dev, dp->irq, exynos_dp_irq_handler,
-			irq_flags, "exynos-dp", dp);
+			       irq_flags, "exynos-dp", dp);
 	if (ret) {
 		dev_err(&pdev->dev, "failed to request irq\n");
 		return ret;
@@ -1315,7 +1312,7 @@ static int exynos_dp_bind(struct device *dev, struct device *master, void *data)
 }
 
 static void exynos_dp_unbind(struct device *dev, struct device *master,
-				void *data)
+			     void *data)
 {
 	struct exynos_dp_device *dp = dev_get_drvdata(dev);
 
@@ -1334,7 +1331,7 @@ static int exynos_dp_probe(struct platform_device *pdev)
 	struct exynos_dp_device *dp;
 
 	dp = devm_kzalloc(&pdev->dev, sizeof(struct exynos_dp_device),
-				GFP_KERNEL);
+			  GFP_KERNEL);
 	if (!dp)
 		return -ENOMEM;
 
@@ -1358,8 +1355,9 @@ static int exynos_dp_probe(struct platform_device *pdev)
 			of_node_put(bridge_node);
 			if (!dp->bridge)
 				return -EPROBE_DEFER;
-		} else
+		} else {
 			return -EPROBE_DEFER;
+		}
 	}
 
 	return component_add(&pdev->dev, &exynos_dp_ops);
diff --git a/drivers/gpu/drm/exynos/exynos_dp_core.h b/drivers/gpu/drm/exynos/exynos_dp_core.h
index a4e7996..c321ad5 100644
--- a/drivers/gpu/drm/exynos/exynos_dp_core.h
+++ b/drivers/gpu/drm/exynos/exynos_dp_core.h
@@ -180,8 +180,8 @@ void exynos_dp_config_interrupt(struct exynos_dp_device *dp);
 enum pll_status exynos_dp_get_pll_lock_status(struct exynos_dp_device *dp);
 void exynos_dp_set_pll_power_down(struct exynos_dp_device *dp, bool enable);
 void exynos_dp_set_analog_power_down(struct exynos_dp_device *dp,
-				enum analog_power_block block,
-				bool enable);
+				     enum analog_power_block block,
+				     bool enable);
 void exynos_dp_init_analog_func(struct exynos_dp_device *dp);
 void exynos_dp_init_hpd(struct exynos_dp_device *dp);
 enum dp_irq_type exynos_dp_get_irq_type(struct exynos_dp_device *dp);
@@ -192,50 +192,50 @@ int exynos_dp_get_plug_in_status(struct exynos_dp_device *dp);
 void exynos_dp_enable_sw_function(struct exynos_dp_device *dp);
 int exynos_dp_start_aux_transaction(struct exynos_dp_device *dp);
 int exynos_dp_write_byte_to_dpcd(struct exynos_dp_device *dp,
-				unsigned int reg_addr,
-				unsigned char data);
+				 unsigned int reg_addr,
+				 unsigned char data);
 int exynos_dp_read_byte_from_dpcd(struct exynos_dp_device *dp,
-				unsigned int reg_addr,
-				unsigned char *data);
+				  unsigned int reg_addr,
+				  unsigned char *data);
 int exynos_dp_write_bytes_to_dpcd(struct exynos_dp_device *dp,
-				unsigned int reg_addr,
-				unsigned int count,
-				unsigned char data[]);
+				  unsigned int reg_addr,
+				  unsigned int count,
+				  unsigned char data[]);
 int exynos_dp_read_bytes_from_dpcd(struct exynos_dp_device *dp,
-				unsigned int reg_addr,
-				unsigned int count,
-				unsigned char data[]);
+				   unsigned int reg_addr,
+				   unsigned int count,
+				   unsigned char data[]);
 int exynos_dp_select_i2c_device(struct exynos_dp_device *dp,
 				unsigned int device_addr,
 				unsigned int reg_addr);
 int exynos_dp_read_byte_from_i2c(struct exynos_dp_device *dp,
-				unsigned int device_addr,
-				unsigned int reg_addr,
-				unsigned int *data);
+				 unsigned int device_addr,
+				 unsigned int reg_addr,
+				 unsigned int *data);
 int exynos_dp_read_bytes_from_i2c(struct exynos_dp_device *dp,
-				unsigned int device_addr,
-				unsigned int reg_addr,
-				unsigned int count,
-				unsigned char edid[]);
+				  unsigned int device_addr,
+				  unsigned int reg_addr,
+				  unsigned int count,
+				  unsigned char edid[]);
 void exynos_dp_set_link_bandwidth(struct exynos_dp_device *dp, u32 bwtype);
 void exynos_dp_get_link_bandwidth(struct exynos_dp_device *dp, u32 *bwtype);
 void exynos_dp_set_lane_count(struct exynos_dp_device *dp, u32 count);
 void exynos_dp_get_lane_count(struct exynos_dp_device *dp, u32 *count);
 void exynos_dp_enable_enhanced_mode(struct exynos_dp_device *dp, bool enable);
 void exynos_dp_set_training_pattern(struct exynos_dp_device *dp,
-				 enum pattern_set pattern);
+				    enum pattern_set pattern);
 void exynos_dp_set_lane0_pre_emphasis(struct exynos_dp_device *dp, u32 level);
 void exynos_dp_set_lane1_pre_emphasis(struct exynos_dp_device *dp, u32 level);
 void exynos_dp_set_lane2_pre_emphasis(struct exynos_dp_device *dp, u32 level);
 void exynos_dp_set_lane3_pre_emphasis(struct exynos_dp_device *dp, u32 level);
 void exynos_dp_set_lane0_link_training(struct exynos_dp_device *dp,
-				u32 training_lane);
+				       u32 training_lane);
 void exynos_dp_set_lane1_link_training(struct exynos_dp_device *dp,
-				u32 training_lane);
+				       u32 training_lane);
 void exynos_dp_set_lane2_link_training(struct exynos_dp_device *dp,
-				u32 training_lane);
+				       u32 training_lane);
 void exynos_dp_set_lane3_link_training(struct exynos_dp_device *dp,
-				u32 training_lane);
+				       u32 training_lane);
 u32 exynos_dp_get_lane0_link_training(struct exynos_dp_device *dp);
 u32 exynos_dp_get_lane1_link_training(struct exynos_dp_device *dp);
 u32 exynos_dp_get_lane2_link_training(struct exynos_dp_device *dp);
@@ -246,9 +246,8 @@ void exynos_dp_init_video(struct exynos_dp_device *dp);
 void exynos_dp_set_video_color_format(struct exynos_dp_device *dp);
 int exynos_dp_is_slave_video_stream_clock_on(struct exynos_dp_device *dp);
 void exynos_dp_set_video_cr_mn(struct exynos_dp_device *dp,
-			enum clock_recovery_m_value_type type,
-			u32 m_value,
-			u32 n_value);
+			       enum clock_recovery_m_value_type type,
+			       u32 m_value, u32 n_value);
 void exynos_dp_set_video_timing_mode(struct exynos_dp_device *dp, u32 type);
 void exynos_dp_enable_video_master(struct exynos_dp_device *dp, bool enable);
 void exynos_dp_start_video(struct exynos_dp_device *dp);
diff --git a/drivers/gpu/drm/exynos/exynos_dp_reg.c b/drivers/gpu/drm/exynos/exynos_dp_reg.c
index c1f87a2..9aa483d 100644
--- a/drivers/gpu/drm/exynos/exynos_dp_reg.c
+++ b/drivers/gpu/drm/exynos/exynos_dp_reg.c
@@ -202,8 +202,8 @@ void exynos_dp_set_pll_power_down(struct exynos_dp_device *dp, bool enable)
 }
 
 void exynos_dp_set_analog_power_down(struct exynos_dp_device *dp,
-				enum analog_power_block block,
-				bool enable)
+				     enum analog_power_block block,
+				     bool enable)
 {
 	u32 reg;
 
@@ -399,8 +399,8 @@ void exynos_dp_init_aux(struct exynos_dp_device *dp)
 	exynos_dp_reset_aux(dp);
 
 	/* Disable AUX transaction H/W retry */
-	reg = AUX_BIT_PERIOD_EXPECTED_DELAY(3) | AUX_HW_RETRY_COUNT_SEL(0)|
-		AUX_HW_RETRY_INTERVAL_600_MICROSECONDS;
+	reg = AUX_BIT_PERIOD_EXPECTED_DELAY(3) | AUX_HW_RETRY_COUNT_SEL(0) |
+	      AUX_HW_RETRY_INTERVAL_600_MICROSECONDS;
 	writel(reg, dp->reg_base + EXYNOS_DP_AUX_HW_RETRY_CTL);
 
 	/* Receive AUX Channel DEFER commands equal to DEFFER_COUNT*64 */
@@ -483,8 +483,8 @@ int exynos_dp_start_aux_transaction(struct exynos_dp_device *dp)
 }
 
 int exynos_dp_write_byte_to_dpcd(struct exynos_dp_device *dp,
-				unsigned int reg_addr,
-				unsigned char data)
+				 unsigned int reg_addr,
+				 unsigned char data)
 {
 	u32 reg;
 	int i;
@@ -519,17 +519,16 @@ int exynos_dp_write_byte_to_dpcd(struct exynos_dp_device *dp,
 		retval = exynos_dp_start_aux_transaction(dp);
 		if (retval == 0)
 			break;
-		else
-			dev_dbg(dp->dev, "%s: Aux Transaction fail!\n",
-				__func__);
+
+		dev_dbg(dp->dev, "%s: Aux Transaction fail!\n", __func__);
 	}
 
 	return retval;
 }
 
 int exynos_dp_read_byte_from_dpcd(struct exynos_dp_device *dp,
-				unsigned int reg_addr,
-				unsigned char *data)
+				  unsigned int reg_addr,
+				  unsigned char *data)
 {
 	u32 reg;
 	int i;
@@ -560,9 +559,8 @@ int exynos_dp_read_byte_from_dpcd(struct exynos_dp_device *dp,
 		retval = exynos_dp_start_aux_transaction(dp);
 		if (retval == 0)
 			break;
-		else
-			dev_dbg(dp->dev, "%s: Aux Transaction fail!\n",
-				__func__);
+
+		dev_dbg(dp->dev, "%s: Aux Transaction fail!\n", __func__);
 	}
 
 	/* Read data buffer */
@@ -573,9 +571,9 @@ int exynos_dp_read_byte_from_dpcd(struct exynos_dp_device *dp,
 }
 
 int exynos_dp_write_bytes_to_dpcd(struct exynos_dp_device *dp,
-				unsigned int reg_addr,
-				unsigned int count,
-				unsigned char data[])
+				  unsigned int reg_addr,
+				  unsigned int count,
+				  unsigned char data[])
 {
 	u32 reg;
 	unsigned int start_offset;
@@ -625,9 +623,9 @@ int exynos_dp_write_bytes_to_dpcd(struct exynos_dp_device *dp,
 			retval = exynos_dp_start_aux_transaction(dp);
 			if (retval == 0)
 				break;
-			else
-				dev_dbg(dp->dev, "%s: Aux Transaction fail!\n",
-					__func__);
+
+			dev_dbg(dp->dev, "%s: Aux Transaction fail!\n",
+				__func__);
 		}
 
 		start_offset += cur_data_count;
@@ -637,9 +635,9 @@ int exynos_dp_write_bytes_to_dpcd(struct exynos_dp_device *dp,
 }
 
 int exynos_dp_read_bytes_from_dpcd(struct exynos_dp_device *dp,
-				unsigned int reg_addr,
-				unsigned int count,
-				unsigned char data[])
+				   unsigned int reg_addr,
+				   unsigned int count,
+				   unsigned char data[])
 {
 	u32 reg;
 	unsigned int start_offset;
@@ -683,9 +681,9 @@ int exynos_dp_read_bytes_from_dpcd(struct exynos_dp_device *dp,
 			retval = exynos_dp_start_aux_transaction(dp);
 			if (retval == 0)
 				break;
-			else
-				dev_dbg(dp->dev, "%s: Aux Transaction fail!\n",
-					__func__);
+
+			dev_dbg(dp->dev, "%s: Aux Transaction fail!\n",
+				__func__);
 		}
 
 		for (cur_data_idx = 0; cur_data_idx < cur_data_count;
@@ -736,9 +734,9 @@ int exynos_dp_select_i2c_device(struct exynos_dp_device *dp,
 }
 
 int exynos_dp_read_byte_from_i2c(struct exynos_dp_device *dp,
-				unsigned int device_addr,
-				unsigned int reg_addr,
-				unsigned int *data)
+				 unsigned int device_addr,
+				 unsigned int reg_addr,
+				 unsigned int *data)
 {
 	u32 reg;
 	int i;
@@ -767,9 +765,8 @@ int exynos_dp_read_byte_from_i2c(struct exynos_dp_device *dp,
 		retval = exynos_dp_start_aux_transaction(dp);
 		if (retval == 0)
 			break;
-		else
-			dev_dbg(dp->dev, "%s: Aux Transaction fail!\n",
-				__func__);
+
+		dev_dbg(dp->dev, "%s: Aux Transaction fail!\n", __func__);
 	}
 
 	/* Read data */
@@ -780,10 +777,10 @@ int exynos_dp_read_byte_from_i2c(struct exynos_dp_device *dp,
 }
 
 int exynos_dp_read_bytes_from_i2c(struct exynos_dp_device *dp,
-				unsigned int device_addr,
-				unsigned int reg_addr,
-				unsigned int count,
-				unsigned char edid[])
+				  unsigned int device_addr,
+				  unsigned int reg_addr,
+				  unsigned int count,
+				  unsigned char edid[])
 {
 	u32 reg;
 	unsigned int i, j;
@@ -807,8 +804,8 @@ int exynos_dp_read_bytes_from_i2c(struct exynos_dp_device *dp,
 			 * request without sending address
 			 */
 			if (!defer)
-				retval = exynos_dp_select_i2c_device(dp,
-						device_addr, reg_addr + i);
+				retval = exynos_dp_select_i2c_device(
+						dp, device_addr, reg_addr + i);
 			else
 				defer = 0;
 
@@ -828,15 +825,14 @@ int exynos_dp_read_bytes_from_i2c(struct exynos_dp_device *dp,
 				retval = exynos_dp_start_aux_transaction(dp);
 				if (retval == 0)
 					break;
-				else
-					dev_dbg(dp->dev,
-						"%s: Aux Transaction fail!\n",
-						__func__);
+
+				dev_dbg(dp->dev, "%s: Aux Transaction fail!\n",
+					__func__);
 			}
 			/* Check if Rx sends defer */
 			reg = readl(dp->reg_base + EXYNOS_DP_AUX_RX_COMM);
 			if (reg == AUX_RX_COMM_AUX_DEFER ||
-				reg == AUX_RX_COMM_I2C_DEFER) {
+			    reg == AUX_RX_COMM_I2C_DEFER) {
 				dev_err(dp->dev, "Defer: %d\n\n", reg);
 				defer = 1;
 			}
@@ -901,7 +897,7 @@ void exynos_dp_enable_enhanced_mode(struct exynos_dp_device *dp, bool enable)
 }
 
 void exynos_dp_set_training_pattern(struct exynos_dp_device *dp,
-				 enum pattern_set pattern)
+				    enum pattern_set pattern)
 {
 	u32 reg;
 
@@ -974,7 +970,7 @@ void exynos_dp_set_lane3_pre_emphasis(struct exynos_dp_device *dp, u32 level)
 }
 
 void exynos_dp_set_lane0_link_training(struct exynos_dp_device *dp,
-					u32 training_lane)
+				       u32 training_lane)
 {
 	u32 reg;
 
@@ -983,7 +979,7 @@ void exynos_dp_set_lane0_link_training(struct exynos_dp_device *dp,
 }
 
 void exynos_dp_set_lane1_link_training(struct exynos_dp_device *dp,
-					u32 training_lane)
+				       u32 training_lane)
 {
 	u32 reg;
 
@@ -992,7 +988,7 @@ void exynos_dp_set_lane1_link_training(struct exynos_dp_device *dp,
 }
 
 void exynos_dp_set_lane2_link_training(struct exynos_dp_device *dp,
-					u32 training_lane)
+				       u32 training_lane)
 {
 	u32 reg;
 
@@ -1001,7 +997,7 @@ void exynos_dp_set_lane2_link_training(struct exynos_dp_device *dp,
 }
 
 void exynos_dp_set_lane3_link_training(struct exynos_dp_device *dp,
-					u32 training_lane)
+				       u32 training_lane)
 {
 	u32 reg;
 
@@ -1125,9 +1121,9 @@ int exynos_dp_is_slave_video_stream_clock_on(struct exynos_dp_device *dp)
 }
 
 void exynos_dp_set_video_cr_mn(struct exynos_dp_device *dp,
-		enum clock_recovery_m_value_type type,
-		u32 m_value,
-		u32 n_value)
+			       enum clock_recovery_m_value_type type,
+			       u32 m_value,
+			       u32 n_value)
 {
 	u32 reg;
 
@@ -1221,7 +1217,7 @@ void exynos_dp_config_video_slave_mode(struct exynos_dp_device *dp)
 	u32 reg;
 
 	reg = readl(dp->reg_base + EXYNOS_DP_FUNC_EN_1);
-	reg &= ~(MASTER_VID_FUNC_EN_N|SLAVE_VID_FUNC_EN_N);
+	reg &= ~(MASTER_VID_FUNC_EN_N | SLAVE_VID_FUNC_EN_N);
 	reg |= MASTER_VID_FUNC_EN_N;
 	writel(reg, dp->reg_base + EXYNOS_DP_FUNC_EN_1);
 
-- 
2.1.2




From catalin.marinas at arm.com  Thu Aug  6 07:08:30 2015
From: catalin.marinas at arm.com (Catalin Marinas)
Date: Thu, 6 Aug 2015 15:08:30 +0100
Subject: [PATCH 11/13] arm64: Panic when VHE and non VHE CPUs coexist
In-Reply-To: <1436372356-30410-12-git-send-email-marc.zyngier@arm.com>
References: <1436372356-30410-1-git-send-email-marc.zyngier@arm.com>
 <1436372356-30410-12-git-send-email-marc.zyngier@arm.com>
Message-ID: <20150806140829.GC17691@e104818-lin.cambridge.arm.com>

On Wed, Jul 08, 2015 at 05:19:14PM +0100, Marc Zyngier wrote:
> Having both VHE and non-VHE capable CPUs in the same system
> is likely to be a recipe for disaster.
> 
> If the boot CPU has VHE, but a secondary is not, we won't be
> able to downgrade and run the kernel at EL1. Add CPU hotplug
> to the mix, and this produces a terrifying mess.
> 
> Let's solve the problem once and for all. If you mix VHE and
> non-VHE CPUs in the same system, you deserve to loose, and this
> patch makes sure you don't get a chance.
> 
> This is implemented by storing the kernel execution level in
> a global variable. Secondaries will park themselves in a
> WFI loop if they observe a mismatch. Also, the primary CPU
> will detect that the secondary CPU has died on a mismatched
> execution level. Panic will follow.

We don't have such system yet but we could try it on the model. Do you
know how far the secondary CPU goes? If it gets to the cpuid sanity
checking, we could do the check together with the rest of the features
(we could add a new CHECK_FATAL macro to make this even more obvious):

diff --git a/arch/arm64/include/asm/cpu.h b/arch/arm64/include/asm/cpu.h
index 8e797b2fcc01..36cc81c9b9df 100644
--- a/arch/arm64/include/asm/cpu.h
+++ b/arch/arm64/include/asm/cpu.h
@@ -29,6 +29,7 @@ struct cpuinfo_arm64 {
 	u32		reg_cntfrq;
 	u32		reg_dczid;
 	u32		reg_midr;
+	u32		reg_currentel;
 
 	u64		reg_id_aa64dfr0;
 	u64		reg_id_aa64dfr1;
diff --git a/arch/arm64/include/asm/cputype.h b/arch/arm64/include/asm/cputype.h
index ee6403df9fe4..de3e8903b5a8 100644
--- a/arch/arm64/include/asm/cputype.h
+++ b/arch/arm64/include/asm/cputype.h
@@ -118,6 +118,14 @@ static inline bool id_aa64mmfr0_mixed_endian_el0(u64 mmfr0)
 	return (ID_AA64MMFR0_BIGEND(mmfr0) == 0x1) ||
 		(ID_AA64MMFR0_BIGENDEL0(mmfr0) == 0x1);
 }
+
+static inline unsigned int read_currentel(void)
+{
+	u64 el;
+	asm("mrs	%0, CurrentEL" : "=r" (el));
+	return el;
+}
+
 #endif /* __ASSEMBLY__ */
 
 #endif
diff --git a/arch/arm64/kernel/cpuinfo.c b/arch/arm64/kernel/cpuinfo.c
index 75d5a867e7fb..c0269210fd54 100644
--- a/arch/arm64/kernel/cpuinfo.c
+++ b/arch/arm64/kernel/cpuinfo.c
@@ -132,6 +132,9 @@ static void cpuinfo_sanity_check(struct cpuinfo_arm64 *cur)
 	/* If different, timekeeping will be broken (especially with KVM) */
 	diff |= CHECK(cntfrq, boot, cur, cpu);
 
+	/* Same EL for all CPUs */
+	diff |= CHECK(currentel, boot, cur, cpu);
+
 	/*
 	 * The kernel uses self-hosted debug features and expects CPUs to
 	 * support identical debug features. We presently need CTX_CMPs, WRPs,
@@ -205,6 +208,7 @@ static void __cpuinfo_store_cpu(struct cpuinfo_arm64 *info)
 	info->reg_ctr = read_cpuid_cachetype();
 	info->reg_dczid = read_cpuid(DCZID_EL0);
 	info->reg_midr = read_cpuid_id();
+	info->reg_currentel = read_currentel();
 
 	info->reg_id_aa64dfr0 = read_cpuid(ID_AA64DFR0_EL1);
 	info->reg_id_aa64dfr1 = read_cpuid(ID_AA64DFR1_EL1);


From ykk at rock-chips.com  Thu Aug  6 07:07:21 2015
From: ykk at rock-chips.com (Yakir Yang)
Date: Thu,  6 Aug 2015 09:07:21 -0500
Subject: [RFC PATCH 2/8] drm: exynos/dp: convert to drm bridge mode
In-Reply-To: <1438868947-22132-1-git-send-email-ykk@rock-chips.com>
References: <1438868947-22132-1-git-send-email-ykk@rock-chips.com>
Message-ID: <1438870041-23130-1-git-send-email-ykk@rock-chips.com>

In order to move exynos dp code to bridge directory,
we need to convert driver drm bridge mode first. As
dp driver already have a ptn3460 bridge, so we need
to move ptn bridge to the next bridge of dp bridge.

Signed-off-by: Yakir Yang <ykk at rock-chips.com>
---
 drivers/gpu/drm/exynos/exynos_dp_core.c | 196 ++++++++++++++++++++------------
 drivers/gpu/drm/exynos/exynos_dp_core.h |   2 +
 2 files changed, 126 insertions(+), 72 deletions(-)

diff --git a/drivers/gpu/drm/exynos/exynos_dp_core.c b/drivers/gpu/drm/exynos/exynos_dp_core.c
index a8097a4..aa99e23 100644
--- a/drivers/gpu/drm/exynos/exynos_dp_core.c
+++ b/drivers/gpu/drm/exynos/exynos_dp_core.c
@@ -3,6 +3,7 @@
  *
  * Copyright (C) 2012 Samsung Electronics Co., Ltd.
  * Author: Jingoo Han <jg1.han at samsung.com>
+ *         Yakir Yang <ykk at 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
@@ -998,59 +999,6 @@ static struct drm_connector_helper_funcs exynos_dp_connector_helper_funcs = {
 	.best_encoder = exynos_dp_best_encoder,
 };
 
-/* returns the number of bridges attached */
-static int exynos_drm_attach_lcd_bridge(struct exynos_dp_device *dp,
-					struct drm_encoder *encoder)
-{
-	int ret;
-
-	encoder->bridge = dp->bridge;
-	dp->bridge->encoder = encoder;
-	ret = drm_bridge_attach(encoder->dev, dp->bridge);
-	if (ret) {
-		DRM_ERROR("Failed to attach bridge to drm\n");
-		return ret;
-	}
-
-	return 0;
-}
-
-static int exynos_dp_create_connector(struct exynos_drm_display *display,
-				      struct drm_encoder *encoder)
-{
-	struct exynos_dp_device *dp = display_to_dp(display);
-	struct drm_connector *connector = &dp->connector;
-	int ret;
-
-	dp->encoder = encoder;
-
-	/* Pre-empt DP connector creation if there's a bridge */
-	if (dp->bridge) {
-		ret = exynos_drm_attach_lcd_bridge(dp, encoder);
-		if (!ret)
-			return 0;
-	}
-
-	connector->polled = DRM_CONNECTOR_POLL_HPD;
-
-	ret = drm_connector_init(dp->drm_dev, connector,
-				 &exynos_dp_connector_funcs,
-				 DRM_MODE_CONNECTOR_eDP);
-	if (ret) {
-		DRM_ERROR("Failed to initialize connector with drm\n");
-		return ret;
-	}
-
-	drm_connector_helper_add(connector, &exynos_dp_connector_helper_funcs);
-	drm_connector_register(connector);
-	drm_mode_connector_attach_encoder(connector, encoder);
-
-	if (dp->panel)
-		ret = drm_panel_attach(dp->panel, &dp->connector);
-
-	return ret;
-}
-
 static void exynos_dp_phy_init(struct exynos_dp_device *dp)
 {
 	if (dp->phy)
@@ -1115,23 +1063,126 @@ static void exynos_dp_poweroff(struct exynos_dp_device *dp)
 	}
 }
 
-static void exynos_dp_dpms(struct exynos_drm_display *display, int mode)
+/* returns the number of bridges attached */
+static int exynos_drm_attach_lcd_bridge(struct exynos_dp_device *dp,
+		struct drm_encoder *encoder)
+{
+	int ret;
+
+	dp->bridge->next = dp->ptn_bridge;
+	dp->bridge->encoder = encoder;
+	ret = drm_bridge_attach(encoder->dev, dp->bridge);
+	if (ret) {
+		DRM_ERROR("Failed to attach ptn bridge to drm\n");
+		return ret;
+	}
+
+	return 0;
+}
+
+static int exynos_dp_bridge_attach(struct drm_bridge *bridge)
+{
+
+	struct exynos_dp_device *dp = bridge->driver_private;
+	struct drm_encoder *encoder = dp->encoder;
+	struct drm_connector *connector = &dp->connector;
+	int ret;
+
+	if (!bridge->encoder) {
+		DRM_ERROR("Parent encoder object not found");
+		return -ENODEV;
+	}
+
+	encoder->bridge = bridge;
+
+	/* Pre-empt DP connector creation if there's a bridge */
+	if (dp->ptn_bridge) {
+		ret = exynos_drm_attach_lcd_bridge(dp, encoder);
+		if (ret)
+			return -ENODEV;
+	}
+
+	connector->polled = DRM_CONNECTOR_POLL_HPD;
+
+	ret = drm_connector_init(dp->drm_dev, connector,
+			&exynos_dp_connector_funcs, DRM_MODE_CONNECTOR_eDP);
+	if (ret) {
+		DRM_ERROR("Failed to initialize connector with drm\n");
+		return ret;
+	}
+
+	drm_connector_helper_add(connector, &exynos_dp_connector_helper_funcs);
+	drm_connector_register(connector);
+	drm_mode_connector_attach_encoder(connector, encoder);
+
+	if (dp->panel)
+		ret = drm_panel_attach(dp->panel, &dp->connector);
+
+	return ret;
+}
+
+static void exynos_dp_bridge_nop(struct drm_bridge *bridge)
+{
+	/* do nothing */
+}
+
+static void exynos_dp_bridge_enable(struct drm_bridge *bridge)
+{
+	struct exynos_dp_device *dp = bridge->driver_private;
+
+	exynos_dp_poweron(dp);
+	dp->dpms_mode = DRM_MODE_DPMS_ON;
+}
+
+static void exynos_dp_bridge_disable(struct drm_bridge *bridge)
+{
+	struct exynos_dp_device *dp = bridge->driver_private;
+
+	exynos_dp_poweroff(dp);
+	dp->dpms_mode = DRM_MODE_DPMS_OFF;
+}
+
+static const struct drm_bridge_funcs exynos_dp_bridge_funcs = {
+	.enable = exynos_dp_bridge_enable,
+	.disable = exynos_dp_bridge_disable,
+	.pre_enable = exynos_dp_bridge_nop,
+	.post_disable = exynos_dp_bridge_nop,
+	.attach = exynos_dp_bridge_attach,
+};
+
+static int exynos_dp_create_connector(struct exynos_drm_display *display,
+				struct drm_encoder *encoder)
 {
 	struct exynos_dp_device *dp = display_to_dp(display);
+	struct drm_device *drm_dev = dp->drm_dev;
+	struct drm_bridge *bridge;
+	int ret;
 
-	switch (mode) {
-	case DRM_MODE_DPMS_ON:
-		exynos_dp_poweron(dp);
-		break;
-	case DRM_MODE_DPMS_STANDBY:
-	case DRM_MODE_DPMS_SUSPEND:
-	case DRM_MODE_DPMS_OFF:
-		exynos_dp_poweroff(dp);
-		break;
-	default:
-		break;
+	bridge = devm_kzalloc(drm_dev->dev, sizeof(*bridge), GFP_KERNEL);
+	if (!bridge) {
+		DRM_ERROR("failed to allocate for drm bridge\n");
+		return -ENOMEM;
 	}
-	dp->dpms_mode = mode;
+
+	dp->bridge = bridge;
+	dp->encoder = encoder;
+
+	bridge->driver_private = dp;
+	bridge->encoder = dp->encoder;
+	bridge->funcs = &exynos_dp_bridge_funcs;
+
+	ret = drm_bridge_attach(drm_dev, bridge);
+	if (ret) {
+		DRM_ERROR("failed to attach drm bridge\n");
+		return -EINVAL;
+	}
+
+	return 0;
+}
+
+static void exynos_dp_dpms(struct exynos_drm_display *display, int mode)
+{
+	/* do nothing */
 }
 
 static struct exynos_drm_display_ops exynos_dp_display_ops = {
@@ -1243,7 +1294,7 @@ static int exynos_dp_bind(struct device *dev, struct device *master, void *data)
 		}
 	}
 
-	if (!dp->panel && !dp->bridge) {
+	if (!dp->panel && !dp->ptn_bridge) {
 		ret = exynos_dp_dt_parse_panel(dp);
 		if (ret)
 			return ret;
@@ -1316,7 +1367,7 @@ static void exynos_dp_unbind(struct device *dev, struct device *master,
 {
 	struct exynos_dp_device *dp = dev_get_drvdata(dev);
 
-	exynos_dp_dpms(&dp->display, DRM_MODE_DPMS_OFF);
+	exynos_dp_bridge_disable(dp->bridge);
 }
 
 static const struct component_ops exynos_dp_ops = {
@@ -1351,9 +1402,9 @@ static int exynos_dp_probe(struct platform_device *pdev)
 	if (endpoint) {
 		bridge_node = of_graph_get_remote_port_parent(endpoint);
 		if (bridge_node) {
-			dp->bridge = of_drm_find_bridge(bridge_node);
+			dp->ptn_bridge = of_drm_find_bridge(bridge_node);
 			of_node_put(bridge_node);
-			if (!dp->bridge)
+			if (!dp->ptn_bridge)
 				return -EPROBE_DEFER;
 		} else {
 			return -EPROBE_DEFER;
@@ -1375,7 +1426,7 @@ static int exynos_dp_suspend(struct device *dev)
 {
 	struct exynos_dp_device *dp = dev_get_drvdata(dev);
 
-	exynos_dp_dpms(&dp->display, DRM_MODE_DPMS_OFF);
+	exynos_dp_bridge_disable(dp->bridge);
 	return 0;
 }
 
@@ -1383,7 +1434,7 @@ static int exynos_dp_resume(struct device *dev)
 {
 	struct exynos_dp_device *dp = dev_get_drvdata(dev);
 
-	exynos_dp_dpms(&dp->display, DRM_MODE_DPMS_ON);
+	exynos_dp_bridge_enable(dp->bridge);
 	return 0;
 }
 #endif
@@ -1410,5 +1461,6 @@ struct platform_driver dp_driver = {
 };
 
 MODULE_AUTHOR("Jingoo Han <jg1.han at samsung.com>");
+MODULE_AUTHOR("Yakir Yang <ykk at rock-chips.com>");
 MODULE_DESCRIPTION("Samsung SoC DP Driver");
 MODULE_LICENSE("GPL v2");
diff --git a/drivers/gpu/drm/exynos/exynos_dp_core.h b/drivers/gpu/drm/exynos/exynos_dp_core.h
index c321ad5..f2584b8 100644
--- a/drivers/gpu/drm/exynos/exynos_dp_core.h
+++ b/drivers/gpu/drm/exynos/exynos_dp_core.h
@@ -3,6 +3,7 @@
  *
  * Copyright (C) 2012 Samsung Electronics Co., Ltd.
  * Author: Jingoo Han <jg1.han at samsung.com>
+ *         Yakir Yang <ykk at 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
@@ -154,6 +155,7 @@ struct exynos_dp_device {
 	struct drm_encoder	*encoder;
 	struct drm_panel	*panel;
 	struct drm_bridge	*bridge;
+	struct drm_bridge	*ptn_bridge;
 	struct clk		*clock;
 	unsigned int		irq;
 	void __iomem		*reg_base;
-- 
2.1.2




From tomeu.vizoso at collabora.com  Thu Aug  6 07:11:38 2015
From: tomeu.vizoso at collabora.com (Tomeu Vizoso)
Date: Thu,  6 Aug 2015 16:11:38 +0200
Subject: [PATCH v3 01/18] platform: delay OF device-driver matches until
 late_initcall
In-Reply-To: <1438870315-18689-1-git-send-email-tomeu.vizoso@collabora.com>
References: <1438870315-18689-1-git-send-email-tomeu.vizoso@collabora.com>
Message-ID: <1438870315-18689-2-git-send-email-tomeu.vizoso@collabora.com>

Delay matches of platform devices with OF nodes until late_initcall,
when we are sure that all built-in drivers have been registered already.
This is needed to prevent deferred probes because of some drivers not
having registered yet.

The reason why only platform devices are delayed is that some other
devices are expected to be probed earlier than late_initcall, for
example, the system PNP driver needs to probe its devices in
fs_initcall.

Additionally, only platform devices with OF nodes are delayed because
some machines may depend on oter platform devices being registered at
specific times.

Signed-off-by: Tomeu Vizoso <tomeu.vizoso at collabora.com>
---

Changes in v3:
- Only delay platform devices with OF nodes

Changes in v2:
- Move delay to platform.c

 drivers/base/platform.c | 29 +++++++++++++++++++++++++++++
 1 file changed, 29 insertions(+)

diff --git a/drivers/base/platform.c b/drivers/base/platform.c
index 063f0ab15259..0848ece2bf9d 100644
--- a/drivers/base/platform.c
+++ b/drivers/base/platform.c
@@ -33,6 +33,8 @@
 /* For automatically allocated device IDs */
 static DEFINE_IDA(platform_devid_ida);
 
+static bool enable_matches;
+
 struct device platform_bus = {
 	.init_name	= "platform",
 };
@@ -839,6 +841,15 @@ static int platform_match(struct device *dev, struct device_driver *drv)
 	struct platform_device *pdev = to_platform_device(dev);
 	struct platform_driver *pdrv = to_platform_driver(drv);
 
+	/*
+	 * Delay matches of OF platform devices until late_initcall, when we
+	 * are sure that all built-in drivers have been registered already.
+	 * This is needed to prevent deferred probes because of some drivers
+	 * not having registered yet.
+	 */
+	if (dev->of_node && !enable_matches)
+		return 0;
+
 	/* When driver_override is set, only bind to the matching driver */
 	if (pdev->driver_override)
 		return !strcmp(pdev->driver_override, drv->name);
@@ -859,6 +870,24 @@ static int platform_match(struct device *dev, struct device_driver *drv)
 	return (strcmp(pdev->name, drv->name) == 0);
 }
 
+static int __probe_device(struct device *dev, void *data)
+{
+	if (dev->of_node)
+		device_initial_probe(dev);
+
+	return 0;
+}
+
+static int probe_delayed_matches_initcall(void)
+{
+	enable_matches = true;
+
+	bus_for_each_dev(&platform_bus_type, NULL, NULL, __probe_device);
+
+	return 0;
+}
+late_initcall(probe_delayed_matches_initcall);
+
 #ifdef CONFIG_PM_SLEEP
 
 static int platform_legacy_suspend(struct device *dev, pm_message_t mesg)
-- 
2.4.3



From tomeu.vizoso at collabora.com  Thu Aug  6 07:11:37 2015
From: tomeu.vizoso at collabora.com (Tomeu Vizoso)
Date: Thu,  6 Aug 2015 16:11:37 +0200
Subject: [PATCH v3 0/18] On-demand device probing
Message-ID: <1438870315-18689-1-git-send-email-tomeu.vizoso@collabora.com>

Hello,

I have a problem with the panel on my Tegra Chromebook taking longer
than expected to be ready during boot (St?phane Marchesin reported what
is basically the same issue in [0]), and have looked into ordered
probing as a better way of solving this than moving nodes around in the
DT or playing with initcall levels and linking order.

While reading the thread [1] that Alexander Holler started with his
series to make probing order deterministic, it occurred to me that it
should be possible to achieve the same by probing devices as they are
referenced by other devices.

This basically reuses the information that is already implicit in the
probe() implementations, saving us from refactoring existing drivers or
adding information to DTBs.

During review of v1 of this series Linus Walleij suggested that it
should be the device driver core to make sure that dependencies are
ready before probing a device. I gave this idea a try [2] but Mark Brown
pointed out to the logic duplication between the resource acquisition
and dependency discovery code paths (though I think it's fairly minor).

To address that code duplication I experimented with Arnd's devm_probe
[3] concept of having drivers declare their dependencies instead of
acquiring them during probe, and while it worked [4], I don't think we
end up winning anything when compared to just probing devices on-demand
from resource getters.

One remaining objection is to the "sprinkling" of calls to
fwnode_ensure_device() in the resource getters of each subsystem, but I
think it's the right thing to do given that the storage of resources is
currently subsystem-specific.

We could avoid the above by moving resource storage into the core, but I
don't think there's a compelling case for that.

I have tested this on boards with Tegra, iMX.6, Exynos and OMAP SoCs,
and these patches were enough to eliminate all the deferred probes
(except one in PandaBoard because omap_dma_system doesn't have a
firmware node as of yet).

Have submitted a branch [5] with these patches to kernelci.org and I'm
currently trying to fix all regressions, usually due to code assuming
that devices will be probed in a specific order. Current results [6] are
348 passes, 30 fails and 42 unknowns (linux-next [7] is currently
387/3/23).

With this series I get the kernel to output to the panel in 0.5s,
instead of 2.8s.

Regards,

Tomeu

[0] http://lists.freedesktop.org/archives/dri-devel/2014-August/066527.html

[1] https://lkml.org/lkml/2014/5/12/452

[2] https://lkml.org/lkml/2015/6/17/305

[3] http://article.gmane.org/gmane.linux.ports.arm.kernel/277689

[4] https://lkml.org/lkml/2015/7/21/441a

[5] https://git.collabora.com/cgit/user/tomeu/linux.git/log/?h=on-demand-probes-v5

[6] http://kernelci.org/boot/all/job/collabora/kernel/v4.2-rc5-6548-g632b98c83840/

[7] http://kernelci.org/boot/all/job/next/kernel/next-20150806/

Changes in v3:
- Only delay platform devices with OF nodes
- Set and use device_node.platform_dev instead of reversing the logic to
  find the platform device that encloses a device node.
- Drop the fwnode API to probe firmware nodes and add OF-only API for
  now. I think this same scheme could be used for machines with ACPI,
  but I haven't been able to find one that had to defer its probes because
  of the device probe order.
- Avoid unlocking the regulator device's mutex if we don't have a device

Changes in v2:
- Move delay to platform.c
- Acquire regulator device lock before returning from regulator_dev_lookup()

Tomeu Vizoso (18):
  platform: delay OF device-driver matches until late_initcall
  of/platform: add of_platform_probe
  gpio: Probe GPIO drivers on demand
  gpio: Probe pinctrl devices on demand
  regulator: core: Reduce critical area in _regulator_get
  regulator: core: Probe regulators on demand
  drm: Probe panels on demand
  drm/tegra: Probe dpaux devices on demand
  i2c: core: Probe i2c adapters and devices on demand
  pwm: Probe PWM chip devices on demand
  backlight: Probe backlight devices on demand
  usb: phy: Probe phy devices on demand
  clk: Probe clk providers on demand
  pinctrl: Probe pinctrl devices on demand
  phy: core: Probe phy providers on demand
  dma: of: Probe DMA controllers on demand
  power-supply: Probe power supplies on demand
  ASoC: core: Probe components on demand

 drivers/base/platform.c             |  29 ++++++++++
 drivers/clk/clk.c                   |   3 +
 drivers/dma/of-dma.c                |   3 +
 drivers/gpio/gpiolib-of.c           |   5 ++
 drivers/gpu/drm/drm_panel.c         |   3 +
 drivers/gpu/drm/tegra/dpaux.c       |   3 +
 drivers/i2c/i2c-core.c              |   5 ++
 drivers/of/platform.c               |  61 +++++++++++++++++++++
 drivers/phy/phy-core.c              |   3 +
 drivers/pinctrl/devicetree.c        |   3 +
 drivers/power/power_supply_core.c   |   3 +
 drivers/pwm/core.c                  |   3 +
 drivers/regulator/core.c            | 106 +++++++++++++++++++++---------------
 drivers/usb/phy/phy.c               |   3 +
 drivers/video/backlight/backlight.c |   3 +
 include/linux/of.h                  |   1 +
 include/linux/of_platform.h         |   2 +
 sound/soc/soc-core.c                |   7 ++-
 18 files changed, 200 insertions(+), 46 deletions(-)

-- 
2.4.3



From tomeu.vizoso at collabora.com  Thu Aug  6 07:11:41 2015
From: tomeu.vizoso at collabora.com (Tomeu Vizoso)
Date: Thu,  6 Aug 2015 16:11:41 +0200
Subject: [PATCH v3 04/18] gpio: Probe pinctrl devices on demand
In-Reply-To: <1438870315-18689-1-git-send-email-tomeu.vizoso@collabora.com>
References: <1438870315-18689-1-git-send-email-tomeu.vizoso@collabora.com>
Message-ID: <1438870315-18689-5-git-send-email-tomeu.vizoso@collabora.com>

When looking up a pin controller through its OF node, probe it if it
hasn't already.

The goal is to reduce deferred probes to a minimum, as it makes it very
cumbersome to find out why a device failed to probe, and can introduce
very big delays in when a critical device is probed.

Signed-off-by: Tomeu Vizoso <tomeu.vizoso at collabora.com>
---

Changes in v3: None
Changes in v2: None

 drivers/gpio/gpiolib-of.c | 2 ++
 1 file changed, 2 insertions(+)

diff --git a/drivers/gpio/gpiolib-of.c b/drivers/gpio/gpiolib-of.c
index d8c617c34c85..2d4a1cca995b 100644
--- a/drivers/gpio/gpiolib-of.c
+++ b/drivers/gpio/gpiolib-of.c
@@ -359,6 +359,8 @@ static int of_gpiochip_add_pin_range(struct gpio_chip *chip)
 		if (ret)
 			break;
 
+		of_platform_probe(pinspec.np);
+
 		pctldev = of_pinctrl_get(pinspec.np);
 		if (!pctldev)
 			return -EPROBE_DEFER;
-- 
2.4.3



From tomeu.vizoso at collabora.com  Thu Aug  6 07:11:39 2015
From: tomeu.vizoso at collabora.com (Tomeu Vizoso)
Date: Thu,  6 Aug 2015 16:11:39 +0200
Subject: [PATCH v3 02/18] of/platform: add of_platform_probe
In-Reply-To: <1438870315-18689-1-git-send-email-tomeu.vizoso@collabora.com>
References: <1438870315-18689-1-git-send-email-tomeu.vizoso@collabora.com>
Message-ID: <1438870315-18689-3-git-send-email-tomeu.vizoso@collabora.com>

Walks the OF tree up and finds the closest ancestor that has a platform
device associated with it, probing it if isn't bound to a driver yet.

The above should ensure that the dependency represented by the passed OF
node is available, because probing a platform device should cause its
descendants to be probed as well.

Subsystems can use this when looking up resources for drivers, to reduce
the chances of deferred probes because of the probing order of devices.

Also adds a platform_dev member to struct device_node, pointing to the
platform device that was registered based on that node, if any.

Signed-off-by: Tomeu Vizoso <tomeu.vizoso at collabora.com>
---

Changes in v3:
- Set and use device_node.platform_dev instead of reversing the logic to
  find the platform device that encloses a device node.
- Drop the fwnode API to probe firmware nodes and add OF-only API for
  now. I think this same scheme could be used for machines with ACPI,
  but I haven't been able to find one that had to defer its probes because
  of the device probe order.

Changes in v2: None

 drivers/of/platform.c       | 61 +++++++++++++++++++++++++++++++++++++++++++++
 include/linux/of.h          |  1 +
 include/linux/of_platform.h |  2 ++
 3 files changed, 64 insertions(+)

diff --git a/drivers/of/platform.c b/drivers/of/platform.c
index 8a002d6151f2..a1930c0d1fee 100644
--- a/drivers/of/platform.c
+++ b/drivers/of/platform.c
@@ -192,6 +192,8 @@ static struct platform_device *of_platform_device_create_pdata(
 		goto err_clear_flag;
 	}
 
+	np->platform_dev = dev;
+
 	return dev;
 
 err_clear_flag:
@@ -501,6 +503,65 @@ void of_platform_depopulate(struct device *parent)
 }
 EXPORT_SYMBOL_GPL(of_platform_depopulate);
 
+/**
+ * of_platform_probe() - Probe platform device associated with OF node
+ * @np: node to probe
+ *
+ * Walks the OF tree up and finds the closest ancestor that has a platform
+ * device associated with it, probing it if isn't bound to a driver yet.
+ *
+ * The above should ensure that the dependency represented by the passed OF
+ * node is available, because probing a platform device should cause its
+ * descendants to be probed as well.
+ */
+void of_platform_probe(struct device_node *np)
+{
+	struct device_node *target;
+	struct platform_device *pdev = NULL;
+
+	if (!of_root || !of_node_check_flag(of_root, OF_POPULATED_BUS))
+		return;
+
+	if (!np)
+		return;
+
+	of_node_get(np);
+
+	for (target = np;
+	     !of_node_is_root(target);
+	     target = of_get_next_parent(target))
+		if (target->platform_dev) {
+			pdev = target->platform_dev;
+			break;
+		}
+
+	of_node_put(target);
+
+	if (!pdev) {
+		pr_warn("Couldn't find a platform device for node '%s'\n",
+			of_node_full_name(np));
+		return;
+	}
+
+	/*
+	 * Device is bound or is being probed right now. If we have bad luck
+	 * and the dependency isn't ready when it's needed, deferred probe
+	 * will save us.
+	 */
+	if (pdev->dev.driver)
+		return;
+
+	if (device_attach(&pdev->dev) != 1)
+		/*
+		 * This cannot be a warning for now because clock nodes have a
+		 * compatible string but the clock framework doesn't follow the
+		 * device/driver model.
+		 */
+		pr_debug("Probe failed for %s (%s)\n", of_node_full_name(np),
+			 dev_name(&pdev->dev));
+}
+EXPORT_SYMBOL_GPL(of_platform_probe);
+
 #ifdef CONFIG_OF_DYNAMIC
 static int of_platform_notify(struct notifier_block *nb,
 				unsigned long action, void *arg)
diff --git a/include/linux/of.h b/include/linux/of.h
index edc068d19c79..2ace86a5fa2d 100644
--- a/include/linux/of.h
+++ b/include/linux/of.h
@@ -52,6 +52,7 @@ struct device_node {
 	phandle phandle;
 	const char *full_name;
 	struct fwnode_handle fwnode;
+	struct platform_device *platform_dev;
 
 	struct	property *properties;
 	struct	property *deadprops;	/* removed properties */
diff --git a/include/linux/of_platform.h b/include/linux/of_platform.h
index 611a691145c4..91ca92c7c061 100644
--- a/include/linux/of_platform.h
+++ b/include/linux/of_platform.h
@@ -73,6 +73,7 @@ extern int of_platform_populate(struct device_node *root,
 				const struct of_dev_auxdata *lookup,
 				struct device *parent);
 extern void of_platform_depopulate(struct device *parent);
+extern void of_platform_probe(struct device_node *np);
 #else
 static inline int of_platform_populate(struct device_node *root,
 					const struct of_device_id *matches,
@@ -82,6 +83,7 @@ static inline int of_platform_populate(struct device_node *root,
 	return -ENODEV;
 }
 static inline void of_platform_depopulate(struct device *parent) { }
+static inline void of_platform_probe(struct device_node *np) { }
 #endif
 
 #if defined(CONFIG_OF_DYNAMIC) && defined(CONFIG_OF_ADDRESS)
-- 
2.4.3



From tomeu.vizoso at collabora.com  Thu Aug  6 07:11:40 2015
From: tomeu.vizoso at collabora.com (Tomeu Vizoso)
Date: Thu,  6 Aug 2015 16:11:40 +0200
Subject: [PATCH v3 03/18] gpio: Probe GPIO drivers on demand
In-Reply-To: <1438870315-18689-1-git-send-email-tomeu.vizoso@collabora.com>
References: <1438870315-18689-1-git-send-email-tomeu.vizoso@collabora.com>
Message-ID: <1438870315-18689-4-git-send-email-tomeu.vizoso@collabora.com>

When looking up a gpiochip through its firmware node, probe it if it
hasn't already.

The goal is to reduce deferred probes to a minimum, as it makes it very
cumbersome to find out why a device failed to probe, and can introduce
very big delays in when a critical device is probed.

Signed-off-by: Tomeu Vizoso <tomeu.vizoso at collabora.com>
---

Changes in v3: None
Changes in v2: None

 drivers/gpio/gpiolib-of.c | 3 +++
 1 file changed, 3 insertions(+)

diff --git a/drivers/gpio/gpiolib-of.c b/drivers/gpio/gpiolib-of.c
index fa6e3c8823d6..d8c617c34c85 100644
--- a/drivers/gpio/gpiolib-of.c
+++ b/drivers/gpio/gpiolib-of.c
@@ -20,6 +20,7 @@
 #include <linux/of.h>
 #include <linux/of_address.h>
 #include <linux/of_gpio.h>
+#include <linux/of_platform.h>
 #include <linux/pinctrl/pinctrl.h>
 #include <linux/slab.h>
 #include <linux/gpio/machine.h>
@@ -95,6 +96,8 @@ struct gpio_desc *of_get_named_gpiod_flags(struct device_node *np,
 		return ERR_PTR(ret);
 	}
 
+	of_platform_probe(gg_data.gpiospec.np);
+
 	gpiochip_find(&gg_data, of_gpiochip_find_and_xlate);
 
 	of_node_put(gg_data.gpiospec.np);
-- 
2.4.3



From tomeu.vizoso at collabora.com  Thu Aug  6 07:11:44 2015
From: tomeu.vizoso at collabora.com (Tomeu Vizoso)
Date: Thu,  6 Aug 2015 16:11:44 +0200
Subject: [PATCH v3 07/18] drm: Probe panels on demand
In-Reply-To: <1438870315-18689-1-git-send-email-tomeu.vizoso@collabora.com>
References: <1438870315-18689-1-git-send-email-tomeu.vizoso@collabora.com>
Message-ID: <1438870315-18689-8-git-send-email-tomeu.vizoso@collabora.com>

When looking up a panel through its OF node, probe it if it hasn't
already.

The goal is to reduce deferred probes to a minimum, as it makes it very
cumbersome to find out why a device failed to probe, and can introduce
very big delays in when a critical device is probed.

Signed-off-by: Tomeu Vizoso <tomeu.vizoso at collabora.com>
---

Changes in v3: None
Changes in v2: None

 drivers/gpu/drm/drm_panel.c | 3 +++
 1 file changed, 3 insertions(+)

diff --git a/drivers/gpu/drm/drm_panel.c b/drivers/gpu/drm/drm_panel.c
index 2ef988e037b7..8f01574cabda 100644
--- a/drivers/gpu/drm/drm_panel.c
+++ b/drivers/gpu/drm/drm_panel.c
@@ -23,6 +23,7 @@
 
 #include <linux/err.h>
 #include <linux/module.h>
+#include <linux/of_platform.h>
 
 #include <drm/drm_crtc.h>
 #include <drm/drm_panel.h>
@@ -80,6 +81,8 @@ struct drm_panel *of_drm_find_panel(struct device_node *np)
 {
 	struct drm_panel *panel;
 
+	of_platform_probe(np);
+
 	mutex_lock(&panel_lock);
 
 	list_for_each_entry(panel, &panel_list, list) {
-- 
2.4.3



From tomeu.vizoso at collabora.com  Thu Aug  6 07:11:43 2015
From: tomeu.vizoso at collabora.com (Tomeu Vizoso)
Date: Thu,  6 Aug 2015 16:11:43 +0200
Subject: [PATCH v3 06/18] regulator: core: Probe regulators on demand
In-Reply-To: <1438870315-18689-1-git-send-email-tomeu.vizoso@collabora.com>
References: <1438870315-18689-1-git-send-email-tomeu.vizoso@collabora.com>
Message-ID: <1438870315-18689-7-git-send-email-tomeu.vizoso@collabora.com>

When looking up a regulator through its OF node, probe it if it hasn't
already.

The goal is to reduce deferred probes to a minimum, as it makes it very
cumbersome to find out why a device failed to probe, and can introduce
very big delays in when a critical device is probed.

Signed-off-by: Tomeu Vizoso <tomeu.vizoso at collabora.com>
---

Changes in v3: None
Changes in v2: None

 drivers/regulator/core.c | 2 ++
 1 file changed, 2 insertions(+)

diff --git a/drivers/regulator/core.c b/drivers/regulator/core.c
index 5f6c76142b08..73ac9fb07f96 100644
--- a/drivers/regulator/core.c
+++ b/drivers/regulator/core.c
@@ -26,6 +26,7 @@
 #include <linux/gpio.h>
 #include <linux/gpio/consumer.h>
 #include <linux/of.h>
+#include <linux/of_platform.h>
 #include <linux/regmap.h>
 #include <linux/regulator/of_regulator.h>
 #include <linux/regulator/consumer.h>
@@ -1336,6 +1337,7 @@ static struct regulator_dev *regulator_dev_lookup(struct device *dev,
 	if (dev && dev->of_node) {
 		node = of_get_regulator(dev, supply);
 		if (node) {
+			of_platform_probe(node);
 			mutex_lock(&regulator_list_mutex);
 			list_for_each_entry(r, &regulator_list, list)
 				if (r->dev.parent &&
-- 
2.4.3



From tomeu.vizoso at collabora.com  Thu Aug  6 07:11:42 2015
From: tomeu.vizoso at collabora.com (Tomeu Vizoso)
Date: Thu,  6 Aug 2015 16:11:42 +0200
Subject: [PATCH v3 05/18] regulator: core: Reduce critical area in
 _regulator_get
In-Reply-To: <1438870315-18689-1-git-send-email-tomeu.vizoso@collabora.com>
References: <1438870315-18689-1-git-send-email-tomeu.vizoso@collabora.com>
Message-ID: <1438870315-18689-6-git-send-email-tomeu.vizoso@collabora.com>

...by moving the locking of regulator_list_mutex into
regulator_dev_lookup(), where it is iterated over.

The regulator device lock gets acquired before returning, and the caller
is responsible for releasing it after it's done with the regulator
device.

In _regulator_get() the regulator_list_mutex mutex is held for most of
the function, but is only strictly needed to protect the list lookups.

This change would be useful if for example regulator devices could be
registered on demand when a driver requests them. regulator_register()
could end up being called from within _regulator_get while the lock on
regulator_list_mutex is being held, causing a deadlock.

This backtrace illustrates the situation described above:

(regulator_register) from [<c05efe64>]
(devm_regulator_register+0x48/0x84)
(devm_regulator_register) from [<c05f0b20>]
(reg_fixed_voltage_probe+0x214/0x35c)
(reg_fixed_voltage_probe) from [<c06cc7fc>]
(platform_drv_probe+0x54/0xbc)
(platform_drv_probe) from [<c06caac8>] (driver_probe_device+0x184/0x2c4)
(driver_probe_device) from [<c06cac58>] (__device_attach+0x50/0x54)
(__device_attach) from [<c06c8eac>] (bus_for_each_drv+0x70/0xa4)
(bus_for_each_drv) from [<c06ca900>] (device_attach+0x90/0xa4)
(device_attach) from [<c06c9eb4>] (bus_probe_device+0x94/0xb8)
(bus_probe_device) from [<c06c7de8>] (device_add+0x384/0x580)
(device_add) from [<c095c104>] (of_device_add+0x44/0x4c)
(of_device_add) from [<c095c968>]
...
(regulator_dev_lookup) from [<c05ee7c0>] (_regulator_get+0x8c/0x26c)
(_regulator_get) from [<c05ee9c0>] (regulator_get+0x20/0x24)
(regulator_get) from [<c05efb1c>] (_devm_regulator_get+0xa4/0xc8)
(_devm_regulator_get) from [<c05efb5c>] (devm_regulator_get+0x1c/0x20)
(devm_regulator_get) from [<c06ba870>] (tegra_hdmi_probe+0xe0/0x278)
(tegra_hdmi_probe) from [<c06cc7fc>] (platform_drv_probe+0x54/0xbc)

Signed-off-by: Tomeu Vizoso <tomeu.vizoso at collabora.com>
---

Changes in v3:
- Avoid unlocking the regulator device's mutex if we don't have a device

Changes in v2:
- Acquire regulator device lock before returning from regulator_dev_lookup()

 drivers/regulator/core.c | 104 +++++++++++++++++++++++++++--------------------
 1 file changed, 59 insertions(+), 45 deletions(-)

diff --git a/drivers/regulator/core.c b/drivers/regulator/core.c
index 613034667b93..5f6c76142b08 100644
--- a/drivers/regulator/core.c
+++ b/drivers/regulator/core.c
@@ -110,6 +110,7 @@ static struct regulator *create_regulator(struct regulator_dev *rdev,
 					  struct device *dev,
 					  const char *supply_name);
 static void _regulator_put(struct regulator *regulator);
+static int _regulator_enable(struct regulator *regulator, bool do_lock);
 
 static const char *rdev_get_name(struct regulator_dev *rdev)
 {
@@ -1212,6 +1213,7 @@ static void unset_regulator_supplies(struct regulator_dev *rdev)
 
 #define REG_STR_SIZE	64
 
+/* rdev->mutex held by caller */
 static struct regulator *create_regulator(struct regulator_dev *rdev,
 					  struct device *dev,
 					  const char *supply_name)
@@ -1224,7 +1226,7 @@ static struct regulator *create_regulator(struct regulator_dev *rdev,
 	if (regulator == NULL)
 		return NULL;
 
-	mutex_lock(&rdev->mutex);
+	lockdep_assert_held_once(&rdev->mutex);
 	regulator->rdev = rdev;
 	list_add(&regulator->list, &rdev->consumer_list);
 
@@ -1276,12 +1278,10 @@ static struct regulator *create_regulator(struct regulator_dev *rdev,
 	    _regulator_is_enabled(rdev))
 		regulator->always_on = true;
 
-	mutex_unlock(&rdev->mutex);
 	return regulator;
 overflow_err:
 	list_del(&regulator->list);
 	kfree(regulator);
-	mutex_unlock(&rdev->mutex);
 	return NULL;
 }
 
@@ -1320,6 +1320,7 @@ static void regulator_supply_alias(struct device **dev, const char **supply)
 	}
 }
 
+/* Caller has to release r->mutex once done with r */
 static struct regulator_dev *regulator_dev_lookup(struct device *dev,
 						  const char *supply,
 						  int *ret)
@@ -1335,10 +1336,15 @@ static struct regulator_dev *regulator_dev_lookup(struct device *dev,
 	if (dev && dev->of_node) {
 		node = of_get_regulator(dev, supply);
 		if (node) {
+			mutex_lock(&regulator_list_mutex);
 			list_for_each_entry(r, &regulator_list, list)
 				if (r->dev.parent &&
-					node == r->dev.of_node)
+					node == r->dev.of_node) {
+					mutex_lock(&r->mutex);
+					mutex_unlock(&regulator_list_mutex);
 					return r;
+				}
+			mutex_unlock(&regulator_list_mutex);
 			*ret = -EPROBE_DEFER;
 			return NULL;
 		} else {
@@ -1356,9 +1362,14 @@ static struct regulator_dev *regulator_dev_lookup(struct device *dev,
 	if (dev)
 		devname = dev_name(dev);
 
+	mutex_lock(&regulator_list_mutex);
 	list_for_each_entry(r, &regulator_list, list)
-		if (strcmp(rdev_get_name(r), supply) == 0)
+		if (strcmp(rdev_get_name(r), supply) == 0) {
+			mutex_lock(&r->mutex);
+			mutex_unlock(&regulator_list_mutex);
 			return r;
+		}
+	mutex_unlock(&regulator_list_mutex);
 
 	list_for_each_entry(map, &regulator_map_list, list) {
 		/* If the mapping has a device set up it must match */
@@ -1400,6 +1411,7 @@ static int regulator_resolve_supply(struct regulator_dev *rdev)
 	if (!r) {
 		if (have_full_constraints()) {
 			r = dummy_regulator_rdev;
+			mutex_lock(&r->mutex);
 		} else {
 			dev_err(dev, "Failed to resolve %s-supply for %s\n",
 				rdev->supply_name, rdev->desc->name);
@@ -1410,23 +1422,25 @@ static int regulator_resolve_supply(struct regulator_dev *rdev)
 	/* Recursively resolve the supply of the supply */
 	ret = regulator_resolve_supply(r);
 	if (ret < 0)
-		return ret;
+		goto out;
 
 	ret = set_supply(rdev, r);
 	if (ret < 0)
-		return ret;
+		goto out;
 
 	/* Cascade always-on state to supply */
 	if (_regulator_is_enabled(rdev)) {
-		ret = regulator_enable(rdev->supply);
+		ret = _regulator_enable(rdev->supply, false);
 		if (ret < 0) {
 			if (rdev->supply)
 				_regulator_put(rdev->supply);
-			return ret;
+			goto out;
 		}
 	}
 
-	return 0;
+out:
+	mutex_unlock(&r->mutex);
+	return ret;
 }
 
 /* Internal regulator request function */
@@ -1451,8 +1465,6 @@ static struct regulator *_regulator_get(struct device *dev, const char *id,
 	else
 		ret = -EPROBE_DEFER;
 
-	mutex_lock(&regulator_list_mutex);
-
 	rdev = regulator_dev_lookup(dev, id, &ret);
 	if (rdev)
 		goto found;
@@ -1464,7 +1476,7 @@ static struct regulator *_regulator_get(struct device *dev, const char *id,
 	 * succeed, so, quit with appropriate error value
 	 */
 	if (ret && ret != -ENODEV)
-		goto out;
+		return regulator;
 
 	if (!devname)
 		devname = "deviceless";
@@ -1478,13 +1490,13 @@ static struct regulator *_regulator_get(struct device *dev, const char *id,
 			devname, id);
 
 		rdev = dummy_regulator_rdev;
+		mutex_lock(&rdev->mutex);
 		goto found;
 	/* Don't log an error when called from regulator_get_optional() */
 	} else if (!have_full_constraints() || exclusive) {
 		dev_warn(dev, "dummy supplies not allowed\n");
 	}
 
-	mutex_unlock(&regulator_list_mutex);
 	return regulator;
 
 found:
@@ -1526,8 +1538,7 @@ found:
 	}
 
 out:
-	mutex_unlock(&regulator_list_mutex);
-
+	mutex_unlock(&rdev->mutex);
 	return regulator;
 }
 
@@ -1986,12 +1997,24 @@ static int _regulator_do_enable(struct regulator_dev *rdev)
 	return 0;
 }
 
-/* locks held by regulator_enable() */
-static int _regulator_enable(struct regulator_dev *rdev)
+static int _regulator_enable(struct regulator *regulator, bool do_lock)
 {
-	int ret;
+	struct regulator_dev *rdev = regulator->rdev;
+	int ret = 0;
 
-	lockdep_assert_held_once(&rdev->mutex);
+	if (regulator->always_on)
+		return 0;
+
+	if (rdev->supply) {
+		ret = regulator_enable(rdev->supply);
+		if (ret != 0)
+			return ret;
+	}
+
+	if (do_lock)
+		mutex_lock(&rdev->mutex);
+	else
+		lockdep_assert_held_once(&rdev->mutex);
 
 	/* check voltage and requested load before enabling */
 	if (rdev->constraints &&
@@ -2002,23 +2025,33 @@ static int _regulator_enable(struct regulator_dev *rdev)
 		/* The regulator may on if it's not switchable or left on */
 		ret = _regulator_is_enabled(rdev);
 		if (ret == -EINVAL || ret == 0) {
-			if (!_regulator_can_change_status(rdev))
-				return -EPERM;
+			if (!_regulator_can_change_status(rdev)) {
+				ret = -EPERM;
+				goto out;
+			}
 
 			ret = _regulator_do_enable(rdev);
 			if (ret < 0)
-				return ret;
+				goto out;
 
 		} else if (ret < 0) {
 			rdev_err(rdev, "is_enabled() failed: %d\n", ret);
-			return ret;
+			goto out;
 		}
 		/* Fallthrough on positive return values - already enabled */
+		ret = 0;
 	}
 
 	rdev->use_count++;
 
-	return 0;
+out:
+	if (do_lock)
+		mutex_unlock(&rdev->mutex);
+
+	if (ret != 0 && rdev->supply)
+		regulator_disable(rdev->supply);
+
+	return ret;
 }
 
 /**
@@ -2034,26 +2067,7 @@ static int _regulator_enable(struct regulator_dev *rdev)
  */
 int regulator_enable(struct regulator *regulator)
 {
-	struct regulator_dev *rdev = regulator->rdev;
-	int ret = 0;
-
-	if (regulator->always_on)
-		return 0;
-
-	if (rdev->supply) {
-		ret = regulator_enable(rdev->supply);
-		if (ret != 0)
-			return ret;
-	}
-
-	mutex_lock(&rdev->mutex);
-	ret = _regulator_enable(rdev);
-	mutex_unlock(&rdev->mutex);
-
-	if (ret != 0 && rdev->supply)
-		regulator_disable(rdev->supply);
-
-	return ret;
+	return _regulator_enable(regulator, true);
 }
 EXPORT_SYMBOL_GPL(regulator_enable);
 
-- 
2.4.3



From tomeu.vizoso at collabora.com  Thu Aug  6 07:11:47 2015
From: tomeu.vizoso at collabora.com (Tomeu Vizoso)
Date: Thu,  6 Aug 2015 16:11:47 +0200
Subject: [PATCH v3 10/18] pwm: Probe PWM chip devices on demand
In-Reply-To: <1438870315-18689-1-git-send-email-tomeu.vizoso@collabora.com>
References: <1438870315-18689-1-git-send-email-tomeu.vizoso@collabora.com>
Message-ID: <1438870315-18689-11-git-send-email-tomeu.vizoso@collabora.com>

When looking up a PWM chip through its OF node, probe it if it hasn't
already.

The goal is to reduce deferred probes to a minimum, as it makes it very
cumbersome to find out why a device failed to probe, and can introduce
very big delays in when a critical device is probed.

Signed-off-by: Tomeu Vizoso <tomeu.vizoso at collabora.com>
---

Changes in v3: None
Changes in v2: None

 drivers/pwm/core.c | 3 +++
 1 file changed, 3 insertions(+)

diff --git a/drivers/pwm/core.c b/drivers/pwm/core.c
index 3a7769fe53de..86649ab60cad 100644
--- a/drivers/pwm/core.c
+++ b/drivers/pwm/core.c
@@ -29,6 +29,7 @@
 #include <linux/device.h>
 #include <linux/debugfs.h>
 #include <linux/seq_file.h>
+#include <linux/of_platform.h>
 
 #include <dt-bindings/pwm/pwm.h>
 
@@ -496,6 +497,8 @@ static struct pwm_chip *of_node_to_pwmchip(struct device_node *np)
 {
 	struct pwm_chip *chip;
 
+	of_platform_probe(np);
+
 	mutex_lock(&pwm_lock);
 
 	list_for_each_entry(chip, &pwm_chips, list)
-- 
2.4.3



From tomeu.vizoso at collabora.com  Thu Aug  6 07:11:45 2015
From: tomeu.vizoso at collabora.com (Tomeu Vizoso)
Date: Thu,  6 Aug 2015 16:11:45 +0200
Subject: [PATCH v3 08/18] drm/tegra: Probe dpaux devices on demand
In-Reply-To: <1438870315-18689-1-git-send-email-tomeu.vizoso@collabora.com>
References: <1438870315-18689-1-git-send-email-tomeu.vizoso@collabora.com>
Message-ID: <1438870315-18689-9-git-send-email-tomeu.vizoso@collabora.com>

When looking up a dpaux device through its OF node, probe it if it
hasn't already.

The goal is to reduce deferred probes to a minimum, as it makes it very
cumbersome to find out why a device failed to probe, and can introduce
very big delays in when a critical device is probed.

Signed-off-by: Tomeu Vizoso <tomeu.vizoso at collabora.com>
---

Changes in v3: None
Changes in v2: None

 drivers/gpu/drm/tegra/dpaux.c | 3 +++
 1 file changed, 3 insertions(+)

diff --git a/drivers/gpu/drm/tegra/dpaux.c b/drivers/gpu/drm/tegra/dpaux.c
index 07b26972f487..5a98acf07b2d 100644
--- a/drivers/gpu/drm/tegra/dpaux.c
+++ b/drivers/gpu/drm/tegra/dpaux.c
@@ -12,6 +12,7 @@
 #include <linux/interrupt.h>
 #include <linux/io.h>
 #include <linux/of_gpio.h>
+#include <linux/of_platform.h>
 #include <linux/platform_device.h>
 #include <linux/reset.h>
 #include <linux/regulator/consumer.h>
@@ -394,6 +395,8 @@ struct tegra_dpaux *tegra_dpaux_find_by_of_node(struct device_node *np)
 {
 	struct tegra_dpaux *dpaux;
 
+	of_platform_probe(np);
+
 	mutex_lock(&dpaux_lock);
 
 	list_for_each_entry(dpaux, &dpaux_list, list)
-- 
2.4.3



From tomeu.vizoso at collabora.com  Thu Aug  6 07:11:46 2015
From: tomeu.vizoso at collabora.com (Tomeu Vizoso)
Date: Thu,  6 Aug 2015 16:11:46 +0200
Subject: [PATCH v3 09/18] i2c: core: Probe i2c adapters and devices on demand
In-Reply-To: <1438870315-18689-1-git-send-email-tomeu.vizoso@collabora.com>
References: <1438870315-18689-1-git-send-email-tomeu.vizoso@collabora.com>
Message-ID: <1438870315-18689-10-git-send-email-tomeu.vizoso@collabora.com>

When looking up an i2c adapter or device through its OF node, probe it
if it hasn't already.

The goal is to reduce deferred probes to a minimum, as it makes it very
cumbersome to find out why a device failed to probe, and can introduce
very big delays in when a critical device is probed.

Signed-off-by: Tomeu Vizoso <tomeu.vizoso at collabora.com>
---

Changes in v3: None
Changes in v2: None

 drivers/i2c/i2c-core.c | 5 +++++
 1 file changed, 5 insertions(+)

diff --git a/drivers/i2c/i2c-core.c b/drivers/i2c/i2c-core.c
index c83e4d13cfc5..9c507b558fa2 100644
--- a/drivers/i2c/i2c-core.c
+++ b/drivers/i2c/i2c-core.c
@@ -40,6 +40,7 @@
 #include <linux/of.h>
 #include <linux/of_device.h>
 #include <linux/of_irq.h>
+#include <linux/of_platform.h>
 #include <linux/clk/clk-conf.h>
 #include <linux/completion.h>
 #include <linux/hardirq.h>
@@ -1342,6 +1343,8 @@ struct i2c_client *of_find_i2c_device_by_node(struct device_node *node)
 	struct device *dev;
 	struct i2c_client *client;
 
+	of_platform_probe(node);
+
 	dev = bus_find_device(&i2c_bus_type, NULL, node, of_dev_node_match);
 	if (!dev)
 		return NULL;
@@ -1360,6 +1363,8 @@ struct i2c_adapter *of_find_i2c_adapter_by_node(struct device_node *node)
 	struct device *dev;
 	struct i2c_adapter *adapter;
 
+	of_platform_probe(node);
+
 	dev = bus_find_device(&i2c_bus_type, NULL, node, of_dev_node_match);
 	if (!dev)
 		return NULL;
-- 
2.4.3



From tomeu.vizoso at collabora.com  Thu Aug  6 07:11:49 2015
From: tomeu.vizoso at collabora.com (Tomeu Vizoso)
Date: Thu,  6 Aug 2015 16:11:49 +0200
Subject: [PATCH v3 12/18] usb: phy: Probe phy devices on demand
In-Reply-To: <1438870315-18689-1-git-send-email-tomeu.vizoso@collabora.com>
References: <1438870315-18689-1-git-send-email-tomeu.vizoso@collabora.com>
Message-ID: <1438870315-18689-13-git-send-email-tomeu.vizoso@collabora.com>

When looking up a phy through its OF node, probe it if it hasn't
already.

The goal is to reduce deferred probes to a minimum, as it makes it very
cumbersome to find out why a device failed to probe, and can introduce
very big delays in when a critical device is probed.

Signed-off-by: Tomeu Vizoso <tomeu.vizoso at collabora.com>
---

Changes in v3: None
Changes in v2: None

 drivers/usb/phy/phy.c | 3 +++
 1 file changed, 3 insertions(+)

diff --git a/drivers/usb/phy/phy.c b/drivers/usb/phy/phy.c
index 98f75d2842b7..a357681362f5 100644
--- a/drivers/usb/phy/phy.c
+++ b/drivers/usb/phy/phy.c
@@ -15,6 +15,7 @@
 #include <linux/module.h>
 #include <linux/slab.h>
 #include <linux/of.h>
+#include <linux/of_platform.h>
 
 #include <linux/usb/phy.h>
 
@@ -196,6 +197,8 @@ struct  usb_phy *devm_usb_get_phy_by_node(struct device *dev,
 		goto err0;
 	}
 
+	of_platform_probe(node);
+
 	spin_lock_irqsave(&phy_lock, flags);
 
 	phy = __of_usb_find_phy(node);
-- 
2.4.3



From tomeu.vizoso at collabora.com  Thu Aug  6 07:11:54 2015
From: tomeu.vizoso at collabora.com (Tomeu Vizoso)
Date: Thu,  6 Aug 2015 16:11:54 +0200
Subject: [PATCH v3 17/18] power-supply: Probe power supplies on demand
In-Reply-To: <1438870315-18689-1-git-send-email-tomeu.vizoso@collabora.com>
References: <1438870315-18689-1-git-send-email-tomeu.vizoso@collabora.com>
Message-ID: <1438870315-18689-18-git-send-email-tomeu.vizoso@collabora.com>

When looking up a power supply through its OF node, probe it if it
hasn't already.

The goal is to reduce deferred probes to a minimum, as it makes it very
cumbersome to find out why a device failed to probe, and can introduce
very big delays in when a critical device is probed.

Signed-off-by: Tomeu Vizoso <tomeu.vizoso at collabora.com>
---

Changes in v3: None
Changes in v2: None

 drivers/power/power_supply_core.c | 3 +++
 1 file changed, 3 insertions(+)

diff --git a/drivers/power/power_supply_core.c b/drivers/power/power_supply_core.c
index 456987c88baa..668d71656592 100644
--- a/drivers/power/power_supply_core.c
+++ b/drivers/power/power_supply_core.c
@@ -19,6 +19,7 @@
 #include <linux/err.h>
 #include <linux/power_supply.h>
 #include <linux/thermal.h>
+#include <linux/of_platform.h>
 #include "power_supply.h"
 
 /* exported for the APM Power driver, APM emulation */
@@ -206,6 +207,8 @@ static int power_supply_find_supply_from_node(struct device_node *supply_node)
 {
 	int error;
 
+	of_platform_probe(supply_node);
+
 	/*
 	 * class_for_each_device() either returns its own errors or values
 	 * returned by __power_supply_find_supply_from_node().
-- 
2.4.3



From tomeu.vizoso at collabora.com  Thu Aug  6 07:11:55 2015
From: tomeu.vizoso at collabora.com (Tomeu Vizoso)
Date: Thu,  6 Aug 2015 16:11:55 +0200
Subject: [PATCH v3 18/18] ASoC: core: Probe components on demand
In-Reply-To: <1438870315-18689-1-git-send-email-tomeu.vizoso@collabora.com>
References: <1438870315-18689-1-git-send-email-tomeu.vizoso@collabora.com>
Message-ID: <1438870315-18689-19-git-send-email-tomeu.vizoso@collabora.com>

When looking up a component through its OF node, probe it if it hasn't
already.

The goal is to reduce deferred probes to a minimum, as it makes it very
cumbersome to find out why a device failed to probe, and can introduce
very big delays in when a critical device is probed.

Signed-off-by: Tomeu Vizoso <tomeu.vizoso at collabora.com>
---

Changes in v3: None
Changes in v2: None

 sound/soc/soc-core.c | 7 ++++++-
 1 file changed, 6 insertions(+), 1 deletion(-)

diff --git a/sound/soc/soc-core.c b/sound/soc/soc-core.c
index c81aec9c872a..1157049b1a34 100644
--- a/sound/soc/soc-core.c
+++ b/sound/soc/soc-core.c
@@ -34,6 +34,7 @@
 #include <linux/ctype.h>
 #include <linux/slab.h>
 #include <linux/of.h>
+#include <linux/of_platform.h>
 #include <sound/core.h>
 #include <sound/jack.h>
 #include <sound/pcm.h>
@@ -865,10 +866,12 @@ static const struct snd_soc_dai_ops null_dai_ops = {
 };
 
 static struct snd_soc_component *soc_find_component(
-	const struct device_node *of_node, const char *name)
+	struct device_node *of_node, const char *name)
 {
 	struct snd_soc_component *component;
 
+	of_platform_probe(of_node);
+
 	lockdep_assert_held(&client_mutex);
 
 	list_for_each_entry(component, &component_list, list) {
@@ -890,6 +893,8 @@ static struct snd_soc_dai *snd_soc_find_dai(
 	struct snd_soc_dai *dai;
 	struct device_node *component_of_node;
 
+	of_platform_probe(dlc->of_node);
+
 	lockdep_assert_held(&client_mutex);
 
 	/* Find CPU DAI from registered DAIs*/
-- 
2.4.3



From tomeu.vizoso at collabora.com  Thu Aug  6 07:11:53 2015
From: tomeu.vizoso at collabora.com (Tomeu Vizoso)
Date: Thu,  6 Aug 2015 16:11:53 +0200
Subject: [PATCH v3 16/18] dma: of: Probe DMA controllers on demand
In-Reply-To: <1438870315-18689-1-git-send-email-tomeu.vizoso@collabora.com>
References: <1438870315-18689-1-git-send-email-tomeu.vizoso@collabora.com>
Message-ID: <1438870315-18689-17-git-send-email-tomeu.vizoso@collabora.com>

When looking up a DMA controller through its OF node, probe it if it
hasn't already.

The goal is to reduce deferred probes to a minimum, as it makes it very
cumbersome to find out why a device failed to probe, and can introduce
very big delays in when a critical device is probed.

Signed-off-by: Tomeu Vizoso <tomeu.vizoso at collabora.com>
---

Changes in v3: None
Changes in v2: None

 drivers/dma/of-dma.c | 3 +++
 1 file changed, 3 insertions(+)

diff --git a/drivers/dma/of-dma.c b/drivers/dma/of-dma.c
index 1e1f2986eba8..9cfc818b9dc8 100644
--- a/drivers/dma/of-dma.c
+++ b/drivers/dma/of-dma.c
@@ -17,6 +17,7 @@
 #include <linux/slab.h>
 #include <linux/of.h>
 #include <linux/of_dma.h>
+#include <linux/of_platform.h>
 
 static LIST_HEAD(of_dma_list);
 static DEFINE_MUTEX(of_dma_lock);
@@ -263,6 +264,8 @@ struct dma_chan *of_dma_request_slave_channel(struct device_node *np,
 		if (of_dma_match_channel(np, name, i, &dma_spec))
 			continue;
 
+		of_platform_probe(dma_spec.np);
+
 		mutex_lock(&of_dma_lock);
 		ofdma = of_dma_find_controller(&dma_spec);
 
-- 
2.4.3



From tomeu.vizoso at collabora.com  Thu Aug  6 07:11:48 2015
From: tomeu.vizoso at collabora.com (Tomeu Vizoso)
Date: Thu,  6 Aug 2015 16:11:48 +0200
Subject: [PATCH v3 11/18] backlight: Probe backlight devices on demand
In-Reply-To: <1438870315-18689-1-git-send-email-tomeu.vizoso@collabora.com>
References: <1438870315-18689-1-git-send-email-tomeu.vizoso@collabora.com>
Message-ID: <1438870315-18689-12-git-send-email-tomeu.vizoso@collabora.com>

When looking up a backlight device through its OF node, probe it if it
hasn't already.

The goal is to reduce deferred probes to a minimum, as it makes it very
cumbersome to find out why a device failed to probe, and can introduce
very big delays in when a critical device is probed.

Signed-off-by: Tomeu Vizoso <tomeu.vizoso at collabora.com>
---

Changes in v3: None
Changes in v2: None

 drivers/video/backlight/backlight.c | 3 +++
 1 file changed, 3 insertions(+)

diff --git a/drivers/video/backlight/backlight.c b/drivers/video/backlight/backlight.c
index bddc8b17a4d8..cad854196ee3 100644
--- a/drivers/video/backlight/backlight.c
+++ b/drivers/video/backlight/backlight.c
@@ -16,6 +16,7 @@
 #include <linux/err.h>
 #include <linux/fb.h>
 #include <linux/slab.h>
+#include <linux/of_platform.h>
 
 #ifdef CONFIG_PMAC_BACKLIGHT
 #include <asm/backlight.h>
@@ -559,6 +560,8 @@ struct backlight_device *of_find_backlight_by_node(struct device_node *node)
 {
 	struct device *dev;
 
+	of_platform_probe(node);
+
 	dev = class_find_device(backlight_class, NULL, node, of_parent_match);
 
 	return dev ? to_backlight_device(dev) : NULL;
-- 
2.4.3



From tomeu.vizoso at collabora.com  Thu Aug  6 07:11:50 2015
From: tomeu.vizoso at collabora.com (Tomeu Vizoso)
Date: Thu,  6 Aug 2015 16:11:50 +0200
Subject: [PATCH v3 13/18] clk: Probe clk providers on demand
In-Reply-To: <1438870315-18689-1-git-send-email-tomeu.vizoso@collabora.com>
References: <1438870315-18689-1-git-send-email-tomeu.vizoso@collabora.com>
Message-ID: <1438870315-18689-14-git-send-email-tomeu.vizoso@collabora.com>

When looking up a clock through its OF node, probe it if it hasn't
already.

The goal is to reduce deferred probes to a minimum, as it makes it very
cumbersome to find out why a device failed to probe, and can introduce
very big delays in when a critical device is probed.

Signed-off-by: Tomeu Vizoso <tomeu.vizoso at collabora.com>
---

Changes in v3: None
Changes in v2: None

 drivers/clk/clk.c | 3 +++
 1 file changed, 3 insertions(+)

diff --git a/drivers/clk/clk.c b/drivers/clk/clk.c
index 898052ee0efa..065870e38881 100644
--- a/drivers/clk/clk.c
+++ b/drivers/clk/clk.c
@@ -19,6 +19,7 @@
 #include <linux/list.h>
 #include <linux/slab.h>
 #include <linux/of.h>
+#include <linux/of_platform.h>
 #include <linux/device.h>
 #include <linux/init.h>
 #include <linux/sched.h>
@@ -2981,6 +2982,8 @@ struct clk *__of_clk_get_from_provider(struct of_phandle_args *clkspec,
 	if (!clkspec)
 		return ERR_PTR(-EINVAL);
 
+	of_platform_probe(clkspec->np);
+
 	/* Check if we have such a provider in our array */
 	mutex_lock(&of_clk_mutex);
 	list_for_each_entry(provider, &of_clk_providers, link) {
-- 
2.4.3



From tomeu.vizoso at collabora.com  Thu Aug  6 07:11:51 2015
From: tomeu.vizoso at collabora.com (Tomeu Vizoso)
Date: Thu,  6 Aug 2015 16:11:51 +0200
Subject: [PATCH v3 14/18] pinctrl: Probe pinctrl devices on demand
In-Reply-To: <1438870315-18689-1-git-send-email-tomeu.vizoso@collabora.com>
References: <1438870315-18689-1-git-send-email-tomeu.vizoso@collabora.com>
Message-ID: <1438870315-18689-15-git-send-email-tomeu.vizoso@collabora.com>

When looking up a pin controller through its OF node, probe it if it
hasn't already.

The goal is to reduce deferred probes to a minimum, as it makes it very
cumbersome to find out why a device failed to probe, and can introduce
very big delays in when a critical device is probed.

Signed-off-by: Tomeu Vizoso <tomeu.vizoso at collabora.com>
---

Changes in v3: None
Changes in v2: None

 drivers/pinctrl/devicetree.c | 3 +++
 1 file changed, 3 insertions(+)

diff --git a/drivers/pinctrl/devicetree.c b/drivers/pinctrl/devicetree.c
index fe04e748dfe4..2326ae99e06a 100644
--- a/drivers/pinctrl/devicetree.c
+++ b/drivers/pinctrl/devicetree.c
@@ -18,6 +18,7 @@
 
 #include <linux/device.h>
 #include <linux/of.h>
+#include <linux/of_platform.h>
 #include <linux/pinctrl/pinctrl.h>
 #include <linux/slab.h>
 
@@ -110,6 +111,8 @@ static int dt_to_map_one_config(struct pinctrl *p, const char *statename,
 	struct pinctrl_map *map;
 	unsigned num_maps;
 
+	of_platform_probe(np_config);
+
 	/* Find the pin controller containing np_config */
 	np_pctldev = of_node_get(np_config);
 	for (;;) {
-- 
2.4.3



From tomeu.vizoso at collabora.com  Thu Aug  6 07:11:52 2015
From: tomeu.vizoso at collabora.com (Tomeu Vizoso)
Date: Thu,  6 Aug 2015 16:11:52 +0200
Subject: [PATCH v3 15/18] phy: core: Probe phy providers on demand
In-Reply-To: <1438870315-18689-1-git-send-email-tomeu.vizoso@collabora.com>
References: <1438870315-18689-1-git-send-email-tomeu.vizoso@collabora.com>
Message-ID: <1438870315-18689-16-git-send-email-tomeu.vizoso@collabora.com>

When looking up a phy provider through its OF node, probe it if it
hasn't already.

The goal is to reduce deferred probes to a minimum, as it makes it very
cumbersome to find out why a device failed to probe, and can introduce
very big delays in when a critical device is probed.

Signed-off-by: Tomeu Vizoso <tomeu.vizoso at collabora.com>
---

Changes in v3: None
Changes in v2: None

 drivers/phy/phy-core.c | 3 +++
 1 file changed, 3 insertions(+)

diff --git a/drivers/phy/phy-core.c b/drivers/phy/phy-core.c
index fc48fac003a6..1ba55fc8cce4 100644
--- a/drivers/phy/phy-core.c
+++ b/drivers/phy/phy-core.c
@@ -18,6 +18,7 @@
 #include <linux/device.h>
 #include <linux/slab.h>
 #include <linux/of.h>
+#include <linux/of_platform.h>
 #include <linux/phy/phy.h>
 #include <linux/idr.h>
 #include <linux/pm_runtime.h>
@@ -363,6 +364,8 @@ static struct phy *_of_phy_get(struct device_node *np, int index)
 	if (ret)
 		return ERR_PTR(-ENODEV);
 
+	of_platform_probe(args.np);
+
 	mutex_lock(&phy_provider_mutex);
 	phy_provider = of_phy_provider_lookup(args.np);
 	if (IS_ERR(phy_provider) || !try_module_get(phy_provider->owner)) {
-- 
2.4.3



From ykk at rock-chips.com  Thu Aug  6 07:19:38 2015
From: ykk at rock-chips.com (Yakir Yang)
Date: Thu,  6 Aug 2015 09:19:38 -0500
Subject: [RFC PATCH 4/8] drm: rockchip/dp: add rockchip platform dp driver
In-Reply-To: <1438868947-22132-1-git-send-email-ykk@rock-chips.com>
References: <1438868947-22132-1-git-send-email-ykk@rock-chips.com>
Message-ID: <1438870778-23847-1-git-send-email-ykk@rock-chips.com>

Rockchip have three clocks for dp controller, we leave pclk_edp
to analogix_dp driver control, and keep the sclk_edp_24m and
sclk_edp in platform driver.

Signed-off-by: Yakir Yang <ykk at rock-chips.com>
---
 drivers/gpu/drm/rockchip/Kconfig                |  10 +
 drivers/gpu/drm/rockchip/Makefile               |   1 +
 drivers/gpu/drm/rockchip/analogix_dp-rockchip.c | 419 ++++++++++++++++++++++++
 3 files changed, 430 insertions(+)
 create mode 100644 drivers/gpu/drm/rockchip/analogix_dp-rockchip.c

diff --git a/drivers/gpu/drm/rockchip/Kconfig b/drivers/gpu/drm/rockchip/Kconfig
index 35215f6..096ed77 100644
--- a/drivers/gpu/drm/rockchip/Kconfig
+++ b/drivers/gpu/drm/rockchip/Kconfig
@@ -25,3 +25,13 @@ config ROCKCHIP_DW_HDMI
 	  for the Synopsys DesignWare HDMI driver. If you want to
 	  enable HDMI on RK3288 based SoC, you should selet this
 	  option.
+
+
+config ROCKCHIP_ANALOGIX_DP
+        tristate "Rockchip specific extensions for Analogix DP driver"
+        depends on DRM_ROCKCHIP
+        select DRM_ANALOGIX_DP
+        help
+	  This selects support for Rockchip SoC specific extensions
+	  for the Analogix Core DP driver. If you want to enable DP
+	  on RK3288 based SoC, you should selet this option.
diff --git a/drivers/gpu/drm/rockchip/Makefile b/drivers/gpu/drm/rockchip/Makefile
index f3d8a19..8ad01fb 100644
--- a/drivers/gpu/drm/rockchip/Makefile
+++ b/drivers/gpu/drm/rockchip/Makefile
@@ -6,5 +6,6 @@ rockchipdrm-y := rockchip_drm_drv.o rockchip_drm_fb.o rockchip_drm_fbdev.o \
 		rockchip_drm_gem.o
 
 obj-$(CONFIG_ROCKCHIP_DW_HDMI) += dw_hdmi-rockchip.o
+obj-$(CONFIG_ROCKCHIP_ANALOGIX_DP) += analogix_dp-rockchip.o
 
 obj-$(CONFIG_DRM_ROCKCHIP) += rockchipdrm.o rockchip_drm_vop.o
diff --git a/drivers/gpu/drm/rockchip/analogix_dp-rockchip.c b/drivers/gpu/drm/rockchip/analogix_dp-rockchip.c
new file mode 100644
index 0000000..804048c
--- /dev/null
+++ b/drivers/gpu/drm/rockchip/analogix_dp-rockchip.c
@@ -0,0 +1,419 @@
+/*
+ * Rockchip SoC DP (Display Port) interface driver.
+ *
+ * Copyright (C) Fuzhou Rockchip Electronics Co., Ltd.
+ * Author: Andy Yan <andy.yan at rock-chips.com>
+ *         Jeff Chen <jeff.chen at rock-chips.com>
+ *         Yakir Yang <ykk at 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.
+ */
+#include <drm/drmP.h>
+#include <drm/drm_crtc_helper.h>
+#include <drm/drm_panel.h>
+#include <drm/drm_of.h>
+#include <drm/drm_dp_helper.h>
+
+#include <linux/component.h>
+#include <linux/clk.h>
+#include <linux/mfd/syscon.h>
+#include <linux/regmap.h>
+#include <linux/reset.h>
+
+#include <video/of_videomode.h>
+#include <video/videomode.h>
+
+#include <drm/bridge/analogix_dp.h>
+
+#include "rockchip_drm_drv.h"
+#include "rockchip_drm_vop.h"
+
+#define encoder_to_dp(c) \
+		container_of(c, struct rockchip_dp_device, encoder)
+
+#define plat_data_to_dp(pd) \
+		container_of(pd, struct rockchip_dp_device, plat_data)
+
+/* dp grf register offset */
+#define DP_VOP_SEL                              0x025c /* grf_soc_con6 */
+#define DP_REF_CLK_SEL                          0x0274 /* grf_soc_con12 */
+
+#define GRF_DP_REF_CLK_SEL_INTER                BIT(4)
+#define DP_SEL_VOP_LIT				BIT(5)
+
+struct rockchip_dp_device {
+	struct drm_device        *drm_dev;
+	struct device            *dev;
+	struct drm_encoder       encoder;
+	struct drm_display_mode  mode;
+
+	struct clk               *clk_dp;
+	struct clk               *clk_24m_parent;
+	struct clk               *clk_24m;
+	struct regmap            *grf;
+	struct reset_control     *rst;
+
+	struct analogix_dp_plat_data plat_data;
+};
+
+static int rockchip_dp_clk_enable(struct rockchip_dp_device *dp)
+{
+	int ret = 0;
+
+	ret = clk_prepare_enable(dp->clk_dp);
+	if (ret < 0) {
+		dev_err(dp->dev, "cannot enable clk_dp %d\n", ret);
+		goto err_clk_dp;
+	}
+
+	ret = clk_set_rate(dp->clk_24m, 24000000);
+	if (ret < 0) {
+		dev_err(dp->dev, "cannot set dp clk_24m %d\n",
+			ret);
+		goto err_clk_24m;
+	}
+
+	ret = clk_prepare_enable(dp->clk_24m);
+	if (ret < 0) {
+		dev_err(dp->dev, "cannot enable dp clk_24m %d\n",
+			ret);
+		goto err_clk_24m;
+	}
+
+	return 0;
+
+err_clk_24m:
+	clk_disable_unprepare(dp->clk_dp);
+err_clk_dp:
+	return ret;
+}
+
+static int rockchip_dp_clk_disable(struct rockchip_dp_device *dp)
+{
+	clk_disable_unprepare(dp->clk_dp);
+	clk_disable_unprepare(dp->clk_24m);
+
+	return 0;
+}
+
+static int rockchip_dp_pre_init(struct rockchip_dp_device *dp)
+{
+	u32 val;
+	int ret;
+
+	val = GRF_DP_REF_CLK_SEL_INTER | (GRF_DP_REF_CLK_SEL_INTER << 16);
+	ret = regmap_write(dp->grf, DP_REF_CLK_SEL, val);
+	if (ret != 0) {
+		dev_err(dp->dev, "Could not write to GRF: %d\n", ret);
+		return ret;
+	}
+
+	reset_control_assert(dp->rst);
+	usleep_range(10, 20);
+	reset_control_deassert(dp->rst);
+
+	return 0;
+}
+
+static int rockchip_dp_poweron(struct analogix_dp_plat_data *plat_data)
+{
+	struct rockchip_dp_device *dp = plat_data_to_dp(plat_data);
+	int ret;
+
+	ret = rockchip_dp_clk_enable(dp);
+	if (ret < 0) {
+		dev_err(dp->dev, "cannot enable dp clk %d\n", ret);
+		return -1;
+	}
+
+	ret = rockchip_dp_pre_init(dp);
+	if (ret < 0) {
+		dev_err(dp->dev, "dp pre init fail %d\n", ret);
+		return -1;
+	}
+
+	return 0;
+}
+
+static int rockchip_dp_poweroff(struct analogix_dp_plat_data *plat_data)
+{
+	struct rockchip_dp_device *dp = plat_data_to_dp(plat_data);
+
+	rockchip_dp_clk_disable(dp);
+
+	return 0;
+}
+
+static bool
+rockchip_dp_drm_encoder_mode_fixup(struct drm_encoder *encoder,
+				   const struct drm_display_mode *mode,
+				   struct drm_display_mode *adjusted_mode)
+{
+	/* do nothing */
+	return true;
+}
+
+static void rockchip_dp_drm_encoder_mode_set(struct drm_encoder *encoder,
+					     struct drm_display_mode *mode,
+					     struct drm_display_mode *adjusted)
+{
+	/* do nothing */
+}
+
+static void rockchip_dp_drm_encoder_prepare(struct drm_encoder *encoder)
+{
+	struct rockchip_dp_device *dp = encoder_to_dp(encoder);
+	u32 val;
+	int ret;
+
+	ret = rockchip_drm_crtc_mode_config(encoder->crtc,
+					    DRM_MODE_CONNECTOR_eDP,
+					    ROCKCHIP_OUT_MODE_AAAA);
+	if (ret < 0) {
+		dev_err(dp->dev, "Could not set crtc mode config: %d.\n", ret);
+		return;
+	}
+
+	ret = rockchip_drm_encoder_get_mux_id(dp->dev->of_node, encoder);
+	if (ret < 0)
+		return;
+
+	if (ret)
+		val = DP_SEL_VOP_LIT | (DP_SEL_VOP_LIT << 16);
+	else
+		val = DP_SEL_VOP_LIT << 16;
+
+	dev_info(dp->dev, "vop %s output to dp\n", (ret) ? "LIT" : "BIG");
+
+	ret = regmap_write(dp->grf, DP_VOP_SEL, val);
+	if (ret != 0) {
+		dev_err(dp->dev, "Could not write to GRF: %d\n", ret);
+		return;
+	}
+}
+
+static void rockchip_dp_drm_encoder_nop(struct drm_encoder *encoder)
+{
+	/* do nothing */
+}
+
+static struct drm_encoder_helper_funcs rockchip_dp_encoder_helper_funcs = {
+	.mode_fixup = rockchip_dp_drm_encoder_mode_fixup,
+	.mode_set = rockchip_dp_drm_encoder_mode_set,
+	.prepare = rockchip_dp_drm_encoder_prepare,
+	.commit = rockchip_dp_drm_encoder_nop,
+	.disable = rockchip_dp_drm_encoder_nop,
+};
+
+static void rockchip_dp_drm_encoder_destroy(struct drm_encoder *encoder)
+{
+	drm_encoder_cleanup(encoder);
+}
+
+static struct drm_encoder_funcs rockchip_dp_encoder_funcs = {
+	.destroy = rockchip_dp_drm_encoder_destroy,
+};
+
+static int rockchip_dp_init(struct rockchip_dp_device *dp)
+{
+	struct device *dev = dp->dev;
+	struct device_node *np = dev->of_node;
+	int ret;
+
+	dp->grf = syscon_regmap_lookup_by_phandle(np, "rockchip,grf");
+	if (IS_ERR(dp->grf)) {
+		dev_err(dev,
+			"rk3288-dp needs rockchip,grf property\n");
+		return PTR_ERR(dp->grf);
+	}
+
+	dp->clk_dp = devm_clk_get(dev, "clk_dp");
+	if (IS_ERR(dp->clk_dp)) {
+		dev_err(dev, "cannot get clk_dp\n");
+		return PTR_ERR(dp->clk_dp);
+	}
+
+	dp->clk_24m = devm_clk_get(dev, "clk_dp_24m");
+	if (IS_ERR(dp->clk_24m)) {
+		dev_err(dev, "cannot get clk_dp_24m\n");
+		return PTR_ERR(dp->clk_24m);
+	}
+
+	dp->rst = devm_reset_control_get(dev, "dp");
+	if (IS_ERR(dp->rst)) {
+		dev_err(dev, "failed to get reset\n");
+		return PTR_ERR(dp->rst);
+	}
+
+	ret = rockchip_dp_clk_enable(dp);
+	if (ret < 0) {
+		dev_err(dp->dev, "cannot enable dp clk %d\n", ret);
+		return ret;
+	}
+
+	ret = rockchip_dp_pre_init(dp);
+	if (ret < 0) {
+		dev_err(dp->dev, "failed to pre init %d\n", ret);
+		return ret;
+	}
+
+	return 0;
+}
+
+static int rockchip_dp_drm_create_encoder(struct rockchip_dp_device *dp)
+{
+	struct drm_encoder *encoder = &dp->encoder;
+	struct drm_device *drm_dev = dp->drm_dev;
+	struct device *dev = dp->dev;
+	int ret;
+
+	encoder->possible_crtcs = drm_of_find_possible_crtcs(drm_dev,
+							     dev->of_node);
+	DRM_DEBUG_KMS("possible_crtcs = 0x%x\n", encoder->possible_crtcs);
+
+	ret = drm_encoder_init(drm_dev, encoder, &rockchip_dp_encoder_funcs,
+			       DRM_MODE_ENCODER_TMDS);
+	if (ret) {
+		DRM_ERROR("failed to initialize encoder with drm\n");
+		return ret;
+	}
+
+	drm_encoder_helper_add(encoder, &rockchip_dp_encoder_helper_funcs);
+
+	return 0;
+}
+
+static int rockchip_dp_bind(struct device *dev, struct device *master,
+			    void *data)
+{
+	struct rockchip_dp_device *dp = dev_get_drvdata(dev);
+	struct drm_device *drm_dev = data;
+	int ret;
+
+	/*
+	 * Just like the probe function said, we don't need the
+	 * device drvrate anymore, we should leave the charge to
+	 * analogix dp driver, set the device drvdata to NULL.
+	 */
+	dev_set_drvdata(dev, NULL);
+
+	ret = rockchip_dp_init(dp);
+	if (ret < 0)
+		return ret;
+
+	dp->drm_dev = drm_dev;
+
+	ret = rockchip_dp_drm_create_encoder(dp);
+	if (ret) {
+		DRM_ERROR("failed to create drm encoder\n");
+		return ret;
+	}
+
+	dp->plat_data.attach = NULL;
+	dp->plat_data.power_on = rockchip_dp_poweron;
+	dp->plat_data.power_off = rockchip_dp_poweroff;
+
+	return analogix_dp_bind(dev, dp->drm_dev, &dp->encoder,
+				&dp->plat_data);
+}
+
+static void rockchip_dp_unbind(struct device *dev, struct device *master,
+			       void *data)
+{
+	return analogix_dp_unbind(dev, master, data);
+}
+
+static const struct component_ops rockchip_dp_component_ops = {
+	.bind = rockchip_dp_bind,
+	.unbind = rockchip_dp_unbind,
+};
+
+static int rockchip_dp_probe(struct platform_device *pdev)
+{
+	struct device *dev = &pdev->dev;
+	struct device_node *panel_node;
+	struct rockchip_dp_device *dp;
+	struct drm_panel *panel;
+
+	panel_node = of_parse_phandle(dev->of_node, "rockchip,panel", 0);
+	if (!panel_node) {
+		DRM_ERROR("failed to find rockchip,panel dt node\n");
+		return -ENODEV;
+	}
+
+	panel = of_drm_find_panel(panel_node);
+	if (!panel) {
+		DRM_ERROR("failed to find panel\n");
+		of_node_put(panel_node);
+		return -EPROBE_DEFER;
+	}
+
+	of_node_put(panel_node);
+
+	dp = devm_kzalloc(dev, sizeof(*dp), GFP_KERNEL);
+	if (!dp)
+		return -ENOMEM;
+
+	dp->dev = dev;
+
+	dp->plat_data.panel = panel;
+
+	/*
+	 * We just use the drvdata until driver run into component
+	 * add function, and then we would set drvdata to null, so
+	 * that analogix dp driver could take charge of the drvdata.
+	 */
+	platform_set_drvdata(pdev, dp);
+
+	return component_add(dev, &rockchip_dp_component_ops);
+}
+
+static int rockchip_dp_remove(struct platform_device *pdev)
+{
+	component_del(&pdev->dev, &rockchip_dp_component_ops);
+
+	return 0;
+}
+
+#ifdef CONFIG_PM_SLEEP
+static int rockchip_dp_suspend(struct device *dev)
+{
+	return analogix_dp_suspend(dev);
+}
+
+static int rockchip_dp_resume(struct device *dev)
+{
+	return analogix_dp_resume(dev);
+}
+#endif
+
+static const struct dev_pm_ops rockchip_dp_pm_ops = {
+	SET_SYSTEM_SLEEP_PM_OPS(rockchip_dp_suspend, rockchip_dp_resume)
+};
+
+static const struct of_device_id rockchip_dp_dt_ids[] = {
+	{.compatible = "rockchip,rk3288-dp",},
+	{}
+};
+MODULE_DEVICE_TABLE(of, rockchip_dp_dt_ids);
+
+static struct platform_driver rockchip_dp_driver = {
+	.probe = rockchip_dp_probe,
+	.remove = rockchip_dp_remove,
+	.driver = {
+		   .name = "rockchip-dp",
+		   .owner = THIS_MODULE,
+		   .pm = &rockchip_dp_pm_ops,
+		   .of_match_table = of_match_ptr(rockchip_dp_dt_ids),
+	},
+};
+
+module_platform_driver(rockchip_dp_driver);
+
+MODULE_AUTHOR("Jeff chen <jeff.chen at rock-chips.com>");
+MODULE_AUTHOR("Yakir Yang <ykk at rock-chips.com>");
+MODULE_DESCRIPTION("Rockchip Specific Analogix-DP Driver Extension");
+MODULE_LICENSE("GPL v2");
-- 
2.1.2




From jingoohan1 at gmail.com  Thu Aug  6 07:19:35 2015
From: jingoohan1 at gmail.com (Jingoo Han)
Date: Thu, 6 Aug 2015 23:19:35 +0900
Subject: [RFC PATCH 2/8] drm: exynos/dp: convert to drm bridge mode
In-Reply-To: <1438870041-23130-1-git-send-email-ykk@rock-chips.com>
References: <1438868947-22132-1-git-send-email-ykk@rock-chips.com>
 <1438870041-23130-1-git-send-email-ykk@rock-chips.com>
Message-ID: <000001d0d052$f44fa3a0$dceeeae0$@com>

On Thursday, August 06, 2015 11:07 PM, Yakir Yang wrote:
> 
> In order to move exynos dp code to bridge directory,
> we need to convert driver drm bridge mode first. As
> dp driver already have a ptn3460 bridge, so we need
> to move ptn bridge to the next bridge of dp bridge.
> 
> Signed-off-by: Yakir Yang <ykk at rock-chips.com>
> ---
>  drivers/gpu/drm/exynos/exynos_dp_core.c | 196 ++++++++++++++++++++------------
>  drivers/gpu/drm/exynos/exynos_dp_core.h |   2 +
>  2 files changed, 126 insertions(+), 72 deletions(-)
> 
> diff --git a/drivers/gpu/drm/exynos/exynos_dp_core.c b/drivers/gpu/drm/exynos/exynos_dp_core.c
> index a8097a4..aa99e23 100644
> --- a/drivers/gpu/drm/exynos/exynos_dp_core.c
> +++ b/drivers/gpu/drm/exynos/exynos_dp_core.c
> @@ -3,6 +3,7 @@
>   *
>   * Copyright (C) 2012 Samsung Electronics Co., Ltd.
>   * Author: Jingoo Han <jg1.han at samsung.com>
> + *         Yakir Yang <ykk at rock-chips.com>

Please don't add this.
You just fixed some parts of this code. I don't find the reason
why you have to be added to author for this file.
If you want the title for an author, please send the patch
for a new IP, instead of modifying the exiting codes.

>   *
>   * 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
> @@ -998,59 +999,6 @@ static struct drm_connector_helper_funcs exynos_dp_connector_helper_funcs = {
>  	.best_encoder = exynos_dp_best_encoder,
>  };
> 
> -/* returns the number of bridges attached */
> -static int exynos_drm_attach_lcd_bridge(struct exynos_dp_device *dp,
> -					struct drm_encoder *encoder)
> -{
> -	int ret;
> -
> -	encoder->bridge = dp->bridge;
> -	dp->bridge->encoder = encoder;
> -	ret = drm_bridge_attach(encoder->dev, dp->bridge);
> -	if (ret) {
> -		DRM_ERROR("Failed to attach bridge to drm\n");
> -		return ret;
> -	}
> -
> -	return 0;
> -}
> -
> -static int exynos_dp_create_connector(struct exynos_drm_display *display,
> -				      struct drm_encoder *encoder)
> -{
> -	struct exynos_dp_device *dp = display_to_dp(display);
> -	struct drm_connector *connector = &dp->connector;
> -	int ret;
> -
> -	dp->encoder = encoder;
> -
> -	/* Pre-empt DP connector creation if there's a bridge */
> -	if (dp->bridge) {
> -		ret = exynos_drm_attach_lcd_bridge(dp, encoder);
> -		if (!ret)
> -			return 0;
> -	}
> -
> -	connector->polled = DRM_CONNECTOR_POLL_HPD;
> -
> -	ret = drm_connector_init(dp->drm_dev, connector,
> -				 &exynos_dp_connector_funcs,
> -				 DRM_MODE_CONNECTOR_eDP);
> -	if (ret) {
> -		DRM_ERROR("Failed to initialize connector with drm\n");
> -		return ret;
> -	}
> -
> -	drm_connector_helper_add(connector, &exynos_dp_connector_helper_funcs);
> -	drm_connector_register(connector);
> -	drm_mode_connector_attach_encoder(connector, encoder);
> -
> -	if (dp->panel)
> -		ret = drm_panel_attach(dp->panel, &dp->connector);
> -
> -	return ret;
> -}
> -
>  static void exynos_dp_phy_init(struct exynos_dp_device *dp)
>  {
>  	if (dp->phy)
> @@ -1115,23 +1063,126 @@ static void exynos_dp_poweroff(struct exynos_dp_device *dp)
>  	}
>  }
> 
> -static void exynos_dp_dpms(struct exynos_drm_display *display, int mode)
> +/* returns the number of bridges attached */
> +static int exynos_drm_attach_lcd_bridge(struct exynos_dp_device *dp,
> +		struct drm_encoder *encoder)
> +{
> +	int ret;
> +
> +	dp->bridge->next = dp->ptn_bridge;
> +	dp->bridge->encoder = encoder;
> +	ret = drm_bridge_attach(encoder->dev, dp->bridge);
> +	if (ret) {
> +		DRM_ERROR("Failed to attach ptn bridge to drm\n");
> +		return ret;
> +	}
> +
> +	return 0;
> +}
> +
> +static int exynos_dp_bridge_attach(struct drm_bridge *bridge)
> +{
> +
> +	struct exynos_dp_device *dp = bridge->driver_private;
> +	struct drm_encoder *encoder = dp->encoder;
> +	struct drm_connector *connector = &dp->connector;
> +	int ret;
> +
> +	if (!bridge->encoder) {
> +		DRM_ERROR("Parent encoder object not found");
> +		return -ENODEV;
> +	}
> +
> +	encoder->bridge = bridge;
> +
> +	/* Pre-empt DP connector creation if there's a bridge */
> +	if (dp->ptn_bridge) {
> +		ret = exynos_drm_attach_lcd_bridge(dp, encoder);
> +		if (ret)
> +			return -ENODEV;
> +	}
> +
> +	connector->polled = DRM_CONNECTOR_POLL_HPD;
> +
> +	ret = drm_connector_init(dp->drm_dev, connector,
> +			&exynos_dp_connector_funcs, DRM_MODE_CONNECTOR_eDP);
> +	if (ret) {
> +		DRM_ERROR("Failed to initialize connector with drm\n");
> +		return ret;
> +	}
> +
> +	drm_connector_helper_add(connector, &exynos_dp_connector_helper_funcs);
> +	drm_connector_register(connector);
> +	drm_mode_connector_attach_encoder(connector, encoder);
> +
> +	if (dp->panel)
> +		ret = drm_panel_attach(dp->panel, &dp->connector);
> +
> +	return ret;
> +}
> +
> +static void exynos_dp_bridge_nop(struct drm_bridge *bridge)
> +{
> +	/* do nothing */
> +}
> +
> +static void exynos_dp_bridge_enable(struct drm_bridge *bridge)
> +{
> +	struct exynos_dp_device *dp = bridge->driver_private;
> +
> +	exynos_dp_poweron(dp);
> +	dp->dpms_mode = DRM_MODE_DPMS_ON;
> +}
> +
> +static void exynos_dp_bridge_disable(struct drm_bridge *bridge)
> +{
> +	struct exynos_dp_device *dp = bridge->driver_private;
> +
> +	exynos_dp_poweroff(dp);
> +	dp->dpms_mode = DRM_MODE_DPMS_OFF;
> +}
> +
> +static const struct drm_bridge_funcs exynos_dp_bridge_funcs = {
> +	.enable = exynos_dp_bridge_enable,
> +	.disable = exynos_dp_bridge_disable,
> +	.pre_enable = exynos_dp_bridge_nop,
> +	.post_disable = exynos_dp_bridge_nop,
> +	.attach = exynos_dp_bridge_attach,
> +};
> +
> +static int exynos_dp_create_connector(struct exynos_drm_display *display,
> +				struct drm_encoder *encoder)
>  {
>  	struct exynos_dp_device *dp = display_to_dp(display);
> +	struct drm_device *drm_dev = dp->drm_dev;
> +	struct drm_bridge *bridge;
> +	int ret;
> 
> -	switch (mode) {
> -	case DRM_MODE_DPMS_ON:
> -		exynos_dp_poweron(dp);
> -		break;
> -	case DRM_MODE_DPMS_STANDBY:
> -	case DRM_MODE_DPMS_SUSPEND:
> -	case DRM_MODE_DPMS_OFF:
> -		exynos_dp_poweroff(dp);
> -		break;
> -	default:
> -		break;
> +	bridge = devm_kzalloc(drm_dev->dev, sizeof(*bridge), GFP_KERNEL);
> +	if (!bridge) {
> +		DRM_ERROR("failed to allocate for drm bridge\n");
> +		return -ENOMEM;
>  	}
> -	dp->dpms_mode = mode;
> +
> +	dp->bridge = bridge;
> +	dp->encoder = encoder;
> +
> +	bridge->driver_private = dp;
> +	bridge->encoder = dp->encoder;
> +	bridge->funcs = &exynos_dp_bridge_funcs;
> +
> +	ret = drm_bridge_attach(drm_dev, bridge);
> +	if (ret) {
> +		DRM_ERROR("failed to attach drm bridge\n");
> +		return -EINVAL;
> +	}
> +
> +	return 0;
> +}
> +
> +static void exynos_dp_dpms(struct exynos_drm_display *display, int mode)
> +{
> +	/* do nothing */
>  }
> 
>  static struct exynos_drm_display_ops exynos_dp_display_ops = {
> @@ -1243,7 +1294,7 @@ static int exynos_dp_bind(struct device *dev, struct device *master, void *data)
>  		}
>  	}
> 
> -	if (!dp->panel && !dp->bridge) {
> +	if (!dp->panel && !dp->ptn_bridge) {
>  		ret = exynos_dp_dt_parse_panel(dp);
>  		if (ret)
>  			return ret;
> @@ -1316,7 +1367,7 @@ static void exynos_dp_unbind(struct device *dev, struct device *master,
>  {
>  	struct exynos_dp_device *dp = dev_get_drvdata(dev);
> 
> -	exynos_dp_dpms(&dp->display, DRM_MODE_DPMS_OFF);
> +	exynos_dp_bridge_disable(dp->bridge);
>  }
> 
>  static const struct component_ops exynos_dp_ops = {
> @@ -1351,9 +1402,9 @@ static int exynos_dp_probe(struct platform_device *pdev)
>  	if (endpoint) {
>  		bridge_node = of_graph_get_remote_port_parent(endpoint);
>  		if (bridge_node) {
> -			dp->bridge = of_drm_find_bridge(bridge_node);
> +			dp->ptn_bridge = of_drm_find_bridge(bridge_node);
>  			of_node_put(bridge_node);
> -			if (!dp->bridge)
> +			if (!dp->ptn_bridge)
>  				return -EPROBE_DEFER;
>  		} else {
>  			return -EPROBE_DEFER;
> @@ -1375,7 +1426,7 @@ static int exynos_dp_suspend(struct device *dev)
>  {
>  	struct exynos_dp_device *dp = dev_get_drvdata(dev);
> 
> -	exynos_dp_dpms(&dp->display, DRM_MODE_DPMS_OFF);
> +	exynos_dp_bridge_disable(dp->bridge);
>  	return 0;
>  }
> 
> @@ -1383,7 +1434,7 @@ static int exynos_dp_resume(struct device *dev)
>  {
>  	struct exynos_dp_device *dp = dev_get_drvdata(dev);
> 
> -	exynos_dp_dpms(&dp->display, DRM_MODE_DPMS_ON);
> +	exynos_dp_bridge_enable(dp->bridge);
>  	return 0;
>  }
>  #endif
> @@ -1410,5 +1461,6 @@ struct platform_driver dp_driver = {
>  };
> 
>  MODULE_AUTHOR("Jingoo Han <jg1.han at samsung.com>");
> +MODULE_AUTHOR("Yakir Yang <ykk at rock-chips.com>");

The same as above.

>  MODULE_DESCRIPTION("Samsung SoC DP Driver");
>  MODULE_LICENSE("GPL v2");
> diff --git a/drivers/gpu/drm/exynos/exynos_dp_core.h b/drivers/gpu/drm/exynos/exynos_dp_core.h
> index c321ad5..f2584b8 100644
> --- a/drivers/gpu/drm/exynos/exynos_dp_core.h
> +++ b/drivers/gpu/drm/exynos/exynos_dp_core.h
> @@ -3,6 +3,7 @@
>   *
>   * Copyright (C) 2012 Samsung Electronics Co., Ltd.
>   * Author: Jingoo Han <jg1.han at samsung.com>
> + *         Yakir Yang <ykk at rock-chips.com>

The same as above.
Here, you just added 1 line. If we add someone to author
in this way, a lot of people should be added to author.

Best regards,
Jingoo Han

>   *
>   * 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
> @@ -154,6 +155,7 @@ struct exynos_dp_device {
>  	struct drm_encoder	*encoder;
>  	struct drm_panel	*panel;
>  	struct drm_bridge	*bridge;
> +	struct drm_bridge	*ptn_bridge;
>  	struct clk		*clock;
>  	unsigned int		irq;
>  	void __iomem		*reg_base;
> --
> 2.1.2




From ykk at rock-chips.com  Thu Aug  6 07:19:49 2015
From: ykk at rock-chips.com (Yakir Yang)
Date: Thu,  6 Aug 2015 09:19:49 -0500
Subject: [RFC PATCH 5/8] drm: bridge/analogix_dp: add platform device type
 support
In-Reply-To: <1438868947-22132-1-git-send-email-ykk@rock-chips.com>
References: <1438868947-22132-1-git-send-email-ykk@rock-chips.com>
Message-ID: <1438870789-23898-1-git-send-email-ykk@rock-chips.com>

Signed-off-by: Yakir Yang <ykk at rock-chips.com>
---
 drivers/gpu/drm/exynos/analogix_dp-exynos.c     | 1 +
 drivers/gpu/drm/rockchip/analogix_dp-rockchip.c | 1 +
 include/drm/bridge/analogix_dp.h                | 6 ++++++
 3 files changed, 8 insertions(+)

diff --git a/drivers/gpu/drm/exynos/analogix_dp-exynos.c b/drivers/gpu/drm/exynos/analogix_dp-exynos.c
index b8d09d4..0668e77 100644
--- a/drivers/gpu/drm/exynos/analogix_dp-exynos.c
+++ b/drivers/gpu/drm/exynos/analogix_dp-exynos.c
@@ -124,6 +124,7 @@ static int exynos_dp_bind(struct device *dev, struct device *master, void *data)
 	dp->dev = dev;
 	dp->drm_dev = drm_dev;
 
+	dp->plat_data.dev_type = EXYNOS_DP;
 	dp->plat_data.power_on = exynos_dp_poweron;
 	dp->plat_data.power_off = exynos_dp_poweroff;
 	dp->plat_data.attach = exynos_dp_bridge_attach;
diff --git a/drivers/gpu/drm/rockchip/analogix_dp-rockchip.c b/drivers/gpu/drm/rockchip/analogix_dp-rockchip.c
index 804048c..b532c21 100644
--- a/drivers/gpu/drm/rockchip/analogix_dp-rockchip.c
+++ b/drivers/gpu/drm/rockchip/analogix_dp-rockchip.c
@@ -312,6 +312,7 @@ static int rockchip_dp_bind(struct device *dev, struct device *master,
 		return ret;
 	}
 
+	dp->plat_data.dev_type = RK3288_DP;
 	dp->plat_data.attach = NULL;
 	dp->plat_data.power_on = rockchip_dp_poweron;
 	dp->plat_data.power_off = rockchip_dp_poweroff;
diff --git a/include/drm/bridge/analogix_dp.h b/include/drm/bridge/analogix_dp.h
index 9a207f8..f317003 100644
--- a/include/drm/bridge/analogix_dp.h
+++ b/include/drm/bridge/analogix_dp.h
@@ -3,7 +3,13 @@
 
 #include <drm/drm_crtc.h>
 
+enum analogix_dp_devtype {
+	EXYNOS_DP,
+	RK3288_DP,
+};
+
 struct analogix_dp_plat_data {
+	enum analogix_dp_devtype dev_type;
 	struct drm_panel *panel;
 
 	int (*power_on)(struct analogix_dp_plat_data *);
-- 
2.1.2




From stefano.stabellini at eu.citrix.com  Thu Aug  6 07:20:09 2015
From: stefano.stabellini at eu.citrix.com (Stefano Stabellini)
Date: Thu, 6 Aug 2015 15:20:09 +0100
Subject: [Xen-devel] [PATCH v2 4/8] xen: Use the correctly the Xen memory
 terminologies
In-Reply-To: <55C34250.3040801@citrix.com>
References: <1438711972-18752-1-git-send-email-julien.grall@citrix.com>
 <1438711972-18752-5-git-send-email-julien.grall@citrix.com>
 <55C33E4E.4050704@citrix.com>
 <alpine.DEB.2.02.1508061205190.11337@kaball.uk.xensource.com>
 <55C34250.3040801@citrix.com>
Message-ID: <alpine.DEB.2.02.1508061520010.11337@kaball.uk.xensource.com>

On Thu, 6 Aug 2015, Julien Grall wrote:
> On 06/08/15 12:06, Stefano Stabellini wrote:
> > On Thu, 6 Aug 2015, Julien Grall wrote:
> >> Hi,
> >>
> >>
> >> On 04/08/15 19:12, Julien Grall wrote:
> >>> diff --git a/include/xen/page.h b/include/xen/page.h
> >>> index c5ed20b..e7e1425 100644
> >>> --- a/include/xen/page.h
> >>> +++ b/include/xen/page.h
> >>> @@ -3,9 +3,9 @@
> >>>  
> >>>  #include <asm/xen/page.h>
> >>>  
> >>> -static inline unsigned long page_to_mfn(struct page *page)
> >>> +static inline unsigned long page_to_gfn(struct page *page)
> >>>  {
> >>> -	return pfn_to_mfn(page_to_pfn(page));
> >>> +	return pfn_to_gfn(page_to_pfn(page));
> >>>  }
> >>
> >> I've just noticed that there is a function gfn_to_page used for KVM.
> >>
> >> Maybe I should rename page_to_gfn to xen_page_to_gfn to avoid confusion
> >> with KVM one?
> > 
> > Yeah, prepending xen would help to avoid namespace pollution.
> 
> Will do. May I keep your Reviewed-by for this mechanical change?

Yes



From ykk at rock-chips.com  Thu Aug  6 07:22:05 2015
From: ykk at rock-chips.com (Yakir Yang)
Date: Thu,  6 Aug 2015 09:22:05 -0500
Subject: [RFC PATCH 6/8] drm: bridge: analogix_dp: add some rk3288 special
 registers setting
In-Reply-To: <1438868947-22132-1-git-send-email-ykk@rock-chips.com>
References: <1438868947-22132-1-git-send-email-ykk@rock-chips.com>
Message-ID: <1438870925-23951-1-git-send-email-ykk@rock-chips.com>

RK3288 need some special registers setting, we can separate
them out by the dev_type of plat_data.

Signed-off-by: Yakir Yang <ykk at rock-chips.com>
---
 drivers/gpu/drm/bridge/analogix_dp_reg.c | 76 ++++++++++++++++++++------------
 drivers/gpu/drm/bridge/analogix_dp_reg.h | 12 +++++
 2 files changed, 60 insertions(+), 28 deletions(-)

diff --git a/drivers/gpu/drm/bridge/analogix_dp_reg.c b/drivers/gpu/drm/bridge/analogix_dp_reg.c
index dfbbde7..4d6e08a 100644
--- a/drivers/gpu/drm/bridge/analogix_dp_reg.c
+++ b/drivers/gpu/drm/bridge/analogix_dp_reg.c
@@ -16,6 +16,8 @@
 #include <linux/delay.h>
 #include <linux/gpio.h>
 
+#include <drm/bridge/analogix_dp.h>
+
 #include "analogix_dp_core.h"
 #include "analogix_dp_reg.h"
 
@@ -73,6 +75,14 @@ void analogix_dp_init_analog_param(struct analogix_dp_device *dp)
 	reg = SEL_24M | TX_DVDD_BIT_1_0625V;
 	writel(reg, dp->reg_base + ANALOGIX_DP_ANALOG_CTL_2);
 
+	if (dp->plat_data && (dp->plat_data->dev_type == RK3288_DP)) {
+		writel(REF_CLK_24M, dp->reg_base + ANALOGIX_DP_PLL_REG_1);
+		writel(0x95, dp->reg_base + ANALOGIX_DP_PLL_REG_2);
+		writel(0x40, dp->reg_base + ANALOGIX_DP_PLL_REG_3);
+		writel(0x58, dp->reg_base + ANALOGIX_DP_PLL_REG_4);
+		writel(0x22, dp->reg_base + ANALOGIX_DP_PLL_REG_5);
+	}
+
 	reg = DRIVE_DVDD_BIT_1_0625V | VCO_BIT_600_MICRO;
 	writel(reg, dp->reg_base + ANALOGIX_DP_ANALOG_CTL_3);
 
@@ -207,81 +217,85 @@ void analogix_dp_set_analog_power_down(struct analogix_dp_device *dp,
 				       bool enable)
 {
 	u32 reg;
+	u32 phy_pd_addr = ANALOGIX_DP_PHY_PD;
+
+	if (dp->plat_data && (dp->plat_data->dev_type == RK3288_DP))
+		phy_pd_addr = ANALOGIX_DP_PD;
 
 	switch (block) {
 	case AUX_BLOCK:
 		if (enable) {
-			reg = readl(dp->reg_base + ANALOGIX_DP_PHY_PD);
+			reg = readl(dp->reg_base + phy_dp_addr);
 			reg |= AUX_PD;
-			writel(reg, dp->reg_base + ANALOGIX_DP_PHY_PD);
+			writel(reg, dp->reg_base + phy_dp_addr);
 		} else {
-			reg = readl(dp->reg_base + ANALOGIX_DP_PHY_PD);
+			reg = readl(dp->reg_base + phy_dp_addr);
 			reg &= ~AUX_PD;
-			writel(reg, dp->reg_base + ANALOGIX_DP_PHY_PD);
+			writel(reg, dp->reg_base + phy_dp_addr);
 		}
 		break;
 	case CH0_BLOCK:
 		if (enable) {
-			reg = readl(dp->reg_base + ANALOGIX_DP_PHY_PD);
+			reg = readl(dp->reg_base + phy_dp_addr);
 			reg |= CH0_PD;
-			writel(reg, dp->reg_base + ANALOGIX_DP_PHY_PD);
+			writel(reg, dp->reg_base + phy_dp_addr);
 		} else {
-			reg = readl(dp->reg_base + ANALOGIX_DP_PHY_PD);
+			reg = readl(dp->reg_base + phy_dp_addr);
 			reg &= ~CH0_PD;
-			writel(reg, dp->reg_base + ANALOGIX_DP_PHY_PD);
+			writel(reg, dp->reg_base + phy_dp_addr);
 		}
 		break;
 	case CH1_BLOCK:
 		if (enable) {
-			reg = readl(dp->reg_base + ANALOGIX_DP_PHY_PD);
+			reg = readl(dp->reg_base + phy_dp_addr);
 			reg |= CH1_PD;
-			writel(reg, dp->reg_base + ANALOGIX_DP_PHY_PD);
+			writel(reg, dp->reg_base + phy_dp_addr);
 		} else {
-			reg = readl(dp->reg_base + ANALOGIX_DP_PHY_PD);
+			reg = readl(dp->reg_base + phy_dp_addr);
 			reg &= ~CH1_PD;
-			writel(reg, dp->reg_base + ANALOGIX_DP_PHY_PD);
+			writel(reg, dp->reg_base + phy_dp_addr);
 		}
 		break;
 	case CH2_BLOCK:
 		if (enable) {
-			reg = readl(dp->reg_base + ANALOGIX_DP_PHY_PD);
+			reg = readl(dp->reg_base + phy_dp_addr);
 			reg |= CH2_PD;
-			writel(reg, dp->reg_base + ANALOGIX_DP_PHY_PD);
+			writel(reg, dp->reg_base + phy_dp_addr);
 		} else {
-			reg = readl(dp->reg_base + ANALOGIX_DP_PHY_PD);
+			reg = readl(dp->reg_base + phy_dp_addr);
 			reg &= ~CH2_PD;
-			writel(reg, dp->reg_base + ANALOGIX_DP_PHY_PD);
+			writel(reg, dp->reg_base + phy_dp_addr);
 		}
 		break;
 	case CH3_BLOCK:
 		if (enable) {
-			reg = readl(dp->reg_base + ANALOGIX_DP_PHY_PD);
+			reg = readl(dp->reg_base + phy_dp_addr);
 			reg |= CH3_PD;
-			writel(reg, dp->reg_base + ANALOGIX_DP_PHY_PD);
+			writel(reg, dp->reg_base + phy_dp_addr);
 		} else {
-			reg = readl(dp->reg_base + ANALOGIX_DP_PHY_PD);
+			reg = readl(dp->reg_base + phy_dp_addr);
 			reg &= ~CH3_PD;
-			writel(reg, dp->reg_base + ANALOGIX_DP_PHY_PD);
+			writel(reg, dp->reg_base + phy_dp_addr);
 		}
 		break;
 	case ANALOG_TOTAL:
 		if (enable) {
-			reg = readl(dp->reg_base + ANALOGIX_DP_PHY_PD);
+			reg = readl(dp->reg_base + phy_dp_addr);
 			reg |= DP_PHY_PD;
-			writel(reg, dp->reg_base + ANALOGIX_DP_PHY_PD);
+			writel(reg, dp->reg_base + phy_dp_addr);
 		} else {
-			reg = readl(dp->reg_base + ANALOGIX_DP_PHY_PD);
+			reg = readl(dp->reg_base + phy_dp_addr);
 			reg &= ~DP_PHY_PD;
-			writel(reg, dp->reg_base + ANALOGIX_DP_PHY_PD);
+			writel(reg, dp->reg_base + phy_dp_addr);
 		}
 		break;
 	case POWER_ALL:
 		if (enable) {
 			reg = DP_PHY_PD | AUX_PD | CH3_PD | CH2_PD |
 				CH1_PD | CH0_PD;
-			writel(reg, dp->reg_base + ANALOGIX_DP_PHY_PD);
+			writel(reg, dp->reg_base + phy_dp_addr);
 		} else {
-			writel(0x00, dp->reg_base + ANALOGIX_DP_PHY_PD);
+			writel(0x00, dp->reg_base + phy_dp_addr);
 		}
 		break;
 	default:
@@ -400,8 +414,14 @@ void analogix_dp_init_aux(struct analogix_dp_device *dp)
 	analogix_dp_reset_aux(dp);
 
 	/* Disable AUX transaction H/W retry */
-	reg = AUX_BIT_PERIOD_EXPECTED_DELAY(3) | AUX_HW_RETRY_COUNT_SEL(0) |
-	      AUX_HW_RETRY_INTERVAL_600_MICROSECONDS;
+	if (dp->plat_data && (dp->plat_data->dev_type == RK3288_DP))
+		reg = AUX_BIT_PERIOD_EXPECTED_DELAY(0) |
+		      AUX_HW_RETRY_COUNT_SEL(3) |
+		      AUX_HW_RETRY_INTERVAL_600_MICROSECONDS;
+	else
+		reg = AUX_BIT_PERIOD_EXPECTED_DELAY(3) |
+		      AUX_HW_RETRY_COUNT_SEL(0) |
+		      AUX_HW_RETRY_INTERVAL_600_MICROSECONDS;
 	writel(reg, dp->reg_base + ANALOGIX_DP_AUX_HW_RETRY_CTL);
 
 	/* Receive AUX Channel DEFER commands equal to DEFFER_COUNT*64 */
diff --git a/drivers/gpu/drm/bridge/analogix_dp_reg.h b/drivers/gpu/drm/bridge/analogix_dp_reg.h
index 98153e2..96c538a 100644
--- a/drivers/gpu/drm/bridge/analogix_dp_reg.h
+++ b/drivers/gpu/drm/bridge/analogix_dp_reg.h
@@ -24,6 +24,14 @@
 #define ANALOGIX_DP_VIDEO_CTL_8			0x3C
 #define ANALOGIX_DP_VIDEO_CTL_10			0x44
 
+#define ANALOGIX_DP_PLL_REG_1			0xfc
+#define ANALOGIX_DP_PLL_REG_2			0x9e4
+#define ANALOGIX_DP_PLL_REG_3			0x9e8
+#define ANALOGIX_DP_PLL_REG_4			0x9ec
+#define ANALOGIX_DP_PLL_REG_5			0xa00
+
+#define ANALOGIX_DP_PD                          0x12c
+
 #define ANALOGIX_DP_LANE_MAP			0x35C
 
 #define ANALOGIX_DP_ANALOG_CTL_1			0x370
@@ -156,6 +164,10 @@
 #define VSYNC_POLARITY_CFG			(0x1 << 1)
 #define HSYNC_POLARITY_CFG			(0x1 << 0)
 
+/* ANALOGIX_DP_PLL_REG_1 */
+#define REF_CLK_24M				(0x1 << 1)
+#define REF_CLK_27M				(0x0 << 1)
+
 /* ANALOGIX_DP_LANE_MAP */
 #define LANE3_MAP_LOGIC_LANE_0			(0x0 << 6)
 #define LANE3_MAP_LOGIC_LANE_1			(0x1 << 6)
-- 
2.1.2




From ykk at rock-chips.com  Thu Aug  6 07:29:29 2015
From: ykk at rock-chips.com (Yakir Yang)
Date: Thu, 6 Aug 2015 22:29:29 +0800
Subject: [RFC PATCH 2/8] drm: exynos/dp: convert to drm bridge mode
In-Reply-To: <000001d0d052$f44fa3a0$dceeeae0$@com>
References: <1438868947-22132-1-git-send-email-ykk@rock-chips.com>
 <1438870041-23130-1-git-send-email-ykk@rock-chips.com>
 <000001d0d052$f44fa3a0$dceeeae0$@com>
Message-ID: <55C36F49.6020207@rock-chips.com>

Hi Jingoo,

? 2015/8/6 22:19, Jingoo Han ??:
> On Thursday, August 06, 2015 11:07 PM, Yakir Yang wrote:
>> In order to move exynos dp code to bridge directory,
>> we need to convert driver drm bridge mode first. As
>> dp driver already have a ptn3460 bridge, so we need
>> to move ptn bridge to the next bridge of dp bridge.
>>
>> Signed-off-by: Yakir Yang <ykk at rock-chips.com>
>> ---
>>   drivers/gpu/drm/exynos/exynos_dp_core.c | 196 ++++++++++++++++++++------------
>>   drivers/gpu/drm/exynos/exynos_dp_core.h |   2 +
>>   2 files changed, 126 insertions(+), 72 deletions(-)
>>
>> diff --git a/drivers/gpu/drm/exynos/exynos_dp_core.c b/drivers/gpu/drm/exynos/exynos_dp_core.c
>> index a8097a4..aa99e23 100644
>> --- a/drivers/gpu/drm/exynos/exynos_dp_core.c
>> +++ b/drivers/gpu/drm/exynos/exynos_dp_core.c
>> @@ -3,6 +3,7 @@
>>    *
>>    * Copyright (C) 2012 Samsung Electronics Co., Ltd.
>>    * Author: Jingoo Han <jg1.han at samsung.com>
>> + *         Yakir Yang <ykk at rock-chips.com>
> Please don't add this.
> You just fixed some parts of this code. I don't find the reason
> why you have to be added to author for this file.
> If you want the title for an author, please send the patch
> for a new IP, instead of modifying the exiting codes.

Okay, thanks for your remind ;)

>>   [...]
>>   MODULE_AUTHOR("Jingoo Han <jg1.han at samsung.com>");
>> +MODULE_AUTHOR("Yakir Yang <ykk at rock-chips.com>");
> The same as above.

Done
>>   MODULE_DESCRIPTION("Samsung SoC DP Driver");
>>   MODULE_LICENSE("GPL v2");
>> diff --git a/drivers/gpu/drm/exynos/exynos_dp_core.h b/drivers/gpu/drm/exynos/exynos_dp_core.h
>> index c321ad5..f2584b8 100644
>> --- a/drivers/gpu/drm/exynos/exynos_dp_core.h
>> +++ b/drivers/gpu/drm/exynos/exynos_dp_core.h
>> @@ -3,6 +3,7 @@
>>    *
>>    * Copyright (C) 2012 Samsung Electronics Co., Ltd.
>>    * Author: Jingoo Han <jg1.han at samsung.com>
>> + *         Yakir Yang <ykk at rock-chips.com>
> The same as above.
> Here, you just added 1 line. If we add someone to author
> in this way, a lot of people should be added to author.

Done

- Yakir
> Best regards,
> Jingoo Han
>
>
>
>
>




From linus.walleij at linaro.org  Thu Aug  6 07:40:48 2015
From: linus.walleij at linaro.org (Linus Walleij)
Date: Thu, 6 Aug 2015 16:40:48 +0200
Subject: [PATCH 2/2] ARM: ux500: simplify secondary CPU boot
In-Reply-To: <20150806081130.GC16520@localhost>
References: <1438586812-30164-1-git-send-email-linus.walleij@linaro.org>
 <20150806081130.GC16520@localhost>
Message-ID: <CACRpkdZDyVjLmOcdUVBmRQo_fLf0TA84kA8yJNpsYGBkn5Jzzg@mail.gmail.com>

On Thu, Aug 6, 2015 at 10:11 AM, Olof Johansson <olof at lixom.net> wrote:
> On Mon, Aug 03, 2015 at 09:26:52AM +0200, Linus Walleij wrote:
>> This removes a lot of ancient cruft from the Ux500 SMP boot.
>> Instead of the pen grab/release, just point the ROM to
>> secondary_boot() and start the second CPU there, then send
>> the IPI.
>>
>> Use our own SMP enable method. This enables us to remove the
>> last static mapping and get both CPUs booting properly.
>>
>> Tested this and it just works.
>>
>> Signed-off-by: Linus Walleij <linus.walleij at linaro.org>
>> ---
>> Hi ARM SoC folks: please apply this to fixes for v4.2. I was
>> intending it for v4.3 but we might as well just kill off the
>> legacy boot method right now so we do not need to restore any
>> static maps and undo the cleanup (which would be just as
>> invasive).
>
> It's a bit late in the cycle for that. I'll apply it in cleanup for 4.3 though.

OK I've got a bunch of cleanups for Ux500, shall I include these
in the pull request or will you apply this separately?

Yours,
Linus Walleij


From jingoohan1 at gmail.com  Thu Aug  6 07:41:36 2015
From: jingoohan1 at gmail.com (Jingoo Han)
Date: Thu, 6 Aug 2015 23:41:36 +0900
Subject: [RFC PATCH 0/8] Add Analogix Core Display Port Driver
In-Reply-To: <1438868947-22132-1-git-send-email-ykk@rock-chips.com>
References: <1438868947-22132-1-git-send-email-ykk@rock-chips.com>
Message-ID: <000201d0d056$06cff040$146fd0c0$@com>

On Thursday, August 06, 2015 10:49 PM, Yakir Yang wrote:
> 
> Hi all,
>    Samsung exynos and Rockchip rk3288 almost share same dp controller,
> so I split the common code out, then rk3288 and exynos can re-used the
> same dp core driver. Cause I can't find the exact IP name of exynos dp
> controller, so I decide to name dp core driver with "analogix" which I
> find in rk3288 eDP TRM ;)


OK, I see.
The Samsung Exynos eDP contoller and Rockchip rk3288 eDP contoller share
the same IP. So, a lot of parts can be re-used. I agree with this.
However, we have to review the code carefully, as others did.

I also cannot find the exact IP name. The "analogix" may be the vendor name
of this IP.

Best regards,
Jingoo Han

> 
> Beyond that, there are three light registers setting differents bewteen
> exynos and rk3288.
> 1. RK3288 have five special pll resigters which not indicata in exynos
>    dp controller.
> 2. The address of DP_PHY_PD(dp phy power manager register) are different
>    between rk3288 and exynos.
> 3. Rk3288 and exynos have different setting with AUX_HW_RETRY_CTL(dp debug
>    register).
> 
> My series patches can be divider into two parts: One for spliting the
> analogix_dp code from exynos dp driver. Another are trying to add rk3288
> dp driver support.
> 
> Best regards,
> - Yakir
> 
> 
> Yakir Yang (8):
>   drm: exynos/dp: fix code style
>   drm: exynos/dp: convert to drm bridge mode
>   drm: bridge: analogix_dp: split exynos dp driver to bridge dir
>   drm: rockchip/dp: add rockchip platform dp driver
>   drm: bridge/analogix_dp: add platform device type support
>   drm: bridge: analogix_dp: add some rk3288 special registers setting
>   drm: bridge: analogix_dp: try force hpd after plug in lookup failed
>   drm: bridge/analogix_dp: expand the delay time for hpd detect
> 
>  drivers/gpu/drm/bridge/Kconfig                     |    5 +
>  drivers/gpu/drm/bridge/Makefile                    |    1 +
>  drivers/gpu/drm/bridge/analogix_dp_core.c          | 1397 +++++++++++++++++++
>  drivers/gpu/drm/bridge/analogix_dp_core.h          |  287 ++++
>  drivers/gpu/drm/bridge/analogix_dp_reg.c           | 1295 ++++++++++++++++++
>  .../exynos_dp_reg.h => bridge/analogix_dp_reg.h}   |  272 ++--
>  drivers/gpu/drm/exynos/Kconfig                     |    5 +-
>  drivers/gpu/drm/exynos/Makefile                    |    2 +-
>  drivers/gpu/drm/exynos/analogix_dp-exynos.c        |  241 ++++
>  drivers/gpu/drm/exynos/exynos_dp_core.c            | 1416 --------------------
>  drivers/gpu/drm/exynos/exynos_dp_core.h            |  282 ----
>  drivers/gpu/drm/exynos/exynos_dp_reg.c             |  100 +-
>  drivers/gpu/drm/rockchip/Kconfig                   |   10 +
>  drivers/gpu/drm/rockchip/Makefile                  |    1 +
>  drivers/gpu/drm/rockchip/analogix_dp-rockchip.c    |  420 ++++++
>  include/drm/bridge/analogix_dp.h                   |   28 +
>  16 files changed, 3880 insertions(+), 1882 deletions(-)
>  create mode 100644 drivers/gpu/drm/bridge/analogix_dp_core.c
>  create mode 100644 drivers/gpu/drm/bridge/analogix_dp_core.h
>  create mode 100644 drivers/gpu/drm/bridge/analogix_dp_reg.c
>  rename drivers/gpu/drm/{exynos/exynos_dp_reg.h => bridge/analogix_dp_reg.h} (62%)
>  create mode 100644 drivers/gpu/drm/exynos/analogix_dp-exynos.c
>  delete mode 100644 drivers/gpu/drm/exynos/exynos_dp_core.c
>  delete mode 100644 drivers/gpu/drm/exynos/exynos_dp_core.h
>  create mode 100644 drivers/gpu/drm/rockchip/analogix_dp-rockchip.c
>  create mode 100644 include/drm/bridge/analogix_dp.h
> 
> --
> 2.1.2




From linus.walleij at linaro.org  Thu Aug  6 07:42:42 2015
From: linus.walleij at linaro.org (Linus Walleij)
Date: Thu,  6 Aug 2015 16:42:42 +0200
Subject: [PATCH 3/4 v2] ARM: nomadik: move l2x0 setup to device tree
Message-ID: <1438872162-13565-1-git-send-email-linus.walleij@linaro.org>

The cache setup magic value in the Nomadik machine is plain wrong,
the correct settings can be done using device tree in accordance
with the settings from ST's own port.

Signed-off-by: Linus Walleij <linus.walleij at linaro.org>
---
This v2 version fixes the syntactic minimalism issue with
just 0/~0 for the AUX val/mask pointed out by Russell.
---
 arch/arm/boot/dts/ste-nomadik-stn8815.dtsi | 7 +++++++
 arch/arm/mach-nomadik/cpu-8815.c           | 5 ++---
 2 files changed, 9 insertions(+), 3 deletions(-)

diff --git a/arch/arm/boot/dts/ste-nomadik-stn8815.dtsi b/arch/arm/boot/dts/ste-nomadik-stn8815.dtsi
index f68988ac800c..ce8936bebe5e 100644
--- a/arch/arm/boot/dts/ste-nomadik-stn8815.dtsi
+++ b/arch/arm/boot/dts/ste-nomadik-stn8815.dtsi
@@ -21,6 +21,13 @@
 		interrupts = <30>;
 		cache-unified;
 		cache-level = <2>;
+		cache-size = <131072>;
+		cache-sets = <512>;
+		cache-line-size = <32>;
+		/* At full speed latency must be >=2 */
+		arm,tag-latency = <2>;
+		arm,data-latency = <2 2>;
+		arm,dirty-latency = <2>;
 	};
 
 	mtu0: mtu at 101e2000 {
diff --git a/arch/arm/mach-nomadik/cpu-8815.c b/arch/arm/mach-nomadik/cpu-8815.c
index 82831dc6122f..0c612d95bd5c 100644
--- a/arch/arm/mach-nomadik/cpu-8815.c
+++ b/arch/arm/mach-nomadik/cpu-8815.c
@@ -114,9 +114,8 @@ static const char * cpu8815_board_compat[] = {
 };
 
 DT_MACHINE_START(NOMADIK_DT, "Nomadik STn8815")
-	/* At full speed latency must be >=2, so 0x249 in low bits */
-	.l2c_aux_val	= 0x00700249,
-	.l2c_aux_mask	= 0xfe0fefff,
+	.l2c_aux_val	= 0,
+	.l2c_aux_mask	= ~0,
 	.map_io		= cpu8815_map_io,
 	.restart	= cpu8815_restart,
 	.dt_compat      = cpu8815_board_compat,
-- 
2.4.3



From tomeu.vizoso at collabora.com  Thu Aug  6 07:43:33 2015
From: tomeu.vizoso at collabora.com (Tomeu Vizoso)
Date: Thu,  6 Aug 2015 16:43:33 +0200
Subject: [PATCH] ARM: multi_v7_defconfig: Build a few drivers in
Message-ID: <1438872213-24754-1-git-send-email-tomeu.vizoso@collabora.com>

Drivers for devices that are basic dependencies (regulators, mainly) of
other devices are better built into the image because otherwise we get
so many probe deferrals that is hard to spot where a device is having
genuine trouble to probe.

Signed-off-by: Tomeu Vizoso <tomeu.vizoso at collabora.com>
---
 arch/arm/configs/multi_v7_defconfig | 14 +++++++-------
 1 file changed, 7 insertions(+), 7 deletions(-)

diff --git a/arch/arm/configs/multi_v7_defconfig b/arch/arm/configs/multi_v7_defconfig
index fb587b2330ad..4c5431e99522 100644
--- a/arch/arm/configs/multi_v7_defconfig
+++ b/arch/arm/configs/multi_v7_defconfig
@@ -309,7 +309,7 @@ CONFIG_I2C_SUN6I_P2WI=y
 CONFIG_I2C_TEGRA=y
 CONFIG_I2C_XILINX=y
 CONFIG_I2C_RCAR=y
-CONFIG_I2C_CROS_EC_TUNNEL=m
+CONFIG_I2C_CROS_EC_TUNNEL=y
 CONFIG_SPI=y
 CONFIG_SPI_ATMEL=m
 CONFIG_SPI_CADENCE=y
@@ -318,7 +318,7 @@ CONFIG_SPI_OMAP24XX=y
 CONFIG_SPI_ORION=y
 CONFIG_SPI_PL022=y
 CONFIG_SPI_RSPI=y
-CONFIG_SPI_S3C64XX=m
+CONFIG_SPI_S3C64XX=y
 CONFIG_SPI_SH_MSIOF=m
 CONFIG_SPI_SH_HSPI=y
 CONFIG_SPI_SIRF=y
@@ -408,7 +408,7 @@ CONFIG_REGULATOR_MAX14577=m
 CONFIG_REGULATOR_MAX8907=y
 CONFIG_REGULATOR_MAX8973=y
 CONFIG_REGULATOR_MAX77686=y
-CONFIG_REGULATOR_MAX77802=m
+CONFIG_REGULATOR_MAX77802=y
 CONFIG_REGULATOR_MAX77693=m
 CONFIG_REGULATOR_PALMAS=y
 CONFIG_REGULATOR_PWM=m
@@ -557,7 +557,7 @@ CONFIG_RTC_DRV_AS3722=y
 CONFIG_RTC_DRV_DS1307=y
 CONFIG_RTC_DRV_MAX8907=y
 CONFIG_RTC_DRV_MAX77686=y
-CONFIG_RTC_DRV_MAX77802=m
+CONFIG_RTC_DRV_MAX77802=y
 CONFIG_RTC_DRV_RS5C372=m
 CONFIG_RTC_DRV_PALMAS=y
 CONFIG_RTC_DRV_ST_LPC=y
@@ -610,7 +610,7 @@ CONFIG_COMMON_CLK_QCOM=y
 CONFIG_CHROME_PLATFORMS=y
 CONFIG_CROS_EC_CHARDEV=m
 CONFIG_COMMON_CLK_MAX77686=y
-CONFIG_COMMON_CLK_MAX77802=m
+CONFIG_COMMON_CLK_MAX77802=y
 CONFIG_COMMON_CLK_S2MPS11=m
 CONFIG_APQ_MMCC_8084=y
 CONFIG_MSM_GCC_8660=y
@@ -632,7 +632,7 @@ CONFIG_PWM=y
 CONFIG_PWM_ATMEL=m
 CONFIG_PWM_ATMEL_TCB=m
 CONFIG_PWM_RENESAS_TPU=y
-CONFIG_PWM_SAMSUNG=m
+CONFIG_PWM_SAMSUNG=y
 CONFIG_PWM_SUN4I=y
 CONFIG_PWM_TEGRA=y
 CONFIG_PWM_VT8500=y
@@ -647,7 +647,7 @@ CONFIG_PHY_STIH41X_USB=y
 CONFIG_PHY_STIH407_USB=y
 CONFIG_PHY_SUN4I_USB=y
 CONFIG_PHY_SUN9I_USB=y
-CONFIG_PHY_SAMSUNG_USB2=m
+CONFIG_PHY_SAMSUNG_USB2=y
 CONFIG_EXT4_FS=y
 CONFIG_AUTOFS4_FS=y
 CONFIG_MSDOS_FS=y
-- 
2.4.3



From tomeu.vizoso at collabora.com  Thu Aug  6 07:44:24 2015
From: tomeu.vizoso at collabora.com (Tomeu Vizoso)
Date: Thu,  6 Aug 2015 16:44:24 +0200
Subject: [PATCH] ARM: multi_v7_defconfig: Add BQ24735, ANATOP and PWM_IMX
Message-ID: <1438872264-24953-1-git-send-email-tomeu.vizoso@collabora.com>

Found the need for these when testing multiv7 kernels on a bunch of
boards.

Signed-off-by: Tomeu Vizoso <tomeu.vizoso at collabora.com>
---
 arch/arm/configs/multi_v7_defconfig | 3 +++
 1 file changed, 3 insertions(+)

diff --git a/arch/arm/configs/multi_v7_defconfig b/arch/arm/configs/multi_v7_defconfig
index 4c5431e99522..827b91d887aa 100644
--- a/arch/arm/configs/multi_v7_defconfig
+++ b/arch/arm/configs/multi_v7_defconfig
@@ -349,6 +349,7 @@ CONFIG_GPIO_SYSCON=y
 CONFIG_GPIO_TPS6586X=y
 CONFIG_GPIO_TPS65910=y
 CONFIG_BATTERY_SBS=y
+CONFIG_CHARGER_BQ24735=y
 CONFIG_BATTERY_MAX17040=m
 CONFIG_BATTERY_MAX17042=m
 CONFIG_CHARGER_MAX14577=m
@@ -396,6 +397,7 @@ CONFIG_MFD_TPS65090=y
 CONFIG_MFD_TPS6586X=y
 CONFIG_MFD_TPS65910=y
 CONFIG_REGULATOR_AB8500=y
+CONFIG_REGULATOR_ANATOP=y
 CONFIG_REGULATOR_AS3711=y
 CONFIG_REGULATOR_AS3722=y
 CONFIG_REGULATOR_AXP20X=y
@@ -631,6 +633,7 @@ CONFIG_AK8975=y
 CONFIG_PWM=y
 CONFIG_PWM_ATMEL=m
 CONFIG_PWM_ATMEL_TCB=m
+CONFIG_PWM_IMX=y
 CONFIG_PWM_RENESAS_TPU=y
 CONFIG_PWM_SAMSUNG=y
 CONFIG_PWM_SUN4I=y
-- 
2.4.3



From ykk at rock-chips.com  Thu Aug  6 07:24:18 2015
From: ykk at rock-chips.com (Yakir Yang)
Date: Thu,  6 Aug 2015 09:24:18 -0500
Subject: [RFC PATCH 7/8] drm: bridge: analogix_dp: try force hpd after plug in
 lookup failed
In-Reply-To: <1438868947-22132-1-git-send-email-ykk@rock-chips.com>
References: <1438868947-22132-1-git-send-email-ykk@rock-chips.com>
Message-ID: <1438871058-24005-1-git-send-email-ykk@rock-chips.com>

Some edp screen do not have hpd signal, so we can't just return
failed when hpd plug in detect failed.

Besides TRM indicate that if HPD_STATUS(RO) is 0, AUX CH will not
work, so we need to give a force hpd action to set HPD_STATUS manually.

Signed-off-by: Yakir Yang <ykk at rock-chips.com>
---
 drivers/gpu/drm/bridge/analogix_dp_core.c | 28 +++++++++++++++++++++++-----
 drivers/gpu/drm/bridge/analogix_dp_core.h |  1 +
 drivers/gpu/drm/bridge/analogix_dp_reg.c  |  9 +++++++++
 3 files changed, 33 insertions(+), 5 deletions(-)

diff --git a/drivers/gpu/drm/bridge/analogix_dp_core.c b/drivers/gpu/drm/bridge/analogix_dp_core.c
index 28724d4..7e67f19 100644
--- a/drivers/gpu/drm/bridge/analogix_dp_core.c
+++ b/drivers/gpu/drm/bridge/analogix_dp_core.c
@@ -68,15 +68,33 @@ static int analogix_dp_detect_hpd(struct analogix_dp_device *dp)
 {
 	int timeout_loop = 0;
 
-	while (analogix_dp_get_plug_in_status(dp) != 0) {
+	while (timeout_loop < DP_TIMEOUT_LOOP_COUNT) {
+		if (analogix_dp_get_plug_in_status(dp) == 0)
+			return 0;
+
 		timeout_loop++;
-		if (DP_TIMEOUT_LOOP_COUNT < timeout_loop) {
-			dev_err(dp->dev, "failed to get hpd plug status\n");
-			return -ETIMEDOUT;
-		}
 		usleep_range(10, 11);
 	}
 
+	/*
+	 * Some edp screen do not have hpd signal, so we can't just
+	 * return failed when hpd plug in detect failed.
+	 *
+	 * Besides TRM indicate that if HPD_STATUS(RO) is 0, AUX CH
+	 * will not work, so we need to give a force hpd action to
+	 * set HPD_STATUS manually.
+	 */
+	dev_dbg(dp->dev, "failed to get hpd plug status, try to force hpd\n");
+
+	analogix_dp_force_hpd(dp);
+
+	if (analogix_dp_get_plug_in_status(dp) != 0) {
+		dev_err(dp->dev, "failed to get hpd plug in status\n");
+		return -ETIMEDOUT;
+	}
+
+	dev_dbg(dp->dev, "success to get plug in status after force hpd\n");
+
 	return 0;
 }
 
diff --git a/drivers/gpu/drm/bridge/analogix_dp_core.h b/drivers/gpu/drm/bridge/analogix_dp_core.h
index fe72695..43cec77 100644
--- a/drivers/gpu/drm/bridge/analogix_dp_core.h
+++ b/drivers/gpu/drm/bridge/analogix_dp_core.h
@@ -183,6 +183,7 @@ void analogix_dp_set_analog_power_down(struct analogix_dp_device *dp,
 				       bool enable);
 void analogix_dp_init_analog_func(struct analogix_dp_device *dp);
 void analogix_dp_init_hpd(struct analogix_dp_device *dp);
+void analogix_dp_force_hpd(struct analogix_dp_device *dp);
 enum dp_irq_type analogix_dp_get_irq_type(struct analogix_dp_device *dp);
 void analogix_dp_clear_hotplug_interrupts(struct analogix_dp_device *dp);
 void analogix_dp_reset_aux(struct analogix_dp_device *dp);
diff --git a/drivers/gpu/drm/bridge/analogix_dp_reg.c b/drivers/gpu/drm/bridge/analogix_dp_reg.c
index 4d6e08a..3fb215b 100644
--- a/drivers/gpu/drm/bridge/analogix_dp_reg.c
+++ b/drivers/gpu/drm/bridge/analogix_dp_reg.c
@@ -366,6 +366,15 @@ void analogix_dp_init_hpd(struct analogix_dp_device *dp)
 	writel(reg, dp->reg_base + ANALOGIX_DP_SYS_CTL_3);
 }
 
+void analogix_dp_force_hpd(struct analogix_dp_device *dp)
+{
+	u32 reg;
+
+	reg = readl(dp->reg_base + ANALOGIX_DP_SYS_CTL_3);
+	reg = (F_HPD | HPD_CTRL);
+	writel(reg, dp->reg_base + ANALOGIX_DP_SYS_CTL_3);
+}
+
 enum dp_irq_type analogix_dp_get_irq_type(struct analogix_dp_device *dp)
 {
 	u32 reg;
-- 
2.1.2




From ykk at rock-chips.com  Thu Aug  6 07:26:33 2015
From: ykk at rock-chips.com (Yakir Yang)
Date: Thu,  6 Aug 2015 09:26:33 -0500
Subject: [RFC PATCH 8/8] drm: bridge/analogix_dp: expand the delay time for
 hpd detect
In-Reply-To: <1438868947-22132-1-git-send-email-ykk@rock-chips.com>
References: <1438868947-22132-1-git-send-email-ykk@rock-chips.com>
Message-ID: <1438871193-24067-1-git-send-email-ykk@rock-chips.com>

Some edp screen with no hpd signal would need some delay time
to ensure that screen would be ready for work, so we can expand
the delay time in hpd detect function, it works prefectly on my
rk3288 sdk board.

Signed-off-by: Yakir Yang <ykk at rock-chips.com>
---
 drivers/gpu/drm/bridge/analogix_dp_core.c | 2 +-
 1 file changed, 1 insertion(+), 1 deletion(-)

diff --git a/drivers/gpu/drm/bridge/analogix_dp_core.c b/drivers/gpu/drm/bridge/analogix_dp_core.c
index 7e67f19..447c94d 100644
--- a/drivers/gpu/drm/bridge/analogix_dp_core.c
+++ b/drivers/gpu/drm/bridge/analogix_dp_core.c
@@ -73,7 +73,7 @@ static int analogix_dp_detect_hpd(struct analogix_dp_device *dp)
 			return 0;
 
 		timeout_loop++;
-		usleep_range(10, 11);
+		usleep_range(100, 110);
 	}
 
 	/*
-- 
2.1.2




From jingoohan1 at gmail.com  Thu Aug  6 07:46:16 2015
From: jingoohan1 at gmail.com (Jingoo Han)
Date: Thu, 6 Aug 2015 23:46:16 +0900
Subject: [PATCH v5 1/9] ARM/PCI: Replace panic with WARN messages on
 failures
In-Reply-To: <20150804215357.9189.11942.stgit@bhelgaas-glaptop2.roam.corp.google.com>
References: <20150804214234.9189.42548.stgit@bhelgaas-glaptop2.roam.corp.google.com>
 <20150804215357.9189.11942.stgit@bhelgaas-glaptop2.roam.corp.google.com>
Message-ID: <000301d0d056$abf8f990$03eaecb0$@com>

On Wednesday, August 05, 2015 6:54 AM, Bjorn Helgaas wrote:
> 
> From: Lorenzo Pieralisi <lorenzo.pieralisi at arm.com>
> 
> In the ARM PCI bios32 layer, failures to dynamically allocate pci_sys_data
> for a PCI bus, or a PCI bus scan failure have to be considered serious
> warnings but they should not trigger a system panic so that at least the
> system is given a chance to be debugged.
> 
> This patch replaces the panic statements with WARN() messages to improve
> error reporting in the ARM PCI bios32 layer.
> 
> Signed-off-by: Lorenzo Pieralisi <lorenzo.pieralisi at arm.com>
> Signed-off-by: Bjorn Helgaas <bhelgaas at google.com>
> Acked-by: Marc Zyngier <marc.zyngier at arm.com>
> CC: Russell King <linux at arm.linux.org.uk>
> CC: Marc Zyngier <marc.zyngier at arm.com>

Reviewed-by: Jingoo Han <jingoohan1 at gmail.com>

In ARM, WARN message looks good.

Best regards,
Jingoo Han

> ---
>  arch/arm/kernel/bios32.c |   10 ++++++----
>  1 file changed, 6 insertions(+), 4 deletions(-)
> 
> diff --git a/arch/arm/kernel/bios32.c b/arch/arm/kernel/bios32.c
> index bf370bc..4e95260 100644
> --- a/arch/arm/kernel/bios32.c
> +++ b/arch/arm/kernel/bios32.c
> @@ -459,8 +459,8 @@ static void pcibios_init_hw(struct device *parent, struct hw_pci *hw,
> 
>  	for (nr = busnr = 0; nr < hw->nr_controllers; nr++) {
>  		sys = kzalloc(sizeof(struct pci_sys_data), GFP_KERNEL);
> -		if (!sys)
> -			panic("PCI: unable to allocate sys data!");
> +		if (WARN(!sys, "PCI: unable to allocate sys data!"))
> +			break;
> 
>  #ifdef CONFIG_PCI_MSI
>  		sys->msi_ctrl = hw->msi_ctrl;
> @@ -489,8 +489,10 @@ static void pcibios_init_hw(struct device *parent, struct hw_pci *hw,
>  				sys->bus = pci_scan_root_bus(parent, sys->busnr,
>  						hw->ops, sys, &sys->resources);
> 
> -			if (!sys->bus)
> -				panic("PCI: unable to scan bus!");
> +			if (WARN(!sys->bus, "PCI: unable to scan bus!")) {
> +				kfree(sys);
> +				break;
> +			}
> 
>  			busnr = sys->bus->busn_res.end + 1;
> 



From jingoohan1 at gmail.com  Thu Aug  6 07:47:55 2015
From: jingoohan1 at gmail.com (Jingoo Han)
Date: Thu, 6 Aug 2015 23:47:55 +0900
Subject: [PATCH v5 2/9] PCI: Add pci_scan_root_bus_msi()
In-Reply-To: <20150804215404.9189.41823.stgit@bhelgaas-glaptop2.roam.corp.google.com>
References: <20150804214234.9189.42548.stgit@bhelgaas-glaptop2.roam.corp.google.com>
 <20150804215404.9189.41823.stgit@bhelgaas-glaptop2.roam.corp.google.com>
Message-ID: <000401d0d056$e700d260$b5027720$@com>

On Wednesday, August 05, 2015 6:54 AM, Bjorn Helgaas wrote:
> 
> From: Lorenzo Pieralisi <lorenzo.pieralisi at arm.com>
> 
> Add a pci_scan_root_bus_msi() interface so an arch can specify the MSI
> controller up front.  This removes the need for a pcibios callback to set
> the MSI controller later.
> 
> This is not exported because I'd like to replace the variety of "scan root
> bus" interfaces with a single, more extensible interface that can handle
> the MSI controller, domain, pci_ops, resources, etc.  I hope this interface
> is temporary.
> 
> [bhelgaas: changelog, split into separate patch, move to drivers/pci/pci.h]
> Suggested-by: Russell King <linux at arm.linux.org.uk>
> Signed-off-by: Lorenzo Pieralisi <lorenzo.pieralisi at arm.com>
> Signed-off-by: Bjorn Helgaas <bhelgaas at google.com>

Reviewed-by: Jingoo Han <jingoohan1 at gmail.com>

Best regards,
Jingoo Han

> ---
>  drivers/pci/pci.h   |    5 +++++
>  drivers/pci/probe.c |   14 ++++++++++++--
>  2 files changed, 17 insertions(+), 2 deletions(-)
> 
> diff --git a/drivers/pci/pci.h b/drivers/pci/pci.h
> index 4ff0ff1..1d4c95c 100644
> --- a/drivers/pci/pci.h
> +++ b/drivers/pci/pci.h
> @@ -223,6 +223,11 @@ enum pci_bar_type {
>  	pci_bar_mem64,		/* A 64-bit memory BAR */
>  };
> 
> +struct pci_bus *pci_scan_root_bus_msi(struct device *parent, int bus,
> +				      struct pci_ops *ops, void *sysdata,
> +				      struct list_head *resources,
> +				      struct msi_controller *msi);
> +
>  bool pci_bus_read_dev_vendor_id(struct pci_bus *bus, int devfn, u32 *pl,
>  				int crs_timeout);
>  int pci_setup_device(struct pci_dev *dev);
> diff --git a/drivers/pci/probe.c b/drivers/pci/probe.c
> index cefd636..9ff4df0 100644
> --- a/drivers/pci/probe.c
> +++ b/drivers/pci/probe.c
> @@ -2096,8 +2096,9 @@ void pci_bus_release_busn_res(struct pci_bus *b)
>  			res, ret ? "can not be" : "is");
>  }
> 
> -struct pci_bus *pci_scan_root_bus(struct device *parent, int bus,
> -		struct pci_ops *ops, void *sysdata, struct list_head *resources)
> +struct pci_bus *pci_scan_root_bus_msi(struct device *parent, int bus,
> +		struct pci_ops *ops, void *sysdata,
> +		struct list_head *resources, struct msi_controller *msi)
>  {
>  	struct resource_entry *window;
>  	bool found = false;
> @@ -2114,6 +2115,8 @@ struct pci_bus *pci_scan_root_bus(struct device *parent, int bus,
>  	if (!b)
>  		return NULL;
> 
> +	b->msi = msi;
> +
>  	if (!found) {
>  		dev_info(&b->dev,
>  		 "No busn resource found for root bus, will use [bus %02x-ff]\n",
> @@ -2128,6 +2131,13 @@ struct pci_bus *pci_scan_root_bus(struct device *parent, int bus,
> 
>  	return b;
>  }
> +
> +struct pci_bus *pci_scan_root_bus(struct device *parent, int bus,
> +		struct pci_ops *ops, void *sysdata, struct list_head *resources)
> +{
> +	return pci_scan_root_bus_msi(parent, bus, ops, sysdata, resources,
> +				     NULL);
> +}
>  EXPORT_SYMBOL(pci_scan_root_bus);
> 
>  struct pci_bus *pci_scan_bus(int bus, struct pci_ops *ops,



From jingoohan1 at gmail.com  Thu Aug  6 07:49:16 2015
From: jingoohan1 at gmail.com (Jingoo Han)
Date: Thu, 6 Aug 2015 23:49:16 +0900
Subject: [PATCH v5 3/9] ARM/PCI, designware,
 xilinx: Use pci_scan_root_bus_msi()
In-Reply-To: <20150804215411.9189.53901.stgit@bhelgaas-glaptop2.roam.corp.google.com>
References: <20150804214234.9189.42548.stgit@bhelgaas-glaptop2.roam.corp.google.com>
 <20150804215411.9189.53901.stgit@bhelgaas-glaptop2.roam.corp.google.com>
Message-ID: <000501d0d057$177e4df0$467ae9d0$@com>

On Wednesday, August 05, 2015 6:54 AM, Bjorn Helgaas wrote:
> 
> From: Lorenzo Pieralisi <lorenzo.pieralisi at arm.com>
> 
> ARM previously stored the msi_controller pointer in its sysdata, struct
> pci_sys_data, and implemented pcibios_msi_controller() to retrieve it.
> That made PCI host controller drivers specific to ARM because they had to
> put the msi_controller pointer in the ARM-specific pci_sys_data.
> 
> There is now a generic mechanism, pci_scan_root_bus_msi(), for giving the
> msi_controller pointer to the PCI core.  Use this for all ARM systems and
> for the DesignWare and Xilinx PCI host controller drivers.
> 
> This removes an ARM dependency from the DesignWare, DRA7xx, EXYNOS, i.MX6,
> Keystone, Layerscape, SPEAr13xx, and Xilinx drivers.
> 
> [bhelgaas: changelog, split into separate patch]
> Suggested-by: Russell King <linux at arm.linux.org.uk>
> Signed-off-by: Lorenzo Pieralisi <lorenzo.pieralisi at arm.com>
> Signed-off-by: Bjorn Helgaas <bhelgaas at google.com>
> CC: Pratyush Anand <pratyush.anand at gmail.com>
> CC: Arnd Bergmann <arnd at arndb.de>
> CC: Jingoo Han <jingoohan1 at gmail.com>

Acked-by: Jingoo Han <jingoohan1 at gmail.com>

Best regards,
Jingoo Han

> CC: Simon Horman <horms at verge.net.au>
> CC: Russell King <linux at arm.linux.org.uk>
> CC: Thomas Petazzoni <thomas.petazzoni at free-electrons.com>
> CC: Thierry Reding <thierry.reding at gmail.com>
> CC: Michal Simek <michal.simek at xilinx.com>
> CC: Marc Zyngier <marc.zyngier at arm.com>
> ---
>  arch/arm/include/asm/mach/pci.h    |    2 --
>  arch/arm/kernel/bios32.c           |    5 +++--
>  drivers/pci/host/pcie-designware.c |    6 +++---
>  drivers/pci/host/pcie-xilinx.c     |    5 ++---
>  4 files changed, 8 insertions(+), 10 deletions(-)
> 
> diff --git a/arch/arm/include/asm/mach/pci.h b/arch/arm/include/asm/mach/pci.h
> index 28b9bb3..c074e7a 100644
> --- a/arch/arm/include/asm/mach/pci.h
> +++ b/arch/arm/include/asm/mach/pci.h
> @@ -19,9 +19,7 @@ struct pci_bus;
>  struct device;
> 
>  struct hw_pci {
> -#ifdef CONFIG_PCI_MSI
>  	struct msi_controller *msi_ctrl;
> -#endif
>  	struct pci_ops	*ops;
>  	int		nr_controllers;
>  	void		**private_data;
> diff --git a/arch/arm/kernel/bios32.c b/arch/arm/kernel/bios32.c
> index 4e95260..283bc1c 100644
> --- a/arch/arm/kernel/bios32.c
> +++ b/arch/arm/kernel/bios32.c
> @@ -486,8 +486,9 @@ static void pcibios_init_hw(struct device *parent, struct hw_pci *hw,
>  			if (hw->scan)
>  				sys->bus = hw->scan(nr, sys);
>  			else
> -				sys->bus = pci_scan_root_bus(parent, sys->busnr,
> -						hw->ops, sys, &sys->resources);
> +				sys->bus = pci_scan_root_bus_msi(parent,
> +					sys->busnr, hw->ops, sys,
> +					&sys->resources, hw->msi_ctrl);
> 
>  			if (WARN(!sys->bus, "PCI: unable to scan bus!")) {
>  				kfree(sys);
> diff --git a/drivers/pci/host/pcie-designware.c b/drivers/pci/host/pcie-designware.c
> index 69486be..bd0aeec 100644
> --- a/drivers/pci/host/pcie-designware.c
> +++ b/drivers/pci/host/pcie-designware.c
> @@ -526,7 +526,6 @@ int dw_pcie_host_init(struct pcie_port *pp)
> 
>  #ifdef CONFIG_PCI_MSI
>  	dw_pcie_msi_chip.dev = pp->dev;
> -	dw_pci.msi_ctrl = &dw_pcie_msi_chip;
>  #endif
> 
>  	dw_pci.nr_controllers = 1;
> @@ -708,8 +707,9 @@ static struct pci_bus *dw_pcie_scan_bus(int nr, struct pci_sys_data *sys)
>  	struct pcie_port *pp = sys_to_pcie(sys);
> 
>  	pp->root_bus_nr = sys->busnr;
> -	bus = pci_scan_root_bus(pp->dev, sys->busnr,
> -				  &dw_pcie_ops, sys, &sys->resources);
> +	bus = pci_scan_root_bus_msi(pp->dev, sys->busnr, &dw_pcie_ops, sys,
> +				    &sys->resources, &dw_pcie_msi_chip);
> +
>  	if (!bus)
>  		return NULL;
> 
> diff --git a/drivers/pci/host/pcie-xilinx.c b/drivers/pci/host/pcie-xilinx.c
> index f1a06a0..526807d 100644
> --- a/drivers/pci/host/pcie-xilinx.c
> +++ b/drivers/pci/host/pcie-xilinx.c
> @@ -647,8 +647,8 @@ static struct pci_bus *xilinx_pcie_scan_bus(int nr, struct pci_sys_data *sys)
>  	struct pci_bus *bus;
> 
>  	port->root_busno = sys->busnr;
> -	bus = pci_scan_root_bus(port->dev, sys->busnr, &xilinx_pcie_ops,
> -				sys, &sys->resources);
> +	bus = pci_scan_root_bus_msi(port->dev, sys->busnr, &xilinx_pcie_ops,
> +				sys, &sys->resources, &xilinx_pcie_msi_chip);
> 
>  	return bus;
>  }
> @@ -847,7 +847,6 @@ static int xilinx_pcie_probe(struct platform_device *pdev)
> 
>  #ifdef CONFIG_PCI_MSI
>  	xilinx_pcie_msi_chip.dev = port->dev;
> -	hw.msi_ctrl = &xilinx_pcie_msi_chip;
>  #endif
>  	pci_common_init_dev(dev, &hw);
> 



From linus.walleij at linaro.org  Thu Aug  6 07:50:13 2015
From: linus.walleij at linaro.org (Linus Walleij)
Date: Thu, 6 Aug 2015 16:50:13 +0200
Subject: [GIT PULL] Nomadik improvements and cleanups for v4.3
Message-ID: <CACRpkdbN6ZDhH56PSUmPD5_uYJhk_o+mCqAvi5GVEtys=AftNg@mail.gmail.com>

Hi ARM SoC folks,

these are a four patches of Nomadik cleanups and improvements
targeted for v4.2.

Since there is a cross-dependency between the board files and the
device tree files I just kept them all on the same branch. Also it seems
a bit overzealous to split patches for this small platform.

Please pull it in as cleanup/development for v4.3.

Yours,
Linus Walleij

The following changes since commit 74d33293e467df61de1b1d8b2fbe29e550dec33b:

  Linux 4.2-rc5 (2015-08-02 18:34:55 -0700)

are available in the git repository at:

  git://git.kernel.org/pub/scm/linux/kernel/git/linusw/linux-nomadik.git
tags/nmk-for-4.3-asoc

for you to fetch changes up to 8c6870b07dd20be91fa4f15fbfcbde75a4dccd28:

  ARM: nomadik: push accelerometer down to boards (2015-08-06 11:24:55 +0200)

----------------------------------------------------------------
Nomadik improvements and cleanups for v4.3:
- Get rid of some custom code and device tree oddities
  that were just placeholders for our now in-kernel
  GPIO hogs.
- Enable UART0 (connected to bluetooth on NHK15)
  selectively on the board, according to reference design
  specs.
- Do the cache AUX register setup in the device tree so
  we understand what is going on.
- Push registration of accelerometers down to the board
  files.

----------------------------------------------------------------
Linus Walleij (4):
      ARM: nomadik: move hog code to use DT hogs
      ARM: nomadik: selectively enable UART0 on boards
      ARM: nomadik: move l2x0 setup to device tree
      ARM: nomadik: push accelerometer down to boards

 arch/arm/boot/dts/ste-nomadik-nhk15.dts    | 39 ++++++++++++++++++++------
 arch/arm/boot/dts/ste-nomadik-s8815.dts    | 44 ++++++++++++++++++++++++------
 arch/arm/boot/dts/ste-nomadik-stn8815.dtsi | 22 +++++----------
 arch/arm/mach-nomadik/cpu-8815.c           | 41 ++--------------------------
 4 files changed, 75 insertions(+), 71 deletions(-)


From jingoohan1 at gmail.com  Thu Aug  6 07:51:24 2015
From: jingoohan1 at gmail.com (Jingoo Han)
Date: Thu, 6 Aug 2015 23:51:24 +0900
Subject: [PATCH v5 4/9] ARM/PCI: Remove msi_controller from struct
 pci_sys_data
In-Reply-To: <20150804215420.9189.22914.stgit@bhelgaas-glaptop2.roam.corp.google.com>
References: <20150804214234.9189.42548.stgit@bhelgaas-glaptop2.roam.corp.google.com>
 <20150804215420.9189.22914.stgit@bhelgaas-glaptop2.roam.corp.google.com>
Message-ID: <000601d0d057$63c40fb0$2b4c2f10$@com>

On Wednesday, August 05, 2015 6:54 AM, Bjorn Helgaas wrote:
> 
> From: Lorenzo Pieralisi <lorenzo.pieralisi at arm.com>
> 
> ARM now uses pci_bus->msi to store the msi_controller pointer, so we don't
> need to save it in struct pci_sys_data, and we don't need to implement
> pcibios_msi_controller() to get it out of pci_sys_data.
> 
> Remove msi_controller from struct pci_sys_data and
> pcibios_msi_controller().
> 
> [bhelgaas: changelog, split into separate patch]
> Signed-off-by: Lorenzo Pieralisi <lorenzo.pieralisi at arm.com>
> Signed-off-by: Bjorn Helgaas <bhelgaas at google.com>

Reviewed-by: Jingoo Han <jingoohan1 at gmail.com>

Best regards,
Jingoo Han

> ---
>  arch/arm/include/asm/mach/pci.h |    3 ---
>  arch/arm/kernel/bios32.c        |   12 ------------
>  2 files changed, 15 deletions(-)
> 
> diff --git a/arch/arm/include/asm/mach/pci.h b/arch/arm/include/asm/mach/pci.h
> index c074e7a..8857d28 100644
> --- a/arch/arm/include/asm/mach/pci.h
> +++ b/arch/arm/include/asm/mach/pci.h
> @@ -40,9 +40,6 @@ struct hw_pci {
>   * Per-controller structure
>   */
>  struct pci_sys_data {
> -#ifdef CONFIG_PCI_MSI
> -	struct msi_controller *msi_ctrl;
> -#endif
>  	struct list_head node;
>  	int		busnr;		/* primary bus number			*/
>  	u64		mem_offset;	/* bus->cpu memory mapping offset	*/
> diff --git a/arch/arm/kernel/bios32.c b/arch/arm/kernel/bios32.c
> index 283bc1c..874e182 100644
> --- a/arch/arm/kernel/bios32.c
> +++ b/arch/arm/kernel/bios32.c
> @@ -18,15 +18,6 @@
> 
>  static int debug_pci;
> 
> -#ifdef CONFIG_PCI_MSI
> -struct msi_controller *pcibios_msi_controller(struct pci_dev *dev)
> -{
> -	struct pci_sys_data *sysdata = dev->bus->sysdata;
> -
> -	return sysdata->msi_ctrl;
> -}
> -#endif
> -
>  /*
>   * We can't use pci_get_device() here since we are
>   * called from interrupt context.
> @@ -462,9 +453,6 @@ static void pcibios_init_hw(struct device *parent, struct hw_pci *hw,
>  		if (WARN(!sys, "PCI: unable to allocate sys data!"))
>  			break;
> 
> -#ifdef CONFIG_PCI_MSI
> -		sys->msi_ctrl = hw->msi_ctrl;
> -#endif
>  		sys->busnr   = busnr;
>  		sys->swizzle = hw->swizzle;
>  		sys->map_irq = hw->map_irq;



From ykk at rock-chips.com  Thu Aug  6 07:57:34 2015
From: ykk at rock-chips.com (Yakir Yang)
Date: Thu, 6 Aug 2015 22:57:34 +0800
Subject: [RFC PATCH 3/8] drm: bridge: analogix_dp: split exynos dp driver
 to bridge dir
In-Reply-To: <000101d0d054$f34e9c70$d9ebd550$@com>
References: <1438868947-22132-1-git-send-email-ykk@rock-chips.com>
 <1438870763-23796-1-git-send-email-ykk@rock-chips.com>
 <000101d0d054$f34e9c70$d9ebd550$@com>
Message-ID: <55C375DE.5070001@rock-chips.com>

Jingoo,

? 2015/8/6 22:33, Jingoo Han ??:
> On Thursday, August 06, 2015 11:19 PM, Yakir Yang wrote:
>> Split the dp core driver from exynos directory to bridge
>> directory, and rename the core driver to analogix_dp_*,
>> leave the platform code to analogix_dp-exynos.
>>
>> Signed-off-by: Yakir Yang <ykk at rock-chips.com>
>> ---
>>   drivers/gpu/drm/bridge/Kconfig                     |    5 +
>>   drivers/gpu/drm/bridge/Makefile                    |    1 +
>>   .../exynos_dp_core.c => bridge/analogix_dp_core.c} |  751 +++++-------
>>   drivers/gpu/drm/bridge/analogix_dp_core.h          |  286 +++++
>>   drivers/gpu/drm/bridge/analogix_dp_reg.c           | 1266 ++++++++++++++++++++
>>   .../exynos_dp_reg.h => bridge/analogix_dp_reg.h}   |  260 ++--
>>   drivers/gpu/drm/exynos/Kconfig                     |    5 +-
>>   drivers/gpu/drm/exynos/Makefile                    |    2 +-
>>   drivers/gpu/drm/exynos/analogix_dp-exynos.c        |  240 ++++
>>   drivers/gpu/drm/exynos/exynos_dp_core.h            |  283 -----
>>   include/drm/bridge/analogix_dp.h                   |   22 +
>>   11 files changed, 2287 insertions(+), 834 deletions(-)
>>   rename drivers/gpu/drm/{exynos/exynos_dp_core.c => bridge/analogix_dp_core.c} (54%)
>>   create mode 100644 drivers/gpu/drm/bridge/analogix_dp_core.h
>>   create mode 100644 drivers/gpu/drm/bridge/analogix_dp_reg.c
>>   rename drivers/gpu/drm/{exynos/exynos_dp_reg.h => bridge/analogix_dp_reg.h} (63%)
>>   create mode 100644 drivers/gpu/drm/exynos/analogix_dp-exynos.c
>>   delete mode 100644 drivers/gpu/drm/exynos/exynos_dp_core.h
>>   create mode 100644 include/drm/bridge/analogix_dp.h
>>
>> [...]
>> rename from drivers/gpu/drm/exynos/exynos_dp_core.c
>> rename to drivers/gpu/drm/bridge/analogix_dp_core.c
>> index aa99e23..28724d4 100644
>> --- a/drivers/gpu/drm/exynos/exynos_dp_core.c
>> +++ b/drivers/gpu/drm/bridge/analogix_dp_core.c
>> @@ -1,7 +1,8 @@
>>   /*
>> - * Samsung SoC DP (Display Port) interface driver.
>> + * Analogix Core DP (Display Port) interface driver.
>>    *
>>    * Copyright (C) 2012 Samsung Electronics Co., Ltd.
>> + * Copyright (C) FuZhou Rockchip Electronics Co., Ltd.
> What is the reason to add this copyright?
> You just replace 'exynos' prefix with 'analogix' prefix.
> I cannot find the reason to add the copyright.
>

Oh! Thanks for your point out, sorry for this one

- Yakir
>>    *
>> --
>> 2.1.2
>
>
>
>




From ykk at rock-chips.com  Thu Aug  6 08:00:47 2015
From: ykk at rock-chips.com (Yakir Yang)
Date: Thu, 6 Aug 2015 23:00:47 +0800
Subject: [RFC PATCH 0/8] Add Analogix Core Display Port Driver
In-Reply-To: <000201d0d056$06cff040$146fd0c0$@com>
References: <1438868947-22132-1-git-send-email-ykk@rock-chips.com>
 <000201d0d056$06cff040$146fd0c0$@com>
Message-ID: <55C3769F.2010405@rock-chips.com>

Jingoo,

? 2015/8/6 22:41, Jingoo Han ??:
> On Thursday, August 06, 2015 10:49 PM, Yakir Yang wrote:
>> Hi all,
>>     Samsung exynos and Rockchip rk3288 almost share same dp controller,
>> so I split the common code out, then rk3288 and exynos can re-used the
>> same dp core driver. Cause I can't find the exact IP name of exynos dp
>> controller, so I decide to name dp core driver with "analogix" which I
>> find in rk3288 eDP TRM ;)
>
> OK, I see.
> The Samsung Exynos eDP contoller and Rockchip rk3288 eDP contoller share
> the same IP. So, a lot of parts can be re-used. I agree with this.
> However, we have to review the code carefully, as others did.
Yeah, feel happy to be reviewed  ;)

> I also cannot find the exact IP name. The "analogix" may be the vendor name
> of this IP.
Okay, so "analogix" is okay for now

Thanks,
- Yakir
> Best regards,
> Jingoo Han
>
>> Beyond that, there are three light registers setting differents bewteen
>> exynos and rk3288.
>> 1. RK3288 have five special pll resigters which not indicata in exynos
>>     dp controller.
>> 2. The address of DP_PHY_PD(dp phy power manager register) are different
>>     between rk3288 and exynos.
>> 3. Rk3288 and exynos have different setting with AUX_HW_RETRY_CTL(dp debug
>>     register).
>>
>> My series patches can be divider into two parts: One for spliting the
>> analogix_dp code from exynos dp driver. Another are trying to add rk3288
>> dp driver support.
>>
>> Best regards,
>> - Yakir
>>
>>
>> --
>> 2.1.2
>
>
>
>




From pawel.moll at arm.com  Thu Aug  6 08:05:13 2015
From: pawel.moll at arm.com (Pawel Moll)
Date: Thu, 06 Aug 2015 16:05:13 +0100
Subject: [PATCH 1/3] clk: versatile: Switch to assigned clock parents
In-Reply-To: <55C24E56.3020004@codeaurora.org>
References: <55BBB2FC.9030102@codeaurora.org>
 <1438386285-5070-1-git-send-email-sboyd@codeaurora.org>
 <1438386285-5070-2-git-send-email-sboyd@codeaurora.org>
 <1438610480.2142.14.camel@arm.com> <55BFAB11.7080600@codeaurora.org>
 <1438770574.2142.80.camel@arm.com> <55C24E56.3020004@codeaurora.org>
Message-ID: <1438873513.2142.95.camel@arm.com>

On Wed, 2015-08-05 at 18:56 +0100, Stephen Boyd wrote:
> On 08/05/2015 03:29 AM, Pawel Moll wrote:
> >
> > Right, that's probably my fault. The sp810 nodes appeared in the VE
> > trees very early (in terms of the "DT era"), when we weren't so strict
> > about documentation. So far, it would be fairly simple, something like
> > the text below - feel free to take it, mend it, extend it with your
> > changes and include in the series:
> >
> > Thanks!
> 
> Great! Can you please provide your signed-off-by? 

Sure. 

8<--------------------------------------------------------

>From cddb00e4c8b6b57e82008fa23a7359560e5c997c Mon Sep 17 00:00:00 2001
From: Pawel Moll <pawel.moll at arm.com>
Date: Thu, 6 Aug 2015 16:04:10 +0100
Subject: [PATCH] clk: versatile: Add SP810 device tree bindings document

Signed-off-by: Pawel Moll <pawel.moll at arm.com>
---
 Documentation/devicetree/bindings/arm/sp810.txt | 35 +++++++++++++++++++++++++
 1 file changed, 35 insertions(+)
 create mode 100644 Documentation/devicetree/bindings/arm/sp810.txt

diff --git a/Documentation/devicetree/bindings/arm/sp810.txt b/Documentation/devicetree/bindings/arm/sp810.txt
new file mode 100644
index 0000000..440ee08
--- /dev/null
+++ b/Documentation/devicetree/bindings/arm/sp810.txt
@@ -0,0 +1,35 @@
+SP810 System Controller
+-----------------------
+
+Required properties:
+
+- compatible:	standard compatible string for a Primecell peripheral,
+		see Documentation/devicetree/bindings/arm/primecell.txt
+		for more details
+		should be: "arm,sp810", "arm,primecell"
+
+- reg:		standard registers property, physical address and size
+		of the control registers
+
+- clock-names:	from the common clock bindings, for more details see
+		Documentation/devicetree/bindings/clock/clock-bindings.txt;
+		should be: "refclk", "timclk", "apb_pclk"
+
+- clocks:	from the common clock bindings, phandle and clock
+		specifier pairs for the entries of clock-names property
+
+- #clock-cells: from the common clock bindings;
+		should be: <1>
+
+- clock-output-names: from the common clock bindings;
+		should be: "timerclken0", "timerclken1", "timerclken2", "timerclken3"
+
+Example:
+	sysctl at 020000 {
+		compatible = "arm,sp810", "arm,primecell";
+		reg = <0x020000 0x1000>;
+		clocks = <&v2m_refclk32khz>, <&v2m_refclk1mhz>, <&smbclk>;
+		clock-names = "refclk", "timclk", "apb_pclk";
+		#clock-cells = <1>;
+		clock-output-names = "timerclken0", "timerclken1", "timerclken2", "timerclken3";
+	};
-- 
2.1.4





From joe at perches.com  Thu Aug  6 08:05:36 2015
From: joe at perches.com (Joe Perches)
Date: Thu, 06 Aug 2015 08:05:36 -0700
Subject: [RFC PATCH 1/8] drm: exynos/dp: fix code style
In-Reply-To: <1438869866-23028-1-git-send-email-ykk@rock-chips.com>
References: <1438868947-22132-1-git-send-email-ykk@rock-chips.com>
 <1438869866-23028-1-git-send-email-ykk@rock-chips.com>
Message-ID: <1438873536.2679.61.camel@perches.com>

On Thu, 2015-08-06 at 09:04 -0500, Yakir Yang wrote:
> make checkpatch.pl script happy

That should not be the primary reason to submit a patch.

Making it easier for human code reader to understand
what the code does should be though.

> diff --git a/drivers/gpu/drm/exynos/exynos_dp_core.c b/drivers/gpu/drm/exynos/exynos_dp_core.c
[]
> @@ -123,10 +123,11 @@ static int exynos_dp_read_edid(struct exynos_dp_device *dp)
>  		dev_dbg(dp->dev, "EDID data includes a single extension!\n");
>  
>  		/* Read EDID data */
> -		retval = exynos_dp_read_bytes_from_i2c(dp, I2C_EDID_DEVICE_ADDR,
> -						EDID_HEADER_PATTERN,
> -						EDID_BLOCK_LENGTH,
> -						&edid[EDID_HEADER_PATTERN]);
> +		retval =
> +		exynos_dp_read_bytes_from_i2c(dp, I2C_EDID_DEVICE_ADDR,
> +					      EDID_HEADER_PATTERN,
> +					      EDID_BLOCK_LENGTH,
> +					      &edid[EDID_HEADER_PATTERN]);

This is a relatively uncommon style.

Because the code uses relatively long variable and
function names as well as longish macro #defines,
prefer to ignore the 80 column limit.




From jingoohan1 at gmail.com  Thu Aug  6 08:06:17 2015
From: jingoohan1 at gmail.com (Jingoo Han)
Date: Fri, 7 Aug 2015 00:06:17 +0900
Subject: [PATCH v6] PCI: Store PCIe bus address in struct of_pci_range
In-Reply-To: <EE11001F9E5DDD47B7634E2F8A612F2E01D72CFE@lhreml503-mbs>
References: <1438010223-124422-1-git-send-email-gabriele.paoloni@huawei.com>
 <20150729172053.GE31170@google.com>
 <EE11001F9E5DDD47B7634E2F8A612F2E01D6F350@lhreml503-mbs>
 <CAL_JsqKs11-sXQTdBD+ZjbVYFWUHBARTW9q5MF1hCXUhZ+nWLQ@mail.gmail.com>
 <EE11001F9E5DDD47B7634E2F8A612F2E01D6F94A@lhreml503-mbs>
 <20150730161447.GG9640@google.com>
 <EE11001F9E5DDD47B7634E2F8A612F2E01D6FB3B@lhreml503-mbs>
 <20150730171445.GI9640@google.com>
 <EE11001F9E5DDD47B7634E2F8A612F2E01D6FC15@lhreml503-mbs>
 <CAL_Jsq+aQVakaZf4xo7sxnVyTmPR+HJ-9ByyS6OYJ0PHDYOwmg@mail.gmail.com>
 <EE11001F9E5DDD47B7634E2F8A612F2E01D70589@lhreml503-mbs>
 <55BB8CC6.1080203@ti.com>
 <CAL_JsqJqjiWVaKs-3ghQ1EBQzRRQ38GzkMV+FELPj53bSF-yXQ@mail.gmail.com>
 <EE11001F9E5DDD47B7634E2F8A612F2E01D712E7@lhreml503-mbs>
 <7F6386B4-D2F5-4840-AC72-F8C76CBC3B94@gmail.com>
 <EE11001F9E5DDD47B7634E2F8A612F2E01D719D1@lhreml503-mbs>
 <EE11001F9E5DDD47B7634E2F8A612F2E01D72CFE@lhreml503-mbs>
Message-ID: <000701d0d059$7810fb70$6832f250$@com>

On Thursday, August 06, 2015 10:53 PM, Gabriele Paoloni wrote:
> 
> Hi all
> 
> This patch has now been moved in "[PATCH v6 1/6] PCI: designware: move calculation of bus addresses to
> DRA7xx"

To Zhou Wang,

Please send your patches to 'jingoohan1 at gmail.com', instead of 'jg1.han at samsung.com'.
Even though, I have done mainline works for Samsung SoCs, Samsung does not support me
as a maintainer. So, please don't send your patches to my Samsung e-mail.

Best regards,
Jingoo Han

> 
> commit "f4c55c5a3f7f (PCI: designware: Program ATU with untranslated address)" has been reverted in
> "[PATCH v6 3/6] PCI: designware: Add ARM64 support"
> 
> Gab
> 
> > -----Original Message-----
> > From: linux-pci-owner at vger.kernel.org [mailto:linux-pci-
> > owner at vger.kernel.org] On Behalf Of Gabriele Paoloni
> > Sent: Tuesday, August 04, 2015 11:12 AM
> > To: Jingoo Han
> > Cc: Rob Herring; Kishon Vijay Abraham I; Bjorn Helgaas; arnd at arndb.de;
> > lorenzo.pieralisi at arm.com; Wangzhou (B); robh+dt at kernel.org;
> > james.morse at arm.com; Liviu.Dudau at arm.com; linux-pci at vger.kernel.org;
> > linux-arm-kernel at lists.infradead.org; devicetree at vger.kernel.org;
> > Yuanzhichang; Zhudacai; zhangjukuo; qiuzhenfa; Liguozhu (Kenneth);
> > Pratyush Anand; Arnd Bergmann
> > Subject: RE: [PATCH v6] PCI: Store PCIe bus address in struct
> > of_pci_range
> >
> >
> >
> > > -----Original Message-----
> > > From: Jingoo Han [mailto:jingoohan1 at gmail.com]
> > > Sent: Tuesday, August 04, 2015 5:20 AM
> > > To: Gabriele Paoloni
> > > Cc: Rob Herring; Kishon Vijay Abraham I; Bjorn Helgaas; arnd at arndb.de;
> > > lorenzo.pieralisi at arm.com; Wangzhou (B); robh+dt at kernel.org;
> > > james.morse at arm.com; Liviu.Dudau at arm.com; linux-pci at vger.kernel.org;
> > > linux-arm-kernel at lists.infradead.org; devicetree at vger.kernel.org;
> > > Yuanzhichang; Zhudacai; zhangjukuo; qiuzhenfa; Liguozhu (Kenneth);
> > > Pratyush Anand; Arnd Bergmann; jingoohan1 at gmail.com
> > > Subject: Re: [PATCH v6] PCI: Store PCIe bus address in struct
> > > of_pci_range
> > >
> > > On 2015. 8. 3., at PM 8:18, Gabriele Paoloni
> > > <gabriele.paoloni at huawei.com> wrote:
> > > >
> > > > Rob, Kishon what about the following solution?....
> > > >
> > > > ---
> > > > drivers/pci/host/pci-dra7xx.c      | 12 ++++++++++++
> > > > drivers/pci/host/pcie-designware.c |  9 +++------
> > >
> > > Hi Paoloni,
> > >
> > > OK, it looks good.
> > > I want you to revert the following patch.
> > >
> > > commit "f4c55c5a3f7f (PCI: designware: Program ATU with untranslated
> > > address)"
> > >
> > > Would you remove all '*_mode_base's?
> >
> > Hi Jingoo Han,
> >
> > If I reverted the commit, in order to get designware working, dra7
> > should mask directly the CPU addresses stored in pp->cfg0_base,
> > pp->cfg1_base, pp->mem_base and pp->io_base.
> >
> > The masking would happen at this point:
> > http://lxr.free-electrons.com/source/drivers/pci/host/pcie-
> > designware.c#L493
> >
> > Now:
> > - I see that pp->cfg<0/1>_base are used in devm_ioremap before that
> >   point and nowhere else, so they should be ok.
> > - pp->mem_base is used in dw_pcie_setup_rc(); dw_pcie_setup_rc() is
> > called
> >   in dra7xx_pcie_host_init()...so here I should move the masking after
> >   dw_pcie_setup() retuned, but I think it should be ok
> > - pp->io_base is used in pci_ioremap_io() in dw_pcie_setup(). Now
> > currently
> >   in designware this is called by pci_bios_init_hw(); this is after the
> >   masking....so here we would have a the wrong value passed
> >
> > Said that if you look at "[PATCH v5 2/5] PCI: designware: Add ARM64
> > support",
> > that is the patchset where this patch is needed, you can see that
> > dw_pcie_setup() is removed and pp->io_base is used in
> > pci_remap_iospace() before
> > the masking would happen in dra7xx_pcie_host_init()...so for this
> > patchset we
> > should be good to revert the commit.
> >
> > I propose to add a new patch in the patchset "[PATCH v5 0/5] PCI: hisi:
> > Add PCIe
> > host support for HiSilicon SoC Hip05" as the one I just posted in this
> > thread (this would not revert the commit but just moves the masking to
> > dra7xx)
> >
> > I would revert the commit in "[PATCH v5 2/5] PCI: designware: Add ARM64
> > support"
> > together with the rest of designware rework.
> >
> > So we would have always a working version of designware...
> >
> > Are you ok with this?
> >
> > >
> > > Best regards,
> > > Jingoo Han
> > >
> > > > 2 files changed, 15 insertions(+), 6 deletions(-)
> > > >
> > > > diff --git a/drivers/pci/host/pci-dra7xx.c b/drivers/pci/host/pci-
> > > dra7xx.c
> > > > index 80db09e..bb2635f 100644
> > > > --- a/drivers/pci/host/pci-dra7xx.c
> > > > +++ b/drivers/pci/host/pci-dra7xx.c
> > > > @@ -61,6 +61,7 @@
> > > >
> > > > #define    PCIECTRL_DRA7XX_CONF_PHY_CS            0x010C
> > > > #define    LINK_UP                        BIT(16)
> > > > +#define CPU_TO_BUS_ADDR             0x0FFFFFFF
> > > >
> > > > struct dra7xx_pcie {
> > > >    void __iomem        *base;
> > > > @@ -138,6 +139,17 @@ static void
> > dra7xx_pcie_enable_interrupts(struct
> > > pcie_port *pp)
> > > >
> > > > static void dra7xx_pcie_host_init(struct pcie_port *pp)
> > > > {
> > > > +    if (pp->io_mod_base)
> > > > +        pp->io_mod_base &= CPU_TO_BUS_ADDR;
> > > > +
> > > > +    if (pp->mem_mod_base)
> > > > +        pp->mem_mod_base &= CPU_TO_BUS_ADDR;
> > > > +
> > > > +    if (pp->cfg0_mod_base) {
> > > > +        pp->cfg0_mod_base &= CPU_TO_BUS_ADDR;
> > > > +        pp->cfg1_mod_base &= CPU_TO_BUS_ADDR;
> > > > +    }
> > > > +
> > > >    dw_pcie_setup_rc(pp);
> > > >    dra7xx_pcie_establish_link(pp);
> > > >    if (IS_ENABLED(CONFIG_PCI_MSI))
> > > > diff --git a/drivers/pci/host/pcie-designware.c
> > > b/drivers/pci/host/pcie-designware.c
> > > > index 69486be..06c682b 100644
> > > > --- a/drivers/pci/host/pcie-designware.c
> > > > +++ b/drivers/pci/host/pcie-designware.c
> > > > @@ -416,8 +416,7 @@ int dw_pcie_host_init(struct pcie_port *pp)
> > > >            pp->io_base = range.cpu_addr;
> > > >
> > > >            /* Find the untranslated IO space address */
> > > > -            pp->io_mod_base = of_read_number(parser.range -
> > > > -                             parser.np + na, ns);
> > > > +            pp->io_mod_base = range.cpu_addr;;
> > > >        }
> > > >        if (restype == IORESOURCE_MEM) {
> > > >            of_pci_range_to_resource(&range, np, &pp->mem);
> > > > @@ -426,8 +425,7 @@ int dw_pcie_host_init(struct pcie_port *pp)
> > > >            pp->mem_bus_addr = range.pci_addr;
> > > >
> > > >            /* Find the untranslated MEM space address */
> > > > -            pp->mem_mod_base = of_read_number(parser.range -
> > > > -                              parser.np + na, ns);
> > > > +            pp->mem_mod_base = range.cpu_addr;
> > > >        }
> > > >        if (restype == 0) {
> > > >            of_pci_range_to_resource(&range, np, &pp->cfg);
> > > > @@ -437,8 +435,7 @@ int dw_pcie_host_init(struct pcie_port *pp)
> > > >            pp->cfg1_base = pp->cfg.start + pp->cfg0_size;
> > > >
> > > >            /* Find the untranslated configuration space address */
> > > > -            pp->cfg0_mod_base = of_read_number(parser.range -
> > > > -                               parser.np + na, ns);
> > > > +            pp->cfg0_mod_base = range.cpu_addr;
> > > >            pp->cfg1_mod_base = pp->cfg0_mod_base +
> > > >                        pp->cfg0_size;
> > > >        }
> > > > --
> > > > 1.9.1
> > > >
> > > >
> > > >> -----Original Message-----
> > > >> From: linux-pci-owner at vger.kernel.org [mailto:linux-pci-
> > > >> owner at vger.kernel.org] On Behalf Of Rob Herring
> > > >> Sent: Friday, July 31, 2015 5:53 PM
> > > >> To: Kishon Vijay Abraham I
> > > >> Cc: Gabriele Paoloni; Bjorn Helgaas; arnd at arndb.de;
> > > >> lorenzo.pieralisi at arm.com; Wangzhou (B); robh+dt at kernel.org;
> > > >> james.morse at arm.com; Liviu.Dudau at arm.com; linux-
> > pci at vger.kernel.org;
> > > >> linux-arm-kernel at lists.infradead.org; devicetree at vger.kernel.org;
> > > >> Yuanzhichang; Zhudacai; zhangjukuo; qiuzhenfa; Liguozhu (Kenneth);
> > > >> Jingoo Han; Pratyush Anand; Arnd Bergmann
> > > >> Subject: Re: [PATCH v6] PCI: Store PCIe bus address in struct
> > > >> of_pci_range
> > > >>
> > > >> On Fri, Jul 31, 2015 at 9:57 AM, Kishon Vijay Abraham I
> > > <kishon at ti.com>
> > > >> wrote:
> > > >>> +Arnd
> > > >>>
> > > >>> Hi,
> > > >>>
> > > >>>> On Friday 31 July 2015 07:55 PM, Gabriele Paoloni wrote:
> > > >>>> [+cc Kishon]
> > > >>>>
> > > >>>>> -----Original Message-----
> > > >>>>> From: linux-pci-owner at vger.kernel.org [mailto:linux-pci-
> > > >>>>> owner at vger.kernel.org] On Behalf Of Rob Herring
> > > >>>>> Sent: Thursday, July 30, 2015 9:42 PM
> > > >>>>> To: Gabriele Paoloni
> > > >>>>> Cc: Bjorn Helgaas; arnd at arndb.de; lorenzo.pieralisi at arm.com;
> > > >> Wangzhou
> > > >>>>> (B); robh+dt at kernel.org; james.morse at arm.com;
> > Liviu.Dudau at arm.com;
> > > >>>>> linux-pci at vger.kernel.org; linux-arm-kernel at lists.infradead.org;
> > > >>>>> devicetree at vger.kernel.org; Yuanzhichang; Zhudacai; zhangjukuo;
> > > >>>>> qiuzhenfa; Liguozhu (Kenneth); Jingoo Han; Pratyush Anand
> > > >>>>> Subject: Re: [PATCH v6] PCI: Store PCIe bus address in struct
> > > >>>>> of_pci_range
> > > >>>>>
> > > >>>>> On Thu, Jul 30, 2015 at 12:34 PM, Gabriele Paoloni
> > > >>>>> <gabriele.paoloni at huawei.com> wrote:
> > > >>>>>>> -----Original Message-----
> > > >>>>>>> From: Bjorn Helgaas [mailto:bhelgaas at google.com]
> > > >>>>>>> Sent: 30 July 2015 18:15
> > > >>>>>>> On Thu, Jul 30, 2015 at 04:50:55PM +0000, Gabriele Paoloni
> > > wrote:
> > > >>>>>>>>> -----Original Message-----
> > > >>>>>>>>> From: linux-pci-owner at vger.kernel.org [mailto:linux-pci-
> > > >>>>>>>>> owner at vger.kernel.org] On Behalf Of Bjorn Helgaas
> > > >>>>>>>>> Sent: Thursday, July 30, 2015 5:15 PM
> > > >>>>>>>>> On Thu, Jul 30, 2015 at 01:52:13PM +0000, Gabriele Paoloni
> > > >> wrote:
> > > >>>>>
> > > >>>>> [...]
> > > >>>>>
> > > >>>>>>>>>> I don?t think we should rely on [CPU] addresses...what if
> > > the
> > > >>>>>>>>> intermediate
> > > >>>>>>>>>> translation layer changes the lower significant bits of
> > the
> > > >>>>> "bus
> > > >>>>>>>>> address"
> > > >>>>>>>>>> to translate into a cpu address?
> > > >>>>>>>>>
> > > >>>>>>>>> Is it really a possiblity that the lower bits could be
> > > changed?
> > > >>>>>>>>
> > > >>>>>>>> I've checked all the current deignware users DTs except
> > "pci-
> > > >>>>>>> layerscape"
> > > >>>>>>>> that I could not find:
> > > >>>>>>>> spear1310.dtsi
> > > >>>>>>>> spear1340.dtsi
> > > >>>>>>>> dra7.dtsi
> > > >>>>>>>> imx6qdl.dtsi
> > > >>>>>>>> imx6sx.dtsi
> > > >>>>>>>> keystone.dtsi
> > > >>>>>>>> exynos5440.dtsi
> > > >>>>>>>>
> > > >>>>>>>> None of them modifies the lower bits. To be more precise the
> > > >> only
> > > >>>>> guy
> > > >>>>>>>> that provides another translation layer is "dra7.dtsi":
> > > >>>>>>>> axi0
> > > >>>>>>>> http://lxr.free-
> > > >>>>> electrons.com/source/arch/arm/boot/dts/dra7.dtsi#L207
> > > >>>>>>>>
> > > >>>>>>>> axi1
> > > >>>>>>>> http://lxr.free-
> > > >>>>> electrons.com/source/arch/arm/boot/dts/dra7.dtsi#L241
> > > >>>>>>>>
> > > >>>>>>>> For this case masking the top 4bits (bits28 to 31) should
> > make
> > > >> the
> > > >>>>> job.
> > > >>>>>
> > > >>>>> IMO, we should just fix this case. After further study, I don't
> > > >> think
> > > >>>>> this is a DW issue, but rather an SOC integration issue.
> > > >>>>>
> > > >>>>> I believe you can just fixup the address in the pp->ops-
> > > >host_init
> > > >> hook.
> > > >>>>
> > > >>>> Yes I guess that I could just assign pp->(*)_mod_base to the CPU
> > > >> address
> > > >>>> in DW and mask it out in dra7xx_pcie_host_init()...
> > > >>>>
> > > >>>> Kishon, would you be ok with that?
> > > >>>
> > > >>> Initially I was using *base-mask* property from dt. Me and Arnd
> > > >> (cc'ed) had
> > > >>> this discussion [1] before we decided the current approach. It'll
> > > be
> > > >> good to
> > > >>> check with Arnd too.
> > > >>>
> > > >>> [1] ->  http://lists.infradead.org/pipermail/linux-arm-
> > kernel/2014-
> > > >> May/253528.html
> > > >>
> > > >> The problem I have here is the use of ranges does not necessarily
> > > mean
> > > >> fewer address bits are available. It can be used just for
> > > convenience
> > > >> of not putting the full address into every node's reg property.
> > And
> > > >> vice versa, there are probably plenty of cases where we have the
> > > full
> > > >> address in the nodes, but really only some of the address bits are
> > > >> decoded at the IP block. Whether the address bits are present is
> > > >> rarely cared about or known by s/w folks until you hit a problem
> > > like
> > > >> this. Given this is an isolated case ATM, I would fix it in an
> > > >> isolated way. It does not affect the binding and could be changed
> > in
> > > >> the kernel later if this becomes a common need.
> > > >>
> > > >> Rob
> > > >> --
> > > >> To unsubscribe from this list: send the line "unsubscribe linux-
> > pci"
> > > in
> > > >> the body of a message to majordomo at vger.kernel.org
> > > >> More majordomo info at  http://vger.kernel.org/majordomo-info.html



From will.deacon at arm.com  Thu Aug  6 08:07:50 2015
From: will.deacon at arm.com (Will Deacon)
Date: Thu, 6 Aug 2015 16:07:50 +0100
Subject: [GIT PULL] iommu/arm-smmu: Updates for 4.3
Message-ID: <20150806150749.GF25483@arm.com>

Hi Joerg,

Here are the arm-smmu and io-pgtable updates I have for 4.3. Main
changes include:

  * Preparation for MSI support for SMMUv3 devices (full support will
    likely come in 4.4, since the IRQ core needs some work to support
    non-PCI devices).

  * A couple of minor fixes in the SMMUv3 driver

  * Support for the dma-coherent propery on SMMUv1/2 devices

  * Removal of the DMA API abuse for flushing page tables out to a
    non-coherent walker. This raised some questions about the DMA API
    Documentation, so I've put these last in the series in case you
    decide not to include them (but I think they're a welcome clean-up).

Please pull,

Will

--->8

The following changes since commit cbfe8fa6cd672011c755c3cd85c9ffd4e2d10a6f:

  Linux 4.2-rc4 (2015-07-26 12:26:21 -0700)

are available in the git repository at:

  git://git.kernel.org/pub/scm/linux/kernel/git/will/linux.git for-joerg/arm-smmu/updates

for you to fetch changes up to f5b831907da3e64bfb0288089a5c07124266b1a5:

  iommu/io-pgtable: Remove flush_pgtable callback (2015-08-06 14:35:40 +0100)

----------------------------------------------------------------
Marc Zyngier (2):
      iommu/arm-smmu: Fix enabling of PRIQ interrupt
      iommu/arm-smmu: Fix MSI memory attributes to match specification

Robin Murphy (9):
      iommu/arm-smmu: Sort out coherency
      iommu/io-pgtable-arm: Allow appropriate DMA API use
      iommu/arm-smmu: Clean up DMA API usage
      iommu/arm-smmu: Clean up DMA API usage
      iommu/ipmmu-vmsa: Clean up DMA API usage
      iommu/io-pgtable-arm: Centralise sync points
      iommu/arm-smmu: Remove arm_smmu_flush_pgtable()
      iommu/arm-smmu: Remove arm_smmu_flush_pgtable()
      iommu/io-pgtable: Remove flush_pgtable callback

Will Deacon (2):
      iommu/arm-smmu: Limit 2-level strtab allocation for small SID sizes
      iommu/arm-smmu: Treat unknown OAS as 48-bit

 .../devicetree/bindings/iommu/arm,smmu.txt         |   6 +
 drivers/iommu/Kconfig                              |   3 +-
 drivers/iommu/arm-smmu-v3.c                        |  66 +++++------
 drivers/iommu/arm-smmu.c                           |  45 +++-----
 drivers/iommu/io-pgtable-arm.c                     | 126 +++++++++++++++------
 drivers/iommu/io-pgtable.h                         |   9 +-
 drivers/iommu/ipmmu-vmsa.c                         |  19 +---
 7 files changed, 157 insertions(+), 117 deletions(-)


From slash.tmp at free.fr  Thu Aug  6 08:17:06 2015
From: slash.tmp at free.fr (Mason)
Date: Thu, 06 Aug 2015 17:17:06 +0200
Subject: IRQ setup on multicore systems (routing, balancing, etc)
In-Reply-To: <55C0C102.7050600@free.fr>
References: <55C0C102.7050600@free.fr>
Message-ID: <55C37A72.2090507@free.fr>

On 04/08/2015 15:41, Mason wrote:

> I have a few very naive questions about [snip]

[META]

Are there perhaps more suitable mailing lists than this one
for such beginner questions?

(It looks like LAKML is for experienced Linux devs proposing kernel
changes, or submitting patches for existing ports.)

I lurked in the #devicetree IRC channel, but there was no activity
in ~6 hours (despite 40 people connected).

Hmmm, I'll give kernelnewbies a try.
http://kernelnewbies.org/mailinglistguidelines

Regards.



From olof at lixom.net  Thu Aug  6 08:18:22 2015
From: olof at lixom.net (Olof Johansson)
Date: Thu, 6 Aug 2015 17:18:22 +0200
Subject: [PATCH 2/2] ARM: ux500: simplify secondary CPU boot
In-Reply-To: <CACRpkdZDyVjLmOcdUVBmRQo_fLf0TA84kA8yJNpsYGBkn5Jzzg@mail.gmail.com>
References: <1438586812-30164-1-git-send-email-linus.walleij@linaro.org>
 <20150806081130.GC16520@localhost>
 <CACRpkdZDyVjLmOcdUVBmRQo_fLf0TA84kA8yJNpsYGBkn5Jzzg@mail.gmail.com>
Message-ID: <CAOesGMgtC=cGZJ1GqETyQN5Ap=g1HbvWyU61Y3c6Araq5F_5iw@mail.gmail.com>

On Thu, Aug 6, 2015 at 4:40 PM, Linus Walleij <linus.walleij at linaro.org> wrote:
> On Thu, Aug 6, 2015 at 10:11 AM, Olof Johansson <olof at lixom.net> wrote:
>> On Mon, Aug 03, 2015 at 09:26:52AM +0200, Linus Walleij wrote:
>>> This removes a lot of ancient cruft from the Ux500 SMP boot.
>>> Instead of the pen grab/release, just point the ROM to
>>> secondary_boot() and start the second CPU there, then send
>>> the IPI.
>>>
>>> Use our own SMP enable method. This enables us to remove the
>>> last static mapping and get both CPUs booting properly.
>>>
>>> Tested this and it just works.
>>>
>>> Signed-off-by: Linus Walleij <linus.walleij at linaro.org>
>>> ---
>>> Hi ARM SoC folks: please apply this to fixes for v4.2. I was
>>> intending it for v4.3 but we might as well just kill off the
>>> legacy boot method right now so we do not need to restore any
>>> static maps and undo the cleanup (which would be just as
>>> invasive).
>>
>> It's a bit late in the cycle for that. I'll apply it in cleanup for 4.3 though.
>
> OK I've got a bunch of cleanups for Ux500, shall I include these
> in the pull request or will you apply this separately?

I've applied it already so just send a pull request with the rest of
it (hopefully not too much conflicts).


-Olof


From gregory.clement at free-electrons.com  Thu Aug  6 08:18:48 2015
From: gregory.clement at free-electrons.com (Gregory CLEMENT)
Date: Thu,  6 Aug 2015 17:18:48 +0200
Subject: [PATCH] rtc: armada38x: Align RTC set time procedure with the
 official errata
Message-ID: <1438874328-31844-1-git-send-email-gregory.clement@free-electrons.com>

From: Nadav Haklai <nadavh at marvell.com>

According to the Armada38x functional errata FE-3124064, writing to
the RTC TIME register may fail. As a workaround, after writing to RTC
TIME register, issue a dummy write of 0x0 twice to the RTC Status
register.  This is the updated implementation of the Errata that
eliminates the need of the long 100ms delay during the RTC set time
procedure.

[gregory.clement at free-electrons.com]: removed the mutex and use the
spinlock again

Signed-off-by: Nadav Haklai <nadavh at marvell.com>
Reviewed-by: Neta Zur Hershkovits <neta at marvell.com>
Signed-off-by: Gregory CLEMENT <gregory.clement at free-electrons.com>
---
Hi,

Finally the long 100ms wait was not needed! So we can remove the mutex
introduced in an earlier commit.
It would be great if this patch could be part of the 4.2-rc.

Thanks

Gregory


 drivers/rtc/rtc-armada38x.c | 32 ++++++++++++--------------------
 1 file changed, 12 insertions(+), 20 deletions(-)

diff --git a/drivers/rtc/rtc-armada38x.c b/drivers/rtc/rtc-armada38x.c
index 2b08cac62f07..06c6bd5eab41 100644
--- a/drivers/rtc/rtc-armada38x.c
+++ b/drivers/rtc/rtc-armada38x.c
@@ -40,13 +40,6 @@ struct armada38x_rtc {
 	void __iomem	    *regs;
 	void __iomem	    *regs_soc;
 	spinlock_t	    lock;
-	/*
-	 * While setting the time, the RTC TIME register should not be
-	 * accessed. Setting the RTC time involves sleeping during
-	 * 100ms, so a mutex instead of a spinlock is used to protect
-	 * it
-	 */
-	struct mutex	    mutex_time;
 	int		    irq;
 };
 
@@ -64,9 +57,9 @@ static void rtc_delayed_write(u32 val, struct armada38x_rtc *rtc, int offset)
 static int armada38x_rtc_read_time(struct device *dev, struct rtc_time *tm)
 {
 	struct armada38x_rtc *rtc = dev_get_drvdata(dev);
-	unsigned long time, time_check;
+	unsigned long time, time_check, flags;
 
-	mutex_lock(&rtc->mutex_time);
+	spin_lock_irqsave(&rtc->lock, flags);
 	time = readl(rtc->regs + RTC_TIME);
 	/*
 	 * WA for failing time set attempts. As stated in HW ERRATA if
@@ -77,7 +70,7 @@ static int armada38x_rtc_read_time(struct device *dev, struct rtc_time *tm)
 	if ((time_check - time) > 1)
 		time_check = readl(rtc->regs + RTC_TIME);
 
-	mutex_unlock(&rtc->mutex_time);
+	spin_unlock_irqrestore(&rtc->lock, flags);
 
 	rtc_time_to_tm(time_check, tm);
 
@@ -88,23 +81,23 @@ static int armada38x_rtc_set_time(struct device *dev, struct rtc_time *tm)
 {
 	struct armada38x_rtc *rtc = dev_get_drvdata(dev);
 	int ret = 0;
-	unsigned long time;
+	unsigned long time, flags;
 
 	ret = rtc_tm_to_time(tm, &time);
 
 	if (ret)
 		goto out;
 	/*
-	 * Setting the RTC time not always succeeds. According to the
-	 * errata we need to first write on the status register and
-	 * then wait for 100ms before writing to the time register to be
-	 * sure that the data will be taken into account.
+	 * According to errata FE-3124064, Write to RTC TIME register
+	 * may fail. As a workaround, after writing to RTC TIME
+	 * register, issue a dummy write of 0x0 twice to RTC Status
+	 * register.
 	 */
-	mutex_lock(&rtc->mutex_time);
-	rtc_delayed_write(0, rtc, RTC_STATUS);
-	msleep(100);
+	spin_lock_irqsave(&rtc->lock, flags);
 	rtc_delayed_write(time, rtc, RTC_TIME);
-	mutex_unlock(&rtc->mutex_time);
+	rtc_delayed_write(0, rtc, RTC_STATUS);
+	rtc_delayed_write(0, rtc, RTC_STATUS);
+	spin_unlock_irqrestore(&rtc->lock, flags);
 
 out:
 	return ret;
@@ -229,7 +222,6 @@ static __init int armada38x_rtc_probe(struct platform_device *pdev)
 		return -ENOMEM;
 
 	spin_lock_init(&rtc->lock);
-	mutex_init(&rtc->mutex_time);
 
 	res = platform_get_resource_byname(pdev, IORESOURCE_MEM, "rtc");
 	rtc->regs = devm_ioremap_resource(&pdev->dev, res);
-- 
2.1.0



From ykk at rock-chips.com  Thu Aug  6 08:20:48 2015
From: ykk at rock-chips.com (Yakir Yang)
Date: Thu, 6 Aug 2015 23:20:48 +0800
Subject: [RFC PATCH 1/8] drm: exynos/dp: fix code style
In-Reply-To: <1438873536.2679.61.camel@perches.com>
References: <1438868947-22132-1-git-send-email-ykk@rock-chips.com>
 <1438869866-23028-1-git-send-email-ykk@rock-chips.com>
 <1438873536.2679.61.camel@perches.com>
Message-ID: <55C37B50.6050706@rock-chips.com>

Joe,

? 2015/8/6 23:05, Joe Perches ??:
> On Thu, 2015-08-06 at 09:04 -0500, Yakir Yang wrote:
>> make checkpatch.pl script happy
> That should not be the primary reason to submit a patch.
>
> Making it easier for human code reader to understand
> what the code does should be though.
Thanks for your reply, but I do think that fix code style and make 
checkpatch.pl passed is my primary reason to submit this patch. I can't 
think out more directly words ;( ,

>> diff --git a/drivers/gpu/drm/exynos/exynos_dp_core.c b/drivers/gpu/drm/exynos/exynos_dp_core.c
> []
>> @@ -123,10 +123,11 @@ static int exynos_dp_read_edid(struct exynos_dp_device *dp)
>>   		dev_dbg(dp->dev, "EDID data includes a single extension!\n");
>>   
>>   		/* Read EDID data */
>> -		retval = exynos_dp_read_bytes_from_i2c(dp, I2C_EDID_DEVICE_ADDR,
>> -						EDID_HEADER_PATTERN,
>> -						EDID_BLOCK_LENGTH,
>> -						&edid[EDID_HEADER_PATTERN]);
>> +		retval =
>> +		exynos_dp_read_bytes_from_i2c(dp, I2C_EDID_DEVICE_ADDR,
>> +					      EDID_HEADER_PATTERN,
>> +					      EDID_BLOCK_LENGTH,
>> +					      &edid[EDID_HEADER_PATTERN]);
> This is a relatively uncommon style.
>
> Because the code uses relatively long variable and
> function names as well as longish macro #defines,
> prefer to ignore the 80 column limit.
Okay, I think it would be better to modify like those:

retval = exynos_dp_read_bytes_from_i2c(
		dp, I2C_EDID_DEVICE_ADDR,
		EDID_HEADER_PATTERN,
		EDID_BLOCK_LENGTH,
		&edid[EDID_HEADER_PATTERN]);


Is it okay ?

- Yakir
>
>
>
>




From will.deacon at arm.com  Thu Aug  6 08:23:27 2015
From: will.deacon at arm.com (Will Deacon)
Date: Thu, 6 Aug 2015 16:23:27 +0100
Subject: [PATCH v5 1/3] iommu: Implement common IOMMU ops for DMA mapping
In-Reply-To: <6ce6b501501f611297ae0eae31e07b0d2060eaae.1438362603.git.robin.murphy@arm.com>
References: <cover.1438362603.git.robin.murphy@arm.com>
 <6ce6b501501f611297ae0eae31e07b0d2060eaae.1438362603.git.robin.murphy@arm.com>
Message-ID: <20150806152327.GH25483@arm.com>

Joerg,

On Fri, Jul 31, 2015 at 06:18:27PM +0100, Robin Murphy wrote:
> Taking inspiration from the existing arch/arm code, break out some
> generic functions to interface the DMA-API to the IOMMU-API. This will
> do the bulk of the heavy lifting for IOMMU-backed dma-mapping.
> 
> Signed-off-by: Robin Murphy <robin.murphy at arm.com>
> ---
>  drivers/iommu/Kconfig     |   7 +
>  drivers/iommu/Makefile    |   1 +
>  drivers/iommu/dma-iommu.c | 534 ++++++++++++++++++++++++++++++++++++++++++++++
>  include/linux/dma-iommu.h |  84 ++++++++
>  include/linux/iommu.h     |   1 +
>  5 files changed, 627 insertions(+)
>  create mode 100644 drivers/iommu/dma-iommu.c
>  create mode 100644 include/linux/dma-iommu.h

We're quite keen to get this in for arm64, since we're without IOMMU DMA
ops and need to get something upstream. Do you think this is likely to
be merged for 4.3/4.4 or would we be better off doing our own
arch-private implementation instead?

Sorry to pester, but we've got people basing their patches and products
on this and I don't want to end up having to support out-of-tree code.

Cheers,

Will


From marc.zyngier at arm.com  Thu Aug  6 08:26:10 2015
From: marc.zyngier at arm.com (Marc Zyngier)
Date: Thu, 06 Aug 2015 16:26:10 +0100
Subject: [PATCH v5 9/9] PCI: xgene: Use pci_scan_root_bus_msi()
In-Reply-To: <20150804215457.9189.27595.stgit@bhelgaas-glaptop2.roam.corp.google.com>
References: <20150804214234.9189.42548.stgit@bhelgaas-glaptop2.roam.corp.google.com>
 <20150804215457.9189.27595.stgit@bhelgaas-glaptop2.roam.corp.google.com>
Message-ID: <55C37C92.1020509@arm.com>

Hi Bjorn,

On 04/08/15 22:54, Bjorn Helgaas wrote:
> Previously there was no way to specify the MSI controller when creating a
> new PCI root bus, so we had to create the bus, set its MSI controller, then
> scan the bus.  With the new pci_scan_root_bus_msi() interface, we can
> specify the MSI controller up front and get rid of that intermediate step.
> 
> Look up the MSI controller first, then use pci_scan_root_bus_msi() to
> create and scan the root PCI bus.

I'm wondering about these XGene patches.

With the code that is queued for v4.3 in tip/irq/core, the X-Gene MSI
driver doesn't export a struct msi_controller anymore, and entirely
relies on IRQ domains to identify to be matched with the actual PCI driver.

Do you intend this as a cleanup until everything lands in mainline? At
that point, we'd be able to remove all traces of struct msi_controller
from this driver.

Alternatively, we could ask tglx to add an extra patch to the existing
queue in order to clean up pci-xgene.c (nuking the whole
xgene_pcie_msi_enable function).

Thoughts?

	M.
-- 
Jazz is not dead. It just smells funny...


From linux at arm.linux.org.uk  Thu Aug  6 08:26:54 2015
From: linux at arm.linux.org.uk (Russell King - ARM Linux)
Date: Thu, 6 Aug 2015 16:26:54 +0100
Subject: IRQ setup on multicore systems (routing, balancing, etc)
In-Reply-To: <55C37A72.2090507@free.fr>
References: <55C0C102.7050600@free.fr>
 <55C37A72.2090507@free.fr>
Message-ID: <20150806152654.GF7557@n2100.arm.linux.org.uk>

On Thu, Aug 06, 2015 at 05:17:06PM +0200, Mason wrote:
> On 04/08/2015 15:41, Mason wrote:
> 
> > I have a few very naive questions about [snip]
> 
> [META]
> 
> Are there perhaps more suitable mailing lists than this one
> for such beginner questions?

I thought your message yesterday indicated you'd found the answer.

You don't setup any kind of routing between CPU cores and devices.
At boot, initially CPU 0 will "own" all interrupts.

You then run a (fixed) version of irqbalanced (preferably the older
version which is not so x86-centric, eg, 0.56) which then distributes
the interrupts between the cores according to what the interrupt is
used for and the load it is imposing on the system.

-- 
FTTC broadband for 0.8mile line: currently at 10.5Mbps down 400kbps up
according to speedtest.net.


From maitysanchayan at gmail.com  Thu Aug  6 08:27:27 2015
From: maitysanchayan at gmail.com (Sanchayan Maity)
Date: Thu,  6 Aug 2015 20:57:27 +0530
Subject: [PATCH v7 1/4] clk: clk-vf610: Add clock for Vybrid OCOTP controller
In-Reply-To: <cover.1438874125.git.maitysanchayan@gmail.com>
References: <cover.1438874125.git.maitysanchayan@gmail.com>
Message-ID: <fe5ec67cc9d29d28eec9da442140b614ca8fecd7.1438874125.git.maitysanchayan@gmail.com>

Add clock support for Vybrid On-Chip One Time Programmable
(OCOTP) controller.

While the OCOTP block does not require explicit clock gating,
for programming the OCOTP timing register the clock rate of
ipg clock is required for timing calculations related to fuse
and shadow register read sequence. We explicitly specify the
ipg clock for OCOTP as a result.

Signed-off-by: Sanchayan Maity <maitysanchayan at gmail.com>
---
 drivers/clk/imx/clk-vf610.c             | 1 +
 include/dt-bindings/clock/vf610-clock.h | 3 ++-
 2 files changed, 3 insertions(+), 1 deletion(-)

diff --git a/drivers/clk/imx/clk-vf610.c b/drivers/clk/imx/clk-vf610.c
index bff45ea..d1b1c95 100644
--- a/drivers/clk/imx/clk-vf610.c
+++ b/drivers/clk/imx/clk-vf610.c
@@ -387,6 +387,7 @@ static void __init vf610_clocks_init(struct device_node *ccm_node)
 
 	clk[VF610_CLK_SNVS] = imx_clk_gate2("snvs-rtc", "ipg_bus", CCM_CCGR6, CCM_CCGRx_CGn(7));
 	clk[VF610_CLK_DAP] = imx_clk_gate("dap", "platform_bus", CCM_CCSR, 24);
+	clk[VF610_CLK_OCOTP] = imx_clk_gate("ocotp", "ipg_bus", CCM_CCGR6, CCM_CCGRx_CGn(5));
 
 	imx_check_clocks(clk, ARRAY_SIZE(clk));
 
diff --git a/include/dt-bindings/clock/vf610-clock.h b/include/dt-bindings/clock/vf610-clock.h
index d197634..56c16aa 100644
--- a/include/dt-bindings/clock/vf610-clock.h
+++ b/include/dt-bindings/clock/vf610-clock.h
@@ -194,6 +194,7 @@
 #define VF610_PLL7_BYPASS		181
 #define VF610_CLK_SNVS			182
 #define VF610_CLK_DAP			183
-#define VF610_CLK_END			184
+#define VF610_CLK_OCOTP         184
+#define VF610_CLK_END			185
 
 #endif /* __DT_BINDINGS_CLOCK_VF610_H */
-- 
2.5.0



From maitysanchayan at gmail.com  Thu Aug  6 08:27:26 2015
From: maitysanchayan at gmail.com (Sanchayan Maity)
Date: Thu,  6 Aug 2015 20:57:26 +0530
Subject: [PATCH v7 0/4] Implement OCOTP driver for Vybrid using NVMEM
Message-ID: <cover.1438874125.git.maitysanchayan@gmail.com>

Hello,

This patchset is based on top of v9 of Srinivas's NVMEM framework patches.

Sample output on Colibri VF61

root at colibri-vf:/sys/bus/nvmem/devices/ocotp0# hexdump nvmem
0000000 0000 0000 0000 0000 0000 0000 0000 0000
*
0000410 72a6 df64 0000 0000 0000 0000 0000 0000
0000420 39d4 2807 0000 0000 0000 0000 0000 0000
0000430 0000 0000 0000 0000 0000 0000 0000 0000
*
0000450 0280 0000 0000 0000 0000 0000 0000 0000
0000460 0000 0000 0000 0000 0000 0000 0000 0000
*
0000880 8f01 0000 0000 0000 0000 0000 0000 0000
0000890 0000 0000 0000 0000 0000 0000 0000 0000
*
00008c0 0000 1500 0000 0000 0000 0000 0000 0000
00008d0 330d 0800 0000 0000 0000 0000 0000 0000
00008e0 0000 e100 0000 0000 0000 0000 0000 0000
00008f0 0000 0000 0000 0000 0000 0000 0000 0000
*
0000c80 bada bada 0000 0000 0000 0000 0000 0000
*
0000cc0 0000 0000 0000 0000 0000 0000 0000 0000
*
0000cf0

The driver has changed quite a bit from the first version
relying on of_platform_populate in mach file, to using
SoC driver under drivers/soc and finally to NVMEM.

Feedback and comments most welcome.

Version 6 RFC patches can be found here
http://lkml.iu.edu/hypermail/linux/kernel/1506.2/05123.html

Version 5 of the patchset can be found here
http://lkml.iu.edu/hypermail/linux/kernel/1506.0/03787.html

Version 4 of the patchset can be found here
https://lkml.org/lkml/2015/5/26/199

Version 3 of the patchset can be found here
http://www.spinics.net/lists/arm-kernel/msg420847.html

Version 2 of the patchset can be found here
http://www.spinics.net/lists/devicetree/msg80654.html

Version 1 of the patchset can be found here
http://www.spinics.net/lists/devicetree/msg80257.html

The RFC version can be found here
https://lkml.org/lkml/2015/5/11/13

Changes since v6:
1. Use the v9 of NVMEM framework patchset
2. Add a few comments
3. Initialise buffer address not part of the fuse map to 0
instead of only handling buffer locations with valid fuse
addresses.

Changes since v5:
Use NVMEM framework by Srinivas and Maxime

Changes since v4:
1. Use devm_* family of functions and use a struct to get rid of
global variables (suggested by Joachim Eastwood)
2. Make Kconfig govern the compilation with tristate, instead of
earlier bool. Paul Bolle raised a valid point that perhaps this
should have been built in with the bool, however I had not taken
into consideration generic distro kernels and it makes sense to
have this tristated. (comments from Paul Bolle and Andreas Farber)

Changes since v3:
Instead of using the syscon_regmap_lookup_by_compatible function
use a phandle in the device tree along with offsets specified in
this phandle node and then read the offset along with the device
node in the driver for reading from the required region.

Changes since v2:
Implement the SoC bus code as a driver in drivers/soc
by registering with fsl,mscm-cpucfg as per Arnd's feedback

Changes since v1:
Sort the headers in alphabetical order

Changes since RFC:
Use a DT entry for the ROM area while specifying it as syscon.

Thanks & Regards,
Sanchayan Maity.

Sanchayan Maity (4):
  clk: clk-vf610: Add clock for Vybrid OCOTP controller
  ARM: dts: vfxxx: Add OCOTP node
  drivers: nvmem: Add Vybrid OCOTP support
  nvmem: Add DT binding documentation for Vybrid OCOTP driver

 .../devicetree/bindings/nvmem/vf610-ocotp.txt      |  20 ++
 arch/arm/boot/dts/vfxxx.dtsi                       |   9 +
 drivers/clk/imx/clk-vf610.c                        |   1 +
 drivers/nvmem/Kconfig                              |  10 +
 drivers/nvmem/Makefile                             |   2 +
 drivers/nvmem/vf610-ocotp.c                        | 297 +++++++++++++++++++++
 include/dt-bindings/clock/vf610-clock.h            |   3 +-
 7 files changed, 341 insertions(+), 1 deletion(-)
 create mode 100644 Documentation/devicetree/bindings/nvmem/vf610-ocotp.txt
 create mode 100644 drivers/nvmem/vf610-ocotp.c

-- 
2.5.0



From maitysanchayan at gmail.com  Thu Aug  6 08:27:28 2015
From: maitysanchayan at gmail.com (Sanchayan Maity)
Date: Thu,  6 Aug 2015 20:57:28 +0530
Subject: [PATCH v7 2/4] ARM: dts: vfxxx: Add OCOTP node
In-Reply-To: <cover.1438874125.git.maitysanchayan@gmail.com>
References: <cover.1438874125.git.maitysanchayan@gmail.com>
Message-ID: <bbd98bd3dc49a8fc4a7b23bcd8208d6ee687add2.1438874125.git.maitysanchayan@gmail.com>

Add device tree node for the On-Chip One Time Programmable
controller (OCOTP) on the Vybrid platform.

Signed-off-by: Sanchayan Maity <maitysanchayan at gmail.com>
---
 arch/arm/boot/dts/vfxxx.dtsi | 9 +++++++++
 1 file changed, 9 insertions(+)

diff --git a/arch/arm/boot/dts/vfxxx.dtsi b/arch/arm/boot/dts/vfxxx.dtsi
index 39173bb..4d40657 100644
--- a/arch/arm/boot/dts/vfxxx.dtsi
+++ b/arch/arm/boot/dts/vfxxx.dtsi
@@ -419,6 +419,15 @@
 				status = "disabled";
 			};
 
+			ocotp: ocotp at 400a5000 {
+				compatible = "fsl,vf610-ocotp";
+				#address-cells = <1>;
+				#size-cells = <1>;
+				reg = <0x400a5000 0xD00>;
+				clocks = <&clks VF610_CLK_OCOTP>;
+				clock-names = "ocotp";
+			};
+
 			snvs0: snvs at 400a7000 {
 			    compatible = "fsl,sec-v4.0-mon", "syscon", "simple-mfd";
 				reg = <0x400a7000 0x2000>;
-- 
2.5.0



From maitysanchayan at gmail.com  Thu Aug  6 08:27:29 2015
From: maitysanchayan at gmail.com (Sanchayan Maity)
Date: Thu,  6 Aug 2015 20:57:29 +0530
Subject: [PATCH v7 3/4] drivers: nvmem: Add Vybrid OCOTP support
In-Reply-To: <cover.1438874125.git.maitysanchayan@gmail.com>
References: <cover.1438874125.git.maitysanchayan@gmail.com>
Message-ID: <3c92671bfca0344e4b43edd2a2405c09bf95f330.1438874125.git.maitysanchayan@gmail.com>

The patch adds support for the On Chip One Time Programmable Peripheral
(OCOTP) on the Vybrid platform.

Signed-off-by: Sanchayan Maity <maitysanchayan at gmail.com>
---
 drivers/nvmem/Kconfig       |  10 ++
 drivers/nvmem/Makefile      |   2 +
 drivers/nvmem/vf610-ocotp.c | 297 ++++++++++++++++++++++++++++++++++++++++++++
 3 files changed, 309 insertions(+)
 create mode 100644 drivers/nvmem/vf610-ocotp.c

diff --git a/drivers/nvmem/Kconfig b/drivers/nvmem/Kconfig
index 0b33014..bfd0c02 100644
--- a/drivers/nvmem/Kconfig
+++ b/drivers/nvmem/Kconfig
@@ -47,4 +47,14 @@ config NVMEM_IMX_OCOTP
 	  This driver can also be built as a module. If so, the module
 	  will be called nvmem-imx-ocotp.
 
+config NVMEM_VF610_OCOTP
+	tristate "VF610_SoCs OCOTP support"
+	depends on SOC_VF610
+	help
+	  This is a driver for the 'OCOTP' peripheral available on Vybrid
+	  devices like VF5xx and VF6xx.
+
+	  This driver can also be built as a module. If so, the module will
+	  be called nvmem-vf610-ocotp.
+
 endif
diff --git a/drivers/nvmem/Makefile b/drivers/nvmem/Makefile
index b512d77..8a1eea8 100644
--- a/drivers/nvmem/Makefile
+++ b/drivers/nvmem/Makefile
@@ -12,3 +12,5 @@ obj-$(CONFIG_NVMEM_SUNXI_SID)	+= nvmem_sunxi_sid.o
 nvmem_sunxi_sid-y		:= sunxi_sid.o
 obj-$(CONFIG_NVMEM_IMX_OCOTP)	+= nvmem-imx-ocotp.o
 nvmem-imx-ocotp-y		:= imx-ocotp.o
+obj-$(CONFIG_NVMEM_VF610_OCOTP)	+= nvmem-vf610-ocotp.o
+nvmem-vf610-ocotp-y		:= vf610-ocotp.o
diff --git a/drivers/nvmem/vf610-ocotp.c b/drivers/nvmem/vf610-ocotp.c
new file mode 100644
index 0000000..25ee701
--- /dev/null
+++ b/drivers/nvmem/vf610-ocotp.c
@@ -0,0 +1,297 @@
+/*
+ * Copyright (C) 2015 Toradex AG.
+ *
+ * Author: Sanchayan Maity <sanchayan.maity at toradex.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 and
+ * only 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/clk.h>
+#include <linux/delay.h>
+#include <linux/device.h>
+#include <linux/io.h>
+#include <linux/module.h>
+#include <linux/nvmem-provider.h>
+#include <linux/of.h>
+#include <linux/platform_device.h>
+#include <linux/regmap.h>
+#include <linux/slab.h>
+
+/* OCOTP Register Offsets */
+#define OCOTP_CTRL_REG				0x00
+#define OCOTP_CTRL_SET				0x04
+#define OCOTP_CTRL_CLR				0x08
+#define OCOTP_TIMING				0x10
+#define OCOTP_DATA				0x20
+#define OCOTP_READ_CTRL_REG			0x30
+#define OCOTP_READ_FUSE_DATA			0x40
+
+/* OCOTP Register bits and masks */
+#define OCOTP_CTRL_WR_UNLOCK			16
+#define OCOTP_CTRL_WR_UNLOCK_KEY		0x3E77
+#define OCOTP_CTRL_WR_UNLOCK_MASK		0xFFFF0000
+#define OCOTP_CTRL_ADDR				0
+#define OCOTP_CTRL_ADDR_MASK			0x7F
+#define OCOTP_CTRL_RELOAD_SHADOWS		(0x1 << 10)
+#define OCOTP_CTRL_ERROR			(0x1 << 9)
+#define OCOTP_CTRL_BUSY				(0x1 << 8)
+
+#define OCOTP_TIMING_STROBE_READ		16
+#define OCOTP_TIMING_STROBE_READ_MASK		0x003F0000
+#define OCOTP_TIMING_RELAX			12
+#define OCOTP_TIMING_RELAX_MASK			0x0000F000
+#define OCOTP_TIMING_STROBE_PROG		0
+#define OCOTP_TIMING_STROBE_PROG_MASK		0x00000FFF
+
+#define OCOTP_READ_CTRL_READ_FUSE		0x1
+
+#define VF610_OCOTP_TIMEOUT			100000
+
+#define BF(value, field)		(((value) << field) & field##_MASK)
+
+#define DEF_RELAX				20
+
+static const int base_to_fuse_addr_mappings[][2] = {
+	{0x400, 0x00},
+	{0x410, 0x01},
+	{0x420, 0x02},
+	{0x450, 0x05},
+	{0x4F0, 0x0F},
+	{0x600, 0x20},
+	{0x610, 0x21},
+	{0x620, 0x22},
+	{0x630, 0x23},
+	{0x640, 0x24},
+	{0x650, 0x25},
+	{0x660, 0x26},
+	{0x670, 0x27},
+	{0x6F0, 0x2F},
+	{0x880, 0x38},
+	{0x890, 0x39},
+	{0x8A0, 0x3A},
+	{0x8B0, 0x3B},
+	{0x8C0, 0x3C},
+	{0x8D0, 0x3D},
+	{0x8E0, 0x3E},
+	{0x8F0, 0x3F},
+	{0xC80, 0x78},
+	{0xC90, 0x79},
+	{0xCA0, 0x7A},
+	{0xCB0, 0x7B},
+	{0xCC0, 0x7C},
+	{0xCD0, 0x7D},
+	{0xCE0, 0x7E},
+	{0xCF0, 0x7F},
+};
+
+struct vf610_ocotp {
+	void __iomem *base;
+	struct clk *clk;
+	struct device *dev;
+	struct nvmem_device *nvmem;
+	int timing;
+};
+
+static int vf610_ocotp_wait_busy(void __iomem *base)
+{
+	int timeout = VF610_OCOTP_TIMEOUT;
+
+	while ((readl(base) & OCOTP_CTRL_BUSY) && --timeout)
+		udelay(10);
+
+	if (!timeout) {
+		writel(OCOTP_CTRL_ERROR, base + OCOTP_CTRL_CLR);
+		return -ETIMEDOUT;
+	}
+
+	udelay(10);
+
+	return 0;
+}
+
+static int vf610_ocotp_calculate_timing(struct vf610_ocotp *ocotp_dev)
+{
+	u32 clk_rate;
+	u32 relax, strobe_read, strobe_prog;
+	u32 timing;
+
+	clk_rate = clk_get_rate(ocotp_dev->clk);
+
+	/* Refer section OTP read/write timing parameters in TRM */
+	relax = clk_rate / (1000000000 / DEF_RELAX) - 1;
+	strobe_prog = clk_rate / (1000000000 / 10000) + 2 * (DEF_RELAX + 1) - 1;
+	strobe_read = clk_rate / (1000000000 / 40) + 2 * (DEF_RELAX + 1) - 1;
+
+	timing = BF(relax, OCOTP_TIMING_RELAX);
+	timing |= BF(strobe_read, OCOTP_TIMING_STROBE_READ);
+	timing |= BF(strobe_prog, OCOTP_TIMING_STROBE_PROG);
+
+	return timing;
+}
+
+static int vf610_get_fuse_address(int base_addr_offset)
+{
+	int i;
+
+	for (i = 0; i < ARRAY_SIZE(base_to_fuse_addr_mappings); i++) {
+		if (base_to_fuse_addr_mappings[i][0] == base_addr_offset)
+			return base_to_fuse_addr_mappings[i][1];
+	}
+
+	return -EINVAL;
+}
+
+static int vf610_ocotp_write(void *context, const void *data, size_t count)
+{
+	return 0;
+}
+
+static int vf610_ocotp_read(void *context,
+					const void *off, size_t reg_size,
+					void *val, size_t val_size)
+{
+	struct vf610_ocotp *ocotp = context;
+	unsigned int offset = *(u32 *)off;
+	u32 reg, *buf = val;
+	int fuse_addr;
+	int ret;
+
+	while (val_size > 0) {
+		fuse_addr = vf610_get_fuse_address(offset);
+		if (fuse_addr > 0) {
+			writel(ocotp->timing, ocotp->base + OCOTP_TIMING);
+			ret = vf610_ocotp_wait_busy(ocotp->base + OCOTP_CTRL_REG);
+			if (ret)
+				return ret;
+
+			reg = readl(ocotp->base + OCOTP_CTRL_REG);
+			reg &= ~OCOTP_CTRL_ADDR_MASK;
+			reg &= ~OCOTP_CTRL_WR_UNLOCK_MASK;
+			reg |= BF(fuse_addr, OCOTP_CTRL_ADDR);
+			writel(reg, ocotp->base + OCOTP_CTRL_REG);
+
+			writel(OCOTP_READ_CTRL_READ_FUSE,
+				ocotp->base + OCOTP_READ_CTRL_REG);
+			ret = vf610_ocotp_wait_busy(ocotp->base + OCOTP_CTRL_REG);
+			if (ret)
+				return ret;
+
+			if (readl(ocotp->base) & OCOTP_CTRL_ERROR) {
+				dev_dbg(ocotp->dev, "Error reading from fuse address %x\n",
+					fuse_addr);
+				writel(OCOTP_CTRL_ERROR, ocotp->base + OCOTP_CTRL_CLR);
+			}
+
+			/*
+			 * In case of error, we do not abort and expect to read
+			 * 0xBADABADA as mentioned by the TRM. We just read this
+			 * value and return.
+			 */
+			*buf = readl(ocotp->base + OCOTP_READ_FUSE_DATA);
+		} else {
+			*buf = 0;
+		}
+
+		buf++;
+		val_size--;
+		offset += reg_size;
+	}
+
+	return 0;
+}
+
+static struct regmap_bus vf610_ocotp_bus = {
+	.read = vf610_ocotp_read,
+	.write = vf610_ocotp_write,
+	.reg_format_endian_default = REGMAP_ENDIAN_NATIVE,
+	.val_format_endian_default = REGMAP_ENDIAN_NATIVE,
+};
+
+static struct regmap_config ocotp_regmap_config = {
+	.reg_bits = 32,
+	.val_bits = 32,
+	.reg_stride = 4,
+	.max_register = 0xCF0,
+};
+
+static struct nvmem_config ocotp_config = {
+	.name = "ocotp",
+	.owner = THIS_MODULE,
+};
+
+static const struct of_device_id ocotp_of_match[] = {
+	{ .compatible = "fsl,vf610-ocotp", },
+	{/* sentinel */},
+};
+MODULE_DEVICE_TABLE(of, ocotp_of_match);
+
+static int vf610_ocotp_remove(struct platform_device *pdev)
+{
+	struct vf610_ocotp *ocotp_dev = platform_get_drvdata(pdev);
+
+	return nvmem_unregister(ocotp_dev->nvmem);
+}
+
+static int vf610_ocotp_probe(struct platform_device *pdev)
+{
+	struct device *dev = &pdev->dev;
+	struct resource *res;
+	struct regmap *regmap;
+	struct vf610_ocotp *ocotp_dev;
+
+	ocotp_dev = devm_kzalloc(&pdev->dev,
+			sizeof(struct vf610_ocotp), GFP_KERNEL);
+	if (!ocotp_dev)
+		return -ENOMEM;
+
+	res = platform_get_resource(pdev, IORESOURCE_MEM, 0);
+	ocotp_dev->base = devm_ioremap_resource(dev, res);
+	if (IS_ERR(ocotp_dev->base))
+		return PTR_ERR(ocotp_dev->base);
+
+	ocotp_dev->clk = devm_clk_get(dev, "ocotp");
+	if (IS_ERR(ocotp_dev->clk)) {
+		dev_err(dev, "failed getting clock, err = %ld\n",
+			PTR_ERR(ocotp_dev->clk));
+		return PTR_ERR(ocotp_dev->clk);
+	}
+
+	regmap = devm_regmap_init(dev,
+		&vf610_ocotp_bus, ocotp_dev, &ocotp_regmap_config);
+	if (IS_ERR(regmap)) {
+		dev_err(dev, "regmap init failed\n");
+		return PTR_ERR(regmap);
+	}
+	ocotp_config.dev = dev;
+
+	ocotp_dev->nvmem = nvmem_register(&ocotp_config);
+	if (IS_ERR(ocotp_dev->nvmem))
+		return PTR_ERR(ocotp_dev->nvmem);
+
+	ocotp_dev->dev = dev;
+	platform_set_drvdata(pdev, ocotp_dev);
+
+	ocotp_dev->timing = vf610_ocotp_calculate_timing(ocotp_dev);
+
+	return 0;
+}
+
+static struct platform_driver vf610_ocotp_driver = {
+	.probe = vf610_ocotp_probe,
+	.remove = vf610_ocotp_remove,
+	.driver = {
+		.name = "vf610-ocotp",
+		.of_match_table = ocotp_of_match,
+	},
+};
+module_platform_driver(vf610_ocotp_driver);
+MODULE_AUTHOR("Sanchayan Maity <sanchayan.maity at toradex.com>");
+MODULE_DESCRIPTION("Vybrid OCOTP driver");
+MODULE_LICENSE("GPL v2");
-- 
2.5.0



From maitysanchayan at gmail.com  Thu Aug  6 08:27:30 2015
From: maitysanchayan at gmail.com (Sanchayan Maity)
Date: Thu,  6 Aug 2015 20:57:30 +0530
Subject: [PATCH v7 4/4] nvmem: Add DT binding documentation for Vybrid OCOTP
 driver
In-Reply-To: <cover.1438874125.git.maitysanchayan@gmail.com>
References: <cover.1438874125.git.maitysanchayan@gmail.com>
Message-ID: <3713643bb44c39c2126edca2916e1c1aa43eabf8.1438874125.git.maitysanchayan@gmail.com>

Add the devicetree bindings for the Freescale Vybrid On-Chip
OTP driver.

Signed-off-by: Sanchayan Maity <maitysanchayan at gmail.com>
---
 .../devicetree/bindings/nvmem/vf610-ocotp.txt        | 20 ++++++++++++++++++++
 1 file changed, 20 insertions(+)
 create mode 100644 Documentation/devicetree/bindings/nvmem/vf610-ocotp.txt

diff --git a/Documentation/devicetree/bindings/nvmem/vf610-ocotp.txt b/Documentation/devicetree/bindings/nvmem/vf610-ocotp.txt
new file mode 100644
index 0000000..5556810
--- /dev/null
+++ b/Documentation/devicetree/bindings/nvmem/vf610-ocotp.txt
@@ -0,0 +1,20 @@
+On-Chip OTP Memory for Freescale Vybrid
+
+Required Properties:
+  compatible:
+  - "fsl,vf610-ocotp" for VF5xx/VF6xx
+  #address-cells : Should be 1
+  #size-cells : Should be 1
+  reg : Address and length of OTP controller registers
+
+Example for Vybrid VF5xx/VF6xx:
+
+	ocotp: ocotp at 400a5000 {
+		compatible = "fsl,vf610-ocotp";
+		#address-cells = <1>;
+		#size-cells = <1>;
+		reg = <0x400a5000 0xD00>;
+		clocks = <&clks VF610_CLK_OCOTP>;
+		clock-names = "ocotp";
+	};
+
-- 
2.5.0



From julien.grall at citrix.com  Thu Aug  6 08:43:15 2015
From: julien.grall at citrix.com (Julien Grall)
Date: Thu, 6 Aug 2015 16:43:15 +0100
Subject: [Xen-devel] [PATCH v2 13/20] xen/events: fifo: Make it running
 on 64KB granularity
In-Reply-To: <55B21527.4010601@citrix.com>
References: <1436474552-31789-1-git-send-email-julien.grall@citrix.com>
 <1436474552-31789-14-git-send-email-julien.grall@citrix.com>
 <55B21527.4010601@citrix.com>
Message-ID: <55C38093.8080609@citrix.com>

Hi David,

On 24/07/15 11:36, David Vrabel wrote:
> On 09/07/15 21:42, Julien Grall wrote:
>> Only use the first 4KB of the page to store the events channel info. It
>> means that we will wast 60KB every time we allocate page for:
>>      * control block: a page is allocating per CPU
>>      * event array: a page is allocating everytime we need to expand it
> 
> Reviewed-by: David Vrabel <david.vrabel at citrix.com>

Thank you!

>>
>> I think we can reduce the memory waste for the 2 areas by:
>>
>>     * control block: sharing between multiple vCPUs. Although it will
>>     require some bookkeeping in order to not free the page when the CPU
>>     goes offline and the other CPUs sharing the page still there
>>
>>     * event array: always extend the array event by 64K (i.e 16 4K
>>     chunk). That would require more care when we fail to expand the
>>     event channel.
> 
> I would extend it by 4 KiB each time but only allocate a new page every
> 16 times.  This minimizes the resources used in Xen.

I will keep it in mind when I will send a patch to reduce memory waster.

Regards,

-- 
Julien Grall


From marc.zyngier at arm.com  Thu Aug  6 08:51:05 2015
From: marc.zyngier at arm.com (Marc Zyngier)
Date: Thu, 06 Aug 2015 16:51:05 +0100
Subject: [v2 2/5] arm64: kdump: implement machine_crash_shutdown()
In-Reply-To: <55C3083D.1000306@linaro.org>
References: <1429861989-8417-1-git-send-email-takahiro.akashi@linaro.org>
 <1429861989-8417-3-git-send-email-takahiro.akashi@linaro.org>
 <20150424103900.GF29183@leverpostej> <553A1E62.9030400@arm.com>
 <55C3083D.1000306@linaro.org>
Message-ID: <55C38269.8090907@arm.com>

Hi,

On 06/08/15 08:09, AKASHI Takahiro wrote:
> Marc, Mark
> 
> Sorry for not revisiting your comment below for a while.

Wow. It took me a few minutes to page the context back in.

> On 04/24/2015 07:43 PM, Marc Zyngier wrote:
>> On 24/04/15 11:39, Mark Rutland wrote:
>>> On Fri, Apr 24, 2015 at 08:53:05AM +0100, AKASHI Takahiro wrote:
>>>> kdump calls machine_crash_shutdown() to shut down non-boot cpus and
>>>> save per-cpu general-purpose registers before restarting the crash dump
>>>> kernel. See kernel_kexec().
>>>> ipi_cpu_stop() is used and a bit modified to support this behavior.
>>>>
>>>> Signed-off-by: AKASHI Takahiro <takahiro.akashi at linaro.org>
>>>> ---
>>>>   arch/arm64/include/asm/kexec.h    |   34 ++++++++++++++++++++++-
>>>>   arch/arm64/kernel/machine_kexec.c |   55 ++++++++++++++++++++++++++++++++++++-
>>>>   arch/arm64/kernel/smp.c           |   12 ++++++--
>>>>   3 files changed, 97 insertions(+), 4 deletions(-)
>>>>
>>>> diff --git a/arch/arm64/include/asm/kexec.h b/arch/arm64/include/asm/kexec.h
>>>> index 3530ff5..eaf3fcb 100644
>>>> --- a/arch/arm64/include/asm/kexec.h
>>>> +++ b/arch/arm64/include/asm/kexec.h
>>>> @@ -30,6 +30,8 @@
>>>>
>>>>   #if !defined(__ASSEMBLY__)
>>>>
>>>> +extern bool in_crash_kexec;
>>>> +
>>>>   /**
>>>>    * crash_setup_regs() - save registers for the panic kernel
>>>>    *
>>>> @@ -40,7 +42,37 @@
>>>>   static inline void crash_setup_regs(struct pt_regs *newregs,
>>>>   				    struct pt_regs *oldregs)
>>>>   {
>>>> -	/* Empty routine needed to avoid build errors. */
>>>> +	if (oldregs) {
>>>> +		memcpy(newregs, oldregs, sizeof(*newregs));
>>>> +	} else {
>>>> +		__asm__ __volatile__ (
>>>> +			"stp	 x0,   x1, [%3]\n\t"
>>>
>>> Why the tabs?
>>>
>>> Please use #16 * N as the offset for consistency with entry.S, with 0
>>> for the first N.
>>>
>>> [...]
>>>
>>>> +static void machine_kexec_mask_interrupts(void)
>>>> +{
>>>> +	unsigned int i;
>>>> +	struct irq_desc *desc;
>>>> +
>>>> +	for_each_irq_desc(i, desc) {
>>>> +		struct irq_chip *chip;
>>>> +
>>>> +		chip = irq_desc_get_chip(desc);
>>>> +		if (!chip)
>>>> +			continue;
>>>> +
>>>> +		if (chip->irq_eoi && irqd_irq_inprogress(&desc->irq_data))
>>>> +			chip->irq_eoi(&desc->irq_data);
>>>> +
>>>> +		if (chip->irq_mask)
>>>> +			chip->irq_mask(&desc->irq_data);
>>>> +
>>>> +		if (chip->irq_disable && !irqd_irq_disabled(&desc->irq_data))
>>>> +			chip->irq_disable(&desc->irq_data);
>>>> +	}
>>>> +}
>>>
>>> I'm surprised that this isn't left to the irqchip driver init code in
>>> the crash kernel. For all we know this state could be corrupt anyway.
>>
>> Indeed, parsing the irqdesc list is a recipe for disaster. Who knows
>> which locks have been taken or simply corrupted, pointers nuked...
>>
>>> Is there any reason we can't get the GIC driver to nuke all of this at
>>> probe time?
> 
> Is it just enough to remove kexec_mask_interrupts() and add gic_eoi_irq()
> at the beginning of gic_cpu_init() in irq-gic.c and irq-gic-v3.c?

No, doing an EOI is definitely the wrong thing to do. If you do it in
the wrong order, you just screw up the GIC state machine. Plus, you have
no idea what to write there...

The only real solution is to zero the "active" registers.

>> This feels like the better option. I can cook a patch or two for that.
> 
> If you do, that will be much better :)

OK, I'll prepare something that we can merge at the same time kexec
comes back from the dead (if it ever does - I'm not holding my breath).

> 
> BTW, in arm-gic-v3.h, GICD_CTRL_ARE_NS is defined as
>      (1U << 4)
> but should it be 5?
> (I'm referring to the page 8-415 in IHI0069A.)

No, look at the definition ARE_NS has when the access is non-secure or
on a system supporting a single security state. The definition you're
referring to is for a secure access (firmware).

Thanks,

	M.
-- 
Jazz is not dead. It just smells funny...


From nm at ti.com  Thu Aug  6 08:54:24 2015
From: nm at ti.com (Nishanth Menon)
Date: Thu, 6 Aug 2015 10:54:24 -0500
Subject: [PATCH] ARM: OMAP5 / DRA7: Introduce workaround for 801819
Message-ID: <1438876464-15424-1-git-send-email-nm@ti.com>

Add workaround for Cortex-A15 ARM erratum 801819 which says in summary
that "A livelock can occur in the L2 cache arbitration that might
prevent a snoop from completing. Under certain conditions this can
cause the system to deadlock. "

Recommended workaround is as follows:
Do both of the following:

1) Do not use the write-back no-allocate memory type.
2) Do not issue write-back cacheable stores at any time when the cache
is disabled (SCTLR.C=0) and the MMU is enabled (SCTLR.M=1). Because it
is implementation defined whether cacheable stores update the cache when
the cache is disabled it is not expected that any portable code will
execute cacheable stores when the cache is disabled.

For implementations of Cortex-A15 configured without the ?L2 arbitration
register slice? option (typically one or two core systems), you must
also do the following:

3) Disable write-streaming in each CPU by setting ACTLR[28:25] = 0b1111

So, we provide an option to disable write streaming on OMAP5 and DRA7.
It is a rare condition to occur and may be enabled selectively based
on platform acceptance of risk.

Applies to: A15 revisions r2p0, r2p1, r2p2, r2p3 or r2p4 and REVIDR[3]
is set to 0.

Based on ARM errata Document revision 18.0 (22 Nov 2013)

Note: the configuration for the workaround needs to be done with
each CPU bringup, since CPU0 bringup is done by bootloader, it is
recommended to have the workaround in the bootloader, kernel also does
ensure that CPU0 has the workaround and makes the workaround active
when CPU1 gets active.

With CONFIG_SMP disabled, it is expected to be done by the bootloader.

This does show significant degradation in synthetic tests such as
mbw (https://packages.qa.debian.org/m/mbw.html)
mbw -n 100 100|grep AVG (on a test platform)
Without enabling the erratum:
AVG Method: MEMCPY  Elapsed: 0.13406  MiB: 100.00000  Copy: 745.913 MiB/s
AVG Method: DUMB    Elapsed: 0.06746  MiB: 100.00000  Copy: 1482.357 MiB/s
AVG Method: MCBLOCK Elapsed: 0.03058  MiB: 100.00000  Copy: 3270.569 MiB/s
After enabling the erratum:
AVG Method: MEMCPY  Elapsed: 0.13757  MiB: 100.00000  Copy: 726.913 MiB/s
AVG Method: DUMB    Elapsed: 0.12024  MiB: 100.00000  Copy: 831.668 MiB/s
AVG Method: MCBLOCK Elapsed: 0.09243  MiB: 100.00000  Copy: 1081.942 MiB/s

Most benchmarks are designed for specific performance analysis, so
overall usecase must be considered before making a decision to
enable/disable the erratum workaround.

Pending internal investigation, the erratum is kept disabled by default.

Cc: Russell King <rmk+kernel at arm.linux.org.uk>
Cc: Catalin Marinas <catalin.marinas at arm.com>
Cc: Tony Lindgren <tony at atomide.com>
Suggested-by: Richard Woodruff <r-woodruff2 at ti.com>
Suggested-by: Brad Griffis <bgriffis at ti.com>
Signed-off-by: Nishanth Menon <nm at ti.com>
---

Since this is a generic ARM erratum with potentially other SoCs
benefitting from a workaround.. the only problem with a generic
workaround, as far as I can see if the SoC specific smc based acr
modification. It will be great to get some direction in this front.

Also note:

We did notice that this erratum was discussed earlier [1] however,
with internal evaluation, it was summarized that this does impact our
SoCs.


[1] https://lists.linaro.org/pipermail/linaro-kernel/2013-June/004687.html
 arch/arm/mach-omap2/Kconfig       |  8 +++++++
 arch/arm/mach-omap2/omap-secure.h |  1 +
 arch/arm/mach-omap2/omap-smp.c    | 48 +++++++++++++++++++++++++++++++++++----
 3 files changed, 52 insertions(+), 5 deletions(-)

diff --git a/arch/arm/mach-omap2/Kconfig b/arch/arm/mach-omap2/Kconfig
index 4a023e8d1bdb..b62835562ff0 100644
--- a/arch/arm/mach-omap2/Kconfig
+++ b/arch/arm/mach-omap2/Kconfig
@@ -245,4 +245,12 @@ endmenu
 
 endif
 
+config OMAP5_ERRATA_801819
+	bool "Errata 801819: An eviction from L1 data cache might stall indefinitely"
+	depends on SOC_OMAP5 || SOC_DRA7XX
+	help
+	  A livelock can occur in the L2 cache arbitration that might prevent
+	  a snoop from completing. Under certain conditions this can cause the
+	  system to deadlock.
+
 endmenu
diff --git a/arch/arm/mach-omap2/omap-secure.h b/arch/arm/mach-omap2/omap-secure.h
index af2851fbcdf0..bae263fba640 100644
--- a/arch/arm/mach-omap2/omap-secure.h
+++ b/arch/arm/mach-omap2/omap-secure.h
@@ -46,6 +46,7 @@
 
 #define OMAP5_DRA7_MON_SET_CNTFRQ_INDEX	0x109
 #define OMAP5_MON_AMBA_IF_INDEX		0x108
+#define OMAP5_DRA7_MON_SET_ACR_INDEX	0x107
 
 /* Secure PPA(Primary Protected Application) APIs */
 #define OMAP4_PPA_L2_POR_INDEX		0x23
diff --git a/arch/arm/mach-omap2/omap-smp.c b/arch/arm/mach-omap2/omap-smp.c
index 5305ec7341ec..faaf366c220e 100644
--- a/arch/arm/mach-omap2/omap-smp.c
+++ b/arch/arm/mach-omap2/omap-smp.c
@@ -50,6 +50,39 @@ void __iomem *omap4_get_scu_base(void)
 	return scu_base;
 }
 
+#ifdef CONFIG_OMAP5_ERRATA_801819
+void omap5_erratum_workaround_801819(void)
+{
+	u32 acr, revidr;
+	u32 acr_mask;
+
+	/* REVIDR[3] indicates erratum fix available on silicon */
+	asm volatile ("mrc p15, 0, %0, c0, c0, 6" : "=r" (revidr));
+	if (revidr & (0x1 << 3))
+		return;
+
+	asm volatile ("mrc p15, 0, %0, c1, c0, 1" : "=r" (acr));
+	/*
+	 * BIT(27) - Disables streaming. All write-allocate lines allocate in
+	 * the L1 or L2 cache.
+	 * BIT(25) - Disables streaming. All write-allocate lines allocate in
+	 * the L1 cache.
+	 */
+	acr_mask = (0x3 << 25) | (0x3 << 27);
+	/* do we already have it done.. if yes, skip expensive smc */
+	if ((acr & acr_mask) == acr_mask)
+		return;
+
+	acr |= acr_mask;
+	omap_smc1(OMAP5_DRA7_MON_SET_ACR_INDEX, acr);
+
+	pr_debug("%s: ARM erratum workaround 801819 applied on CPU%d\n",
+		 __func__, smp_processor_id());
+}
+#else
+static inline void omap5_erratum_workaround_801819(void) { }
+#endif
+
 static void omap4_secondary_init(unsigned int cpu)
 {
 	/*
@@ -64,12 +97,15 @@ static void omap4_secondary_init(unsigned int cpu)
 		omap_secure_dispatcher(OMAP4_PPA_CPU_ACTRL_SMP_INDEX,
 							4, 0, 0, 0, 0, 0);
 
-	/*
-	 * Configure the CNTFRQ register for the secondary cpu's which
-	 * indicates the frequency of the cpu local timers.
-	 */
-	if (soc_is_omap54xx() || soc_is_dra7xx())
+	if (soc_is_omap54xx() || soc_is_dra7xx()) {
+		/*
+		 * Configure the CNTFRQ register for the secondary cpu's which
+		 * indicates the frequency of the cpu local timers.
+		 */
 		set_cntfreq();
+		/* Configure ACR to disable streaming WA for 801819 */
+		omap5_erratum_workaround_801819();
+	}
 
 	/*
 	 * Synchronise with the boot thread.
@@ -218,6 +254,8 @@ static void __init omap4_smp_prepare_cpus(unsigned int max_cpus)
 
 	if (cpu_is_omap446x())
 		startup_addr = omap4460_secondary_startup;
+	if (soc_is_dra74x() || soc_is_omap54xx())
+		omap5_erratum_workaround_801819();
 
 	/*
 	 * Write the address of secondary startup routine into the
-- 
2.1.4



From maitysanchayan at gmail.com  Thu Aug  6 08:58:22 2015
From: maitysanchayan at gmail.com (Sanchayan Maity)
Date: Thu,  6 Aug 2015 21:28:22 +0530
Subject: [PATCH] ARM: dts: vfxxx: Add iio_hwmon node for ADC temperature
 channel
Message-ID: <b639ca620369d196491a4af8739b87d580e71bf6.1438876380.git.maitysanchayan@gmail.com>

Add iio_hwmon node to expose the temperature channel on Vybrid
as hardware monitor device using the iio_hwmon driver.

Signed-off-by: Sanchayan Maity <maitysanchayan at gmail.com>
---
 arch/arm/boot/dts/vfxxx.dtsi | 5 +++++
 1 file changed, 5 insertions(+)

diff --git a/arch/arm/boot/dts/vfxxx.dtsi b/arch/arm/boot/dts/vfxxx.dtsi
index 39173bb..0993d66 100644
--- a/arch/arm/boot/dts/vfxxx.dtsi
+++ b/arch/arm/boot/dts/vfxxx.dtsi
@@ -597,5 +597,10 @@
 				status = "disabled";
 			};
 		};
+
+		iio_hwmon {
+			compatible = "iio-hwmon";
+			io-channels = <&adc0 16>;
+		};
 	};
 };
-- 
2.5.0



From broonie at kernel.org  Thu Aug  6 09:03:50 2015
From: broonie at kernel.org (Mark Brown)
Date: Thu, 6 Aug 2015 17:03:50 +0100
Subject: [RFC PATCH 1/5] spi: introduce flag for memory mapped read
In-Reply-To: <CAOMqctQKc6f5Mbe_CSd-ghguUfZvf6v_BRvYxQJVqPne73iESA@mail.gmail.com>
References: <20150804155148.GR20873@sirena.org.uk> <55C0FD98.1090107@ti.com>
 <20150805115013.GJ20873@sirena.org.uk>
 <CAOMqctQXwcHyiWBwtugSDSE_k65qrNfrwnhjQMDJkLoJMmGzUw@mail.gmail.com>
 <20150805124412.GN20873@sirena.org.uk>
 <CAOMqctS9Y5FxpUCCJew6+cnjH5iTvbzkH3g-8yrXs4OuS2pSGA@mail.gmail.com>
 <20150806090202.GO20873@sirena.org.uk>
 <CAOMqctQZRZ4zG_yYy=CeX3DX4NVNWN1COP4Q-2YvMun9xYOA7g@mail.gmail.com>
 <20150806112353.GT20873@sirena.org.uk>
 <CAOMqctQKc6f5Mbe_CSd-ghguUfZvf6v_BRvYxQJVqPne73iESA@mail.gmail.com>
Message-ID: <20150806160350.GX20873@sirena.org.uk>

On Thu, Aug 06, 2015 at 01:42:32PM +0200, Michal Suchanek wrote:
> On 6 August 2015 at 13:23, Mark Brown <broonie at kernel.org> wrote:

> > Sure, but at the end of the day it's just emitting standard SPI messages
> > which don't know anything about flash.  If those messages are a sensible
> > interface here then why bother with the flag, we can just pattern match
> > on the format of the message.  If that doesn't work then probably this
> > isn't a great interface and a separate, application specific interface
> > makes more sense.

> The messages are sensible interface for communicating with a device
> that interprets a particular part of the mesasge as address and
> another particular part of the message as command and sends same
> amount of junk before reply as the flash chip would. If your device

That's just a statement that it's possible to do things this way, it's
not clear to me that it's an explanation as to why it is sensible to do
so - the obvious thing to do there would be to specify the flash
operation as a flash operation rather than reverse engineer the flash
operation from the wire format.

> happens to send reply immediately part of it is trashed. If it happens
> to interpret address differently the data ends up in random part of
> your memory. So no, that is not something you can autodetect.

If this stuff doesn't appear in the spi_message in some observable form
then I'd expect that any existing flash support is broken since a SPI
controller that doesn't have any acceleration is just going to do what
the message says.

> At the end of the day you have valid SPI messages but the m25p80 layer
> adds interpretation to those messages which may not always give
> correct result.

Which comes back to the thing I keep saying about needing some sort of
information about what the flag means and the questions about why this
is a good interface...

> On the other hand, if you ever get to m25p80 or spi-nor you can assume
> any message you send goes to a flash chip and insist that the
> controller uses the flash-specific interface.

There's an awful lot of flashes out there connected to controllers that
don't implement any sort of acceleration for flash, I'm not convinced
that your assumption there is valid.

> If there is possibility of connecting different kind of devices to
> multiple chipselects on the same master then you probably want to
> select this option per message or per slave.

We definitely need to account for that.
-------------- next part --------------
A non-text attachment was scrubbed...
Name: signature.asc
Type: application/pgp-signature
Size: 473 bytes
Desc: Digital signature
URL: <http://lists.infradead.org/pipermail/linux-arm-kernel/attachments/20150806/4aaabe9e/attachment.sig>

From srinivas.kandagatla at linaro.org  Thu Aug  6 09:12:02 2015
From: srinivas.kandagatla at linaro.org (Srinivas Kandagatla)
Date: Thu, 06 Aug 2015 17:12:02 +0100
Subject: [PATCH 1/3] nvmem: Add i.MX6 OCOTP device tree binding
 documentation
In-Reply-To: <1438693342-605-1-git-send-email-p.zabel@pengutronix.de>
References: <1438693342-605-1-git-send-email-p.zabel@pengutronix.de>
Message-ID: <55C38752.3040406@linaro.org>



On 04/08/15 14:02, Philipp Zabel wrote:
> This patch documents the i.MX6 OCOTP device tree binding.
>
> Signed-off-by: Philipp Zabel <p.zabel at pengutronix.de>
> ---
>   .../devicetree/bindings/nvmem/imx-ocotp.txt          | 20 ++++++++++++++++++++
>   1 file changed, 20 insertions(+)
>   create mode 100644 Documentation/devicetree/bindings/nvmem/imx-ocotp.txt
>
> diff --git a/Documentation/devicetree/bindings/nvmem/imx-ocotp.txt b/Documentation/devicetree/bindings/nvmem/imx-ocotp.txt
> new file mode 100644
> index 0000000..7d9a3fc
> --- /dev/null
> +++ b/Documentation/devicetree/bindings/nvmem/imx-ocotp.txt
> @@ -0,0 +1,20 @@
> +Freescale i.MX6 On-Chip OTP Controller (OCOTP) device tree bindings
> +
> +This binding represents the on-chip eFuse OTP controller found on
> +i.MX6Q/D, i.MX6DL/S, i.MX6SL, and i.MX6SX SoCs.
> +
> +Required properties:
> +- compatible: should be one of
> +	"fsl,imx6q-ocotp" (i.MX6Q/D/DL/S),
> +        "fsl,imx6sl-ocotp" (i.MX6SL), or
> +	"fsl,imx6sx-ocotp" (i.MX6SX), followed by "syscon".
> +- reg: Should contain the register base and length.
> +- clocks: Should contain a phandle pointing to the gated peripheral clock.
> +
> +Example:
> +
> +	ocotp: ocotp at 021bc000 {
> +		compatible = "fsl,imx6q-ocotp", "syscon";
Do you still need syscon?

> +		reg = <0x021bc000 0x4000>;
Can't we just have a register range specific to the OTP device?

> +		clocks = <&clks IMX6QDL_CLK_IIM>;
> +	};
>


From geert at linux-m68k.org  Thu Aug  6 09:14:00 2015
From: geert at linux-m68k.org (Geert Uytterhoeven)
Date: Thu, 6 Aug 2015 18:14:00 +0200
Subject: [RFC PATCH 1/5] spi: introduce flag for memory mapped read
In-Reply-To: <20150806135129.GJ7576@n2100.arm.linux.org.uk>
References: <20150804155148.GR20873@sirena.org.uk> <55C0FD98.1090107@ti.com>
 <20150805115013.GJ20873@sirena.org.uk>
 <CAOMqctQXwcHyiWBwtugSDSE_k65qrNfrwnhjQMDJkLoJMmGzUw@mail.gmail.com>
 <20150805124412.GN20873@sirena.org.uk>
 <CAOMqctS9Y5FxpUCCJew6+cnjH5iTvbzkH3g-8yrXs4OuS2pSGA@mail.gmail.com>
 <20150806090202.GO20873@sirena.org.uk>
 <CAOMqctQZRZ4zG_yYy=CeX3DX4NVNWN1COP4Q-2YvMun9xYOA7g@mail.gmail.com>
 <20150806102225.GI7576@n2100.arm.linux.org.uk>
 <55C35233.2000105@ti.com>
 <20150806135129.GJ7576@n2100.arm.linux.org.uk>
Message-ID: <CAMuHMdWWDwZ=ziGQXFCnOX8pErXpsEi533J73_Hh=sEqq4hR6Q@mail.gmail.com>

On Thu, Aug 6, 2015 at 3:51 PM, Russell King - ARM Linux
<linux at arm.linux.org.uk> wrote:
> On Thu, Aug 06, 2015 at 05:55:23PM +0530, Vignesh R wrote:
>> On the whole following are my requirements:
>> 1. to be able to communicate with non -flash SPI devices via config port
>> ( this functionality is supported by current driver, I dont want to
>> break it). Or pump any spi_message on to SPI bus directly.
>> 2. take advantage of memory mapped port in order to increase read
>> throughput( and use dma in future) when the slave is a m25p80 type flash.
>> 3. handle m25p80 as well as other slave on multiple chipselects.
>>
>> I just need to know whether the user that requested the transfer is
>> m25p80 driver. If yes, ti-qspi driver can take advantage of memory
>> mapped interface, else just use config port to access SPI bus directly.
>
> The problem with this approach is that it's an abomination.  It's adding
> a SPI-user specific hack which is detected by a specific driver.  That's
> really not sane - what happens when we have lots of these kinds of "I'm
> an X SPI-user" with drivers detecting that?  It's not maintainable in the
> long term.
>
> Yes, your requirements _today_ seem simple and easy, but you're only
> thinking about today, not tomorrow when you've moved on and someone else
> has to maintain the mess left behind (or delete it from mainline because
> they're sick of dealing with a hack.)
>
>> The spi_message that is received in transfer_one_message() is too
>> generic to imply the slave device that is on the other side of the wire.
>> IMO, the read command does not imply that the slave is m25p80 flash
>> (besides the read opcodes vary across vendors of m25p80 and across modes).
>
> I can see both sides of the argument.
>
> Mark is saying: if the SPI driver detects that the message to be transmitted
> is a read command followed by the appropriate number of dummy bytes, and
> then the data being read _and_ it's using quad-mode access, and the hardware
> generates _exactly_ that in hardware using the memory mapped mode, there is
> no reason _not_ to use the hardware to achieve that SPI transaction.  The
> bus activity will be identical to what happens when the SPI controller is
> used manually to achieve that bus sequence.
>
> You're saying: but the documentation says you can't use it for anything
> except m25p80.  If you look at 24.5.4.1.2, it tells you what the SFI
> generates on the bus, which is:
>
> 1. CS active
> 2. Read command byte sent
> 3. 1-4 address bytes sent
> 4. 0-3 dummy bytes sent
> 5. data bytes read from bus
> 6. CS inactive
>
> So, Mark's point is "if we can detect a transaction which fits _that_
> bus activity, there's no reason not to use this acceleration for the
> transaction."
>
> What you're failing to counter with is: we don't have enough information
> in the SPI driver to know how many dummy bytes there are between the
> address bytes and the data read from the bus.

Irrespective of the dummy bytes.
What if the spi device is not a FLASH ROM, but some other device,
which receives a data packet that accidentally looks like an m25p80 READ
command?

Gr{oetje,eeting}s,

                        Geert

--
Geert Uytterhoeven -- There's lots of Linux beyond ia32 -- geert at linux-m68k.org

In personal conversations with technical people, I call myself a hacker. But
when I'm talking to journalists I just say "programmer" or something like that.
                                -- Linus Torvalds


From slash.tmp at free.fr  Thu Aug  6 09:14:46 2015
From: slash.tmp at free.fr (Mason)
Date: Thu, 06 Aug 2015 18:14:46 +0200
Subject: IRQ setup on multicore systems (routing, balancing, etc)
In-Reply-To: <20150806152654.GF7557@n2100.arm.linux.org.uk>
References: <55C0C102.7050600@free.fr> <55C37A72.2090507@free.fr>
 <20150806152654.GF7557@n2100.arm.linux.org.uk>
Message-ID: <55C387F6.8090708@free.fr>

On 06/08/2015 17:26, Russell King - ARM Linux wrote:
> On Thu, Aug 06, 2015 at 05:17:06PM +0200, Mason wrote:
>> On 04/08/2015 15:41, Mason wrote:
>>
>>> I have a few very naive questions about [snip]
>>
>> [META]
>>
>> Are there perhaps more suitable mailing lists than this one
>> for such beginner questions?
> 
> I thought your message yesterday indicated you'd found the answer.

I have so many questions, I could write a (very boring) book.

> You don't setup any kind of routing between CPU cores and devices.
> At boot, initially CPU 0 will "own" all interrupts.

OK.

It doesn't help that the port I'm working on doesn't follow
"established guidelines". In this case, interrupt routing is
hard-coded in the platform code:

static inline void tangox_enable(struct irq_data *data)
{
	int bit = data->irq - IRQ_CONTROLLER_IRQ_BASE;
#ifdef ENABLE_INTERRUPT_ON_CPU1
	if(route_interrupt_to_cpu1(bit))
		tangox_fiq_enable(bit);
	else
#endif
		tangox_irq_enable(bit);
}

(tangox_enable is called in the .irq_startup struct irq_chip callback.)

Throw weird naming in the mix (I thought FIQ was reserved for
the secure world, and my Linux runs in non-secure) and my
confusion level is up to 11.

> You then run a (fixed) version of irqbalanced (preferably the older
> version which is not so x86-centric, eg, 0.56) which then distributes
> the interrupts between the cores according to what the interrupt is
> used for and the load it is imposing on the system.

OK. Thanks for pointing that out.

Unfortunately, I guess I should have asked the more fundamental
questions first. Balancing IRQs only makes sense once IRQs are
working.

I don't understand how to convert my board file mess into the
equivalent device tree, and the platform IRQ code is ugly.

I still haven't found a good reference explaining "DT for dummies".
I don't know how the GIC and platform INTC interact.

I tried randomly copy/pasting DT snippets, but unsurprisingly,
nothing has worked so far.

(I use Mans Rullgard's port as a reference as much as I can.)
https://github.com/mansr/linux-tangox

/dts-v1/;

/ {
	compatible = "sigma,tango4-soc";

	#address-cells = <1>;
	#size-cells = <1>;

	gic: interrupt-controller at 20001000 {
		compatible = "arm,cortex-a9-gic";
		interrupt-controller;
		#interrupt-cells = <3>;
		reg = <0x20001000 0x1000>,
		      <0x20000100 0x0100>;
	};

	soc {
		compatible = "simple-bus";
		interrupt-parent = <&irqintc>;
		#address-cells = <1>;
		#size-cells = <1>;
		ranges;

		uart0: serial at 10700 {
			compatible = "ns16550a";
			reg = <0x10700 0x100>;
			clock-frequency = <7372800>;
			reg-shift = <2>;
			no-loopback-test;
		};

		eth0: emac at 26000 {
			compatible = "sigma,smp8640-emac";
			reg = <0x26000 0x800>;
			interrupts = <38>;
			clocks = <396000000>;
		};
	};

	cpublock: cpublock {
		compatible = "simple-bus";
		reg = <0x60000 0x10000>;
		ranges = <0x0 0x60000 0x10000>;
		interrupt-parent = <&irqintc>;
		#address-cells = <1>;
		#size-cells = <1>;

		intc: intc at e000 {
			compatible = "sigma,smp8640-intc";
			reg = <0xe000 0x1000>;
			ranges = <0x0 0xe000 0x1000>;
			interrupt-parent = <&gic>;
			interrupt-controller;
			#address-cells = <1>;
			#size-cells = <1>;

			irqintc: irq at 000 {
				reg = <0x000 0x100>;
				#interrupt-cells = <2>;
				interrupts = <2>;
				label = "IRQ";
			};

			fiqintc: fiq at 100 {
				reg = <0x100 0x100>;
				#interrupt-cells = <2>;
				interrupts = <3>;
				label = "FIQ";
			};

			iiqintc: iiq at 300 {
				reg = <0x300 0x100>;
				#interrupt-cells = <2>;
				interrupts = <4>;
				label = "IIQ";
			};
		};
	};

};

Bleh! I need a break. Be back in a few weeks.

Regards.



From will.deacon at arm.com  Thu Aug  6 09:16:25 2015
From: will.deacon at arm.com (Will Deacon)
Date: Thu, 6 Aug 2015 17:16:25 +0100
Subject: [PATCH V2] iommu/arm-smmu-v2: ThunderX mis-extends 64bit registers
In-Reply-To: <1438793668-15597-1-git-send-email-tchalamarla@caviumnetworks.com>
References: <1438793668-15597-1-git-send-email-tchalamarla@caviumnetworks.com>
Message-ID: <20150806161625.GJ25483@arm.com>

Hi Tirumalesh,

I think this looks pretty good now, just one small comment below.

On Wed, Aug 05, 2015 at 05:54:28PM +0100, Tirumalesh Chalamarla wrote:
> The SMMU architecture defines two different behaviors when 64-bit
> registers are written with 32-bit writes.  The first behavior causes
> zero extension into the upper 32-bits.  The second behavior splits a
> 64-bit register into "normal" 32-bit register pairs.
> 
> On some buggy implementations, registers incorrectly zero extended
> when they should instead behave as normal 32-bit register pairs.
> 
> Signed-off-by: Tirumalesh Chalamarla <tchalamarla at caviumnetworks.com>
> ---
> 
> Changes from V1:
> 	- Introduced smmu_writeq
> 
>  drivers/iommu/arm-smmu.c | 45 +++++++++++++++++++++++++--------------------
>  1 file changed, 25 insertions(+), 20 deletions(-)
> 
> diff --git a/drivers/iommu/arm-smmu.c b/drivers/iommu/arm-smmu.c
> index 66a803b..0912c78 100644
> --- a/drivers/iommu/arm-smmu.c
> +++ b/drivers/iommu/arm-smmu.c
> @@ -69,6 +69,18 @@
>  		((smmu->options & ARM_SMMU_OPT_SECURE_CFG_ACCESS)	\
>  			? 0x400 : 0))
>  
> +#ifdef CONFIG_64BIT
> +#define smmu_writeq(reg64, addr)	writeq_relaxed((reg64), (addr))
> +#else
> +#define smmu_writeq(reg64, addr)				\
> +	do {							\
> +		u64 __val = (reg64);				\
> +		void __iomem *__addr = (addr);			\
> +		writel_relaxed(__val >> 32, __addr + 4);	\
> +		writel_relaxed(__val, __addr);			\
> +	} while (0)
> +#endif
> +
>  /* Configuration registers */
>  #define ARM_SMMU_GR0_sCR0		0x0
>  #define sCR0_CLIENTPD			(1 << 0)
> @@ -226,7 +238,7 @@
>  #define TTBCR2_SEP_SHIFT		15
>  #define TTBCR2_SEP_UPSTREAM		(0x7 << TTBCR2_SEP_SHIFT)
>  
> -#define TTBRn_HI_ASID_SHIFT            16
> +#define TTBRn_ASID_SHIFT		48
>  
>  #define FSR_MULTI			(1 << 31)
>  #define FSR_SS				(1 << 30)
> @@ -762,22 +774,17 @@ static void arm_smmu_init_context_bank(struct arm_smmu_domain *smmu_domain,
>  
>  	/* TTBRs */
>  	if (stage1) {
> -		reg = pgtbl_cfg->arm_lpae_s1_cfg.ttbr[0];
> -		writel_relaxed(reg, cb_base + ARM_SMMU_CB_TTBR0_LO);
> -		reg = pgtbl_cfg->arm_lpae_s1_cfg.ttbr[0] >> 32;
> -		reg |= ARM_SMMU_CB_ASID(cfg) << TTBRn_HI_ASID_SHIFT;
> -		writel_relaxed(reg, cb_base + ARM_SMMU_CB_TTBR0_HI);
> -
> -		reg = pgtbl_cfg->arm_lpae_s1_cfg.ttbr[1];
> -		writel_relaxed(reg, cb_base + ARM_SMMU_CB_TTBR1_LO);
> -		reg = pgtbl_cfg->arm_lpae_s1_cfg.ttbr[1] >> 32;
> -		reg |= ARM_SMMU_CB_ASID(cfg) << TTBRn_HI_ASID_SHIFT;
> -		writel_relaxed(reg, cb_base + ARM_SMMU_CB_TTBR1_HI);
> +		u64 reg64 = pgtbl_cfg->arm_lpae_s1_cfg.ttbr[0];

Can we move this declaration to the start of the function along with
u32 reg, please? It's used in both cases of the if/else block so it
might be a tad cleaner.

Will


From srinivas.kandagatla at linaro.org  Thu Aug  6 09:20:17 2015
From: srinivas.kandagatla at linaro.org (Srinivas Kandagatla)
Date: Thu, 06 Aug 2015 17:20:17 +0100
Subject: [PATCH 2/3] nvmem: imx-ocotp: Add i.MX6 OCOTP driver
In-Reply-To: <1438693342-605-2-git-send-email-p.zabel@pengutronix.de>
References: <1438693342-605-1-git-send-email-p.zabel@pengutronix.de>
 <1438693342-605-2-git-send-email-p.zabel@pengutronix.de>
Message-ID: <55C38941.9090709@linaro.org>

Few Nits..

On 04/08/15 14:02, Philipp Zabel wrote:
> This driver handles the i.MX On-Chip OTP Controller found in
> i.MX6Q/D, i.MX6S/DL, i.MX6SL, and i.MX6SX SoCs. Currently it
> just returns the values stored in the shadow registers.
>
> Signed-off-by: Philipp Zabel <p.zabel at pengutronix.de>
> ---
> This patch is based on the v9 "Add simple NVMEM Framework via regmap"
> series which can be found here: https://lkml.org/lkml/2015/7/27/342
> ---
>   drivers/nvmem/Kconfig     |  11 ++++
>   drivers/nvmem/Makefile    |   2 +
>   drivers/nvmem/imx-ocotp.c | 155 ++++++++++++++++++++++++++++++++++++++++++++++
>   3 files changed, 168 insertions(+)
>   create mode 100644 drivers/nvmem/imx-ocotp.c
>
> diff --git a/drivers/nvmem/Kconfig b/drivers/nvmem/Kconfig
> index 8db2978..0b33014 100644
> --- a/drivers/nvmem/Kconfig
> +++ b/drivers/nvmem/Kconfig
> @@ -36,4 +36,15 @@ config NVMEM_SUNXI_SID
>   	  This driver can also be built as a module. If so, the module
>   	  will be called nvmem_sunxi_sid.
>
> +config NVMEM_IMX_OCOTP
> +	tristate "i.MX6 On-Chip OTP Controller support"
> +	depends on SOC_IMX6
> +	help
> +	  This is a driver for the On-Chip OTP Controller (OCOTP) available on
> +	  i.MX6 SoCs, providing access to 4 Kbits of one-time programmable
> +	  eFuses.
> +
> +	  This driver can also be built as a module. If so, the module
> +	  will be called nvmem-imx-ocotp.
> +
>   endif
> diff --git a/drivers/nvmem/Makefile b/drivers/nvmem/Makefile
> index 4328b93..b512d77 100644
> --- a/drivers/nvmem/Makefile
> +++ b/drivers/nvmem/Makefile
> @@ -10,3 +10,5 @@ obj-$(CONFIG_QCOM_QFPROM)	+= nvmem_qfprom.o
>   nvmem_qfprom-y			:= qfprom.o
>   obj-$(CONFIG_NVMEM_SUNXI_SID)	+= nvmem_sunxi_sid.o
>   nvmem_sunxi_sid-y		:= sunxi_sid.o
> +obj-$(CONFIG_NVMEM_IMX_OCOTP)	+= nvmem-imx-ocotp.o
> +nvmem-imx-ocotp-y		:= imx-ocotp.o
> diff --git a/drivers/nvmem/imx-ocotp.c b/drivers/nvmem/imx-ocotp.c
> new file mode 100644
> index 0000000..e918967
> --- /dev/null
> +++ b/drivers/nvmem/imx-ocotp.c
> @@ -0,0 +1,155 @@
> +/*
> + * i.MX6 OCOTP fusebox driver
> + *
> + * Copyright (c) 2015 Pengutronix, Philipp Zabel <p.zabel at pengutronix.de>
> + *
> + * Based on the barebox ocotp driver,
> + * Copyright (c) 2010 Baruch Siach <baruch at tkos.co.il>,
> + *	Orex Computed Radiography
> + *
> + * 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.
> + *
> + * http://www.opensource.org/licenses/gpl-license.html
> + * http://www.gnu.org/copyleft/gpl.html
> + */
> +
> +#include <linux/clk.h>
May be you can drop this?

BTW, who is taking care of the gated peripheral clock controlled for 
this driver?


> +#include <linux/device.h>
> +#include <linux/io.h>
> +#include <linux/module.h>
> +#include <linux/nvmem-provider.h>
> +#include <linux/of.h>
> +#include <linux/of_device.h>
> +#include <linux/platform_device.h>
> +#include <linux/regmap.h>
> +#include <linux/slab.h>
> +
> +struct ocotp_priv {
> +	struct device *dev;
> +	void __iomem *base;
> +	unsigned int nregs;
> +};
> +
> +static int imx_ocotp_read(void *context, const void *reg, size_t reg_size,
> +			  void *val, size_t val_size)
> +{
> +	struct ocotp_priv *priv = context;
> +	unsigned int offset = *(u32 *)reg;
> +	unsigned int count;
> +	int i;
> +	u32 index;
> +
> +	index = offset >> 2;
> +	count = val_size >> 2;
> +
> +	if (count > (priv->nregs - index))
> +		count = priv->nregs - index;
> +
> +	for (i = index; i < (index + count); i++) {
> +		*(u32 *)val = readl(priv->base + 0x400 + i * 0x10);
> +		val += 4;
> +	}
> +
> +	return (i - index) * 4;
> +}
> +
> +static int imx_ocotp_write(void *context, const void *data, size_t count)
> +{
> +	/* Not implemented */
> +	return 0;
> +}
> +
> +static struct regmap_bus imx_ocotp_bus = {
> +	.read = imx_ocotp_read,
> +	.write = imx_ocotp_write,
> +	.reg_format_endian_default = REGMAP_ENDIAN_NATIVE,
> +	.val_format_endian_default = REGMAP_ENDIAN_NATIVE,
> +};
> +
> +static bool imx_ocotp_writeable_reg(struct device *dev, unsigned int reg)
> +{
> +	return false;
> +}
> +
> +static struct regmap_config imx_ocotp_regmap_config = {
> +	.reg_bits = 32,
> +	.val_bits = 32,
> +	.reg_stride = 4,
> +	.writeable_reg = imx_ocotp_writeable_reg,
> +	.name = "imx-ocotp",
> +};
> +
> +static struct nvmem_config imx_ocotp_nvmem_config = {
> +	.name = "imx-ocotp",
> +	.read_only = true,
> +	.owner = THIS_MODULE,
> +};
> +
> +static const struct of_device_id imx_ocotp_dt_ids[] = {
> +	{ .compatible = "fsl,imx6q-ocotp",  (void *)128 },
> +	{ .compatible = "fsl,imx6sl-ocotp", (void *)32 },
> +	{ .compatible = "fsl,imx6sx-ocotp", (void *)128 },
> +	{ },
> +};
> +MODULE_DEVICE_TABLE(of, imx_ocotp_dt_ids);
> +
> +static int imx_ocotp_probe(struct platform_device *pdev)
> +{
> +	const struct of_device_id *of_id;
> +	struct device *dev = &pdev->dev;
> +	struct resource *res;
> +	struct regmap *regmap;
> +	struct ocotp_priv *priv;
> +	struct nvmem_device *nvmem;
> +
> +	priv = devm_kzalloc(dev, sizeof(*priv), GFP_KERNEL);
> +	if (!priv)
> +		return -ENOMEM;
> +
> +	res = platform_get_resource(pdev, IORESOURCE_MEM, 0);
> +	priv->base = devm_ioremap_resource(dev, res);
> +	if (IS_ERR(priv->base))
> +		return PTR_ERR(priv->base);
> +
> +	of_id = of_match_device(imx_ocotp_dt_ids, dev);
> +	priv->nregs = (unsigned int)of_id->data;
> +	imx_ocotp_regmap_config.max_register = 4 * priv->nregs - 4;
> +
> +	regmap = devm_regmap_init(dev, &imx_ocotp_bus, priv,
> +				  &imx_ocotp_regmap_config);
> +	if (IS_ERR(regmap)) {
> +		dev_err(dev, "regmap init failed\n");
> +		return PTR_ERR(regmap);
> +	}
> +	imx_ocotp_nvmem_config.dev = dev;
> +	nvmem = nvmem_register(&imx_ocotp_nvmem_config);
> +	if (IS_ERR(nvmem))
> +		return PTR_ERR(nvmem);
> +
> +	platform_set_drvdata(pdev, nvmem);
> +
> +	return 0;
> +}
> +
> +static int imx_ocotp_remove(struct platform_device *pdev)
> +{
> +	struct nvmem_device *nvmem = platform_get_drvdata(pdev);
> +
> +	return nvmem_unregister(nvmem);
> +}
> +
> +static struct platform_driver imx_ocotp_driver = {
> +	.probe	= imx_ocotp_probe,
> +	.remove	= imx_ocotp_remove,
> +	.driver = {
> +		.name	= "imx_ocotp",
> +		.of_match_table = imx_ocotp_dt_ids,
> +	},
> +};
> +module_platform_driver(imx_ocotp_driver);
> +
> +MODULE_AUTHOR("Philipp Zabel <p.zabel at pengutronix.de>");
> +MODULE_DESCRIPTION("i.MX6 OCOTP fuse box driver");
> +MODULE_LICENSE("GPL");

GPL v2 ?

>


From geert at linux-m68k.org  Thu Aug  6 09:21:58 2015
From: geert at linux-m68k.org (Geert Uytterhoeven)
Date: Thu, 6 Aug 2015 18:21:58 +0200
Subject: [PATCH v4 1/6] ARM: shmobile: r8a7740 dtsi: Add L2
 cache-controller node
In-Reply-To: <55C1EC3C.9000407@arm.com>
References: <1438765090-823-1-git-send-email-geert+renesas@glider.be>
 <1438765090-823-2-git-send-email-geert+renesas@glider.be>
 <55C1D894.8070302@arm.com>
 <CAMuHMdXdEV+41mH338bDbazzqOErDLQkBUAj2+uVX4Wupn1ABQ@mail.gmail.com>
 <55C1EC3C.9000407@arm.com>
Message-ID: <CAMuHMdVAOba0ofmoy8OH2DdY1m3XaD8iOXvXBE035=C4yK58VQ@mail.gmail.com>

Hi Sudeep,

On Wed, Aug 5, 2015 at 12:58 PM, Sudeep Holla <sudeep.holla at arm.com> wrote:
> On 05/08/15 11:44, Geert Uytterhoeven wrote:
>> On Wed, Aug 5, 2015 at 11:34 AM, Sudeep Holla <sudeep.holla at arm.com>
>> wrote:
>>> On 05/08/15 09:58, Geert Uytterhoeven wrote:
>>>> Add the missing L2 cache-controller node. This will allow migration to
>>>> the generic l2c OF initialization.
>>>>
>>>> The L2 cache is an ARM L2C-310 (r3p1-150rel0), of size 256 KiB (32 KiB x
>>>> 8 ways).
>>>>
>>>> Signed-off-by: Geert Uytterhoeven <geert+renesas at glider.be>
>>
>>
>>>> diff --git a/arch/arm/boot/dts/r8a7740.dtsi
>>>> b/arch/arm/boot/dts/r8a7740.dtsi
>>>> index d84714468cce18df..ddef5b1c68fa06b3 100644
>>>> --- a/arch/arm/boot/dts/r8a7740.dtsi
>>>> +++ b/arch/arm/boot/dts/r8a7740.dtsi
>>>> @@ -37,6 +37,22 @@
>>>>                        <0xc2000000 0x1000>;
>>>>          };
>>>>
>>>> +       L2: cache-controller {
>>>> +               compatible = "arm,pl310-cache";
>>>> +               reg = <0xf0100000 0x1000>;
>>>> +               interrupts = <0 84 IRQ_TYPE_LEVEL_HIGH>;
>>>> +               power-domains = <&pd_a3sm>;
>>>> +               arm,data-latency = <3 3 3>;
>>>> +               arm,tag-latency = <2 2 2>;
>>>> +               arm,shared-override;
>>>> +               cache-unified;
>>>> +               cache-level = <2>;
>>>> +               cache-size = <0x40000>;
>>>> +               cache-sets = <1024>;
>>>> +               cache-block-size = <32>;
>>>> +               cache-line-size = <32>;
>>>
>>> Any particular reason whey you need all this cache-* properties ? Is
>>
>> To describe the cache as good as possible.
>
> Why if you can probe it ? IMO DT is mostly useful to describe things
> that can't be probed/discovered using hardware.
>
>>> something broken on these SoCs ? We should be able to get most of these
>>> information from the SoC(reading some registers). It's good to avoid
>>> passing them via DT if they can be discovered from hardware.
>>
>> So we have all these documented properties in
>> Documentation/devicetree/bindings/arm/l2cc.txt, but they're not meant to
>> be used?
>
> No I didn't mean that, I just wanted to know if they can't be probed due
> to some hardware issue. It would avoid issues with wrong DTs especially
> if they are not so easy to upgrade.

I think it works just fine without them.

Should I drop all cache-* properties marked optional in
Documentation/devicetree/bindings/arm/l2cc.txt?
That would be cache-size, cache-sets, cache-block-size, and cache-line-size.

What about the L1 cache? I know Linux uses none of the d-cache-*
and i-cache-* properties.

Thanks!

Gr{oetje,eeting}s,

                        Geert

--
Geert Uytterhoeven -- There's lots of Linux beyond ia32 -- geert at linux-m68k.org

In personal conversations with technical people, I call myself a hacker. But
when I'm talking to journalists I just say "programmer" or something like that.
                                -- Linus Torvalds


From p.zabel at pengutronix.de  Thu Aug  6 09:28:10 2015
From: p.zabel at pengutronix.de (Philipp Zabel)
Date: Thu, 06 Aug 2015 18:28:10 +0200
Subject: [PATCH 2/3] nvmem: imx-ocotp: Add i.MX6 OCOTP driver
In-Reply-To: <55C38941.9090709@linaro.org>
References: <1438693342-605-1-git-send-email-p.zabel@pengutronix.de>
 <1438693342-605-2-git-send-email-p.zabel@pengutronix.de>
 <55C38941.9090709@linaro.org>
Message-ID: <1438878490.3223.10.camel@pengutronix.de>

Hi Srinivas,

Am Donnerstag, den 06.08.2015, 17:20 +0100 schrieb Srinivas Kandagatla:
> Few Nits..
> 
> On 04/08/15 14:02, Philipp Zabel wrote:
> > +#include <linux/clk.h>
> May be you can drop this?

Yes, that's a left-over and can be removed.

> BTW, who is taking care of the gated peripheral clock controlled for 
> this driver?

Nobody. I had initially copied the code that actually senses the fuses,
but since this happens during power-on reset anyway (all values are
stored in shadow registers), I didn't see the point and dropped it for
now.
The shadow registers are clocked directly by the ungated ipg_root clock.

[...]
> > +MODULE_LICENSE("GPL");
> 
> GPL v2 ?

Will do.

thanks
Philipp



From marc.zyngier at arm.com  Thu Aug  6 09:29:17 2015
From: marc.zyngier at arm.com (Marc Zyngier)
Date: Thu, 06 Aug 2015 17:29:17 +0100
Subject: [PATCH v4 02/10] ACPI / irqchip: Add self-probe infrastructure
 to initialize IRQ controller
In-Reply-To: <55C20E9A.7000906@linaro.org>
References: <1438164539-29256-1-git-send-email-hanjun.guo@linaro.org>
 <1438164539-29256-3-git-send-email-hanjun.guo@linaro.org>
 <55C0AFA2.8050704@arm.com> <55C20E9A.7000906@linaro.org>
Message-ID: <55C38B5D.9090407@arm.com>

On 05/08/15 14:24, Hanjun Guo wrote:
> Hi Marc,
> 
> On 08/04/2015 08:27 PM, Marc Zyngier wrote:
>> On 29/07/15 11:08, Hanjun Guo wrote:
>>> This self-probe infrastructure works in the similar way as OF,
>>> but there is some different in the mechanism:
>>>
>>> For DT, the init fn will be called once it finds compatible strings
>>> in DT,  but for ACPI, we init irqchips by static tables, and in
>>> static ACPI tables, there are no compatible strings to indicate
>>> irqchips, but thanks to the GIC version presented in ACPI table,
>>> we can call the corresponding GIC drivers matching the GIC version
>>> with this framework.
>>>
>>> This mechanism can also be used for clock declare and may also works
>>> on x86 for some table parsing too.
>>>
>>> This patch is based on Tomasz Nowicki <tomasz.nowicki at linaro.org>'s
>>> work.
>>>
>>> Signed-off-by: Hanjun Guo <hanjun.guo at linaro.org>
>>> ---
>>>   drivers/irqchip/irq-gic-acpi.c    | 33 +++++++++++++++++++++++++++++++++
>>>   include/asm-generic/vmlinux.lds.h | 13 +++++++++++++
>>>   include/linux/acpi.h              | 16 ++++++++++++++++
>>>   include/linux/irqchip.h           | 13 +++++++++++++
>>>   include/linux/mod_devicetable.h   |  8 ++++++++
>>>   5 files changed, 83 insertions(+)
>>>
>>> diff --git a/drivers/irqchip/irq-gic-acpi.c b/drivers/irqchip/irq-gic-acpi.c
>>> index 6537b43..011468d 100644
>>> --- a/drivers/irqchip/irq-gic-acpi.c
>>> +++ b/drivers/irqchip/irq-gic-acpi.c
>>> @@ -107,3 +107,36 @@ static int __init acpi_gic_version_init(void)
>>>
>>>   	return 0;
>>>   }
>>> +
>>> +/*
>>> + * This special acpi_table_id is the sentinel at the end of the
>>> + * acpi_table_id[] array of all irqchips. It is automatically placed at
>>> + * the end of the array by the linker, thanks to being part of a
>>> + * special section.
>>> + */
>>> +static const struct acpi_table_id
>>> +irqchip_acpi_match_end __used __section(__irqchip_acpi_table_end);
>>
>> What is this thing for? Nobody refers to it (I know
>> drivers/irqchip/irqchip.c has a similar thing, but that's not enough a
>> reason...).
> 
> If I'm not mistaken, this is for proper section termination, please
> see below:
> 
> /* scan the irqchip table to match the GIC version and its driver */
> for (id = __irqchip_acpi_table; id->id[0]; id++) {
> ...
> }
> 
> Then irqchip_acpi_match_end will be the end of the table section,
> which will terminate the scanning.

Yeah, I got that bit, but I didn't realized this was getting pulled into
the section. It's probably fine then.

>>
>>> +
>>> +extern struct acpi_table_id __irqchip_acpi_table[];
>>> +
>>> +void __init acpi_irqchip_init(void)
>>> +{
>>> +	struct acpi_table_id *id;
>>> +
>>> +	if (acpi_disabled)
>>> +		return;
>>> +
>>> +	if (acpi_gic_version_init())
>>> +		return;
>>
>> This is the only place where we need the version, right? So just get
>> acpi_gic_version_init to return the version number, and loose the global
>> variable.
> 
> The global variable is still needed because we need to get the GIC
> version when scanning the MADT tables, we can't return the table value
> directly in acpi_table_parse_madt() at now.
> 
>>
>>> +
>>> +	/* scan the irqchip table to match the GIC version and its driver */
>>> +	for (id = __irqchip_acpi_table; id->id[0]; id++) {
>>> +		if (gic_version == (u8)id->driver_data) {
>>> +			acpi_table_parse(id->id,
>>> +					 (acpi_tbl_table_handler)id->handler);
>>> +			return;
>>> +		}
>>> +	}
>>> +
>>> +	pr_err("No matched driver GIC version %d\n", gic_version);
>>> +}
>>> diff --git a/include/asm-generic/vmlinux.lds.h b/include/asm-generic/vmlinux.lds.h
>>> index 8bd374d..625776c 100644
>>> --- a/include/asm-generic/vmlinux.lds.h
>>> +++ b/include/asm-generic/vmlinux.lds.h
>>> @@ -181,6 +181,18 @@
>>>   #define CPUIDLE_METHOD_OF_TABLES() OF_TABLE(CONFIG_CPU_IDLE, cpuidle_method)
>>>   #define EARLYCON_OF_TABLES()	OF_TABLE(CONFIG_SERIAL_EARLYCON, earlycon)
>>>
>>> +#ifdef CONFIG_ACPI
>>> +#define ACPI_TABLE(name)						\
>>> +	. = ALIGN(8);							\
>>> +	VMLINUX_SYMBOL(__##name##_acpi_table) = .;			\
>>> +	*(__##name##_acpi_table)					\
>>> +	*(__##name##_acpi_table_end)
>>> +
>>> +#define IRQCHIP_ACPI_MATCH_TABLE()	ACPI_TABLE(irqchip)
>>> +#else
>>> +#define IRQCHIP_ACPI_MATCH_TABLE()
>>> +#endif
>>> +
>>>   #define KERNEL_DTB()							\
>>>   	STRUCT_ALIGN();							\
>>>   	VMLINUX_SYMBOL(__dtb_start) = .;				\
>>> @@ -516,6 +528,7 @@
>>>   	CPUIDLE_METHOD_OF_TABLES()					\
>>>   	KERNEL_DTB()							\
>>>   	IRQCHIP_OF_MATCH_TABLE()					\
>>> +	IRQCHIP_ACPI_MATCH_TABLE()					\
>>>   	EARLYCON_TABLE()						\
>>>   	EARLYCON_OF_TABLES()
>>>
>>> diff --git a/include/linux/acpi.h b/include/linux/acpi.h
>>> index 0820cb1..04dd0bb 100644
>>> --- a/include/linux/acpi.h
>>> +++ b/include/linux/acpi.h
>>> @@ -829,4 +829,20 @@ static inline struct acpi_device *acpi_get_next_child(struct device *dev,
>>>
>>>   #endif
>>>
>>> +#ifdef CONFIG_ACPI
>>> +#define ACPI_DECLARE(table, name, table_id, data, fn)			\
>>> +	static const struct acpi_table_id __acpi_table_##name		\
>>> +		__used __section(__##table##_acpi_table)		\
>>> +		 = { .id = table_id,					\
>>> +		     .handler = (void *)fn,				\
>>> +		     .driver_data = data }
>>> +#else
>>> +#define ACPI_DECLARE(table, name, table_id, data, fn)			\
>>> +	static const struct acpi_table_id __acpi_table_##name		\
>>> +		__attribute__((unused))					\
>>> +		 = { .id = table_id,					\
>>> +		     .handler = (void *)fn,				\
>>> +		     .driver_data = data }
>>> +#endif
>>> +
>>>   #endif	/*_LINUX_ACPI_H*/
>>> diff --git a/include/linux/irqchip.h b/include/linux/irqchip.h
>>> index 6388873..6b66d3e 100644
>>> --- a/include/linux/irqchip.h
>>> +++ b/include/linux/irqchip.h
>>> @@ -11,6 +11,7 @@
>>>   #ifndef _LINUX_IRQCHIP_H
>>>   #define _LINUX_IRQCHIP_H
>>>
>>> +#include <linux/acpi.h>
>>>   #include <linux/of.h>
>>>
>>>   /*
>>> @@ -25,6 +26,18 @@
>>>    */
>>>   #define IRQCHIP_DECLARE(name, compat, fn) OF_DECLARE_2(irqchip, name, compat, fn)
>>>
>>> +/*
>>> + * This macro must be used by the different ARM GIC drivers to declare
>>> + * the association between their version and their initialization function.
>>> + *
>>> + * @name: name that must be unique accross all IRQCHIP_ACPI_DECLARE of the
>>> + * same file.
>>> + * @gic_version: version of GIC
>>> + * @fn: initialization function
>>> + */
>>> +#define IRQCHIP_ACPI_DECLARE(name, gic_version, fn)	\
>>> +	ACPI_DECLARE(irqchip, name, ACPI_SIG_MADT, gic_version, fn)
>>
>> I don't think this is the right approach. The MADT table has a *huge*
>> number of possible subtables, and none of them is matched by the GIC
>> version.
>>
>> What you *really* want is MADT -> GICD -> GIC type. Your ACPI_DECLARE
>> macro doesn't reflect this at all (you've basically cloned OF, and
>> that's clearly not good enough).
>>
>> This probably require an intermediate matching function, ending up with
>> something like:
>>
>> #define IRQCHIP_ACPI_DECLARE(name, subtable, version, fn) \
>> 	ACPI_DECLARE(irqchip, name, ACPI_SIG_MADT, match_madt_subtable,\
>> 		subtable, version, fn)
>>
>> where match_madt_subtable is going to check that a given subtable is
>> really suitable for a given irqchip. None of that should be GIC
>> specific, really.
> 
> I'm little confused here, in the previous patch, the gic version is
> stored, so we only need to match the GIC driver with the gic version.
> 
> In the GIC dirver itself, we will match the madt subtable to find
> information we need to init the GIC, so I'm not sure why
> match_madt_subtable in the ACPI_DECLARE, I think I missed something,
> please correct me.

What you're missing is that it should be possible to use
IRQCHIP_ACPI_DECLARE with something that is *not* a GIC. It shouldn't be
GIC specific in any way.

You must have a generic way of describing a match in a table by naming
one of its structures, and possibly a type value inside this structures.

I want to be able to write something like:

IRQCHIP_ACPI_DECLARE(ioapic, ACPI_IOAPIC, 0, ioacpi_acpi_probe);

where ACPI_IOAPIC is 1 (the type for the IOAPIC structure in the MADT
table).

For GICv3, I want to be able to write:

IRQCHIP_ACPI_DECLARE(gicv3, ACPI_GICD, ACPI_GICD_GICV3, \
                     gicv3_acpi_probe);

where ACPI_GICD is 0xC, and ACPI_GICD_GICV3 is 3.

Do you see what I'm aiming for? We follow the spec, strictly the spec,
but all the spec. No shortcut that only ends up matching the GIC in MADT.

Thanks,

	M.
-- 
Jazz is not dead. It just smells funny...


From benoar at dolka.fr  Thu Aug  6 09:29:52 2015
From: benoar at dolka.fr (Benjamin Cama)
Date: Thu, 06 Aug 2015 18:29:52 +0200
Subject: [PATCH v3] ARM: dts: Convert Linkstation Mini to Device Tree
Message-ID: <1438878592.15635.89.camel@dolka.fr>

The title says it all. The name of the dts file as been changed to
better reflect the manufacturer's device name (LS-WSGL), rather than
the original "lsmini", which exists in a kirkwood version too.

Signed-off-by: Benjamin Cama <benoar at dolka.fr>
---
Since v2, I re-ordered the dts in the Makefile, and removed the
makefile rule for the old .c file.

Thanks everyone for your support in guiding me to make the patch
acceptable.

 arch/arm/boot/dts/Makefile           |   1 +
 arch/arm/boot/dts/orion5x-lswsgl.dts | 276 ++++++++++++++++++++++++++++++++++
 arch/arm/mach-orion5x/Kconfig        |   6 +-
 arch/arm/mach-orion5x/Makefile       |   1 -
 arch/arm/mach-orion5x/lsmini-setup.c | 280 -----------------------------------
 5 files changed, 280 insertions(+), 284 deletions(-)
 create mode 100644 arch/arm/boot/dts/orion5x-lswsgl.dts
 delete mode 100644 arch/arm/mach-orion5x/lsmini-setup.c

diff --git a/arch/arm/boot/dts/Makefile b/arch/arm/boot/dts/Makefile
index 992736b..65fc046 100644
--- a/arch/arm/boot/dts/Makefile
+++ b/arch/arm/boot/dts/Makefile
@@ -440,6 +440,7 @@ dtb-$(CONFIG_SOC_DRA7XX) += \
 dtb-$(CONFIG_ARCH_ORION5X) += \
 	orion5x-lacie-d2-network.dtb \
 	orion5x-lacie-ethernet-disk-mini-v2.dtb \
+	orion5x-lswsgl.dtb \
 	orion5x-maxtor-shared-storage-2.dtb \
 	orion5x-rd88f5182-nas.dtb
 dtb-$(CONFIG_ARCH_PRIMA2) += \
diff --git a/arch/arm/boot/dts/orion5x-lswsgl.dts b/arch/arm/boot/dts/orion5x-lswsgl.dts
new file mode 100644
index 0000000..34816a9
--- /dev/null
+++ b/arch/arm/boot/dts/orion5x-lswsgl.dts
@@ -0,0 +1,276 @@
+/*
+ * Copyright (C) 2015 Benjamin Cama <benoar at dolka.fr>
+ * Copyright (C) 2014 Thomas Petazzoni <thomas.petazzoni at free-electrons.com>
+ * Based on the board file arch/arm/mach-orion5x/lsmini-setup.c,
+ * Copyright (C) 2008 Alexey Kopytko <alexey at kopytko.ru>
+ *
+ * This file is dual-licensed: you can use it either under the terms
+ * of the GPL or the X11 license, at your option. Note that this dual
+ * licensing only applies to this file, and not this project as a
+ * whole.
+ *
+ *  a) This file is free software; you can redistribute it and/or
+ *     modify it under the terms of the GNU General Public License as
+ *     published by the Free Software Foundation; either version 2 of the
+ *     License, or (at your option) any later version.
+ *
+ *     This file is distributed in the hope that it will be useful
+ *     but WITHOUT ANY WARRANTY; without even the implied warranty of
+ *     MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ *     GNU General Public License for more details.
+ *
+ * Or, alternatively
+ *
+ *  b) Permission is hereby granted, free of charge, to any person
+ *     obtaining a copy of this software and associated documentation
+ *     files (the "Software"), to deal in the Software without
+ *     restriction, including without limitation the rights to use
+ *     copy, modify, merge, publish, distribute, sublicense, and/or
+ *     sell copies of the Software, and to permit persons to whom the
+ *     Software is furnished to do so, subject to the following
+ *     conditions:
+ *
+ *     The above copyright notice and this permission notice shall be
+ *     included in all copies or substantial portions of the Software.
+ *
+ *     THE SOFTWARE IS PROVIDED , WITHOUT WARRANTY OF ANY KIND
+ *     EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES
+ *     OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
+ *     NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT
+ *     HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY
+ *     WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
+ *     FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR
+ *     OTHER DEALINGS IN THE SOFTWARE.
+ */
+
+/dts-v1/;
+
+#include <dt-bindings/gpio/gpio.h>
+#include <dt-bindings/input/input.h>
+#include <dt-bindings/interrupt-controller/irq.h>
+#include "orion5x-mv88f5182.dtsi"
+
+/ {
+	model = "Buffalo Linkstation Mini (LS-WSGL)";
+	compatible = "buffalo,lswsgl", "marvell,orion5x-88f5182", "marvell,orion5x";
+
+	memory {
+		reg = <0x00000000 0x8000000>; /* 128 MB */
+	};
+
+	chosen {
+		bootargs = "console=ttyS0,115200 earlyprintk";
+		linux,stdout-path = &uart0;
+	};
+
+	soc {
+		ranges = <MBUS_ID(0xf0, 0x01) 0 0xf1000000 0x100000>,
+			 <MBUS_ID(0x09, 0x00) 0 0xf2200000 0x800>,
+			 <MBUS_ID(0x01, 0x0f) 0 0xf4000000 0x40000>;
+	};
+
+	gpio-keys {
+		compatible = "gpio-keys";
+		pinctrl-0 = <&pmx_buttons>;
+		pinctrl-names = "default";
+		#address-cells = <1>;
+		#size-cells = <0>;
+		func {
+			label = "Function Button";
+			linux,code = <KEY_OPTION>;
+			gpios = <&gpio0 15 GPIO_ACTIVE_LOW>;
+		};
+
+		power {
+			label = "Power-on Switch";
+			linux,input-type = <5>; /* EV_SW */
+			linux,code = <KEY_RESERVED>; /* LSMINI_SW_POWER */
+			gpios = <&gpio0 18 GPIO_ACTIVE_LOW>;
+		};
+
+		autopower {
+			label = "Power-auto Switch";
+			linux,input-type = <5>; /* EV_SW */
+			linux,code = <KEY_ESC>; /* LSMINI_SW_AUTOPOWER */
+			gpios = <&gpio0 17 GPIO_ACTIVE_LOW>;
+		};
+	};
+
+	gpio-leds {
+		compatible = "gpio-leds";
+		pinctrl-0 = <&pmx_led_alarm &pmx_led_info &pmx_led_func
+			     &pmx_led_power>;
+		pinctrl-names = "default";
+
+		alarm {
+			label = "lswsgl:alarm:red";
+			gpio = <&gpio0 2 GPIO_ACTIVE_LOW>;
+		};
+
+		info {
+			label = "lswsgl:info:amber";
+			gpio = <&gpio0 3 GPIO_ACTIVE_LOW>;
+		};
+
+		func {
+			label = "lswsgl:func:blue:top";
+			gpio = <&gpio0 9 GPIO_ACTIVE_LOW>;
+		};
+
+		power {
+			label = "lswsgl:power:blue:bottom";
+			gpio = <&gpio0 14 GPIO_ACTIVE_LOW>;
+			default-state = "on";
+		};
+	};
+
+	restart_poweroff {
+		compatible = "restart-poweroff";
+	};
+
+	regulators {
+		compatible = "simple-bus";
+		#address-cells = <1>;
+		#size-cells = <0>;
+		pinctrl-0 = <&pmx_sata0_power &pmx_sata1_power &pmx_usb_power>;
+		pinctrl-names = "default";
+
+		sata0_power: regulator at 0 {
+			compatible = "regulator-fixed";
+			reg = <0>;
+			regulator-name = "SATA0 Power";
+			regulator-min-microvolt = <5000000>;
+			regulator-max-microvolt = <5000000>;
+			enable-active-high;
+			regulator-always-on;
+			regulator-boot-on;
+			gpio = <&gpio0 1 GPIO_ACTIVE_HIGH>;
+		};
+
+		sata1_power: regulator at 1 {
+			compatible = "regulator-fixed";
+			reg = <1>;
+			regulator-name = "SATA1 Power";
+			regulator-min-microvolt = <5000000>;
+			regulator-max-microvolt = <5000000>;
+			enable-active-high;
+			regulator-always-on;
+			regulator-boot-on;
+			gpio = <&gpio0 19 GPIO_ACTIVE_HIGH>;
+		};
+
+		usb_power: regulator at 2 {
+			compatible = "regulator-fixed";
+			reg = <2>;
+			regulator-name = "USB Power";
+			regulator-min-microvolt = <5000000>;
+			regulator-max-microvolt = <5000000>;
+			enable-active-high;
+			regulator-always-on;
+			regulator-boot-on;
+			gpio = <&gpio0 16 GPIO_ACTIVE_HIGH>;
+		};
+	};
+};
+
+&devbus_bootcs {
+	status = "okay";
+
+	devbus,keep-config;
+
+	flash at 0 {
+		compatible = "cfi-flash";
+		reg = <0 0x40000>;
+		bank-width = <1>;
+                #address-cells = <1>;
+		#size-cells = <1>;
+
+		partition at 0 {
+			label = "Full256Kb";
+			reg = <0 0x40000>;
+			read-only;
+		};
+	};
+};
+
+&mdio {
+	status = "okay";
+
+	ethphy: ethernet-phy {
+		reg = <8>;
+	};
+};
+
+&ehci0 {
+	status = "okay";
+};
+
+&eth {
+	status = "okay";
+
+	ethernet-port at 0 {
+		phy-handle = <&ethphy>;
+	};
+};
+
+&i2c {
+	status = "okay";
+	clock-frequency = <100000>;
+	#address-cells = <1>;
+
+	rtc at 32 {
+		compatible = "ricoh,rs5c372a";
+		reg = <0x32>;
+	};
+};
+
+&pinctrl {
+	pmx_buttons: pmx-buttons {
+		marvell,pins = "mpp15", "mpp17", "mpp18";
+		marvell,function = "gpio";
+	};
+
+	pmx_led_alarm: pmx-leds {
+		marvell,pins = "mpp2";
+		marvell,function = "gpio";
+	};
+
+	pmx_led_info: pmx-leds {
+		marvell,pins = "mpp3";
+		marvell,function = "gpio";
+	};
+
+	pmx_led_func: pmx-leds {
+		marvell,pins = "mpp9";
+		marvell,function = "gpio";
+	};
+
+	pmx_led_power: pmx-leds {
+		marvell,pins = "mpp14";
+		marvell,function = "gpio";
+	};
+
+	pmx_sata0_power: pmx-sata0-power {
+		marvell,pins = "mpp1";
+		marvell,function = "gpio";
+	};
+
+	pmx_sata1_power: pmx-sata1-power {
+		marvell,pins = "mpp19";
+		marvell,function = "gpio";
+	};
+
+	pmx_usb_power: pmx-usb-power {
+		marvell,pins = "mpp16";
+		marvell,function = "gpio";
+	};
+};
+
+&sata {
+	status = "okay";
+	nr-ports = <2>;
+};
+
+&uart0 {
+	status = "okay";
+};
diff --git a/arch/arm/mach-orion5x/Kconfig b/arch/arm/mach-orion5x/Kconfig
index 2412efb..08d2be2 100644
--- a/arch/arm/mach-orion5x/Kconfig
+++ b/arch/arm/mach-orion5x/Kconfig
@@ -78,11 +78,11 @@ config MACH_LINKSTATION_LSCHL
 	  Buffalo Linkstation Live v3 (LS-CHL) platform.
 
 config MACH_LINKSTATION_MINI
-	bool "Buffalo Linkstation Mini"
-	select I2C_BOARDINFO
+	bool "Buffalo Linkstation Mini (Flattened Device Tree)"
+	select ARCH_ORION5X_DT
 	help
 	  Say 'Y' here if you want your kernel to support the
-	  Buffalo Linkstation Mini platform.
+	  Buffalo Linkstation Mini (LS-WSGL) platform.
 
 config MACH_LINKSTATION_LS_HGL
 	bool "Buffalo Linkstation LS-HGL"
diff --git a/arch/arm/mach-orion5x/Makefile b/arch/arm/mach-orion5x/Makefile
index a40b5c9..a1e0fbe 100644
--- a/arch/arm/mach-orion5x/Makefile
+++ b/arch/arm/mach-orion5x/Makefile
@@ -4,7 +4,6 @@ obj-$(CONFIG_MACH_RD88F5182)	+= rd88f5182-setup.o
 obj-$(CONFIG_MACH_KUROBOX_PRO)	+= kurobox_pro-setup.o
 obj-$(CONFIG_MACH_TERASTATION_PRO2)	+= terastation_pro2-setup.o
 obj-$(CONFIG_MACH_LINKSTATION_PRO) += kurobox_pro-setup.o
-obj-$(CONFIG_MACH_LINKSTATION_MINI) += lsmini-setup.o
 obj-$(CONFIG_MACH_LINKSTATION_LS_HGL) += ls_hgl-setup.o
 obj-$(CONFIG_MACH_DNS323)	+= dns323-setup.o
 obj-$(CONFIG_MACH_TS209)	+= ts209-setup.o tsx09-common.o
diff --git a/arch/arm/mach-orion5x/lsmini-setup.c b/arch/arm/mach-orion5x/lsmini-setup.c
deleted file mode 100644
index a6493e7..0000000
--- a/arch/arm/mach-orion5x/lsmini-setup.c
+++ /dev/null
@@ -1,280 +0,0 @@
-/*
- * arch/arm/mach-orion5x/lsmini-setup.c
- *
- * Maintainer: Alexey Kopytko <alexey at kopytko.ru>
- *
- * This file is licensed under the terms of the GNU General Public
- * License version 2.  This program is licensed "as is" without any
- * warranty of any kind, whether express or implied.
- */
-
-#include <linux/kernel.h>
-#include <linux/init.h>
-#include <linux/platform_device.h>
-#include <linux/mtd/physmap.h>
-#include <linux/mv643xx_eth.h>
-#include <linux/leds.h>
-#include <linux/gpio_keys.h>
-#include <linux/input.h>
-#include <linux/i2c.h>
-#include <linux/ata_platform.h>
-#include <linux/gpio.h>
-#include <asm/mach-types.h>
-#include <asm/mach/arch.h>
-#include <mach/orion5x.h>
-#include "common.h"
-#include "mpp.h"
-
-/*****************************************************************************
- * Linkstation Mini Info
- ****************************************************************************/
-
-/*
- * 256K NOR flash Device bus boot chip select
- */
-
-#define LSMINI_NOR_BOOT_BASE	0xf4000000
-#define LSMINI_NOR_BOOT_SIZE	SZ_256K
-
-/*****************************************************************************
- * 256KB NOR Flash on BOOT Device
- ****************************************************************************/
-
-static struct physmap_flash_data lsmini_nor_flash_data = {
-	.width		= 1,
-};
-
-static struct resource lsmini_nor_flash_resource = {
-	.flags	= IORESOURCE_MEM,
-	.start	= LSMINI_NOR_BOOT_BASE,
-	.end	= LSMINI_NOR_BOOT_BASE + LSMINI_NOR_BOOT_SIZE - 1,
-};
-
-static struct platform_device lsmini_nor_flash = {
-	.name			= "physmap-flash",
-	.id			= 0,
-	.dev		= {
-		.platform_data	= &lsmini_nor_flash_data,
-	},
-	.num_resources		= 1,
-	.resource		= &lsmini_nor_flash_resource,
-};
-
-/*****************************************************************************
- * Ethernet
- ****************************************************************************/
-
-static struct mv643xx_eth_platform_data lsmini_eth_data = {
-	.phy_addr	= 8,
-};
-
-/*****************************************************************************
- * RTC 5C372a on I2C bus
- ****************************************************************************/
-
-static struct i2c_board_info __initdata lsmini_i2c_rtc = {
-	I2C_BOARD_INFO("rs5c372a", 0x32),
-};
-
-/*****************************************************************************
- * LEDs attached to GPIO
- ****************************************************************************/
-
-#define LSMINI_GPIO_LED_ALARM	2
-#define LSMINI_GPIO_LED_INFO	3
-#define LSMINI_GPIO_LED_FUNC	9
-#define LSMINI_GPIO_LED_PWR	14
-
-static struct gpio_led lsmini_led_pins[] = {
-	{
-		.name	   = "alarm:red",
-		.gpio	   = LSMINI_GPIO_LED_ALARM,
-		.active_low     = 1,
-	}, {
-		.name	   = "info:amber",
-		.gpio	   = LSMINI_GPIO_LED_INFO,
-		.active_low     = 1,
-	}, {
-		.name	   = "func:blue:top",
-		.gpio	   = LSMINI_GPIO_LED_FUNC,
-		.active_low     = 1,
-	}, {
-		.name	   = "power:blue:bottom",
-		.gpio	   = LSMINI_GPIO_LED_PWR,
-	},
-};
-
-static struct gpio_led_platform_data lsmini_led_data = {
-	.leds	   = lsmini_led_pins,
-	.num_leds       = ARRAY_SIZE(lsmini_led_pins),
-};
-
-static struct platform_device lsmini_leds = {
-	.name   = "leds-gpio",
-	.id     = -1,
-	.dev    = {
-		.platform_data  = &lsmini_led_data,
-	},
-};
-
-/****************************************************************************
- * GPIO Attached Keys
- ****************************************************************************/
-
-#define LSMINI_GPIO_KEY_FUNC       15
-#define LSMINI_GPIO_KEY_POWER	   18
-#define LSMINI_GPIO_KEY_AUTOPOWER 17
-
-#define LSMINI_SW_POWER		0x00
-#define LSMINI_SW_AUTOPOWER	0x01
-
-static struct gpio_keys_button lsmini_buttons[] = {
-	{
-		.code	   = KEY_OPTION,
-		.gpio	   = LSMINI_GPIO_KEY_FUNC,
-		.desc	   = "Function Button",
-		.active_low     = 1,
-	}, {
-		.type		= EV_SW,
-		.code	   = LSMINI_SW_POWER,
-		.gpio	   = LSMINI_GPIO_KEY_POWER,
-		.desc	   = "Power-on Switch",
-		.active_low     = 1,
-	}, {
-		.type		= EV_SW,
-		.code	   = LSMINI_SW_AUTOPOWER,
-		.gpio	   = LSMINI_GPIO_KEY_AUTOPOWER,
-		.desc	   = "Power-auto Switch",
-		.active_low     = 1,
-	},
-};
-
-static struct gpio_keys_platform_data lsmini_button_data = {
-	.buttons	= lsmini_buttons,
-	.nbuttons       = ARRAY_SIZE(lsmini_buttons),
-};
-
-static struct platform_device lsmini_button_device = {
-	.name	   = "gpio-keys",
-	.id	     = -1,
-	.num_resources  = 0,
-	.dev	    = {
-		.platform_data  = &lsmini_button_data,
-	},
-};
-
-
-/*****************************************************************************
- * SATA
- ****************************************************************************/
-static struct mv_sata_platform_data lsmini_sata_data = {
-	.n_ports	= 2,
-};
-
-
-/*****************************************************************************
- * Linkstation Mini specific power off method: reboot
- ****************************************************************************/
-/*
- * On the Linkstation Mini, the shutdown process is following:
- * - Userland monitors key events until the power switch goes to off position
- * - The board reboots
- * - U-boot starts and goes into an idle mode waiting for the user
- *   to move the switch to ON position
- */
-
-static void lsmini_power_off(void)
-{
-	orion5x_restart(REBOOT_HARD, NULL);
-}
-
-
-/*****************************************************************************
- * General Setup
- ****************************************************************************/
-
-#define LSMINI_GPIO_USB_POWER	16
-#define LSMINI_GPIO_AUTO_POWER	17
-#define LSMINI_GPIO_POWER	18
-
-#define LSMINI_GPIO_HDD_POWER0	1
-#define LSMINI_GPIO_HDD_POWER1	19
-
-static unsigned int lsmini_mpp_modes[] __initdata = {
-	MPP0_UNUSED, /* LED_RESERVE1 (unused) */
-	MPP1_GPIO, /* HDD_PWR */
-	MPP2_GPIO, /* LED_ALARM */
-	MPP3_GPIO, /* LED_INFO */
-	MPP4_UNUSED,
-	MPP5_UNUSED,
-	MPP6_UNUSED,
-	MPP7_UNUSED,
-	MPP8_UNUSED,
-	MPP9_GPIO, /* LED_FUNC */
-	MPP10_UNUSED,
-	MPP11_UNUSED, /* LED_ETH (dummy) */
-	MPP12_UNUSED,
-	MPP13_UNUSED,
-	MPP14_GPIO, /* LED_PWR */
-	MPP15_GPIO, /* FUNC */
-	MPP16_GPIO, /* USB_PWR */
-	MPP17_GPIO, /* AUTO_POWER */
-	MPP18_GPIO, /* POWER */
-	MPP19_GPIO, /* HDD_PWR1 */
-	0,
-};
-
-static void __init lsmini_init(void)
-{
-	/*
-	 * Setup basic Orion functions. Need to be called early.
-	 */
-	orion5x_init();
-
-	orion5x_mpp_conf(lsmini_mpp_modes);
-
-	/*
-	 * Configure peripherals.
-	 */
-	orion5x_ehci0_init();
-	orion5x_ehci1_init();
-	orion5x_eth_init(&lsmini_eth_data);
-	orion5x_i2c_init();
-	orion5x_sata_init(&lsmini_sata_data);
-	orion5x_uart0_init();
-	orion5x_xor_init();
-
-	mvebu_mbus_add_window_by_id(ORION_MBUS_DEVBUS_BOOT_TARGET,
-				    ORION_MBUS_DEVBUS_BOOT_ATTR,
-				    LSMINI_NOR_BOOT_BASE,
-				    LSMINI_NOR_BOOT_SIZE);
-	platform_device_register(&lsmini_nor_flash);
-
-	platform_device_register(&lsmini_button_device);
-
-	platform_device_register(&lsmini_leds);
-
-	i2c_register_board_info(0, &lsmini_i2c_rtc, 1);
-
-	/* enable USB power */
-	gpio_set_value(LSMINI_GPIO_USB_POWER, 1);
-
-	/* register power-off method */
-	pm_power_off = lsmini_power_off;
-
-	pr_info("%s: finished\n", __func__);
-}
-
-#ifdef CONFIG_MACH_LINKSTATION_MINI
-MACHINE_START(LINKSTATION_MINI, "Buffalo Linkstation Mini")
-	/* Maintainer: Alexey Kopytko <alexey at kopytko.ru> */
-	.atag_offset	= 0x100,
-	.init_machine	= lsmini_init,
-	.map_io		= orion5x_map_io,
-	.init_early	= orion5x_init_early,
-	.init_irq	= orion5x_init_irq,
-	.init_time	= orion5x_timer_init,
-	.fixup		= tag_fixup_mem32,
-	.restart	= orion5x_restart,
-MACHINE_END
-#endif
-- 
2.1.4



From robin.murphy at arm.com  Thu Aug  6 09:31:24 2015
From: robin.murphy at arm.com (Robin Murphy)
Date: Thu, 06 Aug 2015 17:31:24 +0100
Subject: [PATCH V2] iommu/arm-smmu-v2: ThunderX mis-extends 64bit registers
In-Reply-To: <20150806161625.GJ25483@arm.com>
References: <1438793668-15597-1-git-send-email-tchalamarla@caviumnetworks.com>
 <20150806161625.GJ25483@arm.com>
Message-ID: <55C38BDC.4030304@arm.com>

On 06/08/15 17:16, Will Deacon wrote:
> Hi Tirumalesh,
>
> I think this looks pretty good now, just one small comment below.
>
> On Wed, Aug 05, 2015 at 05:54:28PM +0100, Tirumalesh Chalamarla wrote:
[...]
>> -#define TTBRn_HI_ASID_SHIFT            16
>> +#define TTBRn_ASID_SHIFT		48
>>
>>   #define FSR_MULTI			(1 << 31)
>>   #define FSR_SS				(1 << 30)
>> @@ -762,22 +774,17 @@ static void arm_smmu_init_context_bank(struct arm_smmu_domain *smmu_domain,
>>
>>   	/* TTBRs */
>>   	if (stage1) {
>> -		reg = pgtbl_cfg->arm_lpae_s1_cfg.ttbr[0];
>> -		writel_relaxed(reg, cb_base + ARM_SMMU_CB_TTBR0_LO);
>> -		reg = pgtbl_cfg->arm_lpae_s1_cfg.ttbr[0] >> 32;
>> -		reg |= ARM_SMMU_CB_ASID(cfg) << TTBRn_HI_ASID_SHIFT;
>> -		writel_relaxed(reg, cb_base + ARM_SMMU_CB_TTBR0_HI);
>> -
>> -		reg = pgtbl_cfg->arm_lpae_s1_cfg.ttbr[1];
>> -		writel_relaxed(reg, cb_base + ARM_SMMU_CB_TTBR1_LO);
>> -		reg = pgtbl_cfg->arm_lpae_s1_cfg.ttbr[1] >> 32;
>> -		reg |= ARM_SMMU_CB_ASID(cfg) << TTBRn_HI_ASID_SHIFT;
>> -		writel_relaxed(reg, cb_base + ARM_SMMU_CB_TTBR1_HI);
>> +		u64 reg64 = pgtbl_cfg->arm_lpae_s1_cfg.ttbr[0];
>
> Can we move this declaration to the start of the function along with
> u32 reg, please? It's used in both cases of the if/else block so it
> might be a tad cleaner.

We could also drop the _LO suffix from the relevant #defines (so they 
match the architectural names) and remove the now-unused _HI versions 
entirely.

Robin.

>
> Will
> _______________________________________________
> iommu mailing list
> iommu at lists.linux-foundation.org
> https://lists.linuxfoundation.org/mailman/listinfo/iommu
>



From p.zabel at pengutronix.de  Thu Aug  6 09:33:55 2015
From: p.zabel at pengutronix.de (Philipp Zabel)
Date: Thu, 06 Aug 2015 18:33:55 +0200
Subject: [PATCH 1/3] nvmem: Add i.MX6 OCOTP device tree binding
 documentation
In-Reply-To: <55C38752.3040406@linaro.org>
References: <1438693342-605-1-git-send-email-p.zabel@pengutronix.de>
 <55C38752.3040406@linaro.org>
Message-ID: <1438878835.3223.14.camel@pengutronix.de>

Am Donnerstag, den 06.08.2015, 17:12 +0100 schrieb Srinivas Kandagatla:
> 
> On 04/08/15 14:02, Philipp Zabel wrote:
> > This patch documents the i.MX6 OCOTP device tree binding.
> >
> > Signed-off-by: Philipp Zabel <p.zabel at pengutronix.de>
> > ---
> >   .../devicetree/bindings/nvmem/imx-ocotp.txt          | 20 ++++++++++++++++++++
> >   1 file changed, 20 insertions(+)
> >   create mode 100644 Documentation/devicetree/bindings/nvmem/imx-ocotp.txt
> >
> > diff --git a/Documentation/devicetree/bindings/nvmem/imx-ocotp.txt b/Documentation/devicetree/bindings/nvmem/imx-ocotp.txt
> > new file mode 100644
> > index 0000000..7d9a3fc
> > --- /dev/null
> > +++ b/Documentation/devicetree/bindings/nvmem/imx-ocotp.txt
> > @@ -0,0 +1,20 @@
> > +Freescale i.MX6 On-Chip OTP Controller (OCOTP) device tree bindings
> > +
> > +This binding represents the on-chip eFuse OTP controller found on
> > +i.MX6Q/D, i.MX6DL/S, i.MX6SL, and i.MX6SX SoCs.
> > +
> > +Required properties:
> > +- compatible: should be one of
> > +	"fsl,imx6q-ocotp" (i.MX6Q/D/DL/S),
> > +        "fsl,imx6sl-ocotp" (i.MX6SL), or
> > +	"fsl,imx6sx-ocotp" (i.MX6SX), followed by "syscon".
> > +- reg: Should contain the register base and length.
> > +- clocks: Should contain a phandle pointing to the gated peripheral clock.
> > +
> > +Example:
> > +
> > +	ocotp: ocotp at 021bc000 {
> > +		compatible = "fsl,imx6q-ocotp", "syscon";
> Do you still need syscon?

Currently the imx_tempmon driver still accesses ocotp via syscon. I'd
like to change that and drop "syscon" after the nvmem framework lands in
mainline.

> > +		reg = <0x021bc000 0x4000>;
> Can't we just have a register range specific to the OTP device?

In the i.MX device trees it is common to specify the register range from
the memory map. In any case, we have to support old device trees where
this is already set.

regards
Philipp



From andrew at lunn.ch  Thu Aug  6 09:34:24 2015
From: andrew at lunn.ch (Andrew Lunn)
Date: Thu, 6 Aug 2015 18:34:24 +0200
Subject: [PATCH v3] ARM: dts: Convert Linkstation Mini to Device Tree
In-Reply-To: <1438878592.15635.89.camel@dolka.fr>
References: <1438878592.15635.89.camel@dolka.fr>
Message-ID: <20150806163424.GH13421@lunn.ch>

On Thu, Aug 06, 2015 at 06:29:52PM +0200, Benjamin Cama wrote:
> The title says it all. The name of the dts file as been changed to
> better reflect the manufacturer's device name (LS-WSGL), rather than
> the original "lsmini", which exists in a kirkwood version too.
> 
> Signed-off-by: Benjamin Cama <benoar at dolka.fr>

Hi Benjamin

It would be normal to add the various Acked-by: here, both Alexey and
mine. It is not an issue, Gregory can add them, when he adds is own.
I'm just mentioning it for any future patches you might submit.

Thanks for the good work converting this,

       Andrew


From lftan.linux at gmail.com  Thu Aug  6 09:41:53 2015
From: lftan.linux at gmail.com (Ley Foon Tan)
Date: Fri, 7 Aug 2015 00:41:53 +0800
Subject: [PATCH v5 9/9] PCI: xgene: Use pci_scan_root_bus_msi()
In-Reply-To: <55C37C92.1020509@arm.com>
References: <20150804214234.9189.42548.stgit@bhelgaas-glaptop2.roam.corp.google.com>
 <20150804215457.9189.27595.stgit@bhelgaas-glaptop2.roam.corp.google.com>
 <55C37C92.1020509@arm.com>
Message-ID: <CAFiDJ58U9u0YOzqVbty8+z+sF82h=F09Y0q-Ks8zMDokdiSEbg@mail.gmail.com>

On Thu, Aug 6, 2015 at 11:26 PM, Marc Zyngier <marc.zyngier at arm.com> wrote:
> Hi Bjorn,
>
> On 04/08/15 22:54, Bjorn Helgaas wrote:
>> Previously there was no way to specify the MSI controller when creating a
>> new PCI root bus, so we had to create the bus, set its MSI controller, then
>> scan the bus.  With the new pci_scan_root_bus_msi() interface, we can
>> specify the MSI controller up front and get rid of that intermediate step.
>>
>> Look up the MSI controller first, then use pci_scan_root_bus_msi() to
>> create and scan the root PCI bus.
>
> I'm wondering about these XGene patches.
>
> With the code that is queued for v4.3 in tip/irq/core, the X-Gene MSI
> driver doesn't export a struct msi_controller anymore, and entirely
> relies on IRQ domains to identify to be matched with the actual PCI driver.
>
> Do you intend this as a cleanup until everything lands in mainline? At
> that point, we'd be able to remove all traces of struct msi_controller
> from this driver.
>
> Alternatively, we could ask tglx to add an extra patch to the existing
> queue in order to clean up pci-xgene.c (nuking the whole
> xgene_pcie_msi_enable function).
>
> Thoughts?

In pcie-altera driver, it uses pci_scan_root_bus() and it doesn't call
to of_pci_find_msi_chip_by_node() to retrieve msi_controller struct as
well.
But, the msi domain stuff is still working. Should I change it to
pci_scan_root_bus_msi()?

Regards
Ley Foon


From marc.zyngier at arm.com  Thu Aug  6 09:42:01 2015
From: marc.zyngier at arm.com (Marc Zyngier)
Date: Thu, 06 Aug 2015 17:42:01 +0100
Subject: [PATCH v4 06/10] irqchip / GICv3: Add ACPI support for GICv3+
 initialization
In-Reply-To: <55C21709.3070907@linaro.org>
References: <1438164539-29256-1-git-send-email-hanjun.guo@linaro.org>
 <1438164539-29256-7-git-send-email-hanjun.guo@linaro.org>
 <55C0BB5E.2080706@arm.com> <55C21709.3070907@linaro.org>
Message-ID: <55C38E59.9090802@arm.com>

On 05/08/15 15:00, Hanjun Guo wrote:
> On 08/04/2015 09:17 PM, Marc Zyngier wrote:
>> On 29/07/15 11:08, Hanjun Guo wrote:
>>> From: Tomasz Nowicki <tomasz.nowicki at linaro.org>
>>>
>>> With the refator of gic_of_init(), GICv3/4 can be initialized
>>> by gic_init_bases() with gic distributor base address and gic
>>> redistributor region(s).
>>>
>>> So get the redistributor region base addresses from MADT GIC
>>> redistributor subtable, and the distributor base address from
>>> GICD subtable to init GICv3 irqchip in ACPI way.
>>>
>>> Note: GIC redistributor base address may also be provided in
>>> GICC structures on systems supporting GICv3 and above if the GIC
>>> Redistributors are not in the always-on power domain, this
>>> patch didn't implement such feature yet.
>>>
>>> Signed-off-by: Tomasz Nowicki <tomasz.nowicki at linaro.org>
>>> [hj: Rework this patch and fix multi issues]
>>> Signed-off-by: Hanjun Guo <hanjun.guo at linaro.org>
>>> ---
>>>   drivers/irqchip/irq-gic-v3.c | 174 +++++++++++++++++++++++++++++++++++++++++--
>>>   1 file changed, 169 insertions(+), 5 deletions(-)
>>>
>>> diff --git a/drivers/irqchip/irq-gic-v3.c b/drivers/irqchip/irq-gic-v3.c
>>> index c0b96c6..ebc5604 100644
>>> --- a/drivers/irqchip/irq-gic-v3.c
>>> +++ b/drivers/irqchip/irq-gic-v3.c
>>> @@ -15,6 +15,7 @@
>>>    * along with this program.  If not, see <http://www.gnu.org/licenses/>.
>>>    */
>>>
>>> +#include <linux/acpi.h>
>>>   #include <linux/cpu.h>
>>>   #include <linux/cpu_pm.h>
>>>   #include <linux/delay.h>
>>> @@ -25,6 +26,7 @@
>>>   #include <linux/percpu.h>
>>>   #include <linux/slab.h>
>>>
>>> +#include <linux/irqchip/arm-gic-acpi.h>
>>>   #include <linux/irqchip/arm-gic-v3.h>
>>>
>>>   #include <asm/cputype.h>
>>> @@ -802,7 +804,8 @@ static int __init gic_init_bases(void __iomem *dist_base,
>>>      set_handle_irq(gic_handle_irq);
>>>
>>>      if (IS_ENABLED(CONFIG_ARM_GIC_V3_ITS) && gic_dist_supports_lpis())
>>> -            its_init(domain_token, &gic_data.rdists, gic_data.domain);
>>> +            its_init(irq_domain_token_to_of_node(domain_token),
>>> +                     &gic_data.rdists, gic_data.domain);
>>
>> This doesn't make much sense. The first parameter to its_init is indeed
>> supposed to be an of_node, but what is the point of calling its_init if
>> you *know* you don't have the necessary topological information to parse
>> the firmware tables?
>>
>> I don't see *any* code that is going to parse the ITS table in this
>> series, so please don't call its_init passing a NULL pointer to it. This
>> is just gross.
> 
> OK, the ITS ACPI code is in later patch which combined with IORT. How
> about moving it to the GIC of init code temporary?

Just don't call its_init if irq_domain_token_to_of_node(domain_token) is
NULL. But don't call it with a NULL parameter.

>>
>>>
>>>      gic_smp_init();
>>>      gic_dist_init();
>>> @@ -818,6 +821,16 @@ out_free:
>>>      return err;
>>>   }
>>>
>>> +static int __init detect_distributor(void __iomem *dist_base)
>>
>> We do have a naming convention in this file. All functions start with gic_.
>>
>>> +{
>>> +    u32 reg = readl_relaxed(dist_base + GICD_PIDR2) & GIC_PIDR2_ARCH_MASK;
>>> +
>>> +    if (reg != GIC_PIDR2_ARCH_GICv3 && reg != GIC_PIDR2_ARCH_GICv4)
>>> +            return -ENODEV;
>>> +
>>> +    return 0;
>>> +}
>>
>> This function doesn't detect anything, it validates that we have
>> something sensible. Please rename it to gic_validate_dist_version, or
>> something similar.
> 
> Ok.
> 
>>
>>> +
>>>   #ifdef CONFIG_OF
>>>   static int __init gic_of_init(struct device_node *node, struct device_node *parent)
>>>   {
>>> @@ -825,7 +838,6 @@ static int __init gic_of_init(struct device_node *node, struct device_node *pare
>>>      struct redist_region *rdist_regs;
>>>      u64 redist_stride;
>>>      u32 nr_redist_regions;
>>> -    u32 reg;
>>>      int err, i;
>>>
>>>      dist_base = of_iomap(node, 0);
>>> @@ -835,11 +847,10 @@ static int __init gic_of_init(struct device_node *node, struct device_node *pare
>>>              return -ENXIO;
>>>      }
>>>
>>> -    reg = readl_relaxed(dist_base + GICD_PIDR2) & GIC_PIDR2_ARCH_MASK;
>>> -    if (reg != GIC_PIDR2_ARCH_GICv3 && reg != GIC_PIDR2_ARCH_GICv4) {
>>> +    err = detect_distributor(dist_base);
>>> +    if (err) {
>>>              pr_err("%s: no distributor detected, giving up\n",
>>>                      node->full_name);
>>> -            err = -ENODEV;
>>>              goto out_unmap_dist;
>>>      }
>>>
>>> @@ -887,3 +898,156 @@ out_unmap_dist:
>>>
>>>   IRQCHIP_DECLARE(gic_v3, "arm,gic-v3", gic_of_init);
>>>   #endif
>>> +
>>> +#ifdef CONFIG_ACPI
>>> +static struct redist_region *redist_regs __initdata;
>>> +static u32 nr_redist_regions __initdata;
>>> +static phys_addr_t dist_phys_base __initdata;
>>> +
>>> +static int __init
>>> +gic_acpi_register_redist(u64 phys_base, u64 size)
>>
>> A physical address must use phys_addr_t.
> 
> OK.
> 
>>
>>> +{
>>> +    struct redist_region *redist_regs_new;
>>> +    void __iomem *redist_base;
>>> +
>>> +    redist_regs_new = krealloc(redist_regs,
>>> +                               sizeof(*redist_regs) * (nr_redist_regions + 1),
>>> +                               GFP_KERNEL);
>>
>> NAK. If you have multiple regions, you count them, you allocate the
>> right number of regions. This will be far more efficient than doing this
>> realloc dance. It is not like we're not parsing the tables a zillion
>> times already. Doing it one more time won't hurt.
> 
> Agreed, will update in next version.
> 
>>
>>> +    if (!redist_regs_new) {
>>> +            pr_err("Couldn't allocate resource for GICR region\n");
>>> +            return -ENOMEM;
>>> +    }
>>> +
>>> +    redist_regs = redist_regs_new;
>>> +
>>> +    redist_base = ioremap(phys_base, size);
>>> +    if (!redist_base) {
>>> +            pr_err("Couldn't map GICR region @%llx\n", phys_base);
>>> +            return -ENOMEM;
>>> +    }
>>> +
>>> +    redist_regs[nr_redist_regions].phys_base = phys_base;
>>> +    redist_regs[nr_redist_regions].redist_base = redist_base;
>>> +    nr_redist_regions++;
>>> +    return 0;
>>> +}
>>> +
>>> +static int __init
>>> +gic_acpi_parse_madt_redist(struct acpi_subtable_header *header,
>>> +                    const unsigned long end)
>>> +{
>>> +    struct acpi_madt_generic_redistributor *redist;
>>> +
>>> +    if (BAD_MADT_ENTRY(header, end))
>>> +            return -EINVAL;
>>> +
>>> +    redist = (struct acpi_madt_generic_redistributor *)header;
>>> +    if (!redist->base_address)
>>> +            return -EINVAL;
>>> +
>>> +    return gic_acpi_register_redist(redist->base_address, redist->length);
>>> +}
>>> +
>>> +static int __init
>>> +gic_acpi_parse_madt_distributor(struct acpi_subtable_header *header,
>>> +                            const unsigned long end)
>>> +{
>>
>> How many versions of gic_acpi_parse_madt_distributor are we going to
>> get? Why isn't the ACPI parsing in a common file? Why do I have to read
>> the same code on and on until my eyes bleed?
> 
> I will try to move it to common file irq-gic-acpi.c.
> 
>>
>>> +    struct acpi_madt_generic_distributor *dist;
>>> +
>>> +    dist = (struct acpi_madt_generic_distributor *)header;
>>> +
>>> +    if (BAD_MADT_ENTRY(dist, end))
>>> +            return -EINVAL;
>>> +
>>> +    dist_phys_base = dist->base_address;
>>> +    return 0;
>>> +}
>>> +
>>> +static int gic_acpi_gsi_desc_populate(struct acpi_gsi_descriptor *data,
>>> +                                  u32 gsi, unsigned int irq_type)
>>> +{
>>> +    /*
>>> +     * Encode GSI and triggering information the way the GIC likes
>>> +     * them.
>>> +     */
>>> +    if (WARN_ON(gsi < 16))
>>> +            return -EINVAL;
>>> +
>>> +    if (gsi >= 32) {
>>> +            data->param[0] = 0;             /* SPI */
>>> +            data->param[1] = gsi - 32;
>>> +            data->param[2] = irq_type;
>>> +    } else {
>>> +            data->param[0] = 1;             /* PPI */
>>> +            data->param[1] = gsi - 16;
>>> +            data->param[2] = 0xff << 4 | irq_type;
>>> +    }
>>> +
>>> +    data->param_count = 3;
>>> +
>>> +    return 0;
>>> +}
>>> +
>>> +static int __init
>>> +gic_acpi_init(struct acpi_table_header *table)
>>> +{
>>> +    int count, i, err = 0;
>>> +    void __iomem *dist_base;
>>> +
>>> +    /* Get distributor base address */
>>> +    count = acpi_parse_entries(ACPI_SIG_MADT,
>>> +                            sizeof(struct acpi_table_madt),
>>> +                            gic_acpi_parse_madt_distributor, table,
>>> +                            ACPI_MADT_TYPE_GENERIC_DISTRIBUTOR, 0);
>>> +    if (count <= 0) {
>>> +            pr_err("No valid GICD entry exist\n");
>>> +            return -EINVAL;
>>> +    } else if (count > 1) {
>>> +            pr_err("More than one GICD entry detected\n");
>>> +            return -EINVAL;
>>> +    }
>>> +
>>> +    dist_base = ioremap(dist_phys_base, ACPI_GICV3_DIST_MEM_SIZE);
>>> +    if (!dist_base) {
>>> +            pr_err("Unable to map GICD registers\n");
>>> +            return -ENOMEM;
>>> +    }
>>> +
>>> +    err = detect_distributor(dist_base);
>>> +    if (err) {
>>> +            pr_err("No distributor detected at @%p, giving up", dist_base);
>>> +            goto out_dist_unmap;
>>> +    }
>>> +
>>> +    /* Collect redistributor base addresses */
>>> +    count = acpi_parse_entries(ACPI_SIG_MADT,
>>> +                    sizeof(struct acpi_table_madt),
>>> +                    gic_acpi_parse_madt_redist, table,
>>> +                    ACPI_MADT_TYPE_GENERIC_REDISTRIBUTOR, 0);
>>> +    if (count <= 0) {
>>> +            pr_info("No valid GICR entries exist\n");
>>> +            err = -EINVAL;
>>> +            goto out_redist_unmap;
>>> +    }
>>> +
>>> +    err = gic_init_bases(dist_base, redist_regs, nr_redist_regions, 0,
>>> +                         (void *)ACPI_IRQ_MODEL_GIC);
>>
>> There is no other global identifier for GICv3? It feels a bit weird to
>> use the same ID as GICv2 (though probably not harmful as you can't have
>> both as the same time). What are you planning to use for the ITS then?
>> You must make sure you have a global namespace.
> 
> I will use the ITS physical base address as the token for ITS, maybe I
> can use the GICD physical base address here instead?

That should be fine as long as the physical address cannot be
interpreted as a kernel address. Which is still a bit dodgy. I'd be more
happy if you had a proper namespace.

>>
>>> +    if (err)
>>> +            goto out_redist_unmap;
>>> +
>>> +    acpi_set_irq_model(ACPI_IRQ_MODEL_GIC, ACPI_IRQ_MODEL_GIC,
>>> +                       gic_acpi_gsi_desc_populate);
>>> +    return 0;
>>> +
>>> +out_redist_unmap:
>>> +    for (i = 0; i < nr_redist_regions; i++)
>>> +            if (redist_regs[i].redist_base)
>>> +                    iounmap(redist_regs[i].redist_base);
>>> +    kfree(redist_regs);
>>> +out_dist_unmap:
>>> +    iounmap(dist_base);
>>> +    return err;
>>> +}
>>> +IRQCHIP_ACPI_DECLARE(gic_v3, ACPI_MADT_GIC_VERSION_V3, gic_acpi_init);
>>> +IRQCHIP_ACPI_DECLARE(gic_v4, ACPI_MADT_GIC_VERSION_V4, gic_acpi_init);
>>
>> As mentioned before, this doesn't work.
> 
> hmm, I think we need more discussion for this one, but we need to match
> V4 for GICv3 drivers, and everything will be the same in the dirver
> as I said before.

And as I said before, you don't need to distinguish v3 from v4 in the
ACPI code. Matching GICv3 is enough.

Thanks,

	M.
-- 
Jazz is not dead. It just smells funny...


From marc.zyngier at arm.com  Thu Aug  6 09:42:50 2015
From: marc.zyngier at arm.com (Marc Zyngier)
Date: Thu, 06 Aug 2015 17:42:50 +0100
Subject: [PATCH v4 07/10] irqchip / GICv3 / ACPI: Add GICR support via
 GICC structures
In-Reply-To: <55C2198A.5060001@linaro.org>
References: <1438164539-29256-1-git-send-email-hanjun.guo@linaro.org>
 <1438164539-29256-8-git-send-email-hanjun.guo@linaro.org>
 <55C0BFFD.3000602@arm.com> <55C2198A.5060001@linaro.org>
Message-ID: <55C38E8A.1060506@arm.com>

On 05/08/15 15:11, Hanjun Guo wrote:
> On 08/04/2015 09:37 PM, Marc Zyngier wrote:
>> On 29/07/15 11:08, Hanjun Guo wrote:
>>> On systems supporting GICv3 and above, in MADT GICC structures, the
>>> field of GICR Base Address holds the 64-bit physical address of the
>>> associated Redistributor if the GIC Redistributors are not in the
>>> always-on power domain, so instead of init GICR regions via GIC
>>> redistributor structure(s), init it with GICR base address in GICC
>>> structures in that case.
>>>
>>> As GICR base in MADT GICC is another way to indicate the GIC version
>>> is 3 or 4, add its support to find out the GIC versions.
>>>
>>> Signed-off-by: Hanjun Guo <hanjun.guo at linaro.org>
>>> ---
>>>   drivers/irqchip/irq-gic-acpi.c       |  35 ++++++-
>>>   drivers/irqchip/irq-gic-v3.c         | 197 +++++++++++++++++++++++++++++++----
>>>   include/linux/irqchip/arm-gic-acpi.h |   2 +
>>>   3 files changed, 215 insertions(+), 19 deletions(-)
>>>
>>> diff --git a/drivers/irqchip/irq-gic-acpi.c b/drivers/irqchip/irq-gic-acpi.c
>>> index 95454e3..3e5c8f4 100644
>>> --- a/drivers/irqchip/irq-gic-acpi.c
>>> +++ b/drivers/irqchip/irq-gic-acpi.c
>>> @@ -21,6 +21,11 @@ static u8 gic_version __initdata = ACPI_MADT_GIC_VERSION_NONE;
>>>
>>>   static phys_addr_t dist_phy_base __initdata;
>>>
>>> +u8 __init acpi_gic_version(void)
>>> +{
>>> +       return gic_version;
>>> +}
>>> +
>>>   static int __init
>>>   acpi_gic_parse_distributor(struct acpi_subtable_header *header,
>>>                             const unsigned long end)
>>> @@ -38,6 +43,27 @@ acpi_gic_parse_distributor(struct acpi_subtable_header *header,
>>>   }
>>>
>>>   static int __init
>>> +gic_acpi_parse_madt_gicc(struct acpi_subtable_header *header,
>>> +                        const unsigned long end)
>>> +{
>>> +       struct acpi_madt_generic_interrupt *gicc;
>>> +
>>> +       gicc = (struct acpi_madt_generic_interrupt *)header;
>>> +
>>> +       if (BAD_MADT_GICC_ENTRY(gicc, end))
>>> +               return -EINVAL;
>>> +
>>> +       /*
>>> +        * If GICC is enabled but has no valid gicr base address, then it
>>> +        * means GICR base is not presented via GICC
>>> +        */
>>> +       if ((gicc->flags & ACPI_MADT_ENABLED) && !gicc->gicr_base_address)
>>> +               return -ENODEV;
>>> +
>>> +       return 0;
>>> +}
>>> +
>>> +static int __init
>>>   match_gic_redist(struct acpi_subtable_header *header, const unsigned long end)
>>>   {
>>>          return 0;
>>> @@ -51,7 +77,14 @@ static bool __init acpi_gic_redist_is_present(void)
>>>          count  =  acpi_table_parse_madt(ACPI_MADT_TYPE_GENERIC_REDISTRIBUTOR,
>>>                                          match_gic_redist, 0);
>>>
>>> -       /* that's true if we have at least one GIC redistributor entry */
>>> +       /* has at least one GIC redistributor entry */
>>> +       if (count > 0)
>>> +               return true;
>>> +
>>> +       /* else try to find GICR base in GICC entries */
>>> +       count = acpi_table_parse_madt(ACPI_MADT_TYPE_GENERIC_INTERRUPT,
>>> +                                     gic_acpi_parse_madt_gicc, 0);
>>> +
>>>          return count > 0;
>>>   }
>>>
>>> diff --git a/drivers/irqchip/irq-gic-v3.c b/drivers/irqchip/irq-gic-v3.c
>>> index ebc5604..b72ccbb 100644
>>> --- a/drivers/irqchip/irq-gic-v3.c
>>> +++ b/drivers/irqchip/irq-gic-v3.c
>>> @@ -389,9 +389,8 @@ static void __init gic_dist_init(void)
>>>                  writeq_relaxed(affinity, base + GICD_IROUTER + i * 8);
>>>   }
>>>
>>> -static int gic_populate_rdist(void)
>>> +static int gic_populate_rdist_with_regions(u64 mpidr)
>>>   {
>>> -       u64 mpidr = cpu_logical_map(smp_processor_id());
>>>          u64 typer;
>>>          u32 aff;
>>>          int i;
>>> @@ -439,6 +438,34 @@ static int gic_populate_rdist(void)
>>>                  } while (!(typer & GICR_TYPER_LAST));
>>>          }
>>>
>>> +       return -ENODEV;
>>> +}
>>> +
>>> +#ifdef CONFIG_ACPI
>>> +/*
>>> + * Populate redist when GIC redistributor address is presented in ACPI
>>> + * MADT GICC entries
>>> + */
>>> +static int gic_populate_rdist_with_gicr_base(u64 mpidr);
>>> +#else
>>> +static inline int gic_populate_rdist_with_gicr_base(u64 mpidr)
>>> +{
>>> +       return -ENODEV;
>>> +}
>>> +#endif
>>> +
>>> +static int gic_populate_rdist(void)
>>> +{
>>> +       u64 mpidr = cpu_logical_map(smp_processor_id());
>>> +
>>> +       if (gic_data.nr_redist_regions) {
>>> +               if (!gic_populate_rdist_with_regions(mpidr))
>>> +                       return 0;
>>> +       } else {
>>> +               if (!gic_populate_rdist_with_gicr_base(mpidr))
>>> +                       return 0;
>>> +       }
>>> +
>>>          /* We couldn't even deal with ourselves... */
>>>          WARN(true, "CPU%d: mpidr %llx has no re-distributor!\n",
>>>               smp_processor_id(), (unsigned long long)mpidr);
>>> @@ -900,6 +927,16 @@ IRQCHIP_DECLARE(gic_v3, "arm,gic-v3", gic_of_init);
>>>   #endif
>>>
>>>   #ifdef CONFIG_ACPI
>>> +
>>> +struct acpi_gicc_redist {
>>> +       struct list_head list;
>>> +       u64 mpidr;
>>> +       phys_addr_t phys_base;
>>> +       void __iomem *redist_base;
>>> +};
>>> +
>>> +static LIST_HEAD(redist_list);
>>> +
>>>   static struct redist_region *redist_regs __initdata;
>>>   static u32 nr_redist_regions __initdata;
>>>   static phys_addr_t dist_phys_base __initdata;
>>> @@ -932,6 +969,17 @@ gic_acpi_register_redist(u64 phys_base, u64 size)
>>>          return 0;
>>>   }
>>>
>>> +static void __init
>>> +gic_acpi_release_redist_regions(void)
>>> +{
>>> +       int i;
>>> +
>>> +       for (i = 0; i < nr_redist_regions; i++)
>>> +               if (redist_regs[i].redist_base)
>>> +                       iounmap(redist_regs[i].redist_base);
>>> +       kfree(redist_regs);
>>> +}
>>> +
>>>   static int __init
>>>   gic_acpi_parse_madt_redist(struct acpi_subtable_header *header,
>>>                          const unsigned long end)
>>> @@ -989,9 +1037,130 @@ static int gic_acpi_gsi_desc_populate(struct acpi_gsi_descriptor *data,
>>>   }
>>>
>>>   static int __init
>>> +gic_acpi_add_gicc_redist(phys_addr_t phys_base, u64 mpidr)
>>> +{
>>> +       struct acpi_gicc_redist *redist;
>>> +
>>> +       redist = kzalloc(sizeof(*redist), GFP_KERNEL);
>>> +       if (!redist)
>>> +               return -ENOMEM;
>>> +
>>> +       redist->mpidr = mpidr;
>>> +       redist->phys_base = phys_base;
>>> +
>>> +       if (acpi_gic_version() == ACPI_MADT_GIC_VERSION_V3)
>>> +               /* RD_base + SGI_base */
>>> +               redist->redist_base = ioremap(phys_base, 2 * SZ_64K);
>>> +       else
>>> +               /*
>>> +                * RD_base + SGI_base + VLPI_base,
>>> +                * we don't map reserved page as it's buggy to access it
>>> +                */
>>> +               redist->redist_base = ioremap(phys_base, 3 * SZ_64K);
>>> +
>>> +       if (!redist->redist_base) {
>>> +               kfree(redist);
>>> +               return -ENOMEM;
>>> +       }
>>> +
>>> +       list_add(&redist->list, &redist_list);
>>> +       return 0;
>>> +}
>>> +
>>> +static void __init
>>> +gic_acpi_release_gicc_redist(void)
>>> +{
>>> +       struct acpi_gicc_redist *redist, *t;
>>> +
>>> +       list_for_each_entry_safe(redist, t, &redist_list, list) {
>>> +               list_del(&redist->list);
>>> +               iounmap(redist->redist_base);
>>> +               kfree(redist);
>>> +       }
>>> +}
>>> +
>>> +static int __init
>>> +gic_acpi_parse_madt_gicc(struct acpi_subtable_header *header,
>>> +                        const unsigned long end)
>>> +{
>>> +       struct acpi_madt_generic_interrupt *gicc;
>>> +
>>> +       gicc = (struct acpi_madt_generic_interrupt *)header;
>>> +
>>> +       if (BAD_MADT_GICC_ENTRY(gicc, end))
>>> +               return -EINVAL;
>>> +
>>> +       /*
>>> +        * just quietly ingore the disabled CPU(s) and continue
>>> +        * to find the enabled one(s), if we return error here,
>>> +        * the scanning will be stopped.
>>> +        */
>>> +       if (!(gicc->flags & ACPI_MADT_ENABLED))
>>> +               return 0;
>>> +
>>> +       return gic_acpi_add_gicc_redist(gicc->gicr_base_address,
>>> +                                       gicc->arm_mpidr);
>>> +}
>>> +
>>> +static int gic_populate_rdist_with_gicr_base(u64 mpidr)
>>> +{
>>> +       struct acpi_gicc_redist *redist;
>>> +       void __iomem *ptr;
>>> +       u32 reg;
>>> +
>>> +       list_for_each_entry(redist, &redist_list, list) {
>>> +               if (redist->mpidr != mpidr)
>>> +                       continue;
>>> +
>>> +               ptr = redist->redist_base;
>>> +               reg = readl_relaxed(ptr + GICR_PIDR2) & GIC_PIDR2_ARCH_MASK;
>>> +               if (reg != GIC_PIDR2_ARCH_GICv3 && reg != GIC_PIDR2_ARCH_GICv4) {
>>> +                       pr_warn("No redistributor present @%p\n", ptr);
>>> +                       return -ENODEV;
>>> +               }
>>> +
>>> +               gic_data_rdist_rd_base() = ptr;
>>> +               gic_data_rdist()->phys_base = redist->phys_base;
>>> +               pr_info("CPU%d: found redistributor %llx phys base:%pa\n",
>>> +                       smp_processor_id(),
>>> +                       (unsigned long long)mpidr,
>>> +                       &gic_data_rdist()->phys_base);
>>> +               return 0;
>>> +       }
>>> +
>>> +       return -ENODEV;
>>> +}
>>> +
>>> +static int __init collect_gicr_base(struct acpi_table_header *table)
>>> +{
>>> +       int count;
>>> +
>>> +       /* Collect redistributor base addresses in GICR entries */
>>> +       count = acpi_parse_entries(ACPI_SIG_MADT,
>>> +                       sizeof(struct acpi_table_madt),
>>> +                       gic_acpi_parse_madt_redist, table,
>>> +                       ACPI_MADT_TYPE_GENERIC_REDISTRIBUTOR, 0);
>>> +       if (count > 0)
>>> +               return 0;
>>> +
>>> +       pr_info("No valid GICR entries exist, try GICC entries\n");
>>> +
>>> +       /* Collect redistributor base addresses in GICC entries */
>>> +       count = acpi_parse_entries(ACPI_SIG_MADT,
>>> +                       sizeof(struct acpi_table_madt),
>>> +                       gic_acpi_parse_madt_gicc, table,
>>> +                       ACPI_MADT_TYPE_GENERIC_INTERRUPT, 0);
>>> +       if (count > 0 && !list_empty(&redist_list))
>>> +               return 0;
>>> +
>>> +       pr_info("No valid GICC entries exist for GICR base\n");
>>> +       return -ENODEV;
>>> +}
>>> +
>>> +static int __init
>>>   gic_acpi_init(struct acpi_table_header *table)
>>>   {
>>> -       int count, i, err = 0;
>>> +       int count, err = 0;
>>>          void __iomem *dist_base;
>>>
>>>          /* Get distributor base address */
>>> @@ -1020,30 +1189,22 @@ gic_acpi_init(struct acpi_table_header *table)
>>>          }
>>>
>>>          /* Collect redistributor base addresses */
>>> -       count = acpi_parse_entries(ACPI_SIG_MADT,
>>> -                       sizeof(struct acpi_table_madt),
>>> -                       gic_acpi_parse_madt_redist, table,
>>> -                       ACPI_MADT_TYPE_GENERIC_REDISTRIBUTOR, 0);
>>> -       if (count <= 0) {
>>> -               pr_info("No valid GICR entries exist\n");
>>> -               err = -EINVAL;
>>> -               goto out_redist_unmap;
>>> -       }
>>> +       if (collect_gicr_base(table))
>>> +               goto out_release_redist;
>>>
>>>          err = gic_init_bases(dist_base, redist_regs, nr_redist_regions, 0,
>>>                               (void *)ACPI_IRQ_MODEL_GIC);
>>>          if (err)
>>> -               goto out_redist_unmap;
>>> +               goto out_release_redist;
>>>
>>>          acpi_set_irq_model(ACPI_IRQ_MODEL_GIC, ACPI_IRQ_MODEL_GIC,
>>>                             gic_acpi_gsi_desc_populate);
>>>          return 0;
>>>
>>> -out_redist_unmap:
>>> -       for (i = 0; i < nr_redist_regions; i++)
>>> -               if (redist_regs[i].redist_base)
>>> -                       iounmap(redist_regs[i].redist_base);
>>> -       kfree(redist_regs);
>>> +out_release_redist:
>>> +       gic_acpi_release_redist_regions();
>>> +       if (!list_empty(&redist_list))
>>> +               gic_acpi_release_gicc_redist();
>>>   out_dist_unmap:
>>>          iounmap(dist_base);
>>>          return err;
>>> diff --git a/include/linux/irqchip/arm-gic-acpi.h b/include/linux/irqchip/arm-gic-acpi.h
>>> index 56cd82c..0d43f515 100644
>>> --- a/include/linux/irqchip/arm-gic-acpi.h
>>> +++ b/include/linux/irqchip/arm-gic-acpi.h
>>> @@ -21,5 +21,7 @@
>>>   #define ACPI_GIC_CPU_IF_MEM_SIZE       (SZ_8K)
>>>   #define ACPI_GICV3_DIST_MEM_SIZE       (SZ_64K)
>>>
>>> +u8 acpi_gic_version(void);
>>> +
>>>   #endif /* CONFIG_ACPI */
>>>   #endif /* ARM_GIC_ACPI_H_ */
>>> --
>>> 1.9.1
>>>
>>
>> This looks absolutely horrid. Why don't you simply populate one region
>> per redistributor, add a flag to struct redist_region so we know not to
>> check for GICR_TYPER_LAST but to move on to the next region instead?
> 
> There is no regions in GICC structures, and only have the GICR base
> address for each CPU, I think we can't figure out which GICR bases
> are belonging to a GICR region.
> 
> So do you mean populate each GICR base as a region, and use the
> existing infrastructure ?

This is exactly what I wrote.

Thanks,

	M.
-- 
Jazz is not dead. It just smells funny...


From benoar at dolka.fr  Thu Aug  6 09:44:33 2015
From: benoar at dolka.fr (Benjamin Cama)
Date: Thu, 06 Aug 2015 18:44:33 +0200
Subject: [PATCH v3] ARM: dts: Convert Linkstation Mini to Device Tree
In-Reply-To: <20150806163424.GH13421@lunn.ch>
References: <1438878592.15635.89.camel@dolka.fr>
 <20150806163424.GH13421@lunn.ch>
Message-ID: <1438879473.15635.91.camel@dolka.fr>

Hi Andrew,

Le jeudi 06 ao?t 2015 ? 18:34 +0200, Andrew Lunn a ?crit :
> On Thu, Aug 06, 2015 at 06:29:52PM +0200, Benjamin Cama wrote:
> > The title says it all. The name of the dts file as been changed to
> > better reflect the manufacturer's device name (LS-WSGL), rather 
> > than
> > the original "lsmini", which exists in a kirkwood version too.
> > 
> > Signed-off-by: Benjamin Cama <benoar at dolka.fr>
> 
> Hi Benjamin
> 
> It would be normal to add the various Acked-by: here, both Alexey and
> mine. It is not an issue, Gregory can add them, when he adds is own.
> I'm just mentioning it for any future patches you might submit.

Ah, OK, I was not sure and didn't want to add them by mistake.

> Thanks for the good work converting this,

Thanks!
--
benjamin


From marc.zyngier at arm.com  Thu Aug  6 09:44:37 2015
From: marc.zyngier at arm.com (Marc Zyngier)
Date: Thu, 06 Aug 2015 17:44:37 +0100
Subject: [PATCH v3 09/11] KVM: arm/arm64: vgic: Prevent userspace injection
 of a mapped interrupt
In-Reply-To: <20150805134754.GB4657@cbox>
References: <1437753309-17989-1-git-send-email-marc.zyngier@arm.com>
 <1437753309-17989-10-git-send-email-marc.zyngier@arm.com>
 <55C0E690.1090808@linaro.org> <55C0EBF5.2060708@arm.com>
 <55C1BBF9.2060004@linaro.org> <55C1DAE9.1050609@arm.com>
 <20150805105345.GA4657@cbox> <55C1F7CF.5070904@linaro.org>
 <20150805134754.GB4657@cbox>
Message-ID: <55C38EF5.1080502@arm.com>

On 05/08/15 14:47, Christoffer Dall wrote:
> On Wed, Aug 05, 2015 at 01:47:27PM +0200, Eric Auger wrote:
>> On 08/05/2015 12:53 PM, Christoffer Dall wrote:
>>> On Wed, Aug 05, 2015 at 10:44:09AM +0100, Marc Zyngier wrote:
>>>> On 05/08/15 08:32, Eric Auger wrote:
>>>>> Hi Marc,
>>>>> On 08/04/2015 06:44 PM, Marc Zyngier wrote:
>>>>>> On 04/08/15 17:21, Eric Auger wrote:
>>>>>>> Hi Marc,
>>>>>>> On 07/24/2015 05:55 PM, Marc Zyngier wrote:
>>>>>>>> Virtual interrupts mapped to a HW interrupt should only be triggered
>>>>>>>> from inside the kernel. Otherwise, you could end up confusing the
>>>>>>>> kernel (and the GIC's) state machine.
>>>>>>>>
>>>>>>>> Rearrange the injection path so that kvm_vgic_inject_irq is
>>>>>>>> used for non-mapped interrupts, and kvm_vgic_inject_mapped_irq is
>>>>>>>> used for mapped interrupts. The latter should only be called from
>>>>>>>> inside the kernel (timer, VFIO).
>>>>>>> nit: I would replace VFIO by irqfd.
>>>>>>> VFIO just triggers the eventfd/irqfd. This is KVM/irqfd that injects the
>>>>>>> virtual irq upon the irqfd signaling and he irqfd adaptation/ARM
>>>>>>> currently is implemented in vgic.c
>>>>>>
>>>>>> Ah, thanks for reminding me of the right terminology, I tend to think of
>>>>>> it as one big bag of nasty tricks... ;-)
>>>>>>
>>>>>> I'll update the commit message.
>>>>>>
>>>>>>>>
>>>>>>>> Signed-off-by: Marc Zyngier <marc.zyngier at arm.com>
>>>>>>>> ---
>>>>>>>>  include/kvm/arm_vgic.h |  2 +
>>>>>>>>  virt/kvm/arm/vgic.c    | 99 ++++++++++++++++++++++++++++++++++----------------
>>>>>>>>  2 files changed, 70 insertions(+), 31 deletions(-)
>>>>>>>>
>>>>>>>> diff --git a/include/kvm/arm_vgic.h b/include/kvm/arm_vgic.h
>>>>>>>> index 7306b4b..f6bfd79 100644
>>>>>>>> --- a/include/kvm/arm_vgic.h
>>>>>>>> +++ b/include/kvm/arm_vgic.h
>>>>>>>> @@ -351,6 +351,8 @@ void kvm_vgic_flush_hwstate(struct kvm_vcpu *vcpu);
>>>>>>>>  void kvm_vgic_sync_hwstate(struct kvm_vcpu *vcpu);
>>>>>>>>  int kvm_vgic_inject_irq(struct kvm *kvm, int cpuid, unsigned int irq_num,
>>>>>>>>  			bool level);
>>>>>>>> +int kvm_vgic_inject_mapped_irq(struct kvm *kvm, int cpuid,
>>>>>>>> +			       struct irq_phys_map *map, bool level);
>>>>>>>>  void vgic_v3_dispatch_sgi(struct kvm_vcpu *vcpu, u64 reg);
>>>>>>>>  int kvm_vgic_vcpu_pending_irq(struct kvm_vcpu *vcpu);
>>>>>>>>  int kvm_vgic_vcpu_active_irq(struct kvm_vcpu *vcpu);
>>>>>>>> diff --git a/virt/kvm/arm/vgic.c b/virt/kvm/arm/vgic.c
>>>>>>>> index 3f7b690..e40ef70 100644
>>>>>>>> --- a/virt/kvm/arm/vgic.c
>>>>>>>> +++ b/virt/kvm/arm/vgic.c
>>>>>>>> @@ -1533,7 +1533,8 @@ static int vgic_validate_injection(struct kvm_vcpu *vcpu, int irq, int level)
>>>>>>>>  }
>>>>>>>>  
>>>>>>>>  static int vgic_update_irq_pending(struct kvm *kvm, int cpuid,
>>>>>>>> -				  unsigned int irq_num, bool level)
>>>>>>>> +				   struct irq_phys_map *map,
>>>>>>>> +				   unsigned int irq_num, bool level)
>>>>>>>>  {
>>>>>>> In vgic_update_irq_pending, I needed to modify the following line and
>>>>>>> add the "&& !map".
>>>>>>>
>>>>>>>         if (!vgic_validate_injection(vcpu, irq_num, level) && !map) {
>>>>>>>
>>>>>>> Without that, the level being not properly modeled for level sensitive
>>>>>>> forwarded IRQs, the 2d injection fails.
>>>>>>
>>>>>> Ah! Is that because we never see the line being reset to zero, and the
>>>>>> VGIC still sees the line as pending at the distributor level?
>>>>> yes indeed
>>>>
>>>> Then it is a bigger problem we need to solve, and your solution just
>>>> papers over the issue.
>>>>
>>>> The main problem is that irqfd is essentially an edge-triggered
>>>> signalling. Fire and forget. Given that we're dealing with a level
>>>> triggered interrupt, we end up with the interrupt still marked as
>>>> pending (nobody took the signal down).
>> this does not really relate to irqfd: irqfd also comes with the concept
>> of resamplefd. in case the IRQ is not forwarded, this is the
>> irqfd_resampler_ack function that toggles the IRQ down (eventfd.c). Its
>> execution is triggered in vgic_process_maintenance. With forwarding the
>> EOI is not trappable anymore so this disappears.
>>
>>
>>>> The usual way to get out of that mess in is to evaluate the state of the
>>>> level on EOI. But we can't trap on EOI for a HW interrupt.
>>>>
>>>> So it raises the question: should we instead consider the HW pending
>>>> state instead of the software one for mapped interrupts? It is
>>>> expensive, but it feels more correct.
>>>>
>>> I thought we already covered this at LCA.  For mapped interrupts
>>> (forwarded) we should never consider the software pending state, because
>>> that state is managed by the hardware.  Or am I confusing concepts here?
>>
>> Yes we discussed we should bypass most of the SW states.
>>
>> in my previous integration I proposed a patch "KVM: arm: vgic: fix state
>> machine for forwarded IRQ". What's wrong with the below approach?
>>
>>
>>     Fix multiple injection of level sensitive forwarded IRQs.
>>     With current code, the second injection fails since the
>>     state bitmaps are not reset (process_maintenance is not
>>     called anymore).
>>
>>     New implementation follows those principles:
>>     - A forwarded IRQ only can be sampled when it is pending
>>     - when queueing the IRQ (programming the LR), the pending state
>>       is removed as for edge sensitive IRQs
>>     - an injection of a forwarded IRQ is considered always valid since
>>       coming from the HW and level always is 1.
>>
> I don't see anything wrong, and I thought this was what we discussed.

I think I just lost track of what we've discussed at LCA. Ignore me.

I'll repost the updated first 10 patches tomorrow. Eric, are you willing
to take custody of patch 11 as part of one of your series?

Thanks,

	M.
-- 
Jazz is not dead. It just smells funny...


From broonie at kernel.org  Thu Aug  6 09:46:56 2015
From: broonie at kernel.org (Mark Brown)
Date: Thu, 6 Aug 2015 17:46:56 +0100
Subject: [RFC PATCH 1/5] spi: introduce flag for memory mapped read
In-Reply-To: <20150806135129.GJ7576@n2100.arm.linux.org.uk>
References: <55C0FD98.1090107@ti.com> <20150805115013.GJ20873@sirena.org.uk>
 <CAOMqctQXwcHyiWBwtugSDSE_k65qrNfrwnhjQMDJkLoJMmGzUw@mail.gmail.com>
 <20150805124412.GN20873@sirena.org.uk>
 <CAOMqctS9Y5FxpUCCJew6+cnjH5iTvbzkH3g-8yrXs4OuS2pSGA@mail.gmail.com>
 <20150806090202.GO20873@sirena.org.uk>
 <CAOMqctQZRZ4zG_yYy=CeX3DX4NVNWN1COP4Q-2YvMun9xYOA7g@mail.gmail.com>
 <20150806102225.GI7576@n2100.arm.linux.org.uk>
 <55C35233.2000105@ti.com>
 <20150806135129.GJ7576@n2100.arm.linux.org.uk>
Message-ID: <20150806164656.GY20873@sirena.org.uk>

On Thu, Aug 06, 2015 at 02:51:29PM +0100, Russell King - ARM Linux wrote:

> The M25P80 driver just appends additional bytes to the message to
> achieve this:
> 
>         struct m25p *flash = nor->priv;
>         unsigned int dummy = nor->read_dummy;
> 
>         /* convert the dummy cycles to the number of bytes */
>         dummy /= 8;
> 
>         flash->command[0] = nor->read_opcode;
>         m25p_addr2cmd(nor, from, flash->command);
> 
>         t[0].tx_buf = flash->command;
>         t[0].len = m25p_cmdsz(nor) + dummy;
>         spi_message_add_tail(&t[0], &m);

> The reason that the number of dummy bytes can't be detected is because
> it's all hidden in the first transaction as the total number of bytes to
> be transmitted - and the dummy bytes are uninitialised, so you can't
> make any assumptions what value they are.  There is no way for the SPI
> driver to know whether these dummy bytes are dummy bytes or whether they
> have an effect on the targetted device.

We *could* (as you suggest below) indicate dummy transfers by having a
separate transfer which omits the transmit buffers though I'd expect
that normally that is going to be a small performance hit if interpreted
directly so we need to think what to do there.  We do get other devices
sending dummy bytes, it's sometimes a requirement for high speed
register access to give settling time for the device, so other things
would get some milage from it.

> What may make more sense from the SPI point of view is to communicate to
> all SPI drivers how many dummy bytes are to be transferred.  I'm not fully
> up on SPI, but maybe something like this:

> 	t[0].tx_buf = flash->command;
> 	t[0].len = m25p_cmdsz(nor);
> 	spi_message_add_tail(&t[0], &m);
> 	t[1].tx_buf = dummy_buffer;
> 	t[1].len = dummy;
> 	t[1].dummy = 1;
> 	spi_message_add_tail(&t[1], &m);

> This way, we're describing the transfer to the SPI core, and explicitly
> indicating that there are some dummy bytes.  The SPI driver can then
> tell that these are dummy bytes, and if the SPI message consists of:

That'd work as well, my first thought would to use NULL as a dummy
buffer pointer and let the core substitute in data for the drivers.  We
currently insist on having at least one buffer but that's fixable.

> This would not be a hack to the SPI code: we're describing to the SPI
> code what we want to achieve in terms of the activity on the bus, and
> providing that level of description then allows the SPI driver to make
> informed decisions on whether it can handle the transfer using some
> non-standard feature.

Yup.
-------------- next part --------------
A non-text attachment was scrubbed...
Name: signature.asc
Type: application/pgp-signature
Size: 473 bytes
Desc: Digital signature
URL: <http://lists.infradead.org/pipermail/linux-arm-kernel/attachments/20150806/9b3dcd74/attachment-0001.sig>

From marc.zyngier at arm.com  Thu Aug  6 09:53:50 2015
From: marc.zyngier at arm.com (Marc Zyngier)
Date: Thu, 06 Aug 2015 17:53:50 +0100
Subject: [PATCH v5 9/9] PCI: xgene: Use pci_scan_root_bus_msi()
In-Reply-To: <CAFiDJ58U9u0YOzqVbty8+z+sF82h=F09Y0q-Ks8zMDokdiSEbg@mail.gmail.com>
References: <20150804214234.9189.42548.stgit@bhelgaas-glaptop2.roam.corp.google.com>	<20150804215457.9189.27595.stgit@bhelgaas-glaptop2.roam.corp.google.com>	<55C37C92.1020509@arm.com>
 <CAFiDJ58U9u0YOzqVbty8+z+sF82h=F09Y0q-Ks8zMDokdiSEbg@mail.gmail.com>
Message-ID: <55C3911E.9090907@arm.com>

On 06/08/15 17:41, Ley Foon Tan wrote:
> On Thu, Aug 6, 2015 at 11:26 PM, Marc Zyngier <marc.zyngier at arm.com> wrote:
>> Hi Bjorn,
>>
>> On 04/08/15 22:54, Bjorn Helgaas wrote:
>>> Previously there was no way to specify the MSI controller when creating a
>>> new PCI root bus, so we had to create the bus, set its MSI controller, then
>>> scan the bus.  With the new pci_scan_root_bus_msi() interface, we can
>>> specify the MSI controller up front and get rid of that intermediate step.
>>>
>>> Look up the MSI controller first, then use pci_scan_root_bus_msi() to
>>> create and scan the root PCI bus.
>>
>> I'm wondering about these XGene patches.
>>
>> With the code that is queued for v4.3 in tip/irq/core, the X-Gene MSI
>> driver doesn't export a struct msi_controller anymore, and entirely
>> relies on IRQ domains to identify to be matched with the actual PCI driver.
>>
>> Do you intend this as a cleanup until everything lands in mainline? At
>> that point, we'd be able to remove all traces of struct msi_controller
>> from this driver.
>>
>> Alternatively, we could ask tglx to add an extra patch to the existing
>> queue in order to clean up pci-xgene.c (nuking the whole
>> xgene_pcie_msi_enable function).
>>
>> Thoughts?
> 
> In pcie-altera driver, it uses pci_scan_root_bus() and it doesn't call
> to of_pci_find_msi_chip_by_node() to retrieve msi_controller struct as
> well.
> But, the msi domain stuff is still working. Should I change it to
> pci_scan_root_bus_msi()?

If you're not using struct msi_controller, I don't see a reason to use
pci_scan_root_bus_msi(). The MSI irq domain patches are queued for 4.3,
and I don't believe your driver will be merged before that.

Eventually, I'd like to kill msi_controller entirely. It is completely
redundant with the use of irq domains.

Thanks,

	M.
-- 
Jazz is not dead. It just smells funny...


From raghumag at gmail.com  Thu Aug  6 09:58:12 2015
From: raghumag at gmail.com (raghu MG)
Date: Thu, 6 Aug 2015 22:28:12 +0530
Subject: Armadaxp GPIO interrupts
In-Reply-To: <20150806132926.GB19896@lunn.ch>
References: <CAG1O52Xg88OsifBzmpSdqvC8wQaOW78nC9nnfxugFv1VU1m1LQ@mail.gmail.com>
 <20150804153439.GA28673@lunn.ch>
 <CAG1O52W2Gy_6_DfewtUqoK_J+Y=KwVGyygNaPu2xyPM_ZkLfcQ@mail.gmail.com>
 <CAG1O52VQPpeGkA8bqYbPMTiT9Mua1yHi3H3osqJsHqm-RRKzow@mail.gmail.com>
 <20150805162155.GE32760@lunn.ch>
 <CAG1O52WPFfm+XGk01iUVWLu=-Dm7bcDVmhv3P8iQDH+HHjsLUA@mail.gmail.com>
 <20150806132926.GB19896@lunn.ch>
Message-ID: <CAG1O52XUyPkgTTRKftujZBNK1=n6GBdWgBg_kq6SsC5XMaeU3w@mail.gmail.com>

Ok,I think I need to understand more about this gpio driver.

As you said its registering chained handler,but why are they(IRQs) not
visible in cat /proc/interrupts.
What could be the reason.?

Do I need to further initialize marvell GPIO registers to trigger
these events. The driver is unmasking all interrupts in probe function
                writel_relaxed(0, mvchip->membase + GPIO_EDGE_CAUSE_OFF);
                writel_relaxed(0, mvchip->membase + GPIO_EDGE_MASK_OFF);
                writel_relaxed(0, mvchip->membase + GPIO_LEVEL_MASK_OFF);


Do I need to change the polarity in polarity register to suit the
board requirements in probe function.

I will try this in the morning.


Regards
Raghu

On Thu, Aug 6, 2015 at 6:59 PM, Andrew Lunn <andrew at lunn.ch> wrote:
>> mvebu_gpio_irq_handler is only called if I register a another handler
>> at irq=82/83/84/85/87/88/89/90/92. I am registering this handler using
>> minimal kernel module.
>
> This is totally wrong. The gpio driver needs these interrupts, and
> will register a chained interrupt handle for these. Don't mess around
> with them. Here is the code in the driver:
>
>         /* Setup the interrupt handlers. Each chip can have up to 4
>          * interrupt handlers, with each handler dealing with 8 GPIO
>          * pins. */
>         for (i = 0; i < 4; i++) {
>                 int irq = platform_get_irq(pdev, i);
>
>                 if (irq < 0)
>                         continue;
>                 irq_set_handler_data(irq, mvchip);
>                 irq_set_chained_handler(irq, mvebu_gpio_irq_handler);
>         }
>
>         Andrew


From gregory.clement at free-electrons.com  Thu Aug  6 10:00:15 2015
From: gregory.clement at free-electrons.com (Gregory CLEMENT)
Date: Thu, 06 Aug 2015 19:00:15 +0200
Subject: [PATCH v3] ARM: dts: Convert Linkstation Mini to Device Tree
In-Reply-To: <1438879473.15635.91.camel@dolka.fr>
References: <1438878592.15635.89.camel@dolka.fr>
 <20150806163424.GH13421@lunn.ch> <1438879473.15635.91.camel@dolka.fr>
Message-ID: <55C3929F.3030209@free-electrons.com>

Hi Benjamin,

On 06/08/2015 18:44, Benjamin Cama wrote:
> Hi Andrew,
> 
> Le jeudi 06 ao?t 2015 ? 18:34 +0200, Andrew Lunn a ?crit :
>> On Thu, Aug 06, 2015 at 06:29:52PM +0200, Benjamin Cama wrote:
>>> The title says it all. The name of the dts file as been changed to
>>> better reflect the manufacturer's device name (LS-WSGL), rather 
>>> than
>>> the original "lsmini", which exists in a kirkwood version too.
>>>
>>> Signed-off-by: Benjamin Cama <benoar at dolka.fr>
>>
>> Hi Benjamin
>>
>> It would be normal to add the various Acked-by: here, both Alexey and
>> mine. It is not an issue, Gregory can add them, when he adds is own.
>> I'm just mentioning it for any future patches you might submit.
> 
> Ah, OK, I was not sure and didn't want to add them by mistake.

applied on mvebu/dt with the Acked-by: flags but also with some minor
fixes :I used tab instead of space to indent dts at line 185 and I
also resolved the merge conflict with patch "ARM: dts: orion5x: add
buffalo linkstation ls-wtgl" in the file arch/arm/boot/dts/Makefile.

Thanks,

Gregory


> 
>> Thanks for the good work converting this,
> 
> Thanks!
> --
> benjamin
> 
> _______________________________________________
> linux-arm-kernel mailing list
> linux-arm-kernel at lists.infradead.org
> http://lists.infradead.org/mailman/listinfo/linux-arm-kernel
> 


-- 
Gregory Clement, Free Electrons
Kernel, drivers, real-time and embedded Linux
development, consulting, training and support.
http://free-electrons.com


From mw at semihalf.com  Thu Aug  6 10:00:27 2015
From: mw at semihalf.com (Marcin Wojtas)
Date: Thu,  6 Aug 2015 19:00:27 +0200
Subject: [PATCH 0/3] Fixes for the network driver of Marvell Armada 375 SoC
In-Reply-To: <y>
References: <y>
Message-ID: <1438880430-5480-1-git-send-email-mw@semihalf.com>

Hello,

This is a set of three patches that fix long-lasting problems implemented in
the initial support for the Armada 375 network controller.

Due to an inappropriate concept of handling the per-CPU sent packets'
processing on TX path the driver numerous problems occured, such as RCU
stalls. Those have been fixed, of which details you can find in the commit
logs. The patches were intensively tested on top of v4.2-rc5.

I'm looking forward to any comments or remarks.

Thanks,
Marcin

Marcin Wojtas (3):
  net: mvpp2: remove excessive spinlocks from driver initialization
  net: mvpp2: enable proper per-CPU TX buffers unmapping
  net: mvpp2: replace TX coalescing interrupts with hrtimer

 drivers/net/ethernet/marvell/mvpp2.c | 244 ++++++++++++++++++++++++-----------
 1 file changed, 167 insertions(+), 77 deletions(-)

-- 
1.8.3.1



From mw at semihalf.com  Thu Aug  6 10:00:29 2015
From: mw at semihalf.com (Marcin Wojtas)
Date: Thu,  6 Aug 2015 19:00:29 +0200
Subject: [PATCH 2/3] net: mvpp2: enable proper per-CPU TX buffers unmapping
In-Reply-To: <1438880430-5480-1-git-send-email-mw@semihalf.com>
References: <y>
 <1438880430-5480-1-git-send-email-mw@semihalf.com>
Message-ID: <1438880430-5480-3-git-send-email-mw@semihalf.com>

mvpp2 driver allows usage of per-CPU TX processing. Once the packets are
prepared independetly on each CPU, the hardware enqueues the descriptors in
common TX queue. After they are sent, the buffers and associated sk_buffs
should be released on the corresponding CPU.

This is why a special index is maintained in order to point to the right data to
be released after transmission takes place. Each per-CPU TX queue comprise an
array of sent sk_buffs, freed in mvpp2_txq_bufs_free function. However, the
index was used there also for obtaining a descriptor (and therefore a buffer to
be DMA-unmapped) from common TX queue, which was wrong, because it was not
referring to the current CPU.

This commit enables proper unmapping of sent data buffers by indexing them in
per-CPU queues using a dedicated array for keeping their physical addresses.

Signed-off-by: Marcin Wojtas <mw at semihalf.com>
---
 drivers/net/ethernet/marvell/mvpp2.c | 52 +++++++++++++++++++++++++-----------
 1 file changed, 37 insertions(+), 15 deletions(-)

diff --git a/drivers/net/ethernet/marvell/mvpp2.c b/drivers/net/ethernet/marvell/mvpp2.c
index f94bd12..3e25d314 100644
--- a/drivers/net/ethernet/marvell/mvpp2.c
+++ b/drivers/net/ethernet/marvell/mvpp2.c
@@ -776,6 +776,9 @@ struct mvpp2_txq_pcpu {
 	/* Array of transmitted skb */
 	struct sk_buff **tx_skb;
 
+	/* Array of transmitted buffers' physical addresses */
+	dma_addr_t *tx_buffs;
+
 	/* Index of last TX DMA descriptor that was inserted */
 	int txq_put_index;
 
@@ -961,9 +964,13 @@ static void mvpp2_txq_inc_get(struct mvpp2_txq_pcpu *txq_pcpu)
 }
 
 static void mvpp2_txq_inc_put(struct mvpp2_txq_pcpu *txq_pcpu,
-			      struct sk_buff *skb)
+			      struct sk_buff *skb,
+			      struct mvpp2_tx_desc *tx_desc)
 {
 	txq_pcpu->tx_skb[txq_pcpu->txq_put_index] = skb;
+	if (skb)
+		txq_pcpu->tx_buffs[txq_pcpu->txq_put_index] =
+							 tx_desc->buf_phys_addr;
 	txq_pcpu->txq_put_index++;
 	if (txq_pcpu->txq_put_index == txq_pcpu->size)
 		txq_pcpu->txq_put_index = 0;
@@ -4392,8 +4399,8 @@ static void mvpp2_txq_bufs_free(struct mvpp2_port *port,
 	int i;
 
 	for (i = 0; i < num; i++) {
-		struct mvpp2_tx_desc *tx_desc = txq->descs +
-							txq_pcpu->txq_get_index;
+		dma_addr_t buf_phys_addr =
+				    txq_pcpu->tx_buffs[txq_pcpu->txq_get_index];
 		struct sk_buff *skb = txq_pcpu->tx_skb[txq_pcpu->txq_get_index];
 
 		mvpp2_txq_inc_get(txq_pcpu);
@@ -4401,8 +4408,8 @@ static void mvpp2_txq_bufs_free(struct mvpp2_port *port,
 		if (!skb)
 			continue;
 
-		dma_unmap_single(port->dev->dev.parent, tx_desc->buf_phys_addr,
-				 tx_desc->data_size, DMA_TO_DEVICE);
+		dma_unmap_single(port->dev->dev.parent, buf_phys_addr,
+				 skb_headlen(skb), DMA_TO_DEVICE);
 		dev_kfree_skb_any(skb);
 	}
 }
@@ -4634,12 +4641,13 @@ static int mvpp2_txq_init(struct mvpp2_port *port,
 		txq_pcpu->tx_skb = kmalloc(txq_pcpu->size *
 					   sizeof(*txq_pcpu->tx_skb),
 					   GFP_KERNEL);
-		if (!txq_pcpu->tx_skb) {
-			dma_free_coherent(port->dev->dev.parent,
-					  txq->size * MVPP2_DESC_ALIGNED_SIZE,
-					  txq->descs, txq->descs_phys);
-			return -ENOMEM;
-		}
+		if (!txq_pcpu->tx_skb)
+			goto error;
+
+		txq_pcpu->tx_buffs = kmalloc(txq_pcpu->size *
+					     sizeof(dma_addr_t), GFP_KERNEL);
+		if (!txq_pcpu->tx_buffs)
+			goto error;
 
 		txq_pcpu->count = 0;
 		txq_pcpu->reserved_num = 0;
@@ -4648,6 +4656,19 @@ static int mvpp2_txq_init(struct mvpp2_port *port,
 	}
 
 	return 0;
+
+error:
+	for_each_present_cpu(cpu) {
+		txq_pcpu = per_cpu_ptr(txq->pcpu, cpu);
+		kfree(txq_pcpu->tx_skb);
+		kfree(txq_pcpu->tx_buffs);
+	}
+
+	dma_free_coherent(port->dev->dev.parent,
+			  txq->size * MVPP2_DESC_ALIGNED_SIZE,
+			  txq->descs, txq->descs_phys);
+
+	return -ENOMEM;
 }
 
 /* Free allocated TXQ resources */
@@ -4660,6 +4681,7 @@ static void mvpp2_txq_deinit(struct mvpp2_port *port,
 	for_each_present_cpu(cpu) {
 		txq_pcpu = per_cpu_ptr(txq->pcpu, cpu);
 		kfree(txq_pcpu->tx_skb);
+		kfree(txq_pcpu->tx_buffs);
 	}
 
 	if (txq->descs)
@@ -5129,11 +5151,11 @@ static int mvpp2_tx_frag_process(struct mvpp2_port *port, struct sk_buff *skb,
 		if (i == (skb_shinfo(skb)->nr_frags - 1)) {
 			/* Last descriptor */
 			tx_desc->command = MVPP2_TXD_L_DESC;
-			mvpp2_txq_inc_put(txq_pcpu, skb);
+			mvpp2_txq_inc_put(txq_pcpu, skb, tx_desc);
 		} else {
 			/* Descriptor in the middle: Not First, Not Last */
 			tx_desc->command = 0;
-			mvpp2_txq_inc_put(txq_pcpu, NULL);
+			mvpp2_txq_inc_put(txq_pcpu, NULL, tx_desc);
 		}
 	}
 
@@ -5199,12 +5221,12 @@ static int mvpp2_tx(struct sk_buff *skb, struct net_device *dev)
 		/* First and Last descriptor */
 		tx_cmd |= MVPP2_TXD_F_DESC | MVPP2_TXD_L_DESC;
 		tx_desc->command = tx_cmd;
-		mvpp2_txq_inc_put(txq_pcpu, skb);
+		mvpp2_txq_inc_put(txq_pcpu, skb, tx_desc);
 	} else {
 		/* First but not Last */
 		tx_cmd |= MVPP2_TXD_F_DESC | MVPP2_TXD_PADDING_DISABLE;
 		tx_desc->command = tx_cmd;
-		mvpp2_txq_inc_put(txq_pcpu, NULL);
+		mvpp2_txq_inc_put(txq_pcpu, NULL, tx_desc);
 
 		/* Continue with other skb fragments */
 		if (mvpp2_tx_frag_process(port, skb, aggr_txq, txq)) {
-- 
1.8.3.1



From mw at semihalf.com  Thu Aug  6 10:00:28 2015
From: mw at semihalf.com (Marcin Wojtas)
Date: Thu,  6 Aug 2015 19:00:28 +0200
Subject: [PATCH 1/3] net: mvpp2: remove excessive spinlocks from driver
 initialization
In-Reply-To: <1438880430-5480-1-git-send-email-mw@semihalf.com>
References: <y>
 <1438880430-5480-1-git-send-email-mw@semihalf.com>
Message-ID: <1438880430-5480-2-git-send-email-mw@semihalf.com>

Using spinlocks protection during one-time driver initialization is not
necessary. Moreover it resulted in invalid GFP_KERNEL allocation under the lock.

This commit removes redundant spinlocks from buffer manager part of mvpp2
initialization.

Signed-off-by: Marcin Wojtas <mw at semihalf.com>
Reported-by: Alexandre Fournier <alexandre.fournier at wisp-e.com>
---
 drivers/net/ethernet/marvell/mvpp2.c | 15 ---------------
 1 file changed, 15 deletions(-)

diff --git a/drivers/net/ethernet/marvell/mvpp2.c b/drivers/net/ethernet/marvell/mvpp2.c
index 3e8b1bf..f94bd12 100644
--- a/drivers/net/ethernet/marvell/mvpp2.c
+++ b/drivers/net/ethernet/marvell/mvpp2.c
@@ -913,8 +913,6 @@ struct mvpp2_bm_pool {
 	/* Occupied buffers indicator */
 	atomic_t in_use;
 	int in_use_thresh;
-
-	spinlock_t lock;
 };
 
 struct mvpp2_buff_hdr {
@@ -3376,7 +3374,6 @@ static int mvpp2_bm_pool_create(struct platform_device *pdev,
 	bm_pool->pkt_size = 0;
 	bm_pool->buf_num = 0;
 	atomic_set(&bm_pool->in_use, 0);
-	spin_lock_init(&bm_pool->lock);
 
 	return 0;
 }
@@ -3647,7 +3644,6 @@ static struct mvpp2_bm_pool *
 mvpp2_bm_pool_use(struct mvpp2_port *port, int pool, enum mvpp2_bm_type type,
 		  int pkt_size)
 {
-	unsigned long flags = 0;
 	struct mvpp2_bm_pool *new_pool = &port->priv->bm_pools[pool];
 	int num;
 
@@ -3656,8 +3652,6 @@ mvpp2_bm_pool_use(struct mvpp2_port *port, int pool, enum mvpp2_bm_type type,
 		return NULL;
 	}
 
-	spin_lock_irqsave(&new_pool->lock, flags);
-
 	if (new_pool->type == MVPP2_BM_FREE)
 		new_pool->type = type;
 
@@ -3686,8 +3680,6 @@ mvpp2_bm_pool_use(struct mvpp2_port *port, int pool, enum mvpp2_bm_type type,
 		if (num != pkts_num) {
 			WARN(1, "pool %d: %d of %d allocated\n",
 			     new_pool->id, num, pkts_num);
-			/* We need to undo the bufs_add() allocations */
-			spin_unlock_irqrestore(&new_pool->lock, flags);
 			return NULL;
 		}
 	}
@@ -3695,15 +3687,12 @@ mvpp2_bm_pool_use(struct mvpp2_port *port, int pool, enum mvpp2_bm_type type,
 	mvpp2_bm_pool_bufsize_set(port->priv, new_pool,
 				  MVPP2_RX_BUF_SIZE(new_pool->pkt_size));
 
-	spin_unlock_irqrestore(&new_pool->lock, flags);
-
 	return new_pool;
 }
 
 /* Initialize pools for swf */
 static int mvpp2_swf_bm_pool_init(struct mvpp2_port *port)
 {
-	unsigned long flags = 0;
 	int rxq;
 
 	if (!port->pool_long) {
@@ -3714,9 +3703,7 @@ static int mvpp2_swf_bm_pool_init(struct mvpp2_port *port)
 		if (!port->pool_long)
 			return -ENOMEM;
 
-		spin_lock_irqsave(&port->pool_long->lock, flags);
 		port->pool_long->port_map |= (1 << port->id);
-		spin_unlock_irqrestore(&port->pool_long->lock, flags);
 
 		for (rxq = 0; rxq < rxq_number; rxq++)
 			mvpp2_rxq_long_pool_set(port, rxq, port->pool_long->id);
@@ -3730,9 +3717,7 @@ static int mvpp2_swf_bm_pool_init(struct mvpp2_port *port)
 		if (!port->pool_short)
 			return -ENOMEM;
 
-		spin_lock_irqsave(&port->pool_short->lock, flags);
 		port->pool_short->port_map |= (1 << port->id);
-		spin_unlock_irqrestore(&port->pool_short->lock, flags);
 
 		for (rxq = 0; rxq < rxq_number; rxq++)
 			mvpp2_rxq_short_pool_set(port, rxq,
-- 
1.8.3.1



From mw at semihalf.com  Thu Aug  6 10:00:30 2015
From: mw at semihalf.com (Marcin Wojtas)
Date: Thu,  6 Aug 2015 19:00:30 +0200
Subject: [PATCH 3/3] net: mvpp2: replace TX coalescing interrupts with hrtimer
In-Reply-To: <1438880430-5480-1-git-send-email-mw@semihalf.com>
References: <y>
 <1438880430-5480-1-git-send-email-mw@semihalf.com>
Message-ID: <1438880430-5480-4-git-send-email-mw@semihalf.com>

The PP2 controller is capable of per-CPU TX processing, which means there are
per-CPU banked register sets and queues. Current version of the driver supports
TX packet coalescing - once on given CPU sent packets amount reaches a threshold
value, an IRQ occurs. However, there is a single interrupt line responsible for
CPU0/1 TX and RX events (the latter is not per-CPU, the hardware does not
support RSS).

When the top-half executes the interrupt cause is not known. This is why in
NAPI poll function, along with RX processing, IRQ cause register on both
CPU's is accessed in order to determine on which of them the TX coalescing
threshold might have been reached. Thus the egress processing and releasing the
buffers is able to take place on the corresponding CPU. Hitherto approach lead
to an illegal usage of on_each_cpu function in softirq context.

The problem is solved by resigning from TX coalescing interrupts and separating
egress finalization from NAPI processing. For that purpose a method of using
hrtimer is introduced. In main transmit function (mvpp2_tx) buffers are released
once a software coalescing threshold is reached. In case not all the data is
processed a timer is set on this CPU - in its interrupt context a tasklet is
scheduled in which all queues are processed. At once only one timer per-CPU can
be running, which is controlled by a dedicated flag.

This commit removes TX processing from NAPI polling function, disables hardware
coalescing and enables hrtimer with tasklet, using new per-CPU port structure
(mvpp2_port_pcpu).

Signed-off-by: Marcin Wojtas <mw at semihalf.com>
---
 drivers/net/ethernet/marvell/mvpp2.c | 177 +++++++++++++++++++++++++----------
 1 file changed, 130 insertions(+), 47 deletions(-)

diff --git a/drivers/net/ethernet/marvell/mvpp2.c b/drivers/net/ethernet/marvell/mvpp2.c
index 3e25d314..d9884fd 100644
--- a/drivers/net/ethernet/marvell/mvpp2.c
+++ b/drivers/net/ethernet/marvell/mvpp2.c
@@ -27,6 +27,8 @@
 #include <linux/of_address.h>
 #include <linux/phy.h>
 #include <linux/clk.h>
+#include <linux/hrtimer.h>
+#include <linux/ktime.h>
 #include <uapi/linux/ppp_defs.h>
 #include <net/ip.h>
 #include <net/ipv6.h>
@@ -299,6 +301,7 @@
 
 /* Coalescing */
 #define MVPP2_TXDONE_COAL_PKTS_THRESH	15
+#define MVPP2_TXDONE_HRTIMER_PERIOD_NS	1000000UL
 #define MVPP2_RX_COAL_PKTS		32
 #define MVPP2_RX_COAL_USEC		100
 
@@ -660,6 +663,14 @@ struct mvpp2_pcpu_stats {
 	u64	tx_bytes;
 };
 
+/* Per-CPU port control */
+struct mvpp2_port_pcpu {
+	struct hrtimer tx_done_timer;
+	bool timer_scheduled;
+	/* Tasklet for egress finalization */
+	struct tasklet_struct tx_done_tasklet;
+};
+
 struct mvpp2_port {
 	u8 id;
 
@@ -679,6 +690,9 @@ struct mvpp2_port {
 	u32 pending_cause_rx;
 	struct napi_struct napi;
 
+	/* Per-CPU port control */
+	struct mvpp2_port_pcpu __percpu *pcpu;
+
 	/* Flags */
 	unsigned long flags;
 
@@ -3798,7 +3812,6 @@ static void mvpp2_interrupts_unmask(void *arg)
 
 	mvpp2_write(port->priv, MVPP2_ISR_RX_TX_MASK_REG(port->id),
 		    (MVPP2_CAUSE_MISC_SUM_MASK |
-		     MVPP2_CAUSE_TXQ_OCCUP_DESC_ALL_MASK |
 		     MVPP2_CAUSE_RXQ_OCCUP_DESC_ALL_MASK));
 }
 
@@ -4374,23 +4387,6 @@ static void mvpp2_rx_time_coal_set(struct mvpp2_port *port,
 	rxq->time_coal = usec;
 }
 
-/* Set threshold for TX_DONE pkts coalescing */
-static void mvpp2_tx_done_pkts_coal_set(void *arg)
-{
-	struct mvpp2_port *port = arg;
-	int queue;
-	u32 val;
-
-	for (queue = 0; queue < txq_number; queue++) {
-		struct mvpp2_tx_queue *txq = port->txqs[queue];
-
-		val = (txq->done_pkts_coal << MVPP2_TRANSMITTED_THRESH_OFFSET) &
-		       MVPP2_TRANSMITTED_THRESH_MASK;
-		mvpp2_write(port->priv, MVPP2_TXQ_NUM_REG, txq->id);
-		mvpp2_write(port->priv, MVPP2_TXQ_THRESH_REG, val);
-	}
-}
-
 /* Free Tx queue skbuffs */
 static void mvpp2_txq_bufs_free(struct mvpp2_port *port,
 				struct mvpp2_tx_queue *txq,
@@ -4425,7 +4421,7 @@ static inline struct mvpp2_rx_queue *mvpp2_get_rx_queue(struct mvpp2_port *port,
 static inline struct mvpp2_tx_queue *mvpp2_get_tx_queue(struct mvpp2_port *port,
 							u32 cause)
 {
-	int queue = fls(cause >> 16) - 1;
+	int queue = fls(cause) - 1;
 
 	return port->txqs[queue];
 }
@@ -4452,6 +4448,29 @@ static void mvpp2_txq_done(struct mvpp2_port *port, struct mvpp2_tx_queue *txq,
 			netif_tx_wake_queue(nq);
 }
 
+static unsigned int mvpp2_tx_done(struct mvpp2_port *port, u32 cause)
+{
+	struct mvpp2_tx_queue *txq;
+	struct mvpp2_txq_pcpu *txq_pcpu;
+	unsigned int tx_todo = 0;
+
+	while (cause) {
+		txq = mvpp2_get_tx_queue(port, cause);
+		if (!txq)
+			break;
+
+		txq_pcpu = this_cpu_ptr(txq->pcpu);
+
+		if (txq_pcpu->count) {
+			mvpp2_txq_done(port, txq, txq_pcpu);
+			tx_todo += txq_pcpu->count;
+		}
+
+		cause &= ~(1 << txq->log_id);
+	}
+	return tx_todo;
+}
+
 /* Rx/Tx queue initialization/cleanup methods */
 
 /* Allocate and initialize descriptors for aggr TXQ */
@@ -4812,7 +4831,6 @@ static int mvpp2_setup_txqs(struct mvpp2_port *port)
 			goto err_cleanup;
 	}
 
-	on_each_cpu(mvpp2_tx_done_pkts_coal_set, port, 1);
 	on_each_cpu(mvpp2_txq_sent_counter_clear, port, 1);
 	return 0;
 
@@ -4894,6 +4912,49 @@ static void mvpp2_link_event(struct net_device *dev)
 	}
 }
 
+static void mvpp2_timer_set(struct mvpp2_port_pcpu *port_pcpu)
+{
+	ktime_t interval;
+
+	if (!port_pcpu->timer_scheduled) {
+		port_pcpu->timer_scheduled = true;
+		interval = ktime_set(0, MVPP2_TXDONE_HRTIMER_PERIOD_NS);
+		hrtimer_start(&port_pcpu->tx_done_timer, interval,
+			      HRTIMER_MODE_REL_PINNED);
+	}
+}
+
+static void mvpp2_tx_proc_cb(unsigned long data)
+{
+	struct net_device *dev = (struct net_device *)data;
+	struct mvpp2_port *port = netdev_priv(dev);
+	struct mvpp2_port_pcpu *port_pcpu = this_cpu_ptr(port->pcpu);
+	unsigned int tx_todo, cause;
+
+	if (!netif_running(dev))
+		return;
+	port_pcpu->timer_scheduled = false;
+
+	/* Process all the Tx queues */
+	cause = (1 << txq_number) - 1;
+	tx_todo = mvpp2_tx_done(port, cause);
+
+	/* Set the timer in case not all the packets were processed */
+	if (tx_todo)
+		mvpp2_timer_set(port_pcpu);
+}
+
+static enum hrtimer_restart mvpp2_hr_timer_cb(struct hrtimer *timer)
+{
+	struct mvpp2_port_pcpu *port_pcpu = container_of(timer,
+							 struct mvpp2_port_pcpu,
+							 tx_done_timer);
+
+	tasklet_schedule(&port_pcpu->tx_done_tasklet);
+
+	return HRTIMER_NORESTART;
+}
+
 /* Main RX/TX processing routines */
 
 /* Display more error info */
@@ -5262,6 +5323,17 @@ out:
 		dev_kfree_skb_any(skb);
 	}
 
+	/* Finalize TX processing */
+	if (txq_pcpu->count >= txq->done_pkts_coal)
+		mvpp2_txq_done(port, txq, txq_pcpu);
+
+	/* Set the timer in case not all frags were processed */
+	if (txq_pcpu->count <= frags && txq_pcpu->count > 0) {
+		struct mvpp2_port_pcpu *port_pcpu = this_cpu_ptr(port->pcpu);
+
+		mvpp2_timer_set(port_pcpu);
+	}
+
 	return NETDEV_TX_OK;
 }
 
@@ -5275,10 +5347,11 @@ static inline void mvpp2_cause_error(struct net_device *dev, int cause)
 		netdev_err(dev, "tx fifo underrun error\n");
 }
 
-static void mvpp2_txq_done_percpu(void *arg)
+static int mvpp2_poll(struct napi_struct *napi, int budget)
 {
-	struct mvpp2_port *port = arg;
-	u32 cause_rx_tx, cause_tx, cause_misc;
+	u32 cause_rx_tx, cause_rx, cause_misc;
+	int rx_done = 0;
+	struct mvpp2_port *port = netdev_priv(napi->dev);
 
 	/* Rx/Tx cause register
 	 *
@@ -5292,7 +5365,7 @@ static void mvpp2_txq_done_percpu(void *arg)
 	 */
 	cause_rx_tx = mvpp2_read(port->priv,
 				 MVPP2_ISR_RX_TX_CAUSE_REG(port->id));
-	cause_tx = cause_rx_tx & MVPP2_CAUSE_TXQ_OCCUP_DESC_ALL_MASK;
+	cause_rx_tx &= ~MVPP2_CAUSE_TXQ_OCCUP_DESC_ALL_MASK;
 	cause_misc = cause_rx_tx & MVPP2_CAUSE_MISC_SUM_MASK;
 
 	if (cause_misc) {
@@ -5304,26 +5377,6 @@ static void mvpp2_txq_done_percpu(void *arg)
 			    cause_rx_tx & ~MVPP2_CAUSE_MISC_SUM_MASK);
 	}
 
-	/* Release TX descriptors */
-	if (cause_tx) {
-		struct mvpp2_tx_queue *txq = mvpp2_get_tx_queue(port, cause_tx);
-		struct mvpp2_txq_pcpu *txq_pcpu = this_cpu_ptr(txq->pcpu);
-
-		if (txq_pcpu->count)
-			mvpp2_txq_done(port, txq, txq_pcpu);
-	}
-}
-
-static int mvpp2_poll(struct napi_struct *napi, int budget)
-{
-	u32 cause_rx_tx, cause_rx;
-	int rx_done = 0;
-	struct mvpp2_port *port = netdev_priv(napi->dev);
-
-	on_each_cpu(mvpp2_txq_done_percpu, port, 1);
-
-	cause_rx_tx = mvpp2_read(port->priv,
-				 MVPP2_ISR_RX_TX_CAUSE_REG(port->id));
 	cause_rx = cause_rx_tx & MVPP2_CAUSE_RXQ_OCCUP_DESC_ALL_MASK;
 
 	/* Process RX packets */
@@ -5568,6 +5621,8 @@ err_cleanup_rxqs:
 static int mvpp2_stop(struct net_device *dev)
 {
 	struct mvpp2_port *port = netdev_priv(dev);
+	struct mvpp2_port_pcpu *port_pcpu;
+	int cpu;
 
 	mvpp2_stop_dev(port);
 	mvpp2_phy_disconnect(port);
@@ -5576,6 +5631,13 @@ static int mvpp2_stop(struct net_device *dev)
 	on_each_cpu(mvpp2_interrupts_mask, port, 1);
 
 	free_irq(port->irq, port);
+	for_each_present_cpu(cpu) {
+		port_pcpu = per_cpu_ptr(port->pcpu, cpu);
+
+		hrtimer_cancel(&port_pcpu->tx_done_timer);
+		port_pcpu->timer_scheduled = false;
+		tasklet_kill(&port_pcpu->tx_done_tasklet);
+	}
 	mvpp2_cleanup_rxqs(port);
 	mvpp2_cleanup_txqs(port);
 
@@ -5791,7 +5853,6 @@ static int mvpp2_ethtool_set_coalesce(struct net_device *dev,
 		txq->done_pkts_coal = c->tx_max_coalesced_frames;
 	}
 
-	on_each_cpu(mvpp2_tx_done_pkts_coal_set, port, 1);
 	return 0;
 }
 
@@ -6042,6 +6103,7 @@ static int mvpp2_port_probe(struct platform_device *pdev,
 {
 	struct device_node *phy_node;
 	struct mvpp2_port *port;
+	struct mvpp2_port_pcpu *port_pcpu;
 	struct net_device *dev;
 	struct resource *res;
 	const char *dt_mac_addr;
@@ -6051,7 +6113,7 @@ static int mvpp2_port_probe(struct platform_device *pdev,
 	int features;
 	int phy_mode;
 	int priv_common_regs_num = 2;
-	int err, i;
+	int err, i, cpu;
 
 	dev = alloc_etherdev_mqs(sizeof(struct mvpp2_port), txq_number,
 				 rxq_number);
@@ -6142,6 +6204,24 @@ static int mvpp2_port_probe(struct platform_device *pdev,
 	}
 	mvpp2_port_power_up(port);
 
+	port->pcpu = alloc_percpu(struct mvpp2_port_pcpu);
+	if (!port->pcpu) {
+		err = -ENOMEM;
+		goto err_free_txq_pcpu;
+	}
+
+	for_each_present_cpu(cpu) {
+		port_pcpu = per_cpu_ptr(port->pcpu, cpu);
+
+		hrtimer_init(&port_pcpu->tx_done_timer, CLOCK_MONOTONIC,
+			     HRTIMER_MODE_REL_PINNED);
+		port_pcpu->tx_done_timer.function = mvpp2_hr_timer_cb;
+		port_pcpu->timer_scheduled = false;
+
+		tasklet_init(&port_pcpu->tx_done_tasklet, mvpp2_tx_proc_cb,
+			     (unsigned long)dev);
+	}
+
 	netif_napi_add(dev, &port->napi, mvpp2_poll, NAPI_POLL_WEIGHT);
 	features = NETIF_F_SG | NETIF_F_IP_CSUM;
 	dev->features = features | NETIF_F_RXCSUM;
@@ -6151,7 +6231,7 @@ static int mvpp2_port_probe(struct platform_device *pdev,
 	err = register_netdev(dev);
 	if (err < 0) {
 		dev_err(&pdev->dev, "failed to register netdev\n");
-		goto err_free_txq_pcpu;
+		goto err_free_port_pcpu;
 	}
 	netdev_info(dev, "Using %s mac address %pM\n", mac_from, dev->dev_addr);
 
@@ -6160,6 +6240,8 @@ static int mvpp2_port_probe(struct platform_device *pdev,
 	priv->port_list[id] = port;
 	return 0;
 
+err_free_port_pcpu:
+	free_percpu(port->pcpu);
 err_free_txq_pcpu:
 	for (i = 0; i < txq_number; i++)
 		free_percpu(port->txqs[i]->pcpu);
@@ -6178,6 +6260,7 @@ static void mvpp2_port_remove(struct mvpp2_port *port)
 	int i;
 
 	unregister_netdev(port->dev);
+	free_percpu(port->pcpu);
 	free_percpu(port->stats);
 	for (i = 0; i < txq_number; i++)
 		free_percpu(port->txqs[i]->pcpu);
-- 
1.8.3.1



From benoar at dolka.fr  Thu Aug  6 10:08:57 2015
From: benoar at dolka.fr (Benjamin Cama)
Date: Thu, 06 Aug 2015 19:08:57 +0200
Subject: [PATCH v3] ARM: dts: Convert Linkstation Mini to Device Tree
In-Reply-To: <55C3929F.3030209@free-electrons.com>
References: <1438878592.15635.89.camel@dolka.fr>
 <20150806163424.GH13421@lunn.ch> <1438879473.15635.91.camel@dolka.fr>
 <55C3929F.3030209@free-electrons.com>
Message-ID: <1438880937.15635.92.camel@dolka.fr>

Hi Gr?gory,

Le jeudi 06 ao?t 2015 ? 19:00 +0200, Gregory CLEMENT a ?crit :
> On 06/08/2015 18:44, Benjamin Cama wrote:
> > Hi Andrew,
> > 
> > Le jeudi 06 ao?t 2015 ? 18:34 +0200, Andrew Lunn a ?crit :
> > > On Thu, Aug 06, 2015 at 06:29:52PM +0200, Benjamin Cama wrote:
> > > > The title says it all. The name of the dts file as been changed 
> > > > to
> > > > better reflect the manufacturer's device name (LS-WSGL), rather 
> > > > 
> > > > than
> > > > the original "lsmini", which exists in a kirkwood version too.
> > > > 
> > > > Signed-off-by: Benjamin Cama <benoar at dolka.fr>
> > > 
> > > Hi Benjamin
> > > 
> > > It would be normal to add the various Acked-by: here, both Alexey 
> > > and
> > > mine. It is not an issue, Gregory can add them, when he adds is 
> > > own.
> > > I'm just mentioning it for any future patches you might submit.
> > 
> > Ah, OK, I was not sure and didn't want to add them by mistake.
> 
> applied on mvebu/dt with the Acked-by: flags but also with some minor
> fixes :I used tab instead of space to indent dts at line 185

Sorry, missed that.

> and I
> also resolved the merge conflict with patch "ARM: dts: orion5x: add
> buffalo linkstation ls-wtgl" in the file arch/arm/boot/dts/Makefile.

Thanks, I didn't rebase on master for some time?

Thanks again for your time,
--
benjamin


From drew.richardson at arm.com  Thu Aug  6 10:08:03 2015
From: drew.richardson at arm.com (Drew Richardson)
Date: Thu, 6 Aug 2015 10:08:03 -0700
Subject: [PATCH] ARM: Mark ret_fast_syscall as a function
In-Reply-To: <1436877957-18127-1-git-send-email-drew.richardson@arm.com>
References: <1436877957-18127-1-git-send-email-drew.richardson@arm.com>
Message-ID: <20150806170758.GA26691@dreric01-gentoo.localdomain>

On Tue, Jul 14, 2015 at 01:45:57PM +0100, Drew Richardson wrote:
> ret_fast_syscall runs when user space makes a syscall. However it
> needs to be marked as such so the ELF information is correct. Before
> it was:
> 
>    101: 8000f300     0 NOTYPE  LOCAL  DEFAULT    2 ret_fast_syscall
> 
> But with this change it correctly shows as:
> 
>    101: 8000f300    96 FUNC    LOCAL  DEFAULT    2 ret_fast_syscall
> 
> I see this function when using perf to unwind call stacks from kernel
> space to user space. Without this change I would need to add some
> special case logic when using the vmlinux ELF information.
> 
> Signed-off-by: Drew Richardson <drew.richardson at arm.com>

I haven't heard any further comments on this, did this get merged and
I just didn't notice? Or did I forget to add someone?

Thanks,

Drew


From gregory.clement at free-electrons.com  Thu Aug  6 10:15:59 2015
From: gregory.clement at free-electrons.com (Gregory CLEMENT)
Date: Thu, 06 Aug 2015 19:15:59 +0200
Subject: [PATCH v3] ARM: dts: Convert Linkstation Mini to Device Tree
In-Reply-To: <1438880937.15635.92.camel@dolka.fr>
References: <1438878592.15635.89.camel@dolka.fr>	
 <20150806163424.GH13421@lunn.ch> <1438879473.15635.91.camel@dolka.fr>	
 <55C3929F.3030209@free-electrons.com> <1438880937.15635.92.camel@dolka.fr>
Message-ID: <55C3964F.5010708@free-electrons.com>

Hi Benjamin,

On 06/08/2015 19:08, Benjamin Cama wrote:
> Hi Gr?gory,
> 
> Le jeudi 06 ao?t 2015 ? 19:00 +0200, Gregory CLEMENT a ?crit :
>> On 06/08/2015 18:44, Benjamin Cama wrote:
>>> Hi Andrew,
>>>
>>> Le jeudi 06 ao?t 2015 ? 18:34 +0200, Andrew Lunn a ?crit :
>>>> On Thu, Aug 06, 2015 at 06:29:52PM +0200, Benjamin Cama wrote:
>>>>> The title says it all. The name of the dts file as been changed 
>>>>> to
>>>>> better reflect the manufacturer's device name (LS-WSGL), rather 
>>>>>
>>>>> than
>>>>> the original "lsmini", which exists in a kirkwood version too.
>>>>>
>>>>> Signed-off-by: Benjamin Cama <benoar at dolka.fr>
>>>>
>>>> Hi Benjamin
>>>>
>>>> It would be normal to add the various Acked-by: here, both Alexey 
>>>> and
>>>> mine. It is not an issue, Gregory can add them, when he adds is 
>>>> own.
>>>> I'm just mentioning it for any future patches you might submit.
>>>
>>> Ah, OK, I was not sure and didn't want to add them by mistake.
>>
>> applied on mvebu/dt with the Acked-by: flags but also with some minor
>> fixes :I used tab instead of space to indent dts at line 185
> 
> Sorry, missed that.

No problem it was very minor, actually I didn't find myself, checpatch did
it for me :)

> 
>> and I
>> also resolved the merge conflict with patch "ARM: dts: orion5x: add
>> buffalo linkstation ls-wtgl" in the file arch/arm/boot/dts/Makefile.
> 
> Thanks, I didn't rebase on master for some time?

For this one you could not have do better, because the conflict
comes from a commit in my mvebu/dt branch and when you send a patch
we expect that it is based on the rc1. So it was really my job to
do this.

> 
> Thanks again for your time,

You're welcome and thanks for your contributions,

Gregory
-- 
Gregory Clement, Free Electrons
Kernel, drivers, real-time and embedded Linux
development, consulting, training and support.
http://free-electrons.com


From andrew at lunn.ch  Thu Aug  6 10:13:12 2015
From: andrew at lunn.ch (Andrew Lunn)
Date: Thu, 6 Aug 2015 19:13:12 +0200
Subject: Armadaxp GPIO interrupts
In-Reply-To: <CAG1O52XUyPkgTTRKftujZBNK1=n6GBdWgBg_kq6SsC5XMaeU3w@mail.gmail.com>
References: <CAG1O52Xg88OsifBzmpSdqvC8wQaOW78nC9nnfxugFv1VU1m1LQ@mail.gmail.com>
 <20150804153439.GA28673@lunn.ch>
 <CAG1O52W2Gy_6_DfewtUqoK_J+Y=KwVGyygNaPu2xyPM_ZkLfcQ@mail.gmail.com>
 <CAG1O52VQPpeGkA8bqYbPMTiT9Mua1yHi3H3osqJsHqm-RRKzow@mail.gmail.com>
 <20150805162155.GE32760@lunn.ch>
 <CAG1O52WPFfm+XGk01iUVWLu=-Dm7bcDVmhv3P8iQDH+HHjsLUA@mail.gmail.com>
 <20150806132926.GB19896@lunn.ch>
 <CAG1O52XUyPkgTTRKftujZBNK1=n6GBdWgBg_kq6SsC5XMaeU3w@mail.gmail.com>
Message-ID: <20150806171312.GI13421@lunn.ch>

On Thu, Aug 06, 2015 at 10:28:12PM +0530, raghu MG wrote:
> Ok,I think I need to understand more about this gpio driver.
> 
> As you said its registering chained handler,but why are they(IRQs) not
> visible in cat /proc/interrupts.

chained interrupts are never visible there. All you see are leaf
interrupts, i.e. the device interrupts. Here is my Armada XP based
WRT1900AC:

$ cat /proc/interrupts 
            CPU0       CPU1       
 16:    8959833   12783597  armada_370_xp_irq   5 Level     armada_370_xp_per_cpu_tick
 19:          0          0  armada_370_xp_irq  31 Level     mv64xxx_i2c
 20:       1453          0  armada_370_xp_irq  41 Level     serial
 26:          0          0  armada_370_xp_irq  45 Level     ehci_hcd:usb3
 27:       9682          0  armada_370_xp_irq   8 Level     mvneta
 28:          4          0  armada_370_xp_irq  10 Level     mvneta
 29:      35078          0  armada_370_xp_irq  55 Level     f10a0000.sata
 30:       3839          0  armada_370_xp_irq 113 Level     f10d0000.nand
 70:          0          0  f1018140.gpio   0 Edge      WPS
 71:         20          0  f1018140.gpio   1 Edge      Factory Reset Button
 90:          2          0  armada_370_xp_irq  51 Level     f1060900.xor
 91:          2          0  armada_370_xp_irq  52 Level     f1060900.xor
 92:          2          0  armada_370_xp_irq  94 Level     f10f0900.xor
 93:          2          0  armada_370_xp_irq  95 Level     f10f0900.xor
 94:          0          0  armada_370_xp_msi_irq   0 Edge      xhci_hcd

Notice the two f1018140.gpio, which are the buttons.

> Do I need to further initialize marvell GPIO registers to trigger
> these events.

Nope, just the normal gpio API and all will work, as demonstrated by
the two buttons on my board.

> Do I need to change the polarity in polarity register to suit the
> board requirements in probe function.

Nope, you put that in the DT file:

        gpio_keys {
                compatible = "gpio-keys";
                #address-cells = <1>;
                #size-cells = <0>;
                pinctrl-0 = <&keys_pin>;
                pinctrl-names = "default";

                button at 1 {
                        label = "WPS";
                        linux,code = <KEY_WPS_BUTTON>;
                        gpios = <&gpio1 0 GPIO_ACTIVE_HIGH>;
                };

                button at 2 {
                        label = "Factory Reset Button";
                        linux,code = <KEY_RESTART>;
                        gpios = <&gpio1 1 GPIO_ACTIVE_HIGH>;
                };
        };

You can change GPIO_ACTIVE_HIGH to GPIO_ACTIVE_LOW if that is what you
need.

	Andrew
 


From broonie at kernel.org  Thu Aug  6 10:27:52 2015
From: broonie at kernel.org (Mark Brown)
Date: Thu, 6 Aug 2015 18:27:52 +0100
Subject: next-20150806 build: 2 failures 52 warnings (next-20150806)
In-Reply-To: <E1ZNIul-0007IF-Ev@optimist>
References: <E1ZNIul-0007IF-Ev@optimist>
Message-ID: <20150806172752.GA20873@sirena.org.uk>

On Thu, Aug 06, 2015 at 12:00:47PM +0100, Build bot for Mark Brown wrote:

Today's linux-next fails to build an ARM allmodconfig with:

> 	arm-allmodconfig
> ../lib/test_user_copy.c:67:2: error: implicit declaration of function 'copy_in_user' [-Werror=implicit-function-declaration]
> ../lib/test_user_copy.c:94:2: error: implicit declaration of function '__copy_in_user' [-Werror=implicit-function-declaration]

due to 3a646f02c7 (lib/test_user_copy.c: check
__copy_in_user()/copy_in_user()) which attempts to test copy_in_user()
which doesn't appear to be defined, at least with the set of include
files and/or config options you get with an allmodconfig and not at all
as far as I can tell.
-------------- next part --------------
A non-text attachment was scrubbed...
Name: signature.asc
Type: application/pgp-signature
Size: 473 bytes
Desc: Digital signature
URL: <http://lists.infradead.org/pipermail/linux-arm-kernel/attachments/20150806/6b5baeb9/attachment.sig>

From nicolas.pitre at linaro.org  Thu Aug  6 10:30:40 2015
From: nicolas.pitre at linaro.org (Nicolas Pitre)
Date: Thu, 6 Aug 2015 13:30:40 -0400 (EDT)
Subject: [PATCH] ARM: Mark ret_fast_syscall as a function
In-Reply-To: <20150806170758.GA26691@dreric01-gentoo.localdomain>
References: <1436877957-18127-1-git-send-email-drew.richardson@arm.com>
 <20150806170758.GA26691@dreric01-gentoo.localdomain>
Message-ID: <alpine.LFD.2.20.1508061327510.1515@knanqh.ubzr>

On Thu, 6 Aug 2015, Drew Richardson wrote:

> On Tue, Jul 14, 2015 at 01:45:57PM +0100, Drew Richardson wrote:
> > ret_fast_syscall runs when user space makes a syscall. However it
> > needs to be marked as such so the ELF information is correct. Before
> > it was:
> > 
> >    101: 8000f300     0 NOTYPE  LOCAL  DEFAULT    2 ret_fast_syscall
> > 
> > But with this change it correctly shows as:
> > 
> >    101: 8000f300    96 FUNC    LOCAL  DEFAULT    2 ret_fast_syscall
> > 
> > I see this function when using perf to unwind call stacks from kernel
> > space to user space. Without this change I would need to add some
> > special case logic when using the vmlinux ELF information.
> > 
> > Signed-off-by: Drew Richardson <drew.richardson at arm.com>
> 
> I haven't heard any further comments on this, did this get merged and
> I just didn't notice? Or did I forget to add someone?

Most likely that it is so trivial that nobody paid much attention.

FWIW, you can add

Acked-by: Nicolas Pitre <nico at linaro.org>

and submit it here: http://www.arm.linux.org.uk/developer/patches/


Nicolas


From hdegoede at redhat.com  Thu Aug  6 07:35:08 2015
From: hdegoede at redhat.com (Hans de Goede)
Date: Thu, 6 Aug 2015 16:35:08 +0200
Subject: [linux-sunxi] [PATCH] musb: sunxi: Ignore VBus errors in
 host-only mode
In-Reply-To: <55C31963.2010701@schinagl.nl>
References: <1438723553-4136-1-git-send-email-hdegoede@redhat.com>
 <55C31963.2010701@schinagl.nl>
Message-ID: <55C3709C.4080609@redhat.com>

Hi,

On 06-08-15 10:22, Olliver Schinagl wrote:
> Hey Hans,
>
> I've tried getting your musb stuff working on a cubietruck, but i don't seem to see this patch on your linux-sunxi/sunxi-wip branch on github? Is your github branch fully functional at the moment?
>
> What I have done so far, is build the kernel using sunxi_defconfig and enabled USB_MUSB_SUNXI with its dependancies (musb isn't enabled there by default): USB_SUPPORT [=y] && USB_MUSB_HDRC [=y] && ARCH_SUNXI [=y] && NOP_USB_XCEIV [=y] && PHY_SUN4I_USB [=y] && EXTCON [=y] && GENERIC_PHY [=y]  Selects: SUNXI_SRAM [=y]
>
> I changed the dts from dr_mode='otg' to dr_mode='host', a) we only need host mode anyway (the id pin isn't properly connected)

If you change the dr_mode to host then you _must_ also remove any id_det and vbus_det
gpio settings from the usb_phy node in the dts, as the sun4i phy code detects
host vs otg mode by checking for the presence of these.

 > and b) I got an error about an known dr_mode before and this was the quick and easy way.
>
> Dmesg produces the following related to musb.
>
> [    1.691062] usb_phy_generic.0.auto supply vcc not found, using dummy regulator
> [    1.691445] musb-hdrc: ConfigData=0xde (UTMI-8, dyn FIFOs, bulk combine, bulk split, HB-ISO Rx, HB-ISO Tx, SoftConn)
> [    1.691453] musb-hdrc: MHDRC RTL version 0.0
> [    1.691467] musb-hdrc: 11/11 max ep, 5184/8192 memory
> [    1.691543] musb-hdrc musb-hdrc.1.auto: MUSB HDRC host driver
> [    1.691553] musb-hdrc musb-hdrc.1.auto: new USB bus registered, assigned bus number 5
> [    1.692470] hub 5-0:1.0: USB hub found
> [    1.692529] hub 5-0:1.0: 1 port detected
> [    1.699956] sunxi-rtc 1c20d00.rtc: setting system clock to 2015-08-06 07:59:08 UTC (1438847948)
> [    1.704733] usb0-vbus: disabling
> [    1.765695] ldo4: disabling
> [    1.808351] ldo3: disabling
> [    1.848769] vcc5v0: disabling
> [    1.848774] vcc3v0: disabling
>
> The usb_phy_generic missing shouldn't be too bad? But the usb0-vbus being disabled obviously might be related to the musb port not working?

Correct.

For starters I would try the dts changes I suggested above.

Regards,

Hans


From boris.ostrovsky at oracle.com  Thu Aug  6 10:34:52 2015
From: boris.ostrovsky at oracle.com (Boris Ostrovsky)
Date: Thu, 06 Aug 2015 13:34:52 -0400
Subject: Fw: drivers/xen/pci.c:31:25: fatal error: asm/pci_x86.h: No such
 file or directory
In-Reply-To: <20150806170426.GM1820@rric.localhost>
References: <20150806170426.GM1820@rric.localhost>
Message-ID: <55C39ABC.5020101@oracle.com>

On 08/06/2015 01:04 PM, Robert Richter wrote:
> Boris,
>
> we are working on acpi pci support for arm64. For this we are enabling
> PCI_MMCONFIG on arm64 which breaks compiling drivers/xen/pci.c.
>
> Looking into it there is x86 code in generic driver code introduced
> with:
>
>   8deb3eb1461e xen/mcfg: Call PHYSDEVOP_pci_mmcfg_reserved for MCFG areas.
>
> This implements:
>
> diff --git a/drivers/xen/pci.c b/drivers/xen/pci.c
> index 18fff88254eb..d15f6e80479f 100644
> --- a/drivers/xen/pci.c
> +++ b/drivers/xen/pci.c
> @@ -26,6 +26,7 @@
>   #include <asm/xen/hypervisor.h>
>   #include <asm/xen/hypercall.h>
>   #include "../pci/pci.h"
> +#include <asm/pci_x86.h>
>   
>   static bool __read_mostly pci_seg_supported = true;
>   
> @@ -192,3 +193,49 @@ static int __init register_xen_pci_notifier(void)
>   }
>   
>   arch_initcall(register_xen_pci_notifier);
> +
> +#ifdef CONFIG_PCI_MMCONFIG
> +static int __init xen_mcfg_late(void)
> +{
> +       struct pci_mmcfg_region *cfg;
> +       int rc;
> +
> +       if (!xen_initial_domain())
> +               return 0;
> +
> +       if ((pci_probe & PCI_PROBE_MMCONF) == 0)
> +               return 0;
> [...]
>
> There are no defines for pci_probe and PCI_PROBE_MMCONF other than for
> the x86 architecture.
>
> I see several ways to fix that:
>
>   * moving code to arch/x86/pci/xen.c,

If this routine is not going to be used by ARM I think this would be the 
way to go. Stefano --- will this be needed by ARM?

>
>   * make code dependent on arch X86,
>
>   * make 'if (pci_probe & PCI_PROBE_MMCONF) ...' an arch function to be
>     implemented by archs,

Otherwise I'd go with this.

-boris

>
>   * reworking the code by removing the check (not sure if that could be
>     done).
>
> I don't think PCI_XEN is enabled yet for arm64, so we just disalbe it
> for !X86 or move it to arch/x86. I suggest the latter. Is there any
> preference you have?


From heiko at sntech.de  Thu Aug  6 10:33:32 2015
From: heiko at sntech.de (Heiko =?ISO-8859-1?Q?St=FCbner?=)
Date: Thu, 06 Aug 2015 19:33:32 +0200
Subject: [PATCH v2 1/2] ARM: dts: rockchip: reserve unusable memory region on
 rk3288
Message-ID: <1763907.pckMEaRNPs@diego>

The all current Rockchip SoCs supporting 4GB of ram have problems accessing
the memory region 0xfe000000~0xff000000. This also seems to includes the
rk3368 arm64 soc.

All current code handling dma memory oddities I could find, seem to involve
soc-specific code (zone-dma or so) while this issue is shared between arm32
and arm64 socs from Rockchip, which would need to have this described in
the soc devicetree on both socs.

Limiting the dma-zone alone also does not solve the issue and as the
dma-masks need to be a power-of-two in the kernel, the next lower dma-mask
brings memory usable for dma down to 2GB.

So as a stop-gap block off the affected region to prevent its use by
devices with 4GB of memory, like some recent Chromebooks.

Signed-off-by: Heiko Stuebner <heiko at sntech.de>
---
changes since v1:
- expand reasons for the reserved memory

 arch/arm/boot/dts/rk3288.dtsi | 20 ++++++++++++++++++++
 1 file changed, 20 insertions(+)

diff --git a/arch/arm/boot/dts/rk3288.dtsi b/arch/arm/boot/dts/rk3288.dtsi
index 47a15aa..118fe74 100644
--- a/arch/arm/boot/dts/rk3288.dtsi
+++ b/arch/arm/boot/dts/rk3288.dtsi
@@ -169,6 +169,26 @@
 		};
 	};
 
+	reserved-memory {
+		#address-cells = <1>;
+		#size-cells = <1>;
+		ranges;
+
+		/*
+		 * The rk3288 cannot use the memory area above 0xfe000000
+		 * for dma operations for some reason. While there is
+		 * probably a better solution available somewhere, we
+		 * haven't found it yet and while devices with 2GB of ram
+		 * are not affected, this issue prevents 4GB from booting.
+		 * So to make these devices at least bootable, block
+		 * this area for the time being until the real solution
+		 * is found.
+		 */
+		dma-unusable at fe000000 {
+			reg = <0xfe000000 0x1000000>;
+		};
+	};
+
 	xin24m: oscillator {
 		compatible = "fixed-clock";
 		clock-frequency = <24000000>;
-- 
2.1.4




From heiko at sntech.de  Thu Aug  6 10:37:54 2015
From: heiko at sntech.de (Heiko =?ISO-8859-1?Q?St=FCbner?=)
Date: Thu, 06 Aug 2015 19:37:54 +0200
Subject: [PATCH v2 2/2] ARM: dts: rockchip: add veyron-minnie board
In-Reply-To: <1763907.pckMEaRNPs@diego>
References: <1763907.pckMEaRNPs@diego>
Message-ID: <3051758.nWNxbUbTXs@diego>

From: Alexandru M Stan <amstan at chromium.org>

Also known as the Asus Chromebook Flip.

Signed-off-by: Alexandru M Stan <amstan at chromium.org>
Signed-off-by: Heiko Stuebner <heiko at sntech.de>
---
 Documentation/devicetree/bindings/arm/rockchip.txt |   7 +
 arch/arm/boot/dts/Makefile                         |   1 +
 arch/arm/boot/dts/rk3288-veyron-minnie.dts         | 253 +++++++++++++++++++++
 3 files changed, 261 insertions(+)
 create mode 100644 arch/arm/boot/dts/rk3288-veyron-minnie.dts

diff --git a/Documentation/devicetree/bindings/arm/rockchip.txt b/Documentation/devicetree/bindings/arm/rockchip.txt
index c7411cc..af58cd7 100644
--- a/Documentation/devicetree/bindings/arm/rockchip.txt
+++ b/Documentation/devicetree/bindings/arm/rockchip.txt
@@ -38,6 +38,13 @@ Rockchip platforms device tree bindings
 		     "google,veyron-jerry-rev3", "google,veyron-jerry",
 		     "google,veyron", "rockchip,rk3288";
 
+- Google Minnie (Asus Chromebook Flip C100P):
+    Required root node properties:
+      - compatible = "google,veyron-minnie-rev4", "google,veyron-minnie-rev3",
+		     "google,veyron-minnie-rev2", "google,veyron-minnie-rev1",
+		     "google,veyron-minnie-rev0", "google,veyron-minnie",
+		     "google,veyron", "rockchip,rk3288";
+
 - Google Pinky (dev-board):
     Required root node properties:
       - compatible = "google,veyron-pinky-rev2", "google,veyron-pinky",
diff --git a/arch/arm/boot/dts/Makefile b/arch/arm/boot/dts/Makefile
index 7017d8e..7805a65 100644
--- a/arch/arm/boot/dts/Makefile
+++ b/arch/arm/boot/dts/Makefile
@@ -491,6 +491,7 @@ dtb-$(CONFIG_ARCH_ROCKCHIP) += \
 	rk3288-firefly.dtb \
 	rk3288-r89.dtb \
 	rk3288-veyron-jerry.dtb \
+	rk3288-veyron-minnie.dtb \
 	rk3288-veyron-pinky.dtb \
 	rk3288-veyron-speedy.dtb
 dtb-$(CONFIG_ARCH_S3C24XX) += \
diff --git a/arch/arm/boot/dts/rk3288-veyron-minnie.dts b/arch/arm/boot/dts/rk3288-veyron-minnie.dts
new file mode 100644
index 0000000..4ce1ec9
--- /dev/null
+++ b/arch/arm/boot/dts/rk3288-veyron-minnie.dts
@@ -0,0 +1,253 @@
+/*
+ * Google Veyron Minnie Rev 0+ board device tree source
+ *
+ * Copyright 2015 Google, Inc
+ *
+ * This file is dual-licensed: you can use it either under the terms
+ * of the GPL or the X11 license, at your option. Note that this dual
+ * licensing only applies to this file, and not this project as a
+ * whole.
+ *
+ *  a) This file is free software; you can redistribute it and/or
+ *     modify it under the terms of the GNU General Public License as
+ *     published by the Free Software Foundation; either version 2 of the
+ *     License, or (at your option) any later version.
+ *
+ *     This file is distributed in the hope that it will be useful,
+ *     but WITHOUT ANY WARRANTY; without even the implied warranty of
+ *     MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ *     GNU General Public License for more details.
+ *
+ *  Or, alternatively,
+ *
+ *  b) Permission is hereby granted, free of charge, to any person
+ *     obtaining a copy of this software and associated documentation
+ *     files (the "Software"), to deal in the Software without
+ *     restriction, including without limitation the rights to use,
+ *     copy, modify, merge, publish, distribute, sublicense, and/or
+ *     sell copies of the Software, and to permit persons to whom the
+ *     Software is furnished to do so, subject to the following
+ *     conditions:
+ *
+ *     The above copyright notice and this permission notice shall be
+ *     included in all copies or substantial portions of the Software.
+ *
+ *     THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
+ *     EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES
+ *     OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
+ *     NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT
+ *     HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY,
+ *     WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
+ *     FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR
+ *     OTHER DEALINGS IN THE SOFTWARE.
+ */
+
+/dts-v1/;
+#include "rk3288-veyron-chromebook.dtsi"
+
+/ {
+	model = "Google Minnie";
+	compatible = "google,veyron-minnie-rev4", "google,veyron-minnie-rev3",
+		     "google,veyron-minnie-rev2", "google,veyron-minnie-rev1",
+		     "google,veyron-minnie-rev0", "google,veyron-minnie",
+		     "google,veyron", "rockchip,rk3288";
+
+	backlight_regulator: backlight-regulator {
+		compatible = "regulator-fixed";
+		enable-active-high;
+		gpio = <&gpio2 12 GPIO_ACTIVE_HIGH>;
+		pinctrl-names = "default";
+		pinctrl-0 = <&bl_pwr_en>;
+		regulator-name = "backlight_regulator";
+		vin-supply = <&vcc33_sys>;
+		startup-delay-us = <15000>;
+	};
+
+	panel_regulator: panel-regulator {
+		compatible = "regulator-fixed";
+		enable-active-high;
+		gpio = <&gpio7 14 GPIO_ACTIVE_HIGH>;
+		pinctrl-names = "default";
+		pinctrl-0 = <&lcd_enable_h>;
+		regulator-name = "panel_regulator";
+		vin-supply = <&vcc33_sys>;
+	};
+
+	vcc18_lcd: vcc18-lcd {
+		compatible = "regulator-fixed";
+		enable-active-high;
+		gpio = <&gpio2 13 GPIO_ACTIVE_HIGH>;
+		pinctrl-names = "default";
+		pinctrl-0 = <&avdd_1v8_disp_en>;
+		regulator-name = "vcc18_lcd";
+		regulator-always-on;
+		regulator-boot-on;
+		vin-supply = <&vcc18_wl>;
+	};
+};
+
+&gpio_keys {
+	pinctrl-0 = <&pwr_key_l &ap_lid_int_l &volum_down_l &volum_up_l>;
+
+	volum_down {
+		label = "Volum_down";
+		gpios = <&gpio5 11 GPIO_ACTIVE_LOW>;
+		linux,code = <KEY_VOLUMEDOWN>;
+		debounce-interval = <100>;
+	};
+
+	volum_up {
+		label = "Volum_up";
+		gpios = <&gpio5 10 GPIO_ACTIVE_LOW>;
+		linux,code = <KEY_VOLUMEUP>;
+		debounce-interval = <100>;
+	};
+};
+
+&i2c_tunnel {
+	battery: bq27500 at 55 {
+		compatible = "ti,bq27500";
+		reg = <0x55>;
+	};
+};
+
+&i2c3 {
+	status = "okay";
+
+	/*
+	 * Touchscreen pin control is shared between Atmel and Elan devices,
+	 * so we have to pull it up to the bus level.
+	 */
+	pinctrl-names = "default";
+	pinctrl-0 = <&i2c3_xfer &touch_int &touch_rst>;
+
+	clock-frequency = <400000>;
+	i2c-scl-falling-time-ns = <50>;
+	i2c-scl-rising-time-ns = <300>;
+
+	touchscreen at 10 {
+		compatible = "elan,ekth3500";
+		reg = <0x10>;
+		interrupt-parent = <&gpio2>;
+		interrupts = <14 IRQ_TYPE_EDGE_FALLING>;
+		reset-gpios = <&gpio2 15 GPIO_ACTIVE_LOW>;
+		vcc33-supply = <&vcc33_touch>;
+		vccio-supply = <&vcc33_touch>;
+	};
+
+	touchscreen at 4a {
+		compatible = "atmel,atmel_mxt_ts";
+		reg = <0x4a>;
+		atmel,reset-gpios = <&gpio2 15 GPIO_ACTIVE_LOW>;
+		avdd-supply = <&vcc5v_touch>;
+		interrupt-parent = <&gpio2>;
+		interrupts = <14 IRQ_TYPE_EDGE_FALLING>;
+		vdd-supply = <&vcc33_touch>;
+	};
+};
+
+&rk808 {
+	pinctrl-names = "default";
+	pinctrl-0 = <&pmic_int_l &dvs_1 &dvs_2>;
+
+	regulators {
+		vcc33_touch: LDO_REG2 {
+			regulator-min-microvolt = <3300000>;
+			regulator-max-microvolt = <3300000>;
+			regulator-name = "vcc33_touch";
+			regulator-suspend-mem-disabled;
+		};
+
+		vcc5v_touch: SWITCH_REG2 {
+			regulator-name = "vcc5v_touch";
+			regulator-suspend-mem-disabled;
+		};
+	};
+};
+
+&sdmmc {
+	disable-wp;
+	pinctrl-names = "default";
+	pinctrl-0 = <&sdmmc_clk &sdmmc_cmd &sdmmc_cd_disabled &sdmmc_cd_gpio
+			&sdmmc_bus4>;
+};
+
+&vcc_5v {
+	enable-active-high;
+	gpio = <&gpio7 21 GPIO_ACTIVE_HIGH>;
+	pinctrl-names = "default";
+	pinctrl-0 = <&drv_5v>;
+};
+
+&vcc50_hdmi {
+	enable-active-high;
+	gpio = <&gpio5 19 GPIO_ACTIVE_HIGH>;
+	pinctrl-names = "default";
+	pinctrl-0 = <&vcc50_hdmi_en>;
+};
+
+&pinctrl {
+	backlight {
+		bl_pwr_en: bl_pwr_en {
+			rockchip,pins = <2 12 RK_FUNC_GPIO &pcfg_pull_none>;
+		};
+	};
+
+	buck-5v {
+		drv_5v: drv-5v {
+			rockchip,pins = <7 21 RK_FUNC_GPIO &pcfg_pull_none>;
+		};
+	};
+
+	buttons {
+		volum_down_l: volum-down-l {
+			rockchip,pins = <5 11 RK_FUNC_GPIO &pcfg_pull_up>;
+		};
+
+		volum_up_l: volum-up-l {
+			rockchip,pins = <5 10 RK_FUNC_GPIO &pcfg_pull_up>;
+		};
+	};
+
+	hdmi {
+		vcc50_hdmi_en: vcc50-hdmi-en {
+			rockchip,pins = <5 19 RK_FUNC_GPIO &pcfg_pull_none>;
+		};
+	};
+
+	lcd {
+		lcd_enable_h: lcd-en {
+			rockchip,pins = <7 14 RK_FUNC_GPIO &pcfg_pull_none>;
+		};
+
+		avdd_1v8_disp_en: avdd-1v8-disp-en {
+			rockchip,pins = <2 13 RK_FUNC_GPIO &pcfg_pull_none>;
+		};
+	};
+
+	pmic {
+		dvs_1: dvs-1 {
+			rockchip,pins = <7 12 RK_FUNC_GPIO &pcfg_pull_down>;
+		};
+
+		dvs_2: dvs-2 {
+			rockchip,pins = <7 15 RK_FUNC_GPIO &pcfg_pull_down>;
+		};
+	};
+
+	prochot {
+		gpio_prochot: gpio-prochot {
+			rockchip,pins = <2 8 RK_FUNC_GPIO &pcfg_pull_none>;
+		};
+	};
+
+	touchscreen {
+		touch_int: touch-int {
+			rockchip,pins = <2 14 RK_FUNC_GPIO &pcfg_pull_none>;
+		};
+
+		touch_rst: touch-rst {
+			rockchip,pins = <2 15 RK_FUNC_GPIO &pcfg_pull_none>;
+		};
+	};
+};
-- 
2.1.4




From mark.rutland at arm.com  Thu Aug  6 10:38:39 2015
From: mark.rutland at arm.com (Mark Rutland)
Date: Thu, 6 Aug 2015 18:38:39 +0100
Subject: [PATCH 2/3] Docs: dt: Add PCI MSI map bindings
In-Reply-To: <BN1PR0301MB06277FDA6EB34E77B557CA75EA750@BN1PR0301MB0627.namprd03.prod.outlook.com>
References: <1437670365-20704-1-git-send-email-mark.rutland@arm.com>
 <1437670365-20704-3-git-send-email-mark.rutland@arm.com>
 <BN1PR0301MB06277FDA6EB34E77B557CA75EA750@BN1PR0301MB0627.namprd03.prod.outlook.com>
Message-ID: <20150806173839.GC6437@leverpostej>

On Wed, Aug 05, 2015 at 05:39:33PM +0100, Varun Sethi wrote:
> Hi Mark
> Thanks for the patch. Please find my comment inline.
> 
> Regards
> Varun
> 
> > -----Original Message-----
> > From: iommu-bounces at lists.linux-foundation.org [mailto:iommu-
> > bounces at lists.linux-foundation.org] On Behalf Of Mark Rutland
> > Sent: Thursday, July 23, 2015 10:23 PM
> > To: devicetree at vger.kernel.org
> > Cc: Mark Rutland; lorenzo.pieralisi at arm.com; arnd at arndb.de;
> > marc.zyngier at arm.com; will.deacon at arm.com; linux-
> > kernel at vger.kernel.org; ddaney at caviumnetworks.com; iommu at lists.linux-
> > foundation.org; tirumalesh.chalamarla at caviumnetworks.com;
> > laurent.pinchart at ideasonboard.com; thunder.leizhen at huawei.com;
> > treding at nvidia.com; linux-arm-kernel at lists.infradead.org;
> > majun258 at huawei.com
> > Subject: [PATCH 2/3] Docs: dt: Add PCI MSI map bindings
> >
> > Currently msi-parent is used by a few bindings to describe the relationship
> > between a PCI root complex and a single MSI controller, but this property
> > does not have a generic binding document.
> >
> > Additionally, msi-parent is insufficient to describe more complex
> > relationships between MSI controllers and devices under a root complex,
> > where devices may be able to target multiple MSI controllers, or where MSI
> > controllers use (non-probeable) sideband information to distinguish devices.
> >
> > This patch adds a generic binding for mapping PCI devices to MSI controllers.
> > This document covers msi-parent, and a new msi-map property (specific to
> > PCI*) which may be used to map devices (identified by their Requester ID) to
> > sideband data for each MSI controller that they may target.
> >
> > Signed-off-by: Mark Rutland <mark.rutland at arm.com>
> > ---
> >  Documentation/devicetree/bindings/pci/pci-msi.txt | 220
> > ++++++++++++++++++++++
> >  1 file changed, 220 insertions(+)
> >  create mode 100644 Documentation/devicetree/bindings/pci/pci-msi.txt
> >
> > diff --git a/Documentation/devicetree/bindings/pci/pci-msi.txt
> > b/Documentation/devicetree/bindings/pci/pci-msi.txt
> > new file mode 100644
> > index 0000000..9b3cc81
> > --- /dev/null
> > +++ b/Documentation/devicetree/bindings/pci/pci-msi.txt
> > @@ -0,0 +1,220 @@
> > +This document describes the generic device tree binding for describing
> > +the relationship between PCI devices and MSI controllers.
> > +
> > +Each PCI device under a root complex is uniquely identified by its
> > +Requester ID (AKA RID). A Requester ID is a triplet of a Bus number,
> > +Device number, and Function number.
> > +
> > +For the purpose of this document, when treated as a numeric value, a
> > +RID is formatted such that:
> > +
> > +* Bits [15:8] are the Bus number.
> > +* Bits [7:3] are the Device number.
> > +* Bits [2:0] are the Function number.
> > +* Any other bits required for padding must be zero.
> > +
> > +MSIs may be distinguished in part through the use of sideband data
> > +accompanying writes. In the case of PCI devices, this sideband data may
> > +be derived from the Requester ID. A mechanism is required to associate
> > +a device with both the MSI controllers it can address, and the sideband
> > +data that will be associated with its writes to those controllers.
> > +
> > +For generic MSI bindings, see
> > +Documentation/devicetree/bindings/interrupt-controller/msi.txt.
> > +
> > +
> > +PCI root complex
> > +================
> > +
> > +Optional properties
> > +-------------------
> > +
> > +- msi-map: Maps a Requester ID to an MSI controller and associated
> > +  msi-specifier data. The property is an arbitrary number of tuples of
> > +  (rid-base,msi-controller,msi-base,length), where:
> [varun] How would we account for hot plug PCI devices and SR-IOV use cases, with the rid base and length?

For hotplug, you simply need the mapping from RID to msi-specifier to be
defined in advance in the DT, for the set of RIDs that could possibly
occur.

For SR-IOV, are you asking about ARI? I should update the description of
the RID to describe that for ARI it has the format:

* Bits [15:8] are the Bus number
* Bits [7:0] are the Identifier

Other than that, the handling would be identical to the non-ARI case.

What else am I missing?

> How do we take in to account for a PCIe bridge, while setting up the requestor ID base and length?

I'm not sure I follow the question. I don't see why this is any
different to any other requester ID.

What do you see as being the problem for this case?

> > +
> > +  * rid-base is a single cell describing the first RID matched by the entry.
> > +
> > +  * msi-controller is a single phandle to an MSI controller
> > +
> > +  * msi-base is an msi-specifier describing the msi-specifier produced for the
> > +    first RID matched by the entry.
> > +
> > +  * length is a single cell describing how many consecutive RIDs are matched
> > +    following the rid-base.
> > +
> > +  Any RID r in the interval [rid-base, rid-base + length) is associated
> > + with  the listed msi-controller, with the msi-specifier (r - rid-base + msi-
> > base).
> > +
> > +- msi-map-mask: A mask to be applied to each Requester ID prior to
> > +being mapped
> > +  to an msi-specifier per the msi-map property.
> > +
> [varun] Can you please elaborate on a use case, where this would help.

It may be the case that at the MSI controller's ID space is smaller
than the RID space, and so only a subset of RID bits matter. For
example, it might be the case that only the Bus ID matters.

Using the msi-map-mask allows for a much smaller msi-map for this case,
e.g.

	msi-map-mask = <0xff00>;
	msi-map = <0x0000 &msi 0x00 1>,
		  <0x0100 &msi 0x01 1>,
		  <0x0200 &msi 0x01 1>,
		  <0x0300 &msi 0x01 1>,
		  ...
		  <0xff00 &msi 0xff 1>;

Rather than:

	msi-map = <0x0000 &msi 0x00 1>,
		  <0x0001 &msi 0x00 1>,
		  <0x0002 &msi 0x00 1>,
		  <0x0003 &msi 0x00 1>,
		  ...
		  <0x00ff &msi 0x00 1>,

		  <0x0100 &msi 0x00 1>,
		  <0x0101 &msi 0x00 1>,
		  <0x0102 &msi 0x00 1>,
		  <0x0103 &msi 0x00 1>,
		  ...
		  <0x01ff &msi 0x00 1>,
		  ...
		  <0xff00 &msi 0xff 1>,
		  <0xff01 &msi 0xff 1>,
		  <0xff02 &msi 0xff 1>,
		  <0xff03 &msi 0xff 1>,
		  ....
		  <0xffff &msi 0xff 1>;

Or for the case that everything maps to a single ID:

		msi-map-mask = <0x0000>;
		msi-map = <0x0000 &msi 0x0000 1>;

Thanks,
Mark.


From catalin.marinas at arm.com  Thu Aug  6 10:43:24 2015
From: catalin.marinas at arm.com (Catalin Marinas)
Date: Thu, 6 Aug 2015 18:43:24 +0100
Subject: [PATCH 00/13] arm64: Virtualization Host Extension support
In-Reply-To: <1436372356-30410-1-git-send-email-marc.zyngier@arm.com>
References: <1436372356-30410-1-git-send-email-marc.zyngier@arm.com>
Message-ID: <20150806174324.GD17691@e104818-lin.cambridge.arm.com>

On Wed, Jul 08, 2015 at 05:19:03PM +0100, Marc Zyngier wrote:
> Marc Zyngier (13):
>   arm/arm64: Add new is_kernel_in_hyp_mode predicate
>   arm64: Allow the arch timer to use the HYP timer
>   arm64: Add ARM64_HAS_VIRT_HOST_EXTN feature
>   arm64: KVM: skip HYP setup when already running in HYP
>   arm64: KVM: VHE: macroize VTCR_EL2 setup
>   arm64: KVM: VHE: Patch out kern_hyp_va
>   arm64: KVM: VHE: Patch out use of HVC
>   arm64: KVM: VHE: Preserve VHE config in world switch
>   arm64: KVM: VHE: Add alternatives for VHE-enabled world-switch
>   arm64: Add support for running Linux in EL2 mode
>   arm64: Panic when VHE and non VHE CPUs coexist
>   arm64: KVM: Split sysreg save/restore
>   arm64: KVM: VHE: Early interrupt handling

Do we need to do anything with the debug code? Do we have any
hardware breakpoints/watchpoints targeting kernel space (kgdb doesn't
seem to support this)?

If a breakpoint target is EL1, I don't think we trigger it when running
in the EL2/VHE mode, in which case we need a different
DBGBCR.{HMC,SSC,PMC} combination - {1,11,00}.

Another random untested patch below but we need to get Will to remember
the code he wrote (and the VHE implications):

diff --git a/arch/arm64/include/asm/hw_breakpoint.h b/arch/arm64/include/asm/hw_breakpoint.h
index 52b484b6aa1a..197af39a5ffb 100644
--- a/arch/arm64/include/asm/hw_breakpoint.h
+++ b/arch/arm64/include/asm/hw_breakpoint.h
@@ -34,8 +34,12 @@ struct arch_hw_breakpoint {
 
 static inline u32 encode_ctrl_reg(struct arch_hw_breakpoint_ctrl ctrl)
 {
-	return (ctrl.len << 5) | (ctrl.type << 3) | (ctrl.privilege << 1) |
+	u32 reg = (ctrl.len << 5) | (ctrl.type << 3) | (ctrl.privilege << 1) |
 		ctrl.enabled;
+	/* set HMC and SSC when debug target is EL2 */
+	if (ctrl.privilege == AARCH64_BREAKPOINT_EL2)
+		reg |= (3 << 14) | (1 << 13);
+	return reg
 }
 
 static inline void decode_ctrl_reg(u32 reg,
@@ -59,6 +63,7 @@ static inline void decode_ctrl_reg(u32 reg,
 #define AARCH64_ESR_ACCESS_MASK	(1 << 6)
 
 /* Privilege Levels */
+#define AARCH64_BREAKPOINT_EL2	0
 #define AARCH64_BREAKPOINT_EL1	1
 #define AARCH64_BREAKPOINT_EL0	2
 
diff --git a/arch/arm64/kernel/hw_breakpoint.c b/arch/arm64/kernel/hw_breakpoint.c
index 7a1a5da6c8c1..77866839d1e8 100644
--- a/arch/arm64/kernel/hw_breakpoint.c
+++ b/arch/arm64/kernel/hw_breakpoint.c
@@ -162,6 +162,7 @@ static enum debug_el debug_exception_level(int privilege)
 	case AARCH64_BREAKPOINT_EL0:
 		return DBG_ACTIVE_EL0;
 	case AARCH64_BREAKPOINT_EL1:
+	case AARCH64_BREAKPOINT_EL2:
 		return DBG_ACTIVE_EL1;
 	default:
 		pr_warning("invalid breakpoint privilege level %d\n", privilege);
@@ -456,7 +457,8 @@ static int arch_build_bp_info(struct perf_event *bp)
 	 * that would complicate the stepping code.
 	 */
 	if (arch_check_bp_in_kernelspace(bp))
-		info->ctrl.privilege = AARCH64_BREAKPOINT_EL1;
+		info->ctrl.privilege = is_kernel_in_hyp_mode() ?
+			AARCH64_BREAKPOINT_EL2 : AARCH64_BREAKPOINT_EL1;
 	else
 		info->ctrl.privilege = AARCH64_BREAKPOINT_EL0;
 
@@ -526,7 +528,7 @@ int arch_validate_hwbkpt_settings(struct perf_event *bp)
 	 * Disallow per-task kernel breakpoints since these would
 	 * complicate the stepping code.
 	 */
-	if (info->ctrl.privilege == AARCH64_BREAKPOINT_EL1 && bp->hw.target)
+	if (info->ctrl.privilege != AARCH64_BREAKPOINT_EL0 && bp->hw.target)
 		return -EINVAL;
 
 	return 0;

-- 
Catalin


From drew.richardson at arm.com  Thu Aug  6 10:52:47 2015
From: drew.richardson at arm.com (Drew Richardson)
Date: Thu, 6 Aug 2015 10:52:47 -0700
Subject: [PATCH] ARM: Mark ret_fast_syscall as a function
In-Reply-To: <alpine.LFD.2.20.1508061327510.1515@knanqh.ubzr>
References: <1436877957-18127-1-git-send-email-drew.richardson@arm.com>
 <20150806170758.GA26691@dreric01-gentoo.localdomain>
 <alpine.LFD.2.20.1508061327510.1515@knanqh.ubzr>
Message-ID: <20150806175246.GA13323@dreric01-gentoo.localdomain>

On Thu, Aug 06, 2015 at 06:30:40PM +0100, Nicolas Pitre wrote:
> On Thu, 6 Aug 2015, Drew Richardson wrote:
> 
> > On Tue, Jul 14, 2015 at 01:45:57PM +0100, Drew Richardson wrote:
> > > ret_fast_syscall runs when user space makes a syscall. However it
> > > needs to be marked as such so the ELF information is correct. Before
> > > it was:
> > > 
> > >    101: 8000f300     0 NOTYPE  LOCAL  DEFAULT    2 ret_fast_syscall
> > > 
> > > But with this change it correctly shows as:
> > > 
> > >    101: 8000f300    96 FUNC    LOCAL  DEFAULT    2 ret_fast_syscall
> > > 
> > > I see this function when using perf to unwind call stacks from kernel
> > > space to user space. Without this change I would need to add some
> > > special case logic when using the vmlinux ELF information.
> > > 
> > > Signed-off-by: Drew Richardson <drew.richardson at arm.com>
> > 
> > I haven't heard any further comments on this, did this get merged and
> > I just didn't notice? Or did I forget to add someone?
> 
> Most likely that it is so trivial that nobody paid much attention.
> 
> FWIW, you can add
> 
> Acked-by: Nicolas Pitre <nico at linaro.org>
> 
> and submit it here: http://www.arm.linux.org.uk/developer/patches/
> 
> 
> Nicolas
> 

Done, thanks.


From joro at 8bytes.org  Thu Aug  6 10:54:39 2015
From: joro at 8bytes.org (joro at 8bytes.org)
Date: Thu, 6 Aug 2015 19:54:39 +0200
Subject: [PATCH v5 1/3] iommu: Implement common IOMMU ops for DMA mapping
In-Reply-To: <20150806152327.GH25483@arm.com>
References: <cover.1438362603.git.robin.murphy@arm.com>
 <6ce6b501501f611297ae0eae31e07b0d2060eaae.1438362603.git.robin.murphy@arm.com>
 <20150806152327.GH25483@arm.com>
Message-ID: <20150806175439.GS14980@8bytes.org>

Hi Will,

On Thu, Aug 06, 2015 at 04:23:27PM +0100, Will Deacon wrote:
> We're quite keen to get this in for arm64, since we're without IOMMU DMA
> ops and need to get something upstream. Do you think this is likely to
> be merged for 4.3/4.4 or would we be better off doing our own
> arch-private implementation instead?
> 
> Sorry to pester, but we've got people basing their patches and products
> on this and I don't want to end up having to support out-of-tree code.

I definitly plan to merge it soon, but not sure if its getting into
v4.3. There are a few things I have questions about or need rework, but
I am sure we can work this out.


	Joerg



From broonie at kernel.org  Thu Aug  6 11:01:56 2015
From: broonie at kernel.org (Mark Brown)
Date: Thu, 6 Aug 2015 19:01:56 +0100
Subject: next-20150806 build: 2 failures 52 warnings (next-20150806)
In-Reply-To: <E1ZNIul-0007IF-Ev@optimist>
References: <E1ZNIul-0007IF-Ev@optimist>
Message-ID: <20150806180156.GC20873@sirena.org.uk>

On Thu, Aug 06, 2015 at 12:00:47PM +0100, Build bot for Mark Brown wrote:

Today's linux-next fails to build an ARM allmodconfig with:

> ../drivers/iommu/omap-iommu-debug.c:138:2: error: void value not ignored as it ought to be

caused by a combination of 1ba2f20ac (fs/seq_file: convert int
seq_vprint/seq_printf/etc... returns to void) which made seq_printf()
return void and e203db293863fa15 (iommu/omap: Fix debug_read_tlb() to
use seq_printf()) which has been in -next for a little while now.
-------------- next part --------------
A non-text attachment was scrubbed...
Name: signature.asc
Type: application/pgp-signature
Size: 473 bytes
Desc: Digital signature
URL: <http://lists.infradead.org/pipermail/linux-arm-kernel/attachments/20150806/41897b91/attachment.sig>

From f.fainelli at gmail.com  Thu Aug  6 11:10:34 2015
From: f.fainelli at gmail.com (Florian Fainelli)
Date: Thu, 06 Aug 2015 11:10:34 -0700
Subject: [PATCH v2] ata: ahci_brcmstb: Fix misuse of IS_ENABLED
In-Reply-To: <1438835298.28215.1.camel@ingics.com>
References: <1438835298.28215.1.camel@ingics.com>
Message-ID: <55C3A31A.6090103@gmail.com>

On 05/08/15 21:28, Axel Lin wrote:
> While IS_ENABLED() is perfectly fine for CONFIG_* symbols, it is not
> for other symbols such as __BIG_ENDIAN that is provided directly by
> the compiler.
> 
> Switch to use CONFIG_CPU_BIG_ENDIAN instead of __BIG_ENDIAN.
> 
> Signed-off-by: Axel Lin <axel.lin at ingics.com>

Acked-by: Florian Fainelli <f.fainelli at gmail.com>

> ---
> v2:
> Based on Florian's comment:
> Switch to use CONFIG_CPU_BIG_ENDIAN instead of __BIG_ENDIAN.
> 
>  drivers/ata/ahci_brcmstb.c | 4 ++--
>  1 file changed, 2 insertions(+), 2 deletions(-)
> 
> diff --git a/drivers/ata/ahci_brcmstb.c b/drivers/ata/ahci_brcmstb.c
> index 42b6cf4..14b7305 100644
> --- a/drivers/ata/ahci_brcmstb.c
> +++ b/drivers/ata/ahci_brcmstb.c
> @@ -92,7 +92,7 @@ static inline u32 brcm_sata_readreg(void __iomem *addr)
>  	 * Other architectures (e.g., ARM) either do not support big endian, or
>  	 * else leave I/O in little endian mode.
>  	 */
> -	if (IS_ENABLED(CONFIG_MIPS) && IS_ENABLED(__BIG_ENDIAN))
> +	if (IS_ENABLED(CONFIG_MIPS) && IS_ENABLED(CONFIG_CPU_BIG_ENDIAN))
>  		return __raw_readl(addr);
>  	else
>  		return readl_relaxed(addr);
> @@ -101,7 +101,7 @@ static inline u32 brcm_sata_readreg(void __iomem *addr)
>  static inline void brcm_sata_writereg(u32 val, void __iomem *addr)
>  {
>  	/* See brcm_sata_readreg() comments */
> -	if (IS_ENABLED(CONFIG_MIPS) && IS_ENABLED(__BIG_ENDIAN))
> +	if (IS_ENABLED(CONFIG_MIPS) && IS_ENABLED(CONFIG_CPU_BIG_ENDIAN))
>  		__raw_writel(val, addr);
>  	else
>  		writel_relaxed(val, addr);
> 


-- 
Florian


From mark.rutland at arm.com  Thu Aug  6 11:14:53 2015
From: mark.rutland at arm.com (Mark Rutland)
Date: Thu, 6 Aug 2015 19:14:53 +0100
Subject: [PATCH 2/3] Docs: dt: Add PCI MSI map bindings
In-Reply-To: <CY1PR0301MB07486794749E499F71BDFCD287750@CY1PR0301MB0748.namprd03.prod.outlook.com>
References: <1437670365-20704-1-git-send-email-mark.rutland@arm.com>
 <1437670365-20704-3-git-send-email-mark.rutland@arm.com>
 <CALRxmdA32xiSX7DDKAJPLR8=bh_9j-6MN124u4KjYGRT8bAKNg@mail.gmail.com>
 <CY1PR0301MB07486794749E499F71BDFCD287750@CY1PR0301MB0748.namprd03.prod.outlook.com>
Message-ID: <20150806181453.GD6437@leverpostej>

[...]

> > +PCI root complex
> > +================
> > +
> > +Optional properties
> > +-------------------
> > +
> > +- msi-map: Maps a Requester ID to an MSI controller and associated
> > +  msi-specifier data. The property is an arbitrary number of tuples of
> > +  (rid-base,msi-controller,msi-base,length), where:
> > +
> > +  * rid-base is a single cell describing the first RID matched by the entry.
> > +
> > +  * msi-controller is a single phandle to an MSI controller
> > +
> > +  * msi-base is an msi-specifier describing the msi-specifier produced for the
> > +    first RID matched by the entry.
> > +
> > +  * length is a single cell describing how many consecutive RIDs are matched
> > +    following the rid-base.
> > +
> > +  Any RID r in the interval [rid-base, rid-base + length) is associated with
> > +  the listed msi-controller, with the msi-specifier (r - rid-base + msi-base).
> > +
> > +- msi-map-mask: A mask to be applied to each Requester ID prior to being mapped
> > +  to an msi-specifier per the msi-map property.
> 
> Can we extend the msi-map-mask definition to say:  "A mask value of 0x0 is valid
> and indicates that no RIDs are _currently_ mapped to any msi-specifier."

That would break a valid case of the mask being all zeroes.

Consider the case that all RIDs get mapped to a single msi-specifier;
the obvious way to write that is:

msi-map-mask = <0x0000>;
msi-map = <0x0000 &msi (msi-specifier) 1>;

In this case all RIDS are always mapped to the single msi-specifier.

> We have an SoC with a programmable hardware table in the PCI controller that maps
> requester ID to stream ID, so the overall msi-map (and iommu-map) definition fit
> into that scheme.  But, we would like to be able make the RID->stream-ID mapping
> decision _lazily_, in Linux, based on actual usage of PCI devices.

Dynamically programming the mapping is at odds to this binding. I don't
see how that can fit.

Why can the RID->SID mapping not be statically configured prior to
entering the OS?

Thanks,
Mark.


From raghumag at gmail.com  Thu Aug  6 11:18:24 2015
From: raghumag at gmail.com (raghu MG)
Date: Thu, 6 Aug 2015 23:48:24 +0530
Subject: Armadaxp GPIO interrupts
In-Reply-To: <20150806171312.GI13421@lunn.ch>
References: <CAG1O52Xg88OsifBzmpSdqvC8wQaOW78nC9nnfxugFv1VU1m1LQ@mail.gmail.com>
 <20150804153439.GA28673@lunn.ch>
 <CAG1O52W2Gy_6_DfewtUqoK_J+Y=KwVGyygNaPu2xyPM_ZkLfcQ@mail.gmail.com>
 <CAG1O52VQPpeGkA8bqYbPMTiT9Mua1yHi3H3osqJsHqm-RRKzow@mail.gmail.com>
 <20150805162155.GE32760@lunn.ch>
 <CAG1O52WPFfm+XGk01iUVWLu=-Dm7bcDVmhv3P8iQDH+HHjsLUA@mail.gmail.com>
 <20150806132926.GB19896@lunn.ch>
 <CAG1O52XUyPkgTTRKftujZBNK1=n6GBdWgBg_kq6SsC5XMaeU3w@mail.gmail.com>
 <20150806171312.GI13421@lunn.ch>
Message-ID: <CAG1O52XO+5F11ELZ+7txWXTYPwmhQP5sVvcjdCiM_T1+ptfp=w@mail.gmail.com>

Ok...
my bad never realised DT entries are necessary.
will try this & post the results.

Regards
Raghu

On Thu, Aug 6, 2015 at 10:43 PM, Andrew Lunn <andrew at lunn.ch> wrote:
> On Thu, Aug 06, 2015 at 10:28:12PM +0530, raghu MG wrote:
>> Ok,I think I need to understand more about this gpio driver.
>>
>> As you said its registering chained handler,but why are they(IRQs) not
>> visible in cat /proc/interrupts.
>
> chained interrupts are never visible there. All you see are leaf
> interrupts, i.e. the device interrupts. Here is my Armada XP based
> WRT1900AC:
>
> $ cat /proc/interrupts
>             CPU0       CPU1
>  16:    8959833   12783597  armada_370_xp_irq   5 Level     armada_370_xp_per_cpu_tick
>  19:          0          0  armada_370_xp_irq  31 Level     mv64xxx_i2c
>  20:       1453          0  armada_370_xp_irq  41 Level     serial
>  26:          0          0  armada_370_xp_irq  45 Level     ehci_hcd:usb3
>  27:       9682          0  armada_370_xp_irq   8 Level     mvneta
>  28:          4          0  armada_370_xp_irq  10 Level     mvneta
>  29:      35078          0  armada_370_xp_irq  55 Level     f10a0000.sata
>  30:       3839          0  armada_370_xp_irq 113 Level     f10d0000.nand
>  70:          0          0  f1018140.gpio   0 Edge      WPS
>  71:         20          0  f1018140.gpio   1 Edge      Factory Reset Button
>  90:          2          0  armada_370_xp_irq  51 Level     f1060900.xor
>  91:          2          0  armada_370_xp_irq  52 Level     f1060900.xor
>  92:          2          0  armada_370_xp_irq  94 Level     f10f0900.xor
>  93:          2          0  armada_370_xp_irq  95 Level     f10f0900.xor
>  94:          0          0  armada_370_xp_msi_irq   0 Edge      xhci_hcd
>
> Notice the two f1018140.gpio, which are the buttons.
>
>> Do I need to further initialize marvell GPIO registers to trigger
>> these events.
>
> Nope, just the normal gpio API and all will work, as demonstrated by
> the two buttons on my board.
>
>> Do I need to change the polarity in polarity register to suit the
>> board requirements in probe function.
>
> Nope, you put that in the DT file:
>
>         gpio_keys {
>                 compatible = "gpio-keys";
>                 #address-cells = <1>;
>                 #size-cells = <0>;
>                 pinctrl-0 = <&keys_pin>;
>                 pinctrl-names = "default";
>
>                 button at 1 {
>                         label = "WPS";
>                         linux,code = <KEY_WPS_BUTTON>;
>                         gpios = <&gpio1 0 GPIO_ACTIVE_HIGH>;
>                 };
>
>                 button at 2 {
>                         label = "Factory Reset Button";
>                         linux,code = <KEY_RESTART>;
>                         gpios = <&gpio1 1 GPIO_ACTIVE_HIGH>;
>                 };
>         };
>
> You can change GPIO_ACTIVE_HIGH to GPIO_ACTIVE_LOW if that is what you
> need.
>
>         Andrew
>


From hramrach at gmail.com  Thu Aug  6 11:20:02 2015
From: hramrach at gmail.com (Michal Suchanek)
Date: Thu, 6 Aug 2015 20:20:02 +0200
Subject: [RFC PATCH 1/5] spi: introduce flag for memory mapped read
In-Reply-To: <CAMuHMdWWDwZ=ziGQXFCnOX8pErXpsEi533J73_Hh=sEqq4hR6Q@mail.gmail.com>
References: <20150804155148.GR20873@sirena.org.uk> <55C0FD98.1090107@ti.com>
 <20150805115013.GJ20873@sirena.org.uk>
 <CAOMqctQXwcHyiWBwtugSDSE_k65qrNfrwnhjQMDJkLoJMmGzUw@mail.gmail.com>
 <20150805124412.GN20873@sirena.org.uk>
 <CAOMqctS9Y5FxpUCCJew6+cnjH5iTvbzkH3g-8yrXs4OuS2pSGA@mail.gmail.com>
 <20150806090202.GO20873@sirena.org.uk>
 <CAOMqctQZRZ4zG_yYy=CeX3DX4NVNWN1COP4Q-2YvMun9xYOA7g@mail.gmail.com>
 <20150806102225.GI7576@n2100.arm.linux.org.uk> <55C35233.2000105@ti.com>
 <20150806135129.GJ7576@n2100.arm.linux.org.uk>
 <CAMuHMdWWDwZ=ziGQXFCnOX8pErXpsEi533J73_Hh=sEqq4hR6Q@mail.gmail.com>
Message-ID: <CAOMqctTisUv4YcSSojKadotX5XAB4Ro0bxT4Wn9tRP=Jyc0iqw@mail.gmail.com>

On 6 August 2015 at 18:14, Geert Uytterhoeven <geert at linux-m68k.org> wrote:
> On Thu, Aug 6, 2015 at 3:51 PM, Russell King - ARM Linux
> <linux at arm.linux.org.uk> wrote:
>> On Thu, Aug 06, 2015 at 05:55:23PM +0530, Vignesh R wrote:
>>> On the whole following are my requirements:
>>> 1. to be able to communicate with non -flash SPI devices via config port
>>> ( this functionality is supported by current driver, I dont want to
>>> break it). Or pump any spi_message on to SPI bus directly.
>>> 2. take advantage of memory mapped port in order to increase read
>>> throughput( and use dma in future) when the slave is a m25p80 type flash.
>>> 3. handle m25p80 as well as other slave on multiple chipselects.
>>>
>>> I just need to know whether the user that requested the transfer is
>>> m25p80 driver. If yes, ti-qspi driver can take advantage of memory
>>> mapped interface, else just use config port to access SPI bus directly.
>>
>> The problem with this approach is that it's an abomination.  It's adding
>> a SPI-user specific hack which is detected by a specific driver.  That's
>> really not sane - what happens when we have lots of these kinds of "I'm
>> an X SPI-user" with drivers detecting that?  It's not maintainable in the
>> long term.
>>
>> Yes, your requirements _today_ seem simple and easy, but you're only
>> thinking about today, not tomorrow when you've moved on and someone else
>> has to maintain the mess left behind (or delete it from mainline because
>> they're sick of dealing with a hack.)
>>
>>> The spi_message that is received in transfer_one_message() is too
>>> generic to imply the slave device that is on the other side of the wire.
>>> IMO, the read command does not imply that the slave is m25p80 flash
>>> (besides the read opcodes vary across vendors of m25p80 and across modes).
>>
>> I can see both sides of the argument.
>>
>> Mark is saying: if the SPI driver detects that the message to be transmitted
>> is a read command followed by the appropriate number of dummy bytes, and
>> then the data being read _and_ it's using quad-mode access, and the hardware
>> generates _exactly_ that in hardware using the memory mapped mode, there is
>> no reason _not_ to use the hardware to achieve that SPI transaction.  The
>> bus activity will be identical to what happens when the SPI controller is
>> used manually to achieve that bus sequence.
>>
>> You're saying: but the documentation says you can't use it for anything
>> except m25p80.  If you look at 24.5.4.1.2, it tells you what the SFI
>> generates on the bus, which is:
>>
>> 1. CS active
>> 2. Read command byte sent
>> 3. 1-4 address bytes sent
>> 4. 0-3 dummy bytes sent
>> 5. data bytes read from bus
>> 6. CS inactive
>>
>> So, Mark's point is "if we can detect a transaction which fits _that_
>> bus activity, there's no reason not to use this acceleration for the
>> transaction."
>>
>> What you're failing to counter with is: we don't have enough information
>> in the SPI driver to know how many dummy bytes there are between the
>> address bytes and the data read from the bus.
>
> Irrespective of the dummy bytes.
> What if the spi device is not a FLASH ROM, but some other device,
> which receives a data packet that accidentally looks like an m25p80 READ
> command?
>

Presumably the driver would interpret some random part of the message
as address and map the reply in your address space at that address
from the flash mmap base.

If you happen to overflow the flash memory mmap space the behaviour
will probably not be well defined.

Thanks

Michal


From broonie at kernel.org  Thu Aug  6 11:20:29 2015
From: broonie at kernel.org (Mark Brown)
Date: Thu, 6 Aug 2015 19:20:29 +0100
Subject: [RFC PATCH 1/5] spi: introduce flag for memory mapped read
In-Reply-To: <55C35233.2000105@ti.com>
References: <20150804155148.GR20873@sirena.org.uk> <55C0FD98.1090107@ti.com>
 <20150805115013.GJ20873@sirena.org.uk>
 <CAOMqctQXwcHyiWBwtugSDSE_k65qrNfrwnhjQMDJkLoJMmGzUw@mail.gmail.com>
 <20150805124412.GN20873@sirena.org.uk>
 <CAOMqctS9Y5FxpUCCJew6+cnjH5iTvbzkH3g-8yrXs4OuS2pSGA@mail.gmail.com>
 <20150806090202.GO20873@sirena.org.uk>
 <CAOMqctQZRZ4zG_yYy=CeX3DX4NVNWN1COP4Q-2YvMun9xYOA7g@mail.gmail.com>
 <20150806102225.GI7576@n2100.arm.linux.org.uk>
 <55C35233.2000105@ti.com>
Message-ID: <20150806182029.GD20873@sirena.org.uk>

On Thu, Aug 06, 2015 at 05:55:23PM +0530, Vignesh R wrote:

> 1.Write to flash config register via config port to switch to QUAD MODE
> (or any mode that flash supports).
> 2. Populate QSPI_SPI_SETUP_REGx with flash read command, number of
> address bytes to use and dummy bytes required.

These things being constant for a given flash?

> 3. Switch to memory mapped port by writing to QSPI_SPI_SWITCH_REG.
> 4. Now, its possible to perform read from 0x5C000000 to 0x5FFFFFFF using
> memcpy. The qspi controller hardware will communicate over SPI bus and
> get the data. This data is directly sent to RAM via SoC's interconnect.

Presumably if it's done via memcpy() it won't go direct to RAM but
rather be bounced through the CPU which is a bit interesting for
performance (it might help, but it does mean that there's a core stalled
waiting for the flash which might not be the best use of resources if
there's other things it can be getting on with).  With DMA it'd be a
direct to memory transfer though.

> Advantages of memory mapped port are: improved read performance,
> MEM_TO_MEM DMA support can be added (ti-qspi hardware as such does not
> provide DMA events).

DMA would definitely help here.

> I just need to know whether the user that requested the transfer is
> m25p80 driver. If yes, ti-qspi driver can take advantage of memory
> mapped interface, else just use config port to access SPI bus directly.

You don't *really* care if it's that specific user so much as that it's
that particular pattern.

> Writing separate driver based on spi-nor framework to interface with
> m25p80 is not an option because, I would lose the ability to interface
> with non-flash devices.

You could, however, expose an explicit flash mapping interface for this
functionality.  That does seem like it's going to be an awful lot easier 
and help with keeping things like DMA support out of the driver and in
the core (which would be useful if there's other controllers with the
same functionality, I seem to recall that there are).

> The spi_message that is received in transfer_one_message() is too
> generic to imply the slave device that is on the other side of the wire.
> IMO, the read command does not imply that the slave is m25p80 flash
> (besides the read opcodes vary across vendors of m25p80 and across modes).

Again, it doesn't matter if it's actually a read command only that it's
got a compatible format on the bus.
-------------- next part --------------
A non-text attachment was scrubbed...
Name: signature.asc
Type: application/pgp-signature
Size: 473 bytes
Desc: Digital signature
URL: <http://lists.infradead.org/pipermail/linux-arm-kernel/attachments/20150806/3969a89c/attachment.sig>

From tj at kernel.org  Thu Aug  6 11:32:22 2015
From: tj at kernel.org (Tejun Heo)
Date: Thu, 6 Aug 2015 14:32:22 -0400
Subject: [PATCH v2] ata: ahci_brcmstb: Fix misuse of IS_ENABLED
In-Reply-To: <1438835298.28215.1.camel@ingics.com>
References: <1438835298.28215.1.camel@ingics.com>
Message-ID: <20150806183222.GA14626@mtj.duckdns.org>

On Thu, Aug 06, 2015 at 12:28:18PM +0800, Axel Lin wrote:
> While IS_ENABLED() is perfectly fine for CONFIG_* symbols, it is not
> for other symbols such as __BIG_ENDIAN that is provided directly by
> the compiler.
> 
> Switch to use CONFIG_CPU_BIG_ENDIAN instead of __BIG_ENDIAN.
> 
> Signed-off-by: Axel Lin <axel.lin at ingics.com>

Applied to libata/for-4.2-fixes w/ stable cc'd.

Thanks.

-- 
tejun


From laurent.pinchart at ideasonboard.com  Thu Aug  6 12:10:35 2015
From: laurent.pinchart at ideasonboard.com (Laurent Pinchart)
Date: Thu, 06 Aug 2015 22:10:35 +0300
Subject: [PATCH 05/13] iommu/io-pgtable-arm: Allow appropriate DMA API use
In-Reply-To: <20150805162452.GH6092@arm.com>
References: <1438608355-7335-1-git-send-email-will.deacon@arm.com>
 <1987558.GfG8OCqzMM@avalon> <20150805162452.GH6092@arm.com>
Message-ID: <3382846.ggsOMiDf7e@avalon>

Hi Will,

On Wednesday 05 August 2015 17:24:52 Will Deacon wrote:
> On Tue, Aug 04, 2015 at 09:54:27PM +0100, Laurent Pinchart wrote:
> > On Tuesday 04 August 2015 15:56:42 Russell King - ARM Linux wrote:
> > > On Tue, Aug 04, 2015 at 03:47:13PM +0100, Robin Murphy wrote:
> > > > On 04/08/15 14:16, Laurent Pinchart wrote:
> > > >> This is what I believe to be an API abuse. The
> > > >> dma_sync_single_for_device()
> > > >> API is meant to pass ownership of a buffer to the device. Unless I'm
> > > >> mistaken, once that's done the CPU isn't allowed to touch the buffer
> > > >> anymore until dma_sync_single_for_cpu() is called to get ownership of
> > > >> the buffer back.
> > > 
> > > That's what I thought up until recently, but it's not strictly true -
> > > see Documentation/DMA-API.txt which Robin quoted.
> > 
> > I find the documentation slightly unclear on this topic. I have nothing
> > against updating it to state that the sync functions ensure visibility of
> > the data to the device or CPU instead of transferring ownership if that's
> > the general understanding of how the API work (or should work). This
> > would of course need to be carefully reviewed to ensure that the current
> > implementation really works that way across all architectures, or at
> > least that it can be made to work that way.
> 
> I was hoping to send this lot off to Joerg tomorrow morning, since it's
> removing a hack from the io-pgtable users before it has chance to spread
> further. This use of the API is certainly ok on arm and arm64 (where
> these drivers currently run) and I don't see why it wouldn't work for
> any IOMMU that treats the page tables as read-only. Once we start getting
> into hardware access/dirty bits, then the streaming-DMA API is a lost
> cause but I would expect those systems to be using SVM with the CPU page
> tables anyway and therefore be cache-coherent.
> 
> I agree that the Documentation isn't brilliant, but that could be addressed
> in a separate patch (especially since I don't think it would be merged
> via the iommu tree).
> 
> Is that alright?

Yes, that's fine with me. The patch set moves usage of the DMA mapping API 
from drivers to a single place in the core, so no problem is introduced. If we 
later consider this to be an API abuse we'll only need to fix it in a single 
place. And if it's a valid use of the API then the documentation 
fix/improvement doesn't need to be synchronous with this patch set.

-- 
Regards,

Laurent Pinchart



From corbet at lwn.net  Thu Aug  6 12:14:32 2015
From: corbet at lwn.net (Jonathan Corbet)
Date: Thu, 6 Aug 2015 13:14:32 -0600
Subject: [Resend: PATCH] ARM: keystone: add documentation for SoCs and EVMs
In-Reply-To: <1438706203-3748-1-git-send-email-m-karicheri2@ti.com>
References: <1438706203-3748-1-git-send-email-m-karicheri2@ti.com>
Message-ID: <20150806131432.6440eb56@lwn.net>

On Tue, 4 Aug 2015 12:36:43 -0400
Murali Karicheri <m-karicheri2 at ti.com> wrote:

> Currently there is no general documentation on Keystone SoCs in the
> Linux Documentation folder of the source tree. This patch adds some
> essential documentation with links to help users of Keystone Linux and
> also provide links to existing documents where necessary.

Applied to the docs tree, thanks.

jon


From srinivas.kandagatla at linaro.org  Thu Aug  6 12:34:07 2015
From: srinivas.kandagatla at linaro.org (Srinivas Kandagatla)
Date: Thu, 06 Aug 2015 20:34:07 +0100
Subject: [PATCH 1/3] nvmem: Add i.MX6 OCOTP device tree binding
 documentation
In-Reply-To: <1438878835.3223.14.camel@pengutronix.de>
References: <1438693342-605-1-git-send-email-p.zabel@pengutronix.de>	
 <55C38752.3040406@linaro.org> <1438878835.3223.14.camel@pengutronix.de>
Message-ID: <55C3B6AF.4050107@linaro.org>



On 06/08/15 17:33, Philipp Zabel wrote:
> Am Donnerstag, den 06.08.2015, 17:12 +0100 schrieb Srinivas Kandagatla:
>>
>> On 04/08/15 14:02, Philipp Zabel wrote:
>>> This patch documents the i.MX6 OCOTP device tree binding.
>>>
>>> Signed-off-by: Philipp Zabel <p.zabel at pengutronix.de>
>>> ---
>>>    .../devicetree/bindings/nvmem/imx-ocotp.txt          | 20 ++++++++++++++++++++
>>>    1 file changed, 20 insertions(+)
>>>    create mode 100644 Documentation/devicetree/bindings/nvmem/imx-ocotp.txt
>>>
>>> diff --git a/Documentation/devicetree/bindings/nvmem/imx-ocotp.txt b/Documentation/devicetree/bindings/nvmem/imx-ocotp.txt
>>> new file mode 100644
>>> index 0000000..7d9a3fc
>>> --- /dev/null
>>> +++ b/Documentation/devicetree/bindings/nvmem/imx-ocotp.txt
>>> @@ -0,0 +1,20 @@
>>> +Freescale i.MX6 On-Chip OTP Controller (OCOTP) device tree bindings
>>> +
>>> +This binding represents the on-chip eFuse OTP controller found on
>>> +i.MX6Q/D, i.MX6DL/S, i.MX6SL, and i.MX6SX SoCs.
>>> +
>>> +Required properties:
>>> +- compatible: should be one of
>>> +	"fsl,imx6q-ocotp" (i.MX6Q/D/DL/S),
>>> +        "fsl,imx6sl-ocotp" (i.MX6SL), or
>>> +	"fsl,imx6sx-ocotp" (i.MX6SX), followed by "syscon".
>>> +- reg: Should contain the register base and length.
>>> +- clocks: Should contain a phandle pointing to the gated peripheral clock.
>>> +
>>> +Example:
>>> +
>>> +	ocotp: ocotp at 021bc000 {
>>> +		compatible = "fsl,imx6q-ocotp", "syscon";
>> Do you still need syscon?
>
> Currently the imx_tempmon driver still accesses ocotp via syscon. I'd
> like to change that and drop "syscon" after the nvmem framework lands in
> mainline.

Makes sense.

>
>>> +		reg = <0x021bc000 0x4000>;
>> Can't we just have a register range specific to the OTP device?
>
> In the i.MX device trees it is common to specify the register range from
> the memory map. In any case, we have to support old device trees where
> this is already set.
ok.

--srini
>
> regards
> Philipp
>


From srinivas.kandagatla at linaro.org  Thu Aug  6 12:36:47 2015
From: srinivas.kandagatla at linaro.org (Srinivas Kandagatla)
Date: Thu, 06 Aug 2015 20:36:47 +0100
Subject: [PATCH 2/3] nvmem: imx-ocotp: Add i.MX6 OCOTP driver
In-Reply-To: <1438878490.3223.10.camel@pengutronix.de>
References: <1438693342-605-1-git-send-email-p.zabel@pengutronix.de>	
 <1438693342-605-2-git-send-email-p.zabel@pengutronix.de>	
 <55C38941.9090709@linaro.org> <1438878490.3223.10.camel@pengutronix.de>
Message-ID: <55C3B74F.5010501@linaro.org>

Hi Philipp,

Could you add Greg KH in the CC, for next merge window, we can request 
Greg to take this driver via his tree.

Once the comments are fixed you can add my

Acked-by: Srinivas Kandagatla <srinivas.kandagatla at linaro.org>

On 06/08/15 17:28, Philipp Zabel wrote:
> Hi Srinivas,
>
> Am Donnerstag, den 06.08.2015, 17:20 +0100 schrieb Srinivas Kandagatla:
>> Few Nits..
>>
>> On 04/08/15 14:02, Philipp Zabel wrote:
>>> +#include <linux/clk.h>
>> May be you can drop this?
>
> Yes, that's a left-over and can be removed.
>
>> BTW, who is taking care of the gated peripheral clock controlled for
>> this driver?
>
> Nobody. I had initially copied the code that actually senses the fuses,
> but since this happens during power-on reset anyway (all values are
> stored in shadow registers), I didn't see the point and dropped it for
> now.
> The shadow registers are clocked directly by the ungated ipg_root clock.

So, are you planning to drop the clocks property from the bindings too?

--srini



>
> [...]
>>> +MODULE_LICENSE("GPL");
>>
>> GPL v2 ?
>
> Will do.
>
> thanks
> Philipp
>


From stuart.yoder at freescale.com  Thu Aug  6 12:46:49 2015
From: stuart.yoder at freescale.com (Stuart Yoder)
Date: Thu, 6 Aug 2015 19:46:49 +0000
Subject: [PATCH 2/3] Docs: dt: Add PCI MSI map bindings
In-Reply-To: <20150806181453.GD6437@leverpostej>
References: <1437670365-20704-1-git-send-email-mark.rutland@arm.com>
 <1437670365-20704-3-git-send-email-mark.rutland@arm.com>
 <CALRxmdA32xiSX7DDKAJPLR8=bh_9j-6MN124u4KjYGRT8bAKNg@mail.gmail.com>
 <CY1PR0301MB07486794749E499F71BDFCD287750@CY1PR0301MB0748.namprd03.prod.outlook.com>
 <20150806181453.GD6437@leverpostej>
Message-ID: <CY1PR0301MB07483BBD1B779122D58D2E0887740@CY1PR0301MB0748.namprd03.prod.outlook.com>



> -----Original Message-----
> From: Mark Rutland [mailto:mark.rutland at arm.com]
> Sent: Thursday, August 06, 2015 1:15 PM
> To: Yoder Stuart-B08248; Marc Zyngier; Will Deacon
> Cc: devicetree at vger.kernel.org; Lorenzo Pieralisi; arnd at arndb.de; linux-kernel at vger.kernel.org;
> ddaney at caviumnetworks.com; iommu at lists.linux-foundation.org; tirumalesh.chalamarla at caviumnetworks.com;
> laurent.pinchart at ideasonboard.com; thunder.leizhen at huawei.com; treding at nvidia.com; linux-arm-
> kernel at lists.infradead.org; majun258 at huawei.com
> Subject: Re: [PATCH 2/3] Docs: dt: Add PCI MSI map bindings
> 
> [...]
> 
> > > +PCI root complex
> > > +================
> > > +
> > > +Optional properties
> > > +-------------------
> > > +
> > > +- msi-map: Maps a Requester ID to an MSI controller and associated
> > > +  msi-specifier data. The property is an arbitrary number of tuples of
> > > +  (rid-base,msi-controller,msi-base,length), where:
> > > +
> > > +  * rid-base is a single cell describing the first RID matched by the entry.
> > > +
> > > +  * msi-controller is a single phandle to an MSI controller
> > > +
> > > +  * msi-base is an msi-specifier describing the msi-specifier produced for the
> > > +    first RID matched by the entry.
> > > +
> > > +  * length is a single cell describing how many consecutive RIDs are matched
> > > +    following the rid-base.
> > > +
> > > +  Any RID r in the interval [rid-base, rid-base + length) is associated with
> > > +  the listed msi-controller, with the msi-specifier (r - rid-base + msi-base).
> > > +
> > > +- msi-map-mask: A mask to be applied to each Requester ID prior to being mapped
> > > +  to an msi-specifier per the msi-map property.
> >
> > Can we extend the msi-map-mask definition to say:  "A mask value of 0x0 is valid
> > and indicates that no RIDs are _currently_ mapped to any msi-specifier."
> 
> That would break a valid case of the mask being all zeroes.
> 
> Consider the case that all RIDs get mapped to a single msi-specifier;
> the obvious way to write that is:
> 
> msi-map-mask = <0x0000>;
> msi-map = <0x0000 &msi (msi-specifier) 1>;
> 
> In this case all RIDS are always mapped to the single msi-specifier.

Does it really break that case?

We could have this (your example):

  msi-map-mask = <0x0000>;
  msi-map = <0x0000 &msi 7 1>;  // map all RIDs to msi-spec 7

Or, my example:

  msi-map-mask = <0x0000>;
  msi-map = <0x0000 &msi 7 4>;  // all RIDs map to any of msi-spec 7,8,9,10

> > We have an SoC with a programmable hardware table in the PCI controller that maps
> > requester ID to stream ID, so the overall msi-map (and iommu-map) definition fit
> > into that scheme.  But, we would like to be able make the RID->stream-ID mapping
> > decision _lazily_, in Linux, based on actual usage of PCI devices.
> 
> Dynamically programming the mapping is at odds to this binding. I don't
> see how that can fit.

My example above obviously doesn't make sense for a static
binding, but can't we allow both a mask value of 0x0 and
a length > 1 at the same time.
 
> Why can the RID->SID mapping not be statically configured prior to
> entering the OS?

The problem for us is the limited number of SIDs available on our SoC.  We
have an SMMU-500 with 128 SIDs / 64-contexts total.  An SR-IOV card could
enable VFs dynamically and suddenly there are 64 new RIDs on a PCI
bus.  There are 4 PCI controllers and firmware doesn't know what
might be enabled on which bus.  We run out of available SIDs.

In that example we want all RIDs mapped to one SID by default, but want
the option of setting our dynamic RID->SID table for a situation where
say someone assigns a VF to a KVM VM and thus needs an SID to use
for SMMU mappings.

I think the binding can work for the dynamic case as long as we allow
the example I showed above.  So, I would propose changing
my proposed text to:

   "A mask value of 0x0 is valid and indicates that all RIDS map to
    the specified msi-specifier(s).  If the mask is 0x0 and length > 1
    it indicates that all RIDs map to any of the msi-specifiers with
    the actual mapping left unspecified by the msi-map property."

Thanks,
Stuart


From sergei.shtylyov at cogentembedded.com  Thu Aug  6 13:06:13 2015
From: sergei.shtylyov at cogentembedded.com (Sergei Shtylyov)
Date: Thu, 6 Aug 2015 23:06:13 +0300
Subject: [PATCH v2 0/2] Add R8A7794 GPIO DT support
In-Reply-To: <20150806004714.GD17231@verge.net.au>
References: <6388101.Drn6rL87rl@wasted.cogentembedded.com>
 <20150806004714.GD17231@verge.net.au>
Message-ID: <55C3BE35.8020408@cogentembedded.com>

Hello.

On 08/06/2015 03:47 AM, Simon Horman wrote:

>>     Here's the set of 2 patches against Simon Horman's 'renesas.git' repo,
>> 'renesas-devel-20150803-v4.2-rc5' tag. Here we add the GPIO device tree support
>> for the R8A7794 SoC.

>> [1/2] ARM: shmobile: r8a7794: add GPIO clocks
>> [2/2] ARM: shmobile: r8a7794: add GPIO DT support

> Thanks, I have queued these up for v4.4.

    Not seeing anything new in your repo. Which is probably a good thing 
considering Geert's comments.

MBR, Sergei



From robherring2 at gmail.com  Thu Aug  6 13:14:26 2015
From: robherring2 at gmail.com (Rob Herring)
Date: Thu, 6 Aug 2015 15:14:26 -0500
Subject: [PATCH v3 0/18] On-demand device probing
In-Reply-To: <1438870315-18689-1-git-send-email-tomeu.vizoso@collabora.com>
References: <1438870315-18689-1-git-send-email-tomeu.vizoso@collabora.com>
Message-ID: <CAL_JsqKq_-TLb_3VRMN_MhjsGnRfpRN1uuEgHE9DAyP3Y3ovhQ@mail.gmail.com>

On Thu, Aug 6, 2015 at 9:11 AM, Tomeu Vizoso <tomeu.vizoso at collabora.com> wrote:
> Hello,
>
> I have a problem with the panel on my Tegra Chromebook taking longer
> than expected to be ready during boot (St?phane Marchesin reported what
> is basically the same issue in [0]), and have looked into ordered
> probing as a better way of solving this than moving nodes around in the
> DT or playing with initcall levels and linking order.
>
> While reading the thread [1] that Alexander Holler started with his
> series to make probing order deterministic, it occurred to me that it
> should be possible to achieve the same by probing devices as they are
> referenced by other devices.
>
> This basically reuses the information that is already implicit in the
> probe() implementations, saving us from refactoring existing drivers or
> adding information to DTBs.
>
> During review of v1 of this series Linus Walleij suggested that it
> should be the device driver core to make sure that dependencies are
> ready before probing a device. I gave this idea a try [2] but Mark Brown
> pointed out to the logic duplication between the resource acquisition
> and dependency discovery code paths (though I think it's fairly minor).
>
> To address that code duplication I experimented with Arnd's devm_probe
> [3] concept of having drivers declare their dependencies instead of
> acquiring them during probe, and while it worked [4], I don't think we
> end up winning anything when compared to just probing devices on-demand
> from resource getters.
>
> One remaining objection is to the "sprinkling" of calls to
> fwnode_ensure_device() in the resource getters of each subsystem, but I
> think it's the right thing to do given that the storage of resources is
> currently subsystem-specific.
>
> We could avoid the above by moving resource storage into the core, but I
> don't think there's a compelling case for that.
>
> I have tested this on boards with Tegra, iMX.6, Exynos and OMAP SoCs,
> and these patches were enough to eliminate all the deferred probes
> (except one in PandaBoard because omap_dma_system doesn't have a
> firmware node as of yet).
>
> Have submitted a branch [5] with these patches to kernelci.org and I'm
> currently trying to fix all regressions, usually due to code assuming
> that devices will be probed in a specific order. Current results [6] are
> 348 passes, 30 fails and 42 unknowns (linux-next [7] is currently
> 387/3/23).

This is a bit worrying. If this causes a high number of boot failures,
fixing the errors you can find is not the path forward as we can't
test a lot of platforms (and many people don't look at -next). We may
want to put this behind a kconfig option so that we can easily restore
old behavior it needed. Otherwise, we could have to revert the series.

Are all the commits before this series fixing boot failures? You can't
do dts updates as the fix or backwards compatibility will be broken.

>
> With this series I get the kernel to output to the panel in 0.5s,
> instead of 2.8s.
>
> Regards,
>
> Tomeu
>
> [0] http://lists.freedesktop.org/archives/dri-devel/2014-August/066527.html
>
> [1] https://lkml.org/lkml/2014/5/12/452
>
> [2] https://lkml.org/lkml/2015/6/17/305
>
> [3] http://article.gmane.org/gmane.linux.ports.arm.kernel/277689
>
> [4] https://lkml.org/lkml/2015/7/21/441a
>
> [5] https://git.collabora.com/cgit/user/tomeu/linux.git/log/?h=on-demand-probes-v5
>
> [6] http://kernelci.org/boot/all/job/collabora/kernel/v4.2-rc5-6548-g632b98c83840/
>
> [7] http://kernelci.org/boot/all/job/next/kernel/next-20150806/
>
> Changes in v3:
> - Only delay platform devices with OF nodes
> - Set and use device_node.platform_dev instead of reversing the logic to
>   find the platform device that encloses a device node.

I still want this to be a struct device and not a struct
platform_device and am not convinced it can't be. It can simply be an
optimization of the existing function:

struct platform_device *of_find_device_by_node(struct device_node *np)
{
  if (node->device && node->device->bus == &platform_bus_type)
    return to_platform_device(node->device);
  return NULL;
}

Rob


From jroedel at suse.de  Thu Aug  6 13:17:24 2015
From: jroedel at suse.de (Joerg Roedel)
Date: Thu, 6 Aug 2015 22:17:24 +0200
Subject: next-20150806 build: 2 failures 52 warnings (next-20150806)
In-Reply-To: <20150806180156.GC20873@sirena.org.uk>
References: <E1ZNIul-0007IF-Ev@optimist> <20150806180156.GC20873@sirena.org.uk>
Message-ID: <20150806201724.GC10112@suse.de>

On Thu, Aug 06, 2015 at 07:01:56PM +0100, Mark Brown wrote:
> On Thu, Aug 06, 2015 at 12:00:47PM +0100, Build bot for Mark Brown wrote:
> 
> Today's linux-next fails to build an ARM allmodconfig with:
> 
> > ../drivers/iommu/omap-iommu-debug.c:138:2: error: void value not ignored as it ought to be
> 
> caused by a combination of 1ba2f20ac (fs/seq_file: convert int
> seq_vprint/seq_printf/etc... returns to void) which made seq_printf()
> return void and e203db293863fa15 (iommu/omap: Fix debug_read_tlb() to
> use seq_printf()) which has been in -next for a little while now.

Whoops. Thanks for the report, I'll fix it tomorrow.


	Joerg



From robherring2 at gmail.com  Thu Aug  6 13:19:12 2015
From: robherring2 at gmail.com (Rob Herring)
Date: Thu, 6 Aug 2015 15:19:12 -0500
Subject: [PATCH v3 01/18] platform: delay OF device-driver matches until
 late_initcall
In-Reply-To: <1438870315-18689-2-git-send-email-tomeu.vizoso@collabora.com>
References: <1438870315-18689-1-git-send-email-tomeu.vizoso@collabora.com>
 <1438870315-18689-2-git-send-email-tomeu.vizoso@collabora.com>
Message-ID: <CAL_Jsq+GLMZe-f6qEi=7i1YrrWc6k99RpGkOyCd5KkYDiyt0QA@mail.gmail.com>

On Thu, Aug 6, 2015 at 9:11 AM, Tomeu Vizoso <tomeu.vizoso at collabora.com> wrote:
> Delay matches of platform devices with OF nodes until late_initcall,
> when we are sure that all built-in drivers have been registered already.
> This is needed to prevent deferred probes because of some drivers not
> having registered yet.
>
> The reason why only platform devices are delayed is that some other
> devices are expected to be probed earlier than late_initcall, for
> example, the system PNP driver needs to probe its devices in
> fs_initcall.
>
> Additionally, only platform devices with OF nodes are delayed because
> some machines may depend on oter platform devices being registered at
> specific times.

How do we know that these probes occur before the unused clocks and
regulators are turned off? Just getting lucky (as is deferred probe)?
Can we do this one level earlier so we have a level left to do things
after probe.

Rob


From linux at arm.linux.org.uk  Thu Aug  6 13:38:16 2015
From: linux at arm.linux.org.uk (Russell King - ARM Linux)
Date: Thu, 6 Aug 2015 21:38:16 +0100
Subject: IRQ setup on multicore systems (routing, balancing, etc)
In-Reply-To: <55C387F6.8090708@free.fr>
References: <55C0C102.7050600@free.fr> <55C37A72.2090507@free.fr>
 <20150806152654.GF7557@n2100.arm.linux.org.uk>
 <55C387F6.8090708@free.fr>
Message-ID: <20150806203816.GG7557@n2100.arm.linux.org.uk>

On Thu, Aug 06, 2015 at 06:14:46PM +0200, Mason wrote:
> It doesn't help that the port I'm working on doesn't follow
> "established guidelines". In this case, interrupt routing is
> hard-coded in the platform code:
> 
> static inline void tangox_enable(struct irq_data *data)
> {
> 	int bit = data->irq - IRQ_CONTROLLER_IRQ_BASE;
> #ifdef ENABLE_INTERRUPT_ON_CPU1
> 	if(route_interrupt_to_cpu1(bit))
> 		tangox_fiq_enable(bit);
> 	else
> #endif
> 		tangox_irq_enable(bit);
> }
> 
> (tangox_enable is called in the .irq_startup struct irq_chip callback.)
> 
> Throw weird naming in the mix (I thought FIQ was reserved for
> the secure world, and my Linux runs in non-secure) and my
> confusion level is up to 11.

Looking at the above code, I must say that it looks like the code is on
some kind of drugs.  The code implies that FIQs are routed to CPU1, which
is obviously a totally insane.  I think I'd be as confused as you over
that.

Are you basing your idea that certain interrupts need to be routed to a
certain CPU on this code, or on practical experience?  It may be better
to experiment with the hardware to find out what's possible rather than
rely on hacky undocumented code such as the above.

-- 
FTTC broadband for 0.8mile line: currently at 10.5Mbps down 400kbps up
according to speedtest.net.


From hermr2d2 at gmail.com  Thu Aug  6 13:51:10 2015
From: hermr2d2 at gmail.com (Hermann Kraus)
Date: Thu, 06 Aug 2015 22:51:10 +0200
Subject: [PATCH v2] spi: spi-sun4i, spi-sun6i: Fix bit rate calculation
In-Reply-To: <20150804171931.GZ20873@sirena.org.uk>
References: <op.x2pmc5kiltbbtz@localhost>
 <20150804171931.GZ20873@sirena.org.uk>
Message-ID: <op.x2yr7kbcltbbtz@localhost>

Use requested bit rate instead of maximum possible and correctly calculate
the divider.

There are two different maximum bitrates. "max_speed_hz" which is the
maximum for a given SPI device and "speed_hz" in "struct spi_transfer"
which is the rate used for this transfer. "speed_hz" must always be
used as the actual transfer rate.
The divider must be calculated by calling ilog2 only once, because this
function truncates the fractional part. Calling it twice increases
the error so much that certain bit rates which are available from the
hardware can't be reached by the kernel.
The result of this calculation must be checked to fit into the register
size instead of being truncated silently.

Signed-off-by: Hermann Kraus <hermr2d2 at gmail.com>
---

Changes to v1: Unconditionally use tfr->speed_hz as requested by Mark  
Brown.


  drivers/spi/spi-sun4i.c | 15 +++++++++++----
  drivers/spi/spi-sun6i.c | 15 +++++++++++----
  2 files changed, 22 insertions(+), 8 deletions(-)

diff --git a/drivers/spi/spi-sun4i.c b/drivers/spi/spi-sun4i.c
index fbb0a4d..729d70b 100644
--- a/drivers/spi/spi-sun4i.c
+++ b/drivers/spi/spi-sun4i.c
@@ -229,8 +229,8 @@ static int sun4i_spi_transfer_one(struct spi_master  
*master,

  	/* Ensure that we have a parent clock fast enough */
  	mclk_rate = clk_get_rate(sspi->mclk);
-	if (mclk_rate < (2 * spi->max_speed_hz)) {
-		clk_set_rate(sspi->mclk, 2 * spi->max_speed_hz);
+	if (mclk_rate < (2 * tfr->speed_hz)) {
+		clk_set_rate(sspi->mclk, 2 * tfr->speed_hz);
  		mclk_rate = clk_get_rate(sspi->mclk);
  	}

@@ -248,14 +248,21 @@ static int sun4i_spi_transfer_one(struct spi_master  
*master,
  	 * First try CDR2, and if we can't reach the expected
  	 * frequency, fall back to CDR1.
  	 */
-	div = mclk_rate / (2 * spi->max_speed_hz);
+	div = mclk_rate / (2 * tfr->speed_hz);
  	if (div <= (SUN4I_CLK_CTL_CDR2_MASK + 1)) {
  		if (div > 0)
  			div--;

  		reg = SUN4I_CLK_CTL_CDR2(div) | SUN4I_CLK_CTL_DRS;
  	} else {
-		div = ilog2(mclk_rate) - ilog2(spi->max_speed_hz);
+		/* ilog2 truncates the fractional part. Therefore we don't
+		 * subtract 1 from the result. */
+		div = ilog2(mclk_rate / tfr->speed_hz + 1);
+		if (div & ~SUN4I_CLK_CTL_CDR1_MASK) {
+			/* Can't reach low enough bit rate. */
+			ret = -EINVAL;
+			goto out;
+		}
  		reg = SUN4I_CLK_CTL_CDR1(div);
  	}

diff --git a/drivers/spi/spi-sun6i.c b/drivers/spi/spi-sun6i.c
index ac48f59..2d3dcda 100644
--- a/drivers/spi/spi-sun6i.c
+++ b/drivers/spi/spi-sun6i.c
@@ -217,8 +217,8 @@ static int sun6i_spi_transfer_one(struct spi_master  
*master,

  	/* Ensure that we have a parent clock fast enough */
  	mclk_rate = clk_get_rate(sspi->mclk);
-	if (mclk_rate < (2 * spi->max_speed_hz)) {
-		clk_set_rate(sspi->mclk, 2 * spi->max_speed_hz);
+	if (mclk_rate < (2 * tfr->speed_hz)) {
+		clk_set_rate(sspi->mclk, 2 * tfr->speed_hz);
  		mclk_rate = clk_get_rate(sspi->mclk);
  	}

@@ -236,14 +236,21 @@ static int sun6i_spi_transfer_one(struct spi_master  
*master,
  	 * First try CDR2, and if we can't reach the expected
  	 * frequency, fall back to CDR1.
  	 */
-	div = mclk_rate / (2 * spi->max_speed_hz);
+	div = mclk_rate / (2 * tfr->speed_hz);
  	if (div <= (SUN6I_CLK_CTL_CDR2_MASK + 1)) {
  		if (div > 0)
  			div--;

  		reg = SUN6I_CLK_CTL_CDR2(div) | SUN6I_CLK_CTL_DRS;
  	} else {
-		div = ilog2(mclk_rate) - ilog2(spi->max_speed_hz);
+		/* ilog2 truncates the fractional part. Therefore we don't
+		 * subtract 1 from the result. */
+		div = ilog2(mclk_rate / tfr->speed_hz + 1);
+		if (div & ~SUN6I_CLK_CTL_CDR1_MASK) {
+			/* Can't reach low enough bit rate. */
+			ret = -EINVAL;
+			goto out;
+		}
  		reg = SUN6I_CLK_CTL_CDR1(div);
  	}

-- 
2.1.4


From al.stone at linaro.org  Thu Aug  6 13:59:25 2015
From: al.stone at linaro.org (Al Stone)
Date: Thu,  6 Aug 2015 14:59:25 -0600
Subject: [PATCH 0/5] ACPI: Provide better MADT subtable sanity checks
Message-ID: <1438894770-31163-1-git-send-email-al.stone@linaro.org>

Currently, the BAD_MADT_ENTRY macro is used to do a very simple sanity
check on the various subtables that are defined for the MADT.  The check
compares the size of the subtable data structure as defined by ACPICA to
the length entry in the subtable.  If they are not the same, the assumption
is that the subtable is incorrect.

Over time, the ACPI spec has allowed for MADT subtables where this can
never be true (the local SAPIC subtable, for example).  Or, more recently,
the spec has accumulated some minor flaws where there are three possible 
sizes for a subtable, all of which are valid, but only for specific versions
of the spec (the GICC subtable).  In both cases, BAD_MADT_ENTRY reports these
subtables as bad when they are not.  In order to retain some sanity check
on the MADT subtables, we now have to special case these subtables.  Of
necessity, these special cases have ended up in arch-dependent code (arm64)
or an arch has simply decided to forgo the check (ia64).

This patch set replaces the BAD_MADT_ENTRY macro with a function called
bad_madt_entry().  This function uses a data set of details about the
subtables to provide more sanity checking than before:

	-- is the subtable legal for the version given in the FADT?

	-- is the subtable legal for the revision of the MADT in use?

	-- is the subtable of the proper length (including checking
	   on the one variable length subtable that is currently ignored),
	   given the FADT version and the MADT revision?

Further, this patch set adds in the call to bad_madt_entry() from the 
acpi_table_parse_madt() function, allowing it to be used consistently
by all architectures, for all subtables, and removing the need for each
of the subtable traversal callback functions to use BAD_MADT_ENTRY.

In theory, as the ACPI specification changes, we would only have to add
additional information to the data set describing the MADT subtables in
order to continue providing sanity checks, even when new subtables are
added.

These patches have been tested on an APM Mustang (arm64) and are known to
work there.  They have also been cross-compiled for x86 and ia64 with no
known failures.


Al Stone (5):
  ACPI: add in a bad_madt_entry() function to eventually replace the
    macro
  ACPI / ARM64: remove usage of BAD_MADT_ENTRY/BAD_MADT_GICC_ENTRY
  ACPI / IA64: remove usage of BAD_MADT_ENTRY
  ACPI / X86: remove usage of BAD_MADT_ENTRY
  ACPI: remove definition of BAD_MADT_ENTRY macro

 arch/arm64/include/asm/acpi.h |   8 --
 arch/arm64/kernel/smp.c       |   2 -
 arch/ia64/kernel/acpi.c       |  20 ----
 arch/x86/kernel/acpi/boot.c   |  27 -----
 drivers/acpi/tables.c         | 241 ++++++++++++++++++++++++++++++++++++++++++
 drivers/irqchip/irq-gic.c     |   6 --
 include/linux/acpi.h          |   4 -
 7 files changed, 241 insertions(+), 67 deletions(-)

-- 
2.4.3



From al.stone at linaro.org  Thu Aug  6 13:59:26 2015
From: al.stone at linaro.org (Al Stone)
Date: Thu,  6 Aug 2015 14:59:26 -0600
Subject: [PATCH 1/5] ACPI: add in a bad_madt_entry() function to eventually
 replace the macro
In-Reply-To: <1438894770-31163-1-git-send-email-al.stone@linaro.org>
References: <1438894770-31163-1-git-send-email-al.stone@linaro.org>
Message-ID: <1438894770-31163-2-git-send-email-al.stone@linaro.org>

The existing BAD_MADT_ENTRY macro only checks that the size of the data
structure for an MADT subtable matches the length entry in the subtable.
This is, unfortunately, not reliable.  Nor, as it turns out, does it have
anything to do with what the length should be in any particular table.

We introduce the bad_madt_entry() function that uses a data set to
do some basic sanity checks on any given MADT subtable.  Over time, as
the spec changes, we should just be able to add entries to the data set
to reflect the changes.

What the data set captures is the allowed MADT subtable length for each
type of subtable, for each revision of the specification.  While there
is a revision number in the MADT that we should be able to use to figure
out the proper subtable length, it was not changed when subtables did.
And, while there is a major and minor revision in the FADT that could
also help, it was not always changed as the subtables changed either.
So, the data set captures for each published version of the ACPI spec
what the FADT revisions numbers should be, the corresponding MADT
revision number, and the subtable types and lengths that were defined
at that time.

The sanity checks done are:
	-- is the length non-zero?
	-- is the subtable type defined/allowed for the revision of
	   the FADT we're using?
	-- is the subtable type defined/allowed for the revision of
	   the MADT we're using?
	-- is the length entry what it should be for this revision
	   of the MADT and FADT?

These checks are more thorough than the previous macro provided, and
are now insulated from data structure size changes by ACPICA, which
have been the source of other patches in the past.

Now that the bad_madt_entry() function is available, we add code to
also invoke it before any subtable handlers are called to use the
info in the subtable.  Subsequent patches will remove the use of the
BAD_MADT_ENTRY macro which is now redundant as a result.  Any ACPI
functions that use acpi_parse_madt_entries() will always have all of
the MADT subtables checked from now on.

Signed-off-by: Al Stone <al.stone at linaro.org>
Cc: Rafael J. Wysocki <rjw at rjwysocki.net>
Cc: Len Brown <lenb at kernel.org>
---
 drivers/acpi/tables.c | 241 ++++++++++++++++++++++++++++++++++++++++++++++++++
 1 file changed, 241 insertions(+)

diff --git a/drivers/acpi/tables.c b/drivers/acpi/tables.c
index 2e19189..abd7a72 100644
--- a/drivers/acpi/tables.c
+++ b/drivers/acpi/tables.c
@@ -214,6 +214,245 @@ void acpi_table_print_madt_entry(struct acpi_subtable_header *header)
 	}
 }
 
+/*
+ * The Long, Sad, True Story of the MADT
+ *    or
+ * What does bad_madt_entry() actually do?
+ *
+ * Once upon a time in ACPI 1.0, there was the MADT.  It was a nice table,
+ * and it had two subtables all of its own.  But, it was also a pretty
+ * busy table, too, so over time the MADT gathered up other nice little
+ * subtables.  By the time ACPI 6.0 came around, the MADT had 16 of the
+ * little guys.
+ *
+ * Now, the MADT kept a little counter around for the subtables.  In fact,
+ * it kept two counters: one was the revision level, which was supposed to
+ * change when new subtables came to be, or as the ones already around grew
+ * up. The second counter was a type number, because the MADT needed a unique
+ * type for each subtable so he could tell them apart.  But, sometimes the
+ * MADT got so busy, he forgot to increment the revision level when he needed
+ * to.  Fortunately, the type counter kept increasing since that's the only
+ * way the MADT could find each little subtable.  It just wouldn't do to have
+ * every subtable called Number 6.
+ *
+ * In the next valley over, a castle full of wizards was watching the MADT
+ * and made a pact to keep their own counter.  Every time the MADT found a
+ * new subtable, or a subtable grew up, the wizards promised they would
+ * increment their counter.  Well, wizards being the forgetful sort, they
+ * didn't alway do that.  And, since there quite a lot of them, they
+ * couldn't always remember who was supposed to keep track of the MADT,
+ * especially if dinner was coming up soon.  Their counter was called the
+ * spec version.
+ *
+ * Every now and then, the MADT would gather up all its little subtables
+ * and take them in to the cobbler to get new boots.  This was a very, very
+ * meticulous cobbler, so every time they came, he wrote down all the boot
+ * sizes for all of the little subtables.  The cobbler would ask each subtable
+ * for its length, check that against his careful notes, and then go get the
+ * right boots.  Sometimes, a little subtable would change a bit, and their
+ * length did not match what the cobbler had written down.  If the wizards
+ * or the MADT had incremented their counters, the cobbler would breath a
+ * sigh of relief and write down the new length as the right one.  But, if
+ * none of the counters had changed, this would make the cobbler very, very
+ * mad.  He couldn't tell if he had the right size boots or not for the
+ * little subtable.  He would have to *guess* and this really bugged him.
+ *
+ * Well, when the cobbler got mad like this, he would go into hiding.  He
+ * would not make or sell any boots.  He would not go out at all.  Pretty
+ * soon, the coffee shop would have to close because the cobbler wasn't
+ * coming by twice a day any more.  Then the grocery store would have to
+ * close because he wouldn't eat much.  After a while, everyone would panic
+ * and have to move from the village and go live with all their relatives
+ * (usually the ones they didn't like very much).
+ *
+ * Eventually, the cobbler would work his way out of his bad mood, and
+ * open up his boot business again.  Then, everyone else could move back
+ * to the village and restart their lives, too.
+ *
+ * Fortunately, we have been able to collect up all the cobbler's careful
+ * notes (and we wrote them down below).  We'll have to keep checking these
+ * notes over time, too, just as the cobbler does.  But, in the meantime,
+ * we can avoid the panic and the reboot since we can make sure that each
+ * subtable is doing okay.  And that's what bad_madt_entry() does.
+ *
+ *
+ * FADT Major Version ->       1    3    4     4     5     5     6
+ * FADT Minor Version ->       x    x    x     x     x     1     0
+ * MADT revision ->            1    1    2     3     3     3     3
+ * Spec Version ->            1.0  2.0  3.0b  4.0a  5.0b  5.1a  6.0
+ * Subtable Name	Type  Expected Length ->
+ * Processor Local APIC  0x0    8    8    8     8     8     8     8
+ * IO APIC               0x1   12   12   12    12    12    12    12
+ * Int Src Override      0x2        10   10    10    10    10    10
+ * NMI Src               0x3         8    8     8     8     8     8
+ * Local APIC NMI Struct 0x4         6    6     6     6     6     6
+ * Local APIC Addr Ovrrd 0x5        16   12    12    12    12    12
+ * IO SAPIC              0x6        20   16    16    16    16    16
+ * Local SAPIC           0x7         8  >16   >16   >16   >16   >16
+ * Platform Int Src      0x8        16   16    16    16    16    16
+ * Proc Local x2APIC     0x9                   16    16    16    16
+ * Local x2APIC NMI      0xa                   12    12    12    12
+ * GICC CPU I/F          0xb                         40    76    80
+ * GICD                  0xc                         24    24    24
+ * GICv2m MSI            0xd                               24    24
+ * GICR                  0xe                               16    16
+ * GIC ITS               0xf                                     16
+ *
+ * In the table, each length entry is what should be in the length
+ * field of the subtable, and -- in general -- it should match the
+ * size of the struct for the subtable.  Any value that is not set
+ * (i.e., is zero) indicates that the subtable is not defined for
+ * that version of the ACPI spec.
+ *
+ */
+#define SUBTABLE_UNDEFINED	0x00
+#define SUBTABLE_VARIABLE	0xff
+#define NUM_SUBTABLE_TYPES	16
+
+struct acpi_madt_subtable_lengths {
+	unsigned short major_version;	/* from revision in FADT header */
+	unsigned short minor_version;	/* FADT field starting with 5.1 */
+	unsigned short madt_version;	/* MADT revision */
+	unsigned short num_types;	/* types possible for this version */
+	unsigned short lengths[NUM_SUBTABLE_TYPES];
+					/* subtable lengths, indexed by type */
+};
+
+static struct acpi_madt_subtable_lengths spec_info[] = {
+	{ /* for ACPI 1.0 */
+		.major_version = 1,
+		.minor_version = 0,
+		.madt_version = 1,
+		.num_types = 2,
+		.lengths = { 8, 12 }
+	},
+	{ /* for ACPI 2.0 */
+		.major_version = 3,
+		.minor_version = 0,
+		.madt_version = 1,
+		.num_types = 9,
+		.lengths = { 8, 12, 10, 8, 6, 16, 20, 8, 16 }
+	},
+	{ /* for ACPI 3.0b */
+		.major_version = 4,
+		.minor_version = 0,
+		.madt_version = 2,
+		.num_types = 9,
+		.lengths = { 8, 12, 10, 8, 6, 12, 16, SUBTABLE_VARIABLE, 16 }
+	},
+	{ /* for ACPI 4.0a */
+		.major_version = 4,
+		.minor_version = 0,
+		.madt_version = 3,
+		.num_types = 11,
+		.lengths = { 8, 12, 10, 8, 6, 12, 16, SUBTABLE_VARIABLE,
+			     16, 16, 12 }
+	},
+	{ /* for ACPI 5.0b */
+		.major_version = 5,
+		.minor_version = 0,
+		.madt_version = 3,
+		.num_types = 13,
+		.lengths = { 8, 12, 10, 8, 6, 12, 16, SUBTABLE_VARIABLE,
+			     16, 16, 12, 40, 24 }
+	},
+	{ /* for ACPI 5.1a */
+		.major_version = 5,
+		.minor_version = 1,
+		.madt_version = 3,
+		.num_types = 15,
+		.lengths = { 8, 12, 10, 8, 6, 12, 16, SUBTABLE_VARIABLE,
+			     16, 16, 12, 76, 24, 24, 16 }
+	},
+	{ /* for ACPI 6.0 */
+		.major_version = 6,
+		.minor_version = 0,
+		.madt_version = 3,
+		.num_types = 16,
+		.lengths = { 8, 12, 10, 8, 6, 12, 16, SUBTABLE_VARIABLE,
+			     16, 16, 12, 80, 24, 24, 16, 16 }
+	},
+	{ /* terminator */
+		.major_version = 0,
+		.minor_version = 0,
+		.madt_version = 0,
+		.num_types = 0,
+		.lengths = { 0 }
+	}
+};
+
+int __init bad_madt_entry(struct acpi_table_header *table,
+			  struct acpi_subtable_header *entry)
+{
+	struct acpi_madt_subtable_lengths *ms;
+	struct acpi_table_madt *madt;
+	unsigned short major;
+	unsigned short minor;
+	unsigned short len;
+
+	/* simple sanity checking on MADT subtable entries */
+	if (!entry || !table)
+		return 1;
+
+	/* FADT minor numbers were not introduced until ACPI 5.1 */
+	major = acpi_gbl_FADT.header.revision;
+	if (major >= 5 && acpi_gbl_FADT.header.length >= 268)
+		minor = acpi_gbl_FADT.minor_revision;
+	else
+		minor = 0;
+
+	madt = (struct acpi_table_madt *)table;
+	ms = spec_info;
+	while (ms->num_types != 0) {
+		if (ms->major_version == major &&
+		    ms->minor_version == minor &&
+		    ms->madt_version == madt->header.revision)
+			break;
+		ms++;
+	}
+	if (!ms) {
+		pr_err("undefined FADT version: %d.%d\n", major, minor);
+		return 1;
+	}
+
+	if (entry->type >= ms->num_types) {
+		pr_err("undefined MADT subtable type for FADT %d.%d: %d (length %d)\n",
+		       major, minor, entry->type, entry->length);
+		return 1;
+	}
+
+	/* verify that the table is allowed for this version of the spec */
+	len = ms->lengths[entry->type];
+	if (!len) {
+		pr_err("MADT subtable %d not defined for FADT %d.%d\n",
+			 entry->type, major, minor);
+		return 1;
+	}
+
+	/* verify that the length is what we expect */
+	if (len == SUBTABLE_VARIABLE) {
+		if (entry->type == ACPI_MADT_TYPE_LOCAL_SAPIC) {
+			struct acpi_madt_local_sapic *lsapic =
+				(struct acpi_madt_local_sapic *)entry;
+
+			if (sizeof(struct acpi_madt_local_sapic) +
+			    strlen(lsapic->uid_string) + 1 != entry->length) {
+				pr_err("Variable length MADT subtable %d is wrong size: %d\n",
+				       entry->type, entry->length);
+				return 1;
+			}
+		}
+	} else {
+		if (entry->length != len) {
+			pr_err("MADT subtable %d is wrong size: %d\n",
+			       len, entry->type);
+			return 1;
+		}
+	}
+
+	return 0;
+}
+
 int __init
 acpi_parse_entries(char *id, unsigned long table_size,
 		acpi_tbl_entry_handler handler,
@@ -249,6 +488,8 @@ acpi_parse_entries(char *id, unsigned long table_size,
 	       table_end) {
 		if (entry->type == entry_id
 		    && (!max_entries || count < max_entries)) {
+			if (bad_madt_entry(table_header, entry))
+				return -EINVAL;
 			if (handler(entry, table_end))
 				return -EINVAL;
 
-- 
2.4.3



From al.stone at linaro.org  Thu Aug  6 13:59:30 2015
From: al.stone at linaro.org (Al Stone)
Date: Thu,  6 Aug 2015 14:59:30 -0600
Subject: [PATCH 5/5] ACPI: remove definition of BAD_MADT_ENTRY macro
In-Reply-To: <1438894770-31163-1-git-send-email-al.stone@linaro.org>
References: <1438894770-31163-1-git-send-email-al.stone@linaro.org>
Message-ID: <1438894770-31163-6-git-send-email-al.stone@linaro.org>

Now that we have introduced to bad_madt_entry(), and we have removed
all the usages of the BAD_MADT_ENTRY macro from all of the various
architectures that use it (arm64, ia64, x86), we can remove the macro
definition since it is no longer used.

Signed-off-by: Al Stone <al.stone at linaro.org>
Cc: Rafael J. Wysocki <rjw at rjwysocki.net>
Cc: Len Brown <lenb at kernel.org>
---
 include/linux/acpi.h | 4 ----
 1 file changed, 4 deletions(-)

diff --git a/include/linux/acpi.h b/include/linux/acpi.h
index d2445fa..06072d8 100644
--- a/include/linux/acpi.h
+++ b/include/linux/acpi.h
@@ -131,10 +131,6 @@ static inline void acpi_initrd_override(void *data, size_t size)
 }
 #endif
 
-#define BAD_MADT_ENTRY(entry, end) (					    \
-		(!entry) || (unsigned long)entry + sizeof(*entry) > end ||  \
-		((struct acpi_subtable_header *)entry)->length < sizeof(*entry))
-
 char * __acpi_map_table (unsigned long phys_addr, unsigned long size);
 void __acpi_unmap_table(char *map, unsigned long size);
 int early_acpi_boot_init(void);
-- 
2.4.3



From al.stone at linaro.org  Thu Aug  6 13:59:28 2015
From: al.stone at linaro.org (Al Stone)
Date: Thu,  6 Aug 2015 14:59:28 -0600
Subject: [PATCH 3/5] ACPI / IA64: remove usage of BAD_MADT_ENTRY
In-Reply-To: <1438894770-31163-1-git-send-email-al.stone@linaro.org>
References: <1438894770-31163-1-git-send-email-al.stone@linaro.org>
Message-ID: <1438894770-31163-4-git-send-email-al.stone@linaro.org>

Now that we have introduced the bad_madt_entry() function, and that
function is being invoked in acpi_table_parse_madt() for us, there
is no longer any need to use the BAD_MADT_ENTRY macro.

Signed-off-by: Al Stone <al.stone at linaro.org>
Cc: Tony Luck <tony.luck at intel.com>
Cc: Fenghua Yu <fenghua.yu at intel.com>
---
 arch/ia64/kernel/acpi.c | 20 --------------------
 1 file changed, 20 deletions(-)

diff --git a/arch/ia64/kernel/acpi.c b/arch/ia64/kernel/acpi.c
index b1698bc..efa3f0a 100644
--- a/arch/ia64/kernel/acpi.c
+++ b/arch/ia64/kernel/acpi.c
@@ -184,9 +184,6 @@ acpi_parse_lapic_addr_ovr(struct acpi_subtable_header * header,
 
 	lapic = (struct acpi_madt_local_apic_override *)header;
 
-	if (BAD_MADT_ENTRY(lapic, end))
-		return -EINVAL;
-
 	if (lapic->address) {
 		iounmap(ipi_base_addr);
 		ipi_base_addr = ioremap(lapic->address, 0);
@@ -201,8 +198,6 @@ acpi_parse_lsapic(struct acpi_subtable_header * header, const unsigned long end)
 
 	lsapic = (struct acpi_madt_local_sapic *)header;
 
-	/*Skip BAD_MADT_ENTRY check, as lsapic size could vary */
-
 	if (lsapic->lapic_flags & ACPI_MADT_ENABLED) {
 #ifdef CONFIG_SMP
 		smp_boot_data.cpu_phys_id[available_cpus] =
@@ -222,9 +217,6 @@ acpi_parse_lapic_nmi(struct acpi_subtable_header * header, const unsigned long e
 
 	lacpi_nmi = (struct acpi_madt_local_apic_nmi *)header;
 
-	if (BAD_MADT_ENTRY(lacpi_nmi, end))
-		return -EINVAL;
-
 	/* TBD: Support lapic_nmi entries */
 	return 0;
 }
@@ -236,9 +228,6 @@ acpi_parse_iosapic(struct acpi_subtable_header * header, const unsigned long end
 
 	iosapic = (struct acpi_madt_io_sapic *)header;
 
-	if (BAD_MADT_ENTRY(iosapic, end))
-		return -EINVAL;
-
 	return iosapic_init(iosapic->address, iosapic->global_irq_base);
 }
 
@@ -253,9 +242,6 @@ acpi_parse_plat_int_src(struct acpi_subtable_header * header,
 
 	plintsrc = (struct acpi_madt_interrupt_source *)header;
 
-	if (BAD_MADT_ENTRY(plintsrc, end))
-		return -EINVAL;
-
 	/*
 	 * Get vector assignment for this interrupt, set attributes,
 	 * and program the IOSAPIC routing table.
@@ -336,9 +322,6 @@ acpi_parse_int_src_ovr(struct acpi_subtable_header * header,
 
 	p = (struct acpi_madt_interrupt_override *)header;
 
-	if (BAD_MADT_ENTRY(p, end))
-		return -EINVAL;
-
 	iosapic_override_isa_irq(p->source_irq, p->global_irq,
 				 ((p->inti_flags & ACPI_MADT_POLARITY_MASK) ==
 				  ACPI_MADT_POLARITY_ACTIVE_LOW) ?
@@ -356,9 +339,6 @@ acpi_parse_nmi_src(struct acpi_subtable_header * header, const unsigned long end
 
 	nmi_src = (struct acpi_madt_nmi_source *)header;
 
-	if (BAD_MADT_ENTRY(nmi_src, end))
-		return -EINVAL;
-
 	/* TBD: Support nimsrc entries */
 	return 0;
 }
-- 
2.4.3



From al.stone at linaro.org  Thu Aug  6 13:59:27 2015
From: al.stone at linaro.org (Al Stone)
Date: Thu,  6 Aug 2015 14:59:27 -0600
Subject: [PATCH 2/5] ACPI / ARM64: remove usage of
 BAD_MADT_ENTRY/BAD_MADT_GICC_ENTRY
In-Reply-To: <1438894770-31163-1-git-send-email-al.stone@linaro.org>
References: <1438894770-31163-1-git-send-email-al.stone@linaro.org>
Message-ID: <1438894770-31163-3-git-send-email-al.stone@linaro.org>

Now that we have introduced the bad_madt_entry() function, and that
function is being invoked in acpi_table_parse_madt() for us, there
is no longer any need to use the BAD_MADT_ENTRY macro, or in the case
of arm64, the BAD_MADT_GICC_ENTRY, too.

Signed-off-by: Al Stone <al.stone at linaro.org>
Cc: Catalin Marinas <catalin.marinas at arm.com>
Cc: Will Deacon <will.deacon at arm.com>
Cc: Thomas Gleixner <tglx at linutronix.de>
Cc: Jason Cooper <jason at lakedaemon.net>
Cc: Marc Zyngier <marc.zyngier at arm.com>
---
 arch/arm64/include/asm/acpi.h | 8 --------
 arch/arm64/kernel/smp.c       | 2 --
 drivers/irqchip/irq-gic.c     | 6 ------
 3 files changed, 16 deletions(-)

diff --git a/arch/arm64/include/asm/acpi.h b/arch/arm64/include/asm/acpi.h
index 406485e..39248d3 100644
--- a/arch/arm64/include/asm/acpi.h
+++ b/arch/arm64/include/asm/acpi.h
@@ -19,14 +19,6 @@
 #include <asm/psci.h>
 #include <asm/smp_plat.h>
 
-/* Macros for consistency checks of the GICC subtable of MADT */
-#define ACPI_MADT_GICC_LENGTH	\
-	(acpi_gbl_FADT.header.revision < 6 ? 76 : 80)
-
-#define BAD_MADT_GICC_ENTRY(entry, end)						\
-	(!(entry) || (unsigned long)(entry) + sizeof(*(entry)) > (end) ||	\
-	 (entry)->header.length != ACPI_MADT_GICC_LENGTH)
-
 /* Basic configuration for ACPI */
 #ifdef	CONFIG_ACPI
 /* ACPI table mapping after acpi_gbl_permanent_mmap is set */
diff --git a/arch/arm64/kernel/smp.c b/arch/arm64/kernel/smp.c
index 50fb469..acd3b27 100644
--- a/arch/arm64/kernel/smp.c
+++ b/arch/arm64/kernel/smp.c
@@ -438,8 +438,6 @@ acpi_parse_gic_cpu_interface(struct acpi_subtable_header *header,
 	struct acpi_madt_generic_interrupt *processor;
 
 	processor = (struct acpi_madt_generic_interrupt *)header;
-	if (BAD_MADT_GICC_ENTRY(processor, end))
-		return -EINVAL;
 
 	acpi_table_print_madt_entry(header);
 
diff --git a/drivers/irqchip/irq-gic.c b/drivers/irqchip/irq-gic.c
index 4dd8826..2735611 100644
--- a/drivers/irqchip/irq-gic.c
+++ b/drivers/irqchip/irq-gic.c
@@ -1055,9 +1055,6 @@ gic_acpi_parse_madt_cpu(struct acpi_subtable_header *header,
 
 	processor = (struct acpi_madt_generic_interrupt *)header;
 
-	if (BAD_MADT_GICC_ENTRY(processor, end))
-		return -EINVAL;
-
 	/*
 	 * There is no support for non-banked GICv1/2 register in ACPI spec.
 	 * All CPU interface addresses have to be the same.
@@ -1079,9 +1076,6 @@ gic_acpi_parse_madt_distributor(struct acpi_subtable_header *header,
 
 	dist = (struct acpi_madt_generic_distributor *)header;
 
-	if (BAD_MADT_ENTRY(dist, end))
-		return -EINVAL;
-
 	dist_phy_base = dist->base_address;
 	return 0;
 }
-- 
2.4.3



From al.stone at linaro.org  Thu Aug  6 13:59:29 2015
From: al.stone at linaro.org (Al Stone)
Date: Thu,  6 Aug 2015 14:59:29 -0600
Subject: [PATCH 4/5] ACPI / X86: remove usage of BAD_MADT_ENTRY
In-Reply-To: <1438894770-31163-1-git-send-email-al.stone@linaro.org>
References: <1438894770-31163-1-git-send-email-al.stone@linaro.org>
Message-ID: <1438894770-31163-5-git-send-email-al.stone@linaro.org>

Now that we have introduced the bad_madt_entry() function, and that
function is being invoked in acpi_table_parse_madt() for us, there
is no longer any need to use the BAD_MADT_ENTRY macro.

Signed-off-by: Al Stone <al.stone at linaro.org>
Cc: Rafael J. Wysocki <rjw at rjwysocki.net>
Cc: Len Brown <len.brown at intel.com>
Cc: Pavel Machek <pavel at ucw.cz>
Cc: Thomas Gleixner <tglx at linutronix.de>
Cc: Ingo Molnar <mingo at redhat.com>
Cc: H. Peter Anvin <hpa at zytor.com>
Cc: x86 at kernel.org
---
 arch/x86/kernel/acpi/boot.c | 27 ---------------------------
 1 file changed, 27 deletions(-)

diff --git a/arch/x86/kernel/acpi/boot.c b/arch/x86/kernel/acpi/boot.c
index e49ee24..9bdf786 100644
--- a/arch/x86/kernel/acpi/boot.c
+++ b/arch/x86/kernel/acpi/boot.c
@@ -194,9 +194,6 @@ acpi_parse_x2apic(struct acpi_subtable_header *header, const unsigned long end)
 
 	processor = (struct acpi_madt_local_x2apic *)header;
 
-	if (BAD_MADT_ENTRY(processor, end))
-		return -EINVAL;
-
 	acpi_table_print_madt_entry(header);
 
 	apic_id = processor->local_apic_id;
@@ -227,9 +224,6 @@ acpi_parse_lapic(struct acpi_subtable_header * header, const unsigned long end)
 
 	processor = (struct acpi_madt_local_apic *)header;
 
-	if (BAD_MADT_ENTRY(processor, end))
-		return -EINVAL;
-
 	acpi_table_print_madt_entry(header);
 
 	/*
@@ -252,9 +246,6 @@ acpi_parse_sapic(struct acpi_subtable_header *header, const unsigned long end)
 
 	processor = (struct acpi_madt_local_sapic *)header;
 
-	if (BAD_MADT_ENTRY(processor, end))
-		return -EINVAL;
-
 	acpi_table_print_madt_entry(header);
 
 	acpi_register_lapic((processor->id << 8) | processor->eid,/* APIC ID */
@@ -271,9 +262,6 @@ acpi_parse_lapic_addr_ovr(struct acpi_subtable_header * header,
 
 	lapic_addr_ovr = (struct acpi_madt_local_apic_override *)header;
 
-	if (BAD_MADT_ENTRY(lapic_addr_ovr, end))
-		return -EINVAL;
-
 	acpi_lapic_addr = lapic_addr_ovr->address;
 
 	return 0;
@@ -287,9 +275,6 @@ acpi_parse_x2apic_nmi(struct acpi_subtable_header *header,
 
 	x2apic_nmi = (struct acpi_madt_local_x2apic_nmi *)header;
 
-	if (BAD_MADT_ENTRY(x2apic_nmi, end))
-		return -EINVAL;
-
 	acpi_table_print_madt_entry(header);
 
 	if (x2apic_nmi->lint != 1)
@@ -305,9 +290,6 @@ acpi_parse_lapic_nmi(struct acpi_subtable_header * header, const unsigned long e
 
 	lapic_nmi = (struct acpi_madt_local_apic_nmi *)header;
 
-	if (BAD_MADT_ENTRY(lapic_nmi, end))
-		return -EINVAL;
-
 	acpi_table_print_madt_entry(header);
 
 	if (lapic_nmi->lint != 1)
@@ -411,9 +393,6 @@ acpi_parse_ioapic(struct acpi_subtable_header * header, const unsigned long end)
 
 	ioapic = (struct acpi_madt_io_apic *)header;
 
-	if (BAD_MADT_ENTRY(ioapic, end))
-		return -EINVAL;
-
 	acpi_table_print_madt_entry(header);
 
 	/* Statically assign IRQ numbers for IOAPICs hosting legacy IRQs */
@@ -462,9 +441,6 @@ acpi_parse_int_src_ovr(struct acpi_subtable_header * header,
 
 	intsrc = (struct acpi_madt_interrupt_override *)header;
 
-	if (BAD_MADT_ENTRY(intsrc, end))
-		return -EINVAL;
-
 	acpi_table_print_madt_entry(header);
 
 	if (intsrc->source_irq == acpi_gbl_FADT.sci_interrupt) {
@@ -503,9 +479,6 @@ acpi_parse_nmi_src(struct acpi_subtable_header * header, const unsigned long end
 
 	nmi_src = (struct acpi_madt_nmi_source *)header;
 
-	if (BAD_MADT_ENTRY(nmi_src, end))
-		return -EINVAL;
-
 	acpi_table_print_madt_entry(header);
 
 	/* TBD: Support nimsrc entries? */
-- 
2.4.3



From linux at arm.linux.org.uk  Thu Aug  6 14:33:40 2015
From: linux at arm.linux.org.uk (Russell King - ARM Linux)
Date: Thu, 6 Aug 2015 22:33:40 +0100
Subject: [RFC PATCH 1/5] spi: introduce flag for memory mapped read
In-Reply-To: <CAMuHMdWWDwZ=ziGQXFCnOX8pErXpsEi533J73_Hh=sEqq4hR6Q@mail.gmail.com>
References: <20150805115013.GJ20873@sirena.org.uk>
 <CAOMqctQXwcHyiWBwtugSDSE_k65qrNfrwnhjQMDJkLoJMmGzUw@mail.gmail.com>
 <20150805124412.GN20873@sirena.org.uk>
 <CAOMqctS9Y5FxpUCCJew6+cnjH5iTvbzkH3g-8yrXs4OuS2pSGA@mail.gmail.com>
 <20150806090202.GO20873@sirena.org.uk>
 <CAOMqctQZRZ4zG_yYy=CeX3DX4NVNWN1COP4Q-2YvMun9xYOA7g@mail.gmail.com>
 <20150806102225.GI7576@n2100.arm.linux.org.uk>
 <55C35233.2000105@ti.com>
 <20150806135129.GJ7576@n2100.arm.linux.org.uk>
 <CAMuHMdWWDwZ=ziGQXFCnOX8pErXpsEi533J73_Hh=sEqq4hR6Q@mail.gmail.com>
Message-ID: <20150806213340.GK7576@n2100.arm.linux.org.uk>

On Thu, Aug 06, 2015 at 06:14:00PM +0200, Geert Uytterhoeven wrote:
> On Thu, Aug 6, 2015 at 3:51 PM, Russell King - ARM Linux
> <linux at arm.linux.org.uk> wrote:
> > On Thu, Aug 06, 2015 at 05:55:23PM +0530, Vignesh R wrote:
> >> On the whole following are my requirements:
> >> 1. to be able to communicate with non -flash SPI devices via config port
> >> ( this functionality is supported by current driver, I dont want to
> >> break it). Or pump any spi_message on to SPI bus directly.
> >> 2. take advantage of memory mapped port in order to increase read
> >> throughput( and use dma in future) when the slave is a m25p80 type flash.
> >> 3. handle m25p80 as well as other slave on multiple chipselects.
> >>
> >> I just need to know whether the user that requested the transfer is
> >> m25p80 driver. If yes, ti-qspi driver can take advantage of memory
> >> mapped interface, else just use config port to access SPI bus directly.
> >
> > The problem with this approach is that it's an abomination.  It's adding
> > a SPI-user specific hack which is detected by a specific driver.  That's
> > really not sane - what happens when we have lots of these kinds of "I'm
> > an X SPI-user" with drivers detecting that?  It's not maintainable in the
> > long term.
> >
> > Yes, your requirements _today_ seem simple and easy, but you're only
> > thinking about today, not tomorrow when you've moved on and someone else
> > has to maintain the mess left behind (or delete it from mainline because
> > they're sick of dealing with a hack.)
> >
> >> The spi_message that is received in transfer_one_message() is too
> >> generic to imply the slave device that is on the other side of the wire.
> >> IMO, the read command does not imply that the slave is m25p80 flash
> >> (besides the read opcodes vary across vendors of m25p80 and across modes).
> >
> > I can see both sides of the argument.
> >
> > Mark is saying: if the SPI driver detects that the message to be transmitted
> > is a read command followed by the appropriate number of dummy bytes, and
> > then the data being read _and_ it's using quad-mode access, and the hardware
> > generates _exactly_ that in hardware using the memory mapped mode, there is
> > no reason _not_ to use the hardware to achieve that SPI transaction.  The
> > bus activity will be identical to what happens when the SPI controller is
> > used manually to achieve that bus sequence.
> >
> > You're saying: but the documentation says you can't use it for anything
> > except m25p80.  If you look at 24.5.4.1.2, it tells you what the SFI
> > generates on the bus, which is:
> >
> > 1. CS active
> > 2. Read command byte sent
> > 3. 1-4 address bytes sent
> > 4. 0-3 dummy bytes sent
> > 5. data bytes read from bus
> > 6. CS inactive
> >
> > So, Mark's point is "if we can detect a transaction which fits _that_
> > bus activity, there's no reason not to use this acceleration for the
> > transaction."
> >
> > What you're failing to counter with is: we don't have enough information
> > in the SPI driver to know how many dummy bytes there are between the
> > address bytes and the data read from the bus.
> 
> Irrespective of the dummy bytes.
> What if the spi device is not a FLASH ROM, but some other device,
> which receives a data packet that accidentally looks like an m25p80 READ
> command?

Well, for the most part it looks like it should still work, but there
could be a gotcha, but first, let's get rid of a myth there.

The QSPI is _not_ specific to the M25P80.  The manual says nothing
about being specific to that device.  What it says is that it's for
SPI NOR memory.  It will work with bus widths of 1, 2 or 4 data lines,
so it probably works with non-M25P80 SPI NOR devices too - and the fact
that the read and write commands are completely programmable suggests
that using it with SPI NOR devices which do not use the M25P80 read
command value is intended.


The SFI is a state machine based translator which sits behind the SPI
interface (look at the manual).  It sequence sthe SPI bus through a
series of standard SPI states which happen to be the states I detailed
above.

Now, the first byte of the SFI-generated SPI message can be programmed
to any 8 bit value.  So the first byte of the SPI message is totally
under software control.  The next one to four bytes which comprise the
"address" can be controlled to by deciding where in the memory map to
start reading from.  Hence, the value of those bytes is also totally
under software control.  The number of dummy bytes can be programmed
too.  So far so good.

So, if we know that we have a SPI message which says "send 0x01 0x20
0x30, send one dummy byte, read 32 bytes", if we program the SFI to
send a read command as 0x01, program an address length of 2 bytes
with one dummy byte, and then read the next 32 bytes at the appropriate
offset in the memory mapping to cause the next two bytes to be 0x20,
0x30, then what we end up with on the bus is:

	send 0x01, 0x20, 0x30
	send one dummy byte

That much is good, but now is the problem - how does the SFI know that
we're going to require to read 32 bytes?  I think the answer to that
is that it doesn't know, so it probably just reads the number of bytes
which the access on the SoC bus is asking for, which makes it
indeterminant from a software point of view to control how many bytes
will be read without provoking another "send 0x01, next address, dummy
byte" sequence.

So, I'm now on the side of not parsing commands in the SPI driver, and
back on the idea that this needs to be handled in some other manner
which doesn't involve polluting the SPI core with flag-hacks.

-- 
FTTC broadband for 0.8mile line: currently at 10.5Mbps down 400kbps up
according to speedtest.net.


From msalter at redhat.com  Thu Aug  6 14:41:36 2015
From: msalter at redhat.com (Mark Salter)
Date: Thu,  6 Aug 2015 17:41:36 -0400
Subject: [PATCH V2 0/3] mm: Add generic copy from early unmapped RAM
Message-ID: <1438897299-2266-1-git-send-email-msalter@redhat.com>

When booting an arm64 kernel w/initrd using UEFI/grub, use of mem= will likely
cut off part or all of the initrd. This leaves it outside the kernel linear
map which leads to failure when unpacking. The x86 code has a similar need to
relocate an initrd outside of mapped memory in some cases.

The current x86 code uses early_memremap() to copy the original initrd from
unmapped to mapped RAM. This patchset creates a generic copy_from_early_mem()
utility based on that x86 code and has arm64 and x86 share it in their
respective initrd relocation code.

Changes from V1:

  * Change cover letter subject to highlight the added generic code

  * Add patch for x86 to use common copy_from_early_mem()

Mark Salter (3):
  mm: add utility for early copy from unmapped ram
  arm64: support initrd outside kernel linear map
  x86: use generic early mem copy

 arch/arm64/kernel/setup.c           | 55 +++++++++++++++++++++++++++++++++++++
 arch/x86/kernel/setup.c             | 21 +-------------
 include/asm-generic/early_ioremap.h |  6 ++++
 mm/early_ioremap.c                  | 22 +++++++++++++++
 4 files changed, 84 insertions(+), 20 deletions(-)

-- 
2.4.3



From msalter at redhat.com  Thu Aug  6 14:41:39 2015
From: msalter at redhat.com (Mark Salter)
Date: Thu,  6 Aug 2015 17:41:39 -0400
Subject: [PATCH V2 3/3] x86: use generic early mem copy
In-Reply-To: <1438897299-2266-1-git-send-email-msalter@redhat.com>
References: <1438897299-2266-1-git-send-email-msalter@redhat.com>
Message-ID: <1438897299-2266-4-git-send-email-msalter@redhat.com>

The early_ioremap library now has a generic copy_from_early_mem()
function. Use the generic copy function for x86 relocate_initrd().

Signed-off-by: Mark Salter <msalter at redhat.com>
---
 arch/x86/kernel/setup.c | 21 +--------------------
 1 file changed, 1 insertion(+), 20 deletions(-)

diff --git a/arch/x86/kernel/setup.c b/arch/x86/kernel/setup.c
index 80f874b..b2a8446 100644
--- a/arch/x86/kernel/setup.c
+++ b/arch/x86/kernel/setup.c
@@ -324,8 +324,6 @@ static void __init relocate_initrd(void)
 	u64 ramdisk_image = get_ramdisk_image();
 	u64 ramdisk_size  = get_ramdisk_size();
 	u64 area_size     = PAGE_ALIGN(ramdisk_size);
-	unsigned long slop, clen, mapaddr;
-	char *p, *q;
 
 	/* We need to move the initrd down into directly mapped mem */
 	relocated_ramdisk = memblock_find_in_range(0, PFN_PHYS(max_pfn_mapped),
@@ -343,25 +341,8 @@ static void __init relocate_initrd(void)
 	printk(KERN_INFO "Allocated new RAMDISK: [mem %#010llx-%#010llx]\n",
 	       relocated_ramdisk, relocated_ramdisk + ramdisk_size - 1);
 
-	q = (char *)initrd_start;
-
-	/* Copy the initrd */
-	while (ramdisk_size) {
-		slop = ramdisk_image & ~PAGE_MASK;
-		clen = ramdisk_size;
-		if (clen > MAX_MAP_CHUNK-slop)
-			clen = MAX_MAP_CHUNK-slop;
-		mapaddr = ramdisk_image & PAGE_MASK;
-		p = early_memremap(mapaddr, clen+slop);
-		memcpy(q, p+slop, clen);
-		early_memunmap(p, clen+slop);
-		q += clen;
-		ramdisk_image += clen;
-		ramdisk_size  -= clen;
-	}
+	copy_from_early_mem((void *)initrd_start, ramdisk_image, ramdisk_size);
 
-	ramdisk_image = get_ramdisk_image();
-	ramdisk_size  = get_ramdisk_size();
 	printk(KERN_INFO "Move RAMDISK from [mem %#010llx-%#010llx] to"
 		" [mem %#010llx-%#010llx]\n",
 		ramdisk_image, ramdisk_image + ramdisk_size - 1,
-- 
2.4.3



From msalter at redhat.com  Thu Aug  6 14:41:38 2015
From: msalter at redhat.com (Mark Salter)
Date: Thu,  6 Aug 2015 17:41:38 -0400
Subject: [PATCH V2 2/3] arm64: support initrd outside kernel linear map
In-Reply-To: <1438897299-2266-1-git-send-email-msalter@redhat.com>
References: <1438897299-2266-1-git-send-email-msalter@redhat.com>
Message-ID: <1438897299-2266-3-git-send-email-msalter@redhat.com>

The use of mem= could leave part or all of the initrd outside of
the kernel linear map. This will lead to an error when unpacking
the initrd and a probable failure to boot. This patch catches that
situation and relocates the initrd to be fully within the linear
map.

Signed-off-by: Mark Salter <msalter at redhat.com>
---
 arch/arm64/kernel/setup.c | 55 +++++++++++++++++++++++++++++++++++++++++++++++
 1 file changed, 55 insertions(+)

diff --git a/arch/arm64/kernel/setup.c b/arch/arm64/kernel/setup.c
index f3067d4..96339b5 100644
--- a/arch/arm64/kernel/setup.c
+++ b/arch/arm64/kernel/setup.c
@@ -359,6 +359,60 @@ static void __init request_standard_resources(void)
 	}
 }
 
+/*
+ * Relocate initrd if it is not completely within the linear mapping.
+ * This would be the case if mem= cuts out all or part of it.
+ */
+static void __init relocate_initrd(void)
+{
+#ifdef CONFIG_BLK_DEV_INITRD
+	phys_addr_t orig_start = __virt_to_phys(initrd_start);
+	phys_addr_t orig_end = __virt_to_phys(initrd_end);
+	phys_addr_t ram_end = memblock_end_of_DRAM();
+	phys_addr_t new_start;
+	unsigned long size, to_free = 0;
+	void *dest;
+
+	if (orig_end <= ram_end)
+		return;
+
+	/* Note if any of original initrd will freeing below */
+	if (orig_start < ram_end)
+		to_free = ram_end - orig_start;
+
+	size = orig_end - orig_start;
+
+	/* initrd needs to be relocated completely inside linear mapping */
+	new_start = memblock_find_in_range(0, PFN_PHYS(max_pfn),
+					   size, PAGE_SIZE);
+	if (!new_start)
+		panic("Cannot relocate initrd of size %ld\n", size);
+	memblock_reserve(new_start, size);
+
+	initrd_start = __phys_to_virt(new_start);
+	initrd_end   = initrd_start + size;
+
+	pr_info("Moving initrd from [%llx-%llx] to [%llx-%llx]\n",
+		orig_start, orig_start + size - 1,
+		new_start, new_start + size - 1);
+
+	dest = (void *)initrd_start;
+
+	if (to_free) {
+		memcpy(dest, (void *)__phys_to_virt(orig_start), to_free);
+		dest += to_free;
+	}
+
+	copy_from_early_mem(dest, orig_start + to_free, size - to_free);
+
+	if (to_free) {
+		pr_info("Freeing original RAMDISK from [%llx-%llx]\n",
+			orig_start, orig_start + to_free - 1);
+		memblock_free(orig_start, to_free);
+	}
+#endif
+}
+
 u64 __cpu_logical_map[NR_CPUS] = { [0 ... NR_CPUS-1] = INVALID_HWID };
 
 void __init setup_arch(char **cmdline_p)
@@ -392,6 +446,7 @@ void __init setup_arch(char **cmdline_p)
 	acpi_boot_table_init();
 
 	paging_init();
+	relocate_initrd();
 	request_standard_resources();
 
 	early_ioremap_reset();
-- 
2.4.3



From james.hogan at imgtec.com  Thu Aug  6 14:52:05 2015
From: james.hogan at imgtec.com (James Hogan)
Date: Thu, 6 Aug 2015 22:52:05 +0100
Subject: next-20150806 build: 2 failures 52 warnings (next-20150806)
In-Reply-To: <20150806172752.GA20873@sirena.org.uk>
References: <E1ZNIul-0007IF-Ev@optimist> <20150806172752.GA20873@sirena.org.uk>
Message-ID: <20150806215205.GB14493@jhogan-linux.le.imgtec.org>

Hi Mark,

On Thu, Aug 06, 2015 at 06:27:52PM +0100, Mark Brown wrote:
> On Thu, Aug 06, 2015 at 12:00:47PM +0100, Build bot for Mark Brown wrote:
> 
> Today's linux-next fails to build an ARM allmodconfig with:
> 
> > 	arm-allmodconfig
> > ../lib/test_user_copy.c:67:2: error: implicit declaration of function 'copy_in_user' [-Werror=implicit-function-declaration]
> > ../lib/test_user_copy.c:94:2: error: implicit declaration of function '__copy_in_user' [-Werror=implicit-function-declaration]
> 
> due to 3a646f02c7 (lib/test_user_copy.c: check
> __copy_in_user()/copy_in_user()) which attempts to test copy_in_user()
> which doesn't appear to be defined, at least with the set of include
> files and/or config options you get with an allmodconfig and not at all
> as far as I can tell.

Yeh, the copy_in_user ones need to be conditional upon CONFIG_COMPAT.
Sorry for the breakage. I've asked Andrew to drop them until I can get a
v2 patchset out tomorrow.

Cheers
James
-------------- next part --------------
A non-text attachment was scrubbed...
Name: signature.asc
Type: application/pgp-signature
Size: 819 bytes
Desc: Digital signature
URL: <http://lists.infradead.org/pipermail/linux-arm-kernel/attachments/20150806/e8f94a6e/attachment.sig>

From eric at anholt.net  Thu Aug  6 16:00:29 2015
From: eric at anholt.net (Eric Anholt)
Date: Thu,  6 Aug 2015 16:00:29 -0700
Subject: Raspberry Pi 2 interrupt controller support (v4)
Message-ID: <1438902033-31477-1-git-send-email-eric@anholt.net>

https://github.com/anholt/linux/tree/bcm2836-irqchip



From eric at anholt.net  Thu Aug  6 16:00:31 2015
From: eric at anholt.net (Eric Anholt)
Date: Thu,  6 Aug 2015 16:00:31 -0700
Subject: [PATCH v4 2/4] irqchip: bcm2835: Add support for being used as a
 second level controller.
In-Reply-To: <1438902033-31477-1-git-send-email-eric@anholt.net>
References: <1438902033-31477-1-git-send-email-eric@anholt.net>
Message-ID: <1438902033-31477-3-git-send-email-eric@anholt.net>

The BCM2836 (Raspberry Pi 2) uses two levels of interrupt handling
with the CPU-local interrupts being the root, so we need to register
ours as chained off of the CPU's local interrupt.

Signed-off-by: Eric Anholt <eric at anholt.net>
Acked-by: Stephen Warren <swarren at wwwdotorg.org>
---

v3: Use a separate compatible value to indicate that the parent
    interrupt controller irq is required (Requested by Stephen Warren)

 .../brcm,bcm2835-armctrl-ic.txt                    | 25 ++++++++++++-
 drivers/irqchip/irq-bcm2835.c                      | 43 ++++++++++++++++++++--
 2 files changed, 64 insertions(+), 4 deletions(-)

diff --git a/Documentation/devicetree/bindings/interrupt-controller/brcm,bcm2835-armctrl-ic.txt b/Documentation/devicetree/bindings/interrupt-controller/brcm,bcm2835-armctrl-ic.txt
index 7da578d..2d6c8bb 100644
--- a/Documentation/devicetree/bindings/interrupt-controller/brcm,bcm2835-armctrl-ic.txt
+++ b/Documentation/devicetree/bindings/interrupt-controller/brcm,bcm2835-armctrl-ic.txt
@@ -5,9 +5,14 @@ The BCM2835 contains a custom top-level interrupt controller, which supports
 controller, or the HW block containing it, is referred to occasionally
 as "armctrl" in the SoC documentation, hence naming of this binding.
 
+The BCM2836 contains the same interrupt controller with the same
+interrupts, but the per-CPU interrupt controller is the root, and an
+interrupt there indicates that the ARMCTRL has an interrupt to handle.
+
 Required properties:
 
-- compatible : should be "brcm,bcm2835-armctrl-ic"
+- compatible : should be "brcm,bcm2835-armctrl-ic" or
+                 "brcm,bcm2836-armctrl-ic"
 - reg : Specifies base physical address and size of the registers.
 - interrupt-controller : Identifies the node as an interrupt controller
 - #interrupt-cells : Specifies the number of cells needed to encode an
@@ -20,6 +25,12 @@ Required properties:
   The 2nd cell contains the interrupt number within the bank. Valid values
   are 0..7 for bank 0, and 0..31 for bank 1.
 
+Additional required properties for brcm,bcm2836-armctrl-ic:
+- interrupt-parent : Specifies the parent interrupt controller when this
+  controller is the second level.
+- interrupts : Specifies the interrupt on the parent for this interrupt
+  controller to handle.
+
 The interrupt sources are as follows:
 
 Bank 0:
@@ -102,9 +113,21 @@ Bank 2:
 
 Example:
 
+/* BCM2835, first level */
 intc: interrupt-controller {
 	compatible = "brcm,bcm2835-armctrl-ic";
 	reg = <0x7e00b200 0x200>;
 	interrupt-controller;
 	#interrupt-cells = <2>;
 };
+
+/* BCM2836, second level */
+intc: interrupt-controller {
+	compatible = "brcm,bcm2836-armctrl-ic";
+	reg = <0x7e00b200 0x200>;
+	interrupt-controller;
+	#interrupt-cells = <2>;
+
+	interrupt-parent = <&local_intc>;
+	interrupts = <8>;
+};
diff --git a/drivers/irqchip/irq-bcm2835.c b/drivers/irqchip/irq-bcm2835.c
index 382450a..f968d3f 100644
--- a/drivers/irqchip/irq-bcm2835.c
+++ b/drivers/irqchip/irq-bcm2835.c
@@ -97,6 +97,7 @@ struct armctrl_ic {
 static struct armctrl_ic intc __read_mostly;
 static void __exception_irq_entry bcm2835_handle_irq(
 	struct pt_regs *regs);
+static void bcm2836_chained_handle_irq(unsigned int irq, struct irq_desc *desc);
 
 static void armctrl_mask_irq(struct irq_data *d)
 {
@@ -140,7 +141,8 @@ static const struct irq_domain_ops armctrl_ops = {
 };
 
 static int __init armctrl_of_init(struct device_node *node,
-	struct device_node *parent)
+				  struct device_node *parent,
+				  bool is_2836)
 {
 	void __iomem *base;
 	int irq, b, i;
@@ -169,10 +171,34 @@ static int __init armctrl_of_init(struct device_node *node,
 		}
 	}
 
-	set_handle_irq(bcm2835_handle_irq);
+	if (is_2836) {
+		int parent_irq = irq_of_parse_and_map(node, 0);
+
+		if (!parent_irq) {
+			panic("%s: unable to get parent interrupt.\n",
+			      node->full_name);
+		}
+		irq_set_chained_handler(parent_irq, bcm2836_chained_handle_irq);
+	} else {
+		set_handle_irq(bcm2835_handle_irq);
+	}
+
 	return 0;
 }
 
+static int __init bcm2835_armctrl_of_init(struct device_node *node,
+					  struct device_node *parent)
+{
+	return armctrl_of_init(node, parent, false);
+}
+
+static int __init bcm2836_armctrl_of_init(struct device_node *node,
+					  struct device_node *parent)
+{
+	return armctrl_of_init(node, parent, true);
+}
+
+
 /*
  * Handle each interrupt across the entire interrupt controller.  This reads the
  * status register before handling each interrupt, which is necessary given that
@@ -220,4 +246,15 @@ static void __exception_irq_entry bcm2835_handle_irq(
 		handle_IRQ(irq_linear_revmap(intc.domain, hwirq), regs);
 }
 
-IRQCHIP_DECLARE(bcm2835_armctrl_ic, "brcm,bcm2835-armctrl-ic", armctrl_of_init);
+static void bcm2836_chained_handle_irq(unsigned int irq, struct irq_desc *desc)
+{
+	u32 hwirq;
+
+	while ((hwirq = get_next_armctrl_hwirq()) != ~0)
+		generic_handle_irq(irq_linear_revmap(intc.domain, hwirq));
+}
+
+IRQCHIP_DECLARE(bcm2835_armctrl_ic, "brcm,bcm2835-armctrl-ic",
+		bcm2835_armctrl_of_init);
+IRQCHIP_DECLARE(bcm2836_armctrl_ic, "brcm,bcm2836-armctrl-ic",
+		bcm2836_armctrl_of_init);
-- 
2.1.4



From eric at anholt.net  Thu Aug  6 16:00:32 2015
From: eric at anholt.net (Eric Anholt)
Date: Thu,  6 Aug 2015 16:00:32 -0700
Subject: [PATCH v4 3/4] irqchip: Add documentation for the bcm2836 interrupt
 controller.
In-Reply-To: <1438902033-31477-1-git-send-email-eric@anholt.net>
References: <1438902033-31477-1-git-send-email-eric@anholt.net>
Message-ID: <1438902033-31477-4-git-send-email-eric@anholt.net>

This is a new per-cpu root interrupt controller on the Raspberry Pi 2,
which will chain to the bcm2835 interrupt controller for peripheral
interrupts.

Signed-off-by: Eric Anholt <eric at anholt.net>
Acked-by: Stephen Warren <swarren at wwwdotorg.org>
---
 .../interrupt-controller/brcm,bcm2836-l1-intc.txt  | 37 ++++++++++++++++++++++
 1 file changed, 37 insertions(+)
 create mode 100644 Documentation/devicetree/bindings/interrupt-controller/brcm,bcm2836-l1-intc.txt

diff --git a/Documentation/devicetree/bindings/interrupt-controller/brcm,bcm2836-l1-intc.txt b/Documentation/devicetree/bindings/interrupt-controller/brcm,bcm2836-l1-intc.txt
new file mode 100644
index 0000000..f320dcd
--- /dev/null
+++ b/Documentation/devicetree/bindings/interrupt-controller/brcm,bcm2836-l1-intc.txt
@@ -0,0 +1,37 @@
+BCM2836 per-CPU interrupt controller
+
+The BCM2836 has a per-cpu interrupt controller for the timer, PMU
+events, and SMP IPIs.  One of the CPUs may receive interrupts for the
+peripheral (GPU) events, which chain to the BCM2835-style interrupt
+controller.
+
+Required properties:
+
+- compatible:	 	Should be "brcm,bcm2836-l1-intc"
+- reg:			Specifies base physical address and size of the
+			  registers
+- interrupt-controller:	Identifies the node as an interrupt controller
+- #interrupt-cells:	Specifies the number of cells needed to encode an
+			  interrupt source. The value shall be 1
+
+Please refer to interrupts.txt in this directory for details of the common
+Interrupt Controllers bindings used by client devices.
+
+The interrupt sources are as follows:
+
+0: CNTPSIRQ
+1: CNTPNSIRQ
+2: CNTHPIRQ
+3: CNTVIRQ
+8: GPU_FAST
+9: PMU_FAST
+
+Example:
+
+local_intc: local_intc {
+	compatible = "brcm,bcm2836-l1-intc";
+	reg = <0x40000000 0x100>;
+	interrupt-controller;
+	#interrupt-cells = <1>;
+	interrupt-parent = <&local_intc>;
+};
-- 
2.1.4



From eric at anholt.net  Thu Aug  6 16:00:30 2015
From: eric at anholt.net (Eric Anholt)
Date: Thu,  6 Aug 2015 16:00:30 -0700
Subject: [PATCH v4 1/4] irqchip: bcm2835: Refactor handle_IRQ() calls out of
 MAKE_HWIRQ.
In-Reply-To: <1438902033-31477-1-git-send-email-eric@anholt.net>
References: <1438902033-31477-1-git-send-email-eric@anholt.net>
Message-ID: <1438902033-31477-2-git-send-email-eric@anholt.net>

For BCM2836, we want to chain into this IRQ chip from the root
controller, and for chaining we need to do something else instead of
handle_IRQ() once we have decoded the IRQ.

Note that this changes the behavior a little bit: Previously for a
non-shortcut IRQ, we'd loop reading and handling the second level IRQ
status until it was cleared before returning to the loop reading the
top level IRQ status (Note that the top level bit is just an OR of the
low level bits).  For the expected case of just one interrupt to be
handled, this was an extra register read, so we're down from 4 to 3
reads.

Signed-off-by: Eric Anholt <eric at anholt.net>
Acked-by: Stephen Warren <swarren at wwwdotorg.org>
---
 drivers/irqchip/irq-bcm2835.c | 57 ++++++++++++++++++++++---------------------
 1 file changed, 29 insertions(+), 28 deletions(-)

diff --git a/drivers/irqchip/irq-bcm2835.c b/drivers/irqchip/irq-bcm2835.c
index e68c3b6..382450a 100644
--- a/drivers/irqchip/irq-bcm2835.c
+++ b/drivers/irqchip/irq-bcm2835.c
@@ -179,44 +179,45 @@ static int __init armctrl_of_init(struct device_node *node,
  * handle_IRQ may briefly re-enable interrupts for soft IRQ handling.
  */
 
-static void armctrl_handle_bank(int bank, struct pt_regs *regs)
+static u32 armctrl_translate_bank(int bank)
 {
-	u32 stat, irq;
+	u32 stat = readl_relaxed(intc.pending[bank]);
 
-	while ((stat = readl_relaxed(intc.pending[bank]))) {
-		irq = MAKE_HWIRQ(bank, ffs(stat) - 1);
-		handle_IRQ(irq_linear_revmap(intc.domain, irq), regs);
-	}
+	return MAKE_HWIRQ(bank, ffs(stat) - 1);
+}
+
+static u32 armctrl_translate_shortcut(int bank, u32 stat)
+{
+	return MAKE_HWIRQ(bank, shortcuts[ffs(stat >> SHORTCUT_SHIFT) - 1]);
 }
 
-static void armctrl_handle_shortcut(int bank, struct pt_regs *regs,
-	u32 stat)
+static u32 get_next_armctrl_hwirq(void)
 {
-	u32 irq = MAKE_HWIRQ(bank, shortcuts[ffs(stat >> SHORTCUT_SHIFT) - 1]);
-	handle_IRQ(irq_linear_revmap(intc.domain, irq), regs);
+	u32 stat = readl_relaxed(intc.pending[0]) & BANK0_VALID_MASK;
+
+	if (stat == 0)
+		return ~0;
+	else if (stat & BANK0_HWIRQ_MASK)
+		return MAKE_HWIRQ(0, ffs(stat & BANK0_HWIRQ_MASK) - 1);
+	else if (stat & SHORTCUT1_MASK)
+		return armctrl_translate_shortcut(1, stat & SHORTCUT1_MASK);
+	else if (stat & SHORTCUT2_MASK)
+		return armctrl_translate_shortcut(2, stat & SHORTCUT2_MASK);
+	else if (stat & BANK1_HWIRQ)
+		return armctrl_translate_bank(1);
+	else if (stat & BANK2_HWIRQ)
+		return armctrl_translate_bank(2);
+	else
+		BUG();
 }
 
 static void __exception_irq_entry bcm2835_handle_irq(
 	struct pt_regs *regs)
 {
-	u32 stat, irq;
-
-	while ((stat = readl_relaxed(intc.pending[0]) & BANK0_VALID_MASK)) {
-		if (stat & BANK0_HWIRQ_MASK) {
-			irq = MAKE_HWIRQ(0, ffs(stat & BANK0_HWIRQ_MASK) - 1);
-			handle_IRQ(irq_linear_revmap(intc.domain, irq), regs);
-		} else if (stat & SHORTCUT1_MASK) {
-			armctrl_handle_shortcut(1, regs, stat & SHORTCUT1_MASK);
-		} else if (stat & SHORTCUT2_MASK) {
-			armctrl_handle_shortcut(2, regs, stat & SHORTCUT2_MASK);
-		} else if (stat & BANK1_HWIRQ) {
-			armctrl_handle_bank(1, regs);
-		} else if (stat & BANK2_HWIRQ) {
-			armctrl_handle_bank(2, regs);
-		} else {
-			BUG();
-		}
-	}
+	u32 hwirq;
+
+	while ((hwirq = get_next_armctrl_hwirq()) != ~0)
+		handle_IRQ(irq_linear_revmap(intc.domain, hwirq), regs);
 }
 
 IRQCHIP_DECLARE(bcm2835_armctrl_ic, "brcm,bcm2835-armctrl-ic", armctrl_of_init);
-- 
2.1.4



From eric at anholt.net  Thu Aug  6 16:00:33 2015
From: eric at anholt.net (Eric Anholt)
Date: Thu,  6 Aug 2015 16:00:33 -0700
Subject: [PATCH v4 4/4] irqchip: Add bcm2836 interrupt controller for
 Raspberry Pi 2.
In-Reply-To: <1438902033-31477-1-git-send-email-eric@anholt.net>
References: <1438902033-31477-1-git-send-email-eric@anholt.net>
Message-ID: <1438902033-31477-5-git-send-email-eric@anholt.net>

This interrupt controller is the new root interrupt controller with
the timer, PMU events, and IPIs, and the bcm2835's interrupt
controller is chained off of it to handle the peripherals.

I wrote the interrupt chip support, while Andrea Merello wrote the IPI
code.

Signed-off-by: Eric Anholt <eric at anholt.net>
Signed-off-by: Andrea Merello <andrea.merello at gmail.com>
Acked-by: Stephen Warren <swarren at wwwdotorg.org>
---

v2: Rename functions/globals to bcm2836_arm_local.  Treat per-cpu
    interrupts as per-cpu in mask/unmask.  Add comments about how
    registers work.
v3: Drop debug printfs from PMU interrupt masking.
v4: Use cpu notifiers to unmask IPIs only when Linux wants the CPU up.

 drivers/irqchip/Makefile      |   1 +
 drivers/irqchip/irq-bcm2836.c | 275 ++++++++++++++++++++++++++++++++++++++++++
 2 files changed, 276 insertions(+)
 create mode 100644 drivers/irqchip/irq-bcm2836.c

diff --git a/drivers/irqchip/Makefile b/drivers/irqchip/Makefile
index b8d4e96..9727681 100644
--- a/drivers/irqchip/Makefile
+++ b/drivers/irqchip/Makefile
@@ -1,6 +1,7 @@
 obj-$(CONFIG_IRQCHIP)			+= irqchip.o
 
 obj-$(CONFIG_ARCH_BCM2835)		+= irq-bcm2835.o
+obj-$(CONFIG_ARCH_BCM2835)		+= irq-bcm2836.o
 obj-$(CONFIG_ARCH_EXYNOS)		+= exynos-combiner.o
 obj-$(CONFIG_ARCH_HIP04)		+= irq-hip04.o
 obj-$(CONFIG_ARCH_MMP)			+= irq-mmp.o
diff --git a/drivers/irqchip/irq-bcm2836.c b/drivers/irqchip/irq-bcm2836.c
new file mode 100644
index 0000000..052bd83
--- /dev/null
+++ b/drivers/irqchip/irq-bcm2836.c
@@ -0,0 +1,275 @@
+/*
+ * Root interrupt controller for the BCM2836 (Raspberry Pi 2).
+ *
+ * Copyright 2015 Broadcom
+ *
+ * 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/cpu.h>
+#include <linux/of_address.h>
+#include <linux/of_irq.h>
+#include <linux/irqchip.h>
+#include <linux/irqdomain.h>
+#include <asm/exception.h>
+
+/*
+ * The low 2 bits identify the CPU that the GPU IRQ goes to, and the
+ * next 2 bits identify the CPU that the GPU FIQ goes to.
+ */
+#define LOCAL_GPU_ROUTING		0x00c
+/* When setting bits 0-3, enables PMU interrupts on that CPU. */
+#define LOCAL_PM_ROUTING_SET		0x010
+/* When setting bits 0-3, disables PMU interrupts on that CPU. */
+#define LOCAL_PM_ROUTING_CLR		0x014
+/*
+ * The low 4 bits of this are the CPU's timer IRQ enables, and the
+ * next 4 bits are the CPU's timer FIQ enables (which override the IRQ
+ * bits).
+ */
+#define LOCAL_TIMER_INT_CONTROL0	0x040
+/*
+ * The low 4 bits of this are the CPU's per-mailbox IRQ enables, and
+ * the next 4 bits are the CPU's per-mailbox FIQ enables (which
+ * override the IRQ bits).
+ */
+#define LOCAL_MAILBOX_INT_CONTROL0	0x050
+/*
+ * The CPU's interrupt status register.  Bits are defined by the the
+ * LOCAL_IRQ_* bits below.
+ */
+#define LOCAL_IRQ_PENDING0		0x060
+/* Same status bits as above, but for FIQ. */
+#define LOCAL_FIQ_PENDING0		0x070
+/*
+ * Mailbox0 write-to-set bits.  There are 16 mailboxes, 4 per CPU, and
+ * these bits are organized by mailbox number and then CPU number.  We
+ * use mailbox 0 for IPIs.  The mailbox's interrupt is raised while
+ * any bit is set.
+ */
+#define LOCAL_MAILBOX0_SET0		0x080
+/* Mailbox0 write-to-clear bits. */
+#define LOCAL_MAILBOX0_CLR0		0x0c0
+
+#define LOCAL_IRQ_CNTPSIRQ	0
+#define LOCAL_IRQ_CNTPNSIRQ	1
+#define LOCAL_IRQ_CNTHPIRQ	2
+#define LOCAL_IRQ_CNTVIRQ	3
+#define LOCAL_IRQ_MAILBOX0	4
+#define LOCAL_IRQ_MAILBOX1	5
+#define LOCAL_IRQ_MAILBOX2	6
+#define LOCAL_IRQ_MAILBOX3	7
+#define LOCAL_IRQ_GPU_FAST	8
+#define LOCAL_IRQ_PMU_FAST	9
+#define LAST_IRQ		LOCAL_IRQ_PMU_FAST
+
+struct bcm2836_arm_irqchip_intc {
+	struct irq_domain *domain;
+	void __iomem *base;
+};
+
+static struct bcm2836_arm_irqchip_intc intc  __read_mostly;
+
+static void bcm2836_arm_irqchip_mask_per_cpu_irq(unsigned int reg_offset,
+						 unsigned int bit,
+						 int cpu)
+{
+	void __iomem *reg = intc.base + reg_offset + 4 * cpu;
+
+	writel(readl(reg) & ~BIT(bit), reg);
+}
+
+static void bcm2836_arm_irqchip_unmask_per_cpu_irq(unsigned int reg_offset,
+						   unsigned int bit,
+						 int cpu)
+{
+	void __iomem *reg = intc.base + reg_offset + 4 * cpu;
+
+	writel(readl(reg) | BIT(bit), reg);
+}
+
+static void bcm2836_arm_irqchip_mask_timer_irq(struct irq_data *d)
+{
+	bcm2836_arm_irqchip_mask_per_cpu_irq(LOCAL_TIMER_INT_CONTROL0,
+					     d->hwirq - LOCAL_IRQ_CNTPSIRQ,
+					     smp_processor_id());
+}
+
+static void bcm2836_arm_irqchip_unmask_timer_irq(struct irq_data *d)
+{
+	bcm2836_arm_irqchip_unmask_per_cpu_irq(LOCAL_TIMER_INT_CONTROL0,
+					       d->hwirq - LOCAL_IRQ_CNTPSIRQ,
+					       smp_processor_id());
+}
+
+static struct irq_chip bcm2836_arm_irqchip_timer = {
+	.name = "bcm2836-timer",
+	.irq_mask = bcm2836_arm_irqchip_mask_timer_irq,
+	.irq_unmask = bcm2836_arm_irqchip_unmask_timer_irq
+};
+
+static void bcm2836_arm_irqchip_mask_pmu_irq(struct irq_data *d)
+{
+	writel(1 << smp_processor_id(), intc.base + LOCAL_PM_ROUTING_CLR);
+}
+
+static void bcm2836_arm_irqchip_unmask_pmu_irq(struct irq_data *d)
+{
+	writel(1 << smp_processor_id(), intc.base + LOCAL_PM_ROUTING_SET);
+}
+
+static struct irq_chip bcm2836_arm_irqchip_pmu = {
+	.name = "bcm2836-pmu",
+	.irq_mask = bcm2836_arm_irqchip_mask_pmu_irq,
+	.irq_unmask = bcm2836_arm_irqchip_unmask_pmu_irq
+};
+
+static void bcm2836_arm_irqchip_mask_gpu_irq(struct irq_data *d)
+{
+}
+
+static void bcm2836_arm_irqchip_unmask_gpu_irq(struct irq_data *d)
+{
+}
+
+static struct irq_chip bcm2836_arm_irqchip_gpu = {
+	.name = "bcm2836-gpu",
+	.irq_mask = bcm2836_arm_irqchip_mask_gpu_irq,
+	.irq_unmask = bcm2836_arm_irqchip_unmask_gpu_irq
+};
+
+static void bcm2836_arm_irqchip_register_irq(int hwirq, struct irq_chip *chip)
+{
+	int irq = irq_create_mapping(intc.domain, hwirq);
+
+	irq_set_percpu_devid(irq);
+	irq_set_chip_and_handler(irq, chip, handle_percpu_devid_irq);
+	irq_set_status_flags(irq, IRQ_NOAUTOEN);
+}
+
+static void __exception_irq_entry bcm2836_arm_irqchip_handle_irq(
+	struct pt_regs *regs)
+{
+	int cpu = smp_processor_id();
+	u32 stat;
+
+	stat = readl_relaxed(intc.base + LOCAL_IRQ_PENDING0 + 4 * cpu);
+	if (stat & 0x10) {
+#ifdef CONFIG_SMP
+		void __iomem *mailbox0 = (intc.base +
+					  LOCAL_MAILBOX0_CLR0 + 16 * cpu);
+		u32 mbox_val = readl(mailbox0);
+		u32 ipi = ffs(mbox_val) - 1;
+
+		writel(1 << ipi, mailbox0);
+		handle_IPI(ipi, regs);
+#endif
+	} else {
+		u32 hwirq = ffs(stat) - 1;
+
+		handle_IRQ(irq_linear_revmap(intc.domain, hwirq), regs);
+	}
+}
+
+#ifdef CONFIG_SMP
+static void bcm2836_arm_irqchip_send_ipi(const struct cpumask *mask,
+					 unsigned int ipi)
+{
+	int cpu;
+	void __iomem *mailbox0_base = intc.base + LOCAL_MAILBOX0_SET0;
+
+	/*
+	 * Ensure that stores to normal memory are visible to the
+	 * other CPUs before issuing the IPI.
+	 */
+	dsb();
+
+	for_each_cpu(cpu, mask)	{
+		writel(1 << ipi, mailbox0_base + 16 * cpu);
+	}
+}
+
+/* Unmasks the IPI on the CPU when it's online. */
+static int bcm2836_arm_irqchip_cpu_notify(struct notifier_block *nfb,
+					  unsigned long action, void *hcpu)
+{
+	unsigned int cpu = (unsigned long)hcpu;
+	unsigned int int_reg = LOCAL_MAILBOX_INT_CONTROL0;
+	unsigned int mailbox = 0;
+
+	if (action == CPU_STARTING || action == CPU_STARTING_FROZEN)
+		bcm2836_arm_irqchip_unmask_per_cpu_irq(int_reg, mailbox, cpu);
+	else if (action == CPU_DYING)
+		bcm2836_arm_irqchip_mask_per_cpu_irq(int_reg, mailbox, cpu);
+
+	return NOTIFY_OK;
+}
+
+static struct notifier_block bcm2836_arm_irqchip_cpu_notifier = {
+	.notifier_call = bcm2836_arm_irqchip_cpu_notify,
+	.priority = 100,
+};
+#endif
+
+static const struct irq_domain_ops bcm2836_arm_irqchip_intc_ops = {
+	.xlate = irq_domain_xlate_onecell
+};
+
+static void
+bcm2836_arm_irqchip_smp_init(void)
+{
+#ifdef CONFIG_SMP
+	/* Unmask IPIs to the boot CPU. */
+	bcm2836_arm_irqchip_cpu_notify(&bcm2836_arm_irqchip_cpu_notifier,
+				       CPU_STARTING,
+				       (void *)smp_processor_id());
+	register_cpu_notifier(&bcm2836_arm_irqchip_cpu_notifier);
+
+	set_smp_cross_call(bcm2836_arm_irqchip_send_ipi);
+#endif
+}
+
+static int __init bcm2836_arm_irqchip_l1_intc_of_init(struct device_node *node,
+						      struct device_node *parent)
+{
+	intc.base = of_iomap(node, 0);
+	if (!intc.base) {
+		panic("%s: unable to map local interrupt registers\n",
+			node->full_name);
+	}
+
+	intc.domain = irq_domain_add_linear(node, LAST_IRQ + 1,
+					    &bcm2836_arm_irqchip_intc_ops,
+					    NULL);
+	if (!intc.domain)
+		panic("%s: unable to create IRQ domain\n", node->full_name);
+
+	bcm2836_arm_irqchip_register_irq(LOCAL_IRQ_CNTPSIRQ,
+					 &bcm2836_arm_irqchip_timer);
+	bcm2836_arm_irqchip_register_irq(LOCAL_IRQ_CNTPNSIRQ,
+					 &bcm2836_arm_irqchip_timer);
+	bcm2836_arm_irqchip_register_irq(LOCAL_IRQ_CNTHPIRQ,
+					 &bcm2836_arm_irqchip_timer);
+	bcm2836_arm_irqchip_register_irq(LOCAL_IRQ_CNTVIRQ,
+					 &bcm2836_arm_irqchip_timer);
+	bcm2836_arm_irqchip_register_irq(LOCAL_IRQ_GPU_FAST,
+					 &bcm2836_arm_irqchip_gpu);
+	bcm2836_arm_irqchip_register_irq(LOCAL_IRQ_PMU_FAST,
+					 &bcm2836_arm_irqchip_pmu);
+
+	bcm2836_arm_irqchip_smp_init();
+
+	set_handle_irq(bcm2836_arm_irqchip_handle_irq);
+	return 0;
+}
+
+IRQCHIP_DECLARE(bcm2836_arm_irqchip_l1_intc, "brcm,bcm2836-l1-intc",
+		bcm2836_arm_irqchip_l1_intc_of_init);
-- 
2.1.4



From phil at ctekproducts.com  Thu Aug  6 16:23:24 2015
From: phil at ctekproducts.com (Phil Sutter)
Date: Thu, 6 Aug 2015 16:23:24 -0700
Subject: Cadence macb on SAM9G25 running 3.16.1
Message-ID: <00fe01d0d09e$e4ac9470$ae05bd50$@ctekproducts.com>

Hi,

I am trying to understand if any patches might be necessary for best
performance of macb Ethernet support on 3.16.1 running on a SAM9G25.  My
reason for asking is that I am seeing some receive framing errors and
dropped packets under heavy file transfer load.  

Thanks,
Phil





From kgene at kernel.org  Thu Aug  6 16:53:18 2015
From: kgene at kernel.org (Kukjin Kim)
Date: Fri, 07 Aug 2015 08:53:18 +0900
Subject: [PATCH v4 0/6] cpufreq: use generic cpufreq drivers for Exynos4x12
 platform
In-Reply-To: <1438868514-8814-1-git-send-email-b.zolnierkie@samsung.com>
References: <1438868514-8814-1-git-send-email-b.zolnierkie@samsung.com>
Message-ID: <015301d0d0a3$1396c900$3ac45b00$@kernel.org>

Bartlomiej Zolnierkiewicz wrote:
> 
> Hi,
> 
Hi Bart,

> This patch series removes the use of Exynos4x12 specific support
> from cpufreq-exynos driver and enables the use of cpufreq-dt driver
> for this platform.
> 
Thanks for this series.

> This patch series has been tested on Exynos4412 based Odroid-U3 and
> Trats2 boards.
> 
Sounds good.

> Depends on:
> - next-20150806 branch of linux-next kernel tree
> - "[PATCH V3 00/16] OPP: Add code to support operating-points-v2 bindings"
>   (http://www.spinics.net/lists/arm-kernel/msg435408.html)
> 
BTW, hmm...how can we see this series in v4.3?...to be honest, I don't think it
can be done in v4.3 because of dependencies with PM / OPP series and previous
exynos CPU OPP series in each cross trees...maybe that's why you created based
on linux-next...any idea?

Thanks,
Kukjin

> Changes since v3
> (http://thread.gmane.org/gmane.linux.power-management.general/63464):
> - rebased on top of next-20150806 branch of linux-next kernel tree
> - made ARCH_EXYNOS config option select thermal support
> - made scaling_boost_freqs sysfs attribute available only when boost
>   support is enabled
> - added Acked-by tag from Viresh to patches #3, #4 and #5
> - added Tested-by tag from Tobias to patches #2-5
> - added Reviewed-by tag from Krzysztof to patch #4
> 
> Changes since v2
> (http://thread.gmane.org/gmane.linux.kernel.samsung-soc/46653):
> - rebased on top of next-20150730 branch of linux-next kernel tree
> - ported over V3 of opp-v2 bindings support patch series
> - put cpu0 nodes in alphabetical order in dts files
> - added Reviewed-by tags from Javier and Krzysztof
> - added Acked-by tag from Sylwester
> 
> Changes since v1
> (http://thread.gmane.org/gmane.linux.kernel.samsung-soc/44361):
> - rebased on top of next-20150629 branch of linux-next kernel tree
> - rebased on top of Exynos5250 cpufreq-dt support patch series
> - fixed if-statement in exynos4_clk_init() (noticed by Tobias Jakobi)
> - ported over opp-v2 bindings (requested by Viresh Kumar)
> 
> Best regards,
> --
> Bartlomiej Zolnierkiewicz
> Samsung R&D Institute Poland
> Samsung Electronics
> 
> 
> Bartlomiej Zolnierkiewicz (6):
>   cpufreq: make scaling_boost_freqs sysfs attr available when boost is
>     enabled
>   clk: samsung: exynos4x12: add cpu clock configuration data and
>     instantiate cpu clock
>   ARM: dts: Exynos4x12: add CPU OPP and regulator supply property
>   ARM: Exynos: switch to using generic cpufreq driver for Exynos4x12
>   cpufreq: exynos: remove Exynos4x12 specific cpufreq driver support
>   cpufreq: remove no longer needed CPU_FREQ_BOOST_SW config option
> 
>  arch/arm/boot/dts/exynos4212.dtsi               |  81 ++++++++
>  arch/arm/boot/dts/exynos4412-odroid-common.dtsi |   4 +
>  arch/arm/boot/dts/exynos4412-origen.dts         |   4 +
>  arch/arm/boot/dts/exynos4412-trats2.dts         |   4 +
>  arch/arm/boot/dts/exynos4412.dtsi               |  83 +++++++++
>  arch/arm/mach-exynos/Kconfig                    |   2 +
>  arch/arm/mach-exynos/exynos.c                   |   2 +
>  drivers/clk/samsung/clk-exynos4.c               |  50 +++++
>  drivers/cpufreq/Kconfig                         |   4 -
>  drivers/cpufreq/Kconfig.arm                     |  38 ----
>  drivers/cpufreq/Makefile                        |   2 -
>  drivers/cpufreq/cpufreq-dt.c                    |   3 +
>  drivers/cpufreq/exynos-cpufreq.c                | 236 ------------------------
>  drivers/cpufreq/exynos-cpufreq.h                |  72 --------
>  drivers/cpufreq/exynos4x12-cpufreq.c            | 236 ------------------------
>  drivers/cpufreq/freq_table.c                    |  10 +-
>  include/linux/cpufreq.h                         |   1 +
>  17 files changed, 241 insertions(+), 591 deletions(-)
>  delete mode 100644 drivers/cpufreq/exynos-cpufreq.c
>  delete mode 100644 drivers/cpufreq/exynos-cpufreq.h
>  delete mode 100644 drivers/cpufreq/exynos4x12-cpufreq.c
> 
> --
> 1.9.1



From msalter at redhat.com  Thu Aug  6 14:41:37 2015
From: msalter at redhat.com (Mark Salter)
Date: Thu,  6 Aug 2015 17:41:37 -0400
Subject: [PATCH V2 1/3] mm: add utility for early copy from unmapped ram
In-Reply-To: <1438897299-2266-1-git-send-email-msalter@redhat.com>
References: <1438897299-2266-1-git-send-email-msalter@redhat.com>
Message-ID: <1438897299-2266-2-git-send-email-msalter@redhat.com>

In some early boot circumstances, it may be necessary to copy
from RAM outside the kernel linear mapping to mapped RAM. The
need to relocate an initrd is one example in the x86 code. This
patch creates a helper function based on current x86 code.

Signed-off-by: Mark Salter <msalter at redhat.com>
---
 include/asm-generic/early_ioremap.h |  6 ++++++
 mm/early_ioremap.c                  | 22 ++++++++++++++++++++++
 2 files changed, 28 insertions(+)

diff --git a/include/asm-generic/early_ioremap.h b/include/asm-generic/early_ioremap.h
index a5de55c..e539f27 100644
--- a/include/asm-generic/early_ioremap.h
+++ b/include/asm-generic/early_ioremap.h
@@ -33,6 +33,12 @@ extern void early_ioremap_setup(void);
  */
 extern void early_ioremap_reset(void);
 
+/*
+ * Early copy from unmapped memory to kernel mapped memory.
+ */
+extern void copy_from_early_mem(void *dest, phys_addr_t src,
+				unsigned long size);
+
 #else
 static inline void early_ioremap_init(void) { }
 static inline void early_ioremap_setup(void) { }
diff --git a/mm/early_ioremap.c b/mm/early_ioremap.c
index e10ccd2..acba804 100644
--- a/mm/early_ioremap.c
+++ b/mm/early_ioremap.c
@@ -217,6 +217,28 @@ early_memremap(resource_size_t phys_addr, unsigned long size)
 	return (__force void *)__early_ioremap(phys_addr, size,
 					       FIXMAP_PAGE_NORMAL);
 }
+
+#define MAX_MAP_CHUNK	(NR_FIX_BTMAPS << PAGE_SHIFT)
+
+void __init copy_from_early_mem(void *dest, phys_addr_t src, unsigned long size)
+{
+	unsigned long slop, clen;
+	char *p;
+
+	while (size) {
+		slop = src & ~PAGE_MASK;
+		clen = size;
+		if (clen > MAX_MAP_CHUNK - slop)
+			clen = MAX_MAP_CHUNK - slop;
+		p = early_memremap(src & PAGE_MASK, clen + slop);
+		memcpy(dest, p + slop, clen);
+		early_iounmap(p, clen + slop);
+		dest += clen;
+		src += clen;
+		size -= clen;
+	}
+}
+
 #else /* CONFIG_MMU */
 
 void __init __iomem *
-- 
2.4.3



From wenyou.yang at atmel.com  Thu Aug  6 17:04:55 2015
From: wenyou.yang at atmel.com (Wenyou Yang)
Date: Fri, 7 Aug 2015 08:04:55 +0800
Subject: [PATCH v6 1/2] drivers: watchdog: add a driver to support SAMA5D4
 watchdog timer
In-Reply-To: <1438856146-2459-1-git-send-email-wenyou.yang@atmel.com>
References: <1438856146-2459-1-git-send-email-wenyou.yang@atmel.com>
Message-ID: <1438905895-18776-1-git-send-email-wenyou.yang@atmel.com>

>From SAMA5D4, the watchdog timer is upgrated with a new feature,
which is describled as in the datasheet, "WDT_MR can be written
until a LOCKMR command is issued in WDT_CR".
That is to say, as long as the bootstrap and u-boot don't issue
a LOCKMR command, WDT_MR can be written more than once in the driver.

So the SAMA5D4 watchdog driver's implementation is different from
the at91sam9260 watchdog driver implemented in file at91sam9_wdt.c.
The user application open the device file to enable the watchdog timer
hardware, and close to disable it, and set the watchdog timer timeout
by seting WDV and WDD fields of WDT_MR register, and ping the watchdog
by issuing WDRSTT command to WDT_CR register with hard-coded key.

Signed-off-by: Wenyou Yang <wenyou.yang at atmel.com>
---
 drivers/watchdog/Kconfig        |    9 ++
 drivers/watchdog/Makefile       |    1 +
 drivers/watchdog/at91sam9_wdt.h |    2 +
 drivers/watchdog/sama5d4_wdt.c  |  280 +++++++++++++++++++++++++++++++++++++++
 4 files changed, 292 insertions(+)
 create mode 100644 drivers/watchdog/sama5d4_wdt.c

diff --git a/drivers/watchdog/Kconfig b/drivers/watchdog/Kconfig
index e5e7c55..47ad39a 100644
--- a/drivers/watchdog/Kconfig
+++ b/drivers/watchdog/Kconfig
@@ -167,6 +167,15 @@ config AT91SAM9X_WATCHDOG
 	  Watchdog timer embedded into AT91SAM9X and AT91CAP9 chips. This will
 	  reboot your system when the timeout is reached.
 
+config SAMA5D4_WATCHDOG
+	tristate "Atmel SAMA5D4 Watchdog Timer"
+	depends on ARCH_AT91
+	select WATCHDOG_CORE
+	help
+	  Atmel SAMA5D4 watchdog timer is embedded into SAMA5D4 chips.
+	  Its Watchdog Timer Mode Register can be written more than once.
+	  This will reboot your system when the timeout is reached.
+
 config CADENCE_WATCHDOG
 	tristate "Cadence Watchdog Timer"
 	select WATCHDOG_CORE
diff --git a/drivers/watchdog/Makefile b/drivers/watchdog/Makefile
index 5c19294..f24b820 100644
--- a/drivers/watchdog/Makefile
+++ b/drivers/watchdog/Makefile
@@ -41,6 +41,7 @@ obj-$(CONFIG_IXP4XX_WATCHDOG) += ixp4xx_wdt.o
 obj-$(CONFIG_KS8695_WATCHDOG) += ks8695_wdt.o
 obj-$(CONFIG_S3C2410_WATCHDOG) += s3c2410_wdt.o
 obj-$(CONFIG_SA1100_WATCHDOG) += sa1100_wdt.o
+obj-$(CONFIG_SAMA5D4_WATCHDOG) += sama5d4_wdt.o
 obj-$(CONFIG_DW_WATCHDOG) += dw_wdt.o
 obj-$(CONFIG_EP93XX_WATCHDOG) += ep93xx_wdt.o
 obj-$(CONFIG_PNX4008_WATCHDOG) += pnx4008_wdt.o
diff --git a/drivers/watchdog/at91sam9_wdt.h b/drivers/watchdog/at91sam9_wdt.h
index c6fbb2e6..b79a83b 100644
--- a/drivers/watchdog/at91sam9_wdt.h
+++ b/drivers/watchdog/at91sam9_wdt.h
@@ -22,11 +22,13 @@
 
 #define AT91_WDT_MR		0x04			/* Watchdog Mode Register */
 #define		AT91_WDT_WDV		(0xfff << 0)		/* Counter Value */
+#define			AT91_WDT_SET_WDV(x)	((x) & AT91_WDT_WDV)
 #define		AT91_WDT_WDFIEN		(1     << 12)		/* Fault Interrupt Enable */
 #define		AT91_WDT_WDRSTEN	(1     << 13)		/* Reset Processor */
 #define		AT91_WDT_WDRPROC	(1     << 14)		/* Timer Restart */
 #define		AT91_WDT_WDDIS		(1     << 15)		/* Watchdog Disable */
 #define		AT91_WDT_WDD		(0xfff << 16)		/* Delta Value */
+#define			AT91_WDT_SET_WDD(x)	(((x) << 16) & AT91_WDT_WDD)
 #define		AT91_WDT_WDDBGHLT	(1     << 28)		/* Debug Halt */
 #define		AT91_WDT_WDIDLEHLT	(1     << 29)		/* Idle Halt */
 
diff --git a/drivers/watchdog/sama5d4_wdt.c b/drivers/watchdog/sama5d4_wdt.c
new file mode 100644
index 0000000..a49634c
--- /dev/null
+++ b/drivers/watchdog/sama5d4_wdt.c
@@ -0,0 +1,280 @@
+/*
+ * Driver for Atmel SAMA5D4 Watchdog Timer
+ *
+ * Copyright (C) 2015 Atmel Corporation
+ *
+ * Licensed under GPLv2.
+ */
+
+#include <linux/interrupt.h>
+#include <linux/io.h>
+#include <linux/kernel.h>
+#include <linux/module.h>
+#include <linux/of.h>
+#include <linux/of_irq.h>
+#include <linux/platform_device.h>
+#include <linux/reboot.h>
+#include <linux/watchdog.h>
+
+#include "at91sam9_wdt.h"
+
+/* minimum and maximum watchdog timeout, in seconds */
+#define MIN_WDT_TIMEOUT		1
+#define MAX_WDT_TIMEOUT		16
+#define WDT_DEFAULT_TIMEOUT	MAX_WDT_TIMEOUT
+
+#define WDT_SEC2TICKS(s)	((s) ? (((s) << 8) - 1) : 0)
+
+struct sama5d4_wdt {
+	struct watchdog_device	wdd;
+	void __iomem		*reg_base;
+	u32	config;
+};
+
+static int wdt_timeout = WDT_DEFAULT_TIMEOUT;
+static bool nowayout = WATCHDOG_NOWAYOUT;
+
+module_param(wdt_timeout, int, 0);
+MODULE_PARM_DESC(wdt_timeout,
+	"Watchdog timeout in seconds. (default = "
+	__MODULE_STRING(WDT_DEFAULT_TIMEOUT) ")");
+
+module_param(nowayout, bool, 0);
+MODULE_PARM_DESC(nowayout,
+	"Watchdog cannot be stopped once started (default="
+	__MODULE_STRING(WATCHDOG_NOWAYOUT) ")");
+
+#define wdt_read(wdt, field) \
+	readl_relaxed((wdt)->reg_base + (field))
+
+#define wdt_write(wtd, field, val) \
+	writel_relaxed((val), (wdt)->reg_base + (field))
+
+static int sama5d4_wdt_start(struct watchdog_device *wdd)
+{
+	struct sama5d4_wdt *wdt = watchdog_get_drvdata(wdd);
+	u32 reg;
+
+	reg = wdt_read(wdt, AT91_WDT_MR);
+	reg &= ~AT91_WDT_WDDIS;
+	wdt_write(wdt, AT91_WDT_MR, reg);
+
+	return 0;
+}
+
+static int sama5d4_wdt_stop(struct watchdog_device *wdd)
+{
+	struct sama5d4_wdt *wdt = watchdog_get_drvdata(wdd);
+	u32 reg;
+
+	reg = wdt_read(wdt, AT91_WDT_MR);
+	reg |= AT91_WDT_WDDIS;
+	wdt_write(wdt, AT91_WDT_MR, reg);
+
+	return 0;
+}
+
+static int sama5d4_wdt_ping(struct watchdog_device *wdd)
+{
+	struct sama5d4_wdt *wdt = watchdog_get_drvdata(wdd);
+
+	wdt_write(wdt, AT91_WDT_CR, AT91_WDT_KEY | AT91_WDT_WDRSTT);
+
+	return 0;
+}
+
+static int sama5d4_wdt_set_timeout(struct watchdog_device *wdd,
+				 unsigned int timeout)
+{
+	struct sama5d4_wdt *wdt = watchdog_get_drvdata(wdd);
+	u32 value = WDT_SEC2TICKS(timeout);
+	u32 reg;
+
+	reg = wdt_read(wdt, AT91_WDT_MR);
+	reg &= ~AT91_WDT_WDV;
+	reg &= ~AT91_WDT_WDD;
+	reg |= AT91_WDT_SET_WDV(value);
+	reg |= AT91_WDT_SET_WDD(value);
+	wdt_write(wdt, AT91_WDT_MR, reg);
+
+	wdd->timeout = timeout;
+
+	return 0;
+}
+
+static const struct watchdog_info sama5d4_wdt_info = {
+	.options = WDIOF_SETTIMEOUT | WDIOF_MAGICCLOSE | WDIOF_KEEPALIVEPING,
+	.identity = "Atmel SAMA5D4 Watchdog",
+};
+
+static struct watchdog_ops sama5d4_wdt_ops = {
+	.owner = THIS_MODULE,
+	.start = sama5d4_wdt_start,
+	.stop = sama5d4_wdt_stop,
+	.ping = sama5d4_wdt_ping,
+	.set_timeout = sama5d4_wdt_set_timeout,
+};
+
+static irqreturn_t sama5d4_wdt_irq_handler(int irq, void *dev_id)
+{
+	struct sama5d4_wdt *wdt = platform_get_drvdata(dev_id);
+
+	if (wdt_read(wdt, AT91_WDT_SR)) {
+		pr_crit("Atmel Watchdog Software Reset\n");
+		emergency_restart();
+		pr_crit("Reboot didn't succeed\n");
+	}
+
+	return IRQ_HANDLED;
+}
+
+static int of_sama5d4_wdt_init(struct device_node *np, struct sama5d4_wdt *wdt)
+{
+	const char *tmp;
+
+	wdt->config = AT91_WDT_WDDIS;
+
+	if (!of_property_read_string(np, "atmel,watchdog-type", &tmp) &&
+	    !strcmp(tmp, "software"))
+		wdt->config |= AT91_WDT_WDFIEN;
+	else
+		wdt->config |= AT91_WDT_WDRSTEN;
+
+	if (of_property_read_bool(np, "atmel,idle-halt"))
+		wdt->config |= AT91_WDT_WDIDLEHLT;
+
+	if (of_property_read_bool(np, "atmel,dbg-halt"))
+		wdt->config |= AT91_WDT_WDDBGHLT;
+
+	return 0;
+}
+
+static int sama5d4_wdt_init(struct sama5d4_wdt *wdt)
+{
+	struct watchdog_device *wdd = &wdt->wdd;
+	u32 value = WDT_SEC2TICKS(wdd->timeout);
+	u32 reg;
+
+	/*
+	 * Because the fields WDV and WDD must not be modified when the WDDIS
+	 * bit is set, so clear the WDDIS bit before writing the WDT_MR.
+	 */
+	reg = wdt_read(wdt, AT91_WDT_MR);
+	reg &= ~AT91_WDT_WDDIS;
+	wdt_write(wdt, AT91_WDT_MR, reg);
+
+	reg = wdt->config;
+	reg |= AT91_WDT_SET_WDD(value);
+	reg |= AT91_WDT_SET_WDV(value);
+
+	wdt_write(wdt, AT91_WDT_MR, reg);
+
+	return 0;
+}
+
+static int sama5d4_wdt_probe(struct platform_device *pdev)
+{
+	struct watchdog_device *wdd;
+	struct sama5d4_wdt *wdt;
+	struct resource *res;
+	void __iomem *regs;
+	u32 irq = 0;
+	int ret;
+
+	wdt = devm_kzalloc(&pdev->dev, sizeof(*wdt), GFP_KERNEL);
+	if (!wdt)
+		return -ENOMEM;
+
+	wdd = &wdt->wdd;
+	wdd->timeout = wdt_timeout;
+	wdd->info = &sama5d4_wdt_info;
+	wdd->ops = &sama5d4_wdt_ops;
+	wdd->min_timeout = MIN_WDT_TIMEOUT;
+	wdd->max_timeout = MAX_WDT_TIMEOUT;
+
+	watchdog_set_drvdata(wdd, wdt);
+
+	res = platform_get_resource(pdev, IORESOURCE_MEM, 0);
+	regs = devm_ioremap_resource(&pdev->dev, res);
+	if (IS_ERR(regs))
+		return PTR_ERR(regs);
+
+	wdt->reg_base = regs;
+
+	if (pdev->dev.of_node) {
+		irq = irq_of_parse_and_map(pdev->dev.of_node, 0);
+		if (!irq)
+			dev_warn(&pdev->dev, "failed to get IRQ from DT\n");
+
+		ret = of_sama5d4_wdt_init(pdev->dev.of_node, wdt);
+		if (ret)
+			return ret;
+	}
+
+	if ((wdt->config & AT91_WDT_WDFIEN) && irq) {
+		ret = devm_request_irq(&pdev->dev, irq, sama5d4_wdt_irq_handler,
+				       IRQF_SHARED | IRQF_IRQPOLL |
+				       IRQF_NO_SUSPEND, pdev->name, pdev);
+		if (ret) {
+			dev_err(&pdev->dev,
+				"cannot register interrupt handler\n");
+			return ret;
+		}
+	}
+
+	ret = watchdog_init_timeout(wdd, wdt_timeout, &pdev->dev);
+	if (ret) {
+		dev_err(&pdev->dev, "unable to set timeout value\n");
+		return ret;
+	}
+
+	ret = sama5d4_wdt_init(wdt);
+	if (ret)
+		return ret;
+
+	watchdog_set_nowayout(wdd, nowayout);
+
+	ret = watchdog_register_device(wdd);
+	if (ret) {
+		dev_err(&pdev->dev, "failed to register watchdog device\n");
+		return ret;
+	}
+
+	platform_set_drvdata(pdev, wdt);
+
+	dev_info(&pdev->dev, "initialized (timeout = %d sec, nowayout = %d)\n",
+		 wdt_timeout, nowayout);
+
+	return 0;
+}
+
+static int sama5d4_wdt_remove(struct platform_device *pdev)
+{
+	struct sama5d4_wdt *wdt = platform_get_drvdata(pdev);
+
+	sama5d4_wdt_stop(&wdt->wdd);
+
+	watchdog_unregister_device(&wdt->wdd);
+
+	return 0;
+}
+
+static const struct of_device_id sama5d4_wdt_of_match[] = {
+	{ .compatible = "atmel,sama5d4-wdt", },
+	{ }
+};
+MODULE_DEVICE_TABLE(of, sama5d4_wdt_of_match);
+
+static struct platform_driver sama5d4_wdt_driver = {
+	.probe		= sama5d4_wdt_probe,
+	.remove		= sama5d4_wdt_remove,
+	.driver		= {
+		.name	= "sama5d4_wdt",
+		.of_match_table = sama5d4_wdt_of_match,
+	}
+};
+module_platform_driver(sama5d4_wdt_driver);
+
+MODULE_AUTHOR("Atmel Corporation");
+MODULE_DESCRIPTION("Atmel SAMA5D4 Watchdog Timer driver");
+MODULE_LICENSE("GPL v2");
-- 
1.7.9.5



From wenyou.yang at atmel.com  Thu Aug  6 17:06:03 2015
From: wenyou.yang at atmel.com (Wenyou Yang)
Date: Fri, 7 Aug 2015 08:06:03 +0800
Subject: [PATCH v6 2/2] Documentation: dt: binding: atmel-sama5d4-wdt: for
 SAMA5D4 watchdog driver
In-Reply-To: <1438856146-2459-1-git-send-email-wenyou.yang@atmel.com>
References: <1438856146-2459-1-git-send-email-wenyou.yang@atmel.com>
Message-ID: <1438905963-21673-1-git-send-email-wenyou.yang@atmel.com>

The compatible "atmel,sama5d4-wdt" supports the SAMA5D4 watchdog driver
and the watchdog's WDT_MR register can be written more than once.

Signed-off-by: Wenyou Yang <wenyou.yang at atmel.com>
---
 .../bindings/watchdog/atmel-sama5d4-wdt.txt        |   35 ++++++++++++++++++++
 1 file changed, 35 insertions(+)
 create mode 100644 Documentation/devicetree/bindings/watchdog/atmel-sama5d4-wdt.txt

diff --git a/Documentation/devicetree/bindings/watchdog/atmel-sama5d4-wdt.txt b/Documentation/devicetree/bindings/watchdog/atmel-sama5d4-wdt.txt
new file mode 100644
index 0000000..f7cc7c0
--- /dev/null
+++ b/Documentation/devicetree/bindings/watchdog/atmel-sama5d4-wdt.txt
@@ -0,0 +1,35 @@
+* Atmel SAMA5D4 Watchdog Timer (WDT) Controller
+
+Required properties:
+- compatible: "atmel,sama5d4-wdt"
+- reg: base physical address and length of memory mapped region.
+
+Optional properties:
+- timeout-sec: watchdog timeout value (in seconds).
+- interrupts: interrupt number to the CPU.
+- atmel,watchdog-type: should be "hardware" or "software".
+	"hardware": enable watchdog fault reset. A watchdog fault triggers
+		    watchdog reset.
+	"software": enable watchdog fault interrupt. A watchdog fault asserts
+		    watchdog interrupt.
+- atmel,idle-halt: present if you want to stop the watchdog when the CPU is
+		   in idle state.
+	CAUTION: This property should be used with care, it actually makes the
+	watchdog not counting when the CPU is in idle state, therefore the
+	watchdog reset time depends on mean CPU usage and will not reset at all
+	if the CPU stop working while it is in idle state, which is probably
+	not what you want.
+- atmel,dbg-halt: present if you want to stop the watchdog when the CPU is
+		  in debug state.
+
+Example:
+	watchdog at fc068640 {
+		compatible = "atmel,sama5d4-wdt";
+		reg = <0xfc068640 0x10>;
+		interrupts = <4 IRQ_TYPE_LEVEL_HIGH 5>;
+		timeout-sec = <10>;
+		atmel,watchdog-type = "hardware";
+		atmel,dbg-halt;
+		atmel,idle-halt;
+		status = "okay";
+	};
-- 
1.7.9.5



From ddaney.cavm at gmail.com  Thu Aug  6 17:33:08 2015
From: ddaney.cavm at gmail.com (David Daney)
Date: Thu,  6 Aug 2015 17:33:08 -0700
Subject: [PATCH 0/2] net: thunder: Add ACPI support.
Message-ID: <1438907590-29649-1-git-send-email-ddaney.cavm@gmail.com>

From: David Daney <david.daney at cavium.com>

Hook up PHYs, and get MAC address from ACPI for the thunder driver.

The first patch (1/2) rearranges the existing code a little with no
functional change to get ready for the second.  The second (2/2) does
the actual work of adding support to extract the needed information
from the ACPI tables.

David Daney (1):
  net, thunder, bgx: Add support for ACPI binding.

Robert Richter (1):
  net: thunder: Factor out DT specific code in BGX

 drivers/net/ethernet/cavium/thunder/thunder_bgx.c | 183 ++++++++++++++++++++--
 1 file changed, 169 insertions(+), 14 deletions(-)

-- 
1.9.1



From ddaney.cavm at gmail.com  Thu Aug  6 17:33:09 2015
From: ddaney.cavm at gmail.com (David Daney)
Date: Thu,  6 Aug 2015 17:33:09 -0700
Subject: [PATCH 1/2] net: thunder: Factor out DT specific code in BGX
In-Reply-To: <1438907590-29649-1-git-send-email-ddaney.cavm@gmail.com>
References: <1438907590-29649-1-git-send-email-ddaney.cavm@gmail.com>
Message-ID: <1438907590-29649-2-git-send-email-ddaney.cavm@gmail.com>

From: Robert Richter <rrichter at cavium.com>

Separate DT code in preparation for follow-on ACPI integration.

Based on code from: Tomasz Nowicki <tomasz.nowicki at linaro.org>

Signed-off-by: Robert Richter <rrichter at cavium.com>
Signed-off-by: David Daney <david.daney at cavium.com>
---
 drivers/net/ethernet/cavium/thunder/thunder_bgx.c | 48 +++++++++++++++++------
 1 file changed, 35 insertions(+), 13 deletions(-)

diff --git a/drivers/net/ethernet/cavium/thunder/thunder_bgx.c b/drivers/net/ethernet/cavium/thunder/thunder_bgx.c
index b961a89..615b2af 100644
--- a/drivers/net/ethernet/cavium/thunder/thunder_bgx.c
+++ b/drivers/net/ethernet/cavium/thunder/thunder_bgx.c
@@ -835,18 +835,28 @@ static void bgx_get_qlm_mode(struct bgx *bgx)
 	}
 }
 
-static void bgx_init_of(struct bgx *bgx, struct device_node *np)
+#if IS_ENABLED(CONFIG_OF_MDIO)
+
+static int bgx_init_of_phy(struct bgx *bgx)
 {
+	struct device_node *np;
 	struct device_node *np_child;
 	u8 lmac = 0;
+	char bgx_sel[5];
+	const char *mac;
 
-	for_each_child_of_node(np, np_child) {
-		struct device_node *phy_np;
-		const char *mac;
+	/* Get BGX node from DT */
+	snprintf(bgx_sel, 5, "bgx%d", bgx->bgx_id);
+	np = of_find_node_by_name(NULL, bgx_sel);
+	if (!np)
+		return -ENODEV;
 
-		phy_np = of_parse_phandle(np_child, "phy-handle", 0);
-		if (phy_np)
-			bgx->lmac[lmac].phydev = of_phy_find_device(phy_np);
+	for_each_child_of_node(np, np_child) {
+		struct device_node *phy_np = of_parse_phandle(np_child,
+							      "phy-handle", 0);
+		if (!phy_np)
+			continue;
+		bgx->lmac[lmac].phydev = of_phy_find_device(phy_np);
 
 		mac = of_get_mac_address(np_child);
 		if (mac)
@@ -858,6 +868,21 @@ static void bgx_init_of(struct bgx *bgx, struct device_node *np)
 		if (lmac == MAX_LMAC_PER_BGX)
 			break;
 	}
+	return 0;
+}
+
+#else
+
+static int bgx_init_of_phy(struct bgx *bgx)
+{
+	return -ENODEV;
+}
+
+#endif /* CONFIG_OF_MDIO */
+
+static int bgx_init_phy(struct bgx *bgx)
+{
+	return bgx_init_of_phy(bgx);
 }
 
 static int bgx_probe(struct pci_dev *pdev, const struct pci_device_id *ent)
@@ -865,8 +890,6 @@ static int bgx_probe(struct pci_dev *pdev, const struct pci_device_id *ent)
 	int err;
 	struct device *dev = &pdev->dev;
 	struct bgx *bgx = NULL;
-	struct device_node *np;
-	char bgx_sel[5];
 	u8 lmac;
 
 	bgx = devm_kzalloc(dev, sizeof(*bgx), GFP_KERNEL);
@@ -902,10 +925,9 @@ static int bgx_probe(struct pci_dev *pdev, const struct pci_device_id *ent)
 	bgx_vnic[bgx->bgx_id] = bgx;
 	bgx_get_qlm_mode(bgx);
 
-	snprintf(bgx_sel, 5, "bgx%d", bgx->bgx_id);
-	np = of_find_node_by_name(NULL, bgx_sel);
-	if (np)
-		bgx_init_of(bgx, np);
+	err = bgx_init_phy(bgx);
+	if (err)
+		goto err_enable;
 
 	bgx_init_hw(bgx);
 
-- 
1.9.1



From ddaney.cavm at gmail.com  Thu Aug  6 17:33:10 2015
From: ddaney.cavm at gmail.com (David Daney)
Date: Thu,  6 Aug 2015 17:33:10 -0700
Subject: [PATCH 2/2] net, thunder, bgx: Add support for ACPI binding.
In-Reply-To: <1438907590-29649-1-git-send-email-ddaney.cavm@gmail.com>
References: <1438907590-29649-1-git-send-email-ddaney.cavm@gmail.com>
Message-ID: <1438907590-29649-3-git-send-email-ddaney.cavm@gmail.com>

From: David Daney <david.daney at cavium.com>

Find out which PHYs belong to which BGX instance in the ACPI way.

Set the MAC address of the device as provided by ACPI tables. This is
similar to the implementation for devicetree in
of_get_mac_address(). The table is searched for the device property
entries "mac-address", "local-mac-address" and "address" in that
order. The address is provided in a u64 variable and must contain a
valid 6 bytes-len mac addr.

Based on code from: Narinder Dhillon <ndhillon at cavium.com>
                    Tomasz Nowicki <tomasz.nowicki at linaro.org>
                    Robert Richter <rrichter at cavium.com>

Signed-off-by: Tomasz Nowicki <tomasz.nowicki at linaro.org>
Signed-off-by: Robert Richter <rrichter at cavium.com>
Signed-off-by: David Daney <david.daney at cavium.com>
---
 drivers/net/ethernet/cavium/thunder/thunder_bgx.c | 137 +++++++++++++++++++++-
 1 file changed, 135 insertions(+), 2 deletions(-)

diff --git a/drivers/net/ethernet/cavium/thunder/thunder_bgx.c b/drivers/net/ethernet/cavium/thunder/thunder_bgx.c
index 615b2af..2056583 100644
--- a/drivers/net/ethernet/cavium/thunder/thunder_bgx.c
+++ b/drivers/net/ethernet/cavium/thunder/thunder_bgx.c
@@ -6,6 +6,7 @@
  * as published by the Free Software Foundation.
  */
 
+#include <linux/acpi.h>
 #include <linux/module.h>
 #include <linux/interrupt.h>
 #include <linux/pci.h>
@@ -26,7 +27,7 @@
 struct lmac {
 	struct bgx		*bgx;
 	int			dmac;
-	unsigned char		mac[ETH_ALEN];
+	u8			mac[ETH_ALEN];
 	bool			link_up;
 	int			lmacid; /* ID within BGX */
 	int			lmacid_bd; /* ID on board */
@@ -835,6 +836,133 @@ static void bgx_get_qlm_mode(struct bgx *bgx)
 	}
 }
 
+#ifdef CONFIG_ACPI
+
+static int bgx_match_phy_id(struct device *dev, void *data)
+{
+	struct phy_device *phydev = to_phy_device(dev);
+	u32 *phy_id = data;
+
+	if (phydev->addr == *phy_id)
+		return 1;
+
+	return 0;
+}
+
+static const char * const addr_propnames[] = {
+	"mac-address",
+	"local-mac-address",
+	"address",
+};
+
+static int acpi_get_mac_address(struct acpi_device *adev, u8 *dst)
+{
+	const union acpi_object *prop;
+	u64 mac_val;
+	u8 mac[ETH_ALEN];
+	int i, j;
+	int ret;
+
+	for (i = 0; i < ARRAY_SIZE(addr_propnames); i++) {
+		ret = acpi_dev_get_property(adev, addr_propnames[i],
+					    ACPI_TYPE_INTEGER, &prop);
+		if (ret)
+			continue;
+
+		mac_val = prop->integer.value;
+
+		if (mac_val & (~0ULL << 48))
+			continue;	/* more than 6 bytes */
+
+		for (j = 0; j < ARRAY_SIZE(mac); j++)
+			mac[j] = (u8)(mac_val >> (8 * j));
+		if (!is_valid_ether_addr(mac))
+			continue;
+
+		memcpy(dst, mac, ETH_ALEN);
+
+		return 0;
+	}
+
+	return ret ? ret : -EINVAL;
+}
+
+static acpi_status bgx_acpi_register_phy(acpi_handle handle,
+					 u32 lvl, void *context, void **rv)
+{
+	struct acpi_reference_args args;
+	const union acpi_object *prop;
+	struct bgx *bgx = context;
+	struct acpi_device *adev;
+	struct device *phy_dev;
+	u32 phy_id;
+
+	if (acpi_bus_get_device(handle, &adev))
+		goto out;
+
+	SET_NETDEV_DEV(&bgx->lmac[bgx->lmac_count].netdev, &bgx->pdev->dev);
+
+	acpi_get_mac_address(adev, bgx->lmac[bgx->lmac_count].mac);
+
+	bgx->lmac[bgx->lmac_count].lmacid = bgx->lmac_count;
+
+	if (acpi_dev_get_property_reference(adev, "phy-handle", 0, &args))
+		goto out;
+
+	if (acpi_dev_get_property(args.adev, "phy-channel", ACPI_TYPE_INTEGER, &prop))
+		goto out;
+
+	phy_id = prop->integer.value;
+
+	phy_dev = bus_find_device(&mdio_bus_type, NULL, (void *)&phy_id,
+				  bgx_match_phy_id);
+	if (!phy_dev)
+		goto out;
+
+	bgx->lmac[bgx->lmac_count].phydev = to_phy_device(phy_dev);
+out:
+	bgx->lmac_count++;
+	return AE_OK;
+}
+
+static acpi_status bgx_acpi_match_id(acpi_handle handle, u32 lvl,
+				     void *context, void **ret_val)
+{
+	struct acpi_buffer string = { ACPI_ALLOCATE_BUFFER, NULL };
+	struct bgx *bgx = context;
+	char bgx_sel[5];
+
+	snprintf(bgx_sel, 5, "BGX%d", bgx->bgx_id);
+	if (ACPI_FAILURE(acpi_get_name(handle, ACPI_SINGLE_NAME, &string))) {
+		pr_warn("Invalid link device\n");
+		return AE_OK;
+	}
+
+	if (strncmp(string.pointer, bgx_sel, 4))
+		return AE_OK;
+
+	acpi_walk_namespace(ACPI_TYPE_DEVICE, handle, 1,
+			    bgx_acpi_register_phy, NULL, bgx, NULL);
+
+	kfree(string.pointer);
+	return AE_CTRL_TERMINATE;
+}
+
+static int bgx_init_acpi_phy(struct bgx *bgx)
+{
+	acpi_get_devices(NULL, bgx_acpi_match_id, bgx, (void **)NULL);
+	return 0;
+}
+
+#else
+
+static int bgx_init_acpi_phy(struct bgx *bgx)
+{
+	return -ENODEV;
+}
+
+#endif /* CONFIG_ACPI */
+
 #if IS_ENABLED(CONFIG_OF_MDIO)
 
 static int bgx_init_of_phy(struct bgx *bgx)
@@ -882,7 +1010,12 @@ static int bgx_init_of_phy(struct bgx *bgx)
 
 static int bgx_init_phy(struct bgx *bgx)
 {
-	return bgx_init_of_phy(bgx);
+	int err = bgx_init_of_phy(bgx);
+
+	if (err != -ENODEV)
+		return err;
+
+	return bgx_init_acpi_phy(bgx);
 }
 
 static int bgx_probe(struct pci_dev *pdev, const struct pci_device_id *ent)
-- 
1.9.1



From sfr at canb.auug.org.au  Thu Aug  6 17:33:32 2015
From: sfr at canb.auug.org.au (Stephen Rothwell)
Date: Fri, 7 Aug 2015 10:33:32 +1000
Subject: linux-next: build failure after merge of the arm-soc tree
Message-ID: <20150807103332.0354c71b@canb.auug.org.au>

Hi all,

After merging the arm-soc tree, today's linux-next build (arm
multi_v7_defconfig) failed like this:

arch/arm/mach-shmobile/Makefile:59: *** missing 'endif'.  Stop.

Caused by commit

  ff20775d189c ("Merge tag 'renesas-marzen-board-removal-for-v4.3' of git://git.kernel.org/pub/scm/linux/kernel/git/horms/renesas into next/cleanup")

I have used the arm-soc tree from next-20150806 for today.

-- 
Cheers,
Stephen Rothwell                    sfr at canb.auug.org.au


From horms at verge.net.au  Thu Aug  6 17:34:55 2015
From: horms at verge.net.au (Simon Horman)
Date: Fri, 7 Aug 2015 09:34:55 +0900
Subject: [PATCH v4 0/6] ARM: shmobile: r8a7740/sh73a0 DT Cache Handling
In-Reply-To: <CAMuHMdW5D2LGA=3+JDiAUhVtPmxk3ZJhAx3=JXFuAHBAgU_NTw@mail.gmail.com>
References: <1438765090-823-1-git-send-email-geert+renesas@glider.be>
 <20150806003511.GB17231@verge.net.au>
 <CAMuHMdW5D2LGA=3+JDiAUhVtPmxk3ZJhAx3=JXFuAHBAgU_NTw@mail.gmail.com>
Message-ID: <20150807003455.GB1145@verge.net.au>

On Thu, Aug 06, 2015 at 09:17:38AM +0200, Geert Uytterhoeven wrote:
> On Thu, Aug 6, 2015 at 2:35 AM, Simon Horman <horms at verge.net.au> wrote:
> > On Wed, Aug 05, 2015 at 10:58:04AM +0200, Geert Uytterhoeven wrote:
> >> This patch series add L1 and L2 cache descriptions to DT for r8a7740 and
> >> sh73a0, and migrates the shmobile DT-based generic r8a7740 and
> >> armadillo legacy platforms from calling l2x0_of_init() to the generic
> >> l2c OF initialization.
> 
> >> Dependencies:
> >>   - This series applies to renesas-devel-20150805-v4.2-rc5,
> >>   - Patch 2 depends on patch 1,
> >>   - Patch 4 depends on patch 2,
> 
> Sorry, "... on patch 3".
> 
> >>   - Patch 5 depends on patch 1 and on "ARM: 8395/1: l2c: Add support for
> >>     the "arm,shared-override" property" in arm/for-next,
> >>   - Patch 6 depends on patch 5.
> >>
> >> Given C code patches depending on DT patches in the same branch are
> >> frowned upon, I think it would be best if patch 1 (and patch 3, if
> >> anyone thinks we may fix the secondary CPU bringup issue during the next
> >> 3 months) are queued for v4.3. The other patches can be queued for
> >> 2016^H^H^H^Hv4.4.
> >
> > Sorry for surprising you with that merge-order requirement.
> 
> In theory it sounds fine, as DT and code are independent.
> Moving functionality from C to DT is something different...

I agree entirely. This is probably something that we should discuss
with the ARM SoC developers. But my feeling is that there should be
some scope for flexibility with regards to merge-order in such cases.

By which I mean we should try where possible, not to apply non-DT patches
on top of DT patches. But if circumstances arise where it seems to
be the best approach then we should to approach things pragmatically.

> > Unfortunately I am not comfortable with taking patch 1 for v4.3 because:
> > 1. Its now very late in the cycle
> 
> I understand.
> 
> > 2. There now seems to be some discussion around it.
> 
> Yeah, that's what v4s are for...
> 
> Let's wait and see if/when it settles...

Yes, lets.

> > I think I am happy to take the other patches for v4.4, now. But perhaps
> > I should wait for the discussion around patch 1 to conclude first?
> 
> Which other patches? Patch 3 has the same issue as patch 1. And all
> the rest depends on patch 1 or patch 3... So there's nothing left to
> apply yet...

Sorry for not being clearer. By other patches I meant patches 2 - 6 of this
series.  It seems that we should wait and I'm quite happy to do so.


From horms at verge.net.au  Thu Aug  6 17:40:48 2015
From: horms at verge.net.au (Simon Horman)
Date: Fri, 7 Aug 2015 09:40:48 +0900
Subject: [PATCH v2 0/2] Add R8A7794 GPIO DT support
In-Reply-To: <CAMuHMdV5F2JL6_OhPY3y7WZn_pfG_ufRUe9NA+2C-CGLtVxVaw@mail.gmail.com>
References: <6388101.Drn6rL87rl@wasted.cogentembedded.com>
 <20150806004714.GD17231@verge.net.au>
 <CAMuHMdV5F2JL6_OhPY3y7WZn_pfG_ufRUe9NA+2C-CGLtVxVaw@mail.gmail.com>
Message-ID: <20150807004048.GC1145@verge.net.au>

On Thu, Aug 06, 2015 at 09:21:34AM +0200, Geert Uytterhoeven wrote:
> On Thu, Aug 6, 2015 at 2:47 AM, Simon Horman <horms at verge.net.au> wrote:
> > On Tue, Aug 04, 2015 at 12:36:27AM +0300, Sergei Shtylyov wrote:
> >>    Here's the set of 2 patches against Simon Horman's 'renesas.git' repo,
> >> 'renesas-devel-20150803-v4.2-rc5' tag. Here we add the GPIO device tree support
> >> for the R8A7794 SoC.
> >>
> >> [1/2] ARM: shmobile: r8a7794: add GPIO clocks
> >> [2/2] ARM: shmobile: r8a7794: add GPIO DT support
> >
> > Thanks, I have queued these up for v4.4.
> 
> Woops, Since CPG/MSTP support is in, GPIO won't work, as the nodes
> lack "power-domains" properties.

Sorry for letting that through.
I will drop these patches accordingly.
Sergei, could you please re-spin them?


From horms at verge.net.au  Thu Aug  6 17:41:40 2015
From: horms at verge.net.au (Simon Horman)
Date: Fri, 7 Aug 2015 09:41:40 +0900
Subject: [PATCH v2 0/2] Add R8A7794 GPIO DT support
In-Reply-To: <55C3BE35.8020408@cogentembedded.com>
References: <6388101.Drn6rL87rl@wasted.cogentembedded.com>
 <20150806004714.GD17231@verge.net.au>
 <55C3BE35.8020408@cogentembedded.com>
Message-ID: <20150807004140.GD1145@verge.net.au>

On Thu, Aug 06, 2015 at 11:06:13PM +0300, Sergei Shtylyov wrote:
> Hello.
> 
> On 08/06/2015 03:47 AM, Simon Horman wrote:
> 
> >>    Here's the set of 2 patches against Simon Horman's 'renesas.git' repo,
> >>'renesas-devel-20150803-v4.2-rc5' tag. Here we add the GPIO device tree support
> >>for the R8A7794 SoC.
> 
> >>[1/2] ARM: shmobile: r8a7794: add GPIO clocks
> >>[2/2] ARM: shmobile: r8a7794: add GPIO DT support
> 
> >Thanks, I have queued these up for v4.4.
> 
>    Not seeing anything new in your repo. Which is probably a good thing
> considering Geert's comments.

It seems that I forgot to push yesterday, which as you say,
does seem quite fortunate given Geert's comments.


From k.kozlowski at samsung.com  Thu Aug  6 17:47:46 2015
From: k.kozlowski at samsung.com (Krzysztof Kozlowski)
Date: Fri, 7 Aug 2015 09:47:46 +0900
Subject: [PATCH] kvm:arm:Fix error handling in the function vgic_v3_probe
In-Reply-To: <55C35E3D.9000708@gmail.com>
References: <1438793303-30228-1-git-send-email-xerofoify@gmail.com>
 <55C240D9.5060900@redhat.com> <55C242C6.6060200@gmail.com>
 <55C31582.4000809@arm.com> <55C34C77.7090303@redhat.com>
 <55C35E3D.9000708@gmail.com>
Message-ID: <CAJKOXPeVGmrkBwRRY6D46MhXtWH+_ybxyJpQjyH4F7BOpKLxSQ@mail.gmail.com>

2015-08-06 22:16 GMT+09:00 nick <xerofoify at gmail.com>:
>
>
> On 2015-08-06 08:00 AM, Paolo Bonzini wrote:
>>
>>
>> On 06/08/2015 10:06, Marc Zyngier wrote:
>>>> If this structure of function pointers can handle function pointers with a return type of
>>>> void I will be glad to do what you request otherwise this would require a major rewrite
>>>> of kvm arm subsystem for a very simple bug fix.
>>>
>>> Just like Paolo said, the error you report should never happen, and
>>> would be caught by a WARN_ON() the first time anyone boots the kernel.
>>> Also, failing to register the device ops results in not being able to
>>> instantiate a VGIC. No harm done. I really don't understand why you want
>>> to rewrite the probe functions.
>>
>> I think he just misunderstood my suggestion.  I didn't suggest making
>> the probe functions return void.  I suggested that
>> kvm_register_device_ops return void.
>>
>> Paolo
>>
> Unfortunately the other maintainer is right in the s390 kvm subsystem uses the return value of the call to
> kvm_register_device_ops. However we could do something like a WARN_ON if kvm_register_device_ops fails in
> callers that never are required to never use it's return value.
> Sorry about the Misunderstanding as I misread your suggestion.
> Nick

Dear Nick,

Since you are not testing the patches, please always mark them with
RFT prefix, instead of PATCH. Someone may get confused and actually
apply untested patch.

Best regards,
Krzysztof


From robdclark at gmail.com  Thu Aug  6 18:19:31 2015
From: robdclark at gmail.com (Rob Clark)
Date: Thu, 6 Aug 2015 21:19:31 -0400
Subject: [PATCH v1 4/7] ARM: dts: apq8064: Add MDP support
In-Reply-To: <55C2B801.1030806@codeaurora.org>
References: <1438087956-17307-1-git-send-email-srinivas.kandagatla@linaro.org>
 <1438088049-17479-1-git-send-email-srinivas.kandagatla@linaro.org>
 <55C2B801.1030806@codeaurora.org>
Message-ID: <CAF6AEGtFM-_boOYsnzp5DXSSATFkBiJ5Bj=PVTXy=-ZzXi1x5Q@mail.gmail.com>

On Wed, Aug 5, 2015 at 9:27 PM, Stephen Boyd <sboyd at codeaurora.org> wrote:
> On 07/28/2015 05:54 AM, Srinivas Kandagatla wrote:
>>
>> @@ -618,5 +633,77 @@
>>                         compatible = "qcom,tcsr-apq8064", "syscon";
>>                         reg = <0x1a400000 0x100>;
>>                 };
>> +
>> +               hdmi: qcom,hdmi-tx at 4a00000 {
>> +                       compatible = "qcom,hdmi-tx-8960";
>> +                       reg-names = "core_physical";
>> +                       reg = <0x04a00000 0x1000>;
>> +                       interrupts = <GIC_SPI 79 0>;
>> +                       clock-names =
>> +                           "core_clk",
>> +                           "master_iface_clk",
>> +                           "slave_iface_clk";
>> +                       clocks =
>> +                           <&mmcc HDMI_APP_CLK>,
>> +                           <&mmcc HDMI_M_AHB_CLK>,
>> +                           <&mmcc HDMI_S_AHB_CLK>;
>> +                       qcom,hdmi-tx-ddc-clk = <&tlmm_pinmux 70
>> GPIO_ACTIVE_HIGH>;
>> +                       qcom,hdmi-tx-ddc-data = <&tlmm_pinmux 71
>> GPIO_ACTIVE_HIGH>;
>> +                       qcom,hdmi-tx-hpd = <&tlmm_pinmux 72
>> GPIO_ACTIVE_HIGH>;
>
>
> These should use standard "-gpios" syntax. Please fix the binding/driver.

With this, and a couple of the other bindings, I'd chosen to follow to
follow the downstream bindings simply because I still need to use
downstream kernel on a handful of devices (for example, I have no a4xx
device which runs anything close to an upstream kernel, yet still
quite a lot of work to do in userspace/mesa there)..  this might be a
scenario that other kernel dev's in other subsystems aren't really
familiar with, but when it comes to gpu's, really only 10% or less of
the driver is in the kernel.  There is a massive sh**-ton of
complexity in terms of cmdstream building in userspace.

But if the change to do things upstream is not too intrusive I'd be
willing to carry the 'revert' patch as a downstream patch on top of
upstream.. or if we could reasonably support both bindings, that is
also an option.  Mostly I just haven't had time to look into it, since
unlike other drivers, when it comes to gpu stuff, the kernel is only
the tip of the (inverted) iceberg..

>> +                       pinctrl-names = "default";
>> +                       pinctrl-0 = <&hdmi_pinctrl>;
>> +               };
>> +
>> +               gpu: qcom,adreno-3xx at 4300000 {
>> +                       compatible = "qcom,adreno-3xx";
>> +                       reg = <0x04300000 0x20000>;
>> +                       reg-names = "kgsl_3d0_reg_memory";
>> +                       interrupts = <GIC_SPI 80 0>;
>> +                       interrupt-names = "kgsl_3d0_irq";
>> +                       clock-names =
>> +                           "core_clk",
>> +                           "iface_clk",
>> +                           "mem_clk",
>> +                           "mem_iface_clk";
>
>
> Please drop "_clk" and fix driver code as we've done for all other drivers.
>
>> +                       clocks =
>> +                           <&mmcc GFX3D_CLK>,
>> +                           <&mmcc GFX3D_AHB_CLK>,
>> +                           <&mmcc GFX3D_AXI_CLK>,
>> +                           <&mmcc MMSS_IMEM_AHB_CLK>;
>> +                       qcom,chipid = <0x03020002>;
>> +                       qcom,gpu-pwrlevels {
>> +                               compatible = "qcom,gpu-pwrlevels";
>> +                               qcom,gpu-pwrlevel at 0 {
>> +                                       qcom,gpu-freq = <450000000>;
>> +                               };
>> +                               qcom,gpu-pwrlevel at 1 {
>> +                                       qcom,gpu-freq = <27000000>;
>> +                               };
>> +                       };
>
>
> These should be OPPs. I see in the cover-letter we're asking to ignore this
> part of the binding. When is the binding and driver going to be fixed? The
> dts has been out of tree for quite some time and I assume work has been
> progressing on the driver even without this dts being in mainline so it
> doesn't make sense how pushing half-baked dts upstream is going to help. In
> fact, it's going to make things worse if someone complains that we're not
> maintaining backwards compatibility and then have to hack up driver code to
> work both ways. At which point there's practically zero incentive to change
> anything in the binding or driver. It's better to fix the driver now and
> avoid these sorts of problems entirely.

again, it is a bit awkward thanks to having to deal with downstream
kernels while upstream catches up..

It does seem interesting to move to cpufreq for managing the gpu
speed, and maybe doing something more clever than all-or-nothing freq
scaling..  but yet again something where I really haven't had time to
investigate beyond "yeah, that seems like a good idea"..

It would be *really* nice if we had some mechanism to mark bindings
that we are not ready yet to call ABI, since on one hand we have an
upstream gpu driver and corresponding userspace to actually have some
interesting some interesting (ie. not just buildroot and serial
console) stuff running on an upstream kernel on actual devices.  And
that is a nice situation that I wouldn't have even thought possible a
few years ago.  But otoh, I agree that we shouldn't call these
bindings final abi.

Anyways, patches welcome.. bonus points if they are not too intrusive
to revert (for the downstream kernels I have to deal with) or if they
continue to support the downstream bindings (for now, until I don't
have to care about downstream kernels)..

BR,
-R


> --
> Qualcomm Innovation Center, Inc. is a member of Code Aurora Forum,
> a Linux Foundation Collaborative Project
>


From horms at verge.net.au  Thu Aug  6 18:28:47 2015
From: horms at verge.net.au (Simon Horman)
Date: Fri, 7 Aug 2015 10:28:47 +0900
Subject: [GIT PULL v2] Renesas ARM Based SoC Marzen Board Removal for v4.3
In-Reply-To: <20150806081000.GA16520@localhost>
References: <cover.1438581659.git.horms+renesas@verge.net.au>
 <20150806081000.GA16520@localhost>
Message-ID: <20150807012847.GF1145@verge.net.au>

On Thu, Aug 06, 2015 at 10:10:00AM +0200, Olof Johansson wrote:
> On Mon, Aug 03, 2015 at 03:04:55PM +0900, Simon Horman wrote:
> > Hi Olof, Hi Kevin, Hi Arnd,
> > 
> > Please consider these Renesas ARM based SoC marzen board removal for v4.3.
> > 
> > 
> > This series removes legacy r8a7779 SoC and marzen board code.
> > It aims to do do so in a way that does not introduce feature regressions
> > when when booting the r8a7779/marzen board using shmobile_defconfig,
> > which provides for booting using multiplatform, a scenario which previously
> > used board code to provide some features including SMP.
> > 
> > Because of the above this series modifies SoC and DT files,
> > and then removes code. And because of that it was not entirely clear to
> > me which branch it should go into, so I have provided it in a stand-alone
> > branch.
> > 
> > Unfortunately this branch has a number of minor conflicts with the "Renesas
> > ARM Based SoC Cleanup for v4.3", tagged as renesas-cleanup-for-v4.3, which
> > you have previously pulled.
> > 
> > A resolution to those conflicts can be found in the
> > renesas-next-20150730-v4.2-rc1 tag of the renesas tree.
> > 
> > On a more positive note, I believe this to well over 8000 lines of legacy
> > code removed in this cycle :)
> > 
> > 
> > Changes between v1 and v2:
> > 
> > * As requested by Olof: Do not include defconfig updates;
> >   these will be handled separately
> > 
> > 
> > The following changes since commit d770e558e21961ad6cfdf0ff7df0eb5d7d4f0754:
> > 
> >   Linux 4.2-rc1 (2015-07-05 11:01:52 -0700)
> > 
> > are available in the git repository at:
> > 
> >   git://git.kernel.org/pub/scm/linux/kernel/git/horms/renesas.git tags/renesas-marzen-board-removal-for-v4.3
> 
> Merged, but it was a messy one and it's awkward to diff with your proposed
> resolution due to other differences.
> 
> Please double-check that I resolved things correctly. Thanks!

Sorry about that, it seems this has been rather messy.

Unfortunately I have noticed what appear to be two merge problems.

I am not sure what the best way to resolve them is,
but my corrections are below. If you need formal patches please
don't hesitate to ask.

* The arch/arm/mach-shmobile/Makefile problem seems to break builds where
  ARCH_SHMOBILE_LEGACY or ARCH_SHMOBILE_MULTI are enabled. In particular
  the following defconfigs: multi_v7, bockw, shmobile.

* The arch/arm/boot/dts/Makefile problem just causes some unnecessary
  dtb compilation. Which seems harmless though should be cleaned
  up at some point.


diff --git a/arch/arm/boot/dts/Makefile b/arch/arm/boot/dts/Makefile
index dd2063ad194f..333e0e3466f1 100644
--- a/arch/arm/boot/dts/Makefile
+++ b/arch/arm/boot/dts/Makefile
@@ -517,9 +517,7 @@ dtb-$(CONFIG_ARCH_S5PV210) += \
 	s5pv210-torbreck.dtb
 dtb-$(CONFIG_ARCH_SHMOBILE_LEGACY) += \
 	r8a7778-bockw.dtb \
-	r8a7778-bockw-reference.dtb \
-	r8a7779-marzen.dtb \
-	sh73a0-kzm9g.dtb
+	r8a7778-bockw-reference.dtb
 dtb-$(CONFIG_ARCH_SHMOBILE_MULTI) += \
 	emev2-kzm9d.dtb \
 	r7s72100-genmai.dtb \
diff --git a/arch/arm/mach-shmobile/Makefile b/arch/arm/mach-shmobile/Makefile
index 8d1e0b6ac2a2..476de30798d7 100644
--- a/arch/arm/mach-shmobile/Makefile
+++ b/arch/arm/mach-shmobile/Makefile
@@ -53,6 +53,7 @@ obj-$(CONFIG_ARCH_RCAR_GEN2)	+= pm-rcar-gen2.o
 ifndef CONFIG_ARCH_SHMOBILE_MULTI
 obj-$(CONFIG_MACH_BOCKW)	+= board-bockw.o
 obj-$(CONFIG_MACH_BOCKW_REFERENCE)	+= board-bockw-reference.o
+endif
 
 # Framework support
 obj-$(CONFIG_SMP)		+= $(smp-y)


From xerofoify at gmail.com  Thu Aug  6 18:31:42 2015
From: xerofoify at gmail.com (nick)
Date: Thu, 06 Aug 2015 21:31:42 -0400
Subject: [PATCH] kvm:arm:Fix error handling in the function vgic_v3_probe
In-Reply-To: <CAJKOXPeVGmrkBwRRY6D46MhXtWH+_ybxyJpQjyH4F7BOpKLxSQ@mail.gmail.com>
References: <1438793303-30228-1-git-send-email-xerofoify@gmail.com>	<55C240D9.5060900@redhat.com>	<55C242C6.6060200@gmail.com>	<55C31582.4000809@arm.com>	<55C34C77.7090303@redhat.com>	<55C35E3D.9000708@gmail.com>
 <CAJKOXPeVGmrkBwRRY6D46MhXtWH+_ybxyJpQjyH4F7BOpKLxSQ@mail.gmail.com>
Message-ID: <55C40A7E.6040003@gmail.com>



On 2015-08-06 08:47 PM, Krzysztof Kozlowski wrote:
> 2015-08-06 22:16 GMT+09:00 nick <xerofoify at gmail.com>:
>>
>>
>> On 2015-08-06 08:00 AM, Paolo Bonzini wrote:
>>>
>>>
>>> On 06/08/2015 10:06, Marc Zyngier wrote:
>>>>> If this structure of function pointers can handle function pointers with a return type of
>>>>> void I will be glad to do what you request otherwise this would require a major rewrite
>>>>> of kvm arm subsystem for a very simple bug fix.
>>>>
>>>> Just like Paolo said, the error you report should never happen, and
>>>> would be caught by a WARN_ON() the first time anyone boots the kernel.
>>>> Also, failing to register the device ops results in not being able to
>>>> instantiate a VGIC. No harm done. I really don't understand why you want
>>>> to rewrite the probe functions.
>>>
>>> I think he just misunderstood my suggestion.  I didn't suggest making
>>> the probe functions return void.  I suggested that
>>> kvm_register_device_ops return void.
>>>
>>> Paolo
>>>
>> Unfortunately the other maintainer is right in the s390 kvm subsystem uses the return value of the call to
>> kvm_register_device_ops. However we could do something like a WARN_ON if kvm_register_device_ops fails in
>> callers that never are required to never use it's return value.
>> Sorry about the Misunderstanding as I misread your suggestion.
>> Nick
> 
> Dear Nick,
> 
> Since you are not testing the patches, please always mark them with
> RFT prefix, instead of PATCH. Someone may get confused and actually
> apply untested patch.
> 
> Best regards,
> Krzysztof
> 
Krzysztof,
I am not stating your wrong here but most of my patches are either trivial bug fixes that
don't need any testing or our on hardware I don't have lying around. In addition unless
my bugs are hard to trace a.k.a locking issues or hardware dependent that need proof due
to being unable to trace without the hardware I feel that your statement is a valid idea
but may not be the best here. If you would like me to still write RFT on my patches or
our concerned about me testing them I can assure you that there tested when I am able
to.
Cheers,
Nick 


From k.kozlowski at samsung.com  Thu Aug  6 18:36:29 2015
From: k.kozlowski at samsung.com (Krzysztof Kozlowski)
Date: Fri, 07 Aug 2015 10:36:29 +0900
Subject: [PATCH] kvm:arm:Fix error handling in the function vgic_v3_probe
In-Reply-To: <55C40A7E.6040003@gmail.com>
References: <1438793303-30228-1-git-send-email-xerofoify@gmail.com>
 <55C240D9.5060900@redhat.com> <55C242C6.6060200@gmail.com>
 <55C31582.4000809@arm.com> <55C34C77.7090303@redhat.com>
 <55C35E3D.9000708@gmail.com>
 <CAJKOXPeVGmrkBwRRY6D46MhXtWH+_ybxyJpQjyH4F7BOpKLxSQ@mail.gmail.com>
 <55C40A7E.6040003@gmail.com>
Message-ID: <55C40B9D.3030409@samsung.com>

On 07.08.2015 10:31, nick wrote:
> 
> 
> On 2015-08-06 08:47 PM, Krzysztof Kozlowski wrote:
>> 2015-08-06 22:16 GMT+09:00 nick <xerofoify at gmail.com>:
>>>
>>>
>>> On 2015-08-06 08:00 AM, Paolo Bonzini wrote:
>>>>
>>>>
>>>> On 06/08/2015 10:06, Marc Zyngier wrote:
>>>>>> If this structure of function pointers can handle function pointers with a return type of
>>>>>> void I will be glad to do what you request otherwise this would require a major rewrite
>>>>>> of kvm arm subsystem for a very simple bug fix.
>>>>>
>>>>> Just like Paolo said, the error you report should never happen, and
>>>>> would be caught by a WARN_ON() the first time anyone boots the kernel.
>>>>> Also, failing to register the device ops results in not being able to
>>>>> instantiate a VGIC. No harm done. I really don't understand why you want
>>>>> to rewrite the probe functions.
>>>>
>>>> I think he just misunderstood my suggestion.  I didn't suggest making
>>>> the probe functions return void.  I suggested that
>>>> kvm_register_device_ops return void.
>>>>
>>>> Paolo
>>>>
>>> Unfortunately the other maintainer is right in the s390 kvm subsystem uses the return value of the call to
>>> kvm_register_device_ops. However we could do something like a WARN_ON if kvm_register_device_ops fails in
>>> callers that never are required to never use it's return value.
>>> Sorry about the Misunderstanding as I misread your suggestion.
>>> Nick
>>
>> Dear Nick,
>>
>> Since you are not testing the patches, please always mark them with
>> RFT prefix, instead of PATCH. Someone may get confused and actually
>> apply untested patch.
>>
>> Best regards,
>> Krzysztof
>>
> Krzysztof,
> I am not stating your wrong here but most of my patches are either trivial bug fixes that
> don't need any testing or our on hardware I don't have lying around. In addition unless
> my bugs are hard to trace a.k.a locking issues or hardware dependent that need proof due
> to being unable to trace without the hardware I feel that your statement is a valid idea
> but may not be the best here. If you would like me to still write RFT on my patches or
> our concerned about me testing them I can assure you that there tested when I am able
> to.

Each patch, even trivial should be tested. If it is not tested then
please indicate it by putting a RFT tag. The maintainer may agree that
testing is not required. It's fine. However it is important to notify
the maintainer so he could make proper decision and assess the risk.

Contributor is not the right person to judge whether testing is
necessary or not.

*Please mark all your patches as RFT.*

I am also doing this on my patches that I cannot test.

Best regards,
Krzysztof


From xerofoify at gmail.com  Thu Aug  6 18:40:43 2015
From: xerofoify at gmail.com (nick)
Date: Thu, 06 Aug 2015 21:40:43 -0400
Subject: [PATCH] kvm:arm:Fix error handling in the function vgic_v3_probe
In-Reply-To: <55C40B9D.3030409@samsung.com>
References: <1438793303-30228-1-git-send-email-xerofoify@gmail.com>
 <55C240D9.5060900@redhat.com> <55C242C6.6060200@gmail.com>
 <55C31582.4000809@arm.com> <55C34C77.7090303@redhat.com>
 <55C35E3D.9000708@gmail.com>
 <CAJKOXPeVGmrkBwRRY6D46MhXtWH+_ybxyJpQjyH4F7BOpKLxSQ@mail.gmail.com>
 <55C40A7E.6040003@gmail.com> <55C40B9D.3030409@samsung.com>
Message-ID: <55C40C9B.8040107@gmail.com>



On 2015-08-06 09:36 PM, Krzysztof Kozlowski wrote:
> On 07.08.2015 10:31, nick wrote:
>>
>>
>> On 2015-08-06 08:47 PM, Krzysztof Kozlowski wrote:
>>> 2015-08-06 22:16 GMT+09:00 nick <xerofoify at gmail.com>:
>>>>
>>>>
>>>> On 2015-08-06 08:00 AM, Paolo Bonzini wrote:
>>>>>
>>>>>
>>>>> On 06/08/2015 10:06, Marc Zyngier wrote:
>>>>>>> If this structure of function pointers can handle function pointers with a return type of
>>>>>>> void I will be glad to do what you request otherwise this would require a major rewrite
>>>>>>> of kvm arm subsystem for a very simple bug fix.
>>>>>>
>>>>>> Just like Paolo said, the error you report should never happen, and
>>>>>> would be caught by a WARN_ON() the first time anyone boots the kernel.
>>>>>> Also, failing to register the device ops results in not being able to
>>>>>> instantiate a VGIC. No harm done. I really don't understand why you want
>>>>>> to rewrite the probe functions.
>>>>>
>>>>> I think he just misunderstood my suggestion.  I didn't suggest making
>>>>> the probe functions return void.  I suggested that
>>>>> kvm_register_device_ops return void.
>>>>>
>>>>> Paolo
>>>>>
>>>> Unfortunately the other maintainer is right in the s390 kvm subsystem uses the return value of the call to
>>>> kvm_register_device_ops. However we could do something like a WARN_ON if kvm_register_device_ops fails in
>>>> callers that never are required to never use it's return value.
>>>> Sorry about the Misunderstanding as I misread your suggestion.
>>>> Nick
>>>
>>> Dear Nick,
>>>
>>> Since you are not testing the patches, please always mark them with
>>> RFT prefix, instead of PATCH. Someone may get confused and actually
>>> apply untested patch.
>>>
>>> Best regards,
>>> Krzysztof
>>>
>> Krzysztof,
>> I am not stating your wrong here but most of my patches are either trivial bug fixes that
>> don't need any testing or our on hardware I don't have lying around. In addition unless
>> my bugs are hard to trace a.k.a locking issues or hardware dependent that need proof due
>> to being unable to trace without the hardware I feel that your statement is a valid idea
>> but may not be the best here. If you would like me to still write RFT on my patches or
>> our concerned about me testing them I can assure you that there tested when I am able
>> to.
> 
> Each patch, even trivial should be tested. If it is not tested then
> please indicate it by putting a RFT tag. The maintainer may agree that
> testing is not required. It's fine. However it is important to notify
> the maintainer so he could make proper decision and assess the risk.
> 
> Contributor is not the right person to judge whether testing is
> necessary or not.
> 
> *Please mark all your patches as RFT.*
> 
> I am also doing this on my patches that I cannot test.
> 
> Best regards,
> Krzysztof
> 
Ok that's fine if that is the practice for untested patches I don't mind.
Nick 


From scott.shu at mediatek.com  Thu Aug  6 18:56:58 2015
From: scott.shu at mediatek.com (Scott Shu)
Date: Fri, 7 Aug 2015 09:56:58 +0800
Subject: [PATCH v3 3/8] soc: Mediatek: Add SCPSYS CPU power domain driver
In-Reply-To: <20150806100311.GP18700@pengutronix.de>
References: <1438696464-59858-1-git-send-email-scott.shu@mediatek.com>
 <1438696464-59858-4-git-send-email-scott.shu@mediatek.com>
 <20150805085034.GG18700@pengutronix.de>
 <1438829942.9435.24.camel@mtkswgap22>
 <20150806100311.GP18700@pengutronix.de>
Message-ID: <1438912618.1900.31.camel@mtkswgap22>

On Thu, 2015-08-06 at 12:03 +0200, Sascha Hauer wrote:
> On Thu, Aug 06, 2015 at 10:59:02AM +0800, Scott Shu wrote:
> > On Wed, 2015-08-05 at 10:50 +0200, Sascha Hauer wrote:
> > > don't do this then it indeed doesn't make much sense to put it into the
> > > same file.
> > > 
> > > From what I see we would need to change the prototype to something like
> > > 
> > > static int __scpsys_power_on(struct scp_domain_data *)
> > > 
> > > (maybe with some additional base addresses and stuff)
> > > 
> > > struct scp_domain_data would additionally need sram_isoint_b and sram_ckiso
> > > members.
> > > 
> > > Sascha
> > > 
> > Hi Sascha,
> >    The CPU power sequence is quite different with the others, as
> > described below.
> > 
> > * Non-CPU
> >    1) Set PWR_ON_BIT, PWR_ON_2ND_BIT
> >    2) Wait PWR_ACK
> >    3) Clear PWR_CLK_DIS_BIT
> >    4) Clear PWR_ISO_BIT
> >    5) Set PWR_RST_B_BIT
> >    6) Clear SRAM_PDN
> >    7) Wait SRAM_PDN_ACK
> > * CPU
> >    1) Set PWR_ON_BIT, PWR_ON_2ND_BIT
> >    2) Wait PWR_ACK
> >    3) Clear PWR_ISO_BIT
> >    4) Clear L1_PDN to power on L1
> >    5) Wait L1_PDN_ACK
> >    6) Set SRAM_ISOINT_B
> >    7) Clear SRAM_CKISO
> >    8) Clear PWR_CLK_DIS
> >    9) Set PWR_RST_B
> > For multi-cluster SoC, the cluster power sequence is also different.
> > 
> > Please think if this is a good idea if we integrate the CPU support into
> > the scpsys_power_on()? Based on the readability and compatible
> > considerations, we provide this patch.
> 
> Maybe it's best if you go back to the v1 layout and put your scpsys code
> to arch/arm/mach-mediatek/. While I think it's possible to share some
> more code I am not sure anymore if this buys us something. We'll know in
> the future.
> 
> Sascha
> 
> 
Thanks Sascha. If you agree, we prefer to keep v3 layout. It's good to
put all scpsys related code and definitions in the same place (your
driver) and limit the CPU MTCMOS code are all located in button half of
the file. We may also change the function name, for example, rename
spm_cpu_mtcmos_on/off to scpsys_cpu_power_on/off, to make a better
overall sense. 

Scott



From scott.shu at mediatek.com  Thu Aug  6 18:59:45 2015
From: scott.shu at mediatek.com (Scott Shu)
Date: Fri, 7 Aug 2015 09:59:45 +0800
Subject: [PATCH v3 5/8] ARM: mediatek: add smp bringup code for MT6580
In-Reply-To: <20150806061918.GK18700@pengutronix.de>
References: <1438696464-59858-1-git-send-email-scott.shu@mediatek.com>
 <1438696464-59858-6-git-send-email-scott.shu@mediatek.com>
 <1801910.hz53dYUgta@ubix> <20150806061918.GK18700@pengutronix.de>
Message-ID: <1438912785.1900.33.camel@mtkswgap22>

On Thu, 2015-08-06 at 08:19 +0200, Sascha Hauer wrote:
> On Wed, Aug 05, 2015 at 06:47:03PM +0200, Matthias Brugger wrote:
> > On Tuesday, August 04, 2015 09:54:21 PM Scott Shu wrote:
> > > Add support for cpu enable-method "mediatek,mt6580-smp" for booting
> > > secondary CPUs on MT6580.
> > > 
> > > Signed-off-by: Scott Shu <scott.shu at mediatek.com>
> > > ---
> > >  arch/arm/mach-mediatek/platsmp.c |  137
> > > ++++++++++++++++++++++++++++++++++++++ 1 file changed, 137 insertions(+)
> > > +
> > > +static void __init mt6580_smp_prepare_cpus(unsigned int max_cpus)
> > > +{
> > > +	static void __iomem *infracfg_ao_base;
> > > +
> > > +	infracfg_ao_base = ioremap(MT6580_INFRACFG_AO, 0x1000);
> > > +	if (!infracfg_ao_base) {
> > > +		pr_err("%s: Unable to map I/O memory\n", __func__);
> > > +		return;
> > > +	}
> > > +
> > > +	/* Enable bootrom power down mode */
> > > +	writel_relaxed(readl(infracfg_ao_base + 0x804) | SW_ROM_PD,
> > > +		       infracfg_ao_base + 0x804);
> > 
> > Please use a define for the offset.
> > I prefer to not cascade reads and writes but to use a temporary variable. But 
> > if this is fine with the kernel coding style (I doubt, but I'm not sure) then 
> > this is fine.
> 
> For what it's worth I also prefer
> 
> 	val = readl(infracfg_ao_base + 0x804);
> 	val |= SW_ROM_PD:
> 	writel_relaxed(val, infracfg_ao_base + 0x804);
> 
> I find this better readable. I don't think though that there's common
> agreement that this style is better.
> 
> Sascha
> 
Fixed in next version. Thanks.

Scott



From horms+renesas at verge.net.au  Thu Aug  6 19:11:31 2015
From: horms+renesas at verge.net.au (Simon Horman)
Date: Fri,  7 Aug 2015 11:11:31 +0900
Subject: [GIT PULL] Third Round of Renesas ARM Based SoC DT Updates for v4.3
Message-ID: <cover.1438911334.git.horms+renesas@verge.net.au>

Hi Olof, Hi Kevin, Hi Arnd,

Please consider these third round of Renesas ARM based SoC DT updates for v4.3.

This pull request is based on the previous round of
such requests, tagged as renesas-dt2-for-v4.3,
which I have already sent a pull-request for.


The following changes since commit 7fd6e11dca09b21efbe2b9db4eff08c8f4a16125:

  ARM: shmobile: r8a7791: Add Audio MIX support on DTSI (2015-07-22 09:36:49 +0900)

are available in the git repository at:

  git://git.kernel.org/pub/scm/linux/kernel/git/horms/renesas.git tags/renesas-dt3-for-v4.3

for you to fetch changes up to 94bdc48d55ca10f90b4a625f0e443197e0013557:

  ARM: shmobile: sh73a0 dtsi: Add missing "gpio-ranges" to gpio node (2015-08-05 06:39:28 +0900)

----------------------------------------------------------------
Third Round of Renesas ARM Based SoC DT Updates for v4.3

* Add JPU support: r8a7791 and r8a7790 SoCs
* Add MMCIF and PFC support: r8a7794 SoC
* Add initial support for r8a7794/silk
* Add missing "gpio-ranges" to gpio nodes: sh73a0, r8a7740 and r8a73a4 SoCs

----------------------------------------------------------------
Geert Uytterhoeven (3):
      ARM: shmobile: r8a73a4 dtsi: Add missing "gpio-ranges" to gpio node
      ARM: shmobile: r8a7740 dtsi: Add missing "gpio-ranges" to gpio node
      ARM: shmobile: sh73a0 dtsi: Add missing "gpio-ranges" to gpio node

Mikhail Ulyanov (2):
      ARM: shmobile: r8a7790: Add JPU device node.
      ARM: shmobile: r8a7791: Add JPU device node.

Sergei Shtylyov (5):
      ARM: shmobile: r8a7794: add PFC DT support
      ARM: shmobile: silk: initial device tree
      ARM: shmobile: silk: add Ether DT support
      ARM: shmobile: r8a7794: add MMCIF DT support
      ARM: shmobile: silk: add eMMC DT support

 arch/arm/boot/dts/Makefile         |   1 +
 arch/arm/boot/dts/r8a73a4.dtsi     |   7 +++
 arch/arm/boot/dts/r8a7740.dtsi     |   1 +
 arch/arm/boot/dts/r8a7790.dtsi     |   7 +++
 arch/arm/boot/dts/r8a7791.dtsi     |   7 +++
 arch/arm/boot/dts/r8a7794-silk.dts | 102 +++++++++++++++++++++++++++++++++++++
 arch/arm/boot/dts/r8a7794.dtsi     |  17 +++++++
 arch/arm/boot/dts/sh73a0.dtsi      |   3 ++
 8 files changed, 145 insertions(+)
 create mode 100644 arch/arm/boot/dts/r8a7794-silk.dts


From horms+renesas at verge.net.au  Thu Aug  6 19:11:25 2015
From: horms+renesas at verge.net.au (Simon Horman)
Date: Fri,  7 Aug 2015 11:11:25 +0900
Subject: [PATCH 01/10] ARM: shmobile: r8a7790: Add JPU device node.
In-Reply-To: <cover.1438911334.git.horms+renesas@verge.net.au>
References: <cover.1438911334.git.horms+renesas@verge.net.au>
Message-ID: <fb847575f8f5a9580c26bdc3e08fe49639144619.1438911334.git.horms+renesas@verge.net.au>

From: Mikhail Ulyanov <mikhail.ulyanov at cogentembedded.com>

This patch contains device tree node definition for JPEG codec peripheral
found in the Renesas R-Car r8a7790 SoC.

Signed-off-by: Mikhail Ulyanov <mikhail.ulyanov at cogentembedded.com>
Signed-off-by: Simon Horman <horms+renesas at verge.net.au>
---
 arch/arm/boot/dts/r8a7790.dtsi | 7 +++++++
 1 file changed, 7 insertions(+)

diff --git a/arch/arm/boot/dts/r8a7790.dtsi b/arch/arm/boot/dts/r8a7790.dtsi
index f1cdccc0a8c8..5b2952d5c700 100644
--- a/arch/arm/boot/dts/r8a7790.dtsi
+++ b/arch/arm/boot/dts/r8a7790.dtsi
@@ -872,6 +872,13 @@
 		status = "disabled";
 	};
 
+	jpu: jpeg-codec at fe980000 {
+		compatible = "renesas,jpu-r8a7790";
+		reg = <0 0xfe980000 0 0x10300>;
+		interrupts = <0 272 IRQ_TYPE_LEVEL_HIGH>;
+		clocks = <&mstp1_clks R8A7790_CLK_JPU>;
+	};
+
 	clocks {
 		#address-cells = <2>;
 		#size-cells = <2>;
-- 
2.1.4



From horms+renesas at verge.net.au  Thu Aug  6 19:11:26 2015
From: horms+renesas at verge.net.au (Simon Horman)
Date: Fri,  7 Aug 2015 11:11:26 +0900
Subject: [PATCH 02/10] ARM: shmobile: r8a7791: Add JPU device node.
In-Reply-To: <cover.1438911334.git.horms+renesas@verge.net.au>
References: <cover.1438911334.git.horms+renesas@verge.net.au>
Message-ID: <0caa36603300dd4ff4841227cf372e91e940c8bd.1438911334.git.horms+renesas@verge.net.au>

From: Mikhail Ulyanov <mikhail.ulyanov at cogentembedded.com>

This patch contains device tree node definition for JPEG codec peripheral
found in the Renesas R-Car r8a7791 SoC.

Signed-off-by: Mikhail Ulyanov <mikhail.ulyanov at cogentembedded.com>
Signed-off-by: Simon Horman <horms+renesas at verge.net.au>
---
 arch/arm/boot/dts/r8a7791.dtsi | 7 +++++++
 1 file changed, 7 insertions(+)

diff --git a/arch/arm/boot/dts/r8a7791.dtsi b/arch/arm/boot/dts/r8a7791.dtsi
index d37339bd7cdb..1cb6c2d07933 100644
--- a/arch/arm/boot/dts/r8a7791.dtsi
+++ b/arch/arm/boot/dts/r8a7791.dtsi
@@ -898,6 +898,13 @@
 		status = "disabled";
 	};
 
+	jpu: jpeg-codec at fe980000 {
+		compatible = "renesas,jpu-r8a7791";
+		reg = <0 0xfe980000 0 0x10300>;
+		interrupts = <0 272 IRQ_TYPE_LEVEL_HIGH>;
+		clocks = <&mstp1_clks R8A7791_CLK_JPU>;
+	};
+
 	clocks {
 		#address-cells = <2>;
 		#size-cells = <2>;
-- 
2.1.4



From horms+renesas at verge.net.au  Thu Aug  6 19:11:27 2015
From: horms+renesas at verge.net.au (Simon Horman)
Date: Fri,  7 Aug 2015 11:11:27 +0900
Subject: [PATCH 03/10] ARM: shmobile: r8a7794: add PFC DT support
In-Reply-To: <cover.1438911334.git.horms+renesas@verge.net.au>
References: <cover.1438911334.git.horms+renesas@verge.net.au>
Message-ID: <fd1683c18c372d51aeeeb25efa8b451f922c9c52.1438911334.git.horms+renesas@verge.net.au>

From: Sergei Shtylyov <sergei.shtylyov at cogentembedded.com>

Define the generic R8A7794 part of the PFC device node.

Based on original patch by Hisashi Nakamura <hisashi.nakamura.ak at renesas.com>.

Signed-off-by: Sergei Shtylyov <sergei.shtylyov at cogentembedded.com>
Acked-by: by: Geert Uytterhoeven <geert+renesas at glider.be>
Signed-off-by: Simon Horman <horms+renesas at verge.net.au>
---
 arch/arm/boot/dts/r8a7794.dtsi | 6 ++++++
 1 file changed, 6 insertions(+)

diff --git a/arch/arm/boot/dts/r8a7794.dtsi b/arch/arm/boot/dts/r8a7794.dtsi
index 8824dbd5dbb4..51cc2b975c3f 100644
--- a/arch/arm/boot/dts/r8a7794.dtsi
+++ b/arch/arm/boot/dts/r8a7794.dtsi
@@ -108,6 +108,12 @@
 		clocks = <&mstp4_clks R8A7794_CLK_IRQC>;
 	};
 
+	pfc: pin-controller at e6060000 {
+		compatible = "renesas,pfc-r8a7794";
+		reg = <0 0xe6060000 0 0x11c>;
+		#gpio-range-cells = <3>;
+	};
+
 	dmac0: dma-controller at e6700000 {
 		compatible = "renesas,rcar-dmac";
 		reg = <0 0xe6700000 0 0x20000>;
-- 
2.1.4



From horms+renesas at verge.net.au  Thu Aug  6 19:11:28 2015
From: horms+renesas at verge.net.au (Simon Horman)
Date: Fri,  7 Aug 2015 11:11:28 +0900
Subject: [PATCH 04/10] ARM: shmobile: silk: initial device tree
In-Reply-To: <cover.1438911334.git.horms+renesas@verge.net.au>
References: <cover.1438911334.git.horms+renesas@verge.net.au>
Message-ID: <a42fc57a9e9d1dbb1d8cc0c3ccf2d7ea1a939559.1438911334.git.horms+renesas@verge.net.au>

From: Sergei Shtylyov <sergei.shtylyov at cogentembedded.com>

Add the initial device  tree for the R8A7794 SoC based SILK low cost board.
SCIF2 serial port support is included, so that the serial console can work.

Based on the original patch by Vladimir Barinov
<vladimir.barinov at cogentembedded.com>.

Signed-off-by: Sergei Shtylyov <sergei.shtylyov at cogentembedded.com>
Signed-off-by: Simon Horman <horms+renesas at verge.net.au>
---
 arch/arm/boot/dts/Makefile         |  1 +
 arch/arm/boot/dts/r8a7794-silk.dts | 51 ++++++++++++++++++++++++++++++++++++++
 2 files changed, 52 insertions(+)
 create mode 100644 arch/arm/boot/dts/r8a7794-silk.dts

diff --git a/arch/arm/boot/dts/Makefile b/arch/arm/boot/dts/Makefile
index 679d7cc2f57c..c6e0befabada 100644
--- a/arch/arm/boot/dts/Makefile
+++ b/arch/arm/boot/dts/Makefile
@@ -518,6 +518,7 @@ dtb-$(CONFIG_ARCH_SHMOBILE_MULTI) += \
 	r8a7791-koelsch.dtb \
 	r8a7793-gose.dtb \
 	r8a7794-alt.dtb \
+	r8a7794-silk.dtb \
 	sh73a0-kzm9g.dtb
 dtb-$(CONFIG_ARCH_SOCFPGA) += \
 	socfpga_arria5_socdk.dtb \
diff --git a/arch/arm/boot/dts/r8a7794-silk.dts b/arch/arm/boot/dts/r8a7794-silk.dts
new file mode 100644
index 000000000000..f3da95b1dedd
--- /dev/null
+++ b/arch/arm/boot/dts/r8a7794-silk.dts
@@ -0,0 +1,51 @@
+/*
+ * Device Tree Source for the SILK board
+ *
+ * Copyright (C) 2014 Renesas Electronics Corporation
+ * Copyright (C) 2014-2015 Renesas Solutions Corp.
+ * Copyright (C) 2014-2015 Cogent Embedded, Inc.
+ *
+ * This file is licensed under the terms of the GNU General Public License
+ * version 2.  This program is licensed "as is" without any warranty of any
+ * kind, whether express or implied.
+ */
+
+/dts-v1/;
+#include "r8a7794.dtsi"
+
+/ {
+	model = "SILK";
+	compatible = "renesas,silk", "renesas,r8a7794";
+
+	aliases {
+		serial0 = &scif2;
+	};
+
+	chosen {
+		bootargs = "ignore_loglevel";
+		stdout-path = &scif2;
+	};
+
+	memory at 40000000 {
+		device_type = "memory";
+		reg = <0 0x40000000 0 0x40000000>;
+	};
+};
+
+&extal_clk {
+	clock-frequency = <20000000>;
+};
+
+&pfc {
+	scif2_pins: serial2 {
+		renesas,groups = "scif2_data";
+		renesas,function = "scif2";
+	};
+};
+
+&scif2 {
+	pinctrl-0 = <&scif2_pins>;
+	pinctrl-names = "default";
+
+	status = "okay";
+};
-- 
2.1.4



From horms+renesas at verge.net.au  Thu Aug  6 19:11:29 2015
From: horms+renesas at verge.net.au (Simon Horman)
Date: Fri,  7 Aug 2015 11:11:29 +0900
Subject: [PATCH 05/10] ARM: shmobile: silk: add Ether DT support
In-Reply-To: <cover.1438911334.git.horms+renesas@verge.net.au>
References: <cover.1438911334.git.horms+renesas@verge.net.au>
Message-ID: <dad5c83d71fcfa117ee678fe66ffa5fd2f1f2440.1438911334.git.horms+renesas@verge.net.au>

From: Sergei Shtylyov <sergei.shtylyov at cogentembedded.com>

Define the SILK board dependent part of the Ether device node.
Enable DHCP and NFS root for the kernel booting.

Based on the original patch by Vladimir Barinov
<vladimir.barinov at cogentembedded.com>.

Signed-off-by: Sergei Shtylyov <sergei.shtylyov at cogentembedded.com>
Signed-off-by: Simon Horman <horms+renesas at verge.net.au>
---
 arch/arm/boot/dts/r8a7794-silk.dts | 28 +++++++++++++++++++++++++++-
 1 file changed, 27 insertions(+), 1 deletion(-)

diff --git a/arch/arm/boot/dts/r8a7794-silk.dts b/arch/arm/boot/dts/r8a7794-silk.dts
index f3da95b1dedd..79bc64b94456 100644
--- a/arch/arm/boot/dts/r8a7794-silk.dts
+++ b/arch/arm/boot/dts/r8a7794-silk.dts
@@ -22,7 +22,7 @@
 	};
 
 	chosen {
-		bootargs = "ignore_loglevel";
+		bootargs = "ignore_loglevel rw root=/dev/nfs ip=dhcp";
 		stdout-path = &scif2;
 	};
 
@@ -41,6 +41,16 @@
 		renesas,groups = "scif2_data";
 		renesas,function = "scif2";
 	};
+
+	ether_pins: ether {
+		renesas,groups = "eth_link", "eth_mdio", "eth_rmii";
+		renesas,function = "eth";
+	};
+
+	phy1_pins: phy1 {
+		renesas,groups = "intc_irq8";
+		renesas,function = "intc";
+	};
 };
 
 &scif2 {
@@ -49,3 +59,19 @@
 
 	status = "okay";
 };
+
+&ether {
+	pinctrl-0 = <&ether_pins &phy1_pins>;
+	pinctrl-names = "default";
+
+	phy-handle = <&phy1>;
+	renesas,ether-link-active-low;
+	status = "okay";
+
+	phy1: ethernet-phy at 1 {
+		reg = <1>;
+		interrupt-parent = <&irqc0>;
+		interrupts = <8 IRQ_TYPE_LEVEL_LOW>;
+		micrel,led-mode = <1>;
+	};
+};
-- 
2.1.4



From horms+renesas at verge.net.au  Thu Aug  6 19:11:30 2015
From: horms+renesas at verge.net.au (Simon Horman)
Date: Fri,  7 Aug 2015 11:11:30 +0900
Subject: [PATCH 06/10] ARM: shmobile: r8a7794: add MMCIF DT support
In-Reply-To: <cover.1438911334.git.horms+renesas@verge.net.au>
References: <cover.1438911334.git.horms+renesas@verge.net.au>
Message-ID: <6cdf6ba19c8b9a386ef882206b29d97a49271317.1438911334.git.horms+renesas@verge.net.au>

From: Sergei Shtylyov <sergei.shtylyov at cogentembedded.com>

Define the generic R8A7794 part of the MMCIF0 device node.

Based on the orginal patch by Shinobu Uehara <shinobu.uehara.xc at renesas.com>.

Signed-off-by: Sergei Shtylyov <sergei.shtylyov at cogentembedded.com>
Signed-off-by: Simon Horman <horms+renesas at verge.net.au>
---
 arch/arm/boot/dts/r8a7794.dtsi | 11 +++++++++++
 1 file changed, 11 insertions(+)

diff --git a/arch/arm/boot/dts/r8a7794.dtsi b/arch/arm/boot/dts/r8a7794.dtsi
index 51cc2b975c3f..43acf185ecc4 100644
--- a/arch/arm/boot/dts/r8a7794.dtsi
+++ b/arch/arm/boot/dts/r8a7794.dtsi
@@ -383,6 +383,17 @@
 		status = "disabled";
 	};
 
+	mmcif0: mmc at ee200000 {
+		compatible = "renesas,mmcif-r8a7794", "renesas,sh-mmcif";
+		reg = <0 0xee200000 0 0x80>;
+		interrupts = <0 169 IRQ_TYPE_LEVEL_HIGH>;
+		clocks = <&mstp3_clks R8A7794_CLK_MMCIF0>;
+		dmas = <&dmac0 0xd1>, <&dmac0 0xd2>;
+		dma-names = "tx", "rx";
+		reg-io-width = <4>;
+		status = "disabled";
+	};
+
 	sdhi0: sd at ee100000 {
 		compatible = "renesas,sdhi-r8a7794";
 		reg = <0 0xee100000 0 0x200>;
-- 
2.1.4



From horms+renesas at verge.net.au  Thu Aug  6 19:11:31 2015
From: horms+renesas at verge.net.au (Simon Horman)
Date: Fri,  7 Aug 2015 11:11:31 +0900
Subject: [PATCH 07/10] ARM: shmobile: silk: add eMMC DT support
In-Reply-To: <cover.1438911334.git.horms+renesas@verge.net.au>
References: <cover.1438911334.git.horms+renesas@verge.net.au>
Message-ID: <054531e7a5cb195140bead068b51cc6147c5c8bf.1438911334.git.horms+renesas@verge.net.au>

From: Sergei Shtylyov <sergei.shtylyov at cogentembedded.com>

Define the SILK board dependent part of the MMCIF device node (the board has
eMMC chip) along with the  necessary voltage regulator (note that the Vcc/Vccq
regulator is dummy -- it's required by the MMCIF driver but doesn't actually
exist on the board).

Based on the original patch by Vladimir Barinov
<vladimir.barinov at cogentembedded.com>.

Signed-off-by: Sergei Shtylyov <sergei.shtylyov at cogentembedded.com>
Signed-off-by: Simon Horman <horms+renesas at verge.net.au>
---
 arch/arm/boot/dts/r8a7794-silk.dts | 25 +++++++++++++++++++++++++
 1 file changed, 25 insertions(+)

diff --git a/arch/arm/boot/dts/r8a7794-silk.dts b/arch/arm/boot/dts/r8a7794-silk.dts
index 79bc64b94456..d4dd5a30ccdf 100644
--- a/arch/arm/boot/dts/r8a7794-silk.dts
+++ b/arch/arm/boot/dts/r8a7794-silk.dts
@@ -30,6 +30,15 @@
 		device_type = "memory";
 		reg = <0 0x40000000 0 0x40000000>;
 	};
+
+	d3_3v: regulator at 0 {
+		compatible = "regulator-fixed";
+		regulator-name = "D3.3V";
+		regulator-min-microvolt = <3300000>;
+		regulator-max-microvolt = <3300000>;
+		regulator-boot-on;
+		regulator-always-on;
+	};
 };
 
 &extal_clk {
@@ -51,6 +60,11 @@
 		renesas,groups = "intc_irq8";
 		renesas,function = "intc";
 	};
+
+	mmcif0_pins: mmcif0 {
+		renesas,groups = "mmc_data8", "mmc_ctrl";
+		renesas,function = "mmc";
+	};
 };
 
 &scif2 {
@@ -75,3 +89,14 @@
 		micrel,led-mode = <1>;
 	};
 };
+
+&mmcif0 {
+	pinctrl-0 = <&mmcif0_pins>;
+	pinctrl-names = "default";
+
+	vmmc-supply = <&d3_3v>;
+	vqmmc-supply = <&d3_3v>;
+	bus-width = <8>;
+	non-removable;
+	status = "okay";
+};
-- 
2.1.4



From horms+renesas at verge.net.au  Thu Aug  6 19:11:32 2015
From: horms+renesas at verge.net.au (Simon Horman)
Date: Fri,  7 Aug 2015 11:11:32 +0900
Subject: [PATCH 08/10] ARM: shmobile: r8a73a4 dtsi: Add missing "gpio-ranges"
 to gpio node
In-Reply-To: <cover.1438911334.git.horms+renesas@verge.net.au>
References: <cover.1438911334.git.horms+renesas@verge.net.au>
Message-ID: <17ccec50cc40bef00b26d506d483e928804cb20e.1438911334.git.horms+renesas@verge.net.au>

From: Geert Uytterhoeven <geert+renesas at glider.be>

If a GPIO driver uses gpiochip_add_pin_range() (which is usually the
case for GPIO/PFC combos), the GPIO hogging mechanism configured from DT
doesn't work:

    requesting hog GPIO led1-high (chip r8a73a4_pfc, offset 28) failed

The actual error code is -517 == -EPROBE_DEFER.

The problem is that PFC+GPIO registration is handled in multiple steps:
  1. pinctrl_register(),
  2. gpiochip_add(),
  3. gpiochip_add_pin_range().

Configuration of the hogs is handled in gpiochip_add():

    gpiochip_add
        of_gpiochip_add
            of_gpiochip_scan_hogs
                gpiod_hog
                    gpiochip_request_own_desc
                        __gpiod_request
                            chip->request
                                pinctrl_request_gpio
                                    pinctrl_get_device_gpio_range

However, at this point the GPIO controller hasn't been added to
pinctrldev_list yet, so the range can't be found, and the operation fails
with -EPROBE_DEFER.

To fix this, add a "gpio-ranges" property to the gpio device node, so
the ranges are added by of_gpiochip_add_pin_range(), which is called by
of_gpiochip_add() before the call to of_gpiochip_scan_hogs().

Signed-off-by: Geert Uytterhoeven <geert+renesas at glider.be>
Acked-by: Laurent Pinchart <laurent.pinchart at ideasonboard.com>
Acked-by: Linus Walleij <linus.walleij at linaro.org>
Signed-off-by: Simon Horman <horms+renesas at verge.net.au>
---
 arch/arm/boot/dts/r8a73a4.dtsi | 7 +++++++
 1 file changed, 7 insertions(+)

diff --git a/arch/arm/boot/dts/r8a73a4.dtsi b/arch/arm/boot/dts/r8a73a4.dtsi
index 5090d1a8f652..cb4f7b2798fe 100644
--- a/arch/arm/boot/dts/r8a73a4.dtsi
+++ b/arch/arm/boot/dts/r8a73a4.dtsi
@@ -207,6 +207,13 @@
 		reg = <0 0xe6050000 0 0x9000>;
 		gpio-controller;
 		#gpio-cells = <2>;
+		gpio-ranges =
+			<&pfc 0 0 31>, <&pfc 32 32 9>,
+			<&pfc 64 64 22>, <&pfc 96 96 31>,
+			<&pfc 128 128 7>, <&pfc 160 160 19>,
+			<&pfc 192 192 31>, <&pfc 224 224 27>,
+			<&pfc 256 256 28>, <&pfc 288 288 21>,
+			<&pfc 320 320 10>;
 		interrupts-extended =
 			<&irqc0  0 0>, <&irqc0  1 0>, <&irqc0  2 0>, <&irqc0  3 0>,
 			<&irqc0  4 0>, <&irqc0  5 0>, <&irqc0  6 0>, <&irqc0  7 0>,
-- 
2.1.4



From horms+renesas at verge.net.au  Thu Aug  6 19:11:33 2015
From: horms+renesas at verge.net.au (Simon Horman)
Date: Fri,  7 Aug 2015 11:11:33 +0900
Subject: [PATCH 09/10] ARM: shmobile: r8a7740 dtsi: Add missing "gpio-ranges"
 to gpio node
In-Reply-To: <cover.1438911334.git.horms+renesas@verge.net.au>
References: <cover.1438911334.git.horms+renesas@verge.net.au>
Message-ID: <09d1c7b4babd3ef9bfc0a148931e5e5702db5e1b.1438911334.git.horms+renesas@verge.net.au>

From: Geert Uytterhoeven <geert+renesas at glider.be>

If a GPIO driver uses gpiochip_add_pin_range() (which is usually the
case for GPIO/PFC combos), the GPIO hogging mechanism configured from DT
doesn't work:

    requesting hog GPIO lcd0 (chip r8a7740_pfc, offset 176) failed

The actual error code is -517 == -EPROBE_DEFER.

The problem is that PFC+GPIO registration is handled in multiple steps:
  1. pinctrl_register(),
  2. gpiochip_add(),
  3. gpiochip_add_pin_range().

Configuration of the hogs is handled in gpiochip_add():

    gpiochip_add
        of_gpiochip_add
            of_gpiochip_scan_hogs
                gpiod_hog
                    gpiochip_request_own_desc
                        __gpiod_request
                            chip->request
                                pinctrl_request_gpio
                                    pinctrl_get_device_gpio_range

However, at this point the GPIO controller hasn't been added to
pinctrldev_list yet, so the range can't be found, and the operation fails
with -EPROBE_DEFER.

To fix this, add a "gpio-ranges" property to the gpio device node, so
the range is added by of_gpiochip_add_pin_range(), which is called by
of_gpiochip_add() before the call to of_gpiochip_scan_hogs().

Signed-off-by: Geert Uytterhoeven <geert+renesas at glider.be>
Acked-by: Laurent Pinchart <laurent.pinchart at ideasonboard.com>
Acked-by: Linus Walleij <linus.walleij at linaro.org>
Signed-off-by: Simon Horman <horms+renesas at verge.net.au>
---
 arch/arm/boot/dts/r8a7740.dtsi | 1 +
 1 file changed, 1 insertion(+)

diff --git a/arch/arm/boot/dts/r8a7740.dtsi b/arch/arm/boot/dts/r8a7740.dtsi
index d84714468cce..e14cb1438216 100644
--- a/arch/arm/boot/dts/r8a7740.dtsi
+++ b/arch/arm/boot/dts/r8a7740.dtsi
@@ -291,6 +291,7 @@
 		      <0xe605800c 0x20>;
 		gpio-controller;
 		#gpio-cells = <2>;
+		gpio-ranges = <&pfc 0 0 212>;
 		interrupts-extended =
 			<&irqpin0 0 0>, <&irqpin0 1 0>, <&irqpin0 2 0>, <&irqpin0 3 0>,
 			<&irqpin0 4 0>, <&irqpin0 5 0>, <&irqpin0 6 0>, <&irqpin0 7 0>,
-- 
2.1.4



From horms+renesas at verge.net.au  Thu Aug  6 19:11:34 2015
From: horms+renesas at verge.net.au (Simon Horman)
Date: Fri,  7 Aug 2015 11:11:34 +0900
Subject: [PATCH 10/10] ARM: shmobile: sh73a0 dtsi: Add missing "gpio-ranges"
 to gpio node
In-Reply-To: <cover.1438911334.git.horms+renesas@verge.net.au>
References: <cover.1438911334.git.horms+renesas@verge.net.au>
Message-ID: <94bdc48d55ca10f90b4a625f0e443197e0013557.1438911334.git.horms+renesas@verge.net.au>

From: Geert Uytterhoeven <geert+renesas at glider.be>

If a GPIO driver uses gpiochip_add_pin_range() (which is usually the
case for GPIO/PFC combos), the GPIO hogging mechanism configured from DT
doesn't work:

    requesting hog GPIO led1-high (chip sh73a0_pfc, offset 20) failed

The actual error code is -517 == -EPROBE_DEFER.

The problem is that PFC+GPIO registration is handled in multiple steps:
  1. pinctrl_register(),
  2. gpiochip_add(),
  3. gpiochip_add_pin_range().

Configuration of the hogs is handled in gpiochip_add():

    gpiochip_add
        of_gpiochip_add
            of_gpiochip_scan_hogs
                gpiod_hog
                    gpiochip_request_own_desc
                        __gpiod_request
                            chip->request
                                pinctrl_request_gpio
                                    pinctrl_get_device_gpio_range

However, at this point the GPIO controller hasn't been added to
pinctrldev_list yet, so the range can't be found, and the operation fails
with -EPROBE_DEFER.

To fix this, add a "gpio-ranges" property to the gpio device node, so
the ranges are added by of_gpiochip_add_pin_range(), which is called by
of_gpiochip_add() before the call to of_gpiochip_scan_hogs().

Signed-off-by: Geert Uytterhoeven <geert+renesas at glider.be>
Acked-by: Laurent Pinchart <laurent.pinchart at ideasonboard.com>
Acked-by: Linus Walleij <linus.walleij at linaro.org>
Signed-off-by: Simon Horman <horms+renesas at verge.net.au>
---
 arch/arm/boot/dts/sh73a0.dtsi | 3 +++
 1 file changed, 3 insertions(+)

diff --git a/arch/arm/boot/dts/sh73a0.dtsi b/arch/arm/boot/dts/sh73a0.dtsi
index 11e17c5f26e2..ff7c8f298f30 100644
--- a/arch/arm/boot/dts/sh73a0.dtsi
+++ b/arch/arm/boot/dts/sh73a0.dtsi
@@ -392,6 +392,9 @@
 		      <0xe605801c 0x1c>;
 		gpio-controller;
 		#gpio-cells = <2>;
+		gpio-ranges =
+			<&pfc 0 0 119>, <&pfc 128 128 37>, <&pfc 192 192 91>,
+			<&pfc 288 288 22>;
 		interrupts-extended =
 			<&irqpin0 0 0>, <&irqpin0 1 0>, <&irqpin0 2 0>, <&irqpin0 3 0>,
 			<&irqpin0 4 0>, <&irqpin0 5 0>, <&irqpin0 6 0>, <&irqpin0 7 0>,
-- 
2.1.4



From horms+renesas at verge.net.au  Thu Aug  6 19:12:03 2015
From: horms+renesas at verge.net.au (Simon Horman)
Date: Fri,  7 Aug 2015 11:12:03 +0900
Subject: [GIT PULL] Renesas ARM Based SoC CPG MSTP Clock Domain Updates for
 v4.3
Message-ID: <cover.1438911559.git.horms+renesas@verge.net.au>

Hi Olof, Hi Kevin, Hi Arnd,

Please consider these Renesas ARM based SoC CPG MSTP clock domain updates
for v4.3.

This pull request is based on "Third Round of Renesas ARM Based SoC DT
Updates for v4.3", tagged as renesas-dt3-for-v4.3, which I have also sent a
pull-request for.

The reason for that base is that the DT changes in this series update nodes
added in that tag.

This series begins with driver changes and follows up with DT changes.
The latter depend on the former.


The following changes since commit 94bdc48d55ca10f90b4a625f0e443197e0013557:

  ARM: shmobile: sh73a0 dtsi: Add missing "gpio-ranges" to gpio node (2015-08-05 06:39:28 +0900)

are available in the git repository at:

  git://git.kernel.org/pub/scm/linux/kernel/git/horms/renesas.git tags/renesas-cpg-mstp-clock-domain-for-v4.3

for you to fetch changes up to 2daa8a5a8c0994893c2ca456303f0bf53e881cb9:

  ARM: shmobile: r8a7794 dtsi: Add CPG/MSTP Clock Domain (2015-08-05 06:42:51 +0900)

----------------------------------------------------------------
Renesas ARM Based SoC CPG MSTP Clock Domain Updates for v4.3

* Add Clock Domain support to the Clock Pulse Generator
  (CPG) Module Stop (MSTP) Clocks driver using the generic PM Domain.

----------------------------------------------------------------
Geert Uytterhoeven (12):
      clk: shmobile: Add CPG/MSTP Clock Domain support
      clk: shmobile: r8a7778: Add CPG/MSTP Clock Domain support
      clk: shmobile: r8a7779: Add CPG/MSTP Clock Domain support
      clk: shmobile: rcar-gen2: Add CPG/MSTP Clock Domain support
      clk: shmobile: rz: Add CPG/MSTP Clock Domain support
      ARM: shmobile: r7s72100 dtsi: Add CPG/MSTP Clock Domain
      ARM: shmobile: r8a7778 dtsi: Add CPG/MSTP Clock Domain
      ARM: shmobile: r8a7779 dtsi: Add CPG/MSTP Clock Domain
      ARM: shmobile: r8a7790 dtsi: Add CPG/MSTP Clock Domain
      ARM: shmobile: r8a7791 dtsi: Add CPG/MSTP Clock Domain
      ARM: shmobile: r8a7793 dtsi: Add CPG/MSTP Clock Domain
      ARM: shmobile: r8a7794 dtsi: Add CPG/MSTP Clock Domain

 .../bindings/clock/renesas,r8a7778-cpg-clocks.txt  | 29 ++++++-
 .../bindings/clock/renesas,r8a7779-cpg-clocks.txt  | 30 +++++++-
 .../clock/renesas,rcar-gen2-cpg-clocks.txt         | 26 ++++++-
 .../bindings/clock/renesas,rz-cpg-clocks.txt       | 29 ++++++-
 arch/arm/boot/dts/r7s72100.dtsi                    | 19 +++++
 arch/arm/boot/dts/r8a7778.dtsi                     | 22 ++++++
 arch/arm/boot/dts/r8a7779.dtsi                     | 23 ++++++
 arch/arm/boot/dts/r8a7790.dtsi                     | 86 ++++++++++++++++++---
 arch/arm/boot/dts/r8a7791.dtsi                     | 88 ++++++++++++++++++++--
 arch/arm/boot/dts/r8a7793.dtsi                     |  7 ++
 arch/arm/boot/dts/r8a7794.dtsi                     | 29 +++++++
 arch/arm/mach-shmobile/Kconfig                     |  2 +
 drivers/clk/shmobile/clk-mstp.c                    | 87 +++++++++++++++++++++
 drivers/clk/shmobile/clk-r8a7778.c                 |  2 +
 drivers/clk/shmobile/clk-r8a7779.c                 |  2 +
 drivers/clk/shmobile/clk-rcar-gen2.c               |  2 +
 drivers/clk/shmobile/clk-rz.c                      |  3 +
 include/linux/clk/shmobile.h                       | 12 +++
 18 files changed, 470 insertions(+), 28 deletions(-)


From horms+renesas at verge.net.au  Thu Aug  6 19:12:00 2015
From: horms+renesas at verge.net.au (Simon Horman)
Date: Fri,  7 Aug 2015 11:12:00 +0900
Subject: [PATCH 01/12] clk: shmobile: Add CPG/MSTP Clock Domain support
In-Reply-To: <cover.1438911559.git.horms+renesas@verge.net.au>
References: <cover.1438911559.git.horms+renesas@verge.net.au>
Message-ID: <c9c437479e6434d4ebfe244143a5760efd705ef3.1438911559.git.horms+renesas@verge.net.au>

From: Geert Uytterhoeven <geert+renesas at glider.be>

Add Clock Domain support to the Clock Pulse Generator (CPG) Module Stop
(MSTP) Clocks driver using the generic PM Domain.  This allows to
power-manage the module clocks of SoC devices that are part of the
CPG/MSTP Clock Domain using Runtime PM, or for system suspend/resume.

SoC devices that are part of the CPG/MSTP Clock Domain and can be
power-managed through an MSTP clock should be tagged in DT with a
proper "power-domains" property.

The CPG/MSTP Clock Domain code will scan such devices for clocks that
are suitable for power-managing the device, by looking for a clock that
is compatible with "renesas,cpg-mstp-clocks".

Signed-off-by: Geert Uytterhoeven <geert+renesas at glider.be>
Acked-by: Laurent Pinchart <laurent.pinchart at ideasonboard.com>
Acked-by: Stephen Boyd <sboyd at codeaurora.org>
Reviewed-by: Ulf Hansson <ulf.hansson at linaro.org>
Reviewed-by: Kevin Hilman <khilman at linaro.org>
Signed-off-by: Simon Horman <horms+renesas at verge.net.au>
---
 drivers/clk/shmobile/clk-mstp.c | 87 +++++++++++++++++++++++++++++++++++++++++
 include/linux/clk/shmobile.h    | 12 ++++++
 2 files changed, 99 insertions(+)

diff --git a/drivers/clk/shmobile/clk-mstp.c b/drivers/clk/shmobile/clk-mstp.c
index 2d2fe773ac81..b1df7b2f1e97 100644
--- a/drivers/clk/shmobile/clk-mstp.c
+++ b/drivers/clk/shmobile/clk-mstp.c
@@ -2,6 +2,7 @@
  * R-Car MSTP clocks
  *
  * Copyright (C) 2013 Ideas On Board SPRL
+ * Copyright (C) 2015 Glider bvba
  *
  * Contact: Laurent Pinchart <laurent.pinchart at ideasonboard.com>
  *
@@ -10,11 +11,16 @@
  * the Free Software Foundation; version 2 of the License.
  */
 
+#include <linux/clk.h>
 #include <linux/clk-provider.h>
 #include <linux/clkdev.h>
+#include <linux/clk/shmobile.h>
+#include <linux/device.h>
 #include <linux/io.h>
 #include <linux/of.h>
 #include <linux/of_address.h>
+#include <linux/pm_clock.h>
+#include <linux/pm_domain.h>
 #include <linux/spinlock.h>
 
 /*
@@ -236,3 +242,84 @@ static void __init cpg_mstp_clocks_init(struct device_node *np)
 	of_clk_add_provider(np, of_clk_src_onecell_get, &group->data);
 }
 CLK_OF_DECLARE(cpg_mstp_clks, "renesas,cpg-mstp-clocks", cpg_mstp_clocks_init);
+
+
+#ifdef CONFIG_PM_GENERIC_DOMAINS_OF
+int cpg_mstp_attach_dev(struct generic_pm_domain *domain, struct device *dev)
+{
+	struct device_node *np = dev->of_node;
+	struct of_phandle_args clkspec;
+	struct clk *clk;
+	int i = 0;
+	int error;
+
+	while (!of_parse_phandle_with_args(np, "clocks", "#clock-cells", i,
+					   &clkspec)) {
+		if (of_device_is_compatible(clkspec.np,
+					    "renesas,cpg-mstp-clocks"))
+			goto found;
+
+		of_node_put(clkspec.np);
+		i++;
+	}
+
+	return 0;
+
+found:
+	clk = of_clk_get_from_provider(&clkspec);
+	of_node_put(clkspec.np);
+
+	if (IS_ERR(clk))
+		return PTR_ERR(clk);
+
+	error = pm_clk_create(dev);
+	if (error) {
+		dev_err(dev, "pm_clk_create failed %d\n", error);
+		goto fail_put;
+	}
+
+	error = pm_clk_add_clk(dev, clk);
+	if (error) {
+		dev_err(dev, "pm_clk_add_clk %pC failed %d\n", clk, error);
+		goto fail_destroy;
+	}
+
+	return 0;
+
+fail_destroy:
+	pm_clk_destroy(dev);
+fail_put:
+	clk_put(clk);
+	return error;
+}
+
+void cpg_mstp_detach_dev(struct generic_pm_domain *domain, struct device *dev)
+{
+	if (!list_empty(&dev->power.subsys_data->clock_list))
+		pm_clk_destroy(dev);
+}
+
+void __init cpg_mstp_add_clk_domain(struct device_node *np)
+{
+	struct generic_pm_domain *pd;
+	u32 ncells;
+
+	if (of_property_read_u32(np, "#power-domain-cells", &ncells)) {
+		pr_warn("%s lacks #power-domain-cells\n", np->full_name);
+		return;
+	}
+
+	pd = kzalloc(sizeof(*pd), GFP_KERNEL);
+	if (!pd)
+		return;
+
+	pd->name = np->name;
+
+	pd->flags = GENPD_FLAG_PM_CLK;
+	pm_genpd_init(pd, &simple_qos_governor, false);
+	pd->attach_dev = cpg_mstp_attach_dev;
+	pd->detach_dev = cpg_mstp_detach_dev;
+
+	of_genpd_add_provider_simple(np, pd);
+}
+#endif /* !CONFIG_PM_GENERIC_DOMAINS_OF */
diff --git a/include/linux/clk/shmobile.h b/include/linux/clk/shmobile.h
index 63a8159c4e64..cb19cc1865ca 100644
--- a/include/linux/clk/shmobile.h
+++ b/include/linux/clk/shmobile.h
@@ -16,8 +16,20 @@
 
 #include <linux/types.h>
 
+struct device;
+struct device_node;
+struct generic_pm_domain;
+
 void r8a7778_clocks_init(u32 mode);
 void r8a7779_clocks_init(u32 mode);
 void rcar_gen2_clocks_init(u32 mode);
 
+#ifdef CONFIG_PM_GENERIC_DOMAINS_OF
+void cpg_mstp_add_clk_domain(struct device_node *np);
+int cpg_mstp_attach_dev(struct generic_pm_domain *domain, struct device *dev);
+void cpg_mstp_detach_dev(struct generic_pm_domain *domain, struct device *dev);
+#else
+static inline void cpg_mstp_add_clk_domain(struct device_node *np) {}
+#endif
+
 #endif
-- 
2.1.4



From horms+renesas at verge.net.au  Thu Aug  6 19:12:01 2015
From: horms+renesas at verge.net.au (Simon Horman)
Date: Fri,  7 Aug 2015 11:12:01 +0900
Subject: [PATCH 02/12] clk: shmobile: r8a7778: Add CPG/MSTP Clock Domain
 support
In-Reply-To: <cover.1438911559.git.horms+renesas@verge.net.au>
References: <cover.1438911559.git.horms+renesas@verge.net.au>
Message-ID: <790fc2951ca6efff4a9fd9f2f7e6c3fe06053e6c.1438911559.git.horms+renesas@verge.net.au>

From: Geert Uytterhoeven <geert+renesas at glider.be>

Add Clock Domain support to the R-Car M1A Clock Pulse Generator (CPG)
driver using the generic PM Domain.  This allows to power-manage the
module clocks of SoC devices that are part of the CPG/MSTP Clock Domain
using Runtime PM, or for system suspend/resume.

SoC devices that are part of the CPG/MSTP Clock Domain and can be
power-managed through an MSTP clock should be tagged in DT with a proper
"power-domains" property.

Signed-off-by: Geert Uytterhoeven <geert+renesas at glider.be>
Acked-by: Stephen Boyd <sboyd at codeaurora.org>
Reviewed-by: Ulf Hansson <ulf.hansson at linaro.org>
Signed-off-by: Simon Horman <horms+renesas at verge.net.au>
---
 .../bindings/clock/renesas,r8a7778-cpg-clocks.txt  | 29 +++++++++++++++++++---
 arch/arm/mach-shmobile/Kconfig                     |  1 +
 drivers/clk/shmobile/clk-r8a7778.c                 |  2 ++
 3 files changed, 29 insertions(+), 3 deletions(-)

diff --git a/Documentation/devicetree/bindings/clock/renesas,r8a7778-cpg-clocks.txt b/Documentation/devicetree/bindings/clock/renesas,r8a7778-cpg-clocks.txt
index 2f3747fdcf1c..e4cdaf1cb333 100644
--- a/Documentation/devicetree/bindings/clock/renesas,r8a7778-cpg-clocks.txt
+++ b/Documentation/devicetree/bindings/clock/renesas,r8a7778-cpg-clocks.txt
@@ -1,7 +1,9 @@
 * Renesas R8A7778 Clock Pulse Generator (CPG)
 
 The CPG generates core clocks for the R8A7778. It includes two PLLs and
-several fixed ratio dividers
+several fixed ratio dividers.
+The CPG also provides a Clock Domain for SoC devices, in combination with the
+CPG Module Stop (MSTP) Clocks.
 
 Required Properties:
 
@@ -10,10 +12,18 @@ Required Properties:
   - #clock-cells: Must be 1
   - clock-output-names: The names of the clocks. Supported clocks are
     "plla", "pllb", "b", "out", "p", "s", and "s1".
+  - #power-domain-cells: Must be 0
 
+SoC devices that are part of the CPG/MSTP Clock Domain and can be power-managed
+through an MSTP clock should refer to the CPG device node in their
+"power-domains" property, as documented by the generic PM domain bindings in
+Documentation/devicetree/bindings/power/power_domain.txt.
 
-Example
--------
+
+Examples
+--------
+
+  - CPG device node:
 
 	cpg_clocks: cpg_clocks at ffc80000 {
 		compatible = "renesas,r8a7778-cpg-clocks";
@@ -22,4 +32,17 @@ Example
 		clocks = <&extal_clk>;
 		clock-output-names = "plla", "pllb", "b",
 				     "out", "p", "s", "s1";
+		#power-domain-cells = <0>;
+	};
+
+
+  - CPG/MSTP Clock Domain member device node:
+
+	sdhi0: sd at ffe4c000 {
+		compatible = "renesas,sdhi-r8a7778";
+		reg = <0xffe4c000 0x100>;
+		interrupts = <0 87 IRQ_TYPE_LEVEL_HIGH>;
+		clocks = <&mstp3_clks R8A7778_CLK_SDHI0>;
+		power-domains = <&cpg_clocks>;
+		status = "disabled";
 	};
diff --git a/arch/arm/mach-shmobile/Kconfig b/arch/arm/mach-shmobile/Kconfig
index 45006479d461..e14fa5e87475 100644
--- a/arch/arm/mach-shmobile/Kconfig
+++ b/arch/arm/mach-shmobile/Kconfig
@@ -4,6 +4,7 @@ config ARCH_SHMOBILE
 
 config PM_RCAR
 	bool
+	select PM_GENERIC_DOMAINS if PM
 
 config PM_RMOBILE
 	bool
diff --git a/drivers/clk/shmobile/clk-r8a7778.c b/drivers/clk/shmobile/clk-r8a7778.c
index cb33b57274bf..fa45684e220c 100644
--- a/drivers/clk/shmobile/clk-r8a7778.c
+++ b/drivers/clk/shmobile/clk-r8a7778.c
@@ -124,6 +124,8 @@ static void __init r8a7778_cpg_clocks_init(struct device_node *np)
 	}
 
 	of_clk_add_provider(np, of_clk_src_onecell_get, &cpg->data);
+
+	cpg_mstp_add_clk_domain(np);
 }
 
 CLK_OF_DECLARE(r8a7778_cpg_clks, "renesas,r8a7778-cpg-clocks",
-- 
2.1.4



From horms+renesas at verge.net.au  Thu Aug  6 19:12:02 2015
From: horms+renesas at verge.net.au (Simon Horman)
Date: Fri,  7 Aug 2015 11:12:02 +0900
Subject: [PATCH 03/12] clk: shmobile: r8a7779: Add CPG/MSTP Clock Domain
 support
In-Reply-To: <cover.1438911559.git.horms+renesas@verge.net.au>
References: <cover.1438911559.git.horms+renesas@verge.net.au>
Message-ID: <38d37c53d6e475d0660626cbb349c3fe28354602.1438911559.git.horms+renesas@verge.net.au>

From: Geert Uytterhoeven <geert+renesas at glider.be>

Add Clock Domain support to the R-Car H1 Clock Pulse Generator (CPG)
driver using the generic PM Domain.  This allows to power-manage the
module clocks of SoC devices that are part of the CPG/MSTP Clock Domain
using Runtime PM, or for system suspend/resume.

SoC devices that are part of the CPG/MSTP Clock Domain and can be
power-managed through an MSTP clock should be tagged in DT with a proper
"power-domains" property.

Also update the reg property in the DT binding doc example to match the
actual dtsi, which uses #address-cells and #size-cells == 1, not 2.

Signed-off-by: Geert Uytterhoeven <geert+renesas at glider.be>
Acked-by: Stephen Boyd <sboyd at codeaurora.org>
Reviewed-by: Ulf Hansson <ulf.hansson at linaro.org>
Signed-off-by: Simon Horman <horms+renesas at verge.net.au>
---
 .../bindings/clock/renesas,r8a7779-cpg-clocks.txt  | 30 +++++++++++++++++++---
 drivers/clk/shmobile/clk-r8a7779.c                 |  2 ++
 2 files changed, 28 insertions(+), 4 deletions(-)

diff --git a/Documentation/devicetree/bindings/clock/renesas,r8a7779-cpg-clocks.txt b/Documentation/devicetree/bindings/clock/renesas,r8a7779-cpg-clocks.txt
index ed3c8cb12f4e..8c81547c29f5 100644
--- a/Documentation/devicetree/bindings/clock/renesas,r8a7779-cpg-clocks.txt
+++ b/Documentation/devicetree/bindings/clock/renesas,r8a7779-cpg-clocks.txt
@@ -1,7 +1,9 @@
 * Renesas R8A7779 Clock Pulse Generator (CPG)
 
 The CPG generates core clocks for the R8A7779. It includes one PLL and
-several fixed ratio dividers
+several fixed ratio dividers.
+The CPG also provides a Clock Domain for SoC devices, in combination with the
+CPG Module Stop (MSTP) Clocks.
 
 Required Properties:
 
@@ -12,16 +14,36 @@ Required Properties:
   - #clock-cells: Must be 1
   - clock-output-names: The names of the clocks. Supported clocks are "plla",
     "z", "zs", "s", "s1", "p", "b", "out".
+  - #power-domain-cells: Must be 0
 
+SoC devices that are part of the CPG/MSTP Clock Domain and can be power-managed
+through an MSTP clock should refer to the CPG device node in their
+"power-domains" property, as documented by the generic PM domain bindings in
+Documentation/devicetree/bindings/power/power_domain.txt.
 
-Example
--------
+
+Examples
+--------
+
+  - CPG device node:
 
 	cpg_clocks: cpg_clocks at ffc80000 {
 		compatible = "renesas,r8a7779-cpg-clocks";
-		reg = <0 0xffc80000 0 0x30>;
+		reg = <0xffc80000 0x30>;
 		clocks = <&extal_clk>;
 		#clock-cells = <1>;
 		clock-output-names = "plla", "z", "zs", "s", "s1", "p",
 		                     "b", "out";
+		#power-domain-cells = <0>;
+	};
+
+
+  - CPG/MSTP Clock Domain member device node:
+
+	sata: sata at fc600000 {
+		compatible = "renesas,sata-r8a7779", "renesas,rcar-sata";
+		reg = <0xfc600000 0x2000>;
+		interrupts = <0 100 IRQ_TYPE_LEVEL_HIGH>;
+		clocks = <&mstp1_clks R8A7779_CLK_SATA>;
+		power-domains = <&cpg_clocks>;
 	};
diff --git a/drivers/clk/shmobile/clk-r8a7779.c b/drivers/clk/shmobile/clk-r8a7779.c
index 652ecacb6daf..e42a63a2ad25 100644
--- a/drivers/clk/shmobile/clk-r8a7779.c
+++ b/drivers/clk/shmobile/clk-r8a7779.c
@@ -168,6 +168,8 @@ static void __init r8a7779_cpg_clocks_init(struct device_node *np)
 	}
 
 	of_clk_add_provider(np, of_clk_src_onecell_get, &cpg->data);
+
+	cpg_mstp_add_clk_domain(np);
 }
 CLK_OF_DECLARE(r8a7779_cpg_clks, "renesas,r8a7779-cpg-clocks",
 	       r8a7779_cpg_clocks_init);
-- 
2.1.4



From horms+renesas at verge.net.au  Thu Aug  6 19:12:03 2015
From: horms+renesas at verge.net.au (Simon Horman)
Date: Fri,  7 Aug 2015 11:12:03 +0900
Subject: [PATCH 04/12] clk: shmobile: rcar-gen2: Add CPG/MSTP Clock Domain
 support
In-Reply-To: <cover.1438911559.git.horms+renesas@verge.net.au>
References: <cover.1438911559.git.horms+renesas@verge.net.au>
Message-ID: <713290fcd73b31d0517c5c6ec505b612e93d1662.1438911559.git.horms+renesas@verge.net.au>

From: Geert Uytterhoeven <geert+renesas at glider.be>

Add Clock Domain support to the R-Car Gen2 Clock Pulse Generator (CPG)
driver using the generic PM Domain.  This allows to power-manage the
module clocks of SoC devices that are part of the CPG/MSTP Clock Domain
using Runtime PM, or for system suspend/resume.

SoC devices that are part of the CPG/MSTP Clock Domain and can be
power-managed through an MSTP clock should be tagged in DT with a proper
"power-domains" property.

Signed-off-by: Geert Uytterhoeven <geert+renesas at glider.be>
Acked-by: Stephen Boyd <sboyd at codeaurora.org>
Reviewed-by: Ulf Hansson <ulf.hansson at linaro.org>
Signed-off-by: Simon Horman <horms+renesas at verge.net.au>
---
 .../clock/renesas,rcar-gen2-cpg-clocks.txt         | 26 ++++++++++++++++++++--
 drivers/clk/shmobile/clk-rcar-gen2.c               |  2 ++
 2 files changed, 26 insertions(+), 2 deletions(-)

diff --git a/Documentation/devicetree/bindings/clock/renesas,rcar-gen2-cpg-clocks.txt b/Documentation/devicetree/bindings/clock/renesas,rcar-gen2-cpg-clocks.txt
index 56f111bd3e45..2a9a8edc8f35 100644
--- a/Documentation/devicetree/bindings/clock/renesas,rcar-gen2-cpg-clocks.txt
+++ b/Documentation/devicetree/bindings/clock/renesas,rcar-gen2-cpg-clocks.txt
@@ -2,6 +2,8 @@
 
 The CPG generates core clocks for the R-Car Gen2 SoCs. It includes three PLLs
 and several fixed ratio dividers.
+The CPG also provides a Clock Domain for SoC devices, in combination with the
+CPG Module Stop (MSTP) Clocks.
 
 Required Properties:
 
@@ -20,10 +22,18 @@ Required Properties:
   - clock-output-names: The names of the clocks. Supported clocks are "main",
     "pll0", "pll1", "pll3", "lb", "qspi", "sdh", "sd0", "sd1", "z", "rcan", and
     "adsp"
+  - #power-domain-cells: Must be 0
 
+SoC devices that are part of the CPG/MSTP Clock Domain and can be power-managed
+through an MSTP clock should refer to the CPG device node in their
+"power-domains" property, as documented by the generic PM domain bindings in
+Documentation/devicetree/bindings/power/power_domain.txt.
 
-Example
--------
+
+Examples
+--------
+
+  - CPG device node:
 
 	cpg_clocks: cpg_clocks at e6150000 {
 		compatible = "renesas,r8a7790-cpg-clocks",
@@ -34,4 +44,16 @@ Example
 		clock-output-names = "main", "pll0, "pll1", "pll3",
 				     "lb", "qspi", "sdh", "sd0", "sd1", "z",
 				     "rcan", "adsp";
+		#power-domain-cells = <0>;
+	};
+
+
+  - CPG/MSTP Clock Domain member device node:
+
+	thermal at e61f0000 {
+		compatible = "renesas,thermal-r8a7790", "renesas,rcar-thermal";
+		reg = <0 0xe61f0000 0 0x14>, <0 0xe61f0100 0 0x38>;
+		interrupts = <0 69 IRQ_TYPE_LEVEL_HIGH>;
+		clocks = <&mstp5_clks R8A7790_CLK_THERMAL>;
+		power-domains = <&cpg_clocks>;
 	};
diff --git a/drivers/clk/shmobile/clk-rcar-gen2.c b/drivers/clk/shmobile/clk-rcar-gen2.c
index acfb6d7dbd6b..f2c457f494eb 100644
--- a/drivers/clk/shmobile/clk-rcar-gen2.c
+++ b/drivers/clk/shmobile/clk-rcar-gen2.c
@@ -415,6 +415,8 @@ static void __init rcar_gen2_cpg_clocks_init(struct device_node *np)
 	}
 
 	of_clk_add_provider(np, of_clk_src_onecell_get, &cpg->data);
+
+	cpg_mstp_add_clk_domain(np);
 }
 CLK_OF_DECLARE(rcar_gen2_cpg_clks, "renesas,rcar-gen2-cpg-clocks",
 	       rcar_gen2_cpg_clocks_init);
-- 
2.1.4



From horms+renesas at verge.net.au  Thu Aug  6 19:12:04 2015
From: horms+renesas at verge.net.au (Simon Horman)
Date: Fri,  7 Aug 2015 11:12:04 +0900
Subject: [PATCH 05/12] clk: shmobile: rz: Add CPG/MSTP Clock Domain support
In-Reply-To: <cover.1438911559.git.horms+renesas@verge.net.au>
References: <cover.1438911559.git.horms+renesas@verge.net.au>
Message-ID: <aeea676370b28723183580985bbce54cebadddf7.1438911559.git.horms+renesas@verge.net.au>

From: Geert Uytterhoeven <geert+renesas at glider.be>

Add Clock Domain support to the RZ Clock Pulse Generator (CPG) driver
using the generic PM Domain.  This allows to power-manage the module
clocks of SoC devices that are part of the CPG/MSTP Clock Domain using
Runtime PM, or for system suspend/resume.

SoC devices that are part of the CPG/MSTP Clock Domain and can be
power-managed through an MSTP clock should be tagged in DT with a proper
"power-domains" property.

Signed-off-by: Geert Uytterhoeven <geert+renesas at glider.be>
Acked-by: Stephen Boyd <sboyd at codeaurora.org>
Reviewed-by: Ulf Hansson <ulf.hansson at linaro.org>
Signed-off-by: Simon Horman <horms+renesas at verge.net.au>
---
 .../bindings/clock/renesas,rz-cpg-clocks.txt       | 29 ++++++++++++++++++++--
 arch/arm/mach-shmobile/Kconfig                     |  1 +
 drivers/clk/shmobile/clk-rz.c                      |  3 +++
 3 files changed, 31 insertions(+), 2 deletions(-)

diff --git a/Documentation/devicetree/bindings/clock/renesas,rz-cpg-clocks.txt b/Documentation/devicetree/bindings/clock/renesas,rz-cpg-clocks.txt
index b0f7ddb8cdb1..bb51a33a1fbf 100644
--- a/Documentation/devicetree/bindings/clock/renesas,rz-cpg-clocks.txt
+++ b/Documentation/devicetree/bindings/clock/renesas,rz-cpg-clocks.txt
@@ -2,6 +2,8 @@
 
 The CPG generates core clocks for the RZ SoCs. It includes the PLL, variable
 CPU and GPU clocks, and several fixed ratio dividers.
+The CPG also provides a Clock Domain for SoC devices, in combination with the
+CPG Module Stop (MSTP) Clocks.
 
 Required Properties:
 
@@ -14,10 +16,18 @@ Required Properties:
   - #clock-cells: Must be 1
   - clock-output-names: The names of the clocks. Supported clocks are "pll",
     "i", and "g"
+  - #power-domain-cells: Must be 0
 
+SoC devices that are part of the CPG/MSTP Clock Domain and can be power-managed
+through an MSTP clock should refer to the CPG device node in their
+"power-domains" property, as documented by the generic PM domain bindings in
+Documentation/devicetree/bindings/power/power_domain.txt.
 
-Example
--------
+
+Examples
+--------
+
+  - CPG device node:
 
 	cpg_clocks: cpg_clocks at fcfe0000 {
 		#clock-cells = <1>;
@@ -26,4 +36,19 @@ Example
 		reg = <0xfcfe0000 0x18>;
 		clocks = <&extal_clk>, <&usb_x1_clk>;
 		clock-output-names = "pll", "i", "g";
+		#power-domain-cells = <0>;
+	};
+
+
+  - CPG/MSTP Clock Domain member device node:
+
+	mtu2: timer at fcff0000 {
+		compatible = "renesas,mtu2-r7s72100", "renesas,mtu2";
+		reg = <0xfcff0000 0x400>;
+		interrupts = <0 107 IRQ_TYPE_LEVEL_HIGH>;
+		interrupt-names = "tgi0a";
+		clocks = <&mstp3_clks R7S72100_CLK_MTU2>;
+		clock-names = "fck";
+		power-domains = <&cpg_clocks>;
+		status = "disabled";
 	};
diff --git a/arch/arm/mach-shmobile/Kconfig b/arch/arm/mach-shmobile/Kconfig
index e14fa5e87475..34eac88a9889 100644
--- a/arch/arm/mach-shmobile/Kconfig
+++ b/arch/arm/mach-shmobile/Kconfig
@@ -51,6 +51,7 @@ config ARCH_EMEV2
 
 config ARCH_R7S72100
 	bool "RZ/A1H (R7S72100)"
+	select PM_GENERIC_DOMAINS if PM
 	select SYS_SUPPORTS_SH_MTU2
 
 config ARCH_R8A73A4
diff --git a/drivers/clk/shmobile/clk-rz.c b/drivers/clk/shmobile/clk-rz.c
index 7e68e8630962..9766e3cb595f 100644
--- a/drivers/clk/shmobile/clk-rz.c
+++ b/drivers/clk/shmobile/clk-rz.c
@@ -10,6 +10,7 @@
  */
 
 #include <linux/clk-provider.h>
+#include <linux/clk/shmobile.h>
 #include <linux/init.h>
 #include <linux/kernel.h>
 #include <linux/of.h>
@@ -99,5 +100,7 @@ static void __init rz_cpg_clocks_init(struct device_node *np)
 	}
 
 	of_clk_add_provider(np, of_clk_src_onecell_get, &cpg->data);
+
+	cpg_mstp_add_clk_domain(np);
 }
 CLK_OF_DECLARE(rz_cpg_clks, "renesas,rz-cpg-clocks", rz_cpg_clocks_init);
-- 
2.1.4



From horms+renesas at verge.net.au  Thu Aug  6 19:12:11 2015
From: horms+renesas at verge.net.au (Simon Horman)
Date: Fri,  7 Aug 2015 11:12:11 +0900
Subject: [PATCH 12/12] ARM: shmobile: r8a7794 dtsi: Add CPG/MSTP Clock Domain
In-Reply-To: <cover.1438911559.git.horms+renesas@verge.net.au>
References: <cover.1438911559.git.horms+renesas@verge.net.au>
Message-ID: <2daa8a5a8c0994893c2ca456303f0bf53e881cb9.1438911559.git.horms+renesas@verge.net.au>

From: Geert Uytterhoeven <geert+renesas at glider.be>

Add an appropriate "#power-domain-cells" property to the cpg_clocks
device node, to create the CPG/MSTP Clock Domain.

Add "power-domains" properties to all device nodes for devices that are
part of the CPG/MSTP Clock Domain and can be power-managed through an
MSTP clock.  This applies to most on-SoC devices, which have a
one-to-one mapping from SoC device to DT device node.

Signed-off-by: Geert Uytterhoeven <geert+renesas at glider.be>
Reviewed-by: Ulf Hansson <ulf.hansson at linaro.org>
Signed-off-by: Simon Horman <horms+renesas at verge.net.au>
---
 arch/arm/boot/dts/r8a7794.dtsi | 29 +++++++++++++++++++++++++++++
 1 file changed, 29 insertions(+)

diff --git a/arch/arm/boot/dts/r8a7794.dtsi b/arch/arm/boot/dts/r8a7794.dtsi
index 43acf185ecc4..97c8e9ace5eb 100644
--- a/arch/arm/boot/dts/r8a7794.dtsi
+++ b/arch/arm/boot/dts/r8a7794.dtsi
@@ -57,6 +57,7 @@
 			     <0 143 IRQ_TYPE_LEVEL_HIGH>;
 		clocks = <&mstp1_clks R8A7794_CLK_CMT0>;
 		clock-names = "fck";
+		power-domains = <&cpg_clocks>;
 
 		renesas,channels-mask = <0x60>;
 
@@ -76,6 +77,7 @@
 			     <0 127 IRQ_TYPE_LEVEL_HIGH>;
 		clocks = <&mstp3_clks R8A7794_CLK_CMT1>;
 		clock-names = "fck";
+		power-domains = <&cpg_clocks>;
 
 		renesas,channels-mask = <0xff>;
 
@@ -106,6 +108,7 @@
 			     <0 16 IRQ_TYPE_LEVEL_HIGH>,
 			     <0 17 IRQ_TYPE_LEVEL_HIGH>;
 		clocks = <&mstp4_clks R8A7794_CLK_IRQC>;
+		power-domains = <&cpg_clocks>;
 	};
 
 	pfc: pin-controller at e6060000 {
@@ -140,6 +143,7 @@
 				"ch12", "ch13", "ch14";
 		clocks = <&mstp2_clks R8A7794_CLK_SYS_DMAC0>;
 		clock-names = "fck";
+		power-domains = <&cpg_clocks>;
 		#dma-cells = <1>;
 		dma-channels = <15>;
 	};
@@ -170,6 +174,7 @@
 				"ch12", "ch13", "ch14";
 		clocks = <&mstp2_clks R8A7794_CLK_SYS_DMAC1>;
 		clock-names = "fck";
+		power-domains = <&cpg_clocks>;
 		#dma-cells = <1>;
 		dma-channels = <15>;
 	};
@@ -182,6 +187,7 @@
 		clock-names = "sci_ick";
 		dmas = <&dmac0 0x21>, <&dmac0 0x22>;
 		dma-names = "tx", "rx";
+		power-domains = <&cpg_clocks>;
 		status = "disabled";
 	};
 
@@ -193,6 +199,7 @@
 		clock-names = "sci_ick";
 		dmas = <&dmac0 0x25>, <&dmac0 0x26>;
 		dma-names = "tx", "rx";
+		power-domains = <&cpg_clocks>;
 		status = "disabled";
 	};
 
@@ -204,6 +211,7 @@
 		clock-names = "sci_ick";
 		dmas = <&dmac0 0x27>, <&dmac0 0x28>;
 		dma-names = "tx", "rx";
+		power-domains = <&cpg_clocks>;
 		status = "disabled";
 	};
 
@@ -215,6 +223,7 @@
 		clock-names = "sci_ick";
 		dmas = <&dmac0 0x1b>, <&dmac0 0x1c>;
 		dma-names = "tx", "rx";
+		power-domains = <&cpg_clocks>;
 		status = "disabled";
 	};
 
@@ -226,6 +235,7 @@
 		clock-names = "sci_ick";
 		dmas = <&dmac0 0x1f>, <&dmac0 0x20>;
 		dma-names = "tx", "rx";
+		power-domains = <&cpg_clocks>;
 		status = "disabled";
 	};
 
@@ -237,6 +247,7 @@
 		clock-names = "sci_ick";
 		dmas = <&dmac0 0x23>, <&dmac0 0x24>;
 		dma-names = "tx", "rx";
+		power-domains = <&cpg_clocks>;
 		status = "disabled";
 	};
 
@@ -248,6 +259,7 @@
 		clock-names = "sci_ick";
 		dmas = <&dmac0 0x3d>, <&dmac0 0x3e>;
 		dma-names = "tx", "rx";
+		power-domains = <&cpg_clocks>;
 		status = "disabled";
 	};
 
@@ -259,6 +271,7 @@
 		clock-names = "sci_ick";
 		dmas = <&dmac0 0x19>, <&dmac0 0x1a>;
 		dma-names = "tx", "rx";
+		power-domains = <&cpg_clocks>;
 		status = "disabled";
 	};
 
@@ -270,6 +283,7 @@
 		clock-names = "sci_ick";
 		dmas = <&dmac0 0x1d>, <&dmac0 0x1e>;
 		dma-names = "tx", "rx";
+		power-domains = <&cpg_clocks>;
 		status = "disabled";
 	};
 
@@ -281,6 +295,7 @@
 		clock-names = "sci_ick";
 		dmas = <&dmac0 0x29>, <&dmac0 0x2a>;
 		dma-names = "tx", "rx";
+		power-domains = <&cpg_clocks>;
 		status = "disabled";
 	};
 
@@ -292,6 +307,7 @@
 		clock-names = "sci_ick";
 		dmas = <&dmac0 0x2d>, <&dmac0 0x2e>;
 		dma-names = "tx", "rx";
+		power-domains = <&cpg_clocks>;
 		status = "disabled";
 	};
 
@@ -303,6 +319,7 @@
 		clock-names = "sci_ick";
 		dmas = <&dmac0 0x2b>, <&dmac0 0x2c>;
 		dma-names = "tx", "rx";
+		power-domains = <&cpg_clocks>;
 		status = "disabled";
 	};
 
@@ -314,6 +331,7 @@
 		clock-names = "sci_ick";
 		dmas = <&dmac0 0x2f>, <&dmac0 0x30>;
 		dma-names = "tx", "rx";
+		power-domains = <&cpg_clocks>;
 		status = "disabled";
 	};
 
@@ -325,6 +343,7 @@
 		clock-names = "sci_ick";
 		dmas = <&dmac0 0xfb>, <&dmac0 0xfc>;
 		dma-names = "tx", "rx";
+		power-domains = <&cpg_clocks>;
 		status = "disabled";
 	};
 
@@ -336,6 +355,7 @@
 		clock-names = "sci_ick";
 		dmas = <&dmac0 0xfd>, <&dmac0 0xfe>;
 		dma-names = "tx", "rx";
+		power-domains = <&cpg_clocks>;
 		status = "disabled";
 	};
 
@@ -347,6 +367,7 @@
 		clock-names = "sci_ick";
 		dmas = <&dmac0 0x39>, <&dmac0 0x3a>;
 		dma-names = "tx", "rx";
+		power-domains = <&cpg_clocks>;
 		status = "disabled";
 	};
 
@@ -358,6 +379,7 @@
 		clock-names = "sci_ick";
 		dmas = <&dmac0 0x4d>, <&dmac0 0x4e>;
 		dma-names = "tx", "rx";
+		power-domains = <&cpg_clocks>;
 		status = "disabled";
 	};
 
@@ -369,6 +391,7 @@
 		clock-names = "sci_ick";
 		dmas = <&dmac0 0x3b>, <&dmac0 0x3c>;
 		dma-names = "tx", "rx";
+		power-domains = <&cpg_clocks>;
 		status = "disabled";
 	};
 
@@ -377,6 +400,7 @@
 		reg = <0 0xee700000 0 0x400>;
 		interrupts = <0 162 IRQ_TYPE_LEVEL_HIGH>;
 		clocks = <&mstp8_clks R8A7794_CLK_ETHER>;
+		power-domains = <&cpg_clocks>;
 		phy-mode = "rmii";
 		#address-cells = <1>;
 		#size-cells = <0>;
@@ -390,6 +414,7 @@
 		clocks = <&mstp3_clks R8A7794_CLK_MMCIF0>;
 		dmas = <&dmac0 0xd1>, <&dmac0 0xd2>;
 		dma-names = "tx", "rx";
+		power-domains = <&cpg_clocks>;
 		reg-io-width = <4>;
 		status = "disabled";
 	};
@@ -399,6 +424,7 @@
 		reg = <0 0xee100000 0 0x200>;
 		interrupts = <0 165 IRQ_TYPE_LEVEL_HIGH>;
 		clocks = <&mstp3_clks R8A7794_CLK_SDHI0>;
+		power-domains = <&cpg_clocks>;
 		status = "disabled";
 	};
 
@@ -407,6 +433,7 @@
 		reg = <0 0xee140000 0 0x100>;
 		interrupts = <0 167 IRQ_TYPE_LEVEL_HIGH>;
 		clocks = <&mstp3_clks R8A7794_CLK_SDHI1>;
+		power-domains = <&cpg_clocks>;
 		status = "disabled";
 	};
 
@@ -415,6 +442,7 @@
 		reg = <0 0xee160000 0 0x100>;
 		interrupts = <0 168 IRQ_TYPE_LEVEL_HIGH>;
 		clocks = <&mstp3_clks R8A7794_CLK_SDHI2>;
+		power-domains = <&cpg_clocks>;
 		status = "disabled";
 	};
 
@@ -441,6 +469,7 @@
 			#clock-cells = <1>;
 			clock-output-names = "main", "pll0", "pll1", "pll3",
 					     "lb", "qspi", "sdh", "sd0", "z";
+			#power-domain-cells = <0>;
 		};
 		/* Variable factor clocks */
 		sd2_clk: sd2_clk at e6150078 {
-- 
2.1.4



From horms+renesas at verge.net.au  Thu Aug  6 19:12:06 2015
From: horms+renesas at verge.net.au (Simon Horman)
Date: Fri,  7 Aug 2015 11:12:06 +0900
Subject: [PATCH 07/12] ARM: shmobile: r8a7778 dtsi: Add CPG/MSTP Clock Domain
In-Reply-To: <cover.1438911559.git.horms+renesas@verge.net.au>
References: <cover.1438911559.git.horms+renesas@verge.net.au>
Message-ID: <eb0a3b905078e8789a4bdcce5947fe96d39f47a9.1438911559.git.horms+renesas@verge.net.au>

From: Geert Uytterhoeven <geert+renesas at glider.be>

Add an appropriate "#power-domain-cells" property to the cpg_clocks
device node, to create the CPG/MSTP Clock Domain.

Add "power-domains" properties to all device nodes for devices that are
part of the CPG/MSTP Clock Domain and can be power-managed through an
MSTP clock.  This applies to most on-SoC devices, which have a
one-to-one mapping from SoC device to DT device node.  A notable
exception is the "sound" node, which represents multiple SoC devices,
each having their own MSTP clocks.

Signed-off-by: Geert Uytterhoeven <geert+renesas at glider.be>
Reviewed-by: Ulf Hansson <ulf.hansson at linaro.org>
Signed-off-by: Simon Horman <horms+renesas at verge.net.au>
---
 arch/arm/boot/dts/r8a7778.dtsi | 22 ++++++++++++++++++++++
 1 file changed, 22 insertions(+)

diff --git a/arch/arm/boot/dts/r8a7778.dtsi b/arch/arm/boot/dts/r8a7778.dtsi
index 7ce9f5fd5865..4b1fa9f42ad5 100644
--- a/arch/arm/boot/dts/r8a7778.dtsi
+++ b/arch/arm/boot/dts/r8a7778.dtsi
@@ -53,6 +53,7 @@
 		reg = <0xfde00000 0x400>;
 		interrupts = <0 105 IRQ_TYPE_LEVEL_HIGH>;
 		clocks = <&mstp1_clks R8A7778_CLK_ETHER>;
+		power-domains = <&cpg_clocks>;
 		phy-mode = "rmii";
 		#address-cells = <1>;
 		#size-cells = <0>;
@@ -152,6 +153,7 @@
 		reg = <0xffc70000 0x1000>;
 		interrupts = <0 67 IRQ_TYPE_LEVEL_HIGH>;
 		clocks = <&mstp0_clks R8A7778_CLK_I2C0>;
+		power-domains = <&cpg_clocks>;
 		status = "disabled";
 	};
 
@@ -162,6 +164,7 @@
 		reg = <0xffc71000 0x1000>;
 		interrupts = <0 78 IRQ_TYPE_LEVEL_HIGH>;
 		clocks = <&mstp0_clks R8A7778_CLK_I2C1>;
+		power-domains = <&cpg_clocks>;
 		status = "disabled";
 	};
 
@@ -172,6 +175,7 @@
 		reg = <0xffc72000 0x1000>;
 		interrupts = <0 76 IRQ_TYPE_LEVEL_HIGH>;
 		clocks = <&mstp0_clks R8A7778_CLK_I2C2>;
+		power-domains = <&cpg_clocks>;
 		status = "disabled";
 	};
 
@@ -182,6 +186,7 @@
 		reg = <0xffc73000 0x1000>;
 		interrupts = <0 77 IRQ_TYPE_LEVEL_HIGH>;
 		clocks = <&mstp0_clks R8A7778_CLK_I2C3>;
+		power-domains = <&cpg_clocks>;
 		status = "disabled";
 	};
 
@@ -193,6 +198,7 @@
 			     <0 34 IRQ_TYPE_LEVEL_HIGH>;
 		clocks = <&mstp0_clks R8A7778_CLK_TMU0>;
 		clock-names = "fck";
+		power-domains = <&cpg_clocks>;
 
 		#renesas,channels = <3>;
 
@@ -207,6 +213,7 @@
 			     <0 38 IRQ_TYPE_LEVEL_HIGH>;
 		clocks = <&mstp0_clks R8A7778_CLK_TMU1>;
 		clock-names = "fck";
+		power-domains = <&cpg_clocks>;
 
 		#renesas,channels = <3>;
 
@@ -221,6 +228,7 @@
 			     <0 42 IRQ_TYPE_LEVEL_HIGH>;
 		clocks = <&mstp0_clks R8A7778_CLK_TMU2>;
 		clock-names = "fck";
+		power-domains = <&cpg_clocks>;
 
 		#renesas,channels = <3>;
 
@@ -288,6 +296,7 @@
 		interrupts = <0 70 IRQ_TYPE_LEVEL_HIGH>;
 		clocks = <&mstp0_clks R8A7778_CLK_SCIF0>;
 		clock-names = "sci_ick";
+		power-domains = <&cpg_clocks>;
 		status = "disabled";
 	};
 
@@ -297,6 +306,7 @@
 		interrupts = <0 71 IRQ_TYPE_LEVEL_HIGH>;
 		clocks = <&mstp0_clks R8A7778_CLK_SCIF1>;
 		clock-names = "sci_ick";
+		power-domains = <&cpg_clocks>;
 		status = "disabled";
 	};
 
@@ -306,6 +316,7 @@
 		interrupts = <0 72 IRQ_TYPE_LEVEL_HIGH>;
 		clocks = <&mstp0_clks R8A7778_CLK_SCIF2>;
 		clock-names = "sci_ick";
+		power-domains = <&cpg_clocks>;
 		status = "disabled";
 	};
 
@@ -315,6 +326,7 @@
 		interrupts = <0 73 IRQ_TYPE_LEVEL_HIGH>;
 		clocks = <&mstp0_clks R8A7778_CLK_SCIF3>;
 		clock-names = "sci_ick";
+		power-domains = <&cpg_clocks>;
 		status = "disabled";
 	};
 
@@ -324,6 +336,7 @@
 		interrupts = <0 74 IRQ_TYPE_LEVEL_HIGH>;
 		clocks = <&mstp0_clks R8A7778_CLK_SCIF4>;
 		clock-names = "sci_ick";
+		power-domains = <&cpg_clocks>;
 		status = "disabled";
 	};
 
@@ -333,6 +346,7 @@
 		interrupts = <0 75 IRQ_TYPE_LEVEL_HIGH>;
 		clocks = <&mstp0_clks R8A7778_CLK_SCIF5>;
 		clock-names = "sci_ick";
+		power-domains = <&cpg_clocks>;
 		status = "disabled";
 	};
 
@@ -341,6 +355,7 @@
 		reg = <0xffe4e000 0x100>;
 		interrupts = <0 61 IRQ_TYPE_LEVEL_HIGH>;
 		clocks = <&mstp3_clks R8A7778_CLK_MMC>;
+		power-domains = <&cpg_clocks>;
 		status = "disabled";
 	};
 
@@ -349,6 +364,7 @@
 		reg = <0xffe4c000 0x100>;
 		interrupts = <0 87 IRQ_TYPE_LEVEL_HIGH>;
 		clocks = <&mstp3_clks R8A7778_CLK_SDHI0>;
+		power-domains = <&cpg_clocks>;
 		status = "disabled";
 	};
 
@@ -357,6 +373,7 @@
 		reg = <0xffe4d000 0x100>;
 		interrupts = <0 88 IRQ_TYPE_LEVEL_HIGH>;
 		clocks = <&mstp3_clks R8A7778_CLK_SDHI1>;
+		power-domains = <&cpg_clocks>;
 		status = "disabled";
 	};
 
@@ -365,6 +382,7 @@
 		reg = <0xffe4f000 0x100>;
 		interrupts = <0 86 IRQ_TYPE_LEVEL_HIGH>;
 		clocks = <&mstp3_clks R8A7778_CLK_SDHI2>;
+		power-domains = <&cpg_clocks>;
 		status = "disabled";
 	};
 
@@ -373,6 +391,7 @@
 		reg = <0xfffc7000 0x18>;
 		interrupts = <0 63 IRQ_TYPE_LEVEL_HIGH>;
 		clocks = <&mstp0_clks R8A7778_CLK_HSPI>;
+		power-domains = <&cpg_clocks>;
 		#address-cells = <1>;
 		#size-cells = <0>;
 		status = "disabled";
@@ -383,6 +402,7 @@
 		reg = <0xfffc8000 0x18>;
 		interrupts = <0 84 IRQ_TYPE_LEVEL_HIGH>;
 		clocks = <&mstp0_clks R8A7778_CLK_HSPI>;
+		power-domains = <&cpg_clocks>;
 		#address-cells = <1>;
 		#size-cells = <0>;
 		status = "disabled";
@@ -393,6 +413,7 @@
 		reg = <0xfffc6000 0x18>;
 		interrupts = <0 85 IRQ_TYPE_LEVEL_HIGH>;
 		clocks = <&mstp0_clks R8A7778_CLK_HSPI>;
+		power-domains = <&cpg_clocks>;
 		#address-cells = <1>;
 		#size-cells = <0>;
 		status = "disabled";
@@ -419,6 +440,7 @@
 			clocks = <&extal_clk>;
 			clock-output-names = "plla", "pllb", "b",
 					     "out", "p", "s", "s1";
+			#power-domain-cells = <0>;
 		};
 
 		/* Audio clocks; frequencies are set by boards if applicable. */
-- 
2.1.4



From horms+renesas at verge.net.au  Thu Aug  6 19:12:05 2015
From: horms+renesas at verge.net.au (Simon Horman)
Date: Fri,  7 Aug 2015 11:12:05 +0900
Subject: [PATCH 06/12] ARM: shmobile: r7s72100 dtsi: Add CPG/MSTP Clock Domain
In-Reply-To: <cover.1438911559.git.horms+renesas@verge.net.au>
References: <cover.1438911559.git.horms+renesas@verge.net.au>
Message-ID: <1c3f5f291f3e7edf7111716cd42f8417c9500aa1.1438911559.git.horms+renesas@verge.net.au>

From: Geert Uytterhoeven <geert+renesas at glider.be>

Add an appropriate "#power-domain-cells" property to the cpg_clocks
device node, to create the CPG/MSTP Clock Domain.

Add "power-domains" properties to all device nodes for devices that are
part of the CPG/MSTP Clock Domain and can be power-managed through an
MSTP clock.  This applies to most on-SoC devices, which have a
one-to-one mapping from SoC device to DT device node.

Signed-off-by: Geert Uytterhoeven <geert+renesas at glider.be>
Reviewed-by: Ulf Hansson <ulf.hansson at linaro.org>
Signed-off-by: Simon Horman <horms+renesas at verge.net.au>
---
 arch/arm/boot/dts/r7s72100.dtsi | 19 +++++++++++++++++++
 1 file changed, 19 insertions(+)

diff --git a/arch/arm/boot/dts/r7s72100.dtsi b/arch/arm/boot/dts/r7s72100.dtsi
index 277e73c110e5..060c32cbd669 100644
--- a/arch/arm/boot/dts/r7s72100.dtsi
+++ b/arch/arm/boot/dts/r7s72100.dtsi
@@ -86,6 +86,7 @@
 			reg = <0xfcfe0000 0x18>;
 			clocks = <&extal_clk>, <&usb_x1_clk>;
 			clock-output-names = "pll", "i", "g";
+			#power-domain-cells = <0>;
 		};
 
 		/* MSTP clocks */
@@ -157,6 +158,7 @@
 			     <0 189 IRQ_TYPE_LEVEL_HIGH>;
 		clocks = <&mstp4_clks R7S72100_CLK_SCIF0>;
 		clock-names = "sci_ick";
+		power-domains = <&cpg_clocks>;
 		status = "disabled";
 	};
 
@@ -169,6 +171,7 @@
 			     <0 193 IRQ_TYPE_LEVEL_HIGH>;
 		clocks = <&mstp4_clks R7S72100_CLK_SCIF1>;
 		clock-names = "sci_ick";
+		power-domains = <&cpg_clocks>;
 		status = "disabled";
 	};
 
@@ -181,6 +184,7 @@
 			     <0 197 IRQ_TYPE_LEVEL_HIGH>;
 		clocks = <&mstp4_clks R7S72100_CLK_SCIF2>;
 		clock-names = "sci_ick";
+		power-domains = <&cpg_clocks>;
 		status = "disabled";
 	};
 
@@ -193,6 +197,7 @@
 			     <0 201 IRQ_TYPE_LEVEL_HIGH>;
 		clocks = <&mstp4_clks R7S72100_CLK_SCIF3>;
 		clock-names = "sci_ick";
+		power-domains = <&cpg_clocks>;
 		status = "disabled";
 	};
 
@@ -205,6 +210,7 @@
 			     <0 205 IRQ_TYPE_LEVEL_HIGH>;
 		clocks = <&mstp4_clks R7S72100_CLK_SCIF4>;
 		clock-names = "sci_ick";
+		power-domains = <&cpg_clocks>;
 		status = "disabled";
 	};
 
@@ -217,6 +223,7 @@
 			     <0 209 IRQ_TYPE_LEVEL_HIGH>;
 		clocks = <&mstp4_clks R7S72100_CLK_SCIF5>;
 		clock-names = "sci_ick";
+		power-domains = <&cpg_clocks>;
 		status = "disabled";
 	};
 
@@ -229,6 +236,7 @@
 			     <0 213 IRQ_TYPE_LEVEL_HIGH>;
 		clocks = <&mstp4_clks R7S72100_CLK_SCIF6>;
 		clock-names = "sci_ick";
+		power-domains = <&cpg_clocks>;
 		status = "disabled";
 	};
 
@@ -241,6 +249,7 @@
 			     <0 217 IRQ_TYPE_LEVEL_HIGH>;
 		clocks = <&mstp4_clks R7S72100_CLK_SCIF7>;
 		clock-names = "sci_ick";
+		power-domains = <&cpg_clocks>;
 		status = "disabled";
 	};
 
@@ -252,6 +261,7 @@
 			     <0 240 IRQ_TYPE_LEVEL_HIGH>;
 		interrupt-names = "error", "rx", "tx";
 		clocks = <&mstp10_clks R7S72100_CLK_SPI0>;
+		power-domains = <&cpg_clocks>;
 		num-cs = <1>;
 		#address-cells = <1>;
 		#size-cells = <0>;
@@ -266,6 +276,7 @@
 			     <0 243 IRQ_TYPE_LEVEL_HIGH>;
 		interrupt-names = "error", "rx", "tx";
 		clocks = <&mstp10_clks R7S72100_CLK_SPI1>;
+		power-domains = <&cpg_clocks>;
 		num-cs = <1>;
 		#address-cells = <1>;
 		#size-cells = <0>;
@@ -280,6 +291,7 @@
 			     <0 246 IRQ_TYPE_LEVEL_HIGH>;
 		interrupt-names = "error", "rx", "tx";
 		clocks = <&mstp10_clks R7S72100_CLK_SPI2>;
+		power-domains = <&cpg_clocks>;
 		num-cs = <1>;
 		#address-cells = <1>;
 		#size-cells = <0>;
@@ -294,6 +306,7 @@
 			     <0 249 IRQ_TYPE_LEVEL_HIGH>;
 		interrupt-names = "error", "rx", "tx";
 		clocks = <&mstp10_clks R7S72100_CLK_SPI3>;
+		power-domains = <&cpg_clocks>;
 		num-cs = <1>;
 		#address-cells = <1>;
 		#size-cells = <0>;
@@ -308,6 +321,7 @@
 			     <0 252 IRQ_TYPE_LEVEL_HIGH>;
 		interrupt-names = "error", "rx", "tx";
 		clocks = <&mstp10_clks R7S72100_CLK_SPI4>;
+		power-domains = <&cpg_clocks>;
 		num-cs = <1>;
 		#address-cells = <1>;
 		#size-cells = <0>;
@@ -338,6 +352,7 @@
 			     <0 164 IRQ_TYPE_LEVEL_HIGH>;
 		clocks = <&mstp9_clks R7S72100_CLK_I2C0>;
 		clock-frequency = <100000>;
+		power-domains = <&cpg_clocks>;
 		status = "disabled";
 	};
 
@@ -356,6 +371,7 @@
 			     <0 172 IRQ_TYPE_LEVEL_HIGH>;
 		clocks = <&mstp9_clks R7S72100_CLK_I2C1>;
 		clock-frequency = <100000>;
+		power-domains = <&cpg_clocks>;
 		status = "disabled";
 	};
 
@@ -374,6 +390,7 @@
 			     <0 180 IRQ_TYPE_LEVEL_HIGH>;
 		clocks = <&mstp9_clks R7S72100_CLK_I2C2>;
 		clock-frequency = <100000>;
+		power-domains = <&cpg_clocks>;
 		status = "disabled";
 	};
 
@@ -392,6 +409,7 @@
 			     <0 188 IRQ_TYPE_LEVEL_HIGH>;
 		clocks = <&mstp9_clks R7S72100_CLK_I2C3>;
 		clock-frequency = <100000>;
+		power-domains = <&cpg_clocks>;
 		status = "disabled";
 	};
 
@@ -402,6 +420,7 @@
 		interrupt-names = "tgi0a";
 		clocks = <&mstp3_clks R7S72100_CLK_MTU2>;
 		clock-names = "fck";
+		power-domains = <&cpg_clocks>;
 		status = "disabled";
 	};
 };
-- 
2.1.4



From horms+renesas at verge.net.au  Thu Aug  6 19:12:07 2015
From: horms+renesas at verge.net.au (Simon Horman)
Date: Fri,  7 Aug 2015 11:12:07 +0900
Subject: [PATCH 08/12] ARM: shmobile: r8a7779 dtsi: Add CPG/MSTP Clock Domain
In-Reply-To: <cover.1438911559.git.horms+renesas@verge.net.au>
References: <cover.1438911559.git.horms+renesas@verge.net.au>
Message-ID: <249921116cae20729f9c50759288b371eb7c1e48.1438911559.git.horms+renesas@verge.net.au>

From: Geert Uytterhoeven <geert+renesas at glider.be>

Add an appropriate "#power-domain-cells" property to the cpg_clocks
device node, to create the CPG/MSTP Clock Domain.

Add "power-domains" properties to all device nodes for devices that are
part of the CPG/MSTP Clock Domain and can be power-managed through an
MSTP clock.  This applies to most on-SoC devices, which have a
one-to-one mapping from SoC device to DT device node.

Signed-off-by: Geert Uytterhoeven <geert+renesas at glider.be>
Reviewed-by: Ulf Hansson <ulf.hansson at linaro.org>
Signed-off-by: Simon Horman <horms+renesas at verge.net.au>
---
 arch/arm/boot/dts/r8a7779.dtsi | 23 +++++++++++++++++++++++
 1 file changed, 23 insertions(+)

diff --git a/arch/arm/boot/dts/r8a7779.dtsi b/arch/arm/boot/dts/r8a7779.dtsi
index a2b5430d3257..6afa909865b5 100644
--- a/arch/arm/boot/dts/r8a7779.dtsi
+++ b/arch/arm/boot/dts/r8a7779.dtsi
@@ -173,6 +173,7 @@
 		reg = <0xffc70000 0x1000>;
 		interrupts = <0 79 IRQ_TYPE_LEVEL_HIGH>;
 		clocks = <&mstp0_clks R8A7779_CLK_I2C0>;
+		power-domains = <&cpg_clocks>;
 		status = "disabled";
 	};
 
@@ -183,6 +184,7 @@
 		reg = <0xffc71000 0x1000>;
 		interrupts = <0 82 IRQ_TYPE_LEVEL_HIGH>;
 		clocks = <&mstp0_clks R8A7779_CLK_I2C1>;
+		power-domains = <&cpg_clocks>;
 		status = "disabled";
 	};
 
@@ -193,6 +195,7 @@
 		reg = <0xffc72000 0x1000>;
 		interrupts = <0 80 IRQ_TYPE_LEVEL_HIGH>;
 		clocks = <&mstp0_clks R8A7779_CLK_I2C2>;
+		power-domains = <&cpg_clocks>;
 		status = "disabled";
 	};
 
@@ -203,6 +206,7 @@
 		reg = <0xffc73000 0x1000>;
 		interrupts = <0 81 IRQ_TYPE_LEVEL_HIGH>;
 		clocks = <&mstp0_clks R8A7779_CLK_I2C3>;
+		power-domains = <&cpg_clocks>;
 		status = "disabled";
 	};
 
@@ -212,6 +216,7 @@
 		interrupts = <0 88 IRQ_TYPE_LEVEL_HIGH>;
 		clocks = <&mstp0_clks R8A7779_CLK_SCIF0>;
 		clock-names = "sci_ick";
+		power-domains = <&cpg_clocks>;
 		status = "disabled";
 	};
 
@@ -221,6 +226,7 @@
 		interrupts = <0 89 IRQ_TYPE_LEVEL_HIGH>;
 		clocks = <&mstp0_clks R8A7779_CLK_SCIF1>;
 		clock-names = "sci_ick";
+		power-domains = <&cpg_clocks>;
 		status = "disabled";
 	};
 
@@ -230,6 +236,7 @@
 		interrupts = <0 90 IRQ_TYPE_LEVEL_HIGH>;
 		clocks = <&mstp0_clks R8A7779_CLK_SCIF2>;
 		clock-names = "sci_ick";
+		power-domains = <&cpg_clocks>;
 		status = "disabled";
 	};
 
@@ -239,6 +246,7 @@
 		interrupts = <0 91 IRQ_TYPE_LEVEL_HIGH>;
 		clocks = <&mstp0_clks R8A7779_CLK_SCIF3>;
 		clock-names = "sci_ick";
+		power-domains = <&cpg_clocks>;
 		status = "disabled";
 	};
 
@@ -248,6 +256,7 @@
 		interrupts = <0 92 IRQ_TYPE_LEVEL_HIGH>;
 		clocks = <&mstp0_clks R8A7779_CLK_SCIF4>;
 		clock-names = "sci_ick";
+		power-domains = <&cpg_clocks>;
 		status = "disabled";
 	};
 
@@ -257,6 +266,7 @@
 		interrupts = <0 93 IRQ_TYPE_LEVEL_HIGH>;
 		clocks = <&mstp0_clks R8A7779_CLK_SCIF5>;
 		clock-names = "sci_ick";
+		power-domains = <&cpg_clocks>;
 		status = "disabled";
 	};
 
@@ -278,6 +288,7 @@
 			     <0 34 IRQ_TYPE_LEVEL_HIGH>;
 		clocks = <&mstp0_clks R8A7779_CLK_TMU0>;
 		clock-names = "fck";
+		power-domains = <&cpg_clocks>;
 
 		#renesas,channels = <3>;
 
@@ -292,6 +303,7 @@
 			     <0 38 IRQ_TYPE_LEVEL_HIGH>;
 		clocks = <&mstp0_clks R8A7779_CLK_TMU1>;
 		clock-names = "fck";
+		power-domains = <&cpg_clocks>;
 
 		#renesas,channels = <3>;
 
@@ -306,6 +318,7 @@
 			     <0 42 IRQ_TYPE_LEVEL_HIGH>;
 		clocks = <&mstp0_clks R8A7779_CLK_TMU2>;
 		clock-names = "fck";
+		power-domains = <&cpg_clocks>;
 
 		#renesas,channels = <3>;
 
@@ -317,6 +330,7 @@
 		reg = <0xfc600000 0x2000>;
 		interrupts = <0 100 IRQ_TYPE_LEVEL_HIGH>;
 		clocks = <&mstp1_clks R8A7779_CLK_SATA>;
+		power-domains = <&cpg_clocks>;
 	};
 
 	sdhi0: sd at ffe4c000 {
@@ -324,6 +338,7 @@
 		reg = <0xffe4c000 0x100>;
 		interrupts = <0 104 IRQ_TYPE_LEVEL_HIGH>;
 		clocks = <&mstp3_clks R8A7779_CLK_SDHI0>;
+		power-domains = <&cpg_clocks>;
 		status = "disabled";
 	};
 
@@ -332,6 +347,7 @@
 		reg = <0xffe4d000 0x100>;
 		interrupts = <0 105 IRQ_TYPE_LEVEL_HIGH>;
 		clocks = <&mstp3_clks R8A7779_CLK_SDHI1>;
+		power-domains = <&cpg_clocks>;
 		status = "disabled";
 	};
 
@@ -340,6 +356,7 @@
 		reg = <0xffe4e000 0x100>;
 		interrupts = <0 107 IRQ_TYPE_LEVEL_HIGH>;
 		clocks = <&mstp3_clks R8A7779_CLK_SDHI2>;
+		power-domains = <&cpg_clocks>;
 		status = "disabled";
 	};
 
@@ -348,6 +365,7 @@
 		reg = <0xffe4f000 0x100>;
 		interrupts = <0 106 IRQ_TYPE_LEVEL_HIGH>;
 		clocks = <&mstp3_clks R8A7779_CLK_SDHI3>;
+		power-domains = <&cpg_clocks>;
 		status = "disabled";
 	};
 
@@ -358,6 +376,7 @@
 		#address-cells = <1>;
 		#size-cells = <0>;
 		clocks = <&mstp0_clks R8A7779_CLK_HSPI>;
+		power-domains = <&cpg_clocks>;
 		status = "disabled";
 	};
 
@@ -368,6 +387,7 @@
 		#address-cells = <1>;
 		#size-cells = <0>;
 		clocks = <&mstp0_clks R8A7779_CLK_HSPI>;
+		power-domains = <&cpg_clocks>;
 		status = "disabled";
 	};
 
@@ -378,6 +398,7 @@
 		#address-cells = <1>;
 		#size-cells = <0>;
 		clocks = <&mstp0_clks R8A7779_CLK_HSPI>;
+		power-domains = <&cpg_clocks>;
 		status = "disabled";
 	};
 
@@ -386,6 +407,7 @@
 		reg = <0 0xfff80000 0 0x40000>;
 		interrupts = <0 31 IRQ_TYPE_LEVEL_HIGH>;
 		clocks = <&mstp1_clks R8A7779_CLK_DU>;
+		power-domains = <&cpg_clocks>;
 		status = "disabled";
 
 		ports {
@@ -427,6 +449,7 @@
 			#clock-cells = <1>;
 			clock-output-names = "plla", "z", "zs", "s",
 					     "s1", "p", "b", "out";
+			#power-domain-cells = <0>;
 		};
 
 		/* Fixed factor clocks */
-- 
2.1.4



From horms+renesas at verge.net.au  Thu Aug  6 19:12:10 2015
From: horms+renesas at verge.net.au (Simon Horman)
Date: Fri,  7 Aug 2015 11:12:10 +0900
Subject: [PATCH 11/12] ARM: shmobile: r8a7793 dtsi: Add CPG/MSTP Clock Domain
In-Reply-To: <cover.1438911559.git.horms+renesas@verge.net.au>
References: <cover.1438911559.git.horms+renesas@verge.net.au>
Message-ID: <155894880657d77f4d3afdc601108df533a00a63.1438911559.git.horms+renesas@verge.net.au>

From: Geert Uytterhoeven <geert+renesas at glider.be>

Add an appropriate "#power-domain-cells" property to the cpg_clocks
device node, to create the CPG/MSTP Clock Domain.

Add "power-domains" properties to all device nodes for devices that are
part of the CPG/MSTP Clock Domain and can be power-managed through an
MSTP clock.  This applies to most on-SoC devices, which have a
one-to-one mapping from SoC device to DT device node.

Signed-off-by: Geert Uytterhoeven <geert+renesas at glider.be>
Reviewed-by: Ulf Hansson <ulf.hansson at linaro.org>
Signed-off-by: Simon Horman <horms+renesas at verge.net.au>
---
 arch/arm/boot/dts/r8a7793.dtsi | 7 +++++++
 1 file changed, 7 insertions(+)

diff --git a/arch/arm/boot/dts/r8a7793.dtsi b/arch/arm/boot/dts/r8a7793.dtsi
index 3355c487d108..c4654047e684 100644
--- a/arch/arm/boot/dts/r8a7793.dtsi
+++ b/arch/arm/boot/dts/r8a7793.dtsi
@@ -68,6 +68,7 @@
 			     <0 143 IRQ_TYPE_LEVEL_HIGH>;
 		clocks = <&mstp1_clks R8A7793_CLK_CMT0>;
 		clock-names = "fck";
+		power-domains = <&cpg_clocks>;
 
 		renesas,channels-mask = <0x60>;
 
@@ -87,6 +88,7 @@
 			     <0 127 IRQ_TYPE_LEVEL_HIGH>;
 		clocks = <&mstp3_clks R8A7793_CLK_CMT1>;
 		clock-names = "fck";
+		power-domains = <&cpg_clocks>;
 
 		renesas,channels-mask = <0xff>;
 
@@ -109,6 +111,7 @@
 			     <0 16 IRQ_TYPE_LEVEL_HIGH>,
 			     <0 17 IRQ_TYPE_LEVEL_HIGH>;
 		clocks = <&mstp4_clks R8A7793_CLK_IRQC>;
+		power-domains = <&cpg_clocks>;
 	};
 
 	scif0: serial at e6e60000 {
@@ -117,6 +120,7 @@
 		interrupts = <0 152 IRQ_TYPE_LEVEL_HIGH>;
 		clocks = <&mstp7_clks R8A7793_CLK_SCIF0>;
 		clock-names = "sci_ick";
+		power-domains = <&cpg_clocks>;
 		status = "disabled";
 	};
 
@@ -126,6 +130,7 @@
 		interrupts = <0 153 IRQ_TYPE_LEVEL_HIGH>;
 		clocks = <&mstp7_clks R8A7793_CLK_SCIF1>;
 		clock-names = "sci_ick";
+		power-domains = <&cpg_clocks>;
 		status = "disabled";
 	};
 
@@ -134,6 +139,7 @@
 		reg = <0 0xee700000 0 0x400>;
 		interrupts = <0 162 IRQ_TYPE_LEVEL_HIGH>;
 		clocks = <&mstp8_clks R8A7793_CLK_ETHER>;
+		power-domains = <&cpg_clocks>;
 		phy-mode = "rmii";
 		#address-cells = <1>;
 		#size-cells = <0>;
@@ -164,6 +170,7 @@
 			clock-output-names = "main", "pll0", "pll1", "pll3",
 					     "lb", "qspi", "sdh", "sd0", "z",
 					     "rcan", "adsp";
+			#power-domain-cells = <0>;
 		};
 
 		/* Variable factor clocks */
-- 
2.1.4



From horms+renesas at verge.net.au  Thu Aug  6 19:12:09 2015
From: horms+renesas at verge.net.au (Simon Horman)
Date: Fri,  7 Aug 2015 11:12:09 +0900
Subject: [PATCH 10/12] ARM: shmobile: r8a7791 dtsi: Add CPG/MSTP Clock Domain
In-Reply-To: <cover.1438911559.git.horms+renesas@verge.net.au>
References: <cover.1438911559.git.horms+renesas@verge.net.au>
Message-ID: <6e3a43d3143822e14e65f42269c32e5878105cb7.1438911559.git.horms+renesas@verge.net.au>

From: Geert Uytterhoeven <geert+renesas at glider.be>

Add an appropriate "#power-domain-cells" property to the cpg_clocks
device node, to create the CPG/MSTP Clock Domain.

Add "power-domains" properties to all device nodes for devices that are
part of the CPG/MSTP Clock Domain and can be power-managed through an
MSTP clock.  This applies to most on-SoC devices, which have a
one-to-one mapping from SoC device to DT device node.  Notable
exceptions are the "display" and "sound" nodes, which represent multiple
SoC devices, each having their own MSTP clocks.

Signed-off-by: Geert Uytterhoeven <geert+renesas at glider.be>
Reviewed-by: Ulf Hansson <ulf.hansson at linaro.org>
Signed-off-by: Simon Horman <horms+renesas at verge.net.au>
---
 arch/arm/boot/dts/r8a7791.dtsi | 88 ++++++++++++++++++++++++++++++++++++++----
 1 file changed, 80 insertions(+), 8 deletions(-)

diff --git a/arch/arm/boot/dts/r8a7791.dtsi b/arch/arm/boot/dts/r8a7791.dtsi
index 1cb6c2d07933..831525dd39a6 100644
--- a/arch/arm/boot/dts/r8a7791.dtsi
+++ b/arch/arm/boot/dts/r8a7791.dtsi
@@ -91,6 +91,7 @@
 		#interrupt-cells = <2>;
 		interrupt-controller;
 		clocks = <&mstp9_clks R8A7791_CLK_GPIO0>;
+		power-domains = <&cpg_clocks>;
 	};
 
 	gpio1: gpio at e6051000 {
@@ -103,6 +104,7 @@
 		#interrupt-cells = <2>;
 		interrupt-controller;
 		clocks = <&mstp9_clks R8A7791_CLK_GPIO1>;
+		power-domains = <&cpg_clocks>;
 	};
 
 	gpio2: gpio at e6052000 {
@@ -115,6 +117,7 @@
 		#interrupt-cells = <2>;
 		interrupt-controller;
 		clocks = <&mstp9_clks R8A7791_CLK_GPIO2>;
+		power-domains = <&cpg_clocks>;
 	};
 
 	gpio3: gpio at e6053000 {
@@ -127,6 +130,7 @@
 		#interrupt-cells = <2>;
 		interrupt-controller;
 		clocks = <&mstp9_clks R8A7791_CLK_GPIO3>;
+		power-domains = <&cpg_clocks>;
 	};
 
 	gpio4: gpio at e6054000 {
@@ -139,6 +143,7 @@
 		#interrupt-cells = <2>;
 		interrupt-controller;
 		clocks = <&mstp9_clks R8A7791_CLK_GPIO4>;
+		power-domains = <&cpg_clocks>;
 	};
 
 	gpio5: gpio at e6055000 {
@@ -151,6 +156,7 @@
 		#interrupt-cells = <2>;
 		interrupt-controller;
 		clocks = <&mstp9_clks R8A7791_CLK_GPIO5>;
+		power-domains = <&cpg_clocks>;
 	};
 
 	gpio6: gpio at e6055400 {
@@ -163,6 +169,7 @@
 		#interrupt-cells = <2>;
 		interrupt-controller;
 		clocks = <&mstp9_clks R8A7791_CLK_GPIO6>;
+		power-domains = <&cpg_clocks>;
 	};
 
 	gpio7: gpio at e6055800 {
@@ -175,6 +182,7 @@
 		#interrupt-cells = <2>;
 		interrupt-controller;
 		clocks = <&mstp9_clks R8A7791_CLK_GPIO7>;
+		power-domains = <&cpg_clocks>;
 	};
 
 	thermal at e61f0000 {
@@ -182,6 +190,7 @@
 		reg = <0 0xe61f0000 0 0x14>, <0 0xe61f0100 0 0x38>;
 		interrupts = <0 69 IRQ_TYPE_LEVEL_HIGH>;
 		clocks = <&mstp5_clks R8A7791_CLK_THERMAL>;
+		power-domains = <&cpg_clocks>;
 	};
 
 	timer {
@@ -199,6 +208,7 @@
 			     <0 143 IRQ_TYPE_LEVEL_HIGH>;
 		clocks = <&mstp1_clks R8A7791_CLK_CMT0>;
 		clock-names = "fck";
+		power-domains = <&cpg_clocks>;
 
 		renesas,channels-mask = <0x60>;
 
@@ -218,6 +228,7 @@
 			     <0 127 IRQ_TYPE_LEVEL_HIGH>;
 		clocks = <&mstp3_clks R8A7791_CLK_CMT1>;
 		clock-names = "fck";
+		power-domains = <&cpg_clocks>;
 
 		renesas,channels-mask = <0xff>;
 
@@ -240,6 +251,7 @@
 			     <0 16 IRQ_TYPE_LEVEL_HIGH>,
 			     <0 17 IRQ_TYPE_LEVEL_HIGH>;
 		clocks = <&mstp4_clks R8A7791_CLK_IRQC>;
+		power-domains = <&cpg_clocks>;
 	};
 
 	dmac0: dma-controller at e6700000 {
@@ -268,6 +280,7 @@
 				"ch12", "ch13", "ch14";
 		clocks = <&mstp2_clks R8A7791_CLK_SYS_DMAC0>;
 		clock-names = "fck";
+		power-domains = <&cpg_clocks>;
 		#dma-cells = <1>;
 		dma-channels = <15>;
 	};
@@ -298,6 +311,7 @@
 				"ch12", "ch13", "ch14";
 		clocks = <&mstp2_clks R8A7791_CLK_SYS_DMAC1>;
 		clock-names = "fck";
+		power-domains = <&cpg_clocks>;
 		#dma-cells = <1>;
 		dma-channels = <15>;
 	};
@@ -326,6 +340,7 @@
 				"ch12";
 		clocks = <&mstp5_clks R8A7791_CLK_AUDIO_DMAC0>;
 		clock-names = "fck";
+		power-domains = <&cpg_clocks>;
 		#dma-cells = <1>;
 		dma-channels = <13>;
 	};
@@ -354,6 +369,7 @@
 				"ch12";
 		clocks = <&mstp5_clks R8A7791_CLK_AUDIO_DMAC1>;
 		clock-names = "fck";
+		power-domains = <&cpg_clocks>;
 		#dma-cells = <1>;
 		dma-channels = <13>;
 	};
@@ -365,6 +381,7 @@
 			      0 109 IRQ_TYPE_LEVEL_HIGH>;
 		interrupt-names = "ch0", "ch1";
 		clocks = <&mstp3_clks R8A7791_CLK_USBDMAC0>;
+		power-domains = <&cpg_clocks>;
 		#dma-cells = <1>;
 		dma-channels = <2>;
 	};
@@ -376,6 +393,7 @@
 			      0 110 IRQ_TYPE_LEVEL_HIGH>;
 		interrupt-names = "ch0", "ch1";
 		clocks = <&mstp3_clks R8A7791_CLK_USBDMAC1>;
+		power-domains = <&cpg_clocks>;
 		#dma-cells = <1>;
 		dma-channels = <2>;
 	};
@@ -388,6 +406,7 @@
 		reg = <0 0xe6508000 0 0x40>;
 		interrupts = <0 287 IRQ_TYPE_LEVEL_HIGH>;
 		clocks = <&mstp9_clks R8A7791_CLK_I2C0>;
+		power-domains = <&cpg_clocks>;
 		status = "disabled";
 	};
 
@@ -398,6 +417,7 @@
 		reg = <0 0xe6518000 0 0x40>;
 		interrupts = <0 288 IRQ_TYPE_LEVEL_HIGH>;
 		clocks = <&mstp9_clks R8A7791_CLK_I2C1>;
+		power-domains = <&cpg_clocks>;
 		status = "disabled";
 	};
 
@@ -408,6 +428,7 @@
 		reg = <0 0xe6530000 0 0x40>;
 		interrupts = <0 286 IRQ_TYPE_LEVEL_HIGH>;
 		clocks = <&mstp9_clks R8A7791_CLK_I2C2>;
+		power-domains = <&cpg_clocks>;
 		status = "disabled";
 	};
 
@@ -418,6 +439,7 @@
 		reg = <0 0xe6540000 0 0x40>;
 		interrupts = <0 290 IRQ_TYPE_LEVEL_HIGH>;
 		clocks = <&mstp9_clks R8A7791_CLK_I2C3>;
+		power-domains = <&cpg_clocks>;
 		status = "disabled";
 	};
 
@@ -428,6 +450,7 @@
 		reg = <0 0xe6520000 0 0x40>;
 		interrupts = <0 19 IRQ_TYPE_LEVEL_HIGH>;
 		clocks = <&mstp9_clks R8A7791_CLK_I2C4>;
+		power-domains = <&cpg_clocks>;
 		status = "disabled";
 	};
 
@@ -439,6 +462,7 @@
 		reg = <0 0xe6528000 0 0x40>;
 		interrupts = <0 20 IRQ_TYPE_LEVEL_HIGH>;
 		clocks = <&mstp9_clks R8A7791_CLK_I2C5>;
+		power-domains = <&cpg_clocks>;
 		status = "disabled";
 	};
 
@@ -452,6 +476,7 @@
 		clocks = <&mstp9_clks R8A7791_CLK_IICDVFS>;
 		dmas = <&dmac0 0x77>, <&dmac0 0x78>;
 		dma-names = "tx", "rx";
+		power-domains = <&cpg_clocks>;
 		status = "disabled";
 	};
 
@@ -464,6 +489,7 @@
 		clocks = <&mstp3_clks R8A7791_CLK_IIC0>;
 		dmas = <&dmac0 0x61>, <&dmac0 0x62>;
 		dma-names = "tx", "rx";
+		power-domains = <&cpg_clocks>;
 		status = "disabled";
 	};
 
@@ -476,6 +502,7 @@
 		clocks = <&mstp3_clks R8A7791_CLK_IIC1>;
 		dmas = <&dmac0 0x65>, <&dmac0 0x66>;
 		dma-names = "tx", "rx";
+		power-domains = <&cpg_clocks>;
 		status = "disabled";
 	};
 
@@ -492,6 +519,7 @@
 		clocks = <&mstp3_clks R8A7791_CLK_MMCIF0>;
 		dmas = <&dmac0 0xd1>, <&dmac0 0xd2>;
 		dma-names = "tx", "rx";
+		power-domains = <&cpg_clocks>;
 		reg-io-width = <4>;
 		status = "disabled";
 		max-frequency = <97500000>;
@@ -504,6 +532,7 @@
 		clocks = <&mstp3_clks R8A7791_CLK_SDHI0>;
 		dmas = <&dmac1 0xcd>, <&dmac1 0xce>;
 		dma-names = "tx", "rx";
+		power-domains = <&cpg_clocks>;
 		status = "disabled";
 	};
 
@@ -514,6 +543,7 @@
 		clocks = <&mstp3_clks R8A7791_CLK_SDHI1>;
 		dmas = <&dmac1 0xc1>, <&dmac1 0xc2>;
 		dma-names = "tx", "rx";
+		power-domains = <&cpg_clocks>;
 		status = "disabled";
 	};
 
@@ -524,6 +554,7 @@
 		clocks = <&mstp3_clks R8A7791_CLK_SDHI2>;
 		dmas = <&dmac1 0xd3>, <&dmac1 0xd4>;
 		dma-names = "tx", "rx";
+		power-domains = <&cpg_clocks>;
 		status = "disabled";
 	};
 
@@ -535,6 +566,7 @@
 		clock-names = "sci_ick";
 		dmas = <&dmac0 0x21>, <&dmac0 0x22>;
 		dma-names = "tx", "rx";
+		power-domains = <&cpg_clocks>;
 		status = "disabled";
 	};
 
@@ -546,6 +578,7 @@
 		clock-names = "sci_ick";
 		dmas = <&dmac0 0x25>, <&dmac0 0x26>;
 		dma-names = "tx", "rx";
+		power-domains = <&cpg_clocks>;
 		status = "disabled";
 	};
 
@@ -557,6 +590,7 @@
 		clock-names = "sci_ick";
 		dmas = <&dmac0 0x27>, <&dmac0 0x28>;
 		dma-names = "tx", "rx";
+		power-domains = <&cpg_clocks>;
 		status = "disabled";
 	};
 
@@ -568,6 +602,7 @@
 		clock-names = "sci_ick";
 		dmas = <&dmac0 0x1b>, <&dmac0 0x1c>;
 		dma-names = "tx", "rx";
+		power-domains = <&cpg_clocks>;
 		status = "disabled";
 	};
 
@@ -579,6 +614,7 @@
 		clock-names = "sci_ick";
 		dmas = <&dmac0 0x1f>, <&dmac0 0x20>;
 		dma-names = "tx", "rx";
+		power-domains = <&cpg_clocks>;
 		status = "disabled";
 	};
 
@@ -590,6 +626,7 @@
 		clock-names = "sci_ick";
 		dmas = <&dmac0 0x23>, <&dmac0 0x24>;
 		dma-names = "tx", "rx";
+		power-domains = <&cpg_clocks>;
 		status = "disabled";
 	};
 
@@ -601,6 +638,7 @@
 		clock-names = "sci_ick";
 		dmas = <&dmac0 0x3d>, <&dmac0 0x3e>;
 		dma-names = "tx", "rx";
+		power-domains = <&cpg_clocks>;
 		status = "disabled";
 	};
 
@@ -612,6 +650,7 @@
 		clock-names = "sci_ick";
 		dmas = <&dmac0 0x19>, <&dmac0 0x1a>;
 		dma-names = "tx", "rx";
+		power-domains = <&cpg_clocks>;
 		status = "disabled";
 	};
 
@@ -623,6 +662,7 @@
 		clock-names = "sci_ick";
 		dmas = <&dmac0 0x1d>, <&dmac0 0x1e>;
 		dma-names = "tx", "rx";
+		power-domains = <&cpg_clocks>;
 		status = "disabled";
 	};
 
@@ -634,6 +674,7 @@
 		clock-names = "sci_ick";
 		dmas = <&dmac0 0x29>, <&dmac0 0x2a>;
 		dma-names = "tx", "rx";
+		power-domains = <&cpg_clocks>;
 		status = "disabled";
 	};
 
@@ -645,6 +686,7 @@
 		clock-names = "sci_ick";
 		dmas = <&dmac0 0x2d>, <&dmac0 0x2e>;
 		dma-names = "tx", "rx";
+		power-domains = <&cpg_clocks>;
 		status = "disabled";
 	};
 
@@ -656,6 +698,7 @@
 		clock-names = "sci_ick";
 		dmas = <&dmac0 0x2b>, <&dmac0 0x2c>;
 		dma-names = "tx", "rx";
+		power-domains = <&cpg_clocks>;
 		status = "disabled";
 	};
 
@@ -667,6 +710,7 @@
 		clock-names = "sci_ick";
 		dmas = <&dmac0 0x2f>, <&dmac0 0x30>;
 		dma-names = "tx", "rx";
+		power-domains = <&cpg_clocks>;
 		status = "disabled";
 	};
 
@@ -678,6 +722,7 @@
 		clock-names = "sci_ick";
 		dmas = <&dmac0 0xfb>, <&dmac0 0xfc>;
 		dma-names = "tx", "rx";
+		power-domains = <&cpg_clocks>;
 		status = "disabled";
 	};
 
@@ -689,6 +734,7 @@
 		clock-names = "sci_ick";
 		dmas = <&dmac0 0xfd>, <&dmac0 0xfe>;
 		dma-names = "tx", "rx";
+		power-domains = <&cpg_clocks>;
 		status = "disabled";
 	};
 
@@ -700,6 +746,7 @@
 		clock-names = "sci_ick";
 		dmas = <&dmac0 0x39>, <&dmac0 0x3a>;
 		dma-names = "tx", "rx";
+		power-domains = <&cpg_clocks>;
 		status = "disabled";
 	};
 
@@ -711,6 +758,7 @@
 		clock-names = "sci_ick";
 		dmas = <&dmac0 0x4d>, <&dmac0 0x4e>;
 		dma-names = "tx", "rx";
+		power-domains = <&cpg_clocks>;
 		status = "disabled";
 	};
 
@@ -722,6 +770,7 @@
 		clock-names = "sci_ick";
 		dmas = <&dmac0 0x3b>, <&dmac0 0x3c>;
 		dma-names = "tx", "rx";
+		power-domains = <&cpg_clocks>;
 		status = "disabled";
 	};
 
@@ -730,6 +779,7 @@
 		reg = <0 0xee700000 0 0x400>;
 		interrupts = <0 162 IRQ_TYPE_LEVEL_HIGH>;
 		clocks = <&mstp8_clks R8A7791_CLK_ETHER>;
+		power-domains = <&cpg_clocks>;
 		phy-mode = "rmii";
 		#address-cells = <1>;
 		#size-cells = <0>;
@@ -741,6 +791,7 @@
 		reg = <0 0xee300000 0 0x2000>;
 		interrupts = <0 105 IRQ_TYPE_LEVEL_HIGH>;
 		clocks = <&mstp8_clks R8A7791_CLK_SATA0>;
+		power-domains = <&cpg_clocks>;
 		status = "disabled";
 	};
 
@@ -749,6 +800,7 @@
 		reg = <0 0xee500000 0 0x2000>;
 		interrupts = <0 106 IRQ_TYPE_LEVEL_HIGH>;
 		clocks = <&mstp8_clks R8A7791_CLK_SATA1>;
+		power-domains = <&cpg_clocks>;
 		status = "disabled";
 	};
 
@@ -757,12 +809,13 @@
 		reg = <0 0xe6590000 0 0x100>;
 		interrupts = <0 107 IRQ_TYPE_LEVEL_HIGH>;
 		clocks = <&mstp7_clks R8A7791_CLK_HSUSB>;
-		renesas,buswait = <4>;
-		phys = <&usb0 1>;
-		phy-names = "usb";
 		dmas = <&usb_dmac0 0>, <&usb_dmac0 1>,
 		       <&usb_dmac1 0>, <&usb_dmac1 1>;
 		dma-names = "ch0", "ch1", "ch2", "ch3";
+		power-domains = <&cpg_clocks>;
+		renesas,buswait = <4>;
+		phys = <&usb0 1>;
+		phy-names = "usb";
 		status = "disabled";
 	};
 
@@ -773,6 +826,7 @@
 		#size-cells = <0>;
 		clocks = <&mstp7_clks R8A7791_CLK_HSUSB>;
 		clock-names = "usbhs";
+		power-domains = <&cpg_clocks>;
 		status = "disabled";
 
 		usb0: usb-channel at 0 {
@@ -787,25 +841,28 @@
 
 	vin0: video at e6ef0000 {
 		compatible = "renesas,vin-r8a7791";
-		clocks = <&mstp8_clks R8A7791_CLK_VIN0>;
 		reg = <0 0xe6ef0000 0 0x1000>;
 		interrupts = <0 188 IRQ_TYPE_LEVEL_HIGH>;
+		clocks = <&mstp8_clks R8A7791_CLK_VIN0>;
+		power-domains = <&cpg_clocks>;
 		status = "disabled";
 	};
 
 	vin1: video at e6ef1000 {
 		compatible = "renesas,vin-r8a7791";
-		clocks = <&mstp8_clks R8A7791_CLK_VIN1>;
 		reg = <0 0xe6ef1000 0 0x1000>;
 		interrupts = <0 189 IRQ_TYPE_LEVEL_HIGH>;
+		clocks = <&mstp8_clks R8A7791_CLK_VIN1>;
+		power-domains = <&cpg_clocks>;
 		status = "disabled";
 	};
 
 	vin2: video at e6ef2000 {
 		compatible = "renesas,vin-r8a7791";
-		clocks = <&mstp8_clks R8A7791_CLK_VIN2>;
 		reg = <0 0xe6ef2000 0 0x1000>;
 		interrupts = <0 190 IRQ_TYPE_LEVEL_HIGH>;
+		clocks = <&mstp8_clks R8A7791_CLK_VIN2>;
+		power-domains = <&cpg_clocks>;
 		status = "disabled";
 	};
 
@@ -814,6 +871,7 @@
 		reg = <0 0xfe928000 0 0x8000>;
 		interrupts = <0 267 IRQ_TYPE_LEVEL_HIGH>;
 		clocks = <&mstp1_clks R8A7791_CLK_VSP1_S>;
+		power-domains = <&cpg_clocks>;
 
 		renesas,has-lut;
 		renesas,has-sru;
@@ -827,6 +885,7 @@
 		reg = <0 0xfe930000 0 0x8000>;
 		interrupts = <0 246 IRQ_TYPE_LEVEL_HIGH>;
 		clocks = <&mstp1_clks R8A7791_CLK_VSP1_DU0>;
+		power-domains = <&cpg_clocks>;
 
 		renesas,has-lif;
 		renesas,has-lut;
@@ -840,6 +899,7 @@
 		reg = <0 0xfe938000 0 0x8000>;
 		interrupts = <0 247 IRQ_TYPE_LEVEL_HIGH>;
 		clocks = <&mstp1_clks R8A7791_CLK_VSP1_DU1>;
+		power-domains = <&cpg_clocks>;
 
 		renesas,has-lif;
 		renesas,has-lut;
@@ -885,6 +945,7 @@
 		clocks = <&mstp9_clks R8A7791_CLK_RCAN0>,
 			 <&cpg_clocks R8A7791_CLK_RCAN>, <&can_clk>;
 		clock-names = "clkp1", "clkp2", "can_clk";
+		power-domains = <&cpg_clocks>;
 		status = "disabled";
 	};
 
@@ -895,6 +956,7 @@
 		clocks = <&mstp9_clks R8A7791_CLK_RCAN1>,
 			 <&cpg_clocks R8A7791_CLK_RCAN>, <&can_clk>;
 		clock-names = "clkp1", "clkp2", "can_clk";
+		power-domains = <&cpg_clocks>;
 		status = "disabled";
 	};
 
@@ -903,6 +965,7 @@
 		reg = <0 0xfe980000 0 0x10300>;
 		interrupts = <0 272 IRQ_TYPE_LEVEL_HIGH>;
 		clocks = <&mstp1_clks R8A7791_CLK_JPU>;
+		power-domains = <&cpg_clocks>;
 	};
 
 	clocks {
@@ -979,6 +1042,7 @@
 			clock-output-names = "main", "pll0", "pll1", "pll3",
 					     "lb", "qspi", "sdh", "sd0", "z",
 					     "rcan", "adsp";
+			#power-domain-cells = <0>;
 		};
 
 		/* Variable factor clocks */
@@ -1361,6 +1425,7 @@
 		clocks = <&mstp9_clks R8A7791_CLK_QSPI_MOD>;
 		dmas = <&dmac0 0x17>, <&dmac0 0x18>;
 		dma-names = "tx", "rx";
+		power-domains = <&cpg_clocks>;
 		num-cs = <1>;
 		#address-cells = <1>;
 		#size-cells = <0>;
@@ -1374,6 +1439,7 @@
 		clocks = <&mstp0_clks R8A7791_CLK_MSIOF0>;
 		dmas = <&dmac0 0x51>, <&dmac0 0x52>;
 		dma-names = "tx", "rx";
+		power-domains = <&cpg_clocks>;
 		#address-cells = <1>;
 		#size-cells = <0>;
 		status = "disabled";
@@ -1386,6 +1452,7 @@
 		clocks = <&mstp2_clks R8A7791_CLK_MSIOF1>;
 		dmas = <&dmac0 0x55>, <&dmac0 0x56>;
 		dma-names = "tx", "rx";
+		power-domains = <&cpg_clocks>;
 		#address-cells = <1>;
 		#size-cells = <0>;
 		status = "disabled";
@@ -1398,6 +1465,7 @@
 		clocks = <&mstp2_clks R8A7791_CLK_MSIOF2>;
 		dmas = <&dmac0 0x41>, <&dmac0 0x42>;
 		dma-names = "tx", "rx";
+		power-domains = <&cpg_clocks>;
 		#address-cells = <1>;
 		#size-cells = <0>;
 		status = "disabled";
@@ -1408,6 +1476,7 @@
 		reg = <0 0xee000000 0 0xc00>;
 		interrupts = <0 101 IRQ_TYPE_LEVEL_HIGH>;
 		clocks = <&mstp3_clks R8A7791_CLK_SSUSB>;
+		power-domains = <&cpg_clocks>;
 		phys = <&usb2 1>;
 		phy-names = "usb";
 		status = "disabled";
@@ -1416,10 +1485,11 @@
 	pci0: pci at ee090000 {
 		compatible = "renesas,pci-r8a7791";
 		device_type = "pci";
-		clocks = <&mstp7_clks R8A7791_CLK_EHCI>;
 		reg = <0 0xee090000 0 0xc00>,
 		      <0 0xee080000 0 0x1100>;
 		interrupts = <0 108 IRQ_TYPE_LEVEL_HIGH>;
+		clocks = <&mstp7_clks R8A7791_CLK_EHCI>;
+		power-domains = <&cpg_clocks>;
 		status = "disabled";
 
 		bus-range = <0 0>;
@@ -1450,10 +1520,11 @@
 	pci1: pci at ee0d0000 {
 		compatible = "renesas,pci-r8a7791";
 		device_type = "pci";
-		clocks = <&mstp7_clks R8A7791_CLK_EHCI>;
 		reg = <0 0xee0d0000 0 0xc00>,
 		      <0 0xee0c0000 0 0x1100>;
 		interrupts = <0 113 IRQ_TYPE_LEVEL_HIGH>;
+		clocks = <&mstp7_clks R8A7791_CLK_EHCI>;
+		power-domains = <&cpg_clocks>;
 		status = "disabled";
 
 		bus-range = <1 1>;
@@ -1503,6 +1574,7 @@
 		interrupt-map = <0 0 0 0 &gic 0 116 IRQ_TYPE_LEVEL_HIGH>;
 		clocks = <&mstp3_clks R8A7791_CLK_PCIEC>, <&pcie_bus_clk>;
 		clock-names = "pcie", "pcie_bus";
+		power-domains = <&cpg_clocks>;
 		status = "disabled";
 	};
 
-- 
2.1.4



From horms+renesas at verge.net.au  Thu Aug  6 19:12:08 2015
From: horms+renesas at verge.net.au (Simon Horman)
Date: Fri,  7 Aug 2015 11:12:08 +0900
Subject: [PATCH 09/12] ARM: shmobile: r8a7790 dtsi: Add CPG/MSTP Clock Domain
In-Reply-To: <cover.1438911559.git.horms+renesas@verge.net.au>
References: <cover.1438911559.git.horms+renesas@verge.net.au>
Message-ID: <394839b5c7948aa93ec755fb26c50dc815aac93f.1438911559.git.horms+renesas@verge.net.au>

From: Geert Uytterhoeven <geert+renesas at glider.be>

Add an appropriate "#power-domain-cells" property to the cpg_clocks
device node, to create the CPG/MSTP Clock Domain.

Add "power-domains" properties to all device nodes for devices that are
part of the CPG/MSTP Clock Domain and can be power-managed through an
MSTP clock.  This applies to most on-SoC devices, which have a
one-to-one mapping from SoC device to DT device node.  Notable
exceptions are the "display" and "sound" nodes, which represent multiple
SoC devices, each having their own MSTP clocks.

Signed-off-by: Geert Uytterhoeven <geert+renesas at glider.be>
Reviewed-by: Ulf Hansson <ulf.hansson at linaro.org>
Signed-off-by: Simon Horman <horms+renesas at verge.net.au>
---
 arch/arm/boot/dts/r8a7790.dtsi | 86 +++++++++++++++++++++++++++++++++++++-----
 1 file changed, 77 insertions(+), 9 deletions(-)

diff --git a/arch/arm/boot/dts/r8a7790.dtsi b/arch/arm/boot/dts/r8a7790.dtsi
index 5b2952d5c700..a0b2a79cbfbd 100644
--- a/arch/arm/boot/dts/r8a7790.dtsi
+++ b/arch/arm/boot/dts/r8a7790.dtsi
@@ -134,6 +134,7 @@
 		#interrupt-cells = <2>;
 		interrupt-controller;
 		clocks = <&mstp9_clks R8A7790_CLK_GPIO0>;
+		power-domains = <&cpg_clocks>;
 	};
 
 	gpio1: gpio at e6051000 {
@@ -146,6 +147,7 @@
 		#interrupt-cells = <2>;
 		interrupt-controller;
 		clocks = <&mstp9_clks R8A7790_CLK_GPIO1>;
+		power-domains = <&cpg_clocks>;
 	};
 
 	gpio2: gpio at e6052000 {
@@ -158,6 +160,7 @@
 		#interrupt-cells = <2>;
 		interrupt-controller;
 		clocks = <&mstp9_clks R8A7790_CLK_GPIO2>;
+		power-domains = <&cpg_clocks>;
 	};
 
 	gpio3: gpio at e6053000 {
@@ -170,6 +173,7 @@
 		#interrupt-cells = <2>;
 		interrupt-controller;
 		clocks = <&mstp9_clks R8A7790_CLK_GPIO3>;
+		power-domains = <&cpg_clocks>;
 	};
 
 	gpio4: gpio at e6054000 {
@@ -182,6 +186,7 @@
 		#interrupt-cells = <2>;
 		interrupt-controller;
 		clocks = <&mstp9_clks R8A7790_CLK_GPIO4>;
+		power-domains = <&cpg_clocks>;
 	};
 
 	gpio5: gpio at e6055000 {
@@ -194,6 +199,7 @@
 		#interrupt-cells = <2>;
 		interrupt-controller;
 		clocks = <&mstp9_clks R8A7790_CLK_GPIO5>;
+		power-domains = <&cpg_clocks>;
 	};
 
 	thermal at e61f0000 {
@@ -201,6 +207,7 @@
 		reg = <0 0xe61f0000 0 0x14>, <0 0xe61f0100 0 0x38>;
 		interrupts = <0 69 IRQ_TYPE_LEVEL_HIGH>;
 		clocks = <&mstp5_clks R8A7790_CLK_THERMAL>;
+		power-domains = <&cpg_clocks>;
 	};
 
 	timer {
@@ -218,6 +225,7 @@
 			     <0 143 IRQ_TYPE_LEVEL_HIGH>;
 		clocks = <&mstp1_clks R8A7790_CLK_CMT0>;
 		clock-names = "fck";
+		power-domains = <&cpg_clocks>;
 
 		renesas,channels-mask = <0x60>;
 
@@ -237,6 +245,7 @@
 			     <0 127 IRQ_TYPE_LEVEL_HIGH>;
 		clocks = <&mstp3_clks R8A7790_CLK_CMT1>;
 		clock-names = "fck";
+		power-domains = <&cpg_clocks>;
 
 		renesas,channels-mask = <0xff>;
 
@@ -253,6 +262,7 @@
 			     <0 2 IRQ_TYPE_LEVEL_HIGH>,
 			     <0 3 IRQ_TYPE_LEVEL_HIGH>;
 		clocks = <&mstp4_clks R8A7790_CLK_IRQC>;
+		power-domains = <&cpg_clocks>;
 	};
 
 	dmac0: dma-controller at e6700000 {
@@ -281,6 +291,7 @@
 				"ch12", "ch13", "ch14";
 		clocks = <&mstp2_clks R8A7790_CLK_SYS_DMAC0>;
 		clock-names = "fck";
+		power-domains = <&cpg_clocks>;
 		#dma-cells = <1>;
 		dma-channels = <15>;
 	};
@@ -311,6 +322,7 @@
 				"ch12", "ch13", "ch14";
 		clocks = <&mstp2_clks R8A7790_CLK_SYS_DMAC1>;
 		clock-names = "fck";
+		power-domains = <&cpg_clocks>;
 		#dma-cells = <1>;
 		dma-channels = <15>;
 	};
@@ -339,6 +351,7 @@
 				"ch12";
 		clocks = <&mstp5_clks R8A7790_CLK_AUDIO_DMAC0>;
 		clock-names = "fck";
+		power-domains = <&cpg_clocks>;
 		#dma-cells = <1>;
 		dma-channels = <13>;
 	};
@@ -367,6 +380,7 @@
 				"ch12";
 		clocks = <&mstp5_clks R8A7790_CLK_AUDIO_DMAC1>;
 		clock-names = "fck";
+		power-domains = <&cpg_clocks>;
 		#dma-cells = <1>;
 		dma-channels = <13>;
 	};
@@ -378,6 +392,7 @@
 			      0 109 IRQ_TYPE_LEVEL_HIGH>;
 		interrupt-names = "ch0", "ch1";
 		clocks = <&mstp3_clks R8A7790_CLK_USBDMAC0>;
+		power-domains = <&cpg_clocks>;
 		#dma-cells = <1>;
 		dma-channels = <2>;
 	};
@@ -389,6 +404,7 @@
 			      0 110 IRQ_TYPE_LEVEL_HIGH>;
 		interrupt-names = "ch0", "ch1";
 		clocks = <&mstp3_clks R8A7790_CLK_USBDMAC1>;
+		power-domains = <&cpg_clocks>;
 		#dma-cells = <1>;
 		dma-channels = <2>;
 	};
@@ -400,6 +416,7 @@
 		reg = <0 0xe6508000 0 0x40>;
 		interrupts = <0 287 IRQ_TYPE_LEVEL_HIGH>;
 		clocks = <&mstp9_clks R8A7790_CLK_I2C0>;
+		power-domains = <&cpg_clocks>;
 		status = "disabled";
 	};
 
@@ -410,6 +427,7 @@
 		reg = <0 0xe6518000 0 0x40>;
 		interrupts = <0 288 IRQ_TYPE_LEVEL_HIGH>;
 		clocks = <&mstp9_clks R8A7790_CLK_I2C1>;
+		power-domains = <&cpg_clocks>;
 		status = "disabled";
 	};
 
@@ -420,6 +438,7 @@
 		reg = <0 0xe6530000 0 0x40>;
 		interrupts = <0 286 IRQ_TYPE_LEVEL_HIGH>;
 		clocks = <&mstp9_clks R8A7790_CLK_I2C2>;
+		power-domains = <&cpg_clocks>;
 		status = "disabled";
 	};
 
@@ -430,6 +449,7 @@
 		reg = <0 0xe6540000 0 0x40>;
 		interrupts = <0 290 IRQ_TYPE_LEVEL_HIGH>;
 		clocks = <&mstp9_clks R8A7790_CLK_I2C3>;
+		power-domains = <&cpg_clocks>;
 		status = "disabled";
 	};
 
@@ -442,6 +462,7 @@
 		clocks = <&mstp3_clks R8A7790_CLK_IIC0>;
 		dmas = <&dmac0 0x61>, <&dmac0 0x62>;
 		dma-names = "tx", "rx";
+		power-domains = <&cpg_clocks>;
 		status = "disabled";
 	};
 
@@ -454,6 +475,7 @@
 		clocks = <&mstp3_clks R8A7790_CLK_IIC1>;
 		dmas = <&dmac0 0x65>, <&dmac0 0x66>;
 		dma-names = "tx", "rx";
+		power-domains = <&cpg_clocks>;
 		status = "disabled";
 	};
 
@@ -466,6 +488,7 @@
 		clocks = <&mstp3_clks R8A7790_CLK_IIC2>;
 		dmas = <&dmac0 0x69>, <&dmac0 0x6a>;
 		dma-names = "tx", "rx";
+		power-domains = <&cpg_clocks>;
 		status = "disabled";
 	};
 
@@ -478,6 +501,7 @@
 		clocks = <&mstp9_clks R8A7790_CLK_IICDVFS>;
 		dmas = <&dmac0 0x77>, <&dmac0 0x78>;
 		dma-names = "tx", "rx";
+		power-domains = <&cpg_clocks>;
 		status = "disabled";
 	};
 
@@ -488,6 +512,7 @@
 		clocks = <&mstp3_clks R8A7790_CLK_MMCIF0>;
 		dmas = <&dmac0 0xd1>, <&dmac0 0xd2>;
 		dma-names = "tx", "rx";
+		power-domains = <&cpg_clocks>;
 		reg-io-width = <4>;
 		status = "disabled";
 		max-frequency = <97500000>;
@@ -500,6 +525,7 @@
 		clocks = <&mstp3_clks R8A7790_CLK_MMCIF1>;
 		dmas = <&dmac0 0xe1>, <&dmac0 0xe2>;
 		dma-names = "tx", "rx";
+		power-domains = <&cpg_clocks>;
 		reg-io-width = <4>;
 		status = "disabled";
 		max-frequency = <97500000>;
@@ -517,6 +543,7 @@
 		clocks = <&mstp3_clks R8A7790_CLK_SDHI0>;
 		dmas = <&dmac1 0xcd>, <&dmac1 0xce>;
 		dma-names = "tx", "rx";
+		power-domains = <&cpg_clocks>;
 		status = "disabled";
 	};
 
@@ -527,6 +554,7 @@
 		clocks = <&mstp3_clks R8A7790_CLK_SDHI1>;
 		dmas = <&dmac1 0xc9>, <&dmac1 0xca>;
 		dma-names = "tx", "rx";
+		power-domains = <&cpg_clocks>;
 		status = "disabled";
 	};
 
@@ -537,6 +565,7 @@
 		clocks = <&mstp3_clks R8A7790_CLK_SDHI2>;
 		dmas = <&dmac1 0xc1>, <&dmac1 0xc2>;
 		dma-names = "tx", "rx";
+		power-domains = <&cpg_clocks>;
 		status = "disabled";
 	};
 
@@ -547,6 +576,7 @@
 		clocks = <&mstp3_clks R8A7790_CLK_SDHI3>;
 		dmas = <&dmac1 0xd3>, <&dmac1 0xd4>;
 		dma-names = "tx", "rx";
+		power-domains = <&cpg_clocks>;
 		status = "disabled";
 	};
 
@@ -558,6 +588,7 @@
 		clock-names = "sci_ick";
 		dmas = <&dmac0 0x21>, <&dmac0 0x22>;
 		dma-names = "tx", "rx";
+		power-domains = <&cpg_clocks>;
 		status = "disabled";
 	};
 
@@ -569,6 +600,7 @@
 		clock-names = "sci_ick";
 		dmas = <&dmac0 0x25>, <&dmac0 0x26>;
 		dma-names = "tx", "rx";
+		power-domains = <&cpg_clocks>;
 		status = "disabled";
 	};
 
@@ -580,6 +612,7 @@
 		clock-names = "sci_ick";
 		dmas = <&dmac0 0x27>, <&dmac0 0x28>;
 		dma-names = "tx", "rx";
+		power-domains = <&cpg_clocks>;
 		status = "disabled";
 	};
 
@@ -591,6 +624,7 @@
 		clock-names = "sci_ick";
 		dmas = <&dmac0 0x3d>, <&dmac0 0x3e>;
 		dma-names = "tx", "rx";
+		power-domains = <&cpg_clocks>;
 		status = "disabled";
 	};
 
@@ -602,6 +636,7 @@
 		clock-names = "sci_ick";
 		dmas = <&dmac0 0x19>, <&dmac0 0x1a>;
 		dma-names = "tx", "rx";
+		power-domains = <&cpg_clocks>;
 		status = "disabled";
 	};
 
@@ -613,6 +648,7 @@
 		clock-names = "sci_ick";
 		dmas = <&dmac0 0x1d>, <&dmac0 0x1e>;
 		dma-names = "tx", "rx";
+		power-domains = <&cpg_clocks>;
 		status = "disabled";
 	};
 
@@ -624,6 +660,7 @@
 		clock-names = "sci_ick";
 		dmas = <&dmac0 0x29>, <&dmac0 0x2a>;
 		dma-names = "tx", "rx";
+		power-domains = <&cpg_clocks>;
 		status = "disabled";
 	};
 
@@ -635,6 +672,7 @@
 		clock-names = "sci_ick";
 		dmas = <&dmac0 0x2d>, <&dmac0 0x2e>;
 		dma-names = "tx", "rx";
+		power-domains = <&cpg_clocks>;
 		status = "disabled";
 	};
 
@@ -646,6 +684,7 @@
 		clock-names = "sci_ick";
 		dmas = <&dmac0 0x39>, <&dmac0 0x3a>;
 		dma-names = "tx", "rx";
+		power-domains = <&cpg_clocks>;
 		status = "disabled";
 	};
 
@@ -657,6 +696,7 @@
 		clock-names = "sci_ick";
 		dmas = <&dmac0 0x4d>, <&dmac0 0x4e>;
 		dma-names = "tx", "rx";
+		power-domains = <&cpg_clocks>;
 		status = "disabled";
 	};
 
@@ -665,6 +705,7 @@
 		reg = <0 0xee700000 0 0x400>;
 		interrupts = <0 162 IRQ_TYPE_LEVEL_HIGH>;
 		clocks = <&mstp8_clks R8A7790_CLK_ETHER>;
+		power-domains = <&cpg_clocks>;
 		phy-mode = "rmii";
 		#address-cells = <1>;
 		#size-cells = <0>;
@@ -676,6 +717,7 @@
 		reg = <0 0xe6800000 0 0x800>, <0 0xee0e8000 0 0x4000>;
 		interrupts = <0 163 IRQ_TYPE_LEVEL_HIGH>;
 		clocks = <&mstp8_clks R8A7790_CLK_ETHERAVB>;
+		power-domains = <&cpg_clocks>;
 		#address-cells = <1>;
 		#size-cells = <0>;
 		status = "disabled";
@@ -686,6 +728,7 @@
 		reg = <0 0xee300000 0 0x2000>;
 		interrupts = <0 105 IRQ_TYPE_LEVEL_HIGH>;
 		clocks = <&mstp8_clks R8A7790_CLK_SATA0>;
+		power-domains = <&cpg_clocks>;
 		status = "disabled";
 	};
 
@@ -694,6 +737,7 @@
 		reg = <0 0xee500000 0 0x2000>;
 		interrupts = <0 106 IRQ_TYPE_LEVEL_HIGH>;
 		clocks = <&mstp8_clks R8A7790_CLK_SATA1>;
+		power-domains = <&cpg_clocks>;
 		status = "disabled";
 	};
 
@@ -702,12 +746,13 @@
 		reg = <0 0xe6590000 0 0x100>;
 		interrupts = <0 107 IRQ_TYPE_LEVEL_HIGH>;
 		clocks = <&mstp7_clks R8A7790_CLK_HSUSB>;
-		renesas,buswait = <4>;
-		phys = <&usb0 1>;
-		phy-names = "usb";
 		dmas = <&usb_dmac0 0>, <&usb_dmac0 1>,
 		       <&usb_dmac1 0>, <&usb_dmac1 1>;
 		dma-names = "ch0", "ch1", "ch2", "ch3";
+		power-domains = <&cpg_clocks>;
+		renesas,buswait = <4>;
+		phys = <&usb0 1>;
+		phy-names = "usb";
 		status = "disabled";
 	};
 
@@ -718,6 +763,7 @@
 		#size-cells = <0>;
 		clocks = <&mstp7_clks R8A7790_CLK_HSUSB>;
 		clock-names = "usbhs";
+		power-domains = <&cpg_clocks>;
 		status = "disabled";
 
 		usb0: usb-channel at 0 {
@@ -732,33 +778,37 @@
 
 	vin0: video at e6ef0000 {
 		compatible = "renesas,vin-r8a7790";
-		clocks = <&mstp8_clks R8A7790_CLK_VIN0>;
 		reg = <0 0xe6ef0000 0 0x1000>;
 		interrupts = <0 188 IRQ_TYPE_LEVEL_HIGH>;
+		clocks = <&mstp8_clks R8A7790_CLK_VIN0>;
+		power-domains = <&cpg_clocks>;
 		status = "disabled";
 	};
 
 	vin1: video at e6ef1000 {
 		compatible = "renesas,vin-r8a7790";
-		clocks = <&mstp8_clks R8A7790_CLK_VIN1>;
 		reg = <0 0xe6ef1000 0 0x1000>;
 		interrupts = <0 189 IRQ_TYPE_LEVEL_HIGH>;
+		clocks = <&mstp8_clks R8A7790_CLK_VIN1>;
+		power-domains = <&cpg_clocks>;
 		status = "disabled";
 	};
 
 	vin2: video at e6ef2000 {
 		compatible = "renesas,vin-r8a7790";
-		clocks = <&mstp8_clks R8A7790_CLK_VIN2>;
 		reg = <0 0xe6ef2000 0 0x1000>;
 		interrupts = <0 190 IRQ_TYPE_LEVEL_HIGH>;
+		clocks = <&mstp8_clks R8A7790_CLK_VIN2>;
+		power-domains = <&cpg_clocks>;
 		status = "disabled";
 	};
 
 	vin3: video at e6ef3000 {
 		compatible = "renesas,vin-r8a7790";
-		clocks = <&mstp8_clks R8A7790_CLK_VIN3>;
 		reg = <0 0xe6ef3000 0 0x1000>;
 		interrupts = <0 191 IRQ_TYPE_LEVEL_HIGH>;
+		clocks = <&mstp8_clks R8A7790_CLK_VIN3>;
+		power-domains = <&cpg_clocks>;
 		status = "disabled";
 	};
 
@@ -767,6 +817,7 @@
 		reg = <0 0xfe920000 0 0x8000>;
 		interrupts = <0 266 IRQ_TYPE_LEVEL_HIGH>;
 		clocks = <&mstp1_clks R8A7790_CLK_VSP1_R>;
+		power-domains = <&cpg_clocks>;
 
 		renesas,has-sru;
 		renesas,#rpf = <5>;
@@ -779,6 +830,7 @@
 		reg = <0 0xfe928000 0 0x8000>;
 		interrupts = <0 267 IRQ_TYPE_LEVEL_HIGH>;
 		clocks = <&mstp1_clks R8A7790_CLK_VSP1_S>;
+		power-domains = <&cpg_clocks>;
 
 		renesas,has-lut;
 		renesas,has-sru;
@@ -792,6 +844,7 @@
 		reg = <0 0xfe930000 0 0x8000>;
 		interrupts = <0 246 IRQ_TYPE_LEVEL_HIGH>;
 		clocks = <&mstp1_clks R8A7790_CLK_VSP1_DU0>;
+		power-domains = <&cpg_clocks>;
 
 		renesas,has-lif;
 		renesas,has-lut;
@@ -805,6 +858,7 @@
 		reg = <0 0xfe938000 0 0x8000>;
 		interrupts = <0 247 IRQ_TYPE_LEVEL_HIGH>;
 		clocks = <&mstp1_clks R8A7790_CLK_VSP1_DU1>;
+		power-domains = <&cpg_clocks>;
 
 		renesas,has-lif;
 		renesas,has-lut;
@@ -859,6 +913,7 @@
 		clocks = <&mstp9_clks R8A7790_CLK_RCAN0>,
 			 <&cpg_clocks R8A7790_CLK_RCAN>, <&can_clk>;
 		clock-names = "clkp1", "clkp2", "can_clk";
+		power-domains = <&cpg_clocks>;
 		status = "disabled";
 	};
 
@@ -869,6 +924,7 @@
 		clocks = <&mstp9_clks R8A7790_CLK_RCAN1>,
 			 <&cpg_clocks R8A7790_CLK_RCAN>, <&can_clk>;
 		clock-names = "clkp1", "clkp2", "can_clk";
+		power-domains = <&cpg_clocks>;
 		status = "disabled";
 	};
 
@@ -877,6 +933,7 @@
 		reg = <0 0xfe980000 0 0x10300>;
 		interrupts = <0 272 IRQ_TYPE_LEVEL_HIGH>;
 		clocks = <&mstp1_clks R8A7790_CLK_JPU>;
+		power-domains = <&cpg_clocks>;
 	};
 
 	clocks {
@@ -953,6 +1010,7 @@
 			clock-output-names = "main", "pll0", "pll1", "pll3",
 					     "lb", "qspi", "sdh", "sd0", "sd1",
 					     "z", "rcan", "adsp";
+			#power-domain-cells = <0>;
 		};
 
 		/* Variable factor clocks */
@@ -1343,6 +1401,7 @@
 		clocks = <&mstp9_clks R8A7790_CLK_QSPI_MOD>;
 		dmas = <&dmac0 0x17>, <&dmac0 0x18>;
 		dma-names = "tx", "rx";
+		power-domains = <&cpg_clocks>;
 		num-cs = <1>;
 		#address-cells = <1>;
 		#size-cells = <0>;
@@ -1356,6 +1415,7 @@
 		clocks = <&mstp0_clks R8A7790_CLK_MSIOF0>;
 		dmas = <&dmac0 0x51>, <&dmac0 0x52>;
 		dma-names = "tx", "rx";
+		power-domains = <&cpg_clocks>;
 		#address-cells = <1>;
 		#size-cells = <0>;
 		status = "disabled";
@@ -1368,6 +1428,7 @@
 		clocks = <&mstp2_clks R8A7790_CLK_MSIOF1>;
 		dmas = <&dmac0 0x55>, <&dmac0 0x56>;
 		dma-names = "tx", "rx";
+		power-domains = <&cpg_clocks>;
 		#address-cells = <1>;
 		#size-cells = <0>;
 		status = "disabled";
@@ -1380,6 +1441,7 @@
 		clocks = <&mstp2_clks R8A7790_CLK_MSIOF2>;
 		dmas = <&dmac0 0x41>, <&dmac0 0x42>;
 		dma-names = "tx", "rx";
+		power-domains = <&cpg_clocks>;
 		#address-cells = <1>;
 		#size-cells = <0>;
 		status = "disabled";
@@ -1392,6 +1454,7 @@
 		clocks = <&mstp2_clks R8A7790_CLK_MSIOF3>;
 		dmas = <&dmac0 0x45>, <&dmac0 0x46>;
 		dma-names = "tx", "rx";
+		power-domains = <&cpg_clocks>;
 		#address-cells = <1>;
 		#size-cells = <0>;
 		status = "disabled";
@@ -1402,6 +1465,7 @@
 		reg = <0 0xee000000 0 0xc00>;
 		interrupts = <0 101 IRQ_TYPE_LEVEL_HIGH>;
 		clocks = <&mstp3_clks R8A7790_CLK_SSUSB>;
+		power-domains = <&cpg_clocks>;
 		phys = <&usb2 1>;
 		phy-names = "usb";
 		status = "disabled";
@@ -1410,10 +1474,11 @@
 	pci0: pci at ee090000 {
 		compatible = "renesas,pci-r8a7790";
 		device_type = "pci";
-		clocks = <&mstp7_clks R8A7790_CLK_EHCI>;
 		reg = <0 0xee090000 0 0xc00>,
 		      <0 0xee080000 0 0x1100>;
 		interrupts = <0 108 IRQ_TYPE_LEVEL_HIGH>;
+		clocks = <&mstp7_clks R8A7790_CLK_EHCI>;
+		power-domains = <&cpg_clocks>;
 		status = "disabled";
 
 		bus-range = <0 0>;
@@ -1444,10 +1509,11 @@
 	pci1: pci at ee0b0000 {
 		compatible = "renesas,pci-r8a7790";
 		device_type = "pci";
-		clocks = <&mstp7_clks R8A7790_CLK_EHCI>;
 		reg = <0 0xee0b0000 0 0xc00>,
 		      <0 0xee0a0000 0 0x1100>;
 		interrupts = <0 112 IRQ_TYPE_LEVEL_HIGH>;
+		clocks = <&mstp7_clks R8A7790_CLK_EHCI>;
+		power-domains = <&cpg_clocks>;
 		status = "disabled";
 
 		bus-range = <1 1>;
@@ -1465,6 +1531,7 @@
 		compatible = "renesas,pci-r8a7790";
 		device_type = "pci";
 		clocks = <&mstp7_clks R8A7790_CLK_EHCI>;
+		power-domains = <&cpg_clocks>;
 		reg = <0 0xee0d0000 0 0xc00>,
 		      <0 0xee0c0000 0 0x1100>;
 		interrupts = <0 113 IRQ_TYPE_LEVEL_HIGH>;
@@ -1517,6 +1584,7 @@
 		interrupt-map = <0 0 0 0 &gic 0 116 IRQ_TYPE_LEVEL_HIGH>;
 		clocks = <&mstp3_clks R8A7790_CLK_PCIEC>, <&pcie_bus_clk>;
 		clock-names = "pcie", "pcie_bus";
+		power-domains = <&cpg_clocks>;
 		status = "disabled";
 	};
 
-- 
2.1.4



From lftan.linux at gmail.com  Thu Aug  6 19:18:45 2015
From: lftan.linux at gmail.com (Ley Foon Tan)
Date: Fri, 7 Aug 2015 10:18:45 +0800
Subject: [PATCH v5 9/9] PCI: xgene: Use pci_scan_root_bus_msi()
In-Reply-To: <55C3911E.9090907@arm.com>
References: <20150804214234.9189.42548.stgit@bhelgaas-glaptop2.roam.corp.google.com>
 <20150804215457.9189.27595.stgit@bhelgaas-glaptop2.roam.corp.google.com>
 <55C37C92.1020509@arm.com>
 <CAFiDJ58U9u0YOzqVbty8+z+sF82h=F09Y0q-Ks8zMDokdiSEbg@mail.gmail.com>
 <55C3911E.9090907@arm.com>
Message-ID: <CAFiDJ5-Xm1E1eJ6NjCYtryOaWsS__U8wuEDLzhBhfShEjj=VhQ@mail.gmail.com>

On Fri, Aug 7, 2015 at 12:53 AM, Marc Zyngier <marc.zyngier at arm.com> wrote:
> On 06/08/15 17:41, Ley Foon Tan wrote:
>> On Thu, Aug 6, 2015 at 11:26 PM, Marc Zyngier <marc.zyngier at arm.com> wrote:
>>> Hi Bjorn,
>>>
>>> On 04/08/15 22:54, Bjorn Helgaas wrote:
>>>> Previously there was no way to specify the MSI controller when creating a
>>>> new PCI root bus, so we had to create the bus, set its MSI controller, then
>>>> scan the bus.  With the new pci_scan_root_bus_msi() interface, we can
>>>> specify the MSI controller up front and get rid of that intermediate step.
>>>>
>>>> Look up the MSI controller first, then use pci_scan_root_bus_msi() to
>>>> create and scan the root PCI bus.
>>>
>>> I'm wondering about these XGene patches.
>>>
>>> With the code that is queued for v4.3 in tip/irq/core, the X-Gene MSI
>>> driver doesn't export a struct msi_controller anymore, and entirely
>>> relies on IRQ domains to identify to be matched with the actual PCI driver.
>>>
>>> Do you intend this as a cleanup until everything lands in mainline? At
>>> that point, we'd be able to remove all traces of struct msi_controller
>>> from this driver.
>>>
>>> Alternatively, we could ask tglx to add an extra patch to the existing
>>> queue in order to clean up pci-xgene.c (nuking the whole
>>> xgene_pcie_msi_enable function).
>>>
>>> Thoughts?
>>
>> In pcie-altera driver, it uses pci_scan_root_bus() and it doesn't call
>> to of_pci_find_msi_chip_by_node() to retrieve msi_controller struct as
>> well.
>> But, the msi domain stuff is still working. Should I change it to
>> pci_scan_root_bus_msi()?
>
> If you're not using struct msi_controller, I don't see a reason to use
> pci_scan_root_bus_msi(). The MSI irq domain patches are queued for 4.3,
> and I don't believe your driver will be merged before that.
>
> Eventually, I'd like to kill msi_controller entirely. It is completely
> redundant with the use of irq domains.
>
Got it. It doesn't require struct msi_controller.
Thanks.

Regards
Ley Foon


From jamesjj.liao at mediatek.com  Thu Aug  6 19:20:18 2015
From: jamesjj.liao at mediatek.com (James Liao)
Date: Fri, 7 Aug 2015 10:20:18 +0800
Subject: [PATCH v6 7/9] clk: mediatek: Add subsystem clocks of MT8173
In-Reply-To: <20150806102059.GQ18700@pengutronix.de>
References: <1438676218-11310-1-git-send-email-jamesjj.liao@mediatek.com>
 <1438676218-11310-8-git-send-email-jamesjj.liao@mediatek.com>
 <20150805064605.GZ18700@pengutronix.de>
 <1438849431.27884.9.camel@mtksdaap41>
 <20150806085354.GN18700@pengutronix.de>
 <1438851644.27884.21.camel@mtksdaap41>
 <CAGS+omAAYZyZJ4+eSdu2jmwThvHg1YpVoehui_cqNp4A5fURWg@mail.gmail.com>
 <20150806102059.GQ18700@pengutronix.de>
Message-ID: <1438914018.29334.6.camel@mtksdaap41>

Hi Sascha,

On Thu, 2015-08-06 at 12:20 +0200, Sascha Hauer wrote:
> On Thu, Aug 06, 2015 at 05:13:21PM +0800, Daniel Kurtz wrote:
> > On Thu, Aug 6, 2015 at 5:00 PM, James Liao <jamesjj.liao at mediatek.com> wrote:
> > > Hi Sascha,
> > >
> > > On Thu, 2015-08-06 at 10:53 +0200, Sascha Hauer wrote:
> > >> On Thu, Aug 06, 2015 at 04:23:51PM +0800, James Liao wrote:
> > >> > On Wed, 2015-08-05 at 08:46 +0200, Sascha Hauer wrote:
> > >> > > On Tue, Aug 04, 2015 at 04:16:56PM +0800, James Liao wrote:
> > >> > > >  static const struct mtk_fixed_clk fixed_clks[] __initconst = {
> > >> > > >         FIXED_CLK(CLK_TOP_CLKPH_MCK_O, "clkph_mck_o", "clk26m", 400 * MHZ),
> > >> > > >         FIXED_CLK(CLK_TOP_USB_SYSPLL_125M, "usb_syspll_125m", "clk26m", 125 * MHZ),
> > >> > > > +       FIXED_CLK(CLK_TOP_DSI0_DIG, "dsi0_dig", "clk26m", 130 * MHZ),
> > >> > > > +       FIXED_CLK(CLK_TOP_DSI1_DIG, "dsi1_dig", "clk26m", 130 * MHZ),
> > >> > > > +       FIXED_CLK(CLK_TOP_LVDS_PXL, "lvds_pxl", "lvdspll", 148.5 * MHZ),
> > >> > > > +       FIXED_CLK(CLK_TOP_LVDS_CTS, "lvds_cts", "lvdspll", 51.975 * MHZ),
> > >> > >
> > >> > > I would expect 51975 * KHZ here to avoid fractional numbers. Probably
> > >> > > gcc calculates that during compile time so this will work as expected,
> > >> > > still I'm not sure this is good style to use fractional numbers here.
> > >> >
> > >> > As I know all constants will be calculated in compile time, so there
> > >> > should be no difference between 51.975 * MHZ and 51975 * KHz.
> > >> >
> > >> > > Anyway, on my system lvdspll is running at 150MHz. Are you sure there is
> > >> > > a clock derived from this running at 148.5MHz? Is it really correct to
> > >> > > use a fixed clock here or should it rather be lvdspll directly?
> > >> >
> > >> > Here is the clock hierarchy between lvdspll and lvds_pxl:
> > >> >
> > >> >             --------       AD_VPLL_DPIX_CK  --------   lvds_pxl  -----
> > >> >            |        |--------------------->|        |---------->|
> > >> >            |        |                      | cksys  |           |
> > >> > LVDSPLL -->| LVDSTX |                      | buffer |           | MMSYS
> > >> >            |        | AD_LVDSTX_CLKDIG_CTS | test   |  lvds_cts |
> > >> >            |        |--------------------->|        |---------->|
> > >> >             --------                        --------             -----
> > >> >
> > >> > Some clocks and blocks are not modeled into CCF. But we prefer to enable
> > >> > lvdspll before enabling lvds_pxl. So I modeled lvds_pxl (and lvds_cts)
> > >> > as a fixed-rate clock with a source from lvdspll.
> > >> >
> > >> > The frequency of these fixed-rate clocks (such as 148.5 MHz) are typical
> > >> > rate. In fact, we don't care about the actual rate of these clocks. We
> > >> > just care about the enable / disable sequence of them.
> > >>
> > >> Please either use the real rate or 0 (along with a explaining why). Using
> > >> a frequency with four to five significant digits makes me think that the
> > >> actual rate is very important.
> > >
> > > Oops, your suggestion is much different from Daniel's.
> > >
> > > Daniel, could you help to comment about how we model these clocks?
> > 
> > First of all, for clocks where the rate doesn't matter, it doesn't
> > matters to what rate we set the clock.
> > 
> > As for the color of our shed, "the designer says these are the typical
> > rates" sounds good enough to me for a "real rate", so I prefer using
> > the rates in James' patch.
> > 
> > If not sure what Sascha's concern is, but if he insists on 0, I'm fine
> > with that too.
> 
> I only find it confusing. I'd expect either the correct rate or an
> obviously dummy rate. Whatever we choose a comment explaining the
> background would really help here. Otherwise we won't know later
> whether this 148.5 MHz rate was introduced because a) The consumers
> depend on this rate being reported, b) It really is the correct rate or
> c) we don't care about the rate.

So the proper setting should be:

clk_name,          parent,    rate
-------------------------------------
"clkph_mck_o",     "clk26m",  0
"usb_syspll_125m", "clk26m",  125 * MHZ
"dsi0_dig",        "clk26m",  0
"dsi1_dig",        "clk26m",  0
"lvds_pxl",        "lvdspll", 0
"lvds_cts",        "lvdspll", 0

usb_syspll_125m will keep in 125 MHz event in different products.Others
may be changed by DRAM or display settings.

Daniel, do you think it's OK to model these clocks like above?


Best regards,

James




From gregkh at linuxfoundation.org  Thu Aug  6 19:21:41 2015
From: gregkh at linuxfoundation.org (Greg Kroah-Hartman)
Date: Thu, 6 Aug 2015 19:21:41 -0700
Subject: [PATCH 0/2] drivers: PL061: Add platform driver probing support
In-Reply-To: <20150803190935.GL7557@n2100.arm.linux.org.uk>
References: <1438585198-8764-1-git-send-email-zhaoshenglong@huawei.com>
 <20150803075848.GH7557@n2100.arm.linux.org.uk>
 <55BF33AD.5040502@huawei.com>
 <20150803094923.GI7557@n2100.arm.linux.org.uk>
 <20150803162623.GB30867@kroah.com>
 <20150803190935.GL7557@n2100.arm.linux.org.uk>
Message-ID: <20150807022141.GD25067@kroah.com>

On Mon, Aug 03, 2015 at 08:09:35PM +0100, Russell King - ARM Linux wrote:
> On Mon, Aug 03, 2015 at 09:26:23AM -0700, Greg Kroah-Hartman wrote:
> > On Mon, Aug 03, 2015 at 10:49:23AM +0100, Russell King - ARM Linux wrote:
> > > On Mon, Aug 03, 2015 at 05:26:05PM +0800, Shannon Zhao wrote:
> > > > Hi Russell,
> > > > 
> > > > On 2015/8/3 15:58, Russell King - ARM Linux wrote:
> > > > > On Mon, Aug 03, 2015 at 02:59:56PM +0800, Shannon Zhao wrote:
> > > > >> From: Shannon Zhao <shannon.zhao at linaro.org>
> > > > >>
> > > > >> According to ACPI SPEC, it supports ARM boards to use "GPIO-signaled
> > > > >> ACPI Events". These events can be used for input events. And to QEMU, it
> > > > >> uses GPIO PL061 controller for input events.
> > > > >>
> > > > >> These two patches add platform driver support for PL061 probed by DT or
> > > > >> ACPI.
> > > > > 
> > > > > This certainly is incorrect for DT, and is probably wrong for ACPI too.
> > > > > DT creates amba devices, so binds via the amba device driver.
> > > > > 
> > > > 
> > > > Oh, sorry. The changes for DT are not necessary. But for ACPI I think it
> > > > needs to convert pl061 to platform device since ACPI doesn't support
> > > > AMBA devices. The Pl011 also does the same thing to support ACPI
> > > > probing. See drivers/tty/serial/amba-pl011.c
> > > 
> > > Maybe rather than having every AMBA driver also converted to a platform
> > > driver (which GregKH hates) maybe ACPI should support the AMBA bus
> > > instead?
> > > 
> > > Greg?
> > 
> > The ACPI developers have been doing work to allow a driver to handle
> > getting the resources from either DT or ACPI no matter what bus it is
> > on, so converting anything to a platform driver shouldn't be needed.
> > 
> > but I don't really know the details here, and this isn't being sent to
> > the ACPI mailing list, so I don't know what to suggest...
> 
> Greg,
> 
> You're the one who's said many times that you'd like to see platform
> devices and platform device drivers to go away.

Yes, of course, I hate the things :)

> So, when I give you
> the opportunity to comment on platform devices being used to augment
> existing device drivers such as the AMBA bus drivers (which you've
> also previously said is a more preferable way to use the driver model)
> why not support that view?

Because I don't know the whole story here, sorry.

> Right now, there seems to be a move to convert _all_ AMBA device drivers
> to become dual-drivers: an amba bus driver and a platform driver.  Is
> that something you really want to see, irrespective of ACPI issues?

Ick, no, I don't think that's wise at all.  Why not just make the needed
resources availble to _all_ bus drivers, then it doesn't matter if it's
AMBA, or ACPI, or USB, or anything else?

I thought that is what some recent patches did to the acpi/of core, but
maybe I was mistaken.

thanks,

greg k-h


From gregory.0xf0 at gmail.com  Thu Aug  6 19:22:38 2015
From: gregory.0xf0 at gmail.com (Gregory Fong)
Date: Thu,  6 Aug 2015 19:22:38 -0700
Subject: [PATCH] ARM: brcmstb: select ARCH_DMA_ADDR_T_64BIT for LPAE
Message-ID: <1438914158-12439-1-git-send-email-gregory.0xf0@gmail.com>

Broadcom STB (BRCMSTB) has some 64-bit capable DMA and therefore needs
dma_addr_t to be a 64-bit size.  One user is the Broadcom SATA3 AHCI
controller driver.

Signed-off-by: Gregory Fong <gregory.0xf0 at gmail.com>
---
 arch/arm/mach-bcm/Kconfig | 1 +
 1 file changed, 1 insertion(+)

diff --git a/arch/arm/mach-bcm/Kconfig b/arch/arm/mach-bcm/Kconfig
index 0ac9e4b3..833b2d5 100644
--- a/arch/arm/mach-bcm/Kconfig
+++ b/arch/arm/mach-bcm/Kconfig
@@ -144,6 +144,7 @@ config ARCH_BRCMSTB
 	select BRCMSTB_GISB_ARB
 	select BRCMSTB_L2_IRQ
 	select BCM7120_L2_IRQ
+	select ARCH_DMA_ADDR_T_64BIT if ARM_LPAE
 	select ARCH_WANT_OPTIONAL_GPIOLIB
 	help
 	  Say Y if you intend to run the kernel on a Broadcom ARM-based STB
-- 
1.9.1



From scott.shu at mediatek.com  Thu Aug  6 19:28:14 2015
From: scott.shu at mediatek.com (Scott Shu)
Date: Fri, 7 Aug 2015 10:28:14 +0800
Subject: [PATCH v3 5/8] ARM: mediatek: add smp bringup code for MT6580
In-Reply-To: <20150805094429.GU7557@n2100.arm.linux.org.uk>
References: <1438696464-59858-1-git-send-email-scott.shu@mediatek.com>
 <1438696464-59858-6-git-send-email-scott.shu@mediatek.com>
 <20150805094429.GU7557@n2100.arm.linux.org.uk>
Message-ID: <1438914494.1900.38.camel@mtkswgap22>

On Wed, 2015-08-05 at 10:44 +0100, Russell King - ARM Linux wrote:
> On Tue, Aug 04, 2015 at 09:54:21PM +0800, Scott Shu wrote:
> > Add support for cpu enable-method "mediatek,mt6580-smp" for booting
> > secondary CPUs on MT6580.
> 
> If you have CPU power domain support, and you power up and power down the
> CPUs, why do you need the boot_lock and pen_release stuff?  Isn't keeping
> the power off on a CPU sufficient to prevent it entering the kernel?
> 
Thanks Russell. Yes, the system works well after removing boot_lock and
pen_release. Will be fixed in next version. 

Scott



From viresh.kumar at linaro.org  Thu Aug  6 20:41:28 2015
From: viresh.kumar at linaro.org (Viresh Kumar)
Date: Fri, 7 Aug 2015 09:11:28 +0530
Subject: [PATCH v4 1/6] cpufreq: make scaling_boost_freqs sysfs attr
 available when boost is enabled
In-Reply-To: <1438868514-8814-2-git-send-email-b.zolnierkie@samsung.com>
References: <1438868514-8814-1-git-send-email-b.zolnierkie@samsung.com>
 <1438868514-8814-2-git-send-email-b.zolnierkie@samsung.com>
Message-ID: <20150807034128.GE6325@linux>

Hi,

I would suggest you sending such patches as reply to the earlier
threads only, instead of a new chain. This will save your time.

For example, you will need to resend other patches unnecessarily if I
NAK this patch :)

On 06-08-15, 15:41, Bartlomiej Zolnierkiewicz wrote:
> Add cpufreq_boost_enabled_generic_attr table and use it in
> cpufreq-dt driver instead of cpufreq_generic_attr one when
> boost support is enabled.  As a result scaling_boost_freqs
> sysfs attribute is available when cpufreq-dt driver is
> used and boost support is enabled.
> 
> Cc: Viresh Kumar <viresh.kumar at linaro.org>
> Cc: Thomas Abraham <thomas.ab at samsung.com>
> Cc: Javier Martinez Canillas <javier at osg.samsung.com>
> Cc: Krzysztof Kozlowski <k.kozlowski at samsung.com>
> Signed-off-by: Bartlomiej Zolnierkiewicz <b.zolnierkie at samsung.com>
> ---
>  drivers/cpufreq/cpufreq-dt.c | 3 +++
>  drivers/cpufreq/freq_table.c | 7 +++++++
>  include/linux/cpufreq.h      | 1 +
>  3 files changed, 11 insertions(+)
> 
> diff --git a/drivers/cpufreq/cpufreq-dt.c b/drivers/cpufreq/cpufreq-dt.c
> index b9259ab..7b091c0 100644
> --- a/drivers/cpufreq/cpufreq-dt.c
> +++ b/drivers/cpufreq/cpufreq-dt.c
> @@ -182,6 +182,8 @@ try_again:
>  	return ret;
>  }
>  
> +static struct cpufreq_driver dt_cpufreq_driver;
> +
>  static int cpufreq_init(struct cpufreq_policy *policy)
>  {
>  	struct cpufreq_frequency_table *freq_table;
> @@ -336,6 +338,7 @@ static int cpufreq_init(struct cpufreq_policy *policy)
>  		ret = cpufreq_enable_boost_support();
>  		if (ret)
>  			goto out_free_cpufreq_table;
> +		dt_cpufreq_driver.attr = cpufreq_boost_enabled_generic_attr;
>  	}
>  
>  	policy->cpuinfo.transition_latency = transition_latency;
> diff --git a/drivers/cpufreq/freq_table.c b/drivers/cpufreq/freq_table.c
> index a8f1daf..5a00a09 100644
> --- a/drivers/cpufreq/freq_table.c
> +++ b/drivers/cpufreq/freq_table.c
> @@ -300,6 +300,13 @@ struct freq_attr *cpufreq_generic_attr[] = {
>  };
>  EXPORT_SYMBOL_GPL(cpufreq_generic_attr);
>  
> +struct freq_attr *cpufreq_boost_enabled_generic_attr[] = {
> +	&cpufreq_freq_attr_scaling_available_freqs,
> +	&cpufreq_freq_attr_scaling_boost_freqs,
> +	NULL,
> +};
> +EXPORT_SYMBOL_GPL(cpufreq_boost_enabled_generic_attr);

This isn't scalable. We can't create a new generic structure every time
a entry comes in. Rather we should leave the generic attr for
cpufreq-dt and do something like this in the cpufreq-dt driver (And
that patch should rather go via cpufreq tree and not ARM SoC)..

diff --git a/drivers/cpufreq/cpufreq-dt.c b/drivers/cpufreq/cpufreq-dt.c
index a5b6a854661f..e229258ad791 100644
--- a/drivers/cpufreq/cpufreq-dt.c
+++ b/drivers/cpufreq/cpufreq-dt.c
@@ -36,6 +36,12 @@ struct private_data {
 	unsigned int voltage_tolerance; /* in percentage */
 };
 
+static struct freq_attr *cpufreq_dt_attr[] = {
+	&cpufreq_freq_attr_scaling_available_freqs,
+	NULL,	/* Extra space for boost-attr if required */
+	NULL,
+};
+
 static int set_target(struct cpufreq_policy *policy, unsigned int index)
 {
 	struct dev_pm_opp *opp;
@@ -337,6 +343,7 @@ static int cpufreq_init(struct cpufreq_policy *policy)
 		ret = cpufreq_enable_boost_support();
 		if (ret)
 			goto out_free_cpufreq_table;
+		cpufreq_dt_attr[1] = &cpufreq_freq_attr_scaling_boost_freqs;
 	}
 
 	policy->cpuinfo.transition_latency = transition_latency;
@@ -412,7 +419,7 @@ static struct cpufreq_driver dt_cpufreq_driver = {
 	.exit = cpufreq_exit,
 	.ready = cpufreq_ready,
 	.name = "cpufreq-dt",
-	.attr = cpufreq_generic_attr,
+	.attr = cpufreq_dt_attr,
 };
 
 static int dt_cpufreq_probe(struct platform_device *pdev)

-- 
viresh


From viresh.kumar at linaro.org  Thu Aug  6 20:50:18 2015
From: viresh.kumar at linaro.org (Viresh Kumar)
Date: Fri, 7 Aug 2015 09:20:18 +0530
Subject: [PATCH v4 0/6] cpufreq: use generic cpufreq drivers for
 Exynos4x12 platform
In-Reply-To: <015301d0d0a3$1396c900$3ac45b00$@kernel.org>
References: <1438868514-8814-1-git-send-email-b.zolnierkie@samsung.com>
 <015301d0d0a3$1396c900$3ac45b00$@kernel.org>
Message-ID: <20150807035018.GF6325@linux>

Cc'ing Rafael again. Guys please don't miss him for any PM related
stuff or use get_maintainers ..

Cc'ing Arnd/Olof as well to discuss the merge stuff..

On 07-08-15, 08:53, Kukjin Kim wrote:
> > Depends on:
> > - next-20150806 branch of linux-next kernel tree
> > - "[PATCH V3 00/16] OPP: Add code to support operating-points-v2 bindings"
> >   (http://www.spinics.net/lists/arm-kernel/msg435408.html)
> > 
> BTW, hmm...how can we see this series in v4.3?...to be honest, I don't think it
> can be done in v4.3 because of dependencies with PM / OPP series

That is merged by Rafael Yesterday. That is manageable 

> and previous
> exynos CPU OPP series in each cross trees...maybe that's why you created based
> on linux-next...any idea?

So there is no build dependency with OPP patches I hope, as its all
about using the bindings defined by them. And so you don't need to
depend on that.

You might have to rebase on the ARM tree to manage your conflicts. In
this case you can rebase directly on ARM SoC branch which has your
patches (rebase directly over the last patch instead of the whole
branch) and make sure Olof knows about this and he doesn't update
(i.e. rebase) his branch, which he might not anyway.

The whole idea is to keep a single sha-id for a commit. So you can
rebase over the published material present in ARM-SoC ..

-- 
viresh


From viresh.kumar at linaro.org  Thu Aug  6 20:51:56 2015
From: viresh.kumar at linaro.org (Viresh Kumar)
Date: Fri, 7 Aug 2015 09:21:56 +0530
Subject: [PATCH v4 0/6] cpufreq: use generic cpufreq drivers for
 Exynos4x12 platform
In-Reply-To: <20150807035018.GF6325@linux>
References: <1438868514-8814-1-git-send-email-b.zolnierkie@samsung.com>
 <015301d0d0a3$1396c900$3ac45b00$@kernel.org>
 <20150807035018.GF6325@linux>
Message-ID: <20150807035156.GG6325@linux>

Fixed Olof's email id..

On 07-08-15, 09:20, Viresh Kumar wrote:
> Cc'ing Rafael again. Guys please don't miss him for any PM related
> stuff or use get_maintainers ..
> 
> Cc'ing Arnd/Olof as well to discuss the merge stuff..
> 
> On 07-08-15, 08:53, Kukjin Kim wrote:
> > > Depends on:
> > > - next-20150806 branch of linux-next kernel tree
> > > - "[PATCH V3 00/16] OPP: Add code to support operating-points-v2 bindings"
> > >   (http://www.spinics.net/lists/arm-kernel/msg435408.html)
> > > 
> > BTW, hmm...how can we see this series in v4.3?...to be honest, I don't think it
> > can be done in v4.3 because of dependencies with PM / OPP series
> 
> That is merged by Rafael Yesterday. That is manageable 
> 
> > and previous
> > exynos CPU OPP series in each cross trees...maybe that's why you created based
> > on linux-next...any idea?
> 
> So there is no build dependency with OPP patches I hope, as its all
> about using the bindings defined by them. And so you don't need to
> depend on that.
> 
> You might have to rebase on the ARM tree to manage your conflicts. In
> this case you can rebase directly on ARM SoC branch which has your
> patches (rebase directly over the last patch instead of the whole
> branch) and make sure Olof knows about this and he doesn't update
> (i.e. rebase) his branch, which he might not anyway.
> 
> The whole idea is to keep a single sha-id for a commit. So you can
> rebase over the published material present in ARM-SoC ..
> 
> -- 
> viresh

-- 
viresh


From shubhrajyoti.datta at gmail.com  Thu Aug  6 20:55:48 2015
From: shubhrajyoti.datta at gmail.com (Shubhrajyoti Datta)
Date: Fri, 7 Aug 2015 09:25:48 +0530
Subject: [PATCH v3] iio: adc: xilinx-xadc: Push interrupts into threaded
 context
In-Reply-To: <55C0722C.7080904@metafoo.de>
References: <CAKfKVtGTO81wLWk50M303t2WjcBEMEt_LUnsJ3_WmvR_3izUjg@mail.gmail.com>
 <1437434050-32907-1-git-send-email-xander.huff@ni.com>
 <55B231DE.4080308@metafoo.de>
 <CAKfKVtGegy2P_YWQAtKEzByN-+q+bq=uus4zNvO4sghXRjpGPQ@mail.gmail.com>
 <55C0722C.7080904@metafoo.de>
Message-ID: <CAKfKVtHPYqB1zjRad2=_xe9LEAuWs8PipNHHC5eUfW=XwChT2A@mail.gmail.com>

On Tue, Aug 4, 2015 at 1:35 PM, Lars-Peter Clausen <lars at metafoo.de> wrote:
>
> Well there is no need to use a threaded IRQ. The interrupt handler is quite
> small and doesn't take too much time and doesn't have any delays or sleeps
> in it either.
>
>
Ok thanks for the explanation.


From k.kozlowski at samsung.com  Thu Aug  6 21:13:57 2015
From: k.kozlowski at samsung.com (Krzysztof Kozlowski)
Date: Fri, 07 Aug 2015 13:13:57 +0900
Subject: [PATCH v4 0/6] cpufreq: use generic cpufreq drivers for Exynos4x12
 platform
In-Reply-To: <20150807035156.GG6325@linux>
References: <1438868514-8814-1-git-send-email-b.zolnierkie@samsung.com>
 <015301d0d0a3$1396c900$3ac45b00$@kernel.org> <20150807035018.GF6325@linux>
 <20150807035156.GG6325@linux>
Message-ID: <55C43085.8090506@samsung.com>

On 07.08.2015 12:51, Viresh Kumar wrote:
> Fixed Olof's email id..
> 
> On 07-08-15, 09:20, Viresh Kumar wrote:
>> Cc'ing Rafael again. Guys please don't miss him for any PM related
>> stuff or use get_maintainers ..
>>
>> Cc'ing Arnd/Olof as well to discuss the merge stuff..
>>
>> On 07-08-15, 08:53, Kukjin Kim wrote:
>>>> Depends on:
>>>> - next-20150806 branch of linux-next kernel tree
>>>> - "[PATCH V3 00/16] OPP: Add code to support operating-points-v2 bindings"
>>>>   (http://www.spinics.net/lists/arm-kernel/msg435408.html)
>>>>
>>> BTW, hmm...how can we see this series in v4.3?...to be honest, I don't think it
>>> can be done in v4.3 because of dependencies with PM / OPP series
>>
>> That is merged by Rafael Yesterday. That is manageable 

Indeed, happy to hear it! So the patchset has no external dependencies.

>>
>>> and previous
>>> exynos CPU OPP series in each cross trees...maybe that's why you created based
>>> on linux-next...any idea?
>>
>> So there is no build dependency with OPP patches I hope, as its all
>> about using the bindings defined by them. And so you don't need to
>> depend on that.
>>
>> You might have to rebase on the ARM tree to manage your conflicts. In
>> this case you can rebase directly on ARM SoC branch which has your
>> patches (rebase directly over the last patch instead of the whole
>> branch) and make sure Olof knows about this and he doesn't update
>> (i.e. rebase) his branch, which he might not anyway.
>>
>> The whole idea is to keep a single sha-id for a commit. So you can
>> rebase over the published material present in ARM-SoC ..

Still patches 1/6 and 6/6 need your acks. Is the patch 1/6 a
prerequisite for others? It does not look like a prerequisite... but it
was put at the beginning of the patchset.

Best regards,
Krzysztof



From takahiro.akashi at linaro.org  Thu Aug  6 21:24:57 2015
From: takahiro.akashi at linaro.org (AKASHI Takahiro)
Date: Fri, 07 Aug 2015 13:24:57 +0900
Subject: [v2 2/5] arm64: kdump: implement machine_crash_shutdown()
In-Reply-To: <55C38269.8090907@arm.com>
References: <1429861989-8417-1-git-send-email-takahiro.akashi@linaro.org>
 <1429861989-8417-3-git-send-email-takahiro.akashi@linaro.org>
 <20150424103900.GF29183@leverpostej> <553A1E62.9030400@arm.com>
 <55C3083D.1000306@linaro.org> <55C38269.8090907@arm.com>
Message-ID: <55C43319.3070906@linaro.org>

Marc,

On 08/07/2015 12:51 AM, Marc Zyngier wrote:
> Hi,
>
> On 06/08/15 08:09, AKASHI Takahiro wrote:
>> Marc, Mark
>>
>> Sorry for not revisiting your comment below for a while.
>
> Wow. It took me a few minutes to page the context back in.

Please don't purge the page from your cache for a while :)

>> On 04/24/2015 07:43 PM, Marc Zyngier wrote:
>>> On 24/04/15 11:39, Mark Rutland wrote:
>>>> On Fri, Apr 24, 2015 at 08:53:05AM +0100, AKASHI Takahiro wrote:
>>>>> kdump calls machine_crash_shutdown() to shut down non-boot cpus and
>>>>> save per-cpu general-purpose registers before restarting the crash dump
>>>>> kernel. See kernel_kexec().
>>>>> ipi_cpu_stop() is used and a bit modified to support this behavior.
>>>>>
>>>>> Signed-off-by: AKASHI Takahiro <takahiro.akashi at linaro.org>
>>>>> ---
>>>>>    arch/arm64/include/asm/kexec.h    |   34 ++++++++++++++++++++++-
>>>>>    arch/arm64/kernel/machine_kexec.c |   55 ++++++++++++++++++++++++++++++++++++-
>>>>>    arch/arm64/kernel/smp.c           |   12 ++++++--
>>>>>    3 files changed, 97 insertions(+), 4 deletions(-)
>>>>>
>>>>> diff --git a/arch/arm64/include/asm/kexec.h b/arch/arm64/include/asm/kexec.h
>>>>> index 3530ff5..eaf3fcb 100644
>>>>> --- a/arch/arm64/include/asm/kexec.h
>>>>> +++ b/arch/arm64/include/asm/kexec.h
>>>>> @@ -30,6 +30,8 @@
>>>>>
>>>>>    #if !defined(__ASSEMBLY__)
>>>>>
>>>>> +extern bool in_crash_kexec;
>>>>> +
>>>>>    /**
>>>>>     * crash_setup_regs() - save registers for the panic kernel
>>>>>     *
>>>>> @@ -40,7 +42,37 @@
>>>>>    static inline void crash_setup_regs(struct pt_regs *newregs,
>>>>>    				    struct pt_regs *oldregs)
>>>>>    {
>>>>> -	/* Empty routine needed to avoid build errors. */
>>>>> +	if (oldregs) {
>>>>> +		memcpy(newregs, oldregs, sizeof(*newregs));
>>>>> +	} else {
>>>>> +		__asm__ __volatile__ (
>>>>> +			"stp	 x0,   x1, [%3]\n\t"
>>>>
>>>> Why the tabs?
>>>>
>>>> Please use #16 * N as the offset for consistency with entry.S, with 0
>>>> for the first N.
>>>>
>>>> [...]
>>>>
>>>>> +static void machine_kexec_mask_interrupts(void)
>>>>> +{
>>>>> +	unsigned int i;
>>>>> +	struct irq_desc *desc;
>>>>> +
>>>>> +	for_each_irq_desc(i, desc) {
>>>>> +		struct irq_chip *chip;
>>>>> +
>>>>> +		chip = irq_desc_get_chip(desc);
>>>>> +		if (!chip)
>>>>> +			continue;
>>>>> +
>>>>> +		if (chip->irq_eoi && irqd_irq_inprogress(&desc->irq_data))
>>>>> +			chip->irq_eoi(&desc->irq_data);
>>>>> +
>>>>> +		if (chip->irq_mask)
>>>>> +			chip->irq_mask(&desc->irq_data);
>>>>> +
>>>>> +		if (chip->irq_disable && !irqd_irq_disabled(&desc->irq_data))
>>>>> +			chip->irq_disable(&desc->irq_data);
>>>>> +	}
>>>>> +}
>>>>
>>>> I'm surprised that this isn't left to the irqchip driver init code in
>>>> the crash kernel. For all we know this state could be corrupt anyway.
>>>
>>> Indeed, parsing the irqdesc list is a recipe for disaster. Who knows
>>> which locks have been taken or simply corrupted, pointers nuked...
>>>
>>>> Is there any reason we can't get the GIC driver to nuke all of this at
>>>> probe time?
>>
>> Is it just enough to remove kexec_mask_interrupts() and add gic_eoi_irq()
>> at the beginning of gic_cpu_init() in irq-gic.c and irq-gic-v3.c?
>
> No, doing an EOI is definitely the wrong thing to do. If you do it in
> the wrong order, you just screw up the GIC state machine. Plus, you have
> no idea what to write there...
>
> The only real solution is to zero the "active" registers.
>
>>> This feels like the better option. I can cook a patch or two for that.
>>
>> If you do, that will be much better :)
>
> OK, I'll prepare something that we can merge at the same time kexec
> comes back from the dead (if it ever does - I'm not holding my breath).

Thank you.
Please note that the same function, machine_kexec_mask_interrupts(),
is already there on arm(/kernel/machine_kexec.c).

Well, kexec/kdump stuff is not dead.
Hopefully I and Geoff will submit a full series of patchset in a few weeks
although the main logic will be the same.

>>
>> BTW, in arm-gic-v3.h, GICD_CTRL_ARE_NS is defined as
>>       (1U << 4)
>> but should it be 5?
>> (I'm referring to the page 8-415 in IHI0069A.)
>
> No, look at the definition ARE_NS has when the access is non-secure or
> on a system supporting a single security state. The definition you're
> referring to is for a secure access (firmware).

Aha, I should remember that arm has "multiple personalities."

-Takahiro AKASHI

> Thanks,
>
> 	M.
>


From viresh.kumar at linaro.org  Thu Aug  6 21:30:37 2015
From: viresh.kumar at linaro.org (Viresh Kumar)
Date: Fri, 7 Aug 2015 10:00:37 +0530
Subject: [PATCH v4 0/6] cpufreq: use generic cpufreq drivers for
 Exynos4x12 platform
In-Reply-To: <55C43085.8090506@samsung.com>
References: <1438868514-8814-1-git-send-email-b.zolnierkie@samsung.com>
 <015301d0d0a3$1396c900$3ac45b00$@kernel.org>
 <20150807035018.GF6325@linux> <20150807035156.GG6325@linux>
 <55C43085.8090506@samsung.com>
Message-ID: <20150807043037.GH6325@linux>

On 07-08-15, 13:13, Krzysztof Kozlowski wrote:
> Still patches 1/6 and 6/6 need your acks. Is the patch 1/6 a
> prerequisite for others? It does not look like a prerequisite... but it
> was put at the beginning of the patchset.

Patch 1/6 is required to get boost working, that's all.. Not sure how
important is that. Anyway, that will work without 1/6 as well, all you
need to do is enable CONFIG_CPU_FREQ_BOOST_SW in you .config.

Anyway, it should go via pm tree and can be sent separately.

-- 
viresh


From viresh.kumar at linaro.org  Thu Aug  6 21:31:16 2015
From: viresh.kumar at linaro.org (Viresh Kumar)
Date: Fri, 7 Aug 2015 10:01:16 +0530
Subject: [PATCH v4 6/6] cpufreq: remove no longer needed
 CPU_FREQ_BOOST_SW config option
In-Reply-To: <1438868514-8814-7-git-send-email-b.zolnierkie@samsung.com>
References: <1438868514-8814-1-git-send-email-b.zolnierkie@samsung.com>
 <1438868514-8814-7-git-send-email-b.zolnierkie@samsung.com>
Message-ID: <20150807043116.GI6325@linux>

On 06-08-15, 15:41, Bartlomiej Zolnierkiewicz wrote:
> Remove no longer needed CPU_FREQ_BOOST_SW config option.
> 
> Cc: Viresh Kumar <viresh.kumar at linaro.org>
> Cc: Thomas Abraham <thomas.ab at samsung.com>
> Cc: Javier Martinez Canillas <javier at osg.samsung.com>
> Cc: Krzysztof Kozlowski <k.kozlowski at samsung.com>
> Signed-off-by: Bartlomiej Zolnierkiewicz <b.zolnierkie at samsung.com>
> ---
>  drivers/cpufreq/Kconfig      | 4 ----
>  drivers/cpufreq/freq_table.c | 3 ---
>  2 files changed, 7 deletions(-)

This must be applied only after fixing 1/6.

-- 
viresh


From f.fainelli at gmail.com  Thu Aug  6 21:40:14 2015
From: f.fainelli at gmail.com (Florian Fainelli)
Date: Thu, 06 Aug 2015 21:40:14 -0700
Subject: [PATCH] ARM: brcmstb: select ARCH_DMA_ADDR_T_64BIT for LPAE
In-Reply-To: <1438914158-12439-1-git-send-email-gregory.0xf0@gmail.com>
References: <1438914158-12439-1-git-send-email-gregory.0xf0@gmail.com>
Message-ID: <55C436AE.6070704@gmail.com>

Le 08/06/15 19:22, Gregory Fong a ?crit :
> Broadcom STB (BRCMSTB) has some 64-bit capable DMA and therefore needs
> dma_addr_t to be a 64-bit size.  One user is the Broadcom SATA3 AHCI
> controller driver.
> 
> Signed-off-by: Gregory Fong <gregory.0xf0 at gmail.com>

Applied to soc/next, thanks Gregory!
-- 
Florian


From k.kozlowski at samsung.com  Thu Aug  6 21:52:01 2015
From: k.kozlowski at samsung.com (Krzysztof Kozlowski)
Date: Fri, 07 Aug 2015 13:52:01 +0900
Subject: [PATCH v4 0/6] cpufreq: use generic cpufreq drivers for Exynos4x12
 platform
In-Reply-To: <20150807043037.GH6325@linux>
References: <1438868514-8814-1-git-send-email-b.zolnierkie@samsung.com>
 <015301d0d0a3$1396c900$3ac45b00$@kernel.org> <20150807035018.GF6325@linux>
 <20150807035156.GG6325@linux> <55C43085.8090506@samsung.com>
 <20150807043037.GH6325@linux>
Message-ID: <55C43971.5010504@samsung.com>

On 07.08.2015 13:30, Viresh Kumar wrote:
> On 07-08-15, 13:13, Krzysztof Kozlowski wrote:
>> Still patches 1/6 and 6/6 need your acks. Is the patch 1/6 a
>> prerequisite for others? It does not look like a prerequisite... but it
>> was put at the beginning of the patchset.
> 
> Patch 1/6 is required to get boost working, that's all.. Not sure how
> important is that. Anyway, that will work without 1/6 as well, all you
> need to do is enable CONFIG_CPU_FREQ_BOOST_SW in you .config.
> 
> Anyway, it should go via pm tree and can be sent separately.

Thanks for explanation. As fair as I understand, Bartlomiej wanted to
merge this in a way which would avoid loosing the boost mode. Kukjin
prepared topic branches for previous cpu-freq/clk stuff so maybe
everything could go through PM?

Kukjin, are you fine with that?

Best regards,
Krzysztof



From viresh.kumar at linaro.org  Thu Aug  6 22:18:26 2015
From: viresh.kumar at linaro.org (Viresh Kumar)
Date: Fri, 7 Aug 2015 10:48:26 +0530
Subject: [PATCH v4 0/6] cpufreq: use generic cpufreq drivers for
 Exynos4x12 platform
In-Reply-To: <55C43971.5010504@samsung.com>
References: <1438868514-8814-1-git-send-email-b.zolnierkie@samsung.com>
 <015301d0d0a3$1396c900$3ac45b00$@kernel.org>
 <20150807035018.GF6325@linux> <20150807035156.GG6325@linux>
 <55C43085.8090506@samsung.com> <20150807043037.GH6325@linux>
 <55C43971.5010504@samsung.com>
Message-ID: <20150807051826.GJ6325@linux>

On 07-08-15, 13:52, Krzysztof Kozlowski wrote:
> Thanks for explanation. As fair as I understand, Bartlomiej wanted to
> merge this in a way which would avoid loosing the boost mode. Kukjin
> prepared topic branches for previous cpu-freq/clk stuff so maybe
> everything could go through PM?

We aren't loosing anything at all. There can be two cases here:

1. Patch 1/6 and 6/6 make it to 4.3 (with suggested changes) via PM tree:
- All will work fine in this case, no issues at all..

2. They don't make it:
- Even in this case, nothing will break. Users can just enable a
  config option and that's all..

So, no need to divert things into another tree this late.

Over that, Rafael will not be around for 2 weeks now (Plumbers and
other stuff) ..

So, just target the cpufreq core changes via PM tree.. rest is just
fine.

I hope that makes sense :)

-- 
viresh


From tony at atomide.com  Thu Aug  6 22:19:03 2015
From: tony at atomide.com (Tony Lindgren)
Date: Thu,  6 Aug 2015 22:19:03 -0700
Subject: [PATCH 1/1] ARM: OMAP2+: Fix power domain operations regression
 caused by 81xx
Message-ID: <1438924743-30025-1-git-send-email-tony@atomide.com>

I managed to mess up omap3 power domain operations with commit
7c80a3f89c51 ("ARM: OMAP2+: Add custom prwdm_operations for 81xx
to support dm814x"), by default we should keep on using the
omap3_pwrdm_operations, only 81xx needs custom handling.

This causes omap3 PM to break so we won't hit off mode any longer
causing idle power consumption go up from less than 10mW to over
50 mW.

Fixs: 7c80a3f89c51 ("ARM: OMAP2+: Add custom prwdm_operations for
81xx to support dm814x")
Signed-off-by: Tony Lindgren <tony at atomide.com>
---
 arch/arm/mach-omap2/powerdomains3xxx_data.c | 6 +++++-
 1 file changed, 5 insertions(+), 1 deletion(-)

--- a/arch/arm/mach-omap2/powerdomains3xxx_data.c
+++ b/arch/arm/mach-omap2/powerdomains3xxx_data.c
@@ -580,7 +580,9 @@ void __init omap3xxx_powerdomains_init(void)
 	if (!cpu_is_omap34xx() && !cpu_is_ti81xx())
 		return;
 
-	pwrdm_register_platform_funcs(&ti81xx_pwrdm_operations);
+	/* Only 81xx needs custom pwrdm_operations */
+	if (!cpu_is_ti81xx())
+		pwrdm_register_platform_funcs(&omap3_pwrdm_operations);;
 
 	rev = omap_rev();
 
@@ -588,9 +590,11 @@ void __init omap3xxx_powerdomains_init(void)
 		pwrdm_register_pwrdms(powerdomains_am35x);
 	} else if (rev == TI8148_REV_ES1_0 || rev == TI8148_REV_ES2_0 ||
 		   rev == TI8148_REV_ES2_1) {
+		pwrdm_register_platform_funcs(&ti81xx_pwrdm_operations);
 		pwrdm_register_pwrdms(powerdomains_ti814x);
 	} else if (rev == TI8168_REV_ES1_0 || rev == TI8168_REV_ES1_1
 			|| rev == TI8168_REV_ES2_0 || rev == TI8168_REV_ES2_1) {
+		pwrdm_register_platform_funcs(&ti81xx_pwrdm_operations);
 		pwrdm_register_pwrdms(powerdomains_ti816x);
 	} else {
 		pwrdm_register_pwrdms(powerdomains_omap3430_common);
-- 
2.1.4



From wangzhou1 at hisilicon.com  Thu Aug  6 22:46:02 2015
From: wangzhou1 at hisilicon.com (Zhou Wang)
Date: Fri, 7 Aug 2015 13:46:02 +0800
Subject: [PATCH v6] PCI: Store PCIe bus address in struct of_pci_range
In-Reply-To: <000701d0d059$7810fb70$6832f250$@com>
References: <1438010223-124422-1-git-send-email-gabriele.paoloni@huawei.com>
 <20150729172053.GE31170@google.com>
 <EE11001F9E5DDD47B7634E2F8A612F2E01D6F350@lhreml503-mbs>
 <CAL_JsqKs11-sXQTdBD+ZjbVYFWUHBARTW9q5MF1hCXUhZ+nWLQ@mail.gmail.com>
 <EE11001F9E5DDD47B7634E2F8A612F2E01D6F94A@lhreml503-mbs>
 <20150730161447.GG9640@google.com>
 <EE11001F9E5DDD47B7634E2F8A612F2E01D6FB3B@lhreml503-mbs>
 <20150730171445.GI9640@google.com>
 <EE11001F9E5DDD47B7634E2F8A612F2E01D6FC15@lhreml503-mbs>
 <CAL_Jsq+aQVakaZf4xo7sxnVyTmPR+HJ-9ByyS6OYJ0PHDYOwmg@mail.gmail.com>
 <EE11001F9E5DDD47B7634E2F8A612F2E01D70589@lhreml503-mbs>
 <55BB8CC6.1080203@ti.com>
 <CAL_JsqJqjiWVaKs-3ghQ1EBQzRRQ38GzkMV+FELPj53bSF-yXQ@mail.gmail.com>
 <EE11001F9E5DDD47B7634E2F8A612F2E01D712E7@lhreml503-mbs>
 <7F6386B4-D2F5-4840-AC72-F8C76CBC3B94@gmail.com>
 <EE11001F9E5DDD47B7634E2F8A612F2E01D719D1@lhreml503-mbs>
 <EE11001F9E5DDD47B7634E2F8A612F2E01D72CFE@lhreml503-mbs>
 <000701d0d059$7810fb70$6832f250$@com>
Message-ID: <55C4461A.8040506@hisilicon.com>

On 2015/8/6 23:06, Jingoo Han wrote:
> On Thursday, August 06, 2015 10:53 PM, Gabriele Paoloni wrote:
>>
>> Hi all
>>
>> This patch has now been moved in "[PATCH v6 1/6] PCI: designware: move calculation of bus addresses to
>> DRA7xx"
> 
> To Zhou Wang,
> 
> Please send your patches to 'jingoohan1 at gmail.com', instead of 'jg1.han at samsung.com'.
> Even though, I have done mainline works for Samsung SoCs, Samsung does not support me
> as a maintainer. So, please don't send your patches to my Samsung e-mail.
> 
> Best regards,
> Jingoo Han
>

Hi Jingoo,

Sorry for that, I will add jingoohan1 at gmail.com to v6 thread.

Thanks for reminding,
Zhou

>>
>> commit "f4c55c5a3f7f (PCI: designware: Program ATU with untranslated address)" has been reverted in
>> "[PATCH v6 3/6] PCI: designware: Add ARM64 support"
>>
>> Gab
>>
>>> -----Original Message-----
>>> From: linux-pci-owner at vger.kernel.org [mailto:linux-pci-
>>> owner at vger.kernel.org] On Behalf Of Gabriele Paoloni
>>> Sent: Tuesday, August 04, 2015 11:12 AM
>>> To: Jingoo Han
>>> Cc: Rob Herring; Kishon Vijay Abraham I; Bjorn Helgaas; arnd at arndb.de;
>>> lorenzo.pieralisi at arm.com; Wangzhou (B); robh+dt at kernel.org;
>>> james.morse at arm.com; Liviu.Dudau at arm.com; linux-pci at vger.kernel.org;
>>> linux-arm-kernel at lists.infradead.org; devicetree at vger.kernel.org;
>>> Yuanzhichang; Zhudacai; zhangjukuo; qiuzhenfa; Liguozhu (Kenneth);
>>> Pratyush Anand; Arnd Bergmann
>>> Subject: RE: [PATCH v6] PCI: Store PCIe bus address in struct
>>> of_pci_range
>>>
>>>
>>>
>>>> -----Original Message-----
>>>> From: Jingoo Han [mailto:jingoohan1 at gmail.com]
>>>> Sent: Tuesday, August 04, 2015 5:20 AM
>>>> To: Gabriele Paoloni
>>>> Cc: Rob Herring; Kishon Vijay Abraham I; Bjorn Helgaas; arnd at arndb.de;
>>>> lorenzo.pieralisi at arm.com; Wangzhou (B); robh+dt at kernel.org;
>>>> james.morse at arm.com; Liviu.Dudau at arm.com; linux-pci at vger.kernel.org;
>>>> linux-arm-kernel at lists.infradead.org; devicetree at vger.kernel.org;
>>>> Yuanzhichang; Zhudacai; zhangjukuo; qiuzhenfa; Liguozhu (Kenneth);
>>>> Pratyush Anand; Arnd Bergmann; jingoohan1 at gmail.com
>>>> Subject: Re: [PATCH v6] PCI: Store PCIe bus address in struct
>>>> of_pci_range
>>>>
>>>> On 2015. 8. 3., at PM 8:18, Gabriele Paoloni
>>>> <gabriele.paoloni at huawei.com> wrote:
>>>>>
>>>>> Rob, Kishon what about the following solution?....
>>>>>
>>>>> ---
>>>>> drivers/pci/host/pci-dra7xx.c      | 12 ++++++++++++
>>>>> drivers/pci/host/pcie-designware.c |  9 +++------
>>>>
>>>> Hi Paoloni,
>>>>
>>>> OK, it looks good.
>>>> I want you to revert the following patch.
>>>>
>>>> commit "f4c55c5a3f7f (PCI: designware: Program ATU with untranslated
>>>> address)"
>>>>
>>>> Would you remove all '*_mode_base's?
>>>
>>> Hi Jingoo Han,
>>>
>>> If I reverted the commit, in order to get designware working, dra7
>>> should mask directly the CPU addresses stored in pp->cfg0_base,
>>> pp->cfg1_base, pp->mem_base and pp->io_base.
>>>
>>> The masking would happen at this point:
>>> http://lxr.free-electrons.com/source/drivers/pci/host/pcie-
>>> designware.c#L493
>>>
>>> Now:
>>> - I see that pp->cfg<0/1>_base are used in devm_ioremap before that
>>>   point and nowhere else, so they should be ok.
>>> - pp->mem_base is used in dw_pcie_setup_rc(); dw_pcie_setup_rc() is
>>> called
>>>   in dra7xx_pcie_host_init()...so here I should move the masking after
>>>   dw_pcie_setup() retuned, but I think it should be ok
>>> - pp->io_base is used in pci_ioremap_io() in dw_pcie_setup(). Now
>>> currently
>>>   in designware this is called by pci_bios_init_hw(); this is after the
>>>   masking....so here we would have a the wrong value passed
>>>
>>> Said that if you look at "[PATCH v5 2/5] PCI: designware: Add ARM64
>>> support",
>>> that is the patchset where this patch is needed, you can see that
>>> dw_pcie_setup() is removed and pp->io_base is used in
>>> pci_remap_iospace() before
>>> the masking would happen in dra7xx_pcie_host_init()...so for this
>>> patchset we
>>> should be good to revert the commit.
>>>
>>> I propose to add a new patch in the patchset "[PATCH v5 0/5] PCI: hisi:
>>> Add PCIe
>>> host support for HiSilicon SoC Hip05" as the one I just posted in this
>>> thread (this would not revert the commit but just moves the masking to
>>> dra7xx)
>>>
>>> I would revert the commit in "[PATCH v5 2/5] PCI: designware: Add ARM64
>>> support"
>>> together with the rest of designware rework.
>>>
>>> So we would have always a working version of designware...
>>>
>>> Are you ok with this?
>>>
>>>>
>>>> Best regards,
>>>> Jingoo Han
>>>>
>>>>> 2 files changed, 15 insertions(+), 6 deletions(-)
>>>>>
>>>>> diff --git a/drivers/pci/host/pci-dra7xx.c b/drivers/pci/host/pci-
>>>> dra7xx.c
>>>>> index 80db09e..bb2635f 100644
>>>>> --- a/drivers/pci/host/pci-dra7xx.c
>>>>> +++ b/drivers/pci/host/pci-dra7xx.c
>>>>> @@ -61,6 +61,7 @@
>>>>>
>>>>> #define    PCIECTRL_DRA7XX_CONF_PHY_CS            0x010C
>>>>> #define    LINK_UP                        BIT(16)
>>>>> +#define CPU_TO_BUS_ADDR             0x0FFFFFFF
>>>>>
>>>>> struct dra7xx_pcie {
>>>>>    void __iomem        *base;
>>>>> @@ -138,6 +139,17 @@ static void
>>> dra7xx_pcie_enable_interrupts(struct
>>>> pcie_port *pp)
>>>>>
>>>>> static void dra7xx_pcie_host_init(struct pcie_port *pp)
>>>>> {
>>>>> +    if (pp->io_mod_base)
>>>>> +        pp->io_mod_base &= CPU_TO_BUS_ADDR;
>>>>> +
>>>>> +    if (pp->mem_mod_base)
>>>>> +        pp->mem_mod_base &= CPU_TO_BUS_ADDR;
>>>>> +
>>>>> +    if (pp->cfg0_mod_base) {
>>>>> +        pp->cfg0_mod_base &= CPU_TO_BUS_ADDR;
>>>>> +        pp->cfg1_mod_base &= CPU_TO_BUS_ADDR;
>>>>> +    }
>>>>> +
>>>>>    dw_pcie_setup_rc(pp);
>>>>>    dra7xx_pcie_establish_link(pp);
>>>>>    if (IS_ENABLED(CONFIG_PCI_MSI))
>>>>> diff --git a/drivers/pci/host/pcie-designware.c
>>>> b/drivers/pci/host/pcie-designware.c
>>>>> index 69486be..06c682b 100644
>>>>> --- a/drivers/pci/host/pcie-designware.c
>>>>> +++ b/drivers/pci/host/pcie-designware.c
>>>>> @@ -416,8 +416,7 @@ int dw_pcie_host_init(struct pcie_port *pp)
>>>>>            pp->io_base = range.cpu_addr;
>>>>>
>>>>>            /* Find the untranslated IO space address */
>>>>> -            pp->io_mod_base = of_read_number(parser.range -
>>>>> -                             parser.np + na, ns);
>>>>> +            pp->io_mod_base = range.cpu_addr;;
>>>>>        }
>>>>>        if (restype == IORESOURCE_MEM) {
>>>>>            of_pci_range_to_resource(&range, np, &pp->mem);
>>>>> @@ -426,8 +425,7 @@ int dw_pcie_host_init(struct pcie_port *pp)
>>>>>            pp->mem_bus_addr = range.pci_addr;
>>>>>
>>>>>            /* Find the untranslated MEM space address */
>>>>> -            pp->mem_mod_base = of_read_number(parser.range -
>>>>> -                              parser.np + na, ns);
>>>>> +            pp->mem_mod_base = range.cpu_addr;
>>>>>        }
>>>>>        if (restype == 0) {
>>>>>            of_pci_range_to_resource(&range, np, &pp->cfg);
>>>>> @@ -437,8 +435,7 @@ int dw_pcie_host_init(struct pcie_port *pp)
>>>>>            pp->cfg1_base = pp->cfg.start + pp->cfg0_size;
>>>>>
>>>>>            /* Find the untranslated configuration space address */
>>>>> -            pp->cfg0_mod_base = of_read_number(parser.range -
>>>>> -                               parser.np + na, ns);
>>>>> +            pp->cfg0_mod_base = range.cpu_addr;
>>>>>            pp->cfg1_mod_base = pp->cfg0_mod_base +
>>>>>                        pp->cfg0_size;
>>>>>        }
>>>>> --
>>>>> 1.9.1
>>>>>
>>>>>
>>>>>> -----Original Message-----
>>>>>> From: linux-pci-owner at vger.kernel.org [mailto:linux-pci-
>>>>>> owner at vger.kernel.org] On Behalf Of Rob Herring
>>>>>> Sent: Friday, July 31, 2015 5:53 PM
>>>>>> To: Kishon Vijay Abraham I
>>>>>> Cc: Gabriele Paoloni; Bjorn Helgaas; arnd at arndb.de;
>>>>>> lorenzo.pieralisi at arm.com; Wangzhou (B); robh+dt at kernel.org;
>>>>>> james.morse at arm.com; Liviu.Dudau at arm.com; linux-
>>> pci at vger.kernel.org;
>>>>>> linux-arm-kernel at lists.infradead.org; devicetree at vger.kernel.org;
>>>>>> Yuanzhichang; Zhudacai; zhangjukuo; qiuzhenfa; Liguozhu (Kenneth);
>>>>>> Jingoo Han; Pratyush Anand; Arnd Bergmann
>>>>>> Subject: Re: [PATCH v6] PCI: Store PCIe bus address in struct
>>>>>> of_pci_range
>>>>>>
>>>>>> On Fri, Jul 31, 2015 at 9:57 AM, Kishon Vijay Abraham I
>>>> <kishon at ti.com>
>>>>>> wrote:
>>>>>>> +Arnd
>>>>>>>
>>>>>>> Hi,
>>>>>>>
>>>>>>>> On Friday 31 July 2015 07:55 PM, Gabriele Paoloni wrote:
>>>>>>>> [+cc Kishon]
>>>>>>>>
>>>>>>>>> -----Original Message-----
>>>>>>>>> From: linux-pci-owner at vger.kernel.org [mailto:linux-pci-
>>>>>>>>> owner at vger.kernel.org] On Behalf Of Rob Herring
>>>>>>>>> Sent: Thursday, July 30, 2015 9:42 PM
>>>>>>>>> To: Gabriele Paoloni
>>>>>>>>> Cc: Bjorn Helgaas; arnd at arndb.de; lorenzo.pieralisi at arm.com;
>>>>>> Wangzhou
>>>>>>>>> (B); robh+dt at kernel.org; james.morse at arm.com;
>>> Liviu.Dudau at arm.com;
>>>>>>>>> linux-pci at vger.kernel.org; linux-arm-kernel at lists.infradead.org;
>>>>>>>>> devicetree at vger.kernel.org; Yuanzhichang; Zhudacai; zhangjukuo;
>>>>>>>>> qiuzhenfa; Liguozhu (Kenneth); Jingoo Han; Pratyush Anand
>>>>>>>>> Subject: Re: [PATCH v6] PCI: Store PCIe bus address in struct
>>>>>>>>> of_pci_range
>>>>>>>>>
>>>>>>>>> On Thu, Jul 30, 2015 at 12:34 PM, Gabriele Paoloni
>>>>>>>>> <gabriele.paoloni at huawei.com> wrote:
>>>>>>>>>>> -----Original Message-----
>>>>>>>>>>> From: Bjorn Helgaas [mailto:bhelgaas at google.com]
>>>>>>>>>>> Sent: 30 July 2015 18:15
>>>>>>>>>>> On Thu, Jul 30, 2015 at 04:50:55PM +0000, Gabriele Paoloni
>>>> wrote:
>>>>>>>>>>>>> -----Original Message-----
>>>>>>>>>>>>> From: linux-pci-owner at vger.kernel.org [mailto:linux-pci-
>>>>>>>>>>>>> owner at vger.kernel.org] On Behalf Of Bjorn Helgaas
>>>>>>>>>>>>> Sent: Thursday, July 30, 2015 5:15 PM
>>>>>>>>>>>>> On Thu, Jul 30, 2015 at 01:52:13PM +0000, Gabriele Paoloni
>>>>>> wrote:
>>>>>>>>>
>>>>>>>>> [...]
>>>>>>>>>
>>>>>>>>>>>>>> I don?t think we should rely on [CPU] addresses...what if
>>>> the
>>>>>>>>>>>>> intermediate
>>>>>>>>>>>>>> translation layer changes the lower significant bits of
>>> the
>>>>>>>>> "bus
>>>>>>>>>>>>> address"
>>>>>>>>>>>>>> to translate into a cpu address?
>>>>>>>>>>>>>
>>>>>>>>>>>>> Is it really a possiblity that the lower bits could be
>>>> changed?
>>>>>>>>>>>>
>>>>>>>>>>>> I've checked all the current deignware users DTs except
>>> "pci-
>>>>>>>>>>> layerscape"
>>>>>>>>>>>> that I could not find:
>>>>>>>>>>>> spear1310.dtsi
>>>>>>>>>>>> spear1340.dtsi
>>>>>>>>>>>> dra7.dtsi
>>>>>>>>>>>> imx6qdl.dtsi
>>>>>>>>>>>> imx6sx.dtsi
>>>>>>>>>>>> keystone.dtsi
>>>>>>>>>>>> exynos5440.dtsi
>>>>>>>>>>>>
>>>>>>>>>>>> None of them modifies the lower bits. To be more precise the
>>>>>> only
>>>>>>>>> guy
>>>>>>>>>>>> that provides another translation layer is "dra7.dtsi":
>>>>>>>>>>>> axi0
>>>>>>>>>>>> http://lxr.free-
>>>>>>>>> electrons.com/source/arch/arm/boot/dts/dra7.dtsi#L207
>>>>>>>>>>>>
>>>>>>>>>>>> axi1
>>>>>>>>>>>> http://lxr.free-
>>>>>>>>> electrons.com/source/arch/arm/boot/dts/dra7.dtsi#L241
>>>>>>>>>>>>
>>>>>>>>>>>> For this case masking the top 4bits (bits28 to 31) should
>>> make
>>>>>> the
>>>>>>>>> job.
>>>>>>>>>
>>>>>>>>> IMO, we should just fix this case. After further study, I don't
>>>>>> think
>>>>>>>>> this is a DW issue, but rather an SOC integration issue.
>>>>>>>>>
>>>>>>>>> I believe you can just fixup the address in the pp->ops-
>>>>> host_init
>>>>>> hook.
>>>>>>>>
>>>>>>>> Yes I guess that I could just assign pp->(*)_mod_base to the CPU
>>>>>> address
>>>>>>>> in DW and mask it out in dra7xx_pcie_host_init()...
>>>>>>>>
>>>>>>>> Kishon, would you be ok with that?
>>>>>>>
>>>>>>> Initially I was using *base-mask* property from dt. Me and Arnd
>>>>>> (cc'ed) had
>>>>>>> this discussion [1] before we decided the current approach. It'll
>>>> be
>>>>>> good to
>>>>>>> check with Arnd too.
>>>>>>>
>>>>>>> [1] ->  http://lists.infradead.org/pipermail/linux-arm-
>>> kernel/2014-
>>>>>> May/253528.html
>>>>>>
>>>>>> The problem I have here is the use of ranges does not necessarily
>>>> mean
>>>>>> fewer address bits are available. It can be used just for
>>>> convenience
>>>>>> of not putting the full address into every node's reg property.
>>> And
>>>>>> vice versa, there are probably plenty of cases where we have the
>>>> full
>>>>>> address in the nodes, but really only some of the address bits are
>>>>>> decoded at the IP block. Whether the address bits are present is
>>>>>> rarely cared about or known by s/w folks until you hit a problem
>>>> like
>>>>>> this. Given this is an isolated case ATM, I would fix it in an
>>>>>> isolated way. It does not affect the binding and could be changed
>>> in
>>>>>> the kernel later if this becomes a common need.
>>>>>>
>>>>>> Rob
>>>>>> --
>>>>>> To unsubscribe from this list: send the line "unsubscribe linux-
>>> pci"
>>>> in
>>>>>> the body of a message to majordomo at vger.kernel.org
>>>>>> More majordomo info at  http://vger.kernel.org/majordomo-info.html
> 
> 
> .
> 




From Vineet.Gupta1 at synopsys.com  Thu Aug  6 22:48:32 2015
From: Vineet.Gupta1 at synopsys.com (Vineet Gupta)
Date: Fri, 7 Aug 2015 05:48:32 +0000
Subject: [RFC PATCH v4 4/9] arc: axs10x_defconfig: remove
 CONFIG_MMC_DW_IDMAC
References: <1438843469-23807-1-git-send-email-shawn.lin@rock-chips.com>
 <1438843526-23976-1-git-send-email-shawn.lin@rock-chips.com>
Message-ID: <C2D7FE5348E1B147BCA15975FBA23075665B17BF@IN01WEMBXB.internal.synopsys.com>

On Thursday 06 August 2015 12:19 PM, Shawn Lin wrote:
> DesignWare MMC Controller's transfer mode should be decided
> at runtime instead of compile-time. So we remove this config
> option and read dw_mmc's register to select DMA master.
>
> Signed-off-by: Shawn Lin <shawn.lin at rock-chips.com>

Acked-by: Vineet Gupta <vgupta at synopsys.com>

Thx,
-Vineet


From wangzhou1 at hisilicon.com  Thu Aug  6 23:01:19 2015
From: wangzhou1 at hisilicon.com (Zhou Wang)
Date: Fri, 7 Aug 2015 14:01:19 +0800
Subject: [PATCH v6 0/6] PCI: hisi: Add PCIe host support for HiSilicon
 SoC Hip05
In-Reply-To: <1438848559-232109-1-git-send-email-wangzhou1@hisilicon.com>
References: <1438848559-232109-1-git-send-email-wangzhou1@hisilicon.com>
Message-ID: <55C449AF.3030303@hisilicon.com>

[+cc jingoohan1 at gmail.com]

On 2015/8/6 16:09, Zhou Wang wrote:
> This patchset adds PCIe host support for HiSilicon SoC Hip05. The PCIe hosts
> use PCIe IP core from Synopsys, So this driver is base on designware PCIe driver.
> 
> Hip05 is an ARMv8 architecture SoC. It should be able to use ARM64 PCIe API in
> designeware PCIe driver. So this patch also adds ARM64 support for designware
> pcie.
> 
> This patchset is based on v4.2-rc1.
> 
> Change from v5:
> - Merge 1/6 in this series, discussion about this can be found in [1]
> 
> Change from v4:
> - Change the author of 1/5 to Gabriele.
> - Modify problems in 3/5 pointed by Bjorn.
> - Modify spelling problems in 4/5.
> 
> Change from v3:
> - Change 1/5 to what Gabriele suggested.
> - Use win->__res.start to get *_mod_base in 2/5, this fix a bug in v3 series.
> 
> Change from v2:
> - Move struct pci_dev *dev and struct pci_sys_data *sys in
>   pcibios_align_resource in 1/5.
> - Add Gabriele's codes in 2/5 which delete unnecessary information parse and
>   use of_pci_get_host_bridge_resources for both ARM32 and ARM64.
> - Add maintainer patch 5/5.
> 
> Change from RFC v1:
> - Add 1/4 patch by Arnd which removes align_resource callback in ARM
>   pcibios_align_resource.
> - Change head file in pcie-designware from asm/hardirq.h to linux/hardirq.h.
> - Set pp->root_bus_nr = 0 in dra7xx, exynos, imx6, keystone, layerscape,
>   spear13xx.
> - Remove unnecessary parentheses of some macros in pcie-hisi.
> - Use macro to replace some magic values.
> - Merge two loops together and add some comments about it in context_config
>   function in pcie-hisi.
> - Modify some value of items in pcie node example in binding document. 
> 
> Change from RFC:
> - delete dw_pcie_setup, dw_pcie_scan_bus, dw_pcie_map_irq and struct hw_pci,
>   merge related operations into dw_pcie_host_init.
> 
> Link of v5:
> - http://www.spinics.net/lists/devicetree/msg87959.html
> Link of v4:
> - http://www.spinics.net/lists/arm-kernel/msg433050.html
> Link of v3:
> - http://www.spinics.net/lists/linux-pci/msg42539.html
> Link of v2:
> - http://www.spinics.net/lists/linux-pci/msg41844.html
> Link of RFC v1:
> - http://www.spinics.net/lists/linux-pci/msg41305.html
> Link of RFC:
> - http://www.spinics.net/lists/linux-pci/msg40434.html
> 
> [1] http://lists.infradead.org/pipermail/linux-arm-kernel/2015-July/359741.html
> 
> Zhou Wang (4):
>   PCI: designware: Add ARM64 support
>   PCI: hisi: Add PCIe host support for HiSilicon SoC Hip05
>   Documentation: DT: Add HiSilicon PCIe host binding
>   MAINTAINERS: Add pcie-hisi maintainer
> 
> gabriele paoloni (2):
>   PCI: designware: move calculation of bus addresses to DRA7xx
>   ARM/PCI: remove align_resource in pci_sys_data
> 
>  .../devicetree/bindings/pci/hisilicon-pcie.txt     |  46 ++++
>  MAINTAINERS                                        |   7 +
>  arch/arm/include/asm/mach/pci.h                    |   5 -
>  arch/arm/kernel/bios32.c                           |  12 +-
>  drivers/pci/host/Kconfig                           |   8 +
>  drivers/pci/host/Makefile                          |   1 +
>  drivers/pci/host/pci-dra7xx.c                      |  14 ++
>  drivers/pci/host/pci-exynos.c                      |   2 +-
>  drivers/pci/host/pci-imx6.c                        |   2 +-
>  drivers/pci/host/pci-keystone-dw.c                 |   2 +-
>  drivers/pci/host/pci-keystone.c                    |   2 +-
>  drivers/pci/host/pci-layerscape.c                  |   2 +-
>  drivers/pci/host/pcie-designware.c                 | 236 ++++++-------------
>  drivers/pci/host/pcie-designware.h                 |  14 +-
>  drivers/pci/host/pcie-hisi.c                       | 254 +++++++++++++++++++++
>  drivers/pci/host/pcie-spear13xx.c                  |   2 +-
>  16 files changed, 425 insertions(+), 184 deletions(-)
>  create mode 100644 Documentation/devicetree/bindings/pci/hisilicon-pcie.txt
>  create mode 100644 drivers/pci/host/pcie-hisi.c
> 




From wangzhou1 at hisilicon.com  Thu Aug  6 23:02:53 2015
From: wangzhou1 at hisilicon.com (Zhou Wang)
Date: Fri, 7 Aug 2015 14:02:53 +0800
Subject: [PATCH v6 0/6] PCI: hisi: Add PCIe host support for HiSilicon
 SoC Hip05
In-Reply-To: <1438848559-232109-1-git-send-email-wangzhou1@hisilicon.com>
References: <1438848559-232109-1-git-send-email-wangzhou1@hisilicon.com>
Message-ID: <55C44A0D.4060809@hisilicon.com>

[+cc jingoohan1 at gmail.com]

On 2015/8/6 16:09, Zhou Wang wrote:
> This patchset adds PCIe host support for HiSilicon SoC Hip05. The PCIe hosts
> use PCIe IP core from Synopsys, So this driver is base on designware PCIe driver.
> 
> Hip05 is an ARMv8 architecture SoC. It should be able to use ARM64 PCIe API in
> designeware PCIe driver. So this patch also adds ARM64 support for designware
> pcie.
> 
> This patchset is based on v4.2-rc1.
> 
> Change from v5:
> - Merge 1/6 in this series, discussion about this can be found in [1]
> 
> Change from v4:
> - Change the author of 1/5 to Gabriele.
> - Modify problems in 3/5 pointed by Bjorn.
> - Modify spelling problems in 4/5.
> 
> Change from v3:
> - Change 1/5 to what Gabriele suggested.
> - Use win->__res.start to get *_mod_base in 2/5, this fix a bug in v3 series.
> 
> Change from v2:
> - Move struct pci_dev *dev and struct pci_sys_data *sys in
>   pcibios_align_resource in 1/5.
> - Add Gabriele's codes in 2/5 which delete unnecessary information parse and
>   use of_pci_get_host_bridge_resources for both ARM32 and ARM64.
> - Add maintainer patch 5/5.
> 
> Change from RFC v1:
> - Add 1/4 patch by Arnd which removes align_resource callback in ARM
>   pcibios_align_resource.
> - Change head file in pcie-designware from asm/hardirq.h to linux/hardirq.h.
> - Set pp->root_bus_nr = 0 in dra7xx, exynos, imx6, keystone, layerscape,
>   spear13xx.
> - Remove unnecessary parentheses of some macros in pcie-hisi.
> - Use macro to replace some magic values.
> - Merge two loops together and add some comments about it in context_config
>   function in pcie-hisi.
> - Modify some value of items in pcie node example in binding document. 
> 
> Change from RFC:
> - delete dw_pcie_setup, dw_pcie_scan_bus, dw_pcie_map_irq and struct hw_pci,
>   merge related operations into dw_pcie_host_init.
> 
> Link of v5:
> - http://www.spinics.net/lists/devicetree/msg87959.html
> Link of v4:
> - http://www.spinics.net/lists/arm-kernel/msg433050.html
> Link of v3:
> - http://www.spinics.net/lists/linux-pci/msg42539.html
> Link of v2:
> - http://www.spinics.net/lists/linux-pci/msg41844.html
> Link of RFC v1:
> - http://www.spinics.net/lists/linux-pci/msg41305.html
> Link of RFC:
> - http://www.spinics.net/lists/linux-pci/msg40434.html
> 
> [1] http://lists.infradead.org/pipermail/linux-arm-kernel/2015-July/359741.html
> 
> Zhou Wang (4):
>   PCI: designware: Add ARM64 support
>   PCI: hisi: Add PCIe host support for HiSilicon SoC Hip05
>   Documentation: DT: Add HiSilicon PCIe host binding
>   MAINTAINERS: Add pcie-hisi maintainer
> 
> gabriele paoloni (2):
>   PCI: designware: move calculation of bus addresses to DRA7xx
>   ARM/PCI: remove align_resource in pci_sys_data
> 
>  .../devicetree/bindings/pci/hisilicon-pcie.txt     |  46 ++++
>  MAINTAINERS                                        |   7 +
>  arch/arm/include/asm/mach/pci.h                    |   5 -
>  arch/arm/kernel/bios32.c                           |  12 +-
>  drivers/pci/host/Kconfig                           |   8 +
>  drivers/pci/host/Makefile                          |   1 +
>  drivers/pci/host/pci-dra7xx.c                      |  14 ++
>  drivers/pci/host/pci-exynos.c                      |   2 +-
>  drivers/pci/host/pci-imx6.c                        |   2 +-
>  drivers/pci/host/pci-keystone-dw.c                 |   2 +-
>  drivers/pci/host/pci-keystone.c                    |   2 +-
>  drivers/pci/host/pci-layerscape.c                  |   2 +-
>  drivers/pci/host/pcie-designware.c                 | 236 ++++++-------------
>  drivers/pci/host/pcie-designware.h                 |  14 +-
>  drivers/pci/host/pcie-hisi.c                       | 254 +++++++++++++++++++++
>  drivers/pci/host/pcie-spear13xx.c                  |   2 +-
>  16 files changed, 425 insertions(+), 184 deletions(-)
>  create mode 100644 Documentation/devicetree/bindings/pci/hisilicon-pcie.txt
>  create mode 100644 drivers/pci/host/pcie-hisi.c
> 




From wangzhou1 at hisilicon.com  Thu Aug  6 23:03:57 2015
From: wangzhou1 at hisilicon.com (Zhou Wang)
Date: Fri, 7 Aug 2015 14:03:57 +0800
Subject: [PATCH v6 1/6] PCI: designware: move calculation of bus addresses
 to DRA7xx
In-Reply-To: <1438848559-232109-2-git-send-email-wangzhou1@hisilicon.com>
References: <1438848559-232109-1-git-send-email-wangzhou1@hisilicon.com>
 <1438848559-232109-2-git-send-email-wangzhou1@hisilicon.com>
Message-ID: <55C44A4D.8070300@hisilicon.com>

[+cc jingoohan1 at gmail.com]

On 2015/8/6 16:09, Zhou Wang wrote:
> From: gabriele paoloni <gabriele.paoloni at huawei.com>
> 
> Commit f4c55c5a3f7f "PCI: designware: Program ATU with untranslated
> address" added the calculation of PCI BUS addresses in designware,
> storing them in new fields added in "struct pcie_port". This
> calculation is done for every designware user even if is only
> applicable to DRA7xx.
> This patch moves the calculation of the bus addresses to the DRA7xx
> driver and is needed to allow the rework of designware to use
> the new DT parsing API.
> 
> Signed-off-by: Gabriele Paoloni <gabriele.paoloni at huawei.com>
> Signed-off-by: Zhou Wang <wangzhou1 at hisilicon.com>
> ---
>  drivers/pci/host/pci-dra7xx.c      | 13 +++++++++++++
>  drivers/pci/host/pcie-designware.c | 15 ++++-----------
>  2 files changed, 17 insertions(+), 11 deletions(-)
> 
> diff --git a/drivers/pci/host/pci-dra7xx.c b/drivers/pci/host/pci-dra7xx.c
> index 80db09e..18ae7ff 100644
> --- a/drivers/pci/host/pci-dra7xx.c
> +++ b/drivers/pci/host/pci-dra7xx.c
> @@ -61,6 +61,7 @@
>  
>  #define	PCIECTRL_DRA7XX_CONF_PHY_CS			0x010C
>  #define	LINK_UP						BIT(16)
> +#define	CPU_TO_BUS_ADDR					0x0FFFFFFF
>  
>  struct dra7xx_pcie {
>  	void __iomem		*base;
> @@ -139,6 +140,18 @@ static void dra7xx_pcie_enable_interrupts(struct pcie_port *pp)
>  static void dra7xx_pcie_host_init(struct pcie_port *pp)
>  {
>  	dw_pcie_setup_rc(pp);
> +
> +	if (pp->io_mod_base)
> +		pp->io_mod_base &= CPU_TO_BUS_ADDR;
> +
> +	if (pp->mem_mod_base)
> +		pp->mem_mod_base &= CPU_TO_BUS_ADDR;
> +
> +	if (pp->cfg0_mod_base) {
> +		pp->cfg0_mod_base &= CPU_TO_BUS_ADDR;
> +		pp->cfg1_mod_base &= CPU_TO_BUS_ADDR;
> +	}
> +
>  	dra7xx_pcie_establish_link(pp);
>  	if (IS_ENABLED(CONFIG_PCI_MSI))
>  		dw_pcie_msi_init(pp);
> diff --git a/drivers/pci/host/pcie-designware.c b/drivers/pci/host/pcie-designware.c
> index 69486be..c5d407c 100644
> --- a/drivers/pci/host/pcie-designware.c
> +++ b/drivers/pci/host/pcie-designware.c
> @@ -366,14 +366,10 @@ int dw_pcie_host_init(struct pcie_port *pp)
>  	struct of_pci_range range;
>  	struct of_pci_range_parser parser;
>  	struct resource *cfg_res;
> -	u32 val, na, ns;
> +	u32 val, ns;
>  	const __be32 *addrp;
>  	int i, index, ret;
>  
> -	/* Find the address cell size and the number of cells in order to get
> -	 * the untranslated address.
> -	 */
> -	of_property_read_u32(np, "#address-cells", &na);
>  	ns = of_n_size_cells(np);
>  
>  	cfg_res = platform_get_resource_byname(pdev, IORESOURCE_MEM, "config");
> @@ -416,8 +412,7 @@ int dw_pcie_host_init(struct pcie_port *pp)
>  			pp->io_base = range.cpu_addr;
>  
>  			/* Find the untranslated IO space address */
> -			pp->io_mod_base = of_read_number(parser.range -
> -							 parser.np + na, ns);
> +			pp->io_mod_base = range.cpu_addr;
>  		}
>  		if (restype == IORESOURCE_MEM) {
>  			of_pci_range_to_resource(&range, np, &pp->mem);
> @@ -426,8 +421,7 @@ int dw_pcie_host_init(struct pcie_port *pp)
>  			pp->mem_bus_addr = range.pci_addr;
>  
>  			/* Find the untranslated MEM space address */
> -			pp->mem_mod_base = of_read_number(parser.range -
> -							  parser.np + na, ns);
> +			pp->mem_mod_base = range.cpu_addr;
>  		}
>  		if (restype == 0) {
>  			of_pci_range_to_resource(&range, np, &pp->cfg);
> @@ -437,8 +431,7 @@ int dw_pcie_host_init(struct pcie_port *pp)
>  			pp->cfg1_base = pp->cfg.start + pp->cfg0_size;
>  
>  			/* Find the untranslated configuration space address */
> -			pp->cfg0_mod_base = of_read_number(parser.range -
> -							   parser.np + na, ns);
> +			pp->cfg0_mod_base = range.cpu_addr;
>  			pp->cfg1_mod_base = pp->cfg0_mod_base +
>  					    pp->cfg0_size;
>  		}
> 




From wangzhou1 at hisilicon.com  Thu Aug  6 23:04:48 2015
From: wangzhou1 at hisilicon.com (Zhou Wang)
Date: Fri, 7 Aug 2015 14:04:48 +0800
Subject: [PATCH v6 1/6] PCI: designware: move calculation of bus addresses
 to DRA7xx
In-Reply-To: <1438848559-232109-2-git-send-email-wangzhou1@hisilicon.com>
References: <1438848559-232109-1-git-send-email-wangzhou1@hisilicon.com>
 <1438848559-232109-2-git-send-email-wangzhou1@hisilicon.com>
Message-ID: <55C44A80.20308@hisilicon.com>

[+cc jingoohan1 at gmail.com]

On 2015/8/6 16:09, Zhou Wang wrote:
> From: gabriele paoloni <gabriele.paoloni at huawei.com>
> 
> Commit f4c55c5a3f7f "PCI: designware: Program ATU with untranslated
> address" added the calculation of PCI BUS addresses in designware,
> storing them in new fields added in "struct pcie_port". This
> calculation is done for every designware user even if is only
> applicable to DRA7xx.
> This patch moves the calculation of the bus addresses to the DRA7xx
> driver and is needed to allow the rework of designware to use
> the new DT parsing API.
> 
> Signed-off-by: Gabriele Paoloni <gabriele.paoloni at huawei.com>
> Signed-off-by: Zhou Wang <wangzhou1 at hisilicon.com>
> ---
>  drivers/pci/host/pci-dra7xx.c      | 13 +++++++++++++
>  drivers/pci/host/pcie-designware.c | 15 ++++-----------
>  2 files changed, 17 insertions(+), 11 deletions(-)
> 
> diff --git a/drivers/pci/host/pci-dra7xx.c b/drivers/pci/host/pci-dra7xx.c
> index 80db09e..18ae7ff 100644
> --- a/drivers/pci/host/pci-dra7xx.c
> +++ b/drivers/pci/host/pci-dra7xx.c
> @@ -61,6 +61,7 @@
>  
>  #define	PCIECTRL_DRA7XX_CONF_PHY_CS			0x010C
>  #define	LINK_UP						BIT(16)
> +#define	CPU_TO_BUS_ADDR					0x0FFFFFFF
>  
>  struct dra7xx_pcie {
>  	void __iomem		*base;
> @@ -139,6 +140,18 @@ static void dra7xx_pcie_enable_interrupts(struct pcie_port *pp)
>  static void dra7xx_pcie_host_init(struct pcie_port *pp)
>  {
>  	dw_pcie_setup_rc(pp);
> +
> +	if (pp->io_mod_base)
> +		pp->io_mod_base &= CPU_TO_BUS_ADDR;
> +
> +	if (pp->mem_mod_base)
> +		pp->mem_mod_base &= CPU_TO_BUS_ADDR;
> +
> +	if (pp->cfg0_mod_base) {
> +		pp->cfg0_mod_base &= CPU_TO_BUS_ADDR;
> +		pp->cfg1_mod_base &= CPU_TO_BUS_ADDR;
> +	}
> +
>  	dra7xx_pcie_establish_link(pp);
>  	if (IS_ENABLED(CONFIG_PCI_MSI))
>  		dw_pcie_msi_init(pp);
> diff --git a/drivers/pci/host/pcie-designware.c b/drivers/pci/host/pcie-designware.c
> index 69486be..c5d407c 100644
> --- a/drivers/pci/host/pcie-designware.c
> +++ b/drivers/pci/host/pcie-designware.c
> @@ -366,14 +366,10 @@ int dw_pcie_host_init(struct pcie_port *pp)
>  	struct of_pci_range range;
>  	struct of_pci_range_parser parser;
>  	struct resource *cfg_res;
> -	u32 val, na, ns;
> +	u32 val, ns;
>  	const __be32 *addrp;
>  	int i, index, ret;
>  
> -	/* Find the address cell size and the number of cells in order to get
> -	 * the untranslated address.
> -	 */
> -	of_property_read_u32(np, "#address-cells", &na);
>  	ns = of_n_size_cells(np);
>  
>  	cfg_res = platform_get_resource_byname(pdev, IORESOURCE_MEM, "config");
> @@ -416,8 +412,7 @@ int dw_pcie_host_init(struct pcie_port *pp)
>  			pp->io_base = range.cpu_addr;
>  
>  			/* Find the untranslated IO space address */
> -			pp->io_mod_base = of_read_number(parser.range -
> -							 parser.np + na, ns);
> +			pp->io_mod_base = range.cpu_addr;
>  		}
>  		if (restype == IORESOURCE_MEM) {
>  			of_pci_range_to_resource(&range, np, &pp->mem);
> @@ -426,8 +421,7 @@ int dw_pcie_host_init(struct pcie_port *pp)
>  			pp->mem_bus_addr = range.pci_addr;
>  
>  			/* Find the untranslated MEM space address */
> -			pp->mem_mod_base = of_read_number(parser.range -
> -							  parser.np + na, ns);
> +			pp->mem_mod_base = range.cpu_addr;
>  		}
>  		if (restype == 0) {
>  			of_pci_range_to_resource(&range, np, &pp->cfg);
> @@ -437,8 +431,7 @@ int dw_pcie_host_init(struct pcie_port *pp)
>  			pp->cfg1_base = pp->cfg.start + pp->cfg0_size;
>  
>  			/* Find the untranslated configuration space address */
> -			pp->cfg0_mod_base = of_read_number(parser.range -
> -							   parser.np + na, ns);
> +			pp->cfg0_mod_base = range.cpu_addr;
>  			pp->cfg1_mod_base = pp->cfg0_mod_base +
>  					    pp->cfg0_size;
>  		}
> 




From wangzhou1 at hisilicon.com  Thu Aug  6 23:06:42 2015
From: wangzhou1 at hisilicon.com (Zhou Wang)
Date: Fri, 7 Aug 2015 14:06:42 +0800
Subject: [PATCH v6 2/6] ARM/PCI: remove align_resource in pci_sys_data
In-Reply-To: <1438848559-232109-3-git-send-email-wangzhou1@hisilicon.com>
References: <1438848559-232109-1-git-send-email-wangzhou1@hisilicon.com>
 <1438848559-232109-3-git-send-email-wangzhou1@hisilicon.com>
Message-ID: <55C44AF2.8040807@hisilicon.com>

[+cc jingoohan1 at gmail.com]

On 2015/8/6 16:09, Zhou Wang wrote:
> From: gabriele paoloni <gabriele.paoloni at huawei.com>
> 
> This patch is needed in order to unify the PCIe designware framework for ARM and
> ARM64 architectures. In the PCIe designware unification process we are calling
> pci_create_root_bus() passing a "sysdata" parameter that is the same for both
> ARM and ARM64 and is of type "struct pcie_port*". In the ARM case this will
> cause a problem with the function pcibios_align_resource(); in fact this will
> cast "dev->sysdata" to "struct pci_sys_data*", whereas designware had passed a
> "struct pcie_port*" pointer.
> 
> This patch solves the issue by removing "align_resource" from "pci_sys_data"
> struct and defining a static global function pointer in "bios32.c"
> 
> Signed-off-by: Gabriele Paoloni <gabriele.paoloni at huawei.com>
> ---
>  arch/arm/include/asm/mach/pci.h |  5 -----
>  arch/arm/kernel/bios32.c        | 12 ++++++++----
>  2 files changed, 8 insertions(+), 9 deletions(-)
> 
> diff --git a/arch/arm/include/asm/mach/pci.h b/arch/arm/include/asm/mach/pci.h
> index 28b9bb3..8a4e4de 100644
> --- a/arch/arm/include/asm/mach/pci.h
> +++ b/arch/arm/include/asm/mach/pci.h
> @@ -58,11 +58,6 @@ struct pci_sys_data {
>  					/* IRQ mapping				*/
>  	int		(*map_irq)(const struct pci_dev *, u8, u8);
>  					/* Resource alignement requirements	*/
> -	resource_size_t (*align_resource)(struct pci_dev *dev,
> -					  const struct resource *res,
> -					  resource_size_t start,
> -					  resource_size_t size,
> -					  resource_size_t align);
>  	void		*private_data;	/* platform controller private data	*/
>  };
>  
> diff --git a/arch/arm/kernel/bios32.c b/arch/arm/kernel/bios32.c
> index fcbbbb1..4cdc64d 100644
> --- a/arch/arm/kernel/bios32.c
> +++ b/arch/arm/kernel/bios32.c
> @@ -17,6 +17,11 @@
>  #include <asm/mach/pci.h>
>  
>  static int debug_pci;
> +static resource_size_t (*align_resource)(struct pci_dev *dev,
> +		  const struct resource *res,
> +		  resource_size_t start,
> +		  resource_size_t size,
> +		  resource_size_t align) = NULL;
>  
>  #ifdef CONFIG_PCI_MSI
>  struct msi_controller *pcibios_msi_controller(struct pci_dev *dev)
> @@ -468,7 +473,7 @@ static void pcibios_init_hw(struct device *parent, struct hw_pci *hw,
>  		sys->busnr   = busnr;
>  		sys->swizzle = hw->swizzle;
>  		sys->map_irq = hw->map_irq;
> -		sys->align_resource = hw->align_resource;
> +		align_resource = hw->align_resource;
>  		INIT_LIST_HEAD(&sys->resources);
>  
>  		if (hw->private_data)
> @@ -589,7 +594,6 @@ resource_size_t pcibios_align_resource(void *data, const struct resource *res,
>  				resource_size_t size, resource_size_t align)
>  {
>  	struct pci_dev *dev = data;
> -	struct pci_sys_data *sys = dev->sysdata;
>  	resource_size_t start = res->start;
>  
>  	if (res->flags & IORESOURCE_IO && start & 0x300)
> @@ -597,8 +601,8 @@ resource_size_t pcibios_align_resource(void *data, const struct resource *res,
>  
>  	start = (start + align - 1) & ~(align - 1);
>  
> -	if (sys->align_resource)
> -		return sys->align_resource(dev, res, start, size, align);
> +	if (align_resource)
> +		return align_resource(dev, res, start, size, align);
>  
>  	return start;
>  }
> 




From wangzhou1 at hisilicon.com  Thu Aug  6 23:08:02 2015
From: wangzhou1 at hisilicon.com (Zhou Wang)
Date: Fri, 7 Aug 2015 14:08:02 +0800
Subject: [PATCH v6 4/6] PCI: hisi: Add PCIe host support for HiSilicon
 SoC Hip05
In-Reply-To: <1438848559-232109-5-git-send-email-wangzhou1@hisilicon.com>
References: <1438848559-232109-1-git-send-email-wangzhou1@hisilicon.com>
 <1438848559-232109-5-git-send-email-wangzhou1@hisilicon.com>
Message-ID: <55C44B42.2050906@hisilicon.com>

[+cc jingoohan1 at gmail.com]

On 2015/8/6 16:09, Zhou Wang wrote:
> This patch adds PCIe host support for HiSilicon SoC Hip05.
> 
> Signed-off-by: Zhou Wang <wangzhou1 at hisilicon.com>
> ---
>  drivers/pci/host/Kconfig     |   8 ++
>  drivers/pci/host/Makefile    |   1 +
>  drivers/pci/host/pcie-hisi.c | 254 +++++++++++++++++++++++++++++++++++++++++++
>  3 files changed, 263 insertions(+)
>  create mode 100644 drivers/pci/host/pcie-hisi.c
> 
> diff --git a/drivers/pci/host/Kconfig b/drivers/pci/host/Kconfig
> index c132bdd..cd2b80b 100644
> --- a/drivers/pci/host/Kconfig
> +++ b/drivers/pci/host/Kconfig
> @@ -145,4 +145,12 @@ config PCIE_IPROC_BCMA
>  	  Say Y here if you want to use the Broadcom iProc PCIe controller
>  	  through the BCMA bus interface
>  
> +config PCI_HISI
> +	depends on OF && ARM64
> +	bool "HiSilicon SoC HIP05 PCIe controller"
> +	select PCIEPORTBUS
> +	select PCIE_DW
> +	help
> +	  Say Y here if you want PCIe controller support on HiSilicon HIP05 SoC
> +
>  endmenu
> diff --git a/drivers/pci/host/Makefile b/drivers/pci/host/Makefile
> index 140d66f..ea1dbf2 100644
> --- a/drivers/pci/host/Makefile
> +++ b/drivers/pci/host/Makefile
> @@ -17,3 +17,4 @@ obj-$(CONFIG_PCI_VERSATILE) += pci-versatile.o
>  obj-$(CONFIG_PCIE_IPROC) += pcie-iproc.o
>  obj-$(CONFIG_PCIE_IPROC_PLATFORM) += pcie-iproc-platform.o
>  obj-$(CONFIG_PCIE_IPROC_BCMA) += pcie-iproc-bcma.o
> +obj-$(CONFIG_PCI_HISI) += pcie-hisi.o
> diff --git a/drivers/pci/host/pcie-hisi.c b/drivers/pci/host/pcie-hisi.c
> new file mode 100644
> index 0000000..7dcacf1
> --- /dev/null
> +++ b/drivers/pci/host/pcie-hisi.c
> @@ -0,0 +1,254 @@
> +/*
> + * PCIe host controller driver for HiSilicon Hip05 SoC
> + *
> + * Copyright (C) 2015 HiSilicon Co., Ltd. http://www.hisilicon.com
> + *
> + * Author: Zhou Wang <wangzhou1 at hisilicon.com>
> + *         Dacai Zhu <zhudacai at hisilicon.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.
> + */
> +#include <linux/interrupt.h>
> +#include <linux/irqdomain.h>
> +#include <linux/module.h>
> +#include <linux/of.h>
> +#include <linux/of_pci.h>
> +#include <linux/platform_device.h>
> +
> +#include "pcie-designware.h"
> +
> +#define PCIE_SUBCTRL_MODE_REG                           0x2800
> +#define PCIE_SUBCTRL_SYS_STATE4_REG                     0x6818
> +#define PCIE_SLV_DBI_MODE                               0x0
> +#define PCIE_SLV_SYSCTRL_MODE                           0x1
> +#define PCIE_SLV_CONTENT_MODE                           0x2
> +#define PCIE_SLV_MSI_ASID                               0x10
> +#define PCIE_LTSSM_LINKUP_STATE                         0x11
> +#define PCIE_LTSSM_STATE_MASK                           0x3F
> +#define PCIE_MSI_ASID_ENABLE                            (0x1 << 12)
> +#define PCIE_MSI_ASID_VALUE                             (0x1 << 16)
> +#define PCIE_MSI_TRANS_ENABLE                           (0x1 << 12)
> +#define PCIE_MSI_TRANS_REG                              0x1c8
> +#define PCIE_MSI_LOW_ADDRESS                            0x1b4
> +#define PCIE_MSI_HIGH_ADDRESS                           0x1c4
> +#define PCIE_MSI_ADDRESS_VAL                            0xb7010040
> +
> +#define to_hisi_pcie(x)	container_of(x, struct hisi_pcie, pp)
> +
> +struct hisi_pcie {
> +	void __iomem *subctrl_base;
> +	void __iomem *reg_base;
> +	struct msi_controller *msi;
> +	u32 port_id;
> +	struct pcie_port pp;
> +};
> +
> +static inline void hisi_pcie_subctrl_writel(struct hisi_pcie *pcie,
> +					    u32 val, u32 reg)
> +{
> +	writel(val, pcie->subctrl_base + reg);
> +}
> +
> +static inline u32 hisi_pcie_subctrl_readl(struct hisi_pcie *pcie, u32 reg)
> +{
> +	return readl(pcie->subctrl_base + reg);
> +}
> +
> +static inline void hisi_pcie_apb_writel(struct hisi_pcie *pcie,
> +					u32 val, u32 reg)
> +{
> +	writel(val, pcie->reg_base + reg);
> +}
> +
> +static inline u32 hisi_pcie_apb_readl(struct hisi_pcie *pcie, u32 reg)
> +{
> +	return readl(pcie->reg_base + reg);
> +}
> +
> +/*
> + * Change mode to indicate the same reg_base to base of PCIe host configure
> + * registers, base of RC configure space or base of vmid/asid context table
> + */
> +static void hisi_pcie_change_apb_mode(struct hisi_pcie *pcie, u32 mode)
> +{
> +	u32 val;
> +	u32 bit_mask;
> +	u32 bit_shift;
> +	u32 port_id = pcie->port_id;
> +	u32 reg = PCIE_SUBCTRL_MODE_REG + 0x100 * port_id;
> +
> +	if ((port_id == 1) || (port_id == 2)) {
> +		bit_mask = 0xc;
> +		bit_shift = 0x2;
> +	} else {
> +		bit_mask = 0x6;
> +		bit_shift = 0x1;
> +	}
> +
> +	val = hisi_pcie_subctrl_readl(pcie, reg);
> +	val = (val & (~bit_mask)) | (mode << bit_shift);
> +	hisi_pcie_subctrl_writel(pcie, val, reg);
> +}
> +
> +/* Configure vmid/asid table in PCIe host */
> +static void hisi_pcie_config_context(struct hisi_pcie *pcie)
> +{
> +	int i;
> +
> +	hisi_pcie_change_apb_mode(pcie, PCIE_SLV_CONTENT_MODE);
> +
> +	/*
> +	 * init vmid and asid tables for all PCIe devices as 0
> +	 * vmid table: 0 ~ 0x3ff, asid table: 0x400 ~ 0x7ff
> +	 */
> +	for (i = 0; i < 0x800; i++)
> +		hisi_pcie_apb_writel(pcie, 0x0, i * 4);
> +
> +	hisi_pcie_change_apb_mode(pcie, PCIE_SLV_SYSCTRL_MODE);
> +
> +	hisi_pcie_apb_writel(pcie, PCIE_MSI_ADDRESS_VAL, PCIE_MSI_LOW_ADDRESS);
> +	hisi_pcie_apb_writel(pcie, 0x0, PCIE_MSI_HIGH_ADDRESS);
> +	hisi_pcie_apb_writel(pcie, PCIE_MSI_ASID_ENABLE | PCIE_MSI_ASID_VALUE,
> +			     PCIE_SLV_MSI_ASID);
> +	hisi_pcie_apb_writel(pcie, PCIE_MSI_TRANS_ENABLE, PCIE_MSI_TRANS_REG);
> +
> +	hisi_pcie_change_apb_mode(pcie, PCIE_SLV_DBI_MODE);
> +}
> +
> +static int hisi_pcie_link_up(struct pcie_port *pp)
> +{
> +	u32 val;
> +	struct hisi_pcie *hisi_pcie = to_hisi_pcie(pp);
> +
> +	val = hisi_pcie_subctrl_readl(hisi_pcie, PCIE_SUBCTRL_SYS_STATE4_REG +
> +				      0x100 * hisi_pcie->port_id);
> +
> +	return ((val & PCIE_LTSSM_STATE_MASK) == PCIE_LTSSM_LINKUP_STATE);
> +}
> +
> +static
> +int hisi_pcie_msi_host_init(struct pcie_port *pp, struct msi_controller *chip)
> +{
> +	struct device_node *msi_node;
> +	struct irq_domain *irq_domain;
> +	struct device_node *np = pp->dev->of_node;
> +
> +	msi_node = of_parse_phandle(np, "msi-parent", 0);
> +	if (!msi_node) {
> +		dev_err(pp->dev, "failed to find msi-parent\n");
> +		return -ENODEV;
> +	}
> +
> +	irq_domain = irq_find_host(msi_node);
> +	if (!irq_domain) {
> +		dev_err(pp->dev, "failed to find irq domain\n");
> +		return -ENODEV;
> +	}
> +
> +	pp->irq_domain = irq_domain;
> +
> +	return 0;
> +}
> +
> +static struct pcie_host_ops hisi_pcie_host_ops = {
> +	.link_up = hisi_pcie_link_up,
> +	.msi_host_init = hisi_pcie_msi_host_init,
> +};
> +
> +static int __init hisi_add_pcie_port(struct pcie_port *pp,
> +				     struct platform_device *pdev)
> +{
> +	int ret;
> +	u32 port_id;
> +	struct resource busn;
> +	struct hisi_pcie *hisi_pcie = to_hisi_pcie(pp);
> +
> +	if (of_property_read_u32(pdev->dev.of_node, "port-id", &port_id)) {
> +		dev_err(&pdev->dev, "failed to read port-id\n");
> +		return -EINVAL;
> +	}
> +	if (port_id > 3) {
> +		dev_err(&pdev->dev, "Invalid port-id: %d\n", port_id);
> +		return -EINVAL;
> +	}
> +
> +	hisi_pcie->port_id = port_id;
> +
> +	if (of_pci_parse_bus_range(pdev->dev.of_node, &busn)) {
> +		dev_err(&pdev->dev, "failed to parse bus-ranges\n");
> +		return -EINVAL;
> +	}
> +
> +	pp->root_bus_nr = busn.start;
> +	pp->ops = &hisi_pcie_host_ops;
> +
> +	hisi_pcie_config_context(hisi_pcie);
> +
> +	ret = dw_pcie_host_init(pp);
> +	if (ret) {
> +		dev_err(&pdev->dev, "failed to initialize host\n");
> +		return ret;
> +	}
> +
> +	return 0;
> +}
> +
> +static int __init hisi_pcie_probe(struct platform_device *pdev)
> +{
> +	struct hisi_pcie *hisi_pcie;
> +	struct pcie_port *pp;
> +	struct resource *reg;
> +	struct resource *subctrl;
> +	int ret;
> +
> +	hisi_pcie = devm_kzalloc(&pdev->dev, sizeof(*hisi_pcie), GFP_KERNEL);
> +	if (!hisi_pcie)
> +		return -ENOMEM;
> +
> +	pp = &hisi_pcie->pp;
> +	pp->dev = &pdev->dev;
> +
> +	subctrl = platform_get_resource_byname(pdev, IORESOURCE_MEM, "subctrl");
> +	hisi_pcie->subctrl_base = devm_ioremap_nocache(&pdev->dev,
> +					subctrl->start, resource_size(subctrl));
> +	if (IS_ERR(hisi_pcie->subctrl_base)) {
> +		dev_err(pp->dev, "cannot get subctrl base\n");
> +		return PTR_ERR(hisi_pcie->subctrl_base);
> +	}
> +
> +	reg = platform_get_resource_byname(pdev, IORESOURCE_MEM, "rc_dbi");
> +	hisi_pcie->reg_base = devm_ioremap_resource(&pdev->dev, reg);
> +	if (IS_ERR(hisi_pcie->reg_base)) {
> +		dev_err(pp->dev, "cannot get rc_dbi base\n");
> +		return PTR_ERR(hisi_pcie->reg_base);
> +	}
> +
> +	hisi_pcie->pp.dbi_base = hisi_pcie->reg_base;
> +
> +	ret = hisi_add_pcie_port(pp, pdev);
> +	if (ret)
> +		return ret;
> +
> +	platform_set_drvdata(pdev, hisi_pcie);
> +
> +	return 0;
> +}
> +
> +static const struct of_device_id hisi_pcie_of_match[] = {
> +	{.compatible = "hisilicon,hip05-pcie",},
> +	{},
> +};
> +
> +MODULE_DEVICE_TABLE(of, hisi_pcie_of_match);
> +
> +static struct platform_driver hisi_pcie_driver = {
> +	.probe  = hisi_pcie_probe,
> +	.driver = {
> +		   .name = "hisi-pcie",
> +		   .of_match_table = hisi_pcie_of_match,
> +	},
> +};
> +
> +module_platform_driver(hisi_pcie_driver);
> 




From wangzhou1 at hisilicon.com  Thu Aug  6 23:09:22 2015
From: wangzhou1 at hisilicon.com (Zhou Wang)
Date: Fri, 7 Aug 2015 14:09:22 +0800
Subject: [PATCH v6 6/6] MAINTAINERS: Add pcie-hisi maintainer
In-Reply-To: <1438848559-232109-7-git-send-email-wangzhou1@hisilicon.com>
References: <1438848559-232109-1-git-send-email-wangzhou1@hisilicon.com>
 <1438848559-232109-7-git-send-email-wangzhou1@hisilicon.com>
Message-ID: <55C44B92.7010707@hisilicon.com>

[+cc jingoohan1 at gmail.com]

On 2015/8/6 16:09, Zhou Wang wrote:
> Signed-off-by: Zhou Wang <wangzhou1 at hisilicon.com>
> ---
>  MAINTAINERS | 7 +++++++
>  1 file changed, 7 insertions(+)
> 
> diff --git a/MAINTAINERS b/MAINTAINERS
> index 8133cef..7cd8e47 100644
> --- a/MAINTAINERS
> +++ b/MAINTAINERS
> @@ -7854,6 +7854,13 @@ S:	Maintained
>  F:	Documentation/devicetree/bindings/pci/xgene-pci-msi.txt
>  F:	drivers/pci/host/pci-xgene-msi.c
>  
> +PCIE DRIVER FOR HISILICON
> +M:	Zhou Wang <wangzhou1 at hisilicon.com>
> +L:	linux-pci at vger.kernel.org
> +S:	Maintained
> +F:	Documentation/devicetree/bindings/pci/hisilicon-pcie.txt
> +F:	drivers/pci/host/pcie-hisi.c
> +
>  PCMCIA SUBSYSTEM
>  P:	Linux PCMCIA Team
>  L:	linux-pcmcia at lists.infradead.org
> 




From b20788 at freescale.com  Fri Aug  7 07:28:33 2015
From: b20788 at freescale.com (Anson Huang)
Date: Fri, 7 Aug 2015 22:28:33 +0800
Subject: [PATCH] ARM: dts: imx6ul: add pm_power_off support
Message-ID: <1438957713-27661-1-git-send-email-b20788@freescale.com>

i.MX6UL can be powered off by programming SNVS.

When long press ON/OFF button(5 seconds),
PMIC_ON_REQ pin will be set to low and external
PMIC will be powered off.

And system can be powered on by long press ON/OFF
button again.

Signed-off-by: Anson Huang <b20788 at freescale.com>
---
 arch/arm/boot/dts/imx6ul-14x14-evk.dts | 4 ++++
 arch/arm/boot/dts/imx6ul.dtsi          | 8 ++++++++
 2 files changed, 12 insertions(+)

diff --git a/arch/arm/boot/dts/imx6ul-14x14-evk.dts b/arch/arm/boot/dts/imx6ul-14x14-evk.dts
index ee2243b..c27f3c4 100644
--- a/arch/arm/boot/dts/imx6ul-14x14-evk.dts
+++ b/arch/arm/boot/dts/imx6ul-14x14-evk.dts
@@ -58,6 +58,10 @@
 	};
 };
 
+&snvs_poweroff {
+	status = "okay";
+};
+
 &uart1 {
 	pinctrl-names = "default";
 	pinctrl-0 = <&pinctrl_uart1>;
diff --git a/arch/arm/boot/dts/imx6ul.dtsi b/arch/arm/boot/dts/imx6ul.dtsi
index 514ae43..446913e 100644
--- a/arch/arm/boot/dts/imx6ul.dtsi
+++ b/arch/arm/boot/dts/imx6ul.dtsi
@@ -404,6 +404,14 @@
 					interrupts = <GIC_SPI 19 IRQ_TYPE_LEVEL_HIGH>, <GIC_SPI 20 IRQ_TYPE_LEVEL_HIGH>;
 				};
 
+				snvs_poweroff: snvs-poweroff {
+					compatible = "syscon-poweroff";
+					regmap = <&snvs>;
+					offset = <0x38>;
+					mask = <0x60>;
+					status = "disabled";
+				};
+
 				snvs_pwrkey: snvs-powerkey {
 					compatible = "fsl,sec-v4.0-pwrkey";
 					regmap = <&snvs>;
-- 
1.9.1



From wangzhou1 at hisilicon.com  Thu Aug  6 23:08:35 2015
From: wangzhou1 at hisilicon.com (Zhou Wang)
Date: Fri, 7 Aug 2015 14:08:35 +0800
Subject: [PATCH v6 5/6] Documentation: DT: Add HiSilicon PCIe host binding
In-Reply-To: <1438848559-232109-6-git-send-email-wangzhou1@hisilicon.com>
References: <1438848559-232109-1-git-send-email-wangzhou1@hisilicon.com>
 <1438848559-232109-6-git-send-email-wangzhou1@hisilicon.com>
Message-ID: <55C44B63.9000409@hisilicon.com>

[+cc jingoohan1 at gmail.com]

On 2015/8/6 16:09, Zhou Wang wrote:
> This patch adds related DTS binding document for HiSilicon PCIe host driver.
> 
> Signed-off-by: Zhou Wang <wangzhou1 at hisilicon.com>
> ---
>  .../devicetree/bindings/pci/hisilicon-pcie.txt     | 46 ++++++++++++++++++++++
>  1 file changed, 46 insertions(+)
>  create mode 100644 Documentation/devicetree/bindings/pci/hisilicon-pcie.txt
> 
> diff --git a/Documentation/devicetree/bindings/pci/hisilicon-pcie.txt b/Documentation/devicetree/bindings/pci/hisilicon-pcie.txt
> new file mode 100644
> index 0000000..2afc9d1
> --- /dev/null
> +++ b/Documentation/devicetree/bindings/pci/hisilicon-pcie.txt
> @@ -0,0 +1,46 @@
> +HiSilicon PCIe host bridge DT description
> +
> +HiSilicon PCIe host controller is based on Designware PCI core.
> +It shares common functions with PCIe Designware core driver and inherits
> +common properties defined in
> +Documentation/devicetree/bindings/pci/designware-pci.txt.
> +
> +Additional properties are described here:
> +
> +Required properties:
> +- compatible: Should contain "hisilicon,hip05-pcie".
> +- reg: Should contain rc_dbi, subctrl, config registers location and length.
> +- reg-names: Must include the following entries:
> +  "rc_dbi": controller configuration registers;
> +  "subctrl": whole PCIe hosts configuration registers;
> +  "config": PCIe configuration space registers.
> +- msi-parent: Should be its_pcie which is an ITS receiving MSI interrupts.
> +- port-id: Should be 0, 1, 2 or 3.
> +
> +Optional properties:
> +- status: Either "ok" or "disabled".
> +- dma-coherent: Present if DMA operations are coherent.
> +
> +Example:
> +	pcie at 0xb0080000 {
> +		compatible = "hisilicon,hip05-pcie", "snps,dw-pcie";
> +		reg = <0 0xb0080000 0 0x10000>, <0 0xb0000000 0 0x10000>,
> +		      <0x220 0x00000000 0 0x2000>;
> +		reg-names = "rc_dbi", "subctrl", "config";
> +		bus-range = <0  15>;
> +		msi-parent = <&its_pcie>;
> +		#address-cells = <3>;
> +		#size-cells = <2>;
> +		device_type = "pci";
> +		dma-coherent;
> +		ranges = <0x82000000 0 0x00000000 0x220 0x00000000 0 0x10000000>;
> +		num-lanes = <8>;
> +		port-id = <1>;
> +		#interrupts-cells = <1>;
> +		interrupts-map-mask = <0xf800 0 0 7>;
> +		interrupts-map = <0x0 0 0 1 &mbigen_pcie 1 10
> +				  0x0 0 0 2 &mbigen_pcie 2 11
> +				  0x0 0 0 3 &mbigen_pcie 3 12
> +				  0x0 0 0 4 &mbigen_pcie 4 13>;
> +		status = "ok";
> +	};
> 




From wangzhou1 at hisilicon.com  Thu Aug  6 23:07:20 2015
From: wangzhou1 at hisilicon.com (Zhou Wang)
Date: Fri, 7 Aug 2015 14:07:20 +0800
Subject: [PATCH v6 3/6] PCI: designware: Add ARM64 support
In-Reply-To: <1438848559-232109-4-git-send-email-wangzhou1@hisilicon.com>
References: <1438848559-232109-1-git-send-email-wangzhou1@hisilicon.com>
 <1438848559-232109-4-git-send-email-wangzhou1@hisilicon.com>
Message-ID: <55C44B18.4010103@hisilicon.com>

[+cc jingoohan1 at gmail.com]

On 2015/8/6 16:09, Zhou Wang wrote:
> This patch tries to unify ARM32 and ARM64 PCIe in designware driver. Delete
> function dw_pcie_setup, dw_pcie_scan_bus, dw_pcie_map_irq and struct hw_pci,
> move related operations to dw_pcie_host_init.
> 
> In past, we use:
> pci_common_init_dev
> 	-> pcibios_init_hw
> 		-> hw->scan (dw_pcie_scan_bus)
> to pass 0 to root_bus_nr in struct pcie_port. This patch set pp->root_bus_nr = 0
> in each PCIe host driver which is based on pcie-designware.
> 
> This patch also try to use of_pci_get_host_bridge_resources for ARM32 and ARM64
> according to the suggestion for Gabriele[1]
> 
> Finally this patch reverts commit f4c55c5a3f7f "PCI: designware: Program ATU
> with untranslated address" based on 1/6 in this series. we delete *_mod_base in
> pcie-designware. This was discussed in [2]
> 
> I have compiled the driver with multi_v7_defconfig. However, I don't have
> ARM32 PCIe related board to do test. It will be appreciated if someone could
> help to test it.
> 
> Signed-off-by: Zhou Wang <wangzhou1 at hisilicon.com>
> Signed-off-by: Gabriele Paoloni <gabriele.paoloni at huawei.com>
> Signed-off-by: Arnd Bergmann <arnd at arndb.de>
> 
> [1] http://www.spinics.net/lists/linux-pci/msg42194.html
> [2] http://www.spinics.net/lists/arm-kernel/msg436779.html
> ---
>  drivers/pci/host/pci-dra7xx.c      |  15 +--
>  drivers/pci/host/pci-exynos.c      |   2 +-
>  drivers/pci/host/pci-imx6.c        |   2 +-
>  drivers/pci/host/pci-keystone-dw.c |   2 +-
>  drivers/pci/host/pci-keystone.c    |   2 +-
>  drivers/pci/host/pci-layerscape.c  |   2 +-
>  drivers/pci/host/pcie-designware.c | 229 ++++++++++++-------------------------
>  drivers/pci/host/pcie-designware.h |  14 +--
>  drivers/pci/host/pcie-spear13xx.c  |   2 +-
>  9 files changed, 95 insertions(+), 175 deletions(-)
> 
> diff --git a/drivers/pci/host/pci-dra7xx.c b/drivers/pci/host/pci-dra7xx.c
> index 18ae7ff..1268c69 100644
> --- a/drivers/pci/host/pci-dra7xx.c
> +++ b/drivers/pci/host/pci-dra7xx.c
> @@ -141,15 +141,15 @@ static void dra7xx_pcie_host_init(struct pcie_port *pp)
>  {
>  	dw_pcie_setup_rc(pp);
>  
> -	if (pp->io_mod_base)
> -		pp->io_mod_base &= CPU_TO_BUS_ADDR;
> +	if (pp->io_base)
> +		pp->io_base &= CPU_TO_BUS_ADDR;
>  
> -	if (pp->mem_mod_base)
> -		pp->mem_mod_base &= CPU_TO_BUS_ADDR;
> +	if (pp->mem_base)
> +		pp->mem_base &= CPU_TO_BUS_ADDR;
>  
> -	if (pp->cfg0_mod_base) {
> -		pp->cfg0_mod_base &= CPU_TO_BUS_ADDR;
> -		pp->cfg1_mod_base &= CPU_TO_BUS_ADDR;
> +	if (pp->cfg0_base) {
> +		pp->cfg0_base &= CPU_TO_BUS_ADDR;
> +		pp->cfg1_base &= CPU_TO_BUS_ADDR;
>  	}
>  
>  	dra7xx_pcie_establish_link(pp);
> @@ -288,6 +288,7 @@ static int __init dra7xx_add_pcie_port(struct dra7xx_pcie *dra7xx,
>  
>  	pp = &dra7xx->pp;
>  	pp->dev = dev;
> +	pp->root_bus_nr = 0;
>  	pp->ops = &dra7xx_pcie_host_ops;
>  
>  	pp->irq = platform_get_irq(pdev, 1);
> diff --git a/drivers/pci/host/pci-exynos.c b/drivers/pci/host/pci-exynos.c
> index f9f468d..9771bb0 100644
> --- a/drivers/pci/host/pci-exynos.c
> +++ b/drivers/pci/host/pci-exynos.c
> @@ -530,7 +530,7 @@ static int __init exynos_add_pcie_port(struct pcie_port *pp,
>  		}
>  	}
>  
> -	pp->root_bus_nr = -1;
> +	pp->root_bus_nr = 0;
>  	pp->ops = &exynos_pcie_host_ops;
>  
>  	ret = dw_pcie_host_init(pp);
> diff --git a/drivers/pci/host/pci-imx6.c b/drivers/pci/host/pci-imx6.c
> index 233a196..bec256c 100644
> --- a/drivers/pci/host/pci-imx6.c
> +++ b/drivers/pci/host/pci-imx6.c
> @@ -551,7 +551,7 @@ static int __init imx6_add_pcie_port(struct pcie_port *pp,
>  		}
>  	}
>  
> -	pp->root_bus_nr = -1;
> +	pp->root_bus_nr = 0;
>  	pp->ops = &imx6_pcie_host_ops;
>  
>  	ret = dw_pcie_host_init(pp);
> diff --git a/drivers/pci/host/pci-keystone-dw.c b/drivers/pci/host/pci-keystone-dw.c
> index f34892e..b1e4135 100644
> --- a/drivers/pci/host/pci-keystone-dw.c
> +++ b/drivers/pci/host/pci-keystone-dw.c
> @@ -327,7 +327,7 @@ static void ks_dw_pcie_clear_dbi_mode(void __iomem *reg_virt)
>  void ks_dw_pcie_setup_rc_app_regs(struct keystone_pcie *ks_pcie)
>  {
>  	struct pcie_port *pp = &ks_pcie->pp;
> -	u32 start = pp->mem.start, end = pp->mem.end;
> +	u32 start = pp->mem->start, end = pp->mem->end;
>  	int i, tr_size;
>  
>  	/* Disable BARs for inbound access */
> diff --git a/drivers/pci/host/pci-keystone.c b/drivers/pci/host/pci-keystone.c
> index 734da58..8113832 100644
> --- a/drivers/pci/host/pci-keystone.c
> +++ b/drivers/pci/host/pci-keystone.c
> @@ -309,7 +309,7 @@ static int __init ks_add_pcie_port(struct keystone_pcie *ks_pcie,
>  			return ret;
>  	}
>  
> -	pp->root_bus_nr = -1;
> +	pp->root_bus_nr = 0;
>  	pp->ops = &keystone_pcie_host_ops;
>  	ret = ks_dw_pcie_host_init(ks_pcie, ks_pcie->msi_intc_np);
>  	if (ret) {
> diff --git a/drivers/pci/host/pci-layerscape.c b/drivers/pci/host/pci-layerscape.c
> index b2328ea1..79ff08c 100644
> --- a/drivers/pci/host/pci-layerscape.c
> +++ b/drivers/pci/host/pci-layerscape.c
> @@ -106,7 +106,7 @@ static int ls_add_pcie_port(struct ls_pcie *pcie)
>  	pp = &pcie->pp;
>  	pp->dev = pcie->dev;
>  	pp->dbi_base = pcie->dbi;
> -	pp->root_bus_nr = -1;
> +	pp->root_bus_nr = 0;
>  	pp->ops = &ls_pcie_host_ops;
>  
>  	ret = dw_pcie_host_init(pp);
> diff --git a/drivers/pci/host/pcie-designware.c b/drivers/pci/host/pcie-designware.c
> index c5d407c..e71a88e 100644
> --- a/drivers/pci/host/pcie-designware.c
> +++ b/drivers/pci/host/pcie-designware.c
> @@ -11,6 +11,7 @@
>   * published by the Free Software Foundation.
>   */
>  
> +#include <linux/hardirq.h>
>  #include <linux/irq.h>
>  #include <linux/irqdomain.h>
>  #include <linux/kernel.h>
> @@ -69,16 +70,7 @@
>  #define PCIE_ATU_FUNC(x)		(((x) & 0x7) << 16)
>  #define PCIE_ATU_UPPER_TARGET		0x91C
>  
> -static struct hw_pci dw_pci;
> -
> -static unsigned long global_io_offset;
> -
> -static inline struct pcie_port *sys_to_pcie(struct pci_sys_data *sys)
> -{
> -	BUG_ON(!sys->private_data);
> -
> -	return sys->private_data;
> -}
> +static struct pci_ops dw_pcie_ops;
>  
>  int dw_pcie_cfg_read(void __iomem *addr, int where, int size, u32 *val)
>  {
> @@ -255,7 +247,7 @@ static void dw_pcie_msi_set_irq(struct pcie_port *pp, int irq)
>  static int assign_irq(int no_irqs, struct msi_desc *desc, int *pos)
>  {
>  	int irq, pos0, i;
> -	struct pcie_port *pp = sys_to_pcie(desc->dev->bus->sysdata);
> +	struct pcie_port *pp = desc->dev->bus->sysdata;
>  
>  	pos0 = bitmap_find_free_region(pp->msi_irq_in_use, MAX_MSI_IRQS,
>  				       order_base_2(no_irqs));
> @@ -298,7 +290,7 @@ static int dw_msi_setup_irq(struct msi_controller *chip, struct pci_dev *pdev,
>  {
>  	int irq, pos;
>  	struct msi_msg msg;
> -	struct pcie_port *pp = sys_to_pcie(pdev->bus->sysdata);
> +	struct pcie_port *pp = pdev->bus->sysdata;
>  
>  	if (desc->msi_attrib.is_msix)
>  		return -EINVAL;
> @@ -327,7 +319,7 @@ static void dw_msi_teardown_irq(struct msi_controller *chip, unsigned int irq)
>  {
>  	struct irq_data *data = irq_get_irq_data(irq);
>  	struct msi_desc *msi = irq_data_get_msi(data);
> -	struct pcie_port *pp = sys_to_pcie(msi->dev->bus->sysdata);
> +	struct pcie_port *pp = msi->dev->bus->sysdata;
>  
>  	clear_irq_range(pp, irq, 1, data->hwirq);
>  }
> @@ -363,14 +355,12 @@ int dw_pcie_host_init(struct pcie_port *pp)
>  {
>  	struct device_node *np = pp->dev->of_node;
>  	struct platform_device *pdev = to_platform_device(pp->dev);
> -	struct of_pci_range range;
> -	struct of_pci_range_parser parser;
> +	struct pci_bus *bus;
>  	struct resource *cfg_res;
> -	u32 val, ns;
> -	const __be32 *addrp;
> -	int i, index, ret;
> -
> -	ns = of_n_size_cells(np);
> +	LIST_HEAD(res);
> +	u32 val;
> +	int i, ret;
> +	struct resource_entry *win;
>  
>  	cfg_res = platform_get_resource_byname(pdev, IORESOURCE_MEM, "config");
>  	if (cfg_res) {
> @@ -378,85 +368,60 @@ int dw_pcie_host_init(struct pcie_port *pp)
>  		pp->cfg1_size = resource_size(cfg_res)/2;
>  		pp->cfg0_base = cfg_res->start;
>  		pp->cfg1_base = cfg_res->start + pp->cfg0_size;
> -
> -		/* Find the untranslated configuration space address */
> -		index = of_property_match_string(np, "reg-names", "config");
> -		addrp = of_get_address(np, index, NULL, NULL);
> -		pp->cfg0_mod_base = of_read_number(addrp, ns);
> -		pp->cfg1_mod_base = pp->cfg0_mod_base + pp->cfg0_size;
>  	} else {
>  		dev_err(pp->dev, "missing *config* reg space\n");
>  	}
>  
> -	if (of_pci_range_parser_init(&parser, np)) {
> -		dev_err(pp->dev, "missing ranges property\n");
> -		return -EINVAL;
> -	}
> +	ret = of_pci_get_host_bridge_resources(np, 0, 0xff, &res, &pp->io_base);
> +	if (ret)
> +		return ret;
>  
>  	/* Get the I/O and memory ranges from DT */
> -	for_each_of_pci_range(&parser, &range) {
> -		unsigned long restype = range.flags & IORESOURCE_TYPE_BITS;
> -
> -		if (restype == IORESOURCE_IO) {
> -			of_pci_range_to_resource(&range, np, &pp->io);
> -			pp->io.name = "I/O";
> -			pp->io.start = max_t(resource_size_t,
> -					     PCIBIOS_MIN_IO,
> -					     range.pci_addr + global_io_offset);
> -			pp->io.end = min_t(resource_size_t,
> -					   IO_SPACE_LIMIT,
> -					   range.pci_addr + range.size
> -					   + global_io_offset - 1);
> -			pp->io_size = resource_size(&pp->io);
> -			pp->io_bus_addr = range.pci_addr;
> -			pp->io_base = range.cpu_addr;
> -
> -			/* Find the untranslated IO space address */
> -			pp->io_mod_base = range.cpu_addr;
> -		}
> -		if (restype == IORESOURCE_MEM) {
> -			of_pci_range_to_resource(&range, np, &pp->mem);
> -			pp->mem.name = "MEM";
> -			pp->mem_size = resource_size(&pp->mem);
> -			pp->mem_bus_addr = range.pci_addr;
> -
> -			/* Find the untranslated MEM space address */
> -			pp->mem_mod_base = range.cpu_addr;
> -		}
> -		if (restype == 0) {
> -			of_pci_range_to_resource(&range, np, &pp->cfg);
> -			pp->cfg0_size = resource_size(&pp->cfg)/2;
> -			pp->cfg1_size = resource_size(&pp->cfg)/2;
> -			pp->cfg0_base = pp->cfg.start;
> -			pp->cfg1_base = pp->cfg.start + pp->cfg0_size;
> -
> -			/* Find the untranslated configuration space address */
> -			pp->cfg0_mod_base = range.cpu_addr;
> -			pp->cfg1_mod_base = pp->cfg0_mod_base +
> -					    pp->cfg0_size;
> +	resource_list_for_each_entry(win, &res) {
> +		switch (resource_type(win->res)) {
> +		case IORESOURCE_IO:
> +			pp->io = win->res;
> +			pp->io->name = "I/O";
> +			pp->io_size = resource_size(pp->io);
> +			pp->io_bus_addr = pp->io->start - win->offset;
> +			ret = pci_remap_iospace(pp->io, pp->io_base);
> +			if (ret) {
> +				dev_warn(pp->dev, "error %d: failed to map resource %pR\n",
> +					 ret, pp->io);
> +				continue;
> +			}
> +			break;
> +		case IORESOURCE_MEM:
> +			pp->mem = win->res;
> +			pp->mem->name = "MEM";
> +			pp->mem_size = resource_size(pp->mem);
> +			pp->mem_bus_addr = pp->mem->start - win->offset;
> +			break;
> +		case 0:
> +			pp->cfg = win->res;
> +			pp->cfg0_size = resource_size(pp->cfg)/2;
> +			pp->cfg1_size = resource_size(pp->cfg)/2;
> +			pp->cfg0_base = pp->cfg->start;
> +			pp->cfg1_base = pp->cfg->start + pp->cfg0_size;
> +			break;
> +		case IORESOURCE_BUS:
> +			pp->busn = win->res;
> +			break;
> +		default:
> +			continue;
>  		}
>  	}
>  
> -	ret = of_pci_parse_bus_range(np, &pp->busn);
> -	if (ret < 0) {
> -		pp->busn.name = np->name;
> -		pp->busn.start = 0;
> -		pp->busn.end = 0xff;
> -		pp->busn.flags = IORESOURCE_BUS;
> -		dev_dbg(pp->dev, "failed to parse bus-range property: %d, using default %pR\n",
> -			ret, &pp->busn);
> -	}
> -
>  	if (!pp->dbi_base) {
> -		pp->dbi_base = devm_ioremap(pp->dev, pp->cfg.start,
> -					resource_size(&pp->cfg));
> +		pp->dbi_base = devm_ioremap(pp->dev, pp->cfg->start,
> +					resource_size(pp->cfg));
>  		if (!pp->dbi_base) {
>  			dev_err(pp->dev, "error with ioremap\n");
>  			return -ENOMEM;
>  		}
>  	}
>  
> -	pp->mem_base = pp->mem.start;
> +	pp->mem_base = pp->mem->start;
>  
>  	if (!pp->va_cfg0_base) {
>  		pp->va_cfg0_base = devm_ioremap(pp->dev, pp->cfg0_base,
> @@ -505,7 +470,7 @@ int dw_pcie_host_init(struct pcie_port *pp)
>  
>  	if (!pp->ops->rd_other_conf)
>  		dw_pcie_prog_outbound_atu(pp, PCIE_ATU_REGION_INDEX1,
> -					  PCIE_ATU_TYPE_MEM, pp->mem_mod_base,
> +					  PCIE_ATU_TYPE_MEM, pp->mem_base,
>  					  pp->mem_bus_addr, pp->mem_size);
>  
>  	dw_pcie_wr_own_conf(pp, PCI_BASE_ADDRESS_0, 4, 0);
> @@ -517,15 +482,29 @@ int dw_pcie_host_init(struct pcie_port *pp)
>  	val |= PORT_LOGIC_SPEED_CHANGE;
>  	dw_pcie_wr_own_conf(pp, PCIE_LINK_WIDTH_SPEED_CONTROL, 4, val);
>  
> -#ifdef CONFIG_PCI_MSI
> +	bus = pci_create_root_bus(pp->dev, pp->root_bus_nr, &dw_pcie_ops,
> +				  pp, &res);
> +	if (!bus)
> +		return -ENOMEM;
> +
> +#ifdef CONFIG_GENERIC_MSI_IRQ_DOMAIN
> +	bus->msi = container_of(&pp->irq_domain, struct msi_controller, domain);
> +#else
>  	dw_pcie_msi_chip.dev = pp->dev;
> -	dw_pci.msi_ctrl = &dw_pcie_msi_chip;
> +	bus->msi = &dw_pcie_msi_chip;
>  #endif
>  
> -	dw_pci.nr_controllers = 1;
> -	dw_pci.private_data = (void **)&pp;
> +	pci_scan_child_bus(bus);
> +	if (pp->ops->scan_bus)
> +		pp->ops->scan_bus(pp);
> +
> +#ifdef CONFIG_ARM
> +	/* support old dtbs that incorrectly describe IRQs */
> +	pci_fixup_irqs(pci_common_swizzle, of_irq_parse_and_map_pci);
> +#endif
>  
> -	pci_common_init_dev(pp->dev, &dw_pci);
> +	pci_assign_unassigned_bus_resources(bus);
> +	pci_bus_add_devices(bus);
>  
>  	return 0;
>  }
> @@ -544,12 +523,12 @@ static int dw_pcie_rd_other_conf(struct pcie_port *pp, struct pci_bus *bus,
>  
>  	if (bus->parent->number == pp->root_bus_nr) {
>  		type = PCIE_ATU_TYPE_CFG0;
> -		cpu_addr = pp->cfg0_mod_base;
> +		cpu_addr = pp->cfg0_base;
>  		cfg_size = pp->cfg0_size;
>  		va_cfg_base = pp->va_cfg0_base;
>  	} else {
>  		type = PCIE_ATU_TYPE_CFG1;
> -		cpu_addr = pp->cfg1_mod_base;
> +		cpu_addr = pp->cfg1_base;
>  		cfg_size = pp->cfg1_size;
>  		va_cfg_base = pp->va_cfg1_base;
>  	}
> @@ -559,7 +538,7 @@ static int dw_pcie_rd_other_conf(struct pcie_port *pp, struct pci_bus *bus,
>  				  busdev, cfg_size);
>  	ret = dw_pcie_cfg_read(va_cfg_base + address, where, size, val);
>  	dw_pcie_prog_outbound_atu(pp, PCIE_ATU_REGION_INDEX0,
> -				  PCIE_ATU_TYPE_IO, pp->io_mod_base,
> +				  PCIE_ATU_TYPE_IO, pp->io_base,
>  				  pp->io_bus_addr, pp->io_size);
>  
>  	return ret;
> @@ -579,12 +558,12 @@ static int dw_pcie_wr_other_conf(struct pcie_port *pp, struct pci_bus *bus,
>  
>  	if (bus->parent->number == pp->root_bus_nr) {
>  		type = PCIE_ATU_TYPE_CFG0;
> -		cpu_addr = pp->cfg0_mod_base;
> +		cpu_addr = pp->cfg0_base;
>  		cfg_size = pp->cfg0_size;
>  		va_cfg_base = pp->va_cfg0_base;
>  	} else {
>  		type = PCIE_ATU_TYPE_CFG1;
> -		cpu_addr = pp->cfg1_mod_base;
> +		cpu_addr = pp->cfg1_base;
>  		cfg_size = pp->cfg1_size;
>  		va_cfg_base = pp->va_cfg1_base;
>  	}
> @@ -594,7 +573,7 @@ static int dw_pcie_wr_other_conf(struct pcie_port *pp, struct pci_bus *bus,
>  				  busdev, cfg_size);
>  	ret = dw_pcie_cfg_write(va_cfg_base + address, where, size, val);
>  	dw_pcie_prog_outbound_atu(pp, PCIE_ATU_REGION_INDEX0,
> -				  PCIE_ATU_TYPE_IO, pp->io_mod_base,
> +				  PCIE_ATU_TYPE_IO, pp->io_base,
>  				  pp->io_bus_addr, pp->io_size);
>  
>  	return ret;
> @@ -626,7 +605,7 @@ static int dw_pcie_valid_config(struct pcie_port *pp,
>  static int dw_pcie_rd_conf(struct pci_bus *bus, u32 devfn, int where,
>  			int size, u32 *val)
>  {
> -	struct pcie_port *pp = sys_to_pcie(bus->sysdata);
> +	struct pcie_port *pp = bus->sysdata;
>  	int ret;
>  
>  	if (dw_pcie_valid_config(pp, bus, PCI_SLOT(devfn)) == 0) {
> @@ -650,7 +629,7 @@ static int dw_pcie_rd_conf(struct pci_bus *bus, u32 devfn, int where,
>  static int dw_pcie_wr_conf(struct pci_bus *bus, u32 devfn,
>  			int where, int size, u32 val)
>  {
> -	struct pcie_port *pp = sys_to_pcie(bus->sysdata);
> +	struct pcie_port *pp = bus->sysdata;
>  	int ret;
>  
>  	if (dw_pcie_valid_config(pp, bus, PCI_SLOT(devfn)) == 0)
> @@ -674,62 +653,6 @@ static struct pci_ops dw_pcie_ops = {
>  	.write = dw_pcie_wr_conf,
>  };
>  
> -static int dw_pcie_setup(int nr, struct pci_sys_data *sys)
> -{
> -	struct pcie_port *pp;
> -
> -	pp = sys_to_pcie(sys);
> -
> -	if (global_io_offset < SZ_1M && pp->io_size > 0) {
> -		sys->io_offset = global_io_offset - pp->io_bus_addr;
> -		pci_ioremap_io(global_io_offset, pp->io_base);
> -		global_io_offset += SZ_64K;
> -		pci_add_resource_offset(&sys->resources, &pp->io,
> -					sys->io_offset);
> -	}
> -
> -	sys->mem_offset = pp->mem.start - pp->mem_bus_addr;
> -	pci_add_resource_offset(&sys->resources, &pp->mem, sys->mem_offset);
> -	pci_add_resource(&sys->resources, &pp->busn);
> -
> -	return 1;
> -}
> -
> -static struct pci_bus *dw_pcie_scan_bus(int nr, struct pci_sys_data *sys)
> -{
> -	struct pci_bus *bus;
> -	struct pcie_port *pp = sys_to_pcie(sys);
> -
> -	pp->root_bus_nr = sys->busnr;
> -	bus = pci_scan_root_bus(pp->dev, sys->busnr,
> -				  &dw_pcie_ops, sys, &sys->resources);
> -	if (!bus)
> -		return NULL;
> -
> -	if (bus && pp->ops->scan_bus)
> -		pp->ops->scan_bus(pp);
> -
> -	return bus;
> -}
> -
> -static int dw_pcie_map_irq(const struct pci_dev *dev, u8 slot, u8 pin)
> -{
> -	struct pcie_port *pp = sys_to_pcie(dev->bus->sysdata);
> -	int irq;
> -
> -	irq = of_irq_parse_and_map_pci(dev, slot, pin);
> -	if (!irq)
> -		irq = pp->irq;
> -
> -	return irq;
> -}
> -
> -static struct hw_pci dw_pci = {
> -	.setup		= dw_pcie_setup,
> -	.scan		= dw_pcie_scan_bus,
> -	.map_irq	= dw_pcie_map_irq,
> -};
> -
>  void dw_pcie_setup_rc(struct pcie_port *pp)
>  {
>  	u32 val;
> diff --git a/drivers/pci/host/pcie-designware.h b/drivers/pci/host/pcie-designware.h
> index d0bbd27..264c969 100644
> --- a/drivers/pci/host/pcie-designware.h
> +++ b/drivers/pci/host/pcie-designware.h
> @@ -27,25 +27,21 @@ struct pcie_port {
>  	u8			root_bus_nr;
>  	void __iomem		*dbi_base;
>  	u64			cfg0_base;
> -	u64			cfg0_mod_base;
>  	void __iomem		*va_cfg0_base;
>  	u32			cfg0_size;
>  	u64			cfg1_base;
> -	u64			cfg1_mod_base;
>  	void __iomem		*va_cfg1_base;
>  	u32			cfg1_size;
> -	u64			io_base;
> -	u64			io_mod_base;
> +	resource_size_t		io_base;
>  	phys_addr_t		io_bus_addr;
>  	u32			io_size;
>  	u64			mem_base;
> -	u64			mem_mod_base;
>  	phys_addr_t		mem_bus_addr;
>  	u32			mem_size;
> -	struct resource		cfg;
> -	struct resource		io;
> -	struct resource		mem;
> -	struct resource		busn;
> +	struct resource		*cfg;
> +	struct resource		*io;
> +	struct resource		*mem;
> +	struct resource		*busn;
>  	int			irq;
>  	u32			lanes;
>  	struct pcie_host_ops	*ops;
> diff --git a/drivers/pci/host/pcie-spear13xx.c b/drivers/pci/host/pcie-spear13xx.c
> index c49fbdc..03eb204 100644
> --- a/drivers/pci/host/pcie-spear13xx.c
> +++ b/drivers/pci/host/pcie-spear13xx.c
> @@ -286,7 +286,7 @@ static int spear13xx_add_pcie_port(struct pcie_port *pp,
>  		return ret;
>  	}
>  
> -	pp->root_bus_nr = -1;
> +	pp->root_bus_nr = 0;
>  	pp->ops = &spear13xx_pcie_host_ops;
>  
>  	ret = dw_pcie_host_init(pp);
> 




From tomeu.vizoso at collabora.com  Thu Aug  6 23:55:45 2015
From: tomeu.vizoso at collabora.com (Tomeu Vizoso)
Date: Fri, 7 Aug 2015 08:55:45 +0200
Subject: [PATCH v3 0/18] On-demand device probing
In-Reply-To: <CAL_JsqKq_-TLb_3VRMN_MhjsGnRfpRN1uuEgHE9DAyP3Y3ovhQ@mail.gmail.com>
References: <1438870315-18689-1-git-send-email-tomeu.vizoso@collabora.com>
 <CAL_JsqKq_-TLb_3VRMN_MhjsGnRfpRN1uuEgHE9DAyP3Y3ovhQ@mail.gmail.com>
Message-ID: <CAAObsKDAMgsVbzvgofbktKAbdgO+iwdXZwSo8AauTVJdaN3TsA@mail.gmail.com>

On 6 August 2015 at 22:14, Rob Herring <robherring2 at gmail.com> wrote:
> On Thu, Aug 6, 2015 at 9:11 AM, Tomeu Vizoso <tomeu.vizoso at collabora.com> wrote:
>> Hello,
>>
>> I have a problem with the panel on my Tegra Chromebook taking longer
>> than expected to be ready during boot (St?phane Marchesin reported what
>> is basically the same issue in [0]), and have looked into ordered
>> probing as a better way of solving this than moving nodes around in the
>> DT or playing with initcall levels and linking order.
>>
>> While reading the thread [1] that Alexander Holler started with his
>> series to make probing order deterministic, it occurred to me that it
>> should be possible to achieve the same by probing devices as they are
>> referenced by other devices.
>>
>> This basically reuses the information that is already implicit in the
>> probe() implementations, saving us from refactoring existing drivers or
>> adding information to DTBs.
>>
>> During review of v1 of this series Linus Walleij suggested that it
>> should be the device driver core to make sure that dependencies are
>> ready before probing a device. I gave this idea a try [2] but Mark Brown
>> pointed out to the logic duplication between the resource acquisition
>> and dependency discovery code paths (though I think it's fairly minor).
>>
>> To address that code duplication I experimented with Arnd's devm_probe
>> [3] concept of having drivers declare their dependencies instead of
>> acquiring them during probe, and while it worked [4], I don't think we
>> end up winning anything when compared to just probing devices on-demand
>> from resource getters.
>>
>> One remaining objection is to the "sprinkling" of calls to
>> fwnode_ensure_device() in the resource getters of each subsystem, but I
>> think it's the right thing to do given that the storage of resources is
>> currently subsystem-specific.
>>
>> We could avoid the above by moving resource storage into the core, but I
>> don't think there's a compelling case for that.
>>
>> I have tested this on boards with Tegra, iMX.6, Exynos and OMAP SoCs,
>> and these patches were enough to eliminate all the deferred probes
>> (except one in PandaBoard because omap_dma_system doesn't have a
>> firmware node as of yet).
>>
>> Have submitted a branch [5] with these patches to kernelci.org and I'm
>> currently trying to fix all regressions, usually due to code assuming
>> that devices will be probed in a specific order. Current results [6] are
>> 348 passes, 30 fails and 42 unknowns (linux-next [7] is currently
>> 387/3/23).
>
> This is a bit worrying. If this causes a high number of boot failures,
> fixing the errors you can find is not the path forward as we can't
> test a lot of platforms (and many people don't look at -next). We may
> want to put this behind a kconfig option so that we can easily restore
> old behavior it needed. Otherwise, we could have to revert the series.

A Kconfig sounds fine to me. Altogether, I don't think it's that bad
because only these boards are known to have broken because of this
series:

at91-sama5d3_xplained
sama5d35ek

ste-snowball

vexpress-v2p-ca15
vexpress-v2p-ca15
vexpress-v2p-ca15_a7
vexpress-v2p-ca15-tc1
vexpress-v2p-ca9

I assume there's only 3 different bugs to fix there, plus a race in
imx boards that I have only papered over with a delay so far.

The failure rate seems to be so high because each boot is a
combination of board+defconfig and there are duplicated boards in
several labs and many were just offline at that moment.

But I agree that there's no way I can test it on all supported hw, so
a Kconfig that people can quickly switch on to disable the feature
sounds good to me.

> Are all the commits before this series fixing boot failures? You can't
> do dts updates as the fix or backwards compatibility will be broken.

The gpio-ranges fix for Tegra has a commit that safeguards backwards
compatibility, and the typo in regulator names for ux500 doesn't
really break anything that I can see, I just stumped into it when
trying to blindly fix the boot for ste-snowball (I don't have access
to that hw).

>> With this series I get the kernel to output to the panel in 0.5s,
>> instead of 2.8s.
>>
>> Regards,
>>
>> Tomeu
>>
>> [0] http://lists.freedesktop.org/archives/dri-devel/2014-August/066527.html
>>
>> [1] https://lkml.org/lkml/2014/5/12/452
>>
>> [2] https://lkml.org/lkml/2015/6/17/305
>>
>> [3] http://article.gmane.org/gmane.linux.ports.arm.kernel/277689
>>
>> [4] https://lkml.org/lkml/2015/7/21/441a
>>
>> [5] https://git.collabora.com/cgit/user/tomeu/linux.git/log/?h=on-demand-probes-v5
>>
>> [6] http://kernelci.org/boot/all/job/collabora/kernel/v4.2-rc5-6548-g632b98c83840/
>>
>> [7] http://kernelci.org/boot/all/job/next/kernel/next-20150806/
>>
>> Changes in v3:
>> - Only delay platform devices with OF nodes
>> - Set and use device_node.platform_dev instead of reversing the logic to
>>   find the platform device that encloses a device node.
>
> I still want this to be a struct device and not a struct
> platform_device and am not convinced it can't be. It can simply be an
> optimization of the existing function:

Now I realize what you meant, that makes sense to me.

Thanks,

Tomeu

> struct platform_device *of_find_device_by_node(struct device_node *np)
> {
>   if (node->device && node->device->bus == &platform_bus_type)
>     return to_platform_device(node->device);
>   return NULL;
> }
>
> Rob
> --
> To unsubscribe from this list: send the line "unsubscribe linux-kernel" in
> the body of a message to majordomo at vger.kernel.org
> More majordomo info at  http://vger.kernel.org/majordomo-info.html
> Please read the FAQ at  http://www.tux.org/lkml/


From davem at davemloft.net  Thu Aug  6 23:58:49 2015
From: davem at davemloft.net (David Miller)
Date: Thu, 06 Aug 2015 23:58:49 -0700 (PDT)
Subject: [PATCH net] net: thunderx: remove effective "default y" from
 Kconfig if ARCH_THUNDER=y
In-Reply-To: <1438716355-11515-1-git-send-email-ijc@hellion.org.uk>
References: <1438716355-11515-1-git-send-email-ijc@hellion.org.uk>
Message-ID: <20150806.235849.1866973399577659068.davem@davemloft.net>

From: Ian Campbell <ijc at hellion.org.uk>
Date: Tue,  4 Aug 2015 20:25:55 +0100

> As well as for kernels built only for ThunderX ARCH_THUNDERX is also enabled
> for kernels which support multiple platforms (such as distro kernels). Thus
> "default ARCH_THUNDER" is inappropriate.
> 
> I believe default m is equally frowned upon, so remove the line completely
> rather than "default m if ARCH_THUNDER".
> 
> Signed-off-by: Ian Campbell <ijc at hellion.org.uk>

Applied.


From eric.auger at linaro.org  Fri Aug  7 00:05:56 2015
From: eric.auger at linaro.org (Eric Auger)
Date: Fri, 07 Aug 2015 09:05:56 +0200
Subject: [PATCH v3 09/11] KVM: arm/arm64: vgic: Prevent userspace injection
 of a mapped interrupt
In-Reply-To: <55C38EF5.1080502@arm.com>
References: <1437753309-17989-1-git-send-email-marc.zyngier@arm.com>
 <1437753309-17989-10-git-send-email-marc.zyngier@arm.com>
 <55C0E690.1090808@linaro.org> <55C0EBF5.2060708@arm.com>
 <55C1BBF9.2060004@linaro.org> <55C1DAE9.1050609@arm.com>
 <20150805105345.GA4657@cbox> <55C1F7CF.5070904@linaro.org>
 <20150805134754.GB4657@cbox> <55C38EF5.1080502@arm.com>
Message-ID: <55C458D4.9030500@linaro.org>

Hi Marc,
On 08/06/2015 06:44 PM, Marc Zyngier wrote:
> On 05/08/15 14:47, Christoffer Dall wrote:
>> On Wed, Aug 05, 2015 at 01:47:27PM +0200, Eric Auger wrote:
>>> On 08/05/2015 12:53 PM, Christoffer Dall wrote:
>>>> On Wed, Aug 05, 2015 at 10:44:09AM +0100, Marc Zyngier wrote:
>>>>> On 05/08/15 08:32, Eric Auger wrote:
>>>>>> Hi Marc,
>>>>>> On 08/04/2015 06:44 PM, Marc Zyngier wrote:
>>>>>>> On 04/08/15 17:21, Eric Auger wrote:
>>>>>>>> Hi Marc,
>>>>>>>> On 07/24/2015 05:55 PM, Marc Zyngier wrote:
>>>>>>>>> Virtual interrupts mapped to a HW interrupt should only be triggered
>>>>>>>>> from inside the kernel. Otherwise, you could end up confusing the
>>>>>>>>> kernel (and the GIC's) state machine.
>>>>>>>>>
>>>>>>>>> Rearrange the injection path so that kvm_vgic_inject_irq is
>>>>>>>>> used for non-mapped interrupts, and kvm_vgic_inject_mapped_irq is
>>>>>>>>> used for mapped interrupts. The latter should only be called from
>>>>>>>>> inside the kernel (timer, VFIO).
>>>>>>>> nit: I would replace VFIO by irqfd.
>>>>>>>> VFIO just triggers the eventfd/irqfd. This is KVM/irqfd that injects the
>>>>>>>> virtual irq upon the irqfd signaling and he irqfd adaptation/ARM
>>>>>>>> currently is implemented in vgic.c
>>>>>>>
>>>>>>> Ah, thanks for reminding me of the right terminology, I tend to think of
>>>>>>> it as one big bag of nasty tricks... ;-)
>>>>>>>
>>>>>>> I'll update the commit message.
>>>>>>>
>>>>>>>>>
>>>>>>>>> Signed-off-by: Marc Zyngier <marc.zyngier at arm.com>
>>>>>>>>> ---
>>>>>>>>>  include/kvm/arm_vgic.h |  2 +
>>>>>>>>>  virt/kvm/arm/vgic.c    | 99 ++++++++++++++++++++++++++++++++++----------------
>>>>>>>>>  2 files changed, 70 insertions(+), 31 deletions(-)
>>>>>>>>>
>>>>>>>>> diff --git a/include/kvm/arm_vgic.h b/include/kvm/arm_vgic.h
>>>>>>>>> index 7306b4b..f6bfd79 100644
>>>>>>>>> --- a/include/kvm/arm_vgic.h
>>>>>>>>> +++ b/include/kvm/arm_vgic.h
>>>>>>>>> @@ -351,6 +351,8 @@ void kvm_vgic_flush_hwstate(struct kvm_vcpu *vcpu);
>>>>>>>>>  void kvm_vgic_sync_hwstate(struct kvm_vcpu *vcpu);
>>>>>>>>>  int kvm_vgic_inject_irq(struct kvm *kvm, int cpuid, unsigned int irq_num,
>>>>>>>>>  			bool level);
>>>>>>>>> +int kvm_vgic_inject_mapped_irq(struct kvm *kvm, int cpuid,
>>>>>>>>> +			       struct irq_phys_map *map, bool level);
>>>>>>>>>  void vgic_v3_dispatch_sgi(struct kvm_vcpu *vcpu, u64 reg);
>>>>>>>>>  int kvm_vgic_vcpu_pending_irq(struct kvm_vcpu *vcpu);
>>>>>>>>>  int kvm_vgic_vcpu_active_irq(struct kvm_vcpu *vcpu);
>>>>>>>>> diff --git a/virt/kvm/arm/vgic.c b/virt/kvm/arm/vgic.c
>>>>>>>>> index 3f7b690..e40ef70 100644
>>>>>>>>> --- a/virt/kvm/arm/vgic.c
>>>>>>>>> +++ b/virt/kvm/arm/vgic.c
>>>>>>>>> @@ -1533,7 +1533,8 @@ static int vgic_validate_injection(struct kvm_vcpu *vcpu, int irq, int level)
>>>>>>>>>  }
>>>>>>>>>  
>>>>>>>>>  static int vgic_update_irq_pending(struct kvm *kvm, int cpuid,
>>>>>>>>> -				  unsigned int irq_num, bool level)
>>>>>>>>> +				   struct irq_phys_map *map,
>>>>>>>>> +				   unsigned int irq_num, bool level)
>>>>>>>>>  {
>>>>>>>> In vgic_update_irq_pending, I needed to modify the following line and
>>>>>>>> add the "&& !map".
>>>>>>>>
>>>>>>>>         if (!vgic_validate_injection(vcpu, irq_num, level) && !map) {
>>>>>>>>
>>>>>>>> Without that, the level being not properly modeled for level sensitive
>>>>>>>> forwarded IRQs, the 2d injection fails.
>>>>>>>
>>>>>>> Ah! Is that because we never see the line being reset to zero, and the
>>>>>>> VGIC still sees the line as pending at the distributor level?
>>>>>> yes indeed
>>>>>
>>>>> Then it is a bigger problem we need to solve, and your solution just
>>>>> papers over the issue.
>>>>>
>>>>> The main problem is that irqfd is essentially an edge-triggered
>>>>> signalling. Fire and forget. Given that we're dealing with a level
>>>>> triggered interrupt, we end up with the interrupt still marked as
>>>>> pending (nobody took the signal down).
>>> this does not really relate to irqfd: irqfd also comes with the concept
>>> of resamplefd. in case the IRQ is not forwarded, this is the
>>> irqfd_resampler_ack function that toggles the IRQ down (eventfd.c). Its
>>> execution is triggered in vgic_process_maintenance. With forwarding the
>>> EOI is not trappable anymore so this disappears.
>>>
>>>
>>>>> The usual way to get out of that mess in is to evaluate the state of the
>>>>> level on EOI. But we can't trap on EOI for a HW interrupt.
>>>>>
>>>>> So it raises the question: should we instead consider the HW pending
>>>>> state instead of the software one for mapped interrupts? It is
>>>>> expensive, but it feels more correct.
>>>>>
>>>> I thought we already covered this at LCA.  For mapped interrupts
>>>> (forwarded) we should never consider the software pending state, because
>>>> that state is managed by the hardware.  Or am I confusing concepts here?
>>>
>>> Yes we discussed we should bypass most of the SW states.
>>>
>>> in my previous integration I proposed a patch "KVM: arm: vgic: fix state
>>> machine for forwarded IRQ". What's wrong with the below approach?
>>>
>>>
>>>     Fix multiple injection of level sensitive forwarded IRQs.
>>>     With current code, the second injection fails since the
>>>     state bitmaps are not reset (process_maintenance is not
>>>     called anymore).
>>>
>>>     New implementation follows those principles:
>>>     - A forwarded IRQ only can be sampled when it is pending
>>>     - when queueing the IRQ (programming the LR), the pending state
>>>       is removed as for edge sensitive IRQs
>>>     - an injection of a forwarded IRQ is considered always valid since
>>>       coming from the HW and level always is 1.
>>>
>> I don't see anything wrong, and I thought this was what we discussed.
> 
> I think I just lost track of what we've discussed at LCA. Ignore me.
> 
> I'll repost the updated first 10 patches tomorrow. Eric, are you willing
> to take custody of patch 11 as part of one of your series?
Yes no problem I can take this over if you prefer. I can easily test it.
May I put it in the irq forwarding series?

Best Regards

Eric
> 
> Thanks,
> 
> 	M.
> 



From tomeu.vizoso at collabora.com  Fri Aug  7 00:11:23 2015
From: tomeu.vizoso at collabora.com (Tomeu Vizoso)
Date: Fri, 7 Aug 2015 09:11:23 +0200
Subject: [PATCH v3 01/18] platform: delay OF device-driver matches until
 late_initcall
In-Reply-To: <CAL_Jsq+GLMZe-f6qEi=7i1YrrWc6k99RpGkOyCd5KkYDiyt0QA@mail.gmail.com>
References: <1438870315-18689-1-git-send-email-tomeu.vizoso@collabora.com>
 <1438870315-18689-2-git-send-email-tomeu.vizoso@collabora.com>
 <CAL_Jsq+GLMZe-f6qEi=7i1YrrWc6k99RpGkOyCd5KkYDiyt0QA@mail.gmail.com>
Message-ID: <CAAObsKBapFqzr+4YEXJfcJWMd+tkaBqYbGiFTntHStAP=+P-_Q@mail.gmail.com>

On 6 August 2015 at 22:19, Rob Herring <robherring2 at gmail.com> wrote:
> On Thu, Aug 6, 2015 at 9:11 AM, Tomeu Vizoso <tomeu.vizoso at collabora.com> wrote:
>> Delay matches of platform devices with OF nodes until late_initcall,
>> when we are sure that all built-in drivers have been registered already.
>> This is needed to prevent deferred probes because of some drivers not
>> having registered yet.
>>
>> The reason why only platform devices are delayed is that some other
>> devices are expected to be probed earlier than late_initcall, for
>> example, the system PNP driver needs to probe its devices in
>> fs_initcall.
>>
>> Additionally, only platform devices with OF nodes are delayed because
>> some machines may depend on oter platform devices being registered at
>> specific times.
>
> How do we know that these probes occur before the unused clocks and
> regulators are turned off? Just getting lucky (as is deferred probe)?
> Can we do this one level earlier so we have a level left to do things
> after probe.

Those are already late_initcall_sync so I guess we're fine.

Thanks,

Tomeu

> Rob
> --
> To unsubscribe from this list: send the line "unsubscribe linux-kernel" in
> the body of a message to majordomo at vger.kernel.org
> More majordomo info at  http://vger.kernel.org/majordomo-info.html
> Please read the FAQ at  http://www.tux.org/lkml/


From leilk.liu at mediatek.com  Fri Aug  7 00:19:49 2015
From: leilk.liu at mediatek.com (Leilk Liu)
Date: Fri, 7 Aug 2015 15:19:49 +0800
Subject: [PATCH v5 1/3] spi: Mediatek: Document devicetree bindings for spi bus
In-Reply-To: <1438931991-17044-1-git-send-email-leilk.liu@mediatek.com>
References: <1438931991-17044-1-git-send-email-leilk.liu@mediatek.com>
Message-ID: <1438931991-17044-2-git-send-email-leilk.liu@mediatek.com>

Signed-off-by: Leilk Liu <leilk.liu at mediatek.com>
---
Change in this patch:
1. change this patch title.
2. change "MTK SPI device" to "MTK SPI controller".
3. "pad-select" is a vendor property, so change it to "mediatek,pad-select".
4. modify the property of clock and clock name.
5. explain what the pad-select values 0-3 mean.
---
 .../devicetree/bindings/spi/spi-mt65xx.txt         | 51 ++++++++++++++++++++++
 1 file changed, 51 insertions(+)
 create mode 100644 Documentation/devicetree/bindings/spi/spi-mt65xx.txt

diff --git a/Documentation/devicetree/bindings/spi/spi-mt65xx.txt b/Documentation/devicetree/bindings/spi/spi-mt65xx.txt
new file mode 100644
index 0000000..dcefc43
--- /dev/null
+++ b/Documentation/devicetree/bindings/spi/spi-mt65xx.txt
@@ -0,0 +1,51 @@
+Binding for MTK SPI controller
+
+Required properties:
+- compatible: should be one of the following.
+    - mediatek,mt8173-spi: for mt8173 platforms
+    - mediatek,mt8135-spi: for mt8135 platforms
+    - mediatek,mt6589-spi: for mt6589 platforms
+
+- #address-cells: should be 1.
+
+- #size-cells: should be 0.
+
+- reg: Address and length of the register set for the device
+
+- interrupts: Should contain spi interrupt
+
+- clocks: phandles to input clocks.
+  The first should be <&topckgen CLK_TOP_SPI_SEL>.
+  The second should be one of the following.
+   -  <&clk26m>: specify parent clock 26MHZ.
+   -  <&topckgen CLK_TOP_SYSPLL3_D2>: specify parent clock 109MHZ.
+				      It's the default one.
+   -  <&topckgen CLK_TOP_SYSPLL4_D2>: specify parent clock 78MHZ.
+   -  <&topckgen CLK_TOP_UNIVPLL2_D4>: specify parent clock 104MHZ.
+   -  <&topckgen CLK_TOP_UNIVPLL1_D8>: specify parent clock 78MHZ.
+
+- clock-names: shall be "spi-clk" for the controller clock, and
+  "parent-clk" for the parent clock.
+
+Optional properties:
+- mediatek,pad-select: specify which pins group(ck/mi/mo/cs) spi
+  controller used, this value should be 0~3, only required for MT8173.
+    0: specify GPIO69,70,71,72 for spi pins.
+    1: specify GPIO102,103,104,105 for spi pins.
+    2: specify GPIO128,129,130,131 for spi pins.
+    3: specify GPIO5,6,7,8 for spi pins.
+
+Example:
+
+- SoC Specific Portion:
+spi: spi at 1100a000 {
+	compatible = "mediatek,mt8173-spi";
+	#address-cells = <1>;
+	#size-cells = <0>;
+	reg = <0 0x1100a000 0 0x1000>;
+	interrupts = <GIC_SPI 110 IRQ_TYPE_LEVEL_LOW>;
+	clocks = <&topckgen CLK_TOP_SPI_SEL>, <&topckgen CLK_TOP_SYSPLL3_D2>;
+	clock-names = "spi-clk", "parent-clk";
+	mediatek,pad-select = <0>;
+	status = "disabled";
+};
-- 
1.8.1.1.dirty



From leilk.liu at mediatek.com  Fri Aug  7 00:19:48 2015
From: leilk.liu at mediatek.com (Leilk Liu)
Date: Fri, 7 Aug 2015 15:19:48 +0800
Subject: [PATCH v5 0/3] Add Mediatek SPI bus driver
Message-ID: <1438931991-17044-1-git-send-email-leilk.liu@mediatek.com>

This series are based on 4.2-rc1 and provide three patches to add mediatek spi driver.

Change in v5:
1. add changelogs in the individual patches.
2. modify clk relevant implement.
3. describe dt-binding document in more detail.

Change in v4:
1. fix Mark Brown review comment.

Change in v3:
1. support fifo mode function.
2. support any non-prime length transfer in dma mode.
3. use interrupt to handle scatterlist.
4. fix review comment.

Change in v2:
1. Remove spi bitbang framwork, use can_dma() and transfer_one().
2. Add PM functions.
3. Fix Mark Brown review comment.

Leilk Liu (3):
  spi: Mediatek: Document devicetree bindings for spi bus
  spi: mediatek: Add spi bus for Mediatek MT8173
  arm64: dts: Add spi bus dts

 .../devicetree/bindings/spi/spi-mt65xx.txt         |  51 ++
 arch/arm64/boot/dts/mediatek/mt8173.dtsi           |  23 +
 drivers/spi/Kconfig                                |   9 +
 drivers/spi/Makefile                               |   1 +
 drivers/spi/spi-mt65xx.c                           | 749 +++++++++++++++++++++
 include/linux/platform_data/spi-mt65xx.h           |  22 +
 6 files changed, 855 insertions(+)
 create mode 100644 Documentation/devicetree/bindings/spi/spi-mt65xx.txt
 create mode 100644 drivers/spi/spi-mt65xx.c
 create mode 100644 include/linux/platform_data/spi-mt65xx.h

--
1.8.1.1.dirty




From leilk.liu at mediatek.com  Fri Aug  7 00:19:51 2015
From: leilk.liu at mediatek.com (Leilk Liu)
Date: Fri, 7 Aug 2015 15:19:51 +0800
Subject: [PATCH v5 3/3] arm64: dts: Add spi bus dts
In-Reply-To: <1438931991-17044-1-git-send-email-leilk.liu@mediatek.com>
References: <1438931991-17044-1-git-send-email-leilk.liu@mediatek.com>
Message-ID: <1438931991-17044-4-git-send-email-leilk.liu@mediatek.com>

This patch adds MT8173 spi bus controllers into device tree.

Signed-off-by: Leilk Liu <leilk.liu at mediatek.com>
---
Change in this patch:
1. "pad-select" is a vendor property, so change it to "mediatek,pad-select".
2. modify the property of clocks and clock-names.
---
 arch/arm64/boot/dts/mediatek/mt8173.dtsi | 23 +++++++++++++++++++++++
 1 file changed, 23 insertions(+)

diff --git a/arch/arm64/boot/dts/mediatek/mt8173.dtsi b/arch/arm64/boot/dts/mediatek/mt8173.dtsi
index d18ee42..066bd6a 100644
--- a/arch/arm64/boot/dts/mediatek/mt8173.dtsi
+++ b/arch/arm64/boot/dts/mediatek/mt8173.dtsi
@@ -220,6 +220,15 @@
 					bias-disable;
 				};
 			};
+
+			spi_pins_a: spi0 {
+				pins_spi {
+					pinmux = <MT8173_PIN_69_SPI_CK__FUNC_SPI_CK_0_>,
+						<MT8173_PIN_70_SPI_MI__FUNC_SPI_MI_0_>,
+						<MT8173_PIN_71_SPI_MO__FUNC_SPI_MO_0_>,
+						<MT8173_PIN_72_SPI_CS__FUNC_SPI_CS_0_>;
+				};
+			};
 		};
 
 		scpsys: scpsys at 10006000 {
@@ -365,6 +374,20 @@
 			status = "disabled";
 		};
 
+		spi: spi at 1100a000 {
+			compatible = "mediatek,mt8173-spi";
+			#address-cells = <1>;
+			#size-cells = <0>;
+			reg = <0 0x1100a000 0 0x1000>;
+			interrupts = <GIC_SPI 110 IRQ_TYPE_LEVEL_LOW>;
+			clocks = <&topckgen CLK_TOP_SPI_SEL>, <&topckgen CLK_TOP_SYSPLL3_D2>;
+			clock-names = "spi-clk", "parent-clk";
+			pinctrl-names = "default";
+			pinctrl-0 = <&spi_pins_a>;
+			mediatek,pad-select = <0>;
+			status = "disabled";
+		};
+
 		i2c3: i2c3 at 11010000 {
 			compatible = "mediatek,mt8173-i2c";
 			reg = <0 0x11010000 0 0x70>,
-- 
1.8.1.1.dirty



From leilk.liu at mediatek.com  Fri Aug  7 00:19:50 2015
From: leilk.liu at mediatek.com (Leilk Liu)
Date: Fri, 7 Aug 2015 15:19:50 +0800
Subject: [PATCH v5 2/3] spi: mediatek: Add spi bus for Mediatek MT8173
In-Reply-To: <1438931991-17044-1-git-send-email-leilk.liu@mediatek.com>
References: <1438931991-17044-1-git-send-email-leilk.liu@mediatek.com>
Message-ID: <1438931991-17044-3-git-send-email-leilk.liu@mediatek.com>

This patch adds basic spi bus for MT8173.

Signed-off-by: Leilk Liu <leilk.liu at mediatek.com>
---
Change in this patch:
1. change "pad-select" to "mediatek,pad-select".
2. modify clk relevant implement.
---
 drivers/spi/Kconfig                      |   9 +
 drivers/spi/Makefile                     |   1 +
 drivers/spi/spi-mt65xx.c                 | 749 +++++++++++++++++++++++++++++++
 include/linux/platform_data/spi-mt65xx.h |  22 +
 4 files changed, 781 insertions(+)
 create mode 100644 drivers/spi/spi-mt65xx.c
 create mode 100644 include/linux/platform_data/spi-mt65xx.h

diff --git a/drivers/spi/Kconfig b/drivers/spi/Kconfig
index 0cae169..38ddfba 100644
--- a/drivers/spi/Kconfig
+++ b/drivers/spi/Kconfig
@@ -326,6 +326,15 @@ config SPI_MESON_SPIFC
 	  This enables master mode support for the SPIFC (SPI flash
 	  controller) available in Amlogic Meson SoCs.
 
+config SPI_MT65XX
+	tristate "MediaTek SPI controller"
+	depends on ARCH_MEDIATEK || COMPILE_TEST
+	help
+	  This selects the MediaTek(R) SPI bus driver.
+	  If you want to use MediaTek(R) SPI interface,
+	  say Y or M here.If you are not sure, say N.
+	  SPI drivers for Mediatek MT65XX and MT81XX series ARM SoCs.
+
 config SPI_OC_TINY
 	tristate "OpenCores tiny SPI"
 	depends on GPIOLIB || COMPILE_TEST
diff --git a/drivers/spi/Makefile b/drivers/spi/Makefile
index 1154dba..9746beb2 100644
--- a/drivers/spi/Makefile
+++ b/drivers/spi/Makefile
@@ -48,6 +48,7 @@ obj-$(CONFIG_SPI_MESON_SPIFC)		+= spi-meson-spifc.o
 obj-$(CONFIG_SPI_MPC512x_PSC)		+= spi-mpc512x-psc.o
 obj-$(CONFIG_SPI_MPC52xx_PSC)		+= spi-mpc52xx-psc.o
 obj-$(CONFIG_SPI_MPC52xx)		+= spi-mpc52xx.o
+obj-$(CONFIG_SPI_MT65XX)                += spi-mt65xx.o
 obj-$(CONFIG_SPI_MXS)			+= spi-mxs.o
 obj-$(CONFIG_SPI_NUC900)		+= spi-nuc900.o
 obj-$(CONFIG_SPI_OC_TINY)		+= spi-oc-tiny.o
diff --git a/drivers/spi/spi-mt65xx.c b/drivers/spi/spi-mt65xx.c
new file mode 100644
index 0000000..4676b01
--- /dev/null
+++ b/drivers/spi/spi-mt65xx.c
@@ -0,0 +1,749 @@
+/*
+ * Copyright (c) 2015 MediaTek Inc.
+ * Author: Leilk Liu <leilk.liu at 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/clk.h>
+#include <linux/device.h>
+#include <linux/err.h>
+#include <linux/interrupt.h>
+#include <linux/ioport.h>
+#include <linux/module.h>
+#include <linux/of.h>
+#include <linux/platform_device.h>
+#include <linux/platform_data/spi-mt65xx.h>
+#include <linux/pm_runtime.h>
+#include <linux/spi/spi.h>
+
+#define SPI_CFG0_REG                      0x0000
+#define SPI_CFG1_REG                      0x0004
+#define SPI_TX_SRC_REG                    0x0008
+#define SPI_RX_DST_REG                    0x000c
+#define SPI_TX_DATA_REG                   0x0010
+#define SPI_RX_DATA_REG                   0x0014
+#define SPI_CMD_REG                       0x0018
+#define SPI_STATUS0_REG                   0x001c
+#define SPI_PAD_SEL_REG                   0x0024
+
+#define SPI_CFG0_SCK_HIGH_OFFSET          0
+#define SPI_CFG0_SCK_LOW_OFFSET           8
+#define SPI_CFG0_CS_HOLD_OFFSET           16
+#define SPI_CFG0_CS_SETUP_OFFSET          24
+
+#define SPI_CFG1_CS_IDLE_OFFSET           0
+#define SPI_CFG1_PACKET_LOOP_OFFSET       8
+#define SPI_CFG1_PACKET_LENGTH_OFFSET     16
+#define SPI_CFG1_GET_TICK_DLY_OFFSET      30
+
+#define SPI_CFG1_CS_IDLE_MASK             0xff
+#define SPI_CFG1_PACKET_LOOP_MASK         0xff00
+#define SPI_CFG1_PACKET_LENGTH_MASK       0x3ff0000
+
+#define SPI_CMD_ACT_OFFSET                0
+#define SPI_CMD_RESUME_OFFSET             1
+#define SPI_CMD_CPHA_OFFSET               8
+#define SPI_CMD_CPOL_OFFSET               9
+#define SPI_CMD_TXMSBF_OFFSET             12
+#define SPI_CMD_RXMSBF_OFFSET             13
+#define SPI_CMD_RX_ENDIAN_OFFSET          14
+#define SPI_CMD_TX_ENDIAN_OFFSET          15
+
+#define SPI_CMD_RST                  BIT(2)
+#define SPI_CMD_PAUSE_EN             BIT(4)
+#define SPI_CMD_DEASSERT             BIT(5)
+#define SPI_CMD_CPHA                 BIT(8)
+#define SPI_CMD_CPOL                 BIT(9)
+#define SPI_CMD_RX_DMA               BIT(10)
+#define SPI_CMD_TX_DMA               BIT(11)
+#define SPI_CMD_TXMSBF               BIT(12)
+#define SPI_CMD_RXMSBF               BIT(13)
+#define SPI_CMD_RX_ENDIAN            BIT(14)
+#define SPI_CMD_TX_ENDIAN            BIT(15)
+#define SPI_CMD_FINISH_IE            BIT(16)
+#define SPI_CMD_PAUSE_IE             BIT(17)
+
+#define MTK_SPI_QUIRK_PAD_SELECT 1
+/* Must explicitly send dummy Tx bytes to do Rx only transfer */
+#define MTK_SPI_QUIRK_MUST_TX 1
+
+#define MT8173_SPI_MAX_PAD_SEL 3
+
+#define MTK_SPI_IDLE 0
+#define MTK_SPI_PAUSED 1
+
+#define MTK_SPI_MAX_FIFO_SIZE 32
+#define MTK_SPI_PACKET_SIZE 1024
+
+struct mtk_spi_compatible {
+	u32 need_pad_sel;
+	u32 must_tx;
+};
+
+struct mtk_spi {
+	void __iomem *base;
+	u32 state;
+	u32 pad_sel;
+	struct clk *spi_clk, *parent_clk;
+	struct spi_transfer *cur_transfer;
+	u32 xfer_len;
+	struct scatterlist *tx_sgl, *rx_sgl;
+	u32 tx_sgl_len, rx_sgl_len;
+	const struct mtk_spi_compatible *dev_comp;
+};
+
+static const struct mtk_spi_compatible mt6589_compat = {
+	.need_pad_sel = 0,
+	.must_tx = 0,
+};
+
+static const struct mtk_spi_compatible mt8135_compat = {
+	.need_pad_sel = 0,
+	.must_tx = 0,
+};
+
+static const struct mtk_spi_compatible mt8173_compat = {
+	.need_pad_sel = MTK_SPI_QUIRK_PAD_SELECT,
+	.must_tx = MTK_SPI_QUIRK_MUST_TX,
+};
+
+/*
+ * A piece of default chip info unless the platform
+ * supplies it.
+ */
+static const struct mtk_chip_config mtk_default_chip_info = {
+	.rx_mlsb = 1,
+	.tx_mlsb = 1,
+	.tx_endian = 0,
+	.rx_endian = 0,
+};
+
+static const struct of_device_id mtk_spi_of_match[] = {
+	{ .compatible = "mediatek,mt6589-spi", .data = (void *)&mt6589_compat },
+	{ .compatible = "mediatek,mt8135-spi", .data = (void *)&mt8135_compat },
+	{ .compatible = "mediatek,mt8173-spi", .data = (void *)&mt8173_compat },
+	{}
+};
+MODULE_DEVICE_TABLE(of, mtk_spi_of_match);
+
+static void mtk_spi_reset(struct mtk_spi *mdata)
+{
+	u32 reg_val;
+
+	/* set the software reset bit in SPI_CMD_REG. */
+	reg_val = readl(mdata->base + SPI_CMD_REG);
+	reg_val |= SPI_CMD_RST;
+	writel(reg_val, mdata->base + SPI_CMD_REG);
+
+	reg_val = readl(mdata->base + SPI_CMD_REG);
+	reg_val &= ~SPI_CMD_RST;
+	writel(reg_val, mdata->base + SPI_CMD_REG);
+}
+
+static void mtk_spi_config(struct mtk_spi *mdata,
+			   struct mtk_chip_config *chip_config)
+{
+	u32 reg_val;
+
+	reg_val = readl(mdata->base + SPI_CMD_REG);
+
+	/* set the mlsbx and mlsbtx */
+	reg_val &= ~(SPI_CMD_TXMSBF | SPI_CMD_RXMSBF);
+	reg_val |= (chip_config->tx_mlsb << SPI_CMD_TXMSBF_OFFSET);
+	reg_val |= (chip_config->rx_mlsb << SPI_CMD_RXMSBF_OFFSET);
+
+	/* set the tx/rx endian */
+	reg_val &= ~(SPI_CMD_TX_ENDIAN | SPI_CMD_RX_ENDIAN);
+	reg_val |= (chip_config->tx_endian << SPI_CMD_TX_ENDIAN_OFFSET);
+	reg_val |= (chip_config->rx_endian << SPI_CMD_RX_ENDIAN_OFFSET);
+
+	/* set finish and pause interrupt always enable */
+	reg_val |= SPI_CMD_FINISH_IE | SPI_CMD_PAUSE_EN;
+
+	/* disable dma mode */
+	reg_val &= ~(SPI_CMD_TX_DMA | SPI_CMD_RX_DMA);
+
+	/* disable deassert mode */
+	reg_val &= ~SPI_CMD_DEASSERT;
+
+	writel(reg_val, mdata->base + SPI_CMD_REG);
+
+	/* pad select */
+	if (mdata->dev_comp->need_pad_sel)
+		writel(mdata->pad_sel, mdata->base + SPI_PAD_SEL_REG);
+}
+
+static int mtk_spi_prepare_hardware(struct spi_master *master)
+{
+	struct spi_transfer *trans;
+	struct mtk_spi *mdata = spi_master_get_devdata(master);
+	struct spi_message *msg = master->cur_msg;
+	int ret;
+
+	ret = clk_prepare_enable(mdata->spi_clk);
+	if (ret < 0) {
+		dev_err(&master->dev, "failed to enable clock (%d)\n", ret);
+		return ret;
+	}
+
+	trans = list_first_entry(&msg->transfers, struct spi_transfer,
+				 transfer_list);
+	if (trans->cs_change == 0) {
+		mdata->state = MTK_SPI_IDLE;
+		mtk_spi_reset(mdata);
+	}
+
+	return ret;
+}
+
+static int mtk_spi_unprepare_hardware(struct spi_master *master)
+{
+	struct mtk_spi *mdata = spi_master_get_devdata(master);
+
+	clk_disable_unprepare(mdata->spi_clk);
+
+	return 0;
+}
+
+static int mtk_spi_prepare_message(struct spi_master *master,
+				   struct spi_message *msg)
+{
+	u32 reg_val;
+	u8 cpha, cpol;
+	struct mtk_chip_config *chip_config;
+	struct spi_device *spi = msg->spi;
+	struct mtk_spi *mdata = spi_master_get_devdata(master);
+
+	cpha = spi->mode & SPI_CPHA ? 1 : 0;
+	cpol = spi->mode & SPI_CPOL ? 1 : 0;
+
+	reg_val = readl(mdata->base + SPI_CMD_REG);
+	reg_val &= ~(SPI_CMD_CPHA | SPI_CMD_CPOL);
+	reg_val |= (cpha << SPI_CMD_CPHA_OFFSET);
+	reg_val |= (cpol << SPI_CMD_CPOL_OFFSET);
+	writel(reg_val, mdata->base + SPI_CMD_REG);
+
+	chip_config = spi->controller_data;
+	if (!chip_config) {
+		chip_config = (void *)&mtk_default_chip_info;
+		spi->controller_data = chip_config;
+	}
+	mtk_spi_config(mdata, chip_config);
+
+	return 0;
+}
+
+static void mtk_spi_set_cs(struct spi_device *spi, bool enable)
+{
+	u32 reg_val;
+	struct mtk_spi *mdata = spi_master_get_devdata(spi->master);
+
+	reg_val = readl(mdata->base + SPI_CMD_REG);
+	if (!enable)
+		reg_val |= SPI_CMD_PAUSE_EN;
+	else
+		reg_val &= ~SPI_CMD_PAUSE_EN;
+	writel(reg_val, mdata->base + SPI_CMD_REG);
+}
+
+static void mtk_spi_prepare_transfer(struct spi_master *master,
+				     struct spi_transfer *xfer)
+{
+	u32 spi_clk_hz, div, high_time, low_time, holdtime,
+	    setuptime, cs_idletime, reg_val = 0;
+	struct mtk_spi *mdata = spi_master_get_devdata(master);
+
+	spi_clk_hz = clk_get_rate(mdata->spi_clk);
+	if (xfer->speed_hz < spi_clk_hz / 2)
+		div = DIV_ROUND_UP(spi_clk_hz, xfer->speed_hz);
+	else
+		div = 1;
+
+	high_time = (div + 1) / 2;
+	low_time = (div + 1) / 2;
+	holdtime = (div + 1) / 2 * 2;
+	setuptime = (div + 1) / 2 * 2;
+	cs_idletime = (div + 1) / 2 * 2;
+
+	reg_val |= (((high_time - 1) & 0xff) << SPI_CFG0_SCK_HIGH_OFFSET);
+	reg_val |= (((low_time - 1) & 0xff) << SPI_CFG0_SCK_LOW_OFFSET);
+	reg_val |= (((holdtime - 1) & 0xff) << SPI_CFG0_CS_HOLD_OFFSET);
+	reg_val |= (((setuptime - 1) & 0xff) << SPI_CFG0_CS_SETUP_OFFSET);
+	writel(reg_val, mdata->base + SPI_CFG0_REG);
+
+	reg_val = readl(mdata->base + SPI_CFG1_REG);
+	reg_val &= ~SPI_CFG1_CS_IDLE_MASK;
+	reg_val |= (((cs_idletime - 1) & 0xff) << SPI_CFG1_CS_IDLE_OFFSET);
+	writel(reg_val, mdata->base + SPI_CFG1_REG);
+}
+
+static void mtk_spi_setup_packet(struct spi_master *master)
+{
+	u32 packet_size, packet_loop, reg_val;
+	struct mtk_spi *mdata = spi_master_get_devdata(master);
+
+	packet_size = min_t(unsigned, mdata->xfer_len, MTK_SPI_PACKET_SIZE);
+	packet_loop = mdata->xfer_len / packet_size;
+
+	reg_val = readl(mdata->base + SPI_CFG1_REG);
+	reg_val &= ~(SPI_CFG1_PACKET_LENGTH_MASK + SPI_CFG1_PACKET_LOOP_MASK);
+	reg_val |= (packet_size - 1) << SPI_CFG1_PACKET_LENGTH_OFFSET;
+	reg_val |= (packet_loop - 1) << SPI_CFG1_PACKET_LOOP_OFFSET;
+	writel(reg_val, mdata->base + SPI_CFG1_REG);
+}
+
+static void mtk_spi_enable_transfer(struct spi_master *master)
+{
+	int cmd;
+	struct mtk_spi *mdata = spi_master_get_devdata(master);
+
+	cmd = readl(mdata->base + SPI_CMD_REG);
+	if (mdata->state == MTK_SPI_IDLE)
+		cmd |= 1 << SPI_CMD_ACT_OFFSET;
+	else
+		cmd |= 1 << SPI_CMD_RESUME_OFFSET;
+	writel(cmd, mdata->base + SPI_CMD_REG);
+}
+
+static int mtk_spi_get_mult_delta(int xfer_len)
+{
+	int mult_delta;
+
+	if (xfer_len > MTK_SPI_PACKET_SIZE)
+		mult_delta = xfer_len % MTK_SPI_PACKET_SIZE;
+	else
+		mult_delta = 0;
+
+	return mult_delta;
+}
+
+static void mtk_spi_update_mdata_len(struct spi_master *master)
+{
+	int mult_delta;
+	struct mtk_spi *mdata = spi_master_get_devdata(master);
+
+	if (mdata->tx_sgl_len && mdata->rx_sgl_len) {
+		if (mdata->tx_sgl_len > mdata->rx_sgl_len) {
+			mult_delta = mtk_spi_get_mult_delta(mdata->rx_sgl_len);
+			mdata->xfer_len = mdata->rx_sgl_len - mult_delta;
+			mdata->rx_sgl_len = mult_delta;
+			mdata->tx_sgl_len -= mdata->xfer_len;
+		} else {
+			mult_delta = mtk_spi_get_mult_delta(mdata->tx_sgl_len);
+			mdata->xfer_len = mdata->tx_sgl_len - mult_delta;
+			mdata->tx_sgl_len = mult_delta;
+			mdata->rx_sgl_len -= mdata->xfer_len;
+		}
+	} else if (mdata->tx_sgl_len) {
+		mult_delta = mtk_spi_get_mult_delta(mdata->tx_sgl_len);
+		mdata->xfer_len = mdata->tx_sgl_len - mult_delta;
+		mdata->tx_sgl_len = mult_delta;
+	} else if (mdata->rx_sgl_len) {
+		mult_delta = mtk_spi_get_mult_delta(mdata->rx_sgl_len);
+		mdata->xfer_len = mdata->rx_sgl_len - mult_delta;
+		mdata->rx_sgl_len = mult_delta;
+	}
+}
+
+static void mtk_spi_setup_dma_addr(struct spi_master *master,
+				   struct spi_transfer *xfer)
+{
+	struct mtk_spi *mdata = spi_master_get_devdata(master);
+
+	if (mdata->tx_sgl)
+		writel(cpu_to_le32(xfer->tx_dma), mdata->base + SPI_TX_SRC_REG);
+	if (mdata->rx_sgl)
+		writel(cpu_to_le32(xfer->rx_dma), mdata->base + SPI_RX_DST_REG);
+}
+
+static int mtk_spi_fifo_transfer(struct spi_master *master,
+				 struct spi_device *spi,
+				 struct spi_transfer *xfer)
+{
+	int cnt, i;
+	struct mtk_spi *mdata = spi_master_get_devdata(master);
+
+	mdata->cur_transfer = xfer;
+	mdata->xfer_len = xfer->len;
+	mtk_spi_prepare_transfer(master, xfer);
+	mtk_spi_setup_packet(master);
+
+	if (xfer->len % 4)
+		cnt = xfer->len / 4 + 1;
+	else
+		cnt = xfer->len / 4;
+
+	for (i = 0; i < cnt; i++)
+		writel(*((u32 *)xfer->tx_buf + i),
+		       mdata->base + SPI_TX_DATA_REG);
+
+	mtk_spi_enable_transfer(master);
+
+	return 1;
+}
+
+static int mtk_spi_dma_transfer(struct spi_master *master,
+				struct spi_device *spi,
+				struct spi_transfer *xfer)
+{
+	int cmd;
+	struct mtk_spi *mdata = spi_master_get_devdata(master);
+
+	mdata->tx_sgl = NULL;
+	mdata->rx_sgl = NULL;
+	mdata->tx_sgl_len = 0;
+	mdata->rx_sgl_len = 0;
+	mdata->cur_transfer = xfer;
+
+	mtk_spi_prepare_transfer(master, xfer);
+
+	cmd = readl(mdata->base + SPI_CMD_REG);
+	if (xfer->tx_buf)
+		cmd |= SPI_CMD_TX_DMA;
+	if (xfer->rx_buf)
+		cmd |= SPI_CMD_RX_DMA;
+	writel(cmd, mdata->base + SPI_CMD_REG);
+
+	if (xfer->tx_buf)
+		mdata->tx_sgl = xfer->tx_sg.sgl;
+	if (xfer->rx_buf)
+		mdata->rx_sgl = xfer->rx_sg.sgl;
+
+	if (mdata->tx_sgl) {
+		xfer->tx_dma = sg_dma_address(mdata->tx_sgl);
+		mdata->tx_sgl_len = sg_dma_len(mdata->tx_sgl);
+	}
+	if (mdata->rx_sgl) {
+		xfer->rx_dma = sg_dma_address(mdata->rx_sgl);
+		mdata->rx_sgl_len = sg_dma_len(mdata->rx_sgl);
+	}
+
+	mtk_spi_update_mdata_len(master);
+	mtk_spi_setup_packet(master);
+	mtk_spi_setup_dma_addr(master, xfer);
+	mtk_spi_enable_transfer(master);
+
+	return 1;
+}
+
+static int mtk_spi_transfer_one(struct spi_master *master,
+				struct spi_device *spi,
+				struct spi_transfer *xfer)
+{
+	if (master->can_dma(master, spi, xfer))
+		return mtk_spi_dma_transfer(master, spi, xfer);
+	else
+		return mtk_spi_fifo_transfer(master, spi, xfer);
+}
+
+static bool mtk_spi_can_dma(struct spi_master *master,
+			    struct spi_device *spi,
+			    struct spi_transfer *xfer)
+{
+	return xfer->len > MTK_SPI_MAX_FIFO_SIZE;
+}
+
+static irqreturn_t mtk_spi_interrupt(int irq, void *dev_id)
+{
+	u32 cmd, reg_val, i;
+	struct spi_master *master = dev_id;
+	struct mtk_spi *mdata = spi_master_get_devdata(master);
+	struct spi_transfer *trans = mdata->cur_transfer;
+
+	reg_val = readl(mdata->base + SPI_STATUS0_REG);
+	if (reg_val & 0x2)
+		mdata->state = MTK_SPI_PAUSED;
+	else
+		mdata->state = MTK_SPI_IDLE;
+
+	if (!master->can_dma(master, master->cur_msg->spi, trans)) {
+		/* xfer len is not N*4 bytes every time in a transfer,
+		 * but SPI_RX_DATA_REG must reads 4 bytes once,
+		 * so rx buffer byte by byte.
+		 */
+		if (trans->rx_buf) {
+			for (i = 0; i < mdata->xfer_len; i++) {
+				if (i % 4 == 0)
+					reg_val =
+					readl(mdata->base + SPI_RX_DATA_REG);
+				*((u8 *)(trans->rx_buf + i)) =
+					(reg_val >> ((i % 4) * 8)) & 0xff;
+			}
+		}
+		spi_finalize_current_transfer(master);
+		return IRQ_HANDLED;
+	}
+
+	if (mdata->tx_sgl)
+		trans->tx_dma += mdata->xfer_len;
+	if (mdata->rx_sgl)
+		trans->rx_dma += mdata->xfer_len;
+
+	if (mdata->tx_sgl && (mdata->tx_sgl_len == 0)) {
+		mdata->tx_sgl = sg_next(mdata->tx_sgl);
+		if (mdata->tx_sgl) {
+			trans->tx_dma = sg_dma_address(mdata->tx_sgl);
+			mdata->tx_sgl_len = sg_dma_len(mdata->tx_sgl);
+		}
+	}
+	if (mdata->rx_sgl && (mdata->rx_sgl_len == 0)) {
+		mdata->rx_sgl = sg_next(mdata->rx_sgl);
+		if (mdata->rx_sgl) {
+			trans->rx_dma = sg_dma_address(mdata->rx_sgl);
+			mdata->rx_sgl_len = sg_dma_len(mdata->rx_sgl);
+		}
+	}
+
+	if (!mdata->tx_sgl && !mdata->rx_sgl) {
+		/* spi disable dma */
+		cmd = readl(mdata->base + SPI_CMD_REG);
+		cmd &= ~SPI_CMD_TX_DMA;
+		cmd &= ~SPI_CMD_RX_DMA;
+		writel(cmd, mdata->base + SPI_CMD_REG);
+
+		spi_finalize_current_transfer(master);
+		return IRQ_HANDLED;
+	}
+
+	mtk_spi_update_mdata_len(master);
+	mtk_spi_setup_packet(master);
+	mtk_spi_setup_dma_addr(master, trans);
+	mtk_spi_enable_transfer(master);
+
+	return IRQ_HANDLED;
+}
+
+static int mtk_spi_probe(struct platform_device *pdev)
+{
+	struct spi_master *master;
+	struct mtk_spi *mdata;
+	const struct of_device_id *of_id;
+	struct resource *res;
+	int	irq, ret;
+
+	master = spi_alloc_master(&pdev->dev, sizeof(*mdata));
+	if (!master) {
+		dev_err(&pdev->dev, "failed to alloc spi master\n");
+		return -ENOMEM;
+	}
+
+	master->auto_runtime_pm = true;
+	master->dev.of_node = pdev->dev.of_node;
+	master->mode_bits = SPI_CPOL | SPI_CPHA;
+
+	master->set_cs = mtk_spi_set_cs;
+	master->prepare_transfer_hardware = mtk_spi_prepare_hardware;
+	master->unprepare_transfer_hardware = mtk_spi_unprepare_hardware;
+	master->prepare_message = mtk_spi_prepare_message;
+	master->transfer_one = mtk_spi_transfer_one;
+	master->can_dma = mtk_spi_can_dma;
+
+	of_id = of_match_node(mtk_spi_of_match, pdev->dev.of_node);
+	if (!of_id) {
+		dev_err(&pdev->dev, "failed to probe of_node\n");
+		ret = -EINVAL;
+		goto err_put_master;
+	}
+
+	mdata = spi_master_get_devdata(master);
+	mdata->dev_comp = of_id->data;
+	if (mdata->dev_comp->must_tx)
+		master->flags = SPI_MASTER_MUST_TX;
+
+	if (mdata->dev_comp->need_pad_sel) {
+		ret = of_property_read_u32(pdev->dev.of_node,
+					   "mediatek,pad-select",
+					   &mdata->pad_sel);
+		if (ret) {
+			dev_err(&pdev->dev, "failed to read pad select: %d\n",
+				ret);
+			goto err_put_master;
+		}
+
+		if (mdata->pad_sel > MT8173_SPI_MAX_PAD_SEL) {
+			dev_err(&pdev->dev, "wrong pad-select: %u\n",
+				mdata->pad_sel);
+			ret = -EINVAL;
+			goto err_put_master;
+		}
+	}
+
+	platform_set_drvdata(pdev, master);
+
+	res = platform_get_resource(pdev, IORESOURCE_MEM, 0);
+	if (!res) {
+		ret = -ENODEV;
+		dev_err(&pdev->dev, "failed to determine base address\n");
+		goto err_put_master;
+	}
+
+	mdata->base = devm_ioremap_resource(&pdev->dev, res);
+	if (IS_ERR(mdata->base)) {
+		ret = PTR_ERR(mdata->base);
+		goto err_put_master;
+	}
+
+	irq = platform_get_irq(pdev, 0);
+	if (irq < 0) {
+		dev_err(&pdev->dev, "failed to get irq (%d)\n", irq);
+		ret = irq;
+		goto err_put_master;
+	}
+
+	if (!pdev->dev.dma_mask)
+		pdev->dev.dma_mask = &pdev->dev.coherent_dma_mask;
+
+	ret = devm_request_irq(&pdev->dev, irq, mtk_spi_interrupt,
+			       IRQF_TRIGGER_NONE, dev_name(&pdev->dev), master);
+	if (ret) {
+		dev_err(&pdev->dev, "failed to register irq (%d)\n", ret);
+		goto err_put_master;
+	}
+
+	mdata->spi_clk = devm_clk_get(&pdev->dev, "spi-clk");
+	if (IS_ERR(mdata->spi_clk)) {
+		ret = PTR_ERR(mdata->spi_clk);
+		dev_err(&pdev->dev, "failed to get spi-clk: %d\n", ret);
+		goto err_put_master;
+	}
+
+	mdata->parent_clk = devm_clk_get(&pdev->dev, "parent-clk");
+	if (IS_ERR(mdata->parent_clk)) {
+		ret = PTR_ERR(mdata->parent_clk);
+		dev_err(&pdev->dev, "failed to get parent-clk: %d\n", ret);
+		goto err_put_master;
+	}
+
+	ret = clk_prepare_enable(mdata->spi_clk);
+	if (ret < 0) {
+		dev_err(&pdev->dev, "failed to enable spi_clk (%d)\n", ret);
+		goto err_put_master;
+	}
+
+	ret = clk_set_parent(mdata->spi_clk, mdata->parent_clk);
+	if (ret < 0) {
+		dev_err(&pdev->dev, "failed to clk_set_parent (%d)\n", ret);
+		goto err_disable_clk;
+	}
+
+	clk_disable_unprepare(mdata->spi_clk);
+
+	pm_runtime_enable(&pdev->dev);
+
+	ret = devm_spi_register_master(&pdev->dev, master);
+	if (ret) {
+		dev_err(&pdev->dev, "failed to register master (%d)\n", ret);
+		goto err_put_master;
+	}
+
+	return 0;
+
+err_disable_clk:
+	clk_disable_unprepare(mdata->spi_clk);
+err_put_master:
+	spi_master_put(master);
+
+	return ret;
+}
+
+static int mtk_spi_remove(struct platform_device *pdev)
+{
+	struct spi_master *master = platform_get_drvdata(pdev);
+	struct mtk_spi *mdata = spi_master_get_devdata(master);
+
+	pm_runtime_disable(&pdev->dev);
+
+	mtk_spi_reset(mdata);
+	clk_disable_unprepare(mdata->spi_clk);
+	spi_master_put(master);
+
+	return 0;
+}
+
+#ifdef CONFIG_PM_SLEEP
+static int mtk_spi_suspend(struct device *dev)
+{
+	int ret;
+	struct spi_master *master = dev_get_drvdata(dev);
+	struct mtk_spi *mdata = spi_master_get_devdata(master);
+
+	ret = spi_master_suspend(master);
+	if (ret)
+		return ret;
+
+	if (!pm_runtime_suspended(dev))
+		clk_disable_unprepare(mdata->spi_clk);
+
+	return ret;
+}
+
+static int mtk_spi_resume(struct device *dev)
+{
+	int ret;
+	struct spi_master *master = dev_get_drvdata(dev);
+	struct mtk_spi *mdata = spi_master_get_devdata(master);
+
+	if (!pm_runtime_suspended(dev)) {
+		ret = clk_prepare_enable(mdata->spi_clk);
+		if (ret < 0)
+			return ret;
+	}
+
+	ret = spi_master_resume(master);
+	if (ret < 0)
+		clk_disable_unprepare(mdata->spi_clk);
+
+	return ret;
+}
+#endif /* CONFIG_PM_SLEEP */
+
+#ifdef CONFIG_PM
+static int mtk_spi_runtime_suspend(struct device *dev)
+{
+	struct spi_master *master = dev_get_drvdata(dev);
+	struct mtk_spi *mdata = spi_master_get_devdata(master);
+
+	clk_disable_unprepare(mdata->spi_clk);
+
+	return 0;
+}
+
+static int mtk_spi_runtime_resume(struct device *dev)
+{
+	struct spi_master *master = dev_get_drvdata(dev);
+	struct mtk_spi *mdata = spi_master_get_devdata(master);
+
+	return clk_prepare_enable(mdata->spi_clk);
+}
+#endif /* CONFIG_PM */
+
+static const struct dev_pm_ops mtk_spi_pm = {
+	SET_SYSTEM_SLEEP_PM_OPS(mtk_spi_suspend, mtk_spi_resume)
+	SET_RUNTIME_PM_OPS(mtk_spi_runtime_suspend,
+			   mtk_spi_runtime_resume, NULL)
+};
+
+struct platform_driver mtk_spi_driver = {
+	.driver = {
+		.name = "mtk-spi",
+		.pm	= &mtk_spi_pm,
+		.of_match_table = mtk_spi_of_match,
+	},
+	.probe = mtk_spi_probe,
+	.remove = mtk_spi_remove,
+};
+
+module_platform_driver(mtk_spi_driver);
+
+MODULE_DESCRIPTION("MTK SPI Controller driver");
+MODULE_AUTHOR("Leilk Liu <leilk.liu at mediatek.com>");
+MODULE_LICENSE("GPL v2");
+MODULE_ALIAS("platform: mtk_spi");
diff --git a/include/linux/platform_data/spi-mt65xx.h b/include/linux/platform_data/spi-mt65xx.h
new file mode 100644
index 0000000..7512255
--- /dev/null
+++ b/include/linux/platform_data/spi-mt65xx.h
@@ -0,0 +1,22 @@
+/*
+ *  MTK SPI bus driver definitions
+ *
+ * Copyright (c) 2015 MediaTek Inc.
+ * Author: Leilk Liu <leilk.liu at 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.
+ */
+
+#ifndef ____LINUX_PLATFORM_DATA_SPI_MTK_H
+#define ____LINUX_PLATFORM_DATA_SPI_MTK_H
+
+/* Board specific platform_data */
+struct mtk_chip_config {
+	u32 tx_mlsb;
+	u32 rx_mlsb;
+	u32 tx_endian;
+	u32 rx_endian;
+};
+#endif
-- 
1.8.1.1.dirty



From henryc.chen at mediatek.com  Fri Aug  7 00:25:59 2015
From: henryc.chen at mediatek.com (Henry Chen)
Date: Fri, 7 Aug 2015 15:25:59 +0800
Subject: [PATCH v2] mfd: mt6397: Implement wake handler and suspend/resume for
 mt6397-core.c
Message-ID: <1438932359-8476-1-git-send-email-henryc.chen@mediatek.com>

Implement .irq_set_wake() to get who is wakeup source and setup on suspend/reumse. Enbale
mt6393_irq as wake up source properly to pinctrl by enable_irq_wake()/enable_irq_wake().

Signed-off-by: Henry Chen <henryc.chen at mediatek.com>
---
Chandes since v1:
Used enable_irq_wake()/disable_irq_wake to handle irq wakeup source.

 drivers/mfd/mt6397-core.c       | 50 +++++++++++++++++++++++++++++++++++++++++
 include/linux/mfd/mt6397/core.h |  1 +
 2 files changed, 51 insertions(+)

diff --git a/drivers/mfd/mt6397-core.c b/drivers/mfd/mt6397-core.c
index 03929a6..49daf1a 100644
--- a/drivers/mfd/mt6397-core.c
+++ b/drivers/mfd/mt6397-core.c
@@ -93,12 +93,31 @@ static void mt6397_irq_enable(struct irq_data *data)
 	mt6397->irq_masks_cur[reg] |= BIT(shift);
 }
 
+#ifdef CONFIG_PM_SLEEP
+static int mt6397_irq_set_wake(struct irq_data *irq_data, unsigned int on)
+{
+	struct mt6397_chip *mt6397 = irq_data_get_irq_chip_data(irq_data);
+	int shift = irq_data->hwirq & 0xf;
+	int reg = irq_data->hwirq >> 4;
+
+	if (on)
+		mt6397->wake_mask[reg] |= BIT(shift);
+	else
+		mt6397->wake_mask[reg] &= ~BIT(shift);
+
+	return 0;
+}
+#else
+#define mt6397_irq_set_wake NULL
+#endif
+
 static struct irq_chip mt6397_irq_chip = {
 	.name = "mt6397-irq",
 	.irq_bus_lock = mt6397_irq_lock,
 	.irq_bus_sync_unlock = mt6397_irq_sync_unlock,
 	.irq_enable = mt6397_irq_enable,
 	.irq_disable = mt6397_irq_disable,
+	.irq_set_wake = mt6397_irq_set_wake,
 };
 
 static void mt6397_irq_handle_reg(struct mt6397_chip *mt6397, int reg,
@@ -142,6 +161,7 @@ static int mt6397_irq_domain_map(struct irq_domain *d, unsigned int irq,
 	irq_set_chip_data(irq, mt6397);
 	irq_set_chip_and_handler(irq, &mt6397_irq_chip, handle_level_irq);
 	irq_set_nested_thread(irq, 1);
+
 #ifdef CONFIG_ARM
 	set_irq_flags(irq, IRQF_VALID);
 #else
@@ -183,6 +203,35 @@ static int mt6397_irq_init(struct mt6397_chip *mt6397)
 	return 0;
 }
 
+#ifdef CONFIG_PM_SLEEP
+static int mt6397_irq_suspend(struct device *dev)
+{
+	struct mt6397_chip *chip = dev_get_drvdata(dev);
+
+	regmap_write(chip->regmap, MT6397_INT_CON0, chip->wake_mask[0]);
+	regmap_write(chip->regmap, MT6397_INT_CON1, chip->wake_mask[1]);
+
+	enable_irq_wake(chip->irq);
+
+	return 0;
+}
+
+static int mt6397_irq_resume(struct device *dev)
+{
+	struct mt6397_chip *chip = dev_get_drvdata(dev);
+
+	regmap_write(chip->regmap, MT6397_INT_CON0, chip->irq_masks_cur[0]);
+	regmap_write(chip->regmap, MT6397_INT_CON1, chip->irq_masks_cur[1]);
+
+	disable_irq_wake(chip->irq);
+
+	return 0;
+}
+#endif
+
+static SIMPLE_DEV_PM_OPS(mt6397_pm_ops, mt6397_irq_suspend,
+			mt6397_irq_resume);
+
 static int mt6397_probe(struct platform_device *pdev)
 {
 	int ret;
@@ -237,6 +286,7 @@ static struct platform_driver mt6397_driver = {
 	.driver = {
 		.name = "mt6397",
 		.of_match_table = of_match_ptr(mt6397_of_match),
+		.pm = &mt6397_pm_ops,
 	},
 };
 
diff --git a/include/linux/mfd/mt6397/core.h b/include/linux/mfd/mt6397/core.h
index cf5265b..45b8e8a 100644
--- a/include/linux/mfd/mt6397/core.h
+++ b/include/linux/mfd/mt6397/core.h
@@ -57,6 +57,7 @@ struct mt6397_chip {
 	int irq;
 	struct irq_domain *irq_domain;
 	struct mutex irqlock;
+	u16 wake_mask[2];
 	u16 irq_masks_cur[2];
 	u16 irq_masks_cache[2];
 };
-- 
1.8.1.1.dirty



From hramrach at gmail.com  Fri Aug  7 00:38:48 2015
From: hramrach at gmail.com (Michal Suchanek)
Date: Fri, 7 Aug 2015 09:38:48 +0200
Subject: [RFC PATCH 1/5] spi: introduce flag for memory mapped read
In-Reply-To: <20150806213340.GK7576@n2100.arm.linux.org.uk>
References: <20150805115013.GJ20873@sirena.org.uk>
 <CAOMqctQXwcHyiWBwtugSDSE_k65qrNfrwnhjQMDJkLoJMmGzUw@mail.gmail.com>
 <20150805124412.GN20873@sirena.org.uk>
 <CAOMqctS9Y5FxpUCCJew6+cnjH5iTvbzkH3g-8yrXs4OuS2pSGA@mail.gmail.com>
 <20150806090202.GO20873@sirena.org.uk>
 <CAOMqctQZRZ4zG_yYy=CeX3DX4NVNWN1COP4Q-2YvMun9xYOA7g@mail.gmail.com>
 <20150806102225.GI7576@n2100.arm.linux.org.uk> <55C35233.2000105@ti.com>
 <20150806135129.GJ7576@n2100.arm.linux.org.uk>
 <CAMuHMdWWDwZ=ziGQXFCnOX8pErXpsEi533J73_Hh=sEqq4hR6Q@mail.gmail.com>
 <20150806213340.GK7576@n2100.arm.linux.org.uk>
Message-ID: <CAOMqctRBW230fA4AEhK7MyqkZY==6ENNNHE-LVm7-mHKA_VzRw@mail.gmail.com>

On 6 August 2015 at 23:33, Russell King - ARM Linux
<linux at arm.linux.org.uk> wrote:
> On Thu, Aug 06, 2015 at 06:14:00PM +0200, Geert Uytterhoeven wrote:
>> On Thu, Aug 6, 2015 at 3:51 PM, Russell King - ARM Linux
>> <linux at arm.linux.org.uk> wrote:
>> > On Thu, Aug 06, 2015 at 05:55:23PM +0530, Vignesh R wrote:
>> >> On the whole following are my requirements:
>> >> 1. to be able to communicate with non -flash SPI devices via config port
>> >> ( this functionality is supported by current driver, I dont want to
>> >> break it). Or pump any spi_message on to SPI bus directly.
>> >> 2. take advantage of memory mapped port in order to increase read
>> >> throughput( and use dma in future) when the slave is a m25p80 type flash.
>> >> 3. handle m25p80 as well as other slave on multiple chipselects.
>> >>
>> >> I just need to know whether the user that requested the transfer is
>> >> m25p80 driver. If yes, ti-qspi driver can take advantage of memory
>> >> mapped interface, else just use config port to access SPI bus directly.
>> >
>> > The problem with this approach is that it's an abomination.  It's adding
>> > a SPI-user specific hack which is detected by a specific driver.  That's
>> > really not sane - what happens when we have lots of these kinds of "I'm
>> > an X SPI-user" with drivers detecting that?  It's not maintainable in the
>> > long term.
>> >
>> > Yes, your requirements _today_ seem simple and easy, but you're only
>> > thinking about today, not tomorrow when you've moved on and someone else
>> > has to maintain the mess left behind (or delete it from mainline because
>> > they're sick of dealing with a hack.)
>> >
>> >> The spi_message that is received in transfer_one_message() is too
>> >> generic to imply the slave device that is on the other side of the wire.
>> >> IMO, the read command does not imply that the slave is m25p80 flash
>> >> (besides the read opcodes vary across vendors of m25p80 and across modes).
>> >
>> > I can see both sides of the argument.
>> >
>> > Mark is saying: if the SPI driver detects that the message to be transmitted
>> > is a read command followed by the appropriate number of dummy bytes, and
>> > then the data being read _and_ it's using quad-mode access, and the hardware
>> > generates _exactly_ that in hardware using the memory mapped mode, there is
>> > no reason _not_ to use the hardware to achieve that SPI transaction.  The
>> > bus activity will be identical to what happens when the SPI controller is
>> > used manually to achieve that bus sequence.
>> >
>> > You're saying: but the documentation says you can't use it for anything
>> > except m25p80.  If you look at 24.5.4.1.2, it tells you what the SFI
>> > generates on the bus, which is:
>> >
>> > 1. CS active
>> > 2. Read command byte sent
>> > 3. 1-4 address bytes sent
>> > 4. 0-3 dummy bytes sent
>> > 5. data bytes read from bus
>> > 6. CS inactive
>> >
>> > So, Mark's point is "if we can detect a transaction which fits _that_
>> > bus activity, there's no reason not to use this acceleration for the
>> > transaction."
>> >
>> > What you're failing to counter with is: we don't have enough information
>> > in the SPI driver to know how many dummy bytes there are between the
>> > address bytes and the data read from the bus.
>>
>> Irrespective of the dummy bytes.
>> What if the spi device is not a FLASH ROM, but some other device,
>> which receives a data packet that accidentally looks like an m25p80 READ
>> command?
>
> Well, for the most part it looks like it should still work, but there
> could be a gotcha, but first, let's get rid of a myth there.
>
> The QSPI is _not_ specific to the M25P80.  The manual says nothing
> about being specific to that device.  What it says is that it's for
> SPI NOR memory.  It will work with bus widths of 1, 2 or 4 data lines,
> so it probably works with non-M25P80 SPI NOR devices too - and the fact
> that the read and write commands are completely programmable suggests
> that using it with SPI NOR devices which do not use the M25P80 read
> command value is intended.
>
...
>
> That much is good, but now is the problem - how does the SFI know that
> we're going to require to read 32 bytes?  I think the answer to that
> is that it doesn't know, so it probably just reads the number of bytes
> which the access on the SoC bus is asking for, which makes it
> indeterminant from a software point of view to control how many bytes
> will be read without provoking another "send 0x01, next address, dummy
> byte" sequence.
>
> So, I'm now on the side of not parsing commands in the SPI driver, and
> back on the idea that this needs to be handled in some other manner
> which doesn't involve polluting the SPI core with flag-hacks.

OK, so we can agree that using this hardware acceleration for any kind
of transfer indiscriminately is not a very good idea.

Now since the description is clearer it's obvious that ti-qspi cannot
work fully mmapped as fsl-qspi does because the setup has to be done
over normal spi access and using non-m25p80 devices on the same bus is
a requirement.

The place where it is known if a transfer can use the mmap access is m25p80.c

So my suggestion is

 - add a new method for spi master that gets the read opcode, dummy
length, address, address length, buffer, buffer length and performs
read from the flash memory in a hardware-specific way

- add a check in m25p80.c that the master supports this feature and if
so use it (eg check that the method is non-null)

Presumably if some new SPI controllers with similar feature are
supported in the future they can use the same inteface because you
pass on everything the m25p80 read knows.

Thanks

Michal


From lftan at altera.com  Fri Aug  7 00:42:57 2015
From: lftan at altera.com (Ley Foon Tan)
Date: Fri, 7 Aug 2015 15:42:57 +0800
Subject: [PATCH v3 0/5] Altera PCIe host controller driver with MSI support
Message-ID: <1438933382-2936-1-git-send-email-lftan@altera.com>

This is the 3rd version of patch set to add support for Altera PCIe host
controller with MSI feature on Altera FPGA device families. This patchset
mainly resolve comments from Marc Zyngier in v2.

It is based on patch series from Marc Zyngier "Per-device MSI domain &
platform MSI" [1] to get rid of struct msi_controller.

[1]: https://lkml.org/lkml/2015/7/23/172

v2->v3 changes:
- pci: host: move depends on PCI_MSI_IRQ_DOMAIN to PCIE_ALTERA_MSI in Kconfig
- pcie-altera: change to use find_first_bit in isr
- pcie-altera: change to use chained irq handler
- pcie-altera: rename hwirq to irq
- pcie-altera: rename irq to virq
- pcie-altera-msi: update isr handling
- pcie-altera-msi: change u64 to phys_addr_t
- pcie-altera-msi: fix find_first_zero_bit error handle
- pcie-altera-msi: change altera_msi_probe to static function
- pcie-altera-msi: remove .owner
- pcie-altera-msi: remove MODULE_DEVICE_TABLE
- pcie-altera-msi: move INTMASK to _alloc()
- change from clear_bit to __clear_bit
- change to use irq_set_chained_handler_and_data
- fix coding style

History:
-------
[v1]: https://lkml.org/lkml/2015/7/28/395
[v2]: https://lkml.org/lkml/2015/7/31/267


Ley Foon Tan (5):
  arm: add msi.h to Kbuild
  pci:host: Add Altera PCIe host controller driver
  pci: altera: Add Altera PCIe MSI driver
  Documentation: dt-bindings: pci: altera pcie device tree binding
  MAINTAINERS: Add Altera PCIe and MSI drivers maintainer

 .../devicetree/bindings/pci/altera-pcie-msi.txt    |  27 ++
 .../devicetree/bindings/pci/altera-pcie.txt        |  49 ++
 MAINTAINERS                                        |  16 +
 arch/arm/include/asm/Kbuild                        |   1 +
 drivers/pci/host/Kconfig                           |  15 +
 drivers/pci/host/Makefile                          |   2 +
 drivers/pci/host/pcie-altera-msi.c                 | 309 ++++++++++++
 drivers/pci/host/pcie-altera.c                     | 532 +++++++++++++++++++++
 8 files changed, 951 insertions(+)
 create mode 100644 Documentation/devicetree/bindings/pci/altera-pcie-msi.txt
 create mode 100644 Documentation/devicetree/bindings/pci/altera-pcie.txt
 create mode 100644 drivers/pci/host/pcie-altera-msi.c
 create mode 100644 drivers/pci/host/pcie-altera.c

-- 
1.8.2.1



From lftan at altera.com  Fri Aug  7 00:42:58 2015
From: lftan at altera.com (Ley Foon Tan)
Date: Fri, 7 Aug 2015 15:42:58 +0800
Subject: [PATCH v3 1/5] arm: add msi.h to Kbuild
In-Reply-To: <1438933382-2936-1-git-send-email-lftan@altera.com>
References: <1438933382-2936-1-git-send-email-lftan@altera.com>
Message-ID: <1438933382-2936-2-git-send-email-lftan@altera.com>

Include asm-generic/msi.h to support CONFIG_GENERIC_MSI_IRQ_DOMAIN.
This to fix compilation error:
"include/linux/msi.h:123:21: fatal error: asm/msi.h:
No such file or directory"

Signed-off-by: Ley Foon Tan <lftan at altera.com>
---
 arch/arm/include/asm/Kbuild | 1 +
 1 file changed, 1 insertion(+)

diff --git a/arch/arm/include/asm/Kbuild b/arch/arm/include/asm/Kbuild
index 83c5019..ddc2761 100644
--- a/arch/arm/include/asm/Kbuild
+++ b/arch/arm/include/asm/Kbuild
@@ -14,6 +14,7 @@ generic-y += local.h
 generic-y += local64.h
 generic-y += mcs_spinlock.h
 generic-y += msgbuf.h
+generic-y += msi.h
 generic-y += param.h
 generic-y += parport.h
 generic-y += poll.h
-- 
1.8.2.1



From lftan at altera.com  Fri Aug  7 00:42:59 2015
From: lftan at altera.com (Ley Foon Tan)
Date: Fri, 7 Aug 2015 15:42:59 +0800
Subject: [PATCH v3 2/5] pci:host: Add Altera PCIe host controller driver
In-Reply-To: <1438933382-2936-1-git-send-email-lftan@altera.com>
References: <1438933382-2936-1-git-send-email-lftan@altera.com>
Message-ID: <1438933382-2936-3-git-send-email-lftan@altera.com>

This patch adds the Altera PCIe host controller driver.

Signed-off-by: Ley Foon Tan <lftan at altera.com>
---
 drivers/pci/host/Kconfig       |   7 +
 drivers/pci/host/Makefile      |   1 +
 drivers/pci/host/pcie-altera.c | 532 +++++++++++++++++++++++++++++++++++++++++
 3 files changed, 540 insertions(+)
 create mode 100644 drivers/pci/host/pcie-altera.c

diff --git a/drivers/pci/host/Kconfig b/drivers/pci/host/Kconfig
index 675c2d1..4b4754a 100644
--- a/drivers/pci/host/Kconfig
+++ b/drivers/pci/host/Kconfig
@@ -145,4 +145,11 @@ config PCIE_IPROC_BCMA
 	  Say Y here if you want to use the Broadcom iProc PCIe controller
 	  through the BCMA bus interface
 
+config PCIE_ALTERA
+	tristate "Altera PCIe controller"
+	depends on ARCH_SOCFPGA
+	help
+	  Say Y here if you want to enable PCIe controller support for Altera
+	  SoCFPGA family of SoCs.
+
 endmenu
diff --git a/drivers/pci/host/Makefile b/drivers/pci/host/Makefile
index 140d66f..6954f76 100644
--- a/drivers/pci/host/Makefile
+++ b/drivers/pci/host/Makefile
@@ -17,3 +17,4 @@ obj-$(CONFIG_PCI_VERSATILE) += pci-versatile.o
 obj-$(CONFIG_PCIE_IPROC) += pcie-iproc.o
 obj-$(CONFIG_PCIE_IPROC_PLATFORM) += pcie-iproc-platform.o
 obj-$(CONFIG_PCIE_IPROC_BCMA) += pcie-iproc-bcma.o
+obj-$(CONFIG_PCIE_ALTERA) += pcie-altera.o
diff --git a/drivers/pci/host/pcie-altera.c b/drivers/pci/host/pcie-altera.c
new file mode 100644
index 0000000..37bed81
--- /dev/null
+++ b/drivers/pci/host/pcie-altera.c
@@ -0,0 +1,532 @@
+/*
+ * Copyright Altera Corporation (C) 2013-2015. All rights reserved
+ *
+ * This program is free software; you can redistribute it and/or modify it
+ * under the terms and conditions of the GNU General Public License,
+ * version 2, as published by the Free Software Foundation.
+ *
+ * This program is distributed in the hope 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.
+ *
+ * You should have received a copy of the GNU General Public License along with
+ * this program.  If not, see <http://www.gnu.org/licenses/>.
+ */
+#include <linux/interrupt.h>
+#include <linux/irqchip/chained_irq.h>
+#include <linux/module.h>
+#include <linux/of_address.h>
+#include <linux/of_irq.h>
+#include <linux/of_pci.h>
+#include <linux/pci.h>
+#include <linux/platform_device.h>
+#include <linux/slab.h>
+
+#define A2P_ADDR_MAP_LO0		0x1000
+#define A2P_ADDR_MAP_HI0		0x1004
+#define RP_TX_REG0			0x2000
+#define RP_TX_REG1			0x2004
+#define RP_TX_CNTRL			0x2008
+#define RP_TX_EOP			0x2
+#define RP_TX_SOP			0x1
+#define RP_RXCPL_STATUS		0x2010
+#define RP_RXCPL_EOP			0x2
+#define RP_RXCPL_SOP			0x1
+#define RP_RXCPL_REG0			0x2014
+#define RP_RXCPL_REG1			0x2018
+#define P2A_INT_STATUS			0x3060
+#define P2A_INT_STS_ALL			0xF
+#define P2A_INT_ENABLE			0x3070
+#define P2A_INT_ENA_ALL			0xF
+#define RP_LTSSM			0x3C64
+#define LTSSM_L0			0xF
+
+/* TLP configuration type 0 and 1 */
+#define TLP_FMTTYPE_CFGRD0		0x04	/* Configuration Read Type 0 */
+#define TLP_FMTTYPE_CFGWR0		0x44	/* Configuration Write Type 0 */
+#define TLP_FMTTYPE_CFGRD1		0x05	/* Configuration Read Type 1 */
+#define TLP_FMTTYPE_CFGWR1		0x45	/* Configuration Write Type 1 */
+#define TLP_PAYLOAD_SIZE		0x01
+#define TLP_READ_TAG			0x1D
+#define TLP_WRITE_TAG			0x10
+#define TLP_CFG_DW0(fmttype)		(((fmttype) << 24) | TLP_PAYLOAD_SIZE)
+#define TLP_CFG_DW1(reqid, tag)		(((reqid) << 16) | (tag << 8) | 0xF)
+#define TLP_CFG_DW2(bus, devfn, offset)	\
+				(((bus) << 24) | ((devfn) << 16) | (offset))
+#define TLP_REQ_ID(bus, devfn)		(((bus) << 8) | (devfn))
+#define TLP_COMPL_STATUS(hdr)		(((hdr) & 0xE0) >> 13)
+#define TLP_HDR_SIZE			3
+#define TLP_LOOP			10
+
+#define INTX_NUM		4
+
+/* Address translation table entry size */
+#define ATT_ENTRY_SIZE		8
+
+#define DWORD_MASK		3
+
+struct altera_pcie {
+	struct platform_device	*pdev;
+	struct resource		*txs;
+	void __iomem		*cra_base;
+	int			irq;
+	u8			root_bus_nr;
+	struct irq_domain		*irq_domain;
+	struct resource		bus_range;
+	struct list_head		resources;
+};
+
+struct tlp_rp_regpair_t {
+	u32 ctrl;
+	u32 reg0;
+	u32 reg1;
+};
+
+static void altera_pcie_retrain(struct pci_dev *dev)
+{
+	u16 linkcap, linkstat;
+
+	/*
+	 * Set the retrain bit if the PCIe rootport support > 2.5GB/s, but
+	 * current speed is 2.5 GB/s.
+	 */
+	pcie_capability_read_word(dev, PCI_EXP_LNKCAP, &linkcap);
+
+	if ((linkcap & PCI_EXP_LNKCAP_SLS) <= PCI_EXP_LNKCAP_SLS_2_5GB)
+		return;
+
+	pcie_capability_read_word(dev, PCI_EXP_LNKSTA, &linkstat);
+	if ((linkstat & PCI_EXP_LNKSTA_CLS) == PCI_EXP_LNKSTA_CLS_2_5GB)
+		pcie_capability_set_word(dev, PCI_EXP_LNKCTL,
+					 PCI_EXP_LNKCTL_RL);
+}
+DECLARE_PCI_FIXUP_EARLY(PCI_ANY_ID, PCI_ANY_ID, altera_pcie_retrain);
+
+static inline void cra_writel(struct altera_pcie *pcie, u32 value, u32 reg)
+{
+	writel_relaxed(value, pcie->cra_base + reg);
+}
+
+static inline u32 cra_readl(struct altera_pcie *pcie, u32 reg)
+{
+	return readl_relaxed(pcie->cra_base + reg);
+}
+
+static void tlp_read_rx(struct altera_pcie *pcie,
+			struct tlp_rp_regpair_t *tlp_rp_regdata)
+{
+	tlp_rp_regdata->ctrl = cra_readl(pcie, RP_RXCPL_STATUS);
+	tlp_rp_regdata->reg0 = cra_readl(pcie, RP_RXCPL_REG0);
+	tlp_rp_regdata->reg1 = cra_readl(pcie, RP_RXCPL_REG1);
+}
+
+static void tlp_write_tx(struct altera_pcie *pcie,
+			 struct tlp_rp_regpair_t *tlp_rp_regdata)
+{
+	cra_writel(pcie, tlp_rp_regdata->reg0, RP_TX_REG0);
+	cra_writel(pcie, tlp_rp_regdata->reg1, RP_TX_REG1);
+	cra_writel(pcie, tlp_rp_regdata->ctrl, RP_TX_CNTRL);
+}
+
+static bool altera_pcie_link_is_up(struct altera_pcie *pcie)
+{
+	return !!(cra_readl(pcie, RP_LTSSM) & LTSSM_L0);
+}
+
+static bool altera_pcie_valid_config(struct altera_pcie *pcie,
+				     struct pci_bus *bus, int dev)
+{
+	/* If there is no link, then there is no device */
+	if (bus->number != pcie->root_bus_nr) {
+		if (!altera_pcie_link_is_up(pcie))
+			return false;
+	}
+
+	/* access only one slot on each root port */
+	if (bus->number == pcie->root_bus_nr && dev > 0)
+		return false;
+
+	/*
+	 * Do not read more than one device on the bus directly attached
+	 * to RC.
+	 */
+	if (bus->primary == pcie->root_bus_nr && dev > 0)
+		return false;
+
+	 return true;
+}
+
+static int tlp_read_packet(struct altera_pcie *pcie, u32 *value)
+{
+	u8 loop;
+	struct tlp_rp_regpair_t tlp_rp_regdata;
+
+	for (loop = TLP_LOOP; loop > 0; loop--) {
+		tlp_read_rx(pcie, &tlp_rp_regdata);
+		if (tlp_rp_regdata.ctrl & RP_RXCPL_EOP) {
+			if (value)
+				*value = tlp_rp_regdata.reg0;
+			return PCIBIOS_SUCCESSFUL;
+		}
+	}
+
+	return -ENOENT;
+}
+
+static void tlp_write_packet(struct altera_pcie *pcie, u32 *headers, u32 data)
+{
+	struct tlp_rp_regpair_t tlp_rp_regdata;
+
+	tlp_rp_regdata.reg0 = headers[0];
+	tlp_rp_regdata.reg1 = headers[1];
+	tlp_rp_regdata.ctrl = RP_TX_SOP;
+	tlp_write_tx(pcie, &tlp_rp_regdata);
+
+	tlp_rp_regdata.reg0 = headers[2];
+	tlp_rp_regdata.reg1 = data;
+	tlp_rp_regdata.ctrl = RP_TX_EOP;
+	tlp_write_tx(pcie, &tlp_rp_regdata);
+}
+
+static int tlp_cfg_dword_read(struct altera_pcie *pcie, u8 bus, u32 devfn,
+			      int where, u32 *value)
+{
+	int ret;
+	u32 headers[TLP_HDR_SIZE];
+
+	if (bus == pcie->root_bus_nr)
+		headers[0] = TLP_CFG_DW0(TLP_FMTTYPE_CFGRD0);
+	else
+		headers[0] = TLP_CFG_DW0(TLP_FMTTYPE_CFGRD1);
+
+	headers[1] = TLP_CFG_DW1(TLP_REQ_ID(pcie->root_bus_nr, devfn),
+					TLP_READ_TAG);
+	headers[2] = TLP_CFG_DW2(bus, devfn, where);
+
+	tlp_write_packet(pcie, headers, 0);
+
+	ret = tlp_read_packet(pcie, value);
+	if (ret)
+		*value = ~0UL;	/* return 0xFFFFFFFF if error */
+
+	return ret;
+}
+
+static int tlp_cfg_dword_write(struct altera_pcie *pcie, u8 bus, u32 devfn,
+			       int where, u32 value)
+{
+	u32 headers[TLP_HDR_SIZE];
+
+	if (bus == pcie->root_bus_nr)
+		headers[0] = TLP_CFG_DW0(TLP_FMTTYPE_CFGWR0);
+	else
+		headers[0] = TLP_CFG_DW0(TLP_FMTTYPE_CFGWR1);
+
+	headers[1] = TLP_CFG_DW1(TLP_REQ_ID(pcie->root_bus_nr, devfn),
+					TLP_WRITE_TAG);
+	headers[2] = TLP_CFG_DW2(bus, devfn, where);
+
+	tlp_write_packet(pcie, headers, value);
+
+	tlp_read_packet(pcie, NULL);
+
+	/* Keep an eye out for changes to the root bus number */
+	if ((bus == pcie->root_bus_nr) && (where == PCI_PRIMARY_BUS))
+		pcie->root_bus_nr = (u8)(value);
+
+	return PCIBIOS_SUCCESSFUL;
+}
+
+static int altera_pcie_cfg_read(struct pci_bus *bus, unsigned int devfn,
+				int where, int size, u32 *value)
+{
+	struct altera_pcie *pcie = bus->sysdata;
+	int ret;
+
+	if (!altera_pcie_valid_config(pcie, bus, PCI_SLOT(devfn))) {
+		*value = ~0UL;
+		return PCIBIOS_DEVICE_NOT_FOUND;
+	}
+
+	ret = tlp_cfg_dword_read(pcie, bus->number, devfn,
+				 (where & ~DWORD_MASK), value);
+	if (ret != PCIBIOS_SUCCESSFUL)
+		return ret;
+
+	if (size == 1)
+		*value = (*value >> (8 * (where & 0x3))) & 0xff;
+	else if (size == 2)
+		*value = (*value >> (8 * (where & 0x2))) & 0xffff;
+
+	return PCIBIOS_SUCCESSFUL;
+}
+
+static int altera_pcie_cfg_write(struct pci_bus *bus, unsigned int devfn,
+				 int where, int size, u32 value)
+{
+	struct altera_pcie *pcie = bus->sysdata;
+	u32 data32 = value;
+	u32 shift = 8 * (where & 3);
+	int ret;
+
+	if (!altera_pcie_valid_config(pcie, bus, PCI_SLOT(devfn)))
+		return PCIBIOS_DEVICE_NOT_FOUND;
+
+	/* write partial */
+	if (size != sizeof(u32)) {
+		ret = tlp_cfg_dword_read(pcie, bus->number, devfn,
+					 where & ~DWORD_MASK, &data32);
+		if (ret)
+			return ret;
+
+		if (size == 2)
+			data32 = (data32 & ~(0xffff << shift)) |
+					((value & 0xffff) << shift);
+		 else if (size == 1)
+			data32 = (data32 & ~(0xff << shift)) |
+					((value & 0xff) << shift);
+	}
+
+	return tlp_cfg_dword_write(pcie, bus->number, devfn,
+		(where & ~DWORD_MASK), data32);
+}
+
+static struct pci_ops altera_pcie_ops = {
+	.read = altera_pcie_cfg_read,
+	.write = altera_pcie_cfg_write,
+};
+
+static int altera_pcie_intx_map(struct irq_domain *domain, unsigned int irq,
+				irq_hw_number_t hwirq)
+{
+	irq_set_chip_and_handler(irq, &dummy_irq_chip, handle_simple_irq);
+	irq_set_chip_data(irq, domain->host_data);
+	set_irq_flags(irq, IRQF_VALID);
+
+	return 0;
+}
+
+static const struct irq_domain_ops intx_domain_ops = {
+	.map = altera_pcie_intx_map,
+};
+
+static void altera_pcie_isr(unsigned int irq, struct irq_desc *desc)
+{
+	struct irq_chip *chip = irq_desc_get_chip(desc);
+	struct altera_pcie *pcie;
+	unsigned long status;
+	u32 bit;
+	u32 virq;
+
+	chained_irq_enter(chip, desc);
+	pcie = irq_desc_get_handler_data(desc);
+
+	do {
+		status = cra_readl(pcie, P2A_INT_STATUS) & P2A_INT_STS_ALL;
+		if (!status)
+			break;
+
+		do {
+			bit = find_first_bit(&status, INTX_NUM);
+			/* clear interrupts */
+			cra_writel(pcie, 1 << bit, P2A_INT_STATUS);
+
+			virq = irq_find_mapping(pcie->irq_domain, bit + 1);
+			if (virq)
+				generic_handle_irq(virq);
+			else
+				dev_info(&pcie->pdev->dev, "unexpected IRQ\n");
+
+			/* Clear the bit from status and repeat without reading
+			 * again status register. */
+			__clear_bit(bit, &status);
+		} while (status);
+	} while (1);
+
+	chained_irq_exit(chip, desc);
+}
+
+static void altera_pcie_release_of_pci_ranges(struct altera_pcie *pcie)
+{
+	pci_free_resource_list(&pcie->resources);
+}
+
+static int altera_pcie_parse_request_of_pci_ranges(struct altera_pcie *pcie)
+{
+	int err, res_valid = 0;
+	struct device *dev = &pcie->pdev->dev;
+	struct device_node *np = dev->of_node;
+	resource_size_t iobase;
+	struct resource_entry *win;
+
+	err = of_pci_get_host_bridge_resources(np, 0, 0xff, &pcie->resources,
+					       &iobase);
+	if (err)
+		return err;
+
+	resource_list_for_each_entry(win, &pcie->resources) {
+		struct resource *parent, *res = win->res;
+
+		switch (resource_type(res)) {
+		case IORESOURCE_MEM:
+			parent = &iomem_resource;
+			res_valid |= !(res->flags & IORESOURCE_PREFETCH);
+			break;
+		default:
+			continue;
+		}
+
+		err = devm_request_resource(dev, parent, res);
+		if (err)
+			goto out_release_res;
+	}
+
+	if (!res_valid) {
+		dev_err(dev, "non-prefetchable memory resource required\n");
+		err = -EINVAL;
+		goto out_release_res;
+	}
+
+	return 0;
+
+out_release_res:
+	altera_pcie_release_of_pci_ranges(pcie);
+	return err;
+}
+
+static void altera_pcie_free_irq_domain(struct altera_pcie *pcie)
+{
+	int i;
+	u32 irq;
+
+	for (i = 0; i < INTX_NUM; i++) {
+		irq = irq_find_mapping(pcie->irq_domain, i);
+		if (irq > 0)
+			irq_dispose_mapping(irq);
+	}
+
+	irq_domain_remove(pcie->irq_domain);
+}
+
+static int altera_pcie_init_irq_domain(struct altera_pcie *pcie)
+{
+	struct device *dev = &pcie->pdev->dev;
+	struct device_node *node = dev->of_node;
+
+	/* Setup INTx */
+	pcie->irq_domain = irq_domain_add_linear(node, INTX_NUM,
+					&intx_domain_ops, pcie);
+	if (!pcie->irq_domain) {
+		dev_err(dev, "Failed to get a INTx IRQ domain\n");
+		return PTR_ERR(pcie->irq_domain);
+	}
+
+	return 0;
+}
+
+static int altera_pcie_parse_dt(struct altera_pcie *pcie)
+{
+	struct resource *cra;
+	struct platform_device *pdev = pcie->pdev;
+
+	cra = platform_get_resource_byname(pdev, IORESOURCE_MEM, "Cra");
+	pcie->cra_base = devm_ioremap_resource(&pdev->dev, cra);
+	if (IS_ERR(pcie->cra_base)) {
+		dev_err(&pdev->dev, "get Cra resource failed\n");
+		return PTR_ERR(pcie->cra_base);
+	}
+
+	/* setup IRQ */
+	pcie->irq = platform_get_irq(pdev, 0);
+	if (pcie->irq <= 0) {
+		dev_err(&pdev->dev, "failed to get IRQ: %d\n", pcie->irq);
+		return -EINVAL;
+	}
+
+	irq_set_chained_handler_and_data(pcie->irq, altera_pcie_isr, pcie);
+
+	return 0;
+}
+
+static int altera_pcie_probe(struct platform_device *pdev)
+{
+	struct altera_pcie *pcie;
+	struct pci_bus *bus;
+	int ret;
+
+	pcie = devm_kzalloc(&pdev->dev, sizeof(*pcie), GFP_KERNEL);
+	if (!pcie)
+		return -ENOMEM;
+
+	pcie->pdev = pdev;
+
+	ret = altera_pcie_parse_dt(pcie);
+	if (ret) {
+		dev_err(&pdev->dev, "Parsing DT failed\n");
+		return ret;
+	}
+
+	INIT_LIST_HEAD(&pcie->resources);
+
+	ret = altera_pcie_parse_request_of_pci_ranges(pcie);
+	if (ret) {
+		dev_err(&pdev->dev, "Failed add resources\n");
+		return ret;
+	}
+
+	ret = altera_pcie_init_irq_domain(pcie);
+	if (ret) {
+		dev_err(&pdev->dev, "Failed creating IRQ Domain\n");
+		return ret;
+	}
+
+	pcie->root_bus_nr = 0;
+
+	/* clear all interrupts */
+	cra_writel(pcie, P2A_INT_STS_ALL, P2A_INT_STATUS);
+	/* enable all interrupts */
+	cra_writel(pcie, P2A_INT_ENA_ALL, P2A_INT_ENABLE);
+
+	bus = pci_scan_root_bus(&pdev->dev, pcie->root_bus_nr, &altera_pcie_ops,
+				pcie, &pcie->resources);
+	if (!bus)
+		return -ENOMEM;
+
+	pci_fixup_irqs(pci_common_swizzle, of_irq_parse_and_map_pci);
+	pci_assign_unassigned_bus_resources(bus);
+	pci_bus_add_devices(bus);
+
+	platform_set_drvdata(pdev, pcie);
+	return ret;
+}
+
+static int __exit altera_pcie_remove(struct platform_device *pdev)
+{
+	struct altera_pcie *pcie = platform_get_drvdata(pdev);
+
+	altera_pcie_free_irq_domain(pcie);
+	platform_set_drvdata(pdev, NULL);
+	return 0;
+}
+
+static const struct of_device_id altera_pcie_of_match[] = {
+	{ .compatible = "altr,pcie-root-port-1.0", },
+	{},
+};
+MODULE_DEVICE_TABLE(of, altera_pcie_of_match);
+
+static struct platform_driver altera_pcie_driver = {
+	.probe		= altera_pcie_probe,
+	.remove		= altera_pcie_remove,
+	.driver = {
+		.name	= "altera-pcie",
+		.of_match_table = altera_pcie_of_match,
+	},
+};
+
+module_platform_driver(altera_pcie_driver);
+
+MODULE_AUTHOR("Ley Foon Tan <lftan at altera.com>");
+MODULE_DESCRIPTION("Altera PCIe host controller driver");
+MODULE_LICENSE("GPL v2");
-- 
1.8.2.1



From lftan at altera.com  Fri Aug  7 00:43:00 2015
From: lftan at altera.com (Ley Foon Tan)
Date: Fri, 7 Aug 2015 15:43:00 +0800
Subject: [PATCH v3 3/5] pci: altera: Add Altera PCIe MSI driver
In-Reply-To: <1438933382-2936-1-git-send-email-lftan@altera.com>
References: <1438933382-2936-1-git-send-email-lftan@altera.com>
Message-ID: <1438933382-2936-4-git-send-email-lftan@altera.com>

This patch adds Altera PCIe MSI driver. This soft IP supports configurable
number of vectors, which is a dts parameter.

Signed-off-by: Ley Foon Tan <lftan at altera.com>
---
 drivers/pci/host/Kconfig           |   8 +
 drivers/pci/host/Makefile          |   1 +
 drivers/pci/host/pcie-altera-msi.c | 309 +++++++++++++++++++++++++++++++++++++
 3 files changed, 318 insertions(+)
 create mode 100644 drivers/pci/host/pcie-altera-msi.c

diff --git a/drivers/pci/host/Kconfig b/drivers/pci/host/Kconfig
index 4b4754a..d28cc6d 100644
--- a/drivers/pci/host/Kconfig
+++ b/drivers/pci/host/Kconfig
@@ -152,4 +152,12 @@ config PCIE_ALTERA
 	  Say Y here if you want to enable PCIe controller support for Altera
 	  SoCFPGA family of SoCs.
 
+config PCIE_ALTERA_MSI
+	bool "Altera PCIe MSI feature"
+	depends on PCI_MSI
+	select PCI_MSI_IRQ_DOMAIN
+	help
+	  Say Y here if you want PCIe MSI support for the Altera SocFPGA SoC.
+	  This MSI driver supports Altera MSI to GIC controller IP.
+
 endmenu
diff --git a/drivers/pci/host/Makefile b/drivers/pci/host/Makefile
index 6954f76..6c4913d 100644
--- a/drivers/pci/host/Makefile
+++ b/drivers/pci/host/Makefile
@@ -18,3 +18,4 @@ obj-$(CONFIG_PCIE_IPROC) += pcie-iproc.o
 obj-$(CONFIG_PCIE_IPROC_PLATFORM) += pcie-iproc-platform.o
 obj-$(CONFIG_PCIE_IPROC_BCMA) += pcie-iproc-bcma.o
 obj-$(CONFIG_PCIE_ALTERA) += pcie-altera.o
+obj-$(CONFIG_PCIE_ALTERA_MSI) += pcie-altera-msi.o
diff --git a/drivers/pci/host/pcie-altera-msi.c b/drivers/pci/host/pcie-altera-msi.c
new file mode 100644
index 0000000..2d84e62
--- /dev/null
+++ b/drivers/pci/host/pcie-altera-msi.c
@@ -0,0 +1,309 @@
+/*
+ * Copyright Altera Corporation (C) 2013-2015. All rights reserved
+ *
+ * This program is free software; you can redistribute it and/or modify it
+ * under the terms and conditions of the GNU General Public License,
+ * version 2, as published by the Free Software Foundation.
+ *
+ * This program is distributed in the hope 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.
+ *
+ * You should have received a copy of the GNU General Public License along with
+ * this program.  If not, see <http://www.gnu.org/licenses/>.
+ */
+#include <linux/interrupt.h>
+#include <linux/irqchip/chained_irq.h>
+#include <linux/module.h>
+#include <linux/msi.h>
+#include <linux/of_address.h>
+#include <linux/of_irq.h>
+#include <linux/of_pci.h>
+#include <linux/pci.h>
+#include <linux/platform_device.h>
+#include <linux/slab.h>
+
+#define MSI_STATUS		0x0
+#define MSI_ERROR		0x4
+#define MSI_INTMASK		0x8
+
+#define MAX_MSI_VECTORS		32
+struct altera_msi {
+	DECLARE_BITMAP(used, MAX_MSI_VECTORS);
+	struct mutex		lock;	/* proctect used variable */
+	struct platform_device	*pdev;
+	struct irq_domain		*msi_domain;
+	struct irq_domain		*inner_domain;
+	void __iomem		*csr_base;
+	void __iomem		*vector_base;
+	phys_addr_t		vector_phy;
+	u32			num_of_vectors;
+	int			irq;
+};
+
+static inline void msi_writel(struct altera_msi *msi, u32 value, u32 reg)
+{
+	writel_relaxed(value, msi->csr_base + reg);
+}
+
+static inline u32 msi_readl(struct altera_msi *msi, u32 reg)
+{
+	return readl_relaxed(msi->csr_base + reg);
+}
+
+static void altera_msi_isr(unsigned int irq, struct irq_desc *desc)
+{
+	struct irq_chip *chip = irq_desc_get_chip(desc);
+	struct altera_msi *msi;
+	unsigned long status;
+	u32 num_of_vectors;
+	u32 bit;
+	u32 virq;
+
+	chained_irq_enter(chip, desc);
+	msi = irq_desc_get_handler_data(desc);
+	num_of_vectors = msi->num_of_vectors;
+
+	do {
+		status = msi_readl(msi, MSI_STATUS);
+		if (!status)
+			break;
+
+		do {
+			bit = find_first_bit(&status, num_of_vectors);
+			/* Dummy read from vector to clear the interrupt */
+			readl_relaxed(msi->vector_base + (bit * sizeof(u32)));
+
+			virq = irq_find_mapping(msi->inner_domain, bit);
+			if (virq && test_bit(bit, msi->used))
+				generic_handle_irq(virq);
+			else
+				dev_err(&msi->pdev->dev, "unexpected MSI\n");
+
+			/* Clear the bit from status and repeat without reading
+			 * again status register. */
+			__clear_bit(bit, &status);
+		} while (status);
+	} while (1);
+
+	chained_irq_exit(chip, desc);
+}
+
+static struct irq_chip altera_msi_irq_chip = {
+	.name = "Altera PCIe MSI",
+	.irq_enable = pci_msi_unmask_irq,
+	.irq_disable = pci_msi_mask_irq,
+	.irq_mask = pci_msi_mask_irq,
+	.irq_unmask = pci_msi_unmask_irq,
+};
+
+static struct msi_domain_info altera_msi_domain_info = {
+	.flags	= (MSI_FLAG_USE_DEF_DOM_OPS | MSI_FLAG_USE_DEF_CHIP_OPS |
+		     MSI_FLAG_PCI_MSIX),
+	.chip	= &altera_msi_irq_chip,
+};
+
+static void altera_compose_msi_msg(struct irq_data *data, struct msi_msg *msg)
+{
+	struct altera_msi *msi = irq_data_get_irq_chip_data(data);
+	phys_addr_t addr = msi->vector_phy + (data->hwirq * sizeof(u32));
+
+	msg->address_lo = lower_32_bits(addr);
+	msg->address_hi = upper_32_bits(addr);
+	msg->data = data->hwirq;
+
+	dev_dbg(&msi->pdev->dev, "msi#%d address_lo 0x%x address_hi 0x%x\n",
+		(int)data->hwirq, msg->address_hi, msg->address_lo);
+}
+
+static int altera_msi_set_affinity(struct irq_data *irq_data,
+				   const struct cpumask *mask, bool force)
+{
+	 return -EINVAL;
+}
+
+static struct irq_chip altera_msi_bottom_irq_chip = {
+	.name			= "Altera MSI",
+	.irq_compose_msi_msg	= altera_compose_msi_msg,
+	.irq_set_affinity	= altera_msi_set_affinity,
+};
+
+static int altera_irq_domain_alloc(struct irq_domain *domain, unsigned int virq,
+				   unsigned int nr_irqs, void *args)
+{
+	struct altera_msi *msi = domain->host_data;
+	unsigned long bit;
+	u32 mask;
+
+	mutex_lock(&msi->lock);
+
+	bit = find_first_zero_bit(msi->used, msi->num_of_vectors);
+	if (bit >= msi->num_of_vectors)
+		return -ENOSPC;
+
+	set_bit(bit, msi->used);
+
+	mutex_unlock(&msi->lock);
+
+	irq_domain_set_info(domain, virq, bit, &altera_msi_bottom_irq_chip,
+			    domain->host_data, handle_simple_irq,
+			    NULL, NULL);
+	set_irq_flags(virq, IRQF_VALID);
+
+	mask = msi_readl(msi, MSI_INTMASK);
+	mask |= 1 << bit;
+	msi_writel(msi, mask, MSI_INTMASK);
+
+	return 0;
+}
+
+static void altera_irq_domain_free(struct irq_domain *domain,
+				   unsigned int virq, unsigned int nr_irqs)
+{
+	struct irq_data *d = irq_domain_get_irq_data(domain, virq);
+	struct altera_msi *msi = irq_data_get_irq_chip_data(d);
+	u32 mask;
+
+	mutex_lock(&msi->lock);
+
+	if (!test_bit(d->hwirq, msi->used)) {
+		dev_err(&msi->pdev->dev, "trying to free unused MSI#%lu\n",
+			d->hwirq);
+	} else {
+		__clear_bit(d->hwirq, msi->used);
+		mask = msi_readl(msi, MSI_INTMASK);
+		mask &= ~(1 << d->hwirq);
+		msi_writel(msi, mask, MSI_INTMASK);
+	}
+
+	mutex_unlock(&msi->lock);
+}
+
+static const struct irq_domain_ops msi_domain_ops = {
+	.alloc	= altera_irq_domain_alloc,
+	.free	= altera_irq_domain_free,
+};
+
+static int altera_allocate_domains(struct altera_msi *msi)
+{
+	msi->inner_domain = irq_domain_add_linear(NULL, msi->num_of_vectors,
+					     &msi_domain_ops, msi);
+	if (!msi->inner_domain) {
+		dev_err(&msi->pdev->dev, "failed to create IRQ domain\n");
+		return -ENOMEM;
+	}
+
+	msi->msi_domain = pci_msi_create_irq_domain(msi->pdev->dev.of_node,
+				&altera_msi_domain_info, msi->inner_domain);
+	if (!msi->msi_domain) {
+		dev_err(&msi->pdev->dev, "failed to create MSI domain\n");
+		irq_domain_remove(msi->inner_domain);
+		return -ENOMEM;
+	}
+
+	return 0;
+}
+
+static void altera_free_domains(struct altera_msi *msi)
+{
+	irq_domain_remove(msi->msi_domain);
+	irq_domain_remove(msi->inner_domain);
+}
+
+static int altera_msi_remove(struct platform_device *pdev)
+{
+	struct altera_msi *msi = platform_get_drvdata(pdev);
+
+	msi_writel(msi, 0, MSI_INTMASK);
+	irq_set_chained_handler(msi->irq, NULL);
+	irq_set_handler_data(msi->irq, NULL);
+
+	altera_free_domains(msi);
+
+	platform_set_drvdata(pdev, NULL);
+	return 0;
+}
+
+static int altera_msi_probe(struct platform_device *pdev)
+{
+	struct altera_msi *msi;
+	struct device_node *np = pdev->dev.of_node;
+	struct resource *res;
+	int ret;
+
+	msi = devm_kzalloc(&pdev->dev, sizeof(struct altera_msi),
+			   GFP_KERNEL);
+	if (!msi)
+		return -ENOMEM;
+
+	mutex_init(&msi->lock);
+	msi->pdev = pdev;
+
+	res = platform_get_resource_byname(pdev, IORESOURCE_MEM, "csr");
+	msi->csr_base = devm_ioremap_resource(&pdev->dev, res);
+	if (IS_ERR(msi->csr_base)) {
+		dev_err(&pdev->dev, "get csr resource failed\n");
+		return PTR_ERR(msi->csr_base);
+	}
+
+	res = platform_get_resource_byname(pdev, IORESOURCE_MEM,
+					   "vector_slave");
+	msi->vector_base = devm_ioremap_resource(&pdev->dev, res);
+	if (IS_ERR(msi->vector_base)) {
+		dev_err(&pdev->dev, "get vector slave resource failed\n");
+		return PTR_ERR(msi->vector_base);
+	}
+
+	msi->vector_phy = res->start;
+
+	if (of_property_read_u32(np, "num-vectors", &msi->num_of_vectors)) {
+		dev_err(&pdev->dev, "failed to parse the number of vectors\n");
+		return -EINVAL;
+	}
+
+	ret = altera_allocate_domains(msi);
+	if (ret)
+		return ret;
+
+	msi->irq = platform_get_irq(pdev, 0);
+	if (msi->irq <= 0) {
+		dev_err(&pdev->dev, "failed to map IRQ: %d\n", msi->irq);
+		ret = -ENODEV;
+		goto err;
+	}
+
+	irq_set_chained_handler_and_data(msi->irq, altera_msi_isr, msi);
+	platform_set_drvdata(pdev, msi);
+
+	return 0;
+
+err:
+	altera_msi_remove(pdev);
+	return ret;
+}
+
+static const struct of_device_id altera_msi_of_match[] = {
+	{ .compatible = "altr,msi-1.0", NULL },
+	{ },
+};
+
+static struct platform_driver altera_msi_driver = {
+	.driver = {
+		.name = "altera-msi",
+		.of_match_table = altera_msi_of_match,
+	},
+	.probe = altera_msi_probe,
+	.remove = altera_msi_remove,
+};
+
+static int __init altera_msi_init(void)
+{
+	return platform_driver_register(&altera_msi_driver);
+}
+
+subsys_initcall(altera_msi_init);
+
+MODULE_AUTHOR("Ley Foon Tan <lftan at altera.com>");
+MODULE_DESCRIPTION("Altera PCIe MSI support");
+MODULE_LICENSE("GPL v2");
-- 
1.8.2.1



From Yuantian.Tang at freescale.com  Fri Aug  7 00:38:31 2015
From: Yuantian.Tang at freescale.com (Yuantian.Tang at freescale.com)
Date: Fri, 7 Aug 2015 15:38:31 +0800
Subject: [PATCH] arm: ls1021a: added SATA node in dts
Message-ID: <1438933111-39418-1-git-send-email-Yuantian.Tang@freescale.com>

From: Tang Yuantian <Yuantian.Tang at freescale.com>

Added SATA device node and enabled AHCI config by default.

Signed-off-by: Shaohui Xie <Shaohui.Xie at freescale.com>
Signed-off-by: Tang Yuantian <Yuantian.Tang at freescale.com>
---
depends on patch:
https://patchwork.kernel.org/patch/6851311/

 arch/arm/boot/dts/ls1021a.dtsi     | 7 +++++++
 arch/arm/configs/ls1021a_defconfig | 2 ++
 2 files changed, 9 insertions(+)

diff --git a/arch/arm/boot/dts/ls1021a.dtsi b/arch/arm/boot/dts/ls1021a.dtsi
index c70bb27..1ee2a79 100644
--- a/arch/arm/boot/dts/ls1021a.dtsi
+++ b/arch/arm/boot/dts/ls1021a.dtsi
@@ -139,6 +139,13 @@
 			status = "disabled";
 		};
 
+		sata: sata at 3200000 {
+			compatible = "fsl,qoriq-ahci";
+			reg = <0x0 0x3200000 0x0 0x10000>;
+			interrupts = <GIC_SPI 101 IRQ_TYPE_LEVEL_HIGH>;
+			clocks = <&platform_clk 1>;
+		};
+
 		scfg: scfg at 1570000 {
 			compatible = "fsl,ls1021a-scfg", "syscon";
 			reg = <0x0 0x1570000 0x0 0x10000>;
diff --git a/arch/arm/configs/ls1021a_defconfig b/arch/arm/configs/ls1021a_defconfig
index 079c48f..f502910 100644
--- a/arch/arm/configs/ls1021a_defconfig
+++ b/arch/arm/configs/ls1021a_defconfig
@@ -70,6 +70,8 @@ CONFIG_BLK_DEV_RAM_SIZE=256000
 CONFIG_BLK_DEV_SD=y
 CONFIG_CHR_DEV_SG=y
 CONFIG_ATA=y
+CONFIG_SATA_AHCI=y
+CONFIG_SATA_AHCI_PLATFORM=y
 CONFIG_NETDEVICES=y
 CONFIG_GIANFAR=y
 CONFIG_VITESSE_PHY=y
-- 
2.1.0.27.g96db324



From lftan at altera.com  Fri Aug  7 00:43:02 2015
From: lftan at altera.com (Ley Foon Tan)
Date: Fri, 7 Aug 2015 15:43:02 +0800
Subject: [PATCH v3 5/5] MAINTAINERS: Add Altera PCIe and MSI drivers maintainer
In-Reply-To: <1438933382-2936-1-git-send-email-lftan@altera.com>
References: <1438933382-2936-1-git-send-email-lftan@altera.com>
Message-ID: <1438933382-2936-6-git-send-email-lftan@altera.com>

Signed-off-by: Ley Foon Tan <lftan at altera.com>
---
 MAINTAINERS | 16 ++++++++++++++++
 1 file changed, 16 insertions(+)

diff --git a/MAINTAINERS b/MAINTAINERS
index fd60784..32f5287 100644
--- a/MAINTAINERS
+++ b/MAINTAINERS
@@ -7759,6 +7759,14 @@ F:	include/linux/pci*
 F:	arch/x86/pci/
 F:	arch/x86/kernel/quirks.c
 
+PCI DRIVER FOR ALTERA PCIE IP
+M:	Ley Foon Tan <lftan at altera.com>
+L:	rfi at lists.rocketboards.org (moderated for non-subscribers)
+L:	linux-pci at vger.kernel.org
+S:	Supported
+F:	Documentation/devicetree/bindings/pci/altera-pcie.txt
+F:	drivers/pci/host/pcie-altera.c
+
 PCI DRIVER FOR ARM VERSATILE PLATFORM
 M:	Rob Herring <robh at kernel.org>
 L:	linux-pci at vger.kernel.org
@@ -7860,6 +7868,14 @@ L:	linux-pci at vger.kernel.org
 S:	Maintained
 F:	drivers/pci/host/*spear*
 
+PCI MSI DRIVER FOR ALTERA MSI IP
+M:	Ley Foon Tan <lftan at altera.com>
+L:	rfi at lists.rocketboards.org (moderated for non-subscribers)
+L:	linux-pci at vger.kernel.org
+S:	Supported
+F:	Documentation/devicetree/bindings/pci/altera-pcie-msi.txt
+F:	drivers/pci/host/pcie-altera-msi.c
+
 PCI MSI DRIVER FOR APPLIEDMICRO XGENE
 M:	Duc Dang <dhdang at apm.com>
 L:	linux-pci at vger.kernel.org
-- 
1.8.2.1



From lftan at altera.com  Fri Aug  7 00:43:01 2015
From: lftan at altera.com (Ley Foon Tan)
Date: Fri, 7 Aug 2015 15:43:01 +0800
Subject: [PATCH v3 4/5] Documentation: dt-bindings: pci: altera pcie device
 tree binding
In-Reply-To: <1438933382-2936-1-git-send-email-lftan@altera.com>
References: <1438933382-2936-1-git-send-email-lftan@altera.com>
Message-ID: <1438933382-2936-5-git-send-email-lftan@altera.com>

This patch adds the bindings for Altera PCIe host controller driver and
Altera PCIe MSI driver.

Signed-off-by: Ley Foon Tan <lftan at altera.com>
---
 .../devicetree/bindings/pci/altera-pcie-msi.txt    | 27 ++++++++++++
 .../devicetree/bindings/pci/altera-pcie.txt        | 49 ++++++++++++++++++++++
 2 files changed, 76 insertions(+)
 create mode 100644 Documentation/devicetree/bindings/pci/altera-pcie-msi.txt
 create mode 100644 Documentation/devicetree/bindings/pci/altera-pcie.txt

diff --git a/Documentation/devicetree/bindings/pci/altera-pcie-msi.txt b/Documentation/devicetree/bindings/pci/altera-pcie-msi.txt
new file mode 100644
index 0000000..7f330c9
--- /dev/null
+++ b/Documentation/devicetree/bindings/pci/altera-pcie-msi.txt
@@ -0,0 +1,27 @@
+* Altera PCIe MSI controller
+
+Required properties:
+- compatible:	should contain "altr,msi-1.0"
+- reg:		specifies the physical base address of the controller and
+		the length of the memory mapped region.
+- reg-names:	Must include the following entries:
+		"csr": CSR registers
+		"vector_slave": vectors region
+-interrupts:	specifies the interrupt source of the parent interrupt
+		controller. The format of the interrupt specifier depends on the
+		parent interrupt controller.
+- num-vectors:	Number of vectors, range 1 to 32.
+- msi-controller:	indicates that this is MSI controller node
+
+
+Example
+msi0: msi at 0xFF200000 {
+	compatible = "altr,msi-1.0";
+	reg = <0xFF200000 0x00000010
+		0xFF200010 0x00000080>;
+	reg-names = "csr", "vector_slave";
+	interrupt-parent = <&hps_0_arm_gic_0>;
+	interrupts = <0 42 4>;
+	msi-controller = <1>;
+	num-vectors = <32>;
+};
diff --git a/Documentation/devicetree/bindings/pci/altera-pcie.txt b/Documentation/devicetree/bindings/pci/altera-pcie.txt
new file mode 100644
index 0000000..729193d
--- /dev/null
+++ b/Documentation/devicetree/bindings/pci/altera-pcie.txt
@@ -0,0 +1,49 @@
+* Altera PCIe controller
+
+Required properties:
+- compatible :	should contain "altr,pcie-root-port-1.0"
+- reg:		A list of physical base address and length for TXS and CRA.
+- reg-names:	Must include the following entries:
+		"Txs": TXS region
+		"Cra": Control register access region
+-interrupts:	specifies the interrupt source of the parent interrupt controller.
+		The format of the interrupt specifier depends on the parent interrupt
+		controller.
+- device_type:	must be "pci"
+- #address-cells:	set to <3>
+- #size-cells:	set to <2>
+- #interrupt-cells:	set to <1>
+- ranges:		Describes the translation of addresses for root ports and standard
+		PCI regions.
+- interrupt-map-mask and interrupt-map: standard PCI properties
+	to define the mapping of the PCIe interface to interrupt
+	numbers.
+
+Optional properties:
+- msi-parent:	Link to the hardware entity that serves as the MSI controller for this PCIe
+		controller.
+- bus-range:	PCI bus numbers covered
+
+Example
+	pcie_0: pcie at 0xc00000000 {
+		compatible = "altr,pcie-root-port-1.0";
+		reg = <0xc0000000 0x20000000>,
+			<0xff220000 0x00004000>;
+		reg-names = "Txs", "Cra";
+		interrupt-parent = <&hps_0_arm_gic_0>;
+		interrupts = <0 40 4>;
+		interrupt-controller;
+		#interrupt-cells = <1>;
+		bus-range = <0x0 0xFF>;
+		device_type = "pci";
+		msi-parent = <&msi_to_gic_gen_0>;
+		#address-cells = <3>;
+		#size-cells = <2>;
+		interrupt-map-mask = <0 0 0 7>;
+		interrupt-map = <0 0 0 1 &pcie_0 1>,
+			            <0 0 0 2 &pcie_0 2>,
+			            <0 0 0 3 &pcie_0 3>,
+			            <0 0 0 4 &pcie_0 4>;
+		ranges = <0x82000000 0x00000000 0x00000000 0xc0000000 0x00000000 0x10000000
+			    0x82000000 0x00000000 0x10000000 0xd0000000 0x00000000 0x10000000>;
+	};
-- 
1.8.2.1



From p.zabel at pengutronix.de  Fri Aug  7 00:46:37 2015
From: p.zabel at pengutronix.de (Philipp Zabel)
Date: Fri, 07 Aug 2015 09:46:37 +0200
Subject: [PATCH 2/3] nvmem: imx-ocotp: Add i.MX6 OCOTP driver
In-Reply-To: <55C3B74F.5010501@linaro.org>
References: <1438693342-605-1-git-send-email-p.zabel@pengutronix.de>
 <1438693342-605-2-git-send-email-p.zabel@pengutronix.de>
 <55C38941.9090709@linaro.org> <1438878490.3223.10.camel@pengutronix.de>
 <55C3B74F.5010501@linaro.org>
Message-ID: <1438933597.3638.5.camel@pengutronix.de>

Am Donnerstag, den 06.08.2015, 20:36 +0100 schrieb Srinivas Kandagatla:
> Hi Philipp,
> 
> Could you add Greg KH in the CC, for next merge window, we can request 
> Greg to take this driver via his tree.
> 
> Once the comments are fixed you can add my
> 
> Acked-by: Srinivas Kandagatla <srinivas.kandagatla at linaro.org>
> 
> On 06/08/15 17:28, Philipp Zabel wrote:
> > Hi Srinivas,
> >
> > Am Donnerstag, den 06.08.2015, 17:20 +0100 schrieb Srinivas Kandagatla:
> >> Few Nits..
> >>
> >> On 04/08/15 14:02, Philipp Zabel wrote:
> >>> +#include <linux/clk.h>
> >> May be you can drop this?
> >
> > Yes, that's a left-over and can be removed.
> >
> >> BTW, who is taking care of the gated peripheral clock controlled for
> >> this driver?
> >
> > Nobody. I had initially copied the code that actually senses the fuses,
> > but since this happens during power-on reset anyway (all values are
> > stored in shadow registers), I didn't see the point and dropped it for
> > now.
> > The shadow registers are clocked directly by the ungated ipg_root clock.
> 
> So, are you planning to drop the clocks property from the bindings too?

The gated clock input exists and is needed for the full functionality of
the device (writing and re-sensing fuses). It should be in the device
tree even if the linux driver doesn't implement writing.

regards
Philipp



From aisheng.dong at freescale.com  Fri Aug  7 00:38:56 2015
From: aisheng.dong at freescale.com (Dong Aisheng)
Date: Fri, 7 Aug 2015 15:38:56 +0800
Subject: [PATCH v4 1/6] mmc: sdhci-esdhc-imx: add imx7d support and
 support HS400
In-Reply-To: <1438771122-8601-2-git-send-email-haibo.chen@freescale.com>
References: <1438771122-8601-1-git-send-email-haibo.chen@freescale.com>
 <1438771122-8601-2-git-send-email-haibo.chen@freescale.com>
Message-ID: <20150807073854.GA6935@shlinux1.ap.freescale.net>

On Wed, Aug 05, 2015 at 06:38:37PM +0800, Haibo Chen wrote:
> The imx7d usdhc is derived from imx6sx, the difference is that
> imx7d support HS400.
> 
> So introduce a new compatible string for imx7d and add HS400
> support for imx7d usdhc.
> 
> Signed-off-by: Haibo Chen <haibo.chen at freescale.com>
> ---
>  drivers/mmc/host/sdhci-esdhc-imx.c | 81 ++++++++++++++++++++++++++++++++++++++
>  1 file changed, 81 insertions(+)
> 
> diff --git a/drivers/mmc/host/sdhci-esdhc-imx.c b/drivers/mmc/host/sdhci-esdhc-imx.c
> index c6b9f64..48f009c 100644
> --- a/drivers/mmc/host/sdhci-esdhc-imx.c
> +++ b/drivers/mmc/host/sdhci-esdhc-imx.c
> @@ -44,6 +44,7 @@
>  #define  ESDHC_MIX_CTRL_EXE_TUNE	(1 << 22)
>  #define  ESDHC_MIX_CTRL_SMPCLK_SEL	(1 << 23)
>  #define  ESDHC_MIX_CTRL_FBCLK_SEL	(1 << 25)
> +#define  ESDHC_MIX_CTRL_HS400_EN	(1 << 26)
>  /* Bits 3 and 6 are not SDHCI standard definitions */
>  #define  ESDHC_MIX_CTRL_SDHCI_MASK	0xb7
>  /* Tuning bits */
> @@ -60,6 +61,16 @@
>  #define  ESDHC_TUNE_CTRL_MIN		0
>  #define  ESDHC_TUNE_CTRL_MAX		((1 << 7) - 1)
>  
> +/* strobe dll register */
> +#define ESDHC_STROBE_DLL_CTRL		0x70
> +#define ESDHC_STROBE_DLL_CTRL_ENABLE	(1 << 0)
> +#define ESDHC_STROBE_DLL_CTRL_RESET	(1 << 1)
> +#define ESDHC_STROBE_DLL_CTRL_SLV_DLY_TARGET_SHIFT	3
> +
> +#define ESDHC_STROBE_DLL_STATUS		0x74
> +#define ESDHC_STROBE_DLL_STS_REF_LOCK	(1 << 1)
> +#define ESDHC_STROBE_DLL_STS_SLV_LOCK	0x1
> +
>  #define ESDHC_TUNING_CTRL		0xcc
>  #define ESDHC_STD_TUNING_EN		(1 << 24)
>  /* NOTE: the minimum valid tuning start tap for mx6sl is 1 */
> @@ -120,6 +131,11 @@
>  #define ESDHC_FLAG_ERR004536		BIT(7)
>  /* The IP supports HS200 mode */
>  #define ESDHC_FLAG_HS200		BIT(8)
> +/* The IP supports HS400 mode */
> +#define ESDHC_FLAG_HS400		BIT(9)
> +
> +/* A higher clock ferquency than this rate requires strobell dll control */
> +#define ESDHC_STROBE_DLL_CLK_FREQ	100000000
>  
>  struct esdhc_soc_data {
>  	u32 flags;
> @@ -156,6 +172,12 @@ static struct esdhc_soc_data usdhc_imx6sx_data = {
>  			| ESDHC_FLAG_HAVE_CAP1 | ESDHC_FLAG_HS200,
>  };
>  
> +static struct esdhc_soc_data usdhc_imx7d_data = {
> +	.flags = ESDHC_FLAG_USDHC | ESDHC_FLAG_STD_TUNING
> +			| ESDHC_FLAG_HAVE_CAP1 | ESDHC_FLAG_HS200
> +			| ESDHC_FLAG_HS400,
> +};
> +
>  struct pltfm_imx_data {
>  	u32 scratchpad;
>  	struct pinctrl *pinctrl;
> @@ -199,6 +221,7 @@ static const struct of_device_id imx_esdhc_dt_ids[] = {
>  	{ .compatible = "fsl,imx6sx-usdhc", .data = &usdhc_imx6sx_data, },
>  	{ .compatible = "fsl,imx6sl-usdhc", .data = &usdhc_imx6sl_data, },
>  	{ .compatible = "fsl,imx6q-usdhc", .data = &usdhc_imx6q_data, },
> +	{ .compatible = "fsl,imx7d-usdhc", .data = &usdhc_imx7d_data, },
>  	{ /* sentinel */ }
>  };
>  MODULE_DEVICE_TABLE(of, imx_esdhc_dt_ids);
> @@ -274,6 +297,9 @@ static u32 esdhc_readl_le(struct sdhci_host *host, int reg)
>  				val = SDHCI_SUPPORT_DDR50 | SDHCI_SUPPORT_SDR104
>  					| SDHCI_SUPPORT_SDR50
>  					| SDHCI_USE_SDR50_TUNING;
> +
> +			if (imx_data->socdata->flags & ESDHC_FLAG_HS400)
> +				val |= SDHCI_SUPPORT_HS400;
>  		}
>  	}
>  
> @@ -774,6 +800,7 @@ static int esdhc_change_pinstate(struct sdhci_host *host,
>  		break;
>  	case MMC_TIMING_UHS_SDR104:
>  	case MMC_TIMING_MMC_HS200:
> +	case MMC_TIMING_MMC_HS400:
>  		pinctrl = imx_data->pins_200mhz;
>  		break;
>  	default:
> @@ -784,6 +811,44 @@ static int esdhc_change_pinstate(struct sdhci_host *host,
>  	return pinctrl_select_state(imx_data->pinctrl, pinctrl);
>  }
>  
> +/*
> + * For HS400 eMMC, there is a data_strobe line, this signal is generated
> + * by the device and used for data output and CRC status response output
> + * in HS400 mode. The frequency of this signal follows the frequency of
> + * CLK generated by host. Host receive the data which is aligned to the
> + * edge of data_strobe line. Due to the time delay between CLK line and
> + * data_strobe line, if the delay time is larger than one clock cycle,
> + * then CLK and data_strobe line will misaligned, read error shows up.
> + * So when the CLK is higher than 100MHz, each clock cycle is short enough,
> + * host should config the delay target.
> + */
> +static void esdhc_set_strobe_dll(struct sdhci_host *host)
> +{
> +	u32 v;
> +
> +	if (host->mmc->actual_clock > ESDHC_STROBE_DLL_CLK_FREQ) {
> +		/* force a reset on strobe dll */
> +		writel(ESDHC_STROBE_DLL_CTRL_RESET,
> +			host->ioaddr + ESDHC_STROBE_DLL_CTRL);
> +		/*
> +		 * enable strobe dll ctrl and adjust the delay target
> +		 * for the uSDHC loopback read clock
> +		 */
> +		v = ESDHC_STROBE_DLL_CTRL_ENABLE |
> +			(7 << ESDHC_STROBE_DLL_CTRL_SLV_DLY_TARGET_SHIFT);
> +		writel(v, host->ioaddr + ESDHC_STROBE_DLL_CTRL);
> +		/* wait 1us to make sure strobe dll status register stable */
> +		udelay(1);
> +		v = readl(host->ioaddr + ESDHC_STROBE_DLL_STATUS);
> +		if (!(v & ESDHC_STROBE_DLL_STS_REF_LOCK))
> +			dev_warn(mmc_dev(host->mmc),
> +				"warning! HS400 strobe DLL status REF not lock!\n");
> +		if (!(v & ESDHC_STROBE_DLL_STS_SLV_LOCK))
> +			dev_warn(mmc_dev(host->mmc),
> +				"warning! HS400 strobe DLL status SLV not lock!\n");
> +	}
> +}
> +
>  static void esdhc_set_uhs_signaling(struct sdhci_host *host, unsigned timing)
>  {
>  	struct sdhci_pltfm_host *pltfm_host = sdhci_priv(host);
> @@ -795,7 +860,13 @@ static void esdhc_set_uhs_signaling(struct sdhci_host *host, unsigned timing)
>  	case MMC_TIMING_UHS_SDR25:
>  	case MMC_TIMING_UHS_SDR50:
>  	case MMC_TIMING_UHS_SDR104:
> +		break;
>  	case MMC_TIMING_MMC_HS200:
> +		/* disable ddr mode and disable HS400 mode */
> +		writel(readl(host->ioaddr + ESDHC_MIX_CTRL) &
> +			~(ESDHC_MIX_CTRL_DDREN | ESDHC_MIX_CTRL_HS400_EN),
> +			host->ioaddr + ESDHC_MIX_CTRL);
> +		imx_data->is_ddr = 0;

Can you please explain why need above code?
Any issues if not do it?

Regards
Dong Aisheng

>  		break;
>  	case MMC_TIMING_UHS_DDR50:
>  	case MMC_TIMING_MMC_DDR52:
> @@ -813,6 +884,13 @@ static void esdhc_set_uhs_signaling(struct sdhci_host *host, unsigned timing)
>  			writel(v, host->ioaddr + ESDHC_DLL_CTRL);
>  		}
>  		break;
> +	case MMC_TIMING_MMC_HS400:
> +		writel(readl(host->ioaddr + ESDHC_MIX_CTRL) |
> +				ESDHC_MIX_CTRL_DDREN | ESDHC_MIX_CTRL_HS400_EN,
> +				host->ioaddr + ESDHC_MIX_CTRL);
> +		imx_data->is_ddr = 1;
> +		esdhc_set_strobe_dll(host);
> +		break;
>  	}
>  
>  	esdhc_change_pinstate(host, timing);
> @@ -1100,6 +1178,9 @@ static int sdhci_esdhc_imx_probe(struct platform_device *pdev)
>  	if (imx_data->socdata->flags & ESDHC_FLAG_ERR004536)
>  		host->quirks |= SDHCI_QUIRK_BROKEN_ADMA;
>  
> +	if (imx_data->socdata->flags & ESDHC_FLAG_HS400)
> +		host->quirks2 |= SDHCI_QUIRK2_CAPS_BIT63_FOR_HS400;
> +
>  	if (of_id)
>  		err = sdhci_esdhc_imx_probe_dt(pdev, host, imx_data);
>  	else
> -- 
> 1.9.1
> 


From aisheng.dong at freescale.com  Fri Aug  7 00:40:20 2015
From: aisheng.dong at freescale.com (Dong Aisheng)
Date: Fri, 7 Aug 2015 15:40:20 +0800
Subject: [PATCH v4 2/6] mmc: sdhci-esdhc-imx: add tuning-step seting
 support
In-Reply-To: <1438771122-8601-3-git-send-email-haibo.chen@freescale.com>
References: <1438771122-8601-1-git-send-email-haibo.chen@freescale.com>
 <1438771122-8601-3-git-send-email-haibo.chen@freescale.com>
Message-ID: <20150807074019.GB6935@shlinux1.ap.freescale.net>

On Wed, Aug 05, 2015 at 06:38:38PM +0800, Haibo Chen wrote:
> tuning-step is the delay cell steps in tuning procedure. The default value
> of tuning-step is 1. Some boards or cards need another value to pass the
> tuning procedure. For example, imx7d-sdb board need the tuning-step value
> as 2, otherwise it can't pass the tuning procedure.
> 
> So this patch add the tuning-step setting in driver, so that user can set
> the tuning-step value in dts.
> 
> Signed-off-by: Haibo Chen <haibo.chen at freescale.com>
> ---
>  drivers/mmc/host/sdhci-esdhc-imx.c          | 9 +++++++++
>  include/linux/platform_data/mmc-esdhc-imx.h | 1 +
>  2 files changed, 10 insertions(+)
> 
> diff --git a/drivers/mmc/host/sdhci-esdhc-imx.c b/drivers/mmc/host/sdhci-esdhc-imx.c
> index 48f009c..803d24f 100644
> --- a/drivers/mmc/host/sdhci-esdhc-imx.c
> +++ b/drivers/mmc/host/sdhci-esdhc-imx.c
> @@ -75,6 +75,7 @@
>  #define ESDHC_STD_TUNING_EN		(1 << 24)
>  /* NOTE: the minimum valid tuning start tap for mx6sl is 1 */
>  #define ESDHC_TUNING_START_TAP		0x1
> +#define ESDHC_TUNING_STEP_SHIFT		16
>  
>  /* pinctrl state */
>  #define ESDHC_PINCTRL_STATE_100MHZ	"state_100mhz"
> @@ -474,6 +475,7 @@ static void esdhc_writew_le(struct sdhci_host *host, u16 val, int reg)
>  		} else if (imx_data->socdata->flags & ESDHC_FLAG_STD_TUNING) {
>  			u32 v = readl(host->ioaddr + SDHCI_ACMD12_ERR);
>  			u32 m = readl(host->ioaddr + ESDHC_MIX_CTRL);
> +			u32 tuning_ctrl;
>  			if (val & SDHCI_CTRL_TUNED_CLK) {
>  				v |= ESDHC_MIX_CTRL_SMPCLK_SEL;
>  			} else {
> @@ -484,6 +486,11 @@ static void esdhc_writew_le(struct sdhci_host *host, u16 val, int reg)
>  			if (val & SDHCI_CTRL_EXEC_TUNING) {
>  				v |= ESDHC_MIX_CTRL_EXE_TUNE;
>  				m |= ESDHC_MIX_CTRL_FBCLK_SEL;
> +				tuning_ctrl = readl(host->ioaddr + ESDHC_TUNING_CTRL);
> +				tuning_ctrl |= ESDHC_STD_TUNING_EN | ESDHC_TUNING_START_TAP;
> +				if (imx_data->boarddata.tuning_step)
> +					tuning_ctrl |= imx_data->boarddata.tuning_step << ESDHC_TUNING_STEP_SHIFT;
> +					writel(tuning_ctrl, host->ioaddr + ESDHC_TUNING_CTRL);

Is there a code indent issue here?
Otherwise, the patch looks good to me.

Regards
Dong Aisheng

>  			} else {
>  				v &= ~ESDHC_MIX_CTRL_EXE_TUNE;
>  			}
> @@ -964,6 +971,8 @@ sdhci_esdhc_imx_probe_dt(struct platform_device *pdev,
>  	if (gpio_is_valid(boarddata->wp_gpio))
>  		boarddata->wp_type = ESDHC_WP_GPIO;
>  
> +	of_property_read_u32(np, "fsl,tuning-step", &boarddata->tuning_step);
> +
>  	if (of_find_property(np, "no-1-8-v", NULL))
>  		boarddata->support_vsel = false;
>  	else
> diff --git a/include/linux/platform_data/mmc-esdhc-imx.h b/include/linux/platform_data/mmc-esdhc-imx.h
> index e1571ef..95ccab3 100644
> --- a/include/linux/platform_data/mmc-esdhc-imx.h
> +++ b/include/linux/platform_data/mmc-esdhc-imx.h
> @@ -45,5 +45,6 @@ struct esdhc_platform_data {
>  	int max_bus_width;
>  	bool support_vsel;
>  	unsigned int delay_line;
> +	unsigned int tuning_step;       /* The delay cell steps in tuning procedure */
>  };
>  #endif /* __ASM_ARCH_IMX_ESDHC_H */
> -- 
> 1.9.1
> 


From aisheng.dong at freescale.com  Fri Aug  7 00:50:51 2015
From: aisheng.dong at freescale.com (Dong Aisheng)
Date: Fri, 7 Aug 2015 15:50:51 +0800
Subject: [PATCH v4 6/6] mmc: sdhci-esdhc-imx: set back the
 burst_length_enable bit to 1
In-Reply-To: <1438771122-8601-7-git-send-email-haibo.chen@freescale.com>
References: <1438771122-8601-1-git-send-email-haibo.chen@freescale.com>
 <1438771122-8601-7-git-send-email-haibo.chen@freescale.com>
Message-ID: <20150807075050.GC6935@shlinux1.ap.freescale.net>

On Wed, Aug 05, 2015 at 06:38:42PM +0800, Haibo Chen wrote:
> Currently we find that if a usdhc is choosed to boot system, then ROM
> code will set the burst length enable bit of this usdhc as 0.
> 
> This will make performance drop a lot if this usdhc's burst length is
> configed. So this patch set back the burst_length_enable bit as 1,
> which is the default value, and means burst length is enabled for INCR.
> 

This patch should be put before patch 5 to avoid function break, right?
[PATCH v4 5/6] mmc: sdhci-esdhc-imx: change default watermark level and burst length

Other than that, this patch looks good to me.

Regards
Dong Aisheng

> Signed-off-by: Haibo Chen <haibo.chen at freescale.com>
> ---
>  drivers/mmc/host/sdhci-esdhc-imx.c | 16 ++++++++++++++++
>  1 file changed, 16 insertions(+)
> 
> diff --git a/drivers/mmc/host/sdhci-esdhc-imx.c b/drivers/mmc/host/sdhci-esdhc-imx.c
> index 97aa944..3334762 100644
> --- a/drivers/mmc/host/sdhci-esdhc-imx.c
> +++ b/drivers/mmc/host/sdhci-esdhc-imx.c
> @@ -32,6 +32,7 @@
>  #include "sdhci-esdhc.h"
>  
>  #define	ESDHC_CTRL_D3CD			0x08
> +#define ESDHC_BURST_LEN_EN_INCR		(1 << 27)
>  /* VENDOR SPEC register */
>  #define ESDHC_VENDOR_SPEC		0xc0
>  #define  ESDHC_VENDOR_SPEC_SDIO_QUIRK	(1 << 1)
> @@ -1165,6 +1166,21 @@ static int sdhci_esdhc_imx_probe(struct platform_device *pdev)
>  		host->quirks2 |= SDHCI_QUIRK2_PRESET_VALUE_BROKEN;
>  		host->mmc->caps |= MMC_CAP_1_8V_DDR;
>  
> +		/*
> +		 * ROM code will change the bit burst_length_enable setting
> +		 * to zero if this usdhc is choosed to boot system. Change
> +		 * it back here, otherwise it will impact the performance a
> +		 * lot. This bit is used to enable/disable the burst length
> +		 * for the external AHB2AXI bridge, it's usefully especially
> +		 * for INCR transfer because without burst length indicator,
> +		 * the AHB2AXI bridge does not know the burst length in
> +		 * advance. And without burst length indicator, AHB INCR
> +		 * transfer can only be converted to singles on the AXI side.
> +		 */
> +		writel(readl(host->ioaddr + SDHCI_HOST_CONTROL)
> +			| ESDHC_BURST_LEN_EN_INCR,
> +			host->ioaddr + SDHCI_HOST_CONTROL);
> +
>  		if (!(imx_data->socdata->flags & ESDHC_FLAG_HS200))
>  			host->quirks2 |= SDHCI_QUIRK2_BROKEN_HS200;
>  
> -- 
> 1.9.1
> 


From a.hajda at samsung.com  Fri Aug  7 00:59:22 2015
From: a.hajda at samsung.com (Andrzej Hajda)
Date: Fri, 07 Aug 2015 09:59:22 +0200
Subject: [PATCH 16/31] net/cavium/liquidio: use kmemdup rather than duplicating
 its implementation
In-Reply-To: <1438934377-4922-1-git-send-email-a.hajda@samsung.com>
References: <1438934377-4922-1-git-send-email-a.hajda@samsung.com>
Message-ID: <1438934377-4922-17-git-send-email-a.hajda@samsung.com>

The patch was generated using fixed coccinelle semantic patch
scripts/coccinelle/api/memdup.cocci [1].

[1]: http://permalink.gmane.org/gmane.linux.kernel/2014320

Signed-off-by: Andrzej Hajda <a.hajda at samsung.com>
---
 drivers/net/ethernet/cavium/liquidio/octeon_device.c | 4 +---
 1 file changed, 1 insertion(+), 3 deletions(-)

diff --git a/drivers/net/ethernet/cavium/liquidio/octeon_device.c b/drivers/net/ethernet/cavium/liquidio/octeon_device.c
index f67641a..8e23e3f 100644
--- a/drivers/net/ethernet/cavium/liquidio/octeon_device.c
+++ b/drivers/net/ethernet/cavium/liquidio/octeon_device.c
@@ -602,12 +602,10 @@ int octeon_download_firmware(struct octeon_device *oct, const u8 *data,
 	snprintf(oct->fw_info.liquidio_firmware_version, 32, "LIQUIDIO: %s",
 		 h->version);
 
-	buffer = kmalloc(size, GFP_KERNEL);
+	buffer = kmemdup(data, size, GFP_KERNEL);
 	if (!buffer)
 		return -ENOMEM;
 
-	memcpy(buffer, data, size);
-
 	p = buffer + sizeof(struct octeon_firmware_file_header);
 
 	/* load all images */
-- 
1.9.1



From a.hajda at samsung.com  Fri Aug  7 00:59:07 2015
From: a.hajda at samsung.com (Andrzej Hajda)
Date: Fri, 07 Aug 2015 09:59:07 +0200
Subject: [PATCH 01/31] arch/arm/mach-lpc32xx: use kmemdup rather than
 duplicating its implementation
In-Reply-To: <1438934377-4922-1-git-send-email-a.hajda@samsung.com>
References: <1438934377-4922-1-git-send-email-a.hajda@samsung.com>
Message-ID: <1438934377-4922-2-git-send-email-a.hajda@samsung.com>

The patch was generated using fixed coccinelle semantic patch
scripts/coccinelle/api/memdup.cocci [1].

[1]: http://permalink.gmane.org/gmane.linux.kernel/2014320

Signed-off-by: Andrzej Hajda <a.hajda at samsung.com>
---
 arch/arm/mach-lpc32xx/pm.c | 7 ++-----
 1 file changed, 2 insertions(+), 5 deletions(-)

diff --git a/arch/arm/mach-lpc32xx/pm.c b/arch/arm/mach-lpc32xx/pm.c
index 207e812..dd3a432 100644
--- a/arch/arm/mach-lpc32xx/pm.c
+++ b/arch/arm/mach-lpc32xx/pm.c
@@ -87,7 +87,8 @@ static int lpc32xx_pm_enter(suspend_state_t state)
 	void *iram_swap_area;
 
 	/* Allocate some space for temporary IRAM storage */
-	iram_swap_area = kmalloc(lpc32xx_sys_suspend_sz, GFP_KERNEL);
+	iram_swap_area = kmemdup((void *)TEMP_IRAM_AREA,
+				 lpc32xx_sys_suspend_sz, GFP_KERNEL);
 	if (!iram_swap_area) {
 		printk(KERN_ERR
 		       "PM Suspend: cannot allocate memory to save portion "
@@ -95,10 +96,6 @@ static int lpc32xx_pm_enter(suspend_state_t state)
 		return -ENOMEM;
 	}
 
-	/* Backup a small area of IRAM used for the suspend code */
-	memcpy(iram_swap_area, (void *) TEMP_IRAM_AREA,
-		lpc32xx_sys_suspend_sz);
-
 	/*
 	 * Copy code to suspend system into IRAM. The suspend code
 	 * needs to run from IRAM as DRAM may no longer be available
-- 
1.9.1



From djkurtz at chromium.org  Fri Aug  7 01:05:33 2015
From: djkurtz at chromium.org (Daniel Kurtz)
Date: Fri, 7 Aug 2015 16:05:33 +0800
Subject: [PATCH v6 7/9] clk: mediatek: Add subsystem clocks of MT8173
In-Reply-To: <1438914018.29334.6.camel@mtksdaap41>
References: <1438676218-11310-1-git-send-email-jamesjj.liao@mediatek.com>
 <1438676218-11310-8-git-send-email-jamesjj.liao@mediatek.com>
 <20150805064605.GZ18700@pengutronix.de> <1438849431.27884.9.camel@mtksdaap41>
 <20150806085354.GN18700@pengutronix.de> <1438851644.27884.21.camel@mtksdaap41>
 <CAGS+omAAYZyZJ4+eSdu2jmwThvHg1YpVoehui_cqNp4A5fURWg@mail.gmail.com>
 <20150806102059.GQ18700@pengutronix.de> <1438914018.29334.6.camel@mtksdaap41>
Message-ID: <CAGS+omBDaP1b-zNJ7SaX89Mt5jhZEp_kDh7Pytsax0d=V++MEA@mail.gmail.com>

On Fri, Aug 7, 2015 at 10:20 AM, James Liao <jamesjj.liao at mediatek.com> wrote:
> Hi Sascha,
>
> On Thu, 2015-08-06 at 12:20 +0200, Sascha Hauer wrote:
>> On Thu, Aug 06, 2015 at 05:13:21PM +0800, Daniel Kurtz wrote:
>> > On Thu, Aug 6, 2015 at 5:00 PM, James Liao <jamesjj.liao at mediatek.com> wrote:
>> > > Hi Sascha,
>> > >
>> > > On Thu, 2015-08-06 at 10:53 +0200, Sascha Hauer wrote:
>> > >> On Thu, Aug 06, 2015 at 04:23:51PM +0800, James Liao wrote:
>> > >> > On Wed, 2015-08-05 at 08:46 +0200, Sascha Hauer wrote:
>> > >> > > On Tue, Aug 04, 2015 at 04:16:56PM +0800, James Liao wrote:
>> > >> > > >  static const struct mtk_fixed_clk fixed_clks[] __initconst = {
>> > >> > > >         FIXED_CLK(CLK_TOP_CLKPH_MCK_O, "clkph_mck_o", "clk26m", 400 * MHZ),
>> > >> > > >         FIXED_CLK(CLK_TOP_USB_SYSPLL_125M, "usb_syspll_125m", "clk26m", 125 * MHZ),
>> > >> > > > +       FIXED_CLK(CLK_TOP_DSI0_DIG, "dsi0_dig", "clk26m", 130 * MHZ),
>> > >> > > > +       FIXED_CLK(CLK_TOP_DSI1_DIG, "dsi1_dig", "clk26m", 130 * MHZ),
>> > >> > > > +       FIXED_CLK(CLK_TOP_LVDS_PXL, "lvds_pxl", "lvdspll", 148.5 * MHZ),
>> > >> > > > +       FIXED_CLK(CLK_TOP_LVDS_CTS, "lvds_cts", "lvdspll", 51.975 * MHZ),
>> > >> > >
>> > >> > > I would expect 51975 * KHZ here to avoid fractional numbers. Probably
>> > >> > > gcc calculates that during compile time so this will work as expected,
>> > >> > > still I'm not sure this is good style to use fractional numbers here.
>> > >> >
>> > >> > As I know all constants will be calculated in compile time, so there
>> > >> > should be no difference between 51.975 * MHZ and 51975 * KHz.
>> > >> >
>> > >> > > Anyway, on my system lvdspll is running at 150MHz. Are you sure there is
>> > >> > > a clock derived from this running at 148.5MHz? Is it really correct to
>> > >> > > use a fixed clock here or should it rather be lvdspll directly?
>> > >> >
>> > >> > Here is the clock hierarchy between lvdspll and lvds_pxl:
>> > >> >
>> > >> >             --------       AD_VPLL_DPIX_CK  --------   lvds_pxl  -----
>> > >> >            |        |--------------------->|        |---------->|
>> > >> >            |        |                      | cksys  |           |
>> > >> > LVDSPLL -->| LVDSTX |                      | buffer |           | MMSYS
>> > >> >            |        | AD_LVDSTX_CLKDIG_CTS | test   |  lvds_cts |
>> > >> >            |        |--------------------->|        |---------->|
>> > >> >             --------                        --------             -----
>> > >> >
>> > >> > Some clocks and blocks are not modeled into CCF. But we prefer to enable
>> > >> > lvdspll before enabling lvds_pxl. So I modeled lvds_pxl (and lvds_cts)
>> > >> > as a fixed-rate clock with a source from lvdspll.
>> > >> >
>> > >> > The frequency of these fixed-rate clocks (such as 148.5 MHz) are typical
>> > >> > rate. In fact, we don't care about the actual rate of these clocks. We
>> > >> > just care about the enable / disable sequence of them.
>> > >>
>> > >> Please either use the real rate or 0 (along with a explaining why). Using
>> > >> a frequency with four to five significant digits makes me think that the
>> > >> actual rate is very important.
>> > >
>> > > Oops, your suggestion is much different from Daniel's.
>> > >
>> > > Daniel, could you help to comment about how we model these clocks?
>> >
>> > First of all, for clocks where the rate doesn't matter, it doesn't
>> > matters to what rate we set the clock.
>> >
>> > As for the color of our shed, "the designer says these are the typical
>> > rates" sounds good enough to me for a "real rate", so I prefer using
>> > the rates in James' patch.
>> >
>> > If not sure what Sascha's concern is, but if he insists on 0, I'm fine
>> > with that too.
>>
>> I only find it confusing. I'd expect either the correct rate or an
>> obviously dummy rate. Whatever we choose a comment explaining the
>> background would really help here. Otherwise we won't know later
>> whether this 148.5 MHz rate was introduced because a) The consumers
>> depend on this rate being reported, b) It really is the correct rate or
>> c) we don't care about the rate.
>
> So the proper setting should be:
>
> clk_name,          parent,    rate
> -------------------------------------
> "clkph_mck_o",     "clk26m",  0
> "usb_syspll_125m", "clk26m",  125 * MHZ
> "dsi0_dig",        "clk26m",  0
> "dsi1_dig",        "clk26m",  0
> "lvds_pxl",        "lvdspll", 0
> "lvds_cts",        "lvdspll", 0
>
> usb_syspll_125m will keep in 125 MHz event in different products.Others
> may be changed by DRAM or display settings.
>
> Daniel, do you think it's OK to model these clocks like above?

Yes, I am fine with this.

>
>
> Best regards,
>
> James
>
>


From djkurtz at chromium.org  Fri Aug  7 01:06:51 2015
From: djkurtz at chromium.org (Daniel Kurtz)
Date: Fri, 7 Aug 2015 16:06:51 +0800
Subject: [PATCH v6 7/9] clk: mediatek: Add subsystem clocks of MT8173
In-Reply-To: <CAGS+omBDaP1b-zNJ7SaX89Mt5jhZEp_kDh7Pytsax0d=V++MEA@mail.gmail.com>
References: <1438676218-11310-1-git-send-email-jamesjj.liao@mediatek.com>
 <1438676218-11310-8-git-send-email-jamesjj.liao@mediatek.com>
 <20150805064605.GZ18700@pengutronix.de> <1438849431.27884.9.camel@mtksdaap41>
 <20150806085354.GN18700@pengutronix.de> <1438851644.27884.21.camel@mtksdaap41>
 <CAGS+omAAYZyZJ4+eSdu2jmwThvHg1YpVoehui_cqNp4A5fURWg@mail.gmail.com>
 <20150806102059.GQ18700@pengutronix.de> <1438914018.29334.6.camel@mtksdaap41>
 <CAGS+omBDaP1b-zNJ7SaX89Mt5jhZEp_kDh7Pytsax0d=V++MEA@mail.gmail.com>
Message-ID: <CAGS+omAizzehDjUx+r0JZRNo75W56zKiDq8kz6PUT9f2fdE7=w@mail.gmail.com>

On Fri, Aug 7, 2015 at 4:05 PM, Daniel Kurtz <djkurtz at chromium.org> wrote:
> On Fri, Aug 7, 2015 at 10:20 AM, James Liao <jamesjj.liao at mediatek.com> wrote:
>> Hi Sascha,
>>
>> On Thu, 2015-08-06 at 12:20 +0200, Sascha Hauer wrote:
>>> On Thu, Aug 06, 2015 at 05:13:21PM +0800, Daniel Kurtz wrote:
>>> > On Thu, Aug 6, 2015 at 5:00 PM, James Liao <jamesjj.liao at mediatek.com> wrote:
>>> > > Hi Sascha,
>>> > >
>>> > > On Thu, 2015-08-06 at 10:53 +0200, Sascha Hauer wrote:
>>> > >> On Thu, Aug 06, 2015 at 04:23:51PM +0800, James Liao wrote:
>>> > >> > On Wed, 2015-08-05 at 08:46 +0200, Sascha Hauer wrote:
>>> > >> > > On Tue, Aug 04, 2015 at 04:16:56PM +0800, James Liao wrote:
>>> > >> > > >  static const struct mtk_fixed_clk fixed_clks[] __initconst = {
>>> > >> > > >         FIXED_CLK(CLK_TOP_CLKPH_MCK_O, "clkph_mck_o", "clk26m", 400 * MHZ),
>>> > >> > > >         FIXED_CLK(CLK_TOP_USB_SYSPLL_125M, "usb_syspll_125m", "clk26m", 125 * MHZ),
>>> > >> > > > +       FIXED_CLK(CLK_TOP_DSI0_DIG, "dsi0_dig", "clk26m", 130 * MHZ),
>>> > >> > > > +       FIXED_CLK(CLK_TOP_DSI1_DIG, "dsi1_dig", "clk26m", 130 * MHZ),
>>> > >> > > > +       FIXED_CLK(CLK_TOP_LVDS_PXL, "lvds_pxl", "lvdspll", 148.5 * MHZ),
>>> > >> > > > +       FIXED_CLK(CLK_TOP_LVDS_CTS, "lvds_cts", "lvdspll", 51.975 * MHZ),
>>> > >> > >
>>> > >> > > I would expect 51975 * KHZ here to avoid fractional numbers. Probably
>>> > >> > > gcc calculates that during compile time so this will work as expected,
>>> > >> > > still I'm not sure this is good style to use fractional numbers here.
>>> > >> >
>>> > >> > As I know all constants will be calculated in compile time, so there
>>> > >> > should be no difference between 51.975 * MHZ and 51975 * KHz.
>>> > >> >
>>> > >> > > Anyway, on my system lvdspll is running at 150MHz. Are you sure there is
>>> > >> > > a clock derived from this running at 148.5MHz? Is it really correct to
>>> > >> > > use a fixed clock here or should it rather be lvdspll directly?
>>> > >> >
>>> > >> > Here is the clock hierarchy between lvdspll and lvds_pxl:
>>> > >> >
>>> > >> >             --------       AD_VPLL_DPIX_CK  --------   lvds_pxl  -----
>>> > >> >            |        |--------------------->|        |---------->|
>>> > >> >            |        |                      | cksys  |           |
>>> > >> > LVDSPLL -->| LVDSTX |                      | buffer |           | MMSYS
>>> > >> >            |        | AD_LVDSTX_CLKDIG_CTS | test   |  lvds_cts |
>>> > >> >            |        |--------------------->|        |---------->|
>>> > >> >             --------                        --------             -----
>>> > >> >
>>> > >> > Some clocks and blocks are not modeled into CCF. But we prefer to enable
>>> > >> > lvdspll before enabling lvds_pxl. So I modeled lvds_pxl (and lvds_cts)
>>> > >> > as a fixed-rate clock with a source from lvdspll.
>>> > >> >
>>> > >> > The frequency of these fixed-rate clocks (such as 148.5 MHz) are typical
>>> > >> > rate. In fact, we don't care about the actual rate of these clocks. We
>>> > >> > just care about the enable / disable sequence of them.
>>> > >>
>>> > >> Please either use the real rate or 0 (along with a explaining why). Using
>>> > >> a frequency with four to five significant digits makes me think that the
>>> > >> actual rate is very important.
>>> > >
>>> > > Oops, your suggestion is much different from Daniel's.
>>> > >
>>> > > Daniel, could you help to comment about how we model these clocks?
>>> >
>>> > First of all, for clocks where the rate doesn't matter, it doesn't
>>> > matters to what rate we set the clock.
>>> >
>>> > As for the color of our shed, "the designer says these are the typical
>>> > rates" sounds good enough to me for a "real rate", so I prefer using
>>> > the rates in James' patch.
>>> >
>>> > If not sure what Sascha's concern is, but if he insists on 0, I'm fine
>>> > with that too.
>>>
>>> I only find it confusing. I'd expect either the correct rate or an
>>> obviously dummy rate. Whatever we choose a comment explaining the
>>> background would really help here. Otherwise we won't know later
>>> whether this 148.5 MHz rate was introduced because a) The consumers
>>> depend on this rate being reported, b) It really is the correct rate or
>>> c) we don't care about the rate.
>>
>> So the proper setting should be:
>>
>> clk_name,          parent,    rate
>> -------------------------------------
>> "clkph_mck_o",     "clk26m",  0
>> "usb_syspll_125m", "clk26m",  125 * MHZ
>> "dsi0_dig",        "clk26m",  0
>> "dsi1_dig",        "clk26m",  0
>> "lvds_pxl",        "lvdspll", 0
>> "lvds_cts",        "lvdspll", 0
>>
>> usb_syspll_125m will keep in 125 MHz event in different products.Others
>> may be changed by DRAM or display settings.
>>
>> Daniel, do you think it's OK to model these clocks like above?
>
> Yes, I am fine with this.

Oh, but Sascha's main point is that, whatever we choose to do, please
document it to make it clear why we are setting these clocks to the
value we choose.

-Dan

>
>>
>>
>> Best regards,
>>
>> James
>>
>>


From tomasz.nowicki at linaro.org  Fri Aug  7 01:09:04 2015
From: tomasz.nowicki at linaro.org (Tomasz Nowicki)
Date: Fri, 07 Aug 2015 10:09:04 +0200
Subject: [PATCH 2/2] net, thunder, bgx: Add support for ACPI binding.
In-Reply-To: <1438907590-29649-3-git-send-email-ddaney.cavm@gmail.com>
References: <1438907590-29649-1-git-send-email-ddaney.cavm@gmail.com>
 <1438907590-29649-3-git-send-email-ddaney.cavm@gmail.com>
Message-ID: <55C467A0.4020601@linaro.org>

On 07.08.2015 02:33, David Daney wrote:
> From: David Daney <david.daney at cavium.com>
>
> Find out which PHYs belong to which BGX instance in the ACPI way.
>
> Set the MAC address of the device as provided by ACPI tables. This is
> similar to the implementation for devicetree in
> of_get_mac_address(). The table is searched for the device property
> entries "mac-address", "local-mac-address" and "address" in that
> order. The address is provided in a u64 variable and must contain a
> valid 6 bytes-len mac addr.
>
> Based on code from: Narinder Dhillon <ndhillon at cavium.com>
>                      Tomasz Nowicki <tomasz.nowicki at linaro.org>
>                      Robert Richter <rrichter at cavium.com>
>
> Signed-off-by: Tomasz Nowicki <tomasz.nowicki at linaro.org>
> Signed-off-by: Robert Richter <rrichter at cavium.com>
> Signed-off-by: David Daney <david.daney at cavium.com>
> ---
>   drivers/net/ethernet/cavium/thunder/thunder_bgx.c | 137 +++++++++++++++++++++-
>   1 file changed, 135 insertions(+), 2 deletions(-)
>
> diff --git a/drivers/net/ethernet/cavium/thunder/thunder_bgx.c b/drivers/net/ethernet/cavium/thunder/thunder_bgx.c
> index 615b2af..2056583 100644
> --- a/drivers/net/ethernet/cavium/thunder/thunder_bgx.c
> +++ b/drivers/net/ethernet/cavium/thunder/thunder_bgx.c
> @@ -6,6 +6,7 @@
>    * as published by the Free Software Foundation.
>    */
>
> +#include <linux/acpi.h>
>   #include <linux/module.h>
>   #include <linux/interrupt.h>
>   #include <linux/pci.h>
> @@ -26,7 +27,7 @@
>   struct lmac {
>   	struct bgx		*bgx;
>   	int			dmac;
> -	unsigned char		mac[ETH_ALEN];
> +	u8			mac[ETH_ALEN];
>   	bool			link_up;
>   	int			lmacid; /* ID within BGX */
>   	int			lmacid_bd; /* ID on board */
> @@ -835,6 +836,133 @@ static void bgx_get_qlm_mode(struct bgx *bgx)
>   	}
>   }
>
> +#ifdef CONFIG_ACPI
> +
> +static int bgx_match_phy_id(struct device *dev, void *data)
> +{
> +	struct phy_device *phydev = to_phy_device(dev);
> +	u32 *phy_id = data;
> +
> +	if (phydev->addr == *phy_id)
> +		return 1;
> +
> +	return 0;
> +}
> +
> +static const char * const addr_propnames[] = {
> +	"mac-address",
> +	"local-mac-address",
> +	"address",
> +};
> +
> +static int acpi_get_mac_address(struct acpi_device *adev, u8 *dst)
> +{
> +	const union acpi_object *prop;
> +	u64 mac_val;
> +	u8 mac[ETH_ALEN];
> +	int i, j;
> +	int ret;
> +
> +	for (i = 0; i < ARRAY_SIZE(addr_propnames); i++) {
> +		ret = acpi_dev_get_property(adev, addr_propnames[i],
> +					    ACPI_TYPE_INTEGER, &prop);
> +		if (ret)
> +			continue;
> +
> +		mac_val = prop->integer.value;
> +
> +		if (mac_val & (~0ULL << 48))
> +			continue;	/* more than 6 bytes */
> +
> +		for (j = 0; j < ARRAY_SIZE(mac); j++)
> +			mac[j] = (u8)(mac_val >> (8 * j));
> +		if (!is_valid_ether_addr(mac))
> +			continue;
> +
> +		memcpy(dst, mac, ETH_ALEN);
> +
> +		return 0;
> +	}
> +
> +	return ret ? ret : -EINVAL;
> +}
> +
> +static acpi_status bgx_acpi_register_phy(acpi_handle handle,
> +					 u32 lvl, void *context, void **rv)
> +{
> +	struct acpi_reference_args args;
> +	const union acpi_object *prop;
> +	struct bgx *bgx = context;
> +	struct acpi_device *adev;
> +	struct device *phy_dev;
> +	u32 phy_id;
> +
> +	if (acpi_bus_get_device(handle, &adev))
> +		goto out;
> +
> +	SET_NETDEV_DEV(&bgx->lmac[bgx->lmac_count].netdev, &bgx->pdev->dev);
> +
> +	acpi_get_mac_address(adev, bgx->lmac[bgx->lmac_count].mac);
> +
> +	bgx->lmac[bgx->lmac_count].lmacid = bgx->lmac_count;
> +
> +	if (acpi_dev_get_property_reference(adev, "phy-handle", 0, &args))
> +		goto out;
> +
> +	if (acpi_dev_get_property(args.adev, "phy-channel", ACPI_TYPE_INTEGER, &prop))
> +		goto out;
> +
> +	phy_id = prop->integer.value;
> +
> +	phy_dev = bus_find_device(&mdio_bus_type, NULL, (void *)&phy_id,
> +				  bgx_match_phy_id);
> +	if (!phy_dev)
> +		goto out;
> +
> +	bgx->lmac[bgx->lmac_count].phydev = to_phy_device(phy_dev);
> +out:
> +	bgx->lmac_count++;
> +	return AE_OK;
> +}
> +
> +static acpi_status bgx_acpi_match_id(acpi_handle handle, u32 lvl,
> +				     void *context, void **ret_val)
> +{
> +	struct acpi_buffer string = { ACPI_ALLOCATE_BUFFER, NULL };
> +	struct bgx *bgx = context;
> +	char bgx_sel[5];
> +
> +	snprintf(bgx_sel, 5, "BGX%d", bgx->bgx_id);
> +	if (ACPI_FAILURE(acpi_get_name(handle, ACPI_SINGLE_NAME, &string))) {
> +		pr_warn("Invalid link device\n");
> +		return AE_OK;
> +	}
> +
> +	if (strncmp(string.pointer, bgx_sel, 4))
> +		return AE_OK;
> +
> +	acpi_walk_namespace(ACPI_TYPE_DEVICE, handle, 1,
> +			    bgx_acpi_register_phy, NULL, bgx, NULL);
> +
> +	kfree(string.pointer);
> +	return AE_CTRL_TERMINATE;
> +}
> +
> +static int bgx_init_acpi_phy(struct bgx *bgx)
> +{
> +	acpi_get_devices(NULL, bgx_acpi_match_id, bgx, (void **)NULL);
> +	return 0;
> +}
> +
> +#else
> +
> +static int bgx_init_acpi_phy(struct bgx *bgx)
> +{
> +	return -ENODEV;
> +}
> +
> +#endif /* CONFIG_ACPI */
> +
>   #if IS_ENABLED(CONFIG_OF_MDIO)
>
>   static int bgx_init_of_phy(struct bgx *bgx)
> @@ -882,7 +1010,12 @@ static int bgx_init_of_phy(struct bgx *bgx)
>
>   static int bgx_init_phy(struct bgx *bgx)
>   {
> -	return bgx_init_of_phy(bgx);
> +	int err = bgx_init_of_phy(bgx);
> +
> +	if (err != -ENODEV)
> +		return err;
> +
> +	return bgx_init_acpi_phy(bgx);
>   }
>

If kernel can work with DT and ACPI (both compiled in), it should take 
only one path instead of probing DT and ACPI sequentially. How about:

@@ -902,10 +925,9 @@ static int bgx_probe(struct pci_dev *pdev, const 
struct pci_device_id *ent)
  	bgx_vnic[bgx->bgx_id] = bgx;
  	bgx_get_qlm_mode(bgx);

-	snprintf(bgx_sel, 5, "bgx%d", bgx->bgx_id);
-	np = of_find_node_by_name(NULL, bgx_sel);
-	if (np)
-		bgx_init_of(bgx, np);
+	err = acpi_disabled ? bgx_init_of_phy(bgx) : bgx_init_acpi_phy(bgx);
+	if (err)
+		goto err_enable;

  	bgx_init_hw(bgx);


Regards,
Tomasz


From jroedel at suse.de  Fri Aug  7 01:17:46 2015
From: jroedel at suse.de (Joerg Roedel)
Date: Fri, 7 Aug 2015 10:17:46 +0200
Subject: [GIT PULL] iommu/arm-smmu: Updates for 4.3
In-Reply-To: <20150806150749.GF25483@arm.com>
References: <20150806150749.GF25483@arm.com>
Message-ID: <20150807081429.GD10112@suse.de>

On Thu, Aug 06, 2015 at 04:07:50PM +0100, Will Deacon wrote:
> The following changes since commit cbfe8fa6cd672011c755c3cd85c9ffd4e2d10a6f:
> 
>   Linux 4.2-rc4 (2015-07-26 12:26:21 -0700)
> 
> are available in the git repository at:
> 
>   git://git.kernel.org/pub/scm/linux/kernel/git/will/linux.git for-joerg/arm-smmu/updates

Pulled, thanks Will.



From martin at sperl.org  Fri Aug  7 01:25:40 2015
From: martin at sperl.org (Martin Sperl)
Date: Fri, 07 Aug 2015 10:25:40 +0200
Subject: [RFC PATCH 1/5] spi: introduce flag for memory mapped read
In-Reply-To: <20150806213340.GK7576@n2100.arm.linux.org.uk>
References: <20150805115013.GJ20873@sirena.org.uk>
 <CAOMqctQXwcHyiWBwtugSDSE_k65qrNfrwnhjQMDJkLoJMmGzUw@mail.gmail.com>
 <20150805124412.GN20873@sirena.org.uk>
 <CAOMqctS9Y5FxpUCCJew6+cnjH5iTvbzkH3g-8yrXs4OuS2pSGA@mail.gmail.com>
 <20150806090202.GO20873@sirena.org.uk>
 <CAOMqctQZRZ4zG_yYy=CeX3DX4NVNWN1COP4Q-2YvMun9xYOA7g@mail.gmail.com>
 <20150806102225.GI7576@n2100.arm.linux.org.uk> <55C35233.2000105@ti.com>
 <20150806135129.GJ7576@n2100.arm.linux.org.uk>
 <CAMuHMdWWDwZ=ziGQXFCnOX8pErXpsEi533J73_Hh=sEqq4hR6Q@mail.gmail.com>
 <20150806213340.GK7576@n2100.arm.linux.org.uk>
Message-ID: <55C46B84.3010304@sperl.org>

On 8/6/2015 23:33, Russell King - ARM Linux wrote:
> On Thu, Aug 06, 2015 at 06:14:00PM +0200, Geert Uytterhoeven wrote:
>>
>> Irrespective of the dummy bytes.
>> What if the spi device is not a FLASH ROM, but some other device,
>> which receives a data packet that accidentally looks like an m25p80 READ
>> command?
> Well, for the most part it looks like it should still work, but there
> could be a gotcha, but first, let's get rid of a myth there.
>
> The QSPI is _not_ specific to the M25P80.  The manual says nothing
> about being specific to that device.  What it says is that it's for
> SPI NOR memory.  It will work with bus widths of 1, 2 or 4 data lines,
> so it probably works with non-M25P80 SPI NOR devices too - and the fact
> that the read and write commands are completely programmable suggests
> that using it with SPI NOR devices which do not use the M25P80 read
> command value is intended.
>
>
> The SFI is a state machine based translator which sits behind the SPI
> interface (look at the manual).  It sequence sthe SPI bus through a
> series of standard SPI states which happen to be the states I detailed
> above.
>
> Now, the first byte of the SFI-generated SPI message can be programmed
> to any 8 bit value.  So the first byte of the SPI message is totally
> under software control.  The next one to four bytes which comprise the
> "address" can be controlled to by deciding where in the memory map to
> start reading from.  Hence, the value of those bytes is also totally
> under software control.  The number of dummy bytes can be programmed
> too.  So far so good.
>
> So, if we know that we have a SPI message which says "send 0x01 0x20
> 0x30, send one dummy byte, read 32 bytes", if we program the SFI to
> send a read command as 0x01, program an address length of 2 bytes
> with one dummy byte, and then read the next 32 bytes at the appropriate
> offset in the memory mapping to cause the next two bytes to be 0x20,
> 0x30, then what we end up with on the bus is:
>
> 	send 0x01, 0x20, 0x30
> 	send one dummy byte
>
> That much is good, but now is the problem - how does the SFI know that
> we're going to require to read 32 bytes?  I think the answer to that
> is that it doesn't know, so it probably just reads the number of bytes
> which the access on the SoC bus is asking for, which makes it
> indeterminant from a software point of view to control how many bytes
> will be read without provoking another "send 0x01, next address, dummy
> byte" sequence.
>
> So, I'm now on the side of not parsing commands in the SPI driver, and
> back on the idea that this needs to be handled in some other manner
> which doesn't involve polluting the SPI core with flag-hacks.
>
So I see 2 distinct options:

Have the nor driver modified to run SPI commands and then ask the
SPI framework (and driver) to switch into mmap mode:

Would probably look something like this inside the nor driver:
    /* lock spi bus for other activities */
    spi_bus_lock(spi);
    /* send the "configuration" for mmap */
    t[0].tx_buf = flash->command;
    t[0].len = m25p_cmdsz(nor);
    spi_message_add_tail(&t[0], &m);
    t[1].tx_buf = dummy_buffer;
    t[1].len = dummy;
    spi_message_add_tail(&t[1], &m);
    spi_sync(spi, &m);
    /* switch to mmap mode */
    spi->mode |= SPI_MMAP;
    spi_setup(spi);
    /* run the mmapped transfers bypassing the spi-layer */
    memcpy(...)
    /* open questions here: which address range
     * and how to detect if transfer is done
*/
/* restore back to "normal" mode */
    spi->mode &= ~SPI_MMAP;
    spi_setup(spi);
    /* unlock spi bus for other activities */
    spi_bus_unlock(spi);

The downside is that it requires modification in several places
(nor-framework, spi-framework plus the driver) and it would not
be generic enough...

IMO such a situation is feasible if we only got a single device
on the spi-bus, but leaves a lot of questions open...
Alternatively we could create an additional api.

On the other end of spectrum could be a solution where the
spi-master driverwould have the opportunity to query the
device-tree for specific propertiesduring the spi_add_device
phase - in this case querying the followingproperty in the
device-tree:
   spi-master-XXX,use-mmap-cmd-mode = <0x08 0x38>;
to implement mmap-mode for commands 0x08 and 0x38.

Maybe we would want to also encode the number of address bytes
to send per command without hardcoding those values explicitly:
so maybe something like:
   spi-master-XXX,use-mmap-cmd-mode = <0x08 2> <0x38 3>;

Obviously these would need to get documented in the bindings
documentation of that driver.

Alternatively we could also introduce generic alternate modes
for the driver(similar to GPIO - ALT modes), but that would be
less transparent and more hard-coded...

In the end this would mean that from the nor framework side
therewould be no change at all - it still would be issuing
something like this:
    /* send the "normal" block read command */
    t[0].tx_buf = flash->command;
    /* note that the address would be encoded here */
    t[0].len = m25p_cmdsz(nor);
    spi_message_add_tail(&t[0], &m);
    /* dummy bytes could also get added to the above transfer */
    t[1].tx_buf = dummy_buffer;
    t[1].len = dummy;
    spi_message_add_tail(&t[1], &m);
    /* the real transfer */
    t[2].rx_buf = read_buffer;
    t[2].len = transfer_size;
    spi_message_add_tail(&t[2], &m);
    spi_sync(spi, &m);

On the spi-master side the driver would need to run:
*  if the spi-message (in this case the first byte) matches
    the "allowed" command pattern:
   * "setup" device in normal mode preparing the transfer engine
   * mode-switch to "mmapped" mode
   * copy via mmapped mode (via DMA to avoid blocking the CPU?)
   * return to "normal" mode
* else
   * run in "normal" spi mode.
(obviously it would be a bit more complicated that that).

Note that a discussion in regards to spi-master methods called
duringspi_add_device has just come up a few days ago in a
slightly differentcontext - forcing to always/never use DMA mode
for a specific spi-device on the bus (as well as tuning other
parameters per device).

Obviously the additional properties should describe required
HW behaviour and not tune the driver parameters - sys should be
used for those, but also for implementing those sys parameters we
would need those above "hooks"...

Just an idea.



From peter.chen at freescale.com  Fri Aug  7 00:15:37 2015
From: peter.chen at freescale.com (Peter Chen)
Date: Fri, 7 Aug 2015 15:15:37 +0800
Subject: [PATCH v3 00/10] USB: chipidea misc patches
Message-ID: <1438931747-25209-1-git-send-email-peter.chen@freescale.com>

Hi all,

In this series, I add several new interfaces for chipidea driver,
they are mainly for system configuration adjustment. The USB
performance may be improved with these configuration changing,
but each vendor driver owner needs to consult with your IC
owner which configuration parameters are suitable for your system
before changing it, and only change it if necessary.

The other changes are for imx, it shows how imx uses these interfaces.
Shawn, the patch [5/10] and [9/10] are dts changes, help to review it
please.

Changes for v3:
- Improve the binding doc according to Rob's comment [Patch 4/10, 8/10]

Changes for v2:
- Use the bit fields which are not used. [Patch 2/10, 6/10, 10/10]
- According to Greg and Sascha comments, format patch 2/10's
  commit log.
- using non-burst instead of unburst for patch 7/10

Peter Chen (10):
  usb: chipidea: udc: zero-length packet is only needed for TX
  usb: chipidea: define stream mode disable for both roles
  usb: chipidea: imx: add stream mode enable for device mode at
    imx6sl/imx6sx
  Doc: usb: ci-hdrc-usb2: add ahb-burst-config for binding doc
  ARM: imx6: set ahb-burst-config as 0 for USB
  usb: chipidea: add ahb burst configuration interface
  usb: chipidea: usbmisc_imx: add non-burst setting for imx6
  Doc: usb: ci-hdrc-usb2: add tx(rx)-burst-config-dword for binding doc
  ARM: imx6: change default burst size for USB
  usb: chipidea: add tx/rx burst size configuration interface

 .../devicetree/bindings/usb/ci-hdrc-usb2.txt       | 17 ++++++
 arch/arm/boot/dts/imx6qdl.dtsi                     | 12 +++++
 arch/arm/boot/dts/imx6sl.dtsi                      |  9 ++++
 arch/arm/boot/dts/imx6sx.dtsi                      |  9 ++++
 drivers/usb/chipidea/bits.h                        |  7 +++
 drivers/usb/chipidea/ci.h                          |  1 +
 drivers/usb/chipidea/ci_hdrc_imx.c                 | 16 +++---
 drivers/usb/chipidea/core.c                        | 62 +++++++++++++++++++++-
 drivers/usb/chipidea/udc.c                         |  2 +-
 drivers/usb/chipidea/usbmisc_imx.c                 | 12 ++++-
 include/linux/usb/chipidea.h                       | 11 +++-
 11 files changed, 147 insertions(+), 11 deletions(-)

-- 
1.9.1



From peter.chen at freescale.com  Fri Aug  7 00:15:38 2015
From: peter.chen at freescale.com (Peter Chen)
Date: Fri, 7 Aug 2015 15:15:38 +0800
Subject: [PATCH v3 01/10] usb: chipidea: udc: zero-length packet is only
 needed for TX
In-Reply-To: <1438931747-25209-1-git-send-email-peter.chen@freescale.com>
References: <1438931747-25209-1-git-send-email-peter.chen@freescale.com>
Message-ID: <1438931747-25209-2-git-send-email-peter.chen@freescale.com>

The zero-length packet is the sendor tells the receiver that there
is no more data, so it is only needed at the TX side.

Signed-off-by: Peter Chen <peter.chen at freescale.com>
---
 drivers/usb/chipidea/udc.c | 2 +-
 1 file changed, 1 insertion(+), 1 deletion(-)

diff --git a/drivers/usb/chipidea/udc.c b/drivers/usb/chipidea/udc.c
index 2a47720..15f55da 100644
--- a/drivers/usb/chipidea/udc.c
+++ b/drivers/usb/chipidea/udc.c
@@ -445,7 +445,7 @@ static int _hardware_enqueue(struct ci_hw_ep *hwep, struct ci_hw_req *hwreq)
 		rest -= count;
 	}
 
-	if (hwreq->req.zero && hwreq->req.length
+	if (hwreq->req.zero && hwreq->req.length && hwep->dir == TX
 	    && (hwreq->req.length % hwep->ep.maxpacket == 0))
 		add_td_to_list(hwep, hwreq, 0);
 
-- 
1.9.1



From peter.chen at freescale.com  Fri Aug  7 00:15:39 2015
From: peter.chen at freescale.com (Peter Chen)
Date: Fri, 7 Aug 2015 15:15:39 +0800
Subject: [PATCH v3 02/10] usb: chipidea: define stream mode disable for both
 roles
In-Reply-To: <1438931747-25209-1-git-send-email-peter.chen@freescale.com>
References: <1438931747-25209-1-git-send-email-peter.chen@freescale.com>
Message-ID: <1438931747-25209-3-git-send-email-peter.chen@freescale.com>

The system bus and chipidea IP have different limitations for
both host and device mode.
For example, with below errata, we need to enable SDIS(Stream Disable
Mode) at host mode. But we don't want it for device mode at the
same system.

TAR 9000378958
Title: Non-Double Word Aligned Buffer Address Sometimes Causes Host to
Hang on OUT Retry
Impacted Configuration: Host mode, all transfer types
Description:
The host core operating in streaming mode may under run while sending
the data packet of an OUT transaction. This under run can occur if
there are unexpected system delays in fetching the remaining packet
data from memory. The host forces a bad CRC on the packet, the device
detects the error and discards the packet. The host then retries a Bulk,
Interrupt, or Control transfer if an under run occurs according to the
USB specification. During simulations, it was found that the host does
not issue the retry of the failed bulk OUT. It does not issue any other
transactions except SOF packets that have incorrect frame numbers.

The second failure mode occurs if the under run occurs on an ISO OUT
transaction and the next ISO transaction is a zero byte packet. The host
does not issue any transactions (including SOFs). The device detects a
Suspend condition, reverts to full speed, and waits for resume signaling.

A third failure mode occurs when the host under runs on an ISO OUT and
the next ISO in the schedule is an ISO OUT with two max packets of 1024
bytes each. The host should issue MDATA for the first OUT followed by
DATA1 for the second. However, it drops the MDATA transaction, and
issues the DATA1 transaction.

The system impact of this bug is the same regardless of the failure mode
observed. The host core hangs, the ehci_ctrl state machine waits for the
protocol engine to send the completion status for the corrupted
transaction, which never occurs. No indication is sent to the host
controller driver, no register bits change and no interrupts occur.
Eventually the requesting application times out.

Detailed internal behavior:
The EHCI control state machine (ehci_ctrl) in the DMA block is responsible
for parsing the schedules and initiating all transactions. The ehci_ctrl
state machine passes the transaction details to the protocol block by
writing the transaction information in to the TxFIFO. It then asserts
the pe_hst_run_pkt signal to inform the host protocol state machine
(pe_hst_state) that there is a packet in the TxFIFO.
A tag of 0x0 indicates a start of packet with the data providing the
following information:

35:32 Tag
31:30 Reserved
29:23 Endpoint (lowest 4 bits)
22:16 Address
15:10 Reserved
9:8 Endpoint speed
7:6 Endpoint type
5:6 Data Toggle
3:0 PID
The pe_hst_state reads the packet information and constructs the packet
and issues it to the PHY interface.
The ehci_ctrl state machine writes the start transaction information in
to the TxFIFO as 0x03002910c for the OUT packet that had the under run
error. However, it writes 0xC3002910C for the retry of the Out
transaction, which is incorrect.
The pe_hst_state enters a bus timeout state after sending the bad CRC
for the packet that under ran. It then purges any data that was back
filled in to the TxFIFO for the packet that under ran. The pe_hst_state
machine stops purging the TxFIFO when it is empty or if it reads a
location that has a tag of 0x0, indicating a start of packet command.

The pe_hst_state reads 0xC3002910C and discards it as it does not decode
to a start of packet command. It continues to purge the OUT data that
has been pre-buffered for the OUT retry . The pe_hst_state detects the
hst_packet_run signal and attempts to read the PID and address
information from the TxFIFO. This location has packet data and so does
not decode to a valid PID and so falls through to the PE_HST_SOF_LOAD
state where the frame_num_counter is updated. The frame_num_counter
is updated with the data in the TxFIFO. In this case, the data is
incorrect as the ehci_ctrl state machine did not initiate the load.
The hst_pe_state machine detects the SOF request signal and sends an
SOF with the bad frame number. Meanwhile, the ehci_ctrl state machine
waits indefinitely in the run_pkt state waiting for the completion
status from pe_hst_state machine, which will never happen.

The ISO failure case is similar except that there is no retry for ISO.
The ehci_ctrl state machine moves to the next transfer in the periodic
schedule. If the under run occurs on the last entry of the periodic
list then it moves to the Async schedule.

In the case of ISO OUT simulations, the next ISO is a zero byte OUT
and again the start of packet command gets corrupted. The TxFIFO is
empty when the hst_pe_state attempts to read the Address and PID
information as the transaction is a zero byte packet. This results
in the hst_pe_state machine staying in the GET_PID state, which means
that it does not issue any transactions (including SOFs). The device
detects a Suspend condition and reverts to full speed mode and waits
for a Resume or Reset signal.

The EHCI specification allows a Non-DoubleWord (32 bits) offset to
be used as a current offset for Buffer Pointer Page 0 of the qTD.
In Non-DoubleWord aligned cases, the core reads the packet data
from the AHB memory, performs the alignment operation before writing
it in to the TxFIFO as a 32 bit data word. An End Of Packet tag (EOP)
is written to the TxFIFO after all the packet data has been written
in to the TxFIFO. The alignment function is reset to Idle by the EOP
tag. The corruption of the start of packet command arises because the
packet buffer for the OUT transaction that under ran is not aligned
to a DoubleWord, and hence no EOP tag is written to the TxFIFO. The
alignment function is still active when the start packet information
is written in to the TxFIFO for the retry of the bulk packet or for
the next transaction in the case of an under run on an ISO. This
results in the corruption of the start tag and the transaction
information.

Click for waveform showing the command 0x 0000300291 being written in
to the TX FIFO for the Out that under ran.
Click for waveform showing the command 0xC3002910C written to the
TxFIFO instead of 0x 0000300291
Versions affected: Versions 2.10a and previous versions
How discovered: Customer simulation

Workaround:
1- The EHCI specification allows a non-DoubleWord offset to be used
as a current offset for Buffer Pointer Page 0 of the qTD. However,
if a DoubleWord offset is used then this issue does not arise.
2- Use non streaming mode to eliminate under runs.

Resolution:
The fix involves changes to the traffic state machine in the
vusb_hs_dma_traf block. The ehci_ctrl state machine updates the context
information by encoding the transaction results on the
hst_op_context_update signals at the end of a transaction. The signal
hst_op_context_update is added to the traffic state machine, and the
tx_fifo_under_ran_r signal is generated if the transaction results in
an under run error. Click for waveform

The traffic state machine then traverses to the do_eop states if the
tx_fifo_under_ran error is asserted. Thus an EOP tag is written in to
the TxFIFO as shown in this waveform .

The EOP tag resets the align state machine to the Idle state ensuring
that the next command written by the echi_ctrl state machine does not
get corrupted.

File(s) modified:
RTL code fixed: ?..
Method of reproducing: This failure cannot be reproduced in the current
test bench.
Date Found: March 2010
Date Fixed: June 2010
Update information:
Added the RTL code fix

Signed-off-by: Peter Chen <peter.chen at freescale.com>
---
 drivers/usb/chipidea/core.c  | 13 ++++++++++++-
 include/linux/usb/chipidea.h |  5 ++++-
 2 files changed, 16 insertions(+), 2 deletions(-)

diff --git a/drivers/usb/chipidea/core.c b/drivers/usb/chipidea/core.c
index 1a1b889..97f937f 100644
--- a/drivers/usb/chipidea/core.c
+++ b/drivers/usb/chipidea/core.c
@@ -64,6 +64,7 @@
 #include <linux/of.h>
 #include <linux/phy.h>
 #include <linux/regulator/consumer.h>
+#include <linux/usb/ehci_def.h>
 
 #include "ci.h"
 #include "udc.h"
@@ -412,7 +413,17 @@ static int ci_usb_phy_init(struct ci_hdrc *ci)
  */
 void ci_platform_configure(struct ci_hdrc *ci)
 {
-	if (ci->platdata->flags & CI_HDRC_DISABLE_STREAMING)
+	bool is_device_mode, is_host_mode;
+
+	is_device_mode = hw_read(ci, OP_USBMODE, USBMODE_CM) == USBMODE_CM_DC;
+	is_host_mode = hw_read(ci, OP_USBMODE, USBMODE_CM) == USBMODE_CM_HC;
+
+	if (is_device_mode &&
+		(ci->platdata->flags & CI_HDRC_DISABLE_DEVICE_STREAMING))
+		hw_write(ci, OP_USBMODE, USBMODE_CI_SDIS, USBMODE_CI_SDIS);
+
+	if (is_host_mode &&
+		(ci->platdata->flags & CI_HDRC_DISABLE_HOST_STREAMING))
 		hw_write(ci, OP_USBMODE, USBMODE_CI_SDIS, USBMODE_CI_SDIS);
 
 	if (ci->platdata->flags & CI_HDRC_FORCE_FULLSPEED) {
diff --git a/include/linux/usb/chipidea.h b/include/linux/usb/chipidea.h
index aa49177..034f7e1 100644
--- a/include/linux/usb/chipidea.h
+++ b/include/linux/usb/chipidea.h
@@ -19,8 +19,11 @@ struct ci_hdrc_platform_data {
 	enum usb_phy_interface phy_mode;
 	unsigned long	 flags;
 #define CI_HDRC_REGS_SHARED		BIT(0)
+#define CI_HDRC_DISABLE_DEVICE_STREAMING	BIT(1)
 #define CI_HDRC_SUPPORTS_RUNTIME_PM	BIT(2)
-#define CI_HDRC_DISABLE_STREAMING	BIT(3)
+#define CI_HDRC_DISABLE_HOST_STREAMING	BIT(3)
+#define CI_HDRC_DISABLE_STREAMING (CI_HDRC_DISABLE_DEVICE_STREAMING |	\
+		CI_HDRC_DISABLE_HOST_STREAMING)
 	/*
 	 * Only set it when DCCPARAMS.DC==1 and DCCPARAMS.HC==1,
 	 * but otg is not supported (no register otgsc).
-- 
1.9.1



From peter.chen at freescale.com  Fri Aug  7 00:15:40 2015
From: peter.chen at freescale.com (Peter Chen)
Date: Fri, 7 Aug 2015 15:15:40 +0800
Subject: [PATCH v3 03/10] usb: chipidea: imx: add stream mode enable for
 device mode at imx6sl/imx6sx
In-Reply-To: <1438931747-25209-1-git-send-email-peter.chen@freescale.com>
References: <1438931747-25209-1-git-send-email-peter.chen@freescale.com>
Message-ID: <1438931747-25209-4-git-send-email-peter.chen@freescale.com>

Stream mode enable is known for better performance, this stream mode
enable patch has been passed with stress tests at device mode for
imx6sl and imx6sx, and no issue is found.

Signed-off-by: Peter Chen <peter.chen at freescale.com>
---
 drivers/usb/chipidea/ci_hdrc_imx.c | 16 ++++++++++------
 1 file changed, 10 insertions(+), 6 deletions(-)

diff --git a/drivers/usb/chipidea/ci_hdrc_imx.c b/drivers/usb/chipidea/ci_hdrc_imx.c
index 6d2a85a..3f41679 100644
--- a/drivers/usb/chipidea/ci_hdrc_imx.c
+++ b/drivers/usb/chipidea/ci_hdrc_imx.c
@@ -29,26 +29,31 @@ struct ci_hdrc_imx_platform_flag {
 };
 
 static const struct ci_hdrc_imx_platform_flag imx27_usb_data = {
+		CI_HDRC_DISABLE_STREAMING,
 };
 
 static const struct ci_hdrc_imx_platform_flag imx28_usb_data = {
 	.flags = CI_HDRC_IMX28_WRITE_FIX |
-		CI_HDRC_TURN_VBUS_EARLY_ON,
+		CI_HDRC_TURN_VBUS_EARLY_ON |
+		CI_HDRC_DISABLE_STREAMING,
 };
 
 static const struct ci_hdrc_imx_platform_flag imx6q_usb_data = {
 	.flags = CI_HDRC_SUPPORTS_RUNTIME_PM |
-		CI_HDRC_TURN_VBUS_EARLY_ON,
+		CI_HDRC_TURN_VBUS_EARLY_ON |
+		CI_HDRC_DISABLE_STREAMING,
 };
 
 static const struct ci_hdrc_imx_platform_flag imx6sl_usb_data = {
 	.flags = CI_HDRC_SUPPORTS_RUNTIME_PM |
-		CI_HDRC_TURN_VBUS_EARLY_ON,
+		CI_HDRC_TURN_VBUS_EARLY_ON |
+		CI_HDRC_DISABLE_HOST_STREAMING,
 };
 
 static const struct ci_hdrc_imx_platform_flag imx6sx_usb_data = {
 	.flags = CI_HDRC_SUPPORTS_RUNTIME_PM |
-		CI_HDRC_TURN_VBUS_EARLY_ON,
+		CI_HDRC_TURN_VBUS_EARLY_ON |
+		CI_HDRC_DISABLE_HOST_STREAMING,
 };
 
 static const struct of_device_id ci_hdrc_imx_dt_ids[] = {
@@ -126,8 +131,7 @@ static int ci_hdrc_imx_probe(struct platform_device *pdev)
 	struct ci_hdrc_platform_data pdata = {
 		.name		= dev_name(&pdev->dev),
 		.capoffset	= DEF_CAPOFFSET,
-		.flags		= CI_HDRC_DISABLE_STREAMING |
-					CI_HDRC_SET_NON_ZERO_TTHA,
+		.flags		= CI_HDRC_SET_NON_ZERO_TTHA,
 	};
 	int ret;
 	const struct of_device_id *of_id =
-- 
1.9.1



From peter.chen at freescale.com  Fri Aug  7 00:15:41 2015
From: peter.chen at freescale.com (Peter Chen)
Date: Fri, 7 Aug 2015 15:15:41 +0800
Subject: [PATCH v3 04/10] Doc: usb: ci-hdrc-usb2: add ahb-burst-config for
 binding doc
In-Reply-To: <1438931747-25209-1-git-send-email-peter.chen@freescale.com>
References: <1438931747-25209-1-git-send-email-peter.chen@freescale.com>
Message-ID: <1438931747-25209-5-git-send-email-peter.chen@freescale.com>

It is used to change ahb burst configuration for platforms, it is
vendor specific.

Signed-off-by: Peter Chen <peter.chen at freescale.com>
---
 Documentation/devicetree/bindings/usb/ci-hdrc-usb2.txt | 7 +++++++
 1 file changed, 7 insertions(+)

diff --git a/Documentation/devicetree/bindings/usb/ci-hdrc-usb2.txt b/Documentation/devicetree/bindings/usb/ci-hdrc-usb2.txt
index 4159c8c..d52a747 100644
--- a/Documentation/devicetree/bindings/usb/ci-hdrc-usb2.txt
+++ b/Documentation/devicetree/bindings/usb/ci-hdrc-usb2.txt
@@ -32,6 +32,11 @@ Optional properties:
 - external-vbus-divider: (FSL only) enables off-chip resistor divider for Vbus
 - itc-setting: interrupt threshold control register control, the setting
   should be aligned with ITC bits at register USBCMD.
+- ahb-burst-config: it is vendor dependent, the required value should be
+  aligned with AHBBRST at SBUSCFG, the range is from 0x0 to 0x7. This
+  property is used to change AHB burst configuration, check the chipidea
+  spec for meaning of each value. If this property is not existed, it
+  will use the reset value.
 
 Example:
 
@@ -44,4 +49,6 @@ Example:
 		phy-names = "usb-phy";
 		vbus-supply = <&reg_usb0_vbus>;
 		gadget-itc-setting = <0x4>; /* 4 micro-frames */
+		 /* Incremental burst of unspecified length */
+		ahb-burst-config = <0x0>;
 	};
-- 
1.9.1



From peter.chen at freescale.com  Fri Aug  7 00:15:42 2015
From: peter.chen at freescale.com (Peter Chen)
Date: Fri, 7 Aug 2015 15:15:42 +0800
Subject: [PATCH v3 05/10] ARM: imx6: set ahb-burst-config as 0 for USB
In-Reply-To: <1438931747-25209-1-git-send-email-peter.chen@freescale.com>
References: <1438931747-25209-1-git-send-email-peter.chen@freescale.com>
Message-ID: <1438931747-25209-6-git-send-email-peter.chen@freescale.com>

After setting ahb burst configuration as 0, we can increase tx/rx
burst size, it will improve the USB performance

Signed-off-by: Peter Chen <peter.chen at freescale.com>
---
 arch/arm/boot/dts/imx6qdl.dtsi | 4 ++++
 arch/arm/boot/dts/imx6sl.dtsi  | 3 +++
 arch/arm/boot/dts/imx6sx.dtsi  | 3 +++
 3 files changed, 10 insertions(+)

diff --git a/arch/arm/boot/dts/imx6qdl.dtsi b/arch/arm/boot/dts/imx6qdl.dtsi
index e6d1359..42d62b0 100644
--- a/arch/arm/boot/dts/imx6qdl.dtsi
+++ b/arch/arm/boot/dts/imx6qdl.dtsi
@@ -853,6 +853,7 @@
 				clocks = <&clks IMX6QDL_CLK_USBOH3>;
 				fsl,usbphy = <&usbphy1>;
 				fsl,usbmisc = <&usbmisc 0>;
+				ahb-burst-config = <0x0>;
 				status = "disabled";
 			};
 
@@ -864,6 +865,7 @@
 				fsl,usbphy = <&usbphy2>;
 				fsl,usbmisc = <&usbmisc 1>;
 				dr_mode = "host";
+				ahb-burst-config = <0x0>;
 				status = "disabled";
 			};
 
@@ -874,6 +876,7 @@
 				clocks = <&clks IMX6QDL_CLK_USBOH3>;
 				fsl,usbmisc = <&usbmisc 2>;
 				dr_mode = "host";
+				ahb-burst-config = <0x0>;
 				status = "disabled";
 			};
 
@@ -884,6 +887,7 @@
 				clocks = <&clks IMX6QDL_CLK_USBOH3>;
 				fsl,usbmisc = <&usbmisc 3>;
 				dr_mode = "host";
+				ahb-burst-config = <0x0>;
 				status = "disabled";
 			};
 
diff --git a/arch/arm/boot/dts/imx6sl.dtsi b/arch/arm/boot/dts/imx6sl.dtsi
index a78e715..066fac9 100644
--- a/arch/arm/boot/dts/imx6sl.dtsi
+++ b/arch/arm/boot/dts/imx6sl.dtsi
@@ -688,6 +688,7 @@
 				clocks = <&clks IMX6SL_CLK_USBOH3>;
 				fsl,usbphy = <&usbphy1>;
 				fsl,usbmisc = <&usbmisc 0>;
+				ahb-burst-config = <0x0>;
 				status = "disabled";
 			};
 
@@ -698,6 +699,7 @@
 				clocks = <&clks IMX6SL_CLK_USBOH3>;
 				fsl,usbphy = <&usbphy2>;
 				fsl,usbmisc = <&usbmisc 1>;
+				ahb-burst-config = <0x0>;
 				status = "disabled";
 			};
 
@@ -708,6 +710,7 @@
 				clocks = <&clks IMX6SL_CLK_USBOH3>;
 				fsl,usbmisc = <&usbmisc 2>;
 				dr_mode = "host";
+				ahb-burst-config = <0x0>;
 				status = "disabled";
 			};
 
diff --git a/arch/arm/boot/dts/imx6sx.dtsi b/arch/arm/boot/dts/imx6sx.dtsi
index 708175d..3656a1d 100644
--- a/arch/arm/boot/dts/imx6sx.dtsi
+++ b/arch/arm/boot/dts/imx6sx.dtsi
@@ -746,6 +746,7 @@
 				fsl,usbphy = <&usbphy1>;
 				fsl,usbmisc = <&usbmisc 0>;
 				fsl,anatop = <&anatop>;
+				ahb-burst-config = <0x0>;
 				status = "disabled";
 			};
 
@@ -756,6 +757,7 @@
 				clocks = <&clks IMX6SX_CLK_USBOH3>;
 				fsl,usbphy = <&usbphy2>;
 				fsl,usbmisc = <&usbmisc 1>;
+				ahb-burst-config = <0x0>;
 				status = "disabled";
 			};
 
@@ -768,6 +770,7 @@
 				phy_type = "hsic";
 				fsl,anatop = <&anatop>;
 				dr_mode = "host";
+				ahb-burst-config = <0x0>;
 				status = "disabled";
 			};
 
-- 
1.9.1



From peter.chen at freescale.com  Fri Aug  7 00:15:43 2015
From: peter.chen at freescale.com (Peter Chen)
Date: Fri, 7 Aug 2015 15:15:43 +0800
Subject: [PATCH v3 06/10] usb: chipidea: add ahb burst configuration interface
In-Reply-To: <1438931747-25209-1-git-send-email-peter.chen@freescale.com>
References: <1438931747-25209-1-git-send-email-peter.chen@freescale.com>
Message-ID: <1438931747-25209-7-git-send-email-peter.chen@freescale.com>

The users can change it through dts or platform data if they
want to change the default value.

Signed-off-by: Peter Chen <peter.chen at freescale.com>
---
 drivers/usb/chipidea/bits.h  |  3 +++
 drivers/usb/chipidea/core.c  | 14 ++++++++++++++
 include/linux/usb/chipidea.h |  2 ++
 3 files changed, 19 insertions(+)

diff --git a/drivers/usb/chipidea/bits.h b/drivers/usb/chipidea/bits.h
index 831a8f6..462ad02 100644
--- a/drivers/usb/chipidea/bits.h
+++ b/drivers/usb/chipidea/bits.h
@@ -25,6 +25,9 @@
 #define VERSION		      (0xF << 25)
 #define CIVERSION	      (0x7 << 29)
 
+/* SBUSCFG */
+#define AHBBRST_MASK		0x7
+
 /* HCCPARAMS */
 #define HCCPARAMS_LEN         BIT(17)
 
diff --git a/drivers/usb/chipidea/core.c b/drivers/usb/chipidea/core.c
index 97f937f..bde49f3 100644
--- a/drivers/usb/chipidea/core.c
+++ b/drivers/usb/chipidea/core.c
@@ -438,6 +438,9 @@ void ci_platform_configure(struct ci_hdrc *ci)
 
 	hw_write(ci, OP_USBCMD, 0xff0000, ci->platdata->itc_setting << 16);
 
+	if (ci->platdata->flags & CI_HDRC_OVERRIDE_AHB_BURST)
+		hw_write_id_reg(ci, ID_SBUSCFG, AHBBRST_MASK,
+			ci->platdata->ahb_burst_config);
 }
 
 /**
@@ -646,6 +649,17 @@ static int ci_get_platdata(struct device *dev,
 		}
 	}
 
+	if (of_find_property(dev->of_node, "ahb-burst-config", NULL)) {
+		ret = of_property_read_u32(dev->of_node, "ahb-burst-config",
+			&platdata->ahb_burst_config);
+		if (ret) {
+			dev_err(dev,
+				"failed to get ahb-burst-config\n");
+			return ret;
+		}
+		platdata->flags |= CI_HDRC_OVERRIDE_AHB_BURST;
+	}
+
 	return 0;
 }
 
diff --git a/include/linux/usb/chipidea.h b/include/linux/usb/chipidea.h
index 034f7e1..fe3c8eb 100644
--- a/include/linux/usb/chipidea.h
+++ b/include/linux/usb/chipidea.h
@@ -33,6 +33,7 @@ struct ci_hdrc_platform_data {
 #define CI_HDRC_FORCE_FULLSPEED		BIT(6)
 #define CI_HDRC_TURN_VBUS_EARLY_ON	BIT(7)
 #define CI_HDRC_SET_NON_ZERO_TTHA	BIT(8)
+#define CI_HDRC_OVERRIDE_AHB_BURST	BIT(9)
 	enum usb_dr_mode	dr_mode;
 #define CI_HDRC_CONTROLLER_RESET_EVENT		0
 #define CI_HDRC_CONTROLLER_STOPPED_EVENT	1
@@ -42,6 +43,7 @@ struct ci_hdrc_platform_data {
 	bool			tpl_support;
 	/* interrupt threshold setting */
 	u32			itc_setting;
+	u32			ahb_burst_config;
 };
 
 /* Default offset of capability registers */
-- 
1.9.1



From peter.chen at freescale.com  Fri Aug  7 00:15:46 2015
From: peter.chen at freescale.com (Peter Chen)
Date: Fri, 7 Aug 2015 15:15:46 +0800
Subject: [PATCH v3 09/10] ARM: imx6: change default burst size for USB
In-Reply-To: <1438931747-25209-1-git-send-email-peter.chen@freescale.com>
References: <1438931747-25209-1-git-send-email-peter.chen@freescale.com>
Message-ID: <1438931747-25209-10-git-send-email-peter.chen@freescale.com>

It can improve the USB performance when choosing larger
burst size at some systems (bus size is larger), there is
no side effect if this burst size is larger than bus size.

Signed-off-by: Peter Chen <peter.chen at freescale.com>
---
 arch/arm/boot/dts/imx6qdl.dtsi | 8 ++++++++
 arch/arm/boot/dts/imx6sl.dtsi  | 6 ++++++
 arch/arm/boot/dts/imx6sx.dtsi  | 6 ++++++
 3 files changed, 20 insertions(+)

diff --git a/arch/arm/boot/dts/imx6qdl.dtsi b/arch/arm/boot/dts/imx6qdl.dtsi
index 42d62b0..b9f2e3a 100644
--- a/arch/arm/boot/dts/imx6qdl.dtsi
+++ b/arch/arm/boot/dts/imx6qdl.dtsi
@@ -854,6 +854,8 @@
 				fsl,usbphy = <&usbphy1>;
 				fsl,usbmisc = <&usbmisc 0>;
 				ahb-burst-config = <0x0>;
+				tx-burst-size-dword = <0x10>;
+				rx-burst-size-dword = <0x10>;
 				status = "disabled";
 			};
 
@@ -866,6 +868,8 @@
 				fsl,usbmisc = <&usbmisc 1>;
 				dr_mode = "host";
 				ahb-burst-config = <0x0>;
+				tx-burst-size-dword = <0x10>;
+				rx-burst-size-dword = <0x10>;
 				status = "disabled";
 			};
 
@@ -877,6 +881,8 @@
 				fsl,usbmisc = <&usbmisc 2>;
 				dr_mode = "host";
 				ahb-burst-config = <0x0>;
+				tx-burst-size-dword = <0x10>;
+				rx-burst-size-dword = <0x10>;
 				status = "disabled";
 			};
 
@@ -888,6 +894,8 @@
 				fsl,usbmisc = <&usbmisc 3>;
 				dr_mode = "host";
 				ahb-burst-config = <0x0>;
+				tx-burst-size-dword = <0x10>;
+				rx-burst-size-dword = <0x10>;
 				status = "disabled";
 			};
 
diff --git a/arch/arm/boot/dts/imx6sl.dtsi b/arch/arm/boot/dts/imx6sl.dtsi
index 066fac9..627549f 100644
--- a/arch/arm/boot/dts/imx6sl.dtsi
+++ b/arch/arm/boot/dts/imx6sl.dtsi
@@ -689,6 +689,8 @@
 				fsl,usbphy = <&usbphy1>;
 				fsl,usbmisc = <&usbmisc 0>;
 				ahb-burst-config = <0x0>;
+				tx-burst-size-dword = <0x10>;
+				rx-burst-size-dword = <0x10>;
 				status = "disabled";
 			};
 
@@ -700,6 +702,8 @@
 				fsl,usbphy = <&usbphy2>;
 				fsl,usbmisc = <&usbmisc 1>;
 				ahb-burst-config = <0x0>;
+				tx-burst-size-dword = <0x10>;
+				rx-burst-size-dword = <0x10>;
 				status = "disabled";
 			};
 
@@ -711,6 +715,8 @@
 				fsl,usbmisc = <&usbmisc 2>;
 				dr_mode = "host";
 				ahb-burst-config = <0x0>;
+				tx-burst-size-dword = <0x10>;
+				rx-burst-size-dword = <0x10>;
 				status = "disabled";
 			};
 
diff --git a/arch/arm/boot/dts/imx6sx.dtsi b/arch/arm/boot/dts/imx6sx.dtsi
index 3656a1d..6844e9e 100644
--- a/arch/arm/boot/dts/imx6sx.dtsi
+++ b/arch/arm/boot/dts/imx6sx.dtsi
@@ -747,6 +747,8 @@
 				fsl,usbmisc = <&usbmisc 0>;
 				fsl,anatop = <&anatop>;
 				ahb-burst-config = <0x0>;
+				tx-burst-size-dword = <0x10>;
+				rx-burst-size-dword = <0x10>;
 				status = "disabled";
 			};
 
@@ -758,6 +760,8 @@
 				fsl,usbphy = <&usbphy2>;
 				fsl,usbmisc = <&usbmisc 1>;
 				ahb-burst-config = <0x0>;
+				tx-burst-size-dword = <0x10>;
+				rx-burst-size-dword = <0x10>;
 				status = "disabled";
 			};
 
@@ -771,6 +775,8 @@
 				fsl,anatop = <&anatop>;
 				dr_mode = "host";
 				ahb-burst-config = <0x0>;
+				tx-burst-size-dword = <0x10>;
+				rx-burst-size-dword = <0x10>;
 				status = "disabled";
 			};
 
-- 
1.9.1



From peter.chen at freescale.com  Fri Aug  7 00:15:44 2015
From: peter.chen at freescale.com (Peter Chen)
Date: Fri, 7 Aug 2015 15:15:44 +0800
Subject: [PATCH v3 07/10] usb: chipidea: usbmisc_imx: add non-burst setting
 for imx6
In-Reply-To: <1438931747-25209-1-git-send-email-peter.chen@freescale.com>
References: <1438931747-25209-1-git-send-email-peter.chen@freescale.com>
Message-ID: <1438931747-25209-8-git-send-email-peter.chen@freescale.com>

With this setting and AHBBRST at SBUSCFG as "Incremental burst of
unspecified length", each non-burst size can be taken as single
transfer. It is benefit for non-burst size transfer.

Signed-off-by: Peter Chen <peter.chen at freescale.com>
---
 drivers/usb/chipidea/usbmisc_imx.c | 12 ++++++++++--
 1 file changed, 10 insertions(+), 2 deletions(-)

diff --git a/drivers/usb/chipidea/usbmisc_imx.c b/drivers/usb/chipidea/usbmisc_imx.c
index 3cefd49..5ddab30 100644
--- a/drivers/usb/chipidea/usbmisc_imx.c
+++ b/drivers/usb/chipidea/usbmisc_imx.c
@@ -54,6 +54,7 @@
 #define MX53_USB_PHYCTRL1_PLLDIV_MASK	0x3
 #define MX53_USB_PLL_DIV_24_MHZ		0x01
 
+#define MX6_BM_NON_BURST_SETTING	BIT(1)
 #define MX6_BM_OVER_CUR_DIS		BIT(7)
 #define MX6_BM_WAKEUP_ENABLE		BIT(10)
 #define MX6_BM_ID_WAKEUP		BIT(16)
@@ -255,14 +256,21 @@ static int usbmisc_imx6q_init(struct imx_usbmisc_data *data)
 	if (data->index > 3)
 		return -EINVAL;
 
+	spin_lock_irqsave(&usbmisc->lock, flags);
+
 	if (data->disable_oc) {
-		spin_lock_irqsave(&usbmisc->lock, flags);
 		reg = readl(usbmisc->base + data->index * 4);
 		writel(reg | MX6_BM_OVER_CUR_DIS,
 			usbmisc->base + data->index * 4);
-		spin_unlock_irqrestore(&usbmisc->lock, flags);
 	}
 
+	/* SoC non-burst setting */
+	reg = readl(usbmisc->base + data->index * 4);
+	writel(reg | MX6_BM_NON_BURST_SETTING,
+			usbmisc->base + data->index * 4);
+
+	spin_unlock_irqrestore(&usbmisc->lock, flags);
+
 	usbmisc_imx6q_set_wakeup(data, false);
 
 	return 0;
-- 
1.9.1



From peter.chen at freescale.com  Fri Aug  7 00:15:45 2015
From: peter.chen at freescale.com (Peter Chen)
Date: Fri, 7 Aug 2015 15:15:45 +0800
Subject: [PATCH v3 08/10] Doc: usb: ci-hdrc-usb2: add
 tx(rx)-burst-config-dword for binding doc
In-Reply-To: <1438931747-25209-1-git-send-email-peter.chen@freescale.com>
References: <1438931747-25209-1-git-send-email-peter.chen@freescale.com>
Message-ID: <1438931747-25209-9-git-send-email-peter.chen@freescale.com>

It is used to override the default setting for burst size, changing
burst size takes effect only when the SBUSCFG.AHBBRST = 0.

Signed-off-by: Peter Chen <peter.chen at freescale.com>
---
 Documentation/devicetree/bindings/usb/ci-hdrc-usb2.txt | 10 ++++++++++
 1 file changed, 10 insertions(+)

diff --git a/Documentation/devicetree/bindings/usb/ci-hdrc-usb2.txt b/Documentation/devicetree/bindings/usb/ci-hdrc-usb2.txt
index d52a747..d71ef07 100644
--- a/Documentation/devicetree/bindings/usb/ci-hdrc-usb2.txt
+++ b/Documentation/devicetree/bindings/usb/ci-hdrc-usb2.txt
@@ -37,6 +37,14 @@ Optional properties:
   property is used to change AHB burst configuration, check the chipidea
   spec for meaning of each value. If this property is not existed, it
   will use the reset value.
+- tx-burst-size-dword: it is vendor dependent, the tx burst size in dword
+  (4 bytes), This register represents the maximum length of a the burst
+  in 32-bit words while moving data from system memory to the USB
+  bus, changing this value takes effect only the SBUSCFG.AHBBRST is 0.
+- rx-burst-size-dword: it is vendor dependent, the rx burst size in dword
+  (4 bytes), This register represents the maximum length of a the burst
+  in 32-bit words while moving data from the USB bus to system memory,
+  changing this value takes effect only the SBUSCFG.AHBBRST is 0.
 
 Example:
 
@@ -51,4 +59,6 @@ Example:
 		gadget-itc-setting = <0x4>; /* 4 micro-frames */
 		 /* Incremental burst of unspecified length */
 		ahb-burst-config = <0x0>;
+		tx-burst-size-dword = <0x10>; /* 64 bytes */
+		rx-burst-size-dword = <0x10>;
 	};
-- 
1.9.1



From peter.chen at freescale.com  Fri Aug  7 00:15:47 2015
From: peter.chen at freescale.com (Peter Chen)
Date: Fri, 7 Aug 2015 15:15:47 +0800
Subject: [PATCH v3 10/10] usb: chipidea: add tx/rx burst size configuration
 interface
In-Reply-To: <1438931747-25209-1-git-send-email-peter.chen@freescale.com>
References: <1438931747-25209-1-git-send-email-peter.chen@freescale.com>
Message-ID: <1438931747-25209-11-git-send-email-peter.chen@freescale.com>

The user can adjust it through dts or platform data

Signed-off-by: Peter Chen <peter.chen at freescale.com>
---
 drivers/usb/chipidea/bits.h  |  4 ++++
 drivers/usb/chipidea/ci.h    |  1 +
 drivers/usb/chipidea/core.c  | 35 +++++++++++++++++++++++++++++++++++
 include/linux/usb/chipidea.h |  4 ++++
 4 files changed, 44 insertions(+)

diff --git a/drivers/usb/chipidea/bits.h b/drivers/usb/chipidea/bits.h
index 462ad02..e462f55 100644
--- a/drivers/usb/chipidea/bits.h
+++ b/drivers/usb/chipidea/bits.h
@@ -61,6 +61,10 @@
 /* Set non-zero value for internal TT Hub address representation */
 #define TTCTRL_TTHA		(0x7fUL << 24)
 
+/* BURSTSIZE */
+#define RX_BURST_MASK		0xff
+#define TX_BURST_MASK		0xff00
+
 /* PORTSC */
 #define PORTSC_CCS            BIT(0)
 #define PORTSC_CSC            BIT(1)
diff --git a/drivers/usb/chipidea/ci.h b/drivers/usb/chipidea/ci.h
index b562544..41d7cf6 100644
--- a/drivers/usb/chipidea/ci.h
+++ b/drivers/usb/chipidea/ci.h
@@ -51,6 +51,7 @@ enum ci_hw_regs {
 	OP_DEVICEADDR,
 	OP_ENDPTLISTADDR,
 	OP_TTCTRL,
+	OP_BURSTSIZE,
 	OP_PORTSC,
 	OP_DEVLC,
 	OP_OTGSC,
diff --git a/drivers/usb/chipidea/core.c b/drivers/usb/chipidea/core.c
index bde49f3..3feebf7 100644
--- a/drivers/usb/chipidea/core.c
+++ b/drivers/usb/chipidea/core.c
@@ -86,6 +86,7 @@ static const u8 ci_regs_nolpm[] = {
 	[OP_DEVICEADDR]		= 0x14U,
 	[OP_ENDPTLISTADDR]	= 0x18U,
 	[OP_TTCTRL]		= 0x1CU,
+	[OP_BURSTSIZE]		= 0x20U,
 	[OP_PORTSC]		= 0x44U,
 	[OP_DEVLC]		= 0x84U,
 	[OP_OTGSC]		= 0x64U,
@@ -109,6 +110,7 @@ static const u8 ci_regs_lpm[] = {
 	[OP_DEVICEADDR]		= 0x14U,
 	[OP_ENDPTLISTADDR]	= 0x18U,
 	[OP_TTCTRL]		= 0x1CU,
+	[OP_BURSTSIZE]		= 0x20U,
 	[OP_PORTSC]		= 0x44U,
 	[OP_DEVLC]		= 0x84U,
 	[OP_OTGSC]		= 0xC4U,
@@ -441,6 +443,17 @@ void ci_platform_configure(struct ci_hdrc *ci)
 	if (ci->platdata->flags & CI_HDRC_OVERRIDE_AHB_BURST)
 		hw_write_id_reg(ci, ID_SBUSCFG, AHBBRST_MASK,
 			ci->platdata->ahb_burst_config);
+
+	/* override burst size, take effect only when ahb_burst_config is 0 */
+	if (!hw_read_id_reg(ci, ID_SBUSCFG, AHBBRST_MASK)) {
+		if (ci->platdata->flags & CI_HDRC_OVERRIDE_TX_BURST)
+			hw_write(ci, OP_BURSTSIZE, TX_BURST_MASK,
+			ci->platdata->tx_burst_size << __ffs(TX_BURST_MASK));
+
+		if (ci->platdata->flags & CI_HDRC_OVERRIDE_RX_BURST)
+			hw_write(ci, OP_BURSTSIZE, RX_BURST_MASK,
+				ci->platdata->rx_burst_size);
+	}
 }
 
 /**
@@ -660,6 +673,28 @@ static int ci_get_platdata(struct device *dev,
 		platdata->flags |= CI_HDRC_OVERRIDE_AHB_BURST;
 	}
 
+	if (of_find_property(dev->of_node, "tx-burst-size-dword", NULL)) {
+		ret = of_property_read_u32(dev->of_node, "tx-burst-size-dword",
+			&platdata->tx_burst_size);
+		if (ret) {
+			dev_err(dev,
+				"failed to get tx-burst-size-dword\n");
+			return ret;
+		}
+		platdata->flags |= CI_HDRC_OVERRIDE_TX_BURST;
+	}
+
+	if (of_find_property(dev->of_node, "rx-burst-size-dword", NULL)) {
+		ret = of_property_read_u32(dev->of_node, "rx-burst-size-dword",
+			&platdata->rx_burst_size);
+		if (ret) {
+			dev_err(dev,
+				"failed to get rx-burst-size-dword\n");
+			return ret;
+		}
+		platdata->flags |= CI_HDRC_OVERRIDE_RX_BURST;
+	}
+
 	return 0;
 }
 
diff --git a/include/linux/usb/chipidea.h b/include/linux/usb/chipidea.h
index fe3c8eb..a41833c 100644
--- a/include/linux/usb/chipidea.h
+++ b/include/linux/usb/chipidea.h
@@ -34,6 +34,8 @@ struct ci_hdrc_platform_data {
 #define CI_HDRC_TURN_VBUS_EARLY_ON	BIT(7)
 #define CI_HDRC_SET_NON_ZERO_TTHA	BIT(8)
 #define CI_HDRC_OVERRIDE_AHB_BURST	BIT(9)
+#define CI_HDRC_OVERRIDE_TX_BURST	BIT(10)
+#define CI_HDRC_OVERRIDE_RX_BURST	BIT(11)
 	enum usb_dr_mode	dr_mode;
 #define CI_HDRC_CONTROLLER_RESET_EVENT		0
 #define CI_HDRC_CONTROLLER_STOPPED_EVENT	1
@@ -44,6 +46,8 @@ struct ci_hdrc_platform_data {
 	/* interrupt threshold setting */
 	u32			itc_setting;
 	u32			ahb_burst_config;
+	u32			tx_burst_size;
+	u32			rx_burst_size;
 };
 
 /* Default offset of capability registers */
-- 
1.9.1



From marc.zyngier at arm.com  Fri Aug  7 01:29:23 2015
From: marc.zyngier at arm.com (Marc Zyngier)
Date: Fri, 07 Aug 2015 09:29:23 +0100
Subject: [PATCH v3 09/11] KVM: arm/arm64: vgic: Prevent userspace injection
 of a mapped interrupt
In-Reply-To: <55C458D4.9030500@linaro.org>
References: <1437753309-17989-1-git-send-email-marc.zyngier@arm.com>
 <1437753309-17989-10-git-send-email-marc.zyngier@arm.com>
 <55C0E690.1090808@linaro.org> <55C0EBF5.2060708@arm.com>
 <55C1BBF9.2060004@linaro.org> <55C1DAE9.1050609@arm.com>
 <20150805105345.GA4657@cbox> <55C1F7CF.5070904@linaro.org>
 <20150805134754.GB4657@cbox> <55C38EF5.1080502@arm.com>
 <55C458D4.9030500@linaro.org>
Message-ID: <55C46C63.2050906@arm.com>

On 07/08/15 08:05, Eric Auger wrote:
> Hi Marc,
> On 08/06/2015 06:44 PM, Marc Zyngier wrote:
>> On 05/08/15 14:47, Christoffer Dall wrote:
>>> On Wed, Aug 05, 2015 at 01:47:27PM +0200, Eric Auger wrote:
>>>> On 08/05/2015 12:53 PM, Christoffer Dall wrote:
>>>>> On Wed, Aug 05, 2015 at 10:44:09AM +0100, Marc Zyngier wrote:
>>>>>> On 05/08/15 08:32, Eric Auger wrote:
>>>>>>> Hi Marc,
>>>>>>> On 08/04/2015 06:44 PM, Marc Zyngier wrote:
>>>>>>>> On 04/08/15 17:21, Eric Auger wrote:
>>>>>>>>> Hi Marc,
>>>>>>>>> On 07/24/2015 05:55 PM, Marc Zyngier wrote:
>>>>>>>>>> Virtual interrupts mapped to a HW interrupt should only be triggered
>>>>>>>>>> from inside the kernel. Otherwise, you could end up confusing the
>>>>>>>>>> kernel (and the GIC's) state machine.
>>>>>>>>>>
>>>>>>>>>> Rearrange the injection path so that kvm_vgic_inject_irq is
>>>>>>>>>> used for non-mapped interrupts, and kvm_vgic_inject_mapped_irq is
>>>>>>>>>> used for mapped interrupts. The latter should only be called from
>>>>>>>>>> inside the kernel (timer, VFIO).
>>>>>>>>> nit: I would replace VFIO by irqfd.
>>>>>>>>> VFIO just triggers the eventfd/irqfd. This is KVM/irqfd that injects the
>>>>>>>>> virtual irq upon the irqfd signaling and he irqfd adaptation/ARM
>>>>>>>>> currently is implemented in vgic.c
>>>>>>>>
>>>>>>>> Ah, thanks for reminding me of the right terminology, I tend to think of
>>>>>>>> it as one big bag of nasty tricks... ;-)
>>>>>>>>
>>>>>>>> I'll update the commit message.
>>>>>>>>
>>>>>>>>>>
>>>>>>>>>> Signed-off-by: Marc Zyngier <marc.zyngier at arm.com>
>>>>>>>>>> ---
>>>>>>>>>>  include/kvm/arm_vgic.h |  2 +
>>>>>>>>>>  virt/kvm/arm/vgic.c    | 99 ++++++++++++++++++++++++++++++++++----------------
>>>>>>>>>>  2 files changed, 70 insertions(+), 31 deletions(-)
>>>>>>>>>>
>>>>>>>>>> diff --git a/include/kvm/arm_vgic.h b/include/kvm/arm_vgic.h
>>>>>>>>>> index 7306b4b..f6bfd79 100644
>>>>>>>>>> --- a/include/kvm/arm_vgic.h
>>>>>>>>>> +++ b/include/kvm/arm_vgic.h
>>>>>>>>>> @@ -351,6 +351,8 @@ void kvm_vgic_flush_hwstate(struct kvm_vcpu *vcpu);
>>>>>>>>>>  void kvm_vgic_sync_hwstate(struct kvm_vcpu *vcpu);
>>>>>>>>>>  int kvm_vgic_inject_irq(struct kvm *kvm, int cpuid, unsigned int irq_num,
>>>>>>>>>>  			bool level);
>>>>>>>>>> +int kvm_vgic_inject_mapped_irq(struct kvm *kvm, int cpuid,
>>>>>>>>>> +			       struct irq_phys_map *map, bool level);
>>>>>>>>>>  void vgic_v3_dispatch_sgi(struct kvm_vcpu *vcpu, u64 reg);
>>>>>>>>>>  int kvm_vgic_vcpu_pending_irq(struct kvm_vcpu *vcpu);
>>>>>>>>>>  int kvm_vgic_vcpu_active_irq(struct kvm_vcpu *vcpu);
>>>>>>>>>> diff --git a/virt/kvm/arm/vgic.c b/virt/kvm/arm/vgic.c
>>>>>>>>>> index 3f7b690..e40ef70 100644
>>>>>>>>>> --- a/virt/kvm/arm/vgic.c
>>>>>>>>>> +++ b/virt/kvm/arm/vgic.c
>>>>>>>>>> @@ -1533,7 +1533,8 @@ static int vgic_validate_injection(struct kvm_vcpu *vcpu, int irq, int level)
>>>>>>>>>>  }
>>>>>>>>>>  
>>>>>>>>>>  static int vgic_update_irq_pending(struct kvm *kvm, int cpuid,
>>>>>>>>>> -				  unsigned int irq_num, bool level)
>>>>>>>>>> +				   struct irq_phys_map *map,
>>>>>>>>>> +				   unsigned int irq_num, bool level)
>>>>>>>>>>  {
>>>>>>>>> In vgic_update_irq_pending, I needed to modify the following line and
>>>>>>>>> add the "&& !map".
>>>>>>>>>
>>>>>>>>>         if (!vgic_validate_injection(vcpu, irq_num, level) && !map) {
>>>>>>>>>
>>>>>>>>> Without that, the level being not properly modeled for level sensitive
>>>>>>>>> forwarded IRQs, the 2d injection fails.
>>>>>>>>
>>>>>>>> Ah! Is that because we never see the line being reset to zero, and the
>>>>>>>> VGIC still sees the line as pending at the distributor level?
>>>>>>> yes indeed
>>>>>>
>>>>>> Then it is a bigger problem we need to solve, and your solution just
>>>>>> papers over the issue.
>>>>>>
>>>>>> The main problem is that irqfd is essentially an edge-triggered
>>>>>> signalling. Fire and forget. Given that we're dealing with a level
>>>>>> triggered interrupt, we end up with the interrupt still marked as
>>>>>> pending (nobody took the signal down).
>>>> this does not really relate to irqfd: irqfd also comes with the concept
>>>> of resamplefd. in case the IRQ is not forwarded, this is the
>>>> irqfd_resampler_ack function that toggles the IRQ down (eventfd.c). Its
>>>> execution is triggered in vgic_process_maintenance. With forwarding the
>>>> EOI is not trappable anymore so this disappears.
>>>>
>>>>
>>>>>> The usual way to get out of that mess in is to evaluate the state of the
>>>>>> level on EOI. But we can't trap on EOI for a HW interrupt.
>>>>>>
>>>>>> So it raises the question: should we instead consider the HW pending
>>>>>> state instead of the software one for mapped interrupts? It is
>>>>>> expensive, but it feels more correct.
>>>>>>
>>>>> I thought we already covered this at LCA.  For mapped interrupts
>>>>> (forwarded) we should never consider the software pending state, because
>>>>> that state is managed by the hardware.  Or am I confusing concepts here?
>>>>
>>>> Yes we discussed we should bypass most of the SW states.
>>>>
>>>> in my previous integration I proposed a patch "KVM: arm: vgic: fix state
>>>> machine for forwarded IRQ". What's wrong with the below approach?
>>>>
>>>>
>>>>     Fix multiple injection of level sensitive forwarded IRQs.
>>>>     With current code, the second injection fails since the
>>>>     state bitmaps are not reset (process_maintenance is not
>>>>     called anymore).
>>>>
>>>>     New implementation follows those principles:
>>>>     - A forwarded IRQ only can be sampled when it is pending
>>>>     - when queueing the IRQ (programming the LR), the pending state
>>>>       is removed as for edge sensitive IRQs
>>>>     - an injection of a forwarded IRQ is considered always valid since
>>>>       coming from the HW and level always is 1.
>>>>
>>> I don't see anything wrong, and I thought this was what we discussed.
>>
>> I think I just lost track of what we've discussed at LCA. Ignore me.
>>
>> I'll repost the updated first 10 patches tomorrow. Eric, are you willing
>> to take custody of patch 11 as part of one of your series?
> Yes no problem I can take this over if you prefer. I can easily test it.
> May I put it in the irq forwarding series?

That would be its natural location.

Thanks,

	M.
-- 
Jazz is not dead. It just smells funny...


From vigneshr at ti.com  Fri Aug  7 01:35:10 2015
From: vigneshr at ti.com (Vignesh R)
Date: Fri, 7 Aug 2015 14:05:10 +0530
Subject: [RFC PATCH 1/5] spi: introduce flag for memory mapped read
In-Reply-To: <CAOMqctRBW230fA4AEhK7MyqkZY==6ENNNHE-LVm7-mHKA_VzRw@mail.gmail.com>
References: <20150805115013.GJ20873@sirena.org.uk>
 <CAOMqctQXwcHyiWBwtugSDSE_k65qrNfrwnhjQMDJkLoJMmGzUw@mail.gmail.com>
 <20150805124412.GN20873@sirena.org.uk>
 <CAOMqctS9Y5FxpUCCJew6+cnjH5iTvbzkH3g-8yrXs4OuS2pSGA@mail.gmail.com>
 <20150806090202.GO20873@sirena.org.uk>
 <CAOMqctQZRZ4zG_yYy=CeX3DX4NVNWN1COP4Q-2YvMun9xYOA7g@mail.gmail.com>
 <20150806102225.GI7576@n2100.arm.linux.org.uk> <55C35233.2000105@ti.com>
 <20150806135129.GJ7576@n2100.arm.linux.org.uk>
 <CAMuHMdWWDwZ=ziGQXFCnOX8pErXpsEi533J73_Hh=sEqq4hR6Q@mail.gmail.com>
 <20150806213340.GK7576@n2100.arm.linux.org.uk>
 <CAOMqctRBW230fA4AEhK7MyqkZY==6ENNNHE-LVm7-mHKA_VzRw@mail.gmail.com>
Message-ID: <55C46DBE.7060809@ti.com>



On 08/07/2015 01:08 PM, Michal Suchanek wrote:

> Now since the description is clearer it's obvious that ti-qspi cannot
> work fully mmapped as fsl-qspi does because the setup has to be done
> over normal spi access and using non-m25p80 devices on the same bus is
> a requirement.
> 
> The place where it is known if a transfer can use the mmap access is m25p80.c
> 
> So my suggestion is
> 
>  - add a new method for spi master that gets the read opcode, dummy
> length, address, address length, buffer, buffer length and performs
> read from the flash memory in a hardware-specific way
> 
> - add a check in m25p80.c that the master supports this feature and if
> so use it (eg check that the method is non-null)
> 
> Presumably if some new SPI controllers with similar feature are
> supported in the future they can use the same inteface because you
> pass on everything the m25p80 read knows.
> 

Ok... Do you mean something like this?

I will take m25p80 as example but can be expanded for any flash.

In include/linux/mtd.h:
	struct spi_mtd_config_info {
		struct spi_device 	*spi;
	        u32                     page_size;
	        u8                      addr_width;
       		u8                      erase_opcode;
	        u8                      read_opcode;
        	u8                      read_dummy;
	        u8                      program_opcode;
        	enum read_mode          flash_read;

	} /* subset of struct spi_nor */


In m25p80.c:

	static int m25p80_read(struct spi_nor *nor, loff_t from,
				size_t len, size_t *retlen,
				u_char *buf)
	{
		struct spi_mtd_config_info info;
		struct spi_device *spi;
		
		if (spi->master->spi_mtd_mmap_read) {
		  /* Populate spi_mtd_config_info */
		  spi->master->spi_mtd_mmap_read(&info, from, len,
						 retlen, buf);
		}
		else {
		/* no mtd specific acceleration supported try normal
		 * SPI way of communicating with flash
		 * continue with current code
		 * set up spi_message and call spi_sync()
		 */
	}

      }

In spi-ti-qspi.c:
Implement spi_mtd_mmap_read while holding master->bus_lock mutex.


-- 
Regards
Vignesh


From joro at 8bytes.org  Fri Aug  7 01:42:28 2015
From: joro at 8bytes.org (Joerg Roedel)
Date: Fri, 7 Aug 2015 10:42:28 +0200
Subject: [PATCH v5 1/3] iommu: Implement common IOMMU ops for DMA mapping
In-Reply-To: <6ce6b501501f611297ae0eae31e07b0d2060eaae.1438362603.git.robin.murphy@arm.com>
References: <cover.1438362603.git.robin.murphy@arm.com>
 <6ce6b501501f611297ae0eae31e07b0d2060eaae.1438362603.git.robin.murphy@arm.com>
Message-ID: <20150807084228.GU14980@8bytes.org>

On Fri, Jul 31, 2015 at 06:18:27PM +0100, Robin Murphy wrote:
> +int iommu_get_dma_cookie(struct iommu_domain *domain)
> +{
> +	struct iova_domain *iovad;
> +
> +	if (domain->dma_api_cookie)
> +		return -EEXIST;

Why do you call that dma_api_cookie? It is just a pointer to an iova
allocator, you can just name it as such, like domain->iova.

> +static struct iova *__alloc_iova(struct iova_domain *iovad, size_t size,
> +		dma_addr_t dma_limit)

I think you also need a struct device here to take segment boundary and
dma_mask into account.

> +/* The IOVA allocator knows what we mapped, so just unmap whatever that was */
> +static void __iommu_dma_unmap(struct iommu_domain *domain, dma_addr_t dma_addr)
> +{
> +	struct iova_domain *iovad = domain->dma_api_cookie;
> +	unsigned long shift = iova_shift(iovad);
> +	unsigned long pfn = dma_addr >> shift;
> +	struct iova *iova = find_iova(iovad, pfn);
> +	size_t size = iova_size(iova) << shift;
> +
> +	/* ...and if we can't, then something is horribly, horribly wrong */
> +	BUG_ON(iommu_unmap(domain, pfn << shift, size) < size);

This is a WARN_ON at most, not a BUG_ON condition, especially since this
type of bug is also catched with the dma-api debugging code.

> +static struct page **__iommu_dma_alloc_pages(unsigned int count, gfp_t gfp)
> +{
> +	struct page **pages;
> +	unsigned int i = 0, array_size = count * sizeof(*pages);
> +
> +	if (array_size <= PAGE_SIZE)
> +		pages = kzalloc(array_size, GFP_KERNEL);
> +	else
> +		pages = vzalloc(array_size);
> +	if (!pages)
> +		return NULL;
> +
> +	/* IOMMU can map any pages, so himem can also be used here */
> +	gfp |= __GFP_NOWARN | __GFP_HIGHMEM;
> +
> +	while (count) {
> +		struct page *page = NULL;
> +		int j, order = __fls(count);
> +
> +		/*
> +		 * Higher-order allocations are a convenience rather
> +		 * than a necessity, hence using __GFP_NORETRY until
> +		 * falling back to single-page allocations.
> +		 */
> +		for (order = min(order, MAX_ORDER); order > 0; order--) {
> +			page = alloc_pages(gfp | __GFP_NORETRY, order);
> +			if (!page)
> +				continue;
> +			if (PageCompound(page)) {
> +				if (!split_huge_page(page))
> +					break;
> +				__free_pages(page, order);
> +			} else {
> +				split_page(page, order);
> +				break;
> +			}
> +		}
> +		if (!page)
> +			page = alloc_page(gfp);
> +		if (!page) {
> +			__iommu_dma_free_pages(pages, i);
> +			return NULL;
> +		}
> +		j = 1 << order;
> +		count -= j;
> +		while (j--)
> +			pages[i++] = page++;
> +	}
> +	return pages;
> +}

Hmm, most dma-api implementation just try to allocate a big enough
region from the page-alloctor. Is it implemented different here to avoid
the use of CMA?


	Joerg



From hanjun.guo at linaro.org  Fri Aug  7 01:42:28 2015
From: hanjun.guo at linaro.org (Hanjun Guo)
Date: Fri, 07 Aug 2015 16:42:28 +0800
Subject: [PATCH v4 09/10] PCI: ACPI: Bind GIC MSI frame to PCI host bridge
In-Reply-To: <55C0C685.4000400@arm.com>
References: <1438164539-29256-1-git-send-email-hanjun.guo@linaro.org>
 <1438164539-29256-10-git-send-email-hanjun.guo@linaro.org>
 <55C0C685.4000400@arm.com>
Message-ID: <55C46F74.4020307@linaro.org>

On 08/04/2015 10:04 PM, Marc Zyngier wrote:
> On 29/07/15 11:08, Hanjun Guo wrote:
>> From: Suravee Suthikulpanit <Suravee.Suthikulpanit at amd.com>
>>
>> This patch introduces pci_host_bridge_acpi_msi_domain(), which queries
>> a GIC MSI irq-domain token and use it to retrieve an irq_domain with
>> DOMAIN_BUS_PCI_MSI bus type, and bind it to PCI host-bridge.
>>
>> Signed-off-by: Suravee Suthikulpanit <Suravee.Suthikulpanit at amd.com>
>> Signed-off-by: Hanjun Guo <hanjun.guo at linaro.org>
>> ---
>>   drivers/pci/pci-acpi.c   | 18 ++++++++++++++++++
>>   drivers/pci/probe.c      |  3 +++
>>   include/linux/pci-acpi.h |  4 ++++
>>   3 files changed, 25 insertions(+)
>>
>> diff --git a/drivers/pci/pci-acpi.c b/drivers/pci/pci-acpi.c
>> index 314a625..5f11653 100644
>> --- a/drivers/pci/pci-acpi.c
>> +++ b/drivers/pci/pci-acpi.c
>> @@ -9,6 +9,7 @@
>>
>>   #include <linux/delay.h>
>>   #include <linux/init.h>
>> +#include <linux/irqdomain.h>
>>   #include <linux/pci.h>
>>   #include <linux/pci_hotplug.h>
>>   #include <linux/module.h>
>> @@ -16,6 +17,7 @@
>>   #include <linux/pci-acpi.h>
>>   #include <linux/pm_runtime.h>
>>   #include <linux/pm_qos.h>
>> +#include <acpi/acpi_gic.h>
>>   #include "pci.h"
>>
>>   /*
>> @@ -681,6 +683,22 @@ static bool pci_acpi_bus_match(struct device *dev)
>>   	return dev_is_pci(dev);
>>   }
>>
>> +#ifdef CONFIG_GENERIC_MSI_IRQ_DOMAIN
>> +struct irq_domain *pci_host_bridge_acpi_msi_domain(struct pci_bus *bus)
>> +{
>> +	struct irq_domain *d = NULL;
>> +	void *token = acpi_gic_get_msi_token(&bus->dev);
>
> Do you see why I positively *hate* having hardware details in generic
> layers? They propagate everywhere...
>
>> +
>> +	if (token)
>> +		d = irq_find_matching_host(token, DOMAIN_BUS_PCI_MSI);
>> +
>> +	if (!d)
>> +		pr_debug("Fail to find domain for MSI\n");
>> +
>> +	return d;
>> +}
>> +#endif /*CONFIG_GENERIC_MSI_IRQ_DOMAIN*/
>> +
>>   static struct acpi_bus_type acpi_pci_bus = {
>>   	.name = "PCI",
>>   	.match = pci_acpi_bus_match,
>> diff --git a/drivers/pci/probe.c b/drivers/pci/probe.c
>> index a7afeac..8c1204c 100644
>> --- a/drivers/pci/probe.c
>> +++ b/drivers/pci/probe.c
>> @@ -12,6 +12,7 @@
>>   #include <linux/module.h>
>>   #include <linux/cpumask.h>
>>   #include <linux/pci-aspm.h>
>> +#include <linux/pci-acpi.h>
>>   #include <asm-generic/pci-bridge.h>
>>   #include "pci.h"
>>
>> @@ -670,6 +671,8 @@ static struct irq_domain *pci_host_bridge_msi_domain(struct pci_bus *bus)
>>   	 * should be called from here.
>>   	 */
>>   	d = pci_host_bridge_of_msi_domain(bus);
>> +	if (!d)
>> +		d = pci_host_bridge_acpi_msi_domain(bus);
>>
>>   	return d;
>>   }
>> diff --git a/include/linux/pci-acpi.h b/include/linux/pci-acpi.h
>> index a965efa..766d045 100644
>> --- a/include/linux/pci-acpi.h
>> +++ b/include/linux/pci-acpi.h
>> @@ -77,6 +77,8 @@ static inline void acpiphp_remove_slots(struct pci_bus *bus) { }
>>   static inline void acpiphp_check_host_bridge(struct acpi_device *adev) { }
>>   #endif
>>
>> +struct irq_domain *pci_host_bridge_acpi_msi_domain(struct pci_bus *bus);
>> +
>>   extern const u8 pci_acpi_dsm_uuid[];
>>   #define DEVICE_LABEL_DSM	0x07
>>   #define RESET_DELAY_DSM		0x08
>> @@ -85,6 +87,8 @@ extern const u8 pci_acpi_dsm_uuid[];
>>   #else	/* CONFIG_ACPI */
>>   static inline void acpi_pci_add_bus(struct pci_bus *bus) { }
>>   static inline void acpi_pci_remove_bus(struct pci_bus *bus) { }
>> +static inline struct irq_domain *
>> +pci_host_bridge_acpi_msi_domain(struct pci_bus *bus) { return NULL; }
>>   #endif	/* CONFIG_ACPI */
>>
>>   #ifdef CONFIG_ACPI_APEI
>>
>
> Once you solve the HW abstraction issue, this will be OK.

Sure, I will sync with Suravee to fix that.

Thanks for you comments!
Hanjun


From oliver+list at schinagl.nl  Fri Aug  7 01:45:53 2015
From: oliver+list at schinagl.nl (Olliver Schinagl)
Date: Fri, 07 Aug 2015 10:45:53 +0200
Subject: [linux-sunxi] [PATCH] musb: sunxi: Ignore VBus errors in host-only
 mode
In-Reply-To: <55C3709C.4080609@redhat.com>
References: <1438723553-4136-1-git-send-email-hdegoede@redhat.com>
 <55C31963.2010701@schinagl.nl> <55C3709C.4080609@redhat.com>
Message-ID: <55C47041.3000603@schinagl.nl>

Hey Hans,

On 06-08-15 16:35, Hans de Goede wrote:
> Hi,
>
> On 06-08-15 10:22, Olliver Schinagl wrote:
>> Hey Hans,
>>
>> I've tried getting your musb stuff working on a cubietruck, but i 
>> don't seem to see this patch on your linux-sunxi/sunxi-wip branch on 
>> github? Is your github branch fully functional at the moment?
>>
>> What I have done so far, is build the kernel using sunxi_defconfig 
>> and enabled USB_MUSB_SUNXI with its dependancies (musb isn't enabled 
>> there by default): USB_SUPPORT [=y] && USB_MUSB_HDRC [=y] && 
>> ARCH_SUNXI [=y] && NOP_USB_XCEIV [=y] && PHY_SUN4I_USB [=y] && EXTCON 
>> [=y] && GENERIC_PHY [=y]  Selects: SUNXI_SRAM [=y]
>>
>> I changed the dts from dr_mode='otg' to dr_mode='host', a) we only 
>> need host mode anyway (the id pin isn't properly connected)
>
> If you change the dr_mode to host then you _must_ also remove any 
> id_det and vbus_det
> gpio settings from the usb_phy node in the dts, as the sun4i phy code 
> detects
> host vs otg mode by checking for the presence of these.
Yes, this fixes it and makes it work. Thanks.

Also I apologize for not noticing this patch in your queue before :) 
Looks like everything is all ready in your WIP branch.

Now, I see that Chen-Yu found the same problems here:
http://permalink.gmane.org/gmane.comp.hardware.netbook.arm.sunxi/17843

So far, with your mentioned changes to remove the id and vbus gpio's you 
can have my

Tested-by: Olliver Schinagl <o.schinagl at ultimaker.com>

>
> > and b) I got an error about an known dr_mode before and this was the 
> quick and easy way.
>>
>> Dmesg produces the following related to musb.
>>
>> [    1.691062] usb_phy_generic.0.auto supply vcc not found, using 
>> dummy regulator
>> [    1.691445] musb-hdrc: ConfigData=0xde (UTMI-8, dyn FIFOs, bulk 
>> combine, bulk split, HB-ISO Rx, HB-ISO Tx, SoftConn)
>> [    1.691453] musb-hdrc: MHDRC RTL version 0.0
>> [    1.691467] musb-hdrc: 11/11 max ep, 5184/8192 memory
>> [    1.691543] musb-hdrc musb-hdrc.1.auto: MUSB HDRC host driver
>> [    1.691553] musb-hdrc musb-hdrc.1.auto: new USB bus registered, 
>> assigned bus number 5
>> [    1.692470] hub 5-0:1.0: USB hub found
>> [    1.692529] hub 5-0:1.0: 1 port detected
>> [    1.699956] sunxi-rtc 1c20d00.rtc: setting system clock to 
>> 2015-08-06 07:59:08 UTC (1438847948)
>> [    1.704733] usb0-vbus: disabling
>> [    1.765695] ldo4: disabling
>> [    1.808351] ldo3: disabling
>> [    1.848769] vcc5v0: disabling
>> [    1.848774] vcc3v0: disabling
>>
>> The usb_phy_generic missing shouldn't be too bad? But the usb0-vbus 
>> being disabled obviously might be related to the musb port not working?
>
> Correct.
>
> For starters I would try the dts changes I suggested above.
Yep that fixed it.
>
> Regards,
>
> Hans



From joro at 8bytes.org  Fri Aug  7 01:52:34 2015
From: joro at 8bytes.org (Joerg Roedel)
Date: Fri, 7 Aug 2015 10:52:34 +0200
Subject: [PATCH v5 2/3] arm64: Add IOMMU dma_ops
In-Reply-To: <8a5abd0a9929aae160ccb74d7a8d9c3698f61910.1438362603.git.robin.murphy@arm.com>
References: <cover.1438362603.git.robin.murphy@arm.com>
 <8a5abd0a9929aae160ccb74d7a8d9c3698f61910.1438362603.git.robin.murphy@arm.com>
Message-ID: <20150807085233.GV14980@8bytes.org>

On Fri, Jul 31, 2015 at 06:18:28PM +0100, Robin Murphy wrote:
> +/*
> + * TODO: Right now __iommu_setup_dma_ops() gets called too early to do
> + * everything it needs to - the device isn't yet fully created, and the
> + * IOMMU driver hasn't seen it yet, so we need this delayed attachment
> + * dance. Once IOMMU probe ordering is sorted to move the
> + * arch_setup_dma_ops() call later, all the notifier bits below become
> + * unnecessary, and will go away.
> + */
> +struct iommu_dma_notifier_data {
> +	struct list_head list;
> +	struct device *dev;
> +	struct iommu_domain *dma_domain;
> +};
> +static LIST_HEAD(iommu_dma_masters);
> +static DEFINE_MUTEX(iommu_dma_notifier_lock);

Ugh, thats incredibly ugly. Why can't you do the setup work then the
iommu driver sees the device? Just call the dma-api setup functions
there (like the x86 iommu drivers do it too) and be done without any
notifiers.

> +static void __iommu_setup_dma_ops(struct device *dev, u64 dma_base, u64 size,
> +				  const struct iommu_ops *ops)
> +{
> +	struct iommu_domain *domain;
> +	int err;
> +
> +	if (!ops)
> +		return;
> +	/*
> +	 * In a perfect world, everything happened in the right order up to
> +	 * here, and the IOMMU core has already attached the device to an
> +	 * appropriate default domain for us to set up...
> +	 */
> +	domain = iommu_get_domain_for_dev(dev);
> +	if (!domain) {
> +		/*
> +		 * Urgh. Reliable default domains for platform devices can't
> +		 * happen anyway without some sensible way of handling
> +		 * non-trivial groups. So until then, HORRIBLE HACKS!
> +		 */

I don't get this, what is preventing to rely on default domains here?

> +		domain = ops->domain_alloc(IOMMU_DOMAIN_DMA);

The IOMMU core should already tried to allocate an IOMMU_DOMAIN_DMA type
domain. No need to try this again here.



	Joerg



From marc.zyngier at arm.com  Fri Aug  7 01:52:32 2015
From: marc.zyngier at arm.com (Marc Zyngier)
Date: Fri, 07 Aug 2015 09:52:32 +0100
Subject: [PATCH TRIVIAL] Enable GICv2m on ARM virt machine
In-Reply-To: <00f501d0ce9c$4d57bcc0$e8073640$@samsung.com>
References: <00f501d0ce9c$4d57bcc0$e8073640$@samsung.com>
Message-ID: <55C471D0.8050400@arm.com>

Hi Pavel,

On 04/08/15 10:59, Pavel Fedin wrote:
> qemu implementation of "virt" includes GICv2m. This commit allows to use
> it also on ARM32 architecture.
> 
> Signed-off-by: Pavel Fedin <p.fedin at samsung.com>
> ---
>  arch/arm/Kconfig            | 1 +
>  arch/arm/include/asm/Kbuild | 1 +
>  2 files changed, 2 insertions(+)
> 
> diff --git a/arch/arm/Kconfig b/arch/arm/Kconfig
> index 45df48b..1091025 100644
> --- a/arch/arm/Kconfig
> +++ b/arch/arm/Kconfig
> @@ -815,6 +815,7 @@ config ARCH_VIRT
>  	bool "Dummy Virtual Machine" if ARCH_MULTI_V7
>  	select ARM_AMBA
>  	select ARM_GIC
> +	select ARM_GIC_V2M if PCI_MSI
>  	select ARM_PSCI
>  	select HAVE_ARM_ARCH_TIMER
>  
> diff --git a/arch/arm/include/asm/Kbuild b/arch/arm/include/asm/Kbuild
> index 3c4596d..01806f5 100644
> --- a/arch/arm/include/asm/Kbuild
> +++ b/arch/arm/include/asm/Kbuild
> @@ -14,6 +14,7 @@ generic-y += local.h
>  generic-y += local64.h
>  generic-y += mcs_spinlock.h
>  generic-y += msgbuf.h
> +generic-y += msi.h
>  generic-y += param.h
>  generic-y += parport.h
>  generic-y += poll.h
> 

You may want to add a comment about the dependency chain that requires
the generic msi.h.

Thanks,

	M.
-- 
Jazz is not dead. It just smells funny...


From joro at 8bytes.org  Fri Aug  7 01:55:17 2015
From: joro at 8bytes.org (Joerg Roedel)
Date: Fri, 7 Aug 2015 10:55:17 +0200
Subject: [PATCH v5 3/3] arm64: Hook up IOMMU dma_ops
In-Reply-To: <caecbce93dd4870995a000bebc8f58d1ca7e551e.1438362603.git.robin.murphy@arm.com>
References: <cover.1438362603.git.robin.murphy@arm.com>
 <caecbce93dd4870995a000bebc8f58d1ca7e551e.1438362603.git.robin.murphy@arm.com>
Message-ID: <20150807085516.GW14980@8bytes.org>

On Fri, Jul 31, 2015 at 06:18:29PM +0100, Robin Murphy wrote:
> +void arch_teardown_dma_ops(struct device *dev)
> +{
> +	struct iommu_domain *domain = iommu_get_domain_for_dev(dev);
> +
> +	if (domain) {
> +		iommu_detach_device(domain, dev);
> +		if (domain->type & __IOMMU_DOMAIN_ARM64_IOVA)
> +			iommu_put_dma_cookie(domain);
> +		if (domain->type & __IOMMU_DOMAIN_ARM64)
> +			iommu_domain_free(domain);
> +		dev->archdata.dma_ops = NULL;
> +	}
> +}

When is this called? In case a device gets removed the IOMMU core and
driver should take care of destroying the domain, at least when its a
default-domain. This is part of the iommu-group handling.


	Joerg



From marc.zyngier at arm.com  Fri Aug  7 02:04:22 2015
From: marc.zyngier at arm.com (Marc Zyngier)
Date: Fri, 07 Aug 2015 10:04:22 +0100
Subject: [PATCH 2/5] ACPI / ARM64: remove usage of
 BAD_MADT_ENTRY/BAD_MADT_GICC_ENTRY
In-Reply-To: <1438894770-31163-3-git-send-email-al.stone@linaro.org>
References: <1438894770-31163-1-git-send-email-al.stone@linaro.org>
 <1438894770-31163-3-git-send-email-al.stone@linaro.org>
Message-ID: <55C47496.5070902@arm.com>

Hi Al,

On 06/08/15 21:59, Al Stone wrote:
> Now that we have introduced the bad_madt_entry() function, and that
> function is being invoked in acpi_table_parse_madt() for us, there
> is no longer any need to use the BAD_MADT_ENTRY macro, or in the case
> of arm64, the BAD_MADT_GICC_ENTRY, too.
> 
> Signed-off-by: Al Stone <al.stone at linaro.org>
> Cc: Catalin Marinas <catalin.marinas at arm.com>
> Cc: Will Deacon <will.deacon at arm.com>
> Cc: Thomas Gleixner <tglx at linutronix.de>
> Cc: Jason Cooper <jason at lakedaemon.net>
> Cc: Marc Zyngier <marc.zyngier at arm.com>
> ---
>  arch/arm64/include/asm/acpi.h | 8 --------
>  arch/arm64/kernel/smp.c       | 2 --
>  drivers/irqchip/irq-gic.c     | 6 ------
>  3 files changed, 16 deletions(-)
> 
> diff --git a/arch/arm64/include/asm/acpi.h b/arch/arm64/include/asm/acpi.h
> index 406485e..39248d3 100644
> --- a/arch/arm64/include/asm/acpi.h
> +++ b/arch/arm64/include/asm/acpi.h
> @@ -19,14 +19,6 @@
>  #include <asm/psci.h>
>  #include <asm/smp_plat.h>
>  
> -/* Macros for consistency checks of the GICC subtable of MADT */
> -#define ACPI_MADT_GICC_LENGTH	\
> -	(acpi_gbl_FADT.header.revision < 6 ? 76 : 80)
> -
> -#define BAD_MADT_GICC_ENTRY(entry, end)						\
> -	(!(entry) || (unsigned long)(entry) + sizeof(*(entry)) > (end) ||	\
> -	 (entry)->header.length != ACPI_MADT_GICC_LENGTH)
> -
>  /* Basic configuration for ACPI */
>  #ifdef	CONFIG_ACPI
>  /* ACPI table mapping after acpi_gbl_permanent_mmap is set */
> diff --git a/arch/arm64/kernel/smp.c b/arch/arm64/kernel/smp.c
> index 50fb469..acd3b27 100644
> --- a/arch/arm64/kernel/smp.c
> +++ b/arch/arm64/kernel/smp.c
> @@ -438,8 +438,6 @@ acpi_parse_gic_cpu_interface(struct acpi_subtable_header *header,
>  	struct acpi_madt_generic_interrupt *processor;
>  
>  	processor = (struct acpi_madt_generic_interrupt *)header;
> -	if (BAD_MADT_GICC_ENTRY(processor, end))
> -		return -EINVAL;
>  
>  	acpi_table_print_madt_entry(header);
>  
> diff --git a/drivers/irqchip/irq-gic.c b/drivers/irqchip/irq-gic.c
> index 4dd8826..2735611 100644
> --- a/drivers/irqchip/irq-gic.c
> +++ b/drivers/irqchip/irq-gic.c
> @@ -1055,9 +1055,6 @@ gic_acpi_parse_madt_cpu(struct acpi_subtable_header *header,
>  
>  	processor = (struct acpi_madt_generic_interrupt *)header;
>  
> -	if (BAD_MADT_GICC_ENTRY(processor, end))
> -		return -EINVAL;
> -
>  	/*
>  	 * There is no support for non-banked GICv1/2 register in ACPI spec.
>  	 * All CPU interface addresses have to be the same.
> @@ -1079,9 +1076,6 @@ gic_acpi_parse_madt_distributor(struct acpi_subtable_header *header,
>  
>  	dist = (struct acpi_madt_generic_distributor *)header;
>  
> -	if (BAD_MADT_ENTRY(dist, end))
> -		return -EINVAL;
> -
>  	dist_phy_base = dist->base_address;
>  	return 0;
>  }
> 

Thanks a lot for doing this - the proliferation of this macro has been
driving me insane.

Acked-by: Marc Zyngier <marc.zyngier at arm.com>

	M.
-- 
Jazz is not dead. It just smells funny...


From srinivas.kandagatla at linaro.org  Fri Aug  7 02:11:23 2015
From: srinivas.kandagatla at linaro.org (Srinivas Kandagatla)
Date: Fri, 07 Aug 2015 10:11:23 +0100
Subject: [PATCH 2/3] nvmem: imx-ocotp: Add i.MX6 OCOTP driver
In-Reply-To: <1438933597.3638.5.camel@pengutronix.de>
References: <1438693342-605-1-git-send-email-p.zabel@pengutronix.de>		
 <1438693342-605-2-git-send-email-p.zabel@pengutronix.de>		
 <55C38941.9090709@linaro.org> <1438878490.3223.10.camel@pengutronix.de>	
 <55C3B74F.5010501@linaro.org> <1438933597.3638.5.camel@pengutronix.de>
Message-ID: <55C4763B.4090508@linaro.org>


On 07/08/15 08:46, Philipp Zabel wrote:
>>> Nobody. I had initially copied the code that actually senses the fuses,
>>> > >but since this happens during power-on reset anyway (all values are
>>> > >stored in shadow registers), I didn't see the point and dropped it for
>>> > >now.
>>> > >The shadow registers are clocked directly by the ungated ipg_root clock.
>> >
>> >So, are you planning to drop the clocks property from the bindings too?
> The gated clock input exists and is needed for the full functionality of
> the device (writing and re-sensing fuses).
Thanks for clarification.

--srini
  It should be in the device
> tree even if the linux driver doesn't implement writing.
>
> regards
> Philipp
>


From hl at rock-chips.com  Fri Aug  7 02:31:11 2015
From: hl at rock-chips.com (Lin Huang)
Date: Fri,  7 Aug 2015 17:31:11 +0800
Subject: [PATCH v4 1/2] clk: rockchip: add pclk_pd_pmu to the list of rk3288
 critical clocks
Message-ID: <1438939872-2116-1-git-send-email-hl@rock-chips.com>

pclk_pd_pmu needs to keep running and with the upcoming gpio clock
handling this is not always the case anymore. So add it to the list
of critical clocks for now.

From: Heiko Stuebner <heiko at sntech.de>
Signed-off-by: Lin Huang <hl at rock-chips.com>
---
Changes in v4:
- Add From: Heiko Stuebner <heiko at sntech.de>

 drivers/clk/rockchip/clk-rk3288.c | 1 +
 1 file changed, 1 insertion(+)

diff --git a/drivers/clk/rockchip/clk-rk3288.c b/drivers/clk/rockchip/clk-rk3288.c
index 0df5bae..9040878 100644
--- a/drivers/clk/rockchip/clk-rk3288.c
+++ b/drivers/clk/rockchip/clk-rk3288.c
@@ -780,6 +780,7 @@ static const char *const rk3288_critical_clocks[] __initconst = {
 	"aclk_cpu",
 	"aclk_peri",
 	"hclk_peri",
+	"pclk_pd_pmu",
 };
 
 #ifdef CONFIG_PM_SLEEP
-- 
1.9.1



From hl at rock-chips.com  Fri Aug  7 02:31:12 2015
From: hl at rock-chips.com (Lin Huang)
Date: Fri,  7 Aug 2015 17:31:12 +0800
Subject: [PATCH v4 2/2] pinctrl: rockchip: only enable gpio clock when it
 setting
In-Reply-To: <1438939872-2116-1-git-send-email-hl@rock-chips.com>
References: <1438939872-2116-1-git-send-email-hl@rock-chips.com>
Message-ID: <1438939872-2116-2-git-send-email-hl@rock-chips.com>

gpio can keep state even the clock disable, for save power
consumption, only enable gpio clock when it setting

Signed-off-by: Lin Huang <hl at rock-chips.com>
Reviewed-by: Heiko Stuebner <heiko at sntech.de>
---
Changes in v4:
-delete some unrelated new blank line

 drivers/pinctrl/pinctrl-rockchip.c | 55 +++++++++++++++++++++++++++++++++++---
 1 file changed, 51 insertions(+), 4 deletions(-)

diff --git a/drivers/pinctrl/pinctrl-rockchip.c b/drivers/pinctrl/pinctrl-rockchip.c
index cc2843a..c5246c0 100644
--- a/drivers/pinctrl/pinctrl-rockchip.c
+++ b/drivers/pinctrl/pinctrl-rockchip.c
@@ -945,6 +945,7 @@ static int _rockchip_pmx_gpio_set_direction(struct gpio_chip *chip,
 	if (ret < 0)
 		return ret;
 
+	clk_enable(bank->clk);
 	spin_lock_irqsave(&bank->slock, flags);
 
 	data = readl_relaxed(bank->reg_base + GPIO_SWPORT_DDR);
@@ -956,6 +957,7 @@ static int _rockchip_pmx_gpio_set_direction(struct gpio_chip *chip,
 	writel_relaxed(data, bank->reg_base + GPIO_SWPORT_DDR);
 
 	spin_unlock_irqrestore(&bank->slock, flags);
+	clk_disable(bank->clk);
 
 	return 0;
 }
@@ -1389,6 +1391,7 @@ static void rockchip_gpio_set(struct gpio_chip *gc, unsigned offset, int value)
 	unsigned long flags;
 	u32 data;
 
+	clk_enable(bank->clk);
 	spin_lock_irqsave(&bank->slock, flags);
 
 	data = readl(reg);
@@ -1398,6 +1401,7 @@ static void rockchip_gpio_set(struct gpio_chip *gc, unsigned offset, int value)
 	writel(data, reg);
 
 	spin_unlock_irqrestore(&bank->slock, flags);
+	clk_disable(bank->clk);
 }
 
 /*
@@ -1409,7 +1413,9 @@ static int rockchip_gpio_get(struct gpio_chip *gc, unsigned offset)
 	struct rockchip_pin_bank *bank = gc_to_pin_bank(gc);
 	u32 data;
 
+	clk_enable(bank->clk);
 	data = readl(bank->reg_base + GPIO_EXT_PORT);
+	clk_disable(bank->clk);
 	data >>= offset;
 	data &= 1;
 	return data;
@@ -1546,6 +1552,7 @@ static int rockchip_irq_set_type(struct irq_data *d, unsigned int type)
 	if (ret < 0)
 		return ret;
 
+	clk_enable(bank->clk);
 	spin_lock_irqsave(&bank->slock, flags);
 
 	data = readl_relaxed(bank->reg_base + GPIO_SWPORT_DDR);
@@ -1603,6 +1610,7 @@ static int rockchip_irq_set_type(struct irq_data *d, unsigned int type)
 	default:
 		irq_gc_unlock(gc);
 		spin_unlock_irqrestore(&bank->slock, flags);
+		clk_disable(bank->clk);
 		return -EINVAL;
 	}
 
@@ -1611,6 +1619,7 @@ static int rockchip_irq_set_type(struct irq_data *d, unsigned int type)
 
 	irq_gc_unlock(gc);
 	spin_unlock_irqrestore(&bank->slock, flags);
+	clk_disable(bank->clk);
 
 	return 0;
 }
@@ -1620,8 +1629,10 @@ static void rockchip_irq_suspend(struct irq_data *d)
 	struct irq_chip_generic *gc = irq_data_get_irq_chip_data(d);
 	struct rockchip_pin_bank *bank = gc->private;
 
+	clk_enable(bank->clk);
 	bank->saved_masks = irq_reg_readl(gc, GPIO_INTMASK);
 	irq_reg_writel(gc, ~gc->wake_active, GPIO_INTMASK);
+	clk_disable(bank->clk);
 }
 
 static void rockchip_irq_resume(struct irq_data *d)
@@ -1629,7 +1640,27 @@ static void rockchip_irq_resume(struct irq_data *d)
 	struct irq_chip_generic *gc = irq_data_get_irq_chip_data(d);
 	struct rockchip_pin_bank *bank = gc->private;
 
+	clk_enable(bank->clk);
 	irq_reg_writel(gc, bank->saved_masks, GPIO_INTMASK);
+	clk_disable(bank->clk);
+}
+
+static void rockchip_irq_gc_mask_clr_bit(struct irq_data *d)
+{
+	struct irq_chip_generic *gc = irq_data_get_irq_chip_data(d);
+	struct rockchip_pin_bank *bank = gc->private;
+
+	clk_enable(bank->clk);
+	irq_gc_mask_clr_bit(d);
+}
+
+void rockchip_irq_gc_mask_set_bit(struct irq_data *d)
+{
+	struct irq_chip_generic *gc = irq_data_get_irq_chip_data(d);
+	struct rockchip_pin_bank *bank = gc->private;
+
+	irq_gc_mask_set_bit(d);
+	clk_disable(bank->clk);
 }
 
 static int rockchip_interrupts_register(struct platform_device *pdev,
@@ -1640,7 +1671,7 @@ static int rockchip_interrupts_register(struct platform_device *pdev,
 	unsigned int clr = IRQ_NOREQUEST | IRQ_NOPROBE | IRQ_NOAUTOEN;
 	struct irq_chip_generic *gc;
 	int ret;
-	int i;
+	int i, j;
 
 	for (i = 0; i < ctrl->nr_banks; ++i, ++bank) {
 		if (!bank->valid) {
@@ -1649,11 +1680,19 @@ static int rockchip_interrupts_register(struct platform_device *pdev,
 			continue;
 		}
 
+		ret = clk_enable(bank->clk);
+		if (ret) {
+			dev_err(&pdev->dev, "failed to enable clock for bank %s\n",
+				bank->name);
+			continue;
+		}
+
 		bank->domain = irq_domain_add_linear(bank->of_node, 32,
 						&irq_generic_chip_ops, NULL);
 		if (!bank->domain) {
 			dev_warn(&pdev->dev, "could not initialize irq domain for bank %s\n",
 				 bank->name);
+			clk_disable(bank->clk);
 			continue;
 		}
 
@@ -1664,6 +1703,7 @@ static int rockchip_interrupts_register(struct platform_device *pdev,
 			dev_err(&pdev->dev, "could not alloc generic chips for bank %s\n",
 				bank->name);
 			irq_domain_remove(bank->domain);
+			clk_disable(bank->clk);
 			continue;
 		}
 
@@ -1681,8 +1721,9 @@ static int rockchip_interrupts_register(struct platform_device *pdev,
 		gc->chip_types[0].regs.mask = GPIO_INTMASK;
 		gc->chip_types[0].regs.ack = GPIO_PORTS_EOI;
 		gc->chip_types[0].chip.irq_ack = irq_gc_ack_set_bit;
-		gc->chip_types[0].chip.irq_mask = irq_gc_mask_set_bit;
-		gc->chip_types[0].chip.irq_unmask = irq_gc_mask_clr_bit;
+		gc->chip_types[0].chip.irq_mask = rockchip_irq_gc_mask_set_bit;
+		gc->chip_types[0].chip.irq_unmask =
+						  rockchip_irq_gc_mask_clr_bit;
 		gc->chip_types[0].chip.irq_set_wake = irq_gc_set_wake;
 		gc->chip_types[0].chip.irq_suspend = rockchip_irq_suspend;
 		gc->chip_types[0].chip.irq_resume = rockchip_irq_resume;
@@ -1691,6 +1732,12 @@ static int rockchip_interrupts_register(struct platform_device *pdev,
 
 		irq_set_chained_handler_and_data(bank->irq,
 						 rockchip_irq_demux, bank);
+
+		/* map the gpio irqs here, when the clock is still running */
+		for (j = 0 ; j < 32 ; j++)
+			irq_create_mapping(bank->domain, j);
+
+		clk_disable(bank->clk);
 	}
 
 	return 0;
@@ -1808,7 +1855,7 @@ static int rockchip_get_bank_data(struct rockchip_pin_bank *bank,
 	if (IS_ERR(bank->clk))
 		return PTR_ERR(bank->clk);
 
-	return clk_prepare_enable(bank->clk);
+	return clk_prepare(bank->clk);
 }
 
 static const struct of_device_id rockchip_pinctrl_dt_match[];
-- 
1.9.1



From matthias.klein at optimeas.de  Fri Aug  7 02:09:59 2015
From: matthias.klein at optimeas.de (Matthias Klein)
Date: Fri,  7 Aug 2015 11:09:59 +0200
Subject: [PATCH] ARM: dts: am335x-phycore-som: Move NAND partition table into
 board files
Message-ID: <1438938599-11252-1-git-send-email-matthias.klein@optimeas.de>

Partitions which are defined in the som file can not be deleted in the
board file.

Signed-off-by: Matthias Klein <matthias.klein at optimeas.de>
---
 arch/arm/boot/dts/am335x-phycore-som.dtsi | 37 -------------------------
 arch/arm/boot/dts/am335x-wega.dtsi        | 45 +++++++++++++++++++++++++++++++
 2 files changed, 45 insertions(+), 37 deletions(-)

diff --git a/arch/arm/boot/dts/am335x-phycore-som.dtsi b/arch/arm/boot/dts/am335x-phycore-som.dtsi
index 4d28fc3..8f12bd54 100644
--- a/arch/arm/boot/dts/am335x-phycore-som.dtsi
+++ b/arch/arm/boot/dts/am335x-phycore-som.dtsi
@@ -189,43 +189,6 @@
 
 		#address-cells = <1>;
 		#size-cells = <1>;
-
-		partition at 0 {
-			label = "xload";
-			reg = <0x0 0x20000>;
-		};
-		partition at 1 {
-			label = "xload_backup1";
-			reg = <0x20000 0x20000>;
-		};
-		partition at 2 {
-			label = "xload_backup2";
-			reg = <0x40000 0x20000>;
-		};
-		partition at 3 {
-			label = "xload_backup3";
-			reg = <0x60000 0x20000>;
-		};
-		partition at 4 {
-			label = "barebox";
-			reg = <0x80000 0x80000>;
-		};
-		partition at 5 {
-			label = "bareboxenv";
-			reg = <0x100000 0x40000>;
-		};
-		partition at 6 {
-			label = "oftree";
-			reg = <0x140000 0x40000>;
-		};
-		partition at 7 {
-			label = "kernel";
-			reg = <0x180000 0x800000>;
-		};
-		partition at 8 {
-			label = "root";
-			reg = <0x980000 0x0>;
-		};
 	};
 };
 
diff --git a/arch/arm/boot/dts/am335x-wega.dtsi b/arch/arm/boot/dts/am335x-wega.dtsi
index 5e541bd..945a41d 100644
--- a/arch/arm/boot/dts/am335x-wega.dtsi
+++ b/arch/arm/boot/dts/am335x-wega.dtsi
@@ -149,3 +149,48 @@
 &usb1_phy {
 	status = "okay";
 };
+
+&nandflash {
+	partition at 0 {
+		label = "xload";
+		reg = <0x0 0x20000>;
+	};
+
+	partition at 1 {
+		label = "xload_backup1";
+		reg = <0x20000 0x20000>;
+	};
+
+	partition at 2 {
+		label = "xload_backup2";
+		reg = <0x40000 0x20000>;
+	};
+
+	partition at 3 {
+		label = "xload_backup3";
+		reg = <0x60000 0x20000>;
+	};
+
+	partition at 4 {
+		label = "barebox";
+		reg = <0x80000 0x80000>;
+	};
+
+	partition at 5 {
+		label = "bareboxenv";
+		reg = <0x100000 0x40000>;
+	};
+
+	partition at 6 {
+		label = "oftree";
+		reg = <0x140000 0x40000>;
+	};
+	partition at 7 {
+		label = "kernel";
+		reg = <0x180000 0x800000>;
+	};
+	partition at 8 {
+		label = "root";
+		reg = <0x980000 0x0>;
+	};
+};
-- 
2.1.4



From srinivas.kandagatla at linaro.org  Fri Aug  7 02:32:41 2015
From: srinivas.kandagatla at linaro.org (Srinivas Kandagatla)
Date: Fri, 07 Aug 2015 10:32:41 +0100
Subject: [PATCH v1 1/7] ARM: dts: ifc6410: Add pwrseq support for WLAN
In-Reply-To: <55B959C4.2090600@codeaurora.org>
References: <1438087956-17307-1-git-send-email-srinivas.kandagatla@linaro.org>
 <1438088022-17350-1-git-send-email-srinivas.kandagatla@linaro.org>
 <55B959C4.2090600@codeaurora.org>
Message-ID: <55C47B39.3030607@linaro.org>



On 29/07/15 23:55, Stephen Boyd wrote:
> On 07/28/2015 05:53 AM, Srinivas Kandagatla wrote:
>> +
>> +        sdcc4_pwrseq:pwrseq {
>
> Missing space here between label and node name.
>
I will fix this in next version.
>> +            compatible = "mmc-pwrseq-simple";
>> +            reset-gpios = <&pm8921_gpio 43 GPIO_ACTIVE_LOW>;
>> +        };
>> +
>
> Also this node is not part of the SoC so it should be in the root,
> possibly under some sort of power-sequences node so that all the
> sequences are grouped in one place.
Good spot and suggestion. I will do that in next version.

--srini
>


From srinivas.kandagatla at linaro.org  Fri Aug  7 02:41:48 2015
From: srinivas.kandagatla at linaro.org (Srinivas Kandagatla)
Date: Fri, 07 Aug 2015 10:41:48 +0100
Subject: [PATCH v1 7/7] ARM: dts: ifc6410: add inforce LVDS panel support
In-Reply-To: <55B957B4.40501@codeaurora.org>
References: <1438087956-17307-1-git-send-email-srinivas.kandagatla@linaro.org>
 <1438088076-17606-1-git-send-email-srinivas.kandagatla@linaro.org>
 <55B957B4.40501@codeaurora.org>
Message-ID: <55C47D5C.8060905@linaro.org>



On 29/07/15 23:46, Stephen Boyd wrote:
> On 07/28/2015 05:54 AM, Srinivas Kandagatla wrote:
>> +
>> +        panel_3p3v: panel_3p3v {
>> +            compatible = "regulator-fixed";
>> +            pinctrl-0 = <&disp_en_gpios>;
>> +            pinctrl-names = "default";
>> +            regulator-min-microvolt = <3300000>;
>> +            regulator-max-microvolt = <3300000>;
>> +            regulator-name = "panel_en_3p3v";
>> +            regulator-type = "voltage";
>> +            startup-delay-us = <0>;
>> +            gpio = <&pm8921_gpio 36 GPIO_ACTIVE_HIGH>;
>> +            enable-active-high;
>> +            regulator-boot-on;
>> +        };
>
> We should put gpio regulators into their own container in the root of
> the tree. Similar to what was done for 8960 gpio regulators.
I agree, Will do this in next version.
>
>> +
>> +        backlight: backlight{
>> +            pinctrl-0 = <&pwm_bl_gpios>;
>> +            pinctrl-names = "default";
>> +            compatible = "gpio-backlight";
>> +            gpios = <&pm8921_gpio 26 GPIO_ACTIVE_HIGH>;
>> +            default-on;
>> +        };
>> +
>> +        panel: auo,b101xtn01 {
>> +            status = "okay";
>> +            compatible = "auo,b101xtn01";
>> +
>> +            ddc-i2c-bus = <&i2c3>;
>> +            backlight = <&backlight>;
>> +            power-supply = <&panel_3p3v>;
>>           };
>
> These two nodes shouldn't be under the SoC node. They don't have
> registers so they should be at the root of the tree. And we don't need
> to put labels twice on nodes. If we're modifying things in board
> specific dtsi files it should be fine to leave the label off if the
> label is in the SoC dtsi file.
Yep, will fix it in next version.
>


From hl at rock-chips.com  Fri Aug  7 02:41:45 2015
From: hl at rock-chips.com (hl)
Date: Fri, 07 Aug 2015 17:41:45 +0800
Subject: [PATCH v4 1/2] clk: rockchip: add pclk_pd_pmu to the list of
 rk3288 critical clocks
In-Reply-To: <1438939872-2116-1-git-send-email-hl@rock-chips.com>
References: <1438939872-2116-1-git-send-email-hl@rock-chips.com>
Message-ID: <55C47D59.8080403@rock-chips.com>

Hi Heiko,
> pclk_pd_pmu needs to keep running and with the upcoming gpio clock
> handling this is not always the case anymore. So add it to the list
> of critical clocks for now.
>
> From: Heiko Stuebner <heiko at sntech.de>
> Signed-off-by: Lin Huang <hl at rock-chips.com>
     is it the right way?  if it still can not meet the requirement, 
please let me know.
> ---
> Changes in v4:
> - Add From: Heiko Stuebner <heiko at sntech.de>
>
>   drivers/clk/rockchip/clk-rk3288.c | 1 +
>   1 file changed, 1 insertion(+)
>
> diff --git a/drivers/clk/rockchip/clk-rk3288.c b/drivers/clk/rockchip/clk-rk3288.c
> index 0df5bae..9040878 100644
> --- a/drivers/clk/rockchip/clk-rk3288.c
> +++ b/drivers/clk/rockchip/clk-rk3288.c
> @@ -780,6 +780,7 @@ static const char *const rk3288_critical_clocks[] __initconst = {
>   	"aclk_cpu",
>   	"aclk_peri",
>   	"hclk_peri",
> +	"pclk_pd_pmu",
>   };
>   
>   #ifdef CONFIG_PM_SLEEP



From stefano.stabellini at eu.citrix.com  Fri Aug  7 02:41:15 2015
From: stefano.stabellini at eu.citrix.com (Stefano Stabellini)
Date: Fri, 7 Aug 2015 10:41:15 +0100
Subject: Fw: drivers/xen/pci.c:31:25: fatal error: asm/pci_x86.h: No such
 file or directory
In-Reply-To: <55C39ABC.5020101@oracle.com>
References: <20150806170426.GM1820@rric.localhost>
 <55C39ABC.5020101@oracle.com>
Message-ID: <alpine.DEB.2.02.1508071021040.11337@kaball.uk.xensource.com>

On Thu, 6 Aug 2015, Boris Ostrovsky wrote:
> On 08/06/2015 01:04 PM, Robert Richter wrote:
> > Boris,
> > 
> > we are working on acpi pci support for arm64. For this we are enabling
> > PCI_MMCONFIG on arm64 which breaks compiling drivers/xen/pci.c.
> > 
> > Looking into it there is x86 code in generic driver code introduced
> > with:
> > 
> >   8deb3eb1461e xen/mcfg: Call PHYSDEVOP_pci_mmcfg_reserved for MCFG areas.
> > 
> > This implements:
> > 
> > diff --git a/drivers/xen/pci.c b/drivers/xen/pci.c
> > index 18fff88254eb..d15f6e80479f 100644
> > --- a/drivers/xen/pci.c
> > +++ b/drivers/xen/pci.c
> > @@ -26,6 +26,7 @@
> >   #include <asm/xen/hypervisor.h>
> >   #include <asm/xen/hypercall.h>
> >   #include "../pci/pci.h"
> > +#include <asm/pci_x86.h>
> >     static bool __read_mostly pci_seg_supported = true;
> >   @@ -192,3 +193,49 @@ static int __init register_xen_pci_notifier(void)
> >   }
> >     arch_initcall(register_xen_pci_notifier);
> > +
> > +#ifdef CONFIG_PCI_MMCONFIG
> > +static int __init xen_mcfg_late(void)
> > +{
> > +       struct pci_mmcfg_region *cfg;
> > +       int rc;
> > +
> > +       if (!xen_initial_domain())
> > +               return 0;
> > +
> > +       if ((pci_probe & PCI_PROBE_MMCONF) == 0)
> > +               return 0;
> > [...]
> > 
> > There are no defines for pci_probe and PCI_PROBE_MMCONF other than for
> > the x86 architecture.
> > 
> > I see several ways to fix that:
> > 
> >   * moving code to arch/x86/pci/xen.c,
> 
> If this routine is not going to be used by ARM I think this would be the way
> to go. Stefano --- will this be needed by ARM?

Yes, I think it is most probable that this code will be needed on ARM,
even though we are still at the design doc stage for Xen and ACPI on ARM
at the moment.

Besides I think you should be able to compile this function on arm64
just fine. The hypercall should build without issues. If the problem is
just this one check, we should be able to rework it somehow.

Is there something equivalent to pci_probe on arm? If not, we could just
ifdef the check for x86.


> > 
> >   * make code dependent on arch X86,
> > 
> >   * make 'if (pci_probe & PCI_PROBE_MMCONF) ...' an arch function to be
> >     implemented by archs,
> 
> Otherwise I'd go with this.

Or this of course


> -boris
> 
> > 
> >   * reworking the code by removing the check (not sure if that could be
> >     done).
> > 
> > I don't think PCI_XEN is enabled yet for arm64, so we just disalbe it
> > for !X86 or move it to arch/x86. I suggest the latter. Is there any
> > preference you have?
> 


From sudeep.holla at arm.com  Fri Aug  7 02:45:22 2015
From: sudeep.holla at arm.com (Sudeep Holla)
Date: Fri, 07 Aug 2015 10:45:22 +0100
Subject: [PATCH v4 1/6] ARM: shmobile: r8a7740 dtsi: Add L2
 cache-controller node
In-Reply-To: <CAMuHMdVAOba0ofmoy8OH2DdY1m3XaD8iOXvXBE035=C4yK58VQ@mail.gmail.com>
References: <1438765090-823-1-git-send-email-geert+renesas@glider.be>	<1438765090-823-2-git-send-email-geert+renesas@glider.be>	<55C1D894.8070302@arm.com>	<CAMuHMdXdEV+41mH338bDbazzqOErDLQkBUAj2+uVX4Wupn1ABQ@mail.gmail.com>	<55C1EC3C.9000407@arm.com>
 <CAMuHMdVAOba0ofmoy8OH2DdY1m3XaD8iOXvXBE035=C4yK58VQ@mail.gmail.com>
Message-ID: <55C47E32.6070400@arm.com>



On 06/08/15 17:21, Geert Uytterhoeven wrote:
> Hi Sudeep,
>
> On Wed, Aug 5, 2015 at 12:58 PM, Sudeep Holla <sudeep.holla at arm.com> wrote:
>> On 05/08/15 11:44, Geert Uytterhoeven wrote:
>>> On Wed, Aug 5, 2015 at 11:34 AM, Sudeep Holla <sudeep.holla at arm.com>
>>> wrote:

[..]

>>>>
>>>> Any particular reason whey you need all this cache-* properties ? Is
>>>
>>> To describe the cache as good as possible.
>>
>> Why if you can probe it ? IMO DT is mostly useful to describe things
>> that can't be probed/discovered using hardware.
>>
>>>> something broken on these SoCs ? We should be able to get most of these
>>>> information from the SoC(reading some registers). It's good to avoid
>>>> passing them via DT if they can be discovered from hardware.
>>>
>>> So we have all these documented properties in
>>> Documentation/devicetree/bindings/arm/l2cc.txt, but they're not meant to
>>> be used?
>>
>> No I didn't mean that, I just wanted to know if they can't be probed due
>> to some hardware issue. It would avoid issues with wrong DTs especially
>> if they are not so easy to upgrade.
>
> I think it works just fine without them.
>

Yes, in general if you specify a value in DT that can be probed, its
usually to override the probed value(useful if there is some h/w errata)...

> Should I drop all cache-* properties marked optional in
> Documentation/devicetree/bindings/arm/l2cc.txt?
> That would be cache-size, cache-sets, cache-block-size, and cache-line-size.
>

... however if you incorrect values by mistake, then it's problematic
even if h/w provides correct value.


> What about the L1 cache? I know Linux uses none of the d-cache-*
> and i-cache-* properties.
>

Same there, IIRC PPC use them, but on ARM I think so far the need has
not arise.

Just to re-iterate myself, I am not against adding them, but it's not
really needed. I just wanted to know if there was any h/w issue.

Regards,
Sudeep


From p.zabel at pengutronix.de  Fri Aug  7 02:48:19 2015
From: p.zabel at pengutronix.de (Philipp Zabel)
Date: Fri,  7 Aug 2015 11:48:19 +0200
Subject: [PATCH v2 0/2] i.MX6 OCOTP NVMEM support
Message-ID: <1438940901-5779-1-git-send-email-p.zabel@pengutronix.de>

Hi,

These patches add support for the i.MX On-Chip OTP (eFuse) Controller found
in i.MX6Q/D, i.MX6S/DL, i.MX6SL, and i.MX6SX SoCs to the NVMEM framework.
Greg, could you take them into the char-misc tree together with the NVMEM
framework?

Changes since v1:
 - Dropped unneeded clk.h include
 - Fixed MODULE_LICENSE
 - Droped third patch (adding the clock to the device tree node can be done separately)

Philipp Zabel (2):
  nvmem: Add i.MX6 OCOTP device tree binding documentation
  nvmem: imx-ocotp: Add i.MX6 OCOTP driver

 .../devicetree/bindings/nvmem/imx-ocotp.txt        |  20 +++
 drivers/nvmem/Kconfig                              |  11 ++
 drivers/nvmem/Makefile                             |   2 +
 drivers/nvmem/imx-ocotp.c                          | 154 +++++++++++++++++++++
 4 files changed, 187 insertions(+)
 create mode 100644 Documentation/devicetree/bindings/nvmem/imx-ocotp.txt
 create mode 100644 drivers/nvmem/imx-ocotp.c

-- 
2.4.6

regards
Philipp


From p.zabel at pengutronix.de  Fri Aug  7 02:48:20 2015
From: p.zabel at pengutronix.de (Philipp Zabel)
Date: Fri,  7 Aug 2015 11:48:20 +0200
Subject: [PATCH v2 1/2] nvmem: Add i.MX6 OCOTP device tree binding
 documentation
In-Reply-To: <1438940901-5779-1-git-send-email-p.zabel@pengutronix.de>
References: <1438940901-5779-1-git-send-email-p.zabel@pengutronix.de>
Message-ID: <1438940901-5779-2-git-send-email-p.zabel@pengutronix.de>

This patch documents the i.MX6 OCOTP device tree binding.

Signed-off-by: Philipp Zabel <p.zabel at pengutronix.de>
---
 .../devicetree/bindings/nvmem/imx-ocotp.txt          | 20 ++++++++++++++++++++
 1 file changed, 20 insertions(+)
 create mode 100644 Documentation/devicetree/bindings/nvmem/imx-ocotp.txt

diff --git a/Documentation/devicetree/bindings/nvmem/imx-ocotp.txt b/Documentation/devicetree/bindings/nvmem/imx-ocotp.txt
new file mode 100644
index 0000000..93e2ad3
--- /dev/null
+++ b/Documentation/devicetree/bindings/nvmem/imx-ocotp.txt
@@ -0,0 +1,20 @@
+Freescale i.MX6 On-Chip OTP Controller (OCOTP) device tree bindings
+
+This binding represents the on-chip eFuse OTP controller found on
+i.MX6Q/D, i.MX6DL/S, i.MX6SL, and i.MX6SX SoCs.
+
+Required properties:
+- compatible: should be one of
+	"fsl,imx6q-ocotp" (i.MX6Q/D/DL/S),
+	"fsl,imx6sl-ocotp" (i.MX6SL), or
+	"fsl,imx6sx-ocotp" (i.MX6SX), followed by "syscon".
+- reg: Should contain the register base and length.
+- clocks: Should contain a phandle pointing to the gated peripheral clock.
+
+Example:
+
+	ocotp: ocotp at 021bc000 {
+		compatible = "fsl,imx6q-ocotp", "syscon";
+		reg = <0x021bc000 0x4000>;
+		clocks = <&clks IMX6QDL_CLK_IIM>;
+	};
-- 
2.4.6



From p.zabel at pengutronix.de  Fri Aug  7 02:48:21 2015
From: p.zabel at pengutronix.de (Philipp Zabel)
Date: Fri,  7 Aug 2015 11:48:21 +0200
Subject: [PATCH v2 2/2] nvmem: imx-ocotp: Add i.MX6 OCOTP driver
In-Reply-To: <1438940901-5779-1-git-send-email-p.zabel@pengutronix.de>
References: <1438940901-5779-1-git-send-email-p.zabel@pengutronix.de>
Message-ID: <1438940901-5779-3-git-send-email-p.zabel@pengutronix.de>

This driver handles the i.MX On-Chip OTP Controller found in
i.MX6Q/D, i.MX6S/DL, i.MX6SL, and i.MX6SX SoCs. Currently it
just returns the values stored in the shadow registers.

Signed-off-by: Philipp Zabel <p.zabel at pengutronix.de>
Acked-by: Srinivas Kandagatla <srinivas.kandagatla at linaro.org>
---
Changes since v1:
 - Dropped unneeded clk.h include
 - Fixed MODULE_LICENSE
---
 drivers/nvmem/Kconfig     |  11 ++++
 drivers/nvmem/Makefile    |   2 +
 drivers/nvmem/imx-ocotp.c | 154 ++++++++++++++++++++++++++++++++++++++++++++++
 3 files changed, 167 insertions(+)
 create mode 100644 drivers/nvmem/imx-ocotp.c

diff --git a/drivers/nvmem/Kconfig b/drivers/nvmem/Kconfig
index 8db2978..0b33014 100644
--- a/drivers/nvmem/Kconfig
+++ b/drivers/nvmem/Kconfig
@@ -36,4 +36,15 @@ config NVMEM_SUNXI_SID
 	  This driver can also be built as a module. If so, the module
 	  will be called nvmem_sunxi_sid.
 
+config NVMEM_IMX_OCOTP
+	tristate "i.MX6 On-Chip OTP Controller support"
+	depends on SOC_IMX6
+	help
+	  This is a driver for the On-Chip OTP Controller (OCOTP) available on
+	  i.MX6 SoCs, providing access to 4 Kbits of one-time programmable
+	  eFuses.
+
+	  This driver can also be built as a module. If so, the module
+	  will be called nvmem-imx-ocotp.
+
 endif
diff --git a/drivers/nvmem/Makefile b/drivers/nvmem/Makefile
index 4328b93..b512d77 100644
--- a/drivers/nvmem/Makefile
+++ b/drivers/nvmem/Makefile
@@ -10,3 +10,5 @@ obj-$(CONFIG_QCOM_QFPROM)	+= nvmem_qfprom.o
 nvmem_qfprom-y			:= qfprom.o
 obj-$(CONFIG_NVMEM_SUNXI_SID)	+= nvmem_sunxi_sid.o
 nvmem_sunxi_sid-y		:= sunxi_sid.o
+obj-$(CONFIG_NVMEM_IMX_OCOTP)	+= nvmem-imx-ocotp.o
+nvmem-imx-ocotp-y		:= imx-ocotp.o
diff --git a/drivers/nvmem/imx-ocotp.c b/drivers/nvmem/imx-ocotp.c
new file mode 100644
index 0000000..b7971d4
--- /dev/null
+++ b/drivers/nvmem/imx-ocotp.c
@@ -0,0 +1,154 @@
+/*
+ * i.MX6 OCOTP fusebox driver
+ *
+ * Copyright (c) 2015 Pengutronix, Philipp Zabel <p.zabel at pengutronix.de>
+ *
+ * Based on the barebox ocotp driver,
+ * Copyright (c) 2010 Baruch Siach <baruch at tkos.co.il>,
+ *	Orex Computed Radiography
+ *
+ * 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.
+ *
+ * http://www.opensource.org/licenses/gpl-license.html
+ * http://www.gnu.org/copyleft/gpl.html
+ */
+
+#include <linux/device.h>
+#include <linux/io.h>
+#include <linux/module.h>
+#include <linux/nvmem-provider.h>
+#include <linux/of.h>
+#include <linux/of_device.h>
+#include <linux/platform_device.h>
+#include <linux/regmap.h>
+#include <linux/slab.h>
+
+struct ocotp_priv {
+	struct device *dev;
+	void __iomem *base;
+	unsigned int nregs;
+};
+
+static int imx_ocotp_read(void *context, const void *reg, size_t reg_size,
+			  void *val, size_t val_size)
+{
+	struct ocotp_priv *priv = context;
+	unsigned int offset = *(u32 *)reg;
+	unsigned int count;
+	int i;
+	u32 index;
+
+	index = offset >> 2;
+	count = val_size >> 2;
+
+	if (count > (priv->nregs - index))
+		count = priv->nregs - index;
+
+	for (i = index; i < (index + count); i++) {
+		*(u32 *)val = readl(priv->base + 0x400 + i * 0x10);
+		val += 4;
+	}
+
+	return (i - index) * 4;
+}
+
+static int imx_ocotp_write(void *context, const void *data, size_t count)
+{
+	/* Not implemented */
+	return 0;
+}
+
+static struct regmap_bus imx_ocotp_bus = {
+	.read = imx_ocotp_read,
+	.write = imx_ocotp_write,
+	.reg_format_endian_default = REGMAP_ENDIAN_NATIVE,
+	.val_format_endian_default = REGMAP_ENDIAN_NATIVE,
+};
+
+static bool imx_ocotp_writeable_reg(struct device *dev, unsigned int reg)
+{
+	return false;
+}
+
+static struct regmap_config imx_ocotp_regmap_config = {
+	.reg_bits = 32,
+	.val_bits = 32,
+	.reg_stride = 4,
+	.writeable_reg = imx_ocotp_writeable_reg,
+	.name = "imx-ocotp",
+};
+
+static struct nvmem_config imx_ocotp_nvmem_config = {
+	.name = "imx-ocotp",
+	.read_only = true,
+	.owner = THIS_MODULE,
+};
+
+static const struct of_device_id imx_ocotp_dt_ids[] = {
+	{ .compatible = "fsl,imx6q-ocotp",  (void *)128 },
+	{ .compatible = "fsl,imx6sl-ocotp", (void *)32 },
+	{ .compatible = "fsl,imx6sx-ocotp", (void *)128 },
+	{ },
+};
+MODULE_DEVICE_TABLE(of, imx_ocotp_dt_ids);
+
+static int imx_ocotp_probe(struct platform_device *pdev)
+{
+	const struct of_device_id *of_id;
+	struct device *dev = &pdev->dev;
+	struct resource *res;
+	struct regmap *regmap;
+	struct ocotp_priv *priv;
+	struct nvmem_device *nvmem;
+
+	priv = devm_kzalloc(dev, sizeof(*priv), GFP_KERNEL);
+	if (!priv)
+		return -ENOMEM;
+
+	res = platform_get_resource(pdev, IORESOURCE_MEM, 0);
+	priv->base = devm_ioremap_resource(dev, res);
+	if (IS_ERR(priv->base))
+		return PTR_ERR(priv->base);
+
+	of_id = of_match_device(imx_ocotp_dt_ids, dev);
+	priv->nregs = (unsigned int)of_id->data;
+	imx_ocotp_regmap_config.max_register = 4 * priv->nregs - 4;
+
+	regmap = devm_regmap_init(dev, &imx_ocotp_bus, priv,
+				  &imx_ocotp_regmap_config);
+	if (IS_ERR(regmap)) {
+		dev_err(dev, "regmap init failed\n");
+		return PTR_ERR(regmap);
+	}
+	imx_ocotp_nvmem_config.dev = dev;
+	nvmem = nvmem_register(&imx_ocotp_nvmem_config);
+	if (IS_ERR(nvmem))
+		return PTR_ERR(nvmem);
+
+	platform_set_drvdata(pdev, nvmem);
+
+	return 0;
+}
+
+static int imx_ocotp_remove(struct platform_device *pdev)
+{
+	struct nvmem_device *nvmem = platform_get_drvdata(pdev);
+
+	return nvmem_unregister(nvmem);
+}
+
+static struct platform_driver imx_ocotp_driver = {
+	.probe	= imx_ocotp_probe,
+	.remove	= imx_ocotp_remove,
+	.driver = {
+		.name	= "imx_ocotp",
+		.of_match_table = imx_ocotp_dt_ids,
+	},
+};
+module_platform_driver(imx_ocotp_driver);
+
+MODULE_AUTHOR("Philipp Zabel <p.zabel at pengutronix.de>");
+MODULE_DESCRIPTION("i.MX6 OCOTP fuse box driver");
+MODULE_LICENSE("GPL v2");
-- 
2.4.6



From Haibo.Chen at freescale.com  Fri Aug  7 02:53:01 2015
From: Haibo.Chen at freescale.com (Chen Bough)
Date: Fri, 7 Aug 2015 09:53:01 +0000
Subject: [PATCH v4 1/6] mmc: sdhci-esdhc-imx: add imx7d support and
 support HS400
In-Reply-To: <20150807073854.GA6935@shlinux1.ap.freescale.net>
References: <1438771122-8601-1-git-send-email-haibo.chen@freescale.com>
 <1438771122-8601-2-git-send-email-haibo.chen@freescale.com>
 <20150807073854.GA6935@shlinux1.ap.freescale.net>
Message-ID: <BY1PR03MB138813618D918A609ED1D7ED9A730@BY1PR03MB1388.namprd03.prod.outlook.com>



> -----Original Message-----
> From: Dong Aisheng [mailto:aisheng.dong at freescale.com]
> Sent: Friday, August 07, 2015 3:39 PM
> To: Chen Haibo-B51421
> Cc: robh+dt at kernel.org; pawel.moll at arm.com; mark.rutland at arm.com;
> ijc+devicetree at hellion.org.uk; galak at codeaurora.org; shawnguo at kernel.org;
> kernel at pengutronix.de; linux at arm.linux.org.uk; ulf.hansson at linaro.org;
> johan.derycke at barco.com; mkl at pengutronix.de; Estevam Fabio-R49496; Dong
> Aisheng-B29396; devicetree at vger.kernel.org; linux-kernel at vger.kernel.org;
> linux-arm-kernel at lists.infradead.org; linux-mmc at vger.kernel.org
> Subject: Re: [PATCH v4 1/6] mmc: sdhci-esdhc-imx: add imx7d support and
> support HS400
> 
> On Wed, Aug 05, 2015 at 06:38:37PM +0800, Haibo Chen wrote:
> > The imx7d usdhc is derived from imx6sx, the difference is that imx7d
> > support HS400.
> >
> > So introduce a new compatible string for imx7d and add HS400 support
> > for imx7d usdhc.
> >
> > Signed-off-by: Haibo Chen <haibo.chen at freescale.com>
> > ---
> >  drivers/mmc/host/sdhci-esdhc-imx.c | 81
> > ++++++++++++++++++++++++++++++++++++++
> >  1 file changed, 81 insertions(+)
> >
> > diff --git a/drivers/mmc/host/sdhci-esdhc-imx.c
> > b/drivers/mmc/host/sdhci-esdhc-imx.c
> > index c6b9f64..48f009c 100644
> > --- a/drivers/mmc/host/sdhci-esdhc-imx.c
> > +++ b/drivers/mmc/host/sdhci-esdhc-imx.c
> > @@ -44,6 +44,7 @@
> >  #define  ESDHC_MIX_CTRL_EXE_TUNE	(1 << 22)
> >  #define  ESDHC_MIX_CTRL_SMPCLK_SEL	(1 << 23)
> >  #define  ESDHC_MIX_CTRL_FBCLK_SEL	(1 << 25)
> > +#define  ESDHC_MIX_CTRL_HS400_EN	(1 << 26)
> >  /* Bits 3 and 6 are not SDHCI standard definitions */
> >  #define  ESDHC_MIX_CTRL_SDHCI_MASK	0xb7
> >  /* Tuning bits */
> > @@ -60,6 +61,16 @@
> >  #define  ESDHC_TUNE_CTRL_MIN		0
> >  #define  ESDHC_TUNE_CTRL_MAX		((1 << 7) - 1)
> >
> > +/* strobe dll register */
> > +#define ESDHC_STROBE_DLL_CTRL		0x70
> > +#define ESDHC_STROBE_DLL_CTRL_ENABLE	(1 << 0)
> > +#define ESDHC_STROBE_DLL_CTRL_RESET	(1 << 1)
> > +#define ESDHC_STROBE_DLL_CTRL_SLV_DLY_TARGET_SHIFT	3
> > +
> > +#define ESDHC_STROBE_DLL_STATUS		0x74
> > +#define ESDHC_STROBE_DLL_STS_REF_LOCK	(1 << 1)
> > +#define ESDHC_STROBE_DLL_STS_SLV_LOCK	0x1
> > +
> >  #define ESDHC_TUNING_CTRL		0xcc
> >  #define ESDHC_STD_TUNING_EN		(1 << 24)
> >  /* NOTE: the minimum valid tuning start tap for mx6sl is 1 */ @@
> > -120,6 +131,11 @@
> >  #define ESDHC_FLAG_ERR004536		BIT(7)
> >  /* The IP supports HS200 mode */
> >  #define ESDHC_FLAG_HS200		BIT(8)
> > +/* The IP supports HS400 mode */
> > +#define ESDHC_FLAG_HS400		BIT(9)
> > +
> > +/* A higher clock ferquency than this rate requires strobell dll
> control */
> > +#define ESDHC_STROBE_DLL_CLK_FREQ	100000000
> >
> >  struct esdhc_soc_data {
> >  	u32 flags;
> > @@ -156,6 +172,12 @@ static struct esdhc_soc_data usdhc_imx6sx_data = {
> >  			| ESDHC_FLAG_HAVE_CAP1 | ESDHC_FLAG_HS200,  };
> >
> > +static struct esdhc_soc_data usdhc_imx7d_data = {
> > +	.flags = ESDHC_FLAG_USDHC | ESDHC_FLAG_STD_TUNING
> > +			| ESDHC_FLAG_HAVE_CAP1 | ESDHC_FLAG_HS200
> > +			| ESDHC_FLAG_HS400,
> > +};
> > +
> >  struct pltfm_imx_data {
> >  	u32 scratchpad;
> >  	struct pinctrl *pinctrl;
> > @@ -199,6 +221,7 @@ static const struct of_device_id imx_esdhc_dt_ids[]
> = {
> >  	{ .compatible = "fsl,imx6sx-usdhc", .data = &usdhc_imx6sx_data, },
> >  	{ .compatible = "fsl,imx6sl-usdhc", .data = &usdhc_imx6sl_data, },
> >  	{ .compatible = "fsl,imx6q-usdhc", .data = &usdhc_imx6q_data, },
> > +	{ .compatible = "fsl,imx7d-usdhc", .data = &usdhc_imx7d_data, },
> >  	{ /* sentinel */ }
> >  };
> >  MODULE_DEVICE_TABLE(of, imx_esdhc_dt_ids); @@ -274,6 +297,9 @@ static
> > u32 esdhc_readl_le(struct sdhci_host *host, int reg)
> >  				val = SDHCI_SUPPORT_DDR50 | SDHCI_SUPPORT_SDR104
> >  					| SDHCI_SUPPORT_SDR50
> >  					| SDHCI_USE_SDR50_TUNING;
> > +
> > +			if (imx_data->socdata->flags & ESDHC_FLAG_HS400)
> > +				val |= SDHCI_SUPPORT_HS400;
> >  		}
> >  	}
> >
> > @@ -774,6 +800,7 @@ static int esdhc_change_pinstate(struct sdhci_host
> *host,
> >  		break;
> >  	case MMC_TIMING_UHS_SDR104:
> >  	case MMC_TIMING_MMC_HS200:
> > +	case MMC_TIMING_MMC_HS400:
> >  		pinctrl = imx_data->pins_200mhz;
> >  		break;
> >  	default:
> > @@ -784,6 +811,44 @@ static int esdhc_change_pinstate(struct sdhci_host
> *host,
> >  	return pinctrl_select_state(imx_data->pinctrl, pinctrl);  }
> >
> > +/*
> > + * For HS400 eMMC, there is a data_strobe line, this signal is
> > +generated
> > + * by the device and used for data output and CRC status response
> > +output
> > + * in HS400 mode. The frequency of this signal follows the frequency
> > +of
> > + * CLK generated by host. Host receive the data which is aligned to
> > +the
> > + * edge of data_strobe line. Due to the time delay between CLK line
> > +and
> > + * data_strobe line, if the delay time is larger than one clock
> > +cycle,
> > + * then CLK and data_strobe line will misaligned, read error shows up.
> > + * So when the CLK is higher than 100MHz, each clock cycle is short
> > +enough,
> > + * host should config the delay target.
> > + */
> > +static void esdhc_set_strobe_dll(struct sdhci_host *host) {
> > +	u32 v;
> > +
> > +	if (host->mmc->actual_clock > ESDHC_STROBE_DLL_CLK_FREQ) {
> > +		/* force a reset on strobe dll */
> > +		writel(ESDHC_STROBE_DLL_CTRL_RESET,
> > +			host->ioaddr + ESDHC_STROBE_DLL_CTRL);
> > +		/*
> > +		 * enable strobe dll ctrl and adjust the delay target
> > +		 * for the uSDHC loopback read clock
> > +		 */
> > +		v = ESDHC_STROBE_DLL_CTRL_ENABLE |
> > +			(7 << ESDHC_STROBE_DLL_CTRL_SLV_DLY_TARGET_SHIFT);
> > +		writel(v, host->ioaddr + ESDHC_STROBE_DLL_CTRL);
> > +		/* wait 1us to make sure strobe dll status register stable */
> > +		udelay(1);
> > +		v = readl(host->ioaddr + ESDHC_STROBE_DLL_STATUS);
> > +		if (!(v & ESDHC_STROBE_DLL_STS_REF_LOCK))
> > +			dev_warn(mmc_dev(host->mmc),
> > +				"warning! HS400 strobe DLL status REF not
> lock!\n");
> > +		if (!(v & ESDHC_STROBE_DLL_STS_SLV_LOCK))
> > +			dev_warn(mmc_dev(host->mmc),
> > +				"warning! HS400 strobe DLL status SLV not
> lock!\n");
> > +	}
> > +}
> > +
> >  static void esdhc_set_uhs_signaling(struct sdhci_host *host, unsigned
> > timing)  {
> >  	struct sdhci_pltfm_host *pltfm_host = sdhci_priv(host); @@ -795,7
> > +860,13 @@ static void esdhc_set_uhs_signaling(struct sdhci_host *host,
> unsigned timing)
> >  	case MMC_TIMING_UHS_SDR25:
> >  	case MMC_TIMING_UHS_SDR50:
> >  	case MMC_TIMING_UHS_SDR104:
> > +		break;
> >  	case MMC_TIMING_MMC_HS200:
> > +		/* disable ddr mode and disable HS400 mode */
> > +		writel(readl(host->ioaddr + ESDHC_MIX_CTRL) &
> > +			~(ESDHC_MIX_CTRL_DDREN | ESDHC_MIX_CTRL_HS400_EN),
> > +			host->ioaddr + ESDHC_MIX_CTRL);
> > +		imx_data->is_ddr = 0;
> 
> Can you please explain why need above code?
> Any issues if not do it?
> 
> Regards
> Dong Aisheng

[haibo] currently, mmc core code use mmc_retune before every request, 
and in mmc_retune, for eMMC, if the chip is in HS400 mode, firstly,
the code use mmc_hs400_to_hs200() to change the emmc chip work in
HS200 mode, and execute the tuning, and then use mmc_hs200_to_hs400()
to make the emmc chip work back in HS400 mode.

Without the above code, when change to hs200 mode from hs400 mode, our
host still enable ddr mode and enable hs400 mode, which is wrong.
So add the code here. 

> 
> >  		break;
> >  	case MMC_TIMING_UHS_DDR50:
> >  	case MMC_TIMING_MMC_DDR52:
> > @@ -813,6 +884,13 @@ static void esdhc_set_uhs_signaling(struct
> sdhci_host *host, unsigned timing)
> >  			writel(v, host->ioaddr + ESDHC_DLL_CTRL);
> >  		}
> >  		break;
> > +	case MMC_TIMING_MMC_HS400:
> > +		writel(readl(host->ioaddr + ESDHC_MIX_CTRL) |
> > +				ESDHC_MIX_CTRL_DDREN | ESDHC_MIX_CTRL_HS400_EN,
> > +				host->ioaddr + ESDHC_MIX_CTRL);
> > +		imx_data->is_ddr = 1;
> > +		esdhc_set_strobe_dll(host);
> > +		break;
> >  	}
> >
> >  	esdhc_change_pinstate(host, timing); @@ -1100,6 +1178,9 @@ static
> > int sdhci_esdhc_imx_probe(struct platform_device *pdev)
> >  	if (imx_data->socdata->flags & ESDHC_FLAG_ERR004536)
> >  		host->quirks |= SDHCI_QUIRK_BROKEN_ADMA;
> >
> > +	if (imx_data->socdata->flags & ESDHC_FLAG_HS400)
> > +		host->quirks2 |= SDHCI_QUIRK2_CAPS_BIT63_FOR_HS400;
> > +
> >  	if (of_id)
> >  		err = sdhci_esdhc_imx_probe_dt(pdev, host, imx_data);
> >  	else
> > --
> > 1.9.1
> >


From tomasz.nowicki at linaro.org  Fri Aug  7 03:03:24 2015
From: tomasz.nowicki at linaro.org (Tomasz Nowicki)
Date: Fri, 07 Aug 2015 12:03:24 +0200
Subject: [PATCH v4 09/10] PCI: ACPI: Bind GIC MSI frame to PCI host bridge
In-Reply-To: <1438164539-29256-10-git-send-email-hanjun.guo@linaro.org>
References: <1438164539-29256-1-git-send-email-hanjun.guo@linaro.org>
 <1438164539-29256-10-git-send-email-hanjun.guo@linaro.org>
Message-ID: <55C4826C.80600@linaro.org>

On 29.07.2015 12:08, Hanjun Guo wrote:
> From: Suravee Suthikulpanit <Suravee.Suthikulpanit at amd.com>
>
> This patch introduces pci_host_bridge_acpi_msi_domain(), which queries
> a GIC MSI irq-domain token and use it to retrieve an irq_domain with
> DOMAIN_BUS_PCI_MSI bus type, and bind it to PCI host-bridge.
>
> Signed-off-by: Suravee Suthikulpanit <Suravee.Suthikulpanit at amd.com>
> Signed-off-by: Hanjun Guo <hanjun.guo at linaro.org>
> ---
>   drivers/pci/pci-acpi.c   | 18 ++++++++++++++++++
>   drivers/pci/probe.c      |  3 +++
>   include/linux/pci-acpi.h |  4 ++++
>   3 files changed, 25 insertions(+)
>
> diff --git a/drivers/pci/pci-acpi.c b/drivers/pci/pci-acpi.c
> index 314a625..5f11653 100644
> --- a/drivers/pci/pci-acpi.c
> +++ b/drivers/pci/pci-acpi.c
> @@ -9,6 +9,7 @@
>
>   #include <linux/delay.h>
>   #include <linux/init.h>
> +#include <linux/irqdomain.h>
>   #include <linux/pci.h>
>   #include <linux/pci_hotplug.h>
>   #include <linux/module.h>
> @@ -16,6 +17,7 @@
>   #include <linux/pci-acpi.h>
>   #include <linux/pm_runtime.h>
>   #include <linux/pm_qos.h>
> +#include <acpi/acpi_gic.h>
>   #include "pci.h"
>
>   /*
> @@ -681,6 +683,22 @@ static bool pci_acpi_bus_match(struct device *dev)
>   	return dev_is_pci(dev);
>   }
>
> +#ifdef CONFIG_GENERIC_MSI_IRQ_DOMAIN
> +struct irq_domain *pci_host_bridge_acpi_msi_domain(struct pci_bus *bus)
> +{
> +	struct irq_domain *d = NULL;
> +	void *token = acpi_gic_get_msi_token(&bus->dev);
> +
> +	if (token)
> +		d = irq_find_matching_host(token, DOMAIN_BUS_PCI_MSI);
> +
> +	if (!d)
> +		pr_debug("Fail to find domain for MSI\n");
> +
> +	return d;
> +}
> +#endif /*CONFIG_GENERIC_MSI_IRQ_DOMAIN*/
> +
>   static struct acpi_bus_type acpi_pci_bus = {
>   	.name = "PCI",
>   	.match = pci_acpi_bus_match,
> diff --git a/drivers/pci/probe.c b/drivers/pci/probe.c
> index a7afeac..8c1204c 100644
> --- a/drivers/pci/probe.c
> +++ b/drivers/pci/probe.c
> @@ -12,6 +12,7 @@
>   #include <linux/module.h>
>   #include <linux/cpumask.h>
>   #include <linux/pci-aspm.h>
> +#include <linux/pci-acpi.h>
>   #include <asm-generic/pci-bridge.h>
>   #include "pci.h"
>
> @@ -670,6 +671,8 @@ static struct irq_domain *pci_host_bridge_msi_domain(struct pci_bus *bus)
>   	 * should be called from here.
>   	 */
>   	d = pci_host_bridge_of_msi_domain(bus);
> +	if (!d)
> +		d = pci_host_bridge_acpi_msi_domain(bus);

Please use acpi_disabled here.

BTW. This is another place where we need to know our firmware - DT vs 
ACPI. I know we can use acpi_disabled but I think more about generic 
solution. Since we already have:
struct fwnode_handle	*fwnode;
we can create macro which identify h/w description style, something like:

#define FWNODE_TYPE(dev)	dev_fwnode(dev)->type

and then:

switch (FWNODE_TYPE(&bus->dev)) {
case FWNODE_OF:
...
case FWNODE_ACPI:
...
case FWNODE_XXX:
...
}

Root bus is special case since it has no frimware type but we could 
factor out pci_set_bus_of_node(). For platform devices we have all we 
need. Just thinking aloud, let me know your thoughts.

Regards,
Tomasz





>
>   	return d;
>   }
> diff --git a/include/linux/pci-acpi.h b/include/linux/pci-acpi.h
> index a965efa..766d045 100644
> --- a/include/linux/pci-acpi.h
> +++ b/include/linux/pci-acpi.h
> @@ -77,6 +77,8 @@ static inline void acpiphp_remove_slots(struct pci_bus *bus) { }
>   static inline void acpiphp_check_host_bridge(struct acpi_device *adev) { }
>   #endif
>
> +struct irq_domain *pci_host_bridge_acpi_msi_domain(struct pci_bus *bus);
> +
>   extern const u8 pci_acpi_dsm_uuid[];
>   #define DEVICE_LABEL_DSM	0x07
>   #define RESET_DELAY_DSM		0x08
> @@ -85,6 +87,8 @@ extern const u8 pci_acpi_dsm_uuid[];
>   #else	/* CONFIG_ACPI */
>   static inline void acpi_pci_add_bus(struct pci_bus *bus) { }
>   static inline void acpi_pci_remove_bus(struct pci_bus *bus) { }
> +static inline struct irq_domain *
> +pci_host_bridge_acpi_msi_domain(struct pci_bus *bus) { return NULL; }
>   #endif	/* CONFIG_ACPI */
>
>   #ifdef CONFIG_ACPI_APEI
>


From Haibo.Chen at freescale.com  Fri Aug  7 03:04:56 2015
From: Haibo.Chen at freescale.com (Chen Bough)
Date: Fri, 7 Aug 2015 10:04:56 +0000
Subject: [PATCH v4 2/6] mmc: sdhci-esdhc-imx: add tuning-step seting
 support
In-Reply-To: <20150807074019.GB6935@shlinux1.ap.freescale.net>
References: <1438771122-8601-1-git-send-email-haibo.chen@freescale.com>
 <1438771122-8601-3-git-send-email-haibo.chen@freescale.com>
 <20150807074019.GB6935@shlinux1.ap.freescale.net>
Message-ID: <BY1PR03MB138864BA52567E75F56808329A730@BY1PR03MB1388.namprd03.prod.outlook.com>



> -----Original Message-----
> From: Dong Aisheng [mailto:aisheng.dong at freescale.com]
> Sent: Friday, August 07, 2015 3:40 PM
> To: Chen Haibo-B51421
> Cc: robh+dt at kernel.org; pawel.moll at arm.com; mark.rutland at arm.com;
> ijc+devicetree at hellion.org.uk; galak at codeaurora.org; shawnguo at kernel.org;
> kernel at pengutronix.de; linux at arm.linux.org.uk; ulf.hansson at linaro.org;
> johan.derycke at barco.com; mkl at pengutronix.de; Estevam Fabio-R49496; Dong
> Aisheng-B29396; devicetree at vger.kernel.org; linux-kernel at vger.kernel.org;
> linux-arm-kernel at lists.infradead.org; linux-mmc at vger.kernel.org
> Subject: Re: [PATCH v4 2/6] mmc: sdhci-esdhc-imx: add tuning-step seting
> support
> 
> On Wed, Aug 05, 2015 at 06:38:38PM +0800, Haibo Chen wrote:
> > tuning-step is the delay cell steps in tuning procedure. The default
> > value of tuning-step is 1. Some boards or cards need another value to
> > pass the tuning procedure. For example, imx7d-sdb board need the
> > tuning-step value as 2, otherwise it can't pass the tuning procedure.
> >
> > So this patch add the tuning-step setting in driver, so that user can
> > set the tuning-step value in dts.
> >
> > Signed-off-by: Haibo Chen <haibo.chen at freescale.com>
> > ---
> >  drivers/mmc/host/sdhci-esdhc-imx.c          | 9 +++++++++
> >  include/linux/platform_data/mmc-esdhc-imx.h | 1 +
> >  2 files changed, 10 insertions(+)
> >
> > diff --git a/drivers/mmc/host/sdhci-esdhc-imx.c
> > b/drivers/mmc/host/sdhci-esdhc-imx.c
> > index 48f009c..803d24f 100644
> > --- a/drivers/mmc/host/sdhci-esdhc-imx.c
> > +++ b/drivers/mmc/host/sdhci-esdhc-imx.c
> > @@ -75,6 +75,7 @@
> >  #define ESDHC_STD_TUNING_EN		(1 << 24)
> >  /* NOTE: the minimum valid tuning start tap for mx6sl is 1 */
> >  #define ESDHC_TUNING_START_TAP		0x1
> > +#define ESDHC_TUNING_STEP_SHIFT		16
> >
> >  /* pinctrl state */
> >  #define ESDHC_PINCTRL_STATE_100MHZ	"state_100mhz"
> > @@ -474,6 +475,7 @@ static void esdhc_writew_le(struct sdhci_host *host,
> u16 val, int reg)
> >  		} else if (imx_data->socdata->flags & ESDHC_FLAG_STD_TUNING)
> {
> >  			u32 v = readl(host->ioaddr + SDHCI_ACMD12_ERR);
> >  			u32 m = readl(host->ioaddr + ESDHC_MIX_CTRL);
> > +			u32 tuning_ctrl;
> >  			if (val & SDHCI_CTRL_TUNED_CLK) {
> >  				v |= ESDHC_MIX_CTRL_SMPCLK_SEL;
> >  			} else {
> > @@ -484,6 +486,11 @@ static void esdhc_writew_le(struct sdhci_host
> *host, u16 val, int reg)
> >  			if (val & SDHCI_CTRL_EXEC_TUNING) {
> >  				v |= ESDHC_MIX_CTRL_EXE_TUNE;
> >  				m |= ESDHC_MIX_CTRL_FBCLK_SEL;
> > +				tuning_ctrl = readl(host->ioaddr +
> ESDHC_TUNING_CTRL);
> > +				tuning_ctrl |= ESDHC_STD_TUNING_EN |
> ESDHC_TUNING_START_TAP;
> > +				if (imx_data->boarddata.tuning_step)
> > +					tuning_ctrl |= imx_data-
> >boarddata.tuning_step << ESDHC_TUNING_STEP_SHIFT;
> > +					writel(tuning_ctrl, host->ioaddr +
> ESDHC_TUNING_CTRL);
> 
> Is there a code indent issue here?
> Otherwise, the patch looks good to me.
> 
> Regards
> Dong Aisheng

[haibo] I check this, the code indent is okay.

> 
> >  			} else {
> >  				v &= ~ESDHC_MIX_CTRL_EXE_TUNE;
> >  			}
> > @@ -964,6 +971,8 @@ sdhci_esdhc_imx_probe_dt(struct platform_device
> *pdev,
> >  	if (gpio_is_valid(boarddata->wp_gpio))
> >  		boarddata->wp_type = ESDHC_WP_GPIO;
> >
> > +	of_property_read_u32(np, "fsl,tuning-step",
> > +&boarddata->tuning_step);
> > +
> >  	if (of_find_property(np, "no-1-8-v", NULL))
> >  		boarddata->support_vsel = false;
> >  	else
> > diff --git a/include/linux/platform_data/mmc-esdhc-imx.h
> > b/include/linux/platform_data/mmc-esdhc-imx.h
> > index e1571ef..95ccab3 100644
> > --- a/include/linux/platform_data/mmc-esdhc-imx.h
> > +++ b/include/linux/platform_data/mmc-esdhc-imx.h
> > @@ -45,5 +45,6 @@ struct esdhc_platform_data {
> >  	int max_bus_width;
> >  	bool support_vsel;
> >  	unsigned int delay_line;
> > +	unsigned int tuning_step;       /* The delay cell steps in tuning
> procedure */
> >  };
> >  #endif /* __ASM_ARCH_IMX_ESDHC_H */
> > --
> > 1.9.1
> >


From b18965 at freescale.com  Fri Aug  7 03:01:59 2015
From: b18965 at freescale.com (Alison Wang)
Date: Fri, 7 Aug 2015 18:01:59 +0800
Subject: [PATCH] ARM: ls1021a: add platform notifier for dma-coherent
 requirement
Message-ID: <1438941719-38350-1-git-send-email-b18965@freescale.com>

This patch adds platform notifier for dma-coherent requirement.
Structure arm_coherent_dma_ops is used instead of arm_dma_ops.

Signed-off-by: Alison Wang <alison.wang at freescale.com>
---
 arch/arm/mach-imx/mach-ls1021a.c | 30 ++++++++++++++++++++++++++++++
 1 file changed, 30 insertions(+)

diff --git a/arch/arm/mach-imx/mach-ls1021a.c b/arch/arm/mach-imx/mach-ls1021a.c
index b89c858..6bfc71b 100644
--- a/arch/arm/mach-imx/mach-ls1021a.c
+++ b/arch/arm/mach-imx/mach-ls1021a.c
@@ -7,10 +7,39 @@
  * (at your option) any later version.
  */
 
+#include <linux/dma-mapping.h>
+#include <linux/of_platform.h>
 #include <asm/mach/arch.h>
 
 #include "common.h"
 
+static int ls1021a_platform_notifier(struct notifier_block *nb,
+				  unsigned long event, void *__dev)
+{
+	struct device *dev = __dev;
+
+	if (event != BUS_NOTIFY_ADD_DEVICE)
+		return NOTIFY_DONE;
+
+	if (of_device_is_compatible(dev->of_node, "fsl,etsec2"))
+		set_dma_ops(dev, &arm_coherent_dma_ops);
+	else if (of_property_read_bool(dev->of_node, "dma-coherent"))
+		set_dma_ops(dev, &arm_coherent_dma_ops);
+
+	return NOTIFY_OK;
+}
+
+static struct notifier_block ls1021a_platform_nb = {
+	.notifier_call = ls1021a_platform_notifier,
+};
+
+static void __init ls1021a_init_machine(void)
+{
+	bus_register_notifier(&platform_bus_type, &ls1021a_platform_nb);
+
+	of_platform_populate(NULL, of_default_bus_match_table, NULL, NULL);
+}
+
 static const char * const ls1021a_dt_compat[] __initconst = {
 	"fsl,ls1021a",
 	NULL,
@@ -18,5 +47,6 @@ static const char * const ls1021a_dt_compat[] __initconst = {
 
 DT_MACHINE_START(LS1021A, "Freescale LS1021A")
 	.smp		= smp_ops(ls1021a_smp_ops),
+	.init_machine   = ls1021a_init_machine,
 	.dt_compat	= ls1021a_dt_compat,
 MACHINE_END
-- 
2.1.0.27.g96db324



From b18965 at freescale.com  Fri Aug  7 03:03:04 2015
From: b18965 at freescale.com (Alison Wang)
Date: Fri, 7 Aug 2015 18:03:04 +0800
Subject: [PATCH v3] ARM: configs: Add Freescale LS1021A defconfig
Message-ID: <1438941784-38403-1-git-send-email-b18965@freescale.com>

Add Freescale LS1021A initial defconfig file.
The LS1021A SoC is a dual-core Cortex-A7 based processor.

LS1021A has some special configure options against common V7 SOCs,
such as CONFIG_THUMB2_KERNEL, CONFIG_VMSPLIT_2G, CONFIG_VFP...

Enable I2C, LPUART, eDMA, WDT, GIANFAR, Sound, DSPI at default.

Signed-off-by: Haikun Wang <haikun.wang at freescale.com>
Signed-off-by: Alison Wang <alison.wang at freescale.com>
---
Changes since v2:
- Enable PSCI, as PSCI is enabled in u-boot.
Changes since v1:
- Enable GIANFAR, Sound and DSPI.

 arch/arm/configs/ls1021a_defconfig | 161 +++++++++++++++++++++++++++++++++++++
 1 file changed, 161 insertions(+)
 create mode 100644 arch/arm/configs/ls1021a_defconfig

diff --git a/arch/arm/configs/ls1021a_defconfig b/arch/arm/configs/ls1021a_defconfig
new file mode 100644
index 0000000..5576f67
--- /dev/null
+++ b/arch/arm/configs/ls1021a_defconfig
@@ -0,0 +1,161 @@
+CONFIG_SYSVIPC=y
+CONFIG_POSIX_MQUEUE=y
+CONFIG_NO_HZ_IDLE=y
+CONFIG_HIGH_RES_TIMERS=y
+CONFIG_LOG_BUF_SHIFT=16
+CONFIG_BLK_DEV_INITRD=y
+CONFIG_CC_OPTIMIZE_FOR_SIZE=y
+CONFIG_SYSCTL_SYSCALL=y
+CONFIG_KALLSYMS_ALL=y
+CONFIG_EMBEDDED=y
+CONFIG_PROFILING=y
+CONFIG_OPROFILE=y
+CONFIG_KPROBES=y
+CONFIG_JUMP_LABEL=y
+CONFIG_MODULES=y
+CONFIG_MODULE_FORCE_LOAD=y
+CONFIG_MODULE_UNLOAD=y
+CONFIG_BLK_CMDLINE_PARSER=y
+CONFIG_ARCH_MXC=y
+CONFIG_SOC_LS1021A=y
+CONFIG_ARM_LPAE=y
+CONFIG_PCI=y
+CONFIG_PCI_MSI=y
+CONFIG_SMP=y
+CONFIG_VMSPLIT_2G=y
+CONFIG_ARM_PSCI=y
+CONFIG_PREEMPT_VOLUNTARY=y
+CONFIG_THUMB2_KERNEL=y
+CONFIG_HIGHMEM=y
+CONFIG_CLEANCACHE=y
+CONFIG_FRONTSWAP=y
+CONFIG_CMDLINE="console=ttyS0,115200"
+CONFIG_VFP=y
+CONFIG_NEON=y
+CONFIG_KERNEL_MODE_NEON=y
+CONFIG_BINFMT_MISC=y
+CONFIG_NET=y
+CONFIG_PACKET=y
+CONFIG_UNIX=y
+CONFIG_UNIX_DIAG=y
+CONFIG_XFRM_USER=y
+CONFIG_NET_KEY=y
+CONFIG_INET=y
+CONFIG_IP_MULTICAST=y
+CONFIG_IP_ADVANCED_ROUTER=y
+CONFIG_IP_PNP=y
+CONFIG_IP_PNP_DHCP=y
+CONFIG_IP_MROUTE=y
+CONFIG_INET_AH=y
+CONFIG_INET_ESP=y
+CONFIG_INET_IPCOMP=y
+CONFIG_INET_UDP_DIAG=m
+CONFIG_NETFILTER=y
+CONFIG_DEVTMPFS=y
+CONFIG_DEVTMPFS_MOUNT=y
+CONFIG_MTD=y
+CONFIG_MTD_CMDLINE_PARTS=y
+CONFIG_MTD_BLOCK=y
+CONFIG_MTD_CFI=y
+CONFIG_MTD_CFI_ADV_OPTIONS=y
+CONFIG_MTD_CFI_BE_BYTE_SWAP=y
+CONFIG_MTD_CFI_GEOMETRY=y
+CONFIG_MTD_CFI_INTELEXT=y
+CONFIG_MTD_CFI_AMDSTD=y
+CONFIG_MTD_CFI_STAA=y
+CONFIG_MTD_PHYSMAP_OF=y
+CONFIG_MTD_NAND=y
+CONFIG_BLK_DEV_LOOP=y
+CONFIG_BLK_DEV_RAM=y
+CONFIG_BLK_DEV_RAM_SIZE=256000
+CONFIG_BLK_DEV_SD=y
+CONFIG_CHR_DEV_SG=y
+CONFIG_ATA=y
+CONFIG_NETDEVICES=y
+CONFIG_GIANFAR=y
+CONFIG_VITESSE_PHY=y
+CONFIG_BROADCOM_PHY=y
+CONFIG_REALTEK_PHY=y
+CONFIG_NATIONAL_PHY=y
+CONFIG_MICREL_PHY=y
+CONFIG_MDIO_BUS_MUX_MMIOREG=y
+CONFIG_INPUT_EVDEV=y
+CONFIG_SERIO_SERPORT=m
+CONFIG_SERIAL_8250=y
+CONFIG_SERIAL_8250_CONSOLE=y
+CONFIG_SERIAL_8250_EXTENDED=y
+CONFIG_SERIAL_8250_SHARE_IRQ=y
+CONFIG_SERIAL_OF_PLATFORM=y
+CONFIG_SERIAL_FSL_LPUART=y
+CONFIG_SERIAL_FSL_LPUART_CONSOLE=y
+CONFIG_HW_RANDOM=y
+CONFIG_I2C=y
+CONFIG_I2C_CHARDEV=y
+CONFIG_I2C_MUX=y
+CONFIG_I2C_MUX_PCA954x=y
+CONFIG_I2C_IMX=y
+CONFIG_SPI=y
+CONFIG_SPI_FSL_DSPI=y
+CONFIG_GPIO_SYSFS=y
+CONFIG_SENSORS_LM90=y
+CONFIG_SENSORS_INA2XX=y
+CONFIG_WATCHDOG=y
+CONFIG_IMX2_WDT=y
+CONFIG_REGULATOR=y
+CONFIG_REGULATOR_DEBUG=y
+CONFIG_REGULATOR_FIXED_VOLTAGE=y
+CONFIG_SOUND=y
+# CONFIG_SOUND_OSS_CORE_PRECLAIM is not set
+CONFIG_SND=y
+CONFIG_SND_MIXER_OSS=y
+CONFIG_SND_PCM_OSS=y
+# CONFIG_SND_ARM is not set
+CONFIG_SND_SOC=y
+CONFIG_SND_SOC_FSL_SAI=y
+CONFIG_SND_SOC_SGTL5000=y
+CONFIG_SND_SIMPLE_CARD=y
+CONFIG_MMC=y
+CONFIG_MMC_SDHCI=y
+CONFIG_MMC_SDHCI_PLTFM=y
+CONFIG_MMC_SDHCI_OF_ARASAN=y
+CONFIG_NEW_LEDS=y
+CONFIG_LEDS_CLASS=y
+CONFIG_LEDS_TRIGGERS=y
+CONFIG_RTC_CLASS=y
+CONFIG_RTC_DRV_DS3232=y
+CONFIG_DMADEVICES=y
+CONFIG_FSL_EDMA=y
+CONFIG_CLK_QORIQ=y
+CONFIG_MEMORY=y
+CONFIG_EXT2_FS=y
+CONFIG_EXT2_FS_XATTR=y
+CONFIG_EXT3_FS=y
+CONFIG_EXT4_FS=y
+CONFIG_FANOTIFY=y
+CONFIG_ISO9660_FS=m
+CONFIG_JOLIET=y
+CONFIG_ZISOFS=y
+CONFIG_UDF_FS=m
+CONFIG_MSDOS_FS=y
+CONFIG_VFAT_FS=y
+CONFIG_NTFS_FS=m
+CONFIG_TMPFS=y
+CONFIG_TMPFS_POSIX_ACL=y
+CONFIG_JFFS2_FS=y
+CONFIG_NFS_FS=y
+CONFIG_NFS_V4=y
+CONFIG_ROOT_NFS=y
+CONFIG_NLS_DEFAULT="cp437"
+CONFIG_NLS_CODEPAGE_437=y
+CONFIG_NLS_ASCII=y
+CONFIG_NLS_ISO8859_1=y
+CONFIG_NLS_ISO8859_2=y
+CONFIG_NLS_ISO8859_15=y
+CONFIG_NLS_UTF8=y
+CONFIG_DEBUG_SECTION_MISMATCH=y
+CONFIG_MAGIC_SYSRQ=y
+CONFIG_CRYPTO_LZO=y
+CONFIG_CRC_CCITT=m
+CONFIG_CRC_T10DIF=y
+CONFIG_CRC7=m
+CONFIG_LIBCRC32C=m
-- 
2.1.0.27.g96db324



From Haibo.Chen at freescale.com  Fri Aug  7 03:11:37 2015
From: Haibo.Chen at freescale.com (Chen Bough)
Date: Fri, 7 Aug 2015 10:11:37 +0000
Subject: [PATCH v4 6/6] mmc: sdhci-esdhc-imx: set back the
 burst_length_enable bit to 1
In-Reply-To: <20150807075050.GC6935@shlinux1.ap.freescale.net>
References: <1438771122-8601-1-git-send-email-haibo.chen@freescale.com>
 <1438771122-8601-7-git-send-email-haibo.chen@freescale.com>
 <20150807075050.GC6935@shlinux1.ap.freescale.net>
Message-ID: <BY1PR03MB13883261FD2D9D28B30697209A730@BY1PR03MB1388.namprd03.prod.outlook.com>



> -----Original Message-----
> From: Dong Aisheng [mailto:aisheng.dong at freescale.com]
> Sent: Friday, August 07, 2015 3:51 PM
> To: Chen Haibo-B51421
> Cc: robh+dt at kernel.org; pawel.moll at arm.com; mark.rutland at arm.com;
> ijc+devicetree at hellion.org.uk; galak at codeaurora.org; shawnguo at kernel.org;
> kernel at pengutronix.de; linux at arm.linux.org.uk; ulf.hansson at linaro.org;
> johan.derycke at barco.com; mkl at pengutronix.de; Estevam Fabio-R49496; Dong
> Aisheng-B29396; devicetree at vger.kernel.org; linux-kernel at vger.kernel.org;
> linux-arm-kernel at lists.infradead.org; linux-mmc at vger.kernel.org
> Subject: Re: [PATCH v4 6/6] mmc: sdhci-esdhc-imx: set back the
> burst_length_enable bit to 1
> 
> On Wed, Aug 05, 2015 at 06:38:42PM +0800, Haibo Chen wrote:
> > Currently we find that if a usdhc is choosed to boot system, then ROM
> > code will set the burst length enable bit of this usdhc as 0.
> >
> > This will make performance drop a lot if this usdhc's burst length is
> > configed. So this patch set back the burst_length_enable bit as 1,
> > which is the default value, and means burst length is enabled for INCR.
> >
> 
> This patch should be put before patch 5 to avoid function break, right?
> [PATCH v4 5/6] mmc: sdhci-esdhc-imx: change default watermark level and
> burst length
> 
> Other than that, this patch looks good to me.
> 
> Regards
> Dong Aisheng
> 

[haibo] Yes, you are right. Patch 6 should be put before patch 5.
 
> > Signed-off-by: Haibo Chen <haibo.chen at freescale.com>
> > ---
> >  drivers/mmc/host/sdhci-esdhc-imx.c | 16 ++++++++++++++++
> >  1 file changed, 16 insertions(+)
> >
> > diff --git a/drivers/mmc/host/sdhci-esdhc-imx.c
> > b/drivers/mmc/host/sdhci-esdhc-imx.c
> > index 97aa944..3334762 100644
> > --- a/drivers/mmc/host/sdhci-esdhc-imx.c
> > +++ b/drivers/mmc/host/sdhci-esdhc-imx.c
> > @@ -32,6 +32,7 @@
> >  #include "sdhci-esdhc.h"
> >
> >  #define	ESDHC_CTRL_D3CD			0x08
> > +#define ESDHC_BURST_LEN_EN_INCR		(1 << 27)
> >  /* VENDOR SPEC register */
> >  #define ESDHC_VENDOR_SPEC		0xc0
> >  #define  ESDHC_VENDOR_SPEC_SDIO_QUIRK	(1 << 1)
> > @@ -1165,6 +1166,21 @@ static int sdhci_esdhc_imx_probe(struct
> platform_device *pdev)
> >  		host->quirks2 |= SDHCI_QUIRK2_PRESET_VALUE_BROKEN;
> >  		host->mmc->caps |= MMC_CAP_1_8V_DDR;
> >
> > +		/*
> > +		 * ROM code will change the bit burst_length_enable setting
> > +		 * to zero if this usdhc is choosed to boot system. Change
> > +		 * it back here, otherwise it will impact the performance a
> > +		 * lot. This bit is used to enable/disable the burst length
> > +		 * for the external AHB2AXI bridge, it's usefully especially
> > +		 * for INCR transfer because without burst length indicator,
> > +		 * the AHB2AXI bridge does not know the burst length in
> > +		 * advance. And without burst length indicator, AHB INCR
> > +		 * transfer can only be converted to singles on the AXI side.
> > +		 */
> > +		writel(readl(host->ioaddr + SDHCI_HOST_CONTROL)
> > +			| ESDHC_BURST_LEN_EN_INCR,
> > +			host->ioaddr + SDHCI_HOST_CONTROL);
> > +
> >  		if (!(imx_data->socdata->flags & ESDHC_FLAG_HS200))
> >  			host->quirks2 |= SDHCI_QUIRK2_BROKEN_HS200;
> >
> > --
> > 1.9.1
> >


From maoguang.meng at mediatek.com  Fri Aug  7 03:14:39 2015
From: maoguang.meng at mediatek.com (maoguang.meng at mediatek.com)
Date: Fri, 7 Aug 2015 18:14:39 +0800
Subject: [PATCH v2] pinctrl: mediatek: Implement wake handler and suspend
 resume
Message-ID: <1438942479-24478-1-git-send-email-maoguang.meng@mediatek.com>

From: Maoguang Meng <maoguang.meng at mediatek.com>

This patch implement irq_set_wake and add suspend resume feature.

Signed-off-by: Maoguang Meng <maoguang.meng at mediatek.com>
---
 drivers/pinctrl/mediatek/pinctrl-mt8173.c     |  1 +
 drivers/pinctrl/mediatek/pinctrl-mtk-common.c | 78 +++++++++++++++++++++++++--
 drivers/pinctrl/mediatek/pinctrl-mtk-common.h |  4 ++
 3 files changed, 80 insertions(+), 3 deletions(-)

diff --git a/drivers/pinctrl/mediatek/pinctrl-mt8173.c b/drivers/pinctrl/mediatek/pinctrl-mt8173.c
index d0c811d..ad27184 100644
--- a/drivers/pinctrl/mediatek/pinctrl-mt8173.c
+++ b/drivers/pinctrl/mediatek/pinctrl-mt8173.c
@@ -385,6 +385,7 @@ static struct platform_driver mtk_pinctrl_driver = {
 	.driver = {
 		.name = "mediatek-mt8173-pinctrl",
 		.of_match_table = mt8173_pctrl_match,
+		.pm = &mtk_eint_pm_ops,
 	},
 };
 
diff --git a/drivers/pinctrl/mediatek/pinctrl-mtk-common.c b/drivers/pinctrl/mediatek/pinctrl-mtk-common.c
index a3d137e..af2d33a 100644
--- a/drivers/pinctrl/mediatek/pinctrl-mtk-common.c
+++ b/drivers/pinctrl/mediatek/pinctrl-mtk-common.c
@@ -35,6 +35,7 @@
 #include <linux/mfd/syscon.h>
 #include <linux/delay.h>
 #include <linux/interrupt.h>
+#include <linux/pm.h>
 #include <dt-bindings/pinctrl/mt65xx.h>
 
 #include "../core.h"
@@ -1066,14 +1067,74 @@ static int mtk_eint_set_type(struct irq_data *d,
 
 static int mtk_eint_irq_set_wake(struct irq_data *d, unsigned int on)
 {
+	struct mtk_pinctrl *pctl = irq_data_get_irq_chip_data(d);
+
 	if (on)
-		d->chip->flags |= IRQF_NO_SUSPEND;
+		set_bit(d->hwirq, (unsigned long *)pctl->wake_mask);
 	else
-		d->chip->flags &= ~IRQF_NO_SUSPEND;
+		clear_bit(d->hwirq, (unsigned long *)pctl->wake_mask);
+
+	return 0;
+}
+
+static void mtk_eint_chip_write_mask(const struct mtk_eint_offsets *chip,
+	void __iomem *eint_reg_base, u32 *buf)
+{
+	int port;
+	void __iomem *reg;
+
+	for (port = 0; port < chip->ports; port++) {
+		reg = eint_reg_base + (port << 2);
+		writel_relaxed(~buf[port], reg + chip->mask_set);
+		writel_relaxed(buf[port], reg + chip->mask_clr);
+	}
+}
+
+static void mtk_eint_chip_read_mask(const struct mtk_eint_offsets *chip,
+	void __iomem *eint_reg_base, u32 *buf)
+{
+	int port;
+	void __iomem *reg;
+
+	for (port = 0; port < chip->ports; port++) {
+		reg = eint_reg_base + chip->mask + (port << 2);
+		buf[port] = ~readl_relaxed(reg);
+	}
+}
+
+static int mtk_eint_suspend(struct device *device)
+{
+	void __iomem *reg;
+	struct platform_device *pdev = to_platform_device(device);
+	struct mtk_pinctrl *pctl = platform_get_drvdata(pdev);
+	const struct mtk_eint_offsets *eint_offsets =
+		&pctl->devdata->eint_offsets;
+
+	reg = pctl->eint_reg_base;
+	mtk_eint_chip_read_mask(eint_offsets, reg, pctl->cur_mask);
+	mtk_eint_chip_write_mask(eint_offsets, reg, pctl->wake_mask);
+
+	return 0;
+}
+
+static int mtk_eint_resume(struct device *device)
+{
+	struct platform_device *pdev = to_platform_device(device);
+	struct mtk_pinctrl *pctl = platform_get_drvdata(pdev);
+	const struct mtk_eint_offsets *eint_offsets =
+		&pctl->devdata->eint_offsets;
+
+	mtk_eint_chip_write_mask(eint_offsets,
+		pctl->eint_reg_base, pctl->cur_mask);
 
 	return 0;
 }
 
+const struct dev_pm_ops mtk_eint_pm_ops = {
+	.suspend = mtk_eint_suspend,
+	.resume = mtk_eint_resume,
+};
+
 static void mtk_eint_ack(struct irq_data *d)
 {
 	struct mtk_pinctrl *pctl = irq_data_get_irq_chip_data(d);
@@ -1231,7 +1292,7 @@ int mtk_pctrl_init(struct platform_device *pdev,
 	struct device_node *np = pdev->dev.of_node, *node;
 	struct property *prop;
 	struct resource *res;
-	int i, ret, irq;
+	int i, ret, irq, ports_buf;
 
 	pctl = devm_kzalloc(&pdev->dev, sizeof(*pctl), GFP_KERNEL);
 	if (!pctl)
@@ -1333,6 +1394,17 @@ int mtk_pctrl_init(struct platform_device *pdev,
 		goto chip_error;
 	}
 
+	ports_buf = ALIGN(pctl->devdata->eint_offsets.ports,
+			sizeof(long)/sizeof(u32));
+	pctl->wake_mask = devm_kcalloc(&pdev->dev, ports_buf * 2,
+					sizeof(*pctl->wake_mask), GFP_KERNEL);
+	if (!pctl->wake_mask) {
+		ret = -ENOMEM;
+		goto chip_error;
+	}
+
+	pctl->cur_mask = pctl->wake_mask + ports_buf;
+
 	pctl->eint_dual_edges = devm_kcalloc(&pdev->dev, pctl->devdata->ap_num,
 					     sizeof(int), GFP_KERNEL);
 	if (!pctl->eint_dual_edges) {
diff --git a/drivers/pinctrl/mediatek/pinctrl-mtk-common.h b/drivers/pinctrl/mediatek/pinctrl-mtk-common.h
index 30213e5..f1be8e8 100644
--- a/drivers/pinctrl/mediatek/pinctrl-mtk-common.h
+++ b/drivers/pinctrl/mediatek/pinctrl-mtk-common.h
@@ -266,6 +266,8 @@ struct mtk_pinctrl {
 	void __iomem		*eint_reg_base;
 	struct irq_domain	*domain;
 	int			*eint_dual_edges;
+	u32 *wake_mask;
+	u32 *cur_mask;
 };
 
 int mtk_pctrl_init(struct platform_device *pdev,
@@ -281,4 +283,6 @@ int mtk_pconf_spec_set_ies_smt_range(struct regmap *regmap,
 		const struct mtk_pin_ies_smt_set *ies_smt_infos, unsigned int info_num,
 		unsigned int pin, unsigned char align, int value);
 
+extern const struct dev_pm_ops mtk_eint_pm_ops;
+
 #endif /* __PINCTRL_MTK_COMMON_H */
-- 
1.8.1.1.dirty



From hramrach at gmail.com  Fri Aug  7 03:16:38 2015
From: hramrach at gmail.com (Michal Suchanek)
Date: Fri, 7 Aug 2015 12:16:38 +0200
Subject: [RFC PATCH 1/5] spi: introduce flag for memory mapped read
In-Reply-To: <55C46B84.3010304@sperl.org>
References: <20150805115013.GJ20873@sirena.org.uk>
 <CAOMqctQXwcHyiWBwtugSDSE_k65qrNfrwnhjQMDJkLoJMmGzUw@mail.gmail.com>
 <20150805124412.GN20873@sirena.org.uk>
 <CAOMqctS9Y5FxpUCCJew6+cnjH5iTvbzkH3g-8yrXs4OuS2pSGA@mail.gmail.com>
 <20150806090202.GO20873@sirena.org.uk>
 <CAOMqctQZRZ4zG_yYy=CeX3DX4NVNWN1COP4Q-2YvMun9xYOA7g@mail.gmail.com>
 <20150806102225.GI7576@n2100.arm.linux.org.uk> <55C35233.2000105@ti.com>
 <20150806135129.GJ7576@n2100.arm.linux.org.uk>
 <CAMuHMdWWDwZ=ziGQXFCnOX8pErXpsEi533J73_Hh=sEqq4hR6Q@mail.gmail.com>
 <20150806213340.GK7576@n2100.arm.linux.org.uk> <55C46B84.3010304@sperl.org>
Message-ID: <CAOMqctScUybdoZPgqH185qzDxB=TyutDMARextHx0XwC7L3Xmw@mail.gmail.com>

On 7 August 2015 at 10:25, Martin Sperl <martin at sperl.org> wrote:
> On 8/6/2015 23:33, Russell King - ARM Linux wrote:
>>
>> On Thu, Aug 06, 2015 at 06:14:00PM +0200, Geert Uytterhoeven wrote:
>>>
>>>
>>> Irrespective of the dummy bytes.
>>> What if the spi device is not a FLASH ROM, but some other device,
>>> which receives a data packet that accidentally looks like an m25p80 READ
>>> command?
>>
>> Well, for the most part it looks like it should still work, but there
>> could be a gotcha, but first, let's get rid of a myth there.
>>
>> The QSPI is _not_ specific to the M25P80.  The manual says nothing
>> about being specific to that device.  What it says is that it's for
>> SPI NOR memory.  It will work with bus widths of 1, 2 or 4 data lines,
>> so it probably works with non-M25P80 SPI NOR devices too - and the fact
>> that the read and write commands are completely programmable suggests
>> that using it with SPI NOR devices which do not use the M25P80 read
>> command value is intended.
>>
>>
>> The SFI is a state machine based translator which sits behind the SPI
>> interface (look at the manual).  It sequence sthe SPI bus through a
>> series of standard SPI states which happen to be the states I detailed
>> above.
>>
>> Now, the first byte of the SFI-generated SPI message can be programmed
>> to any 8 bit value.  So the first byte of the SPI message is totally
>> under software control.  The next one to four bytes which comprise the
>> "address" can be controlled to by deciding where in the memory map to
>> start reading from.  Hence, the value of those bytes is also totally
>> under software control.  The number of dummy bytes can be programmed
>> too.  So far so good.
>>
>> So, if we know that we have a SPI message which says "send 0x01 0x20
>> 0x30, send one dummy byte, read 32 bytes", if we program the SFI to
>> send a read command as 0x01, program an address length of 2 bytes
>> with one dummy byte, and then read the next 32 bytes at the appropriate
>> offset in the memory mapping to cause the next two bytes to be 0x20,
>> 0x30, then what we end up with on the bus is:
>>
>>         send 0x01, 0x20, 0x30
>>         send one dummy byte
>>
>> That much is good, but now is the problem - how does the SFI know that
>> we're going to require to read 32 bytes?  I think the answer to that
>> is that it doesn't know, so it probably just reads the number of bytes
>> which the access on the SoC bus is asking for, which makes it
>> indeterminant from a software point of view to control how many bytes
>> will be read without provoking another "send 0x01, next address, dummy
>> byte" sequence.
>>
>> So, I'm now on the side of not parsing commands in the SPI driver, and
>> back on the idea that this needs to be handled in some other manner
>> which doesn't involve polluting the SPI core with flag-hacks.
>>
> So I see 2 distinct options:
>
> Have the nor driver modified to run SPI commands and then ask the
> SPI framework (and driver) to switch into mmap mode:
>
> Would probably look something like this inside the nor driver:
>    /* lock spi bus for other activities */
>    spi_bus_lock(spi);
>    /* send the "configuration" for mmap */
>    t[0].tx_buf = flash->command;
>    t[0].len = m25p_cmdsz(nor);
>    spi_message_add_tail(&t[0], &m);
>    t[1].tx_buf = dummy_buffer;
>    t[1].len = dummy;
>    spi_message_add_tail(&t[1], &m);
>    spi_sync(spi, &m);

>    /* switch to mmap mode */
>    spi->mode |= SPI_MMAP;

Presumably you will do this *before* sending the read command so the
SPI driver can reverse-engineer it according to the spi-nor read
pattern.

Then the mmap mode can be set in spi_sync() but you also have to lock
the spi controller to prevent other transfers from resetting it.

Or you can pass the read buffer to the SPI master driver as well to do
the memcpy for you. Which you want to do anyway in case the SPI master
can use DMA to fill the buffer rather than memcpy.

>    spi_setup(spi);
>    /* run the mmapped transfers bypassing the spi-layer */
>    memcpy(...)
>    /* open questions here: which address range
>     * and how to detect if transfer is done
> */

Presumably when the memcpy ends the transfer is done.

> /* restore back to "normal" mode */
>    spi->mode &= ~SPI_MMAP;
>    spi_setup(spi);
>    /* unlock spi bus for other activities */
>    spi_bus_unlock(spi);

Presumably you have to restore to non-mmap mode only when you receive
a command that requires it. If the next command is read with same
configuration you can just keep reading.

>
> The downside is that it requires modification in several places
> (nor-framework, spi-framework plus the driver) and it would not
> be generic enough...

You only need modification to the SPI master driver and m25p80 driver.

The SPI master driver is where the hardware-specific operation is
executed and m25p80 is where you have the information so you can
decide to take advantage of the hardware acceleration.

>
> IMO such a situation is feasible if we only got a single device
> on the spi-bus, but leaves a lot of questions open...
> Alternatively we could create an additional api.

The spi master driver can track what mode is set on the controller and
change it as needed before each transfer. This is what is commonly
done for other SPI master hardware configuration options.

>
> On the other end of spectrum could be a solution where the
> spi-master driverwould have the opportunity to query the
> device-tree for specific propertiesduring the spi_add_device
> phase - in this case querying the followingproperty in the
> device-tree:
>   spi-master-XXX,use-mmap-cmd-mode = <0x08 0x38>;
> to implement mmap-mode for commands 0x08 and 0x38.

This is bogus.

Firstly this is per-slave and not per-master.

Secondly in devicetree you have jedec,spi-nor which says exactly that
the SPI slave is a device that responds to the JEDEC identify command.
Nothing more. The data returned from the identify command is used to
determine what the command opcodes are, what features are supported,
etc. So that is *not* in the dt and there is no place for hardwiring
opcodes in the dt.

> Alternatively we could also introduce generic alternate modes
> for the driver(similar to GPIO - ALT modes), but that would be
> less transparent and more hard-coded...
>
> In the end this would mean that from the nor framework side
> therewould be no change at all - it still would be issuing
> something like this:
>    /* send the "normal" block read command */
>    t[0].tx_buf = flash->command;
>    /* note that the address would be encoded here */
>    t[0].len = m25p_cmdsz(nor);
>    spi_message_add_tail(&t[0], &m);
>    /* dummy bytes could also get added to the above transfer */
>    t[1].tx_buf = dummy_buffer;
>    t[1].len = dummy;
>    spi_message_add_tail(&t[1], &m);
>    /* the real transfer */
>    t[2].rx_buf = read_buffer;
>    t[2].len = transfer_size;
>    spi_message_add_tail(&t[2], &m);
>    spi_sync(spi, &m);
>
> On the spi-master side the driver would need to run:
> *  if the spi-message (in this case the first byte) matches
>    the "allowed" command pattern:

There is no 'allowed' pattern. Any message like 1~7 bytes long can be
interpreted as read command. Unless you can tell the SPI master driver
it cannot know.

And you go the abominable route of the original patch that you compose
a SPI message in m25p80, and then decide in the SPI master driver that
you will in fact not send a SPI message and reverse-engineer what
m25p80 really meant.

On 7 August 2015 at 10:35, Vignesh R <vigneshr at ti.com> wrote:
>
>
> On 08/07/2015 01:08 PM, Michal Suchanek wrote:
>
>> Now since the description is clearer it's obvious that ti-qspi cannot
>> work fully mmapped as fsl-qspi does because the setup has to be done
>> over normal spi access and using non-m25p80 devices on the same bus is
>> a requirement.
>>
>> The place where it is known if a transfer can use the mmap access is m25p80.c
>>
>> So my suggestion is
>>
>>  - add a new method for spi master that gets the read opcode, dummy
>> length, address, address length, buffer, buffer length and performs
>> read from the flash memory in a hardware-specific way
>>
>> - add a check in m25p80.c that the master supports this feature and if
>> so use it (eg check that the method is non-null)
>>
>> Presumably if some new SPI controllers with similar feature are
>> supported in the future they can use the same inteface because you
>> pass on everything the m25p80 read knows.
>>
>
> Ok... Do you mean something like this?
>
> I will take m25p80 as example but can be expanded for any flash.
>
> In include/linux/mtd.h:
>         struct spi_mtd_config_info {
>                 struct spi_device       *spi;
>                 u32                     page_size;
>                 u8                      addr_width;
>                 u8                      erase_opcode;
>                 u8                      read_opcode;
>                 u8                      read_dummy;
>                 u8                      program_opcode;
>                 enum read_mode          flash_read;
>
>         } /* subset of struct spi_nor */
>

I would just pass these as separate arguments to the function but whatver.

> In m25p80.c:
>
>         static int m25p80_read(struct spi_nor *nor, loff_t from,
>                                 size_t len, size_t *retlen,
>                                 u_char *buf)
>         {
>                 struct spi_mtd_config_info info;
>                 struct spi_device *spi;
>
>                 if (spi->master->spi_mtd_mmap_read) {
>                   /* Populate spi_mtd_config_info */
>                   spi->master->spi_mtd_mmap_read(&info, from, len,
>                                                  retlen, buf);
>                 }
>                 else {
>                 /* no mtd specific acceleration supported try normal
>                  * SPI way of communicating with flash
>                  * continue with current code
>                  * set up spi_message and call spi_sync()
>                  */
>         }
>
>       }
>
> In spi-ti-qspi.c:
> Implement spi_mtd_mmap_read while holding master->bus_lock mutex.
>

Thanks

Michal


From p.fedin at samsung.com  Fri Aug  7 03:20:43 2015
From: p.fedin at samsung.com (Pavel Fedin)
Date: Fri, 07 Aug 2015 13:20:43 +0300
Subject: [PATCH TRIVIAL] Enable GICv2m on ARM virt machine
In-Reply-To: <55C471D0.8050400@arm.com>
References: <00f501d0ce9c$4d57bcc0$e8073640$@samsung.com>
 <55C471D0.8050400@arm.com>
Message-ID: <00f901d0d0fa$b8168770$28439650$@samsung.com>

Hello!

> You may want to add a comment about the dependency chain that requires
> the generic msi.h.

 The error i get is:
--- cut ---
In file included from kernel/irq/chip.c:14:0:
include/linux/msi.h:123:21: fatal error: asm/msi.h: No such file or directory
 #include <asm/msi.h>
                     ^
--- cut ---

This portion in linux/msi.h sits under #ifdef CONFIG_GENERIC_MSI_IRQ_DOMAIN, which is activated by
the following chain:
ARM_GIC_V2M => PCI_MSI_IRQ_DOMAIN => GENERIC_MSI_IRQ_DOMAIN

 Do i need to respin just because of comment?

Kind regards,
Pavel Fedin
Expert Engineer
Samsung Electronics Research center Russia




From marc.zyngier at arm.com  Fri Aug  7 03:33:54 2015
From: marc.zyngier at arm.com (Marc Zyngier)
Date: Fri, 07 Aug 2015 11:33:54 +0100
Subject: [PATCH TRIVIAL] Enable GICv2m on ARM virt machine
In-Reply-To: <00f901d0d0fa$b8168770$28439650$@samsung.com>
References: <00f501d0ce9c$4d57bcc0$e8073640$@samsung.com>
 <55C471D0.8050400@arm.com> <00f901d0d0fa$b8168770$28439650$@samsung.com>
Message-ID: <55C48992.6060700@arm.com>

On 07/08/15 11:20, Pavel Fedin wrote:
> Hello!
> 
>> You may want to add a comment about the dependency chain that requires
>> the generic msi.h.
> 
>  The error i get is:
> --- cut ---
> In file included from kernel/irq/chip.c:14:0:
> include/linux/msi.h:123:21: fatal error: asm/msi.h: No such file or directory
>  #include <asm/msi.h>
>                      ^
> --- cut ---
> 
> This portion in linux/msi.h sits under #ifdef CONFIG_GENERIC_MSI_IRQ_DOMAIN, which is activated by
> the following chain:
> ARM_GIC_V2M => PCI_MSI_IRQ_DOMAIN => GENERIC_MSI_IRQ_DOMAIN
> 
>  Do i need to respin just because of comment?

That's for Russell to decide, really. But I feel that adding an include
file that affects the whole architecture (and not just a single
platform) deserves an explanation in the commit log.

Thanks,

	M.
-- 
Jazz is not dead. It just smells funny...


From b.zolnierkie at samsung.com  Fri Aug  7 03:34:23 2015
From: b.zolnierkie at samsung.com (Bartlomiej Zolnierkiewicz)
Date: Fri, 07 Aug 2015 12:34:23 +0200
Subject: [PATCH v4 1/6] cpufreq: make scaling_boost_freqs sysfs attr
 available when boost is enabled
In-Reply-To: <20150807034128.GE6325@linux>
References: <1438868514-8814-1-git-send-email-b.zolnierkie@samsung.com>
 <1438868514-8814-2-git-send-email-b.zolnierkie@samsung.com>
 <20150807034128.GE6325@linux>
Message-ID: <5184469.cOpIkgzX4h@amdc1976>


Hi,

On Friday, August 07, 2015 09:11:28 AM Viresh Kumar wrote:
> Hi,
> 
> I would suggest you sending such patches as reply to the earlier
> threads only, instead of a new chain. This will save your time.

Please explain it more.  This patch needs to be first for cpufreq-dt
switch to be complete.  scaling_boost_freqs is available currently
for exynos-cpufreq users when boost is enabled and ideally we would
like it to be available immediately after the switch to cpufreq-dt.

> For example, you will need to resend other patches unnecessarily if I
> NAK this patch :)
> 
> On 06-08-15, 15:41, Bartlomiej Zolnierkiewicz wrote:
> > Add cpufreq_boost_enabled_generic_attr table and use it in
> > cpufreq-dt driver instead of cpufreq_generic_attr one when
> > boost support is enabled.  As a result scaling_boost_freqs
> > sysfs attribute is available when cpufreq-dt driver is
> > used and boost support is enabled.
> > 
> > Cc: Viresh Kumar <viresh.kumar at linaro.org>
> > Cc: Thomas Abraham <thomas.ab at samsung.com>
> > Cc: Javier Martinez Canillas <javier at osg.samsung.com>
> > Cc: Krzysztof Kozlowski <k.kozlowski at samsung.com>
> > Signed-off-by: Bartlomiej Zolnierkiewicz <b.zolnierkie at samsung.com>
> > ---
> >  drivers/cpufreq/cpufreq-dt.c | 3 +++
> >  drivers/cpufreq/freq_table.c | 7 +++++++
> >  include/linux/cpufreq.h      | 1 +
> >  3 files changed, 11 insertions(+)
> > 
> > diff --git a/drivers/cpufreq/cpufreq-dt.c b/drivers/cpufreq/cpufreq-dt.c
> > index b9259ab..7b091c0 100644
> > --- a/drivers/cpufreq/cpufreq-dt.c
> > +++ b/drivers/cpufreq/cpufreq-dt.c
> > @@ -182,6 +182,8 @@ try_again:
> >  	return ret;
> >  }
> >  
> > +static struct cpufreq_driver dt_cpufreq_driver;
> > +
> >  static int cpufreq_init(struct cpufreq_policy *policy)
> >  {
> >  	struct cpufreq_frequency_table *freq_table;
> > @@ -336,6 +338,7 @@ static int cpufreq_init(struct cpufreq_policy *policy)
> >  		ret = cpufreq_enable_boost_support();
> >  		if (ret)
> >  			goto out_free_cpufreq_table;
> > +		dt_cpufreq_driver.attr = cpufreq_boost_enabled_generic_attr;
> >  	}
> >  
> >  	policy->cpuinfo.transition_latency = transition_latency;
> > diff --git a/drivers/cpufreq/freq_table.c b/drivers/cpufreq/freq_table.c
> > index a8f1daf..5a00a09 100644
> > --- a/drivers/cpufreq/freq_table.c
> > +++ b/drivers/cpufreq/freq_table.c
> > @@ -300,6 +300,13 @@ struct freq_attr *cpufreq_generic_attr[] = {
> >  };
> >  EXPORT_SYMBOL_GPL(cpufreq_generic_attr);
> >  
> > +struct freq_attr *cpufreq_boost_enabled_generic_attr[] = {
> > +	&cpufreq_freq_attr_scaling_available_freqs,
> > +	&cpufreq_freq_attr_scaling_boost_freqs,
> > +	NULL,
> > +};
> > +EXPORT_SYMBOL_GPL(cpufreq_boost_enabled_generic_attr);
> 
> This isn't scalable. We can't create a new generic structure every time
> a entry comes in. Rather we should leave the generic attr for

boost entry is rather generic one so I imagine that other cpufreq
drivers that add support for boost would also like to use it.

Anyway since there are no such drivers currently I agree that
making a new generic structure may be premature and I will re-do
this patch according to your request.

Best regards,
--
Bartlomiej Zolnierkiewicz
Samsung R&D Institute Poland
Samsung Electronics

> cpufreq-dt and do something like this in the cpufreq-dt driver (And
> that patch should rather go via cpufreq tree and not ARM SoC)..
> 
> diff --git a/drivers/cpufreq/cpufreq-dt.c b/drivers/cpufreq/cpufreq-dt.c
> index a5b6a854661f..e229258ad791 100644
> --- a/drivers/cpufreq/cpufreq-dt.c
> +++ b/drivers/cpufreq/cpufreq-dt.c
> @@ -36,6 +36,12 @@ struct private_data {
>  	unsigned int voltage_tolerance; /* in percentage */
>  };
>  
> +static struct freq_attr *cpufreq_dt_attr[] = {
> +	&cpufreq_freq_attr_scaling_available_freqs,
> +	NULL,	/* Extra space for boost-attr if required */
> +	NULL,
> +};
> +
>  static int set_target(struct cpufreq_policy *policy, unsigned int index)
>  {
>  	struct dev_pm_opp *opp;
> @@ -337,6 +343,7 @@ static int cpufreq_init(struct cpufreq_policy *policy)
>  		ret = cpufreq_enable_boost_support();
>  		if (ret)
>  			goto out_free_cpufreq_table;
> +		cpufreq_dt_attr[1] = &cpufreq_freq_attr_scaling_boost_freqs;
>  	}
>  
>  	policy->cpuinfo.transition_latency = transition_latency;
> @@ -412,7 +419,7 @@ static struct cpufreq_driver dt_cpufreq_driver = {
>  	.exit = cpufreq_exit,
>  	.ready = cpufreq_ready,
>  	.name = "cpufreq-dt",
> -	.attr = cpufreq_generic_attr,
> +	.attr = cpufreq_dt_attr,
>  };
>  
>  static int dt_cpufreq_probe(struct platform_device *pdev)



From ykk at rock-chips.com  Fri Aug  7 03:34:34 2015
From: ykk at rock-chips.com (Yakir Yang)
Date: Fri,  7 Aug 2015 05:34:34 -0500
Subject: [PATCH v2 0/8] Add Analogix Core Display Port Driver
Message-ID: <1438943674-18191-1-git-send-email-ykk@rock-chips.com>

Hi all,
   The Samsung Exynos eDP controller and Rockchip RK3288 eDP controller
share the same IP, so a lot of parts can be re-used. I split the common
code into bridge directory, then rk3288 and exynos only need to keep
some platform code. Cause I can't find the exact IP name of exynos dp
controller, so I decide to name dp core driver with "analogix" which I
find in rk3288 eDP TRM ;)

Beyond that, there are three light registers setting differents bewteen
exynos and rk3288.
1. RK3288 have five special pll resigters which not indicata in exynos
   dp controller.
2. The address of DP_PHY_PD(dp phy power manager register) are different
   between rk3288 and exynos.
3. Rk3288 and exynos have different setting with AUX_HW_RETRY_CTL(dp debug
   register).

My series patches can be divider into two parts: One for spliting the
analogix_dp code from exynos dp driver. Another are trying to add rk3288
platform special code.

Thanks,
- Yakir

Changes in v2:
- Take Joe Preches advise, improved commit message more readable, and
  avoid using some uncommon style like bellow:
  -  retval = exynos_dp_read_bytes_from_i2c(...
				...)
  +  retval =
  +  exynos_dp_read_bytes_from_i2c(......);
- Take Jingoo Han suggest, cause I jsut improve parts
  of the code, so just remove my name from author list.
- Take Jingoo Han suggest, remove new copyright
- Fix compiled failed dut to analogix_dp_device misspell
- Add GNU license v2 declared and samsung copyright
- Fix compile failed dut to phy_pd_addr variable misspell error

Yakir Yang (8):
  drm: exynos/dp: fix code style
  drm: exynos/dp: convert to drm bridge mode
  drm: bridge: analogix_dp: split exynos dp driver to bridge dir
  drm: rockchip/dp: add rockchip platform dp driver
  drm: bridge/analogix_dp: add platform device type support
  drm: bridge: analogix_dp: add some rk3288 special registers setting
  drm: bridge: analogix_dp: try force hpd after plug in lookup failed
  drm: bridge/analogix_dp: expand the delay time for hpd detect

 drivers/gpu/drm/bridge/Kconfig                     |    5 +
 drivers/gpu/drm/bridge/Makefile                    |    1 +
 drivers/gpu/drm/bridge/analogix_dp_core.c          | 1397 +++++++++++++++++++
 drivers/gpu/drm/bridge/analogix_dp_core.h          |  286 ++++
 drivers/gpu/drm/bridge/analogix_dp_reg.c           | 1294 ++++++++++++++++++
 .../exynos_dp_reg.h => bridge/analogix_dp_reg.h}   |  270 ++--
 drivers/gpu/drm/exynos/Kconfig                     |    5 +-
 drivers/gpu/drm/exynos/Makefile                    |    2 +-
 drivers/gpu/drm/exynos/analogix_dp-exynos.c        |  238 ++++
 drivers/gpu/drm/exynos/exynos_dp_core.c            | 1416 --------------------
 drivers/gpu/drm/exynos/exynos_dp_core.h            |  282 ----
 drivers/gpu/drm/exynos/exynos_dp_reg.c             | 1263 -----------------
 drivers/gpu/drm/rockchip/Kconfig                   |   10 +
 drivers/gpu/drm/rockchip/Makefile                  |    1 +
 drivers/gpu/drm/rockchip/analogix_dp-rockchip.c    |  420 ++++++
 include/drm/bridge/analogix_dp.h                   |   38 +
 16 files changed, 3835 insertions(+), 3093 deletions(-)
 create mode 100644 drivers/gpu/drm/bridge/analogix_dp_core.c
 create mode 100644 drivers/gpu/drm/bridge/analogix_dp_core.h
 create mode 100644 drivers/gpu/drm/bridge/analogix_dp_reg.c
 rename drivers/gpu/drm/{exynos/exynos_dp_reg.h => bridge/analogix_dp_reg.h} (62%)
 create mode 100644 drivers/gpu/drm/exynos/analogix_dp-exynos.c
 delete mode 100644 drivers/gpu/drm/exynos/exynos_dp_core.c
 delete mode 100644 drivers/gpu/drm/exynos/exynos_dp_core.h
 delete mode 100644 drivers/gpu/drm/exynos/exynos_dp_reg.c
 create mode 100644 drivers/gpu/drm/rockchip/analogix_dp-rockchip.c
 create mode 100644 include/drm/bridge/analogix_dp.h

-- 
1.9.1




From ykk at rock-chips.com  Fri Aug  7 03:37:10 2015
From: ykk at rock-chips.com (Yakir Yang)
Date: Fri,  7 Aug 2015 05:37:10 -0500
Subject: [PATCH v2 1/8] drm: exynos/dp: fix code style
In-Reply-To: <1438943674-18191-1-git-send-email-ykk@rock-chips.com>
References: <1438943674-18191-1-git-send-email-ykk@rock-chips.com>
Message-ID: <1438943830-18386-1-git-send-email-ykk@rock-chips.com>

After run "checkpatch.pl -f --subjective" command, I see there
are lots of alignment problem in exynos_dp driver, so let just
fix them.

Signed-off-by: Yakir Yang <ykk at rock-chips.com>
---
Changes in v2:
- Take Joe Preches advise, improved commit message more readable, and
  avoid using some uncommon style like bellow:
  -  retval = exynos_dp_read_bytes_from_i2c(...
				...)
  +  retval =
  +  exynos_dp_read_bytes_from_i2c(......);

 drivers/gpu/drm/exynos/exynos_dp_core.c | 219 ++++++++++++++++----------------
 drivers/gpu/drm/exynos/exynos_dp_core.h |  53 ++++----
 drivers/gpu/drm/exynos/exynos_dp_reg.c  | 100 +++++++--------
 3 files changed, 182 insertions(+), 190 deletions(-)

diff --git a/drivers/gpu/drm/exynos/exynos_dp_core.c b/drivers/gpu/drm/exynos/exynos_dp_core.c
index 172b800..562f4a8 100644
--- a/drivers/gpu/drm/exynos/exynos_dp_core.c
+++ b/drivers/gpu/drm/exynos/exynos_dp_core.c
@@ -114,8 +114,8 @@ static int exynos_dp_read_edid(struct exynos_dp_device *dp)
 
 	/* Read Extension Flag, Number of 128-byte EDID extension blocks */
 	retval = exynos_dp_read_byte_from_i2c(dp, I2C_EDID_DEVICE_ADDR,
-				EDID_EXTENSION_FLAG,
-				&extend_block);
+					      EDID_EXTENSION_FLAG,
+					      &extend_block);
 	if (retval)
 		return retval;
 
@@ -123,10 +123,11 @@ static int exynos_dp_read_edid(struct exynos_dp_device *dp)
 		dev_dbg(dp->dev, "EDID data includes a single extension!\n");
 
 		/* Read EDID data */
-		retval = exynos_dp_read_bytes_from_i2c(dp, I2C_EDID_DEVICE_ADDR,
-						EDID_HEADER_PATTERN,
-						EDID_BLOCK_LENGTH,
-						&edid[EDID_HEADER_PATTERN]);
+		retval = exynos_dp_read_bytes_from_i2c(
+					dp, I2C_EDID_DEVICE_ADDR,
+					EDID_HEADER_PATTERN,
+					EDID_BLOCK_LENGTH,
+					&edid[EDID_HEADER_PATTERN]);
 		if (retval != 0) {
 			dev_err(dp->dev, "EDID Read failed!\n");
 			return -EIO;
@@ -138,11 +139,11 @@ static int exynos_dp_read_edid(struct exynos_dp_device *dp)
 		}
 
 		/* Read additional EDID data */
-		retval = exynos_dp_read_bytes_from_i2c(dp,
-				I2C_EDID_DEVICE_ADDR,
-				EDID_BLOCK_LENGTH,
-				EDID_BLOCK_LENGTH,
-				&edid[EDID_BLOCK_LENGTH]);
+		retval = exynos_dp_read_bytes_from_i2c(
+					dp, I2C_EDID_DEVICE_ADDR,
+					EDID_BLOCK_LENGTH,
+					EDID_BLOCK_LENGTH,
+					&edid[EDID_BLOCK_LENGTH]);
 		if (retval != 0) {
 			dev_err(dp->dev, "EDID Read failed!\n");
 			return -EIO;
@@ -154,24 +155,22 @@ static int exynos_dp_read_edid(struct exynos_dp_device *dp)
 		}
 
 		exynos_dp_read_byte_from_dpcd(dp, DP_TEST_REQUEST,
-					&test_vector);
+					      &test_vector);
 		if (test_vector & DP_TEST_LINK_EDID_READ) {
-			exynos_dp_write_byte_to_dpcd(dp,
-				DP_TEST_EDID_CHECKSUM,
+			exynos_dp_write_byte_to_dpcd(
+				dp, DP_TEST_EDID_CHECKSUM,
 				edid[EDID_BLOCK_LENGTH + EDID_CHECKSUM]);
-			exynos_dp_write_byte_to_dpcd(dp,
-				DP_TEST_RESPONSE,
+			exynos_dp_write_byte_to_dpcd(
+				dp, DP_TEST_RESPONSE,
 				DP_TEST_EDID_CHECKSUM_WRITE);
 		}
 	} else {
 		dev_info(dp->dev, "EDID data does not include any extensions.\n");
 
 		/* Read EDID data */
-		retval = exynos_dp_read_bytes_from_i2c(dp,
-				I2C_EDID_DEVICE_ADDR,
-				EDID_HEADER_PATTERN,
-				EDID_BLOCK_LENGTH,
-				&edid[EDID_HEADER_PATTERN]);
+		retval = exynos_dp_read_bytes_from_i2c(
+				dp, I2C_EDID_DEVICE_ADDR, EDID_HEADER_PATTERN,
+				EDID_BLOCK_LENGTH, &edid[EDID_HEADER_PATTERN]);
 		if (retval != 0) {
 			dev_err(dp->dev, "EDID Read failed!\n");
 			return -EIO;
@@ -182,16 +181,15 @@ static int exynos_dp_read_edid(struct exynos_dp_device *dp)
 			return -EIO;
 		}
 
-		exynos_dp_read_byte_from_dpcd(dp,
-			DP_TEST_REQUEST,
-			&test_vector);
+		exynos_dp_read_byte_from_dpcd(dp, DP_TEST_REQUEST,
+					      &test_vector);
 		if (test_vector & DP_TEST_LINK_EDID_READ) {
-			exynos_dp_write_byte_to_dpcd(dp,
-				DP_TEST_EDID_CHECKSUM,
-				edid[EDID_CHECKSUM]);
-			exynos_dp_write_byte_to_dpcd(dp,
-				DP_TEST_RESPONSE,
-				DP_TEST_EDID_CHECKSUM_WRITE);
+			exynos_dp_write_byte_to_dpcd(
+					dp, DP_TEST_EDID_CHECKSUM,
+					edid[EDID_CHECKSUM]);
+			exynos_dp_write_byte_to_dpcd(
+					dp, DP_TEST_RESPONSE,
+					DP_TEST_EDID_CHECKSUM_WRITE);
 		}
 	}
 
@@ -206,8 +204,7 @@ static int exynos_dp_handle_edid(struct exynos_dp_device *dp)
 	int retval;
 
 	/* Read DPCD DP_DPCD_REV~RECEIVE_PORT1_CAP_1 */
-	retval = exynos_dp_read_bytes_from_dpcd(dp, DP_DPCD_REV,
-				12, buf);
+	retval = exynos_dp_read_bytes_from_dpcd(dp, DP_DPCD_REV, 12, buf);
 	if (retval)
 		return retval;
 
@@ -222,19 +219,21 @@ static int exynos_dp_handle_edid(struct exynos_dp_device *dp)
 }
 
 static void exynos_dp_enable_rx_to_enhanced_mode(struct exynos_dp_device *dp,
-						bool enable)
+						 bool enable)
 {
 	u8 data;
 
 	exynos_dp_read_byte_from_dpcd(dp, DP_LANE_COUNT_SET, &data);
 
 	if (enable)
-		exynos_dp_write_byte_to_dpcd(dp, DP_LANE_COUNT_SET,
-			DP_LANE_COUNT_ENHANCED_FRAME_EN |
-			DPCD_LANE_COUNT_SET(data));
+		exynos_dp_write_byte_to_dpcd(
+					dp, DP_LANE_COUNT_SET,
+					DP_LANE_COUNT_ENHANCED_FRAME_EN |
+					DPCD_LANE_COUNT_SET(data));
 	else
-		exynos_dp_write_byte_to_dpcd(dp, DP_LANE_COUNT_SET,
-			DPCD_LANE_COUNT_SET(data));
+		exynos_dp_write_byte_to_dpcd(
+					dp, DP_LANE_COUNT_SET,
+					DPCD_LANE_COUNT_SET(data));
 }
 
 static int exynos_dp_is_enhanced_mode_available(struct exynos_dp_device *dp)
@@ -261,13 +260,12 @@ static void exynos_dp_training_pattern_dis(struct exynos_dp_device *dp)
 {
 	exynos_dp_set_training_pattern(dp, DP_NONE);
 
-	exynos_dp_write_byte_to_dpcd(dp,
-		DP_TRAINING_PATTERN_SET,
-		DP_TRAINING_PATTERN_DISABLE);
+	exynos_dp_write_byte_to_dpcd(dp, DP_TRAINING_PATTERN_SET,
+				     DP_TRAINING_PATTERN_DISABLE);
 }
 
 static void exynos_dp_set_lane_lane_pre_emphasis(struct exynos_dp_device *dp,
-					int pre_emphasis, int lane)
+						 int pre_emphasis, int lane)
 {
 	switch (lane) {
 	case 0:
@@ -307,15 +305,14 @@ static int exynos_dp_link_start(struct exynos_dp_device *dp)
 	/* Setup RX configuration */
 	buf[0] = dp->link_train.link_rate;
 	buf[1] = dp->link_train.lane_count;
-	retval = exynos_dp_write_bytes_to_dpcd(dp, DP_LINK_BW_SET,
-				2, buf);
+	retval = exynos_dp_write_bytes_to_dpcd(dp, DP_LINK_BW_SET, 2, buf);
 	if (retval)
 		return retval;
 
 	/* Set TX pre-emphasis to minimum */
 	for (lane = 0; lane < lane_count; lane++)
-		exynos_dp_set_lane_lane_pre_emphasis(dp,
-			PRE_EMPHASIS_LEVEL_0, lane);
+		exynos_dp_set_lane_lane_pre_emphasis(dp, PRE_EMPHASIS_LEVEL_0,
+						     lane);
 
 	/* Wait for PLL lock */
 	pll_tries = 0;
@@ -333,9 +330,9 @@ static int exynos_dp_link_start(struct exynos_dp_device *dp)
 	exynos_dp_set_training_pattern(dp, TRAINING_PTN1);
 
 	/* Set RX training pattern */
-	retval = exynos_dp_write_byte_to_dpcd(dp,
-			DP_TRAINING_PATTERN_SET,
-			DP_LINK_SCRAMBLING_DISABLE | DP_TRAINING_PATTERN_1);
+	retval = exynos_dp_write_byte_to_dpcd(dp, DP_TRAINING_PATTERN_SET,
+					      DP_LINK_SCRAMBLING_DISABLE |
+					      DP_TRAINING_PATTERN_1);
 	if (retval)
 		return retval;
 
@@ -344,7 +341,7 @@ static int exynos_dp_link_start(struct exynos_dp_device *dp)
 			    DP_TRAIN_VOLTAGE_SWING_LEVEL_0;
 
 	retval = exynos_dp_write_bytes_to_dpcd(dp, DP_TRAINING_LANE0_SET,
-			lane_count, buf);
+					       lane_count, buf);
 
 	return retval;
 }
@@ -352,7 +349,7 @@ static int exynos_dp_link_start(struct exynos_dp_device *dp)
 static unsigned char exynos_dp_get_lane_status(u8 link_status[2], int lane)
 {
 	int shift = (lane & 1) * 4;
-	u8 link_value = link_status[lane>>1];
+	u8 link_value = link_status[lane >> 1];
 
 	return (link_value >> shift) & 0xf;
 }
@@ -371,7 +368,7 @@ static int exynos_dp_clock_recovery_ok(u8 link_status[2], int lane_count)
 }
 
 static int exynos_dp_channel_eq_ok(u8 link_status[2], u8 link_align,
-				int lane_count)
+				   int lane_count)
 {
 	int lane;
 	u8 lane_status;
@@ -390,10 +387,10 @@ static int exynos_dp_channel_eq_ok(u8 link_status[2], u8 link_align,
 }
 
 static unsigned char exynos_dp_get_adjust_request_voltage(u8 adjust_request[2],
-							int lane)
+							  int lane)
 {
 	int shift = (lane & 1) * 4;
-	u8 link_value = adjust_request[lane>>1];
+	u8 link_value = adjust_request[lane >> 1];
 
 	return (link_value >> shift) & 0x3;
 }
@@ -403,13 +400,13 @@ static unsigned char exynos_dp_get_adjust_request_pre_emphasis(
 					int lane)
 {
 	int shift = (lane & 1) * 4;
-	u8 link_value = adjust_request[lane>>1];
+	u8 link_value = adjust_request[lane >> 1];
 
 	return ((link_value >> shift) & 0xc) >> 2;
 }
 
 static void exynos_dp_set_lane_link_training(struct exynos_dp_device *dp,
-					u8 training_lane_set, int lane)
+					     u8 training_lane_set, int lane)
 {
 	switch (lane) {
 	case 0:
@@ -465,7 +462,7 @@ static void exynos_dp_reduce_link_rate(struct exynos_dp_device *dp)
 }
 
 static void exynos_dp_get_adjust_training_lane(struct exynos_dp_device *dp,
-					u8 adjust_request[2])
+					       u8 adjust_request[2])
 {
 	int lane, lane_count;
 	u8 voltage_swing, pre_emphasis, training_lane;
@@ -498,13 +495,13 @@ static int exynos_dp_process_clock_recovery(struct exynos_dp_device *dp)
 
 	lane_count = dp->link_train.lane_count;
 
-	retval =  exynos_dp_read_bytes_from_dpcd(dp,
-			DP_LANE0_1_STATUS, 2, link_status);
+	retval = exynos_dp_read_bytes_from_dpcd(dp, DP_LANE0_1_STATUS,
+						2, link_status);
 	if (retval)
 		return retval;
 
-	retval =  exynos_dp_read_bytes_from_dpcd(dp,
-			DP_ADJUST_REQUEST_LANE0_1, 2, adjust_request);
+	retval = exynos_dp_read_bytes_from_dpcd(dp, DP_ADJUST_REQUEST_LANE0_1,
+						2, adjust_request);
 	if (retval)
 		return retval;
 
@@ -512,8 +509,8 @@ static int exynos_dp_process_clock_recovery(struct exynos_dp_device *dp)
 		/* set training pattern 2 for EQ */
 		exynos_dp_set_training_pattern(dp, TRAINING_PTN2);
 
-		retval = exynos_dp_write_byte_to_dpcd(dp,
-				DP_TRAINING_PATTERN_SET,
+		retval = exynos_dp_write_byte_to_dpcd(
+				dp, DP_TRAINING_PATTERN_SET,
 				DP_LINK_SCRAMBLING_DISABLE |
 				DP_TRAINING_PATTERN_2);
 		if (retval)
@@ -551,11 +548,11 @@ static int exynos_dp_process_clock_recovery(struct exynos_dp_device *dp)
 	exynos_dp_get_adjust_training_lane(dp, adjust_request);
 
 	for (lane = 0; lane < lane_count; lane++)
-		exynos_dp_set_lane_link_training(dp,
-			dp->link_train.training_lane[lane], lane);
+		exynos_dp_set_lane_link_training(
+				dp, dp->link_train.training_lane[lane], lane);
 
-	retval = exynos_dp_write_bytes_to_dpcd(dp,
-			DP_TRAINING_LANE0_SET, lane_count,
+	retval = exynos_dp_write_bytes_to_dpcd(
+			dp, DP_TRAINING_LANE0_SET, lane_count,
 			dp->link_train.training_lane);
 	if (retval)
 		return retval;
@@ -573,8 +570,8 @@ static int exynos_dp_process_equalizer_training(struct exynos_dp_device *dp)
 
 	lane_count = dp->link_train.lane_count;
 
-	retval = exynos_dp_read_bytes_from_dpcd(dp,
-			DP_LANE0_1_STATUS, 2, link_status);
+	retval = exynos_dp_read_bytes_from_dpcd(dp, DP_LANE0_1_STATUS,
+						2, link_status);
 	if (retval)
 		return retval;
 
@@ -583,13 +580,13 @@ static int exynos_dp_process_equalizer_training(struct exynos_dp_device *dp)
 		return -EIO;
 	}
 
-	retval = exynos_dp_read_bytes_from_dpcd(dp,
-			DP_ADJUST_REQUEST_LANE0_1, 2, adjust_request);
+	retval = exynos_dp_read_bytes_from_dpcd(dp, DP_ADJUST_REQUEST_LANE0_1,
+						2, adjust_request);
 	if (retval)
 		return retval;
 
-	retval = exynos_dp_read_byte_from_dpcd(dp,
-			DP_LANE_ALIGN_STATUS_UPDATED, &link_align);
+	retval = exynos_dp_read_byte_from_dpcd(
+			dp, DP_LANE_ALIGN_STATUS_UPDATED, &link_align);
 	if (retval)
 		return retval;
 
@@ -628,17 +625,18 @@ static int exynos_dp_process_equalizer_training(struct exynos_dp_device *dp)
 	}
 
 	for (lane = 0; lane < lane_count; lane++)
-		exynos_dp_set_lane_link_training(dp,
-			dp->link_train.training_lane[lane], lane);
+		exynos_dp_set_lane_link_training(
+				dp, dp->link_train.training_lane[lane], lane);
 
 	retval = exynos_dp_write_bytes_to_dpcd(dp, DP_TRAINING_LANE0_SET,
-			lane_count, dp->link_train.training_lane);
+					       lane_count,
+					       dp->link_train.training_lane);
 
 	return retval;
 }
 
 static void exynos_dp_get_max_rx_bandwidth(struct exynos_dp_device *dp,
-					u8 *bandwidth)
+					   u8 *bandwidth)
 {
 	u8 data;
 
@@ -651,7 +649,7 @@ static void exynos_dp_get_max_rx_bandwidth(struct exynos_dp_device *dp,
 }
 
 static void exynos_dp_get_max_rx_lane_count(struct exynos_dp_device *dp,
-					u8 *lane_count)
+					    u8 *lane_count)
 {
 	u8 data;
 
@@ -664,8 +662,8 @@ static void exynos_dp_get_max_rx_lane_count(struct exynos_dp_device *dp,
 }
 
 static void exynos_dp_init_training(struct exynos_dp_device *dp,
-			enum link_lane_count_type max_lane,
-			enum link_rate_type max_rate)
+				    enum link_lane_count_type max_lane,
+				    enum link_rate_type max_rate)
 {
 	/*
 	 * MACRO_RST must be applied after the PLL_LOCK to avoid
@@ -678,7 +676,7 @@ static void exynos_dp_init_training(struct exynos_dp_device *dp,
 	exynos_dp_get_max_rx_lane_count(dp, &dp->link_train.lane_count);
 
 	if ((dp->link_train.link_rate != LINK_RATE_1_62GBPS) &&
-	   (dp->link_train.link_rate != LINK_RATE_2_70GBPS)) {
+	    (dp->link_train.link_rate != LINK_RATE_2_70GBPS)) {
 		dev_err(dp->dev, "Rx Max Link Rate is abnormal :%x !\n",
 			dp->link_train.link_rate);
 		dp->link_train.link_rate = LINK_RATE_1_62GBPS;
@@ -738,8 +736,7 @@ static int exynos_dp_sw_link_training(struct exynos_dp_device *dp)
 }
 
 static int exynos_dp_set_link_train(struct exynos_dp_device *dp,
-				u32 count,
-				u32 bwtype)
+				    u32 count, u32 bwtype)
 {
 	int i;
 	int retval;
@@ -830,21 +827,19 @@ static void exynos_dp_enable_scramble(struct exynos_dp_device *dp, bool enable)
 	if (enable) {
 		exynos_dp_enable_scrambling(dp);
 
-		exynos_dp_read_byte_from_dpcd(dp,
-			DP_TRAINING_PATTERN_SET,
-			&data);
-		exynos_dp_write_byte_to_dpcd(dp,
-			DP_TRAINING_PATTERN_SET,
+		exynos_dp_read_byte_from_dpcd(dp, DP_TRAINING_PATTERN_SET,
+					      &data);
+		exynos_dp_write_byte_to_dpcd(
+			dp, DP_TRAINING_PATTERN_SET,
 			(u8)(data & ~DP_LINK_SCRAMBLING_DISABLE));
 	} else {
 		exynos_dp_disable_scrambling(dp);
 
-		exynos_dp_read_byte_from_dpcd(dp,
-			DP_TRAINING_PATTERN_SET,
-			&data);
-		exynos_dp_write_byte_to_dpcd(dp,
-			DP_TRAINING_PATTERN_SET,
-			(u8)(data | DP_LINK_SCRAMBLING_DISABLE));
+		exynos_dp_read_byte_from_dpcd(dp, DP_TRAINING_PATTERN_SET,
+					      &data);
+		exynos_dp_write_byte_to_dpcd(
+				dp, DP_TRAINING_PATTERN_SET,
+				(u8)(data | DP_LINK_SCRAMBLING_DISABLE));
 	}
 }
 
@@ -915,7 +910,7 @@ static void exynos_dp_commit(struct exynos_drm_display *display)
 	}
 
 	ret = exynos_dp_set_link_train(dp, dp->video_info->lane_count,
-					dp->video_info->link_rate);
+				       dp->video_info->link_rate);
 	if (ret) {
 		dev_err(dp->dev, "unable to do link train\n");
 		return;
@@ -1004,7 +999,7 @@ static struct drm_connector_helper_funcs exynos_dp_connector_helper_funcs = {
 
 /* returns the number of bridges attached */
 static int exynos_drm_attach_lcd_bridge(struct exynos_dp_device *dp,
-		struct drm_encoder *encoder)
+					struct drm_encoder *encoder)
 {
 	int ret;
 
@@ -1020,7 +1015,7 @@ static int exynos_drm_attach_lcd_bridge(struct exynos_dp_device *dp,
 }
 
 static int exynos_dp_create_connector(struct exynos_drm_display *display,
-				struct drm_encoder *encoder)
+				      struct drm_encoder *encoder)
 {
 	struct exynos_dp_device *dp = display_to_dp(display);
 	struct drm_connector *connector = &dp->connector;
@@ -1038,7 +1033,8 @@ static int exynos_dp_create_connector(struct exynos_drm_display *display,
 	connector->polled = DRM_CONNECTOR_POLL_HPD;
 
 	ret = drm_connector_init(dp->drm_dev, connector,
-			&exynos_dp_connector_funcs, DRM_MODE_CONNECTOR_eDP);
+				 &exynos_dp_connector_funcs,
+				 DRM_MODE_CONNECTOR_eDP);
 	if (ret) {
 		DRM_ERROR("Failed to initialize connector with drm\n");
 		return ret;
@@ -1148,8 +1144,8 @@ static struct video_info *exynos_dp_dt_parse_pdata(struct device *dev)
 	struct device_node *dp_node = dev->of_node;
 	struct video_info *dp_video_config;
 
-	dp_video_config = devm_kzalloc(dev,
-				sizeof(*dp_video_config), GFP_KERNEL);
+	dp_video_config = devm_kzalloc(dev, sizeof(*dp_video_config),
+				       GFP_KERNEL);
 	if (!dp_video_config)
 		return ERR_PTR(-ENOMEM);
 
@@ -1163,37 +1159,37 @@ static struct video_info *exynos_dp_dt_parse_pdata(struct device *dev)
 		of_property_read_bool(dp_node, "interlaced");
 
 	if (of_property_read_u32(dp_node, "samsung,color-space",
-				&dp_video_config->color_space)) {
+				 &dp_video_config->color_space)) {
 		dev_err(dev, "failed to get color-space\n");
 		return ERR_PTR(-EINVAL);
 	}
 
 	if (of_property_read_u32(dp_node, "samsung,dynamic-range",
-				&dp_video_config->dynamic_range)) {
+				 &dp_video_config->dynamic_range)) {
 		dev_err(dev, "failed to get dynamic-range\n");
 		return ERR_PTR(-EINVAL);
 	}
 
 	if (of_property_read_u32(dp_node, "samsung,ycbcr-coeff",
-				&dp_video_config->ycbcr_coeff)) {
+				 &dp_video_config->ycbcr_coeff)) {
 		dev_err(dev, "failed to get ycbcr-coeff\n");
 		return ERR_PTR(-EINVAL);
 	}
 
 	if (of_property_read_u32(dp_node, "samsung,color-depth",
-				&dp_video_config->color_depth)) {
+				 &dp_video_config->color_depth)) {
 		dev_err(dev, "failed to get color-depth\n");
 		return ERR_PTR(-EINVAL);
 	}
 
 	if (of_property_read_u32(dp_node, "samsung,link-rate",
-				&dp_video_config->link_rate)) {
+				 &dp_video_config->link_rate)) {
 		dev_err(dev, "failed to get link-rate\n");
 		return ERR_PTR(-EINVAL);
 	}
 
 	if (of_property_read_u32(dp_node, "samsung,lane-count",
-				&dp_video_config->lane_count)) {
+				 &dp_video_config->lane_count)) {
 		dev_err(dev, "failed to get lane-count\n");
 		return ERR_PTR(-EINVAL);
 	}
@@ -1206,7 +1202,7 @@ static int exynos_dp_dt_parse_panel(struct exynos_dp_device *dp)
 	int ret;
 
 	ret = of_get_videomode(dp->dev->of_node, &dp->priv.vm,
-			OF_USE_NATIVE_MODE);
+			       OF_USE_NATIVE_MODE);
 	if (ret) {
 		DRM_ERROR("failed: of_get_videomode() : %d\n", ret);
 		return ret;
@@ -1302,7 +1298,7 @@ static int exynos_dp_bind(struct device *dev, struct device *master, void *data)
 	exynos_dp_init_dp(dp);
 
 	ret = devm_request_irq(&pdev->dev, dp->irq, exynos_dp_irq_handler,
-			irq_flags, "exynos-dp", dp);
+			       irq_flags, "exynos-dp", dp);
 	if (ret) {
 		dev_err(&pdev->dev, "failed to request irq\n");
 		return ret;
@@ -1315,7 +1311,7 @@ static int exynos_dp_bind(struct device *dev, struct device *master, void *data)
 }
 
 static void exynos_dp_unbind(struct device *dev, struct device *master,
-				void *data)
+			     void *data)
 {
 	struct exynos_dp_device *dp = dev_get_drvdata(dev);
 
@@ -1334,7 +1330,7 @@ static int exynos_dp_probe(struct platform_device *pdev)
 	struct exynos_dp_device *dp;
 
 	dp = devm_kzalloc(&pdev->dev, sizeof(struct exynos_dp_device),
-				GFP_KERNEL);
+			  GFP_KERNEL);
 	if (!dp)
 		return -ENOMEM;
 
@@ -1358,8 +1354,9 @@ static int exynos_dp_probe(struct platform_device *pdev)
 			of_node_put(bridge_node);
 			if (!dp->bridge)
 				return -EPROBE_DEFER;
-		} else
+		} else {
 			return -EPROBE_DEFER;
+		}
 	}
 
 	return component_add(&pdev->dev, &exynos_dp_ops);
diff --git a/drivers/gpu/drm/exynos/exynos_dp_core.h b/drivers/gpu/drm/exynos/exynos_dp_core.h
index a4e7996..c321ad5 100644
--- a/drivers/gpu/drm/exynos/exynos_dp_core.h
+++ b/drivers/gpu/drm/exynos/exynos_dp_core.h
@@ -180,8 +180,8 @@ void exynos_dp_config_interrupt(struct exynos_dp_device *dp);
 enum pll_status exynos_dp_get_pll_lock_status(struct exynos_dp_device *dp);
 void exynos_dp_set_pll_power_down(struct exynos_dp_device *dp, bool enable);
 void exynos_dp_set_analog_power_down(struct exynos_dp_device *dp,
-				enum analog_power_block block,
-				bool enable);
+				     enum analog_power_block block,
+				     bool enable);
 void exynos_dp_init_analog_func(struct exynos_dp_device *dp);
 void exynos_dp_init_hpd(struct exynos_dp_device *dp);
 enum dp_irq_type exynos_dp_get_irq_type(struct exynos_dp_device *dp);
@@ -192,50 +192,50 @@ int exynos_dp_get_plug_in_status(struct exynos_dp_device *dp);
 void exynos_dp_enable_sw_function(struct exynos_dp_device *dp);
 int exynos_dp_start_aux_transaction(struct exynos_dp_device *dp);
 int exynos_dp_write_byte_to_dpcd(struct exynos_dp_device *dp,
-				unsigned int reg_addr,
-				unsigned char data);
+				 unsigned int reg_addr,
+				 unsigned char data);
 int exynos_dp_read_byte_from_dpcd(struct exynos_dp_device *dp,
-				unsigned int reg_addr,
-				unsigned char *data);
+				  unsigned int reg_addr,
+				  unsigned char *data);
 int exynos_dp_write_bytes_to_dpcd(struct exynos_dp_device *dp,
-				unsigned int reg_addr,
-				unsigned int count,
-				unsigned char data[]);
+				  unsigned int reg_addr,
+				  unsigned int count,
+				  unsigned char data[]);
 int exynos_dp_read_bytes_from_dpcd(struct exynos_dp_device *dp,
-				unsigned int reg_addr,
-				unsigned int count,
-				unsigned char data[]);
+				   unsigned int reg_addr,
+				   unsigned int count,
+				   unsigned char data[]);
 int exynos_dp_select_i2c_device(struct exynos_dp_device *dp,
 				unsigned int device_addr,
 				unsigned int reg_addr);
 int exynos_dp_read_byte_from_i2c(struct exynos_dp_device *dp,
-				unsigned int device_addr,
-				unsigned int reg_addr,
-				unsigned int *data);
+				 unsigned int device_addr,
+				 unsigned int reg_addr,
+				 unsigned int *data);
 int exynos_dp_read_bytes_from_i2c(struct exynos_dp_device *dp,
-				unsigned int device_addr,
-				unsigned int reg_addr,
-				unsigned int count,
-				unsigned char edid[]);
+				  unsigned int device_addr,
+				  unsigned int reg_addr,
+				  unsigned int count,
+				  unsigned char edid[]);
 void exynos_dp_set_link_bandwidth(struct exynos_dp_device *dp, u32 bwtype);
 void exynos_dp_get_link_bandwidth(struct exynos_dp_device *dp, u32 *bwtype);
 void exynos_dp_set_lane_count(struct exynos_dp_device *dp, u32 count);
 void exynos_dp_get_lane_count(struct exynos_dp_device *dp, u32 *count);
 void exynos_dp_enable_enhanced_mode(struct exynos_dp_device *dp, bool enable);
 void exynos_dp_set_training_pattern(struct exynos_dp_device *dp,
-				 enum pattern_set pattern);
+				    enum pattern_set pattern);
 void exynos_dp_set_lane0_pre_emphasis(struct exynos_dp_device *dp, u32 level);
 void exynos_dp_set_lane1_pre_emphasis(struct exynos_dp_device *dp, u32 level);
 void exynos_dp_set_lane2_pre_emphasis(struct exynos_dp_device *dp, u32 level);
 void exynos_dp_set_lane3_pre_emphasis(struct exynos_dp_device *dp, u32 level);
 void exynos_dp_set_lane0_link_training(struct exynos_dp_device *dp,
-				u32 training_lane);
+				       u32 training_lane);
 void exynos_dp_set_lane1_link_training(struct exynos_dp_device *dp,
-				u32 training_lane);
+				       u32 training_lane);
 void exynos_dp_set_lane2_link_training(struct exynos_dp_device *dp,
-				u32 training_lane);
+				       u32 training_lane);
 void exynos_dp_set_lane3_link_training(struct exynos_dp_device *dp,
-				u32 training_lane);
+				       u32 training_lane);
 u32 exynos_dp_get_lane0_link_training(struct exynos_dp_device *dp);
 u32 exynos_dp_get_lane1_link_training(struct exynos_dp_device *dp);
 u32 exynos_dp_get_lane2_link_training(struct exynos_dp_device *dp);
@@ -246,9 +246,8 @@ void exynos_dp_init_video(struct exynos_dp_device *dp);
 void exynos_dp_set_video_color_format(struct exynos_dp_device *dp);
 int exynos_dp_is_slave_video_stream_clock_on(struct exynos_dp_device *dp);
 void exynos_dp_set_video_cr_mn(struct exynos_dp_device *dp,
-			enum clock_recovery_m_value_type type,
-			u32 m_value,
-			u32 n_value);
+			       enum clock_recovery_m_value_type type,
+			       u32 m_value, u32 n_value);
 void exynos_dp_set_video_timing_mode(struct exynos_dp_device *dp, u32 type);
 void exynos_dp_enable_video_master(struct exynos_dp_device *dp, bool enable);
 void exynos_dp_start_video(struct exynos_dp_device *dp);
diff --git a/drivers/gpu/drm/exynos/exynos_dp_reg.c b/drivers/gpu/drm/exynos/exynos_dp_reg.c
index c1f87a2..9aa483d 100644
--- a/drivers/gpu/drm/exynos/exynos_dp_reg.c
+++ b/drivers/gpu/drm/exynos/exynos_dp_reg.c
@@ -202,8 +202,8 @@ void exynos_dp_set_pll_power_down(struct exynos_dp_device *dp, bool enable)
 }
 
 void exynos_dp_set_analog_power_down(struct exynos_dp_device *dp,
-				enum analog_power_block block,
-				bool enable)
+				     enum analog_power_block block,
+				     bool enable)
 {
 	u32 reg;
 
@@ -399,8 +399,8 @@ void exynos_dp_init_aux(struct exynos_dp_device *dp)
 	exynos_dp_reset_aux(dp);
 
 	/* Disable AUX transaction H/W retry */
-	reg = AUX_BIT_PERIOD_EXPECTED_DELAY(3) | AUX_HW_RETRY_COUNT_SEL(0)|
-		AUX_HW_RETRY_INTERVAL_600_MICROSECONDS;
+	reg = AUX_BIT_PERIOD_EXPECTED_DELAY(3) | AUX_HW_RETRY_COUNT_SEL(0) |
+	      AUX_HW_RETRY_INTERVAL_600_MICROSECONDS;
 	writel(reg, dp->reg_base + EXYNOS_DP_AUX_HW_RETRY_CTL);
 
 	/* Receive AUX Channel DEFER commands equal to DEFFER_COUNT*64 */
@@ -483,8 +483,8 @@ int exynos_dp_start_aux_transaction(struct exynos_dp_device *dp)
 }
 
 int exynos_dp_write_byte_to_dpcd(struct exynos_dp_device *dp,
-				unsigned int reg_addr,
-				unsigned char data)
+				 unsigned int reg_addr,
+				 unsigned char data)
 {
 	u32 reg;
 	int i;
@@ -519,17 +519,16 @@ int exynos_dp_write_byte_to_dpcd(struct exynos_dp_device *dp,
 		retval = exynos_dp_start_aux_transaction(dp);
 		if (retval == 0)
 			break;
-		else
-			dev_dbg(dp->dev, "%s: Aux Transaction fail!\n",
-				__func__);
+
+		dev_dbg(dp->dev, "%s: Aux Transaction fail!\n", __func__);
 	}
 
 	return retval;
 }
 
 int exynos_dp_read_byte_from_dpcd(struct exynos_dp_device *dp,
-				unsigned int reg_addr,
-				unsigned char *data)
+				  unsigned int reg_addr,
+				  unsigned char *data)
 {
 	u32 reg;
 	int i;
@@ -560,9 +559,8 @@ int exynos_dp_read_byte_from_dpcd(struct exynos_dp_device *dp,
 		retval = exynos_dp_start_aux_transaction(dp);
 		if (retval == 0)
 			break;
-		else
-			dev_dbg(dp->dev, "%s: Aux Transaction fail!\n",
-				__func__);
+
+		dev_dbg(dp->dev, "%s: Aux Transaction fail!\n", __func__);
 	}
 
 	/* Read data buffer */
@@ -573,9 +571,9 @@ int exynos_dp_read_byte_from_dpcd(struct exynos_dp_device *dp,
 }
 
 int exynos_dp_write_bytes_to_dpcd(struct exynos_dp_device *dp,
-				unsigned int reg_addr,
-				unsigned int count,
-				unsigned char data[])
+				  unsigned int reg_addr,
+				  unsigned int count,
+				  unsigned char data[])
 {
 	u32 reg;
 	unsigned int start_offset;
@@ -625,9 +623,9 @@ int exynos_dp_write_bytes_to_dpcd(struct exynos_dp_device *dp,
 			retval = exynos_dp_start_aux_transaction(dp);
 			if (retval == 0)
 				break;
-			else
-				dev_dbg(dp->dev, "%s: Aux Transaction fail!\n",
-					__func__);
+
+			dev_dbg(dp->dev, "%s: Aux Transaction fail!\n",
+				__func__);
 		}
 
 		start_offset += cur_data_count;
@@ -637,9 +635,9 @@ int exynos_dp_write_bytes_to_dpcd(struct exynos_dp_device *dp,
 }
 
 int exynos_dp_read_bytes_from_dpcd(struct exynos_dp_device *dp,
-				unsigned int reg_addr,
-				unsigned int count,
-				unsigned char data[])
+				   unsigned int reg_addr,
+				   unsigned int count,
+				   unsigned char data[])
 {
 	u32 reg;
 	unsigned int start_offset;
@@ -683,9 +681,9 @@ int exynos_dp_read_bytes_from_dpcd(struct exynos_dp_device *dp,
 			retval = exynos_dp_start_aux_transaction(dp);
 			if (retval == 0)
 				break;
-			else
-				dev_dbg(dp->dev, "%s: Aux Transaction fail!\n",
-					__func__);
+
+			dev_dbg(dp->dev, "%s: Aux Transaction fail!\n",
+				__func__);
 		}
 
 		for (cur_data_idx = 0; cur_data_idx < cur_data_count;
@@ -736,9 +734,9 @@ int exynos_dp_select_i2c_device(struct exynos_dp_device *dp,
 }
 
 int exynos_dp_read_byte_from_i2c(struct exynos_dp_device *dp,
-				unsigned int device_addr,
-				unsigned int reg_addr,
-				unsigned int *data)
+				 unsigned int device_addr,
+				 unsigned int reg_addr,
+				 unsigned int *data)
 {
 	u32 reg;
 	int i;
@@ -767,9 +765,8 @@ int exynos_dp_read_byte_from_i2c(struct exynos_dp_device *dp,
 		retval = exynos_dp_start_aux_transaction(dp);
 		if (retval == 0)
 			break;
-		else
-			dev_dbg(dp->dev, "%s: Aux Transaction fail!\n",
-				__func__);
+
+		dev_dbg(dp->dev, "%s: Aux Transaction fail!\n", __func__);
 	}
 
 	/* Read data */
@@ -780,10 +777,10 @@ int exynos_dp_read_byte_from_i2c(struct exynos_dp_device *dp,
 }
 
 int exynos_dp_read_bytes_from_i2c(struct exynos_dp_device *dp,
-				unsigned int device_addr,
-				unsigned int reg_addr,
-				unsigned int count,
-				unsigned char edid[])
+				  unsigned int device_addr,
+				  unsigned int reg_addr,
+				  unsigned int count,
+				  unsigned char edid[])
 {
 	u32 reg;
 	unsigned int i, j;
@@ -807,8 +804,8 @@ int exynos_dp_read_bytes_from_i2c(struct exynos_dp_device *dp,
 			 * request without sending address
 			 */
 			if (!defer)
-				retval = exynos_dp_select_i2c_device(dp,
-						device_addr, reg_addr + i);
+				retval = exynos_dp_select_i2c_device(
+						dp, device_addr, reg_addr + i);
 			else
 				defer = 0;
 
@@ -828,15 +825,14 @@ int exynos_dp_read_bytes_from_i2c(struct exynos_dp_device *dp,
 				retval = exynos_dp_start_aux_transaction(dp);
 				if (retval == 0)
 					break;
-				else
-					dev_dbg(dp->dev,
-						"%s: Aux Transaction fail!\n",
-						__func__);
+
+				dev_dbg(dp->dev, "%s: Aux Transaction fail!\n",
+					__func__);
 			}
 			/* Check if Rx sends defer */
 			reg = readl(dp->reg_base + EXYNOS_DP_AUX_RX_COMM);
 			if (reg == AUX_RX_COMM_AUX_DEFER ||
-				reg == AUX_RX_COMM_I2C_DEFER) {
+			    reg == AUX_RX_COMM_I2C_DEFER) {
 				dev_err(dp->dev, "Defer: %d\n\n", reg);
 				defer = 1;
 			}
@@ -901,7 +897,7 @@ void exynos_dp_enable_enhanced_mode(struct exynos_dp_device *dp, bool enable)
 }
 
 void exynos_dp_set_training_pattern(struct exynos_dp_device *dp,
-				 enum pattern_set pattern)
+				    enum pattern_set pattern)
 {
 	u32 reg;
 
@@ -974,7 +970,7 @@ void exynos_dp_set_lane3_pre_emphasis(struct exynos_dp_device *dp, u32 level)
 }
 
 void exynos_dp_set_lane0_link_training(struct exynos_dp_device *dp,
-					u32 training_lane)
+				       u32 training_lane)
 {
 	u32 reg;
 
@@ -983,7 +979,7 @@ void exynos_dp_set_lane0_link_training(struct exynos_dp_device *dp,
 }
 
 void exynos_dp_set_lane1_link_training(struct exynos_dp_device *dp,
-					u32 training_lane)
+				       u32 training_lane)
 {
 	u32 reg;
 
@@ -992,7 +988,7 @@ void exynos_dp_set_lane1_link_training(struct exynos_dp_device *dp,
 }
 
 void exynos_dp_set_lane2_link_training(struct exynos_dp_device *dp,
-					u32 training_lane)
+				       u32 training_lane)
 {
 	u32 reg;
 
@@ -1001,7 +997,7 @@ void exynos_dp_set_lane2_link_training(struct exynos_dp_device *dp,
 }
 
 void exynos_dp_set_lane3_link_training(struct exynos_dp_device *dp,
-					u32 training_lane)
+				       u32 training_lane)
 {
 	u32 reg;
 
@@ -1125,9 +1121,9 @@ int exynos_dp_is_slave_video_stream_clock_on(struct exynos_dp_device *dp)
 }
 
 void exynos_dp_set_video_cr_mn(struct exynos_dp_device *dp,
-		enum clock_recovery_m_value_type type,
-		u32 m_value,
-		u32 n_value)
+			       enum clock_recovery_m_value_type type,
+			       u32 m_value,
+			       u32 n_value)
 {
 	u32 reg;
 
@@ -1221,7 +1217,7 @@ void exynos_dp_config_video_slave_mode(struct exynos_dp_device *dp)
 	u32 reg;
 
 	reg = readl(dp->reg_base + EXYNOS_DP_FUNC_EN_1);
-	reg &= ~(MASTER_VID_FUNC_EN_N|SLAVE_VID_FUNC_EN_N);
+	reg &= ~(MASTER_VID_FUNC_EN_N | SLAVE_VID_FUNC_EN_N);
 	reg |= MASTER_VID_FUNC_EN_N;
 	writel(reg, dp->reg_base + EXYNOS_DP_FUNC_EN_1);
 
-- 
1.9.1




From viresh.kumar at linaro.org  Fri Aug  7 03:41:56 2015
From: viresh.kumar at linaro.org (Viresh Kumar)
Date: Fri, 7 Aug 2015 16:11:56 +0530
Subject: [PATCH v4 1/6] cpufreq: make scaling_boost_freqs sysfs attr
 available when boost is enabled
In-Reply-To: <5184469.cOpIkgzX4h@amdc1976>
References: <1438868514-8814-1-git-send-email-b.zolnierkie@samsung.com>
 <1438868514-8814-2-git-send-email-b.zolnierkie@samsung.com>
 <20150807034128.GE6325@linux> <5184469.cOpIkgzX4h@amdc1976>
Message-ID: <20150807104156.GE6939@linux>

On 07-08-15, 12:34, Bartlomiej Zolnierkiewicz wrote:
> > I would suggest you sending such patches as reply to the earlier
> > threads only, instead of a new chain. This will save your time.
> 
> Please explain it more.  This patch needs to be first for cpufreq-dt
> switch to be complete.  scaling_boost_freqs is available currently
> for exynos-cpufreq users when boost is enabled and ideally we would
> like it to be available immediately after the switch to cpufreq-dt.

I wasn't talking about the ordering of the patches here, but when to
send patches.

So, you now sent these patches again, but what you could have done
is: only send the first patch in reply to the earlier thread. And ask
if it looks fine. If yes, resend the whole series properly or keep
fixing there only..

That makes things really fast. You don't have to resend the series and
people wouldn't stay away from it. I stayed away from this series to
find enough available time to see your 6 patches. Had it been just a
reply, I would have replied immediately like now.

Look at how updated versions in the same mail chain in case of OPP
series..

-- 
viresh


From ykk at rock-chips.com  Fri Aug  7 03:40:38 2015
From: ykk at rock-chips.com (Yakir Yang)
Date: Fri,  7 Aug 2015 05:40:38 -0500
Subject: [PATCH v2 2/8] drm: exynos/dp: convert to drm bridge mode
In-Reply-To: <1438943674-18191-1-git-send-email-ykk@rock-chips.com>
References: <1438943674-18191-1-git-send-email-ykk@rock-chips.com>
Message-ID: <1438944039-18690-1-git-send-email-ykk@rock-chips.com>

In order to move exynos dp code to bridge directory,
we need to convert driver drm bridge mode first. As
dp driver already have a ptn3460 bridge, so we need
to move ptn bridge to the next bridge of dp bridge.

Signed-off-by: Yakir Yang <ykk at rock-chips.com>
---
Changes in v2:
- Take Jingoo Han suggest, cause I jsut improve parts
  of the code, so just remove my name from author list.

 drivers/gpu/drm/exynos/exynos_dp_core.c | 194 ++++++++++++++++++++------------
 drivers/gpu/drm/exynos/exynos_dp_core.h |   1 +
 2 files changed, 123 insertions(+), 72 deletions(-)

diff --git a/drivers/gpu/drm/exynos/exynos_dp_core.c b/drivers/gpu/drm/exynos/exynos_dp_core.c
index 562f4a8..2b87406 100644
--- a/drivers/gpu/drm/exynos/exynos_dp_core.c
+++ b/drivers/gpu/drm/exynos/exynos_dp_core.c
@@ -997,59 +997,6 @@ static struct drm_connector_helper_funcs exynos_dp_connector_helper_funcs = {
 	.best_encoder = exynos_dp_best_encoder,
 };
 
-/* returns the number of bridges attached */
-static int exynos_drm_attach_lcd_bridge(struct exynos_dp_device *dp,
-					struct drm_encoder *encoder)
-{
-	int ret;
-
-	encoder->bridge = dp->bridge;
-	dp->bridge->encoder = encoder;
-	ret = drm_bridge_attach(encoder->dev, dp->bridge);
-	if (ret) {
-		DRM_ERROR("Failed to attach bridge to drm\n");
-		return ret;
-	}
-
-	return 0;
-}
-
-static int exynos_dp_create_connector(struct exynos_drm_display *display,
-				      struct drm_encoder *encoder)
-{
-	struct exynos_dp_device *dp = display_to_dp(display);
-	struct drm_connector *connector = &dp->connector;
-	int ret;
-
-	dp->encoder = encoder;
-
-	/* Pre-empt DP connector creation if there's a bridge */
-	if (dp->bridge) {
-		ret = exynos_drm_attach_lcd_bridge(dp, encoder);
-		if (!ret)
-			return 0;
-	}
-
-	connector->polled = DRM_CONNECTOR_POLL_HPD;
-
-	ret = drm_connector_init(dp->drm_dev, connector,
-				 &exynos_dp_connector_funcs,
-				 DRM_MODE_CONNECTOR_eDP);
-	if (ret) {
-		DRM_ERROR("Failed to initialize connector with drm\n");
-		return ret;
-	}
-
-	drm_connector_helper_add(connector, &exynos_dp_connector_helper_funcs);
-	drm_connector_register(connector);
-	drm_mode_connector_attach_encoder(connector, encoder);
-
-	if (dp->panel)
-		ret = drm_panel_attach(dp->panel, &dp->connector);
-
-	return ret;
-}
-
 static void exynos_dp_phy_init(struct exynos_dp_device *dp)
 {
 	if (dp->phy)
@@ -1114,23 +1061,126 @@ static void exynos_dp_poweroff(struct exynos_dp_device *dp)
 	}
 }
 
-static void exynos_dp_dpms(struct exynos_drm_display *display, int mode)
+/* returns the number of bridges attached */
+static int exynos_drm_attach_lcd_bridge(struct exynos_dp_device *dp,
+		struct drm_encoder *encoder)
+{
+	int ret;
+
+	dp->bridge->next = dp->ptn_bridge;
+	dp->bridge->encoder = encoder;
+	ret = drm_bridge_attach(encoder->dev, dp->bridge);
+	if (ret) {
+		DRM_ERROR("Failed to attach ptn bridge to drm\n");
+		return ret;
+	}
+
+	return 0;
+}
+
+static int exynos_dp_bridge_attach(struct drm_bridge *bridge)
+{
+
+	struct exynos_dp_device *dp = bridge->driver_private;
+	struct drm_encoder *encoder = dp->encoder;
+	struct drm_connector *connector = &dp->connector;
+	int ret;
+
+	if (!bridge->encoder) {
+		DRM_ERROR("Parent encoder object not found");
+		return -ENODEV;
+	}
+
+	encoder->bridge = bridge;
+
+	/* Pre-empt DP connector creation if there's a bridge */
+	if (dp->ptn_bridge) {
+		ret = exynos_drm_attach_lcd_bridge(dp, encoder);
+		if (ret)
+			return -ENODEV;
+	}
+
+	connector->polled = DRM_CONNECTOR_POLL_HPD;
+
+	ret = drm_connector_init(dp->drm_dev, connector,
+			&exynos_dp_connector_funcs, DRM_MODE_CONNECTOR_eDP);
+	if (ret) {
+		DRM_ERROR("Failed to initialize connector with drm\n");
+		return ret;
+	}
+
+	drm_connector_helper_add(connector, &exynos_dp_connector_helper_funcs);
+	drm_connector_register(connector);
+	drm_mode_connector_attach_encoder(connector, encoder);
+
+	if (dp->panel)
+		ret = drm_panel_attach(dp->panel, &dp->connector);
+
+	return ret;
+}
+
+static void exynos_dp_bridge_nop(struct drm_bridge *bridge)
+{
+	/* do nothing */
+}
+
+static void exynos_dp_bridge_enable(struct drm_bridge *bridge)
+{
+	struct exynos_dp_device *dp = bridge->driver_private;
+
+	exynos_dp_poweron(dp);
+	dp->dpms_mode = DRM_MODE_DPMS_ON;
+}
+
+static void exynos_dp_bridge_disable(struct drm_bridge *bridge)
+{
+	struct exynos_dp_device *dp = bridge->driver_private;
+
+	exynos_dp_poweroff(dp);
+	dp->dpms_mode = DRM_MODE_DPMS_OFF;
+}
+
+static const struct drm_bridge_funcs exynos_dp_bridge_funcs = {
+	.enable = exynos_dp_bridge_enable,
+	.disable = exynos_dp_bridge_disable,
+	.pre_enable = exynos_dp_bridge_nop,
+	.post_disable = exynos_dp_bridge_nop,
+	.attach = exynos_dp_bridge_attach,
+};
+
+static int exynos_dp_create_connector(struct exynos_drm_display *display,
+				struct drm_encoder *encoder)
 {
 	struct exynos_dp_device *dp = display_to_dp(display);
+	struct drm_device *drm_dev = dp->drm_dev;
+	struct drm_bridge *bridge;
+	int ret;
 
-	switch (mode) {
-	case DRM_MODE_DPMS_ON:
-		exynos_dp_poweron(dp);
-		break;
-	case DRM_MODE_DPMS_STANDBY:
-	case DRM_MODE_DPMS_SUSPEND:
-	case DRM_MODE_DPMS_OFF:
-		exynos_dp_poweroff(dp);
-		break;
-	default:
-		break;
+	bridge = devm_kzalloc(drm_dev->dev, sizeof(*bridge), GFP_KERNEL);
+	if (!bridge) {
+		DRM_ERROR("failed to allocate for drm bridge\n");
+		return -ENOMEM;
 	}
-	dp->dpms_mode = mode;
+
+	dp->bridge = bridge;
+	dp->encoder = encoder;
+
+	bridge->driver_private = dp;
+	bridge->encoder = dp->encoder;
+	bridge->funcs = &exynos_dp_bridge_funcs;
+
+	ret = drm_bridge_attach(drm_dev, bridge);
+	if (ret) {
+		DRM_ERROR("failed to attach drm bridge\n");
+		return -EINVAL;
+	}
+
+	return 0;
+}
+
+static void exynos_dp_dpms(struct exynos_drm_display *display, int mode)
+{
+	/* do nothing */
 }
 
 static struct exynos_drm_display_ops exynos_dp_display_ops = {
@@ -1242,7 +1292,7 @@ static int exynos_dp_bind(struct device *dev, struct device *master, void *data)
 		}
 	}
 
-	if (!dp->panel && !dp->bridge) {
+	if (!dp->panel && !dp->ptn_bridge) {
 		ret = exynos_dp_dt_parse_panel(dp);
 		if (ret)
 			return ret;
@@ -1315,7 +1365,7 @@ static void exynos_dp_unbind(struct device *dev, struct device *master,
 {
 	struct exynos_dp_device *dp = dev_get_drvdata(dev);
 
-	exynos_dp_dpms(&dp->display, DRM_MODE_DPMS_OFF);
+	exynos_dp_bridge_disable(dp->bridge);
 }
 
 static const struct component_ops exynos_dp_ops = {
@@ -1350,9 +1400,9 @@ static int exynos_dp_probe(struct platform_device *pdev)
 	if (endpoint) {
 		bridge_node = of_graph_get_remote_port_parent(endpoint);
 		if (bridge_node) {
-			dp->bridge = of_drm_find_bridge(bridge_node);
+			dp->ptn_bridge = of_drm_find_bridge(bridge_node);
 			of_node_put(bridge_node);
-			if (!dp->bridge)
+			if (!dp->ptn_bridge)
 				return -EPROBE_DEFER;
 		} else {
 			return -EPROBE_DEFER;
@@ -1374,7 +1424,7 @@ static int exynos_dp_suspend(struct device *dev)
 {
 	struct exynos_dp_device *dp = dev_get_drvdata(dev);
 
-	exynos_dp_dpms(&dp->display, DRM_MODE_DPMS_OFF);
+	exynos_dp_bridge_disable(dp->bridge);
 	return 0;
 }
 
@@ -1382,7 +1432,7 @@ static int exynos_dp_resume(struct device *dev)
 {
 	struct exynos_dp_device *dp = dev_get_drvdata(dev);
 
-	exynos_dp_dpms(&dp->display, DRM_MODE_DPMS_ON);
+	exynos_dp_bridge_enable(dp->bridge);
 	return 0;
 }
 #endif
diff --git a/drivers/gpu/drm/exynos/exynos_dp_core.h b/drivers/gpu/drm/exynos/exynos_dp_core.h
index c321ad5..29bd56e 100644
--- a/drivers/gpu/drm/exynos/exynos_dp_core.h
+++ b/drivers/gpu/drm/exynos/exynos_dp_core.h
@@ -154,6 +154,7 @@ struct exynos_dp_device {
 	struct drm_encoder	*encoder;
 	struct drm_panel	*panel;
 	struct drm_bridge	*bridge;
+	struct drm_bridge	*ptn_bridge;
 	struct clk		*clock;
 	unsigned int		irq;
 	void __iomem		*reg_base;
-- 
1.9.1




From robert.richter at caviumnetworks.com  Fri Aug  7 03:43:20 2015
From: robert.richter at caviumnetworks.com (Robert Richter)
Date: Fri, 7 Aug 2015 12:43:20 +0200
Subject: [PATCH 2/2] net, thunder, bgx: Add support for ACPI binding.
In-Reply-To: <55C467A0.4020601@linaro.org>
References: <1438907590-29649-1-git-send-email-ddaney.cavm@gmail.com>
 <1438907590-29649-3-git-send-email-ddaney.cavm@gmail.com>
 <55C467A0.4020601@linaro.org>
Message-ID: <20150807104320.GQ1820@rric.localhost>

On 07.08.15 10:09:04, Tomasz Nowicki wrote:
> On 07.08.2015 02:33, David Daney wrote:

...

> >+#else
> >+
> >+static int bgx_init_acpi_phy(struct bgx *bgx)
> >+{
> >+	return -ENODEV;
> >+}
> >+
> >+#endif /* CONFIG_ACPI */
> >+
> >  #if IS_ENABLED(CONFIG_OF_MDIO)
> >
> >  static int bgx_init_of_phy(struct bgx *bgx)
> >@@ -882,7 +1010,12 @@ static int bgx_init_of_phy(struct bgx *bgx)
> >
> >  static int bgx_init_phy(struct bgx *bgx)
> >  {
> >-	return bgx_init_of_phy(bgx);
> >+	int err = bgx_init_of_phy(bgx);
> >+
> >+	if (err != -ENODEV)
> >+		return err;
> >+
> >+	return bgx_init_acpi_phy(bgx);
> >  }
> >
> 
> If kernel can work with DT and ACPI (both compiled in), it should take only
> one path instead of probing DT and ACPI sequentially. How about:
> 
> @@ -902,10 +925,9 @@ static int bgx_probe(struct pci_dev *pdev, const struct
> pci_device_id *ent)
>  	bgx_vnic[bgx->bgx_id] = bgx;
>  	bgx_get_qlm_mode(bgx);
> 
> -	snprintf(bgx_sel, 5, "bgx%d", bgx->bgx_id);
> -	np = of_find_node_by_name(NULL, bgx_sel);
> -	if (np)
> -		bgx_init_of(bgx, np);
> +	err = acpi_disabled ? bgx_init_of_phy(bgx) : bgx_init_acpi_phy(bgx);
> +	if (err)
> +		goto err_enable;
> 
>  	bgx_init_hw(bgx);

I would not pollute bgx_probe() with acpi and dt specifics, and instead
keep bgx_init_phy(). The typical design pattern for this is:

static int bgx_init_phy(struct bgx *bgx)
{
#ifdef CONFIG_ACPI
        if (!acpi_disabled)
                return bgx_init_acpi_phy(bgx);
#endif
        return bgx_init_of_phy(bgx);
}

This adds acpi runtime detection (acpi=no), does not call dt code in
case of acpi, and saves the #else for bgx_init_acpi_phy().

-Robert


From ykk at rock-chips.com  Fri Aug  7 03:46:20 2015
From: ykk at rock-chips.com (Yakir Yang)
Date: Fri,  7 Aug 2015 05:46:20 -0500
Subject: [PATCH v2 4/8] drm: rockchip/dp: add rockchip platform dp driver
In-Reply-To: <1438943674-18191-1-git-send-email-ykk@rock-chips.com>
References: <1438943674-18191-1-git-send-email-ykk@rock-chips.com>
Message-ID: <1438944380-18897-1-git-send-email-ykk@rock-chips.com>

Rockchip have three clocks for dp controller, we leave pclk_edp
to analogix_dp driver control, and keep the sclk_edp_24m and
sclk_edp in platform driver.

Signed-off-by: Yakir Yang <ykk at rock-chips.com>
---
Changes in v2: None

 drivers/gpu/drm/rockchip/Kconfig                |  10 +
 drivers/gpu/drm/rockchip/Makefile               |   1 +
 drivers/gpu/drm/rockchip/analogix_dp-rockchip.c | 419 ++++++++++++++++++++++++
 3 files changed, 430 insertions(+)
 create mode 100644 drivers/gpu/drm/rockchip/analogix_dp-rockchip.c

diff --git a/drivers/gpu/drm/rockchip/Kconfig b/drivers/gpu/drm/rockchip/Kconfig
index 35215f6..096ed77 100644
--- a/drivers/gpu/drm/rockchip/Kconfig
+++ b/drivers/gpu/drm/rockchip/Kconfig
@@ -25,3 +25,13 @@ config ROCKCHIP_DW_HDMI
 	  for the Synopsys DesignWare HDMI driver. If you want to
 	  enable HDMI on RK3288 based SoC, you should selet this
 	  option.
+
+
+config ROCKCHIP_ANALOGIX_DP
+        tristate "Rockchip specific extensions for Analogix DP driver"
+        depends on DRM_ROCKCHIP
+        select DRM_ANALOGIX_DP
+        help
+	  This selects support for Rockchip SoC specific extensions
+	  for the Analogix Core DP driver. If you want to enable DP
+	  on RK3288 based SoC, you should selet this option.
diff --git a/drivers/gpu/drm/rockchip/Makefile b/drivers/gpu/drm/rockchip/Makefile
index f3d8a19..8ad01fb 100644
--- a/drivers/gpu/drm/rockchip/Makefile
+++ b/drivers/gpu/drm/rockchip/Makefile
@@ -6,5 +6,6 @@ rockchipdrm-y := rockchip_drm_drv.o rockchip_drm_fb.o rockchip_drm_fbdev.o \
 		rockchip_drm_gem.o
 
 obj-$(CONFIG_ROCKCHIP_DW_HDMI) += dw_hdmi-rockchip.o
+obj-$(CONFIG_ROCKCHIP_ANALOGIX_DP) += analogix_dp-rockchip.o
 
 obj-$(CONFIG_DRM_ROCKCHIP) += rockchipdrm.o rockchip_drm_vop.o
diff --git a/drivers/gpu/drm/rockchip/analogix_dp-rockchip.c b/drivers/gpu/drm/rockchip/analogix_dp-rockchip.c
new file mode 100644
index 0000000..2f86e5e
--- /dev/null
+++ b/drivers/gpu/drm/rockchip/analogix_dp-rockchip.c
@@ -0,0 +1,419 @@
+/*
+ * Rockchip SoC DP (Display Port) interface driver.
+ *
+ * Copyright (C) Fuzhou Rockchip Electronics Co., Ltd.
+ * Author: Andy Yan <andy.yan at rock-chips.com>
+ *         Yakir Yang <ykk at rock-chips.com>
+ *         Jeff Chen <jeff.chen at 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.
+ */
+#include <drm/drmP.h>
+#include <drm/drm_crtc_helper.h>
+#include <drm/drm_panel.h>
+#include <drm/drm_of.h>
+#include <drm/drm_dp_helper.h>
+
+#include <linux/component.h>
+#include <linux/clk.h>
+#include <linux/mfd/syscon.h>
+#include <linux/regmap.h>
+#include <linux/reset.h>
+
+#include <video/of_videomode.h>
+#include <video/videomode.h>
+
+#include <drm/bridge/analogix_dp.h>
+
+#include "rockchip_drm_drv.h"
+#include "rockchip_drm_vop.h"
+
+#define encoder_to_dp(c) \
+		container_of(c, struct rockchip_dp_device, encoder)
+
+#define plat_data_to_dp(pd) \
+		container_of(pd, struct rockchip_dp_device, plat_data)
+
+/* dp grf register offset */
+#define DP_VOP_SEL                              0x025c /* grf_soc_con6 */
+#define DP_REF_CLK_SEL                          0x0274 /* grf_soc_con12 */
+
+#define GRF_DP_REF_CLK_SEL_INTER                BIT(4)
+#define DP_SEL_VOP_LIT				BIT(5)
+
+struct rockchip_dp_device {
+	struct drm_device        *drm_dev;
+	struct device            *dev;
+	struct drm_encoder       encoder;
+	struct drm_display_mode  mode;
+
+	struct clk               *clk_dp;
+	struct clk               *clk_24m_parent;
+	struct clk               *clk_24m;
+	struct regmap            *grf;
+	struct reset_control     *rst;
+
+	struct analogix_dp_plat_data plat_data;
+};
+
+static int rockchip_dp_clk_enable(struct rockchip_dp_device *dp)
+{
+	int ret = 0;
+
+	ret = clk_prepare_enable(dp->clk_dp);
+	if (ret < 0) {
+		dev_err(dp->dev, "cannot enable clk_dp %d\n", ret);
+		goto err_clk_dp;
+	}
+
+	ret = clk_set_rate(dp->clk_24m, 24000000);
+	if (ret < 0) {
+		dev_err(dp->dev, "cannot set dp clk_24m %d\n",
+			ret);
+		goto err_clk_24m;
+	}
+
+	ret = clk_prepare_enable(dp->clk_24m);
+	if (ret < 0) {
+		dev_err(dp->dev, "cannot enable dp clk_24m %d\n",
+			ret);
+		goto err_clk_24m;
+	}
+
+	return 0;
+
+err_clk_24m:
+	clk_disable_unprepare(dp->clk_dp);
+err_clk_dp:
+	return ret;
+}
+
+static int rockchip_dp_clk_disable(struct rockchip_dp_device *dp)
+{
+	clk_disable_unprepare(dp->clk_dp);
+	clk_disable_unprepare(dp->clk_24m);
+
+	return 0;
+}
+
+static int rockchip_dp_pre_init(struct rockchip_dp_device *dp)
+{
+	u32 val;
+	int ret;
+
+	val = GRF_DP_REF_CLK_SEL_INTER | (GRF_DP_REF_CLK_SEL_INTER << 16);
+	ret = regmap_write(dp->grf, DP_REF_CLK_SEL, val);
+	if (ret != 0) {
+		dev_err(dp->dev, "Could not write to GRF: %d\n", ret);
+		return ret;
+	}
+
+	reset_control_assert(dp->rst);
+	usleep_range(10, 20);
+	reset_control_deassert(dp->rst);
+
+	return 0;
+}
+
+static int rockchip_dp_poweron(struct analogix_dp_plat_data *plat_data)
+{
+	struct rockchip_dp_device *dp = plat_data_to_dp(plat_data);
+	int ret;
+
+	ret = rockchip_dp_clk_enable(dp);
+	if (ret < 0) {
+		dev_err(dp->dev, "cannot enable dp clk %d\n", ret);
+		return -1;
+	}
+
+	ret = rockchip_dp_pre_init(dp);
+	if (ret < 0) {
+		dev_err(dp->dev, "dp pre init fail %d\n", ret);
+		return -1;
+	}
+
+	return 0;
+}
+
+static int rockchip_dp_poweroff(struct analogix_dp_plat_data *plat_data)
+{
+	struct rockchip_dp_device *dp = plat_data_to_dp(plat_data);
+
+	rockchip_dp_clk_disable(dp);
+
+	return 0;
+}
+
+static bool
+rockchip_dp_drm_encoder_mode_fixup(struct drm_encoder *encoder,
+				   const struct drm_display_mode *mode,
+				   struct drm_display_mode *adjusted_mode)
+{
+	/* do nothing */
+	return true;
+}
+
+static void rockchip_dp_drm_encoder_mode_set(struct drm_encoder *encoder,
+					     struct drm_display_mode *mode,
+					     struct drm_display_mode *adjusted)
+{
+	/* do nothing */
+}
+
+static void rockchip_dp_drm_encoder_prepare(struct drm_encoder *encoder)
+{
+	struct rockchip_dp_device *dp = encoder_to_dp(encoder);
+	u32 val;
+	int ret;
+
+	ret = rockchip_drm_crtc_mode_config(encoder->crtc,
+					    DRM_MODE_CONNECTOR_eDP,
+					    ROCKCHIP_OUT_MODE_AAAA);
+	if (ret < 0) {
+		dev_err(dp->dev, "Could not set crtc mode config: %d.\n", ret);
+		return;
+	}
+
+	ret = rockchip_drm_encoder_get_mux_id(dp->dev->of_node, encoder);
+	if (ret < 0)
+		return;
+
+	if (ret)
+		val = DP_SEL_VOP_LIT | (DP_SEL_VOP_LIT << 16);
+	else
+		val = DP_SEL_VOP_LIT << 16;
+
+	dev_info(dp->dev, "vop %s output to dp\n", (ret) ? "LIT" : "BIG");
+
+	ret = regmap_write(dp->grf, DP_VOP_SEL, val);
+	if (ret != 0) {
+		dev_err(dp->dev, "Could not write to GRF: %d\n", ret);
+		return;
+	}
+}
+
+static void rockchip_dp_drm_encoder_nop(struct drm_encoder *encoder)
+{
+	/* do nothing */
+}
+
+static struct drm_encoder_helper_funcs rockchip_dp_encoder_helper_funcs = {
+	.mode_fixup = rockchip_dp_drm_encoder_mode_fixup,
+	.mode_set = rockchip_dp_drm_encoder_mode_set,
+	.prepare = rockchip_dp_drm_encoder_prepare,
+	.commit = rockchip_dp_drm_encoder_nop,
+	.disable = rockchip_dp_drm_encoder_nop,
+};
+
+static void rockchip_dp_drm_encoder_destroy(struct drm_encoder *encoder)
+{
+	drm_encoder_cleanup(encoder);
+}
+
+static struct drm_encoder_funcs rockchip_dp_encoder_funcs = {
+	.destroy = rockchip_dp_drm_encoder_destroy,
+};
+
+static int rockchip_dp_init(struct rockchip_dp_device *dp)
+{
+	struct device *dev = dp->dev;
+	struct device_node *np = dev->of_node;
+	int ret;
+
+	dp->grf = syscon_regmap_lookup_by_phandle(np, "rockchip,grf");
+	if (IS_ERR(dp->grf)) {
+		dev_err(dev,
+			"rk3288-dp needs rockchip,grf property\n");
+		return PTR_ERR(dp->grf);
+	}
+
+	dp->clk_dp = devm_clk_get(dev, "clk_dp");
+	if (IS_ERR(dp->clk_dp)) {
+		dev_err(dev, "cannot get clk_dp\n");
+		return PTR_ERR(dp->clk_dp);
+	}
+
+	dp->clk_24m = devm_clk_get(dev, "clk_dp_24m");
+	if (IS_ERR(dp->clk_24m)) {
+		dev_err(dev, "cannot get clk_dp_24m\n");
+		return PTR_ERR(dp->clk_24m);
+	}
+
+	dp->rst = devm_reset_control_get(dev, "dp");
+	if (IS_ERR(dp->rst)) {
+		dev_err(dev, "failed to get reset\n");
+		return PTR_ERR(dp->rst);
+	}
+
+	ret = rockchip_dp_clk_enable(dp);
+	if (ret < 0) {
+		dev_err(dp->dev, "cannot enable dp clk %d\n", ret);
+		return ret;
+	}
+
+	ret = rockchip_dp_pre_init(dp);
+	if (ret < 0) {
+		dev_err(dp->dev, "failed to pre init %d\n", ret);
+		return ret;
+	}
+
+	return 0;
+}
+
+static int rockchip_dp_drm_create_encoder(struct rockchip_dp_device *dp)
+{
+	struct drm_encoder *encoder = &dp->encoder;
+	struct drm_device *drm_dev = dp->drm_dev;
+	struct device *dev = dp->dev;
+	int ret;
+
+	encoder->possible_crtcs = drm_of_find_possible_crtcs(drm_dev,
+							     dev->of_node);
+	DRM_DEBUG_KMS("possible_crtcs = 0x%x\n", encoder->possible_crtcs);
+
+	ret = drm_encoder_init(drm_dev, encoder, &rockchip_dp_encoder_funcs,
+			       DRM_MODE_ENCODER_TMDS);
+	if (ret) {
+		DRM_ERROR("failed to initialize encoder with drm\n");
+		return ret;
+	}
+
+	drm_encoder_helper_add(encoder, &rockchip_dp_encoder_helper_funcs);
+
+	return 0;
+}
+
+static int rockchip_dp_bind(struct device *dev, struct device *master,
+			    void *data)
+{
+	struct rockchip_dp_device *dp = dev_get_drvdata(dev);
+	struct drm_device *drm_dev = data;
+	int ret;
+
+	/*
+	 * Just like the probe function said, we don't need the
+	 * device drvrate anymore, we should leave the charge to
+	 * analogix dp driver, set the device drvdata to NULL.
+	 */
+	dev_set_drvdata(dev, NULL);
+
+	ret = rockchip_dp_init(dp);
+	if (ret < 0)
+		return ret;
+
+	dp->drm_dev = drm_dev;
+
+	ret = rockchip_dp_drm_create_encoder(dp);
+	if (ret) {
+		DRM_ERROR("failed to create drm encoder\n");
+		return ret;
+	}
+
+	dp->plat_data.attach = NULL;
+	dp->plat_data.power_on = rockchip_dp_poweron;
+	dp->plat_data.power_off = rockchip_dp_poweroff;
+
+	return analogix_dp_bind(dev, dp->drm_dev, &dp->encoder,
+				&dp->plat_data);
+}
+
+static void rockchip_dp_unbind(struct device *dev, struct device *master,
+			       void *data)
+{
+	return analogix_dp_unbind(dev, master, data);
+}
+
+static const struct component_ops rockchip_dp_component_ops = {
+	.bind = rockchip_dp_bind,
+	.unbind = rockchip_dp_unbind,
+};
+
+static int rockchip_dp_probe(struct platform_device *pdev)
+{
+	struct device *dev = &pdev->dev;
+	struct device_node *panel_node;
+	struct rockchip_dp_device *dp;
+	struct drm_panel *panel;
+
+	panel_node = of_parse_phandle(dev->of_node, "rockchip,panel", 0);
+	if (!panel_node) {
+		DRM_ERROR("failed to find rockchip,panel dt node\n");
+		return -ENODEV;
+	}
+
+	panel = of_drm_find_panel(panel_node);
+	if (!panel) {
+		DRM_ERROR("failed to find panel\n");
+		of_node_put(panel_node);
+		return -EPROBE_DEFER;
+	}
+
+	of_node_put(panel_node);
+
+	dp = devm_kzalloc(dev, sizeof(*dp), GFP_KERNEL);
+	if (!dp)
+		return -ENOMEM;
+
+	dp->dev = dev;
+
+	dp->plat_data.panel = panel;
+
+	/*
+	 * We just use the drvdata until driver run into component
+	 * add function, and then we would set drvdata to null, so
+	 * that analogix dp driver could take charge of the drvdata.
+	 */
+	platform_set_drvdata(pdev, dp);
+
+	return component_add(dev, &rockchip_dp_component_ops);
+}
+
+static int rockchip_dp_remove(struct platform_device *pdev)
+{
+	component_del(&pdev->dev, &rockchip_dp_component_ops);
+
+	return 0;
+}
+
+#ifdef CONFIG_PM_SLEEP
+static int rockchip_dp_suspend(struct device *dev)
+{
+	return analogix_dp_suspend(dev);
+}
+
+static int rockchip_dp_resume(struct device *dev)
+{
+	return analogix_dp_resume(dev);
+}
+#endif
+
+static const struct dev_pm_ops rockchip_dp_pm_ops = {
+	SET_SYSTEM_SLEEP_PM_OPS(rockchip_dp_suspend, rockchip_dp_resume)
+};
+
+static const struct of_device_id rockchip_dp_dt_ids[] = {
+	{.compatible = "rockchip,rk3288-dp",},
+	{}
+};
+MODULE_DEVICE_TABLE(of, rockchip_dp_dt_ids);
+
+static struct platform_driver rockchip_dp_driver = {
+	.probe = rockchip_dp_probe,
+	.remove = rockchip_dp_remove,
+	.driver = {
+		   .name = "rockchip-dp",
+		   .owner = THIS_MODULE,
+		   .pm = &rockchip_dp_pm_ops,
+		   .of_match_table = of_match_ptr(rockchip_dp_dt_ids),
+	},
+};
+
+module_platform_driver(rockchip_dp_driver);
+
+MODULE_AUTHOR("Yakir Yang <ykk at rock-chips.com>");
+MODULE_AUTHOR("Jeff chen <jeff.chen at rock-chips.com>");
+MODULE_DESCRIPTION("Rockchip Specific Analogix-DP Driver Extension");
+MODULE_LICENSE("GPL v2");
-- 
1.9.1




From ykk at rock-chips.com  Fri Aug  7 03:46:35 2015
From: ykk at rock-chips.com (Yakir Yang)
Date: Fri,  7 Aug 2015 05:46:35 -0500
Subject: [PATCH v2 5/8] drm: bridge/analogix_dp: add platform device type
 support
In-Reply-To: <1438943674-18191-1-git-send-email-ykk@rock-chips.com>
References: <1438943674-18191-1-git-send-email-ykk@rock-chips.com>
Message-ID: <1438944396-18951-1-git-send-email-ykk@rock-chips.com>

Signed-off-by: Yakir Yang <ykk at rock-chips.com>
---
Changes in v2:
- Add GNU license v2 declared and samsung copyright

 drivers/gpu/drm/exynos/analogix_dp-exynos.c     |  1 +
 drivers/gpu/drm/rockchip/analogix_dp-rockchip.c |  1 +
 include/drm/bridge/analogix_dp.h                | 16 ++++++++++++++++
 3 files changed, 18 insertions(+)

diff --git a/drivers/gpu/drm/exynos/analogix_dp-exynos.c b/drivers/gpu/drm/exynos/analogix_dp-exynos.c
index 1468ce7..5a2027d 100644
--- a/drivers/gpu/drm/exynos/analogix_dp-exynos.c
+++ b/drivers/gpu/drm/exynos/analogix_dp-exynos.c
@@ -122,6 +122,7 @@ static int exynos_dp_bind(struct device *dev, struct device *master, void *data)
 	dp->dev = dev;
 	dp->drm_dev = drm_dev;
 
+	dp->plat_data.dev_type = EXYNOS_DP;
 	dp->plat_data.power_on = exynos_dp_poweron;
 	dp->plat_data.power_off = exynos_dp_poweroff;
 	dp->plat_data.attach = exynos_dp_bridge_attach;
diff --git a/drivers/gpu/drm/rockchip/analogix_dp-rockchip.c b/drivers/gpu/drm/rockchip/analogix_dp-rockchip.c
index 2f86e5e..e7cf9ab 100644
--- a/drivers/gpu/drm/rockchip/analogix_dp-rockchip.c
+++ b/drivers/gpu/drm/rockchip/analogix_dp-rockchip.c
@@ -312,6 +312,7 @@ static int rockchip_dp_bind(struct device *dev, struct device *master,
 		return ret;
 	}
 
+	dp->plat_data.dev_type = RK3288_DP;
 	dp->plat_data.attach = NULL;
 	dp->plat_data.power_on = rockchip_dp_poweron;
 	dp->plat_data.power_off = rockchip_dp_poweroff;
diff --git a/include/drm/bridge/analogix_dp.h b/include/drm/bridge/analogix_dp.h
index 9a207f8..d5f9a5b 100644
--- a/include/drm/bridge/analogix_dp.h
+++ b/include/drm/bridge/analogix_dp.h
@@ -1,9 +1,25 @@
+/*
+ * Analogix Core DP (Display Port) interface driver.
+ *
+ * Copyright (C) 2012 Samsung Electronics Co., Ltd.
+ *
+ * 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.
+ */
 #ifndef _ANALOGIX_DP_H_
 #define _ANALOGIX_DP_H_
 
 #include <drm/drm_crtc.h>
 
+enum analogix_dp_devtype {
+	EXYNOS_DP,
+	RK3288_DP,
+};
+
 struct analogix_dp_plat_data {
+	enum analogix_dp_devtype dev_type;
 	struct drm_panel *panel;
 
 	int (*power_on)(struct analogix_dp_plat_data *);
-- 
1.9.1




From jbe at pengutronix.de  Fri Aug  7 03:47:03 2015
From: jbe at pengutronix.de (Juergen Borleis)
Date: Fri,  7 Aug 2015 12:47:03 +0200
Subject: [PATCH v4 1/2] serial: mxs-auart: use a function name to reflect what
 it really does
Message-ID: <1438944424-9053-1-git-send-email-jbe@pengutronix.de>

This function clears the reset the AUART unit is in after system start
to make it work.

Signed-off-by: Juergen Borleis <jbe at pengutronix.de>
---
 drivers/tty/serial/mxs-auart.c | 4 ++--
 1 file changed, 2 insertions(+), 2 deletions(-)

diff --git a/drivers/tty/serial/mxs-auart.c b/drivers/tty/serial/mxs-auart.c
index 13cf773..7dc87a9 100644
--- a/drivers/tty/serial/mxs-auart.c
+++ b/drivers/tty/serial/mxs-auart.c
@@ -842,7 +842,7 @@ static irqreturn_t mxs_auart_irq_handle(int irq, void *context)
 	return IRQ_HANDLED;
 }
 
-static void mxs_auart_reset(struct uart_port *u)
+static void mxs_auart_reset_deassert(struct uart_port *u)
 {
 	int i;
 	unsigned int reg;
@@ -1291,7 +1291,7 @@ static int mxs_auart_probe(struct platform_device *pdev)
 
 	auart_port[s->port.line] = s;
 
-	mxs_auart_reset(&s->port);
+	mxs_auart_reset_deassert(&s->port);
 
 	ret = uart_add_one_port(&auart_driver, &s->port);
 	if (ret)
-- 
2.4.6



From jbe at pengutronix.de  Fri Aug  7 03:47:04 2015
From: jbe at pengutronix.de (Juergen Borleis)
Date: Fri,  7 Aug 2015 12:47:04 +0200
Subject: [PATCH v4 2/2] serial: mxs-auart: keep the AUART unit in reset state
 when not in use
In-Reply-To: <1438944424-9053-1-git-send-email-jbe@pengutronix.de>
References: <1438944424-9053-1-git-send-email-jbe@pengutronix.de>
Message-ID: <1438944424-9053-2-git-send-email-jbe@pengutronix.de>

Whenever the UART device driver gets closed from userland, the driver
disables the UART unit and then stops the clocks to save power.

The bit which disabled the UART unit is described as:

?"UART Enable. If this bit is set to 1, the UART is enabled. Data
  transmission and reception occurs for the UART signals. When the
  UART is disabled in the middle of transmission or reception, it
  completes the current character before stopping."

The important part is the "it completes the current character". Whenever
a reception is ongoing when the UART gets disabled (including the clock
off) the statemachine freezes and "remembers" this state on the next
open() when re-enabling the unit's clock.

In this case we end up receiving an additional bogus character
immediately.

The solution in this change is to switch the AUART unit into its reset
state on close() and only release it from its reset state on the next
open().

Note: when the unit is also used as system console it is always 'in use',
so we cannot reset it on close().

Signed-off-by: Juergen Borleis <jbe at pengutronix.de>
---
 drivers/tty/serial/mxs-auart.c | 46 +++++++++++++++++++++++++++++++++++-------
 1 file changed, 39 insertions(+), 7 deletions(-)

diff --git a/drivers/tty/serial/mxs-auart.c b/drivers/tty/serial/mxs-auart.c
index 7dc87a9..8d1cd15 100644
--- a/drivers/tty/serial/mxs-auart.c
+++ b/drivers/tty/serial/mxs-auart.c
@@ -858,6 +858,30 @@ static void mxs_auart_reset_deassert(struct uart_port *u)
 	writel(AUART_CTRL0_CLKGATE, u->membase + AUART_CTRL0_CLR);
 }
 
+static void mxs_auart_reset_assert(struct uart_port *u)
+{
+	int i;
+	u32 reg;
+
+	reg = readl(u->membase + AUART_CTRL0);
+	/* if already in reset state, keep it untouched */
+	if (reg & AUART_CTRL0_SFTRST)
+		return;
+
+	writel(AUART_CTRL0_CLKGATE, u->membase + AUART_CTRL0_CLR);
+	writel(AUART_CTRL0_SFTRST, u->membase + AUART_CTRL0_SET);
+
+	for (i = 0; i < 1000; i++) {
+		reg = readl(u->membase + AUART_CTRL0);
+		/* reset is finished when the clock is gated */
+		if (reg & AUART_CTRL0_CLKGATE)
+			return;
+		udelay(10);
+	}
+
+	dev_err(u->dev, "Failed to reset the unit.");
+}
+
 static int mxs_auart_startup(struct uart_port *u)
 {
 	int ret;
@@ -867,7 +891,13 @@ static int mxs_auart_startup(struct uart_port *u)
 	if (ret)
 		return ret;
 
-	writel(AUART_CTRL0_CLKGATE, u->membase + AUART_CTRL0_CLR);
+	if (uart_console(u)) {
+		writel(AUART_CTRL0_CLKGATE, u->membase + AUART_CTRL0_CLR);
+	} else {
+		/* reset the unit to a well known state */
+		mxs_auart_reset_assert(u);
+		mxs_auart_reset_deassert(u);
+	}
 
 	writel(AUART_CTRL2_UARTEN, u->membase + AUART_CTRL2_SET);
 
@@ -899,12 +929,14 @@ static void mxs_auart_shutdown(struct uart_port *u)
 	if (auart_dma_enabled(s))
 		mxs_auart_dma_exit(s);
 
-	writel(AUART_CTRL2_UARTEN, u->membase + AUART_CTRL2_CLR);
-
-	writel(AUART_INTR_RXIEN | AUART_INTR_RTIEN | AUART_INTR_CTSMIEN,
-			u->membase + AUART_INTR_CLR);
-
-	writel(AUART_CTRL0_CLKGATE, u->membase + AUART_CTRL0_SET);
+	if (uart_console(u)) {
+		writel(AUART_CTRL2_UARTEN, u->membase + AUART_CTRL2_CLR);
+		writel(AUART_INTR_RXIEN | AUART_INTR_RTIEN | AUART_INTR_CTSMIEN,
+				u->membase + AUART_INTR_CLR);
+		writel(AUART_CTRL0_CLKGATE, u->membase + AUART_CTRL0_SET);
+	} else {
+		mxs_auart_reset_assert(u);
+	}
 
 	clk_disable_unprepare(s->clk);
 }
-- 
2.4.6



From broonie at kernel.org  Fri Aug  7 03:48:03 2015
From: broonie at kernel.org (Mark Brown)
Date: Fri, 7 Aug 2015 11:48:03 +0100
Subject: [PATCH v4 09/10] PCI: ACPI: Bind GIC MSI frame to PCI host bridge
In-Reply-To: <55C4826C.80600@linaro.org>
References: <1438164539-29256-1-git-send-email-hanjun.guo@linaro.org>
 <1438164539-29256-10-git-send-email-hanjun.guo@linaro.org>
 <55C4826C.80600@linaro.org>
Message-ID: <20150807104803.GO20873@sirena.org.uk>

On Fri, Aug 07, 2015 at 12:03:24PM +0200, Tomasz Nowicki wrote:

> >@@ -670,6 +671,8 @@ static struct irq_domain *pci_host_bridge_msi_domain(struct pci_bus *bus)
> >  	 * should be called from here.
> >  	 */
> >  	d = pci_host_bridge_of_msi_domain(bus);
> >+	if (!d)
> >+		d = pci_host_bridge_acpi_msi_domain(bus);
> 
> Please use acpi_disabled here.

> BTW. This is another place where we need to know our firmware - DT vs ACPI.
> I know we can use acpi_disabled but I think more about generic solution.
> Since we already have:
> struct fwnode_handle	*fwnode;
> we can create macro which identify h/w description style, something like:

> #define FWNODE_TYPE(dev)	dev_fwnode(dev)->type

> and then:

> switch (FWNODE_TYPE(&bus->dev)) {
> case FWNODE_OF:
> ...
> case FWNODE_ACPI:
> ...
> case FWNODE_XXX:
> ...
> }

> Root bus is special case since it has no frimware type but we could factor
> out pci_set_bus_of_node(). For platform devices we have all we need. Just
> thinking aloud, let me know your thoughts.

Not knowing the particular detail here but can we not go a step further
than that and have a fwnode_disabled() for this which does appropriate
things for both ACPI and DT?
-------------- next part --------------
A non-text attachment was scrubbed...
Name: signature.asc
Type: application/pgp-signature
Size: 473 bytes
Desc: Digital signature
URL: <http://lists.infradead.org/pipermail/linux-arm-kernel/attachments/20150807/f5c2fece/attachment.sig>

From yingjoe.chen at mediatek.com  Fri Aug  7 03:50:18 2015
From: yingjoe.chen at mediatek.com (Yingjoe Chen)
Date: Fri, 7 Aug 2015 18:50:18 +0800
Subject: [PATCH v3 0/5] Add SMP bringup support for mt65xx socs
In-Reply-To: <20150805223115.GD7557@n2100.arm.linux.org.uk>
References: <1436851111-2369-1-git-send-email-yingjoe.chen@mediatek.com>
 <4831607.pyCH8elj8i@ubix> <20150805223115.GD7557@n2100.arm.linux.org.uk>
Message-ID: <1438944618.14580.5.camel@mtksdaap41>

On Wed, 2015-08-05 at 23:31 +0100, Russell King - ARM Linux wrote:
> On Wed, Aug 05, 2015 at 08:44:11PM +0200, Matthias Brugger wrote:
> > On Tuesday, July 14, 2015 01:18:26 PM Yingjoe Chen wrote:
> > > This series add SMP brinup support for MediaTek SoCs. This is based
> > > on v4.2-rc1 and Matthias' next branch (for dts parts).
<...>

> > Applied to v4.2-next/soc-2 and v4.2-next/dts-2 
> 
> I've just NAK'd one of the patches in this set; I don't tend to even see
> mediatek patches normally, as they all head into my junk mailfolder
> because mediatek's mail server setup is truely abysmal (it has broken
> reverse DNS - the DNS positively says that the mail server is not a
> legit owner of the name it claims to be.)

Hi Russell,

Hope you see this.

Thanks for your review. I already pass this information to our IT, hope
they can resolve this soon.


> The problem is that this patch series uses memblock_reserve() way after
> the memory has been transitioned out of memblock's control, so actually
> this has no effect.
> 
> I've seen a number of patches doing this.  I'm not sure what's soo friggin
> hard for people to understand: memblock is about the EARLY stages of
> getting the system up and running.  Once the memory has been handed
> over to the kernel's memory management, memblock MUST NOT BE USED to
> reserve memory.
> 
> There is one place, and one place only in the ARM kernel where
> memblock_reserve() is possible, and that's in the ->reserve machine
> callback.  NOWHERE ELSE is permissible.


It seems we can write memory-reserve node in device tree to do this as
well. Do you prefer us to reserve memblock in reserve callback or using
device tree?

Joe.C




From p.fedin at samsung.com  Fri Aug  7 03:50:45 2015
From: p.fedin at samsung.com (Pavel Fedin)
Date: Fri, 07 Aug 2015 13:50:45 +0300
Subject: [PATCH v2 TRIVIAL] Enable GICv2m on ARM virt machine
Message-ID: <00fa01d0d0fe$ea19e2e0$be4da8a0$@samsung.com>

qemu implementation of "virt" includes GICv2m. This commit allows to use
it also on ARM32 architecture.

msi.h is added because it is required by linux/msi.h
if CONFIG_GENERIC_MSI_IRQ_DOMAIN is defined. It gets enabled by the
following KConfig dependency chain:
ARM_GIC_V2M => PCI_MSI_IRQ_DOMAIN => GENERIC_MSI_IRQ_DOMAIN

Signed-off-by: Pavel Fedin <p.fedin at samsung.com>
---
v1 => v2:
Added verbose explanation in commit message
---
 arch/arm/Kconfig            | 1 +
 arch/arm/include/asm/Kbuild | 1 +
 2 files changed, 2 insertions(+)

diff --git a/arch/arm/Kconfig b/arch/arm/Kconfig
index 45df48b..1091025 100644
--- a/arch/arm/Kconfig
+++ b/arch/arm/Kconfig
@@ -815,6 +815,7 @@ config ARCH_VIRT
 	bool "Dummy Virtual Machine" if ARCH_MULTI_V7
 	select ARM_AMBA
 	select ARM_GIC
+	select ARM_GIC_V2M if PCI_MSI
 	select ARM_PSCI
 	select HAVE_ARM_ARCH_TIMER
 
diff --git a/arch/arm/include/asm/Kbuild b/arch/arm/include/asm/Kbuild
index 3c4596d..01806f5 100644
--- a/arch/arm/include/asm/Kbuild
+++ b/arch/arm/include/asm/Kbuild
@@ -14,6 +14,7 @@ generic-y += local.h
 generic-y += local64.h
 generic-y += mcs_spinlock.h
 generic-y += msgbuf.h
+generic-y += msi.h
 generic-y += param.h
 generic-y += parport.h
 generic-y += poll.h
-- 
1.9.5.msysgit.0



_______________________________________________
linux-arm-kernel mailing list
linux-arm-kernel at lists.infradead.org
http://lists.infradead.org/mailman/listinfo/linux-arm-kernel



From ykk at rock-chips.com  Fri Aug  7 03:49:24 2015
From: ykk at rock-chips.com (Yakir Yang)
Date: Fri,  7 Aug 2015 05:49:24 -0500
Subject: [PATCH v2 6/8] drm: bridge: analogix_dp: add some rk3288 special
 registers setting
In-Reply-To: <1438943674-18191-1-git-send-email-ykk@rock-chips.com>
References: <1438943674-18191-1-git-send-email-ykk@rock-chips.com>
Message-ID: <1438944564-19010-1-git-send-email-ykk@rock-chips.com>

RK3288 need some special registers setting, we can separate
them out by the dev_type of plat_data.

Signed-off-by: Yakir Yang <ykk at rock-chips.com>
---
Changes in v2:
- Fix compile failed dut to phy_pd_addr variable misspell error

 drivers/gpu/drm/bridge/analogix_dp_reg.c | 76 ++++++++++++++++++++------------
 drivers/gpu/drm/bridge/analogix_dp_reg.h | 12 +++++
 2 files changed, 60 insertions(+), 28 deletions(-)

diff --git a/drivers/gpu/drm/bridge/analogix_dp_reg.c b/drivers/gpu/drm/bridge/analogix_dp_reg.c
index cc5cdbf..a0fc1fb 100644
--- a/drivers/gpu/drm/bridge/analogix_dp_reg.c
+++ b/drivers/gpu/drm/bridge/analogix_dp_reg.c
@@ -15,6 +15,8 @@
 #include <linux/delay.h>
 #include <linux/gpio.h>
 
+#include <drm/bridge/analogix_dp.h>
+
 #include "analogix_dp_core.h"
 #include "analogix_dp_reg.h"
 
@@ -72,6 +74,14 @@ void analogix_dp_init_analog_param(struct analogix_dp_device *dp)
 	reg = SEL_24M | TX_DVDD_BIT_1_0625V;
 	writel(reg, dp->reg_base + ANALOGIX_DP_ANALOG_CTL_2);
 
+	if (dp->plat_data && (dp->plat_data->dev_type == RK3288_DP)) {
+		writel(REF_CLK_24M, dp->reg_base + ANALOGIX_DP_PLL_REG_1);
+		writel(0x95, dp->reg_base + ANALOGIX_DP_PLL_REG_2);
+		writel(0x40, dp->reg_base + ANALOGIX_DP_PLL_REG_3);
+		writel(0x58, dp->reg_base + ANALOGIX_DP_PLL_REG_4);
+		writel(0x22, dp->reg_base + ANALOGIX_DP_PLL_REG_5);
+	}
+
 	reg = DRIVE_DVDD_BIT_1_0625V | VCO_BIT_600_MICRO;
 	writel(reg, dp->reg_base + ANALOGIX_DP_ANALOG_CTL_3);
 
@@ -206,81 +216,85 @@ void analogix_dp_set_analog_power_down(struct analogix_dp_device *dp,
 				       bool enable)
 {
 	u32 reg;
+	u32 phy_pd_addr = ANALOGIX_DP_PHY_PD;
+
+	if (dp->plat_data && (dp->plat_data->dev_type == RK3288_DP))
+		phy_pd_addr = ANALOGIX_DP_PD;
 
 	switch (block) {
 	case AUX_BLOCK:
 		if (enable) {
-			reg = readl(dp->reg_base + ANALOGIX_DP_PHY_PD);
+			reg = readl(dp->reg_base + phy_pd_addr);
 			reg |= AUX_PD;
-			writel(reg, dp->reg_base + ANALOGIX_DP_PHY_PD);
+			writel(reg, dp->reg_base + phy_pd_addr);
 		} else {
-			reg = readl(dp->reg_base + ANALOGIX_DP_PHY_PD);
+			reg = readl(dp->reg_base + phy_pd_addr);
 			reg &= ~AUX_PD;
-			writel(reg, dp->reg_base + ANALOGIX_DP_PHY_PD);
+			writel(reg, dp->reg_base + phy_pd_addr);
 		}
 		break;
 	case CH0_BLOCK:
 		if (enable) {
-			reg = readl(dp->reg_base + ANALOGIX_DP_PHY_PD);
+			reg = readl(dp->reg_base + phy_pd_addr);
 			reg |= CH0_PD;
-			writel(reg, dp->reg_base + ANALOGIX_DP_PHY_PD);
+			writel(reg, dp->reg_base + phy_pd_addr);
 		} else {
-			reg = readl(dp->reg_base + ANALOGIX_DP_PHY_PD);
+			reg = readl(dp->reg_base + phy_pd_addr);
 			reg &= ~CH0_PD;
-			writel(reg, dp->reg_base + ANALOGIX_DP_PHY_PD);
+			writel(reg, dp->reg_base + phy_pd_addr);
 		}
 		break;
 	case CH1_BLOCK:
 		if (enable) {
-			reg = readl(dp->reg_base + ANALOGIX_DP_PHY_PD);
+			reg = readl(dp->reg_base + phy_pd_addr);
 			reg |= CH1_PD;
-			writel(reg, dp->reg_base + ANALOGIX_DP_PHY_PD);
+			writel(reg, dp->reg_base + phy_pd_addr);
 		} else {
-			reg = readl(dp->reg_base + ANALOGIX_DP_PHY_PD);
+			reg = readl(dp->reg_base + phy_pd_addr);
 			reg &= ~CH1_PD;
-			writel(reg, dp->reg_base + ANALOGIX_DP_PHY_PD);
+			writel(reg, dp->reg_base + phy_pd_addr);
 		}
 		break;
 	case CH2_BLOCK:
 		if (enable) {
-			reg = readl(dp->reg_base + ANALOGIX_DP_PHY_PD);
+			reg = readl(dp->reg_base + phy_pd_addr);
 			reg |= CH2_PD;
-			writel(reg, dp->reg_base + ANALOGIX_DP_PHY_PD);
+			writel(reg, dp->reg_base + phy_pd_addr);
 		} else {
-			reg = readl(dp->reg_base + ANALOGIX_DP_PHY_PD);
+			reg = readl(dp->reg_base + phy_pd_addr);
 			reg &= ~CH2_PD;
-			writel(reg, dp->reg_base + ANALOGIX_DP_PHY_PD);
+			writel(reg, dp->reg_base + phy_pd_addr);
 		}
 		break;
 	case CH3_BLOCK:
 		if (enable) {
-			reg = readl(dp->reg_base + ANALOGIX_DP_PHY_PD);
+			reg = readl(dp->reg_base + phy_pd_addr);
 			reg |= CH3_PD;
-			writel(reg, dp->reg_base + ANALOGIX_DP_PHY_PD);
+			writel(reg, dp->reg_base + phy_pd_addr);
 		} else {
-			reg = readl(dp->reg_base + ANALOGIX_DP_PHY_PD);
+			reg = readl(dp->reg_base + phy_pd_addr);
 			reg &= ~CH3_PD;
-			writel(reg, dp->reg_base + ANALOGIX_DP_PHY_PD);
+			writel(reg, dp->reg_base + phy_pd_addr);
 		}
 		break;
 	case ANALOG_TOTAL:
 		if (enable) {
-			reg = readl(dp->reg_base + ANALOGIX_DP_PHY_PD);
+			reg = readl(dp->reg_base + phy_pd_addr);
 			reg |= DP_PHY_PD;
-			writel(reg, dp->reg_base + ANALOGIX_DP_PHY_PD);
+			writel(reg, dp->reg_base + phy_pd_addr);
 		} else {
-			reg = readl(dp->reg_base + ANALOGIX_DP_PHY_PD);
+			reg = readl(dp->reg_base + phy_pd_addr);
 			reg &= ~DP_PHY_PD;
-			writel(reg, dp->reg_base + ANALOGIX_DP_PHY_PD);
+			writel(reg, dp->reg_base + phy_pd_addr);
 		}
 		break;
 	case POWER_ALL:
 		if (enable) {
 			reg = DP_PHY_PD | AUX_PD | CH3_PD | CH2_PD |
 				CH1_PD | CH0_PD;
-			writel(reg, dp->reg_base + ANALOGIX_DP_PHY_PD);
+			writel(reg, dp->reg_base + phy_pd_addr);
 		} else {
-			writel(0x00, dp->reg_base + ANALOGIX_DP_PHY_PD);
+			writel(0x00, dp->reg_base + phy_pd_addr);
 		}
 		break;
 	default:
@@ -399,8 +413,14 @@ void analogix_dp_init_aux(struct analogix_dp_device *dp)
 	analogix_dp_reset_aux(dp);
 
 	/* Disable AUX transaction H/W retry */
-	reg = AUX_BIT_PERIOD_EXPECTED_DELAY(3) | AUX_HW_RETRY_COUNT_SEL(0) |
-	      AUX_HW_RETRY_INTERVAL_600_MICROSECONDS;
+	if (dp->plat_data && (dp->plat_data->dev_type == RK3288_DP))
+		reg = AUX_BIT_PERIOD_EXPECTED_DELAY(0) |
+		      AUX_HW_RETRY_COUNT_SEL(3) |
+		      AUX_HW_RETRY_INTERVAL_600_MICROSECONDS;
+	else
+		reg = AUX_BIT_PERIOD_EXPECTED_DELAY(3) |
+		      AUX_HW_RETRY_COUNT_SEL(0) |
+		      AUX_HW_RETRY_INTERVAL_600_MICROSECONDS;
 	writel(reg, dp->reg_base + ANALOGIX_DP_AUX_HW_RETRY_CTL);
 
 	/* Receive AUX Channel DEFER commands equal to DEFFER_COUNT*64 */
diff --git a/drivers/gpu/drm/bridge/analogix_dp_reg.h b/drivers/gpu/drm/bridge/analogix_dp_reg.h
index bed226f..e38af21 100644
--- a/drivers/gpu/drm/bridge/analogix_dp_reg.h
+++ b/drivers/gpu/drm/bridge/analogix_dp_reg.h
@@ -22,6 +22,14 @@
 #define ANALOGIX_DP_VIDEO_CTL_8			0x3C
 #define ANALOGIX_DP_VIDEO_CTL_10			0x44
 
+#define ANALOGIX_DP_PLL_REG_1			0xfc
+#define ANALOGIX_DP_PLL_REG_2			0x9e4
+#define ANALOGIX_DP_PLL_REG_3			0x9e8
+#define ANALOGIX_DP_PLL_REG_4			0x9ec
+#define ANALOGIX_DP_PLL_REG_5			0xa00
+
+#define ANALOGIX_DP_PD                          0x12c
+
 #define ANALOGIX_DP_LANE_MAP			0x35C
 
 #define ANALOGIX_DP_ANALOG_CTL_1			0x370
@@ -154,6 +162,10 @@
 #define VSYNC_POLARITY_CFG			(0x1 << 1)
 #define HSYNC_POLARITY_CFG			(0x1 << 0)
 
+/* ANALOGIX_DP_PLL_REG_1 */
+#define REF_CLK_24M				(0x1 << 1)
+#define REF_CLK_27M				(0x0 << 1)
+
 /* ANALOGIX_DP_LANE_MAP */
 #define LANE3_MAP_LOGIC_LANE_0			(0x0 << 6)
 #define LANE3_MAP_LOGIC_LANE_1			(0x1 << 6)
-- 
1.9.1




From tomasz.nowicki at linaro.org  Fri Aug  7 03:52:41 2015
From: tomasz.nowicki at linaro.org (Tomasz Nowicki)
Date: Fri, 07 Aug 2015 12:52:41 +0200
Subject: [PATCH 2/2] net, thunder, bgx: Add support for ACPI binding.
In-Reply-To: <20150807104320.GQ1820@rric.localhost>
References: <1438907590-29649-1-git-send-email-ddaney.cavm@gmail.com>
 <1438907590-29649-3-git-send-email-ddaney.cavm@gmail.com>
 <55C467A0.4020601@linaro.org> <20150807104320.GQ1820@rric.localhost>
Message-ID: <55C48DF9.70406@linaro.org>

On 07.08.2015 12:43, Robert Richter wrote:
> On 07.08.15 10:09:04, Tomasz Nowicki wrote:
>> On 07.08.2015 02:33, David Daney wrote:
>
> ...
>
>>> +#else
>>> +
>>> +static int bgx_init_acpi_phy(struct bgx *bgx)
>>> +{
>>> +	return -ENODEV;
>>> +}
>>> +
>>> +#endif /* CONFIG_ACPI */
>>> +
>>>   #if IS_ENABLED(CONFIG_OF_MDIO)
>>>
>>>   static int bgx_init_of_phy(struct bgx *bgx)
>>> @@ -882,7 +1010,12 @@ static int bgx_init_of_phy(struct bgx *bgx)
>>>
>>>   static int bgx_init_phy(struct bgx *bgx)
>>>   {
>>> -	return bgx_init_of_phy(bgx);
>>> +	int err = bgx_init_of_phy(bgx);
>>> +
>>> +	if (err != -ENODEV)
>>> +		return err;
>>> +
>>> +	return bgx_init_acpi_phy(bgx);
>>>   }
>>>
>>
>> If kernel can work with DT and ACPI (both compiled in), it should take only
>> one path instead of probing DT and ACPI sequentially. How about:
>>
>> @@ -902,10 +925,9 @@ static int bgx_probe(struct pci_dev *pdev, const struct
>> pci_device_id *ent)
>>   	bgx_vnic[bgx->bgx_id] = bgx;
>>   	bgx_get_qlm_mode(bgx);
>>
>> -	snprintf(bgx_sel, 5, "bgx%d", bgx->bgx_id);
>> -	np = of_find_node_by_name(NULL, bgx_sel);
>> -	if (np)
>> -		bgx_init_of(bgx, np);
>> +	err = acpi_disabled ? bgx_init_of_phy(bgx) : bgx_init_acpi_phy(bgx);
>> +	if (err)
>> +		goto err_enable;
>>
>>   	bgx_init_hw(bgx);
>
> I would not pollute bgx_probe() with acpi and dt specifics, and instead
> keep bgx_init_phy(). The typical design pattern for this is:
>
> static int bgx_init_phy(struct bgx *bgx)
> {
> #ifdef CONFIG_ACPI
>          if (!acpi_disabled)
>                  return bgx_init_acpi_phy(bgx);
> #endif
>          return bgx_init_of_phy(bgx);
> }
>
> This adds acpi runtime detection (acpi=no), does not call dt code in
> case of acpi, and saves the #else for bgx_init_acpi_phy().
>

I am fine with keeping it in bgx_init_phy(), however we can drop there 
#ifdefs since both of bgx_init_{acpi,of}_phy calls have empty stub for 
!ACPI and !OF case. Like that:

static int bgx_init_phy(struct bgx *bgx)
{

         if (!acpi_disabled)
                 return bgx_init_acpi_phy(bgx);
	else
         	return bgx_init_of_phy(bgx);
}

Tomasz


From ykk at rock-chips.com  Fri Aug  7 03:51:49 2015
From: ykk at rock-chips.com (Yakir Yang)
Date: Fri,  7 Aug 2015 05:51:49 -0500
Subject: [PATCH v2 7/8] drm: bridge: analogix_dp: try force hpd after plug in
 lookup failed
In-Reply-To: <1438943674-18191-1-git-send-email-ykk@rock-chips.com>
References: <1438943674-18191-1-git-send-email-ykk@rock-chips.com>
Message-ID: <1438944709-19091-1-git-send-email-ykk@rock-chips.com>

Some edp screen do not have hpd signal, so we can't just return
failed when hpd plug in detect failed.

Besides TRM indicate that if HPD_STATUS(RO) is 0, AUX CH will not
work, so we need to give a force hpd action to set HPD_STATUS manually.

Signed-off-by: Yakir Yang <ykk at rock-chips.com>
---
Changes in v2: None

 drivers/gpu/drm/bridge/analogix_dp_core.c | 28 +++++++++++++++++++++++-----
 drivers/gpu/drm/bridge/analogix_dp_core.h |  1 +
 drivers/gpu/drm/bridge/analogix_dp_reg.c  |  9 +++++++++
 3 files changed, 33 insertions(+), 5 deletions(-)

diff --git a/drivers/gpu/drm/bridge/analogix_dp_core.c b/drivers/gpu/drm/bridge/analogix_dp_core.c
index 44be01d..efd810c 100644
--- a/drivers/gpu/drm/bridge/analogix_dp_core.c
+++ b/drivers/gpu/drm/bridge/analogix_dp_core.c
@@ -66,15 +66,33 @@ static int analogix_dp_detect_hpd(struct analogix_dp_device *dp)
 {
 	int timeout_loop = 0;
 
-	while (analogix_dp_get_plug_in_status(dp) != 0) {
+	while (timeout_loop < DP_TIMEOUT_LOOP_COUNT) {
+		if (analogix_dp_get_plug_in_status(dp) == 0)
+			return 0;
+
 		timeout_loop++;
-		if (DP_TIMEOUT_LOOP_COUNT < timeout_loop) {
-			dev_err(dp->dev, "failed to get hpd plug status\n");
-			return -ETIMEDOUT;
-		}
 		usleep_range(10, 11);
 	}
 
+	/*
+	 * Some edp screen do not have hpd signal, so we can't just
+	 * return failed when hpd plug in detect failed.
+	 *
+	 * Besides TRM indicate that if HPD_STATUS(RO) is 0, AUX CH
+	 * will not work, so we need to give a force hpd action to
+	 * set HPD_STATUS manually.
+	 */
+	dev_dbg(dp->dev, "failed to get hpd plug status, try to force hpd\n");
+
+	analogix_dp_force_hpd(dp);
+
+	if (analogix_dp_get_plug_in_status(dp) != 0) {
+		dev_err(dp->dev, "failed to get hpd plug in status\n");
+		return -ETIMEDOUT;
+	}
+
+	dev_dbg(dp->dev, "success to get plug in status after force hpd\n");
+
 	return 0;
 }
 
diff --git a/drivers/gpu/drm/bridge/analogix_dp_core.h b/drivers/gpu/drm/bridge/analogix_dp_core.h
index 713c57f..53f3973 100644
--- a/drivers/gpu/drm/bridge/analogix_dp_core.h
+++ b/drivers/gpu/drm/bridge/analogix_dp_core.h
@@ -182,6 +182,7 @@ void analogix_dp_set_analog_power_down(struct analogix_dp_device *dp,
 				       bool enable);
 void analogix_dp_init_analog_func(struct analogix_dp_device *dp);
 void analogix_dp_init_hpd(struct analogix_dp_device *dp);
+void analogix_dp_force_hpd(struct analogix_dp_device *dp);
 enum dp_irq_type analogix_dp_get_irq_type(struct analogix_dp_device *dp);
 void analogix_dp_clear_hotplug_interrupts(struct analogix_dp_device *dp);
 void analogix_dp_reset_aux(struct analogix_dp_device *dp);
diff --git a/drivers/gpu/drm/bridge/analogix_dp_reg.c b/drivers/gpu/drm/bridge/analogix_dp_reg.c
index a0fc1fb..bf7cee1 100644
--- a/drivers/gpu/drm/bridge/analogix_dp_reg.c
+++ b/drivers/gpu/drm/bridge/analogix_dp_reg.c
@@ -365,6 +365,15 @@ void analogix_dp_init_hpd(struct analogix_dp_device *dp)
 	writel(reg, dp->reg_base + ANALOGIX_DP_SYS_CTL_3);
 }
 
+void analogix_dp_force_hpd(struct analogix_dp_device *dp)
+{
+	u32 reg;
+
+	reg = readl(dp->reg_base + ANALOGIX_DP_SYS_CTL_3);
+	reg = (F_HPD | HPD_CTRL);
+	writel(reg, dp->reg_base + ANALOGIX_DP_SYS_CTL_3);
+}
+
 enum dp_irq_type analogix_dp_get_irq_type(struct analogix_dp_device *dp)
 {
 	u32 reg;
-- 
1.9.1




From ykk at rock-chips.com  Fri Aug  7 03:54:04 2015
From: ykk at rock-chips.com (Yakir Yang)
Date: Fri,  7 Aug 2015 05:54:04 -0500
Subject: [PATCH v2 8/8] drm: bridge/analogix_dp: expand the delay time for hpd
 detect
In-Reply-To: <1438943674-18191-1-git-send-email-ykk@rock-chips.com>
References: <1438943674-18191-1-git-send-email-ykk@rock-chips.com>
Message-ID: <1438944844-19243-1-git-send-email-ykk@rock-chips.com>

Some edp screen with no hpd signal would need some delay time
to ensure that screen would be ready for work, so we can expand
the delay time in hpd detect function, it works prefectly on my
rk3288 sdk board.

Signed-off-by: Yakir Yang <ykk at rock-chips.com>
---
Changes in v2: None

 drivers/gpu/drm/bridge/analogix_dp_core.c | 2 +-
 1 file changed, 1 insertion(+), 1 deletion(-)

diff --git a/drivers/gpu/drm/bridge/analogix_dp_core.c b/drivers/gpu/drm/bridge/analogix_dp_core.c
index efd810c..3ba10fa2 100644
--- a/drivers/gpu/drm/bridge/analogix_dp_core.c
+++ b/drivers/gpu/drm/bridge/analogix_dp_core.c
@@ -71,7 +71,7 @@ static int analogix_dp_detect_hpd(struct analogix_dp_device *dp)
 			return 0;
 
 		timeout_loop++;
-		usleep_range(10, 11);
+		usleep_range(100, 110);
 	}
 
 	/*
-- 
1.9.1




From alexandre.belloni at free-electrons.com  Fri Aug  7 03:57:20 2015
From: alexandre.belloni at free-electrons.com (Alexandre Belloni)
Date: Fri,  7 Aug 2015 12:57:20 +0200
Subject: [PATCH] ARM: at91: dt: sama5d2: use slow clock where necessary
Message-ID: <1438945040-11800-1-git-send-email-alexandre.belloni@free-electrons.com>

The watchdog, the reset controller, the RTC, the shutdown controller, the
timer counters and the LCD PWM need the slow clock, add it to the currently
defined nodes.

Signed-off-by: Alexandre Belloni <alexandre.belloni at free-electrons.com>
---
 arch/arm/boot/dts/sama5d2.dtsi | 9 +++++----
 1 file changed, 5 insertions(+), 4 deletions(-)

diff --git a/arch/arm/boot/dts/sama5d2.dtsi b/arch/arm/boot/dts/sama5d2.dtsi
index f39258fa3815..034cd48ae28b 100644
--- a/arch/arm/boot/dts/sama5d2.dtsi
+++ b/arch/arm/boot/dts/sama5d2.dtsi
@@ -764,16 +764,16 @@
 				compatible = "atmel,at91sam9x5-tcb";
 				reg = <0xf800c000 0x100>;
 				interrupts = <35 IRQ_TYPE_LEVEL_HIGH 0>;
-				clocks = <&tcb0_clk>;
-				clock-names = "t0_clk";
+				clocks = <&tcb0_clk>, <&clk32k>;
+				clock-names = "t0_clk", "slow_clk";
 			};
 
 			tcb1: timer at f8010000 {
 				compatible = "atmel,at91sam9x5-tcb";
 				reg = <0xf8010000 0x100>;
 				interrupts = <36 IRQ_TYPE_LEVEL_HIGH 0>;
-				clocks = <&tcb1_clk>;
-				clock-names = "t0_clk";
+				clocks = <&tcb1_clk>, <&clk32k>;
+				clock-names = "t0_clk", "slow_clk";
 			};
 
 			uart0: serial at f801c000 {
@@ -857,6 +857,7 @@
 				compatible = "atmel,at91rm9200-rtc";
 				reg = <0xf80480b0 0x30>;
 				interrupts = <74 IRQ_TYPE_LEVEL_HIGH 7>;
+				clocks = <&clk32k>;
 			};
 
 			spi1: spi at fc000000 {
-- 
2.1.4



From b.zolnierkie at samsung.com  Fri Aug  7 04:12:56 2015
From: b.zolnierkie at samsung.com (Bartlomiej Zolnierkiewicz)
Date: Fri, 07 Aug 2015 13:12:56 +0200
Subject: [PATCH v4 1/6] cpufreq: make scaling_boost_freqs sysfs attr
 available when boost is enabled
In-Reply-To: <20150807104156.GE6939@linux>
References: <1438868514-8814-1-git-send-email-b.zolnierkie@samsung.com>
 <5184469.cOpIkgzX4h@amdc1976> <20150807104156.GE6939@linux>
Message-ID: <1594902.Dv5JKhve0y@amdc1976>

On Friday, August 07, 2015 04:11:56 PM Viresh Kumar wrote:
> On 07-08-15, 12:34, Bartlomiej Zolnierkiewicz wrote:
> > > I would suggest you sending such patches as reply to the earlier
> > > threads only, instead of a new chain. This will save your time.
> > 
> > Please explain it more.  This patch needs to be first for cpufreq-dt
> > switch to be complete.  scaling_boost_freqs is available currently
> > for exynos-cpufreq users when boost is enabled and ideally we would
> > like it to be available immediately after the switch to cpufreq-dt.
> 
> I wasn't talking about the ordering of the patches here, but when to
> send patches.
> 
> So, you now sent these patches again, but what you could have done
> is: only send the first patch in reply to the earlier thread. And ask
> if it looks fine. If yes, resend the whole series properly or keep
> fixing there only..
> 
> That makes things really fast. You don't have to resend the series and
> people wouldn't stay away from it. I stayed away from this series to
> find enough available time to see your 6 patches. Had it been just a
> reply, I would have replied immediately like now.
> 
> Look at how updated versions in the same mail chain in case of OPP
> series..

Please find updated patch below.  It can be moved just before
patch #6 and all patches in the series would still apply fine.

---------------------8<-------------------

>From 993ebb6fc632ec7b61654c9610c90ff4dca4be34 Mon Sep 17 00:00:00 2001
From: Bartlomiej Zolnierkiewicz <b.zolnierkie at samsung.com>
Date: Fri, 7 Aug 2015 13:07:51 +0200
Subject: [PATCH] cpufreq-dt: make scaling_boost_freqs sysfs attr available
 when boost is enabled

Make scaling_boost_freqs sysfs attribute is available when
cpufreq-dt driver is used and boost support is enabled.

Cc: Thomas Abraham <thomas.ab at samsung.com>
Cc: Javier Martinez Canillas <javier at osg.samsung.com>
Cc: Krzysztof Kozlowski <k.kozlowski at samsung.com>
Suggested-by: Viresh Kumar <viresh.kumar at linaro.org>
Signed-off-by: Bartlomiej Zolnierkiewicz <b.zolnierkie at samsung.com>
---
 drivers/cpufreq/cpufreq-dt.c | 11 ++++++++++-
 include/linux/cpufreq.h      |  1 +
 2 files changed, 11 insertions(+), 1 deletion(-)

diff --git a/drivers/cpufreq/cpufreq-dt.c b/drivers/cpufreq/cpufreq-dt.c
index b9259ab..c6a3b98 100644
--- a/drivers/cpufreq/cpufreq-dt.c
+++ b/drivers/cpufreq/cpufreq-dt.c
@@ -36,6 +36,12 @@ struct private_data {
 	unsigned int voltage_tolerance; /* in percentage */
 };
 
+static struct freq_attr *cpufreq_dt_attr[] = {
+	&cpufreq_freq_attr_scaling_available_freqs,
+	NULL,   /* Extra space for boost-attr if required */
+	NULL,
+};
+
 static int set_target(struct cpufreq_policy *policy, unsigned int index)
 {
 	struct dev_pm_opp *opp;
@@ -182,6 +188,8 @@ try_again:
 	return ret;
 }
 
+static struct cpufreq_driver dt_cpufreq_driver;
+
 static int cpufreq_init(struct cpufreq_policy *policy)
 {
 	struct cpufreq_frequency_table *freq_table;
@@ -336,6 +344,7 @@ static int cpufreq_init(struct cpufreq_policy *policy)
 		ret = cpufreq_enable_boost_support();
 		if (ret)
 			goto out_free_cpufreq_table;
+		cpufreq_dt_attr[1] = &cpufreq_freq_attr_scaling_boost_freqs;
 	}
 
 	policy->cpuinfo.transition_latency = transition_latency;
@@ -411,7 +420,7 @@ static struct cpufreq_driver dt_cpufreq_driver = {
 	.exit = cpufreq_exit,
 	.ready = cpufreq_ready,
 	.name = "cpufreq-dt",
-	.attr = cpufreq_generic_attr,
+	.attr = cpufreq_dt_attr,
 };
 
 static int dt_cpufreq_probe(struct platform_device *pdev)
diff --git a/include/linux/cpufreq.h b/include/linux/cpufreq.h
index 95f0186..657542d 100644
--- a/include/linux/cpufreq.h
+++ b/include/linux/cpufreq.h
@@ -609,6 +609,7 @@ struct cpufreq_frequency_table *cpufreq_frequency_get_table(unsigned int cpu);
 
 /* the following are really really optional */
 extern struct freq_attr cpufreq_freq_attr_scaling_available_freqs;
+extern struct freq_attr cpufreq_freq_attr_scaling_boost_freqs;
 extern struct freq_attr *cpufreq_generic_attr[];
 int cpufreq_table_validate_and_show(struct cpufreq_policy *policy,
 				      struct cpufreq_frequency_table *table);
-- 
1.9.1




From chunfeng.yun at mediatek.com  Fri Aug  7 04:17:19 2015
From: chunfeng.yun at mediatek.com (chunfeng yun)
Date: Fri, 7 Aug 2015 19:17:19 +0800
Subject: [PATCH v4 2/5] dt-bindings: Add a binding for Mediatek xHCI
 host controller
In-Reply-To: <20150731134556.GC25118@leverpostej>
References: <1438347836-29060-1-git-send-email-chunfeng.yun@mediatek.com>
 <1438347836-29060-3-git-send-email-chunfeng.yun@mediatek.com>
 <20150731134556.GC25118@leverpostej>
Message-ID: <1438946239.26208.23.camel@mhfsdcap03>

hi,

On Fri, 2015-07-31 at 14:45 +0100, Mark Rutland wrote:
> Hi,
> 
> Sorry for my late reply to a prior version of this series, but I still
> have concerns with some of the properties.
> 
> I'll repeat those below.
> 
> On Fri, Jul 31, 2015 at 02:03:53PM +0100, Chunfeng Yun wrote:
> > add a DT binding documentation of xHCI host controller for the
> > MT8173 SoC from Mediatek.
> > 
> > Signed-off-by: Chunfeng Yun <chunfeng.yun at mediatek.com>
> > ---
> >  .../devicetree/bindings/usb/mt8173-xhci.txt        | 51 ++++++++++++++++++++++
> >  1 file changed, 51 insertions(+)
> >  create mode 100644 Documentation/devicetree/bindings/usb/mt8173-xhci.txt
> > 
> > diff --git a/Documentation/devicetree/bindings/usb/mt8173-xhci.txt b/Documentation/devicetree/bindings/usb/mt8173-xhci.txt
> > new file mode 100644
> > index 0000000..364be5a
> > --- /dev/null
> > +++ b/Documentation/devicetree/bindings/usb/mt8173-xhci.txt
> > @@ -0,0 +1,51 @@
> > +MT65XX xhci
> > +
> > +The device node for Mediatek SOC usb3.0 host controller
> > +
> > +Required properties:
> > + - compatible : Supports "mediatek,mt8173-xhci"
> 
> s/Supports/should contain/
> 
done
> > + - reg : Specifies physical base address and size of the registers,
> > +	the first one for MAC, the second for IPPC
> > + - interrupts : Interrupt mode, number and trigger mode
> 
> Just specify what this logically corresponds to; the format of the
> interrupts proeprty depends on the interrupt controller.
> 
done
> > + - power-domains : To enable usb's mtcmos
> 
> Please describe what this contains. I assume you exped a single power
> domain to be described, covering the whole xHCI controller?
> 
> > + - vusb33-supply : Regulator of usb avdd3.3v
> > + - clocks : Must support all clocks that xhci needs
> 
> - clocks: a list of phandle + clock-specifier pairs, one for each entry
>   in clock-names.
> 
> > + - clock-names : Should be "sys_mac" for sys and mac clocks, and
> > +	"wakeup_deb_p0", "wakeup_deb_p1" for wakeup debounce control
> > +	clocks
> 
> This would be better as a list, e.g.
> 
> - clock-names: should contain:
>   * "sys_mac" <description here if necessary>
>   * "wakeup_deb_p0" <description here if necessary>
>   * "wakeup_deb_p1" <description here if necessary>
> 
done
> Is sys_mac a single clock input line? Or is it jsut the case that a
> single line feeds two inputs currently? if the latter they should be
> separate entries.
> 
It is a single clock for usb MAC, already rename it

> > + - phys : List of PHY specifiers (used by generic PHY framework).
> 
> The bracketed part should go. The bidnigns should know nothing of Linux
> internals.
> 
remove it
> > + - phy-names : Must be "usb-phy0", "usb-phy1",.., "usb-phyN", based on
> > +	the number of PHYs as specified in @phys property.
> 
> This is useless.
> 
> You either don't need names, and can acquire the phys by index, or you
> need names which correspond to those on the data sheet for the xHCI
> controller.
> 
Ok, re-write the phy driver, and here also make use of the new format.

> > + - mediatek,usb-wakeup : To access usb wakeup control register
> 
> Please describe what this points to (I guess it's a syscon)/
> 
> > + - mediatek,wakeup-src : 1: Ip sleep wakeup mode; 2: line state wakeup
> > +	mode; others means don't enable wakeup source of usb
> 
> This sounds like a runtime decision.
> 
No, the driver do not know whether to enable wakeup function or not and
also don't know enable which one, except tell it. 
And it will set different registers of @mediatek,usb-wakeup to enable
the selected wakeup mode when system enter suspend.

> _why_ do you think this needs to be in the DT?
> 
> > + - mediatek,u2port-num : The number should not greater than the number
> > +	of phys
> 
> This is useless. Either this is implied by the entries in the phys
> property, or it should be a runtime decision.
> 
Yes, it can be calculated from @phys, already remove it.

Thanks a lot for your suggestion
 
> Thanks,
> Mark.
> 
> > +
> > +Optional properties:
> > + - vbus-supply : Reference to the VBUS regulator;
> > +
> > +Example:
> > +usb: usb at 11270000 {
> > +	compatible = "mediatek,mt8173-xhci";
> > +	reg = <0 0x11270000 0 0x4000>,
> > +	      <0 0x11280000 0 0x0800>;
> > +	interrupts = <GIC_SPI 115 IRQ_TYPE_LEVEL_LOW>;
> > +	power-domains = <&scpsys MT8173_POWER_DOMAIN_USB>;
> > +	clocks = <&topckgen CLK_TOP_USB30_SEL>,
> > +		 <&pericfg CLK_PERI_USB0>,
> > +		 <&pericfg CLK_PERI_USB1>;
> > +	clock-names = "sys_mac",
> > +		      "wakeup_deb_p0",
> > +		      "wakeup_deb_p1";
> > +	phys = <&u3phy 0>, <&u3phy 1>;
> > +	phy-names = "usb-phy0", "usb-phy1";
> > +	vusb33-supply = <&mt6397_vusb_reg>;
> > +	vbus-supply = <&usb_p1_vbus>;
> > +	usb3-lpm-capable;
> > +	mediatek,usb-wakeup = <&pericfg>;
> > +	mediatek,wakeup-src = <1>;
> > +	mediatek,u2port-num = <2>;
> > +	status = "okay";
> > +};
> > -- 
> > 1.8.1.1.dirty
> > 




From daniel at ffwll.ch  Fri Aug  7 04:25:35 2015
From: daniel at ffwll.ch (Daniel Vetter)
Date: Fri, 7 Aug 2015 13:25:35 +0200
Subject: [RFC PATCH 2/8] drm: exynos/dp: convert to drm bridge mode
In-Reply-To: <55C36F49.6020207@rock-chips.com>
References: <1438868947-22132-1-git-send-email-ykk@rock-chips.com>
 <1438870041-23130-1-git-send-email-ykk@rock-chips.com>
 <000001d0d052$f44fa3a0$dceeeae0$@com>
 <55C36F49.6020207@rock-chips.com>
Message-ID: <20150807112535.GK17734@phenom.ffwll.local>

On Thu, Aug 06, 2015 at 10:29:29PM +0800, Yakir Yang wrote:
> Hi Jingoo,
> 
> ? 2015/8/6 22:19, Jingoo Han ??:
> >On Thursday, August 06, 2015 11:07 PM, Yakir Yang wrote:
> >>In order to move exynos dp code to bridge directory,
> >>we need to convert driver drm bridge mode first. As
> >>dp driver already have a ptn3460 bridge, so we need
> >>to move ptn bridge to the next bridge of dp bridge.
> >>
> >>Signed-off-by: Yakir Yang <ykk at rock-chips.com>
> >>---
> >>  drivers/gpu/drm/exynos/exynos_dp_core.c | 196 ++++++++++++++++++++------------
> >>  drivers/gpu/drm/exynos/exynos_dp_core.h |   2 +
> >>  2 files changed, 126 insertions(+), 72 deletions(-)
> >>
> >>diff --git a/drivers/gpu/drm/exynos/exynos_dp_core.c b/drivers/gpu/drm/exynos/exynos_dp_core.c
> >>index a8097a4..aa99e23 100644
> >>--- a/drivers/gpu/drm/exynos/exynos_dp_core.c
> >>+++ b/drivers/gpu/drm/exynos/exynos_dp_core.c
> >>@@ -3,6 +3,7 @@
> >>   *
> >>   * Copyright (C) 2012 Samsung Electronics Co., Ltd.
> >>   * Author: Jingoo Han <jg1.han at samsung.com>
> >>+ *         Yakir Yang <ykk at rock-chips.com>
> >Please don't add this.
> >You just fixed some parts of this code. I don't find the reason
> >why you have to be added to author for this file.
> >If you want the title for an author, please send the patch
> >for a new IP, instead of modifying the exiting codes.
> 
> Okay, thanks for your remind ;)

tbh the author lines are completely irrelevant, git blame/log is the
authoritative source for that. Copyright is a bit a different matter
entirely, but in general we seem to be not too good at updating.

Really if that's all you have to comment and no substantial technical
concerns or questions then just can such a bikeshed mail.
-Daniel
-- 
Daniel Vetter
Software Engineer, Intel Corporation
http://blog.ffwll.ch


From aisheng.dong at freescale.com  Fri Aug  7 04:19:38 2015
From: aisheng.dong at freescale.com (Dong Aisheng)
Date: Fri, 7 Aug 2015 19:19:38 +0800
Subject: [PATCH v4 1/6] mmc: sdhci-esdhc-imx: add imx7d support and
 support HS400
In-Reply-To: <BY1PR03MB138813618D918A609ED1D7ED9A730@BY1PR03MB1388.namprd03.prod.outlook.com>
References: <1438771122-8601-1-git-send-email-haibo.chen@freescale.com>
 <1438771122-8601-2-git-send-email-haibo.chen@freescale.com>
 <20150807073854.GA6935@shlinux1.ap.freescale.net>
 <BY1PR03MB138813618D918A609ED1D7ED9A730@BY1PR03MB1388.namprd03.prod.outlook.com>
Message-ID: <20150807111937.GD6935@shlinux1.ap.freescale.net>

On Fri, Aug 07, 2015 at 05:53:01PM +0800, Chen Haibo-B51421 wrote:
> 
> 
> > -----Original Message-----
> > From: Dong Aisheng [mailto:aisheng.dong at freescale.com]
> > Sent: Friday, August 07, 2015 3:39 PM
> > To: Chen Haibo-B51421
> > Cc: robh+dt at kernel.org; pawel.moll at arm.com; mark.rutland at arm.com;
> > ijc+devicetree at hellion.org.uk; galak at codeaurora.org; shawnguo at kernel.org;
> > kernel at pengutronix.de; linux at arm.linux.org.uk; ulf.hansson at linaro.org;
> > johan.derycke at barco.com; mkl at pengutronix.de; Estevam Fabio-R49496; Dong
> > Aisheng-B29396; devicetree at vger.kernel.org; linux-kernel at vger.kernel.org;
> > linux-arm-kernel at lists.infradead.org; linux-mmc at vger.kernel.org
> > Subject: Re: [PATCH v4 1/6] mmc: sdhci-esdhc-imx: add imx7d support and
> > support HS400
> > 
> > On Wed, Aug 05, 2015 at 06:38:37PM +0800, Haibo Chen wrote:
> > > The imx7d usdhc is derived from imx6sx, the difference is that imx7d
> > > support HS400.
> > >
> > > So introduce a new compatible string for imx7d and add HS400 support
> > > for imx7d usdhc.
> > >
> > > Signed-off-by: Haibo Chen <haibo.chen at freescale.com>
> > > ---
> > >  drivers/mmc/host/sdhci-esdhc-imx.c | 81
> > > ++++++++++++++++++++++++++++++++++++++
> > >  1 file changed, 81 insertions(+)
> > >
> > > diff --git a/drivers/mmc/host/sdhci-esdhc-imx.c
> > > b/drivers/mmc/host/sdhci-esdhc-imx.c
> > > index c6b9f64..48f009c 100644
> > > --- a/drivers/mmc/host/sdhci-esdhc-imx.c
> > > +++ b/drivers/mmc/host/sdhci-esdhc-imx.c
> > > @@ -44,6 +44,7 @@
> > >  #define  ESDHC_MIX_CTRL_EXE_TUNE	(1 << 22)
> > >  #define  ESDHC_MIX_CTRL_SMPCLK_SEL	(1 << 23)
> > >  #define  ESDHC_MIX_CTRL_FBCLK_SEL	(1 << 25)
> > > +#define  ESDHC_MIX_CTRL_HS400_EN	(1 << 26)
> > >  /* Bits 3 and 6 are not SDHCI standard definitions */
> > >  #define  ESDHC_MIX_CTRL_SDHCI_MASK	0xb7
> > >  /* Tuning bits */
> > > @@ -60,6 +61,16 @@
> > >  #define  ESDHC_TUNE_CTRL_MIN		0
> > >  #define  ESDHC_TUNE_CTRL_MAX		((1 << 7) - 1)
> > >
> > > +/* strobe dll register */
> > > +#define ESDHC_STROBE_DLL_CTRL		0x70
> > > +#define ESDHC_STROBE_DLL_CTRL_ENABLE	(1 << 0)
> > > +#define ESDHC_STROBE_DLL_CTRL_RESET	(1 << 1)
> > > +#define ESDHC_STROBE_DLL_CTRL_SLV_DLY_TARGET_SHIFT	3
> > > +
> > > +#define ESDHC_STROBE_DLL_STATUS		0x74
> > > +#define ESDHC_STROBE_DLL_STS_REF_LOCK	(1 << 1)
> > > +#define ESDHC_STROBE_DLL_STS_SLV_LOCK	0x1
> > > +
> > >  #define ESDHC_TUNING_CTRL		0xcc
> > >  #define ESDHC_STD_TUNING_EN		(1 << 24)
> > >  /* NOTE: the minimum valid tuning start tap for mx6sl is 1 */ @@
> > > -120,6 +131,11 @@
> > >  #define ESDHC_FLAG_ERR004536		BIT(7)
> > >  /* The IP supports HS200 mode */
> > >  #define ESDHC_FLAG_HS200		BIT(8)
> > > +/* The IP supports HS400 mode */
> > > +#define ESDHC_FLAG_HS400		BIT(9)
> > > +
> > > +/* A higher clock ferquency than this rate requires strobell dll
> > control */
> > > +#define ESDHC_STROBE_DLL_CLK_FREQ	100000000
> > >
> > >  struct esdhc_soc_data {
> > >  	u32 flags;
> > > @@ -156,6 +172,12 @@ static struct esdhc_soc_data usdhc_imx6sx_data = {
> > >  			| ESDHC_FLAG_HAVE_CAP1 | ESDHC_FLAG_HS200,  };
> > >
> > > +static struct esdhc_soc_data usdhc_imx7d_data = {
> > > +	.flags = ESDHC_FLAG_USDHC | ESDHC_FLAG_STD_TUNING
> > > +			| ESDHC_FLAG_HAVE_CAP1 | ESDHC_FLAG_HS200
> > > +			| ESDHC_FLAG_HS400,
> > > +};
> > > +
> > >  struct pltfm_imx_data {
> > >  	u32 scratchpad;
> > >  	struct pinctrl *pinctrl;
> > > @@ -199,6 +221,7 @@ static const struct of_device_id imx_esdhc_dt_ids[]
> > = {
> > >  	{ .compatible = "fsl,imx6sx-usdhc", .data = &usdhc_imx6sx_data, },
> > >  	{ .compatible = "fsl,imx6sl-usdhc", .data = &usdhc_imx6sl_data, },
> > >  	{ .compatible = "fsl,imx6q-usdhc", .data = &usdhc_imx6q_data, },
> > > +	{ .compatible = "fsl,imx7d-usdhc", .data = &usdhc_imx7d_data, },
> > >  	{ /* sentinel */ }
> > >  };
> > >  MODULE_DEVICE_TABLE(of, imx_esdhc_dt_ids); @@ -274,6 +297,9 @@ static
> > > u32 esdhc_readl_le(struct sdhci_host *host, int reg)
> > >  				val = SDHCI_SUPPORT_DDR50 | SDHCI_SUPPORT_SDR104
> > >  					| SDHCI_SUPPORT_SDR50
> > >  					| SDHCI_USE_SDR50_TUNING;
> > > +
> > > +			if (imx_data->socdata->flags & ESDHC_FLAG_HS400)
> > > +				val |= SDHCI_SUPPORT_HS400;
> > >  		}
> > >  	}
> > >
> > > @@ -774,6 +800,7 @@ static int esdhc_change_pinstate(struct sdhci_host
> > *host,
> > >  		break;
> > >  	case MMC_TIMING_UHS_SDR104:
> > >  	case MMC_TIMING_MMC_HS200:
> > > +	case MMC_TIMING_MMC_HS400:
> > >  		pinctrl = imx_data->pins_200mhz;
> > >  		break;
> > >  	default:
> > > @@ -784,6 +811,44 @@ static int esdhc_change_pinstate(struct sdhci_host
> > *host,
> > >  	return pinctrl_select_state(imx_data->pinctrl, pinctrl);  }
> > >
> > > +/*
> > > + * For HS400 eMMC, there is a data_strobe line, this signal is
> > > +generated
> > > + * by the device and used for data output and CRC status response
> > > +output
> > > + * in HS400 mode. The frequency of this signal follows the frequency
> > > +of
> > > + * CLK generated by host. Host receive the data which is aligned to
> > > +the
> > > + * edge of data_strobe line. Due to the time delay between CLK line
> > > +and
> > > + * data_strobe line, if the delay time is larger than one clock
> > > +cycle,
> > > + * then CLK and data_strobe line will misaligned, read error shows up.
> > > + * So when the CLK is higher than 100MHz, each clock cycle is short
> > > +enough,
> > > + * host should config the delay target.
> > > + */
> > > +static void esdhc_set_strobe_dll(struct sdhci_host *host) {
> > > +	u32 v;
> > > +
> > > +	if (host->mmc->actual_clock > ESDHC_STROBE_DLL_CLK_FREQ) {
> > > +		/* force a reset on strobe dll */
> > > +		writel(ESDHC_STROBE_DLL_CTRL_RESET,
> > > +			host->ioaddr + ESDHC_STROBE_DLL_CTRL);
> > > +		/*
> > > +		 * enable strobe dll ctrl and adjust the delay target
> > > +		 * for the uSDHC loopback read clock
> > > +		 */
> > > +		v = ESDHC_STROBE_DLL_CTRL_ENABLE |
> > > +			(7 << ESDHC_STROBE_DLL_CTRL_SLV_DLY_TARGET_SHIFT);
> > > +		writel(v, host->ioaddr + ESDHC_STROBE_DLL_CTRL);
> > > +		/* wait 1us to make sure strobe dll status register stable */
> > > +		udelay(1);
> > > +		v = readl(host->ioaddr + ESDHC_STROBE_DLL_STATUS);
> > > +		if (!(v & ESDHC_STROBE_DLL_STS_REF_LOCK))
> > > +			dev_warn(mmc_dev(host->mmc),
> > > +				"warning! HS400 strobe DLL status REF not
> > lock!\n");
> > > +		if (!(v & ESDHC_STROBE_DLL_STS_SLV_LOCK))
> > > +			dev_warn(mmc_dev(host->mmc),
> > > +				"warning! HS400 strobe DLL status SLV not
> > lock!\n");
> > > +	}
> > > +}
> > > +
> > >  static void esdhc_set_uhs_signaling(struct sdhci_host *host, unsigned
> > > timing)  {
> > >  	struct sdhci_pltfm_host *pltfm_host = sdhci_priv(host); @@ -795,7
> > > +860,13 @@ static void esdhc_set_uhs_signaling(struct sdhci_host *host,
> > unsigned timing)
> > >  	case MMC_TIMING_UHS_SDR25:
> > >  	case MMC_TIMING_UHS_SDR50:
> > >  	case MMC_TIMING_UHS_SDR104:
> > > +		break;
> > >  	case MMC_TIMING_MMC_HS200:
> > > +		/* disable ddr mode and disable HS400 mode */
> > > +		writel(readl(host->ioaddr + ESDHC_MIX_CTRL) &
> > > +			~(ESDHC_MIX_CTRL_DDREN | ESDHC_MIX_CTRL_HS400_EN),
> > > +			host->ioaddr + ESDHC_MIX_CTRL);
> > > +		imx_data->is_ddr = 0;
> > 
> > Can you please explain why need above code?
> > Any issues if not do it?
> > 
> > Regards
> > Dong Aisheng
> 
> [haibo] currently, mmc core code use mmc_retune before every request,
> and in mmc_retune, for eMMC, if the chip is in HS400 mode, firstly,
> the code use mmc_hs400_to_hs200() to change the emmc chip work in
> HS200 mode, and execute the tuning, and then use mmc_hs200_to_hs400()
> to make the emmc chip work back in HS400 mode.
> 
> Without the above code, when change to hs200 mode from hs400 mode, our
> host still enable ddr mode and enable hs400 mode, which is wrong.
> So add the code here. 
> 

Okay, understand.
Clearing only for HS200 case is a bit confusing.
A common rule to do it might be:
Step 1) Clear exist timing setting at first
Step 2) Set the required timing for each case

I'd suggest you do like as follows:

m = readl(host->ioaddr + ESDHC_MIX_CTRL);
m &=~(ESDHC_MIX_CTRL_DDREN | ESDHC_MIX_CTRL_HS400_EN);
imx_data->is_ddr = 0;

Then
case HS200:
...
case HS400:
...

Regards
Dong Aisheng

> > 
> > >  		break;
> > >  	case MMC_TIMING_UHS_DDR50:
> > >  	case MMC_TIMING_MMC_DDR52:
> > > @@ -813,6 +884,13 @@ static void esdhc_set_uhs_signaling(struct
> > sdhci_host *host, unsigned timing)
> > >  			writel(v, host->ioaddr + ESDHC_DLL_CTRL);
> > >  		}
> > >  		break;
> > > +	case MMC_TIMING_MMC_HS400:
> > > +		writel(readl(host->ioaddr + ESDHC_MIX_CTRL) |
> > > +				ESDHC_MIX_CTRL_DDREN | ESDHC_MIX_CTRL_HS400_EN,
> > > +				host->ioaddr + ESDHC_MIX_CTRL);
> > > +		imx_data->is_ddr = 1;
> > > +		esdhc_set_strobe_dll(host);
> > > +		break;
> > >  	}
> > >
> > >  	esdhc_change_pinstate(host, timing); @@ -1100,6 +1178,9 @@ static
> > > int sdhci_esdhc_imx_probe(struct platform_device *pdev)
> > >  	if (imx_data->socdata->flags & ESDHC_FLAG_ERR004536)
> > >  		host->quirks |= SDHCI_QUIRK_BROKEN_ADMA;
> > >
> > > +	if (imx_data->socdata->flags & ESDHC_FLAG_HS400)
> > > +		host->quirks2 |= SDHCI_QUIRK2_CAPS_BIT63_FOR_HS400;
> > > +
> > >  	if (of_id)
> > >  		err = sdhci_esdhc_imx_probe_dt(pdev, host, imx_data);
> > >  	else
> > > --
> > > 1.9.1
> > >


From b.zolnierkie at samsung.com  Fri Aug  7 04:31:15 2015
From: b.zolnierkie at samsung.com (Bartlomiej Zolnierkiewicz)
Date: Fri, 07 Aug 2015 13:31:15 +0200
Subject: [PATCH v4 0/6] cpufreq: use generic cpufreq drivers for Exynos4x12
 platform
In-Reply-To: <20150807051826.GJ6325@linux>
References: <1438868514-8814-1-git-send-email-b.zolnierkie@samsung.com>
 <55C43971.5010504@samsung.com> <20150807051826.GJ6325@linux>
Message-ID: <2061119.GBaoSb4YSL@amdc1976>


Hi,

On Friday, August 07, 2015 10:48:26 AM Viresh Kumar wrote:
> On 07-08-15, 13:52, Krzysztof Kozlowski wrote:
> > Thanks for explanation. As fair as I understand, Bartlomiej wanted to
> > merge this in a way which would avoid loosing the boost mode. Kukjin
> > prepared topic branches for previous cpu-freq/clk stuff so maybe
> > everything could go through PM?
> 
> We aren't loosing anything at all. There can be two cases here:
> 
> 1. Patch 1/6 and 6/6 make it to 4.3 (with suggested changes) via PM tree:
> - All will work fine in this case, no issues at all..
> 
> 2. They don't make it:
> - Even in this case, nothing will break. Users can just enable a
>   config option and that's all..

Users don't need to enable the config option to get boost
functionality working.  It is only needed to get scaling_boost_freqs
sysfs attribute visible (which lists available boost freqs) when
using cpufreq-dt driver.  Also the config option in question is not
user visible.

The worst thing that happens if these 2 PM patches don't make it
in time is that there will be no scaling_boost_freqs available
when using cpufreq-dt driver.  Which is not very important from
Exynos4x12 POV as it only supports single boost freq currently.

> So, no need to divert things into another tree this late.

I agree.

> Over that, Rafael will not be around for 2 weeks now (Plumbers and
> other stuff) ..
> 
> So, just target the cpufreq core changes via PM tree.. rest is just
> fine.
> 
> I hope that makes sense :)

Yes. :)
 
Best regards,
--
Bartlomiej Zolnierkiewicz
Samsung R&D Institute Poland
Samsung Electronics



From heiko at sntech.de  Fri Aug  7 04:36:38 2015
From: heiko at sntech.de (Heiko =?ISO-8859-1?Q?St=FCbner?=)
Date: Fri, 07 Aug 2015 13:36:38 +0200
Subject: [PATCH v4 1/2] clk: rockchip: add pclk_pd_pmu to the list of
 rk3288 critical clocks
In-Reply-To: <55C47D59.8080403@rock-chips.com>
References: <1438939872-2116-1-git-send-email-hl@rock-chips.com>
 <55C47D59.8080403@rock-chips.com>
Message-ID: <2226681.uyCeUEdNHm@diego>

Am Freitag, 7. August 2015, 17:41:45 schrieb hl:
> Hi Heiko,
> 
> > pclk_pd_pmu needs to keep running and with the upcoming gpio clock
> > handling this is not always the case anymore. So add it to the list
> > of critical clocks for now.
> > 
> > From: Heiko Stuebner <heiko at sntech.de>
> > Signed-off-by: Lin Huang <hl at rock-chips.com>
> 
>      is it the right way?  if it still can not meet the requirement,
> please let me know.

nearly, but not quite ;-)

You can take a look at my minnie patch [0] for inspiration.


Also please make sure to include linus.walleij at linaro.org also in this
first mail. This clock patch is a prequisite for the pinctrl change so
we would like Linus Walleij to merge both into his pinctrl tree.

Ideally both times in the "To" and not the "Cc" recipients, as To vs. Cc
is often used to distinguish whom you want to apply the patch.


Heiko


[0] http://lists.infradead.org/pipermail/linux-rockchip/2015-August/003608.html




> 
> > ---
> > Changes in v4:
> > - Add From: Heiko Stuebner <heiko at sntech.de>
> > 
> >   drivers/clk/rockchip/clk-rk3288.c | 1 +
> >   1 file changed, 1 insertion(+)
> > 
> > diff --git a/drivers/clk/rockchip/clk-rk3288.c
> > b/drivers/clk/rockchip/clk-rk3288.c index 0df5bae..9040878 100644
> > --- a/drivers/clk/rockchip/clk-rk3288.c
> > +++ b/drivers/clk/rockchip/clk-rk3288.c
> > @@ -780,6 +780,7 @@ static const char *const rk3288_critical_clocks[]
> > __initconst = {> 
> >   	"aclk_cpu",
> >   	"aclk_peri",
> >   	"hclk_peri",
> > 
> > +	"pclk_pd_pmu",
> > 
> >   };
> >   
> >   #ifdef CONFIG_PM_SLEEP



From viresh.kumar at linaro.org  Fri Aug  7 04:37:39 2015
From: viresh.kumar at linaro.org (Viresh Kumar)
Date: Fri, 7 Aug 2015 17:07:39 +0530
Subject: [PATCH v4 1/6] cpufreq: make scaling_boost_freqs sysfs attr
 available when boost is enabled
In-Reply-To: <1594902.Dv5JKhve0y@amdc1976>
References: <1438868514-8814-1-git-send-email-b.zolnierkie@samsung.com>
 <5184469.cOpIkgzX4h@amdc1976> <20150807104156.GE6939@linux>
 <1594902.Dv5JKhve0y@amdc1976>
Message-ID: <20150807113739.GF6939@linux>

On 07-08-15, 13:12, Bartlomiej Zolnierkiewicz wrote:
> >From 993ebb6fc632ec7b61654c9610c90ff4dca4be34 Mon Sep 17 00:00:00 2001
> From: Bartlomiej Zolnierkiewicz <b.zolnierkie at samsung.com>
> Date: Fri, 7 Aug 2015 13:07:51 +0200
> Subject: [PATCH] cpufreq-dt: make scaling_boost_freqs sysfs attr available
>  when boost is enabled
> 
> Make scaling_boost_freqs sysfs attribute is available when
> cpufreq-dt driver is used and boost support is enabled.
> 
> Cc: Thomas Abraham <thomas.ab at samsung.com>
> Cc: Javier Martinez Canillas <javier at osg.samsung.com>
> Cc: Krzysztof Kozlowski <k.kozlowski at samsung.com>
> Suggested-by: Viresh Kumar <viresh.kumar at linaro.org>
> Signed-off-by: Bartlomiej Zolnierkiewicz <b.zolnierkie at samsung.com>
> ---
>  drivers/cpufreq/cpufreq-dt.c | 11 ++++++++++-
>  include/linux/cpufreq.h      |  1 +
>  2 files changed, 11 insertions(+), 1 deletion(-)
> 
> diff --git a/drivers/cpufreq/cpufreq-dt.c b/drivers/cpufreq/cpufreq-dt.c
> index b9259ab..c6a3b98 100644
> --- a/drivers/cpufreq/cpufreq-dt.c
> +++ b/drivers/cpufreq/cpufreq-dt.c
> @@ -36,6 +36,12 @@ struct private_data {
>  	unsigned int voltage_tolerance; /* in percentage */
>  };
>  
> +static struct freq_attr *cpufreq_dt_attr[] = {
> +	&cpufreq_freq_attr_scaling_available_freqs,
> +	NULL,   /* Extra space for boost-attr if required */
> +	NULL,
> +};
> +
>  static int set_target(struct cpufreq_policy *policy, unsigned int index)
>  {
>  	struct dev_pm_opp *opp;
> @@ -182,6 +188,8 @@ try_again:
>  	return ret;
>  }
>  
> +static struct cpufreq_driver dt_cpufreq_driver;
> +
>  static int cpufreq_init(struct cpufreq_policy *policy)
>  {
>  	struct cpufreq_frequency_table *freq_table;
> @@ -336,6 +344,7 @@ static int cpufreq_init(struct cpufreq_policy *policy)
>  		ret = cpufreq_enable_boost_support();
>  		if (ret)
>  			goto out_free_cpufreq_table;
> +		cpufreq_dt_attr[1] = &cpufreq_freq_attr_scaling_boost_freqs;
>  	}
>  
>  	policy->cpuinfo.transition_latency = transition_latency;
> @@ -411,7 +420,7 @@ static struct cpufreq_driver dt_cpufreq_driver = {
>  	.exit = cpufreq_exit,
>  	.ready = cpufreq_ready,
>  	.name = "cpufreq-dt",
> -	.attr = cpufreq_generic_attr,
> +	.attr = cpufreq_dt_attr,
>  };
>  
>  static int dt_cpufreq_probe(struct platform_device *pdev)
> diff --git a/include/linux/cpufreq.h b/include/linux/cpufreq.h
> index 95f0186..657542d 100644
> --- a/include/linux/cpufreq.h
> +++ b/include/linux/cpufreq.h
> @@ -609,6 +609,7 @@ struct cpufreq_frequency_table *cpufreq_frequency_get_table(unsigned int cpu);
>  
>  /* the following are really really optional */
>  extern struct freq_attr cpufreq_freq_attr_scaling_available_freqs;
> +extern struct freq_attr cpufreq_freq_attr_scaling_boost_freqs;
>  extern struct freq_attr *cpufreq_generic_attr[];
>  int cpufreq_table_validate_and_show(struct cpufreq_policy *policy,
>  				      struct cpufreq_frequency_table *table);

Acked-by: Viresh Kumar <viresh.kumar at linaro.org>

-- 
viresh


From viresh.kumar at linaro.org  Fri Aug  7 04:39:50 2015
From: viresh.kumar at linaro.org (Viresh Kumar)
Date: Fri, 7 Aug 2015 17:09:50 +0530
Subject: [PATCH v4 0/6] cpufreq: use generic cpufreq drivers for
 Exynos4x12 platform
In-Reply-To: <2061119.GBaoSb4YSL@amdc1976>
References: <1438868514-8814-1-git-send-email-b.zolnierkie@samsung.com>
 <55C43971.5010504@samsung.com> <20150807051826.GJ6325@linux>
 <2061119.GBaoSb4YSL@amdc1976>
Message-ID: <20150807113950.GG6939@linux>

On 07-08-15, 13:31, Bartlomiej Zolnierkiewicz wrote:
> Users don't need to enable the config option to get boost
> functionality working.  It is only needed to get scaling_boost_freqs
> sysfs attribute visible (which lists available boost freqs) when
> using cpufreq-dt driver.  Also the config option in question is not
> user visible.

By users I meant the people who will prepare the build images for the
release. They can just enable the config option :)

> The worst thing that happens if these 2 PM patches don't make it
> in time is that there will be no scaling_boost_freqs available
> when using cpufreq-dt driver.  Which is not very important from
> Exynos4x12 POV as it only supports single boost freq currently.

Right. So, now that your patch is Acked, send 1/6 and 6/6 separately
to pm-list and Rafael can get them merged himself..

I hope, your 6/6 patch will change a bit now ?

-- 
viresh


From sjoerd.simons at collabora.co.uk  Fri Aug  7 04:44:13 2015
From: sjoerd.simons at collabora.co.uk (Sjoerd Simons)
Date: Fri,  7 Aug 2015 13:44:13 +0200
Subject: [PATCH v3 3/4] ARM: dts: rockchip: Add SPDIF transceiver for RK3188
In-Reply-To: <1438947854-3743-1-git-send-email-sjoerd.simons@collabora.co.uk>
References: <1438947854-3743-1-git-send-email-sjoerd.simons@collabora.co.uk>
Message-ID: <1438947854-3743-4-git-send-email-sjoerd.simons@collabora.co.uk>

Add the SPDIF transceiver controller and pin for RK3188

Signed-off-by: Sjoerd Simons <sjoerd.simons at collabora.co.uk>

---

Changes in v3: None
Changes in v2:
- Sort the spdif node properties
- Drop the 0x prefix from the node name
- Rename the spdif@ node to sound@

 arch/arm/boot/dts/rk3188.dtsi | 22 ++++++++++++++++++++++
 1 file changed, 22 insertions(+)

diff --git a/arch/arm/boot/dts/rk3188.dtsi b/arch/arm/boot/dts/rk3188.dtsi
index 0f23aed..abdb5bc 100644
--- a/arch/arm/boot/dts/rk3188.dtsi
+++ b/arch/arm/boot/dts/rk3188.dtsi
@@ -121,6 +121,22 @@
 		status = "disabled";
 	};
 
+	spdif: sound at 1011e000 {
+		compatible = "rockchip,rk3188-spdif", "rockchip,rk3066-spdif";
+		reg = <0x1011e000 0x2000>;
+		#address-cells = <1>;
+		#size-cells = <0>;
+		#sound-dai-cells = <0>;
+		clock-names = "spdif_hclk", "spdif_clk";
+		clocks = <&cru HCLK_SPDIF>, <&cru SCLK_SPDIF>;
+		dmas = <&dmac1_s 8>;
+		dma-names = "tx";
+		interrupts = <GIC_SPI 32 IRQ_TYPE_LEVEL_HIGH>;
+		pinctrl-names = "default";
+		pinctrl-0 = <&spdif_tx>;
+		status = "disabled";
+	};
+
 	cru: clock-controller at 20000000 {
 		compatible = "rockchip,rk3188-cru";
 		reg = <0x20000000 0x1000>;
@@ -462,6 +478,12 @@
 						<RK_GPIO1 21 RK_FUNC_1 &pcfg_pull_none>;
 			};
 		};
+
+		spdif {
+			spdif_tx: spdif-tx {
+				rockchip,pins = <RK_GPIO1 14 RK_FUNC_1 &pcfg_pull_none>;
+			};
+		};
 	};
 };
 
-- 
2.5.0



From sjoerd.simons at collabora.co.uk  Fri Aug  7 04:44:10 2015
From: sjoerd.simons at collabora.co.uk (Sjoerd Simons)
Date: Fri,  7 Aug 2015 13:44:10 +0200
Subject: [PATCH v3 0/4] Add SPDIF support for rockchip
Message-ID: <1438947854-3743-1-git-send-email-sjoerd.simons@collabora.co.uk>

This patchset adds support for the Rockchip SPDIF transceiver as present
on RK3066, RK3188 and RK3288 boards and enables it on a Radxa rock pro.
Tested on a Radxa Rock Pro board.

Changes in v3:
- Fix typos in commit message
- Resent patches to a more complete list of maintainers.

Changes in v2:
- Remove platform: module alias as it was unused
- Call MODULE_DEVICE_TABLE(of, ) right after the of match table
- use rk_spdif as a prefix consistenly throughout the driver
- Check return code of regmap_update and bubble it up
- Sort the spdif node properties
- Drop the 0x prefix from the node name
- Rename the spdif@ node to sound@

Sjoerd Simons (4):
  ASoC: dt-bindings: add rockchip tranceiver bindings
  ASoC: rockchip: Add rockchip SPDIF transceiver driver
  ARM: dts: rockchip: Add SPDIF transceiver for RK3188
  ARM: dts: rockchip: Add SPDIF optical out on Radxa Rock

 .../devicetree/bindings/sound/rockchip-spdif.txt   |  41 +++
 arch/arm/boot/dts/rk3188-radxarock.dts             |  19 +
 arch/arm/boot/dts/rk3188.dtsi                      |  22 ++
 sound/soc/rockchip/Kconfig                         |   8 +
 sound/soc/rockchip/Makefile                        |   2 +
 sound/soc/rockchip/rockchip_spdif.c                | 381 +++++++++++++++++++++
 sound/soc/rockchip/rockchip_spdif.h                |  63 ++++
 7 files changed, 536 insertions(+)
 create mode 100644 Documentation/devicetree/bindings/sound/rockchip-spdif.txt
 create mode 100644 sound/soc/rockchip/rockchip_spdif.c
 create mode 100644 sound/soc/rockchip/rockchip_spdif.h

-- 
2.5.0



From sjoerd.simons at collabora.co.uk  Fri Aug  7 04:44:14 2015
From: sjoerd.simons at collabora.co.uk (Sjoerd Simons)
Date: Fri,  7 Aug 2015 13:44:14 +0200
Subject: [PATCH v3 4/4] ARM: dts: rockchip: Add SPDIF optical out on Radxa Rock
In-Reply-To: <1438947854-3743-1-git-send-email-sjoerd.simons@collabora.co.uk>
References: <1438947854-3743-1-git-send-email-sjoerd.simons@collabora.co.uk>
Message-ID: <1438947854-3743-5-git-send-email-sjoerd.simons@collabora.co.uk>

This enables the SPDIF optical audio output on the Radxa Rock

Signed-off-by: Sjoerd Simons <sjoerd.simons at collabora.co.uk>

---

Changes in v3:
- Resent patches to a more complete list of maintainers.

Changes in v2: None

 arch/arm/boot/dts/rk3188-radxarock.dts | 19 +++++++++++++++++++
 1 file changed, 19 insertions(+)

diff --git a/arch/arm/boot/dts/rk3188-radxarock.dts b/arch/arm/boot/dts/rk3188-radxarock.dts
index 4bb014d..dea020c 100644
--- a/arch/arm/boot/dts/rk3188-radxarock.dts
+++ b/arch/arm/boot/dts/rk3188-radxarock.dts
@@ -90,6 +90,21 @@
 		};
 	};
 
+	sound {
+		compatible = "simple-audio-card";
+		simple-audio-card,name = "SPDIF";
+
+		simple-audio-card,dai-link at 1 {  /* S/PDIF - S/PDIF */
+			cpu { sound-dai = <&spdif>; };
+			codec { sound-dai = <&spdif_out>; };
+		};
+	};
+
+	spdif_out: spdif-out {
+		compatible = "linux,spdif-dit";
+		#sound-dai-cells = <0>;
+	};
+
 	ir_recv: gpio-ir-receiver {
 		compatible = "gpio-ir-receiver";
 		gpios = <&gpio0 10 1>;
@@ -343,6 +358,10 @@
 	};
 };
 
+&spdif {
+	status = "okay";
+};
+
 &uart0 {
 	status = "okay";
 };
-- 
2.5.0



From sjoerd.simons at collabora.co.uk  Fri Aug  7 04:44:11 2015
From: sjoerd.simons at collabora.co.uk (Sjoerd Simons)
Date: Fri,  7 Aug 2015 13:44:11 +0200
Subject: [PATCH v3 1/4] ASoC: dt-bindings: add rockchip tranceiver bindings
In-Reply-To: <1438947854-3743-1-git-send-email-sjoerd.simons@collabora.co.uk>
References: <1438947854-3743-1-git-send-email-sjoerd.simons@collabora.co.uk>
Message-ID: <1438947854-3743-2-git-send-email-sjoerd.simons@collabora.co.uk>

Add devicetree bindings for the spdif tranceiver found on
found on rk3066, rk3188 and rk3288 SoCs

Signed-off-by: Sjoerd Simons <sjoerd.simons at collabora.co.uk>
---

Changes in v3: None
Changes in v2: None

 .../devicetree/bindings/sound/rockchip-spdif.txt   | 41 ++++++++++++++++++++++
 1 file changed, 41 insertions(+)
 create mode 100644 Documentation/devicetree/bindings/sound/rockchip-spdif.txt

diff --git a/Documentation/devicetree/bindings/sound/rockchip-spdif.txt b/Documentation/devicetree/bindings/sound/rockchip-spdif.txt
new file mode 100644
index 0000000..2da8a09
--- /dev/null
+++ b/Documentation/devicetree/bindings/sound/rockchip-spdif.txt
@@ -0,0 +1,41 @@
+* Rockchip SPDIF transceiver
+
+The S/PDIF audio block is a stereo transceiver that allows the
+processor to receive and transmit digital audio via an coaxial cable or
+a fibre cable.
+
+Required properties:
+
+- compatible: should be one of the following:
+   - "rockchip,rk3066-spdif": for rk3066
+   - "rockchip,rk3188-spdif", "rockchip,rk3066-spdif": for rk3188
+   - "rockchip,rk3288-spdif", "rockchip,rk3066-spdif": for rk3288
+- reg: physical base address of the controller and length of memory mapped
+  region.
+- interrupts: should contain the SPDIF interrupt.
+- #address-cells: should be 1.
+- #size-cells: should be 0.
+- dmas: DMA specifiers for tx dma. See the DMA client binding,
+  Documentation/devicetree/bindings/dma/dma.txt
+- dma-names: should be "tx"
+- clocks: a list of phandle + clock-specifier pairs, one for each entry
+  in clock-names.
+- clock-names: should contain following:
+   - "spdif_hclk": clock for SPPIF controller
+   - "spdif_clk" : clock for SPDIF bus
+
+Example for the rk3188 SPDIF controller:
+
+spdif: spdif at 0x1011e000 {
+	compatible = "rockchip,rk3188-spdif", "rockchip,rk3066-spdif";
+	reg = <0x1011e000 0x2000>;
+	interrupts = <GIC_SPI 32 IRQ_TYPE_LEVEL_HIGH>;
+	#address-cells = <1>;
+	#size-cells = <0>;
+	dmas = <&dmac1_s 8>;
+	dma-names = "tx";
+	clock-names = "spdif_hclk", "spdif_clk";
+	clocks = <&cru HCLK_SPDIF>, <&cru SCLK_SPDIF>;
+	status = "disabled";
+	#sound-dai-cells = <0>;
+};
-- 
2.5.0



From sjoerd.simons at collabora.co.uk  Fri Aug  7 04:44:12 2015
From: sjoerd.simons at collabora.co.uk (Sjoerd Simons)
Date: Fri,  7 Aug 2015 13:44:12 +0200
Subject: [PATCH v3 2/4] ASoC: rockchip: Add rockchip SPDIF transceiver driver
In-Reply-To: <1438947854-3743-1-git-send-email-sjoerd.simons@collabora.co.uk>
References: <1438947854-3743-1-git-send-email-sjoerd.simons@collabora.co.uk>
Message-ID: <1438947854-3743-3-git-send-email-sjoerd.simons@collabora.co.uk>

Add a driver for the SPDIF transceiver available on RK3066, RK3188 and
RK3288. Heavily based on the rockchip i2s driver.

Signed-off-by: Sjoerd Simons <sjoerd.simons at collabora.co.uk>
---

Changes in v3:
- Fix typos in commit message

Changes in v2:
- Remove platform: module alias as it was unused
- Call MODULE_DEVICE_TABLE(of, ) right after the of match table
- use rk_spdif as a prefix consistenly throughout the driver
- Check return code of regmap_update and bubble it up

 sound/soc/rockchip/Kconfig          |   8 +
 sound/soc/rockchip/Makefile         |   2 +
 sound/soc/rockchip/rockchip_spdif.c | 381 ++++++++++++++++++++++++++++++++++++
 sound/soc/rockchip/rockchip_spdif.h |  63 ++++++
 4 files changed, 454 insertions(+)
 create mode 100644 sound/soc/rockchip/rockchip_spdif.c
 create mode 100644 sound/soc/rockchip/rockchip_spdif.h

diff --git a/sound/soc/rockchip/Kconfig b/sound/soc/rockchip/Kconfig
index 58bae8e..603fd1f 100644
--- a/sound/soc/rockchip/Kconfig
+++ b/sound/soc/rockchip/Kconfig
@@ -15,6 +15,14 @@ config SND_SOC_ROCKCHIP_I2S
 	  Rockchip I2S device. The device supports upto maximum of
 	  8 channels each for play and record.
 
+config SND_SOC_ROCKCHIP_SPDIF
+	tristate "Rockchip SPDIF Device Driver"
+	depends on CLKDEV_LOOKUP && SND_SOC_ROCKCHIP
+	select SND_SOC_GENERIC_DMAENGINE_PCM
+	help
+	  Say Y or M if you want to add support for SPDIF driver for
+	  Rockchip SPDIF transceiver device.
+
 config SND_SOC_ROCKCHIP_MAX98090
 	tristate "ASoC support for Rockchip boards using a MAX98090 codec"
 	depends on SND_SOC_ROCKCHIP && I2C && GPIOLIB
diff --git a/sound/soc/rockchip/Makefile b/sound/soc/rockchip/Makefile
index 1bc1dc3..9a244d7 100644
--- a/sound/soc/rockchip/Makefile
+++ b/sound/soc/rockchip/Makefile
@@ -1,7 +1,9 @@
 # ROCKCHIP Platform Support
 snd-soc-i2s-objs := rockchip_i2s.o
+snd-soc-spdif-objs := rockchip_spdif.o
 
 obj-$(CONFIG_SND_SOC_ROCKCHIP_I2S) += snd-soc-i2s.o
+obj-$(CONFIG_SND_SOC_ROCKCHIP_SPDIF) += snd-soc-spdif.o
 
 snd-soc-rockchip-max98090-objs := rockchip_max98090.o
 snd-soc-rockchip-rt5645-objs := rockchip_rt5645.o
diff --git a/sound/soc/rockchip/rockchip_spdif.c b/sound/soc/rockchip/rockchip_spdif.c
new file mode 100644
index 0000000..39d33c0
--- /dev/null
+++ b/sound/soc/rockchip/rockchip_spdif.c
@@ -0,0 +1,381 @@
+/* sound/soc/rockchip/rk_spdif.c
+ *
+ * ALSA SoC Audio Layer - Rockchip I2S Controller driver
+ *
+ * Copyright (c) 2014 Rockchip Electronics Co. Ltd.
+ * Author: Jianqun <jay.xu at rock-chips.com>
+ * Copyright (c) 2015 Collabora Ltd.
+ * Author: Sjoerd Simons <sjoerd.simons at collabora.co.uk>
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License version 2 as
+ * published by the Free Software Foundation.
+ */
+
+#include <linux/module.h>
+#include <linux/delay.h>
+#include <linux/of_gpio.h>
+#include <linux/clk.h>
+#include <linux/pm_runtime.h>
+#include <linux/regmap.h>
+#include <sound/pcm_params.h>
+#include <sound/dmaengine_pcm.h>
+
+#include "rockchip_spdif.h"
+
+struct rk_spdif_dev {
+	struct device *dev;
+
+	struct clk *mclk;
+	struct clk *hclk;
+
+	struct snd_dmaengine_dai_dma_data playback_dma_data;
+
+	struct regmap *regmap;
+};
+
+static int rk_spdif_runtime_suspend(struct device *dev)
+{
+	struct rk_spdif_dev *spdif = dev_get_drvdata(dev);
+
+	clk_disable_unprepare(spdif->mclk);
+
+	return 0;
+}
+
+static int rk_spdif_runtime_resume(struct device *dev)
+{
+	struct rk_spdif_dev *spdif = dev_get_drvdata(dev);
+	int ret;
+
+	ret = clk_prepare_enable(spdif->mclk);
+	if (ret) {
+		dev_err(spdif->dev, "clock enable failed %d\n", ret);
+		return ret;
+	}
+
+	return 0;
+}
+
+static inline struct rk_spdif_dev *to_info(struct snd_soc_dai *dai)
+{
+	return snd_soc_dai_get_drvdata(dai);
+}
+
+static int rk_spdif_snd_txctrl(struct rk_spdif_dev *spdif, int on)
+{
+	int ret;
+
+	if (on) {
+		ret = regmap_update_bits(spdif->regmap, SPDIF_DMACR,
+				   SPDIF_DMACR_TDE_ENABLE,
+				   SPDIF_DMACR_TDE_ENABLE);
+
+		if (ret != 0)
+			goto bail;
+
+		ret = regmap_update_bits(spdif->regmap, SPDIF_XFER,
+				   SPDIF_XFER_TXS_START,
+				   SPDIF_XFER_TXS_START);
+	} else {
+		ret = regmap_update_bits(spdif->regmap, SPDIF_DMACR,
+				   SPDIF_DMACR_TDE_ENABLE,
+				   SPDIF_DMACR_TDE_DISABLE);
+
+		if (ret != 0)
+			goto bail;
+
+		ret = regmap_update_bits(spdif->regmap, SPDIF_XFER,
+				   SPDIF_XFER_TXS_START,
+				   SPDIF_XFER_TXS_STOP);
+	}
+
+bail:
+	return ret;
+}
+
+static int rk_spdif_hw_params(struct snd_pcm_substream *substream,
+				  struct snd_pcm_hw_params *params,
+				  struct snd_soc_dai *dai)
+{
+	struct rk_spdif_dev *spdif = to_info(dai);
+	unsigned int val = SPDIF_CFGR_HALFWORD_ENABLE;
+	int srate, mclk;
+
+	srate = params_rate(params);
+	switch (srate) {
+	case 32000:
+	case 48000:
+	case 96000:
+		mclk = 12288000;
+		break;
+	case 44100:
+		mclk = 11289600;
+		break;
+	default:
+		return -EINVAL;
+	}
+
+	switch (params_format(params)) {
+	case SNDRV_PCM_FORMAT_S16_LE:
+		val |= SPDIF_CFGR_VDW_16;
+		break;
+	case SNDRV_PCM_FORMAT_S20_3LE:
+		val |= SPDIF_CFGR_VDW_20;
+		break;
+	case SNDRV_PCM_FORMAT_S24_LE:
+		val |= SPDIF_CFGR_VDW_24;
+		break;
+	default:
+		return -EINVAL;
+	}
+
+	/* Set clock and calculate divider */
+	clk_set_rate(spdif->mclk, mclk);
+	val |= SPDIF_CFGR_CLK_DIV(mclk/(srate * 256));
+
+	return regmap_update_bits(spdif->regmap, SPDIF_CFGR,
+		SPDIF_CFGR_CLK_DIV_MASK | SPDIF_CFGR_HALFWORD_ENABLE |
+		SDPIF_CFGR_VDW_MASK,
+		val);
+}
+
+static int rk_spdif_trigger(struct snd_pcm_substream *substream,
+				int cmd, struct snd_soc_dai *dai)
+{
+	struct rk_spdif_dev *spdif = to_info(dai);
+	int ret;
+
+	switch (cmd) {
+	case SNDRV_PCM_TRIGGER_START:
+	case SNDRV_PCM_TRIGGER_RESUME:
+	case SNDRV_PCM_TRIGGER_PAUSE_RELEASE:
+		ret = rk_spdif_snd_txctrl(spdif, true);
+		break;
+	case SNDRV_PCM_TRIGGER_SUSPEND:
+	case SNDRV_PCM_TRIGGER_STOP:
+	case SNDRV_PCM_TRIGGER_PAUSE_PUSH:
+		ret = rk_spdif_snd_txctrl(spdif, false);
+		break;
+	default:
+		ret = -EINVAL;
+		break;
+	}
+
+	return ret;
+}
+
+static int rk_spdif_dai_probe(struct snd_soc_dai *dai)
+{
+	struct rk_spdif_dev *spdif = snd_soc_dai_get_drvdata(dai);
+
+	dai->playback_dma_data = &spdif->playback_dma_data;
+
+	return 0;
+}
+
+static const struct snd_soc_dai_ops rk_spdif_dai_ops = {
+	.hw_params = rk_spdif_hw_params,
+	.trigger = rk_spdif_trigger,
+};
+
+static struct snd_soc_dai_driver rk_spdif_dai = {
+	.probe = rk_spdif_dai_probe,
+	.playback = {
+		.stream_name = "Playback",
+		.channels_min = 2,
+		.channels_max = 2,
+		.rates = (SNDRV_PCM_RATE_32000 |
+			  SNDRV_PCM_RATE_44100 |
+			  SNDRV_PCM_RATE_48000 |
+			  SNDRV_PCM_RATE_96000),
+		.formats = (SNDRV_PCM_FMTBIT_S16_LE |
+			    SNDRV_PCM_FMTBIT_S20_3LE |
+			    SNDRV_PCM_FMTBIT_S24_LE),
+	},
+	.ops = &rk_spdif_dai_ops,
+};
+
+static const struct snd_soc_component_driver rk_spdif_component = {
+	.name = "rockchip-spdif",
+};
+
+static bool rk_spdif_wr_reg(struct device *dev, unsigned int reg)
+{
+	switch (reg) {
+	case SPDIF_CFGR:
+	case SPDIF_DMACR:
+	case SPDIF_INTCR:
+	case SPDIF_XFER:
+	case SPDIF_SMPDR:
+		return true;
+	default:
+		return false;
+	}
+}
+
+static bool rk_spdif_rd_reg(struct device *dev, unsigned int reg)
+{
+	switch (reg) {
+	case SPDIF_CFGR:
+	case SPDIF_SDBLR:
+	case SPDIF_INTCR:
+	case SPDIF_INTSR:
+	case SPDIF_XFER:
+		return true;
+	default:
+		return false;
+	}
+}
+
+static bool rk_spdif_volatile_reg(struct device *dev, unsigned int reg)
+{
+	switch (reg) {
+	case SPDIF_INTSR:
+	case SPDIF_SDBLR:
+		return true;
+	default:
+		return false;
+	}
+}
+
+static const struct regmap_config rk_spdif_regmap_config = {
+	.reg_bits = 32,
+	.reg_stride = 4,
+	.val_bits = 32,
+	.max_register = SPDIF_SMPDR,
+	.writeable_reg = rk_spdif_wr_reg,
+	.readable_reg = rk_spdif_rd_reg,
+	.volatile_reg = rk_spdif_volatile_reg,
+	.cache_type = REGCACHE_FLAT,
+};
+
+static int rk_spdif_probe(struct platform_device *pdev)
+{
+	struct rk_spdif_dev *spdif;
+	struct resource *res;
+	void __iomem *regs;
+	int ret;
+
+	spdif = devm_kzalloc(&pdev->dev, sizeof(*spdif), GFP_KERNEL);
+	if (!spdif)
+		return -ENOMEM;
+
+	spdif->hclk = devm_clk_get(&pdev->dev, "spdif_hclk");
+	if (IS_ERR(spdif->hclk)) {
+		dev_err(&pdev->dev, "Can't retrieve rk_spdif bus clock\n");
+		return PTR_ERR(spdif->hclk);
+	}
+	ret = clk_prepare_enable(spdif->hclk);
+	if (ret) {
+		dev_err(spdif->dev, "hclock enable failed %d\n", ret);
+		return ret;
+	}
+
+	spdif->mclk = devm_clk_get(&pdev->dev, "spdif_clk");
+	if (IS_ERR(spdif->mclk)) {
+		dev_err(&pdev->dev, "Can't retrieve rk_spdif master clock\n");
+		return PTR_ERR(spdif->hclk);
+	}
+
+	ret = clk_prepare_enable(spdif->mclk);
+	if (ret) {
+		dev_err(spdif->dev, "clock enable failed %d\n", ret);
+		return ret;
+	}
+
+	res = platform_get_resource(pdev, IORESOURCE_MEM, 0);
+	regs = devm_ioremap_resource(&pdev->dev, res);
+	if (IS_ERR(regs))
+		return PTR_ERR(regs);
+
+	spdif->regmap = devm_regmap_init_mmio(&pdev->dev, regs,
+					    &rk_spdif_regmap_config);
+	if (IS_ERR(spdif->regmap)) {
+		dev_err(&pdev->dev,
+			"Failed to initialise managed register map\n");
+		return PTR_ERR(spdif->regmap);
+	}
+
+	spdif->playback_dma_data.addr = res->start + SPDIF_SMPDR;
+	spdif->playback_dma_data.addr_width = DMA_SLAVE_BUSWIDTH_4_BYTES;
+	spdif->playback_dma_data.maxburst = 4;
+
+	spdif->dev = &pdev->dev;
+	dev_set_drvdata(&pdev->dev, spdif);
+
+	pm_runtime_enable(&pdev->dev);
+	if (!pm_runtime_enabled(&pdev->dev)) {
+		ret = rk_spdif_runtime_resume(&pdev->dev);
+		if (ret)
+			goto err_pm_disable;
+	}
+
+	ret = devm_snd_soc_register_component(&pdev->dev,
+					      &rk_spdif_component,
+					      &rk_spdif_dai, 1);
+	if (ret) {
+		dev_err(&pdev->dev, "Could not register DAI\n");
+		goto err_suspend;
+	}
+
+	ret = snd_dmaengine_pcm_register(&pdev->dev, NULL, 0);
+	if (ret) {
+		dev_err(&pdev->dev, "Could not register PCM\n");
+		goto err_pcm_register;
+	}
+
+	return 0;
+
+err_pcm_register:
+	snd_dmaengine_pcm_unregister(&pdev->dev);
+err_suspend:
+	if (!pm_runtime_status_suspended(&pdev->dev))
+		rk_spdif_runtime_suspend(&pdev->dev);
+err_pm_disable:
+	pm_runtime_disable(&pdev->dev);
+
+	return ret;
+}
+
+static int rk_spdif_remove(struct platform_device *pdev)
+{
+	struct rk_spdif_dev *spdif = dev_get_drvdata(&pdev->dev);
+
+	pm_runtime_disable(&pdev->dev);
+	if (!pm_runtime_status_suspended(&pdev->dev))
+		rk_spdif_runtime_suspend(&pdev->dev);
+
+	clk_disable_unprepare(spdif->mclk);
+	clk_disable_unprepare(spdif->hclk);
+	snd_dmaengine_pcm_unregister(&pdev->dev);
+	snd_soc_unregister_component(&pdev->dev);
+
+	return 0;
+}
+
+static const struct of_device_id rk_spdif_match[] = {
+	{ .compatible = "rockchip,rk3066-spdif", },
+	{},
+};
+MODULE_DEVICE_TABLE(of, rk_spdif_match);
+
+static const struct dev_pm_ops rk_spdif_pm_ops = {
+	SET_RUNTIME_PM_OPS(rk_spdif_runtime_suspend, rk_spdif_runtime_resume,
+			   NULL)
+};
+
+static struct platform_driver rk_spdif_driver = {
+	.probe = rk_spdif_probe,
+	.remove = rk_spdif_remove,
+	.driver = {
+		.name = "rockchip-spdif",
+		.of_match_table = of_match_ptr(rk_spdif_match),
+		.pm = &rk_spdif_pm_ops,
+	},
+};
+module_platform_driver(rk_spdif_driver);
+
+MODULE_DESCRIPTION("ROCKCHIP SPDIF transceiver Interface");
+MODULE_AUTHOR("Sjoerd Simons <sjoerd.simons at collabora.co.uk>");
+MODULE_LICENSE("GPL v2");
diff --git a/sound/soc/rockchip/rockchip_spdif.h b/sound/soc/rockchip/rockchip_spdif.h
new file mode 100644
index 0000000..07f86a2
--- /dev/null
+++ b/sound/soc/rockchip/rockchip_spdif.h
@@ -0,0 +1,63 @@
+/*
+ * ALSA SoC Audio Layer - Rockchip SPDIF transceiver driver
+ *
+ * Copyright (c) 2015 Collabora Ltd.
+ * Author: Sjoerd Simons <sjoerd.simons at collabora.co.uk>
+ *
+ * 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.
+ */
+
+#ifndef _ROCKCHIP_SPDIF_H
+#define _ROCKCHIP_SPDIF_H
+
+/*
+ * CFGR
+ * transfer configuration register
+*/
+#define SPDIF_CFGR_CLK_DIV_SHIFT	(16)
+#define SPDIF_CFGR_CLK_DIV_MASK		(0xff << SPDIF_CFGR_CLK_DIV_SHIFT)
+#define SPDIF_CFGR_CLK_DIV(x)		(x << SPDIF_CFGR_CLK_DIV_SHIFT)
+
+#define SPDIF_CFGR_HALFWORD_SHIFT	2
+#define SPDIF_CFGR_HALFWORD_DISABLE	(0 << SPDIF_CFGR_HALFWORD_SHIFT)
+#define SPDIF_CFGR_HALFWORD_ENABLE	(1 << SPDIF_CFGR_HALFWORD_SHIFT)
+
+#define SPDIF_CFGR_VDW_SHIFT	0
+#define SPDIF_CFGR_VDW(x)	(x << SPDIF_CFGR_VDW_SHIFT)
+#define SDPIF_CFGR_VDW_MASK	(0xf << SPDIF_CFGR_VDW_SHIFT)
+
+#define SPDIF_CFGR_VDW_16	SPDIF_CFGR_VDW(0x00)
+#define SPDIF_CFGR_VDW_20	SPDIF_CFGR_VDW(0x01)
+#define SPDIF_CFGR_VDW_24	SPDIF_CFGR_VDW(0x10)
+
+/*
+ * DMACR
+ * DMA control register
+*/
+#define SPDIF_DMACR_TDE_SHIFT	5
+#define SPDIF_DMACR_TDE_DISABLE	(0 << SPDIF_DMACR_TDE_SHIFT)
+#define SPDIF_DMACR_TDE_ENABLE	(1 << SPDIF_DMACR_TDE_SHIFT)
+
+#define SPDIF_DMACR_TDL_SHIFT	0
+#define SPDIF_DMACR_TDL(x)	((x) << SPDIF_DMACR_TDL_SHIFT)
+#define SPDIF_DMACR_TDL_MASK	(0x1f << SDPIF_DMACR_TDL_SHIFT)
+
+/*
+ * XFER
+ * Transfer control register
+*/
+#define SPDIF_XFER_TXS_SHIFT	0
+#define SPDIF_XFER_TXS_STOP	(0 << SPDIF_XFER_TXS_SHIFT)
+#define SPDIF_XFER_TXS_START	(1 << SPDIF_XFER_TXS_SHIFT)
+
+#define SPDIF_CFGR	(0x0000)
+#define SPDIF_SDBLR	(0x0004)
+#define SPDIF_DMACR	(0x0008)
+#define SPDIF_INTCR	(0x000c)
+#define SPDIF_INTSR	(0x0010)
+#define SPDIF_XFER	(0x0018)
+#define SPDIF_SMPDR	(0x0020)
+
+#endif /* _ROCKCHIP_SPDIF_H */
-- 
2.5.0



From pbrobinson at gmail.com  Fri Aug  7 04:48:26 2015
From: pbrobinson at gmail.com (Peter Robinson)
Date: Fri, 7 Aug 2015 12:48:26 +0100
Subject: [PATCH 0/4] omap: Fix broken pbias device creation
In-Reply-To: <20150805100009.GY16878@atomide.com>
References: <1437999401-3519-1-git-send-email-kishon@ti.com>
 <55B89590.6000109@ti.com> <20150805100009.GY16878@atomide.com>
Message-ID: <CALeDE9OBjESdkXhkAEVj1L-XKJ1yoFg8rkHvcJ_Uj_RXOC-yUQ@mail.gmail.com>

On Wed, Aug 5, 2015 at 11:00 AM, Tony Lindgren <tony at atomide.com> wrote:
> * Grygorii Strashko <grygorii.strashko at ti.com> [150729 02:01]:
>> On 07/27/2015 03:16 PM, Kishon Vijay Abraham I wrote:
>> >pbias device creation got broken once SCM cleanup got merged.
>> >This patch series re-enables device creation by adding
>> >"simple-bus" in the compatible property of the syscon
>> >dt node.
>> >
>> >validated this series in DRA72, OMAP4 PANDA and OMAP5 UEVM
>> >boards.
>> >
>> >Kishon Vijay Abraham I (4):
>> >   ARM: dts: omap24xx: Fix broken pbias device creation
>> >   ARM: dts: OMAP4: Fix broken pbias device creation
>> >   ARM: dts: OMAP5: Fix broken pbias device creation
>> >   ARM: dts: dra7: Fix broken pbias device creation
>> >
>> >  arch/arm/boot/dts/dra7.dtsi     |    2 +-
>> >  arch/arm/boot/dts/omap2430.dtsi |    3 ++-
>> >  arch/arm/boot/dts/omap4.dtsi    |    3 ++-
>> >  arch/arm/boot/dts/omap5.dtsi    |    3 ++-
>> >  4 files changed, 7 insertions(+), 4 deletions(-)
>> >
>>
>> For dra7-evm:
>> Tested-by: Grygorii Strashko <grygorii.strashko at ti.com>
>
> Applying all into omap-for-v4.2fixes-v2 thanks.

Do we need the same for am33xx.dtsi too given commit e3bc5358e097 ?

Peter


From b.zolnierkie at samsung.com  Fri Aug  7 04:47:26 2015
From: b.zolnierkie at samsung.com (Bartlomiej Zolnierkiewicz)
Date: Fri, 07 Aug 2015 13:47:26 +0200
Subject: [PATCH v4 0/6] cpufreq: use generic cpufreq drivers for Exynos4x12
 platform
In-Reply-To: <20150807113950.GG6939@linux>
References: <1438868514-8814-1-git-send-email-b.zolnierkie@samsung.com>
 <2061119.GBaoSb4YSL@amdc1976> <20150807113950.GG6939@linux>
Message-ID: <2359635.Hxe4cb8zKm@amdc1976>

On Friday, August 07, 2015 05:09:50 PM Viresh Kumar wrote:
> On 07-08-15, 13:31, Bartlomiej Zolnierkiewicz wrote:
> > Users don't need to enable the config option to get boost
> > functionality working.  It is only needed to get scaling_boost_freqs
> > sysfs attribute visible (which lists available boost freqs) when
> > using cpufreq-dt driver.  Also the config option in question is not
> > user visible.
> 
> By users I meant the people who will prepare the build images for the
> release. They can just enable the config option :)

OK.

> > The worst thing that happens if these 2 PM patches don't make it
> > in time is that there will be no scaling_boost_freqs available
> > when using cpufreq-dt driver.  Which is not very important from
> > Exynos4x12 POV as it only supports single boost freq currently.
> 
> Right. So, now that your patch is Acked, send 1/6 and 6/6 separately
> to pm-list and Rafael can get them merged himself..
> 
> I hope, your 6/6 patch will change a bit now ?

Hmm, wait.  Patch 6/6 depends on earlier changes.  I cannot remove
the config option in question now as it is currently used by
exynos-cpufreq specific boost support.  Patch 1/6 can be applied
now but 6/6 needs to wait for patches 2-5 to be applied first.

Actually 6/6 is trivial and can be applied later in v4.3 cycle or
even in v4.4 one.

Best regards,
--
Bartlomiej Zolnierkiewicz
Samsung R&D Institute Poland
Samsung Electronics



From b.zolnierkie at samsung.com  Fri Aug  7 04:50:30 2015
From: b.zolnierkie at samsung.com (Bartlomiej Zolnierkiewicz)
Date: Fri, 07 Aug 2015 13:50:30 +0200
Subject: [PATCH] cpufreq-dt: make scaling_boost_freqs sysfs attr available when
 boost is enabled
Message-ID: <4591050.xDpgbpsIAB@amdc1976>

Make scaling_boost_freqs sysfs attribute is available when
cpufreq-dt driver is used and boost support is enabled.

Cc: Thomas Abraham <thomas.ab at samsung.com>
Cc: Javier Martinez Canillas <javier at osg.samsung.com>
Cc: Krzysztof Kozlowski <k.kozlowski at samsung.com>
Suggested-by: Viresh Kumar <viresh.kumar at linaro.org>
Acked-by: Viresh Kumar <viresh.kumar at linaro.org>
Signed-off-by: Bartlomiej Zolnierkiewicz <b.zolnierkie at samsung.com>
---
Rafael, please apply for v4.3.  Thanks!

 drivers/cpufreq/cpufreq-dt.c | 11 ++++++++++-
 include/linux/cpufreq.h      |  1 +
 2 files changed, 11 insertions(+), 1 deletion(-)

diff --git a/drivers/cpufreq/cpufreq-dt.c b/drivers/cpufreq/cpufreq-dt.c
index b9259ab..c6a3b98 100644
--- a/drivers/cpufreq/cpufreq-dt.c
+++ b/drivers/cpufreq/cpufreq-dt.c
@@ -36,6 +36,12 @@ struct private_data {
 	unsigned int voltage_tolerance; /* in percentage */
 };
 
+static struct freq_attr *cpufreq_dt_attr[] = {
+	&cpufreq_freq_attr_scaling_available_freqs,
+	NULL,   /* Extra space for boost-attr if required */
+	NULL,
+};
+
 static int set_target(struct cpufreq_policy *policy, unsigned int index)
 {
 	struct dev_pm_opp *opp;
@@ -182,6 +188,8 @@ try_again:
 	return ret;
 }
 
+static struct cpufreq_driver dt_cpufreq_driver;
+
 static int cpufreq_init(struct cpufreq_policy *policy)
 {
 	struct cpufreq_frequency_table *freq_table;
@@ -336,6 +344,7 @@ static int cpufreq_init(struct cpufreq_policy *policy)
 		ret = cpufreq_enable_boost_support();
 		if (ret)
 			goto out_free_cpufreq_table;
+		cpufreq_dt_attr[1] = &cpufreq_freq_attr_scaling_boost_freqs;
 	}
 
 	policy->cpuinfo.transition_latency = transition_latency;
@@ -411,7 +420,7 @@ static struct cpufreq_driver dt_cpufreq_driver = {
 	.exit = cpufreq_exit,
 	.ready = cpufreq_ready,
 	.name = "cpufreq-dt",
-	.attr = cpufreq_generic_attr,
+	.attr = cpufreq_dt_attr,
 };
 
 static int dt_cpufreq_probe(struct platform_device *pdev)
diff --git a/include/linux/cpufreq.h b/include/linux/cpufreq.h
index 95f0186..657542d 100644
--- a/include/linux/cpufreq.h
+++ b/include/linux/cpufreq.h
@@ -609,6 +609,7 @@ struct cpufreq_frequency_table *cpufreq_frequency_get_table(unsigned int cpu);
 
 /* the following are really really optional */
 extern struct freq_attr cpufreq_freq_attr_scaling_available_freqs;
+extern struct freq_attr cpufreq_freq_attr_scaling_boost_freqs;
 extern struct freq_attr *cpufreq_generic_attr[];
 int cpufreq_table_validate_and_show(struct cpufreq_policy *policy,
 				      struct cpufreq_frequency_table *table);
-- 
1.9.1




From viresh.kumar at linaro.org  Fri Aug  7 04:56:27 2015
From: viresh.kumar at linaro.org (Viresh Kumar)
Date: Fri, 7 Aug 2015 17:26:27 +0530
Subject: [PATCH v4 0/6] cpufreq: use generic cpufreq drivers for
 Exynos4x12 platform
In-Reply-To: <2359635.Hxe4cb8zKm@amdc1976>
References: <1438868514-8814-1-git-send-email-b.zolnierkie@samsung.com>
 <2061119.GBaoSb4YSL@amdc1976> <20150807113950.GG6939@linux>
 <2359635.Hxe4cb8zKm@amdc1976>
Message-ID: <20150807115627.GH6939@linux>

On 07-08-15, 13:47, Bartlomiej Zolnierkiewicz wrote:
> Hmm, wait.  Patch 6/6 depends on earlier changes.  I cannot remove
> the config option in question now as it is currently used by
> exynos-cpufreq specific boost support.  Patch 1/6 can be applied
> now but 6/6 needs to wait for patches 2-5 to be applied first.
> 
> Actually 6/6 is trivial and can be applied later in v4.3 cycle or
> even in v4.4 one.

Ack.

-- 
viresh


From robert.richter at caviumnetworks.com  Fri Aug  7 04:56:22 2015
From: robert.richter at caviumnetworks.com (Robert Richter)
Date: Fri, 7 Aug 2015 13:56:22 +0200
Subject: [PATCH 2/2] net, thunder, bgx: Add support for ACPI binding.
In-Reply-To: <55C48DF9.70406@linaro.org>
References: <1438907590-29649-1-git-send-email-ddaney.cavm@gmail.com>
 <1438907590-29649-3-git-send-email-ddaney.cavm@gmail.com>
 <55C467A0.4020601@linaro.org>
 <20150807104320.GQ1820@rric.localhost> <55C48DF9.70406@linaro.org>
Message-ID: <20150807115622.GS4914@rric.localhost>

On 07.08.15 12:52:41, Tomasz Nowicki wrote:
> On 07.08.2015 12:43, Robert Richter wrote:
> >On 07.08.15 10:09:04, Tomasz Nowicki wrote:
> >>On 07.08.2015 02:33, David Daney wrote:
> >
> >...
> >
> >>>+#else
> >>>+
> >>>+static int bgx_init_acpi_phy(struct bgx *bgx)
> >>>+{
> >>>+	return -ENODEV;
> >>>+}
> >>>+
> >>>+#endif /* CONFIG_ACPI */
> >>>+
> >>>  #if IS_ENABLED(CONFIG_OF_MDIO)
> >>>
> >>>  static int bgx_init_of_phy(struct bgx *bgx)
> >>>@@ -882,7 +1010,12 @@ static int bgx_init_of_phy(struct bgx *bgx)
> >>>
> >>>  static int bgx_init_phy(struct bgx *bgx)
> >>>  {
> >>>-	return bgx_init_of_phy(bgx);
> >>>+	int err = bgx_init_of_phy(bgx);
> >>>+
> >>>+	if (err != -ENODEV)
> >>>+		return err;
> >>>+
> >>>+	return bgx_init_acpi_phy(bgx);
> >>>  }
> >>>
> >>
> >>If kernel can work with DT and ACPI (both compiled in), it should take only
> >>one path instead of probing DT and ACPI sequentially. How about:
> >>
> >>@@ -902,10 +925,9 @@ static int bgx_probe(struct pci_dev *pdev, const struct
> >>pci_device_id *ent)
> >>  	bgx_vnic[bgx->bgx_id] = bgx;
> >>  	bgx_get_qlm_mode(bgx);
> >>
> >>-	snprintf(bgx_sel, 5, "bgx%d", bgx->bgx_id);
> >>-	np = of_find_node_by_name(NULL, bgx_sel);
> >>-	if (np)
> >>-		bgx_init_of(bgx, np);
> >>+	err = acpi_disabled ? bgx_init_of_phy(bgx) : bgx_init_acpi_phy(bgx);
> >>+	if (err)
> >>+		goto err_enable;
> >>
> >>  	bgx_init_hw(bgx);
> >
> >I would not pollute bgx_probe() with acpi and dt specifics, and instead
> >keep bgx_init_phy(). The typical design pattern for this is:
> >
> >static int bgx_init_phy(struct bgx *bgx)
> >{
> >#ifdef CONFIG_ACPI
> >         if (!acpi_disabled)
> >                 return bgx_init_acpi_phy(bgx);
> >#endif
> >         return bgx_init_of_phy(bgx);
> >}
> >
> >This adds acpi runtime detection (acpi=no), does not call dt code in
> >case of acpi, and saves the #else for bgx_init_acpi_phy().
> >
> 
> I am fine with keeping it in bgx_init_phy(), however we can drop there
> #ifdefs since both of bgx_init_{acpi,of}_phy calls have empty stub for !ACPI
> and !OF case. Like that:
> 
> static int bgx_init_phy(struct bgx *bgx)
> {
> 
>         if (!acpi_disabled)
>                 return bgx_init_acpi_phy(bgx);
> 	else
>         	return bgx_init_of_phy(bgx);
> }

As said, keeping it in #ifdefs makes the empty stub function for !acpi
obsolete, which makes the code smaller and better readable. This style
is common practice in the kernel. Apart from that, the 'else' should
be dropped as it is useless.

-Robert


From b.zolnierkie at samsung.com  Fri Aug  7 04:56:04 2015
From: b.zolnierkie at samsung.com (Bartlomiej Zolnierkiewicz)
Date: Fri, 07 Aug 2015 13:56:04 +0200
Subject: [PATCH v2] cpufreq-dt: make scaling_boost_freqs sysfs attr available
 when boost is enabled
Message-ID: <3835403.gWyHpfh1Gz@amdc1976>

Make scaling_boost_freqs sysfs attribute is available when
cpufreq-dt driver is used and boost support is enabled.

Cc: Thomas Abraham <thomas.ab at samsung.com>
Cc: Javier Martinez Canillas <javier at osg.samsung.com>
Cc: Krzysztof Kozlowski <k.kozlowski at samsung.com>
Suggested-by: Viresh Kumar <viresh.kumar at linaro.org>
Signed-off-by: Bartlomiej Zolnierkiewicz <b.zolnierkie at samsung.com>
---
v2: Removed leftover prototype.

 drivers/cpufreq/cpufreq-dt.c | 9 ++++++++-
 include/linux/cpufreq.h      | 1 +
 2 files changed, 9 insertions(+), 1 deletion(-)

diff --git a/drivers/cpufreq/cpufreq-dt.c b/drivers/cpufreq/cpufreq-dt.c
index b9259ab..c3583cd 100644
--- a/drivers/cpufreq/cpufreq-dt.c
+++ b/drivers/cpufreq/cpufreq-dt.c
@@ -36,6 +36,12 @@ struct private_data {
 	unsigned int voltage_tolerance; /* in percentage */
 };
 
+static struct freq_attr *cpufreq_dt_attr[] = {
+	&cpufreq_freq_attr_scaling_available_freqs,
+	NULL,   /* Extra space for boost-attr if required */
+	NULL,
+};
+
 static int set_target(struct cpufreq_policy *policy, unsigned int index)
 {
 	struct dev_pm_opp *opp;
@@ -336,6 +342,7 @@ static int cpufreq_init(struct cpufreq_policy *policy)
 		ret = cpufreq_enable_boost_support();
 		if (ret)
 			goto out_free_cpufreq_table;
+		cpufreq_dt_attr[1] = &cpufreq_freq_attr_scaling_boost_freqs;
 	}
 
 	policy->cpuinfo.transition_latency = transition_latency;
@@ -411,7 +418,7 @@ static struct cpufreq_driver dt_cpufreq_driver = {
 	.exit = cpufreq_exit,
 	.ready = cpufreq_ready,
 	.name = "cpufreq-dt",
-	.attr = cpufreq_generic_attr,
+	.attr = cpufreq_dt_attr,
 };
 
 static int dt_cpufreq_probe(struct platform_device *pdev)
diff --git a/include/linux/cpufreq.h b/include/linux/cpufreq.h
index 95f0186..657542d 100644
--- a/include/linux/cpufreq.h
+++ b/include/linux/cpufreq.h
@@ -609,6 +609,7 @@ struct cpufreq_frequency_table *cpufreq_frequency_get_table(unsigned int cpu);
 
 /* the following are really really optional */
 extern struct freq_attr cpufreq_freq_attr_scaling_available_freqs;
+extern struct freq_attr cpufreq_freq_attr_scaling_boost_freqs;
 extern struct freq_attr *cpufreq_generic_attr[];
 int cpufreq_table_validate_and_show(struct cpufreq_policy *policy,
 				      struct cpufreq_frequency_table *table);
-- 
1.9.1




From b.zolnierkie at samsung.com  Fri Aug  7 04:59:16 2015
From: b.zolnierkie at samsung.com (Bartlomiej Zolnierkiewicz)
Date: Fri, 07 Aug 2015 13:59:16 +0200
Subject: [PATCH v3] cpufreq-dt: make scaling_boost_freqs sysfs attr available
 when boost is enabled
Message-ID: <2130756.euuUs9t9I5@amdc1976>

Make scaling_boost_freqs sysfs attribute is available when
cpufreq-dt driver is used and boost support is enabled.

Cc: Thomas Abraham <thomas.ab at samsung.com>
Cc: Javier Martinez Canillas <javier at osg.samsung.com>
Cc: Krzysztof Kozlowski <k.kozlowski at samsung.com>
Suggested-by: Viresh Kumar <viresh.kumar at linaro.org>
Acked-by: Viresh Kumar <viresh.kumar at linaro.org>
Signed-off-by: Bartlomiej Zolnierkiewicz <b.zolnierkie at samsung.com>
---
v2: Removed leftover prototype.
v3: added missing Acked-by
Sorry for two resends, this is not my day..
Rafael, please apply for v4.3.

 drivers/cpufreq/cpufreq-dt.c | 9 ++++++++-
 include/linux/cpufreq.h      | 1 +
 2 files changed, 9 insertions(+), 1 deletion(-)

diff --git a/drivers/cpufreq/cpufreq-dt.c b/drivers/cpufreq/cpufreq-dt.c
index b9259ab..c3583cd 100644
--- a/drivers/cpufreq/cpufreq-dt.c
+++ b/drivers/cpufreq/cpufreq-dt.c
@@ -36,6 +36,12 @@ struct private_data {
 	unsigned int voltage_tolerance; /* in percentage */
 };
 
+static struct freq_attr *cpufreq_dt_attr[] = {
+	&cpufreq_freq_attr_scaling_available_freqs,
+	NULL,   /* Extra space for boost-attr if required */
+	NULL,
+};
+
 static int set_target(struct cpufreq_policy *policy, unsigned int index)
 {
 	struct dev_pm_opp *opp;
@@ -336,6 +342,7 @@ static int cpufreq_init(struct cpufreq_policy *policy)
 		ret = cpufreq_enable_boost_support();
 		if (ret)
 			goto out_free_cpufreq_table;
+		cpufreq_dt_attr[1] = &cpufreq_freq_attr_scaling_boost_freqs;
 	}
 
 	policy->cpuinfo.transition_latency = transition_latency;
@@ -411,7 +418,7 @@ static struct cpufreq_driver dt_cpufreq_driver = {
 	.exit = cpufreq_exit,
 	.ready = cpufreq_ready,
 	.name = "cpufreq-dt",
-	.attr = cpufreq_generic_attr,
+	.attr = cpufreq_dt_attr,
 };
 
 static int dt_cpufreq_probe(struct platform_device *pdev)
diff --git a/include/linux/cpufreq.h b/include/linux/cpufreq.h
index 95f0186..657542d 100644
--- a/include/linux/cpufreq.h
+++ b/include/linux/cpufreq.h
@@ -609,6 +609,7 @@ struct cpufreq_frequency_table *cpufreq_frequency_get_table(unsigned int cpu);
 
 /* the following are really really optional */
 extern struct freq_attr cpufreq_freq_attr_scaling_available_freqs;
+extern struct freq_attr cpufreq_freq_attr_scaling_boost_freqs;
 extern struct freq_attr *cpufreq_generic_attr[];
 int cpufreq_table_validate_and_show(struct cpufreq_policy *policy,
 				      struct cpufreq_frequency_table *table);
-- 
1.9.1




From marc.zyngier at arm.com  Fri Aug  7 05:06:40 2015
From: marc.zyngier at arm.com (Marc Zyngier)
Date: Fri, 07 Aug 2015 13:06:40 +0100
Subject: [PATCH v4 09/10] PCI: ACPI: Bind GIC MSI frame to PCI host bridge
In-Reply-To: <55C4826C.80600@linaro.org>
References: <1438164539-29256-1-git-send-email-hanjun.guo@linaro.org>
 <1438164539-29256-10-git-send-email-hanjun.guo@linaro.org>
 <55C4826C.80600@linaro.org>
Message-ID: <55C49F50.1080903@arm.com>

On 07/08/15 11:03, Tomasz Nowicki wrote:
> On 29.07.2015 12:08, Hanjun Guo wrote:
>> From: Suravee Suthikulpanit <Suravee.Suthikulpanit at amd.com>
>>
>> This patch introduces pci_host_bridge_acpi_msi_domain(), which queries
>> a GIC MSI irq-domain token and use it to retrieve an irq_domain with
>> DOMAIN_BUS_PCI_MSI bus type, and bind it to PCI host-bridge.
>>
>> Signed-off-by: Suravee Suthikulpanit <Suravee.Suthikulpanit at amd.com>
>> Signed-off-by: Hanjun Guo <hanjun.guo at linaro.org>
>> ---
>>   drivers/pci/pci-acpi.c   | 18 ++++++++++++++++++
>>   drivers/pci/probe.c      |  3 +++
>>   include/linux/pci-acpi.h |  4 ++++
>>   3 files changed, 25 insertions(+)
>>
>> diff --git a/drivers/pci/pci-acpi.c b/drivers/pci/pci-acpi.c
>> index 314a625..5f11653 100644
>> --- a/drivers/pci/pci-acpi.c
>> +++ b/drivers/pci/pci-acpi.c
>> @@ -9,6 +9,7 @@
>>
>>   #include <linux/delay.h>
>>   #include <linux/init.h>
>> +#include <linux/irqdomain.h>
>>   #include <linux/pci.h>
>>   #include <linux/pci_hotplug.h>
>>   #include <linux/module.h>
>> @@ -16,6 +17,7 @@
>>   #include <linux/pci-acpi.h>
>>   #include <linux/pm_runtime.h>
>>   #include <linux/pm_qos.h>
>> +#include <acpi/acpi_gic.h>
>>   #include "pci.h"
>>
>>   /*
>> @@ -681,6 +683,22 @@ static bool pci_acpi_bus_match(struct device *dev)
>>   	return dev_is_pci(dev);
>>   }
>>
>> +#ifdef CONFIG_GENERIC_MSI_IRQ_DOMAIN
>> +struct irq_domain *pci_host_bridge_acpi_msi_domain(struct pci_bus *bus)
>> +{
>> +	struct irq_domain *d = NULL;
>> +	void *token = acpi_gic_get_msi_token(&bus->dev);
>> +
>> +	if (token)
>> +		d = irq_find_matching_host(token, DOMAIN_BUS_PCI_MSI);
>> +
>> +	if (!d)
>> +		pr_debug("Fail to find domain for MSI\n");
>> +
>> +	return d;
>> +}
>> +#endif /*CONFIG_GENERIC_MSI_IRQ_DOMAIN*/
>> +
>>   static struct acpi_bus_type acpi_pci_bus = {
>>   	.name = "PCI",
>>   	.match = pci_acpi_bus_match,
>> diff --git a/drivers/pci/probe.c b/drivers/pci/probe.c
>> index a7afeac..8c1204c 100644
>> --- a/drivers/pci/probe.c
>> +++ b/drivers/pci/probe.c
>> @@ -12,6 +12,7 @@
>>   #include <linux/module.h>
>>   #include <linux/cpumask.h>
>>   #include <linux/pci-aspm.h>
>> +#include <linux/pci-acpi.h>
>>   #include <asm-generic/pci-bridge.h>
>>   #include "pci.h"
>>
>> @@ -670,6 +671,8 @@ static struct irq_domain *pci_host_bridge_msi_domain(struct pci_bus *bus)
>>   	 * should be called from here.
>>   	 */
>>   	d = pci_host_bridge_of_msi_domain(bus);
>> +	if (!d)
>> +		d = pci_host_bridge_acpi_msi_domain(bus);
> 
> Please use acpi_disabled here.

No, thanks. pci_host_bridge_acpi_msi_domain() can return NULL if ACPI is
disabled, just like pci_host_bridge_of_msi_domain will return NULL if
there is no domain to be found (or no OF support).

Littering various firmware predicates all over the place hardly seem
like a scalable solution, and I'd expect the ACPI backends to be self
contained.

> BTW. This is another place where we need to know our firmware - DT vs 
> ACPI. I know we can use acpi_disabled but I think more about generic 
> solution. Since we already have:
> struct fwnode_handle	*fwnode;
> we can create macro which identify h/w description style, something like:
> 
> #define FWNODE_TYPE(dev)	dev_fwnode(dev)->type
> 
> and then:
> 
> switch (FWNODE_TYPE(&bus->dev)) {
> case FWNODE_OF:
> ...
> case FWNODE_ACPI:
> ...
> case FWNODE_XXX:
> ...
> }
> 
> Root bus is special case since it has no frimware type but we could 
> factor out pci_set_bus_of_node(). For platform devices we have all we 
> need. Just thinking aloud, let me know your thoughts.

For that to work, we'd need to start converging device_node and
fwnode_handle. Having both feels quite redundant at the moment.

Thanks,

	M.
-- 
Jazz is not dead. It just smells funny...


From broonie at kernel.org  Fri Aug  7 05:07:52 2015
From: broonie at kernel.org (Mark Brown)
Date: Fri, 7 Aug 2015 13:07:52 +0100
Subject: [PATCH v3 05/18] regulator: core: Reduce critical area in
 _regulator_get
In-Reply-To: <1438870315-18689-6-git-send-email-tomeu.vizoso@collabora.com>
References: <1438870315-18689-1-git-send-email-tomeu.vizoso@collabora.com>
 <1438870315-18689-6-git-send-email-tomeu.vizoso@collabora.com>
Message-ID: <20150807120752.GQ20873@sirena.org.uk>

On Thu, Aug 06, 2015 at 04:11:42PM +0200, Tomeu Vizoso wrote:

> This backtrace illustrates the situation described above:
> 
> (regulator_register) from [<c05efe64>]
> (devm_regulator_register+0x48/0x84)

Please don't paste entire backtraces into commit messages, they are
enormous and contain very little useful content - they just obscure
actual information in the commit message.  If you feel there's useful
information in there just include edited highlights with only that.

> +static int _regulator_enable(struct regulator *regulator, bool do_lock)
>  {
> -	int ret;
> +	struct regulator_dev *rdev = regulator->rdev;
> +	int ret = 0;
>  
> -	lockdep_assert_held_once(&rdev->mutex);
> +	if (regulator->always_on)
> +		return 0;
> +
> +	if (rdev->supply) {
> +		ret = regulator_enable(rdev->supply);
> +		if (ret != 0)
> +			return ret;
> +	}
> +
> +	if (do_lock)
> +		mutex_lock(&rdev->mutex);
> +	else
> +		lockdep_assert_held_once(&rdev->mutex);

Eew.  This do_lock stuff is *not* nice and going to be fragile.  I'm not
a fan, we need something better.
-------------- next part --------------
A non-text attachment was scrubbed...
Name: signature.asc
Type: application/pgp-signature
Size: 473 bytes
Desc: Digital signature
URL: <http://lists.infradead.org/pipermail/linux-arm-kernel/attachments/20150807/91a3715c/attachment.sig>

From broonie at kernel.org  Fri Aug  7 05:09:06 2015
From: broonie at kernel.org (Mark Brown)
Date: Fri, 7 Aug 2015 13:09:06 +0100
Subject: [PATCH v3 06/18] regulator: core: Probe regulators on demand
In-Reply-To: <1438870315-18689-7-git-send-email-tomeu.vizoso@collabora.com>
References: <1438870315-18689-1-git-send-email-tomeu.vizoso@collabora.com>
 <1438870315-18689-7-git-send-email-tomeu.vizoso@collabora.com>
Message-ID: <20150807120906.GR20873@sirena.org.uk>

On Thu, Aug 06, 2015 at 04:11:43PM +0200, Tomeu Vizoso wrote:

> When looking up a regulator through its OF node, probe it if it hasn't
> already.
> 
> The goal is to reduce deferred probes to a minimum, as it makes it very
> cumbersome to find out why a device failed to probe, and can introduce
> very big delays in when a critical device is probed.

Still the same problem as we had before with this stuff, why is this DT
only?

>  #include <linux/regulator/consumer.h>
> @@ -1336,6 +1337,7 @@ static struct regulator_dev *regulator_dev_lookup(struct device *dev,
>  	if (dev && dev->of_node) {
>  		node = of_get_regulator(dev, supply);
>  		if (node) {
> +			of_platform_probe(node);

And why the assumption that this is a platform device?
-------------- next part --------------
A non-text attachment was scrubbed...
Name: signature.asc
Type: application/pgp-signature
Size: 473 bytes
Desc: Digital signature
URL: <http://lists.infradead.org/pipermail/linux-arm-kernel/attachments/20150807/6862a5d3/attachment.sig>

From broonie at kernel.org  Fri Aug  7 05:19:13 2015
From: broonie at kernel.org (Mark Brown)
Date: Fri, 7 Aug 2015 13:19:13 +0100
Subject: [PATCH v3 02/18] of/platform: add of_platform_probe
In-Reply-To: <1438870315-18689-3-git-send-email-tomeu.vizoso@collabora.com>
References: <1438870315-18689-1-git-send-email-tomeu.vizoso@collabora.com>
 <1438870315-18689-3-git-send-email-tomeu.vizoso@collabora.com>
Message-ID: <20150807121913.GS20873@sirena.org.uk>

On Thu, Aug 06, 2015 at 04:11:39PM +0200, Tomeu Vizoso wrote:

> Walks the OF tree up and finds the closest ancestor that has a platform
> device associated with it, probing it if isn't bound to a driver yet.

> The above should ensure that the dependency represented by the passed OF
> node is available, because probing a platform device should cause its
> descendants to be probed as well.

This sounds like it's going to break in the case where we have MFDs that
represent their functions in DT (not a pattern I'm a fan of but it's a
thing people do).  We'll walk back to the platform device for the MFD
function, try to probe it and then give up.  Perhaps that's good enough
anyway but it's not clear to me why we don't just try every parent we
find?

I'm also not a fan of the fact that the interface here is explicitly
saying that we want to probe a platform device, that's an implementation
detail that callers shouldn't need to know about.  From the point of
view of the callers what they're trying to do is kick any dependencies
into being instantiated, the fact that we currently try to accomplish it
with platform devices isn't something they care about.
-------------- next part --------------
A non-text attachment was scrubbed...
Name: signature.asc
Type: application/pgp-signature
Size: 473 bytes
Desc: Digital signature
URL: <http://lists.infradead.org/pipermail/linux-arm-kernel/attachments/20150807/90403c12/attachment-0001.sig>

From broonie at kernel.org  Fri Aug  7 05:23:44 2015
From: broonie at kernel.org (Mark Brown)
Date: Fri, 7 Aug 2015 13:23:44 +0100
Subject: next-20150807 build: 2 failures 51 warnings (next-20150807)
In-Reply-To: <E1ZNgYS-0000SE-QL@optimist>
References: <E1ZNgYS-0000SE-QL@optimist>
Message-ID: <20150807122344.GT20873@sirena.org.uk>

On Fri, Aug 07, 2015 at 01:15:20PM +0100, Build bot for Mark Brown wrote:

Today's linux-next fails to build an arm64 allmodconfig with:

> 	arm64-allmodconfig
> ../drivers/firmware/qcom_scm-32.c:27:28: fatal error: asm/outercache.h: No such file or directory

This header file only exists on ARM, either the driver shouldn't be
built for ARMv8, we need a dummy header for ARMv8 or we need to use the
header conditionally in the driver.
-------------- next part --------------
A non-text attachment was scrubbed...
Name: signature.asc
Type: application/pgp-signature
Size: 473 bytes
Desc: Digital signature
URL: <http://lists.infradead.org/pipermail/linux-arm-kernel/attachments/20150807/4e390095/attachment.sig>

From chunfeng.yun at mediatek.com  Fri Aug  7 05:30:41 2015
From: chunfeng.yun at mediatek.com (Chunfeng Yun)
Date: Fri, 7 Aug 2015 20:30:41 +0800
Subject: [PATCH v5 2/5] dt-bindings: Add a binding for Mediatek xHCI host
 controller
In-Reply-To: <1438950644-27290-1-git-send-email-chunfeng.yun@mediatek.com>
References: <1438950644-27290-1-git-send-email-chunfeng.yun@mediatek.com>
Message-ID: <1438950644-27290-3-git-send-email-chunfeng.yun@mediatek.com>

add a DT binding documentation of xHCI host controller for the
MT8173 SoC from Mediatek.

Signed-off-by: Chunfeng Yun <chunfeng.yun at mediatek.com>
---
 .../devicetree/bindings/usb/mt8173-xhci.txt        | 52 ++++++++++++++++++++++
 1 file changed, 52 insertions(+)
 create mode 100644 Documentation/devicetree/bindings/usb/mt8173-xhci.txt

diff --git a/Documentation/devicetree/bindings/usb/mt8173-xhci.txt b/Documentation/devicetree/bindings/usb/mt8173-xhci.txt
new file mode 100644
index 0000000..8e6e463
--- /dev/null
+++ b/Documentation/devicetree/bindings/usb/mt8173-xhci.txt
@@ -0,0 +1,52 @@
+mt65XX xHCI
+
+The device node for Mediatek SOC usb3.0 host controller
+
+Required properties:
+ - compatible : should contain "mediatek,mt8173-xhci"
+ - reg : specifies physical base address and size of the registers,
+	the first one for MAC, the second for IPPC
+ - interrupts : interrupt used by the controller
+ - power-domains : a phandle to USB power domain node to control usb's
+	mtcmos
+ - vusb33-supply : regulator of usb avdd3.3v
+
+ - clocks : a list of phandle + clock-specifier pairs, one for each
+	entry in clock-names
+ - clock-names : must contain
+	"sys_ck": for clock of xHCI MAC
+	"wakeup_deb_p0": for usb wakeup debounce clock of port0
+	"wakeup_deb_p0": for usb wakeup debounce clock of port1
+
+ - phys : a list of phandle + phy specifier pairs
+ - usb3-lpm-capable : supports USB3 LPM
+ - mediatek,syscon-wakeup : phandle to syscon used to access usb wakeup
+	control register
+ - mediatek,wakeup-src : 1: ip sleep wakeup mode; 2: line state wakeup
+	mode; others means don't enable wakeup source of usb
+
+Optional properties:
+ - vbus-supply : Reference to the VBUS regulator;
+
+Example:
+usb30: usb at 11270000 {
+	compatible = "mediatek,mt8173-xhci";
+	reg = <0 0x11270000 0 0x4000>,
+	      <0 0x11280000 0 0x0800>;
+	interrupts = <GIC_SPI 115 IRQ_TYPE_LEVEL_LOW>;
+	power-domains = <&scpsys MT8173_POWER_DOMAIN_USB>;
+	clocks = <&topckgen CLK_TOP_USB30_SEL>,
+		 <&pericfg CLK_PERI_USB0>,
+		 <&pericfg CLK_PERI_USB1>;
+	clock-names = "sys_ck",
+		      "wakeup_deb_p0",
+		      "wakeup_deb_p1";
+	phys = <&phy_port0 PHY_TYPE_USB3>,
+	       <&phy_port1 PHY_TYPE_USB2>;
+	vusb33-supply = <&mt6397_vusb_reg>;
+	vbus-supply = <&usb_p1_vbus>;
+	usb3-lpm-capable;
+	mediatek,syscon-wakeup = <&pericfg>;
+	mediatek,wakeup-src = <1>;
+	status = "okay";
+};
-- 
1.8.1.1.dirty



From chunfeng.yun at mediatek.com  Fri Aug  7 05:30:39 2015
From: chunfeng.yun at mediatek.com (Chunfeng Yun)
Date: Fri, 7 Aug 2015 20:30:39 +0800
Subject: Mediatek xHCI support
Message-ID: <1438950644-27290-1-git-send-email-chunfeng.yun@mediatek.com>

>From 5c00619366ce4e7ff2bad050697dd6b3294f38ec Mon Sep 17 00:00:00 2001
From: Chunfeng Yun <chunfeng.yun at mediatek.com>
Date: Fri, 7 Aug 2015 20:16:42 +0800
Subject: [PATCH v5 0/5]  Mediatek xHCI support

The patch supports MediaTek's xHCI controller.

There are some differences from xHCI spec:
1. The interval is specified in 250 * 8ns increments for Interrupt Moderation
Interval(IMODI) of the Interrupter Moderation(IMOD) register, it is 8 times as
much as that defined in xHCI spec.

2. For the value of TD Size in Normal TRB, MTK's xHCI controller defines a
number of packets that remain to be transferred for a TD after processing all
Max packets in all previous TRBs,that means don't include the current TRB's,
but in xHCI spec it includes the current ones.

3. To minimize the scheduling effort for synchronous endpoints in xHC, the MTK
architecture defines some extra SW scheduling parameters for HW. According to
these parameters provided by SW, the xHC can easily decide whether a
synchronous endpoint should be scheduled in a specific uFrame. The extra SW
scheduling parameters are put into reserved DWs in Slot and Endpoint Context.
And a bandwidth scheduler algorithm is added to support such feature.

A usb3.0 phy driver is also added which used by mt65xx SoCs platform, it
supports two usb2.0 ports and one usb3.0 port.

Change in v5:
1. descripte more exactly for each specifiers in xHCI binding
2. make use of new multi-phy feature for phy driver


Chunfeng Yun (5):
  dt-bindings: Add usb3.0 phy binding for MT65xx SoCs
  dt-bindings: Add a binding for Mediatek xHCI host controller
  usb: phy: add usb3.0 phy driver for mt65xx SoCs
  xhci: mediatek: support MTK xHCI host controller
  arm64: dts: mediatek: add xHCI & usb phy for mt8173

 .../devicetree/bindings/phy/phy-mt65xx-usb.txt     |  69 ++
 .../devicetree/bindings/usb/mt8173-xhci.txt        |  52 ++
 arch/arm64/boot/dts/mediatek/mt8173-evb.dts        |  16 +
 arch/arm64/boot/dts/mediatek/mt8173.dtsi           |  44 ++
 drivers/phy/Kconfig                                |   9 +
 drivers/phy/Makefile                               |   1 +
 drivers/phy/phy-mt65xx-usb3.c                      | 467 ++++++++++++
 drivers/usb/host/Kconfig                           |   9 +
 drivers/usb/host/Makefile                          |   4 +
 drivers/usb/host/xhci-mtk-sch.c                    | 436 +++++++++++
 drivers/usb/host/xhci-mtk.c                        | 837 +++++++++++++++++++++
 drivers/usb/host/xhci-mtk.h                        | 133 ++++
 drivers/usb/host/xhci-ring.c                       |  35 +-
 drivers/usb/host/xhci.c                            |  19 +-
 drivers/usb/host/xhci.h                            |   1 +
 15 files changed, 2125 insertions(+), 7 deletions(-)
 create mode 100644 Documentation/devicetree/bindings/phy/phy-mt65xx-usb.txt
 create mode 100644 Documentation/devicetree/bindings/usb/mt8173-xhci.txt
 create mode 100644 drivers/phy/phy-mt65xx-usb3.c
 create mode 100644 drivers/usb/host/xhci-mtk-sch.c
 create mode 100644 drivers/usb/host/xhci-mtk.c
 create mode 100644 drivers/usb/host/xhci-mtk.h

--
1.8.1.1.dirty




From chunfeng.yun at mediatek.com  Fri Aug  7 05:30:40 2015
From: chunfeng.yun at mediatek.com (Chunfeng Yun)
Date: Fri, 7 Aug 2015 20:30:40 +0800
Subject: [PATCH v5 1/5] dt-bindings: Add usb3.0 phy binding for MT65xx SoCs
In-Reply-To: <1438950644-27290-1-git-send-email-chunfeng.yun@mediatek.com>
References: <1438950644-27290-1-git-send-email-chunfeng.yun@mediatek.com>
Message-ID: <1438950644-27290-2-git-send-email-chunfeng.yun@mediatek.com>

add a DT binding documentation of usb3.0 phy for MT65xx
SoCs from Mediatek.

Signed-off-by: Chunfeng Yun <chunfeng.yun at mediatek.com>
---
 .../devicetree/bindings/phy/phy-mt65xx-usb.txt     | 69 ++++++++++++++++++++++
 1 file changed, 69 insertions(+)
 create mode 100644 Documentation/devicetree/bindings/phy/phy-mt65xx-usb.txt

diff --git a/Documentation/devicetree/bindings/phy/phy-mt65xx-usb.txt b/Documentation/devicetree/bindings/phy/phy-mt65xx-usb.txt
new file mode 100644
index 0000000..5812d20
--- /dev/null
+++ b/Documentation/devicetree/bindings/phy/phy-mt65xx-usb.txt
@@ -0,0 +1,69 @@
+mt65xx USB3.0 PHY binding
+--------------------------
+
+This binding describes a usb3.0 phy for mt65xx platforms of Medaitek SoC.
+
+Required properties (controller (parent) node):
+ - compatible	: should be "mediatek,mt8173-u3phy"
+ - reg		: offset and length of register for phy, exclude port's
+		  register.
+ - clocks	: a list of phandle + clock-specifier pairs, one for each
+		  entry in clock-names
+ - clock-names	: must contain
+		  "u3phya_ref": for reference clock of usb3.0 analog phy.
+
+Required nodes	: a sub-node is required for each port the controller
+		  provides. Address range information including the usual
+		  'reg' property is used inside these nodes to describe
+		  the controller's topology. These nodes are translated
+		  by the driver's .xlate() function.
+
+Required properties (port (child) node):
+- reg		: address and length of the register set for the port.
+- #phy-cells	: should be 1 (See second example)
+		  cell after port phandle is phy type from:
+			- PHY_TYPE_USB2
+			- PHY_TYPE_USB3
+
+Example:
+
+u3phy: usb-phy at 11290000 {
+	compatible = "mediatek,mt8173-u3phy";
+	reg = <0 0x11290000 0 0x800>;
+	clocks = <&apmixedsys CLK_APMIXED_REF2USB_TX>;
+	clock-names = "u3phya_ref";
+	#address-cells = <2>;
+	#size-cells = <2>;
+	ranges;
+	status = "okay";
+
+	phy_port0: port at 11290800 {
+		reg = <0 0x11290800 0 0x800>;
+		#phy-cells = <1>;
+		status = "okay";
+	};
+
+	phy_port1: port at 11291000 {
+		reg = <0 0x11291000 0 0x800>;
+		#phy-cells = <1>;
+		status = "okay";
+	};
+};
+
+Specifying phy control of devices
+---------------------------------
+
+Device nodes should specify the configuration required in their "phys"
+property, containing a phandle to the phy port node and a device type;
+phy-names for each port are optional.
+
+Example:
+
+#include <dt-bindings/phy/phy.h>
+
+usb30: usb at 11270000 {
+	...
+	phys = <&phy_port0 PHY_TYPE_USB3>;
+	phy-names = "usb3-0";
+	...
+};
-- 
1.8.1.1.dirty



From chunfeng.yun at mediatek.com  Fri Aug  7 05:30:42 2015
From: chunfeng.yun at mediatek.com (Chunfeng Yun)
Date: Fri, 7 Aug 2015 20:30:42 +0800
Subject: [PATCH v5 3/5] usb: phy: add usb3.0 phy driver for mt65xx SoCs
In-Reply-To: <1438950644-27290-1-git-send-email-chunfeng.yun@mediatek.com>
References: <1438950644-27290-1-git-send-email-chunfeng.yun@mediatek.com>
Message-ID: <1438950644-27290-4-git-send-email-chunfeng.yun@mediatek.com>

support usb3.0 phy of mt65xx SoCs

Signed-off-by: Chunfeng Yun <chunfeng.yun at mediatek.com>
---
 drivers/phy/Kconfig           |   9 +
 drivers/phy/Makefile          |   1 +
 drivers/phy/phy-mt65xx-usb3.c | 467 ++++++++++++++++++++++++++++++++++++++++++
 3 files changed, 477 insertions(+)
 create mode 100644 drivers/phy/phy-mt65xx-usb3.c

diff --git a/drivers/phy/Kconfig b/drivers/phy/Kconfig
index c0e6ede..019cf8b 100644
--- a/drivers/phy/Kconfig
+++ b/drivers/phy/Kconfig
@@ -193,6 +193,15 @@ config PHY_HIX5HD2_SATA
 	help
 	  Support for SATA PHY on Hisilicon hix5hd2 Soc.
 
+config PHY_MT65XX_USB3
+	tristate "Mediatek USB3.0 PHY Driver"
+	depends on ARCH_MEDIATEK && OF
+	select GENERIC_PHY
+	help
+	  Say 'Y' here to add support for Mediatek USB3.0 PHY driver
+	  for mt65xx SoCs. it supports two usb2.0 ports and
+	  one usb3.0 port.
+
 config PHY_SUN4I_USB
 	tristate "Allwinner sunxi SoC USB PHY driver"
 	depends on ARCH_SUNXI && HAS_IOMEM && OF
diff --git a/drivers/phy/Makefile b/drivers/phy/Makefile
index f344e1b..3ceff2a 100644
--- a/drivers/phy/Makefile
+++ b/drivers/phy/Makefile
@@ -22,6 +22,7 @@ obj-$(CONFIG_TI_PIPE3)			+= phy-ti-pipe3.o
 obj-$(CONFIG_TWL4030_USB)		+= phy-twl4030-usb.o
 obj-$(CONFIG_PHY_EXYNOS5250_SATA)	+= phy-exynos5250-sata.o
 obj-$(CONFIG_PHY_HIX5HD2_SATA)		+= phy-hix5hd2-sata.o
+obj-$(CONFIG_PHY_MT65XX_USB3)		+= phy-mt65xx-usb3.o
 obj-$(CONFIG_PHY_SUN4I_USB)		+= phy-sun4i-usb.o
 obj-$(CONFIG_PHY_SUN9I_USB)		+= phy-sun9i-usb.o
 obj-$(CONFIG_PHY_SAMSUNG_USB2)		+= phy-exynos-usb2.o
diff --git a/drivers/phy/phy-mt65xx-usb3.c b/drivers/phy/phy-mt65xx-usb3.c
new file mode 100644
index 0000000..6835bff
--- /dev/null
+++ b/drivers/phy/phy-mt65xx-usb3.c
@@ -0,0 +1,467 @@
+/*
+ * Copyright (c) 2015 MediaTek Inc.
+ * Author: Chunfeng Yun <chunfeng.yun at mediatek.com>
+ *
+ * This software is licensed under the terms of the GNU General Public
+ * License version 2, as published by the Free Software Foundation, and
+ * may be copied, distributed, and modified under those terms.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ * GNU General Public License for more details.
+ *
+ */
+
+#include <dt-bindings/phy/phy.h>
+#include <linux/clk.h>
+#include <linux/delay.h>
+#include <linux/io.h>
+#include <linux/module.h>
+#include <linux/of_address.h>
+#include <linux/phy/phy.h>
+#include <linux/platform_device.h>
+
+/*
+ * for sifslv2 register, but exclude port's;
+ * relative to USB3_SIF2_BASE base address
+ */
+#define SSUSB_SIFSLV_SPLLC		0x0000
+
+/* offsets of sub-segment in each port registers */
+#define SSUSB_SIFSLV_U2PHY_COM_BASE	0x0000
+#define SSUSB_SIFSLV_U3PHYD_BASE	0x0100
+#define SSUSB_USB30_PHYA_SIV_B_BASE	0x0300
+#define SSUSB_SIFSLV_U3PHYA_DA_BASE	0x0400
+
+#define U3P_USBPHYACR0		(SSUSB_SIFSLV_U2PHY_COM_BASE + 0x0000)
+#define PA0_RG_U2PLL_FORCE_ON		BIT(15)
+
+#define U3P_USBPHYACR2		(SSUSB_SIFSLV_U2PHY_COM_BASE + 0x0008)
+#define PA2_RG_SIF_U2PLL_FORCE_EN	BIT(18)
+
+#define U3P_USBPHYACR5		(SSUSB_SIFSLV_U2PHY_COM_BASE + 0x0014)
+#define PA5_RG_U2_HSTX_SRCTRL		(0x7 << 12)
+#define PA5_RG_U2_HSTX_SRCTRL_VAL(x)	((0x7 & (x)) << 12)
+#define PA5_RG_U2_HS_100U_U3_EN	BIT(11)
+
+#define U3P_USBPHYACR6		(SSUSB_SIFSLV_U2PHY_COM_BASE + 0x0018)
+#define PA6_RG_U2_ISO_EN		BIT(31)
+#define PA6_RG_U2_BC11_SW_EN		BIT(23)
+#define PA6_RG_U2_OTG_VBUSCMP_EN	BIT(20)
+
+#define U3P_U2PHYACR4		(SSUSB_SIFSLV_U2PHY_COM_BASE + 0x0020)
+#define P2C_RG_USB20_GPIO_CTL		BIT(9)
+#define P2C_USB20_GPIO_MODE		BIT(8)
+#define P2C_U2_GPIO_CTR_MSK	(P2C_RG_USB20_GPIO_CTL | P2C_USB20_GPIO_MODE)
+
+#define U3D_U2PHYDCR0		(SSUSB_SIFSLV_U2PHY_COM_BASE + 0x0060)
+#define P2C_RG_SIF_U2PLL_FORCE_ON	BIT(24)
+
+#define U3P_U2PHYDTM0		(SSUSB_SIFSLV_U2PHY_COM_BASE + 0x0068)
+#define P2C_FORCE_UART_EN		BIT(26)
+#define P2C_FORCE_DATAIN		BIT(23)
+#define P2C_FORCE_DM_PULLDOWN		BIT(21)
+#define P2C_FORCE_DP_PULLDOWN		BIT(20)
+#define P2C_FORCE_XCVRSEL		BIT(19)
+#define P2C_FORCE_SUSPENDM		BIT(18)
+#define P2C_FORCE_TERMSEL		BIT(17)
+#define P2C_RG_DATAIN			(0xf << 10)
+#define P2C_RG_DATAIN_VAL(x)		((0xf & (x)) << 10)
+#define P2C_RG_DMPULLDOWN		BIT(7)
+#define P2C_RG_DPPULLDOWN		BIT(6)
+#define P2C_RG_XCVRSEL			(0x3 << 4)
+#define P2C_RG_XCVRSEL_VAL(x)		((0x3 & (x)) << 4)
+#define P2C_RG_SUSPENDM			BIT(3)
+#define P2C_RG_TERMSEL			BIT(2)
+#define P2C_DTM0_PART_MASK \
+		(P2C_FORCE_DATAIN | P2C_FORCE_DM_PULLDOWN | \
+		P2C_FORCE_DP_PULLDOWN | P2C_FORCE_XCVRSEL | \
+		P2C_FORCE_TERMSEL | P2C_RG_DMPULLDOWN | \
+		P2C_RG_DPPULLDOWN | P2C_RG_TERMSEL)
+
+#define U3P_U2PHYDTM1		(SSUSB_SIFSLV_U2PHY_COM_BASE + 0x006C)
+#define P2C_RG_UART_EN			BIT(16)
+#define P2C_RG_VBUSVALID		BIT(5)
+#define P2C_RG_SESSEND			BIT(4)
+#define P2C_RG_AVALID			BIT(2)
+
+#define U3P_U3_PHYA_REG0	(SSUSB_USB30_PHYA_SIV_B_BASE + 0x0000)
+#define P3A_RG_U3_VUSB10_ON		BIT(5)
+
+#define U3P_U3_PHYA_REG6	(SSUSB_USB30_PHYA_SIV_B_BASE + 0x0018)
+#define P3A_RG_TX_EIDLE_CM		(0xf << 28)
+#define P3A_RG_TX_EIDLE_CM_VAL(x)	((0xf & (x)) << 28)
+
+#define U3P_U3_PHYA_REG9	(SSUSB_USB30_PHYA_SIV_B_BASE + 0x0024)
+#define P3A_RG_RX_DAC_MUX		(0x1f << 1)
+#define P3A_RG_RX_DAC_MUX_VAL(x)	((0x1f & (x)) << 1)
+
+#define U3P_U3PHYA_DA_REG0	(SSUSB_SIFSLV_U3PHYA_DA_BASE + 0x0000)
+#define P3A_RG_XTAL_EXT_EN_U3		(0x3 << 10)
+#define P3A_RG_XTAL_EXT_EN_U3_VAL(x)	((0x3 & (x)) << 10)
+
+#define U3P_PHYD_CDR1		(SSUSB_SIFSLV_U3PHYD_BASE + 0x005c)
+#define P3D_RG_CDR_BIR_LTD1		(0x1f << 24)
+#define P3D_RG_CDR_BIR_LTD1_VAL(x)	((0x1f & (x)) << 24)
+#define P3D_RG_CDR_BIR_LTD0		(0x1f << 8)
+#define P3D_RG_CDR_BIR_LTD0_VAL(x)	((0x1f & (x)) << 8)
+
+#define U3P_XTALCTL3		(SSUSB_SIFSLV_SPLLC + 0x0018)
+#define XC3_RG_U3_XTAL_RX_PWD		BIT(9)
+#define XC3_RG_U3_FRC_XTAL_RX_PWD	BIT(8)
+
+struct mt65xx_phy_instance {
+	struct phy *phy;
+	void __iomem *port_base;
+	u32 index;
+	u8 type;
+};
+
+struct mt65xx_u3phy {
+	struct device *dev;
+	void __iomem *sif_base;	/* include sif2, but exclude port's */
+	struct clk *u3phya_ref;	/* reference clock of usb3 anolog phy */
+	struct mt65xx_phy_instance **phys;
+	int nphys;
+};
+
+static void phy_instance_init(struct mt65xx_u3phy *u3phy,
+	struct mt65xx_phy_instance *instance)
+{
+	void __iomem *port_base = instance->port_base;
+	u32 index = instance->index;
+	u32 tmp;
+
+	/* switch to USB function. (system register, force ip into usb mode) */
+	tmp = readl(port_base + U3P_U2PHYDTM0);
+	tmp &= ~P2C_FORCE_UART_EN;
+	writel(tmp, port_base + U3P_U2PHYDTM0);
+
+	tmp = readl(port_base + U3P_U2PHYDTM1);
+	tmp &= ~P2C_RG_UART_EN;
+	writel(tmp, port_base + U3P_U2PHYDTM1);
+
+	if (!index) {
+		tmp = readl(port_base + U3P_U2PHYACR4);
+		tmp &= ~P2C_U2_GPIO_CTR_MSK;
+		writel(tmp, port_base + U3P_U2PHYACR4);
+	}
+
+	/* DP/DM BC1.1 path Disable */
+	tmp = readl(port_base + U3P_USBPHYACR6);
+	tmp &= ~PA6_RG_U2_BC11_SW_EN;
+	writel(tmp, port_base + U3P_USBPHYACR6);
+
+	tmp = readl(port_base + U3P_U3PHYA_DA_REG0);
+	tmp &= ~P3A_RG_XTAL_EXT_EN_U3;
+	tmp |= P3A_RG_XTAL_EXT_EN_U3_VAL(2);
+	writel(tmp, port_base + U3P_U3PHYA_DA_REG0);
+
+	tmp = readl(port_base + U3P_U3_PHYA_REG9);
+	tmp &= ~P3A_RG_RX_DAC_MUX;
+	tmp |= P3A_RG_RX_DAC_MUX_VAL(4);
+	writel(tmp, port_base + U3P_U3_PHYA_REG9);
+
+	tmp = readl(port_base + U3P_U3_PHYA_REG6);
+	tmp &= ~P3A_RG_TX_EIDLE_CM;
+	tmp |= P3A_RG_TX_EIDLE_CM_VAL(0xe);
+	writel(tmp, port_base + U3P_U3_PHYA_REG6);
+
+	tmp = readl(port_base + U3P_PHYD_CDR1);
+	tmp &= ~(P3D_RG_CDR_BIR_LTD0 | P3D_RG_CDR_BIR_LTD1);
+	tmp |= P3D_RG_CDR_BIR_LTD0_VAL(0xc) | P3D_RG_CDR_BIR_LTD1_VAL(0x3);
+	writel(tmp, port_base + U3P_PHYD_CDR1);
+
+	dev_dbg(u3phy->dev, "%s(%d)\n", __func__, index);
+}
+
+static void phy_instance_power_on(struct mt65xx_u3phy *u3phy,
+	struct mt65xx_phy_instance *instance)
+{
+	void __iomem *port_base = instance->port_base;
+	u32 index = instance->index;
+	u32 tmp;
+
+	if (!index) {
+		/* Set RG_SSUSB_VUSB10_ON as 1 after VUSB10 ready */
+		tmp = readl(port_base + U3P_U3_PHYA_REG0);
+		tmp |= P3A_RG_U3_VUSB10_ON;
+		writel(tmp, port_base + U3P_U3_PHYA_REG0);
+	}
+
+	/* (force_suspendm=0) (let suspendm=1, enable usb 480MHz pll) */
+	tmp = readl(port_base + U3P_U2PHYDTM0);
+	tmp &= ~(P2C_FORCE_SUSPENDM | P2C_RG_XCVRSEL);
+	tmp &= ~(P2C_RG_DATAIN | P2C_DTM0_PART_MASK);
+	writel(tmp, port_base + U3P_U2PHYDTM0);
+
+	/* OTG Enable */
+	tmp = readl(port_base + U3P_USBPHYACR6);
+	tmp |= PA6_RG_U2_OTG_VBUSCMP_EN;
+	writel(tmp, port_base + U3P_USBPHYACR6);
+
+	if (!index) {
+		tmp = readl(u3phy->sif_base + U3P_XTALCTL3);
+		tmp |= XC3_RG_U3_XTAL_RX_PWD | XC3_RG_U3_FRC_XTAL_RX_PWD;
+		writel(tmp, u3phy->sif_base + U3P_XTALCTL3);
+		/* [mt8173]disable Change 100uA current from SSUSB */
+		tmp = readl(port_base + U3P_USBPHYACR5);
+		tmp &= ~PA5_RG_U2_HS_100U_U3_EN;
+		writel(tmp, port_base + U3P_USBPHYACR5);
+	}
+	udelay(800);
+
+	tmp = readl(port_base + U3P_U2PHYDTM1);
+	tmp |= P2C_RG_VBUSVALID | P2C_RG_AVALID;
+	tmp &= ~P2C_RG_SESSEND;
+	writel(tmp, port_base + U3P_U2PHYDTM1);
+	/* USB 2.0 slew rate calibration */
+	tmp = readl(port_base + U3P_USBPHYACR5);
+	tmp &= ~PA5_RG_U2_HSTX_SRCTRL;
+	tmp |= PA5_RG_U2_HSTX_SRCTRL_VAL(4);
+	writel(tmp, port_base + U3P_USBPHYACR5);
+
+	dev_dbg(u3phy->dev, "%s(%d)\n", __func__, index);
+}
+
+static void phy_instance_power_off(struct mt65xx_u3phy *u3phy,
+	struct mt65xx_phy_instance *instance)
+{
+	void __iomem *port_base = instance->port_base;
+	u32 index = instance->index;
+	u32 tmp;
+
+	tmp = readl(port_base + U3P_U2PHYDTM0);
+	tmp &= ~(P2C_RG_XCVRSEL | P2C_RG_DATAIN);
+	tmp |= P2C_RG_XCVRSEL_VAL(1) | P2C_RG_DATAIN_VAL(0);
+	tmp |= P2C_FORCE_SUSPENDM;
+	writel(tmp, port_base + U3P_U2PHYDTM0);
+
+	/* OTG Disable */
+	tmp = readl(port_base + U3P_USBPHYACR6);
+	tmp &= ~PA6_RG_U2_OTG_VBUSCMP_EN;
+	writel(tmp, port_base + U3P_USBPHYACR6);
+	if (!index) {
+		/* (also disable)Change 100uA current switch to USB2.0 */
+		tmp = readl(port_base + U3P_USBPHYACR5);
+		tmp &= ~PA5_RG_U2_HS_100U_U3_EN;
+		writel(tmp, port_base + U3P_USBPHYACR5);
+	}
+	udelay(800);
+
+	/* let suspendm=0, set utmi into analog power down */
+	tmp = readl(port_base + U3P_U2PHYDTM0);
+	tmp &= ~P2C_RG_SUSPENDM;
+	writel(tmp, port_base + U3P_U2PHYDTM0);
+	udelay(1);
+
+	tmp = readl(port_base + U3P_U2PHYDTM1);
+	tmp &= ~(P2C_RG_VBUSVALID | P2C_RG_AVALID);
+	tmp |= P2C_RG_SESSEND;
+	writel(tmp, port_base + U3P_U2PHYDTM1);
+
+	if (!index) {
+		tmp = readl(port_base + U3P_U3_PHYA_REG0);
+		tmp &= ~P3A_RG_U3_VUSB10_ON;
+		writel(tmp, port_base + U3P_U3_PHYA_REG0);
+	}
+
+	dev_dbg(u3phy->dev, "%s(%d)\n", __func__, index);
+}
+
+static int u3phy_clk_enable(struct mt65xx_u3phy *u3phy)
+{
+	int ret;
+
+	ret = clk_prepare_enable(u3phy->u3phya_ref);
+	if (ret) {
+		dev_err(u3phy->dev, "failed to enable u3phya_ref\n");
+		return ret;
+	}
+	udelay(100);
+
+	return 0;
+}
+
+static int mt65xx_phy_init(struct phy *phy)
+{
+	struct mt65xx_phy_instance *instance = phy_get_drvdata(phy);
+	struct mt65xx_u3phy *u3phy = dev_get_drvdata(phy->dev.parent);
+
+	phy_instance_init(u3phy, instance);
+	return 0;
+}
+
+static int mt65xx_phy_power_on(struct phy *phy)
+{
+	struct mt65xx_phy_instance *instance = phy_get_drvdata(phy);
+	struct mt65xx_u3phy *u3phy = dev_get_drvdata(phy->dev.parent);
+
+	phy_instance_power_on(u3phy, instance);
+	msleep(20);
+	return 0;
+}
+
+static int mt65xx_phy_power_off(struct phy *phy)
+{
+	struct mt65xx_phy_instance *instance = phy_get_drvdata(phy);
+	struct mt65xx_u3phy *u3phy = dev_get_drvdata(phy->dev.parent);
+
+	phy_instance_power_off(u3phy, instance);
+	return 0;
+}
+
+static struct phy *mt65xx_phy_xlate(struct device *dev,
+					struct of_phandle_args *args)
+{
+	struct mt65xx_u3phy *u3phy = dev_get_drvdata(dev);
+	struct mt65xx_phy_instance *instance = NULL;
+	struct device_node *phy_np = args->np;
+	struct resource res;
+	int index;
+	int ret;
+
+	if (args->args_count != 1) {
+		dev_err(dev, "invalid number of cells in 'phy' property\n");
+		return ERR_PTR(-EINVAL);
+	}
+
+	for (index = 0; index < u3phy->nphys; index++)
+		if (phy_np == u3phy->phys[index]->phy->dev.of_node) {
+			instance = u3phy->phys[index];
+			break;
+		}
+
+	if (!instance) {
+		dev_err(dev, "failed to find appropriate phy\n");
+		return ERR_PTR(-EINVAL);
+	}
+
+	instance->type = args->args[0];
+
+	if (!(instance->type == PHY_TYPE_USB2 ||
+	      instance->type == PHY_TYPE_USB3)) {
+		dev_err(dev, "unsupported device type: %d\n", instance->type);
+		return ERR_PTR(-EINVAL);
+	}
+
+	ret = of_address_to_resource(phy_np, 0, &res);
+	if (ret) {
+		dev_err(dev, "failed to get address resource, err-%d (index-%d)\n",
+			ret, instance->index);
+		return ERR_PTR(-EINVAL);
+	}
+
+	instance->port_base = devm_ioremap_resource(&instance->phy->dev, &res);
+	if (IS_ERR(instance->port_base)) {
+		dev_err(dev, "failed to remap sif regs\n");
+		return instance->port_base;
+	}
+
+	return instance->phy;
+}
+
+static struct phy_ops mt65xx_u3phy_ops = {
+	.init		= mt65xx_phy_init,
+	.power_on	= mt65xx_phy_power_on,
+	.power_off	= mt65xx_phy_power_off,
+	.owner		= THIS_MODULE,
+};
+
+static int mt65xx_u3phy_probe(struct platform_device *pdev)
+{
+	struct device *dev = &pdev->dev;
+	struct device_node *np = dev->of_node;
+	struct device_node *child_np;
+	struct phy_provider *phy_provider;
+	struct resource *sif_res;
+	struct mt65xx_u3phy *u3phy;
+	int port;
+
+	u3phy = devm_kzalloc(dev, sizeof(*u3phy), GFP_KERNEL);
+	if (!u3phy)
+		return -ENOMEM;
+
+	u3phy->nphys = of_get_child_count(np);
+	u3phy->phys = devm_kcalloc(dev, u3phy->nphys,
+				       sizeof(*u3phy->phys), GFP_KERNEL);
+	if (!u3phy->phys)
+		return -ENOMEM;
+
+	u3phy->dev = dev;
+	platform_set_drvdata(pdev, u3phy);
+
+	sif_res = platform_get_resource(pdev, IORESOURCE_MEM, 0);
+	u3phy->sif_base = devm_ioremap_resource(dev, sif_res);
+	if (IS_ERR(u3phy->sif_base)) {
+		dev_err(dev, "failed to remap sif regs\n");
+		return PTR_ERR(u3phy->sif_base);
+	}
+
+	u3phy->u3phya_ref = devm_clk_get(dev, "u3phya_ref");
+	if (IS_ERR(u3phy->u3phya_ref)) {
+		dev_err(dev, "error to get u3phya_ref\n");
+		return PTR_ERR(u3phy->u3phya_ref);
+	}
+
+	port = 0;
+	for_each_child_of_node(np, child_np) {
+		struct mt65xx_phy_instance *instance;
+		struct phy *phy;
+
+		instance = devm_kzalloc(dev, sizeof(*instance), GFP_KERNEL);
+		if (!instance)
+			return -ENOMEM;
+
+		u3phy->phys[port] = instance;
+
+		phy = devm_phy_create(dev, child_np, &mt65xx_u3phy_ops);
+		if (IS_ERR(phy)) {
+			dev_err(dev, "failed to create phy\n");
+			return PTR_ERR(phy);
+		}
+		instance->phy = phy;
+		instance->index = port;
+		phy_set_drvdata(phy, instance);
+		port++;
+	}
+
+	phy_provider = devm_of_phy_provider_register(dev, mt65xx_phy_xlate);
+	if (IS_ERR(phy_provider)) {
+		dev_err(dev, "Failed to register phy provider\n");
+		return PTR_ERR(phy_provider);
+	}
+
+	return u3phy_clk_enable(u3phy);
+}
+
+static int mt65xx_u3phy_remove(struct platform_device *pdev)
+{
+	struct mt65xx_u3phy *u3phy = platform_get_drvdata(pdev);
+
+	clk_disable_unprepare(u3phy->u3phya_ref);
+
+	return 0;
+}
+
+static const struct of_device_id mt65xx_u3phy_id_table[] = {
+	{ .compatible = "mediatek,mt8173-u3phy", },
+	{ },
+};
+MODULE_DEVICE_TABLE(of, mt65xx_u3phy_id_table);
+
+static struct platform_driver mt65xx_u3phy_driver = {
+	.probe		= mt65xx_u3phy_probe,
+	.remove		= mt65xx_u3phy_remove,
+	.driver		= {
+		.name	= "mt65xx-u3phy",
+		.of_match_table = mt65xx_u3phy_id_table,
+	},
+};
+
+module_platform_driver(mt65xx_u3phy_driver);
+
+MODULE_AUTHOR("Chunfeng Yun <chunfeng.yun at mediatek.com>");
+MODULE_DESCRIPTION("Mt65xx USB PHY driver");
+MODULE_LICENSE("GPL v2");
-- 
1.8.1.1.dirty



From chunfeng.yun at mediatek.com  Fri Aug  7 05:30:44 2015
From: chunfeng.yun at mediatek.com (Chunfeng Yun)
Date: Fri, 7 Aug 2015 20:30:44 +0800
Subject: [PATCH v5 5/5] arm64: dts: mediatek: add xHCI & usb phy for mt8173
In-Reply-To: <1438950644-27290-1-git-send-email-chunfeng.yun@mediatek.com>
References: <1438950644-27290-1-git-send-email-chunfeng.yun@mediatek.com>
Message-ID: <1438950644-27290-6-git-send-email-chunfeng.yun@mediatek.com>

add xHCI and phy drivers for MT8173-EVB

Signed-off-by: Chunfeng Yun <chunfeng.yun at mediatek.com>
---
 arch/arm64/boot/dts/mediatek/mt8173-evb.dts | 16 +++++++++++
 arch/arm64/boot/dts/mediatek/mt8173.dtsi    | 44 +++++++++++++++++++++++++++++
 2 files changed, 60 insertions(+)

diff --git a/arch/arm64/boot/dts/mediatek/mt8173-evb.dts b/arch/arm64/boot/dts/mediatek/mt8173-evb.dts
index f433c21..112f3f3 100644
--- a/arch/arm64/boot/dts/mediatek/mt8173-evb.dts
+++ b/arch/arm64/boot/dts/mediatek/mt8173-evb.dts
@@ -13,6 +13,7 @@
  */
 
 /dts-v1/;
+#include <dt-bindings/gpio/gpio.h>
 #include "mt8173.dtsi"
 
 / {
@@ -32,6 +33,15 @@
 	};
 
 	chosen { };
+
+	usb_p1_vbus: regulator at 0 {
+		compatible = "regulator-fixed";
+		regulator-name = "usb_vbus";
+		regulator-min-microvolt = <5000000>;
+		regulator-max-microvolt = <5000000>;
+		gpio = <&pio 130 GPIO_ACTIVE_HIGH>;
+		enable-active-high;
+	};
 };
 
 &pwrap {
@@ -211,3 +221,9 @@
 &uart0 {
 	status = "okay";
 };
+
+&usb30 {
+	vusb33-supply = <&mt6397_vusb_reg>;
+	vbus-supply = <&usb_p1_vbus>;
+	mediatek,wakeup-src = <1>;
+};
diff --git a/arch/arm64/boot/dts/mediatek/mt8173.dtsi b/arch/arm64/boot/dts/mediatek/mt8173.dtsi
index 0696f8f..f88b2f9 100644
--- a/arch/arm64/boot/dts/mediatek/mt8173.dtsi
+++ b/arch/arm64/boot/dts/mediatek/mt8173.dtsi
@@ -14,6 +14,8 @@
 #include <dt-bindings/clock/mt8173-clk.h>
 #include <dt-bindings/interrupt-controller/irq.h>
 #include <dt-bindings/interrupt-controller/arm-gic.h>
+#include <dt-bindings/phy/phy.h>
+#include <dt-bindings/power/mt8173-power.h>
 #include <dt-bindings/reset-controller/mt8173-resets.h>
 #include "mt8173-pinfunc.h"
 
@@ -393,6 +395,48 @@
 			#size-cells = <0>;
 			status = "disabled";
 		};
+
+		usb30: usb at 11270000 {
+			compatible = "mediatek,mt8173-xhci";
+			reg = <0 0x11270000 0 0x4000>,
+			      <0 0x11280000 0 0x0800>;
+			interrupts = <GIC_SPI 115 IRQ_TYPE_LEVEL_LOW>;
+			power-domains = <&scpsys MT8173_POWER_DOMAIN_USB>;
+			clocks = <&topckgen CLK_TOP_USB30_SEL>,
+				 <&pericfg CLK_PERI_USB0>,
+				 <&pericfg CLK_PERI_USB1>;
+			clock-names = "sys_ck",
+				      "wakeup_deb_p0",
+				      "wakeup_deb_p1";
+			phys = <&phy_port0 PHY_TYPE_USB3>,
+			       <&phy_port1 PHY_TYPE_USB2>;
+			usb3-lpm-capable;
+			mediatek,syscon-wakeup = <&pericfg>;
+			status = "okay";
+		};
+
+		u3phy: usb-phy at 11290000 {
+			compatible = "mediatek,mt8173-u3phy";
+			reg = <0 0x11290000 0 0x800>;
+			clocks = <&apmixedsys CLK_APMIXED_REF2USB_TX>;
+			clock-names = "u3phya_ref";
+			#address-cells = <2>;
+			#size-cells = <2>;
+			ranges;
+			status = "okay";
+
+			phy_port0: port at 11290800 {
+				reg = <0 0x11290800 0 0x800>;
+				#phy-cells = <1>;
+				status = "okay";
+			};
+
+			phy_port1: port at 11291000 {
+				reg = <0 0x11291000 0 0x800>;
+				#phy-cells = <1>;
+				status = "okay";
+			};
+		};
 	};
 };
 
-- 
1.8.1.1.dirty



From chunfeng.yun at mediatek.com  Fri Aug  7 05:30:43 2015
From: chunfeng.yun at mediatek.com (Chunfeng Yun)
Date: Fri, 7 Aug 2015 20:30:43 +0800
Subject: [PATCH v5 4/5] xhci: mediatek: support MTK xHCI host controller
In-Reply-To: <1438950644-27290-1-git-send-email-chunfeng.yun@mediatek.com>
References: <1438950644-27290-1-git-send-email-chunfeng.yun@mediatek.com>
Message-ID: <1438950644-27290-5-git-send-email-chunfeng.yun@mediatek.com>

MTK xhci host controller defines some extra SW scheduling
parameters for HW to minimize the scheduling effort for
synchronous and interrupt endpoints. The parameters are
put into reseved DWs of slot context and endpoint context

Signed-off-by: Chunfeng Yun <chunfeng.yun at mediatek.com>
---
 drivers/usb/host/Kconfig        |   9 +
 drivers/usb/host/Makefile       |   4 +
 drivers/usb/host/xhci-mtk-sch.c | 436 +++++++++++++++++++++
 drivers/usb/host/xhci-mtk.c     | 837 ++++++++++++++++++++++++++++++++++++++++
 drivers/usb/host/xhci-mtk.h     | 133 +++++++
 drivers/usb/host/xhci-ring.c    |  35 +-
 drivers/usb/host/xhci.c         |  19 +-
 drivers/usb/host/xhci.h         |   1 +
 8 files changed, 1467 insertions(+), 7 deletions(-)
 create mode 100644 drivers/usb/host/xhci-mtk-sch.c
 create mode 100644 drivers/usb/host/xhci-mtk.c
 create mode 100644 drivers/usb/host/xhci-mtk.h

diff --git a/drivers/usb/host/Kconfig b/drivers/usb/host/Kconfig
index 8afc3c1..358ab6d 100644
--- a/drivers/usb/host/Kconfig
+++ b/drivers/usb/host/Kconfig
@@ -34,6 +34,15 @@ config USB_XHCI_PCI
 config USB_XHCI_PLATFORM
 	tristate
 
+config USB_XHCI_MTK
+	tristate "xHCI support for Mediatek MT65xx"
+	select MFD_SYSCON
+	depends on ARCH_MEDIATEK || COMPILE_TEST
+	---help---
+	  Say 'Y' to enable the support for the xHCI host controller
+	  found in Mediatek MT65xx SoCs.
+	  If unsure, say N.
+
 config USB_XHCI_MVEBU
 	tristate "xHCI support for Marvell Armada 375/38x"
 	select USB_XHCI_PLATFORM
diff --git a/drivers/usb/host/Makefile b/drivers/usb/host/Makefile
index 754efaa..00401f9 100644
--- a/drivers/usb/host/Makefile
+++ b/drivers/usb/host/Makefile
@@ -13,6 +13,9 @@ fhci-$(CONFIG_FHCI_DEBUG) += fhci-dbg.o
 xhci-hcd-y := xhci.o xhci-mem.o
 xhci-hcd-y += xhci-ring.o xhci-hub.o xhci-dbg.o
 xhci-hcd-y += xhci-trace.o
+ifneq ($(CONFIG_USB_XHCI_MTK), )
+	xhci-hcd-y += xhci-mtk-sch.o
+endif
 
 xhci-plat-hcd-y := xhci-plat.o
 ifneq ($(CONFIG_USB_XHCI_MVEBU), )
@@ -30,6 +33,7 @@ endif
 
 obj-$(CONFIG_USB_XHCI_PCI)	+= xhci-pci.o
 obj-$(CONFIG_USB_XHCI_PLATFORM) += xhci-plat-hcd.o
+obj-$(CONFIG_USB_XHCI_MTK)	+= xhci-mtk.o
 
 obj-$(CONFIG_USB_EHCI_HCD)	+= ehci-hcd.o
 obj-$(CONFIG_USB_EHCI_PCI)	+= ehci-pci.o
diff --git a/drivers/usb/host/xhci-mtk-sch.c b/drivers/usb/host/xhci-mtk-sch.c
new file mode 100644
index 0000000..d4b41a6
--- /dev/null
+++ b/drivers/usb/host/xhci-mtk-sch.c
@@ -0,0 +1,436 @@
+/*
+ * Copyright (c) 2015 MediaTek Inc.
+ * Author:
+ *  Zhigang.Wei <zhigang.wei at mediatek.com>
+ *  Chunfeng.Yun <chunfeng.yun at mediatek.com>
+ *
+ * This software is licensed under the terms of the GNU General Public
+ * License version 2, as published by the Free Software Foundation, and
+ * may be copied, distributed, and modified under those terms.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ * GNU General Public License for more details.
+ *
+ */
+
+#include <linux/kernel.h>
+#include <linux/module.h>
+#include <linux/slab.h>
+
+#include "xhci.h"
+#include "xhci-mtk.h"
+
+#define SS_BW_BOUNDARY	51000
+/* table 5-5. High-speed Isoc Transaction Limits in usb_20 spec */
+#define HS_BW_BOUNDARY	6144
+/* usb2 spec section11.18.1: at most 188 FS bytes per microframe */
+#define FS_PAYLOAD_MAX 188
+
+/* mtk scheduler bitmasks */
+#define EP_BPKTS(p)	((p) & 0x3f)
+#define EP_BCSCOUNT(p)	(((p) & 0x7) << 8)
+#define EP_BBM(p)	((p) << 11)
+#define EP_BOFFSET(p)	((p) & 0x3fff)
+#define EP_BREPEAT(p)	(((p) & 0x7fff) << 16)
+
+static int is_fs_or_ls(enum usb_device_speed speed)
+{
+	return speed == USB_SPEED_FULL || speed == USB_SPEED_LOW;
+}
+
+static int get_bw_index(struct xhci_hcd *xhci, struct usb_device *udev,
+	struct usb_host_endpoint *ep)
+{
+	int bw_index;
+	int port_id;
+	struct xhci_virt_device *virt_dev;
+
+	virt_dev = xhci->devs[udev->slot_id];
+	port_id = virt_dev->real_port;
+
+	if (udev->speed == USB_SPEED_SUPER) {
+		if (usb_endpoint_dir_out(&ep->desc))
+			bw_index = (port_id - 1) * 2;
+		else
+			bw_index = (port_id - 1) * 2 + 1;
+	} else {
+		bw_index = port_id + xhci->num_usb3_ports - 1;
+	}
+
+	return bw_index;
+}
+
+static void setup_sch_info(struct usb_device *udev,
+		struct xhci_ep_ctx *ep_ctx, struct mu3h_sch_ep_info *sch_ep)
+{
+	u32 ep_type;
+	u32 ep_interval;
+	u32 max_packet_size;
+	u32 max_burst;
+	u32 mult;
+	u32 esit_pkts;
+
+	ep_type = CTX_TO_EP_TYPE(le32_to_cpu(ep_ctx->ep_info2));
+	ep_interval = CTX_TO_EP_INTERVAL(le32_to_cpu(ep_ctx->ep_info));
+	max_packet_size = MAX_PACKET_DECODED(le32_to_cpu(ep_ctx->ep_info2));
+	max_burst = CTX_TO_MAX_BURST(le32_to_cpu(ep_ctx->ep_info2));
+	mult = CTX_TO_EP_MULT(le32_to_cpu(ep_ctx->ep_info));
+
+	sch_ep->ep_type = ep_type;
+	sch_ep->max_packet_size = max_packet_size;
+	sch_ep->esit = 1 << ep_interval;
+	sch_ep->offset = 0;
+	sch_ep->burst_mode = 0;
+
+	if (udev->speed == USB_SPEED_HIGH) {
+		sch_ep->cs_count = 0;
+		/*
+		 * usb_20 spec section5.9
+		 * a single microframe is enough for HS synchromous endpoints
+		 * in a interval
+		 */
+		sch_ep->num_budget_microframes = 1;
+		sch_ep->repeat = 0;
+		/*
+		 * xHCI spec section6.2.3.4
+		 * @max_busrt is the number of additional transactions
+		 * opportunities per microframe
+		 */
+		sch_ep->pkts = max_burst + 1;
+		sch_ep->bw_cost_per_microframe = max_packet_size * sch_ep->pkts;
+	} else if (udev->speed == USB_SPEED_SUPER) {
+		/* usb3_r1 spec section4.4.7 & 4.4.8 */
+		sch_ep->cs_count = 0;
+		esit_pkts = (mult + 1) * (max_burst + 1);
+		if (ep_type == INT_IN_EP || ep_type == INT_OUT_EP) {
+			sch_ep->pkts = esit_pkts;
+			sch_ep->num_budget_microframes = 1;
+			sch_ep->repeat = 0;
+		}
+
+		if (ep_type == ISOC_IN_EP || ep_type == ISOC_OUT_EP) {
+			if (esit_pkts <= sch_ep->esit)
+				sch_ep->pkts = 1;
+			else
+				sch_ep->pkts = roundup_pow_of_two(esit_pkts)
+					/ sch_ep->esit;
+
+			sch_ep->num_budget_microframes =
+				DIV_ROUND_UP(esit_pkts, sch_ep->pkts);
+
+			if (sch_ep->num_budget_microframes > 1)
+				sch_ep->repeat = 1;
+			else
+				sch_ep->repeat = 0;
+		}
+		sch_ep->bw_cost_per_microframe = max_packet_size * sch_ep->pkts;
+	} else if (is_fs_or_ls(udev->speed)) {
+		/*
+		 * usb_20 spec section11.18.4
+		 * assume worst cases
+		 */
+		sch_ep->repeat = 0;
+		sch_ep->pkts = 1; /* at most one packet for each microframe */
+		if (ep_type == INT_IN_EP || ep_type == INT_OUT_EP) {
+			sch_ep->cs_count = 3; /* at most need 3 CS*/
+			/* one for SS and one for budgeted transaction */
+			sch_ep->num_budget_microframes = sch_ep->cs_count + 2;
+			sch_ep->bw_cost_per_microframe = max_packet_size;
+		}
+		if (ep_type == ISOC_OUT_EP) {
+			/* must never schedule a cs ISOC OUT ep */
+			sch_ep->cs_count = 0;
+			/*
+			 * the best case FS budget assumes that 188 FS bytes
+			 * occur in each microframe
+			 */
+			sch_ep->num_budget_microframes = DIV_ROUND_UP(
+				sch_ep->max_packet_size, FS_PAYLOAD_MAX);
+			sch_ep->bw_cost_per_microframe = FS_PAYLOAD_MAX;
+		}
+		if (ep_type == ISOC_IN_EP) {
+			/* at most need additional two CS. */
+			sch_ep->cs_count = DIV_ROUND_UP(
+				sch_ep->max_packet_size, FS_PAYLOAD_MAX) + 2;
+			sch_ep->num_budget_microframes = sch_ep->cs_count + 2;
+			sch_ep->bw_cost_per_microframe = FS_PAYLOAD_MAX;
+		}
+	}
+}
+
+/* Get maximum bandwidth when we schedule at offset slot. */
+static u32 get_max_bw(struct mu3h_sch_bw_info *sch_bw,
+	struct mu3h_sch_ep_info *sch_ep, u32 offset)
+{
+	u32 num_esit;
+	u32 max_bw = 0;
+	int i;
+	int j;
+
+	num_esit = XHCI_MTK_MAX_ESIT / sch_ep->esit;
+	for (i = 0; i < num_esit; i++) {
+		u32 base = offset + i * sch_ep->esit;
+
+		for (j = 0; j < sch_ep->num_budget_microframes; j++) {
+			if (sch_bw->bus_bw[base + j] > max_bw)
+				max_bw = sch_bw->bus_bw[base + j];
+		}
+	}
+	return max_bw;
+}
+
+static void update_bus_bw(struct mu3h_sch_bw_info *sch_bw,
+	struct mu3h_sch_ep_info *sch_ep, int bw_cost)
+{
+	u32 num_esit;
+	u32 base;
+	int i;
+	int j;
+
+	num_esit = XHCI_MTK_MAX_ESIT / sch_ep->esit;
+	for (i = 0; i < num_esit; i++) {
+		base = sch_ep->offset + i * sch_ep->esit;
+		for (j = 0; j < sch_ep->num_budget_microframes; j++)
+			sch_bw->bus_bw[base + j] += bw_cost;
+	}
+}
+
+static int check_sch_bw(struct usb_device *udev,
+	struct mu3h_sch_bw_info *sch_bw, struct mu3h_sch_ep_info *sch_ep)
+{
+	u32 offset;
+	u32 esit;
+	u32 num_budget_microframes;
+	u32 min_bw;
+	u32 min_index;
+	u32 worst_bw;
+	u32 bw_boundary;
+
+	if (sch_ep->esit > XHCI_MTK_MAX_ESIT)
+		sch_ep->esit = XHCI_MTK_MAX_ESIT;
+
+	esit = sch_ep->esit;
+	num_budget_microframes = sch_ep->num_budget_microframes;
+
+	/*
+	 * Search through all possible schedule microframes.
+	 * and find a microframe where its worst bandwidth is minimum.
+	 */
+	min_bw = ~0;
+	min_index = 0;
+	for (offset = 0; offset < esit; offset++) {
+		if ((offset + num_budget_microframes) > sch_ep->esit)
+			break;
+		/*
+		 * usb_20 spec section11.18:
+		 * must never schedule Start-Split in Y6
+		 */
+		if (is_fs_or_ls(udev->speed) && (offset % 8 == 6))
+			continue;
+
+		worst_bw = get_max_bw(sch_bw, sch_ep, offset);
+		if (min_bw > worst_bw) {
+			min_bw = worst_bw;
+			min_index = offset;
+		}
+		if (min_bw == 0)
+			break;
+	}
+	sch_ep->offset = min_index;
+
+	bw_boundary = (udev->speed == USB_SPEED_SUPER)
+				? SS_BW_BOUNDARY : HS_BW_BOUNDARY;
+
+	/* check bandwidth */
+	if (min_bw + sch_ep->bw_cost_per_microframe > bw_boundary)
+		return -1;
+
+	/* update bus bandwidth info */
+	update_bus_bw(sch_bw, sch_ep, sch_ep->bw_cost_per_microframe);
+
+	return 0;
+}
+
+static bool need_bw_sch(struct usb_host_endpoint *ep,
+	enum usb_device_speed speed, int has_tt)
+{
+	/* only for periodic endpoints */
+	if (usb_endpoint_xfer_control(&ep->desc)
+		|| usb_endpoint_xfer_bulk(&ep->desc))
+		return false;
+	/*
+	 * for LS & FS periodic endpoints which its device don't attach
+	 * to TT are also ignored, root-hub will schedule them directly
+	 */
+	if (is_fs_or_ls(speed) && !has_tt)
+		return false;
+
+	return true;
+}
+
+int xhci_mtk_sch_init(struct xhci_hcd *xhci)
+{
+	struct usb_hcd *hcd = xhci_to_hcd(xhci);
+	struct device *dev = hcd->self.controller;
+	struct xhci_hcd_mtk *mtk = dev_get_drvdata(dev);
+	struct mu3h_sch_bw_info *sch_array;
+	int num_usb_bus;
+	int i;
+
+	/* ss IN and OUT are separated */
+	num_usb_bus = xhci->num_usb3_ports * 2 + xhci->num_usb2_ports;
+
+	sch_array = kcalloc(num_usb_bus, sizeof(*sch_array), GFP_KERNEL);
+	if (sch_array == NULL)
+		return -ENOMEM;
+
+	for (i = 0; i < num_usb_bus; i++)
+		INIT_LIST_HEAD(&sch_array[i].bw_ep_list);
+
+	mtk->sch_array = sch_array;
+
+	return 0;
+}
+EXPORT_SYMBOL_GPL(xhci_mtk_sch_init);
+
+void xhci_mtk_sch_exit(struct xhci_hcd *xhci)
+{
+	struct usb_hcd *hcd = xhci_to_hcd(xhci);
+	struct device *dev = hcd->self.controller;
+	struct xhci_hcd_mtk *mtk = dev_get_drvdata(dev);
+
+	kfree(mtk->sch_array);
+}
+EXPORT_SYMBOL_GPL(xhci_mtk_sch_exit);
+
+int xhci_mtk_add_ep_quirk(struct usb_hcd *hcd, struct usb_device *udev,
+		struct usb_host_endpoint *ep)
+{
+	struct device *dev = hcd->self.controller;
+	struct xhci_hcd_mtk *mtk = dev_get_drvdata(dev);
+
+	int ret = 0;
+	int port_id;
+	int bw_index;
+	struct xhci_hcd *xhci;
+	unsigned int ep_index;
+	struct xhci_ep_ctx *ep_ctx;
+	struct xhci_slot_ctx *slot_ctx;
+	struct xhci_virt_device *virt_dev;
+	struct mu3h_sch_bw_info *sch_bw;
+	struct mu3h_sch_ep_info *sch_ep;
+	struct mu3h_sch_bw_info *sch_array;
+
+	xhci = hcd_to_xhci(hcd);
+	virt_dev = xhci->devs[udev->slot_id];
+	ep_index = xhci_get_endpoint_index(&ep->desc);
+	slot_ctx = xhci_get_slot_ctx(xhci, virt_dev->in_ctx);
+	ep_ctx = xhci_get_ep_ctx(xhci, virt_dev->in_ctx, ep_index);
+	sch_array = mtk->sch_array;
+
+	port_id = virt_dev->real_port;
+	xhci_dbg(xhci, "%s() xfer_type: %d, speed:%d, ep:%p\n", __func__,
+		usb_endpoint_type(&ep->desc), udev->speed, ep);
+
+	if (!need_bw_sch(ep, udev->speed, slot_ctx->tt_info & TT_SLOT))
+		return 0;
+
+	bw_index = get_bw_index(xhci, udev, ep);
+	sch_bw = &sch_array[bw_index];
+
+	sch_ep = kzalloc(sizeof(struct mu3h_sch_ep_info), GFP_NOIO);
+	if (!sch_ep)
+		return -ENOMEM;
+
+	setup_sch_info(udev, ep_ctx, sch_ep);
+
+	ret = check_sch_bw(udev, sch_bw, sch_ep);
+	if (ret) {
+		xhci_err(xhci, "Not enough bandwidth!\n");
+		kfree(sch_ep);
+		return -ENOSPC;
+	}
+
+	list_add_tail(&sch_ep->endpoint, &sch_bw->bw_ep_list);
+	sch_ep->ep = ep;
+
+	ep_ctx->reserved[0] |= cpu_to_le32(EP_BPKTS(sch_ep->pkts)
+		| EP_BCSCOUNT(sch_ep->cs_count) | EP_BBM(sch_ep->burst_mode));
+	ep_ctx->reserved[1] |= cpu_to_le32(EP_BOFFSET(sch_ep->offset)
+		| EP_BREPEAT(sch_ep->repeat));
+
+	return 0;
+}
+EXPORT_SYMBOL_GPL(xhci_mtk_add_ep_quirk);
+
+void xhci_mtk_drop_ep_quirk(struct usb_hcd *hcd, struct usb_device *udev,
+		struct usb_host_endpoint *ep)
+{
+	struct device *dev = hcd->self.controller;
+	struct xhci_hcd_mtk *mtk = dev_get_drvdata(dev);
+
+	int bw_index;
+	struct xhci_hcd *xhci;
+	struct xhci_slot_ctx *slot_ctx;
+	struct xhci_virt_device *virt_dev;
+	struct mu3h_sch_bw_info *sch_array;
+	struct mu3h_sch_bw_info *sch_bw;
+	struct mu3h_sch_ep_info *sch_ep;
+
+	xhci = hcd_to_xhci(hcd);
+	virt_dev = xhci->devs[udev->slot_id];
+	slot_ctx = xhci_get_slot_ctx(xhci, virt_dev->in_ctx);
+	sch_array = mtk->sch_array;
+
+	xhci_dbg(xhci, "%s() xfer_type: %d, speed:%d, ep:%p\n", __func__,
+		usb_endpoint_type(&ep->desc), udev->speed, ep);
+
+	if (!need_bw_sch(ep, udev->speed, slot_ctx->tt_info & TT_SLOT))
+		return;
+
+	bw_index = get_bw_index(xhci, udev, ep);
+	sch_bw = &sch_array[bw_index];
+
+	list_for_each_entry(sch_ep, &sch_bw->bw_ep_list, endpoint) {
+		if (sch_ep->ep == ep) {
+			update_bus_bw(sch_bw, sch_ep,
+				-sch_ep->bw_cost_per_microframe);
+			list_del(&sch_ep->endpoint);
+			kfree(sch_ep);
+			break;
+		}
+	}
+}
+EXPORT_SYMBOL_GPL(xhci_mtk_drop_ep_quirk);
+
+/*
+ * The TD size is the number of max packet sized packets remaining in the TD
+ * (including this TRB), right shifted by 10.
+ * It must fit in bits 21:17, so it can't be bigger than 31.
+ */
+u32 xhci_mtk_td_remainder_quirk(unsigned int td_running_total,
+	unsigned trb_buffer_length, struct urb *urb)
+{
+	u32 max = 31;
+	int remainder, td_packet_count, packet_transferred;
+	unsigned int td_transfer_size = urb->transfer_buffer_length;
+	unsigned int maxp;
+
+	maxp = GET_MAX_PACKET(usb_endpoint_maxp(&urb->ep->desc));
+
+	/* 0 for the last TRB */
+	if (td_running_total + trb_buffer_length == td_transfer_size)
+		return 0;
+
+	packet_transferred = td_running_total / maxp;
+	td_packet_count = DIV_ROUND_UP(td_transfer_size, maxp);
+	remainder = td_packet_count - packet_transferred;
+
+	if (remainder > max)
+		return max << 17;
+	else
+		return remainder << 17;
+}
+EXPORT_SYMBOL_GPL(xhci_mtk_td_remainder_quirk);
diff --git a/drivers/usb/host/xhci-mtk.c b/drivers/usb/host/xhci-mtk.c
new file mode 100644
index 0000000..6f535a2
--- /dev/null
+++ b/drivers/usb/host/xhci-mtk.c
@@ -0,0 +1,837 @@
+/*
+ * Copyright (c) 2015 MediaTek Inc.
+ * Author:
+ *  Chunfeng Yun <chunfeng.yun at mediatek.com>
+ *
+ * This software is licensed under the terms of the GNU General Public
+ * License version 2, as published by the Free Software Foundation, and
+ * may be copied, distributed, and modified under those terms.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ * GNU General Public License for more details.
+ *
+ */
+
+#include <linux/clk.h>
+#include <linux/dma-mapping.h>
+#include <linux/iopoll.h>
+#include <linux/kernel.h>
+#include <linux/mfd/syscon.h>
+#include <linux/module.h>
+#include <linux/of.h>
+#include <linux/phy/phy.h>
+#include <linux/platform_device.h>
+#include <linux/pm_runtime.h>
+#include <linux/regmap.h>
+#include <linux/regulator/consumer.h>
+#include <linux/slab.h>
+#include <linux/usb/phy.h>
+#include <linux/usb/xhci_pdriver.h>
+
+#include "xhci.h"
+#include "xhci-mtk.h"
+
+#define SSUSB_USB3_MAC_CSR_BASE	(0x2400)
+#define SSUSB_USB3_SYS_CSR_BASE	(0x2400)
+#define SSUSB_USB2_CSR_BASE	(0x3400)
+
+#define SSUSB_SIFSLV_IPPC_BASE	(0x700)
+
+#define U3P_UX_EXIT_LFPS_PARAM	(SSUSB_USB3_MAC_CSR_BASE + 0x00A0)
+#define RX_UX_EXIT_REF		(0xff << 8)
+#define RX_UX_EXIT_REF_VAL	(0x3 << 8)
+
+#define U3P_REF_CLK_PARAM	(SSUSB_USB3_MAC_CSR_BASE + 0x00B0)
+#define REF_CLK_1000NS		(0xff << 0)
+#define REF_CLK_VAL_DEF		(0xa << 0)
+
+#define U3P_LINK_PM_TIMER	(SSUSB_USB3_SYS_CSR_BASE + 0x0208)
+#define PM_LC_TIMEOUT		(0xf << 0)
+#define PM_LC_TIMEOUT_VAL	(0x3 << 0)
+
+#define U3P_TIMING_PULSE_CTRL	(SSUSB_USB3_SYS_CSR_BASE + 0x02B4)
+#define U3T_CNT_1US			(0xff << 0)
+#define U3T_CNT_1US_VAL		(0x3f << 0)	/* 62.5MHz: 63 */
+
+#define U3P_U2_TIMING_PARAM	(SSUSB_USB2_CSR_BASE + 0x0040)
+#define U2T_VAL_1US		(0xff << 0)
+#define U2T_VAL_1US_VAL	(0x3f << 0)	/* 62.5MHz: 63 */
+
+#define U3P_IP_PW_CTRL0	(SSUSB_SIFSLV_IPPC_BASE + 0x0000)
+#define CTRL0_IP_SW_RST	BIT(0)
+
+#define U3P_IP_PW_CTRL1	(SSUSB_SIFSLV_IPPC_BASE + 0x0004)
+#define CTRL1_IP_HOST_PDN	BIT(0)
+
+#define U3P_IP_PW_CTRL2	(SSUSB_SIFSLV_IPPC_BASE + 0x0008)
+#define CTRL2_IP_DEV_PDN	BIT(0)
+
+#define U3P_IP_PW_STS1	(SSUSB_SIFSLV_IPPC_BASE + 0x0010)
+#define STS1_IP_SLEEP_STS	BIT(30)
+#define STS1_U3_MAC_RST	BIT(16)
+#define STS1_SYS125_RST	BIT(10)
+#define STS1_REF_RST		BIT(8)
+#define STS1_SYSPLL_STABLE	BIT(0)
+
+#define U3P_IP_PW_STS2	(SSUSB_SIFSLV_IPPC_BASE + 0x0014)
+#define STS2_U2_MAC_RST	BIT(0)
+
+#define U3P_IP_XHCI_CAP	(SSUSB_SIFSLV_IPPC_BASE + 0x0024)
+#define CAP_U3_PORT_NUM(p)	((p) & 0xff)
+#define CAP_U2_PORT_NUM(p)	(((p) >> 8) & 0xff)
+
+#define U3P_U3_CTRL_0P	(SSUSB_SIFSLV_IPPC_BASE + 0x0030)
+#define CTRL_U3_PORT_HOST_SEL	BIT(2)
+#define CTRL_U3_PORT_PDN	BIT(1)
+#define CTRL_U3_PORT_DIS	BIT(0)
+
+#define U3P_U2_CTRL_0P	(SSUSB_SIFSLV_IPPC_BASE + 0x0050)
+#define CTRL_U2_PORT_HOST_SEL	BIT(2)
+#define CTRL_U2_PORT_PDN	BIT(1)
+#define CTRL_U2_PORT_DIS	BIT(0)
+
+#define U3P_U2_PHY_PLL	(SSUSB_SIFSLV_IPPC_BASE+0x007c)
+#define CTRL_U2_FORCE_PLL_STB	(0x1<<28)
+
+#define U3P_U3_CTRL(p)	(U3P_U3_CTRL_0P + ((p) * 0x08))
+#define U3P_U2_CTRL(p)	(U3P_U2_CTRL_0P + ((p) * 0x08))
+
+#define PERI_WK_CTRL0		0x400
+#define UWK_CTR0_0P_LS_PE	BIT(8)  /* posedge */
+#define UWK_CTR0_0P_LS_NE	BIT(7)  /* negedge for 0p linestate*/
+#define UWK_CTL1_1P_LS_C(x)	(((x) & 0xf) << 1)
+#define UWK_CTL1_1P_LS_E	BIT(0)
+
+#define PERI_WK_CTRL1		0x404
+#define UWK_CTL1_IS_C(x)	(((x) & 0xf) << 26)
+#define UWK_CTL1_IS_E		BIT(25)
+#define UWK_CTL1_0P_LS_C(x)	(((x) & 0xf) << 21)
+#define UWK_CTL1_0P_LS_E	BIT(20)
+#define UWK_CTL1_IDDIG_C(x)	(((x) & 0xf) << 11)  /* cycle debounce */
+#define UWK_CTL1_IDDIG_E	BIT(10) /* enable debounce */
+#define UWK_CTL1_IDDIG_P	BIT(9)  /* polarity */
+#define UWK_CTL1_0P_LS_P	BIT(7)
+#define UWK_CTL1_IS_P		BIT(6)  /* polarity for ip sleep */
+
+enum ssusb_wakeup_src {
+	SSUSB_WK_IP_SLEEP = 1,
+	SSUSB_WK_LINE_STATE = 2,
+};
+
+static int check_ip_clk_status(struct xhci_hcd_mtk *mtk)
+{
+	int ret;
+	int u3_port_num;
+	int u2_port_num;
+	u32 xhci_cap;
+	u32 val;
+	void __iomem *ippc_base = mtk->ippc_base;
+
+	xhci_cap = readl(ippc_base + U3P_IP_XHCI_CAP);
+	u3_port_num = CAP_U3_PORT_NUM(xhci_cap);
+	u2_port_num = CAP_U2_PORT_NUM(xhci_cap);
+
+	ret = readl_poll_timeout(ippc_base + U3P_IP_PW_STS1, val,
+			  (val & STS1_SYSPLL_STABLE), 100, 10000);
+	if (ret) {
+		dev_err(mtk->dev, "syspll is not stable!!!\n");
+		return ret;
+	}
+
+	ret = readl_poll_timeout(ippc_base + U3P_IP_PW_STS1, val,
+			  (val & STS1_REF_RST), 100, 10000);
+	if (ret) {
+		dev_err(mtk->dev, "ref_clk is still active!!!\n");
+		return ret;
+	}
+
+	ret = readl_poll_timeout(ippc_base + U3P_IP_PW_STS1, val,
+			   (val & STS1_SYS125_RST), 100, 10000);
+	if (ret) {
+		dev_err(mtk->dev, "sys125_ck is still active!!!\n");
+		return ret;
+	}
+
+	if (u3_port_num) {
+		ret = readl_poll_timeout(ippc_base + U3P_IP_PW_STS1, val,
+				   (val & STS1_U3_MAC_RST), 100, 10000);
+		if (ret) {
+			dev_err(mtk->dev, "mac3_mac_ck is still active!!!\n");
+			return ret;
+		}
+	}
+
+	if (u2_port_num) {
+		ret = readl_poll_timeout(ippc_base + U3P_IP_PW_STS2, val,
+				   (val & STS2_U2_MAC_RST), 100, 10000);
+		if (ret) {
+			dev_err(mtk->dev, "mac2_sys_ck is still active!!!\n");
+			return ret;
+		}
+	}
+
+	return 0;
+}
+
+static int xhci_mtk_ports_enable(struct xhci_hcd_mtk *mtk)
+{
+	int i;
+	u32 temp;
+	int u3_port_num;
+	int u2_port_num;
+	void __iomem *ippc_base = mtk->ippc_base;
+
+	temp = readl(ippc_base + U3P_IP_XHCI_CAP);
+	u3_port_num = CAP_U3_PORT_NUM(temp);
+	u2_port_num = CAP_U2_PORT_NUM(temp);
+	dev_dbg(mtk->dev, "%s u2p:%d, u3p:%d\n", __func__,
+			u2_port_num, u3_port_num);
+
+	/* power on host ip */
+	temp = readl(ippc_base + U3P_IP_PW_CTRL1);
+	temp &= ~CTRL1_IP_HOST_PDN;
+	writel(temp, ippc_base + U3P_IP_PW_CTRL1);
+
+	/* power on and enable all u3 ports */
+	for (i = 0; i < u3_port_num; i++) {
+		temp = readl(ippc_base + U3P_U3_CTRL(i));
+		temp &= ~(CTRL_U3_PORT_PDN | CTRL_U3_PORT_DIS);
+		temp |= CTRL_U3_PORT_HOST_SEL;
+		writel(temp, ippc_base + U3P_U3_CTRL(i));
+	}
+
+	/* power on and enable all u2 ports */
+	for (i = 0; i < u2_port_num; i++) {
+		temp = readl(ippc_base + U3P_U2_CTRL(i));
+		temp &= ~(CTRL_U2_PORT_PDN | CTRL_U2_PORT_DIS);
+		temp |= CTRL_U2_PORT_HOST_SEL;
+		writel(temp, ippc_base + U3P_U2_CTRL(i));
+	}
+	return check_ip_clk_status(mtk);
+}
+
+static int xhci_mtk_ports_disable(struct xhci_hcd_mtk *mtk)
+{
+	int i;
+	u32 temp;
+	int ret;
+	int u3_port_num;
+	int u2_port_num;
+	void __iomem *ippc_base = mtk->ippc_base;
+
+	temp = readl(ippc_base + U3P_IP_XHCI_CAP);
+	u3_port_num = CAP_U3_PORT_NUM(temp);
+	u2_port_num = CAP_U2_PORT_NUM(temp);
+	dev_dbg(mtk->dev, "%s u2p:%d, u3p:%d\n", __func__,
+			u2_port_num, u3_port_num);
+
+	/* disable all u3 ports */
+	for (i = 0; i < u3_port_num; i++) {
+		temp = readl(ippc_base + U3P_U3_CTRL(i));
+		temp |= CTRL_U3_PORT_PDN;
+		writel(temp, ippc_base + U3P_U3_CTRL(i));
+	}
+
+	/* disable all u2 ports */
+	for (i = 0; i < u2_port_num; i++) {
+		temp = readl(ippc_base + U3P_U2_CTRL(i));
+		temp |= CTRL_U2_PORT_PDN;
+		writel(temp, ippc_base + U3P_U2_CTRL(i));
+	}
+
+	/* power off ip */
+	temp = readl(ippc_base + U3P_IP_PW_CTRL1);
+	temp |= CTRL1_IP_HOST_PDN;
+	writel(temp, ippc_base + U3P_IP_PW_CTRL1);
+
+	temp = readl(ippc_base + U3P_IP_PW_CTRL2);
+	temp |= CTRL2_IP_DEV_PDN;
+	writel(temp, ippc_base + U3P_IP_PW_CTRL2);
+
+	ret = readl_poll_timeout(ippc_base + U3P_IP_PW_STS1, temp,
+			  (temp & STS1_IP_SLEEP_STS), 100, 100000);
+	if (ret) {
+		dev_err(mtk->dev, "ip sleep failed!!!\n");
+		return ret;
+	}
+	return 0;
+}
+
+static void xhci_mtk_timing_init(struct xhci_hcd_mtk *mtk)
+{
+	void __iomem *mbase = mtk->mac_base;
+	int u3_port_num;
+	u32 temp;
+
+	temp = readl(mtk->ippc_base + U3P_IP_XHCI_CAP);
+	u3_port_num = CAP_U3_PORT_NUM(temp);
+
+	if (u3_port_num) {
+		/* set MAC reference clock speed */
+		temp = readl(mbase + U3P_UX_EXIT_LFPS_PARAM);
+		temp &= ~RX_UX_EXIT_REF;
+		temp |= RX_UX_EXIT_REF_VAL;
+		writel(temp, mbase + U3P_UX_EXIT_LFPS_PARAM);
+		/* set REF_CLK */
+		temp = readl(mbase + U3P_REF_CLK_PARAM);
+		temp &= ~REF_CLK_1000NS;
+		temp |= REF_CLK_VAL_DEF;
+		writel(temp, mbase + U3P_REF_CLK_PARAM);
+		/* set SYS_CLK */
+		temp = readl(mbase + U3P_TIMING_PULSE_CTRL);
+		temp &= ~U3T_CNT_1US;
+		temp |= U3T_CNT_1US_VAL;
+		writel(temp, mbase + U3P_TIMING_PULSE_CTRL);
+		/* set LINK_PM_TIMER=3 */
+		temp = readl(mbase + U3P_LINK_PM_TIMER);
+		temp &= ~PM_LC_TIMEOUT;
+		temp |= PM_LC_TIMEOUT_VAL;
+		writel(temp, mbase + U3P_LINK_PM_TIMER);
+	}
+
+	temp = readl(mbase + U3P_U2_TIMING_PARAM);
+	temp &= ~U2T_VAL_1US;
+	temp |= U2T_VAL_1US_VAL;
+	writel(temp, mbase + U3P_U2_TIMING_PARAM);
+}
+
+static void xhci_mtk_ports_config(struct xhci_hcd_mtk *mtk)
+{
+	u32 temp;
+
+	/* reset whole ip */
+	temp = readl(mtk->ippc_base + U3P_IP_PW_CTRL0);
+	temp |= CTRL0_IP_SW_RST;
+	writel(temp, mtk->ippc_base + U3P_IP_PW_CTRL0);
+	udelay(1);
+	temp = readl(mtk->ippc_base + U3P_IP_PW_CTRL0);
+	temp &= ~CTRL0_IP_SW_RST;
+	writel(temp, mtk->ippc_base + U3P_IP_PW_CTRL0);
+
+	xhci_mtk_ports_enable(mtk);
+	xhci_mtk_timing_init(mtk);
+}
+
+static int xhci_mtk_clks_enable(struct xhci_hcd_mtk *mtk)
+{
+	int ret;
+
+	ret = clk_prepare_enable(mtk->sys_mac);
+	if (ret) {
+		dev_err(mtk->dev, "failed to enable u3phya_ref\n");
+		goto u3phya_ref_err;
+	}
+	ret = clk_prepare_enable(mtk->wk_deb_p0);
+	if (ret) {
+		dev_err(mtk->dev, "failed to enable wk_deb_p0\n");
+		goto usb_p0_err;
+	}
+	if (mtk->num_phys > 1) {
+		ret = clk_prepare_enable(mtk->wk_deb_p1);
+		if (ret) {
+			dev_err(mtk->dev, "failed to enable wk_deb_p1\n");
+			goto usb_p1_err;
+		}
+	}
+
+	return 0;
+
+usb_p1_err:
+	clk_disable_unprepare(mtk->wk_deb_p0);
+usb_p0_err:
+	clk_disable_unprepare(mtk->sys_mac);
+u3phya_ref_err:
+	return -EINVAL;
+}
+
+static void xhci_mtk_clks_disable(struct xhci_hcd_mtk *mtk)
+{
+	if (mtk->num_phys > 1)
+		clk_disable_unprepare(mtk->wk_deb_p1);
+	clk_disable_unprepare(mtk->wk_deb_p0);
+	clk_disable_unprepare(mtk->sys_mac);
+}
+
+/* only clocks can be turn off for ip-sleep wakeup mode */
+static void usb_wakeup_ip_sleep_en(struct xhci_hcd_mtk *mtk)
+{
+	u32 tmp;
+	struct regmap *pericfg = mtk->pericfg;
+
+	regmap_read(pericfg, PERI_WK_CTRL1, &tmp);
+	tmp &= ~UWK_CTL1_IS_P;
+	tmp &= ~(UWK_CTL1_IS_C(0xf));
+	tmp |= UWK_CTL1_IS_C(0x8);
+	regmap_write(pericfg, PERI_WK_CTRL1, tmp);
+	regmap_write(pericfg, PERI_WK_CTRL1, tmp | UWK_CTL1_IS_E);
+
+	regmap_read(pericfg, PERI_WK_CTRL1, &tmp);
+	dev_dbg(mtk->dev, "%s(): WK_CTRL1[P6,E25,C26:29]=%#x\n",
+		__func__, tmp);
+}
+
+static void usb_wakeup_ip_sleep_dis(struct xhci_hcd_mtk *mtk)
+{
+	u32 tmp;
+
+	regmap_read(mtk->pericfg, PERI_WK_CTRL1, &tmp);
+	tmp &= ~UWK_CTL1_IS_E;
+	regmap_write(mtk->pericfg, PERI_WK_CTRL1, tmp);
+}
+
+/*
+* for line-state wakeup mode, phy's power should not power-down
+* and only support cable plug in/out
+*/
+static void usb_wakeup_line_state_en(struct xhci_hcd_mtk *mtk)
+{
+	u32 tmp;
+	struct regmap *pericfg = mtk->pericfg;
+
+	/* line-state of u2-port0 */
+	regmap_read(pericfg, PERI_WK_CTRL1, &tmp);
+	tmp &= ~UWK_CTL1_0P_LS_P;
+	tmp &= ~(UWK_CTL1_0P_LS_C(0xf));
+	tmp |= UWK_CTL1_0P_LS_C(0x8);
+	regmap_write(pericfg, PERI_WK_CTRL1, tmp);
+	regmap_read(pericfg, PERI_WK_CTRL1, &tmp);
+	regmap_write(pericfg, PERI_WK_CTRL1, tmp | UWK_CTL1_0P_LS_E);
+
+	/* line-state of u2-port1 if support */
+	if (mtk->num_phys > 1) {
+		regmap_read(pericfg, PERI_WK_CTRL0, &tmp);
+		tmp &= ~(UWK_CTL1_1P_LS_C(0xf));
+		tmp |= UWK_CTL1_1P_LS_C(0x8);
+		regmap_write(pericfg, PERI_WK_CTRL0, tmp);
+		regmap_write(pericfg, PERI_WK_CTRL0, tmp | UWK_CTL1_1P_LS_E);
+	}
+}
+
+static void usb_wakeup_line_state_dis(struct xhci_hcd_mtk *mtk)
+{
+	u32 tmp;
+	struct regmap *pericfg = mtk->pericfg;
+
+	regmap_read(pericfg, PERI_WK_CTRL1, &tmp);
+	tmp &= ~UWK_CTL1_0P_LS_E;
+	regmap_write(pericfg, PERI_WK_CTRL1, tmp);
+
+	if (mtk->num_phys > 1) {
+		regmap_read(pericfg, PERI_WK_CTRL0, &tmp);
+		tmp &= ~UWK_CTL1_1P_LS_E;
+		regmap_write(pericfg, PERI_WK_CTRL0, tmp);
+	}
+}
+
+static void usb_wakeup_enable(struct xhci_hcd_mtk *mtk)
+{
+	if (mtk->wakeup_src == SSUSB_WK_IP_SLEEP)
+		usb_wakeup_ip_sleep_en(mtk);
+	else if (mtk->wakeup_src == SSUSB_WK_LINE_STATE)
+		usb_wakeup_line_state_en(mtk);
+}
+
+static void usb_wakeup_disable(struct xhci_hcd_mtk *mtk)
+{
+	if (mtk->wakeup_src == SSUSB_WK_IP_SLEEP)
+		usb_wakeup_ip_sleep_dis(mtk);
+	else if (mtk->wakeup_src == SSUSB_WK_LINE_STATE)
+		usb_wakeup_line_state_dis(mtk);
+}
+
+
+static int xhci_mtk_setup(struct usb_hcd *hcd);
+static const struct xhci_driver_overrides xhci_mtk_overrides __initconst = {
+	.extra_priv_size = sizeof(struct xhci_hcd),
+	.reset = xhci_mtk_setup,
+};
+
+static struct hc_driver __read_mostly xhci_mtk_hc_driver;
+
+static int xhci_mtk_phy_enable(struct xhci_hcd_mtk *mtk)
+{
+	unsigned int i;
+	int ret;
+
+	for (i = 0; i < mtk->num_phys; i++) {
+		ret = phy_init(mtk->phys[i]);
+		if (ret)
+			goto disable_phy;
+		ret = phy_power_on(mtk->phys[i]);
+		if (ret) {
+			phy_exit(mtk->phys[i]);
+			goto disable_phy;
+		}
+	}
+
+	return 0;
+
+disable_phy:
+	for (; i > 0; i--) {
+		phy_power_off(mtk->phys[i - 1]);
+		phy_exit(mtk->phys[i - 1]);
+	}
+	return ret;
+}
+
+static void xhci_mtk_phy_disable(struct xhci_hcd_mtk *mtk)
+{
+	unsigned int i;
+
+	for (i = 0; i < mtk->num_phys; i++) {
+		phy_power_off(mtk->phys[i]);
+		phy_exit(mtk->phys[i]);
+	}
+}
+
+static int xhci_mtk_ldos_enable(struct xhci_hcd_mtk *mtk)
+{
+	int ret;
+
+	ret = regulator_enable(mtk->vbus);
+	if (ret) {
+		dev_err(mtk->dev, "failed to enable vbus\n");
+		return ret;
+	}
+
+	ret = regulator_enable(mtk->vusb33);
+	if (ret) {
+		dev_err(mtk->dev, "failed to enable vusb33\n");
+		regulator_disable(mtk->vbus);
+		return ret;
+	}
+	return 0;
+}
+
+static void xhci_mtk_ldos_disable(struct xhci_hcd_mtk *mtk)
+{
+	regulator_disable(mtk->vbus);
+	regulator_disable(mtk->vusb33);
+}
+
+static void xhci_mtk_quirks(struct device *dev, struct xhci_hcd *xhci)
+{
+	/*
+	 * As of now platform drivers don't provide MSI support so we ensure
+	 * here that the generic code does not try to make a pci_dev from our
+	 * dev struct in order to setup MSI
+	 */
+	xhci->quirks |= XHCI_PLAT;
+	xhci->quirks |= XHCI_MTK_HOST;
+	/*
+	 * MTK host controller gives a spurious successful event after a
+	 * short transfer. Ignore it.
+	 */
+	xhci->quirks |= XHCI_SPURIOUS_SUCCESS;
+}
+
+/* called during probe() after chip reset completes */
+static int xhci_mtk_setup(struct usb_hcd *hcd)
+{
+	struct xhci_hcd *xhci;
+	int ret;
+
+	ret = xhci_gen_setup(hcd, xhci_mtk_quirks);
+	if (ret)
+		return ret;
+
+	if (!usb_hcd_is_primary_hcd(hcd))
+		return 0;
+
+	xhci = hcd_to_xhci(hcd);
+	ret = xhci_mtk_sch_init(xhci);
+	if (ret) {
+		kfree(xhci);
+		return ret;
+	}
+
+	return ret;
+}
+
+
+static int xhci_mtk_probe(struct platform_device *pdev)
+{
+	struct device *dev = &pdev->dev;
+	struct device_node *node = dev->of_node;
+	struct usb_xhci_pdata *pdata = dev_get_platdata(dev);
+	struct xhci_hcd_mtk *mtk;
+	const struct hc_driver *driver;
+	struct xhci_hcd *xhci;
+	struct resource *res;
+	struct usb_hcd *hcd;
+	struct phy *phy;
+	int phy_num;
+	int ret = -ENODEV;
+	int irq;
+
+	if (usb_disabled())
+		return -ENODEV;
+
+	driver = &xhci_mtk_hc_driver;
+	mtk = devm_kzalloc(dev, sizeof(*mtk), GFP_KERNEL);
+	if (!mtk)
+		return -ENOMEM;
+
+	mtk->dev = dev;
+	mtk->vbus = devm_regulator_get(dev, "vbus");
+	if (IS_ERR(mtk->vbus)) {
+		dev_err(dev, "fail to get vbus\n");
+		return PTR_ERR(mtk->vbus);
+	}
+
+	mtk->vusb33 = devm_regulator_get(dev, "vusb33");
+	if (IS_ERR(mtk->vusb33)) {
+		dev_err(dev, "fail to get vusb33\n");
+		return PTR_ERR(mtk->vusb33);
+	}
+
+	mtk->sys_mac = devm_clk_get(dev, "sys_ck");
+	if (IS_ERR(mtk->sys_mac)) {
+		dev_err(dev, "fail to get sys_ck\n");
+		return PTR_ERR(mtk->sys_mac);
+	}
+
+	of_property_read_u32(node, "mediatek,wakeup-src", &mtk->wakeup_src);
+
+	mtk->wk_deb_p0 = devm_clk_get(dev, "wakeup_deb_p0");
+	if (IS_ERR(mtk->wk_deb_p0)) {
+		dev_err(dev, "fail to get wakeup_deb_p0\n");
+		return PTR_ERR(mtk->wk_deb_p0);
+	}
+
+	mtk->wk_deb_p1 = devm_clk_get(dev, "wakeup_deb_p1");
+	if (IS_ERR(mtk->wk_deb_p1)) {
+		dev_err(dev, "fail to get wakeup_deb_p1\n");
+		return PTR_ERR(mtk->wk_deb_p1);
+	}
+
+	mtk->pericfg = syscon_regmap_lookup_by_phandle(node,
+						"mediatek,syscon-wakeup");
+	if (IS_ERR(mtk->pericfg)) {
+		dev_err(dev, "fail to get pericfg regs\n");
+		return PTR_ERR(mtk->pericfg);
+	}
+
+	mtk->num_phys = of_count_phandle_with_args(node,
+			"phys", "#phy-cells");
+	if (mtk->num_phys > 0) {
+		mtk->phys = devm_kcalloc(dev, mtk->num_phys,
+					sizeof(*mtk->phys), GFP_KERNEL);
+		if (!mtk->phys)
+			return -ENOMEM;
+	} else {
+		mtk->num_phys = 0;
+	}
+	pm_runtime_enable(dev);
+	pm_runtime_get_sync(dev);
+
+	ret = xhci_mtk_ldos_enable(mtk);
+	if (ret)
+		goto disable_pm;
+
+	ret = xhci_mtk_clks_enable(mtk);
+	if (ret)
+		goto disable_ldos;
+
+	irq = platform_get_irq(pdev, 0);
+	if (irq < 0)
+		goto disable_clk;
+
+	/* Initialize dma_mask and coherent_dma_mask to 32-bits */
+	ret = dma_set_coherent_mask(dev, DMA_BIT_MASK(32));
+	if (ret)
+		goto disable_clk;
+
+	if (!dev->dma_mask)
+		dev->dma_mask = &dev->coherent_dma_mask;
+	else
+		dma_set_mask(dev, DMA_BIT_MASK(32));
+
+	hcd = usb_create_hcd(driver, dev, dev_name(dev));
+	if (!hcd) {
+		ret = -ENOMEM;
+		goto disable_clk;
+	}
+
+	/*
+	 * USB 2.0 roothub is stored in the platform_device.
+	 * Swap it with mtk HCD.
+	 */
+	mtk->hcd = platform_get_drvdata(pdev);
+	platform_set_drvdata(pdev, mtk);
+
+	res = platform_get_resource(pdev, IORESOURCE_MEM, 0);
+	hcd->regs = devm_ioremap_resource(dev, res);
+	if (IS_ERR(hcd->regs)) {
+		ret = PTR_ERR(hcd->regs);
+		goto put_usb2_hcd;
+	}
+	hcd->rsrc_start = res->start;
+	hcd->rsrc_len = resource_size(res);
+	mtk->mac_base = hcd->regs;
+
+	res = platform_get_resource(pdev, IORESOURCE_MEM, 1);
+	mtk->ippc_base = devm_ioremap_resource(dev, res);
+	if (IS_ERR(mtk->ippc_base)) {
+		ret = PTR_ERR(mtk->ippc_base);
+		goto put_usb2_hcd;
+	}
+
+	for (phy_num = 0; phy_num < mtk->num_phys; phy_num++) {
+		phy = devm_of_phy_get_by_index(dev, node, phy_num);
+		if (IS_ERR(phy)) {
+			ret = PTR_ERR(phy);
+			goto put_usb2_hcd;
+		}
+		mtk->phys[phy_num] = phy;
+	}
+
+	xhci_mtk_ports_config(mtk);
+	xhci_mtk_phy_enable(mtk);
+	device_init_wakeup(dev, 1);
+
+	xhci = hcd_to_xhci(hcd);
+	xhci->main_hcd = hcd;
+	xhci->shared_hcd = usb_create_shared_hcd(driver, dev,
+			dev_name(dev), hcd);
+	if (!xhci->shared_hcd) {
+		ret = -ENOMEM;
+		goto disable_usb_phy;
+	}
+
+	if ((node && of_property_read_bool(node, "usb3-lpm-capable")) ||
+			(pdata && pdata->usb3_lpm_capable))
+		xhci->quirks |= XHCI_LPM_SUPPORT;
+
+	if (HCC_MAX_PSA(xhci->hcc_params) >= 4)
+		xhci->shared_hcd->can_do_streams = 1;
+
+	ret = usb_add_hcd(hcd, irq, IRQF_SHARED);
+	if (ret)
+		goto put_usb3_hcd;
+
+	ret = usb_add_hcd(xhci->shared_hcd, irq, IRQF_SHARED);
+	if (ret)
+		goto dealloc_usb2_hcd;
+
+	return 0;
+
+dealloc_usb2_hcd:
+	usb_remove_hcd(hcd);
+
+put_usb3_hcd:
+	usb_put_hcd(xhci->shared_hcd);
+
+disable_usb_phy:
+	xhci_mtk_phy_disable(mtk);
+	device_init_wakeup(dev, 0);
+
+put_usb2_hcd:
+	usb_put_hcd(hcd);
+
+disable_clk:
+	xhci_mtk_clks_disable(mtk);
+
+disable_ldos:
+	xhci_mtk_ldos_disable(mtk);
+
+disable_pm:
+	pm_runtime_put_sync(dev);
+	pm_runtime_disable(dev);
+	return ret;
+}
+
+static int xhci_mtk_remove(struct platform_device *dev)
+{
+	struct xhci_hcd_mtk *mtk = platform_get_drvdata(dev);
+	struct usb_hcd	*hcd = mtk->hcd;
+	struct xhci_hcd	*xhci = hcd_to_xhci(hcd);
+
+	usb_remove_hcd(xhci->shared_hcd);
+	xhci_mtk_phy_disable(mtk);
+	device_init_wakeup(&dev->dev, 0);
+
+	usb_remove_hcd(hcd);
+	usb_put_hcd(xhci->shared_hcd);
+	usb_put_hcd(hcd);
+	xhci_mtk_sch_exit(xhci);
+	xhci_mtk_clks_disable(mtk);
+	xhci_mtk_ldos_disable(mtk);
+	pm_runtime_put_sync(&dev->dev);
+	pm_runtime_disable(&dev->dev);
+
+	return 0;
+}
+
+#ifdef CONFIG_PM_SLEEP
+static int xhci_mtk_suspend(struct device *dev)
+{
+	struct xhci_hcd_mtk *mtk = dev_get_drvdata(dev);
+	int i;
+
+	xhci_mtk_ports_disable(mtk);
+	for (i = 0; i < mtk->num_phys; i++)
+		phy_power_off(mtk->phys[i]);
+
+	xhci_mtk_clks_disable(mtk);
+	usb_wakeup_enable(mtk);
+	return 0;
+}
+
+static int xhci_mtk_resume(struct device *dev)
+{
+	struct xhci_hcd_mtk *mtk = dev_get_drvdata(dev);
+	int i;
+
+	usb_wakeup_disable(mtk);
+	xhci_mtk_clks_enable(mtk);
+	for (i = 0; i < mtk->num_phys; i++)
+		phy_power_on(mtk->phys[i]);
+
+	xhci_mtk_ports_enable(mtk);
+	return 0;
+}
+
+static const struct dev_pm_ops xhci_mtk_pm_ops = {
+	SET_SYSTEM_SLEEP_PM_OPS(xhci_mtk_suspend, xhci_mtk_resume)
+};
+#define DEV_PM_OPS	(&xhci_mtk_pm_ops)
+#else
+#define DEV_PM_OPS	NULL
+#endif /* CONFIG_PM */
+
+#ifdef CONFIG_OF
+static const struct of_device_id mtk_xhci_of_match[] = {
+	{ .compatible = "mediatek,mt8173-xhci"},
+	{ },
+};
+MODULE_DEVICE_TABLE(of, mtk_xhci_of_match);
+#endif
+
+static struct platform_driver mtk_xhci_driver = {
+	.probe	= xhci_mtk_probe,
+	.remove	= xhci_mtk_remove,
+	.driver	= {
+		.name = "xhci-mtk",
+		.pm = DEV_PM_OPS,
+		.of_match_table = of_match_ptr(mtk_xhci_of_match),
+	},
+};
+
+static int __init xhci_mtk_init(void)
+{
+	xhci_init_driver(&xhci_mtk_hc_driver, &xhci_mtk_overrides);
+	return platform_driver_register(&mtk_xhci_driver);
+}
+module_init(xhci_mtk_init);
+
+static void __exit xhci_mtk_exit(void)
+{
+	platform_driver_unregister(&mtk_xhci_driver);
+}
+module_exit(xhci_mtk_exit);
+
+MODULE_DESCRIPTION("MediaTek xHCI Host Controller Driver");
+MODULE_LICENSE("GPL v2");
diff --git a/drivers/usb/host/xhci-mtk.h b/drivers/usb/host/xhci-mtk.h
new file mode 100644
index 0000000..5adba62
--- /dev/null
+++ b/drivers/usb/host/xhci-mtk.h
@@ -0,0 +1,133 @@
+/*
+ * Copyright (c) 2015 MediaTek Inc.
+ * Author:
+ *  Zhigang.Wei <zhigang.wei at mediatek.com>
+ *  Chunfeng.Yun <chunfeng.yun at mediatek.com>
+ *
+ * This software is licensed under the terms of the GNU General Public
+ * License version 2, as published by the Free Software Foundation, and
+ * may be copied, distributed, and modified under those terms.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ * GNU General Public License for more details.
+ *
+ */
+
+#ifndef _XHCI_MTK_H_
+#define _XHCI_MTK_H_
+
+#include "xhci.h"
+
+/**
+ * To simplify scheduler algorithm, set a upper limit for ESIT,
+ * if a synchromous ep's ESIT is larger than @XHCI_MTK_MAX_ESIT,
+ * round down to the limit value, that means allocating more
+ * bandwidth to it.
+ */
+#define XHCI_MTK_MAX_ESIT	64
+
+/**
+ * struct mu3h_sch_bw_info
+ * @bus_bw: array to keep track of bandwidth already used at each uframes
+ * @bw_ep_list: eps in the bandwidth domain
+ *
+ * treat a HS root port as a bandwidth domain, but treat a SS root port as
+ * two bandwidth domains, one for IN eps and another for OUT eps.
+ */
+struct mu3h_sch_bw_info {
+	u32 bus_bw[XHCI_MTK_MAX_ESIT];
+	struct list_head bw_ep_list;
+};
+
+/**
+ * struct mu3h_sch_ep_info
+ * @esit: unit is 125us, equal to 2 << Interval field in ep-context
+ * @num_budget_microframes: number of continuous uframes
+ *		(@repeat==1) scheduled within the interval
+ * @ep: address of usb_host_endpoint
+ * @offset: which uframe of the interval that transfer should be
+ *		scheduled first time within the interval
+ * @repeat: the time gap between two uframes that transfers are
+ *		scheduled within a interval. in the simple algorithm, only
+ *		assign 0 or 1 to it; 0 means using only one uframe in a
+ *		interval, and1 means using @num_budget_microframes
+ *		continuous uframes
+ * @pkts: number of packets to be transferred in the scheduled uframes
+ * @cs_count: number of CS that host will trigger
+ */
+struct mu3h_sch_ep_info {
+	u32 ep_type;
+	u32 max_packet_size;
+	u32 esit;
+	u32 num_budget_microframes;
+	u32 bw_cost_per_microframe;
+	void *ep;
+	struct list_head endpoint;
+
+	/* mtk xhci scheduling info */
+	u32 offset;
+	u32 repeat;
+	u32 pkts;
+	u32 cs_count;
+	u32 burst_mode;
+};
+
+struct xhci_hcd_mtk {
+	struct device *dev;
+	struct usb_hcd *hcd;
+	struct mu3h_sch_bw_info *sch_array;
+	void __iomem *mac_base;
+	void __iomem *ippc_base;
+	struct regulator *vusb33;
+	struct regulator *vbus;
+	struct clk *sys_mac;	/* sys and mac clock */
+	struct clk *wk_deb_p0;	/* port0's wakeup debounce clock */
+	struct clk *wk_deb_p1;
+	struct regmap *pericfg;
+	int wakeup_src;
+	struct phy **phys;
+	int num_phys;
+};
+
+#if IS_ENABLED(CONFIG_USB_XHCI_MTK)
+int xhci_mtk_sch_init(struct xhci_hcd *xhci);
+void xhci_mtk_sch_exit(struct xhci_hcd *xhci);
+int xhci_mtk_add_ep_quirk(struct usb_hcd *hcd, struct usb_device *udev,
+		struct usb_host_endpoint *ep);
+void xhci_mtk_drop_ep_quirk(struct usb_hcd *hcd, struct usb_device *udev,
+		struct usb_host_endpoint *ep);
+u32 xhci_mtk_td_remainder_quirk(unsigned int td_running_total,
+	unsigned trb_buffer_length, struct urb *urb);
+
+#else
+static inline int xhci_mtk_sch_init(struct xhci_hcd *xhci)
+{
+	return 0;
+}
+
+static inline void xhci_mtk_sch_exit(struct xhci_hcd *xhci)
+{
+}
+
+static inline int xhci_mtk_add_ep_quirk(struct usb_hcd *hcd,
+	struct usb_device *udev, struct usb_host_endpoint *ep)
+{
+	return 0;
+}
+
+static inline void xhci_mtk_drop_ep_quirk(struct usb_hcd *hcd,
+	struct usb_device *udev, struct usb_host_endpoint *ep)
+{
+}
+
+static inline u32 xhci_mtk_td_remainder_quirk(unsigned int td_running_total,
+	unsigned trb_buffer_length, struct urb *urb)
+{
+	return 0;
+}
+
+#endif
+
+#endif		/* _XHCI_MTK_H_ */
diff --git a/drivers/usb/host/xhci-ring.c b/drivers/usb/host/xhci-ring.c
index 94416ff..73997a0 100644
--- a/drivers/usb/host/xhci-ring.c
+++ b/drivers/usb/host/xhci-ring.c
@@ -68,6 +68,7 @@
 #include <linux/slab.h>
 #include "xhci.h"
 #include "xhci-trace.h"
+#include "xhci-mtk.h"
 
 /*
  * Returns zero if the TRB isn't in this segment, otherwise it returns the DMA
@@ -3131,9 +3132,14 @@ static int queue_bulk_sg_tx(struct xhci_hcd *xhci, gfp_t mem_flags,
 
 		/* Set the TRB length, TD size, and interrupter fields. */
 		if (xhci->hci_version < 0x100) {
-			remainder = xhci_td_remainder(
+			if (xhci->quirks & XHCI_MTK_HOST) {
+				remainder = xhci_mtk_td_remainder_quirk(
+					running_total, trb_buff_len, urb);
+			} else {
+				remainder = xhci_td_remainder(
 					urb->transfer_buffer_length -
 					running_total);
+			}
 		} else {
 			remainder = xhci_v1_0_td_remainder(running_total,
 					trb_buff_len, total_packet_count, urb,
@@ -3286,9 +3292,14 @@ int xhci_queue_bulk_tx(struct xhci_hcd *xhci, gfp_t mem_flags,
 
 		/* Set the TRB length, TD size, and interrupter fields. */
 		if (xhci->hci_version < 0x100) {
-			remainder = xhci_td_remainder(
+			if (xhci->quirks & XHCI_MTK_HOST) {
+				remainder = xhci_mtk_td_remainder_quirk(
+					running_total, trb_buff_len, urb);
+			} else {
+				remainder = xhci_td_remainder(
 					urb->transfer_buffer_length -
 					running_total);
+			}
 		} else {
 			remainder = xhci_v1_0_td_remainder(running_total,
 					trb_buff_len, total_packet_count, urb,
@@ -3383,7 +3394,7 @@ int xhci_queue_ctrl_tx(struct xhci_hcd *xhci, gfp_t mem_flags,
 		field |= 0x1;
 
 	/* xHCI 1.0 6.4.1.2.1: Transfer Type field */
-	if (xhci->hci_version == 0x100) {
+	if ((xhci->hci_version == 0x100) || (xhci->quirks & XHCI_MTK_HOST)) {
 		if (urb->transfer_buffer_length > 0) {
 			if (setup->bRequestType & USB_DIR_IN)
 				field |= TRB_TX_TYPE(TRB_DATA_IN);
@@ -3407,8 +3418,14 @@ int xhci_queue_ctrl_tx(struct xhci_hcd *xhci, gfp_t mem_flags,
 		field = TRB_TYPE(TRB_DATA);
 
 	length_field = TRB_LEN(urb->transfer_buffer_length) |
-		xhci_td_remainder(urb->transfer_buffer_length) |
 		TRB_INTR_TARGET(0);
+
+	if (xhci->quirks & XHCI_MTK_HOST)
+		length_field |= xhci_mtk_td_remainder_quirk(0,
+				urb->transfer_buffer_length, urb);
+	else
+		length_field |= xhci_td_remainder(urb->transfer_buffer_length);
+
 	if (urb->transfer_buffer_length > 0) {
 		if (setup->bRequestType & USB_DIR_IN)
 			field |= TRB_DIR_IN;
@@ -3632,8 +3649,14 @@ static int xhci_queue_isoc_tx(struct xhci_hcd *xhci, gfp_t mem_flags,
 
 			/* Set the TRB length, TD size, & interrupter fields. */
 			if (xhci->hci_version < 0x100) {
-				remainder = xhci_td_remainder(
-						td_len - running_total);
+				if (xhci->quirks & XHCI_MTK_HOST) {
+					remainder = xhci_mtk_td_remainder_quirk(
+						running_total, trb_buff_len,
+						urb);
+				} else {
+					remainder = xhci_td_remainder(
+							td_len - running_total);
+				}
 			} else {
 				remainder = xhci_v1_0_td_remainder(
 						running_total, trb_buff_len,
diff --git a/drivers/usb/host/xhci.c b/drivers/usb/host/xhci.c
index 7da0d60..209fc8a 100644
--- a/drivers/usb/host/xhci.c
+++ b/drivers/usb/host/xhci.c
@@ -31,6 +31,7 @@
 
 #include "xhci.h"
 #include "xhci-trace.h"
+#include "xhci-mtk.h"
 
 #define DRIVER_AUTHOR "Sarah Sharp"
 #define DRIVER_DESC "'eXtensible' Host Controller (xHC) Driver"
@@ -623,7 +624,11 @@ int xhci_run(struct usb_hcd *hcd)
 			"// Set the interrupt modulation register");
 	temp = readl(&xhci->ir_set->irq_control);
 	temp &= ~ER_IRQ_INTERVAL_MASK;
-	temp |= (u32) 160;
+	/*
+	 * the increment interval is 8 times as much as that defined
+	 * in xHCI spec on MTK's controller
+	 */
+	temp |= (u32) ((xhci->quirks & XHCI_MTK_HOST) ? 20 : 160);
 	writel(temp, &xhci->ir_set->irq_control);
 
 	/* Set the HCD state before we enable the irqs */
@@ -1688,6 +1693,9 @@ int xhci_drop_endpoint(struct usb_hcd *hcd, struct usb_device *udev,
 
 	xhci_endpoint_zero(xhci, xhci->devs[udev->slot_id], ep);
 
+	if (xhci->quirks & XHCI_MTK_HOST)
+		xhci_mtk_drop_ep_quirk(hcd, udev, ep);
+
 	xhci_dbg(xhci, "drop ep 0x%x, slot id %d, new drop flags = %#x, new add flags = %#x\n",
 			(unsigned int) ep->desc.bEndpointAddress,
 			udev->slot_id,
@@ -1783,6 +1791,15 @@ int xhci_add_endpoint(struct usb_hcd *hcd, struct usb_device *udev,
 		return -ENOMEM;
 	}
 
+	if (xhci->quirks & XHCI_MTK_HOST) {
+		ret = xhci_mtk_add_ep_quirk(hcd, udev, ep);
+		if (ret < 0) {
+			xhci_free_or_cache_endpoint_ring(xhci,
+				virt_dev, ep_index);
+			return ret;
+		}
+	}
+
 	ctrl_ctx->add_flags |= cpu_to_le32(added_ctxs);
 	new_add_flags = le32_to_cpu(ctrl_ctx->add_flags);
 
diff --git a/drivers/usb/host/xhci.h b/drivers/usb/host/xhci.h
index 31e46cc..d257ce3 100644
--- a/drivers/usb/host/xhci.h
+++ b/drivers/usb/host/xhci.h
@@ -1567,6 +1567,7 @@ struct xhci_hcd {
 /* For controllers with a broken beyond repair streams implementation */
 #define XHCI_BROKEN_STREAMS	(1 << 19)
 #define XHCI_PME_STUCK_QUIRK	(1 << 20)
+#define XHCI_MTK_HOST		(1 << 21)
 	unsigned int		num_active_eps;
 	unsigned int		limit_active_eps;
 	/* There are two roothubs to keep track of bus suspend info for */
-- 
1.8.1.1.dirty



From eric.auger at linaro.org  Fri Aug  7 05:36:40 2015
From: eric.auger at linaro.org (Eric Auger)
Date: Fri, 07 Aug 2015 14:36:40 +0200
Subject: [PATCH 1/2] KVM: arm: rename pause into power_off
In-Reply-To: <20150718090913.GN14024@cbox>
References: <1436186996-22528-1-git-send-email-eric.auger@linaro.org>
 <1436186996-22528-2-git-send-email-eric.auger@linaro.org>
 <20150718090913.GN14024@cbox>
Message-ID: <55C4A658.3060302@linaro.org>

Hi Christoffer,
On 07/18/2015 11:09 AM, Christoffer Dall wrote:
> On Mon, Jul 06, 2015 at 02:49:55PM +0200, Eric Auger wrote:
>> The kvm_vcpu_arch pause field is renamed into power_off to prepare
>> for the introduction of a new pause field.
>>
>> Signed-off-by: Eric Auger <eric.auger at linaro.org>
>>
>> v4 -> v5:
>> - fix compilation issue on arm64 (add power_off field in kvm_host.h)
>> ---
>>  arch/arm/include/asm/kvm_host.h   |  4 ++--
>>  arch/arm/kvm/arm.c                | 10 +++++-----
>>  arch/arm/kvm/psci.c               | 10 +++++-----
>>  arch/arm64/include/asm/kvm_host.h |  4 ++--
>>  4 files changed, 14 insertions(+), 14 deletions(-)
>>
>> diff --git a/arch/arm/include/asm/kvm_host.h b/arch/arm/include/asm/kvm_host.h
>> index e896d2c..304004d 100644
>> --- a/arch/arm/include/asm/kvm_host.h
>> +++ b/arch/arm/include/asm/kvm_host.h
>> @@ -129,8 +129,8 @@ struct kvm_vcpu_arch {
>>  	 * here.
>>  	 */
>>  
>> -	/* Don't run the guest on this vcpu */
>> -	bool pause;
>> +	/* vcpu power-off state */
>> +	bool power_off;
>>  
>>  	/* IO related fields */
>>  	struct kvm_decode mmio_decode;
>> diff --git a/arch/arm/kvm/arm.c b/arch/arm/kvm/arm.c
>> index bcdf799..7537e68 100644
>> --- a/arch/arm/kvm/arm.c
>> +++ b/arch/arm/kvm/arm.c
>> @@ -475,7 +475,7 @@ static void vcpu_pause(struct kvm_vcpu *vcpu)
>>  {
>>  	wait_queue_head_t *wq = kvm_arch_vcpu_wq(vcpu);
>>  
>> -	wait_event_interruptible(*wq, !vcpu->arch.pause);
>> +	wait_event_interruptible(*wq, !vcpu->arch.power_off);
> 
> would there be any benefit to simply calling kvm_vcpu_block() instead of
> vcpu_pause, and rewrite kvm_arch_vcpu_runnable to:
Wouldn't it somehow change the known behavior or kvm_vcpu_block which is
expected/used to exit on IRQ/FIQ (WFI). Here it would exit when
power_off changes to false (or maybe you meant pause below in the new
context?).
> 
> int kvm_arch_vcpu_runnable(struct kvm_vcpu *v)
> {
> ?       return !vcpu->arch.power_off &&
> 		(!!v->arch.irq_lines || kvm_vgic_vcpu_pending_irq(v));
> }
> 
> Not sure really, certainly the runnable function does not become more
> readable.
To me the usage of kvm_vcpu_block looks more complex than this code and
I would prefer keeping that version if you don't mind.
> 
>>  }
>>  
>>  static int kvm_vcpu_initialized(struct kvm_vcpu *vcpu)
>> @@ -525,7 +525,7 @@ int kvm_arch_vcpu_ioctl_run(struct kvm_vcpu *vcpu, struct kvm_run *run)
>>  
>>  		update_vttbr(vcpu->kvm);
>>  
>> -		if (vcpu->arch.pause)
>> +		if (vcpu->arch.power_off)
>>  			vcpu_pause(vcpu);
> 
> looking back over this code, how does this actually guarantee that we
> don't run a powered-off cpu?
> 
> vcpu_pause() just does a wait_event_interruptible(), so if we get
> scheduled again, we'll just proceed running. 
actually it also checks the !vcpu->arch.power_off condition, right?
 Is there any case where we
> could get scheduled without signal_pending() being true and therefore
> inadvertedly run the vcpu?
kvm_arm_halt_guest can happen at any time, including after the execution
of above vcpu_pause(vcpu) call. This is the reason why I added the
second check below, once we entered the critical section and just before
running the vcpu.

With regard to renamed power_off boolean my understanding is:

power_off is set
- on kvm_arch_vcpu_ioctl_vcpu_init/KVM_ARM_VCPU_POWER_OFF
- on PSCI calls from guests through traps from HVC instructions
in that case I don't think this can happen

- on KVM_SET_MP_STATE ioctl: I think in that case, what you describe can
happen.

Do you share the same understanding?

Best Regards

Eric

> 
> if so, we should change the line below like this:
> 
> diff --git a/arch/arm/kvm/arm.c b/arch/arm/kvm/arm.c
> index bc738d2..98f31e6 100644
> --- a/arch/arm/kvm/arm.c
> +++ b/arch/arm/kvm/arm.c
> @@ -542,7 +542,8 @@ int kvm_arch_vcpu_ioctl_run(struct kvm_vcpu *vcpu, struct kvm_run *run)
>  			run->exit_reason = KVM_EXIT_INTR;
>  		}
>  
> -		if (ret <= 0 || need_new_vmid_gen(vcpu->kvm)) {
> +		if (ret <= 0 || need_new_vmid_gen(vcpu->kvm) ||
> +		    vcpu->arch.power_off) {
>  			local_irq_enable();
>  			preempt_enable();
>  			kvm_timer_sync_hwstate(vcpu);
> 
> 
> Sorry for polluting your patch with these questions, I'm otherwise fine
> with the rename.
> 
> Thanks,
> -Christoffer
> 
>>  
>>  		/*
>> @@ -766,12 +766,12 @@ static int kvm_arch_vcpu_ioctl_vcpu_init(struct kvm_vcpu *vcpu,
>>  	vcpu_reset_hcr(vcpu);
>>  
>>  	/*
>> -	 * Handle the "start in power-off" case by marking the VCPU as paused.
>> +	 * Handle the "start in power-off" case.
>>  	 */
>>  	if (test_bit(KVM_ARM_VCPU_POWER_OFF, vcpu->arch.features))
>> -		vcpu->arch.pause = true;
>> +		vcpu->arch.power_off = true;
>>  	else
>> -		vcpu->arch.pause = false;
>> +		vcpu->arch.power_off = false;
>>  
>>  	return 0;
>>  }
>> diff --git a/arch/arm/kvm/psci.c b/arch/arm/kvm/psci.c
>> index 4b94b51..134971a 100644
>> --- a/arch/arm/kvm/psci.c
>> +++ b/arch/arm/kvm/psci.c
>> @@ -63,7 +63,7 @@ static unsigned long kvm_psci_vcpu_suspend(struct kvm_vcpu *vcpu)
>>  
>>  static void kvm_psci_vcpu_off(struct kvm_vcpu *vcpu)
>>  {
>> -	vcpu->arch.pause = true;
>> +	vcpu->arch.power_off = true;
>>  }
>>  
>>  static unsigned long kvm_psci_vcpu_on(struct kvm_vcpu *source_vcpu)
>> @@ -87,7 +87,7 @@ static unsigned long kvm_psci_vcpu_on(struct kvm_vcpu *source_vcpu)
>>  	 */
>>  	if (!vcpu)
>>  		return PSCI_RET_INVALID_PARAMS;
>> -	if (!vcpu->arch.pause) {
>> +	if (!vcpu->arch.power_off) {
>>  		if (kvm_psci_version(source_vcpu) != KVM_ARM_PSCI_0_1)
>>  			return PSCI_RET_ALREADY_ON;
>>  		else
>> @@ -115,7 +115,7 @@ static unsigned long kvm_psci_vcpu_on(struct kvm_vcpu *source_vcpu)
>>  	 * the general puspose registers are undefined upon CPU_ON.
>>  	 */
>>  	*vcpu_reg(vcpu, 0) = context_id;
>> -	vcpu->arch.pause = false;
>> +	vcpu->arch.power_off = false;
>>  	smp_mb();		/* Make sure the above is visible */
>>  
>>  	wq = kvm_arch_vcpu_wq(vcpu);
>> @@ -152,7 +152,7 @@ static unsigned long kvm_psci_vcpu_affinity_info(struct kvm_vcpu *vcpu)
>>  	kvm_for_each_vcpu(i, tmp, kvm) {
>>  		mpidr = kvm_vcpu_get_mpidr_aff(tmp);
>>  		if (((mpidr & target_affinity_mask) == target_affinity) &&
>> -		    !tmp->arch.pause) {
>> +		    !tmp->arch.power_off) {
>>  			return PSCI_0_2_AFFINITY_LEVEL_ON;
>>  		}
>>  	}
>> @@ -175,7 +175,7 @@ static void kvm_prepare_system_event(struct kvm_vcpu *vcpu, u32 type)
>>  	 * re-initialized.
>>  	 */
>>  	kvm_for_each_vcpu(i, tmp, vcpu->kvm) {
>> -		tmp->arch.pause = true;
>> +		tmp->arch.power_off = true;
>>  		kvm_vcpu_kick(tmp);
>>  	}
>>  
>> diff --git a/arch/arm64/include/asm/kvm_host.h b/arch/arm64/include/asm/kvm_host.h
>> index 2709db2..009da6b 100644
>> --- a/arch/arm64/include/asm/kvm_host.h
>> +++ b/arch/arm64/include/asm/kvm_host.h
>> @@ -122,8 +122,8 @@ struct kvm_vcpu_arch {
>>  	 * here.
>>  	 */
>>  
>> -	/* Don't run the guest */
>> -	bool pause;
>> +	/* vcpu power-off state */
>> +	bool power_off;
>>  
>>  	/* IO related fields */
>>  	struct kvm_decode mmio_decode;
>> -- 
>> 1.9.1
>>



From tomasz.nowicki at linaro.org  Fri Aug  7 05:42:20 2015
From: tomasz.nowicki at linaro.org (Tomasz Nowicki)
Date: Fri, 07 Aug 2015 14:42:20 +0200
Subject: [PATCH 2/2] net, thunder, bgx: Add support for ACPI binding.
In-Reply-To: <20150807115622.GS4914@rric.localhost>
References: <1438907590-29649-1-git-send-email-ddaney.cavm@gmail.com>
 <1438907590-29649-3-git-send-email-ddaney.cavm@gmail.com>
 <55C467A0.4020601@linaro.org> <20150807104320.GQ1820@rric.localhost>
 <55C48DF9.70406@linaro.org> <20150807115622.GS4914@rric.localhost>
Message-ID: <55C4A7AC.1080902@linaro.org>

On 07.08.2015 13:56, Robert Richter wrote:
> On 07.08.15 12:52:41, Tomasz Nowicki wrote:
>> On 07.08.2015 12:43, Robert Richter wrote:
>>> On 07.08.15 10:09:04, Tomasz Nowicki wrote:
>>>> On 07.08.2015 02:33, David Daney wrote:
>>>
>>> ...
>>>
>>>>> +#else
>>>>> +
>>>>> +static int bgx_init_acpi_phy(struct bgx *bgx)
>>>>> +{
>>>>> +	return -ENODEV;
>>>>> +}
>>>>> +
>>>>> +#endif /* CONFIG_ACPI */
>>>>> +
>>>>>   #if IS_ENABLED(CONFIG_OF_MDIO)
>>>>>
>>>>>   static int bgx_init_of_phy(struct bgx *bgx)
>>>>> @@ -882,7 +1010,12 @@ static int bgx_init_of_phy(struct bgx *bgx)
>>>>>
>>>>>   static int bgx_init_phy(struct bgx *bgx)
>>>>>   {
>>>>> -	return bgx_init_of_phy(bgx);
>>>>> +	int err = bgx_init_of_phy(bgx);
>>>>> +
>>>>> +	if (err != -ENODEV)
>>>>> +		return err;
>>>>> +
>>>>> +	return bgx_init_acpi_phy(bgx);
>>>>>   }
>>>>>
>>>>
>>>> If kernel can work with DT and ACPI (both compiled in), it should take only
>>>> one path instead of probing DT and ACPI sequentially. How about:
>>>>
>>>> @@ -902,10 +925,9 @@ static int bgx_probe(struct pci_dev *pdev, const struct
>>>> pci_device_id *ent)
>>>>   	bgx_vnic[bgx->bgx_id] = bgx;
>>>>   	bgx_get_qlm_mode(bgx);
>>>>
>>>> -	snprintf(bgx_sel, 5, "bgx%d", bgx->bgx_id);
>>>> -	np = of_find_node_by_name(NULL, bgx_sel);
>>>> -	if (np)
>>>> -		bgx_init_of(bgx, np);
>>>> +	err = acpi_disabled ? bgx_init_of_phy(bgx) : bgx_init_acpi_phy(bgx);
>>>> +	if (err)
>>>> +		goto err_enable;
>>>>
>>>>   	bgx_init_hw(bgx);
>>>
>>> I would not pollute bgx_probe() with acpi and dt specifics, and instead
>>> keep bgx_init_phy(). The typical design pattern for this is:
>>>
>>> static int bgx_init_phy(struct bgx *bgx)
>>> {
>>> #ifdef CONFIG_ACPI
>>>          if (!acpi_disabled)
>>>                  return bgx_init_acpi_phy(bgx);
>>> #endif
>>>          return bgx_init_of_phy(bgx);
>>> }
>>>
>>> This adds acpi runtime detection (acpi=no), does not call dt code in
>>> case of acpi, and saves the #else for bgx_init_acpi_phy().
>>>
>>
>> I am fine with keeping it in bgx_init_phy(), however we can drop there
>> #ifdefs since both of bgx_init_{acpi,of}_phy calls have empty stub for !ACPI
>> and !OF case. Like that:
>>
>> static int bgx_init_phy(struct bgx *bgx)
>> {
>>
>>          if (!acpi_disabled)
>>                  return bgx_init_acpi_phy(bgx);
>> 	else
>>          	return bgx_init_of_phy(bgx);
>> }
>
> As said, keeping it in #ifdefs makes the empty stub function for !acpi
> obsolete, which makes the code smaller and better readable. This style
> is common practice in the kernel. Apart from that, the 'else' should
> be dropped as it is useless.
>

I would't say the code is better readable (bgx_init_of_phy has still two 
stubs) but this is just cosmetic, my point was to use run time detection 
using acpi_disabled.

Tomasz


From viresh.kumar at linaro.org  Fri Aug  7 05:43:10 2015
From: viresh.kumar at linaro.org (Viresh Kumar)
Date: Fri, 7 Aug 2015 18:13:10 +0530
Subject: [PATCH v2] cpufreq-dt: make scaling_boost_freqs sysfs attr
 available when boost is enabled
In-Reply-To: <3835403.gWyHpfh1Gz@amdc1976>
References: <3835403.gWyHpfh1Gz@amdc1976>
Message-ID: <20150807124310.GI6939@linux>

On 07-08-15, 13:56, Bartlomiej Zolnierkiewicz wrote:
> Make scaling_boost_freqs sysfs attribute is available when
> cpufreq-dt driver is used and boost support is enabled.
> 
> Cc: Thomas Abraham <thomas.ab at samsung.com>
> Cc: Javier Martinez Canillas <javier at osg.samsung.com>
> Cc: Krzysztof Kozlowski <k.kozlowski at samsung.com>
> Suggested-by: Viresh Kumar <viresh.kumar at linaro.org>
> Signed-off-by: Bartlomiej Zolnierkiewicz <b.zolnierkie at samsung.com>
> ---
> v2: Removed leftover prototype.
> 
>  drivers/cpufreq/cpufreq-dt.c | 9 ++++++++-
>  include/linux/cpufreq.h      | 1 +
>  2 files changed, 9 insertions(+), 1 deletion(-)

Acked-by: Viresh Kumar <viresh.kumar at linaro.org>

-- 
viresh


From eric.auger at linaro.org  Fri Aug  7 05:56:31 2015
From: eric.auger at linaro.org (Eric Auger)
Date: Fri, 07 Aug 2015 14:56:31 +0200
Subject: [PATCH 2/2] kvm: arm/arm64: implement kvm_arm_[halt, resume]_guest
In-Reply-To: <20150718091851.GO14024@cbox>
References: <1436186996-22528-1-git-send-email-eric.auger@linaro.org>
 <1436186996-22528-3-git-send-email-eric.auger@linaro.org>
 <20150718091851.GO14024@cbox>
Message-ID: <55C4AAFF.8080408@linaro.org>

On 07/18/2015 11:18 AM, Christoffer Dall wrote:
> On Mon, Jul 06, 2015 at 02:49:56PM +0200, Eric Auger wrote:
>> On halt, the guest is forced to exit and prevented from being
>> re-entered. This is synchronous.
>>
>> Those two operations will be needed for IRQ forwarding setting.
>>
>> Signed-off-by: Eric Auger <eric.auger at linaro.org>
>>
>> ---
>> RFC v1 -> v2:
>> - add __maybe_unused
>>
>> RFC:
>> - rename the function and this latter becomes static
>> - remove __KVM_HAVE_ARCH_HALT_GUEST
>>
>> v4 -> v5: add arm64 support
>> - also defines __KVM_HAVE_ARCH_HALT_GUEST for arm64
>> - add pause field
>> ---
>>  arch/arm/include/asm/kvm_host.h   |  3 +++
>>  arch/arm/kvm/arm.c                | 35 ++++++++++++++++++++++++++++++++---
>>  arch/arm64/include/asm/kvm_host.h |  3 +++
>>  3 files changed, 38 insertions(+), 3 deletions(-)
>>
>> diff --git a/arch/arm/include/asm/kvm_host.h b/arch/arm/include/asm/kvm_host.h
>> index 304004d..899ae27 100644
>> --- a/arch/arm/include/asm/kvm_host.h
>> +++ b/arch/arm/include/asm/kvm_host.h
>> @@ -132,6 +132,9 @@ struct kvm_vcpu_arch {
>>  	/* vcpu power-off state */
>>  	bool power_off;
>>  
>> +	/* Don't run the guest */
>> +	bool pause;
>> +
>>  	/* IO related fields */
>>  	struct kvm_decode mmio_decode;
>>  
>> diff --git a/arch/arm/kvm/arm.c b/arch/arm/kvm/arm.c
>> index 7537e68..46d4ef6 100644
>> --- a/arch/arm/kvm/arm.c
>> +++ b/arch/arm/kvm/arm.c
>> @@ -471,11 +471,39 @@ bool kvm_arch_intc_initialized(struct kvm *kvm)
>>  	return vgic_initialized(kvm);
>>  }
>>  
>> +static void kvm_arm_halt_guest(struct kvm *kvm) __maybe_unused;
>> +static void kvm_arm_resume_guest(struct kvm *kvm) __maybe_unused;
>> +
>> +static void kvm_arm_halt_guest(struct kvm *kvm)
>> +{
>> +	int i;
>> +	struct kvm_vcpu *vcpu;
>> +
>> +	kvm_for_each_vcpu(i, vcpu, kvm)
>> +		vcpu->arch.pause = true;
>> +	force_vm_exit(cpu_all_mask);
>> +}
>> +
>> +static void kvm_arm_resume_guest(struct kvm *kvm)
>> +{
>> +	int i;
>> +	struct kvm_vcpu *vcpu;
>> +
>> +	kvm_for_each_vcpu(i, vcpu, kvm) {
>> +		wait_queue_head_t *wq = kvm_arch_vcpu_wq(vcpu);
>> +
>> +		vcpu->arch.pause = false;
>> +		wake_up_interruptible(wq);
>> +	}
>> +}
>> +
>> +
>>  static void vcpu_pause(struct kvm_vcpu *vcpu)
>>  {
>>  	wait_queue_head_t *wq = kvm_arch_vcpu_wq(vcpu);
>>  
>> -	wait_event_interruptible(*wq, !vcpu->arch.power_off);
>> +	wait_event_interruptible(*wq, ((!vcpu->arch.power_off) &&
>> +				       (!vcpu->arch.pause)));
>>  }
>>  
>>  static int kvm_vcpu_initialized(struct kvm_vcpu *vcpu)
>> @@ -525,7 +553,7 @@ int kvm_arch_vcpu_ioctl_run(struct kvm_vcpu *vcpu, struct kvm_run *run)
>>  
>>  		update_vttbr(vcpu->kvm);
>>  
>> -		if (vcpu->arch.power_off)
>> +		if (vcpu->arch.power_off || vcpu->arch.pause)
>>  			vcpu_pause(vcpu);
> 
> These two changes really make me feel like kvm_arch_vcpu_runnable()
> should be changed to check for both flags and all thes eplaces should
> check for runnable instead.
> 
> To make the runnable function more robust, perhaps it should check:
> 
> 1. The vcpu is neither paused nor powered off
> 2. The vcpu is not in a WFI state (vcpu->arch.wfi_request) OR there are
>    pending interrupts (the current check).
> 
> Then the logic would fit the name of the function, instead of being a
> specific check only called through handle_wfx.

Reading this again, I reconsider what I said in previous comment answer
and this definitively makes sense to update the runnable function. I
was/am afraid by this vcpu_block function and I need to better undertand
it - I think what I said previously is not correct - .

I will investigate that direction.

Eric
> 
>>  
>>  		/*
>> @@ -551,7 +579,8 @@ int kvm_arch_vcpu_ioctl_run(struct kvm_vcpu *vcpu, struct kvm_run *run)
>>  			run->exit_reason = KVM_EXIT_INTR;
>>  		}
>>  
>> -		if (ret <= 0 || need_new_vmid_gen(vcpu->kvm)) {
>> +		if (ret <= 0 || need_new_vmid_gen(vcpu->kvm) ||
>> +		    vcpu->arch.pause) {
> 
> so why do we need to re-check the pause flag, but not the power_off
> flag?  That is non-trivial for sure, so if it's correct, deserves a
> comment.  Also see my comment on the last patch.
> 
>>  			local_irq_enable();
>>  			preempt_enable();
>>  			kvm_vgic_sync_hwstate(vcpu);
>> diff --git a/arch/arm64/include/asm/kvm_host.h b/arch/arm64/include/asm/kvm_host.h
>> index 009da6b..69e3785 100644
>> --- a/arch/arm64/include/asm/kvm_host.h
>> +++ b/arch/arm64/include/asm/kvm_host.h
>> @@ -125,6 +125,9 @@ struct kvm_vcpu_arch {
>>  	/* vcpu power-off state */
>>  	bool power_off;
>>  
>> +	/* Don't run the guest */
> 
> Probably need to be more clear about this being an implementation
> requirement rather than being guest visible or related to any
> architectural concept.
> 
>> +	bool pause;
>> +
>>  	/* IO related fields */
>>  	struct kvm_decode mmio_decode;
>>  
>> -- 
>> 1.9.1
>>
> 
> Thanks,
> -Christoffer
> 



From broonie at kernel.org  Fri Aug  7 06:03:11 2015
From: broonie at kernel.org (Mark Brown)
Date: Fri, 7 Aug 2015 14:03:11 +0100
Subject: [PATCH v3 2/4] ASoC: rockchip: Add rockchip SPDIF transceiver
 driver
In-Reply-To: <1438947854-3743-3-git-send-email-sjoerd.simons@collabora.co.uk>
References: <1438947854-3743-1-git-send-email-sjoerd.simons@collabora.co.uk>
 <1438947854-3743-3-git-send-email-sjoerd.simons@collabora.co.uk>
Message-ID: <20150807130311.GW20873@sirena.org.uk>

On Fri, Aug 07, 2015 at 01:44:12PM +0200, Sjoerd Simons wrote:

> Changes in v2:
> - Remove platform: module alias as it was unused

Ugh, I see Paul Bolle replied to one of your earlier patches :/  Please
just ignore him, he doesn't understand that we don't require machine
definitions to be in tree.  A platform: module alias is useful for any
platform device.

> +static inline struct rk_spdif_dev *to_info(struct snd_soc_dai *dai)
> +{
> +	return snd_soc_dai_get_drvdata(dai);
> +}

I'm not sure this is adding much to the two users but whatever.

> +static int rk_spdif_snd_txctrl(struct rk_spdif_dev *spdif, int on)
> +{
> +	int ret;
> +
> +	if (on) {
> +		ret = regmap_update_bits(spdif->regmap, SPDIF_DMACR,
> +				   SPDIF_DMACR_TDE_ENABLE,
> +				   SPDIF_DMACR_TDE_ENABLE);
> +
> +		if (ret != 0)
> +			goto bail;
> +
> +		ret = regmap_update_bits(spdif->regmap, SPDIF_XFER,
> +				   SPDIF_XFER_TXS_START,
> +				   SPDIF_XFER_TXS_START);

This function has no common code, just two branches in an if/else that
share nothing and is called from a single location.  Why not just inline
this into the trigger function?

> +	/* Set clock and calculate divider */
> +	clk_set_rate(spdif->mclk, mclk);

We should check the return value of clk_set_rate().

> +	spdif->hclk = devm_clk_get(&pdev->dev, "spdif_hclk");
> +	if (IS_ERR(spdif->hclk)) {
> +		dev_err(&pdev->dev, "Can't retrieve rk_spdif bus clock\n");
> +		return PTR_ERR(spdif->hclk);
> +	}
> +	ret = clk_prepare_enable(spdif->hclk);
> +	if (ret) {
> +		dev_err(spdif->dev, "hclock enable failed %d\n", ret);
> +		return ret;
> +	}

I notice that we don't manage the hclk over suspend/resume - should we
perhaps be using regmap_init_mmio_clk() together with runtime PM to
manage it?

> +	pm_runtime_enable(&pdev->dev);
> +	if (!pm_runtime_enabled(&pdev->dev)) {
> +		ret = rk_spdif_runtime_resume(&pdev->dev);
> +		if (ret)
> +			goto err_pm_disable;
> +	}

The normal pattern with this is to start the device powered up then idle
it - this does mean we need to bounce the power on but fitting in with
the common pattern is good and it's less conditional code.
-------------- next part --------------
A non-text attachment was scrubbed...
Name: signature.asc
Type: application/pgp-signature
Size: 473 bytes
Desc: Digital signature
URL: <http://lists.infradead.org/pipermail/linux-arm-kernel/attachments/20150807/644ccefb/attachment.sig>

From broonie at kernel.org  Fri Aug  7 06:05:40 2015
From: broonie at kernel.org (Mark Brown)
Date: Fri, 7 Aug 2015 14:05:40 +0100
Subject: [PATCH v3 1/4] ASoC: dt-bindings: add rockchip tranceiver bindings
In-Reply-To: <1438947854-3743-2-git-send-email-sjoerd.simons@collabora.co.uk>
References: <1438947854-3743-1-git-send-email-sjoerd.simons@collabora.co.uk>
 <1438947854-3743-2-git-send-email-sjoerd.simons@collabora.co.uk>
Message-ID: <20150807130540.GX20873@sirena.org.uk>

On Fri, Aug 07, 2015 at 01:44:11PM +0200, Sjoerd Simons wrote:

> +- compatible: should be one of the following:
> +   - "rockchip,rk3066-spdif": for rk3066
> +   - "rockchip,rk3188-spdif", "rockchip,rk3066-spdif": for rk3188
> +   - "rockchip,rk3288-spdif", "rockchip,rk3066-spdif": for rk3288

The binding claims that we support these three compatibles but the
driver only supports rockchip,rk3066-spdif.  It's better to list all the
compatibles in the binding even if they all boil down to the same thing
since it's less error prone when we do start adding device specific
code - people are less likely to forget to handle some variant properly.
-------------- next part --------------
A non-text attachment was scrubbed...
Name: signature.asc
Type: application/pgp-signature
Size: 473 bytes
Desc: Digital signature
URL: <http://lists.infradead.org/pipermail/linux-arm-kernel/attachments/20150807/7ea0e7eb/attachment.sig>

From broonie at kernel.org  Fri Aug  7 06:13:59 2015
From: broonie at kernel.org (Mark Brown)
Date: Fri, 7 Aug 2015 14:13:59 +0100
Subject: [PATCH 2/4] ASoc: rockchip: Add rockchip SPDIF transceiver driver
In-Reply-To: <1438159908.5106.32.camel@tiscali.nl>
References: <1438085011-16577-1-git-send-email-sjoerd.simons@collabora.co.uk>
 <1438085011-16577-3-git-send-email-sjoerd.simons@collabora.co.uk>
 <1438159908.5106.32.camel@tiscali.nl>
Message-ID: <20150807131359.GA8892@sirena.org.uk>

On Wed, Jul 29, 2015 at 10:51:48AM +0200, Paul Bolle wrote:

> > +		.name = DRV_NAME,
> > +		.of_match_table = of_match_ptr(rockchip_spdif_match),
> > +		.pm = &rockchip_spdif_pm_ops,
> > +	},
> > +};
> > +module_platform_driver(rockchip_spdif_driver);

> > +MODULE_ALIAS("platform:" DRV_NAME);

> (I seem to remember that Mark Brown is OK with this, at least for the
> time being, but for future reference I'll ask the question anyway.) Is
> there a corresponding struct platform_device with a "rockchip-spdif"
> .name? Because if there's no such platform_device I think this line
> doesn't really do anything for this driver.

Paul, you've been told this before but please stop providing these
review comments.  It has been explained to you repeatedly that we do not
require any form of machine definition to be merged to merge a driver,
please pay attention to those explanations and stop sending the same
bogus feedback to patch submitters.  This just creates confusion for the
submitters and wastes everyone's time.  

If you have questions the way to raise them is to respond to the
original discussions, not to send new replies to other submitters
repeating the same feedback you were previously advised was incorrect.
-------------- next part --------------
A non-text attachment was scrubbed...
Name: signature.asc
Type: application/pgp-signature
Size: 473 bytes
Desc: Digital signature
URL: <http://lists.infradead.org/pipermail/linux-arm-kernel/attachments/20150807/a24111b4/attachment.sig>

From broonie at kernel.org  Fri Aug  7 06:14:46 2015
From: broonie at kernel.org (Mark Brown)
Date: Fri, 7 Aug 2015 14:14:46 +0100
Subject: [PATCH v2] spi: spi-sun4i, spi-sun6i: Fix bit rate calculation
In-Reply-To: <op.x2yr7kbcltbbtz@localhost>
References: <op.x2pmc5kiltbbtz@localhost>
 <20150804171931.GZ20873@sirena.org.uk>
 <op.x2yr7kbcltbbtz@localhost>
Message-ID: <20150807131446.GA10301@sirena.org.uk>

On Thu, Aug 06, 2015 at 10:51:10PM +0200, Hermann Kraus wrote:
> Use requested bit rate instead of maximum possible and correctly calculate
> the divider.

Please don't put things like "Re: " at the start of subject lines for
patch submissions, it makes it look like a reply to an existing thread
rather than a patch submission.
-------------- next part --------------
A non-text attachment was scrubbed...
Name: signature.asc
Type: application/pgp-signature
Size: 473 bytes
Desc: Digital signature
URL: <http://lists.infradead.org/pipermail/linux-arm-kernel/attachments/20150807/bc88d35c/attachment.sig>

From broonie at kernel.org  Fri Aug  7 06:16:27 2015
From: broonie at kernel.org (Mark Brown)
Date: Fri, 7 Aug 2015 14:16:27 +0100
Subject: [PATCH v2] spi: spi-sun4i, spi-sun6i: Fix bit rate calculation
In-Reply-To: <op.x2yr7kbcltbbtz@localhost>
References: <op.x2pmc5kiltbbtz@localhost>
 <20150804171931.GZ20873@sirena.org.uk>
 <op.x2yr7kbcltbbtz@localhost>
Message-ID: <20150807131627.GB10301@sirena.org.uk>

On Thu, Aug 06, 2015 at 10:51:10PM +0200, Hermann Kraus wrote:
> Use requested bit rate instead of maximum possible and correctly calculate
> the divider.

This doesn't apply against current code, please check and resend.
-------------- next part --------------
A non-text attachment was scrubbed...
Name: signature.asc
Type: application/pgp-signature
Size: 473 bytes
Desc: Digital signature
URL: <http://lists.infradead.org/pipermail/linux-arm-kernel/attachments/20150807/d45010eb/attachment.sig>

From ykk at rock-chips.com  Fri Aug  7 06:18:10 2015
From: ykk at rock-chips.com (Yakir Yang)
Date: Fri, 7 Aug 2015 21:18:10 +0800
Subject: [RFC PATCH 2/8] drm: exynos/dp: convert to drm bridge mode
In-Reply-To: <20150807112535.GK17734@phenom.ffwll.local>
References: <1438868947-22132-1-git-send-email-ykk@rock-chips.com>
 <1438870041-23130-1-git-send-email-ykk@rock-chips.com>
 <000001d0d052$f44fa3a0$dceeeae0$@com> <55C36F49.6020207@rock-chips.com>
 <20150807112535.GK17734@phenom.ffwll.local>
Message-ID: <55C4B012.3010600@rock-chips.com>

Daniel,

? 2015/8/7 19:25, Daniel Vetter ??:
> On Thu, Aug 06, 2015 at 10:29:29PM +0800, Yakir Yang wrote:
>> Hi Jingoo,
>>
>> ? 2015/8/6 22:19, Jingoo Han ??:
>>> On Thursday, August 06, 2015 11:07 PM, Yakir Yang wrote:
>>>> In order to move exynos dp code to bridge directory,
>>>> we need to convert driver drm bridge mode first. As
>>>> dp driver already have a ptn3460 bridge, so we need
>>>> to move ptn bridge to the next bridge of dp bridge.
>>>>
>>>> Signed-off-by: Yakir Yang <ykk at rock-chips.com>
>>>> ---
>>>>   drivers/gpu/drm/exynos/exynos_dp_core.c | 196 ++++++++++++++++++++------------
>>>>   drivers/gpu/drm/exynos/exynos_dp_core.h |   2 +
>>>>   2 files changed, 126 insertions(+), 72 deletions(-)
>>>>
>>>> diff --git a/drivers/gpu/drm/exynos/exynos_dp_core.c b/drivers/gpu/drm/exynos/exynos_dp_core.c
>>>> index a8097a4..aa99e23 100644
>>>> --- a/drivers/gpu/drm/exynos/exynos_dp_core.c
>>>> +++ b/drivers/gpu/drm/exynos/exynos_dp_core.c
>>>> @@ -3,6 +3,7 @@
>>>>    *
>>>>    * Copyright (C) 2012 Samsung Electronics Co., Ltd.
>>>>    * Author: Jingoo Han <jg1.han at samsung.com>
>>>> + *         Yakir Yang <ykk at rock-chips.com>
>>> Please don't add this.
>>> You just fixed some parts of this code. I don't find the reason
>>> why you have to be added to author for this file.
>>> If you want the title for an author, please send the patch
>>> for a new IP, instead of modifying the exiting codes.
>> Okay, thanks for your remind ;)
> tbh the author lines are completely irrelevant, git blame/log is the
> authoritative source for that. Copyright is a bit a different matter
> entirely, but in general we seem to be not too good at updating.
Thanks for your good explain  ;)

- Yakir
> Really if that's all you have to comment and no substantial technical
> concerns or questions then just can such a bikeshed mail.
> -Daniel




From thierry.reding at gmail.com  Fri Aug  7 06:34:44 2015
From: thierry.reding at gmail.com (Thierry Reding)
Date: Fri,  7 Aug 2015 15:34:44 +0200
Subject: [PATCH 0/2] ARM: Wire up userfaultfd and mlock2 syscalls
Message-ID: <1438954486-28286-1-git-send-email-thierry.reding@gmail.com>

From: Thierry Reding <treding at nvidia.com>

These are two fairly trivial patches to wire up the userfaultfd and
mlock2 syscalls on 32-bit ARM. I've verified that these work by running
the userfaultfd and mlock2-tests tests from tools/testing/selftests/vm/
and they give good results. Note that mlock2-tests doesn't work without
additional fixups in linux-next needed to remove VM flags clashes.

I suppose this would have to wait until both of the above syscalls have
actually been merged, but I figured I'd post them anyway since I already
did the work and verified that they work.

Thierry

Thierry Reding (2):
  ARM: Wire up userfaultfd syscall
  ARM: Wire up mlock2 syscall

 arch/arm/include/asm/unistd.h      | 2 +-
 arch/arm/include/uapi/asm/unistd.h | 2 ++
 arch/arm/kernel/calls.S            | 2 ++
 3 files changed, 5 insertions(+), 1 deletion(-)

-- 
2.4.5



From thierry.reding at gmail.com  Fri Aug  7 06:34:45 2015
From: thierry.reding at gmail.com (Thierry Reding)
Date: Fri,  7 Aug 2015 15:34:45 +0200
Subject: [PATCH 1/2] ARM: Wire up userfaultfd syscall
In-Reply-To: <1438954486-28286-1-git-send-email-thierry.reding@gmail.com>
References: <1438954486-28286-1-git-send-email-thierry.reding@gmail.com>
Message-ID: <1438954486-28286-2-git-send-email-thierry.reding@gmail.com>

From: Thierry Reding <treding at nvidia.com>

Signed-off-by: Thierry Reding <treding at nvidia.com>
---
 arch/arm/include/asm/unistd.h      | 2 +-
 arch/arm/include/uapi/asm/unistd.h | 1 +
 arch/arm/kernel/calls.S            | 1 +
 3 files changed, 3 insertions(+), 1 deletion(-)

diff --git a/arch/arm/include/asm/unistd.h b/arch/arm/include/asm/unistd.h
index 32640c431a08..7cba573c2cc9 100644
--- a/arch/arm/include/asm/unistd.h
+++ b/arch/arm/include/asm/unistd.h
@@ -19,7 +19,7 @@
  * This may need to be greater than __NR_last_syscall+1 in order to
  * account for the padding in the syscall table
  */
-#define __NR_syscalls  (388)
+#define __NR_syscalls  (392)
 
 /*
  * *NOTE*: This is a ghost syscall private to the kernel.  Only the
diff --git a/arch/arm/include/uapi/asm/unistd.h b/arch/arm/include/uapi/asm/unistd.h
index 0c3f5a0dafd3..ca96eca3453c 100644
--- a/arch/arm/include/uapi/asm/unistd.h
+++ b/arch/arm/include/uapi/asm/unistd.h
@@ -414,6 +414,7 @@
 #define __NR_memfd_create		(__NR_SYSCALL_BASE+385)
 #define __NR_bpf			(__NR_SYSCALL_BASE+386)
 #define __NR_execveat			(__NR_SYSCALL_BASE+387)
+#define __NR_userfaultfd		(__NR_SYSCALL_BASE+388)
 
 /*
  * The following SWIs are ARM private.
diff --git a/arch/arm/kernel/calls.S b/arch/arm/kernel/calls.S
index 05745eb838c5..84c405670ff0 100644
--- a/arch/arm/kernel/calls.S
+++ b/arch/arm/kernel/calls.S
@@ -397,6 +397,7 @@
 /* 385 */	CALL(sys_memfd_create)
 		CALL(sys_bpf)
 		CALL(sys_execveat)
+		CALL(sys_userfaultfd)
 #ifndef syscalls_counted
 .equ syscalls_padding, ((NR_syscalls + 3) & ~3) - NR_syscalls
 #define syscalls_counted
-- 
2.4.5



From thierry.reding at gmail.com  Fri Aug  7 06:34:46 2015
From: thierry.reding at gmail.com (Thierry Reding)
Date: Fri,  7 Aug 2015 15:34:46 +0200
Subject: [PATCH 2/2] ARM: Wire up mlock2 syscall
In-Reply-To: <1438954486-28286-1-git-send-email-thierry.reding@gmail.com>
References: <1438954486-28286-1-git-send-email-thierry.reding@gmail.com>
Message-ID: <1438954486-28286-3-git-send-email-thierry.reding@gmail.com>

From: Thierry Reding <treding at nvidia.com>

Signed-off-by: Thierry Reding <treding at nvidia.com>
---
 arch/arm/include/uapi/asm/unistd.h | 1 +
 arch/arm/kernel/calls.S            | 1 +
 2 files changed, 2 insertions(+)

diff --git a/arch/arm/include/uapi/asm/unistd.h b/arch/arm/include/uapi/asm/unistd.h
index ca96eca3453c..977831f49576 100644
--- a/arch/arm/include/uapi/asm/unistd.h
+++ b/arch/arm/include/uapi/asm/unistd.h
@@ -415,6 +415,7 @@
 #define __NR_bpf			(__NR_SYSCALL_BASE+386)
 #define __NR_execveat			(__NR_SYSCALL_BASE+387)
 #define __NR_userfaultfd		(__NR_SYSCALL_BASE+388)
+#define __NR_mlock2			(__NR_SYSCALL_BASE+389)
 
 /*
  * The following SWIs are ARM private.
diff --git a/arch/arm/kernel/calls.S b/arch/arm/kernel/calls.S
index 84c405670ff0..e9705ba5a1ff 100644
--- a/arch/arm/kernel/calls.S
+++ b/arch/arm/kernel/calls.S
@@ -398,6 +398,7 @@
 		CALL(sys_bpf)
 		CALL(sys_execveat)
 		CALL(sys_userfaultfd)
+		CALL(sys_mlock2)
 #ifndef syscalls_counted
 .equ syscalls_padding, ((NR_syscalls + 3) & ~3) - NR_syscalls
 #define syscalls_counted
-- 
2.4.5



From robin.murphy at arm.com  Fri Aug  7 06:38:39 2015
From: robin.murphy at arm.com (Robin Murphy)
Date: Fri, 07 Aug 2015 14:38:39 +0100
Subject: [PATCH v5 1/3] iommu: Implement common IOMMU ops for DMA mapping
In-Reply-To: <20150807084228.GU14980@8bytes.org>
References: <cover.1438362603.git.robin.murphy@arm.com>
 <6ce6b501501f611297ae0eae31e07b0d2060eaae.1438362603.git.robin.murphy@arm.com>
 <20150807084228.GU14980@8bytes.org>
Message-ID: <55C4B4DF.4040608@arm.com>

Hi Joerg,

Thanks for taking a look,

On 07/08/15 09:42, Joerg Roedel wrote:
> On Fri, Jul 31, 2015 at 06:18:27PM +0100, Robin Murphy wrote:
>> +int iommu_get_dma_cookie(struct iommu_domain *domain)
>> +{
>> +	struct iova_domain *iovad;
>> +
>> +	if (domain->dma_api_cookie)
>> +		return -EEXIST;
>
> Why do you call that dma_api_cookie? It is just a pointer to an iova
> allocator, you can just name it as such, like domain->iova.

Sure, it was more the case that since it had to be in the top-level 
generic domain structure, I didn't want it to be too 
implementation-specific. I figured this was a reasonable compromise that 
wouldn't be a waste of space for implementations with different 
per-domain DMA API data - e.g. the AMD IOMMU driver could then make use 
of protection_domain->domain->dma_api_cookie instead of having 
protection_domain->priv, but that's a patch that wouldn't belong in this 
series anyway.

If you really hate that idea, then yeah, let's just call it iova and 
consider if factoring out redundancy is still applicable later.

>> +static struct iova *__alloc_iova(struct iova_domain *iovad, size_t size,
>> +		dma_addr_t dma_limit)
>
> I think you also need a struct device here to take segment boundary and
> dma_mask into account.

To the best of my understanding, those limits are only relevant when 
actually handing off a scatterlist to a client device doing hardware 
scatter-gather operations, so it's not so much the IOVA allocation that 
matters, but where the segments lie within it when handling dma_map_sg.

However, you do raise a good point - in the current "map everything 
consecutively" approach, if there is a non-power-of-2-sized segment in 
the middle of a scatterlist, then subsequent segments could possibly end 
up inadvertently straddling a boundary. That needs handling in 
iommu_dma_map_sg; I'll fix it appropriately.

>> +/* The IOVA allocator knows what we mapped, so just unmap whatever that was */
>> +static void __iommu_dma_unmap(struct iommu_domain *domain, dma_addr_t dma_addr)
>> +{
>> +	struct iova_domain *iovad = domain->dma_api_cookie;
>> +	unsigned long shift = iova_shift(iovad);
>> +	unsigned long pfn = dma_addr >> shift;
>> +	struct iova *iova = find_iova(iovad, pfn);
>> +	size_t size = iova_size(iova) << shift;
>> +
>> +	/* ...and if we can't, then something is horribly, horribly wrong */
>> +	BUG_ON(iommu_unmap(domain, pfn << shift, size) < size);
>
> This is a WARN_ON at most, not a BUG_ON condition, especially since this
> type of bug is also catched with the dma-api debugging code.

Indeed, DMA_DEBUG will check that a driver is making DMA API calls to 
the arch code in the right way; this is a different check, to catch 
things like the arch code passing the wrong domain into this layer, or 
someone else having messed directly with the domain via the IOMMU API. 
If the iommu_unmap doesn't match the IOVA region we looked up, that 
means the IOMMU page tables have somehow become inconsistent with the 
IOVA allocator, so we are in an unrecoverable situation where we can no 
longer be sure what devices have access to. That's bad.

>> +static struct page **__iommu_dma_alloc_pages(unsigned int count, gfp_t gfp)
>> +{
>> +	struct page **pages;
>> +	unsigned int i = 0, array_size = count * sizeof(*pages);
>> +
>> +	if (array_size <= PAGE_SIZE)
>> +		pages = kzalloc(array_size, GFP_KERNEL);
>> +	else
>> +		pages = vzalloc(array_size);
>> +	if (!pages)
>> +		return NULL;
>> +
>> +	/* IOMMU can map any pages, so himem can also be used here */
>> +	gfp |= __GFP_NOWARN | __GFP_HIGHMEM;
>> +
>> +	while (count) {
>> +		struct page *page = NULL;
>> +		int j, order = __fls(count);
>> +
>> +		/*
>> +		 * Higher-order allocations are a convenience rather
>> +		 * than a necessity, hence using __GFP_NORETRY until
>> +		 * falling back to single-page allocations.
>> +		 */
>> +		for (order = min(order, MAX_ORDER); order > 0; order--) {
>> +			page = alloc_pages(gfp | __GFP_NORETRY, order);
>> +			if (!page)
>> +				continue;
>> +			if (PageCompound(page)) {
>> +				if (!split_huge_page(page))
>> +					break;
>> +				__free_pages(page, order);
>> +			} else {
>> +				split_page(page, order);
>> +				break;
>> +			}
>> +		}
>> +		if (!page)
>> +			page = alloc_page(gfp);
>> +		if (!page) {
>> +			__iommu_dma_free_pages(pages, i);
>> +			return NULL;
>> +		}
>> +		j = 1 << order;
>> +		count -= j;
>> +		while (j--)
>> +			pages[i++] = page++;
>> +	}
>> +	return pages;
>> +}
>
> Hmm, most dma-api implementation just try to allocate a big enough
> region from the page-alloctor. Is it implemented different here to avoid
> the use of CMA?

AFAIK, yes (this is just a slight tidyup of the existing code that 
32-bit Exynos/Tegra/Rockchip/etc. devices are already using) - the 
display guys want increasingly massive contiguous allocations for 
framebuffers, layers, etc., so having IOMMU magic deal with that saves 
CMA for non-IOMMU devices that really need it.

Robin.



From thierry.reding at gmail.com  Fri Aug  7 06:56:47 2015
From: thierry.reding at gmail.com (Thierry Reding)
Date: Fri,  7 Aug 2015 15:56:47 +0200
Subject: [PATCH] drivers: psci: Allow PSCI node to be disabled
Message-ID: <1438955807-18574-1-git-send-email-thierry.reding@gmail.com>

From: Thierry Reding <treding at nvidia.com>

Allow disabling PSCI support (mostly for testing purposes) by setting
the status property to "disabled". This makes the node behave in much
the same way as proper device nodes.

Signed-off-by: Thierry Reding <treding at nvidia.com>
---
 drivers/firmware/psci.c | 2 +-
 1 file changed, 1 insertion(+), 1 deletion(-)

diff --git a/drivers/firmware/psci.c b/drivers/firmware/psci.c
index a6956007dd38..59e66ac2c3b6 100644
--- a/drivers/firmware/psci.c
+++ b/drivers/firmware/psci.c
@@ -351,7 +351,7 @@ int __init psci_dt_init(void)
 
 	np = of_find_matching_node_and_match(NULL, psci_of_match, &matched_np);
 
-	if (!np)
+	if (!np || !of_device_is_available(np))
 		return -ENODEV;
 
 	init_fn = (psci_initcall_t)matched_np->data;
-- 
2.4.5



From robherring2 at gmail.com  Fri Aug  7 06:58:30 2015
From: robherring2 at gmail.com (Rob Herring)
Date: Fri, 7 Aug 2015 08:58:30 -0500
Subject: [PATCH v3 06/18] regulator: core: Probe regulators on demand
In-Reply-To: <20150807120906.GR20873@sirena.org.uk>
References: <1438870315-18689-1-git-send-email-tomeu.vizoso@collabora.com>
 <1438870315-18689-7-git-send-email-tomeu.vizoso@collabora.com>
 <20150807120906.GR20873@sirena.org.uk>
Message-ID: <CAL_JsqJf-ZeAhJjkd-6sPH12xL3FX9pOyTBMYHsvS8PnOkAXDQ@mail.gmail.com>

On Fri, Aug 7, 2015 at 7:09 AM, Mark Brown <broonie at kernel.org> wrote:
> On Thu, Aug 06, 2015 at 04:11:43PM +0200, Tomeu Vizoso wrote:
>
>> When looking up a regulator through its OF node, probe it if it hasn't
>> already.
>>
>> The goal is to reduce deferred probes to a minimum, as it makes it very
>> cumbersome to find out why a device failed to probe, and can introduce
>> very big delays in when a critical device is probed.
>
> Still the same problem as we had before with this stuff, why is this DT
> only?

The last version was more generic, but it was obvious that doing that
was pointless with current code structure. You have a call sequence
like either:

generic get -> DT specific get -> generic poke  -> DT specific poke

or

generic get -> DT specific get -> DT specific poke

v2 did the former and this version does the latter. However, for some
reason with regulators this is not all contained within
of_get_regulator.

>
>>  #include <linux/regulator/consumer.h>
>> @@ -1336,6 +1337,7 @@ static struct regulator_dev *regulator_dev_lookup(struct device *dev,
>>       if (dev && dev->of_node) {
>>               node = of_get_regulator(dev, supply);
>>               if (node) {
>> +                     of_platform_probe(node);
>
> And why the assumption that this is a platform device?

Agreed on this point.

Rob


From mark.rutland at arm.com  Fri Aug  7 07:01:06 2015
From: mark.rutland at arm.com (Mark Rutland)
Date: Fri, 7 Aug 2015 15:01:06 +0100
Subject: [PATCH 2/2] net, thunder, bgx: Add support for ACPI binding.
In-Reply-To: <1438907590-29649-3-git-send-email-ddaney.cavm@gmail.com>
References: <1438907590-29649-1-git-send-email-ddaney.cavm@gmail.com>
 <1438907590-29649-3-git-send-email-ddaney.cavm@gmail.com>
Message-ID: <20150807140106.GE7646@leverpostej>

On Fri, Aug 07, 2015 at 01:33:10AM +0100, David Daney wrote:
> From: David Daney <david.daney at cavium.com>
> 
> Find out which PHYs belong to which BGX instance in the ACPI way.
> 
> Set the MAC address of the device as provided by ACPI tables. This is
> similar to the implementation for devicetree in
> of_get_mac_address(). The table is searched for the device property
> entries "mac-address", "local-mac-address" and "address" in that
> order. The address is provided in a u64 variable and must contain a
> valid 6 bytes-len mac addr.
> 
> Based on code from: Narinder Dhillon <ndhillon at cavium.com>
>                     Tomasz Nowicki <tomasz.nowicki at linaro.org>
>                     Robert Richter <rrichter at cavium.com>
> 
> Signed-off-by: Tomasz Nowicki <tomasz.nowicki at linaro.org>
> Signed-off-by: Robert Richter <rrichter at cavium.com>
> Signed-off-by: David Daney <david.daney at cavium.com>
> ---
>  drivers/net/ethernet/cavium/thunder/thunder_bgx.c | 137 +++++++++++++++++++++-
>  1 file changed, 135 insertions(+), 2 deletions(-)
> 
> diff --git a/drivers/net/ethernet/cavium/thunder/thunder_bgx.c b/drivers/net/ethernet/cavium/thunder/thunder_bgx.c
> index 615b2af..2056583 100644
> --- a/drivers/net/ethernet/cavium/thunder/thunder_bgx.c
> +++ b/drivers/net/ethernet/cavium/thunder/thunder_bgx.c
> @@ -6,6 +6,7 @@
>   * as published by the Free Software Foundation.
>   */
>  
> +#include <linux/acpi.h>
>  #include <linux/module.h>
>  #include <linux/interrupt.h>
>  #include <linux/pci.h>
> @@ -26,7 +27,7 @@
>  struct lmac {
>  	struct bgx		*bgx;
>  	int			dmac;
> -	unsigned char		mac[ETH_ALEN];
> +	u8			mac[ETH_ALEN];
>  	bool			link_up;
>  	int			lmacid; /* ID within BGX */
>  	int			lmacid_bd; /* ID on board */
> @@ -835,6 +836,133 @@ static void bgx_get_qlm_mode(struct bgx *bgx)
>  	}
>  }
>  
> +#ifdef CONFIG_ACPI
> +
> +static int bgx_match_phy_id(struct device *dev, void *data)
> +{
> +	struct phy_device *phydev = to_phy_device(dev);
> +	u32 *phy_id = data;
> +
> +	if (phydev->addr == *phy_id)
> +		return 1;
> +
> +	return 0;
> +}
> +
> +static const char * const addr_propnames[] = {
> +	"mac-address",
> +	"local-mac-address",
> +	"address",
> +};

If these are going to be generally necessary, then we should get them
adopted as standardised _DSD properties (ideally just one of them).

[...]

> +static acpi_status bgx_acpi_register_phy(acpi_handle handle,
> +					 u32 lvl, void *context, void **rv)
> +{
> +	struct acpi_reference_args args;
> +	const union acpi_object *prop;
> +	struct bgx *bgx = context;
> +	struct acpi_device *adev;
> +	struct device *phy_dev;
> +	u32 phy_id;
> +
> +	if (acpi_bus_get_device(handle, &adev))
> +		goto out;
> +
> +	SET_NETDEV_DEV(&bgx->lmac[bgx->lmac_count].netdev, &bgx->pdev->dev);
> +
> +	acpi_get_mac_address(adev, bgx->lmac[bgx->lmac_count].mac);
> +
> +	bgx->lmac[bgx->lmac_count].lmacid = bgx->lmac_count;
> +
> +	if (acpi_dev_get_property_reference(adev, "phy-handle", 0, &args))
> +		goto out;
> +
> +	if (acpi_dev_get_property(args.adev, "phy-channel", ACPI_TYPE_INTEGER, &prop))
> +		goto out;

Likewise for any inter-device properties, so that we can actually handle
them in a generic fashion, and avoid / learn from the mistakes we've
already handled with DT.

Mark.


From mchehab at osg.samsung.com  Fri Aug  7 07:20:05 2015
From: mchehab at osg.samsung.com (Mauro Carvalho Chehab)
Date: Fri,  7 Aug 2015 11:20:05 -0300
Subject: [PATCH RFC v2 07/16] media: get rid of unused "extra_links" param on
 media_entity_init()
In-Reply-To: <cover.1438954897.git.mchehab@osg.samsung.com>
References: <cover.1438954897.git.mchehab@osg.samsung.com>
Message-ID: <7b9f2654888f0fd54c290c50f50248a367768da7.1438954897.git.mchehab@osg.samsung.com>

Currently, media_entity_init() creates an array with the links,
allocated at init time. It provides a parameter (extra_links)
that would allocate more links than the current needs, but this
is not used by any driver.

As we want to be able to do dynamic link allocation/removal,
we'll need to change the implementation of the links. So,
before doing that, let's first remove that extra unused
parameter, in order to cleanup the interface first.

Signed-off-by: Mauro Carvalho Chehab <mchehab at osg.samsung.com>

diff --git a/Documentation/media-framework.txt b/Documentation/media-framework.txt
index f552a75c0e70..2cc6019f7147 100644
--- a/Documentation/media-framework.txt
+++ b/Documentation/media-framework.txt
@@ -104,7 +104,7 @@ although drivers can allocate entities directly.
 Drivers initialize entities by calling
 
 	media_entity_init(struct media_entity *entity, u16 num_pads,
-			  struct media_pad *pads, u16 extra_links);
+			  struct media_pad *pads);
 
 The media_entity name, type, flags, revision and group_id fields can be
 initialized before or after calling media_entity_init. Entities embedded in
diff --git a/Documentation/video4linux/v4l2-framework.txt b/Documentation/video4linux/v4l2-framework.txt
index 75d5c18d689a..109cc3792534 100644
--- a/Documentation/video4linux/v4l2-framework.txt
+++ b/Documentation/video4linux/v4l2-framework.txt
@@ -300,7 +300,7 @@ calling media_entity_init():
 	struct media_pad *pads = &my_sd->pads;
 	int err;
 
-	err = media_entity_init(&sd->entity, npads, pads, 0);
+	err = media_entity_init(&sd->entity, npads, pads);
 
 The pads array must have been previously initialized. There is no need to
 manually set the struct media_entity type and name fields, but the revision
@@ -700,7 +700,7 @@ calling media_entity_init():
 	struct media_pad *pad = &my_vdev->pad;
 	int err;
 
-	err = media_entity_init(&vdev->entity, 1, pad, 0);
+	err = media_entity_init(&vdev->entity, 1, pad);
 
 The pads array must have been previously initialized. There is no need to
 manually set the struct media_entity type and name fields.
diff --git a/Documentation/zh_CN/video4linux/v4l2-framework.txt b/Documentation/zh_CN/video4linux/v4l2-framework.txt
index 2b828e631e31..ff815cb92031 100644
--- a/Documentation/zh_CN/video4linux/v4l2-framework.txt
+++ b/Documentation/zh_CN/video4linux/v4l2-framework.txt
@@ -295,7 +295,7 @@ owner ??????????????? i2c ?????????????????????????????????????????????
 	struct media_pad *pads = &my_sd->pads;
 	int err;
 
-	err = media_entity_init(&sd->entity, npads, pads, 0);
+	err = media_entity_init(&sd->entity, npads, pads);
 
 pads ???????????????????????????????????????????????? media_entity ??? type ???
 name ????????????????????????revision ?????????????????????
@@ -602,7 +602,7 @@ v4l2_file_operations ???????????? file_operations ???????????????????????????
 	struct media_pad *pad = &my_vdev->pad;
 	int err;
 
-	err = media_entity_init(&vdev->entity, 1, pad, 0);
+	err = media_entity_init(&vdev->entity, 1, pad);
 
 pads ?????????????????????????????????????????????????????? media_entity ??? type ???
 name ??????
diff --git a/drivers/media/dvb-core/dvbdev.c b/drivers/media/dvb-core/dvbdev.c
index 13bb57f0457f..2fdcbb5f000a 100644
--- a/drivers/media/dvb-core/dvbdev.c
+++ b/drivers/media/dvb-core/dvbdev.c
@@ -249,7 +249,7 @@ static void dvb_register_media_device(struct dvb_device *dvbdev,
 	}
 
 	if (npads)
-		ret = media_entity_init(dvbdev->entity, npads, dvbdev->pads, 0);
+		ret = media_entity_init(dvbdev->entity, npads, dvbdev->pads);
 	if (!ret)
 		ret = media_device_register_entity(dvbdev->adapter->mdev,
 						   dvbdev->entity);
diff --git a/drivers/media/i2c/ad9389b.c b/drivers/media/i2c/ad9389b.c
index 69094ab047b1..39d6ee681aeb 100644
--- a/drivers/media/i2c/ad9389b.c
+++ b/drivers/media/i2c/ad9389b.c
@@ -1158,7 +1158,7 @@ static int ad9389b_probe(struct i2c_client *client, const struct i2c_device_id *
 	state->rgb_quantization_range_ctrl->is_private = true;
 
 	state->pad.flags = MEDIA_PAD_FL_SINK;
-	err = media_entity_init(&sd->entity, 1, &state->pad, 0);
+	err = media_entity_init(&sd->entity, 1, &state->pad);
 	if (err)
 		goto err_hdl;
 
diff --git a/drivers/media/i2c/adp1653.c b/drivers/media/i2c/adp1653.c
index c70ababce954..5f76997f6e07 100644
--- a/drivers/media/i2c/adp1653.c
+++ b/drivers/media/i2c/adp1653.c
@@ -512,7 +512,7 @@ static int adp1653_probe(struct i2c_client *client,
 	if (ret)
 		goto free_and_quit;
 
-	ret = media_entity_init(&flash->subdev.entity, 0, NULL, 0);
+	ret = media_entity_init(&flash->subdev.entity, 0, NULL);
 	if (ret < 0)
 		goto free_and_quit;
 
diff --git a/drivers/media/i2c/adv7180.c b/drivers/media/i2c/adv7180.c
index 09a96df170d1..cd15336260a3 100644
--- a/drivers/media/i2c/adv7180.c
+++ b/drivers/media/i2c/adv7180.c
@@ -1214,7 +1214,7 @@ static int adv7180_probe(struct i2c_client *client,
 
 	state->pad.flags = MEDIA_PAD_FL_SOURCE;
 	sd->entity.flags |= MEDIA_ENT_T_V4L2_SUBDEV_DECODER;
-	ret = media_entity_init(&sd->entity, 1, &state->pad, 0);
+	ret = media_entity_init(&sd->entity, 1, &state->pad);
 	if (ret)
 		goto err_free_ctrl;
 
diff --git a/drivers/media/i2c/adv7511.c b/drivers/media/i2c/adv7511.c
index 95bcd4026451..e70aa56a0b11 100644
--- a/drivers/media/i2c/adv7511.c
+++ b/drivers/media/i2c/adv7511.c
@@ -1482,7 +1482,7 @@ static int adv7511_probe(struct i2c_client *client, const struct i2c_device_id *
 	state->rgb_quantization_range_ctrl->is_private = true;
 
 	state->pad.flags = MEDIA_PAD_FL_SINK;
-	err = media_entity_init(&sd->entity, 1, &state->pad, 0);
+	err = media_entity_init(&sd->entity, 1, &state->pad);
 	if (err)
 		goto err_hdl;
 
diff --git a/drivers/media/i2c/adv7604.c b/drivers/media/i2c/adv7604.c
index bfb0b6a72bbc..dcefa810c8ac 100644
--- a/drivers/media/i2c/adv7604.c
+++ b/drivers/media/i2c/adv7604.c
@@ -3198,7 +3198,7 @@ static int adv76xx_probe(struct i2c_client *client,
 	state->pads[state->source_pad].flags = MEDIA_PAD_FL_SOURCE;
 
 	err = media_entity_init(&sd->entity, state->source_pad + 1,
-				state->pads, 0);
+				state->pads);
 	if (err)
 		goto err_work_queues;
 
diff --git a/drivers/media/i2c/adv7842.c b/drivers/media/i2c/adv7842.c
index 897d68c78b06..8a1ecc6ab36c 100644
--- a/drivers/media/i2c/adv7842.c
+++ b/drivers/media/i2c/adv7842.c
@@ -3309,7 +3309,7 @@ static int adv7842_probe(struct i2c_client *client,
 			adv7842_delayed_work_enable_hotplug);
 
 	state->pad.flags = MEDIA_PAD_FL_SOURCE;
-	err = media_entity_init(&sd->entity, 1, &state->pad, 0);
+	err = media_entity_init(&sd->entity, 1, &state->pad);
 	if (err)
 		goto err_work_queues;
 
diff --git a/drivers/media/i2c/as3645a.c b/drivers/media/i2c/as3645a.c
index 301084b07887..9d579a836f79 100644
--- a/drivers/media/i2c/as3645a.c
+++ b/drivers/media/i2c/as3645a.c
@@ -827,7 +827,7 @@ static int as3645a_probe(struct i2c_client *client,
 	if (ret < 0)
 		goto done;
 
-	ret = media_entity_init(&flash->subdev.entity, 0, NULL, 0);
+	ret = media_entity_init(&flash->subdev.entity, 0, NULL);
 	if (ret < 0)
 		goto done;
 
diff --git a/drivers/media/i2c/cx25840/cx25840-core.c b/drivers/media/i2c/cx25840/cx25840-core.c
index e15a789ad596..7a2cf352d9c5 100644
--- a/drivers/media/i2c/cx25840/cx25840-core.c
+++ b/drivers/media/i2c/cx25840/cx25840-core.c
@@ -5211,7 +5211,7 @@ static int cx25840_probe(struct i2c_client *client,
 	sd->entity.type = MEDIA_ENT_T_V4L2_SUBDEV_DECODER;
 
 	ret = media_entity_init(&sd->entity, ARRAY_SIZE(state->pads),
-				state->pads, 0);
+				state->pads);
 	if (ret < 0) {
 		v4l_info(client, "failed to initialize media entity!\n");
 		return ret;
diff --git a/drivers/media/i2c/lm3560.c b/drivers/media/i2c/lm3560.c
index d9ece4b2d047..9bd9def0852c 100644
--- a/drivers/media/i2c/lm3560.c
+++ b/drivers/media/i2c/lm3560.c
@@ -365,7 +365,7 @@ static int lm3560_subdev_init(struct lm3560_flash *flash,
 	rval = lm3560_init_controls(flash, led_no);
 	if (rval)
 		goto err_out;
-	rval = media_entity_init(&flash->subdev_led[led_no].entity, 0, NULL, 0);
+	rval = media_entity_init(&flash->subdev_led[led_no].entity, 0, NULL);
 	if (rval < 0)
 		goto err_out;
 	flash->subdev_led[led_no].entity.type = MEDIA_ENT_T_V4L2_SUBDEV_FLASH;
diff --git a/drivers/media/i2c/lm3646.c b/drivers/media/i2c/lm3646.c
index 626fb4679c02..4160e18af607 100644
--- a/drivers/media/i2c/lm3646.c
+++ b/drivers/media/i2c/lm3646.c
@@ -282,7 +282,7 @@ static int lm3646_subdev_init(struct lm3646_flash *flash)
 	rval = lm3646_init_controls(flash);
 	if (rval)
 		goto err_out;
-	rval = media_entity_init(&flash->subdev_led.entity, 0, NULL, 0);
+	rval = media_entity_init(&flash->subdev_led.entity, 0, NULL);
 	if (rval < 0)
 		goto err_out;
 	flash->subdev_led.entity.type = MEDIA_ENT_T_V4L2_SUBDEV_FLASH;
diff --git a/drivers/media/i2c/m5mols/m5mols_core.c b/drivers/media/i2c/m5mols/m5mols_core.c
index 6404c0d93e7a..f718a1009e4c 100644
--- a/drivers/media/i2c/m5mols/m5mols_core.c
+++ b/drivers/media/i2c/m5mols/m5mols_core.c
@@ -975,7 +975,7 @@ static int m5mols_probe(struct i2c_client *client,
 
 	sd->internal_ops = &m5mols_subdev_internal_ops;
 	info->pad.flags = MEDIA_PAD_FL_SOURCE;
-	ret = media_entity_init(&sd->entity, 1, &info->pad, 0);
+	ret = media_entity_init(&sd->entity, 1, &info->pad);
 	if (ret < 0)
 		return ret;
 	sd->entity.type = MEDIA_ENT_T_V4L2_SUBDEV_SENSOR;
diff --git a/drivers/media/i2c/mt9m032.c b/drivers/media/i2c/mt9m032.c
index c7747bd0cabb..1493ab6e7fb3 100644
--- a/drivers/media/i2c/mt9m032.c
+++ b/drivers/media/i2c/mt9m032.c
@@ -799,7 +799,7 @@ static int mt9m032_probe(struct i2c_client *client,
 
 	sensor->subdev.ctrl_handler = &sensor->ctrls;
 	sensor->pad.flags = MEDIA_PAD_FL_SOURCE;
-	ret = media_entity_init(&sensor->subdev.entity, 1, &sensor->pad, 0);
+	ret = media_entity_init(&sensor->subdev.entity, 1, &sensor->pad);
 	if (ret < 0)
 		goto error_ctrl;
 
diff --git a/drivers/media/i2c/mt9p031.c b/drivers/media/i2c/mt9p031.c
index 0db15f528ac1..e3c5af82b7c1 100644
--- a/drivers/media/i2c/mt9p031.c
+++ b/drivers/media/i2c/mt9p031.c
@@ -1112,7 +1112,7 @@ static int mt9p031_probe(struct i2c_client *client,
 	mt9p031->subdev.internal_ops = &mt9p031_subdev_internal_ops;
 
 	mt9p031->pad.flags = MEDIA_PAD_FL_SOURCE;
-	ret = media_entity_init(&mt9p031->subdev.entity, 1, &mt9p031->pad, 0);
+	ret = media_entity_init(&mt9p031->subdev.entity, 1, &mt9p031->pad);
 	if (ret < 0)
 		goto done;
 
diff --git a/drivers/media/i2c/mt9t001.c b/drivers/media/i2c/mt9t001.c
index 8ae99f7f254c..1dae1a98bc85 100644
--- a/drivers/media/i2c/mt9t001.c
+++ b/drivers/media/i2c/mt9t001.c
@@ -933,7 +933,7 @@ static int mt9t001_probe(struct i2c_client *client,
 	mt9t001->subdev.flags |= V4L2_SUBDEV_FL_HAS_DEVNODE;
 
 	mt9t001->pad.flags = MEDIA_PAD_FL_SOURCE;
-	ret = media_entity_init(&mt9t001->subdev.entity, 1, &mt9t001->pad, 0);
+	ret = media_entity_init(&mt9t001->subdev.entity, 1, &mt9t001->pad);
 
 done:
 	if (ret < 0) {
diff --git a/drivers/media/i2c/mt9v032.c b/drivers/media/i2c/mt9v032.c
index 977f4006edbd..980011aa039d 100644
--- a/drivers/media/i2c/mt9v032.c
+++ b/drivers/media/i2c/mt9v032.c
@@ -1046,7 +1046,7 @@ static int mt9v032_probe(struct i2c_client *client,
 	mt9v032->subdev.flags |= V4L2_SUBDEV_FL_HAS_DEVNODE;
 
 	mt9v032->pad.flags = MEDIA_PAD_FL_SOURCE;
-	ret = media_entity_init(&mt9v032->subdev.entity, 1, &mt9v032->pad, 0);
+	ret = media_entity_init(&mt9v032->subdev.entity, 1, &mt9v032->pad);
 	if (ret < 0)
 		goto err;
 
diff --git a/drivers/media/i2c/noon010pc30.c b/drivers/media/i2c/noon010pc30.c
index f197b6cbd407..a9761251b970 100644
--- a/drivers/media/i2c/noon010pc30.c
+++ b/drivers/media/i2c/noon010pc30.c
@@ -780,7 +780,7 @@ static int noon010_probe(struct i2c_client *client,
 
 	info->pad.flags = MEDIA_PAD_FL_SOURCE;
 	sd->entity.type = MEDIA_ENT_T_V4L2_SUBDEV_SENSOR;
-	ret = media_entity_init(&sd->entity, 1, &info->pad, 0);
+	ret = media_entity_init(&sd->entity, 1, &info->pad);
 	if (ret < 0)
 		goto np_err;
 
diff --git a/drivers/media/i2c/ov2659.c b/drivers/media/i2c/ov2659.c
index 6edffc7b74e3..39f2d2cfdc9c 100644
--- a/drivers/media/i2c/ov2659.c
+++ b/drivers/media/i2c/ov2659.c
@@ -1450,7 +1450,7 @@ static int ov2659_probe(struct i2c_client *client,
 #if defined(CONFIG_MEDIA_CONTROLLER)
 	ov2659->pad.flags = MEDIA_PAD_FL_SOURCE;
 	sd->entity.type = MEDIA_ENT_T_V4L2_SUBDEV_SENSOR;
-	ret = media_entity_init(&sd->entity, 1, &ov2659->pad, 0);
+	ret = media_entity_init(&sd->entity, 1, &ov2659->pad);
 	if (ret < 0) {
 		v4l2_ctrl_handler_free(&ov2659->ctrls);
 		return ret;
diff --git a/drivers/media/i2c/ov9650.c b/drivers/media/i2c/ov9650.c
index 2bc473385c91..6a6747343512 100644
--- a/drivers/media/i2c/ov9650.c
+++ b/drivers/media/i2c/ov9650.c
@@ -1501,7 +1501,7 @@ static int ov965x_probe(struct i2c_client *client,
 
 	ov965x->pad.flags = MEDIA_PAD_FL_SOURCE;
 	sd->entity.type = MEDIA_ENT_T_V4L2_SUBDEV_SENSOR;
-	ret = media_entity_init(&sd->entity, 1, &ov965x->pad, 0);
+	ret = media_entity_init(&sd->entity, 1, &ov965x->pad);
 	if (ret < 0)
 		return ret;
 
diff --git a/drivers/media/i2c/s5c73m3/s5c73m3-core.c b/drivers/media/i2c/s5c73m3/s5c73m3-core.c
index 53c5ea89f0b9..6d167428727d 100644
--- a/drivers/media/i2c/s5c73m3/s5c73m3-core.c
+++ b/drivers/media/i2c/s5c73m3/s5c73m3-core.c
@@ -1691,7 +1691,7 @@ static int s5c73m3_probe(struct i2c_client *client,
 	sd->entity.type = MEDIA_ENT_T_V4L2_SUBDEV;
 
 	ret = media_entity_init(&sd->entity, S5C73M3_NUM_PADS,
-							state->sensor_pads, 0);
+							state->sensor_pads);
 	if (ret < 0)
 		return ret;
 
@@ -1707,7 +1707,7 @@ static int s5c73m3_probe(struct i2c_client *client,
 	oif_sd->entity.type = MEDIA_ENT_T_V4L2_SUBDEV;
 
 	ret = media_entity_init(&oif_sd->entity, OIF_NUM_PADS,
-							state->oif_pads, 0);
+							state->oif_pads);
 	if (ret < 0)
 		return ret;
 
diff --git a/drivers/media/i2c/s5k4ecgx.c b/drivers/media/i2c/s5k4ecgx.c
index 97084237275d..d207ddce31b6 100644
--- a/drivers/media/i2c/s5k4ecgx.c
+++ b/drivers/media/i2c/s5k4ecgx.c
@@ -962,7 +962,7 @@ static int s5k4ecgx_probe(struct i2c_client *client,
 
 	priv->pad.flags = MEDIA_PAD_FL_SOURCE;
 	sd->entity.type = MEDIA_ENT_T_V4L2_SUBDEV_SENSOR;
-	ret = media_entity_init(&sd->entity, 1, &priv->pad, 0);
+	ret = media_entity_init(&sd->entity, 1, &priv->pad);
 	if (ret)
 		return ret;
 
diff --git a/drivers/media/i2c/s5k5baf.c b/drivers/media/i2c/s5k5baf.c
index 774e0d0c94cb..30a9ca62e034 100644
--- a/drivers/media/i2c/s5k5baf.c
+++ b/drivers/media/i2c/s5k5baf.c
@@ -1905,7 +1905,7 @@ static int s5k5baf_configure_subdevs(struct s5k5baf *state,
 
 	state->cis_pad.flags = MEDIA_PAD_FL_SOURCE;
 	sd->entity.type = MEDIA_ENT_T_V4L2_SUBDEV_SENSOR;
-	ret = media_entity_init(&sd->entity, NUM_CIS_PADS, &state->cis_pad, 0);
+	ret = media_entity_init(&sd->entity, NUM_CIS_PADS, &state->cis_pad);
 	if (ret < 0)
 		goto err;
 
@@ -1920,7 +1920,7 @@ static int s5k5baf_configure_subdevs(struct s5k5baf *state,
 	state->pads[PAD_CIS].flags = MEDIA_PAD_FL_SINK;
 	state->pads[PAD_OUT].flags = MEDIA_PAD_FL_SOURCE;
 	sd->entity.type = MEDIA_ENT_T_V4L2_SUBDEV;
-	ret = media_entity_init(&sd->entity, NUM_ISP_PADS, state->pads, 0);
+	ret = media_entity_init(&sd->entity, NUM_ISP_PADS, state->pads);
 
 	if (!ret)
 		return 0;
diff --git a/drivers/media/i2c/s5k6a3.c b/drivers/media/i2c/s5k6a3.c
index bc389d5e42ae..617a065bde6f 100644
--- a/drivers/media/i2c/s5k6a3.c
+++ b/drivers/media/i2c/s5k6a3.c
@@ -333,7 +333,7 @@ static int s5k6a3_probe(struct i2c_client *client,
 	sensor->format.height = S5K6A3_DEFAULT_HEIGHT;
 
 	sensor->pad.flags = MEDIA_PAD_FL_SOURCE;
-	ret = media_entity_init(&sd->entity, 1, &sensor->pad, 0);
+	ret = media_entity_init(&sd->entity, 1, &sensor->pad);
 	if (ret < 0)
 		return ret;
 
diff --git a/drivers/media/i2c/s5k6aa.c b/drivers/media/i2c/s5k6aa.c
index d0ad6a25bdab..39a461f9d9bb 100644
--- a/drivers/media/i2c/s5k6aa.c
+++ b/drivers/media/i2c/s5k6aa.c
@@ -1578,7 +1578,7 @@ static int s5k6aa_probe(struct i2c_client *client,
 
 	s5k6aa->pad.flags = MEDIA_PAD_FL_SOURCE;
 	sd->entity.type = MEDIA_ENT_T_V4L2_SUBDEV_SENSOR;
-	ret = media_entity_init(&sd->entity, 1, &s5k6aa->pad, 0);
+	ret = media_entity_init(&sd->entity, 1, &s5k6aa->pad);
 	if (ret)
 		return ret;
 
diff --git a/drivers/media/i2c/smiapp/smiapp-core.c b/drivers/media/i2c/smiapp/smiapp-core.c
index 636ebd6fe5dc..308613ea0aed 100644
--- a/drivers/media/i2c/smiapp/smiapp-core.c
+++ b/drivers/media/i2c/smiapp/smiapp-core.c
@@ -2488,7 +2488,7 @@ static int smiapp_register_subdevs(struct smiapp_sensor *sensor)
 			continue;
 
 		rval = media_entity_init(&this->sd.entity,
-					 this->npads, this->pads, 0);
+					 this->npads, this->pads);
 		if (rval) {
 			dev_err(&client->dev,
 				"media_entity_init failed\n");
@@ -3078,7 +3078,7 @@ static int smiapp_probe(struct i2c_client *client,
 
 	sensor->src->pads[0].flags = MEDIA_PAD_FL_SOURCE;
 	rval = media_entity_init(&sensor->src->sd.entity, 2,
-				 sensor->src->pads, 0);
+				 sensor->src->pads);
 	if (rval < 0)
 		return rval;
 
diff --git a/drivers/media/i2c/tc358743.c b/drivers/media/i2c/tc358743.c
index d0dd83d7a38e..39f47044af24 100644
--- a/drivers/media/i2c/tc358743.c
+++ b/drivers/media/i2c/tc358743.c
@@ -1880,7 +1880,7 @@ static int tc358743_probe(struct i2c_client *client,
 	}
 
 	state->pad.flags = MEDIA_PAD_FL_SOURCE;
-	err = media_entity_init(&sd->entity, 1, &state->pad, 0);
+	err = media_entity_init(&sd->entity, 1, &state->pad);
 	if (err < 0)
 		goto err_hdl;
 
diff --git a/drivers/media/i2c/tvp514x.c b/drivers/media/i2c/tvp514x.c
index a93985a9b070..11801636d901 100644
--- a/drivers/media/i2c/tvp514x.c
+++ b/drivers/media/i2c/tvp514x.c
@@ -1097,7 +1097,7 @@ tvp514x_probe(struct i2c_client *client, const struct i2c_device_id *id)
 	decoder->sd.flags |= V4L2_SUBDEV_FL_HAS_DEVNODE;
 	decoder->sd.entity.flags |= MEDIA_ENT_T_V4L2_SUBDEV_DECODER;
 
-	ret = media_entity_init(&decoder->sd.entity, 1, &decoder->pad, 0);
+	ret = media_entity_init(&decoder->sd.entity, 1, &decoder->pad);
 	if (ret < 0) {
 		v4l2_err(sd, "%s decoder driver failed to register !!\n",
 			 sd->name);
diff --git a/drivers/media/i2c/tvp7002.c b/drivers/media/i2c/tvp7002.c
index f617d8b745ee..3630f3e2a4c7 100644
--- a/drivers/media/i2c/tvp7002.c
+++ b/drivers/media/i2c/tvp7002.c
@@ -1014,7 +1014,7 @@ static int tvp7002_probe(struct i2c_client *c, const struct i2c_device_id *id)
 	device->sd.flags |= V4L2_SUBDEV_FL_HAS_DEVNODE;
 	device->sd.entity.flags |= MEDIA_ENT_T_V4L2_SUBDEV_DECODER;
 
-	error = media_entity_init(&device->sd.entity, 1, &device->pad, 0);
+	error = media_entity_init(&device->sd.entity, 1, &device->pad);
 	if (error < 0)
 		return error;
 #endif
diff --git a/drivers/media/media-entity.c b/drivers/media/media-entity.c
index 6985d5c53632..e8451a4a403b 100644
--- a/drivers/media/media-entity.c
+++ b/drivers/media/media-entity.c
@@ -68,7 +68,6 @@ void graph_obj_remove(struct media_graph_obj *gobj)
  * media_entity_init - Initialize a media entity
  *
  * @num_pads: Total number of sink and source pads.
- * @extra_links: Initial estimate of the number of extra links.
  * @pads: Array of 'num_pads' pads.
  *
  * The total number of pads is an intrinsic property of entities known by the
@@ -90,10 +89,10 @@ void graph_obj_remove(struct media_graph_obj *gobj)
  */
 int
 media_entity_init(struct media_entity *entity, u16 num_pads,
-		  struct media_pad *pads, u16 extra_links)
+		  struct media_pad *pads)
 {
 	struct media_link *links;
-	unsigned int max_links = num_pads + extra_links;
+	unsigned int max_links = num_pads;
 	unsigned int i;
 
 	links = kzalloc(max_links * sizeof(links[0]), GFP_KERNEL);
diff --git a/drivers/media/platform/exynos4-is/fimc-capture.c b/drivers/media/platform/exynos4-is/fimc-capture.c
index cfebf292e15a..0627a93b2f3b 100644
--- a/drivers/media/platform/exynos4-is/fimc-capture.c
+++ b/drivers/media/platform/exynos4-is/fimc-capture.c
@@ -1804,7 +1804,7 @@ static int fimc_register_capture_device(struct fimc_dev *fimc,
 	vid_cap->wb_fmt.code = fmt->mbus_code;
 
 	vid_cap->vd_pad.flags = MEDIA_PAD_FL_SINK;
-	ret = media_entity_init(&vfd->entity, 1, &vid_cap->vd_pad, 0);
+	ret = media_entity_init(&vfd->entity, 1, &vid_cap->vd_pad);
 	if (ret)
 		goto err_free_ctx;
 
@@ -1897,7 +1897,7 @@ int fimc_initialize_capture_subdev(struct fimc_dev *fimc)
 	fimc->vid_cap.sd_pads[FIMC_SD_PAD_SINK_FIFO].flags = MEDIA_PAD_FL_SINK;
 	fimc->vid_cap.sd_pads[FIMC_SD_PAD_SOURCE].flags = MEDIA_PAD_FL_SOURCE;
 	ret = media_entity_init(&sd->entity, FIMC_SD_PADS_NUM,
-				fimc->vid_cap.sd_pads, 0);
+				fimc->vid_cap.sd_pads);
 	if (ret)
 		return ret;
 
diff --git a/drivers/media/platform/exynos4-is/fimc-isp-video.c b/drivers/media/platform/exynos4-is/fimc-isp-video.c
index 76b6b4d14616..b7dc5ac66e36 100644
--- a/drivers/media/platform/exynos4-is/fimc-isp-video.c
+++ b/drivers/media/platform/exynos4-is/fimc-isp-video.c
@@ -618,7 +618,7 @@ int fimc_isp_video_device_register(struct fimc_isp *isp,
 	vdev->lock = &isp->video_lock;
 
 	iv->pad.flags = MEDIA_PAD_FL_SINK;
-	ret = media_entity_init(&vdev->entity, 1, &iv->pad, 0);
+	ret = media_entity_init(&vdev->entity, 1, &iv->pad);
 	if (ret < 0)
 		return ret;
 
diff --git a/drivers/media/platform/exynos4-is/fimc-isp.c b/drivers/media/platform/exynos4-is/fimc-isp.c
index 5d78f5716f3b..f52eebf765c1 100644
--- a/drivers/media/platform/exynos4-is/fimc-isp.c
+++ b/drivers/media/platform/exynos4-is/fimc-isp.c
@@ -709,7 +709,7 @@ int fimc_isp_subdev_create(struct fimc_isp *isp)
 	isp->subdev_pads[FIMC_ISP_SD_PAD_SRC_FIFO].flags = MEDIA_PAD_FL_SOURCE;
 	isp->subdev_pads[FIMC_ISP_SD_PAD_SRC_DMA].flags = MEDIA_PAD_FL_SOURCE;
 	ret = media_entity_init(&sd->entity, FIMC_ISP_SD_PADS_NUM,
-				isp->subdev_pads, 0);
+				isp->subdev_pads);
 	if (ret)
 		return ret;
 
diff --git a/drivers/media/platform/exynos4-is/fimc-lite.c b/drivers/media/platform/exynos4-is/fimc-lite.c
index ca6261a86a5f..e8f707d1729b 100644
--- a/drivers/media/platform/exynos4-is/fimc-lite.c
+++ b/drivers/media/platform/exynos4-is/fimc-lite.c
@@ -1322,7 +1322,7 @@ static int fimc_lite_subdev_registered(struct v4l2_subdev *sd)
 		return ret;
 
 	fimc->vd_pad.flags = MEDIA_PAD_FL_SINK;
-	ret = media_entity_init(&vfd->entity, 1, &fimc->vd_pad, 0);
+	ret = media_entity_init(&vfd->entity, 1, &fimc->vd_pad);
 	if (ret < 0)
 		return ret;
 
@@ -1437,7 +1437,7 @@ static int fimc_lite_create_capture_subdev(struct fimc_lite *fimc)
 	fimc->subdev_pads[FLITE_SD_PAD_SOURCE_DMA].flags = MEDIA_PAD_FL_SOURCE;
 	fimc->subdev_pads[FLITE_SD_PAD_SOURCE_ISP].flags = MEDIA_PAD_FL_SOURCE;
 	ret = media_entity_init(&sd->entity, FLITE_SD_PADS_NUM,
-				fimc->subdev_pads, 0);
+				fimc->subdev_pads);
 	if (ret)
 		return ret;
 
diff --git a/drivers/media/platform/exynos4-is/fimc-m2m.c b/drivers/media/platform/exynos4-is/fimc-m2m.c
index 0ad1b6f84a27..b57daec48b21 100644
--- a/drivers/media/platform/exynos4-is/fimc-m2m.c
+++ b/drivers/media/platform/exynos4-is/fimc-m2m.c
@@ -738,7 +738,7 @@ int fimc_register_m2m_device(struct fimc_dev *fimc,
 		return PTR_ERR(fimc->m2m.m2m_dev);
 	}
 
-	ret = media_entity_init(&vfd->entity, 0, NULL, 0);
+	ret = media_entity_init(&vfd->entity, 0, NULL);
 	if (ret)
 		goto err_me;
 
diff --git a/drivers/media/platform/exynos4-is/mipi-csis.c b/drivers/media/platform/exynos4-is/mipi-csis.c
index d74e1bec3d86..cf10cd783a86 100644
--- a/drivers/media/platform/exynos4-is/mipi-csis.c
+++ b/drivers/media/platform/exynos4-is/mipi-csis.c
@@ -866,7 +866,7 @@ static int s5pcsis_probe(struct platform_device *pdev)
 	state->pads[CSIS_PAD_SINK].flags = MEDIA_PAD_FL_SINK;
 	state->pads[CSIS_PAD_SOURCE].flags = MEDIA_PAD_FL_SOURCE;
 	ret = media_entity_init(&state->sd.entity,
-				CSIS_PADS_NUM, state->pads, 0);
+				CSIS_PADS_NUM, state->pads);
 	if (ret < 0)
 		goto e_clkdis;
 
diff --git a/drivers/media/platform/omap3isp/ispccdc.c b/drivers/media/platform/omap3isp/ispccdc.c
index a6a61cce43dd..3b10304b580b 100644
--- a/drivers/media/platform/omap3isp/ispccdc.c
+++ b/drivers/media/platform/omap3isp/ispccdc.c
@@ -2650,7 +2650,7 @@ static int ccdc_init_entities(struct isp_ccdc_device *ccdc)
 	pads[CCDC_PAD_SOURCE_OF].flags = MEDIA_PAD_FL_SOURCE;
 
 	me->ops = &ccdc_media_ops;
-	ret = media_entity_init(me, CCDC_PADS_NUM, pads, 0);
+	ret = media_entity_init(me, CCDC_PADS_NUM, pads);
 	if (ret < 0)
 		return ret;
 
diff --git a/drivers/media/platform/omap3isp/ispccp2.c b/drivers/media/platform/omap3isp/ispccp2.c
index 38e6a974c5b1..e1b5f5bea541 100644
--- a/drivers/media/platform/omap3isp/ispccp2.c
+++ b/drivers/media/platform/omap3isp/ispccp2.c
@@ -1071,7 +1071,7 @@ static int ccp2_init_entities(struct isp_ccp2_device *ccp2)
 	pads[CCP2_PAD_SOURCE].flags = MEDIA_PAD_FL_SOURCE;
 
 	me->ops = &ccp2_media_ops;
-	ret = media_entity_init(me, CCP2_PADS_NUM, pads, 0);
+	ret = media_entity_init(me, CCP2_PADS_NUM, pads);
 	if (ret < 0)
 		return ret;
 
diff --git a/drivers/media/platform/omap3isp/ispcsi2.c b/drivers/media/platform/omap3isp/ispcsi2.c
index a78338d012b4..6fff92f0813a 100644
--- a/drivers/media/platform/omap3isp/ispcsi2.c
+++ b/drivers/media/platform/omap3isp/ispcsi2.c
@@ -1245,7 +1245,7 @@ static int csi2_init_entities(struct isp_csi2_device *csi2)
 				    | MEDIA_PAD_FL_MUST_CONNECT;
 
 	me->ops = &csi2_media_ops;
-	ret = media_entity_init(me, CSI2_PADS_NUM, pads, 0);
+	ret = media_entity_init(me, CSI2_PADS_NUM, pads);
 	if (ret < 0)
 		return ret;
 
diff --git a/drivers/media/platform/omap3isp/isppreview.c b/drivers/media/platform/omap3isp/isppreview.c
index 13803270d104..b440c6342ca4 100644
--- a/drivers/media/platform/omap3isp/isppreview.c
+++ b/drivers/media/platform/omap3isp/isppreview.c
@@ -2282,7 +2282,7 @@ static int preview_init_entities(struct isp_prev_device *prev)
 	pads[PREV_PAD_SOURCE].flags = MEDIA_PAD_FL_SOURCE;
 
 	me->ops = &preview_media_ops;
-	ret = media_entity_init(me, PREV_PADS_NUM, pads, 0);
+	ret = media_entity_init(me, PREV_PADS_NUM, pads);
 	if (ret < 0)
 		return ret;
 
diff --git a/drivers/media/platform/omap3isp/ispresizer.c b/drivers/media/platform/omap3isp/ispresizer.c
index 7cfb43dc0ffd..3deb1ec4a973 100644
--- a/drivers/media/platform/omap3isp/ispresizer.c
+++ b/drivers/media/platform/omap3isp/ispresizer.c
@@ -1728,7 +1728,7 @@ static int resizer_init_entities(struct isp_res_device *res)
 	pads[RESZ_PAD_SOURCE].flags = MEDIA_PAD_FL_SOURCE;
 
 	me->ops = &resizer_media_ops;
-	ret = media_entity_init(me, RESZ_PADS_NUM, pads, 0);
+	ret = media_entity_init(me, RESZ_PADS_NUM, pads);
 	if (ret < 0)
 		return ret;
 
diff --git a/drivers/media/platform/omap3isp/ispstat.c b/drivers/media/platform/omap3isp/ispstat.c
index 20434e83e801..92a31dd28ace 100644
--- a/drivers/media/platform/omap3isp/ispstat.c
+++ b/drivers/media/platform/omap3isp/ispstat.c
@@ -1029,7 +1029,7 @@ static int isp_stat_init_entities(struct ispstat *stat, const char *name,
 	stat->pad.flags = MEDIA_PAD_FL_SINK | MEDIA_PAD_FL_MUST_CONNECT;
 	me->ops = NULL;
 
-	return media_entity_init(me, 1, &stat->pad, 0);
+	return media_entity_init(me, 1, &stat->pad);
 }
 
 int omap3isp_stat_init(struct ispstat *stat, const char *name,
diff --git a/drivers/media/platform/omap3isp/ispvideo.c b/drivers/media/platform/omap3isp/ispvideo.c
index d285af18df7f..1809e52d2df9 100644
--- a/drivers/media/platform/omap3isp/ispvideo.c
+++ b/drivers/media/platform/omap3isp/ispvideo.c
@@ -1368,7 +1368,7 @@ int omap3isp_video_init(struct isp_video *video, const char *name)
 	if (IS_ERR(video->alloc_ctx))
 		return PTR_ERR(video->alloc_ctx);
 
-	ret = media_entity_init(&video->video.entity, 1, &video->pad, 0);
+	ret = media_entity_init(&video->video.entity, 1, &video->pad);
 	if (ret < 0) {
 		vb2_dma_contig_cleanup_ctx(video->alloc_ctx);
 		return ret;
diff --git a/drivers/media/platform/s3c-camif/camif-capture.c b/drivers/media/platform/s3c-camif/camif-capture.c
index 76e6289a5612..eae667eab1b9 100644
--- a/drivers/media/platform/s3c-camif/camif-capture.c
+++ b/drivers/media/platform/s3c-camif/camif-capture.c
@@ -1159,7 +1159,7 @@ int s3c_camif_register_video_node(struct camif_dev *camif, int idx)
 		goto err_vd_rel;
 
 	vp->pad.flags = MEDIA_PAD_FL_SINK;
-	ret = media_entity_init(&vfd->entity, 1, &vp->pad, 0);
+	ret = media_entity_init(&vfd->entity, 1, &vp->pad);
 	if (ret)
 		goto err_vd_rel;
 
@@ -1575,7 +1575,7 @@ int s3c_camif_create_subdev(struct camif_dev *camif)
 	camif->pads[CAMIF_SD_PAD_SOURCE_P].flags = MEDIA_PAD_FL_SOURCE;
 
 	ret = media_entity_init(&sd->entity, CAMIF_SD_PADS_NUM,
-				camif->pads, 0);
+				camif->pads);
 	if (ret)
 		return ret;
 
diff --git a/drivers/media/platform/vsp1/vsp1_entity.c b/drivers/media/platform/vsp1/vsp1_entity.c
index fd95a75b04f4..619942ff2058 100644
--- a/drivers/media/platform/vsp1/vsp1_entity.c
+++ b/drivers/media/platform/vsp1/vsp1_entity.c
@@ -220,7 +220,7 @@ int vsp1_entity_init(struct vsp1_device *vsp1, struct vsp1_entity *entity,
 
 	/* Initialize the media entity. */
 	return media_entity_init(&entity->subdev.entity, num_pads,
-				 entity->pads, 0);
+				 entity->pads);
 }
 
 void vsp1_entity_destroy(struct vsp1_entity *entity)
diff --git a/drivers/media/platform/vsp1/vsp1_video.c b/drivers/media/platform/vsp1/vsp1_video.c
index 3c124c14ce14..17f08973f835 100644
--- a/drivers/media/platform/vsp1/vsp1_video.c
+++ b/drivers/media/platform/vsp1/vsp1_video.c
@@ -1221,7 +1221,7 @@ int vsp1_video_init(struct vsp1_video *video, struct vsp1_entity *rwpf)
 	video->pipe.state = VSP1_PIPELINE_STOPPED;
 
 	/* Initialize the media entity... */
-	ret = media_entity_init(&video->video.entity, 1, &video->pad, 0);
+	ret = media_entity_init(&video->video.entity, 1, &video->pad);
 	if (ret < 0)
 		return ret;
 
diff --git a/drivers/media/platform/xilinx/xilinx-dma.c b/drivers/media/platform/xilinx/xilinx-dma.c
index e779c93cb015..f7f9aa353a55 100644
--- a/drivers/media/platform/xilinx/xilinx-dma.c
+++ b/drivers/media/platform/xilinx/xilinx-dma.c
@@ -676,7 +676,7 @@ int xvip_dma_init(struct xvip_composite_device *xdev, struct xvip_dma *dma,
 	dma->pad.flags = type == V4L2_BUF_TYPE_VIDEO_CAPTURE
 		       ? MEDIA_PAD_FL_SINK : MEDIA_PAD_FL_SOURCE;
 
-	ret = media_entity_init(&dma->video.entity, 1, &dma->pad, 0);
+	ret = media_entity_init(&dma->video.entity, 1, &dma->pad);
 	if (ret < 0)
 		goto error;
 
diff --git a/drivers/media/platform/xilinx/xilinx-tpg.c b/drivers/media/platform/xilinx/xilinx-tpg.c
index b5f7d5ecb7f6..285976aa0f4d 100644
--- a/drivers/media/platform/xilinx/xilinx-tpg.c
+++ b/drivers/media/platform/xilinx/xilinx-tpg.c
@@ -836,7 +836,7 @@ static int xtpg_probe(struct platform_device *pdev)
 	subdev->flags |= V4L2_SUBDEV_FL_HAS_DEVNODE;
 	subdev->entity.ops = &xtpg_media_ops;
 
-	ret = media_entity_init(&subdev->entity, xtpg->npads, xtpg->pads, 0);
+	ret = media_entity_init(&subdev->entity, xtpg->npads, xtpg->pads);
 	if (ret < 0)
 		goto error;
 
diff --git a/drivers/media/usb/cx231xx/cx231xx-video.c b/drivers/media/usb/cx231xx/cx231xx-video.c
index c6ff8968286a..8f04b125486f 100644
--- a/drivers/media/usb/cx231xx/cx231xx-video.c
+++ b/drivers/media/usb/cx231xx/cx231xx-video.c
@@ -2175,7 +2175,7 @@ int cx231xx_register_analog_devices(struct cx231xx *dev)
 	cx231xx_vdev_init(dev, &dev->vdev, &cx231xx_video_template, "video");
 #if defined(CONFIG_MEDIA_CONTROLLER)
 	dev->video_pad.flags = MEDIA_PAD_FL_SINK;
-	ret = media_entity_init(&dev->vdev.entity, 1, &dev->video_pad, 0);
+	ret = media_entity_init(&dev->vdev.entity, 1, &dev->video_pad);
 	if (ret < 0)
 		dev_err(dev->dev, "failed to initialize video media entity!\n");
 #endif
@@ -2202,7 +2202,7 @@ int cx231xx_register_analog_devices(struct cx231xx *dev)
 
 #if defined(CONFIG_MEDIA_CONTROLLER)
 	dev->vbi_pad.flags = MEDIA_PAD_FL_SINK;
-	ret = media_entity_init(&dev->vbi_dev.entity, 1, &dev->vbi_pad, 0);
+	ret = media_entity_init(&dev->vbi_dev.entity, 1, &dev->vbi_pad);
 	if (ret < 0)
 		dev_err(dev->dev, "failed to initialize vbi media entity!\n");
 #endif
diff --git a/drivers/media/usb/uvc/uvc_entity.c b/drivers/media/usb/uvc/uvc_entity.c
index dc56a59ecadc..245445491516 100644
--- a/drivers/media/usb/uvc/uvc_entity.c
+++ b/drivers/media/usb/uvc/uvc_entity.c
@@ -89,10 +89,10 @@ static int uvc_mc_init_entity(struct uvc_entity *entity)
 			sizeof(entity->subdev.name));
 
 		ret = media_entity_init(&entity->subdev.entity,
-					entity->num_pads, entity->pads, 0);
+					entity->num_pads, entity->pads);
 	} else if (entity->vdev != NULL) {
 		ret = media_entity_init(&entity->vdev->entity,
-					entity->num_pads, entity->pads, 0);
+					entity->num_pads, entity->pads);
 		if (entity->flags & UVC_ENTITY_FLAG_DEFAULT)
 			entity->vdev->entity.flags |= MEDIA_ENT_FL_DEFAULT;
 	} else
diff --git a/drivers/media/v4l2-core/tuner-core.c b/drivers/media/v4l2-core/tuner-core.c
index abdcffabcb59..0ccf9a903e1e 100644
--- a/drivers/media/v4l2-core/tuner-core.c
+++ b/drivers/media/v4l2-core/tuner-core.c
@@ -699,7 +699,7 @@ register_client:
 	t->sd.entity.type = MEDIA_ENT_T_V4L2_SUBDEV_TUNER;
 	t->sd.entity.name = t->name;
 
-	ret = media_entity_init(&t->sd.entity, 1, &t->pad, 0);
+	ret = media_entity_init(&t->sd.entity, 1, &t->pad);
 	if (ret < 0) {
 		tuner_err("failed to initialize media entity!\n");
 		kfree(t);
diff --git a/drivers/media/v4l2-core/v4l2-flash-led-class.c b/drivers/media/v4l2-core/v4l2-flash-led-class.c
index 5bdfb8d5263a..34c489fed55e 100644
--- a/drivers/media/v4l2-core/v4l2-flash-led-class.c
+++ b/drivers/media/v4l2-core/v4l2-flash-led-class.c
@@ -651,7 +651,7 @@ struct v4l2_flash *v4l2_flash_init(
 	sd->flags |= V4L2_SUBDEV_FL_HAS_DEVNODE;
 	strlcpy(sd->name, config->dev_name, sizeof(sd->name));
 
-	ret = media_entity_init(&sd->entity, 0, NULL, 0);
+	ret = media_entity_init(&sd->entity, 0, NULL);
 	if (ret < 0)
 		return ERR_PTR(ret);
 
diff --git a/drivers/staging/media/davinci_vpfe/dm365_ipipe.c b/drivers/staging/media/davinci_vpfe/dm365_ipipe.c
index 1bbb90ce0086..b89a057b8b7e 100644
--- a/drivers/staging/media/davinci_vpfe/dm365_ipipe.c
+++ b/drivers/staging/media/davinci_vpfe/dm365_ipipe.c
@@ -1839,7 +1839,7 @@ vpfe_ipipe_init(struct vpfe_ipipe_device *ipipe, struct platform_device *pdev)
 	v4l2_ctrl_handler_setup(&ipipe->ctrls);
 	sd->ctrl_handler = &ipipe->ctrls;
 
-	return media_entity_init(me, IPIPE_PADS_NUM, pads, 0);
+	return media_entity_init(me, IPIPE_PADS_NUM, pads);
 }
 
 /*
diff --git a/drivers/staging/media/davinci_vpfe/dm365_ipipeif.c b/drivers/staging/media/davinci_vpfe/dm365_ipipeif.c
index 8b230541b1d1..8fb676186898 100644
--- a/drivers/staging/media/davinci_vpfe/dm365_ipipeif.c
+++ b/drivers/staging/media/davinci_vpfe/dm365_ipipeif.c
@@ -1026,7 +1026,7 @@ int vpfe_ipipeif_init(struct vpfe_ipipeif_device *ipipeif,
 	ipipeif->output = IPIPEIF_OUTPUT_NONE;
 	me->ops = &ipipeif_media_ops;
 
-	ret = media_entity_init(me, IPIPEIF_NUM_PADS, pads, 0);
+	ret = media_entity_init(me, IPIPEIF_NUM_PADS, pads);
 	if (ret)
 		goto fail;
 
diff --git a/drivers/staging/media/davinci_vpfe/dm365_isif.c b/drivers/staging/media/davinci_vpfe/dm365_isif.c
index 80907b464412..b1f01adfa7c8 100644
--- a/drivers/staging/media/davinci_vpfe/dm365_isif.c
+++ b/drivers/staging/media/davinci_vpfe/dm365_isif.c
@@ -2052,7 +2052,7 @@ int vpfe_isif_init(struct vpfe_isif_device *isif, struct platform_device *pdev)
 	isif->input = ISIF_INPUT_NONE;
 	isif->output = ISIF_OUTPUT_NONE;
 	me->ops = &isif_media_ops;
-	status = media_entity_init(me, ISIF_PADS_NUM, pads, 0);
+	status = media_entity_init(me, ISIF_PADS_NUM, pads);
 	if (status)
 		goto isif_fail;
 	isif->video_out.type = V4L2_BUF_TYPE_VIDEO_CAPTURE;
diff --git a/drivers/staging/media/davinci_vpfe/dm365_resizer.c b/drivers/staging/media/davinci_vpfe/dm365_resizer.c
index acb293ed9c91..692789aa22f4 100644
--- a/drivers/staging/media/davinci_vpfe/dm365_resizer.c
+++ b/drivers/staging/media/davinci_vpfe/dm365_resizer.c
@@ -1915,7 +1915,7 @@ int vpfe_resizer_init(struct vpfe_resizer_device *vpfe_rsz,
 	vpfe_rsz->crop_resizer.output2 = RESIZER_CROP_OUTPUT_NONE;
 	vpfe_rsz->crop_resizer.rsz_device = vpfe_rsz;
 	me->ops = &resizer_media_ops;
-	ret = media_entity_init(me, RESIZER_CROP_PADS_NUM, pads, 0);
+	ret = media_entity_init(me, RESIZER_CROP_PADS_NUM, pads);
 	if (ret)
 		return ret;
 
@@ -1937,7 +1937,7 @@ int vpfe_resizer_init(struct vpfe_resizer_device *vpfe_rsz,
 	vpfe_rsz->resizer_a.output = RESIZER_OUTPUT_NONE;
 	vpfe_rsz->resizer_a.rsz_device = vpfe_rsz;
 	me->ops = &resizer_media_ops;
-	ret = media_entity_init(me, RESIZER_PADS_NUM, pads, 0);
+	ret = media_entity_init(me, RESIZER_PADS_NUM, pads);
 	if (ret)
 		return ret;
 
@@ -1959,7 +1959,7 @@ int vpfe_resizer_init(struct vpfe_resizer_device *vpfe_rsz,
 	vpfe_rsz->resizer_b.output = RESIZER_OUTPUT_NONE;
 	vpfe_rsz->resizer_b.rsz_device = vpfe_rsz;
 	me->ops = &resizer_media_ops;
-	ret = media_entity_init(me, RESIZER_PADS_NUM, pads, 0);
+	ret = media_entity_init(me, RESIZER_PADS_NUM, pads);
 	if (ret)
 		return ret;
 
diff --git a/drivers/staging/media/davinci_vpfe/vpfe_video.c b/drivers/staging/media/davinci_vpfe/vpfe_video.c
index 87048a14c34d..61a8d5beff58 100644
--- a/drivers/staging/media/davinci_vpfe/vpfe_video.c
+++ b/drivers/staging/media/davinci_vpfe/vpfe_video.c
@@ -1594,7 +1594,7 @@ int vpfe_video_init(struct vpfe_video_device *video, const char *name)
 	spin_lock_init(&video->dma_queue_lock);
 	mutex_init(&video->lock);
 	ret = media_entity_init(&video->video_dev.entity,
-				1, &video->pad, 0);
+				1, &video->pad);
 	if (ret < 0)
 		return ret;
 
diff --git a/drivers/staging/media/omap4iss/iss_csi2.c b/drivers/staging/media/omap4iss/iss_csi2.c
index bc83f8246101..e936cfc218cb 100644
--- a/drivers/staging/media/omap4iss/iss_csi2.c
+++ b/drivers/staging/media/omap4iss/iss_csi2.c
@@ -1271,7 +1271,7 @@ static int csi2_init_entities(struct iss_csi2_device *csi2, const char *subname)
 	pads[CSI2_PAD_SINK].flags = MEDIA_PAD_FL_SINK;
 
 	me->ops = &csi2_media_ops;
-	ret = media_entity_init(me, CSI2_PADS_NUM, pads, 0);
+	ret = media_entity_init(me, CSI2_PADS_NUM, pads);
 	if (ret < 0)
 		return ret;
 
diff --git a/drivers/staging/media/omap4iss/iss_ipipe.c b/drivers/staging/media/omap4iss/iss_ipipe.c
index f94a59299a83..e1a7b7ba7362 100644
--- a/drivers/staging/media/omap4iss/iss_ipipe.c
+++ b/drivers/staging/media/omap4iss/iss_ipipe.c
@@ -513,7 +513,7 @@ static int ipipe_init_entities(struct iss_ipipe_device *ipipe)
 	pads[IPIPE_PAD_SOURCE_VP].flags = MEDIA_PAD_FL_SOURCE;
 
 	me->ops = &ipipe_media_ops;
-	ret = media_entity_init(me, IPIPE_PADS_NUM, pads, 0);
+	ret = media_entity_init(me, IPIPE_PADS_NUM, pads);
 	if (ret < 0)
 		return ret;
 
diff --git a/drivers/staging/media/omap4iss/iss_ipipeif.c b/drivers/staging/media/omap4iss/iss_ipipeif.c
index c0da13d55865..be5f80d7b5dc 100644
--- a/drivers/staging/media/omap4iss/iss_ipipeif.c
+++ b/drivers/staging/media/omap4iss/iss_ipipeif.c
@@ -743,7 +743,7 @@ static int ipipeif_init_entities(struct iss_ipipeif_device *ipipeif)
 	pads[IPIPEIF_PAD_SOURCE_VP].flags = MEDIA_PAD_FL_SOURCE;
 
 	me->ops = &ipipeif_media_ops;
-	ret = media_entity_init(me, IPIPEIF_PADS_NUM, pads, 0);
+	ret = media_entity_init(me, IPIPEIF_PADS_NUM, pads);
 	if (ret < 0)
 		return ret;
 
diff --git a/drivers/staging/media/omap4iss/iss_resizer.c b/drivers/staging/media/omap4iss/iss_resizer.c
index 5030cf3cd34c..91e724085dba 100644
--- a/drivers/staging/media/omap4iss/iss_resizer.c
+++ b/drivers/staging/media/omap4iss/iss_resizer.c
@@ -787,7 +787,7 @@ static int resizer_init_entities(struct iss_resizer_device *resizer)
 	pads[RESIZER_PAD_SOURCE_MEM].flags = MEDIA_PAD_FL_SOURCE;
 
 	me->ops = &resizer_media_ops;
-	ret = media_entity_init(me, RESIZER_PADS_NUM, pads, 0);
+	ret = media_entity_init(me, RESIZER_PADS_NUM, pads);
 	if (ret < 0)
 		return ret;
 
diff --git a/drivers/staging/media/omap4iss/iss_video.c b/drivers/staging/media/omap4iss/iss_video.c
index 40405d8710a6..bae67742706f 100644
--- a/drivers/staging/media/omap4iss/iss_video.c
+++ b/drivers/staging/media/omap4iss/iss_video.c
@@ -1104,7 +1104,7 @@ int omap4iss_video_init(struct iss_video *video, const char *name)
 		return -EINVAL;
 	}
 
-	ret = media_entity_init(&video->video.entity, 1, &video->pad, 0);
+	ret = media_entity_init(&video->video.entity, 1, &video->pad);
 	if (ret < 0)
 		return ret;
 
diff --git a/include/media/media-entity.h b/include/media/media-entity.h
index 738e1d5d25dc..be6885e7c8ed 100644
--- a/include/media/media-entity.h
+++ b/include/media/media-entity.h
@@ -177,7 +177,7 @@ void graph_obj_init(struct media_device *mdev,
 void graph_obj_remove(struct media_graph_obj *gobj);
 
 int media_entity_init(struct media_entity *entity, u16 num_pads,
-		struct media_pad *pads, u16 extra_links);
+		struct media_pad *pads);
 void media_entity_cleanup(struct media_entity *entity);
 
 int media_entity_create_link(struct media_entity *source, u16 source_pad,
-- 
2.4.3



From kishon at ti.com  Fri Aug  7 07:25:43 2015
From: kishon at ti.com (Kishon Vijay Abraham I)
Date: Fri, 7 Aug 2015 19:55:43 +0530
Subject: [PATCH 0/4] omap: Fix broken pbias device creation
In-Reply-To: <CALeDE9OBjESdkXhkAEVj1L-XKJ1yoFg8rkHvcJ_Uj_RXOC-yUQ@mail.gmail.com>
References: <1437999401-3519-1-git-send-email-kishon@ti.com>	<55B89590.6000109@ti.com>	<20150805100009.GY16878@atomide.com>
 <CALeDE9OBjESdkXhkAEVj1L-XKJ1yoFg8rkHvcJ_Uj_RXOC-yUQ@mail.gmail.com>
Message-ID: <55C4BFE7.2070302@ti.com>

Hi Peter,

On Friday 07 August 2015 05:18 PM, Peter Robinson wrote:
> On Wed, Aug 5, 2015 at 11:00 AM, Tony Lindgren <tony at atomide.com> wrote:
>> * Grygorii Strashko <grygorii.strashko at ti.com> [150729 02:01]:
>>> On 07/27/2015 03:16 PM, Kishon Vijay Abraham I wrote:
>>>> pbias device creation got broken once SCM cleanup got merged.
>>>> This patch series re-enables device creation by adding
>>>> "simple-bus" in the compatible property of the syscon
>>>> dt node.
>>>>
>>>> validated this series in DRA72, OMAP4 PANDA and OMAP5 UEVM
>>>> boards.
>>>>
>>>> Kishon Vijay Abraham I (4):
>>>>   ARM: dts: omap24xx: Fix broken pbias device creation
>>>>   ARM: dts: OMAP4: Fix broken pbias device creation
>>>>   ARM: dts: OMAP5: Fix broken pbias device creation
>>>>   ARM: dts: dra7: Fix broken pbias device creation
>>>>
>>>>  arch/arm/boot/dts/dra7.dtsi     |    2 +-
>>>>  arch/arm/boot/dts/omap2430.dtsi |    3 ++-
>>>>  arch/arm/boot/dts/omap4.dtsi    |    3 ++-
>>>>  arch/arm/boot/dts/omap5.dtsi    |    3 ++-
>>>>  4 files changed, 7 insertions(+), 4 deletions(-)
>>>>
>>>
>>> For dra7-evm:
>>> Tested-by: Grygorii Strashko <grygorii.strashko at ti.com>
>>
>> Applying all into omap-for-v4.2fixes-v2 thanks.
> 
> Do we need the same for am33xx.dtsi too given commit e3bc5358e097 ?

PBIAS is not present in am33xx.

Thanks
Kishon


From marc.zyngier at arm.com  Fri Aug  7 07:34:10 2015
From: marc.zyngier at arm.com (Marc Zyngier)
Date: Fri, 07 Aug 2015 15:34:10 +0100
Subject: [PATCH v3 2/5] pci:host: Add Altera PCIe host controller driver
In-Reply-To: <1438933382-2936-3-git-send-email-lftan@altera.com>
References: <1438933382-2936-1-git-send-email-lftan@altera.com>
 <1438933382-2936-3-git-send-email-lftan@altera.com>
Message-ID: <55C4C1E2.7080205@arm.com>

On 07/08/15 08:42, Ley Foon Tan wrote:
> This patch adds the Altera PCIe host controller driver.
> 
> Signed-off-by: Ley Foon Tan <lftan at altera.com>
> ---
>  drivers/pci/host/Kconfig       |   7 +
>  drivers/pci/host/Makefile      |   1 +
>  drivers/pci/host/pcie-altera.c | 532 +++++++++++++++++++++++++++++++++++++++++
>  3 files changed, 540 insertions(+)
>  create mode 100644 drivers/pci/host/pcie-altera.c
> 
> diff --git a/drivers/pci/host/Kconfig b/drivers/pci/host/Kconfig
> index 675c2d1..4b4754a 100644
> --- a/drivers/pci/host/Kconfig
> +++ b/drivers/pci/host/Kconfig
> @@ -145,4 +145,11 @@ config PCIE_IPROC_BCMA
>           Say Y here if you want to use the Broadcom iProc PCIe controller
>           through the BCMA bus interface
> 
> +config PCIE_ALTERA
> +       tristate "Altera PCIe controller"
> +       depends on ARCH_SOCFPGA
> +       help
> +         Say Y here if you want to enable PCIe controller support for Altera
> +         SoCFPGA family of SoCs.
> +
>  endmenu
> diff --git a/drivers/pci/host/Makefile b/drivers/pci/host/Makefile
> index 140d66f..6954f76 100644
> --- a/drivers/pci/host/Makefile
> +++ b/drivers/pci/host/Makefile
> @@ -17,3 +17,4 @@ obj-$(CONFIG_PCI_VERSATILE) += pci-versatile.o
>  obj-$(CONFIG_PCIE_IPROC) += pcie-iproc.o
>  obj-$(CONFIG_PCIE_IPROC_PLATFORM) += pcie-iproc-platform.o
>  obj-$(CONFIG_PCIE_IPROC_BCMA) += pcie-iproc-bcma.o
> +obj-$(CONFIG_PCIE_ALTERA) += pcie-altera.o
> diff --git a/drivers/pci/host/pcie-altera.c b/drivers/pci/host/pcie-altera.c
> new file mode 100644
> index 0000000..37bed81
> --- /dev/null
> +++ b/drivers/pci/host/pcie-altera.c
> @@ -0,0 +1,532 @@
> +/*
> + * Copyright Altera Corporation (C) 2013-2015. All rights reserved
> + *
> + * This program is free software; you can redistribute it and/or modify it
> + * under the terms and conditions of the GNU General Public License,
> + * version 2, as published by the Free Software Foundation.
> + *
> + * This program is distributed in the hope 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.
> + *
> + * You should have received a copy of the GNU General Public License along with
> + * this program.  If not, see <http://www.gnu.org/licenses/>.
> + */
> +#include <linux/interrupt.h>
> +#include <linux/irqchip/chained_irq.h>
> +#include <linux/module.h>
> +#include <linux/of_address.h>
> +#include <linux/of_irq.h>
> +#include <linux/of_pci.h>
> +#include <linux/pci.h>
> +#include <linux/platform_device.h>
> +#include <linux/slab.h>
> +
> +#define A2P_ADDR_MAP_LO0               0x1000
> +#define A2P_ADDR_MAP_HI0               0x1004
> +#define RP_TX_REG0                     0x2000
> +#define RP_TX_REG1                     0x2004
> +#define RP_TX_CNTRL                    0x2008
> +#define RP_TX_EOP                      0x2
> +#define RP_TX_SOP                      0x1
> +#define RP_RXCPL_STATUS                0x2010
> +#define RP_RXCPL_EOP                   0x2
> +#define RP_RXCPL_SOP                   0x1
> +#define RP_RXCPL_REG0                  0x2014
> +#define RP_RXCPL_REG1                  0x2018
> +#define P2A_INT_STATUS                 0x3060
> +#define P2A_INT_STS_ALL                        0xF
> +#define P2A_INT_ENABLE                 0x3070
> +#define P2A_INT_ENA_ALL                        0xF
> +#define RP_LTSSM                       0x3C64
> +#define LTSSM_L0                       0xF
> +
> +/* TLP configuration type 0 and 1 */
> +#define TLP_FMTTYPE_CFGRD0             0x04    /* Configuration Read Type 0 */
> +#define TLP_FMTTYPE_CFGWR0             0x44    /* Configuration Write Type 0 */
> +#define TLP_FMTTYPE_CFGRD1             0x05    /* Configuration Read Type 1 */
> +#define TLP_FMTTYPE_CFGWR1             0x45    /* Configuration Write Type 1 */
> +#define TLP_PAYLOAD_SIZE               0x01
> +#define TLP_READ_TAG                   0x1D
> +#define TLP_WRITE_TAG                  0x10
> +#define TLP_CFG_DW0(fmttype)           (((fmttype) << 24) | TLP_PAYLOAD_SIZE)
> +#define TLP_CFG_DW1(reqid, tag)                (((reqid) << 16) | (tag << 8) | 0xF)
> +#define TLP_CFG_DW2(bus, devfn, offset)        \
> +                               (((bus) << 24) | ((devfn) << 16) | (offset))
> +#define TLP_REQ_ID(bus, devfn)         (((bus) << 8) | (devfn))
> +#define TLP_COMPL_STATUS(hdr)          (((hdr) & 0xE0) >> 13)
> +#define TLP_HDR_SIZE                   3
> +#define TLP_LOOP                       10
> +
> +#define INTX_NUM               4
> +
> +/* Address translation table entry size */
> +#define ATT_ENTRY_SIZE         8
> +
> +#define DWORD_MASK             3
> +
> +struct altera_pcie {
> +       struct platform_device  *pdev;
> +       struct resource         *txs;
> +       void __iomem            *cra_base;
> +       int                     irq;
> +       u8                      root_bus_nr;
> +       struct irq_domain               *irq_domain;
> +       struct resource         bus_range;
> +       struct list_head                resources;
> +};
> +
> +struct tlp_rp_regpair_t {
> +       u32 ctrl;
> +       u32 reg0;
> +       u32 reg1;
> +};
> +
> +static void altera_pcie_retrain(struct pci_dev *dev)
> +{
> +       u16 linkcap, linkstat;
> +
> +       /*
> +        * Set the retrain bit if the PCIe rootport support > 2.5GB/s, but
> +        * current speed is 2.5 GB/s.
> +        */
> +       pcie_capability_read_word(dev, PCI_EXP_LNKCAP, &linkcap);
> +
> +       if ((linkcap & PCI_EXP_LNKCAP_SLS) <= PCI_EXP_LNKCAP_SLS_2_5GB)
> +               return;
> +
> +       pcie_capability_read_word(dev, PCI_EXP_LNKSTA, &linkstat);
> +       if ((linkstat & PCI_EXP_LNKSTA_CLS) == PCI_EXP_LNKSTA_CLS_2_5GB)
> +               pcie_capability_set_word(dev, PCI_EXP_LNKCTL,
> +                                        PCI_EXP_LNKCTL_RL);
> +}
> +DECLARE_PCI_FIXUP_EARLY(PCI_ANY_ID, PCI_ANY_ID, altera_pcie_retrain);
> +
> +static inline void cra_writel(struct altera_pcie *pcie, u32 value, u32 reg)
> +{
> +       writel_relaxed(value, pcie->cra_base + reg);
> +}
> +
> +static inline u32 cra_readl(struct altera_pcie *pcie, u32 reg)
> +{
> +       return readl_relaxed(pcie->cra_base + reg);
> +}
> +
> +static void tlp_read_rx(struct altera_pcie *pcie,
> +                       struct tlp_rp_regpair_t *tlp_rp_regdata)
> +{
> +       tlp_rp_regdata->ctrl = cra_readl(pcie, RP_RXCPL_STATUS);
> +       tlp_rp_regdata->reg0 = cra_readl(pcie, RP_RXCPL_REG0);
> +       tlp_rp_regdata->reg1 = cra_readl(pcie, RP_RXCPL_REG1);
> +}
> +
> +static void tlp_write_tx(struct altera_pcie *pcie,
> +                        struct tlp_rp_regpair_t *tlp_rp_regdata)
> +{
> +       cra_writel(pcie, tlp_rp_regdata->reg0, RP_TX_REG0);
> +       cra_writel(pcie, tlp_rp_regdata->reg1, RP_TX_REG1);
> +       cra_writel(pcie, tlp_rp_regdata->ctrl, RP_TX_CNTRL);
> +}
> +
> +static bool altera_pcie_link_is_up(struct altera_pcie *pcie)
> +{
> +       return !!(cra_readl(pcie, RP_LTSSM) & LTSSM_L0);
> +}
> +
> +static bool altera_pcie_valid_config(struct altera_pcie *pcie,
> +                                    struct pci_bus *bus, int dev)
> +{
> +       /* If there is no link, then there is no device */
> +       if (bus->number != pcie->root_bus_nr) {
> +               if (!altera_pcie_link_is_up(pcie))
> +                       return false;
> +       }
> +
> +       /* access only one slot on each root port */
> +       if (bus->number == pcie->root_bus_nr && dev > 0)
> +               return false;
> +
> +       /*
> +        * Do not read more than one device on the bus directly attached
> +        * to RC.
> +        */
> +       if (bus->primary == pcie->root_bus_nr && dev > 0)
> +               return false;
> +
> +        return true;
> +}
> +
> +static int tlp_read_packet(struct altera_pcie *pcie, u32 *value)
> +{
> +       u8 loop;
> +       struct tlp_rp_regpair_t tlp_rp_regdata;
> +
> +       for (loop = TLP_LOOP; loop > 0; loop--) {

I'd prefer to see the more common idiom:

	for (loop = 0; loop < TLP_LOOP; loop++) {

> +               tlp_read_rx(pcie, &tlp_rp_regdata);
> +               if (tlp_rp_regdata.ctrl & RP_RXCPL_EOP) {
> +                       if (value)
> +                               *value = tlp_rp_regdata.reg0;
> +                       return PCIBIOS_SUCCESSFUL;
> +               }

Don't you need some form of relaxation here? A delay of some sort?
Repeatedly polling the HW is usually not helping it to recover...

> +       }
> +
> +       return -ENOENT;
> +}
> +
> +static void tlp_write_packet(struct altera_pcie *pcie, u32 *headers, u32 data)
> +{
> +       struct tlp_rp_regpair_t tlp_rp_regdata;
> +
> +       tlp_rp_regdata.reg0 = headers[0];
> +       tlp_rp_regdata.reg1 = headers[1];
> +       tlp_rp_regdata.ctrl = RP_TX_SOP;
> +       tlp_write_tx(pcie, &tlp_rp_regdata);
> +
> +       tlp_rp_regdata.reg0 = headers[2];
> +       tlp_rp_regdata.reg1 = data;
> +       tlp_rp_regdata.ctrl = RP_TX_EOP;
> +       tlp_write_tx(pcie, &tlp_rp_regdata);
> +}
> +
> +static int tlp_cfg_dword_read(struct altera_pcie *pcie, u8 bus, u32 devfn,
> +                             int where, u32 *value)
> +{
> +       int ret;
> +       u32 headers[TLP_HDR_SIZE];
> +
> +       if (bus == pcie->root_bus_nr)
> +               headers[0] = TLP_CFG_DW0(TLP_FMTTYPE_CFGRD0);
> +       else
> +               headers[0] = TLP_CFG_DW0(TLP_FMTTYPE_CFGRD1);
> +
> +       headers[1] = TLP_CFG_DW1(TLP_REQ_ID(pcie->root_bus_nr, devfn),
> +                                       TLP_READ_TAG);
> +       headers[2] = TLP_CFG_DW2(bus, devfn, where);
> +
> +       tlp_write_packet(pcie, headers, 0);
> +
> +       ret = tlp_read_packet(pcie, value);
> +       if (ret)
> +               *value = ~0UL;  /* return 0xFFFFFFFF if error */
> +
> +       return ret;
> +}
> +
> +static int tlp_cfg_dword_write(struct altera_pcie *pcie, u8 bus, u32 devfn,
> +                              int where, u32 value)
> +{
> +       u32 headers[TLP_HDR_SIZE];
> +
> +       if (bus == pcie->root_bus_nr)
> +               headers[0] = TLP_CFG_DW0(TLP_FMTTYPE_CFGWR0);
> +       else
> +               headers[0] = TLP_CFG_DW0(TLP_FMTTYPE_CFGWR1);
> +
> +       headers[1] = TLP_CFG_DW1(TLP_REQ_ID(pcie->root_bus_nr, devfn),
> +                                       TLP_WRITE_TAG);
> +       headers[2] = TLP_CFG_DW2(bus, devfn, where);
> +
> +       tlp_write_packet(pcie, headers, value);
> +
> +       tlp_read_packet(pcie, NULL);
> +
> +       /* Keep an eye out for changes to the root bus number */
> +       if ((bus == pcie->root_bus_nr) && (where == PCI_PRIMARY_BUS))
> +               pcie->root_bus_nr = (u8)(value);
> +
> +       return PCIBIOS_SUCCESSFUL;
> +}
> +
> +static int altera_pcie_cfg_read(struct pci_bus *bus, unsigned int devfn,
> +                               int where, int size, u32 *value)
> +{
> +       struct altera_pcie *pcie = bus->sysdata;
> +       int ret;
> +
> +       if (!altera_pcie_valid_config(pcie, bus, PCI_SLOT(devfn))) {
> +               *value = ~0UL;
> +               return PCIBIOS_DEVICE_NOT_FOUND;
> +       }
> +
> +       ret = tlp_cfg_dword_read(pcie, bus->number, devfn,
> +                                (where & ~DWORD_MASK), value);
> +       if (ret != PCIBIOS_SUCCESSFUL)
> +               return ret;
> +
> +       if (size == 1)
> +               *value = (*value >> (8 * (where & 0x3))) & 0xff;
> +       else if (size == 2)
> +               *value = (*value >> (8 * (where & 0x2))) & 0xffff;
> +
> +       return PCIBIOS_SUCCESSFUL;
> +}
> +
> +static int altera_pcie_cfg_write(struct pci_bus *bus, unsigned int devfn,
> +                                int where, int size, u32 value)
> +{
> +       struct altera_pcie *pcie = bus->sysdata;
> +       u32 data32 = value;
> +       u32 shift = 8 * (where & 3);
> +       int ret;
> +
> +       if (!altera_pcie_valid_config(pcie, bus, PCI_SLOT(devfn)))
> +               return PCIBIOS_DEVICE_NOT_FOUND;
> +
> +       /* write partial */
> +       if (size != sizeof(u32)) {
> +               ret = tlp_cfg_dword_read(pcie, bus->number, devfn,
> +                                        where & ~DWORD_MASK, &data32);
> +               if (ret)
> +                       return ret;
> +
> +               if (size == 2)
> +                       data32 = (data32 & ~(0xffff << shift)) |
> +                                       ((value & 0xffff) << shift);
> +                else if (size == 1)
> +                       data32 = (data32 & ~(0xff << shift)) |
> +                                       ((value & 0xff) << shift);
> +       }
> +
> +       return tlp_cfg_dword_write(pcie, bus->number, devfn,
> +               (where & ~DWORD_MASK), data32);
> +}
> +
> +static struct pci_ops altera_pcie_ops = {
> +       .read = altera_pcie_cfg_read,
> +       .write = altera_pcie_cfg_write,
> +};
> +
> +static int altera_pcie_intx_map(struct irq_domain *domain, unsigned int irq,
> +                               irq_hw_number_t hwirq)
> +{
> +       irq_set_chip_and_handler(irq, &dummy_irq_chip, handle_simple_irq);
> +       irq_set_chip_data(irq, domain->host_data);
> +       set_irq_flags(irq, IRQF_VALID);
> +
> +       return 0;
> +}
> +
> +static const struct irq_domain_ops intx_domain_ops = {
> +       .map = altera_pcie_intx_map,
> +};
> +
> +static void altera_pcie_isr(unsigned int irq, struct irq_desc *desc)
> +{
> +       struct irq_chip *chip = irq_desc_get_chip(desc);
> +       struct altera_pcie *pcie;
> +       unsigned long status;
> +       u32 bit;
> +       u32 virq;
> +
> +       chained_irq_enter(chip, desc);
> +       pcie = irq_desc_get_handler_data(desc);
> +
> +       do {
> +               status = cra_readl(pcie, P2A_INT_STATUS) & P2A_INT_STS_ALL;
> +               if (!status)
> +                       break;
> +
> +               do {
> +                       bit = find_first_bit(&status, INTX_NUM);
> +                       /* clear interrupts */
> +                       cra_writel(pcie, 1 << bit, P2A_INT_STATUS);
> +
> +                       virq = irq_find_mapping(pcie->irq_domain, bit + 1);
> +                       if (virq)
> +                               generic_handle_irq(virq);
> +                       else
> +                               dev_info(&pcie->pdev->dev, "unexpected IRQ\n");
> +
> +                       /* Clear the bit from status and repeat without reading
> +                        * again status register. */
> +                       __clear_bit(bit, &status);
> +               } while (status);
> +       } while (1);
> +
> +       chained_irq_exit(chip, desc);
> +}
> +
> +static void altera_pcie_release_of_pci_ranges(struct altera_pcie *pcie)
> +{
> +       pci_free_resource_list(&pcie->resources);
> +}
> +
> +static int altera_pcie_parse_request_of_pci_ranges(struct altera_pcie *pcie)
> +{
> +       int err, res_valid = 0;
> +       struct device *dev = &pcie->pdev->dev;
> +       struct device_node *np = dev->of_node;
> +       resource_size_t iobase;
> +       struct resource_entry *win;
> +
> +       err = of_pci_get_host_bridge_resources(np, 0, 0xff, &pcie->resources,
> +                                              &iobase);
> +       if (err)
> +               return err;
> +
> +       resource_list_for_each_entry(win, &pcie->resources) {
> +               struct resource *parent, *res = win->res;
> +
> +               switch (resource_type(res)) {
> +               case IORESOURCE_MEM:
> +                       parent = &iomem_resource;
> +                       res_valid |= !(res->flags & IORESOURCE_PREFETCH);
> +                       break;
> +               default:
> +                       continue;
> +               }
> +
> +               err = devm_request_resource(dev, parent, res);
> +               if (err)
> +                       goto out_release_res;
> +       }
> +
> +       if (!res_valid) {
> +               dev_err(dev, "non-prefetchable memory resource required\n");
> +               err = -EINVAL;
> +               goto out_release_res;
> +       }
> +
> +       return 0;
> +
> +out_release_res:
> +       altera_pcie_release_of_pci_ranges(pcie);
> +       return err;
> +}
> +
> +static void altera_pcie_free_irq_domain(struct altera_pcie *pcie)
> +{
> +       int i;
> +       u32 irq;
> +
> +       for (i = 0; i < INTX_NUM; i++) {
> +               irq = irq_find_mapping(pcie->irq_domain, i);
> +               if (irq > 0)
> +                       irq_dispose_mapping(irq);
> +       }
> +
> +       irq_domain_remove(pcie->irq_domain);
> +}
> +
> +static int altera_pcie_init_irq_domain(struct altera_pcie *pcie)
> +{
> +       struct device *dev = &pcie->pdev->dev;
> +       struct device_node *node = dev->of_node;
> +
> +       /* Setup INTx */
> +       pcie->irq_domain = irq_domain_add_linear(node, INTX_NUM,
> +                                       &intx_domain_ops, pcie);
> +       if (!pcie->irq_domain) {
> +               dev_err(dev, "Failed to get a INTx IRQ domain\n");
> +               return PTR_ERR(pcie->irq_domain);

Err, no. irq_domain_add returns NULL on error, so PTR_ERR(NULL) is still
going to be zero.

> +       }
> +
> +       return 0;
> +}
> +
> +static int altera_pcie_parse_dt(struct altera_pcie *pcie)
> +{
> +       struct resource *cra;
> +       struct platform_device *pdev = pcie->pdev;
> +
> +       cra = platform_get_resource_byname(pdev, IORESOURCE_MEM, "Cra");

Probably worth checking that this hasn't failed.

> +       pcie->cra_base = devm_ioremap_resource(&pdev->dev, cra);
> +       if (IS_ERR(pcie->cra_base)) {
> +               dev_err(&pdev->dev, "get Cra resource failed\n");
> +               return PTR_ERR(pcie->cra_base);
> +       }
> +
> +       /* setup IRQ */
> +       pcie->irq = platform_get_irq(pdev, 0);
> +       if (pcie->irq <= 0) {
> +               dev_err(&pdev->dev, "failed to get IRQ: %d\n", pcie->irq);
> +               return -EINVAL;
> +       }
> +
> +       irq_set_chained_handler_and_data(pcie->irq, altera_pcie_isr, pcie);
> +
> +       return 0;
> +}
> +
> +static int altera_pcie_probe(struct platform_device *pdev)
> +{
> +       struct altera_pcie *pcie;
> +       struct pci_bus *bus;
> +       int ret;
> +
> +       pcie = devm_kzalloc(&pdev->dev, sizeof(*pcie), GFP_KERNEL);
> +       if (!pcie)
> +               return -ENOMEM;
> +
> +       pcie->pdev = pdev;
> +
> +       ret = altera_pcie_parse_dt(pcie);
> +       if (ret) {
> +               dev_err(&pdev->dev, "Parsing DT failed\n");
> +               return ret;
> +       }
> +
> +       INIT_LIST_HEAD(&pcie->resources);
> +
> +       ret = altera_pcie_parse_request_of_pci_ranges(pcie);
> +       if (ret) {
> +               dev_err(&pdev->dev, "Failed add resources\n");
> +               return ret;
> +       }
> +
> +       ret = altera_pcie_init_irq_domain(pcie);
> +       if (ret) {
> +               dev_err(&pdev->dev, "Failed creating IRQ Domain\n");
> +               return ret;
> +       }
> +
> +       pcie->root_bus_nr = 0;
> +
> +       /* clear all interrupts */
> +       cra_writel(pcie, P2A_INT_STS_ALL, P2A_INT_STATUS);
> +       /* enable all interrupts */
> +       cra_writel(pcie, P2A_INT_ENA_ALL, P2A_INT_ENABLE);
> +
> +       bus = pci_scan_root_bus(&pdev->dev, pcie->root_bus_nr, &altera_pcie_ops,
> +                               pcie, &pcie->resources);
> +       if (!bus)
> +               return -ENOMEM;
> +
> +       pci_fixup_irqs(pci_common_swizzle, of_irq_parse_and_map_pci);
> +       pci_assign_unassigned_bus_resources(bus);
> +       pci_bus_add_devices(bus);
> +
> +       platform_set_drvdata(pdev, pcie);
> +       return ret;
> +}
> +
> +static int __exit altera_pcie_remove(struct platform_device *pdev)
> +{
> +       struct altera_pcie *pcie = platform_get_drvdata(pdev);
> +
> +       altera_pcie_free_irq_domain(pcie);
> +       platform_set_drvdata(pdev, NULL);
> +       return 0;
> +}
> +
> +static const struct of_device_id altera_pcie_of_match[] = {
> +       { .compatible = "altr,pcie-root-port-1.0", },
> +       {},
> +};
> +MODULE_DEVICE_TABLE(of, altera_pcie_of_match);
> +
> +static struct platform_driver altera_pcie_driver = {
> +       .probe          = altera_pcie_probe,
> +       .remove         = altera_pcie_remove,
> +       .driver = {
> +               .name   = "altera-pcie",
> +               .of_match_table = altera_pcie_of_match,
> +       },
> +};
> +
> +module_platform_driver(altera_pcie_driver);
> +
> +MODULE_AUTHOR("Ley Foon Tan <lftan at altera.com>");
> +MODULE_DESCRIPTION("Altera PCIe host controller driver");
> +MODULE_LICENSE("GPL v2");
> --
> 1.8.2.1
> 

This is starting to look better. You should get someone to review the DT
parts though.

Thanks,

	M.
-- 
Jazz is not dead. It just smells funny...


From marc.zyngier at arm.com  Fri Aug  7 07:44:24 2015
From: marc.zyngier at arm.com (Marc Zyngier)
Date: Fri, 07 Aug 2015 15:44:24 +0100
Subject: [PATCH v3 3/5] pci: altera: Add Altera PCIe MSI driver
In-Reply-To: <1438933382-2936-4-git-send-email-lftan@altera.com>
References: <1438933382-2936-1-git-send-email-lftan@altera.com>
 <1438933382-2936-4-git-send-email-lftan@altera.com>
Message-ID: <55C4C448.4020102@arm.com>

On 07/08/15 08:43, Ley Foon Tan wrote:
> This patch adds Altera PCIe MSI driver. This soft IP supports configurable
> number of vectors, which is a dts parameter.
> 
> Signed-off-by: Ley Foon Tan <lftan at altera.com>
> ---
>  drivers/pci/host/Kconfig           |   8 +
>  drivers/pci/host/Makefile          |   1 +
>  drivers/pci/host/pcie-altera-msi.c | 309 +++++++++++++++++++++++++++++++++++++
>  3 files changed, 318 insertions(+)
>  create mode 100644 drivers/pci/host/pcie-altera-msi.c
> 
> diff --git a/drivers/pci/host/Kconfig b/drivers/pci/host/Kconfig
> index 4b4754a..d28cc6d 100644
> --- a/drivers/pci/host/Kconfig
> +++ b/drivers/pci/host/Kconfig
> @@ -152,4 +152,12 @@ config PCIE_ALTERA
>           Say Y here if you want to enable PCIe controller support for Altera
>           SoCFPGA family of SoCs.
> 
> +config PCIE_ALTERA_MSI
> +       bool "Altera PCIe MSI feature"
> +       depends on PCI_MSI
> +       select PCI_MSI_IRQ_DOMAIN
> +       help
> +         Say Y here if you want PCIe MSI support for the Altera SocFPGA SoC.
> +         This MSI driver supports Altera MSI to GIC controller IP.
> +
>  endmenu
> diff --git a/drivers/pci/host/Makefile b/drivers/pci/host/Makefile
> index 6954f76..6c4913d 100644
> --- a/drivers/pci/host/Makefile
> +++ b/drivers/pci/host/Makefile
> @@ -18,3 +18,4 @@ obj-$(CONFIG_PCIE_IPROC) += pcie-iproc.o
>  obj-$(CONFIG_PCIE_IPROC_PLATFORM) += pcie-iproc-platform.o
>  obj-$(CONFIG_PCIE_IPROC_BCMA) += pcie-iproc-bcma.o
>  obj-$(CONFIG_PCIE_ALTERA) += pcie-altera.o
> +obj-$(CONFIG_PCIE_ALTERA_MSI) += pcie-altera-msi.o
> diff --git a/drivers/pci/host/pcie-altera-msi.c b/drivers/pci/host/pcie-altera-msi.c
> new file mode 100644
> index 0000000..2d84e62
> --- /dev/null
> +++ b/drivers/pci/host/pcie-altera-msi.c
> @@ -0,0 +1,309 @@
> +/*
> + * Copyright Altera Corporation (C) 2013-2015. All rights reserved
> + *
> + * This program is free software; you can redistribute it and/or modify it
> + * under the terms and conditions of the GNU General Public License,
> + * version 2, as published by the Free Software Foundation.
> + *
> + * This program is distributed in the hope 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.
> + *
> + * You should have received a copy of the GNU General Public License along with
> + * this program.  If not, see <http://www.gnu.org/licenses/>.
> + */
> +#include <linux/interrupt.h>
> +#include <linux/irqchip/chained_irq.h>
> +#include <linux/module.h>
> +#include <linux/msi.h>
> +#include <linux/of_address.h>
> +#include <linux/of_irq.h>
> +#include <linux/of_pci.h>
> +#include <linux/pci.h>
> +#include <linux/platform_device.h>
> +#include <linux/slab.h>
> +
> +#define MSI_STATUS             0x0
> +#define MSI_ERROR              0x4
> +#define MSI_INTMASK            0x8
> +
> +#define MAX_MSI_VECTORS                32
> +struct altera_msi {
> +       DECLARE_BITMAP(used, MAX_MSI_VECTORS);
> +       struct mutex            lock;   /* proctect used variable */
> +       struct platform_device  *pdev;
> +       struct irq_domain               *msi_domain;
> +       struct irq_domain               *inner_domain;
> +       void __iomem            *csr_base;
> +       void __iomem            *vector_base;
> +       phys_addr_t             vector_phy;
> +       u32                     num_of_vectors;
> +       int                     irq;
> +};
> +
> +static inline void msi_writel(struct altera_msi *msi, u32 value, u32 reg)
> +{
> +       writel_relaxed(value, msi->csr_base + reg);
> +}
> +
> +static inline u32 msi_readl(struct altera_msi *msi, u32 reg)
> +{
> +       return readl_relaxed(msi->csr_base + reg);
> +}
> +
> +static void altera_msi_isr(unsigned int irq, struct irq_desc *desc)
> +{
> +       struct irq_chip *chip = irq_desc_get_chip(desc);
> +       struct altera_msi *msi;
> +       unsigned long status;
> +       u32 num_of_vectors;
> +       u32 bit;
> +       u32 virq;
> +
> +       chained_irq_enter(chip, desc);
> +       msi = irq_desc_get_handler_data(desc);
> +       num_of_vectors = msi->num_of_vectors;
> +
> +       do {
> +               status = msi_readl(msi, MSI_STATUS);
> +               if (!status)
> +                       break;
> +
> +               do {
> +                       bit = find_first_bit(&status, num_of_vectors);
> +                       /* Dummy read from vector to clear the interrupt */
> +                       readl_relaxed(msi->vector_base + (bit * sizeof(u32)));
> +
> +                       virq = irq_find_mapping(msi->inner_domain, bit);
> +                       if (virq && test_bit(bit, msi->used))
> +                               generic_handle_irq(virq);
> +                       else
> +                               dev_err(&msi->pdev->dev, "unexpected MSI\n");
> +
> +                       /* Clear the bit from status and repeat without reading
> +                        * again status register. */
> +                       __clear_bit(bit, &status);
> +               } while (status);
> +       } while (1);
> +
> +       chained_irq_exit(chip, desc);
> +}
> +
> +static struct irq_chip altera_msi_irq_chip = {
> +       .name = "Altera PCIe MSI",
> +       .irq_enable = pci_msi_unmask_irq,
> +       .irq_disable = pci_msi_mask_irq,
> +       .irq_mask = pci_msi_mask_irq,
> +       .irq_unmask = pci_msi_unmask_irq,
> +};
> +
> +static struct msi_domain_info altera_msi_domain_info = {
> +       .flags  = (MSI_FLAG_USE_DEF_DOM_OPS | MSI_FLAG_USE_DEF_CHIP_OPS |
> +                    MSI_FLAG_PCI_MSIX),
> +       .chip   = &altera_msi_irq_chip,
> +};
> +
> +static void altera_compose_msi_msg(struct irq_data *data, struct msi_msg *msg)
> +{
> +       struct altera_msi *msi = irq_data_get_irq_chip_data(data);
> +       phys_addr_t addr = msi->vector_phy + (data->hwirq * sizeof(u32));
> +
> +       msg->address_lo = lower_32_bits(addr);
> +       msg->address_hi = upper_32_bits(addr);
> +       msg->data = data->hwirq;
> +
> +       dev_dbg(&msi->pdev->dev, "msi#%d address_lo 0x%x address_hi 0x%x\n",
> +               (int)data->hwirq, msg->address_hi, msg->address_lo);
> +}
> +
> +static int altera_msi_set_affinity(struct irq_data *irq_data,
> +                                  const struct cpumask *mask, bool force)
> +{
> +        return -EINVAL;
> +}
> +
> +static struct irq_chip altera_msi_bottom_irq_chip = {
> +       .name                   = "Altera MSI",
> +       .irq_compose_msi_msg    = altera_compose_msi_msg,
> +       .irq_set_affinity       = altera_msi_set_affinity,
> +};
> +
> +static int altera_irq_domain_alloc(struct irq_domain *domain, unsigned int virq,
> +                                  unsigned int nr_irqs, void *args)
> +{
> +       struct altera_msi *msi = domain->host_data;
> +       unsigned long bit;
> +       u32 mask;
> +

As you cannot support multi-MSI, it would be good to have a
WARN_ON(nr_irqs != 1) here. Just in case...

> +       mutex_lock(&msi->lock);
> +
> +       bit = find_first_zero_bit(msi->used, msi->num_of_vectors);
> +       if (bit >= msi->num_of_vectors)
> +               return -ENOSPC;
> +
> +       set_bit(bit, msi->used);
> +
> +       mutex_unlock(&msi->lock);
> +
> +       irq_domain_set_info(domain, virq, bit, &altera_msi_bottom_irq_chip,
> +                           domain->host_data, handle_simple_irq,
> +                           NULL, NULL);
> +       set_irq_flags(virq, IRQF_VALID);
> +
> +       mask = msi_readl(msi, MSI_INTMASK);
> +       mask |= 1 << bit;
> +       msi_writel(msi, mask, MSI_INTMASK);
> +
> +       return 0;
> +}
> +
> +static void altera_irq_domain_free(struct irq_domain *domain,
> +                                  unsigned int virq, unsigned int nr_irqs)
> +{
> +       struct irq_data *d = irq_domain_get_irq_data(domain, virq);
> +       struct altera_msi *msi = irq_data_get_irq_chip_data(d);
> +       u32 mask;
> +
> +       mutex_lock(&msi->lock);
> +
> +       if (!test_bit(d->hwirq, msi->used)) {
> +               dev_err(&msi->pdev->dev, "trying to free unused MSI#%lu\n",
> +                       d->hwirq);
> +       } else {
> +               __clear_bit(d->hwirq, msi->used);
> +               mask = msi_readl(msi, MSI_INTMASK);
> +               mask &= ~(1 << d->hwirq);
> +               msi_writel(msi, mask, MSI_INTMASK);
> +       }
> +
> +       mutex_unlock(&msi->lock);
> +}
> +
> +static const struct irq_domain_ops msi_domain_ops = {
> +       .alloc  = altera_irq_domain_alloc,
> +       .free   = altera_irq_domain_free,
> +};
> +
> +static int altera_allocate_domains(struct altera_msi *msi)
> +{
> +       msi->inner_domain = irq_domain_add_linear(NULL, msi->num_of_vectors,
> +                                            &msi_domain_ops, msi);
> +       if (!msi->inner_domain) {
> +               dev_err(&msi->pdev->dev, "failed to create IRQ domain\n");
> +               return -ENOMEM;
> +       }
> +
> +       msi->msi_domain = pci_msi_create_irq_domain(msi->pdev->dev.of_node,
> +                               &altera_msi_domain_info, msi->inner_domain);
> +       if (!msi->msi_domain) {
> +               dev_err(&msi->pdev->dev, "failed to create MSI domain\n");
> +               irq_domain_remove(msi->inner_domain);
> +               return -ENOMEM;
> +       }
> +
> +       return 0;
> +}
> +
> +static void altera_free_domains(struct altera_msi *msi)
> +{
> +       irq_domain_remove(msi->msi_domain);
> +       irq_domain_remove(msi->inner_domain);
> +}
> +
> +static int altera_msi_remove(struct platform_device *pdev)
> +{
> +       struct altera_msi *msi = platform_get_drvdata(pdev);
> +
> +       msi_writel(msi, 0, MSI_INTMASK);
> +       irq_set_chained_handler(msi->irq, NULL);
> +       irq_set_handler_data(msi->irq, NULL);
> +
> +       altera_free_domains(msi);
> +
> +       platform_set_drvdata(pdev, NULL);
> +       return 0;
> +}
> +
> +static int altera_msi_probe(struct platform_device *pdev)
> +{
> +       struct altera_msi *msi;
> +       struct device_node *np = pdev->dev.of_node;
> +       struct resource *res;
> +       int ret;
> +
> +       msi = devm_kzalloc(&pdev->dev, sizeof(struct altera_msi),
> +                          GFP_KERNEL);
> +       if (!msi)
> +               return -ENOMEM;
> +
> +       mutex_init(&msi->lock);
> +       msi->pdev = pdev;
> +
> +       res = platform_get_resource_byname(pdev, IORESOURCE_MEM, "csr");

Error checking here.

> +       msi->csr_base = devm_ioremap_resource(&pdev->dev, res);
> +       if (IS_ERR(msi->csr_base)) {
> +               dev_err(&pdev->dev, "get csr resource failed\n");
> +               return PTR_ERR(msi->csr_base);
> +       }
> +
> +       res = platform_get_resource_byname(pdev, IORESOURCE_MEM,
> +                                          "vector_slave");

And here.

> +       msi->vector_base = devm_ioremap_resource(&pdev->dev, res);
> +       if (IS_ERR(msi->vector_base)) {
> +               dev_err(&pdev->dev, "get vector slave resource failed\n");
> +               return PTR_ERR(msi->vector_base);
> +       }
> +
> +       msi->vector_phy = res->start;
> +
> +       if (of_property_read_u32(np, "num-vectors", &msi->num_of_vectors)) {
> +               dev_err(&pdev->dev, "failed to parse the number of vectors\n");
> +               return -EINVAL;
> +       }
> +
> +       ret = altera_allocate_domains(msi);
> +       if (ret)
> +               return ret;
> +
> +       msi->irq = platform_get_irq(pdev, 0);
> +       if (msi->irq <= 0) {
> +               dev_err(&pdev->dev, "failed to map IRQ: %d\n", msi->irq);
> +               ret = -ENODEV;
> +               goto err;
> +       }
> +
> +       irq_set_chained_handler_and_data(msi->irq, altera_msi_isr, msi);
> +       platform_set_drvdata(pdev, msi);
> +
> +       return 0;
> +
> +err:
> +       altera_msi_remove(pdev);
> +       return ret;
> +}
> +
> +static const struct of_device_id altera_msi_of_match[] = {
> +       { .compatible = "altr,msi-1.0", NULL },
> +       { },
> +};
> +
> +static struct platform_driver altera_msi_driver = {
> +       .driver = {
> +               .name = "altera-msi",
> +               .of_match_table = altera_msi_of_match,
> +       },
> +       .probe = altera_msi_probe,
> +       .remove = altera_msi_remove,
> +};
> +
> +static int __init altera_msi_init(void)
> +{
> +       return platform_driver_register(&altera_msi_driver);
> +}
> +
> +subsys_initcall(altera_msi_init);
> +
> +MODULE_AUTHOR("Ley Foon Tan <lftan at altera.com>");
> +MODULE_DESCRIPTION("Altera PCIe MSI support");
> +MODULE_LICENSE("GPL v2");
> --
> 1.8.2.1
> 

Apart from the couple of nits above, this is starting to look good too.
And as for the PCIe driver, you need to get the DT maintainers to review
that part.

Thanks,

	M.
-- 
Jazz is not dead. It just smells funny...


From kishon at ti.com  Fri Aug  7 07:45:02 2015
From: kishon at ti.com (Kishon Vijay Abraham I)
Date: Fri, 7 Aug 2015 20:15:02 +0530
Subject: [PATCH 00/11] omap_hsmmc: voltage switching and tuning
In-Reply-To: <20150806064821.GO16878@atomide.com>
References: <1438242394-25599-1-git-send-email-kishon@ti.com>
 <20150805104355.GE16878@atomide.com> <55C22524.5050304@ti.com>
 <20150806064821.GO16878@atomide.com>
Message-ID: <55C4C46E.9080200@ti.com>

Hi,

On Thursday 06 August 2015 12:18 PM, Tony Lindgren wrote:
> * Kishon Vijay Abraham I <kishon at ti.com> [150805 08:03]:
>> Hi,
>>
>> On Wednesday 05 August 2015 04:13 PM, Tony Lindgren wrote:
>>> * Kishon Vijay Abraham I <kishon at ti.com> [150730 00:49]:
>>>> Patch series implements voltage switching and tuning for omap_hsmmc
>>>> driver.
>>>>
>>>> Did basic read/write test in J6, J6 Eco, Beagle-x15, AM437x EVM,
>>>> Beaglebone black, OMAP5 uEVM and OMAP4 PANDA.
>>>
>>> Your tests are missing omap3?
>>
>> I don't have one at my disposal :-( I'll try to find one and add omap3 tests.
> 
> Great :) Beagle xm is a good one to test the USB PHY stuff on
> and also MMC. Having USB cable connected or EHCI loaded blocks the PM
> though, so NFSroot is not very usable for testing on it.

I found a beagle xm. So I should be able to get back to this early next week.

Thanks
Kishon
> 
> If you want to test PM over NFSroot, boards with the smsc911x known
> to work with PM  are at least omap3-evm-37xx.dts and
> logicpd-torpedo-37xx-devkit.dts.  Since you tinker with the USB PHYs,
> torpedo has MUSB working the same way as the beagle boards, EVM I
> think can be modified that way but by default has diffent PHY.
> 
> Also overo tobi boards work with PM but only for retntion idle and
> not off idle, and map3-sbc-t3517.dts probably can be made to work
> with PM but I have mine as a gateway and have not been able to test
> with it.
> 
> Probably also zoom3 boards with later processor boards can be made
> to work, the LDP has early omap34xx variants and can't be made to
> work reliably.
> 
> I don't have omap3-lilly, but I'd assume that can also be made
> to work with PM if not already working.
> 
>>> I suggest you add some omap3 tests in general as otherwise you are
>>> only testing a subset of the driver features and completely missing
>>> things like rutnime PM and save and restore for the deeper idle
>>> states.
>>
>> yeah, I'll do those tests and re-post the series.
> 
> Thanks!
> 
> Tony
> 


From gg at slimlogic.co.uk  Fri Aug  7 07:54:14 2015
From: gg at slimlogic.co.uk (Graeme Gregory)
Date: Fri, 7 Aug 2015 15:54:14 +0100
Subject: [PATCH 2/2] net, thunder, bgx: Add support for ACPI binding.
In-Reply-To: <1438907590-29649-3-git-send-email-ddaney.cavm@gmail.com>
References: <1438907590-29649-1-git-send-email-ddaney.cavm@gmail.com>
 <1438907590-29649-3-git-send-email-ddaney.cavm@gmail.com>
Message-ID: <20150807145414.GA5468@xora-haswell.xora.org.uk>

On Thu, Aug 06, 2015 at 05:33:10PM -0700, David Daney wrote:
> From: David Daney <david.daney at cavium.com>
> 
> Find out which PHYs belong to which BGX instance in the ACPI way.
> 
> Set the MAC address of the device as provided by ACPI tables. This is
> similar to the implementation for devicetree in
> of_get_mac_address(). The table is searched for the device property
> entries "mac-address", "local-mac-address" and "address" in that
> order. The address is provided in a u64 variable and must contain a
> valid 6 bytes-len mac addr.
> 
> Based on code from: Narinder Dhillon <ndhillon at cavium.com>
>                     Tomasz Nowicki <tomasz.nowicki at linaro.org>
>                     Robert Richter <rrichter at cavium.com>
> 
> Signed-off-by: Tomasz Nowicki <tomasz.nowicki at linaro.org>
> Signed-off-by: Robert Richter <rrichter at cavium.com>
> Signed-off-by: David Daney <david.daney at cavium.com>
> ---
>  drivers/net/ethernet/cavium/thunder/thunder_bgx.c | 137 +++++++++++++++++++++-
>  1 file changed, 135 insertions(+), 2 deletions(-)
> 
> diff --git a/drivers/net/ethernet/cavium/thunder/thunder_bgx.c b/drivers/net/ethernet/cavium/thunder/thunder_bgx.c
> index 615b2af..2056583 100644
> --- a/drivers/net/ethernet/cavium/thunder/thunder_bgx.c
> +++ b/drivers/net/ethernet/cavium/thunder/thunder_bgx.c
> @@ -6,6 +6,7 @@
>   * as published by the Free Software Foundation.
>   */
>  
> +#include <linux/acpi.h>
>  #include <linux/module.h>
>  #include <linux/interrupt.h>
>  #include <linux/pci.h>
> @@ -26,7 +27,7 @@
>  struct lmac {
>  	struct bgx		*bgx;
>  	int			dmac;
> -	unsigned char		mac[ETH_ALEN];
> +	u8			mac[ETH_ALEN];
>  	bool			link_up;
>  	int			lmacid; /* ID within BGX */
>  	int			lmacid_bd; /* ID on board */
> @@ -835,6 +836,133 @@ static void bgx_get_qlm_mode(struct bgx *bgx)
>  	}
>  }
>  
> +#ifdef CONFIG_ACPI
> +
> +static int bgx_match_phy_id(struct device *dev, void *data)
> +{
> +	struct phy_device *phydev = to_phy_device(dev);
> +	u32 *phy_id = data;
> +
> +	if (phydev->addr == *phy_id)
> +		return 1;
> +
> +	return 0;
> +}
> +
> +static const char * const addr_propnames[] = {
> +	"mac-address",
> +	"local-mac-address",
> +	"address",
> +};
> +
> +static int acpi_get_mac_address(struct acpi_device *adev, u8 *dst)
> +{
> +	const union acpi_object *prop;
> +	u64 mac_val;
> +	u8 mac[ETH_ALEN];
> +	int i, j;
> +	int ret;
> +
> +	for (i = 0; i < ARRAY_SIZE(addr_propnames); i++) {
> +		ret = acpi_dev_get_property(adev, addr_propnames[i],
> +					    ACPI_TYPE_INTEGER, &prop);

Shouldn't this be trying to use device_property_read_* API and making
the DT/ACPI path the same where possible?

Graeme

> +		if (ret)
> +			continue;
> +
> +		mac_val = prop->integer.value;
> +
> +		if (mac_val & (~0ULL << 48))
> +			continue;	/* more than 6 bytes */
> +
> +		for (j = 0; j < ARRAY_SIZE(mac); j++)
> +			mac[j] = (u8)(mac_val >> (8 * j));
> +		if (!is_valid_ether_addr(mac))
> +			continue;
> +
> +		memcpy(dst, mac, ETH_ALEN);
> +
> +		return 0;
> +	}
> +
> +	return ret ? ret : -EINVAL;
> +}
> +
> +static acpi_status bgx_acpi_register_phy(acpi_handle handle,
> +					 u32 lvl, void *context, void **rv)
> +{
> +	struct acpi_reference_args args;
> +	const union acpi_object *prop;
> +	struct bgx *bgx = context;
> +	struct acpi_device *adev;
> +	struct device *phy_dev;
> +	u32 phy_id;
> +
> +	if (acpi_bus_get_device(handle, &adev))
> +		goto out;
> +
> +	SET_NETDEV_DEV(&bgx->lmac[bgx->lmac_count].netdev, &bgx->pdev->dev);
> +
> +	acpi_get_mac_address(adev, bgx->lmac[bgx->lmac_count].mac);
> +
> +	bgx->lmac[bgx->lmac_count].lmacid = bgx->lmac_count;
> +
> +	if (acpi_dev_get_property_reference(adev, "phy-handle", 0, &args))
> +		goto out;
> +
> +	if (acpi_dev_get_property(args.adev, "phy-channel", ACPI_TYPE_INTEGER, &prop))
> +		goto out;
> +
> +	phy_id = prop->integer.value;
> +
> +	phy_dev = bus_find_device(&mdio_bus_type, NULL, (void *)&phy_id,
> +				  bgx_match_phy_id);
> +	if (!phy_dev)
> +		goto out;
> +
> +	bgx->lmac[bgx->lmac_count].phydev = to_phy_device(phy_dev);
> +out:
> +	bgx->lmac_count++;
> +	return AE_OK;
> +}
> +
> +static acpi_status bgx_acpi_match_id(acpi_handle handle, u32 lvl,
> +				     void *context, void **ret_val)
> +{
> +	struct acpi_buffer string = { ACPI_ALLOCATE_BUFFER, NULL };
> +	struct bgx *bgx = context;
> +	char bgx_sel[5];
> +
> +	snprintf(bgx_sel, 5, "BGX%d", bgx->bgx_id);
> +	if (ACPI_FAILURE(acpi_get_name(handle, ACPI_SINGLE_NAME, &string))) {
> +		pr_warn("Invalid link device\n");
> +		return AE_OK;
> +	}
> +
> +	if (strncmp(string.pointer, bgx_sel, 4))
> +		return AE_OK;
> +
> +	acpi_walk_namespace(ACPI_TYPE_DEVICE, handle, 1,
> +			    bgx_acpi_register_phy, NULL, bgx, NULL);
> +
> +	kfree(string.pointer);
> +	return AE_CTRL_TERMINATE;
> +}
> +
> +static int bgx_init_acpi_phy(struct bgx *bgx)
> +{
> +	acpi_get_devices(NULL, bgx_acpi_match_id, bgx, (void **)NULL);
> +	return 0;
> +}
> +
> +#else
> +
> +static int bgx_init_acpi_phy(struct bgx *bgx)
> +{
> +	return -ENODEV;
> +}
> +
> +#endif /* CONFIG_ACPI */
> +
>  #if IS_ENABLED(CONFIG_OF_MDIO)
>  
>  static int bgx_init_of_phy(struct bgx *bgx)
> @@ -882,7 +1010,12 @@ static int bgx_init_of_phy(struct bgx *bgx)
>  
>  static int bgx_init_phy(struct bgx *bgx)
>  {
> -	return bgx_init_of_phy(bgx);
> +	int err = bgx_init_of_phy(bgx);
> +
> +	if (err != -ENODEV)
> +		return err;
> +
> +	return bgx_init_acpi_phy(bgx);
>  }
>  
>  static int bgx_probe(struct pci_dev *pdev, const struct pci_device_id *ent)
> -- 
> 1.9.1
> 
> --
> To unsubscribe from this list: send the line "unsubscribe linux-acpi" in
> the body of a message to majordomo at vger.kernel.org
> More majordomo info at  http://vger.kernel.org/majordomo-info.html


From hdegoede at redhat.com  Fri Aug  7 08:22:34 2015
From: hdegoede at redhat.com (Hans de Goede)
Date: Fri,  7 Aug 2015 17:22:34 +0200
Subject: [PATCH 2/3] ARM: dts: sun6i: Turn on gmac on Colombus
In-Reply-To: <1438960955-6551-1-git-send-email-hdegoede@redhat.com>
References: <1438960955-6551-1-git-send-email-hdegoede@redhat.com>
Message-ID: <1438960955-6551-2-git-send-email-hdegoede@redhat.com>

We've everything we need to support the gmac on Colombus, turn it on.

Signed-off-by: Hans de Goede <hdegoede at redhat.com>
---
 arch/arm/boot/dts/sun6i-a31-colombus.dts | 12 ++++++++++++
 1 file changed, 12 insertions(+)

diff --git a/arch/arm/boot/dts/sun6i-a31-colombus.dts b/arch/arm/boot/dts/sun6i-a31-colombus.dts
index 0cf9926..0d0b6f2 100644
--- a/arch/arm/boot/dts/sun6i-a31-colombus.dts
+++ b/arch/arm/boot/dts/sun6i-a31-colombus.dts
@@ -66,6 +66,18 @@
 	status = "okay";
 };
 
+&gmac {
+	pinctrl-names = "default";
+	pinctrl-0 = <&gmac_pins_rgmii_a>;
+	phy = <&phy1>;
+	phy-mode = "rgmii";
+	status = "okay";
+
+	phy1: ethernet-phy at 1 {
+		reg = <1>;
+	};
+};
+
 &i2c0 {
 	pinctrl-names = "default";
 	pinctrl-0 = <&i2c0_pins_a>;
-- 
2.4.3



From hdegoede at redhat.com  Fri Aug  7 08:22:35 2015
From: hdegoede at redhat.com (Hans de Goede)
Date: Fri,  7 Aug 2015 17:22:35 +0200
Subject: [PATCH 3/3] ARM: dts: sun6i: Columbus: Add i2c controller for
 communicating with the LCD
In-Reply-To: <1438960955-6551-1-git-send-email-hdegoede@redhat.com>
References: <1438960955-6551-1-git-send-email-hdegoede@redhat.com>
Message-ID: <1438960955-6551-3-git-send-email-hdegoede@redhat.com>

The Colombus development kit uses an optional 2048x1536 edp panel using
an anx9804 parallel lcd to edp convertor. The anx9804 chip is controlled
via an i2c bus which is connected to 2 regular gpio pins.

Signed-off-by: Hans de Goede <hdegoede at redhat.com>
---
 arch/arm/boot/dts/sun6i-a31-colombus.dts | 17 +++++++++++++++++
 1 file changed, 17 insertions(+)

diff --git a/arch/arm/boot/dts/sun6i-a31-colombus.dts b/arch/arm/boot/dts/sun6i-a31-colombus.dts
index 0d0b6f2..0e51249 100644
--- a/arch/arm/boot/dts/sun6i-a31-colombus.dts
+++ b/arch/arm/boot/dts/sun6i-a31-colombus.dts
@@ -60,6 +60,16 @@
 	chosen {
 		stdout-path = "serial0:115200n8";
 	};
+
+	i2c_lcd: i2c at 0 {
+		/* The lcd panel i2c interface is hooked up via gpios */
+		compatible = "i2c-gpio";
+		pinctrl-names = "default";
+		pinctrl-0 = <&i2c_lcd_pins>;
+		gpios = <&pio 0 23 GPIO_ACTIVE_HIGH>, /* PA23, sda */
+			<&pio 0 24 GPIO_ACTIVE_HIGH>; /* PA24, scl */
+		i2c-gpio,delay-us = <5>;
+	};
 };
 
 &ehci1 {
@@ -124,6 +134,13 @@
 		allwinner,drive = <SUN4I_PINCTRL_10_MA>;
 		allwinner,pull = <SUN4I_PINCTRL_NO_PULL>;
 	};
+
+	i2c_lcd_pins: i2c_lcd_pin at 0 {
+		allwinner,pins = "PA23", "PA24";
+		allwinner,function = "gpio_out";
+		allwinner,drive = <SUN4I_PINCTRL_10_MA>;
+		allwinner,pull = <SUN4I_PINCTRL_PULL_UP>;
+	};
 };
 
 &reg_usb2_vbus {
-- 
2.4.3



From hdegoede at redhat.com  Fri Aug  7 08:22:33 2015
From: hdegoede at redhat.com (Hans de Goede)
Date: Fri,  7 Aug 2015 17:22:33 +0200
Subject: [PATCH 1/3] ARM: dts: sun5i: Add support for the Auxtek-T003 HDMI
 stick
Message-ID: <1438960955-6551-1-git-send-email-hdegoede@redhat.com>

The Auxtek-T003 HDMI stick is an A10s based HDMI stick with USB wifi,
and composite video out support.

Signed-off-by: Hans de Goede <hdegoede at redhat.com>
---
 arch/arm/boot/dts/Makefile                   |   1 +
 arch/arm/boot/dts/sun5i-a10s-auxtek-t003.dts | 159 +++++++++++++++++++++++++++
 2 files changed, 160 insertions(+)
 create mode 100644 arch/arm/boot/dts/sun5i-a10s-auxtek-t003.dts

diff --git a/arch/arm/boot/dts/Makefile b/arch/arm/boot/dts/Makefile
index 151a413..95daf91 100644
--- a/arch/arm/boot/dts/Makefile
+++ b/arch/arm/boot/dts/Makefile
@@ -563,6 +563,7 @@ dtb-$(CONFIG_MACH_SUN4I) += \
 	sun4i-a10-olinuxino-lime.dtb \
 	sun4i-a10-pcduino.dtb
 dtb-$(CONFIG_MACH_SUN5I) += \
+	sun5i-a10s-auxtek-t003.dtb \
 	sun5i-a10s-auxtek-t004.dtb \
 	sun5i-a10s-mk802.dtb \
 	sun5i-a10s-olinuxino-micro.dtb \
diff --git a/arch/arm/boot/dts/sun5i-a10s-auxtek-t003.dts b/arch/arm/boot/dts/sun5i-a10s-auxtek-t003.dts
new file mode 100644
index 0000000..d4ad021
--- /dev/null
+++ b/arch/arm/boot/dts/sun5i-a10s-auxtek-t003.dts
@@ -0,0 +1,159 @@
+/*
+ * Copyright 2015 Hans de Goede <hdegoede at redhat.com>
+ *
+ * This file is dual-licensed: you can use it either under the terms
+ * of the GPL or the X11 license, at your option. Note that this dual
+ * licensing only applies to this file, and not this project as a
+ * whole.
+ *
+ *  a) This file is free software; you can redistribute it and/or
+ *     modify it under the terms of the GNU General Public License as
+ *     published by the Free Software Foundation; either version 2 of the
+ *     License, or (at your option) any later version.
+ *
+ *     This file is distributed in the hope that it will be useful,
+ *     but WITHOUT ANY WARRANTY; without even the implied warranty of
+ *     MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ *     GNU General Public License for more details.
+ *
+ * Or, alternatively,
+ *
+ *  b) Permission is hereby granted, free of charge, to any person
+ *     obtaining a copy of this software and associated documentation
+ *     files (the "Software"), to deal in the Software without
+ *     restriction, including without limitation the rights to use,
+ *     copy, modify, merge, publish, distribute, sublicense, and/or
+ *     sell copies of the Software, and to permit persons to whom the
+ *     Software is furnished to do so, subject to the following
+ *     conditions:
+ *
+ *     The above copyright notice and this permission notice shall be
+ *     included in all copies or substantial portions of the Software.
+ *
+ *     THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
+ *     EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES
+ *     OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
+ *     NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT
+ *     HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY,
+ *     WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
+ *     FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR
+ *     OTHER DEALINGS IN THE SOFTWARE.
+ */
+
+/dts-v1/;
+#include "sun5i-a10s.dtsi"
+#include "sunxi-common-regulators.dtsi"
+#include <dt-bindings/gpio/gpio.h>
+#include <dt-bindings/pinctrl/sun4i-a10.h>
+
+/ {
+	model = "Auxtek t003 A10s hdmi tv-stick";
+	compatible = "allwinner,auxtek-t003", "allwinner,sun5i-a10s";
+
+	aliases {
+		serial0 = &uart0;
+	};
+
+	chosen {
+		stdout-path = "serial0:115200n8";
+	};
+
+	leds {
+		compatible = "gpio-leds";
+		pinctrl-names = "default";
+		pinctrl-0 = <&led_pins_t003>;
+
+		red {
+			label = "t003-tv-dongle:red:usr";
+			gpios = <&pio 1 2 GPIO_ACTIVE_HIGH>; /* PB2 */
+			default-state = "on";
+		};
+	};
+};
+
+&ehci0 {
+	status = "okay";
+};
+
+&i2c0 {
+	pinctrl-names = "default";
+	pinctrl-0 = <&i2c0_pins_a>;
+	status = "okay";
+
+	axp152: pmic at 30 {
+		compatible = "x-powers,axp152";
+		reg = <0x30>;
+		interrupts = <0>;
+		interrupt-controller;
+		#interrupt-cells = <1>;
+	};
+};
+
+&mmc0 {
+	pinctrl-names = "default";
+	pinctrl-0 = <&mmc0_pins_a>, <&mmc0_cd_pin_t003>;
+	vmmc-supply = <&reg_vcc3v3>;
+	bus-width = <4>;
+	cd-gpios = <&pio 6 1 GPIO_ACTIVE_HIGH>; /* PG1 */
+	cd-inverted;
+	status = "okay";
+};
+
+&ohci0 {
+	status = "okay";
+};
+
+&otg_sram {
+	status = "okay";
+};
+
+&pio {
+	mmc0_cd_pin_t003: mmc0_cd_pin at 0 {
+		allwinner,pins = "PG1";
+		allwinner,function = "gpio_in";
+		allwinner,drive = <SUN4I_PINCTRL_10_MA>;
+		allwinner,pull = <SUN4I_PINCTRL_PULL_UP>;
+	};
+
+	led_pins_t003: led_pins at 0 {
+		allwinner,pins = "PB2";
+		allwinner,function = "gpio_out";
+		allwinner,drive = <SUN4I_PINCTRL_20_MA>;
+		allwinner,pull = <SUN4I_PINCTRL_NO_PULL>;
+	};
+};
+
+&reg_usb0_vbus {
+	gpio = <&pio 6 13 GPIO_ACTIVE_HIGH>; /* PG13 */
+	status = "okay";
+};
+
+&reg_usb1_vbus {
+	gpio = <&pio 1 10 GPIO_ACTIVE_HIGH>; /* PB10 */
+	status = "okay";
+};
+
+&uart0 {
+	pinctrl-names = "default";
+	pinctrl-0 = <&uart0_pins_a>;
+	status = "okay";
+};
+
+&usb0_vbus_pin_a {
+	allwinner,pins = "PG13";
+};
+
+&usb1_vbus_pin_a {
+	allwinner,pins = "PB10";
+};
+
+&usb_otg {
+	dr_mode = "host";
+	status = "okay";
+};
+
+&usbphy {
+	usb0_vbus-supply = <&reg_usb0_vbus>;
+	usb1_vbus-supply = <&reg_usb1_vbus>;
+	status = "okay";
+};
-- 
2.4.3



From robin.murphy at arm.com  Fri Aug  7 08:27:56 2015
From: robin.murphy at arm.com (Robin Murphy)
Date: Fri, 07 Aug 2015 16:27:56 +0100
Subject: [PATCH v5 2/3] arm64: Add IOMMU dma_ops
In-Reply-To: <20150807085233.GV14980@8bytes.org>
References: <cover.1438362603.git.robin.murphy@arm.com>
 <8a5abd0a9929aae160ccb74d7a8d9c3698f61910.1438362603.git.robin.murphy@arm.com>
 <20150807085233.GV14980@8bytes.org>
Message-ID: <55C4CE7C.7050205@arm.com>

On 07/08/15 09:52, Joerg Roedel wrote:
> On Fri, Jul 31, 2015 at 06:18:28PM +0100, Robin Murphy wrote:
>> +/*
>> + * TODO: Right now __iommu_setup_dma_ops() gets called too early to do
>> + * everything it needs to - the device isn't yet fully created, and the
>> + * IOMMU driver hasn't seen it yet, so we need this delayed attachment
>> + * dance. Once IOMMU probe ordering is sorted to move the
>> + * arch_setup_dma_ops() call later, all the notifier bits below become
>> + * unnecessary, and will go away.
>> + */
>> +struct iommu_dma_notifier_data {
>> +	struct list_head list;
>> +	struct device *dev;
>> +	struct iommu_domain *dma_domain;
>> +};
>> +static LIST_HEAD(iommu_dma_masters);
>> +static DEFINE_MUTEX(iommu_dma_notifier_lock);
>
> Ugh, thats incredibly ugly. Why can't you do the setup work then the
> iommu driver sees the device? Just call the dma-api setup functions
> there (like the x86 iommu drivers do it too) and be done without any
> notifiers.

As per the comments, the issue here lies in the order in which the 
OF/driver core code currently calls things for platform devices: as it 
stands we can't attach the device to a domain in arch_setup_dma_ops() 
because it doesn't have a group, and we can't even add it to a group 
ourselves because it isn't fully created and doesn't exist in sysfs yet. 
The only reason arch/arm is currently getting away without this 
workaround is that the few IOMMU drivers there hooked up to the generic 
infrastructure don't actually mind that they get an attach_device from 
arch_setup_dma_ops() before they've even seen an add_device (largely 
because they don't care about groups).

Laurent's probe-deferral series largely solves these problems in the 
right place - adding identical boilerplate code to every IOMMU driver to 
do something they shouldn't have to know about (and don't necessarily 
have all the right information for) is exactly what we don't want to do. 
As discussed over on another thread, I'm planning to pick that series up 
and polish it off after this, but my top priority is getting the basic 
dma_ops functionality into arm64 that people need right now. I will be 
only too happy when I can submit the patch removing this notifier 
workaround ;)

>> +static void __iommu_setup_dma_ops(struct device *dev, u64 dma_base, u64 size,
>> +				  const struct iommu_ops *ops)
>> +{
>> +	struct iommu_domain *domain;
>> +	int err;
>> +
>> +	if (!ops)
>> +		return;
>> +	/*
>> +	 * In a perfect world, everything happened in the right order up to
>> +	 * here, and the IOMMU core has already attached the device to an
>> +	 * appropriate default domain for us to set up...
>> +	 */
>> +	domain = iommu_get_domain_for_dev(dev);
>> +	if (!domain) {
>> +		/*
>> +		 * Urgh. Reliable default domains for platform devices can't
>> +		 * happen anyway without some sensible way of handling
>> +		 * non-trivial groups. So until then, HORRIBLE HACKS!
>> +		 */
>
> I don't get this, what is preventing to rely on default domains here?

No driver other than the AMD IOMMU has any support yet. Support for 
IOMMU_DOMAIN_DMA can easily be added to existing drivers based on patch 
1 of this series, but more generally it's not entirely clear how default 
domains are going to work beyond x86. On systems like Juno or Seattle 
with different sets of masters behind different IOMMU instances (with 
limited domain contexts each), the most sensible approach would be to 
have a single default domain per IOMMU (spanning domains across 
instances would need some hideous synchronisation logic for some 
implementations), but the current domain_alloc interface gives us no way 
to do that. On something like RK3288 with two different types of IOMMU 
on the platform "bus", it breaks down even further as there's no way to 
guarantee that iommu_domain_alloc() even gives you a domain from the 
right *driver* (hence bypassing it by going through ops directly here).

>
>> +		domain = ops->domain_alloc(IOMMU_DOMAIN_DMA);
>
> The IOMMU core should already tried to allocate an IOMMU_DOMAIN_DMA type
> domain. No need to try this again here.

Only for PCI devices, via iommu_group_get_for_pci_dev(). The code here, 
however, only runs for platform devices - ops will be always null for a 
PCI device since of_iommu_configure() will have bailed out (see the 
silly warning removed by my patch you picked up the other day). Once 
iommu_group_get_for_dev() supports platform devices, this too can go 
away. In the meantime if someone adds PCI support to 
of_iommu_configure() and IOMMU_DOMAIN_DMA support to their IOMMU driver, 
then we'll get a domain back from iommu_get_domain_for_dev() and just 
use that.

Robin.



From peter at hurleysoftware.com  Fri Aug  7 08:30:27 2015
From: peter at hurleysoftware.com (Peter Hurley)
Date: Fri, 07 Aug 2015 11:30:27 -0400
Subject: [PATCH v4 2/2] serial: mxs-auart: keep the AUART unit in reset
 state when not in use
In-Reply-To: <1438944424-9053-2-git-send-email-jbe@pengutronix.de>
References: <1438944424-9053-1-git-send-email-jbe@pengutronix.de>
 <1438944424-9053-2-git-send-email-jbe@pengutronix.de>
Message-ID: <55C4CF13.90206@hurleysoftware.com>

On 08/07/2015 06:47 AM, Juergen Borleis wrote:
> Whenever the UART device driver gets closed from userland, the driver
> disables the UART unit and then stops the clocks to save power.
> 
> The bit which disabled the UART unit is described as:
> 
>  "UART Enable. If this bit is set to 1, the UART is enabled. Data
>   transmission and reception occurs for the UART signals. When the
>   UART is disabled in the middle of transmission or reception, it
>   completes the current character before stopping."
> 
> The important part is the "it completes the current character". Whenever
> a reception is ongoing when the UART gets disabled (including the clock
> off) the statemachine freezes and "remembers" this state on the next
> open() when re-enabling the unit's clock.
> 
> In this case we end up receiving an additional bogus character
> immediately.
> 
> The solution in this change is to switch the AUART unit into its reset
> state on close() and only release it from its reset state on the next
> open().
> 
> Note: when the unit is also used as system console it is always 'in use',
> so we cannot reset it on close().

The code is still a bit ackward but looks functional, so

Reviewed-by: Peter Hurley <peter at hurleysoftware.com>


PS - This mxs driver has the same problem as the i.MX driver.
     The irq request and hardware init should be done in startup().



From manabian at gmail.com  Fri Aug  7 08:44:01 2015
From: manabian at gmail.com (Joachim Eastwood)
Date: Fri, 7 Aug 2015 17:44:01 +0200
Subject: [PATCH 2/2] DT: pwm: Add NXP LPC18xx PWM/SCT binding documentation
In-Reply-To: <CAAEAJfBjr2wxn-x1RiEj+ezoHA0aWNqCFfpYLM3RzhTrnHDyWw@mail.gmail.com>
References: <1437972345-16444-1-git-send-email-ariel@vanguardiasur.com.ar>
 <1437972345-16444-3-git-send-email-ariel@vanguardiasur.com.ar>
 <CAGhQ9Vyy+oUAWm0q2+NV0D9RVf5qyED8Tn54-cGzbDc-EZR4yw@mail.gmail.com>
 <CAAEAJfApE8=cAue-bc5xPD_XAtV8qzur12C4okF-uLJ-__reBA@mail.gmail.com>
 <CAGhQ9VwudkK=bo5Qk79O7fmdEEm1KEWxUhLO14ucCJ+FbhqQqw@mail.gmail.com>
 <CAAEAJfA22JA0AWB1FCiDVYEy5BqasDror_Ejpd=b3s14BWpORw@mail.gmail.com>
 <CAGhQ9VyCNrH_J6rP+L+6OkV-PCgemOzhznuFRg07YxPpLX_nig@mail.gmail.com>
 <CAAEAJfBjr2wxn-x1RiEj+ezoHA0aWNqCFfpYLM3RzhTrnHDyWw@mail.gmail.com>
Message-ID: <CAGhQ9VyGYro=PZgj7cu+vP3QCZapL8cxYX-Zxp4+ZS9AtxznFw@mail.gmail.com>

On 31 July 2015 at 20:09, Ezequiel Garcia <ezequiel at vanguardiasur.com.ar> wrote:
> Joachim,
>
> On 30 July 2015 at 20:30, Joachim  Eastwood <manabian at gmail.com> wrote:
>> On 29 July 2015 at 15:47, Ezequiel Garcia <ezequiel at vanguardiasur.com.ar> wrote:
>>> +devicetree guys
>>>
>>> On 28 July 2015 at 20:22, Joachim  Eastwood <manabian at gmail.com> wrote:
>>>> On 29 July 2015 at 00:45, Ezequiel Garcia <ezequiel at vanguardiasur.com.ar> wrote:
>>>>> On 28 July 2015 at 19:37, Joachim  Eastwood <manabian at gmail.com> wrote:
>>>>>> On 27 July 2015 at 06:45, Ariel D'Alessandro <ariel at vanguardiasur.com.ar> wrote:
>>>>>>> Add the devicetree binding document for NXP LPC18xx PWM/SCT.
>>>>>>>
>>>>>>> Signed-off-by: Ariel D'Alessandro <ariel at vanguardiasur.com.ar>
>>>>>>> ---
>>>>>>>  .../devicetree/bindings/pwm/lpc1850-pwm.txt          | 20 ++++++++++++++++++++
>>>>>>>  1 file changed, 20 insertions(+)
>>>>>>>  create mode 100644 Documentation/devicetree/bindings/pwm/lpc1850-pwm.txt
>>>>>>>
>>>>>>> diff --git a/Documentation/devicetree/bindings/pwm/lpc1850-pwm.txt b/Documentation/devicetree/bindings/pwm/lpc1850-pwm.txt
>>>>>>> new file mode 100644
>>>>>>> index 0000000..3055429
>>>>>>> --- /dev/null
>>>>>>> +++ b/Documentation/devicetree/bindings/pwm/lpc1850-pwm.txt
>>>>>>> @@ -0,0 +1,20 @@
>>>>>>> +* NXP LPC18xx Pulse Width Modulator driver
>>>>>>> +
>>>>>>> +Required properties:
>>>>>>> +  - compatible: Should be "nxp,lpc1850-pwm"
>>>>>>> +  - reg: Should contain physical base address and length of pwm registers.
>>>>>>> +  - clocks: Must contain an entry for each entry in clock-names.
>>>>>>> +    See ../clock/clock-bindings.txt for details.
>>>>>>> +  - clock-names: Must include the following entries.
>>>>>>> +    - pwm: PWM operating clock.
>>>>>>> +  - #pwm-cells: Should be 3. See pwm.txt in this directory for the description
>>>>>>> +    of the cells format.
>>>>>>> +
>>>>>>> +Example:
>>>>>>> +  pwm: pwm at 40000000 {
>>>>>>> +    compatible = "nxp,lpc1850-pwm";
>>>>>>
>>>>>> I would prefer "nxp,lpc1850-sct" for a couple of reasons. SCT is the
>>>>>> name of hardware block as described in the user manual and while PWM
>>>>>> is the most obvious usage for this block on Linux, the hardware is not
>>>>>> limited to just doing that. So as a bit of future proofing if someone
>>>>>> wants to use this block for more than PWM I would prefer SCT.
>>>>>>
>>>>>
>>>>> Shouldn't we use something like "nxp,lpc1850-sct-pwm"?
>>>>>
>>>>> Sounds like the word PWM should be in the compatible as it describes
>>>>> not only the device, but the device used in a certain way.
>>>>>
>>>>> Otherwise, how would we use "nxp,lpc1850-sct" to distinguish a PWM from
>>>>> e.g. a clocksource/clockevents (we can also use SCT for that)?
>>>>
>>>> I not sure how to best handle dt bindings with such flexible hardware blocks.
>>>>
>>>> But are you suggestion to have multiple drivers for the same hw block?
>>>> ie.: "nxp,lpc1850-sct-pwm" for PWM and for example
>>>> "nxp,lpc1850-sct-clocksource" for clocksource and then use/enable one
>>>> or the other.
>>>>
>>>
>>> Yup, I'm suggesting just that. If the hardware is capable, I can't see
>>> why we can't have different drivers for it.
>>
>> Well, I think it would be nice if we could have one driver per hw
>> block. But then you need a way to select whether you want to use the
>> counter in the SCT block for PWM or, for example, clocksource. Sort of
>> mode selection I guess.
>>
>> But then again if someone has some very custom and application
>> specific usage for the SCT block that maybe better served by a
>> standalone driver anyway.
>>
>
> Technically speaking, I believe we can use "nxp,lpc1850-sct" to expose
> both a PWM interface and a clocksource in a single driver. Not too
> clean, though.

Well, I don't think that is unclean way of doing it. But it's up to
the different subsystem maintainers if they want users outside their
normal directory as we would, for example, end of with a clocksource
under the pwm dir.

> Alternatively, we should be able to have a multifunction device (MFD) to mux
> the SCT resources to be consumed by different kind of drivers.

That is an other way of doing it.

But you would still need to a way to chose between either PWM or
clocksource since the SCT has a limited number of counters. (SCT can
be configured to have either two 16-bit timers or one 32-bit)

> Given there's no counter API to feed SCT, and given we use the other
> timer hw block to feed clocksource and clockevents for the LPC18/43xx,
> I think currently the simplest choice is to have "nxp,lpc1850-sct-pwm"
> describing this PWM SCT driver.
>
> If we later want to change completely the PWM SCT driver, we can do
> that without any bindings change.

Agreed. Let's keep it simple now and deal with it again if another
user for the SCT block turns up.


regards,
Joachim Eastwood


From alexandre.belloni at free-electrons.com  Fri Aug  7 08:45:44 2015
From: alexandre.belloni at free-electrons.com (Alexandre Belloni)
Date: Fri, 7 Aug 2015 17:45:44 +0200
Subject: [GIT PULL] at91: dt for 4.3 #2
Message-ID: <20150807154544.GA18934@piout.net>


Arnd, Olof, Kevin,

This is the second batch of DT changes for 4.3.
It is mainly some preparation to support properly getting the slow clock
from each driver so that the dtsis are ready when the driver change
lands in each subsystem.

It also adds support for the lcd controller on at91sam9x5 and
at91sam9n12. The driver changes have been submitted but didn't yet land
in the drm and mfd subsystem however, I don't expect any issue getting
those in.

Thanks, best regards,

The following changes since commit 22b5a0f7bc07ac4b4e4aab9a7f8cf2521819c1c4:

  ARM: at91/dt: add minimal sama5d2 Xplained board (2015-07-30 18:44:44 +0200)

are available in the git repository at:

  git://git.kernel.org/pub/scm/linux/kernel/git/abelloni/linux.git tags/at91-ab-dt2

for you to fetch changes up to 761c5867ef031fae244d030bc17c93f5a3df106f:

  ARM: at91/dt: sama5d2: use slow clock where necessary (2015-08-07 17:33:54 +0200)

----------------------------------------------------------------
Second batch of DT changes for 4.3:
- Add the slow clock to the nodes that will use it
- Add hlcd to the at91sam9x5 and at91sam9n12
- Add touchscreen and touch button support to the at91sam9x5ek

----------------------------------------------------------------
Alexandre Belloni (15):
      Documentation: dt: atmel-at91: add clocks to system timer, rstc and shdwc
      Documentation: watchdog: at91sam9_wdt: add clocks property
      Documentation: dt: rtc: at91rm9200: add clocks property
      ARM: at91/dt: at91rm9200: use slow clock where necessary
      ARM: at91/dt: at91sam9260: use slow clock where necessary
      ARM: at91/dt: at91sam9261: use slow clock where necessary
      ARM: at91/dt: at91sam9263: use slow clock where necessary
      ARM: at91/dt: at91sam9g45: use slow clock where necessary
      ARM: at91/dt: at91sam9n12: use slow clock where necessary
      ARM: at91/dt: at91sam9rl: use slow clock where necessary
      ARM: at91/dt: at91sam9x5: use slow clock where necessary
      ARM: at91/dt: sama5d3: use slow clock where necessary
      ARM: at91/dt: sama5d4: use slow clock where necessary
      ARM: at91/dt: at91sam9x5dm: add support for the touschscreen
      ARM: at91/dt: sama5d2: use slow clock where necessary

Bo Shen (1):
      ARM: at91/dt: add drm support for at91sam9n12ek

Boris Brezillon (5):
      Documentation: dt: atmel-at91: add slow clock to tcb
      ARM: at91/dt: define hlcdc node in at91sam9x5_lcd.dtsi
      ARM: at91/dt: include lcd dtsi in at91sam9x5 dtsis
      ARM: at91/dt: add at91sam9x5-ek Display Module dtsi
      ARM: at91/dt: enable lcd support for at91sam9x5 SoCs

Nicolas Ferre (1):
      ARM: at91/dt: at91sam9x5dm: add QT1070 touch button controller

 .../devicetree/bindings/arm/atmel-at91.txt         |  13 +-
 .../bindings/rtc/atmel,at91rm9200-rtc.txt          |   2 +
 .../devicetree/bindings/watchdog/atmel-wdt.txt     |   2 +
 arch/arm/boot/dts/at91rm9200.dtsi                  |  10 +-
 arch/arm/boot/dts/at91sam9260.dtsi                 |  11 +-
 arch/arm/boot/dts/at91sam9261.dtsi                 |   7 +-
 arch/arm/boot/dts/at91sam9263.dtsi                 |   7 +-
 arch/arm/boot/dts/at91sam9g15.dtsi                 |   1 +
 arch/arm/boot/dts/at91sam9g15ek.dts                |  25 ++++
 arch/arm/boot/dts/at91sam9g35.dtsi                 |   1 +
 arch/arm/boot/dts/at91sam9g35ek.dts                |  21 ++++
 arch/arm/boot/dts/at91sam9g45.dtsi                 |  12 +-
 arch/arm/boot/dts/at91sam9n12.dtsi                 |  83 +++++++++++-
 arch/arm/boot/dts/at91sam9n12ek.dts                |  61 +++++++++
 arch/arm/boot/dts/at91sam9rl.dtsi                  |   8 +-
 arch/arm/boot/dts/at91sam9x35.dtsi                 |   1 +
 arch/arm/boot/dts/at91sam9x35ek.dts                |  20 +++
 arch/arm/boot/dts/at91sam9x5.dtsi                  |  12 +-
 arch/arm/boot/dts/at91sam9x5_lcd.dtsi              | 139 +++++++++++++++++++++
 arch/arm/boot/dts/at91sam9x5dm.dtsi                | 101 +++++++++++++++
 arch/arm/boot/dts/sama5d2.dtsi                     |   9 +-
 arch/arm/boot/dts/sama5d3.dtsi                     |   8 +-
 arch/arm/boot/dts/sama5d3_tcb1.dtsi                |   4 +-
 arch/arm/boot/dts/sama5d4.dtsi                     |  12 +-
 24 files changed, 528 insertions(+), 42 deletions(-)
 create mode 100644 arch/arm/boot/dts/at91sam9x5dm.dtsi

-- 
Alexandre Belloni, Free Electrons
Embedded Linux, Kernel and Android engineering
http://free-electrons.com


From marc.zyngier at arm.com  Fri Aug  7 08:45:36 2015
From: marc.zyngier at arm.com (Marc Zyngier)
Date: Fri,  7 Aug 2015 16:45:36 +0100
Subject: [PATCH v4 00/11] arm/arm64: KVM: Active interrupt state switching for
 shared devices
Message-ID: <1438962347-17541-1-git-send-email-marc.zyngier@arm.com>

>From day 1, our timer code has been using a terrible hack: whenever
the guest is scheduled with a timer interrupt pending (i.e. the HW
timer has expired), we restore the timer state with the MASK bit set,
in order to avoid the physical interrupt to fire again. And again. And
again...

This is absolutely silly, for at least two reasons:

- This relies on the device (the timer) having a mask bit that we can
  play with. Not all devices are built like this.

- This expects some behaviour of the guest that only works because the
  both the kernel timer code and the KVM counterpart have been written
  by the same idiot (the idiot being me).

The One True Way is to set the GIC active bit when injecting the
interrupt, and to context-switch across the world switch. This is what
this series implements.

We introduce a relatively simple infrastructure enabling the mapping
of a virtual interrupt with its physical counterpart:

- Whenever an virtual interrupt is injected, we look it up in an
  rbtree. If we have a match, the interrupt is injected with the HW
  bit set in the LR, together with the physical interrupt.

- Across the world switch, we save/restore the active state for these
  interrupts using the irqchip_state API.

- On guest EOI, the HW interrupt is automagically deactivated by the
  GIC, allowing the interrupt to be resampled.

The timer code is slightly modified to set the active state at the
same time as the injection.

The last patch also allows non-shared devices to have their interrupt
deactivated the same way (in this case we do not context-switch the
active state). This is the first step in the long overdue direction of
the mythical IRQ forwarding thing... This last patch is not a
candidate for merging, but is included for completeness, and to allow
Eric to base his own code on this stuff.

This series is based on v4.2-rc2 + the current queue for 4.3, and has
been tested on Juno, Cubietruck (GICv2) and the FVP Base model (GICv3
host, both GICv2 and GICv3 guests). I'd appreciate any form of
testing, specially in the context of guest migration (there is
obviously some interesting stuff there...).

The code is otherwise available at
git://git.kernel.org/pub/scm/linux/kernel/git/maz/arm-platforms.git kvm-arm64/active-timer-next

* From v3:
  - Fixed RCU thinko
  - Some more documentation
  - Added RBs from Christoffer

* From v2:
  - Many comments added
  - Fixed potential race between unmap and destroy
  - Removed the requirement for a GFP_ATOMIC allocations in map
  - New function names for the exported functions (map, unmap, get, set, init)
  - New patch preventing the injection of a HW mapped interrupt, and
    offer a new injection API

* From v1:
  - Rebased on top of current mainline
  - Fixed non-shared handling of forwarded interrupts
  - Fixed memory leaks on VM exit
  - Used RCU lists instead of an RB tree

Marc Zyngier (11):
  arm/arm64: KVM: Fix ordering of timer/GIC on guest entry
  arm/arm64: KVM: Move vgic handling to a non-preemptible section
  KVM: arm/arm64: vgic: Convert struct vgic_lr to use bitfields
  KVM: arm/arm64: vgic: Allow HW irq to be encoded in LR
  KVM: arm/arm64: vgic: Relax vgic_can_sample_irq for edge IRQs
  KVM: arm/arm64: vgic: Allow dynamic mapping of physical/virtual
    interrupts
  KVM: arm/arm64: vgic: Allow HW interrupts to be queued to a guest
  KVM: arm/arm64: vgic: Add vgic_{get,set}_phys_irq_active
  KVM: arm/arm64: vgic: Prevent userspace injection of a mapped
    interrupt
  KVM: arm/arm64: timer: Allow the timer to control the active state
  KVM: arm/arm64: vgic: Allow HW interrupts for non-shared devices

 arch/arm/kvm/arm.c                 |  21 +-
 arch/arm/kvm/reset.c               |   4 +-
 arch/arm64/kvm/reset.c             |   4 +-
 include/kvm/arm_arch_timer.h       |   7 +-
 include/kvm/arm_vgic.h             |  41 +++-
 include/linux/irqchip/arm-gic-v3.h |   3 +
 include/linux/irqchip/arm-gic.h    |   3 +-
 virt/kvm/arm/arch_timer.c          |  30 ++-
 virt/kvm/arm/vgic-v2.c             |  16 +-
 virt/kvm/arm/vgic-v3.c             |  21 +-
 virt/kvm/arm/vgic.c                | 472 ++++++++++++++++++++++++++++++++++---
 11 files changed, 557 insertions(+), 65 deletions(-)

-- 
2.1.4



From marc.zyngier at arm.com  Fri Aug  7 08:45:38 2015
From: marc.zyngier at arm.com (Marc Zyngier)
Date: Fri,  7 Aug 2015 16:45:38 +0100
Subject: [PATCH v4 02/11] arm/arm64: KVM: Move vgic handling to a
 non-preemptible section
In-Reply-To: <1438962347-17541-1-git-send-email-marc.zyngier@arm.com>
References: <1438962347-17541-1-git-send-email-marc.zyngier@arm.com>
Message-ID: <1438962347-17541-3-git-send-email-marc.zyngier@arm.com>

As we're about to introduce some serious GIC-poking to the vgic code,
it is important to make sure that we're going to poke the part of
the GIC that belongs to the CPU we're about to run on (otherwise,
we'd end up with some unexpected interrupts firing)...

Introducing a non-preemptible section in kvm_arch_vcpu_ioctl_run
prevents the problem from occuring.

Reviewed-by: Alex Benn?e <alex.bennee at linaro.org>
Reviewed-by: Christoffer Dall <christoffer.dall at linaro.org>
Signed-off-by: Marc Zyngier <marc.zyngier at arm.com>
---
 arch/arm/kvm/arm.c | 18 +++++++++++++++---
 1 file changed, 15 insertions(+), 3 deletions(-)

diff --git a/arch/arm/kvm/arm.c b/arch/arm/kvm/arm.c
index 1141d21..f1bf418 100644
--- a/arch/arm/kvm/arm.c
+++ b/arch/arm/kvm/arm.c
@@ -523,10 +523,20 @@ int kvm_arch_vcpu_ioctl_run(struct kvm_vcpu *vcpu, struct kvm_run *run)
 		if (vcpu->arch.pause)
 			vcpu_pause(vcpu);
 
+		/*
+		 * Disarming the background timer must be done in a
+		 * preemptible context, as this call may sleep.
+		 */
 		kvm_timer_flush_hwstate(vcpu);
-		kvm_vgic_flush_hwstate(vcpu);
 
+		/*
+		 * Preparing the interrupts to be injected also
+		 * involves poking the GIC, which must be done in a
+		 * non-preemptible context.
+		 */
 		preempt_disable();
+		kvm_vgic_flush_hwstate(vcpu);
+
 		local_irq_disable();
 
 		/*
@@ -539,8 +549,8 @@ int kvm_arch_vcpu_ioctl_run(struct kvm_vcpu *vcpu, struct kvm_run *run)
 
 		if (ret <= 0 || need_new_vmid_gen(vcpu->kvm)) {
 			local_irq_enable();
-			preempt_enable();
 			kvm_vgic_sync_hwstate(vcpu);
+			preempt_enable();
 			kvm_timer_sync_hwstate(vcpu);
 			continue;
 		}
@@ -585,9 +595,11 @@ int kvm_arch_vcpu_ioctl_run(struct kvm_vcpu *vcpu, struct kvm_run *run)
 		 */
 		kvm_guest_exit();
 		trace_kvm_exit(kvm_vcpu_trap_get_class(vcpu), *vcpu_pc(vcpu));
-		preempt_enable();
 
 		kvm_vgic_sync_hwstate(vcpu);
+
+		preempt_enable();
+
 		kvm_timer_sync_hwstate(vcpu);
 
 		ret = handle_exit(vcpu, run, ret);
-- 
2.1.4



From marc.zyngier at arm.com  Fri Aug  7 08:45:39 2015
From: marc.zyngier at arm.com (Marc Zyngier)
Date: Fri,  7 Aug 2015 16:45:39 +0100
Subject: [PATCH v4 03/11] KVM: arm/arm64: vgic: Convert struct vgic_lr to use
 bitfields
In-Reply-To: <1438962347-17541-1-git-send-email-marc.zyngier@arm.com>
References: <1438962347-17541-1-git-send-email-marc.zyngier@arm.com>
Message-ID: <1438962347-17541-4-git-send-email-marc.zyngier@arm.com>

As we're about to cram more information in the vgic_lr structure
(HW interrupt number and additional state information), we switch
to a layout similar to the HW's:

- use bitfields to save space (we don't need more than 10 bits
  to represent the irq numbers)
- source CPU and HW interrupt can share the same field, as
  a SGI doesn't have a physical line.

Reviewed-by: Alex Benn?e <alex.bennee at linaro.org>
Reviewed-by: Christoffer Dall <christoffer.dall at linaro.org>
Signed-off-by: Marc Zyngier <marc.zyngier at arm.com>
---
 include/kvm/arm_vgic.h | 10 +++++++---
 1 file changed, 7 insertions(+), 3 deletions(-)

diff --git a/include/kvm/arm_vgic.h b/include/kvm/arm_vgic.h
index 133ea00..a881e39 100644
--- a/include/kvm/arm_vgic.h
+++ b/include/kvm/arm_vgic.h
@@ -95,11 +95,15 @@ enum vgic_type {
 #define LR_STATE_ACTIVE		(1 << 1)
 #define LR_STATE_MASK		(3 << 0)
 #define LR_EOI_INT		(1 << 2)
+#define LR_HW			(1 << 3)
 
 struct vgic_lr {
-	u16	irq;
-	u8	source;
-	u8	state;
+	unsigned irq:10;
+	union {
+		unsigned hwirq:10;
+		unsigned source:3;
+	};
+	unsigned state:4;
 };
 
 struct vgic_vmcr {
-- 
2.1.4



From marc.zyngier at arm.com  Fri Aug  7 08:45:37 2015
From: marc.zyngier at arm.com (Marc Zyngier)
Date: Fri,  7 Aug 2015 16:45:37 +0100
Subject: [PATCH v4 01/11] arm/arm64: KVM: Fix ordering of timer/GIC on guest
 entry
In-Reply-To: <1438962347-17541-1-git-send-email-marc.zyngier@arm.com>
References: <1438962347-17541-1-git-send-email-marc.zyngier@arm.com>
Message-ID: <1438962347-17541-2-git-send-email-marc.zyngier@arm.com>

As we now inject the timer interrupt when we're about to enter
the guest, it makes a lot more sense to make sure this happens
before the vgic code queues the pending interrupts.

Otherwise, we get the interrupt on the following exit, which is
not great for latency (and leads to all kind of bizarre issues
when using with active interrupts at the HW level).

Signed-off-by: Marc Zyngier <marc.zyngier at arm.com>
Reviewed-by: Alex Benn?e <alex.bennee at linaro.org>
Reviewed-by: Christoffer Dall <christoffer.dall at linaro.org>
---
 arch/arm/kvm/arm.c | 7 +++----
 1 file changed, 3 insertions(+), 4 deletions(-)

diff --git a/arch/arm/kvm/arm.c b/arch/arm/kvm/arm.c
index 9ce5cf0..1141d21 100644
--- a/arch/arm/kvm/arm.c
+++ b/arch/arm/kvm/arm.c
@@ -523,8 +523,8 @@ int kvm_arch_vcpu_ioctl_run(struct kvm_vcpu *vcpu, struct kvm_run *run)
 		if (vcpu->arch.pause)
 			vcpu_pause(vcpu);
 
-		kvm_vgic_flush_hwstate(vcpu);
 		kvm_timer_flush_hwstate(vcpu);
+		kvm_vgic_flush_hwstate(vcpu);
 
 		preempt_disable();
 		local_irq_disable();
@@ -540,8 +540,8 @@ int kvm_arch_vcpu_ioctl_run(struct kvm_vcpu *vcpu, struct kvm_run *run)
 		if (ret <= 0 || need_new_vmid_gen(vcpu->kvm)) {
 			local_irq_enable();
 			preempt_enable();
-			kvm_timer_sync_hwstate(vcpu);
 			kvm_vgic_sync_hwstate(vcpu);
+			kvm_timer_sync_hwstate(vcpu);
 			continue;
 		}
 
@@ -587,9 +587,8 @@ int kvm_arch_vcpu_ioctl_run(struct kvm_vcpu *vcpu, struct kvm_run *run)
 		trace_kvm_exit(kvm_vcpu_trap_get_class(vcpu), *vcpu_pc(vcpu));
 		preempt_enable();
 
-
-		kvm_timer_sync_hwstate(vcpu);
 		kvm_vgic_sync_hwstate(vcpu);
+		kvm_timer_sync_hwstate(vcpu);
 
 		ret = handle_exit(vcpu, run, ret);
 	}
-- 
2.1.4



From marc.zyngier at arm.com  Fri Aug  7 08:45:40 2015
From: marc.zyngier at arm.com (Marc Zyngier)
Date: Fri,  7 Aug 2015 16:45:40 +0100
Subject: [PATCH v4 04/11] KVM: arm/arm64: vgic: Allow HW irq to be encoded in
 LR
In-Reply-To: <1438962347-17541-1-git-send-email-marc.zyngier@arm.com>
References: <1438962347-17541-1-git-send-email-marc.zyngier@arm.com>
Message-ID: <1438962347-17541-5-git-send-email-marc.zyngier@arm.com>

Now that struct vgic_lr supports the LR_HW bit and carries a hwirq
field, we can encode that information into the list registers.

This patch provides implementations for both GICv2 and GICv3.

Reviewed-by: Christoffer Dall <christoffer.dall at linaro.org>
Signed-off-by: Marc Zyngier <marc.zyngier at arm.com>
---
 include/linux/irqchip/arm-gic-v3.h |  3 +++
 include/linux/irqchip/arm-gic.h    |  3 ++-
 virt/kvm/arm/vgic-v2.c             | 16 +++++++++++++++-
 virt/kvm/arm/vgic-v3.c             | 21 ++++++++++++++++++---
 4 files changed, 38 insertions(+), 5 deletions(-)

diff --git a/include/linux/irqchip/arm-gic-v3.h b/include/linux/irqchip/arm-gic-v3.h
index ffbc034..cf637d6 100644
--- a/include/linux/irqchip/arm-gic-v3.h
+++ b/include/linux/irqchip/arm-gic-v3.h
@@ -268,9 +268,12 @@
 
 #define ICH_LR_EOI			(1UL << 41)
 #define ICH_LR_GROUP			(1UL << 60)
+#define ICH_LR_HW			(1UL << 61)
 #define ICH_LR_STATE			(3UL << 62)
 #define ICH_LR_PENDING_BIT		(1UL << 62)
 #define ICH_LR_ACTIVE_BIT		(1UL << 63)
+#define ICH_LR_PHYS_ID_SHIFT		32
+#define ICH_LR_PHYS_ID_MASK		(0x3ffUL << ICH_LR_PHYS_ID_SHIFT)
 
 #define ICH_MISR_EOI			(1 << 0)
 #define ICH_MISR_U			(1 << 1)
diff --git a/include/linux/irqchip/arm-gic.h b/include/linux/irqchip/arm-gic.h
index 9de976b..ca88dad 100644
--- a/include/linux/irqchip/arm-gic.h
+++ b/include/linux/irqchip/arm-gic.h
@@ -71,11 +71,12 @@
 
 #define GICH_LR_VIRTUALID		(0x3ff << 0)
 #define GICH_LR_PHYSID_CPUID_SHIFT	(10)
-#define GICH_LR_PHYSID_CPUID		(7 << GICH_LR_PHYSID_CPUID_SHIFT)
+#define GICH_LR_PHYSID_CPUID		(0x3ff << GICH_LR_PHYSID_CPUID_SHIFT)
 #define GICH_LR_STATE			(3 << 28)
 #define GICH_LR_PENDING_BIT		(1 << 28)
 #define GICH_LR_ACTIVE_BIT		(1 << 29)
 #define GICH_LR_EOI			(1 << 19)
+#define GICH_LR_HW			(1 << 31)
 
 #define GICH_VMCR_CTRL_SHIFT		0
 #define GICH_VMCR_CTRL_MASK		(0x21f << GICH_VMCR_CTRL_SHIFT)
diff --git a/virt/kvm/arm/vgic-v2.c b/virt/kvm/arm/vgic-v2.c
index f9b9c7c..8d7b04d 100644
--- a/virt/kvm/arm/vgic-v2.c
+++ b/virt/kvm/arm/vgic-v2.c
@@ -48,6 +48,10 @@ static struct vgic_lr vgic_v2_get_lr(const struct kvm_vcpu *vcpu, int lr)
 		lr_desc.state |= LR_STATE_ACTIVE;
 	if (val & GICH_LR_EOI)
 		lr_desc.state |= LR_EOI_INT;
+	if (val & GICH_LR_HW) {
+		lr_desc.state |= LR_HW;
+		lr_desc.hwirq = (val & GICH_LR_PHYSID_CPUID) >> GICH_LR_PHYSID_CPUID_SHIFT;
+	}
 
 	return lr_desc;
 }
@@ -55,7 +59,9 @@ static struct vgic_lr vgic_v2_get_lr(const struct kvm_vcpu *vcpu, int lr)
 static void vgic_v2_set_lr(struct kvm_vcpu *vcpu, int lr,
 			   struct vgic_lr lr_desc)
 {
-	u32 lr_val = (lr_desc.source << GICH_LR_PHYSID_CPUID_SHIFT) | lr_desc.irq;
+	u32 lr_val;
+
+	lr_val = lr_desc.irq;
 
 	if (lr_desc.state & LR_STATE_PENDING)
 		lr_val |= GICH_LR_PENDING_BIT;
@@ -64,6 +70,14 @@ static void vgic_v2_set_lr(struct kvm_vcpu *vcpu, int lr,
 	if (lr_desc.state & LR_EOI_INT)
 		lr_val |= GICH_LR_EOI;
 
+	if (lr_desc.state & LR_HW) {
+		lr_val |= GICH_LR_HW;
+		lr_val |= (u32)lr_desc.hwirq << GICH_LR_PHYSID_CPUID_SHIFT;
+	}
+
+	if (lr_desc.irq < VGIC_NR_SGIS)
+		lr_val |= (lr_desc.source << GICH_LR_PHYSID_CPUID_SHIFT);
+
 	vcpu->arch.vgic_cpu.vgic_v2.vgic_lr[lr] = lr_val;
 }
 
diff --git a/virt/kvm/arm/vgic-v3.c b/virt/kvm/arm/vgic-v3.c
index dff0602..afbf925 100644
--- a/virt/kvm/arm/vgic-v3.c
+++ b/virt/kvm/arm/vgic-v3.c
@@ -67,6 +67,10 @@ static struct vgic_lr vgic_v3_get_lr(const struct kvm_vcpu *vcpu, int lr)
 		lr_desc.state |= LR_STATE_ACTIVE;
 	if (val & ICH_LR_EOI)
 		lr_desc.state |= LR_EOI_INT;
+	if (val & ICH_LR_HW) {
+		lr_desc.state |= LR_HW;
+		lr_desc.hwirq = (val >> ICH_LR_PHYS_ID_SHIFT) & GENMASK(9, 0);
+	}
 
 	return lr_desc;
 }
@@ -84,10 +88,17 @@ static void vgic_v3_set_lr(struct kvm_vcpu *vcpu, int lr,
 	 * Eventually we want to make this configurable, so we may revisit
 	 * this in the future.
 	 */
-	if (vcpu->kvm->arch.vgic.vgic_model == KVM_DEV_TYPE_ARM_VGIC_V3)
+	switch (vcpu->kvm->arch.vgic.vgic_model) {
+	case KVM_DEV_TYPE_ARM_VGIC_V3:
 		lr_val |= ICH_LR_GROUP;
-	else
-		lr_val |= (u32)lr_desc.source << GICH_LR_PHYSID_CPUID_SHIFT;
+		break;
+	case  KVM_DEV_TYPE_ARM_VGIC_V2:
+		if (lr_desc.irq < VGIC_NR_SGIS)
+			lr_val |= (u32)lr_desc.source << GICH_LR_PHYSID_CPUID_SHIFT;
+		break;
+	default:
+		BUG();
+	}
 
 	if (lr_desc.state & LR_STATE_PENDING)
 		lr_val |= ICH_LR_PENDING_BIT;
@@ -95,6 +106,10 @@ static void vgic_v3_set_lr(struct kvm_vcpu *vcpu, int lr,
 		lr_val |= ICH_LR_ACTIVE_BIT;
 	if (lr_desc.state & LR_EOI_INT)
 		lr_val |= ICH_LR_EOI;
+	if (lr_desc.state & LR_HW) {
+		lr_val |= ICH_LR_HW;
+		lr_val |= ((u64)lr_desc.hwirq) << ICH_LR_PHYS_ID_SHIFT;
+	}
 
 	vcpu->arch.vgic_cpu.vgic_v3.vgic_lr[LR_INDEX(lr)] = lr_val;
 }
-- 
2.1.4



From marc.zyngier at arm.com  Fri Aug  7 08:45:44 2015
From: marc.zyngier at arm.com (Marc Zyngier)
Date: Fri,  7 Aug 2015 16:45:44 +0100
Subject: [PATCH v4 08/11] KVM: arm/arm64: vgic: Add vgic_{get,
 set}_phys_irq_active
In-Reply-To: <1438962347-17541-1-git-send-email-marc.zyngier@arm.com>
References: <1438962347-17541-1-git-send-email-marc.zyngier@arm.com>
Message-ID: <1438962347-17541-9-git-send-email-marc.zyngier@arm.com>

In order to control the active state of an interrupt, introduce
a pair of accessors allowing the state to be set/queried.

This only affects the logical state, and the HW state will only be
applied at world-switch time.

Acked-by: Christoffer Dall <christoffer.dall at linaro.org>
Signed-off-by: Marc Zyngier <marc.zyngier at arm.com>
---
 include/kvm/arm_vgic.h |  2 ++
 virt/kvm/arm/vgic.c    | 24 ++++++++++++++++++++++++
 2 files changed, 26 insertions(+)

diff --git a/include/kvm/arm_vgic.h b/include/kvm/arm_vgic.h
index c0e6354..e789e47 100644
--- a/include/kvm/arm_vgic.h
+++ b/include/kvm/arm_vgic.h
@@ -356,6 +356,8 @@ int kvm_vgic_vcpu_active_irq(struct kvm_vcpu *vcpu);
 struct irq_phys_map *kvm_vgic_map_phys_irq(struct kvm_vcpu *vcpu,
 					   int virt_irq, int irq);
 int kvm_vgic_unmap_phys_irq(struct kvm_vcpu *vcpu, struct irq_phys_map *map);
+bool kvm_vgic_get_phys_irq_active(struct irq_phys_map *map);
+void kvm_vgic_set_phys_irq_active(struct irq_phys_map *map, bool active);
 
 #define irqchip_in_kernel(k)	(!!((k)->arch.vgic.in_kernel))
 #define vgic_initialized(k)	(!!((k)->arch.vgic.nr_cpus))
diff --git a/virt/kvm/arm/vgic.c b/virt/kvm/arm/vgic.c
index 9d009d2..b553a8f 100644
--- a/virt/kvm/arm/vgic.c
+++ b/virt/kvm/arm/vgic.c
@@ -1802,6 +1802,30 @@ static void vgic_free_phys_irq_map_rcu(struct rcu_head *rcu)
 }
 
 /**
+ * kvm_vgic_get_phys_irq_active - Return the active state of a mapped IRQ
+ *
+ * Return the logical active state of a mapped interrupt. This doesn't
+ * necessarily reflects the current HW state.
+ */
+bool kvm_vgic_get_phys_irq_active(struct irq_phys_map *map)
+{
+	BUG_ON(!map);
+	return map->active;
+}
+
+/**
+ * kvm_vgic_set_phys_irq_active - Set the active state of a mapped IRQ
+ *
+ * Set the logical active state of a mapped interrupt. This doesn't
+ * immediately affects the HW state.
+ */
+void kvm_vgic_set_phys_irq_active(struct irq_phys_map *map, bool active)
+{
+	BUG_ON(!map);
+	map->active = active;
+}
+
+/**
  * kvm_vgic_unmap_phys_irq - Remove a virtual to physical IRQ mapping
  * @vcpu: The VCPU pointer
  * @map: The pointer to a mapping obtained through kvm_vgic_map_phys_irq
-- 
2.1.4



From marc.zyngier at arm.com  Fri Aug  7 08:45:43 2015
From: marc.zyngier at arm.com (Marc Zyngier)
Date: Fri,  7 Aug 2015 16:45:43 +0100
Subject: [PATCH v4 07/11] KVM: arm/arm64: vgic: Allow HW interrupts to be
 queued to a guest
In-Reply-To: <1438962347-17541-1-git-send-email-marc.zyngier@arm.com>
References: <1438962347-17541-1-git-send-email-marc.zyngier@arm.com>
Message-ID: <1438962347-17541-8-git-send-email-marc.zyngier@arm.com>

To allow a HW interrupt to be injected into a guest, we lookup the
guest virtual interrupt in the irq_phys_map list, and if we have
a match, encode both interrupts in the LR.

We also mark the interrupt as "active" at the host distributor level.

On guest EOI on the virtual interrupt, the host interrupt will be
deactivated.

Reviewed-by: Christoffer Dall <christoffer.dall at linaro.org>
Signed-off-by: Marc Zyngier <marc.zyngier at arm.com>
---
 virt/kvm/arm/vgic.c | 89 +++++++++++++++++++++++++++++++++++++++++++++++++++--
 1 file changed, 86 insertions(+), 3 deletions(-)

diff --git a/virt/kvm/arm/vgic.c b/virt/kvm/arm/vgic.c
index 51c9900..9d009d2 100644
--- a/virt/kvm/arm/vgic.c
+++ b/virt/kvm/arm/vgic.c
@@ -1140,6 +1140,39 @@ static void vgic_queue_irq_to_lr(struct kvm_vcpu *vcpu, int irq,
 	if (!vgic_irq_is_edge(vcpu, irq))
 		vlr.state |= LR_EOI_INT;
 
+	if (vlr.irq >= VGIC_NR_SGIS) {
+		struct irq_phys_map *map;
+		map = vgic_irq_map_search(vcpu, irq);
+
+		/*
+		 * If we have a mapping, and the virtual interrupt is
+		 * being injected, then we must set the state to
+		 * active in the physical world. Otherwise the
+		 * physical interrupt will fire and the guest will
+		 * exit before processing the virtual interrupt.
+		 */
+		if (map) {
+			int ret;
+
+			BUG_ON(!map->active);
+			vlr.hwirq = map->phys_irq;
+			vlr.state |= LR_HW;
+			vlr.state &= ~LR_EOI_INT;
+
+			ret = irq_set_irqchip_state(map->irq,
+						    IRQCHIP_STATE_ACTIVE,
+						    true);
+			WARN_ON(ret);
+
+			/*
+			 * Make sure we're not going to sample this
+			 * again, as a HW-backed interrupt cannot be
+			 * in the PENDING_ACTIVE stage.
+			 */
+			vgic_irq_set_queued(vcpu, irq);
+		}
+	}
+
 	vgic_set_lr(vcpu, lr_nr, vlr);
 	vgic_sync_lr_elrsr(vcpu, lr_nr, vlr);
 }
@@ -1364,6 +1397,39 @@ static bool vgic_process_maintenance(struct kvm_vcpu *vcpu)
 	return level_pending;
 }
 
+/*
+ * Save the physical active state, and reset it to inactive.
+ *
+ * Return 1 if HW interrupt went from active to inactive, and 0 otherwise.
+ */
+static int vgic_sync_hwirq(struct kvm_vcpu *vcpu, struct vgic_lr vlr)
+{
+	struct irq_phys_map *map;
+	int ret;
+
+	if (!(vlr.state & LR_HW))
+		return 0;
+
+	map = vgic_irq_map_search(vcpu, vlr.irq);
+	BUG_ON(!map || !map->active);
+
+	ret = irq_get_irqchip_state(map->irq,
+				    IRQCHIP_STATE_ACTIVE,
+				    &map->active);
+
+	WARN_ON(ret);
+
+	if (map->active) {
+		ret = irq_set_irqchip_state(map->irq,
+					    IRQCHIP_STATE_ACTIVE,
+					    false);
+		WARN_ON(ret);
+		return 0;
+	}
+
+	return 1;
+}
+
 /* Sync back the VGIC state after a guest run */
 static void __kvm_vgic_sync_hwstate(struct kvm_vcpu *vcpu)
 {
@@ -1378,14 +1444,31 @@ static void __kvm_vgic_sync_hwstate(struct kvm_vcpu *vcpu)
 	elrsr = vgic_get_elrsr(vcpu);
 	elrsr_ptr = u64_to_bitmask(&elrsr);
 
-	/* Clear mappings for empty LRs */
-	for_each_set_bit(lr, elrsr_ptr, vgic->nr_lr) {
+	/* Deal with HW interrupts, and clear mappings for empty LRs */
+	for (lr = 0; lr < vgic->nr_lr; lr++) {
 		struct vgic_lr vlr;
 
-		if (!test_and_clear_bit(lr, vgic_cpu->lr_used))
+		if (!test_bit(lr, vgic_cpu->lr_used))
 			continue;
 
 		vlr = vgic_get_lr(vcpu, lr);
+		if (vgic_sync_hwirq(vcpu, vlr)) {
+			/*
+			 * So this is a HW interrupt that the guest
+			 * EOI-ed. Clean the LR state and allow the
+			 * interrupt to be sampled again.
+			 */
+			vlr.state = 0;
+			vlr.hwirq = 0;
+			vgic_set_lr(vcpu, lr, vlr);
+			vgic_irq_clear_queued(vcpu, vlr.irq);
+			set_bit(lr, elrsr_ptr);
+		}
+
+		if (!test_bit(lr, elrsr_ptr))
+			continue;
+
+		clear_bit(lr, vgic_cpu->lr_used);
 
 		BUG_ON(vlr.irq >= dist->nr_irqs);
 		vgic_cpu->vgic_irq_lr_map[vlr.irq] = LR_EMPTY;
-- 
2.1.4



From marc.zyngier at arm.com  Fri Aug  7 08:45:47 2015
From: marc.zyngier at arm.com (Marc Zyngier)
Date: Fri,  7 Aug 2015 16:45:47 +0100
Subject: [PATCH v4 11/11] KVM: arm/arm64: vgic: Allow HW interrupts for
 non-shared devices
In-Reply-To: <1438962347-17541-1-git-send-email-marc.zyngier@arm.com>
References: <1438962347-17541-1-git-send-email-marc.zyngier@arm.com>
Message-ID: <1438962347-17541-12-git-send-email-marc.zyngier@arm.com>

So far, the only use of the HW interrupt facility is the timer,
implying that the active state is context-switched for each vcpu,
as the device is is shared across all vcpus.

This does not work for a device that has been assigned to a VM,
as the guest is entierely in control of that device (the HW is
not shared). In that case, it makes sense to bypass the whole
active state switching, and only track the deactivation of the
interrupt.

Signed-off-by: Marc Zyngier <marc.zyngier at arm.com>
---
 include/kvm/arm_vgic.h    |  6 ++--
 virt/kvm/arm/arch_timer.c |  3 +-
 virt/kvm/arm/vgic.c       | 73 ++++++++++++++++++++++++++++++++++++++---------
 3 files changed, 65 insertions(+), 17 deletions(-)

diff --git a/include/kvm/arm_vgic.h b/include/kvm/arm_vgic.h
index d901f1a..7ef9ce0 100644
--- a/include/kvm/arm_vgic.h
+++ b/include/kvm/arm_vgic.h
@@ -163,7 +163,8 @@ struct irq_phys_map {
 	u32			virt_irq;
 	u32			phys_irq;
 	u32			irq;
-	bool			active;
+	bool			shared;
+	bool			active; /* Only valid if shared */
 };
 
 struct irq_phys_map_entry {
@@ -356,7 +357,8 @@ void vgic_v3_dispatch_sgi(struct kvm_vcpu *vcpu, u64 reg);
 int kvm_vgic_vcpu_pending_irq(struct kvm_vcpu *vcpu);
 int kvm_vgic_vcpu_active_irq(struct kvm_vcpu *vcpu);
 struct irq_phys_map *kvm_vgic_map_phys_irq(struct kvm_vcpu *vcpu,
-					   int virt_irq, int irq);
+					   int virt_irq, int irq,
+					   bool shared);
 int kvm_vgic_unmap_phys_irq(struct kvm_vcpu *vcpu, struct irq_phys_map *map);
 bool kvm_vgic_get_phys_irq_active(struct irq_phys_map *map);
 void kvm_vgic_set_phys_irq_active(struct irq_phys_map *map, bool active);
diff --git a/virt/kvm/arm/arch_timer.c b/virt/kvm/arm/arch_timer.c
index 76e38d2..db21d8f 100644
--- a/virt/kvm/arm/arch_timer.c
+++ b/virt/kvm/arm/arch_timer.c
@@ -203,7 +203,8 @@ int kvm_timer_vcpu_reset(struct kvm_vcpu *vcpu,
 	 * Tell the VGIC that the virtual interrupt is tied to a
 	 * physical interrupt. We do that once per VCPU.
 	 */
-	map = kvm_vgic_map_phys_irq(vcpu, irq->irq, host_vtimer_irq);
+	map = kvm_vgic_map_phys_irq(vcpu, irq->irq,
+				    host_vtimer_irq, true);
 	if (WARN_ON(IS_ERR(map)))
 		return PTR_ERR(map);
 
diff --git a/virt/kvm/arm/vgic.c b/virt/kvm/arm/vgic.c
index 9eb489a..3a3c06f5 100644
--- a/virt/kvm/arm/vgic.c
+++ b/virt/kvm/arm/vgic.c
@@ -1150,19 +1150,25 @@ static void vgic_queue_irq_to_lr(struct kvm_vcpu *vcpu, int irq,
 		 * active in the physical world. Otherwise the
 		 * physical interrupt will fire and the guest will
 		 * exit before processing the virtual interrupt.
+		 *
+		 * This is of course only valid for a shared
+		 * interrupt. A non shared interrupt should already be
+		 * active.
 		 */
 		if (map) {
-			int ret;
-
-			BUG_ON(!map->active);
 			vlr.hwirq = map->phys_irq;
 			vlr.state |= LR_HW;
 			vlr.state &= ~LR_EOI_INT;
 
-			ret = irq_set_irqchip_state(map->irq,
-						    IRQCHIP_STATE_ACTIVE,
-						    true);
-			WARN_ON(ret);
+			if (map->shared) {
+				int ret;
+
+				BUG_ON(!map->active);
+				ret = irq_set_irqchip_state(map->irq,
+							    IRQCHIP_STATE_ACTIVE,
+							    true);
+				WARN_ON(ret);
+			}
 
 			/*
 			 * Make sure we're not going to sample this
@@ -1405,21 +1411,42 @@ static bool vgic_process_maintenance(struct kvm_vcpu *vcpu)
 static int vgic_sync_hwirq(struct kvm_vcpu *vcpu, struct vgic_lr vlr)
 {
 	struct irq_phys_map *map;
+	bool active;
 	int ret;
 
 	if (!(vlr.state & LR_HW))
 		return 0;
 
 	map = vgic_irq_map_search(vcpu, vlr.irq);
-	BUG_ON(!map || !map->active);
+	BUG_ON(!map);
+	BUG_ON(map->shared && !map->active);
 
 	ret = irq_get_irqchip_state(map->irq,
 				    IRQCHIP_STATE_ACTIVE,
-				    &map->active);
+				    &active);
 
 	WARN_ON(ret);
 
-	if (map->active) {
+	/*
+	 * For a non-shared interrupt, we have to cater for two
+	 * possible deactivation conditions:
+	 *
+	 * - the physical interrupt is now inactive (EOIed from the
+	 *   guest)
+	 * - the physical interrupt is still active, but its virtual
+	 *   counterpart is flagged as "not queued", indicating another
+	 *   interrupt has fired between the EOI and the guest exit.
+	 *
+	 * Also, we are not deactivating a non-shared interrupt
+	 * ourselves. This is always left to the guest, who solely own
+	 * the device.
+	 */
+	if (!map->shared)
+		return !active || !vgic_irq_is_queued(vcpu, vlr.irq);
+
+	map->active = active;
+
+	if (active) {
 		ret = irq_set_irqchip_state(map->irq,
 					    IRQCHIP_STATE_ACTIVE,
 					    false);
@@ -1612,6 +1639,17 @@ static int vgic_update_irq_pending(struct kvm *kvm, int cpuid,
 		goto out;
 	}
 
+	if (map && !map->shared) {
+		/*
+		 * We are told to inject a HW irq, so we have to trust
+		 * the caller that the previous one has been EOIed,
+		 * and that a new one is now active. Clearing the
+		 * queued state will have the effect of making it
+		 * sample-able again.
+		 */
+		vgic_irq_clear_queued(vcpu, irq_num);
+	}
+
 	if (!vgic_can_sample_irq(vcpu, irq_num)) {
 		/*
 		 * Level interrupt in progress, will be picked up
@@ -1742,16 +1780,21 @@ static struct list_head *vgic_get_irq_phys_map_list(struct kvm_vcpu *vcpu,
  * @vcpu: The VCPU pointer
  * @virt_irq: The virtual irq number
  * @irq: The Linux IRQ number
+ * @shared: Indicates if the interrupt has to be context-switched or
+ *          if it is private to a VM
  *
  * Establish a mapping between a guest visible irq (@virt_irq) and a
  * Linux irq (@irq). On injection, @virt_irq will be associated with
  * the physical interrupt represented by @irq. This mapping can be
  * established multiple times as long as the parameters are the same.
+ * If @shared is true, the active state of the interrupt will be
+ * context-switched.
  *
  * Returns a valid pointer on success, and an error pointer otherwise
  */
 struct irq_phys_map *kvm_vgic_map_phys_irq(struct kvm_vcpu *vcpu,
-					   int virt_irq, int irq)
+					   int virt_irq, int irq,
+					   bool shared)
 {
 	struct vgic_dist *dist = &vcpu->kvm->arch.vgic;
 	struct list_head *root = vgic_get_irq_phys_map_list(vcpu, virt_irq);
@@ -1785,7 +1828,8 @@ struct irq_phys_map *kvm_vgic_map_phys_irq(struct kvm_vcpu *vcpu,
 	if (map) {
 		/* Make sure this mapping matches */
 		if (map->phys_irq != phys_irq	||
-		    map->irq      != irq)
+		    map->irq      != irq	||
+		    map->shared   != shared)
 			map = ERR_PTR(-EINVAL);
 
 		/* Found an existing, valid mapping */
@@ -1796,6 +1840,7 @@ struct irq_phys_map *kvm_vgic_map_phys_irq(struct kvm_vcpu *vcpu,
 	map->virt_irq = virt_irq;
 	map->phys_irq = phys_irq;
 	map->irq      = irq;
+	map->shared   = shared;
 
 	list_add_tail_rcu(&entry->entry, root);
 
@@ -1846,7 +1891,7 @@ static void vgic_free_phys_irq_map_rcu(struct rcu_head *rcu)
  */
 bool kvm_vgic_get_phys_irq_active(struct irq_phys_map *map)
 {
-	BUG_ON(!map);
+	BUG_ON(!map || !map->shared);
 	return map->active;
 }
 
@@ -1858,7 +1903,7 @@ bool kvm_vgic_get_phys_irq_active(struct irq_phys_map *map)
  */
 void kvm_vgic_set_phys_irq_active(struct irq_phys_map *map, bool active)
 {
-	BUG_ON(!map);
+	BUG_ON(!map || !map->shared);
 	map->active = active;
 }
 
-- 
2.1.4



From marc.zyngier at arm.com  Fri Aug  7 08:45:45 2015
From: marc.zyngier at arm.com (Marc Zyngier)
Date: Fri,  7 Aug 2015 16:45:45 +0100
Subject: [PATCH v4 09/11] KVM: arm/arm64: vgic: Prevent userspace injection of
 a mapped interrupt
In-Reply-To: <1438962347-17541-1-git-send-email-marc.zyngier@arm.com>
References: <1438962347-17541-1-git-send-email-marc.zyngier@arm.com>
Message-ID: <1438962347-17541-10-git-send-email-marc.zyngier@arm.com>

Virtual interrupts mapped to a HW interrupt should only be triggered
from inside the kernel. Otherwise, you could end up confusing the
kernel (and the GIC's) state machine.

Rearrange the injection path so that kvm_vgic_inject_irq is
used for non-mapped interrupts, and kvm_vgic_inject_mapped_irq is
used for mapped interrupts. The latter should only be called from
inside the kernel (timer, irqfd).

Signed-off-by: Marc Zyngier <marc.zyngier at arm.com>
---
 include/kvm/arm_vgic.h |   2 +
 virt/kvm/arm/vgic.c    | 103 +++++++++++++++++++++++++++++++++----------------
 2 files changed, 72 insertions(+), 33 deletions(-)

diff --git a/include/kvm/arm_vgic.h b/include/kvm/arm_vgic.h
index e789e47..d901f1a 100644
--- a/include/kvm/arm_vgic.h
+++ b/include/kvm/arm_vgic.h
@@ -350,6 +350,8 @@ void kvm_vgic_flush_hwstate(struct kvm_vcpu *vcpu);
 void kvm_vgic_sync_hwstate(struct kvm_vcpu *vcpu);
 int kvm_vgic_inject_irq(struct kvm *kvm, int cpuid, unsigned int irq_num,
 			bool level);
+int kvm_vgic_inject_mapped_irq(struct kvm *kvm, int cpuid,
+			       struct irq_phys_map *map, bool level);
 void vgic_v3_dispatch_sgi(struct kvm_vcpu *vcpu, u64 reg);
 int kvm_vgic_vcpu_pending_irq(struct kvm_vcpu *vcpu);
 int kvm_vgic_vcpu_active_irq(struct kvm_vcpu *vcpu);
diff --git a/virt/kvm/arm/vgic.c b/virt/kvm/arm/vgic.c
index b553a8f..9eb489a 100644
--- a/virt/kvm/arm/vgic.c
+++ b/virt/kvm/arm/vgic.c
@@ -1555,7 +1555,8 @@ static int vgic_validate_injection(struct kvm_vcpu *vcpu, int irq, int level)
 }
 
 static int vgic_update_irq_pending(struct kvm *kvm, int cpuid,
-				  unsigned int irq_num, bool level)
+				   struct irq_phys_map *map,
+				   unsigned int irq_num, bool level)
 {
 	struct vgic_dist *dist = &kvm->arch.vgic;
 	struct kvm_vcpu *vcpu;
@@ -1563,6 +1564,9 @@ static int vgic_update_irq_pending(struct kvm *kvm, int cpuid,
 	int enabled;
 	bool ret = true, can_inject = true;
 
+	if (irq_num >= min(kvm->arch.vgic.nr_irqs, 1020))
+		return -EINVAL;
+
 	spin_lock(&dist->lock);
 
 	vcpu = kvm_get_vcpu(kvm, cpuid);
@@ -1625,18 +1629,46 @@ static int vgic_update_irq_pending(struct kvm *kvm, int cpuid,
 out:
 	spin_unlock(&dist->lock);
 
-	return ret ? cpuid : -EINVAL;
+	if (ret) {
+		/* kick the specified vcpu */
+		kvm_vcpu_kick(kvm_get_vcpu(kvm, cpuid));
+	}
+
+	return 0;
+}
+
+static int vgic_lazy_init(struct kvm *kvm)
+{
+	int ret = 0;
+
+	if (unlikely(!vgic_initialized(kvm))) {
+		/*
+		 * We only provide the automatic initialization of the VGIC
+		 * for the legacy case of a GICv2. Any other type must
+		 * be explicitly initialized once setup with the respective
+		 * KVM device call.
+		 */
+		if (kvm->arch.vgic.vgic_model != KVM_DEV_TYPE_ARM_VGIC_V2)
+			return -EBUSY;
+
+		mutex_lock(&kvm->lock);
+		ret = vgic_init(kvm);
+		mutex_unlock(&kvm->lock);
+	}
+
+	return ret;
 }
 
 /**
  * kvm_vgic_inject_irq - Inject an IRQ from a device to the vgic
  * @kvm:     The VM structure pointer
  * @cpuid:   The CPU for PPIs
- * @irq_num: The IRQ number that is assigned to the device
+ * @irq_num: The IRQ number that is assigned to the device. This IRQ
+ *           must not be mapped to a HW interrupt.
  * @level:   Edge-triggered:  true:  to trigger the interrupt
  *			      false: to ignore the call
- *	     Level-sensitive  true:  activates an interrupt
- *			      false: deactivates an interrupt
+ *	     Level-sensitive  true:  raise the input signal
+ *			      false: lower the input signal
  *
  * The GIC is not concerned with devices being active-LOW or active-HIGH for
  * level-sensitive interrupts.  You can think of the level parameter as 1
@@ -1645,39 +1677,44 @@ out:
 int kvm_vgic_inject_irq(struct kvm *kvm, int cpuid, unsigned int irq_num,
 			bool level)
 {
-	int ret = 0;
-	int vcpu_id;
-
-	if (unlikely(!vgic_initialized(kvm))) {
-		/*
-		 * We only provide the automatic initialization of the VGIC
-		 * for the legacy case of a GICv2. Any other type must
-		 * be explicitly initialized once setup with the respective
-		 * KVM device call.
-		 */
-		if (kvm->arch.vgic.vgic_model != KVM_DEV_TYPE_ARM_VGIC_V2) {
-			ret = -EBUSY;
-			goto out;
-		}
-		mutex_lock(&kvm->lock);
-		ret = vgic_init(kvm);
-		mutex_unlock(&kvm->lock);
+	struct irq_phys_map *map;
+	int ret;
 
-		if (ret)
-			goto out;
-	}
+	ret = vgic_lazy_init(kvm);
+	if (ret)
+		return ret;
 
-	if (irq_num >= min(kvm->arch.vgic.nr_irqs, 1020))
+	map = vgic_irq_map_search(kvm_get_vcpu(kvm, cpuid), irq_num);
+	if (map)
 		return -EINVAL;
 
-	vcpu_id = vgic_update_irq_pending(kvm, cpuid, irq_num, level);
-	if (vcpu_id >= 0) {
-		/* kick the specified vcpu */
-		kvm_vcpu_kick(kvm_get_vcpu(kvm, vcpu_id));
-	}
+	return vgic_update_irq_pending(kvm, cpuid, NULL, irq_num, level);
+}
 
-out:
-	return ret;
+/**
+ * kvm_vgic_inject_mapped_irq - Inject a physically mapped IRQ to the vgic
+ * @kvm:     The VM structure pointer
+ * @cpuid:   The CPU for PPIs
+ * @map:     Pointer to a irq_phys_map structure describing the mapping
+ * @level:   Edge-triggered:  true:  to trigger the interrupt
+ *			      false: to ignore the call
+ *	     Level-sensitive  true:  raise the input signal
+ *			      false: lower the input signal
+ *
+ * The GIC is not concerned with devices being active-LOW or active-HIGH for
+ * level-sensitive interrupts.  You can think of the level parameter as 1
+ * being HIGH and 0 being LOW and all devices being active-HIGH.
+ */
+int kvm_vgic_inject_mapped_irq(struct kvm *kvm, int cpuid,
+			       struct irq_phys_map *map, bool level)
+{
+	int ret;
+
+	ret = vgic_lazy_init(kvm);
+	if (ret)
+		return ret;
+
+	return vgic_update_irq_pending(kvm, cpuid, map, map->virt_irq, level);
 }
 
 static irqreturn_t vgic_maintenance_handler(int irq, void *data)
-- 
2.1.4



From marc.zyngier at arm.com  Fri Aug  7 08:45:41 2015
From: marc.zyngier at arm.com (Marc Zyngier)
Date: Fri,  7 Aug 2015 16:45:41 +0100
Subject: [PATCH v4 05/11] KVM: arm/arm64: vgic: Relax vgic_can_sample_irq for
 edge IRQs
In-Reply-To: <1438962347-17541-1-git-send-email-marc.zyngier@arm.com>
References: <1438962347-17541-1-git-send-email-marc.zyngier@arm.com>
Message-ID: <1438962347-17541-6-git-send-email-marc.zyngier@arm.com>

We only set the irq_queued flag for level interrupts, meaning
that "!vgic_irq_is_queued(vcpu, irq)" is a good enough predicate
for all interrupts.

This will allow us to inject edge HW interrupts, for which the
state ACTIVE+PENDING is not allowed.

Reviewed-by: Christoffer Dall <christoffer.dall at linaro.org>
Signed-off-by: Marc Zyngier <marc.zyngier at arm.com>
---
 virt/kvm/arm/vgic.c | 2 +-
 1 file changed, 1 insertion(+), 1 deletion(-)

diff --git a/virt/kvm/arm/vgic.c b/virt/kvm/arm/vgic.c
index bc40137..5bd1695 100644
--- a/virt/kvm/arm/vgic.c
+++ b/virt/kvm/arm/vgic.c
@@ -375,7 +375,7 @@ void vgic_cpu_irq_clear(struct kvm_vcpu *vcpu, int irq)
 
 static bool vgic_can_sample_irq(struct kvm_vcpu *vcpu, int irq)
 {
-	return vgic_irq_is_edge(vcpu, irq) || !vgic_irq_is_queued(vcpu, irq);
+	return !vgic_irq_is_queued(vcpu, irq);
 }
 
 /**
-- 
2.1.4



From marc.zyngier at arm.com  Fri Aug  7 08:45:42 2015
From: marc.zyngier at arm.com (Marc Zyngier)
Date: Fri,  7 Aug 2015 16:45:42 +0100
Subject: [PATCH v4 06/11] KVM: arm/arm64: vgic: Allow dynamic mapping of
 physical/virtual interrupts
In-Reply-To: <1438962347-17541-1-git-send-email-marc.zyngier@arm.com>
References: <1438962347-17541-1-git-send-email-marc.zyngier@arm.com>
Message-ID: <1438962347-17541-7-git-send-email-marc.zyngier@arm.com>

In order to be able to feed physical interrupts to a guest, we need
to be able to establish the virtual-physical mapping between the two
worlds.

The mappings are kept in a set of RCU lists, indexed by virtual interrupts.

Signed-off-by: Marc Zyngier <marc.zyngier at arm.com>
---
 arch/arm/kvm/arm.c     |   2 +
 include/kvm/arm_vgic.h |  25 ++++++
 virt/kvm/arm/vgic.c    | 209 ++++++++++++++++++++++++++++++++++++++++++++++++-
 3 files changed, 235 insertions(+), 1 deletion(-)

diff --git a/arch/arm/kvm/arm.c b/arch/arm/kvm/arm.c
index f1bf418..ce404a5 100644
--- a/arch/arm/kvm/arm.c
+++ b/arch/arm/kvm/arm.c
@@ -125,6 +125,7 @@ int kvm_arch_init_vm(struct kvm *kvm, unsigned long type)
 	if (ret)
 		goto out_free_stage2_pgd;
 
+	kvm_vgic_early_init(kvm);
 	kvm_timer_init(kvm);
 
 	/* Mark the initial VMID generation invalid */
@@ -249,6 +250,7 @@ out:
 
 void kvm_arch_vcpu_postcreate(struct kvm_vcpu *vcpu)
 {
+	kvm_vgic_vcpu_early_init(vcpu);
 }
 
 void kvm_arch_vcpu_free(struct kvm_vcpu *vcpu)
diff --git a/include/kvm/arm_vgic.h b/include/kvm/arm_vgic.h
index a881e39..c0e6354 100644
--- a/include/kvm/arm_vgic.h
+++ b/include/kvm/arm_vgic.h
@@ -159,6 +159,19 @@ struct vgic_io_device {
 	struct kvm_io_device dev;
 };
 
+struct irq_phys_map {
+	u32			virt_irq;
+	u32			phys_irq;
+	u32			irq;
+	bool			active;
+};
+
+struct irq_phys_map_entry {
+	struct list_head	entry;
+	struct rcu_head		rcu;
+	struct irq_phys_map	map;
+};
+
 struct vgic_dist {
 	spinlock_t		lock;
 	bool			in_kernel;
@@ -256,6 +269,10 @@ struct vgic_dist {
 	struct vgic_vm_ops	vm_ops;
 	struct vgic_io_device	dist_iodev;
 	struct vgic_io_device	*redist_iodevs;
+
+	/* Virtual irq to hwirq mapping */
+	spinlock_t		irq_phys_map_lock;
+	struct list_head	irq_phys_map_list;
 };
 
 struct vgic_v2_cpu_if {
@@ -307,6 +324,9 @@ struct vgic_cpu {
 		struct vgic_v2_cpu_if	vgic_v2;
 		struct vgic_v3_cpu_if	vgic_v3;
 	};
+
+	/* Protected by the distributor's irq_phys_map_lock */
+	struct list_head	irq_phys_map_list;
 };
 
 #define LR_EMPTY	0xff
@@ -321,8 +341,10 @@ int kvm_vgic_addr(struct kvm *kvm, unsigned long type, u64 *addr, bool write);
 int kvm_vgic_hyp_init(void);
 int kvm_vgic_map_resources(struct kvm *kvm);
 int kvm_vgic_get_max_vcpus(void);
+void kvm_vgic_early_init(struct kvm *kvm);
 int kvm_vgic_create(struct kvm *kvm, u32 type);
 void kvm_vgic_destroy(struct kvm *kvm);
+void kvm_vgic_vcpu_early_init(struct kvm_vcpu *vcpu);
 void kvm_vgic_vcpu_destroy(struct kvm_vcpu *vcpu);
 void kvm_vgic_flush_hwstate(struct kvm_vcpu *vcpu);
 void kvm_vgic_sync_hwstate(struct kvm_vcpu *vcpu);
@@ -331,6 +353,9 @@ int kvm_vgic_inject_irq(struct kvm *kvm, int cpuid, unsigned int irq_num,
 void vgic_v3_dispatch_sgi(struct kvm_vcpu *vcpu, u64 reg);
 int kvm_vgic_vcpu_pending_irq(struct kvm_vcpu *vcpu);
 int kvm_vgic_vcpu_active_irq(struct kvm_vcpu *vcpu);
+struct irq_phys_map *kvm_vgic_map_phys_irq(struct kvm_vcpu *vcpu,
+					   int virt_irq, int irq);
+int kvm_vgic_unmap_phys_irq(struct kvm_vcpu *vcpu, struct irq_phys_map *map);
 
 #define irqchip_in_kernel(k)	(!!((k)->arch.vgic.in_kernel))
 #define vgic_initialized(k)	(!!((k)->arch.vgic.nr_cpus))
diff --git a/virt/kvm/arm/vgic.c b/virt/kvm/arm/vgic.c
index 5bd1695..51c9900 100644
--- a/virt/kvm/arm/vgic.c
+++ b/virt/kvm/arm/vgic.c
@@ -24,6 +24,7 @@
 #include <linux/of.h>
 #include <linux/of_address.h>
 #include <linux/of_irq.h>
+#include <linux/rculist.h>
 #include <linux/uaccess.h>
 
 #include <asm/kvm_emulate.h>
@@ -74,6 +75,28 @@
  *   cause the interrupt to become inactive in such a situation.
  *   Conversely, writes to GICD_ICPENDRn do not cause the interrupt to become
  *   inactive as long as the external input line is held high.
+ *
+ *
+ * Initialization rules: there are multiple stages to the vgic
+ * initialization, both for the distributor and the CPU interfaces.
+ *
+ * Distributor:
+ *
+ * - kvm_vgic_early_init(): initialization of static data that doesn't
+ *   depend on any sizing information or emulation type. No allocation
+ *   is allowed there.
+ *
+ * - vgic_init(): allocation and initialization of the generic data
+ *   structures that depend on sizing information (number of CPUs,
+ *   number of interrupts). Also initializes the vcpu specific data
+ *   structures. Can be executed lazily for GICv2.
+ *   [to be renamed to kvm_vgic_init??]
+ *
+ * CPU Interface:
+ *
+ * - kvm_vgic_cpu_early_init(): initialization of static data that
+ *   doesn't depend on any sizing information or emulation type. No
+ *   allocation is allowed there.
  */
 
 #include "vgic.h"
@@ -82,6 +105,8 @@ static void vgic_retire_disabled_irqs(struct kvm_vcpu *vcpu);
 static void vgic_retire_lr(int lr_nr, int irq, struct kvm_vcpu *vcpu);
 static struct vgic_lr vgic_get_lr(const struct kvm_vcpu *vcpu, int lr);
 static void vgic_set_lr(struct kvm_vcpu *vcpu, int lr, struct vgic_lr lr_desc);
+static struct irq_phys_map *vgic_irq_map_search(struct kvm_vcpu *vcpu,
+						int virt_irq);
 
 static const struct vgic_ops *vgic_ops;
 static const struct vgic_params *vgic;
@@ -1583,6 +1608,164 @@ static irqreturn_t vgic_maintenance_handler(int irq, void *data)
 	return IRQ_HANDLED;
 }
 
+static struct list_head *vgic_get_irq_phys_map_list(struct kvm_vcpu *vcpu,
+						    int virt_irq)
+{
+	if (virt_irq < VGIC_NR_PRIVATE_IRQS)
+		return &vcpu->arch.vgic_cpu.irq_phys_map_list;
+	else
+		return &vcpu->kvm->arch.vgic.irq_phys_map_list;
+}
+
+/**
+ * kvm_vgic_map_phys_irq - map a virtual IRQ to a physical IRQ
+ * @vcpu: The VCPU pointer
+ * @virt_irq: The virtual irq number
+ * @irq: The Linux IRQ number
+ *
+ * Establish a mapping between a guest visible irq (@virt_irq) and a
+ * Linux irq (@irq). On injection, @virt_irq will be associated with
+ * the physical interrupt represented by @irq. This mapping can be
+ * established multiple times as long as the parameters are the same.
+ *
+ * Returns a valid pointer on success, and an error pointer otherwise
+ */
+struct irq_phys_map *kvm_vgic_map_phys_irq(struct kvm_vcpu *vcpu,
+					   int virt_irq, int irq)
+{
+	struct vgic_dist *dist = &vcpu->kvm->arch.vgic;
+	struct list_head *root = vgic_get_irq_phys_map_list(vcpu, virt_irq);
+	struct irq_phys_map *map;
+	struct irq_phys_map_entry *entry;
+	struct irq_desc *desc;
+	struct irq_data *data;
+	int phys_irq;
+
+	desc = irq_to_desc(irq);
+	if (!desc) {
+		kvm_err("%s: no interrupt descriptor\n", __func__);
+		return ERR_PTR(-EINVAL);
+	}
+
+	data = irq_desc_get_irq_data(desc);
+	while (data->parent_data)
+		data = data->parent_data;
+
+	phys_irq = data->hwirq;
+
+	/* Create a new mapping */
+	entry = kzalloc(sizeof(*entry), GFP_KERNEL);
+	if (!entry)
+		return ERR_PTR(-ENOMEM);
+
+	spin_lock(&dist->irq_phys_map_lock);
+
+	/* Try to match an existing mapping */
+	map = vgic_irq_map_search(vcpu, virt_irq);
+	if (map) {
+		/* Make sure this mapping matches */
+		if (map->phys_irq != phys_irq	||
+		    map->irq      != irq)
+			map = ERR_PTR(-EINVAL);
+
+		/* Found an existing, valid mapping */
+		goto out;
+	}
+
+	map           = &entry->map;
+	map->virt_irq = virt_irq;
+	map->phys_irq = phys_irq;
+	map->irq      = irq;
+
+	list_add_tail_rcu(&entry->entry, root);
+
+out:
+	spin_unlock(&dist->irq_phys_map_lock);
+	/* If we've found a hit in the existing list, free the useless
+	 * entry */
+	if (IS_ERR(map) || map != &entry->map)
+		kfree(entry);
+	return map;
+}
+
+static struct irq_phys_map *vgic_irq_map_search(struct kvm_vcpu *vcpu,
+						int virt_irq)
+{
+	struct list_head *root = vgic_get_irq_phys_map_list(vcpu, virt_irq);
+	struct irq_phys_map_entry *entry;
+	struct irq_phys_map *map;
+
+	rcu_read_lock();
+
+	list_for_each_entry_rcu(entry, root, entry) {
+		map = &entry->map;
+		if (map->virt_irq == virt_irq) {
+			rcu_read_unlock();
+			return map;
+		}
+	}
+
+	rcu_read_unlock();
+
+	return NULL;
+}
+
+static void vgic_free_phys_irq_map_rcu(struct rcu_head *rcu)
+{
+	struct irq_phys_map_entry *entry;
+
+	entry = container_of(rcu, struct irq_phys_map_entry, rcu);
+	kfree(entry);
+}
+
+/**
+ * kvm_vgic_unmap_phys_irq - Remove a virtual to physical IRQ mapping
+ * @vcpu: The VCPU pointer
+ * @map: The pointer to a mapping obtained through kvm_vgic_map_phys_irq
+ *
+ * Remove an existing mapping between virtual and physical interrupts.
+ */
+int kvm_vgic_unmap_phys_irq(struct kvm_vcpu *vcpu, struct irq_phys_map *map)
+{
+	struct vgic_dist *dist = &vcpu->kvm->arch.vgic;
+	struct irq_phys_map_entry *entry;
+	struct list_head *root;
+
+	if (!map)
+		return -EINVAL;
+
+	root = vgic_get_irq_phys_map_list(vcpu, map->virt_irq);
+
+	spin_lock(&dist->irq_phys_map_lock);
+
+	list_for_each_entry(entry, root, entry) {
+		if (&entry->map == map) {
+			list_del_rcu(&entry->entry);
+			call_rcu(&entry->rcu, vgic_free_phys_irq_map_rcu);
+			break;
+		}
+	}
+
+	spin_unlock(&dist->irq_phys_map_lock);
+
+	return 0;
+}
+
+static void vgic_destroy_irq_phys_map(struct kvm *kvm, struct list_head *root)
+{
+	struct vgic_dist *dist = &kvm->arch.vgic;
+	struct irq_phys_map_entry *entry;
+
+	spin_lock(&dist->irq_phys_map_lock);
+
+	list_for_each_entry(entry, root, entry) {
+		list_del_rcu(&entry->entry);
+		call_rcu(&entry->rcu, vgic_free_phys_irq_map_rcu);
+	}
+
+	spin_unlock(&dist->irq_phys_map_lock);
+}
+
 void kvm_vgic_vcpu_destroy(struct kvm_vcpu *vcpu)
 {
 	struct vgic_cpu *vgic_cpu = &vcpu->arch.vgic_cpu;
@@ -1591,6 +1774,7 @@ void kvm_vgic_vcpu_destroy(struct kvm_vcpu *vcpu)
 	kfree(vgic_cpu->active_shared);
 	kfree(vgic_cpu->pend_act_shared);
 	kfree(vgic_cpu->vgic_irq_lr_map);
+	vgic_destroy_irq_phys_map(vcpu->kvm, &vgic_cpu->irq_phys_map_list);
 	vgic_cpu->pending_shared = NULL;
 	vgic_cpu->active_shared = NULL;
 	vgic_cpu->pend_act_shared = NULL;
@@ -1628,6 +1812,17 @@ static int vgic_vcpu_init_maps(struct kvm_vcpu *vcpu, int nr_irqs)
 }
 
 /**
+ * kvm_vgic_vcpu_early_init - Earliest possible per-vcpu vgic init stage
+ *
+ * No memory allocation should be performed here, only static init.
+ */
+void kvm_vgic_vcpu_early_init(struct kvm_vcpu *vcpu)
+{
+	struct vgic_cpu *vgic_cpu = &vcpu->arch.vgic_cpu;
+	INIT_LIST_HEAD(&vgic_cpu->irq_phys_map_list);
+}
+
+/**
  * kvm_vgic_get_max_vcpus - Get the maximum number of VCPUs allowed by HW
  *
  * The host's GIC naturally limits the maximum amount of VCPUs a guest
@@ -1664,6 +1859,7 @@ void kvm_vgic_destroy(struct kvm *kvm)
 	kfree(dist->irq_spi_target);
 	kfree(dist->irq_pending_on_cpu);
 	kfree(dist->irq_active_on_cpu);
+	vgic_destroy_irq_phys_map(kvm, &dist->irq_phys_map_list);
 	dist->irq_sgi_sources = NULL;
 	dist->irq_spi_cpu = NULL;
 	dist->irq_spi_target = NULL;
@@ -1787,6 +1983,18 @@ static int init_vgic_model(struct kvm *kvm, int type)
 	return 0;
 }
 
+/**
+ * kvm_vgic_early_init - Earliest possible vgic initialization stage
+ *
+ * No memory allocation should be performed here, only static init.
+ */
+void kvm_vgic_early_init(struct kvm *kvm)
+{
+	spin_lock_init(&kvm->arch.vgic.lock);
+	spin_lock_init(&kvm->arch.vgic.irq_phys_map_lock);
+	INIT_LIST_HEAD(&kvm->arch.vgic.irq_phys_map_list);
+}
+
 int kvm_vgic_create(struct kvm *kvm, u32 type)
 {
 	int i, vcpu_lock_idx = -1, ret;
@@ -1832,7 +2040,6 @@ int kvm_vgic_create(struct kvm *kvm, u32 type)
 	if (ret)
 		goto out_unlock;
 
-	spin_lock_init(&kvm->arch.vgic.lock);
 	kvm->arch.vgic.in_kernel = true;
 	kvm->arch.vgic.vgic_model = type;
 	kvm->arch.vgic.vctrl_base = vgic->vctrl_base;
-- 
2.1.4



From marc.zyngier at arm.com  Fri Aug  7 08:45:46 2015
From: marc.zyngier at arm.com (Marc Zyngier)
Date: Fri,  7 Aug 2015 16:45:46 +0100
Subject: [PATCH v4 10/11] KVM: arm/arm64: timer: Allow the timer to control
 the active state
In-Reply-To: <1438962347-17541-1-git-send-email-marc.zyngier@arm.com>
References: <1438962347-17541-1-git-send-email-marc.zyngier@arm.com>
Message-ID: <1438962347-17541-11-git-send-email-marc.zyngier@arm.com>

In order to remove the crude hack where we sneak the masked bit
into the timer's control register, make use of the phys_irq_map
API control the active state of the interrupt.

This causes some limited changes to allow for potential error
propagation.

Reviewed-by: Christoffer Dall <christoffer.dall at linaro.org>
Signed-off-by: Marc Zyngier <marc.zyngier at arm.com>
---
 arch/arm/kvm/reset.c         |  4 +---
 arch/arm64/kvm/reset.c       |  4 +---
 include/kvm/arm_arch_timer.h |  7 +++++--
 virt/kvm/arm/arch_timer.c    | 29 ++++++++++++++++++++++-------
 4 files changed, 29 insertions(+), 15 deletions(-)

diff --git a/arch/arm/kvm/reset.c b/arch/arm/kvm/reset.c
index f558c07..eeb85858 100644
--- a/arch/arm/kvm/reset.c
+++ b/arch/arm/kvm/reset.c
@@ -77,7 +77,5 @@ int kvm_reset_vcpu(struct kvm_vcpu *vcpu)
 	kvm_reset_coprocs(vcpu);
 
 	/* Reset arch_timer context */
-	kvm_timer_vcpu_reset(vcpu, cpu_vtimer_irq);
-
-	return 0;
+	return kvm_timer_vcpu_reset(vcpu, cpu_vtimer_irq);
 }
diff --git a/arch/arm64/kvm/reset.c b/arch/arm64/kvm/reset.c
index b4af618..91cf535 100644
--- a/arch/arm64/kvm/reset.c
+++ b/arch/arm64/kvm/reset.c
@@ -121,7 +121,5 @@ int kvm_reset_vcpu(struct kvm_vcpu *vcpu)
 	kvm_reset_sys_regs(vcpu);
 
 	/* Reset timer */
-	kvm_timer_vcpu_reset(vcpu, cpu_vtimer_irq);
-
-	return 0;
+	return kvm_timer_vcpu_reset(vcpu, cpu_vtimer_irq);
 }
diff --git a/include/kvm/arm_arch_timer.h b/include/kvm/arm_arch_timer.h
index e596675..e1e4d7c 100644
--- a/include/kvm/arm_arch_timer.h
+++ b/include/kvm/arm_arch_timer.h
@@ -52,13 +52,16 @@ struct arch_timer_cpu {
 
 	/* Timer IRQ */
 	const struct kvm_irq_level	*irq;
+
+	/* VGIC mapping */
+	struct irq_phys_map		*map;
 };
 
 int kvm_timer_hyp_init(void);
 void kvm_timer_enable(struct kvm *kvm);
 void kvm_timer_init(struct kvm *kvm);
-void kvm_timer_vcpu_reset(struct kvm_vcpu *vcpu,
-			  const struct kvm_irq_level *irq);
+int kvm_timer_vcpu_reset(struct kvm_vcpu *vcpu,
+			 const struct kvm_irq_level *irq);
 void kvm_timer_vcpu_init(struct kvm_vcpu *vcpu);
 void kvm_timer_flush_hwstate(struct kvm_vcpu *vcpu);
 void kvm_timer_sync_hwstate(struct kvm_vcpu *vcpu);
diff --git a/virt/kvm/arm/arch_timer.c b/virt/kvm/arm/arch_timer.c
index 98c95f2..76e38d2 100644
--- a/virt/kvm/arm/arch_timer.c
+++ b/virt/kvm/arm/arch_timer.c
@@ -64,10 +64,10 @@ static void kvm_timer_inject_irq(struct kvm_vcpu *vcpu)
 	int ret;
 	struct arch_timer_cpu *timer = &vcpu->arch.timer_cpu;
 
-	timer->cntv_ctl |= ARCH_TIMER_CTRL_IT_MASK;
-	ret = kvm_vgic_inject_irq(vcpu->kvm, vcpu->vcpu_id,
-				  timer->irq->irq,
-				  timer->irq->level);
+	kvm_vgic_set_phys_irq_active(timer->map, true);
+	ret = kvm_vgic_inject_mapped_irq(vcpu->kvm, vcpu->vcpu_id,
+					 timer->map,
+					 timer->irq->level);
 	WARN_ON(ret);
 }
 
@@ -117,7 +117,8 @@ bool kvm_timer_should_fire(struct kvm_vcpu *vcpu)
 	cycle_t cval, now;
 
 	if ((timer->cntv_ctl & ARCH_TIMER_CTRL_IT_MASK) ||
-		!(timer->cntv_ctl & ARCH_TIMER_CTRL_ENABLE))
+	    !(timer->cntv_ctl & ARCH_TIMER_CTRL_ENABLE) ||
+	    kvm_vgic_get_phys_irq_active(timer->map))
 		return false;
 
 	cval = timer->cntv_cval;
@@ -184,10 +185,11 @@ void kvm_timer_sync_hwstate(struct kvm_vcpu *vcpu)
 	timer_arm(timer, ns);
 }
 
-void kvm_timer_vcpu_reset(struct kvm_vcpu *vcpu,
-			  const struct kvm_irq_level *irq)
+int kvm_timer_vcpu_reset(struct kvm_vcpu *vcpu,
+			 const struct kvm_irq_level *irq)
 {
 	struct arch_timer_cpu *timer = &vcpu->arch.timer_cpu;
+	struct irq_phys_map *map;
 
 	/*
 	 * The vcpu timer irq number cannot be determined in
@@ -196,6 +198,17 @@ void kvm_timer_vcpu_reset(struct kvm_vcpu *vcpu,
 	 * vcpu timer irq number when the vcpu is reset.
 	 */
 	timer->irq = irq;
+
+	/*
+	 * Tell the VGIC that the virtual interrupt is tied to a
+	 * physical interrupt. We do that once per VCPU.
+	 */
+	map = kvm_vgic_map_phys_irq(vcpu, irq->irq, host_vtimer_irq);
+	if (WARN_ON(IS_ERR(map)))
+		return PTR_ERR(map);
+
+	timer->map = map;
+	return 0;
 }
 
 void kvm_timer_vcpu_init(struct kvm_vcpu *vcpu)
@@ -335,6 +348,8 @@ void kvm_timer_vcpu_terminate(struct kvm_vcpu *vcpu)
 	struct arch_timer_cpu *timer = &vcpu->arch.timer_cpu;
 
 	timer_disarm(timer);
+	if (timer->map)
+		kvm_vgic_unmap_phys_irq(vcpu, timer->map);
 }
 
 void kvm_timer_enable(struct kvm *kvm)
-- 
2.1.4



From gregory.clement at free-electrons.com  Fri Aug  7 09:01:41 2015
From: gregory.clement at free-electrons.com (Gregory CLEMENT)
Date: Fri, 07 Aug 2015 18:01:41 +0200
Subject: [GIT PULL] ARM: mvebu: soc changes for v4.3 #2
Message-ID: <55C4D665.8060702@free-electrons.com>

Hi,

Here is the second pull request for soc for mvebu for v4.3

Gregory

The following changes since commit 482d638f98cc626bf01d4c9f6d6d35fc77d630c8:

  ARM: mvebu: Warn about the wake-up sources not taken into account in suspend (2015-07-28 11:40:47 +0200)

are available in the git repository at:

  git://git.infradead.org/linux-mvebu.git tags/mvebu-soc-4.3-2

for you to fetch changes up to 44e259ac909f3b41786cf732a44b5cf8444e098a:

  ARM: dove: create a proper PMU driver for power domains, PMU IRQs and resets (2015-08-05 18:36:49 +0200)

----------------------------------------------------------------
mvebu soc changes for v4.3 (part #2)

SoC part of the Dove PMU series

----------------------------------------------------------------
Russell King (1):
      ARM: dove: create a proper PMU driver for power domains, PMU IRQs and resets

 arch/arm/mach-mvebu/Kconfig  |   1 +
 arch/arm/mach-mvebu/dove.c   |   2 +
 drivers/soc/Makefile         |   1 +
 drivers/soc/dove/Makefile    |   1 +
 drivers/soc/dove/pmu.c       | 412 +++++++++++++++++++++++++++++++++++++++++++
 include/linux/soc/dove/pmu.h |   6 +
 6 files changed, 423 insertions(+)
 create mode 100644 drivers/soc/dove/Makefile
 create mode 100644 drivers/soc/dove/pmu.c
 create mode 100644 include/linux/soc/dove/pmu.h

-- 
Gregory Clement, Free Electrons
Kernel, drivers, real-time and embedded Linux
development, consulting, training and support.
http://free-electrons.com




From gregory.clement at free-electrons.com  Fri Aug  7 09:01:39 2015
From: gregory.clement at free-electrons.com (Gregory CLEMENT)
Date: Fri, 07 Aug 2015 18:01:39 +0200
Subject: [GIT PULL] ARM: mvebu: dt changes for v4.3 #3
Message-ID: <55C4D663.4050508@free-electrons.com>

Hi,

Here is the third  pull request for dt for mvebu for v4.3

Gregory

he following changes since commit dc57844a736f10bf3799d63d7c0d0efc29b1ad7d:

  ARM: dts: orion5x: add buffalo linkstation ls-wtgl (2015-07-25 16:19:20 +0200)

are available in the git repository at:

  git://git.infradead.org/linux-mvebu.git tags/mvebu-dt-4.3-3

for you to fetch changes up to 15979aeeb548e020b6107214f0405be894891a57:

  ARM: dts: Convert Linkstation Mini to Device Tree (2015-08-06 18:51:29 +0200)

----------------------------------------------------------------
mvebu dt changes for v4.3 (part #3)

- device tree part of the Dove PMU series
- converting a new orion5x based platform to dt: Linkstation Mini

----------------------------------------------------------------
Benjamin Cama (1):
      ARM: dts: Convert Linkstation Mini to Device Tree

Russell King (4):
      ARM: dt: Add PMU node, making PMU child devices childs of this node
      ARM: dt: dove: wire up RTC interrupt
      ARM: dt: dove: add video decoder power domain description
      ARM: dt: dove: add GPU power domain description

 arch/arm/boot/dts/Makefile           |   1 +
 arch/arm/boot/dts/dove.dtsi          | 604 ++++++++++++++++++-----------------
 arch/arm/boot/dts/orion5x-lswsgl.dts | 276 ++++++++++++++++
 arch/arm/mach-orion5x/Kconfig        |   6 +-
 arch/arm/mach-orion5x/Makefile       |   1 -
 arch/arm/mach-orion5x/lsmini-setup.c | 280 ----------------
 6 files changed, 598 insertions(+), 570 deletions(-)
 create mode 100644 arch/arm/boot/dts/orion5x-lswsgl.dts
 delete mode 100644 arch/arm/mach-orion5x/lsmini-setup.c
-- 
Gregory Clement, Free Electrons
Kernel, drivers, real-time and embedded Linux
development, consulting, training and support.
http://free-electrons.com




From eric.auger at linaro.org  Fri Aug  7 09:08:29 2015
From: eric.auger at linaro.org (Eric Auger)
Date: Fri,  7 Aug 2015 18:08:29 +0200
Subject: [PATCH v2 0/4] KVM: arm/arm64: guest synchronous halt/resume
Message-ID: <1438963713-10460-1-git-send-email-eric.auger@linaro.org>

This series introduces the capability to synchronously exit the guest
and prevent it from being re-entered. This modality will be used by
IRQ forwarding series when changing the state of the IRQ.

Former pause flag used when starting the vcpu in KVM_ARM_VCPU_POWER_OFF
state, in PSCI calls and in KVM_SET_MP_STATE ioctl is renamed into
power_off. A new pause flag is introduced. Both now are checked in
kvm_arch_vcpu_runnable and in the VCPU_RUN critical section, before
entering the vcpu.

Best Regards

Eric

History:

v1 -> v2:
- check pause, power_off and in kvm_arch_vcpu_runnable
- check power_off in vcpu_run critcal section before guest entry
- correct compil issue in first patch reported by Andrew
- rename vcpu_pause into vcpu_sleep

RFC -> PATCH v1:
- originally part of [RFC 00/17] ARM IRQ forward control based on IRQ
  bypass manager (https://lkml.org/lkml/2015/7/2/268) and isolated in
  this series.
- added __maybe_unused following Marc's advice


Eric Auger (4):
  KVM: arm/arm64: rename pause into power_off
  KVM: arm/arm64: check power_off in kvm_arch_vcpu_runnable
  KVM: arm/arm64: check power_off in critical section before VCPU run
  KVM: arm/arm64: implement kvm_arm_[halt,resume]_guest

 arch/arm/include/asm/kvm_host.h   |  5 +++-
 arch/arm/kvm/arm.c                | 53 ++++++++++++++++++++++++++++++---------
 arch/arm/kvm/psci.c               | 10 ++++----
 arch/arm64/include/asm/kvm_host.h |  3 +++
 4 files changed, 53 insertions(+), 18 deletions(-)

-- 
1.9.1



From eric.auger at linaro.org  Fri Aug  7 09:08:31 2015
From: eric.auger at linaro.org (Eric Auger)
Date: Fri,  7 Aug 2015 18:08:31 +0200
Subject: [PATCH v2 2/4] KVM: arm/arm64: check power_off in
 kvm_arch_vcpu_runnable
In-Reply-To: <1438963713-10460-1-git-send-email-eric.auger@linaro.org>
References: <1438963713-10460-1-git-send-email-eric.auger@linaro.org>
Message-ID: <1438963713-10460-3-git-send-email-eric.auger@linaro.org>

kvm_arch_vcpu_runnable now also checks whether the power_off
flag is set.

Signed-off-by: Eric Auger <eric.auger at linaro.org>
---
 arch/arm/kvm/arm.c | 3 ++-
 1 file changed, 2 insertions(+), 1 deletion(-)

diff --git a/arch/arm/kvm/arm.c b/arch/arm/kvm/arm.c
index 3ac6b4c..4f50be3 100644
--- a/arch/arm/kvm/arm.c
+++ b/arch/arm/kvm/arm.c
@@ -347,7 +347,8 @@ int kvm_arch_vcpu_ioctl_set_mpstate(struct kvm_vcpu *vcpu,
  */
 int kvm_arch_vcpu_runnable(struct kvm_vcpu *v)
 {
-	return !!v->arch.irq_lines || kvm_vgic_vcpu_pending_irq(v);
+	return ((!!v->arch.irq_lines || kvm_vgic_vcpu_pending_irq(v))
+		&& !v->arch.power_off);
 }
 
 /* Just ensure a guest exit from a particular CPU */
-- 
1.9.1



From eric.auger at linaro.org  Fri Aug  7 09:08:30 2015
From: eric.auger at linaro.org (Eric Auger)
Date: Fri,  7 Aug 2015 18:08:30 +0200
Subject: [PATCH v2 1/4] KVM: arm/arm64: rename pause into power_off
In-Reply-To: <1438963713-10460-1-git-send-email-eric.auger@linaro.org>
References: <1438963713-10460-1-git-send-email-eric.auger@linaro.org>
Message-ID: <1438963713-10460-2-git-send-email-eric.auger@linaro.org>

The kvm_vcpu_arch pause field is renamed into power_off to prepare
for the introduction of a new pause field. Also vcpu_pause is renamed
into vcpu_sleep since we will sleep until both power_off and pause are
false.

Signed-off-by: Eric Auger <eric.auger at linaro.org>

---

v1 -> v2:
- rename pause in kvm_arch_vcpu_ioctl_[set,get]_mpstate
- rename vcpu_pause into vcpu_sleep
---
 arch/arm/include/asm/kvm_host.h   |  4 ++--
 arch/arm/kvm/arm.c                | 20 ++++++++++----------
 arch/arm/kvm/psci.c               | 10 +++++-----
 arch/arm64/include/asm/kvm_host.h |  4 ++--
 4 files changed, 19 insertions(+), 19 deletions(-)

diff --git a/arch/arm/include/asm/kvm_host.h b/arch/arm/include/asm/kvm_host.h
index e896d2c..304004d 100644
--- a/arch/arm/include/asm/kvm_host.h
+++ b/arch/arm/include/asm/kvm_host.h
@@ -129,8 +129,8 @@ struct kvm_vcpu_arch {
 	 * here.
 	 */
 
-	/* Don't run the guest on this vcpu */
-	bool pause;
+	/* vcpu power-off state */
+	bool power_off;
 
 	/* IO related fields */
 	struct kvm_decode mmio_decode;
diff --git a/arch/arm/kvm/arm.c b/arch/arm/kvm/arm.c
index b598aa4..3ac6b4c 100644
--- a/arch/arm/kvm/arm.c
+++ b/arch/arm/kvm/arm.c
@@ -313,7 +313,7 @@ int kvm_arch_vcpu_ioctl_set_guest_debug(struct kvm_vcpu *vcpu,
 int kvm_arch_vcpu_ioctl_get_mpstate(struct kvm_vcpu *vcpu,
 				    struct kvm_mp_state *mp_state)
 {
-	if (vcpu->arch.pause)
+	if (vcpu->arch.power_off)
 		mp_state->mp_state = KVM_MP_STATE_STOPPED;
 	else
 		mp_state->mp_state = KVM_MP_STATE_RUNNABLE;
@@ -326,10 +326,10 @@ int kvm_arch_vcpu_ioctl_set_mpstate(struct kvm_vcpu *vcpu,
 {
 	switch (mp_state->mp_state) {
 	case KVM_MP_STATE_RUNNABLE:
-		vcpu->arch.pause = false;
+		vcpu->arch.power_off = false;
 		break;
 	case KVM_MP_STATE_STOPPED:
-		vcpu->arch.pause = true;
+		vcpu->arch.power_off = true;
 		break;
 	default:
 		return -EINVAL;
@@ -473,11 +473,11 @@ bool kvm_arch_intc_initialized(struct kvm *kvm)
 	return vgic_initialized(kvm);
 }
 
-static void vcpu_pause(struct kvm_vcpu *vcpu)
+static void vcpu_sleep(struct kvm_vcpu *vcpu)
 {
 	wait_queue_head_t *wq = kvm_arch_vcpu_wq(vcpu);
 
-	wait_event_interruptible(*wq, !vcpu->arch.pause);
+	wait_event_interruptible(*wq, !vcpu->arch.power_off);
 }
 
 static int kvm_vcpu_initialized(struct kvm_vcpu *vcpu)
@@ -527,8 +527,8 @@ int kvm_arch_vcpu_ioctl_run(struct kvm_vcpu *vcpu, struct kvm_run *run)
 
 		update_vttbr(vcpu->kvm);
 
-		if (vcpu->arch.pause)
-			vcpu_pause(vcpu);
+		if (vcpu->arch.power_off)
+			vcpu_sleep(vcpu);
 
 		/*
 		 * Disarming the background timer must be done in a
@@ -766,12 +766,12 @@ static int kvm_arch_vcpu_ioctl_vcpu_init(struct kvm_vcpu *vcpu,
 	vcpu_reset_hcr(vcpu);
 
 	/*
-	 * Handle the "start in power-off" case by marking the VCPU as paused.
+	 * Handle the "start in power-off" case.
 	 */
 	if (test_bit(KVM_ARM_VCPU_POWER_OFF, vcpu->arch.features))
-		vcpu->arch.pause = true;
+		vcpu->arch.power_off = true;
 	else
-		vcpu->arch.pause = false;
+		vcpu->arch.power_off = false;
 
 	return 0;
 }
diff --git a/arch/arm/kvm/psci.c b/arch/arm/kvm/psci.c
index 4b94b51..134971a 100644
--- a/arch/arm/kvm/psci.c
+++ b/arch/arm/kvm/psci.c
@@ -63,7 +63,7 @@ static unsigned long kvm_psci_vcpu_suspend(struct kvm_vcpu *vcpu)
 
 static void kvm_psci_vcpu_off(struct kvm_vcpu *vcpu)
 {
-	vcpu->arch.pause = true;
+	vcpu->arch.power_off = true;
 }
 
 static unsigned long kvm_psci_vcpu_on(struct kvm_vcpu *source_vcpu)
@@ -87,7 +87,7 @@ static unsigned long kvm_psci_vcpu_on(struct kvm_vcpu *source_vcpu)
 	 */
 	if (!vcpu)
 		return PSCI_RET_INVALID_PARAMS;
-	if (!vcpu->arch.pause) {
+	if (!vcpu->arch.power_off) {
 		if (kvm_psci_version(source_vcpu) != KVM_ARM_PSCI_0_1)
 			return PSCI_RET_ALREADY_ON;
 		else
@@ -115,7 +115,7 @@ static unsigned long kvm_psci_vcpu_on(struct kvm_vcpu *source_vcpu)
 	 * the general puspose registers are undefined upon CPU_ON.
 	 */
 	*vcpu_reg(vcpu, 0) = context_id;
-	vcpu->arch.pause = false;
+	vcpu->arch.power_off = false;
 	smp_mb();		/* Make sure the above is visible */
 
 	wq = kvm_arch_vcpu_wq(vcpu);
@@ -152,7 +152,7 @@ static unsigned long kvm_psci_vcpu_affinity_info(struct kvm_vcpu *vcpu)
 	kvm_for_each_vcpu(i, tmp, kvm) {
 		mpidr = kvm_vcpu_get_mpidr_aff(tmp);
 		if (((mpidr & target_affinity_mask) == target_affinity) &&
-		    !tmp->arch.pause) {
+		    !tmp->arch.power_off) {
 			return PSCI_0_2_AFFINITY_LEVEL_ON;
 		}
 	}
@@ -175,7 +175,7 @@ static void kvm_prepare_system_event(struct kvm_vcpu *vcpu, u32 type)
 	 * re-initialized.
 	 */
 	kvm_for_each_vcpu(i, tmp, vcpu->kvm) {
-		tmp->arch.pause = true;
+		tmp->arch.power_off = true;
 		kvm_vcpu_kick(tmp);
 	}
 
diff --git a/arch/arm64/include/asm/kvm_host.h b/arch/arm64/include/asm/kvm_host.h
index 2709db2..009da6b 100644
--- a/arch/arm64/include/asm/kvm_host.h
+++ b/arch/arm64/include/asm/kvm_host.h
@@ -122,8 +122,8 @@ struct kvm_vcpu_arch {
 	 * here.
 	 */
 
-	/* Don't run the guest */
-	bool pause;
+	/* vcpu power-off state */
+	bool power_off;
 
 	/* IO related fields */
 	struct kvm_decode mmio_decode;
-- 
1.9.1



From eric.auger at linaro.org  Fri Aug  7 09:08:32 2015
From: eric.auger at linaro.org (Eric Auger)
Date: Fri,  7 Aug 2015 18:08:32 +0200
Subject: [PATCH v2 3/4] KVM: arm/arm64: check power_off in critical section
 before VCPU run
In-Reply-To: <1438963713-10460-1-git-send-email-eric.auger@linaro.org>
References: <1438963713-10460-1-git-send-email-eric.auger@linaro.org>
Message-ID: <1438963713-10460-4-git-send-email-eric.auger@linaro.org>

In case KVM_SET_MP_STATE ioctl is called just after we executed the
vcpu_sleep check, we can enter the guest although KVM_MP_STATE_STOPPED
is set. Let's check the power_off state in the critical section,
just before entering the guest.

Signed-off-by: Eric Auger <eric.auger at linaro.org>
Reported-by: Christoffer Dall <christoffer.dall at linaro.org>
---
 arch/arm/kvm/arm.c | 3 ++-
 1 file changed, 2 insertions(+), 1 deletion(-)

diff --git a/arch/arm/kvm/arm.c b/arch/arm/kvm/arm.c
index 4f50be3..cc404a8 100644
--- a/arch/arm/kvm/arm.c
+++ b/arch/arm/kvm/arm.c
@@ -555,7 +555,8 @@ int kvm_arch_vcpu_ioctl_run(struct kvm_vcpu *vcpu, struct kvm_run *run)
 			run->exit_reason = KVM_EXIT_INTR;
 		}
 
-		if (ret <= 0 || need_new_vmid_gen(vcpu->kvm)) {
+		if (ret <= 0 || need_new_vmid_gen(vcpu->kvm) ||
+			vcpu->arch.power_off) {
 			local_irq_enable();
 			kvm_vgic_sync_hwstate(vcpu);
 			preempt_enable();
-- 
1.9.1



From eric.auger at linaro.org  Fri Aug  7 09:08:33 2015
From: eric.auger at linaro.org (Eric Auger)
Date: Fri,  7 Aug 2015 18:08:33 +0200
Subject: [PATCH v2 4/4] KVM: arm/arm64: implement kvm_arm_[halt,resume]_guest
In-Reply-To: <1438963713-10460-1-git-send-email-eric.auger@linaro.org>
References: <1438963713-10460-1-git-send-email-eric.auger@linaro.org>
Message-ID: <1438963713-10460-5-git-send-email-eric.auger@linaro.org>

We introduce kvm_arm_halt_guest and resume functions. They
will be used for IRQ forward state change.

Halt is synchronous and prevents the guest from being re-entered.
We use the same mechanism put in place for PSCI former pause,
now renamed power_off. A new flag is introduced in arch vcpu state,
pause, only meant to be used by those functions.

Signed-off-by: Eric Auger <eric.auger at linaro.org>

---
v1 -> v2:
- check pause in kvm_arch_vcpu_runnable
- we cannot use kvm_vcpu_block since this latter would exit on
  IRQ/FIQ and this is not what we want
---
 arch/arm/include/asm/kvm_host.h   |  3 +++
 arch/arm/kvm/arm.c                | 35 +++++++++++++++++++++++++++++++----
 arch/arm64/include/asm/kvm_host.h |  3 +++
 3 files changed, 37 insertions(+), 4 deletions(-)

diff --git a/arch/arm/include/asm/kvm_host.h b/arch/arm/include/asm/kvm_host.h
index 304004d..dac85f6 100644
--- a/arch/arm/include/asm/kvm_host.h
+++ b/arch/arm/include/asm/kvm_host.h
@@ -132,6 +132,9 @@ struct kvm_vcpu_arch {
 	/* vcpu power-off state */
 	bool power_off;
 
+	 /* Exit and don't run the guest (internal implementation need) */
+	bool pause;
+
 	/* IO related fields */
 	struct kvm_decode mmio_decode;
 
diff --git a/arch/arm/kvm/arm.c b/arch/arm/kvm/arm.c
index cc404a8..0529b38 100644
--- a/arch/arm/kvm/arm.c
+++ b/arch/arm/kvm/arm.c
@@ -348,7 +348,7 @@ int kvm_arch_vcpu_ioctl_set_mpstate(struct kvm_vcpu *vcpu,
 int kvm_arch_vcpu_runnable(struct kvm_vcpu *v)
 {
 	return ((!!v->arch.irq_lines || kvm_vgic_vcpu_pending_irq(v))
-		&& !v->arch.power_off);
+		&& !v->arch.power_off && !v->arch.pause);
 }
 
 /* Just ensure a guest exit from a particular CPU */
@@ -474,11 +474,38 @@ bool kvm_arch_intc_initialized(struct kvm *kvm)
 	return vgic_initialized(kvm);
 }
 
+static void kvm_arm_halt_guest(struct kvm *kvm) __maybe_unused;
+static void kvm_arm_resume_guest(struct kvm *kvm) __maybe_unused;
+
+static void kvm_arm_halt_guest(struct kvm *kvm)
+{
+	int i;
+	struct kvm_vcpu *vcpu;
+
+	kvm_for_each_vcpu(i, vcpu, kvm)
+		vcpu->arch.pause = true;
+	force_vm_exit(cpu_all_mask);
+}
+
+static void kvm_arm_resume_guest(struct kvm *kvm)
+{
+	int i;
+	struct kvm_vcpu *vcpu;
+
+	kvm_for_each_vcpu(i, vcpu, kvm) {
+		wait_queue_head_t *wq = kvm_arch_vcpu_wq(vcpu);
+
+		vcpu->arch.pause = false;
+		wake_up_interruptible(wq);
+	}
+}
+
 static void vcpu_sleep(struct kvm_vcpu *vcpu)
 {
 	wait_queue_head_t *wq = kvm_arch_vcpu_wq(vcpu);
 
-	wait_event_interruptible(*wq, !vcpu->arch.power_off);
+	wait_event_interruptible(*wq, ((!vcpu->arch.power_off) &&
+				       (!vcpu->arch.pause)));
 }
 
 static int kvm_vcpu_initialized(struct kvm_vcpu *vcpu)
@@ -528,7 +555,7 @@ int kvm_arch_vcpu_ioctl_run(struct kvm_vcpu *vcpu, struct kvm_run *run)
 
 		update_vttbr(vcpu->kvm);
 
-		if (vcpu->arch.power_off)
+		if (vcpu->arch.power_off || vcpu->arch.pause)
 			vcpu_sleep(vcpu);
 
 		/*
@@ -556,7 +583,7 @@ int kvm_arch_vcpu_ioctl_run(struct kvm_vcpu *vcpu, struct kvm_run *run)
 		}
 
 		if (ret <= 0 || need_new_vmid_gen(vcpu->kvm) ||
-			vcpu->arch.power_off) {
+			vcpu->arch.power_off || vcpu->arch.pause) {
 			local_irq_enable();
 			kvm_vgic_sync_hwstate(vcpu);
 			preempt_enable();
diff --git a/arch/arm64/include/asm/kvm_host.h b/arch/arm64/include/asm/kvm_host.h
index 009da6b..69e3785 100644
--- a/arch/arm64/include/asm/kvm_host.h
+++ b/arch/arm64/include/asm/kvm_host.h
@@ -125,6 +125,9 @@ struct kvm_vcpu_arch {
 	/* vcpu power-off state */
 	bool power_off;
 
+	/* Don't run the guest */
+	bool pause;
+
 	/* IO related fields */
 	struct kvm_decode mmio_decode;
 
-- 
1.9.1



From wsa at the-dreams.de  Fri Aug  7 09:10:55 2015
From: wsa at the-dreams.de (Wolfram Sang)
Date: Fri, 7 Aug 2015 18:10:55 +0200
Subject: [PATCH 0/8] misc: remove boundary checks from bin attr users
In-Reply-To: <1437945502-27944-1-git-send-email-vz@mleia.com>
References: <1437945502-27944-1-git-send-email-vz@mleia.com>
Message-ID: <20150807161055.GD25357@katana>

Vladimir,

On Mon, Jul 27, 2015 at 12:18:22AM +0300, Vladimir Zapolskiy wrote:
> This change removes a number of redundant checks on bin attribute
> client's side, the same checks are done by sysfs_kf_bin_read() or
> sysfs_kf_bin_write() caller from fs/sysfs/file.c.
> 
> Note, drivers/misc/pch_phub.c and drivers/misc/c2port/core.c may be
> updated in a similar way, however this task is not done due to more
> complicated read()/write() callbacks.

Can you resend the patches which touch i2c drivers with me on cc? I'd
like to take care of them.

Thanks,

   Wolfram

-------------- next part --------------
A non-text attachment was scrubbed...
Name: signature.asc
Type: application/pgp-signature
Size: 819 bytes
Desc: Digital signature
URL: <http://lists.infradead.org/pipermail/linux-arm-kernel/attachments/20150807/fe9bc9a6/attachment.sig>

From khilman at kernel.org  Fri Aug  7 09:13:35 2015
From: khilman at kernel.org (Kevin Hilman)
Date: Fri, 07 Aug 2015 09:13:35 -0700
Subject: [PATCH v9 0/9] Add simple NVMEM Framework via regmap.
In-Reply-To: <1437995567-11203-1-git-send-email-srinivas.kandagatla@linaro.org>
 (Srinivas Kandagatla's message of "Mon, 27 Jul 2015 12:12:47 +0100")
References: <1437995567-11203-1-git-send-email-srinivas.kandagatla@linaro.org>
Message-ID: <7hwpx7vzyo.fsf@deeprootsystems.com>

Srinivas Kandagatla <srinivas.kandagatla at linaro.org> writes:

> This patchset adds a new simple NVMEM framework to kernel, and it is tested
> with various drivers like "QCOM thermal sensors", "QCOM cpr driver",
> "begal bone cape manager" and few more on the way.
>
> Can you please consider this as 4.3 material, AFAIK there are more than 3 drivers
> depending on this framework which are wating since last 2 merge windows.
>
> Should these patches go via ARM-SOC tree or via Greg's tree?

With Greg's ack, we can take this through the arm-soc tree (unless Greg
wants to queue it, which is fine also.)

Can you collect the final Tested-by's and prepare a pull request?

Thanks,

Kevin


From vz at mleia.com  Fri Aug  7 09:15:46 2015
From: vz at mleia.com (Vladimir Zapolskiy)
Date: Fri, 07 Aug 2015 19:15:46 +0300
Subject: [PATCH 0/8] misc: remove boundary checks from bin attr users
In-Reply-To: <20150807161055.GD25357@katana>
References: <1437945502-27944-1-git-send-email-vz@mleia.com>
 <20150807161055.GD25357@katana>
Message-ID: <55C4D9B2.3000708@mleia.com>

Hi Wolfram,

On 07.08.2015 19:10, Wolfram Sang wrote:
> Vladimir,
> 
> On Mon, Jul 27, 2015 at 12:18:22AM +0300, Vladimir Zapolskiy wrote:
>> This change removes a number of redundant checks on bin attribute
>> client's side, the same checks are done by sysfs_kf_bin_read() or
>> sysfs_kf_bin_write() caller from fs/sysfs/file.c.
>>
>> Note, drivers/misc/pch_phub.c and drivers/misc/c2port/core.c may be
>> updated in a similar way, however this task is not done due to more
>> complicated read()/write() callbacks.
> 
> Can you resend the patches which touch i2c drivers with me on cc? I'd
> like to take care of them.

if we're talking about this particular series, you should have them in
your mailbox, since you have them applied in wsa/i2c/for-next:

commit d12c0aaf3780c5b26b4ea9e795252381f586c063
Author: Vladimir Zapolskiy <vz at mleia.com>
Date:   Mon Jul 27 00:18:51 2015 +0300

    misc: eeprom: at24: clean up at24_bin_write()

    The change removes redundant sysfs binary file boundary check, since
    this task is already done on caller side in fs/sysfs/file.c

    Signed-off-by: Vladimir Zapolskiy <vz at mleia.com>
    Signed-off-by: Wolfram Sang <wsa at the-dreams.de>

commit 1f023297f7f77d434ecc221018d2e181eac0ae36
Author: Vladimir Zapolskiy <vz at mleia.com>
Date:   Mon Jul 27 00:16:31 2015 +0300

    i2c: slave eeprom: clean up sysfs bin attribute read()/write()

    The change removes redundant sysfs binary file boundary checks,
    since this task is already done on caller side in fs/sysfs/file.c

    Note, on file size overflow read() now returns 0, and this is a
    correct and expected EOF notification according to POSIX.

    Signed-off-by: Vladimir Zapolskiy <vz at mleia.com>
    Signed-off-by: Wolfram Sang <wsa at the-dreams.de>


Do you want me to send them to you again anyway?

--
With best wishes,
Vladimir


From eric.auger at linaro.org  Fri Aug  7 09:17:05 2015
From: eric.auger at linaro.org (Eric Auger)
Date: Fri, 07 Aug 2015 18:17:05 +0200
Subject: [PATCH 2/2] kvm: arm/arm64: implement kvm_arm_[halt, resume]_guest
In-Reply-To: <20150718091851.GO14024@cbox>
References: <1436186996-22528-1-git-send-email-eric.auger@linaro.org>
 <1436186996-22528-3-git-send-email-eric.auger@linaro.org>
 <20150718091851.GO14024@cbox>
Message-ID: <55C4DA01.7040603@linaro.org>

Hi Chistoffer,
On 07/18/2015 11:18 AM, Christoffer Dall wrote:
> On Mon, Jul 06, 2015 at 02:49:56PM +0200, Eric Auger wrote:
>> On halt, the guest is forced to exit and prevented from being
>> re-entered. This is synchronous.
>>
>> Those two operations will be needed for IRQ forwarding setting.
>>
>> Signed-off-by: Eric Auger <eric.auger at linaro.org>
>>
>> ---
>> RFC v1 -> v2:
>> - add __maybe_unused
>>
>> RFC:
>> - rename the function and this latter becomes static
>> - remove __KVM_HAVE_ARCH_HALT_GUEST
>>
>> v4 -> v5: add arm64 support
>> - also defines __KVM_HAVE_ARCH_HALT_GUEST for arm64
>> - add pause field
>> ---
>>  arch/arm/include/asm/kvm_host.h   |  3 +++
>>  arch/arm/kvm/arm.c                | 35 ++++++++++++++++++++++++++++++++---
>>  arch/arm64/include/asm/kvm_host.h |  3 +++
>>  3 files changed, 38 insertions(+), 3 deletions(-)
>>
>> diff --git a/arch/arm/include/asm/kvm_host.h b/arch/arm/include/asm/kvm_host.h
>> index 304004d..899ae27 100644
>> --- a/arch/arm/include/asm/kvm_host.h
>> +++ b/arch/arm/include/asm/kvm_host.h
>> @@ -132,6 +132,9 @@ struct kvm_vcpu_arch {
>>  	/* vcpu power-off state */
>>  	bool power_off;
>>  
>> +	/* Don't run the guest */
>> +	bool pause;
>> +
>>  	/* IO related fields */
>>  	struct kvm_decode mmio_decode;
>>  
>> diff --git a/arch/arm/kvm/arm.c b/arch/arm/kvm/arm.c
>> index 7537e68..46d4ef6 100644
>> --- a/arch/arm/kvm/arm.c
>> +++ b/arch/arm/kvm/arm.c
>> @@ -471,11 +471,39 @@ bool kvm_arch_intc_initialized(struct kvm *kvm)
>>  	return vgic_initialized(kvm);
>>  }
>>  
>> +static void kvm_arm_halt_guest(struct kvm *kvm) __maybe_unused;
>> +static void kvm_arm_resume_guest(struct kvm *kvm) __maybe_unused;
>> +
>> +static void kvm_arm_halt_guest(struct kvm *kvm)
>> +{
>> +	int i;
>> +	struct kvm_vcpu *vcpu;
>> +
>> +	kvm_for_each_vcpu(i, vcpu, kvm)
>> +		vcpu->arch.pause = true;
>> +	force_vm_exit(cpu_all_mask);
>> +}
>> +
>> +static void kvm_arm_resume_guest(struct kvm *kvm)
>> +{
>> +	int i;
>> +	struct kvm_vcpu *vcpu;
>> +
>> +	kvm_for_each_vcpu(i, vcpu, kvm) {
>> +		wait_queue_head_t *wq = kvm_arch_vcpu_wq(vcpu);
>> +
>> +		vcpu->arch.pause = false;
>> +		wake_up_interruptible(wq);
>> +	}
>> +}
>> +
>> +
>>  static void vcpu_pause(struct kvm_vcpu *vcpu)
>>  {
>>  	wait_queue_head_t *wq = kvm_arch_vcpu_wq(vcpu);
>>  
>> -	wait_event_interruptible(*wq, !vcpu->arch.power_off);
>> +	wait_event_interruptible(*wq, ((!vcpu->arch.power_off) &&
>> +				       (!vcpu->arch.pause)));
>>  }
>>  
>>  static int kvm_vcpu_initialized(struct kvm_vcpu *vcpu)
>> @@ -525,7 +553,7 @@ int kvm_arch_vcpu_ioctl_run(struct kvm_vcpu *vcpu, struct kvm_run *run)
>>  
>>  		update_vttbr(vcpu->kvm);
>>  
>> -		if (vcpu->arch.power_off)
>> +		if (vcpu->arch.power_off || vcpu->arch.pause)
>>  			vcpu_pause(vcpu);
> 
> These two changes really make me feel like kvm_arch_vcpu_runnable()
> should be changed to check for both flags and all thes eplaces should
> check for runnable instead.
> 
> To make the runnable function more robust, perhaps it should check:
> 
> 1. The vcpu is neither paused nor powered off
> 2. The vcpu is not in a WFI state (vcpu->arch.wfi_request) OR there are
>    pending interrupts (the current check).

I did not understand what you meant by this vcpu->arch.wfi_request,
which I could not find. In case we call runnable from
kvm_vcpu_block/kvm_vcpu_check_block we sometimes are in WFI
(kvm_handle_wfx)?

Thanks

Eric
> 
> Then the logic would fit the name of the function, instead of being a
> specific check only called through handle_wfx.
> 
>>  
>>  		/*
>> @@ -551,7 +579,8 @@ int kvm_arch_vcpu_ioctl_run(struct kvm_vcpu *vcpu, struct kvm_run *run)
>>  			run->exit_reason = KVM_EXIT_INTR;
>>  		}
>>  
>> -		if (ret <= 0 || need_new_vmid_gen(vcpu->kvm)) {
>> +		if (ret <= 0 || need_new_vmid_gen(vcpu->kvm) ||
>> +		    vcpu->arch.pause) {
> 
> so why do we need to re-check the pause flag, but not the power_off
> flag?  That is non-trivial for sure, so if it's correct, deserves a
> comment.  Also see my comment on the last patch.
> 
>>  			local_irq_enable();
>>  			preempt_enable();
>>  			kvm_vgic_sync_hwstate(vcpu);
>> diff --git a/arch/arm64/include/asm/kvm_host.h b/arch/arm64/include/asm/kvm_host.h
>> index 009da6b..69e3785 100644
>> --- a/arch/arm64/include/asm/kvm_host.h
>> +++ b/arch/arm64/include/asm/kvm_host.h
>> @@ -125,6 +125,9 @@ struct kvm_vcpu_arch {
>>  	/* vcpu power-off state */
>>  	bool power_off;
>>  
>> +	/* Don't run the guest */
> 
> Probably need to be more clear about this being an implementation
> requirement rather than being guest visible or related to any
> architectural concept.
> 
>> +	bool pause;
>> +
>>  	/* IO related fields */
>>  	struct kvm_decode mmio_decode;
>>  
>> -- 
>> 1.9.1
>>
> 
> Thanks,
> -Christoffer
> 



From srinivas.kandagatla at linaro.org  Fri Aug  7 09:18:10 2015
From: srinivas.kandagatla at linaro.org (Srinivas Kandagatla)
Date: Fri, 07 Aug 2015 17:18:10 +0100
Subject: [PATCH v9 0/9] Add simple NVMEM Framework via regmap.
In-Reply-To: <7hwpx7vzyo.fsf@deeprootsystems.com>
References: <1437995567-11203-1-git-send-email-srinivas.kandagatla@linaro.org>
 <7hwpx7vzyo.fsf@deeprootsystems.com>
Message-ID: <55C4DA42.909@linaro.org>

Thanks Kevin,

On 07/08/15 17:13, Kevin Hilman wrote:
> Srinivas Kandagatla <srinivas.kandagatla at linaro.org> writes:
>
>> This patchset adds a new simple NVMEM framework to kernel, and it is tested
>> with various drivers like "QCOM thermal sensors", "QCOM cpr driver",
>> "begal bone cape manager" and few more on the way.
>>
>> Can you please consider this as 4.3 material, AFAIK there are more than 3 drivers
>> depending on this framework which are wating since last 2 merge windows.
>>
>> Should these patches go via ARM-SOC tree or via Greg's tree?
>
> With Greg's ack, we can take this through the arm-soc tree (unless Greg
> wants to queue it, which is fine also.)
>

Greg already merged these patches yesterday on to 
git://git.kernel.org/pub/scm/linux/kernel/git/gregkh/char-misc.git
in the char-misc-next branch.

Now the patches are available in linux-next for more testing.

--srini
> Can you collect the final Tested-by's and prepare a pull request?
>
> Thanks,
>
> Kevin
>


From wens at csie.org  Fri Aug  7 09:21:17 2015
From: wens at csie.org (Chen-Yu Tsai)
Date: Sat, 8 Aug 2015 00:21:17 +0800
Subject: [PATCH v2 5/7] ARM: sun8i: Add clock indices
In-Reply-To: <1438364782-3968-6-git-send-email-maxime.ripard@free-electrons.com>
References: <1438364782-3968-1-git-send-email-maxime.ripard@free-electrons.com>
 <1438364782-3968-6-git-send-email-maxime.ripard@free-electrons.com>
Message-ID: <CAGb2v64nvA1K=Ya7_99-2G1LtFjcuj+qQbO1GJaqsL+yPF+Xdw@mail.gmail.com>

On Sat, Aug 1, 2015 at 1:46 AM, Maxime Ripard
<maxime.ripard at free-electrons.com> wrote:
> The A23 and A33 gates have a non continuous set of clock IDs that are
> valid. Add the clock-indices property to the DT to express this.
>
> Signed-off-by: Maxime Ripard <maxime.ripard at free-electrons.com>
> ---
>  arch/arm/boot/dts/sun8i-a23-a33.dtsi | 15 +++++++++++++++
>  1 file changed, 15 insertions(+)
>
> diff --git a/arch/arm/boot/dts/sun8i-a23-a33.dtsi b/arch/arm/boot/dts/sun8i-a23-a33.dtsi
> index 7abd0ae3143d..c318c770b6c1 100644
> --- a/arch/arm/boot/dts/sun8i-a23-a33.dtsi
> +++ b/arch/arm/boot/dts/sun8i-a23-a33.dtsi
> @@ -180,6 +180,15 @@
>                         compatible = "allwinner,sun8i-a23-ahb1-gates-clk";
>                         reg = <0x01c20060 0x8>;
>                         clocks = <&ahb1>;
> +                       clock-indices = <1>, <6>,

Turns out the A33 (and I assume the same with the A23) has
an ahb1 clock gate for the Security System at clock-index <5>.

This is found in the updated A33 user manual.

> +                                       <8>, <9>, <10>,
> +                                       <13>, <14>,
> +                                       <19>, <20>,
> +                                       <21>, <24>, <26>,
> +                                       <29>, <32>, <36>,
> +                                       <40>, <44>, <46>,
> +                                       <52>, <54>,

<53> is ahb1 clock gate for msgbox, again found in A33 manual.

> +                                       <57>;

<58> is ahb1 clock gate for SAT, which seems to be part of the
display pipeline.

>                         clock-output-names = "ahb1_mipidsi", "ahb1_dma",
>                                         "ahb1_mmc0", "ahb1_mmc1", "ahb1_mmc2",
>                                         "ahb1_nand", "ahb1_sdram",
> @@ -196,6 +205,8 @@
>                         compatible = "allwinner,sun8i-a23-apb1-gates-clk";
>                         reg = <0x01c20068 0x4>;
>                         clocks = <&apb1>;
> +                       clock-indices = <0>, <5>,
> +                                       <12>, <13>;
>                         clock-output-names = "apb1_codec", "apb1_pio",
>                                         "apb1_daudio0", "apb1_daudio1";
>                 };
> @@ -213,6 +224,10 @@
>                         compatible = "allwinner,sun8i-a23-apb2-gates-clk";
>                         reg = <0x01c2006c 0x4>;
>                         clocks = <&apb2>;
> +                       clock-indices = <0>, <1>,
> +                                       <2>, <16>,
> +                                       <17>, <18>,
> +                                       <19>, <20>;
>                         clock-output-names = "apb2_i2c0", "apb2_i2c1",
>                                         "apb2_i2c2", "apb2_uart0",
>                                         "apb2_uart1", "apb2_uart2",
> --
> 2.4.6
>

Not sure if you want to add the clocks I mentioned together
in this patch, or do a separate patch.

The rest look good.

ChenYu


From alexandre.belloni at free-electrons.com  Fri Aug  7 09:27:54 2015
From: alexandre.belloni at free-electrons.com (Alexandre Belloni)
Date: Fri, 7 Aug 2015 18:27:54 +0200
Subject: [GIT PULL] at91: defconfig for 4.3 #2
Message-ID: <20150807162754.GA20169@piout.net>

Arnd, Olof, Kevin,

A little defconfig update. That will probably be all for this cycle.

Thanks, bye,


The following changes since commit eff7f41572a645bf14a96a6f844be4f1c88cd9dd:

  ARM: at91: at91_dt_defconfig: enable ISI and ov2640 support (2015-07-30 14:17:31 +0200)

are available in the git repository at:

  git://git.kernel.org/pub/scm/linux/kernel/git/abelloni/linux.git tags/at91-ab-defconfig2

for you to fetch changes up to ea7bf603fd494391acc1f42acbfc34260b965c44:

  ARM: at91/defconfig: at91_dt: remove ARM_AT91_ETHER (2015-08-07 12:07:50 +0200)

----------------------------------------------------------------
Second batch of defconfig update for 4.3:
- enable the HLCDC driver for at91sam9
- remove an obsolete config option

----------------------------------------------------------------
Alexandre Belloni (1):
      ARM: at91/defconfig: at91_dt: remove ARM_AT91_ETHER

Josh Wu (1):
      ARM: at91/defconfig: at91_dt: enable DRM hlcdc support

 arch/arm/configs/at91_dt_defconfig | 7 ++++++-
 1 file changed, 6 insertions(+), 1 deletion(-)

-- 
Alexandre Belloni, Free Electrons
Embedded Linux, Kernel and Android engineering
http://free-electrons.com


From thierry.reding at gmail.com  Fri Aug  7 09:27:32 2015
From: thierry.reding at gmail.com (Thierry Reding)
Date: Fri,  7 Aug 2015 18:27:32 +0200
Subject: [PATCH 1/4] ARM: exynos: Remove PTN3460 dependency
Message-ID: <1438964855-16989-1-git-send-email-thierry.reding@gmail.com>

From: Thierry Reding <treding at nvidia.com>

Now that the PTN3460 driver has been rewritten as a proper I2C driver
and there is infrastructure to hook up the bridge with a DRM device, it
is no longer necessary to have this dependency to ensure the correct
build mode.

Signed-off-by: Thierry Reding <treding at nvidia.com>
---
 drivers/gpu/drm/exynos/Kconfig | 2 +-
 1 file changed, 1 insertion(+), 1 deletion(-)

diff --git a/drivers/gpu/drm/exynos/Kconfig b/drivers/gpu/drm/exynos/Kconfig
index 43003c4ad80b..df0b61a60501 100644
--- a/drivers/gpu/drm/exynos/Kconfig
+++ b/drivers/gpu/drm/exynos/Kconfig
@@ -56,7 +56,7 @@ config DRM_EXYNOS_DSI
 
 config DRM_EXYNOS_DP
 	bool "EXYNOS DRM DP driver support"
-	depends on DRM_EXYNOS && (DRM_EXYNOS_FIMD || DRM_EXYNOS7_DECON) && (DRM_PTN3460=n || DRM_PTN3460=y || DRM_PTN3460=DRM_EXYNOS)
+	depends on DRM_EXYNOS && (DRM_EXYNOS_FIMD || DRM_EXYNOS7_DECON)
 	default DRM_EXYNOS
 	select DRM_PANEL
 	help
-- 
2.4.5



From thierry.reding at gmail.com  Fri Aug  7 09:27:33 2015
From: thierry.reding at gmail.com (Thierry Reding)
Date: Fri,  7 Aug 2015 18:27:33 +0200
Subject: [PATCH 2/4] drm/bridge: Add vendor prefixes
In-Reply-To: <1438964855-16989-1-git-send-email-thierry.reding@gmail.com>
References: <1438964855-16989-1-git-send-email-thierry.reding@gmail.com>
Message-ID: <1438964855-16989-2-git-send-email-thierry.reding@gmail.com>

From: Thierry Reding <treding at nvidia.com>

Use vendor prefixes for Kconfig symbols and filenames. This should make
it easier to identify the various bridge drivers and to organize the
directory.

While at it, rename dw_hdmi.[ch] to dw-hdmi.[ch] for consistency.

Signed-off-by: Thierry Reding <treding at nvidia.com>
---
 arch/arm/configs/exynos_defconfig                    |  4 ++--
 arch/arm/configs/multi_v7_defconfig                  |  4 ++--
 drivers/gpu/drm/bridge/Kconfig                       | 10 +++++-----
 drivers/gpu/drm/bridge/Makefile                      |  6 +++---
 drivers/gpu/drm/bridge/{dw_hdmi.c => dw-hdmi.c}      |  2 +-
 drivers/gpu/drm/bridge/{dw_hdmi.h => dw-hdmi.h}      |  0
 drivers/gpu/drm/bridge/{ptn3460.c => nxp-ptn3460.c}  |  0
 drivers/gpu/drm/bridge/{ps8622.c => parade-ps8622.c} |  0
 8 files changed, 13 insertions(+), 13 deletions(-)
 rename drivers/gpu/drm/bridge/{dw_hdmi.c => dw-hdmi.c} (99%)
 rename drivers/gpu/drm/bridge/{dw_hdmi.h => dw-hdmi.h} (100%)
 rename drivers/gpu/drm/bridge/{ptn3460.c => nxp-ptn3460.c} (100%)
 rename drivers/gpu/drm/bridge/{ps8622.c => parade-ps8622.c} (100%)

diff --git a/arch/arm/configs/exynos_defconfig b/arch/arm/configs/exynos_defconfig
index 67965cedeb69..099438e19f05 100644
--- a/arch/arm/configs/exynos_defconfig
+++ b/arch/arm/configs/exynos_defconfig
@@ -125,8 +125,8 @@ CONFIG_REGULATOR_S2MPS11=y
 CONFIG_REGULATOR_S5M8767=y
 CONFIG_REGULATOR_TPS65090=y
 CONFIG_DRM=y
-CONFIG_DRM_PTN3460=y
-CONFIG_DRM_PS8622=y
+CONFIG_DRM_NXP_PTN3460=y
+CONFIG_DRM_PARADE_PS8622=y
 CONFIG_DRM_EXYNOS=y
 CONFIG_DRM_EXYNOS_FIMD=y
 CONFIG_DRM_EXYNOS_DSI=y
diff --git a/arch/arm/configs/multi_v7_defconfig b/arch/arm/configs/multi_v7_defconfig
index fb587b2330ad..29be77726ec8 100644
--- a/arch/arm/configs/multi_v7_defconfig
+++ b/arch/arm/configs/multi_v7_defconfig
@@ -438,8 +438,8 @@ CONFIG_VIDEO_RENESAS_VSP1=m
 CONFIG_VIDEO_ADV7180=m
 CONFIG_VIDEO_ML86V7667=m
 CONFIG_DRM=y
-CONFIG_DRM_PTN3460=m
-CONFIG_DRM_PS8622=m
+CONFIG_DRM_NXP_PTN3460=m
+CONFIG_DRM_PARADE_PS8622=m
 CONFIG_DRM_EXYNOS=m
 CONFIG_DRM_EXYNOS_DSI=y
 CONFIG_DRM_EXYNOS_FIMD=y
diff --git a/drivers/gpu/drm/bridge/Kconfig b/drivers/gpu/drm/bridge/Kconfig
index acef3223772c..adac3250684b 100644
--- a/drivers/gpu/drm/bridge/Kconfig
+++ b/drivers/gpu/drm/bridge/Kconfig
@@ -3,16 +3,16 @@ config DRM_DW_HDMI
 	depends on DRM
 	select DRM_KMS_HELPER
 
-config DRM_PTN3460
-	tristate "PTN3460 DP/LVDS bridge"
+config DRM_NXP_PTN3460
+	tristate "NXP PTN3460 DP/LVDS bridge"
 	depends on DRM
 	depends on OF
 	select DRM_KMS_HELPER
 	select DRM_PANEL
 	---help---
-	  ptn3460 eDP-LVDS bridge chip driver.
+	  NXP PTN3460 eDP-LVDS bridge chip driver.
 
-config DRM_PS8622
+config DRM_PARADE_PS8622
 	tristate "Parade eDP/LVDS bridge"
 	depends on DRM
 	depends on OF
@@ -21,4 +21,4 @@ config DRM_PS8622
 	select BACKLIGHT_LCD_SUPPORT
 	select BACKLIGHT_CLASS_DEVICE
 	---help---
-	  parade eDP-LVDS bridge chip driver.
+	  Parade eDP-LVDS bridge chip driver.
diff --git a/drivers/gpu/drm/bridge/Makefile b/drivers/gpu/drm/bridge/Makefile
index 8dfebd984370..fe490e2a7f25 100644
--- a/drivers/gpu/drm/bridge/Makefile
+++ b/drivers/gpu/drm/bridge/Makefile
@@ -1,5 +1,5 @@
 ccflags-y := -Iinclude/drm
 
-obj-$(CONFIG_DRM_PS8622) += ps8622.o
-obj-$(CONFIG_DRM_PTN3460) += ptn3460.o
-obj-$(CONFIG_DRM_DW_HDMI) += dw_hdmi.o
+obj-$(CONFIG_DRM_DW_HDMI) += dw-hdmi.o
+obj-$(CONFIG_DRM_NXP_PTN3460) += nxp-ptn3460.o
+obj-$(CONFIG_DRM_PARADE_PS8622) += parade-ps8622.o
diff --git a/drivers/gpu/drm/bridge/dw_hdmi.c b/drivers/gpu/drm/bridge/dw-hdmi.c
similarity index 99%
rename from drivers/gpu/drm/bridge/dw_hdmi.c
rename to drivers/gpu/drm/bridge/dw-hdmi.c
index 816d104ca4da..8bb00b70702a 100644
--- a/drivers/gpu/drm/bridge/dw_hdmi.c
+++ b/drivers/gpu/drm/bridge/dw-hdmi.c
@@ -26,7 +26,7 @@
 #include <drm/drm_encoder_slave.h>
 #include <drm/bridge/dw_hdmi.h>
 
-#include "dw_hdmi.h"
+#include "dw-hdmi.h"
 
 #define HDMI_EDID_LEN		512
 
diff --git a/drivers/gpu/drm/bridge/dw_hdmi.h b/drivers/gpu/drm/bridge/dw-hdmi.h
similarity index 100%
rename from drivers/gpu/drm/bridge/dw_hdmi.h
rename to drivers/gpu/drm/bridge/dw-hdmi.h
diff --git a/drivers/gpu/drm/bridge/ptn3460.c b/drivers/gpu/drm/bridge/nxp-ptn3460.c
similarity index 100%
rename from drivers/gpu/drm/bridge/ptn3460.c
rename to drivers/gpu/drm/bridge/nxp-ptn3460.c
diff --git a/drivers/gpu/drm/bridge/ps8622.c b/drivers/gpu/drm/bridge/parade-ps8622.c
similarity index 100%
rename from drivers/gpu/drm/bridge/ps8622.c
rename to drivers/gpu/drm/bridge/parade-ps8622.c
-- 
2.4.5



From thierry.reding at gmail.com  Fri Aug  7 09:27:35 2015
From: thierry.reding at gmail.com (Thierry Reding)
Date: Fri,  7 Aug 2015 18:27:35 +0200
Subject: [PATCH 4/4] drm/bridge: Put Kconfig entries in a separate menu
In-Reply-To: <1438964855-16989-1-git-send-email-thierry.reding@gmail.com>
References: <1438964855-16989-1-git-send-email-thierry.reding@gmail.com>
Message-ID: <1438964855-16989-4-git-send-email-thierry.reding@gmail.com>

From: Thierry Reding <treding at nvidia.com>

Put the Kconfig entries for bridge drivers into a separate menu so that
they are automatically grouped and don't clutter up the top-level menu.

While at it, move the bridge menu towards the end of the top-level menu
where the panel menu is already located.

Signed-off-by: Thierry Reding <treding at nvidia.com>
---
 drivers/gpu/drm/Kconfig        |  4 ++--
 drivers/gpu/drm/bridge/Kconfig | 14 +++++++++++---
 2 files changed, 13 insertions(+), 5 deletions(-)

diff --git a/drivers/gpu/drm/Kconfig b/drivers/gpu/drm/Kconfig
index 06ae5008c5ed..86191586340f 100644
--- a/drivers/gpu/drm/Kconfig
+++ b/drivers/gpu/drm/Kconfig
@@ -99,8 +99,6 @@ config DRM_KMS_CMA_HELPER
 
 source "drivers/gpu/drm/i2c/Kconfig"
 
-source "drivers/gpu/drm/bridge/Kconfig"
-
 config DRM_TDFX
 	tristate "3dfx Banshee/Voodoo3+"
 	depends on DRM && PCI
@@ -255,6 +253,8 @@ source "drivers/gpu/drm/tegra/Kconfig"
 
 source "drivers/gpu/drm/panel/Kconfig"
 
+source "drivers/gpu/drm/bridge/Kconfig"
+
 source "drivers/gpu/drm/sti/Kconfig"
 
 source "drivers/gpu/drm/amd/amdkfd/Kconfig"
diff --git a/drivers/gpu/drm/bridge/Kconfig b/drivers/gpu/drm/bridge/Kconfig
index adac3250684b..2de52a53a803 100644
--- a/drivers/gpu/drm/bridge/Kconfig
+++ b/drivers/gpu/drm/bridge/Kconfig
@@ -1,11 +1,18 @@
+config DRM_BRIDGE
+	def_bool y
+	depends on DRM
+	help
+	  Bridge registration and lookup framework.
+
+menu "Display Interface Bridges"
+	depends on DRM && DRM_BRIDGE
+
 config DRM_DW_HDMI
 	tristate
-	depends on DRM
 	select DRM_KMS_HELPER
 
 config DRM_NXP_PTN3460
 	tristate "NXP PTN3460 DP/LVDS bridge"
-	depends on DRM
 	depends on OF
 	select DRM_KMS_HELPER
 	select DRM_PANEL
@@ -14,7 +21,6 @@ config DRM_NXP_PTN3460
 
 config DRM_PARADE_PS8622
 	tristate "Parade eDP/LVDS bridge"
-	depends on DRM
 	depends on OF
 	select DRM_PANEL
 	select DRM_KMS_HELPER
@@ -22,3 +28,5 @@ config DRM_PARADE_PS8622
 	select BACKLIGHT_CLASS_DEVICE
 	---help---
 	  Parade eDP-LVDS bridge chip driver.
+
+endmenu
-- 
2.4.5



From thierry.reding at gmail.com  Fri Aug  7 09:27:34 2015
From: thierry.reding at gmail.com (Thierry Reding)
Date: Fri,  7 Aug 2015 18:27:34 +0200
Subject: [PATCH 3/4] drm/panel: Add Samsung prefix to panel drivers
In-Reply-To: <1438964855-16989-1-git-send-email-thierry.reding@gmail.com>
References: <1438964855-16989-1-git-send-email-thierry.reding@gmail.com>
Message-ID: <1438964855-16989-3-git-send-email-thierry.reding@gmail.com>

From: Thierry Reding <treding at nvidia.com>

The likelihood of getting a large number of panel drivers from different
vendors is quite high. Add a prefix to the two existing Samsung panel
drivers to set a guideline for future patch submissions. Using vendor
prefixes consistently should allow a cleaner organization of the tree.

Signed-off-by: Thierry Reding <treding at nvidia.com>
---
 arch/arm/configs/exynos_defconfig                                 | 2 +-
 arch/arm/configs/multi_v7_defconfig                               | 2 +-
 drivers/gpu/drm/panel/Kconfig                                     | 8 ++++----
 drivers/gpu/drm/panel/Makefile                                    | 4 ++--
 drivers/gpu/drm/panel/{panel-ld9040.c => panel-samsung-ld9040.c}  | 2 +-
 .../gpu/drm/panel/{panel-s6e8aa0.c => panel-samsung-s6e8aa0.c}    | 2 +-
 6 files changed, 10 insertions(+), 10 deletions(-)
 rename drivers/gpu/drm/panel/{panel-ld9040.c => panel-samsung-ld9040.c} (99%)
 rename drivers/gpu/drm/panel/{panel-s6e8aa0.c => panel-samsung-s6e8aa0.c} (99%)

diff --git a/arch/arm/configs/exynos_defconfig b/arch/arm/configs/exynos_defconfig
index 099438e19f05..354124c3ed2c 100644
--- a/arch/arm/configs/exynos_defconfig
+++ b/arch/arm/configs/exynos_defconfig
@@ -132,7 +132,7 @@ CONFIG_DRM_EXYNOS_FIMD=y
 CONFIG_DRM_EXYNOS_DSI=y
 CONFIG_DRM_EXYNOS_HDMI=y
 CONFIG_DRM_PANEL_SIMPLE=y
-CONFIG_DRM_PANEL_S6E8AA0=y
+CONFIG_DRM_PANEL_SAMSUNG_S6E8AA0=y
 CONFIG_FB_SIMPLE=y
 CONFIG_EXYNOS_VIDEO=y
 CONFIG_EXYNOS_MIPI_DSI=y
diff --git a/arch/arm/configs/multi_v7_defconfig b/arch/arm/configs/multi_v7_defconfig
index 29be77726ec8..6ba9608798ab 100644
--- a/arch/arm/configs/multi_v7_defconfig
+++ b/arch/arm/configs/multi_v7_defconfig
@@ -446,7 +446,7 @@ CONFIG_DRM_EXYNOS_FIMD=y
 CONFIG_DRM_EXYNOS_HDMI=y
 CONFIG_DRM_RCAR_DU=m
 CONFIG_DRM_TEGRA=y
-CONFIG_DRM_PANEL_S6E8AA0=m
+CONFIG_DRM_PANEL_SAMSUNG_S6E8AA0=m
 CONFIG_DRM_PANEL_SIMPLE=y
 CONFIG_FB_ARMCLCD=y
 CONFIG_FB_WM8505=y
diff --git a/drivers/gpu/drm/panel/Kconfig b/drivers/gpu/drm/panel/Kconfig
index 6d64c7bb908b..5be25d9282e3 100644
--- a/drivers/gpu/drm/panel/Kconfig
+++ b/drivers/gpu/drm/panel/Kconfig
@@ -18,13 +18,13 @@ config DRM_PANEL_SIMPLE
 	  that it can be automatically turned off when the panel goes into a
 	  low power state.
 
-config DRM_PANEL_LD9040
-	tristate "LD9040 RGB/SPI panel"
+config DRM_PANEL_SAMSUNG_LD9040
+	tristate "Samsung LD9040 RGB/SPI panel"
 	depends on OF && SPI
 	select VIDEOMODE_HELPERS
 
-config DRM_PANEL_S6E8AA0
-	tristate "S6E8AA0 DSI video mode panel"
+config DRM_PANEL_SAMSUNG_S6E8AA0
+	tristate "Samsung S6E8AA0 DSI video mode panel"
 	depends on OF
 	select DRM_MIPI_DSI
 	select VIDEOMODE_HELPERS
diff --git a/drivers/gpu/drm/panel/Makefile b/drivers/gpu/drm/panel/Makefile
index 4b2a0430804b..8026ce5d18b5 100644
--- a/drivers/gpu/drm/panel/Makefile
+++ b/drivers/gpu/drm/panel/Makefile
@@ -1,4 +1,4 @@
 obj-$(CONFIG_DRM_PANEL_SIMPLE) += panel-simple.o
-obj-$(CONFIG_DRM_PANEL_LD9040) += panel-ld9040.o
-obj-$(CONFIG_DRM_PANEL_S6E8AA0) += panel-s6e8aa0.o
+obj-$(CONFIG_DRM_PANEL_SAMSUNG_LD9040) += panel-samsung-ld9040.o
+obj-$(CONFIG_DRM_PANEL_SAMSUNG_S6E8AA0) += panel-samsung-s6e8aa0.o
 obj-$(CONFIG_DRM_PANEL_SHARP_LQ101R1SX01) += panel-sharp-lq101r1sx01.o
diff --git a/drivers/gpu/drm/panel/panel-ld9040.c b/drivers/gpu/drm/panel/panel-samsung-ld9040.c
similarity index 99%
rename from drivers/gpu/drm/panel/panel-ld9040.c
rename to drivers/gpu/drm/panel/panel-samsung-ld9040.c
index bba3501c5821..fcb827003a8c 100644
--- a/drivers/gpu/drm/panel/panel-ld9040.c
+++ b/drivers/gpu/drm/panel/panel-samsung-ld9040.c
@@ -378,7 +378,7 @@ static struct spi_driver ld9040_driver = {
 	.probe = ld9040_probe,
 	.remove = ld9040_remove,
 	.driver = {
-		.name = "ld9040",
+		.name = "panel-samsung-ld9040",
 		.owner = THIS_MODULE,
 		.of_match_table = ld9040_of_match,
 	},
diff --git a/drivers/gpu/drm/panel/panel-s6e8aa0.c b/drivers/gpu/drm/panel/panel-samsung-s6e8aa0.c
similarity index 99%
rename from drivers/gpu/drm/panel/panel-s6e8aa0.c
rename to drivers/gpu/drm/panel/panel-samsung-s6e8aa0.c
index 9e79bc43b047..6b11e75ff645 100644
--- a/drivers/gpu/drm/panel/panel-s6e8aa0.c
+++ b/drivers/gpu/drm/panel/panel-samsung-s6e8aa0.c
@@ -1052,7 +1052,7 @@ static struct mipi_dsi_driver s6e8aa0_driver = {
 	.probe = s6e8aa0_probe,
 	.remove = s6e8aa0_remove,
 	.driver = {
-		.name = "panel_s6e8aa0",
+		.name = "panel-samsung-s6e8aa0",
 		.of_match_table = s6e8aa0_of_match,
 	},
 };
-- 
2.4.5



From khilman at kernel.org  Fri Aug  7 09:30:06 2015
From: khilman at kernel.org (Kevin Hilman)
Date: Fri, 7 Aug 2015 09:30:06 -0700
Subject: [PATCH v9 0/9] Add simple NVMEM Framework via regmap.
In-Reply-To: <55C4DA42.909@linaro.org>
References: <1437995567-11203-1-git-send-email-srinivas.kandagatla@linaro.org>
 <7hwpx7vzyo.fsf@deeprootsystems.com> <55C4DA42.909@linaro.org>
Message-ID: <CAMAWPa_=1oTziNz-oorXV70AZ2S3JbVu4rhK_nX_=wYwjr2a3g@mail.gmail.com>

On Fri, Aug 7, 2015 at 9:18 AM, Srinivas Kandagatla
<srinivas.kandagatla at linaro.org> wrote:
> Thanks Kevin,
>
> On 07/08/15 17:13, Kevin Hilman wrote:
>>
>> Srinivas Kandagatla <srinivas.kandagatla at linaro.org> writes:
>>
>>> This patchset adds a new simple NVMEM framework to kernel, and it is
>>> tested
>>> with various drivers like "QCOM thermal sensors", "QCOM cpr driver",
>>> "begal bone cape manager" and few more on the way.
>>>
>>> Can you please consider this as 4.3 material, AFAIK there are more than 3
>>> drivers
>>> depending on this framework which are wating since last 2 merge windows.
>>>
>>> Should these patches go via ARM-SOC tree or via Greg's tree?
>>
>>
>> With Greg's ack, we can take this through the arm-soc tree (unless Greg
>> wants to queue it, which is fine also.)
>>
>
> Greg already merged these patches yesterday on to
> git://git.kernel.org/pub/scm/linux/kernel/git/gregkh/char-misc.git
> in the char-misc-next branch.

Ah, great.  I missed that (still catching up on post-vacation mail backlog.)

Thanks,

Kevin


From julien.grall at citrix.com  Fri Aug  7 09:34:35 2015
From: julien.grall at citrix.com (Julien Grall)
Date: Fri, 7 Aug 2015 17:34:35 +0100
Subject: [PATCH v3 2/9] xen: Make clear that swiotlb and biomerge are dealing
 with DMA address
In-Reply-To: <1438965282-19103-1-git-send-email-julien.grall@citrix.com>
References: <1438965282-19103-1-git-send-email-julien.grall@citrix.com>
Message-ID: <1438965282-19103-3-git-send-email-julien.grall@citrix.com>

The swiotlb is required when programming a DMA address on ARM when a
device is not protected by an IOMMU.

In this case, the DMA address should always be equal to the machine address.
For DOM0 memory, Xen ensure it by have an identity mapping between the
guest address and host address. However, when mapping a foreign grant
reference, the 1:1 model doesn't work.

For ARM guest, most of the callers of pfn_to_mfn expects to get a GFN
(Guest Frame Number), i.e a PFN (Page Frame Number) from the Linux point
of view given that all ARM guest are auto-translated.

Even though the name pfn_to_mfn is misleading, we need to ensure that
those caller get a GFN and not by mistake a MFN. In pratical, I haven't
seen error related to this but we should fix it for the sake of
correctness.

In order to fix the implementation of pfn_to_mfn on ARM in a follow-up
patch, we have to introduce new helpers to return the DMA from a PFN and
the invert.

On x86, the new helpers will be an alias of pfn_to_mfn and mfn_to_pfn.

The helpers will be used in swiotlb and xen_biovec_phys_mergeable.

This is necessary in the latter because we have to ensure that the
biovec code will not try to merge a biovec using foreign page and
another using Linux memory.

Lastly, the helper mfn_to_local_pfn has been renamed to bfn_to_local_pfn
given that the only usage was in swiotlb.

Signed-off-by: Julien Grall <julien.grall at citrix.com>
Reviewed-by: Stefano Stabellini <stefano.stabellini at eu.citrix.com>

---
Cc: Russell King <linux at arm.linux.org.uk>
Cc: Konrad Rzeszutek Wilk <konrad.wilk at oracle.com>
Cc: Boris Ostrovsky <boris.ostrovsky at oracle.com>
Cc: David Vrabel <david.vrabel at citrix.com>
Cc: Thomas Gleixner <tglx at linutronix.de>
Cc: Ingo Molnar <mingo at redhat.com>
Cc: "H. Peter Anvin" <hpa at zytor.com>
Cc: x86 at kernel.org
Cc: linux-arm-kernel at lists.infradead.org

    Changes in v3:
        - Typoes in the commit message
        - Forgot to replace some dfn in bfn
        - Add Stefano's reviewed-by

    Changes in v2:
        - Use bfn (Bus Frame Number) rather than dfn to match the
        proposed terminology for pv-iommu hypercall.
---
 arch/arm/include/asm/xen/page.h | 23 +++++++++++++++++++++--
 arch/arm/xen/mm.c               |  4 ++--
 arch/x86/include/asm/xen/page.h |  8 ++++++--
 drivers/xen/biomerge.c          |  6 +++---
 drivers/xen/swiotlb-xen.c       | 16 ++++++++--------
 5 files changed, 40 insertions(+), 17 deletions(-)

diff --git a/arch/arm/include/asm/xen/page.h b/arch/arm/include/asm/xen/page.h
index 98b1084..5f76a9e 100644
--- a/arch/arm/include/asm/xen/page.h
+++ b/arch/arm/include/asm/xen/page.h
@@ -52,7 +52,26 @@ static inline unsigned long mfn_to_pfn(unsigned long mfn)
 	return mfn;
 }
 
-#define mfn_to_local_pfn(mfn) mfn_to_pfn(mfn)
+/* Pseudo-physical <-> BUS conversion */
+static inline unsigned long pfn_to_bfn(unsigned long pfn)
+{
+	unsigned long mfn;
+
+	if (phys_to_mach.rb_node != NULL) {
+		mfn = __pfn_to_mfn(pfn);
+		if (mfn != INVALID_P2M_ENTRY)
+			return mfn;
+	}
+
+	return pfn;
+}
+
+static inline unsigned long bfn_to_pfn(unsigned long bfn)
+{
+	return bfn;
+}
+
+#define bfn_to_local_pfn(bfn)	bfn_to_pfn(bfn)
 
 /* VIRT <-> MACHINE conversion */
 #define virt_to_mfn(v)		(pfn_to_mfn(virt_to_pfn(v)))
@@ -96,7 +115,7 @@ static inline bool set_phys_to_machine(unsigned long pfn, unsigned long mfn)
 
 bool xen_arch_need_swiotlb(struct device *dev,
 			   unsigned long pfn,
-			   unsigned long mfn);
+			   unsigned long bfn);
 unsigned long xen_get_swiotlb_free_pages(unsigned int order);
 
 #endif /* _ASM_ARM_XEN_PAGE_H */
diff --git a/arch/arm/xen/mm.c b/arch/arm/xen/mm.c
index 03e75fe..6dd911d 100644
--- a/arch/arm/xen/mm.c
+++ b/arch/arm/xen/mm.c
@@ -139,9 +139,9 @@ void __xen_dma_sync_single_for_device(struct device *hwdev,
 
 bool xen_arch_need_swiotlb(struct device *dev,
 			   unsigned long pfn,
-			   unsigned long mfn)
+			   unsigned long bfn)
 {
-	return (!hypercall_cflush && (pfn != mfn) && !is_device_dma_coherent(dev));
+	return (!hypercall_cflush && (pfn != bfn) && !is_device_dma_coherent(dev));
 }
 
 int xen_create_contiguous_region(phys_addr_t pstart, unsigned int order,
diff --git a/arch/x86/include/asm/xen/page.h b/arch/x86/include/asm/xen/page.h
index a3804fb..724bffb 100644
--- a/arch/x86/include/asm/xen/page.h
+++ b/arch/x86/include/asm/xen/page.h
@@ -176,6 +176,10 @@ static inline xpaddr_t machine_to_phys(xmaddr_t machine)
 	return XPADDR(PFN_PHYS(mfn_to_pfn(PFN_DOWN(machine.maddr))) | offset);
 }
 
+/* Pseudo-physical <-> Bus conversion */
+#define pfn_to_bfn(pfn)		pfn_to_mfn(pfn)
+#define bfn_to_pfn(bfn)		mfn_to_pfn(bfn)
+
 /*
  * We detect special mappings in one of two ways:
  *  1. If the MFN is an I/O page then Xen will set the m2p entry
@@ -196,7 +200,7 @@ static inline xpaddr_t machine_to_phys(xmaddr_t machine)
  *      require. In all the cases we care about, the FOREIGN_FRAME bit is
  *      masked (e.g., pfn_to_mfn()) so behaviour there is correct.
  */
-static inline unsigned long mfn_to_local_pfn(unsigned long mfn)
+static inline unsigned long bfn_to_local_pfn(unsigned long mfn)
 {
 	unsigned long pfn;
 
@@ -262,7 +266,7 @@ void make_lowmem_page_readwrite(void *vaddr);
 
 static inline bool xen_arch_need_swiotlb(struct device *dev,
 					 unsigned long pfn,
-					 unsigned long mfn)
+					 unsigned long bfn)
 {
 	return false;
 }
diff --git a/drivers/xen/biomerge.c b/drivers/xen/biomerge.c
index 0edb91c..8ae2fc90 100644
--- a/drivers/xen/biomerge.c
+++ b/drivers/xen/biomerge.c
@@ -6,10 +6,10 @@
 bool xen_biovec_phys_mergeable(const struct bio_vec *vec1,
 			       const struct bio_vec *vec2)
 {
-	unsigned long mfn1 = pfn_to_mfn(page_to_pfn(vec1->bv_page));
-	unsigned long mfn2 = pfn_to_mfn(page_to_pfn(vec2->bv_page));
+	unsigned long bfn1 = pfn_to_bfn(page_to_pfn(vec1->bv_page));
+	unsigned long bfn2 = pfn_to_bfn(page_to_pfn(vec2->bv_page));
 
 	return __BIOVEC_PHYS_MERGEABLE(vec1, vec2) &&
-		((mfn1 == mfn2) || ((mfn1+1) == mfn2));
+		((bfn1 == bfn2) || ((bfn1+1) == bfn2));
 }
 EXPORT_SYMBOL(xen_biovec_phys_mergeable);
diff --git a/drivers/xen/swiotlb-xen.c b/drivers/xen/swiotlb-xen.c
index 4c54932..d757a3e 100644
--- a/drivers/xen/swiotlb-xen.c
+++ b/drivers/xen/swiotlb-xen.c
@@ -82,8 +82,8 @@ static u64 start_dma_addr;
  */
 static inline dma_addr_t xen_phys_to_bus(phys_addr_t paddr)
 {
-	unsigned long mfn = pfn_to_mfn(PFN_DOWN(paddr));
-	dma_addr_t dma = (dma_addr_t)mfn << PAGE_SHIFT;
+	unsigned long bfn = pfn_to_bfn(PFN_DOWN(paddr));
+	dma_addr_t dma = (dma_addr_t)bfn << PAGE_SHIFT;
 
 	dma |= paddr & ~PAGE_MASK;
 
@@ -92,7 +92,7 @@ static inline dma_addr_t xen_phys_to_bus(phys_addr_t paddr)
 
 static inline phys_addr_t xen_bus_to_phys(dma_addr_t baddr)
 {
-	unsigned long pfn = mfn_to_pfn(PFN_DOWN(baddr));
+	unsigned long pfn = bfn_to_pfn(PFN_DOWN(baddr));
 	dma_addr_t dma = (dma_addr_t)pfn << PAGE_SHIFT;
 	phys_addr_t paddr = dma;
 
@@ -110,15 +110,15 @@ static int check_pages_physically_contiguous(unsigned long pfn,
 					     unsigned int offset,
 					     size_t length)
 {
-	unsigned long next_mfn;
+	unsigned long next_bfn;
 	int i;
 	int nr_pages;
 
-	next_mfn = pfn_to_mfn(pfn);
+	next_bfn = pfn_to_bfn(pfn);
 	nr_pages = (offset + length + PAGE_SIZE-1) >> PAGE_SHIFT;
 
 	for (i = 1; i < nr_pages; i++) {
-		if (pfn_to_mfn(++pfn) != ++next_mfn)
+		if (pfn_to_bfn(++pfn) != ++next_bfn)
 			return 0;
 	}
 	return 1;
@@ -138,8 +138,8 @@ static inline int range_straddles_page_boundary(phys_addr_t p, size_t size)
 
 static int is_xen_swiotlb_buffer(dma_addr_t dma_addr)
 {
-	unsigned long mfn = PFN_DOWN(dma_addr);
-	unsigned long pfn = mfn_to_local_pfn(mfn);
+	unsigned long bfn = PFN_DOWN(dma_addr);
+	unsigned long pfn = bfn_to_local_pfn(bfn);
 	phys_addr_t paddr;
 
 	/* If the address is outside our domain, it CAN
-- 
2.1.4



From julien.grall at citrix.com  Fri Aug  7 09:34:33 2015
From: julien.grall at citrix.com (Julien Grall)
Date: Fri, 7 Aug 2015 17:34:33 +0100
Subject: [PATCH v3 0/9] Use correctly the Xen memory terminologies
Message-ID: <1438965282-19103-1-git-send-email-julien.grall@citrix.com>

Hi all,

This patch series aims to use the memory terminologies described in
include/xen/mm.h [1] for Linux xen code.

The differences from v2 is minor but I resent it because my 64K series depends
on this series.

Linux is using mistakenly MFN when GFN is meant, I suspect this is because the
first support of Xen was for PV. This has brought some misimplementation
of memory helpers on ARM and make the developper confused about the expected
behavior.

For instance, with pfn_to_mfn, we expect to get a MFN based on the name.
Although, if we look at the implementation on x86, it's returning a GFN.
Most of the callers are also using it this way.

The first 2 patches of this series is ARM related in order to remove
PV specific helpers which should not be used and fixing the implementation of
pfn_to_mfn.

The rest of the series is here rename most of the usage in the common code
of MFN to GFN. I also took the opportunity to replace most of the call to
pfn_to_gfn in the common code by page_to_gfn avoid construction such
as pfn_to_gfn(page_to_pfn(...).

Note the one xen-blkfront will be dropped by 64K series [2], I can include
here if necessary.

Major changes in v3:
    - More typoes
    - Rename page_to_gfn to xen_page_to_gfn to avoid confusing with the
    KVM function gfn_to_page

Major changes in v2:
    - Use bfn rather than dfn for the DMA address
    - Re-introduced pfn_to_mfn for PV guests only
    - Typoes

For all the changes see in each patch.

This series is based on xentip for-linus-4.3 branch. A branch with all the
patches can be found here:
    git://xenbits.xen.org/people/julieng/linux-arm.git branch page-renaming-v3

It has been boot tested on ARM64 and ARM32 and only built for x86.
I would be happy if someone can give a try on x86 as I don't have a x86
box setup with Xen.

Sincerely yours,

[1] http://xenbits.xen.org/gitweb/?p=xen.git;a=commitdiff;h=e758ed14f390342513405dd766e874934573e6cb
[2] https://lkml.org/lkml/2015/7/9/628

Cc: Boris Ostrovsky <boris.ostrovsky at oracle.com>
Cc: David Vrabel <david.vrabel at citrix.com>
Cc: Dmitry Torokhov <dmitry.torokhov at gmail.com>
Cc: Greg Kroah-Hartman <gregkh at linuxfoundation.org>
Cc: "H. Peter Anvin" <hpa at zytor.com>
Cc: Ian Campbell <ian.campbell at citrix.com>
Cc: Ingo Molnar <mingo at redhat.com>
Cc: "James E.J. Bottomley" <JBottomley at odin.com>
Cc: Jean-Christophe Plagniol-Villard <plagnioj at jcrosoft.com>
Cc: Jiri Slaby <jslaby at suse.com>
Cc: Juergen Gross <jgross at suse.com>
Cc: Konrad Rzeszutek Wilk <konrad.wilk at oracle.com>
Cc: linux-api at vger.kernel.org
Cc: linux-arm-kernel at lists.infradead.org
Cc: linux-fbdev at vger.kernel.org
Cc: linux-input at vger.kernel.org
Cc: linuxppc-dev at lists.ozlabs.org
Cc: linux-scsi at vger.kernel.org
Cc: netdev at vger.kernel.org
Cc: "Roger Pau Monn?" <roger.pau at citrix.com>
Cc: Russell King <linux at arm.linux.org.uk>
Cc: Stefano Stabellini <stefano.stabellini at eu.citrix.com>
Cc: Thomas Gleixner <tglx at linutronix.de>
Cc: Tomi Valkeinen <tomi.valkeinen at ti.com>
Cc: Wei Liu <wei.liu2 at citrix.com>
Cc: x86 at kernel.org



Julien Grall (9):
  arm/xen: Remove helpers which are PV specific
  xen: Make clear that swiotlb and biomerge are dealing with DMA address
  arm/xen: implement correctly pfn_to_mfn
  xen: Use correctly the Xen memory terminologies
  xen/tmem: Use xen_page_to_gfn rather than pfn_to_gfn
  video/xen-fbfront: Further s/MFN/GFN clean-up
  hvc/xen: Further s/MFN/GFN clean-up
  xen/privcmd: Further s/MFN/GFN/ clean-up
  xen/xenbus: Rename the variable xen_store_mfn to xen_store_gfn

 arch/arm/include/asm/xen/page.h         | 44 ++++++++++++++++-----------------
 arch/arm/xen/enlighten.c                | 18 +++++++-------
 arch/arm/xen/mm.c                       |  4 +--
 arch/x86/include/asm/xen/page.h         | 35 +++++++++++++++++++++-----
 arch/x86/xen/mmu.c                      | 32 ++++++++++++------------
 arch/x86/xen/smp.c                      |  2 +-
 drivers/block/xen-blkfront.c            |  6 ++---
 drivers/input/misc/xen-kbdfront.c       |  4 +--
 drivers/net/xen-netback/netback.c       |  4 +--
 drivers/net/xen-netfront.c              | 12 +++++----
 drivers/scsi/xen-scsifront.c            | 10 ++++----
 drivers/tty/hvc/hvc_xen.c               | 18 ++++++--------
 drivers/video/fbdev/xen-fbfront.c       | 20 +++++++--------
 drivers/xen/balloon.c                   |  2 +-
 drivers/xen/biomerge.c                  |  6 ++---
 drivers/xen/events/events_base.c        |  2 +-
 drivers/xen/events/events_fifo.c        |  4 +--
 drivers/xen/gntalloc.c                  |  3 ++-
 drivers/xen/manage.c                    |  2 +-
 drivers/xen/privcmd.c                   | 44 ++++++++++++++++-----------------
 drivers/xen/swiotlb-xen.c               | 16 ++++++------
 drivers/xen/tmem.c                      | 21 ++++++----------
 drivers/xen/xenbus/xenbus_client.c      |  2 +-
 drivers/xen/xenbus/xenbus_dev_backend.c |  2 +-
 drivers/xen/xenbus/xenbus_probe.c       | 16 ++++++------
 drivers/xen/xlate_mmu.c                 | 18 +++++++-------
 include/uapi/xen/privcmd.h              |  4 +++
 include/xen/page.h                      |  4 +--
 include/xen/xen-ops.h                   | 10 ++++----
 29 files changed, 191 insertions(+), 174 deletions(-)

-- 
2.1.4



From julien.grall at citrix.com  Fri Aug  7 09:34:41 2015
From: julien.grall at citrix.com (Julien Grall)
Date: Fri, 7 Aug 2015 17:34:41 +0100
Subject: [PATCH v3 8/9] xen/privcmd: Further s/MFN/GFN/ clean-up
In-Reply-To: <1438965282-19103-1-git-send-email-julien.grall@citrix.com>
References: <1438965282-19103-1-git-send-email-julien.grall@citrix.com>
Message-ID: <1438965282-19103-9-git-send-email-julien.grall@citrix.com>

The privcmd code is mixing the usage of GFN and MFN within the same
functions which make the code difficult to understand when you only work
with auto-translated guests.

The privcmd driver is only dealing with GFN so replace all the mention
of MFN into GFN.

The ioctl structure used to map foreign change has been left unchanged
given that the userspace is using it. Nonetheless, add a comment to
explain the expected value within the "mfn" field.

Signed-off-by: Julien Grall <julien.grall at citrix.com>
Reviewed-by: David Vrabel <david.vrabel at citrix.com>

---
Cc: Stefano Stabellini <stefano.stabellini at eu.citrix.com>
Cc: Russell King <linux at arm.linux.org.uk>
Cc: Konrad Rzeszutek Wilk <konrad.wilk at oracle.com>
Cc: Boris Ostrovsky <boris.ostrovsky at oracle.com>
Cc: Thomas Gleixner <tglx at linutronix.de>
Cc: Ingo Molnar <mingo at redhat.com>
Cc: "H. Peter Anvin" <hpa at zytor.com>
Cc: x86 at kernel.org
Cc: linux-arm-kernel at lists.infradead.org
Cc: linux-api at vger.kernel.org

    Changes in v2:
        - Add David's reviewed-by
---
 arch/arm/xen/enlighten.c   | 18 +++++++++---------
 arch/x86/xen/mmu.c         | 32 ++++++++++++++++----------------
 drivers/xen/privcmd.c      | 44 ++++++++++++++++++++++----------------------
 drivers/xen/xlate_mmu.c    | 18 +++++++++---------
 include/uapi/xen/privcmd.h |  4 ++++
 include/xen/xen-ops.h      | 10 +++++-----
 6 files changed, 65 insertions(+), 61 deletions(-)

diff --git a/arch/arm/xen/enlighten.c b/arch/arm/xen/enlighten.c
index c50c8d3..eeeab07 100644
--- a/arch/arm/xen/enlighten.c
+++ b/arch/arm/xen/enlighten.c
@@ -49,35 +49,35 @@ static __read_mostly unsigned int xen_events_irq;
 
 static __initdata struct device_node *xen_node;
 
-int xen_remap_domain_mfn_array(struct vm_area_struct *vma,
+int xen_remap_domain_gfn_array(struct vm_area_struct *vma,
 			       unsigned long addr,
-			       xen_pfn_t *mfn, int nr,
+			       xen_pfn_t *gfn, int nr,
 			       int *err_ptr, pgprot_t prot,
 			       unsigned domid,
 			       struct page **pages)
 {
-	return xen_xlate_remap_gfn_array(vma, addr, mfn, nr, err_ptr,
+	return xen_xlate_remap_gfn_array(vma, addr, gfn, nr, err_ptr,
 					 prot, domid, pages);
 }
-EXPORT_SYMBOL_GPL(xen_remap_domain_mfn_array);
+EXPORT_SYMBOL_GPL(xen_remap_domain_gfn_array);
 
 /* Not used by XENFEAT_auto_translated guests. */
-int xen_remap_domain_mfn_range(struct vm_area_struct *vma,
+int xen_remap_domain_gfn_range(struct vm_area_struct *vma,
                               unsigned long addr,
-                              xen_pfn_t mfn, int nr,
+                              xen_pfn_t gfn, int nr,
                               pgprot_t prot, unsigned domid,
                               struct page **pages)
 {
 	return -ENOSYS;
 }
-EXPORT_SYMBOL_GPL(xen_remap_domain_mfn_range);
+EXPORT_SYMBOL_GPL(xen_remap_domain_gfn_range);
 
-int xen_unmap_domain_mfn_range(struct vm_area_struct *vma,
+int xen_unmap_domain_gfn_range(struct vm_area_struct *vma,
 			       int nr, struct page **pages)
 {
 	return xen_xlate_unmap_gfn_range(vma, nr, pages);
 }
-EXPORT_SYMBOL_GPL(xen_unmap_domain_mfn_range);
+EXPORT_SYMBOL_GPL(xen_unmap_domain_gfn_range);
 
 static void xen_percpu_init(void)
 {
diff --git a/arch/x86/xen/mmu.c b/arch/x86/xen/mmu.c
index 59ec3c3..53447a7 100644
--- a/arch/x86/xen/mmu.c
+++ b/arch/x86/xen/mmu.c
@@ -2812,9 +2812,9 @@ static int remap_area_mfn_pte_fn(pte_t *ptep, pgtable_t token,
 	return 0;
 }
 
-static int do_remap_mfn(struct vm_area_struct *vma,
+static int do_remap_gfn(struct vm_area_struct *vma,
 			unsigned long addr,
-			xen_pfn_t *mfn, int nr,
+			xen_pfn_t *gfn, int nr,
 			int *err_ptr, pgprot_t prot,
 			unsigned domid,
 			struct page **pages)
@@ -2830,14 +2830,14 @@ static int do_remap_mfn(struct vm_area_struct *vma,
 	if (xen_feature(XENFEAT_auto_translated_physmap)) {
 #ifdef CONFIG_XEN_PVH
 		/* We need to update the local page tables and the xen HAP */
-		return xen_xlate_remap_gfn_array(vma, addr, mfn, nr, err_ptr,
+		return xen_xlate_remap_gfn_array(vma, addr, gfn, nr, err_ptr,
 						 prot, domid, pages);
 #else
 		return -EINVAL;
 #endif
         }
 
-	rmd.mfn = mfn;
+	rmd.mfn = gfn;
 	rmd.prot = prot;
 	/* We use the err_ptr to indicate if there we are doing a contigious
 	 * mapping or a discontigious mapping. */
@@ -2865,8 +2865,8 @@ static int do_remap_mfn(struct vm_area_struct *vma,
 						    batch_left, &done, domid);
 
 			/*
-			 * @err_ptr may be the same buffer as @mfn, so
-			 * only clear it after each chunk of @mfn is
+			 * @err_ptr may be the same buffer as @gfn, so
+			 * only clear it after each chunk of @gfn is
 			 * used.
 			 */
 			if (err_ptr) {
@@ -2896,19 +2896,19 @@ out:
 	return err < 0 ? err : mapped;
 }
 
-int xen_remap_domain_mfn_range(struct vm_area_struct *vma,
+int xen_remap_domain_gfn_range(struct vm_area_struct *vma,
 			       unsigned long addr,
-			       xen_pfn_t mfn, int nr,
+			       xen_pfn_t gfn, int nr,
 			       pgprot_t prot, unsigned domid,
 			       struct page **pages)
 {
-	return do_remap_mfn(vma, addr, &mfn, nr, NULL, prot, domid, pages);
+	return do_remap_gfn(vma, addr, &gfn, nr, NULL, prot, domid, pages);
 }
-EXPORT_SYMBOL_GPL(xen_remap_domain_mfn_range);
+EXPORT_SYMBOL_GPL(xen_remap_domain_gfn_range);
 
-int xen_remap_domain_mfn_array(struct vm_area_struct *vma,
+int xen_remap_domain_gfn_array(struct vm_area_struct *vma,
 			       unsigned long addr,
-			       xen_pfn_t *mfn, int nr,
+			       xen_pfn_t *gfn, int nr,
 			       int *err_ptr, pgprot_t prot,
 			       unsigned domid, struct page **pages)
 {
@@ -2917,13 +2917,13 @@ int xen_remap_domain_mfn_array(struct vm_area_struct *vma,
 	 * cause of "wrong memory was mapped in".
 	 */
 	BUG_ON(err_ptr == NULL);
-	return do_remap_mfn(vma, addr, mfn, nr, err_ptr, prot, domid, pages);
+	return do_remap_gfn(vma, addr, gfn, nr, err_ptr, prot, domid, pages);
 }
-EXPORT_SYMBOL_GPL(xen_remap_domain_mfn_array);
+EXPORT_SYMBOL_GPL(xen_remap_domain_gfn_array);
 
 
 /* Returns: 0 success */
-int xen_unmap_domain_mfn_range(struct vm_area_struct *vma,
+int xen_unmap_domain_gfn_range(struct vm_area_struct *vma,
 			       int numpgs, struct page **pages)
 {
 	if (!pages || !xen_feature(XENFEAT_auto_translated_physmap))
@@ -2935,4 +2935,4 @@ int xen_unmap_domain_mfn_range(struct vm_area_struct *vma,
 	return -EINVAL;
 #endif
 }
-EXPORT_SYMBOL_GPL(xen_unmap_domain_mfn_range);
+EXPORT_SYMBOL_GPL(xen_unmap_domain_gfn_range);
diff --git a/drivers/xen/privcmd.c b/drivers/xen/privcmd.c
index 5a29616..c6deb87 100644
--- a/drivers/xen/privcmd.c
+++ b/drivers/xen/privcmd.c
@@ -193,16 +193,16 @@ static int traverse_pages_block(unsigned nelem, size_t size,
 	return ret;
 }
 
-struct mmap_mfn_state {
+struct mmap_gfn_state {
 	unsigned long va;
 	struct vm_area_struct *vma;
 	domid_t domain;
 };
 
-static int mmap_mfn_range(void *data, void *state)
+static int mmap_gfn_range(void *data, void *state)
 {
 	struct privcmd_mmap_entry *msg = data;
-	struct mmap_mfn_state *st = state;
+	struct mmap_gfn_state *st = state;
 	struct vm_area_struct *vma = st->vma;
 	int rc;
 
@@ -216,7 +216,7 @@ static int mmap_mfn_range(void *data, void *state)
 	    ((msg->va+(msg->npages<<PAGE_SHIFT)) > vma->vm_end))
 		return -EINVAL;
 
-	rc = xen_remap_domain_mfn_range(vma,
+	rc = xen_remap_domain_gfn_range(vma,
 					msg->va & PAGE_MASK,
 					msg->mfn, msg->npages,
 					vma->vm_page_prot,
@@ -236,7 +236,7 @@ static long privcmd_ioctl_mmap(void __user *udata)
 	struct vm_area_struct *vma;
 	int rc;
 	LIST_HEAD(pagelist);
-	struct mmap_mfn_state state;
+	struct mmap_gfn_state state;
 
 	/* We only support privcmd_ioctl_mmap_batch for auto translated. */
 	if (xen_feature(XENFEAT_auto_translated_physmap))
@@ -273,7 +273,7 @@ static long privcmd_ioctl_mmap(void __user *udata)
 
 	rc = traverse_pages(mmapcmd.num, sizeof(struct privcmd_mmap_entry),
 			    &pagelist,
-			    mmap_mfn_range, &state);
+			    mmap_gfn_range, &state);
 
 
 out_up:
@@ -299,18 +299,18 @@ struct mmap_batch_state {
 	int global_error;
 	int version;
 
-	/* User-space mfn array to store errors in the second pass for V1. */
-	xen_pfn_t __user *user_mfn;
+	/* User-space gfn array to store errors in the second pass for V1. */
+	xen_pfn_t __user *user_gfn;
 	/* User-space int array to store errors in the second pass for V2. */
 	int __user *user_err;
 };
 
-/* auto translated dom0 note: if domU being created is PV, then mfn is
- * mfn(addr on bus). If it's auto xlated, then mfn is pfn (input to HAP).
+/* auto translated dom0 note: if domU being created is PV, then gfn is
+ * mfn(addr on bus). If it's auto xlated, then gfn is pfn (input to HAP).
  */
 static int mmap_batch_fn(void *data, int nr, void *state)
 {
-	xen_pfn_t *mfnp = data;
+	xen_pfn_t *gfnp = data;
 	struct mmap_batch_state *st = state;
 	struct vm_area_struct *vma = st->vma;
 	struct page **pages = vma->vm_private_data;
@@ -321,8 +321,8 @@ static int mmap_batch_fn(void *data, int nr, void *state)
 		cur_pages = &pages[st->index];
 
 	BUG_ON(nr < 0);
-	ret = xen_remap_domain_mfn_array(st->vma, st->va & PAGE_MASK, mfnp, nr,
-					 (int *)mfnp, st->vma->vm_page_prot,
+	ret = xen_remap_domain_gfn_array(st->vma, st->va & PAGE_MASK, gfnp, nr,
+					 (int *)gfnp, st->vma->vm_page_prot,
 					 st->domain, cur_pages);
 
 	/* Adjust the global_error? */
@@ -347,22 +347,22 @@ static int mmap_return_error(int err, struct mmap_batch_state *st)
 
 	if (st->version == 1) {
 		if (err) {
-			xen_pfn_t mfn;
+			xen_pfn_t gfn;
 
-			ret = get_user(mfn, st->user_mfn);
+			ret = get_user(gfn, st->user_gfn);
 			if (ret < 0)
 				return ret;
 			/*
 			 * V1 encodes the error codes in the 32bit top
-			 * nibble of the mfn (with its known
+			 * nibble of the gfn (with its known
 			 * limitations vis-a-vis 64 bit callers).
 			 */
-			mfn |= (err == -ENOENT) ?
+			gfn |= (err == -ENOENT) ?
 				PRIVCMD_MMAPBATCH_PAGED_ERROR :
 				PRIVCMD_MMAPBATCH_MFN_ERROR;
-			return __put_user(mfn, st->user_mfn++);
+			return __put_user(gfn, st->user_gfn++);
 		} else
-			st->user_mfn++;
+			st->user_gfn++;
 	} else { /* st->version == 2 */
 		if (err)
 			return __put_user(err, st->user_err++);
@@ -388,7 +388,7 @@ static int mmap_return_errors(void *data, int nr, void *state)
 	return 0;
 }
 
-/* Allocate pfns that are then mapped with gmfns from foreign domid. Update
+/* Allocate pfns that are then mapped with gfns from foreign domid. Update
  * the vma with the page info to use later.
  * Returns: 0 if success, otherwise -errno
  */
@@ -526,7 +526,7 @@ static long privcmd_ioctl_mmap_batch(void __user *udata, int version)
 
 	if (state.global_error) {
 		/* Write back errors in second pass. */
-		state.user_mfn = (xen_pfn_t *)m.arr;
+		state.user_gfn = (xen_pfn_t *)m.arr;
 		state.user_err = m.err;
 		ret = traverse_pages_block(m.num, sizeof(xen_pfn_t),
 					   &pagelist, mmap_return_errors, &state);
@@ -587,7 +587,7 @@ static void privcmd_close(struct vm_area_struct *vma)
 	if (!xen_feature(XENFEAT_auto_translated_physmap) || !numpgs || !pages)
 		return;
 
-	rc = xen_unmap_domain_mfn_range(vma, numpgs, pages);
+	rc = xen_unmap_domain_gfn_range(vma, numpgs, pages);
 	if (rc == 0)
 		free_xenballooned_pages(numpgs, pages);
 	else
diff --git a/drivers/xen/xlate_mmu.c b/drivers/xen/xlate_mmu.c
index 58a5389..cff2387 100644
--- a/drivers/xen/xlate_mmu.c
+++ b/drivers/xen/xlate_mmu.c
@@ -38,8 +38,8 @@
 #include <xen/interface/xen.h>
 #include <xen/interface/memory.h>
 
-/* map fgmfn of domid to lpfn in the current domain */
-static int map_foreign_page(unsigned long lpfn, unsigned long fgmfn,
+/* map fgfn of domid to lpfn in the current domain */
+static int map_foreign_page(unsigned long lpfn, unsigned long fgfn,
 			    unsigned int domid)
 {
 	int rc;
@@ -49,7 +49,7 @@ static int map_foreign_page(unsigned long lpfn, unsigned long fgmfn,
 		.size = 1,
 		.space = XENMAPSPACE_gmfn_foreign,
 	};
-	xen_ulong_t idx = fgmfn;
+	xen_ulong_t idx = fgfn;
 	xen_pfn_t gpfn = lpfn;
 	int err = 0;
 
@@ -62,13 +62,13 @@ static int map_foreign_page(unsigned long lpfn, unsigned long fgmfn,
 }
 
 struct remap_data {
-	xen_pfn_t *fgmfn; /* foreign domain's gmfn */
+	xen_pfn_t *fgfn; /* foreign domain's gfn */
 	pgprot_t prot;
 	domid_t  domid;
 	struct vm_area_struct *vma;
 	int index;
 	struct page **pages;
-	struct xen_remap_mfn_info *info;
+	struct xen_remap_gfn_info *info;
 	int *err_ptr;
 	int mapped;
 };
@@ -82,20 +82,20 @@ static int remap_pte_fn(pte_t *ptep, pgtable_t token, unsigned long addr,
 	pte_t pte = pte_mkspecial(pfn_pte(pfn, info->prot));
 	int rc;
 
-	rc = map_foreign_page(pfn, *info->fgmfn, info->domid);
+	rc = map_foreign_page(pfn, *info->fgfn, info->domid);
 	*info->err_ptr++ = rc;
 	if (!rc) {
 		set_pte_at(info->vma->vm_mm, addr, ptep, pte);
 		info->mapped++;
 	}
-	info->fgmfn++;
+	info->fgfn++;
 
 	return 0;
 }
 
 int xen_xlate_remap_gfn_array(struct vm_area_struct *vma,
 			      unsigned long addr,
-			      xen_pfn_t *mfn, int nr,
+			      xen_pfn_t *gfn, int nr,
 			      int *err_ptr, pgprot_t prot,
 			      unsigned domid,
 			      struct page **pages)
@@ -108,7 +108,7 @@ int xen_xlate_remap_gfn_array(struct vm_area_struct *vma,
 	   x86 PVOPS */
 	BUG_ON(!((vma->vm_flags & (VM_PFNMAP | VM_IO)) == (VM_PFNMAP | VM_IO)));
 
-	data.fgmfn = mfn;
+	data.fgfn = gfn;
 	data.prot  = prot;
 	data.domid = domid;
 	data.vma   = vma;
diff --git a/include/uapi/xen/privcmd.h b/include/uapi/xen/privcmd.h
index a853168..7ddeeda 100644
--- a/include/uapi/xen/privcmd.h
+++ b/include/uapi/xen/privcmd.h
@@ -44,6 +44,10 @@ struct privcmd_hypercall {
 
 struct privcmd_mmap_entry {
 	__u64 va;
+	/*
+	 * This should be a GFN. It's not possible to change the name because
+	 * it's exposed to the user-space.
+	 */
 	__u64 mfn;
 	__u64 npages;
 };
diff --git a/include/xen/xen-ops.h b/include/xen/xen-ops.h
index 0ce4f32..e4e214a 100644
--- a/include/xen/xen-ops.h
+++ b/include/xen/xen-ops.h
@@ -30,7 +30,7 @@ void xen_destroy_contiguous_region(phys_addr_t pstart, unsigned int order);
 struct vm_area_struct;
 
 /*
- * xen_remap_domain_mfn_array() - map an array of foreign frames
+ * xen_remap_domain_gfn_array() - map an array of foreign frames
  * @vma:     VMA to map the pages into
  * @addr:    Address at which to map the pages
  * @gfn:     Array of GFNs to map
@@ -46,14 +46,14 @@ struct vm_area_struct;
  * Returns the number of successfully mapped frames, or a -ve error
  * code.
  */
-int xen_remap_domain_mfn_array(struct vm_area_struct *vma,
+int xen_remap_domain_gfn_array(struct vm_area_struct *vma,
 			       unsigned long addr,
 			       xen_pfn_t *gfn, int nr,
 			       int *err_ptr, pgprot_t prot,
 			       unsigned domid,
 			       struct page **pages);
 
-/* xen_remap_domain_mfn_range() - map a range of foreign frames
+/* xen_remap_domain_gfn_range() - map a range of foreign frames
  * @vma:     VMA to map the pages into
  * @addr:    Address at which to map the pages
  * @gfn:     First GFN to map.
@@ -65,12 +65,12 @@ int xen_remap_domain_mfn_array(struct vm_area_struct *vma,
  * Returns the number of successfully mapped frames, or a -ve error
  * code.
  */
-int xen_remap_domain_mfn_range(struct vm_area_struct *vma,
+int xen_remap_domain_gfn_range(struct vm_area_struct *vma,
 			       unsigned long addr,
 			       xen_pfn_t gfn, int nr,
 			       pgprot_t prot, unsigned domid,
 			       struct page **pages);
-int xen_unmap_domain_mfn_range(struct vm_area_struct *vma,
+int xen_unmap_domain_gfn_range(struct vm_area_struct *vma,
 			       int numpgs, struct page **pages);
 int xen_xlate_remap_gfn_array(struct vm_area_struct *vma,
 			      unsigned long addr,
-- 
2.1.4



From julien.grall at citrix.com  Fri Aug  7 09:34:34 2015
From: julien.grall at citrix.com (Julien Grall)
Date: Fri, 7 Aug 2015 17:34:34 +0100
Subject: [PATCH v3 1/9] arm/xen: Remove helpers which are PV specific
In-Reply-To: <1438965282-19103-1-git-send-email-julien.grall@citrix.com>
References: <1438965282-19103-1-git-send-email-julien.grall@citrix.com>
Message-ID: <1438965282-19103-2-git-send-email-julien.grall@citrix.com>

ARM guests are always HVM. The current implementation is assuming a 1:1
mapping which is only true for DOM0 and may not be at all in the future.

Furthermore, all the helpers but arbitrary_virt_to_machine are used in
x86 specific code (or only compiled for).

The helper arbitrary_virt_to_machine is only used in PV specific code.
Therefore we should never call the function.

Add a BUG() in this helper and drop all the others.

Signed-off-by: Julien Grall <julien.grall at citrix.com>
Acked-by: Stefano Stabellini <stefano.stabellini at eu.citrix.com>

---
Cc: Russell King <linux at arm.linux.org.uk>
Cc: linux-arm-kernel at lists.infradead.org

    Changes in v2:
        - Typoes
        - Add Stefano's acked-by
---
 arch/arm/include/asm/xen/page.h | 16 ++--------------
 1 file changed, 2 insertions(+), 14 deletions(-)

diff --git a/arch/arm/include/asm/xen/page.h b/arch/arm/include/asm/xen/page.h
index 1bee8ca..98b1084 100644
--- a/arch/arm/include/asm/xen/page.h
+++ b/arch/arm/include/asm/xen/page.h
@@ -54,26 +54,14 @@ static inline unsigned long mfn_to_pfn(unsigned long mfn)
 
 #define mfn_to_local_pfn(mfn) mfn_to_pfn(mfn)
 
-static inline xmaddr_t phys_to_machine(xpaddr_t phys)
-{
-	unsigned offset = phys.paddr & ~PAGE_MASK;
-	return XMADDR(PFN_PHYS(pfn_to_mfn(PFN_DOWN(phys.paddr))) | offset);
-}
-
-static inline xpaddr_t machine_to_phys(xmaddr_t machine)
-{
-	unsigned offset = machine.maddr & ~PAGE_MASK;
-	return XPADDR(PFN_PHYS(mfn_to_pfn(PFN_DOWN(machine.maddr))) | offset);
-}
 /* VIRT <-> MACHINE conversion */
-#define virt_to_machine(v)	(phys_to_machine(XPADDR(__pa(v))))
 #define virt_to_mfn(v)		(pfn_to_mfn(virt_to_pfn(v)))
 #define mfn_to_virt(m)		(__va(mfn_to_pfn(m) << PAGE_SHIFT))
 
+/* Only used in PV code. But ARM guests are always HVM. */
 static inline xmaddr_t arbitrary_virt_to_machine(void *vaddr)
 {
-	/* TODO: assuming it is mapped in the kernel 1:1 */
-	return virt_to_machine(vaddr);
+	BUG();
 }
 
 /* TODO: this shouldn't be here but it is because the frontend drivers
-- 
2.1.4



From julien.grall at citrix.com  Fri Aug  7 09:34:36 2015
From: julien.grall at citrix.com (Julien Grall)
Date: Fri, 7 Aug 2015 17:34:36 +0100
Subject: [PATCH v3 3/9] arm/xen: implement correctly pfn_to_mfn
In-Reply-To: <1438965282-19103-1-git-send-email-julien.grall@citrix.com>
References: <1438965282-19103-1-git-send-email-julien.grall@citrix.com>
Message-ID: <1438965282-19103-4-git-send-email-julien.grall@citrix.com>

After the commit introducing convertion between DMA and guest addresses,
all the callers of pfn_to_mfn are expecting to get a GFN (Guest Frame
Number). On ARM, all the guests are auto-translated so the GFN is equal
to the Linux PFN (Pseudo-physical Frame Number).

The current implementation may return an MFN if the caller is passing a
PFN associated to a mapped foreign grant. In pratice, I haven't seen
the problem on running guest but we should fix it for the sake of
correctness.

Correct the implementation by always returning the pfn passed in parameter.

A follow-up patch will take care to rename pfn_to_mfn to a suitable
name.

Signed-off-by: Julien Grall <julien.grall at citrix.com>
Reviewed-by: Stefano Stabellini <stefano.stabellini at eu.citrix.com>

---
Cc: Russell King <linux at arm.linux.org.uk>
Cc: linux-arm-kernel at lists.infradead.org

    Changes in v3:
        - Typoes in the commit message
        - Add Stefano's reviewed-by
---
 arch/arm/include/asm/xen/page.h | 8 --------
 1 file changed, 8 deletions(-)

diff --git a/arch/arm/include/asm/xen/page.h b/arch/arm/include/asm/xen/page.h
index 5f76a9e..911d62b 100644
--- a/arch/arm/include/asm/xen/page.h
+++ b/arch/arm/include/asm/xen/page.h
@@ -36,14 +36,6 @@ extern struct rb_root phys_to_mach;
 
 static inline unsigned long pfn_to_mfn(unsigned long pfn)
 {
-	unsigned long mfn;
-
-	if (phys_to_mach.rb_node != NULL) {
-		mfn = __pfn_to_mfn(pfn);
-		if (mfn != INVALID_P2M_ENTRY)
-			return mfn;
-	}
-
 	return pfn;
 }
 
-- 
2.1.4



From julien.grall at citrix.com  Fri Aug  7 09:34:37 2015
From: julien.grall at citrix.com (Julien Grall)
Date: Fri, 7 Aug 2015 17:34:37 +0100
Subject: [PATCH v3 4/9] xen: Use correctly the Xen memory terminologies
In-Reply-To: <1438965282-19103-1-git-send-email-julien.grall@citrix.com>
References: <1438965282-19103-1-git-send-email-julien.grall@citrix.com>
Message-ID: <1438965282-19103-5-git-send-email-julien.grall@citrix.com>

Based on include/xen/mm.h [1], Linux is mistakenly using MFN when GFN
is meant, I suspect this is because the first support for Xen was for
PV. This resulted in some misimplementation of helpers on ARM and
confused developers about the expected behavior.

For instance, with pfn_to_mfn, we expect to get an MFN based on the name.
Although, if we look at the implementation on x86, it's returning a GFN.

For clarity and avoid new confusion, replace any reference to mfn with
gfn in any helpers used by PV drivers. The x86 code will still keep some
reference of pfn_to_mfn but exclusively for PV (a BUG_ON has been added
to ensure this). No changes as been made in the hypercall field, even
though they may be invalid, in order to keep the same as the defintion
in xen repo.

Note that page_to_mfn has been renamed to xen_page_to_gfn to avoid a
name to close to the KVM function gfn_to_page.

Take also the opportunity to simplify simple construction such
as pfn_to_mfn(page_to_pfn(page)) into xen_page_to_gfn. More complex clean up
will come in follow-up patches.

[1] http://xenbits.xen.org/gitweb/?p=xen.git;a=commitdiff;h=e758ed14f390342513405dd766e874934573e6cb

Signed-off-by: Julien Grall <julien.grall at citrix.com>
Reviewed-by: Stefano Stabellini <stefano.stabellini at eu.citrix.com>
Acked-by: Dmitry Torokhov <dmitry.torokhov at gmail.com>
Acked-by: Wei Liu <wei.liu2 at citrix.com>

---
Cc: Russell King <linux at arm.linux.org.uk>
Cc: Konrad Rzeszutek Wilk <konrad.wilk at oracle.com>
Cc: Boris Ostrovsky <boris.ostrovsky at oracle.com>
Cc: David Vrabel <david.vrabel at citrix.com>
Cc: Thomas Gleixner <tglx at linutronix.de>
Cc: Ingo Molnar <mingo at redhat.com>
Cc: "H. Peter Anvin" <hpa at zytor.com>
Cc: x86 at kernel.org
Cc: "Roger Pau Monn?" <roger.pau at citrix.com>
Cc: Ian Campbell <ian.campbell at citrix.com>
Cc: Juergen Gross <jgross at suse.com>
Cc: "James E.J. Bottomley" <JBottomley at odin.com>
Cc: Greg Kroah-Hartman <gregkh at linuxfoundation.org>
Cc: Jiri Slaby <jslaby at suse.com>
Cc: Jean-Christophe Plagniol-Villard <plagnioj at jcrosoft.com>
Cc: Tomi Valkeinen <tomi.valkeinen at ti.com>
Cc: linux-input at vger.kernel.org
Cc: netdev at vger.kernel.org
Cc: linux-scsi at vger.kernel.org
Cc: linuxppc-dev at lists.ozlabs.org
Cc: linux-fbdev at vger.kernel.org
Cc: linux-arm-kernel at lists.infradead.org

    Note that I've re-introduced in v2 mfn_to_pfn & co only for x86 PV code.
    The helpers contain a BUG_ON to ensure that it's never called for
    auto-translated guests. I did as best as my can to determine whether
    mfn or gfn helpers should be used. Although, I haven't tried to boot
    it.

    It may be possible to do further cleanup in the mmu.c where I found
    some check to auto-translated. I'm not sure why given that the pvmmu
    callback are only used for non-auto translated guest.

    Changes in v3:
        - Add Stefano's reviewed-by (except for the x86 bits)
        - Add Wei (netback) and Dmitry's (input) acked-by
        - Keep the VIRT <-> MACHINE macro in the same order as before
        in arch/x86/include/asm/xen/page.h
        - Rename page_to_gfn to xen_page_to_gfn to avoid confusion with
        the KVM function gfn_to_page.
        - Typoes in the commit title

    Changes in v2:
        - Give directly the URL to the commit rather than the commit ID
        - xenstored_local_init: keep the cast to void *
        - Typoes
        - Keep pfn_to_mfn for x86 and PV-only. The *mfn* helpers are
        used in arch/x86/xen for enlighten.c, mmu.c, p2m.c, setup.c,
        smp.c and mm.c
---
 arch/arm/include/asm/xen/page.h         | 13 +++++++------
 arch/x86/include/asm/xen/page.h         | 31 +++++++++++++++++++++++++------
 arch/x86/xen/smp.c                      |  2 +-
 drivers/block/xen-blkfront.c            |  6 +++---
 drivers/input/misc/xen-kbdfront.c       |  4 ++--
 drivers/net/xen-netback/netback.c       |  4 ++--
 drivers/net/xen-netfront.c              | 12 +++++++-----
 drivers/scsi/xen-scsifront.c            | 10 +++++-----
 drivers/tty/hvc/hvc_xen.c               |  5 +++--
 drivers/video/fbdev/xen-fbfront.c       |  4 ++--
 drivers/xen/balloon.c                   |  2 +-
 drivers/xen/events/events_base.c        |  2 +-
 drivers/xen/events/events_fifo.c        |  4 ++--
 drivers/xen/gntalloc.c                  |  3 ++-
 drivers/xen/manage.c                    |  2 +-
 drivers/xen/tmem.c                      |  4 ++--
 drivers/xen/xenbus/xenbus_client.c      |  2 +-
 drivers/xen/xenbus/xenbus_dev_backend.c |  2 +-
 drivers/xen/xenbus/xenbus_probe.c       |  8 +++-----
 include/xen/page.h                      |  4 ++--
 20 files changed, 73 insertions(+), 51 deletions(-)

diff --git a/arch/arm/include/asm/xen/page.h b/arch/arm/include/asm/xen/page.h
index 911d62b..1279563 100644
--- a/arch/arm/include/asm/xen/page.h
+++ b/arch/arm/include/asm/xen/page.h
@@ -34,14 +34,15 @@ typedef struct xpaddr {
 unsigned long __pfn_to_mfn(unsigned long pfn);
 extern struct rb_root phys_to_mach;
 
-static inline unsigned long pfn_to_mfn(unsigned long pfn)
+/* Pseudo-physical <-> Guest conversion */
+static inline unsigned long pfn_to_gfn(unsigned long pfn)
 {
 	return pfn;
 }
 
-static inline unsigned long mfn_to_pfn(unsigned long mfn)
+static inline unsigned long gfn_to_pfn(unsigned long gfn)
 {
-	return mfn;
+	return gfn;
 }
 
 /* Pseudo-physical <-> BUS conversion */
@@ -65,9 +66,9 @@ static inline unsigned long bfn_to_pfn(unsigned long bfn)
 
 #define bfn_to_local_pfn(bfn)	bfn_to_pfn(bfn)
 
-/* VIRT <-> MACHINE conversion */
-#define virt_to_mfn(v)		(pfn_to_mfn(virt_to_pfn(v)))
-#define mfn_to_virt(m)		(__va(mfn_to_pfn(m) << PAGE_SHIFT))
+/* VIRT <-> GUEST conversion */
+#define virt_to_gfn(v)		(pfn_to_gfn(virt_to_pfn(v)))
+#define gfn_to_virt(m)		(__va(gfn_to_pfn(m) << PAGE_SHIFT))
 
 /* Only used in PV code. But ARM guests are always HVM. */
 static inline xmaddr_t arbitrary_virt_to_machine(void *vaddr)
diff --git a/arch/x86/include/asm/xen/page.h b/arch/x86/include/asm/xen/page.h
index 724bffb..0b762f6 100644
--- a/arch/x86/include/asm/xen/page.h
+++ b/arch/x86/include/asm/xen/page.h
@@ -101,8 +101,7 @@ static inline unsigned long pfn_to_mfn(unsigned long pfn)
 {
 	unsigned long mfn;
 
-	if (xen_feature(XENFEAT_auto_translated_physmap))
-		return pfn;
+	BUG_ON(xen_feature(XENFEAT_auto_translated_physmap));
 
 	mfn = __pfn_to_mfn(pfn);
 
@@ -147,8 +146,7 @@ static inline unsigned long mfn_to_pfn(unsigned long mfn)
 {
 	unsigned long pfn;
 
-	if (xen_feature(XENFEAT_auto_translated_physmap))
-		return mfn;
+	BUG_ON(xen_feature(XENFEAT_auto_translated_physmap));
 
 	pfn = mfn_to_pfn_no_overrides(mfn);
 	if (__pfn_to_mfn(pfn) != mfn)
@@ -176,9 +174,26 @@ static inline xpaddr_t machine_to_phys(xmaddr_t machine)
 	return XPADDR(PFN_PHYS(mfn_to_pfn(PFN_DOWN(machine.maddr))) | offset);
 }
 
+/* Pseudo-physical <-> Guest conversion */
+static inline unsigned long pfn_to_gfn(unsigned long pfn)
+{
+	if (xen_feature(XENFEAT_auto_translated_physmap))
+		return pfn;
+	else
+		return pfn_to_mfn(pfn);
+}
+
+static inline unsigned long gfn_to_pfn(unsigned long gfn)
+{
+	if (xen_feature(XENFEAT_auto_translated_physmap))
+		return gfn;
+	else
+		return mfn_to_pfn(gfn);
+}
+
 /* Pseudo-physical <-> Bus conversion */
-#define pfn_to_bfn(pfn)		pfn_to_mfn(pfn)
-#define bfn_to_pfn(bfn)		mfn_to_pfn(bfn)
+#define pfn_to_bfn(pfn)		pfn_to_gfn(pfn)
+#define bfn_to_pfn(bfn)		gfn_to_pfn(bfn)
 
 /*
  * We detect special mappings in one of two ways:
@@ -219,6 +234,10 @@ static inline unsigned long bfn_to_local_pfn(unsigned long mfn)
 #define virt_to_mfn(v)		(pfn_to_mfn(virt_to_pfn(v)))
 #define mfn_to_virt(m)		(__va(mfn_to_pfn(m) << PAGE_SHIFT))
 
+/* VIRT <-> GUEST conversion */
+#define virt_to_gfn(v)		(pfn_to_gfn(virt_to_pfn(v)))
+#define gfn_to_virt(g)		(__va(gfn_to_pfn(g) << PAGE_SHIFT))
+
 static inline unsigned long pte_mfn(pte_t pte)
 {
 	return (pte.pte & PTE_PFN_MASK) >> PAGE_SHIFT;
diff --git a/arch/x86/xen/smp.c b/arch/x86/xen/smp.c
index 8648438..1e0931b 100644
--- a/arch/x86/xen/smp.c
+++ b/arch/x86/xen/smp.c
@@ -429,7 +429,7 @@ cpu_initialize_context(unsigned int cpu, struct task_struct *idle)
 	}
 #endif
 	ctxt->user_regs.esp = idle->thread.sp0 - sizeof(struct pt_regs);
-	ctxt->ctrlreg[3] = xen_pfn_to_cr3(virt_to_mfn(swapper_pg_dir));
+	ctxt->ctrlreg[3] = xen_pfn_to_cr3(virt_to_gfn(swapper_pg_dir));
 	if (HYPERVISOR_vcpu_op(VCPUOP_initialise, cpu, ctxt))
 		BUG();
 
diff --git a/drivers/block/xen-blkfront.c b/drivers/block/xen-blkfront.c
index 5b45ee5..ebb3624 100644
--- a/drivers/block/xen-blkfront.c
+++ b/drivers/block/xen-blkfront.c
@@ -249,7 +249,7 @@ static struct grant *get_grant(grant_ref_t *gref_head,
                                struct blkfront_info *info)
 {
 	struct grant *gnt_list_entry;
-	unsigned long buffer_mfn;
+	unsigned long buffer_gfn;
 
 	BUG_ON(list_empty(&info->grants));
 	gnt_list_entry = list_first_entry(&info->grants, struct grant,
@@ -268,10 +268,10 @@ static struct grant *get_grant(grant_ref_t *gref_head,
 		BUG_ON(!pfn);
 		gnt_list_entry->pfn = pfn;
 	}
-	buffer_mfn = pfn_to_mfn(gnt_list_entry->pfn);
+	buffer_gfn = pfn_to_gfn(gnt_list_entry->pfn);
 	gnttab_grant_foreign_access_ref(gnt_list_entry->gref,
 	                                info->xbdev->otherend_id,
-	                                buffer_mfn, 0);
+	                                buffer_gfn, 0);
 	return gnt_list_entry;
 }
 
diff --git a/drivers/input/misc/xen-kbdfront.c b/drivers/input/misc/xen-kbdfront.c
index 95599e4..23d0549 100644
--- a/drivers/input/misc/xen-kbdfront.c
+++ b/drivers/input/misc/xen-kbdfront.c
@@ -232,7 +232,7 @@ static int xenkbd_connect_backend(struct xenbus_device *dev,
 	struct xenbus_transaction xbt;
 
 	ret = gnttab_grant_foreign_access(dev->otherend_id,
-	                                  virt_to_mfn(info->page), 0);
+	                                  virt_to_gfn(info->page), 0);
 	if (ret < 0)
 		return ret;
 	info->gref = ret;
@@ -255,7 +255,7 @@ static int xenkbd_connect_backend(struct xenbus_device *dev,
 		goto error_irqh;
 	}
 	ret = xenbus_printf(xbt, dev->nodename, "page-ref", "%lu",
-			    virt_to_mfn(info->page));
+			    virt_to_gfn(info->page));
 	if (ret)
 		goto error_xenbus;
 	ret = xenbus_printf(xbt, dev->nodename, "page-gref", "%u", info->gref);
diff --git a/drivers/net/xen-netback/netback.c b/drivers/net/xen-netback/netback.c
index 880d0d6..8293374 100644
--- a/drivers/net/xen-netback/netback.c
+++ b/drivers/net/xen-netback/netback.c
@@ -314,7 +314,7 @@ static void xenvif_gop_frag_copy(struct xenvif_queue *queue, struct sk_buff *skb
 		} else {
 			copy_gop->source.domid = DOMID_SELF;
 			copy_gop->source.u.gmfn =
-				virt_to_mfn(page_address(page));
+				virt_to_gfn(page_address(page));
 		}
 		copy_gop->source.offset = offset;
 
@@ -1284,7 +1284,7 @@ static void xenvif_tx_build_gops(struct xenvif_queue *queue,
 		queue->tx_copy_ops[*copy_ops].source.offset = txreq.offset;
 
 		queue->tx_copy_ops[*copy_ops].dest.u.gmfn =
-			virt_to_mfn(skb->data);
+			virt_to_gfn(skb->data);
 		queue->tx_copy_ops[*copy_ops].dest.domid = DOMID_SELF;
 		queue->tx_copy_ops[*copy_ops].dest.offset =
 			offset_in_page(skb->data);
diff --git a/drivers/net/xen-netfront.c b/drivers/net/xen-netfront.c
index f948c46..47f791e 100644
--- a/drivers/net/xen-netfront.c
+++ b/drivers/net/xen-netfront.c
@@ -291,7 +291,7 @@ static void xennet_alloc_rx_buffers(struct netfront_queue *queue)
 		struct sk_buff *skb;
 		unsigned short id;
 		grant_ref_t ref;
-		unsigned long pfn;
+		unsigned long gfn;
 		struct xen_netif_rx_request *req;
 
 		skb = xennet_alloc_one_rx_buffer(queue);
@@ -307,12 +307,12 @@ static void xennet_alloc_rx_buffers(struct netfront_queue *queue)
 		BUG_ON((signed short)ref < 0);
 		queue->grant_rx_ref[id] = ref;
 
-		pfn = page_to_pfn(skb_frag_page(&skb_shinfo(skb)->frags[0]));
+		gfn = xen_page_to_gfn(skb_frag_page(&skb_shinfo(skb)->frags[0]));
 
 		req = RING_GET_REQUEST(&queue->rx, req_prod);
 		gnttab_grant_foreign_access_ref(ref,
 						queue->info->xbdev->otherend_id,
-						pfn_to_mfn(pfn),
+						gfn,
 						0);
 
 		req->id = id;
@@ -430,8 +430,10 @@ static struct xen_netif_tx_request *xennet_make_one_txreq(
 	ref = gnttab_claim_grant_reference(&queue->gref_tx_head);
 	BUG_ON((signed short)ref < 0);
 
-	gnttab_grant_foreign_access_ref(ref, queue->info->xbdev->otherend_id,
-					page_to_mfn(page), GNTMAP_readonly);
+	gnttab_grant_foreign_access_ref(ref,
+					queue->info->xbdev->otherend_id,
+					xen_page_to_gfn(page),
+					GNTMAP_readonly);
 
 	queue->tx_skbs[id].skb = skb;
 	queue->grant_tx_page[id] = page;
diff --git a/drivers/scsi/xen-scsifront.c b/drivers/scsi/xen-scsifront.c
index fad22ca..9dc8687 100644
--- a/drivers/scsi/xen-scsifront.c
+++ b/drivers/scsi/xen-scsifront.c
@@ -377,7 +377,6 @@ static int map_data_for_request(struct vscsifrnt_info *info,
 	unsigned int data_len = scsi_bufflen(sc);
 	unsigned int data_grants = 0, seg_grants = 0;
 	struct scatterlist *sg;
-	unsigned long mfn;
 	struct scsiif_request_segment *seg;
 
 	ring_req->nr_segments = 0;
@@ -420,9 +419,9 @@ static int map_data_for_request(struct vscsifrnt_info *info,
 			ref = gnttab_claim_grant_reference(&gref_head);
 			BUG_ON(ref == -ENOSPC);
 
-			mfn = pfn_to_mfn(page_to_pfn(page));
 			gnttab_grant_foreign_access_ref(ref,
-				info->dev->otherend_id, mfn, 1);
+				info->dev->otherend_id,
+				xen_page_to_gfn(page), 1);
 			shadow->gref[ref_cnt] = ref;
 			ring_req->seg[ref_cnt].gref   = ref;
 			ring_req->seg[ref_cnt].offset = (uint16_t)off;
@@ -454,9 +453,10 @@ static int map_data_for_request(struct vscsifrnt_info *info,
 			ref = gnttab_claim_grant_reference(&gref_head);
 			BUG_ON(ref == -ENOSPC);
 
-			mfn = pfn_to_mfn(page_to_pfn(page));
 			gnttab_grant_foreign_access_ref(ref,
-				info->dev->otherend_id, mfn, grant_ro);
+				info->dev->otherend_id,
+				xen_page_to_gfn(page),
+				grant_ro);
 
 			shadow->gref[ref_cnt] = ref;
 			seg->gref   = ref;
diff --git a/drivers/tty/hvc/hvc_xen.c b/drivers/tty/hvc/hvc_xen.c
index a9d837f..efe5124 100644
--- a/drivers/tty/hvc/hvc_xen.c
+++ b/drivers/tty/hvc/hvc_xen.c
@@ -265,7 +265,8 @@ static int xen_pv_console_init(void)
 		return 0;
 	}
 	info->evtchn = xen_start_info->console.domU.evtchn;
-	info->intf = mfn_to_virt(xen_start_info->console.domU.mfn);
+	/* GFN == MFN for PV guest */
+	info->intf = gfn_to_virt(xen_start_info->console.domU.mfn);
 	info->vtermno = HVC_COOKIE;
 
 	spin_lock(&xencons_lock);
@@ -390,7 +391,7 @@ static int xencons_connect_backend(struct xenbus_device *dev,
 	if (IS_ERR(info->hvc))
 		return PTR_ERR(info->hvc);
 	if (xen_pv_domain())
-		mfn = virt_to_mfn(info->intf);
+		mfn = virt_to_gfn(info->intf);
 	else
 		mfn = __pa(info->intf) >> PAGE_SHIFT;
 	ret = gnttab_alloc_grant_references(1, &gref_head);
diff --git a/drivers/video/fbdev/xen-fbfront.c b/drivers/video/fbdev/xen-fbfront.c
index 09dc447..25e3cce 100644
--- a/drivers/video/fbdev/xen-fbfront.c
+++ b/drivers/video/fbdev/xen-fbfront.c
@@ -539,7 +539,7 @@ static int xenfb_remove(struct xenbus_device *dev)
 
 static unsigned long vmalloc_to_mfn(void *address)
 {
-	return pfn_to_mfn(vmalloc_to_pfn(address));
+	return pfn_to_gfn(vmalloc_to_pfn(address));
 }
 
 static void xenfb_init_shared_page(struct xenfb_info *info,
@@ -586,7 +586,7 @@ static int xenfb_connect_backend(struct xenbus_device *dev,
 		goto unbind_irq;
 	}
 	ret = xenbus_printf(xbt, dev->nodename, "page-ref", "%lu",
-			    virt_to_mfn(info->page));
+			    virt_to_gfn(info->page));
 	if (ret)
 		goto error_xenbus;
 	ret = xenbus_printf(xbt, dev->nodename, "event-channel", "%u",
diff --git a/drivers/xen/balloon.c b/drivers/xen/balloon.c
index fd93369..9734649 100644
--- a/drivers/xen/balloon.c
+++ b/drivers/xen/balloon.c
@@ -441,7 +441,7 @@ static enum bp_state decrease_reservation(unsigned long nr_pages, gfp_t gfp)
 	/* Update direct mapping, invalidate P2M, and add to balloon. */
 	for (i = 0; i < nr_pages; i++) {
 		pfn = frame_list[i];
-		frame_list[i] = pfn_to_mfn(pfn);
+		frame_list[i] = pfn_to_gfn(pfn);
 		page = pfn_to_page(pfn);
 
 #ifdef CONFIG_XEN_HAVE_PVMMU
diff --git a/drivers/xen/events/events_base.c b/drivers/xen/events/events_base.c
index ed620e5..c49bb7a 100644
--- a/drivers/xen/events/events_base.c
+++ b/drivers/xen/events/events_base.c
@@ -1688,7 +1688,7 @@ void __init xen_init_IRQ(void)
 		struct physdev_pirq_eoi_gmfn eoi_gmfn;
 
 		pirq_eoi_map = (void *)__get_free_page(GFP_KERNEL|__GFP_ZERO);
-		eoi_gmfn.gmfn = virt_to_mfn(pirq_eoi_map);
+		eoi_gmfn.gmfn = virt_to_gfn(pirq_eoi_map);
 		rc = HYPERVISOR_physdev_op(PHYSDEVOP_pirq_eoi_gmfn_v2, &eoi_gmfn);
 		/* TODO: No PVH support for PIRQ EOI */
 		if (rc != 0) {
diff --git a/drivers/xen/events/events_fifo.c b/drivers/xen/events/events_fifo.c
index ed673e1..1d4baf5 100644
--- a/drivers/xen/events/events_fifo.c
+++ b/drivers/xen/events/events_fifo.c
@@ -111,7 +111,7 @@ static int init_control_block(int cpu,
 	for (i = 0; i < EVTCHN_FIFO_MAX_QUEUES; i++)
 		q->head[i] = 0;
 
-	init_control.control_gfn = virt_to_mfn(control_block);
+	init_control.control_gfn = virt_to_gfn(control_block);
 	init_control.offset      = 0;
 	init_control.vcpu        = cpu;
 
@@ -167,7 +167,7 @@ static int evtchn_fifo_setup(struct irq_info *info)
 		/* Mask all events in this page before adding it. */
 		init_array_page(array_page);
 
-		expand_array.array_gfn = virt_to_mfn(array_page);
+		expand_array.array_gfn = virt_to_gfn(array_page);
 
 		ret = HYPERVISOR_event_channel_op(EVTCHNOP_expand_array, &expand_array);
 		if (ret < 0)
diff --git a/drivers/xen/gntalloc.c b/drivers/xen/gntalloc.c
index e53fe19..14370df 100644
--- a/drivers/xen/gntalloc.c
+++ b/drivers/xen/gntalloc.c
@@ -142,7 +142,8 @@ static int add_grefs(struct ioctl_gntalloc_alloc_gref *op,
 
 		/* Grant foreign access to the page. */
 		rc = gnttab_grant_foreign_access(op->domid,
-			pfn_to_mfn(page_to_pfn(gref->page)), readonly);
+						 xen_page_to_gfn(gref->page),
+						 readonly);
 		if (rc < 0)
 			goto undo;
 		gref_ids[i] = gref->gref_id = rc;
diff --git a/drivers/xen/manage.c b/drivers/xen/manage.c
index d10effe..e12bd36 100644
--- a/drivers/xen/manage.c
+++ b/drivers/xen/manage.c
@@ -80,7 +80,7 @@ static int xen_suspend(void *data)
 	 * is resuming in a new domain.
 	 */
 	si->cancelled = HYPERVISOR_suspend(xen_pv_domain()
-                                           ? virt_to_mfn(xen_start_info)
+                                           ? virt_to_gfn(xen_start_info)
                                            : 0);
 
 	xen_arch_post_suspend(si->cancelled);
diff --git a/drivers/xen/tmem.c b/drivers/xen/tmem.c
index 239738f..28c97ff 100644
--- a/drivers/xen/tmem.c
+++ b/drivers/xen/tmem.c
@@ -131,7 +131,7 @@ static int xen_tmem_new_pool(struct tmem_pool_uuid uuid,
 static int xen_tmem_put_page(u32 pool_id, struct tmem_oid oid,
 			     u32 index, unsigned long pfn)
 {
-	unsigned long gmfn = xen_pv_domain() ? pfn_to_mfn(pfn) : pfn;
+	unsigned long gmfn = pfn_to_gfn(pfn);
 
 	return xen_tmem_op(TMEM_PUT_PAGE, pool_id, oid, index,
 		gmfn, 0, 0, 0);
@@ -140,7 +140,7 @@ static int xen_tmem_put_page(u32 pool_id, struct tmem_oid oid,
 static int xen_tmem_get_page(u32 pool_id, struct tmem_oid oid,
 			     u32 index, unsigned long pfn)
 {
-	unsigned long gmfn = xen_pv_domain() ? pfn_to_mfn(pfn) : pfn;
+	unsigned long gmfn = pfn_to_gfn(pfn);
 
 	return xen_tmem_op(TMEM_GET_PAGE, pool_id, oid, index,
 		gmfn, 0, 0, 0);
diff --git a/drivers/xen/xenbus/xenbus_client.c b/drivers/xen/xenbus/xenbus_client.c
index 9ad3272..daa267a 100644
--- a/drivers/xen/xenbus/xenbus_client.c
+++ b/drivers/xen/xenbus/xenbus_client.c
@@ -380,7 +380,7 @@ int xenbus_grant_ring(struct xenbus_device *dev, void *vaddr,
 
 	for (i = 0; i < nr_pages; i++) {
 		err = gnttab_grant_foreign_access(dev->otherend_id,
-						  virt_to_mfn(vaddr), 0);
+						  virt_to_gfn(vaddr), 0);
 		if (err < 0) {
 			xenbus_dev_fatal(dev, err,
 					 "granting access to ring page");
diff --git a/drivers/xen/xenbus/xenbus_dev_backend.c b/drivers/xen/xenbus/xenbus_dev_backend.c
index b17707e..ee6d9ef 100644
--- a/drivers/xen/xenbus/xenbus_dev_backend.c
+++ b/drivers/xen/xenbus/xenbus_dev_backend.c
@@ -49,7 +49,7 @@ static long xenbus_alloc(domid_t domid)
 		goto out_err;
 
 	gnttab_grant_foreign_access_ref(GNTTAB_RESERVED_XENSTORE, domid,
-			virt_to_mfn(xen_store_interface), 0 /* writable */);
+			virt_to_gfn(xen_store_interface), 0 /* writable */);
 
 	arg.dom = DOMID_SELF;
 	arg.remote_dom = domid;
diff --git a/drivers/xen/xenbus/xenbus_probe.c b/drivers/xen/xenbus/xenbus_probe.c
index 4308fb3..b3870f4 100644
--- a/drivers/xen/xenbus/xenbus_probe.c
+++ b/drivers/xen/xenbus/xenbus_probe.c
@@ -711,9 +711,7 @@ static int __init xenstored_local_init(void)
 	if (!page)
 		goto out_err;
 
-	xen_store_mfn = xen_start_info->store_mfn =
-		pfn_to_mfn(virt_to_phys((void *)page) >>
-			   PAGE_SHIFT);
+	xen_store_mfn = xen_start_info->store_mfn = virt_to_gfn((void *)page);
 
 	/* Next allocate a local port which xenstored can bind to */
 	alloc_unbound.dom        = DOMID_SELF;
@@ -787,12 +785,12 @@ static int __init xenbus_init(void)
 		err = xenstored_local_init();
 		if (err)
 			goto out_error;
-		xen_store_interface = mfn_to_virt(xen_store_mfn);
+		xen_store_interface = gfn_to_virt(xen_store_mfn);
 		break;
 	case XS_PV:
 		xen_store_evtchn = xen_start_info->store_evtchn;
 		xen_store_mfn = xen_start_info->store_mfn;
-		xen_store_interface = mfn_to_virt(xen_store_mfn);
+		xen_store_interface = gfn_to_virt(xen_store_mfn);
 		break;
 	case XS_HVM:
 		err = hvm_get_parameter(HVM_PARAM_STORE_EVTCHN, &v);
diff --git a/include/xen/page.h b/include/xen/page.h
index c5ed20b..f202992 100644
--- a/include/xen/page.h
+++ b/include/xen/page.h
@@ -3,9 +3,9 @@
 
 #include <asm/xen/page.h>
 
-static inline unsigned long page_to_mfn(struct page *page)
+static inline unsigned long xen_page_to_gfn(struct page *page)
 {
-	return pfn_to_mfn(page_to_pfn(page));
+	return pfn_to_gfn(page_to_pfn(page));
 }
 
 struct xen_memory_region {
-- 
2.1.4



From ddaney at caviumnetworks.com  Fri Aug  7 09:40:41 2015
From: ddaney at caviumnetworks.com (David Daney)
Date: Fri, 7 Aug 2015 09:40:41 -0700
Subject: [PATCH 2/2] net, thunder, bgx: Add support for ACPI binding.
In-Reply-To: <55C4A7AC.1080902@linaro.org>
References: <1438907590-29649-1-git-send-email-ddaney.cavm@gmail.com>
 <1438907590-29649-3-git-send-email-ddaney.cavm@gmail.com>
 <55C467A0.4020601@linaro.org> <20150807104320.GQ1820@rric.localhost>
 <55C48DF9.70406@linaro.org> <20150807115622.GS4914@rric.localhost>
 <55C4A7AC.1080902@linaro.org>
Message-ID: <55C4DF89.9060502@caviumnetworks.com>

On 08/07/2015 05:42 AM, Tomasz Nowicki wrote:
> On 07.08.2015 13:56, Robert Richter wrote:
>> On 07.08.15 12:52:41, Tomasz Nowicki wrote:
[...]

>>>>
>>>> I would not pollute bgx_probe() with acpi and dt specifics, and instead
>>>> keep bgx_init_phy(). The typical design pattern for this is:
>>>>
>>>> static int bgx_init_phy(struct bgx *bgx)
>>>> {
>>>> #ifdef CONFIG_ACPI
>>>>          if (!acpi_disabled)
>>>>                  return bgx_init_acpi_phy(bgx);
>>>> #endif
>>>>          return bgx_init_of_phy(bgx);
>>>> }
>>>>
>>>> This adds acpi runtime detection (acpi=no), does not call dt code in
>>>> case of acpi, and saves the #else for bgx_init_acpi_phy().
>>>>
>>>
>>> I am fine with keeping it in bgx_init_phy(), however we can drop there
>>> #ifdefs since both of bgx_init_{acpi,of}_phy calls have empty stub
>>> for !ACPI
>>> and !OF case. Like that:
>>>
>>> static int bgx_init_phy(struct bgx *bgx)
>>> {
>>>
>>>          if (!acpi_disabled)
>>>                  return bgx_init_acpi_phy(bgx);
>>>     else
>>>              return bgx_init_of_phy(bgx);
>>> }
>>
>> As said, keeping it in #ifdefs makes the empty stub function for !acpi
>> obsolete, which makes the code smaller and better readable. This style
>> is common practice in the kernel. Apart from that, the 'else' should
>> be dropped as it is useless.
>>
>
> I would't say the code is better readable (bgx_init_of_phy has still two
> stubs) but this is just cosmetic, my point was to use run time detection
> using acpi_disabled.
>

Thanks Tomasz and Robert for the input.  Because of this, it seems that 
another version of the patch will be necessary.  In the interests of 
code clarity and asthetics, we will go with the code without the 
#ifdefs, and rely on the compiler to optimize away any dead code.

David Daney

> Tomasz



From julien.grall at citrix.com  Fri Aug  7 09:46:47 2015
From: julien.grall at citrix.com (Julien Grall)
Date: Fri, 7 Aug 2015 17:46:47 +0100
Subject: [PATCH v3 08/20] block/xen-blkfront: split get_grant in 2
In-Reply-To: <1438966019-19322-1-git-send-email-julien.grall@citrix.com>
References: <1438966019-19322-1-git-send-email-julien.grall@citrix.com>
Message-ID: <1438966019-19322-9-git-send-email-julien.grall@citrix.com>

Prepare the code to support 64KB page granularity. The first
implementation will use a full Linux page per indirect and persistent
grant. When non-persistent grant is used, each page of a bio request
may be split in multiple grant.

Furthermore, the field page of the grant structure is only used to copy
data from persistent grant or indirect grant. Avoid to set it for other
use case as it will have no meaning given the page will be split in
multiple grant.

Provide 2 functions, to setup indirect grant, the other for bio page.

Signed-off-by: Julien Grall <julien.grall at citrix.com>

---
Cc: Konrad Rzeszutek Wilk <konrad.wilk at oracle.com>
Cc: Roger Pau Monn? <roger.pau at citrix.com>
Cc: Boris Ostrovsky <boris.ostrovsky at oracle.com>
Cc: David Vrabel <david.vrabel at citrix.com>

    Changes in v3:
        - Fix errors reported by checkpatch.pl
        - gnttab_page_grant_foreign_access_ref has been renamed to
        gnttab_page_grant_foreign_access_ref_one
        - Fix compilation by using get_indirect_grant rather than
        get_grant (the changes was in a later patch...).
        - Make grant_foreign_access static inline
        - s/mfn/gfn/ based on the new naming

    Changes in v2:
        - Patch added
---
 drivers/block/xen-blkfront.c | 88 +++++++++++++++++++++++++++++---------------
 1 file changed, 59 insertions(+), 29 deletions(-)

diff --git a/drivers/block/xen-blkfront.c b/drivers/block/xen-blkfront.c
index e431e82..52105e7 100644
--- a/drivers/block/xen-blkfront.c
+++ b/drivers/block/xen-blkfront.c
@@ -244,34 +244,77 @@ out_of_memory:
 	return -ENOMEM;
 }
 
-static struct grant *get_grant(grant_ref_t *gref_head,
-			       struct page *page,
-			       struct blkfront_info *info)
+static struct grant *get_free_grant(struct blkfront_info *info)
 {
 	struct grant *gnt_list_entry;
-	unsigned long buffer_gfn;
 
 	BUG_ON(list_empty(&info->grants));
 	gnt_list_entry = list_first_entry(&info->grants, struct grant,
-	                                  node);
+					  node);
 	list_del(&gnt_list_entry->node);
 
-	if (gnt_list_entry->gref != GRANT_INVALID_REF) {
+	if (gnt_list_entry->gref != GRANT_INVALID_REF)
 		info->persistent_gnts_c--;
+
+	return gnt_list_entry;
+}
+
+static inline void grant_foreign_access(const struct grant *gnt_list_entry,
+					const struct blkfront_info *info)
+{
+	gnttab_page_grant_foreign_access_ref_one(gnt_list_entry->gref,
+						 info->xbdev->otherend_id,
+						 gnt_list_entry->page,
+						 0);
+}
+
+static struct grant *get_grant(grant_ref_t *gref_head,
+			       unsigned long gfn,
+			       struct blkfront_info *info)
+{
+	struct grant *gnt_list_entry = get_free_grant(info);
+
+	if (gnt_list_entry->gref != GRANT_INVALID_REF)
 		return gnt_list_entry;
+
+	/* Assign a gref to this page */
+	gnt_list_entry->gref = gnttab_claim_grant_reference(gref_head);
+	BUG_ON(gnt_list_entry->gref == -ENOSPC);
+	if (info->feature_persistent)
+		grant_foreign_access(gnt_list_entry, info);
+	else {
+		/* Grant access to the GFN passed by the caller */
+		gnttab_grant_foreign_access_ref(gnt_list_entry->gref,
+						info->xbdev->otherend_id,
+						gfn, 0);
 	}
 
+	return gnt_list_entry;
+}
+
+static struct grant *get_indirect_grant(grant_ref_t *gref_head,
+					struct blkfront_info *info)
+{
+	struct grant *gnt_list_entry = get_free_grant(info);
+
+	if (gnt_list_entry->gref != GRANT_INVALID_REF)
+		return gnt_list_entry;
+
 	/* Assign a gref to this page */
 	gnt_list_entry->gref = gnttab_claim_grant_reference(gref_head);
 	BUG_ON(gnt_list_entry->gref == -ENOSPC);
 	if (!info->feature_persistent) {
-		BUG_ON(!page);
-		gnt_list_entry->page = page;
+		struct page *indirect_page;
+
+		/* Fetch a pre-allocated page to use for indirect grefs */
+		BUG_ON(list_empty(&info->indirect_pages));
+		indirect_page = list_first_entry(&info->indirect_pages,
+						 struct page, lru);
+		list_del(&indirect_page->lru);
+		gnt_list_entry->page = indirect_page;
 	}
-	buffer_gfn = xen_page_to_gfn(gnt_list_entry->page);
-	gnttab_grant_foreign_access_ref(gnt_list_entry->gref,
-	                                info->xbdev->otherend_id,
-	                                buffer_gfn, 0);
+	grant_foreign_access(gnt_list_entry, info);
+
 	return gnt_list_entry;
 }
 
@@ -524,32 +567,19 @@ static int blkif_queue_rw_req(struct request *req)
 
 		if ((ring_req->operation == BLKIF_OP_INDIRECT) &&
 		    (i % SEGS_PER_INDIRECT_FRAME == 0)) {
-			struct page *uninitialized_var(page);
-
 			if (segments)
 				kunmap_atomic(segments);
 
 			n = i / SEGS_PER_INDIRECT_FRAME;
-			if (!info->feature_persistent) {
-				struct page *indirect_page;
-
-				/*
-				 * Fetch a pre-allocated page to use for
-				 * indirect grefs
-				 */
-				BUG_ON(list_empty(&info->indirect_pages));
-				indirect_page = list_first_entry(&info->indirect_pages,
-								 struct page, lru);
-				list_del(&indirect_page->lru);
-				page = indirect_page;
-			}
-			gnt_list_entry = get_grant(&gref_head, page, info);
+			gnt_list_entry = get_indirect_grant(&gref_head, info);
 			info->shadow[id].indirect_grants[n] = gnt_list_entry;
 			segments = kmap_atomic(gnt_list_entry->page);
 			ring_req->u.indirect.indirect_grefs[n] = gnt_list_entry->gref;
 		}
 
-		gnt_list_entry = get_grant(&gref_head, sg_page(sg), info);
+		gnt_list_entry = get_grant(&gref_head,
+					   xen_page_to_gfn(sg_page(sg)),
+					   info);
 		ref = gnt_list_entry->gref;
 
 		info->shadow[id].grants_used[i] = gnt_list_entry;
-- 
2.1.4



From julien.grall at citrix.com  Fri Aug  7 09:46:44 2015
From: julien.grall at citrix.com (Julien Grall)
Date: Fri, 7 Aug 2015 17:46:44 +0100
Subject: [PATCH v3 05/20] xen/grant: Add helper
 gnttab_page_grant_foreign_access_ref_one
In-Reply-To: <1438966019-19322-1-git-send-email-julien.grall@citrix.com>
References: <1438966019-19322-1-git-send-email-julien.grall@citrix.com>
Message-ID: <1438966019-19322-6-git-send-email-julien.grall@citrix.com>

Many PV drivers contain the idiom:

pfn = page_to_gfn(...) /* Or similar */
gnttab_grant_foreign_access_ref

Replace it by a new helper. Note that when Linux is using a different
page granularity than Xen, the helper only gives access to the first 4KB
grant.

This is useful where drivers are allocating a full Linux page for each
grant.

Also include xen/interface/grant_table.h rather than xen/grant_table.h in
asm/page.h for x86 to fix a compilation issue [1]. Only the former is
useful in order to get the structure definition.

[1] Interdependency between asm/page.h and xen/grant_table.h which result
to page_mfn not being defined when necessary.

Signed-off-by: Julien Grall <julien.grall at linaro.org>
Reviewed-by: David Vrabel <david.vrabel at citrix.com>
Reviewed-by: Stefano Stabellini <stefano.stabellini at eu.citrix.com>

---
Cc: Konrad Rzeszutek Wilk <konrad.wilk at oracle.com>
Cc: Boris Ostrovsky <boris.ostrovsky at oracle.com>

    Changes in v3:
        - Rename gnttab_page_grant_foreign_access_ref into
        gnttab_page_grant_foreign_access_ref_one
        - Fix typo in the commit message
        - s/mfn/gfn based on the new naming
        - Add David and Stefano's reviewed-by

    Changes in v2:
        - Patch added
---
 include/xen/grant_table.h | 9 +++++++++
 1 file changed, 9 insertions(+)

diff --git a/include/xen/grant_table.h b/include/xen/grant_table.h
index 2a8ebe8..1c1ddd9 100644
--- a/include/xen/grant_table.h
+++ b/include/xen/grant_table.h
@@ -131,6 +131,15 @@ void gnttab_cancel_free_callback(struct gnttab_free_callback *callback);
 void gnttab_grant_foreign_access_ref(grant_ref_t ref, domid_t domid,
 				     unsigned long frame, int readonly);
 
+/* Give access to the first 4K of the page */
+static inline void gnttab_page_grant_foreign_access_ref_one(
+	grant_ref_t ref, domid_t domid,
+	struct page *page, int readonly)
+{
+	gnttab_grant_foreign_access_ref(ref, domid, xen_page_to_gfn(page),
+					readonly);
+}
+
 void gnttab_grant_foreign_transfer_ref(grant_ref_t, domid_t domid,
 				       unsigned long pfn);
 
-- 
2.1.4



From julien.grall at citrix.com  Fri Aug  7 09:46:40 2015
From: julien.grall at citrix.com (Julien Grall)
Date: Fri, 7 Aug 2015 17:46:40 +0100
Subject: [PATCH v3 01/20] net/xen-netback: xenvif_gop_frag_copy: move GSO
 check out of the loop
In-Reply-To: <1438966019-19322-1-git-send-email-julien.grall@citrix.com>
References: <1438966019-19322-1-git-send-email-julien.grall@citrix.com>
Message-ID: <1438966019-19322-2-git-send-email-julien.grall@citrix.com>

The skb doesn't change within the function. Therefore it's only
necessary to check if we need GSO once at the beginning.

Signed-off-by: Julien Grall <julien.grall at citrix.com>

---
Cc: Ian Campbell <ian.campbell at citrix.com>
Cc: Wei Liu <wei.liu2 at citrix.com>
Cc: netdev at vger.kernel.org

    Changes in v2:
        - Patch added
---
 drivers/net/xen-netback/netback.c | 14 +++++++-------
 1 file changed, 7 insertions(+), 7 deletions(-)

diff --git a/drivers/net/xen-netback/netback.c b/drivers/net/xen-netback/netback.c
index 8293374..66f1780 100644
--- a/drivers/net/xen-netback/netback.c
+++ b/drivers/net/xen-netback/netback.c
@@ -277,6 +277,13 @@ static void xenvif_gop_frag_copy(struct xenvif_queue *queue, struct sk_buff *skb
 	unsigned long bytes;
 	int gso_type = XEN_NETIF_GSO_TYPE_NONE;
 
+	if (skb_is_gso(skb)) {
+		if (skb_shinfo(skb)->gso_type & SKB_GSO_TCPV4)
+			gso_type = XEN_NETIF_GSO_TYPE_TCPV4;
+		else if (skb_shinfo(skb)->gso_type & SKB_GSO_TCPV6)
+			gso_type = XEN_NETIF_GSO_TYPE_TCPV6;
+	}
+
 	/* Data must not cross a page boundary. */
 	BUG_ON(size + offset > PAGE_SIZE<<compound_order(page));
 
@@ -336,13 +343,6 @@ static void xenvif_gop_frag_copy(struct xenvif_queue *queue, struct sk_buff *skb
 		}
 
 		/* Leave a gap for the GSO descriptor. */
-		if (skb_is_gso(skb)) {
-			if (skb_shinfo(skb)->gso_type & SKB_GSO_TCPV4)
-				gso_type = XEN_NETIF_GSO_TYPE_TCPV4;
-			else if (skb_shinfo(skb)->gso_type & SKB_GSO_TCPV6)
-				gso_type = XEN_NETIF_GSO_TYPE_TCPV6;
-		}
-
 		if (*head && ((1 << gso_type) & queue->vif->gso_mask))
 			queue->rx.req_cons++;
 
-- 
2.1.4



From julien.grall at citrix.com  Fri Aug  7 09:46:41 2015
From: julien.grall at citrix.com (Julien Grall)
Date: Fri, 7 Aug 2015 17:46:41 +0100
Subject: [PATCH v3 02/20] arm/xen: Drop pte_mfn and mfn_pte
In-Reply-To: <1438966019-19322-1-git-send-email-julien.grall@citrix.com>
References: <1438966019-19322-1-git-send-email-julien.grall@citrix.com>
Message-ID: <1438966019-19322-3-git-send-email-julien.grall@citrix.com>

They are not used in common code expect in one place in balloon.c which is
only compiled when Linux is using PV MMU. It's not the case on ARM.

Rather than worrying how to handle the 64KB case, drop them.

Signed-off-by: Julien Grall <julien.grall at citrix.com>

---
Stefano Stabellini <stefano.stabellini at eu.citrix.com>
Russell King <linux at arm.linux.org.uk>

    Changes in v3:
        - Patch added
---
 arch/arm/include/asm/xen/page.h | 3 ---
 1 file changed, 3 deletions(-)

diff --git a/arch/arm/include/asm/xen/page.h b/arch/arm/include/asm/xen/page.h
index 1279563..98c9fc3 100644
--- a/arch/arm/include/asm/xen/page.h
+++ b/arch/arm/include/asm/xen/page.h
@@ -13,9 +13,6 @@
 
 #define phys_to_machine_mapping_valid(pfn) (1)
 
-#define pte_mfn	    pte_pfn
-#define mfn_pte	    pfn_pte
-
 /* Xen machine address */
 typedef struct xmaddr {
 	phys_addr_t maddr;
-- 
2.1.4



From julien.grall at citrix.com  Fri Aug  7 09:46:46 2015
From: julien.grall at citrix.com (Julien Grall)
Date: Fri, 7 Aug 2015 17:46:46 +0100
Subject: [PATCH v3 07/20] block/xen-blkfront: Store a page rather a pfn in the
 grant structure
In-Reply-To: <1438966019-19322-1-git-send-email-julien.grall@citrix.com>
References: <1438966019-19322-1-git-send-email-julien.grall@citrix.com>
Message-ID: <1438966019-19322-8-git-send-email-julien.grall@citrix.com>

All the usage of the field pfn are done using the same idiom:

pfn_to_page(grant->pfn)

This will  return always the same page. Store directly the page in the
grant to clean up the code.

Signed-off-by: Julien Grall <julien.grall at citrix.com>
Acked-by: Roger Pau Monn? <roger.pau at citrix.com>
Reviewed-by: Stefano Stabellini <stefano.stabellini at eu.citrix.com>

---
Cc: Konrad Rzeszutek Wilk <konrad.wilk at oracle.com>
Cc: Boris Ostrovsky <boris.ostrovsky at oracle.com>
Cc: David Vrabel <david.vrabel at citrix.com>

    Changes in v3:
        - Use the correct indentation in get_grant. The current
        indentation (i.e without this patch) was wrong because it was
        using space rather than tabulation.
        - Add Roger's acked and Stefano's reviewed
        - s/mfn/gfn based on the new naming

    Changes in v2:
        - Patch added
---
 drivers/block/xen-blkfront.c | 39 +++++++++++++++++++--------------------
 1 file changed, 19 insertions(+), 20 deletions(-)

diff --git a/drivers/block/xen-blkfront.c b/drivers/block/xen-blkfront.c
index b235689..e431e82 100644
--- a/drivers/block/xen-blkfront.c
+++ b/drivers/block/xen-blkfront.c
@@ -68,7 +68,7 @@ enum blkif_state {
 
 struct grant {
 	grant_ref_t gref;
-	unsigned long pfn;
+	struct page *page;
 	struct list_head node;
 };
 
@@ -221,7 +221,7 @@ static int fill_grant_buffer(struct blkfront_info *info, int num)
 				kfree(gnt_list_entry);
 				goto out_of_memory;
 			}
-			gnt_list_entry->pfn = page_to_pfn(granted_page);
+			gnt_list_entry->page = granted_page;
 		}
 
 		gnt_list_entry->gref = GRANT_INVALID_REF;
@@ -236,7 +236,7 @@ out_of_memory:
 	                         &info->grants, node) {
 		list_del(&gnt_list_entry->node);
 		if (info->feature_persistent)
-			__free_page(pfn_to_page(gnt_list_entry->pfn));
+			__free_page(gnt_list_entry->page);
 		kfree(gnt_list_entry);
 		i--;
 	}
@@ -245,8 +245,8 @@ out_of_memory:
 }
 
 static struct grant *get_grant(grant_ref_t *gref_head,
-                               unsigned long pfn,
-                               struct blkfront_info *info)
+			       struct page *page,
+			       struct blkfront_info *info)
 {
 	struct grant *gnt_list_entry;
 	unsigned long buffer_gfn;
@@ -265,10 +265,10 @@ static struct grant *get_grant(grant_ref_t *gref_head,
 	gnt_list_entry->gref = gnttab_claim_grant_reference(gref_head);
 	BUG_ON(gnt_list_entry->gref == -ENOSPC);
 	if (!info->feature_persistent) {
-		BUG_ON(!pfn);
-		gnt_list_entry->pfn = pfn;
+		BUG_ON(!page);
+		gnt_list_entry->page = page;
 	}
-	buffer_gfn = pfn_to_gfn(gnt_list_entry->pfn);
+	buffer_gfn = xen_page_to_gfn(gnt_list_entry->page);
 	gnttab_grant_foreign_access_ref(gnt_list_entry->gref,
 	                                info->xbdev->otherend_id,
 	                                buffer_gfn, 0);
@@ -524,7 +524,7 @@ static int blkif_queue_rw_req(struct request *req)
 
 		if ((ring_req->operation == BLKIF_OP_INDIRECT) &&
 		    (i % SEGS_PER_INDIRECT_FRAME == 0)) {
-			unsigned long uninitialized_var(pfn);
+			struct page *uninitialized_var(page);
 
 			if (segments)
 				kunmap_atomic(segments);
@@ -541,15 +541,15 @@ static int blkif_queue_rw_req(struct request *req)
 				indirect_page = list_first_entry(&info->indirect_pages,
 								 struct page, lru);
 				list_del(&indirect_page->lru);
-				pfn = page_to_pfn(indirect_page);
+				page = indirect_page;
 			}
-			gnt_list_entry = get_grant(&gref_head, pfn, info);
+			gnt_list_entry = get_grant(&gref_head, page, info);
 			info->shadow[id].indirect_grants[n] = gnt_list_entry;
-			segments = kmap_atomic(pfn_to_page(gnt_list_entry->pfn));
+			segments = kmap_atomic(gnt_list_entry->page);
 			ring_req->u.indirect.indirect_grefs[n] = gnt_list_entry->gref;
 		}
 
-		gnt_list_entry = get_grant(&gref_head, page_to_pfn(sg_page(sg)), info);
+		gnt_list_entry = get_grant(&gref_head, sg_page(sg), info);
 		ref = gnt_list_entry->gref;
 
 		info->shadow[id].grants_used[i] = gnt_list_entry;
@@ -560,7 +560,7 @@ static int blkif_queue_rw_req(struct request *req)
 
 			BUG_ON(sg->offset + sg->length > PAGE_SIZE);
 
-			shared_data = kmap_atomic(pfn_to_page(gnt_list_entry->pfn));
+			shared_data = kmap_atomic(gnt_list_entry->page);
 			bvec_data = kmap_atomic(sg_page(sg));
 
 			/*
@@ -1001,7 +1001,7 @@ static void blkif_free(struct blkfront_info *info, int suspend)
 				info->persistent_gnts_c--;
 			}
 			if (info->feature_persistent)
-				__free_page(pfn_to_page(persistent_gnt->pfn));
+				__free_page(persistent_gnt->page);
 			kfree(persistent_gnt);
 		}
 	}
@@ -1036,7 +1036,7 @@ static void blkif_free(struct blkfront_info *info, int suspend)
 			persistent_gnt = info->shadow[i].grants_used[j];
 			gnttab_end_foreign_access(persistent_gnt->gref, 0, 0UL);
 			if (info->feature_persistent)
-				__free_page(pfn_to_page(persistent_gnt->pfn));
+				__free_page(persistent_gnt->page);
 			kfree(persistent_gnt);
 		}
 
@@ -1050,7 +1050,7 @@ static void blkif_free(struct blkfront_info *info, int suspend)
 		for (j = 0; j < INDIRECT_GREFS(segs); j++) {
 			persistent_gnt = info->shadow[i].indirect_grants[j];
 			gnttab_end_foreign_access(persistent_gnt->gref, 0, 0UL);
-			__free_page(pfn_to_page(persistent_gnt->pfn));
+			__free_page(persistent_gnt->page);
 			kfree(persistent_gnt);
 		}
 
@@ -1101,8 +1101,7 @@ static void blkif_completion(struct blk_shadow *s, struct blkfront_info *info,
 	if (bret->operation == BLKIF_OP_READ && info->feature_persistent) {
 		for_each_sg(s->sg, sg, nseg, i) {
 			BUG_ON(sg->offset + sg->length > PAGE_SIZE);
-			shared_data = kmap_atomic(
-				pfn_to_page(s->grants_used[i]->pfn));
+			shared_data = kmap_atomic(s->grants_used[i]->page);
 			bvec_data = kmap_atomic(sg_page(sg));
 			memcpy(bvec_data   + sg->offset,
 			       shared_data + sg->offset,
@@ -1153,7 +1152,7 @@ static void blkif_completion(struct blk_shadow *s, struct blkfront_info *info,
 				 * Add the used indirect page back to the list of
 				 * available pages for indirect grefs.
 				 */
-				indirect_page = pfn_to_page(s->indirect_grants[i]->pfn);
+				indirect_page = s->indirect_grants[i]->page;
 				list_add(&indirect_page->lru, &info->indirect_pages);
 				s->indirect_grants[i]->gref = GRANT_INVALID_REF;
 				list_add_tail(&s->indirect_grants[i]->node, &info->grants);
-- 
2.1.4



From julien.grall at citrix.com  Fri Aug  7 09:46:39 2015
From: julien.grall at citrix.com (Julien Grall)
Date: Fri, 7 Aug 2015 17:46:39 +0100
Subject: [PATCH v3 00/20] xen/arm64: Add support for 64KB page
Message-ID: <1438966019-19322-1-git-send-email-julien.grall@citrix.com>

Hi all,

ARM64 Linux is supporting both 4KB and 64KB page granularity. Although, Xen
hypercall interface and PV protocol are always based on 4KB page granularity.

Any attempt to boot a Linux guest with 64KB pages enabled will result to a
guest crash.

This series is a first attempt to allow those Linux running with the current
hypercall interface and PV protocol.

This solution has been chosen because we want to run Linux 64KB in released
Xen ARM version or/and platform using an old version of Linux DOM0.

There is room for improvement, such as support of 64KB grant, modification
of PV protocol to support different page size... They will be explored in a
separate patch series later.

TODO list:
    - Convert swiotlb to 64KB
    - Convert xenfb to 64KB
    - Check if backend in QEMU works with DOM0 64KB
    - It may be possible to move some common define between
    netback/netfront and blkfront/blkback in an header

All patches has been built tested for ARM32, ARM64, x86. But I haven't tested
to run it on x86 as I don't have a box with Xen x86 running. I would be
happy if someone give a try and see possible regression for x86.

A branch based on the latest linux/master can be found here:

git://xenbits.xen.org/people/julieng/linux-arm.git branch xen-64k-v3

Comments, suggestions are welcomed.

Sincerely yours,

Cc: david.vrabel at citrix.com
Cc: konrad.wilk at oracle.com
Cc: boris.ostrovsky at oracle.com
Cc: wei.liu2 at citrix.com
Cc: roger.pau at citrix.com

Julien Grall (20):
  net/xen-netback: xenvif_gop_frag_copy: move GSO check out of the loop
  arm/xen: Drop pte_mfn and mfn_pte
  xen: Add Xen specific page definition
  xen/grant: Introduce helpers to split a page into grant
  xen/grant: Add helper gnttab_page_grant_foreign_access_ref_one
  block/xen-blkfront: Split blkif_queue_request in 2
  block/xen-blkfront: Store a page rather a pfn in the grant structure
  block/xen-blkfront: split get_grant in 2
  xen/biomerge: Don't allow biovec to be merge when Linux is not using
    4KB page
  xen/xenbus: Use Xen page definition
  tty/hvc: xen: Use xen page definition
  xen/balloon: Don't rely on the page granularity is the same for Xen
    and Linux
  xen/events: fifo: Make it running on 64KB granularity
  xen/grant-table: Make it running on 64KB granularity
  block/xen-blkfront: Make it running on 64KB page granularity
  block/xen-blkback: Make it running on 64KB page granularity
  net/xen-netfront: Make it running on 64KB page granularity
  net/xen-netback: Make it running on 64KB page granularity
  xen/privcmd: Add support for Linux 64KB page granularity
  arm/xen: Add support for 64KB page granularity

 arch/arm/include/asm/xen/page.h     |  18 +-
 arch/arm/xen/enlighten.c            |   6 +-
 arch/arm/xen/p2m.c                  |   6 +-
 arch/x86/include/asm/xen/page.h     |   2 +-
 drivers/block/xen-blkback/blkback.c |   5 +-
 drivers/block/xen-blkback/common.h  |  17 +-
 drivers/block/xen-blkback/xenbus.c  |   9 +-
 drivers/block/xen-blkfront.c        | 552 +++++++++++++++++++++++-------------
 drivers/net/xen-netback/common.h    |  15 +-
 drivers/net/xen-netback/netback.c   | 163 +++++++----
 drivers/net/xen-netfront.c          | 122 +++++---
 drivers/tty/hvc/hvc_xen.c           |   4 +-
 drivers/xen/balloon.c               |  47 ++-
 drivers/xen/biomerge.c              |   8 +
 drivers/xen/events/events_base.c    |   2 +-
 drivers/xen/events/events_fifo.c    |   2 +-
 drivers/xen/grant-table.c           |  32 ++-
 drivers/xen/privcmd.c               |   8 +-
 drivers/xen/xenbus/xenbus_client.c  |   6 +-
 drivers/xen/xenbus/xenbus_probe.c   |   3 +-
 drivers/xen/xlate_mmu.c             | 124 +++++---
 include/xen/grant_table.h           |  51 ++++
 include/xen/page.h                  |  27 +-
 23 files changed, 844 insertions(+), 385 deletions(-)

-- 
2.1.4



From julien.grall at citrix.com  Fri Aug  7 09:46:43 2015
From: julien.grall at citrix.com (Julien Grall)
Date: Fri, 7 Aug 2015 17:46:43 +0100
Subject: [PATCH v3 04/20] xen/grant: Introduce helpers to split a page into
 grant
In-Reply-To: <1438966019-19322-1-git-send-email-julien.grall@citrix.com>
References: <1438966019-19322-1-git-send-email-julien.grall@citrix.com>
Message-ID: <1438966019-19322-5-git-send-email-julien.grall@citrix.com>

Currently, a grant is always based on the Xen page granularity (i.e
4KB). When Linux is using a different page granularity, a single page
will be split between multiple grants.

The new helpers will be in charge to split the Linux page into grants and
call a function given by the caller on each grant.

Also provide an helper to count the number of grants within a given
contiguous region.

Note that the x86/include/asm/xen/page.h is now including
xen/interface/grant_table.h rather than xen/grant_table.h. It's
necessary because xen/grant_table.h depends on asm/xen/page.h and will
break the compilation. Furthermore, only definition in
interface/grant_table.h was required.

Signed-off-by: Julien Grall <julien.grall at citrix.com>

---
Cc: Konrad Rzeszutek Wilk <konrad.wilk at oracle.com>
Cc: Boris Ostrovsky <boris.ostrovsky at oracle.com>
Cc: David Vrabel <david.vrabel at citrix.com>
Cc: Thomas Gleixner <tglx at linutronix.de>
Cc: Ingo Molnar <mingo at redhat.com>
Cc: "H. Peter Anvin" <hpa at zytor.com>
Cc: x86 at kernel.org

    Changes in v3:
        - Fix error reported by checkpatch.pl
        - Typoes
        - s/pfn/xen_pfn/ in gnttab_foreach_grant
        - Drop the possibility to use less data. The complexity is moved
        in netback which is the only user
        - Rename gnttab_foreach_grant into gnttab_foreach_grant_in_range
        - s/offset/start/ in gnttab_count_grant and update the
        description of the parameter
        - s/mfn/gfn base on the new terminologies
        - Add EXPORT_SYMBOL_GPL for gnttab_foreach_grant_in_range
        - Use xen_offset_in_page and XEN_PFN_DOWN whenever it's possible
        - Fix compilation on x86.

    Changes in v2:
        - Patch added
---
 arch/x86/include/asm/xen/page.h |  2 +-
 drivers/xen/grant-table.c       | 26 +++++++++++++++++++++++++
 include/xen/grant_table.h       | 42 +++++++++++++++++++++++++++++++++++++++++
 3 files changed, 69 insertions(+), 1 deletion(-)

diff --git a/arch/x86/include/asm/xen/page.h b/arch/x86/include/asm/xen/page.h
index 0b762f6..501479e 100644
--- a/arch/x86/include/asm/xen/page.h
+++ b/arch/x86/include/asm/xen/page.h
@@ -12,7 +12,7 @@
 #include <asm/pgtable.h>
 
 #include <xen/interface/xen.h>
-#include <xen/grant_table.h>
+#include <xen/interface/grant_table.h>
 #include <xen/features.h>
 
 /* Xen machine address */
diff --git a/drivers/xen/grant-table.c b/drivers/xen/grant-table.c
index 62f591f..94ae0fd 100644
--- a/drivers/xen/grant-table.c
+++ b/drivers/xen/grant-table.c
@@ -776,6 +776,32 @@ void gnttab_batch_copy(struct gnttab_copy *batch, unsigned count)
 }
 EXPORT_SYMBOL_GPL(gnttab_batch_copy);
 
+void gnttab_foreach_grant_in_range(struct page *page,
+				   unsigned int offset,
+				   unsigned int len,
+				   xen_grant_fn_t fn,
+				   void *data)
+{
+	unsigned int goffset;
+	unsigned int glen;
+	unsigned long xen_pfn;
+
+	len = min_t(unsigned int, PAGE_SIZE - offset, len);
+	goffset = xen_offset_in_page(offset);
+
+	xen_pfn = xen_page_to_pfn(page) + XEN_PFN_DOWN(offset);
+
+	while (len) {
+		glen = min_t(unsigned int, XEN_PAGE_SIZE - goffset, len);
+		fn(pfn_to_gfn(xen_pfn), goffset, glen, data);
+
+		goffset = 0;
+		xen_pfn++;
+		len -= glen;
+	}
+}
+EXPORT_SYMBOL_GPL(gnttab_foreach_grant_in_range);
+
 int gnttab_map_refs(struct gnttab_map_grant_ref *map_ops,
 		    struct gnttab_map_grant_ref *kmap_ops,
 		    struct page **pages, unsigned int count)
diff --git a/include/xen/grant_table.h b/include/xen/grant_table.h
index 4478f4b..2a8ebe8 100644
--- a/include/xen/grant_table.h
+++ b/include/xen/grant_table.h
@@ -45,8 +45,10 @@
 #include <asm/xen/hypervisor.h>
 
 #include <xen/features.h>
+#include <xen/page.h>
 #include <linux/mm_types.h>
 #include <linux/page-flags.h>
+#include <linux/kernel.h>
 
 #define GNTTAB_RESERVED_XENSTORE 1
 
@@ -224,4 +226,44 @@ static inline struct xen_page_foreign *xen_page_foreign(struct page *page)
 #endif
 }
 
+/* Split Linux page in chunk of the size of the grant and call fn
+ *
+ * Parameters of fn:
+ *	gfn: guest frame number
+ *	offset: offset in the grant
+ *	len: length of the data in the grant.
+ *	data: internal information
+ */
+typedef void (*xen_grant_fn_t)(unsigned long gfn, unsigned int offset,
+			       unsigned int len, void *data);
+
+void gnttab_foreach_grant_in_range(struct page *page,
+				   unsigned int offset,
+				   unsigned int len,
+				   xen_grant_fn_t fn,
+				   void *data);
+
+/* Helper to get to call fn only on the first "grant chunk" */
+static inline void gnttab_one_grant(struct page *page, unsigned int offset,
+				    unsigned len, xen_grant_fn_t fn,
+				    void *data)
+{
+	/* The first request is limited to the size of one grant */
+	len = min_t(unsigned int, XEN_PAGE_SIZE - (offset & ~XEN_PAGE_MASK),
+		    len);
+
+	gnttab_foreach_grant_in_range(page, offset, len, fn, data);
+}
+
+/* Get the number of grant in a specified region
+ *
+ * start: Offset from the beginning of the first page
+ * len: total length of data (can cross multiple page)
+ */
+static inline unsigned int gnttab_count_grant(unsigned int start,
+					      unsigned int len)
+{
+	return XEN_PFN_UP(xen_offset_in_page(start) + len);
+}
+
 #endif /* __ASM_GNTTAB_H__ */
-- 
2.1.4



From julien.grall at citrix.com  Fri Aug  7 09:46:48 2015
From: julien.grall at citrix.com (Julien Grall)
Date: Fri, 7 Aug 2015 17:46:48 +0100
Subject: [PATCH v3 09/20] xen/biomerge: Don't allow biovec to be merge when
 Linux is not using 4KB page
In-Reply-To: <1438966019-19322-1-git-send-email-julien.grall@citrix.com>
References: <1438966019-19322-1-git-send-email-julien.grall@citrix.com>
Message-ID: <1438966019-19322-10-git-send-email-julien.grall@citrix.com>

On ARM all dma-capable devices on a same platform may not be protected
by an IOMMU. The DMA requests have to use the BFN (i.e MFN on ARM) in
order to use correctly the device.

While the DOM0 memory is allocated in a 1:1 fashion (PFN == MFN), grant
mapping will screw this contiguous mapping.

When Linux is using 64KB page granularitary, the page may be split
accross multiple non-contiguous MFN (Xen is using 4KB page
granularity). Therefore a DMA request will likely fail.

Checking that a 64KB page is using contiguous MFN is tedious. For
now, always says that biovec are not mergeable.

Signed-off-by: Julien Grall <julien.grall at citrix.com>

---
Cc: Konrad Rzeszutek Wilk <konrad.wilk at oracle.com>
Cc: Boris Ostrovsky <boris.ostrovsky at oracle.com>
Cc: David Vrabel <david.vrabel at citrix.com>

    There is some ideas to check whether two biovec could be merged
    (see [1]) but it's not critical and can be consider as a performance
    improvement.

    Changes in v3:
        - Update commit message
        - s/mfn/bfn/ base on the new renaming
        - Update TODO

    Changes in v2:
        - Remove the workaround and check if the Linux page granularity
        is the same as Xen or not

    [1] https://lkml.org/lkml/2015/7/17/418
---
 drivers/xen/biomerge.c | 8 ++++++++
 1 file changed, 8 insertions(+)

diff --git a/drivers/xen/biomerge.c b/drivers/xen/biomerge.c
index 8ae2fc90..4da69db 100644
--- a/drivers/xen/biomerge.c
+++ b/drivers/xen/biomerge.c
@@ -6,10 +6,18 @@
 bool xen_biovec_phys_mergeable(const struct bio_vec *vec1,
 			       const struct bio_vec *vec2)
 {
+#if XEN_PAGE_SIZE == PAGE_SIZE
 	unsigned long bfn1 = pfn_to_bfn(page_to_pfn(vec1->bv_page));
 	unsigned long bfn2 = pfn_to_bfn(page_to_pfn(vec2->bv_page));
 
 	return __BIOVEC_PHYS_MERGEABLE(vec1, vec2) &&
 		((bfn1 == bfn2) || ((bfn1+1) == bfn2));
+#else
+	/*
+	 * XXX: Add support for merging bio_vec when using different page
+	 * size in Xen and Linux.
+	 */
+	return 0;
+#endif
 }
 EXPORT_SYMBOL(xen_biovec_phys_mergeable);
-- 
2.1.4



From julien.grall at citrix.com  Fri Aug  7 09:46:42 2015
From: julien.grall at citrix.com (Julien Grall)
Date: Fri, 7 Aug 2015 17:46:42 +0100
Subject: [PATCH v3 03/20] xen: Add Xen specific page definition
In-Reply-To: <1438966019-19322-1-git-send-email-julien.grall@citrix.com>
References: <1438966019-19322-1-git-send-email-julien.grall@citrix.com>
Message-ID: <1438966019-19322-4-git-send-email-julien.grall@citrix.com>

The Xen hypercall interface is always using 4K page granularity on ARM
and x86 architecture.

With the incoming support of 64K page granularity for ARM64 guest, it
won't be possible to re-use the Linux page definition in Xen drivers.

Introduce Xen page definition helpers based on the Linux page
definition. They have exactly the same name but prefixed with
XEN_/xen_ prefix.

Also modify xen_page_to_gfn to use new Xen page definition.

Signed-off-by: Julien Grall <julien.grall at citrix.com>
Reviewed-by: Stefano Stabellini <stefano.stabellini at eu.citrix.com>

---
Cc: Konrad Rzeszutek Wilk <konrad.wilk at oracle.com>
Cc: Boris Ostrovsky <boris.ostrovsky at oracle.com>
Cc: David Vrabel <david.vrabel at citrix.com>

    Changes in v3:
        - Fix errors reported by checkpatch.pl
        - Rename pfn to xen_pfn in xen_pfn_to_page
        - Add a comment that we assume PAGE_SIZE to be a multiple of
        XEN_PAGE_SIZE
        - s/MFN/GFN/ according to new naming
        - Add Stefano's reviewed-by

    Changes in v2:
        - Add XEN_PFN_UP
        - Add a comment describing the behavior of page_to_pfn
---
 include/xen/page.h | 27 ++++++++++++++++++++++++++-
 1 file changed, 26 insertions(+), 1 deletion(-)

diff --git a/include/xen/page.h b/include/xen/page.h
index f202992..dac1b26 100644
--- a/include/xen/page.h
+++ b/include/xen/page.h
@@ -1,11 +1,36 @@
 #ifndef _XEN_PAGE_H
 #define _XEN_PAGE_H
 
+#include <asm/page.h>
+
+/* The hypercall interface supports only 4KB page */
+#define XEN_PAGE_SHIFT	12
+#define XEN_PAGE_SIZE	(_AC(1, UL) << XEN_PAGE_SHIFT)
+#define XEN_PAGE_MASK	(~(XEN_PAGE_SIZE-1))
+#define xen_offset_in_page(p)	((unsigned long)(p) & ~XEN_PAGE_MASK)
+
+/*
+ * We asume that PAGE_SIZE is a multiple of XEN_PAGE_SIZE
+ * XXX: Add a BUILD_BUG_ON?
+ */
+
+#define xen_pfn_to_page(xen_pfn)	\
+	((pfn_to_page(((unsigned long)(xen_pfn) << XEN_PAGE_SHIFT) >> PAGE_SHIFT)))
+#define xen_page_to_pfn(page)	\
+	(((page_to_pfn(page)) << PAGE_SHIFT) >> XEN_PAGE_SHIFT)
+
+#define XEN_PFN_PER_PAGE	(PAGE_SIZE / XEN_PAGE_SIZE)
+
+#define XEN_PFN_DOWN(x)	((x) >> XEN_PAGE_SHIFT)
+#define XEN_PFN_UP(x)	(((x) + XEN_PAGE_SIZE-1) >> XEN_PAGE_SHIFT)
+#define XEN_PFN_PHYS(x)	((phys_addr_t)(x) << XEN_PAGE_SHIFT)
+
 #include <asm/xen/page.h>
 
+/* Return the GFN associated to the first 4KB of the page */
 static inline unsigned long xen_page_to_gfn(struct page *page)
 {
-	return pfn_to_gfn(page_to_pfn(page));
+	return pfn_to_gfn(xen_page_to_pfn(page));
 }
 
 struct xen_memory_region {
-- 
2.1.4



From julien.grall at citrix.com  Fri Aug  7 09:46:45 2015
From: julien.grall at citrix.com (Julien Grall)
Date: Fri, 7 Aug 2015 17:46:45 +0100
Subject: [PATCH v3 06/20] block/xen-blkfront: Split blkif_queue_request in 2
In-Reply-To: <1438966019-19322-1-git-send-email-julien.grall@citrix.com>
References: <1438966019-19322-1-git-send-email-julien.grall@citrix.com>
Message-ID: <1438966019-19322-7-git-send-email-julien.grall@citrix.com>

Currently, blkif_queue_request has 2 distinct execution path:
    - Send a discard request
    - Send a read/write request

The function is also allocating grants to use for generating the
request. Although, this is only used for read/write request.

Rather than having a function with 2 distinct execution path, separate
the function in 2. This will also remove one level of tabulation.

Signed-off-by: Julien Grall <julien.grall at citrix.com>
Reviewed-by: Roger Pau Monn? <roger.pau at citrix.com>

---
Cc: Konrad Rzeszutek Wilk <konrad.wilk at oracle.com>
Cc: Boris Ostrovsky <boris.ostrovsky at oracle.com>
Cc: David Vrabel <david.vrabel at citrix.com>

    Roger, if you really want if can drop the else clause in
    blkif_queue_request, IHMO it's more clear here. Although I've kept
    your Reviewed-by. Let me know if it's not fine.

    Changes in v3:
        - Fix errors reported by checkpatch.pl
        - Add Roger's Reviewed-by

    Changes in v2:
        - Patch added
---
 drivers/block/xen-blkfront.c | 281 ++++++++++++++++++++++++-------------------
 1 file changed, 155 insertions(+), 126 deletions(-)

diff --git a/drivers/block/xen-blkfront.c b/drivers/block/xen-blkfront.c
index ebb3624..b235689 100644
--- a/drivers/block/xen-blkfront.c
+++ b/drivers/block/xen-blkfront.c
@@ -394,13 +394,35 @@ static int blkif_ioctl(struct block_device *bdev, fmode_t mode,
 	return 0;
 }
 
-/*
- * Generate a Xen blkfront IO request from a blk layer request.  Reads
- * and writes are handled as expected.
- *
- * @req: a request struct
- */
-static int blkif_queue_request(struct request *req)
+static int blkif_queue_discard_req(struct request *req)
+{
+	struct blkfront_info *info = req->rq_disk->private_data;
+	struct blkif_request *ring_req;
+	unsigned long id;
+
+	/* Fill out a communications ring structure. */
+	ring_req = RING_GET_REQUEST(&info->ring, info->ring.req_prod_pvt);
+	id = get_id_from_freelist(info);
+	info->shadow[id].request = req;
+
+	ring_req->operation = BLKIF_OP_DISCARD;
+	ring_req->u.discard.nr_sectors = blk_rq_sectors(req);
+	ring_req->u.discard.id = id;
+	ring_req->u.discard.sector_number = (blkif_sector_t)blk_rq_pos(req);
+	if ((req->cmd_flags & REQ_SECURE) && info->feature_secdiscard)
+		ring_req->u.discard.flag = BLKIF_DISCARD_SECURE;
+	else
+		ring_req->u.discard.flag = 0;
+
+	info->ring.req_prod_pvt++;
+
+	/* Keep a private copy so we can reissue requests when recovering. */
+	info->shadow[id].req = *ring_req;
+
+	return 0;
+}
+
+static int blkif_queue_rw_req(struct request *req)
 {
 	struct blkfront_info *info = req->rq_disk->private_data;
 	struct blkif_request *ring_req;
@@ -420,9 +442,6 @@ static int blkif_queue_request(struct request *req)
 	struct scatterlist *sg;
 	int nseg, max_grefs;
 
-	if (unlikely(info->connected != BLKIF_STATE_CONNECTED))
-		return 1;
-
 	max_grefs = req->nr_phys_segments;
 	if (max_grefs > BLKIF_MAX_SEGMENTS_PER_REQUEST)
 		/*
@@ -452,139 +471,131 @@ static int blkif_queue_request(struct request *req)
 	id = get_id_from_freelist(info);
 	info->shadow[id].request = req;
 
-	if (unlikely(req->cmd_flags & (REQ_DISCARD | REQ_SECURE))) {
-		ring_req->operation = BLKIF_OP_DISCARD;
-		ring_req->u.discard.nr_sectors = blk_rq_sectors(req);
-		ring_req->u.discard.id = id;
-		ring_req->u.discard.sector_number = (blkif_sector_t)blk_rq_pos(req);
-		if ((req->cmd_flags & REQ_SECURE) && info->feature_secdiscard)
-			ring_req->u.discard.flag = BLKIF_DISCARD_SECURE;
-		else
-			ring_req->u.discard.flag = 0;
+	BUG_ON(info->max_indirect_segments == 0 &&
+	       req->nr_phys_segments > BLKIF_MAX_SEGMENTS_PER_REQUEST);
+	BUG_ON(info->max_indirect_segments &&
+	       req->nr_phys_segments > info->max_indirect_segments);
+	nseg = blk_rq_map_sg(req->q, req, info->shadow[id].sg);
+	ring_req->u.rw.id = id;
+	if (nseg > BLKIF_MAX_SEGMENTS_PER_REQUEST) {
+		/*
+		 * The indirect operation can only be a BLKIF_OP_READ or
+		 * BLKIF_OP_WRITE
+		 */
+		BUG_ON(req->cmd_flags & (REQ_FLUSH | REQ_FUA));
+		ring_req->operation = BLKIF_OP_INDIRECT;
+		ring_req->u.indirect.indirect_op = rq_data_dir(req) ?
+			BLKIF_OP_WRITE : BLKIF_OP_READ;
+		ring_req->u.indirect.sector_number = (blkif_sector_t)blk_rq_pos(req);
+		ring_req->u.indirect.handle = info->handle;
+		ring_req->u.indirect.nr_segments = nseg;
 	} else {
-		BUG_ON(info->max_indirect_segments == 0 &&
-		       req->nr_phys_segments > BLKIF_MAX_SEGMENTS_PER_REQUEST);
-		BUG_ON(info->max_indirect_segments &&
-		       req->nr_phys_segments > info->max_indirect_segments);
-		nseg = blk_rq_map_sg(req->q, req, info->shadow[id].sg);
-		ring_req->u.rw.id = id;
-		if (nseg > BLKIF_MAX_SEGMENTS_PER_REQUEST) {
+		ring_req->u.rw.sector_number = (blkif_sector_t)blk_rq_pos(req);
+		ring_req->u.rw.handle = info->handle;
+		ring_req->operation = rq_data_dir(req) ?
+			BLKIF_OP_WRITE : BLKIF_OP_READ;
+		if (req->cmd_flags & (REQ_FLUSH | REQ_FUA)) {
 			/*
-			 * The indirect operation can only be a BLKIF_OP_READ or
-			 * BLKIF_OP_WRITE
+			 * Ideally we can do an unordered flush-to-disk.
+			 * In case the backend onlysupports barriers, use that.
+			 * A barrier request a superset of FUA, so we can
+			 * implement it the same way.  (It's also a FLUSH+FUA,
+			 * since it is guaranteed ordered WRT previous writes.)
 			 */
-			BUG_ON(req->cmd_flags & (REQ_FLUSH | REQ_FUA));
-			ring_req->operation = BLKIF_OP_INDIRECT;
-			ring_req->u.indirect.indirect_op = rq_data_dir(req) ?
-				BLKIF_OP_WRITE : BLKIF_OP_READ;
-			ring_req->u.indirect.sector_number = (blkif_sector_t)blk_rq_pos(req);
-			ring_req->u.indirect.handle = info->handle;
-			ring_req->u.indirect.nr_segments = nseg;
-		} else {
-			ring_req->u.rw.sector_number = (blkif_sector_t)blk_rq_pos(req);
-			ring_req->u.rw.handle = info->handle;
-			ring_req->operation = rq_data_dir(req) ?
-				BLKIF_OP_WRITE : BLKIF_OP_READ;
-			if (req->cmd_flags & (REQ_FLUSH | REQ_FUA)) {
+			switch (info->feature_flush &
+				((REQ_FLUSH|REQ_FUA))) {
+			case REQ_FLUSH|REQ_FUA:
+				ring_req->operation =
+					BLKIF_OP_WRITE_BARRIER;
+				break;
+			case REQ_FLUSH:
+				ring_req->operation =
+					BLKIF_OP_FLUSH_DISKCACHE;
+				break;
+			default:
+				ring_req->operation = 0;
+			}
+		}
+		ring_req->u.rw.nr_segments = nseg;
+	}
+	for_each_sg(info->shadow[id].sg, sg, nseg, i) {
+		fsect = sg->offset >> 9;
+		lsect = fsect + (sg->length >> 9) - 1;
+
+		if ((ring_req->operation == BLKIF_OP_INDIRECT) &&
+		    (i % SEGS_PER_INDIRECT_FRAME == 0)) {
+			unsigned long uninitialized_var(pfn);
+
+			if (segments)
+				kunmap_atomic(segments);
+
+			n = i / SEGS_PER_INDIRECT_FRAME;
+			if (!info->feature_persistent) {
+				struct page *indirect_page;
+
 				/*
-				 * Ideally we can do an unordered flush-to-disk. In case the
-				 * backend onlysupports barriers, use that. A barrier request
-				 * a superset of FUA, so we can implement it the same
-				 * way.  (It's also a FLUSH+FUA, since it is
-				 * guaranteed ordered WRT previous writes.)
+				 * Fetch a pre-allocated page to use for
+				 * indirect grefs
 				 */
-				switch (info->feature_flush &
-					((REQ_FLUSH|REQ_FUA))) {
-				case REQ_FLUSH|REQ_FUA:
-					ring_req->operation =
-						BLKIF_OP_WRITE_BARRIER;
-					break;
-				case REQ_FLUSH:
-					ring_req->operation =
-						BLKIF_OP_FLUSH_DISKCACHE;
-					break;
-				default:
-					ring_req->operation = 0;
-				}
+				BUG_ON(list_empty(&info->indirect_pages));
+				indirect_page = list_first_entry(&info->indirect_pages,
+								 struct page, lru);
+				list_del(&indirect_page->lru);
+				pfn = page_to_pfn(indirect_page);
 			}
-			ring_req->u.rw.nr_segments = nseg;
+			gnt_list_entry = get_grant(&gref_head, pfn, info);
+			info->shadow[id].indirect_grants[n] = gnt_list_entry;
+			segments = kmap_atomic(pfn_to_page(gnt_list_entry->pfn));
+			ring_req->u.indirect.indirect_grefs[n] = gnt_list_entry->gref;
 		}
-		for_each_sg(info->shadow[id].sg, sg, nseg, i) {
-			fsect = sg->offset >> 9;
-			lsect = fsect + (sg->length >> 9) - 1;
-
-			if ((ring_req->operation == BLKIF_OP_INDIRECT) &&
-			    (i % SEGS_PER_INDIRECT_FRAME == 0)) {
-				unsigned long uninitialized_var(pfn);
-
-				if (segments)
-					kunmap_atomic(segments);
-
-				n = i / SEGS_PER_INDIRECT_FRAME;
-				if (!info->feature_persistent) {
-					struct page *indirect_page;
-
-					/* Fetch a pre-allocated page to use for indirect grefs */
-					BUG_ON(list_empty(&info->indirect_pages));
-					indirect_page = list_first_entry(&info->indirect_pages,
-					                                 struct page, lru);
-					list_del(&indirect_page->lru);
-					pfn = page_to_pfn(indirect_page);
-				}
-				gnt_list_entry = get_grant(&gref_head, pfn, info);
-				info->shadow[id].indirect_grants[n] = gnt_list_entry;
-				segments = kmap_atomic(pfn_to_page(gnt_list_entry->pfn));
-				ring_req->u.indirect.indirect_grefs[n] = gnt_list_entry->gref;
-			}
 
-			gnt_list_entry = get_grant(&gref_head, page_to_pfn(sg_page(sg)), info);
-			ref = gnt_list_entry->gref;
+		gnt_list_entry = get_grant(&gref_head, page_to_pfn(sg_page(sg)), info);
+		ref = gnt_list_entry->gref;
 
-			info->shadow[id].grants_used[i] = gnt_list_entry;
+		info->shadow[id].grants_used[i] = gnt_list_entry;
 
-			if (rq_data_dir(req) && info->feature_persistent) {
-				char *bvec_data;
-				void *shared_data;
+		if (rq_data_dir(req) && info->feature_persistent) {
+			char *bvec_data;
+			void *shared_data;
 
-				BUG_ON(sg->offset + sg->length > PAGE_SIZE);
+			BUG_ON(sg->offset + sg->length > PAGE_SIZE);
 
-				shared_data = kmap_atomic(pfn_to_page(gnt_list_entry->pfn));
-				bvec_data = kmap_atomic(sg_page(sg));
+			shared_data = kmap_atomic(pfn_to_page(gnt_list_entry->pfn));
+			bvec_data = kmap_atomic(sg_page(sg));
 
-				/*
-				 * this does not wipe data stored outside the
-				 * range sg->offset..sg->offset+sg->length.
-				 * Therefore, blkback *could* see data from
-				 * previous requests. This is OK as long as
-				 * persistent grants are shared with just one
-				 * domain. It may need refactoring if this
-				 * changes
-				 */
-				memcpy(shared_data + sg->offset,
-				       bvec_data   + sg->offset,
-				       sg->length);
+			/*
+			 * this does not wipe data stored outside the
+			 * range sg->offset..sg->offset+sg->length.
+			 * Therefore, blkback *could* see data from
+			 * previous requests. This is OK as long as
+			 * persistent grants are shared with just one
+			 * domain. It may need refactoring if this
+			 * changes
+			 */
+			memcpy(shared_data + sg->offset,
+			       bvec_data   + sg->offset,
+			       sg->length);
 
-				kunmap_atomic(bvec_data);
-				kunmap_atomic(shared_data);
-			}
-			if (ring_req->operation != BLKIF_OP_INDIRECT) {
-				ring_req->u.rw.seg[i] =
-						(struct blkif_request_segment) {
-							.gref       = ref,
-							.first_sect = fsect,
-							.last_sect  = lsect };
-			} else {
-				n = i % SEGS_PER_INDIRECT_FRAME;
-				segments[n] =
+			kunmap_atomic(bvec_data);
+			kunmap_atomic(shared_data);
+		}
+		if (ring_req->operation != BLKIF_OP_INDIRECT) {
+			ring_req->u.rw.seg[i] =
 					(struct blkif_request_segment) {
-							.gref       = ref,
-							.first_sect = fsect,
-							.last_sect  = lsect };
-			}
+						.gref       = ref,
+						.first_sect = fsect,
+						.last_sect  = lsect };
+		} else {
+			n = i % SEGS_PER_INDIRECT_FRAME;
+			segments[n] =
+				(struct blkif_request_segment) {
+						.gref       = ref,
+						.first_sect = fsect,
+						.last_sect  = lsect };
 		}
-		if (segments)
-			kunmap_atomic(segments);
 	}
+	if (segments)
+		kunmap_atomic(segments);
 
 	info->ring.req_prod_pvt++;
 
@@ -597,6 +608,24 @@ static int blkif_queue_request(struct request *req)
 	return 0;
 }
 
+/*
+ * Generate a Xen blkfront IO request from a blk layer request.  Reads
+ * and writes are handled as expected.
+ *
+ * @req: a request struct
+ */
+static int blkif_queue_request(struct request *req)
+{
+	struct blkfront_info *info = req->rq_disk->private_data;
+
+	if (unlikely(info->connected != BLKIF_STATE_CONNECTED))
+		return 1;
+
+	if (unlikely(req->cmd_flags & (REQ_DISCARD | REQ_SECURE)))
+		return blkif_queue_discard_req(req);
+	else
+		return blkif_queue_rw_req(req);
+}
 
 static inline void flush_requests(struct blkfront_info *info)
 {
-- 
2.1.4



From catalin.marinas at arm.com  Fri Aug  7 09:57:01 2015
From: catalin.marinas at arm.com (Catalin Marinas)
Date: Fri, 7 Aug 2015 17:57:01 +0100
Subject: [PATCH 2/5] ACPI / ARM64: remove usage of
 BAD_MADT_ENTRY/BAD_MADT_GICC_ENTRY
In-Reply-To: <1438894770-31163-3-git-send-email-al.stone@linaro.org>
References: <1438894770-31163-1-git-send-email-al.stone@linaro.org>
 <1438894770-31163-3-git-send-email-al.stone@linaro.org>
Message-ID: <20150807165701.GI19308@e104818-lin.cambridge.arm.com>

On Thu, Aug 06, 2015 at 02:59:27PM -0600, Al Stone wrote:
> Now that we have introduced the bad_madt_entry() function, and that
> function is being invoked in acpi_table_parse_madt() for us, there
> is no longer any need to use the BAD_MADT_ENTRY macro, or in the case
> of arm64, the BAD_MADT_GICC_ENTRY, too.
> 
> Signed-off-by: Al Stone <al.stone at linaro.org>
> Cc: Catalin Marinas <catalin.marinas at arm.com>
> Cc: Will Deacon <will.deacon at arm.com>
> Cc: Thomas Gleixner <tglx at linutronix.de>
> Cc: Jason Cooper <jason at lakedaemon.net>
> Cc: Marc Zyngier <marc.zyngier at arm.com>

Acked-by: Catalin Marinas <catalin.marinas at arm.com>


From grygorii.strashko at ti.com  Fri Aug  7 10:06:31 2015
From: grygorii.strashko at ti.com (Grygorii Strashko)
Date: Fri, 7 Aug 2015 20:06:31 +0300
Subject: [PATCH v3 01/18] platform: delay OF device-driver matches until
 late_initcall
In-Reply-To: <CAAObsKBapFqzr+4YEXJfcJWMd+tkaBqYbGiFTntHStAP=+P-_Q@mail.gmail.com>
References: <1438870315-18689-1-git-send-email-tomeu.vizoso@collabora.com>
 <1438870315-18689-2-git-send-email-tomeu.vizoso@collabora.com>
 <CAL_Jsq+GLMZe-f6qEi=7i1YrrWc6k99RpGkOyCd5KkYDiyt0QA@mail.gmail.com>
 <CAAObsKBapFqzr+4YEXJfcJWMd+tkaBqYbGiFTntHStAP=+P-_Q@mail.gmail.com>
Message-ID: <55C4E597.1010701@ti.com>

On 08/07/2015 10:11 AM, Tomeu Vizoso wrote:
> On 6 August 2015 at 22:19, Rob Herring <robherring2 at gmail.com> wrote:
>> On Thu, Aug 6, 2015 at 9:11 AM, Tomeu Vizoso <tomeu.vizoso at collabora.com> wrote:
>>> Delay matches of platform devices with OF nodes until late_initcall,
>>> when we are sure that all built-in drivers have been registered already.
>>> This is needed to prevent deferred probes because of some drivers not
>>> having registered yet.
>>>
>>> The reason why only platform devices are delayed is that some other
>>> devices are expected to be probed earlier than late_initcall, for
>>> example, the system PNP driver needs to probe its devices in
>>> fs_initcall.
>>>
>>> Additionally, only platform devices with OF nodes are delayed because
>>> some machines may depend on oter platform devices being registered at
>>> specific times.
>>
>> How do we know that these probes occur before the unused clocks and
>> regulators are turned off? Just getting lucky (as is deferred probe)?
>> Can we do this one level earlier so we have a level left to do things
>> after probe.
> 
> Those are already late_initcall_sync so I guess we're fine.

I wouldn't be so sure :(
FYI:
http://git.ti.com/ti-linux-kernel/ti-linux-kernel/commit/763d643bbfc0f445c6685c541fcae3c370e4314a


-- 
regards,
-grygorii


From julien.grall at citrix.com  Fri Aug  7 10:11:02 2015
From: julien.grall at citrix.com (Julien Grall)
Date: Fri, 7 Aug 2015 18:11:02 +0100
Subject: [Xen-devel] [PATCH v3 00/20] xen/arm64: Add support for 64KB page
In-Reply-To: <1438966019-19322-1-git-send-email-julien.grall@citrix.com>
References: <1438966019-19322-1-git-send-email-julien.grall@citrix.com>
Message-ID: <55C4E6A6.3010808@citrix.com>

On 07/08/15 17:46, Julien Grall wrote:
> Hi all,
> 
> ARM64 Linux is supporting both 4KB and 64KB page granularity. Although, Xen
> hypercall interface and PV protocol are always based on 4KB page granularity.
> 
> Any attempt to boot a Linux guest with 64KB pages enabled will result to a
> guest crash.
> 
> This series is a first attempt to allow those Linux running with the current
> hypercall interface and PV protocol.
> 
> This solution has been chosen because we want to run Linux 64KB in released
> Xen ARM version or/and platform using an old version of Linux DOM0.
> 
> There is room for improvement, such as support of 64KB grant, modification
> of PV protocol to support different page size... They will be explored in a
> separate patch series later.
> 
> TODO list:
>     - Convert swiotlb to 64KB
>     - Convert xenfb to 64KB
>     - Check if backend in QEMU works with DOM0 64KB
>     - It may be possible to move some common define between
>     netback/netfront and blkfront/blkback in an header
> 
> All patches has been built tested for ARM32, ARM64, x86. But I haven't tested
> to run it on x86 as I don't have a box with Xen x86 running. I would be
> happy if someone give a try and see possible regression for x86.
> 
> A branch based on the latest linux/master can be found here:

Sorry, I forgot to update this bits in the cover letter.

It's based on xentip for-linus-4.3 and depends on "Use correctly the Xen
memory terminologies". The v3 has been sent few minutes ago [1]


> 
> git://xenbits.xen.org/people/julieng/linux-arm.git branch xen-64k-v3
> 
> Comments, suggestions are welcomed.
> 
> Sincerely yours,

[1] http://lists.xen.org/archives/html/xen-devel/2015-08/msg00619.html


-- 
Julien Grall


From matthias.bgg at gmail.com  Fri Aug  7 10:13:05 2015
From: matthias.bgg at gmail.com (Matthias Brugger)
Date: Fri, 07 Aug 2015 19:13:05 +0200
Subject: [PATCH v3 0/5] Add SMP bringup support for mt65xx socs
In-Reply-To: <20150805223115.GD7557@n2100.arm.linux.org.uk>
References: <1436851111-2369-1-git-send-email-yingjoe.chen@mediatek.com>
 <4831607.pyCH8elj8i@ubix> <20150805223115.GD7557@n2100.arm.linux.org.uk>
Message-ID: <1582995.hxLqnb2lXW@ubix>

On Wednesday, August 05, 2015 11:31:15 PM Russell King - ARM Linux wrote:
> On Wed, Aug 05, 2015 at 08:44:11PM +0200, Matthias Brugger wrote:
> > On Tuesday, July 14, 2015 01:18:26 PM Yingjoe Chen wrote:
> > > This series add SMP brinup support for MediaTek SoCs. This is based
> > > on v4.2-rc1 and Matthias' next branch (for dts parts).
> > > 
> > > There are similar but different SMP bringup up methods on MediaTek
> > > mt65xx and mt81xx. On MT8135 & MT8127, system boots with a trustzone
> > > firmware. Others, like MT6589, doesn't have trustzone, and run kernel
> > > directly in secure world.
> > > 
> > > Patch 1 enable arch timer support.
> > > Patch 2,3 add support for cpu enable-method "mediatek,mt6589-smp" and
> > > "mediatek,mt81xx-tz-smp", which support Mediatek SMP bringup for non-TZ
> > > and TZ platform.
> > > Patch 4,5 finally enable SMP bringup for mt8135 and mt8127.
> > > 
> > > Changes in v3:
> > > - The first 2 patches in v2 are merged in v4.2-rc1.
> > > - Patch 3~4 in v2 are moved to another series [1]
> > > - platsmp.c changes based on Stephen's suggestion
> > > - Change cpu enable-method name to "mediatek,mt6589-smp"
> > > 
> > > Changes in v2:
> > > - Fix boot issue for THUMB2 kernel.
> > > - Not enable GPT_CLK_EVT when setup to fix GPT spurious interrupt issue
> > > - Change platsmp.c according to Matthias' suggestion
> > > http://lists.infradead.org/pipermail/linux-mediatek/2015-May/000714.html
> > > 
> > > v1:
> > > http://lists.infradead.org/pipermail/linux-mediatek/2015-May/000528.html
> > > 
> > > [1]
> > > http://lists.infradead.org/pipermail/linux-mediatek/2015-July/001544.htm
> > > l
> > > 
> > > Matthias Brugger (1):
> > >   ARM: mediatek: enable gpt6 on boot up to make arch timer working
> > > 
> > > Yingjoe Chen (4):
> > >   devicetree: bindings: add new SMP enable method Mediatek SoC
> > >   ARM: mediatek: add smp bringup code
> > >   ARM: dts: mt8135: enable basic SMP bringup for mt8135
> > >   ARM: dts: mt8127: enable basic SMP bringup for mt8127
> > >  
> > >  Documentation/devicetree/bindings/arm/cpus.txt |   2 +
> > >  arch/arm/boot/dts/mt8127.dtsi                  |  16 +++
> > >  arch/arm/boot/dts/mt8135.dtsi                  |  16 +++
> > >  arch/arm/mach-mediatek/Makefile                |   3 +
> > >  arch/arm/mach-mediatek/mediatek.c              |  27 +++++
> > >  arch/arm/mach-mediatek/platsmp.c               | 144
> > > 
> > > +++++++++++++++++++++++++ 6 files changed, 208 insertions(+)
> > > 
> > >  create mode 100644 arch/arm/mach-mediatek/platsmp.c
> > 
> > Applied to v4.2-next/soc-2 and v4.2-next/dts-2
> 
> I've just NAK'd one of the patches in this set; I don't tend to even see
> mediatek patches normally, as they all head into my junk mailfolder
> because mediatek's mail server setup is truely abysmal (it has broken
> reverse DNS - the DNS positively says that the mail server is not a
> legit owner of the name it claims to be.)
> 
> The problem is that this patch series uses memblock_reserve() way after
> the memory has been transitioned out of memblock's control, so actually
> this has no effect.
> 
> I've seen a number of patches doing this.  I'm not sure what's soo friggin
> hard for people to understand: memblock is about the EARLY stages of
> getting the system up and running.  Once the memory has been handed
> over to the kernel's memory management, memblock MUST NOT BE USED to
> reserve memory.
> 
> There is one place, and one place only in the ARM kernel where
> memblock_reserve() is possible, and that's in the ->reserve machine
> callback.  NOWHERE ELSE is permissible.

OK, I just dropped the patches. Thanks for reviewing this.

Matthias


From julien.grall at citrix.com  Fri Aug  7 09:46:49 2015
From: julien.grall at citrix.com (Julien Grall)
Date: Fri, 7 Aug 2015 17:46:49 +0100
Subject: [PATCH v3 10/20] xen/xenbus: Use Xen page definition
In-Reply-To: <1438966019-19322-1-git-send-email-julien.grall@citrix.com>
References: <1438966019-19322-1-git-send-email-julien.grall@citrix.com>
Message-ID: <1438966019-19322-11-git-send-email-julien.grall@citrix.com>

All the ring (xenstore, and PV rings) are always based on the page
granularity of Xen.

Signed-off-by: Julien Grall <julien.grall at citrix.com>
Reviewed-by: David Vrabel <david.vrabel at citrix.com>
Reviewed-by: Stefano Stabellini <stefano.stabellini at eu.citrix.com>

---
Cc: Konrad Rzeszutek Wilk <konrad.wilk at oracle.com>
Cc: Boris Ostrovsky <boris.ostrovsky at oracle.com>

    Changes in v3:
        - Fix errors reported by checkpatch.pl
        - s/MFN/GFN base on the new naming
        - Add David and Stefano's reviewed-by

    Changes in v2:
        - Also update the ring mapping function
---
 drivers/xen/xenbus/xenbus_client.c | 6 +++---
 drivers/xen/xenbus/xenbus_probe.c  | 3 ++-
 2 files changed, 5 insertions(+), 4 deletions(-)

diff --git a/drivers/xen/xenbus/xenbus_client.c b/drivers/xen/xenbus/xenbus_client.c
index daa267a..a2f6276 100644
--- a/drivers/xen/xenbus/xenbus_client.c
+++ b/drivers/xen/xenbus/xenbus_client.c
@@ -388,7 +388,7 @@ int xenbus_grant_ring(struct xenbus_device *dev, void *vaddr,
 		}
 		grefs[i] = err;
 
-		vaddr = vaddr + PAGE_SIZE;
+		vaddr = vaddr + XEN_PAGE_SIZE;
 	}
 
 	return 0;
@@ -555,7 +555,7 @@ static int xenbus_map_ring_valloc_pv(struct xenbus_device *dev,
 	if (!node)
 		return -ENOMEM;
 
-	area = alloc_vm_area(PAGE_SIZE * nr_grefs, ptes);
+	area = alloc_vm_area(XEN_PAGE_SIZE * nr_grefs, ptes);
 	if (!area) {
 		kfree(node);
 		return -ENOMEM;
@@ -750,7 +750,7 @@ static int xenbus_unmap_ring_vfree_pv(struct xenbus_device *dev, void *vaddr)
 		unsigned long addr;
 
 		memset(&unmap[i], 0, sizeof(unmap[i]));
-		addr = (unsigned long)vaddr + (PAGE_SIZE * i);
+		addr = (unsigned long)vaddr + (XEN_PAGE_SIZE * i);
 		unmap[i].host_addr = arbitrary_virt_to_machine(
 			lookup_address(addr, &level)).maddr;
 		unmap[i].dev_bus_addr = 0;
diff --git a/drivers/xen/xenbus/xenbus_probe.c b/drivers/xen/xenbus/xenbus_probe.c
index 3cbe055..33a31cf 100644
--- a/drivers/xen/xenbus/xenbus_probe.c
+++ b/drivers/xen/xenbus/xenbus_probe.c
@@ -802,7 +802,8 @@ static int __init xenbus_init(void)
 			goto out_error;
 		xen_store_gfn = (unsigned long)v;
 		xen_store_interface =
-			xen_remap(xen_store_gfn << PAGE_SHIFT, PAGE_SIZE);
+			xen_remap(xen_store_gfn << XEN_PAGE_SHIFT,
+				  XEN_PAGE_SIZE);
 		break;
 	default:
 		pr_warn("Xenstore state unknown\n");
-- 
2.1.4



From julien.grall at citrix.com  Fri Aug  7 09:46:58 2015
From: julien.grall at citrix.com (Julien Grall)
Date: Fri, 7 Aug 2015 17:46:58 +0100
Subject: [PATCH v3 19/20] xen/privcmd: Add support for Linux 64KB page
 granularity
In-Reply-To: <1438966019-19322-1-git-send-email-julien.grall@citrix.com>
References: <1438966019-19322-1-git-send-email-julien.grall@citrix.com>
Message-ID: <1438966019-19322-20-git-send-email-julien.grall@citrix.com>

The hypercall interface (as well as the toolstack) is always using 4KB
page granularity. When the toolstack is asking for mapping a series of
guest PFN in a batch, it expects to have the page map contiguously in
its virtual memory.

When Linux is using 64KB page granularity, the privcmd driver will have
to map multiple Xen PFN in a single Linux page.

Note that this solution works on page granularity which is a multiple of
4KB.

Signed-off-by: Julien Grall <julien.grall at citrix.com>

---
Cc: Konrad Rzeszutek Wilk <konrad.wilk at oracle.com>
Cc: Boris Ostrovsky <boris.ostrovsky at oracle.com>
Cc: David Vrabel <david.vrabel at citrix.com>

    I kept the hypercall arguments in remap_data to avoid allocating them on
    the stack every time that remap_pte_fn is called.
    I will keep like that unless someone is strongly disagree.

    Changes in v3:
        - The function to split a Linux page in mutiple Xen page has
        been moved internally. It was the only use (not used anymore in
        the balloon) and it's not quite clear what should be the common
        interface. Differ the question until someone need to use it.
        - s/nr_pfn/numgfns/ to make clear that we are dealing with GFN
        - Use DIV_ROUND_UP rather round_up and fix the usage in
        xen_xlate_unmap_gfn_range

    Changes in v2:
        - Use xen_apply_to_page
---
 drivers/xen/privcmd.c   |   8 ++--
 drivers/xen/xlate_mmu.c | 124 ++++++++++++++++++++++++++++++++----------------
 2 files changed, 89 insertions(+), 43 deletions(-)

diff --git a/drivers/xen/privcmd.c b/drivers/xen/privcmd.c
index c6deb87..c8798ee 100644
--- a/drivers/xen/privcmd.c
+++ b/drivers/xen/privcmd.c
@@ -446,7 +446,7 @@ static long privcmd_ioctl_mmap_batch(void __user *udata, int version)
 		return -EINVAL;
 	}
 
-	nr_pages = m.num;
+	nr_pages = DIV_ROUND_UP(m.num, XEN_PFN_PER_PAGE);
 	if ((m.num <= 0) || (nr_pages > (LONG_MAX >> PAGE_SHIFT)))
 		return -EINVAL;
 
@@ -494,7 +494,7 @@ static long privcmd_ioctl_mmap_batch(void __user *udata, int version)
 			goto out_unlock;
 		}
 		if (xen_feature(XENFEAT_auto_translated_physmap)) {
-			ret = alloc_empty_pages(vma, m.num);
+			ret = alloc_empty_pages(vma, nr_pages);
 			if (ret < 0)
 				goto out_unlock;
 		} else
@@ -518,6 +518,7 @@ static long privcmd_ioctl_mmap_batch(void __user *udata, int version)
 	state.global_error  = 0;
 	state.version       = version;
 
+	BUILD_BUG_ON(((PAGE_SIZE / sizeof(xen_pfn_t)) % XEN_PFN_PER_PAGE) != 0);
 	/* mmap_batch_fn guarantees ret == 0 */
 	BUG_ON(traverse_pages_block(m.num, sizeof(xen_pfn_t),
 				    &pagelist, mmap_batch_fn, &state));
@@ -582,12 +583,13 @@ static void privcmd_close(struct vm_area_struct *vma)
 {
 	struct page **pages = vma->vm_private_data;
 	int numpgs = (vma->vm_end - vma->vm_start) >> PAGE_SHIFT;
+	int numgfns = (vma->vm_end - vma->vm_start) >> XEN_PAGE_SHIFT;
 	int rc;
 
 	if (!xen_feature(XENFEAT_auto_translated_physmap) || !numpgs || !pages)
 		return;
 
-	rc = xen_unmap_domain_gfn_range(vma, numpgs, pages);
+	rc = xen_unmap_domain_gfn_range(vma, numgfns, pages);
 	if (rc == 0)
 		free_xenballooned_pages(numpgs, pages);
 	else
diff --git a/drivers/xen/xlate_mmu.c b/drivers/xen/xlate_mmu.c
index cff2387..a1d3904 100644
--- a/drivers/xen/xlate_mmu.c
+++ b/drivers/xen/xlate_mmu.c
@@ -38,31 +38,28 @@
 #include <xen/interface/xen.h>
 #include <xen/interface/memory.h>
 
-/* map fgfn of domid to lpfn in the current domain */
-static int map_foreign_page(unsigned long lpfn, unsigned long fgfn,
-			    unsigned int domid)
-{
-	int rc;
-	struct xen_add_to_physmap_range xatp = {
-		.domid = DOMID_SELF,
-		.foreign_domid = domid,
-		.size = 1,
-		.space = XENMAPSPACE_gmfn_foreign,
-	};
-	xen_ulong_t idx = fgfn;
-	xen_pfn_t gpfn = lpfn;
-	int err = 0;
+typedef void (*xen_gfn_fn_t)(unsigned long gfn, void *data);
 
-	set_xen_guest_handle(xatp.idxs, &idx);
-	set_xen_guest_handle(xatp.gpfns, &gpfn);
-	set_xen_guest_handle(xatp.errs, &err);
+/* Break down the pages in 4KB chunk and call fn for each gfn */
+static void xen_for_each_gfn(struct page **pages, unsigned nr_gfn,
+			     xen_gfn_fn_t fn, void *data)
+{
+	unsigned long xen_pfn = 0;
+	struct page *page;
+	int i;
 
-	rc = HYPERVISOR_memory_op(XENMEM_add_to_physmap_range, &xatp);
-	return rc < 0 ? rc : err;
+	for (i = 0; i < nr_gfn; i++) {
+		if ((i % XEN_PFN_PER_PAGE) == 0) {
+			page = pages[i / XEN_PFN_PER_PAGE];
+			xen_pfn = xen_page_to_pfn(page);
+		}
+		fn(pfn_to_gfn(xen_pfn++), data);
+	}
 }
 
 struct remap_data {
 	xen_pfn_t *fgfn; /* foreign domain's gfn */
+	int nr_fgfn; /* Number of foreign gfn left to map */
 	pgprot_t prot;
 	domid_t  domid;
 	struct vm_area_struct *vma;
@@ -71,24 +68,71 @@ struct remap_data {
 	struct xen_remap_gfn_info *info;
 	int *err_ptr;
 	int mapped;
+
+	/* Hypercall parameters */
+	int h_errs[XEN_PFN_PER_PAGE];
+	xen_ulong_t h_idxs[XEN_PFN_PER_PAGE];
+	xen_pfn_t h_gpfns[XEN_PFN_PER_PAGE];
+
+	int h_iter;	/* Iterator */
 };
 
+static void setup_hparams(unsigned long gfn, void *data)
+{
+	struct remap_data *info = data;
+
+	info->h_idxs[info->h_iter] = *info->fgfn;
+	info->h_gpfns[info->h_iter] = gfn;
+	info->h_errs[info->h_iter] = 0;
+
+	info->h_iter++;
+	info->fgfn++;
+}
+
 static int remap_pte_fn(pte_t *ptep, pgtable_t token, unsigned long addr,
 			void *data)
 {
 	struct remap_data *info = data;
 	struct page *page = info->pages[info->index++];
-	unsigned long pfn = page_to_pfn(page);
-	pte_t pte = pte_mkspecial(pfn_pte(pfn, info->prot));
-	int rc;
+	pte_t pte = pte_mkspecial(pfn_pte(page_to_pfn(page), info->prot));
+	int rc, nr_gfn;
+	uint32_t i;
+	struct xen_add_to_physmap_range xatp = {
+		.domid = DOMID_SELF,
+		.foreign_domid = info->domid,
+		.space = XENMAPSPACE_gmfn_foreign,
+	};
 
-	rc = map_foreign_page(pfn, *info->fgfn, info->domid);
-	*info->err_ptr++ = rc;
-	if (!rc) {
-		set_pte_at(info->vma->vm_mm, addr, ptep, pte);
-		info->mapped++;
+	nr_gfn = min_t(typeof(info->nr_fgfn), XEN_PFN_PER_PAGE, info->nr_fgfn);
+	info->nr_fgfn -= nr_gfn;
+
+	info->h_iter = 0;
+	xen_for_each_gfn(&page, nr_gfn, setup_hparams, info);
+	BUG_ON(info->h_iter != nr_gfn);
+
+	set_xen_guest_handle(xatp.idxs, info->h_idxs);
+	set_xen_guest_handle(xatp.gpfns, info->h_gpfns);
+	set_xen_guest_handle(xatp.errs, info->h_errs);
+	xatp.size = nr_gfn;
+
+	rc = HYPERVISOR_memory_op(XENMEM_add_to_physmap_range, &xatp);
+
+	/* info->err_ptr expect to have one error status per Xen PFN */
+	for (i = 0; i < nr_gfn; i++) {
+		int err = (rc < 0) ? rc : info->h_errs[i];
+
+		*(info->err_ptr++) = err;
+		if (!err)
+			info->mapped++;
 	}
-	info->fgfn++;
+
+	/*
+	 * Note: The hypercall will return 0 in most of the case if even if
+	 * all the fgmfn are not mapped. We still have to update the pte
+	 * as the userspace may decide to continue.
+	 */
+	if (!rc)
+		set_pte_at(info->vma->vm_mm, addr, ptep, pte);
 
 	return 0;
 }
@@ -102,13 +146,14 @@ int xen_xlate_remap_gfn_array(struct vm_area_struct *vma,
 {
 	int err;
 	struct remap_data data;
-	unsigned long range = nr << PAGE_SHIFT;
+	unsigned long range = DIV_ROUND_UP(nr, XEN_PFN_PER_PAGE) << PAGE_SHIFT;
 
 	/* Kept here for the purpose of making sure code doesn't break
 	   x86 PVOPS */
 	BUG_ON(!((vma->vm_flags & (VM_PFNMAP | VM_IO)) == (VM_PFNMAP | VM_IO)));
 
 	data.fgfn = gfn;
+	data.nr_fgfn = nr;
 	data.prot  = prot;
 	data.domid = domid;
 	data.vma   = vma;
@@ -123,21 +168,20 @@ int xen_xlate_remap_gfn_array(struct vm_area_struct *vma,
 }
 EXPORT_SYMBOL_GPL(xen_xlate_remap_gfn_array);
 
-int xen_xlate_unmap_gfn_range(struct vm_area_struct *vma,
-			      int nr, struct page **pages)
+static void unmap_gfn(unsigned long gfn, void *data)
 {
-	int i;
+	struct xen_remove_from_physmap xrp;
 
-	for (i = 0; i < nr; i++) {
-		struct xen_remove_from_physmap xrp;
-		unsigned long pfn;
+	xrp.domid = DOMID_SELF;
+	xrp.gpfn = gfn;
+	(void)HYPERVISOR_memory_op(XENMEM_remove_from_physmap, &xrp);
+}
 
-		pfn = page_to_pfn(pages[i]);
+int xen_xlate_unmap_gfn_range(struct vm_area_struct *vma,
+			      int nr, struct page **pages)
+{
+	xen_for_each_gfn(pages, nr, unmap_gfn, NULL);
 
-		xrp.domid = DOMID_SELF;
-		xrp.gpfn = pfn;
-		(void)HYPERVISOR_memory_op(XENMEM_remove_from_physmap, &xrp);
-	}
 	return 0;
 }
 EXPORT_SYMBOL_GPL(xen_xlate_unmap_gfn_range);
-- 
2.1.4



From julien.grall at citrix.com  Fri Aug  7 09:46:53 2015
From: julien.grall at citrix.com (Julien Grall)
Date: Fri, 7 Aug 2015 17:46:53 +0100
Subject: [PATCH v3 14/20] xen/grant-table: Make it running on 64KB granularity
In-Reply-To: <1438966019-19322-1-git-send-email-julien.grall@citrix.com>
References: <1438966019-19322-1-git-send-email-julien.grall@citrix.com>
Message-ID: <1438966019-19322-15-git-send-email-julien.grall@citrix.com>

The Xen interface is using 4KB page granularity. This means that each
grant is 4KB.

The current implementation allocates a Linux page per grant. On Linux
using 64KB page granularity, only the first 4KB of the page will be
used.

We could decrease the memory wasted by sharing the page with multiple
grant. It will require some care with the {Set,Clear}ForeignPage macro.

Note that no changes has been made in the x86 code because both Linux
and Xen will only use 4KB page granularity.

Signed-off-by: Julien Grall <julien.grall at citrix.com>
Reviewed-by: David Vrabel <david.vrabel at citrix.com>
Reviewed-by: Stefano Stabellini <stefano.stabellini at eu.citrix.com>

---
Cc: Stefano Stabellini <stefano.stabellini at eu.citrix.com>
Cc: Russell King <linux at arm.linux.org.uk>
Cc: Konrad Rzeszutek Wilk <konrad.wilk at oracle.com>
Cc: Boris Ostrovsky <boris.ostrovsky at oracle.com>

    Changes in v3:
        - Add Stefano's reviewed-by

    Changes in v2
        - Add David's reviewed-by
---
 arch/arm/xen/p2m.c        | 6 +++---
 drivers/xen/grant-table.c | 6 +++---
 2 files changed, 6 insertions(+), 6 deletions(-)

diff --git a/arch/arm/xen/p2m.c b/arch/arm/xen/p2m.c
index 887596c..0ed01f2 100644
--- a/arch/arm/xen/p2m.c
+++ b/arch/arm/xen/p2m.c
@@ -93,8 +93,8 @@ int set_foreign_p2m_mapping(struct gnttab_map_grant_ref *map_ops,
 	for (i = 0; i < count; i++) {
 		if (map_ops[i].status)
 			continue;
-		set_phys_to_machine(map_ops[i].host_addr >> PAGE_SHIFT,
-				    map_ops[i].dev_bus_addr >> PAGE_SHIFT);
+		set_phys_to_machine(map_ops[i].host_addr >> XEN_PAGE_SHIFT,
+				    map_ops[i].dev_bus_addr >> XEN_PAGE_SHIFT);
 	}
 
 	return 0;
@@ -108,7 +108,7 @@ int clear_foreign_p2m_mapping(struct gnttab_unmap_grant_ref *unmap_ops,
 	int i;
 
 	for (i = 0; i < count; i++) {
-		set_phys_to_machine(unmap_ops[i].host_addr >> PAGE_SHIFT,
+		set_phys_to_machine(unmap_ops[i].host_addr >> XEN_PAGE_SHIFT,
 				    INVALID_P2M_ENTRY);
 	}
 
diff --git a/drivers/xen/grant-table.c b/drivers/xen/grant-table.c
index 94ae0fd..253d4db 100644
--- a/drivers/xen/grant-table.c
+++ b/drivers/xen/grant-table.c
@@ -642,7 +642,7 @@ int gnttab_setup_auto_xlat_frames(phys_addr_t addr)
 	if (xen_auto_xlat_grant_frames.count)
 		return -EINVAL;
 
-	vaddr = xen_remap(addr, PAGE_SIZE * max_nr_gframes);
+	vaddr = xen_remap(addr, XEN_PAGE_SIZE * max_nr_gframes);
 	if (vaddr == NULL) {
 		pr_warn("Failed to ioremap gnttab share frames (addr=%pa)!\n",
 			&addr);
@@ -654,7 +654,7 @@ int gnttab_setup_auto_xlat_frames(phys_addr_t addr)
 		return -ENOMEM;
 	}
 	for (i = 0; i < max_nr_gframes; i++)
-		pfn[i] = PFN_DOWN(addr) + i;
+		pfn[i] = XEN_PFN_DOWN(addr) + i;
 
 	xen_auto_xlat_grant_frames.vaddr = vaddr;
 	xen_auto_xlat_grant_frames.pfn = pfn;
@@ -1004,7 +1004,7 @@ static void gnttab_request_version(void)
 {
 	/* Only version 1 is used, which will always be available. */
 	grant_table_version = 1;
-	grefs_per_grant_frame = PAGE_SIZE / sizeof(struct grant_entry_v1);
+	grefs_per_grant_frame = XEN_PAGE_SIZE / sizeof(struct grant_entry_v1);
 	gnttab_interface = &gnttab_v1_ops;
 
 	pr_info("Grant tables using version %d layout\n", grant_table_version);
-- 
2.1.4



From julien.grall at citrix.com  Fri Aug  7 09:46:52 2015
From: julien.grall at citrix.com (Julien Grall)
Date: Fri, 7 Aug 2015 17:46:52 +0100
Subject: [PATCH v3 13/20] xen/events: fifo: Make it running on 64KB granularity
In-Reply-To: <1438966019-19322-1-git-send-email-julien.grall@citrix.com>
References: <1438966019-19322-1-git-send-email-julien.grall@citrix.com>
Message-ID: <1438966019-19322-14-git-send-email-julien.grall@citrix.com>

Only use the first 4KB of the page to store the events channel info. It
means that we will waste 60KB every time we allocate page for:
     * control block: a page is allocating per CPU
     * event array: a page is allocating everytime we need to expand it

I think we can reduce the memory waste for the 2 areas by:

    * control block: sharing between multiple vCPUs. Although it will
    require some bookkeeping in order to not free the page when the CPU
    goes offline and the other CPUs sharing the page still there

    * event array: always extend the array event by 64K (i.e 16 4K
    chunk). That would require more care when we fail to expand the
    event channel.

Signed-off-by: Julien Grall <julien.grall at citrix.com>
Reviewed-by: David Vrabel <david.vrabel at citrix.com>
Reviewed-by: Stefano Stabellini <stefano.stabellini at citrix.com>

---
Cc: Konrad Rzeszutek Wilk <konrad.wilk at oracle.com>
Cc: Boris Ostrovsky <boris.ostrovsky at oracle.com>

    Note I haven't updated the suggestion to reduce the memory waste
    after David's email [1]. I can do it if necessary.

    Changes in v3:
        - Add David and Stefano's reviewed-by

    [1] http://lists.xen.org/archives/html/xen-devel/2015-07/msg04596.html
---
 drivers/xen/events/events_base.c | 2 +-
 drivers/xen/events/events_fifo.c | 2 +-
 2 files changed, 2 insertions(+), 2 deletions(-)

diff --git a/drivers/xen/events/events_base.c b/drivers/xen/events/events_base.c
index c49bb7a..00dd923 100644
--- a/drivers/xen/events/events_base.c
+++ b/drivers/xen/events/events_base.c
@@ -40,11 +40,11 @@
 #include <asm/idle.h>
 #include <asm/io_apic.h>
 #include <asm/xen/pci.h>
-#include <xen/page.h>
 #endif
 #include <asm/sync_bitops.h>
 #include <asm/xen/hypercall.h>
 #include <asm/xen/hypervisor.h>
+#include <xen/page.h>
 
 #include <xen/xen.h>
 #include <xen/hvm.h>
diff --git a/drivers/xen/events/events_fifo.c b/drivers/xen/events/events_fifo.c
index 1d4baf5..e3e9e3d 100644
--- a/drivers/xen/events/events_fifo.c
+++ b/drivers/xen/events/events_fifo.c
@@ -54,7 +54,7 @@
 
 #include "events_internal.h"
 
-#define EVENT_WORDS_PER_PAGE (PAGE_SIZE / sizeof(event_word_t))
+#define EVENT_WORDS_PER_PAGE (XEN_PAGE_SIZE / sizeof(event_word_t))
 #define MAX_EVENT_ARRAY_PAGES (EVTCHN_FIFO_NR_CHANNELS / EVENT_WORDS_PER_PAGE)
 
 struct evtchn_fifo_queue {
-- 
2.1.4



From julien.grall at citrix.com  Fri Aug  7 09:46:50 2015
From: julien.grall at citrix.com (Julien Grall)
Date: Fri, 7 Aug 2015 17:46:50 +0100
Subject: [PATCH v3 11/20] tty/hvc: xen: Use xen page definition
In-Reply-To: <1438966019-19322-1-git-send-email-julien.grall@citrix.com>
References: <1438966019-19322-1-git-send-email-julien.grall@citrix.com>
Message-ID: <1438966019-19322-12-git-send-email-julien.grall@citrix.com>

The console ring is always based on the page granularity of Xen.

Signed-off-by: Julien Grall <julien.grall at citrix.com>
Reviewed-by: Stefano Stabellini <stefano.stabellini at eu.citrix.com>

---
Cc: Greg Kroah-Hartman <gregkh at linuxfoundation.org>
Cc: Jiri Slaby <jslaby at suse.cz>
Cc: David Vrabel <david.vrabel at citrix.com>
Cc: Boris Ostrovsky <boris.ostrovsky at oracle.com>
Cc: linuxppc-dev at lists.ozlabs.org

    Changes in v3:
        - Some changes has been moved in the series "Use correctly the
        Xen memory terminologies in Linux".
        - Add Stefano's reviewed-by
---
 drivers/tty/hvc/hvc_xen.c | 4 ++--
 1 file changed, 2 insertions(+), 2 deletions(-)

diff --git a/drivers/tty/hvc/hvc_xen.c b/drivers/tty/hvc/hvc_xen.c
index 10beb15..0599d9d 100644
--- a/drivers/tty/hvc/hvc_xen.c
+++ b/drivers/tty/hvc/hvc_xen.c
@@ -230,7 +230,7 @@ static int xen_hvm_console_init(void)
 	if (r < 0 || v == 0)
 		goto err;
 	gfn = v;
-	info->intf = xen_remap(gfn << PAGE_SHIFT, PAGE_SIZE);
+	info->intf = xen_remap(gfn << XEN_PAGE_SHIFT, PAGE_SIZE);
 	if (info->intf == NULL)
 		goto err;
 	info->vtermno = HVC_COOKIE;
@@ -472,7 +472,7 @@ static int xencons_resume(struct xenbus_device *dev)
 	struct xencons_info *info = dev_get_drvdata(&dev->dev);
 
 	xencons_disconnect_backend(info);
-	memset(info->intf, 0, PAGE_SIZE);
+	memset(info->intf, 0, XEN_PAGE_SIZE);
 	return xencons_connect_backend(dev, info);
 }
 
-- 
2.1.4



From julien.grall at citrix.com  Fri Aug  7 09:46:57 2015
From: julien.grall at citrix.com (Julien Grall)
Date: Fri, 7 Aug 2015 17:46:57 +0100
Subject: [PATCH v3 18/20] net/xen-netback: Make it running on 64KB page
 granularity
In-Reply-To: <1438966019-19322-1-git-send-email-julien.grall@citrix.com>
References: <1438966019-19322-1-git-send-email-julien.grall@citrix.com>
Message-ID: <1438966019-19322-19-git-send-email-julien.grall@citrix.com>

The PV network protocol is using 4KB page granularity. The goal of this
patch is to allow a Linux using 64KB page granularity working as a
network backend on a non-modified Xen.

It's only necessary to adapt the ring size and break skb data in small
chunk of 4KB. The rest of the code is relying on the grant table code.

Signed-off-by: Julien Grall <julien.grall at citrix.com>

---
Cc: Ian Campbell <ian.campbell at citrix.com>
Cc: Wei Liu <wei.liu2 at citrix.com>
Cc: netdev at vger.kernel.org

Improvement such as support of 64KB grant is not taken into
consideration in this patch because we have the requirement to run a
Linux using 64KB pages on a non-modified Xen.

    Changes in v3:
        - Fix errors reported by checkpatch.pl
        - s/mfn/gfn/ based on the new naming
        - gnttab_foreach_grant has been renamed to gnttab_forach_grant_in_range
        - The grant callback doesn't allow anymore to use less data. An
        helpers has been added in netback to handle this.

    Changes in v2:
        - Correctly set MAX_GRANT_COPY_OPS and XEN_NETBK_RX_SLOTS_MAX
        - Don't use XEN_PAGE_SIZE in handle_frag_list as we coalesce
        fragment into a new skb
        - Use gnntab_foreach_grant to split a Linux page into grant
---
 drivers/net/xen-netback/common.h  |  15 ++--
 drivers/net/xen-netback/netback.c | 153 ++++++++++++++++++++++++--------------
 2 files changed, 107 insertions(+), 61 deletions(-)

diff --git a/drivers/net/xen-netback/common.h b/drivers/net/xen-netback/common.h
index 8a495b3..bb68211 100644
--- a/drivers/net/xen-netback/common.h
+++ b/drivers/net/xen-netback/common.h
@@ -44,6 +44,7 @@
 #include <xen/interface/grant_table.h>
 #include <xen/grant_table.h>
 #include <xen/xenbus.h>
+#include <xen/page.h>
 #include <linux/debugfs.h>
 
 typedef unsigned int pending_ring_idx_t;
@@ -64,8 +65,8 @@ struct pending_tx_info {
 	struct ubuf_info callback_struct;
 };
 
-#define XEN_NETIF_TX_RING_SIZE __CONST_RING_SIZE(xen_netif_tx, PAGE_SIZE)
-#define XEN_NETIF_RX_RING_SIZE __CONST_RING_SIZE(xen_netif_rx, PAGE_SIZE)
+#define XEN_NETIF_TX_RING_SIZE __CONST_RING_SIZE(xen_netif_tx, XEN_PAGE_SIZE)
+#define XEN_NETIF_RX_RING_SIZE __CONST_RING_SIZE(xen_netif_rx, XEN_PAGE_SIZE)
 
 struct xenvif_rx_meta {
 	int id;
@@ -80,16 +81,18 @@ struct xenvif_rx_meta {
 /* Discriminate from any valid pending_idx value. */
 #define INVALID_PENDING_IDX 0xFFFF
 
-#define MAX_BUFFER_OFFSET PAGE_SIZE
+#define MAX_BUFFER_OFFSET XEN_PAGE_SIZE
 
 #define MAX_PENDING_REQS XEN_NETIF_TX_RING_SIZE
 
+#define MAX_XEN_SKB_FRAGS (65536 / XEN_PAGE_SIZE + 1)
+
 /* It's possible for an skb to have a maximal number of frags
  * but still be less than MAX_BUFFER_OFFSET in size. Thus the
- * worst-case number of copy operations is MAX_SKB_FRAGS per
+ * worst-case number of copy operations is MAX_XEN_SKB_FRAGS per
  * ring slot.
  */
-#define MAX_GRANT_COPY_OPS (MAX_SKB_FRAGS * XEN_NETIF_RX_RING_SIZE)
+#define MAX_GRANT_COPY_OPS (MAX_XEN_SKB_FRAGS * XEN_NETIF_RX_RING_SIZE)
 
 #define NETBACK_INVALID_HANDLE -1
 
@@ -203,7 +206,7 @@ struct xenvif_queue { /* Per-queue data for xenvif */
 /* Maximum number of Rx slots a to-guest packet may use, including the
  * slot needed for GSO meta-data.
  */
-#define XEN_NETBK_RX_SLOTS_MAX (MAX_SKB_FRAGS + 1)
+#define XEN_NETBK_RX_SLOTS_MAX ((MAX_XEN_SKB_FRAGS + 1))
 
 enum state_bit_shift {
 	/* This bit marks that the vif is connected */
diff --git a/drivers/net/xen-netback/netback.c b/drivers/net/xen-netback/netback.c
index 66f1780..c32a9f2 100644
--- a/drivers/net/xen-netback/netback.c
+++ b/drivers/net/xen-netback/netback.c
@@ -263,6 +263,80 @@ static struct xenvif_rx_meta *get_next_rx_buffer(struct xenvif_queue *queue,
 	return meta;
 }
 
+struct gop_frag_copy {
+	struct xenvif_queue *queue;
+	struct netrx_pending_operations *npo;
+	struct xenvif_rx_meta *meta;
+	int head;
+	int gso_type;
+
+	struct page *page;
+};
+
+static void xenvif_setup_copy_gop(unsigned long gfn,
+				  unsigned int offset,
+				  unsigned int *len,
+				  struct gop_frag_copy *info)
+{
+	struct gnttab_copy *copy_gop;
+	struct xen_page_foreign *foreign;
+	/* Convenient aliases */
+	struct xenvif_queue *queue = info->queue;
+	struct netrx_pending_operations *npo = info->npo;
+	struct page *page = info->page;
+
+	BUG_ON(npo->copy_off > MAX_BUFFER_OFFSET);
+
+	if (npo->copy_off == MAX_BUFFER_OFFSET)
+		info->meta = get_next_rx_buffer(queue, npo);
+
+	if (npo->copy_off + *len > MAX_BUFFER_OFFSET)
+		*len = MAX_BUFFER_OFFSET - npo->copy_off;
+
+	copy_gop = npo->copy + npo->copy_prod++;
+	copy_gop->flags = GNTCOPY_dest_gref;
+	copy_gop->len = *len;
+
+	foreign = xen_page_foreign(page);
+	if (foreign) {
+		copy_gop->source.domid = foreign->domid;
+		copy_gop->source.u.ref = foreign->gref;
+		copy_gop->flags |= GNTCOPY_source_gref;
+	} else {
+		copy_gop->source.domid = DOMID_SELF;
+		copy_gop->source.u.gmfn = gfn;
+	}
+	copy_gop->source.offset = offset;
+
+	copy_gop->dest.domid = queue->vif->domid;
+	copy_gop->dest.offset = npo->copy_off;
+	copy_gop->dest.u.ref = npo->copy_gref;
+
+	npo->copy_off += *len;
+	info->meta->size += *len;
+
+	/* Leave a gap for the GSO descriptor. */
+	if (info->head && ((1 << info->gso_type) & queue->vif->gso_mask))
+		queue->rx.req_cons++;
+
+	info->head = 0; /* There must be something in this buffer now */
+}
+
+static void xenvif_gop_frag_copy_grant(unsigned long gfn,
+				       unsigned offset,
+				       unsigned int len,
+				       void *data)
+{
+	unsigned int bytes;
+
+	while (len) {
+		bytes = len;
+		xenvif_setup_copy_gop(gfn, offset, &bytes, data);
+		offset += bytes;
+		len -= bytes;
+	}
+}
+
 /*
  * Set up the grant operations for this fragment. If it's a flipping
  * interface, we also set up the unmap request from here.
@@ -272,83 +346,52 @@ static void xenvif_gop_frag_copy(struct xenvif_queue *queue, struct sk_buff *skb
 				 struct page *page, unsigned long size,
 				 unsigned long offset, int *head)
 {
-	struct gnttab_copy *copy_gop;
-	struct xenvif_rx_meta *meta;
+	struct gop_frag_copy info = {
+		.queue = queue,
+		.npo = npo,
+		.head = *head,
+		.gso_type = XEN_NETIF_GSO_TYPE_NONE,
+	};
 	unsigned long bytes;
-	int gso_type = XEN_NETIF_GSO_TYPE_NONE;
 
 	if (skb_is_gso(skb)) {
 		if (skb_shinfo(skb)->gso_type & SKB_GSO_TCPV4)
-			gso_type = XEN_NETIF_GSO_TYPE_TCPV4;
+			info.gso_type = XEN_NETIF_GSO_TYPE_TCPV4;
 		else if (skb_shinfo(skb)->gso_type & SKB_GSO_TCPV6)
-			gso_type = XEN_NETIF_GSO_TYPE_TCPV6;
+			info.gso_type = XEN_NETIF_GSO_TYPE_TCPV6;
 	}
 
 	/* Data must not cross a page boundary. */
 	BUG_ON(size + offset > PAGE_SIZE<<compound_order(page));
 
-	meta = npo->meta + npo->meta_prod - 1;
+	info.meta = npo->meta + npo->meta_prod - 1;
 
 	/* Skip unused frames from start of page */
 	page += offset >> PAGE_SHIFT;
 	offset &= ~PAGE_MASK;
 
 	while (size > 0) {
-		struct xen_page_foreign *foreign;
-
 		BUG_ON(offset >= PAGE_SIZE);
-		BUG_ON(npo->copy_off > MAX_BUFFER_OFFSET);
-
-		if (npo->copy_off == MAX_BUFFER_OFFSET)
-			meta = get_next_rx_buffer(queue, npo);
 
 		bytes = PAGE_SIZE - offset;
 		if (bytes > size)
 			bytes = size;
 
-		if (npo->copy_off + bytes > MAX_BUFFER_OFFSET)
-			bytes = MAX_BUFFER_OFFSET - npo->copy_off;
-
-		copy_gop = npo->copy + npo->copy_prod++;
-		copy_gop->flags = GNTCOPY_dest_gref;
-		copy_gop->len = bytes;
-
-		foreign = xen_page_foreign(page);
-		if (foreign) {
-			copy_gop->source.domid = foreign->domid;
-			copy_gop->source.u.ref = foreign->gref;
-			copy_gop->flags |= GNTCOPY_source_gref;
-		} else {
-			copy_gop->source.domid = DOMID_SELF;
-			copy_gop->source.u.gmfn =
-				virt_to_gfn(page_address(page));
-		}
-		copy_gop->source.offset = offset;
-
-		copy_gop->dest.domid = queue->vif->domid;
-		copy_gop->dest.offset = npo->copy_off;
-		copy_gop->dest.u.ref = npo->copy_gref;
-
-		npo->copy_off += bytes;
-		meta->size += bytes;
-
-		offset += bytes;
+		info.page = page;
+		gnttab_foreach_grant_in_range(page, offset, bytes,
+					      xenvif_gop_frag_copy_grant,
+					      &info);
 		size -= bytes;
+		offset = 0;
 
-		/* Next frame */
-		if (offset == PAGE_SIZE && size) {
+		/* Next page */
+		if (size) {
 			BUG_ON(!PageCompound(page));
 			page++;
-			offset = 0;
 		}
-
-		/* Leave a gap for the GSO descriptor. */
-		if (*head && ((1 << gso_type) & queue->vif->gso_mask))
-			queue->rx.req_cons++;
-
-		*head = 0; /* There must be something in this buffer now. */
-
 	}
+
+	*head = info.head;
 }
 
 /*
@@ -747,7 +790,7 @@ static int xenvif_count_requests(struct xenvif_queue *queue,
 		first->size -= txp->size;
 		slots++;
 
-		if (unlikely((txp->offset + txp->size) > PAGE_SIZE)) {
+		if (unlikely((txp->offset + txp->size) > XEN_PAGE_SIZE)) {
 			netdev_err(queue->vif->dev, "Cross page boundary, txp->offset: %u, size: %u\n",
 				 txp->offset, txp->size);
 			xenvif_fatal_tx_err(queue->vif);
@@ -1241,11 +1284,11 @@ static void xenvif_tx_build_gops(struct xenvif_queue *queue,
 		}
 
 		/* No crossing a page as the payload mustn't fragment. */
-		if (unlikely((txreq.offset + txreq.size) > PAGE_SIZE)) {
+		if (unlikely((txreq.offset + txreq.size) > XEN_PAGE_SIZE)) {
 			netdev_err(queue->vif->dev,
 				   "txreq.offset: %u, size: %u, end: %lu\n",
 				   txreq.offset, txreq.size,
-				   (unsigned long)(txreq.offset&~PAGE_MASK) + txreq.size);
+				   (unsigned long)(txreq.offset&~XEN_PAGE_MASK) + txreq.size);
 			xenvif_fatal_tx_err(queue->vif);
 			break;
 		}
@@ -1287,7 +1330,7 @@ static void xenvif_tx_build_gops(struct xenvif_queue *queue,
 			virt_to_gfn(skb->data);
 		queue->tx_copy_ops[*copy_ops].dest.domid = DOMID_SELF;
 		queue->tx_copy_ops[*copy_ops].dest.offset =
-			offset_in_page(skb->data);
+			offset_in_page(skb->data) & ~XEN_PAGE_MASK;
 
 		queue->tx_copy_ops[*copy_ops].len = data_len;
 		queue->tx_copy_ops[*copy_ops].flags = GNTCOPY_source_gref;
@@ -1780,7 +1823,7 @@ int xenvif_map_frontend_rings(struct xenvif_queue *queue,
 		goto err;
 
 	txs = (struct xen_netif_tx_sring *)addr;
-	BACK_RING_INIT(&queue->tx, txs, PAGE_SIZE);
+	BACK_RING_INIT(&queue->tx, txs, XEN_PAGE_SIZE);
 
 	err = xenbus_map_ring_valloc(xenvif_to_xenbus_device(queue->vif),
 				     &rx_ring_ref, 1, &addr);
@@ -1788,7 +1831,7 @@ int xenvif_map_frontend_rings(struct xenvif_queue *queue,
 		goto err;
 
 	rxs = (struct xen_netif_rx_sring *)addr;
-	BACK_RING_INIT(&queue->rx, rxs, PAGE_SIZE);
+	BACK_RING_INIT(&queue->rx, rxs, XEN_PAGE_SIZE);
 
 	return 0;
 
-- 
2.1.4



From julien.grall at citrix.com  Fri Aug  7 09:46:54 2015
From: julien.grall at citrix.com (Julien Grall)
Date: Fri, 7 Aug 2015 17:46:54 +0100
Subject: [PATCH v3 15/20] block/xen-blkfront: Make it running on 64KB page
 granularity
In-Reply-To: <1438966019-19322-1-git-send-email-julien.grall@citrix.com>
References: <1438966019-19322-1-git-send-email-julien.grall@citrix.com>
Message-ID: <1438966019-19322-16-git-send-email-julien.grall@citrix.com>

The PV block protocol is using 4KB page granularity. The goal of this
patch is to allow a Linux using 64KB page granularity using block
device on a non-modified Xen.

The block API is using segment which should at least be the size of a
Linux page. Therefore, the driver will have to break the page in chunk
of 4K before giving the page to the backend.

Breaking a 64KB segment in 4KB chunk will result to have some chunk with
no data. As the PV protocol always require to have data in the chunk, we
have to count the number of Xen page which will be in use and avoid to
sent empty chunk.

Note that, a pre-defined number of grant is reserved before preparing
the request. This pre-defined number is based on the number and the
maximum size of the segments. If each segment contain a very small
amount of data, the driver may reserve too much grant (16 grant is
reserved per segment with 64KB page granularity).

Futhermore, in the case of persistent grant we allocate one Linux page
per grant although only the 4KB of the page will be effectively use.
This could be improved by share the page with multiple grants.

Signed-off-by: Julien Grall <julien.grall at citrix.com>

---
Cc: Konrad Rzeszutek Wilk <konrad.wilk at oracle.com>
Cc: Roger Pau Monn? <roger.pau at citrix.com>
Cc: Boris Ostrovsky <boris.ostrovsky at oracle.com>
Cc: David Vrabel <david.vrabel at citrix.com>

Improvement such as support 64KB grant is not taken into consideration in
this patch because we have the requirement to run a Linux using 64KB page
on a non-modified Xen.

Royger, I haven't retain your acked-by because of some changes which
were not because of naming modifications.

    Changes in v3:
        - Use DIV_ROUND_UP in INDIRECT_GREFS
        - Split lines over 80 characters whenever it's possible
        - s/mfn/gfn/ based on the new naming
        - The grant callback doesn't allow anymore to change the len
        (wasn't used here).
        - gnttab_foreach_grant has been renamed to gnttab_foreach_grant_in_range
        - Use gnttab_count_grant to get the number of grants in a sg
        - Do some renaming to use the correct variable every time

    Changes in v2:
        - Use gnttab_foreach_grant to split a Linux page into grant
---
 drivers/block/xen-blkfront.c | 324 ++++++++++++++++++++++++++++---------------
 1 file changed, 213 insertions(+), 111 deletions(-)

diff --git a/drivers/block/xen-blkfront.c b/drivers/block/xen-blkfront.c
index 52105e7..acc4208 100644
--- a/drivers/block/xen-blkfront.c
+++ b/drivers/block/xen-blkfront.c
@@ -78,6 +78,7 @@ struct blk_shadow {
 	struct grant **grants_used;
 	struct grant **indirect_grants;
 	struct scatterlist *sg;
+	unsigned int num_sg;
 };
 
 struct split_bio {
@@ -107,8 +108,12 @@ static unsigned int xen_blkif_max_ring_order;
 module_param_named(max_ring_page_order, xen_blkif_max_ring_order, int, S_IRUGO);
 MODULE_PARM_DESC(max_ring_page_order, "Maximum order of pages to be used for the shared ring");
 
-#define BLK_RING_SIZE(info) __CONST_RING_SIZE(blkif, PAGE_SIZE * (info)->nr_ring_pages)
-#define BLK_MAX_RING_SIZE __CONST_RING_SIZE(blkif, PAGE_SIZE * XENBUS_MAX_RING_PAGES)
+#define BLK_RING_SIZE(info)	\
+	__CONST_RING_SIZE(blkif, XEN_PAGE_SIZE * (info)->nr_ring_pages)
+
+#define BLK_MAX_RING_SIZE	\
+	__CONST_RING_SIZE(blkif, XEN_PAGE_SIZE * XENBUS_MAX_RING_PAGES)
+
 /*
  * ring-ref%i i=(-1UL) would take 11 characters + 'ring-ref' is 8, so 19
  * characters are enough. Define to 20 to keep consist with backend.
@@ -147,6 +152,7 @@ struct blkfront_info
 	unsigned int discard_granularity;
 	unsigned int discard_alignment;
 	unsigned int feature_persistent:1;
+	/* Number of 4KB segments handled */
 	unsigned int max_indirect_segments;
 	int is_ready;
 	struct blk_mq_tag_set tag_set;
@@ -175,10 +181,23 @@ static DEFINE_SPINLOCK(minor_lock);
 
 #define DEV_NAME	"xvd"	/* name in /dev */
 
-#define SEGS_PER_INDIRECT_FRAME \
-	(PAGE_SIZE/sizeof(struct blkif_request_segment))
-#define INDIRECT_GREFS(_segs) \
-	((_segs + SEGS_PER_INDIRECT_FRAME - 1)/SEGS_PER_INDIRECT_FRAME)
+/*
+ * Grants are always the same size as a Xen page (i.e 4KB).
+ * A physical segment is always the same size as a Linux page.
+ * Number of grants per physical segment
+ */
+#define GRANTS_PER_PSEG	(PAGE_SIZE / XEN_PAGE_SIZE)
+
+#define GRANTS_PER_INDIRECT_FRAME \
+	(XEN_PAGE_SIZE / sizeof(struct blkif_request_segment))
+
+#define PSEGS_PER_INDIRECT_FRAME	\
+	(GRANTS_INDIRECT_FRAME / GRANTS_PSEGS)
+
+#define INDIRECT_GREFS(_grants)		\
+	DIV_ROUND_UP(_grants, GRANTS_PER_INDIRECT_FRAME)
+
+#define GREFS(_psegs)	((_psegs) * GRANTS_PER_PSEG)
 
 static int blkfront_setup_indirect(struct blkfront_info *info);
 
@@ -465,14 +484,100 @@ static int blkif_queue_discard_req(struct request *req)
 	return 0;
 }
 
+struct setup_rw_req {
+	unsigned int grant_idx;
+	struct blkif_request_segment *segments;
+	struct blkfront_info *info;
+	struct blkif_request *ring_req;
+	grant_ref_t gref_head;
+	unsigned int id;
+	/* Only used when persistent grant is used and it's a read request */
+	bool need_copy;
+	unsigned int bvec_off;
+	char *bvec_data;
+};
+
+static void blkif_setup_rw_req_grant(unsigned long gfn, unsigned int offset,
+				     unsigned int len, void *data)
+{
+	struct setup_rw_req *setup = data;
+	int n, ref;
+	struct grant *gnt_list_entry;
+	unsigned int fsect, lsect;
+	/* Convenient aliases */
+	unsigned int grant_idx = setup->grant_idx;
+	struct blkif_request *ring_req = setup->ring_req;
+	struct blkfront_info *info = setup->info;
+	struct blk_shadow *shadow = &info->shadow[setup->id];
+
+	if ((ring_req->operation == BLKIF_OP_INDIRECT) &&
+	    (grant_idx % GRANTS_PER_INDIRECT_FRAME == 0)) {
+		if (setup->segments)
+			kunmap_atomic(setup->segments);
+
+		n = grant_idx / GRANTS_PER_INDIRECT_FRAME;
+		gnt_list_entry = get_indirect_grant(&setup->gref_head, info);
+		shadow->indirect_grants[n] = gnt_list_entry;
+		setup->segments = kmap_atomic(gnt_list_entry->page);
+		ring_req->u.indirect.indirect_grefs[n] = gnt_list_entry->gref;
+	}
+
+	gnt_list_entry = get_grant(&setup->gref_head, gfn, info);
+	ref = gnt_list_entry->gref;
+	shadow->grants_used[grant_idx] = gnt_list_entry;
+
+	if (setup->need_copy) {
+		void *shared_data;
+
+		shared_data = kmap_atomic(gnt_list_entry->page);
+		/*
+		 * this does not wipe data stored outside the
+		 * range sg->offset..sg->offset+sg->length.
+		 * Therefore, blkback *could* see data from
+		 * previous requests. This is OK as long as
+		 * persistent grants are shared with just one
+		 * domain. It may need refactoring if this
+		 * changes
+		 */
+		memcpy(shared_data + offset,
+		       setup->bvec_data + setup->bvec_off,
+		       len);
+
+		kunmap_atomic(shared_data);
+		setup->bvec_off += len;
+	}
+
+	fsect = offset >> 9;
+	lsect = fsect + (len >> 9) - 1;
+	if (ring_req->operation != BLKIF_OP_INDIRECT) {
+		ring_req->u.rw.seg[grant_idx] =
+			(struct blkif_request_segment) {
+				.gref       = ref,
+				.first_sect = fsect,
+				.last_sect  = lsect };
+	} else {
+		setup->segments[grant_idx % GRANTS_PER_INDIRECT_FRAME] =
+			(struct blkif_request_segment) {
+				.gref       = ref,
+				.first_sect = fsect,
+				.last_sect  = lsect };
+	}
+
+	(setup->grant_idx)++;
+}
+
 static int blkif_queue_rw_req(struct request *req)
 {
 	struct blkfront_info *info = req->rq_disk->private_data;
 	struct blkif_request *ring_req;
 	unsigned long id;
-	unsigned int fsect, lsect;
-	int i, ref, n;
-	struct blkif_request_segment *segments = NULL;
+	int i;
+	struct setup_rw_req setup = {
+		.grant_idx = 0,
+		.segments = NULL,
+		.info = info,
+		.need_copy = rq_data_dir(req) && info->feature_persistent,
+	};
 
 	/*
 	 * Used to store if we are able to queue the request by just using
@@ -480,25 +585,23 @@ static int blkif_queue_rw_req(struct request *req)
 	 * as there are not sufficiently many free.
 	 */
 	bool new_persistent_gnts;
-	grant_ref_t gref_head;
-	struct grant *gnt_list_entry = NULL;
 	struct scatterlist *sg;
-	int nseg, max_grefs;
+	int num_sg, max_grefs, num_grant;
 
-	max_grefs = req->nr_phys_segments;
+	max_grefs = req->nr_phys_segments * GRANTS_PER_PSEG;
 	if (max_grefs > BLKIF_MAX_SEGMENTS_PER_REQUEST)
 		/*
 		 * If we are using indirect segments we need to account
 		 * for the indirect grefs used in the request.
 		 */
-		max_grefs += INDIRECT_GREFS(req->nr_phys_segments);
+		max_grefs += INDIRECT_GREFS(max_grefs);
 
 	/* Check if we have enough grants to allocate a requests */
 	if (info->persistent_gnts_c < max_grefs) {
 		new_persistent_gnts = 1;
 		if (gnttab_alloc_grant_references(
 		    max_grefs - info->persistent_gnts_c,
-		    &gref_head) < 0) {
+		    &setup.gref_head) < 0) {
 			gnttab_request_free_callback(
 				&info->callback,
 				blkif_restart_queue_callback,
@@ -515,12 +618,19 @@ static int blkif_queue_rw_req(struct request *req)
 	info->shadow[id].request = req;
 
 	BUG_ON(info->max_indirect_segments == 0 &&
-	       req->nr_phys_segments > BLKIF_MAX_SEGMENTS_PER_REQUEST);
+	       GREFS(req->nr_phys_segments) > BLKIF_MAX_SEGMENTS_PER_REQUEST);
 	BUG_ON(info->max_indirect_segments &&
-	       req->nr_phys_segments > info->max_indirect_segments);
-	nseg = blk_rq_map_sg(req->q, req, info->shadow[id].sg);
+	       GREFS(req->nr_phys_segments) > info->max_indirect_segments);
+
+	num_sg = blk_rq_map_sg(req->q, req, info->shadow[id].sg);
+	num_grant = 0;
+	/* Calculate the number of grant used */
+	for_each_sg(info->shadow[id].sg, sg, num_sg, i)
+	       num_grant += gnttab_count_grant(sg->offset, sg->length);
+
 	ring_req->u.rw.id = id;
-	if (nseg > BLKIF_MAX_SEGMENTS_PER_REQUEST) {
+	info->shadow[id].num_sg = num_sg;
+	if (num_grant > BLKIF_MAX_SEGMENTS_PER_REQUEST) {
 		/*
 		 * The indirect operation can only be a BLKIF_OP_READ or
 		 * BLKIF_OP_WRITE
@@ -531,7 +641,7 @@ static int blkif_queue_rw_req(struct request *req)
 			BLKIF_OP_WRITE : BLKIF_OP_READ;
 		ring_req->u.indirect.sector_number = (blkif_sector_t)blk_rq_pos(req);
 		ring_req->u.indirect.handle = info->handle;
-		ring_req->u.indirect.nr_segments = nseg;
+		ring_req->u.indirect.nr_segments = num_grant;
 	} else {
 		ring_req->u.rw.sector_number = (blkif_sector_t)blk_rq_pos(req);
 		ring_req->u.rw.handle = info->handle;
@@ -559,73 +669,30 @@ static int blkif_queue_rw_req(struct request *req)
 				ring_req->operation = 0;
 			}
 		}
-		ring_req->u.rw.nr_segments = nseg;
-	}
-	for_each_sg(info->shadow[id].sg, sg, nseg, i) {
-		fsect = sg->offset >> 9;
-		lsect = fsect + (sg->length >> 9) - 1;
-
-		if ((ring_req->operation == BLKIF_OP_INDIRECT) &&
-		    (i % SEGS_PER_INDIRECT_FRAME == 0)) {
-			if (segments)
-				kunmap_atomic(segments);
-
-			n = i / SEGS_PER_INDIRECT_FRAME;
-			gnt_list_entry = get_indirect_grant(&gref_head, info);
-			info->shadow[id].indirect_grants[n] = gnt_list_entry;
-			segments = kmap_atomic(gnt_list_entry->page);
-			ring_req->u.indirect.indirect_grefs[n] = gnt_list_entry->gref;
-		}
-
-		gnt_list_entry = get_grant(&gref_head,
-					   xen_page_to_gfn(sg_page(sg)),
-					   info);
-		ref = gnt_list_entry->gref;
-
-		info->shadow[id].grants_used[i] = gnt_list_entry;
-
-		if (rq_data_dir(req) && info->feature_persistent) {
-			char *bvec_data;
-			void *shared_data;
+		ring_req->u.rw.nr_segments = num_grant;
+	}
 
-			BUG_ON(sg->offset + sg->length > PAGE_SIZE);
+	setup.ring_req = ring_req;
+	setup.id = id;
+	for_each_sg(info->shadow[id].sg, sg, num_sg, i) {
+		BUG_ON(sg->offset + sg->length > PAGE_SIZE);
 
-			shared_data = kmap_atomic(gnt_list_entry->page);
-			bvec_data = kmap_atomic(sg_page(sg));
+		if (setup.need_copy) {
+			setup.bvec_off = sg->offset;
+			setup.bvec_data = kmap_atomic(sg_page(sg));
+		}
 
-			/*
-			 * this does not wipe data stored outside the
-			 * range sg->offset..sg->offset+sg->length.
-			 * Therefore, blkback *could* see data from
-			 * previous requests. This is OK as long as
-			 * persistent grants are shared with just one
-			 * domain. It may need refactoring if this
-			 * changes
-			 */
-			memcpy(shared_data + sg->offset,
-			       bvec_data   + sg->offset,
-			       sg->length);
+		gnttab_foreach_grant_in_range(sg_page(sg),
+					      sg->offset,
+					      sg->length,
+					      blkif_setup_rw_req_grant,
+					      &setup);
 
-			kunmap_atomic(bvec_data);
-			kunmap_atomic(shared_data);
-		}
-		if (ring_req->operation != BLKIF_OP_INDIRECT) {
-			ring_req->u.rw.seg[i] =
-					(struct blkif_request_segment) {
-						.gref       = ref,
-						.first_sect = fsect,
-						.last_sect  = lsect };
-		} else {
-			n = i % SEGS_PER_INDIRECT_FRAME;
-			segments[n] =
-				(struct blkif_request_segment) {
-						.gref       = ref,
-						.first_sect = fsect,
-						.last_sect  = lsect };
-		}
+		if (setup.need_copy)
+			kunmap_atomic(setup.bvec_data);
 	}
-	if (segments)
-		kunmap_atomic(segments);
+	if (setup.segments)
+		kunmap_atomic(setup.segments);
 
 	info->ring.req_prod_pvt++;
 
@@ -633,7 +700,7 @@ static int blkif_queue_rw_req(struct request *req)
 	info->shadow[id].req = *ring_req;
 
 	if (new_persistent_gnts)
-		gnttab_free_grant_references(gref_head);
+		gnttab_free_grant_references(setup.gref_head);
 
 	return 0;
 }
@@ -750,14 +817,14 @@ static int xlvbd_init_blk_queue(struct gendisk *gd, u16 sector_size,
 	/* Hard sector size and max sectors impersonate the equiv. hardware. */
 	blk_queue_logical_block_size(rq, sector_size);
 	blk_queue_physical_block_size(rq, physical_sector_size);
-	blk_queue_max_hw_sectors(rq, (segments * PAGE_SIZE) / 512);
+	blk_queue_max_hw_sectors(rq, (segments * XEN_PAGE_SIZE) / 512);
 
 	/* Each segment in a request is up to an aligned page in size. */
 	blk_queue_segment_boundary(rq, PAGE_SIZE - 1);
 	blk_queue_max_segment_size(rq, PAGE_SIZE);
 
 	/* Ensure a merged request will fit in a single I/O ring slot. */
-	blk_queue_max_segments(rq, segments);
+	blk_queue_max_segments(rq, segments / GRANTS_PER_PSEG);
 
 	/* Make sure buffer addresses are sector-aligned. */
 	blk_queue_dma_alignment(rq, 511);
@@ -1116,32 +1183,65 @@ free_shadow:
 
 }
 
+struct copy_from_grant {
+	const struct blk_shadow *s;
+	unsigned int grant_idx;
+	unsigned int bvec_offset;
+	char *bvec_data;
+};
+
+static void blkif_copy_from_grant(unsigned long gfn, unsigned int offset,
+				  unsigned int len, void *data)
+{
+	struct copy_from_grant *info = data;
+	char *shared_data;
+	/* Convenient aliases */
+	const struct blk_shadow *s = info->s;
+
+	shared_data = kmap_atomic(s->grants_used[info->grant_idx]->page);
+
+	memcpy(info->bvec_data + info->bvec_offset,
+	       shared_data + offset, len);
+
+	info->bvec_offset += len;
+	info->grant_idx++;
+
+	kunmap_atomic(shared_data);
+}
+
 static void blkif_completion(struct blk_shadow *s, struct blkfront_info *info,
 			     struct blkif_response *bret)
 {
 	int i = 0;
 	struct scatterlist *sg;
-	char *bvec_data;
-	void *shared_data;
-	int nseg;
+	int num_sg, num_grant;
+	struct copy_from_grant data = {
+		.s = s,
+		.grant_idx = 0,
+	};
 
-	nseg = s->req.operation == BLKIF_OP_INDIRECT ?
+	num_grant = s->req.operation == BLKIF_OP_INDIRECT ?
 		s->req.u.indirect.nr_segments : s->req.u.rw.nr_segments;
+	num_sg = s->num_sg;
 
 	if (bret->operation == BLKIF_OP_READ && info->feature_persistent) {
-		for_each_sg(s->sg, sg, nseg, i) {
+		for_each_sg(s->sg, sg, num_sg, i) {
 			BUG_ON(sg->offset + sg->length > PAGE_SIZE);
-			shared_data = kmap_atomic(s->grants_used[i]->page);
-			bvec_data = kmap_atomic(sg_page(sg));
-			memcpy(bvec_data   + sg->offset,
-			       shared_data + sg->offset,
-			       sg->length);
-			kunmap_atomic(bvec_data);
-			kunmap_atomic(shared_data);
+
+			data.bvec_offset = sg->offset;
+			data.bvec_data = kmap_atomic(sg_page(sg));
+
+			gnttab_foreach_grant_in_range(sg_page(sg),
+						      sg->offset,
+						      sg->length,
+						      blkif_copy_from_grant,
+						      &data);
+
+			kunmap_atomic(data.bvec_data);
 		}
 	}
 	/* Add the persistent grant into the list of free grants */
-	for (i = 0; i < nseg; i++) {
+	for (i = 0; i < num_grant; i++) {
 		if (gnttab_query_foreign_access(s->grants_used[i]->gref)) {
 			/*
 			 * If the grant is still mapped by the backend (the
@@ -1167,7 +1267,7 @@ static void blkif_completion(struct blk_shadow *s, struct blkfront_info *info,
 		}
 	}
 	if (s->req.operation == BLKIF_OP_INDIRECT) {
-		for (i = 0; i < INDIRECT_GREFS(nseg); i++) {
+		for (i = 0; i < INDIRECT_GREFS(num_grant); i++) {
 			if (gnttab_query_foreign_access(s->indirect_grants[i]->gref)) {
 				if (!info->feature_persistent)
 					pr_alert_ratelimited("backed has not unmapped grant: %u\n",
@@ -1309,7 +1409,7 @@ static int setup_blkring(struct xenbus_device *dev,
 {
 	struct blkif_sring *sring;
 	int err, i;
-	unsigned long ring_size = info->nr_ring_pages * PAGE_SIZE;
+	unsigned long ring_size = info->nr_ring_pages * XEN_PAGE_SIZE;
 	grant_ref_t gref[XENBUS_MAX_RING_PAGES];
 
 	for (i = 0; i < info->nr_ring_pages; i++)
@@ -1640,8 +1740,8 @@ static int blkif_recover(struct blkfront_info *info)
 			atomic_set(&split_bio->pending, pending);
 			split_bio->bio = bio;
 			for (i = 0; i < pending; i++) {
-				offset = (i * segs * PAGE_SIZE) >> 9;
-				size = min((unsigned int)(segs * PAGE_SIZE) >> 9,
+				offset = (i * segs * XEN_PAGE_SIZE) >> 9;
+				size = min((unsigned int)(segs * XEN_PAGE_SIZE) >> 9,
 					   (unsigned int)bio_sectors(bio) - offset);
 				cloned_bio = bio_clone(bio, GFP_NOIO);
 				BUG_ON(cloned_bio == NULL);
@@ -1752,7 +1852,7 @@ static void blkfront_setup_discard(struct blkfront_info *info)
 
 static int blkfront_setup_indirect(struct blkfront_info *info)
 {
-	unsigned int indirect_segments, segs;
+	unsigned int indirect_segments, psegs, grants;
 	int err, i;
 
 	err = xenbus_gather(XBT_NIL, info->xbdev->otherend,
@@ -1760,14 +1860,16 @@ static int blkfront_setup_indirect(struct blkfront_info *info)
 			    NULL);
 	if (err) {
 		info->max_indirect_segments = 0;
-		segs = BLKIF_MAX_SEGMENTS_PER_REQUEST;
+		grants = BLKIF_MAX_SEGMENTS_PER_REQUEST;
 	} else {
 		info->max_indirect_segments = min(indirect_segments,
 						  xen_blkif_max_segments);
-		segs = info->max_indirect_segments;
+		grants = info->max_indirect_segments;
 	}
+	psegs = grants / GRANTS_PER_PSEG;
 
-	err = fill_grant_buffer(info, (segs + INDIRECT_GREFS(segs)) * BLK_RING_SIZE(info));
+	err = fill_grant_buffer(info,
+				(grants + INDIRECT_GREFS(grants)) * BLK_RING_SIZE(info));
 	if (err)
 		goto out_of_memory;
 
@@ -1777,7 +1879,7 @@ static int blkfront_setup_indirect(struct blkfront_info *info)
 		 * grants, we need to allocate a set of pages that can be
 		 * used for mapping indirect grefs
 		 */
-		int num = INDIRECT_GREFS(segs) * BLK_RING_SIZE(info);
+		int num = INDIRECT_GREFS(grants) * BLK_RING_SIZE(info);
 
 		BUG_ON(!list_empty(&info->indirect_pages));
 		for (i = 0; i < num; i++) {
@@ -1790,20 +1892,20 @@ static int blkfront_setup_indirect(struct blkfront_info *info)
 
 	for (i = 0; i < BLK_RING_SIZE(info); i++) {
 		info->shadow[i].grants_used = kzalloc(
-			sizeof(info->shadow[i].grants_used[0]) * segs,
+			sizeof(info->shadow[i].grants_used[0]) * grants,
 			GFP_NOIO);
-		info->shadow[i].sg = kzalloc(sizeof(info->shadow[i].sg[0]) * segs, GFP_NOIO);
+		info->shadow[i].sg = kzalloc(sizeof(info->shadow[i].sg[0]) * psegs, GFP_NOIO);
 		if (info->max_indirect_segments)
 			info->shadow[i].indirect_grants = kzalloc(
 				sizeof(info->shadow[i].indirect_grants[0]) *
-				INDIRECT_GREFS(segs),
+				INDIRECT_GREFS(grants),
 				GFP_NOIO);
 		if ((info->shadow[i].grants_used == NULL) ||
 			(info->shadow[i].sg == NULL) ||
 		     (info->max_indirect_segments &&
 		     (info->shadow[i].indirect_grants == NULL)))
 			goto out_of_memory;
-		sg_init_table(info->shadow[i].sg, segs);
+		sg_init_table(info->shadow[i].sg, psegs);
 	}
 
 
-- 
2.1.4



From julien.grall at citrix.com  Fri Aug  7 09:46:51 2015
From: julien.grall at citrix.com (Julien Grall)
Date: Fri, 7 Aug 2015 17:46:51 +0100
Subject: [PATCH v3 12/20] xen/balloon: Don't rely on the page granularity is
 the same for Xen and Linux
In-Reply-To: <1438966019-19322-1-git-send-email-julien.grall@citrix.com>
References: <1438966019-19322-1-git-send-email-julien.grall@citrix.com>
Message-ID: <1438966019-19322-13-git-send-email-julien.grall@citrix.com>

For ARM64 guests, Linux is able to support either 64K or 4K page
granularity. Although, the hypercall interface is always based on 4K
page granularity.

With 64K page granularity, a single page will be spread over multiple
Xen frame.

To avoid splitting the page into 4K frame, take advantage of the
extent_order field to directly allocate/free chunk of the Linux page
size.

Note that PVMMU is only used for PV guest (which is x86) and the page
granularity is always 4KB. Some BUILD_BUG_ON has been added to ensure
that because the code has not been modified.

Signed-off-by: Julien Grall <julien.grall at citrix.com>

---
Cc: Konrad Rzeszutek Wilk <konrad.wilk at oracle.com>
Cc: Boris Ostrovsky <boris.ostrovsky at oracle.com>
Cc: David Vrabel <david.vrabel at citrix.com>
Cc: Wei Liu <wei.liu2 at citrix.com>

    Changes in v3:
        - Fix errors reported by checkpatch.pl
        - s/mfn/gfn/ based on the new naming
        - Rather than splitting the page into 4KB chunk, use the
        extent_order field to allocate directly a Linux page size. This
        is avoid lots of code for no benefits.

    Changes in v2:
        - Use xen_apply_to_page to split a page in 4K chunk
        - It's not necessary to have a smaller frame list. Re-use
        PAGE_SIZE
        - Convert reserve_additional_memory to use XEN_... macro
---
 drivers/xen/balloon.c | 47 ++++++++++++++++++++++++++++++++++++-----------
 1 file changed, 36 insertions(+), 11 deletions(-)

diff --git a/drivers/xen/balloon.c b/drivers/xen/balloon.c
index 9734649..c8739c8 100644
--- a/drivers/xen/balloon.c
+++ b/drivers/xen/balloon.c
@@ -70,6 +70,9 @@
 #include <xen/features.h>
 #include <xen/page.h>
 
+/* Use one extent per PAGE_SIZE to avoid break down into multiple frame */
+#define EXTENT_ORDER (fls(XEN_PFN_PER_PAGE) - 1)
+
 /*
  * balloon_process() state:
  *
@@ -230,6 +233,11 @@ static enum bp_state reserve_additional_memory(long credit)
 	nid = memory_add_physaddr_to_nid(hotplug_start_paddr);
 
 #ifdef CONFIG_XEN_HAVE_PVMMU
+	/* We don't support PV MMU when Linux and Xen is using
+	 * different page granularity.
+	 */
+	BUILD_BUG_ON(XEN_PAGE_SIZE != PAGE_SIZE);
+
         /*
          * add_memory() will build page tables for the new memory so
          * the p2m must contain invalid entries so the correct
@@ -326,11 +334,11 @@ static enum bp_state reserve_additional_memory(long credit)
 static enum bp_state increase_reservation(unsigned long nr_pages)
 {
 	int rc;
-	unsigned long  pfn, i;
+	unsigned long i;
 	struct page   *page;
 	struct xen_memory_reservation reservation = {
 		.address_bits = 0,
-		.extent_order = 0,
+		.extent_order = EXTENT_ORDER,
 		.domid        = DOMID_SELF
 	};
 
@@ -352,7 +360,11 @@ static enum bp_state increase_reservation(unsigned long nr_pages)
 			nr_pages = i;
 			break;
 		}
-		frame_list[i] = page_to_pfn(page);
+
+		/* XENMEM_populate_physmap requires a PFN based on Xen
+		 * granularity.
+		 */
+		frame_list[i] = xen_page_to_pfn(page);
 		page = balloon_next_page(page);
 	}
 
@@ -366,10 +378,15 @@ static enum bp_state increase_reservation(unsigned long nr_pages)
 		page = balloon_retrieve(false);
 		BUG_ON(page == NULL);
 
-		pfn = page_to_pfn(page);
-
 #ifdef CONFIG_XEN_HAVE_PVMMU
+		/* We don't support PV MMU when Linux and Xen is using
+		 * different page granularity.
+		 */
+		BUILD_BUG_ON(XEN_PAGE_SIZE != PAGE_SIZE);
+
 		if (!xen_feature(XENFEAT_auto_translated_physmap)) {
+			unsigned long pfn = page_to_pfn(page);
+
 			set_phys_to_machine(pfn, frame_list[i]);
 
 			/* Link back into the page tables if not highmem. */
@@ -396,14 +413,15 @@ static enum bp_state increase_reservation(unsigned long nr_pages)
 static enum bp_state decrease_reservation(unsigned long nr_pages, gfp_t gfp)
 {
 	enum bp_state state = BP_DONE;
-	unsigned long  pfn, i;
+	unsigned long i;
 	struct page   *page;
 	int ret;
 	struct xen_memory_reservation reservation = {
 		.address_bits = 0,
-		.extent_order = 0,
+		.extent_order = EXTENT_ORDER,
 		.domid        = DOMID_SELF
 	};
+	static struct page *pages[ARRAY_SIZE(frame_list)];
 
 #ifdef CONFIG_XEN_BALLOON_MEMORY_HOTPLUG
 	if (balloon_stats.hotplug_pages) {
@@ -426,7 +444,9 @@ static enum bp_state decrease_reservation(unsigned long nr_pages, gfp_t gfp)
 		}
 		scrub_page(page);
 
-		frame_list[i] = page_to_pfn(page);
+		/* XENMEM_decrease_reservation requires a GFN */
+		frame_list[i] = xen_page_to_gfn(page);
+		pages[i] = page;
 	}
 
 	/*
@@ -440,12 +460,17 @@ static enum bp_state decrease_reservation(unsigned long nr_pages, gfp_t gfp)
 
 	/* Update direct mapping, invalidate P2M, and add to balloon. */
 	for (i = 0; i < nr_pages; i++) {
-		pfn = frame_list[i];
-		frame_list[i] = pfn_to_gfn(pfn);
-		page = pfn_to_page(pfn);
+		page = pages[i];
 
 #ifdef CONFIG_XEN_HAVE_PVMMU
+		/* We don't support PV MMU when Linux and Xen is using
+		 * different page granularity.
+		 */
+		BUILD_BUG_ON(XEN_PAGE_SIZE != PAGE_SIZE);
+
 		if (!xen_feature(XENFEAT_auto_translated_physmap)) {
+			unsigned long pfn = page_to_pfn(page);
+
 			if (!PageHighMem(page)) {
 				ret = HYPERVISOR_update_va_mapping(
 						(unsigned long)__va(pfn << PAGE_SHIFT),
-- 
2.1.4



From julien.grall at citrix.com  Fri Aug  7 09:46:56 2015
From: julien.grall at citrix.com (Julien Grall)
Date: Fri, 7 Aug 2015 17:46:56 +0100
Subject: [PATCH v3 17/20] net/xen-netfront: Make it running on 64KB page
 granularity
In-Reply-To: <1438966019-19322-1-git-send-email-julien.grall@citrix.com>
References: <1438966019-19322-1-git-send-email-julien.grall@citrix.com>
Message-ID: <1438966019-19322-18-git-send-email-julien.grall@citrix.com>

The PV network protocol is using 4KB page granularity. The goal of this
patch is to allow a Linux using 64KB page granularity using network
device on a non-modified Xen.

It's only necessary to adapt the ring size and break skb data in small
chunk of 4KB. The rest of the code is relying on the grant table code.

Note that we allocate a Linux page for each rx skb but only the first
4KB is used. We may improve the memory usage by extending the size of
the rx skb.

Signed-off-by: Julien Grall <julien.grall at citrix.com>

---
Cc: Konrad Rzeszutek Wilk <konrad.wilk at oracle.com>
Cc: Boris Ostrovsky <boris.ostrovsky at oracle.com>
Cc: David Vrabel <david.vrabel at citrix.com>
Cc: netdev at vger.kernel.org

Improvement such as support of 64KB grant is not taken into
consideration in this patch because we have the requirement to run a Linux
using 64KB pages on a non-modified Xen.

Tested with workload such as ping, ssh, wget, git... I would happy if
someone give details how to test all the path.

    Changes in v3:
        - Fix errors reported by checkpatch.pl
        - s/mfn/gfn/ base on the new naming
        - xennet_tx_setup_grant was calling itself resulting an
        guest stall when using iperf.
        - The grant callback doesn't allow anymore to change the len
        (wasn't used here)
        - gnttab_foreach_grant has been renamed to gnttab_foreach_grant_in_range
        - gnttab_page_grant_foreign_ref has been renamed to
        gnttab_foreach_grant_foreign_ref_one

    Changes in v2:
        - Use gnttab_foreach_grant to split a Linux page in grant
        - Fix count slots
---
 drivers/net/xen-netfront.c | 122 ++++++++++++++++++++++++++++++++-------------
 1 file changed, 86 insertions(+), 36 deletions(-)

diff --git a/drivers/net/xen-netfront.c b/drivers/net/xen-netfront.c
index 47f791e..204ffb8 100644
--- a/drivers/net/xen-netfront.c
+++ b/drivers/net/xen-netfront.c
@@ -74,8 +74,8 @@ struct netfront_cb {
 
 #define GRANT_INVALID_REF	0
 
-#define NET_TX_RING_SIZE __CONST_RING_SIZE(xen_netif_tx, PAGE_SIZE)
-#define NET_RX_RING_SIZE __CONST_RING_SIZE(xen_netif_rx, PAGE_SIZE)
+#define NET_TX_RING_SIZE __CONST_RING_SIZE(xen_netif_tx, XEN_PAGE_SIZE)
+#define NET_RX_RING_SIZE __CONST_RING_SIZE(xen_netif_rx, XEN_PAGE_SIZE)
 
 /* Minimum number of Rx slots (includes slot for GSO metadata). */
 #define NET_RX_SLOTS_MIN (XEN_NETIF_NR_SLOTS_MIN + 1)
@@ -291,7 +291,7 @@ static void xennet_alloc_rx_buffers(struct netfront_queue *queue)
 		struct sk_buff *skb;
 		unsigned short id;
 		grant_ref_t ref;
-		unsigned long gfn;
+		struct page *page;
 		struct xen_netif_rx_request *req;
 
 		skb = xennet_alloc_one_rx_buffer(queue);
@@ -307,14 +307,13 @@ static void xennet_alloc_rx_buffers(struct netfront_queue *queue)
 		BUG_ON((signed short)ref < 0);
 		queue->grant_rx_ref[id] = ref;
 
-		gfn = xen_page_to_gfn(skb_frag_page(&skb_shinfo(skb)->frags[0]));
+		page = skb_frag_page(&skb_shinfo(skb)->frags[0]);
 
 		req = RING_GET_REQUEST(&queue->rx, req_prod);
-		gnttab_grant_foreign_access_ref(ref,
-						queue->info->xbdev->otherend_id,
-						gfn,
-						0);
-
+		gnttab_page_grant_foreign_access_ref_one(ref,
+							 queue->info->xbdev->otherend_id,
+							 page,
+							 0);
 		req->id = id;
 		req->gref = ref;
 	}
@@ -415,25 +414,33 @@ static void xennet_tx_buf_gc(struct netfront_queue *queue)
 	xennet_maybe_wake_tx(queue);
 }
 
-static struct xen_netif_tx_request *xennet_make_one_txreq(
-	struct netfront_queue *queue, struct sk_buff *skb,
-	struct page *page, unsigned int offset, unsigned int len)
+struct xennet_gnttab_make_txreq {
+	struct netfront_queue *queue;
+	struct sk_buff *skb;
+	struct page *page;
+	struct xen_netif_tx_request *tx; /* Last request */
+	unsigned int size;
+};
+
+static void xennet_tx_setup_grant(unsigned long gfn, unsigned int offset,
+				  unsigned int len, void *data)
 {
+	struct xennet_gnttab_make_txreq *info = data;
 	unsigned int id;
 	struct xen_netif_tx_request *tx;
 	grant_ref_t ref;
-
-	len = min_t(unsigned int, PAGE_SIZE - offset, len);
+	/* convenient aliases */
+	struct page *page = info->page;
+	struct netfront_queue *queue = info->queue;
+	struct sk_buff *skb = info->skb;
 
 	id = get_id_from_freelist(&queue->tx_skb_freelist, queue->tx_skbs);
 	tx = RING_GET_REQUEST(&queue->tx, queue->tx.req_prod_pvt++);
 	ref = gnttab_claim_grant_reference(&queue->gref_tx_head);
 	BUG_ON((signed short)ref < 0);
 
-	gnttab_grant_foreign_access_ref(ref,
-					queue->info->xbdev->otherend_id,
-					xen_page_to_gfn(page),
-					GNTMAP_readonly);
+	gnttab_grant_foreign_access_ref(ref, queue->info->xbdev->otherend_id,
+					gfn, GNTMAP_readonly);
 
 	queue->tx_skbs[id].skb = skb;
 	queue->grant_tx_page[id] = page;
@@ -445,7 +452,34 @@ static struct xen_netif_tx_request *xennet_make_one_txreq(
 	tx->size = len;
 	tx->flags = 0;
 
-	return tx;
+	info->tx = tx;
+	info->size += tx->size;
+}
+
+static struct xen_netif_tx_request *xennet_make_first_txreq(
+	struct netfront_queue *queue, struct sk_buff *skb,
+	struct page *page, unsigned int offset, unsigned int len)
+{
+	struct xennet_gnttab_make_txreq info = {
+		.queue = queue,
+		.skb = skb,
+		.page = page,
+		.size = 0,
+	};
+
+	gnttab_one_grant(page, offset, len, xennet_tx_setup_grant, &info);
+
+	return info.tx;
+}
+
+static void xennet_make_one_txreq(unsigned long gfn, unsigned int offset,
+				  unsigned int len, void *data)
+{
+	struct xennet_gnttab_make_txreq *info = data;
+
+	info->tx->flags |= XEN_NETTXF_more_data;
+	skb_get(info->skb);
+	xennet_tx_setup_grant(gfn, offset, len, data);
 }
 
 static struct xen_netif_tx_request *xennet_make_txreqs(
@@ -453,20 +487,30 @@ static struct xen_netif_tx_request *xennet_make_txreqs(
 	struct sk_buff *skb, struct page *page,
 	unsigned int offset, unsigned int len)
 {
+	struct xennet_gnttab_make_txreq info = {
+		.queue = queue,
+		.skb = skb,
+		.tx = tx,
+	};
+
 	/* Skip unused frames from start of page */
 	page += offset >> PAGE_SHIFT;
 	offset &= ~PAGE_MASK;
 
 	while (len) {
-		tx->flags |= XEN_NETTXF_more_data;
-		tx = xennet_make_one_txreq(queue, skb_get(skb),
-					   page, offset, len);
+		info.page = page;
+		info.size = 0;
+
+		gnttab_foreach_grant_in_range(page, offset, len,
+					      xennet_make_one_txreq,
+					      &info);
+
 		page++;
 		offset = 0;
-		len -= tx->size;
+		len -= info.size;
 	}
 
-	return tx;
+	return info.tx;
 }
 
 /*
@@ -476,9 +520,10 @@ static struct xen_netif_tx_request *xennet_make_txreqs(
 static int xennet_count_skb_slots(struct sk_buff *skb)
 {
 	int i, frags = skb_shinfo(skb)->nr_frags;
-	int pages;
+	int slots;
 
-	pages = PFN_UP(offset_in_page(skb->data) + skb_headlen(skb));
+	slots = gnttab_count_grant(offset_in_page(skb->data),
+				   skb_headlen(skb));
 
 	for (i = 0; i < frags; i++) {
 		skb_frag_t *frag = skb_shinfo(skb)->frags + i;
@@ -488,10 +533,10 @@ static int xennet_count_skb_slots(struct sk_buff *skb)
 		/* Skip unused frames from start of page */
 		offset &= ~PAGE_MASK;
 
-		pages += PFN_UP(offset + size);
+		slots += gnttab_count_grant(offset, size);
 	}
 
-	return pages;
+	return slots;
 }
 
 static u16 xennet_select_queue(struct net_device *dev, struct sk_buff *skb,
@@ -512,6 +557,8 @@ static u16 xennet_select_queue(struct net_device *dev, struct sk_buff *skb,
 	return queue_idx;
 }
 
+#define MAX_XEN_SKB_FRAGS (65536 / XEN_PAGE_SIZE + 1)
+
 static int xennet_start_xmit(struct sk_buff *skb, struct net_device *dev)
 {
 	struct netfront_info *np = netdev_priv(dev);
@@ -546,7 +593,7 @@ static int xennet_start_xmit(struct sk_buff *skb, struct net_device *dev)
 	}
 
 	slots = xennet_count_skb_slots(skb);
-	if (unlikely(slots > MAX_SKB_FRAGS + 1)) {
+	if (unlikely(slots > MAX_XEN_SKB_FRAGS + 1)) {
 		net_dbg_ratelimited("xennet: skb rides the rocket: %d slots, %d bytes\n",
 				    slots, skb->len);
 		if (skb_linearize(skb))
@@ -567,10 +614,13 @@ static int xennet_start_xmit(struct sk_buff *skb, struct net_device *dev)
 	}
 
 	/* First request for the linear area. */
-	first_tx = tx = xennet_make_one_txreq(queue, skb,
-					      page, offset, len);
-	page++;
-	offset = 0;
+	first_tx = tx = xennet_make_first_txreq(queue, skb,
+						page, offset, len);
+	offset += tx->size;
+	if (offset == PAGE_SIZE) {
+		page++;
+		offset = 0;
+	}
 	len -= tx->size;
 
 	if (skb->ip_summed == CHECKSUM_PARTIAL)
@@ -732,7 +782,7 @@ static int xennet_get_responses(struct netfront_queue *queue,
 
 	for (;;) {
 		if (unlikely(rx->status < 0 ||
-			     rx->offset + rx->status > PAGE_SIZE)) {
+			     rx->offset + rx->status > XEN_PAGE_SIZE)) {
 			if (net_ratelimit())
 				dev_warn(dev, "rx->offset: %u, size: %d\n",
 					 rx->offset, rx->status);
@@ -1495,7 +1545,7 @@ static int setup_netfront(struct xenbus_device *dev,
 		goto fail;
 	}
 	SHARED_RING_INIT(txs);
-	FRONT_RING_INIT(&queue->tx, txs, PAGE_SIZE);
+	FRONT_RING_INIT(&queue->tx, txs, XEN_PAGE_SIZE);
 
 	err = xenbus_grant_ring(dev, txs, 1, &gref);
 	if (err < 0)
@@ -1509,7 +1559,7 @@ static int setup_netfront(struct xenbus_device *dev,
 		goto alloc_rx_ring_fail;
 	}
 	SHARED_RING_INIT(rxs);
-	FRONT_RING_INIT(&queue->rx, rxs, PAGE_SIZE);
+	FRONT_RING_INIT(&queue->rx, rxs, XEN_PAGE_SIZE);
 
 	err = xenbus_grant_ring(dev, rxs, 1, &gref);
 	if (err < 0)
-- 
2.1.4



From julien.grall at citrix.com  Fri Aug  7 09:46:59 2015
From: julien.grall at citrix.com (Julien Grall)
Date: Fri, 7 Aug 2015 17:46:59 +0100
Subject: [PATCH v3 20/20] arm/xen: Add support for 64KB page granularity
In-Reply-To: <1438966019-19322-1-git-send-email-julien.grall@citrix.com>
References: <1438966019-19322-1-git-send-email-julien.grall@citrix.com>
Message-ID: <1438966019-19322-21-git-send-email-julien.grall@citrix.com>

The hypercall interface is always using 4KB page granularity. This is
requiring to use xen page definition macro when we deal with hypercall.

Note that pfn_to_gfn is working with a Xen pfn (i.e 4KB). We may want to
rename pfn_gfn to make this explicit.

We also allocate a 64KB page for the shared page even though only the
first 4KB is used. I don't think this is really important for now as it
helps to have the pointer 4KB aligned (XENMEM_add_to_physmap is taking a
Xen PFN).

Signed-off-by: Julien Grall <julien.grall at citrix.com>

---
Cc: Stefano Stabellini <stefano.stabellini at eu.citrix.com>
Cc: Russell King <linux at arm.linux.org.uk>

Stefano, I've dropped your reviewed-by given I've updated the doc and do
changes to avoid usage of XEN_PAGE_SHIFT

    Changes in v3:
        - s/MFN/GFN/ base on the new naming
        - Use virt_to_gfn to avoid use XEN_PAGE_SHIFT
        - Drop Stefano's reviewed-by
        - Add some docs in arch/arm/asm/xen/page.h

    Changes in v2
        - Add Stefano's reviewed-by
---
 arch/arm/include/asm/xen/page.h | 15 +++++++++++++--
 arch/arm/xen/enlighten.c        |  6 +++---
 2 files changed, 16 insertions(+), 5 deletions(-)

diff --git a/arch/arm/include/asm/xen/page.h b/arch/arm/include/asm/xen/page.h
index 98c9fc3..e3d94cf 100644
--- a/arch/arm/include/asm/xen/page.h
+++ b/arch/arm/include/asm/xen/page.h
@@ -28,6 +28,17 @@ typedef struct xpaddr {
 
 #define INVALID_P2M_ENTRY      (~0UL)
 
+/*
+ * The pseudo-physical frame (pfn) used in all the helpers is always based
+ * on Xen page granularity (i.e 4KB).
+ *
+ * A Linux page may be split across multiple non-contiguous Xen page so we
+ * have to keep track with frame based on 4KB page granularity.
+ *
+ * PV drivers should never make a direct usage of those helpers (particularly
+ * pfn_to_gfn and gfn_to_pfn).
+ */
+
 unsigned long __pfn_to_mfn(unsigned long pfn);
 extern struct rb_root phys_to_mach;
 
@@ -64,8 +75,8 @@ static inline unsigned long bfn_to_pfn(unsigned long bfn)
 #define bfn_to_local_pfn(bfn)	bfn_to_pfn(bfn)
 
 /* VIRT <-> GUEST conversion */
-#define virt_to_gfn(v)		(pfn_to_gfn(virt_to_pfn(v)))
-#define gfn_to_virt(m)		(__va(gfn_to_pfn(m) << PAGE_SHIFT))
+#define virt_to_gfn(v)		(pfn_to_gfn(virt_to_phys(v) >> XEN_PAGE_SHIFT))
+#define gfn_to_virt(m)		(__va(gfn_to_pfn(m) << XEN_PAGE_SHIFT))
 
 /* Only used in PV code. But ARM guests are always HVM. */
 static inline xmaddr_t arbitrary_virt_to_machine(void *vaddr)
diff --git a/arch/arm/xen/enlighten.c b/arch/arm/xen/enlighten.c
index eeeab07..50b4769 100644
--- a/arch/arm/xen/enlighten.c
+++ b/arch/arm/xen/enlighten.c
@@ -89,8 +89,8 @@ static void xen_percpu_init(void)
 	pr_info("Xen: initializing cpu%d\n", cpu);
 	vcpup = per_cpu_ptr(xen_vcpu_info, cpu);
 
-	info.mfn = __pa(vcpup) >> PAGE_SHIFT;
-	info.offset = offset_in_page(vcpup);
+	info.mfn = virt_to_gfn(vcpup);
+	info.offset = xen_offset_in_page(vcpup);
 
 	err = HYPERVISOR_vcpu_op(VCPUOP_register_vcpu_info, cpu, &info);
 	BUG_ON(err);
@@ -213,7 +213,7 @@ static int __init xen_guest_init(void)
 	xatp.domid = DOMID_SELF;
 	xatp.idx = 0;
 	xatp.space = XENMAPSPACE_shared_info;
-	xatp.gpfn = __pa(shared_info_page) >> PAGE_SHIFT;
+	xatp.gpfn = virt_to_gfn(shared_info_page);
 	if (HYPERVISOR_memory_op(XENMEM_add_to_physmap, &xatp))
 		BUG();
 
-- 
2.1.4



From julien.grall at citrix.com  Fri Aug  7 09:46:55 2015
From: julien.grall at citrix.com (Julien Grall)
Date: Fri, 7 Aug 2015 17:46:55 +0100
Subject: [PATCH v3 16/20] block/xen-blkback: Make it running on 64KB page
 granularity
In-Reply-To: <1438966019-19322-1-git-send-email-julien.grall@citrix.com>
References: <1438966019-19322-1-git-send-email-julien.grall@citrix.com>
Message-ID: <1438966019-19322-17-git-send-email-julien.grall@citrix.com>

The PV block protocol is using 4KB page granularity. The goal of this
patch is to allow a Linux using 64KB page granularity behaving as a
block backend on a non-modified Xen.

It's only necessary to adapt the ring size and the number of request per
indirect frames. The rest of the code is relying on the grant table
code.

Note that the grant table code is allocating a Linux page per grant
which will result to waste 6OKB for every grant when Linux is using 64KB
page granularity. This could be improved by sharing the page between
multiple grants.

Signed-off-by: Julien Grall <julien.grall at citrix.com>
---

Cc: Konrad Rzeszutek Wilk <konrad.wilk at oracle.com>
Cc: "Roger Pau Monn?" <roger.pau at citrix.com>
Cc: Boris Ostrovsky <boris.ostrovsky at oracle.com>
Cc: David Vrabel <david.vrabel at citrix.com>

Improvement such as support of 64KB grant is not taken into
consideration in this patch because we have the requirement to run a
Linux using 64KB pages on a non-modified Xen.

This has been tested only with a loop device. I plan to test passing
hard drive partition but I didn't yet convert the swiotlb code.

    Changes in v3:
        - Use DIV_ROUND_UP in INDIRECT_PAGES to avoid a line over 80
        characters
---
 drivers/block/xen-blkback/blkback.c |  5 +++--
 drivers/block/xen-blkback/common.h  | 17 +++++++++++++----
 drivers/block/xen-blkback/xenbus.c  |  9 ++++++---
 3 files changed, 22 insertions(+), 9 deletions(-)

diff --git a/drivers/block/xen-blkback/blkback.c b/drivers/block/xen-blkback/blkback.c
index ced9677..d5cce8c 100644
--- a/drivers/block/xen-blkback/blkback.c
+++ b/drivers/block/xen-blkback/blkback.c
@@ -961,7 +961,7 @@ static int xen_blkbk_parse_indirect(struct blkif_request *req,
 		seg[n].nsec = segments[i].last_sect -
 			segments[i].first_sect + 1;
 		seg[n].offset = (segments[i].first_sect << 9);
-		if ((segments[i].last_sect >= (PAGE_SIZE >> 9)) ||
+		if ((segments[i].last_sect >= (XEN_PAGE_SIZE >> 9)) ||
 		    (segments[i].last_sect < segments[i].first_sect)) {
 			rc = -EINVAL;
 			goto unmap;
@@ -1210,6 +1210,7 @@ static int dispatch_rw_block_io(struct xen_blkif *blkif,
 
 	req_operation = req->operation == BLKIF_OP_INDIRECT ?
 			req->u.indirect.indirect_op : req->operation;
+
 	if ((req->operation == BLKIF_OP_INDIRECT) &&
 	    (req_operation != BLKIF_OP_READ) &&
 	    (req_operation != BLKIF_OP_WRITE)) {
@@ -1268,7 +1269,7 @@ static int dispatch_rw_block_io(struct xen_blkif *blkif,
 			seg[i].nsec = req->u.rw.seg[i].last_sect -
 				req->u.rw.seg[i].first_sect + 1;
 			seg[i].offset = (req->u.rw.seg[i].first_sect << 9);
-			if ((req->u.rw.seg[i].last_sect >= (PAGE_SIZE >> 9)) ||
+			if ((req->u.rw.seg[i].last_sect >= (XEN_PAGE_SIZE >> 9)) ||
 			    (req->u.rw.seg[i].last_sect <
 			     req->u.rw.seg[i].first_sect))
 				goto fail_response;
diff --git a/drivers/block/xen-blkback/common.h b/drivers/block/xen-blkback/common.h
index 45a044a..68e87a0 100644
--- a/drivers/block/xen-blkback/common.h
+++ b/drivers/block/xen-blkback/common.h
@@ -39,6 +39,7 @@
 #include <asm/pgalloc.h>
 #include <asm/hypervisor.h>
 #include <xen/grant_table.h>
+#include <xen/page.h>
 #include <xen/xenbus.h>
 #include <xen/interface/io/ring.h>
 #include <xen/interface/io/blkif.h>
@@ -51,12 +52,20 @@ extern unsigned int xen_blkif_max_ring_order;
  */
 #define MAX_INDIRECT_SEGMENTS 256
 
-#define SEGS_PER_INDIRECT_FRAME \
-	(PAGE_SIZE/sizeof(struct blkif_request_segment))
+/*
+ * Xen use 4K pages. The guest may use different page size (4K or 64K)
+ * Number of Xen pages per segment
+ */
+#define XEN_PAGES_PER_SEGMENT   (PAGE_SIZE / XEN_PAGE_SIZE)
+
+#define XEN_PAGES_PER_INDIRECT_FRAME \
+	(XEN_PAGE_SIZE/sizeof(struct blkif_request_segment))
+#define SEGS_PER_INDIRECT_FRAME	\
+	(XEN_PAGES_PER_INDIRECT_FRAME / XEN_PAGES_PER_SEGMENT)
+
 #define MAX_INDIRECT_PAGES \
 	((MAX_INDIRECT_SEGMENTS + SEGS_PER_INDIRECT_FRAME - 1)/SEGS_PER_INDIRECT_FRAME)
-#define INDIRECT_PAGES(_segs) \
-	((_segs + SEGS_PER_INDIRECT_FRAME - 1)/SEGS_PER_INDIRECT_FRAME)
+#define INDIRECT_PAGES(_segs) DIV_ROUND_UP(_segs, XEN_PAGES_PER_INDIRECT_FRAME)
 
 /* Not a real protocol.  Used to generate ring structs which contain
  * the elements common to all protocols only.  This way we get a
diff --git a/drivers/block/xen-blkback/xenbus.c b/drivers/block/xen-blkback/xenbus.c
index deb3f00..edd27e4 100644
--- a/drivers/block/xen-blkback/xenbus.c
+++ b/drivers/block/xen-blkback/xenbus.c
@@ -176,21 +176,24 @@ static int xen_blkif_map(struct xen_blkif *blkif, grant_ref_t *gref,
 	{
 		struct blkif_sring *sring;
 		sring = (struct blkif_sring *)blkif->blk_ring;
-		BACK_RING_INIT(&blkif->blk_rings.native, sring, PAGE_SIZE * nr_grefs);
+		BACK_RING_INIT(&blkif->blk_rings.native, sring,
+			       XEN_PAGE_SIZE * nr_grefs);
 		break;
 	}
 	case BLKIF_PROTOCOL_X86_32:
 	{
 		struct blkif_x86_32_sring *sring_x86_32;
 		sring_x86_32 = (struct blkif_x86_32_sring *)blkif->blk_ring;
-		BACK_RING_INIT(&blkif->blk_rings.x86_32, sring_x86_32, PAGE_SIZE * nr_grefs);
+		BACK_RING_INIT(&blkif->blk_rings.x86_32, sring_x86_32,
+			       XEN_PAGE_SIZE * nr_grefs);
 		break;
 	}
 	case BLKIF_PROTOCOL_X86_64:
 	{
 		struct blkif_x86_64_sring *sring_x86_64;
 		sring_x86_64 = (struct blkif_x86_64_sring *)blkif->blk_ring;
-		BACK_RING_INIT(&blkif->blk_rings.x86_64, sring_x86_64, PAGE_SIZE * nr_grefs);
+		BACK_RING_INIT(&blkif->blk_rings.x86_64, sring_x86_64,
+			       XEN_PAGE_SIZE * nr_grefs);
 		break;
 	}
 	default:
-- 
2.1.4



From festevam at gmail.com  Fri Aug  7 10:16:12 2015
From: festevam at gmail.com (Fabio Estevam)
Date: Fri, 7 Aug 2015 14:16:12 -0300
Subject: could not get clock /usdhc1_pwrseq:ext_clock(0)
Message-ID: <CAOMZO5BFSBjLNDuEVrdANU9Og1tttawp=a3vLCKFBJok95=r0g@mail.gmail.com>

Hi,

When booting linux-next 20150807 on a imx6q-cuboxi I see the following
error coming from __of_clk_get_by_name():

[    1.674167] ERROR: could not get clock /usdhc1_pwrseq:ext_clock(0)

The ext_clock clock is passed in the imx6qdl-microsom.dtsi:

    usdhc1_pwrseq: usdhc1_pwrseq {
        compatible = "mmc-pwrseq-simple";
        reset-gpios = <&gpio5 26 GPIO_ACTIVE_LOW>,
                  <&gpio6 0 GPIO_ACTIVE_LOW>;
        clocks = <&clk_sdio>;
        clock-names = "ext_clock";
    };

, where:

    clk_sdio: sdio-clock{
        compatible = "gpio-gate-clock";
        #clock-cells = <0>;
        pinctrl-names = "default";
        pinctrl-0 = <&pinctrl_microsom_brcm_osc>;
        enable-gpios = <&gpio5 5 GPIO_ACTIVE_HIGH>;
    };

This used to work earlier, but I haven't bisected it yet.

Does anyone have an idea as to why __of_clk_get_by_name() fail in this case?

Thanks,

Fabio Estevam


From fainelli at broadcom.com  Fri Aug  7 10:20:08 2015
From: fainelli at broadcom.com (Florian Fainelli)
Date: Fri, 7 Aug 2015 10:20:08 -0700
Subject: [GIT PULL] Broadcom SoC changes for 4.3 (part 2)
In-Reply-To: <1438796683-18581-3-git-send-email-f.fainelli@gmail.com>
References: <1438796683-18581-1-git-send-email-f.fainelli@gmail.com>
 <1438796683-18581-3-git-send-email-f.fainelli@gmail.com>
Message-ID: <55C4E8C8.7030503@broadcom.com>

Arnd, Kevin, Olof,

Can you drop this pull request, or if you already merged it, there will
be a second one for a single patch coming in shortly. Thank you!

On 05/08/15 10:44, Florian Fainelli wrote:
> The following changes since commit 39aa437e18cac7acae55481ed73feea0de497399:
> 
>   Merge branch 'queue/irq/arm' of git://git.kernel.org/pub/scm/linux/kernel/git/tip/tip into next/cleanup (2015-08-05 17:24:11 +0200)
> 
> are available in the git repository at:
> 
>   http://github.com/broadcom/stblinux tags/arm-soc/for-4.3/soc-part2
> 
> for you to fetch changes up to 661e59d30168331e5e1c7386d23ea8fd14965270:
> 
>   ARM: BCM: Enable ARM erratum 798181 for BRCMSTB (2015-08-05 10:30:59 -0700)
> 
> ----------------------------------------------------------------
> This pull request contains the following changes:
> 
> - Gregory updates the BRCMSTB Kconfig to select the ARM erratum 798181 which
>   affects the chips covered by this platform
> 
> ----------------------------------------------------------------
> Gregory Fong (1):
>       ARM: BCM: Enable ARM erratum 798181 for BRCMSTB
> 
>  arch/arm/mach-bcm/Kconfig | 1 +
>  1 file changed, 1 insertion(+)
> 


-- 
Florian


From agross at codeaurora.org  Fri Aug  7 10:30:31 2015
From: agross at codeaurora.org (Andy Gross)
Date: Fri, 7 Aug 2015 12:30:31 -0500
Subject: next-20150807 build: 2 failures 51 warnings (next-20150807)
In-Reply-To: <20150807122344.GT20873@sirena.org.uk>
References: <E1ZNgYS-0000SE-QL@optimist> <20150807122344.GT20873@sirena.org.uk>
Message-ID: <20150807173031.GA25070@qualcomm.com>

On Fri, Aug 07, 2015 at 01:23:44PM +0100, Mark Brown wrote:
> On Fri, Aug 07, 2015 at 01:15:20PM +0100, Build bot for Mark Brown wrote:
> 
> Today's linux-next fails to build an arm64 allmodconfig with:
> 
> > 	arm64-allmodconfig
> > ../drivers/firmware/qcom_scm-32.c:27:28: fatal error: asm/outercache.h: No such file or directory
> 
> This header file only exists on ARM, either the driver shouldn't be
> built for ARMv8, we need a dummy header for ARMv8 or we need to use the
> header conditionally in the driver.

Right.  We're right in the middle of pulling together SCM for 64 bit.  I think
for now, perhaps I should just send in a stubbed out placeholder for ARMV8 SCM
and then fill it in once we get that patch set reworked (previously sent by
Kumar Gala).

I'll add that to my branch today and it should resolve our next builds.  I'll
send it to arm/soc in a fixes pull request.

-- 
Qualcomm Innovation Center, Inc.
The Qualcomm Innovation Center, Inc. is a member of the Code Aurora Forum,
a Linux Foundation Collaborative Project



From ddaney at caviumnetworks.com  Fri Aug  7 10:37:10 2015
From: ddaney at caviumnetworks.com (David Daney)
Date: Fri, 7 Aug 2015 10:37:10 -0700
Subject: [PATCH 2/2] net, thunder, bgx: Add support for ACPI binding.
In-Reply-To: <20150807140106.GE7646@leverpostej>
References: <1438907590-29649-1-git-send-email-ddaney.cavm@gmail.com>
 <1438907590-29649-3-git-send-email-ddaney.cavm@gmail.com>
 <20150807140106.GE7646@leverpostej>
Message-ID: <55C4ECC6.7050908@caviumnetworks.com>

On 08/07/2015 07:01 AM, Mark Rutland wrote:
> On Fri, Aug 07, 2015 at 01:33:10AM +0100, David Daney wrote:
>> From: David Daney <david.daney at cavium.com>
>>
>> Find out which PHYs belong to which BGX instance in the ACPI way.
>>
>> Set the MAC address of the device as provided by ACPI tables. This is
>> similar to the implementation for devicetree in
>> of_get_mac_address(). The table is searched for the device property
>> entries "mac-address", "local-mac-address" and "address" in that
>> order. The address is provided in a u64 variable and must contain a
>> valid 6 bytes-len mac addr.
>>
>> Based on code from: Narinder Dhillon <ndhillon at cavium.com>
>>                      Tomasz Nowicki <tomasz.nowicki at linaro.org>
>>                      Robert Richter <rrichter at cavium.com>
>>
>> Signed-off-by: Tomasz Nowicki <tomasz.nowicki at linaro.org>
>> Signed-off-by: Robert Richter <rrichter at cavium.com>
>> Signed-off-by: David Daney <david.daney at cavium.com>
>> ---
>>   drivers/net/ethernet/cavium/thunder/thunder_bgx.c | 137 +++++++++++++++++++++-
>>   1 file changed, 135 insertions(+), 2 deletions(-)
>>
>> diff --git a/drivers/net/ethernet/cavium/thunder/thunder_bgx.c b/drivers/net/ethernet/cavium/thunder/thunder_bgx.c
>> index 615b2af..2056583 100644
>> --- a/drivers/net/ethernet/cavium/thunder/thunder_bgx.c
>> +++ b/drivers/net/ethernet/cavium/thunder/thunder_bgx.c
>> @@ -6,6 +6,7 @@
>>    * as published by the Free Software Foundation.
>>    */
>>
>> +#include <linux/acpi.h>
>>   #include <linux/module.h>
>>   #include <linux/interrupt.h>
>>   #include <linux/pci.h>
>> @@ -26,7 +27,7 @@
>>   struct lmac {
>>   	struct bgx		*bgx;
>>   	int			dmac;
>> -	unsigned char		mac[ETH_ALEN];
>> +	u8			mac[ETH_ALEN];
>>   	bool			link_up;
>>   	int			lmacid; /* ID within BGX */
>>   	int			lmacid_bd; /* ID on board */
>> @@ -835,6 +836,133 @@ static void bgx_get_qlm_mode(struct bgx *bgx)
>>   	}
>>   }
>>
>> +#ifdef CONFIG_ACPI
>> +
>> +static int bgx_match_phy_id(struct device *dev, void *data)
>> +{
>> +	struct phy_device *phydev = to_phy_device(dev);
>> +	u32 *phy_id = data;
>> +
>> +	if (phydev->addr == *phy_id)
>> +		return 1;
>> +
>> +	return 0;
>> +}
>> +
>> +static const char * const addr_propnames[] = {
>> +	"mac-address",
>> +	"local-mac-address",
>> +	"address",
>> +};
>
> If these are going to be generally necessary, then we should get them
> adopted as standardised _DSD properties (ideally just one of them).

As far as I can tell, and please correct me if I am wrong, ACPI-6.0 
doesn't contemplate MAC addresses.

Today we are using "mac-address", which is an Integer containing the MAC 
address in its lowest order 48 bits in Little-Endian byte order.

The hardware and ACPI tables are here today, and we would like to 
support it.  If some future ACPI specification specifies a standard way 
to do this, we will probably adapt the code to do this in a standard manner.


>
> [...]
>
>> +static acpi_status bgx_acpi_register_phy(acpi_handle handle,
>> +					 u32 lvl, void *context, void **rv)
>> +{
>> +	struct acpi_reference_args args;
>> +	const union acpi_object *prop;
>> +	struct bgx *bgx = context;
>> +	struct acpi_device *adev;
>> +	struct device *phy_dev;
>> +	u32 phy_id;
>> +
>> +	if (acpi_bus_get_device(handle, &adev))
>> +		goto out;
>> +
>> +	SET_NETDEV_DEV(&bgx->lmac[bgx->lmac_count].netdev, &bgx->pdev->dev);
>> +
>> +	acpi_get_mac_address(adev, bgx->lmac[bgx->lmac_count].mac);
>> +
>> +	bgx->lmac[bgx->lmac_count].lmacid = bgx->lmac_count;
>> +
>> +	if (acpi_dev_get_property_reference(adev, "phy-handle", 0, &args))
>> +		goto out;
>> +
>> +	if (acpi_dev_get_property(args.adev, "phy-channel", ACPI_TYPE_INTEGER, &prop))
>> +		goto out;
>
> Likewise for any inter-device properties, so that we can actually handle
> them in a generic fashion, and avoid / learn from the mistakes we've
> already handled with DT.

This is the fallacy of the ACPI is superior to DT argument.  The 
specification of PHY topology and MAC addresses is well standardized in 
DT, there is no question about what the proper way to specify it is. 
Under ACPI, it is the Wild West, there is no specification, so each 
system design is forced to invent something, and everybody comes up with 
an incompatible implementation.

That said, this is all specific to our BGX device, so anything we do 
doesn't break other devices.

David Daney




From mark.rutland at arm.com  Fri Aug  7 10:51:27 2015
From: mark.rutland at arm.com (Mark Rutland)
Date: Fri, 7 Aug 2015 18:51:27 +0100
Subject: [PATCH 2/2] net, thunder, bgx: Add support for ACPI binding.
In-Reply-To: <55C4ECC6.7050908@caviumnetworks.com>
References: <1438907590-29649-1-git-send-email-ddaney.cavm@gmail.com>
 <1438907590-29649-3-git-send-email-ddaney.cavm@gmail.com>
 <20150807140106.GE7646@leverpostej>
 <55C4ECC6.7050908@caviumnetworks.com>
Message-ID: <20150807175127.GB12013@leverpostej>

[Correcting the devicetree list address, which I typo'd in my original
reply]

> >> +static const char * const addr_propnames[] = {
> >> +	"mac-address",
> >> +	"local-mac-address",
> >> +	"address",
> >> +};
> >
> > If these are going to be generally necessary, then we should get them
> > adopted as standardised _DSD properties (ideally just one of them).
> 
> As far as I can tell, and please correct me if I am wrong, ACPI-6.0 
> doesn't contemplate MAC addresses.
> 
> Today we are using "mac-address", which is an Integer containing the MAC 
> address in its lowest order 48 bits in Little-Endian byte order.
> 
> The hardware and ACPI tables are here today, and we would like to 
> support it.  If some future ACPI specification specifies a standard way 
> to do this, we will probably adapt the code to do this in a standard manner.
> 
> 
> >
> > [...]
> >
> >> +static acpi_status bgx_acpi_register_phy(acpi_handle handle,
> >> +					 u32 lvl, void *context, void **rv)
> >> +{
> >> +	struct acpi_reference_args args;
> >> +	const union acpi_object *prop;
> >> +	struct bgx *bgx = context;
> >> +	struct acpi_device *adev;
> >> +	struct device *phy_dev;
> >> +	u32 phy_id;
> >> +
> >> +	if (acpi_bus_get_device(handle, &adev))
> >> +		goto out;
> >> +
> >> +	SET_NETDEV_DEV(&bgx->lmac[bgx->lmac_count].netdev, &bgx->pdev->dev);
> >> +
> >> +	acpi_get_mac_address(adev, bgx->lmac[bgx->lmac_count].mac);
> >> +
> >> +	bgx->lmac[bgx->lmac_count].lmacid = bgx->lmac_count;
> >> +
> >> +	if (acpi_dev_get_property_reference(adev, "phy-handle", 0, &args))
> >> +		goto out;
> >> +
> >> +	if (acpi_dev_get_property(args.adev, "phy-channel", ACPI_TYPE_INTEGER, &prop))
> >> +		goto out;
> >
> > Likewise for any inter-device properties, so that we can actually handle
> > them in a generic fashion, and avoid / learn from the mistakes we've
> > already handled with DT.
> 
> This is the fallacy of the ACPI is superior to DT argument.  The 
> specification of PHY topology and MAC addresses is well standardized in 
> DT, there is no question about what the proper way to specify it is. 
> Under ACPI, it is the Wild West, there is no specification, so each 
> system design is forced to invent something, and everybody comes up with 
> an incompatible implementation.

Indeed.

If ACPI is going to handle it, it should handle it properly. I really
don't see the point in bodging properties together in a less standard
manner than DT, especially for inter-device relationships.

Doing so is painful for _everyone_, and it's extremely unlikely that
other ACPI-aware OSs will actually support these custom descriptions,
making this Linux-specific, and breaking the rationale for using ACPI in
the first place -- a standard that says "just do non-standard stuff" is
not a usable standard.

For intra-device properties, we should standardise what we can, but
vendor-specific stuff is ok -- this can be self-contained within a
driver.

For inter-device relationships ACPI _must_ gain a better model of
componentised devices. It's simply unworkable otherwise, and as you
point out it's fallacious to say that because ACPI is being used that
something is magically industry standard, portable, etc.

This is not your problem in particular; the entire handling of _DSD so
far is a joke IMO.

Thanks,
Mark.


From mark.rutland at arm.com  Fri Aug  7 10:53:53 2015
From: mark.rutland at arm.com (Mark Rutland)
Date: Fri, 7 Aug 2015 18:53:53 +0100
Subject: [PATCH 2/2] net, thunder, bgx: Add support for ACPI binding.
In-Reply-To: <55C4ECC6.7050908@caviumnetworks.com>
References: <1438907590-29649-1-git-send-email-ddaney.cavm@gmail.com>
 <1438907590-29649-3-git-send-email-ddaney.cavm@gmail.com>
 <20150807140106.GE7646@leverpostej>
 <55C4ECC6.7050908@caviumnetworks.com>
Message-ID: <20150807175353.GA31122@leverpostej>

[Correcting the devicetree list address, which I typo'd in my original
reply]

[resending to _really_ correct the address, apologies for the spam]

> >> +static const char * const addr_propnames[] = {
> >> +	"mac-address",
> >> +	"local-mac-address",
> >> +	"address",
> >> +};
> >
> > If these are going to be generally necessary, then we should get them
> > adopted as standardised _DSD properties (ideally just one of them).
> 
> As far as I can tell, and please correct me if I am wrong, ACPI-6.0 
> doesn't contemplate MAC addresses.
> 
> Today we are using "mac-address", which is an Integer containing the MAC 
> address in its lowest order 48 bits in Little-Endian byte order.
> 
> The hardware and ACPI tables are here today, and we would like to 
> support it.  If some future ACPI specification specifies a standard way 
> to do this, we will probably adapt the code to do this in a standard manner.
> 
> 
> >
> > [...]
> >
> >> +static acpi_status bgx_acpi_register_phy(acpi_handle handle,
> >> +					 u32 lvl, void *context, void **rv)
> >> +{
> >> +	struct acpi_reference_args args;
> >> +	const union acpi_object *prop;
> >> +	struct bgx *bgx = context;
> >> +	struct acpi_device *adev;
> >> +	struct device *phy_dev;
> >> +	u32 phy_id;
> >> +
> >> +	if (acpi_bus_get_device(handle, &adev))
> >> +		goto out;
> >> +
> >> +	SET_NETDEV_DEV(&bgx->lmac[bgx->lmac_count].netdev, &bgx->pdev->dev);
> >> +
> >> +	acpi_get_mac_address(adev, bgx->lmac[bgx->lmac_count].mac);
> >> +
> >> +	bgx->lmac[bgx->lmac_count].lmacid = bgx->lmac_count;
> >> +
> >> +	if (acpi_dev_get_property_reference(adev, "phy-handle", 0, &args))
> >> +		goto out;
> >> +
> >> +	if (acpi_dev_get_property(args.adev, "phy-channel", ACPI_TYPE_INTEGER, &prop))
> >> +		goto out;
> >
> > Likewise for any inter-device properties, so that we can actually handle
> > them in a generic fashion, and avoid / learn from the mistakes we've
> > already handled with DT.
> 
> This is the fallacy of the ACPI is superior to DT argument.  The 
> specification of PHY topology and MAC addresses is well standardized in 
> DT, there is no question about what the proper way to specify it is. 
> Under ACPI, it is the Wild West, there is no specification, so each 
> system design is forced to invent something, and everybody comes up with 
> an incompatible implementation.

Indeed.

If ACPI is going to handle it, it should handle it properly. I really
don't see the point in bodging properties together in a less standard
manner than DT, especially for inter-device relationships.

Doing so is painful for _everyone_, and it's extremely unlikely that
other ACPI-aware OSs will actually support these custom descriptions,
making this Linux-specific, and breaking the rationale for using ACPI in
the first place -- a standard that says "just do non-standard stuff" is
not a usable standard.

For intra-device properties, we should standardise what we can, but
vendor-specific stuff is ok -- this can be self-contained within a
driver.

For inter-device relationships ACPI _must_ gain a better model of
componentised devices. It's simply unworkable otherwise, and as you
point out it's fallacious to say that because ACPI is being used that
something is magically industry standard, portable, etc.

This is not your problem in particular; the entire handling of _DSD so
far is a joke IMO.

Thanks,
Mark.


From ddaney at caviumnetworks.com  Fri Aug  7 11:14:47 2015
From: ddaney at caviumnetworks.com (David Daney)
Date: Fri, 7 Aug 2015 11:14:47 -0700
Subject: [PATCH 2/2] net, thunder, bgx: Add support for ACPI binding.
In-Reply-To: <20150807145414.GA5468@xora-haswell.xora.org.uk>
References: <1438907590-29649-1-git-send-email-ddaney.cavm@gmail.com>
 <1438907590-29649-3-git-send-email-ddaney.cavm@gmail.com>
 <20150807145414.GA5468@xora-haswell.xora.org.uk>
Message-ID: <55C4F597.50103@caviumnetworks.com>

On 08/07/2015 07:54 AM, Graeme Gregory wrote:
> On Thu, Aug 06, 2015 at 05:33:10PM -0700, David Daney wrote:
>> From: David Daney <david.daney at cavium.com>
>>
>> Find out which PHYs belong to which BGX instance in the ACPI way.
>>
>> Set the MAC address of the device as provided by ACPI tables. This is
>> similar to the implementation for devicetree in
>> of_get_mac_address(). The table is searched for the device property
>> entries "mac-address", "local-mac-address" and "address" in that
>> order. The address is provided in a u64 variable and must contain a
>> valid 6 bytes-len mac addr.
>>
>> Based on code from: Narinder Dhillon <ndhillon at cavium.com>
>>                      Tomasz Nowicki <tomasz.nowicki at linaro.org>
>>                      Robert Richter <rrichter at cavium.com>
>>
>> Signed-off-by: Tomasz Nowicki <tomasz.nowicki at linaro.org>
>> Signed-off-by: Robert Richter <rrichter at cavium.com>
>> Signed-off-by: David Daney <david.daney at cavium.com>
>> ---
>>   drivers/net/ethernet/cavium/thunder/thunder_bgx.c | 137 +++++++++++++++++++++-
>>   1 file changed, 135 insertions(+), 2 deletions(-)
>>
>> diff --git a/drivers/net/ethernet/cavium/thunder/thunder_bgx.c b/drivers/net/ethernet/cavium/thunder/thunder_bgx.c
>> index 615b2af..2056583 100644
>> --- a/drivers/net/ethernet/cavium/thunder/thunder_bgx.c
>> +++ b/drivers/net/ethernet/cavium/thunder/thunder_bgx.c
[...]
>> +
>> +static int acpi_get_mac_address(struct acpi_device *adev, u8 *dst)
>> +{
>> +	const union acpi_object *prop;
>> +	u64 mac_val;
>> +	u8 mac[ETH_ALEN];
>> +	int i, j;
>> +	int ret;
>> +
>> +	for (i = 0; i < ARRAY_SIZE(addr_propnames); i++) {
>> +		ret = acpi_dev_get_property(adev, addr_propnames[i],
>> +					    ACPI_TYPE_INTEGER, &prop);
>
> Shouldn't this be trying to use device_property_read_* API and making
> the DT/ACPI path the same where possible?
>

Ideally, something like you suggest would be possible.  However, there 
are a couple of problems trying to do it in the kernel as it exists today:

1) There is no 'struct device *' here, so device_property_read_* is not 
applicable.

2) There is no standard ACPI binding for MAC addresses, so it is 
impossible to create a hypothetical fw_get_mac_address(), which would be 
analogous to of_get_mac_address().

Other e-mail threads have suggested that the path to an elegant solution 
is to inter-mix a bunch of calls to acpi_dev_get_property*() and 
fwnode_property_read*() as to use these more generic 
fwnode_property_read*() functions whereever possible.  I rejected this 
approach as it seems cleaner to me to consistently use a single set of APIs.

Thanks,
David Daney



> Graeme
>
>> +		if (ret)
>> +			continue;
>> +
>> +		mac_val = prop->integer.value;
>> +
>> +		if (mac_val & (~0ULL << 48))
>> +			continue;	/* more than 6 bytes */
>> +
>> +		for (j = 0; j < ARRAY_SIZE(mac); j++)
>> +			mac[j] = (u8)(mac_val >> (8 * j));
>> +		if (!is_valid_ether_addr(mac))
>> +			continue;
>> +
>> +		memcpy(dst, mac, ETH_ALEN);
>> +
>> +		return 0;
>> +	}
>> +
>> +	return ret ? ret : -EINVAL;
>> +}
>> +
>> +static acpi_status bgx_acpi_register_phy(acpi_handle handle,
>> +					 u32 lvl, void *context, void **rv)
>> +{
>> +	struct acpi_reference_args args;
>> +	const union acpi_object *prop;
>> +	struct bgx *bgx = context;
>> +	struct acpi_device *adev;
>> +	struct device *phy_dev;
>> +	u32 phy_id;
>> +
>> +	if (acpi_bus_get_device(handle, &adev))
>> +		goto out;
>> +
>> +	SET_NETDEV_DEV(&bgx->lmac[bgx->lmac_count].netdev, &bgx->pdev->dev);
>> +
>> +	acpi_get_mac_address(adev, bgx->lmac[bgx->lmac_count].mac);
>> +
>> +	bgx->lmac[bgx->lmac_count].lmacid = bgx->lmac_count;
>> +
>> +	if (acpi_dev_get_property_reference(adev, "phy-handle", 0, &args))
>> +		goto out;
>> +
>> +	if (acpi_dev_get_property(args.adev, "phy-channel", ACPI_TYPE_INTEGER, &prop))
>> +		goto out;
>> +
>> +	phy_id = prop->integer.value;
>> +
>> +	phy_dev = bus_find_device(&mdio_bus_type, NULL, (void *)&phy_id,
>> +				  bgx_match_phy_id);
>> +	if (!phy_dev)
>> +		goto out;
>> +
>> +	bgx->lmac[bgx->lmac_count].phydev = to_phy_device(phy_dev);
>> +out:
>> +	bgx->lmac_count++;
>> +	return AE_OK;
>> +}
>> +
>> +static acpi_status bgx_acpi_match_id(acpi_handle handle, u32 lvl,
>> +				     void *context, void **ret_val)
>> +{
>> +	struct acpi_buffer string = { ACPI_ALLOCATE_BUFFER, NULL };
>> +	struct bgx *bgx = context;
>> +	char bgx_sel[5];
>> +
>> +	snprintf(bgx_sel, 5, "BGX%d", bgx->bgx_id);
>> +	if (ACPI_FAILURE(acpi_get_name(handle, ACPI_SINGLE_NAME, &string))) {
>> +		pr_warn("Invalid link device\n");
>> +		return AE_OK;
>> +	}
>> +
>> +	if (strncmp(string.pointer, bgx_sel, 4))
>> +		return AE_OK;
>> +
>> +	acpi_walk_namespace(ACPI_TYPE_DEVICE, handle, 1,
>> +			    bgx_acpi_register_phy, NULL, bgx, NULL);
>> +
>> +	kfree(string.pointer);
>> +	return AE_CTRL_TERMINATE;
>> +}
>> +
>> +static int bgx_init_acpi_phy(struct bgx *bgx)
>> +{
>> +	acpi_get_devices(NULL, bgx_acpi_match_id, bgx, (void **)NULL);
>> +	return 0;
>> +}
>> +
>> +#else
>> +
>> +static int bgx_init_acpi_phy(struct bgx *bgx)
>> +{
>> +	return -ENODEV;
>> +}
>> +
>> +#endif /* CONFIG_ACPI */
>> +
>>   #if IS_ENABLED(CONFIG_OF_MDIO)
>>
>>   static int bgx_init_of_phy(struct bgx *bgx)
>> @@ -882,7 +1010,12 @@ static int bgx_init_of_phy(struct bgx *bgx)
>>
>>   static int bgx_init_phy(struct bgx *bgx)
>>   {
>> -	return bgx_init_of_phy(bgx);
>> +	int err = bgx_init_of_phy(bgx);
>> +
>> +	if (err != -ENODEV)
>> +		return err;
>> +
>> +	return bgx_init_acpi_phy(bgx);
>>   }
>>
>>   static int bgx_probe(struct pci_dev *pdev, const struct pci_device_id *ent)
>> --
>> 1.9.1
>>
>> --
>> To unsubscribe from this list: send the line "unsubscribe linux-acpi" in
>> the body of a message to majordomo at vger.kernel.org
>> More majordomo info at  http://vger.kernel.org/majordomo-info.html



From stuart.yoder at freescale.com  Fri Aug  7 12:01:47 2015
From: stuart.yoder at freescale.com (Stuart Yoder)
Date: Fri, 7 Aug 2015 19:01:47 +0000
Subject: [RFC] arm64: defconfig: enable 48-bit VA by default
In-Reply-To: <CAKv+Gu-Wbv3J9-2KbXrz_3W_=VXChrD+REo1-q1Ns_=RUM1BFw@mail.gmail.com>
References: <CY1PR0301MB07488D6DC5F0B171D6B290E187830@CY1PR0301MB0748.namprd03.prod.outlook.com>
 <55B0E1AD.60409@arm.com>
 <BY2PR0301MB0743CBCFC5476E39A5D1EC0B878C0@BY2PR0301MB0743.namprd03.prod.outlook.com>
 <CAKv+Gu9LHBd7wM6P4H0X5WigzDETtpr2++_Ebo=adg5QtTOW2w@mail.gmail.com>
 <BY2PR0301MB074300C5F31701D9211827F0878C0@BY2PR0301MB0743.namprd03.prod.outlook.com>
 <20150730101358.GA30796@e104818-lin.cambridge.arm.com>
 <CY1PR0301MB074850E27D5D298D1B8495D2878B0@CY1PR0301MB0748.namprd03.prod.outlook.com>
 <20150730161210.GE407@e104818-lin.cambridge.arm.com>
 <CY1PR0301MB0748FA3A10AFA9BFC1AB0A39878B0@CY1PR0301MB0748.namprd03.prod.outlook.com>
 <CAKv+Gu-Wbv3J9-2KbXrz_3W_=VXChrD+REo1-q1Ns_=RUM1BFw@mail.gmail.com>
Message-ID: <BY2PR0301MB07436AC9C8D023DC7C67DE3D87730@BY2PR0301MB0743.namprd03.prod.outlook.com>

> Whether defconfig supports your platform optimally has nothing to do
> with that. Of course, we should deal with the unexpected memory layout
> gracefully, which is why Mark Rutland and myself proposed patches to
> fix the panic you reported. But in a development context, I think it
> is perfectly acceptable to simply load the kernel at 0x80_8000_0000,
> and be able to run defconfig fine while losing just 2 GB of your 16 GB
> at the low end.

I've done this experiment-- loading/running the kernel at 0x80_8000_0000
and losing the lower 2GB of memory.  And in fact I can see the kernel
ignoring the low memory:

   [    0.000000] Ignoring memory block 0x80000000 - 0x100000000

However, this only works with 48-bit VA enabled.  With 39-bit VA
enabled the kernel crashes before the early console is working
and I see nothing.

Does the linear mapping we've been talking about just need to cover
all of _RAM_, or does it need to cover all of I/O as well in 
the same mapping.

In our case we have various SoC I/O devices, like the UART
in the space below 4 GB... at 0x0100_0000.

Before debugging further I want to check whether this should
work in theory.  I had the impression that the issue was
discontiguous RAM regions, and I/O was a separate issue.

Thanks,
Stuart

From petr.cvek at tul.cz  Fri Aug  7 12:14:47 2015
From: petr.cvek at tul.cz (Petr Cvek)
Date: Fri, 07 Aug 2015 21:14:47 +0200
Subject: [BUG, RFC] Different bitfields in documentation and driver
Message-ID: <55C503A7.6020304@tul.cz>

Hello,
It seems that PXA2xx framebuffer has switched bitfields in nonstd definition (when using overlay).

This:

	http://lxr.free-electrons.com/source/drivers/video/fbdev/pxafb.h#L80

versus this:

	http://lxr.free-electrons.com/source/Documentation/fb/pxafb.txt#L128

Should be this changed in documentation or in driver? I was able to find only one use (in form of little outdated mplayer patch) and it fills both bitfields with zero (so potential change in driver will not break it).

P.S. Lack of overlay2's use is probably caused by errata "E24: LCD: Enabling Overlay 2 for YUV420 hangs LCD controller.", which is not workarounded in this driver. It should be mentioned in documentation and/or code, because the only way to start the LCD again is a full PXA SoC reset.

Petr Cvek


From alex.williamson at redhat.com  Fri Aug  7 13:09:15 2015
From: alex.williamson at redhat.com (Alex Williamson)
Date: Fri, 07 Aug 2015 14:09:15 -0600
Subject: [PATCH v4 5/5] KVM: eventfd: add irq bypass consumer management
In-Reply-To: <1438622444-25444-6-git-send-email-eric.auger@linaro.org>
References: <1438622444-25444-1-git-send-email-eric.auger@linaro.org>
 <1438622444-25444-6-git-send-email-eric.auger@linaro.org>
Message-ID: <1438978155.4023.263.camel@redhat.com>

On Mon, 2015-08-03 at 19:20 +0200, Eric Auger wrote:
> This patch adds the registration/unregistration of an
> irq_bypass_consumer on irqfd assignment/deassignment.
> 
> Signed-off-by: Eric Auger <eric.auger at linaro.org>
> Signed-off-by: Feng Wu <feng.wu at intel.com>
> 
> ---
> 
> v2 -> v3 (Feng Wu):
> - Use kvm_arch_irq_bypass_start
> - Remove kvm_arch_irq_bypass_update
> - Add member 'struct irq_bypass_producer *producer' in
>   'struct kvm_kernel_irqfd', it is needed by posted interrupt.
> - Remove 'irq_bypass_unregister_consumer' in kvm_irqfd_deassign()
> 
> v1 -> v2:
> - populate of kvm and gsi removed
> - unregister the consumer on irqfd_shutdown
> ---
>  include/linux/kvm_irqfd.h |  2 ++
>  virt/kvm/eventfd.c        | 10 ++++++++++
>  2 files changed, 12 insertions(+)
> 
> diff --git a/include/linux/kvm_irqfd.h b/include/linux/kvm_irqfd.h
> index f926b39..0c1de05 100644
> --- a/include/linux/kvm_irqfd.h
> +++ b/include/linux/kvm_irqfd.h
> @@ -64,6 +64,8 @@ struct kvm_kernel_irqfd {
>  	struct list_head list;
>  	poll_table pt;
>  	struct work_struct shutdown;
> +	struct irq_bypass_consumer consumer;
> +	struct irq_bypass_producer *producer;
>  };
>  
>  #endif /* __LINUX_KVM_IRQFD_H */
> diff --git a/virt/kvm/eventfd.c b/virt/kvm/eventfd.c
> index 647ffb8..08855de 100644
> --- a/virt/kvm/eventfd.c
> +++ b/virt/kvm/eventfd.c
> @@ -35,6 +35,7 @@
>  #include <linux/srcu.h>
>  #include <linux/slab.h>
>  #include <linux/seqlock.h>
> +#include <linux/irqbypass.h>
>  #include <trace/events/kvm.h>
>  
>  #include <kvm/iodev.h>
> @@ -140,6 +141,7 @@ irqfd_shutdown(struct work_struct *work)
>  	/*
>  	 * It is now safe to release the object's resources
>  	 */
> +	irq_bypass_unregister_consumer(&irqfd->consumer);
>  	eventfd_ctx_put(irqfd->eventfd);
>  	kfree(irqfd);
>  }
> @@ -380,6 +382,14 @@ kvm_irqfd_assign(struct kvm *kvm, struct kvm_irqfd *args)
>  	 */
>  	fdput(f);
>  
> +	irqfd->consumer.token = (void *)irqfd->eventfd;
> +	irqfd->consumer.add_producer = kvm_arch_irq_bypass_add_producer;
> +	irqfd->consumer.del_producer = kvm_arch_irq_bypass_del_producer;
> +	irqfd->consumer.stop = kvm_arch_irq_bypass_stop;
> +	irqfd->consumer.start = kvm_arch_irq_bypass_start;
> +	ret = irq_bypass_register_consumer(&irqfd->consumer);
> +	WARN_ON(ret);

This seems like a lazy way to handle this error.  What is the stack
trace from this WARN_ON going to tell us that we didn't already know?
If we get the WARN_ON, it's probably means that an incompatible producer
registered the token first.  It means we can't do bypass, but it doesn't
tell us anything about whether bypass is or is not enabled.  Wouldn't a
pr_info/debug() suffice for that?  Thanks,

Alex

> +
>  	return 0;
>  
>  fail:





From alex.williamson at redhat.com  Fri Aug  7 13:09:14 2015
From: alex.williamson at redhat.com (Alex Williamson)
Date: Fri, 07 Aug 2015 14:09:14 -0600
Subject: [PATCH v4 4/5] KVM: introduce kvm_arch functions for IRQ bypass
In-Reply-To: <1438622444-25444-5-git-send-email-eric.auger@linaro.org>
References: <1438622444-25444-1-git-send-email-eric.auger@linaro.org>
 <1438622444-25444-5-git-send-email-eric.auger@linaro.org>
Message-ID: <1438978154.4023.262.camel@redhat.com>

On Mon, 2015-08-03 at 19:20 +0200, Eric Auger wrote:
> This patch introduces
> - kvm_arch_irq_bypass_add_producer
> - kvm_arch_irq_bypass_del_producer
> - kvm_arch_irq_bypass_stop
> - kvm_arch_irq_bypass_start
> 
> They make possible to specialize the KVM IRQ bypass consumer in
> case CONFIG_KVM_HAVE_IRQ_BYPASS is set.
> 
> Signed-off-by: Eric Auger <eric.auger at linaro.org>
> Signed-off-by: Feng Wu <feng.wu at intel.com>
> 
> ---
> 
> v2 -> v3 (Feng Wu):
> - use 'kvm_arch_irq_bypass_start' instead of 'kvm_arch_irq_bypass_resume'
> - Remove 'kvm_arch_irq_bypass_update', which is not needed to be
>   a irqbypass callback per Alex's comments.
> - Make kvm_arch_irq_bypass_add_producer return 'int'
> 
> v1 -> v2:
> - use CONFIG_KVM_HAVE_IRQ_BYPASS instead CONFIG_IRQ_BYPASS_MANAGER
> - rename all functions according to Paolo's proposal
> - add kvm_arch_irq_bypass_update according to Feng's need
> ---
>  include/linux/kvm_host.h | 33 +++++++++++++++++++++++++++++++++
>  virt/kvm/Kconfig         |  3 +++
>  2 files changed, 36 insertions(+)
> 
> diff --git a/include/linux/kvm_host.h b/include/linux/kvm_host.h
> index 05e99b8..84b5feb 100644
> --- a/include/linux/kvm_host.h
> +++ b/include/linux/kvm_host.h
> @@ -24,6 +24,7 @@
>  #include <linux/err.h>
>  #include <linux/irqflags.h>
>  #include <linux/context_tracking.h>
> +#include <linux/irqbypass.h>
>  #include <asm/signal.h>
>  
>  #include <linux/kvm.h>
> @@ -1151,5 +1152,37 @@ static inline void kvm_vcpu_set_dy_eligible(struct kvm_vcpu *vcpu, bool val)
>  {
>  }
>  #endif /* CONFIG_HAVE_KVM_CPU_RELAX_INTERCEPT */
> +
> +#ifdef CONFIG_HAVE_KVM_IRQ_BYPASS
> +
> +int kvm_arch_irq_bypass_add_producer(struct irq_bypass_consumer *,
> +			   struct irq_bypass_producer *);
> +void kvm_arch_irq_bypass_del_producer(struct irq_bypass_consumer *,
> +			   struct irq_bypass_producer *);
> +void kvm_arch_irq_bypass_stop(struct irq_bypass_consumer *);
> +void kvm_arch_irq_bypass_start(struct irq_bypass_consumer *);
> +
> +#else

Do we really need static inline stubs?  When would they get used?  How
would they work since we call them via function pointers?

> +
> +static inline int kvm_arch_irq_bypass_add_producer(
> +			struct irq_bypass_consumer *cons,
> +			struct irq_bypass_producer *prod)
> +{
> +	return -1;

No reason not to stick with standard errno values, is there?  -EINVAL
Thanks,

Alex

> +}
> +static inline void kvm_arch_irq_bypass_del_producer(
> +			struct irq_bypass_consumer *cons,
> +			struct irq_bypass_producer *prod)
> +{
> +}
> +static inline void kvm_arch_irq_bypass_stop(
> +			struct irq_bypass_consumer *cons)
> +{
> +}
> +static inline void kvm_arch_irq_bypass_start(
> +			struct irq_bypass_consumer *cons)
> +{
> +}
> +#endif /* CONFIG_HAVE_KVM_IRQ_BYPASS */
>  #endif
>  
> diff --git a/virt/kvm/Kconfig b/virt/kvm/Kconfig
> index e2c876d..9f8014d 100644
> --- a/virt/kvm/Kconfig
> +++ b/virt/kvm/Kconfig
> @@ -47,3 +47,6 @@ config KVM_GENERIC_DIRTYLOG_READ_PROTECT
>  config KVM_COMPAT
>         def_bool y
>         depends on COMPAT && !S390
> +
> +config HAVE_KVM_IRQ_BYPASS
> +       bool





From petr.cvek at tul.cz  Fri Aug  7 13:20:41 2015
From: petr.cvek at tul.cz (Petr Cvek)
Date: Fri, 07 Aug 2015 22:20:41 +0200
Subject: [BUG, RFC] MTD Execute in Place on ARM breaks build
Message-ID: <55C51319.2010901@tul.cz>

Hello,

Configuration:

	CONFIG_MTD_XIP=y

on PXA2xx architecture causes request of undefined macros from 

	drivers/mtd/chipscfi_cmdset_0001.c

These macros (using ICIP and ICMR) are defined here:

	http://lxr.free-electrons.com/source/arch/arm/mach-pxa/include/mach/mtd-xip.h#L20

register definitions for ICIP and ICMR were removed by commit:
	
	5d284e353eb11ab2e8b1c5671ba06489b0bd1e0c

Similar is for macros with OSCR (lines 23 and 24), which have different type.
Re-adding ICIP and ICMR definition and explicit type conversion will fix the build
and the kernel boots, but I'm not yet able to test XIP functionality (too many different
bugs to flash over windows mobile image).

My temporal fix (ugly):

#define ICIP __REG(0x40D00000)  /* Interrupt Controller IRQ Pending Register */
#define ICMR __REG(0x40D00004)  /* Interrupt Controller Mask Register */
...
#define xip_currtime()		((unsigned long) OSCR)
#define xip_elapsed_since(x)	(signed)((((unsigned long) OSCR) - (x)) / 4)


P.S. Same macros are used on omap1 and sa1100 too.

Petr Cvek


From raghumag at gmail.com  Fri Aug  7 13:54:04 2015
From: raghumag at gmail.com (raghu MG)
Date: Sat, 8 Aug 2015 02:24:04 +0530
Subject: Armadaxp GPIO interrupts
In-Reply-To: <CAG1O52XO+5F11ELZ+7txWXTYPwmhQP5sVvcjdCiM_T1+ptfp=w@mail.gmail.com>
References: <CAG1O52Xg88OsifBzmpSdqvC8wQaOW78nC9nnfxugFv1VU1m1LQ@mail.gmail.com>
 <20150804153439.GA28673@lunn.ch>
 <CAG1O52W2Gy_6_DfewtUqoK_J+Y=KwVGyygNaPu2xyPM_ZkLfcQ@mail.gmail.com>
 <CAG1O52VQPpeGkA8bqYbPMTiT9Mua1yHi3H3osqJsHqm-RRKzow@mail.gmail.com>
 <20150805162155.GE32760@lunn.ch>
 <CAG1O52WPFfm+XGk01iUVWLu=-Dm7bcDVmhv3P8iQDH+HHjsLUA@mail.gmail.com>
 <20150806132926.GB19896@lunn.ch>
 <CAG1O52XUyPkgTTRKftujZBNK1=n6GBdWgBg_kq6SsC5XMaeU3w@mail.gmail.com>
 <20150806171312.GI13421@lunn.ch>
 <CAG1O52XO+5F11ELZ+7txWXTYPwmhQP5sVvcjdCiM_T1+ptfp=w@mail.gmail.com>
Message-ID: <CAG1O52VTqkiGbQ2Et98WyL_vqAhcx6VXxPmHMpLnSJx5wCLe-w@mail.gmail.com>

Hi Andrew,
I added these entries into armada-xp-gp.dtb
 gpio_rtm {
                compatible = "gpio-rtm";
                #address-cells = <1>;
                #size-cells = <0>;
                pinctrl-0 = <&keys_pin>;
                pinctrl-names = "default";

                 rtm at 57 {
                        label = "RTM JACKINOUT";
                        gpios = <&gpio1 26 GPIO_ACTIVE_LOW>; /* GPIO 57 */
                };
        };

So I understand the leaf nodes are specific purpose of
GPIOs(input:keyboard,mouse,touchpad etc).
1)For the board I am working needs different implementation for GPIO
57 unlike input devices drivers driving GPIOs.
2)To implement the functionality I need to write driver specific to my
board which will implement event specific to requirements.
I hope I am going right here, can you name a simple driver(kernel
source) where it would make my driver development easy.

Thanks & Regards
Raghu


From dtor at chromium.org  Fri Aug  7 13:59:23 2015
From: dtor at chromium.org (Dmitry Torokhov)
Date: Fri, 7 Aug 2015 13:59:23 -0700
Subject: [PATCH] thermal: rockchip: fix handling of invalid readings
Message-ID: <20150807205923.GA33949@dtor-ws>

We attempted to signal invalid code by returning -EAGAIN from
rk_tsadcv2_code_to_temp(), unfortunately the return value was stuffed
directly into the temperature pointer, potentially confusing upper
layers with temperature of -EINVAL.

Let's split temperature from error/success indicator to avoid such
confusion.

Also change the way we scan the temperature table to start with the 2nd
element so that we do not need to worry that we may reference out of
bounds element while doing binary search and keep checking that we end
up with 'mid' equal to 0 (since we are looking for the temperature that
would fall into interval between the 'mid' and 'mid - 1') .

Signed-off-by: Dmitry Torokhov <dtor at chromium.org>
---
 drivers/thermal/rockchip_thermal.c | 28 +++++++++++++---------------
 1 file changed, 13 insertions(+), 15 deletions(-)

diff --git a/drivers/thermal/rockchip_thermal.c b/drivers/thermal/rockchip_thermal.c
index c89ffb2..93ee307 100644
--- a/drivers/thermal/rockchip_thermal.c
+++ b/drivers/thermal/rockchip_thermal.c
@@ -124,7 +124,7 @@ struct rockchip_thermal_data {
 #define TSADCV2_AUTO_PERIOD_HT_TIME		50  /* msec */
 
 struct tsadc_table {
-	unsigned long code;
+	u32 code;
 	long temp;
 };
 
@@ -164,7 +164,6 @@ static const struct tsadc_table v2_code_table[] = {
 	{3452, 115000},
 	{3437, 120000},
 	{3421, 125000},
-	{0, 125000},
 };
 
 static u32 rk_tsadcv2_temp_to_code(long temp)
@@ -191,19 +190,21 @@ static u32 rk_tsadcv2_temp_to_code(long temp)
 	return 0;
 }
 
-static int rk_tsadcv2_code_to_temp(u32 code)
+static int rk_tsadcv2_code_to_temp(u32 code, int *temp)
 {
-	unsigned int low = 0;
+	unsigned int low = 1;
 	unsigned int high = ARRAY_SIZE(v2_code_table) - 1;
 	unsigned int mid = (low + high) / 2;
 	unsigned int num;
 	unsigned long denom;
 
-	/* Invalid code, return -EAGAIN */
-	if (code > TSADCV2_DATA_MASK)
-		return -EAGAIN;
+	BUILD_BUG_ON(ARRAY_SIZE(v2_code_table) < 2);
 
-	while (low <= high && mid) {
+	code &= TSADCV2_DATA_MASK;
+	if (code < v2_code_table[high].code)
+		return -EAGAIN;		/* Incorrect reading */
+
+	while (low <= high) {
 		if (code >= v2_code_table[mid].code &&
 		    code < v2_code_table[mid - 1].code)
 			break;
@@ -223,7 +224,9 @@ static int rk_tsadcv2_code_to_temp(u32 code)
 	num = v2_code_table[mid].temp - v2_code_table[mid - 1].temp;
 	num *= v2_code_table[mid - 1].code - code;
 	denom = v2_code_table[mid - 1].code - v2_code_table[mid].code;
-	return v2_code_table[mid - 1].temp + (num / denom);
+	*temp = v2_code_table[mid - 1].temp + (num / denom);
+
+	return 0;
 }
 
 /**
@@ -281,14 +284,9 @@ static int rk_tsadcv2_get_temp(int chn, void __iomem *regs, int *temp)
 {
 	u32 val;
 
-	/* the A/D value of the channel last conversion need some time */
 	val = readl_relaxed(regs + TSADCV2_DATA(chn));
-	if (val == 0)
-		return -EAGAIN;
-
-	*temp = rk_tsadcv2_code_to_temp(val);
 
-	return 0;
+	return rk_tsadcv2_code_to_temp(val, temp);
 }
 
 static void rk_tsadcv2_tshut_temp(int chn, void __iomem *regs, long temp)
-- 
2.5.0.rc2.392.g76e840b


-- 
Dmitry


From dtor at chromium.org  Fri Aug  7 14:00:52 2015
From: dtor at chromium.org (Dmitry Torokhov)
Date: Fri, 7 Aug 2015 14:00:52 -0700
Subject: [PATCH] thermal: rockhip: fix setting thermal shutdown polarity
Message-ID: <20150807210052.GA34032@dtor-ws>

When requested thermal shutdown signal polarity is low we need to make
sure that the bit representing high level of signal is reset, and not
set all other bits in that register.

Also rename TSADCV2_INT_PD_CLEAR to TSADCV2_INT_PD_CLEAR_MASK to better
reflect its nature.

Signed-off-by: Dmitry Torokhov <dtor at chromium.org>
---
 drivers/thermal/rockchip_thermal.c | 10 ++++------
 1 file changed, 4 insertions(+), 6 deletions(-)

diff --git a/drivers/thermal/rockchip_thermal.c b/drivers/thermal/rockchip_thermal.c
index 93ee307..4d5b7d4 100644
--- a/drivers/thermal/rockchip_thermal.c
+++ b/drivers/thermal/rockchip_thermal.c
@@ -106,16 +106,14 @@ struct rockchip_thermal_data {
 #define TSADCV2_AUTO_PERIOD_HT			0x6c
 
 #define TSADCV2_AUTO_EN				BIT(0)
-#define TSADCV2_AUTO_DISABLE			~BIT(0)
 #define TSADCV2_AUTO_SRC_EN(chn)		BIT(4 + (chn))
 #define TSADCV2_AUTO_TSHUT_POLARITY_HIGH	BIT(8)
-#define TSADCV2_AUTO_TSHUT_POLARITY_LOW		~BIT(8)
 
 #define TSADCV2_INT_SRC_EN(chn)			BIT(chn)
 #define TSADCV2_SHUT_2GPIO_SRC_EN(chn)		BIT(4 + (chn))
 #define TSADCV2_SHUT_2CRU_SRC_EN(chn)		BIT(8 + (chn))
 
-#define TSADCV2_INT_PD_CLEAR			~BIT(8)
+#define TSADCV2_INT_PD_CLEAR_MASK		~BIT(8)
 
 #define TSADCV2_DATA_MASK			0xfff
 #define TSADCV2_HIGHT_INT_DEBOUNCE_COUNT	4
@@ -244,10 +242,10 @@ static void rk_tsadcv2_initialize(void __iomem *regs,
 				  enum tshut_polarity tshut_polarity)
 {
 	if (tshut_polarity == TSHUT_HIGH_ACTIVE)
-		writel_relaxed(0 | (TSADCV2_AUTO_TSHUT_POLARITY_HIGH),
+		writel_relaxed(0U | TSADCV2_AUTO_TSHUT_POLARITY_HIGH,
 			       regs + TSADCV2_AUTO_CON);
 	else
-		writel_relaxed(0 | (TSADCV2_AUTO_TSHUT_POLARITY_LOW),
+		writel_relaxed(0U & ~TSADCV2_AUTO_TSHUT_POLARITY_HIGH,
 			       regs + TSADCV2_AUTO_CON);
 
 	writel_relaxed(TSADCV2_AUTO_PERIOD_TIME, regs + TSADCV2_AUTO_PERIOD);
@@ -264,7 +262,7 @@ static void rk_tsadcv2_irq_ack(void __iomem *regs)
 	u32 val;
 
 	val = readl_relaxed(regs + TSADCV2_INT_PD);
-	writel_relaxed(val & TSADCV2_INT_PD_CLEAR, regs + TSADCV2_INT_PD);
+	writel_relaxed(val & TSADCV2_INT_PD_CLEAR_MASK, regs + TSADCV2_INT_PD);
 }
 
 static void rk_tsadcv2_control(void __iomem *regs, bool enable)
-- 
2.5.0.rc2.392.g76e840b


-- 
Dmitry


From dianders at chromium.org  Fri Aug  7 14:31:02 2015
From: dianders at chromium.org (Doug Anderson)
Date: Fri, 7 Aug 2015 14:31:02 -0700
Subject: [PATCH v2 1/2] ARM: dts: rockchip: reserve unusable memory region
 on rk3288
In-Reply-To: <1763907.pckMEaRNPs@diego>
References: <1763907.pckMEaRNPs@diego>
Message-ID: <CAD=FV=Vo0tQO-KdCLbcJF-yYEgwGbjEx3qvvnv7jgAKcVA4p+g@mail.gmail.com>

Heiko,

On Thu, Aug 6, 2015 at 10:33 AM, Heiko St?bner <heiko at sntech.de> wrote:
> The all current Rockchip SoCs supporting 4GB of ram have problems accessing
> the memory region 0xfe000000~0xff000000. This also seems to includes the
> rk3368 arm64 soc.
>
> All current code handling dma memory oddities I could find, seem to involve
> soc-specific code (zone-dma or so) while this issue is shared between arm32
> and arm64 socs from Rockchip, which would need to have this described in
> the soc devicetree on both socs.
>
> Limiting the dma-zone alone also does not solve the issue and as the
> dma-masks need to be a power-of-two in the kernel, the next lower dma-mask
> brings memory usable for dma down to 2GB.
>
> So as a stop-gap block off the affected region to prevent its use by
> devices with 4GB of memory, like some recent Chromebooks.
>
> Signed-off-by: Heiko Stuebner <heiko at sntech.de>
> ---
> changes since v1:
> - expand reasons for the reserved memory
>
>  arch/arm/boot/dts/rk3288.dtsi | 20 ++++++++++++++++++++
>  1 file changed, 20 insertions(+)

As discussed earlier, I'm now convinced that this is an appropriate
stopgap.  ...and the description looks good to me.

Reviewed-by: Douglas Anderson <dianders at chromium.org>


From manabian at gmail.com  Fri Aug  7 14:32:05 2015
From: manabian at gmail.com (Joachim Eastwood)
Date: Fri, 7 Aug 2015 23:32:05 +0200
Subject: [RFC PATCH v4 1/9] mmc: dw_mmc: Add external dma interface support
In-Reply-To: <1438843491-23853-1-git-send-email-shawn.lin@rock-chips.com>
References: <1438843469-23807-1-git-send-email-shawn.lin@rock-chips.com>
 <1438843491-23853-1-git-send-email-shawn.lin@rock-chips.com>
Message-ID: <CAGhQ9VxUYvgGD=K3J3cQ0CNpCC-RfGE9cxhBHnTeAU2CmWkiKA@mail.gmail.com>

Hi Shawn,

On 6 August 2015 at 08:44, Shawn Lin <shawn.lin at rock-chips.com> wrote:
> DesignWare MMC Controller can supports two types of DMA
> mode: external dma and internal dma. We get a RK312x platform
> integrated dw_mmc and ARM pl330 dma controller. This patch add
> edmac ops to support these platforms. I've tested it on RK312x
> platform with edmac mode and RK3288 platform with idmac mode.
>
> Signed-off-by: Shawn Lin <shawn.lin at rock-chips.com>

> @@ -2256,26 +2373,30 @@ static irqreturn_t dw_mci_interrupt(int irq, void *dev_id)
>
>         }
>
> -#ifdef CONFIG_MMC_DW_IDMAC
> -       /* Handle DMA interrupts */
> -       if (host->dma_64bit_address == 1) {
> -               pending = mci_readl(host, IDSTS64);
> -               if (pending & (SDMMC_IDMAC_INT_TI | SDMMC_IDMAC_INT_RI)) {
> -                       mci_writel(host, IDSTS64, SDMMC_IDMAC_INT_TI |
> -                                                       SDMMC_IDMAC_INT_RI);
> -                       mci_writel(host, IDSTS64, SDMMC_IDMAC_INT_NI);
> -                       host->dma_ops->complete(host);
> -               }
> -       } else {
> -               pending = mci_readl(host, IDSTS);
> -               if (pending & (SDMMC_IDMAC_INT_TI | SDMMC_IDMAC_INT_RI)) {
> -                       mci_writel(host, IDSTS, SDMMC_IDMAC_INT_TI |
> -                                                       SDMMC_IDMAC_INT_RI);
> -                       mci_writel(host, IDSTS, SDMMC_IDMAC_INT_NI);
> -                       host->dma_ops->complete(host);
> +       if (host->use_dma == TRANS_MODE_IDMAC) {

Doing:
if (host->use_dma != TRANS_MODE_IDMAC)
    return IRQ_HANDLED;

Could save you the extra level of identation you add below.

> +               /* Handle DMA interrupts */
> +               if (host->dma_64bit_address == 1) {
> +                       pending = mci_readl(host, IDSTS64);
> +                       if (pending & (SDMMC_IDMAC_INT_TI |
> +                                      SDMMC_IDMAC_INT_RI)) {
> +                               mci_writel(host, IDSTS64,
> +                                          SDMMC_IDMAC_INT_TI |
> +                                          SDMMC_IDMAC_INT_RI);
> +                               mci_writel(host, IDSTS64, SDMMC_IDMAC_INT_NI);
> +                               host->dma_ops->complete((void *)host);
> +                       }
> +               } else {
> +                       pending = mci_readl(host, IDSTS);
> +                       if (pending & (SDMMC_IDMAC_INT_TI |
> +                                      SDMMC_IDMAC_INT_RI)) {
> +                               mci_writel(host, IDSTS,
> +                                          SDMMC_IDMAC_INT_TI |
> +                                          SDMMC_IDMAC_INT_RI);
> +                               mci_writel(host, IDSTS, SDMMC_IDMAC_INT_NI);
> +                               host->dma_ops->complete((void *)host);
> +                       }
>                 }
>         }
> -#endif
>
>         return IRQ_HANDLED;
>  }


> @@ -2437,6 +2567,21 @@ static void dw_mci_cleanup_slot(struct dw_mci_slot *slot, unsigned int id)
>  static void dw_mci_init_dma(struct dw_mci *host)
>  {
>         int addr_config;
> +       int trans_mode;
> +       struct device *dev = host->dev;
> +       struct device_node *np = dev->of_node;
> +
> +       /* Check tansfer mode */
> +       trans_mode = (mci_readl(host, HCON) >> 16) & 0x3;

I think it would be nice if you could add some defines for 16 and 0x03
or add a macro like SDMMC_GET_FCNT() that is in dw_mmc.h.

> +       if (trans_mode == 0) {
> +               trans_mode = TRANS_MODE_IDMAC;
> +       } else if (trans_mode == 1 || trans_mode == 2) {
> +               trans_mode = TRANS_MODE_EDMAC;
> +       } else {
> +               trans_mode = TRANS_MODE_PIO;
> +               goto no_dma;
> +       }
> +
>         /* Check ADDR_CONFIG bit in HCON to find IDMAC address bus width */
>         addr_config = (mci_readl(host, HCON) >> 27) & 0x01;

I'll try to get this patch tested on my lpc18xx platform soon.
btw, the HCON reg on lpc18xx reads as 0x00e42cc1 (address 0x40004070).


regard,
Joachim Eastwood


From manabian at gmail.com  Fri Aug  7 14:34:24 2015
From: manabian at gmail.com (Joachim Eastwood)
Date: Fri, 7 Aug 2015 23:34:24 +0200
Subject: [RFC PATCH v4 7/9] arm: lpc18xx_defconfig: remove
 CONFIG_MMC_DW_IDMAC
In-Reply-To: <1438843590-24101-1-git-send-email-shawn.lin@rock-chips.com>
References: <1438843469-23807-1-git-send-email-shawn.lin@rock-chips.com>
 <1438843590-24101-1-git-send-email-shawn.lin@rock-chips.com>
Message-ID: <CAGhQ9VxkFk19HGtToUm8bOU62Z8S0_dMqciUiNfJry-Jb5YF=Q@mail.gmail.com>

On 6 August 2015 at 08:46, Shawn Lin <shawn.lin at rock-chips.com> wrote:
> DesignWare MMC Controller's transfer mode should be decided
> at runtime instead of compile-time. So we remove this config
> option and read dw_mmc's register to select DMA master.
>
> Signed-off-by: Shawn Lin <shawn.lin at rock-chips.com>

Acked-by: Joachim Eastwood <manabian at gmail.com>

>  arch/arm/configs/lpc18xx_defconfig | 1 -
>  1 file changed, 1 deletion(-)
>
> diff --git a/arch/arm/configs/lpc18xx_defconfig b/arch/arm/configs/lpc18xx_defconfig
> index 1c47f86..b7e8cda 100644
> --- a/arch/arm/configs/lpc18xx_defconfig
> +++ b/arch/arm/configs/lpc18xx_defconfig
> @@ -119,7 +119,6 @@ CONFIG_USB_EHCI_HCD=y
>  CONFIG_USB_EHCI_ROOT_HUB_TT=y
>  CONFIG_MMC=y
>  CONFIG_MMC_DW=y
> -CONFIG_MMC_DW_IDMAC=y
>  CONFIG_NEW_LEDS=y
>  CONFIG_LEDS_CLASS=y
>  CONFIG_LEDS_PCA9532=y
> --
> 2.3.7
>
>
> --
> To unsubscribe from this list: send the line "unsubscribe linux-kernel" in
> the body of a message to majordomo at vger.kernel.org
> More majordomo info at  http://vger.kernel.org/majordomo-info.html
> Please read the FAQ at  http://www.tux.org/lkml/


From rjw at rjwysocki.net  Fri Aug  7 15:21:04 2015
From: rjw at rjwysocki.net (Rafael J. Wysocki)
Date: Sat, 08 Aug 2015 00:21:04 +0200
Subject: [PATCH v4 1/6] cpufreq: make scaling_boost_freqs sysfs attr
 available when boost is enabled
In-Reply-To: <20150807113739.GF6939@linux>
References: <1438868514-8814-1-git-send-email-b.zolnierkie@samsung.com>
 <1594902.Dv5JKhve0y@amdc1976> <20150807113739.GF6939@linux>
Message-ID: <11605783.uxKCOKbq1D@vostro.rjw.lan>

On Friday, August 07, 2015 05:07:39 PM Viresh Kumar wrote:
> On 07-08-15, 13:12, Bartlomiej Zolnierkiewicz wrote:
> > >From 993ebb6fc632ec7b61654c9610c90ff4dca4be34 Mon Sep 17 00:00:00 2001
> > From: Bartlomiej Zolnierkiewicz <b.zolnierkie at samsung.com>
> > Date: Fri, 7 Aug 2015 13:07:51 +0200
> > Subject: [PATCH] cpufreq-dt: make scaling_boost_freqs sysfs attr available
> >  when boost is enabled
> > 
> > Make scaling_boost_freqs sysfs attribute is available when
> > cpufreq-dt driver is used and boost support is enabled.
> > 
> > Cc: Thomas Abraham <thomas.ab at samsung.com>
> > Cc: Javier Martinez Canillas <javier at osg.samsung.com>
> > Cc: Krzysztof Kozlowski <k.kozlowski at samsung.com>
> > Suggested-by: Viresh Kumar <viresh.kumar at linaro.org>
> > Signed-off-by: Bartlomiej Zolnierkiewicz <b.zolnierkie at samsung.com>
> > ---
> >  drivers/cpufreq/cpufreq-dt.c | 11 ++++++++++-
> >  include/linux/cpufreq.h      |  1 +
> >  2 files changed, 11 insertions(+), 1 deletion(-)
> > 
> > diff --git a/drivers/cpufreq/cpufreq-dt.c b/drivers/cpufreq/cpufreq-dt.c
> > index b9259ab..c6a3b98 100644
> > --- a/drivers/cpufreq/cpufreq-dt.c
> > +++ b/drivers/cpufreq/cpufreq-dt.c
> > @@ -36,6 +36,12 @@ struct private_data {
> >  	unsigned int voltage_tolerance; /* in percentage */
> >  };
> >  
> > +static struct freq_attr *cpufreq_dt_attr[] = {
> > +	&cpufreq_freq_attr_scaling_available_freqs,
> > +	NULL,   /* Extra space for boost-attr if required */
> > +	NULL,
> > +};
> > +
> >  static int set_target(struct cpufreq_policy *policy, unsigned int index)
> >  {
> >  	struct dev_pm_opp *opp;
> > @@ -182,6 +188,8 @@ try_again:
> >  	return ret;
> >  }
> >  
> > +static struct cpufreq_driver dt_cpufreq_driver;
> > +
> >  static int cpufreq_init(struct cpufreq_policy *policy)
> >  {
> >  	struct cpufreq_frequency_table *freq_table;
> > @@ -336,6 +344,7 @@ static int cpufreq_init(struct cpufreq_policy *policy)
> >  		ret = cpufreq_enable_boost_support();
> >  		if (ret)
> >  			goto out_free_cpufreq_table;
> > +		cpufreq_dt_attr[1] = &cpufreq_freq_attr_scaling_boost_freqs;
> >  	}
> >  
> >  	policy->cpuinfo.transition_latency = transition_latency;
> > @@ -411,7 +420,7 @@ static struct cpufreq_driver dt_cpufreq_driver = {
> >  	.exit = cpufreq_exit,
> >  	.ready = cpufreq_ready,
> >  	.name = "cpufreq-dt",
> > -	.attr = cpufreq_generic_attr,
> > +	.attr = cpufreq_dt_attr,
> >  };
> >  
> >  static int dt_cpufreq_probe(struct platform_device *pdev)
> > diff --git a/include/linux/cpufreq.h b/include/linux/cpufreq.h
> > index 95f0186..657542d 100644
> > --- a/include/linux/cpufreq.h
> > +++ b/include/linux/cpufreq.h
> > @@ -609,6 +609,7 @@ struct cpufreq_frequency_table *cpufreq_frequency_get_table(unsigned int cpu);
> >  
> >  /* the following are really really optional */
> >  extern struct freq_attr cpufreq_freq_attr_scaling_available_freqs;
> > +extern struct freq_attr cpufreq_freq_attr_scaling_boost_freqs;
> >  extern struct freq_attr *cpufreq_generic_attr[];
> >  int cpufreq_table_validate_and_show(struct cpufreq_policy *policy,
> >  				      struct cpufreq_frequency_table *table);
> 
> Acked-by: Viresh Kumar <viresh.kumar at linaro.org>

And what exactly am I supposed to do with this?

Have a robot that will pick up all patches ACKed by you magically or what?

Rafael



From rjw at rjwysocki.net  Fri Aug  7 15:24:36 2015
From: rjw at rjwysocki.net (Rafael J. Wysocki)
Date: Sat, 08 Aug 2015 00:24:36 +0200
Subject: [PATCH v4 0/6] cpufreq: use generic cpufreq drivers for
 Exynos4x12 platform
In-Reply-To: <20150807115627.GH6939@linux>
References: <1438868514-8814-1-git-send-email-b.zolnierkie@samsung.com>
 <2359635.Hxe4cb8zKm@amdc1976> <20150807115627.GH6939@linux>
Message-ID: <1525406.7aXvVQzEDd@vostro.rjw.lan>

On Friday, August 07, 2015 05:26:27 PM Viresh Kumar wrote:
> On 07-08-15, 13:47, Bartlomiej Zolnierkiewicz wrote:
> > Hmm, wait.  Patch 6/6 depends on earlier changes.  I cannot remove
> > the config option in question now as it is currently used by
> > exynos-cpufreq specific boost support.  Patch 1/6 can be applied
> > now but 6/6 needs to wait for patches 2-5 to be applied first.
> > 
> > Actually 6/6 is trivial and can be applied later in v4.3 cycle or
> > even in v4.4 one.
> 
> Ack.

OK, so please let me know which patches you want me to pick up.

Ideally, I'd prefer them to be resent in a separate series with ACKs and all
with a cover letter clearly stating whose tree they are being targeted at.

Thanks,
Rafael



From dianders at chromium.org  Fri Aug  7 15:06:39 2015
From: dianders at chromium.org (Doug Anderson)
Date: Fri, 7 Aug 2015 15:06:39 -0700
Subject: [PATCH v2 2/2] ARM: dts: rockchip: add veyron-minnie board
In-Reply-To: <3051758.nWNxbUbTXs@diego>
References: <1763907.pckMEaRNPs@diego>
	<3051758.nWNxbUbTXs@diego>
Message-ID: <CAD=FV=XVxxDzXkz7DuX47d=3MENzGkHrBYYDzH_KCKDpyORYYA@mail.gmail.com>

Heiko,

On Thu, Aug 6, 2015 at 10:37 AM, Heiko St?bner <heiko at sntech.de> wrote:
> +&i2c3 {
> +       status = "okay";
> +
> +       /*
> +        * Touchscreen pin control is shared between Atmel and Elan devices,
> +        * so we have to pull it up to the bus level.
> +        */
> +       pinctrl-names = "default";
> +       pinctrl-0 = <&i2c3_xfer &touch_int &touch_rst>;
> +
> +       clock-frequency = <400000>;
> +       i2c-scl-falling-time-ns = <50>;
> +       i2c-scl-rising-time-ns = <300>;
> +
> +       touchscreen at 10 {
> +               compatible = "elan,ekth3500";
> +               reg = <0x10>;
> +               interrupt-parent = <&gpio2>;
> +               interrupts = <14 IRQ_TYPE_EDGE_FALLING>;
> +               reset-gpios = <&gpio2 15 GPIO_ACTIVE_LOW>;
> +               vcc33-supply = <&vcc33_touch>;
> +               vccio-supply = <&vcc33_touch>;
> +       };
> +
> +       touchscreen at 4a {
> +               compatible = "atmel,atmel_mxt_ts";
> +               reg = <0x4a>;
> +               atmel,reset-gpios = <&gpio2 15 GPIO_ACTIVE_LOW>;
> +               avdd-supply = <&vcc5v_touch>;
> +               interrupt-parent = <&gpio2>;
> +               interrupts = <14 IRQ_TYPE_EDGE_FALLING>;
> +               vdd-supply = <&vcc33_touch>;

Technically I don't think most of these properties exist upstream, but
Dmitry (now CCed) might know more.

...actually similar for elan.  At least I don't see 'reset-gpios', nor
'vcc33-supply' and 'vccio-supply' in the bindings when I checkout
linuxnext...

Oh, and also locally our tree has hacks in it to handle the fact that
both atmel and elan will try to grab the same reset GPIO.  I'm nearly
certain that Dmitry said that the current hacks we have wouldn't be
appropriate for upstream.  I had some proposals for better solutions,
but they were slightly more controversial.  In any case, I think all
shipping devices ended up using one or the other of these two
touchscreens (I forget which), so you could probably simplify and just
pick one of them.  If old prototype devices don't work upstream it
wouldn't be the end of the world.


Everything else looks fine to me, so if you avoid using non-upstream
properties for the touchscreens then you can add my Reviewed-by.

-Doug


From dmitry.torokhov at gmail.com  Fri Aug  7 15:13:13 2015
From: dmitry.torokhov at gmail.com (Dmitry Torokhov)
Date: Fri, 7 Aug 2015 15:13:13 -0700
Subject: [PATCH v2 2/2] ARM: dts: rockchip: add veyron-minnie board
In-Reply-To: <CAD=FV=XVxxDzXkz7DuX47d=3MENzGkHrBYYDzH_KCKDpyORYYA@mail.gmail.com>
References: <1763907.pckMEaRNPs@diego> <3051758.nWNxbUbTXs@diego>
 <CAD=FV=XVxxDzXkz7DuX47d=3MENzGkHrBYYDzH_KCKDpyORYYA@mail.gmail.com>
Message-ID: <CAKdAkRTVbGeDY2J_T1N1x1yQaq7vCnO71TVmQGAZAkMaQsz2qw@mail.gmail.com>

On Fri, Aug 7, 2015 at 3:06 PM, Doug Anderson <dianders at chromium.org> wrote:
> Heiko,
>
> On Thu, Aug 6, 2015 at 10:37 AM, Heiko St?bner <heiko at sntech.de> wrote:
>> +&i2c3 {
>> +       status = "okay";
>> +
>> +       /*
>> +        * Touchscreen pin control is shared between Atmel and Elan devices,
>> +        * so we have to pull it up to the bus level.
>> +        */
>> +       pinctrl-names = "default";
>> +       pinctrl-0 = <&i2c3_xfer &touch_int &touch_rst>;
>> +
>> +       clock-frequency = <400000>;
>> +       i2c-scl-falling-time-ns = <50>;
>> +       i2c-scl-rising-time-ns = <300>;
>> +
>> +       touchscreen at 10 {
>> +               compatible = "elan,ekth3500";
>> +               reg = <0x10>;
>> +               interrupt-parent = <&gpio2>;
>> +               interrupts = <14 IRQ_TYPE_EDGE_FALLING>;
>> +               reset-gpios = <&gpio2 15 GPIO_ACTIVE_LOW>;
>> +               vcc33-supply = <&vcc33_touch>;
>> +               vccio-supply = <&vcc33_touch>;
>> +       };
>> +
>> +       touchscreen at 4a {
>> +               compatible = "atmel,atmel_mxt_ts";
>> +               reg = <0x4a>;
>> +               atmel,reset-gpios = <&gpio2 15 GPIO_ACTIVE_LOW>;
>> +               avdd-supply = <&vcc5v_touch>;
>> +               interrupt-parent = <&gpio2>;
>> +               interrupts = <14 IRQ_TYPE_EDGE_FALLING>;
>> +               vdd-supply = <&vcc33_touch>;
>
> Technically I don't think most of these properties exist upstream, but
> Dmitry (now CCed) might know more.
>
> ...actually similar for elan.  At least I don't see 'reset-gpios', nor
> 'vcc33-supply' and 'vccio-supply' in the bindings when I checkout
> linuxnext...
>

I just merged the Elan regulator/gpio support, it will show up in the next next.

> Oh, and also locally our tree has hacks in it to handle the fact that
> both atmel and elan will try to grab the same reset GPIO.  I'm nearly
> certain that Dmitry said that the current hacks we have wouldn't be
> appropriate for upstream.  I had some proposals for better solutions,
> but they were slightly more controversial.  In any case, I think all
> shipping devices ended up using one or the other of these two
> touchscreens (I forget which), so you could probably simplify and just
> pick one of them.  If old prototype devices don't work upstream it
> wouldn't be the end of the world.

I think if you pick Elan for this board it will cover majority (all?)
devices that actually shipped.

Thanks.

-- 
Dmitry


From andrew at lunn.ch  Fri Aug  7 15:10:52 2015
From: andrew at lunn.ch (Andrew Lunn)
Date: Sat, 8 Aug 2015 00:10:52 +0200
Subject: Armadaxp GPIO interrupts
In-Reply-To: <CAG1O52VTqkiGbQ2Et98WyL_vqAhcx6VXxPmHMpLnSJx5wCLe-w@mail.gmail.com>
References: <20150804153439.GA28673@lunn.ch>
 <CAG1O52W2Gy_6_DfewtUqoK_J+Y=KwVGyygNaPu2xyPM_ZkLfcQ@mail.gmail.com>
 <CAG1O52VQPpeGkA8bqYbPMTiT9Mua1yHi3H3osqJsHqm-RRKzow@mail.gmail.com>
 <20150805162155.GE32760@lunn.ch>
 <CAG1O52WPFfm+XGk01iUVWLu=-Dm7bcDVmhv3P8iQDH+HHjsLUA@mail.gmail.com>
 <20150806132926.GB19896@lunn.ch>
 <CAG1O52XUyPkgTTRKftujZBNK1=n6GBdWgBg_kq6SsC5XMaeU3w@mail.gmail.com>
 <20150806171312.GI13421@lunn.ch>
 <CAG1O52XO+5F11ELZ+7txWXTYPwmhQP5sVvcjdCiM_T1+ptfp=w@mail.gmail.com>
 <CAG1O52VTqkiGbQ2Et98WyL_vqAhcx6VXxPmHMpLnSJx5wCLe-w@mail.gmail.com>
Message-ID: <20150807221052.GJ26884@lunn.ch>

On Sat, Aug 08, 2015 at 02:24:04AM +0530, raghu MG wrote:
> Hi Andrew,
> I added these entries into armada-xp-gp.dtb
>  gpio_rtm {
>                 compatible = "gpio-rtm";
>                 #address-cells = <1>;
>                 #size-cells = <0>;
>                 pinctrl-0 = <&keys_pin>;
>                 pinctrl-names = "default";
> 
>                  rtm at 57 {
>                         label = "RTM JACKINOUT";
>                         gpios = <&gpio1 26 GPIO_ACTIVE_LOW>; /* GPIO 57 */
>                 };
>         };
> 
> So I understand the leaf nodes are specific purpose of
> GPIOs(input:keyboard,mouse,touchpad etc).
> 1)For the board I am working needs different implementation for GPIO
> 57 unlike input devices drivers driving GPIOs.
> 2)To implement the functionality I need to write driver specific to my
> board which will implement event specific to requirements.
> I hope I am going right here, can you name a simple driver(kernel
> source) where it would make my driver development easy.

Given the name "RTM JACKINOUT", how about

sound/soc/soc-jack.c

	Andrew


From sboyd at codeaurora.org  Fri Aug  7 15:28:23 2015
From: sboyd at codeaurora.org (Stephen Boyd)
Date: Fri, 7 Aug 2015 15:28:23 -0700
Subject: [PATCH 1/3] clk: versatile: Switch to assigned clock parents
In-Reply-To: <1438873513.2142.95.camel@arm.com>
References: <55BBB2FC.9030102@codeaurora.org>
 <1438386285-5070-1-git-send-email-sboyd@codeaurora.org>
 <1438386285-5070-2-git-send-email-sboyd@codeaurora.org>
 <1438610480.2142.14.camel@arm.com>
 <55BFAB11.7080600@codeaurora.org>
 <1438770574.2142.80.camel@arm.com>
 <55C24E56.3020004@codeaurora.org>
 <1438873513.2142.95.camel@arm.com>
Message-ID: <20150807222823.GB16477@codeaurora.org>

On 08/06, Pawel Moll wrote:
> On Wed, 2015-08-05 at 18:56 +0100, Stephen Boyd wrote:
> > On 08/05/2015 03:29 AM, Pawel Moll wrote:
> > >
> > > Right, that's probably my fault. The sp810 nodes appeared in the VE
> > > trees very early (in terms of the "DT era"), when we weren't so strict
> > > about documentation. So far, it would be fairly simple, something like
> > > the text below - feel free to take it, mend it, extend it with your
> > > changes and include in the series:
> > >
> > > Thanks!
> > 
> > Great! Can you please provide your signed-off-by? 
> 
> Sure. 

Thanks! I've put that patch before my series and squashed this into patch 1/3.

----8<----
diff --git a/Documentation/devicetree/bindings/arm/sp810.txt b/Documentation/devicetree/bindings/arm/sp810.txt
index 440ee0892a4d..6808fb5dee40 100644
--- a/Documentation/devicetree/bindings/arm/sp810.txt
+++ b/Documentation/devicetree/bindings/arm/sp810.txt
@@ -24,12 +24,23 @@ Required properties:
 - clock-output-names: from the common clock bindings;
 		should be: "timerclken0", "timerclken1", "timerclken2", "timerclken3"
 
+- assigned-clocks: from the common clock binding;
+		should be: clock specifier for each output clock of this
+		provider node
+
+- assigned-clock-parents: from the common clock binding;
+		should be: clock specifier of input clock listed in clocks
+		property with the highest frequency
+
 Example:
-	sysctl at 020000 {
+	v2m_sysctl: sysctl at 020000 {
 		compatible = "arm,sp810", "arm,primecell";
 		reg = <0x020000 0x1000>;
 		clocks = <&v2m_refclk32khz>, <&v2m_refclk1mhz>, <&smbclk>;
 		clock-names = "refclk", "timclk", "apb_pclk";
 		#clock-cells = <1>;
 		clock-output-names = "timerclken0", "timerclken1", "timerclken2", "timerclken3";
+		assigned-clocks = <&v2m_sysctl 0>, <&v2m_sysctl 1>, <&v2m_sysctl 3>, <&v2m_sysctl 3>;
+		assigned-clock-parents = <&v2m_refclk1mhz>, <&v2m_refclk1mhz>, <&v2m_refclk1mhz>, <&v2m_refclk1mhz>;
+
 	};
-- 
Qualcomm Innovation Center, Inc. is a member of Code Aurora Forum,
a Linux Foundation Collaborative Project


From wsa at the-dreams.de  Fri Aug  7 15:34:56 2015
From: wsa at the-dreams.de (Wolfram Sang)
Date: Sat, 8 Aug 2015 00:34:56 +0200
Subject: [PATCH 0/8] misc: remove boundary checks from bin attr users
In-Reply-To: <55C4D9B2.3000708@mleia.com>
References: <1437945502-27944-1-git-send-email-vz@mleia.com>
 <20150807161055.GD25357@katana> <55C4D9B2.3000708@mleia.com>
Message-ID: <20150807223456.GA1527@katana>


> if we're talking about this particular series, you should have them in
> your mailbox, since you have them applied in wsa/i2c/for-next:

Those are already in linus tree. I mean all drivers which use struct
i2c_driver. Or do you prefer they go via Greg? I am fine with both.

-------------- next part --------------
A non-text attachment was scrubbed...
Name: signature.asc
Type: application/pgp-signature
Size: 819 bytes
Desc: Digital signature
URL: <http://lists.infradead.org/pipermail/linux-arm-kernel/attachments/20150808/6047f4e5/attachment.sig>

From heiko at sntech.de  Fri Aug  7 15:46:20 2015
From: heiko at sntech.de (Heiko =?ISO-8859-1?Q?St=FCbner?=)
Date: Sat, 08 Aug 2015 00:46:20 +0200
Subject: [PATCH v2 4/8] drm: rockchip/dp: add rockchip platform dp driver
In-Reply-To: <1438944380-18897-1-git-send-email-ykk@rock-chips.com>
References: <1438943674-18191-1-git-send-email-ykk@rock-chips.com>
 <1438944380-18897-1-git-send-email-ykk@rock-chips.com>
Message-ID: <1730542.s7otqjtiXD@diego>

Hi Yakir,


I think this Rockchip portion is missing a devicetree binding.

You have the ability to power down the actual edp phy by using
grf_edp_iddq_en from GRF_SOC_CON12. This is similar to how the
rk3288 usb-phy gets put into a deeper state. So maybe you could
provide a phy driver (drivers/phy) for this similar to what the
exynos-dp does.

Some more stuff inline. But I guess by no means complete, as I'm
still trying to integrate this into my development-tree.


Am Freitag, 7. August 2015, 05:46:20 schrieb Yakir Yang:
> Rockchip have three clocks for dp controller, we leave pclk_edp
> to analogix_dp driver control, and keep the sclk_edp_24m and
> sclk_edp in platform driver.
> 
> Signed-off-by: Yakir Yang <ykk at rock-chips.com>
> ---
> Changes in v2: None
> 
>  drivers/gpu/drm/rockchip/Kconfig                |  10 +
>  drivers/gpu/drm/rockchip/Makefile               |   1 +
>  drivers/gpu/drm/rockchip/analogix_dp-rockchip.c | 419
> ++++++++++++++++++++++++ 3 files changed, 430 insertions(+)
>  create mode 100644 drivers/gpu/drm/rockchip/analogix_dp-rockchip.c
> 
> diff --git a/drivers/gpu/drm/rockchip/Kconfig
> b/drivers/gpu/drm/rockchip/Kconfig index 35215f6..096ed77 100644
> --- a/drivers/gpu/drm/rockchip/Kconfig
> +++ b/drivers/gpu/drm/rockchip/Kconfig
> @@ -25,3 +25,13 @@ config ROCKCHIP_DW_HDMI
>  	  for the Synopsys DesignWare HDMI driver. If you want to
>  	  enable HDMI on RK3288 based SoC, you should selet this
>  	  option.
> +
> +

nit: double blank line

> +config ROCKCHIP_ANALOGIX_DP
> +        tristate "Rockchip specific extensions for Analogix DP driver"
> +        depends on DRM_ROCKCHIP
> +        select DRM_ANALOGIX_DP
> +        help
> +	  This selects support for Rockchip SoC specific extensions
> +	  for the Analogix Core DP driver. If you want to enable DP
> +	  on RK3288 based SoC, you should selet this option.

[...]


> diff --git a/drivers/gpu/drm/rockchip/analogix_dp-rockchip.c
> b/drivers/gpu/drm/rockchip/analogix_dp-rockchip.c new file mode 100644
> index 0000000..2f86e5e
> --- /dev/null
> +++ b/drivers/gpu/drm/rockchip/analogix_dp-rockchip.c
> @@ -0,0 +1,419 @@
> +/*
> + * Rockchip SoC DP (Display Port) interface driver.
> + *
> + * Copyright (C) Fuzhou Rockchip Electronics Co., Ltd.
> + * Author: Andy Yan <andy.yan at rock-chips.com>
> + *         Yakir Yang <ykk at rock-chips.com>
> + *         Jeff Chen <jeff.chen at 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.
> + */
> +#include <drm/drmP.h>
> +#include <drm/drm_crtc_helper.h>
> +#include <drm/drm_panel.h>
> +#include <drm/drm_of.h>
> +#include <drm/drm_dp_helper.h>
> +
> +#include <linux/component.h>
> +#include <linux/clk.h>
> +#include <linux/mfd/syscon.h>
> +#include <linux/regmap.h>
> +#include <linux/reset.h>
> +
> +#include <video/of_videomode.h>
> +#include <video/videomode.h>
> +
> +#include <drm/bridge/analogix_dp.h>
> +
> +#include "rockchip_drm_drv.h"
> +#include "rockchip_drm_vop.h"
> +
> +#define encoder_to_dp(c) \
> +		container_of(c, struct rockchip_dp_device, encoder)
> +
> +#define plat_data_to_dp(pd) \
> +		container_of(pd, struct rockchip_dp_device, plat_data)
> +
> +/* dp grf register offset */
> +#define DP_VOP_SEL                              0x025c /* grf_soc_con6 */
> +#define DP_REF_CLK_SEL                          0x0274 /* grf_soc_con12 */
> +
> +#define GRF_DP_REF_CLK_SEL_INTER                BIT(4)
> +#define DP_SEL_VOP_LIT				BIT(5)
> +
> +struct rockchip_dp_device {
> +	struct drm_device        *drm_dev;
> +	struct device            *dev;
> +	struct drm_encoder       encoder;
> +	struct drm_display_mode  mode;
> +
> +	struct clk               *clk_dp;
> +	struct clk               *clk_24m_parent;

this clk_24m_parent does not seem used at all

> +	struct clk               *clk_24m;
> +	struct regmap            *grf;
> +	struct reset_control     *rst;
> +
> +	struct analogix_dp_plat_data plat_data;
> +};
> +

[...]

> +static int rockchip_dp_init(struct rockchip_dp_device *dp)
> +{
> +	struct device *dev = dp->dev;
> +	struct device_node *np = dev->of_node;
> +	int ret;
> +
> +	dp->grf = syscon_regmap_lookup_by_phandle(np, "rockchip,grf");
> +	if (IS_ERR(dp->grf)) {
> +		dev_err(dev,
> +			"rk3288-dp needs rockchip,grf property\n");
> +		return PTR_ERR(dp->grf);
> +	}
> +
> +	dp->clk_dp = devm_clk_get(dev, "clk_dp");

I've looked at the manual, but couldn't find an actual clock-name
used there. Is it really "clk_dp" or should it just be "dp"?


> +	if (IS_ERR(dp->clk_dp)) {
> +		dev_err(dev, "cannot get clk_dp\n");
> +		return PTR_ERR(dp->clk_dp);
> +	}
> +
> +	dp->clk_24m = devm_clk_get(dev, "clk_dp_24m");

Same here, maybe "dp_24m".


> +	if (IS_ERR(dp->clk_24m)) {
> +		dev_err(dev, "cannot get clk_dp_24m\n");
> +		return PTR_ERR(dp->clk_24m);
> +	}

I think you're missing the pclk here (PCLK_EDP_CTRL) or is this part of
something else?



> +
> +	dp->rst = devm_reset_control_get(dev, "dp");
> +	if (IS_ERR(dp->rst)) {
> +		dev_err(dev, "failed to get reset\n");
> +		return PTR_ERR(dp->rst);
> +	}
> +
> +	ret = rockchip_dp_clk_enable(dp);
> +	if (ret < 0) {
> +		dev_err(dp->dev, "cannot enable dp clk %d\n", ret);
> +		return ret;
> +	}
> +
> +	ret = rockchip_dp_pre_init(dp);
> +	if (ret < 0) {
> +		dev_err(dp->dev, "failed to pre init %d\n", ret);
> +		return ret;
> +	}
> +
> +	return 0;
> +}

[...]

> +static int rockchip_dp_probe(struct platform_device *pdev)
> +{
> +	struct device *dev = &pdev->dev;
> +	struct device_node *panel_node;
> +	struct rockchip_dp_device *dp;
> +	struct drm_panel *panel;
> +
> +	panel_node = of_parse_phandle(dev->of_node, "rockchip,panel", 0);
> +	if (!panel_node) {
> +		DRM_ERROR("failed to find rockchip,panel dt node\n");
> +		return -ENODEV;
> +	}

Personally I would prefer to continue with the of-graph framework to
attach the panel instead of defining a special node. But I'm not
authorative on this. But that way the dts could then look like [0].

I've sucessfully modified the driver currently in use in Chromeos for my
dev-tree and have ported this change over onto your driver [1].


[0] https://github.com/mmind/linux-rockchip/blob/devel/somewhat-stable/arch/arm/boot/dts/rk3288-veyron-edp.dtsi#L76
[1]
---------- 8< -------------
diff --git a/drivers/gpu/drm/rockchip/analogix_dp-rockchip.c b/drivers/gpu/drm/rockchip/analogix_dp-rockchip.c
index e7cf9ab..24e872d 100644
--- a/drivers/gpu/drm/rockchip/analogix_dp-rockchip.c
+++ b/drivers/gpu/drm/rockchip/analogix_dp-rockchip.c
@@ -20,6 +20,7 @@
 #include <linux/component.h>
 #include <linux/clk.h>
 #include <linux/mfd/syscon.h>
+#include <linux/of_graph.h>
 #include <linux/regmap.h>
 #include <linux/reset.h>
 
@@ -335,14 +336,28 @@ static const struct component_ops rockchip_dp_component_ops = {
 static int rockchip_dp_probe(struct platform_device *pdev)
 {
 	struct device *dev = &pdev->dev;
-	struct device_node *panel_node;
+	struct device_node *panel_node, *port, *endpoint;
 	struct rockchip_dp_device *dp;
 	struct drm_panel *panel;
 
-	panel_node = of_parse_phandle(dev->of_node, "rockchip,panel", 0);
+	port = of_graph_get_port_by_id(dev->of_node, 1);
+	if (!port) {
+		dev_err(dev, "can't find output port\n");
+		return -EINVAL;
+	}
+
+	endpoint = of_get_child_by_name(port, "endpoint");
+	of_node_put(port);
+	if (!endpoint) {
+		dev_err(dev, "no output endpoint found\n");
+		return -EINVAL;
+	}
+
+	panel_node = of_graph_get_remote_port_parent(endpoint);
+	of_node_put(endpoint);
 	if (!panel_node) {
-		DRM_ERROR("failed to find rockchip,panel dt node\n");
-		return -ENODEV;
+		dev_err(&pdev->dev, "no output node found\n");
+		return -EINVAL;
 	}
 
 	panel = of_drm_find_panel(panel_node);
---------- 8< -------------



From heiko at sntech.de  Fri Aug  7 15:50:15 2015
From: heiko at sntech.de (Heiko =?ISO-8859-1?Q?St=FCbner?=)
Date: Sat, 08 Aug 2015 00:50:15 +0200
Subject: [PATCH v2 2/2] ARM: dts: rockchip: add veyron-minnie board
In-Reply-To: <CAKdAkRTVbGeDY2J_T1N1x1yQaq7vCnO71TVmQGAZAkMaQsz2qw@mail.gmail.com>
References: <1763907.pckMEaRNPs@diego>
 <CAD=FV=XVxxDzXkz7DuX47d=3MENzGkHrBYYDzH_KCKDpyORYYA@mail.gmail.com>
 <CAKdAkRTVbGeDY2J_T1N1x1yQaq7vCnO71TVmQGAZAkMaQsz2qw@mail.gmail.com>
Message-ID: <4355831.vggPnSTQsd@diego>

Am Freitag, 7. August 2015, 15:13:13 schrieb Dmitry Torokhov:
> On Fri, Aug 7, 2015 at 3:06 PM, Doug Anderson <dianders at chromium.org> wrote:
> > Heiko,
> > 
> > On Thu, Aug 6, 2015 at 10:37 AM, Heiko St?bner <heiko at sntech.de> wrote:
> >> +&i2c3 {
> >> +       status = "okay";
> >> +
> >> +       /*
> >> +        * Touchscreen pin control is shared between Atmel and Elan
> >> devices, +        * so we have to pull it up to the bus level.
> >> +        */
> >> +       pinctrl-names = "default";
> >> +       pinctrl-0 = <&i2c3_xfer &touch_int &touch_rst>;
> >> +
> >> +       clock-frequency = <400000>;
> >> +       i2c-scl-falling-time-ns = <50>;
> >> +       i2c-scl-rising-time-ns = <300>;
> >> +
> >> +       touchscreen at 10 {
> >> +               compatible = "elan,ekth3500";
> >> +               reg = <0x10>;
> >> +               interrupt-parent = <&gpio2>;
> >> +               interrupts = <14 IRQ_TYPE_EDGE_FALLING>;
> >> +               reset-gpios = <&gpio2 15 GPIO_ACTIVE_LOW>;
> >> +               vcc33-supply = <&vcc33_touch>;
> >> +               vccio-supply = <&vcc33_touch>;
> >> +       };
> >> +
> >> +       touchscreen at 4a {
> >> +               compatible = "atmel,atmel_mxt_ts";
> >> +               reg = <0x4a>;
> >> +               atmel,reset-gpios = <&gpio2 15 GPIO_ACTIVE_LOW>;
> >> +               avdd-supply = <&vcc5v_touch>;
> >> +               interrupt-parent = <&gpio2>;
> >> +               interrupts = <14 IRQ_TYPE_EDGE_FALLING>;
> >> +               vdd-supply = <&vcc33_touch>;
> > 
> > Technically I don't think most of these properties exist upstream, but
> > Dmitry (now CCed) might know more.
> > 
> > ...actually similar for elan.  At least I don't see 'reset-gpios', nor
> > 'vcc33-supply' and 'vccio-supply' in the bindings when I checkout
> > linuxnext...
> 
> I just merged the Elan regulator/gpio support, it will show up in the next
> next.
> > Oh, and also locally our tree has hacks in it to handle the fact that
> > both atmel and elan will try to grab the same reset GPIO.  I'm nearly
> > certain that Dmitry said that the current hacks we have wouldn't be
> > appropriate for upstream.  I had some proposals for better solutions,
> > but they were slightly more controversial.  In any case, I think all
> > shipping devices ended up using one or the other of these two
> > touchscreens (I forget which), so you could probably simplify and just
> > pick one of them.  If old prototype devices don't work upstream it
> > wouldn't be the end of the world.
> 
> I think if you pick Elan for this board it will cover majority (all?)
> devices that actually shipped.

I guess I'll simply drop the touchscreens for for this initial submission - at 
this point in time we don't have support for the internal display anyway, so I 
can sort out the touchscreens a bit later.

armsoc has a slightly early cutoff most of the time, so I'll try to land the 
initial support and worry about the smaller tidbits later :-)


Heiko


From khilman at kernel.org  Fri Aug  7 16:07:07 2015
From: khilman at kernel.org (Kevin Hilman)
Date: Fri, 07 Aug 2015 16:07:07 -0700
Subject: [PATCH 0/3] ARM: multi_v7_defconfig: Enable more OMAP family
 platforms
In-Reply-To: <20150805102234.GZ16878@atomide.com> (Tony Lindgren's message of
 "Wed, 5 Aug 2015 03:22:34 -0700")
References: <1428614121-3374-1-git-send-email-nm@ti.com>
 <20150805102234.GZ16878@atomide.com>
Message-ID: <7hfv3uwvdw.fsf@deeprootsystems.com>

Tony Lindgren <tony at atomide.com> writes:

> Ping, looks like these are still pending. Probably should be
> applied directly by the arm-soc maintainers.

If these should go through arm-soc, please resend to:arm at kernel.org so
they make it into our queue of stuff to be reviewed/applied.

Kevin


From shawn.lin at rock-chips.com  Fri Aug  7 16:37:55 2015
From: shawn.lin at rock-chips.com (Shawn Lin)
Date: Sat, 8 Aug 2015 07:37:55 +0800
Subject: [RFC PATCH v4 1/9] mmc: dw_mmc: Add external dma interface support
In-Reply-To: <CAGhQ9VxUYvgGD=K3J3cQ0CNpCC-RfGE9cxhBHnTeAU2CmWkiKA@mail.gmail.com>
References: <1438843469-23807-1-git-send-email-shawn.lin@rock-chips.com>
 <1438843491-23853-1-git-send-email-shawn.lin@rock-chips.com>
 <CAGhQ9VxUYvgGD=K3J3cQ0CNpCC-RfGE9cxhBHnTeAU2CmWkiKA@mail.gmail.com>
Message-ID: <55C54153.2070709@rock-chips.com>

? 2015/8/8 5:32, Joachim Eastwood ??:
> Hi Shawn,
>
> On 6 August 2015 at 08:44, Shawn Lin <shawn.lin at rock-chips.com> wrote:
>> DesignWare MMC Controller can supports two types of DMA
>> mode: external dma and internal dma. We get a RK312x platform
>> integrated dw_mmc and ARM pl330 dma controller. This patch add
>> edmac ops to support these platforms. I've tested it on RK312x
>> platform with edmac mode and RK3288 platform with idmac mode.
>>
>> Signed-off-by: Shawn Lin <shawn.lin at rock-chips.com>
>
>> @@ -2256,26 +2373,30 @@ static irqreturn_t dw_mci_interrupt(int irq, void *dev_id)
>>
>>          }
>>
>> -#ifdef CONFIG_MMC_DW_IDMAC
>> -       /* Handle DMA interrupts */
>> -       if (host->dma_64bit_address == 1) {
>> -               pending = mci_readl(host, IDSTS64);
>> -               if (pending & (SDMMC_IDMAC_INT_TI | SDMMC_IDMAC_INT_RI)) {
>> -                       mci_writel(host, IDSTS64, SDMMC_IDMAC_INT_TI |
>> -                                                       SDMMC_IDMAC_INT_RI);
>> -                       mci_writel(host, IDSTS64, SDMMC_IDMAC_INT_NI);
>> -                       host->dma_ops->complete(host);
>> -               }
>> -       } else {
>> -               pending = mci_readl(host, IDSTS);
>> -               if (pending & (SDMMC_IDMAC_INT_TI | SDMMC_IDMAC_INT_RI)) {
>> -                       mci_writel(host, IDSTS, SDMMC_IDMAC_INT_TI |
>> -                                                       SDMMC_IDMAC_INT_RI);
>> -                       mci_writel(host, IDSTS, SDMMC_IDMAC_INT_NI);
>> -                       host->dma_ops->complete(host);
>> +       if (host->use_dma == TRANS_MODE_IDMAC) {
>
> Doing:
> if (host->use_dma != TRANS_MODE_IDMAC)
>      return IRQ_HANDLED;
>

Okay.

> Could save you the extra level of identation you add below.
>
>> +               /* Handle DMA interrupts */
>> +               if (host->dma_64bit_address == 1) {
>> +                       pending = mci_readl(host, IDSTS64);
>> +                       if (pending & (SDMMC_IDMAC_INT_TI |
>> +                                      SDMMC_IDMAC_INT_RI)) {
>> +                               mci_writel(host, IDSTS64,
>> +                                          SDMMC_IDMAC_INT_TI |
>> +                                          SDMMC_IDMAC_INT_RI);
>> +                               mci_writel(host, IDSTS64, SDMMC_IDMAC_INT_NI);
>> +                               host->dma_ops->complete((void *)host);
>> +                       }
>> +               } else {
>> +                       pending = mci_readl(host, IDSTS);
>> +                       if (pending & (SDMMC_IDMAC_INT_TI |
>> +                                      SDMMC_IDMAC_INT_RI)) {
>> +                               mci_writel(host, IDSTS,
>> +                                          SDMMC_IDMAC_INT_TI |
>> +                                          SDMMC_IDMAC_INT_RI);
>> +                               mci_writel(host, IDSTS, SDMMC_IDMAC_INT_NI);
>> +                               host->dma_ops->complete((void *)host);
>> +                       }
>>                  }
>>          }
>> -#endif
>>
>>          return IRQ_HANDLED;
>>   }
>
>
>> @@ -2437,6 +2567,21 @@ static void dw_mci_cleanup_slot(struct dw_mci_slot *slot, unsigned int id)
>>   static void dw_mci_init_dma(struct dw_mci *host)
>>   {
>>          int addr_config;
>> +       int trans_mode;
>> +       struct device *dev = host->dev;
>> +       struct device_node *np = dev->of_node;
>> +
>> +       /* Check tansfer mode */
>> +       trans_mode = (mci_readl(host, HCON) >> 16) & 0x3;
>
> I think it would be nice if you could add some defines for 16 and 0x03
> or add a macro like SDMMC_GET_FCNT() that is in dw_mmc.h.
>

yes, it's better to avoid magic number for register operation to make
others understand w/o checking databook for details. And might more than 
one (e.g "Check ADDR_CONFIG bit in HCON to find IDMAC address bus 
width") should be modified.

Although one patch only do one thing, I will drop by to make it in v5.

>> +       if (trans_mode == 0) {
>> +               trans_mode = TRANS_MODE_IDMAC;
>> +       } else if (trans_mode == 1 || trans_mode == 2) {
>> +               trans_mode = TRANS_MODE_EDMAC;
>> +       } else {
>> +               trans_mode = TRANS_MODE_PIO;
>> +               goto no_dma;
>> +       }
>> +
>>          /* Check ADDR_CONFIG bit in HCON to find IDMAC address bus width */
>>          addr_config = (mci_readl(host, HCON) >> 27) & 0x01;
>
> I'll try to get this patch tested on my lpc18xx platform soon.
> btw, the HCON reg on lpc18xx reads as 0x00e42cc1 (address 0x40004070).
>

yes, HCON[17:16] is 2b'00 means your lpc18xx use IDMAC.

>
> regard,
> Joachim Eastwood
>
>
>


-- 
Shawn Lin



From khilman at kernel.org  Fri Aug  7 16:45:36 2015
From: khilman at kernel.org (Kevin Hilman)
Date: Fri, 07 Aug 2015 16:45:36 -0700
Subject: [PATCH 5/9] ARM: common: Introduce PM domains for CPUs/clusters
In-Reply-To: <CAL_JsqK67=DTtjZwwnonObLDjLbahkREfm0RvyXVV95bhR-d4Q@mail.gmail.com>
 (Rob Herring's message of "Wed, 5 Aug 2015 22:14:51 -0500")
References: <1438731339-58317-1-git-send-email-lina.iyer@linaro.org>
 <1438731339-58317-6-git-send-email-lina.iyer@linaro.org>
 <CAL_JsqK67=DTtjZwwnonObLDjLbahkREfm0RvyXVV95bhR-d4Q@mail.gmail.com>
Message-ID: <7hd1yyvf1b.fsf@deeprootsystems.com>

Rob Herring <robherring2 at gmail.com> writes:

> On Tue, Aug 4, 2015 at 6:35 PM, Lina Iyer <lina.iyer at linaro.org> wrote:
>> Define and add Generic PM domains (genpd) for ARM CPU clusters. Many
>> new

@Lina: I know you inherited this from some proof-of-concept code frome me, so
I'm partially to blame, but...

There's really nothing ARM specific about this driver.  

>> SoCs group CPUs as clusters. Clusters share common resources like GIC,
>> power rail, caches, VFP, Coresight etc. When all CPUs in the cluster are
>> idle, these shared resources may also be put in their idle state.
>>
>> The idle time between the last CPU entering idle and a CPU resuming
>> execution is an opportunity for these shared resources to be powered
>> down. Generic PM domain provides a framework for defining such power
>> domains and attach devices to the domain. When the devices in the domain
>> are idle at runtime, the domain would also be suspended and resumed
>> before the first of the devices resume execution.
>>
>> We define a generic PM domain for each cluster and attach CPU devices in
>> the cluster to that PM domain. The DT definitions for the SoC describe
>> this relationship. Genpd callbacks for power_on and power_off can then
>> be used to power up/down the shared resources for the domain.
>
> [...]
>
>> +ARM CPU Power domains
>> +
>> +The device tree allows describing of CPU power domains in a SoC. In ARM SoC,
>> +CPUs may be grouped as clusters. A cluster may have CPUs, GIC, Coresight,
>> +caches, VFP and power controller and other peripheral hardware. Generally,
>> +when the CPUs in the cluster are idle/suspended, the shared resources may also
>> +be suspended and resumed before any of the CPUs resume execution.
>> +
>> +CPUs are the defined as the PM domain consumers and there is a PM domain
>> +provider for the CPUs. Bindings for generic PM domains (genpd) is described in
>> +[1].
>> +
>> +The ARM CPU PM domain follows the same binding convention as any generic PM
>> +domain. Additional binding properties are -
>> +
>> +- compatible:
>> +       Usage: required
>> +       Value type: <string>
>> +       Definition: Must also have
>> +                       "arm,pd"
>> +               inorder to initialize the genpd provider as ARM CPU PM domain.
>
> A compatible string should represent a particular h/w block. If it is
> generic, it should represent some sort of standard programming
> interface (e.g, AHCI, EHCI, etc.). This doesn't seem to be either and
> is rather just a mapping of what "driver" you want to use.
>
> I would expect that identifying a cpu's or cluster's power domain
> would be done by a phandle between the cpu/cluster node and power
> domain node. 

That's correct, the CPU nodes (and other nodes in the cluster like GIC,
Coresight, etc.) would have phandles to the cluster power domain node.

But this series is meant to create the driver & binding for those cluster
power domain(s), so the question is how exactly describe it.

What we're trying to get to is binding to describe a powerdomain of a
generic CPU cluster, but of course the actual programming interface for
powering down the cluster will be platform specific.  In earlier RFC
versions, Lina had proposed ways for platforms to register some
low-level hooks with this generic driver for the platform-specific bits,
but if you have some other suggests, we'd be all ears.

Kevin






From sboyd at codeaurora.org  Fri Aug  7 16:52:31 2015
From: sboyd at codeaurora.org (Stephen Boyd)
Date: Fri, 7 Aug 2015 16:52:31 -0700
Subject: [PATCH v7 01/13] clk: qcom: Add support for GDSCs
In-Reply-To: <55C19FA4.4070402@codeaurora.org>
References: <1438076046-4706-1-git-send-email-rnayak@codeaurora.org>
 <1438076046-4706-2-git-send-email-rnayak@codeaurora.org>
 <20150803192427.GA7096@codeaurora.org>
 <55C19FA4.4070402@codeaurora.org>
Message-ID: <20150807235230.GE16477@codeaurora.org>

On 08/05, Rajendra Nayak wrote:
> 
> 
> On 08/04/2015 12:54 AM, Stephen Boyd wrote:
> >On 07/28, Rajendra Nayak wrote:
> >>+
> >>+#define PWR_ON_MASK		BIT(31)
> >>+#define EN_REST_WAIT_MASK	GENMASK(23, 20)
> >>+#define EN_FEW_WAIT_MASK	GENMASK(19, 16)
> >>+#define CLK_DIS_WAIT_MASK	GENMASK(15, 12)
> >
> >This trips up some static checker...
> >
> >drivers/clk/qcom/gdsc.c:234:53: warning: cast truncates bits from
> >constant value (fffffffffff006 becomes fffff006)
> >
> >So I think we can use GENMASK_ULL here instead.
> 
> Sure. btw, what static checker is this? I did not see it with sparse.

Pretty sure this was with sparse. Which now has me concerned that
my sparse is old!

$ sparse --version
v0.5.0-47-g0f71312959ed

But I updated to

$ sparse --version
v0.5.0-51-ga53cea28f0db

And I still see it.

-- 
Qualcomm Innovation Center, Inc. is a member of Code Aurora Forum,
a Linux Foundation Collaborative Project


From sboyd at codeaurora.org  Fri Aug  7 16:59:49 2015
From: sboyd at codeaurora.org (Stephen Boyd)
Date: Fri, 7 Aug 2015 16:59:49 -0700
Subject: [PATCH 1/3] clk: berlin: add cpuclk
In-Reply-To: <1438259752-16320-2-git-send-email-antoine.tenart@free-electrons.com>
References: <1438259752-16320-1-git-send-email-antoine.tenart@free-electrons.com>
 <1438259752-16320-2-git-send-email-antoine.tenart@free-electrons.com>
Message-ID: <20150807235949.GB9678@codeaurora.org>

On 07/30, Antoine Tenart wrote:
> Add cpuclk in the Berlin BG2Q clock driver. This clk has a divider
> fixed to 1.
> 
> Signed-off-by: Antoine Tenart <antoine.tenart at free-electrons.com>
> ---

I didn't get anything besides 1/3, but this looks ok. If you
don't want us to take this through clk-tree, feel to take my ack

Acked-by: Stephen Boyd <sboyd at codeaurora.org>

>  drivers/clk/berlin/bg2q.c            | 14 +++++++-------
>  include/dt-bindings/clock/berlin2q.h |  3 ++-
>  2 files changed, 9 insertions(+), 8 deletions(-)
> 
> diff --git a/drivers/clk/berlin/bg2q.c b/drivers/clk/berlin/bg2q.c
> index 221f40c2b850..72d2f3500db8 100644
> --- a/drivers/clk/berlin/bg2q.c
> +++ b/drivers/clk/berlin/bg2q.c
> @@ -45,7 +45,7 @@
>  #define REG_SDIO0XIN_CLKCTL	0x0158
>  #define REG_SDIO1XIN_CLKCTL	0x015c
>  
> -#define	MAX_CLKS 27
> +#define	MAX_CLKS 28

Maybe you should move this into the dt-bindings.h file.

-- 
Qualcomm Innovation Center, Inc. is a member of Code Aurora Forum,
a Linux Foundation Collaborative Project


From rafael at kernel.org  Fri Aug  7 17:05:55 2015
From: rafael at kernel.org (Rafael J. Wysocki)
Date: Sat, 8 Aug 2015 02:05:55 +0200
Subject: [PATCH 2/2] net, thunder, bgx: Add support for ACPI binding.
In-Reply-To: <20150807175127.GB12013@leverpostej>
References: <1438907590-29649-1-git-send-email-ddaney.cavm@gmail.com>
 <1438907590-29649-3-git-send-email-ddaney.cavm@gmail.com>
 <20150807140106.GE7646@leverpostej>
 <55C4ECC6.7050908@caviumnetworks.com>
 <20150807175127.GB12013@leverpostej>
Message-ID: <CAJZ5v0gc=bo3ayO7aWq19Hh_205YC52wqXGbbM5vxR1atXm+oA@mail.gmail.com>

Hi Mark,

On Fri, Aug 7, 2015 at 7:51 PM, Mark Rutland <mark.rutland at arm.com> wrote:
> [Correcting the devicetree list address, which I typo'd in my original
> reply]
>
>> >> +static const char * const addr_propnames[] = {
>> >> +  "mac-address",
>> >> +  "local-mac-address",
>> >> +  "address",
>> >> +};
>> >
>> > If these are going to be generally necessary, then we should get them
>> > adopted as standardised _DSD properties (ideally just one of them).
>>
>> As far as I can tell, and please correct me if I am wrong, ACPI-6.0
>> doesn't contemplate MAC addresses.
>>
>> Today we are using "mac-address", which is an Integer containing the MAC
>> address in its lowest order 48 bits in Little-Endian byte order.
>>
>> The hardware and ACPI tables are here today, and we would like to
>> support it.  If some future ACPI specification specifies a standard way
>> to do this, we will probably adapt the code to do this in a standard manner.
>>
>>
>> >
>> > [...]
>> >
>> >> +static acpi_status bgx_acpi_register_phy(acpi_handle handle,
>> >> +                                   u32 lvl, void *context, void **rv)
>> >> +{
>> >> +  struct acpi_reference_args args;
>> >> +  const union acpi_object *prop;
>> >> +  struct bgx *bgx = context;
>> >> +  struct acpi_device *adev;
>> >> +  struct device *phy_dev;
>> >> +  u32 phy_id;
>> >> +
>> >> +  if (acpi_bus_get_device(handle, &adev))
>> >> +          goto out;
>> >> +
>> >> +  SET_NETDEV_DEV(&bgx->lmac[bgx->lmac_count].netdev, &bgx->pdev->dev);
>> >> +
>> >> +  acpi_get_mac_address(adev, bgx->lmac[bgx->lmac_count].mac);
>> >> +
>> >> +  bgx->lmac[bgx->lmac_count].lmacid = bgx->lmac_count;
>> >> +
>> >> +  if (acpi_dev_get_property_reference(adev, "phy-handle", 0, &args))
>> >> +          goto out;
>> >> +
>> >> +  if (acpi_dev_get_property(args.adev, "phy-channel", ACPI_TYPE_INTEGER, &prop))
>> >> +          goto out;
>> >
>> > Likewise for any inter-device properties, so that we can actually handle
>> > them in a generic fashion, and avoid / learn from the mistakes we've
>> > already handled with DT.
>>
>> This is the fallacy of the ACPI is superior to DT argument.  The
>> specification of PHY topology and MAC addresses is well standardized in
>> DT, there is no question about what the proper way to specify it is.
>> Under ACPI, it is the Wild West, there is no specification, so each
>> system design is forced to invent something, and everybody comes up with
>> an incompatible implementation.
>
> Indeed.
>
> If ACPI is going to handle it, it should handle it properly. I really
> don't see the point in bodging properties together in a less standard
> manner than DT, especially for inter-device relationships.
>
> Doing so is painful for _everyone_, and it's extremely unlikely that
> other ACPI-aware OSs will actually support these custom descriptions,
> making this Linux-specific, and breaking the rationale for using ACPI in
> the first place -- a standard that says "just do non-standard stuff" is
> not a usable standard.
>
> For intra-device properties, we should standardise what we can, but
> vendor-specific stuff is ok -- this can be self-contained within a
> driver.
>
> For inter-device relationships ACPI _must_ gain a better model of
> componentised devices. It's simply unworkable otherwise, and as you
> point out it's fallacious to say that because ACPI is being used that
> something is magically industry standard, portable, etc.
>
> This is not your problem in particular; the entire handling of _DSD so
> far is a joke IMO.

It is actually useful to people as far as I can say.

Also, if somebody is going to use properties with ACPI, why whould
they use a different set of properties with DT?

Wouldn't it be more reasonable to use the same set in both cases?

Thanks,
Rafael


From ddaney at caviumnetworks.com  Fri Aug  7 17:11:57 2015
From: ddaney at caviumnetworks.com (David Daney)
Date: Fri, 7 Aug 2015 17:11:57 -0700
Subject: [PATCH 2/2] net, thunder, bgx: Add support for ACPI binding.
In-Reply-To: <CAJZ5v0gc=bo3ayO7aWq19Hh_205YC52wqXGbbM5vxR1atXm+oA@mail.gmail.com>
References: <1438907590-29649-1-git-send-email-ddaney.cavm@gmail.com>
 <1438907590-29649-3-git-send-email-ddaney.cavm@gmail.com>
 <20150807140106.GE7646@leverpostej> <55C4ECC6.7050908@caviumnetworks.com>
 <20150807175127.GB12013@leverpostej>
 <CAJZ5v0gc=bo3ayO7aWq19Hh_205YC52wqXGbbM5vxR1atXm+oA@mail.gmail.com>
Message-ID: <55C5494D.5010903@caviumnetworks.com>

On 08/07/2015 05:05 PM, Rafael J. Wysocki wrote:
> Hi Mark,
>
> On Fri, Aug 7, 2015 at 7:51 PM, Mark Rutland <mark.rutland at arm.com> wrote:
>> [Correcting the devicetree list address, which I typo'd in my original
>> reply]
>>
>>>>> +static const char * const addr_propnames[] = {
>>>>> +  "mac-address",
>>>>> +  "local-mac-address",
>>>>> +  "address",
>>>>> +};
>>>>
>>>> If these are going to be generally necessary, then we should get them
>>>> adopted as standardised _DSD properties (ideally just one of them).
>>>
>>> As far as I can tell, and please correct me if I am wrong, ACPI-6.0
>>> doesn't contemplate MAC addresses.
>>>
>>> Today we are using "mac-address", which is an Integer containing the MAC
>>> address in its lowest order 48 bits in Little-Endian byte order.
>>>
>>> The hardware and ACPI tables are here today, and we would like to
>>> support it.  If some future ACPI specification specifies a standard way
>>> to do this, we will probably adapt the code to do this in a standard manner.
>>>
>>>
>>>>
>>>> [...]
>>>>
>>>>> +static acpi_status bgx_acpi_register_phy(acpi_handle handle,
>>>>> +                                   u32 lvl, void *context, void **rv)
>>>>> +{
>>>>> +  struct acpi_reference_args args;
>>>>> +  const union acpi_object *prop;
>>>>> +  struct bgx *bgx = context;
>>>>> +  struct acpi_device *adev;
>>>>> +  struct device *phy_dev;
>>>>> +  u32 phy_id;
>>>>> +
>>>>> +  if (acpi_bus_get_device(handle, &adev))
>>>>> +          goto out;
>>>>> +
>>>>> +  SET_NETDEV_DEV(&bgx->lmac[bgx->lmac_count].netdev, &bgx->pdev->dev);
>>>>> +
>>>>> +  acpi_get_mac_address(adev, bgx->lmac[bgx->lmac_count].mac);
>>>>> +
>>>>> +  bgx->lmac[bgx->lmac_count].lmacid = bgx->lmac_count;
>>>>> +
>>>>> +  if (acpi_dev_get_property_reference(adev, "phy-handle", 0, &args))
>>>>> +          goto out;
>>>>> +
>>>>> +  if (acpi_dev_get_property(args.adev, "phy-channel", ACPI_TYPE_INTEGER, &prop))
>>>>> +          goto out;
>>>>
>>>> Likewise for any inter-device properties, so that we can actually handle
>>>> them in a generic fashion, and avoid / learn from the mistakes we've
>>>> already handled with DT.
>>>
>>> This is the fallacy of the ACPI is superior to DT argument.  The
>>> specification of PHY topology and MAC addresses is well standardized in
>>> DT, there is no question about what the proper way to specify it is.
>>> Under ACPI, it is the Wild West, there is no specification, so each
>>> system design is forced to invent something, and everybody comes up with
>>> an incompatible implementation.
>>
>> Indeed.
>>
>> If ACPI is going to handle it, it should handle it properly. I really
>> don't see the point in bodging properties together in a less standard
>> manner than DT, especially for inter-device relationships.
>>
>> Doing so is painful for _everyone_, and it's extremely unlikely that
>> other ACPI-aware OSs will actually support these custom descriptions,
>> making this Linux-specific, and breaking the rationale for using ACPI in
>> the first place -- a standard that says "just do non-standard stuff" is
>> not a usable standard.
>>
>> For intra-device properties, we should standardise what we can, but
>> vendor-specific stuff is ok -- this can be self-contained within a
>> driver.
>>
>> For inter-device relationships ACPI _must_ gain a better model of
>> componentised devices. It's simply unworkable otherwise, and as you
>> point out it's fallacious to say that because ACPI is being used that
>> something is magically industry standard, portable, etc.
>>
>> This is not your problem in particular; the entire handling of _DSD so
>> far is a joke IMO.
>
> It is actually useful to people as far as I can say.
>
> Also, if somebody is going to use properties with ACPI, why whould
> they use a different set of properties with DT?
>
> Wouldn't it be more reasonable to use the same set in both cases?

Yes, but there is still quite a bit of leeway to screw things up.


FWIW:  http://www.uefi.org/sites/default/files/resources/nic-request-v2.pdf

This actually seems to have been adopted by the UEFI people as a
"Standard", I am not sure where a record of this is kept though.

So, we are changing our firmware to use this standard (which is quite
similar the the DT with respect to MAC addresses).

Thanks,
David Daney


From timur at codeaurora.org  Fri Aug  7 17:16:33 2015
From: timur at codeaurora.org (Timur Tabi)
Date: Fri,  7 Aug 2015 19:16:33 -0500
Subject: [PATCH 1/3] [v2] hvc_dcc: don't ignore errors during initialization
Message-ID: <1438992995-22610-1-git-send-email-timur@codeaurora.org>

hvc_instantiate() and hvc_alloc() return errors if they fail, so don't
ignore them.

Signed-off-by: Timur Tabi <timur at codeaurora.org>
---
 drivers/tty/hvc/hvc_dcc.c | 17 +++++++++++++----
 1 file changed, 13 insertions(+), 4 deletions(-)

diff --git a/drivers/tty/hvc/hvc_dcc.c b/drivers/tty/hvc/hvc_dcc.c
index 809920d..47654ea 100644
--- a/drivers/tty/hvc/hvc_dcc.c
+++ b/drivers/tty/hvc/hvc_dcc.c
@@ -70,20 +70,29 @@ static const struct hv_ops hvc_dcc_get_put_ops = {
 
 static int __init hvc_dcc_console_init(void)
 {
+	int ret;
+
+	/* This always runs on boot core */
 	if (!hvc_dcc_check())
 		return -ENODEV;
 
-	hvc_instantiate(0, 0, &hvc_dcc_get_put_ops);
-	return 0;
+	/* Returns -1 if error */
+	ret = hvc_instantiate(0, 0, &hvc_dcc_get_put_ops);
+
+	return ret < 0 ? -ENODEV : 0;
 }
 console_initcall(hvc_dcc_console_init);
 
 static int __init hvc_dcc_init(void)
 {
+	struct hvc_struct *p;
+
+	/* This can run on any core */
 	if (!hvc_dcc_check())
 		return -ENODEV;
 
-	hvc_alloc(0, 0, &hvc_dcc_get_put_ops, 128);
-	return 0;
+	p = hvc_alloc(0, 0, &hvc_dcc_get_put_ops, 128);
+
+	return PTR_ERR_OR_ZERO(p);
 }
 device_initcall(hvc_dcc_init);
-- 
Qualcomm Innovation Center, Inc.
The Qualcomm Innovation Center, Inc. is a member of the Code Aurora Forum,
a Linux Foundation Collaborative Project.



From timur at codeaurora.org  Fri Aug  7 17:16:35 2015
From: timur at codeaurora.org (Timur Tabi)
Date: Fri,  7 Aug 2015 19:16:35 -0500
Subject: [PATCH 3/3] [v2] hvc_dcc: disable user-space access to DCC
In-Reply-To: <1438992995-22610-1-git-send-email-timur@codeaurora.org>
References: <1438992995-22610-1-git-send-email-timur@codeaurora.org>
Message-ID: <1438992995-22610-3-git-send-email-timur@codeaurora.org>

If the DCC driver loads, then disable user-space access to the DCC so that
we don't have two entities trying to access the DCC at the same time.

Signed-off-by: Timur Tabi <timur at codeaurora.org>
---
 arch/arm/include/asm/dcc.h   | 15 +++++++++++++++
 arch/arm64/include/asm/dcc.h | 11 +++++++++++
 drivers/tty/hvc/hvc_dcc.c    |  2 ++
 3 files changed, 28 insertions(+)

diff --git a/arch/arm/include/asm/dcc.h b/arch/arm/include/asm/dcc.h
index b74899d..c50056b 100644
--- a/arch/arm/include/asm/dcc.h
+++ b/arch/arm/include/asm/dcc.h
@@ -9,8 +9,11 @@
  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
  * GNU General Public License for more details.
  */
+#ifndef __ASM_DCC_H
+#define __ASM_DCC_H
 
 #include <asm/barrier.h>
+#include <asm/hardware/cp14.h>
 
 static inline u32 __dcc_getstatus(void)
 {
@@ -39,3 +42,15 @@ static inline void __dcc_putchar(char c)
 		: "r" (c));
 	isb();
 }
+
+static inline void __dcc_initialize(void)
+{
+	u32 val;
+
+	/* Disable user-space access to DCC */
+	val = MRC14(0, c0, c1, 0);
+	val |= 1 << 12; /* DSCR[Comms] */
+	MCR14(val, 0, c0, c1, 0);
+}
+
+#endif
diff --git a/arch/arm64/include/asm/dcc.h b/arch/arm64/include/asm/dcc.h
index fcb8d7d..a6496f2 100644
--- a/arch/arm64/include/asm/dcc.h
+++ b/arch/arm64/include/asm/dcc.h
@@ -49,4 +49,15 @@ static inline void __dcc_putchar(char c)
 	isb();
 }
 
+static inline void __dcc_initialize(void)
+{
+	u32 val;
+
+	/* Disable user-space access to DCC */
+	asm volatile ("mrs %0, mdscr_el1\n"
+		"	orr %0, %0, #4096\n" /* Set the TDCC bit */
+		"	msr mdscr_el1, %0\n"
+		: "=r" (val));
+}
+
 #endif
diff --git a/drivers/tty/hvc/hvc_dcc.c b/drivers/tty/hvc/hvc_dcc.c
index 47654ea..e260acb 100644
--- a/drivers/tty/hvc/hvc_dcc.c
+++ b/drivers/tty/hvc/hvc_dcc.c
@@ -76,6 +76,8 @@ static int __init hvc_dcc_console_init(void)
 	if (!hvc_dcc_check())
 		return -ENODEV;
 
+	__dcc_initialize();
+
 	/* Returns -1 if error */
 	ret = hvc_instantiate(0, 0, &hvc_dcc_get_put_ops);
 
-- 
Qualcomm Innovation Center, Inc.
The Qualcomm Innovation Center, Inc. is a member of the Code Aurora Forum,
a Linux Foundation Collaborative Project.



From timur at codeaurora.org  Fri Aug  7 17:16:34 2015
From: timur at codeaurora.org (Timur Tabi)
Date: Fri,  7 Aug 2015 19:16:34 -0500
Subject: [PATCH 2/3] [v4] ARM64: TTY: hvc_dcc: Add support for ARM64 dcc
In-Reply-To: <1438992995-22610-1-git-send-email-timur@codeaurora.org>
References: <1438992995-22610-1-git-send-email-timur@codeaurora.org>
Message-ID: <1438992995-22610-2-git-send-email-timur@codeaurora.org>

From: Abhimanyu Kapur <abhimany at codeaurora.org>

Add support for debug communications channel based
hvc console for arm64 cpus.

Signed-off-by: Abhimanyu Kapur <abhimany at codeaurora.org>
Signed-off-by: Timur Tabi <timur at codeaurora.org>
---
 arch/arm64/include/asm/dcc.h | 52 ++++++++++++++++++++++++++++++++++++++++++++
 drivers/tty/hvc/Kconfig      |  2 +-
 2 files changed, 53 insertions(+), 1 deletion(-)
 create mode 100644 arch/arm64/include/asm/dcc.h

diff --git a/arch/arm64/include/asm/dcc.h b/arch/arm64/include/asm/dcc.h
new file mode 100644
index 0000000..fcb8d7d
--- /dev/null
+++ b/arch/arm64/include/asm/dcc.h
@@ -0,0 +1,52 @@
+/* Copyright (c) 2014-2015 The Linux Foundation. All rights reserved.
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License version 2 and
+ * only 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.
+ *
+ * A call to __dcc_getchar() or __dcc_putchar() is typically followed by
+ * a call to __dcc_getstatus().  We want to make sure that the CPU does
+ * not speculative read the DCC status before executing the read or write
+ * instruction.  That's what the ISBs are for.
+ *
+ * The 'volatile' ensures that the compiler does not cache the status bits,
+ * and instead reads the DCC register every time.
+ */
+#ifndef __ASM_DCC_H
+#define __ASM_DCC_H
+
+#include <asm/barrier.h>
+
+static inline u32 __dcc_getstatus(void)
+{
+	u32 ret;
+
+	asm volatile("mrs %0, mdccsr_el0" : "=r" (ret));
+
+	return ret;
+}
+
+static inline char __dcc_getchar(void)
+{
+	char c;
+
+	asm volatile("mrs %0, dbgdtrrx_el0" : "=r" (c));
+	isb();
+
+	return c;
+}
+
+static inline void __dcc_putchar(char c)
+{
+	asm volatile("msr dbgdtrtx_el0, %0"
+			: /* No output register */
+			: "r" (c));
+	isb();
+}
+
+#endif
diff --git a/drivers/tty/hvc/Kconfig b/drivers/tty/hvc/Kconfig
index 2509d05..574da15 100644
--- a/drivers/tty/hvc/Kconfig
+++ b/drivers/tty/hvc/Kconfig
@@ -81,7 +81,7 @@ config HVC_UDBG
 
 config HVC_DCC
        bool "ARM JTAG DCC console"
-       depends on ARM
+       depends on ARM || ARM64
        select HVC_DRIVER
        help
          This console uses the JTAG DCC on ARM to create a console under the HVC
-- 
Qualcomm Innovation Center, Inc.
The Qualcomm Innovation Center, Inc. is a member of the Code Aurora Forum,
a Linux Foundation Collaborative Project.



From rafael at kernel.org  Fri Aug  7 17:28:38 2015
From: rafael at kernel.org (Rafael J. Wysocki)
Date: Sat, 8 Aug 2015 02:28:38 +0200
Subject: [PATCH 2/2] net, thunder, bgx: Add support for ACPI binding.
In-Reply-To: <55C5494D.5010903@caviumnetworks.com>
References: <1438907590-29649-1-git-send-email-ddaney.cavm@gmail.com>
 <1438907590-29649-3-git-send-email-ddaney.cavm@gmail.com>
 <20150807140106.GE7646@leverpostej>
 <55C4ECC6.7050908@caviumnetworks.com>
 <20150807175127.GB12013@leverpostej>
 <CAJZ5v0gc=bo3ayO7aWq19Hh_205YC52wqXGbbM5vxR1atXm+oA@mail.gmail.com>
 <55C5494D.5010903@caviumnetworks.com>
Message-ID: <CAJZ5v0iNqRsrpwzWY5o97R1S+Dr-CzRPg3Cymt1q4v5gvABCQA@mail.gmail.com>

Hi David,

On Sat, Aug 8, 2015 at 2:11 AM, David Daney <ddaney at caviumnetworks.com> wrote:
> On 08/07/2015 05:05 PM, Rafael J. Wysocki wrote:

[cut]

>>
>> It is actually useful to people as far as I can say.
>>
>> Also, if somebody is going to use properties with ACPI, why whould
>> they use a different set of properties with DT?
>>
>> Wouldn't it be more reasonable to use the same set in both cases?
>
>
> Yes, but there is still quite a bit of leeway to screw things up.

That I have to agree with, unfortunately.

On the other hand, this is a fairly new concept and we need to gain
some experience with it to be able to come up with best practices and
so on.  Cases like yours are really helpful here.

> FWIW:  http://www.uefi.org/sites/default/files/resources/nic-request-v2.pdf
>
> This actually seems to have been adopted by the UEFI people as a
> "Standard", I am not sure where a record of this is kept though.

Work on this is in progress, but far from completion.  Essentially,
what's needed is more pressure from vendors who want to use properties
in their firmware.

> So, we are changing our firmware to use this standard (which is quite
> similar the the DT with respect to MAC addresses).

Cool. :-)

Thanks,
Rafael


From rafael at kernel.org  Fri Aug  7 17:32:42 2015
From: rafael at kernel.org (Rafael J. Wysocki)
Date: Sat, 8 Aug 2015 02:32:42 +0200
Subject: [PATCH 2/2] net, thunder, bgx: Add support for ACPI binding.
In-Reply-To: <55C4F597.50103@caviumnetworks.com>
References: <1438907590-29649-1-git-send-email-ddaney.cavm@gmail.com>
 <1438907590-29649-3-git-send-email-ddaney.cavm@gmail.com>
 <20150807145414.GA5468@xora-haswell.xora.org.uk>
 <55C4F597.50103@caviumnetworks.com>
Message-ID: <CAJZ5v0hG8xUX9k7QD+vTR90_V+Rrvv3LqxLF966YCRk192zrzQ@mail.gmail.com>

Hi David,

On Fri, Aug 7, 2015 at 8:14 PM, David Daney <ddaney at caviumnetworks.com> wrote:
> On 08/07/2015 07:54 AM, Graeme Gregory wrote:
>>
>> On Thu, Aug 06, 2015 at 05:33:10PM -0700, David Daney wrote:
>>>
>>> From: David Daney <david.daney at cavium.com>
>>>
>>> Find out which PHYs belong to which BGX instance in the ACPI way.
>>>
>>> Set the MAC address of the device as provided by ACPI tables. This is
>>> similar to the implementation for devicetree in
>>> of_get_mac_address(). The table is searched for the device property
>>> entries "mac-address", "local-mac-address" and "address" in that
>>> order. The address is provided in a u64 variable and must contain a
>>> valid 6 bytes-len mac addr.
>>>
>>> Based on code from: Narinder Dhillon <ndhillon at cavium.com>
>>>                      Tomasz Nowicki <tomasz.nowicki at linaro.org>
>>>                      Robert Richter <rrichter at cavium.com>
>>>
>>> Signed-off-by: Tomasz Nowicki <tomasz.nowicki at linaro.org>
>>> Signed-off-by: Robert Richter <rrichter at cavium.com>
>>> Signed-off-by: David Daney <david.daney at cavium.com>
>>> ---
>>>   drivers/net/ethernet/cavium/thunder/thunder_bgx.c | 137
>>> +++++++++++++++++++++-
>>>   1 file changed, 135 insertions(+), 2 deletions(-)
>>>
>>> diff --git a/drivers/net/ethernet/cavium/thunder/thunder_bgx.c
>>> b/drivers/net/ethernet/cavium/thunder/thunder_bgx.c
>>> index 615b2af..2056583 100644
>>> --- a/drivers/net/ethernet/cavium/thunder/thunder_bgx.c
>>> +++ b/drivers/net/ethernet/cavium/thunder/thunder_bgx.c
>
> [...]
>>>
>>> +
>>> +static int acpi_get_mac_address(struct acpi_device *adev, u8 *dst)
>>> +{
>>> +       const union acpi_object *prop;
>>> +       u64 mac_val;
>>> +       u8 mac[ETH_ALEN];
>>> +       int i, j;
>>> +       int ret;
>>> +
>>> +       for (i = 0; i < ARRAY_SIZE(addr_propnames); i++) {
>>> +               ret = acpi_dev_get_property(adev, addr_propnames[i],
>>> +                                           ACPI_TYPE_INTEGER, &prop);
>>
>>
>> Shouldn't this be trying to use device_property_read_* API and making
>> the DT/ACPI path the same where possible?
>>
>
> Ideally, something like you suggest would be possible.  However, there are a
> couple of problems trying to do it in the kernel as it exists today:
>
> 1) There is no 'struct device *' here, so device_property_read_* is not
> applicable.
>
> 2) There is no standard ACPI binding for MAC addresses, so it is impossible
> to create a hypothetical fw_get_mac_address(), which would be analogous to
> of_get_mac_address().
>
> Other e-mail threads have suggested that the path to an elegant solution is
> to inter-mix a bunch of calls to acpi_dev_get_property*() and
> fwnode_property_read*() as to use these more generic fwnode_property_read*()
> functions whereever possible.  I rejected this approach as it seems cleaner
> to me to consistently use a single set of APIs.

Actually, that wasn't my intention.

I wanted to say that once you'd got an ACPI device pointer (struct
acpi_device), you could easly convert it to a struct fwnode_handle
pointer and operate that going forward when accessing properties.
That at least would help with the properties that do not differ
between DT and ACPI.

Thanks,
Rafael


From mturquette at baylibre.com  Fri Aug  7 17:55:09 2015
From: mturquette at baylibre.com (Michael Turquette)
Date: Fri, 07 Aug 2015 17:55:09 -0700
Subject: [GIT PULL] Xilinx Zynq changes for v4.3
In-Reply-To: <20150805085344.GH6390@localhost>
References: <55BB31E8.7040806@monstr.eu> <20150805085344.GH6390@localhost>
Message-ID: <20150808005509.2416.8174@quantum>

Quoting Olof Johansson (2015-08-05 01:53:44)
> Hi,
> 
> On Fri, Jul 31, 2015 at 10:29:28AM +0200, Michal Simek wrote:
> > Hi,
> > 
> > please pull these SoC changes to your tree.
> > 
> > Thanks,
> > Michal
> > 
> > The following changes since commit d770e558e21961ad6cfdf0ff7df0eb5d7d4f0754:
> > 
> >   Linux 4.2-rc1 (2015-07-05 11:01:52 -0700)
> > 
> > are available in the git repository at:
> > 
> >   https://github.com/Xilinx/linux-xlnx.git tags/zynq-soc-for-4.3
> > 
> > for you to fetch changes up to e4a9288942392965bd5cfad93d9996b83c0dc4a6:
> > 
> >   ARM: zynq: reserve space for jump target in secondary trampoline
> > (2015-07-31 10:24:41 +0200)
> 
> Merged, however:
> 
> > Arun Chandran (1):
> >       ARM: zynq: Fix earlyprintk in big endian mode
> > 
> > Masahiro Yamada (1):
> >       clk: zynq: remove redundant $(CONFIG_ARCH_ZYNQ) in Makefile
> 
> This should have gone through the clk tree. Seems small and simple enough that
> I'll take it, but please send patches through appropriate maintainers.
> 
> (Adding Mike and Stephen on cc so they know about it).

Olof,

Thanks for the heads up.

Michal,

No reason that patch couldn't have gone through the clk tree. It was
posted on July 27th, which wasn't that long ago. Please feel free to
ping Stephen or I on #linux-clk if you think one of your clk patches has
slipped through the cracks.

Regards,
Mike

> 
> 
> -Olof
> 
> 
> _______________________________________________
> linux-arm-kernel mailing list
> linux-arm-kernel at lists.infradead.org
> http://lists.infradead.org/mailman/listinfo/linux-arm-kernel


From dhdang at apm.com  Fri Aug  7 18:03:35 2015
From: dhdang at apm.com (Duc Dang)
Date: Fri,  7 Aug 2015 18:03:35 -0700
Subject: [PATCH v4 1/2] usb: make xhci platform driver use 64 bit or 32 bit DMA
In-Reply-To: <CADaLNDkeOP+gBw0qdSDha551w+w+q4ry9-EevDw5giyiQGdnqA@mail.gmail.com>
References: <CADaLNDkeOP+gBw0qdSDha551w+w+q4ry9-EevDw5giyiQGdnqA@mail.gmail.com>
Message-ID: <07fb19170aa7c027f44af634aac7e7918daac7cd.1438994178.git.dhdang@apm.com>

The xhci platform driver needs to work on systems that
either only support 64-bit DMA or only support 32-bit DMA. 
Attempt to set a coherent dma mask for 64-bit DMA, and 
attempt again with 32-bit DMA if that fails.

[dhdang: regenerate the patch over 4.2-rc5]
Signed-off-by: Mark Langsdorf <mlangsdo at redhat.com>
Tested-by: Mark Salter <msalter at redhat.com>
Signed-off-by: Duc Dang <dhdang at apm.com>

---
Changes from v3:
	Re-generate the patch over 4.2-rc5
	No code change.

Changes from v2:
	None

Changes from v1:
        Consolidated to use dma_set_mask_and_coherent
        Got rid of the check against sizeof(dma_addr_t)

 drivers/usb/host/xhci-plat.c | 16 ++++++++--------
 1 file changed, 8 insertions(+), 8 deletions(-)

diff --git a/drivers/usb/host/xhci-plat.c b/drivers/usb/host/xhci-plat.c
index 890ad9d..5d03f8b 100644
--- a/drivers/usb/host/xhci-plat.c
+++ b/drivers/usb/host/xhci-plat.c
@@ -93,14 +93,14 @@ static int xhci_plat_probe(struct platform_device *pdev)
 	if (irq < 0)
 		return -ENODEV;
 
-	/* Initialize dma_mask and coherent_dma_mask to 32-bits */
-	ret = dma_set_coherent_mask(&pdev->dev, DMA_BIT_MASK(32));
-	if (ret)
-		return ret;
-	if (!pdev->dev.dma_mask)
-		pdev->dev.dma_mask = &pdev->dev.coherent_dma_mask;
-	else
-		dma_set_mask(&pdev->dev, DMA_BIT_MASK(32));
+	/* Try setting the coherent_dma_mask to 64 bits, then try 32 bits */
+	ret = dma_set_mask_and_coherent(&pdev->dev, DMA_BIT_MASK(64));
+	if (ret) {
+		ret = dma_set_mask_and_coherent(&pdev->dev, DMA_BIT_MASK(32));
+		if (ret)
+			return ret;
+	}
+
 
 	hcd = usb_create_hcd(driver, &pdev->dev, dev_name(&pdev->dev));
 	if (!hcd)
-- 
1.9.1



From dhdang at apm.com  Fri Aug  7 18:03:36 2015
From: dhdang at apm.com (Duc Dang)
Date: Fri,  7 Aug 2015 18:03:36 -0700
Subject: [PATCH v4 2/2] usb: Add support for ACPI identification to
 xhci-platform
In-Reply-To: <07fb19170aa7c027f44af634aac7e7918daac7cd.1438994178.git.dhdang@apm.com>
References: <07fb19170aa7c027f44af634aac7e7918daac7cd.1438994178.git.dhdang@apm.com>
Message-ID: <5e302acb5b03c9bf61ecfb9b5b37e8b3b520bed9.1438994178.git.dhdang@apm.com>

Provide the methods to let ACPI identify the need to use
xhci-platform. Change the Kconfig files so the
xhci-plat.o file is selectable during kernel config.

This has been tested on an ARM64 machine with platform XHCI, an
x86_64 machine with XHCI, and an x86_64 machine without XHCI.
There were no regressions or error messages on the machines
without platform XHCI.

[dhdang: regenerate the patch over 4.2-rc5]
Signed-off-by: Mark Langsdorf <mlangsdo at redhat.com>
Signed-off-by: Duc Dang <dhdang at apm.com>

---
Changes from v3:
	Regenerate the patch over 4.2-rc5
	No code change

Changes from v2
	Replaced tristate with a boolean as the driver doesn't
		compile as a module
	Correct --help-- to ---help---

Changes from v1
	Renamed from "add support for APM X-Gene to xhci-platform"
	Removed changes to arm64/Kconfig
	Made CONFIG_USB_XHCI_PLATFORM a user selectable config option

 drivers/usb/host/Kconfig     |  7 ++++++-
 drivers/usb/host/xhci-plat.c | 11 +++++++++++
 2 files changed, 17 insertions(+), 1 deletion(-)

diff --git a/drivers/usb/host/Kconfig b/drivers/usb/host/Kconfig
index 8afc3c1..96231ee 100644
--- a/drivers/usb/host/Kconfig
+++ b/drivers/usb/host/Kconfig
@@ -32,7 +32,12 @@ config USB_XHCI_PCI
        default y
 
 config USB_XHCI_PLATFORM
-	tristate
+	tristate "xHCI platform driver support"
+	---help---
+	  Say 'Y' to enable the support for the xHCI host controller
+	  as a platform device. Many ARM SoCs provide USB this way.
+
+	  If unsure, say 'Y'.
 
 config USB_XHCI_MVEBU
 	tristate "xHCI support for Marvell Armada 375/38x"
diff --git a/drivers/usb/host/xhci-plat.c b/drivers/usb/host/xhci-plat.c
index 5d03f8b..14b40d2 100644
--- a/drivers/usb/host/xhci-plat.c
+++ b/drivers/usb/host/xhci-plat.c
@@ -19,6 +19,7 @@
 #include <linux/usb/phy.h>
 #include <linux/slab.h>
 #include <linux/usb/xhci_pdriver.h>
+#include <linux/acpi.h>
 
 #include "xhci.h"
 #include "xhci-mvebu.h"
@@ -262,6 +263,15 @@ static const struct of_device_id usb_xhci_of_match[] = {
 MODULE_DEVICE_TABLE(of, usb_xhci_of_match);
 #endif
 
+#ifdef CONFIG_ACPI
+static const struct acpi_device_id usb_xhci_acpi_match[] = {
+	/* APM X-Gene USB Controller */
+	{ "PNP0D10", },
+	{ }
+};
+MODULE_DEVICE_TABLE(acpi, usb_xhci_acpi_match);
+#endif
+
 static struct platform_driver usb_xhci_driver = {
 	.probe	= xhci_plat_probe,
 	.remove	= xhci_plat_remove,
@@ -269,6 +279,7 @@ static struct platform_driver usb_xhci_driver = {
 		.name = "xhci-hcd",
 		.pm = DEV_PM_OPS,
 		.of_match_table = of_match_ptr(usb_xhci_of_match),
+		.acpi_match_table = ACPI_PTR(usb_xhci_acpi_match),
 	},
 };
 MODULE_ALIAS("platform:xhci-hcd");
-- 
1.9.1



From gregkh at linuxfoundation.org  Fri Aug  7 18:29:05 2015
From: gregkh at linuxfoundation.org (Greg KH)
Date: Fri, 7 Aug 2015 18:29:05 -0700
Subject: [PATCH v4 2/2] usb: Add support for ACPI identification to
 xhci-platform
In-Reply-To: <5e302acb5b03c9bf61ecfb9b5b37e8b3b520bed9.1438994178.git.dhdang@apm.com>
References: <CADaLNDkeOP+gBw0qdSDha551w+w+q4ry9-EevDw5giyiQGdnqA@mail.gmail.com>
 <5e302acb5b03c9bf61ecfb9b5b37e8b3b520bed9.1438994178.git.dhdang@apm.com>
Message-ID: <20150808012905.GA10407@kroah.com>

On Fri, Aug 07, 2015 at 06:03:36PM -0700, Duc Dang wrote:
> Provide the methods to let ACPI identify the need to use
> xhci-platform. Change the Kconfig files so the
> xhci-plat.o file is selectable during kernel config.
> 
> This has been tested on an ARM64 machine with platform XHCI, an
> x86_64 machine with XHCI, and an x86_64 machine without XHCI.
> There were no regressions or error messages on the machines
> without platform XHCI.
> 
> [dhdang: regenerate the patch over 4.2-rc5]
> Signed-off-by: Mark Langsdorf <mlangsdo at redhat.com>
> Signed-off-by: Duc Dang <dhdang at apm.com>
> 
> ---
> Changes from v3:
> 	Regenerate the patch over 4.2-rc5
> 	No code change
> 
> Changes from v2
> 	Replaced tristate with a boolean as the driver doesn't
> 		compile as a module
> 	Correct --help-- to ---help---
> 
> Changes from v1
> 	Renamed from "add support for APM X-Gene to xhci-platform"
> 	Removed changes to arm64/Kconfig
> 	Made CONFIG_USB_XHCI_PLATFORM a user selectable config option
> 
>  drivers/usb/host/Kconfig     |  7 ++++++-
>  drivers/usb/host/xhci-plat.c | 11 +++++++++++
>  2 files changed, 17 insertions(+), 1 deletion(-)
> 
> diff --git a/drivers/usb/host/Kconfig b/drivers/usb/host/Kconfig
> index 8afc3c1..96231ee 100644
> --- a/drivers/usb/host/Kconfig
> +++ b/drivers/usb/host/Kconfig
> @@ -32,7 +32,12 @@ config USB_XHCI_PCI
>         default y
>  
>  config USB_XHCI_PLATFORM
> -	tristate
> +	tristate "xHCI platform driver support"
> +	---help---
> +	  Say 'Y' to enable the support for the xHCI host controller
> +	  as a platform device. Many ARM SoCs provide USB this way.
> +
> +	  If unsure, say 'Y'.
>  
>  config USB_XHCI_MVEBU
>  	tristate "xHCI support for Marvell Armada 375/38x"
> diff --git a/drivers/usb/host/xhci-plat.c b/drivers/usb/host/xhci-plat.c
> index 5d03f8b..14b40d2 100644
> --- a/drivers/usb/host/xhci-plat.c
> +++ b/drivers/usb/host/xhci-plat.c
> @@ -19,6 +19,7 @@
>  #include <linux/usb/phy.h>
>  #include <linux/slab.h>
>  #include <linux/usb/xhci_pdriver.h>
> +#include <linux/acpi.h>
>  
>  #include "xhci.h"
>  #include "xhci-mvebu.h"
> @@ -262,6 +263,15 @@ static const struct of_device_id usb_xhci_of_match[] = {
>  MODULE_DEVICE_TABLE(of, usb_xhci_of_match);
>  #endif
>  
> +#ifdef CONFIG_ACPI

You shoudn't need this #ifdef, right?

thanks,

greg k-h


From nathan_lynch at mentor.com  Fri Aug  7 19:03:22 2015
From: nathan_lynch at mentor.com (Nathan Lynch)
Date: Fri, 7 Aug 2015 21:03:22 -0500
Subject: [PATCH 1/2] ARM: VDSO: fix coarse clock monotonicity regression
In-Reply-To: <1438999403-5770-1-git-send-email-nathan_lynch@mentor.com>
References: <1438999403-5770-1-git-send-email-nathan_lynch@mentor.com>
Message-ID: <1438999403-5770-2-git-send-email-nathan_lynch@mentor.com>

Since 906c55579a63 ("timekeeping: Copy the shadow-timekeeper over the
real timekeeper last") it has become possible on ARM to:

- Obtain a CLOCK_MONOTONIC_COARSE or CLOCK_REALTIME_COARSE timestamp
  via syscall.
- Subsequently obtain a timestamp for the same clock ID via VDSO which
  predates the first timestamp (by one jiffy).

This is because ARM's update_vsyscall is deriving the coarse time
using the __current_kernel_time interface, when it should really be
using the timekeeper object provided to it by the timekeeping core.
It happened to work before only because __current_kernel_time would
access the same timekeeper object which had been passed to
update_vsyscall.  This is no longer the case.

Signed-off-by: Nathan Lynch <nathan_lynch at mentor.com>
---
 arch/arm/kernel/vdso.c | 7 +++----
 1 file changed, 3 insertions(+), 4 deletions(-)

diff --git a/arch/arm/kernel/vdso.c b/arch/arm/kernel/vdso.c
index efe17dd9b921..c8b243c1aef8 100644
--- a/arch/arm/kernel/vdso.c
+++ b/arch/arm/kernel/vdso.c
@@ -296,7 +296,6 @@ static bool tk_is_cntvct(const struct timekeeper *tk)
  */
 void update_vsyscall(struct timekeeper *tk)
 {
-	struct timespec xtime_coarse;
 	struct timespec64 *wtm = &tk->wall_to_monotonic;
 
 	if (!cntvct_ok) {
@@ -308,10 +307,10 @@ void update_vsyscall(struct timekeeper *tk)
 
 	vdso_write_begin(vdso_data);
 
-	xtime_coarse = __current_kernel_time();
 	vdso_data->tk_is_cntvct			= tk_is_cntvct(tk);
-	vdso_data->xtime_coarse_sec		= xtime_coarse.tv_sec;
-	vdso_data->xtime_coarse_nsec		= xtime_coarse.tv_nsec;
+	vdso_data->xtime_coarse_sec		= tk->xtime_sec;
+	vdso_data->xtime_coarse_nsec		= tk->tkr_mono.xtime_nsec >>
+							tk->tkr_mono.shift;
 	vdso_data->wtm_clock_sec		= wtm->tv_sec;
 	vdso_data->wtm_clock_nsec		= wtm->tv_nsec;
 
-- 
2.1.0



From nathan_lynch at mentor.com  Fri Aug  7 19:03:23 2015
From: nathan_lynch at mentor.com (Nathan Lynch)
Date: Fri, 7 Aug 2015 21:03:23 -0500
Subject: [PATCH 2/2] arm64: VDSO: fix coarse clock monotonicity regression
In-Reply-To: <1438999403-5770-1-git-send-email-nathan_lynch@mentor.com>
References: <1438999403-5770-1-git-send-email-nathan_lynch@mentor.com>
Message-ID: <1438999403-5770-3-git-send-email-nathan_lynch@mentor.com>

Since 906c55579a63 ("timekeeping: Copy the shadow-timekeeper over the
real timekeeper last") it has become possible on arm64 to:

- Obtain a CLOCK_MONOTONIC_COARSE or CLOCK_REALTIME_COARSE timestamp
  via syscall.
- Subsequently obtain a timestamp for the same clock ID via VDSO which
  predates the first timestamp (by one jiffy).

This is because arm64's update_vsyscall is deriving the coarse time
using the __current_kernel_time interface, when it should really be
using the timekeeper object provided to it by the timekeeping core.
It happened to work before only because __current_kernel_time would
access the same timekeeper object which had been passed to
update_vsyscall.  This is no longer the case.

Signed-off-by: Nathan Lynch <nathan_lynch at mentor.com>
---
 arch/arm64/kernel/vdso.c | 7 +++----
 1 file changed, 3 insertions(+), 4 deletions(-)

diff --git a/arch/arm64/kernel/vdso.c b/arch/arm64/kernel/vdso.c
index ec37ab3f524f..97bc68f4c689 100644
--- a/arch/arm64/kernel/vdso.c
+++ b/arch/arm64/kernel/vdso.c
@@ -199,16 +199,15 @@ int arch_setup_additional_pages(struct linux_binprm *bprm,
  */
 void update_vsyscall(struct timekeeper *tk)
 {
-	struct timespec xtime_coarse;
 	u32 use_syscall = strcmp(tk->tkr_mono.clock->name, "arch_sys_counter");
 
 	++vdso_data->tb_seq_count;
 	smp_wmb();
 
-	xtime_coarse = __current_kernel_time();
 	vdso_data->use_syscall			= use_syscall;
-	vdso_data->xtime_coarse_sec		= xtime_coarse.tv_sec;
-	vdso_data->xtime_coarse_nsec		= xtime_coarse.tv_nsec;
+	vdso_data->xtime_coarse_sec		= tk->xtime_sec;
+	vdso_data->xtime_coarse_nsec		= tk->tkr_mono.xtime_nsec >>
+							tk->tkr_mono.shift;
 	vdso_data->wtm_clock_sec		= tk->wall_to_monotonic.tv_sec;
 	vdso_data->wtm_clock_nsec		= tk->wall_to_monotonic.tv_nsec;
 
-- 
2.1.0



From nathan_lynch at mentor.com  Fri Aug  7 19:03:21 2015
From: nathan_lynch at mentor.com (Nathan Lynch)
Date: Fri, 7 Aug 2015 21:03:21 -0500
Subject: [PATCH 0/2] fix vdso coarse clock monotonicity regressions
Message-ID: <1438999403-5770-1-git-send-email-nathan_lynch@mentor.com>

Commit 906c55579a63 ("timekeeping: Copy the shadow-timekeeper over the
real timekeeper last") made it so the user can observe the coarse
clocks going backwards on arm and arm64, if they're really looking for
it.

Technically these are fixing regressions versus 4.1, but I won't be
bothered if they don't make 4.2 final at this late stage, since only
the (seldom-used?) coarse clocks are affected.

I'd like to collect review/acks for these now and make sure they at
least make it into 4.3-rc1 (and -stable after that).


Nathan Lynch (2):
  ARM: VDSO: fix coarse clock monotonicity regression
  arm64: VDSO: fix coarse clock monotonicity regression

 arch/arm/kernel/vdso.c   | 7 +++----
 arch/arm64/kernel/vdso.c | 7 +++----
 2 files changed, 6 insertions(+), 8 deletions(-)

-- 
2.1.0



From viresh.kumar at linaro.org  Fri Aug  7 19:06:42 2015
From: viresh.kumar at linaro.org (Viresh Kumar)
Date: Sat, 8 Aug 2015 07:36:42 +0530
Subject: [PATCH v4 1/6] cpufreq: make scaling_boost_freqs sysfs attr
 available when boost is enabled
In-Reply-To: <11605783.uxKCOKbq1D@vostro.rjw.lan>
References: <1438868514-8814-1-git-send-email-b.zolnierkie@samsung.com>
 <1594902.Dv5JKhve0y@amdc1976> <20150807113739.GF6939@linux>
 <11605783.uxKCOKbq1D@vostro.rjw.lan>
Message-ID: <20150808020642.GL6939@linux>

On 08-08-15, 00:21, Rafael J. Wysocki wrote:
> > Acked-by: Viresh Kumar <viresh.kumar at linaro.org>
> 
> And what exactly am I supposed to do with this?
> 
> Have a robot that will pick up all patches ACKed by you magically or what?

:)

That's why I have asked Bartlomiej specifically to send it separately
to the pm list as a cpufreq patch. I wasn't expecting you to apply
right from here.

-- 
viresh


From viresh.kumar at linaro.org  Fri Aug  7 19:07:40 2015
From: viresh.kumar at linaro.org (Viresh Kumar)
Date: Sat, 8 Aug 2015 07:37:40 +0530
Subject: [PATCH v4 0/6] cpufreq: use generic cpufreq drivers for
 Exynos4x12 platform
In-Reply-To: <1525406.7aXvVQzEDd@vostro.rjw.lan>
References: <1438868514-8814-1-git-send-email-b.zolnierkie@samsung.com>
 <2359635.Hxe4cb8zKm@amdc1976> <20150807115627.GH6939@linux>
 <1525406.7aXvVQzEDd@vostro.rjw.lan>
Message-ID: <20150808020740.GM6939@linux>

On 08-08-15, 00:24, Rafael J. Wysocki wrote:
> OK, so please let me know which patches you want me to pick up.
> 
> Ideally, I'd prefer them to be resent in a separate series with ACKs and all
> with a cover letter clearly stating whose tree they are being targeted at.

He already sent it separately, let me send a confirmatory mail in
reply to that.

-- 
viresh


From viresh.kumar at linaro.org  Fri Aug  7 19:09:00 2015
From: viresh.kumar at linaro.org (Viresh Kumar)
Date: Sat, 8 Aug 2015 07:39:00 +0530
Subject: [PATCH v3] cpufreq-dt: make scaling_boost_freqs sysfs attr
 available when boost is enabled
In-Reply-To: <2130756.euuUs9t9I5@amdc1976>
References: <2130756.euuUs9t9I5@amdc1976>
Message-ID: <20150808020900.GN6939@linux>

On 07-08-15, 13:59, Bartlomiej Zolnierkiewicz wrote:
> Make scaling_boost_freqs sysfs attribute is available when
> cpufreq-dt driver is used and boost support is enabled.
> 
> Cc: Thomas Abraham <thomas.ab at samsung.com>
> Cc: Javier Martinez Canillas <javier at osg.samsung.com>
> Cc: Krzysztof Kozlowski <k.kozlowski at samsung.com>
> Suggested-by: Viresh Kumar <viresh.kumar at linaro.org>
> Acked-by: Viresh Kumar <viresh.kumar at linaro.org>
> Signed-off-by: Bartlomiej Zolnierkiewicz <b.zolnierkie at samsung.com>
> ---
> v2: Removed leftover prototype.
> v3: added missing Acked-by
> Sorry for two resends, this is not my day..
> Rafael, please apply for v4.3.

Yeah, please apply only this patch from the series.

-- 
viresh


From dhdang at apm.com  Fri Aug  7 19:40:56 2015
From: dhdang at apm.com (Duc Dang)
Date: Fri, 7 Aug 2015 19:40:56 -0700
Subject: [PATCH v4 2/2] usb: Add support for ACPI identification to
 xhci-platform
In-Reply-To: <20150808012905.GA10407@kroah.com>
References: <CADaLNDkeOP+gBw0qdSDha551w+w+q4ry9-EevDw5giyiQGdnqA@mail.gmail.com>
 <5e302acb5b03c9bf61ecfb9b5b37e8b3b520bed9.1438994178.git.dhdang@apm.com>
 <20150808012905.GA10407@kroah.com>
Message-ID: <CADaLNDkU14GCPZE_zNt_9kMSsUdywyNp1QCiWpokXQgbfRS0qw@mail.gmail.com>

On Fri, Aug 7, 2015 at 6:29 PM, Greg KH <gregkh at linuxfoundation.org> wrote:
> On Fri, Aug 07, 2015 at 06:03:36PM -0700, Duc Dang wrote:
>> Provide the methods to let ACPI identify the need to use
>> xhci-platform. Change the Kconfig files so the
>> xhci-plat.o file is selectable during kernel config.
>>
>> This has been tested on an ARM64 machine with platform XHCI, an
>> x86_64 machine with XHCI, and an x86_64 machine without XHCI.
>> There were no regressions or error messages on the machines
>> without platform XHCI.
>>
>> [dhdang: regenerate the patch over 4.2-rc5]
>> Signed-off-by: Mark Langsdorf <mlangsdo at redhat.com>
>> Signed-off-by: Duc Dang <dhdang at apm.com>
>>
>> ---
>> Changes from v3:
>>       Regenerate the patch over 4.2-rc5
>>       No code change
>>
>> Changes from v2
>>       Replaced tristate with a boolean as the driver doesn't
>>               compile as a module
>>       Correct --help-- to ---help---
>>
>> Changes from v1
>>       Renamed from "add support for APM X-Gene to xhci-platform"
>>       Removed changes to arm64/Kconfig
>>       Made CONFIG_USB_XHCI_PLATFORM a user selectable config option
>>
>>  drivers/usb/host/Kconfig     |  7 ++++++-
>>  drivers/usb/host/xhci-plat.c | 11 +++++++++++
>>  2 files changed, 17 insertions(+), 1 deletion(-)
>>
>> diff --git a/drivers/usb/host/Kconfig b/drivers/usb/host/Kconfig
>> index 8afc3c1..96231ee 100644
>> --- a/drivers/usb/host/Kconfig
>> +++ b/drivers/usb/host/Kconfig
>> @@ -32,7 +32,12 @@ config USB_XHCI_PCI
>>         default y
>>
>>  config USB_XHCI_PLATFORM
>> -     tristate
>> +     tristate "xHCI platform driver support"
>> +     ---help---
>> +       Say 'Y' to enable the support for the xHCI host controller
>> +       as a platform device. Many ARM SoCs provide USB this way.
>> +
>> +       If unsure, say 'Y'.
>>
>>  config USB_XHCI_MVEBU
>>       tristate "xHCI support for Marvell Armada 375/38x"
>> diff --git a/drivers/usb/host/xhci-plat.c b/drivers/usb/host/xhci-plat.c
>> index 5d03f8b..14b40d2 100644
>> --- a/drivers/usb/host/xhci-plat.c
>> +++ b/drivers/usb/host/xhci-plat.c
>> @@ -19,6 +19,7 @@
>>  #include <linux/usb/phy.h>
>>  #include <linux/slab.h>
>>  #include <linux/usb/xhci_pdriver.h>
>> +#include <linux/acpi.h>
>>
>>  #include "xhci.h"
>>  #include "xhci-mvebu.h"
>> @@ -262,6 +263,15 @@ static const struct of_device_id usb_xhci_of_match[] = {
>>  MODULE_DEVICE_TABLE(of, usb_xhci_of_match);
>>  #endif
>>
>> +#ifdef CONFIG_ACPI
>
> You shoudn't need this #ifdef, right?

You are correct, Greg.

I will post a new version that remove this #ifdef CONFIG_ACPI shortly

>
> thanks,
>
> greg k-h



-- 
Regards,
Duc Dang.


From dhdang at apm.com  Fri Aug  7 20:18:49 2015
From: dhdang at apm.com (Duc Dang)
Date: Fri,  7 Aug 2015 20:18:49 -0700
Subject: [PATCH v5 2/2] usb: Add support for ACPI identification to
 xhci-platform
In-Reply-To: <74fe0b014334a5ac1db90dec46bdbf6c30c07895.1439002338.git.dhdang@apm.com>
References: <74fe0b014334a5ac1db90dec46bdbf6c30c07895.1439002338.git.dhdang@apm.com>
Message-ID: <651f91b3efbba4b4f5ff8f531f353a4855b9e9d9.1439002338.git.dhdang@apm.com>

Provide the methods to let ACPI identify the need to use
xhci-platform. Change the Kconfig files so the
xhci-plat.o file is selectable during kernel config.

This has been tested on an ARM64 machine with platform XHCI, an
x86_64 machine with XHCI, and an x86_64 machine without XHCI.
There were no regressions or error messages on the machines
without platform XHCI.

Signed-off-by: Mark Langsdorf <mlangsdo at redhat.com>
Signed-off-by: Duc Dang <dhdang at apm.com>

---
Changes from v4:
	Remove #ifdef CONFIG_ACPI

Changes from v3:
        Regenerate the patch over 4.2-rc5
        No code change

Changes from v2
        Replaced tristate with a boolean as the driver doesn't
                compile as a module
        Correct --help-- to ---help---

Changes from v1
        Renamed from "add support for APM X-Gene to xhci-platform"
        Removed changes to arm64/Kconfig
        Made CONFIG_USB_XHCI_PLATFORM a user selectable config option

 drivers/usb/host/Kconfig     | 7 ++++++-
 drivers/usb/host/xhci-plat.c | 9 +++++++++
 2 files changed, 15 insertions(+), 1 deletion(-)

diff --git a/drivers/usb/host/Kconfig b/drivers/usb/host/Kconfig
index 8afc3c1..96231ee 100644
--- a/drivers/usb/host/Kconfig
+++ b/drivers/usb/host/Kconfig
@@ -32,7 +32,12 @@ config USB_XHCI_PCI
        default y
 
 config USB_XHCI_PLATFORM
-	tristate
+	tristate "xHCI platform driver support"
+	---help---
+	  Say 'Y' to enable the support for the xHCI host controller
+	  as a platform device. Many ARM SoCs provide USB this way.
+
+	  If unsure, say 'Y'.
 
 config USB_XHCI_MVEBU
 	tristate "xHCI support for Marvell Armada 375/38x"
diff --git a/drivers/usb/host/xhci-plat.c b/drivers/usb/host/xhci-plat.c
index 5d03f8b..bd282cd 100644
--- a/drivers/usb/host/xhci-plat.c
+++ b/drivers/usb/host/xhci-plat.c
@@ -19,6 +19,7 @@
 #include <linux/usb/phy.h>
 #include <linux/slab.h>
 #include <linux/usb/xhci_pdriver.h>
+#include <linux/acpi.h>
 
 #include "xhci.h"
 #include "xhci-mvebu.h"
@@ -262,6 +263,13 @@ static const struct of_device_id usb_xhci_of_match[] = {
 MODULE_DEVICE_TABLE(of, usb_xhci_of_match);
 #endif
 
+static const struct acpi_device_id usb_xhci_acpi_match[] = {
+	/* APM X-Gene USB Controller */
+	{ "PNP0D10", },
+	{ }
+};
+MODULE_DEVICE_TABLE(acpi, usb_xhci_acpi_match);
+
 static struct platform_driver usb_xhci_driver = {
 	.probe	= xhci_plat_probe,
 	.remove	= xhci_plat_remove,
@@ -269,6 +277,7 @@ static struct platform_driver usb_xhci_driver = {
 		.name = "xhci-hcd",
 		.pm = DEV_PM_OPS,
 		.of_match_table = of_match_ptr(usb_xhci_of_match),
+		.acpi_match_table = ACPI_PTR(usb_xhci_acpi_match),
 	},
 };
 MODULE_ALIAS("platform:xhci-hcd");
-- 
1.9.1



From dhdang at apm.com  Fri Aug  7 20:18:48 2015
From: dhdang at apm.com (Duc Dang)
Date: Fri,  7 Aug 2015 20:18:48 -0700
Subject: [PATCH v5 1/2] usb: make xhci platform driver use 64 bit or 32 bit DMA
In-Reply-To: <CADaLNDkU14GCPZE_zNt_9kMSsUdywyNp1QCiWpokXQgbfRS0qw@mail.gmail.com>
References: <CADaLNDkU14GCPZE_zNt_9kMSsUdywyNp1QCiWpokXQgbfRS0qw@mail.gmail.com>
Message-ID: <74fe0b014334a5ac1db90dec46bdbf6c30c07895.1439002338.git.dhdang@apm.com>

The xhci platform driver needs to work on systems that
either only support 64-bit DMA or only support 32-bit DMA.
Attempt to set a coherent dma mask for 64-bit DMA, and
attempt again with 32-bit DMA if that fails.

[dhdang: Regenerate the patch over 4.2-rc5]
Signed-off-by: Mark Langsdorf <mlangsdo at redhat.com>
Tested-by: Mark Salter <msalter at redhat.com>
Signed-off-by: Duc Dang <dhdang at apm.com>

---
Changes from v4:
	None

Changes from v3:
        Re-generate the patch over 4.2-rc5
        No code change.

Changes from v2:
        None

Changes from v1:
        Consolidated to use dma_set_mask_and_coherent
        Got rid of the check against sizeof(dma_addr_t)

 drivers/usb/host/xhci-plat.c | 16 ++++++++--------
 1 file changed, 8 insertions(+), 8 deletions(-)

diff --git a/drivers/usb/host/xhci-plat.c b/drivers/usb/host/xhci-plat.c
index 890ad9d..5d03f8b 100644
--- a/drivers/usb/host/xhci-plat.c
+++ b/drivers/usb/host/xhci-plat.c
@@ -93,14 +93,14 @@ static int xhci_plat_probe(struct platform_device *pdev)
 	if (irq < 0)
 		return -ENODEV;
 
-	/* Initialize dma_mask and coherent_dma_mask to 32-bits */
-	ret = dma_set_coherent_mask(&pdev->dev, DMA_BIT_MASK(32));
-	if (ret)
-		return ret;
-	if (!pdev->dev.dma_mask)
-		pdev->dev.dma_mask = &pdev->dev.coherent_dma_mask;
-	else
-		dma_set_mask(&pdev->dev, DMA_BIT_MASK(32));
+	/* Try setting the coherent_dma_mask to 64 bits, then try 32 bits */
+	ret = dma_set_mask_and_coherent(&pdev->dev, DMA_BIT_MASK(64));
+	if (ret) {
+		ret = dma_set_mask_and_coherent(&pdev->dev, DMA_BIT_MASK(32));
+		if (ret)
+			return ret;
+	}
+
 
 	hcd = usb_create_hcd(driver, &pdev->dev, dev_name(&pdev->dev));
 	if (!hcd)
-- 
1.9.1



From wens at csie.org  Fri Aug  7 22:28:39 2015
From: wens at csie.org (Chen-Yu Tsai)
Date: Sat, 8 Aug 2015 13:28:39 +0800
Subject: ARM: dts: sunxi: Regulators at common board layouts
In-Reply-To: <55B9F245.2000300@whiteboxes.ch>
References: <55B9F245.2000300@whiteboxes.ch>
Message-ID: <CAGb2v64PgX9aiBBYRXcBjchzqfEovFXdDMkHhooPnGF9AAfL+A@mail.gmail.com>

Hi,

On Thu, Jul 30, 2015 at 5:45 PM, Mikhail Yakshin <greycat at whiteboxes.ch> wrote:
> Hi,
>
> I've been analyzing various boards based on Allwinner A20 CPU and
> X-Powers AXP209 PMU (to make a proper configuration for our board,
> Whitebox Labs Watermelon).
>
> There are some things very common and some things pretty different on
> various boards.
>
> Namely, there's agreement on that DCDC2 and DCDC3 and used for CPU
> voltages (VDD-CPU and (VDD-SYS=VDD-INT)+VDD-DLL respectively) on all
> boards I've analyzed (Olimex boards, Cubieboard / Cubietruck, BananaPi,
> PCDuino, Watermelon, etc) and probably it should be kept this way.
>
> However, what puzzles me the most so far is LDO1 regulator. According to
> [AXP209 datasheet, p. 13, p. 23][1] and all the boards I've
> investigated, it's used exclusively for powering VDD-RTC input of A20
> CPU that supports internal CPU's RTC. LDO1 gets very special status in
> AXP209 - basically, it's as close to "always on" (even on backup
> battery) as possible the purpose of timekeeping.
>
> According to the same spec, LDO1 allows 2 distinct voltage choices: 1.3V
> and 3.3V. However, according to the [A20 datasheet][2], VDD-RTC (pin K8)
> has absolute minimum and maximum voltage ratings of 3.0V. I'm not sure
> how is it supposed to work together, given that X-Powers AXP209 and
> Allwinner A20 is basically produced by different branches the same
> company and are meant to be totally compatible.

Get an updated datasheet. Mine (v1.5 20150510) recommends VDD-RTC to
be 1.2 V ~ 1.4 V, and nominally at 1.3 V.

Also, my AXP209 datasheet (v1.0 Chinese) says LDO1SET grounded means
LDO1 is set to 1.3 V.

> What's even more weird, is that all configurations I've encountered so
> far (i.e. FEX configurations for 3.4 sunxi kernel and DTS for modern
> mainline kernels) use hard locked 1.3V setting for LDO1. For example,
> kernel 3.4:
>
> /sys/devices/platform/sunxi-i2c.0/i2c-0/0-0034/axp20-regulator.21/regulator/regulator.1/
> name    axp20_ldo1
> microvolts      1300000
> min_microvolts  1300000
> max_microvolts  1300000
>
> and similar construction in mainline DTSes:
>
>     vdd_rtc: ldo1 {
>             regulator-min-microvolt = <1300000>;
>             regulator-max-microvolt = <1300000>;
>             regulator-always-on;
>     };
>
> or in axp209.dtsi:
>
>     reg_ldo1: ldo1 {
>             /* LDO1 is a fixed output regulator */
>             regulator-always-on;
>             regulator-min-microvolt = <1300000>;
>             regulator-max-microvolt = <1300000>;
>             regulator-name = "ldo1";
>     };
>
> If we'll take a look at default power-on setup for AXP209 in the
> datasheet (page 24), we'll see that it's determined by LDO1SET pin. If
> it's connected to GND, then LDO1 will start with 1.3V, if it's connected
> to VINT, then it would be 3.3V.
>
> I've analyzed all the schematics I found in public:
>
> * Older Olimex schematics (Lime rev C, Lime rev D, Lime2 rev B) state
> that LDO1 line is "3V3/30mA". LDO1SET is grounded.
> * Newer Olimex schematics (Lime2 rev C) call that "1V3/30mA". LDO1SET is
> grounded.
> * All Bananapi and Cubieboard schematics look very similar and seem to
> be originating from the same source (reference Allwinner design?) and do
> not hint any voltages. LDO1SET is grounded.
>
> Can someone explain to me how does it work / supposed to work?

See above.

ChenYu

> [1]: http://linux-sunxi.org/images/8/89/AXP209_Datasheet_v1.0en.pdf
> [2]:
> https://github.com/OLIMEX/OLINUXINO/raw/master/HARDWARE/A20-PDFs/A20%20Datasheet%20v1.0%2020130227.pdf
>
> --
> WBR, Mikhail Yakshin
>
>
> _______________________________________________
> linux-arm-kernel mailing list
> linux-arm-kernel at lists.infradead.org
> http://lists.infradead.org/mailman/listinfo/linux-arm-kernel
>


From javier at dowhile0.org  Fri Aug  7 22:43:40 2015
From: javier at dowhile0.org (Javier Martinez Canillas)
Date: Sat, 8 Aug 2015 07:43:40 +0200
Subject: [PATCH v4 2/2] usb: Add support for ACPI identification to
 xhci-platform
In-Reply-To: <20150808012905.GA10407@kroah.com>
References: <CADaLNDkeOP+gBw0qdSDha551w+w+q4ry9-EevDw5giyiQGdnqA@mail.gmail.com>
 <5e302acb5b03c9bf61ecfb9b5b37e8b3b520bed9.1438994178.git.dhdang@apm.com>
 <20150808012905.GA10407@kroah.com>
Message-ID: <CABxcv=nAxKqt06js1epALu8Y_61bZ+XeRwy_N=oQUTeRVCh6-w@mail.gmail.com>

Hello Greg,

On Sat, Aug 8, 2015 at 3:29 AM, Greg KH <gregkh at linuxfoundation.org> wrote:
> On Fri, Aug 07, 2015 at 06:03:36PM -0700, Duc Dang wrote:
>> Provide the methods to let ACPI identify the need to use
>> xhci-platform. Change the Kconfig files so the
>> xhci-plat.o file is selectable during kernel config.
>>
>> This has been tested on an ARM64 machine with platform XHCI, an
>> x86_64 machine with XHCI, and an x86_64 machine without XHCI.
>> There were no regressions or error messages on the machines
>> without platform XHCI.
>>
>> [dhdang: regenerate the patch over 4.2-rc5]
>> Signed-off-by: Mark Langsdorf <mlangsdo at redhat.com>
>> Signed-off-by: Duc Dang <dhdang at apm.com>
>>
>> ---
>> Changes from v3:
>>       Regenerate the patch over 4.2-rc5
>>       No code change
>>
>> Changes from v2
>>       Replaced tristate with a boolean as the driver doesn't
>>               compile as a module
>>       Correct --help-- to ---help---
>>
>> Changes from v1
>>       Renamed from "add support for APM X-Gene to xhci-platform"
>>       Removed changes to arm64/Kconfig
>>       Made CONFIG_USB_XHCI_PLATFORM a user selectable config option
>>
>>  drivers/usb/host/Kconfig     |  7 ++++++-
>>  drivers/usb/host/xhci-plat.c | 11 +++++++++++
>>  2 files changed, 17 insertions(+), 1 deletion(-)
>>
>> diff --git a/drivers/usb/host/Kconfig b/drivers/usb/host/Kconfig
>> index 8afc3c1..96231ee 100644
>> --- a/drivers/usb/host/Kconfig
>> +++ b/drivers/usb/host/Kconfig
>> @@ -32,7 +32,12 @@ config USB_XHCI_PCI
>>         default y
>>
>>  config USB_XHCI_PLATFORM
>> -     tristate
>> +     tristate "xHCI platform driver support"
>> +     ---help---
>> +       Say 'Y' to enable the support for the xHCI host controller
>> +       as a platform device. Many ARM SoCs provide USB this way.
>> +
>> +       If unsure, say 'Y'.
>>
>>  config USB_XHCI_MVEBU
>>       tristate "xHCI support for Marvell Armada 375/38x"
>> diff --git a/drivers/usb/host/xhci-plat.c b/drivers/usb/host/xhci-plat.c
>> index 5d03f8b..14b40d2 100644
>> --- a/drivers/usb/host/xhci-plat.c
>> +++ b/drivers/usb/host/xhci-plat.c
>> @@ -19,6 +19,7 @@
>>  #include <linux/usb/phy.h>
>>  #include <linux/slab.h>
>>  #include <linux/usb/xhci_pdriver.h>
>> +#include <linux/acpi.h>
>>
>>  #include "xhci.h"
>>  #include "xhci-mvebu.h"
>> @@ -262,6 +263,15 @@ static const struct of_device_id usb_xhci_of_match[] = {
>>  MODULE_DEVICE_TABLE(of, usb_xhci_of_match);
>>  #endif
>>
>> +#ifdef CONFIG_ACPI
>
> You shoudn't need this #ifdef, right?
>

Why it is not needed?

The driver does .acpi_match_table = ACPI_PTR(usb_xhci_acpi_match) and
ACPI_PTR() is NULL if CONFIG_ACPI is not enabled. Which can happen
AFAIU since the driver also supports OF. So without the #ifdef guards,
.acpi_match_table = NULL and the struct acpi_device_id
usb_xhci_acpi_match[] will be built but not used.

Or am I missing something?

> thanks,
>
> greg k-h
>

Best regards,
Javier


From k.kozlowski at samsung.com  Fri Aug  7 23:53:10 2015
From: k.kozlowski at samsung.com (Krzysztof Kozlowski)
Date: Sat, 08 Aug 2015 15:53:10 +0900
Subject: [PATCH 2/4] drm/bridge: Add vendor prefixes
In-Reply-To: <1438964855-16989-2-git-send-email-thierry.reding@gmail.com>
References: <1438964855-16989-1-git-send-email-thierry.reding@gmail.com>
 <1438964855-16989-2-git-send-email-thierry.reding@gmail.com>
Message-ID: <55C5A756.7050308@samsung.com>

W dniu 08.08.2015 o 01:27, Thierry Reding pisze:
> From: Thierry Reding <treding at nvidia.com>
> 
> Use vendor prefixes for Kconfig symbols and filenames. This should make
> it easier to identify the various bridge drivers and to organize the
> directory.
> 
> While at it, rename dw_hdmi.[ch] to dw-hdmi.[ch] for consistency.
> 
> Signed-off-by: Thierry Reding <treding at nvidia.com>
> ---
>  arch/arm/configs/exynos_defconfig                    |  4 ++--
>  arch/arm/configs/multi_v7_defconfig                  |  4 ++--
>  drivers/gpu/drm/bridge/Kconfig                       | 10 +++++-----
>  drivers/gpu/drm/bridge/Makefile                      |  6 +++---
>  drivers/gpu/drm/bridge/{dw_hdmi.c => dw-hdmi.c}      |  2 +-
>  drivers/gpu/drm/bridge/{dw_hdmi.h => dw-hdmi.h}      |  0
>  drivers/gpu/drm/bridge/{ptn3460.c => nxp-ptn3460.c}  |  0
>  drivers/gpu/drm/bridge/{ps8622.c => parade-ps8622.c} |  0
>  8 files changed, 13 insertions(+), 13 deletions(-)
>  rename drivers/gpu/drm/bridge/{dw_hdmi.c => dw-hdmi.c} (99%)
>  rename drivers/gpu/drm/bridge/{dw_hdmi.h => dw-hdmi.h} (100%)
>  rename drivers/gpu/drm/bridge/{ptn3460.c => nxp-ptn3460.c} (100%)
>  rename drivers/gpu/drm/bridge/{ps8622.c => parade-ps8622.c} (100%)

I assume this will go through some DRM tree? If yes then:
Acked-by: Krzysztof Kozlowski <k.kozlowski at samsung.com>

Best regards,
Krzysztof


From k.kozlowski at samsung.com  Fri Aug  7 23:54:43 2015
From: k.kozlowski at samsung.com (Krzysztof Kozlowski)
Date: Sat, 08 Aug 2015 15:54:43 +0900
Subject: [PATCH 3/4] drm/panel: Add Samsung prefix to panel drivers
In-Reply-To: <1438964855-16989-3-git-send-email-thierry.reding@gmail.com>
References: <1438964855-16989-1-git-send-email-thierry.reding@gmail.com>
 <1438964855-16989-3-git-send-email-thierry.reding@gmail.com>
Message-ID: <55C5A7B3.2010701@samsung.com>

W dniu 08.08.2015 o 01:27, Thierry Reding pisze:
> From: Thierry Reding <treding at nvidia.com>
> 
> The likelihood of getting a large number of panel drivers from different
> vendors is quite high. Add a prefix to the two existing Samsung panel
> drivers to set a guideline for future patch submissions. Using vendor
> prefixes consistently should allow a cleaner organization of the tree.
> 
> Signed-off-by: Thierry Reding <treding at nvidia.com>
> ---
>  arch/arm/configs/exynos_defconfig                                 | 2 +-
>  arch/arm/configs/multi_v7_defconfig                               | 2 +-

Acked-by: Krzysztof Kozlowski <k.kozlowski at samsung.com>

Best regards,
Krzysztof


>  drivers/gpu/drm/panel/Kconfig                                     | 8 ++++----
>  drivers/gpu/drm/panel/Makefile                                    | 4 ++--
>  drivers/gpu/drm/panel/{panel-ld9040.c => panel-samsung-ld9040.c}  | 2 +-
>  .../gpu/drm/panel/{panel-s6e8aa0.c => panel-samsung-s6e8aa0.c}    | 2 +-
>  6 files changed, 10 insertions(+), 10 deletions(-)
>  rename drivers/gpu/drm/panel/{panel-ld9040.c => panel-samsung-ld9040.c} (99%)
>  rename drivers/gpu/drm/panel/{panel-s6e8aa0.c => panel-samsung-s6e8aa0.c} (99%)



From k.kozlowski at samsung.com  Sat Aug  8 00:27:10 2015
From: k.kozlowski at samsung.com (Krzysztof Kozlowski)
Date: Sat, 08 Aug 2015 16:27:10 +0900
Subject: [PATCH v4 0/6] cpufreq: use generic cpufreq drivers for Exynos4x12
 platform
In-Reply-To: <20150808020740.GM6939@linux>
References: <1438868514-8814-1-git-send-email-b.zolnierkie@samsung.com>
 <2359635.Hxe4cb8zKm@amdc1976> <20150807115627.GH6939@linux>
 <1525406.7aXvVQzEDd@vostro.rjw.lan> <20150808020740.GM6939@linux>
Message-ID: <55C5AF4E.3010500@samsung.com>

W dniu 08.08.2015 o 11:07, Viresh Kumar pisze:
> On 08-08-15, 00:24, Rafael J. Wysocki wrote:
>> OK, so please let me know which patches you want me to pick up.
>>
>> Ideally, I'd prefer them to be resent in a separate series with ACKs and all
>> with a cover letter clearly stating whose tree they are being targeted at.
> 
> He already sent it separately, let me send a confirmatory mail in
> reply to that.

Dear Kukjin,

Can you apply the 2-5 of this series to v4.3? It's getting late but
maybe they still could go?

Best regards,
Krzysztof


From ard.biesheuvel at linaro.org  Sat Aug  8 01:20:58 2015
From: ard.biesheuvel at linaro.org (Ard Biesheuvel)
Date: Sat, 8 Aug 2015 10:20:58 +0200
Subject: [RFC] arm64: defconfig: enable 48-bit VA by default
In-Reply-To: <BY2PR0301MB07436AC9C8D023DC7C67DE3D87730@BY2PR0301MB0743.namprd03.prod.outlook.com>
References: <CY1PR0301MB07488D6DC5F0B171D6B290E187830@CY1PR0301MB0748.namprd03.prod.outlook.com>
 <55B0E1AD.60409@arm.com>
 <BY2PR0301MB0743CBCFC5476E39A5D1EC0B878C0@BY2PR0301MB0743.namprd03.prod.outlook.com>
 <CAKv+Gu9LHBd7wM6P4H0X5WigzDETtpr2++_Ebo=adg5QtTOW2w@mail.gmail.com>
 <BY2PR0301MB074300C5F31701D9211827F0878C0@BY2PR0301MB0743.namprd03.prod.outlook.com>
 <20150730101358.GA30796@e104818-lin.cambridge.arm.com>
 <CY1PR0301MB074850E27D5D298D1B8495D2878B0@CY1PR0301MB0748.namprd03.prod.outlook.com>
 <20150730161210.GE407@e104818-lin.cambridge.arm.com>
 <CY1PR0301MB0748FA3A10AFA9BFC1AB0A39878B0@CY1PR0301MB0748.namprd03.prod.outlook.com>
 <CAKv+Gu-Wbv3J9-2KbXrz_3W_=VXChrD+REo1-q1Ns_=RUM1BFw@mail.gmail.com>
 <BY2PR0301MB07436AC9C8D023DC7C67DE3D87730@BY2PR0301MB0743.namprd03.prod.outlook.com>
Message-ID: <CAKv+Gu-SH7MjkrgevfcUurPc7iQm+11cntfEo84opkqQoN2YPQ@mail.gmail.com>

On 7 aug. 2015, at 21:01, Stuart Yoder <stuart.yoder at freescale.com> wrote:

>> Whether defconfig supports your platform optimally has nothing to do
>> with that. Of course, we should deal with the unexpected memory layout
>> gracefully, which is why Mark Rutland and myself proposed patches to
>> fix the panic you reported. But in a development context, I think it
>> is perfectly acceptable to simply load the kernel at 0x80_8000_0000,
>> and be able to run defconfig fine while losing just 2 GB of your 16 GB
>> at the low end.
>
> I've done this experiment-- loading/running the kernel at 0x80_8000_0000
> and losing the lower 2GB of memory.  And in fact I can see the kernel
> ignoring the low memory:
>
>   [    0.000000] Ignoring memory block 0x80000000 - 0x100000000
>

Yes that looks correct

> However, this only works with 48-bit VA enabled.  With 39-bit VA
> enabled the kernel crashes before the early console is working
> and I see nothing.
>

That may well be a kernel bug: the changes to allow 39-bit VA kernels
to execute on systems whose memory is outside the 39-bit VA range was
developed and tested on AMD Seattle only, which has its RAM at
0x80_0000_0000. But it is hard to be sure, of course, with no output
at all ...

> Does the linear mapping we've been talking about just need to cover
> all of _RAM_, or does it need to cover all of I/O as well in
> the same mapping.
>
> In our case we have various SoC I/O devices, like the UART
> in the space below 4 GB... at 0x0100_0000.
>

The linear mapping only covers system RAM, so that should not matter at all.

> Before debugging further I want to check whether this should
> work in theory.  I had the impression that the issue was
> discontiguous RAM regions, and I/O was a separate issue.

Yes, it should work in theory. The linear region starts at the base of
the kernel Image, and extends all the way up to the end of DRAM (14 GB
in your case, IIRC)

-- 
Ard.


From linux at arm.linux.org.uk  Sat Aug  8 02:22:52 2015
From: linux at arm.linux.org.uk (Russell King - ARM Linux)
Date: Sat, 8 Aug 2015 10:22:52 +0100
Subject: [PATCH v5 1/2] usb: make xhci platform driver use 64 bit or 32
 bit DMA
In-Reply-To: <74fe0b014334a5ac1db90dec46bdbf6c30c07895.1439002338.git.dhdang@apm.com>
References: <CADaLNDkU14GCPZE_zNt_9kMSsUdywyNp1QCiWpokXQgbfRS0qw@mail.gmail.com>
 <74fe0b014334a5ac1db90dec46bdbf6c30c07895.1439002338.git.dhdang@apm.com>
Message-ID: <20150808092252.GJ7557@n2100.arm.linux.org.uk>

On Fri, Aug 07, 2015 at 08:18:48PM -0700, Duc Dang wrote:
> diff --git a/drivers/usb/host/xhci-plat.c b/drivers/usb/host/xhci-plat.c
> index 890ad9d..5d03f8b 100644
> --- a/drivers/usb/host/xhci-plat.c
> +++ b/drivers/usb/host/xhci-plat.c
> @@ -93,14 +93,14 @@ static int xhci_plat_probe(struct platform_device *pdev)
>  	if (irq < 0)
>  		return -ENODEV;
>  
> -	/* Initialize dma_mask and coherent_dma_mask to 32-bits */
> -	ret = dma_set_coherent_mask(&pdev->dev, DMA_BIT_MASK(32));
> -	if (ret)
> -		return ret;
> -	if (!pdev->dev.dma_mask)
> -		pdev->dev.dma_mask = &pdev->dev.coherent_dma_mask;
> -	else
> -		dma_set_mask(&pdev->dev, DMA_BIT_MASK(32));
> +	/* Try setting the coherent_dma_mask to 64 bits, then try 32 bits */
> +	ret = dma_set_mask_and_coherent(&pdev->dev, DMA_BIT_MASK(64));
> +	if (ret) {
> +		ret = dma_set_mask_and_coherent(&pdev->dev, DMA_BIT_MASK(32));
> +		if (ret)
> +			return ret;
> +	}

Note that dma_set_mask_and_coherent() and the original code are not
equivalent because of this:

	if (!pdev->dev.dma_mask)
		pdev->dev.dma_mask = &pdev->dev.coherent_dma_mask;

If we know that pdev->dev.dma_mask will always be initialised at this
point, then the above change is fine.  If not, it's introducing a
regression - dma_set_mask_and_coherent() will fail if pdev->dev.dma_mask
is NULL (depending on the architectures implementation of dma_set_mask()).

Prefixing the above change with the two lines I mention above would
ensure equivalent behaviour.  Even if we do want to get rid of this,
I'd advise to do it as a separate patch after this change, which can
be independently reverted if there's problems with its removal.

-- 
FTTC broadband for 0.8mile line: currently at 10.5Mbps down 400kbps up
according to speedtest.net.


From alexandre.belloni at free-electrons.com  Sat Aug  8 03:11:11 2015
From: alexandre.belloni at free-electrons.com (Alexandre Belloni)
Date: Sat,  8 Aug 2015 12:11:11 +0200
Subject: [PATCH] ARM: at91: debug: use DEBUG_UART_PHYS
Message-ID: <1439028671-22131-1-git-send-email-alexandre.belloni@free-electrons.com>

Instead of having to add a new configuration option each time support for
new SoC is added, use CONFIG_DEBUG_UART_PHYS. For now,
CONFIG_DEBUG_UART_VIRT is automatically computed.

Signed-off-by: Alexandre Belloni <alexandre.belloni at free-electrons.com>
---
 arch/arm/Kconfig.debug        | 41 ++++++++++++++++-------------------------
 arch/arm/include/debug/at91.S | 18 ++++--------------
 2 files changed, 20 insertions(+), 39 deletions(-)

diff --git a/arch/arm/Kconfig.debug b/arch/arm/Kconfig.debug
index 946c8c0fa1fb..3ba23d0f5c55 100644
--- a/arch/arm/Kconfig.debug
+++ b/arch/arm/Kconfig.debug
@@ -123,29 +123,23 @@ choice
 		    0x80020000      | 0xf0020000     | UART8
 		    0x80024000      | 0xf0024000     | UART9
 
-	config AT91_DEBUG_LL_DBGU0
-		bool "Kernel low-level debugging on rm9200, 9260/9g20, 9261/9g10, 9rl, 9x5, 9n12"
-		select DEBUG_AT91_UART
+	config DEBUG_AT91_UART
+		bool "Kernel low-level debugging on Atmel SoCs"
 		depends on ARCH_AT91
-		depends on SOC_AT91RM9200 || SOC_AT91SAM9
+		help
+		  Say Y here if you want the debug print routines to direct
+		  their output to the serial port on atmel devices.
 
-	config AT91_DEBUG_LL_DBGU1
-		bool "Kernel low-level debugging on 9263, 9g45 and sama5d3"
-		select DEBUG_AT91_UART
-		depends on ARCH_AT91
-		depends on SOC_AT91SAM9 || SOC_SAMA5
+		  SOC                  DEBUG_UART_PHYS   DEBUG_UART_VIRT  PORT
+		  rm9200, 9260/9g20,   0xfffff200        0xfefff200       DBGU
+		  9261/9g10, 9rl
+		  9263, 9g45, sama5d3  0xffffee00        0xfeffee00       DBGU
+		  sama5d4              0xfc00c000        0xfb00c000       USART3
+		  sama5d4              0xfc069000        0xfb069000       DBGU
+		  sama5d2              0xf8020000        0xf7020000       UART1
 
-	config AT91_DEBUG_LL_DBGU2
-		bool "Kernel low-level debugging on sama5d4"
-		select DEBUG_AT91_UART
-		depends on ARCH_AT91
-		depends on SOC_SAMA5
-
-	config AT91_DEBUG_LL_DBGU3
-		bool "Kernel low-level debugging on sama5d2"
-		select DEBUG_AT91_UART
-		depends on ARCH_AT91
-		depends on SOC_SAMA5
+		  Please adjust DEBUG_UART_PHYS configuration options based on
+		  your needs.
 
 	config DEBUG_BCM2835
 		bool "Kernel low-level debugging on BCM2835 PL011 UART"
@@ -1242,10 +1236,6 @@ choice
 
 endchoice
 
-config DEBUG_AT91_UART
-	bool
-	depends on ARCH_AT91
-
 config DEBUG_EXYNOS_UART
 	bool
 
@@ -1476,7 +1466,8 @@ config DEBUG_UART_PHYS
 		DEBUG_RMOBILE_SCIFA0 || DEBUG_RMOBILE_SCIFA1 || \
 		DEBUG_RMOBILE_SCIFA4 || DEBUG_S3C24XX_UART || \
 		DEBUG_UART_BCM63XX || DEBUG_ASM9260_UART || \
-		DEBUG_SIRFSOC_UART || DEBUG_DIGICOLOR_UA0
+		DEBUG_SIRFSOC_UART || DEBUG_DIGICOLOR_UA0 || \
+		DEBUG_AT91_UART
 
 config DEBUG_UART_VIRT
 	hex "Virtual base address of debug UART"
diff --git a/arch/arm/include/debug/at91.S b/arch/arm/include/debug/at91.S
index 2556a8801c8c..43243be94cfc 100644
--- a/arch/arm/include/debug/at91.S
+++ b/arch/arm/include/debug/at91.S
@@ -9,32 +9,22 @@
  *
 */
 
-#if defined(CONFIG_AT91_DEBUG_LL_DBGU0)
-#define AT91_DBGU 0xfffff200 /* AT91_BASE_DBGU0 */
-#elif defined(CONFIG_AT91_DEBUG_LL_DBGU1)
-#define AT91_DBGU 0xffffee00 /* AT91_BASE_DBGU1 */
-#elif defined(CONFIG_AT91_DEBUG_LL_DBGU2)
-/* On sama5d4, use USART3 as low level serial console */
-#define AT91_DBGU 0xfc00c000 /* SAMA5D4_BASE_USART3 */
-#else
-/* On sama5d2, use UART1 as low level serial console */
-#define AT91_DBGU 0xf8020000
-#endif
-
 #ifdef CONFIG_MMU
 #define AT91_IO_P2V(x) ((x) - 0x01000000)
 #else
 #define AT91_IO_P2V(x) (x)
 #endif
 
+#define CONFIG_DEBUG_UART_VIRT AT91_IO_P2V(CONFIG_DEBUG_UART_PHYS)
+
 #define AT91_DBGU_SR		(0x14)	/* Status Register */
 #define AT91_DBGU_THR		(0x1c)	/* Transmitter Holding Register */
 #define AT91_DBGU_TXRDY		(1 << 1)	/* Transmitter Ready */
 #define AT91_DBGU_TXEMPTY	(1 << 9)	/* Transmitter Empty */
 
 	.macro	addruart, rp, rv, tmp
-	ldr	\rp, =AT91_DBGU				@ System peripherals (phys address)
-	ldr	\rv, =AT91_IO_P2V(AT91_DBGU)		@ System peripherals (virt address)
+	ldr	\rp, =CONFIG_DEBUG_UART_PHYS		@ System peripherals (phys address)
+	ldr	\rv, =CONFIG_DEBUG_UART_VIRT		@ System peripherals (virt address)
 	.endm
 
 	.macro	senduart,rd,rx
-- 
2.1.4



From heiko at sntech.de  Sat Aug  8 03:27:25 2015
From: heiko at sntech.de (Heiko =?ISO-8859-1?Q?St=FCbner?=)
Date: Sat, 08 Aug 2015 12:27:25 +0200
Subject: [PATCH 1/3] ARM: dts: rockchip: set correct dwc2 params for
 cortex-a9 socs
In-Reply-To: <1617149.AMXNNUATDo@diego>
References: <1617149.AMXNNUATDo@diego>
Message-ID: <1512558.RdU3anUM3L@diego>

Am Sonntag, 2. August 2015, 23:43:12 schrieb Heiko St?bner:
> According to the manual, the fifo sizes are the same as on later socs
> like the rk3288 and this also fixes an error about "insufficient fifo
> memory", as it seems the values read from the ip are wrong.
> 
> Signed-off-by: Heiko Stuebner <heiko at sntech.de>
> ---

applied all 3 patches to my dts branch


From heiko at sntech.de  Sat Aug  8 03:32:50 2015
From: heiko at sntech.de (Heiko =?ISO-8859-1?Q?St=FCbner?=)
Date: Sat, 08 Aug 2015 12:32:50 +0200
Subject: [PATCH v2 2/2] ARM: dts: rockchip: add veyron-minnie board
In-Reply-To: <3051758.nWNxbUbTXs@diego>
References: <1763907.pckMEaRNPs@diego> <3051758.nWNxbUbTXs@diego>
Message-ID: <1717731.vRKiVuqZ53@diego>

Am Donnerstag, 6. August 2015, 19:37:54 schrieb Heiko St?bner:
> From: Alexandru M Stan <amstan at chromium.org>
> 
> Also known as the Asus Chromebook Flip.
> 
> Signed-off-by: Alexandru M Stan <amstan at chromium.org>
> Signed-off-by: Heiko Stuebner <heiko at sntech.de>

applied both patches with Dougs Reviewed-by after dropping the touchscreen 
nodes from the initial set.


From arnd at arndb.de  Sat Aug  8 04:26:23 2015
From: arnd at arndb.de (Arnd Bergmann)
Date: Sat, 08 Aug 2015 13:26:23 +0200
Subject: [PATCH 2/2] net, thunder, bgx: Add support for ACPI binding.
In-Reply-To: <20150807104320.GQ1820@rric.localhost>
References: <1438907590-29649-1-git-send-email-ddaney.cavm@gmail.com>
 <55C467A0.4020601@linaro.org> <20150807104320.GQ1820@rric.localhost>
Message-ID: <2414262.jivbxTLuUW@wuerfel>

On Friday 07 August 2015 12:43:20 Robert Richter wrote:
> 
> I would not pollute bgx_probe() with acpi and dt specifics, and instead
> keep bgx_init_phy(). The typical design pattern for this is:
> 
> static int bgx_init_phy(struct bgx *bgx)
> {
> #ifdef CONFIG_ACPI
>         if (!acpi_disabled)
>                 return bgx_init_acpi_phy(bgx);
> #endif
>         return bgx_init_of_phy(bgx);
> }
> 
> This adds acpi runtime detection (acpi=no), does not call dt code in
> case of acpi, and saves the #else for bgx_init_acpi_phy().
> 

What you should really do is to use the same function for both,
using the generic device properties API. If that is not possible,
explain in a comment why not.

Aside from that, if you do have to use compile-time conditionals,
use 'if (IS_ENABLED(CONFIG_ACPI) && !acpi_disabled)' instead of
#ifdef, for readability. The compiler will produce the same binary,
but also give helpful warnings about incorrect code that you don't
get with #ifdef.

	Arnd



From arnd at arndb.de  Sat Aug  8 04:42:50 2015
From: arnd at arndb.de (Arnd Bergmann)
Date: Sat, 08 Aug 2015 13:42:50 +0200
Subject: [BUG, RFC] MTD Execute in Place on ARM breaks build
In-Reply-To: <55C51319.2010901@tul.cz>
References: <55C51319.2010901@tul.cz>
Message-ID: <1564596.BEQS8u7XSM@wuerfel>

On Friday 07 August 2015 22:20:41 Petr Cvek wrote:
> Hello,
> 
> Configuration:
> 
> 	CONFIG_MTD_XIP=y
> 
> on PXA2xx architecture causes request of undefined macros from 
> 
> 	drivers/mtd/chipscfi_cmdset_0001.c
> 
> These macros (using ICIP and ICMR) are defined here:
> 
> 	http://lxr.free-electrons.com/source/arch/arm/mach-pxa/include/mach/mtd-xip.h#L20
> 
> register definitions for ICIP and ICMR were removed by commit:
> 	
> 	5d284e353eb11ab2e8b1c5671ba06489b0bd1e0c
> 
> Similar is for macros with OSCR (lines 23 and 24), which have different type.
> Re-adding ICIP and ICMR definition and explicit type conversion will fix the build
> and the kernel boots, but I'm not yet able to test XIP functionality (too many different
> bugs to flash over windows mobile image).
>
> My temporal fix (ugly):
> 
> #define ICIP __REG(0x40D00000)  /* Interrupt Controller IRQ Pending Register */
> #define ICMR __REG(0x40D00004)  /* Interrupt Controller Mask Register */
> ...
> #define xip_currtime()		((unsigned long) OSCR)
> #define xip_elapsed_since(x)	(signed)((((unsigned long) OSCR) - (x)) / 4)


Macros that do implicit pointer dereferences are discouraged, a better way to
write them is

	#define xip_currtime()	readl_relaxed(OSCR)

with the OSCR definition from arch/arm/mach-pxa/include/mach/regs-ost.h.

> P.S. Same macros are used on omap1 and sa1100 too.

There is a (slow) effort to move both omap1 and pxa into ARCH_MULTIPLATFORM
in the long run, and at that point we have to come up with something
better. The easiest way out would be to replace the functions with
function pointers that can be set by platform specific code.

A cleaner approach might be to replace xip_currtime() with
ktime_get_ns(), and find some other generic interface to replace
xip_irqpending. That would let us eliminate the mach/mtd-xip.h
header entirely and make mtd-xip portablel to a lot of other
platforms.

For a real multiplatform kernel, you'd also need to replace the
#ifdef CONFIG_MTD_XIP instances with a runtime conditional, but that
is less urgent for real world use cases.

	Arnd


From yamada.masahiro at socionext.com  Sat Aug  8 04:56:47 2015
From: yamada.masahiro at socionext.com (Masahiro Yamada)
Date: Sat, 8 Aug 2015 20:56:47 +0900
Subject: [PATCH] ARM: refactor bitops functions with BIT_MASK() and
 BIT_WORD()
In-Reply-To: <1437461324-7284-1-git-send-email-yamada.masahiro@socionext.com>
References: <1437461324-7284-1-git-send-email-yamada.masahiro@socionext.com>
Message-ID: <CAK7LNAQpU_S-dUZ+z9eXsJP7gVMYitHa40JpLHNevN5479oU8Q@mail.gmail.com>

Hi.

No comment?

If nobody has objection to this patch,
I will post it to the patch tracking system.




2015-07-21 15:48 GMT+09:00 Masahiro Yamada <yamada.masahiro at socionext.com>:
> Use BIT_MASK() and BIT_WORD() rather than hard-coding the size
> of the "long" type.
>
> Signed-off-by: Masahiro Yamada <yamada.masahiro at socionext.com>
> ---
>
>  arch/arm/include/asm/bitops.h | 24 ++++++++++++------------
>  1 file changed, 12 insertions(+), 12 deletions(-)
>
> diff --git a/arch/arm/include/asm/bitops.h b/arch/arm/include/asm/bitops.h
> index 5638099..e943e6c 100644
> --- a/arch/arm/include/asm/bitops.h
> +++ b/arch/arm/include/asm/bitops.h
> @@ -35,9 +35,9 @@
>  static inline void ____atomic_set_bit(unsigned int bit, volatile unsigned long *p)
>  {
>         unsigned long flags;
> -       unsigned long mask = 1UL << (bit & 31);
> +       unsigned long mask = BIT_MASK(bit);
>
> -       p += bit >> 5;
> +       p += BIT_WORD(bit);
>
>         raw_local_irq_save(flags);
>         *p |= mask;
> @@ -47,9 +47,9 @@ static inline void ____atomic_set_bit(unsigned int bit, volatile unsigned long *
>  static inline void ____atomic_clear_bit(unsigned int bit, volatile unsigned long *p)
>  {
>         unsigned long flags;
> -       unsigned long mask = 1UL << (bit & 31);
> +       unsigned long mask = BIT_MASK(bit);
>
> -       p += bit >> 5;
> +       p += BIT_WORD(bit);
>
>         raw_local_irq_save(flags);
>         *p &= ~mask;
> @@ -59,9 +59,9 @@ static inline void ____atomic_clear_bit(unsigned int bit, volatile unsigned long
>  static inline void ____atomic_change_bit(unsigned int bit, volatile unsigned long *p)
>  {
>         unsigned long flags;
> -       unsigned long mask = 1UL << (bit & 31);
> +       unsigned long mask = BIT_MASK(bit);
>
> -       p += bit >> 5;
> +       p += BIT_WORD(bit);
>
>         raw_local_irq_save(flags);
>         *p ^= mask;
> @@ -73,9 +73,9 @@ ____atomic_test_and_set_bit(unsigned int bit, volatile unsigned long *p)
>  {
>         unsigned long flags;
>         unsigned int res;
> -       unsigned long mask = 1UL << (bit & 31);
> +       unsigned long mask = BIT_MASK(bit);
>
> -       p += bit >> 5;
> +       p += BIT_WORD(bit);
>
>         raw_local_irq_save(flags);
>         res = *p;
> @@ -90,9 +90,9 @@ ____atomic_test_and_clear_bit(unsigned int bit, volatile unsigned long *p)
>  {
>         unsigned long flags;
>         unsigned int res;
> -       unsigned long mask = 1UL << (bit & 31);
> +       unsigned long mask = BIT_MASK(bit);
>
> -       p += bit >> 5;
> +       p += BIT_WORD(bit);
>
>         raw_local_irq_save(flags);
>         res = *p;
> @@ -107,9 +107,9 @@ ____atomic_test_and_change_bit(unsigned int bit, volatile unsigned long *p)
>  {
>         unsigned long flags;
>         unsigned int res;
> -       unsigned long mask = 1UL << (bit & 31);
> +       unsigned long mask = BIT_MASK(bit);
>
> -       p += bit >> 5;
> +       p += BIT_WORD(bit);
>
>         raw_local_irq_save(flags);
>         res = *p;
> --
> 1.9.1
>
>
> _______________________________________________
> linux-arm-kernel mailing list
> linux-arm-kernel at lists.infradead.org
> http://lists.infradead.org/mailman/listinfo/linux-arm-kernel



-- 
Best Regards
Masahiro Yamada


From yamada.masahiro at socionext.com  Sat Aug  8 05:11:39 2015
From: yamada.masahiro at socionext.com (Masahiro Yamada)
Date: Sat,  8 Aug 2015 21:11:39 +0900
Subject: [PATCH] ARM: Feroceon: use of_iomap() to map register base
Message-ID: <1439035899-1783-1-git-send-email-yamada.masahiro@socionext.com>

The sequence of of_address_to_resource() and ioremap() can be
replaced with of_iomap().

Signed-off-by: Masahiro Yamada <yamada.masahiro at socionext.com>
---

 arch/arm/mm/cache-feroceon-l2.c | 6 +-----
 1 file changed, 1 insertion(+), 5 deletions(-)

diff --git a/arch/arm/mm/cache-feroceon-l2.c b/arch/arm/mm/cache-feroceon-l2.c
index 097181e..5c1b7a7 100644
--- a/arch/arm/mm/cache-feroceon-l2.c
+++ b/arch/arm/mm/cache-feroceon-l2.c
@@ -368,7 +368,6 @@ int __init feroceon_of_init(void)
 	struct device_node *node;
 	void __iomem *base;
 	bool l2_wt_override = false;
-	struct resource res;
 
 #if defined(CONFIG_CACHE_FEROCEON_L2_WRITETHROUGH)
 	l2_wt_override = true;
@@ -376,10 +375,7 @@ int __init feroceon_of_init(void)
 
 	node = of_find_matching_node(NULL, feroceon_ids);
 	if (node && of_device_is_compatible(node, "marvell,kirkwood-cache")) {
-		if (of_address_to_resource(node, 0, &res))
-			return -ENODEV;
-
-		base = ioremap(res.start, resource_size(&res));
+		base = of_iomap(node, 0);
 		if (!base)
 			return -ENOMEM;
 
-- 
1.9.1



From yamada.masahiro at socionext.com  Sat Aug  8 05:13:44 2015
From: yamada.masahiro at socionext.com (Masahiro Yamada)
Date: Sat,  8 Aug 2015 21:13:44 +0900
Subject: [PATCH] ARM: UniPhier: drop v7_invalidate_l1 call at secondary entry
Message-ID: <1439036024-1933-1-git-send-email-yamada.masahiro@socionext.com>

This is unnecessary since commit 02b4e2756e01 ("ARM: v7 setup
function should invalidate L1 cache").

Signed-off-by: Masahiro Yamada <yamada.masahiro at socionext.com>
---

 arch/arm/mach-uniphier/platsmp.c | 8 +-------
 1 file changed, 1 insertion(+), 7 deletions(-)

diff --git a/arch/arm/mach-uniphier/platsmp.c b/arch/arm/mach-uniphier/platsmp.c
index 5943e1c..4b784f7 100644
--- a/arch/arm/mach-uniphier/platsmp.c
+++ b/arch/arm/mach-uniphier/platsmp.c
@@ -60,12 +60,6 @@ err:
 	sbcm_regmap = NULL;
 }
 
-static void __naked uniphier_secondary_startup(void)
-{
-	asm("bl		v7_invalidate_l1\n"
-	    "b		secondary_startup\n");
-};
-
 static int uniphier_boot_secondary(unsigned int cpu,
 				   struct task_struct *idle)
 {
@@ -75,7 +69,7 @@ static int uniphier_boot_secondary(unsigned int cpu,
 		return -ENODEV;
 
 	ret = regmap_write(sbcm_regmap, 0x1208,
-			   virt_to_phys(uniphier_secondary_startup));
+			   virt_to_phys(secondary_startup));
 	if (!ret)
 		asm("sev"); /* wake up secondary CPU */
 
-- 
1.9.1



From yamada.masahiro at socionext.com  Sat Aug  8 05:29:58 2015
From: yamada.masahiro at socionext.com (Masahiro Yamada)
Date: Sat, 8 Aug 2015 21:29:58 +0900
Subject: [PATCH] ARM: add boot image dependencies not to generate invalid
 images
In-Reply-To: <CAK7LNARe25AX6gLxHaSb3YANcx=10WW0cisKUnZY-mWFAUiGow@mail.gmail.com>
References: <1436186224-6673-1-git-send-email-yamada.masahiro@socionext.com>
 <20150710102222.GP7557@n2100.arm.linux.org.uk>
 <CAK7LNAS9L1GEpCfrA7YNzifFfwNbhHFy5ia=wy=Wyuho11BOnw@mail.gmail.com>
 <CAK7LNARe25AX6gLxHaSb3YANcx=10WW0cisKUnZY-mWFAUiGow@mail.gmail.com>
Message-ID: <CAK7LNASto6_AMF=f3p7scjdUN8Mscp10v1z4LrQUMwtZn8qw9w@mail.gmail.com>

Hi Russell,

I will rephrase the git-description and post v2.





2015-07-21 15:58 GMT+09:00 Masahiro Yamada <yamada.masahiro at socionext.com>:
> Hi Russel,
>
> No more comment?
> I answered your question.
>
>
>
>
> 2015-07-11 1:41 GMT+09:00 Masahiro Yamada <yamada.masahiro at socionext.com>:
>> Hi Russel,
>>
>>
>> 2015-07-10 19:22 GMT+09:00 Russell King - ARM Linux <linux at arm.linux.org.uk>:
>>> On Mon, Jul 06, 2015 at 09:37:04PM +0900, Masahiro Yamada wrote:
>>>> [3] Then, re-build "all" and "uImage" simultaneously.
>>>>     You will get an invalid uImage at random.
>>>>   $ make -s -j8 ARCH=arm UIMAGE_LOADADDR=0x80208000 all uImage
>>>>   Image Name:   Linux-4.2.0-rc1-00008-g1c4c715-d
>>>>   Created:      Mon Jul  6 17:52:22 2015
>>>>   Image Type:   ARM Linux Kernel Image (uncompressed)
>>>>   Data Size:    26768 Bytes = 26.14 kB = 0.03 MB
>>>>   Load Address: 80208000
>>>>   Entry Point:  80208000
>>>
>>> At no point in the above do I see an attempt to rebuild init/main.o,
>>> which there should be as you touched the corresponding .c file -
>>> because you're hiding that output with -s.  Please show what's going
>>> on without using -s.
>>
>> Please see the log attached at the end of this message.
>>
>>
>>>> "make uImage" could descend into arch/arm/boot/Makefile before
>>>> "make zImage" is completed because arch/arm/Makefile describes no
>>>> dependency among boot targets.
>>>
>>> The uImage target should depend on vmlinux, which should force the
>>> rebuild of init/main.o, and relink of the top-level vmlinux file
>>> before decending into arch/arm/boot/Makefile for the
>>> arch/arm/boot/uImage target.
>>>
>>> That makefile contains the dependencies required to order things
>>> correctly - the arch/arm/boot/uImage target depends on
>>> arch/arm/boot/zImage, which in turn depends on
>>> arch/arm/boot/compressed/vmlinux, and then arch/arm/boot/Image.
>>>
>>> In other words, arch/arm/boot/Makefile deals with the dependencies
>>> between the targets it's responsible for building itself.
>>
>> No, you do not understand what is happening in here.
>>
>>
>> The dependencies among targets such as Image, zImage, uImage,
>> are fully described in arch/arm/boot/Makefile, but it is not enough.
>>
>> Because arch/arm/boot/Makefile is _not_ included from the top-level Makefile,
>> the top-level build cannot know the dependency between zImage and uImage.
>>
>> arch/arm/Makefile, which is included from the top Makefile,
>> only describes that zImage depends on vmlinux,
>> and uImage depends on vmlinux as well.
>> But, no dependency between zImage and uImage is written in arch/arm/Makefile.
>>
>> Consequently, we run make with the parallel option, first Kbuild
>> updates vmlinux,
>> and then two different threads descends into arch/arm/boot/Makefile
>> almost at the same time, one for updating zImage and the other for uImage.
>>
>> The is a race between the two threads.
>>
>> While one thread is re-generating zImage and also uImage on top of that,
>> the other thread tries to re-generate zImage independently.
>>
>> zImage is overwritten by the slower thread, and then uImage is
>> re-generated based on the broken zImage.
>>
>> See my detailed build log below:
>>
>> Please note:
>> "Kernel: arch/arm/boot/zImage is ready"
>> is displayed twice,
>> the first one is shown before the uImage log, and the second one is
>> after uImage.
>>
>> zImage is correct, but uImage is extremely small when this problem happens.
>>
>>
>>
>> $ git describe
>> v4.2-rc1-62-gc4b5fd3
>>
>>
>> $ touch init/main.c
>> $ make -j8 ARCH=arm UIMAGE_LOADADDR=0x80208000 all uImage
>>   CHK     include/config/kernel.release
>>   CHK     include/generated/uapi/linux/version.h
>>   CHK     include/generated/utsrelease.h
>> make[1]: `include/generated/mach-types.h' is up to date.
>>   CHK     include/generated/timeconst.h
>>   CHK     include/generated/bounds.h
>>   CHK     include/generated/asm-offsets.h
>>   CALL    scripts/checksyscalls.sh
>>   CC      init/main.o
>>   CHK     include/generated/compile.h
>>   LD      init/built-in.o
>>   LINK    vmlinux
>>   LD      vmlinux.o
>>   MODPOST vmlinux.o
>>   GEN     .version
>>   CHK     include/generated/compile.h
>>   UPD     include/generated/compile.h
>>   CC      init/version.o
>>   LD      init/built-in.o
>>   KSYM    .tmp_kallsyms1.o
>>   KSYM    .tmp_kallsyms2.o
>>   LD      vmlinux
>>   SORTEX  vmlinux
>>   SYSMAP  System.map
>>   OBJCOPY arch/arm/boot/Image
>>   Building modules, stage 2.
>>   Kernel: arch/arm/boot/Image is ready
>>   GZIP    arch/arm/boot/compressed/piggy.gzip
>>   AS      arch/arm/boot/compressed/piggy.gzip.o
>>   Kernel: arch/arm/boot/Image is ready
>>   GZIP    arch/arm/boot/compressed/piggy.gzip
>>   LD      arch/arm/boot/compressed/vmlinux
>>   OBJCOPY arch/arm/boot/zImage
>>   Kernel: arch/arm/boot/zImage is ready
>>   UIMAGE  arch/arm/boot/uImage
>> Image Name:   Linux-4.2.0-rc1-00062-gc4b5fd3-d
>> Created:      Sat Jul 11 01:22:22 2015
>> Image Type:   ARM Linux Kernel Image (uncompressed)
>> Data Size:    26472 Bytes = 25.85 kB = 0.03 MB
>> Load Address: 80208000
>> Entry Point:  80208000
>>   Image arch/arm/boot/uImage is ready
>>   MODPOST 192 modules
>>   AS      arch/arm/boot/compressed/piggy.gzip.o
>>   LD      arch/arm/boot/compressed/vmlinux
>>   OBJCOPY arch/arm/boot/zImage
>>   Kernel: arch/arm/boot/zImage is ready
>> $ LANG=C ls -l arch/arm/boot/
>> total 19636
>> -rwxrwxr-x 1 masahiro masahiro 13766656 Jul 11 01:22 Image
>> -rw-rw-r-- 1 masahiro masahiro     3137 Jul  3 01:17 Makefile
>> drwxrwxr-x 2 masahiro masahiro     4096 Jul  3 01:17 bootp
>> drwxrwxr-x 2 masahiro masahiro     4096 Jul 11 01:22 compressed
>> drwxrwxr-x 3 masahiro masahiro   155648 Jul 11 00:58 dts
>> -rw-rw-r-- 1 masahiro masahiro     1648 Jul  3 01:17 install.sh
>> -rw-rw-r-- 1 masahiro masahiro    26536 Jul 11 01:22 uImage
>> -rwxrwxr-x 1 masahiro masahiro  6135048 Jul 11 01:22 zImage
>>
>>
>>
>>
>>
>>
>>
>> --
>> Best Regards
>> Masahiro Yamada
>
>
>
> --
> Best Regards
> Masahiro Yamada



-- 
Best Regards
Masahiro Yamada


From vz at mleia.com  Sat Aug  8 05:51:54 2015
From: vz at mleia.com (Vladimir Zapolskiy)
Date: Sat, 08 Aug 2015 15:51:54 +0300
Subject: [PATCH 0/8] misc: remove boundary checks from bin attr users
In-Reply-To: <20150807223456.GA1527@katana>
References: <1437945502-27944-1-git-send-email-vz@mleia.com>
 <20150807161055.GD25357@katana> <55C4D9B2.3000708@mleia.com>
 <20150807223456.GA1527@katana>
Message-ID: <55C5FB6A.5010300@mleia.com>

Hi Wolfram,

On 08.08.2015 01:34, Wolfram Sang wrote:
> 
>> if we're talking about this particular series, you should have them in
>> your mailbox, since you have them applied in wsa/i2c/for-next:
> 
> Those are already in linus tree. I mean all drivers which use struct
> i2c_driver. Or do you prefer they go via Greg? I am fine with both.
> 

I think you may find most of the changes applied by Greg into
misc/char-misc-next branch.

The only change from the series, which is not found in
misc/char-misc-next or i2c/for-next is related to at25 driver (IC is
sitting on SPI):

  https://lkml.org/lkml/2015/7/26/101

Change 8/8 for sunxi is outdated due to accepted NVMEM framework.

With best wishes,
Vladimir


From linux at arm.linux.org.uk  Sat Aug  8 06:47:09 2015
From: linux at arm.linux.org.uk (Russell King - ARM Linux)
Date: Sat, 8 Aug 2015 14:47:09 +0100
Subject: [BUG, RFC] MTD Execute in Place on ARM breaks build
In-Reply-To: <1564596.BEQS8u7XSM@wuerfel>
References: <55C51319.2010901@tul.cz>
 <1564596.BEQS8u7XSM@wuerfel>
Message-ID: <20150808134708.GK7557@n2100.arm.linux.org.uk>

On Sat, Aug 08, 2015 at 01:42:50PM +0200, Arnd Bergmann wrote:
> A cleaner approach might be to replace xip_currtime() with
> ktime_get_ns(), and find some other generic interface to replace
> xip_irqpending.

Definitely not.

The issue here is that the kernel sits in flash.  When we want to write
to flash, we need to switch the flash into a mode where the data
contained in the flash becomes unreadable - reading from it results in
status bytes being returned.  Status bytes are not executable.

To get around that problem, we have a small amount of code in RAM which
does the flash erasing and/or programming.  This code, however, needs
to have access to the interrupt controller and timer.

Calling generic functions that would be part of the paged-out kernel
image is just not possible; doing so will immediately crash the kernel
and break what's being achieved here.  You'd need to mark these functions
and any functions that they then call (including spinlocks, probably
the entire lockdep infrastructure, etc) with __xipram.  I don't think
that's feasible.

In any case, I don't think XIP multiplatform makes any sense what so
ever.  Needless to say, it _could_ be made to work, but you're likely
need some complexity, and given that it has very few users, I don't
think there's much to be gained from putting that work in.  We've even
talked a few times about removing XIP support altogether.

-- 
FTTC broadband for 0.8mile line: currently at 10.5Mbps down 400kbps up
according to speedtest.net.


From kwizart at gmail.com  Sat Aug  8 06:58:12 2015
From: kwizart at gmail.com (Nicolas Chauvet)
Date: Sat,  8 Aug 2015 15:58:12 +0200
Subject: [PATCH] [ARM][TEGRA] Fix AHB base address on tegra20,
 tegra30 and tegra114
Message-ID: <1439042292-19912-1-git-send-email-kwizart@gmail.com>

Current base address is wrong by 0x04 bytes for AHB bus device as shown in dmesg:
 tegra-ahb 6000c004.ahb: incorrect AHB base address in DT data - enabling workaround

To correct old dtbs,  the commit ce7a10b0ff3db63 checks for the low bit
of the base address and removes theses 0x04 bytes at runtime.

This patch fix the original dts, so upstream version doesn't need
the workaround of the base address.

As both addresses are valid, this patch doesn't break compatibility

Tested on tegra20-paz00 (aka ac100)

Signed-off-by: Nicolas Chauvet <kwizart at gmail.com>
---
 arch/arm/boot/dts/tegra114.dtsi | 4 ++--
 arch/arm/boot/dts/tegra20.dtsi  | 4 ++--
 arch/arm/boot/dts/tegra30.dtsi  | 4 ++--
 3 files changed, 6 insertions(+), 6 deletions(-)

diff --git a/arch/arm/boot/dts/tegra114.dtsi b/arch/arm/boot/dts/tegra114.dtsi
index f58a3d9..4bdf8f9 100644
--- a/arch/arm/boot/dts/tegra114.dtsi
+++ b/arch/arm/boot/dts/tegra114.dtsi
@@ -214,9 +214,9 @@
 		#dma-cells = <1>;
 	};
 
-	ahb: ahb at 6000c004 {
+	ahb: ahb at 6000c000 {
 		compatible = "nvidia,tegra114-ahb", "nvidia,tegra30-ahb";
-		reg = <0x6000c004 0x14c>;
+		reg = <0x6000c000 0x150>;
 	};
 
 	gpio: gpio at 6000d000 {
diff --git a/arch/arm/boot/dts/tegra20.dtsi b/arch/arm/boot/dts/tegra20.dtsi
index f444b67..f6f1461 100644
--- a/arch/arm/boot/dts/tegra20.dtsi
+++ b/arch/arm/boot/dts/tegra20.dtsi
@@ -225,9 +225,9 @@
 		#dma-cells = <1>;
 	};
 
-	ahb at 6000c004 {
+	ahb at 6000c000 {
 		compatible = "nvidia,tegra20-ahb";
-		reg = <0x6000c004 0x10c>; /* AHB Arbitration + Gizmo Controller */
+		reg = <0x6000c000 0x110>; /* AHB Arbitration + Gizmo Controller */
 	};
 
 	gpio: gpio at 6000d000 {
diff --git a/arch/arm/boot/dts/tegra30.dtsi b/arch/arm/boot/dts/tegra30.dtsi
index 782b11b..559763e 100644
--- a/arch/arm/boot/dts/tegra30.dtsi
+++ b/arch/arm/boot/dts/tegra30.dtsi
@@ -329,9 +329,9 @@
 		#dma-cells = <1>;
 	};
 
-	ahb: ahb at 6000c004 {
+	ahb: ahb at 6000c000 {
 		compatible = "nvidia,tegra30-ahb";
-		reg = <0x6000c004 0x14c>; /* AHB Arbitration + Gizmo Controller */
+		reg = <0x6000c000 0x150>; /* AHB Arbitration + Gizmo Controller */
 	};
 
 	gpio: gpio at 6000d000 {
-- 
2.4.3



From wei.liu2 at citrix.com  Sat Aug  8 06:59:04 2015
From: wei.liu2 at citrix.com (Wei Liu)
Date: Sat, 8 Aug 2015 14:59:04 +0100
Subject: [PATCH v3 01/20] net/xen-netback: xenvif_gop_frag_copy: move GSO
 check out of the loop
In-Reply-To: <1438966019-19322-2-git-send-email-julien.grall@citrix.com>
References: <1438966019-19322-1-git-send-email-julien.grall@citrix.com>
 <1438966019-19322-2-git-send-email-julien.grall@citrix.com>
Message-ID: <20150808135904.GA14214@zion.uk.xensource.com>

On Fri, Aug 07, 2015 at 05:46:40PM +0100, Julien Grall wrote:
> The skb doesn't change within the function. Therefore it's only
> necessary to check if we need GSO once at the beginning.
> 
> Signed-off-by: Julien Grall <julien.grall at citrix.com>
> 

Acked-by: Wei Liu <wei.liu2 at citrix.com>


From viresh.kumar at linaro.org  Sat Aug  8 06:59:36 2015
From: viresh.kumar at linaro.org (Viresh Kumar)
Date: Sat, 8 Aug 2015 19:29:36 +0530
Subject: [PATCH v4 0/6] cpufreq: use generic cpufreq drivers for
 Exynos4x12 platform
In-Reply-To: <55C5AF4E.3010500@samsung.com>
References: <1438868514-8814-1-git-send-email-b.zolnierkie@samsung.com>
 <2359635.Hxe4cb8zKm@amdc1976> <20150807115627.GH6939@linux>
 <1525406.7aXvVQzEDd@vostro.rjw.lan> <20150808020740.GM6939@linux>
 <55C5AF4E.3010500@samsung.com>
Message-ID: <20150808135936.GQ6939@linux>

On 08-08-15, 16:27, Krzysztof Kozlowski wrote:
> Can you apply the 2-5 of this series to v4.3? It's getting late but
> maybe they still could go?

FWIW, 1/6 (updated version) is already applied by Rafael.

-- 
viresh


From jic23 at kernel.org  Sat Aug  8 07:29:47 2015
From: jic23 at kernel.org (Jonathan Cameron)
Date: Sat, 8 Aug 2015 15:29:47 +0100
Subject: [PATCH v2] iio: adc: vf610: Add IIO buffer support for Vybrid ADC
In-Reply-To: <1bb1f290da601bbda41875a92ba6e983b423d7b0.1438775572.git.maitysanchayan@gmail.com>
References: <cover.1438775572.git.maitysanchayan@gmail.com>
 <1bb1f290da601bbda41875a92ba6e983b423d7b0.1438775572.git.maitysanchayan@gmail.com>
Message-ID: <55C6125B.1060103@kernel.org>

On 05/08/15 13:10, Sanchayan Maity wrote:
> This patch adds support for IIO buffer to the Vybrid ADC driver.
> IIO triggered buffer infrastructure along with iio sysfs trigger
> is used to leverage continuous sampling support provided by the
> ADC block.
Looking good.  Just a couple more bits and pieces inline from me.
One or two of which aren't corrected from Peter's review of v1.

I will want Fugang Dong's ack / review tag on the final version
before applying it however.  This driver is some distance form my
area of expertise!

Jonathan
> 
> Signed-off-by: Sanchayan Maity <maitysanchayan at gmail.com>
> ---
>  drivers/iio/adc/Kconfig     |   4 ++
>  drivers/iio/adc/vf610_adc.c | 107 +++++++++++++++++++++++++++++++++++++++++---
>  2 files changed, 105 insertions(+), 6 deletions(-)
> 
> diff --git a/drivers/iio/adc/Kconfig b/drivers/iio/adc/Kconfig
> index 7c55658..4661241 100644
> --- a/drivers/iio/adc/Kconfig
> +++ b/drivers/iio/adc/Kconfig
> @@ -337,6 +337,10 @@ config TWL6030_GPADC
>  config VF610_ADC
>  	tristate "Freescale vf610 ADC driver"
>  	depends on OF
> +	select IIO_BUFFER
> +	select IIO_TRIGGER
> +	select IIO_SYSFS_TRIGGER
Unless I missed something there is no dependency on this particular
trigger (it just happens to be the one you've been testing with I guess).
Could be driven from a hardware trigger belonging to another device for
example.

> +	select IIO_TRIGGERED_BUFFER
>  	help
>  	  Say yes here to support for Vybrid board analog-to-digital converter.
>  	  Since the IP is used for i.MX6SLX, the driver also support i.MX6SLX.
> diff --git a/drivers/iio/adc/vf610_adc.c b/drivers/iio/adc/vf610_adc.c
> index 23b8fb9..97cb2ed 100644
> --- a/drivers/iio/adc/vf610_adc.c
> +++ b/drivers/iio/adc/vf610_adc.c
> @@ -34,8 +34,11 @@
>  #include <linux/err.h>
>  
>  #include <linux/iio/iio.h>
> +#include <linux/iio/buffer.h>
>  #include <linux/iio/sysfs.h>
> -#include <linux/iio/driver.h>
> +#include <linux/iio/trigger.h>
> +#include <linux/iio/trigger_consumer.h>
> +#include <linux/iio/triggered_buffer.h>
>  
>  /* This will be the driver name the kernel reports */
>  #define DRIVER_NAME "vf610-adc"
> @@ -170,6 +173,7 @@ struct vf610_adc {
>  	u32 sample_freq_avail[5];
>  
>  	struct completion completion;
> +	u16 buffer[2];
Note the requirements on the buffer provided to
iio_push_to_buffers_with_timestamp
Needs to be u16 buffer[8] to allow for the aligned 64bit (4 word) timestamp.

Peter pointed this out in his follow up email and you said you'd implement
it.. Guessing this got lost somewhere.


>  };
>  
>  static const u32 vf610_hw_avgs[] = { 1, 4, 8, 16, 32 };
> @@ -505,12 +509,22 @@ static const struct iio_chan_spec_ext_info vf610_ext_info[] = {
>  	.info_mask_shared_by_type = BIT(IIO_CHAN_INFO_SCALE) |	\
>  				BIT(IIO_CHAN_INFO_SAMP_FREQ),	\
>  	.ext_info = vf610_ext_info,				\
> +	.address = (_idx),				\
> +	.scan_index = (_idx),			\
> +	.scan_type.sign = 'u',			\
> +	.scan_type.realbits = 12,		\
> +	.scan_type.storagebits = 16,	\
>  }
>  
>  #define VF610_ADC_TEMPERATURE_CHAN(_idx, _chan_type) {	\
>  	.type = (_chan_type),	\
>  	.channel = (_idx),		\
>  	.info_mask_separate = BIT(IIO_CHAN_INFO_PROCESSED),	\
> +	.address = (_idx),						\
> +	.scan_index = (_idx),					\
.scan_type = {
	   .sign = 'u',
	   etc.

Peter picked up on this..

> +	.scan_type.sign = 'u',					\
> +	.scan_type.realbits = 12,				\
> +	.scan_type.storagebits = 16,			\
>  }
>  
>  static const struct iio_chan_spec vf610_adc_iio_channels[] = {
> @@ -531,6 +545,7 @@ static const struct iio_chan_spec vf610_adc_iio_channels[] = {
>  	VF610_ADC_CHAN(14, IIO_VOLTAGE),
>  	VF610_ADC_CHAN(15, IIO_VOLTAGE),
>  	VF610_ADC_TEMPERATURE_CHAN(26, IIO_TEMP),
> +	IIO_CHAN_SOFT_TIMESTAMP(32),
It's bit extreme throwing it out at scan_index 32.  Is there a reason
to think that migh be neccesary?  Mind you, why is the temperature
channel down at 26?  Are we dealing with a set of reserved real channels
inbetween?
>  	/* sentinel */
>  };
>  
> @@ -559,13 +574,20 @@ static int vf610_adc_read_data(struct vf610_adc *info)
>  
>  static irqreturn_t vf610_adc_isr(int irq, void *dev_id)
>  {
> -	struct vf610_adc *info = (struct vf610_adc *)dev_id;
> +	struct iio_dev *indio_dev = (struct iio_dev *)dev_id;
> +	struct vf610_adc *info = iio_priv(indio_dev);
>  	int coco;
>  
>  	coco = readl(info->regs + VF610_REG_ADC_HS);
>  	if (coco & VF610_ADC_HS_COCO0) {
>  		info->value = vf610_adc_read_data(info);

I'd be tempted to make the non buffered path also use
info->bufffer[0] and drop info->value entirely.
A more invasive patch, but a cleaner resulting code (slightly!)
> -		complete(&info->completion);
> +		if (iio_buffer_enabled(indio_dev)) {
> +			info->buffer[0] = info->value;
> +			iio_push_to_buffers_with_timestamp(indio_dev,
> +					info->buffer, iio_get_time_ns());
> +			iio_trigger_notify_done(indio_dev->trig);
> +		} else
> +			complete(&info->completion);
>  	}
>  
>  	return IRQ_HANDLED;
> @@ -612,6 +634,9 @@ static int vf610_read_raw(struct iio_dev *indio_dev,
>  	switch (mask) {
>  	case IIO_CHAN_INFO_RAW:
>  	case IIO_CHAN_INFO_PROCESSED:

To avoid possible races this check should be done under the mlock.
> +		if (iio_buffer_enabled(indio_dev))
> +			return -EBUSY;
> +
>  		mutex_lock(&indio_dev->mlock);
>  		reinit_completion(&info->completion);
>  
> @@ -694,6 +719,68 @@ static int vf610_write_raw(struct iio_dev *indio_dev,
>  	return -EINVAL;
>  }
>  
> +static int vf610_adc_buffer_postenable(struct iio_dev *indio_dev)
> +{
> +	struct vf610_adc *info = iio_priv(indio_dev);
> +	unsigned int channel;
> +	int ret;
> +	int val;
> +
> +	ret = iio_triggered_buffer_postenable(indio_dev);
> +	if (ret)
> +		return ret;
> +
> +	val = readl(info->regs + VF610_REG_ADC_GC);
> +	val |= VF610_ADC_ADCON;
> +	writel(val, info->regs + VF610_REG_ADC_GC);
> +
> +	channel = find_first_bit(indio_dev->active_scan_mask,
> +						indio_dev->masklength);
> +
> +	val = VF610_ADC_ADCHC(channel);
> +	val |= VF610_ADC_AIEN;
> +
> +	writel(val, info->regs + VF610_REG_ADC_HC0);
> +
> +	return 0;
> +}
> +
> +static int vf610_adc_buffer_postdisable(struct iio_dev *indio_dev)
> +{
> +	struct vf610_adc *info = iio_priv(indio_dev);
> +	unsigned int hc_cfg = 0;
> +	int val;
> +
> +	val = readl(info->regs + VF610_REG_ADC_GC);
> +	val &= ~VF610_ADC_ADCON;
> +	writel(val, info->regs + VF610_REG_ADC_GC);
> +
> +	hc_cfg |= VF610_ADC_CONV_DISABLE;
> +	hc_cfg &= ~VF610_ADC_AIEN;
> +
> +	writel(hc_cfg, info->regs + VF610_REG_ADC_HC0);
> +
> +	return 0;
> +}
> +
> +static const struct iio_buffer_setup_ops iio_triggered_buffer_setup_ops = {
> +	.postenable = &vf610_adc_buffer_postenable,
> +	.predisable = &iio_triggered_buffer_predisable,
> +	.postdisable = &vf610_adc_buffer_postdisable,
> +	.validate_scan_mask = &iio_validate_scan_mask_onehot,
> +};
> +
> +static int vf610_adc_buffer_init(struct iio_dev *indio_dev)
> +{
> +	return iio_triggered_buffer_setup(indio_dev, &iio_pollfunc_store_time,
> +		NULL, &iio_triggered_buffer_setup_ops);
> +}
> +
> +static void vf610_adc_buffer_remove(struct iio_dev *indio_dev)
> +{
> +	iio_triggered_buffer_cleanup(indio_dev);
> +}
These to wrappers seem a little superflous. I'd have just put the code
inline, but it's obviously a matter of personal taste and I don't care
that much!

> +
>  static int vf610_adc_reg_access(struct iio_dev *indio_dev,
>  			unsigned reg, unsigned writeval,
>  			unsigned *readval)
> @@ -753,7 +840,7 @@ static int vf610_adc_probe(struct platform_device *pdev)
>  
>  	ret = devm_request_irq(info->dev, irq,
>  				vf610_adc_isr, 0,
> -				dev_name(&pdev->dev), info);
> +				dev_name(&pdev->dev), indio_dev);
>  	if (ret < 0) {
>  		dev_err(&pdev->dev, "failed requesting irq, irq = %d\n", irq);
>  		return ret;
> @@ -806,15 +893,22 @@ static int vf610_adc_probe(struct platform_device *pdev)
>  	vf610_adc_cfg_init(info);
>  	vf610_adc_hw_init(info);
>  
> +	ret = vf610_adc_buffer_init(indio_dev);
> +	if (ret < 0) {
> +		dev_err(&pdev->dev, "Couldn't initialise the buffer\n");
> +		goto error_iio_device_register;
> +	}
> +
>  	ret = iio_device_register(indio_dev);
>  	if (ret) {
>  		dev_err(&pdev->dev, "Couldn't register the device.\n");
> -		goto error_iio_device_register;
> +		goto error_adc_buffer_init;
>  	}
>  
>  	return 0;
>  
> -
> +error_adc_buffer_init:
> +	vf610_adc_buffer_remove(indio_dev);
>  error_iio_device_register:
>  	clk_disable_unprepare(info->clk);
>  error_adc_clk_enable:
> @@ -829,6 +923,7 @@ static int vf610_adc_remove(struct platform_device *pdev)
>  	struct vf610_adc *info = iio_priv(indio_dev);
>  
>  	iio_device_unregister(indio_dev);
> +	vf610_adc_buffer_remove(indio_dev);
>  	regulator_disable(info->vref);
>  	clk_disable_unprepare(info->clk);
>  
> 



From wei.liu2 at citrix.com  Sat Aug  8 07:55:34 2015
From: wei.liu2 at citrix.com (Wei Liu)
Date: Sat, 8 Aug 2015 15:55:34 +0100
Subject: [PATCH v3 18/20] net/xen-netback: Make it running on 64KB page
 granularity
In-Reply-To: <1438966019-19322-19-git-send-email-julien.grall@citrix.com>
References: <1438966019-19322-1-git-send-email-julien.grall@citrix.com>
 <1438966019-19322-19-git-send-email-julien.grall@citrix.com>
Message-ID: <20150808145534.GB14214@zion.uk.xensource.com>

On Fri, Aug 07, 2015 at 05:46:57PM +0100, Julien Grall wrote:
> The PV network protocol is using 4KB page granularity. The goal of this
> patch is to allow a Linux using 64KB page granularity working as a
> network backend on a non-modified Xen.
> 
> It's only necessary to adapt the ring size and break skb data in small
> chunk of 4KB. The rest of the code is relying on the grant table code.
> 
> Signed-off-by: Julien Grall <julien.grall at citrix.com>
> 
> ---
> Cc: Ian Campbell <ian.campbell at citrix.com>
> Cc: Wei Liu <wei.liu2 at citrix.com>
> Cc: netdev at vger.kernel.org
> 
[...]
> +#define XEN_NETIF_TX_RING_SIZE __CONST_RING_SIZE(xen_netif_tx, XEN_PAGE_SIZE)
> +#define XEN_NETIF_RX_RING_SIZE __CONST_RING_SIZE(xen_netif_rx, XEN_PAGE_SIZE)
>  
>  struct xenvif_rx_meta {
>  	int id;
> @@ -80,16 +81,18 @@ struct xenvif_rx_meta {
>  /* Discriminate from any valid pending_idx value. */
>  #define INVALID_PENDING_IDX 0xFFFF
>  
> -#define MAX_BUFFER_OFFSET PAGE_SIZE
> +#define MAX_BUFFER_OFFSET XEN_PAGE_SIZE
>  
>  #define MAX_PENDING_REQS XEN_NETIF_TX_RING_SIZE
>  
> +#define MAX_XEN_SKB_FRAGS (65536 / XEN_PAGE_SIZE + 1)
> +

It might be clearer if you add a comment saying the maximum number of
frags is derived from the page size of the grant page, which happens to
be XEN_PAGE_SIZE at the moment. 

In the future we need to figure out the page size of grant page in a
dynamic way. We shall cross the bridge when we get there.

>  /* It's possible for an skb to have a maximal number of frags
>   * but still be less than MAX_BUFFER_OFFSET in size. Thus the
> - * worst-case number of copy operations is MAX_SKB_FRAGS per
> + * worst-case number of copy operations is MAX_XEN_SKB_FRAGS per
>   * ring slot.
>   */
> -#define MAX_GRANT_COPY_OPS (MAX_SKB_FRAGS * XEN_NETIF_RX_RING_SIZE)
> +#define MAX_GRANT_COPY_OPS (MAX_XEN_SKB_FRAGS * XEN_NETIF_RX_RING_SIZE)
>  
>  #define NETBACK_INVALID_HANDLE -1
>  
> @@ -203,7 +206,7 @@ struct xenvif_queue { /* Per-queue data for xenvif */
>  /* Maximum number of Rx slots a to-guest packet may use, including the
>   * slot needed for GSO meta-data.
>   */
> -#define XEN_NETBK_RX_SLOTS_MAX (MAX_SKB_FRAGS + 1)
> +#define XEN_NETBK_RX_SLOTS_MAX ((MAX_XEN_SKB_FRAGS + 1))
>  
>  enum state_bit_shift {
>  	/* This bit marks that the vif is connected */
> diff --git a/drivers/net/xen-netback/netback.c b/drivers/net/xen-netback/netback.c
> index 66f1780..c32a9f2 100644
> --- a/drivers/net/xen-netback/netback.c
> +++ b/drivers/net/xen-netback/netback.c
> @@ -263,6 +263,80 @@ static struct xenvif_rx_meta *get_next_rx_buffer(struct xenvif_queue *queue,
>  	return meta;
>  }
>  
[...]
>   * Set up the grant operations for this fragment. If it's a flipping
>   * interface, we also set up the unmap request from here.
> @@ -272,83 +346,52 @@ static void xenvif_gop_frag_copy(struct xenvif_queue *queue, struct sk_buff *skb
>  				 struct page *page, unsigned long size,
>  				 unsigned long offset, int *head)
>  {
> -	struct gnttab_copy *copy_gop;
> -	struct xenvif_rx_meta *meta;
> +	struct gop_frag_copy info = {
> +		.queue = queue,
> +		.npo = npo,
> +		.head = *head,
> +		.gso_type = XEN_NETIF_GSO_TYPE_NONE,
> +	};
>  	unsigned long bytes;
> -	int gso_type = XEN_NETIF_GSO_TYPE_NONE;
>  
>  	if (skb_is_gso(skb)) {
>  		if (skb_shinfo(skb)->gso_type & SKB_GSO_TCPV4)
> -			gso_type = XEN_NETIF_GSO_TYPE_TCPV4;
> +			info.gso_type = XEN_NETIF_GSO_TYPE_TCPV4;
>  		else if (skb_shinfo(skb)->gso_type & SKB_GSO_TCPV6)
> -			gso_type = XEN_NETIF_GSO_TYPE_TCPV6;
> +			info.gso_type = XEN_NETIF_GSO_TYPE_TCPV6;
>  	}
>  
>  	/* Data must not cross a page boundary. */
>  	BUG_ON(size + offset > PAGE_SIZE<<compound_order(page));
>  
> -	meta = npo->meta + npo->meta_prod - 1;
> +	info.meta = npo->meta + npo->meta_prod - 1;
>  
>  	/* Skip unused frames from start of page */
>  	page += offset >> PAGE_SHIFT;
>  	offset &= ~PAGE_MASK;
>  
>  	while (size > 0) {
> -		struct xen_page_foreign *foreign;
> -
>  		BUG_ON(offset >= PAGE_SIZE);
> -		BUG_ON(npo->copy_off > MAX_BUFFER_OFFSET);
> -
> -		if (npo->copy_off == MAX_BUFFER_OFFSET)
> -			meta = get_next_rx_buffer(queue, npo);
>  
>  		bytes = PAGE_SIZE - offset;
>  		if (bytes > size)
>  			bytes = size;
>  
> -		if (npo->copy_off + bytes > MAX_BUFFER_OFFSET)
> -			bytes = MAX_BUFFER_OFFSET - npo->copy_off;
> -
> -		copy_gop = npo->copy + npo->copy_prod++;
> -		copy_gop->flags = GNTCOPY_dest_gref;
> -		copy_gop->len = bytes;
> -
> -		foreign = xen_page_foreign(page);
> -		if (foreign) {
> -			copy_gop->source.domid = foreign->domid;
> -			copy_gop->source.u.ref = foreign->gref;
> -			copy_gop->flags |= GNTCOPY_source_gref;
> -		} else {
> -			copy_gop->source.domid = DOMID_SELF;
> -			copy_gop->source.u.gmfn =
> -				virt_to_gfn(page_address(page));
> -		}
> -		copy_gop->source.offset = offset;
> -
> -		copy_gop->dest.domid = queue->vif->domid;
> -		copy_gop->dest.offset = npo->copy_off;
> -		copy_gop->dest.u.ref = npo->copy_gref;
> -
> -		npo->copy_off += bytes;
> -		meta->size += bytes;
> -
> -		offset += bytes;
> +		info.page = page;
> +		gnttab_foreach_grant_in_range(page, offset, bytes,
> +					      xenvif_gop_frag_copy_grant,
> +					      &info);

Looks like I need to at least wait until the API is settle before giving
my ack.

>  		size -= bytes;
> +		offset = 0;

This looks wrong. Should be offset += bytes.

>  
> -		/* Next frame */
> -		if (offset == PAGE_SIZE && size) {
> +		/* Next page */
> +		if (size) {
>  			BUG_ON(!PageCompound(page));
>  			page++;
> -			offset = 0;

And this should not be deleted, I think.

What is the reason for changing offset calculation? I think there is
still compound page when using 64K page.

>  		}
> -
> -		/* Leave a gap for the GSO descriptor. */
> -		if (*head && ((1 << gso_type) & queue->vif->gso_mask))
> -			queue->rx.req_cons++;
> -
> -		*head = 0; /* There must be something in this buffer now. */
> -
>  	}
> +
> +	*head = info.head;
>  }
>  

The reset looks OK.

Wei.


From Varun.Sethi at freescale.com  Sat Aug  8 08:06:12 2015
From: Varun.Sethi at freescale.com (Varun Sethi)
Date: Sat, 8 Aug 2015 15:06:12 +0000
Subject: [PATCH 2/3] Docs: dt: Add PCI MSI map bindings
In-Reply-To: <20150806173839.GC6437@leverpostej>
References: <1437670365-20704-1-git-send-email-mark.rutland@arm.com>
 <1437670365-20704-3-git-send-email-mark.rutland@arm.com>
 <BN1PR0301MB06277FDA6EB34E77B557CA75EA750@BN1PR0301MB0627.namprd03.prod.outlook.com>
 <20150806173839.GC6437@leverpostej>
Message-ID: <BN1PR0301MB0627EEEEBB0D30C391B421B0EA720@BN1PR0301MB0627.namprd03.prod.outlook.com>

Hi Mark,
Thanks for the response. Please find my comments inline.

Regards
Varun

> -----Original Message-----
> From: Mark Rutland [mailto:mark.rutland at arm.com]
> Sent: Thursday, August 06, 2015 11:09 PM
> To: Sethi Varun-B16395
> Cc: devicetree at vger.kernel.org; Lorenzo Pieralisi; arnd at arndb.de; Marc
> Zyngier; Will Deacon; linux-kernel at vger.kernel.org;
> ddaney at caviumnetworks.com; iommu at lists.linux-foundation.org;
> tirumalesh.chalamarla at caviumnetworks.com;
> laurent.pinchart at ideasonboard.com; thunder.leizhen at huawei.com;
> treding at nvidia.com; linux-arm-kernel at lists.infradead.org;
> majun258 at huawei.com; Yoder Stuart-B08248
> Subject: Re: [PATCH 2/3] Docs: dt: Add PCI MSI map bindings
> 
> On Wed, Aug 05, 2015 at 05:39:33PM +0100, Varun Sethi wrote:
> > Hi Mark
> > Thanks for the patch. Please find my comment inline.
> >
> > Regards
> > Varun
> >
> > > -----Original Message-----
> > > From: iommu-bounces at lists.linux-foundation.org [mailto:iommu-
> > > bounces at lists.linux-foundation.org] On Behalf Of Mark Rutland
> > > Sent: Thursday, July 23, 2015 10:23 PM
> > > To: devicetree at vger.kernel.org
> > > Cc: Mark Rutland; lorenzo.pieralisi at arm.com; arnd at arndb.de;
> > > marc.zyngier at arm.com; will.deacon at arm.com; linux-
> > > kernel at vger.kernel.org; ddaney at caviumnetworks.com;
> > > iommu at lists.linux- foundation.org;
> > > tirumalesh.chalamarla at caviumnetworks.com;
> > > laurent.pinchart at ideasonboard.com; thunder.leizhen at huawei.com;
> > > treding at nvidia.com; linux-arm-kernel at lists.infradead.org;
> > > majun258 at huawei.com
> > > Subject: [PATCH 2/3] Docs: dt: Add PCI MSI map bindings
> > >
> > > Currently msi-parent is used by a few bindings to describe the
> > > relationship between a PCI root complex and a single MSI controller,
> > > but this property does not have a generic binding document.
> > >
> > > Additionally, msi-parent is insufficient to describe more complex
> > > relationships between MSI controllers and devices under a root
> > > complex, where devices may be able to target multiple MSI
> > > controllers, or where MSI controllers use (non-probeable) sideband
> information to distinguish devices.
> > >
> > > This patch adds a generic binding for mapping PCI devices to MSI
> controllers.
> > > This document covers msi-parent, and a new msi-map property
> > > (specific to
> > > PCI*) which may be used to map devices (identified by their
> > > Requester ID) to sideband data for each MSI controller that they may
> target.
> > >
> > > Signed-off-by: Mark Rutland <mark.rutland at arm.com>
> > > ---
> > >  Documentation/devicetree/bindings/pci/pci-msi.txt | 220
> > > ++++++++++++++++++++++
> > >  1 file changed, 220 insertions(+)
> > >  create mode 100644
> > > Documentation/devicetree/bindings/pci/pci-msi.txt
> > >
> > > diff --git a/Documentation/devicetree/bindings/pci/pci-msi.txt
> > > b/Documentation/devicetree/bindings/pci/pci-msi.txt
> > > new file mode 100644
> > > index 0000000..9b3cc81
> > > --- /dev/null
> > > +++ b/Documentation/devicetree/bindings/pci/pci-msi.txt
> > > @@ -0,0 +1,220 @@
> > > +This document describes the generic device tree binding for
> > > +describing the relationship between PCI devices and MSI controllers.
> > > +
> > > +Each PCI device under a root complex is uniquely identified by its
> > > +Requester ID (AKA RID). A Requester ID is a triplet of a Bus
> > > +number, Device number, and Function number.
> > > +
> > > +For the purpose of this document, when treated as a numeric value,
> > > +a RID is formatted such that:
> > > +
> > > +* Bits [15:8] are the Bus number.
> > > +* Bits [7:3] are the Device number.
> > > +* Bits [2:0] are the Function number.
> > > +* Any other bits required for padding must be zero.
> > > +
> > > +MSIs may be distinguished in part through the use of sideband data
> > > +accompanying writes. In the case of PCI devices, this sideband data
> > > +may be derived from the Requester ID. A mechanism is required to
> > > +associate a device with both the MSI controllers it can address,
> > > +and the sideband data that will be associated with its writes to those
> controllers.
> > > +
> > > +For generic MSI bindings, see
> > > +Documentation/devicetree/bindings/interrupt-controller/msi.txt.
> > > +
> > > +
> > > +PCI root complex
> > > +================
> > > +
> > > +Optional properties
> > > +-------------------
> > > +
> > > +- msi-map: Maps a Requester ID to an MSI controller and associated
> > > +  msi-specifier data. The property is an arbitrary number of tuples
> > > +of
> > > +  (rid-base,msi-controller,msi-base,length), where:
> > [varun] How would we account for hot plug PCI devices and SR-IOV use
> cases, with the rid base and length?
> 
> For hotplug, you simply need the mapping from RID to msi-specifier to be
> defined in advance in the DT, for the set of RIDs that could possibly occur.
> 
> For SR-IOV, are you asking about ARI? I should update the description of the
> RID to describe that for ARI it has the format:
> 
> * Bits [15:8] are the Bus number
> * Bits [7:0] are the Identifier
> 
> Other than that, the handling would be identical to the non-ARI case.
> 
> What else am I missing?
> 
> > How do we take in to account for a PCIe bridge, while setting up the
> requestor ID base and length?
> 
> I'm not sure I follow the question. I don't see why this is any different to any
> other requester ID.
> 
> What do you see as being the problem for this case?


[varun]  Would the boot loader be responsible for the  PCI bus probe and setting up of the requestor id information in the device tree. Also, during bus probe the boot loader would understand the topology, and handle cases like non transparent host bridge and non standard devices (e.g. require special handling based on quirks). 

Also, the msi identifier would typically be the stream ID provided by the device.  So, this would be limited by the number of SMRs, right? Considering that the each device can have its specific IOMMU domain, which would also require mapping for MSI access, we may also be restricted by the number of context banks. So, we may be able to support a restricted number of msi identifiers.

We already have the PCI bus probe in Linux. If my assumption about the boot loader doing the probe is correct, why do we want to duplicate the work. Also, can we just provide a list of possible MSI identifiers to Linux for each PCIe controller. The IOMMU driver in the Linux kernel can interface with PCIe controller for setting up "requestor id"->"msi identifier" translation.




From jic23 at kernel.org  Sat Aug  8 08:15:46 2015
From: jic23 at kernel.org (Jonathan Cameron)
Date: Sat, 8 Aug 2015 16:15:46 +0100
Subject: [V4] [TWL4030 MADC] Fix ADC[3:6] readings
In-Reply-To: <1438712148-27004-2-git-send-email-adam.yh.lee@gmail.com>
References: <1438712148-27004-1-git-send-email-adam.yh.lee@gmail.com>
 <1438712148-27004-2-git-send-email-adam.yh.lee@gmail.com>
Message-ID: <55C61D22.7080604@kernel.org>

On 04/08/15 19:15, Adam YH Lee wrote:
> MADC[3:6] reads incorrect values without these two following changes:
> 
> - enable the 3v1 bias regulator for ADC[3:6]
> - configure ADC[3:6] lines as input, not as USB
> 
> Signed-off-by: Adam YH Lee <adam.yh.lee at gmail.com>
I'd ideally like an ack from the driver author or Sebastian as this isn't
a driver I'm particular familiar with.

Also, for future reference, patches should be titled something like
[Patch v4] iio: twl4030 madc: Fix ADC[3:6] readings.
(the patch bit is standard, the rest is iio convention)

Jonathan

> ---
>  drivers/iio/adc/twl4030-madc.c | 34 ++++++++++++++++++++++++++++++++++
>  1 file changed, 34 insertions(+)
> 
> diff --git a/drivers/iio/adc/twl4030-madc.c b/drivers/iio/adc/twl4030-madc.c
> index 94c5f05..8c58498 100644
> --- a/drivers/iio/adc/twl4030-madc.c
> +++ b/drivers/iio/adc/twl4030-madc.c
> @@ -45,13 +45,18 @@
>  #include <linux/types.h>
>  #include <linux/gfp.h>
>  #include <linux/err.h>
> +#include <linux/regulator/consumer.h>
>  
>  #include <linux/iio/iio.h>
>  
> +#define TWL4030_USB_SEL_MADC_MCPC	(1<<3)
> +#define TWL4030_USB_CARKIT_ANA_CTRL	0xBB
> +
>  /**
>   * struct twl4030_madc_data - a container for madc info
>   * @dev:		Pointer to device structure for madc
>   * @lock:		Mutex protecting this data structure
> + * @regulator:		Pointer to bias regulator for madc
>   * @requests:		Array of request struct corresponding to SW1, SW2 and RT
>   * @use_second_irq:	IRQ selection (main or co-processor)
>   * @imr:		Interrupt mask register of MADC
> @@ -60,6 +65,7 @@
>  struct twl4030_madc_data {
>  	struct device *dev;
>  	struct mutex lock;	/* mutex protecting this data structure */
> +	struct regulator *usb3v1;
>  	struct twl4030_madc_request requests[TWL4030_MADC_NUM_METHODS];
>  	bool use_second_irq;
>  	u8 imr;
> @@ -842,6 +848,32 @@ static int twl4030_madc_probe(struct platform_device *pdev)
>  	}
>  	twl4030_madc = madc;
>  
> +	/* Configure MADC[3:6] */
> +	ret = twl_i2c_read_u8(TWL_MODULE_USB, &regval,
> +			TWL4030_USB_CARKIT_ANA_CTRL);
> +	if (ret) {
> +		dev_err(&pdev->dev, "unable to read reg CARKIT_ANA_CTRL  0x%X\n",
> +				TWL4030_USB_CARKIT_ANA_CTRL);
> +		goto err_i2c;
> +	}
> +	regval |= TWL4030_USB_SEL_MADC_MCPC;
> +	ret = twl_i2c_write_u8(TWL_MODULE_USB, regval,
> +				 TWL4030_USB_CARKIT_ANA_CTRL);
> +	if (ret) {
> +		dev_err(&pdev->dev, "unable to write reg CARKIT_ANA_CTRL 0x%X\n",
> +				TWL4030_USB_CARKIT_ANA_CTRL);
> +		goto err_i2c;
> +	}
> +
> +	/* Enable 3v1 bias regulator for MADC[3:6] */
> +	madc->usb3v1 = devm_regulator_get(madc->dev, "vusb3v1");
> +	if (IS_ERR(madc->usb3v1))
> +		return -ENODEV;
> +
> +	ret = regulator_enable(madc->usb3v1);
> +	if (ret)
> +		dev_err(madc->dev, "could not enable 3v1 bias regulator\n");
> +
>  	ret = iio_device_register(iio_dev);
>  	if (ret) {
>  		dev_err(&pdev->dev, "could not register iio device\n");
> @@ -867,6 +899,8 @@ static int twl4030_madc_remove(struct platform_device *pdev)
>  	twl4030_madc_set_current_generator(madc, 0, 0);
>  	twl4030_madc_set_power(madc, 0);
>  
> +	regulator_disable(madc->usb3v1);
> +
>  	return 0;
>  }
>  
> 



From hdegoede at redhat.com  Sat Aug  8 08:35:36 2015
From: hdegoede at redhat.com (Hans de Goede)
Date: Sat, 8 Aug 2015 17:35:36 +0200
Subject: [linux-sunxi] [PATCH v2] ARM: dts: sunxi: Add regulators for
 LeMaker BananaPi
In-Reply-To: <1438532305-5884-1-git-send-email-public_timo.s@silentcreek.de>
References: <1438532305-5884-1-git-send-email-public_timo.s@silentcreek.de>
Message-ID: <55C621C8.7040302@redhat.com>

Hi,

On 02-08-15 18:18, Timo Sigurdsson wrote:
> sun7i-a20-bananapi.dts doesn't contain regulator nodes for the AXP209 PMU
> driver, so add them to allow for voltage-scaling with cpufreq-dt.
>
> Signed-off-by: Timo Sigurdsson <public_timo.s at silentcreek.de>

Thanks for doing this, looks good to me:

Acked-by: Hans de Goede <hdegoede at redhat.com>

Regards,

Hans


p.s.

I've replaced my own patch with this one in my sunxi-wip branch.


> ---
> Changes since v1 (RFC):
>
> - Dropped the changes to the cpufreq operating points and renamed the patch
> accordingly
> - Limited the CPU voltage range so it doesn't exceed the SOC specifications
> ---
>   arch/arm/boot/dts/sun7i-a20-bananapi.dts | 35 ++++++++++++++++++++++++++++----
>   1 file changed, 31 insertions(+), 4 deletions(-)
>
> diff --git a/arch/arm/boot/dts/sun7i-a20-bananapi.dts b/arch/arm/boot/dts/sun7i-a20-bananapi.dts
> index 9f7b472..74382f3 100644
> --- a/arch/arm/boot/dts/sun7i-a20-bananapi.dts
> +++ b/arch/arm/boot/dts/sun7i-a20-bananapi.dts
> @@ -92,6 +92,10 @@
>   	status = "okay";
>   };
>
> +&cpu0 {
> +	cpu-supply = <&reg_dcdc2>;
> +};
> +
>   &ehci0 {
>   	status = "okay";
>   };
> @@ -119,13 +123,9 @@
>   	status = "okay";
>
>   	axp209: pmic at 34 {
> -		compatible = "x-powers,axp209";
>   		reg = <0x34>;
>   		interrupt-parent = <&nmi_intc>;
>   		interrupts = <0 IRQ_TYPE_LEVEL_LOW>;
> -
> -		interrupt-controller;
> -		#interrupt-cells = <1>;
>   	};
>   };
>
> @@ -182,6 +182,33 @@
>   	};
>   };
>
> +#include "axp209.dtsi"
> +
> +&reg_dcdc2 {
> +	regulator-always-on;
> +	regulator-min-microvolt = <1000000>;
> +	regulator-max-microvolt = <1400000>;
> +	regulator-name = "vdd-cpu";
> +};
> +
> +&reg_dcdc3 {
> +	regulator-always-on;
> +	regulator-min-microvolt = <1000000>;
> +	regulator-max-microvolt = <1400000>;
> +	regulator-name = "vdd-int-dll";
> +};
> +
> +&reg_ldo1 {
> +	regulator-name = "vdd-rtc";
> +};
> +
> +&reg_ldo2 {
> +	regulator-always-on;
> +	regulator-min-microvolt = <3000000>;
> +	regulator-max-microvolt = <3000000>;
> +	regulator-name = "avcc";
> +};
> +
>   &reg_usb1_vbus {
>   	status = "okay";
>   };
>


From linux at arm.linux.org.uk  Sat Aug  8 08:35:41 2015
From: linux at arm.linux.org.uk (Russell King - ARM Linux)
Date: Sat, 8 Aug 2015 16:35:41 +0100
Subject: [PATCH v5 4/6] drm: bridge/dw_hdmi-i2s-audio: add audio driver
In-Reply-To: <1434731295-11060-1-git-send-email-ykk@rock-chips.com>
References: <1434730417-10629-1-git-send-email-ykk@rock-chips.com>
 <1434731295-11060-1-git-send-email-ykk@rock-chips.com>
Message-ID: <20150808153540.GL7557@n2100.arm.linux.org.uk>

On Sat, Jun 20, 2015 at 12:28:15AM +0800, Yakir Yang wrote:
> Add ALSA based HDMI I2S audio driver for dw_hdmi. Sound card
> driver could connect to this codec through the codec dai name
> "dw-hdmi-i2s-audio".

I'm applying this patch to my tree with some changes.  I haven't seen
anyone ack it, nor review it any further.  I'm hoping someone can ack
this patch with the following changes below - I'll be posting it as
part of my dw-hdmi devel updates later today.

> +	ret = request_irq(dw->data.irq, snd_dw_hdmi_irq, IRQF_SHARED,
> +			  "dw-dw-audio", dw);

			  DRIVER_NAME, dw);

> +MODULE_AUTHOR("Yakir Yang <ykk at rock-chips.com>");
> +MODULE_DESCRIPTION("DW dw Audio ASoC Interface");

Fixing this to be "Synopsis DesignWare HDMI I2S ASoC interface".

> +MODULE_LICENSE("GPL v2");
> +MODULE_ALIAS(PLATFORM_MODULE_PREFIX DRIVER_NAME);

Replacing PLATFORM_MODULE_PREFIX with the "platform:" string.

> +	if (hdmi_readb(hdmi, HDMI_CONFIG1_ID) & HDMI_CONFIG1_AHB) {
>  		pdevinfo.name = "dw-hdmi-ahb-audio";

Fixing this to be "dw-hdmi-i2s-audio".

-- 
FTTC broadband for 0.8mile line: currently at 10.5Mbps down 400kbps up
according to speedtest.net.


From gregkh at linuxfoundation.org  Sat Aug  8 08:37:10 2015
From: gregkh at linuxfoundation.org (Greg KH)
Date: Sat, 8 Aug 2015 08:37:10 -0700
Subject: [PATCH v4 2/2] usb: Add support for ACPI identification to
 xhci-platform
In-Reply-To: <CABxcv=nAxKqt06js1epALu8Y_61bZ+XeRwy_N=oQUTeRVCh6-w@mail.gmail.com>
References: <CADaLNDkeOP+gBw0qdSDha551w+w+q4ry9-EevDw5giyiQGdnqA@mail.gmail.com>
 <5e302acb5b03c9bf61ecfb9b5b37e8b3b520bed9.1438994178.git.dhdang@apm.com>
 <20150808012905.GA10407@kroah.com>
 <CABxcv=nAxKqt06js1epALu8Y_61bZ+XeRwy_N=oQUTeRVCh6-w@mail.gmail.com>
Message-ID: <20150808153710.GA11851@kroah.com>

On Sat, Aug 08, 2015 at 07:43:40AM +0200, Javier Martinez Canillas wrote:
> Hello Greg,
> 
> On Sat, Aug 8, 2015 at 3:29 AM, Greg KH <gregkh at linuxfoundation.org> wrote:
> > On Fri, Aug 07, 2015 at 06:03:36PM -0700, Duc Dang wrote:
> >> Provide the methods to let ACPI identify the need to use
> >> xhci-platform. Change the Kconfig files so the
> >> xhci-plat.o file is selectable during kernel config.
> >>
> >> This has been tested on an ARM64 machine with platform XHCI, an
> >> x86_64 machine with XHCI, and an x86_64 machine without XHCI.
> >> There were no regressions or error messages on the machines
> >> without platform XHCI.
> >>
> >> [dhdang: regenerate the patch over 4.2-rc5]
> >> Signed-off-by: Mark Langsdorf <mlangsdo at redhat.com>
> >> Signed-off-by: Duc Dang <dhdang at apm.com>
> >>
> >> ---
> >> Changes from v3:
> >>       Regenerate the patch over 4.2-rc5
> >>       No code change
> >>
> >> Changes from v2
> >>       Replaced tristate with a boolean as the driver doesn't
> >>               compile as a module
> >>       Correct --help-- to ---help---
> >>
> >> Changes from v1
> >>       Renamed from "add support for APM X-Gene to xhci-platform"
> >>       Removed changes to arm64/Kconfig
> >>       Made CONFIG_USB_XHCI_PLATFORM a user selectable config option
> >>
> >>  drivers/usb/host/Kconfig     |  7 ++++++-
> >>  drivers/usb/host/xhci-plat.c | 11 +++++++++++
> >>  2 files changed, 17 insertions(+), 1 deletion(-)
> >>
> >> diff --git a/drivers/usb/host/Kconfig b/drivers/usb/host/Kconfig
> >> index 8afc3c1..96231ee 100644
> >> --- a/drivers/usb/host/Kconfig
> >> +++ b/drivers/usb/host/Kconfig
> >> @@ -32,7 +32,12 @@ config USB_XHCI_PCI
> >>         default y
> >>
> >>  config USB_XHCI_PLATFORM
> >> -     tristate
> >> +     tristate "xHCI platform driver support"
> >> +     ---help---
> >> +       Say 'Y' to enable the support for the xHCI host controller
> >> +       as a platform device. Many ARM SoCs provide USB this way.
> >> +
> >> +       If unsure, say 'Y'.
> >>
> >>  config USB_XHCI_MVEBU
> >>       tristate "xHCI support for Marvell Armada 375/38x"
> >> diff --git a/drivers/usb/host/xhci-plat.c b/drivers/usb/host/xhci-plat.c
> >> index 5d03f8b..14b40d2 100644
> >> --- a/drivers/usb/host/xhci-plat.c
> >> +++ b/drivers/usb/host/xhci-plat.c
> >> @@ -19,6 +19,7 @@
> >>  #include <linux/usb/phy.h>
> >>  #include <linux/slab.h>
> >>  #include <linux/usb/xhci_pdriver.h>
> >> +#include <linux/acpi.h>
> >>
> >>  #include "xhci.h"
> >>  #include "xhci-mvebu.h"
> >> @@ -262,6 +263,15 @@ static const struct of_device_id usb_xhci_of_match[] = {
> >>  MODULE_DEVICE_TABLE(of, usb_xhci_of_match);
> >>  #endif
> >>
> >> +#ifdef CONFIG_ACPI
> >
> > You shoudn't need this #ifdef, right?
> >
> 
> Why it is not needed?

Why is it needed?

> The driver does .acpi_match_table = ACPI_PTR(usb_xhci_acpi_match) and
> ACPI_PTR() is NULL if CONFIG_ACPI is not enabled. Which can happen
> AFAIU since the driver also supports OF. So without the #ifdef guards,
> .acpi_match_table = NULL and the struct acpi_device_id
> usb_xhci_acpi_match[] will be built but not used.

Which is just fine, right?

> Or am I missing something?

Don't put #ifdef in .c files if at all possible is the kernel style
rules.

thanks,

greg k-h


From hdegoede at redhat.com  Sat Aug  8 08:38:54 2015
From: hdegoede at redhat.com (Hans de Goede)
Date: Sat,  8 Aug 2015 17:38:54 +0200
Subject: [PATCH] ARM: dts: sun4i: Enable i2c1 and i2c2 on the Chuwi V7-CW0825
 tablet
Message-ID: <1439048334-14704-1-git-send-email-hdegoede@redhat.com>

i2c1 has a freescale mma7660 accelerometer connected to it at addr 0x4c,
i2c2 has a ft5x touchscreen connected to it at addr 0x38.

Signed-off-by: Hans de Goede <hdegoede at redhat.com>
---
 arch/arm/boot/dts/sun4i-a10-chuwi-v7-cw0825.dts | 12 ++++++++++++
 1 file changed, 12 insertions(+)

diff --git a/arch/arm/boot/dts/sun4i-a10-chuwi-v7-cw0825.dts b/arch/arm/boot/dts/sun4i-a10-chuwi-v7-cw0825.dts
index 1430568..5366089 100644
--- a/arch/arm/boot/dts/sun4i-a10-chuwi-v7-cw0825.dts
+++ b/arch/arm/boot/dts/sun4i-a10-chuwi-v7-cw0825.dts
@@ -78,6 +78,18 @@
 	};
 };
 
+&i2c1 {
+	pinctrl-names = "default";
+	pinctrl-0 = <&i2c1_pins_a>;
+	status = "okay";
+};
+
+&i2c2 {
+	pinctrl-names = "default";
+	pinctrl-0 = <&i2c2_pins_a>;
+	status = "okay";
+};
+
 &lradc {
 	vref-supply = <&reg_vcc3v0>;
 	status = "okay";
-- 
2.4.3



From yamada.masahiro at socionext.com  Sat Aug  8 08:53:31 2015
From: yamada.masahiro at socionext.com (Masahiro Yamada)
Date: Sun,  9 Aug 2015 00:53:31 +0900
Subject: [PATCH v2] ARM: add boot image dependencies to not generate invalid
 images
Message-ID: <1439049211-4181-1-git-send-email-yamada.masahiro@socionext.com>

U-Boot is often used to boot the kernel on ARM boards, but uImage
is not built by "make all", so we are often inclined to do
"make all uImage" to generate DTBs, modules and uImage in a single
command, but we should notice a pitfall behind it.  In fact,
"make all uImage" could generate an invalid uImage if it is run with
the parallel option (-j).

You can reproduce this problem with the following procedure:

[1] First, build "all" and "uImage" separately.
    You will get a valid uImage

  $ git clean -f -x -d
  $ export CROSS_COMPILE=<your-tools-prefix>
  $ make -s -j8 ARCH=arm multi_v7_defconfig
  $ make -s -j8 ARCH=arm all
  $ make -j8 ARCH=arm UIMAGE_LOADADDR=0x80208000 uImage
    CHK     include/config/kernel.release
    CHK     include/generated/uapi/linux/version.h
    CHK     include/generated/utsrelease.h
  make[1]: `include/generated/mach-types.h' is up to date.
    CHK     include/generated/timeconst.h
    CHK     include/generated/bounds.h
    CHK     include/generated/asm-offsets.h
    CALL    scripts/checksyscalls.sh
    CHK     include/generated/compile.h
    Kernel: arch/arm/boot/Image is ready
    Kernel: arch/arm/boot/zImage is ready
    UIMAGE  arch/arm/boot/uImage
  Image Name:   Linux-4.2.0-rc5-00156-gdd2384a-d
  Created:      Sat Aug  8 23:21:35 2015
  Image Type:   ARM Linux Kernel Image (uncompressed)
  Data Size:    6138648 Bytes = 5994.77 kB = 5.85 MB
  Load Address: 80208000
  Entry Point:  80208000
    Image arch/arm/boot/uImage is ready
  $ ls -l arch/arm/boot/*Image
  -rwxrwxr-x 1 masahiro masahiro 13766656 Aug  8 23:20 arch/arm/boot/Image
  -rw-rw-r-- 1 masahiro masahiro  6138712 Aug  8 23:21 arch/arm/boot/uImage
  -rwxrwxr-x 1 masahiro masahiro  6138648 Aug  8 23:20 arch/arm/boot/zImage

[2] Update some source file(s)

  $ touch init/main.c

[3] Then, re-build "all" and "uImage" simultaneously.
    You will get an invalid uImage at random.

  $ make -j8 ARCH=arm UIMAGE_LOADADDR=0x80208000 all uImage
    CHK     include/config/kernel.release
    CHK     include/generated/uapi/linux/version.h
    CHK     include/generated/utsrelease.h
  make[1]: `include/generated/mach-types.h' is up to date.
    CHK     include/generated/timeconst.h
    CHK     include/generated/bounds.h
    CHK     include/generated/asm-offsets.h
    CALL    scripts/checksyscalls.sh
    CC      init/main.o
    CHK     include/generated/compile.h
    LD      init/built-in.o
    LINK    vmlinux
    LD      vmlinux.o
    MODPOST vmlinux.o
    GEN     .version
    CHK     include/generated/compile.h
    UPD     include/generated/compile.h
    CC      init/version.o
    LD      init/built-in.o
    KSYM    .tmp_kallsyms1.o
    KSYM    .tmp_kallsyms2.o
    LD      vmlinux
    SORTEX  vmlinux
    SYSMAP  System.map
    OBJCOPY arch/arm/boot/Image
    Building modules, stage 2.
    Kernel: arch/arm/boot/Image is ready
    GZIP    arch/arm/boot/compressed/piggy.gzip
    AS      arch/arm/boot/compressed/piggy.gzip.o
    Kernel: arch/arm/boot/Image is ready
    LD      arch/arm/boot/compressed/vmlinux
    GZIP    arch/arm/boot/compressed/piggy.gzip
    OBJCOPY arch/arm/boot/zImage
    Kernel: arch/arm/boot/zImage is ready
    UIMAGE  arch/arm/boot/uImage
  Image Name:   Linux-4.2.0-rc5-00156-gdd2384a-d
  Created:      Sat Aug  8 23:23:14 2015
  Image Type:   ARM Linux Kernel Image (uncompressed)
  Data Size:    26472 Bytes = 25.85 kB = 0.03 MB
  Load Address: 80208000
  Entry Point:  80208000
    Image arch/arm/boot/uImage is ready
    MODPOST 192 modules
    AS      arch/arm/boot/compressed/piggy.gzip.o
    LD      arch/arm/boot/compressed/vmlinux
    OBJCOPY arch/arm/boot/zImage
    Kernel: arch/arm/boot/zImage is ready
  $ ls -l arch/arm/boot/*Image
  -rwxrwxr-x 1 masahiro masahiro 13766656 Aug  8 23:23 arch/arm/boot/Image
  -rw-rw-r-- 1 masahiro masahiro    26536 Aug  8 23:23 arch/arm/boot/uImage
  -rwxrwxr-x 1 masahiro masahiro  6138648 Aug  8 23:23 arch/arm/boot/zImage

Please notice the uImage is extremely small when this issue is
encountered.  Besides, "Kernel: arch/arm/boot/zImage is ready" is
displayed twice, before and after the uImage log.

The root cause of this is the race condition between zImage and
uImage.  Actually, uImage depends on zImage, but the dependency
between the two is only described in arch/arm/boot/Makefile.
Because arch/arm/boot/Makefile is not included from the top-level
Makefile, it cannot know the dependency between zImage and uImage.

Consequently, when we run make with the parallel option, Kbuild
updates vmlinux first, and then two different threads descends into
the arch/arm/boot/Makefile almost at the same time, one for updating
zImage and the other for uImage.  While one thread is re-generating
zImage, the other also tries to update zImage before creating uImage
on top of that.  zImage is overwritten by the slower thread and then
uImage is created based on the half-written zImage.

This is the reason why "Kernel: arch/arm/boot/zImage is ready" is
displayed twice, and a broken uImage is created.

The same problem could happen on bootpImage.

This commit adds dependencies among Image, zImage, uImage, and
bootpImage to arch/arm/Makefile, which is included from the
top-level Makefile.

Signed-off-by: Masahiro Yamada <yamada.masahiro at socionext.com>
---

Changes in v2:
  - Add more detailed build log and explanation.

 arch/arm/Makefile | 3 +++
 1 file changed, 3 insertions(+)

diff --git a/arch/arm/Makefile b/arch/arm/Makefile
index 07ab3d2..7451b44 100644
--- a/arch/arm/Makefile
+++ b/arch/arm/Makefile
@@ -312,6 +312,9 @@ INSTALL_TARGETS	= zinstall uinstall install
 
 PHONY += bzImage $(BOOT_TARGETS) $(INSTALL_TARGETS)
 
+bootpImage uImage: zImage
+zImage: Image
+
 $(BOOT_TARGETS): vmlinux
 	$(Q)$(MAKE) $(build)=$(boot) MACHINE=$(MACHINE) $(boot)/$@
 
-- 
1.9.1



From hdegoede at redhat.com  Sat Aug  8 08:58:41 2015
From: hdegoede at redhat.com (Hans de Goede)
Date: Sat,  8 Aug 2015 17:58:41 +0200
Subject: [PATCH v4 2/2] mfd: axp20x: Add a cell for the usb power_supply part
 of the axp20x PMICs
In-Reply-To: <1439049521-30766-1-git-send-email-hdegoede@redhat.com>
References: <1439049521-30766-1-git-send-email-hdegoede@redhat.com>
Message-ID: <1439049521-30766-2-git-send-email-hdegoede@redhat.com>

Add a cell for the usb power_supply part of the axp20x PMICs.

Note that this cell is only for the usb power_supply part and not the
ac-power / battery-charger / rtc-backup-bat-charger bits.

Depending on the board each of those must be enabled / disabled separately
in devicetree as most boards do not use all 4. So in dt each one needs its
own child-node of the axp20x node. Another reason for using separate child
nodes for each is so that other devicetree nodes can have a power-supply
property with a phandle referencing a node representing a single
power-supply.

The decision to use a separate devicetree node for each is reflected on
the kernel side by each getting its own mfd-cell / platform_device and
platform-driver.

Note this commit also makes some whitespace changes to the intialization
of existing cells in axp20x_cells, these are pure whitespace changes,
functionally nothing changes.

Cc: Bruno Pr?mont <bonbons at linux-vserver.org>
Signed-off-by: Bruno Pr?mont <bonbons at linux-vserver.org>
Signed-off-by: Hans de Goede <hdegoede at redhat.com>
Acked-by: Maxime Ripard <maxime.ripard at free-electrons.com>
Acked-by: Lee Jones <lee.jones at linaro.org>
---
Changes in v2:
-Use DEFINE_RES_IRQ_NAMED
-Change indentation of axp20x_cells initializers to avoid line wrapping
Changes in v3:
-Improve commit message
-Add Bruno's S-o-b
---
 drivers/mfd/axp20x.c | 20 ++++++++++++++++----
 1 file changed, 16 insertions(+), 4 deletions(-)

diff --git a/drivers/mfd/axp20x.c b/drivers/mfd/axp20x.c
index d9f2f96..3f576b7 100644
--- a/drivers/mfd/axp20x.c
+++ b/drivers/mfd/axp20x.c
@@ -140,6 +140,13 @@ static struct resource axp20x_pek_resources[] = {
 	},
 };
 
+static struct resource axp20x_usb_power_supply_resources[] = {
+	DEFINE_RES_IRQ_NAMED(AXP20X_IRQ_VBUS_PLUGIN, "VBUS_PLUGIN"),
+	DEFINE_RES_IRQ_NAMED(AXP20X_IRQ_VBUS_REMOVAL, "VBUS_REMOVAL"),
+	DEFINE_RES_IRQ_NAMED(AXP20X_IRQ_VBUS_VALID, "VBUS_VALID"),
+	DEFINE_RES_IRQ_NAMED(AXP20X_IRQ_VBUS_NOT_VALID, "VBUS_NOT_VALID"),
+};
+
 static struct resource axp22x_pek_resources[] = {
 	{
 		.name   = "PEK_DBR",
@@ -432,11 +439,16 @@ static const struct regmap_irq_chip axp288_regmap_irq_chip = {
 
 static struct mfd_cell axp20x_cells[] = {
 	{
-		.name			= "axp20x-pek",
-		.num_resources		= ARRAY_SIZE(axp20x_pek_resources),
-		.resources		= axp20x_pek_resources,
+		.name		= "axp20x-pek",
+		.num_resources	= ARRAY_SIZE(axp20x_pek_resources),
+		.resources	= axp20x_pek_resources,
 	}, {
-		.name			= "axp20x-regulator",
+		.name		= "axp20x-regulator",
+	}, {
+		.name		= "axp20x-usb-power-supply",
+		.of_compatible	= "x-powers,axp202-usb-power-supply",
+		.num_resources	= ARRAY_SIZE(axp20x_usb_power_supply_resources),
+		.resources	= axp20x_usb_power_supply_resources,
 	},
 };
 
-- 
2.4.3



From hdegoede at redhat.com  Sat Aug  8 08:58:40 2015
From: hdegoede at redhat.com (Hans de Goede)
Date: Sat,  8 Aug 2015 17:58:40 +0200
Subject: [PATCH v4 1/2] mfd: axp20x: Add missing registers,
 and mark more registers volatile
Message-ID: <1439049521-30766-1-git-send-email-hdegoede@redhat.com>

From: Bruno Pr?mont <bonbons at linux-vserver.org>

Add an extra set of registers which is necessary tu support the PMICs
battery charger function, and mark registers which contain status bits,
gpio status, and adc readings as volatile.

Cc: Bruno Pr?mont <bonbons at linux-vserver.org>
Signed-off-by: Bruno Pr?mont <bonbons at linux-vserver.org>
Signed-off-by: Hans de Goede <hdegoede at redhat.com>
Acked-by: Lee Jones <lee.jones at linaro.org>
Acked-by: Maxime Ripard <maxime.ripard at free-electrons.com>
---
Changes in v2:
-Add a AXP20X_OCV_MAX define
Changes in v3:
-Add Bruno's S-o-b
Changes in v4:
-Consistently use AXP20X_OCV_MAX everywhere
---
 drivers/mfd/axp20x.c       | 8 +++++++-
 include/linux/mfd/axp20x.h | 6 ++++++
 2 files changed, 13 insertions(+), 1 deletion(-)

diff --git a/drivers/mfd/axp20x.c b/drivers/mfd/axp20x.c
index b369cfc..d9f2f96 100644
--- a/drivers/mfd/axp20x.c
+++ b/drivers/mfd/axp20x.c
@@ -61,10 +61,16 @@ static const struct regmap_access_table axp152_volatile_table = {
 static const struct regmap_range axp20x_writeable_ranges[] = {
 	regmap_reg_range(AXP20X_DATACACHE(0), AXP20X_IRQ5_STATE),
 	regmap_reg_range(AXP20X_DCDC_MODE, AXP20X_FG_RES),
+	regmap_reg_range(AXP20X_RDC_H, AXP20X_OCV(AXP20X_OCV_MAX)),
 };
 
 static const struct regmap_range axp20x_volatile_ranges[] = {
+	regmap_reg_range(AXP20X_PWR_INPUT_STATUS, AXP20X_USB_OTG_STATUS),
+	regmap_reg_range(AXP20X_CHRG_CTRL1, AXP20X_CHRG_CTRL2),
 	regmap_reg_range(AXP20X_IRQ1_EN, AXP20X_IRQ5_STATE),
+	regmap_reg_range(AXP20X_ACIN_V_ADC_H, AXP20X_IPSOUT_V_HIGH_L),
+	regmap_reg_range(AXP20X_GPIO20_SS, AXP20X_GPIO3_CTRL),
+	regmap_reg_range(AXP20X_FG_RES, AXP20X_RDC_L),
 };
 
 static const struct regmap_access_table axp20x_writeable_table = {
@@ -195,7 +201,7 @@ static const struct regmap_config axp20x_regmap_config = {
 	.val_bits	= 8,
 	.wr_table	= &axp20x_writeable_table,
 	.volatile_table	= &axp20x_volatile_table,
-	.max_register	= AXP20X_FG_RES,
+	.max_register	= AXP20X_OCV(AXP20X_OCV_MAX),
 	.cache_type	= REGCACHE_RBTREE,
 };
 
diff --git a/include/linux/mfd/axp20x.h b/include/linux/mfd/axp20x.h
index 52203d5..cc8ad1e 100644
--- a/include/linux/mfd/axp20x.h
+++ b/include/linux/mfd/axp20x.h
@@ -190,6 +190,12 @@ enum {
 #define AXP20X_CC_CTRL			0xb8
 #define AXP20X_FG_RES			0xb9
 
+/* OCV */
+#define AXP20X_RDC_H			0xba
+#define AXP20X_RDC_L			0xbb
+#define AXP20X_OCV(m)			(0xc0 + (m))
+#define AXP20X_OCV_MAX			0xf
+
 /* AXP22X specific registers */
 #define AXP22X_BATLOW_THRES1		0xe6
 
-- 
2.4.3



From linux at arm.linux.org.uk  Sat Aug  8 09:02:51 2015
From: linux at arm.linux.org.uk (Russell King - ARM Linux)
Date: Sat, 8 Aug 2015 17:02:51 +0100
Subject: [PATCH 00/12] dw-hdmi development
Message-ID: <20150808160251.GM7557@n2100.arm.linux.org.uk>

This sub-series is a mixture of development:

* Removing the incorrect pixel repetition configuration code
* Preventing pixel-doubled modes from being used
* Adding interlaced video support
* Implementing the sink_is_hdmi/sink_has_audio flags I suggested a few
  months ago
* Only enabling audio support if the sink indicates it has audio
* Avoiding double-enabling the HDMI interface
* Fixing the mis-leading name of "dw_hdmi_phy_enable_power"
* Adding connector mode forcing (important if your monitor bounces
  RXSENSE and HPD signals while in low-power mode.)
* Improving the HDMI enable/disabling on sink status

For review (and testing if people feel like it).  Acks/tested-bys etc
welcome.  It applies on top of my drm-dwhdmi-devel branch, which is
waiting for David Airlie to pull (see pull request on dri-devel, 15th
July.)

 drivers/gpu/drm/bridge/dw_hdmi.c | 275 ++++++++++++++++++++++++++++++---------
 drivers/gpu/ipu-v3/ipu-dc.c      |  18 ++-
 drivers/gpu/ipu-v3/ipu-di.c      | 129 +++++++++---------
 3 files changed, 291 insertions(+), 131 deletions(-)

-- 
FTTC broadband for 0.8mile line: currently at 10.5Mbps down 400kbps up
according to speedtest.net.


From rmk+kernel at arm.linux.org.uk  Sat Aug  8 09:03:24 2015
From: rmk+kernel at arm.linux.org.uk (Russell King)
Date: Sat, 08 Aug 2015 17:03:24 +0100
Subject: [PATCH 01/12] drm: bridge/dw_hdmi: remove pixel repetition setting
 for all VICs
In-Reply-To: <20150808160251.GM7557@n2100.arm.linux.org.uk>
References: <20150808160251.GM7557@n2100.arm.linux.org.uk>
Message-ID: <E1ZO6ai-0002qN-Nn@rmk-PC.arm.linux.org.uk>

dw_hdmi sets a pixel repetition factor of 1 for VICs 10-15, 25-30 and
35-38.  However, DRM uses their native resolutions in its timing
information.  For example, VIC 14 can be 1440x480 with no repetition,
or 720x480 with one pixel repetition.  As DRM uses 1440 pixels per line
for this video mode, we need no pixel repetition.

In any case, pixel repetition appears broken in dw_hdmi.

Signed-off-by: Russell King <rmk+kernel at arm.linux.org.uk>
---
 drivers/gpu/drm/bridge/dw_hdmi.c | 13 +------------
 1 file changed, 1 insertion(+), 12 deletions(-)

diff --git a/drivers/gpu/drm/bridge/dw_hdmi.c b/drivers/gpu/drm/bridge/dw_hdmi.c
index f070ee07b8c9..1c0ee3476138 100644
--- a/drivers/gpu/drm/bridge/dw_hdmi.c
+++ b/drivers/gpu/drm/bridge/dw_hdmi.c
@@ -1236,18 +1236,7 @@ static int dw_hdmi_setup(struct dw_hdmi *hdmi, struct drm_display_mode *mode)
 	else
 		hdmi->hdmi_data.colorimetry = HDMI_COLORIMETRY_ITU_709;
 
-	if ((hdmi->vic == 10) || (hdmi->vic == 11) ||
-	    (hdmi->vic == 12) || (hdmi->vic == 13) ||
-	    (hdmi->vic == 14) || (hdmi->vic == 15) ||
-	    (hdmi->vic == 25) || (hdmi->vic == 26) ||
-	    (hdmi->vic == 27) || (hdmi->vic == 28) ||
-	    (hdmi->vic == 29) || (hdmi->vic == 30) ||
-	    (hdmi->vic == 35) || (hdmi->vic == 36) ||
-	    (hdmi->vic == 37) || (hdmi->vic == 38))
-		hdmi->hdmi_data.video_mode.mpixelrepetitionoutput = 1;
-	else
-		hdmi->hdmi_data.video_mode.mpixelrepetitionoutput = 0;
-
+	hdmi->hdmi_data.video_mode.mpixelrepetitionoutput = 0;
 	hdmi->hdmi_data.video_mode.mpixelrepetitioninput = 0;
 
 	/* TODO: Get input format from IPU (via FB driver interface) */
-- 
2.1.0



From rmk+kernel at arm.linux.org.uk  Sat Aug  8 09:03:29 2015
From: rmk+kernel at arm.linux.org.uk (Russell King)
Date: Sat, 08 Aug 2015 17:03:29 +0100
Subject: [PATCH 02/12] drm: bridge/dw_hdmi: don't support any pixel doubled
 modes
In-Reply-To: <20150808160251.GM7557@n2100.arm.linux.org.uk>
References: <20150808160251.GM7557@n2100.arm.linux.org.uk>
Message-ID: <E1ZO6an-0002qT-Ue@rmk-PC.arm.linux.org.uk>

As mentioned in the previous commit, the dw-hdmi driver does not support
pixel doubled modes at present; it does not configure the PLL correctly
for these modes.  Therefore, filter out the double-clocked modes as we
presently are unable to support them.

Signed-off-by: Russell King <rmk+kernel at arm.linux.org.uk>
---
 drivers/gpu/drm/bridge/dw_hdmi.c | 4 ++++
 1 file changed, 4 insertions(+)

diff --git a/drivers/gpu/drm/bridge/dw_hdmi.c b/drivers/gpu/drm/bridge/dw_hdmi.c
index 1c0ee3476138..8edf4c31f55c 100644
--- a/drivers/gpu/drm/bridge/dw_hdmi.c
+++ b/drivers/gpu/drm/bridge/dw_hdmi.c
@@ -1448,6 +1448,10 @@ dw_hdmi_connector_mode_valid(struct drm_connector *connector,
 					   struct dw_hdmi, connector);
 	enum drm_mode_status mode_status = MODE_OK;
 
+	/* We don't support double-clocked modes */
+	if (mode->flags & DRM_MODE_FLAG_DBLCLK)
+		return MODE_BAD;
+
 	if (hdmi->plat_data->mode_valid)
 		mode_status = hdmi->plat_data->mode_valid(connector, mode);
 
-- 
2.1.0



From rmk+kernel at arm.linux.org.uk  Sat Aug  8 09:03:35 2015
From: rmk+kernel at arm.linux.org.uk (Russell King)
Date: Sat, 08 Aug 2015 17:03:35 +0100
Subject: [PATCH 03/12] gpu: imx: simplify sync polarity setting
In-Reply-To: <20150808160251.GM7557@n2100.arm.linux.org.uk>
References: <20150808160251.GM7557@n2100.arm.linux.org.uk>
Message-ID: <E1ZO6at-0002qb-2m@rmk-PC.arm.linux.org.uk>

Use a function to convert the sync pin to a bit mask for the DI_GENERAL
register, and move this out of the interlace/non-interlace path to the
common path.

Signed-off-by: Russell King <rmk+kernel at arm.linux.org.uk>
---
 drivers/gpu/ipu-v3/ipu-di.c | 50 +++++++++++++++++++++++++--------------------
 1 file changed, 28 insertions(+), 22 deletions(-)

diff --git a/drivers/gpu/ipu-v3/ipu-di.c b/drivers/gpu/ipu-v3/ipu-di.c
index 2970c6bb668c..a96991c5c15f 100644
--- a/drivers/gpu/ipu-v3/ipu-di.c
+++ b/drivers/gpu/ipu-v3/ipu-di.c
@@ -543,6 +543,29 @@ int ipu_di_adjust_videomode(struct ipu_di *di, struct videomode *mode)
 }
 EXPORT_SYMBOL_GPL(ipu_di_adjust_videomode);
 
+static u32 ipu_di_gen_polarity(int pin)
+{
+	switch (pin) {
+	case 1:
+		return DI_GEN_POLARITY_1;
+	case 2:
+		return DI_GEN_POLARITY_2;
+	case 3:
+		return DI_GEN_POLARITY_3;
+	case 4:
+		return DI_GEN_POLARITY_4;
+	case 5:
+		return DI_GEN_POLARITY_5;
+	case 6:
+		return DI_GEN_POLARITY_6;
+	case 7:
+		return DI_GEN_POLARITY_7;
+	case 8:
+		return DI_GEN_POLARITY_8;
+	}
+	return 0;
+}
+
 int ipu_di_init_sync_panel(struct ipu_di *di, struct ipu_di_signal_cfg *sig)
 {
 	u32 reg;
@@ -586,11 +609,6 @@ int ipu_di_init_sync_panel(struct ipu_di *di, struct ipu_di_signal_cfg *sig)
 		di_gen |= DI_GEN_POLARITY_8;
 
 		vsync_cnt = 7;
-
-		if (sig->mode.flags & DISPLAY_FLAGS_HSYNC_HIGH)
-			di_gen |= DI_GEN_POLARITY_3;
-		if (sig->mode.flags & DISPLAY_FLAGS_VSYNC_HIGH)
-			di_gen |= DI_GEN_POLARITY_2;
 	} else {
 		ipu_di_sync_config_noninterlaced(di, sig, div);
 
@@ -602,25 +620,13 @@ int ipu_di_init_sync_panel(struct ipu_di *di, struct ipu_di_signal_cfg *sig)
 			 */
 			if (!(sig->hsync_pin == 2 && sig->vsync_pin == 3))
 				vsync_cnt = 6;
-
-		if (sig->mode.flags & DISPLAY_FLAGS_HSYNC_HIGH) {
-			if (sig->hsync_pin == 2)
-				di_gen |= DI_GEN_POLARITY_2;
-			else if (sig->hsync_pin == 4)
-				di_gen |= DI_GEN_POLARITY_4;
-			else if (sig->hsync_pin == 7)
-				di_gen |= DI_GEN_POLARITY_7;
-		}
-		if (sig->mode.flags & DISPLAY_FLAGS_VSYNC_HIGH) {
-			if (sig->vsync_pin == 3)
-				di_gen |= DI_GEN_POLARITY_3;
-			else if (sig->vsync_pin == 6)
-				di_gen |= DI_GEN_POLARITY_6;
-			else if (sig->vsync_pin == 8)
-				di_gen |= DI_GEN_POLARITY_8;
-		}
 	}
 
+	if (sig->mode.flags & DISPLAY_FLAGS_HSYNC_HIGH)
+		di_gen |= ipu_di_gen_polarity(sig->hsync_pin);
+	if (sig->mode.flags & DISPLAY_FLAGS_VSYNC_HIGH)
+		di_gen |= ipu_di_gen_polarity(sig->vsync_pin);
+
 	if (sig->clk_pol)
 		di_gen |= DI_GEN_POLARITY_DISP_CLK;
 
-- 
2.1.0



From rmk+kernel at arm.linux.org.uk  Sat Aug  8 09:03:40 2015
From: rmk+kernel at arm.linux.org.uk (Russell King)
Date: Sat, 08 Aug 2015 17:03:40 +0100
Subject: [PATCH 04/12] gpu: imx: fix support for interlaced modes
In-Reply-To: <20150808160251.GM7557@n2100.arm.linux.org.uk>
References: <20150808160251.GM7557@n2100.arm.linux.org.uk>
Message-ID: <E1ZO6ay-0002qh-6E@rmk-PC.arm.linux.org.uk>

The support for interlaced video modes seems to be broken; we don't use
anything other than the vtotal/htotal from the timing information to
define the various sync counters.

Freescale patches for interlaced video support contain an alternative
sync counter setup, which we include here.  This setup produces the
hsync and vsync via the normal counter 2 and 3, but moves the display
enable signal from counter 5 to counter 6.  Therefore, we need to
change the display controller setup as well.

The corresponding Freescale patches for this change are:
  iMX6-HDMI-support-interlaced-display-mode.patch
  IPU-fine-tuning-the-interlace-display-timing-for-CEA.patch

This produces a working interlace format output from the IPU.

Signed-off-by: Russell King <rmk+kernel at arm.linux.org.uk>
---
 drivers/gpu/ipu-v3/ipu-dc.c | 18 ++++++++---
 drivers/gpu/ipu-v3/ipu-di.c | 79 +++++++++++++++++++++------------------------
 2 files changed, 51 insertions(+), 46 deletions(-)

diff --git a/drivers/gpu/ipu-v3/ipu-dc.c b/drivers/gpu/ipu-v3/ipu-dc.c
index 9ef2e1f54ca4..aa560855c1dc 100644
--- a/drivers/gpu/ipu-v3/ipu-dc.c
+++ b/drivers/gpu/ipu-v3/ipu-dc.c
@@ -183,12 +183,22 @@ int ipu_dc_init_sync(struct ipu_dc *dc, struct ipu_di *di, bool interlaced,
 	}
 
 	if (interlaced) {
-		dc_link_event(dc, DC_EVT_NL, 0, 3);
-		dc_link_event(dc, DC_EVT_EOL, 0, 2);
-		dc_link_event(dc, DC_EVT_NEW_DATA, 0, 1);
+		int word, addr;
+
+		if (dc->di) {
+			addr = 1;
+			word = 1;
+		} else {
+			addr = 0;
+			word = 0;
+		}
+
+		dc_link_event(dc, DC_EVT_NL, addr, 3);
+		dc_link_event(dc, DC_EVT_EOL, addr, 2);
+		dc_link_event(dc, DC_EVT_NEW_DATA, addr, 1);
 
 		/* Init template microcode */
-		dc_write_tmpl(dc, 0, WROD(0), 0, map, SYNC_WAVE, 0, 8, 1);
+		dc_write_tmpl(dc, word, WROD(0), 0, map, SYNC_WAVE, 0, 6, 1);
 	} else {
 		if (dc->di) {
 			dc_link_event(dc, DC_EVT_NL, 2, 3);
diff --git a/drivers/gpu/ipu-v3/ipu-di.c b/drivers/gpu/ipu-v3/ipu-di.c
index a96991c5c15f..359268e3a166 100644
--- a/drivers/gpu/ipu-v3/ipu-di.c
+++ b/drivers/gpu/ipu-v3/ipu-di.c
@@ -71,6 +71,10 @@ enum di_sync_wave {
 	DI_SYNC_HSYNC = 3,
 	DI_SYNC_VSYNC = 4,
 	DI_SYNC_DE = 6,
+
+	DI_SYNC_CNT1 = 2,	/* counter >= 2 only */
+	DI_SYNC_CNT4 = 5,	/* counter >= 5 only */
+	DI_SYNC_CNT5 = 6,	/* counter >= 6 only */
 };
 
 #define SYNC_WAVE 0
@@ -211,66 +215,59 @@ static void ipu_di_sync_config_interlaced(struct ipu_di *di,
 		sig->mode.hback_porch + sig->mode.hfront_porch;
 	u32 v_total = sig->mode.vactive + sig->mode.vsync_len +
 		sig->mode.vback_porch + sig->mode.vfront_porch;
-	u32 reg;
 	struct di_sync_config cfg[] = {
 		{
-			.run_count = h_total / 2 - 1,
-			.run_src = DI_SYNC_CLK,
+			/* 1: internal VSYNC for each frame */
+			.run_count = v_total * 2 - 1,
+			.run_src = 3,			/* == counter 7 */
 		}, {
-			.run_count = h_total - 11,
+			/* PIN2: HSYNC waveform */
+			.run_count = h_total - 1,
 			.run_src = DI_SYNC_CLK,
-			.cnt_down = 4,
+			.cnt_polarity_gen_en = 1,
+			.cnt_polarity_trigger_src = DI_SYNC_CLK,
+			.cnt_down = sig->mode.hsync_len * 2,
 		}, {
-			.run_count = v_total * 2 - 1,
-			.run_src = DI_SYNC_INT_HSYNC,
-			.offset_count = 1,
-			.offset_src = DI_SYNC_INT_HSYNC,
-			.cnt_down = 4,
+			/* PIN3: VSYNC waveform */
+			.run_count = v_total - 1,
+			.run_src = 4,			/* == counter 7 */
+			.cnt_polarity_gen_en = 1,
+			.cnt_polarity_trigger_src = 4,	/* == counter 7 */
+			.cnt_down = sig->mode.vsync_len * 2,
+			.cnt_clr_src = DI_SYNC_CNT1,
 		}, {
-			.run_count = v_total / 2 - 1,
+			/* 4: Field */
+			.run_count = v_total / 2,
 			.run_src = DI_SYNC_HSYNC,
-			.offset_count = sig->mode.vback_porch,
-			.offset_src = DI_SYNC_HSYNC,
+			.offset_count = h_total / 2,
+			.offset_src = DI_SYNC_CLK,
 			.repeat_count = 2,
-			.cnt_clr_src = DI_SYNC_VSYNC,
+			.cnt_clr_src = DI_SYNC_CNT1,
 		}, {
+			/* 5: Active lines */
 			.run_src = DI_SYNC_HSYNC,
-			.repeat_count = sig->mode.vactive / 2,
-			.cnt_clr_src = 4,
-		}, {
-			.run_count = v_total - 1,
-			.run_src = DI_SYNC_HSYNC,
-		}, {
-			.run_count = v_total / 2 - 1,
-			.run_src = DI_SYNC_HSYNC,
-			.offset_count = 9,
+			.offset_count = (sig->mode.vsync_len +
+					 sig->mode.vback_porch) / 2,
 			.offset_src = DI_SYNC_HSYNC,
-			.repeat_count = 2,
-			.cnt_clr_src = DI_SYNC_VSYNC,
+			.repeat_count = sig->mode.vactive / 2,
+			.cnt_clr_src = DI_SYNC_CNT4,
 		}, {
+			/* 6: Active pixel, referenced by DC */
 			.run_src = DI_SYNC_CLK,
-			.offset_count = sig->mode.hback_porch,
+			.offset_count = sig->mode.hsync_len +
+					sig->mode.hback_porch,
 			.offset_src = DI_SYNC_CLK,
 			.repeat_count = sig->mode.hactive,
-			.cnt_clr_src = 5,
+			.cnt_clr_src = DI_SYNC_CNT5,
 		}, {
-			.run_count = v_total - 1,
-			.run_src = DI_SYNC_INT_HSYNC,
-			.offset_count = v_total / 2,
-			.offset_src = DI_SYNC_INT_HSYNC,
-			.cnt_clr_src = DI_SYNC_HSYNC,
-			.cnt_down = 4,
+			/* 7: Half line HSYNC */
+			.run_count = h_total / 2 - 1,
+			.run_src = DI_SYNC_CLK,
 		}
 	};
 
 	ipu_di_sync_config(di, cfg, 0, ARRAY_SIZE(cfg));
 
-	/* set gentime select and tag sel */
-	reg = ipu_di_read(di, DI_SW_GEN1(9));
-	reg &= 0x1FFFFFFF;
-	reg |= (3 - 1) << 29 | 0x00008000;
-	ipu_di_write(di, reg, DI_SW_GEN1(9));
-
 	ipu_di_write(di, v_total / 2 - 1, DI_SCR_CONF);
 }
 
@@ -605,10 +602,8 @@ int ipu_di_init_sync_panel(struct ipu_di *di, struct ipu_di_signal_cfg *sig)
 
 		/* set y_sel = 1 */
 		di_gen |= 0x10000000;
-		di_gen |= DI_GEN_POLARITY_5;
-		di_gen |= DI_GEN_POLARITY_8;
 
-		vsync_cnt = 7;
+		vsync_cnt = 3;
 	} else {
 		ipu_di_sync_config_noninterlaced(di, sig, div);
 
-- 
2.1.0



From rmk+kernel at arm.linux.org.uk  Sat Aug  8 09:03:45 2015
From: rmk+kernel at arm.linux.org.uk (Russell King)
Date: Sat, 08 Aug 2015 17:03:45 +0100
Subject: [PATCH 05/12] drm: bridge/dw_hdmi: add support for interlaced video
 modes
In-Reply-To: <20150808160251.GM7557@n2100.arm.linux.org.uk>
References: <20150808160251.GM7557@n2100.arm.linux.org.uk>
Message-ID: <E1ZO6b3-0002qv-BK@rmk-PC.arm.linux.org.uk>

Add support for interlaced video modes to the dw_hdmi bridge.  This
mainly involves halving the vertical parameters to be programmed into
the bridge registers, and setting the interlace_allowed connector flag.

This brings working 1080i support.  However, 480i and 576i fail to
work due to the lack of proper pixel repetition support, which is not
trivial to add due to the tabular PLL parameterisation.  Hence, we
filter out these modes in our mode_valid() method.

Signed-off-by: Russell King <rmk+kernel at arm.linux.org.uk>
---
 drivers/gpu/drm/bridge/dw_hdmi.c | 26 +++++++++++++++++++++-----
 1 file changed, 21 insertions(+), 5 deletions(-)

diff --git a/drivers/gpu/drm/bridge/dw_hdmi.c b/drivers/gpu/drm/bridge/dw_hdmi.c
index 8edf4c31f55c..2e211b8331ed 100644
--- a/drivers/gpu/drm/bridge/dw_hdmi.c
+++ b/drivers/gpu/drm/bridge/dw_hdmi.c
@@ -1060,6 +1060,7 @@ static void hdmi_av_composer(struct dw_hdmi *hdmi,
 	u8 inv_val;
 	struct hdmi_vmode *vmode = &hdmi->hdmi_data.video_mode;
 	int hblank, vblank, h_de_hs, v_de_vs, hsync_len, vsync_len;
+	unsigned int vdisplay;
 
 	vmode->mpixelclock = mode->clock * 1000;
 
@@ -1099,13 +1100,29 @@ static void hdmi_av_composer(struct dw_hdmi *hdmi,
 
 	hdmi_writeb(hdmi, inv_val, HDMI_FC_INVIDCONF);
 
+	vdisplay = mode->vdisplay;
+	vblank = mode->vtotal - mode->vdisplay;
+	v_de_vs = mode->vsync_start - mode->vdisplay;
+	vsync_len = mode->vsync_end - mode->vsync_start;
+
+	/*
+	 * When we're setting an interlaced mode, we need
+	 * to adjust the vertical timing to suit.
+	 */
+	if (mode->flags & DRM_MODE_FLAG_INTERLACE) {
+		vdisplay /= 2;
+		vblank /= 2;
+		v_de_vs /= 2;
+		vsync_len /= 2;
+	}
+
 	/* Set up horizontal active pixel width */
 	hdmi_writeb(hdmi, mode->hdisplay >> 8, HDMI_FC_INHACTV1);
 	hdmi_writeb(hdmi, mode->hdisplay, HDMI_FC_INHACTV0);
 
 	/* Set up vertical active lines */
-	hdmi_writeb(hdmi, mode->vdisplay >> 8, HDMI_FC_INVACTV1);
-	hdmi_writeb(hdmi, mode->vdisplay, HDMI_FC_INVACTV0);
+	hdmi_writeb(hdmi, vdisplay >> 8, HDMI_FC_INVACTV1);
+	hdmi_writeb(hdmi, vdisplay, HDMI_FC_INVACTV0);
 
 	/* Set up horizontal blanking pixel region width */
 	hblank = mode->htotal - mode->hdisplay;
@@ -1113,7 +1130,6 @@ static void hdmi_av_composer(struct dw_hdmi *hdmi,
 	hdmi_writeb(hdmi, hblank, HDMI_FC_INHBLANK0);
 
 	/* Set up vertical blanking pixel region width */
-	vblank = mode->vtotal - mode->vdisplay;
 	hdmi_writeb(hdmi, vblank, HDMI_FC_INVBLANK);
 
 	/* Set up HSYNC active edge delay width (in pixel clks) */
@@ -1122,7 +1138,6 @@ static void hdmi_av_composer(struct dw_hdmi *hdmi,
 	hdmi_writeb(hdmi, h_de_hs, HDMI_FC_HSYNCINDELAY0);
 
 	/* Set up VSYNC active edge delay (in lines) */
-	v_de_vs = mode->vsync_start - mode->vdisplay;
 	hdmi_writeb(hdmi, v_de_vs, HDMI_FC_VSYNCINDELAY);
 
 	/* Set up HSYNC active pulse width (in pixel clks) */
@@ -1131,7 +1146,6 @@ static void hdmi_av_composer(struct dw_hdmi *hdmi,
 	hdmi_writeb(hdmi, hsync_len, HDMI_FC_HSYNCINWIDTH0);
 
 	/* Set up VSYNC active edge delay (in lines) */
-	vsync_len = mode->vsync_end - mode->vsync_start;
 	hdmi_writeb(hdmi, vsync_len, HDMI_FC_VSYNCINWIDTH);
 }
 
@@ -1593,6 +1607,8 @@ int dw_hdmi_bind(struct device *dev, struct device *master,
 	if (!hdmi)
 		return -ENOMEM;
 
+	hdmi->connector.interlace_allowed = 1;
+
 	hdmi->plat_data = plat_data;
 	hdmi->dev = dev;
 	hdmi->dev_type = plat_data->dev_type;
-- 
2.1.0



From rmk+kernel at arm.linux.org.uk  Sat Aug  8 09:03:50 2015
From: rmk+kernel at arm.linux.org.uk (Russell King)
Date: Sat, 08 Aug 2015 17:03:50 +0100
Subject: [PATCH 06/12] drm: bridge/dw_hdmi: clean up HDMI vs DVI mode handling
In-Reply-To: <20150808160251.GM7557@n2100.arm.linux.org.uk>
References: <20150808160251.GM7557@n2100.arm.linux.org.uk>
Message-ID: <E1ZO6b8-0002r1-Gr@rmk-PC.arm.linux.org.uk>

The FSL kernel detects the HDMI vendor id, and uses this to set
hdmi->edid_cfg.hdmi_cap, which is then used to set mdvi appropriately,
rather than detecting whether we are outputting a CEA mode.  Update
the dw_hdmi code to use this logic, but lets eliminate the mdvi
variable, prefering the more verbose "hdmi->sink_is_hdmi" instead.

Use the generic drm_detect_hdmi_monitor() to detect a HDMI sink.

Signed-off-by: Russell King <rmk+kernel at arm.linux.org.uk>
---
 drivers/gpu/drm/bridge/dw_hdmi.c | 26 ++++++++++++--------------
 1 file changed, 12 insertions(+), 14 deletions(-)

diff --git a/drivers/gpu/drm/bridge/dw_hdmi.c b/drivers/gpu/drm/bridge/dw_hdmi.c
index 2e211b8331ed..7f764716f3c4 100644
--- a/drivers/gpu/drm/bridge/dw_hdmi.c
+++ b/drivers/gpu/drm/bridge/dw_hdmi.c
@@ -82,7 +82,6 @@ static const u16 csc_coeff_rgb_in_eitu709[3][4] = {
 };
 
 struct hdmi_vmode {
-	bool mdvi;
 	bool mdataenablepolarity;
 
 	unsigned int mpixelclock;
@@ -123,6 +122,7 @@ struct dw_hdmi {
 
 	struct i2c_adapter *ddc;
 	void __iomem *regs;
+	bool sink_is_hdmi;
 
 	spinlock_t audio_lock;
 	struct mutex audio_mutex;
@@ -913,11 +913,10 @@ static int hdmi_phy_configure(struct dw_hdmi *hdmi, unsigned char prep,
 static int dw_hdmi_phy_init(struct dw_hdmi *hdmi)
 {
 	int i, ret;
-	bool cscon = false;
+	bool cscon;
 
 	/*check csc whether needed activated in HDMI mode */
-	cscon = (is_color_space_conversion(hdmi) &&
-			!hdmi->hdmi_data.video_mode.mdvi);
+	cscon = hdmi->sink_is_hdmi && is_color_space_conversion(hdmi);
 
 	/* HDMI Phy spec says to do the phy initialization sequence twice */
 	for (i = 0; i < 2; i++) {
@@ -1094,9 +1093,9 @@ static void hdmi_av_composer(struct dw_hdmi *hdmi,
 		HDMI_FC_INVIDCONF_IN_I_P_INTERLACED :
 		HDMI_FC_INVIDCONF_IN_I_P_PROGRESSIVE;
 
-	inv_val |= (vmode->mdvi ?
-		HDMI_FC_INVIDCONF_DVI_MODEZ_DVI_MODE :
-		HDMI_FC_INVIDCONF_DVI_MODEZ_HDMI_MODE);
+	inv_val |= hdmi->sink_is_hdmi ?
+		HDMI_FC_INVIDCONF_DVI_MODEZ_HDMI_MODE :
+		HDMI_FC_INVIDCONF_DVI_MODEZ_DVI_MODE;
 
 	hdmi_writeb(hdmi, inv_val, HDMI_FC_INVIDCONF);
 
@@ -1236,10 +1235,8 @@ static int dw_hdmi_setup(struct dw_hdmi *hdmi, struct drm_display_mode *mode)
 
 	if (!hdmi->vic) {
 		dev_dbg(hdmi->dev, "Non-CEA mode used in HDMI\n");
-		hdmi->hdmi_data.video_mode.mdvi = true;
 	} else {
 		dev_dbg(hdmi->dev, "CEA mode used vic=%d\n", hdmi->vic);
-		hdmi->hdmi_data.video_mode.mdvi = false;
 	}
 
 	if ((hdmi->vic == 6) || (hdmi->vic == 7) ||
@@ -1275,10 +1272,8 @@ static int dw_hdmi_setup(struct dw_hdmi *hdmi, struct drm_display_mode *mode)
 	dw_hdmi_enable_video_path(hdmi);
 
 	/* not for DVI mode */
-	if (hdmi->hdmi_data.video_mode.mdvi) {
-		dev_dbg(hdmi->dev, "%s DVI mode\n", __func__);
-	} else {
-		dev_dbg(hdmi->dev, "%s CEA mode\n", __func__);
+	if (hdmi->sink_is_hdmi) {
+		dev_dbg(hdmi->dev, "%s HDMI mode\n", __func__);
 
 		/* HDMI Initialization Step E - Configure audio */
 		hdmi_clk_regenerator_update_pixel_clock(hdmi);
@@ -1286,6 +1281,8 @@ static int dw_hdmi_setup(struct dw_hdmi *hdmi, struct drm_display_mode *mode)
 
 		/* HDMI Initialization Step F - Configure AVI InfoFrame */
 		hdmi_config_AVI(hdmi, mode);
+	} else {
+		dev_dbg(hdmi->dev, "%s DVI mode\n", __func__);
 	}
 
 	hdmi_video_packetize(hdmi);
@@ -1294,7 +1291,7 @@ static int dw_hdmi_setup(struct dw_hdmi *hdmi, struct drm_display_mode *mode)
 	hdmi_tx_hdcp_config(hdmi);
 
 	dw_hdmi_clear_overflow(hdmi);
-	if (hdmi->cable_plugin && !hdmi->hdmi_data.video_mode.mdvi)
+	if (hdmi->cable_plugin && hdmi->sink_is_hdmi)
 		hdmi_enable_overflow_interrupts(hdmi);
 
 	return 0;
@@ -1444,6 +1441,7 @@ static int dw_hdmi_connector_get_modes(struct drm_connector *connector)
 		dev_dbg(hdmi->dev, "got edid: width[%d] x height[%d]\n",
 			edid->width_cm, edid->height_cm);
 
+		hdmi->sink_is_hdmi = drm_detect_hdmi_monitor(edid);
 		drm_mode_connector_update_edid_property(connector, edid);
 		ret = drm_add_edid_modes(connector, edid);
 		kfree(edid);
-- 
2.1.0



From rmk+kernel at arm.linux.org.uk  Sat Aug  8 09:04:05 2015
From: rmk+kernel at arm.linux.org.uk (Russell King)
Date: Sat, 08 Aug 2015 17:04:05 +0100
Subject: [PATCH 09/12] drm: bridge/dw_hdmi: rename dw_hdmi_phy_enable_power()
In-Reply-To: <20150808160251.GM7557@n2100.arm.linux.org.uk>
References: <20150808160251.GM7557@n2100.arm.linux.org.uk>
Message-ID: <E1ZO6bN-0002uc-UE@rmk-PC.arm.linux.org.uk>

dw_hdmi_phy_enable_power() is not about enabling and disabling power.
It is about allowing or preventing power-down mode being entered - the
register is documented as "Power-down enable (active low 0b)."

This can be seen as the bit has no effect when the HDMI phy is
operational on iMX6 hardware.

Rename the function to dw_hdmi_phy_enable_powerdown() to reflect the
documentation, make it take a bool for the 'enable' argument, and invert
the value to be written.

Signed-off-by: Russell King <rmk+kernel at arm.linux.org.uk>
---
 drivers/gpu/drm/bridge/dw_hdmi.c | 10 +++++-----
 1 file changed, 5 insertions(+), 5 deletions(-)

diff --git a/drivers/gpu/drm/bridge/dw_hdmi.c b/drivers/gpu/drm/bridge/dw_hdmi.c
index fbac8386552b..7b8a4e942a71 100644
--- a/drivers/gpu/drm/bridge/dw_hdmi.c
+++ b/drivers/gpu/drm/bridge/dw_hdmi.c
@@ -737,9 +737,9 @@ static int hdmi_phy_i2c_write(struct dw_hdmi *hdmi, unsigned short data,
 	return 0;
 }
 
-static void dw_hdmi_phy_enable_power(struct dw_hdmi *hdmi, u8 enable)
+static void dw_hdmi_phy_enable_powerdown(struct dw_hdmi *hdmi, bool enable)
 {
-	hdmi_mask_writeb(hdmi, enable, HDMI_PHY_CONF0,
+	hdmi_mask_writeb(hdmi, !enable, HDMI_PHY_CONF0,
 			 HDMI_PHY_CONF0_PDZ_OFFSET,
 			 HDMI_PHY_CONF0_PDZ_MASK);
 }
@@ -879,7 +879,7 @@ static int hdmi_phy_configure(struct dw_hdmi *hdmi, unsigned char prep,
 	/* REMOVE CLK TERM */
 	hdmi_phy_i2c_write(hdmi, 0x8000, 0x05);  /* CKCALCTRL */
 
-	dw_hdmi_phy_enable_power(hdmi, 1);
+	dw_hdmi_phy_enable_powerdown(hdmi, false);
 
 	/* toggle TMDS enable */
 	dw_hdmi_phy_enable_tmds(hdmi, 0);
@@ -924,7 +924,7 @@ static int dw_hdmi_phy_init(struct dw_hdmi *hdmi)
 		dw_hdmi_phy_sel_data_en_pol(hdmi, 1);
 		dw_hdmi_phy_sel_interface_control(hdmi, 0);
 		dw_hdmi_phy_enable_tmds(hdmi, 0);
-		dw_hdmi_phy_enable_power(hdmi, 0);
+		dw_hdmi_phy_enable_powerdown(hdmi, true);
 
 		/* Enable CSC */
 		ret = hdmi_phy_configure(hdmi, 0, 8, cscon);
@@ -1155,7 +1155,7 @@ static void dw_hdmi_phy_disable(struct dw_hdmi *hdmi)
 		return;
 
 	dw_hdmi_phy_enable_tmds(hdmi, 0);
-	dw_hdmi_phy_enable_power(hdmi, 0);
+	dw_hdmi_phy_enable_powerdown(hdmi, true);
 
 	hdmi->phy_enabled = false;
 }
-- 
2.1.0



From rmk+kernel at arm.linux.org.uk  Sat Aug  8 09:04:16 2015
From: rmk+kernel at arm.linux.org.uk (Russell King)
Date: Sat, 08 Aug 2015 17:04:16 +0100
Subject: [PATCH 11/12] drm: bridge/dw_hdmi: add connector mode forcing
In-Reply-To: <20150808160251.GM7557@n2100.arm.linux.org.uk>
References: <20150808160251.GM7557@n2100.arm.linux.org.uk>
Message-ID: <E1ZO6bY-0002vr-9R@rmk-PC.arm.linux.org.uk>

When connected to HDMI sources, some DVI monitors de-assert their HPD
signal and TDMS loads for one seconds every four seconds when there is
no signal present on the connection.

Unfortunately, this behaviour is indistinguishable from a proper HDMI
setup with an AV receiver in the path to the display: the HDMI spec
requires us to detect HPD deassertions as short as 100ms, which indicate
that the EDID has changed.

Since it is possible to connect a DVI monitor to an AV receiver and then
to a HDMI source, merely working around this by detecting the lack of
HDMI vendor block in the EDID is insufficient - the AV receiver is at
liberty to modify the EDID as it sees fit, and it will place its own
parameters into the EDID including the HDMI vendor block.

DRM has support for forcing the state of a connector, which we should
implement to allow us to work around these broken DVI monitors - we can
tell DRM to force the connection state to indicate that there is always
a device connected to work around this problem.  Although this requires
manual configuration, it is better than nothing at all.

When a forced connection state has been set, there is no point handling
our RXSENSE interrupts, so disable them in this circumstance.

Signed-off-by: Russell King <rmk+kernel at arm.linux.org.uk>
---
 drivers/gpu/drm/bridge/dw_hdmi.c | 51 ++++++++++++++++++++++++++++++++++++----
 1 file changed, 47 insertions(+), 4 deletions(-)

diff --git a/drivers/gpu/drm/bridge/dw_hdmi.c b/drivers/gpu/drm/bridge/dw_hdmi.c
index 0ee188930d26..2d1c7e4ec086 100644
--- a/drivers/gpu/drm/bridge/dw_hdmi.c
+++ b/drivers/gpu/drm/bridge/dw_hdmi.c
@@ -126,7 +126,9 @@ struct dw_hdmi {
 	bool sink_has_audio;
 
 	struct mutex mutex;		/* for state below and previous_mode */
+	enum drm_connector_force force;	/* mutex-protected force state */
 	bool disabled;			/* DRM has disabled our bridge */
+	bool bridge_is_on;		/* indicates the bridge is on */
 
 	spinlock_t audio_lock;
 	struct mutex audio_mutex;
@@ -1378,12 +1380,36 @@ static void initialize_hdmi_ih_mutes(struct dw_hdmi *hdmi)
 
 static void dw_hdmi_poweron(struct dw_hdmi *hdmi)
 {
+	hdmi->bridge_is_on = true;
 	dw_hdmi_setup(hdmi, &hdmi->previous_mode);
 }
 
 static void dw_hdmi_poweroff(struct dw_hdmi *hdmi)
 {
 	dw_hdmi_phy_disable(hdmi);
+	hdmi->bridge_is_on = false;
+}
+
+static void dw_hdmi_update_power(struct dw_hdmi *hdmi)
+{
+	int force = hdmi->force;
+
+	if (hdmi->disabled) {
+		force = DRM_FORCE_OFF;
+	} else if (force == DRM_FORCE_UNSPECIFIED) {
+		if (hdmi_readb(hdmi, HDMI_PHY_STAT0) & HDMI_PHY_HPD)
+			force = DRM_FORCE_ON;
+		else
+			force = DRM_FORCE_OFF;
+	}
+
+	if (force == DRM_FORCE_OFF) {
+		if (hdmi->bridge_is_on)
+			dw_hdmi_poweroff(hdmi);
+	} else {
+		if (!hdmi->bridge_is_on)
+			dw_hdmi_poweron(hdmi);
+	}
 }
 
 static void dw_hdmi_bridge_mode_set(struct drm_bridge *bridge,
@@ -1413,7 +1439,7 @@ static void dw_hdmi_bridge_disable(struct drm_bridge *bridge)
 
 	mutex_lock(&hdmi->mutex);
 	hdmi->disabled = true;
-	dw_hdmi_poweroff(hdmi);
+	dw_hdmi_update_power(hdmi);
 	mutex_unlock(&hdmi->mutex);
 }
 
@@ -1422,8 +1448,8 @@ static void dw_hdmi_bridge_enable(struct drm_bridge *bridge)
 	struct dw_hdmi *hdmi = bridge->driver_private;
 
 	mutex_lock(&hdmi->mutex);
-	dw_hdmi_poweron(hdmi);
 	hdmi->disabled = false;
+	dw_hdmi_update_power(hdmi);
 	mutex_unlock(&hdmi->mutex);
 }
 
@@ -1438,6 +1464,11 @@ dw_hdmi_connector_detect(struct drm_connector *connector, bool force)
 	struct dw_hdmi *hdmi = container_of(connector, struct dw_hdmi,
 					     connector);
 
+	mutex_lock(&hdmi->mutex);
+	hdmi->force = DRM_FORCE_UNSPECIFIED;
+	dw_hdmi_update_power(hdmi);
+	mutex_unlock(&hdmi->mutex);
+
 	return hdmi_readb(hdmi, HDMI_PHY_STAT0) & HDMI_PHY_HPD ?
 		connector_status_connected : connector_status_disconnected;
 }
@@ -1502,11 +1533,23 @@ static void dw_hdmi_connector_destroy(struct drm_connector *connector)
 	drm_connector_cleanup(connector);
 }
 
+static void dw_hdmi_connector_force(struct drm_connector *connector)
+{
+	struct dw_hdmi *hdmi = container_of(connector, struct dw_hdmi,
+					     connector);
+
+	mutex_lock(&hdmi->mutex);
+	hdmi->force = connector->force;
+	dw_hdmi_update_power(hdmi);
+	mutex_unlock(&hdmi->mutex);
+}
+
 static struct drm_connector_funcs dw_hdmi_connector_funcs = {
 	.dpms = drm_helper_connector_dpms,
 	.fill_modes = drm_helper_probe_single_connector_modes,
 	.detect = dw_hdmi_connector_detect,
 	.destroy = dw_hdmi_connector_destroy,
+	.force = dw_hdmi_connector_force,
 };
 
 static struct drm_connector_helper_funcs dw_hdmi_connector_helper_funcs = {
@@ -1552,12 +1595,12 @@ static irqreturn_t dw_hdmi_irq(int irq, void *dev_id)
 		if (phy_int_pol & HDMI_PHY_HPD) {
 			dev_dbg(hdmi->dev, "EVENT=plugin\n");
 
-			if (!hdmi->disabled)
+			if (!hdmi->disabled && !hdmi->force)
 				dw_hdmi_poweron(hdmi);
 		} else {
 			dev_dbg(hdmi->dev, "EVENT=plugout\n");
 
-			if (!hdmi->disabled)
+			if (!hdmi->disabled && !hdmi->force)
 				dw_hdmi_poweroff(hdmi);
 		}
 		mutex_unlock(&hdmi->mutex);
-- 
2.1.0



From rmk+kernel at arm.linux.org.uk  Sat Aug  8 09:03:55 2015
From: rmk+kernel at arm.linux.org.uk (Russell King)
Date: Sat, 08 Aug 2015 17:03:55 +0100
Subject: [PATCH 07/12] drm: bridge/dw_hdmi: enable audio only if sink supports
 audio
In-Reply-To: <20150808160251.GM7557@n2100.arm.linux.org.uk>
References: <20150808160251.GM7557@n2100.arm.linux.org.uk>
Message-ID: <E1ZO6bD-0002r7-KP@rmk-PC.arm.linux.org.uk>

Only enable audio support if the sink supports audio in some form, as
defined via its EDID.  We discover this capability using the generic
drm_detect_monitor_audio() function.

Signed-off-by: Russell King <rmk+kernel at arm.linux.org.uk>
---
 drivers/gpu/drm/bridge/dw_hdmi.c | 12 +++++++++---
 1 file changed, 9 insertions(+), 3 deletions(-)

diff --git a/drivers/gpu/drm/bridge/dw_hdmi.c b/drivers/gpu/drm/bridge/dw_hdmi.c
index 7f764716f3c4..578d7362cd65 100644
--- a/drivers/gpu/drm/bridge/dw_hdmi.c
+++ b/drivers/gpu/drm/bridge/dw_hdmi.c
@@ -123,6 +123,7 @@ struct dw_hdmi {
 	struct i2c_adapter *ddc;
 	void __iomem *regs;
 	bool sink_is_hdmi;
+	bool sink_has_audio;
 
 	spinlock_t audio_lock;
 	struct mutex audio_mutex;
@@ -1271,13 +1272,17 @@ static int dw_hdmi_setup(struct dw_hdmi *hdmi, struct drm_display_mode *mode)
 	/* HDMI Initialization Step B.3 */
 	dw_hdmi_enable_video_path(hdmi);
 
-	/* not for DVI mode */
-	if (hdmi->sink_is_hdmi) {
-		dev_dbg(hdmi->dev, "%s HDMI mode\n", __func__);
+	if (hdmi->sink_has_audio) {
+		dev_dbg(hdmi->dev, "sink has audio support\n");
 
 		/* HDMI Initialization Step E - Configure audio */
 		hdmi_clk_regenerator_update_pixel_clock(hdmi);
 		hdmi_enable_audio_clk(hdmi);
+	}
+
+	/* not for DVI mode */
+	if (hdmi->sink_is_hdmi) {
+		dev_dbg(hdmi->dev, "%s HDMI mode\n", __func__);
 
 		/* HDMI Initialization Step F - Configure AVI InfoFrame */
 		hdmi_config_AVI(hdmi, mode);
@@ -1442,6 +1447,7 @@ static int dw_hdmi_connector_get_modes(struct drm_connector *connector)
 			edid->width_cm, edid->height_cm);
 
 		hdmi->sink_is_hdmi = drm_detect_hdmi_monitor(edid);
+		hdmi->sink_has_audio = drm_detect_monitor_audio(edid);
 		drm_mode_connector_update_edid_property(connector, edid);
 		ret = drm_add_edid_modes(connector, edid);
 		kfree(edid);
-- 
2.1.0



From rmk+kernel at arm.linux.org.uk  Sat Aug  8 09:04:21 2015
From: rmk+kernel at arm.linux.org.uk (Russell King)
Date: Sat, 08 Aug 2015 17:04:21 +0100
Subject: [PATCH 12/12] drm: bridge/dw_hdmi: improve HDMI enable/disable
 handling
In-Reply-To: <20150808160251.GM7557@n2100.arm.linux.org.uk>
References: <20150808160251.GM7557@n2100.arm.linux.org.uk>
Message-ID: <E1ZO6bd-0002vx-DL@rmk-PC.arm.linux.org.uk>

HDMI sinks are permitted to de-assert and re-assert the HPD signal to
indicate that their EDID has been updated, which may not involve a
change of video information.

An example of where such a situation can arise is when an AV receiver
is connected between the source and the display device.  Events which
can cause the HPD to be deasserted include:

 * turning on or switching to standby the AV receiver.
 * turning on or switching to standby the display device.

Each of these can change the entire EDID data, or just a part of the
EDID data - it's up to the connected HDMI sink to do what they desire
here.  For example

 - with the AV receiver and display device both in standby, a source
   connected to the AV receiver may provide its own EDID to the source.
 - turning on the display device causes the display device's EDID to be
   made available in an unmodified form to the source.
 - subsequently turning on the AV receiver then provides a modified
   version of the display device's EDID.

Moreover, HPD doesn't tell us whether something is actually listening
on the HDMI TDMS signals.  The phy gives us a set of RXSENSE indications
which tell us whether there is a sink connected to the TMDS signals.

Currently, we use the HPD signal to enable or disable the HDMI block,
which is questionable when HPD is used in this manner.  Using the
RXSENSE would be more appropriate, but there is some bad behaviour
which needs to be coped with.  The iMX6 implementation lets the TMDS
signals float when the phy is "powered down", which cause spurious
interrupts.  Rather than just using RXSENSE, use RXSENSE and HPD
becoming both active to signal the presence of a device, but loss
of RXSENSE to indicate that the device has been unplugged.

The side effect of this change is that a sink deasserting the HPD
signal to cause a re-read of the EDID data will not cause the bridge
to immediately disable the video signal.

Signed-off-by: Russell King <rmk+kernel at arm.linux.org.uk>
---
 drivers/gpu/drm/bridge/dw_hdmi.c | 124 ++++++++++++++++++++++++++++++++-------
 1 file changed, 102 insertions(+), 22 deletions(-)

diff --git a/drivers/gpu/drm/bridge/dw_hdmi.c b/drivers/gpu/drm/bridge/dw_hdmi.c
index 2d1c7e4ec086..fba25607ef88 100644
--- a/drivers/gpu/drm/bridge/dw_hdmi.c
+++ b/drivers/gpu/drm/bridge/dw_hdmi.c
@@ -129,6 +129,8 @@ struct dw_hdmi {
 	enum drm_connector_force force;	/* mutex-protected force state */
 	bool disabled;			/* DRM has disabled our bridge */
 	bool bridge_is_on;		/* indicates the bridge is on */
+	bool rxsense;			/* rxsense state */
+	u8 phy_mask;			/* desired phy int mask settings */
 
 	spinlock_t audio_lock;
 	struct mutex audio_mutex;
@@ -142,6 +144,14 @@ struct dw_hdmi {
 	u8 (*read)(struct dw_hdmi *hdmi, int offset);
 };
 
+#define HDMI_IH_PHY_STAT0_RX_SENSE \
+	(HDMI_IH_PHY_STAT0_RX_SENSE0 | HDMI_IH_PHY_STAT0_RX_SENSE1 | \
+	 HDMI_IH_PHY_STAT0_RX_SENSE2 | HDMI_IH_PHY_STAT0_RX_SENSE3)
+
+#define HDMI_PHY_RX_SENSE \
+	(HDMI_PHY_RX_SENSE0 | HDMI_PHY_RX_SENSE1 | \
+	 HDMI_PHY_RX_SENSE2 | HDMI_PHY_RX_SENSE3)
+
 static void dw_hdmi_writel(struct dw_hdmi *hdmi, u8 val, int offset)
 {
 	writel(val, hdmi->regs + (offset << 2));
@@ -1318,10 +1328,11 @@ static int dw_hdmi_fb_registered(struct dw_hdmi *hdmi)
 		    HDMI_PHY_I2CM_CTLINT_ADDR);
 
 	/* enable cable hot plug irq */
-	hdmi_writeb(hdmi, (u8)~HDMI_PHY_HPD, HDMI_PHY_MASK0);
+	hdmi_writeb(hdmi, hdmi->phy_mask, HDMI_PHY_MASK0);
 
 	/* Clear Hotplug interrupts */
-	hdmi_writeb(hdmi, HDMI_IH_PHY_STAT0_HPD, HDMI_IH_PHY_STAT0);
+	hdmi_writeb(hdmi, HDMI_IH_PHY_STAT0_HPD | HDMI_IH_PHY_STAT0_RX_SENSE,
+		    HDMI_IH_PHY_STAT0);
 
 	return 0;
 }
@@ -1397,7 +1408,7 @@ static void dw_hdmi_update_power(struct dw_hdmi *hdmi)
 	if (hdmi->disabled) {
 		force = DRM_FORCE_OFF;
 	} else if (force == DRM_FORCE_UNSPECIFIED) {
-		if (hdmi_readb(hdmi, HDMI_PHY_STAT0) & HDMI_PHY_HPD)
+		if (hdmi->rxsense)
 			force = DRM_FORCE_ON;
 		else
 			force = DRM_FORCE_OFF;
@@ -1412,6 +1423,31 @@ static void dw_hdmi_update_power(struct dw_hdmi *hdmi)
 	}
 }
 
+/*
+ * Adjust the detection of RXSENSE according to whether we have a forced
+ * connection mode enabled, or whether we have been disabled.  There is
+ * no point processing RXSENSE interrupts if we have a forced connection
+ * state, or DRM has us disabled.
+ *
+ * We also disable rxsense interrupts when we think we're disconnected
+ * to avoid floating TDMS signals giving false rxsense interrupts.
+ *
+ * Note: we still need to listen for HPD interrupts even when DRM has us
+ * disabled so that we can detect a connect event.
+ */
+static void dw_hdmi_update_phy_mask(struct dw_hdmi *hdmi)
+{
+	u8 old_mask = hdmi->phy_mask;
+
+	if (hdmi->force || hdmi->disabled || !hdmi->rxsense)
+		hdmi->phy_mask |= HDMI_PHY_RX_SENSE;
+	else
+		hdmi->phy_mask &= ~HDMI_PHY_RX_SENSE;
+
+	if (old_mask != hdmi->phy_mask)
+		hdmi_writeb(hdmi, hdmi->phy_mask, HDMI_PHY_MASK0);
+}
+
 static void dw_hdmi_bridge_mode_set(struct drm_bridge *bridge,
 				    struct drm_display_mode *orig_mode,
 				    struct drm_display_mode *mode)
@@ -1440,6 +1476,7 @@ static void dw_hdmi_bridge_disable(struct drm_bridge *bridge)
 	mutex_lock(&hdmi->mutex);
 	hdmi->disabled = true;
 	dw_hdmi_update_power(hdmi);
+	dw_hdmi_update_phy_mask(hdmi);
 	mutex_unlock(&hdmi->mutex);
 }
 
@@ -1450,6 +1487,7 @@ static void dw_hdmi_bridge_enable(struct drm_bridge *bridge)
 	mutex_lock(&hdmi->mutex);
 	hdmi->disabled = false;
 	dw_hdmi_update_power(hdmi);
+	dw_hdmi_update_phy_mask(hdmi);
 	mutex_unlock(&hdmi->mutex);
 }
 
@@ -1467,6 +1505,7 @@ dw_hdmi_connector_detect(struct drm_connector *connector, bool force)
 	mutex_lock(&hdmi->mutex);
 	hdmi->force = DRM_FORCE_UNSPECIFIED;
 	dw_hdmi_update_power(hdmi);
+	dw_hdmi_update_phy_mask(hdmi);
 	mutex_unlock(&hdmi->mutex);
 
 	return hdmi_readb(hdmi, HDMI_PHY_STAT0) & HDMI_PHY_HPD ?
@@ -1541,6 +1580,7 @@ static void dw_hdmi_connector_force(struct drm_connector *connector)
 	mutex_lock(&hdmi->mutex);
 	hdmi->force = connector->force;
 	dw_hdmi_update_power(hdmi);
+	dw_hdmi_update_phy_mask(hdmi);
 	mutex_unlock(&hdmi->mutex);
 }
 
@@ -1582,33 +1622,69 @@ static irqreturn_t dw_hdmi_hardirq(int irq, void *dev_id)
 static irqreturn_t dw_hdmi_irq(int irq, void *dev_id)
 {
 	struct dw_hdmi *hdmi = dev_id;
-	u8 intr_stat;
-	u8 phy_int_pol;
+	u8 intr_stat, phy_int_pol, phy_pol_mask, phy_stat;
 
 	intr_stat = hdmi_readb(hdmi, HDMI_IH_PHY_STAT0);
-
 	phy_int_pol = hdmi_readb(hdmi, HDMI_PHY_POL0);
+	phy_stat = hdmi_readb(hdmi, HDMI_PHY_STAT0);
+
+	phy_pol_mask = 0;
+	if (intr_stat & HDMI_IH_PHY_STAT0_HPD)
+		phy_pol_mask |= HDMI_PHY_HPD;
+	if (intr_stat & HDMI_IH_PHY_STAT0_RX_SENSE0)
+		phy_pol_mask |= HDMI_PHY_RX_SENSE0;
+	if (intr_stat & HDMI_IH_PHY_STAT0_RX_SENSE1)
+		phy_pol_mask |= HDMI_PHY_RX_SENSE1;
+	if (intr_stat & HDMI_IH_PHY_STAT0_RX_SENSE2)
+		phy_pol_mask |= HDMI_PHY_RX_SENSE2;
+	if (intr_stat & HDMI_IH_PHY_STAT0_RX_SENSE3)
+		phy_pol_mask |= HDMI_PHY_RX_SENSE3;
+
+	if (phy_pol_mask)
+		hdmi_modb(hdmi, ~phy_int_pol, phy_pol_mask, HDMI_PHY_POL0);
 
-	if (intr_stat & HDMI_IH_PHY_STAT0_HPD) {
-		hdmi_modb(hdmi, ~phy_int_pol, HDMI_PHY_HPD, HDMI_PHY_POL0);
+	/*
+	 * RX sense tells us whether the TDMS transmitters are detecting
+	 * load - in other words, there's something listening on the
+	 * other end of the link.  Use this to decide whether we should
+	 * power on the phy as HPD may be toggled by the sink to merely
+	 * ask the source to re-read the EDID.
+	 */
+	if (intr_stat &
+	    (HDMI_IH_PHY_STAT0_RX_SENSE | HDMI_IH_PHY_STAT0_HPD)) {
 		mutex_lock(&hdmi->mutex);
-		if (phy_int_pol & HDMI_PHY_HPD) {
-			dev_dbg(hdmi->dev, "EVENT=plugin\n");
-
-			if (!hdmi->disabled && !hdmi->force)
-				dw_hdmi_poweron(hdmi);
-		} else {
-			dev_dbg(hdmi->dev, "EVENT=plugout\n");
-
-			if (!hdmi->disabled && !hdmi->force)
-				dw_hdmi_poweroff(hdmi);
+		if (!hdmi->disabled && !hdmi->force) {
+			/*
+			 * If the RX sense status indicates we're disconnected,
+			 * clear the software rxsense status.
+			 */
+			if (!(phy_stat & HDMI_PHY_RX_SENSE))
+				hdmi->rxsense = false;
+
+			/*
+			 * Only set the software rxsense status when both
+			 * rxsense and hpd indicates we're connected.
+			 * This avoids what seems to be bad behaviour in
+			 * at least iMX6S versions of the phy.
+			 */
+			if (phy_stat & HDMI_PHY_HPD)
+				hdmi->rxsense = true;
+
+			dw_hdmi_update_power(hdmi);
+			dw_hdmi_update_phy_mask(hdmi);
 		}
 		mutex_unlock(&hdmi->mutex);
+	}
+
+	if (intr_stat & HDMI_IH_PHY_STAT0_HPD) {
+		dev_dbg(hdmi->dev, "EVENT=%s\n",
+			phy_int_pol & HDMI_PHY_HPD ? "plugin" : "plugout");
 		drm_helper_hpd_irq_event(hdmi->bridge->dev);
 	}
 
 	hdmi_writeb(hdmi, intr_stat, HDMI_IH_PHY_STAT0);
-	hdmi_writeb(hdmi, ~HDMI_IH_PHY_STAT0_HPD, HDMI_IH_MUTE_PHY_STAT0);
+	hdmi_writeb(hdmi, ~(HDMI_IH_PHY_STAT0_HPD | HDMI_IH_PHY_STAT0_RX_SENSE),
+		    HDMI_IH_MUTE_PHY_STAT0);
 
 	return IRQ_HANDLED;
 }
@@ -1674,6 +1750,8 @@ int dw_hdmi_bind(struct device *dev, struct device *master,
 	hdmi->ratio = 100;
 	hdmi->encoder = encoder;
 	hdmi->disabled = true;
+	hdmi->rxsense = true;
+	hdmi->phy_mask = (u8)~(HDMI_PHY_HPD | HDMI_PHY_RX_SENSE);
 
 	mutex_init(&hdmi->mutex);
 	mutex_init(&hdmi->audio_mutex);
@@ -1764,10 +1842,11 @@ int dw_hdmi_bind(struct device *dev, struct device *master,
 	 * Configure registers related to HDMI interrupt
 	 * generation before registering IRQ.
 	 */
-	hdmi_writeb(hdmi, HDMI_PHY_HPD, HDMI_PHY_POL0);
+	hdmi_writeb(hdmi, HDMI_PHY_HPD | HDMI_PHY_RX_SENSE, HDMI_PHY_POL0);
 
 	/* Clear Hotplug interrupts */
-	hdmi_writeb(hdmi, HDMI_IH_PHY_STAT0_HPD, HDMI_IH_PHY_STAT0);
+	hdmi_writeb(hdmi, HDMI_IH_PHY_STAT0_HPD | HDMI_IH_PHY_STAT0_RX_SENSE,
+		    HDMI_IH_PHY_STAT0);
 
 	ret = dw_hdmi_fb_registered(hdmi);
 	if (ret)
@@ -1778,7 +1857,8 @@ int dw_hdmi_bind(struct device *dev, struct device *master,
 		goto err_iahb;
 
 	/* Unmute interrupts */
-	hdmi_writeb(hdmi, ~HDMI_IH_PHY_STAT0_HPD, HDMI_IH_MUTE_PHY_STAT0);
+	hdmi_writeb(hdmi, ~(HDMI_IH_PHY_STAT0_HPD | HDMI_IH_PHY_STAT0_RX_SENSE),
+		    HDMI_IH_MUTE_PHY_STAT0);
 
 	dev_set_drvdata(dev, hdmi);
 
-- 
2.1.0



From rmk+kernel at arm.linux.org.uk  Sat Aug  8 09:04:00 2015
From: rmk+kernel at arm.linux.org.uk (Russell King)
Date: Sat, 08 Aug 2015 17:04:00 +0100
Subject: [PATCH 08/12] drm: bridge/dw_hdmi: avoid enabling interface in
 mode_set
In-Reply-To: <20150808160251.GM7557@n2100.arm.linux.org.uk>
References: <20150808160251.GM7557@n2100.arm.linux.org.uk>
Message-ID: <E1ZO6bI-0002rG-PI@rmk-PC.arm.linux.org.uk>

On a mode set, DRM makes the following sequence of calls:
* for_each_encoder
*   bridge	mode_fixup
*   encoder	mode_fixup
* crtc		mode_fixup
* for_each_encoder
*   bridge	disable
*   encoder	prepare
*   bridge	post_disable
* disable unused encoders
* crtc		prepare
* crtc		mode_set
* for_each_encoder
*   encoder	mode_set
*   bridge	mode_set
* crtc		commit
* for_each_encoder
*   bridge	pre_enable
*   encoder	commit
*   bridge	enable

dw_hdmi enables the HDMI output in both the bridge mode_set() and also
the bridge enable() step.  This is duplicated work - we can avoid the
setup in mode_set() and just do it in the enable() stage.  This
simplifies the code a little.

Signed-off-by: Russell King <rmk+kernel at arm.linux.org.uk>
---
 drivers/gpu/drm/bridge/dw_hdmi.c | 2 --
 1 file changed, 2 deletions(-)

diff --git a/drivers/gpu/drm/bridge/dw_hdmi.c b/drivers/gpu/drm/bridge/dw_hdmi.c
index 578d7362cd65..fbac8386552b 100644
--- a/drivers/gpu/drm/bridge/dw_hdmi.c
+++ b/drivers/gpu/drm/bridge/dw_hdmi.c
@@ -1389,8 +1389,6 @@ static void dw_hdmi_bridge_mode_set(struct drm_bridge *bridge,
 {
 	struct dw_hdmi *hdmi = bridge->driver_private;
 
-	dw_hdmi_setup(hdmi, mode);
-
 	/* Store the display mode for plugin/DKMS poweron events */
 	memcpy(&hdmi->previous_mode, mode, sizeof(hdmi->previous_mode));
 }
-- 
2.1.0



From rmk+kernel at arm.linux.org.uk  Sat Aug  8 09:04:11 2015
From: rmk+kernel at arm.linux.org.uk (Russell King)
Date: Sat, 08 Aug 2015 17:04:11 +0100
Subject: [PATCH 10/12] drm: bridge/dw_hdmi: fix phy enable/disable handling
In-Reply-To: <20150808160251.GM7557@n2100.arm.linux.org.uk>
References: <20150808160251.GM7557@n2100.arm.linux.org.uk>
Message-ID: <E1ZO6bT-0002vk-3d@rmk-PC.arm.linux.org.uk>

The dw_hdmi enable/disable handling is particularly weak in several
regards:
* The hotplug interrupt could call hdmi_poweron() or hdmi_poweroff()
  while DRM is setting a mode, which could race with a mode being set.
* Hotplug will always re-enable the phy whenever it detects an active
  hotplug signal, even if DRM has disabled the output.

Resolve all of these by introducing a mutex to prevent races, and a
state-tracking bool so we know whether DRM wishes the output to be
enabled.  We choose to use our own mutex rather than ->struct_mutex
so that we can still process interrupts in a timely fashion.

Signed-off-by: Russell King <rmk+kernel at arm.linux.org.uk>
---
 drivers/gpu/drm/bridge/dw_hdmi.c | 29 ++++++++++++++++++++++-------
 1 file changed, 22 insertions(+), 7 deletions(-)

diff --git a/drivers/gpu/drm/bridge/dw_hdmi.c b/drivers/gpu/drm/bridge/dw_hdmi.c
index 7b8a4e942a71..0ee188930d26 100644
--- a/drivers/gpu/drm/bridge/dw_hdmi.c
+++ b/drivers/gpu/drm/bridge/dw_hdmi.c
@@ -125,6 +125,9 @@ struct dw_hdmi {
 	bool sink_is_hdmi;
 	bool sink_has_audio;
 
+	struct mutex mutex;		/* for state below and previous_mode */
+	bool disabled;			/* DRM has disabled our bridge */
+
 	spinlock_t audio_lock;
 	struct mutex audio_mutex;
 	unsigned int sample_rate;
@@ -1389,8 +1392,12 @@ static void dw_hdmi_bridge_mode_set(struct drm_bridge *bridge,
 {
 	struct dw_hdmi *hdmi = bridge->driver_private;
 
+	mutex_lock(&hdmi->mutex);
+
 	/* Store the display mode for plugin/DKMS poweron events */
 	memcpy(&hdmi->previous_mode, mode, sizeof(hdmi->previous_mode));
+
+	mutex_unlock(&hdmi->mutex);
 }
 
 static bool dw_hdmi_bridge_mode_fixup(struct drm_bridge *bridge,
@@ -1404,14 +1411,20 @@ static void dw_hdmi_bridge_disable(struct drm_bridge *bridge)
 {
 	struct dw_hdmi *hdmi = bridge->driver_private;
 
+	mutex_lock(&hdmi->mutex);
+	hdmi->disabled = true;
 	dw_hdmi_poweroff(hdmi);
+	mutex_unlock(&hdmi->mutex);
 }
 
 static void dw_hdmi_bridge_enable(struct drm_bridge *bridge)
 {
 	struct dw_hdmi *hdmi = bridge->driver_private;
 
+	mutex_lock(&hdmi->mutex);
 	dw_hdmi_poweron(hdmi);
+	hdmi->disabled = false;
+	mutex_unlock(&hdmi->mutex);
 }
 
 static void dw_hdmi_bridge_nop(struct drm_bridge *bridge)
@@ -1534,20 +1547,20 @@ static irqreturn_t dw_hdmi_irq(int irq, void *dev_id)
 	phy_int_pol = hdmi_readb(hdmi, HDMI_PHY_POL0);
 
 	if (intr_stat & HDMI_IH_PHY_STAT0_HPD) {
+		hdmi_modb(hdmi, ~phy_int_pol, HDMI_PHY_HPD, HDMI_PHY_POL0);
+		mutex_lock(&hdmi->mutex);
 		if (phy_int_pol & HDMI_PHY_HPD) {
 			dev_dbg(hdmi->dev, "EVENT=plugin\n");
 
-			hdmi_modb(hdmi, 0, HDMI_PHY_HPD, HDMI_PHY_POL0);
-
-			dw_hdmi_poweron(hdmi);
+			if (!hdmi->disabled)
+				dw_hdmi_poweron(hdmi);
 		} else {
 			dev_dbg(hdmi->dev, "EVENT=plugout\n");
 
-			hdmi_modb(hdmi, HDMI_PHY_HPD, HDMI_PHY_HPD,
-				  HDMI_PHY_POL0);
-
-			dw_hdmi_poweroff(hdmi);
+			if (!hdmi->disabled)
+				dw_hdmi_poweroff(hdmi);
 		}
+		mutex_unlock(&hdmi->mutex);
 		drm_helper_hpd_irq_event(hdmi->bridge->dev);
 	}
 
@@ -1617,7 +1630,9 @@ int dw_hdmi_bind(struct device *dev, struct device *master,
 	hdmi->sample_rate = 48000;
 	hdmi->ratio = 100;
 	hdmi->encoder = encoder;
+	hdmi->disabled = true;
 
+	mutex_init(&hdmi->mutex);
 	mutex_init(&hdmi->audio_mutex);
 	spin_lock_init(&hdmi->audio_lock);
 
-- 
2.1.0



From linux at arm.linux.org.uk  Sat Aug  8 09:09:36 2015
From: linux at arm.linux.org.uk (Russell King - ARM Linux)
Date: Sat, 8 Aug 2015 17:09:36 +0100
Subject: [PATCH 0/9] dw-hdmi audio support
In-Reply-To: <20150808160251.GM7557@n2100.arm.linux.org.uk>
References: <20150808160251.GM7557@n2100.arm.linux.org.uk>
Message-ID: <20150808160936.GN7557@n2100.arm.linux.org.uk>

Following on from the previous sub-series, this sub-series adds audio
support to dw-hdmi.

The two different variants are now in this patch: AHB audio support
found on iMX6 platforms, and I2S support found on Rockchip patches.
Thanks to Yakir Yang for contributing the I2S support.

I suspect that there is still some discussion to be had on this
series, though I would like to see it moving forward so that we can
get something merged.

 drivers/gpu/drm/bridge/Kconfig             |  20 +
 drivers/gpu/drm/bridge/Makefile            |   2 +
 drivers/gpu/drm/bridge/dw_hdmi-ahb-audio.c | 635 +++++++++++++++++++++++++++++
 drivers/gpu/drm/bridge/dw_hdmi-audio.h     |  14 +
 drivers/gpu/drm/bridge/dw_hdmi-i2s-audio.c | 398 ++++++++++++++++++
 drivers/gpu/drm/bridge/dw_hdmi.c           | 202 ++++-----
 drivers/gpu/drm/bridge/dw_hdmi.h           |   6 +
 7 files changed, 1155 insertions(+), 122 deletions(-)

-- 
FTTC broadband for 0.8mile line: currently at 10.5Mbps down 400kbps up
according to speedtest.net.


From rmk+kernel at arm.linux.org.uk  Sat Aug  8 09:10:06 2015
From: rmk+kernel at arm.linux.org.uk (Russell King)
Date: Sat, 08 Aug 2015 17:10:06 +0100
Subject: [PATCH 1/9] drm: bridge/dw_hdmi-ahb-audio: add audio driver
In-Reply-To: <20150808160936.GN7557@n2100.arm.linux.org.uk>
References: <20150808160936.GN7557@n2100.arm.linux.org.uk>
Message-ID: <E1ZO6hC-0003M5-EU@rmk-PC.arm.linux.org.uk>

Add ALSA based HDMI AHB audio driver for dw_hdmi.  The only buffer
format supported by the hardware is its own special IEC958 based format,
which is not compatible with any ALSA format.  To avoid doing too much
data manipulation within the driver, we support only ALSAs IEC958 LE and
24-bit PCM formats for 2 to 6 channels, which we convert to its hardware
format.

A more desirable solution would be to have this conversion in userspace,
but ALSA does not appear to allow such transformations outside of
libasound itself.

Signed-off-by: Russell King <rmk+kernel at arm.linux.org.uk>
---
 drivers/gpu/drm/bridge/Kconfig             |  10 +
 drivers/gpu/drm/bridge/Makefile            |   1 +
 drivers/gpu/drm/bridge/dw_hdmi-ahb-audio.c | 561 +++++++++++++++++++++++++++++
 drivers/gpu/drm/bridge/dw_hdmi-audio.h     |  13 +
 drivers/gpu/drm/bridge/dw_hdmi.c           |  24 ++
 drivers/gpu/drm/bridge/dw_hdmi.h           |   3 +
 6 files changed, 612 insertions(+)
 create mode 100644 drivers/gpu/drm/bridge/dw_hdmi-ahb-audio.c
 create mode 100644 drivers/gpu/drm/bridge/dw_hdmi-audio.h

diff --git a/drivers/gpu/drm/bridge/Kconfig b/drivers/gpu/drm/bridge/Kconfig
index acef3223772c..56ed35fe0734 100644
--- a/drivers/gpu/drm/bridge/Kconfig
+++ b/drivers/gpu/drm/bridge/Kconfig
@@ -3,6 +3,16 @@ config DRM_DW_HDMI
 	depends on DRM
 	select DRM_KMS_HELPER
 
+config DRM_DW_HDMI_AHB_AUDIO
+	tristate "Synopsis Designware AHB Audio interface"
+	depends on DRM_DW_HDMI && SND
+	select SND_PCM
+	select SND_PCM_IEC958
+	help
+	  Support the AHB Audio interface which is part of the Synopsis
+	  Designware HDMI block.  This is used in conjunction with
+	  the i.MX6 HDMI driver.
+
 config DRM_PTN3460
 	tristate "PTN3460 DP/LVDS bridge"
 	depends on DRM
diff --git a/drivers/gpu/drm/bridge/Makefile b/drivers/gpu/drm/bridge/Makefile
index 8dfebd984370..eb80dbbb8365 100644
--- a/drivers/gpu/drm/bridge/Makefile
+++ b/drivers/gpu/drm/bridge/Makefile
@@ -3,3 +3,4 @@ ccflags-y := -Iinclude/drm
 obj-$(CONFIG_DRM_PS8622) += ps8622.o
 obj-$(CONFIG_DRM_PTN3460) += ptn3460.o
 obj-$(CONFIG_DRM_DW_HDMI) += dw_hdmi.o
+obj-$(CONFIG_DRM_DW_HDMI_AHB_AUDIO) += dw_hdmi-ahb-audio.o
diff --git a/drivers/gpu/drm/bridge/dw_hdmi-ahb-audio.c b/drivers/gpu/drm/bridge/dw_hdmi-ahb-audio.c
new file mode 100644
index 000000000000..22bbbc5c2393
--- /dev/null
+++ b/drivers/gpu/drm/bridge/dw_hdmi-ahb-audio.c
@@ -0,0 +1,561 @@
+/*
+ * DesignWare HDMI audio driver
+ *
+ * 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.
+ *
+ * Written and tested against the Designware HDMI Tx found in iMX6.
+ */
+#include <linux/io.h>
+#include <linux/interrupt.h>
+#include <linux/module.h>
+#include <linux/platform_device.h>
+#include <drm/bridge/dw_hdmi.h>
+
+#include <sound/asoundef.h>
+#include <sound/core.h>
+#include <sound/initval.h>
+#include <sound/pcm.h>
+#include <sound/pcm_iec958.h>
+
+#include "dw_hdmi-audio.h"
+
+#define DRIVER_NAME "dw-hdmi-ahb-audio"
+
+/* Provide some bits rather than bit offsets */
+enum {
+	HDMI_AHB_DMA_CONF0_SW_FIFO_RST = BIT(7),
+	HDMI_AHB_DMA_CONF0_EN_HLOCK = BIT(3),
+	HDMI_AHB_DMA_START_START = BIT(0),
+	HDMI_AHB_DMA_STOP_STOP = BIT(0),
+	HDMI_IH_MUTE_AHBDMAAUD_STAT0_ERROR = BIT(5),
+	HDMI_IH_MUTE_AHBDMAAUD_STAT0_LOST = BIT(4),
+	HDMI_IH_MUTE_AHBDMAAUD_STAT0_RETRY = BIT(3),
+	HDMI_IH_MUTE_AHBDMAAUD_STAT0_DONE = BIT(2),
+	HDMI_IH_MUTE_AHBDMAAUD_STAT0_BUFFFULL = BIT(1),
+	HDMI_IH_MUTE_AHBDMAAUD_STAT0_BUFFEMPTY = BIT(0),
+	HDMI_IH_MUTE_AHBDMAAUD_STAT0_ALL =
+		HDMI_IH_MUTE_AHBDMAAUD_STAT0_ERROR |
+		HDMI_IH_MUTE_AHBDMAAUD_STAT0_LOST |
+		HDMI_IH_MUTE_AHBDMAAUD_STAT0_RETRY |
+		HDMI_IH_MUTE_AHBDMAAUD_STAT0_DONE |
+		HDMI_IH_MUTE_AHBDMAAUD_STAT0_BUFFFULL |
+		HDMI_IH_MUTE_AHBDMAAUD_STAT0_BUFFEMPTY,
+	HDMI_IH_AHBDMAAUD_STAT0_ERROR = BIT(5),
+	HDMI_IH_AHBDMAAUD_STAT0_LOST = BIT(4),
+	HDMI_IH_AHBDMAAUD_STAT0_RETRY = BIT(3),
+	HDMI_IH_AHBDMAAUD_STAT0_DONE = BIT(2),
+	HDMI_IH_AHBDMAAUD_STAT0_BUFFFULL = BIT(1),
+	HDMI_IH_AHBDMAAUD_STAT0_BUFFEMPTY = BIT(0),
+	HDMI_IH_AHBDMAAUD_STAT0_ALL =
+		HDMI_IH_AHBDMAAUD_STAT0_ERROR |
+		HDMI_IH_AHBDMAAUD_STAT0_LOST |
+		HDMI_IH_AHBDMAAUD_STAT0_RETRY |
+		HDMI_IH_AHBDMAAUD_STAT0_DONE |
+		HDMI_IH_AHBDMAAUD_STAT0_BUFFFULL |
+		HDMI_IH_AHBDMAAUD_STAT0_BUFFEMPTY,
+	HDMI_AHB_DMA_CONF0_INCR16 = 2 << 1,
+	HDMI_AHB_DMA_CONF0_INCR8 = 1 << 1,
+	HDMI_AHB_DMA_CONF0_INCR4 = 0,
+	HDMI_AHB_DMA_CONF0_BURST_MODE = BIT(0),
+	HDMI_AHB_DMA_MASK_DONE = BIT(7),
+	HDMI_REVISION_ID = 0x0001,
+	HDMI_IH_AHBDMAAUD_STAT0 = 0x0109,
+	HDMI_IH_MUTE_AHBDMAAUD_STAT0 = 0x0189,
+	HDMI_AHB_DMA_CONF0 = 0x3600,
+	HDMI_AHB_DMA_START = 0x3601,
+	HDMI_AHB_DMA_STOP = 0x3602,
+	HDMI_AHB_DMA_THRSLD = 0x3603,
+	HDMI_AHB_DMA_STRADDR0 = 0x3604,
+	HDMI_AHB_DMA_STPADDR0 = 0x3608,
+	HDMI_AHB_DMA_MASK = 0x3614,
+	HDMI_AHB_DMA_POL = 0x3615,
+	HDMI_AHB_DMA_CONF1 = 0x3616,
+	HDMI_AHB_DMA_BUFFPOL = 0x361a,
+};
+
+struct snd_dw_hdmi {
+	struct snd_card *card;
+	struct snd_pcm *pcm;
+	struct dw_hdmi_audio_data data;
+	struct snd_pcm_substream *substream;
+	void (*reformat)(struct snd_dw_hdmi *, size_t, size_t);
+	void *buf_src;
+	void *buf_dst;
+	dma_addr_t buf_addr;
+	unsigned buf_offset;
+	unsigned buf_period;
+	unsigned buf_size;
+	unsigned channels;
+	u8 revision;
+	u8 iec_offset;
+	u8 cs[192][8];
+};
+
+static void dw_hdmi_writel(unsigned long val, void __iomem *ptr)
+{
+	writeb_relaxed(val, ptr);
+	writeb_relaxed(val >> 8, ptr + 1);
+	writeb_relaxed(val >> 16, ptr + 2);
+	writeb_relaxed(val >> 24, ptr + 3);
+}
+
+/*
+ * Convert to hardware format: The userspace buffer contains IEC958 samples,
+ * with the PCUV bits in bits 31..28 and audio samples in bits 27..4.  We
+ * need these to be in bits 27..24, with the IEC B bit in bit 28, and audio
+ * samples in 23..0.
+ *
+ * Default preamble in bits 3..0: 8 = block start, 4 = even 2 = odd
+ *
+ * Ideally, we could do with having the data properly formatted in userspace.
+ */
+static void dw_hdmi_reformat_iec958(struct snd_dw_hdmi *dw,
+	size_t offset, size_t bytes)
+{
+	u32 *src = dw->buf_src + offset;
+	u32 *dst = dw->buf_dst + offset;
+	u32 *end = dw->buf_src + offset + bytes;
+
+	do {
+		u32 b, sample = *src++;
+
+		b = (sample & 8) << (28 - 3);
+
+		sample >>= 4;
+
+		*dst++ = sample | b;
+	} while (src < end);
+}
+
+static u32 parity(u32 sample)
+{
+	sample ^= sample >> 16;
+	sample ^= sample >> 8;
+	sample ^= sample >> 4;
+	sample ^= sample >> 2;
+	sample ^= sample >> 1;
+	return (sample & 1) << 27;
+}
+
+static void dw_hdmi_reformat_s24(struct snd_dw_hdmi *dw,
+	size_t offset, size_t bytes)
+{
+	u32 *src = dw->buf_src + offset;
+	u32 *dst = dw->buf_dst + offset;
+	u32 *end = dw->buf_src + offset + bytes;
+
+	do {
+		unsigned i;
+		u8 *cs;
+
+		cs = dw->cs[dw->iec_offset++];
+		if (dw->iec_offset >= 192)
+			dw->iec_offset = 0;
+
+		i = dw->channels;
+		do {
+			u32 sample = *src++;
+
+			sample &= ~0xff000000;
+			sample |= *cs++ << 24;
+			sample |= parity(sample & ~0xf8000000);
+
+			*dst++ = sample;
+		} while (--i);
+	} while (src < end);
+}
+
+static void dw_hdmi_create_cs(struct snd_dw_hdmi *dw,
+	struct snd_pcm_runtime *runtime)
+{
+	u8 cs[4];
+	unsigned ch, i, j;
+
+	snd_pcm_create_iec958_consumer(runtime, cs, sizeof(cs));
+
+	memset(dw->cs, 0, sizeof(dw->cs));
+
+	for (ch = 0; ch < 8; ch++) {
+		cs[2] &= ~IEC958_AES2_CON_CHANNEL;
+		cs[2] |= (ch + 1) << 4;
+
+		for (i = 0; i < ARRAY_SIZE(cs); i++) {
+			unsigned c = cs[i];
+
+			for (j = 0; j < 8; j++, c >>= 1)
+				dw->cs[i * 8 + j][ch] = (c & 1) << 2;
+		}
+	}
+	dw->cs[0][0] |= BIT(4);
+}
+
+static void dw_hdmi_start_dma(struct snd_dw_hdmi *dw)
+{
+	void __iomem *base = dw->data.base;
+	unsigned offset = dw->buf_offset;
+	unsigned period = dw->buf_period;
+	u32 start, stop;
+
+	dw->reformat(dw, offset, period);
+
+	/* Clear all irqs before enabling irqs and starting DMA */
+	writeb_relaxed(HDMI_IH_AHBDMAAUD_STAT0_ALL,
+		       base + HDMI_IH_AHBDMAAUD_STAT0);
+
+	start = dw->buf_addr + offset;
+	stop = start + period - 1;
+
+	/* Setup the hardware start/stop addresses */
+	dw_hdmi_writel(start, base + HDMI_AHB_DMA_STRADDR0);
+	dw_hdmi_writel(stop, base + HDMI_AHB_DMA_STPADDR0);
+
+	writeb_relaxed((u8)~HDMI_AHB_DMA_MASK_DONE, base + HDMI_AHB_DMA_MASK);
+	writeb(HDMI_AHB_DMA_START_START, base + HDMI_AHB_DMA_START);
+
+	offset += period;
+	if (offset >= dw->buf_size)
+		offset = 0;
+	dw->buf_offset = offset;
+}
+
+static void dw_hdmi_stop_dma(struct snd_dw_hdmi *dw)
+{
+	dw->substream = NULL;
+
+	/* Disable interrupts before disabling DMA */
+	writeb_relaxed(~0, dw->data.base + HDMI_AHB_DMA_MASK);
+	writeb_relaxed(HDMI_AHB_DMA_STOP_STOP, dw->data.base + HDMI_AHB_DMA_STOP);
+}
+
+static irqreturn_t snd_dw_hdmi_irq(int irq, void *data)
+{
+	struct snd_dw_hdmi *dw = data;
+	struct snd_pcm_substream *substream;
+	unsigned stat;
+
+	stat = readb_relaxed(dw->data.base + HDMI_IH_AHBDMAAUD_STAT0);
+	if (!stat)
+		return IRQ_NONE;
+
+	writeb_relaxed(stat, dw->data.base + HDMI_IH_AHBDMAAUD_STAT0);
+
+	substream = dw->substream;
+	if (stat & HDMI_IH_AHBDMAAUD_STAT0_DONE && substream) {
+		snd_pcm_period_elapsed(substream);
+		if (dw->substream)
+			dw_hdmi_start_dma(dw);
+	}
+
+	return IRQ_HANDLED;
+}
+
+static struct snd_pcm_hardware dw_hdmi_hw = {
+	.info = SNDRV_PCM_INFO_INTERLEAVED |
+		SNDRV_PCM_INFO_BLOCK_TRANSFER |
+		SNDRV_PCM_INFO_MMAP |
+		SNDRV_PCM_INFO_MMAP_VALID,
+	.formats = SNDRV_PCM_FMTBIT_IEC958_SUBFRAME_LE |
+		   SNDRV_PCM_FMTBIT_S24_LE,
+	.rates = SNDRV_PCM_RATE_32000 |
+		 SNDRV_PCM_RATE_44100 |
+		 SNDRV_PCM_RATE_48000 |
+		 SNDRV_PCM_RATE_88200 |
+		 SNDRV_PCM_RATE_96000 |
+		 SNDRV_PCM_RATE_176400 |
+		 SNDRV_PCM_RATE_192000,
+	.channels_min = 2,
+	.channels_max = 8,
+	.buffer_bytes_max = 64 * 1024,
+	.period_bytes_min = 256,
+	.period_bytes_max = 8192,	/* ERR004323: must limit to 8k */
+	.periods_min = 2,
+	.periods_max = 16,
+	.fifo_size = 0,
+};
+
+static int dw_hdmi_open(struct snd_pcm_substream *substream)
+{
+	struct snd_pcm_runtime *runtime = substream->runtime;
+	struct snd_dw_hdmi *dw = substream->private_data;
+	void __iomem *base = dw->data.base;
+	int ret;
+
+	runtime->hw = dw_hdmi_hw;
+
+	ret = snd_pcm_limit_hw_rates(runtime);
+	if (ret < 0)
+		return ret;
+
+	ret = snd_pcm_hw_constraint_integer(runtime, SNDRV_PCM_HW_PARAM_PERIODS);
+	if (ret < 0)
+		return ret;
+
+	/* Clear FIFO */
+	writeb_relaxed(HDMI_AHB_DMA_CONF0_SW_FIFO_RST,
+		       base + HDMI_AHB_DMA_CONF0);
+
+	/* Configure interrupt polarities */
+	writeb_relaxed(~0, base + HDMI_AHB_DMA_POL);
+	writeb_relaxed(~0, base + HDMI_AHB_DMA_BUFFPOL);
+
+	/* Keep interrupts masked, and clear any pending */
+	writeb_relaxed(~0, base + HDMI_AHB_DMA_MASK);
+	writeb_relaxed(~0, base + HDMI_IH_AHBDMAAUD_STAT0);
+
+	ret = request_irq(dw->data.irq, snd_dw_hdmi_irq, IRQF_SHARED,
+			  "dw-hdmi-audio", dw);
+	if (ret)
+		return ret;
+
+	/* Un-mute done interrupt */
+	writeb_relaxed(HDMI_IH_MUTE_AHBDMAAUD_STAT0_ALL &
+		       ~HDMI_IH_MUTE_AHBDMAAUD_STAT0_DONE,
+		       base + HDMI_IH_MUTE_AHBDMAAUD_STAT0);
+
+	return 0;
+}
+
+static int dw_hdmi_close(struct snd_pcm_substream *substream)
+{
+	struct snd_dw_hdmi *dw = substream->private_data;
+
+	/* Mute all interrupts */
+	writeb_relaxed(HDMI_IH_MUTE_AHBDMAAUD_STAT0_ALL,
+		       dw->data.base + HDMI_IH_MUTE_AHBDMAAUD_STAT0);
+
+	free_irq(dw->data.irq, dw);
+
+	return 0;
+}
+
+static int dw_hdmi_hw_free(struct snd_pcm_substream *substream)
+{
+	return snd_pcm_lib_free_vmalloc_buffer(substream);
+}
+
+static int dw_hdmi_hw_params(struct snd_pcm_substream *substream,
+	struct snd_pcm_hw_params *params)
+{
+	return snd_pcm_lib_alloc_vmalloc_buffer(substream,
+						params_buffer_bytes(params));
+}
+
+static int dw_hdmi_prepare(struct snd_pcm_substream *substream)
+{
+	struct snd_pcm_runtime *runtime = substream->runtime;
+	struct snd_dw_hdmi *dw = substream->private_data;
+	u8 threshold, conf0, conf1;
+
+	/* Setup as per 3.0.5 FSL 4.1.0 BSP */
+	switch (dw->revision) {
+	case 0x0a:
+		conf0 = HDMI_AHB_DMA_CONF0_BURST_MODE |
+			HDMI_AHB_DMA_CONF0_INCR4;
+		if (runtime->channels == 2)
+			threshold = 126;
+		else
+			threshold = 124;
+		break;
+	case 0x1a:
+		conf0 = HDMI_AHB_DMA_CONF0_BURST_MODE |
+			HDMI_AHB_DMA_CONF0_INCR8;
+		threshold = 128;
+		break;
+	default:
+		/* NOTREACHED */
+		return -EINVAL;
+	}
+
+	dw_hdmi_set_sample_rate(dw->data.hdmi, runtime->rate);
+
+	/* Minimum number of bytes in the fifo. */
+	runtime->hw.fifo_size = threshold * 32;
+
+	conf0 |= HDMI_AHB_DMA_CONF0_EN_HLOCK;
+	conf1 = (1 << runtime->channels) - 1;
+
+	writeb_relaxed(threshold, dw->data.base + HDMI_AHB_DMA_THRSLD);
+	writeb_relaxed(conf0, dw->data.base + HDMI_AHB_DMA_CONF0);
+	writeb_relaxed(conf1, dw->data.base + HDMI_AHB_DMA_CONF1);
+
+	switch (runtime->format) {
+	case SNDRV_PCM_FORMAT_IEC958_SUBFRAME_LE:
+		dw->reformat = dw_hdmi_reformat_iec958;
+		break;
+	case SNDRV_PCM_FORMAT_S24_LE:
+		dw_hdmi_create_cs(dw, runtime);
+		dw->reformat = dw_hdmi_reformat_s24;
+		break;
+	}
+	dw->iec_offset = 0;
+	dw->channels = runtime->channels;
+	dw->buf_src  = runtime->dma_area;
+	dw->buf_dst  = substream->dma_buffer.area;
+	dw->buf_addr = substream->dma_buffer.addr;
+	dw->buf_period = snd_pcm_lib_period_bytes(substream);
+	dw->buf_size = snd_pcm_lib_buffer_bytes(substream);
+
+	return 0;
+}
+
+static int dw_hdmi_trigger(struct snd_pcm_substream *substream, int cmd)
+{
+	struct snd_dw_hdmi *dw = substream->private_data;
+	int ret = 0;
+
+	switch (cmd) {
+	case SNDRV_PCM_TRIGGER_START:
+		dw->buf_offset = 0;
+		dw->substream = substream;
+		dw_hdmi_start_dma(dw);
+		dw_hdmi_audio_enable(dw->data.hdmi);
+		substream->runtime->delay = substream->runtime->period_size;
+		break;
+
+	case SNDRV_PCM_TRIGGER_STOP:
+		dw_hdmi_stop_dma(dw);
+		dw_hdmi_audio_disable(dw->data.hdmi);
+		break;
+
+	default:
+		ret = -EINVAL;
+		break;
+	}
+
+	return ret;
+}
+
+static snd_pcm_uframes_t dw_hdmi_pointer(struct snd_pcm_substream *substream)
+{
+	struct snd_pcm_runtime *runtime = substream->runtime;
+	struct snd_dw_hdmi *dw = substream->private_data;
+
+	return bytes_to_frames(runtime, dw->buf_offset);
+}
+
+static struct snd_pcm_ops snd_dw_hdmi_ops = {
+	.open = dw_hdmi_open,
+	.close = dw_hdmi_close,
+	.ioctl = snd_pcm_lib_ioctl,
+	.hw_params = dw_hdmi_hw_params,
+	.hw_free = dw_hdmi_hw_free,
+	.prepare = dw_hdmi_prepare,
+	.trigger = dw_hdmi_trigger,
+	.pointer = dw_hdmi_pointer,
+	.page = snd_pcm_lib_get_vmalloc_page,
+};
+
+static int snd_dw_hdmi_probe(struct platform_device *pdev)
+{
+	const struct dw_hdmi_audio_data *data = pdev->dev.platform_data;
+	struct device *dev = pdev->dev.parent;
+	struct snd_dw_hdmi *dw;
+	struct snd_card *card;
+	struct snd_pcm *pcm;
+	unsigned revision;
+	int ret;
+
+	writeb_relaxed(HDMI_IH_MUTE_AHBDMAAUD_STAT0_ALL,
+		       data->base + HDMI_IH_MUTE_AHBDMAAUD_STAT0);
+	revision = readb_relaxed(data->base + HDMI_REVISION_ID);
+	if (revision != 0x0a && revision != 0x1a) {
+		dev_err(dev, "dw-hdmi-audio: unknown revision 0x%02x\n",
+			revision);
+		return -ENXIO;
+	}
+
+	ret = snd_card_new(dev, SNDRV_DEFAULT_IDX1, SNDRV_DEFAULT_STR1,
+			      THIS_MODULE, sizeof(struct snd_dw_hdmi), &card);
+	if (ret < 0)
+		return ret;
+
+	strlcpy(card->driver, DRIVER_NAME, sizeof(card->driver));
+	strlcpy(card->shortname, "DW-HDMI", sizeof(card->shortname));
+	snprintf(card->longname, sizeof(card->longname),
+		 "%s rev 0x%02x, irq %d", card->shortname, revision,
+		 data->irq);
+
+	dw = card->private_data;
+	dw->card = card;
+	dw->data = *data;
+	dw->revision = revision;
+
+	ret = snd_pcm_new(card, "DW HDMI", 0, 1, 0, &pcm);
+	if (ret < 0)
+		goto err;
+
+	dw->pcm = pcm;
+	pcm->private_data = dw;
+	strlcpy(pcm->name, DRIVER_NAME, sizeof(pcm->name));
+	snd_pcm_set_ops(pcm, SNDRV_PCM_STREAM_PLAYBACK, &snd_dw_hdmi_ops);
+
+	snd_pcm_lib_preallocate_pages_for_all(pcm, SNDRV_DMA_TYPE_DEV,
+			dev, 64 * 1024, 64 * 1024);
+
+	ret = snd_card_register(card);
+	if (ret < 0)
+		goto err;
+
+	platform_set_drvdata(pdev, dw);
+
+	return 0;
+
+err:
+	snd_card_free(card);
+	return ret;
+}
+
+static int snd_dw_hdmi_remove(struct platform_device *pdev)
+{
+	struct snd_dw_hdmi *dw = platform_get_drvdata(pdev);
+
+	snd_card_free(dw->card);
+
+	return 0;
+}
+
+#ifdef CONFIG_PM_SLEEP
+static int snd_dw_hdmi_suspend(struct device *dev)
+{
+	struct snd_dw_hdmi *dw = dev_get_drvdata(dev);
+
+	snd_power_change_state(dw->card, SNDRV_CTL_POWER_D3cold);
+	snd_pcm_suspend_all(dw->pcm);
+
+	return 0;
+}
+
+static int snd_dw_hdmi_resume(struct device *dev)
+{
+	struct snd_dw_hdmi *dw = dev_get_drvdata(dev);
+
+	snd_power_change_state(dw->card, SNDRV_CTL_POWER_D0);
+
+	return 0;
+}
+
+static SIMPLE_DEV_PM_OPS(snd_dw_hdmi_pm, snd_dw_hdmi_suspend,
+			 snd_dw_hdmi_resume);
+#define PM_OPS &snd_dw_hdmi_pm
+#else
+#define PM_OPS NULL
+#endif
+
+static struct platform_driver snd_dw_hdmi_driver = {
+	.probe	= snd_dw_hdmi_probe,
+	.remove	= snd_dw_hdmi_remove,
+	.driver	= {
+		.name = DRIVER_NAME,
+		.owner = THIS_MODULE,
+		.pm = PM_OPS,
+	},
+};
+
+module_platform_driver(snd_dw_hdmi_driver);
+
+MODULE_AUTHOR("Russell King <rmk+kernel at arm.linux.org.uk>");
+MODULE_DESCRIPTION("Synopsis Designware HDMI AHB ALSA interface");
+MODULE_LICENSE("GPL v2");
+MODULE_ALIAS("platform:" DRIVER_NAME);
diff --git a/drivers/gpu/drm/bridge/dw_hdmi-audio.h b/drivers/gpu/drm/bridge/dw_hdmi-audio.h
new file mode 100644
index 000000000000..1e840118d90a
--- /dev/null
+++ b/drivers/gpu/drm/bridge/dw_hdmi-audio.h
@@ -0,0 +1,13 @@
+#ifndef DW_HDMI_AUDIO_H
+#define DW_HDMI_AUDIO_H
+
+struct dw_hdmi;
+
+struct dw_hdmi_audio_data {
+	phys_addr_t phys;
+	void __iomem *base;
+	int irq;
+	struct dw_hdmi *hdmi;
+};
+
+#endif
diff --git a/drivers/gpu/drm/bridge/dw_hdmi.c b/drivers/gpu/drm/bridge/dw_hdmi.c
index fba25607ef88..b65464789fbd 100644
--- a/drivers/gpu/drm/bridge/dw_hdmi.c
+++ b/drivers/gpu/drm/bridge/dw_hdmi.c
@@ -28,6 +28,7 @@
 #include <drm/bridge/dw_hdmi.h>
 
 #include "dw_hdmi.h"
+#include "dw_hdmi-audio.h"
 
 #define HDMI_EDID_LEN		512
 
@@ -104,6 +105,7 @@ struct dw_hdmi {
 	struct drm_encoder *encoder;
 	struct drm_bridge *bridge;
 
+	struct platform_device *audio;
 	enum dw_hdmi_devtype dev_type;
 	struct device *dev;
 	struct clk *isfr_clk;
@@ -1732,7 +1734,9 @@ int dw_hdmi_bind(struct device *dev, struct device *master,
 {
 	struct drm_device *drm = data;
 	struct device_node *np = dev->of_node;
+	struct platform_device_info pdevinfo;
 	struct device_node *ddc_node;
+	struct dw_hdmi_audio_data audio;
 	struct dw_hdmi *hdmi;
 	int ret;
 	u32 val = 1;
@@ -1860,6 +1864,23 @@ int dw_hdmi_bind(struct device *dev, struct device *master,
 	hdmi_writeb(hdmi, ~(HDMI_IH_PHY_STAT0_HPD | HDMI_IH_PHY_STAT0_RX_SENSE),
 		    HDMI_IH_MUTE_PHY_STAT0);
 
+	memset(&pdevinfo, 0, sizeof(pdevinfo));
+	pdevinfo.parent = dev;
+	pdevinfo.id = PLATFORM_DEVID_AUTO;
+
+	if (hdmi_readb(hdmi, HDMI_CONFIG1_ID) & HDMI_CONFIG1_AHB) {
+		audio.phys = iores->start;
+		audio.base = hdmi->regs;
+		audio.irq = irq;
+		audio.hdmi = hdmi;
+
+		pdevinfo.name = "dw-hdmi-ahb-audio";
+		pdevinfo.data = &audio;
+		pdevinfo.size_data = sizeof(audio);
+		pdevinfo.dma_mask = DMA_BIT_MASK(32);
+		hdmi->audio = platform_device_register_full(&pdevinfo);
+	}
+
 	dev_set_drvdata(dev, hdmi);
 
 	return 0;
@@ -1877,6 +1898,9 @@ void dw_hdmi_unbind(struct device *dev, struct device *master, void *data)
 {
 	struct dw_hdmi *hdmi = dev_get_drvdata(dev);
 
+	if (hdmi->audio && !IS_ERR(hdmi->audio))
+		platform_device_unregister(hdmi->audio);
+
 	/* Disable all interrupts */
 	hdmi_writeb(hdmi, ~0, HDMI_IH_MUTE_PHY_STAT0);
 
diff --git a/drivers/gpu/drm/bridge/dw_hdmi.h b/drivers/gpu/drm/bridge/dw_hdmi.h
index 175dbc89a824..78e54e813212 100644
--- a/drivers/gpu/drm/bridge/dw_hdmi.h
+++ b/drivers/gpu/drm/bridge/dw_hdmi.h
@@ -545,6 +545,9 @@
 #define HDMI_I2CM_FS_SCL_LCNT_0_ADDR            0x7E12
 
 enum {
+/* CONFIG1_ID field values */
+	HDMI_CONFIG1_AHB = 0x01,
+
 /* IH_FC_INT2 field values */
 	HDMI_IH_FC_INT2_OVERFLOW_MASK = 0x03,
 	HDMI_IH_FC_INT2_LOW_PRIORITY_OVERFLOW = 0x02,
-- 
2.1.0



From rmk+kernel at arm.linux.org.uk  Sat Aug  8 09:10:16 2015
From: rmk+kernel at arm.linux.org.uk (Russell King)
Date: Sat, 08 Aug 2015 17:10:16 +0100
Subject: [PATCH 3/9] drm: bridge/dw_hdmi-ahb-audio: basic support for
 multi-channel PCM audio
In-Reply-To: <20150808160936.GN7557@n2100.arm.linux.org.uk>
References: <20150808160936.GN7557@n2100.arm.linux.org.uk>
Message-ID: <E1ZO6hM-0003N8-NX@rmk-PC.arm.linux.org.uk>

Add basic support for multi-channel PCM audio, with fixed speaker
mappings.  This has been tested with an AV receiver, and appears to
work for low sample rates up to 8 channels.

It should be noted that multi-channel mode using the IEC958 alsa-lib
conversion plugin requires correct AES channel status for the AV
receiver to recognise the stream, especially the sample rate bits.
"Not identified" does not work there.

Signed-off-by: Russell King <rmk+kernel at arm.linux.org.uk>
---
 drivers/gpu/drm/bridge/dw_hdmi-ahb-audio.c | 59 +++++++++++++++++++++++++++++-
 1 file changed, 57 insertions(+), 2 deletions(-)

diff --git a/drivers/gpu/drm/bridge/dw_hdmi-ahb-audio.c b/drivers/gpu/drm/bridge/dw_hdmi-ahb-audio.c
index 125b81306254..3a8f32e04b63 100644
--- a/drivers/gpu/drm/bridge/dw_hdmi-ahb-audio.c
+++ b/drivers/gpu/drm/bridge/dw_hdmi-ahb-audio.c
@@ -62,9 +62,14 @@ enum {
 	HDMI_AHB_DMA_CONF0_INCR4 = 0,
 	HDMI_AHB_DMA_CONF0_BURST_MODE = BIT(0),
 	HDMI_AHB_DMA_MASK_DONE = BIT(7),
+
 	HDMI_REVISION_ID = 0x0001,
 	HDMI_IH_AHBDMAAUD_STAT0 = 0x0109,
 	HDMI_IH_MUTE_AHBDMAAUD_STAT0 = 0x0189,
+	HDMI_FC_AUDICONF2 = 0x1027,
+	HDMI_FC_AUDSCONF = 0x1063,
+	HDMI_FC_AUDSCONF_LAYOUT1 = 1 << 0,
+	HDMI_FC_AUDSCONF_LAYOUT0 = 0 << 0,
 	HDMI_AHB_DMA_CONF0 = 0x3600,
 	HDMI_AHB_DMA_START = 0x3601,
 	HDMI_AHB_DMA_STOP = 0x3602,
@@ -77,6 +82,44 @@ enum {
 	HDMI_AHB_DMA_BUFFPOL = 0x361a,
 };
 
+struct dw_hdmi_channel_conf {
+	u8 conf1;
+	u8 ca;
+};
+
+/*
+ * The default mapping of ALSA channels to HDMI channels and speaker
+ * allocation bits.  Note that we can't do channel remapping here -
+ * channels must be in the same order.
+ *
+ * Mappings for alsa-lib pcm/surround*.conf files:
+ *
+ *		Front	Sur4.0	Sur4.1	Sur5.0	Sur5.1	Sur7.1
+ * Channels	2	4	6	6	6	8
+ *
+ * Our mapping from ALSA channel to CEA686D speaker name and HDMI channel:
+ *
+ *				Number of ALSA channels
+ * ALSA Channel	2	3	4	5	6	7	8
+ * 0		FL:0	=	=	=	=	=	=
+ * 1		FR:1	=	=	=	=	=	=
+ * 2			FC:3	RL:4	LFE:2	=	=	=
+ * 3				RR:5	RL:4	FC:3	=	=
+ * 4					RR:5	RL:4	=	=
+ * 5						RR:5	=	=
+ * 6							RC:6	=
+ * 7							RLC/FRC	RLC/FRC
+ */
+static struct dw_hdmi_channel_conf default_hdmi_channel_config[7] = {
+	{ 0x03, 0x00 },	/* FL,FR */
+	{ 0x0b, 0x02 },	/* FL,FR,FC */
+	{ 0x33, 0x08 },	/* FL,FR,RL,RR */
+	{ 0x37, 0x09 },	/* FL,FR,LFE,RL,RR */
+	{ 0x3f, 0x0b },	/* FL,FR,LFE,FC,RL,RR */
+	{ 0x7f, 0x0f },	/* FL,FR,LFE,FC,RL,RR,RC */
+	{ 0xff, 0x13 },	/* FL,FR,LFE,FC,RL,RR,[FR]RC,[FR]LC */
+};
+
 struct snd_dw_hdmi {
 	struct snd_card *card;
 	struct snd_pcm *pcm;
@@ -352,7 +395,7 @@ static int dw_hdmi_prepare(struct snd_pcm_substream *substream)
 {
 	struct snd_pcm_runtime *runtime = substream->runtime;
 	struct snd_dw_hdmi *dw = substream->private_data;
-	u8 threshold, conf0, conf1;
+	u8 threshold, conf0, conf1, layout, ca;
 
 	/* Setup as per 3.0.5 FSL 4.1.0 BSP */
 	switch (dw->revision) {
@@ -380,11 +423,23 @@ static int dw_hdmi_prepare(struct snd_pcm_substream *substream)
 	runtime->hw.fifo_size = threshold * 32;
 
 	conf0 |= HDMI_AHB_DMA_CONF0_EN_HLOCK;
-	conf1 = (1 << runtime->channels) - 1;
+	conf1 = default_hdmi_channel_config[runtime->channels - 2].conf1;
+	ca = default_hdmi_channel_config[runtime->channels - 2].ca;
+
+	/*
+	 * For >2 channel PCM audio, we need to select layout 1
+	 * and set an appropriate channel map.
+	 */
+	if (runtime->channels > 2)
+		layout = HDMI_FC_AUDSCONF_LAYOUT1;
+	else
+		layout = HDMI_FC_AUDSCONF_LAYOUT0;
 
 	writeb_relaxed(threshold, dw->data.base + HDMI_AHB_DMA_THRSLD);
 	writeb_relaxed(conf0, dw->data.base + HDMI_AHB_DMA_CONF0);
 	writeb_relaxed(conf1, dw->data.base + HDMI_AHB_DMA_CONF1);
+	writeb_relaxed(layout, dw->data.base + HDMI_FC_AUDSCONF);
+	writeb_relaxed(ca, dw->data.base + HDMI_FC_AUDICONF2);
 
 	switch (runtime->format) {
 	case SNDRV_PCM_FORMAT_IEC958_SUBFRAME_LE:
-- 
2.1.0



From rmk+kernel at arm.linux.org.uk  Sat Aug  8 09:10:21 2015
From: rmk+kernel at arm.linux.org.uk (Russell King)
Date: Sat, 08 Aug 2015 17:10:21 +0100
Subject: [PATCH 4/9] drm: bridge/dw_hdmi-ahb-audio: allow larger buffer sizes
In-Reply-To: <20150808160936.GN7557@n2100.arm.linux.org.uk>
References: <20150808160936.GN7557@n2100.arm.linux.org.uk>
Message-ID: <E1ZO6hR-0003NE-Rq@rmk-PC.arm.linux.org.uk>

With multichannel audio, we need to allow larger buffer sizes to avoid
XRUNs during playback.  Push the buffer size up to 1024K, but as we
maintain two buffers, ensure that the vmalloc buffer does not exceed
the userspace buffer size.

Signed-off-by: Russell King <rmk+kernel at arm.linux.org.uk>
---
 drivers/gpu/drm/bridge/dw_hdmi-ahb-audio.c | 19 ++++++++++++++++---
 1 file changed, 16 insertions(+), 3 deletions(-)

diff --git a/drivers/gpu/drm/bridge/dw_hdmi-ahb-audio.c b/drivers/gpu/drm/bridge/dw_hdmi-ahb-audio.c
index 3a8f32e04b63..4b537f9ce8f0 100644
--- a/drivers/gpu/drm/bridge/dw_hdmi-ahb-audio.c
+++ b/drivers/gpu/drm/bridge/dw_hdmi-ahb-audio.c
@@ -312,7 +312,7 @@ static struct snd_pcm_hardware dw_hdmi_hw = {
 		 SNDRV_PCM_RATE_192000,
 	.channels_min = 2,
 	.channels_max = 8,
-	.buffer_bytes_max = 64 * 1024,
+	.buffer_bytes_max = 1024 * 1024,
 	.period_bytes_min = 256,
 	.period_bytes_max = 8192,	/* ERR004323: must limit to 8k */
 	.periods_min = 2,
@@ -337,7 +337,15 @@ static int dw_hdmi_open(struct snd_pcm_substream *substream)
 	if (ret < 0)
 		return ret;
 
-	ret = snd_pcm_hw_constraint_integer(runtime, SNDRV_PCM_HW_PARAM_PERIODS);
+	ret = snd_pcm_hw_constraint_integer(runtime,
+					    SNDRV_PCM_HW_PARAM_PERIODS);
+	if (ret < 0)
+		return ret;
+
+	/* Limit the buffer size to the size of the preallocated buffer */
+	ret = snd_pcm_hw_constraint_minmax(runtime,
+					   SNDRV_PCM_HW_PARAM_BUFFER_SIZE,
+					   0, substream->dma_buffer.bytes);
 	if (ret < 0)
 		return ret;
 
@@ -387,6 +395,7 @@ static int dw_hdmi_hw_free(struct snd_pcm_substream *substream)
 static int dw_hdmi_hw_params(struct snd_pcm_substream *substream,
 	struct snd_pcm_hw_params *params)
 {
+	/* Allocate the PCM runtime buffer, which is exposed to userspace. */
 	return snd_pcm_lib_alloc_vmalloc_buffer(substream,
 						params_buffer_bytes(params));
 }
@@ -552,8 +561,12 @@ static int snd_dw_hdmi_probe(struct platform_device *pdev)
 	strlcpy(pcm->name, DRIVER_NAME, sizeof(pcm->name));
 	snd_pcm_set_ops(pcm, SNDRV_PCM_STREAM_PLAYBACK, &snd_dw_hdmi_ops);
 
+	/*
+	 * To support 8-channel 96kHz audio reliably, we need 512k
+	 * to satisfy alsa with our restricted period (ERR004323).
+	 */
 	snd_pcm_lib_preallocate_pages_for_all(pcm, SNDRV_DMA_TYPE_DEV,
-			dev, 64 * 1024, 64 * 1024);
+			dev, 128 * 1024, 1024 * 1024);
 
 	ret = snd_card_register(card);
 	if (ret < 0)
-- 
2.1.0



From rmk+kernel at arm.linux.org.uk  Sat Aug  8 09:10:27 2015
From: rmk+kernel at arm.linux.org.uk (Russell King)
Date: Sat, 08 Aug 2015 17:10:27 +0100
Subject: [PATCH 5/9] drm: bridge/dw_hdmi: avoid being recursive in N
 calculation
In-Reply-To: <20150808160936.GN7557@n2100.arm.linux.org.uk>
References: <20150808160936.GN7557@n2100.arm.linux.org.uk>
Message-ID: <E1ZO6hX-0003NK-0H@rmk-PC.arm.linux.org.uk>

There's no need to be recursive when computing the N value for the ACR
packet - we can instead calculate the multiplier prior to our switch()
based lookup, and multiply the N value appropriately afterwards.

Signed-off-by: Russell King <rmk+kernel at arm.linux.org.uk>
---
 drivers/gpu/drm/bridge/dw_hdmi.c | 25 +++++++++----------------
 1 file changed, 9 insertions(+), 16 deletions(-)

diff --git a/drivers/gpu/drm/bridge/dw_hdmi.c b/drivers/gpu/drm/bridge/dw_hdmi.c
index a8b243278774..f0e6059f818a 100644
--- a/drivers/gpu/drm/bridge/dw_hdmi.c
+++ b/drivers/gpu/drm/bridge/dw_hdmi.c
@@ -221,6 +221,12 @@ static unsigned int hdmi_compute_n(unsigned int freq, unsigned long pixel_clk,
 				   unsigned int ratio)
 {
 	unsigned int n = (128 * freq) / 1000;
+	unsigned int mult = 1;
+
+	while (freq > 48000) {
+		mult *= 2;
+		freq /= 2;
+	}
 
 	switch (freq) {
 	case 32000:
@@ -232,6 +238,7 @@ static unsigned int hdmi_compute_n(unsigned int freq, unsigned long pixel_clk,
 			n = 11648;
 		else
 			n = 4096;
+		n *= mult;
 		break;
 
 	case 44100:
@@ -243,6 +250,7 @@ static unsigned int hdmi_compute_n(unsigned int freq, unsigned long pixel_clk,
 			n = (ratio == 150) ? 17836 : 8918;
 		else
 			n = 6272;
+		n *= mult;
 		break;
 
 	case 48000:
@@ -256,22 +264,7 @@ static unsigned int hdmi_compute_n(unsigned int freq, unsigned long pixel_clk,
 			n = (ratio == 150) ? 11648 : 5824;
 		else
 			n = 6144;
-		break;
-
-	case 88200:
-		n = hdmi_compute_n(44100, pixel_clk, ratio) * 2;
-		break;
-
-	case 96000:
-		n = hdmi_compute_n(48000, pixel_clk, ratio) * 2;
-		break;
-
-	case 176400:
-		n = hdmi_compute_n(44100, pixel_clk, ratio) * 4;
-		break;
-
-	case 192000:
-		n = hdmi_compute_n(48000, pixel_clk, ratio) * 4;
+		n *= mult;
 		break;
 
 	default:
-- 
2.1.0



From rmk+kernel at arm.linux.org.uk  Sat Aug  8 09:10:32 2015
From: rmk+kernel at arm.linux.org.uk (Russell King)
Date: Sat, 08 Aug 2015 17:10:32 +0100
Subject: [PATCH 6/9] drm: bridge/dw_hdmi: adjust pixel clock values in N
 calculation
In-Reply-To: <20150808160936.GN7557@n2100.arm.linux.org.uk>
References: <20150808160936.GN7557@n2100.arm.linux.org.uk>
Message-ID: <E1ZO6hc-0003NW-55@rmk-PC.arm.linux.org.uk>

Adjust the pixel clock values in the N calculation to match the more
accurate clock values we're given by the DRM subsystem, which are the
kHz pixel rate, with any fractional kHz rounded down in the case of
the non-240, non-480 line modes, or rounded up for the others.  So,

	 25.20 / 1.001 =>  25175
	 27.00 * 1.001 =>  27027
	 74.25 / 1.001 =>  74176
	148.50 / 1.001 => 148352

Signed-off-by: Russell King <rmk+kernel at arm.linux.org.uk>
---
 drivers/gpu/drm/bridge/dw_hdmi.c | 20 ++++++++++----------
 1 file changed, 10 insertions(+), 10 deletions(-)

diff --git a/drivers/gpu/drm/bridge/dw_hdmi.c b/drivers/gpu/drm/bridge/dw_hdmi.c
index f0e6059f818a..5576cd7d7abb 100644
--- a/drivers/gpu/drm/bridge/dw_hdmi.c
+++ b/drivers/gpu/drm/bridge/dw_hdmi.c
@@ -230,11 +230,11 @@ static unsigned int hdmi_compute_n(unsigned int freq, unsigned long pixel_clk,
 
 	switch (freq) {
 	case 32000:
-		if (pixel_clk == 25170000)
+		if (pixel_clk == 25175000)
 			n = (ratio == 150) ? 9152 : 4576;
-		else if (pixel_clk == 27020000)
+		else if (pixel_clk == 27027000)
 			n = (ratio == 150) ? 8192 : 4096;
-		else if (pixel_clk == 74170000 || pixel_clk == 148350000)
+		else if (pixel_clk == 74176000 || pixel_clk == 148352000)
 			n = 11648;
 		else
 			n = 4096;
@@ -242,11 +242,11 @@ static unsigned int hdmi_compute_n(unsigned int freq, unsigned long pixel_clk,
 		break;
 
 	case 44100:
-		if (pixel_clk == 25170000)
+		if (pixel_clk == 25175000)
 			n = 7007;
-		else if (pixel_clk == 74170000)
+		else if (pixel_clk == 74176000)
 			n = 17836;
-		else if (pixel_clk == 148350000)
+		else if (pixel_clk == 148352000)
 			n = (ratio == 150) ? 17836 : 8918;
 		else
 			n = 6272;
@@ -254,13 +254,13 @@ static unsigned int hdmi_compute_n(unsigned int freq, unsigned long pixel_clk,
 		break;
 
 	case 48000:
-		if (pixel_clk == 25170000)
+		if (pixel_clk == 25175000)
 			n = (ratio == 150) ? 9152 : 6864;
-		else if (pixel_clk == 27020000)
+		else if (pixel_clk == 27027000)
 			n = (ratio == 150) ? 8192 : 6144;
-		else if (pixel_clk == 74170000)
+		else if (pixel_clk == 74176000)
 			n = 11648;
-		else if (pixel_clk == 148350000)
+		else if (pixel_clk == 148352000)
 			n = (ratio == 150) ? 11648 : 5824;
 		else
 			n = 6144;
-- 
2.1.0



From rmk+kernel at arm.linux.org.uk  Sat Aug  8 09:10:47 2015
From: rmk+kernel at arm.linux.org.uk (Russell King)
Date: Sat, 08 Aug 2015 17:10:47 +0100
Subject: [PATCH 9/9] drm: bridge/dw_hdmi-i2s-audio: add audio driver
In-Reply-To: <20150808160936.GN7557@n2100.arm.linux.org.uk>
References: <20150808160936.GN7557@n2100.arm.linux.org.uk>
Message-ID: <E1ZO6hr-0003No-RB@rmk-PC.arm.linux.org.uk>

From: Yakir Yang <ykk at rock-chips.com>
To: linux-rockchip at lists.infradead.org,alsa-devel at alsa-project.org,dri-devel at lists.freedesktop.org,linux-kernel at vger.kernel.org,linux-arm-kernel at lists.infradead.org

Add ALSA based HDMI I2S audio driver for dw_hdmi. Sound card
driver could connect to this codec through the codec dai name
"dw-hdmi-i2s-audio".

[Fixed IRQ name, MODULE_DESCRIPTION, MODULE_ALIAS in
 dw-hdmi-i2s-audio.c, and platform device name in dw-hdmi.c --rmk]

Signed-off-by: Yakir Yang <ykk at rock-chips.com>
Signed-off-by: Russell King <rmk+kernel at arm.linux.org.uk>
---
 drivers/gpu/drm/bridge/Kconfig             |   9 +
 drivers/gpu/drm/bridge/Makefile            |   1 +
 drivers/gpu/drm/bridge/dw_hdmi-i2s-audio.c | 398 +++++++++++++++++++++++++++++
 drivers/gpu/drm/bridge/dw_hdmi.c           |  24 +-
 drivers/gpu/drm/bridge/dw_hdmi.h           |   3 +
 5 files changed, 426 insertions(+), 9 deletions(-)
 create mode 100644 drivers/gpu/drm/bridge/dw_hdmi-i2s-audio.c

diff --git a/drivers/gpu/drm/bridge/Kconfig b/drivers/gpu/drm/bridge/Kconfig
index 204861bfb867..59e3f24c4918 100644
--- a/drivers/gpu/drm/bridge/Kconfig
+++ b/drivers/gpu/drm/bridge/Kconfig
@@ -14,6 +14,15 @@ config DRM_DW_HDMI_AHB_AUDIO
 	  Designware HDMI block.  This is used in conjunction with
 	  the i.MX6 HDMI driver.
 
+config DRM_DW_HDMI_I2S_AUDIO
+	tristate "Synopsis Designware I2S Audio interface"
+	depends on DRM_DW_HDMI && SND
+	select SND_PCM
+	help
+	  Support the I2S Audio interface which is part of the Synopsis
+	  Designware HDMI block.  This is used in conjunction with the
+	  RK3288 HDMI driver.
+
 config DRM_PTN3460
 	tristate "PTN3460 DP/LVDS bridge"
 	depends on DRM
diff --git a/drivers/gpu/drm/bridge/Makefile b/drivers/gpu/drm/bridge/Makefile
index eb80dbbb8365..65a12390844a 100644
--- a/drivers/gpu/drm/bridge/Makefile
+++ b/drivers/gpu/drm/bridge/Makefile
@@ -4,3 +4,4 @@ obj-$(CONFIG_DRM_PS8622) += ps8622.o
 obj-$(CONFIG_DRM_PTN3460) += ptn3460.o
 obj-$(CONFIG_DRM_DW_HDMI) += dw_hdmi.o
 obj-$(CONFIG_DRM_DW_HDMI_AHB_AUDIO) += dw_hdmi-ahb-audio.o
+obj-$(CONFIG_DRM_DW_HDMI_I2S_AUDIO) += dw_hdmi-i2s-audio.o
diff --git a/drivers/gpu/drm/bridge/dw_hdmi-i2s-audio.c b/drivers/gpu/drm/bridge/dw_hdmi-i2s-audio.c
new file mode 100644
index 000000000000..62d3d33642d0
--- /dev/null
+++ b/drivers/gpu/drm/bridge/dw_hdmi-i2s-audio.c
@@ -0,0 +1,398 @@
+/*
+ * DesignWare HDMI audio driver
+ *
+ * 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.
+ *
+ * Written and tested against the Designware HDMI Tx found in RK3288.
+ */
+#include <linux/io.h>
+#include <linux/init.h>
+#include <linux/kernel.h>
+#include <linux/module.h>
+#include <linux/device.h>
+#include <linux/moduleparam.h>
+
+#include <sound/pcm.h>
+#include <sound/soc.h>
+#include <sound/core.h>
+#include <sound/jack.h>
+#include <sound/initval.h>
+#include <sound/pcm_params.h>
+#include <drm/bridge/dw_hdmi.h>
+
+#include "dw_hdmi-audio.h"
+
+#define DRIVER_NAME "dw-hdmi-i2s-audio"
+
+enum {
+	AUDIO_CONF1_DATWIDTH_MSK = 0x1F,
+	AUDIO_CONF1_DATAMODE_MSK = 0xE0,
+	AUDIO_DAIFMT_IIS = 0x0,
+	AUDIO_DAIFMT_RIGHT_J = 0x20,
+	AUDIO_DAIFMT_LEFT_J = 0x40,
+	AUDIO_DAIFMT_BURST_1 = 0x60,
+	AUDIO_DAIFMT_BURST_2 = 0x80,
+	AUDIO_CONF0_INTERFACE_MSK = BIT(5),
+	AUDIO_INPUTTYPE_IIS = 0x20,
+	AUDIO_INPUTTYPE_SPDIF = 0x00,
+	AUDIO_CONF0_I2SINEN_MSK = 0x0F,
+	AUDIO_CHANNELNUM_2 = 0x01,
+	AUDIO_CHANNELNUM_4 = 0x03,
+	AUDIO_CHANNELNUM_6 = 0x07,
+	AUDIO_CHANNELNUM_8 = 0x0F,
+	HDMI_PHY_HPD = BIT(1),
+	HDMI_PHY_STAT0 = 0x3004,
+	HDMI_AUD_CONF0 = 0x3100,
+	HDMI_AUD_CONF1 = 0x3101,
+	HDMI_AUD_INPUTCLKFS = 0x3206,
+};
+
+struct dw_audio_fmt {
+	int input_type;
+	int chan_num;
+	int sample_rate;
+	int word_length;
+	int dai_fmt;
+};
+
+struct snd_dw_hdmi {
+	struct device *dev;
+	struct dw_hdmi_audio_data data;
+
+	bool is_jack_ready;
+	struct snd_soc_jack jack;
+
+	bool is_playback_status;
+	struct dw_audio_fmt fmt;
+};
+
+static void hdmi_writel(struct snd_dw_hdmi *dw, u8 val, int offset)
+{
+	writel(val, dw->data.base + (offset << 2));
+}
+
+static u8 hdmi_readl(struct snd_dw_hdmi *dw, int offset)
+{
+	return readl(dw->data.base + (offset << 2));
+}
+
+static void hdmi_modl(struct snd_dw_hdmi *dw, u8 data,
+		      u8 mask, unsigned reg)
+{
+	u8 val = hdmi_readl(dw, reg) & ~mask;
+
+	val |= data & mask;
+	hdmi_writel(dw, val, reg);
+}
+
+int snd_dw_hdmi_jack_detect(struct snd_dw_hdmi *dw)
+{
+	u8 jack_status;
+
+	if (!dw->is_jack_ready)
+		return -EINVAL;
+
+	jack_status = !!(hdmi_readl(dw, HDMI_PHY_STAT0) & HDMI_PHY_HPD) ?
+			SND_JACK_LINEOUT : 0;
+
+	snd_soc_jack_report(&dw->jack, jack_status, SND_JACK_LINEOUT);
+
+	return 0;
+}
+
+static irqreturn_t snd_dw_hdmi_irq(int irq, void *dev_id)
+{
+	struct snd_dw_hdmi *dw = dev_id;
+
+	snd_dw_hdmi_jack_detect(dw);
+
+	return IRQ_HANDLED;
+}
+
+static void dw_hdmi_audio_set_fmt(struct snd_dw_hdmi *dw,
+				  const struct dw_audio_fmt *fmt)
+{
+	hdmi_modl(dw, fmt->input_type, AUDIO_CONF0_INTERFACE_MSK,
+		  HDMI_AUD_CONF0);
+
+	hdmi_modl(dw, fmt->chan_num, AUDIO_CONF0_I2SINEN_MSK,
+		  HDMI_AUD_CONF0);
+
+	hdmi_modl(dw, fmt->word_length, AUDIO_CONF1_DATWIDTH_MSK,
+		  HDMI_AUD_CONF1);
+
+	hdmi_modl(dw, fmt->dai_fmt, AUDIO_CONF1_DATAMODE_MSK,
+		  HDMI_AUD_CONF1);
+
+	hdmi_writel(dw, 0, HDMI_AUD_INPUTCLKFS);
+
+	dw_hdmi_set_sample_rate(dw->data.hdmi, fmt->sample_rate);
+}
+
+static void dw_audio_set_fmt(struct snd_dw_hdmi *dw,
+			     const struct dw_audio_fmt *fmt)
+{
+	if (fmt)
+		dw->fmt = *fmt;
+	dw_hdmi_audio_set_fmt(dw, &dw->fmt);
+}
+
+static int snd_dw_hdmi_dai_startup(struct snd_pcm_substream *substream,
+				   struct snd_soc_dai *codec_dai)
+{
+	struct snd_dw_hdmi *dw = snd_soc_dai_get_drvdata(codec_dai);
+
+	dw->is_playback_status = true;
+	dw_hdmi_audio_enable(dw->data.hdmi);
+
+	return 0;
+}
+
+static int snd_dw_hdmi_dai_hw_params(struct snd_pcm_substream *substream,
+				     struct snd_pcm_hw_params *params,
+				     struct snd_soc_dai *codec_dai)
+{
+	struct snd_dw_hdmi *dw = snd_soc_dai_get_drvdata(codec_dai);
+	struct snd_soc_pcm_runtime *rtd = substream->private_data;
+	struct dw_audio_fmt dw_fmt;
+	unsigned int fmt, rate, chan, width;
+
+	fmt = rtd->dai_link->dai_fmt & SND_SOC_DAIFMT_FORMAT_MASK;
+	switch (fmt) {
+	case SND_SOC_DAIFMT_I2S:
+		dw_fmt.dai_fmt = AUDIO_DAIFMT_IIS;
+		break;
+	case SND_SOC_DAIFMT_LEFT_J:
+		dw_fmt.dai_fmt = AUDIO_DAIFMT_LEFT_J;
+		break;
+	case SND_SOC_DAIFMT_RIGHT_J:
+		dw_fmt.dai_fmt = AUDIO_DAIFMT_RIGHT_J;
+		break;
+	default:
+		dev_err(codec_dai->dev, "DAI format unsupported");
+		return -EINVAL;
+	}
+
+	width = params_width(params);
+	switch (width) {
+	case 16:
+	case 24:
+		dw_fmt.word_length = width;
+		break;
+	default:
+		dev_err(codec_dai->dev, "width[%d] not support!\n", width);
+		return -EINVAL;
+	}
+
+	chan = params_channels(params);
+	switch (chan) {
+	case 2:
+		dw_fmt.chan_num = AUDIO_CHANNELNUM_2;
+		break;
+	case 4:
+		dw_fmt.chan_num = AUDIO_CHANNELNUM_4;
+		break;
+	case 6:
+		dw_fmt.chan_num = AUDIO_CHANNELNUM_6;
+		break;
+	case 8:
+		dw_fmt.chan_num = AUDIO_CHANNELNUM_8;
+		break;
+	default:
+		dev_err(codec_dai->dev, "channel[%d] not support!\n", chan);
+		return -EINVAL;
+	}
+
+	rate = params_rate(params);
+	switch (rate) {
+	case 32000:
+	case 44100:
+	case 48000:
+	case 88200:
+	case 96000:
+	case 176400:
+	case 192000:
+		dw_fmt.sample_rate = rate;
+		break;
+	default:
+		dev_err(codec_dai->dev, "rate[%d] not support!\n", rate);
+		return -EINVAL;
+	}
+
+	dw_fmt.input_type = AUDIO_INPUTTYPE_IIS;
+
+	dw_audio_set_fmt(dw, &dw_fmt);
+
+	return 0;
+}
+
+static int snd_dw_hdmi_dai_trigger(struct snd_pcm_substream *substream,
+				   int cmd, struct snd_soc_dai *codec_dai)
+{
+	struct snd_dw_hdmi *dw = snd_soc_dai_get_drvdata(codec_dai);
+
+	switch (cmd) {
+	case SNDRV_PCM_TRIGGER_START:
+	case SNDRV_PCM_TRIGGER_RESUME:
+	case SNDRV_PCM_TRIGGER_PAUSE_RELEASE:
+		dw_hdmi_audio_enable(dw->data.hdmi);
+		break;
+	case SNDRV_PCM_TRIGGER_STOP:
+	case SNDRV_PCM_TRIGGER_SUSPEND:
+	case SNDRV_PCM_TRIGGER_PAUSE_PUSH:
+		dw_hdmi_audio_disable(dw->data.hdmi);
+		break;
+	default:
+		return -EINVAL;
+	}
+
+	return 0;
+}
+
+static void snd_dw_hdmi_dai_shutdown(struct snd_pcm_substream *substream,
+				     struct snd_soc_dai *codec_dai)
+{
+	struct snd_dw_hdmi *dw = snd_soc_dai_get_drvdata(codec_dai);
+
+	dw->is_playback_status = false;
+	dw_hdmi_audio_disable(dw->data.hdmi);
+}
+
+static int snd_dw_hdmi_audio_probe(struct snd_soc_codec *codec)
+{
+	struct snd_dw_hdmi *dw = snd_soc_codec_get_drvdata(codec);
+	int ret;
+
+	ret = snd_soc_jack_new(codec, "dw Jack", SND_JACK_LINEOUT,
+			       &dw->jack);
+	if (ret) {
+		dev_err(dw->dev, "jack new failed (%d)\n", ret);
+		dw->is_jack_ready = false;
+		return ret;
+	}
+
+	dw->is_jack_ready = true;
+
+	return snd_dw_hdmi_jack_detect(dw);
+}
+
+static const struct snd_soc_dapm_widget snd_dw_hdmi_audio_widgets[] = {
+	SND_SOC_DAPM_OUTPUT("TX"),
+};
+
+static const struct snd_soc_dapm_route snd_dw_hdmi_audio_routes[] = {
+	{ "TX", NULL, "Playback" },
+};
+
+static const struct snd_soc_dai_ops dw_hdmi_dai_ops = {
+	.startup = snd_dw_hdmi_dai_startup,
+	.hw_params = snd_dw_hdmi_dai_hw_params,
+	.trigger = snd_dw_hdmi_dai_trigger,
+	.shutdown = snd_dw_hdmi_dai_shutdown,
+};
+
+static struct snd_soc_dai_driver dw_hdmi_audio_dai = {
+	.name = "dw-hdmi-i2s-hifi",
+	.playback = {
+		.stream_name = "Playback",
+		.channels_min = 2,
+		.channels_max = 8,
+		.rates = SNDRV_PCM_RATE_32000 |
+			 SNDRV_PCM_RATE_44100 | SNDRV_PCM_RATE_48000 |
+			 SNDRV_PCM_RATE_88200 | SNDRV_PCM_RATE_96000 |
+			 SNDRV_PCM_RATE_176400 | SNDRV_PCM_RATE_192000,
+		.formats = SNDRV_PCM_FMTBIT_S16_LE | SNDRV_PCM_FMTBIT_S24_LE,
+	},
+	.ops = &dw_hdmi_dai_ops,
+};
+
+static const struct snd_soc_codec_driver dw_hdmi_audio = {
+	.probe = snd_dw_hdmi_audio_probe,
+	.dapm_widgets = snd_dw_hdmi_audio_widgets,
+	.num_dapm_widgets = ARRAY_SIZE(snd_dw_hdmi_audio_widgets),
+	.dapm_routes = snd_dw_hdmi_audio_routes,
+	.num_dapm_routes = ARRAY_SIZE(snd_dw_hdmi_audio_routes),
+};
+
+static int dw_hdmi_audio_probe(struct platform_device *pdev)
+{
+	struct dw_hdmi_audio_data *data = pdev->dev.platform_data;
+	struct snd_dw_hdmi *dw;
+	int ret;
+
+	dw = devm_kzalloc(&pdev->dev, sizeof(*dw), GFP_KERNEL);
+	if (!dw)
+		return -ENOMEM;
+
+	dw->data = *data;
+	dw->dev = &pdev->dev;
+	dw->is_jack_ready = false;
+	platform_set_drvdata(pdev, dw);
+
+	ret = request_irq(dw->data.irq, snd_dw_hdmi_irq, IRQF_SHARED,
+			  DRIVER_NAME, dw);
+	if (ret) {
+		dev_err(&pdev->dev, "request irq failed (%d)\n", ret);
+		return -EINVAL;
+	}
+
+	ret = snd_soc_register_codec(&pdev->dev, &dw_hdmi_audio,
+				     &dw_hdmi_audio_dai, 1);
+	if (ret) {
+		dev_err(&pdev->dev, "register codec failed (%d)\n", ret);
+		return -EINVAL;
+	}
+
+	dev_dbg(&pdev->dev, "dw audio init success.\n");
+
+	return 0;
+}
+
+static int dw_hdmi_audio_remove(struct platform_device *pdev)
+{
+	struct snd_dw_hdmi *dw = platform_get_drvdata(pdev);
+
+	snd_soc_unregister_codec(&pdev->dev);
+
+	return 0;
+}
+
+#ifdef CONFIG_PM
+static int dw_hdmi_audio_resume(struct device *dev)
+{
+	struct snd_dw_hdmi *dw = dev_get_drvdata(dev);
+
+	snd_dw_hdmi_jack_detect(dw);
+
+	if (dw->is_playback_status)
+		dw_hdmi_audio_set_fmt(dw, &dw->fmt);
+
+	return 0;
+}
+
+static int dw_hdmi_audio_suspend(struct device *dev)
+{
+	return 0;
+}
+#endif
+
+static const struct dev_pm_ops dw_hdmi_audio_pm = {
+	SET_SYSTEM_SLEEP_PM_OPS(dw_hdmi_audio_suspend, dw_hdmi_audio_resume)
+};
+
+static struct platform_driver dw_hdmi_audio_driver = {
+	.driver = {
+		.name = DRIVER_NAME,
+		.pm = &dw_hdmi_audio_pm,
+	},
+	.probe = dw_hdmi_audio_probe,
+	.remove = dw_hdmi_audio_remove,
+};
+module_platform_driver(dw_hdmi_audio_driver);
+
+MODULE_AUTHOR("Yakir Yang <ykk at rock-chips.com>");
+MODULE_DESCRIPTION("Synopsis DesignWare HDMI I2S ASoC Interface");
+MODULE_LICENSE("GPL v2");
+MODULE_ALIAS("platform:" DRIVER_NAME);
diff --git a/drivers/gpu/drm/bridge/dw_hdmi.c b/drivers/gpu/drm/bridge/dw_hdmi.c
index a4f9aecf1862..b08311be90d9 100644
--- a/drivers/gpu/drm/bridge/dw_hdmi.c
+++ b/drivers/gpu/drm/bridge/dw_hdmi.c
@@ -1793,19 +1793,25 @@ int dw_hdmi_bind(struct device *dev, struct device *master,
 
 	memset(&pdevinfo, 0, sizeof(pdevinfo));
 	pdevinfo.parent = dev;
-	pdevinfo.id = PLATFORM_DEVID_AUTO;
+
+	audio.phys = iores->start;
+	audio.base = hdmi->regs;
+	audio.irq = irq;
+	audio.hdmi = hdmi;
+	audio.eld = hdmi->connector.eld;
+
+	pdevinfo.data = &audio;
+	pdevinfo.size_data = sizeof(audio);
 
 	if (hdmi_readb(hdmi, HDMI_CONFIG1_ID) & HDMI_CONFIG1_AHB) {
-		audio.phys = iores->start;
-		audio.base = hdmi->regs;
-		audio.irq = irq;
-		audio.hdmi = hdmi;
-		audio.eld = hdmi->connector.eld;
+		pdevinfo.name = "dw-hdmi-i2s-audio";
+		pdevinfo.id = PLATFORM_DEVID_AUTO;
+		pdevinfo.dma_mask = DMA_BIT_MASK(32);
+		hdmi->audio = platform_device_register_full(&pdevinfo);
 
+	} else if (hdmi_readb(hdmi, HDMI_CONFIG0_ID) & HDMI_CONFIG0_I2S) {
 		pdevinfo.name = "dw-hdmi-ahb-audio";
-		pdevinfo.data = &audio;
-		pdevinfo.size_data = sizeof(audio);
-		pdevinfo.dma_mask = DMA_BIT_MASK(32);
+		pdevinfo.id = PLATFORM_DEVID_NONE;
 		hdmi->audio = platform_device_register_full(&pdevinfo);
 	}
 
diff --git a/drivers/gpu/drm/bridge/dw_hdmi.h b/drivers/gpu/drm/bridge/dw_hdmi.h
index 78e54e813212..9c2237753f0a 100644
--- a/drivers/gpu/drm/bridge/dw_hdmi.h
+++ b/drivers/gpu/drm/bridge/dw_hdmi.h
@@ -545,6 +545,9 @@
 #define HDMI_I2CM_FS_SCL_LCNT_0_ADDR            0x7E12
 
 enum {
+/* CONFIG0_ID field values */
+	HDMI_CONFIG0_I2S = 0x01,
+
 /* CONFIG1_ID field values */
 	HDMI_CONFIG1_AHB = 0x01,
 
-- 
2.1.0



From rmk+kernel at arm.linux.org.uk  Sat Aug  8 09:10:42 2015
From: rmk+kernel at arm.linux.org.uk (Russell King)
Date: Sat, 08 Aug 2015 17:10:42 +0100
Subject: [PATCH 8/9] drm: bridge/dw_hdmi: replace CTS calculation for the ACR
In-Reply-To: <20150808160936.GN7557@n2100.arm.linux.org.uk>
References: <20150808160936.GN7557@n2100.arm.linux.org.uk>
Message-ID: <E1ZO6hm-0003Ni-E0@rmk-PC.arm.linux.org.uk>

Given the TDMS clock, audio sample rate, and the N parameter, we can
calculate the CTS value for the audio clock regenerator (ACR) using the
following calculation given in the HDMI specification:

	CTS = ftdms * N / (128 * fs)

The specification says that the CTS value is an average value, which is
true if the source hardware measures it.  Where source hardware needs it
to be programmed, it is particularly difficult to alternate it between
two values correctly to ensure that we achieve a correct "average"
fractional value at the sink.

Also, there's the problem that our "ftdms" is not a fully accurate
value; it is rounded to a kHz value.  This introduces an unnecessary
(and harmless) fractional value into the above equation for combinations
like 148.5MHz/1.001 for 44100Hz - we still calculate the correct CTS
value.

Signed-off-by: Russell King <rmk+kernel at arm.linux.org.uk>
---
 drivers/gpu/drm/bridge/dw_hdmi.c | 92 +++++++---------------------------------
 1 file changed, 16 insertions(+), 76 deletions(-)

diff --git a/drivers/gpu/drm/bridge/dw_hdmi.c b/drivers/gpu/drm/bridge/dw_hdmi.c
index 60487bff48e3..a4f9aecf1862 100644
--- a/drivers/gpu/drm/bridge/dw_hdmi.c
+++ b/drivers/gpu/drm/bridge/dw_hdmi.c
@@ -272,89 +272,29 @@ static unsigned int hdmi_compute_n(unsigned int freq, unsigned long pixel_clk)
 	return n;
 }
 
-static unsigned int hdmi_compute_cts(unsigned int freq, unsigned long pixel_clk)
-{
-	unsigned int cts = 0;
-
-	pr_debug("%s: freq: %d pixel_clk: %ld\n", __func__, freq, pixel_clk);
-
-	switch (freq) {
-	case 32000:
-		if (pixel_clk == 297000000) {
-			cts = 222750;
-			break;
-		}
-	case 48000:
-	case 96000:
-	case 192000:
-		switch (pixel_clk) {
-		case 25200000:
-		case 27000000:
-		case 54000000:
-		case 74250000:
-		case 148500000:
-			cts = pixel_clk / 1000;
-			break;
-		case 297000000:
-			cts = 247500;
-			break;
-		/*
-		 * All other TMDS clocks are not supported by
-		 * DWC_hdmi_tx. The TMDS clocks divided or
-		 * multiplied by 1,001 coefficients are not
-		 * supported.
-		 */
-		default:
-			break;
-		}
-		break;
-	case 44100:
-	case 88200:
-	case 176400:
-		switch (pixel_clk) {
-		case 25200000:
-			cts = 28000;
-			break;
-		case 27000000:
-			cts = 30000;
-			break;
-		case 54000000:
-			cts = 60000;
-			break;
-		case 74250000:
-			cts = 82500;
-			break;
-		case 148500000:
-			cts = 165000;
-			break;
-		case 297000000:
-			cts = 247500;
-			break;
-		default:
-			break;
-		}
-		break;
-	default:
-		break;
-	}
-	return cts;
-}
-
 static void hdmi_set_clk_regenerator(struct dw_hdmi *hdmi,
 	unsigned long pixel_clk, unsigned int sample_rate)
 {
+	unsigned long ftdms = pixel_clk;
 	unsigned int n, cts;
+	u64 tmp;
 
 	n = hdmi_compute_n(sample_rate, pixel_clk);
-	cts = hdmi_compute_cts(sample_rate, pixel_clk);
-	if (!cts) {
-		dev_err(hdmi->dev,
-			"%s: pixel clock/sample rate not supported: %luMHz / %ukHz\n",
-			__func__, pixel_clk, sample_rate);
-	}
 
-	dev_dbg(hdmi->dev, "%s: samplerate=%ukHz pixelclk=%luMHz N=%d cts=%d\n",
-		__func__, sample_rate, pixel_clk, n, cts);
+	/*
+	 * Compute the CTS value from the N value.  Note that CTS and N
+	 * can be up to 20 bits in total, so we need 64-bit math.  Also
+	 * note that our TDMS clock is not fully accurate; it is accurate
+	 * to kHz.  This can introduce an unnecessary remainder in the
+	 * calculation below, so we don't try to warn about that.
+	 */
+	tmp = (u64)ftdms * n;
+	do_div(tmp, 128 * sample_rate);
+	cts = tmp;
+
+	dev_dbg(hdmi->dev, "%s: fs=%uHz ftdms=%lu.%03luMHz N=%d cts=%d\n",
+		__func__, sample_rate, ftdms / 1000000, (ftdms / 1000) % 1000,
+		n, cts);
 
 	spin_lock_irq(&hdmi->audio_lock);
 	hdmi->audio_n = n;
-- 
2.1.0



From rmk+kernel at arm.linux.org.uk  Sat Aug  8 09:10:37 2015
From: rmk+kernel at arm.linux.org.uk (Russell King)
Date: Sat, 08 Aug 2015 17:10:37 +0100
Subject: [PATCH 7/9] drm: bridge/dw_hdmi: remove ratio support from ACR code
In-Reply-To: <20150808160936.GN7557@n2100.arm.linux.org.uk>
References: <20150808160936.GN7557@n2100.arm.linux.org.uk>
Message-ID: <E1ZO6hh-0003Nc-A7@rmk-PC.arm.linux.org.uk>

We never set the ratio for CTS/N calculation for the audio clock
regenerator (ACR) to anything but 100, so this adds pointless
complexity.  Should we support pixel repetition, we should update the
CTS/N calculation code to use those parameters or the actual TMDS clock
rate instead of a ratio.

Signed-off-by: Russell King <rmk+kernel at arm.linux.org.uk>
---
 drivers/gpu/drm/bridge/dw_hdmi.c | 44 ++++++++++++++++------------------------
 1 file changed, 18 insertions(+), 26 deletions(-)

diff --git a/drivers/gpu/drm/bridge/dw_hdmi.c b/drivers/gpu/drm/bridge/dw_hdmi.c
index 5576cd7d7abb..60487bff48e3 100644
--- a/drivers/gpu/drm/bridge/dw_hdmi.c
+++ b/drivers/gpu/drm/bridge/dw_hdmi.c
@@ -140,7 +140,6 @@ struct dw_hdmi {
 	unsigned int audio_cts;
 	unsigned int audio_n;
 	bool audio_enable;
-	int ratio;
 
 	void (*write)(struct dw_hdmi *hdmi, u8 val, int offset);
 	u8 (*read)(struct dw_hdmi *hdmi, int offset);
@@ -217,8 +216,7 @@ static void hdmi_set_cts_n(struct dw_hdmi *hdmi, unsigned int cts,
 	hdmi_writeb(hdmi, n & 0xff, HDMI_AUD_N1);
 }
 
-static unsigned int hdmi_compute_n(unsigned int freq, unsigned long pixel_clk,
-				   unsigned int ratio)
+static unsigned int hdmi_compute_n(unsigned int freq, unsigned long pixel_clk)
 {
 	unsigned int n = (128 * freq) / 1000;
 	unsigned int mult = 1;
@@ -231,9 +229,9 @@ static unsigned int hdmi_compute_n(unsigned int freq, unsigned long pixel_clk,
 	switch (freq) {
 	case 32000:
 		if (pixel_clk == 25175000)
-			n = (ratio == 150) ? 9152 : 4576;
+			n = 4576;
 		else if (pixel_clk == 27027000)
-			n = (ratio == 150) ? 8192 : 4096;
+			n = 4096;
 		else if (pixel_clk == 74176000 || pixel_clk == 148352000)
 			n = 11648;
 		else
@@ -247,7 +245,7 @@ static unsigned int hdmi_compute_n(unsigned int freq, unsigned long pixel_clk,
 		else if (pixel_clk == 74176000)
 			n = 17836;
 		else if (pixel_clk == 148352000)
-			n = (ratio == 150) ? 17836 : 8918;
+			n = 8918;
 		else
 			n = 6272;
 		n *= mult;
@@ -255,13 +253,13 @@ static unsigned int hdmi_compute_n(unsigned int freq, unsigned long pixel_clk,
 
 	case 48000:
 		if (pixel_clk == 25175000)
-			n = (ratio == 150) ? 9152 : 6864;
+			n = 6864;
 		else if (pixel_clk == 27027000)
-			n = (ratio == 150) ? 8192 : 6144;
+			n = 6144;
 		else if (pixel_clk == 74176000)
 			n = 11648;
 		else if (pixel_clk == 148352000)
-			n = (ratio == 150) ? 11648 : 5824;
+			n = 5824;
 		else
 			n = 6144;
 		n *= mult;
@@ -274,13 +272,11 @@ static unsigned int hdmi_compute_n(unsigned int freq, unsigned long pixel_clk,
 	return n;
 }
 
-static unsigned int hdmi_compute_cts(unsigned int freq, unsigned long pixel_clk,
-				     unsigned int ratio)
+static unsigned int hdmi_compute_cts(unsigned int freq, unsigned long pixel_clk)
 {
 	unsigned int cts = 0;
 
-	pr_debug("%s: freq: %d pixel_clk: %ld ratio: %d\n", __func__, freq,
-		 pixel_clk, ratio);
+	pr_debug("%s: freq: %d pixel_clk: %ld\n", __func__, freq, pixel_clk);
 
 	switch (freq) {
 	case 32000:
@@ -341,26 +337,24 @@ static unsigned int hdmi_compute_cts(unsigned int freq, unsigned long pixel_clk,
 	default:
 		break;
 	}
-	if (ratio == 100)
-		return cts;
-	return (cts * ratio) / 100;
+	return cts;
 }
 
 static void hdmi_set_clk_regenerator(struct dw_hdmi *hdmi,
-	unsigned long pixel_clk, unsigned int sample_rate, unsigned int ratio)
+	unsigned long pixel_clk, unsigned int sample_rate)
 {
 	unsigned int n, cts;
 
-	n = hdmi_compute_n(sample_rate, pixel_clk, ratio);
-	cts = hdmi_compute_cts(sample_rate, pixel_clk, ratio);
+	n = hdmi_compute_n(sample_rate, pixel_clk);
+	cts = hdmi_compute_cts(sample_rate, pixel_clk);
 	if (!cts) {
 		dev_err(hdmi->dev,
 			"%s: pixel clock/sample rate not supported: %luMHz / %ukHz\n",
 			__func__, pixel_clk, sample_rate);
 	}
 
-	dev_dbg(hdmi->dev, "%s: samplerate=%ukHz ratio=%d pixelclk=%luMHz N=%d cts=%d\n",
-		__func__, sample_rate, ratio, pixel_clk, n, cts);
+	dev_dbg(hdmi->dev, "%s: samplerate=%ukHz pixelclk=%luMHz N=%d cts=%d\n",
+		__func__, sample_rate, pixel_clk, n, cts);
 
 	spin_lock_irq(&hdmi->audio_lock);
 	hdmi->audio_n = n;
@@ -372,8 +366,7 @@ static void hdmi_set_clk_regenerator(struct dw_hdmi *hdmi,
 static void hdmi_init_clk_regenerator(struct dw_hdmi *hdmi)
 {
 	mutex_lock(&hdmi->audio_mutex);
-	hdmi_set_clk_regenerator(hdmi, 74250000, hdmi->sample_rate,
-				 hdmi->ratio);
+	hdmi_set_clk_regenerator(hdmi, 74250000, hdmi->sample_rate);
 	mutex_unlock(&hdmi->audio_mutex);
 }
 
@@ -381,7 +374,7 @@ static void hdmi_clk_regenerator_update_pixel_clock(struct dw_hdmi *hdmi)
 {
 	mutex_lock(&hdmi->audio_mutex);
 	hdmi_set_clk_regenerator(hdmi, hdmi->hdmi_data.video_mode.mpixelclock,
-				 hdmi->sample_rate, hdmi->ratio);
+				 hdmi->sample_rate);
 	mutex_unlock(&hdmi->audio_mutex);
 }
 
@@ -390,7 +383,7 @@ void dw_hdmi_set_sample_rate(struct dw_hdmi *hdmi, unsigned int rate)
 	mutex_lock(&hdmi->audio_mutex);
 	hdmi->sample_rate = rate;
 	hdmi_set_clk_regenerator(hdmi, hdmi->hdmi_data.video_mode.mpixelclock,
-				 hdmi->sample_rate, hdmi->ratio);
+				 hdmi->sample_rate);
 	mutex_unlock(&hdmi->audio_mutex);
 }
 EXPORT_SYMBOL_GPL(dw_hdmi_set_sample_rate);
@@ -1746,7 +1739,6 @@ int dw_hdmi_bind(struct device *dev, struct device *master,
 	hdmi->dev = dev;
 	hdmi->dev_type = plat_data->dev_type;
 	hdmi->sample_rate = 48000;
-	hdmi->ratio = 100;
 	hdmi->encoder = encoder;
 	hdmi->disabled = true;
 	hdmi->rxsense = true;
-- 
2.1.0



From rmk+kernel at arm.linux.org.uk  Sat Aug  8 09:10:11 2015
From: rmk+kernel at arm.linux.org.uk (Russell King)
Date: Sat, 08 Aug 2015 17:10:11 +0100
Subject: [PATCH 2/9] drm: bridge/dw_hdmi-ahb-audio: parse ELD from HDMI driver
In-Reply-To: <20150808160936.GN7557@n2100.arm.linux.org.uk>
References: <20150808160936.GN7557@n2100.arm.linux.org.uk>
Message-ID: <E1ZO6hH-0003N1-IM@rmk-PC.arm.linux.org.uk>

Parse the ELD (EDID like data) stored from the HDMI driver to restrict
the sample rates and channels which are available to ALSA.  This causes
the ALSA device to reflect the capabilities of the overall audio path,
not just what is supported at the HDMI source interface level.

Signed-off-by: Russell King <rmk+kernel at arm.linux.org.uk>
---
 drivers/gpu/drm/bridge/Kconfig             | 1 +
 drivers/gpu/drm/bridge/dw_hdmi-ahb-audio.c | 6 ++++++
 drivers/gpu/drm/bridge/dw_hdmi-audio.h     | 1 +
 drivers/gpu/drm/bridge/dw_hdmi.c           | 3 +++
 4 files changed, 11 insertions(+)

diff --git a/drivers/gpu/drm/bridge/Kconfig b/drivers/gpu/drm/bridge/Kconfig
index 56ed35fe0734..204861bfb867 100644
--- a/drivers/gpu/drm/bridge/Kconfig
+++ b/drivers/gpu/drm/bridge/Kconfig
@@ -7,6 +7,7 @@ config DRM_DW_HDMI_AHB_AUDIO
 	tristate "Synopsis Designware AHB Audio interface"
 	depends on DRM_DW_HDMI && SND
 	select SND_PCM
+	select SND_PCM_ELD
 	select SND_PCM_IEC958
 	help
 	  Support the AHB Audio interface which is part of the Synopsis
diff --git a/drivers/gpu/drm/bridge/dw_hdmi-ahb-audio.c b/drivers/gpu/drm/bridge/dw_hdmi-ahb-audio.c
index 22bbbc5c2393..125b81306254 100644
--- a/drivers/gpu/drm/bridge/dw_hdmi-ahb-audio.c
+++ b/drivers/gpu/drm/bridge/dw_hdmi-ahb-audio.c
@@ -12,11 +12,13 @@
 #include <linux/module.h>
 #include <linux/platform_device.h>
 #include <drm/bridge/dw_hdmi.h>
+#include <drm/drm_edid.h>
 
 #include <sound/asoundef.h>
 #include <sound/core.h>
 #include <sound/initval.h>
 #include <sound/pcm.h>
+#include <sound/pcm_drm_eld.h>
 #include <sound/pcm_iec958.h>
 
 #include "dw_hdmi-audio.h"
@@ -284,6 +286,10 @@ static int dw_hdmi_open(struct snd_pcm_substream *substream)
 
 	runtime->hw = dw_hdmi_hw;
 
+	ret = snd_pcm_hw_constraint_eld(runtime, dw->data.eld);
+	if (ret < 0)
+		return ret;
+
 	ret = snd_pcm_limit_hw_rates(runtime);
 	if (ret < 0)
 		return ret;
diff --git a/drivers/gpu/drm/bridge/dw_hdmi-audio.h b/drivers/gpu/drm/bridge/dw_hdmi-audio.h
index 1e840118d90a..91f631beecc7 100644
--- a/drivers/gpu/drm/bridge/dw_hdmi-audio.h
+++ b/drivers/gpu/drm/bridge/dw_hdmi-audio.h
@@ -8,6 +8,7 @@ struct dw_hdmi_audio_data {
 	void __iomem *base;
 	int irq;
 	struct dw_hdmi *hdmi;
+	u8 *eld;
 };
 
 #endif
diff --git a/drivers/gpu/drm/bridge/dw_hdmi.c b/drivers/gpu/drm/bridge/dw_hdmi.c
index b65464789fbd..a8b243278774 100644
--- a/drivers/gpu/drm/bridge/dw_hdmi.c
+++ b/drivers/gpu/drm/bridge/dw_hdmi.c
@@ -1533,6 +1533,8 @@ static int dw_hdmi_connector_get_modes(struct drm_connector *connector)
 		hdmi->sink_has_audio = drm_detect_monitor_audio(edid);
 		drm_mode_connector_update_edid_property(connector, edid);
 		ret = drm_add_edid_modes(connector, edid);
+		/* Store the ELD */
+		drm_edid_to_eld(connector, edid);
 		kfree(edid);
 	} else {
 		dev_dbg(hdmi->dev, "failed to get edid\n");
@@ -1873,6 +1875,7 @@ int dw_hdmi_bind(struct device *dev, struct device *master,
 		audio.base = hdmi->regs;
 		audio.irq = irq;
 		audio.hdmi = hdmi;
+		audio.eld = hdmi->connector.eld;
 
 		pdevinfo.name = "dw-hdmi-ahb-audio";
 		pdevinfo.data = &audio;
-- 
2.1.0



From dhdang at apm.com  Sat Aug  8 09:45:33 2015
From: dhdang at apm.com (Duc Dang)
Date: Sat, 8 Aug 2015 09:45:33 -0700
Subject: [PATCH v4 2/2] usb: Add support for ACPI identification to
 xhci-platform
In-Reply-To: <20150808153710.GA11851@kroah.com>
References: <CADaLNDkeOP+gBw0qdSDha551w+w+q4ry9-EevDw5giyiQGdnqA@mail.gmail.com>
 <5e302acb5b03c9bf61ecfb9b5b37e8b3b520bed9.1438994178.git.dhdang@apm.com>
 <20150808012905.GA10407@kroah.com>
 <CABxcv=nAxKqt06js1epALu8Y_61bZ+XeRwy_N=oQUTeRVCh6-w@mail.gmail.com>
 <20150808153710.GA11851@kroah.com>
Message-ID: <CADaLND=nvwjUO41FXZds7YQMbyDFmKGwnuaj_ThdY_s1cNzLJw@mail.gmail.com>

On Sat, Aug 8, 2015 at 8:37 AM, Greg KH <gregkh at linuxfoundation.org> wrote:
> On Sat, Aug 08, 2015 at 07:43:40AM +0200, Javier Martinez Canillas wrote:
>> Hello Greg,
>>
>> On Sat, Aug 8, 2015 at 3:29 AM, Greg KH <gregkh at linuxfoundation.org> wrote:
>> > On Fri, Aug 07, 2015 at 06:03:36PM -0700, Duc Dang wrote:
>> >> Provide the methods to let ACPI identify the need to use
>> >> xhci-platform. Change the Kconfig files so the
>> >> xhci-plat.o file is selectable during kernel config.
>> >>
>> >> This has been tested on an ARM64 machine with platform XHCI, an
>> >> x86_64 machine with XHCI, and an x86_64 machine without XHCI.
>> >> There were no regressions or error messages on the machines
>> >> without platform XHCI.
>> >>
>> >> [dhdang: regenerate the patch over 4.2-rc5]
>> >> Signed-off-by: Mark Langsdorf <mlangsdo at redhat.com>
>> >> Signed-off-by: Duc Dang <dhdang at apm.com>
>> >>
>> >> ---
>> >> Changes from v3:
>> >>       Regenerate the patch over 4.2-rc5
>> >>       No code change
>> >>
>> >> Changes from v2
>> >>       Replaced tristate with a boolean as the driver doesn't
>> >>               compile as a module
>> >>       Correct --help-- to ---help---
>> >>
>> >> Changes from v1
>> >>       Renamed from "add support for APM X-Gene to xhci-platform"
>> >>       Removed changes to arm64/Kconfig
>> >>       Made CONFIG_USB_XHCI_PLATFORM a user selectable config option
>> >>
>> >>  drivers/usb/host/Kconfig     |  7 ++++++-
>> >>  drivers/usb/host/xhci-plat.c | 11 +++++++++++
>> >>  2 files changed, 17 insertions(+), 1 deletion(-)
>> >>
>> >> diff --git a/drivers/usb/host/Kconfig b/drivers/usb/host/Kconfig
>> >> index 8afc3c1..96231ee 100644
>> >> --- a/drivers/usb/host/Kconfig
>> >> +++ b/drivers/usb/host/Kconfig
>> >> @@ -32,7 +32,12 @@ config USB_XHCI_PCI
>> >>         default y
>> >>
>> >>  config USB_XHCI_PLATFORM
>> >> -     tristate
>> >> +     tristate "xHCI platform driver support"
>> >> +     ---help---
>> >> +       Say 'Y' to enable the support for the xHCI host controller
>> >> +       as a platform device. Many ARM SoCs provide USB this way.
>> >> +
>> >> +       If unsure, say 'Y'.
>> >>
>> >>  config USB_XHCI_MVEBU
>> >>       tristate "xHCI support for Marvell Armada 375/38x"
>> >> diff --git a/drivers/usb/host/xhci-plat.c b/drivers/usb/host/xhci-plat.c
>> >> index 5d03f8b..14b40d2 100644
>> >> --- a/drivers/usb/host/xhci-plat.c
>> >> +++ b/drivers/usb/host/xhci-plat.c
>> >> @@ -19,6 +19,7 @@
>> >>  #include <linux/usb/phy.h>
>> >>  #include <linux/slab.h>
>> >>  #include <linux/usb/xhci_pdriver.h>
>> >> +#include <linux/acpi.h>
>> >>
>> >>  #include "xhci.h"
>> >>  #include "xhci-mvebu.h"
>> >> @@ -262,6 +263,15 @@ static const struct of_device_id usb_xhci_of_match[] = {
>> >>  MODULE_DEVICE_TABLE(of, usb_xhci_of_match);
>> >>  #endif
>> >>
>> >> +#ifdef CONFIG_ACPI
>> >
>> > You shoudn't need this #ifdef, right?
>> >
>>
>> Why it is not needed?
>
> Why is it needed?
>
>> The driver does .acpi_match_table = ACPI_PTR(usb_xhci_acpi_match) and
>> ACPI_PTR() is NULL if CONFIG_ACPI is not enabled. Which can happen
>> AFAIU since the driver also supports OF. So without the #ifdef guards,
>> .acpi_match_table = NULL and the struct acpi_device_id
>> usb_xhci_acpi_match[] will be built but not used.
>
> Which is just fine, right?
>
>> Or am I missing something?
>
> Don't put #ifdef in .c files if at all possible is the kernel style
> rules.

I tested booting with both device tree and ACPI with the new code that
has #ifdef CONFIG_ACPI removed and USB works fine with my X-Gene Arm64
platform.

>
> thanks,
>
> greg k-h



-- 
Regards,
Duc Dang.


From wsa at the-dreams.de  Sat Aug  8 09:49:06 2015
From: wsa at the-dreams.de (Wolfram Sang)
Date: Sat, 8 Aug 2015 18:49:06 +0200
Subject: [PATCH 0/8] misc: remove boundary checks from bin attr users
In-Reply-To: <55C5FB6A.5010300@mleia.com>
References: <1437945502-27944-1-git-send-email-vz@mleia.com>
 <20150807161055.GD25357@katana> <55C4D9B2.3000708@mleia.com>
 <20150807223456.GA1527@katana> <55C5FB6A.5010300@mleia.com>
Message-ID: <20150808164906.GA1528@katana>

On Sat, Aug 08, 2015 at 03:51:54PM +0300, Vladimir Zapolskiy wrote:
> Hi Wolfram,
> 
> On 08.08.2015 01:34, Wolfram Sang wrote:
> > 
> >> if we're talking about this particular series, you should have them in
> >> your mailbox, since you have them applied in wsa/i2c/for-next:
> > 
> > Those are already in linus tree. I mean all drivers which use struct
> > i2c_driver. Or do you prefer they go via Greg? I am fine with both.
> > 
> 
> I think you may find most of the changes applied by Greg into
> misc/char-misc-next branch.

Great, thanks for the heads up!

-------------- next part --------------
A non-text attachment was scrubbed...
Name: signature.asc
Type: application/pgp-signature
Size: 819 bytes
Desc: Digital signature
URL: <http://lists.infradead.org/pipermail/linux-arm-kernel/attachments/20150808/e80cfbcb/attachment.sig>

From robert.jarzmik at free.fr  Sat Aug  8 09:56:34 2015
From: robert.jarzmik at free.fr (Robert Jarzmik)
Date: Sat, 08 Aug 2015 18:56:34 +0200
Subject: [BUG, RFC] Different bitfields in documentation and driver
In-Reply-To: <55C503A7.6020304@tul.cz> (Petr Cvek's message of "Fri, 07 Aug
 2015 21:14:47 +0200")
References: <55C503A7.6020304@tul.cz>
Message-ID: <87zj21k9bx.fsf@belgarion.home>

Petr Cvek <petr.cvek at tul.cz> writes:

> Hello,
> It seems that PXA2xx framebuffer has switched bitfields in nonstd definition (when using overlay).
>
> This:
>
> 	http://lxr.free-electrons.com/source/drivers/video/fbdev/pxafb.h#L80
>
> versus this:
>
> 	http://lxr.free-electrons.com/source/Documentation/fb/pxafb.txt#L128
>
> Should be this changed in documentation or in driver? I was able to find only
> one use (in form of little outdated mplayer patch) and it fills both bitfields
> with zero (so potential change in driver will not break it).
I'd rather go for documentation. Not only the driver's way looks more pretty to
me, but it also guarantees compatibility from the kernel side.

> P.S. Lack of overlay2's use is probably caused by errata "E24: LCD: Enabling
> Overlay 2 for YUV420 hangs LCD controller.", which is not workarounded in this
> driver. It should be mentioned in documentation and/or code, because the only
> way to start the LCD again is a full PXA SoC reset.
Ok, do you know if this this true for all pxa variants and steppings or is this
for only a subset of them ?

Cheers.

-- 
Robert


From maitysanchayan at gmail.com  Sat Aug  8 10:22:00 2015
From: maitysanchayan at gmail.com (maitysanchayan at gmail.com)
Date: Sat, 8 Aug 2015 22:52:00 +0530
Subject: [PATCH v2] iio: adc: vf610: Add IIO buffer support for Vybrid ADC
In-Reply-To: <55C6125B.1060103@kernel.org>
References: <cover.1438775572.git.maitysanchayan@gmail.com>
 <1bb1f290da601bbda41875a92ba6e983b423d7b0.1438775572.git.maitysanchayan@gmail.com>
 <55C6125B.1060103@kernel.org>
Message-ID: <20150808172200.GA2758@Sanchayan-Arch>

Hello Jonathan,

On 15-08-08 15:29:47, Jonathan Cameron wrote:
> On 05/08/15 13:10, Sanchayan Maity wrote:
> > This patch adds support for IIO buffer to the Vybrid ADC driver.
> > IIO triggered buffer infrastructure along with iio sysfs trigger
> > is used to leverage continuous sampling support provided by the
> > ADC block.
> Looking good.  Just a couple more bits and pieces inline from me.
> One or two of which aren't corrected from Peter's review of v1.
> 
> I will want Fugang Dong's ack / review tag on the final version
> before applying it however.

Sure.

> This driver is some distance form my area of expertise!

I doubt :).

> 
> Jonathan
> > 
> > Signed-off-by: Sanchayan Maity <maitysanchayan at gmail.com>
> > ---
> >  drivers/iio/adc/Kconfig     |   4 ++
> >  drivers/iio/adc/vf610_adc.c | 107 +++++++++++++++++++++++++++++++++++++++++---
> >  2 files changed, 105 insertions(+), 6 deletions(-)
> > 
> > diff --git a/drivers/iio/adc/Kconfig b/drivers/iio/adc/Kconfig
> > index 7c55658..4661241 100644
> > --- a/drivers/iio/adc/Kconfig
> > +++ b/drivers/iio/adc/Kconfig
> > @@ -337,6 +337,10 @@ config TWL6030_GPADC
> >  config VF610_ADC
> >  	tristate "Freescale vf610 ADC driver"
> >  	depends on OF
> > +	select IIO_BUFFER
> > +	select IIO_TRIGGER
> > +	select IIO_SYSFS_TRIGGER
> Unless I missed something there is no dependency on this particular
> trigger (it just happens to be the one you've been testing with I guess).
> Could be driven from a hardware trigger belonging to another device for
> example.

Yes right in a way. Right now we do not provide or there is no provision
for hardware triggers. On the Vybrid, the Peripheral Delay Block (PDB)
does the job of providing support for software and hardware triggers. PDB
support is not yet there in Linux however. 

There is also the question of where the Vybrid PDB driver would belong
to? In the TRM it is put in the timers but the kernel has no generic timer
framework that I am aware of. After some internal reviews we decided to
do a platform driver which provided functions ADC driver could called into.

I have a patchset ready which provides trigger support using PDB however
configuring the PDB properly has proven to be tricky. While it works but
not reliably with multiple channels and it would be a while before I get
that working and post that patchset. So kind of stalled there and just
because of two registers which need to be written with the correct value
:). For what it's worth if someone comes across this, some discussion
here [1] along with patches. (Note however those are a bit old patches
not exactly my new work).

Sorry for digressing from the topic. Anyways so the idea was to provide
sysfs triggers as default for using this continuous sampling. Later the
driver may provide additional triggers. So for now I added the sysfs
trigger as a select option so that a user won't have to recompile the
kernel for using the buffers with continuous sampling.

> 
> > +	select IIO_TRIGGERED_BUFFER
> >  	help
> >  	  Say yes here to support for Vybrid board analog-to-digital converter.
> >  	  Since the IP is used for i.MX6SLX, the driver also support i.MX6SLX.
> > diff --git a/drivers/iio/adc/vf610_adc.c b/drivers/iio/adc/vf610_adc.c
> > index 23b8fb9..97cb2ed 100644
> > --- a/drivers/iio/adc/vf610_adc.c
> > +++ b/drivers/iio/adc/vf610_adc.c
> > @@ -34,8 +34,11 @@
> >  #include <linux/err.h>
> >  
> >  #include <linux/iio/iio.h>
> > +#include <linux/iio/buffer.h>
> >  #include <linux/iio/sysfs.h>
> > -#include <linux/iio/driver.h>
> > +#include <linux/iio/trigger.h>
> > +#include <linux/iio/trigger_consumer.h>
> > +#include <linux/iio/triggered_buffer.h>
> >  
> >  /* This will be the driver name the kernel reports */
> >  #define DRIVER_NAME "vf610-adc"
> > @@ -170,6 +173,7 @@ struct vf610_adc {
> >  	u32 sample_freq_avail[5];
> >  
> >  	struct completion completion;
> > +	u16 buffer[2];
> Note the requirements on the buffer provided to
> iio_push_to_buffers_with_timestamp
> Needs to be u16 buffer[8] to allow for the aligned 64bit (4 word) timestamp.
> 
> Peter pointed this out in his follow up email and you said you'd implement
> it.. Guessing this got lost somewhere.

No, I meant to implement what Peter recommended but I guess I did not completely
grasp what he intended. Sorry about that. Will fix this and ask further if in
more doubts.

> 
> 
> >  };
> >  
> >  static const u32 vf610_hw_avgs[] = { 1, 4, 8, 16, 32 };
> > @@ -505,12 +509,22 @@ static const struct iio_chan_spec_ext_info vf610_ext_info[] = {
> >  	.info_mask_shared_by_type = BIT(IIO_CHAN_INFO_SCALE) |	\
> >  				BIT(IIO_CHAN_INFO_SAMP_FREQ),	\
> >  	.ext_info = vf610_ext_info,				\
> > +	.address = (_idx),				\
> > +	.scan_index = (_idx),			\
> > +	.scan_type.sign = 'u',			\
> > +	.scan_type.realbits = 12,		\
> > +	.scan_type.storagebits = 16,	\
> >  }
> >  
> >  #define VF610_ADC_TEMPERATURE_CHAN(_idx, _chan_type) {	\
> >  	.type = (_chan_type),	\
> >  	.channel = (_idx),		\
> >  	.info_mask_separate = BIT(IIO_CHAN_INFO_PROCESSED),	\
> > +	.address = (_idx),						\
> > +	.scan_index = (_idx),					\
> .scan_type = {
> 	   .sign = 'u',
> 	   etc.
> 
> Peter picked up on this..

Sorry yes missed that. Will definitely fix.

> 
> > +	.scan_type.sign = 'u',					\
> > +	.scan_type.realbits = 12,				\
> > +	.scan_type.storagebits = 16,			\
> >  }
> >  
> >  static const struct iio_chan_spec vf610_adc_iio_channels[] = {
> > @@ -531,6 +545,7 @@ static const struct iio_chan_spec vf610_adc_iio_channels[] = {
> >  	VF610_ADC_CHAN(14, IIO_VOLTAGE),
> >  	VF610_ADC_CHAN(15, IIO_VOLTAGE),
> >  	VF610_ADC_TEMPERATURE_CHAN(26, IIO_TEMP),
> > +	IIO_CHAN_SOFT_TIMESTAMP(32),
> It's bit extreme throwing it out at scan_index 32.  Is there a reason
> to think that migh be neccesary?  Mind you, why is the temperature
> channel down at 26?  Are we dealing with a set of reserved real channels
> inbetween?


The temperature channel is the 26th channel and there are some reserved
channels in between. 31st is the channel which acts as a conversion
disabled setting. So I put the timestamp at index 32.


> >  	/* sentinel */
> >  };
> >  
> > @@ -559,13 +574,20 @@ static int vf610_adc_read_data(struct vf610_adc *info)
> >  
> >  static irqreturn_t vf610_adc_isr(int irq, void *dev_id)
> >  {
> > -	struct vf610_adc *info = (struct vf610_adc *)dev_id;
> > +	struct iio_dev *indio_dev = (struct iio_dev *)dev_id;
> > +	struct vf610_adc *info = iio_priv(indio_dev);
> >  	int coco;
> >  
> >  	coco = readl(info->regs + VF610_REG_ADC_HS);
> >  	if (coco & VF610_ADC_HS_COCO0) {
> >  		info->value = vf610_adc_read_data(info);
> 
> I'd be tempted to make the non buffered path also use
> info->bufffer[0] and drop info->value entirely.
> A more invasive patch, but a cleaner resulting code (slightly!)

I did think of that but decided against it as I wanted the changes
to as less invasive as possible making only the necessary changes
and keeping the old code as is.

> > -		complete(&info->completion);
> > +		if (iio_buffer_enabled(indio_dev)) {
> > +			info->buffer[0] = info->value;
> > +			iio_push_to_buffers_with_timestamp(indio_dev,
> > +					info->buffer, iio_get_time_ns());
> > +			iio_trigger_notify_done(indio_dev->trig);
> > +		} else
> > +			complete(&info->completion);
> >  	}
> >  
> >  	return IRQ_HANDLED;
> > @@ -612,6 +634,9 @@ static int vf610_read_raw(struct iio_dev *indio_dev,
> >  	switch (mask) {
> >  	case IIO_CHAN_INFO_RAW:
> >  	case IIO_CHAN_INFO_PROCESSED:
> 
> To avoid possible races this check should be done under the mlock

Thanks for picking this. Somehow I remember seeing it outside of the
mlock. However grepping again shows otherwise. Will fix.

.
> > +		if (iio_buffer_enabled(indio_dev))
> > +			return -EBUSY;
> > +
> >  		mutex_lock(&indio_dev->mlock);
> >  		reinit_completion(&info->completion);
> >  
> > @@ -694,6 +719,68 @@ static int vf610_write_raw(struct iio_dev *indio_dev,
> >  	return -EINVAL;
> >  }
> >  
> > +static int vf610_adc_buffer_postenable(struct iio_dev *indio_dev)
> > +{
> > +	struct vf610_adc *info = iio_priv(indio_dev);
> > +	unsigned int channel;
> > +	int ret;
> > +	int val;
> > +
> > +	ret = iio_triggered_buffer_postenable(indio_dev);
> > +	if (ret)
> > +		return ret;
> > +
> > +	val = readl(info->regs + VF610_REG_ADC_GC);
> > +	val |= VF610_ADC_ADCON;
> > +	writel(val, info->regs + VF610_REG_ADC_GC);
> > +
> > +	channel = find_first_bit(indio_dev->active_scan_mask,
> > +						indio_dev->masklength);
> > +
> > +	val = VF610_ADC_ADCHC(channel);
> > +	val |= VF610_ADC_AIEN;
> > +
> > +	writel(val, info->regs + VF610_REG_ADC_HC0);
> > +
> > +	return 0;
> > +}
> > +
> > +static int vf610_adc_buffer_postdisable(struct iio_dev *indio_dev)
> > +{
> > +	struct vf610_adc *info = iio_priv(indio_dev);
> > +	unsigned int hc_cfg = 0;
> > +	int val;
> > +
> > +	val = readl(info->regs + VF610_REG_ADC_GC);
> > +	val &= ~VF610_ADC_ADCON;
> > +	writel(val, info->regs + VF610_REG_ADC_GC);
> > +
> > +	hc_cfg |= VF610_ADC_CONV_DISABLE;
> > +	hc_cfg &= ~VF610_ADC_AIEN;
> > +
> > +	writel(hc_cfg, info->regs + VF610_REG_ADC_HC0);
> > +
> > +	return 0;
> > +}
> > +
> > +static const struct iio_buffer_setup_ops iio_triggered_buffer_setup_ops = {
> > +	.postenable = &vf610_adc_buffer_postenable,
> > +	.predisable = &iio_triggered_buffer_predisable,
> > +	.postdisable = &vf610_adc_buffer_postdisable,
> > +	.validate_scan_mask = &iio_validate_scan_mask_onehot,
> > +};
> > +
> > +static int vf610_adc_buffer_init(struct iio_dev *indio_dev)
> > +{
> > +	return iio_triggered_buffer_setup(indio_dev, &iio_pollfunc_store_time,
> > +		NULL, &iio_triggered_buffer_setup_ops);
> > +}
> > +
> > +static void vf610_adc_buffer_remove(struct iio_dev *indio_dev)
> > +{
> > +	iio_triggered_buffer_cleanup(indio_dev);
> > +}
> These to wrappers seem a little superflous. I'd have just put the code
> inline, but it's obviously a matter of personal taste and I don't care
> that much!

Ok. I do not have strong opinions on this. I just tried to follow how the
at91 adc code did it considering it as a good example. Will drop it.

> 
> > +
> >  static int vf610_adc_reg_access(struct iio_dev *indio_dev,
> >  			unsigned reg, unsigned writeval,
> >  			unsigned *readval)
> > @@ -753,7 +840,7 @@ static int vf610_adc_probe(struct platform_device *pdev)
> >  
> >  	ret = devm_request_irq(info->dev, irq,
> >  				vf610_adc_isr, 0,
> > -				dev_name(&pdev->dev), info);
> > +				dev_name(&pdev->dev), indio_dev);
> >  	if (ret < 0) {
> >  		dev_err(&pdev->dev, "failed requesting irq, irq = %d\n", irq);
> >  		return ret;
> > @@ -806,15 +893,22 @@ static int vf610_adc_probe(struct platform_device *pdev)
> >  	vf610_adc_cfg_init(info);
> >  	vf610_adc_hw_init(info);
> >  
> > +	ret = vf610_adc_buffer_init(indio_dev);
> > +	if (ret < 0) {
> > +		dev_err(&pdev->dev, "Couldn't initialise the buffer\n");
> > +		goto error_iio_device_register;
> > +	}
> > +
> >  	ret = iio_device_register(indio_dev);
> >  	if (ret) {
> >  		dev_err(&pdev->dev, "Couldn't register the device.\n");
> > -		goto error_iio_device_register;
> > +		goto error_adc_buffer_init;
> >  	}
> >  
> >  	return 0;
> >  
> > -
> > +error_adc_buffer_init:
> > +	vf610_adc_buffer_remove(indio_dev);
> >  error_iio_device_register:
> >  	clk_disable_unprepare(info->clk);
> >  error_adc_clk_enable:
> > @@ -829,6 +923,7 @@ static int vf610_adc_remove(struct platform_device *pdev)
> >  	struct vf610_adc *info = iio_priv(indio_dev);
> >  
> >  	iio_device_unregister(indio_dev);
> > +	vf610_adc_buffer_remove(indio_dev);
> >  	regulator_disable(info->vref);
> >  	clk_disable_unprepare(info->clk);
> >  
> > 
> 

Thanks for the review.

- Sanchayan.

[1]. https://community.freescale.com/thread/357619


From petr.cvek at tul.cz  Sat Aug  8 10:41:42 2015
From: petr.cvek at tul.cz (Petr Cvek)
Date: Sat, 08 Aug 2015 19:41:42 +0200
Subject: [BUG, RFC] Different bitfields in documentation and driver
In-Reply-To: <87zj21k9bx.fsf@belgarion.home>
References: <55C503A7.6020304@tul.cz> <87zj21k9bx.fsf@belgarion.home>
Message-ID: <55C63F56.3030602@tul.cz>

On 8.8.2015 18:56, Robert Jarzmik wrote:
> Petr Cvek <petr.cvek at tul.cz> writes:
> 
>> Hello,
>> It seems that PXA2xx framebuffer has switched bitfields in nonstd definition (when using overlay).
>>
>> This:
>>
>> 	http://lxr.free-electrons.com/source/drivers/video/fbdev/pxafb.h#L80
>>
>> versus this:
>>
>> 	http://lxr.free-electrons.com/source/Documentation/fb/pxafb.txt#L128
>>
>> Should be this changed in documentation or in driver? I was able to find only
>> one use (in form of little outdated mplayer patch) and it fills both bitfields
>> with zero (so potential change in driver will not break it).
> I'd rather go for documentation. Not only the driver's way looks more pretty to
> me, but it also guarantees compatibility from the kernel side.

Oh you are right, I forgot to look into SoC datasheet and related register has YX version
(driver side). Will send patch with errata warning.

> 
>> P.S. Lack of overlay2's use is probably caused by errata "E24: LCD: Enabling
>> Overlay 2 for YUV420 hangs LCD controller.", which is not workarounded in this
>> driver. It should be mentioned in documentation and/or code, because the only
>> way to start the LCD again is a full PXA SoC reset.
> Ok, do you know if this this true for all pxa variants and steppings or is this
> for only a subset of them ?
According to this:

	http://www.marvell.com/application-processors/pxa-family/assets/pxa_27x_spec_update.pdf

errata (page 11, errata 24), bug is only for C0 revision (newer are OK, but I would guess most of devices
will have C0). There is some workaround pseudocode, but it seems it does not work with me (only
few tries to implement it, but penalty is reboot ... workaround description is a little bit confusing)

P.S. LCD controller has other errors too (notably E15 (not fixed) and E16).

Petr

> 
> Cheers.
> 



From linux at arm.linux.org.uk  Sat Aug  8 10:53:13 2015
From: linux at arm.linux.org.uk (Russell King - ARM Linux)
Date: Sat, 8 Aug 2015 18:53:13 +0100
Subject: [PATCH v4] ARM: early fixmap support for earlycon
In-Reply-To: <00498073e34373292dd053cdb700ff25@agner.ch>
References: <1434491507-6208-1-git-send-email-stefan@agner.ch>
 <00498073e34373292dd053cdb700ff25@agner.ch>
Message-ID: <20150808175313.GO7557@n2100.arm.linux.org.uk>

On Thu, Jul 30, 2015 at 11:02:38PM +0200, Stefan Agner wrote:
> On 2015-06-16 23:51, Stefan Agner wrote:
> >  static void __init devicemaps_init(const struct machine_desc *mdesc)
> >  {
> > @@ -1231,7 +1272,10 @@ static void __init devicemaps_init(const struct
> > machine_desc *mdesc)
> >  
> >  	early_trap_init(vectors);
> >  
> > -	for (addr = VMALLOC_START; addr; addr += PMD_SIZE)
> > +	/*
> > +	 * Clear page table except top pmd used by early fixmaps
> > +	 */
> > +	for (addr = VMALLOC_START; addr < (FIXADDR_TOP & PMD_MASK); addr += PMD_SIZE)
> >  		pmd_clear(pmd_off_k(addr));
> >  
> 
> Hi Russel,
> 
> Checked this again, v4 does the right thing:
> FIXADDR_TOP (0xffeff000) & PMD_MASK (0xffe00000) gives us the address of
> the top PMD (0xFFE00000). We don't clear that since that is taken care
> of by early fixmap support (early_fixmap_shutdown). v3 used
> FIXADDR_START, which also left out the second to top PMD. The 3MiB of
> fixmap spawns two PMD's however only the top PMD is handled by early
> fixmap. Hence this was wrong in v3, but is fixed in v4.
> 
> Can you reconsider this patch?

I applied the patch which was in the patch system, and Olof's builder
reported failures:

        arm.allnoconfig:
:(.init.text+0x7a0): undefined reference to `early_fixmap_init'

        arm.efm32_defconfig:
arch/arm/kernel/setup.c:958: undefined reference to `early_fixmap_init'

        arm.lpc18xx_defconfig:
arch/arm/include/asm/fixmap.h:25:29: error: 'L_PTE_YOUNG' undeclared (first use in this function)
arch/arm/include/asm/fixmap.h:25:43: error: 'L_PTE_PRESENT' undeclared (first use in this function)
arch/arm/include/asm/fixmap.h:25:59: error: 'L_PTE_XN' undeclared (first use in this function)
arch/arm/include/asm/fixmap.h:25:70: error: 'L_PTE_DIRTY' undeclared (first use in this function)
arch/arm/include/asm/fixmap.h:30:47: error: 'L_PTE_MT_DEV_SHARED' undeclared (first use in this function)
arch/arm/include/asm/fixmap.h:30:69: error: 'L_PTE_SHARED' undeclared (first use in this function)

So I'm going to drop it from my tree.  Please resubmit a fixed version,
thanks.

-- 
FTTC broadband for 0.8mile line: currently at 10.5Mbps down 400kbps up
according to speedtest.net.


From petr.cvek at tul.cz  Sat Aug  8 11:20:20 2015
From: petr.cvek at tul.cz (Petr Cvek)
Date: Sat, 08 Aug 2015 20:20:20 +0200
Subject: [PATCH v1, TRIVIAL] Fix pxafb nonstd field documentation and add
 errata info
Message-ID: <55C64864.6070405@tul.cz>

Fix pxafb nonstd field documentation and add warning comment to Kconfig
and pxafb.c (errata: YUV420 hangs LCD).

Signed-off-by: Petr Cvek <petr.cvek at tul.cz>
---
 Documentation/fb/pxafb.txt  | 8 ++++----
 drivers/video/fbdev/Kconfig | 5 +++++
 drivers/video/fbdev/pxafb.c | 4 ++++
 3 files changed, 13 insertions(+), 4 deletions(-)

diff --git a/Documentation/fb/pxafb.txt b/Documentation/fb/pxafb.txt
index d143a0a..dbbf5eb 100644
--- a/Documentation/fb/pxafb.txt
+++ b/Documentation/fb/pxafb.txt
@@ -123,12 +123,12 @@ Overlay Support for PXA27x and later LCD controllers
      framebuffer framework, application has to take care of the offsets
      and lengths of each component within the framebuffer.
 
-  4. var->nonstd is used to pass starting (x, y) position and color format,
+  4. var->nonstd is used to pass starting (y, x) position and color format,
      the detailed bit fields are shown below:
 
     31                23  20         10          0
      +-----------------+---+----------+----------+
-     |  ... unused ... |FOR|   XPOS   |   YPOS   |
+     |  ... unused ... |FOR|   YPOS   |   XPOS   | (as in OVLxC2 register)
      +-----------------+---+----------+----------+
 
      FOR  - color format, as defined by OVERLAY_FORMAT_* in pxafb.h
@@ -136,7 +136,7 @@ Overlay Support for PXA27x and later LCD controllers
 	    1 - YUV444 PACKED
 	    2 - YUV444 PLANAR
 	    3 - YUV422 PLANAR
-	    4 - YUR420 PLANAR
+	    4 - YUV420 PLANAR
 
-     XPOS - starting horizontal position
      YPOS - starting vertical position
+     XPOS - starting horizontal position
diff --git a/drivers/video/fbdev/Kconfig b/drivers/video/fbdev/Kconfig
index 2d98de5..8f485ec 100644
--- a/drivers/video/fbdev/Kconfig
+++ b/drivers/video/fbdev/Kconfig
@@ -1893,6 +1893,11 @@ config FB_PXA_OVERLAY
 	bool "Support PXA27x/PXA3xx Overlay(s) as framebuffer"
 	default n
 	depends on FB_PXA && (PXA27x || PXA3xx)
+	---help---
+	  Using the overlay 2 and YUV420 mode on a PXA27x C0 chip revision will
+	  hang the LCD until the next SoC restart (errata E24).
+
+	  If unsure, say N or check /proc/cpuinfo for "CPU revision : 4".
 
 config FB_PXA_SMARTPANEL
 	bool "PXA Smartpanel LCD support"
diff --git a/drivers/video/fbdev/pxafb.c b/drivers/video/fbdev/pxafb.c
index 7245611..e573699 100644
--- a/drivers/video/fbdev/pxafb.c
+++ b/drivers/video/fbdev/pxafb.c
@@ -30,6 +30,10 @@
  *
  *   Copyright (C) 2006-2008 Marvell International Ltd.
  *   All Rights Reserved
+ *
+ * NOTICE
+ * According to PXA27x errata E24 an enable of the overlay 2 in YUV420 mode
+ * on C0 chip revision will hang the LCD until the next SoC reset.
  */
 
 #include <linux/module.h>
-- 
1.7.12.1




From jic23 at kernel.org  Sat Aug  8 11:46:00 2015
From: jic23 at kernel.org (Jonathan Cameron)
Date: Sat, 8 Aug 2015 19:46:00 +0100
Subject: [PATCH v2] iio: adc: vf610: Add IIO buffer support for Vybrid ADC
In-Reply-To: <20150808172200.GA2758@Sanchayan-Arch>
References: <cover.1438775572.git.maitysanchayan@gmail.com>
 <1bb1f290da601bbda41875a92ba6e983b423d7b0.1438775572.git.maitysanchayan@gmail.com>
 <55C6125B.1060103@kernel.org> <20150808172200.GA2758@Sanchayan-Arch>
Message-ID: <55C64E68.8010500@kernel.org>

On 08/08/15 18:22, maitysanchayan at gmail.com wrote:
> Hello Jonathan,
> 
> On 15-08-08 15:29:47, Jonathan Cameron wrote:
>> On 05/08/15 13:10, Sanchayan Maity wrote:
>>> This patch adds support for IIO buffer to the Vybrid ADC driver.
>>> IIO triggered buffer infrastructure along with iio sysfs trigger
>>> is used to leverage continuous sampling support provided by the
>>> ADC block.
>> Looking good.  Just a couple more bits and pieces inline from me.
>> One or two of which aren't corrected from Peter's review of v1.
>>
>> I will want Fugang Dong's ack / review tag on the final version
>> before applying it however.
> 
> Sure.
> 
>> This driver is some distance form my area of expertise!
> 
> I doubt :).
> 
>>
>> Jonathan
>>>
>>> Signed-off-by: Sanchayan Maity <maitysanchayan at gmail.com>
>>> ---
>>>  drivers/iio/adc/Kconfig     |   4 ++
>>>  drivers/iio/adc/vf610_adc.c | 107 +++++++++++++++++++++++++++++++++++++++++---
>>>  2 files changed, 105 insertions(+), 6 deletions(-)
>>>
>>> diff --git a/drivers/iio/adc/Kconfig b/drivers/iio/adc/Kconfig
>>> index 7c55658..4661241 100644
>>> --- a/drivers/iio/adc/Kconfig
>>> +++ b/drivers/iio/adc/Kconfig
>>> @@ -337,6 +337,10 @@ config TWL6030_GPADC
>>>  config VF610_ADC
>>>  	tristate "Freescale vf610 ADC driver"
>>>  	depends on OF
>>> +	select IIO_BUFFER
>>> +	select IIO_TRIGGER
>>> +	select IIO_SYSFS_TRIGGER
>> Unless I missed something there is no dependency on this particular
>> trigger (it just happens to be the one you've been testing with I guess).
>> Could be driven from a hardware trigger belonging to another device for
>> example.
> 
> Yes right in a way. Right now we do not provide or there is no provision
> for hardware triggers. On the Vybrid, the Peripheral Delay Block (PDB)
> does the job of providing support for software and hardware triggers. PDB
> support is not yet there in Linux however. 
Not supplying a trigger is fine, but any trigger (that allows other devices
to bind to it) will be fine.
> 
> There is also the question of where the Vybrid PDB driver would belong
> to? In the TRM it is put in the timers but the kernel has no generic timer
> framework that I am aware of.
It's been debated a number of times, but no one has ever written one.
Not seen anything recently on this topic..  Lars, you seen anything?
(the blackfin-timer trigger is similar to what you are describing I think).

> After some internal reviews we decided to
> do a platform driver which provided functions ADC driver could called into.
Does rather feel like there ought to be at least a standard home for these.
Might be worth asking the arm-soc guys...
> 
> I have a patchset ready which provides trigger support using PDB however
> configuring the PDB properly has proven to be tricky. While it works but
> not reliably with multiple channels and it would be a while before I get
> that working and post that patchset. So kind of stalled there and just
> because of two registers which need to be written with the correct value
> :). For what it's worth if someone comes across this, some discussion
> here [1] along with patches. (Note however those are a bit old patches
> not exactly my new work).
> 
> Sorry for digressing from the topic. Anyways so the idea was to provide
> sysfs triggers as default for using this continuous sampling. Later the
> driver may provide additional triggers. So for now I added the sysfs
> trigger as a select option so that a user won't have to recompile the
> kernel for using the buffers with continuous sampling.
It's a policy decision so should really be left to the distro builders.
There are lots of possible triggers out there (though sysfs might be
the most likely one!)

Hence don't put the select there in Kconfig.  We should shortly have
Daniel's update to the patches for the high resolution timer
which would give another obvious choice for starters.

I doubt many distros build without the sysfs triggers but with other IIO
stuff.

> 
>>
>>> +	select IIO_TRIGGERED_BUFFER
>>>  	help
>>>  	  Say yes here to support for Vybrid board analog-to-digital converter.
>>>  	  Since the IP is used for i.MX6SLX, the driver also support i.MX6SLX.
>>> diff --git a/drivers/iio/adc/vf610_adc.c b/drivers/iio/adc/vf610_adc.c
>>> index 23b8fb9..97cb2ed 100644
>>> --- a/drivers/iio/adc/vf610_adc.c
>>> +++ b/drivers/iio/adc/vf610_adc.c
>>> @@ -34,8 +34,11 @@
>>>  #include <linux/err.h>
>>>  
>>>  #include <linux/iio/iio.h>
>>> +#include <linux/iio/buffer.h>
>>>  #include <linux/iio/sysfs.h>
>>> -#include <linux/iio/driver.h>
>>> +#include <linux/iio/trigger.h>
>>> +#include <linux/iio/trigger_consumer.h>
>>> +#include <linux/iio/triggered_buffer.h>
>>>  
>>>  /* This will be the driver name the kernel reports */
>>>  #define DRIVER_NAME "vf610-adc"
>>> @@ -170,6 +173,7 @@ struct vf610_adc {
>>>  	u32 sample_freq_avail[5];
>>>  
>>>  	struct completion completion;
>>> +	u16 buffer[2];
>> Note the requirements on the buffer provided to
>> iio_push_to_buffers_with_timestamp
>> Needs to be u16 buffer[8] to allow for the aligned 64bit (4 word) timestamp.
>>
>> Peter pointed this out in his follow up email and you said you'd implement
>> it.. Guessing this got lost somewhere.
> 
> No, I meant to implement what Peter recommended but I guess I did not completely
> grasp what he intended. Sorry about that. Will fix this and ask further if in
> more doubts.
> 
>>
>>
>>>  };
>>>  
>>>  static const u32 vf610_hw_avgs[] = { 1, 4, 8, 16, 32 };
>>> @@ -505,12 +509,22 @@ static const struct iio_chan_spec_ext_info vf610_ext_info[] = {
>>>  	.info_mask_shared_by_type = BIT(IIO_CHAN_INFO_SCALE) |	\
>>>  				BIT(IIO_CHAN_INFO_SAMP_FREQ),	\
>>>  	.ext_info = vf610_ext_info,				\
>>> +	.address = (_idx),				\
>>> +	.scan_index = (_idx),			\
>>> +	.scan_type.sign = 'u',			\
>>> +	.scan_type.realbits = 12,		\
>>> +	.scan_type.storagebits = 16,	\
>>>  }
>>>  
>>>  #define VF610_ADC_TEMPERATURE_CHAN(_idx, _chan_type) {	\
>>>  	.type = (_chan_type),	\
>>>  	.channel = (_idx),		\
>>>  	.info_mask_separate = BIT(IIO_CHAN_INFO_PROCESSED),	\
>>> +	.address = (_idx),						\
>>> +	.scan_index = (_idx),					\
>> .scan_type = {
>> 	   .sign = 'u',
>> 	   etc.
>>
>> Peter picked up on this..
> 
> Sorry yes missed that. Will definitely fix.
> 
>>
>>> +	.scan_type.sign = 'u',					\
>>> +	.scan_type.realbits = 12,				\
>>> +	.scan_type.storagebits = 16,			\
>>>  }
>>>  
>>>  static const struct iio_chan_spec vf610_adc_iio_channels[] = {
>>> @@ -531,6 +545,7 @@ static const struct iio_chan_spec vf610_adc_iio_channels[] = {
>>>  	VF610_ADC_CHAN(14, IIO_VOLTAGE),
>>>  	VF610_ADC_CHAN(15, IIO_VOLTAGE),
>>>  	VF610_ADC_TEMPERATURE_CHAN(26, IIO_TEMP),
>>> +	IIO_CHAN_SOFT_TIMESTAMP(32),
>> It's bit extreme throwing it out at scan_index 32.  Is there a reason
>> to think that migh be neccesary?  Mind you, why is the temperature
>> channel down at 26?  Are we dealing with a set of reserved real channels
>> inbetween?
> 
> 
> The temperature channel is the 26th channel and there are some reserved
> channels in between. 31st is the channel which acts as a conversion
> disabled setting. So I put the timestamp at index 32.
Fair enough if weird ;)
> 
> 
>>>  	/* sentinel */
>>>  };
>>>  
>>> @@ -559,13 +574,20 @@ static int vf610_adc_read_data(struct vf610_adc *info)
>>>  
>>>  static irqreturn_t vf610_adc_isr(int irq, void *dev_id)
>>>  {
>>> -	struct vf610_adc *info = (struct vf610_adc *)dev_id;
>>> +	struct iio_dev *indio_dev = (struct iio_dev *)dev_id;
>>> +	struct vf610_adc *info = iio_priv(indio_dev);
>>>  	int coco;
>>>  
>>>  	coco = readl(info->regs + VF610_REG_ADC_HS);
>>>  	if (coco & VF610_ADC_HS_COCO0) {
>>>  		info->value = vf610_adc_read_data(info);
>>
>> I'd be tempted to make the non buffered path also use
>> info->bufffer[0] and drop info->value entirely.
>> A more invasive patch, but a cleaner resulting code (slightly!)
> 
> I did think of that but decided against it as I wanted the changes
> to as less invasive as possible making only the necessary changes
> and keeping the old code as is.
You could do this then clean up in a follow up patch which would be
really easy to review.
> 
>>> -		complete(&info->completion);
>>> +		if (iio_buffer_enabled(indio_dev)) {
>>> +			info->buffer[0] = info->value;
>>> +			iio_push_to_buffers_with_timestamp(indio_dev,
>>> +					info->buffer, iio_get_time_ns());
>>> +			iio_trigger_notify_done(indio_dev->trig);
>>> +		} else
>>> +			complete(&info->completion);
>>>  	}
>>>  
>>>  	return IRQ_HANDLED;
>>> @@ -612,6 +634,9 @@ static int vf610_read_raw(struct iio_dev *indio_dev,
>>>  	switch (mask) {
>>>  	case IIO_CHAN_INFO_RAW:
>>>  	case IIO_CHAN_INFO_PROCESSED:
>>
>> To avoid possible races this check should be done under the mlock
> 
> Thanks for picking this. Somehow I remember seeing it outside of the
> mlock. However grepping again shows otherwise. Will fix.
> 
> .
>>> +		if (iio_buffer_enabled(indio_dev))
>>> +			return -EBUSY;
>>> +
>>>  		mutex_lock(&indio_dev->mlock);
>>>  		reinit_completion(&info->completion);
>>>  
>>> @@ -694,6 +719,68 @@ static int vf610_write_raw(struct iio_dev *indio_dev,
>>>  	return -EINVAL;
>>>  }
>>>  
>>> +static int vf610_adc_buffer_postenable(struct iio_dev *indio_dev)
>>> +{
>>> +	struct vf610_adc *info = iio_priv(indio_dev);
>>> +	unsigned int channel;
>>> +	int ret;
>>> +	int val;
>>> +
>>> +	ret = iio_triggered_buffer_postenable(indio_dev);
>>> +	if (ret)
>>> +		return ret;
>>> +
>>> +	val = readl(info->regs + VF610_REG_ADC_GC);
>>> +	val |= VF610_ADC_ADCON;
>>> +	writel(val, info->regs + VF610_REG_ADC_GC);
>>> +
>>> +	channel = find_first_bit(indio_dev->active_scan_mask,
>>> +						indio_dev->masklength);
>>> +
>>> +	val = VF610_ADC_ADCHC(channel);
>>> +	val |= VF610_ADC_AIEN;
>>> +
>>> +	writel(val, info->regs + VF610_REG_ADC_HC0);
>>> +
>>> +	return 0;
>>> +}
>>> +
>>> +static int vf610_adc_buffer_postdisable(struct iio_dev *indio_dev)
>>> +{
>>> +	struct vf610_adc *info = iio_priv(indio_dev);
>>> +	unsigned int hc_cfg = 0;
>>> +	int val;
>>> +
>>> +	val = readl(info->regs + VF610_REG_ADC_GC);
>>> +	val &= ~VF610_ADC_ADCON;
>>> +	writel(val, info->regs + VF610_REG_ADC_GC);
>>> +
>>> +	hc_cfg |= VF610_ADC_CONV_DISABLE;
>>> +	hc_cfg &= ~VF610_ADC_AIEN;
>>> +
>>> +	writel(hc_cfg, info->regs + VF610_REG_ADC_HC0);
>>> +
>>> +	return 0;
>>> +}
>>> +
>>> +static const struct iio_buffer_setup_ops iio_triggered_buffer_setup_ops = {
>>> +	.postenable = &vf610_adc_buffer_postenable,
>>> +	.predisable = &iio_triggered_buffer_predisable,
>>> +	.postdisable = &vf610_adc_buffer_postdisable,
>>> +	.validate_scan_mask = &iio_validate_scan_mask_onehot,
>>> +};
>>> +
>>> +static int vf610_adc_buffer_init(struct iio_dev *indio_dev)
>>> +{
>>> +	return iio_triggered_buffer_setup(indio_dev, &iio_pollfunc_store_time,
>>> +		NULL, &iio_triggered_buffer_setup_ops);
>>> +}
>>> +
>>> +static void vf610_adc_buffer_remove(struct iio_dev *indio_dev)
>>> +{
>>> +	iio_triggered_buffer_cleanup(indio_dev);
>>> +}
>> These to wrappers seem a little superflous. I'd have just put the code
>> inline, but it's obviously a matter of personal taste and I don't care
>> that much!
> 
> Ok. I do not have strong opinions on this. I just tried to follow how the
> at91 adc code did it considering it as a good example. Will drop it.
> 
>>
>>> +
>>>  static int vf610_adc_reg_access(struct iio_dev *indio_dev,
>>>  			unsigned reg, unsigned writeval,
>>>  			unsigned *readval)
>>> @@ -753,7 +840,7 @@ static int vf610_adc_probe(struct platform_device *pdev)
>>>  
>>>  	ret = devm_request_irq(info->dev, irq,
>>>  				vf610_adc_isr, 0,
>>> -				dev_name(&pdev->dev), info);
>>> +				dev_name(&pdev->dev), indio_dev);
>>>  	if (ret < 0) {
>>>  		dev_err(&pdev->dev, "failed requesting irq, irq = %d\n", irq);
>>>  		return ret;
>>> @@ -806,15 +893,22 @@ static int vf610_adc_probe(struct platform_device *pdev)
>>>  	vf610_adc_cfg_init(info);
>>>  	vf610_adc_hw_init(info);
>>>  
>>> +	ret = vf610_adc_buffer_init(indio_dev);
>>> +	if (ret < 0) {
>>> +		dev_err(&pdev->dev, "Couldn't initialise the buffer\n");
>>> +		goto error_iio_device_register;
>>> +	}
>>> +
>>>  	ret = iio_device_register(indio_dev);
>>>  	if (ret) {
>>>  		dev_err(&pdev->dev, "Couldn't register the device.\n");
>>> -		goto error_iio_device_register;
>>> +		goto error_adc_buffer_init;
>>>  	}
>>>  
>>>  	return 0;
>>>  
>>> -
>>> +error_adc_buffer_init:
>>> +	vf610_adc_buffer_remove(indio_dev);
>>>  error_iio_device_register:
>>>  	clk_disable_unprepare(info->clk);
>>>  error_adc_clk_enable:
>>> @@ -829,6 +923,7 @@ static int vf610_adc_remove(struct platform_device *pdev)
>>>  	struct vf610_adc *info = iio_priv(indio_dev);
>>>  
>>>  	iio_device_unregister(indio_dev);
>>> +	vf610_adc_buffer_remove(indio_dev);
>>>  	regulator_disable(info->vref);
>>>  	clk_disable_unprepare(info->clk);
>>>  
>>>
>>
> 
> Thanks for the review.
> 
> - Sanchayan.
> 
> [1]. https://community.freescale.com/thread/357619
> 



From petr.cvek at tul.cz  Sat Aug  8 11:52:22 2015
From: petr.cvek at tul.cz (Petr Cvek)
Date: Sat, 08 Aug 2015 20:52:22 +0200
Subject: [BUG, RFC] MTD Execute in Place on ARM breaks build
In-Reply-To: <20150808134708.GK7557@n2100.arm.linux.org.uk>
References: <55C51319.2010901@tul.cz> <1564596.BEQS8u7XSM@wuerfel>
 <20150808134708.GK7557@n2100.arm.linux.org.uk>
Message-ID: <55C64FE6.40007@tul.cz>

On 8.8.2015 15:47, Russell King - ARM Linux wrote:
> On Sat, Aug 08, 2015 at 01:42:50PM +0200, Arnd Bergmann wrote:
>> A cleaner approach might be to replace xip_currtime() with
>> ktime_get_ns(), and find some other generic interface to replace
>> xip_irqpending.
> 
> Definitely not.
> 
> The issue here is that the kernel sits in flash.  When we want to write
> to flash, we need to switch the flash into a mode where the data
> contained in the flash becomes unreadable - reading from it results in
> status bytes being returned.  Status bytes are not executable.
> 
> To get around that problem, we have a small amount of code in RAM which
> does the flash erasing and/or programming.  This code, however, needs
> to have access to the interrupt controller and timer.
> 
> Calling generic functions that would be part of the paged-out kernel
> image is just not possible; doing so will immediately crash the kernel
> and break what's being achieved here.  You'd need to mark these functions
> and any functions that they then call (including spinlocks, probably
> the entire lockdep infrastructure, etc) with __xipram.  I don't think
> that's feasible.
> 
> In any case, I don't think XIP multiplatform makes any sense what so
> ever.  Needless to say, it _could_ be made to work, but you're likely
> need some complexity, and given that it has very few users, I don't
> think there's much to be gained from putting that work in.  We've even
> talked a few times about removing XIP support altogether.
> 

How often are these chips erased/written? If it is only for system image update,
it could be done with special code (something like BIOS flashing). Reading chip
in XIP mode is more useful IMO.

Anyway, is my patch proposal for build fixing OK?

Cheers,
Petr


From robert.jarzmik at free.fr  Sat Aug  8 12:15:31 2015
From: robert.jarzmik at free.fr (Robert Jarzmik)
Date: Sat, 08 Aug 2015 21:15:31 +0200
Subject: [PATCH v1,
 TRIVIAL] Fix pxafb nonstd field documentation and add errata info
In-Reply-To: <55C64864.6070405@tul.cz> (Petr Cvek's message of "Sat, 08 Aug
 2015 20:20:20 +0200")
References: <55C64864.6070405@tul.cz>
Message-ID: <87vbcpk2wc.fsf@belgarion.home>

Petr Cvek <petr.cvek at tul.cz> writes:

> Fix pxafb nonstd field documentation and add warning comment to Kconfig
> and pxafb.c (errata: YUV420 hangs LCD).
>
> Signed-off-by: Petr Cvek <petr.cvek at tul.cz>
Acked-by: Robert Jarzmik <robert.jarzmik at free.fr>

Cheers.

--
Robert


From linux at arm.linux.org.uk  Sat Aug  8 12:34:12 2015
From: linux at arm.linux.org.uk (Russell King - ARM Linux)
Date: Sat, 8 Aug 2015 20:34:12 +0100
Subject: [BUG, RFC] MTD Execute in Place on ARM breaks build
In-Reply-To: <55C64FE6.40007@tul.cz>
References: <55C51319.2010901@tul.cz> <1564596.BEQS8u7XSM@wuerfel>
 <20150808134708.GK7557@n2100.arm.linux.org.uk>
 <55C64FE6.40007@tul.cz>
Message-ID: <20150808193412.GP7557@n2100.arm.linux.org.uk>

On Sat, Aug 08, 2015 at 08:52:22PM +0200, Petr Cvek wrote:
> How often are these chips erased/written? If it is only for system
> image update, it could be done with special code (something like
> BIOS flashing).

I have no idea what the use case is for this.  Nicolas did all the
development work while working for Montavista...  It's entirely
possible that people use jffs2 or some other writable filesystem.

> Anyway, is my patch proposal for build fixing OK?

I don't think so - it effectively hides the broken nature of it,
which really isn't what kernel maintanence is about.  If something
is wrong, either it needs to be fixed properly, or it needs to stay
as a reportable bug so it reminds people that it needs to be fixed.
Papering over a bug with something that doesn't work isn't a way
forward.

Arnd suggested getting around some of the issue with:

	#define xip_currtime()  readl_relaxed(OSCR)

which would be a step in the right direction - that should issue
correct code on PXA to read the OSCR register from the __xipram
marked code.

-- 
FTTC broadband for 0.8mile line: currently at 10.5Mbps down 400kbps up
according to speedtest.net.


From oliver at schinagl.nl  Sat Aug  8 12:41:51 2015
From: oliver at schinagl.nl (Olliver Schinagl)
Date: Sat,  8 Aug 2015 21:41:51 +0200
Subject: [PATCH v6] ARM: sun4i: spi: Allow transfers larger than FIFO size
Message-ID: <1439062912-4405-1-git-send-email-oliver@schinagl.nl>

Alexandru sent this patch over a year and a half ago, and I believe several
tree's have been carrying it since. We've been using this patch on an
Olimex OLinuxIno Lime1 and Lime2 using the mmc-spi driver to access SD cards
without problems. So bumping this and adding my

Tested-by: Olliver Schinagl <oliver at schinagl.nl>

Changes from v5as warned by checkpatch. No functional changes.
 * Added some newlines to make checkpatch happy. No functional changes.

Changes from v4:
 * use min3() instead of two if statements in sun4i_spi_fill_fifo()
 * fix trivial whitespace issue in if statement in sun4i_spi_handler()
 * use consistent style in assigning 'reg' in the added functions.

Alexandru Gagniuc (1):
  ARM: sun4i: spi: Allow transfers larger than FIFO size

 drivers/spi/spi-sun4i.c | 76 +++++++++++++++++++++++++++++++++++++++++++------
 1 file changed, 67 insertions(+), 9 deletions(-)

-- 
2.1.4



From oliver at schinagl.nl  Sat Aug  8 12:41:52 2015
From: oliver at schinagl.nl (Olliver Schinagl)
Date: Sat,  8 Aug 2015 21:41:52 +0200
Subject: [PATCH v6] ARM: sun4i: spi: Allow transfers larger than FIFO size
In-Reply-To: <1439062912-4405-1-git-send-email-oliver@schinagl.nl>
References: <1439062912-4405-1-git-send-email-oliver@schinagl.nl>
Message-ID: <1439062912-4405-2-git-send-email-oliver@schinagl.nl>

From: Alexandru Gagniuc <mr.nuke.me at gmail.com>

SPI transfers were limited to one FIFO depth, which is 64 bytes.
This was an artificial limitation, however, as the hardware can handle
much larger bursts. To accommodate this, we enable the interrupt when
the Rx FIFO is 3/4 full, and drain the FIFO within the interrupt
handler. The 3/4 ratio was chosen arbitrarily, with the intention to
reduce the potential number of interrupts.

Since the SUN4I_CTL_TP bit is set, the hardware will pause
transmission whenever the FIFO is full, so there is no risk of losing
data if we can't service the interrupt in time.

For the Tx side, enable and use the Tx FIFO 3/4 empty interrupt to
replenish the FIFO on large SPI bursts. This requires more care in
when the interrupt is left enabled, as this interrupt will continually
trigger when the FIFO is less than 1/4 full, even though we
acknowledge it.

Signed-off-by: Alexandru Gagniuc <mr.nuke.me at gmail.com>
Acked-by: Maxime Ripard <maxime.ripard at free-electrons.com>
Signed-off-by: Olliver Schinagl <o.schinagl at ultimaker.com>
---
 drivers/spi/spi-sun4i.c | 76 +++++++++++++++++++++++++++++++++++++++++++------
 1 file changed, 67 insertions(+), 9 deletions(-)

diff --git a/drivers/spi/spi-sun4i.c b/drivers/spi/spi-sun4i.c
index fbb0a4d..9a30e49 100644
--- a/drivers/spi/spi-sun4i.c
+++ b/drivers/spi/spi-sun4i.c
@@ -46,6 +46,8 @@
 #define SUN4I_CTL_TP				BIT(18)
 
 #define SUN4I_INT_CTL_REG		0x0c
+#define SUN4I_INT_CTL_RF_F34			BIT(4)
+#define SUN4I_INT_CTL_TF_E34			BIT(12)
 #define SUN4I_INT_CTL_TC			BIT(16)
 
 #define SUN4I_INT_STA_REG		0x10
@@ -61,11 +63,14 @@
 #define SUN4I_CLK_CTL_CDR1(div)			(((div) & SUN4I_CLK_CTL_CDR1_MASK) << 8)
 #define SUN4I_CLK_CTL_DRS			BIT(12)
 
+#define SUN4I_MAX_XFER_SIZE			0xffffff
+
 #define SUN4I_BURST_CNT_REG		0x20
-#define SUN4I_BURST_CNT(cnt)			((cnt) & 0xffffff)
+#define SUN4I_BURST_CNT(cnt)			((cnt) & SUN4I_MAX_XFER_SIZE)
 
 #define SUN4I_XMIT_CNT_REG		0x24
-#define SUN4I_XMIT_CNT(cnt)			((cnt) & 0xffffff)
+#define SUN4I_XMIT_CNT(cnt)			((cnt) & SUN4I_MAX_XFER_SIZE)
+
 
 #define SUN4I_FIFO_STA_REG		0x28
 #define SUN4I_FIFO_STA_RF_CNT_MASK		0x7f
@@ -96,6 +101,31 @@ static inline void sun4i_spi_write(struct sun4i_spi *sspi, u32 reg, u32 value)
 	writel(value, sspi->base_addr + reg);
 }
 
+static inline u32 sun4i_spi_get_tx_fifo_count(struct sun4i_spi *sspi)
+{
+	u32 reg = sun4i_spi_read(sspi, SUN4I_FIFO_STA_REG);
+
+	reg >>= SUN4I_FIFO_STA_TF_CNT_BITS;
+
+	return reg & SUN4I_FIFO_STA_TF_CNT_MASK;
+}
+
+static inline void sun4i_spi_enable_interrupt(struct sun4i_spi *sspi, u32 mask)
+{
+	u32 reg = sun4i_spi_read(sspi, SUN4I_INT_CTL_REG);
+
+	reg |= mask;
+	sun4i_spi_write(sspi, SUN4I_INT_CTL_REG, reg);
+}
+
+static inline void sun4i_spi_disable_interrupt(struct sun4i_spi *sspi, u32 mask)
+{
+	u32 reg = sun4i_spi_read(sspi, SUN4I_INT_CTL_REG);
+
+	reg &= ~mask;
+	sun4i_spi_write(sspi, SUN4I_INT_CTL_REG, reg);
+}
+
 static inline void sun4i_spi_drain_fifo(struct sun4i_spi *sspi, int len)
 {
 	u32 reg, cnt;
@@ -118,10 +148,13 @@ static inline void sun4i_spi_drain_fifo(struct sun4i_spi *sspi, int len)
 
 static inline void sun4i_spi_fill_fifo(struct sun4i_spi *sspi, int len)
 {
+	u32 cnt;
 	u8 byte;
 
-	if (len > sspi->len)
-		len = sspi->len;
+	/* See how much data we can fit */
+	cnt = SUN4I_FIFO_DEPTH - sun4i_spi_get_tx_fifo_count(sspi);
+
+	len = min3(len, (int)cnt, sspi->len);
 
 	while (len--) {
 		byte = sspi->tx_buf ? *sspi->tx_buf++ : 0;
@@ -174,8 +207,8 @@ static int sun4i_spi_transfer_one(struct spi_master *master,
 	int ret = 0;
 	u32 reg;
 
-	/* We don't support transfer larger than the FIFO */
-	if (tfr->len > SUN4I_FIFO_DEPTH)
+	/* This is the maximum SPI burst size supported by the hardware */
+	if (tfr->len > SUN4I_MAX_XFER_SIZE)
 		return -EINVAL;
 
 	reinit_completion(&sspi->done);
@@ -273,7 +306,11 @@ static int sun4i_spi_transfer_one(struct spi_master *master,
 	sun4i_spi_fill_fifo(sspi, SUN4I_FIFO_DEPTH);
 
 	/* Enable the interrupts */
-	sun4i_spi_write(sspi, SUN4I_INT_CTL_REG, SUN4I_INT_CTL_TC);
+	sun4i_spi_enable_interrupt(sspi, SUN4I_INT_CTL_TC |
+					 SUN4I_INT_CTL_RF_F34);
+	/* Only enable Tx FIFO interrupt if we really need it */
+	if (tx_len > SUN4I_FIFO_DEPTH)
+		sun4i_spi_enable_interrupt(sspi, SUN4I_INT_CTL_TF_E34);
 
 	/* Start the transfer */
 	reg = sun4i_spi_read(sspi, SUN4I_CTL_REG);
@@ -286,8 +323,6 @@ static int sun4i_spi_transfer_one(struct spi_master *master,
 		goto out;
 	}
 
-	sun4i_spi_drain_fifo(sspi, SUN4I_FIFO_DEPTH);
-
 out:
 	sun4i_spi_write(sspi, SUN4I_INT_CTL_REG, 0);
 
@@ -302,10 +337,33 @@ static irqreturn_t sun4i_spi_handler(int irq, void *dev_id)
 	/* Transfer complete */
 	if (status & SUN4I_INT_CTL_TC) {
 		sun4i_spi_write(sspi, SUN4I_INT_STA_REG, SUN4I_INT_CTL_TC);
+		sun4i_spi_drain_fifo(sspi, SUN4I_FIFO_DEPTH);
 		complete(&sspi->done);
 		return IRQ_HANDLED;
 	}
 
+	/* Receive FIFO 3/4 full */
+	if (status & SUN4I_INT_CTL_RF_F34) {
+		sun4i_spi_drain_fifo(sspi, SUN4I_FIFO_DEPTH);
+		/* Only clear the interrupt _after_ draining the FIFO */
+		sun4i_spi_write(sspi, SUN4I_INT_STA_REG, SUN4I_INT_CTL_RF_F34);
+		return IRQ_HANDLED;
+	}
+
+	/* Transmit FIFO 3/4 empty */
+	if (status & SUN4I_INT_CTL_TF_E34) {
+		sun4i_spi_fill_fifo(sspi, SUN4I_FIFO_DEPTH);
+
+		if (!sspi->len)
+			/* nothing left to transmit */
+			sun4i_spi_disable_interrupt(sspi, SUN4I_INT_CTL_TF_E34);
+
+		/* Only clear the interrupt _after_ re-seeding the FIFO */
+		sun4i_spi_write(sspi, SUN4I_INT_STA_REG, SUN4I_INT_CTL_TF_E34);
+
+		return IRQ_HANDLED;
+	}
+
 	return IRQ_NONE;
 }
 
-- 
2.1.4



From f.fainelli at gmail.com  Sat Aug  8 12:50:44 2015
From: f.fainelli at gmail.com (Florian Fainelli)
Date: Sat,  8 Aug 2015 12:50:44 -0700
Subject: [GIT PULL] Broadcom SoC changes for 4.3 (part 2, try2)
In-Reply-To: <55C4E8C8.7030503@broadcom.com>
References: <55C4E8C8.7030503@broadcom.com>
Message-ID: <1439063444-12466-1-git-send-email-f.fainelli@gmail.com>

The following changes since commit 39aa437e18cac7acae55481ed73feea0de497399:

  Merge branch 'queue/irq/arm' of git://git.kernel.org/pub/scm/linux/kernel/git/tip/tip into next/cleanup (2015-08-05 17:24:11 +0200)

are available in the git repository at:

  http://github.com/broadcom/stblinux tags/arm-soc/for-4.3/soc-part2

for you to fetch changes up to cf1140515b3b94ef5aa06a085e94ddd814a8cd78:

  ARM: brcmstb: select ARCH_DMA_ADDR_T_64BIT for LPAE (2015-08-06 21:38:13 -0700)

----------------------------------------------------------------
This pull request contains two changes for brcmstb SoCs from Gregory:

- Update the BRCMSTB Kconfig to select the ARM erratum 798181 which
  affects the chips covered by this platform

- Update the BRCMST Kconfig to select 64-bits DMA address types when LPAE
  is enabled

----------------------------------------------------------------
Gregory Fong (2):
      ARM: BCM: Enable ARM erratum 798181 for BRCMSTB
      ARM: brcmstb: select ARCH_DMA_ADDR_T_64BIT for LPAE

 arch/arm/mach-bcm/Kconfig | 2 ++
 1 file changed, 2 insertions(+)


From dhdang at apm.com  Sat Aug  8 13:31:02 2015
From: dhdang at apm.com (Duc Dang)
Date: Sat, 8 Aug 2015 13:31:02 -0700
Subject: [PATCH v5 1/2] usb: make xhci platform driver use 64 bit or 32
 bit DMA
In-Reply-To: <20150808092252.GJ7557@n2100.arm.linux.org.uk>
References: <CADaLNDkU14GCPZE_zNt_9kMSsUdywyNp1QCiWpokXQgbfRS0qw@mail.gmail.com>
 <74fe0b014334a5ac1db90dec46bdbf6c30c07895.1439002338.git.dhdang@apm.com>
 <20150808092252.GJ7557@n2100.arm.linux.org.uk>
Message-ID: <CADaLNDn4SvW3hvi7H0c_z2xgVSgRHLOK06xMyTYJd+ddFqc7Nw@mail.gmail.com>

On Sat, Aug 8, 2015 at 2:22 AM, Russell King - ARM Linux
<linux at arm.linux.org.uk> wrote:
> On Fri, Aug 07, 2015 at 08:18:48PM -0700, Duc Dang wrote:
>> diff --git a/drivers/usb/host/xhci-plat.c b/drivers/usb/host/xhci-plat.c
>> index 890ad9d..5d03f8b 100644
>> --- a/drivers/usb/host/xhci-plat.c
>> +++ b/drivers/usb/host/xhci-plat.c
>> @@ -93,14 +93,14 @@ static int xhci_plat_probe(struct platform_device *pdev)
>>       if (irq < 0)
>>               return -ENODEV;
>>
>> -     /* Initialize dma_mask and coherent_dma_mask to 32-bits */
>> -     ret = dma_set_coherent_mask(&pdev->dev, DMA_BIT_MASK(32));
>> -     if (ret)
>> -             return ret;
>> -     if (!pdev->dev.dma_mask)
>> -             pdev->dev.dma_mask = &pdev->dev.coherent_dma_mask;
>> -     else
>> -             dma_set_mask(&pdev->dev, DMA_BIT_MASK(32));
>> +     /* Try setting the coherent_dma_mask to 64 bits, then try 32 bits */
>> +     ret = dma_set_mask_and_coherent(&pdev->dev, DMA_BIT_MASK(64));
>> +     if (ret) {
>> +             ret = dma_set_mask_and_coherent(&pdev->dev, DMA_BIT_MASK(32));
>> +             if (ret)
>> +                     return ret;
>> +     }
>
> Note that dma_set_mask_and_coherent() and the original code are not
> equivalent because of this:
>
>         if (!pdev->dev.dma_mask)
>                 pdev->dev.dma_mask = &pdev->dev.coherent_dma_mask;
>
> If we know that pdev->dev.dma_mask will always be initialised at this
> point, then the above change is fine.  If not, it's introducing a
> regression - dma_set_mask_and_coherent() will fail if pdev->dev.dma_mask
> is NULL (depending on the architectures implementation of dma_set_mask()).
>
> Prefixing the above change with the two lines I mention above would
> ensure equivalent behaviour.  Even if we do want to get rid of this,
> I'd advise to do it as a separate patch after this change, which can
> be independently reverted if there's problems with its removal.
>
Hi Russell,

I will add the 2 lines you mentioned back to next version of the
patch. It is safer to do it that way as I do not see
pdev->dev.dma_mask gets initialized before the call
dma_set_mask_and_coherent  inside this xhci_plat.c file.

> --
> FTTC broadband for 0.8mile line: currently at 10.5Mbps down 400kbps up
> according to speedtest.net.

-- 
Regards,
Duc Dang.


From gregkh at linuxfoundation.org  Sat Aug  8 13:37:46 2015
From: gregkh at linuxfoundation.org (gregkh at linuxfoundation.org)
Date: Sat, 08 Aug 2015 13:37:46 -0700
Subject: Patch "irqchip/gicv3-its: Fix mapping of LPIs to collections" has
 been added to the 4.1-stable tree
Message-ID: <14390662669147@kroah.com>


This is a note to let you know that I've just added the patch titled

    irqchip/gicv3-its: Fix mapping of LPIs to collections

to the 4.1-stable tree which can be found at:
    http://www.kernel.org/git/?p=linux/kernel/git/stable/stable-queue.git;a=summary

The filename of the patch is:
     irqchip-gicv3-its-fix-mapping-of-lpis-to-collections.patch
and it can be found in the queue-4.1 subdirectory.

If you, or anyone else, feels it should not be added to the stable tree,
please let <stable at vger.kernel.org> know about it.


>From 591e5bec13f15feb13fc445b6c9c59954711c4ac Mon Sep 17 00:00:00 2001
From: Marc Zyngier <marc.zyngier at arm.com>
Date: Fri, 17 Jul 2015 10:46:42 +0100
Subject: irqchip/gicv3-its: Fix mapping of LPIs to collections

From: Marc Zyngier <marc.zyngier at arm.com>

commit 591e5bec13f15feb13fc445b6c9c59954711c4ac upstream.

The GICv3 ITS architecture allows a given [DevID, EventID] pair to be
translated to a [LPI, Collection] pair, where DevID is the device writing
the MSI, EventID is the payload being written, LPI is the actual
interrupt number, and Collection is roughly equivalent to a target CPU.

Each LPI can be mapped to a separate collection, but the ITS driver
insists on maintaining the collection on a device basis, instead of doing
it on a per interrupt basis.

This is obviously flawed, and this patch fixes it by adding a per interrupt
index that indicates which collection number is in use.

Reported-by: Ian Campbell <ian.campbell at citrix.com>
Signed-off-by: Marc Zyngier <marc.zyngier at arm.com>
Cc: <linux-arm-kernel at lists.infradead.org>
Cc: Jason Cooper <jason at lakedaemon.net>
Link: http://lkml.kernel.org/r/1437126402-11677-1-git-send-email-marc.zyngier at arm.com
Signed-off-by: Thomas Gleixner <tglx at linutronix.de>
Signed-off-by: Greg Kroah-Hartman <gregkh at linuxfoundation.org>

---
 drivers/irqchip/irq-gic-v3-its.c |  111 ++++++++++++++++++++++++++-------------
 1 file changed, 75 insertions(+), 36 deletions(-)

--- a/drivers/irqchip/irq-gic-v3-its.c
+++ b/drivers/irqchip/irq-gic-v3-its.c
@@ -75,6 +75,13 @@ struct its_node {
 
 #define ITS_ITT_ALIGN		SZ_256
 
+struct event_lpi_map {
+	unsigned long		*lpi_map;
+	u16			*col_map;
+	irq_hw_number_t		lpi_base;
+	int			nr_lpis;
+};
+
 /*
  * The ITS view of a device - belongs to an ITS, a collection, owns an
  * interrupt translation table, and a list of interrupts.
@@ -82,11 +89,8 @@ struct its_node {
 struct its_device {
 	struct list_head	entry;
 	struct its_node		*its;
-	struct its_collection	*collection;
+	struct event_lpi_map	event_map;
 	void			*itt;
-	unsigned long		*lpi_map;
-	irq_hw_number_t		lpi_base;
-	int			nr_lpis;
 	u32			nr_ites;
 	u32			device_id;
 };
@@ -99,6 +103,14 @@ static struct rdists *gic_rdists;
 #define gic_data_rdist()		(raw_cpu_ptr(gic_rdists->rdist))
 #define gic_data_rdist_rd_base()	(gic_data_rdist()->rd_base)
 
+static struct its_collection *dev_event_to_col(struct its_device *its_dev,
+					       u32 event)
+{
+	struct its_node *its = its_dev->its;
+
+	return its->collections + its_dev->event_map.col_map[event];
+}
+
 /*
  * ITS command descriptors - parameters to be encoded in a command
  * block.
@@ -134,7 +146,7 @@ struct its_cmd_desc {
 		struct {
 			struct its_device *dev;
 			struct its_collection *col;
-			u32 id;
+			u32 event_id;
 		} its_movi_cmd;
 
 		struct {
@@ -241,7 +253,7 @@ static struct its_collection *its_build_
 
 	its_fixup_cmd(cmd);
 
-	return desc->its_mapd_cmd.dev->collection;
+	return NULL;
 }
 
 static struct its_collection *its_build_mapc_cmd(struct its_cmd_block *cmd,
@@ -260,52 +272,72 @@ static struct its_collection *its_build_
 static struct its_collection *its_build_mapvi_cmd(struct its_cmd_block *cmd,
 						  struct its_cmd_desc *desc)
 {
+	struct its_collection *col;
+
+	col = dev_event_to_col(desc->its_mapvi_cmd.dev,
+			       desc->its_mapvi_cmd.event_id);
+
 	its_encode_cmd(cmd, GITS_CMD_MAPVI);
 	its_encode_devid(cmd, desc->its_mapvi_cmd.dev->device_id);
 	its_encode_event_id(cmd, desc->its_mapvi_cmd.event_id);
 	its_encode_phys_id(cmd, desc->its_mapvi_cmd.phys_id);
-	its_encode_collection(cmd, desc->its_mapvi_cmd.dev->collection->col_id);
+	its_encode_collection(cmd, col->col_id);
 
 	its_fixup_cmd(cmd);
 
-	return desc->its_mapvi_cmd.dev->collection;
+	return col;
 }
 
 static struct its_collection *its_build_movi_cmd(struct its_cmd_block *cmd,
 						 struct its_cmd_desc *desc)
 {
+	struct its_collection *col;
+
+	col = dev_event_to_col(desc->its_movi_cmd.dev,
+			       desc->its_movi_cmd.event_id);
+
 	its_encode_cmd(cmd, GITS_CMD_MOVI);
 	its_encode_devid(cmd, desc->its_movi_cmd.dev->device_id);
-	its_encode_event_id(cmd, desc->its_movi_cmd.id);
+	its_encode_event_id(cmd, desc->its_movi_cmd.event_id);
 	its_encode_collection(cmd, desc->its_movi_cmd.col->col_id);
 
 	its_fixup_cmd(cmd);
 
-	return desc->its_movi_cmd.dev->collection;
+	return col;
 }
 
 static struct its_collection *its_build_discard_cmd(struct its_cmd_block *cmd,
 						    struct its_cmd_desc *desc)
 {
+	struct its_collection *col;
+
+	col = dev_event_to_col(desc->its_discard_cmd.dev,
+			       desc->its_discard_cmd.event_id);
+
 	its_encode_cmd(cmd, GITS_CMD_DISCARD);
 	its_encode_devid(cmd, desc->its_discard_cmd.dev->device_id);
 	its_encode_event_id(cmd, desc->its_discard_cmd.event_id);
 
 	its_fixup_cmd(cmd);
 
-	return desc->its_discard_cmd.dev->collection;
+	return col;
 }
 
 static struct its_collection *its_build_inv_cmd(struct its_cmd_block *cmd,
 						struct its_cmd_desc *desc)
 {
+	struct its_collection *col;
+
+	col = dev_event_to_col(desc->its_inv_cmd.dev,
+			       desc->its_inv_cmd.event_id);
+
 	its_encode_cmd(cmd, GITS_CMD_INV);
 	its_encode_devid(cmd, desc->its_inv_cmd.dev->device_id);
 	its_encode_event_id(cmd, desc->its_inv_cmd.event_id);
 
 	its_fixup_cmd(cmd);
 
-	return desc->its_inv_cmd.dev->collection;
+	return col;
 }
 
 static struct its_collection *its_build_invall_cmd(struct its_cmd_block *cmd,
@@ -497,7 +529,7 @@ static void its_send_movi(struct its_dev
 
 	desc.its_movi_cmd.dev = dev;
 	desc.its_movi_cmd.col = col;
-	desc.its_movi_cmd.id = id;
+	desc.its_movi_cmd.event_id = id;
 
 	its_send_single_command(dev->its, its_build_movi_cmd, &desc);
 }
@@ -528,7 +560,7 @@ static void its_send_invall(struct its_n
 static inline u32 its_get_event_id(struct irq_data *d)
 {
 	struct its_device *its_dev = irq_data_get_irq_chip_data(d);
-	return d->hwirq - its_dev->lpi_base;
+	return d->hwirq - its_dev->event_map.lpi_base;
 }
 
 static void lpi_set_config(struct irq_data *d, bool enable)
@@ -583,7 +615,7 @@ static int its_set_affinity(struct irq_d
 
 	target_col = &its_dev->its->collections[cpu];
 	its_send_movi(its_dev, target_col, id);
-	its_dev->collection = target_col;
+	its_dev->event_map.col_map[id] = cpu;
 
 	return IRQ_SET_MASK_OK_DONE;
 }
@@ -713,8 +745,10 @@ out:
 	return bitmap;
 }
 
-static void its_lpi_free(unsigned long *bitmap, int base, int nr_ids)
+static void its_lpi_free(struct event_lpi_map *map)
 {
+	int base = map->lpi_base;
+	int nr_ids = map->nr_lpis;
 	int lpi;
 
 	spin_lock(&lpi_lock);
@@ -731,7 +765,8 @@ static void its_lpi_free(unsigned long *
 
 	spin_unlock(&lpi_lock);
 
-	kfree(bitmap);
+	kfree(map->lpi_map);
+	kfree(map->col_map);
 }
 
 /*
@@ -1099,11 +1134,11 @@ static struct its_device *its_create_dev
 	struct its_device *dev;
 	unsigned long *lpi_map;
 	unsigned long flags;
+	u16 *col_map = NULL;
 	void *itt;
 	int lpi_base;
 	int nr_lpis;
 	int nr_ites;
-	int cpu;
 	int sz;
 
 	dev = kzalloc(sizeof(*dev), GFP_KERNEL);
@@ -1117,20 +1152,24 @@ static struct its_device *its_create_dev
 	sz = max(sz, ITS_ITT_ALIGN) + ITS_ITT_ALIGN - 1;
 	itt = kzalloc(sz, GFP_KERNEL);
 	lpi_map = its_lpi_alloc_chunks(nvecs, &lpi_base, &nr_lpis);
+	if (lpi_map)
+		col_map = kzalloc(sizeof(*col_map) * nr_lpis, GFP_KERNEL);
 
-	if (!dev || !itt || !lpi_map) {
+	if (!dev || !itt || !lpi_map || !col_map) {
 		kfree(dev);
 		kfree(itt);
 		kfree(lpi_map);
+		kfree(col_map);
 		return NULL;
 	}
 
 	dev->its = its;
 	dev->itt = itt;
 	dev->nr_ites = nr_ites;
-	dev->lpi_map = lpi_map;
-	dev->lpi_base = lpi_base;
-	dev->nr_lpis = nr_lpis;
+	dev->event_map.lpi_map = lpi_map;
+	dev->event_map.col_map = col_map;
+	dev->event_map.lpi_base = lpi_base;
+	dev->event_map.nr_lpis = nr_lpis;
 	dev->device_id = dev_id;
 	INIT_LIST_HEAD(&dev->entry);
 
@@ -1138,10 +1177,6 @@ static struct its_device *its_create_dev
 	list_add(&dev->entry, &its->its_device_list);
 	raw_spin_unlock_irqrestore(&its->lock, flags);
 
-	/* Bind the device to the first possible CPU */
-	cpu = cpumask_first(cpu_online_mask);
-	dev->collection = &its->collections[cpu];
-
 	/* Map device to its ITT */
 	its_send_mapd(dev, 1);
 
@@ -1163,12 +1198,13 @@ static int its_alloc_device_irq(struct i
 {
 	int idx;
 
-	idx = find_first_zero_bit(dev->lpi_map, dev->nr_lpis);
-	if (idx == dev->nr_lpis)
+	idx = find_first_zero_bit(dev->event_map.lpi_map,
+				  dev->event_map.nr_lpis);
+	if (idx == dev->event_map.nr_lpis)
 		return -ENOSPC;
 
-	*hwirq = dev->lpi_base + idx;
-	set_bit(idx, dev->lpi_map);
+	*hwirq = dev->event_map.lpi_base + idx;
+	set_bit(idx, dev->event_map.lpi_map);
 
 	return 0;
 }
@@ -1288,7 +1324,8 @@ static int its_irq_domain_alloc(struct i
 		irq_domain_set_hwirq_and_chip(domain, virq + i,
 					      hwirq, &its_irq_chip, its_dev);
 		dev_dbg(info->scratchpad[1].ptr, "ID:%d pID:%d vID:%d\n",
-			(int)(hwirq - its_dev->lpi_base), (int)hwirq, virq + i);
+			(int)(hwirq - its_dev->event_map.lpi_base),
+			(int)hwirq, virq + i);
 	}
 
 	return 0;
@@ -1300,6 +1337,9 @@ static void its_irq_domain_activate(stru
 	struct its_device *its_dev = irq_data_get_irq_chip_data(d);
 	u32 event = its_get_event_id(d);
 
+	/* Bind the LPI to the first possible CPU */
+	its_dev->event_map.col_map[event] = cpumask_first(cpu_online_mask);
+
 	/* Map the GIC IRQ and event to the device */
 	its_send_mapvi(its_dev, d->hwirq, event);
 }
@@ -1327,17 +1367,16 @@ static void its_irq_domain_free(struct i
 		u32 event = its_get_event_id(data);
 
 		/* Mark interrupt index as unused */
-		clear_bit(event, its_dev->lpi_map);
+		clear_bit(event, its_dev->event_map.lpi_map);
 
 		/* Nuke the entry in the domain */
 		irq_domain_reset_irq_data(data);
 	}
 
 	/* If all interrupts have been freed, start mopping the floor */
-	if (bitmap_empty(its_dev->lpi_map, its_dev->nr_lpis)) {
-		its_lpi_free(its_dev->lpi_map,
-			     its_dev->lpi_base,
-			     its_dev->nr_lpis);
+	if (bitmap_empty(its_dev->event_map.lpi_map,
+			 its_dev->event_map.nr_lpis)) {
+		its_lpi_free(&its_dev->event_map);
 
 		/* Unmap device/itt */
 		its_send_mapd(its_dev, 0);


Patches currently in stable-queue which might be from marc.zyngier at arm.com are

queue-4.1/irqchip-gicv3-its-fix-mapping-of-lpis-to-collections.patch


From javier at dowhile0.org  Sat Aug  8 14:05:42 2015
From: javier at dowhile0.org (Javier Martinez Canillas)
Date: Sat, 8 Aug 2015 23:05:42 +0200
Subject: [PATCH v4 2/2] usb: Add support for ACPI identification to
 xhci-platform
In-Reply-To: <20150808153710.GA11851@kroah.com>
References: <CADaLNDkeOP+gBw0qdSDha551w+w+q4ry9-EevDw5giyiQGdnqA@mail.gmail.com>
 <5e302acb5b03c9bf61ecfb9b5b37e8b3b520bed9.1438994178.git.dhdang@apm.com>
 <20150808012905.GA10407@kroah.com>
 <CABxcv=nAxKqt06js1epALu8Y_61bZ+XeRwy_N=oQUTeRVCh6-w@mail.gmail.com>
 <20150808153710.GA11851@kroah.com>
Message-ID: <CABxcv=nRpAec7yGa8xK0Or7Jk5fzF-5SsZ+_Dn2Oa1xqntys+Q@mail.gmail.com>

Hello Greg,

On Sat, Aug 8, 2015 at 5:37 PM, Greg KH <gregkh at linuxfoundation.org> wrote:
> On Sat, Aug 08, 2015 at 07:43:40AM +0200, Javier Martinez Canillas wrote:
>> Hello Greg,
>>
>> On Sat, Aug 8, 2015 at 3:29 AM, Greg KH <gregkh at linuxfoundation.org> wrote:
>> > On Fri, Aug 07, 2015 at 06:03:36PM -0700, Duc Dang wrote:
>> >> Provide the methods to let ACPI identify the need to use
>> >> xhci-platform. Change the Kconfig files so the
>> >> xhci-plat.o file is selectable during kernel config.
>> >>
>> >> This has been tested on an ARM64 machine with platform XHCI, an
>> >> x86_64 machine with XHCI, and an x86_64 machine without XHCI.
>> >> There were no regressions or error messages on the machines
>> >> without platform XHCI.
>> >>
>> >> [dhdang: regenerate the patch over 4.2-rc5]
>> >> Signed-off-by: Mark Langsdorf <mlangsdo at redhat.com>
>> >> Signed-off-by: Duc Dang <dhdang at apm.com>
>> >>
>> >> ---
>> >> Changes from v3:
>> >>       Regenerate the patch over 4.2-rc5
>> >>       No code change
>> >>
>> >> Changes from v2
>> >>       Replaced tristate with a boolean as the driver doesn't
>> >>               compile as a module
>> >>       Correct --help-- to ---help---
>> >>
>> >> Changes from v1
>> >>       Renamed from "add support for APM X-Gene to xhci-platform"
>> >>       Removed changes to arm64/Kconfig
>> >>       Made CONFIG_USB_XHCI_PLATFORM a user selectable config option
>> >>
>> >>  drivers/usb/host/Kconfig     |  7 ++++++-
>> >>  drivers/usb/host/xhci-plat.c | 11 +++++++++++
>> >>  2 files changed, 17 insertions(+), 1 deletion(-)
>> >>
>> >> diff --git a/drivers/usb/host/Kconfig b/drivers/usb/host/Kconfig
>> >> index 8afc3c1..96231ee 100644
>> >> --- a/drivers/usb/host/Kconfig
>> >> +++ b/drivers/usb/host/Kconfig
>> >> @@ -32,7 +32,12 @@ config USB_XHCI_PCI
>> >>         default y
>> >>
>> >>  config USB_XHCI_PLATFORM
>> >> -     tristate
>> >> +     tristate "xHCI platform driver support"
>> >> +     ---help---
>> >> +       Say 'Y' to enable the support for the xHCI host controller
>> >> +       as a platform device. Many ARM SoCs provide USB this way.
>> >> +
>> >> +       If unsure, say 'Y'.
>> >>
>> >>  config USB_XHCI_MVEBU
>> >>       tristate "xHCI support for Marvell Armada 375/38x"
>> >> diff --git a/drivers/usb/host/xhci-plat.c b/drivers/usb/host/xhci-plat.c
>> >> index 5d03f8b..14b40d2 100644
>> >> --- a/drivers/usb/host/xhci-plat.c
>> >> +++ b/drivers/usb/host/xhci-plat.c
>> >> @@ -19,6 +19,7 @@
>> >>  #include <linux/usb/phy.h>
>> >>  #include <linux/slab.h>
>> >>  #include <linux/usb/xhci_pdriver.h>
>> >> +#include <linux/acpi.h>
>> >>
>> >>  #include "xhci.h"
>> >>  #include "xhci-mvebu.h"
>> >> @@ -262,6 +263,15 @@ static const struct of_device_id usb_xhci_of_match[] = {
>> >>  MODULE_DEVICE_TABLE(of, usb_xhci_of_match);
>> >>  #endif
>> >>
>> >> +#ifdef CONFIG_ACPI
>> >
>> > You shoudn't need this #ifdef, right?
>> >
>>
>> Why it is not needed?
>
> Why is it needed?
>

As explained, to have avoid having an unused variable.

>> The driver does .acpi_match_table = ACPI_PTR(usb_xhci_acpi_match) and
>> ACPI_PTR() is NULL if CONFIG_ACPI is not enabled. Which can happen
>> AFAIU since the driver also supports OF. So without the #ifdef guards,
>> .acpi_match_table = NULL and the struct acpi_device_id
>> usb_xhci_acpi_match[] will be built but not used.
>
> Which is just fine, right?
>

I've seen people having different opinions about this specific case
(using #ifdef guards for ACPI, OF, etc match tables definition),
that's why I asked.

>> Or am I missing something?
>
> Don't put #ifdef in .c files if at all possible is the kernel style
> rules.
>

I know but as you said the rule is to not have #ifdef if possible. But
I understand now that for you this case doesn't justify the #ifdefery.

> thanks,
>
> greg k-h

Best regards,
Javier


From heiko at sntech.de  Sat Aug  8 14:28:07 2015
From: heiko at sntech.de (Heiko =?ISO-8859-1?Q?St=FCbner?=)
Date: Sat, 08 Aug 2015 23:28:07 +0200
Subject: [GIT PULL 1/2] Rockchip soc changes for 4.3, part2
Message-ID: <3109032.sS4ICWceDv@diego>

Hi Olof, Kevin, Arnd,

here is round two of soc and devicetree changes for 4.3.

So if ok, please pull

Thanks
Heiko


The following changes since commit cb8cc37f4d38d96552f2c52deb15e511cdacf906:

  ARM: rockchip: fix broken build (2015-07-06 11:46:08 +0200)

are available in the git repository at:

  git://git.kernel.org/pub/scm/linux/kernel/git/mmind/linux-rockchip.git tags/v4.3-rockchip32-soc2

for you to fetch changes up to 9bb91ae970dd004393a3d7d09bdcc30dfe2f8693:

  ARM: rockchip: enable PMU_GPIOINT_WAKEUP_EN when entering shallow suspend (2015-08-06 13:05:14 +0200)

----------------------------------------------------------------
Improve reliability of resume on rk3288 boards. For whatever
reason resuming from suspend worked sucessfully on the rk3288-evb
but not on other boards, like veyron-devices. Two problems seem
to have existed. For one the stabilization delays for pmic and
oscillator may have been to short and secondly the shallow
suspend seems to need GPIO wakups enabled. Normally this should
be covered by the more generic ARMINT wakeups already and
the reason for this is still investigated at Rockchip, but
meanwhile this makes boards actually resume.

----------------------------------------------------------------
Heiko Stuebner (3):
      ARM: rockchip: rename osc_switch_to_32k variable
      ARM: rockchip: set correct stabilization thresholds in suspend
      ARM: rockchip: enable PMU_GPIOINT_WAKEUP_EN when entering shallow suspend

 arch/arm/mach-rockchip/pm.c | 35 +++++++++++++++++++++++++++--------
 arch/arm/mach-rockchip/pm.h |  5 +----
 2 files changed, 28 insertions(+), 12 deletions(-)



From heiko at sntech.de  Sat Aug  8 14:28:54 2015
From: heiko at sntech.de (Heiko =?ISO-8859-1?Q?St=FCbner?=)
Date: Sat, 08 Aug 2015 23:28:54 +0200
Subject: [GIT PULL 2/2] Rockchip devicetree changes for 4.3, part2
In-Reply-To: <3109032.sS4ICWceDv@diego>
References: <3109032.sS4ICWceDv@diego>
Message-ID: <1647709.GpuDCKf86R@diego>

The following changes since commit 4863dcd394019b542ac968870cba734d27e992e0:

  ARM: dts: rockchip: add rk3288 arm-pmu irq affinity (2015-07-16 22:22:47 +0200)

are available in the git repository at:

  git://git.kernel.org/pub/scm/linux/kernel/git/mmind/linux-rockchip.git tags/v4.3-rockchip32-dts2

for you to fetch changes up to 378abcdf3297613f6712343ce3a79b7d6abdf955:

  ARM: dts: rockchip: add veyron-minnie board (2015-08-08 12:31:27 +0200)

----------------------------------------------------------------
Some more devicetree changes, including usbphy support for the
Cortex-A9 SoCs and actually enabling usb on the rk3066-marsboard,
Two more veyron-devices - namely Speedy and Minnie and a fix for
the tsadc.
One slightly more interesting fix is the blocking of the last
16MB of memory on 4GB rk3288 devices. The rk3288 cannot use this
area for dma operations, so things like the mmc or usb controllers
regularly fail when trying to read data. This solution mimicks the
solution from the ChromeOS kernel, who also do not seem to have
found a better solution yet. Here it only moves to the devicetree.
As this issue is also present on the arm64 rk3368, any future
better solution to this problem would need to describe this in
the devicetree as well and could then remove this block.

----------------------------------------------------------------
Alexandru M Stan (1):
      ARM: dts: rockchip: add veyron-minnie board

Heiko Stuebner (4):
      ARM: dts: rockchip: set correct dwc2 params for cortex-a9 socs
      ARM: dts: rockchip: add usb phys to Cortex-A9 socs
      ARM: dts: rockchip: enable usb controller on marsboard
      ARM: dts: rockchip: reserve unusable memory region on rk3288

Romain Perier (2):
      ARM: dts: rockchip: Use correct dts properties for tsadc node on veyron
      ARM: dts: rockchip: Add veyron-speedy board

 Documentation/devicetree/bindings/arm/rockchip.txt |  15 ++
 arch/arm/boot/dts/Makefile                         |   4 +-
 arch/arm/boot/dts/rk3066a-marsboard.dts            |  12 ++
 arch/arm/boot/dts/rk3066a-rayeager.dts             |   4 +
 arch/arm/boot/dts/rk3066a.dtsi                     |  22 ++
 arch/arm/boot/dts/rk3188-radxarock.dts             |   4 +
 arch/arm/boot/dts/rk3188.dtsi                      |  22 ++
 arch/arm/boot/dts/rk3288-veyron-minnie.dts         | 226 +++++++++++++++++++++
 arch/arm/boot/dts/rk3288-veyron-speedy.dts         | 155 ++++++++++++++
 arch/arm/boot/dts/rk3288-veyron.dtsi               |   4 +-
 arch/arm/boot/dts/rk3288.dtsi                      |  20 ++
 arch/arm/boot/dts/rk3xxx.dtsi                      |  10 +
 12 files changed, 495 insertions(+), 3 deletions(-)
 create mode 100644 arch/arm/boot/dts/rk3288-veyron-minnie.dts
 create mode 100644 arch/arm/boot/dts/rk3288-veyron-speedy.dts



From manabian at gmail.com  Sat Aug  8 15:02:41 2015
From: manabian at gmail.com (Joachim Eastwood)
Date: Sun,  9 Aug 2015 00:02:41 +0200
Subject: [PATCH] phy: lpc18xx-usb-otg: fix clock order in phy init
Message-ID: <1439071361-23105-1-git-send-email-manabian@gmail.com>

Changing the frequency of the USB clock must be done before the
PLL is powered on (prepared). This matters when the USB clock
is not setup by either boot ROM or boot loader. Reorder the
function calls to adhere to the order noted in the user manual.

Signed-off-by: Joachim Eastwood <manabian at gmail.com>
---
Hi Kishon,

Here one small fix for lpc18xx-usb-otg which I hope can go in
for 4.3. While not a critical fix it will be needed when I add
support for USB0 clock setup in Linux which I hope to add for
4.4. This patch is prerequisite for that.

Right now USB only works if clocks are setup by either boot ROM
or boot loader.

Patch based on the next branch in your phy tree.

 drivers/phy/phy-lpc18xx-usb-otg.c | 6 +++---
 1 file changed, 3 insertions(+), 3 deletions(-)

diff --git a/drivers/phy/phy-lpc18xx-usb-otg.c b/drivers/phy/phy-lpc18xx-usb-otg.c
index 3aa8e4de1b03..3b7a71eb5b7e 100644
--- a/drivers/phy/phy-lpc18xx-usb-otg.c
+++ b/drivers/phy/phy-lpc18xx-usb-otg.c
@@ -33,12 +33,12 @@ static int lpc18xx_usb_otg_phy_init(struct phy *phy)
 	struct lpc18xx_usb_otg_phy *lpc = phy_get_drvdata(phy);
 	int ret;
 
-	ret = clk_prepare(lpc->clk);
+	/* The PHY must be clocked at 480 MHz */
+	ret = clk_set_rate(lpc->clk, 480000000);
 	if (ret)
 		return ret;
 
-	/* The PHY must be clocked at 480 MHz */
-	return clk_set_rate(lpc->clk, 480000000);
+	return clk_prepare(lpc->clk);
 }
 
 static int lpc18xx_usb_otg_phy_exit(struct phy *phy)
-- 
1.8.0



From sergei.shtylyov at cogentembedded.com  Sat Aug  8 15:06:40 2015
From: sergei.shtylyov at cogentembedded.com (Sergei Shtylyov)
Date: Sun, 09 Aug 2015 01:06:40 +0300
Subject: [PATCH v2 0/2] Add R8A7794 GPIO DT support
Message-ID: <1458933.B2H9sbD3e6@wasted.cogentembedded.com>

Hello.

   Here's the set of 2 patches against Simon Horman's 'renesas.git' repo,
'renesas-devel-20150807-v4.2-rc5' tag. Here we add the GPIO device tree support
for the R8A7794 SoC.

[1/2] ARM: shmobile: r8a7794: add GPIO clocks
[2/2] ARM: shmobile: r8a7794: add GPIO DT support

WBR, Sergei



From sergei.shtylyov at cogentembedded.com  Sat Aug  8 15:06:55 2015
From: sergei.shtylyov at cogentembedded.com (Sergei Shtylyov)
Date: Sun, 09 Aug 2015 01:06:55 +0300
Subject: [PATCH v3 0/2] Add R8A7794 GPIO DT support
Message-ID: <2265315.MpjeDzrVz2@wasted.cogentembedded.com>

Hello.

   Here's the set of 2 patches against Simon Horman's 'renesas.git' repo,
'renesas-devel-20150807-v4.2-rc5' tag. Here we add the GPIO device tree support
for the R8A7794 SoC.

[1/2] ARM: shmobile: r8a7794: add GPIO clocks
[2/2] ARM: shmobile: r8a7794: add GPIO DT support

WBR, Sergei


From sergei.shtylyov at cogentembedded.com  Sat Aug  8 15:08:21 2015
From: sergei.shtylyov at cogentembedded.com (Sergei Shtylyov)
Date: Sun, 09 Aug 2015 01:08:21 +0300
Subject: [PATCH v3 1/2] ARM: shmobile: r8a7794: add GPIO clocks
In-Reply-To: <2265315.MpjeDzrVz2@wasted.cogentembedded.com>
References: <2265315.MpjeDzrVz2@wasted.cogentembedded.com>
Message-ID: <6521353.aWaEAArBdd@wasted.cogentembedded.com>

Describe the GPIO clocks in the R8A7794 device tree.

Based on the original patch by Koji Matsuoka <koji.matsuoka.xm at renesas.com>.

Signed-off-by: Sergei Shtylyov <sergei.shtylyov at cogentembedded.com>
Acked-by: Geert Uytterhoeven <geert+renesas at glider.be>
Acked-by: Laurent Pinchart <laurent.pinchart at ideasonboard.com>

---
Changes in version 3:
- refreshed the patch.

Changes in version 2:
- refreshed the patch;
- added Geert's and Laurent's ACKs.

 arch/arm/boot/dts/r8a7794.dtsi |   22 ++++++++++++++--------
 1 file changed, 14 insertions(+), 8 deletions(-)

Index: renesas/arch/arm/boot/dts/r8a7794.dtsi
===================================================================
--- renesas.orig/arch/arm/boot/dts/r8a7794.dtsi
+++ renesas/arch/arm/boot/dts/r8a7794.dtsi
@@ -749,16 +749,22 @@
 		mstp9_clks: mstp9_clks at e6150994 {
 			compatible = "renesas,r8a7794-mstp-clocks", "renesas,cpg-mstp-clocks";
 			reg = <0 0xe6150994 0 4>, <0 0xe61509a4 0 4>;
-			clocks = <&cpg_clocks R8A7794_CLK_QSPI>, <&hp_clk>, <&hp_clk>,
-				<&hp_clk>, <&hp_clk>, <&hp_clk>, <&hp_clk>;
+			clocks = <&cp_clk>, <&cp_clk>, <&cp_clk>, <&cp_clk>,
+				 <&cp_clk>, <&cp_clk>, <&cp_clk>,
+				 <&cpg_clocks R8A7794_CLK_QSPI>, <&hp_clk>, <&hp_clk>,
+				 <&hp_clk>, <&hp_clk>, <&hp_clk>, <&hp_clk>;
 			#clock-cells = <1>;
-			clock-indices = <
-				R8A7794_CLK_QSPI_MOD R8A7794_CLK_I2C5 R8A7794_CLK_I2C4
-				R8A7794_CLK_I2C3 R8A7794_CLK_I2C2 R8A7794_CLK_I2C1
-				R8A7794_CLK_I2C0
-			>;
+			clock-indices = <R8A7794_CLK_GPIO6 R8A7794_CLK_GPIO5
+					 R8A7794_CLK_GPIO4 R8A7794_CLK_GPIO3
+					 R8A7794_CLK_GPIO2 R8A7794_CLK_GPIO1
+					 R8A7794_CLK_GPIO0 R8A7794_CLK_QSPI_MOD
+					 R8A7794_CLK_I2C5 R8A7794_CLK_I2C4
+					 R8A7794_CLK_I2C3 R8A7794_CLK_I2C2
+					 R8A7794_CLK_I2C1 R8A7794_CLK_I2C0>;
 			clock-output-names =
-				"qspi_mod", "i2c5", "i2c4", "i2c3", "i2c2", "i2c1", "i2c0";
+				"gpio6", "gpio5", "gpio4", "gpio3", "gpio2",
+				"gpio1", "gpio0", "qspi_mod",
+				"i2c5", "i2c4", "i2c3", "i2c2", "i2c1", "i2c0";
 		};
 		mstp11_clks: mstp11_clks at e615099c {
 			compatible = "renesas,r8a7794-mstp-clocks", "renesas,cpg-mstp-clocks";



From sergei.shtylyov at cogentembedded.com  Sat Aug  8 15:09:31 2015
From: sergei.shtylyov at cogentembedded.com (Sergei Shtylyov)
Date: Sun, 09 Aug 2015 01:09:31 +0300
Subject: [PATCH v3 2/2] ARM: shmobile: r8a7794: add GPIO DT support
In-Reply-To: <2265315.MpjeDzrVz2@wasted.cogentembedded.com>
References: <2265315.MpjeDzrVz2@wasted.cogentembedded.com>
Message-ID: <10288801.ZnYt2TD47O@wasted.cogentembedded.com>

Describe GPIO[0-6] controllers in the R8A7794 device tree.

Based on original patch by Hisashi Nakamura <hisashi.nakamura.ak at renesas.com>.

Signed-off-by: Sergei Shtylyov <sergei.shtylyov at cogentembedded.com>
Acked-by: Geert Uytterhoeven <geert+renesas at glider.be>

---
Changes in version 3:
- added "power-domains" property to the GPIO device nodes.

Changes in version 2:
- fixed "gpio-ranges" property's last value for GPIO1/5/6;
- added Geert's ACK.

 arch/arm/boot/dts/r8a7794.dtsi |   91 +++++++++++++++++++++++++++++++++++++++++
 1 file changed, 91 insertions(+)

Index: renesas/arch/arm/boot/dts/r8a7794.dtsi
===================================================================
--- renesas.orig/arch/arm/boot/dts/r8a7794.dtsi
+++ renesas/arch/arm/boot/dts/r8a7794.dtsi
@@ -50,6 +50,97 @@
 		interrupts = <1 9 (GIC_CPU_MASK_SIMPLE(2) | IRQ_TYPE_LEVEL_HIGH)>;
 	};
 
+	gpio0: gpio at e6050000 {
+		compatible = "renesas,gpio-r8a7794", "renesas,gpio-rcar";
+		reg = <0 0xe6050000 0 0x50>;
+		interrupts = <0 4 IRQ_TYPE_LEVEL_HIGH>;
+		#gpio-cells = <2>;
+		gpio-controller;
+		gpio-ranges = <&pfc 0 0 32>;
+		#interrupt-cells = <2>;
+		interrupt-controller;
+		clocks = <&mstp9_clks R8A7794_CLK_GPIO0>;
+		power-domains = <&cpg_clocks>;
+	};
+
+	gpio1: gpio at e6051000 {
+		compatible = "renesas,gpio-r8a7794", "renesas,gpio-rcar";
+		reg = <0 0xe6051000 0 0x50>;
+		interrupts = <0 5 IRQ_TYPE_LEVEL_HIGH>;
+		#gpio-cells = <2>;
+		gpio-controller;
+		gpio-ranges = <&pfc 0 32 26>;
+		#interrupt-cells = <2>;
+		interrupt-controller;
+		clocks = <&mstp9_clks R8A7794_CLK_GPIO1>;
+		power-domains = <&cpg_clocks>;
+	};
+
+	gpio2: gpio at e6052000 {
+		compatible = "renesas,gpio-r8a7794", "renesas,gpio-rcar";
+		reg = <0 0xe6052000 0 0x50>;
+		interrupts = <0 6 IRQ_TYPE_LEVEL_HIGH>;
+		#gpio-cells = <2>;
+		gpio-controller;
+		gpio-ranges = <&pfc 0 64 32>;
+		#interrupt-cells = <2>;
+		interrupt-controller;
+		clocks = <&mstp9_clks R8A7794_CLK_GPIO2>;
+		power-domains = <&cpg_clocks>;
+	};
+
+	gpio3: gpio at e6053000 {
+		compatible = "renesas,gpio-r8a7794", "renesas,gpio-rcar";
+		reg = <0 0xe6053000 0 0x50>;
+		interrupts = <0 7 IRQ_TYPE_LEVEL_HIGH>;
+		#gpio-cells = <2>;
+		gpio-controller;
+		gpio-ranges = <&pfc 0 96 32>;
+		#interrupt-cells = <2>;
+		interrupt-controller;
+		clocks = <&mstp9_clks R8A7794_CLK_GPIO3>;
+		power-domains = <&cpg_clocks>;
+	};
+
+	gpio4: gpio at e6054000 {
+		compatible = "renesas,gpio-r8a7794", "renesas,gpio-rcar";
+		reg = <0 0xe6054000 0 0x50>;
+		interrupts = <0 8 IRQ_TYPE_LEVEL_HIGH>;
+		#gpio-cells = <2>;
+		gpio-controller;
+		gpio-ranges = <&pfc 0 128 32>;
+		#interrupt-cells = <2>;
+		interrupt-controller;
+		clocks = <&mstp9_clks R8A7794_CLK_GPIO4>;
+		power-domains = <&cpg_clocks>;
+	};
+
+	gpio5: gpio at e6055000 {
+		compatible = "renesas,gpio-r8a7794", "renesas,gpio-rcar";
+		reg = <0 0xe6055000 0 0x50>;
+		interrupts = <0 9 IRQ_TYPE_LEVEL_HIGH>;
+		#gpio-cells = <2>;
+		gpio-controller;
+		gpio-ranges = <&pfc 0 160 28>;
+		#interrupt-cells = <2>;
+		interrupt-controller;
+		clocks = <&mstp9_clks R8A7794_CLK_GPIO5>;
+		power-domains = <&cpg_clocks>;
+	};
+
+	gpio6: gpio at e6055400 {
+		compatible = "renesas,gpio-r8a7794", "renesas,gpio-rcar";
+		reg = <0 0xe6055400 0 0x50>;
+		interrupts = <0 10 IRQ_TYPE_LEVEL_HIGH>;
+		#gpio-cells = <2>;
+		gpio-controller;
+		gpio-ranges = <&pfc 0 192 26>;
+		#interrupt-cells = <2>;
+		interrupt-controller;
+		clocks = <&mstp9_clks R8A7794_CLK_GPIO6>;
+		power-domains = <&cpg_clocks>;
+	};
+
 	cmt0: timer at ffca0000 {
 		compatible = "renesas,cmt-48-gen2";
 		reg = <0 0xffca0000 0 0x1004>;




From gregkh at linuxfoundation.org  Sat Aug  8 15:08:49 2015
From: gregkh at linuxfoundation.org (Greg Kroah-Hartman)
Date: Sat,  8 Aug 2015 15:08:49 -0700
Subject: [PATCH 4.1 051/123] irqchip/gicv3-its: Fix mapping of LPIs to
 collections
In-Reply-To: <20150808220717.771230091@linuxfoundation.org>
References: <20150808220717.771230091@linuxfoundation.org>
Message-ID: <20150808220719.711590815@linuxfoundation.org>

4.1-stable review patch.  If anyone has any objections, please let me know.

------------------

From: Marc Zyngier <marc.zyngier at arm.com>

commit 591e5bec13f15feb13fc445b6c9c59954711c4ac upstream.

The GICv3 ITS architecture allows a given [DevID, EventID] pair to be
translated to a [LPI, Collection] pair, where DevID is the device writing
the MSI, EventID is the payload being written, LPI is the actual
interrupt number, and Collection is roughly equivalent to a target CPU.

Each LPI can be mapped to a separate collection, but the ITS driver
insists on maintaining the collection on a device basis, instead of doing
it on a per interrupt basis.

This is obviously flawed, and this patch fixes it by adding a per interrupt
index that indicates which collection number is in use.

Reported-by: Ian Campbell <ian.campbell at citrix.com>
Signed-off-by: Marc Zyngier <marc.zyngier at arm.com>
Cc: <linux-arm-kernel at lists.infradead.org>
Cc: Jason Cooper <jason at lakedaemon.net>
Link: http://lkml.kernel.org/r/1437126402-11677-1-git-send-email-marc.zyngier at arm.com
Signed-off-by: Thomas Gleixner <tglx at linutronix.de>
Signed-off-by: Greg Kroah-Hartman <gregkh at linuxfoundation.org>

---
 drivers/irqchip/irq-gic-v3-its.c |  111 ++++++++++++++++++++++++++-------------
 1 file changed, 75 insertions(+), 36 deletions(-)

--- a/drivers/irqchip/irq-gic-v3-its.c
+++ b/drivers/irqchip/irq-gic-v3-its.c
@@ -75,6 +75,13 @@ struct its_node {
 
 #define ITS_ITT_ALIGN		SZ_256
 
+struct event_lpi_map {
+	unsigned long		*lpi_map;
+	u16			*col_map;
+	irq_hw_number_t		lpi_base;
+	int			nr_lpis;
+};
+
 /*
  * The ITS view of a device - belongs to an ITS, a collection, owns an
  * interrupt translation table, and a list of interrupts.
@@ -82,11 +89,8 @@ struct its_node {
 struct its_device {
 	struct list_head	entry;
 	struct its_node		*its;
-	struct its_collection	*collection;
+	struct event_lpi_map	event_map;
 	void			*itt;
-	unsigned long		*lpi_map;
-	irq_hw_number_t		lpi_base;
-	int			nr_lpis;
 	u32			nr_ites;
 	u32			device_id;
 };
@@ -99,6 +103,14 @@ static struct rdists *gic_rdists;
 #define gic_data_rdist()		(raw_cpu_ptr(gic_rdists->rdist))
 #define gic_data_rdist_rd_base()	(gic_data_rdist()->rd_base)
 
+static struct its_collection *dev_event_to_col(struct its_device *its_dev,
+					       u32 event)
+{
+	struct its_node *its = its_dev->its;
+
+	return its->collections + its_dev->event_map.col_map[event];
+}
+
 /*
  * ITS command descriptors - parameters to be encoded in a command
  * block.
@@ -134,7 +146,7 @@ struct its_cmd_desc {
 		struct {
 			struct its_device *dev;
 			struct its_collection *col;
-			u32 id;
+			u32 event_id;
 		} its_movi_cmd;
 
 		struct {
@@ -241,7 +253,7 @@ static struct its_collection *its_build_
 
 	its_fixup_cmd(cmd);
 
-	return desc->its_mapd_cmd.dev->collection;
+	return NULL;
 }
 
 static struct its_collection *its_build_mapc_cmd(struct its_cmd_block *cmd,
@@ -260,52 +272,72 @@ static struct its_collection *its_build_
 static struct its_collection *its_build_mapvi_cmd(struct its_cmd_block *cmd,
 						  struct its_cmd_desc *desc)
 {
+	struct its_collection *col;
+
+	col = dev_event_to_col(desc->its_mapvi_cmd.dev,
+			       desc->its_mapvi_cmd.event_id);
+
 	its_encode_cmd(cmd, GITS_CMD_MAPVI);
 	its_encode_devid(cmd, desc->its_mapvi_cmd.dev->device_id);
 	its_encode_event_id(cmd, desc->its_mapvi_cmd.event_id);
 	its_encode_phys_id(cmd, desc->its_mapvi_cmd.phys_id);
-	its_encode_collection(cmd, desc->its_mapvi_cmd.dev->collection->col_id);
+	its_encode_collection(cmd, col->col_id);
 
 	its_fixup_cmd(cmd);
 
-	return desc->its_mapvi_cmd.dev->collection;
+	return col;
 }
 
 static struct its_collection *its_build_movi_cmd(struct its_cmd_block *cmd,
 						 struct its_cmd_desc *desc)
 {
+	struct its_collection *col;
+
+	col = dev_event_to_col(desc->its_movi_cmd.dev,
+			       desc->its_movi_cmd.event_id);
+
 	its_encode_cmd(cmd, GITS_CMD_MOVI);
 	its_encode_devid(cmd, desc->its_movi_cmd.dev->device_id);
-	its_encode_event_id(cmd, desc->its_movi_cmd.id);
+	its_encode_event_id(cmd, desc->its_movi_cmd.event_id);
 	its_encode_collection(cmd, desc->its_movi_cmd.col->col_id);
 
 	its_fixup_cmd(cmd);
 
-	return desc->its_movi_cmd.dev->collection;
+	return col;
 }
 
 static struct its_collection *its_build_discard_cmd(struct its_cmd_block *cmd,
 						    struct its_cmd_desc *desc)
 {
+	struct its_collection *col;
+
+	col = dev_event_to_col(desc->its_discard_cmd.dev,
+			       desc->its_discard_cmd.event_id);
+
 	its_encode_cmd(cmd, GITS_CMD_DISCARD);
 	its_encode_devid(cmd, desc->its_discard_cmd.dev->device_id);
 	its_encode_event_id(cmd, desc->its_discard_cmd.event_id);
 
 	its_fixup_cmd(cmd);
 
-	return desc->its_discard_cmd.dev->collection;
+	return col;
 }
 
 static struct its_collection *its_build_inv_cmd(struct its_cmd_block *cmd,
 						struct its_cmd_desc *desc)
 {
+	struct its_collection *col;
+
+	col = dev_event_to_col(desc->its_inv_cmd.dev,
+			       desc->its_inv_cmd.event_id);
+
 	its_encode_cmd(cmd, GITS_CMD_INV);
 	its_encode_devid(cmd, desc->its_inv_cmd.dev->device_id);
 	its_encode_event_id(cmd, desc->its_inv_cmd.event_id);
 
 	its_fixup_cmd(cmd);
 
-	return desc->its_inv_cmd.dev->collection;
+	return col;
 }
 
 static struct its_collection *its_build_invall_cmd(struct its_cmd_block *cmd,
@@ -497,7 +529,7 @@ static void its_send_movi(struct its_dev
 
 	desc.its_movi_cmd.dev = dev;
 	desc.its_movi_cmd.col = col;
-	desc.its_movi_cmd.id = id;
+	desc.its_movi_cmd.event_id = id;
 
 	its_send_single_command(dev->its, its_build_movi_cmd, &desc);
 }
@@ -528,7 +560,7 @@ static void its_send_invall(struct its_n
 static inline u32 its_get_event_id(struct irq_data *d)
 {
 	struct its_device *its_dev = irq_data_get_irq_chip_data(d);
-	return d->hwirq - its_dev->lpi_base;
+	return d->hwirq - its_dev->event_map.lpi_base;
 }
 
 static void lpi_set_config(struct irq_data *d, bool enable)
@@ -583,7 +615,7 @@ static int its_set_affinity(struct irq_d
 
 	target_col = &its_dev->its->collections[cpu];
 	its_send_movi(its_dev, target_col, id);
-	its_dev->collection = target_col;
+	its_dev->event_map.col_map[id] = cpu;
 
 	return IRQ_SET_MASK_OK_DONE;
 }
@@ -713,8 +745,10 @@ out:
 	return bitmap;
 }
 
-static void its_lpi_free(unsigned long *bitmap, int base, int nr_ids)
+static void its_lpi_free(struct event_lpi_map *map)
 {
+	int base = map->lpi_base;
+	int nr_ids = map->nr_lpis;
 	int lpi;
 
 	spin_lock(&lpi_lock);
@@ -731,7 +765,8 @@ static void its_lpi_free(unsigned long *
 
 	spin_unlock(&lpi_lock);
 
-	kfree(bitmap);
+	kfree(map->lpi_map);
+	kfree(map->col_map);
 }
 
 /*
@@ -1099,11 +1134,11 @@ static struct its_device *its_create_dev
 	struct its_device *dev;
 	unsigned long *lpi_map;
 	unsigned long flags;
+	u16 *col_map = NULL;
 	void *itt;
 	int lpi_base;
 	int nr_lpis;
 	int nr_ites;
-	int cpu;
 	int sz;
 
 	dev = kzalloc(sizeof(*dev), GFP_KERNEL);
@@ -1117,20 +1152,24 @@ static struct its_device *its_create_dev
 	sz = max(sz, ITS_ITT_ALIGN) + ITS_ITT_ALIGN - 1;
 	itt = kzalloc(sz, GFP_KERNEL);
 	lpi_map = its_lpi_alloc_chunks(nvecs, &lpi_base, &nr_lpis);
+	if (lpi_map)
+		col_map = kzalloc(sizeof(*col_map) * nr_lpis, GFP_KERNEL);
 
-	if (!dev || !itt || !lpi_map) {
+	if (!dev || !itt || !lpi_map || !col_map) {
 		kfree(dev);
 		kfree(itt);
 		kfree(lpi_map);
+		kfree(col_map);
 		return NULL;
 	}
 
 	dev->its = its;
 	dev->itt = itt;
 	dev->nr_ites = nr_ites;
-	dev->lpi_map = lpi_map;
-	dev->lpi_base = lpi_base;
-	dev->nr_lpis = nr_lpis;
+	dev->event_map.lpi_map = lpi_map;
+	dev->event_map.col_map = col_map;
+	dev->event_map.lpi_base = lpi_base;
+	dev->event_map.nr_lpis = nr_lpis;
 	dev->device_id = dev_id;
 	INIT_LIST_HEAD(&dev->entry);
 
@@ -1138,10 +1177,6 @@ static struct its_device *its_create_dev
 	list_add(&dev->entry, &its->its_device_list);
 	raw_spin_unlock_irqrestore(&its->lock, flags);
 
-	/* Bind the device to the first possible CPU */
-	cpu = cpumask_first(cpu_online_mask);
-	dev->collection = &its->collections[cpu];
-
 	/* Map device to its ITT */
 	its_send_mapd(dev, 1);
 
@@ -1163,12 +1198,13 @@ static int its_alloc_device_irq(struct i
 {
 	int idx;
 
-	idx = find_first_zero_bit(dev->lpi_map, dev->nr_lpis);
-	if (idx == dev->nr_lpis)
+	idx = find_first_zero_bit(dev->event_map.lpi_map,
+				  dev->event_map.nr_lpis);
+	if (idx == dev->event_map.nr_lpis)
 		return -ENOSPC;
 
-	*hwirq = dev->lpi_base + idx;
-	set_bit(idx, dev->lpi_map);
+	*hwirq = dev->event_map.lpi_base + idx;
+	set_bit(idx, dev->event_map.lpi_map);
 
 	return 0;
 }
@@ -1288,7 +1324,8 @@ static int its_irq_domain_alloc(struct i
 		irq_domain_set_hwirq_and_chip(domain, virq + i,
 					      hwirq, &its_irq_chip, its_dev);
 		dev_dbg(info->scratchpad[1].ptr, "ID:%d pID:%d vID:%d\n",
-			(int)(hwirq - its_dev->lpi_base), (int)hwirq, virq + i);
+			(int)(hwirq - its_dev->event_map.lpi_base),
+			(int)hwirq, virq + i);
 	}
 
 	return 0;
@@ -1300,6 +1337,9 @@ static void its_irq_domain_activate(stru
 	struct its_device *its_dev = irq_data_get_irq_chip_data(d);
 	u32 event = its_get_event_id(d);
 
+	/* Bind the LPI to the first possible CPU */
+	its_dev->event_map.col_map[event] = cpumask_first(cpu_online_mask);
+
 	/* Map the GIC IRQ and event to the device */
 	its_send_mapvi(its_dev, d->hwirq, event);
 }
@@ -1327,17 +1367,16 @@ static void its_irq_domain_free(struct i
 		u32 event = its_get_event_id(data);
 
 		/* Mark interrupt index as unused */
-		clear_bit(event, its_dev->lpi_map);
+		clear_bit(event, its_dev->event_map.lpi_map);
 
 		/* Nuke the entry in the domain */
 		irq_domain_reset_irq_data(data);
 	}
 
 	/* If all interrupts have been freed, start mopping the floor */
-	if (bitmap_empty(its_dev->lpi_map, its_dev->nr_lpis)) {
-		its_lpi_free(its_dev->lpi_map,
-			     its_dev->lpi_base,
-			     its_dev->nr_lpis);
+	if (bitmap_empty(its_dev->event_map.lpi_map,
+			 its_dev->event_map.nr_lpis)) {
+		its_lpi_free(&its_dev->event_map);
 
 		/* Unmap device/itt */
 		its_send_mapd(its_dev, 0);




From sergei.shtylyov at cogentembedded.com  Sat Aug  8 15:24:49 2015
From: sergei.shtylyov at cogentembedded.com (Sergei Shtylyov)
Date: Sun, 09 Aug 2015 01:24:49 +0300
Subject: [PATCH 0/2] Add R8A7794/SILK QSPI DT support
Message-ID: <1898263.zrOs5SAUTS@wasted.cogentembedded.com>

Hello.

   Here's the set of 2 patches against Simon Horman's 'renesas.git' repo,
'renesas-devel-20150807-v4.2-rc5' tag plus the R8A7794 GPIO patches I've just
posted. Here we add the QSPI device tree support for the R8A7794/SILK board.

[1/2] ARM: shmobile: r8a7794: add QSPI DT support
[2/2] ARM: shmobile: silk: add QSPI DT support

WBR, Sergei



From sergei.shtylyov at cogentembedded.com  Sat Aug  8 15:26:10 2015
From: sergei.shtylyov at cogentembedded.com (Sergei Shtylyov)
Date: Sun, 09 Aug 2015 01:26:10 +0300
Subject: [PATCH 1/2] ARM: shmobile: r8a7794: add QSPI DT support
In-Reply-To: <1898263.zrOs5SAUTS@wasted.cogentembedded.com>
References: <1898263.zrOs5SAUTS@wasted.cogentembedded.com>
Message-ID: <5339616.vfIYf6AeR8@wasted.cogentembedded.com>

Define the generic R8A7794 part of the QSPI device node.

Based on original patch by Hisashi Nakamura <hisashi.nakamura.ak at renesas.com>.

Signed-off-by: Sergei Shtylyov <sergei.shtylyov at cogentembedded.com>

---
 arch/arm/boot/dts/r8a7794.dtsi |   18 ++++++++++++++++++
 1 file changed, 18 insertions(+)

Index: renesas/arch/arm/boot/dts/r8a7794.dtsi
===================================================================
--- renesas.orig/arch/arm/boot/dts/r8a7794.dtsi
+++ renesas/arch/arm/boot/dts/r8a7794.dtsi
@@ -19,6 +19,10 @@
 	#address-cells = <2>;
 	#size-cells = <2>;
 
+	aliases {
+		spi0 = &qspi;
+	};
+
 	cpus {
 		#address-cells = <1>;
 		#size-cells = <0>;
@@ -537,6 +541,20 @@
 		status = "disabled";
 	};
 
+	qspi: spi at e6b10000 {
+		compatible = "renesas,qspi-r8a7794", "renesas,qspi";
+		reg = <0 0xe6b10000 0 0x2c>;
+		interrupts = <0 184 IRQ_TYPE_LEVEL_HIGH>;
+		clocks = <&mstp9_clks R8A7794_CLK_QSPI_MOD>;
+		power-domains = <&cpg_clocks>;
+		dmas = <&dmac0 0x17>, <&dmac0 0x18>;
+		dma-names = "tx", "rx";
+		num-cs = <1>;
+		#address-cells = <1>;
+		#size-cells = <0>;
+		status = "disabled";
+	};
+
 	clocks {
 		#address-cells = <2>;
 		#size-cells = <2>;



From sergei.shtylyov at cogentembedded.com  Sat Aug  8 15:27:14 2015
From: sergei.shtylyov at cogentembedded.com (Sergei Shtylyov)
Date: Sun, 09 Aug 2015 01:27:14 +0300
Subject: [PATCH 2/2] ARM: shmobile: silk: add QSPI DT support
In-Reply-To: <1898263.zrOs5SAUTS@wasted.cogentembedded.com>
References: <1898263.zrOs5SAUTS@wasted.cogentembedded.com>
Message-ID: <1768974.jEFIAaInqd@wasted.cogentembedded.com>

Define the SILK board dependent part of the QSPI device node.
Add device nodes  for Spansion  S25FL512S SPI flash and MTD partitions on it.

Based on the original patch by Vladimir Barinov
<vladimir.barinov at cogentembedded.com>.

Signed-off-by: Sergei Shtylyov <sergei.shtylyov at cogentembedded.com>

---
 arch/arm/boot/dts/r8a7794-silk.dts |   40 +++++++++++++++++++++++++++++++++++++
 1 file changed, 40 insertions(+)

Index: renesas/arch/arm/boot/dts/r8a7794-silk.dts
===================================================================
--- renesas.orig/arch/arm/boot/dts/r8a7794-silk.dts
+++ renesas/arch/arm/boot/dts/r8a7794-silk.dts
@@ -65,6 +65,11 @@
 		renesas,groups = "mmc_data8", "mmc_ctrl";
 		renesas,function = "mmc";
 	};
+
+	qspi_pins: spi0 {
+		renesas,groups = "qspi_ctrl", "qspi_data4";
+		renesas,function = "qspi";
+	};
 };
 
 &scif2 {
@@ -100,3 +105,38 @@
 	non-removable;
 	status = "okay";
 };
+
+&qspi {
+	pinctrl-0 = <&qspi_pins>;
+	pinctrl-names = "default";
+
+	status = "okay";
+
+	flash at 0 {
+		#address-cells = <1>;
+		#size-cells = <1>;
+		compatible = "spansion,s25fl512s";
+		reg = <0>;
+		spi-max-frequency = <30000000>;
+		spi-tx-bus-width = <4>;
+		spi-rx-bus-width = <4>;
+		m25p,fast-read;
+		spi-cpol;
+		spi-cpha;
+
+		partition at 0 {
+			label = "loader";
+			reg = <0x00000000 0x00040000>;
+			read-only;
+		};
+		partition at 40000 {
+			label = "user";
+			reg = <0x00040000 0x00400000>;
+			read-only;
+		};
+		partition at 440000 {
+			label = "flash";
+			reg = <0x00440000 0x03bc0000>;
+		};
+	};
+};



From paul.gortmaker at windriver.com  Sat Aug  8 17:51:32 2015
From: paul.gortmaker at windriver.com (Paul Gortmaker)
Date: Sat, 8 Aug 2015 20:51:32 -0400
Subject: [PATCH 0/5] drivers/tty: make more bool drivers explicitly non-modular
Message-ID: <1439081497-14986-1-git-send-email-paul.gortmaker@windriver.com>

This second set of patches to drivers/tty steps outside of the serial
dir, and an improved auditing finds two more serial drivers pretending
to be modular that really are not.

The reasoning for doing this is the same as the first set[1] of patches
and is largely copied below:

  In the previous merge window, we made changes to allow better
  delineation between modular and non-modular code in commit
  0fd972a7d91d6e15393c449492a04d94c0b89351 ("module: relocate module_init
  from init.h to module.h").  This allows us to now ensure module code
  looks modular and non-modular code does not accidentally look modular
  without suffering build breakage.
  
  Here we target code that is, by nature of their Kconfig settings, only
  available to be built-in, but implicitly presenting itself as being
  possibly modular by way of using modular headers, macros, and functions.
  
  The goal here is to remove that illusion of modularity from these
  drivers, but in a way that leaves the actual runtime unchanged.
  In doing so, we remove code that has never been tested and adds
  no value to the tree.  And we begin the process of expecting a
  level of consistency between the Kconfig of a driver and the code
  that the driver uses.
  
Build tested for allyesconfig on x86_64, and ARM for lpc81xx, and powerpc
for hvc_console and mpsc, layered onto tty/tty-next as a baseline.

Paul.

[1] https://lkml.kernel.org/r/1437530538-5078-1-git-send-email-paul.gortmaker at windriver.com
--

Cc: Greg Kroah-Hartman <gregkh at linuxfoundation.org>
Cc: Jiri Slaby <jslaby at suse.com>
Cc: Joachim Eastwood <manabian at gmail.com>
Cc: linux-arm-kernel at lists.infradead.org
Cc: linuxppc-dev at lists.ozlabs.org
Cc: linux-serial at vger.kernel.org

Paul Gortmaker (5):
  drivers/tty: make pty.c slightly more explicitly non-modular
  drivers/tty: make sysrq.c slightly more explicitly non-modular
  drivers/tty: make hvc_console.c explicitly non-modular
  drivers/tty: make serial/mpsc.c driver explicitly non-modular
  drivers/tty: make serial 8250_lpc18xx.c explicitly non-modular

 drivers/tty/hvc/hvc_console.c          | 18 +----------------
 drivers/tty/pty.c                      |  7 +++++--
 drivers/tty/serial/8250/8250_lpc18xx.c | 19 ++++--------------
 drivers/tty/serial/mpsc.c              | 36 +++-------------------------------
 drivers/tty/sysrq.c                    |  6 +++++-
 5 files changed, 18 insertions(+), 68 deletions(-)

-- 
2.5.0


From paul.gortmaker at windriver.com  Sat Aug  8 17:51:37 2015
From: paul.gortmaker at windriver.com (Paul Gortmaker)
Date: Sat, 8 Aug 2015 20:51:37 -0400
Subject: [PATCH 5/5] drivers/tty: make serial 8250_lpc18xx.c explicitly
 non-modular
In-Reply-To: <1439081497-14986-1-git-send-email-paul.gortmaker@windriver.com>
References: <1439081497-14986-1-git-send-email-paul.gortmaker@windriver.com>
Message-ID: <1439081497-14986-6-git-send-email-paul.gortmaker@windriver.com>

The Kconfig currently controlling compilation of this code is:

8250/Kconfig:config SERIAL_8250_LPC18XX
8250/Kconfig:        bool "NXP LPC18xx/43xx serial port support"

...meaning that it currently is not being built as a module by anyone.

Lets remove the modular code that is essentially orphaned, so that
when reading the driver there is no doubt it is builtin-only.

Since module_platform_driver() uses the same init level priority as
builtin_platform_driver() the init ordering remains unchanged with
this commit.

Also note that MODULE_DEVICE_TABLE is a no-op for non-modular code.

We leave some tags like MODULE_AUTHOR for documentation purposes.

Cc: Greg Kroah-Hartman <gregkh at linuxfoundation.org>
Cc: Jiri Slaby <jslaby at suse.com>
Cc: Joachim Eastwood <manabian at gmail.com>
Cc: linux-serial at vger.kernel.org
Cc: linux-arm-kernel at lists.infradead.org
Signed-off-by: Paul Gortmaker <paul.gortmaker at windriver.com>
---
 drivers/tty/serial/8250/8250_lpc18xx.c | 19 ++++---------------
 1 file changed, 4 insertions(+), 15 deletions(-)

diff --git a/drivers/tty/serial/8250/8250_lpc18xx.c b/drivers/tty/serial/8250/8250_lpc18xx.c
index 99cd478851ff..f5112bee1ab6 100644
--- a/drivers/tty/serial/8250/8250_lpc18xx.c
+++ b/drivers/tty/serial/8250/8250_lpc18xx.c
@@ -15,7 +15,7 @@
 
 #include <linux/clk.h>
 #include <linux/io.h>
-#include <linux/module.h>
+#include <linux/init.h>
 #include <linux/of.h>
 #include <linux/platform_device.h>
 
@@ -198,33 +198,22 @@ dis_clk_reg:
 	return ret;
 }
 
-static int lpc18xx_serial_remove(struct platform_device *pdev)
-{
-	struct lpc18xx_uart_data *data = platform_get_drvdata(pdev);
-
-	serial8250_unregister_port(data->line);
-	clk_disable_unprepare(data->clk_uart);
-	clk_disable_unprepare(data->clk_reg);
-
-	return 0;
-}
-
 static const struct of_device_id lpc18xx_serial_match[] = {
 	{ .compatible = "nxp,lpc1850-uart" },
 	{ },
 };
-MODULE_DEVICE_TABLE(of, lpc18xx_serial_match);
 
 static struct platform_driver lpc18xx_serial_driver = {
 	.probe  = lpc18xx_serial_probe,
-	.remove = lpc18xx_serial_remove,
 	.driver = {
 		.name = "lpc18xx-uart",
 		.of_match_table = lpc18xx_serial_match,
 	},
 };
-module_platform_driver(lpc18xx_serial_driver);
+builtin_platform_driver(lpc18xx_serial_driver);
 
+/*
 MODULE_AUTHOR("Joachim Eastwood <manabian at gmail.com>");
 MODULE_DESCRIPTION("Serial port driver NXP LPC18xx/43xx devices");
 MODULE_LICENSE("GPL v2");
+*/
-- 
2.5.0



From timur at codeaurora.org  Sat Aug  8 17:59:00 2015
From: timur at codeaurora.org (Timur Tabi)
Date: Sat, 8 Aug 2015 17:59:00 -0700
Subject: [PATCH v5 05/11] drivers: PL011: refactor pl011_probe()
In-Reply-To: <1432225584-4655-6-git-send-email-andre.przywara@arm.com>
References: <1432225584-4655-1-git-send-email-andre.przywara@arm.com>
 <1432225584-4655-6-git-send-email-andre.przywara@arm.com>
Message-ID: <CAOZdJXVgRQZhEfYY9YdpiQ=n1D56yYL84s42V4hd2=YX2k48ZA@mail.gmail.com>

On Thu, May 21, 2015 at 9:26 AM, Andre Przywara <andre.przywara at arm.com> wrote:
> +static int pl011_probe(struct amba_device *dev, const struct amba_id *id)
> +{
> +       struct uart_amba_port *uap;
> +       struct vendor_data *vendor = id->data;
> +       int portnr, ret;
> +
> +       portnr = pl011_find_free_port();
> +       if (portnr < 0)
> +               return portnr;
> +
> +       uap = devm_kzalloc(&dev->dev, sizeof(struct uart_amba_port),
> +                          GFP_KERNEL);
> +       if (!uap)
> +               return -ENOMEM;
> +
> +       uap->clk = devm_clk_get(&dev->dev, NULL);
> +       if (IS_ERR(uap->clk))
> +               return PTR_ERR(uap->clk);
> +
> +       = vendor;

I'm having trouble with this.  Specifically, I can't get SBSA early
console to work, because uap->vendor is uninitialized when
pl011_early_write() is called.

I don't have a non-SBSA system to test, but looking at the code, I'm
not sure how early console is supposed to work any more.  In both SBSA
and non-SBSA cases, uap->vendor is not initialized until the probe
function is called.  Isn't that too late?  I thought early console was
supposed to be running before the driver is probed.

If I make this change, then early console works on SBSA systems (with
earlycon=pl011,<address>).  But of course, this only works for SBSA
and breaks regular PL011.

--- a/drivers/tty/serial/amba-pl011.c
+++ b/drivers/tty/serial/amba-pl011.c
@@ -2326,9 +2326,15 @@ static void pl011_early_write(struct console *con, const
 static int __init pl011_early_console_setup(struct earlycon_device *device,
                                            const char *opt)
 {
+       struct uart_amba_port *uap =
+           container_of(&device->port, struct uart_amba_port, port);
+
        if (!device->port.membase)
                return -ENODEV;
+       if (!uap->vendor)
+               uap->vendor = &vendor_sbsa;
+
        device->con->write = pl011_early_write;
        return 0;
 }

-- 
Qualcomm Innovation Center, Inc.
The Qualcomm Innovation Center, Inc. is a member of the Code Aurora Forum,
a Linux Foundation Collaborative Project.


From emunson at akamai.com  Sat Aug  8 22:22:52 2015
From: emunson at akamai.com (Eric B Munson)
Date: Sun,  9 Aug 2015 01:22:52 -0400
Subject: [PATCH v7 2/6] mm: mlock: Add new mlock system call
In-Reply-To: <1439097776-27695-1-git-send-email-emunson@akamai.com>
References: <1439097776-27695-1-git-send-email-emunson@akamai.com>
Message-ID: <1439097776-27695-3-git-send-email-emunson@akamai.com>

With the refactored mlock code, introduce a new system call for mlock.
The new call will allow the user to specify what lock states are being
added.  mlock2 is trivial at the moment, but a follow on patch will add
a new mlock state making it useful.

Signed-off-by: Eric B Munson <emunson at akamai.com>
Acked-by: Vlastimil Babka <vbabka at suse.cz>
Cc: Michal Hocko <mhocko at suse.cz>
Cc: Vlastimil Babka <vbabka at suse.cz>
Cc: Heiko Carstens <heiko.carstens at de.ibm.com>
Cc: Geert Uytterhoeven <geert at linux-m68k.org>
Cc: Catalin Marinas <catalin.marinas at arm.com>
Cc: Stephen Rothwell <sfr at canb.auug.org.au>
Cc: Guenter Roeck <linux at roeck-us.net>
Cc: Andrea Arcangeli <aarcange at redhat.com>
Cc: linux-alpha at vger.kernel.org
Cc: linux-kernel at vger.kernel.org
Cc: linux-arm-kernel at lists.infradead.org
Cc: adi-buildroot-devel at lists.sourceforge.net
Cc: linux-cris-kernel at axis.com
Cc: linux-ia64 at vger.kernel.org
Cc: linux-m68k at lists.linux-m68k.org
Cc: linux-am33-list at redhat.com
Cc: linux-parisc at vger.kernel.org
Cc: linuxppc-dev at lists.ozlabs.org
Cc: linux-s390 at vger.kernel.org
Cc: linux-sh at vger.kernel.org
Cc: sparclinux at vger.kernel.org
Cc: linux-xtensa at linux-xtensa.org
Cc: linux-api at vger.kernel.org
Cc: linux-arch at vger.kernel.org
Cc: linux-mm at kvack.org
---
 arch/x86/entry/syscalls/syscall_32.tbl | 1 +
 arch/x86/entry/syscalls/syscall_64.tbl | 1 +
 include/linux/syscalls.h               | 2 ++
 include/uapi/asm-generic/unistd.h      | 4 +++-
 kernel/sys_ni.c                        | 1 +
 mm/mlock.c                             | 8 ++++++++
 6 files changed, 16 insertions(+), 1 deletion(-)

diff --git a/arch/x86/entry/syscalls/syscall_32.tbl b/arch/x86/entry/syscalls/syscall_32.tbl
index ef8187f..8e06da6 100644
--- a/arch/x86/entry/syscalls/syscall_32.tbl
+++ b/arch/x86/entry/syscalls/syscall_32.tbl
@@ -365,3 +365,4 @@
 356	i386	memfd_create		sys_memfd_create
 357	i386	bpf			sys_bpf
 358	i386	execveat		sys_execveat			stub32_execveat
+360	i386	mlock2			sys_mlock2
diff --git a/arch/x86/entry/syscalls/syscall_64.tbl b/arch/x86/entry/syscalls/syscall_64.tbl
index 9ef32d5..67601e7 100644
--- a/arch/x86/entry/syscalls/syscall_64.tbl
+++ b/arch/x86/entry/syscalls/syscall_64.tbl
@@ -329,6 +329,7 @@
 320	common	kexec_file_load		sys_kexec_file_load
 321	common	bpf			sys_bpf
 322	64	execveat		stub_execveat
+324	common	mlock2			sys_mlock2
 
 #
 # x32-specific system call numbers start at 512 to avoid cache impact
diff --git a/include/linux/syscalls.h b/include/linux/syscalls.h
index b45c45b..56a3d59 100644
--- a/include/linux/syscalls.h
+++ b/include/linux/syscalls.h
@@ -884,4 +884,6 @@ asmlinkage long sys_execveat(int dfd, const char __user *filename,
 			const char __user *const __user *argv,
 			const char __user *const __user *envp, int flags);
 
+asmlinkage long sys_mlock2(unsigned long start, size_t len, int flags);
+
 #endif
diff --git a/include/uapi/asm-generic/unistd.h b/include/uapi/asm-generic/unistd.h
index e016bd9..14a6013 100644
--- a/include/uapi/asm-generic/unistd.h
+++ b/include/uapi/asm-generic/unistd.h
@@ -709,9 +709,11 @@ __SYSCALL(__NR_memfd_create, sys_memfd_create)
 __SYSCALL(__NR_bpf, sys_bpf)
 #define __NR_execveat 281
 __SC_COMP(__NR_execveat, sys_execveat, compat_sys_execveat)
+#define __NR_mlock2 282
+__SYSCALL(__NR_mlock2, sys_mlock2)
 
 #undef __NR_syscalls
-#define __NR_syscalls 282
+#define __NR_syscalls 283
 
 /*
  * All syscalls below here should go away really,
diff --git a/kernel/sys_ni.c b/kernel/sys_ni.c
index 7995ef5..4818b71 100644
--- a/kernel/sys_ni.c
+++ b/kernel/sys_ni.c
@@ -193,6 +193,7 @@ cond_syscall(sys_mlock);
 cond_syscall(sys_munlock);
 cond_syscall(sys_mlockall);
 cond_syscall(sys_munlockall);
+cond_syscall(sys_mlock2);
 cond_syscall(sys_mincore);
 cond_syscall(sys_madvise);
 cond_syscall(sys_mremap);
diff --git a/mm/mlock.c b/mm/mlock.c
index 5692ee5..3094f27 100644
--- a/mm/mlock.c
+++ b/mm/mlock.c
@@ -643,6 +643,14 @@ SYSCALL_DEFINE2(mlock, unsigned long, start, size_t, len)
 	return do_mlock(start, len, VM_LOCKED);
 }
 
+SYSCALL_DEFINE3(mlock2, unsigned long, start, size_t, len, int, flags)
+{
+	if (flags)
+		return -EINVAL;
+
+	return do_mlock(start, len, VM_LOCKED);
+}
+
 SYSCALL_DEFINE2(munlock, unsigned long, start, size_t, len)
 {
 	int ret;
-- 
1.9.1



From wsa at the-dreams.de  Sun Aug  9 00:43:12 2015
From: wsa at the-dreams.de (Wolfram Sang)
Date: Sun, 9 Aug 2015 09:43:12 +0200
Subject: [PATCH] i2c: cadence: set THIS_MODULE to the owner of the adapter
In-Reply-To: <1437462876-13755-1-git-send-email-yamada.masahiro@socionext.com>
References: <1437462876-13755-1-git-send-email-yamada.masahiro@socionext.com>
Message-ID: <20150809074312.GD1526@katana>

On Tue, Jul 21, 2015 at 04:14:36PM +0900, Masahiro Yamada wrote:
> The owner of the adapter is missing, while this driver is tristate.
> 
> Signed-off-by: Masahiro Yamada <yamada.masahiro at socionext.com>

Applied to for-next, thanks!

-------------- next part --------------
A non-text attachment was scrubbed...
Name: signature.asc
Type: application/pgp-signature
Size: 819 bytes
Desc: Digital signature
URL: <http://lists.infradead.org/pipermail/linux-arm-kernel/attachments/20150809/82a0004f/attachment.sig>

From Suravee.Suthikulpanit at amd.com  Sun Aug  9 01:02:33 2015
From: Suravee.Suthikulpanit at amd.com (Suravee Suthikulpanit)
Date: Sun, 9 Aug 2015 15:02:33 +0700
Subject: [PATCH v4 08/10] ACPI: GIC: Add ACPI helper functions to query
 irq-domain tokens for for GIC MSI and ITS
In-Reply-To: <55C0C5DD.6090607@arm.com>
References: <1438164539-29256-1-git-send-email-hanjun.guo@linaro.org>
 <1438164539-29256-9-git-send-email-hanjun.guo@linaro.org>
 <55C0C5DD.6090607@arm.com>
Message-ID: <55C70919.2050805@amd.com>

Hi Marc,

Sorry for late reply. Please see my comments below.

On 8/4/15 21:02, Marc Zyngier wrote:
> On 29/07/15 11:08, Hanjun Guo wrote:
>> From: Suravee Suthikulpanit <Suravee.Suthikulpanit at amd.com>
>>
>> This patch introduces acpi_gic_get_msi_token(), which returns irq-domain
>> token that can be used to look up MSI doamin of a device.
>> In both GIC MSI and ITS cases, the base_address specified in the GIC MSI
>> or GIC ITS structure is used as a token for MSI domain.
>>
>> In addition, this patch also provides low-level helper functions to parse
>> and query GIC MSI structure and GIC ITS from MADT. Once parsed, it keeps
>> a copy of the structure for use in subsequent queries to avoid having
>> to map and parse MADT multiple times.
>>
>> Signed-off-by: Suravee Suthikulpanit <Suravee.Suthikulpanit at amd.com>
>> Signed-off-by: Hanjun Guo <hanjun.guo at linaro.org>
>> ---
>>   drivers/acpi/Makefile   |   1 +
>>   drivers/acpi/acpi_gic.c | 234 ++++++++++++++++++++++++++++++++++++++++++++++++
>>   include/acpi/acpi_gic.h |  23 +++++
>>   include/linux/acpi.h    |   1 +
>>   4 files changed, 259 insertions(+)
>>   create mode 100644 drivers/acpi/acpi_gic.c
>>   create mode 100644 include/acpi/acpi_gic.h
>>
>> diff --git a/drivers/acpi/Makefile b/drivers/acpi/Makefile
>> index 8321430..def54b9 100644
>> --- a/drivers/acpi/Makefile
>> +++ b/drivers/acpi/Makefile
>> @@ -54,6 +54,7 @@ acpi-$(CONFIG_ACPI_NUMA)	+= numa.o
>>   acpi-$(CONFIG_ACPI_PROCFS_POWER) += cm_sbs.o
>>   acpi-y				+= acpi_lpat.o
>>   acpi-$(CONFIG_ACPI_GENERIC_GSI) += gsi.o
>> +acpi-$(CONFIG_ARM_GIC_ACPI)	+= acpi_gic.o
>>
>>   # These are (potentially) separate modules
>>
>> diff --git a/drivers/acpi/acpi_gic.c b/drivers/acpi/acpi_gic.c
>> new file mode 100644
>> index 0000000..11ee4eb
>> --- /dev/null
>> +++ b/drivers/acpi/acpi_gic.c
>
> I think this is starting badly. If this is GIC specific, it lives in
> drivers/irqchip. Nothing in drivers/acpi should be interrupt-controller
> specific at all. If there are things you need to expose through the ACPI
> layer, add some indirections.

OK, originally, I intended for this to be an intermediate layer b/w ACPI 
and irqchip, but I guess that's still not what you are looking for. I'll 
rework this again.

[....]
>> +
>> +#endif /*__ACPI_GIC_H__*/
>> diff --git a/include/linux/acpi.h b/include/linux/acpi.h
>> index 04dd0bb..5d58b61 100644
>> --- a/include/linux/acpi.h
>> +++ b/include/linux/acpi.h
>> @@ -44,6 +44,7 @@
>>
>>   #include <acpi/acpi_bus.h>
>>   #include <acpi/acpi_drivers.h>
>> +#include <acpi/acpi_gic.h>
>
> Ah! No.
>
>>   #include <acpi/acpi_numa.h>
>>   #include <acpi/acpi_io.h>
>>   #include <asm/acpi.h>
>>
>
> Right. Very little of what is above belongs to the ACPI layer. What
> would belong here is a generic acpi_get_msi_domain_token(dev) that would
> call into a controller-specific function to parse the various tables and
> find out which GICv2m frame (or which ITS) is serving the given device.
> This would include parsing of the IORT structures if they are available.

The problem here is we would need to figure out the hook into *a 
controller-specific function* from a generic layer (ACPI in this case).

> For GICv2m, it should be simplistic: just return the domain_token of the
> v2m widget. For the ITS, it is slightly more complex, and there should
> be some specific backend for that. There is no ACPI support for the ITS
> yet, so that shouldn't be your concern at this point in time.
>
> Overall, drivers/acpi should be hardware agnostic (or at least aim for
> it), just like drivers/of is.

I think I understand how you don't like the current approach. Lemme try 
a different approach and send out another revision.

Thanks,
Suravee


From Suravee.Suthikulpanit at amd.com  Sun Aug  9 01:02:45 2015
From: Suravee.Suthikulpanit at amd.com (Suravee Suthikulpanit)
Date: Sun, 9 Aug 2015 15:02:45 +0700
Subject: [PATCH v4 09/10] PCI: ACPI: Bind GIC MSI frame to PCI host bridge
In-Reply-To: <55C0C685.4000400@arm.com>
References: <1438164539-29256-1-git-send-email-hanjun.guo@linaro.org>
 <1438164539-29256-10-git-send-email-hanjun.guo@linaro.org>
 <55C0C685.4000400@arm.com>
Message-ID: <55C70925.2000306@amd.com>

Hi Marc,

On 8/4/15 21:04, Marc Zyngier wrote:
> On 29/07/15 11:08, Hanjun Guo wrote:
>> From: Suravee Suthikulpanit <Suravee.Suthikulpanit at amd.com>
>>
>> This patch introduces pci_host_bridge_acpi_msi_domain(), which queries
>> a GIC MSI irq-domain token and use it to retrieve an irq_domain with
>> DOMAIN_BUS_PCI_MSI bus type, and bind it to PCI host-bridge.
>>
>> Signed-off-by: Suravee Suthikulpanit <Suravee.Suthikulpanit at amd.com>
>> Signed-off-by: Hanjun Guo <hanjun.guo at linaro.org>
>> ---
>>   drivers/pci/pci-acpi.c   | 18 ++++++++++++++++++
>>   drivers/pci/probe.c      |  3 +++
>>   include/linux/pci-acpi.h |  4 ++++
>>   3 files changed, 25 insertions(+)
>>
>> diff --git a/drivers/pci/pci-acpi.c b/drivers/pci/pci-acpi.c
>> index 314a625..5f11653 100644
>> --- a/drivers/pci/pci-acpi.c
>> +++ b/drivers/pci/pci-acpi.c
>> @@ -9,6 +9,7 @@
>>
>>   #include <linux/delay.h>
>>   #include <linux/init.h>
>> +#include <linux/irqdomain.h>
>>   #include <linux/pci.h>
>>   #include <linux/pci_hotplug.h>
>>   #include <linux/module.h>
>> @@ -16,6 +17,7 @@
>>   #include <linux/pci-acpi.h>
>>   #include <linux/pm_runtime.h>
>>   #include <linux/pm_qos.h>
>> +#include <acpi/acpi_gic.h>
>>   #include "pci.h"
>>
>>   /*
>> @@ -681,6 +683,22 @@ static bool pci_acpi_bus_match(struct device *dev)
>>   	return dev_is_pci(dev);
>>   }
>>
>> +#ifdef CONFIG_GENERIC_MSI_IRQ_DOMAIN
>> +struct irq_domain *pci_host_bridge_acpi_msi_domain(struct pci_bus *bus)
>> +{
>> +	struct irq_domain *d = NULL;
>> +	void *token = acpi_gic_get_msi_token(&bus->dev);
>
> Do you see why I positively *hate* having hardware details in generic
> layers? They propagate everywhere...
>
>> +
>> +	if (token)
>> +		d = irq_find_matching_host(token, DOMAIN_BUS_PCI_MSI);
>> +
>> +	if (!d)
>> +		pr_debug("Fail to find domain for MSI\n");
>> +
>> +	return d;
>> +}
>> +#endif /*CONFIG_GENERIC_MSI_IRQ_DOMAIN*/
>> +
>>   static struct acpi_bus_type acpi_pci_bus = {
>>   	.name = "PCI",
>>   	.match = pci_acpi_bus_match,
>> diff --git a/drivers/pci/probe.c b/drivers/pci/probe.c
>> index a7afeac..8c1204c 100644
>> --- a/drivers/pci/probe.c
>> +++ b/drivers/pci/probe.c
>> @@ -12,6 +12,7 @@
>>   #include <linux/module.h>
>>   #include <linux/cpumask.h>
>>   #include <linux/pci-aspm.h>
>> +#include <linux/pci-acpi.h>
>>   #include <asm-generic/pci-bridge.h>
>>   #include "pci.h"
>>
>> @@ -670,6 +671,8 @@ static struct irq_domain *pci_host_bridge_msi_domain(struct pci_bus *bus)
>>   	 * should be called from here.
>>   	 */
>>   	d = pci_host_bridge_of_msi_domain(bus);
>> +	if (!d)
>> +		d = pci_host_bridge_acpi_msi_domain(bus);
>>
>>   	return d;
>>   }
>> diff --git a/include/linux/pci-acpi.h b/include/linux/pci-acpi.h
>> index a965efa..766d045 100644
>> --- a/include/linux/pci-acpi.h
>> +++ b/include/linux/pci-acpi.h
>> @@ -77,6 +77,8 @@ static inline void acpiphp_remove_slots(struct pci_bus *bus) { }
>>   static inline void acpiphp_check_host_bridge(struct acpi_device *adev) { }
>>   #endif
>>
>> +struct irq_domain *pci_host_bridge_acpi_msi_domain(struct pci_bus *bus);
>> +
>>   extern const u8 pci_acpi_dsm_uuid[];
>>   #define DEVICE_LABEL_DSM	0x07
>>   #define RESET_DELAY_DSM		0x08
>> @@ -85,6 +87,8 @@ extern const u8 pci_acpi_dsm_uuid[];
>>   #else	/* CONFIG_ACPI */
>>   static inline void acpi_pci_add_bus(struct pci_bus *bus) { }
>>   static inline void acpi_pci_remove_bus(struct pci_bus *bus) { }
>> +static inline struct irq_domain *
>> +pci_host_bridge_acpi_msi_domain(struct pci_bus *bus) { return NULL; }
>>   #endif	/* CONFIG_ACPI */
>>
>>   #ifdef CONFIG_ACPI_APEI
>>
>
> Once you solve the HW abstraction issue, this will be OK.
>
> Thanks,
>
> 	M.
>

Ok. Thanks,

Suravee


From Suravee.Suthikulpanit at amd.com  Sun Aug  9 01:04:31 2015
From: Suravee.Suthikulpanit at amd.com (Suravee Suthikulpanit)
Date: Sun, 9 Aug 2015 15:04:31 +0700
Subject: [PATCH v4 10/10] irqchip / gicv2m: Introducing gicv2m_acpi_init()
In-Reply-To: <55C0CAC4.3010202@arm.com>
References: <1438164539-29256-1-git-send-email-hanjun.guo@linaro.org>
 <1438164539-29256-11-git-send-email-hanjun.guo@linaro.org>
 <55C0CAC4.3010202@arm.com>
Message-ID: <55C7098F.5010303@amd.com>

Hi Marc,

On 8/4/15 21:23, Marc Zyngier wrote:
> On 29/07/15 11:08, Hanjun Guo wrote:
>> From: Suravee Suthikulpanit <Suravee.Suthikulpanit at amd.com>
>>
>> This patch introduces gicv2m_acpi_init(), which uses information
>> in MADT GIC MSI frames structure to initialize GICv2m driver.
>> It also refactors gicv2m_init_one() to handle both DT and ACPI
>> initialization path.
>>
>> Signed-off-by: Suravee Suthikulpanit <Suravee.Suthikulpanit at amd.com>
>> Signed-off-by: Hanjun Guo <hanjun.guo at linaro.org>
>> ---
>>   drivers/irqchip/irq-gic-v2m.c   | 111 +++++++++++++++++++++++++++++++---------
>>   drivers/irqchip/irq-gic.c       |   3 ++
>>   include/linux/irqchip/arm-gic.h |   7 +++
>>   3 files changed, 98 insertions(+), 23 deletions(-)
>>
>> diff --git a/drivers/irqchip/irq-gic-v2m.c b/drivers/irqchip/irq-gic-v2m.c
>> index d0fcbf8..c491a08 100644
>> --- a/drivers/irqchip/irq-gic-v2m.c
>> +++ b/drivers/irqchip/irq-gic-v2m.c
>> @@ -15,6 +15,7 @@
>>
>>   #define pr_fmt(fmt) "GICv2m: " fmt
>>
>> +#include <linux/acpi.h>
>>   #include <linux/irq.h>
>>   #include <linux/irqdomain.h>
>>   #include <linux/kernel.h>
>> @@ -211,6 +212,10 @@ static bool is_msi_spi_valid(u32 base, u32 num)
>>   	return true;
>>   }
>>
>> +char gicv2m_domain_name[] = "GICV2M";
>> +char gicv2m_pci_msi_domain_name[] = "GICV2M-PCI-MSI";
>> +char gicv2m_plat_msi_domain_name[] = "GICV2M-PLAT-MSI";
>> +
>
> Can't these be static? Why do we need them?

Of course, this is not needed. I figured it was useful when I was 
debugging the irq domain hierarchy stuff. I'll remove it then.

[...]
>> @@ -329,15 +330,79 @@ int __init gicv2m_of_init(struct device_node *node, struct irq_domain *parent)
>>
>>   	for (child = of_find_matching_node(node, gicv2m_device_id); child;
>>   	     child = of_find_matching_node(child, gicv2m_device_id)) {
>> +		u32 spi_start = 0, nr_spis = 0;
>> +		struct resource res;
>> +
>>   		if (!of_find_property(child, "msi-controller", NULL))
>>   			continue;
>>
>> -		ret = gicv2m_init_one(child, parent);
>> +		ret = of_address_to_resource(child, 0, &res);
>> +		if (ret) {
>> +			pr_err("Failed to allocate v2m resource.\n");
>> +			break;
>> +		}
>> +
>> +		if (!of_property_read_u32(child, "arm,msi-base-spi", &spi_start) &&
>> +		    !of_property_read_u32(child, "arm,msi-num-spis", &nr_spis))
>> +			pr_info("Overriding V2M MSI_TYPER (base:%u, num:%u)\n",
>> +				spi_start, nr_spis);
>> +
>> +		ret = gicv2m_init_one(parent, &spi_start, &nr_spis, &res,
>
> If these spi_start and nr_spis pointers passed to gicv2m_init_one are
> only for the benefit of printing the message below, just move the
> message inside the function...
>

Ok.

>> +				      child);
>>   		if (ret) {
>>   			of_node_put(node);
>>   			break;
>>   		}
>> +
>> +		pr_info("Node %s: range[%#lx:%#lx], SPI[%d:%d]\n", child->name,
>> +			(unsigned long)res.start, (unsigned long)res.end,
>> +			spi_start, (spi_start + nr_spis));
>>   	}
>>
>>   	return ret;
>>   }
>> +
>> +#ifdef CONFIG_ACPI
>> +int __init gicv2m_acpi_init(struct acpi_table_header *table,
>> +			    struct irq_domain *parent)
>> +{
>> +	int i, ret;
>> +
>> +	ret = acpi_gic_msi_init(table);
>> +	if (ret)
>> +		return ret;
>> +
>> +	for (i = 0; i < acpi_gic_get_num_msi_frame(); i++) {
>> +		struct resource res;
>> +		u32 spi_start = 0, nr_spis = 0;
>> +		struct acpi_madt_generic_msi_frame *m;
>> +
>> +		ret = acpi_gic_get_msi_frame(i, &m);
>> +		if (ret)
>> +			return ret;
>> +
>
> All of that should be moved here. And we don't need to build an
> intermediate representation. Just build the v2m_data structures as you go.

I'll rework the ACPI MADT parsing, and move it into this file, and get 
rid of the structure.

>> +		res.start = m->base_address;
>> +		res.end = m->base_address + 0x1000;
>> +
>> +		if (m->flags & ACPI_MADT_OVERRIDE_SPI_VALUES) {
>> +			spi_start = m->spi_base;
>> +			nr_spis = m->spi_count;
>> +
>> +			pr_info("ACPI overriding V2M MSI_TYPER (base:%u, num:%u)\n",
>> +				spi_start, nr_spis);
>> +		}
>> +
>> +		ret = gicv2m_init_one(parent, &spi_start, &nr_spis, &res,
>> +				      (void *)(m->base_address));
>> +		if (ret)
>> +			break;
>> +
>> +		pr_info("MSI frame ID %u: range[%#lx:%#lx], SPI[%d:%d]\n",
>> +			m->msi_frame_id,
>> +			(unsigned long)res.start, (unsigned long)res.end,
>> +			spi_start, (spi_start + nr_spis));
>> +	}
>> +	return ret;
>> +}
>> +
>> +#endif /* CONFIG_ACPI */
>> diff --git a/drivers/irqchip/irq-gic.c b/drivers/irqchip/irq-gic.c
>> index bec6b00..531ebbc 100644
>> --- a/drivers/irqchip/irq-gic.c
>> +++ b/drivers/irqchip/irq-gic.c
>> @@ -1159,6 +1159,9 @@ gic_v2_acpi_init(struct acpi_table_header *table)
>>   	 */
>>   	gic_init_bases(0, -1, dist_base, cpu_base, 0, (void *)ACPI_IRQ_MODEL_GIC);
>>
>> +	if (IS_ENABLED(CONFIG_ARM_GIC_V2M))
>> +		gicv2m_acpi_init(table, gic_data[0].domain);
>> +
>>   	acpi_set_irq_model(ACPI_IRQ_MODEL_GIC, ACPI_IRQ_MODEL_GIC,
>>   			   gic_acpi_gsi_desc_populate);
>>   	return 0;
>> diff --git a/include/linux/irqchip/arm-gic.h b/include/linux/irqchip/arm-gic.h
>> index 97799b7..27d8196 100644
>> --- a/include/linux/irqchip/arm-gic.h
>> +++ b/include/linux/irqchip/arm-gic.h
>> @@ -109,6 +109,13 @@ static inline void gic_init(unsigned int nr, int start,
>>
>>   int gicv2m_of_init(struct device_node *node, struct irq_domain *parent);
>>
>> +#ifdef CONFIG_ACPI
>> +struct acpi_table_header;
>> +
>> +int gicv2m_acpi_init(struct acpi_table_header *table,
>> +		     struct irq_domain *parent);
>> +#endif
>> +
>>   void gic_send_sgi(unsigned int cpu_id, unsigned int irq);
>>   int gic_get_cpu_id(unsigned int cpu);
>>   void gic_migrate_target(unsigned int new_cpu_id);
>>
>
> This needs rework to do the parsing of the tables in this driver. Just
> expose the domain_token through a function that you register with the
> ACPI layer.

Ok. I'll investigate and rework this to only expose the domain_token.

Basically, I would need a way to pass down a device from ACPI layer into 
irqchips (e.g. GICv2m and GICv3-ITS), so that it can verify the device 
with the MSI domains and return the appropriate domain token (or some 
sort of domain reference).

Thanks,
Suravee


From robert.jarzmik at free.fr  Sun Aug  9 05:18:57 2015
From: robert.jarzmik at free.fr (Robert Jarzmik)
Date: Sun, 09 Aug 2015 14:18:57 +0200
Subject: [PATCH-v5 5/5] i2c: pxa: Add ILCR (tLow & tHigh) configuration
 support
In-Reply-To: <55C1CE8E.9000601@linaro.org> (Vaibhav Hiremath's message of
 "Wed, 05 Aug 2015 14:21:26 +0530")
References: <1437482466-16126-1-git-send-email-vaibhav.hiremath@linaro.org>
 <1437482466-16126-6-git-send-email-vaibhav.hiremath@linaro.org>
 <55C1CE8E.9000601@linaro.org>
Message-ID: <87bnegk632.fsf@belgarion.home>

Vaibhav Hiremath <vaibhav.hiremath at linaro.org> writes:

> Robert,
>
> It would be helpful if you can test this patch-series and confirm that
> it now fixes the NULL pointer deference issue.
Tested, it works on pxa27x in master mode, in non-DT mode.

For all non-DT patches, you can add my :
Tested-by: Robert Jarzmik <robert.jarzmik at free.fr>

Cheers.

-- 
Robert


From wsa at the-dreams.de  Sun Aug  9 05:34:30 2015
From: wsa at the-dreams.de (Wolfram Sang)
Date: Sun, 9 Aug 2015 14:34:30 +0200
Subject: [PATCH v2 13/22] i2c: core: Probe i2c master devices on demand
In-Reply-To: <1438089593-7696-14-git-send-email-tomeu.vizoso@collabora.com>
References: <1438089593-7696-1-git-send-email-tomeu.vizoso@collabora.com>
 <1438089593-7696-14-git-send-email-tomeu.vizoso@collabora.com>
Message-ID: <20150809123430.GB1521@katana>

On Tue, Jul 28, 2015 at 03:19:44PM +0200, Tomeu Vizoso wrote:
> When looking up an i2c master through its firmware node, probe it if it
> hasn't already.
> 
> The goal is to reduce deferred probes to a minimum, as it makes it very
> cumbersome to find out why a device failed to probe, and can introduce
> very big delays in when a critical device is probed.
> 
> Signed-off-by: Tomeu Vizoso <tomeu.vizoso at collabora.com>

What is the status of this series? The boot time reduction sounds great.

> ---
> 
> Changes in v2: None
> 
>  drivers/i2c/i2c-core.c | 2 ++
>  1 file changed, 2 insertions(+)
> 
> diff --git a/drivers/i2c/i2c-core.c b/drivers/i2c/i2c-core.c
> index e6d4935161e4..5520b413e3db 100644
> --- a/drivers/i2c/i2c-core.c
> +++ b/drivers/i2c/i2c-core.c
> @@ -1353,6 +1353,8 @@ struct i2c_adapter *of_find_i2c_adapter_by_node(struct device_node *node)
>  {
>  	struct device *dev;
>  
> +	fwnode_ensure_device(&node->fwnode);

TBH, the function name doesn't tell me a lot. It ensures what?

> +
>  	dev = bus_find_device(&i2c_bus_type, NULL, node,
>  					 of_dev_node_match);
>  	if (!dev)
> -- 
> 2.4.3
> 
-------------- next part --------------
A non-text attachment was scrubbed...
Name: signature.asc
Type: application/pgp-signature
Size: 819 bytes
Desc: Digital signature
URL: <http://lists.infradead.org/pipermail/linux-arm-kernel/attachments/20150809/1949a188/attachment.sig>

From tomeu.vizoso at collabora.com  Sun Aug  9 06:03:14 2015
From: tomeu.vizoso at collabora.com (Tomeu Vizoso)
Date: Sun, 9 Aug 2015 15:03:14 +0200
Subject: [PATCH v3 01/18] platform: delay OF device-driver matches until
 late_initcall
In-Reply-To: <55C4E597.1010701@ti.com>
References: <1438870315-18689-1-git-send-email-tomeu.vizoso@collabora.com>
 <1438870315-18689-2-git-send-email-tomeu.vizoso@collabora.com>
 <CAL_Jsq+GLMZe-f6qEi=7i1YrrWc6k99RpGkOyCd5KkYDiyt0QA@mail.gmail.com>
 <CAAObsKBapFqzr+4YEXJfcJWMd+tkaBqYbGiFTntHStAP=+P-_Q@mail.gmail.com>
 <55C4E597.1010701@ti.com>
Message-ID: <CAAObsKDJsuhuQfLbxq27Mtm1T_Auz7Gohp8PDyK7rNNDyaGhcg@mail.gmail.com>

On 7 August 2015 at 19:06, Grygorii Strashko <grygorii.strashko at ti.com> wrote:
> On 08/07/2015 10:11 AM, Tomeu Vizoso wrote:
>> On 6 August 2015 at 22:19, Rob Herring <robherring2 at gmail.com> wrote:
>>> On Thu, Aug 6, 2015 at 9:11 AM, Tomeu Vizoso <tomeu.vizoso at collabora.com> wrote:
>>>> Delay matches of platform devices with OF nodes until late_initcall,
>>>> when we are sure that all built-in drivers have been registered already.
>>>> This is needed to prevent deferred probes because of some drivers not
>>>> having registered yet.
>>>>
>>>> The reason why only platform devices are delayed is that some other
>>>> devices are expected to be probed earlier than late_initcall, for
>>>> example, the system PNP driver needs to probe its devices in
>>>> fs_initcall.
>>>>
>>>> Additionally, only platform devices with OF nodes are delayed because
>>>> some machines may depend on oter platform devices being registered at
>>>> specific times.
>>>
>>> How do we know that these probes occur before the unused clocks and
>>> regulators are turned off? Just getting lucky (as is deferred probe)?
>>> Can we do this one level earlier so we have a level left to do things
>>> after probe.
>>
>> Those are already late_initcall_sync so I guess we're fine.
>
> I wouldn't be so sure :(
> FYI:
> http://git.ti.com/ti-linux-kernel/ti-linux-kernel/commit/763d643bbfc0f445c6685c541fcae3c370e4314a

If I understand the situation correctly, this is one more instance of
starting to do some work at some point and hoping that something else
that started before has already finished happening. If that's the
case, how does this series make that worst?

During this development I have found many hacks intended to put some
order, even if not enough care was taken to make sure that the order
was guaranteed. In general I would recommend for moving code into
proper drivers and have them to defer the probe of their devices if
some dependency isn't fulfilled at that moment.

Once that's done and we have a safe and reliable boot, we can avoid
those deferred probes by fulfilling the dependency on-demand as this
series shows.

There was some recent thread about how the disabling of unused clocks
and regulators isn't really safe because after late_initcall_sync more
drivers can be registered from modules. Furthermore, there's async
device probes.

Regards,

Tomeu

>
> --
> regards,
> -grygorii
>
> _______________________________________________
> linux-arm-kernel mailing list
> linux-arm-kernel at lists.infradead.org
> http://lists.infradead.org/mailman/listinfo/linux-arm-kernel


From tomeu.vizoso at collabora.com  Sun Aug  9 06:37:36 2015
From: tomeu.vizoso at collabora.com (Tomeu Vizoso)
Date: Sun, 9 Aug 2015 15:37:36 +0200
Subject: [PATCH v2 13/22] i2c: core: Probe i2c master devices on demand
In-Reply-To: <20150809123430.GB1521@katana>
References: <1438089593-7696-1-git-send-email-tomeu.vizoso@collabora.com>
 <1438089593-7696-14-git-send-email-tomeu.vizoso@collabora.com>
 <20150809123430.GB1521@katana>
Message-ID: <CAAObsKBUxtdT7gsO9mh__E5kFamp9yPUAetxJJ=ftV4Bu_b2HA@mail.gmail.com>

On 9 August 2015 at 14:34, Wolfram Sang <wsa at the-dreams.de> wrote:
> On Tue, Jul 28, 2015 at 03:19:44PM +0200, Tomeu Vizoso wrote:
>> When looking up an i2c master through its firmware node, probe it if it
>> hasn't already.
>>
>> The goal is to reduce deferred probes to a minimum, as it makes it very
>> cumbersome to find out why a device failed to probe, and can introduce
>> very big delays in when a critical device is probed.
>>
>> Signed-off-by: Tomeu Vizoso <tomeu.vizoso at collabora.com>
>
> What is the status of this series?

See here for a summary:

http://lkml.kernel.org/g/1438870315-18689-1-git-send-email-tomeu.vizoso at collabora.com

> The boot time reduction sounds great.

Note that this should not reduce total boot time substantially, as the
time wasted due to superfluous probe deferrals is really small when
compared to the time spent in delays due to hardware constraints. If
you want to reduce total boot time, async probing may be helpful in
some scenarios.

Regards,

Tomeu

>> ---
>>
>> Changes in v2: None
>>
>>  drivers/i2c/i2c-core.c | 2 ++
>>  1 file changed, 2 insertions(+)
>>
>> diff --git a/drivers/i2c/i2c-core.c b/drivers/i2c/i2c-core.c
>> index e6d4935161e4..5520b413e3db 100644
>> --- a/drivers/i2c/i2c-core.c
>> +++ b/drivers/i2c/i2c-core.c
>> @@ -1353,6 +1353,8 @@ struct i2c_adapter *of_find_i2c_adapter_by_node(struct device_node *node)
>>  {
>>       struct device *dev;
>>
>> +     fwnode_ensure_device(&node->fwnode);
>
> TBH, the function name doesn't tell me a lot. It ensures what?
>
>> +
>>       dev = bus_find_device(&i2c_bus_type, NULL, node,
>>                                        of_dev_node_match);
>>       if (!dev)
>> --
>> 2.4.3
>>


From andrew at lunn.ch  Sun Aug  9 08:19:16 2015
From: andrew at lunn.ch (Andrew Lunn)
Date: Sun, 9 Aug 2015 17:19:16 +0200
Subject: [PATCH v9 0/9] Add simple NVMEM Framework via regmap.
In-Reply-To: <1438693367.3793.29.camel@pengutronix.de>
References: <1437995567-11203-1-git-send-email-srinivas.kandagatla@linaro.org>
 <1438693367.3793.29.camel@pengutronix.de>
Message-ID: <20150809151916.GF14271@lunn.ch>

Hi Srinivas

The AT24 eeprom driver contains the comment:

        /*                                                                                               
         * Export the EEPROM bytes through sysfs, since that's convenient.                               
         * By default, only root should see the data (maybe passwords etc)                               
         */

and as you would expect from this:

# ls -l ./devices/platform/soc/soc:aips-bus at 40000000/40066000.i2c/i2c-0/0-0050/eeprom
-rw------- 1 root root 512 Aug  9 10:16 ./devices/platform/soc/soc:aips-bus at 40000000/40066000.i2c/i2c-0/0-0050/eeprom

The AT25 and the MAX6875 driver are the same.

However nvmem has different defaults:

# ls -l ./devices/platform/soc/soc:aips-bus at 40000000/40066000.i2c/i2c-0/0-0050/0-00500/nvmem
-rw-r--r-- 1 root root 0 Aug  9 10:16 ./devices/platform/soc/soc:aips-bus at 40000000/40066000.i2c/i2c-0/0-0050/0-00500/nvmem

Has this been considered and discussed?

Thanks
    Andrew


From vaibhav.hiremath at linaro.org  Sun Aug  9 09:53:30 2015
From: vaibhav.hiremath at linaro.org (Vaibhav Hiremath)
Date: Sun, 09 Aug 2015 22:23:30 +0530
Subject: [PATCH-v5 5/5] i2c: pxa: Add ILCR (tLow & tHigh) configuration
 support
In-Reply-To: <87bnegk632.fsf@belgarion.home>
References: <1437482466-16126-1-git-send-email-vaibhav.hiremath@linaro.org>	<1437482466-16126-6-git-send-email-vaibhav.hiremath@linaro.org>	<55C1CE8E.9000601@linaro.org>
 <87bnegk632.fsf@belgarion.home>
Message-ID: <55C7858A.5080308@linaro.org>



On Sunday 09 August 2015 05:48 PM, Robert Jarzmik wrote:
> Vaibhav Hiremath <vaibhav.hiremath at linaro.org> writes:
>
>> Robert,
>>
>> It would be helpful if you can test this patch-series and confirm that
>> it now fixes the NULL pointer deference issue.
> Tested, it works on pxa27x in master mode, in non-DT mode.
>
> For all non-DT patches, you can add my :
> Tested-by: Robert Jarzmik <robert.jarzmik at free.fr>
>

Thanks Robert,

Wolfram,
Request you to please take a look at this series.
We can have discussion on DT properties as well.

Thanks,
Vaibhav


From oliver at schinagl.nl  Sun Aug  9 11:22:57 2015
From: oliver at schinagl.nl (Olliver Schinagl)
Date: Sun,  9 Aug 2015 20:22:57 +0200
Subject: [PATCH] ARM: dts: sunxi enable otg port on the
 sun7i-a20-olinuxino-lime2
Message-ID: <1439144578-7890-1-git-send-email-oliver@schinagl.nl>

From: Olliver Schinagl <o.schinagl at ultimaker.com>

This patch enables the recently introduced OTG support for the OLinuXino Lime2.
Tested with a keyboard and some USB mass-storage flash-drives and various
hotplug.

Signed-off-by: Olliver Schinagl <oliver at schinagl.nl>

Olliver Schinagl (1):
  ARM: dts: sunxi: enable otg port on the sun7i-a20-olinuxino-lime2

 arch/arm/boot/dts/sun7i-a20-olinuxino-lime2.dts | 41 +++++++++++++++++++++++++
 1 file changed, 41 insertions(+)

-- 
2.1.4



From oliver at schinagl.nl  Sun Aug  9 11:22:58 2015
From: oliver at schinagl.nl (Olliver Schinagl)
Date: Sun,  9 Aug 2015 20:22:58 +0200
Subject: [PATCH] ARM: dts: sunxi: enable otg port on the
 sun7i-a20-olinuxino-lime2
In-Reply-To: <1439144578-7890-1-git-send-email-oliver@schinagl.nl>
References: <1439144578-7890-1-git-send-email-oliver@schinagl.nl>
Message-ID: <1439144578-7890-2-git-send-email-oliver@schinagl.nl>

From: Olliver Schinagl <o.schinagl at ultimaker.com>

This patch enables the musb-otg USB controller on the Lime2. The Lime2
differs from the Lime1 series in pins used for usb0 power.

Tested on a OlinuXino Lime2-4GB.

Signed-off-by: Olliver Schinagl <oliver at schinagl.nl>
---
 arch/arm/boot/dts/sun7i-a20-olinuxino-lime2.dts | 41 +++++++++++++++++++++++++
 1 file changed, 41 insertions(+)

diff --git a/arch/arm/boot/dts/sun7i-a20-olinuxino-lime2.dts b/arch/arm/boot/dts/sun7i-a20-olinuxino-lime2.dts
index 22cd052..a7239fc 100644
--- a/arch/arm/boot/dts/sun7i-a20-olinuxino-lime2.dts
+++ b/arch/arm/boot/dts/sun7i-a20-olinuxino-lime2.dts
@@ -196,6 +196,10 @@
 	status = "okay";
 };
 
+&otg_sram {
+	status = "okay";
+};
+
 &pio {
 	ahci_pwr_pin_olinuxinolime: ahci_pwr_pin at 1 {
 		allwinner,pins = "PC3";
@@ -210,6 +214,27 @@
 		allwinner,drive = <SUN4I_PINCTRL_20_MA>;
 		allwinner,pull = <SUN4I_PINCTRL_NO_PULL>;
 	};
+
+	usb0_id_detect_pin: usb0_id_detect_pin at 0 {
+		allwinner,pins = "PH4";
+		allwinner,function = "gpio_in";
+		allwinner,drive = <SUN4I_PINCTRL_10_MA>;
+		allwinner,pull = <SUN4I_PINCTRL_PULL_UP>;
+	};
+
+	usb0_vbus_detect_pin: usb0_vbus_detect_pin at 0 {
+		allwinner,pins = "PH5";
+		allwinner,function = "gpio_in";
+		allwinner,drive = <SUN4I_PINCTRL_10_MA>;
+		allwinner,pull = <SUN4I_PINCTRL_PULL_DOWN>;
+	};
+
+	usb0_vbus_pin_lime2: usb0_vbus_pin at 0 {
+		allwinner,pins = "PC17";
+		allwinner,function = "gpio_out";
+		allwinner,drive = <SUN4I_PINCTRL_10_MA>;
+		allwinner,pull = <SUN4I_PINCTRL_NO_PULL>;
+	};
 };
 
 &reg_ahci_5v {
@@ -218,6 +243,12 @@
 	status = "okay";
 };
 
+&reg_usb0_vbus {
+	pinctrl-0 = <&usb0_vbus_pin_lime2>;
+	gpio = <&pio 2 17 GPIO_ACTIVE_HIGH>;
+	status = "okay";
+};
+
 &reg_usb1_vbus {
 	status = "okay";
 };
@@ -232,7 +263,17 @@
 	status = "okay";
 };
 
+&usb_otg {
+	dr_mode = "otg";
+	status = "okay";
+};
+
 &usbphy {
+	pinctrl-names = "default";
+	pinctrl-0 = <&usb0_id_detect_pin>, <&usb0_vbus_detect_pin>;
+	usb0_id_det-gpio = <&pio 7 4 GPIO_ACTIVE_HIGH>; /* PH4 */
+	usb0_vbus_det-gpio = <&pio 7 5 GPIO_ACTIVE_HIGH>; /* PH5 */
+	usb0_vbus-supply = <&reg_usb0_vbus>;
 	usb1_vbus-supply = <&reg_usb1_vbus>;
 	usb2_vbus-supply = <&reg_usb2_vbus>;
 	status = "okay";
-- 
2.1.4



From oliver at schinagl.nl  Sun Aug  9 12:02:47 2015
From: oliver at schinagl.nl (Olliver Schinagl)
Date: Sun,  9 Aug 2015 21:02:47 +0200
Subject: [PATCH] ARM: dts: sunxi: Use the axp209 driver on the olimex lime2
Message-ID: <1439146968-9039-1-git-send-email-oliver@schinagl.nl>

This patch enables usage of the axp209 on the OLinuXino Lime2 and was tested
the OLinuXino Lime2-4GB.

Signed-off-by: Olliver Schinagl <oliver at schinagl.nl>

Olliver Schinagl (1):
  ARM: dts: sunxi: enable otg port on the sun7i-a20-olinuxino-lime2

 arch/arm/boot/dts/sun7i-a20-olinuxino-lime2.dts | 131 ++++++++++++++----------
 1 file changed, 75 insertions(+), 56 deletions(-)

-- 
2.1.4



From oliver at schinagl.nl  Sun Aug  9 12:02:48 2015
From: oliver at schinagl.nl (Olliver Schinagl)
Date: Sun,  9 Aug 2015 21:02:48 +0200
Subject: [PATCH] ARM: dts: sunxi: enable otg port on the
 sun7i-a20-olinuxino-lime2
In-Reply-To: <1439146968-9039-1-git-send-email-oliver@schinagl.nl>
References: <1439146968-9039-1-git-send-email-oliver@schinagl.nl>
Message-ID: <1439146968-9039-2-git-send-email-oliver@schinagl.nl>

From: Olliver Schinagl <o.schinagl at ultimaker.com>

This patch enables the musb-otg USB controller on the Lime2. The Lime2
differs from the Lime1 series in pins used for usb0 power.

Tested on a OlinuXino Lime2-4GB.

Signed-off-by: Olliver Schinagl <oliver at schinagl.nl>
---
 arch/arm/boot/dts/sun7i-a20-olinuxino-lime2.dts | 131 ++++++++++++++----------
 1 file changed, 75 insertions(+), 56 deletions(-)

diff --git a/arch/arm/boot/dts/sun7i-a20-olinuxino-lime2.dts b/arch/arm/boot/dts/sun7i-a20-olinuxino-lime2.dts
index 22cd052..efd9ebb 100644
--- a/arch/arm/boot/dts/sun7i-a20-olinuxino-lime2.dts
+++ b/arch/arm/boot/dts/sun7i-a20-olinuxino-lime2.dts
@@ -71,14 +71,6 @@
 			default-state = "on";
 		};
 	};
-
-	reg_axp_ipsout: axp_ipsout {
-		compatible = "regulator-fixed";
-		regulator-name = "axp-ipsout";
-		regulator-min-microvolt = <5000000>;
-		regulator-max-microvolt = <5000000>;
-		regulator-always-on;
-	};
 };
 
 &ahci {
@@ -86,6 +78,10 @@
 	status = "okay";
 };
 
+&cpu0 {
+	cpu-supply = <&reg_dcdc2>;
+};
+
 &ehci0 {
 	status = "okay";
 };
@@ -112,57 +108,9 @@
 	status = "okay";
 
 	axp209: pmic at 34 {
-		compatible = "x-powers,axp209";
 		reg = <0x34>;
 		interrupt-parent = <&nmi_intc>;
 		interrupts = <0 IRQ_TYPE_LEVEL_LOW>;
-
-		interrupt-controller;
-		#interrupt-cells = <1>;
-
-		acin-supply = <&reg_axp_ipsout>;
-		vin2-supply = <&reg_axp_ipsout>;
-		vin3-supply = <&reg_axp_ipsout>;
-		ldo24in-supply = <&reg_axp_ipsout>;
-		ldo3in-supply = <&reg_axp_ipsout>;
-
-		regulators {
-			vdd_rtc: ldo1 {
-				regulator-min-microvolt = <1300000>;
-				regulator-max-microvolt = <1300000>;
-				regulator-always-on;
-			};
-
-			avcc: ldo2 {
-				regulator-min-microvolt = <1800000>;
-				regulator-max-microvolt = <3300000>;
-				regulator-always-on;
-			};
-
-			vcc_csi0: ldo3 {
-				regulator-min-microvolt = <700000>;
-				regulator-max-microvolt = <3500000>;
-				regulator-always-on;
-			};
-
-			vcc_csi1: ldo4 {
-				regulator-min-microvolt = <1250000>;
-				regulator-max-microvolt = <3300000>;
-				regulator-always-on;
-			};
-
-			vdd_cpu: dcdc2 {
-				regulator-min-microvolt = <700000>;
-				regulator-max-microvolt = <2275000>;
-				regulator-always-on;
-			};
-
-			vdd_int: dcdc3 {
-				regulator-min-microvolt = <700000>;
-				regulator-max-microvolt = <3500000>;
-				regulator-always-on;
-			};
-		};
 	};
 };
 
@@ -196,6 +144,10 @@
 	status = "okay";
 };
 
+&otg_sram {
+	status = "okay";
+};
+
 &pio {
 	ahci_pwr_pin_olinuxinolime: ahci_pwr_pin at 1 {
 		allwinner,pins = "PC3";
@@ -210,6 +162,27 @@
 		allwinner,drive = <SUN4I_PINCTRL_20_MA>;
 		allwinner,pull = <SUN4I_PINCTRL_NO_PULL>;
 	};
+
+	usb0_id_detect_pin: usb0_id_detect_pin at 0 {
+		allwinner,pins = "PH4";
+		allwinner,function = "gpio_in";
+		allwinner,drive = <SUN4I_PINCTRL_10_MA>;
+		allwinner,pull = <SUN4I_PINCTRL_PULL_UP>;
+	};
+
+	usb0_vbus_detect_pin: usb0_vbus_detect_pin at 0 {
+		allwinner,pins = "PH5";
+		allwinner,function = "gpio_in";
+		allwinner,drive = <SUN4I_PINCTRL_10_MA>;
+		allwinner,pull = <SUN4I_PINCTRL_PULL_DOWN>;
+	};
+
+	usb0_vbus_pin_lime2: usb0_vbus_pin at 0 {
+		allwinner,pins = "PC17";
+		allwinner,function = "gpio_out";
+		allwinner,drive = <SUN4I_PINCTRL_10_MA>;
+		allwinner,pull = <SUN4I_PINCTRL_NO_PULL>;
+	};
 };
 
 &reg_ahci_5v {
@@ -218,6 +191,42 @@
 	status = "okay";
 };
 
+#include "axp209.dtsi"
+
+&reg_dcdc2 {
+	regulator-always-on;
+	regulator-min-microvolt = <1000000>;
+	regulator-max-microvolt = <1450000>;
+	regulator-name = "vdd-cpu";
+};
+
+&reg_dcdc3 {
+	regulator-always-on;
+	regulator-min-microvolt = <1000000>;
+	regulator-max-microvolt = <1400000>;
+	regulator-name = "vdd-int-dll";
+};
+
+&reg_ldo1 {
+	regulator-always-on;
+	regulator-min-microvolt = <1300000>;
+	regulator-max-microvolt = <1300000>;
+	regulator-name = "vdd-rtc";
+};
+
+&reg_ldo2 {
+	regulator-always-on;
+	regulator-min-microvolt = <3000000>;
+	regulator-max-microvolt = <3000000>;
+	regulator-name = "avcc";
+};
+
+&reg_usb0_vbus {
+	pinctrl-0 = <&usb0_vbus_pin_lime2>;
+	gpio = <&pio 2 17 GPIO_ACTIVE_HIGH>;
+	status = "okay";
+};
+
 &reg_usb1_vbus {
 	status = "okay";
 };
@@ -232,7 +241,17 @@
 	status = "okay";
 };
 
+&usb_otg {
+	dr_mode = "otg";
+	status = "okay";
+};
+
 &usbphy {
+	pinctrl-names = "default";
+	pinctrl-0 = <&usb0_id_detect_pin>, <&usb0_vbus_detect_pin>;
+	usb0_id_det-gpio = <&pio 7 4 GPIO_ACTIVE_HIGH>; /* PH4 */
+	usb0_vbus_det-gpio = <&pio 7 5 GPIO_ACTIVE_HIGH>; /* PH5 */
+	usb0_vbus-supply = <&reg_usb0_vbus>;
 	usb1_vbus-supply = <&reg_usb1_vbus>;
 	usb2_vbus-supply = <&reg_usb2_vbus>;
 	status = "okay";
-- 
2.1.4



From ipaton0 at gmail.com  Sun Aug  9 15:58:55 2015
From: ipaton0 at gmail.com (Iain Paton)
Date: Sun, 09 Aug 2015 23:58:55 +0100
Subject: [linux-sunxi] [PATCH v2] ARM: dts: sunxi: Raise minimum CPU
 voltage for sun7i-a20 to meet SoC specifications
In-Reply-To: <1438722481-2302-1-git-send-email-public_timo.s@silentcreek.de>
References: <1438722481-2302-1-git-send-email-public_timo.s@silentcreek.de>
Message-ID: <55C7DB2F.5080907@gmail.com>

Acked-by: Iain Paton <ipaton0 at gmail.com>

On 04/08/15 22:08, Timo Sigurdsson wrote:
> sun7i-a20.dtsi contains a cpufreq operating point at 0.9 volts. The minimum
> CPU voltage for the Allwinner A20 SoC, however, is 1.0 volts. Thus, raise
> the voltage for the lowest operating point to 1.0 volts in order to stay
> within the SoC specifications. It is an undervolted setting that isn't
> stable across all SoCs and boards out there.
> 
> Signed-off-by: Timo Sigurdsson <public_timo.s at silentcreek.de>
> ---
> Changes since v1:
> 
> - Fixed checkpatch warnings
> - Changed the commit message and title to clarify that this is not a board-specific issue, but rather a limitation by the SoC  
> ---
>  arch/arm/boot/dts/sun7i-a20.dtsi | 2 +-
>  1 file changed, 1 insertion(+), 1 deletion(-)
> 
> diff --git a/arch/arm/boot/dts/sun7i-a20.dtsi b/arch/arm/boot/dts/sun7i-a20.dtsi
> index 6a63f30..f5f384c 100644
> --- a/arch/arm/boot/dts/sun7i-a20.dtsi
> +++ b/arch/arm/boot/dts/sun7i-a20.dtsi
> @@ -107,7 +107,7 @@
>  				720000	1200000
>  				528000	1100000
>  				312000	1000000
> -				144000	900000
> +				144000	1000000
>  				>;
>  			#cooling-cells = <2>;
>  			cooling-min-level = <0>;
> 



From ipaton0 at gmail.com  Sun Aug  9 16:05:05 2015
From: ipaton0 at gmail.com (Iain Paton)
Date: Mon, 10 Aug 2015 00:05:05 +0100
Subject: [linux-sunxi] [PATCH] ARM: dts: sunxi: enable otg port on the
 sun7i-a20-olinuxino-lime2
In-Reply-To: <1439146968-9039-2-git-send-email-oliver@schinagl.nl>
References: <1439146968-9039-1-git-send-email-oliver@schinagl.nl>
 <1439146968-9039-2-git-send-email-oliver@schinagl.nl>
Message-ID: <55C7DCA1.2090204@gmail.com>

NAK. This does much more than enabling the otg port.

Neither wholesale re-writing the regulator node or hooking up the 
dcdc2 regulator to the operating points definition is required in order 
to enable the otg port.  

At the very least you need to split your patches and describe them 
properly rather than trying to get additional changes that are likely 
to cause further discussion through unnoticed using a misleading 
subject.

Rgds,
Iain
 
On 09/08/15 20:02, Olliver Schinagl wrote:
> From: Olliver Schinagl <o.schinagl at ultimaker.com>
> 
> This patch enables the musb-otg USB controller on the Lime2. The Lime2
> differs from the Lime1 series in pins used for usb0 power.
> 
> Tested on a OlinuXino Lime2-4GB.
> 
> Signed-off-by: Olliver Schinagl <oliver at schinagl.nl>
> ---
>  arch/arm/boot/dts/sun7i-a20-olinuxino-lime2.dts | 131 ++++++++++++++----------
>  1 file changed, 75 insertions(+), 56 deletions(-)
> 
> diff --git a/arch/arm/boot/dts/sun7i-a20-olinuxino-lime2.dts b/arch/arm/boot/dts/sun7i-a20-olinuxino-lime2.dts
> index 22cd052..efd9ebb 100644
> --- a/arch/arm/boot/dts/sun7i-a20-olinuxino-lime2.dts
> +++ b/arch/arm/boot/dts/sun7i-a20-olinuxino-lime2.dts
> @@ -71,14 +71,6 @@
>  			default-state = "on";
>  		};
>  	};
> -
> -	reg_axp_ipsout: axp_ipsout {
> -		compatible = "regulator-fixed";
> -		regulator-name = "axp-ipsout";
> -		regulator-min-microvolt = <5000000>;
> -		regulator-max-microvolt = <5000000>;
> -		regulator-always-on;
> -	};
>  };
>  
>  &ahci {
> @@ -86,6 +78,10 @@
>  	status = "okay";
>  };
>  
> +&cpu0 {
> +	cpu-supply = <&reg_dcdc2>;
> +};
> +
>  &ehci0 {
>  	status = "okay";
>  };
> @@ -112,57 +108,9 @@
>  	status = "okay";
>  
>  	axp209: pmic at 34 {
> -		compatible = "x-powers,axp209";
>  		reg = <0x34>;
>  		interrupt-parent = <&nmi_intc>;
>  		interrupts = <0 IRQ_TYPE_LEVEL_LOW>;
> -
> -		interrupt-controller;
> -		#interrupt-cells = <1>;
> -
> -		acin-supply = <&reg_axp_ipsout>;
> -		vin2-supply = <&reg_axp_ipsout>;
> -		vin3-supply = <&reg_axp_ipsout>;
> -		ldo24in-supply = <&reg_axp_ipsout>;
> -		ldo3in-supply = <&reg_axp_ipsout>;
> -
> -		regulators {
> -			vdd_rtc: ldo1 {
> -				regulator-min-microvolt = <1300000>;
> -				regulator-max-microvolt = <1300000>;
> -				regulator-always-on;
> -			};
> -
> -			avcc: ldo2 {
> -				regulator-min-microvolt = <1800000>;
> -				regulator-max-microvolt = <3300000>;
> -				regulator-always-on;
> -			};
> -
> -			vcc_csi0: ldo3 {
> -				regulator-min-microvolt = <700000>;
> -				regulator-max-microvolt = <3500000>;
> -				regulator-always-on;
> -			};
> -
> -			vcc_csi1: ldo4 {
> -				regulator-min-microvolt = <1250000>;
> -				regulator-max-microvolt = <3300000>;
> -				regulator-always-on;
> -			};
> -
> -			vdd_cpu: dcdc2 {
> -				regulator-min-microvolt = <700000>;
> -				regulator-max-microvolt = <2275000>;
> -				regulator-always-on;
> -			};
> -
> -			vdd_int: dcdc3 {
> -				regulator-min-microvolt = <700000>;
> -				regulator-max-microvolt = <3500000>;
> -				regulator-always-on;
> -			};
> -		};
>  	};
>  };
>  
> @@ -196,6 +144,10 @@
>  	status = "okay";
>  };
>  
> +&otg_sram {
> +	status = "okay";
> +};
> +
>  &pio {
>  	ahci_pwr_pin_olinuxinolime: ahci_pwr_pin at 1 {
>  		allwinner,pins = "PC3";
> @@ -210,6 +162,27 @@
>  		allwinner,drive = <SUN4I_PINCTRL_20_MA>;
>  		allwinner,pull = <SUN4I_PINCTRL_NO_PULL>;
>  	};
> +
> +	usb0_id_detect_pin: usb0_id_detect_pin at 0 {
> +		allwinner,pins = "PH4";
> +		allwinner,function = "gpio_in";
> +		allwinner,drive = <SUN4I_PINCTRL_10_MA>;
> +		allwinner,pull = <SUN4I_PINCTRL_PULL_UP>;
> +	};
> +
> +	usb0_vbus_detect_pin: usb0_vbus_detect_pin at 0 {
> +		allwinner,pins = "PH5";
> +		allwinner,function = "gpio_in";
> +		allwinner,drive = <SUN4I_PINCTRL_10_MA>;
> +		allwinner,pull = <SUN4I_PINCTRL_PULL_DOWN>;
> +	};
> +
> +	usb0_vbus_pin_lime2: usb0_vbus_pin at 0 {
> +		allwinner,pins = "PC17";
> +		allwinner,function = "gpio_out";
> +		allwinner,drive = <SUN4I_PINCTRL_10_MA>;
> +		allwinner,pull = <SUN4I_PINCTRL_NO_PULL>;
> +	};
>  };
>  
>  &reg_ahci_5v {
> @@ -218,6 +191,42 @@
>  	status = "okay";
>  };
>  
> +#include "axp209.dtsi"
> +
> +&reg_dcdc2 {
> +	regulator-always-on;
> +	regulator-min-microvolt = <1000000>;
> +	regulator-max-microvolt = <1450000>;
> +	regulator-name = "vdd-cpu";
> +};
> +
> +&reg_dcdc3 {
> +	regulator-always-on;
> +	regulator-min-microvolt = <1000000>;
> +	regulator-max-microvolt = <1400000>;
> +	regulator-name = "vdd-int-dll";
> +};
> +
> +&reg_ldo1 {
> +	regulator-always-on;
> +	regulator-min-microvolt = <1300000>;
> +	regulator-max-microvolt = <1300000>;
> +	regulator-name = "vdd-rtc";
> +};
> +
> +&reg_ldo2 {
> +	regulator-always-on;
> +	regulator-min-microvolt = <3000000>;
> +	regulator-max-microvolt = <3000000>;
> +	regulator-name = "avcc";
> +};
> +
> +&reg_usb0_vbus {
> +	pinctrl-0 = <&usb0_vbus_pin_lime2>;
> +	gpio = <&pio 2 17 GPIO_ACTIVE_HIGH>;
> +	status = "okay";
> +};
> +
>  &reg_usb1_vbus {
>  	status = "okay";
>  };
> @@ -232,7 +241,17 @@
>  	status = "okay";
>  };
>  
> +&usb_otg {
> +	dr_mode = "otg";
> +	status = "okay";
> +};
> +
>  &usbphy {
> +	pinctrl-names = "default";
> +	pinctrl-0 = <&usb0_id_detect_pin>, <&usb0_vbus_detect_pin>;
> +	usb0_id_det-gpio = <&pio 7 4 GPIO_ACTIVE_HIGH>; /* PH4 */
> +	usb0_vbus_det-gpio = <&pio 7 5 GPIO_ACTIVE_HIGH>; /* PH5 */
> +	usb0_vbus-supply = <&reg_usb0_vbus>;
>  	usb1_vbus-supply = <&reg_usb1_vbus>;
>  	usb2_vbus-supply = <&reg_usb2_vbus>;
>  	status = "okay";
> 



From kgene at kernel.org  Sun Aug  9 17:41:04 2015
From: kgene at kernel.org (Kukjin Kim)
Date: Mon, 10 Aug 2015 09:41:04 +0900
Subject: [GIT PULL 1/5] Samsung non-critical-fixes for v4.3
In-Reply-To: <55C06995.2030600@kernel.org>
References: <55C06995.2030600@kernel.org>
Message-ID: <03ce01d0d305$3ceaea70$b6c0bf50$@kernel.org>

Kukjin Kim wrote:
> 
> Hi Arnd, Olof, Kevin,
> 
> Here is Samsung non-critical-fixes for v4.3.
> Please pull.
> 
> Thanks,
> Kukjin
> 
Hi arm-soc maintainers,

Is there any problem on this series?
If not, please pull ;-)

Thanks,
Kukjin

> The following changes since commit d770e558e21961ad6cfdf0ff7df0eb5d7d4f0754:
> 
>   Linux 4.2-rc1 (2015-07-05 11:01:52 -0700)
> 
> are available in the git repository at:
> 
>   git://git.kernel.org/pub/scm/linux/kernel/git/kgene/linux-samsung.git
> tags/samsung-non-critical-1
> 
> for you to fetch changes up to 2cc6b813579415c4f627b08a043079bdc5b87a33:
> 
>   ARM: EXYNOS: Use IOMEM_ERR_PTR when function returns iomem (2015-07-21
> 13:19:06 +0900)
> 
> ----------------------------------------------------------------
> Samsung non-critical fixes for v4.3
> 
> - fix sparse warning for returning iomem
> - fix clock-frequency of display timing0 for exynos3250-rinato
> 
> ----------------------------------------------------------------
> Hyungwon Hwang (1):
>       ARM: dts: fix clock-frequency of display timing0 for exynos3250-rinato
> 
> Krzysztof Kozlowski (1):
>       ARM: EXYNOS: Use IOMEM_ERR_PTR when function returns iomem
> 
>  arch/arm/boot/dts/exynos3250-rinato.dts | 2 +-
>  arch/arm/mach-exynos/platsmp.c          | 2 +-
>  2 files changed, 2 insertions(+), 2 deletions(-)



From kgene at kernel.org  Sun Aug  9 18:27:18 2015
From: kgene at kernel.org (Kukjin Kim)
Date: Mon, 10 Aug 2015 10:27:18 +0900
Subject: [PATCH v4 0/6] cpufreq: use generic cpufreq drivers for Exynos4x12
 platform
In-Reply-To: <55C5AF4E.3010500@samsung.com>
References: <1438868514-8814-1-git-send-email-b.zolnierkie@samsung.com>
 <2359635.Hxe4cb8zKm@amdc1976> <20150807115627.GH6939@linux>
 <1525406.7aXvVQzEDd@vostro.rjw.lan> <20150808020740.GM6939@linux>
 <55C5AF4E.3010500@samsung.com>
Message-ID: <03ee01d0d30b$b279c490$176d4db0$@kernel.org>

Krzysztof Kozlowski wrote:
> 
> W dniu 08.08.2015 o 11:07, Viresh Kumar pisze:
> > On 08-08-15, 00:24, Rafael J. Wysocki wrote:
> >> OK, so please let me know which patches you want me to pick up.
> >>
> >> Ideally, I'd prefer them to be resent in a separate series with ACKs and all
> >> with a cover letter clearly stating whose tree they are being targeted at.
> >
> > He already sent it separately, let me send a confirmatory mail in
> > reply to that.
> 
> Dear Kukjin,
> 
> Can you apply the 2-5 of this series to v4.3? It's getting late but
> maybe they still could go?
> 
Once my previous pull-request landed into arm-soc, I'll try to send out this
series 2-5 for v4.3.

Thanks,
Kukjin



From k.kozlowski at samsung.com  Sun Aug  9 18:52:10 2015
From: k.kozlowski at samsung.com (Krzysztof Kozlowski)
Date: Mon, 10 Aug 2015 10:52:10 +0900
Subject: [GIT PULL] Samsung mach fixes for 4.2
Message-ID: <1439171530-971-1-git-send-email-k.kozlowski@samsung.com>

Dear Kukjin,

Please find latest two fixes for v4.2 cycle. You can find more detailed
description with the tag.

Best regards,
Krzysztof


The following changes since commit d770e558e21961ad6cfdf0ff7df0eb5d7d4f0754:

  Linux 4.2-rc1 (2015-07-05 11:01:52 -0700)

are available in the git repository at:

  https://github.com/krzk/linux.git tags/samsung-mach-fixes-4.2

for you to fetch changes up to 3e9f798784b30293012682021d5a0352f78658b8:

  ARM: EXYNOS: fix double of_node_put() on error path (2015-07-31 10:12:17 +0900)

----------------------------------------------------------------
Two fixes for bugs in Exynos power domain error exit path:
1. kfree() of read-only memory (name of power domain returned
   by kstrdup_const()),
2. Doubled of_node_put() leading to invalid ref count for OF node.

----------------------------------------------------------------
Vladimir Zapolskiy (2):
      ARM: EXYNOS: Fix potentian kfree() of ro memory
      ARM: EXYNOS: fix double of_node_put() on error path

 arch/arm/mach-exynos/pm_domains.c | 3 +--
 1 file changed, 1 insertion(+), 2 deletions(-)


From kgene at kernel.org  Sun Aug  9 19:04:25 2015
From: kgene at kernel.org (Kukjin Kim)
Date: Mon, 10 Aug 2015 11:04:25 +0900
Subject: [GIT PULL] Samsung mach fixes for 4.2
In-Reply-To: <1439171530-971-1-git-send-email-k.kozlowski@samsung.com>
References: <1439171530-971-1-git-send-email-k.kozlowski@samsung.com>
Message-ID: <040901d0d310$e233fde0$a69bf9a0$@kernel.org>

Hi arm-soc guys,

Can you please pull this into arm-soc fixes for v4.2 directly?
I don't have other samsung fixes in my tree at this moment.

Thanks,
Kukjin

Krzysztof Kozlowski wrote:
> 
> Dear Kukjin,
> 
> Please find latest two fixes for v4.2 cycle. You can find more detailed
> description with the tag.
> 
> Best regards,
> Krzysztof
> 
> 
> The following changes since commit d770e558e21961ad6cfdf0ff7df0eb5d7d4f0754:
> 
>   Linux 4.2-rc1 (2015-07-05 11:01:52 -0700)
> 
> are available in the git repository at:
> 
>   https://github.com/krzk/linux.git tags/samsung-mach-fixes-4.2
> 
> for you to fetch changes up to 3e9f798784b30293012682021d5a0352f78658b8:
> 
>   ARM: EXYNOS: fix double of_node_put() on error path (2015-07-31 10:12:17 +0900)
> 
> ----------------------------------------------------------------
> Two fixes for bugs in Exynos power domain error exit path:
> 1. kfree() of read-only memory (name of power domain returned
>    by kstrdup_const()),
> 2. Doubled of_node_put() leading to invalid ref count for OF node.
> 
> ----------------------------------------------------------------
> Vladimir Zapolskiy (2):
>       ARM: EXYNOS: Fix potentian kfree() of ro memory
>       ARM: EXYNOS: fix double of_node_put() on error path
> 
>  arch/arm/mach-exynos/pm_domains.c | 3 +--
>  1 file changed, 1 insertion(+), 2 deletions(-)



From 21cnbao at gmail.com  Sun Aug  9 19:35:12 2015
From: 21cnbao at gmail.com (Barry Song)
Date: Mon, 10 Aug 2015 10:35:12 +0800
Subject: [PATCH 5/7] clk: atlas7: fix the clock tree for bluetooth stuff
In-Reply-To: <55C2BBED.4050608@codeaurora.org>
References: <1438064845-17894-1-git-send-email-21cnbao@gmail.com>
 <1438064845-17894-6-git-send-email-21cnbao@gmail.com>
 <55B7FD22.10609@codeaurora.org>
 <CAGsJ_4wg1+5KrwTJRzE-iaSTvgvgFrM6cDyUTL16gx6Hk+tdPw@mail.gmail.com>
 <55C2BBED.4050608@codeaurora.org>
Message-ID: <CAGsJ_4y=TC1LXC1CPB=c1bfY7ZR0ktMD+hVuUZWxXXpyRR9zEw@mail.gmail.com>

2015-08-06 9:44 GMT+08:00 Stephen Boyd <sboyd at codeaurora.org>:
> On 07/29/2015 07:52 AM, Barry Song wrote:
>>
>> 2015-07-29 6:07 GMT+08:00 Stephen Boyd <sboyd at codeaurora.org>:
>>>
>>> On 07/27/2015 11:27 PM, Barry Song wrote:
>>>>
>>>> From: Guo Zeng <guo.zeng at csr.com>
>>>>
>>>> normally dmac should depends on only one clock, to operate
>>>> dmac internal register, but dmac4 is very special case, it
>>>> normally dmac should depends on only one clock, to operate
>>>> dmac internal register, but dmac4 is very special case, it
>>>
>>> The sentence is duplicated twice here
>>>
>>>> depends on two additional clock, the reason is that dmac4
>>>> is wrapped in hw into bt a7ca module, and accessing dmac4
>>>> internal register would also require that the a7ca_io and
>>>> related bt macro io clk also enabled.
>>>> here workaround this by setting depend clk into parent of
>>>> dmac4, and also related clks, to reflect dependency.
>>>
>>> We don't put clocks as parents of other clocks just because the child
>>> depends on the parent to be accessed. It isn't very clear from the
>>> description, but it sounds like a7ca_io is just another clock that the
>>> bluetooth driver needs to control? We want to express the true clk
>>> hierarchy, not some psuedo dependency tree.
>>>
>> Stephen, generically i agree the codes should be a map of real
>> hardware connection. here the problem is real hardware connection is
>> very much difficult for its drivers implementation and these clocks
>> are buggy designed in HW. they are not a tree, they are a "network".
>>
>> see attached diagram(hope LKML will not reject the attachment), we are
>> not a tree,  that means btm_noc_clk depends on btm_io_clk, a7ca_io_clk
>> depends on btm_io_clk, dmac4_io_clk depends on btm_noc_clk,
>> a7ca_io_clk and btm_noc_clk....
>> usp3_io_clk depends on uart6_io_clk, dmac4_io_clk, btm_noc_clk,
>> a7ca_io_clk and btm_noc_clk.
>>
>> so in the driver, we have a choice as below:
>> in uart6 driver, we take all of the clocks.
>> in dmac4 driver, we take all of btm_noc_clk, a7ca_io_clk and btm_noc_clk.
>> ...
>> what a ugly code! that is what we did before.
>>
>> so here, we moved to do a not-real clock tree,  that means
>> we makes
>> 1.btm_io_clk the parent of btm_noc_clk
>> 2. btm_noc_clk the parent of a7ca_io_clk
>> 3. a7ca_io_clk the parent of dmac4_io_clk
>> ...
>>
>> but it doesn't break any dependency of these clocks, and make all
>> clients driver as clean as a simple tree.
>> i strongly think we should keep this "workaround", otherwise, we have
>> many pain in all of the related drivers.
>>
>>
>
> Thanks for the nice PNG. It seems like you have a typical bus topology where
> UART and USP need to go through DMAC and the Data NOC to get out on the
> system bus. btm_io_clk is the true parent of all the clocks.
>
> I can only guess that A7CA is some sort of device that you have to go
> through from the CPU side to access the UART, USP, and DMAC hardware blocks.
> Is that right? Can you please describe what each of these blocks do and if
> there are linux drivers for them?
>
> One way to model this would be to make UART and USP children of the DMAC
> hardware block. And then make a driver/device up for the NOC and have the
> DMAC be a child of the NOC device. Then the NOC would probe and be runtime
> PM enabled to turn on the btm_noc_clk whenever it or its children are
> enabled. Then the DMAC device would do the same thing, but with the
> dmac4_io_clk, and the UART and USP devices would get the uart6_io_clk and
> usp3_io_clk respectively and enable/disable them when the device is active.
>
> That leaves us with the a7ca_io_clk, which is really just the clock for a
> bus that register read/writes go through. In designs I've seen, I usually
> left that clock under the control of each individual device that sits on the
> bus. So in this case, the DMAC, USP and UART device drivers would all need
> to get the a7ca_io_clk as their "interface" clock and make sure to enable or
> disable it whenever the driver wants to read/write the registers. I'm not
> sure if something else is done on the APB for you, but that may be all
> that's necessary.
>
> This actually points out a big problem we have right now in Linux, which is
> the lack of proper power management for the type of bus topology you see in
> embedded systems. Some of the genpd work going on may also be another
> solution to this problem, where we could group multiple devices into generic
> power domains that know to turn on 2 or 3 of the clocks. For example, the
> DMAC, USP, and UART device could all be in the APB power domain so that the
> a7ca_io_clk is enabled whenever one of those devices is active. And there
> could be another power domain for the NOC that encompasses all devices that
> are sitting on that NOC.
>

Stephen, this should be a possible option, i will talk with HW guys to
figure out the relationship of power domain, and check whether we
handle this issue by the power domain solution.

btw, would you apply other patches in this series at first? we can
hold on this one to find a final solution.

-barry


From dinh.linux at gmail.com  Sun Aug  9 20:15:56 2015
From: dinh.linux at gmail.com (dinh.linux at gmail.com)
Date: Sun,  9 Aug 2015 22:15:56 -0500
Subject: [GIT PULL] SoCFPGA DTS updates for v4.3, part 2
Message-ID: <1439176556-30367-1-git-send-email-dinh.linux@gmail.com>

Hi Arnd, Kevin, and Olof:

This is a 2nd pull-request for v4.3. Please consider pulling in this patches.

Thanks,
Dinh


The following changes since commit d770e558e21961ad6cfdf0ff7df0eb5d7d4f0754:

  Linux 4.2-rc1 (2015-07-05 11:01:52 -0700)

are available in the git repository at:

  git://git.kernel.org/pub/scm/linux/kernel/git/dinguyen/linux.git socfpga_dts_for_v4.3_part_2

for you to fetch changes up to 6855e5b7090330add9521d8947017875d5f4f88e:

  ARM: socfpga: dts: Add resets for EMACs on Arria10 (2015-08-09 21:58:58 -0500)

----------------------------------------------------------------
SoCFPGA DTS updates for v4.3, take 2
- Add DTS property "altr,modrst-offset" for reset driver to
  use
- Add updated reset defines for the reset driver
- Add reset property for EMACs on Arria10

----------------------------------------------------------------
Dinh Nguyen (3):
      dt-bindings: Add reset manager offsets for Arria10
      ARM: socfpga: dts: add "altr,modrst-offset" property
      ARM: socfpga: dts: Add resets for EMACs on Arria10

 .../devicetree/bindings/reset/socfpga-reset.txt    |   2 +
 arch/arm/boot/dts/socfpga.dtsi                     |   1 +
 arch/arm/boot/dts/socfpga_arria10.dtsi             |   6 ++
 include/dt-bindings/reset/altr,rst-mgr-a10.h       | 110 +++++++++++++++++++++
 4 files changed, 119 insertions(+)
 create mode 100644 include/dt-bindings/reset/altr,rst-mgr-a10.h


From ssantosh at kernel.org  Sun Aug  9 20:26:40 2015
From: ssantosh at kernel.org (Santosh Shilimkar)
Date: Sun,  9 Aug 2015 20:26:40 -0700
Subject: [GIT PULL] ARM: Couple of Keystone MDIO DTS fixes for 4.2-rc6+
Message-ID: <1439177200-32434-1-git-send-email-ssantosh@kernel.org>

ARM-SoC folks,

Please pull below couple of late fixes for 4.2-rc6+. I know its late
with rc6 already out but if possible please consider. 

The following changes since commit f7644cbfcdf03528f0f450f3940c4985b2291f49:

  Linux 4.2-rc6 (2015-08-09 15:54:30 -0400)

are available in the git repository at:

  git://git.kernel.org/pub/scm/linux/kernel/git/ssantosh/linux-keystone.git tags/keystone-dts-late-fixes

for you to fetch changes up to 6a024079862443b3ec9455931e9219cd5912656d:

  ARM: dts: keystone: Fix the mdio bindings by moving it to soc specific file (2015-08-09 20:06:27 -0700)

----------------------------------------------------------------
ARM: Couple of Keysyone MDIO DTS fixes for 4.2-rc6+

These are necessary to get the NIC card working on all Keystone
EVMs. Couple of boards are nroken without these two fixes.

----------------------------------------------------------------
Murali Karicheri (2):
      ARM: dts: keystone: fix the clock node for mdio
      ARM: dts: keystone: Fix the mdio bindings by moving it to soc specific file

 arch/arm/boot/dts/k2e.dtsi      | 15 +++++++++++----
 arch/arm/boot/dts/k2hk.dtsi     | 11 +++++++++++
 arch/arm/boot/dts/k2l.dtsi      | 16 +++++++++++-----
 arch/arm/boot/dts/keystone.dtsi | 11 -----------
 4 files changed, 33 insertions(+), 20 deletions(-)


Regards,
Santosh



From aneesh.kumar at linux.vnet.ibm.com  Sun Aug  9 23:01:12 2015
From: aneesh.kumar at linux.vnet.ibm.com (Aneesh Kumar K.V)
Date: Mon, 10 Aug 2015 11:31:12 +0530
Subject: [PATCH v4 2/7] mm: kasan: introduce generic
 kasan_populate_zero_shadow()
In-Reply-To: <1437756119-12817-3-git-send-email-a.ryabinin@samsung.com>
References: <1437756119-12817-1-git-send-email-a.ryabinin@samsung.com>
 <1437756119-12817-3-git-send-email-a.ryabinin@samsung.com>
Message-ID: <87mvxzptqv.fsf@linux.vnet.ibm.com>

Andrey Ryabinin <a.ryabinin at samsung.com> writes:

> Introduce generic kasan_populate_zero_shadow(start, end).
> This function maps kasan_zero_page to the [start, end] addresses.
>
> In follow on patches it will be used for ARMv8 (and maybe other
> architectures) and will replace x86_64 specific populate_zero_shadow().
>
> Signed-off-by: Andrey Ryabinin <a.ryabinin at samsung.com>

This assume that we can have shared pgtable_t in generic code ? Is that
true for generic code ? Even if it is we may want to allow some arch to
override this ? On ppc64, we store the hardware hash page table slot
number in pte_t, Hence we won't be able to share pgtable_t. 



> ---
>  arch/x86/mm/kasan_init_64.c |  14 ----
>  include/linux/kasan.h       |   8 +++
>  mm/kasan/Makefile           |   2 +-
>  mm/kasan/kasan_init.c       | 151 ++++++++++++++++++++++++++++++++++++++++++++
>  4 files changed, 160 insertions(+), 15 deletions(-)
>  create mode 100644 mm/kasan/kasan_init.c
>
> diff --git a/arch/x86/mm/kasan_init_64.c b/arch/x86/mm/kasan_init_64.c
> index e1840f3..812086c 100644
> --- a/arch/x86/mm/kasan_init_64.c
> +++ b/arch/x86/mm/kasan_init_64.c
> @@ -12,20 +12,6 @@
>  extern pgd_t early_level4_pgt[PTRS_PER_PGD];
>  extern struct range pfn_mapped[E820_X_MAX];
>  
> -static pud_t kasan_zero_pud[PTRS_PER_PUD] __page_aligned_bss;
> -static pmd_t kasan_zero_pmd[PTRS_PER_PMD] __page_aligned_bss;
> -static pte_t kasan_zero_pte[PTRS_PER_PTE] __page_aligned_bss;
> -
> -/*

-aneesh



From viresh.kumar at linaro.org  Sun Aug  9 23:12:29 2015
From: viresh.kumar at linaro.org (Viresh Kumar)
Date: Mon, 10 Aug 2015 11:42:29 +0530
Subject: [PATCH V1 Resend 07/11] drivers: rtc: Drop (un)likely before
 IS_ERR(_OR_NULL)
In-Reply-To: <cover.1439187003.git.viresh.kumar@linaro.org>
References: <cover.1439187003.git.viresh.kumar@linaro.org>
Message-ID: <2ea7e46d3a63b1229889b1e8f0a9976725578189.1439187003.git.viresh.kumar@linaro.org>

IS_ERR(_OR_NULL) already contain an 'unlikely' compiler flag and there
is no need to do that again from its callers. Drop it.

gemini driver was using likely() for a failure case while the rtc driver
is getting registered. That looks wrong and it should really be
unlikely. But because we are killing all the unlikely() flags, lets kill
that too.

Acked-by: Hans Ulli Kroll <ulli.kroll at googlemail.com> (gemini)
Signed-off-by: Viresh Kumar <viresh.kumar at linaro.org>
---
 drivers/rtc/interface.c  | 2 +-
 drivers/rtc/rtc-bfin.c   | 2 +-
 drivers/rtc/rtc-gemini.c | 2 +-
 3 files changed, 3 insertions(+), 3 deletions(-)

diff --git a/drivers/rtc/interface.c b/drivers/rtc/interface.c
index 11b639067312..5836751b8203 100644
--- a/drivers/rtc/interface.c
+++ b/drivers/rtc/interface.c
@@ -564,7 +564,7 @@ enum hrtimer_restart rtc_pie_update_irq(struct hrtimer *timer)
 void rtc_update_irq(struct rtc_device *rtc,
 		unsigned long num, unsigned long events)
 {
-	if (unlikely(IS_ERR_OR_NULL(rtc)))
+	if (IS_ERR_OR_NULL(rtc))
 		return;
 
 	pm_stay_awake(rtc->dev.parent);
diff --git a/drivers/rtc/rtc-bfin.c b/drivers/rtc/rtc-bfin.c
index 3d44b11721ea..535a5f9338d0 100644
--- a/drivers/rtc/rtc-bfin.c
+++ b/drivers/rtc/rtc-bfin.c
@@ -361,7 +361,7 @@ static int bfin_rtc_probe(struct platform_device *pdev)
 	/* Register our RTC with the RTC framework */
 	rtc->rtc_dev = devm_rtc_device_register(dev, pdev->name, &bfin_rtc_ops,
 						THIS_MODULE);
-	if (unlikely(IS_ERR(rtc->rtc_dev)))
+	if (IS_ERR(rtc->rtc_dev))
 		return PTR_ERR(rtc->rtc_dev);
 
 	/* Grab the IRQ and init the hardware */
diff --git a/drivers/rtc/rtc-gemini.c b/drivers/rtc/rtc-gemini.c
index 35f4486738fc..2fed93e1114a 100644
--- a/drivers/rtc/rtc-gemini.c
+++ b/drivers/rtc/rtc-gemini.c
@@ -148,7 +148,7 @@ static int gemini_rtc_probe(struct platform_device *pdev)
 
 	rtc->rtc_dev = rtc_device_register(pdev->name, dev,
 					   &gemini_rtc_ops, THIS_MODULE);
-	if (likely(IS_ERR(rtc->rtc_dev)))
+	if (IS_ERR(rtc->rtc_dev))
 		return PTR_ERR(rtc->rtc_dev);
 
 	return 0;
-- 
2.4.0



From wxt at rock-chips.com  Sun Aug  9 23:34:57 2015
From: wxt at rock-chips.com (Caesar Wang)
Date: Mon, 10 Aug 2015 14:34:57 +0800
Subject: [PATCH] thermal: rockhip: fix setting thermal shutdown polarity
In-Reply-To: <20150807210052.GA34032@dtor-ws>
References: <20150807210052.GA34032@dtor-ws>
Message-ID: <55C84611.10904@rock-chips.com>

Dear Dmitry,

Thanks to work for it.

? 2015?08?08? 05:00, Dmitry Torokhov ??:
> When requested thermal shutdown signal polarity is low we need to make
> sure that the bit representing high level of signal is reset, and not
> set all other bits in that register.
>
> Also rename TSADCV2_INT_PD_CLEAR to TSADCV2_INT_PD_CLEAR_MASK to better
> reflect its nature.
>
> Signed-off-by: Dmitry Torokhov <dtor at chromium.org>

  Acked-by: Caesar Wang <wxt at rock-chips.com>

--
Thanks,
Caesar

> ---
>   drivers/thermal/rockchip_thermal.c | 10 ++++------
>   1 file changed, 4 insertions(+), 6 deletions(-)
>
> diff --git a/drivers/thermal/rockchip_thermal.c b/drivers/thermal/rockchip_thermal.c
> index 93ee307..4d5b7d4 100644
> --- a/drivers/thermal/rockchip_thermal.c
> +++ b/drivers/thermal/rockchip_thermal.c
> @@ -106,16 +106,14 @@ struct rockchip_thermal_data {
>   #define TSADCV2_AUTO_PERIOD_HT			0x6c
>   
>   #define TSADCV2_AUTO_EN				BIT(0)
> -#define TSADCV2_AUTO_DISABLE			~BIT(0)
>   #define TSADCV2_AUTO_SRC_EN(chn)		BIT(4 + (chn))
>   #define TSADCV2_AUTO_TSHUT_POLARITY_HIGH	BIT(8)
> -#define TSADCV2_AUTO_TSHUT_POLARITY_LOW		~BIT(8)
>   
>   #define TSADCV2_INT_SRC_EN(chn)			BIT(chn)
>   #define TSADCV2_SHUT_2GPIO_SRC_EN(chn)		BIT(4 + (chn))
>   #define TSADCV2_SHUT_2CRU_SRC_EN(chn)		BIT(8 + (chn))
>   
> -#define TSADCV2_INT_PD_CLEAR			~BIT(8)
> +#define TSADCV2_INT_PD_CLEAR_MASK		~BIT(8)
>   
>   #define TSADCV2_DATA_MASK			0xfff
>   #define TSADCV2_HIGHT_INT_DEBOUNCE_COUNT	4
> @@ -244,10 +242,10 @@ static void rk_tsadcv2_initialize(void __iomem *regs,
>   				  enum tshut_polarity tshut_polarity)
>   {
>   	if (tshut_polarity == TSHUT_HIGH_ACTIVE)
> -		writel_relaxed(0 | (TSADCV2_AUTO_TSHUT_POLARITY_HIGH),
> +		writel_relaxed(0U | TSADCV2_AUTO_TSHUT_POLARITY_HIGH,
>   			       regs + TSADCV2_AUTO_CON);
>   	else
> -		writel_relaxed(0 | (TSADCV2_AUTO_TSHUT_POLARITY_LOW),
> +		writel_relaxed(0U & ~TSADCV2_AUTO_TSHUT_POLARITY_HIGH,
>   			       regs + TSADCV2_AUTO_CON);
>   
>   	writel_relaxed(TSADCV2_AUTO_PERIOD_TIME, regs + TSADCV2_AUTO_PERIOD);
> @@ -264,7 +262,7 @@ static void rk_tsadcv2_irq_ack(void __iomem *regs)
>   	u32 val;
>   
>   	val = readl_relaxed(regs + TSADCV2_INT_PD);
> -	writel_relaxed(val & TSADCV2_INT_PD_CLEAR, regs + TSADCV2_INT_PD);
> +	writel_relaxed(val & TSADCV2_INT_PD_CLEAR_MASK, regs + TSADCV2_INT_PD);
>   }
>   
>   static void rk_tsadcv2_control(void __iomem *regs, bool enable)




From maitysanchayan at gmail.com  Sun Aug  9 23:35:08 2015
From: maitysanchayan at gmail.com (maitysanchayan at gmail.com)
Date: Mon, 10 Aug 2015 12:05:08 +0530
Subject: [PATCH v2] iio: adc: vf610: Add IIO buffer support for Vybrid ADC
In-Reply-To: <55C64E68.8010500@kernel.org>
References: <cover.1438775572.git.maitysanchayan@gmail.com>
 <1bb1f290da601bbda41875a92ba6e983b423d7b0.1438775572.git.maitysanchayan@gmail.com>
 <55C6125B.1060103@kernel.org>
 <20150808172200.GA2758@Sanchayan-Arch>
 <55C64E68.8010500@kernel.org>
Message-ID: <20150810063508.GA2273@Sanchayan-Arch.toradex.int>

Hello,

On 15-08-08 19:46:00, Jonathan Cameron wrote:
> On 08/08/15 18:22, maitysanchayan at gmail.com wrote:
> > Hello Jonathan,
> > 
> > On 15-08-08 15:29:47, Jonathan Cameron wrote:
> >> On 05/08/15 13:10, Sanchayan Maity wrote:
> >>> This patch adds support for IIO buffer to the Vybrid ADC driver.
> >>> IIO triggered buffer infrastructure along with iio sysfs trigger
> >>> is used to leverage continuous sampling support provided by the
> >>> ADC block.
> >> Looking good.  Just a couple more bits and pieces inline from me.
> >> One or two of which aren't corrected from Peter's review of v1.
> >>
> >> I will want Fugang Dong's ack / review tag on the final version
> >> before applying it however.
> > 
> > Sure.
> > 
> >> This driver is some distance form my area of expertise!
> > 
> > I doubt :).
> > 
> >>
> >> Jonathan
> >>>
> >>> Signed-off-by: Sanchayan Maity <maitysanchayan at gmail.com>
> >>> ---
> >>>  drivers/iio/adc/Kconfig     |   4 ++
> >>>  drivers/iio/adc/vf610_adc.c | 107 +++++++++++++++++++++++++++++++++++++++++---
> >>>  2 files changed, 105 insertions(+), 6 deletions(-)
> >>>
> >>> diff --git a/drivers/iio/adc/Kconfig b/drivers/iio/adc/Kconfig
> >>> index 7c55658..4661241 100644
> >>> --- a/drivers/iio/adc/Kconfig
> >>> +++ b/drivers/iio/adc/Kconfig
> >>> @@ -337,6 +337,10 @@ config TWL6030_GPADC
> >>>  config VF610_ADC
> >>>  	tristate "Freescale vf610 ADC driver"
> >>>  	depends on OF
> >>> +	select IIO_BUFFER
> >>> +	select IIO_TRIGGER
> >>> +	select IIO_SYSFS_TRIGGER
> >> Unless I missed something there is no dependency on this particular
> >> trigger (it just happens to be the one you've been testing with I guess).
> >> Could be driven from a hardware trigger belonging to another device for
> >> example.
> > 
> > Yes right in a way. Right now we do not provide or there is no provision
> > for hardware triggers. On the Vybrid, the Peripheral Delay Block (PDB)
> > does the job of providing support for software and hardware triggers. PDB
> > support is not yet there in Linux however. 
> Not supplying a trigger is fine, but any trigger (that allows other devices
> to bind to it) will be fine.

Ok.

> > 
> > There is also the question of where the Vybrid PDB driver would belong
> > to? In the TRM it is put in the timers but the kernel has no generic timer
> > framework that I am aware of.
> It's been debated a number of times, but no one has ever written one.
> Not seen anything recently on this topic..  Lars, you seen anything?
> (the blackfin-timer trigger is similar to what you are describing I think).
> 
> > After some internal reviews we decided to
> > do a platform driver which provided functions ADC driver could called into.
> Does rather feel like there ought to be at least a standard home for these.
> Might be worth asking the arm-soc guys...
> > 
> > I have a patchset ready which provides trigger support using PDB however
> > configuring the PDB properly has proven to be tricky. While it works but
> > not reliably with multiple channels and it would be a while before I get
> > that working and post that patchset. So kind of stalled there and just
> > because of two registers which need to be written with the correct value
> > :). For what it's worth if someone comes across this, some discussion
> > here [1] along with patches. (Note however those are a bit old patches
> > not exactly my new work).
> > 
> > Sorry for digressing from the topic. Anyways so the idea was to provide
> > sysfs triggers as default for using this continuous sampling. Later the
> > driver may provide additional triggers. So for now I added the sysfs
> > trigger as a select option so that a user won't have to recompile the
> > kernel for using the buffers with continuous sampling.
> It's a policy decision so should really be left to the distro builders.
> There are lots of possible triggers out there (though sysfs might be
> the most likely one!)
> 
> Hence don't put the select there in Kconfig.  We should shortly have
> Daniel's update to the patches for the high resolution timer
> which would give another obvious choice for starters.

Alright. Will drop that iio sysfs tigger select from the Kconfig.

> 
> I doubt many distros build without the sysfs triggers but with other IIO
> stuff.
> 
> > 
> >>
> >>> +	select IIO_TRIGGERED_BUFFER
> >>>  	help
> >>>  	  Say yes here to support for Vybrid board analog-to-digital converter.
> >>>  	  Since the IP is used for i.MX6SLX, the driver also support i.MX6SLX.
> >>> diff --git a/drivers/iio/adc/vf610_adc.c b/drivers/iio/adc/vf610_adc.c
> >>> index 23b8fb9..97cb2ed 100644
> >>> --- a/drivers/iio/adc/vf610_adc.c
> >>> +++ b/drivers/iio/adc/vf610_adc.c
> >>> @@ -34,8 +34,11 @@
> >>>  #include <linux/err.h>
> >>>  
> >>>  #include <linux/iio/iio.h>
> >>> +#include <linux/iio/buffer.h>
> >>>  #include <linux/iio/sysfs.h>
> >>> -#include <linux/iio/driver.h>
> >>> +#include <linux/iio/trigger.h>
> >>> +#include <linux/iio/trigger_consumer.h>
> >>> +#include <linux/iio/triggered_buffer.h>
> >>>  
> >>>  /* This will be the driver name the kernel reports */
> >>>  #define DRIVER_NAME "vf610-adc"
> >>> @@ -170,6 +173,7 @@ struct vf610_adc {
> >>>  	u32 sample_freq_avail[5];
> >>>  
> >>>  	struct completion completion;
> >>> +	u16 buffer[2];
> >> Note the requirements on the buffer provided to
> >> iio_push_to_buffers_with_timestamp
> >> Needs to be u16 buffer[8] to allow for the aligned 64bit (4 word) timestamp.
> >>
> >> Peter pointed this out in his follow up email and you said you'd implement
> >> it.. Guessing this got lost somewhere.
> > 
> > No, I meant to implement what Peter recommended but I guess I did not completely
> > grasp what he intended. Sorry about that. Will fix this and ask further if in
> > more doubts.
> > 
> >>
> >>
> >>>  };
> >>>  
> >>>  static const u32 vf610_hw_avgs[] = { 1, 4, 8, 16, 32 };
> >>> @@ -505,12 +509,22 @@ static const struct iio_chan_spec_ext_info vf610_ext_info[] = {
> >>>  	.info_mask_shared_by_type = BIT(IIO_CHAN_INFO_SCALE) |	\
> >>>  				BIT(IIO_CHAN_INFO_SAMP_FREQ),	\
> >>>  	.ext_info = vf610_ext_info,				\
> >>> +	.address = (_idx),				\
> >>> +	.scan_index = (_idx),			\
> >>> +	.scan_type.sign = 'u',			\
> >>> +	.scan_type.realbits = 12,		\
> >>> +	.scan_type.storagebits = 16,	\
> >>>  }
> >>>  
> >>>  #define VF610_ADC_TEMPERATURE_CHAN(_idx, _chan_type) {	\
> >>>  	.type = (_chan_type),	\
> >>>  	.channel = (_idx),		\
> >>>  	.info_mask_separate = BIT(IIO_CHAN_INFO_PROCESSED),	\
> >>> +	.address = (_idx),						\
> >>> +	.scan_index = (_idx),					\
> >> .scan_type = {
> >> 	   .sign = 'u',
> >> 	   etc.
> >>
> >> Peter picked up on this..
> > 
> > Sorry yes missed that. Will definitely fix.
> > 
> >>
> >>> +	.scan_type.sign = 'u',					\
> >>> +	.scan_type.realbits = 12,				\
> >>> +	.scan_type.storagebits = 16,			\
> >>>  }
> >>>  
> >>>  static const struct iio_chan_spec vf610_adc_iio_channels[] = {
> >>> @@ -531,6 +545,7 @@ static const struct iio_chan_spec vf610_adc_iio_channels[] = {
> >>>  	VF610_ADC_CHAN(14, IIO_VOLTAGE),
> >>>  	VF610_ADC_CHAN(15, IIO_VOLTAGE),
> >>>  	VF610_ADC_TEMPERATURE_CHAN(26, IIO_TEMP),
> >>> +	IIO_CHAN_SOFT_TIMESTAMP(32),
> >> It's bit extreme throwing it out at scan_index 32.  Is there a reason
> >> to think that migh be neccesary?  Mind you, why is the temperature
> >> channel down at 26?  Are we dealing with a set of reserved real channels
> >> inbetween?
> > 
> > 
> > The temperature channel is the 26th channel and there are some reserved
> > channels in between. 31st is the channel which acts as a conversion
> > disabled setting. So I put the timestamp at index 32.
> Fair enough if weird ;)
> > 
> > 
> >>>  	/* sentinel */
> >>>  };
> >>>  
> >>> @@ -559,13 +574,20 @@ static int vf610_adc_read_data(struct vf610_adc *info)
> >>>  
> >>>  static irqreturn_t vf610_adc_isr(int irq, void *dev_id)
> >>>  {
> >>> -	struct vf610_adc *info = (struct vf610_adc *)dev_id;
> >>> +	struct iio_dev *indio_dev = (struct iio_dev *)dev_id;
> >>> +	struct vf610_adc *info = iio_priv(indio_dev);
> >>>  	int coco;
> >>>  
> >>>  	coco = readl(info->regs + VF610_REG_ADC_HS);
> >>>  	if (coco & VF610_ADC_HS_COCO0) {
> >>>  		info->value = vf610_adc_read_data(info);
> >>
> >> I'd be tempted to make the non buffered path also use
> >> info->bufffer[0] and drop info->value entirely.
> >> A more invasive patch, but a cleaner resulting code (slightly!)
> > 
> > I did think of that but decided against it as I wanted the changes
> > to as less invasive as possible making only the necessary changes
> > and keeping the old code as is.
> You could do this then clean up in a follow up patch which would be
> really easy to review.

Ok. Will implement the same with a follow up second patch in the third
revision.

- Sanchayan.

> > 
> >>> -		complete(&info->completion);
> >>> +		if (iio_buffer_enabled(indio_dev)) {
> >>> +			info->buffer[0] = info->value;
> >>> +			iio_push_to_buffers_with_timestamp(indio_dev,
> >>> +					info->buffer, iio_get_time_ns());
> >>> +			iio_trigger_notify_done(indio_dev->trig);
> >>> +		} else
> >>> +			complete(&info->completion);
> >>>  	}
> >>>  
> >>>  	return IRQ_HANDLED;
> >>> @@ -612,6 +634,9 @@ static int vf610_read_raw(struct iio_dev *indio_dev,
> >>>  	switch (mask) {
> >>>  	case IIO_CHAN_INFO_RAW:
> >>>  	case IIO_CHAN_INFO_PROCESSED:
> >>
> >> To avoid possible races this check should be done under the mlock
> > 
> > Thanks for picking this. Somehow I remember seeing it outside of the
> > mlock. However grepping again shows otherwise. Will fix.
> > 
> > .
> >>> +		if (iio_buffer_enabled(indio_dev))
> >>> +			return -EBUSY;
> >>> +
> >>>  		mutex_lock(&indio_dev->mlock);
> >>>  		reinit_completion(&info->completion);
> >>>  
> >>> @@ -694,6 +719,68 @@ static int vf610_write_raw(struct iio_dev *indio_dev,
> >>>  	return -EINVAL;
> >>>  }
> >>>  
> >>> +static int vf610_adc_buffer_postenable(struct iio_dev *indio_dev)
> >>> +{
> >>> +	struct vf610_adc *info = iio_priv(indio_dev);
> >>> +	unsigned int channel;
> >>> +	int ret;
> >>> +	int val;
> >>> +
> >>> +	ret = iio_triggered_buffer_postenable(indio_dev);
> >>> +	if (ret)
> >>> +		return ret;
> >>> +
> >>> +	val = readl(info->regs + VF610_REG_ADC_GC);
> >>> +	val |= VF610_ADC_ADCON;
> >>> +	writel(val, info->regs + VF610_REG_ADC_GC);
> >>> +
> >>> +	channel = find_first_bit(indio_dev->active_scan_mask,
> >>> +						indio_dev->masklength);
> >>> +
> >>> +	val = VF610_ADC_ADCHC(channel);
> >>> +	val |= VF610_ADC_AIEN;
> >>> +
> >>> +	writel(val, info->regs + VF610_REG_ADC_HC0);
> >>> +
> >>> +	return 0;
> >>> +}
> >>> +
> >>> +static int vf610_adc_buffer_postdisable(struct iio_dev *indio_dev)
> >>> +{
> >>> +	struct vf610_adc *info = iio_priv(indio_dev);
> >>> +	unsigned int hc_cfg = 0;
> >>> +	int val;
> >>> +
> >>> +	val = readl(info->regs + VF610_REG_ADC_GC);
> >>> +	val &= ~VF610_ADC_ADCON;
> >>> +	writel(val, info->regs + VF610_REG_ADC_GC);
> >>> +
> >>> +	hc_cfg |= VF610_ADC_CONV_DISABLE;
> >>> +	hc_cfg &= ~VF610_ADC_AIEN;
> >>> +
> >>> +	writel(hc_cfg, info->regs + VF610_REG_ADC_HC0);
> >>> +
> >>> +	return 0;
> >>> +}
> >>> +
> >>> +static const struct iio_buffer_setup_ops iio_triggered_buffer_setup_ops = {
> >>> +	.postenable = &vf610_adc_buffer_postenable,
> >>> +	.predisable = &iio_triggered_buffer_predisable,
> >>> +	.postdisable = &vf610_adc_buffer_postdisable,
> >>> +	.validate_scan_mask = &iio_validate_scan_mask_onehot,
> >>> +};
> >>> +
> >>> +static int vf610_adc_buffer_init(struct iio_dev *indio_dev)
> >>> +{
> >>> +	return iio_triggered_buffer_setup(indio_dev, &iio_pollfunc_store_time,
> >>> +		NULL, &iio_triggered_buffer_setup_ops);
> >>> +}
> >>> +
> >>> +static void vf610_adc_buffer_remove(struct iio_dev *indio_dev)
> >>> +{
> >>> +	iio_triggered_buffer_cleanup(indio_dev);
> >>> +}
> >> These to wrappers seem a little superflous. I'd have just put the code
> >> inline, but it's obviously a matter of personal taste and I don't care
> >> that much!
> > 
> > Ok. I do not have strong opinions on this. I just tried to follow how the
> > at91 adc code did it considering it as a good example. Will drop it.
> > 
> >>
> >>> +
> >>>  static int vf610_adc_reg_access(struct iio_dev *indio_dev,
> >>>  			unsigned reg, unsigned writeval,
> >>>  			unsigned *readval)
> >>> @@ -753,7 +840,7 @@ static int vf610_adc_probe(struct platform_device *pdev)
> >>>  
> >>>  	ret = devm_request_irq(info->dev, irq,
> >>>  				vf610_adc_isr, 0,
> >>> -				dev_name(&pdev->dev), info);
> >>> +				dev_name(&pdev->dev), indio_dev);
> >>>  	if (ret < 0) {
> >>>  		dev_err(&pdev->dev, "failed requesting irq, irq = %d\n", irq);
> >>>  		return ret;
> >>> @@ -806,15 +893,22 @@ static int vf610_adc_probe(struct platform_device *pdev)
> >>>  	vf610_adc_cfg_init(info);
> >>>  	vf610_adc_hw_init(info);
> >>>  
> >>> +	ret = vf610_adc_buffer_init(indio_dev);
> >>> +	if (ret < 0) {
> >>> +		dev_err(&pdev->dev, "Couldn't initialise the buffer\n");
> >>> +		goto error_iio_device_register;
> >>> +	}
> >>> +
> >>>  	ret = iio_device_register(indio_dev);
> >>>  	if (ret) {
> >>>  		dev_err(&pdev->dev, "Couldn't register the device.\n");
> >>> -		goto error_iio_device_register;
> >>> +		goto error_adc_buffer_init;
> >>>  	}
> >>>  
> >>>  	return 0;
> >>>  
> >>> -
> >>> +error_adc_buffer_init:
> >>> +	vf610_adc_buffer_remove(indio_dev);
> >>>  error_iio_device_register:
> >>>  	clk_disable_unprepare(info->clk);
> >>>  error_adc_clk_enable:
> >>> @@ -829,6 +923,7 @@ static int vf610_adc_remove(struct platform_device *pdev)
> >>>  	struct vf610_adc *info = iio_priv(indio_dev);
> >>>  
> >>>  	iio_device_unregister(indio_dev);
> >>> +	vf610_adc_buffer_remove(indio_dev);
> >>>  	regulator_disable(info->vref);
> >>>  	clk_disable_unprepare(info->clk);
> >>>  
> >>>
> >>
> > 
> > Thanks for the review.
> > 
> > - Sanchayan.
> > 
> > [1]. https://community.freescale.com/thread/357619
> > 
> 


From wxt at rock-chips.com  Sun Aug  9 23:37:42 2015
From: wxt at rock-chips.com (Caesar Wang)
Date: Mon, 10 Aug 2015 14:37:42 +0800
Subject: [PATCH] thermal: rockhip: fix setting thermal shutdown polarity
In-Reply-To: <55C84611.10904@rock-chips.com>
References: <20150807210052.GA34032@dtor-ws> <55C84611.10904@rock-chips.com>
Message-ID: <55C846B6.2050303@rock-chips.com>

Sorry, forgot it!
\s 'rockhip' to 'rockchip' :-)

? 2015?08?10? 14:34, Caesar Wang ??:
> Dear Dmitry,
>
> Thanks to work for it.
>
> ? 2015?08?08? 05:00, Dmitry Torokhov ??:
>> When requested thermal shutdown signal polarity is low we need to make
>> sure that the bit representing high level of signal is reset, and not
>> set all other bits in that register.
>>
>> Also rename TSADCV2_INT_PD_CLEAR to TSADCV2_INT_PD_CLEAR_MASK to better
>> reflect its nature.
>>
>> Signed-off-by: Dmitry Torokhov <dtor at chromium.org>
>
>  Acked-by: Caesar Wang <wxt at rock-chips.com>
>
> -- 
> Thanks,
> Caesar
>
>> ---
>>   drivers/thermal/rockchip_thermal.c | 10 ++++------
>>   1 file changed, 4 insertions(+), 6 deletions(-)
>>
>> diff --git a/drivers/thermal/rockchip_thermal.c 
>> b/drivers/thermal/rockchip_thermal.c
>> index 93ee307..4d5b7d4 100644
>> --- a/drivers/thermal/rockchip_thermal.c
>> +++ b/drivers/thermal/rockchip_thermal.c
>> @@ -106,16 +106,14 @@ struct rockchip_thermal_data {
>>   #define TSADCV2_AUTO_PERIOD_HT            0x6c
>>     #define TSADCV2_AUTO_EN                BIT(0)
>> -#define TSADCV2_AUTO_DISABLE            ~BIT(0)
>>   #define TSADCV2_AUTO_SRC_EN(chn)        BIT(4 + (chn))
>>   #define TSADCV2_AUTO_TSHUT_POLARITY_HIGH    BIT(8)
>> -#define TSADCV2_AUTO_TSHUT_POLARITY_LOW        ~BIT(8)
>>     #define TSADCV2_INT_SRC_EN(chn)            BIT(chn)
>>   #define TSADCV2_SHUT_2GPIO_SRC_EN(chn)        BIT(4 + (chn))
>>   #define TSADCV2_SHUT_2CRU_SRC_EN(chn)        BIT(8 + (chn))
>>   -#define TSADCV2_INT_PD_CLEAR            ~BIT(8)
>> +#define TSADCV2_INT_PD_CLEAR_MASK        ~BIT(8)
>>     #define TSADCV2_DATA_MASK            0xfff
>>   #define TSADCV2_HIGHT_INT_DEBOUNCE_COUNT    4
>> @@ -244,10 +242,10 @@ static void rk_tsadcv2_initialize(void __iomem 
>> *regs,
>>                     enum tshut_polarity tshut_polarity)
>>   {
>>       if (tshut_polarity == TSHUT_HIGH_ACTIVE)
>> -        writel_relaxed(0 | (TSADCV2_AUTO_TSHUT_POLARITY_HIGH),
>> +        writel_relaxed(0U | TSADCV2_AUTO_TSHUT_POLARITY_HIGH,
>>                      regs + TSADCV2_AUTO_CON);
>>       else
>> -        writel_relaxed(0 | (TSADCV2_AUTO_TSHUT_POLARITY_LOW),
>> +        writel_relaxed(0U & ~TSADCV2_AUTO_TSHUT_POLARITY_HIGH,
>>                      regs + TSADCV2_AUTO_CON);
>>         writel_relaxed(TSADCV2_AUTO_PERIOD_TIME, regs + 
>> TSADCV2_AUTO_PERIOD);
>> @@ -264,7 +262,7 @@ static void rk_tsadcv2_irq_ack(void __iomem *regs)
>>       u32 val;
>>         val = readl_relaxed(regs + TSADCV2_INT_PD);
>> -    writel_relaxed(val & TSADCV2_INT_PD_CLEAR, regs + TSADCV2_INT_PD);
>> +    writel_relaxed(val & TSADCV2_INT_PD_CLEAR_MASK, regs + 
>> TSADCV2_INT_PD);
>>   }
>>     static void rk_tsadcv2_control(void __iomem *regs, bool enable)
>




From jassisinghbrar at gmail.com  Sun Aug  9 23:45:33 2015
From: jassisinghbrar at gmail.com (Jassi Brar)
Date: Mon, 10 Aug 2015 12:15:33 +0530
Subject: [PATCH v2 5/6] mailbox: Add generic mechanism for testing Mailbox
 Controllers
In-Reply-To: <1437990272-23111-6-git-send-email-lee.jones@linaro.org>
References: <1437990272-23111-1-git-send-email-lee.jones@linaro.org>
 <1437990272-23111-6-git-send-email-lee.jones@linaro.org>
Message-ID: <CABb+yY20nQbiEEZeRvWTMUsJ2qgwRn8CrWvnFDSB-b1dgVaAuw@mail.gmail.com>

On Mon, Jul 27, 2015 at 3:14 PM, Lee Jones <lee.jones at linaro.org> wrote:
> This particular Client implementation uses shared memory in order
> to pass messages between Mailbox users; however, it can be easily
> hacked to support any type of Controller.
>
> Signed-off-by: Lee Jones <lee.jones at linaro.org>
> ---
>  drivers/mailbox/Kconfig        |   7 ++
>  drivers/mailbox/Makefile       |   2 +
>  drivers/mailbox/mailbox-test.c | 210 +++++++++++++++++++++++++++++++++++++++++
>  3 files changed, 219 insertions(+)
>  create mode 100644 drivers/mailbox/mailbox-test.c
>
> diff --git a/drivers/mailbox/Kconfig b/drivers/mailbox/Kconfig
> index 2cc4c39..7720bde 100644
> --- a/drivers/mailbox/Kconfig
> +++ b/drivers/mailbox/Kconfig
> @@ -77,4 +77,11 @@ config STI_MBOX
>           Mailbox implementation for STMicroelectonics family chips with
>           hardware for interprocessor communication.
>
> +config MAILBOX_TEST
> +       tristate "Mailbox Test Client"
> +       depends on OF
> +       help
> +         Test client to help with testing new Controller driver
> +         implementations.
> +
>  endif
> diff --git a/drivers/mailbox/Makefile b/drivers/mailbox/Makefile
> index 7cb4766..92435ef 100644
> --- a/drivers/mailbox/Makefile
> +++ b/drivers/mailbox/Makefile
> @@ -2,6 +2,8 @@
>
>  obj-$(CONFIG_MAILBOX)          += mailbox.o
>
> +obj-$(CONFIG_MAILBOX_TEST)     += mailbox-test.o
> +
>  obj-$(CONFIG_ARM_MHU)  += arm_mhu.o
>
>  obj-$(CONFIG_PL320_MBOX)       += pl320-ipc.o
> diff --git a/drivers/mailbox/mailbox-test.c b/drivers/mailbox/mailbox-test.c
> new file mode 100644
> index 0000000..10bfe3a
> --- /dev/null
> +++ b/drivers/mailbox/mailbox-test.c
> @@ -0,0 +1,210 @@
> +/*
> + * Copyright (C) 2015 ST Microelectronics
> + *
> + * Author: Lee Jones <lee.jones at linaro.org>
> + *
> + * This program is free software; you can redistribute it and/or modify
> + * it under the terms of the GNU General Public License as published by
> + * the Free Software Foundation; either version 2 of the License, or
> + * (at your option) any later version.
> + */
> +
> +#include <linux/debugfs.h>
> +#include <linux/err.h>
> +#include <linux/kernel.h>
> +#include <linux/mailbox_client.h>
> +#include <linux/module.h>
> +#include <linux/of.h>
> +#include <linux/platform_device.h>
> +#include <linux/slab.h>
> +#include <linux/uaccess.h>
> +
> +#define MBOX_MAX_MSG_LEN 128
> +
> +static struct dentry *root_debugfs_dir;
> +
> +struct mbox_test_device {
> +       struct device           *dev;
> +       struct mbox_chan        *tx_channel;
> +       struct mbox_chan        *rx_channel;
> +       void __iomem            *mmio;
> +
> +};
> +
> +static ssize_t mbox_test_write(struct file *filp,
> +                              const char __user *userbuf,
> +                              size_t count, loff_t *ppos)
> +{
> +       struct mbox_test_device *tdev = filp->private_data;
> +       char *message;
> +       int ret;
> +
> +       if (count > MBOX_MAX_MSG_LEN) {
> +               dev_err(tdev->dev,
> +                       "Message length %d greater than max allowed %d\n",
> +                       count, MBOX_MAX_MSG_LEN);
> +               return -EINVAL;
> +       }
> +
> +       message = kzalloc(count, GFP_KERNEL);
> +       if (!message)
> +               return -ENOMEM;
> +
> +       ret = copy_from_user(message, userbuf, count);
> +       if (ret)
> +               return -EFAULT;
> +
> +       print_hex_dump(KERN_ERR, "Client: Sending: ", DUMP_PREFIX_ADDRESS,
> +                      16, 1, message, 16, true);
> +
> +       ret = mbox_send_message(tdev->tx_channel, message);
> +       if (ret < 0)
> +               dev_err(tdev->dev, "Failed to send message via mailbox\n");
> +
> +       kfree(message);
> +
> +       return ret < 0 ? ret : count;
> +}
> +
> +static const struct file_operations mbox_test_ops = {
> +       .write  = mbox_test_write,
> +       .open   = simple_open,
> +       .llseek = generic_file_llseek,
> +};
> +
> +static int mbox_test_add_debugfs(struct platform_device *pdev,
> +                                struct mbox_test_device *tdev)
> +{
> +       if (!debugfs_initialized())
> +               return 0;
> +
> +       root_debugfs_dir = debugfs_create_dir("mailbox", NULL);
> +       if (!root_debugfs_dir) {
> +               dev_err(&pdev->dev, "Failed to create Mailbox debugfs\n");
> +               return -EINVAL;
> +       }
> +
> +       debugfs_create_file("send-message", 0200, root_debugfs_dir,
> +                           tdev, &mbox_test_ops);
> +
> +       return 0;
> +}
> +
> +static void mbox_test_receive_message(struct mbox_client *client, void *message)
> +{
> +       struct mbox_test_device *tdev = dev_get_drvdata(client->dev);
> +
> +       if (!tdev->mmio) {
> +               dev_info(tdev->dev, "Client: Recived something [read mmio]\n");
> +               return;
> +       }
> +
> +       print_hex_dump(KERN_ERR, "Client: from co-proc: ", DUMP_PREFIX_ADDRESS,
> +                      16, 1, tdev->mmio, MBOX_MAX_MSG_LEN, true);
> +}
> +
> +static void mbox_test_prepare_message(struct mbox_client *client, void *message)
> +{
> +       struct mbox_test_device *tdev = dev_get_drvdata(client->dev);
> +
> +       if (tdev->mmio)
> +               memcpy(tdev->mmio, message, MBOX_MAX_MSG_LEN);
>
This is unlikely to work. Those platforms that need to send a 2 part
message, they do :
(a) Signal/Command/Target code via some controller register (via
mbox_send_message).
(b) Setup the payload in Shared-Memory (via tx_prepare).

This test driver assumes both are the same. I think you have to
declare something like

struct mbox_test_message { /* same for TX and RX */
          unsigned sig_len;
          void *signal;               /* rx/tx via mailbox api */
          unsigned pl_len;
          void *payload;           /* rx/tx via shared-memory */
};

> +
> +static void mbox_test_message_sent(struct mbox_client *client,
> +                                  void *message, int r)
> +{
> +       if (r)
> +               dev_warn(client->dev,
> +                        "Client: Message could not be sent: %d\n", r);
> +       else
> +               dev_info(client->dev,
> +                        "Client: Message sent\n");
> +}
> +
> +static struct mbox_chan *
> +mbox_test_request_channel(struct platform_device *pdev, const char *name)
> +{
> +       struct mbox_client *client;
> +
> +       client = devm_kzalloc(&pdev->dev, sizeof(*client), GFP_KERNEL);
> +       if (!client)
> +               return ERR_PTR(-ENOMEM);
> +
> +       client->dev             = &pdev->dev;
> +       client->rx_callback     = mbox_test_receive_message;
> +       client->tx_prepare      = mbox_test_prepare_message;
> +       client->tx_done         = mbox_test_message_sent;
> +       client->tx_block        = true;
> +       client->knows_txdone    = false;
> +       client->tx_tout         = 500;
> +
> +       return mbox_request_channel_byname(client, name);
> +}
> +
> +static int mbox_test_probe(struct platform_device *pdev)
> +{
> +       struct mbox_test_device *tdev;
> +       struct resource *res;
> +       int ret;
> +
> +       tdev = devm_kzalloc(&pdev->dev, sizeof(*tdev), GFP_KERNEL);
> +       if (!tdev)
> +               return -ENOMEM;
> +
> +       /* It's okay for MMIO to be NULL */
> +       res = platform_get_resource(pdev, IORESOURCE_MEM, 0);
> +       tdev->mmio = devm_ioremap_resource(&pdev->dev, res);
> +       if (IS_ERR(tdev->mmio))
> +               tdev->mmio = NULL;
> +
> +       tdev->tx_channel = mbox_test_request_channel(pdev, "tx");
> +       if (IS_ERR(tdev->tx_channel))
> +               return PTR_ERR(tdev->tx_channel);
> +
> +       tdev->rx_channel = mbox_test_request_channel(pdev, "rx");
> +       if (IS_ERR(tdev->rx_channel))
> +               return PTR_ERR(tdev->rx_channel);
> +
Should it really fail on TX or RX only clients?
It takes write from userspace but shouldn't it also provide data
received to the userspace?

Cheers.
Jassi


From ludovic.desroches at atmel.com  Sun Aug  9 23:53:34 2015
From: ludovic.desroches at atmel.com (Ludovic Desroches)
Date: Mon, 10 Aug 2015 08:53:34 +0200
Subject: [RFC PATCH 0/3] New Atmel PIO4 pinctrl/gpio driver
In-Reply-To: <20150805073117.GP5161@pengutronix.de>
References: <1438355290-28255-1-git-send-email-ludovic.desroches@atmel.com>
 <20150805073117.GP5161@pengutronix.de>
Message-ID: <20150810065334.GC2635@odux.rfo.atmel.com>

Hi Sascha,

On Wed, Aug 05, 2015 at 09:31:17AM +0200, Sascha Hauer wrote:
> On Fri, Jul 31, 2015 at 05:08:07PM +0200, Ludovic Desroches wrote:
> > Hi,
> > 
> > Following our discussion, I send an RFC version of my driver. RFC because it is
> > not totally achieved, some cleanup and feature addition is needed.
> > 
> > At least, we could discuss about the 'core' part. I have used the pinmux
> > property as Mediatek driver. Patch 3 is the internal dt files we are using.
> 
> As you can imagine I am fine with the binding, so I can add my acked-by
> once you send a non-RFC version.
>

Great, I'm glad to hear that.
 
> The only thing I never understood is what's so special about GPIOs that
> they have to bypass the pinctrl framework and instead a gpio_request
> magically translates a gpio into a pin.

Not sure to really understand your concern here... Do you mean I could
get rid of gpio_request_enable()?

> Wouldn't it make sense to at
> least add the pins in their GPIO mode to
> arch/arm/boot/dts/sama5d2-pinfunc.h?

It is done, PIN_PA0 could be used for this purpose.

Regards

Ludovic


From jassisinghbrar at gmail.com  Sun Aug  9 23:58:17 2015
From: jassisinghbrar at gmail.com (Jassi Brar)
Date: Mon, 10 Aug 2015 12:28:17 +0530
Subject: [PATCH v2 2/6] mailbox: dt-bindings: Add shared [driver <=>
 device tree] defines
In-Reply-To: <1437990272-23111-3-git-send-email-lee.jones@linaro.org>
References: <1437990272-23111-1-git-send-email-lee.jones@linaro.org>
 <1437990272-23111-3-git-send-email-lee.jones@linaro.org>
Message-ID: <CABb+yY2asjH-c+VJXvG+RK0=2p=P4Y21pznNP0riaKMWLxYZog@mail.gmail.com>

On Mon, Jul 27, 2015 at 3:14 PM, Lee Jones <lee.jones at linaro.org> wrote:
> This header is currently only used for defines pertaining to data
> direction i.e. Rx, Tx or Loopback.
>
> Signed-off-by: Lee Jones <lee.jones at linaro.org>
> ---
>  include/dt-bindings/mailbox/mailbox.h | 14 ++++++++++++++
>  1 file changed, 14 insertions(+)
>  create mode 100644 include/dt-bindings/mailbox/mailbox.h
>
> diff --git a/include/dt-bindings/mailbox/mailbox.h b/include/dt-bindings/mailbox/mailbox.h
> new file mode 100644
> index 0000000..82e929a
> --- /dev/null
> +++ b/include/dt-bindings/mailbox/mailbox.h
> @@ -0,0 +1,14 @@
> +/*
> + * 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.
> + */
> +
> +#ifndef __MAILBOX_CONTROLLER_DT_BINDINGS_H
> +#define __MAILBOX_CONTROLLER_DT_BINDINGS_H
> +
> +#define MBOX_TX                0x1
> +#define MBOX_RX                0x2
> +#define MBOX_LOOPBACK  (MBOX_RX | MBOX_TX)
> +
Not sure I understand 'loopback'.  Does it mean h/w has some
'loopback' mode for testing purposes? Or it simply means the
controller can send as well as receive messages?

Thanks.


From jassisinghbrar at gmail.com  Mon Aug 10 00:02:05 2015
From: jassisinghbrar at gmail.com (Jassi Brar)
Date: Mon, 10 Aug 2015 12:32:05 +0530
Subject: [RFC PATCH 0/3] mailbox: hisilicon: add mailbox driver
In-Reply-To: <20150805231743.GB6880@leoy-linaro>
References: <1438564390-28111-1-git-send-email-leo.yan@linaro.org>
 <CABb+yY0-RQ80q92EBsuBoYpjxW5zR=nXr+j3zCXw3wKkCf33OQ@mail.gmail.com>
 <20150805231743.GB6880@leoy-linaro>
Message-ID: <CABb+yY1HTGNi4gZABNhXjpA57DPZx-tv=6+m4JLyx4wPHfovyA@mail.gmail.com>

On Thu, Aug 6, 2015 at 4:47 AM, Leo Yan <leo.yan at linaro.org> wrote:
> Hi Jassi,
>
> Thanks for review.
>
> On Wed, Aug 05, 2015 at 04:22:01PM +0530, Jassi Brar wrote:
>> On Mon, Aug 3, 2015 at 6:43 AM, Leo Yan <leo.yan at linaro.org> wrote:
>
> [...]
>
>> > For easily extending for Hisilicon series SoCs (SoCs may have difference
>> > for register's definition with each other), so firstly implement common
>> > mailbox driver; this common mailbox driver provides three mainly
>> > functionality:
>> >
>> >  - help register channels into framework;
>> >  - hook low level callback functions for register's operations;
>> >  - Enhance rx channel's message queue, which is based on the code in
>> >    drivers/mailbox/omap-mailbox.c.
>> >
>> Not cool.
>>  Please don't reinvent the wheel by having platform specific
>> implementation of the mailbox api. Which vendor doesn't plan to roll
>> out new SoCs, and hence variations of mailbox controllers?  The OMAP
>> stack predates the common api, and was actually supposed to be
>> converted over eventually. Please implement just the
>> drivers/mailbox/hi6220-mailbox.c (preferably by the name of the
>> mailbox controller, if any)
>
> Understood. Here i have one question, the rx channel's message queue is
> looks like a common mechanism and can be added into framework file
> mailbox.c, then Soc driver file can _ONLY_ focus on register level's
> operations. If so, the common driver in this patch also is unnecessary.
>
Yes, that's what I say, no 'common' driver for a platform.

> Do you suggest to use upper method to rework patches? Or just think
> it's okay to implement rx channel's message queue in hi6220-mailbox.c?
>
The code in drivers/mailbox/ should only manage the controller
(registers and interrupts). Everything else (queues, shmem etc) should
be in platform specific client driver(s).


From dhdang at apm.com  Mon Aug 10 00:37:21 2015
From: dhdang at apm.com (Duc Dang)
Date: Mon, 10 Aug 2015 00:37:21 -0700
Subject: [PATCH v6 1/2] usb: make xhci platform driver use 64 bit or 32 bit DMA
In-Reply-To: <20150808092252.GJ7557@n2100.arm.linux.org.uk>
References: <20150808092252.GJ7557@n2100.arm.linux.org.uk>
Message-ID: <eb7cf78f9c43ee61a5ad1f51a1bd53bd7524e05f.1439190829.git.dhdang@apm.com>

The xhci platform driver needs to work on systems that
either only support 64-bit DMA or only support 32-bit DMA.
Attempt to set a coherent dma mask for 64-bit DMA, and
attempt again with 32-bit DMA if that fails.

[dhdang: regenerate the patch over 4.2-rc5 and address new comments]
Signed-off-by: Mark Langsdorf <mlangsdo at redhat.com>
Tested-by: Mark Salter <msalter at redhat.com>
Signed-off-by: Duc Dang <dhdang at apm.com>

---
Changes from v5:
	-Change comment
	-Assign dma_mask to coherent_dma_mask if dma_mask is NULL
	to make sure dma_set_mask_and_coherent does not	fail prematurely.

Changes from v4:
        -None

Changes from v3:
        -Re-generate the patch over 4.2-rc5
        -No code change.

Changes from v2:
        -None

Changes from v1:
        -Consolidated to use dma_set_mask_and_coherent
        -Got rid of the check against sizeof(dma_addr_t)

 drivers/usb/host/xhci-plat.c | 16 ++++++++++------
 1 file changed, 10 insertions(+), 6 deletions(-)

diff --git a/drivers/usb/host/xhci-plat.c b/drivers/usb/host/xhci-plat.c
index 890ad9d..5d1b84b 100644
--- a/drivers/usb/host/xhci-plat.c
+++ b/drivers/usb/host/xhci-plat.c
@@ -93,14 +93,18 @@ static int xhci_plat_probe(struct platform_device *pdev)
 	if (irq < 0)
 		return -ENODEV;
 
-	/* Initialize dma_mask and coherent_dma_mask to 32-bits */
-	ret = dma_set_coherent_mask(&pdev->dev, DMA_BIT_MASK(32));
-	if (ret)
-		return ret;
+	/*
+	 * Try setting dma_mask and coherent_dma_mask to 64 bits,
+	 * then try 32 bits
+	 */
 	if (!pdev->dev.dma_mask)
 		pdev->dev.dma_mask = &pdev->dev.coherent_dma_mask;
-	else
-		dma_set_mask(&pdev->dev, DMA_BIT_MASK(32));
+	ret = dma_set_mask_and_coherent(&pdev->dev, DMA_BIT_MASK(64));
+	if (ret) {
+		ret = dma_set_mask_and_coherent(&pdev->dev, DMA_BIT_MASK(32));
+		if (ret)
+			return ret;
+	}
 
 	hcd = usb_create_hcd(driver, &pdev->dev, dev_name(&pdev->dev));
 	if (!hcd)
-- 
1.9.1



From dhdang at apm.com  Mon Aug 10 00:37:22 2015
From: dhdang at apm.com (Duc Dang)
Date: Mon, 10 Aug 2015 00:37:22 -0700
Subject: [PATCH v6 2/2] usb: Add support for ACPI identification to
 xhci-platform
In-Reply-To: <eb7cf78f9c43ee61a5ad1f51a1bd53bd7524e05f.1439190829.git.dhdang@apm.com>
References: <eb7cf78f9c43ee61a5ad1f51a1bd53bd7524e05f.1439190829.git.dhdang@apm.com>
Message-ID: <466084f08a22e7af257f5ed3c7757938c76bf5cd.1439190829.git.dhdang@apm.com>

Provide the methods to let ACPI identify the need to use
xhci-platform. Change the Kconfig files so the
xhci-plat.o file is selectable during kernel config.

This has been tested on an ARM64 machine with platform XHCI, an
x86_64 machine with XHCI, and an x86_64 machine without XHCI.
There were no regressions or error messages on the machines
without platform XHCI.

[dhdang: regenerate the patch over 4.2-rc5 and address new comments]
Signed-off-by: Mark Langsdorf <mlangsdo at redhat.com>
Signed-off-by: Duc Dang <dhdang at apm.com>

---
Change from v5:
	Change comment to "XHCI-compliant USB Controller" as
	"PNP0D10" ID is not X-Gene specific

Changes from v4:
        Remove #ifdef CONFIG_ACPI

Changes from v3:
        Regenerate the patch over 4.2-rc5
        No code change

Changes from v2
        Replaced tristate with a boolean as the driver doesn't
                compile as a module
        Correct --help-- to ---help---

Changes from v1
        Renamed from "add support for APM X-Gene to xhci-platform"
        Removed changes to arm64/Kconfig
        Made CONFIG_USB_XHCI_PLATFORM a user selectable config option

 drivers/usb/host/Kconfig     | 7 ++++++-
 drivers/usb/host/xhci-plat.c | 9 +++++++++
 2 files changed, 15 insertions(+), 1 deletion(-)

diff --git a/drivers/usb/host/Kconfig b/drivers/usb/host/Kconfig
index 8afc3c1..96231ee 100644
--- a/drivers/usb/host/Kconfig
+++ b/drivers/usb/host/Kconfig
@@ -32,7 +32,12 @@ config USB_XHCI_PCI
        default y
 
 config USB_XHCI_PLATFORM
-	tristate
+	tristate "xHCI platform driver support"
+	---help---
+	  Say 'Y' to enable the support for the xHCI host controller
+	  as a platform device. Many ARM SoCs provide USB this way.
+
+	  If unsure, say 'Y'.
 
 config USB_XHCI_MVEBU
 	tristate "xHCI support for Marvell Armada 375/38x"
diff --git a/drivers/usb/host/xhci-plat.c b/drivers/usb/host/xhci-plat.c
index 5d1b84b..7ec2d31 100644
--- a/drivers/usb/host/xhci-plat.c
+++ b/drivers/usb/host/xhci-plat.c
@@ -19,6 +19,7 @@
 #include <linux/usb/phy.h>
 #include <linux/slab.h>
 #include <linux/usb/xhci_pdriver.h>
+#include <linux/acpi.h>
 
 #include "xhci.h"
 #include "xhci-mvebu.h"
@@ -266,6 +267,13 @@ static const struct of_device_id usb_xhci_of_match[] = {
 MODULE_DEVICE_TABLE(of, usb_xhci_of_match);
 #endif
 
+static const struct acpi_device_id usb_xhci_acpi_match[] = {
+	/* XHCI-compliant USB Controller */
+	{ "PNP0D10", },
+	{ }
+};
+MODULE_DEVICE_TABLE(acpi, usb_xhci_acpi_match);
+
 static struct platform_driver usb_xhci_driver = {
 	.probe	= xhci_plat_probe,
 	.remove	= xhci_plat_remove,
@@ -273,6 +281,7 @@ static struct platform_driver usb_xhci_driver = {
 		.name = "xhci-hcd",
 		.pm = DEV_PM_OPS,
 		.of_match_table = of_match_ptr(usb_xhci_of_match),
+		.acpi_match_table = ACPI_PTR(usb_xhci_acpi_match),
 	},
 };
 MODULE_ALIAS("platform:xhci-hcd");
-- 
1.9.1



From maxime.coquelin at st.com  Mon Aug 10 00:44:44 2015
From: maxime.coquelin at st.com (Maxime Coquelin)
Date: Mon, 10 Aug 2015 09:44:44 +0200
Subject: [PATCH v2 4/9] usb: host: ehci-st: Simplify return statement
In-Reply-To: <29a173be5ace786d064ae14c02324fee42fee06c.1438695318.git.skarajga@visteon.com>
References: <cover.1438695318.git.skarajga@visteon.com>
 <29a173be5ace786d064ae14c02324fee42fee06c.1438695318.git.skarajga@visteon.com>
Message-ID: <55C8566C.9080401@st.com>

Hi Saurabh,

On 08/04/2015 04:02 PM, Karajgaonkar, Saurabh (S.) wrote:
> From: Saurabh Karajgaonkar <skarajga at visteon.com>
>
> Replace redundant variable use in return statement.
>
> Signed-off-by: Saurabh Karajgaonkar <skarajga at visteon.com>
> ---
>   drivers/usb/host/ehci-st.c | 7 +------
>   1 file changed, 1 insertion(+), 6 deletions(-)
>
>

Acked-by: Maxime Coquelin <maxime.coquelin at st.com>

Thanks!
Maxime


From dtor at chromium.org  Mon Aug 10 00:59:04 2015
From: dtor at chromium.org (Dmitry Torokhov)
Date: Mon, 10 Aug 2015 00:59:04 -0700
Subject: [PATCH] thermal: rockchip: fix handling of invalid readings
In-Reply-To: <55C84521.5040007@rock-chips.com>
References: <20150807205923.GA33949@dtor-ws> <55C84521.5040007@rock-chips.com>
Message-ID: <CAE_wzQ_xhh17tsVj28W5Z=mgomnz1nOMPMN15Sozb8KcMjo=wA@mail.gmail.com>

Hi Caesar,

On Sun, Aug 9, 2015 at 11:30 PM, Caesar Wang <wxt at rock-chips.com> wrote:
> Dear Dmitry,
>
> Thanks your patch.
>
> The code looks like fine,but I don't think the TS-ADC will work on rk3288
> SoC.

What do you mean? It seems to work when I ran it...

>
>
> ? 2015?08?08? 04:59, Dmitry Torokhov ??:
>>
>> We attempted to signal invalid code by returning -EAGAIN from
>> rk_tsadcv2_code_to_temp(), unfortunately the return value was stuffed
>> directly into the temperature pointer, potentially confusing upper
>> layers with temperature of -EINVAL.
>>
>> Let's split temperature from error/success indicator to avoid such
>> confusion.
>>
>> Also change the way we scan the temperature table to start with the 2nd
>> element so that we do not need to worry that we may reference out of
>> bounds element while doing binary search and keep checking that we end
>> up with 'mid' equal to 0 (since we are looking for the temperature that
>> would fall into interval between the 'mid' and 'mid - 1') .
>>
>> Signed-off-by: Dmitry Torokhov <dtor at chromium.org>
>> ---
>>   drivers/thermal/rockchip_thermal.c | 28 +++++++++++++---------------
>>   1 file changed, 13 insertions(+), 15 deletions(-)
>>
>> diff --git a/drivers/thermal/rockchip_thermal.c
>> b/drivers/thermal/rockchip_thermal.c
>> index c89ffb2..93ee307 100644
>> --- a/drivers/thermal/rockchip_thermal.c
>> +++ b/drivers/thermal/rockchip_thermal.c
>> @@ -124,7 +124,7 @@ struct rockchip_thermal_data {
>>   #define TSADCV2_AUTO_PERIOD_HT_TIME           50  /* msec */
>>     struct tsadc_table {
>> -       unsigned long code;
>> +       u32 code;
>>         long temp;
>>   };
>>   @@ -164,7 +164,6 @@ static const struct tsadc_table v2_code_table[] = {
>>         {3452, 115000},
>>         {3437, 120000},
>>         {3421, 125000},
>> -       {0, 125000},
>>   };
>>     static u32 rk_tsadcv2_temp_to_code(long temp)
>> @@ -191,19 +190,21 @@ static u32 rk_tsadcv2_temp_to_code(long temp)
>>         return 0;
>>   }
>>   -static int rk_tsadcv2_code_to_temp(u32 code)
>> +static int rk_tsadcv2_code_to_temp(u32 code, int *temp)
>>   {
>> -       unsigned int low = 0;
>> +       unsigned int low = 1;
>>         unsigned int high = ARRAY_SIZE(v2_code_table) - 1;
>>         unsigned int mid = (low + high) / 2;
>>         unsigned int num;
>>         unsigned long denom;
>>   -     /* Invalid code, return -EAGAIN */
>> -       if (code > TSADCV2_DATA_MASK)
>> -               return -EAGAIN;
>> +       BUILD_BUG_ON(ARRAY_SIZE(v2_code_table) < 2);
>>   -     while (low <= high && mid) {
>> +       code &= TSADCV2_DATA_MASK;
>> +       if (code < v2_code_table[high].code)
>> +               return -EAGAIN;         /* Incorrect reading */
>> +
>> +       while (low <= high) {
>>                 if (code >= v2_code_table[mid].code &&
>>                     code < v2_code_table[mid - 1].code)
>>                         break;
>> @@ -223,7 +224,9 @@ static int rk_tsadcv2_code_to_temp(u32 code)
>>         num = v2_code_table[mid].temp - v2_code_table[mid - 1].temp;
>>         num *= v2_code_table[mid - 1].code - code;
>>         denom = v2_code_table[mid - 1].code - v2_code_table[mid].code;
>> -       return v2_code_table[mid - 1].temp + (num / denom);
>> +       *temp = v2_code_table[mid - 1].temp + (num / denom);
>> +
>> +       return 0;
>>   }
>>     /**
>> @@ -281,14 +284,9 @@ static int rk_tsadcv2_get_temp(int chn, void __iomem
>> *regs, int *temp)
>>   {
>>         u32 val;
>>   -     /* the A/D value of the channel last conversion need some time */
>>         val = readl_relaxed(regs + TSADCV2_DATA(chn));
>> -       if (val == 0)
>> -               return -EAGAIN;
>> -
>
>
> if we reserve the above code, that will get the ADC value.

But if we pass  0 into rk_tsadcv2_code_to_temp() it will trigger:

>> +       if (code < v2_code_table[high].code)
>> +               return -EAGAIN;         /* Incorrect reading */

and still return -EAGAIN, as it was. There is no behavior change as
far as I can see.

>
>
>> -       *temp = rk_tsadcv2_code_to_temp(val);
>>   -     return 0;
>> +       return rk_tsadcv2_code_to_temp(val, temp);
>>   }
>>     static void rk_tsadcv2_tshut_temp(int chn, void __iomem *regs, long
>> temp)
>
>

Thanks,
Dmitry


From jassisinghbrar at gmail.com  Mon Aug 10 01:05:29 2015
From: jassisinghbrar at gmail.com (Jassi Brar)
Date: Mon, 10 Aug 2015 13:35:29 +0530
Subject: [PATCHv7 2/2] mailbox: Adding driver for Xilinx LogiCORE IP
 mailbox.
In-Reply-To: <1436922022-17564-3-git-send-email-moritz.fischer@ettus.com>
References: <1436922022-17564-1-git-send-email-moritz.fischer@ettus.com>
 <1436922022-17564-3-git-send-email-moritz.fischer@ettus.com>
Message-ID: <CABb+yY3tpepdO=s9nb9kAE241sYVTTXB-ci_4ihuthHTekedNg@mail.gmail.com>

On Wed, Jul 15, 2015 at 6:30 AM, Moritz Fischer
<moritz.fischer at ettus.com> wrote:

> +
> +static void xilinx_mbox_rx_data(struct mbox_chan *chan)
> +{
> +       struct xilinx_mbox *mbox = mbox_chan_to_xilinx_mbox(chan);
> +       u32 data;
> +
> +       if (xilinx_mbox_pending(mbox)) {
> +               data = readl_relaxed(mbox->mbox_base + MAILBOX_REG_RDDATA);
> +               mbox_chan_received_data(chan, (void *)data);
>
If RDDATA is a FIFO, then above seems wrong - you are assuming
messages are always going to be exactly 32-bits for every protocol.
Ideally you should empty the fifo fully, at least when RX has an
interrupt.

> +
> +static int xilinx_mbox_irq_send_data(struct mbox_chan *chan, void *data)
> +{
> +       struct xilinx_mbox *mbox = mbox_chan_to_xilinx_mbox(chan);
> +       u32 *udata = data;
> +
> +       if (xilinx_mbox_full(mbox))
> +               return -EBUSY;
>
This check is redundant. last_tx_done already makes sure this is always true.

> +       /* enable interrupt before send */
> +       xilinx_mbox_tx_intmask(mbox, true);
> +
> +       writel_relaxed(*udata, mbox->mbox_base + MAILBOX_REG_WRDATA);
> +
>From status EMPTY and FULL, it seems WRDATA is a FIFO. So here also
you should expect messages to be <= fifo depth. And not assume exactly
32bit messages always.

> +
> +static bool xilinx_mbox_last_tx_done(struct mbox_chan *chan)
> +{
> +       struct xilinx_mbox *mbox = mbox_chan_to_xilinx_mbox(chan);
> +
> +       /* return false if mailbox is full */
> +       return !xilinx_mbox_full(mbox);
>
Instead of FULL, I think it should check for stricter EMPTY status ...
mbox api submits only 1 message at a time.

> +
> +static bool xilinx_mbox_peek_data(struct mbox_chan *chan)
> +{
> +       struct xilinx_mbox *mbox = mbox_chan_to_xilinx_mbox(chan);
> +
> +       return xilinx_mbox_pending(mbox);
> +}
> +
> +static void xilinx_mbox_irq_shutdown(struct mbox_chan *chan)
> +{
> +       struct xilinx_mbox *mbox = mbox_chan_to_xilinx_mbox(chan);
> +
> +       /* mask all interrupts */
> +       writel_relaxed(0, mbox->mbox_base + MAILBOX_REG_IE);
> +
> +       clk_disable_unprepare(mbox->clk);
> +
> +       free_irq(mbox->irq, chan);
> +}
> +
> +static void xilinx_mbox_poll_shutdown(struct mbox_chan *chan)
> +{
> +       struct xilinx_mbox *mbox = mbox_chan_to_xilinx_mbox(chan);
> +
> +       del_timer_sync(&mbox->rxpoll_timer);
> +
> +       clk_disable_unprepare(mbox->clk);
> +}
> +
> +static const struct mbox_chan_ops xilinx_mbox_irq_ops = {
> +       .send_data = xilinx_mbox_irq_send_data,
> +       .startup = xilinx_mbox_irq_startup,
> +       .shutdown = xilinx_mbox_irq_shutdown,
> +       .last_tx_done = xilinx_mbox_last_tx_done,
> +       .peek_data = xilinx_mbox_peek_data,
> +};
> +
> +static const struct mbox_chan_ops xilinx_mbox_poll_ops = {
> +       .send_data = xilinx_mbox_poll_send_data,
> +       .startup = xilinx_mbox_poll_startup,
> +       .shutdown = xilinx_mbox_poll_shutdown,
> +       .last_tx_done = xilinx_mbox_last_tx_done,
> +       .peek_data = xilinx_mbox_peek_data,
> +};
> +
> +static int xilinx_mbox_probe(struct platform_device *pdev)
> +{
> +       struct xilinx_mbox *mbox;
> +       struct resource *regs;
> +       int ret;
> +
> +       mbox = devm_kzalloc(&pdev->dev, sizeof(*mbox), GFP_KERNEL);
> +       if (!mbox)
> +               return -ENOMEM;
> +
> +       /* get clk and enable */
> +       mbox->clk = devm_clk_get(&pdev->dev, "mbox");
> +       if (IS_ERR(mbox->clk)) {
> +               dev_err(&pdev->dev, "Couldn't get clk.\n");
> +               return PTR_ERR(mbox->clk);
> +       }
> +
> +       regs = platform_get_resource(pdev, IORESOURCE_MEM, 0);
> +
> +       mbox->mbox_base = devm_ioremap_resource(&pdev->dev, regs);
> +       if (IS_ERR(mbox->mbox_base))
> +               return PTR_ERR(mbox->mbox_base);
> +
> +       mbox->irq = platform_get_irq(pdev, 0);
> +       /* if irq is present, we can use it, otherwise, poll */
> +       if (mbox->irq > 0) {
> +               mbox->controller.txdone_irq = true;
> +               mbox->controller.ops = &xilinx_mbox_irq_ops;
> +       } else {
> +               dev_info(&pdev->dev, "IRQ not found, fallback to polling.\n");
> +               mbox->controller.txdone_poll = true;
> +               mbox->controller.txpoll_period = MBOX_POLLING_MS;
> +               mbox->controller.ops = &xilinx_mbox_poll_ops;
> +
> +               setup_timer(&mbox->rxpoll_timer, xilinx_mbox_poll_rx,
> +                           (unsigned long)&mbox->chan);
>
I believe there is indeed some platform that doesn't have RX-Interrupt?
 If no, please remove this.
 If yes, you may want to get some hint from platform about the size of
messages and do mbox_chan_received_data() only upon reading those many
bytes.

Cheers.


From haibo.chen at freescale.com  Mon Aug 10 01:18:02 2015
From: haibo.chen at freescale.com (Haibo Chen)
Date: Mon, 10 Aug 2015 16:18:02 +0800
Subject: [PATCH v5 0/6] mmc: imx: a few fixes and new feature
Message-ID: <1439194688-18335-1-git-send-email-haibo.chen@freescale.com>

Changes for v5:
-move the clear exist timing setting to a common place rather than only in HS200 mode.
-put the patch 6 ahead of patch 5.

Haibo Chen (6):
  mmc: sdhci-esdhc-imx: add imx7d support and support HS400
  mmc: sdhci-esdhc-imx: add tuning-step seting support
  mmc: sdhci-esdhc-imx: add compatible string in bingding doc
  ARM: dts: imx7d-sdb: add eMMC5.0 support
  mmc: sdhci-esdhc-imx: set back the burst_length_enable bit to 1
  mmc: sdhci-esdhc-imx: change default watermark level and burst length

 .../devicetree/bindings/mmc/fsl-imx-esdhc.txt      |   6 ++
 arch/arm/boot/dts/imx7d-sdb.dts                    |  13 +++
 drivers/mmc/host/sdhci-esdhc-imx.c                 | 116 ++++++++++++++++++++-
 include/linux/platform_data/mmc-esdhc-imx.h        |   1 +
 4 files changed, 132 insertions(+), 4 deletions(-)

-- 
1.9.1



From haibo.chen at freescale.com  Mon Aug 10 01:18:03 2015
From: haibo.chen at freescale.com (Haibo Chen)
Date: Mon, 10 Aug 2015 16:18:03 +0800
Subject: [PATCH v5 1/6] mmc: sdhci-esdhc-imx: add imx7d support and support
 HS400
In-Reply-To: <1439194688-18335-1-git-send-email-haibo.chen@freescale.com>
References: <1439194688-18335-1-git-send-email-haibo.chen@freescale.com>
Message-ID: <1439194688-18335-2-git-send-email-haibo.chen@freescale.com>

The imx7d usdhc is derived from imx6sx, the difference is that
imx7d support HS400.

So introduce a new compatible string for imx7d and add HS400
support for imx7d usdhc.

Signed-off-by: Haibo Chen <haibo.chen at freescale.com>
---
 drivers/mmc/host/sdhci-esdhc-imx.c | 88 ++++++++++++++++++++++++++++++++++++--
 1 file changed, 85 insertions(+), 3 deletions(-)

diff --git a/drivers/mmc/host/sdhci-esdhc-imx.c b/drivers/mmc/host/sdhci-esdhc-imx.c
index c6b9f64..2a816ad 100644
--- a/drivers/mmc/host/sdhci-esdhc-imx.c
+++ b/drivers/mmc/host/sdhci-esdhc-imx.c
@@ -44,6 +44,7 @@
 #define  ESDHC_MIX_CTRL_EXE_TUNE	(1 << 22)
 #define  ESDHC_MIX_CTRL_SMPCLK_SEL	(1 << 23)
 #define  ESDHC_MIX_CTRL_FBCLK_SEL	(1 << 25)
+#define  ESDHC_MIX_CTRL_HS400_EN	(1 << 26)
 /* Bits 3 and 6 are not SDHCI standard definitions */
 #define  ESDHC_MIX_CTRL_SDHCI_MASK	0xb7
 /* Tuning bits */
@@ -60,6 +61,16 @@
 #define  ESDHC_TUNE_CTRL_MIN		0
 #define  ESDHC_TUNE_CTRL_MAX		((1 << 7) - 1)
 
+/* strobe dll register */
+#define ESDHC_STROBE_DLL_CTRL		0x70
+#define ESDHC_STROBE_DLL_CTRL_ENABLE	(1 << 0)
+#define ESDHC_STROBE_DLL_CTRL_RESET	(1 << 1)
+#define ESDHC_STROBE_DLL_CTRL_SLV_DLY_TARGET_SHIFT	3
+
+#define ESDHC_STROBE_DLL_STATUS		0x74
+#define ESDHC_STROBE_DLL_STS_REF_LOCK	(1 << 1)
+#define ESDHC_STROBE_DLL_STS_SLV_LOCK	0x1
+
 #define ESDHC_TUNING_CTRL		0xcc
 #define ESDHC_STD_TUNING_EN		(1 << 24)
 /* NOTE: the minimum valid tuning start tap for mx6sl is 1 */
@@ -120,6 +131,11 @@
 #define ESDHC_FLAG_ERR004536		BIT(7)
 /* The IP supports HS200 mode */
 #define ESDHC_FLAG_HS200		BIT(8)
+/* The IP supports HS400 mode */
+#define ESDHC_FLAG_HS400		BIT(9)
+
+/* A higher clock ferquency than this rate requires strobell dll control */
+#define ESDHC_STROBE_DLL_CLK_FREQ	100000000
 
 struct esdhc_soc_data {
 	u32 flags;
@@ -156,6 +172,12 @@ static struct esdhc_soc_data usdhc_imx6sx_data = {
 			| ESDHC_FLAG_HAVE_CAP1 | ESDHC_FLAG_HS200,
 };
 
+static struct esdhc_soc_data usdhc_imx7d_data = {
+	.flags = ESDHC_FLAG_USDHC | ESDHC_FLAG_STD_TUNING
+			| ESDHC_FLAG_HAVE_CAP1 | ESDHC_FLAG_HS200
+			| ESDHC_FLAG_HS400,
+};
+
 struct pltfm_imx_data {
 	u32 scratchpad;
 	struct pinctrl *pinctrl;
@@ -199,6 +221,7 @@ static const struct of_device_id imx_esdhc_dt_ids[] = {
 	{ .compatible = "fsl,imx6sx-usdhc", .data = &usdhc_imx6sx_data, },
 	{ .compatible = "fsl,imx6sl-usdhc", .data = &usdhc_imx6sl_data, },
 	{ .compatible = "fsl,imx6q-usdhc", .data = &usdhc_imx6q_data, },
+	{ .compatible = "fsl,imx7d-usdhc", .data = &usdhc_imx7d_data, },
 	{ /* sentinel */ }
 };
 MODULE_DEVICE_TABLE(of, imx_esdhc_dt_ids);
@@ -274,6 +297,9 @@ static u32 esdhc_readl_le(struct sdhci_host *host, int reg)
 				val = SDHCI_SUPPORT_DDR50 | SDHCI_SUPPORT_SDR104
 					| SDHCI_SUPPORT_SDR50
 					| SDHCI_USE_SDR50_TUNING;
+
+			if (imx_data->socdata->flags & ESDHC_FLAG_HS400)
+				val |= SDHCI_SUPPORT_HS400;
 		}
 	}
 
@@ -774,6 +800,7 @@ static int esdhc_change_pinstate(struct sdhci_host *host,
 		break;
 	case MMC_TIMING_UHS_SDR104:
 	case MMC_TIMING_MMC_HS200:
+	case MMC_TIMING_MMC_HS400:
 		pinctrl = imx_data->pins_200mhz;
 		break;
 	default:
@@ -784,12 +811,57 @@ static int esdhc_change_pinstate(struct sdhci_host *host,
 	return pinctrl_select_state(imx_data->pinctrl, pinctrl);
 }
 
+/*
+ * For HS400 eMMC, there is a data_strobe line, this signal is generated
+ * by the device and used for data output and CRC status response output
+ * in HS400 mode. The frequency of this signal follows the frequency of
+ * CLK generated by host. Host receive the data which is aligned to the
+ * edge of data_strobe line. Due to the time delay between CLK line and
+ * data_strobe line, if the delay time is larger than one clock cycle,
+ * then CLK and data_strobe line will misaligned, read error shows up.
+ * So when the CLK is higher than 100MHz, each clock cycle is short enough,
+ * host should config the delay target.
+ */
+static void esdhc_set_strobe_dll(struct sdhci_host *host)
+{
+	u32 v;
+
+	if (host->mmc->actual_clock > ESDHC_STROBE_DLL_CLK_FREQ) {
+		/* force a reset on strobe dll */
+		writel(ESDHC_STROBE_DLL_CTRL_RESET,
+			host->ioaddr + ESDHC_STROBE_DLL_CTRL);
+		/*
+		 * enable strobe dll ctrl and adjust the delay target
+		 * for the uSDHC loopback read clock
+		 */
+		v = ESDHC_STROBE_DLL_CTRL_ENABLE |
+			(7 << ESDHC_STROBE_DLL_CTRL_SLV_DLY_TARGET_SHIFT);
+		writel(v, host->ioaddr + ESDHC_STROBE_DLL_CTRL);
+		/* wait 1us to make sure strobe dll status register stable */
+		udelay(1);
+		v = readl(host->ioaddr + ESDHC_STROBE_DLL_STATUS);
+		if (!(v & ESDHC_STROBE_DLL_STS_REF_LOCK))
+			dev_warn(mmc_dev(host->mmc),
+				"warning! HS400 strobe DLL status REF not lock!\n");
+		if (!(v & ESDHC_STROBE_DLL_STS_SLV_LOCK))
+			dev_warn(mmc_dev(host->mmc),
+				"warning! HS400 strobe DLL status SLV not lock!\n");
+	}
+}
+
 static void esdhc_set_uhs_signaling(struct sdhci_host *host, unsigned timing)
 {
+	u32 m;
 	struct sdhci_pltfm_host *pltfm_host = sdhci_priv(host);
 	struct pltfm_imx_data *imx_data = pltfm_host->priv;
 	struct esdhc_platform_data *boarddata = &imx_data->boarddata;
 
+	/* disable ddr mode and disable HS400 mode */
+	m = readl(host->ioaddr + ESDHC_MIX_CTRL);
+	m &= ~(ESDHC_MIX_CTRL_DDREN | ESDHC_MIX_CTRL_HS400_EN);
+	writel(m, host->ioaddr + ESDHC_MIX_CTRL);
+	imx_data->is_ddr = 0;
+
 	switch (timing) {
 	case MMC_TIMING_UHS_SDR12:
 	case MMC_TIMING_UHS_SDR25:
@@ -799,9 +871,9 @@ static void esdhc_set_uhs_signaling(struct sdhci_host *host, unsigned timing)
 		break;
 	case MMC_TIMING_UHS_DDR50:
 	case MMC_TIMING_MMC_DDR52:
-		writel(readl(host->ioaddr + ESDHC_MIX_CTRL) |
-				ESDHC_MIX_CTRL_DDREN,
-				host->ioaddr + ESDHC_MIX_CTRL);
+		m = readl(host->ioaddr + ESDHC_MIX_CTRL);
+		m |= ESDHC_MIX_CTRL_DDREN;
+		writel(m, host->ioaddr + ESDHC_MIX_CTRL);
 		imx_data->is_ddr = 1;
 		if (boarddata->delay_line) {
 			u32 v;
@@ -813,6 +885,13 @@ static void esdhc_set_uhs_signaling(struct sdhci_host *host, unsigned timing)
 			writel(v, host->ioaddr + ESDHC_DLL_CTRL);
 		}
 		break;
+	case MMC_TIMING_MMC_HS400:
+		m = readl(host->ioaddr + ESDHC_MIX_CTRL);
+		m |= ESDHC_MIX_CTRL_DDREN | ESDHC_MIX_CTRL_HS400_EN;
+		writel(m, host->ioaddr + ESDHC_MIX_CTRL);
+		imx_data->is_ddr = 1;
+		esdhc_set_strobe_dll(host);
+		break;
 	}
 
 	esdhc_change_pinstate(host, timing);
@@ -1100,6 +1179,9 @@ static int sdhci_esdhc_imx_probe(struct platform_device *pdev)
 	if (imx_data->socdata->flags & ESDHC_FLAG_ERR004536)
 		host->quirks |= SDHCI_QUIRK_BROKEN_ADMA;
 
+	if (imx_data->socdata->flags & ESDHC_FLAG_HS400)
+		host->quirks2 |= SDHCI_QUIRK2_CAPS_BIT63_FOR_HS400;
+
 	if (of_id)
 		err = sdhci_esdhc_imx_probe_dt(pdev, host, imx_data);
 	else
-- 
1.9.1



From haibo.chen at freescale.com  Mon Aug 10 01:18:04 2015
From: haibo.chen at freescale.com (Haibo Chen)
Date: Mon, 10 Aug 2015 16:18:04 +0800
Subject: [PATCH v5 2/6] mmc: sdhci-esdhc-imx: add tuning-step seting support
In-Reply-To: <1439194688-18335-1-git-send-email-haibo.chen@freescale.com>
References: <1439194688-18335-1-git-send-email-haibo.chen@freescale.com>
Message-ID: <1439194688-18335-3-git-send-email-haibo.chen@freescale.com>

tuning-step is the delay cell steps in tuning procedure. The default value
of tuning-step is 1. Some boards or cards need another value to pass the
tuning procedure. For example, imx7d-sdb board need the tuning-step value
as 2, otherwise it can't pass the tuning procedure.

So this patch add the tuning-step setting in driver, so that user can set
the tuning-step value in dts.

Signed-off-by: Haibo Chen <haibo.chen at freescale.com>
---
 drivers/mmc/host/sdhci-esdhc-imx.c          | 9 +++++++++
 include/linux/platform_data/mmc-esdhc-imx.h | 1 +
 2 files changed, 10 insertions(+)

diff --git a/drivers/mmc/host/sdhci-esdhc-imx.c b/drivers/mmc/host/sdhci-esdhc-imx.c
index 2a816ad..03c9f33 100644
--- a/drivers/mmc/host/sdhci-esdhc-imx.c
+++ b/drivers/mmc/host/sdhci-esdhc-imx.c
@@ -75,6 +75,7 @@
 #define ESDHC_STD_TUNING_EN		(1 << 24)
 /* NOTE: the minimum valid tuning start tap for mx6sl is 1 */
 #define ESDHC_TUNING_START_TAP		0x1
+#define ESDHC_TUNING_STEP_SHIFT		16
 
 /* pinctrl state */
 #define ESDHC_PINCTRL_STATE_100MHZ	"state_100mhz"
@@ -474,6 +475,7 @@ static void esdhc_writew_le(struct sdhci_host *host, u16 val, int reg)
 		} else if (imx_data->socdata->flags & ESDHC_FLAG_STD_TUNING) {
 			u32 v = readl(host->ioaddr + SDHCI_ACMD12_ERR);
 			u32 m = readl(host->ioaddr + ESDHC_MIX_CTRL);
+			u32 tuning_ctrl;
 			if (val & SDHCI_CTRL_TUNED_CLK) {
 				v |= ESDHC_MIX_CTRL_SMPCLK_SEL;
 			} else {
@@ -484,6 +486,11 @@ static void esdhc_writew_le(struct sdhci_host *host, u16 val, int reg)
 			if (val & SDHCI_CTRL_EXEC_TUNING) {
 				v |= ESDHC_MIX_CTRL_EXE_TUNE;
 				m |= ESDHC_MIX_CTRL_FBCLK_SEL;
+				tuning_ctrl = readl(host->ioaddr + ESDHC_TUNING_CTRL);
+				tuning_ctrl |= ESDHC_STD_TUNING_EN | ESDHC_TUNING_START_TAP;
+				if (imx_data->boarddata.tuning_step)
+					tuning_ctrl |= imx_data->boarddata.tuning_step << ESDHC_TUNING_STEP_SHIFT;
+					writel(tuning_ctrl, host->ioaddr + ESDHC_TUNING_CTRL);
 			} else {
 				v &= ~ESDHC_MIX_CTRL_EXE_TUNE;
 			}
@@ -965,6 +972,8 @@ sdhci_esdhc_imx_probe_dt(struct platform_device *pdev,
 	if (gpio_is_valid(boarddata->wp_gpio))
 		boarddata->wp_type = ESDHC_WP_GPIO;
 
+	of_property_read_u32(np, "fsl,tuning-step", &boarddata->tuning_step);
+
 	if (of_find_property(np, "no-1-8-v", NULL))
 		boarddata->support_vsel = false;
 	else
diff --git a/include/linux/platform_data/mmc-esdhc-imx.h b/include/linux/platform_data/mmc-esdhc-imx.h
index e1571ef..95ccab3 100644
--- a/include/linux/platform_data/mmc-esdhc-imx.h
+++ b/include/linux/platform_data/mmc-esdhc-imx.h
@@ -45,5 +45,6 @@ struct esdhc_platform_data {
 	int max_bus_width;
 	bool support_vsel;
 	unsigned int delay_line;
+	unsigned int tuning_step;       /* The delay cell steps in tuning procedure */
 };
 #endif /* __ASM_ARCH_IMX_ESDHC_H */
-- 
1.9.1



From haibo.chen at freescale.com  Mon Aug 10 01:18:05 2015
From: haibo.chen at freescale.com (Haibo Chen)
Date: Mon, 10 Aug 2015 16:18:05 +0800
Subject: [PATCH v5 3/6] mmc: sdhci-esdhc-imx: add compatible string in
 bingding doc
In-Reply-To: <1439194688-18335-1-git-send-email-haibo.chen@freescale.com>
References: <1439194688-18335-1-git-send-email-haibo.chen@freescale.com>
Message-ID: <1439194688-18335-4-git-send-email-haibo.chen@freescale.com>

Add a required property "fsl,imx7d-usdhc" in binding doc.
Add an optional property "fsl,tuning-step" in binding doc.

Signed-off-by: Haibo Chen <haibo.chen at freescale.com>
---
 Documentation/devicetree/bindings/mmc/fsl-imx-esdhc.txt | 6 ++++++
 1 file changed, 6 insertions(+)

diff --git a/Documentation/devicetree/bindings/mmc/fsl-imx-esdhc.txt b/Documentation/devicetree/bindings/mmc/fsl-imx-esdhc.txt
index 211e778..dca56d6 100644
--- a/Documentation/devicetree/bindings/mmc/fsl-imx-esdhc.txt
+++ b/Documentation/devicetree/bindings/mmc/fsl-imx-esdhc.txt
@@ -15,6 +15,7 @@ Required properties:
 	       "fsl,imx6q-usdhc"
 	       "fsl,imx6sl-usdhc"
 	       "fsl,imx6sx-usdhc"
+	       "fsl,imx7d-usdhc"
 
 Optional properties:
 - fsl,wp-controller : Indicate to use controller internal write protection
@@ -27,6 +28,11 @@ Optional properties:
   transparent level shifters on the outputs of the controller. Two cells are
   required, first cell specifies minimum slot voltage (mV), second cell
   specifies maximum slot voltage (mV). Several ranges could be specified.
+- fsl,tuning-step: Specify the increasing delay cell steps in tuning procedure.
+  The uSDHC use one delay cell as default increasing step to do tuning process.
+  This property allows user to change the tuning step to more than one delay
+  cells which is useful for some special boards or cards when the default
+  tuning step can't find the proper delay window within limited tuning retries.
 
 Examples:
 
-- 
1.9.1



From haibo.chen at freescale.com  Mon Aug 10 01:18:06 2015
From: haibo.chen at freescale.com (Haibo Chen)
Date: Mon, 10 Aug 2015 16:18:06 +0800
Subject: [PATCH v5 4/6] ARM: dts: imx7d-sdb: add eMMC5.0 support
In-Reply-To: <1439194688-18335-1-git-send-email-haibo.chen@freescale.com>
References: <1439194688-18335-1-git-send-email-haibo.chen@freescale.com>
Message-ID: <1439194688-18335-5-git-send-email-haibo.chen@freescale.com>

imx7d-sdb board has a eMMC5.0 on usdhc3. This eMMC support HS400.
This patch add usdhc3 support for HS400

Signed-off-by: Haibo Chen <haibo.chen at freescale.com>
---
 arch/arm/boot/dts/imx7d-sdb.dts | 13 +++++++++++++
 1 file changed, 13 insertions(+)

diff --git a/arch/arm/boot/dts/imx7d-sdb.dts b/arch/arm/boot/dts/imx7d-sdb.dts
index fdd1d7c..8059458 100644
--- a/arch/arm/boot/dts/imx7d-sdb.dts
+++ b/arch/arm/boot/dts/imx7d-sdb.dts
@@ -241,6 +241,19 @@
 	status = "okay";
 };
 
+&usdhc3 {
+	pinctrl-names = "default", "state_100mhz", "state_200mhz";
+	pinctrl-0 = <&pinctrl_usdhc3>;
+	pinctrl-1 = <&pinctrl_usdhc3_100mhz>;
+	pinctrl-2 = <&pinctrl_usdhc3_200mhz>;
+	assigned-clocks = <&clks IMX7D_USDHC3_ROOT_CLK>;
+	assigned-clock-rates = <400000000>;
+	bus-width = <8>;
+	fsl,tuning-step = <2>;
+	non-removable;
+	status = "okay";
+};
+
 &iomuxc {
 	pinctrl-names = "default";
 	pinctrl-0 = <&pinctrl_hog>;
-- 
1.9.1



From haibo.chen at freescale.com  Mon Aug 10 01:18:07 2015
From: haibo.chen at freescale.com (Haibo Chen)
Date: Mon, 10 Aug 2015 16:18:07 +0800
Subject: [PATCH v5 5/6] mmc: sdhci-esdhc-imx: set back the burst_length_enable
 bit to 1
In-Reply-To: <1439194688-18335-1-git-send-email-haibo.chen@freescale.com>
References: <1439194688-18335-1-git-send-email-haibo.chen@freescale.com>
Message-ID: <1439194688-18335-6-git-send-email-haibo.chen@freescale.com>

Currently we find that if a usdhc is choosed to boot system, then ROM
code will set the burst length enable bit of this usdhc as 0.

This will make performance drop a lot if this usdhc's burst length is
configed. So this patch set back the burst_length_enable bit as 1,
which is the default value, and means burst length is enabled for INCR.

Signed-off-by: Haibo Chen <haibo.chen at freescale.com>
---
 drivers/mmc/host/sdhci-esdhc-imx.c | 16 ++++++++++++++++
 1 file changed, 16 insertions(+)

diff --git a/drivers/mmc/host/sdhci-esdhc-imx.c b/drivers/mmc/host/sdhci-esdhc-imx.c
index 03c9f33..d7ec993 100644
--- a/drivers/mmc/host/sdhci-esdhc-imx.c
+++ b/drivers/mmc/host/sdhci-esdhc-imx.c
@@ -32,6 +32,7 @@
 #include "sdhci-esdhc.h"
 
 #define	ESDHC_CTRL_D3CD			0x08
+#define ESDHC_BURST_LEN_EN_INCR		(1 << 27)
 /* VENDOR SPEC register */
 #define ESDHC_VENDOR_SPEC		0xc0
 #define  ESDHC_VENDOR_SPEC_SDIO_QUIRK	(1 << 1)
@@ -1165,6 +1166,21 @@ static int sdhci_esdhc_imx_probe(struct platform_device *pdev)
 		host->quirks2 |= SDHCI_QUIRK2_PRESET_VALUE_BROKEN;
 		host->mmc->caps |= MMC_CAP_1_8V_DDR;
 
+		/*
+		 * ROM code will change the bit burst_length_enable setting
+		 * to zero if this usdhc is choosed to boot system. Change
+		 * it back here, otherwise it will impact the performance a
+		 * lot. This bit is used to enable/disable the burst length
+		 * for the external AHB2AXI bridge, it's usefully especially
+		 * for INCR transfer because without burst length indicator,
+		 * the AHB2AXI bridge does not know the burst length in
+		 * advance. And without burst length indicator, AHB INCR
+		 * transfer can only be converted to singles on the AXI side.
+		 */
+		writel(readl(host->ioaddr + SDHCI_HOST_CONTROL)
+			| ESDHC_BURST_LEN_EN_INCR,
+			host->ioaddr + SDHCI_HOST_CONTROL);
+
 		if (!(imx_data->socdata->flags & ESDHC_FLAG_HS200))
 			host->quirks2 |= SDHCI_QUIRK2_BROKEN_HS200;
 
-- 
1.9.1



From haibo.chen at freescale.com  Mon Aug 10 01:18:08 2015
From: haibo.chen at freescale.com (Haibo Chen)
Date: Mon, 10 Aug 2015 16:18:08 +0800
Subject: [PATCH v5 6/6] mmc: sdhci-esdhc-imx: change default watermark level
 and burst length
In-Reply-To: <1439194688-18335-1-git-send-email-haibo.chen@freescale.com>
References: <1439194688-18335-1-git-send-email-haibo.chen@freescale.com>
Message-ID: <1439194688-18335-7-git-send-email-haibo.chen@freescale.com>

By default, for all imx SoC types, the watermark level is 16, and the
burst length is 8. But if the SDIO/SD/MMC I/O speed is fast enough,
this default watermark level and burst length will be the performance
bottleneck.

For example, i.MX7D support eMMC HS400 mode, this mode can run in 8 bit,
200MHZ DDR mode. So the I/O speed improve a lot compare to SD3.0.
The default burst length is 8, if we don't change this value, in
HS400 mode, when we do eMMC read operation, we can find that the
clock signal will stop for a period of time. This means the speed
of data moving on AHB bus is slower than I/O speed. So we should
improve the speed of data moving on AHB bus.

This patch set the default burst length as 16, and set the default
watermark level as 64. The test result is the clock signal has
no stop during the eMMC HS400 operation.

Signed-off-by: Haibo Chen <haibo.chen at freescale.com>
---
 drivers/mmc/host/sdhci-esdhc-imx.c | 3 ++-
 1 file changed, 2 insertions(+), 1 deletion(-)

diff --git a/drivers/mmc/host/sdhci-esdhc-imx.c b/drivers/mmc/host/sdhci-esdhc-imx.c
index d7ec993..1b31d36 100644
--- a/drivers/mmc/host/sdhci-esdhc-imx.c
+++ b/drivers/mmc/host/sdhci-esdhc-imx.c
@@ -1162,7 +1162,8 @@ static int sdhci_esdhc_imx_probe(struct platform_device *pdev)
 	 * to something insane.  Change it back here.
 	 */
 	if (esdhc_is_usdhc(imx_data)) {
-		writel(0x08100810, host->ioaddr + ESDHC_WTMK_LVL);
+		writel(0x10401040, host->ioaddr + ESDHC_WTMK_LVL);
+
 		host->quirks2 |= SDHCI_QUIRK2_PRESET_VALUE_BROKEN;
 		host->mmc->caps |= MMC_CAP_1_8V_DDR;
 
-- 
1.9.1



From lee.jones at linaro.org  Mon Aug 10 01:24:45 2015
From: lee.jones at linaro.org (Lee Jones)
Date: Mon, 10 Aug 2015 09:24:45 +0100
Subject: [PATCH v2 2/6] mailbox: dt-bindings: Add shared [driver <=>
 device tree] defines
In-Reply-To: <CABb+yY2asjH-c+VJXvG+RK0=2p=P4Y21pznNP0riaKMWLxYZog@mail.gmail.com>
References: <1437990272-23111-1-git-send-email-lee.jones@linaro.org>
 <1437990272-23111-3-git-send-email-lee.jones@linaro.org>
 <CABb+yY2asjH-c+VJXvG+RK0=2p=P4Y21pznNP0riaKMWLxYZog@mail.gmail.com>
Message-ID: <20150810082445.GA3249@x1>

On Mon, 10 Aug 2015, Jassi Brar wrote:
> On Mon, Jul 27, 2015 at 3:14 PM, Lee Jones <lee.jones at linaro.org> wrote:
> > This header is currently only used for defines pertaining to data
> > direction i.e. Rx, Tx or Loopback.
> >
> > Signed-off-by: Lee Jones <lee.jones at linaro.org>
> > ---
> >  include/dt-bindings/mailbox/mailbox.h | 14 ++++++++++++++
> >  1 file changed, 14 insertions(+)
> >  create mode 100644 include/dt-bindings/mailbox/mailbox.h
> >
> > diff --git a/include/dt-bindings/mailbox/mailbox.h b/include/dt-bindings/mailbox/mailbox.h
> > new file mode 100644
> > index 0000000..82e929a
> > --- /dev/null
> > +++ b/include/dt-bindings/mailbox/mailbox.h
> > @@ -0,0 +1,14 @@
> > +/*
> > + * 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.
> > + */
> > +
> > +#ifndef __MAILBOX_CONTROLLER_DT_BINDINGS_H
> > +#define __MAILBOX_CONTROLLER_DT_BINDINGS_H
> > +
> > +#define MBOX_TX                0x1
> > +#define MBOX_RX                0x2
> > +#define MBOX_LOOPBACK  (MBOX_RX | MBOX_TX)
> > +
> Not sure I understand 'loopback'.  Does it mean h/w has some
> 'loopback' mode for testing purposes? Or it simply means the
> controller can send as well as receive messages?

'loopback' allows firmware to conduct some early function tests.
However, channels are simplex, so we provide protection against
multiple allocation of single channel.  By allocating a LOOPBACK
channel we over-ride this protection and allow a single channel to be
allocated twice, once for Rx and the other for Tx.

This mode was born out of a _real_ use-case.  Some of ST's firmware
running on products actually uses the loopback feature.

-- 
Lee Jones
Linaro STMicroelectronics Landing Team Lead
Linaro.org ? Open source software for ARM SoCs
Follow Linaro: Facebook | Twitter | Blog


From aisheng.dong at freescale.com  Mon Aug 10 01:21:03 2015
From: aisheng.dong at freescale.com (Dong Aisheng)
Date: Mon, 10 Aug 2015 16:21:03 +0800
Subject: [PATCH v5 1/6] mmc: sdhci-esdhc-imx: add imx7d support and
 support HS400
In-Reply-To: <1439194688-18335-2-git-send-email-haibo.chen@freescale.com>
References: <1439194688-18335-1-git-send-email-haibo.chen@freescale.com>
 <1439194688-18335-2-git-send-email-haibo.chen@freescale.com>
Message-ID: <20150810082100.GA15036@shlinux1.ap.freescale.net>

On Mon, Aug 10, 2015 at 04:18:03PM +0800, Haibo Chen wrote:
> The imx7d usdhc is derived from imx6sx, the difference is that
> imx7d support HS400.
> 
> So introduce a new compatible string for imx7d and add HS400
> support for imx7d usdhc.
> 
> Signed-off-by: Haibo Chen <haibo.chen at freescale.com>
> ---
>  drivers/mmc/host/sdhci-esdhc-imx.c | 88 ++++++++++++++++++++++++++++++++++++--
>  1 file changed, 85 insertions(+), 3 deletions(-)
> 
> diff --git a/drivers/mmc/host/sdhci-esdhc-imx.c b/drivers/mmc/host/sdhci-esdhc-imx.c
> index c6b9f64..2a816ad 100644
> --- a/drivers/mmc/host/sdhci-esdhc-imx.c
> +++ b/drivers/mmc/host/sdhci-esdhc-imx.c
> @@ -44,6 +44,7 @@
>  #define  ESDHC_MIX_CTRL_EXE_TUNE	(1 << 22)
>  #define  ESDHC_MIX_CTRL_SMPCLK_SEL	(1 << 23)
>  #define  ESDHC_MIX_CTRL_FBCLK_SEL	(1 << 25)
> +#define  ESDHC_MIX_CTRL_HS400_EN	(1 << 26)
>  /* Bits 3 and 6 are not SDHCI standard definitions */
>  #define  ESDHC_MIX_CTRL_SDHCI_MASK	0xb7
>  /* Tuning bits */
> @@ -60,6 +61,16 @@
>  #define  ESDHC_TUNE_CTRL_MIN		0
>  #define  ESDHC_TUNE_CTRL_MAX		((1 << 7) - 1)
>  
> +/* strobe dll register */
> +#define ESDHC_STROBE_DLL_CTRL		0x70
> +#define ESDHC_STROBE_DLL_CTRL_ENABLE	(1 << 0)
> +#define ESDHC_STROBE_DLL_CTRL_RESET	(1 << 1)
> +#define ESDHC_STROBE_DLL_CTRL_SLV_DLY_TARGET_SHIFT	3
> +
> +#define ESDHC_STROBE_DLL_STATUS		0x74
> +#define ESDHC_STROBE_DLL_STS_REF_LOCK	(1 << 1)
> +#define ESDHC_STROBE_DLL_STS_SLV_LOCK	0x1
> +
>  #define ESDHC_TUNING_CTRL		0xcc
>  #define ESDHC_STD_TUNING_EN		(1 << 24)
>  /* NOTE: the minimum valid tuning start tap for mx6sl is 1 */
> @@ -120,6 +131,11 @@
>  #define ESDHC_FLAG_ERR004536		BIT(7)
>  /* The IP supports HS200 mode */
>  #define ESDHC_FLAG_HS200		BIT(8)
> +/* The IP supports HS400 mode */
> +#define ESDHC_FLAG_HS400		BIT(9)
> +
> +/* A higher clock ferquency than this rate requires strobell dll control */
> +#define ESDHC_STROBE_DLL_CLK_FREQ	100000000
>  
>  struct esdhc_soc_data {
>  	u32 flags;
> @@ -156,6 +172,12 @@ static struct esdhc_soc_data usdhc_imx6sx_data = {
>  			| ESDHC_FLAG_HAVE_CAP1 | ESDHC_FLAG_HS200,
>  };
>  
> +static struct esdhc_soc_data usdhc_imx7d_data = {
> +	.flags = ESDHC_FLAG_USDHC | ESDHC_FLAG_STD_TUNING
> +			| ESDHC_FLAG_HAVE_CAP1 | ESDHC_FLAG_HS200
> +			| ESDHC_FLAG_HS400,
> +};
> +
>  struct pltfm_imx_data {
>  	u32 scratchpad;
>  	struct pinctrl *pinctrl;
> @@ -199,6 +221,7 @@ static const struct of_device_id imx_esdhc_dt_ids[] = {
>  	{ .compatible = "fsl,imx6sx-usdhc", .data = &usdhc_imx6sx_data, },
>  	{ .compatible = "fsl,imx6sl-usdhc", .data = &usdhc_imx6sl_data, },
>  	{ .compatible = "fsl,imx6q-usdhc", .data = &usdhc_imx6q_data, },
> +	{ .compatible = "fsl,imx7d-usdhc", .data = &usdhc_imx7d_data, },
>  	{ /* sentinel */ }
>  };
>  MODULE_DEVICE_TABLE(of, imx_esdhc_dt_ids);
> @@ -274,6 +297,9 @@ static u32 esdhc_readl_le(struct sdhci_host *host, int reg)
>  				val = SDHCI_SUPPORT_DDR50 | SDHCI_SUPPORT_SDR104
>  					| SDHCI_SUPPORT_SDR50
>  					| SDHCI_USE_SDR50_TUNING;
> +
> +			if (imx_data->socdata->flags & ESDHC_FLAG_HS400)
> +				val |= SDHCI_SUPPORT_HS400;
>  		}
>  	}
>  
> @@ -774,6 +800,7 @@ static int esdhc_change_pinstate(struct sdhci_host *host,
>  		break;
>  	case MMC_TIMING_UHS_SDR104:
>  	case MMC_TIMING_MMC_HS200:
> +	case MMC_TIMING_MMC_HS400:
>  		pinctrl = imx_data->pins_200mhz;
>  		break;
>  	default:
> @@ -784,12 +811,57 @@ static int esdhc_change_pinstate(struct sdhci_host *host,
>  	return pinctrl_select_state(imx_data->pinctrl, pinctrl);
>  }
>  
> +/*
> + * For HS400 eMMC, there is a data_strobe line, this signal is generated
> + * by the device and used for data output and CRC status response output
> + * in HS400 mode. The frequency of this signal follows the frequency of
> + * CLK generated by host. Host receive the data which is aligned to the
> + * edge of data_strobe line. Due to the time delay between CLK line and
> + * data_strobe line, if the delay time is larger than one clock cycle,
> + * then CLK and data_strobe line will misaligned, read error shows up.
> + * So when the CLK is higher than 100MHz, each clock cycle is short enough,
> + * host should config the delay target.
> + */
> +static void esdhc_set_strobe_dll(struct sdhci_host *host)
> +{
> +	u32 v;
> +
> +	if (host->mmc->actual_clock > ESDHC_STROBE_DLL_CLK_FREQ) {
> +		/* force a reset on strobe dll */
> +		writel(ESDHC_STROBE_DLL_CTRL_RESET,
> +			host->ioaddr + ESDHC_STROBE_DLL_CTRL);
> +		/*
> +		 * enable strobe dll ctrl and adjust the delay target
> +		 * for the uSDHC loopback read clock
> +		 */
> +		v = ESDHC_STROBE_DLL_CTRL_ENABLE |
> +			(7 << ESDHC_STROBE_DLL_CTRL_SLV_DLY_TARGET_SHIFT);
> +		writel(v, host->ioaddr + ESDHC_STROBE_DLL_CTRL);
> +		/* wait 1us to make sure strobe dll status register stable */
> +		udelay(1);
> +		v = readl(host->ioaddr + ESDHC_STROBE_DLL_STATUS);
> +		if (!(v & ESDHC_STROBE_DLL_STS_REF_LOCK))
> +			dev_warn(mmc_dev(host->mmc),
> +				"warning! HS400 strobe DLL status REF not lock!\n");
> +		if (!(v & ESDHC_STROBE_DLL_STS_SLV_LOCK))
> +			dev_warn(mmc_dev(host->mmc),
> +				"warning! HS400 strobe DLL status SLV not lock!\n");
> +	}
> +}
> +
>  static void esdhc_set_uhs_signaling(struct sdhci_host *host, unsigned timing)
>  {
> +	u32 m;
>  	struct sdhci_pltfm_host *pltfm_host = sdhci_priv(host);
>  	struct pltfm_imx_data *imx_data = pltfm_host->priv;
>  	struct esdhc_platform_data *boarddata = &imx_data->boarddata;
>  
> +	/* disable ddr mode and disable HS400 mode */
> +	m = readl(host->ioaddr + ESDHC_MIX_CTRL);
> +	m &= ~(ESDHC_MIX_CTRL_DDREN | ESDHC_MIX_CTRL_HS400_EN);
> +	writel(m, host->ioaddr + ESDHC_MIX_CTRL);

Is this write really required?

> +	imx_data->is_ddr = 0;
> +
>  	switch (timing) {
>  	case MMC_TIMING_UHS_SDR12:
>  	case MMC_TIMING_UHS_SDR25:
> @@ -799,9 +871,9 @@ static void esdhc_set_uhs_signaling(struct sdhci_host *host, unsigned timing)
>  		break;
>  	case MMC_TIMING_UHS_DDR50:
>  	case MMC_TIMING_MMC_DDR52:
> -		writel(readl(host->ioaddr + ESDHC_MIX_CTRL) |
> -				ESDHC_MIX_CTRL_DDREN,
> -				host->ioaddr + ESDHC_MIX_CTRL);
> +		m = readl(host->ioaddr + ESDHC_MIX_CTRL);

Can this line be droped if using the former readback mixctl value?

> +		m |= ESDHC_MIX_CTRL_DDREN;
> +		writel(m, host->ioaddr + ESDHC_MIX_CTRL);
>  		imx_data->is_ddr = 1;
>  		if (boarddata->delay_line) {
>  			u32 v;
> @@ -813,6 +885,13 @@ static void esdhc_set_uhs_signaling(struct sdhci_host *host, unsigned timing)
>  			writel(v, host->ioaddr + ESDHC_DLL_CTRL);
>  		}
>  		break;
> +	case MMC_TIMING_MMC_HS400:
> +		m = readl(host->ioaddr + ESDHC_MIX_CTRL);

ditto

Regards
Dong Aisheng

> +		m |= ESDHC_MIX_CTRL_DDREN | ESDHC_MIX_CTRL_HS400_EN;
> +		writel(m, host->ioaddr + ESDHC_MIX_CTRL);
> +		imx_data->is_ddr = 1;
> +		esdhc_set_strobe_dll(host);
> +		break;
>  	}
>  
>  	esdhc_change_pinstate(host, timing);
> @@ -1100,6 +1179,9 @@ static int sdhci_esdhc_imx_probe(struct platform_device *pdev)
>  	if (imx_data->socdata->flags & ESDHC_FLAG_ERR004536)
>  		host->quirks |= SDHCI_QUIRK_BROKEN_ADMA;
>  
> +	if (imx_data->socdata->flags & ESDHC_FLAG_HS400)
> +		host->quirks2 |= SDHCI_QUIRK2_CAPS_BIT63_FOR_HS400;
> +
>  	if (of_id)
>  		err = sdhci_esdhc_imx_probe_dt(pdev, host, imx_data);
>  	else
> -- 
> 1.9.1
> 


From aisheng.dong at freescale.com  Mon Aug 10 01:25:01 2015
From: aisheng.dong at freescale.com (Dong Aisheng)
Date: Mon, 10 Aug 2015 16:25:01 +0800
Subject: [PATCH v5 2/6] mmc: sdhci-esdhc-imx: add tuning-step seting
 support
In-Reply-To: <1439194688-18335-3-git-send-email-haibo.chen@freescale.com>
References: <1439194688-18335-1-git-send-email-haibo.chen@freescale.com>
 <1439194688-18335-3-git-send-email-haibo.chen@freescale.com>
Message-ID: <20150810082500.GB15036@shlinux1.ap.freescale.net>

On Mon, Aug 10, 2015 at 04:18:04PM +0800, Haibo Chen wrote:
> tuning-step is the delay cell steps in tuning procedure. The default value
> of tuning-step is 1. Some boards or cards need another value to pass the
> tuning procedure. For example, imx7d-sdb board need the tuning-step value
> as 2, otherwise it can't pass the tuning procedure.
> 
> So this patch add the tuning-step setting in driver, so that user can set
> the tuning-step value in dts.
> 

Fix a typo.

For patch title:
mmc: sdhci-esdhc-imx: add tuning-step seting support
s/seting/setting

Regards
Dong Aisheng

> Signed-off-by: Haibo Chen <haibo.chen at freescale.com>
> ---
>  drivers/mmc/host/sdhci-esdhc-imx.c          | 9 +++++++++
>  include/linux/platform_data/mmc-esdhc-imx.h | 1 +
>  2 files changed, 10 insertions(+)
> 
> diff --git a/drivers/mmc/host/sdhci-esdhc-imx.c b/drivers/mmc/host/sdhci-esdhc-imx.c
> index 2a816ad..03c9f33 100644
> --- a/drivers/mmc/host/sdhci-esdhc-imx.c
> +++ b/drivers/mmc/host/sdhci-esdhc-imx.c
> @@ -75,6 +75,7 @@
>  #define ESDHC_STD_TUNING_EN		(1 << 24)
>  /* NOTE: the minimum valid tuning start tap for mx6sl is 1 */
>  #define ESDHC_TUNING_START_TAP		0x1
> +#define ESDHC_TUNING_STEP_SHIFT		16
>  
>  /* pinctrl state */
>  #define ESDHC_PINCTRL_STATE_100MHZ	"state_100mhz"
> @@ -474,6 +475,7 @@ static void esdhc_writew_le(struct sdhci_host *host, u16 val, int reg)
>  		} else if (imx_data->socdata->flags & ESDHC_FLAG_STD_TUNING) {
>  			u32 v = readl(host->ioaddr + SDHCI_ACMD12_ERR);
>  			u32 m = readl(host->ioaddr + ESDHC_MIX_CTRL);
> +			u32 tuning_ctrl;
>  			if (val & SDHCI_CTRL_TUNED_CLK) {
>  				v |= ESDHC_MIX_CTRL_SMPCLK_SEL;
>  			} else {
> @@ -484,6 +486,11 @@ static void esdhc_writew_le(struct sdhci_host *host, u16 val, int reg)
>  			if (val & SDHCI_CTRL_EXEC_TUNING) {
>  				v |= ESDHC_MIX_CTRL_EXE_TUNE;
>  				m |= ESDHC_MIX_CTRL_FBCLK_SEL;
> +				tuning_ctrl = readl(host->ioaddr + ESDHC_TUNING_CTRL);
> +				tuning_ctrl |= ESDHC_STD_TUNING_EN | ESDHC_TUNING_START_TAP;
> +				if (imx_data->boarddata.tuning_step)
> +					tuning_ctrl |= imx_data->boarddata.tuning_step << ESDHC_TUNING_STEP_SHIFT;
> +					writel(tuning_ctrl, host->ioaddr + ESDHC_TUNING_CTRL);
>  			} else {
>  				v &= ~ESDHC_MIX_CTRL_EXE_TUNE;
>  			}
> @@ -965,6 +972,8 @@ sdhci_esdhc_imx_probe_dt(struct platform_device *pdev,
>  	if (gpio_is_valid(boarddata->wp_gpio))
>  		boarddata->wp_type = ESDHC_WP_GPIO;
>  
> +	of_property_read_u32(np, "fsl,tuning-step", &boarddata->tuning_step);
> +
>  	if (of_find_property(np, "no-1-8-v", NULL))
>  		boarddata->support_vsel = false;
>  	else
> diff --git a/include/linux/platform_data/mmc-esdhc-imx.h b/include/linux/platform_data/mmc-esdhc-imx.h
> index e1571ef..95ccab3 100644
> --- a/include/linux/platform_data/mmc-esdhc-imx.h
> +++ b/include/linux/platform_data/mmc-esdhc-imx.h
> @@ -45,5 +45,6 @@ struct esdhc_platform_data {
>  	int max_bus_width;
>  	bool support_vsel;
>  	unsigned int delay_line;
> +	unsigned int tuning_step;       /* The delay cell steps in tuning procedure */
>  };
>  #endif /* __ASM_ARCH_IMX_ESDHC_H */
> -- 
> 1.9.1
> 


From aisheng.dong at freescale.com  Mon Aug 10 01:29:06 2015
From: aisheng.dong at freescale.com (Dong Aisheng)
Date: Mon, 10 Aug 2015 16:29:06 +0800
Subject: [PATCH v5 3/6] mmc: sdhci-esdhc-imx: add compatible string in
 bingding doc
In-Reply-To: <1439194688-18335-4-git-send-email-haibo.chen@freescale.com>
References: <1439194688-18335-1-git-send-email-haibo.chen@freescale.com>
 <1439194688-18335-4-git-send-email-haibo.chen@freescale.com>
Message-ID: <20150810082905.GC15036@shlinux1.ap.freescale.net>

On Mon, Aug 10, 2015 at 04:18:05PM +0800, Haibo Chen wrote:
> Add a required property "fsl,imx7d-usdhc" in binding doc.
> Add an optional property "fsl,tuning-step" in binding doc.
> 
> Signed-off-by: Haibo Chen <haibo.chen at freescale.com>

You missed my former comments.

The patch title is too generous.
Better to change to something like:
mmc: sdhci-esdhc-imx: add imx7d support in bingding doc

Regards
Dong Aisheng

> ---
>  Documentation/devicetree/bindings/mmc/fsl-imx-esdhc.txt | 6 ++++++
>  1 file changed, 6 insertions(+)
> 
> diff --git a/Documentation/devicetree/bindings/mmc/fsl-imx-esdhc.txt b/Documentation/devicetree/bindings/mmc/fsl-imx-esdhc.txt
> index 211e778..dca56d6 100644
> --- a/Documentation/devicetree/bindings/mmc/fsl-imx-esdhc.txt
> +++ b/Documentation/devicetree/bindings/mmc/fsl-imx-esdhc.txt
> @@ -15,6 +15,7 @@ Required properties:
>  	       "fsl,imx6q-usdhc"
>  	       "fsl,imx6sl-usdhc"
>  	       "fsl,imx6sx-usdhc"
> +	       "fsl,imx7d-usdhc"
>  
>  Optional properties:
>  - fsl,wp-controller : Indicate to use controller internal write protection
> @@ -27,6 +28,11 @@ Optional properties:
>    transparent level shifters on the outputs of the controller. Two cells are
>    required, first cell specifies minimum slot voltage (mV), second cell
>    specifies maximum slot voltage (mV). Several ranges could be specified.
> +- fsl,tuning-step: Specify the increasing delay cell steps in tuning procedure.
> +  The uSDHC use one delay cell as default increasing step to do tuning process.
> +  This property allows user to change the tuning step to more than one delay
> +  cells which is useful for some special boards or cards when the default
> +  tuning step can't find the proper delay window within limited tuning retries.
>  
>  Examples:
>  
> -- 
> 1.9.1
> 


From eric.auger at linaro.org  Mon Aug 10 01:43:00 2015
From: eric.auger at linaro.org (Eric Auger)
Date: Mon, 10 Aug 2015 10:43:00 +0200
Subject: [PATCH v4 4/5] KVM: introduce kvm_arch functions for IRQ bypass
In-Reply-To: <1438978154.4023.262.camel@redhat.com>
References: <1438622444-25444-1-git-send-email-eric.auger@linaro.org>	
 <1438622444-25444-5-git-send-email-eric.auger@linaro.org>
 <1438978154.4023.262.camel@redhat.com>
Message-ID: <55C86414.5070203@linaro.org>

On 08/07/2015 10:09 PM, Alex Williamson wrote:
> On Mon, 2015-08-03 at 19:20 +0200, Eric Auger wrote:
>> This patch introduces
>> - kvm_arch_irq_bypass_add_producer
>> - kvm_arch_irq_bypass_del_producer
>> - kvm_arch_irq_bypass_stop
>> - kvm_arch_irq_bypass_start
>>
>> They make possible to specialize the KVM IRQ bypass consumer in
>> case CONFIG_KVM_HAVE_IRQ_BYPASS is set.
>>
>> Signed-off-by: Eric Auger <eric.auger at linaro.org>
>> Signed-off-by: Feng Wu <feng.wu at intel.com>
>>
>> ---
>>
>> v2 -> v3 (Feng Wu):
>> - use 'kvm_arch_irq_bypass_start' instead of 'kvm_arch_irq_bypass_resume'
>> - Remove 'kvm_arch_irq_bypass_update', which is not needed to be
>>   a irqbypass callback per Alex's comments.
>> - Make kvm_arch_irq_bypass_add_producer return 'int'
>>
>> v1 -> v2:
>> - use CONFIG_KVM_HAVE_IRQ_BYPASS instead CONFIG_IRQ_BYPASS_MANAGER
>> - rename all functions according to Paolo's proposal
>> - add kvm_arch_irq_bypass_update according to Feng's need
>> ---
>>  include/linux/kvm_host.h | 33 +++++++++++++++++++++++++++++++++
>>  virt/kvm/Kconfig         |  3 +++
>>  2 files changed, 36 insertions(+)
>>
>> diff --git a/include/linux/kvm_host.h b/include/linux/kvm_host.h
>> index 05e99b8..84b5feb 100644
>> --- a/include/linux/kvm_host.h
>> +++ b/include/linux/kvm_host.h
>> @@ -24,6 +24,7 @@
>>  #include <linux/err.h>
>>  #include <linux/irqflags.h>
>>  #include <linux/context_tracking.h>
>> +#include <linux/irqbypass.h>
>>  #include <asm/signal.h>
>>  
>>  #include <linux/kvm.h>
>> @@ -1151,5 +1152,37 @@ static inline void kvm_vcpu_set_dy_eligible(struct kvm_vcpu *vcpu, bool val)
>>  {
>>  }
>>  #endif /* CONFIG_HAVE_KVM_CPU_RELAX_INTERCEPT */
>> +
>> +#ifdef CONFIG_HAVE_KVM_IRQ_BYPASS
>> +
>> +int kvm_arch_irq_bypass_add_producer(struct irq_bypass_consumer *,
>> +			   struct irq_bypass_producer *);
>> +void kvm_arch_irq_bypass_del_producer(struct irq_bypass_consumer *,
>> +			   struct irq_bypass_producer *);
>> +void kvm_arch_irq_bypass_stop(struct irq_bypass_consumer *);
>> +void kvm_arch_irq_bypass_start(struct irq_bypass_consumer *);
>> +
>> +#else
> 
> Do we really need static inline stubs?  When would they get used?
This addresses the case where another arch would use an irq bypass
producer (such as vfio platform driver ) and irqfd without
implementing/needing forwarding/posting stuff.

I see 2 solutions: either we have those stubs or in eventfd.c we guard
	irq_bypass_unregister_consumer(&irqfd->consumer);
and
	ret = irq_bypass_register_consumer(&irqfd->consumer);
by

#ifdef CONFIG_HAVE_KVM_IRQ_BYPASS
#endif

This latter solution maybe is better.

  How
> would they work since we call them via function pointers?
Just tested that without the ARM forwarding implementation of kvm_arch
functions and that runs fine.
> 
>> +
>> +static inline int kvm_arch_irq_bypass_add_producer(
>> +			struct irq_bypass_consumer *cons,
>> +			struct irq_bypass_producer *prod)
>> +{
>> +	return -1;
> 
> No reason not to stick with standard errno values, is there?  -EINVAL
> Thanks,
sure

Thanks

Eric
> 
> Alex
> 
>> +}
>> +static inline void kvm_arch_irq_bypass_del_producer(
>> +			struct irq_bypass_consumer *cons,
>> +			struct irq_bypass_producer *prod)
>> +{
>> +}
>> +static inline void kvm_arch_irq_bypass_stop(
>> +			struct irq_bypass_consumer *cons)
>> +{
>> +}
>> +static inline void kvm_arch_irq_bypass_start(
>> +			struct irq_bypass_consumer *cons)
>> +{
>> +}
>> +#endif /* CONFIG_HAVE_KVM_IRQ_BYPASS */
>>  #endif
>>  
>> diff --git a/virt/kvm/Kconfig b/virt/kvm/Kconfig
>> index e2c876d..9f8014d 100644
>> --- a/virt/kvm/Kconfig
>> +++ b/virt/kvm/Kconfig
>> @@ -47,3 +47,6 @@ config KVM_GENERIC_DIRTYLOG_READ_PROTECT
>>  config KVM_COMPAT
>>         def_bool y
>>         depends on COMPAT && !S390
>> +
>> +config HAVE_KVM_IRQ_BYPASS
>> +       bool
> 
> 
> 



From oliver at schinagl.nl  Mon Aug 10 01:43:37 2015
From: oliver at schinagl.nl (Olliver Schinagl)
Date: Mon, 10 Aug 2015 10:43:37 +0200
Subject: [linux-sunxi] [PATCH] ARM: dts: sunxi: enable otg port on the
 sun7i-a20-olinuxino-lime2
In-Reply-To: <55C7DCA1.2090204@gmail.com>
References: <1439146968-9039-1-git-send-email-oliver@schinagl.nl>
 <1439146968-9039-2-git-send-email-oliver@schinagl.nl>
 <55C7DCA1.2090204@gmail.com>
Message-ID: <55C86439.4000005@schinagl.nl>

Yeah I just noticed as well that for some reason i've sent a merged patch :(

I all ready fixed it locally this morning and will re-send the patches. 
I wonder what I did though ..

Sorry again,

Olliver

On 10-08-15 01:05, Iain Paton wrote:
> NAK. This does much more than enabling the otg port.
>
> Neither wholesale re-writing the regulator node or hooking up the
> dcdc2 regulator to the operating points definition is required in order
> to enable the otg port.
>
> At the very least you need to split your patches and describe them
> properly rather than trying to get additional changes that are likely
> to cause further discussion through unnoticed using a misleading
> subject.
>
> Rgds,
> Iain
>   
> On 09/08/15 20:02, Olliver Schinagl wrote:
>> From: Olliver Schinagl <o.schinagl at ultimaker.com>
>>
>> This patch enables the musb-otg USB controller on the Lime2. The Lime2
>> differs from the Lime1 series in pins used for usb0 power.
>>
>> Tested on a OlinuXino Lime2-4GB.
>>
>> Signed-off-by: Olliver Schinagl <oliver at schinagl.nl>
>> ---
>>   arch/arm/boot/dts/sun7i-a20-olinuxino-lime2.dts | 131 ++++++++++++++----------
>>   1 file changed, 75 insertions(+), 56 deletions(-)
>>
>> diff --git a/arch/arm/boot/dts/sun7i-a20-olinuxino-lime2.dts b/arch/arm/boot/dts/sun7i-a20-olinuxino-lime2.dts
>> index 22cd052..efd9ebb 100644
>> --- a/arch/arm/boot/dts/sun7i-a20-olinuxino-lime2.dts
>> +++ b/arch/arm/boot/dts/sun7i-a20-olinuxino-lime2.dts
>> @@ -71,14 +71,6 @@
>>   			default-state = "on";
>>   		};
>>   	};
>> -
>> -	reg_axp_ipsout: axp_ipsout {
>> -		compatible = "regulator-fixed";
>> -		regulator-name = "axp-ipsout";
>> -		regulator-min-microvolt = <5000000>;
>> -		regulator-max-microvolt = <5000000>;
>> -		regulator-always-on;
>> -	};
>>   };
>>   
>>   &ahci {
>> @@ -86,6 +78,10 @@
>>   	status = "okay";
>>   };
>>   
>> +&cpu0 {
>> +	cpu-supply = <&reg_dcdc2>;
>> +};
>> +
>>   &ehci0 {
>>   	status = "okay";
>>   };
>> @@ -112,57 +108,9 @@
>>   	status = "okay";
>>   
>>   	axp209: pmic at 34 {
>> -		compatible = "x-powers,axp209";
>>   		reg = <0x34>;
>>   		interrupt-parent = <&nmi_intc>;
>>   		interrupts = <0 IRQ_TYPE_LEVEL_LOW>;
>> -
>> -		interrupt-controller;
>> -		#interrupt-cells = <1>;
>> -
>> -		acin-supply = <&reg_axp_ipsout>;
>> -		vin2-supply = <&reg_axp_ipsout>;
>> -		vin3-supply = <&reg_axp_ipsout>;
>> -		ldo24in-supply = <&reg_axp_ipsout>;
>> -		ldo3in-supply = <&reg_axp_ipsout>;
>> -
>> -		regulators {
>> -			vdd_rtc: ldo1 {
>> -				regulator-min-microvolt = <1300000>;
>> -				regulator-max-microvolt = <1300000>;
>> -				regulator-always-on;
>> -			};
>> -
>> -			avcc: ldo2 {
>> -				regulator-min-microvolt = <1800000>;
>> -				regulator-max-microvolt = <3300000>;
>> -				regulator-always-on;
>> -			};
>> -
>> -			vcc_csi0: ldo3 {
>> -				regulator-min-microvolt = <700000>;
>> -				regulator-max-microvolt = <3500000>;
>> -				regulator-always-on;
>> -			};
>> -
>> -			vcc_csi1: ldo4 {
>> -				regulator-min-microvolt = <1250000>;
>> -				regulator-max-microvolt = <3300000>;
>> -				regulator-always-on;
>> -			};
>> -
>> -			vdd_cpu: dcdc2 {
>> -				regulator-min-microvolt = <700000>;
>> -				regulator-max-microvolt = <2275000>;
>> -				regulator-always-on;
>> -			};
>> -
>> -			vdd_int: dcdc3 {
>> -				regulator-min-microvolt = <700000>;
>> -				regulator-max-microvolt = <3500000>;
>> -				regulator-always-on;
>> -			};
>> -		};
>>   	};
>>   };
>>   
>> @@ -196,6 +144,10 @@
>>   	status = "okay";
>>   };
>>   
>> +&otg_sram {
>> +	status = "okay";
>> +};
>> +
>>   &pio {
>>   	ahci_pwr_pin_olinuxinolime: ahci_pwr_pin at 1 {
>>   		allwinner,pins = "PC3";
>> @@ -210,6 +162,27 @@
>>   		allwinner,drive = <SUN4I_PINCTRL_20_MA>;
>>   		allwinner,pull = <SUN4I_PINCTRL_NO_PULL>;
>>   	};
>> +
>> +	usb0_id_detect_pin: usb0_id_detect_pin at 0 {
>> +		allwinner,pins = "PH4";
>> +		allwinner,function = "gpio_in";
>> +		allwinner,drive = <SUN4I_PINCTRL_10_MA>;
>> +		allwinner,pull = <SUN4I_PINCTRL_PULL_UP>;
>> +	};
>> +
>> +	usb0_vbus_detect_pin: usb0_vbus_detect_pin at 0 {
>> +		allwinner,pins = "PH5";
>> +		allwinner,function = "gpio_in";
>> +		allwinner,drive = <SUN4I_PINCTRL_10_MA>;
>> +		allwinner,pull = <SUN4I_PINCTRL_PULL_DOWN>;
>> +	};
>> +
>> +	usb0_vbus_pin_lime2: usb0_vbus_pin at 0 {
>> +		allwinner,pins = "PC17";
>> +		allwinner,function = "gpio_out";
>> +		allwinner,drive = <SUN4I_PINCTRL_10_MA>;
>> +		allwinner,pull = <SUN4I_PINCTRL_NO_PULL>;
>> +	};
>>   };
>>   
>>   &reg_ahci_5v {
>> @@ -218,6 +191,42 @@
>>   	status = "okay";
>>   };
>>   
>> +#include "axp209.dtsi"
>> +
>> +&reg_dcdc2 {
>> +	regulator-always-on;
>> +	regulator-min-microvolt = <1000000>;
>> +	regulator-max-microvolt = <1450000>;
>> +	regulator-name = "vdd-cpu";
>> +};
>> +
>> +&reg_dcdc3 {
>> +	regulator-always-on;
>> +	regulator-min-microvolt = <1000000>;
>> +	regulator-max-microvolt = <1400000>;
>> +	regulator-name = "vdd-int-dll";
>> +};
>> +
>> +&reg_ldo1 {
>> +	regulator-always-on;
>> +	regulator-min-microvolt = <1300000>;
>> +	regulator-max-microvolt = <1300000>;
>> +	regulator-name = "vdd-rtc";
>> +};
>> +
>> +&reg_ldo2 {
>> +	regulator-always-on;
>> +	regulator-min-microvolt = <3000000>;
>> +	regulator-max-microvolt = <3000000>;
>> +	regulator-name = "avcc";
>> +};
>> +
>> +&reg_usb0_vbus {
>> +	pinctrl-0 = <&usb0_vbus_pin_lime2>;
>> +	gpio = <&pio 2 17 GPIO_ACTIVE_HIGH>;
>> +	status = "okay";
>> +};
>> +
>>   &reg_usb1_vbus {
>>   	status = "okay";
>>   };
>> @@ -232,7 +241,17 @@
>>   	status = "okay";
>>   };
>>   
>> +&usb_otg {
>> +	dr_mode = "otg";
>> +	status = "okay";
>> +};
>> +
>>   &usbphy {
>> +	pinctrl-names = "default";
>> +	pinctrl-0 = <&usb0_id_detect_pin>, <&usb0_vbus_detect_pin>;
>> +	usb0_id_det-gpio = <&pio 7 4 GPIO_ACTIVE_HIGH>; /* PH4 */
>> +	usb0_vbus_det-gpio = <&pio 7 5 GPIO_ACTIVE_HIGH>; /* PH5 */
>> +	usb0_vbus-supply = <&reg_usb0_vbus>;
>>   	usb1_vbus-supply = <&reg_usb1_vbus>;
>>   	usb2_vbus-supply = <&reg_usb2_vbus>;
>>   	status = "okay";
>>



From eric.auger at linaro.org  Mon Aug 10 01:44:14 2015
From: eric.auger at linaro.org (Eric Auger)
Date: Mon, 10 Aug 2015 10:44:14 +0200
Subject: [PATCH v4 5/5] KVM: eventfd: add irq bypass consumer management
In-Reply-To: <1438978155.4023.263.camel@redhat.com>
References: <1438622444-25444-1-git-send-email-eric.auger@linaro.org>	
 <1438622444-25444-6-git-send-email-eric.auger@linaro.org>
 <1438978155.4023.263.camel@redhat.com>
Message-ID: <55C8645E.6060505@linaro.org>

Hi Alex,
On 08/07/2015 10:09 PM, Alex Williamson wrote:
> On Mon, 2015-08-03 at 19:20 +0200, Eric Auger wrote:
>> This patch adds the registration/unregistration of an
>> irq_bypass_consumer on irqfd assignment/deassignment.
>>
>> Signed-off-by: Eric Auger <eric.auger at linaro.org>
>> Signed-off-by: Feng Wu <feng.wu at intel.com>
>>
>> ---
>>
>> v2 -> v3 (Feng Wu):
>> - Use kvm_arch_irq_bypass_start
>> - Remove kvm_arch_irq_bypass_update
>> - Add member 'struct irq_bypass_producer *producer' in
>>   'struct kvm_kernel_irqfd', it is needed by posted interrupt.
>> - Remove 'irq_bypass_unregister_consumer' in kvm_irqfd_deassign()
>>
>> v1 -> v2:
>> - populate of kvm and gsi removed
>> - unregister the consumer on irqfd_shutdown
>> ---
>>  include/linux/kvm_irqfd.h |  2 ++
>>  virt/kvm/eventfd.c        | 10 ++++++++++
>>  2 files changed, 12 insertions(+)
>>
>> diff --git a/include/linux/kvm_irqfd.h b/include/linux/kvm_irqfd.h
>> index f926b39..0c1de05 100644
>> --- a/include/linux/kvm_irqfd.h
>> +++ b/include/linux/kvm_irqfd.h
>> @@ -64,6 +64,8 @@ struct kvm_kernel_irqfd {
>>  	struct list_head list;
>>  	poll_table pt;
>>  	struct work_struct shutdown;
>> +	struct irq_bypass_consumer consumer;
>> +	struct irq_bypass_producer *producer;
>>  };
>>  
>>  #endif /* __LINUX_KVM_IRQFD_H */
>> diff --git a/virt/kvm/eventfd.c b/virt/kvm/eventfd.c
>> index 647ffb8..08855de 100644
>> --- a/virt/kvm/eventfd.c
>> +++ b/virt/kvm/eventfd.c
>> @@ -35,6 +35,7 @@
>>  #include <linux/srcu.h>
>>  #include <linux/slab.h>
>>  #include <linux/seqlock.h>
>> +#include <linux/irqbypass.h>
>>  #include <trace/events/kvm.h>
>>  
>>  #include <kvm/iodev.h>
>> @@ -140,6 +141,7 @@ irqfd_shutdown(struct work_struct *work)
>>  	/*
>>  	 * It is now safe to release the object's resources
>>  	 */
>> +	irq_bypass_unregister_consumer(&irqfd->consumer);
>>  	eventfd_ctx_put(irqfd->eventfd);
>>  	kfree(irqfd);
>>  }
>> @@ -380,6 +382,14 @@ kvm_irqfd_assign(struct kvm *kvm, struct kvm_irqfd *args)
>>  	 */
>>  	fdput(f);
>>  
>> +	irqfd->consumer.token = (void *)irqfd->eventfd;
>> +	irqfd->consumer.add_producer = kvm_arch_irq_bypass_add_producer;
>> +	irqfd->consumer.del_producer = kvm_arch_irq_bypass_del_producer;
>> +	irqfd->consumer.stop = kvm_arch_irq_bypass_stop;
>> +	irqfd->consumer.start = kvm_arch_irq_bypass_start;
>> +	ret = irq_bypass_register_consumer(&irqfd->consumer);
>> +	WARN_ON(ret);
> 
> This seems like a lazy way to handle this error.  What is the stack
> trace from this WARN_ON going to tell us that we didn't already know?
> If we get the WARN_ON, it's probably means that an incompatible producer
> registered the token first.  It means we can't do bypass, but it doesn't
> tell us anything about whether bypass is or is not enabled.  Wouldn't a
> pr_info/debug() suffice for that?  Thanks,

Sure I will output some more relevant traces.

Thanks

Eric
> 
> Alex
> 
>> +
>>  	return 0;
>>  
>>  fail:
> 
> 
> 



From jassisinghbrar at gmail.com  Mon Aug 10 01:47:19 2015
From: jassisinghbrar at gmail.com (Jassi Brar)
Date: Mon, 10 Aug 2015 14:17:19 +0530
Subject: [PATCH v2 2/6] mailbox: dt-bindings: Add shared [driver <=>
 device tree] defines
In-Reply-To: <20150810082445.GA3249@x1>
References: <1437990272-23111-1-git-send-email-lee.jones@linaro.org>
 <1437990272-23111-3-git-send-email-lee.jones@linaro.org>
 <CABb+yY2asjH-c+VJXvG+RK0=2p=P4Y21pznNP0riaKMWLxYZog@mail.gmail.com>
 <20150810082445.GA3249@x1>
Message-ID: <CABb+yY3jUKXXJys32bHY1u+dbdsix71Xq_H1Lrkkt27vZzmf7w@mail.gmail.com>

On Mon, Aug 10, 2015 at 1:54 PM, Lee Jones <lee.jones at linaro.org> wrote:
> On Mon, 10 Aug 2015, Jassi Brar wrote:
>> On Mon, Jul 27, 2015 at 3:14 PM, Lee Jones <lee.jones at linaro.org> wrote:
>> > This header is currently only used for defines pertaining to data
>> > direction i.e. Rx, Tx or Loopback.
>> >
>> > Signed-off-by: Lee Jones <lee.jones at linaro.org>
>> > ---
>> >  include/dt-bindings/mailbox/mailbox.h | 14 ++++++++++++++
>> >  1 file changed, 14 insertions(+)
>> >  create mode 100644 include/dt-bindings/mailbox/mailbox.h
>> >
>> > diff --git a/include/dt-bindings/mailbox/mailbox.h b/include/dt-bindings/mailbox/mailbox.h
>> > new file mode 100644
>> > index 0000000..82e929a
>> > --- /dev/null
>> > +++ b/include/dt-bindings/mailbox/mailbox.h
>> > @@ -0,0 +1,14 @@
>> > +/*
>> > + * 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.
>> > + */
>> > +
>> > +#ifndef __MAILBOX_CONTROLLER_DT_BINDINGS_H
>> > +#define __MAILBOX_CONTROLLER_DT_BINDINGS_H
>> > +
>> > +#define MBOX_TX                0x1
>> > +#define MBOX_RX                0x2
>> > +#define MBOX_LOOPBACK  (MBOX_RX | MBOX_TX)
>> > +
>> Not sure I understand 'loopback'.  Does it mean h/w has some
>> 'loopback' mode for testing purposes? Or it simply means the
>> controller can send as well as receive messages?
>
> 'loopback' allows firmware to conduct some early function tests.
> However, channels are simplex, so we provide protection against
> multiple allocation of single channel.  By allocating a LOOPBACK
> channel we over-ride this protection and allow a single channel to be
> allocated twice, once for Rx and the other for Tx.
>
So basically hardware is half-duplex, not simplex. I think maybe you
should simply allow for RX and TX always. It should work. Just
handover any received data before send_data (reflecting the h/w
limitation). That way you don't need any such special flag.


From leo.yan at linaro.org  Mon Aug 10 01:52:44 2015
From: leo.yan at linaro.org (Leo Yan)
Date: Mon, 10 Aug 2015 16:52:44 +0800
Subject: [RFC PATCH 0/3] mailbox: hisilicon: add mailbox driver
In-Reply-To: <CABb+yY1HTGNi4gZABNhXjpA57DPZx-tv=6+m4JLyx4wPHfovyA@mail.gmail.com>
References: <1438564390-28111-1-git-send-email-leo.yan@linaro.org>
 <CABb+yY0-RQ80q92EBsuBoYpjxW5zR=nXr+j3zCXw3wKkCf33OQ@mail.gmail.com>
 <20150805231743.GB6880@leoy-linaro>
 <CABb+yY1HTGNi4gZABNhXjpA57DPZx-tv=6+m4JLyx4wPHfovyA@mail.gmail.com>
Message-ID: <20150810085244.GA13147@leoy-linaro>

Hi Jassi,

On Mon, Aug 10, 2015 at 12:32:05PM +0530, Jassi Brar wrote:
> On Thu, Aug 6, 2015 at 4:47 AM, Leo Yan <leo.yan at linaro.org> wrote:
> > Hi Jassi,
> >
> > Thanks for review.
> >
> > On Wed, Aug 05, 2015 at 04:22:01PM +0530, Jassi Brar wrote:
> >> On Mon, Aug 3, 2015 at 6:43 AM, Leo Yan <leo.yan at linaro.org> wrote:
> >
> > [...]
> >
> >> > For easily extending for Hisilicon series SoCs (SoCs may have difference
> >> > for register's definition with each other), so firstly implement common
> >> > mailbox driver; this common mailbox driver provides three mainly
> >> > functionality:
> >> >
> >> >  - help register channels into framework;
> >> >  - hook low level callback functions for register's operations;
> >> >  - Enhance rx channel's message queue, which is based on the code in
> >> >    drivers/mailbox/omap-mailbox.c.
> >> >
> >> Not cool.
> >>  Please don't reinvent the wheel by having platform specific
> >> implementation of the mailbox api. Which vendor doesn't plan to roll
> >> out new SoCs, and hence variations of mailbox controllers?  The OMAP
> >> stack predates the common api, and was actually supposed to be
> >> converted over eventually. Please implement just the
> >> drivers/mailbox/hi6220-mailbox.c (preferably by the name of the
> >> mailbox controller, if any)
> >
> > Understood. Here i have one question, the rx channel's message queue is
> > looks like a common mechanism and can be added into framework file
> > mailbox.c, then Soc driver file can _ONLY_ focus on register level's
> > operations. If so, the common driver in this patch also is unnecessary.
> >
> Yes, that's what I say, no 'common' driver for a platform.
> 
> > Do you suggest to use upper method to rework patches? Or just think
> > it's okay to implement rx channel's message queue in hi6220-mailbox.c?
> >
> The code in drivers/mailbox/ should only manage the controller
> (registers and interrupts). Everything else (queues, shmem etc) should
> be in platform specific client driver(s).

Thanks for suggestion, will send new version patches for reviewing.

Thanks,
Leo Yan


From linus.walleij at linaro.org  Mon Aug 10 02:01:48 2015
From: linus.walleij at linaro.org (Linus Walleij)
Date: Mon, 10 Aug 2015 11:01:48 +0200
Subject: [PATCH] ARM/EP93xx/timer: Migrate to new 'set-state' interface
In-Reply-To: <744dca162a7626694770a9f51457566a33c3e08f.1438852023.git.viresh.kumar@linaro.org>
References: <744dca162a7626694770a9f51457566a33c3e08f.1438852023.git.viresh.kumar@linaro.org>
Message-ID: <CACRpkdZknzqgH+-F0MZgZywtoOL1hhbg=7w1RSC5aZohXtDB3A@mail.gmail.com>

On Thu, Aug 6, 2015 at 11:11 AM, Viresh Kumar <viresh.kumar at linaro.org> wrote:

> Migrate EP93xx driver to the new 'set-state' interface provided by
> clockevents core, the earlier 'set-mode' interface is marked obsolete
> now.
>
> This also enables us to implement callbacks for new states of clockevent
> devices, for example: ONESHOT_STOPPED.
>
> Signed-off-by: Viresh Kumar <viresh.kumar at linaro.org>
> ---
> Linus,
>
> All other clockevent drivers are migrated to the new interface and yours
> was left as it adapted generic clockevents framework just now.
>
> Probably Olof can apply it directly to ARM SoC tree..

Sure, but does it work right off or does Olof have to
pull a branch from your tree in for it to work? In that
case I suggest you take this in the -rc phase. Anyways:
Acked-by: Linus Walleij <linus.walleij at linaro.org>

Yours,
Linus Walleij


From viresh.kumar at linaro.org  Mon Aug 10 02:03:34 2015
From: viresh.kumar at linaro.org (Viresh Kumar)
Date: Mon, 10 Aug 2015 14:33:34 +0530
Subject: [PATCH] ARM/EP93xx/timer: Migrate to new 'set-state' interface
In-Reply-To: <CACRpkdZknzqgH+-F0MZgZywtoOL1hhbg=7w1RSC5aZohXtDB3A@mail.gmail.com>
References: <744dca162a7626694770a9f51457566a33c3e08f.1438852023.git.viresh.kumar@linaro.org>
 <CACRpkdZknzqgH+-F0MZgZywtoOL1hhbg=7w1RSC5aZohXtDB3A@mail.gmail.com>
Message-ID: <20150810090334.GB5766@linux>

On 10-08-15, 11:01, Linus Walleij wrote:
> Sure, but does it work right off or does Olof have to
> pull a branch from your tree in for it to work? In that
> case I suggest you take this in the -rc phase. Anyways:
> Acked-by: Linus Walleij <linus.walleij at linaro.org>

It should work with latest 4.2 rc..

-- 
viresh


From will.deacon at arm.com  Mon Aug 10 02:08:24 2015
From: will.deacon at arm.com (Will Deacon)
Date: Mon, 10 Aug 2015 10:08:24 +0100
Subject: [PATCH 1/2] ARM: VDSO: fix coarse clock monotonicity regression
In-Reply-To: <1438999403-5770-2-git-send-email-nathan_lynch@mentor.com>
References: <1438999403-5770-1-git-send-email-nathan_lynch@mentor.com>
 <1438999403-5770-2-git-send-email-nathan_lynch@mentor.com>
Message-ID: <20150810090824.GA1604@arm.com>

On Sat, Aug 08, 2015 at 03:03:22AM +0100, Nathan Lynch wrote:
> Since 906c55579a63 ("timekeeping: Copy the shadow-timekeeper over the
> real timekeeper last") it has become possible on ARM to:
> 
> - Obtain a CLOCK_MONOTONIC_COARSE or CLOCK_REALTIME_COARSE timestamp
>   via syscall.
> - Subsequently obtain a timestamp for the same clock ID via VDSO which
>   predates the first timestamp (by one jiffy).
> 
> This is because ARM's update_vsyscall is deriving the coarse time
> using the __current_kernel_time interface, when it should really be
> using the timekeeper object provided to it by the timekeeping core.
> It happened to work before only because __current_kernel_time would
> access the same timekeeper object which had been passed to
> update_vsyscall.  This is no longer the case.
> 
> Signed-off-by: Nathan Lynch <nathan_lynch at mentor.com>
> ---
>  arch/arm/kernel/vdso.c | 7 +++----
>  1 file changed, 3 insertions(+), 4 deletions(-)
> 
> diff --git a/arch/arm/kernel/vdso.c b/arch/arm/kernel/vdso.c
> index efe17dd9b921..c8b243c1aef8 100644
> --- a/arch/arm/kernel/vdso.c
> +++ b/arch/arm/kernel/vdso.c
> @@ -296,7 +296,6 @@ static bool tk_is_cntvct(const struct timekeeper *tk)
>   */
>  void update_vsyscall(struct timekeeper *tk)
>  {
> -	struct timespec xtime_coarse;
>  	struct timespec64 *wtm = &tk->wall_to_monotonic;
>  
>  	if (!cntvct_ok) {
> @@ -308,10 +307,10 @@ void update_vsyscall(struct timekeeper *tk)
>  
>  	vdso_write_begin(vdso_data);
>  
> -	xtime_coarse = __current_kernel_time();
>  	vdso_data->tk_is_cntvct			= tk_is_cntvct(tk);
> -	vdso_data->xtime_coarse_sec		= xtime_coarse.tv_sec;
> -	vdso_data->xtime_coarse_nsec		= xtime_coarse.tv_nsec;
> +	vdso_data->xtime_coarse_sec		= tk->xtime_sec;
> +	vdso_data->xtime_coarse_nsec		= tk->tkr_mono.xtime_nsec >>
> +							tk->tkr_mono.shift;

Do you need a cast to u32 here?

Will


From linus.walleij at linaro.org  Mon Aug 10 02:08:52 2015
From: linus.walleij at linaro.org (Linus Walleij)
Date: Mon, 10 Aug 2015 11:08:52 +0200
Subject: [PATCH 0/4] PL08x DT bindings and LPC18xx DMA support
In-Reply-To: <1436616727-4847-1-git-send-email-manabian@gmail.com>
References: <1436616727-4847-1-git-send-email-manabian@gmail.com>
Message-ID: <CACRpkdZ-Fnh5A-=u92gWEFdfLVmp230OSWV4YsyFexhB34gMRg@mail.gmail.com>

On Sat, Jul 11, 2015 at 2:12 PM, Joachim Eastwood <manabian at gmail.com> wrote:

> Hi Vinod,
>
> This is the non-RFC version of the patch set with only a few changes.
> Hope this can go in for 4.3. Changes to the DT for LPC18xx/43xx will
> go thru arm-soc once this get accepted.

What's happening with this patch set? I was planning to base some
Nomadik development on it, and can't see anything wrong with it.
Reviewed-by: Linus Walleij <linus.walleij at linaro.org> for the parts
I didn't write myself.

Yours,
Linus Walleij


From srinivas.kandagatla at linaro.org  Mon Aug 10 02:17:53 2015
From: srinivas.kandagatla at linaro.org (Srinivas Kandagatla)
Date: Mon, 10 Aug 2015 10:17:53 +0100
Subject: [PATCH v7 3/4] drivers: nvmem: Add Vybrid OCOTP support
In-Reply-To: <3c92671bfca0344e4b43edd2a2405c09bf95f330.1438874125.git.maitysanchayan@gmail.com>
References: <cover.1438874125.git.maitysanchayan@gmail.com>
 <3c92671bfca0344e4b43edd2a2405c09bf95f330.1438874125.git.maitysanchayan@gmail.com>
Message-ID: <55C86C41.9010806@linaro.org>

Hi Sanchayan,


Could you add Greg to the "to list" so that we can request him to pick 
this via his tree.


Few nits, other than that driver looks good.


On 06/08/15 16:27, Sanchayan Maity wrote:
> The patch adds support for the On Chip One Time Programmable Peripheral
> (OCOTP) on the Vybrid platform.
>
> Signed-off-by: Sanchayan Maity <maitysanchayan at gmail.com>
> ---
>   drivers/nvmem/Kconfig       |  10 ++
>   drivers/nvmem/Makefile      |   2 +
>   drivers/nvmem/vf610-ocotp.c | 297 ++++++++++++++++++++++++++++++++++++++++++++
>   3 files changed, 309 insertions(+)
>   create mode 100644 drivers/nvmem/vf610-ocotp.c
>
> diff --git a/drivers/nvmem/Kconfig b/drivers/nvmem/Kconfig
> index 0b33014..bfd0c02 100644
> --- a/drivers/nvmem/Kconfig
> +++ b/drivers/nvmem/Kconfig
> @@ -47,4 +47,14 @@ config NVMEM_IMX_OCOTP
>   	  This driver can also be built as a module. If so, the module
>   	  will be called nvmem-imx-ocotp.
>
> +config NVMEM_VF610_OCOTP
> +	tristate "VF610_SoCs OCOTP support"
> +	depends on SOC_VF610
You could also add COMPILE_TEST which will ensure that its compile checked.
> +	help
> +	  This is a driver for the 'OCOTP' peripheral available on Vybrid
> +	  devices like VF5xx and VF6xx.
> +
> +	  This driver can also be built as a module. If so, the module will
> +	  be called nvmem-vf610-ocotp.
> +
>   endif
> diff --git a/drivers/nvmem/Makefile b/drivers/nvmem/Makefile
> index b512d77..8a1eea8 100644
> --- a/drivers/nvmem/Makefile
> +++ b/drivers/nvmem/Makefile
> @@ -12,3 +12,5 @@ obj-$(CONFIG_NVMEM_SUNXI_SID)	+= nvmem_sunxi_sid.o
>   nvmem_sunxi_sid-y		:= sunxi_sid.o
>   obj-$(CONFIG_NVMEM_IMX_OCOTP)	+= nvmem-imx-ocotp.o
>   nvmem-imx-ocotp-y		:= imx-ocotp.o
> +obj-$(CONFIG_NVMEM_VF610_OCOTP)	+= nvmem-vf610-ocotp.o
> +nvmem-vf610-ocotp-y		:= vf610-ocotp.o
> diff --git a/drivers/nvmem/vf610-ocotp.c b/drivers/nvmem/vf610-ocotp.c
> new file mode 100644
> index 0000000..25ee701
> --- /dev/null
> +++ b/drivers/nvmem/vf610-ocotp.c
> @@ -0,0 +1,297 @@
> +/*
> + * Copyright (C) 2015 Toradex AG.
> + *
> + * Author: Sanchayan Maity <sanchayan.maity at toradex.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 and
> + * only 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/clk.h>
> +#include <linux/delay.h>
> +#include <linux/device.h>
> +#include <linux/io.h>
> +#include <linux/module.h>
> +#include <linux/nvmem-provider.h>
> +#include <linux/of.h>
> +#include <linux/platform_device.h>
> +#include <linux/regmap.h>
> +#include <linux/slab.h>
> +
> +/* OCOTP Register Offsets */
> +#define OCOTP_CTRL_REG				0x00
> +#define OCOTP_CTRL_SET				0x04
> +#define OCOTP_CTRL_CLR				0x08
> +#define OCOTP_TIMING				0x10
> +#define OCOTP_DATA				0x20
> +#define OCOTP_READ_CTRL_REG			0x30
> +#define OCOTP_READ_FUSE_DATA			0x40
> +
> +/* OCOTP Register bits and masks */
> +#define OCOTP_CTRL_WR_UNLOCK			16
> +#define OCOTP_CTRL_WR_UNLOCK_KEY		0x3E77
> +#define OCOTP_CTRL_WR_UNLOCK_MASK		0xFFFF0000
> +#define OCOTP_CTRL_ADDR				0
> +#define OCOTP_CTRL_ADDR_MASK			0x7F
> +#define OCOTP_CTRL_RELOAD_SHADOWS		(0x1 << 10)
> +#define OCOTP_CTRL_ERROR			(0x1 << 9)
> +#define OCOTP_CTRL_BUSY				(0x1 << 8)

we can use BIT and GENMASK variants here for most of the defines.
> +
> +#define OCOTP_TIMING_STROBE_READ		16
> +#define OCOTP_TIMING_STROBE_READ_MASK		0x003F0000
> +#define OCOTP_TIMING_RELAX			12
> +#define OCOTP_TIMING_RELAX_MASK			0x0000F000
> +#define OCOTP_TIMING_STROBE_PROG		0
> +#define OCOTP_TIMING_STROBE_PROG_MASK		0x00000FFF
> +
> +#define OCOTP_READ_CTRL_READ_FUSE		0x1
> +
> +#define VF610_OCOTP_TIMEOUT			100000
> +
> +#define BF(value, field)		(((value) << field) & field##_MASK)
> +
> +#define DEF_RELAX				20
> +
> +static const int base_to_fuse_addr_mappings[][2] = {
> +	{0x400, 0x00},
> +	{0x410, 0x01},
> +	{0x420, 0x02},
> +	{0x450, 0x05},
> +	{0x4F0, 0x0F},
> +	{0x600, 0x20},
> +	{0x610, 0x21},
> +	{0x620, 0x22},
> +	{0x630, 0x23},
> +	{0x640, 0x24},
> +	{0x650, 0x25},
> +	{0x660, 0x26},
> +	{0x670, 0x27},
> +	{0x6F0, 0x2F},
> +	{0x880, 0x38},
> +	{0x890, 0x39},
> +	{0x8A0, 0x3A},
> +	{0x8B0, 0x3B},
> +	{0x8C0, 0x3C},
> +	{0x8D0, 0x3D},
> +	{0x8E0, 0x3E},
> +	{0x8F0, 0x3F},
> +	{0xC80, 0x78},
> +	{0xC90, 0x79},
> +	{0xCA0, 0x7A},
> +	{0xCB0, 0x7B},
> +	{0xCC0, 0x7C},
> +	{0xCD0, 0x7D},
> +	{0xCE0, 0x7E},
> +	{0xCF0, 0x7F},
> +};
> +
> +struct vf610_ocotp {
> +	void __iomem *base;
> +	struct clk *clk;
> +	struct device *dev;
> +	struct nvmem_device *nvmem;
> +	int timing;
> +};
> +
> +static int vf610_ocotp_wait_busy(void __iomem *base)
> +{
> +	int timeout = VF610_OCOTP_TIMEOUT;
> +
> +	while ((readl(base) & OCOTP_CTRL_BUSY) && --timeout)
> +		udelay(10);
> +
> +	if (!timeout) {
> +		writel(OCOTP_CTRL_ERROR, base + OCOTP_CTRL_CLR);
> +		return -ETIMEDOUT;
> +	}
> +
> +	udelay(10);
> +
> +	return 0;
> +}
> +
> +static int vf610_ocotp_calculate_timing(struct vf610_ocotp *ocotp_dev)
> +{
> +	u32 clk_rate;
> +	u32 relax, strobe_read, strobe_prog;
> +	u32 timing;
> +
> +	clk_rate = clk_get_rate(ocotp_dev->clk);
> +
> +	/* Refer section OTP read/write timing parameters in TRM */
> +	relax = clk_rate / (1000000000 / DEF_RELAX) - 1;
> +	strobe_prog = clk_rate / (1000000000 / 10000) + 2 * (DEF_RELAX + 1) - 1;
> +	strobe_read = clk_rate / (1000000000 / 40) + 2 * (DEF_RELAX + 1) - 1;
> +
> +	timing = BF(relax, OCOTP_TIMING_RELAX);
> +	timing |= BF(strobe_read, OCOTP_TIMING_STROBE_READ);
> +	timing |= BF(strobe_prog, OCOTP_TIMING_STROBE_PROG);
> +
> +	return timing;
> +}
> +
> +static int vf610_get_fuse_address(int base_addr_offset)
> +{
> +	int i;
> +
> +	for (i = 0; i < ARRAY_SIZE(base_to_fuse_addr_mappings); i++) {
> +		if (base_to_fuse_addr_mappings[i][0] == base_addr_offset)
> +			return base_to_fuse_addr_mappings[i][1];
> +	}
> +
> +	return -EINVAL;
> +}
> +
> +static int vf610_ocotp_write(void *context, const void *data, size_t count)
> +{
> +	return 0;
> +}
> +
> +static int vf610_ocotp_read(void *context,
> +					const void *off, size_t reg_size,
> +					void *val, size_t val_size)
Align it to the braces.
> +{
> +	struct vf610_ocotp *ocotp = context;
> +	unsigned int offset = *(u32 *)off;
> +	u32 reg, *buf = val;
> +	int fuse_addr;
> +	int ret;
> +
> +	while (val_size > 0) {
> +		fuse_addr = vf610_get_fuse_address(offset);
> +		if (fuse_addr > 0) {
> +			writel(ocotp->timing, ocotp->base + OCOTP_TIMING);
> +			ret = vf610_ocotp_wait_busy(ocotp->base + OCOTP_CTRL_REG);
> +			if (ret)
> +				return ret;
> +
> +			reg = readl(ocotp->base + OCOTP_CTRL_REG);
> +			reg &= ~OCOTP_CTRL_ADDR_MASK;
> +			reg &= ~OCOTP_CTRL_WR_UNLOCK_MASK;
> +			reg |= BF(fuse_addr, OCOTP_CTRL_ADDR);
> +			writel(reg, ocotp->base + OCOTP_CTRL_REG);
> +
> +			writel(OCOTP_READ_CTRL_READ_FUSE,
> +				ocotp->base + OCOTP_READ_CTRL_REG);
> +			ret = vf610_ocotp_wait_busy(ocotp->base + OCOTP_CTRL_REG);
> +			if (ret)
> +				return ret;
> +
> +			if (readl(ocotp->base) & OCOTP_CTRL_ERROR) {
> +				dev_dbg(ocotp->dev, "Error reading from fuse address %x\n",
> +					fuse_addr);
> +				writel(OCOTP_CTRL_ERROR, ocotp->base + OCOTP_CTRL_CLR);
> +			}
> +
> +			/*
> +			 * In case of error, we do not abort and expect to read
> +			 * 0xBADABADA as mentioned by the TRM. We just read this
> +			 * value and return.
> +			 */
> +			*buf = readl(ocotp->base + OCOTP_READ_FUSE_DATA);
> +		} else {
> +			*buf = 0;
> +		}
> +
> +		buf++;
> +		val_size--;
> +		offset += reg_size;
> +	}
> +
> +	return 0;
> +}
> +
> +static struct regmap_bus vf610_ocotp_bus = {
> +	.read = vf610_ocotp_read,
> +	.write = vf610_ocotp_write,
> +	.reg_format_endian_default = REGMAP_ENDIAN_NATIVE,
> +	.val_format_endian_default = REGMAP_ENDIAN_NATIVE,
> +};
> +
> +static struct regmap_config ocotp_regmap_config = {
> +	.reg_bits = 32,
> +	.val_bits = 32,
> +	.reg_stride = 4,
> +	.max_register = 0xCF0,
Cant we get this info from the resource_size() ?
> +};
> +
> +static struct nvmem_config ocotp_config = {
> +	.name = "ocotp",
> +	.owner = THIS_MODULE,
> +};
> +
> +static const struct of_device_id ocotp_of_match[] = {
> +	{ .compatible = "fsl,vf610-ocotp", },
> +	{/* sentinel */},
> +};
> +MODULE_DEVICE_TABLE(of, ocotp_of_match);
> +
> +static int vf610_ocotp_remove(struct platform_device *pdev)
> +{
> +	struct vf610_ocotp *ocotp_dev = platform_get_drvdata(pdev);
> +
> +	return nvmem_unregister(ocotp_dev->nvmem);
> +}
> +
> +static int vf610_ocotp_probe(struct platform_device *pdev)
> +{
> +	struct device *dev = &pdev->dev;
> +	struct resource *res;
> +	struct regmap *regmap;
> +	struct vf610_ocotp *ocotp_dev;
> +
> +	ocotp_dev = devm_kzalloc(&pdev->dev,
> +			sizeof(struct vf610_ocotp), GFP_KERNEL);
> +	if (!ocotp_dev)
> +		return -ENOMEM;
> +
> +	res = platform_get_resource(pdev, IORESOURCE_MEM, 0);
> +	ocotp_dev->base = devm_ioremap_resource(dev, res);
> +	if (IS_ERR(ocotp_dev->base))
> +		return PTR_ERR(ocotp_dev->base);
> +
> +	ocotp_dev->clk = devm_clk_get(dev, "ocotp");
> +	if (IS_ERR(ocotp_dev->clk)) {
> +		dev_err(dev, "failed getting clock, err = %ld\n",
> +			PTR_ERR(ocotp_dev->clk));
> +		return PTR_ERR(ocotp_dev->clk);
> +	}
> +
> +	regmap = devm_regmap_init(dev,
> +		&vf610_ocotp_bus, ocotp_dev, &ocotp_regmap_config);
> +	if (IS_ERR(regmap)) {
> +		dev_err(dev, "regmap init failed\n");
> +		return PTR_ERR(regmap);
> +	}
> +	ocotp_config.dev = dev;
> +
> +	ocotp_dev->nvmem = nvmem_register(&ocotp_config);
> +	if (IS_ERR(ocotp_dev->nvmem))
> +		return PTR_ERR(ocotp_dev->nvmem);
> +
> +	ocotp_dev->dev = dev;
> +	platform_set_drvdata(pdev, ocotp_dev);
> +
> +	ocotp_dev->timing = vf610_ocotp_calculate_timing(ocotp_dev);
> +
> +	return 0;
> +}
> +
> +static struct platform_driver vf610_ocotp_driver = {
> +	.probe = vf610_ocotp_probe,
> +	.remove = vf610_ocotp_remove,
> +	.driver = {
> +		.name = "vf610-ocotp",
> +		.of_match_table = ocotp_of_match,
> +	},
> +};
> +module_platform_driver(vf610_ocotp_driver);
> +MODULE_AUTHOR("Sanchayan Maity <sanchayan.maity at toradex.com>");
> +MODULE_DESCRIPTION("Vybrid OCOTP driver");
> +MODULE_LICENSE("GPL v2");
>


From srinivas.kandagatla at linaro.org  Mon Aug 10 02:18:01 2015
From: srinivas.kandagatla at linaro.org (Srinivas Kandagatla)
Date: Mon, 10 Aug 2015 10:18:01 +0100
Subject: [PATCH v7 4/4] nvmem: Add DT binding documentation for Vybrid
 OCOTP driver
In-Reply-To: <3713643bb44c39c2126edca2916e1c1aa43eabf8.1438874125.git.maitysanchayan@gmail.com>
References: <cover.1438874125.git.maitysanchayan@gmail.com>
 <3713643bb44c39c2126edca2916e1c1aa43eabf8.1438874125.git.maitysanchayan@gmail.com>
Message-ID: <55C86C49.6080708@linaro.org>



On 06/08/15 16:27, Sanchayan Maity wrote:
> Add the devicetree bindings for the Freescale Vybrid On-Chip
> OTP driver.
>
> Signed-off-by: Sanchayan Maity <maitysanchayan at gmail.com>
> ---
>   .../devicetree/bindings/nvmem/vf610-ocotp.txt        | 20 ++++++++++++++++++++
>   1 file changed, 20 insertions(+)
>   create mode 100644 Documentation/devicetree/bindings/nvmem/vf610-ocotp.txt
>
> diff --git a/Documentation/devicetree/bindings/nvmem/vf610-ocotp.txt b/Documentation/devicetree/bindings/nvmem/vf610-ocotp.txt
> new file mode 100644
> index 0000000..5556810
> --- /dev/null
> +++ b/Documentation/devicetree/bindings/nvmem/vf610-ocotp.txt
> @@ -0,0 +1,20 @@
> +On-Chip OTP Memory for Freescale Vybrid
> +
> +Required Properties:
> +  compatible:
> +  - "fsl,vf610-ocotp" for VF5xx/VF6xx
> +  #address-cells : Should be 1
> +  #size-cells : Should be 1
> +  reg : Address and length of OTP controller registers

Is there a reason to not add clocks property in to the bindings?

> +
> +Example for Vybrid VF5xx/VF6xx:
> +
> +	ocotp: ocotp at 400a5000 {
> +		compatible = "fsl,vf610-ocotp";
> +		#address-cells = <1>;
> +		#size-cells = <1>;
> +		reg = <0x400a5000 0xD00>;
> +		clocks = <&clks VF610_CLK_OCOTP>;
> +		clock-names = "ocotp";
> +	};
> +
>


From linus.walleij at linaro.org  Mon Aug 10 02:20:00 2015
From: linus.walleij at linaro.org (Linus Walleij)
Date: Mon, 10 Aug 2015 11:20:00 +0200
Subject: [PATCH 3/9] gpio: Allow hogged gpios to be requested
In-Reply-To: <20150728091753.GJ28535@localhost>
References: <1437125570-28623-1-git-send-email-mpa@pengutronix.de>
 <1437125570-28623-4-git-send-email-mpa@pengutronix.de>
 <20150717202702.GK7013@pengutronix.de>
 <20150719140142.GV26287@pengutronix.de>
 <20150728091753.GJ28535@localhost>
Message-ID: <CACRpkdbHwCNttDCEUyYq_5REh1PDuR__XDeLD0mR6NqfO6h_HA@mail.gmail.com>

On Tue, Jul 28, 2015 at 11:17 AM, Johan Hovold <johan at kernel.org> wrote:
> On Sun, Jul 19, 2015 at 04:01:42PM +0200, Markus Pargmann wrote:

>> > I don't like this patch. IMHO hogging is a "use" of a GPIO that should
>> > prevent it being requested.
>>
>> I disagree with you here. The original patch stated in its description
>> that it was designed to initialize GPIOs. In my understanding this does
>> not necessarily mean that a hogged GPIO has to be blocked forever.
>
> IIRC, this use case was discussed but was rejected by Linus when hogs
> were added:
>
>         https://lkml.kernel.org/r/CACRpkdZcNcPBYQM438CZJx1gYst9BFBSTj-3Qv2aPGF9pdWa5g at mail.gmail.com
>
> Linus?

Yeah that is true. But maybe I softened up a bit.

Basically I want to avoid having two very similar mechanisms.

But that is maybe more of a question of how the code is
arranged and named than what it is called. It would be nicer
if this was referring to initial values rather than hogging,
the mechanism inside the kernel could be the same.

But then there is the path where something that is initially
a hog is turned into a userspace GPIO. Then it is essentially
not a hog anymore, so this property is not static.

Yours,
Linus Walleij


From maitysanchayan at gmail.com  Mon Aug 10 02:17:25 2015
From: maitysanchayan at gmail.com (maitysanchayan at gmail.com)
Date: Mon, 10 Aug 2015 14:47:25 +0530
Subject: [PATCH v7 4/4] nvmem: Add DT binding documentation for Vybrid
 OCOTP driver
In-Reply-To: <55C86C49.6080708@linaro.org>
References: <cover.1438874125.git.maitysanchayan@gmail.com>
 <3713643bb44c39c2126edca2916e1c1aa43eabf8.1438874125.git.maitysanchayan@gmail.com>
 <55C86C49.6080708@linaro.org>
Message-ID: <20150810091725.GB2273@Sanchayan-Arch.toradex.int>

Hello,

On 15-08-10 10:18:01, Srinivas Kandagatla wrote:
> 
> 
> On 06/08/15 16:27, Sanchayan Maity wrote:
> > Add the devicetree bindings for the Freescale Vybrid On-Chip
> > OTP driver.
> >
> > Signed-off-by: Sanchayan Maity <maitysanchayan at gmail.com>
> > ---
> >   .../devicetree/bindings/nvmem/vf610-ocotp.txt        | 20 ++++++++++++++++++++
> >   1 file changed, 20 insertions(+)
> >   create mode 100644 Documentation/devicetree/bindings/nvmem/vf610-ocotp.txt
> >
> > diff --git a/Documentation/devicetree/bindings/nvmem/vf610-ocotp.txt b/Documentation/devicetree/bindings/nvmem/vf610-ocotp.txt
> > new file mode 100644
> > index 0000000..5556810
> > --- /dev/null
> > +++ b/Documentation/devicetree/bindings/nvmem/vf610-ocotp.txt
> > @@ -0,0 +1,20 @@
> > +On-Chip OTP Memory for Freescale Vybrid
> > +
> > +Required Properties:
> > +  compatible:
> > +  - "fsl,vf610-ocotp" for VF5xx/VF6xx
> > +  #address-cells : Should be 1
> > +  #size-cells : Should be 1
> > +  reg : Address and length of OTP controller registers
> 
> Is there a reason to not add clocks property in to the bindings?

An error on my part. Will fix with the next revision.

- Sanchayan.

> 
> > +
> > +Example for Vybrid VF5xx/VF6xx:
> > +
> > +	ocotp: ocotp at 400a5000 {
> > +		compatible = "fsl,vf610-ocotp";
> > +		#address-cells = <1>;
> > +		#size-cells = <1>;
> > +		reg = <0x400a5000 0xD00>;
> > +		clocks = <&clks VF610_CLK_OCOTP>;
> > +		clock-names = "ocotp";
> > +	};
> > +
> >


From will.deacon at arm.com  Mon Aug 10 02:22:53 2015
From: will.deacon at arm.com (Will Deacon)
Date: Mon, 10 Aug 2015 10:22:53 +0100
Subject: [PATCH 2/2] arm64: VDSO: fix coarse clock monotonicity regression
In-Reply-To: <1438999403-5770-3-git-send-email-nathan_lynch@mentor.com>
References: <1438999403-5770-1-git-send-email-nathan_lynch@mentor.com>
 <1438999403-5770-3-git-send-email-nathan_lynch@mentor.com>
Message-ID: <20150810092252.GB1604@arm.com>

Hi Nathan,

On Sat, Aug 08, 2015 at 03:03:23AM +0100, Nathan Lynch wrote:
> Since 906c55579a63 ("timekeeping: Copy the shadow-timekeeper over the
> real timekeeper last") it has become possible on arm64 to:
> 
> - Obtain a CLOCK_MONOTONIC_COARSE or CLOCK_REALTIME_COARSE timestamp
>   via syscall.
> - Subsequently obtain a timestamp for the same clock ID via VDSO which
>   predates the first timestamp (by one jiffy).
> 
> This is because arm64's update_vsyscall is deriving the coarse time
> using the __current_kernel_time interface, when it should really be
> using the timekeeper object provided to it by the timekeeping core.
> It happened to work before only because __current_kernel_time would
> access the same timekeeper object which had been passed to
> update_vsyscall.  This is no longer the case.
> 
> Signed-off-by: Nathan Lynch <nathan_lynch at mentor.com>
> ---
>  arch/arm64/kernel/vdso.c | 7 +++----
>  1 file changed, 3 insertions(+), 4 deletions(-)
> 
> diff --git a/arch/arm64/kernel/vdso.c b/arch/arm64/kernel/vdso.c
> index ec37ab3f524f..97bc68f4c689 100644
> --- a/arch/arm64/kernel/vdso.c
> +++ b/arch/arm64/kernel/vdso.c
> @@ -199,16 +199,15 @@ int arch_setup_additional_pages(struct linux_binprm *bprm,
>   */
>  void update_vsyscall(struct timekeeper *tk)
>  {
> -	struct timespec xtime_coarse;
>  	u32 use_syscall = strcmp(tk->tkr_mono.clock->name, "arch_sys_counter");
>  
>  	++vdso_data->tb_seq_count;
>  	smp_wmb();
>  
> -	xtime_coarse = __current_kernel_time();
>  	vdso_data->use_syscall			= use_syscall;
> -	vdso_data->xtime_coarse_sec		= xtime_coarse.tv_sec;
> -	vdso_data->xtime_coarse_nsec		= xtime_coarse.tv_nsec;
> +	vdso_data->xtime_coarse_sec		= tk->xtime_sec;
> +	vdso_data->xtime_coarse_nsec		= tk->tkr_mono.xtime_nsec >>
> +							tk->tkr_mono.shift;
>  	vdso_data->wtm_clock_sec		= tk->wall_to_monotonic.tv_sec;
>  	vdso_data->wtm_clock_nsec		= tk->wall_to_monotonic.tv_nsec;

Looks good,

  Acked-by: Will Deacon <will.deacon at arm.com>

There's probably still time for Catalin to pick this up for 4.2.

Will


From maitysanchayan at gmail.com  Mon Aug 10 02:20:05 2015
From: maitysanchayan at gmail.com (maitysanchayan at gmail.com)
Date: Mon, 10 Aug 2015 14:50:05 +0530
Subject: [PATCH v7 3/4] drivers: nvmem: Add Vybrid OCOTP support
In-Reply-To: <55C86C41.9010806@linaro.org>
References: <cover.1438874125.git.maitysanchayan@gmail.com>
 <3c92671bfca0344e4b43edd2a2405c09bf95f330.1438874125.git.maitysanchayan@gmail.com>
 <55C86C41.9010806@linaro.org>
Message-ID: <20150810092005.GC2273@Sanchayan-Arch.toradex.int>

Hello,

On 15-08-10 10:17:53, Srinivas Kandagatla wrote:
> Hi Sanchayan,
> 
> 
> Could you add Greg to the "to list" so that we can request him to pick 
> this via his tree.

Will add Greg in cc with the next revision.

> 
> 
> Few nits, other than that driver looks good.
> 
> 
> On 06/08/15 16:27, Sanchayan Maity wrote:
> > The patch adds support for the On Chip One Time Programmable Peripheral
> > (OCOTP) on the Vybrid platform.
> >
> > Signed-off-by: Sanchayan Maity <maitysanchayan at gmail.com>
> > ---
> >   drivers/nvmem/Kconfig       |  10 ++
> >   drivers/nvmem/Makefile      |   2 +
> >   drivers/nvmem/vf610-ocotp.c | 297 ++++++++++++++++++++++++++++++++++++++++++++
> >   3 files changed, 309 insertions(+)
> >   create mode 100644 drivers/nvmem/vf610-ocotp.c
> >
> > diff --git a/drivers/nvmem/Kconfig b/drivers/nvmem/Kconfig
> > index 0b33014..bfd0c02 100644
> > --- a/drivers/nvmem/Kconfig
> > +++ b/drivers/nvmem/Kconfig
> > @@ -47,4 +47,14 @@ config NVMEM_IMX_OCOTP
> >   	  This driver can also be built as a module. If so, the module
> >   	  will be called nvmem-imx-ocotp.
> >
> > +config NVMEM_VF610_OCOTP
> > +	tristate "VF610_SoCs OCOTP support"
> > +	depends on SOC_VF610
> You could also add COMPILE_TEST which will ensure that its compile checked.

Ok.

> > +	help
> > +	  This is a driver for the 'OCOTP' peripheral available on Vybrid
> > +	  devices like VF5xx and VF6xx.
> > +
> > +	  This driver can also be built as a module. If so, the module will
> > +	  be called nvmem-vf610-ocotp.
> > +
> >   endif
> > diff --git a/drivers/nvmem/Makefile b/drivers/nvmem/Makefile
> > index b512d77..8a1eea8 100644
> > --- a/drivers/nvmem/Makefile
> > +++ b/drivers/nvmem/Makefile
> > @@ -12,3 +12,5 @@ obj-$(CONFIG_NVMEM_SUNXI_SID)	+= nvmem_sunxi_sid.o
> >   nvmem_sunxi_sid-y		:= sunxi_sid.o
> >   obj-$(CONFIG_NVMEM_IMX_OCOTP)	+= nvmem-imx-ocotp.o
> >   nvmem-imx-ocotp-y		:= imx-ocotp.o
> > +obj-$(CONFIG_NVMEM_VF610_OCOTP)	+= nvmem-vf610-ocotp.o
> > +nvmem-vf610-ocotp-y		:= vf610-ocotp.o
> > diff --git a/drivers/nvmem/vf610-ocotp.c b/drivers/nvmem/vf610-ocotp.c
> > new file mode 100644
> > index 0000000..25ee701
> > --- /dev/null
> > +++ b/drivers/nvmem/vf610-ocotp.c
> > @@ -0,0 +1,297 @@
> > +/*
> > + * Copyright (C) 2015 Toradex AG.
> > + *
> > + * Author: Sanchayan Maity <sanchayan.maity at toradex.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 and
> > + * only 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/clk.h>
> > +#include <linux/delay.h>
> > +#include <linux/device.h>
> > +#include <linux/io.h>
> > +#include <linux/module.h>
> > +#include <linux/nvmem-provider.h>
> > +#include <linux/of.h>
> > +#include <linux/platform_device.h>
> > +#include <linux/regmap.h>
> > +#include <linux/slab.h>
> > +
> > +/* OCOTP Register Offsets */
> > +#define OCOTP_CTRL_REG				0x00
> > +#define OCOTP_CTRL_SET				0x04
> > +#define OCOTP_CTRL_CLR				0x08
> > +#define OCOTP_TIMING				0x10
> > +#define OCOTP_DATA				0x20
> > +#define OCOTP_READ_CTRL_REG			0x30
> > +#define OCOTP_READ_FUSE_DATA			0x40
> > +
> > +/* OCOTP Register bits and masks */
> > +#define OCOTP_CTRL_WR_UNLOCK			16
> > +#define OCOTP_CTRL_WR_UNLOCK_KEY		0x3E77
> > +#define OCOTP_CTRL_WR_UNLOCK_MASK		0xFFFF0000
> > +#define OCOTP_CTRL_ADDR				0
> > +#define OCOTP_CTRL_ADDR_MASK			0x7F
> > +#define OCOTP_CTRL_RELOAD_SHADOWS		(0x1 << 10)
> > +#define OCOTP_CTRL_ERROR			(0x1 << 9)
> > +#define OCOTP_CTRL_BUSY				(0x1 << 8)
> 
> we can use BIT and GENMASK variants here for most of the defines.

Ok.

> > +
> > +#define OCOTP_TIMING_STROBE_READ		16
> > +#define OCOTP_TIMING_STROBE_READ_MASK		0x003F0000
> > +#define OCOTP_TIMING_RELAX			12
> > +#define OCOTP_TIMING_RELAX_MASK			0x0000F000
> > +#define OCOTP_TIMING_STROBE_PROG		0
> > +#define OCOTP_TIMING_STROBE_PROG_MASK		0x00000FFF
> > +
> > +#define OCOTP_READ_CTRL_READ_FUSE		0x1
> > +
> > +#define VF610_OCOTP_TIMEOUT			100000
> > +
> > +#define BF(value, field)		(((value) << field) & field##_MASK)
> > +
> > +#define DEF_RELAX				20
> > +
> > +static const int base_to_fuse_addr_mappings[][2] = {
> > +	{0x400, 0x00},
> > +	{0x410, 0x01},
> > +	{0x420, 0x02},
> > +	{0x450, 0x05},
> > +	{0x4F0, 0x0F},
> > +	{0x600, 0x20},
> > +	{0x610, 0x21},
> > +	{0x620, 0x22},
> > +	{0x630, 0x23},
> > +	{0x640, 0x24},
> > +	{0x650, 0x25},
> > +	{0x660, 0x26},
> > +	{0x670, 0x27},
> > +	{0x6F0, 0x2F},
> > +	{0x880, 0x38},
> > +	{0x890, 0x39},
> > +	{0x8A0, 0x3A},
> > +	{0x8B0, 0x3B},
> > +	{0x8C0, 0x3C},
> > +	{0x8D0, 0x3D},
> > +	{0x8E0, 0x3E},
> > +	{0x8F0, 0x3F},
> > +	{0xC80, 0x78},
> > +	{0xC90, 0x79},
> > +	{0xCA0, 0x7A},
> > +	{0xCB0, 0x7B},
> > +	{0xCC0, 0x7C},
> > +	{0xCD0, 0x7D},
> > +	{0xCE0, 0x7E},
> > +	{0xCF0, 0x7F},
> > +};
> > +
> > +struct vf610_ocotp {
> > +	void __iomem *base;
> > +	struct clk *clk;
> > +	struct device *dev;
> > +	struct nvmem_device *nvmem;
> > +	int timing;
> > +};
> > +
> > +static int vf610_ocotp_wait_busy(void __iomem *base)
> > +{
> > +	int timeout = VF610_OCOTP_TIMEOUT;
> > +
> > +	while ((readl(base) & OCOTP_CTRL_BUSY) && --timeout)
> > +		udelay(10);
> > +
> > +	if (!timeout) {
> > +		writel(OCOTP_CTRL_ERROR, base + OCOTP_CTRL_CLR);
> > +		return -ETIMEDOUT;
> > +	}
> > +
> > +	udelay(10);
> > +
> > +	return 0;
> > +}
> > +
> > +static int vf610_ocotp_calculate_timing(struct vf610_ocotp *ocotp_dev)
> > +{
> > +	u32 clk_rate;
> > +	u32 relax, strobe_read, strobe_prog;
> > +	u32 timing;
> > +
> > +	clk_rate = clk_get_rate(ocotp_dev->clk);
> > +
> > +	/* Refer section OTP read/write timing parameters in TRM */
> > +	relax = clk_rate / (1000000000 / DEF_RELAX) - 1;
> > +	strobe_prog = clk_rate / (1000000000 / 10000) + 2 * (DEF_RELAX + 1) - 1;
> > +	strobe_read = clk_rate / (1000000000 / 40) + 2 * (DEF_RELAX + 1) - 1;
> > +
> > +	timing = BF(relax, OCOTP_TIMING_RELAX);
> > +	timing |= BF(strobe_read, OCOTP_TIMING_STROBE_READ);
> > +	timing |= BF(strobe_prog, OCOTP_TIMING_STROBE_PROG);
> > +
> > +	return timing;
> > +}
> > +
> > +static int vf610_get_fuse_address(int base_addr_offset)
> > +{
> > +	int i;
> > +
> > +	for (i = 0; i < ARRAY_SIZE(base_to_fuse_addr_mappings); i++) {
> > +		if (base_to_fuse_addr_mappings[i][0] == base_addr_offset)
> > +			return base_to_fuse_addr_mappings[i][1];
> > +	}
> > +
> > +	return -EINVAL;
> > +}
> > +
> > +static int vf610_ocotp_write(void *context, const void *data, size_t count)
> > +{
> > +	return 0;
> > +}
> > +
> > +static int vf610_ocotp_read(void *context,
> > +					const void *off, size_t reg_size,
> > +					void *val, size_t val_size)
> Align it to the braces.

Ok.

> > +{
> > +	struct vf610_ocotp *ocotp = context;
> > +	unsigned int offset = *(u32 *)off;
> > +	u32 reg, *buf = val;
> > +	int fuse_addr;
> > +	int ret;
> > +
> > +	while (val_size > 0) {
> > +		fuse_addr = vf610_get_fuse_address(offset);
> > +		if (fuse_addr > 0) {
> > +			writel(ocotp->timing, ocotp->base + OCOTP_TIMING);
> > +			ret = vf610_ocotp_wait_busy(ocotp->base + OCOTP_CTRL_REG);
> > +			if (ret)
> > +				return ret;
> > +
> > +			reg = readl(ocotp->base + OCOTP_CTRL_REG);
> > +			reg &= ~OCOTP_CTRL_ADDR_MASK;
> > +			reg &= ~OCOTP_CTRL_WR_UNLOCK_MASK;
> > +			reg |= BF(fuse_addr, OCOTP_CTRL_ADDR);
> > +			writel(reg, ocotp->base + OCOTP_CTRL_REG);
> > +
> > +			writel(OCOTP_READ_CTRL_READ_FUSE,
> > +				ocotp->base + OCOTP_READ_CTRL_REG);
> > +			ret = vf610_ocotp_wait_busy(ocotp->base + OCOTP_CTRL_REG);
> > +			if (ret)
> > +				return ret;
> > +
> > +			if (readl(ocotp->base) & OCOTP_CTRL_ERROR) {
> > +				dev_dbg(ocotp->dev, "Error reading from fuse address %x\n",
> > +					fuse_addr);
> > +				writel(OCOTP_CTRL_ERROR, ocotp->base + OCOTP_CTRL_CLR);
> > +			}
> > +
> > +			/*
> > +			 * In case of error, we do not abort and expect to read
> > +			 * 0xBADABADA as mentioned by the TRM. We just read this
> > +			 * value and return.
> > +			 */
> > +			*buf = readl(ocotp->base + OCOTP_READ_FUSE_DATA);
> > +		} else {
> > +			*buf = 0;
> > +		}
> > +
> > +		buf++;
> > +		val_size--;
> > +		offset += reg_size;
> > +	}
> > +
> > +	return 0;
> > +}
> > +
> > +static struct regmap_bus vf610_ocotp_bus = {
> > +	.read = vf610_ocotp_read,
> > +	.write = vf610_ocotp_write,
> > +	.reg_format_endian_default = REGMAP_ENDIAN_NATIVE,
> > +	.val_format_endian_default = REGMAP_ENDIAN_NATIVE,
> > +};
> > +
> > +static struct regmap_config ocotp_regmap_config = {
> > +	.reg_bits = 32,
> > +	.val_bits = 32,
> > +	.reg_stride = 4,
> > +	.max_register = 0xCF0,
> Cant we get this info from the resource_size() ?

Yes we can. I will change to that.

Thanks for the review.

- Sanchayan.

> > +};
> > +
> > +static struct nvmem_config ocotp_config = {
> > +	.name = "ocotp",
> > +	.owner = THIS_MODULE,
> > +};
> > +
> > +static const struct of_device_id ocotp_of_match[] = {
> > +	{ .compatible = "fsl,vf610-ocotp", },
> > +	{/* sentinel */},
> > +};
> > +MODULE_DEVICE_TABLE(of, ocotp_of_match);
> > +
> > +static int vf610_ocotp_remove(struct platform_device *pdev)
> > +{
> > +	struct vf610_ocotp *ocotp_dev = platform_get_drvdata(pdev);
> > +
> > +	return nvmem_unregister(ocotp_dev->nvmem);
> > +}
> > +
> > +static int vf610_ocotp_probe(struct platform_device *pdev)
> > +{
> > +	struct device *dev = &pdev->dev;
> > +	struct resource *res;
> > +	struct regmap *regmap;
> > +	struct vf610_ocotp *ocotp_dev;
> > +
> > +	ocotp_dev = devm_kzalloc(&pdev->dev,
> > +			sizeof(struct vf610_ocotp), GFP_KERNEL);
> > +	if (!ocotp_dev)
> > +		return -ENOMEM;
> > +
> > +	res = platform_get_resource(pdev, IORESOURCE_MEM, 0);
> > +	ocotp_dev->base = devm_ioremap_resource(dev, res);
> > +	if (IS_ERR(ocotp_dev->base))
> > +		return PTR_ERR(ocotp_dev->base);
> > +
> > +	ocotp_dev->clk = devm_clk_get(dev, "ocotp");
> > +	if (IS_ERR(ocotp_dev->clk)) {
> > +		dev_err(dev, "failed getting clock, err = %ld\n",
> > +			PTR_ERR(ocotp_dev->clk));
> > +		return PTR_ERR(ocotp_dev->clk);
> > +	}
> > +
> > +	regmap = devm_regmap_init(dev,
> > +		&vf610_ocotp_bus, ocotp_dev, &ocotp_regmap_config);
> > +	if (IS_ERR(regmap)) {
> > +		dev_err(dev, "regmap init failed\n");
> > +		return PTR_ERR(regmap);
> > +	}
> > +	ocotp_config.dev = dev;
> > +
> > +	ocotp_dev->nvmem = nvmem_register(&ocotp_config);
> > +	if (IS_ERR(ocotp_dev->nvmem))
> > +		return PTR_ERR(ocotp_dev->nvmem);
> > +
> > +	ocotp_dev->dev = dev;
> > +	platform_set_drvdata(pdev, ocotp_dev);
> > +
> > +	ocotp_dev->timing = vf610_ocotp_calculate_timing(ocotp_dev);
> > +
> > +	return 0;
> > +}
> > +
> > +static struct platform_driver vf610_ocotp_driver = {
> > +	.probe = vf610_ocotp_probe,
> > +	.remove = vf610_ocotp_remove,
> > +	.driver = {
> > +		.name = "vf610-ocotp",
> > +		.of_match_table = ocotp_of_match,
> > +	},
> > +};
> > +module_platform_driver(vf610_ocotp_driver);
> > +MODULE_AUTHOR("Sanchayan Maity <sanchayan.maity at toradex.com>");
> > +MODULE_DESCRIPTION("Vybrid OCOTP driver");
> > +MODULE_LICENSE("GPL v2");
> >


From linus.walleij at linaro.org  Mon Aug 10 02:26:49 2015
From: linus.walleij at linaro.org (Linus Walleij)
Date: Mon, 10 Aug 2015 11:26:49 +0200
Subject: [PATCH v2] gpio: Allow hogged gpios to be requested
In-Reply-To: <1438680424-698-1-git-send-email-mpa@pengutronix.de>
References: <1438680424-698-1-git-send-email-mpa@pengutronix.de>
Message-ID: <CACRpkdZAjWf3Echvz6Z2hTOF8Bqs=OqLKUTYc04r9vzFo727jg@mail.gmail.com>

On Tue, Aug 4, 2015 at 11:27 AM, Markus Pargmann <mpa at pengutronix.de> wrote:

> It can be useful to claim hogged gpios later, for example from
> userspace. This allows to set defaults for GPIOs using the hogging
> mechanism and override the setup later from userspace or a kernel driver.
>
> This patch adds a check for hogged gpios to allow requesting them. If
> the gpio is not hogged but marked as requested, it still fails with
> -EBUSY.
>
> Signed-off-by: Markus Pargmann <mpa at pengutronix.de>

To me it feels like a new DT property "gpio-inital-value" or so
need to be defined in addition to the hogging bindings, and that
one just sets the GPIO up without setting the FLAG_IS_HOGGED.

The mechanism needs to be available to non-DT as well
of course, but it could be a first usecase.

So instead of:

line_b {
           gpio-initval;
           gpios = <6 0>;
           output-low;
};

Note: no line-name. And it shouldn't be allowed: we don't
know who will use this in the end.

Yours,
Linus Walleij


From linus.walleij at linaro.org  Mon Aug 10 02:29:58 2015
From: linus.walleij at linaro.org (Linus Walleij)
Date: Mon, 10 Aug 2015 11:29:58 +0200
Subject: [PATCH 1/6] gpiolib-of: Rename gpio_hog functions to be generic
In-Reply-To: <1438680203-13432-2-git-send-email-mpa@pengutronix.de>
References: <1438680203-13432-1-git-send-email-mpa@pengutronix.de>
 <1438680203-13432-2-git-send-email-mpa@pengutronix.de>
Message-ID: <CACRpkdYpeoo2scKzNuSYbWfWLTBodXJEX3KyRzoRQPuoaeqzKw@mail.gmail.com>

On Tue, Aug 4, 2015 at 11:23 AM, Markus Pargmann <mpa at pengutronix.de> wrote:

> The gpio hogging functions are currently only used for gpio-hogging. But
> these functions are widely generic ones which parse gpio device nodes in
> the DT.
>
> Signed-off-by: Markus Pargmann <mpa at pengutronix.de>
(...)
>  /**
> - * of_get_gpio_hog() - Get a GPIO hog descriptor, names and flags for GPIO API
> + * of_parse_gpio() - Get a GPIO hog descriptor, names and flags for GPIO API

It's not a good name, too generic. It could easily be assued this is
for something
wider.

of_parse_own_gpio() or something, indicating that this pertains to the
chip itself and not to outside users, would be better.

Yours,
Linus Walleij


From tomi.valkeinen at ti.com  Mon Aug 10 02:33:34 2015
From: tomi.valkeinen at ti.com (Tomi Valkeinen)
Date: Mon, 10 Aug 2015 12:33:34 +0300
Subject: [PATCH] ARM/fb: ep93xx: switch framebuffer to use modedb only
In-Reply-To: <1437744688-29915-1-git-send-email-linus.walleij@linaro.org>
References: <1437744688-29915-1-git-send-email-linus.walleij@linaro.org>
Message-ID: <55C86FEE.6090502@ti.com>



On 24/07/15 16:31, Linus Walleij wrote:
> All the EP93xx boards exclusively use modedb to look up video
> modes from the command line. Root out the parametrization of
> custom video modes from the platform data and board files
> and simplify the driver.
> 
> Cc: Jean-Christophe Plagniol-Villard <plagnioj at jcrosoft.com>
> Cc: Tomi Valkeinen <tomi.valkeinen at ti.com>
> Signed-off-by: Linus Walleij <linus.walleij at linaro.org>
> ---
> J-C/Tomi: please ACK this if you're OK with it so I can take
> it through the ARM SoC tree.

Acked-by: Tomi Valkeinen <tomi.valkeinen at ti.com>

 Tomi

-------------- next part --------------
A non-text attachment was scrubbed...
Name: signature.asc
Type: application/pgp-signature
Size: 819 bytes
Desc: OpenPGP digital signature
URL: <http://lists.infradead.org/pipermail/linux-arm-kernel/attachments/20150810/340ad3f3/attachment.sig>

From linus.walleij at linaro.org  Mon Aug 10 02:37:06 2015
From: linus.walleij at linaro.org (Linus Walleij)
Date: Mon, 10 Aug 2015 11:37:06 +0200
Subject: [PATCH 2/6] gpio: Introduce gpio descriptor 'name'
In-Reply-To: <1438680203-13432-3-git-send-email-mpa@pengutronix.de>
References: <1438680203-13432-1-git-send-email-mpa@pengutronix.de>
 <1438680203-13432-3-git-send-email-mpa@pengutronix.de>
Message-ID: <CACRpkdYv=-fCj+ts9tTmFsovPN0RPYkOdYh9Dj6oFDJiRV=RUA@mail.gmail.com>

On Tue, Aug 4, 2015 at 11:23 AM, Markus Pargmann <mpa at pengutronix.de> wrote:

> The latest gpio hogging mechanism assigns each gpio a 'line-name' in the
> devicetree. The 'name' field is different from the 'label' field.
> 'label' is only used for requested GPIOs to describe its current use by
> driver or userspace.
>
> The 'name' field describes the GPIO itself, not the use. This is most
> likely identical to the label in the schematic on the GPIO line and
> should help to find this particular GPIO.
>
> This patch adds a helper function to find gpio descriptors by name
> instead of gpio number.
>
> Signed-off-by: Markus Pargmann <mpa at pengutronix.de>

Oh I realized there is a big problem with this.

struct gpio_chip already contains this:

        const char              *const *names;

Now it seems like names can be stored in two places:
in an array in the gpio_chip and in a name tag in struct
gpio_desc.

So how do we handle this?

I guess we need to keep just *one* of them, so maybe remove
the names array from the struct gpio_chip and add a helper function
that sets the names on the descs for the lines like:

int gpiochip_set_names(struct gpio_chip *gc, const char * const names);

And then refactor all code and chips that use the old names
array to use this instead. I don't think they are too many, really.

(Maybe I got it all wrong, hammer me down, it is monday.)

Yours,
Linus Walleij


From linus.walleij at linaro.org  Mon Aug 10 02:38:34 2015
From: linus.walleij at linaro.org (Linus Walleij)
Date: Mon, 10 Aug 2015 11:38:34 +0200
Subject: [PATCH 3/6] gpiolib-of: Reuse 'line-name' from DT as gpio
 descriptor name
In-Reply-To: <1438680203-13432-4-git-send-email-mpa@pengutronix.de>
References: <1438680203-13432-1-git-send-email-mpa@pengutronix.de>
 <1438680203-13432-4-git-send-email-mpa@pengutronix.de>
Message-ID: <CACRpkdY+jOxZY4_uvhQ75nKkoA2hJ7k=cv2OZwv4D86Jn4QnGw@mail.gmail.com>

On Tue, Aug 4, 2015 at 11:23 AM, Markus Pargmann <mpa at pengutronix.de> wrote:

> The DT describes gpios with subnodes. These subnodes can contain a
> property 'line-name'. This information can be useful in other areas
> where we want to identify a GPIO by its name.
>
> This patch stores the line-name in the gpio descriptor.
>
> Signed-off-by: Markus Pargmann <mpa at pengutronix.de>

This patch looks correct given the context works as intended.

Yours,
Linus Walleij


From will.deacon at arm.com  Mon Aug 10 02:40:08 2015
From: will.deacon at arm.com (Will Deacon)
Date: Mon, 10 Aug 2015 10:40:08 +0100
Subject: [PATCH 2/3] [v4] ARM64: TTY: hvc_dcc: Add support for ARM64 dcc
In-Reply-To: <1438992995-22610-2-git-send-email-timur@codeaurora.org>
References: <1438992995-22610-1-git-send-email-timur@codeaurora.org>
 <1438992995-22610-2-git-send-email-timur@codeaurora.org>
Message-ID: <20150810094008.GD1604@arm.com>

On Sat, Aug 08, 2015 at 01:16:34AM +0100, Timur Tabi wrote:
> From: Abhimanyu Kapur <abhimany at codeaurora.org>
> 
> Add support for debug communications channel based
> hvc console for arm64 cpus.
> 
> Signed-off-by: Abhimanyu Kapur <abhimany at codeaurora.org>
> Signed-off-by: Timur Tabi <timur at codeaurora.org>
> ---
>  arch/arm64/include/asm/dcc.h | 52 ++++++++++++++++++++++++++++++++++++++++++++
>  drivers/tty/hvc/Kconfig      |  2 +-
>  2 files changed, 53 insertions(+), 1 deletion(-)
>  create mode 100644 arch/arm64/include/asm/dcc.h
> 
> diff --git a/arch/arm64/include/asm/dcc.h b/arch/arm64/include/asm/dcc.h
> new file mode 100644
> index 0000000..fcb8d7d
> --- /dev/null
> +++ b/arch/arm64/include/asm/dcc.h
> @@ -0,0 +1,52 @@
> +/* Copyright (c) 2014-2015 The Linux Foundation. All rights reserved.
> + *
> + * This program is free software; you can redistribute it and/or modify
> + * it under the terms of the GNU General Public License version 2 and
> + * only 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.
> + *
> + * A call to __dcc_getchar() or __dcc_putchar() is typically followed by
> + * a call to __dcc_getstatus().  We want to make sure that the CPU does
> + * not speculative read the DCC status before executing the read or write
> + * instruction.  That's what the ISBs are for.
> + *
> + * The 'volatile' ensures that the compiler does not cache the status bits,
> + * and instead reads the DCC register every time.
> + */
> +#ifndef __ASM_DCC_H
> +#define __ASM_DCC_H
> +
> +#include <asm/barrier.h>
> +
> +static inline u32 __dcc_getstatus(void)
> +{
> +	u32 ret;
> +
> +	asm volatile("mrs %0, mdccsr_el0" : "=r" (ret));
> +
> +	return ret;
> +}
> +
> +static inline char __dcc_getchar(void)
> +{
> +	char c;
> +
> +	asm volatile("mrs %0, dbgdtrrx_el0" : "=r" (c));
> +	isb();
> +
> +	return c;
> +}
> +
> +static inline void __dcc_putchar(char c)
> +{
> +	asm volatile("msr dbgdtrtx_el0, %0"
> +			: /* No output register */
> +			: "r" (c));
> +	isb();

I think we should be masking out the upper bits of c before the msr
(the compiler probably expects a uxtb).

Other than that, this looks ok.

Will


From linus.walleij at linaro.org  Mon Aug 10 02:40:27 2015
From: linus.walleij at linaro.org (Linus Walleij)
Date: Mon, 10 Aug 2015 11:40:27 +0200
Subject: [PATCH 4/6] gpiolib-sysfs: Add gpio name parsing for sysfs export
In-Reply-To: <1438680203-13432-5-git-send-email-mpa@pengutronix.de>
References: <1438680203-13432-1-git-send-email-mpa@pengutronix.de>
 <1438680203-13432-5-git-send-email-mpa@pengutronix.de>
Message-ID: <CACRpkdaomx0JHnO2+sg-UZ+gZbX8fTs3c26Wcq=-GP4zFp-TGQ@mail.gmail.com>

On Tue, Aug 4, 2015 at 11:23 AM, Markus Pargmann <mpa at pengutronix.de> wrote:

> Signed-off-by: Markus Pargmann <mpa at pengutronix.de>

Needs a bigger commit message, but looks correct in this context.

Yours,
Linus Walleij


From will.deacon at arm.com  Mon Aug 10 02:47:56 2015
From: will.deacon at arm.com (Will Deacon)
Date: Mon, 10 Aug 2015 10:47:56 +0100
Subject: [PATCH 3/3] [v2] hvc_dcc: disable user-space access to DCC
In-Reply-To: <1438992995-22610-3-git-send-email-timur@codeaurora.org>
References: <1438992995-22610-1-git-send-email-timur@codeaurora.org>
 <1438992995-22610-3-git-send-email-timur@codeaurora.org>
Message-ID: <20150810094755.GE1604@arm.com>

On Sat, Aug 08, 2015 at 01:16:35AM +0100, Timur Tabi wrote:
> If the DCC driver loads, then disable user-space access to the DCC so that
> we don't have two entities trying to access the DCC at the same time.
> 
> Signed-off-by: Timur Tabi <timur at codeaurora.org>
> ---
>  arch/arm/include/asm/dcc.h   | 15 +++++++++++++++
>  arch/arm64/include/asm/dcc.h | 11 +++++++++++
>  drivers/tty/hvc/hvc_dcc.c    |  2 ++
>  3 files changed, 28 insertions(+)
> 
> diff --git a/arch/arm/include/asm/dcc.h b/arch/arm/include/asm/dcc.h
> index b74899d..c50056b 100644
> --- a/arch/arm/include/asm/dcc.h
> +++ b/arch/arm/include/asm/dcc.h
> @@ -9,8 +9,11 @@
>   * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
>   * GNU General Public License for more details.
>   */
> +#ifndef __ASM_DCC_H
> +#define __ASM_DCC_H
>  
>  #include <asm/barrier.h>
> +#include <asm/hardware/cp14.h>
>  
>  static inline u32 __dcc_getstatus(void)
>  {
> @@ -39,3 +42,15 @@ static inline void __dcc_putchar(char c)
>  		: "r" (c));
>  	isb();
>  }
> +
> +static inline void __dcc_initialize(void)
> +{
> +	u32 val;
> +
> +	/* Disable user-space access to DCC */
> +	val = MRC14(0, c0, c1, 0);
> +	val |= 1 << 12; /* DSCR[Comms] */
> +	MCR14(val, 0, c0, c1, 0);
> +}
> +
> +#endif
> diff --git a/arch/arm64/include/asm/dcc.h b/arch/arm64/include/asm/dcc.h
> index fcb8d7d..a6496f2 100644
> --- a/arch/arm64/include/asm/dcc.h
> +++ b/arch/arm64/include/asm/dcc.h
> @@ -49,4 +49,15 @@ static inline void __dcc_putchar(char c)
>  	isb();
>  }
>  
> +static inline void __dcc_initialize(void)
> +{
> +	u32 val;
> +
> +	/* Disable user-space access to DCC */
> +	asm volatile ("mrs %0, mdscr_el1\n"
> +		"	orr %0, %0, #4096\n" /* Set the TDCC bit */

So this is the same as your "1 << 12" for arch/arm/. Shouldn't we
#define that someplace common?

> +		"	msr mdscr_el1, %0\n"
> +		: "=r" (val));
> +}
> +
>  #endif
> diff --git a/drivers/tty/hvc/hvc_dcc.c b/drivers/tty/hvc/hvc_dcc.c
> index 47654ea..e260acb 100644
> --- a/drivers/tty/hvc/hvc_dcc.c
> +++ b/drivers/tty/hvc/hvc_dcc.c
> @@ -76,6 +76,8 @@ static int __init hvc_dcc_console_init(void)
>  	if (!hvc_dcc_check())
>  		return -ENODEV;
>  
> +	__dcc_initialize();
> +
>  	/* Returns -1 if error */
>  	ret = hvc_instantiate(0, 0, &hvc_dcc_get_put_ops);

Can this driver be built as a module and unloaded? If so, should we
re-enable userspace access when the kernel doesn't need it anymore?

Finally, have you checked the behaviour on CPU hotplug? It looks like we
zero mdscr_el1 in the cold boot path. The alternative is to set this bit
there and never allow userspace access. Do you know of any compelling
use-cases where userspace accesses the DCC directly?

Will


From will.deacon at arm.com  Mon Aug 10 02:48:59 2015
From: will.deacon at arm.com (Will Deacon)
Date: Mon, 10 Aug 2015 10:48:59 +0100
Subject: [PATCH 1/3] [v2] hvc_dcc: don't ignore errors during
 initialization
In-Reply-To: <1438992995-22610-1-git-send-email-timur@codeaurora.org>
References: <1438992995-22610-1-git-send-email-timur@codeaurora.org>
Message-ID: <20150810094859.GF1604@arm.com>

On Sat, Aug 08, 2015 at 01:16:33AM +0100, Timur Tabi wrote:
> hvc_instantiate() and hvc_alloc() return errors if they fail, so don't
> ignore them.
> 
> Signed-off-by: Timur Tabi <timur at codeaurora.org>
> ---
>  drivers/tty/hvc/hvc_dcc.c | 17 +++++++++++++----
>  1 file changed, 13 insertions(+), 4 deletions(-)
> 
> diff --git a/drivers/tty/hvc/hvc_dcc.c b/drivers/tty/hvc/hvc_dcc.c
> index 809920d..47654ea 100644
> --- a/drivers/tty/hvc/hvc_dcc.c
> +++ b/drivers/tty/hvc/hvc_dcc.c
> @@ -70,20 +70,29 @@ static const struct hv_ops hvc_dcc_get_put_ops = {
>  
>  static int __init hvc_dcc_console_init(void)
>  {
> +	int ret;
> +
> +	/* This always runs on boot core */

Does this really "always run on the boot core"? I couldn't find anything
suggesting that console_init is limited in that regard.

Will


From linus.walleij at linaro.org  Mon Aug 10 02:50:16 2015
From: linus.walleij at linaro.org (Linus Walleij)
Date: Mon, 10 Aug 2015 11:50:16 +0200
Subject: [PATCH 5/6] gpiolib-sysfs: Show gpio-name in
 /sys/class/gpio/gpio*/name
In-Reply-To: <1438680203-13432-6-git-send-email-mpa@pengutronix.de>
References: <1438680203-13432-1-git-send-email-mpa@pengutronix.de>
 <1438680203-13432-6-git-send-email-mpa@pengutronix.de>
Message-ID: <CACRpkdZCSwWUuhbe2+nrEPTRnqNGvJrrbZLDwy8fkHeEJDujUg@mail.gmail.com>

On Tue, Aug 4, 2015 at 11:23 AM, Markus Pargmann <mpa at pengutronix.de> wrote:

> This patch adds a sysfs attribute 'name' to gpios that were exported. It
> exposes the newly added name property of gpio descriptors.
>
> Signed-off-by: Markus Pargmann <mpa at pengutronix.de>

This needs to also patch Documentation/ABI/testing/sysfs-gpio
if we should go with it. It says this:

    /sys/class/gpio
        /export ... asks the kernel to export a GPIO to userspace
        /unexport ... to return a GPIO to the kernel
        /gpioN ... for each exported GPIO #N
            /value ... always readable, writes fail for input GPIOs
            /direction ... r/w as: in, out (default low); write: high, low
            /edge ... r/w as: none, falling, rising, both

Anyways I don't know if this is right, and that ABI doc is also lying.

Look at this in gpiolib-sysfs.c:

        if (chip->names && chip->names[offset])
                ioname = chip->names[offset];

        dev = device_create_with_groups(&gpio_class, chip->dev,
                                        MKDEV(0, 0), data, gpio_groups,
                                        ioname ? ioname : "gpio%u",
                                        desc_to_gpio(desc));

I.e. what the ABI doc say about the dirs being named "gpioN" is
a plain lie, it can have a descriptive name as its directory  name
under /sys/class/gpio/foo-line or so.

Since this already exist and is a flat namespace ... we should
use that.

However it has the implication like I said before that two names
cannot be the same. I think Johan's comment that they could
be non-unique did not take into account the fact that two chips
could use the same .names array (and that would already fail,
by the way) so the .names in the struct gpio_chip *MUST* be
unique as compared to all other names.

We *could* deprecate the old line naming mechanism (that create
dirs named after the pin), and from here on only use gpioN and
"name" in a separate file like this patch does. However that is
not really OK either: we want to move away from the GPIO numbers
and to descriptors and descriptive names, so I currently feel
we should name the directories after the line instead, and
require them to be unique.

I'll have to patch this document now anyways because it is
lying about the ABI :(

Yours,
Linus Walleij


From jaz at semihalf.com  Mon Aug 10 02:51:54 2015
From: jaz at semihalf.com (Grzegorz Jaszczyk)
Date: Mon, 10 Aug 2015 11:51:54 +0200
Subject: [PATCH] ARM: mvebu: update mvebu_v7_defconfig for Armada 38x USB3.0
Message-ID: <1439200314-26850-1-git-send-email-jaz@semihalf.com>

	This patch enables the fixed voltage regulator and the gpio PCA953X
	drivers in mvebu_v7_defconfig, as they are used for enabling the USB3.0
	phy on some of the Armada's 38x boards.

Signed-off-by: Grzegorz Jaszczyk <jaz at semihalf.com>
Cc: <stable at vger.kernel.org>
---
 arch/arm/configs/mvebu_v7_defconfig | 3 +++
 1 file changed, 3 insertions(+)

diff --git a/arch/arm/configs/mvebu_v7_defconfig b/arch/arm/configs/mvebu_v7_defconfig
index cacc9f4..1b8ecf4 100644
--- a/arch/arm/configs/mvebu_v7_defconfig
+++ b/arch/arm/configs/mvebu_v7_defconfig
@@ -83,11 +83,14 @@ CONFIG_I2C_MV64XXX=y
 CONFIG_SPI=y
 CONFIG_SPI_ORION=y
 CONFIG_GPIO_SYSFS=y
+CONFIG_GPIO_PCA953X=y
 CONFIG_SENSORS_GPIO_FAN=y
 CONFIG_THERMAL=y
 CONFIG_ARMADA_THERMAL=y
 CONFIG_WATCHDOG=y
 CONFIG_ORION_WATCHDOG=y
+CONFIG_REGULATOR=y
+CONFIG_REGULATOR_FIXED_VOLTAGE=y
 CONFIG_SOUND=y
 CONFIG_SND=y
 CONFIG_SND_SOC=y
-- 
1.8.3.1



From jamesjj.liao at mediatek.com  Mon Aug 10 02:50:21 2015
From: jamesjj.liao at mediatek.com (James Liao)
Date: Mon, 10 Aug 2015 17:50:21 +0800
Subject: [PATCH v7 2/9] clk: mediatek: Remove unused code from MT8173.
In-Reply-To: <1439200228-318-1-git-send-email-jamesjj.liao@mediatek.com>
References: <1439200228-318-1-git-send-email-jamesjj.liao@mediatek.com>
Message-ID: <1439200228-318-3-git-send-email-jamesjj.liao@mediatek.com>

Remove unused header files from MT8173, and remove unused
keywords from function declaration.

Signed-off-by: James Liao <jamesjj.liao at mediatek.com>
---
 drivers/clk/mediatek/clk-mt8173.c | 2 --
 drivers/clk/mediatek/clk-mtk.h    | 4 ++--
 2 files changed, 2 insertions(+), 4 deletions(-)

diff --git a/drivers/clk/mediatek/clk-mt8173.c b/drivers/clk/mediatek/clk-mt8173.c
index 80871e2..13aa432 100644
--- a/drivers/clk/mediatek/clk-mt8173.c
+++ b/drivers/clk/mediatek/clk-mt8173.c
@@ -14,8 +14,6 @@
 
 #include <linux/of.h>
 #include <linux/of_address.h>
-#include <linux/slab.h>
-#include <linux/mfd/syscon.h>
 
 #include "clk-mtk.h"
 #include "clk-gate.h"
diff --git a/drivers/clk/mediatek/clk-mtk.h b/drivers/clk/mediatek/clk-mtk.h
index 9dda9d8..740fe5e 100644
--- a/drivers/clk/mediatek/clk-mtk.h
+++ b/drivers/clk/mediatek/clk-mtk.h
@@ -41,7 +41,7 @@ struct mtk_fixed_factor {
 		.div = _div,				\
 	}
 
-extern void mtk_clk_register_factors(const struct mtk_fixed_factor *clks,
+void mtk_clk_register_factors(const struct mtk_fixed_factor *clks,
 		int num, struct clk_onecell_data *clk_data);
 
 struct mtk_composite {
@@ -152,7 +152,7 @@ struct mtk_pll_data {
 	int pcw_shift;
 };
 
-void __init mtk_clk_register_plls(struct device_node *node,
+void mtk_clk_register_plls(struct device_node *node,
 		const struct mtk_pll_data *plls, int num_plls,
 		struct clk_onecell_data *clk_data);
 
-- 
1.8.1.1.dirty



From jamesjj.liao at mediatek.com  Mon Aug 10 02:50:19 2015
From: jamesjj.liao at mediatek.com (James Liao)
Date: Mon, 10 Aug 2015 17:50:19 +0800
Subject: [PATCH v7 0/9] Fixes and new clocks support for Mediatek MT8173
Message-ID: <1439200228-318-1-git-send-email-jamesjj.liao@mediatek.com>

This patchset is based on 4.2-rc2 and [1], and contains minor fixes and
subsystem clocks support for Mediatek MT8173.

The previous reviews can be found in [2].

changes since v6:
- Use DUMMY_RATE (0) instead of typical rate for clocks that we don't care
  and not controlled in CCF.

changes since v5:
- Rebase to 4.2-rc2.
- Patch "Fix enabling of critical clocks" had been included in 4.2-rc2,
  so it need not be included in this patchset.

changes since v4:
- Add a separated patch to remove unused dpi_ck.
- Add separated patches to fix clk/mediatek in release 4.2-rc1.
- Add __init* for initialization data and functions.
- Rename dummy_clk with oscillator in DT.
- Remove mtk_clk_register_apmixed_ex(), call mtk_clk_register_ref2usb_tx()
  directly to register USB clock.

changes since v3:
- Remove clk_null dependency from root clocks.
- Use fixed-rate clocks with typical rate to replace clk_null.
- Separate ref2usb_tx implementation to clk-apmixed.c
- Use clock-controller as the name of clock providers.

changes since v2:
- Rebase to 4.2-rc1.
- Add device tree nodes for subsystem clocks.
- Fine tune comments of patches.
- Add __init, __initconst and const to init data and functions.
- Removed unused code from init functions of subsystem clocks.

changes since v1:
- Add CA7PLL and CA15PLL as critical clocks.
- Use the same register descriptor for imgsys, vensys and vencltsys.
- Generalize apmixedsys special clocks registration.

[1] https://patchwork.kernel.org/patch/6446341/
[2] https://lkml.org/lkml/2015/8/4/111

James Liao (9):
  clk: mediatek: Removed unused dpi_ck clock from MT8173
  clk: mediatek: Remove unused code from MT8173.
  clk: mediatek: Add __initdata and __init for data and functions
  clk: mediatek: Add fixed clocks support for Mediatek SoC.
  clk: mediatek: Fix rate and dependency of MT8173 clocks
  dt-bindings: ARM: Mediatek: Document devicetree bindings for clock
    controllers
  clk: mediatek: Add subsystem clocks of MT8173
  clk: mediatek: Add USB clock support in MT8173 APMIXEDSYS
  arm64: dts: mt8173: Add subsystem clock controller device nodes

 .../bindings/arm/mediatek/mediatek,imgsys.txt      |  22 ++
 .../bindings/arm/mediatek/mediatek,mmsys.txt       |  22 ++
 .../bindings/arm/mediatek/mediatek,vdecsys.txt     |  22 ++
 .../bindings/arm/mediatek/mediatek,vencltsys.txt   |  22 ++
 .../bindings/arm/mediatek/mediatek,vencsys.txt     |  22 ++
 arch/arm64/boot/dts/mediatek/mt8173.dtsi           |  37 +++
 drivers/clk/mediatek/Makefile                      |   2 +-
 drivers/clk/mediatek/clk-apmixed.c                 | 107 +++++++
 drivers/clk/mediatek/clk-gate.c                    |   2 +-
 drivers/clk/mediatek/clk-mt8173.c                  | 342 ++++++++++++++++++++-
 drivers/clk/mediatek/clk-mtk.c                     |  36 ++-
 drivers/clk/mediatek/clk-mtk.h                     |  24 +-
 drivers/clk/mediatek/clk-pll.c                     |   7 +-
 include/dt-bindings/clock/mt8173-clk.h             | 101 +++++-
 14 files changed, 735 insertions(+), 33 deletions(-)
 create mode 100644 Documentation/devicetree/bindings/arm/mediatek/mediatek,imgsys.txt
 create mode 100644 Documentation/devicetree/bindings/arm/mediatek/mediatek,mmsys.txt
 create mode 100644 Documentation/devicetree/bindings/arm/mediatek/mediatek,vdecsys.txt
 create mode 100644 Documentation/devicetree/bindings/arm/mediatek/mediatek,vencltsys.txt
 create mode 100644 Documentation/devicetree/bindings/arm/mediatek/mediatek,vencsys.txt
 create mode 100644 drivers/clk/mediatek/clk-apmixed.c

--
1.8.1.1.dirty



From jamesjj.liao at mediatek.com  Mon Aug 10 02:50:28 2015
From: jamesjj.liao at mediatek.com (James Liao)
Date: Mon, 10 Aug 2015 17:50:28 +0800
Subject: [PATCH v7 9/9] arm64: dts: mt8173: Add subsystem clock controller
 device nodes
In-Reply-To: <1439200228-318-1-git-send-email-jamesjj.liao@mediatek.com>
References: <1439200228-318-1-git-send-email-jamesjj.liao@mediatek.com>
Message-ID: <1439200228-318-10-git-send-email-jamesjj.liao@mediatek.com>

This patch adds device nodes providing subsystem clocks on MT8173,
includes mmsys, imgsys, vdecsys, vencsys and vencltsys.

Signed-off-by: James Liao <jamesjj.liao at mediatek.com>
---
 arch/arm64/boot/dts/mediatek/mt8173.dtsi | 37 ++++++++++++++++++++++++++++++++
 1 file changed, 37 insertions(+)

diff --git a/arch/arm64/boot/dts/mediatek/mt8173.dtsi b/arch/arm64/boot/dts/mediatek/mt8173.dtsi
index a2f63e4..32c85cc 100644
--- a/arch/arm64/boot/dts/mediatek/mt8173.dtsi
+++ b/arch/arm64/boot/dts/mediatek/mt8173.dtsi
@@ -102,6 +102,13 @@
 		clock-output-names = "clk32k";
 	};
 
+	cpum_ck: oscillator at 2 {
+		compatible = "fixed-clock";
+		#clock-cells = <0>;
+		clock-frequency = <0>;
+		clock-output-names = "cpum_ck";
+	};
+
 	timer {
 		compatible = "arm,armv8-timer";
 		interrupt-parent = <&gic>;
@@ -227,6 +234,36 @@
 			clocks = <&uart_clk>;
 			status = "disabled";
 		};
+
+		mmsys: clock-controller at 14000000 {
+			compatible = "mediatek,mt8173-mmsys", "syscon";
+			reg = <0 0x14000000 0 0x1000>;
+			#clock-cells = <1>;
+		};
+
+		imgsys: clock-controller at 15000000 {
+			compatible = "mediatek,mt8173-imgsys", "syscon";
+			reg = <0 0x15000000 0 0x1000>;
+			#clock-cells = <1>;
+		};
+
+		vdecsys: clock-controller at 16000000 {
+			compatible = "mediatek,mt8173-vdecsys", "syscon";
+			reg = <0 0x16000000 0 0x1000>;
+			#clock-cells = <1>;
+		};
+
+		vencsys: clock-controller at 18000000 {
+			compatible = "mediatek,mt8173-vencsys", "syscon";
+			reg = <0 0x18000000 0 0x1000>;
+			#clock-cells = <1>;
+		};
+
+		vencltsys: clock-controller at 19000000 {
+			compatible = "mediatek,mt8173-vencltsys", "syscon";
+			reg = <0 0x19000000 0 0x1000>;
+			#clock-cells = <1>;
+		};
 	};
 };
 
-- 
1.8.1.1.dirty



From jamesjj.liao at mediatek.com  Mon Aug 10 02:50:22 2015
From: jamesjj.liao at mediatek.com (James Liao)
Date: Mon, 10 Aug 2015 17:50:22 +0800
Subject: [PATCH v7 3/9] clk: mediatek: Add __initdata and __init for data and
 functions
In-Reply-To: <1439200228-318-1-git-send-email-jamesjj.liao@mediatek.com>
References: <1439200228-318-1-git-send-email-jamesjj.liao@mediatek.com>
Message-ID: <1439200228-318-4-git-send-email-jamesjj.liao@mediatek.com>

Add __init for clock registration functions, and add __initdata for
mtk_gate_regs initial structures.

Signed-off-by: James Liao <jamesjj.liao at mediatek.com>
---
 drivers/clk/mediatek/clk-gate.c   |  2 +-
 drivers/clk/mediatek/clk-mt8173.c |  6 +++---
 drivers/clk/mediatek/clk-mtk.c    | 13 +++++++------
 3 files changed, 11 insertions(+), 10 deletions(-)

diff --git a/drivers/clk/mediatek/clk-gate.c b/drivers/clk/mediatek/clk-gate.c
index 5702036..576bdb7 100644
--- a/drivers/clk/mediatek/clk-gate.c
+++ b/drivers/clk/mediatek/clk-gate.c
@@ -97,7 +97,7 @@ const struct clk_ops mtk_clk_gate_ops_setclr_inv = {
 	.disable	= mtk_cg_disable_inv,
 };
 
-struct clk *mtk_clk_register_gate(
+struct clk * __init mtk_clk_register_gate(
 		const char *name,
 		const char *parent_name,
 		struct regmap *regmap,
diff --git a/drivers/clk/mediatek/clk-mt8173.c b/drivers/clk/mediatek/clk-mt8173.c
index 13aa432..361fe32 100644
--- a/drivers/clk/mediatek/clk-mt8173.c
+++ b/drivers/clk/mediatek/clk-mt8173.c
@@ -586,7 +586,7 @@ static const struct mtk_composite top_muxes[] __initconst = {
 	MUX(CLK_TOP_I2S3_B_SEL, "i2s3_b_ck_sel", i2s3_b_ck_parents, 0x120, 8, 1),
 };
 
-static const struct mtk_gate_regs infra_cg_regs = {
+static const struct mtk_gate_regs infra_cg_regs __initconst = {
 	.set_ofs = 0x0040,
 	.clr_ofs = 0x0044,
 	.sta_ofs = 0x0048,
@@ -615,13 +615,13 @@ static const struct mtk_gate infra_clks[] __initconst = {
 	GATE_ICG(CLK_INFRA_PMICWRAP, "infra_pmicwrap", "axi_sel", 23),
 };
 
-static const struct mtk_gate_regs peri0_cg_regs = {
+static const struct mtk_gate_regs peri0_cg_regs __initconst = {
 	.set_ofs = 0x0008,
 	.clr_ofs = 0x0010,
 	.sta_ofs = 0x0018,
 };
 
-static const struct mtk_gate_regs peri1_cg_regs = {
+static const struct mtk_gate_regs peri1_cg_regs __initconst = {
 	.set_ofs = 0x000c,
 	.clr_ofs = 0x0014,
 	.sta_ofs = 0x001c,
diff --git a/drivers/clk/mediatek/clk-mtk.c b/drivers/clk/mediatek/clk-mtk.c
index 18444ae..268b6ff 100644
--- a/drivers/clk/mediatek/clk-mtk.c
+++ b/drivers/clk/mediatek/clk-mtk.c
@@ -24,7 +24,7 @@
 #include "clk-mtk.h"
 #include "clk-gate.h"
 
-struct clk_onecell_data *mtk_alloc_clk_data(unsigned int clk_num)
+struct clk_onecell_data * __init mtk_alloc_clk_data(unsigned int clk_num)
 {
 	int i;
 	struct clk_onecell_data *clk_data;
@@ -49,8 +49,8 @@ err_out:
 	return NULL;
 }
 
-void mtk_clk_register_factors(const struct mtk_fixed_factor *clks, int num,
-		struct clk_onecell_data *clk_data)
+void __init mtk_clk_register_factors(const struct mtk_fixed_factor *clks,
+		int num, struct clk_onecell_data *clk_data)
 {
 	int i;
 	struct clk *clk;
@@ -72,7 +72,8 @@ void mtk_clk_register_factors(const struct mtk_fixed_factor *clks, int num,
 	}
 }
 
-int mtk_clk_register_gates(struct device_node *node, const struct mtk_gate *clks,
+int __init mtk_clk_register_gates(struct device_node *node,
+		const struct mtk_gate *clks,
 		int num, struct clk_onecell_data *clk_data)
 {
 	int i;
@@ -111,7 +112,7 @@ int mtk_clk_register_gates(struct device_node *node, const struct mtk_gate *clks
 	return 0;
 }
 
-struct clk *mtk_clk_register_composite(const struct mtk_composite *mc,
+struct clk * __init mtk_clk_register_composite(const struct mtk_composite *mc,
 		void __iomem *base, spinlock_t *lock)
 {
 	struct clk *clk;
@@ -196,7 +197,7 @@ err_out:
 	return ERR_PTR(ret);
 }
 
-void mtk_clk_register_composites(const struct mtk_composite *mcs,
+void __init mtk_clk_register_composites(const struct mtk_composite *mcs,
 		int num, void __iomem *base, spinlock_t *lock,
 		struct clk_onecell_data *clk_data)
 {
-- 
1.8.1.1.dirty



From jamesjj.liao at mediatek.com  Mon Aug 10 02:50:23 2015
From: jamesjj.liao at mediatek.com (James Liao)
Date: Mon, 10 Aug 2015 17:50:23 +0800
Subject: [PATCH v7 4/9] clk: mediatek: Add fixed clocks support for Mediatek
 SoC.
In-Reply-To: <1439200228-318-1-git-send-email-jamesjj.liao@mediatek.com>
References: <1439200228-318-1-git-send-email-jamesjj.liao@mediatek.com>
Message-ID: <1439200228-318-5-git-send-email-jamesjj.liao@mediatek.com>

This patch adds fixed clocks support by using CCF fixed-rate
clock implementation.

Signed-off-by: James Liao <jamesjj.liao at mediatek.com>
---
 drivers/clk/mediatek/clk-mtk.c | 23 +++++++++++++++++++++++
 drivers/clk/mediatek/clk-mtk.h | 17 +++++++++++++++++
 2 files changed, 40 insertions(+)

diff --git a/drivers/clk/mediatek/clk-mtk.c b/drivers/clk/mediatek/clk-mtk.c
index 268b6ff..cf08db6 100644
--- a/drivers/clk/mediatek/clk-mtk.c
+++ b/drivers/clk/mediatek/clk-mtk.c
@@ -49,6 +49,29 @@ err_out:
 	return NULL;
 }
 
+void __init mtk_clk_register_fixed_clks(const struct mtk_fixed_clk *clks,
+		int num, struct clk_onecell_data *clk_data)
+{
+	int i;
+	struct clk *clk;
+
+	for (i = 0; i < num; i++) {
+		const struct mtk_fixed_clk *rc = &clks[i];
+
+		clk = clk_register_fixed_rate(NULL, rc->name, rc->parent,
+				rc->parent ? 0 : CLK_IS_ROOT, rc->rate);
+
+		if (IS_ERR(clk)) {
+			pr_err("Failed to register clk %s: %ld\n",
+					rc->name, PTR_ERR(clk));
+			continue;
+		}
+
+		if (clk_data)
+			clk_data->clks[rc->id] = clk;
+	}
+}
+
 void __init mtk_clk_register_factors(const struct mtk_fixed_factor *clks,
 		int num, struct clk_onecell_data *clk_data)
 {
diff --git a/drivers/clk/mediatek/clk-mtk.h b/drivers/clk/mediatek/clk-mtk.h
index 740fe5e..32d4f55 100644
--- a/drivers/clk/mediatek/clk-mtk.h
+++ b/drivers/clk/mediatek/clk-mtk.h
@@ -25,6 +25,23 @@
 
 #define MHZ (1000 * 1000)
 
+struct mtk_fixed_clk {
+	int id;
+	const char *name;
+	const char *parent;
+	unsigned long rate;
+};
+
+#define FIXED_CLK(_id, _name, _parent, _rate) {		\
+		.id = _id,				\
+		.name = _name,				\
+		.parent = _parent,			\
+		.rate = _rate,				\
+	}
+
+void mtk_clk_register_fixed_clks(const struct mtk_fixed_clk *clks,
+		int num, struct clk_onecell_data *clk_data);
+
 struct mtk_fixed_factor {
 	int id;
 	const char *name;
-- 
1.8.1.1.dirty



From jamesjj.liao at mediatek.com  Mon Aug 10 02:50:25 2015
From: jamesjj.liao at mediatek.com (James Liao)
Date: Mon, 10 Aug 2015 17:50:25 +0800
Subject: [PATCH v7 6/9] dt-bindings: ARM: Mediatek: Document devicetree
 bindings for clock controllers
In-Reply-To: <1439200228-318-1-git-send-email-jamesjj.liao@mediatek.com>
References: <1439200228-318-1-git-send-email-jamesjj.liao@mediatek.com>
Message-ID: <1439200228-318-7-git-send-email-jamesjj.liao@mediatek.com>

This adds the binding documentation for the mmsys, imgsys, vdecsys,
vencsys and vencltsys controllers found on Mediatek SoCs.

Signed-off-by: James Liao <jamesjj.liao at mediatek.com>
---
 .../bindings/arm/mediatek/mediatek,imgsys.txt      | 22 ++++++++++++++++++++++
 .../bindings/arm/mediatek/mediatek,mmsys.txt       | 22 ++++++++++++++++++++++
 .../bindings/arm/mediatek/mediatek,vdecsys.txt     | 22 ++++++++++++++++++++++
 .../bindings/arm/mediatek/mediatek,vencltsys.txt   | 22 ++++++++++++++++++++++
 .../bindings/arm/mediatek/mediatek,vencsys.txt     | 22 ++++++++++++++++++++++
 5 files changed, 110 insertions(+)
 create mode 100644 Documentation/devicetree/bindings/arm/mediatek/mediatek,imgsys.txt
 create mode 100644 Documentation/devicetree/bindings/arm/mediatek/mediatek,mmsys.txt
 create mode 100644 Documentation/devicetree/bindings/arm/mediatek/mediatek,vdecsys.txt
 create mode 100644 Documentation/devicetree/bindings/arm/mediatek/mediatek,vencltsys.txt
 create mode 100644 Documentation/devicetree/bindings/arm/mediatek/mediatek,vencsys.txt

diff --git a/Documentation/devicetree/bindings/arm/mediatek/mediatek,imgsys.txt b/Documentation/devicetree/bindings/arm/mediatek/mediatek,imgsys.txt
new file mode 100644
index 0000000..b1f2ce1
--- /dev/null
+++ b/Documentation/devicetree/bindings/arm/mediatek/mediatek,imgsys.txt
@@ -0,0 +1,22 @@
+Mediatek imgsys controller
+============================
+
+The Mediatek imgsys controller provides various clocks to the system.
+
+Required Properties:
+
+- compatible: Should be:
+	- "mediatek,mt8173-imgsys", "syscon"
+- #clock-cells: Must be 1
+
+The imgsys controller uses the common clk binding from
+Documentation/devicetree/bindings/clock/clock-bindings.txt
+The available clocks are defined in dt-bindings/clock/mt*-clk.h.
+
+Example:
+
+imgsys: clock-controller at 15000000 {
+	compatible = "mediatek,mt8173-imgsys", "syscon";
+	reg = <0 0x15000000 0 0x1000>;
+	#clock-cells = <1>;
+};
diff --git a/Documentation/devicetree/bindings/arm/mediatek/mediatek,mmsys.txt b/Documentation/devicetree/bindings/arm/mediatek/mediatek,mmsys.txt
new file mode 100644
index 0000000..4385946
--- /dev/null
+++ b/Documentation/devicetree/bindings/arm/mediatek/mediatek,mmsys.txt
@@ -0,0 +1,22 @@
+Mediatek mmsys controller
+============================
+
+The Mediatek mmsys controller provides various clocks to the system.
+
+Required Properties:
+
+- compatible: Should be:
+	- "mediatek,mt8173-mmsys", "syscon"
+- #clock-cells: Must be 1
+
+The mmsys controller uses the common clk binding from
+Documentation/devicetree/bindings/clock/clock-bindings.txt
+The available clocks are defined in dt-bindings/clock/mt*-clk.h.
+
+Example:
+
+mmsys: clock-controller at 14000000 {
+	compatible = "mediatek,mt8173-mmsys", "syscon";
+	reg = <0 0x14000000 0 0x1000>;
+	#clock-cells = <1>;
+};
diff --git a/Documentation/devicetree/bindings/arm/mediatek/mediatek,vdecsys.txt b/Documentation/devicetree/bindings/arm/mediatek/mediatek,vdecsys.txt
new file mode 100644
index 0000000..1faacf1
--- /dev/null
+++ b/Documentation/devicetree/bindings/arm/mediatek/mediatek,vdecsys.txt
@@ -0,0 +1,22 @@
+Mediatek vdecsys controller
+============================
+
+The Mediatek vdecsys controller provides various clocks to the system.
+
+Required Properties:
+
+- compatible: Should be:
+	- "mediatek,mt8173-vdecsys", "syscon"
+- #clock-cells: Must be 1
+
+The vdecsys controller uses the common clk binding from
+Documentation/devicetree/bindings/clock/clock-bindings.txt
+The available clocks are defined in dt-bindings/clock/mt*-clk.h.
+
+Example:
+
+vdecsys: clock-controller at 16000000 {
+	compatible = "mediatek,mt8173-vdecsys", "syscon";
+	reg = <0 0x16000000 0 0x1000>;
+	#clock-cells = <1>;
+};
diff --git a/Documentation/devicetree/bindings/arm/mediatek/mediatek,vencltsys.txt b/Documentation/devicetree/bindings/arm/mediatek/mediatek,vencltsys.txt
new file mode 100644
index 0000000..3cc299f
--- /dev/null
+++ b/Documentation/devicetree/bindings/arm/mediatek/mediatek,vencltsys.txt
@@ -0,0 +1,22 @@
+Mediatek vencltsys controller
+============================
+
+The Mediatek vencltsys controller provides various clocks to the system.
+
+Required Properties:
+
+- compatible: Should be:
+	- "mediatek,mt8173-vencltsys", "syscon"
+- #clock-cells: Must be 1
+
+The vencltsys controller uses the common clk binding from
+Documentation/devicetree/bindings/clock/clock-bindings.txt
+The available clocks are defined in dt-bindings/clock/mt*-clk.h.
+
+Example:
+
+vencltsys: clock-controller at 19000000 {
+	compatible = "mediatek,mt8173-vencltsys", "syscon";
+	reg = <0 0x19000000 0 0x1000>;
+	#clock-cells = <1>;
+};
diff --git a/Documentation/devicetree/bindings/arm/mediatek/mediatek,vencsys.txt b/Documentation/devicetree/bindings/arm/mediatek/mediatek,vencsys.txt
new file mode 100644
index 0000000..5bb2866
--- /dev/null
+++ b/Documentation/devicetree/bindings/arm/mediatek/mediatek,vencsys.txt
@@ -0,0 +1,22 @@
+Mediatek vencsys controller
+============================
+
+The Mediatek vencsys controller provides various clocks to the system.
+
+Required Properties:
+
+- compatible: Should be:
+	- "mediatek,mt8173-vencsys", "syscon"
+- #clock-cells: Must be 1
+
+The vencsys controller uses the common clk binding from
+Documentation/devicetree/bindings/clock/clock-bindings.txt
+The available clocks are defined in dt-bindings/clock/mt*-clk.h.
+
+Example:
+
+vencsys: clock-controller at 18000000 {
+	compatible = "mediatek,mt8173-vencsys", "syscon";
+	reg = <0 0x18000000 0 0x1000>;
+	#clock-cells = <1>;
+};
-- 
1.8.1.1.dirty



From jamesjj.liao at mediatek.com  Mon Aug 10 02:50:20 2015
From: jamesjj.liao at mediatek.com (James Liao)
Date: Mon, 10 Aug 2015 17:50:20 +0800
Subject: [PATCH v7 1/9] clk: mediatek: Removed unused dpi_ck clock from MT8173
In-Reply-To: <1439200228-318-1-git-send-email-jamesjj.liao@mediatek.com>
References: <1439200228-318-1-git-send-email-jamesjj.liao@mediatek.com>
Message-ID: <1439200228-318-2-git-send-email-jamesjj.liao@mediatek.com>

The dpi_ck clock can be removed because it not actually used
in topckgen and subsystems.

Signed-off-by: James Liao <jamesjj.liao at mediatek.com>
---
 drivers/clk/mediatek/clk-mt8173.c      | 1 -
 include/dt-bindings/clock/mt8173-clk.h | 1 -
 2 files changed, 2 deletions(-)

diff --git a/drivers/clk/mediatek/clk-mt8173.c b/drivers/clk/mediatek/clk-mt8173.c
index 8b6523d..80871e2 100644
--- a/drivers/clk/mediatek/clk-mt8173.c
+++ b/drivers/clk/mediatek/clk-mt8173.c
@@ -26,7 +26,6 @@ static DEFINE_SPINLOCK(mt8173_clk_lock);
 
 static const struct mtk_fixed_factor root_clk_alias[] __initconst = {
 	FACTOR(CLK_TOP_CLKPH_MCK_O, "clkph_mck_o", "clk_null", 1, 1),
-	FACTOR(CLK_TOP_DPI, "dpi_ck", "clk_null", 1, 1),
 	FACTOR(CLK_TOP_USB_SYSPLL_125M, "usb_syspll_125m", "clk_null", 1, 1),
 	FACTOR(CLK_TOP_HDMITX_DIG_CTS, "hdmitx_dig_cts", "clk_null", 1, 1),
 };
diff --git a/include/dt-bindings/clock/mt8173-clk.h b/include/dt-bindings/clock/mt8173-clk.h
index 4ad76ed..7230c38 100644
--- a/include/dt-bindings/clock/mt8173-clk.h
+++ b/include/dt-bindings/clock/mt8173-clk.h
@@ -18,7 +18,6 @@
 /* TOPCKGEN */
 
 #define CLK_TOP_CLKPH_MCK_O		1
-#define CLK_TOP_DPI			2
 #define CLK_TOP_USB_SYSPLL_125M		3
 #define CLK_TOP_HDMITX_DIG_CTS		4
 #define CLK_TOP_ARMCA7PLL_754M		5
-- 
1.8.1.1.dirty



From jamesjj.liao at mediatek.com  Mon Aug 10 02:50:24 2015
From: jamesjj.liao at mediatek.com (James Liao)
Date: Mon, 10 Aug 2015 17:50:24 +0800
Subject: [PATCH v7 5/9] clk: mediatek: Fix rate and dependency of MT8173 clocks
In-Reply-To: <1439200228-318-1-git-send-email-jamesjj.liao@mediatek.com>
References: <1439200228-318-1-git-send-email-jamesjj.liao@mediatek.com>
Message-ID: <1439200228-318-6-git-send-email-jamesjj.liao@mediatek.com>

Remove the dependency from clk_null, and give all root clocks a
typical rate, include clkph_mck_o, usb_syspll_125m and hdmitx_dig_cts.

dpi_ck was removed due to no clock reference to it.

Replace parent clock of infra_cpum with cpum_ck, which is an external
clock and can be defined in the device tree.

Signed-off-by: James Liao <jamesjj.liao at mediatek.com>
---
 drivers/clk/mediatek/clk-mt8173.c | 19 +++++++++++++------
 1 file changed, 13 insertions(+), 6 deletions(-)

diff --git a/drivers/clk/mediatek/clk-mt8173.c b/drivers/clk/mediatek/clk-mt8173.c
index 361fe32..c251787 100644
--- a/drivers/clk/mediatek/clk-mt8173.c
+++ b/drivers/clk/mediatek/clk-mt8173.c
@@ -20,12 +20,18 @@
 
 #include <dt-bindings/clock/mt8173-clk.h>
 
+/*
+ * For some clocks, we don't care what their actual rates are. And these
+ * clocks may change their rate on different products or different scenarios.
+ * So we model these clocks' rate as 0, to denote it's not an actual rate.
+ */
+#define DUMMY_RATE		0
+
 static DEFINE_SPINLOCK(mt8173_clk_lock);
 
-static const struct mtk_fixed_factor root_clk_alias[] __initconst = {
-	FACTOR(CLK_TOP_CLKPH_MCK_O, "clkph_mck_o", "clk_null", 1, 1),
-	FACTOR(CLK_TOP_USB_SYSPLL_125M, "usb_syspll_125m", "clk_null", 1, 1),
-	FACTOR(CLK_TOP_HDMITX_DIG_CTS, "hdmitx_dig_cts", "clk_null", 1, 1),
+static const struct mtk_fixed_clk fixed_clks[] __initconst = {
+	FIXED_CLK(CLK_TOP_CLKPH_MCK_O, "clkph_mck_o", "clk26m", DUMMY_RATE),
+	FIXED_CLK(CLK_TOP_USB_SYSPLL_125M, "usb_syspll_125m", "clk26m", 125 * MHZ),
 };
 
 static const struct mtk_fixed_factor top_divs[] __initconst = {
@@ -50,6 +56,7 @@ static const struct mtk_fixed_factor top_divs[] __initconst = {
 	FACTOR(CLK_TOP_CLKRTC_INT, "clkrtc_int", "clk26m", 1, 793),
 	FACTOR(CLK_TOP_FPC, "fpc_ck", "clk26m", 1, 1),
 
+	FACTOR(CLK_TOP_HDMITX_DIG_CTS, "hdmitx_dig_cts", "tvdpll_445p5m", 1, 3),
 	FACTOR(CLK_TOP_HDMITXPLL_D2, "hdmitxpll_d2", "hdmitx_dig_cts", 1, 2),
 	FACTOR(CLK_TOP_HDMITXPLL_D3, "hdmitxpll_d3", "hdmitx_dig_cts", 1, 3),
 
@@ -608,7 +615,7 @@ static const struct mtk_gate infra_clks[] __initconst = {
 	GATE_ICG(CLK_INFRA_GCE, "infra_gce", "axi_sel", 6),
 	GATE_ICG(CLK_INFRA_L2C_SRAM, "infra_l2c_sram", "axi_sel", 7),
 	GATE_ICG(CLK_INFRA_M4U, "infra_m4u", "mem_sel", 8),
-	GATE_ICG(CLK_INFRA_CPUM, "infra_cpum", "clk_null", 15),
+	GATE_ICG(CLK_INFRA_CPUM, "infra_cpum", "cpum_ck", 15),
 	GATE_ICG(CLK_INFRA_KP, "infra_kp", "axi_sel", 16),
 	GATE_ICG(CLK_INFRA_CEC, "infra_cec", "clk26m", 18),
 	GATE_ICG(CLK_INFRA_PMICSPI, "infra_pmicspi", "pmicspi_sel", 22),
@@ -727,7 +734,7 @@ static void __init mtk_topckgen_init(struct device_node *node)
 
 	mt8173_top_clk_data = clk_data = mtk_alloc_clk_data(CLK_TOP_NR_CLK);
 
-	mtk_clk_register_factors(root_clk_alias, ARRAY_SIZE(root_clk_alias), clk_data);
+	mtk_clk_register_fixed_clks(fixed_clks, ARRAY_SIZE(fixed_clks), clk_data);
 	mtk_clk_register_factors(top_divs, ARRAY_SIZE(top_divs), clk_data);
 	mtk_clk_register_composites(top_muxes, ARRAY_SIZE(top_muxes), base,
 			&mt8173_clk_lock, clk_data);
-- 
1.8.1.1.dirty



From jamesjj.liao at mediatek.com  Mon Aug 10 02:50:26 2015
From: jamesjj.liao at mediatek.com (James Liao)
Date: Mon, 10 Aug 2015 17:50:26 +0800
Subject: [PATCH v7 7/9] clk: mediatek: Add subsystem clocks of MT8173
In-Reply-To: <1439200228-318-1-git-send-email-jamesjj.liao@mediatek.com>
References: <1439200228-318-1-git-send-email-jamesjj.liao@mediatek.com>
Message-ID: <1439200228-318-8-git-send-email-jamesjj.liao@mediatek.com>

Most multimedia subsystem clocks will be accessed by multiple
drivers, so it's a better way to manage these clocks in CCF.
This patch adds clock support for MM, IMG, VDEC, VENC and VENC_LT
subsystems.

Signed-off-by: James Liao <jamesjj.liao at mediatek.com>
---
 drivers/clk/mediatek/clk-mt8173.c      | 267 +++++++++++++++++++++++++++++++++
 include/dt-bindings/clock/mt8173-clk.h |  97 +++++++++++-
 2 files changed, 361 insertions(+), 3 deletions(-)

diff --git a/drivers/clk/mediatek/clk-mt8173.c b/drivers/clk/mediatek/clk-mt8173.c
index c251787..14f61f1 100644
--- a/drivers/clk/mediatek/clk-mt8173.c
+++ b/drivers/clk/mediatek/clk-mt8173.c
@@ -32,6 +32,10 @@ static DEFINE_SPINLOCK(mt8173_clk_lock);
 static const struct mtk_fixed_clk fixed_clks[] __initconst = {
 	FIXED_CLK(CLK_TOP_CLKPH_MCK_O, "clkph_mck_o", "clk26m", DUMMY_RATE),
 	FIXED_CLK(CLK_TOP_USB_SYSPLL_125M, "usb_syspll_125m", "clk26m", 125 * MHZ),
+	FIXED_CLK(CLK_TOP_DSI0_DIG, "dsi0_dig", "clk26m", DUMMY_RATE),
+	FIXED_CLK(CLK_TOP_DSI1_DIG, "dsi1_dig", "clk26m", DUMMY_RATE),
+	FIXED_CLK(CLK_TOP_LVDS_PXL, "lvds_pxl", "lvdspll", DUMMY_RATE),
+	FIXED_CLK(CLK_TOP_LVDS_CTS, "lvds_cts", "lvdspll", DUMMY_RATE),
 };
 
 static const struct mtk_fixed_factor top_divs[] __initconst = {
@@ -704,6 +708,183 @@ static const struct mtk_composite peri_clks[] __initconst = {
 	MUX(CLK_PERI_UART3_SEL, "uart3_ck_sel", uart_ck_sel_parents, 0x40c, 3, 1),
 };
 
+static const struct mtk_gate_regs cg_regs_4_8_0 __initconst = {
+	.set_ofs = 0x0004,
+	.clr_ofs = 0x0008,
+	.sta_ofs = 0x0000,
+};
+
+#define GATE_IMG(_id, _name, _parent, _shift) {			\
+		.id = _id,					\
+		.name = _name,					\
+		.parent_name = _parent,				\
+		.regs = &cg_regs_4_8_0,				\
+		.shift = _shift,				\
+		.ops = &mtk_clk_gate_ops_setclr,		\
+	}
+
+static const struct mtk_gate img_clks[] __initconst = {
+	GATE_IMG(CLK_IMG_LARB2_SMI, "img_larb2_smi", "mm_sel", 0),
+	GATE_IMG(CLK_IMG_CAM_SMI, "img_cam_smi", "mm_sel", 5),
+	GATE_IMG(CLK_IMG_CAM_CAM, "img_cam_cam", "mm_sel", 6),
+	GATE_IMG(CLK_IMG_SEN_TG, "img_sen_tg", "camtg_sel", 7),
+	GATE_IMG(CLK_IMG_SEN_CAM, "img_sen_cam", "mm_sel", 8),
+	GATE_IMG(CLK_IMG_CAM_SV, "img_cam_sv", "mm_sel", 9),
+	GATE_IMG(CLK_IMG_FD, "img_fd", "mm_sel", 11),
+};
+
+static const struct mtk_gate_regs mm0_cg_regs __initconst = {
+	.set_ofs = 0x0104,
+	.clr_ofs = 0x0108,
+	.sta_ofs = 0x0100,
+};
+
+static const struct mtk_gate_regs mm1_cg_regs __initconst = {
+	.set_ofs = 0x0114,
+	.clr_ofs = 0x0118,
+	.sta_ofs = 0x0110,
+};
+
+#define GATE_MM0(_id, _name, _parent, _shift) {			\
+		.id = _id,					\
+		.name = _name,					\
+		.parent_name = _parent,				\
+		.regs = &mm0_cg_regs,				\
+		.shift = _shift,				\
+		.ops = &mtk_clk_gate_ops_setclr,		\
+	}
+
+#define GATE_MM1(_id, _name, _parent, _shift) {			\
+		.id = _id,					\
+		.name = _name,					\
+		.parent_name = _parent,				\
+		.regs = &mm1_cg_regs,				\
+		.shift = _shift,				\
+		.ops = &mtk_clk_gate_ops_setclr,		\
+	}
+
+static const struct mtk_gate mm_clks[] __initconst = {
+	/* MM0 */
+	GATE_MM0(CLK_MM_SMI_COMMON, "mm_smi_common", "mm_sel", 0),
+	GATE_MM0(CLK_MM_SMI_LARB0, "mm_smi_larb0", "mm_sel", 1),
+	GATE_MM0(CLK_MM_CAM_MDP, "mm_cam_mdp", "mm_sel", 2),
+	GATE_MM0(CLK_MM_MDP_RDMA0, "mm_mdp_rdma0", "mm_sel", 3),
+	GATE_MM0(CLK_MM_MDP_RDMA1, "mm_mdp_rdma1", "mm_sel", 4),
+	GATE_MM0(CLK_MM_MDP_RSZ0, "mm_mdp_rsz0", "mm_sel", 5),
+	GATE_MM0(CLK_MM_MDP_RSZ1, "mm_mdp_rsz1", "mm_sel", 6),
+	GATE_MM0(CLK_MM_MDP_RSZ2, "mm_mdp_rsz2", "mm_sel", 7),
+	GATE_MM0(CLK_MM_MDP_TDSHP0, "mm_mdp_tdshp0", "mm_sel", 8),
+	GATE_MM0(CLK_MM_MDP_TDSHP1, "mm_mdp_tdshp1", "mm_sel", 9),
+	GATE_MM0(CLK_MM_MDP_WDMA, "mm_mdp_wdma", "mm_sel", 11),
+	GATE_MM0(CLK_MM_MDP_WROT0, "mm_mdp_wrot0", "mm_sel", 12),
+	GATE_MM0(CLK_MM_MDP_WROT1, "mm_mdp_wrot1", "mm_sel", 13),
+	GATE_MM0(CLK_MM_FAKE_ENG, "mm_fake_eng", "mm_sel", 14),
+	GATE_MM0(CLK_MM_MUTEX_32K, "mm_mutex_32k", "rtc_sel", 15),
+	GATE_MM0(CLK_MM_DISP_OVL0, "mm_disp_ovl0", "mm_sel", 16),
+	GATE_MM0(CLK_MM_DISP_OVL1, "mm_disp_ovl1", "mm_sel", 17),
+	GATE_MM0(CLK_MM_DISP_RDMA0, "mm_disp_rdma0", "mm_sel", 18),
+	GATE_MM0(CLK_MM_DISP_RDMA1, "mm_disp_rdma1", "mm_sel", 19),
+	GATE_MM0(CLK_MM_DISP_RDMA2, "mm_disp_rdma2", "mm_sel", 20),
+	GATE_MM0(CLK_MM_DISP_WDMA0, "mm_disp_wdma0", "mm_sel", 21),
+	GATE_MM0(CLK_MM_DISP_WDMA1, "mm_disp_wdma1", "mm_sel", 22),
+	GATE_MM0(CLK_MM_DISP_COLOR0, "mm_disp_color0", "mm_sel", 23),
+	GATE_MM0(CLK_MM_DISP_COLOR1, "mm_disp_color1", "mm_sel", 24),
+	GATE_MM0(CLK_MM_DISP_AAL, "mm_disp_aal", "mm_sel", 25),
+	GATE_MM0(CLK_MM_DISP_GAMMA, "mm_disp_gamma", "mm_sel", 26),
+	GATE_MM0(CLK_MM_DISP_UFOE, "mm_disp_ufoe", "mm_sel", 27),
+	GATE_MM0(CLK_MM_DISP_SPLIT0, "mm_disp_split0", "mm_sel", 28),
+	GATE_MM0(CLK_MM_DISP_SPLIT1, "mm_disp_split1", "mm_sel", 29),
+	GATE_MM0(CLK_MM_DISP_MERGE, "mm_disp_merge", "mm_sel", 30),
+	GATE_MM0(CLK_MM_DISP_OD, "mm_disp_od", "mm_sel", 31),
+	/* MM1 */
+	GATE_MM1(CLK_MM_DISP_PWM0MM, "mm_disp_pwm0mm", "mm_sel", 0),
+	GATE_MM1(CLK_MM_DISP_PWM026M, "mm_disp_pwm026m", "pwm_sel", 1),
+	GATE_MM1(CLK_MM_DISP_PWM1MM, "mm_disp_pwm1mm", "mm_sel", 2),
+	GATE_MM1(CLK_MM_DISP_PWM126M, "mm_disp_pwm126m", "pwm_sel", 3),
+	GATE_MM1(CLK_MM_DSI0_ENGINE, "mm_dsi0_engine", "mm_sel", 4),
+	GATE_MM1(CLK_MM_DSI0_DIGITAL, "mm_dsi0_digital", "dsi0_dig", 5),
+	GATE_MM1(CLK_MM_DSI1_ENGINE, "mm_dsi1_engine", "mm_sel", 6),
+	GATE_MM1(CLK_MM_DSI1_DIGITAL, "mm_dsi1_digital", "dsi1_dig", 7),
+	GATE_MM1(CLK_MM_DPI_PIXEL, "mm_dpi_pixel", "dpi0_sel", 8),
+	GATE_MM1(CLK_MM_DPI_ENGINE, "mm_dpi_engine", "mm_sel", 9),
+	GATE_MM1(CLK_MM_DPI1_PIXEL, "mm_dpi1_pixel", "lvds_pxl", 10),
+	GATE_MM1(CLK_MM_DPI1_ENGINE, "mm_dpi1_engine", "mm_sel", 11),
+	GATE_MM1(CLK_MM_HDMI_PIXEL, "mm_hdmi_pixel", "dpi0_sel", 12),
+	GATE_MM1(CLK_MM_HDMI_PLLCK, "mm_hdmi_pllck", "hdmi_sel", 13),
+	GATE_MM1(CLK_MM_HDMI_AUDIO, "mm_hdmi_audio", "apll1", 14),
+	GATE_MM1(CLK_MM_HDMI_SPDIF, "mm_hdmi_spdif", "apll2", 15),
+	GATE_MM1(CLK_MM_LVDS_PIXEL, "mm_lvds_pixel", "lvds_pxl", 16),
+	GATE_MM1(CLK_MM_LVDS_CTS, "mm_lvds_cts", "lvds_cts", 17),
+	GATE_MM1(CLK_MM_SMI_LARB4, "mm_smi_larb4", "mm_sel", 18),
+	GATE_MM1(CLK_MM_HDMI_HDCP, "mm_hdmi_hdcp", "hdcp_sel", 19),
+	GATE_MM1(CLK_MM_HDMI_HDCP24M, "mm_hdmi_hdcp24m", "hdcp_24m_sel", 20),
+};
+
+static const struct mtk_gate_regs vdec0_cg_regs __initconst = {
+	.set_ofs = 0x0000,
+	.clr_ofs = 0x0004,
+	.sta_ofs = 0x0000,
+};
+
+static const struct mtk_gate_regs vdec1_cg_regs __initconst = {
+	.set_ofs = 0x0008,
+	.clr_ofs = 0x000c,
+	.sta_ofs = 0x0008,
+};
+
+#define GATE_VDEC0(_id, _name, _parent, _shift) {		\
+		.id = _id,					\
+		.name = _name,					\
+		.parent_name = _parent,				\
+		.regs = &vdec0_cg_regs,				\
+		.shift = _shift,				\
+		.ops = &mtk_clk_gate_ops_setclr_inv,		\
+	}
+
+#define GATE_VDEC1(_id, _name, _parent, _shift) {		\
+		.id = _id,					\
+		.name = _name,					\
+		.parent_name = _parent,				\
+		.regs = &vdec1_cg_regs,				\
+		.shift = _shift,				\
+		.ops = &mtk_clk_gate_ops_setclr_inv,		\
+	}
+
+static const struct mtk_gate vdec_clks[] __initconst = {
+	GATE_VDEC0(CLK_VDEC_CKEN, "vdec_cken", "vdec_sel", 0),
+	GATE_VDEC1(CLK_VDEC_LARB_CKEN, "vdec_larb_cken", "mm_sel", 0),
+};
+
+#define GATE_VENC(_id, _name, _parent, _shift) {		\
+		.id = _id,					\
+		.name = _name,					\
+		.parent_name = _parent,				\
+		.regs = &cg_regs_4_8_0,				\
+		.shift = _shift,				\
+		.ops = &mtk_clk_gate_ops_setclr_inv,		\
+	}
+
+static const struct mtk_gate venc_clks[] __initconst = {
+	GATE_VENC(CLK_VENC_CKE0, "venc_cke0", "mm_sel", 0),
+	GATE_VENC(CLK_VENC_CKE1, "venc_cke1", "venc_sel", 4),
+	GATE_VENC(CLK_VENC_CKE2, "venc_cke2", "venc_sel", 8),
+	GATE_VENC(CLK_VENC_CKE3, "venc_cke3", "venc_sel", 12),
+};
+
+#define GATE_VENCLT(_id, _name, _parent, _shift) {		\
+		.id = _id,					\
+		.name = _name,					\
+		.parent_name = _parent,				\
+		.regs = &cg_regs_4_8_0,				\
+		.shift = _shift,				\
+		.ops = &mtk_clk_gate_ops_setclr_inv,		\
+	}
+
+static const struct mtk_gate venclt_clks[] __initconst = {
+	GATE_VENCLT(CLK_VENCLT_CKE0, "venclt_cke0", "mm_sel", 0),
+	GATE_VENCLT(CLK_VENCLT_CKE1, "venclt_cke1", "venclt_sel", 4),
+};
+
 static struct clk_onecell_data *mt8173_top_clk_data __initdata;
 static struct clk_onecell_data *mt8173_pll_clk_data __initdata;
 
@@ -848,3 +1029,89 @@ static void __init mtk_apmixedsys_init(struct device_node *node)
 }
 CLK_OF_DECLARE(mtk_apmixedsys, "mediatek,mt8173-apmixedsys",
 		mtk_apmixedsys_init);
+
+static void __init mtk_imgsys_init(struct device_node *node)
+{
+	struct clk_onecell_data *clk_data;
+	int r;
+
+	clk_data = mtk_alloc_clk_data(CLK_IMG_NR_CLK);
+
+	mtk_clk_register_gates(node, img_clks, ARRAY_SIZE(img_clks),
+						clk_data);
+
+	r = of_clk_add_provider(node, of_clk_src_onecell_get, clk_data);
+
+	if (r)
+		pr_err("%s(): could not register clock provider: %d\n",
+			__func__, r);
+}
+CLK_OF_DECLARE(mtk_imgsys, "mediatek,mt8173-imgsys", mtk_imgsys_init);
+
+static void __init mtk_mmsys_init(struct device_node *node)
+{
+	struct clk_onecell_data *clk_data;
+	int r;
+
+	clk_data = mtk_alloc_clk_data(CLK_MM_NR_CLK);
+
+	mtk_clk_register_gates(node, mm_clks, ARRAY_SIZE(mm_clks),
+						clk_data);
+
+	r = of_clk_add_provider(node, of_clk_src_onecell_get, clk_data);
+	if (r)
+		pr_err("%s(): could not register clock provider: %d\n",
+			__func__, r);
+}
+CLK_OF_DECLARE(mtk_mmsys, "mediatek,mt8173-mmsys", mtk_mmsys_init);
+
+static void __init mtk_vdecsys_init(struct device_node *node)
+{
+	struct clk_onecell_data *clk_data;
+	int r;
+
+	clk_data = mtk_alloc_clk_data(CLK_VDEC_NR_CLK);
+
+	mtk_clk_register_gates(node, vdec_clks, ARRAY_SIZE(vdec_clks),
+						clk_data);
+
+	r = of_clk_add_provider(node, of_clk_src_onecell_get, clk_data);
+	if (r)
+		pr_err("%s(): could not register clock provider: %d\n",
+			__func__, r);
+}
+CLK_OF_DECLARE(mtk_vdecsys, "mediatek,mt8173-vdecsys", mtk_vdecsys_init);
+
+static void __init mtk_vencsys_init(struct device_node *node)
+{
+	struct clk_onecell_data *clk_data;
+	int r;
+
+	clk_data = mtk_alloc_clk_data(CLK_VENC_NR_CLK);
+
+	mtk_clk_register_gates(node, venc_clks, ARRAY_SIZE(venc_clks),
+						clk_data);
+
+	r = of_clk_add_provider(node, of_clk_src_onecell_get, clk_data);
+	if (r)
+		pr_err("%s(): could not register clock provider: %d\n",
+			__func__, r);
+}
+CLK_OF_DECLARE(mtk_vencsys, "mediatek,mt8173-vencsys", mtk_vencsys_init);
+
+static void __init mtk_vencltsys_init(struct device_node *node)
+{
+	struct clk_onecell_data *clk_data;
+	int r;
+
+	clk_data = mtk_alloc_clk_data(CLK_VENCLT_NR_CLK);
+
+	mtk_clk_register_gates(node, venclt_clks, ARRAY_SIZE(venclt_clks),
+						clk_data);
+
+	r = of_clk_add_provider(node, of_clk_src_onecell_get, clk_data);
+	if (r)
+		pr_err("%s(): could not register clock provider: %d\n",
+			__func__, r);
+}
+CLK_OF_DECLARE(mtk_vencltsys, "mediatek,mt8173-vencltsys", mtk_vencltsys_init);
diff --git a/include/dt-bindings/clock/mt8173-clk.h b/include/dt-bindings/clock/mt8173-clk.h
index 7230c38..87820ee 100644
--- a/include/dt-bindings/clock/mt8173-clk.h
+++ b/include/dt-bindings/clock/mt8173-clk.h
@@ -153,12 +153,16 @@
 #define CLK_TOP_I2S2_M_SEL		135
 #define CLK_TOP_I2S3_M_SEL		136
 #define CLK_TOP_I2S3_B_SEL		137
-#define CLK_TOP_NR_CLK			138
+#define CLK_TOP_DSI0_DIG		138
+#define CLK_TOP_DSI1_DIG		139
+#define CLK_TOP_LVDS_PXL		140
+#define CLK_TOP_LVDS_CTS		141
+#define CLK_TOP_NR_CLK			142
 
 /* APMIXED_SYS */
 
-#define CLK_APMIXED_ARMCA15PLL	1
-#define CLK_APMIXED_ARMCA7PLL	2
+#define CLK_APMIXED_ARMCA15PLL		1
+#define CLK_APMIXED_ARMCA7PLL		2
 #define CLK_APMIXED_MAINPLL		3
 #define CLK_APMIXED_UNIVPLL		4
 #define CLK_APMIXED_MMPLL		5
@@ -231,4 +235,91 @@
 #define CLK_PERI_UART3_SEL		39
 #define CLK_PERI_NR_CLK			40
 
+/* IMG_SYS */
+
+#define CLK_IMG_LARB2_SMI		1
+#define CLK_IMG_CAM_SMI			2
+#define CLK_IMG_CAM_CAM			3
+#define CLK_IMG_SEN_TG			4
+#define CLK_IMG_SEN_CAM			5
+#define CLK_IMG_CAM_SV			6
+#define CLK_IMG_FD			7
+#define CLK_IMG_NR_CLK			8
+
+/* MM_SYS */
+
+#define CLK_MM_SMI_COMMON		1
+#define CLK_MM_SMI_LARB0		2
+#define CLK_MM_CAM_MDP			3
+#define CLK_MM_MDP_RDMA0		4
+#define CLK_MM_MDP_RDMA1		5
+#define CLK_MM_MDP_RSZ0			6
+#define CLK_MM_MDP_RSZ1			7
+#define CLK_MM_MDP_RSZ2			8
+#define CLK_MM_MDP_TDSHP0		9
+#define CLK_MM_MDP_TDSHP1		10
+#define CLK_MM_MDP_WDMA			11
+#define CLK_MM_MDP_WROT0		12
+#define CLK_MM_MDP_WROT1		13
+#define CLK_MM_FAKE_ENG			14
+#define CLK_MM_MUTEX_32K		15
+#define CLK_MM_DISP_OVL0		16
+#define CLK_MM_DISP_OVL1		17
+#define CLK_MM_DISP_RDMA0		18
+#define CLK_MM_DISP_RDMA1		19
+#define CLK_MM_DISP_RDMA2		20
+#define CLK_MM_DISP_WDMA0		21
+#define CLK_MM_DISP_WDMA1		22
+#define CLK_MM_DISP_COLOR0		23
+#define CLK_MM_DISP_COLOR1		24
+#define CLK_MM_DISP_AAL			25
+#define CLK_MM_DISP_GAMMA		26
+#define CLK_MM_DISP_UFOE		27
+#define CLK_MM_DISP_SPLIT0		28
+#define CLK_MM_DISP_SPLIT1		29
+#define CLK_MM_DISP_MERGE		30
+#define CLK_MM_DISP_OD			31
+#define CLK_MM_DISP_PWM0MM		32
+#define CLK_MM_DISP_PWM026M		33
+#define CLK_MM_DISP_PWM1MM		34
+#define CLK_MM_DISP_PWM126M		35
+#define CLK_MM_DSI0_ENGINE		36
+#define CLK_MM_DSI0_DIGITAL		37
+#define CLK_MM_DSI1_ENGINE		38
+#define CLK_MM_DSI1_DIGITAL		39
+#define CLK_MM_DPI_PIXEL		40
+#define CLK_MM_DPI_ENGINE		41
+#define CLK_MM_DPI1_PIXEL		42
+#define CLK_MM_DPI1_ENGINE		43
+#define CLK_MM_HDMI_PIXEL		44
+#define CLK_MM_HDMI_PLLCK		45
+#define CLK_MM_HDMI_AUDIO		46
+#define CLK_MM_HDMI_SPDIF		47
+#define CLK_MM_LVDS_PIXEL		48
+#define CLK_MM_LVDS_CTS			49
+#define CLK_MM_SMI_LARB4		50
+#define CLK_MM_HDMI_HDCP		51
+#define CLK_MM_HDMI_HDCP24M		52
+#define CLK_MM_NR_CLK			53
+
+/* VDEC_SYS */
+
+#define CLK_VDEC_CKEN			1
+#define CLK_VDEC_LARB_CKEN		2
+#define CLK_VDEC_NR_CLK			3
+
+/* VENC_SYS */
+
+#define CLK_VENC_CKE0			1
+#define CLK_VENC_CKE1			2
+#define CLK_VENC_CKE2			3
+#define CLK_VENC_CKE3			4
+#define CLK_VENC_NR_CLK			5
+
+/* VENCLT_SYS */
+
+#define CLK_VENCLT_CKE0			1
+#define CLK_VENCLT_CKE1			2
+#define CLK_VENCLT_NR_CLK		3
+
 #endif /* _DT_BINDINGS_CLK_MT8173_H */
-- 
1.8.1.1.dirty



From daniel.lezcano at linaro.org  Mon Aug 10 02:51:19 2015
From: daniel.lezcano at linaro.org (Daniel Lezcano)
Date: Mon, 10 Aug 2015 11:51:19 +0200
Subject: [PATCH 02/74] clockevents/drivers/arm_global_timer: Migrate to new
 'set-state' interface
In-Reply-To: <1439200352-26767-1-git-send-email-daniel.lezcano@linaro.org>
References: <55C87382.4070309@linaro.org>
 <1439200352-26767-1-git-send-email-daniel.lezcano@linaro.org>
Message-ID: <1439200352-26767-2-git-send-email-daniel.lezcano@linaro.org>

From: Viresh Kumar <viresh.kumar at linaro.org>

Migrate arm_global_timer driver to the new 'set-state' interface
provided by the clockevents core, the earlier 'set-mode' interface is
marked obsolete now.

This also enables us to implement callbacks for new states of clockevent
devices, for example: ONESHOT_STOPPED.

Acked-by: Daniel Lezcano <daniel.lezcano at linaro.org>
Acked-by: Maxime Coquelin <maxime.coquelin at st.com>
Acked-by: Srinivas Kandagatla <srinivas.kandagatla at linaro.org>
Cc: Srinivas Kandagatla <srinivas.kandagatla at gmail.com>
Cc: Maxime Coquelin <maxime.coquelin at st.com>
Cc: Patrice Chotard <patrice.chotard at st.com>
Signed-off-by: Viresh Kumar <viresh.kumar at linaro.org>
Signed-off-by: Daniel Lezcano <daniel.lezcano at linaro.org>
---
 drivers/clocksource/arm_global_timer.c | 37 ++++++++++++++++------------------
 1 file changed, 17 insertions(+), 20 deletions(-)

diff --git a/drivers/clocksource/arm_global_timer.c b/drivers/clocksource/arm_global_timer.c
index e683377..29ea50a 100644
--- a/drivers/clocksource/arm_global_timer.c
+++ b/drivers/clocksource/arm_global_timer.c
@@ -107,26 +107,21 @@ static void gt_compare_set(unsigned long delta, int periodic)
 	writel(ctrl, gt_base + GT_CONTROL);
 }
 
-static void gt_clockevent_set_mode(enum clock_event_mode mode,
-				   struct clock_event_device *clk)
+static int gt_clockevent_shutdown(struct clock_event_device *evt)
 {
 	unsigned long ctrl;
 
-	switch (mode) {
-	case CLOCK_EVT_MODE_PERIODIC:
-		gt_compare_set(DIV_ROUND_CLOSEST(gt_clk_rate, HZ), 1);
-		break;
-	case CLOCK_EVT_MODE_ONESHOT:
-	case CLOCK_EVT_MODE_UNUSED:
-	case CLOCK_EVT_MODE_SHUTDOWN:
-		ctrl = readl(gt_base + GT_CONTROL);
-		ctrl &= ~(GT_CONTROL_COMP_ENABLE |
-				GT_CONTROL_IRQ_ENABLE | GT_CONTROL_AUTO_INC);
-		writel(ctrl, gt_base + GT_CONTROL);
-		break;
-	default:
-		break;
-	}
+	ctrl = readl(gt_base + GT_CONTROL);
+	ctrl &= ~(GT_CONTROL_COMP_ENABLE | GT_CONTROL_IRQ_ENABLE |
+		  GT_CONTROL_AUTO_INC);
+	writel(ctrl, gt_base + GT_CONTROL);
+	return 0;
+}
+
+static int gt_clockevent_set_periodic(struct clock_event_device *evt)
+{
+	gt_compare_set(DIV_ROUND_CLOSEST(gt_clk_rate, HZ), 1);
+	return 0;
 }
 
 static int gt_clockevent_set_next_event(unsigned long evt,
@@ -155,7 +150,7 @@ static irqreturn_t gt_clockevent_interrupt(int irq, void *dev_id)
 	 *	the Global Timer flag _after_ having incremented
 	 *	the Comparator register	value to a higher value.
 	 */
-	if (evt->mode == CLOCK_EVT_MODE_ONESHOT)
+	if (clockevent_state_oneshot(evt))
 		gt_compare_set(ULONG_MAX, 0);
 
 	writel_relaxed(GT_INT_STATUS_EVENT_FLAG, gt_base + GT_INT_STATUS);
@@ -171,7 +166,9 @@ static int gt_clockevents_init(struct clock_event_device *clk)
 	clk->name = "arm_global_timer";
 	clk->features = CLOCK_EVT_FEAT_PERIODIC | CLOCK_EVT_FEAT_ONESHOT |
 		CLOCK_EVT_FEAT_PERCPU;
-	clk->set_mode = gt_clockevent_set_mode;
+	clk->set_state_shutdown = gt_clockevent_shutdown;
+	clk->set_state_periodic = gt_clockevent_set_periodic;
+	clk->set_state_oneshot = gt_clockevent_shutdown;
 	clk->set_next_event = gt_clockevent_set_next_event;
 	clk->cpumask = cpumask_of(cpu);
 	clk->rating = 300;
@@ -184,7 +181,7 @@ static int gt_clockevents_init(struct clock_event_device *clk)
 
 static void gt_clockevents_stop(struct clock_event_device *clk)
 {
-	gt_clockevent_set_mode(CLOCK_EVT_MODE_UNUSED, clk);
+	gt_clockevent_shutdown(clk);
 	disable_percpu_irq(clk->irq);
 }
 
-- 
1.9.1



From daniel.lezcano at linaro.org  Mon Aug 10 02:51:25 2015
From: daniel.lezcano at linaro.org (Daniel Lezcano)
Date: Mon, 10 Aug 2015 11:51:25 +0200
Subject: [PATCH 08/74] clockevents/drivers/exynos_mct: Remove unneeded
 container_of()
In-Reply-To: <1439200352-26767-1-git-send-email-daniel.lezcano@linaro.org>
References: <55C87382.4070309@linaro.org>
 <1439200352-26767-1-git-send-email-daniel.lezcano@linaro.org>
Message-ID: <1439200352-26767-8-git-send-email-daniel.lezcano@linaro.org>

From: Alexey Klimov <klimov.linux at gmail.com>

Patch removes unneeded container_of() macro in exynos4_local_timer_setup().
Instead let's pass mevt pointer to setup and stop functions from
exynos4_mct_cpu_notify() and let them get evt pointer.

Tested on odroid-xu3.

Signed-off-by: Alexey Klimov <klimov.linux at gmail.com>
Acked-by: Stephen Boyd <sboyd at codeaurora.org>
Signed-off-by: Daniel Lezcano <daniel.lezcano at linaro.org>
Reviewed-by: Krzysztof Kozlowski <k.kozlowski at samsung.com>
---
 drivers/clocksource/exynos_mct.c | 16 ++++++++--------
 1 file changed, 8 insertions(+), 8 deletions(-)

diff --git a/drivers/clocksource/exynos_mct.c b/drivers/clocksource/exynos_mct.c
index 9064ff7..4d2330a 100644
--- a/drivers/clocksource/exynos_mct.c
+++ b/drivers/clocksource/exynos_mct.c
@@ -442,13 +442,11 @@ static irqreturn_t exynos4_mct_tick_isr(int irq, void *dev_id)
 	return IRQ_HANDLED;
 }
 
-static int exynos4_local_timer_setup(struct clock_event_device *evt)
+static int exynos4_local_timer_setup(struct mct_clock_event_device *mevt)
 {
-	struct mct_clock_event_device *mevt;
+	struct clock_event_device *evt = &mevt->evt;
 	unsigned int cpu = smp_processor_id();
 
-	mevt = container_of(evt, struct mct_clock_event_device, evt);
-
 	mevt->base = EXYNOS4_MCT_L_BASE(cpu);
 	snprintf(mevt->name, sizeof(mevt->name), "mct_tick%d", cpu);
 
@@ -477,8 +475,10 @@ static int exynos4_local_timer_setup(struct clock_event_device *evt)
 	return 0;
 }
 
-static void exynos4_local_timer_stop(struct clock_event_device *evt)
+static void exynos4_local_timer_stop(struct mct_clock_event_device *mevt)
 {
+	struct clock_event_device *evt = &mevt->evt;
+
 	evt->set_mode(CLOCK_EVT_MODE_UNUSED, evt);
 	if (mct_int_type == MCT_INT_SPI) {
 		if (evt->irq != -1)
@@ -500,11 +500,11 @@ static int exynos4_mct_cpu_notify(struct notifier_block *self,
 	switch (action & ~CPU_TASKS_FROZEN) {
 	case CPU_STARTING:
 		mevt = this_cpu_ptr(&percpu_mct_tick);
-		exynos4_local_timer_setup(&mevt->evt);
+		exynos4_local_timer_setup(mevt);
 		break;
 	case CPU_DYING:
 		mevt = this_cpu_ptr(&percpu_mct_tick);
-		exynos4_local_timer_stop(&mevt->evt);
+		exynos4_local_timer_stop(mevt);
 		break;
 	}
 
@@ -570,7 +570,7 @@ static void __init exynos4_timer_resources(struct device_node *np, void __iomem
 		goto out_irq;
 
 	/* Immediately configure the timer on the boot CPU */
-	exynos4_local_timer_setup(&mevt->evt);
+	exynos4_local_timer_setup(mevt);
 	return;
 
 out_irq:
-- 
1.9.1



From daniel.lezcano at linaro.org  Mon Aug 10 02:51:30 2015
From: daniel.lezcano at linaro.org (Daniel Lezcano)
Date: Mon, 10 Aug 2015 11:51:30 +0200
Subject: [PATCH 13/74] clockevents/drivers/clps711x: Migrate to new
 'set-state' interface
In-Reply-To: <1439200352-26767-1-git-send-email-daniel.lezcano@linaro.org>
References: <55C87382.4070309@linaro.org>
 <1439200352-26767-1-git-send-email-daniel.lezcano@linaro.org>
Message-ID: <1439200352-26767-13-git-send-email-daniel.lezcano@linaro.org>

From: Viresh Kumar <viresh.kumar at linaro.org>

Migrate clps711x driver to the new 'set-state' interface provided by
clockevents core, the earlier 'set-mode' interface is marked obsolete
now.

This also enables us to implement callbacks for new states of clockevent
devices, for example: ONESHOT_STOPPED.

We weren't doing anything in the ->set_mode() callback. So, this patch
doesn't provide any set-state callbacks.

Cc: Alexander Shiyan <shc_work at mail.ru>
Signed-off-by: Viresh Kumar <viresh.kumar at linaro.org>
Signed-off-by: Daniel Lezcano <daniel.lezcano at linaro.org>
---
 drivers/clocksource/clps711x-timer.c | 6 ------
 1 file changed, 6 deletions(-)

diff --git a/drivers/clocksource/clps711x-timer.c b/drivers/clocksource/clps711x-timer.c
index d83ec1f..cdd86e3 100644
--- a/drivers/clocksource/clps711x-timer.c
+++ b/drivers/clocksource/clps711x-timer.c
@@ -61,11 +61,6 @@ static irqreturn_t clps711x_timer_interrupt(int irq, void *dev_id)
 	return IRQ_HANDLED;
 }
 
-static void clps711x_clockevent_set_mode(enum clock_event_mode mode,
-					 struct clock_event_device *evt)
-{
-}
-
 static int __init _clps711x_clkevt_init(struct clk *clock, void __iomem *base,
 					unsigned int irq)
 {
@@ -91,7 +86,6 @@ static int __init _clps711x_clkevt_init(struct clk *clock, void __iomem *base,
 	clkevt->name = "clps711x-clockevent";
 	clkevt->rating = 300;
 	clkevt->features = CLOCK_EVT_FEAT_PERIODIC | CLOCK_EVT_FEAT_C3STOP;
-	clkevt->set_mode = clps711x_clockevent_set_mode;
 	clkevt->cpumask = cpumask_of(0);
 	clockevents_config_and_register(clkevt, HZ, 0, 0);
 
-- 
1.9.1



From daniel.lezcano at linaro.org  Mon Aug 10 02:51:29 2015
From: daniel.lezcano at linaro.org (Daniel Lezcano)
Date: Mon, 10 Aug 2015 11:51:29 +0200
Subject: [PATCH 12/74] clockevents/drivers/cadence_ttc: Migrate to new
 'set-state' interface
In-Reply-To: <1439200352-26767-1-git-send-email-daniel.lezcano@linaro.org>
References: <55C87382.4070309@linaro.org>
 <1439200352-26767-1-git-send-email-daniel.lezcano@linaro.org>
Message-ID: <1439200352-26767-12-git-send-email-daniel.lezcano@linaro.org>

From: Viresh Kumar <viresh.kumar at linaro.org>

Migrate cadence_ttc driver to the new 'set-state' interface provided by
clockevents core, the earlier 'set-mode' interface is marked obsolete
now.

This also enables us to implement callbacks for new states of clockevent
devices, for example: ONESHOT_STOPPED.

Cc: Michal Simek <michal.simek at xilinx.com>
Cc: S?ren Brinkmann <soren.brinkmann at xilinx.com>
Signed-off-by: Viresh Kumar <viresh.kumar at linaro.org>
Signed-off-by: Daniel Lezcano <daniel.lezcano at linaro.org>
Tested-by: S?ren Brinkmann <soren.brinkmann at xilinx.com>
---
 drivers/clocksource/cadence_ttc_timer.c | 59 ++++++++++++++++++---------------
 1 file changed, 32 insertions(+), 27 deletions(-)

diff --git a/drivers/clocksource/cadence_ttc_timer.c b/drivers/clocksource/cadence_ttc_timer.c
index 510c8a1..e47e0e0 100644
--- a/drivers/clocksource/cadence_ttc_timer.c
+++ b/drivers/clocksource/cadence_ttc_timer.c
@@ -191,40 +191,42 @@ static int ttc_set_next_event(unsigned long cycles,
 }
 
 /**
- * ttc_set_mode - Sets the mode of timer
+ * ttc_set_{shutdown|oneshot|periodic} - Sets the state of timer
  *
- * @mode:	Mode to be set
  * @evt:	Address of clock event instance
  **/
-static void ttc_set_mode(enum clock_event_mode mode,
-					struct clock_event_device *evt)
+static int ttc_shutdown(struct clock_event_device *evt)
 {
 	struct ttc_timer_clockevent *ttce = to_ttc_timer_clkevent(evt);
 	struct ttc_timer *timer = &ttce->ttc;
 	u32 ctrl_reg;
 
-	switch (mode) {
-	case CLOCK_EVT_MODE_PERIODIC:
-		ttc_set_interval(timer, DIV_ROUND_CLOSEST(ttce->ttc.freq,
-						PRESCALE * HZ));
-		break;
-	case CLOCK_EVT_MODE_ONESHOT:
-	case CLOCK_EVT_MODE_UNUSED:
-	case CLOCK_EVT_MODE_SHUTDOWN:
-		ctrl_reg = readl_relaxed(timer->base_addr +
-					TTC_CNT_CNTRL_OFFSET);
-		ctrl_reg |= TTC_CNT_CNTRL_DISABLE_MASK;
-		writel_relaxed(ctrl_reg,
-				timer->base_addr + TTC_CNT_CNTRL_OFFSET);
-		break;
-	case CLOCK_EVT_MODE_RESUME:
-		ctrl_reg = readl_relaxed(timer->base_addr +
-					TTC_CNT_CNTRL_OFFSET);
-		ctrl_reg &= ~TTC_CNT_CNTRL_DISABLE_MASK;
-		writel_relaxed(ctrl_reg,
-				timer->base_addr + TTC_CNT_CNTRL_OFFSET);
-		break;
-	}
+	ctrl_reg = readl_relaxed(timer->base_addr + TTC_CNT_CNTRL_OFFSET);
+	ctrl_reg |= TTC_CNT_CNTRL_DISABLE_MASK;
+	writel_relaxed(ctrl_reg, timer->base_addr + TTC_CNT_CNTRL_OFFSET);
+	return 0;
+}
+
+static int ttc_set_periodic(struct clock_event_device *evt)
+{
+	struct ttc_timer_clockevent *ttce = to_ttc_timer_clkevent(evt);
+	struct ttc_timer *timer = &ttce->ttc;
+
+	ttc_set_interval(timer,
+			 DIV_ROUND_CLOSEST(ttce->ttc.freq, PRESCALE * HZ));
+	return 0;
+}
+
+static int ttc_resume(struct clock_event_device *evt)
+{
+	struct ttc_timer_clockevent *ttce = to_ttc_timer_clkevent(evt);
+	struct ttc_timer *timer = &ttce->ttc;
+	u32 ctrl_reg;
+
+	ctrl_reg = readl_relaxed(timer->base_addr + TTC_CNT_CNTRL_OFFSET);
+	ctrl_reg &= ~TTC_CNT_CNTRL_DISABLE_MASK;
+	writel_relaxed(ctrl_reg, timer->base_addr + TTC_CNT_CNTRL_OFFSET);
+	return 0;
 }
 
 static int ttc_rate_change_clocksource_cb(struct notifier_block *nb,
@@ -430,7 +432,10 @@ static void __init ttc_setup_clockevent(struct clk *clk,
 	ttcce->ce.name = "ttc_clockevent";
 	ttcce->ce.features = CLOCK_EVT_FEAT_PERIODIC | CLOCK_EVT_FEAT_ONESHOT;
 	ttcce->ce.set_next_event = ttc_set_next_event;
-	ttcce->ce.set_mode = ttc_set_mode;
+	ttcce->ce.set_state_shutdown = ttc_shutdown;
+	ttcce->ce.set_state_periodic = ttc_set_periodic;
+	ttcce->ce.set_state_oneshot = ttc_shutdown;
+	ttcce->ce.tick_resume = ttc_resume;
 	ttcce->ce.rating = 200;
 	ttcce->ce.irq = irq;
 	ttcce->ce.cpumask = cpu_possible_mask;
-- 
1.9.1



From daniel.lezcano at linaro.org  Mon Aug 10 02:51:35 2015
From: daniel.lezcano at linaro.org (Daniel Lezcano)
Date: Mon, 10 Aug 2015 11:51:35 +0200
Subject: [PATCH 18/74] clockevents/drivers/meson6: Migrate to new 'set-state'
 interface
In-Reply-To: <1439200352-26767-1-git-send-email-daniel.lezcano@linaro.org>
References: <55C87382.4070309@linaro.org>
 <1439200352-26767-1-git-send-email-daniel.lezcano@linaro.org>
Message-ID: <1439200352-26767-18-git-send-email-daniel.lezcano@linaro.org>

From: Viresh Kumar <viresh.kumar at linaro.org>

Migrate meson6 driver to the new 'set-state' interface provided by
clockevents core, the earlier 'set-mode' interface is marked obsolete
now.

This also enables us to implement callbacks for new states of clockevent
devices, for example: ONESHOT_STOPPED.

Cc: Carlo Caione <carlo at caione.org>
Signed-off-by: Viresh Kumar <viresh.kumar at linaro.org>
Signed-off-by: Daniel Lezcano <daniel.lezcano at linaro.org>
Acked-by: Carlo Caione <carlo at caione.org>
---
 drivers/clocksource/meson6_timer.c | 50 ++++++++++++++++++++------------------
 1 file changed, 27 insertions(+), 23 deletions(-)

diff --git a/drivers/clocksource/meson6_timer.c b/drivers/clocksource/meson6_timer.c
index 5c15cba..1fa22c4 100644
--- a/drivers/clocksource/meson6_timer.c
+++ b/drivers/clocksource/meson6_timer.c
@@ -67,25 +67,25 @@ static void meson6_clkevt_time_start(unsigned char timer, bool periodic)
 	writel(val | TIMER_ENABLE_BIT(timer), timer_base + TIMER_ISA_MUX);
 }
 
-static void meson6_clkevt_mode(enum clock_event_mode mode,
-			       struct clock_event_device *clk)
+static int meson6_shutdown(struct clock_event_device *evt)
 {
-	switch (mode) {
-	case CLOCK_EVT_MODE_PERIODIC:
-		meson6_clkevt_time_stop(CED_ID);
-		meson6_clkevt_time_setup(CED_ID, USEC_PER_SEC/HZ - 1);
-		meson6_clkevt_time_start(CED_ID, true);
-		break;
-	case CLOCK_EVT_MODE_ONESHOT:
-		meson6_clkevt_time_stop(CED_ID);
-		meson6_clkevt_time_start(CED_ID, false);
-		break;
-	case CLOCK_EVT_MODE_UNUSED:
-	case CLOCK_EVT_MODE_SHUTDOWN:
-	default:
-		meson6_clkevt_time_stop(CED_ID);
-		break;
-	}
+	meson6_clkevt_time_stop(CED_ID);
+	return 0;
+}
+
+static int meson6_set_oneshot(struct clock_event_device *evt)
+{
+	meson6_clkevt_time_stop(CED_ID);
+	meson6_clkevt_time_start(CED_ID, false);
+	return 0;
+}
+
+static int meson6_set_periodic(struct clock_event_device *evt)
+{
+	meson6_clkevt_time_stop(CED_ID);
+	meson6_clkevt_time_setup(CED_ID, USEC_PER_SEC / HZ - 1);
+	meson6_clkevt_time_start(CED_ID, true);
+	return 0;
 }
 
 static int meson6_clkevt_next_event(unsigned long evt,
@@ -99,11 +99,15 @@ static int meson6_clkevt_next_event(unsigned long evt,
 }
 
 static struct clock_event_device meson6_clockevent = {
-	.name		= "meson6_tick",
-	.rating		= 400,
-	.features	= CLOCK_EVT_FEAT_PERIODIC | CLOCK_EVT_FEAT_ONESHOT,
-	.set_mode	= meson6_clkevt_mode,
-	.set_next_event	= meson6_clkevt_next_event,
+	.name			= "meson6_tick",
+	.rating			= 400,
+	.features		= CLOCK_EVT_FEAT_PERIODIC |
+				  CLOCK_EVT_FEAT_ONESHOT,
+	.set_state_shutdown	= meson6_shutdown,
+	.set_state_periodic	= meson6_set_periodic,
+	.set_state_oneshot	= meson6_set_oneshot,
+	.tick_resume		= meson6_shutdown,
+	.set_next_event		= meson6_clkevt_next_event,
 };
 
 static irqreturn_t meson6_timer_interrupt(int irq, void *dev_id)
-- 
1.9.1



From daniel.lezcano at linaro.org  Mon Aug 10 02:51:44 2015
From: daniel.lezcano at linaro.org (Daniel Lezcano)
Date: Mon, 10 Aug 2015 11:51:44 +0200
Subject: [PATCH 27/74] clockevents/drivers/rockchip: Migrate to new
 'set-state' interface
In-Reply-To: <1439200352-26767-1-git-send-email-daniel.lezcano@linaro.org>
References: <55C87382.4070309@linaro.org>
 <1439200352-26767-1-git-send-email-daniel.lezcano@linaro.org>
Message-ID: <1439200352-26767-27-git-send-email-daniel.lezcano@linaro.org>

From: Viresh Kumar <viresh.kumar at linaro.org>

Migrate rockchip driver to the new 'set-state' interface provided by
clockevents core, the earlier 'set-mode' interface is marked obsolete
now.

This also enables us to implement callbacks for new states of clockevent
devices, for example: ONESHOT_STOPPED.

We weren't doing anything for oneshot or resume modes, and so the
callbacks aren't provided.

Cc: Heiko Stuebner <heiko at sntech.de>
Signed-off-by: Viresh Kumar <viresh.kumar at linaro.org>
Signed-off-by: Daniel Lezcano <daniel.lezcano at linaro.org>
---
 drivers/clocksource/rockchip_timer.c | 32 ++++++++++++++------------------
 1 file changed, 14 insertions(+), 18 deletions(-)

diff --git a/drivers/clocksource/rockchip_timer.c b/drivers/clocksource/rockchip_timer.c
index a35993b..bb2c2b0 100644
--- a/drivers/clocksource/rockchip_timer.c
+++ b/drivers/clocksource/rockchip_timer.c
@@ -82,23 +82,18 @@ static inline int rk_timer_set_next_event(unsigned long cycles,
 	return 0;
 }
 
-static inline void rk_timer_set_mode(enum clock_event_mode mode,
-				     struct clock_event_device *ce)
+static int rk_timer_shutdown(struct clock_event_device *ce)
 {
-	switch (mode) {
-	case CLOCK_EVT_MODE_PERIODIC:
-		rk_timer_disable(ce);
-		rk_timer_update_counter(rk_timer(ce)->freq / HZ - 1, ce);
-		rk_timer_enable(ce, TIMER_MODE_FREE_RUNNING);
-		break;
-	case CLOCK_EVT_MODE_ONESHOT:
-	case CLOCK_EVT_MODE_RESUME:
-		break;
-	case CLOCK_EVT_MODE_UNUSED:
-	case CLOCK_EVT_MODE_SHUTDOWN:
-		rk_timer_disable(ce);
-		break;
-	}
+	rk_timer_disable(ce);
+	return 0;
+}
+
+static int rk_timer_set_periodic(struct clock_event_device *ce)
+{
+	rk_timer_disable(ce);
+	rk_timer_update_counter(rk_timer(ce)->freq / HZ - 1, ce);
+	rk_timer_enable(ce, TIMER_MODE_FREE_RUNNING);
+	return 0;
 }
 
 static irqreturn_t rk_timer_interrupt(int irq, void *dev_id)
@@ -107,7 +102,7 @@ static irqreturn_t rk_timer_interrupt(int irq, void *dev_id)
 
 	rk_timer_interrupt_clear(ce);
 
-	if (ce->mode == CLOCK_EVT_MODE_ONESHOT)
+	if (clockevent_state_oneshot(ce))
 		rk_timer_disable(ce);
 
 	ce->event_handler(ce);
@@ -161,7 +156,8 @@ static void __init rk_timer_init(struct device_node *np)
 	ce->name = TIMER_NAME;
 	ce->features = CLOCK_EVT_FEAT_PERIODIC | CLOCK_EVT_FEAT_ONESHOT;
 	ce->set_next_event = rk_timer_set_next_event;
-	ce->set_mode = rk_timer_set_mode;
+	ce->set_state_shutdown = rk_timer_shutdown;
+	ce->set_state_periodic = rk_timer_set_periodic;
 	ce->irq = irq;
 	ce->cpumask = cpumask_of(0);
 	ce->rating = 250;
-- 
1.9.1



From daniel.lezcano at linaro.org  Mon Aug 10 02:51:49 2015
From: daniel.lezcano at linaro.org (Daniel Lezcano)
Date: Mon, 10 Aug 2015 11:51:49 +0200
Subject: [PATCH 32/74] clockevents/drivers/sun4i: Migrate to new 'set-state'
 interface
In-Reply-To: <1439200352-26767-1-git-send-email-daniel.lezcano@linaro.org>
References: <55C87382.4070309@linaro.org>
 <1439200352-26767-1-git-send-email-daniel.lezcano@linaro.org>
Message-ID: <1439200352-26767-32-git-send-email-daniel.lezcano@linaro.org>

From: Viresh Kumar <viresh.kumar at linaro.org>

Migrate sun4i driver to the new 'set-state' interface provided by
clockevents core, the earlier 'set-mode' interface is marked obsolete
now.

This also enables us to implement callbacks for new states of clockevent
devices, for example: ONESHOT_STOPPED.

Cc: Maxime Ripard <maxime.ripard at free-electrons.com>
Signed-off-by: Viresh Kumar <viresh.kumar at linaro.org>
Signed-off-by: Daniel Lezcano <daniel.lezcano at linaro.org>
Acked-by: Maxime Ripard <maxime.ripard at free-electrons.com>
---
 drivers/clocksource/sun4i_timer.c | 41 +++++++++++++++++++++------------------
 1 file changed, 22 insertions(+), 19 deletions(-)

diff --git a/drivers/clocksource/sun4i_timer.c b/drivers/clocksource/sun4i_timer.c
index 1928a89..6f3719d 100644
--- a/drivers/clocksource/sun4i_timer.c
+++ b/drivers/clocksource/sun4i_timer.c
@@ -81,25 +81,25 @@ static void sun4i_clkevt_time_start(u8 timer, bool periodic)
 	       timer_base + TIMER_CTL_REG(timer));
 }
 
-static void sun4i_clkevt_mode(enum clock_event_mode mode,
-			      struct clock_event_device *clk)
+static int sun4i_clkevt_shutdown(struct clock_event_device *evt)
 {
-	switch (mode) {
-	case CLOCK_EVT_MODE_PERIODIC:
-		sun4i_clkevt_time_stop(0);
-		sun4i_clkevt_time_setup(0, ticks_per_jiffy);
-		sun4i_clkevt_time_start(0, true);
-		break;
-	case CLOCK_EVT_MODE_ONESHOT:
-		sun4i_clkevt_time_stop(0);
-		sun4i_clkevt_time_start(0, false);
-		break;
-	case CLOCK_EVT_MODE_UNUSED:
-	case CLOCK_EVT_MODE_SHUTDOWN:
-	default:
-		sun4i_clkevt_time_stop(0);
-		break;
-	}
+	sun4i_clkevt_time_stop(0);
+	return 0;
+}
+
+static int sun4i_clkevt_set_oneshot(struct clock_event_device *evt)
+{
+	sun4i_clkevt_time_stop(0);
+	sun4i_clkevt_time_start(0, false);
+	return 0;
+}
+
+static int sun4i_clkevt_set_periodic(struct clock_event_device *evt)
+{
+	sun4i_clkevt_time_stop(0);
+	sun4i_clkevt_time_setup(0, ticks_per_jiffy);
+	sun4i_clkevt_time_start(0, true);
+	return 0;
 }
 
 static int sun4i_clkevt_next_event(unsigned long evt,
@@ -116,7 +116,10 @@ static struct clock_event_device sun4i_clockevent = {
 	.name = "sun4i_tick",
 	.rating = 350,
 	.features = CLOCK_EVT_FEAT_PERIODIC | CLOCK_EVT_FEAT_ONESHOT,
-	.set_mode = sun4i_clkevt_mode,
+	.set_state_shutdown = sun4i_clkevt_shutdown,
+	.set_state_periodic = sun4i_clkevt_set_periodic,
+	.set_state_oneshot = sun4i_clkevt_set_oneshot,
+	.tick_resume = sun4i_clkevt_shutdown,
 	.set_next_event = sun4i_clkevt_next_event,
 };
 
-- 
1.9.1



From daniel.lezcano at linaro.org  Mon Aug 10 02:51:52 2015
From: daniel.lezcano at linaro.org (Daniel Lezcano)
Date: Mon, 10 Aug 2015 11:51:52 +0200
Subject: [PATCH 35/74] clockevents/drivers/efm32: Migrate to new 'set-state'
 interface
In-Reply-To: <1439200352-26767-1-git-send-email-daniel.lezcano@linaro.org>
References: <55C87382.4070309@linaro.org>
 <1439200352-26767-1-git-send-email-daniel.lezcano@linaro.org>
Message-ID: <1439200352-26767-35-git-send-email-daniel.lezcano@linaro.org>

From: Viresh Kumar <viresh.kumar at linaro.org>

Migrate efm32 driver to the new 'set-state' interface provided by
clockevents core, the earlier 'set-mode' interface is marked obsolete
now.

This also enables us to implement callbacks for new states of clockevent
devices, for example: ONESHOT_STOPPED.

There is nothing to be done for resume state and so isn't implemented.

Cc: Uwe Kleine-K?nig <kernel at pengutronix.de>
Signed-off-by: Viresh Kumar <viresh.kumar at linaro.org>
Signed-off-by: Daniel Lezcano <daniel.lezcano at linaro.org>
---
 drivers/clocksource/time-efm32.c | 66 +++++++++++++++++++++-------------------
 1 file changed, 35 insertions(+), 31 deletions(-)

diff --git a/drivers/clocksource/time-efm32.c b/drivers/clocksource/time-efm32.c
index 5b6e3d5..b06e4c2 100644
--- a/drivers/clocksource/time-efm32.c
+++ b/drivers/clocksource/time-efm32.c
@@ -48,40 +48,42 @@ struct efm32_clock_event_ddata {
 	unsigned periodic_top;
 };
 
-static void efm32_clock_event_set_mode(enum clock_event_mode mode,
-				       struct clock_event_device *evtdev)
+static int efm32_clock_event_shutdown(struct clock_event_device *evtdev)
 {
 	struct efm32_clock_event_ddata *ddata =
 		container_of(evtdev, struct efm32_clock_event_ddata, evtdev);
 
-	switch (mode) {
-	case CLOCK_EVT_MODE_PERIODIC:
-		writel_relaxed(TIMERn_CMD_STOP, ddata->base + TIMERn_CMD);
-		writel_relaxed(ddata->periodic_top, ddata->base + TIMERn_TOP);
-		writel_relaxed(TIMERn_CTRL_PRESC_1024 |
-			       TIMERn_CTRL_CLKSEL_PRESCHFPERCLK |
-			       TIMERn_CTRL_MODE_DOWN,
-			       ddata->base + TIMERn_CTRL);
-		writel_relaxed(TIMERn_CMD_START, ddata->base + TIMERn_CMD);
-		break;
-
-	case CLOCK_EVT_MODE_ONESHOT:
-		writel_relaxed(TIMERn_CMD_STOP, ddata->base + TIMERn_CMD);
-		writel_relaxed(TIMERn_CTRL_PRESC_1024 |
-			       TIMERn_CTRL_CLKSEL_PRESCHFPERCLK |
-			       TIMERn_CTRL_OSMEN |
-			       TIMERn_CTRL_MODE_DOWN,
-			       ddata->base + TIMERn_CTRL);
-		break;
-
-	case CLOCK_EVT_MODE_UNUSED:
-	case CLOCK_EVT_MODE_SHUTDOWN:
-		writel_relaxed(TIMERn_CMD_STOP, ddata->base + TIMERn_CMD);
-		break;
-
-	case CLOCK_EVT_MODE_RESUME:
-		break;
-	}
+	writel_relaxed(TIMERn_CMD_STOP, ddata->base + TIMERn_CMD);
+	return 0;
+}
+
+static int efm32_clock_event_set_oneshot(struct clock_event_device *evtdev)
+{
+	struct efm32_clock_event_ddata *ddata =
+		container_of(evtdev, struct efm32_clock_event_ddata, evtdev);
+
+	writel_relaxed(TIMERn_CMD_STOP, ddata->base + TIMERn_CMD);
+	writel_relaxed(TIMERn_CTRL_PRESC_1024 |
+		       TIMERn_CTRL_CLKSEL_PRESCHFPERCLK |
+		       TIMERn_CTRL_OSMEN |
+		       TIMERn_CTRL_MODE_DOWN,
+		       ddata->base + TIMERn_CTRL);
+	return 0;
+}
+
+static int efm32_clock_event_set_periodic(struct clock_event_device *evtdev)
+{
+	struct efm32_clock_event_ddata *ddata =
+		container_of(evtdev, struct efm32_clock_event_ddata, evtdev);
+
+	writel_relaxed(TIMERn_CMD_STOP, ddata->base + TIMERn_CMD);
+	writel_relaxed(ddata->periodic_top, ddata->base + TIMERn_TOP);
+	writel_relaxed(TIMERn_CTRL_PRESC_1024 |
+		       TIMERn_CTRL_CLKSEL_PRESCHFPERCLK |
+		       TIMERn_CTRL_MODE_DOWN,
+		       ddata->base + TIMERn_CTRL);
+	writel_relaxed(TIMERn_CMD_START, ddata->base + TIMERn_CMD);
+	return 0;
 }
 
 static int efm32_clock_event_set_next_event(unsigned long evt,
@@ -112,7 +114,9 @@ static struct efm32_clock_event_ddata clock_event_ddata = {
 	.evtdev = {
 		.name = "efm32 clockevent",
 		.features = CLOCK_EVT_FEAT_ONESHOT | CLOCK_EVT_FEAT_PERIODIC,
-		.set_mode = efm32_clock_event_set_mode,
+		.set_state_shutdown = efm32_clock_event_shutdown,
+		.set_state_periodic = efm32_clock_event_set_periodic,
+		.set_state_oneshot = efm32_clock_event_set_oneshot,
 		.set_next_event = efm32_clock_event_set_next_event,
 		.rating = 200,
 	},
-- 
1.9.1



From daniel.lezcano at linaro.org  Mon Aug 10 02:51:54 2015
From: daniel.lezcano at linaro.org (Daniel Lezcano)
Date: Mon, 10 Aug 2015 11:51:54 +0200
Subject: [PATCH 37/74] clockevents/drivers/atlas7: Migrate to new 'set-state'
 interface
In-Reply-To: <1439200352-26767-1-git-send-email-daniel.lezcano@linaro.org>
References: <55C87382.4070309@linaro.org>
 <1439200352-26767-1-git-send-email-daniel.lezcano@linaro.org>
Message-ID: <1439200352-26767-37-git-send-email-daniel.lezcano@linaro.org>

From: Viresh Kumar <viresh.kumar at linaro.org>

Migrate atlas7 driver to the new 'set-state' interface provided by
clockevents core, the earlier 'set-mode' interface is marked obsolete
now.

This also enables us to implement callbacks for new states of clockevent
devices, for example: ONESHOT_STOPPED.

Cc: Barry Song <baohua at kernel.org>
Signed-off-by: Viresh Kumar <viresh.kumar at linaro.org>
Signed-off-by: Daniel Lezcano <daniel.lezcano at linaro.org>
---
 drivers/clocksource/timer-atlas7.c | 19 +++++++------------
 1 file changed, 7 insertions(+), 12 deletions(-)

diff --git a/drivers/clocksource/timer-atlas7.c b/drivers/clocksource/timer-atlas7.c
index 60f9de3..27fa136 100644
--- a/drivers/clocksource/timer-atlas7.c
+++ b/drivers/clocksource/timer-atlas7.c
@@ -76,7 +76,7 @@ static irqreturn_t sirfsoc_timer_interrupt(int irq, void *dev_id)
 	/* clear timer interrupt */
 	writel_relaxed(BIT(cpu), sirfsoc_timer_base + SIRFSOC_TIMER_INTR_STATUS);
 
-	if (ce->mode == CLOCK_EVT_MODE_ONESHOT)
+	if (clockevent_state_oneshot(ce))
 		sirfsoc_timer_count_disable(cpu);
 
 	ce->event_handler(ce);
@@ -117,18 +117,11 @@ static int sirfsoc_timer_set_next_event(unsigned long delta,
 	return 0;
 }
 
-static void sirfsoc_timer_set_mode(enum clock_event_mode mode,
-	struct clock_event_device *ce)
+/* Oneshot is enabled in set_next_event */
+static int sirfsoc_timer_shutdown(struct clock_event_device *evt)
 {
-	switch (mode) {
-	case CLOCK_EVT_MODE_ONESHOT:
-		/* enable in set_next_event */
-		break;
-	default:
-		break;
-	}
-
 	sirfsoc_timer_count_disable(smp_processor_id());
+	return 0;
 }
 
 static void sirfsoc_clocksource_suspend(struct clocksource *cs)
@@ -193,7 +186,9 @@ static int sirfsoc_local_timer_setup(struct clock_event_device *ce)
 	ce->name = "local_timer";
 	ce->features = CLOCK_EVT_FEAT_ONESHOT;
 	ce->rating = 200;
-	ce->set_mode = sirfsoc_timer_set_mode;
+	ce->set_state_shutdown = sirfsoc_timer_shutdown;
+	ce->set_state_oneshot = sirfsoc_timer_shutdown;
+	ce->tick_resume = sirfsoc_timer_shutdown;
 	ce->set_next_event = sirfsoc_timer_set_next_event;
 	clockevents_calc_mult_shift(ce, atlas7_timer_rate, 60);
 	ce->max_delta_ns = clockevent_delta2ns(-2, ce);
-- 
1.9.1



From daniel.lezcano at linaro.org  Mon Aug 10 02:51:57 2015
From: daniel.lezcano at linaro.org (Daniel Lezcano)
Date: Mon, 10 Aug 2015 11:51:57 +0200
Subject: [PATCH 40/74] clockevents/drivers/digicolor: Migrate to new
 'set-state' interface
In-Reply-To: <1439200352-26767-1-git-send-email-daniel.lezcano@linaro.org>
References: <55C87382.4070309@linaro.org>
 <1439200352-26767-1-git-send-email-daniel.lezcano@linaro.org>
Message-ID: <1439200352-26767-40-git-send-email-daniel.lezcano@linaro.org>

From: Viresh Kumar <viresh.kumar at linaro.org>

Migrate digicolor driver to the new 'set-state' interface provided by
clockevents core, the earlier 'set-mode' interface is marked obsolete
now.

This also enables us to implement callbacks for new states of clockevent
devices, for example: ONESHOT_STOPPED.

Cc: Baruch Siach <baruch at tkos.co.il>
Signed-off-by: Viresh Kumar <viresh.kumar at linaro.org>
Signed-off-by: Daniel Lezcano <daniel.lezcano at linaro.org>
Acked-by: Baruch Siach <baruch at tkos.co.il>
Tested-by: Baruch Siach <baruch at tkos.co.il>
---
 drivers/clocksource/timer-digicolor.c | 41 +++++++++++++++++++----------------
 1 file changed, 22 insertions(+), 19 deletions(-)

diff --git a/drivers/clocksource/timer-digicolor.c b/drivers/clocksource/timer-digicolor.c
index 7f8388c..e73947f0f 100644
--- a/drivers/clocksource/timer-digicolor.c
+++ b/drivers/clocksource/timer-digicolor.c
@@ -87,27 +87,27 @@ static inline void dc_timer_set_count(struct clock_event_device *ce,
 	writel(count, dt->base + COUNT(dt->timer_id));
 }
 
-static void digicolor_clkevt_mode(enum clock_event_mode mode,
-				  struct clock_event_device *ce)
+static int digicolor_clkevt_shutdown(struct clock_event_device *ce)
+{
+	dc_timer_disable(ce);
+	return 0;
+}
+
+static int digicolor_clkevt_set_oneshot(struct clock_event_device *ce)
+{
+	dc_timer_disable(ce);
+	dc_timer_enable(ce, CONTROL_MODE_ONESHOT);
+	return 0;
+}
+
+static int digicolor_clkevt_set_periodic(struct clock_event_device *ce)
 {
 	struct digicolor_timer *dt = dc_timer(ce);
 
-	switch (mode) {
-	case CLOCK_EVT_MODE_PERIODIC:
-		dc_timer_disable(ce);
-		dc_timer_set_count(ce, dt->ticks_per_jiffy);
-		dc_timer_enable(ce, CONTROL_MODE_PERIODIC);
-		break;
-	case CLOCK_EVT_MODE_ONESHOT:
-		dc_timer_disable(ce);
-		dc_timer_enable(ce, CONTROL_MODE_ONESHOT);
-		break;
-	case CLOCK_EVT_MODE_UNUSED:
-	case CLOCK_EVT_MODE_SHUTDOWN:
-	default:
-		dc_timer_disable(ce);
-		break;
-	}
+	dc_timer_disable(ce);
+	dc_timer_set_count(ce, dt->ticks_per_jiffy);
+	dc_timer_enable(ce, CONTROL_MODE_PERIODIC);
+	return 0;
 }
 
 static int digicolor_clkevt_next_event(unsigned long evt,
@@ -125,7 +125,10 @@ static struct digicolor_timer dc_timer_dev = {
 		.name = "digicolor_tick",
 		.rating = 340,
 		.features = CLOCK_EVT_FEAT_PERIODIC | CLOCK_EVT_FEAT_ONESHOT,
-		.set_mode = digicolor_clkevt_mode,
+		.set_state_shutdown = digicolor_clkevt_shutdown,
+		.set_state_periodic = digicolor_clkevt_set_periodic,
+		.set_state_oneshot = digicolor_clkevt_set_oneshot,
+		.tick_resume = digicolor_clkevt_shutdown,
 		.set_next_event = digicolor_clkevt_next_event,
 	},
 	.timer_id = TIMER_C,
-- 
1.9.1



From daniel.lezcano at linaro.org  Mon Aug 10 02:51:39 2015
From: daniel.lezcano at linaro.org (Daniel Lezcano)
Date: Mon, 10 Aug 2015 11:51:39 +0200
Subject: [PATCH 22/74] clockevents/drivers/mtk: Migrate to new 'set-state'
 interface
In-Reply-To: <1439200352-26767-1-git-send-email-daniel.lezcano@linaro.org>
References: <55C87382.4070309@linaro.org>
 <1439200352-26767-1-git-send-email-daniel.lezcano@linaro.org>
Message-ID: <1439200352-26767-22-git-send-email-daniel.lezcano@linaro.org>

From: Viresh Kumar <viresh.kumar at linaro.org>

Migrate mtk driver to the new 'set-state' interface provided by
clockevents core, the earlier 'set-mode' interface is marked obsolete
now.

This also enables us to implement callbacks for new states of clockevent
devices, for example: ONESHOT_STOPPED.

Cc: Matthias Brugger <matthias.bgg at gmail.com>
Signed-off-by: Viresh Kumar <viresh.kumar at linaro.org>
Signed-off-by: Daniel Lezcano <daniel.lezcano at linaro.org>
---
 drivers/clocksource/mtk_timer.c | 32 ++++++++++++++------------------
 1 file changed, 14 insertions(+), 18 deletions(-)

diff --git a/drivers/clocksource/mtk_timer.c b/drivers/clocksource/mtk_timer.c
index 68ab423..50f0641 100644
--- a/drivers/clocksource/mtk_timer.c
+++ b/drivers/clocksource/mtk_timer.c
@@ -102,27 +102,20 @@ static void mtk_clkevt_time_start(struct mtk_clock_event_device *evt,
 	       evt->gpt_base + TIMER_CTRL_REG(timer));
 }
 
-static void mtk_clkevt_mode(enum clock_event_mode mode,
-				struct clock_event_device *clk)
+static int mtk_clkevt_shutdown(struct clock_event_device *clk)
+{
+	mtk_clkevt_time_stop(to_mtk_clk(clk), GPT_CLK_EVT);
+	return 0;
+}
+
+static int mtk_clkevt_set_periodic(struct clock_event_device *clk)
 {
 	struct mtk_clock_event_device *evt = to_mtk_clk(clk);
 
 	mtk_clkevt_time_stop(evt, GPT_CLK_EVT);
-
-	switch (mode) {
-	case CLOCK_EVT_MODE_PERIODIC:
-		mtk_clkevt_time_setup(evt, evt->ticks_per_jiffy, GPT_CLK_EVT);
-		mtk_clkevt_time_start(evt, true, GPT_CLK_EVT);
-		break;
-	case CLOCK_EVT_MODE_ONESHOT:
-		/* Timer is enabled in set_next_event */
-		break;
-	case CLOCK_EVT_MODE_UNUSED:
-	case CLOCK_EVT_MODE_SHUTDOWN:
-	default:
-		/* No more interrupts will occur as source is disabled */
-		break;
-	}
+	mtk_clkevt_time_setup(evt, evt->ticks_per_jiffy, GPT_CLK_EVT);
+	mtk_clkevt_time_start(evt, true, GPT_CLK_EVT);
+	return 0;
 }
 
 static int mtk_clkevt_next_event(unsigned long event,
@@ -196,7 +189,10 @@ static void __init mtk_timer_init(struct device_node *node)
 	evt->dev.name = "mtk_tick";
 	evt->dev.rating = 300;
 	evt->dev.features = CLOCK_EVT_FEAT_PERIODIC | CLOCK_EVT_FEAT_ONESHOT;
-	evt->dev.set_mode = mtk_clkevt_mode;
+	evt->dev.set_state_shutdown = mtk_clkevt_shutdown;
+	evt->dev.set_state_periodic = mtk_clkevt_set_periodic;
+	evt->dev.set_state_oneshot = mtk_clkevt_shutdown;
+	evt->dev.tick_resume = mtk_clkevt_shutdown;
 	evt->dev.set_next_event = mtk_clkevt_next_event;
 	evt->dev.cpumask = cpu_possible_mask;
 
-- 
1.9.1



From daniel.lezcano at linaro.org  Mon Aug 10 02:52:00 2015
From: daniel.lezcano at linaro.org (Daniel Lezcano)
Date: Mon, 10 Aug 2015 11:52:00 +0200
Subject: [PATCH 43/74] clockevents/drivers/prima2: Migrate to new 'set-state'
 interface
In-Reply-To: <1439200352-26767-1-git-send-email-daniel.lezcano@linaro.org>
References: <55C87382.4070309@linaro.org>
 <1439200352-26767-1-git-send-email-daniel.lezcano@linaro.org>
Message-ID: <1439200352-26767-43-git-send-email-daniel.lezcano@linaro.org>

From: Viresh Kumar <viresh.kumar at linaro.org>

Migrate prima2 driver to the new 'set-state' interface provided by
clockevents core, the earlier 'set-mode' interface is marked obsolete
now.

This also enables us to implement callbacks for new states of clockevent
devices, for example: ONESHOT_STOPPED.

Cc: Barry Song <baohua at kernel.org>
Signed-off-by: Viresh Kumar <viresh.kumar at linaro.org>
Signed-off-by: Daniel Lezcano <daniel.lezcano at linaro.org>
---
 drivers/clocksource/timer-prima2.c | 34 +++++++++++++++-------------------
 1 file changed, 15 insertions(+), 19 deletions(-)

diff --git a/drivers/clocksource/timer-prima2.c b/drivers/clocksource/timer-prima2.c
index ce18d57..78de982 100644
--- a/drivers/clocksource/timer-prima2.c
+++ b/drivers/clocksource/timer-prima2.c
@@ -104,26 +104,21 @@ static int sirfsoc_timer_set_next_event(unsigned long delta,
 	return next - now > delta ? -ETIME : 0;
 }
 
-static void sirfsoc_timer_set_mode(enum clock_event_mode mode,
-	struct clock_event_device *ce)
+static int sirfsoc_timer_shutdown(struct clock_event_device *evt)
 {
 	u32 val = readl_relaxed(sirfsoc_timer_base + SIRFSOC_TIMER_INT_EN);
-	switch (mode) {
-	case CLOCK_EVT_MODE_PERIODIC:
-		WARN_ON(1);
-		break;
-	case CLOCK_EVT_MODE_ONESHOT:
-		writel_relaxed(val | BIT(0),
-			sirfsoc_timer_base + SIRFSOC_TIMER_INT_EN);
-		break;
-	case CLOCK_EVT_MODE_SHUTDOWN:
-		writel_relaxed(val & ~BIT(0),
-			sirfsoc_timer_base + SIRFSOC_TIMER_INT_EN);
-		break;
-	case CLOCK_EVT_MODE_UNUSED:
-	case CLOCK_EVT_MODE_RESUME:
-		break;
-	}
+
+	writel_relaxed(val & ~BIT(0),
+		       sirfsoc_timer_base + SIRFSOC_TIMER_INT_EN);
+	return 0;
+}
+
+static int sirfsoc_timer_set_oneshot(struct clock_event_device *evt)
+{
+	u32 val = readl_relaxed(sirfsoc_timer_base + SIRFSOC_TIMER_INT_EN);
+
+	writel_relaxed(val | BIT(0), sirfsoc_timer_base + SIRFSOC_TIMER_INT_EN);
+	return 0;
 }
 
 static void sirfsoc_clocksource_suspend(struct clocksource *cs)
@@ -157,7 +152,8 @@ static struct clock_event_device sirfsoc_clockevent = {
 	.name = "sirfsoc_clockevent",
 	.rating = 200,
 	.features = CLOCK_EVT_FEAT_ONESHOT,
-	.set_mode = sirfsoc_timer_set_mode,
+	.set_state_shutdown = sirfsoc_timer_shutdown,
+	.set_state_oneshot = sirfsoc_timer_set_oneshot,
 	.set_next_event = sirfsoc_timer_set_next_event,
 };
 
-- 
1.9.1



From daniel.lezcano at linaro.org  Mon Aug 10 02:51:59 2015
From: daniel.lezcano at linaro.org (Daniel Lezcano)
Date: Mon, 10 Aug 2015 11:51:59 +0200
Subject: [PATCH 42/74] clockevents/drivers/keystone: Migrate to new
 'set-state' interface
In-Reply-To: <1439200352-26767-1-git-send-email-daniel.lezcano@linaro.org>
References: <55C87382.4070309@linaro.org>
 <1439200352-26767-1-git-send-email-daniel.lezcano@linaro.org>
Message-ID: <1439200352-26767-42-git-send-email-daniel.lezcano@linaro.org>

From: Viresh Kumar <viresh.kumar at linaro.org>

Migrate keystone driver to the new 'set-state' interface provided by
clockevents core, the earlier 'set-mode' interface is marked obsolete
now.

This also enables us to implement callbacks for new states of clockevent
devices, for example: ONESHOT_STOPPED.

Also pass the mode-mask to keystone_timer_config() instead of the mode
as mode macro's aren't valid anymore.

Cc: Santosh Shilimkar <ssantosh at kernel.org>
Signed-off-by: Viresh Kumar <viresh.kumar at linaro.org>
Signed-off-by: Daniel Lezcano <daniel.lezcano at linaro.org>
---
 drivers/clocksource/timer-keystone.c | 44 +++++++++++++-----------------------
 1 file changed, 16 insertions(+), 28 deletions(-)

diff --git a/drivers/clocksource/timer-keystone.c b/drivers/clocksource/timer-keystone.c
index 0250354..edacf39 100644
--- a/drivers/clocksource/timer-keystone.c
+++ b/drivers/clocksource/timer-keystone.c
@@ -72,10 +72,10 @@ static inline void keystone_timer_barrier(void)
 
 /**
  * keystone_timer_config: configures timer to work in oneshot/periodic modes.
- * @ mode: mode to configure
+ * @ mask: mask of the mode to configure
  * @ period: cycles number to configure for
  */
-static int keystone_timer_config(u64 period, enum clock_event_mode mode)
+static int keystone_timer_config(u64 period, int mask)
 {
 	u32 tcr;
 	u32 off;
@@ -84,16 +84,7 @@ static int keystone_timer_config(u64 period, enum clock_event_mode mode)
 	off = tcr & ~(TCR_ENAMODE_MASK);
 
 	/* set enable mode */
-	switch (mode) {
-	case CLOCK_EVT_MODE_ONESHOT:
-		tcr |= TCR_ENAMODE_ONESHOT_MASK;
-		break;
-	case CLOCK_EVT_MODE_PERIODIC:
-		tcr |= TCR_ENAMODE_PERIODIC_MASK;
-		break;
-	default:
-		return -1;
-	}
+	tcr |= mask;
 
 	/* disable timer */
 	keystone_timer_writel(off, TCR);
@@ -138,24 +129,19 @@ static irqreturn_t keystone_timer_interrupt(int irq, void *dev_id)
 static int keystone_set_next_event(unsigned long cycles,
 				  struct clock_event_device *evt)
 {
-	return keystone_timer_config(cycles, evt->mode);
+	return keystone_timer_config(cycles, TCR_ENAMODE_ONESHOT_MASK);
 }
 
-static void keystone_set_mode(enum clock_event_mode mode,
-			     struct clock_event_device *evt)
+static int keystone_shutdown(struct clock_event_device *evt)
 {
-	switch (mode) {
-	case CLOCK_EVT_MODE_PERIODIC:
-		keystone_timer_config(timer.hz_period, CLOCK_EVT_MODE_PERIODIC);
-		break;
-	case CLOCK_EVT_MODE_UNUSED:
-	case CLOCK_EVT_MODE_SHUTDOWN:
-	case CLOCK_EVT_MODE_ONESHOT:
-		keystone_timer_disable();
-		break;
-	default:
-		break;
-	}
+	keystone_timer_disable();
+	return 0;
+}
+
+static int keystone_set_periodic(struct clock_event_device *evt)
+{
+	keystone_timer_config(timer.hz_period, TCR_ENAMODE_PERIODIC_MASK);
+	return 0;
 }
 
 static void __init keystone_timer_init(struct device_node *np)
@@ -222,7 +208,9 @@ static void __init keystone_timer_init(struct device_node *np)
 	/* setup clockevent */
 	event_dev->features = CLOCK_EVT_FEAT_PERIODIC | CLOCK_EVT_FEAT_ONESHOT;
 	event_dev->set_next_event = keystone_set_next_event;
-	event_dev->set_mode = keystone_set_mode;
+	event_dev->set_state_shutdown = keystone_shutdown;
+	event_dev->set_state_periodic = keystone_set_periodic;
+	event_dev->set_state_oneshot = keystone_shutdown;
 	event_dev->cpumask = cpu_all_mask;
 	event_dev->owner = THIS_MODULE;
 	event_dev->name = TIMER_NAME;
-- 
1.9.1



From daniel.lezcano at linaro.org  Mon Aug 10 02:52:02 2015
From: daniel.lezcano at linaro.org (Daniel Lezcano)
Date: Mon, 10 Aug 2015 11:52:02 +0200
Subject: [PATCH 45/74] clockevents/drivers/sun5i: Migrate to new 'set-state'
 interface
In-Reply-To: <1439200352-26767-1-git-send-email-daniel.lezcano@linaro.org>
References: <55C87382.4070309@linaro.org>
 <1439200352-26767-1-git-send-email-daniel.lezcano@linaro.org>
Message-ID: <1439200352-26767-45-git-send-email-daniel.lezcano@linaro.org>

From: Viresh Kumar <viresh.kumar at linaro.org>

Migrate sun5i driver to the new 'set-state' interface provided by
clockevents core, the earlier 'set-mode' interface is marked obsolete
now.

This also enables us to implement callbacks for new states of clockevent
devices, for example: ONESHOT_STOPPED.

Cc: Maxime Ripard <maxime.ripard at free-electrons.com>
Signed-off-by: Viresh Kumar <viresh.kumar at linaro.org>
Signed-off-by: Daniel Lezcano <daniel.lezcano at linaro.org>
Acked-by: Maxime Ripard <maxime.ripard at free-electrons.com>
---
 drivers/clocksource/timer-sun5i.c | 45 ++++++++++++++++++++++-----------------
 1 file changed, 26 insertions(+), 19 deletions(-)

diff --git a/drivers/clocksource/timer-sun5i.c b/drivers/clocksource/timer-sun5i.c
index 0ffb4ea..bca9573 100644
--- a/drivers/clocksource/timer-sun5i.c
+++ b/drivers/clocksource/timer-sun5i.c
@@ -103,27 +103,31 @@ static void sun5i_clkevt_time_start(struct sun5i_timer_clkevt *ce, u8 timer, boo
 	       ce->timer.base + TIMER_CTL_REG(timer));
 }
 
-static void sun5i_clkevt_mode(enum clock_event_mode mode,
-			      struct clock_event_device *clkevt)
+static int sun5i_clkevt_shutdown(struct clock_event_device *clkevt)
 {
 	struct sun5i_timer_clkevt *ce = to_sun5i_timer_clkevt(clkevt);
 
-	switch (mode) {
-	case CLOCK_EVT_MODE_PERIODIC:
-		sun5i_clkevt_time_stop(ce, 0);
-		sun5i_clkevt_time_setup(ce, 0, ce->timer.ticks_per_jiffy);
-		sun5i_clkevt_time_start(ce, 0, true);
-		break;
-	case CLOCK_EVT_MODE_ONESHOT:
-		sun5i_clkevt_time_stop(ce, 0);
-		sun5i_clkevt_time_start(ce, 0, false);
-		break;
-	case CLOCK_EVT_MODE_UNUSED:
-	case CLOCK_EVT_MODE_SHUTDOWN:
-	default:
-		sun5i_clkevt_time_stop(ce, 0);
-		break;
-	}
+	sun5i_clkevt_time_stop(ce, 0);
+	return 0;
+}
+
+static int sun5i_clkevt_set_oneshot(struct clock_event_device *clkevt)
+{
+	struct sun5i_timer_clkevt *ce = to_sun5i_timer_clkevt(clkevt);
+
+	sun5i_clkevt_time_stop(ce, 0);
+	sun5i_clkevt_time_start(ce, 0, false);
+	return 0;
+}
+
+static int sun5i_clkevt_set_periodic(struct clock_event_device *clkevt)
+{
+	struct sun5i_timer_clkevt *ce = to_sun5i_timer_clkevt(clkevt);
+
+	sun5i_clkevt_time_stop(ce, 0);
+	sun5i_clkevt_time_setup(ce, 0, ce->timer.ticks_per_jiffy);
+	sun5i_clkevt_time_start(ce, 0, true);
+	return 0;
 }
 
 static int sun5i_clkevt_next_event(unsigned long evt,
@@ -286,7 +290,10 @@ static int __init sun5i_setup_clockevent(struct device_node *node, void __iomem
 	ce->clkevt.name = node->name;
 	ce->clkevt.features = CLOCK_EVT_FEAT_PERIODIC | CLOCK_EVT_FEAT_ONESHOT;
 	ce->clkevt.set_next_event = sun5i_clkevt_next_event;
-	ce->clkevt.set_mode = sun5i_clkevt_mode;
+	ce->clkevt.set_state_shutdown = sun5i_clkevt_shutdown;
+	ce->clkevt.set_state_periodic = sun5i_clkevt_set_periodic;
+	ce->clkevt.set_state_oneshot = sun5i_clkevt_set_oneshot;
+	ce->clkevt.tick_resume = sun5i_clkevt_shutdown;
 	ce->clkevt.rating = 340;
 	ce->clkevt.irq = irq;
 	ce->clkevt.cpumask = cpu_possible_mask;
-- 
1.9.1



From daniel.lezcano at linaro.org  Mon Aug 10 02:52:01 2015
From: daniel.lezcano at linaro.org (Daniel Lezcano)
Date: Mon, 10 Aug 2015 11:52:01 +0200
Subject: [PATCH 44/74] clockevents/drivers/stm32: Migrate to new 'set-state'
 interface
In-Reply-To: <1439200352-26767-1-git-send-email-daniel.lezcano@linaro.org>
References: <55C87382.4070309@linaro.org>
 <1439200352-26767-1-git-send-email-daniel.lezcano@linaro.org>
Message-ID: <1439200352-26767-44-git-send-email-daniel.lezcano@linaro.org>

From: Viresh Kumar <viresh.kumar at linaro.org>

Migrate stm32 driver to the new 'set-state' interface provided by
clockevents core, the earlier 'set-mode' interface is marked obsolete
now.

This also enables us to implement callbacks for new states of clockevent
devices, for example: ONESHOT_STOPPED.

Cc: Maxime Coquelin <mcoquelin.stm32 at gmail.com>
Signed-off-by: Viresh Kumar <viresh.kumar at linaro.org>
Signed-off-by: Daniel Lezcano <daniel.lezcano at linaro.org>
Tested-by: Maxime Coquelin <mcoquelin.stm32 at gmail.com>
Acked-by: Maxime Coquelin <mcoquelin.stm32 at gmail.com>
---
 drivers/clocksource/timer-stm32.c | 30 +++++++++++++++++-------------
 1 file changed, 17 insertions(+), 13 deletions(-)

diff --git a/drivers/clocksource/timer-stm32.c b/drivers/clocksource/timer-stm32.c
index a97e8b5..f3dcb76 100644
--- a/drivers/clocksource/timer-stm32.c
+++ b/drivers/clocksource/timer-stm32.c
@@ -40,24 +40,25 @@ struct stm32_clock_event_ddata {
 	void __iomem *base;
 };
 
-static void stm32_clock_event_set_mode(enum clock_event_mode mode,
-				       struct clock_event_device *evtdev)
+static int stm32_clock_event_shutdown(struct clock_event_device *evtdev)
 {
 	struct stm32_clock_event_ddata *data =
 		container_of(evtdev, struct stm32_clock_event_ddata, evtdev);
 	void *base = data->base;
 
-	switch (mode) {
-	case CLOCK_EVT_MODE_PERIODIC:
-		writel_relaxed(data->periodic_top, base + TIM_ARR);
-		writel_relaxed(TIM_CR1_ARPE | TIM_CR1_CEN, base + TIM_CR1);
-		break;
+	writel_relaxed(0, base + TIM_CR1);
+	return 0;
+}
 
-	case CLOCK_EVT_MODE_ONESHOT:
-	default:
-		writel_relaxed(0, base + TIM_CR1);
-		break;
-	}
+static int stm32_clock_event_set_periodic(struct clock_event_device *evtdev)
+{
+	struct stm32_clock_event_ddata *data =
+		container_of(evtdev, struct stm32_clock_event_ddata, evtdev);
+	void *base = data->base;
+
+	writel_relaxed(data->periodic_top, base + TIM_ARR);
+	writel_relaxed(TIM_CR1_ARPE | TIM_CR1_CEN, base + TIM_CR1);
+	return 0;
 }
 
 static int stm32_clock_event_set_next_event(unsigned long evt,
@@ -88,7 +89,10 @@ static struct stm32_clock_event_ddata clock_event_ddata = {
 	.evtdev = {
 		.name = "stm32 clockevent",
 		.features = CLOCK_EVT_FEAT_ONESHOT | CLOCK_EVT_FEAT_PERIODIC,
-		.set_mode = stm32_clock_event_set_mode,
+		.set_state_shutdown = stm32_clock_event_shutdown,
+		.set_state_periodic = stm32_clock_event_set_periodic,
+		.set_state_oneshot = stm32_clock_event_shutdown,
+		.tick_resume = stm32_clock_event_shutdown,
 		.set_next_event = stm32_clock_event_set_next_event,
 		.rating = 200,
 	},
-- 
1.9.1



From daniel.lezcano at linaro.org  Mon Aug 10 02:52:05 2015
From: daniel.lezcano at linaro.org (Daniel Lezcano)
Date: Mon, 10 Aug 2015 11:52:05 +0200
Subject: [PATCH 48/74] clockevents/drivers/vt8500: Migrate to new 'set-state'
 interface
In-Reply-To: <1439200352-26767-1-git-send-email-daniel.lezcano@linaro.org>
References: <55C87382.4070309@linaro.org>
 <1439200352-26767-1-git-send-email-daniel.lezcano@linaro.org>
Message-ID: <1439200352-26767-48-git-send-email-daniel.lezcano@linaro.org>

From: Viresh Kumar <viresh.kumar at linaro.org>

Migrate vt8500 driver to the new 'set-state' interface provided by
clockevents core, the earlier 'set-mode' interface is marked obsolete
now.

This also enables us to implement callbacks for new states of clockevent
devices, for example: ONESHOT_STOPPED.

Cc: Tony Prisk <linux at prisktech.co.nz>
Signed-off-by: Viresh Kumar <viresh.kumar at linaro.org>
Signed-off-by: Daniel Lezcano <daniel.lezcano at linaro.org>
---
 drivers/clocksource/vt8500_timer.c | 29 ++++++++++-------------------
 1 file changed, 10 insertions(+), 19 deletions(-)

diff --git a/drivers/clocksource/vt8500_timer.c b/drivers/clocksource/vt8500_timer.c
index 1098ed3..a92e94b 100644
--- a/drivers/clocksource/vt8500_timer.c
+++ b/drivers/clocksource/vt8500_timer.c
@@ -88,29 +88,20 @@ static int vt8500_timer_set_next_event(unsigned long cycles,
 	return 0;
 }
 
-static void vt8500_timer_set_mode(enum clock_event_mode mode,
-			      struct clock_event_device *evt)
+static int vt8500_shutdown(struct clock_event_device *evt)
 {
-	switch (mode) {
-	case CLOCK_EVT_MODE_RESUME:
-	case CLOCK_EVT_MODE_PERIODIC:
-		break;
-	case CLOCK_EVT_MODE_ONESHOT:
-	case CLOCK_EVT_MODE_UNUSED:
-	case CLOCK_EVT_MODE_SHUTDOWN:
-		writel(readl(regbase + TIMER_CTRL_VAL) | 1,
-			regbase + TIMER_CTRL_VAL);
-		writel(0, regbase + TIMER_IER_VAL);
-		break;
-	}
+	writel(readl(regbase + TIMER_CTRL_VAL) | 1, regbase + TIMER_CTRL_VAL);
+	writel(0, regbase + TIMER_IER_VAL);
+	return 0;
 }
 
 static struct clock_event_device clockevent = {
-	.name           = "vt8500_timer",
-	.features       = CLOCK_EVT_FEAT_ONESHOT,
-	.rating         = 200,
-	.set_next_event = vt8500_timer_set_next_event,
-	.set_mode       = vt8500_timer_set_mode,
+	.name			= "vt8500_timer",
+	.features		= CLOCK_EVT_FEAT_ONESHOT,
+	.rating			= 200,
+	.set_next_event		= vt8500_timer_set_next_event,
+	.set_state_shutdown	= vt8500_shutdown,
+	.set_state_oneshot	= vt8500_shutdown,
 };
 
 static irqreturn_t vt8500_timer_interrupt(int irq, void *dev_id)
-- 
1.9.1



From daniel.lezcano at linaro.org  Mon Aug 10 02:52:03 2015
From: daniel.lezcano at linaro.org (Daniel Lezcano)
Date: Mon, 10 Aug 2015 11:52:03 +0200
Subject: [PATCH 46/74] clockevents/drivers/u300: Migrate to new 'set-state'
 interface
In-Reply-To: <1439200352-26767-1-git-send-email-daniel.lezcano@linaro.org>
References: <55C87382.4070309@linaro.org>
 <1439200352-26767-1-git-send-email-daniel.lezcano@linaro.org>
Message-ID: <1439200352-26767-46-git-send-email-daniel.lezcano@linaro.org>

From: Viresh Kumar <viresh.kumar at linaro.org>

Migrate u300 driver to the new 'set-state' interface provided by
clockevents core, the earlier 'set-mode' interface is marked obsolete
now.

This also enables us to implement callbacks for new states of clockevent
devices, for example: ONESHOT_STOPPED.

Cc: Linus Walleij <linus.walleij at linaro.org>
Signed-off-by: Viresh Kumar <viresh.kumar at linaro.org>
Signed-off-by: Daniel Lezcano <daniel.lezcano at linaro.org>
Acked-by: Linus Walleij <linus.walleij at linaro.org>
---
 drivers/clocksource/timer-u300.c | 155 +++++++++++++++++++--------------------
 1 file changed, 77 insertions(+), 78 deletions(-)

diff --git a/drivers/clocksource/timer-u300.c b/drivers/clocksource/timer-u300.c
index 5dcf756..1744b24 100644
--- a/drivers/clocksource/timer-u300.c
+++ b/drivers/clocksource/timer-u300.c
@@ -187,85 +187,82 @@ struct u300_clockevent_data {
 	unsigned ticks_per_jiffy;
 };
 
+static int u300_shutdown(struct clock_event_device *evt)
+{
+	/* Disable interrupts on GP1 */
+	writel(U300_TIMER_APP_GPT1IE_IRQ_DISABLE,
+	       u300_timer_base + U300_TIMER_APP_GPT1IE);
+	/* Disable GP1 */
+	writel(U300_TIMER_APP_DGPT1_TIMER_DISABLE,
+	       u300_timer_base + U300_TIMER_APP_DGPT1);
+	return 0;
+}
+
 /*
- * The u300_set_mode() function is always called first, if we
- * have oneshot timer active, the oneshot scheduling function
+ * If we have oneshot timer active, the oneshot scheduling function
  * u300_set_next_event() is called immediately after.
  */
-static void u300_set_mode(enum clock_event_mode mode,
-			  struct clock_event_device *evt)
+static int u300_set_oneshot(struct clock_event_device *evt)
+{
+	/* Just return; here? */
+	/*
+	 * The actual event will be programmed by the next event hook,
+	 * so we just set a dummy value somewhere at the end of the
+	 * universe here.
+	 */
+	/* Disable interrupts on GPT1 */
+	writel(U300_TIMER_APP_GPT1IE_IRQ_DISABLE,
+	       u300_timer_base + U300_TIMER_APP_GPT1IE);
+	/* Disable GP1 while we're reprogramming it. */
+	writel(U300_TIMER_APP_DGPT1_TIMER_DISABLE,
+	       u300_timer_base + U300_TIMER_APP_DGPT1);
+	/*
+	 * Expire far in the future, u300_set_next_event() will be
+	 * called soon...
+	 */
+	writel(0xFFFFFFFF, u300_timer_base + U300_TIMER_APP_GPT1TC);
+	/* We run one shot per tick here! */
+	writel(U300_TIMER_APP_SGPT1M_MODE_ONE_SHOT,
+	       u300_timer_base + U300_TIMER_APP_SGPT1M);
+	/* Enable interrupts for this timer */
+	writel(U300_TIMER_APP_GPT1IE_IRQ_ENABLE,
+	       u300_timer_base + U300_TIMER_APP_GPT1IE);
+	/* Enable timer */
+	writel(U300_TIMER_APP_EGPT1_TIMER_ENABLE,
+	       u300_timer_base + U300_TIMER_APP_EGPT1);
+	return 0;
+}
+
+static int u300_set_periodic(struct clock_event_device *evt)
 {
 	struct u300_clockevent_data *cevdata =
 		container_of(evt, struct u300_clockevent_data, cevd);
 
-	switch (mode) {
-	case CLOCK_EVT_MODE_PERIODIC:
-		/* Disable interrupts on GPT1 */
-		writel(U300_TIMER_APP_GPT1IE_IRQ_DISABLE,
-		       u300_timer_base + U300_TIMER_APP_GPT1IE);
-		/* Disable GP1 while we're reprogramming it. */
-		writel(U300_TIMER_APP_DGPT1_TIMER_DISABLE,
-		       u300_timer_base + U300_TIMER_APP_DGPT1);
-		/*
-		 * Set the periodic mode to a certain number of ticks per
-		 * jiffy.
-		 */
-		writel(cevdata->ticks_per_jiffy,
-		       u300_timer_base + U300_TIMER_APP_GPT1TC);
-		/*
-		 * Set continuous mode, so the timer keeps triggering
-		 * interrupts.
-		 */
-		writel(U300_TIMER_APP_SGPT1M_MODE_CONTINUOUS,
-		       u300_timer_base + U300_TIMER_APP_SGPT1M);
-		/* Enable timer interrupts */
-		writel(U300_TIMER_APP_GPT1IE_IRQ_ENABLE,
-		       u300_timer_base + U300_TIMER_APP_GPT1IE);
-		/* Then enable the OS timer again */
-		writel(U300_TIMER_APP_EGPT1_TIMER_ENABLE,
-		       u300_timer_base + U300_TIMER_APP_EGPT1);
-		break;
-	case CLOCK_EVT_MODE_ONESHOT:
-		/* Just break; here? */
-		/*
-		 * The actual event will be programmed by the next event hook,
-		 * so we just set a dummy value somewhere at the end of the
-		 * universe here.
-		 */
-		/* Disable interrupts on GPT1 */
-		writel(U300_TIMER_APP_GPT1IE_IRQ_DISABLE,
-		       u300_timer_base + U300_TIMER_APP_GPT1IE);
-		/* Disable GP1 while we're reprogramming it. */
-		writel(U300_TIMER_APP_DGPT1_TIMER_DISABLE,
-		       u300_timer_base + U300_TIMER_APP_DGPT1);
-		/*
-		 * Expire far in the future, u300_set_next_event() will be
-		 * called soon...
-		 */
-		writel(0xFFFFFFFF, u300_timer_base + U300_TIMER_APP_GPT1TC);
-		/* We run one shot per tick here! */
-		writel(U300_TIMER_APP_SGPT1M_MODE_ONE_SHOT,
-		       u300_timer_base + U300_TIMER_APP_SGPT1M);
-		/* Enable interrupts for this timer */
-		writel(U300_TIMER_APP_GPT1IE_IRQ_ENABLE,
-		       u300_timer_base + U300_TIMER_APP_GPT1IE);
-		/* Enable timer */
-		writel(U300_TIMER_APP_EGPT1_TIMER_ENABLE,
-		       u300_timer_base + U300_TIMER_APP_EGPT1);
-		break;
-	case CLOCK_EVT_MODE_UNUSED:
-	case CLOCK_EVT_MODE_SHUTDOWN:
-		/* Disable interrupts on GP1 */
-		writel(U300_TIMER_APP_GPT1IE_IRQ_DISABLE,
-		       u300_timer_base + U300_TIMER_APP_GPT1IE);
-		/* Disable GP1 */
-		writel(U300_TIMER_APP_DGPT1_TIMER_DISABLE,
-		       u300_timer_base + U300_TIMER_APP_DGPT1);
-		break;
-	case CLOCK_EVT_MODE_RESUME:
-		/* Ignore this call */
-		break;
-	}
+	/* Disable interrupts on GPT1 */
+	writel(U300_TIMER_APP_GPT1IE_IRQ_DISABLE,
+	       u300_timer_base + U300_TIMER_APP_GPT1IE);
+	/* Disable GP1 while we're reprogramming it. */
+	writel(U300_TIMER_APP_DGPT1_TIMER_DISABLE,
+	       u300_timer_base + U300_TIMER_APP_DGPT1);
+	/*
+	 * Set the periodic mode to a certain number of ticks per
+	 * jiffy.
+	 */
+	writel(cevdata->ticks_per_jiffy,
+	       u300_timer_base + U300_TIMER_APP_GPT1TC);
+	/*
+	 * Set continuous mode, so the timer keeps triggering
+	 * interrupts.
+	 */
+	writel(U300_TIMER_APP_SGPT1M_MODE_CONTINUOUS,
+	       u300_timer_base + U300_TIMER_APP_SGPT1M);
+	/* Enable timer interrupts */
+	writel(U300_TIMER_APP_GPT1IE_IRQ_ENABLE,
+	       u300_timer_base + U300_TIMER_APP_GPT1IE);
+	/* Then enable the OS timer again */
+	writel(U300_TIMER_APP_EGPT1_TIMER_ENABLE,
+	       u300_timer_base + U300_TIMER_APP_EGPT1);
+	return 0;
 }
 
 /*
@@ -309,13 +306,15 @@ static int u300_set_next_event(unsigned long cycles,
 static struct u300_clockevent_data u300_clockevent_data = {
 	/* Use general purpose timer 1 as clock event */
 	.cevd = {
-		.name		= "GPT1",
+		.name			= "GPT1",
 		/* Reasonably fast and accurate clock event */
-		.rating		= 300,
-		.features	= CLOCK_EVT_FEAT_PERIODIC |
-			CLOCK_EVT_FEAT_ONESHOT,
-		.set_next_event	= u300_set_next_event,
-		.set_mode	= u300_set_mode,
+		.rating			= 300,
+		.features		= CLOCK_EVT_FEAT_PERIODIC |
+					  CLOCK_EVT_FEAT_ONESHOT,
+		.set_next_event		= u300_set_next_event,
+		.set_state_shutdown	= u300_shutdown,
+		.set_state_periodic	= u300_set_periodic,
+		.set_state_oneshot	= u300_set_oneshot,
 	},
 };
 
-- 
1.9.1



From daniel.lezcano at linaro.org  Mon Aug 10 02:52:07 2015
From: daniel.lezcano at linaro.org (Daniel Lezcano)
Date: Mon, 10 Aug 2015 11:52:07 +0200
Subject: [PATCH 50/74] clockevents/drivers/tcb_clksrc: Migrate to new
 'set-state' interface
In-Reply-To: <1439200352-26767-1-git-send-email-daniel.lezcano@linaro.org>
References: <55C87382.4070309@linaro.org>
 <1439200352-26767-1-git-send-email-daniel.lezcano@linaro.org>
Message-ID: <1439200352-26767-50-git-send-email-daniel.lezcano@linaro.org>

From: Viresh Kumar <viresh.kumar at linaro.org>

Migrate tcb_clksrc driver to the new 'set-state' interface provided by
clockevents core, the earlier 'set-mode' interface is marked obsolete
now.

This also enables us to implement callbacks for new states of clockevent
devices, for example: ONESHOT_STOPPED.

Cc: Nicolas Ferre <nicolas.ferre at atmel.com>
Signed-off-by: Viresh Kumar <viresh.kumar at linaro.org>
Signed-off-by: Daniel Lezcano <daniel.lezcano at linaro.org>
---
 drivers/clocksource/tcb_clksrc.c | 93 ++++++++++++++++++++++------------------
 1 file changed, 51 insertions(+), 42 deletions(-)

diff --git a/drivers/clocksource/tcb_clksrc.c b/drivers/clocksource/tcb_clksrc.c
index 8bdbc45..d28d2fe 100644
--- a/drivers/clocksource/tcb_clksrc.c
+++ b/drivers/clocksource/tcb_clksrc.c
@@ -91,55 +91,62 @@ static struct tc_clkevt_device *to_tc_clkevt(struct clock_event_device *clkevt)
  */
 static u32 timer_clock;
 
-static void tc_mode(enum clock_event_mode m, struct clock_event_device *d)
+static int tc_shutdown(struct clock_event_device *d)
 {
 	struct tc_clkevt_device *tcd = to_tc_clkevt(d);
 	void __iomem		*regs = tcd->regs;
 
-	if (tcd->clkevt.mode == CLOCK_EVT_MODE_PERIODIC
-			|| tcd->clkevt.mode == CLOCK_EVT_MODE_ONESHOT) {
-		__raw_writel(0xff, regs + ATMEL_TC_REG(2, IDR));
-		__raw_writel(ATMEL_TC_CLKDIS, regs + ATMEL_TC_REG(2, CCR));
-		clk_disable(tcd->clk);
-	}
+	__raw_writel(0xff, regs + ATMEL_TC_REG(2, IDR));
+	__raw_writel(ATMEL_TC_CLKDIS, regs + ATMEL_TC_REG(2, CCR));
+	clk_disable(tcd->clk);
 
-	switch (m) {
+	return 0;
+}
 
-	/* By not making the gentime core emulate periodic mode on top
-	 * of oneshot, we get lower overhead and improved accuracy.
-	 */
-	case CLOCK_EVT_MODE_PERIODIC:
-		clk_enable(tcd->clk);
+static int tc_set_oneshot(struct clock_event_device *d)
+{
+	struct tc_clkevt_device *tcd = to_tc_clkevt(d);
+	void __iomem		*regs = tcd->regs;
 
-		/* slow clock, count up to RC, then irq and restart */
-		__raw_writel(timer_clock
-				| ATMEL_TC_WAVE | ATMEL_TC_WAVESEL_UP_AUTO,
-				regs + ATMEL_TC_REG(2, CMR));
-		__raw_writel((32768 + HZ/2) / HZ, tcaddr + ATMEL_TC_REG(2, RC));
+	if (clockevent_state_oneshot(d) || clockevent_state_periodic(d))
+		tc_shutdown(d);
 
-		/* Enable clock and interrupts on RC compare */
-		__raw_writel(ATMEL_TC_CPCS, regs + ATMEL_TC_REG(2, IER));
+	clk_enable(tcd->clk);
 
-		/* go go gadget! */
-		__raw_writel(ATMEL_TC_CLKEN | ATMEL_TC_SWTRG,
-				regs + ATMEL_TC_REG(2, CCR));
-		break;
+	/* slow clock, count up to RC, then irq and stop */
+	__raw_writel(timer_clock | ATMEL_TC_CPCSTOP | ATMEL_TC_WAVE |
+		     ATMEL_TC_WAVESEL_UP_AUTO, regs + ATMEL_TC_REG(2, CMR));
+	__raw_writel(ATMEL_TC_CPCS, regs + ATMEL_TC_REG(2, IER));
 
-	case CLOCK_EVT_MODE_ONESHOT:
-		clk_enable(tcd->clk);
+	/* set_next_event() configures and starts the timer */
+	return 0;
+}
 
-		/* slow clock, count up to RC, then irq and stop */
-		__raw_writel(timer_clock | ATMEL_TC_CPCSTOP
-				| ATMEL_TC_WAVE | ATMEL_TC_WAVESEL_UP_AUTO,
-				regs + ATMEL_TC_REG(2, CMR));
-		__raw_writel(ATMEL_TC_CPCS, regs + ATMEL_TC_REG(2, IER));
+static int tc_set_periodic(struct clock_event_device *d)
+{
+	struct tc_clkevt_device *tcd = to_tc_clkevt(d);
+	void __iomem		*regs = tcd->regs;
 
-		/* set_next_event() configures and starts the timer */
-		break;
+	if (clockevent_state_oneshot(d) || clockevent_state_periodic(d))
+		tc_shutdown(d);
 
-	default:
-		break;
-	}
+	/* By not making the gentime core emulate periodic mode on top
+	 * of oneshot, we get lower overhead and improved accuracy.
+	 */
+	clk_enable(tcd->clk);
+
+	/* slow clock, count up to RC, then irq and restart */
+	__raw_writel(timer_clock | ATMEL_TC_WAVE | ATMEL_TC_WAVESEL_UP_AUTO,
+		     regs + ATMEL_TC_REG(2, CMR));
+	__raw_writel((32768 + HZ / 2) / HZ, tcaddr + ATMEL_TC_REG(2, RC));
+
+	/* Enable clock and interrupts on RC compare */
+	__raw_writel(ATMEL_TC_CPCS, regs + ATMEL_TC_REG(2, IER));
+
+	/* go go gadget! */
+	__raw_writel(ATMEL_TC_CLKEN | ATMEL_TC_SWTRG, regs +
+		     ATMEL_TC_REG(2, CCR));
+	return 0;
 }
 
 static int tc_next_event(unsigned long delta, struct clock_event_device *d)
@@ -154,13 +161,15 @@ static int tc_next_event(unsigned long delta, struct clock_event_device *d)
 
 static struct tc_clkevt_device clkevt = {
 	.clkevt	= {
-		.name		= "tc_clkevt",
-		.features	= CLOCK_EVT_FEAT_PERIODIC
-					| CLOCK_EVT_FEAT_ONESHOT,
+		.name			= "tc_clkevt",
+		.features		= CLOCK_EVT_FEAT_PERIODIC |
+					  CLOCK_EVT_FEAT_ONESHOT,
 		/* Should be lower than at91rm9200's system timer */
-		.rating		= 125,
-		.set_next_event	= tc_next_event,
-		.set_mode	= tc_mode,
+		.rating			= 125,
+		.set_next_event		= tc_next_event,
+		.set_state_shutdown	= tc_shutdown,
+		.set_state_periodic	= tc_set_periodic,
+		.set_state_oneshot	= tc_set_oneshot,
 	},
 };
 
-- 
1.9.1



From daniel.lezcano at linaro.org  Mon Aug 10 02:52:08 2015
From: daniel.lezcano at linaro.org (Daniel Lezcano)
Date: Mon, 10 Aug 2015 11:52:08 +0200
Subject: [PATCH 51/74] clockevents/drivers/exynos_mct: Migrate to new
 'set-state' interface
In-Reply-To: <1439200352-26767-1-git-send-email-daniel.lezcano@linaro.org>
References: <55C87382.4070309@linaro.org>
 <1439200352-26767-1-git-send-email-daniel.lezcano@linaro.org>
Message-ID: <1439200352-26767-51-git-send-email-daniel.lezcano@linaro.org>

From: Viresh Kumar <viresh.kumar at linaro.org>

Migrate exynos_mct driver to the new 'set-state' interface provided by
clockevents core, the earlier 'set-mode' interface is marked obsolete
now.

This also enables us to implement callbacks for new states of clockevent
devices, for example: ONESHOT_STOPPED.

Cc: Kukjin Kim <kgene.kim at samsung.com>
Signed-off-by: Viresh Kumar <viresh.kumar at linaro.org>
Signed-off-by: Daniel Lezcano <daniel.lezcano at linaro.org>
---
 drivers/clocksource/exynos_mct.c | 85 +++++++++++++++++++---------------------
 1 file changed, 40 insertions(+), 45 deletions(-)

diff --git a/drivers/clocksource/exynos_mct.c b/drivers/clocksource/exynos_mct.c
index 4d2330a..029f96a 100644
--- a/drivers/clocksource/exynos_mct.c
+++ b/drivers/clocksource/exynos_mct.c
@@ -257,15 +257,14 @@ static void exynos4_mct_comp0_stop(void)
 	exynos4_mct_write(0, EXYNOS4_MCT_G_INT_ENB);
 }
 
-static void exynos4_mct_comp0_start(enum clock_event_mode mode,
-				    unsigned long cycles)
+static void exynos4_mct_comp0_start(bool periodic, unsigned long cycles)
 {
 	unsigned int tcon;
 	cycle_t comp_cycle;
 
 	tcon = readl_relaxed(reg_base + EXYNOS4_MCT_G_TCON);
 
-	if (mode == CLOCK_EVT_MODE_PERIODIC) {
+	if (periodic) {
 		tcon |= MCT_G_TCON_COMP0_AUTO_INC;
 		exynos4_mct_write(cycles, EXYNOS4_MCT_G_COMP0_ADD_INCR);
 	}
@@ -283,38 +282,38 @@ static void exynos4_mct_comp0_start(enum clock_event_mode mode,
 static int exynos4_comp_set_next_event(unsigned long cycles,
 				       struct clock_event_device *evt)
 {
-	exynos4_mct_comp0_start(evt->mode, cycles);
+	exynos4_mct_comp0_start(false, cycles);
 
 	return 0;
 }
 
-static void exynos4_comp_set_mode(enum clock_event_mode mode,
-				  struct clock_event_device *evt)
+static int mct_set_state_shutdown(struct clock_event_device *evt)
 {
-	unsigned long cycles_per_jiffy;
 	exynos4_mct_comp0_stop();
+	return 0;
+}
 
-	switch (mode) {
-	case CLOCK_EVT_MODE_PERIODIC:
-		cycles_per_jiffy =
-			(((unsigned long long) NSEC_PER_SEC / HZ * evt->mult) >> evt->shift);
-		exynos4_mct_comp0_start(mode, cycles_per_jiffy);
-		break;
+static int mct_set_state_periodic(struct clock_event_device *evt)
+{
+	unsigned long cycles_per_jiffy;
 
-	case CLOCK_EVT_MODE_ONESHOT:
-	case CLOCK_EVT_MODE_UNUSED:
-	case CLOCK_EVT_MODE_SHUTDOWN:
-	case CLOCK_EVT_MODE_RESUME:
-		break;
-	}
+	cycles_per_jiffy = (((unsigned long long)NSEC_PER_SEC / HZ * evt->mult)
+			    >> evt->shift);
+	exynos4_mct_comp0_stop();
+	exynos4_mct_comp0_start(true, cycles_per_jiffy);
+	return 0;
 }
 
 static struct clock_event_device mct_comp_device = {
-	.name		= "mct-comp",
-	.features       = CLOCK_EVT_FEAT_PERIODIC | CLOCK_EVT_FEAT_ONESHOT,
-	.rating		= 250,
-	.set_next_event	= exynos4_comp_set_next_event,
-	.set_mode	= exynos4_comp_set_mode,
+	.name			= "mct-comp",
+	.features		= CLOCK_EVT_FEAT_PERIODIC |
+				  CLOCK_EVT_FEAT_ONESHOT,
+	.rating			= 250,
+	.set_next_event		= exynos4_comp_set_next_event,
+	.set_state_periodic	= mct_set_state_periodic,
+	.set_state_shutdown	= mct_set_state_shutdown,
+	.set_state_oneshot	= mct_set_state_shutdown,
+	.tick_resume		= mct_set_state_shutdown,
 };
 
 static irqreturn_t exynos4_mct_comp_isr(int irq, void *dev_id)
@@ -390,39 +389,32 @@ static int exynos4_tick_set_next_event(unsigned long cycles,
 	return 0;
 }
 
-static inline void exynos4_tick_set_mode(enum clock_event_mode mode,
-					 struct clock_event_device *evt)
+static int set_state_shutdown(struct clock_event_device *evt)
+{
+	exynos4_mct_tick_stop(this_cpu_ptr(&percpu_mct_tick));
+	return 0;
+}
+
+static int set_state_periodic(struct clock_event_device *evt)
 {
 	struct mct_clock_event_device *mevt = this_cpu_ptr(&percpu_mct_tick);
 	unsigned long cycles_per_jiffy;
 
+	cycles_per_jiffy = (((unsigned long long)NSEC_PER_SEC / HZ * evt->mult)
+			    >> evt->shift);
 	exynos4_mct_tick_stop(mevt);
-
-	switch (mode) {
-	case CLOCK_EVT_MODE_PERIODIC:
-		cycles_per_jiffy =
-			(((unsigned long long) NSEC_PER_SEC / HZ * evt->mult) >> evt->shift);
-		exynos4_mct_tick_start(cycles_per_jiffy, mevt);
-		break;
-
-	case CLOCK_EVT_MODE_ONESHOT:
-	case CLOCK_EVT_MODE_UNUSED:
-	case CLOCK_EVT_MODE_SHUTDOWN:
-	case CLOCK_EVT_MODE_RESUME:
-		break;
-	}
+	exynos4_mct_tick_start(cycles_per_jiffy, mevt);
+	return 0;
 }
 
 static void exynos4_mct_tick_clear(struct mct_clock_event_device *mevt)
 {
-	struct clock_event_device *evt = &mevt->evt;
-
 	/*
 	 * This is for supporting oneshot mode.
 	 * Mct would generate interrupt periodically
 	 * without explicit stopping.
 	 */
-	if (evt->mode != CLOCK_EVT_MODE_PERIODIC)
+	if (!clockevent_state_periodic(&mevt->evt))
 		exynos4_mct_tick_stop(mevt);
 
 	/* Clear the MCT tick interrupt */
@@ -453,7 +445,10 @@ static int exynos4_local_timer_setup(struct mct_clock_event_device *mevt)
 	evt->name = mevt->name;
 	evt->cpumask = cpumask_of(cpu);
 	evt->set_next_event = exynos4_tick_set_next_event;
-	evt->set_mode = exynos4_tick_set_mode;
+	evt->set_state_periodic = set_state_periodic;
+	evt->set_state_shutdown = set_state_shutdown;
+	evt->set_state_oneshot = set_state_shutdown;
+	evt->tick_resume = set_state_shutdown;
 	evt->features = CLOCK_EVT_FEAT_PERIODIC | CLOCK_EVT_FEAT_ONESHOT;
 	evt->rating = 450;
 
@@ -479,7 +474,7 @@ static void exynos4_local_timer_stop(struct mct_clock_event_device *mevt)
 {
 	struct clock_event_device *evt = &mevt->evt;
 
-	evt->set_mode(CLOCK_EVT_MODE_UNUSED, evt);
+	evt->set_state_shutdown(evt);
 	if (mct_int_type == MCT_INT_SPI) {
 		if (evt->irq != -1)
 			disable_irq_nosync(evt->irq);
-- 
1.9.1



From julien.grall at citrix.com  Mon Aug 10 02:57:48 2015
From: julien.grall at citrix.com (Julien Grall)
Date: Mon, 10 Aug 2015 10:57:48 +0100
Subject: [PATCH v3 18/20] net/xen-netback: Make it running on 64KB page
 granularity
In-Reply-To: <20150808145534.GB14214@zion.uk.xensource.com>
References: <1438966019-19322-1-git-send-email-julien.grall@citrix.com>
 <1438966019-19322-19-git-send-email-julien.grall@citrix.com>
 <20150808145534.GB14214@zion.uk.xensource.com>
Message-ID: <55C8759C.3010507@citrix.com>

Hi Wei,

On 08/08/2015 15:55, Wei Liu wrote:
>>   struct xenvif_rx_meta {
>>   	int id;
>> @@ -80,16 +81,18 @@ struct xenvif_rx_meta {
>>   /* Discriminate from any valid pending_idx value. */
>>   #define INVALID_PENDING_IDX 0xFFFF
>>
>> -#define MAX_BUFFER_OFFSET PAGE_SIZE
>> +#define MAX_BUFFER_OFFSET XEN_PAGE_SIZE
>>
>>   #define MAX_PENDING_REQS XEN_NETIF_TX_RING_SIZE
>>
>> +#define MAX_XEN_SKB_FRAGS (65536 / XEN_PAGE_SIZE + 1)
>> +
>
> It might be clearer if you add a comment saying the maximum number of
> frags is derived from the page size of the grant page, which happens to
> be XEN_PAGE_SIZE at the moment.

Will do.


> In the future we need to figure out the page size of grant page in a
> dynamic way. We shall cross the bridge when we get there.

Right, there is few other places where we would need to do that too (see 
MAX_BUFFER_OFFSET for instance).


[..]

>> +		info.page = page;
>> +		gnttab_foreach_grant_in_range(page, offset, bytes,
>> +					      xenvif_gop_frag_copy_grant,
>> +					      &info);
>
> Looks like I need to at least wait until the API is settle before giving
> my ack.
>
>>   		size -= bytes;
>> +		offset = 0;
>
> This looks wrong. Should be offset += bytes.

With the new implementation of the loop, each iteration will be on a 
different page.
So only the first page has an offset different than zero.

>
>>
>> -		/* Next frame */
>> -		if (offset == PAGE_SIZE && size) {
>> +		/* Next page */
>> +		if (size) {
>>   			BUG_ON(!PageCompound(page));
>>   			page++;
>> -			offset = 0;
>
> And this should not be deleted, I think.
>
> What is the reason for changing offset calculation? I think there is
> still compound page when using 64K page.

The compound pages are still working ... gnttab_foreach_grant_in_range 
is called once per page. So the offset can be reset to 0 every time. No 
need to add code which would make the result less clear.

We only need to know if the size is not 0 to get the next page.

The patch may not be clear enough to see it's working so I've copied the 
result loop below:

         while (size > 0) {
                 BUG_ON(offset >= PAGE_SIZE);

                 bytes = PAGE_SIZE - offset;
                 if (bytes > size)
                         bytes = size;

                 info.page = page;
                 gnttab_foreach_grant_in_range(page, offset, bytes,
                                              xenvif_gop_frag_copy_grant,
                                               &info);
                 size -= bytes;
                 offset = 0;

                 /* Next page */
                 if (size) {
                         BUG_ON(!PageCompound(page));
                         page++;
                 }
         }

Regards,

-- 
Julien Grall


From linus.walleij at linaro.org  Mon Aug 10 03:02:13 2015
From: linus.walleij at linaro.org (Linus Walleij)
Date: Mon, 10 Aug 2015 12:02:13 +0200
Subject: [PATCH 6/6] gpiolib: Add gpio name information to
 /sys/kernel/debug/gpio
In-Reply-To: <1438680203-13432-7-git-send-email-mpa@pengutronix.de>
References: <1438680203-13432-1-git-send-email-mpa@pengutronix.de>
 <1438680203-13432-7-git-send-email-mpa@pengutronix.de>
Message-ID: <CACRpkdajd5B6qUa6mi_0m53eMtLenoAWUCnmq-mOC+EhXfzpTA@mail.gmail.com>

On Tue, Aug 4, 2015 at 11:23 AM, Markus Pargmann <mpa at pengutronix.de> wrote:

> Add some information about gpio names to the debugfs gpio file. name and
> label of a GPIO are then displayed next to each other. This way it is
> easy to see what the real name of GPIO is and what the driver requested
> it for.
>
> Signed-off-by: Markus Pargmann <mpa at pengutronix.de>

This patch looks correct in the context.

Yours,
Linus Walleij


From stefano.stabellini at eu.citrix.com  Mon Aug 10 03:10:17 2015
From: stefano.stabellini at eu.citrix.com (Stefano Stabellini)
Date: Mon, 10 Aug 2015 11:10:17 +0100
Subject: [PATCH v3 02/20] arm/xen: Drop pte_mfn and mfn_pte
In-Reply-To: <1438966019-19322-3-git-send-email-julien.grall@citrix.com>
References: <1438966019-19322-1-git-send-email-julien.grall@citrix.com>
 <1438966019-19322-3-git-send-email-julien.grall@citrix.com>
Message-ID: <alpine.DEB.2.02.1508101110080.11337@kaball.uk.xensource.com>

On Fri, 7 Aug 2015, Julien Grall wrote:
> They are not used in common code expect in one place in balloon.c which is
> only compiled when Linux is using PV MMU. It's not the case on ARM.
> 
> Rather than worrying how to handle the 64KB case, drop them.
> 
> Signed-off-by: Julien Grall <julien.grall at citrix.com>

Reviewed-by: Stefano Stabellini <stefano.stabellini at eu.citrix.com>


> Stefano Stabellini <stefano.stabellini at eu.citrix.com>
> Russell King <linux at arm.linux.org.uk>
> 
>     Changes in v3:
>         - Patch added
> ---
>  arch/arm/include/asm/xen/page.h | 3 ---
>  1 file changed, 3 deletions(-)
> 
> diff --git a/arch/arm/include/asm/xen/page.h b/arch/arm/include/asm/xen/page.h
> index 1279563..98c9fc3 100644
> --- a/arch/arm/include/asm/xen/page.h
> +++ b/arch/arm/include/asm/xen/page.h
> @@ -13,9 +13,6 @@
>  
>  #define phys_to_machine_mapping_valid(pfn) (1)
>  
> -#define pte_mfn	    pte_pfn
> -#define mfn_pte	    pfn_pte
> -
>  /* Xen machine address */
>  typedef struct xmaddr {
>  	phys_addr_t maddr;
> -- 
> 2.1.4
> 


From wxt at rock-chips.com  Mon Aug 10 03:22:40 2015
From: wxt at rock-chips.com (Caesar Wang)
Date: Mon, 10 Aug 2015 18:22:40 +0800
Subject: [PATCH] thermal: rockchip: fix handling of invalid readings
In-Reply-To: <CAE_wzQ_xhh17tsVj28W5Z=mgomnz1nOMPMN15Sozb8KcMjo=wA@mail.gmail.com>
References: <20150807205923.GA33949@dtor-ws>	<55C84521.5040007@rock-chips.com>
 <CAE_wzQ_xhh17tsVj28W5Z=mgomnz1nOMPMN15Sozb8KcMjo=wA@mail.gmail.com>
Message-ID: <55C87B70.5050805@rock-chips.com>



? 2015?08?10? 15:59, Dmitry Torokhov ??:
> Hi Caesar,
>
> On Sun, Aug 9, 2015 at 11:30 PM, Caesar Wang <wxt at rock-chips.com> wrote:
>> Dear Dmitry,
>>
>> Thanks your patch.
>>
>> The code looks like fine,but I don't think the TS-ADC will work on rk3288
>> SoC.
> What do you mean? It seems to work when I ran it...

Making a mistake.:-(

>>
>> ? 2015?08?08? 04:59, Dmitry Torokhov ??:
>>> We attempted to signal invalid code by returning -EAGAIN from
>>> rk_tsadcv2_code_to_temp(), unfortunately the return value was stuffed
>>> directly into the temperature pointer, potentially confusing upper
>>> layers with temperature of -EINVAL.
>>>
>>> Let's split temperature from error/success indicator to avoid such
>>> confusion.
>>>
>>> Also change the way we scan the temperature table to start with the 2nd
>>> element so that we do not need to worry that we may reference out of
>>> bounds element while doing binary search and keep checking that we end
>>> up with 'mid' equal to 0 (since we are looking for the temperature that
>>> would fall into interval between the 'mid' and 'mid - 1') .
>>>
>>> Signed-off-by: Dmitry Torokhov <dtor at chromium.org>
>>> ---
>>>    drivers/thermal/rockchip_thermal.c | 28 +++++++++++++---------------
>>>    1 file changed, 13 insertions(+), 15 deletions(-)
>>>
>>> diff --git a/drivers/thermal/rockchip_thermal.c
>>> b/drivers/thermal/rockchip_thermal.c
>>> index c89ffb2..93ee307 100644
>>> --- a/drivers/thermal/rockchip_thermal.c
>>> +++ b/drivers/thermal/rockchip_thermal.c
>>> @@ -124,7 +124,7 @@ struct rockchip_thermal_data {
>>>    #define TSADCV2_AUTO_PERIOD_HT_TIME           50  /* msec */
>>>      struct tsadc_table {
>>> -       unsigned long code;
>>> +       u32 code;
>>>          long temp;
>>>    };
>>>    @@ -164,7 +164,6 @@ static const struct tsadc_table v2_code_table[] = {
>>>          {3452, 115000},
>>>          {3437, 120000},
>>>          {3421, 125000},
>>> -       {0, 125000},
>>>    };
>>>      static u32 rk_tsadcv2_temp_to_code(long temp)
>>> @@ -191,19 +190,21 @@ static u32 rk_tsadcv2_temp_to_code(long temp)
>>>          return 0;
>>>    }
>>>    -static int rk_tsadcv2_code_to_temp(u32 code)
>>> +static int rk_tsadcv2_code_to_temp(u32 code, int *temp)

It's wired that can't git-am this patch.

I search the Eduardo'branch[0] for rockchip-thermal.c driver. The 
function is "static long rk_tsadcv2_code_to_temp(u32 code)"

Maybe i'm missing something, I verified this patch on my board but this 
fixed.

So you can free add it:
Tested-by: Caesar Wang <wxt at rock-chips.com>

[0]:
url = 
git://git.kernel.org/pub/scm/linux/kernel/git/evalenti/linux-soc-thermal.git



---
Thanks,
Caesar



>>>    {
>>> -       unsigned int low = 0;
>>> +       unsigned int low = 1;
>>>          unsigned int high = ARRAY_SIZE(v2_code_table) - 1;
>>>          unsigned int mid = (low + high) / 2;
>>>          unsigned int num;
>>>          unsigned long denom;
>>>    -     /* Invalid code, return -EAGAIN */
>>> -       if (code > TSADCV2_DATA_MASK)
>>> -               return -EAGAIN;
>>> +       BUILD_BUG_ON(ARRAY_SIZE(v2_code_table) < 2);
>>>    -     while (low <= high && mid) {
>>> +       code &= TSADCV2_DATA_MASK;
>>> +       if (code < v2_code_table[high].code)
>>> +               return -EAGAIN;         /* Incorrect reading */
>>> +
>>> +       while (low <= high) {
>>>                  if (code >= v2_code_table[mid].code &&
>>>                      code < v2_code_table[mid - 1].code)
>>>                          break;
>>> @@ -223,7 +224,9 @@ static int rk_tsadcv2_code_to_temp(u32 code)
>>>          num = v2_code_table[mid].temp - v2_code_table[mid - 1].temp;
>>>          num *= v2_code_table[mid - 1].code - code;
>>>          denom = v2_code_table[mid - 1].code - v2_code_table[mid].code;
>>> -       return v2_code_table[mid - 1].temp + (num / denom);
>>> +       *temp = v2_code_table[mid - 1].temp + (num / denom);
>>> +
>>> +       return 0;
>>>    }
>>>      /**
>>> @@ -281,14 +284,9 @@ static int rk_tsadcv2_get_temp(int chn, void __iomem
>>> *regs, int *temp)
>>>    {
>>>          u32 val;
>>>    -     /* the A/D value of the channel last conversion need some time */
>>>          val = readl_relaxed(regs + TSADCV2_DATA(chn));
>>> -       if (val == 0)
>>> -               return -EAGAIN;
>>> -
>>
>> if we reserve the above code, that will get the ADC value.
> But if we pass  0 into rk_tsadcv2_code_to_temp() it will trigger:
>
>>> +       if (code < v2_code_table[high].code)
>>> +               return -EAGAIN;         /* Incorrect reading */
> and still return -EAGAIN, as it was. There is no behavior change as
> far as I can see.
Yup, that's ok for me.

>>
>>> -       *temp = rk_tsadcv2_code_to_temp(val);
>>>    -     return 0;
>>> +       return rk_tsadcv2_code_to_temp(val, temp);
>>>    }
>>>      static void rk_tsadcv2_tshut_temp(int chn, void __iomem *regs, long
>>> temp)
>>
> Thanks,
> Dmitry
>
>
>




From broonie at kernel.org  Mon Aug 10 03:25:15 2015
From: broonie at kernel.org (Mark Brown)
Date: Mon, 10 Aug 2015 11:25:15 +0100
Subject: [PATCH v3 01/18] platform: delay OF device-driver matches until
 late_initcall
In-Reply-To: <CAAObsKDJsuhuQfLbxq27Mtm1T_Auz7Gohp8PDyK7rNNDyaGhcg@mail.gmail.com>
References: <1438870315-18689-1-git-send-email-tomeu.vizoso@collabora.com>
 <1438870315-18689-2-git-send-email-tomeu.vizoso@collabora.com>
 <CAL_Jsq+GLMZe-f6qEi=7i1YrrWc6k99RpGkOyCd5KkYDiyt0QA@mail.gmail.com>
 <CAAObsKBapFqzr+4YEXJfcJWMd+tkaBqYbGiFTntHStAP=+P-_Q@mail.gmail.com>
 <55C4E597.1010701@ti.com>
 <CAAObsKDJsuhuQfLbxq27Mtm1T_Auz7Gohp8PDyK7rNNDyaGhcg@mail.gmail.com>
Message-ID: <20150810102515.GA1965@sirena.org.uk>

On Sun, Aug 09, 2015 at 03:03:14PM +0200, Tomeu Vizoso wrote:

> There was some recent thread about how the disabling of unused clocks
> and regulators isn't really safe because after late_initcall_sync more
> drivers can be registered from modules. Furthermore, there's async
> device probes.

What recent thread and why would that be unsafe?  Any driver using a
clock or regulator ought to be making sure that the clock or regulator
is enabled before it tries to use it.  The worst that should happen is
that something gets the power bounced during boot which isn't the end of
the world.
-------------- next part --------------
A non-text attachment was scrubbed...
Name: signature.asc
Type: application/pgp-signature
Size: 473 bytes
Desc: Digital signature
URL: <http://lists.infradead.org/pipermail/linux-arm-kernel/attachments/20150810/5a6b2746/attachment.sig>

From srinivas.kandagatla at linaro.org  Mon Aug 10 03:37:35 2015
From: srinivas.kandagatla at linaro.org (Srinivas Kandagatla)
Date: Mon, 10 Aug 2015 11:37:35 +0100
Subject: [PATCH v9 0/9] Add simple NVMEM Framework via regmap.
In-Reply-To: <20150809151916.GF14271@lunn.ch>
References: <1437995567-11203-1-git-send-email-srinivas.kandagatla@linaro.org>
 <1438693367.3793.29.camel@pengutronix.de> <20150809151916.GF14271@lunn.ch>
Message-ID: <55C87EEF.6020609@linaro.org>

Hi Andrew,

On 09/08/15 16:19, Andrew Lunn wrote:
> Hi Srinivas
>
> The AT24 eeprom driver contains the comment:
>
>          /*
>           * Export the EEPROM bytes through sysfs, since that's convenient.
>           * By default, only root should see the data (maybe passwords etc)
>           */
>
> and as you would expect from this:
>
> # ls -l ./devices/platform/soc/soc:aips-bus at 40000000/40066000.i2c/i2c-0/0-0050/eeprom
> -rw------- 1 root root 512 Aug  9 10:16 ./devices/platform/soc/soc:aips-bus at 40000000/40066000.i2c/i2c-0/0-0050/eeprom
>
> The AT25 and the MAX6875 driver are the same.
>
> However nvmem has different defaults:
>
> # ls -l ./devices/platform/soc/soc:aips-bus at 40000000/40066000.i2c/i2c-0/0-0050/0-00500/nvmem
> -rw-r--r-- 1 root root 0 Aug  9 10:16 ./devices/platform/soc/soc:aips-bus at 40000000/40066000.i2c/i2c-0/0-0050/0-00500/nvmem
>
Yes, nvmem by default sets the read permission for everyone S_IRUGO. 
Which was the most common use case.

> Has this been considered and discussed?
Thanks for bringing this up, No, we did not discuss this explicitly, but 
it should not be an issue to accommodate this. Provider still have 
flexibility to configure such things.

As a first patchset we wanted to keep the framework simple and add 
features as we move on.

Thanks,
srini
>
> Thanks
>      Andrew
>


From linux at arm.linux.org.uk  Mon Aug 10 03:39:21 2015
From: linux at arm.linux.org.uk (Russell King - ARM Linux)
Date: Mon, 10 Aug 2015 11:39:21 +0100
Subject: [PATCH 1/9] drm: bridge/dw_hdmi-ahb-audio: add audio driver
In-Reply-To: <s5hk2t35ui4.wl-tiwai@suse.de>
References: <20150808160936.GN7557@n2100.arm.linux.org.uk>
 <E1ZO6hC-0003M5-EU@rmk-PC.arm.linux.org.uk>
 <s5hk2t35ui4.wl-tiwai@suse.de>
Message-ID: <20150810103921.GR7557@n2100.arm.linux.org.uk>

On Mon, Aug 10, 2015 at 12:05:07PM +0200, Takashi Iwai wrote:
> On Sat, 08 Aug 2015 18:10:06 +0200,
> Russell King wrote:
> > +static irqreturn_t snd_dw_hdmi_irq(int irq, void *data)
> > +{
> > +	struct snd_dw_hdmi *dw = data;
> > +	struct snd_pcm_substream *substream;
> > +	unsigned stat;
> > +
> > +	stat = readb_relaxed(dw->data.base + HDMI_IH_AHBDMAAUD_STAT0);
> > +	if (!stat)
> > +		return IRQ_NONE;
> > +
> > +	writeb_relaxed(stat, dw->data.base + HDMI_IH_AHBDMAAUD_STAT0);
> > +
> > +	substream = dw->substream;
> > +	if (stat & HDMI_IH_AHBDMAAUD_STAT0_DONE && substream) {
> > +		snd_pcm_period_elapsed(substream);
> > +		if (dw->substream)
> > +			dw_hdmi_start_dma(dw);
> > +	}
> 
> Don't we need locking?

Possibly.

> In theory, the trigger can be issued while the irq is being handled.

Well, we can't have a lock around the whole of the above, because that
results in deadlock (as snd_pcm_period_elapsed() can end up calling into
the trigger method.)  I'm not happy to throw a spinlock around this
because of the in-built format conversion (something else I'm really not
happy about - which has to exist here because alsalib is soo painful
to add custom sample reformatting to - such modules have to be built
as part of alsalib itself rather than an add-on module.)

> > +static int dw_hdmi_trigger(struct snd_pcm_substream *substream, int cmd)
> > +{
> > +	struct snd_dw_hdmi *dw = substream->private_data;
> > +	int ret = 0;
> > +
> > +	switch (cmd) {
> > +	case SNDRV_PCM_TRIGGER_START:
> > +		dw->buf_offset = 0;
> > +		dw->substream = substream;
> > +		dw_hdmi_start_dma(dw);
> > +		dw_hdmi_audio_enable(dw->data.hdmi);
> > +		substream->runtime->delay = substream->runtime->period_size;
> > +		break;
> > +
> > +	case SNDRV_PCM_TRIGGER_STOP:
> > +		dw_hdmi_stop_dma(dw);
> > +		dw_hdmi_audio_disable(dw->data.hdmi);
> > +		break;
> > +
> > +	default:
> > +		ret = -EINVAL;
> > +		break;
> 
> SNDRV_PCM_TRIGGER_SUSPEND may be passed at suspend, too.

I think rather than adding code which would be difficult for me to test,
I'd instead remove the suspend/resume callbacks, or at least disable them
until someone can test that feature, or is willing to implement it.

> > +static snd_pcm_uframes_t dw_hdmi_pointer(struct snd_pcm_substream *substream)
> > +{
> > +	struct snd_pcm_runtime *runtime = substream->runtime;
> > +	struct snd_dw_hdmi *dw = substream->private_data;
> > +
> > +	return bytes_to_frames(runtime, dw->buf_offset);
> 
> So, this returns the offset that has been reformatted.  Does the
> hardware support any better position reporting?  We may give the delay
> from the driver if possible.

Basically, no.  Reading a 32-bit DMA position as separate bytes while
DMA is active is racy.

This is the best we can do, and the way we report the position has been
arrived at after what's getting on for two years of testing with
pulseaudio, vlc direct access & spdif pass-through, aplay, etc:

Author: Russell King <rmk+kernel at arm.linux.org.uk>
Date:   Thu Nov 7 16:01:45 2013 +0000

    drm: bridge/dw_hdmi-ahb-audio: add audio driver

-- 
FTTC broadband for 0.8mile line: currently at 10.5Mbps down 400kbps up
according to speedtest.net.


From stefano.stabellini at eu.citrix.com  Mon Aug 10 03:44:48 2015
From: stefano.stabellini at eu.citrix.com (Stefano Stabellini)
Date: Mon, 10 Aug 2015 11:44:48 +0100
Subject: [PATCH v3 04/20] xen/grant: Introduce helpers to split a page
 into grant
In-Reply-To: <1438966019-19322-5-git-send-email-julien.grall@citrix.com>
References: <1438966019-19322-1-git-send-email-julien.grall@citrix.com>
 <1438966019-19322-5-git-send-email-julien.grall@citrix.com>
Message-ID: <alpine.DEB.2.02.1508101143180.11337@kaball.uk.xensource.com>

On Fri, 7 Aug 2015, Julien Grall wrote:
> Currently, a grant is always based on the Xen page granularity (i.e
> 4KB). When Linux is using a different page granularity, a single page
> will be split between multiple grants.
> 
> The new helpers will be in charge to split the Linux page into grants and
                                    ^ of splitting

> call a function given by the caller on each grant.
> 
> Also provide an helper to count the number of grants within a given
> contiguous region.
> 
> Note that the x86/include/asm/xen/page.h is now including
> xen/interface/grant_table.h rather than xen/grant_table.h. It's
> necessary because xen/grant_table.h depends on asm/xen/page.h and will
> break the compilation. Furthermore, only definition in
> interface/grant_table.h was required.
                           ^ is

> Signed-off-by: Julien Grall <julien.grall at citrix.com>

Reviewed-by: Stefano Stabellini <stefano.stabellini at eu.citrix.com>


> ---
> Cc: Konrad Rzeszutek Wilk <konrad.wilk at oracle.com>
> Cc: Boris Ostrovsky <boris.ostrovsky at oracle.com>
> Cc: David Vrabel <david.vrabel at citrix.com>
> Cc: Thomas Gleixner <tglx at linutronix.de>
> Cc: Ingo Molnar <mingo at redhat.com>
> Cc: "H. Peter Anvin" <hpa at zytor.com>
> Cc: x86 at kernel.org
> 
>     Changes in v3:
>         - Fix error reported by checkpatch.pl
>         - Typoes
>         - s/pfn/xen_pfn/ in gnttab_foreach_grant
>         - Drop the possibility to use less data. The complexity is moved
>         in netback which is the only user
>         - Rename gnttab_foreach_grant into gnttab_foreach_grant_in_range
>         - s/offset/start/ in gnttab_count_grant and update the
>         description of the parameter
>         - s/mfn/gfn base on the new terminologies
>         - Add EXPORT_SYMBOL_GPL for gnttab_foreach_grant_in_range
>         - Use xen_offset_in_page and XEN_PFN_DOWN whenever it's possible
>         - Fix compilation on x86.
> 
>     Changes in v2:
>         - Patch added
> ---
>  arch/x86/include/asm/xen/page.h |  2 +-
>  drivers/xen/grant-table.c       | 26 +++++++++++++++++++++++++
>  include/xen/grant_table.h       | 42 +++++++++++++++++++++++++++++++++++++++++
>  3 files changed, 69 insertions(+), 1 deletion(-)
> 
> diff --git a/arch/x86/include/asm/xen/page.h b/arch/x86/include/asm/xen/page.h
> index 0b762f6..501479e 100644
> --- a/arch/x86/include/asm/xen/page.h
> +++ b/arch/x86/include/asm/xen/page.h
> @@ -12,7 +12,7 @@
>  #include <asm/pgtable.h>
>  
>  #include <xen/interface/xen.h>
> -#include <xen/grant_table.h>
> +#include <xen/interface/grant_table.h>
>  #include <xen/features.h>
>  
>  /* Xen machine address */
> diff --git a/drivers/xen/grant-table.c b/drivers/xen/grant-table.c
> index 62f591f..94ae0fd 100644
> --- a/drivers/xen/grant-table.c
> +++ b/drivers/xen/grant-table.c
> @@ -776,6 +776,32 @@ void gnttab_batch_copy(struct gnttab_copy *batch, unsigned count)
>  }
>  EXPORT_SYMBOL_GPL(gnttab_batch_copy);
>  
> +void gnttab_foreach_grant_in_range(struct page *page,
> +				   unsigned int offset,
> +				   unsigned int len,
> +				   xen_grant_fn_t fn,
> +				   void *data)
> +{
> +	unsigned int goffset;
> +	unsigned int glen;
> +	unsigned long xen_pfn;
> +
> +	len = min_t(unsigned int, PAGE_SIZE - offset, len);
> +	goffset = xen_offset_in_page(offset);
> +
> +	xen_pfn = xen_page_to_pfn(page) + XEN_PFN_DOWN(offset);
> +
> +	while (len) {
> +		glen = min_t(unsigned int, XEN_PAGE_SIZE - goffset, len);
> +		fn(pfn_to_gfn(xen_pfn), goffset, glen, data);
> +
> +		goffset = 0;
> +		xen_pfn++;
> +		len -= glen;
> +	}
> +}
> +EXPORT_SYMBOL_GPL(gnttab_foreach_grant_in_range);
> +
>  int gnttab_map_refs(struct gnttab_map_grant_ref *map_ops,
>  		    struct gnttab_map_grant_ref *kmap_ops,
>  		    struct page **pages, unsigned int count)
> diff --git a/include/xen/grant_table.h b/include/xen/grant_table.h
> index 4478f4b..2a8ebe8 100644
> --- a/include/xen/grant_table.h
> +++ b/include/xen/grant_table.h
> @@ -45,8 +45,10 @@
>  #include <asm/xen/hypervisor.h>
>  
>  #include <xen/features.h>
> +#include <xen/page.h>
>  #include <linux/mm_types.h>
>  #include <linux/page-flags.h>
> +#include <linux/kernel.h>
>  
>  #define GNTTAB_RESERVED_XENSTORE 1
>  
> @@ -224,4 +226,44 @@ static inline struct xen_page_foreign *xen_page_foreign(struct page *page)
>  #endif
>  }
>  
> +/* Split Linux page in chunk of the size of the grant and call fn
> + *
> + * Parameters of fn:
> + *	gfn: guest frame number
> + *	offset: offset in the grant
> + *	len: length of the data in the grant.
> + *	data: internal information
> + */
> +typedef void (*xen_grant_fn_t)(unsigned long gfn, unsigned int offset,
> +			       unsigned int len, void *data);
> +
> +void gnttab_foreach_grant_in_range(struct page *page,
> +				   unsigned int offset,
> +				   unsigned int len,
> +				   xen_grant_fn_t fn,
> +				   void *data);
> +
> +/* Helper to get to call fn only on the first "grant chunk" */
> +static inline void gnttab_one_grant(struct page *page, unsigned int offset,
> +				    unsigned len, xen_grant_fn_t fn,
> +				    void *data)
> +{
> +	/* The first request is limited to the size of one grant */
> +	len = min_t(unsigned int, XEN_PAGE_SIZE - (offset & ~XEN_PAGE_MASK),
> +		    len);
> +
> +	gnttab_foreach_grant_in_range(page, offset, len, fn, data);
> +}
> +
> +/* Get the number of grant in a specified region
> + *
> + * start: Offset from the beginning of the first page
> + * len: total length of data (can cross multiple page)
> + */
> +static inline unsigned int gnttab_count_grant(unsigned int start,
> +					      unsigned int len)
> +{
> +	return XEN_PFN_UP(xen_offset_in_page(start) + len);
> +}
> +
>  #endif /* __ASM_GNTTAB_H__ */
> -- 
> 2.1.4
> 


From stefano.stabellini at eu.citrix.com  Mon Aug 10 03:46:33 2015
From: stefano.stabellini at eu.citrix.com (Stefano Stabellini)
Date: Mon, 10 Aug 2015 11:46:33 +0100
Subject: [PATCH v3 03/20] xen: Add Xen specific page definition
In-Reply-To: <1438966019-19322-4-git-send-email-julien.grall@citrix.com>
References: <1438966019-19322-1-git-send-email-julien.grall@citrix.com>
 <1438966019-19322-4-git-send-email-julien.grall@citrix.com>
Message-ID: <alpine.DEB.2.02.1508101145380.11337@kaball.uk.xensource.com>

On Fri, 7 Aug 2015, Julien Grall wrote:
> The Xen hypercall interface is always using 4K page granularity on ARM
> and x86 architecture.
> 
> With the incoming support of 64K page granularity for ARM64 guest, it
> won't be possible to re-use the Linux page definition in Xen drivers.
> 
> Introduce Xen page definition helpers based on the Linux page
> definition. They have exactly the same name but prefixed with
> XEN_/xen_ prefix.
> 
> Also modify xen_page_to_gfn to use new Xen page definition.
> 
> Signed-off-by: Julien Grall <julien.grall at citrix.com>
> Reviewed-by: Stefano Stabellini <stefano.stabellini at eu.citrix.com>
> 
> ---
> Cc: Konrad Rzeszutek Wilk <konrad.wilk at oracle.com>
> Cc: Boris Ostrovsky <boris.ostrovsky at oracle.com>
> Cc: David Vrabel <david.vrabel at citrix.com>
> 
>     Changes in v3:
>         - Fix errors reported by checkpatch.pl
>         - Rename pfn to xen_pfn in xen_pfn_to_page
>         - Add a comment that we assume PAGE_SIZE to be a multiple of
>         XEN_PAGE_SIZE
>         - s/MFN/GFN/ according to new naming
>         - Add Stefano's reviewed-by
> 
>     Changes in v2:
>         - Add XEN_PFN_UP
>         - Add a comment describing the behavior of page_to_pfn
> ---
>  include/xen/page.h | 27 ++++++++++++++++++++++++++-
>  1 file changed, 26 insertions(+), 1 deletion(-)
> 
> diff --git a/include/xen/page.h b/include/xen/page.h
> index f202992..dac1b26 100644
> --- a/include/xen/page.h
> +++ b/include/xen/page.h
> @@ -1,11 +1,36 @@
>  #ifndef _XEN_PAGE_H
>  #define _XEN_PAGE_H
>  
> +#include <asm/page.h>
> +
> +/* The hypercall interface supports only 4KB page */
> +#define XEN_PAGE_SHIFT	12
> +#define XEN_PAGE_SIZE	(_AC(1, UL) << XEN_PAGE_SHIFT)
> +#define XEN_PAGE_MASK	(~(XEN_PAGE_SIZE-1))
> +#define xen_offset_in_page(p)	((unsigned long)(p) & ~XEN_PAGE_MASK)
> +
> +/*
> + * We asume that PAGE_SIZE is a multiple of XEN_PAGE_SIZE
          ^ assume

> + * XXX: Add a BUILD_BUG_ON?
> + */
> +
> +#define xen_pfn_to_page(xen_pfn)	\
> +	((pfn_to_page(((unsigned long)(xen_pfn) << XEN_PAGE_SHIFT) >> PAGE_SHIFT)))
> +#define xen_page_to_pfn(page)	\
> +	(((page_to_pfn(page)) << PAGE_SHIFT) >> XEN_PAGE_SHIFT)
> +
> +#define XEN_PFN_PER_PAGE	(PAGE_SIZE / XEN_PAGE_SIZE)
> +
> +#define XEN_PFN_DOWN(x)	((x) >> XEN_PAGE_SHIFT)
> +#define XEN_PFN_UP(x)	(((x) + XEN_PAGE_SIZE-1) >> XEN_PAGE_SHIFT)
> +#define XEN_PFN_PHYS(x)	((phys_addr_t)(x) << XEN_PAGE_SHIFT)
> +
>  #include <asm/xen/page.h>
>  
> +/* Return the GFN associated to the first 4KB of the page */
>  static inline unsigned long xen_page_to_gfn(struct page *page)
>  {
> -	return pfn_to_gfn(page_to_pfn(page));
> +	return pfn_to_gfn(xen_page_to_pfn(page));
>  }
>  
>  struct xen_memory_region {
> -- 
> 2.1.4
> 


From stefano.stabellini at eu.citrix.com  Mon Aug 10 03:50:45 2015
From: stefano.stabellini at eu.citrix.com (Stefano Stabellini)
Date: Mon, 10 Aug 2015 11:50:45 +0100
Subject: [PATCH v3 09/20] xen/biomerge: Don't allow biovec to be merge
 when Linux is not using 4KB page
In-Reply-To: <1438966019-19322-10-git-send-email-julien.grall@citrix.com>
References: <1438966019-19322-1-git-send-email-julien.grall@citrix.com>
 <1438966019-19322-10-git-send-email-julien.grall@citrix.com>
Message-ID: <alpine.DEB.2.02.1508101149070.11337@kaball.uk.xensource.com>

On Fri, 7 Aug 2015, Julien Grall wrote:
> On ARM all dma-capable devices on a same platform may not be protected
> by an IOMMU. The DMA requests have to use the BFN (i.e MFN on ARM) in
> order to use correctly the device.
> 
> While the DOM0 memory is allocated in a 1:1 fashion (PFN == MFN), grant
> mapping will screw this contiguous mapping.
> 
> When Linux is using 64KB page granularitary, the page may be split
> accross multiple non-contiguous MFN (Xen is using 4KB page
> granularity). Therefore a DMA request will likely fail.
> 
> Checking that a 64KB page is using contiguous MFN is tedious. For
> now, always says that biovec are not mergeable.
> 
> Signed-off-by: Julien Grall <julien.grall at citrix.com>

Please fix the grammar in the subject line.

Reviewed-by: Stefano Stabellini <stefano.stabellini at eu.citrix.com>


> ---
> Cc: Konrad Rzeszutek Wilk <konrad.wilk at oracle.com>
> Cc: Boris Ostrovsky <boris.ostrovsky at oracle.com>
> Cc: David Vrabel <david.vrabel at citrix.com>
> 
>     There is some ideas to check whether two biovec could be merged
>     (see [1]) but it's not critical and can be consider as a performance
>     improvement.
> 
>     Changes in v3:
>         - Update commit message
>         - s/mfn/bfn/ base on the new renaming
>         - Update TODO
> 
>     Changes in v2:
>         - Remove the workaround and check if the Linux page granularity
>         is the same as Xen or not
> 
>     [1] https://lkml.org/lkml/2015/7/17/418
> ---
>  drivers/xen/biomerge.c | 8 ++++++++
>  1 file changed, 8 insertions(+)
> 
> diff --git a/drivers/xen/biomerge.c b/drivers/xen/biomerge.c
> index 8ae2fc90..4da69db 100644
> --- a/drivers/xen/biomerge.c
> +++ b/drivers/xen/biomerge.c
> @@ -6,10 +6,18 @@
>  bool xen_biovec_phys_mergeable(const struct bio_vec *vec1,
>  			       const struct bio_vec *vec2)
>  {
> +#if XEN_PAGE_SIZE == PAGE_SIZE
>  	unsigned long bfn1 = pfn_to_bfn(page_to_pfn(vec1->bv_page));
>  	unsigned long bfn2 = pfn_to_bfn(page_to_pfn(vec2->bv_page));
>  
>  	return __BIOVEC_PHYS_MERGEABLE(vec1, vec2) &&
>  		((bfn1 == bfn2) || ((bfn1+1) == bfn2));
> +#else
> +	/*
> +	 * XXX: Add support for merging bio_vec when using different page
> +	 * size in Xen and Linux.
       ^ sizes

> +	 */
> +	return 0;
> +#endif
>  }
>  EXPORT_SYMBOL(xen_biovec_phys_mergeable);
> -- 
> 2.1.4
> 


From tiwai at suse.de  Mon Aug 10 03:05:07 2015
From: tiwai at suse.de (Takashi Iwai)
Date: Mon, 10 Aug 2015 12:05:07 +0200
Subject: [PATCH 1/9] drm: bridge/dw_hdmi-ahb-audio: add audio driver
In-Reply-To: <E1ZO6hC-0003M5-EU@rmk-PC.arm.linux.org.uk>
References: <20150808160936.GN7557@n2100.arm.linux.org.uk>
 <E1ZO6hC-0003M5-EU@rmk-PC.arm.linux.org.uk>
Message-ID: <s5hk2t35ui4.wl-tiwai@suse.de>

On Sat, 08 Aug 2015 18:10:06 +0200,
Russell King wrote:
> 
> Add ALSA based HDMI AHB audio driver for dw_hdmi.  The only buffer
> format supported by the hardware is its own special IEC958 based format,
> which is not compatible with any ALSA format.  To avoid doing too much
> data manipulation within the driver, we support only ALSAs IEC958 LE and
> 24-bit PCM formats for 2 to 6 channels, which we convert to its hardware
> format.
> 
> A more desirable solution would be to have this conversion in userspace,
> but ALSA does not appear to allow such transformations outside of
> libasound itself.
> 
> Signed-off-by: Russell King <rmk+kernel at arm.linux.org.uk>
> ---
>  drivers/gpu/drm/bridge/Kconfig             |  10 +
>  drivers/gpu/drm/bridge/Makefile            |   1 +
>  drivers/gpu/drm/bridge/dw_hdmi-ahb-audio.c | 561 +++++++++++++++++++++++++++++
>  drivers/gpu/drm/bridge/dw_hdmi-audio.h     |  13 +
>  drivers/gpu/drm/bridge/dw_hdmi.c           |  24 ++
>  drivers/gpu/drm/bridge/dw_hdmi.h           |   3 +
>  6 files changed, 612 insertions(+)
>  create mode 100644 drivers/gpu/drm/bridge/dw_hdmi-ahb-audio.c
>  create mode 100644 drivers/gpu/drm/bridge/dw_hdmi-audio.h
> 
> diff --git a/drivers/gpu/drm/bridge/Kconfig b/drivers/gpu/drm/bridge/Kconfig
> index acef3223772c..56ed35fe0734 100644
> --- a/drivers/gpu/drm/bridge/Kconfig
> +++ b/drivers/gpu/drm/bridge/Kconfig
> @@ -3,6 +3,16 @@ config DRM_DW_HDMI
>  	depends on DRM
>  	select DRM_KMS_HELPER
>  
> +config DRM_DW_HDMI_AHB_AUDIO
> +	tristate "Synopsis Designware AHB Audio interface"
> +	depends on DRM_DW_HDMI && SND
> +	select SND_PCM
> +	select SND_PCM_IEC958
> +	help
> +	  Support the AHB Audio interface which is part of the Synopsis
> +	  Designware HDMI block.  This is used in conjunction with
> +	  the i.MX6 HDMI driver.
> +
>  config DRM_PTN3460
>  	tristate "PTN3460 DP/LVDS bridge"
>  	depends on DRM
> diff --git a/drivers/gpu/drm/bridge/Makefile b/drivers/gpu/drm/bridge/Makefile
> index 8dfebd984370..eb80dbbb8365 100644
> --- a/drivers/gpu/drm/bridge/Makefile
> +++ b/drivers/gpu/drm/bridge/Makefile
> @@ -3,3 +3,4 @@ ccflags-y := -Iinclude/drm
>  obj-$(CONFIG_DRM_PS8622) += ps8622.o
>  obj-$(CONFIG_DRM_PTN3460) += ptn3460.o
>  obj-$(CONFIG_DRM_DW_HDMI) += dw_hdmi.o
> +obj-$(CONFIG_DRM_DW_HDMI_AHB_AUDIO) += dw_hdmi-ahb-audio.o
> diff --git a/drivers/gpu/drm/bridge/dw_hdmi-ahb-audio.c b/drivers/gpu/drm/bridge/dw_hdmi-ahb-audio.c
> new file mode 100644
> index 000000000000..22bbbc5c2393
> --- /dev/null
> +++ b/drivers/gpu/drm/bridge/dw_hdmi-ahb-audio.c
> @@ -0,0 +1,561 @@
> +/*
> + * DesignWare HDMI audio driver
> + *
> + * 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.
> + *
> + * Written and tested against the Designware HDMI Tx found in iMX6.
> + */
> +#include <linux/io.h>
> +#include <linux/interrupt.h>
> +#include <linux/module.h>
> +#include <linux/platform_device.h>
> +#include <drm/bridge/dw_hdmi.h>
> +
> +#include <sound/asoundef.h>
> +#include <sound/core.h>
> +#include <sound/initval.h>
> +#include <sound/pcm.h>
> +#include <sound/pcm_iec958.h>
> +
> +#include "dw_hdmi-audio.h"
> +
> +#define DRIVER_NAME "dw-hdmi-ahb-audio"
> +
> +/* Provide some bits rather than bit offsets */
> +enum {
> +	HDMI_AHB_DMA_CONF0_SW_FIFO_RST = BIT(7),
> +	HDMI_AHB_DMA_CONF0_EN_HLOCK = BIT(3),
> +	HDMI_AHB_DMA_START_START = BIT(0),
> +	HDMI_AHB_DMA_STOP_STOP = BIT(0),
> +	HDMI_IH_MUTE_AHBDMAAUD_STAT0_ERROR = BIT(5),
> +	HDMI_IH_MUTE_AHBDMAAUD_STAT0_LOST = BIT(4),
> +	HDMI_IH_MUTE_AHBDMAAUD_STAT0_RETRY = BIT(3),
> +	HDMI_IH_MUTE_AHBDMAAUD_STAT0_DONE = BIT(2),
> +	HDMI_IH_MUTE_AHBDMAAUD_STAT0_BUFFFULL = BIT(1),
> +	HDMI_IH_MUTE_AHBDMAAUD_STAT0_BUFFEMPTY = BIT(0),
> +	HDMI_IH_MUTE_AHBDMAAUD_STAT0_ALL =
> +		HDMI_IH_MUTE_AHBDMAAUD_STAT0_ERROR |
> +		HDMI_IH_MUTE_AHBDMAAUD_STAT0_LOST |
> +		HDMI_IH_MUTE_AHBDMAAUD_STAT0_RETRY |
> +		HDMI_IH_MUTE_AHBDMAAUD_STAT0_DONE |
> +		HDMI_IH_MUTE_AHBDMAAUD_STAT0_BUFFFULL |
> +		HDMI_IH_MUTE_AHBDMAAUD_STAT0_BUFFEMPTY,
> +	HDMI_IH_AHBDMAAUD_STAT0_ERROR = BIT(5),
> +	HDMI_IH_AHBDMAAUD_STAT0_LOST = BIT(4),
> +	HDMI_IH_AHBDMAAUD_STAT0_RETRY = BIT(3),
> +	HDMI_IH_AHBDMAAUD_STAT0_DONE = BIT(2),
> +	HDMI_IH_AHBDMAAUD_STAT0_BUFFFULL = BIT(1),
> +	HDMI_IH_AHBDMAAUD_STAT0_BUFFEMPTY = BIT(0),
> +	HDMI_IH_AHBDMAAUD_STAT0_ALL =
> +		HDMI_IH_AHBDMAAUD_STAT0_ERROR |
> +		HDMI_IH_AHBDMAAUD_STAT0_LOST |
> +		HDMI_IH_AHBDMAAUD_STAT0_RETRY |
> +		HDMI_IH_AHBDMAAUD_STAT0_DONE |
> +		HDMI_IH_AHBDMAAUD_STAT0_BUFFFULL |
> +		HDMI_IH_AHBDMAAUD_STAT0_BUFFEMPTY,
> +	HDMI_AHB_DMA_CONF0_INCR16 = 2 << 1,
> +	HDMI_AHB_DMA_CONF0_INCR8 = 1 << 1,
> +	HDMI_AHB_DMA_CONF0_INCR4 = 0,
> +	HDMI_AHB_DMA_CONF0_BURST_MODE = BIT(0),
> +	HDMI_AHB_DMA_MASK_DONE = BIT(7),
> +	HDMI_REVISION_ID = 0x0001,
> +	HDMI_IH_AHBDMAAUD_STAT0 = 0x0109,
> +	HDMI_IH_MUTE_AHBDMAAUD_STAT0 = 0x0189,
> +	HDMI_AHB_DMA_CONF0 = 0x3600,
> +	HDMI_AHB_DMA_START = 0x3601,
> +	HDMI_AHB_DMA_STOP = 0x3602,
> +	HDMI_AHB_DMA_THRSLD = 0x3603,
> +	HDMI_AHB_DMA_STRADDR0 = 0x3604,
> +	HDMI_AHB_DMA_STPADDR0 = 0x3608,
> +	HDMI_AHB_DMA_MASK = 0x3614,
> +	HDMI_AHB_DMA_POL = 0x3615,
> +	HDMI_AHB_DMA_CONF1 = 0x3616,
> +	HDMI_AHB_DMA_BUFFPOL = 0x361a,
> +};
> +
> +struct snd_dw_hdmi {
> +	struct snd_card *card;
> +	struct snd_pcm *pcm;
> +	struct dw_hdmi_audio_data data;
> +	struct snd_pcm_substream *substream;
> +	void (*reformat)(struct snd_dw_hdmi *, size_t, size_t);
> +	void *buf_src;
> +	void *buf_dst;
> +	dma_addr_t buf_addr;
> +	unsigned buf_offset;
> +	unsigned buf_period;
> +	unsigned buf_size;
> +	unsigned channels;
> +	u8 revision;
> +	u8 iec_offset;
> +	u8 cs[192][8];
> +};
> +
> +static void dw_hdmi_writel(unsigned long val, void __iomem *ptr)

Better to be u32 instead of unsigned long in general.

> +{
> +	writeb_relaxed(val, ptr);
> +	writeb_relaxed(val >> 8, ptr + 1);
> +	writeb_relaxed(val >> 16, ptr + 2);
> +	writeb_relaxed(val >> 24, ptr + 3);
> +}
> +
> +/*
> + * Convert to hardware format: The userspace buffer contains IEC958 samples,
> + * with the PCUV bits in bits 31..28 and audio samples in bits 27..4.  We
> + * need these to be in bits 27..24, with the IEC B bit in bit 28, and audio
> + * samples in 23..0.
> + *
> + * Default preamble in bits 3..0: 8 = block start, 4 = even 2 = odd
> + *
> + * Ideally, we could do with having the data properly formatted in userspace.
> + */
> +static void dw_hdmi_reformat_iec958(struct snd_dw_hdmi *dw,
> +	size_t offset, size_t bytes)
> +{
> +	u32 *src = dw->buf_src + offset;
> +	u32 *dst = dw->buf_dst + offset;
> +	u32 *end = dw->buf_src + offset + bytes;
> +
> +	do {
> +		u32 b, sample = *src++;
> +
> +		b = (sample & 8) << (28 - 3);
> +
> +		sample >>= 4;
> +
> +		*dst++ = sample | b;
> +	} while (src < end);
> +}
> +
> +static u32 parity(u32 sample)
> +{
> +	sample ^= sample >> 16;
> +	sample ^= sample >> 8;
> +	sample ^= sample >> 4;
> +	sample ^= sample >> 2;
> +	sample ^= sample >> 1;
> +	return (sample & 1) << 27;
> +}
> +
> +static void dw_hdmi_reformat_s24(struct snd_dw_hdmi *dw,
> +	size_t offset, size_t bytes)
> +{
> +	u32 *src = dw->buf_src + offset;
> +	u32 *dst = dw->buf_dst + offset;
> +	u32 *end = dw->buf_src + offset + bytes;
> +
> +	do {
> +		unsigned i;
> +		u8 *cs;
> +
> +		cs = dw->cs[dw->iec_offset++];
> +		if (dw->iec_offset >= 192)
> +			dw->iec_offset = 0;
> +
> +		i = dw->channels;
> +		do {
> +			u32 sample = *src++;
> +
> +			sample &= ~0xff000000;
> +			sample |= *cs++ << 24;
> +			sample |= parity(sample & ~0xf8000000);
> +
> +			*dst++ = sample;
> +		} while (--i);
> +	} while (src < end);
> +}
> +
> +static void dw_hdmi_create_cs(struct snd_dw_hdmi *dw,
> +	struct snd_pcm_runtime *runtime)
> +{
> +	u8 cs[4];
> +	unsigned ch, i, j;
> +
> +	snd_pcm_create_iec958_consumer(runtime, cs, sizeof(cs));
> +
> +	memset(dw->cs, 0, sizeof(dw->cs));
> +
> +	for (ch = 0; ch < 8; ch++) {
> +		cs[2] &= ~IEC958_AES2_CON_CHANNEL;
> +		cs[2] |= (ch + 1) << 4;
> +
> +		for (i = 0; i < ARRAY_SIZE(cs); i++) {
> +			unsigned c = cs[i];
> +
> +			for (j = 0; j < 8; j++, c >>= 1)
> +				dw->cs[i * 8 + j][ch] = (c & 1) << 2;
> +		}
> +	}
> +	dw->cs[0][0] |= BIT(4);
> +}
> +
> +static void dw_hdmi_start_dma(struct snd_dw_hdmi *dw)
> +{
> +	void __iomem *base = dw->data.base;
> +	unsigned offset = dw->buf_offset;
> +	unsigned period = dw->buf_period;
> +	u32 start, stop;
> +
> +	dw->reformat(dw, offset, period);
> +
> +	/* Clear all irqs before enabling irqs and starting DMA */
> +	writeb_relaxed(HDMI_IH_AHBDMAAUD_STAT0_ALL,
> +		       base + HDMI_IH_AHBDMAAUD_STAT0);
> +
> +	start = dw->buf_addr + offset;
> +	stop = start + period - 1;
> +
> +	/* Setup the hardware start/stop addresses */
> +	dw_hdmi_writel(start, base + HDMI_AHB_DMA_STRADDR0);
> +	dw_hdmi_writel(stop, base + HDMI_AHB_DMA_STPADDR0);
> +
> +	writeb_relaxed((u8)~HDMI_AHB_DMA_MASK_DONE, base + HDMI_AHB_DMA_MASK);
> +	writeb(HDMI_AHB_DMA_START_START, base + HDMI_AHB_DMA_START);
> +
> +	offset += period;
> +	if (offset >= dw->buf_size)
> +		offset = 0;
> +	dw->buf_offset = offset;
> +}
> +
> +static void dw_hdmi_stop_dma(struct snd_dw_hdmi *dw)
> +{
> +	dw->substream = NULL;
> +
> +	/* Disable interrupts before disabling DMA */
> +	writeb_relaxed(~0, dw->data.base + HDMI_AHB_DMA_MASK);
> +	writeb_relaxed(HDMI_AHB_DMA_STOP_STOP, dw->data.base + HDMI_AHB_DMA_STOP);
> +}
> +
> +static irqreturn_t snd_dw_hdmi_irq(int irq, void *data)
> +{
> +	struct snd_dw_hdmi *dw = data;
> +	struct snd_pcm_substream *substream;
> +	unsigned stat;
> +
> +	stat = readb_relaxed(dw->data.base + HDMI_IH_AHBDMAAUD_STAT0);
> +	if (!stat)
> +		return IRQ_NONE;
> +
> +	writeb_relaxed(stat, dw->data.base + HDMI_IH_AHBDMAAUD_STAT0);
> +
> +	substream = dw->substream;
> +	if (stat & HDMI_IH_AHBDMAAUD_STAT0_DONE && substream) {
> +		snd_pcm_period_elapsed(substream);
> +		if (dw->substream)
> +			dw_hdmi_start_dma(dw);
> +	}

Don't we need locking?  In theory, the trigger can be issued while the
irq is being handled.

> +
> +	return IRQ_HANDLED;
> +}
> +
> +static struct snd_pcm_hardware dw_hdmi_hw = {
> +	.info = SNDRV_PCM_INFO_INTERLEAVED |
> +		SNDRV_PCM_INFO_BLOCK_TRANSFER |
> +		SNDRV_PCM_INFO_MMAP |
> +		SNDRV_PCM_INFO_MMAP_VALID,
> +	.formats = SNDRV_PCM_FMTBIT_IEC958_SUBFRAME_LE |
> +		   SNDRV_PCM_FMTBIT_S24_LE,
> +	.rates = SNDRV_PCM_RATE_32000 |
> +		 SNDRV_PCM_RATE_44100 |
> +		 SNDRV_PCM_RATE_48000 |
> +		 SNDRV_PCM_RATE_88200 |
> +		 SNDRV_PCM_RATE_96000 |
> +		 SNDRV_PCM_RATE_176400 |
> +		 SNDRV_PCM_RATE_192000,
> +	.channels_min = 2,
> +	.channels_max = 8,
> +	.buffer_bytes_max = 64 * 1024,
> +	.period_bytes_min = 256,
> +	.period_bytes_max = 8192,	/* ERR004323: must limit to 8k */
> +	.periods_min = 2,
> +	.periods_max = 16,
> +	.fifo_size = 0,
> +};
> +
> +static int dw_hdmi_open(struct snd_pcm_substream *substream)
> +{
> +	struct snd_pcm_runtime *runtime = substream->runtime;
> +	struct snd_dw_hdmi *dw = substream->private_data;
> +	void __iomem *base = dw->data.base;
> +	int ret;
> +
> +	runtime->hw = dw_hdmi_hw;
> +
> +	ret = snd_pcm_limit_hw_rates(runtime);
> +	if (ret < 0)
> +		return ret;
> +
> +	ret = snd_pcm_hw_constraint_integer(runtime, SNDRV_PCM_HW_PARAM_PERIODS);
> +	if (ret < 0)
> +		return ret;
> +
> +	/* Clear FIFO */
> +	writeb_relaxed(HDMI_AHB_DMA_CONF0_SW_FIFO_RST,
> +		       base + HDMI_AHB_DMA_CONF0);
> +
> +	/* Configure interrupt polarities */
> +	writeb_relaxed(~0, base + HDMI_AHB_DMA_POL);
> +	writeb_relaxed(~0, base + HDMI_AHB_DMA_BUFFPOL);
> +
> +	/* Keep interrupts masked, and clear any pending */
> +	writeb_relaxed(~0, base + HDMI_AHB_DMA_MASK);
> +	writeb_relaxed(~0, base + HDMI_IH_AHBDMAAUD_STAT0);
> +
> +	ret = request_irq(dw->data.irq, snd_dw_hdmi_irq, IRQF_SHARED,
> +			  "dw-hdmi-audio", dw);
> +	if (ret)
> +		return ret;
> +
> +	/* Un-mute done interrupt */
> +	writeb_relaxed(HDMI_IH_MUTE_AHBDMAAUD_STAT0_ALL &
> +		       ~HDMI_IH_MUTE_AHBDMAAUD_STAT0_DONE,
> +		       base + HDMI_IH_MUTE_AHBDMAAUD_STAT0);
> +
> +	return 0;
> +}
> +
> +static int dw_hdmi_close(struct snd_pcm_substream *substream)
> +{
> +	struct snd_dw_hdmi *dw = substream->private_data;
> +
> +	/* Mute all interrupts */
> +	writeb_relaxed(HDMI_IH_MUTE_AHBDMAAUD_STAT0_ALL,
> +		       dw->data.base + HDMI_IH_MUTE_AHBDMAAUD_STAT0);
> +
> +	free_irq(dw->data.irq, dw);
> +
> +	return 0;
> +}
> +
> +static int dw_hdmi_hw_free(struct snd_pcm_substream *substream)
> +{
> +	return snd_pcm_lib_free_vmalloc_buffer(substream);
> +}
> +
> +static int dw_hdmi_hw_params(struct snd_pcm_substream *substream,
> +	struct snd_pcm_hw_params *params)
> +{
> +	return snd_pcm_lib_alloc_vmalloc_buffer(substream,
> +						params_buffer_bytes(params));
> +}
> +
> +static int dw_hdmi_prepare(struct snd_pcm_substream *substream)
> +{
> +	struct snd_pcm_runtime *runtime = substream->runtime;
> +	struct snd_dw_hdmi *dw = substream->private_data;
> +	u8 threshold, conf0, conf1;
> +
> +	/* Setup as per 3.0.5 FSL 4.1.0 BSP */
> +	switch (dw->revision) {
> +	case 0x0a:
> +		conf0 = HDMI_AHB_DMA_CONF0_BURST_MODE |
> +			HDMI_AHB_DMA_CONF0_INCR4;
> +		if (runtime->channels == 2)
> +			threshold = 126;
> +		else
> +			threshold = 124;
> +		break;
> +	case 0x1a:
> +		conf0 = HDMI_AHB_DMA_CONF0_BURST_MODE |
> +			HDMI_AHB_DMA_CONF0_INCR8;
> +		threshold = 128;
> +		break;
> +	default:
> +		/* NOTREACHED */
> +		return -EINVAL;
> +	}
> +
> +	dw_hdmi_set_sample_rate(dw->data.hdmi, runtime->rate);
> +
> +	/* Minimum number of bytes in the fifo. */
> +	runtime->hw.fifo_size = threshold * 32;
> +
> +	conf0 |= HDMI_AHB_DMA_CONF0_EN_HLOCK;
> +	conf1 = (1 << runtime->channels) - 1;
> +
> +	writeb_relaxed(threshold, dw->data.base + HDMI_AHB_DMA_THRSLD);
> +	writeb_relaxed(conf0, dw->data.base + HDMI_AHB_DMA_CONF0);
> +	writeb_relaxed(conf1, dw->data.base + HDMI_AHB_DMA_CONF1);
> +
> +	switch (runtime->format) {
> +	case SNDRV_PCM_FORMAT_IEC958_SUBFRAME_LE:
> +		dw->reformat = dw_hdmi_reformat_iec958;
> +		break;
> +	case SNDRV_PCM_FORMAT_S24_LE:
> +		dw_hdmi_create_cs(dw, runtime);
> +		dw->reformat = dw_hdmi_reformat_s24;
> +		break;
> +	}
> +	dw->iec_offset = 0;
> +	dw->channels = runtime->channels;
> +	dw->buf_src  = runtime->dma_area;
> +	dw->buf_dst  = substream->dma_buffer.area;
> +	dw->buf_addr = substream->dma_buffer.addr;
> +	dw->buf_period = snd_pcm_lib_period_bytes(substream);
> +	dw->buf_size = snd_pcm_lib_buffer_bytes(substream);
> +
> +	return 0;
> +}
> +
> +static int dw_hdmi_trigger(struct snd_pcm_substream *substream, int cmd)
> +{
> +	struct snd_dw_hdmi *dw = substream->private_data;
> +	int ret = 0;
> +
> +	switch (cmd) {
> +	case SNDRV_PCM_TRIGGER_START:
> +		dw->buf_offset = 0;
> +		dw->substream = substream;
> +		dw_hdmi_start_dma(dw);
> +		dw_hdmi_audio_enable(dw->data.hdmi);
> +		substream->runtime->delay = substream->runtime->period_size;
> +		break;
> +
> +	case SNDRV_PCM_TRIGGER_STOP:
> +		dw_hdmi_stop_dma(dw);
> +		dw_hdmi_audio_disable(dw->data.hdmi);
> +		break;
> +
> +	default:
> +		ret = -EINVAL;
> +		break;

SNDRV_PCM_TRIGGER_SUSPEND may be passed at suspend, too.


> +	}
> +
> +	return ret;
> +}
> +
> +static snd_pcm_uframes_t dw_hdmi_pointer(struct snd_pcm_substream *substream)
> +{
> +	struct snd_pcm_runtime *runtime = substream->runtime;
> +	struct snd_dw_hdmi *dw = substream->private_data;
> +
> +	return bytes_to_frames(runtime, dw->buf_offset);

So, this returns the offset that has been reformatted.  Does the
hardware support any better position reporting?  We may give the delay
from the driver if possible.


thanks,

Takashi


> +}
> +
> +static struct snd_pcm_ops snd_dw_hdmi_ops = {
> +	.open = dw_hdmi_open,
> +	.close = dw_hdmi_close,
> +	.ioctl = snd_pcm_lib_ioctl,
> +	.hw_params = dw_hdmi_hw_params,
> +	.hw_free = dw_hdmi_hw_free,
> +	.prepare = dw_hdmi_prepare,
> +	.trigger = dw_hdmi_trigger,
> +	.pointer = dw_hdmi_pointer,
> +	.page = snd_pcm_lib_get_vmalloc_page,
> +};
> +
> +static int snd_dw_hdmi_probe(struct platform_device *pdev)
> +{
> +	const struct dw_hdmi_audio_data *data = pdev->dev.platform_data;
> +	struct device *dev = pdev->dev.parent;
> +	struct snd_dw_hdmi *dw;
> +	struct snd_card *card;
> +	struct snd_pcm *pcm;
> +	unsigned revision;
> +	int ret;
> +
> +	writeb_relaxed(HDMI_IH_MUTE_AHBDMAAUD_STAT0_ALL,
> +		       data->base + HDMI_IH_MUTE_AHBDMAAUD_STAT0);
> +	revision = readb_relaxed(data->base + HDMI_REVISION_ID);
> +	if (revision != 0x0a && revision != 0x1a) {
> +		dev_err(dev, "dw-hdmi-audio: unknown revision 0x%02x\n",
> +			revision);
> +		return -ENXIO;
> +	}
> +
> +	ret = snd_card_new(dev, SNDRV_DEFAULT_IDX1, SNDRV_DEFAULT_STR1,
> +			      THIS_MODULE, sizeof(struct snd_dw_hdmi), &card);
> +	if (ret < 0)
> +		return ret;
> +
> +	strlcpy(card->driver, DRIVER_NAME, sizeof(card->driver));
> +	strlcpy(card->shortname, "DW-HDMI", sizeof(card->shortname));
> +	snprintf(card->longname, sizeof(card->longname),
> +		 "%s rev 0x%02x, irq %d", card->shortname, revision,
> +		 data->irq);
> +
> +	dw = card->private_data;
> +	dw->card = card;
> +	dw->data = *data;
> +	dw->revision = revision;
> +
> +	ret = snd_pcm_new(card, "DW HDMI", 0, 1, 0, &pcm);
> +	if (ret < 0)
> +		goto err;
> +
> +	dw->pcm = pcm;
> +	pcm->private_data = dw;
> +	strlcpy(pcm->name, DRIVER_NAME, sizeof(pcm->name));
> +	snd_pcm_set_ops(pcm, SNDRV_PCM_STREAM_PLAYBACK, &snd_dw_hdmi_ops);
> +
> +	snd_pcm_lib_preallocate_pages_for_all(pcm, SNDRV_DMA_TYPE_DEV,
> +			dev, 64 * 1024, 64 * 1024);
> +
> +	ret = snd_card_register(card);
> +	if (ret < 0)
> +		goto err;
> +
> +	platform_set_drvdata(pdev, dw);
> +
> +	return 0;
> +
> +err:
> +	snd_card_free(card);
> +	return ret;
> +}
> +
> +static int snd_dw_hdmi_remove(struct platform_device *pdev)
> +{
> +	struct snd_dw_hdmi *dw = platform_get_drvdata(pdev);
> +
> +	snd_card_free(dw->card);
> +
> +	return 0;
> +}
> +
> +#ifdef CONFIG_PM_SLEEP
> +static int snd_dw_hdmi_suspend(struct device *dev)
> +{
> +	struct snd_dw_hdmi *dw = dev_get_drvdata(dev);
> +
> +	snd_power_change_state(dw->card, SNDRV_CTL_POWER_D3cold);
> +	snd_pcm_suspend_all(dw->pcm);
> +
> +	return 0;
> +}
> +
> +static int snd_dw_hdmi_resume(struct device *dev)
> +{
> +	struct snd_dw_hdmi *dw = dev_get_drvdata(dev);
> +
> +	snd_power_change_state(dw->card, SNDRV_CTL_POWER_D0);
> +
> +	return 0;
> +}
> +
> +static SIMPLE_DEV_PM_OPS(snd_dw_hdmi_pm, snd_dw_hdmi_suspend,
> +			 snd_dw_hdmi_resume);
> +#define PM_OPS &snd_dw_hdmi_pm
> +#else
> +#define PM_OPS NULL
> +#endif
> +
> +static struct platform_driver snd_dw_hdmi_driver = {
> +	.probe	= snd_dw_hdmi_probe,
> +	.remove	= snd_dw_hdmi_remove,
> +	.driver	= {
> +		.name = DRIVER_NAME,
> +		.owner = THIS_MODULE,
> +		.pm = PM_OPS,
> +	},
> +};
> +
> +module_platform_driver(snd_dw_hdmi_driver);
> +
> +MODULE_AUTHOR("Russell King <rmk+kernel at arm.linux.org.uk>");
> +MODULE_DESCRIPTION("Synopsis Designware HDMI AHB ALSA interface");
> +MODULE_LICENSE("GPL v2");
> +MODULE_ALIAS("platform:" DRIVER_NAME);
> diff --git a/drivers/gpu/drm/bridge/dw_hdmi-audio.h b/drivers/gpu/drm/bridge/dw_hdmi-audio.h
> new file mode 100644
> index 000000000000..1e840118d90a
> --- /dev/null
> +++ b/drivers/gpu/drm/bridge/dw_hdmi-audio.h
> @@ -0,0 +1,13 @@
> +#ifndef DW_HDMI_AUDIO_H
> +#define DW_HDMI_AUDIO_H
> +
> +struct dw_hdmi;
> +
> +struct dw_hdmi_audio_data {
> +	phys_addr_t phys;
> +	void __iomem *base;
> +	int irq;
> +	struct dw_hdmi *hdmi;
> +};
> +
> +#endif
> diff --git a/drivers/gpu/drm/bridge/dw_hdmi.c b/drivers/gpu/drm/bridge/dw_hdmi.c
> index fba25607ef88..b65464789fbd 100644
> --- a/drivers/gpu/drm/bridge/dw_hdmi.c
> +++ b/drivers/gpu/drm/bridge/dw_hdmi.c
> @@ -28,6 +28,7 @@
>  #include <drm/bridge/dw_hdmi.h>
>  
>  #include "dw_hdmi.h"
> +#include "dw_hdmi-audio.h"
>  
>  #define HDMI_EDID_LEN		512
>  
> @@ -104,6 +105,7 @@ struct dw_hdmi {
>  	struct drm_encoder *encoder;
>  	struct drm_bridge *bridge;
>  
> +	struct platform_device *audio;
>  	enum dw_hdmi_devtype dev_type;
>  	struct device *dev;
>  	struct clk *isfr_clk;
> @@ -1732,7 +1734,9 @@ int dw_hdmi_bind(struct device *dev, struct device *master,
>  {
>  	struct drm_device *drm = data;
>  	struct device_node *np = dev->of_node;
> +	struct platform_device_info pdevinfo;
>  	struct device_node *ddc_node;
> +	struct dw_hdmi_audio_data audio;
>  	struct dw_hdmi *hdmi;
>  	int ret;
>  	u32 val = 1;
> @@ -1860,6 +1864,23 @@ int dw_hdmi_bind(struct device *dev, struct device *master,
>  	hdmi_writeb(hdmi, ~(HDMI_IH_PHY_STAT0_HPD | HDMI_IH_PHY_STAT0_RX_SENSE),
>  		    HDMI_IH_MUTE_PHY_STAT0);
>  
> +	memset(&pdevinfo, 0, sizeof(pdevinfo));
> +	pdevinfo.parent = dev;
> +	pdevinfo.id = PLATFORM_DEVID_AUTO;
> +
> +	if (hdmi_readb(hdmi, HDMI_CONFIG1_ID) & HDMI_CONFIG1_AHB) {
> +		audio.phys = iores->start;
> +		audio.base = hdmi->regs;
> +		audio.irq = irq;
> +		audio.hdmi = hdmi;
> +
> +		pdevinfo.name = "dw-hdmi-ahb-audio";
> +		pdevinfo.data = &audio;
> +		pdevinfo.size_data = sizeof(audio);
> +		pdevinfo.dma_mask = DMA_BIT_MASK(32);
> +		hdmi->audio = platform_device_register_full(&pdevinfo);
> +	}
> +
>  	dev_set_drvdata(dev, hdmi);
>  
>  	return 0;
> @@ -1877,6 +1898,9 @@ void dw_hdmi_unbind(struct device *dev, struct device *master, void *data)
>  {
>  	struct dw_hdmi *hdmi = dev_get_drvdata(dev);
>  
> +	if (hdmi->audio && !IS_ERR(hdmi->audio))
> +		platform_device_unregister(hdmi->audio);
> +
>  	/* Disable all interrupts */
>  	hdmi_writeb(hdmi, ~0, HDMI_IH_MUTE_PHY_STAT0);
>  
> diff --git a/drivers/gpu/drm/bridge/dw_hdmi.h b/drivers/gpu/drm/bridge/dw_hdmi.h
> index 175dbc89a824..78e54e813212 100644
> --- a/drivers/gpu/drm/bridge/dw_hdmi.h
> +++ b/drivers/gpu/drm/bridge/dw_hdmi.h
> @@ -545,6 +545,9 @@
>  #define HDMI_I2CM_FS_SCL_LCNT_0_ADDR            0x7E12
>  
>  enum {
> +/* CONFIG1_ID field values */
> +	HDMI_CONFIG1_AHB = 0x01,
> +
>  /* IH_FC_INT2 field values */
>  	HDMI_IH_FC_INT2_OVERFLOW_MASK = 0x03,
>  	HDMI_IH_FC_INT2_LOW_PRIORITY_OVERFLOW = 0x02,
> -- 
> 2.1.0
> 


From jamesjj.liao at mediatek.com  Mon Aug 10 02:50:27 2015
From: jamesjj.liao at mediatek.com (James Liao)
Date: Mon, 10 Aug 2015 17:50:27 +0800
Subject: [PATCH v7 8/9] clk: mediatek: Add USB clock support in MT8173
 APMIXEDSYS
In-Reply-To: <1439200228-318-1-git-send-email-jamesjj.liao@mediatek.com>
References: <1439200228-318-1-git-send-email-jamesjj.liao@mediatek.com>
Message-ID: <1439200228-318-9-git-send-email-jamesjj.liao@mediatek.com>

Add REF2USB_TX clock support into MT8173 APMIXEDSYS. This clock
is needed by USB 3.0.

Signed-off-by: James Liao <jamesjj.liao at mediatek.com>
---
 drivers/clk/mediatek/Makefile          |   2 +-
 drivers/clk/mediatek/clk-apmixed.c     | 107 +++++++++++++++++++++++++++++++++
 drivers/clk/mediatek/clk-mt8173.c      |  47 +++++++++++++++
 drivers/clk/mediatek/clk-mtk.h         |   3 +
 drivers/clk/mediatek/clk-pll.c         |   7 +--
 include/dt-bindings/clock/mt8173-clk.h |   3 +-
 6 files changed, 161 insertions(+), 8 deletions(-)
 create mode 100644 drivers/clk/mediatek/clk-apmixed.c

diff --git a/drivers/clk/mediatek/Makefile b/drivers/clk/mediatek/Makefile
index 8e4b2a4..95fdfac 100644
--- a/drivers/clk/mediatek/Makefile
+++ b/drivers/clk/mediatek/Makefile
@@ -1,4 +1,4 @@
-obj-y += clk-mtk.o clk-pll.o clk-gate.o
+obj-y += clk-mtk.o clk-pll.o clk-gate.o clk-apmixed.o
 obj-$(CONFIG_RESET_CONTROLLER) += reset.o
 obj-y += clk-mt8135.o
 obj-y += clk-mt8173.o
diff --git a/drivers/clk/mediatek/clk-apmixed.c b/drivers/clk/mediatek/clk-apmixed.c
new file mode 100644
index 0000000..5303c59
--- /dev/null
+++ b/drivers/clk/mediatek/clk-apmixed.c
@@ -0,0 +1,107 @@
+/*
+ * Copyright (c) 2015 MediaTek Inc.
+ * Author: James Liao <jamesjj.liao at 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/delay.h>
+#include <linux/of_address.h>
+#include <linux/slab.h>
+
+#include "clk-mtk.h"
+
+#define REF2USB_TX_EN		BIT(0)
+#define REF2USB_TX_LPF_EN	BIT(1)
+#define REF2USB_TX_OUT_EN	BIT(2)
+#define REF2USB_EN_MASK		(REF2USB_TX_EN | REF2USB_TX_LPF_EN | \
+				 REF2USB_TX_OUT_EN)
+
+struct mtk_ref2usb_tx {
+	struct clk_hw	hw;
+	void __iomem	*base_addr;
+};
+
+static inline struct mtk_ref2usb_tx *to_mtk_ref2usb_tx(struct clk_hw *hw)
+{
+	return container_of(hw, struct mtk_ref2usb_tx, hw);
+}
+
+static int mtk_ref2usb_tx_is_prepared(struct clk_hw *hw)
+{
+	struct mtk_ref2usb_tx *tx = to_mtk_ref2usb_tx(hw);
+
+	return (readl(tx->base_addr) & REF2USB_EN_MASK) == REF2USB_EN_MASK;
+}
+
+static int mtk_ref2usb_tx_prepare(struct clk_hw *hw)
+{
+	struct mtk_ref2usb_tx *tx = to_mtk_ref2usb_tx(hw);
+	u32 val;
+
+	val = readl(tx->base_addr);
+
+	val |= REF2USB_TX_EN;
+	writel(val, tx->base_addr);
+	udelay(100);
+
+	val |= REF2USB_TX_LPF_EN;
+	writel(val, tx->base_addr);
+
+	val |= REF2USB_TX_OUT_EN;
+	writel(val, tx->base_addr);
+
+	return 0;
+}
+
+static void mtk_ref2usb_tx_unprepare(struct clk_hw *hw)
+{
+	struct mtk_ref2usb_tx *tx = to_mtk_ref2usb_tx(hw);
+	u32 val;
+
+	val = readl(tx->base_addr);
+	val &= ~REF2USB_EN_MASK;
+	writel(val, tx->base_addr);
+}
+
+static const struct clk_ops mtk_ref2usb_tx_ops = {
+	.is_prepared	= mtk_ref2usb_tx_is_prepared,
+	.prepare	= mtk_ref2usb_tx_prepare,
+	.unprepare	= mtk_ref2usb_tx_unprepare,
+};
+
+struct clk * __init mtk_clk_register_ref2usb_tx(const char *name,
+			const char *parent_name, void __iomem *reg)
+{
+	struct mtk_ref2usb_tx *tx;
+	struct clk_init_data init = {};
+	struct clk *clk;
+
+	tx = kzalloc(sizeof(*tx), GFP_KERNEL);
+	if (!tx)
+		return ERR_PTR(-ENOMEM);
+
+	tx->base_addr = reg;
+	tx->hw.init = &init;
+
+	init.name = name;
+	init.ops = &mtk_ref2usb_tx_ops;
+	init.parent_names = &parent_name;
+	init.num_parents = 1;
+
+	clk = clk_register(NULL, &tx->hw);
+
+	if (IS_ERR(clk)) {
+		pr_err("Failed to register clk %s: %ld\n", name, PTR_ERR(clk));
+		kfree(tx);
+	}
+
+	return clk;
+}
diff --git a/drivers/clk/mediatek/clk-mt8173.c b/drivers/clk/mediatek/clk-mt8173.c
index 14f61f1..2a12b74 100644
--- a/drivers/clk/mediatek/clk-mt8173.c
+++ b/drivers/clk/mediatek/clk-mt8173.c
@@ -976,6 +976,24 @@ static void __init mtk_pericfg_init(struct device_node *node)
 }
 CLK_OF_DECLARE(mtk_pericfg, "mediatek,mt8173-pericfg", mtk_pericfg_init);
 
+struct mtk_clk_usb {
+	int id;
+	const char *name;
+	const char *parent;
+	u32 reg_ofs;
+};
+
+#define APMIXED_USB(_id, _name, _parent, _reg_ofs) {			\
+		.id = _id,						\
+		.name = _name,						\
+		.parent = _parent,					\
+		.reg_ofs = _reg_ofs,					\
+	}
+
+static const struct mtk_clk_usb apmixed_usb[] __initconst = {
+	APMIXED_USB(CLK_APMIXED_REF2USB_TX, "ref2usb_tx", "clk26m", 0x8),
+};
+
 #define MT8173_PLL_FMAX		(3000UL * MHZ)
 
 #define CON0_MT8173_RST_BAR	BIT(24)
@@ -1018,6 +1036,15 @@ static const struct mtk_pll_data plls[] = {
 static void __init mtk_apmixedsys_init(struct device_node *node)
 {
 	struct clk_onecell_data *clk_data;
+	void __iomem *base;
+	struct clk *clk;
+	int r, i;
+
+	base = of_iomap(node, 0);
+	if (!base) {
+		pr_err("%s(): ioremap failed\n", __func__);
+		return;
+	}
 
 	mt8173_pll_clk_data = clk_data = mtk_alloc_clk_data(CLK_APMIXED_NR_CLK);
 	if (!clk_data)
@@ -1025,6 +1052,26 @@ static void __init mtk_apmixedsys_init(struct device_node *node)
 
 	mtk_clk_register_plls(node, plls, ARRAY_SIZE(plls), clk_data);
 
+	for (i = 0; i < ARRAY_SIZE(apmixed_usb); i++) {
+		const struct mtk_clk_usb *cku = &apmixed_usb[i];
+
+		clk = mtk_clk_register_ref2usb_tx(cku->name, cku->parent,
+					base + cku->reg_ofs);
+
+		if (IS_ERR(clk)) {
+			pr_err("Failed to register clk %s: %ld\n", cku->name,
+					PTR_ERR(clk));
+			continue;
+		}
+
+		clk_data->clks[cku->id] = clk;
+	}
+
+	r = of_clk_add_provider(node, of_clk_src_onecell_get, clk_data);
+	if (r)
+		pr_err("%s(): could not register clock provider: %d\n",
+			__func__, r);
+
 	mtk_clk_enable_critical();
 }
 CLK_OF_DECLARE(mtk_apmixedsys, "mediatek,mt8173-apmixedsys",
diff --git a/drivers/clk/mediatek/clk-mtk.h b/drivers/clk/mediatek/clk-mtk.h
index 32d4f55..cf19363 100644
--- a/drivers/clk/mediatek/clk-mtk.h
+++ b/drivers/clk/mediatek/clk-mtk.h
@@ -173,6 +173,9 @@ void mtk_clk_register_plls(struct device_node *node,
 		const struct mtk_pll_data *plls, int num_plls,
 		struct clk_onecell_data *clk_data);
 
+struct clk *mtk_clk_register_ref2usb_tx(const char *name,
+			const char *parent_name, void __iomem *reg);
+
 #ifdef CONFIG_RESET_CONTROLLER
 void mtk_register_reset_controller(struct device_node *np,
 			unsigned int num_regs, int regofs);
diff --git a/drivers/clk/mediatek/clk-pll.c b/drivers/clk/mediatek/clk-pll.c
index 44409e9..813f0c7 100644
--- a/drivers/clk/mediatek/clk-pll.c
+++ b/drivers/clk/mediatek/clk-pll.c
@@ -302,7 +302,7 @@ void __init mtk_clk_register_plls(struct device_node *node,
 		const struct mtk_pll_data *plls, int num_plls, struct clk_onecell_data *clk_data)
 {
 	void __iomem *base;
-	int r, i;
+	int i;
 	struct clk *clk;
 
 	base = of_iomap(node, 0);
@@ -324,9 +324,4 @@ void __init mtk_clk_register_plls(struct device_node *node,
 
 		clk_data->clks[pll->id] = clk;
 	}
-
-	r = of_clk_add_provider(node, of_clk_src_onecell_get, clk_data);
-	if (r)
-		pr_err("%s(): could not register clock provider: %d\n",
-			__func__, r);
 }
diff --git a/include/dt-bindings/clock/mt8173-clk.h b/include/dt-bindings/clock/mt8173-clk.h
index 87820ee..e3db63a 100644
--- a/include/dt-bindings/clock/mt8173-clk.h
+++ b/include/dt-bindings/clock/mt8173-clk.h
@@ -175,7 +175,8 @@
 #define CLK_APMIXED_APLL2		12
 #define CLK_APMIXED_LVDSPLL		13
 #define CLK_APMIXED_MSDCPLL2		14
-#define CLK_APMIXED_NR_CLK		15
+#define CLK_APMIXED_REF2USB_TX		15
+#define CLK_APMIXED_NR_CLK		16
 
 /* INFRA_SYS */
 
-- 
1.8.1.1.dirty



From hanjun.guo at linaro.org  Mon Aug 10 04:00:13 2015
From: hanjun.guo at linaro.org (Hanjun Guo)
Date: Mon, 10 Aug 2015 19:00:13 +0800
Subject: [PATCH v3 15/31] arm64: SMP support
In-Reply-To: <20150806095621.GB17691@e104818-lin.cambridge.arm.com>
References: <1347035226-18649-1-git-send-email-catalin.marinas@arm.com>
 <1347035226-18649-16-git-send-email-catalin.marinas@arm.com>
 <CAOZdJXVoDJM3y2mnKO+91yf2EHogKfMjumjhhi85REAfhcJM=Q@mail.gmail.com>
 <20150806095621.GB17691@e104818-lin.cambridge.arm.com>
Message-ID: <55C8843D.8050600@linaro.org>

Hi Timur,

On 08/06/2015 05:56 PM, Catalin Marinas wrote:
> On Wed, Aug 05, 2015 at 05:46:03PM -0700, Timur Tabi wrote:
>> Catalin,
>>
>> I know this patch is three years old, but I have a question about it:
>>
>> On Fri, Sep 7, 2012 at 9:26 AM, Catalin Marinas <catalin.marinas at arm.com> wrote:
>>> +static void ipi_cpu_stop(unsigned int cpu)
>>> +{
>>> +       if (system_state == SYSTEM_BOOTING ||
>>> +           system_state == SYSTEM_RUNNING) {
>>> +               raw_spin_lock(&stop_lock);
>>> +               pr_crit("CPU%u: stopping\n", cpu);
>>> +               dump_stack();
>>> +               raw_spin_unlock(&stop_lock);
>>> +       }
>>> +
>>> +       set_cpu_online(cpu, false);
>>> +
>>> +       local_fiq_disable();
>>> +       local_irq_disable();
>>> +
>>> +       while (1)
>>> +               cpu_relax();
>>> +}
>>
>> Why do you display a message and dump the stack when a CPU is stopped?
>>   I ask because emergency_restart() calls this function, and so
>> whenever I want to do an "emergency" reboot, it dumps the stack for
>> each core.  On an ARM64 system with lots of cores, this produces a ton
>> of output.  That makes emergency_restart() almost useless.
>
> This code was inherited from arch/arm which initially was always dumping
> the stack but it later gained the system_state check. Unless it's useful
> to anyone for debugging purposes, I'm ok with removing it.

Do you have patch for this one? My colleagues said that they met the
same problem :)

Thanks
Hanjun


From lftan at altera.com  Mon Aug 10 04:00:44 2015
From: lftan at altera.com (Ley Foon Tan)
Date: Mon, 10 Aug 2015 19:00:44 +0800
Subject: [PATCH v3 3/5] pci: altera: Add Altera PCIe MSI driver
In-Reply-To: <55C4C448.4020102@arm.com>
References: <1438933382-2936-1-git-send-email-lftan@altera.com>
 <1438933382-2936-4-git-send-email-lftan@altera.com>
 <55C4C448.4020102@arm.com>
Message-ID: <CAFiDJ58QQzDVBE1-0vvyYHv03R_PVs9Nk3t_0wcJAdozBSLz7Q@mail.gmail.com>

On Fri, Aug 7, 2015 at 10:44 PM, Marc Zyngier <marc.zyngier at arm.com> wrote:
> On 07/08/15 08:43, Ley Foon Tan wrote:
>> This patch adds Altera PCIe MSI driver. This soft IP supports configurable
>> number of vectors, which is a dts parameter.
>>
>> Signed-off-by: Ley Foon Tan <lftan at altera.com>
>> ---
>>  drivers/pci/host/Kconfig           |   8 +
>>  drivers/pci/host/Makefile          |   1 +
>>  drivers/pci/host/pcie-altera-msi.c | 309 +++++++++++++++++++++++++++++++++++++
>>  3 files changed, 318 insertions(+)
>>  create mode 100644 drivers/pci/host/pcie-altera-msi.c
>>
<snip>
>> +static int altera_irq_domain_alloc(struct irq_domain *domain, unsigned int virq,
>> +                                  unsigned int nr_irqs, void *args)
>> +{
>> +       struct altera_msi *msi = domain->host_data;
>> +       unsigned long bit;
>> +       u32 mask;
>> +
>
> As you cannot support multi-MSI, it would be good to have a
> WARN_ON(nr_irqs != 1) here. Just in case...
Noted.

>
>> +       mutex_lock(&msi->lock);
>> +
>> +       bit = find_first_zero_bit(msi->used, msi->num_of_vectors);
>> +       if (bit >= msi->num_of_vectors)
>> +               return -ENOSPC;
>> +
>> +       set_bit(bit, msi->used);
>> +
>> +       mutex_unlock(&msi->lock);
>> +
>> +       irq_domain_set_info(domain, virq, bit, &altera_msi_bottom_irq_chip,
>> +                           domain->host_data, handle_simple_irq,
>> +                           NULL, NULL);
>> +       set_irq_flags(virq, IRQF_VALID);
>> +
>> +       mask = msi_readl(msi, MSI_INTMASK);
>> +       mask |= 1 << bit;
>> +       msi_writel(msi, mask, MSI_INTMASK);
>> +
>> +       return 0;
>> +}
>> +
>> +static void altera_irq_domain_free(struct irq_domain *domain,
>> +                                  unsigned int virq, unsigned int nr_irqs)
>> +{
>> +       struct irq_data *d = irq_domain_get_irq_data(domain, virq);
>> +       struct altera_msi *msi = irq_data_get_irq_chip_data(d);
>> +       u32 mask;
>> +
>> +       mutex_lock(&msi->lock);
>> +
>> +       if (!test_bit(d->hwirq, msi->used)) {
>> +               dev_err(&msi->pdev->dev, "trying to free unused MSI#%lu\n",
>> +                       d->hwirq);
>> +       } else {
>> +               __clear_bit(d->hwirq, msi->used);
>> +               mask = msi_readl(msi, MSI_INTMASK);
>> +               mask &= ~(1 << d->hwirq);
>> +               msi_writel(msi, mask, MSI_INTMASK);
>> +       }
>> +
>> +       mutex_unlock(&msi->lock);
>> +}
>> +
>> +static const struct irq_domain_ops msi_domain_ops = {
>> +       .alloc  = altera_irq_domain_alloc,
>> +       .free   = altera_irq_domain_free,
>> +};
>> +
>> +static int altera_allocate_domains(struct altera_msi *msi)
>> +{
>> +       msi->inner_domain = irq_domain_add_linear(NULL, msi->num_of_vectors,
>> +                                            &msi_domain_ops, msi);
>> +       if (!msi->inner_domain) {
>> +               dev_err(&msi->pdev->dev, "failed to create IRQ domain\n");
>> +               return -ENOMEM;
>> +       }
>> +
>> +       msi->msi_domain = pci_msi_create_irq_domain(msi->pdev->dev.of_node,
>> +                               &altera_msi_domain_info, msi->inner_domain);
>> +       if (!msi->msi_domain) {
>> +               dev_err(&msi->pdev->dev, "failed to create MSI domain\n");
>> +               irq_domain_remove(msi->inner_domain);
>> +               return -ENOMEM;
>> +       }
>> +
>> +       return 0;
>> +}
>> +
>> +static void altera_free_domains(struct altera_msi *msi)
>> +{
>> +       irq_domain_remove(msi->msi_domain);
>> +       irq_domain_remove(msi->inner_domain);
>> +}
>> +
>> +static int altera_msi_remove(struct platform_device *pdev)
>> +{
>> +       struct altera_msi *msi = platform_get_drvdata(pdev);
>> +
>> +       msi_writel(msi, 0, MSI_INTMASK);
>> +       irq_set_chained_handler(msi->irq, NULL);
>> +       irq_set_handler_data(msi->irq, NULL);
>> +
>> +       altera_free_domains(msi);
>> +
>> +       platform_set_drvdata(pdev, NULL);
>> +       return 0;
>> +}
>> +
>> +static int altera_msi_probe(struct platform_device *pdev)
>> +{
>> +       struct altera_msi *msi;
>> +       struct device_node *np = pdev->dev.of_node;
>> +       struct resource *res;
>> +       int ret;
>> +
>> +       msi = devm_kzalloc(&pdev->dev, sizeof(struct altera_msi),
>> +                          GFP_KERNEL);
>> +       if (!msi)
>> +               return -ENOMEM;
>> +
>> +       mutex_init(&msi->lock);
>> +       msi->pdev = pdev;
>> +
>> +       res = platform_get_resource_byname(pdev, IORESOURCE_MEM, "csr");
>
> Error checking here.
Noted.
>
>> +       msi->csr_base = devm_ioremap_resource(&pdev->dev, res);
>> +       if (IS_ERR(msi->csr_base)) {
>> +               dev_err(&pdev->dev, "get csr resource failed\n");
>> +               return PTR_ERR(msi->csr_base);
>> +       }
>> +
>> +       res = platform_get_resource_byname(pdev, IORESOURCE_MEM,
>> +                                          "vector_slave");
>
> And here.
Noted.
>
>> +       msi->vector_base = devm_ioremap_resource(&pdev->dev, res);
>> +       if (IS_ERR(msi->vector_base)) {
>> +               dev_err(&pdev->dev, "get vector slave resource failed\n");
>> +               return PTR_ERR(msi->vector_base);
>> +       }
>> +
>> +       msi->vector_phy = res->start;
>> +
>> +       if (of_property_read_u32(np, "num-vectors", &msi->num_of_vectors)) {
>> +               dev_err(&pdev->dev, "failed to parse the number of vectors\n");
>> +               return -EINVAL;
>> +       }
>> +
>> +       ret = altera_allocate_domains(msi);
>> +       if (ret)
>> +               return ret;
>> +
>> +       msi->irq = platform_get_irq(pdev, 0);
>> +       if (msi->irq <= 0) {
>> +               dev_err(&pdev->dev, "failed to map IRQ: %d\n", msi->irq);
>> +               ret = -ENODEV;
>> +               goto err;
>> +       }
>> +
>> +       irq_set_chained_handler_and_data(msi->irq, altera_msi_isr, msi);
>> +       platform_set_drvdata(pdev, msi);
>> +
>> +       return 0;
>> +
>> +err:
>> +       altera_msi_remove(pdev);
>> +       return ret;
>> +}
>> +
>> +static const struct of_device_id altera_msi_of_match[] = {
>> +       { .compatible = "altr,msi-1.0", NULL },
>> +       { },
>> +};
>> +
>> +static struct platform_driver altera_msi_driver = {
>> +       .driver = {
>> +               .name = "altera-msi",
>> +               .of_match_table = altera_msi_of_match,
>> +       },
>> +       .probe = altera_msi_probe,
>> +       .remove = altera_msi_remove,
>> +};
>> +
>> +static int __init altera_msi_init(void)
>> +{
>> +       return platform_driver_register(&altera_msi_driver);
>> +}
>> +
>> +subsys_initcall(altera_msi_init);
>> +
>> +MODULE_AUTHOR("Ley Foon Tan <lftan at altera.com>");
>> +MODULE_DESCRIPTION("Altera PCIe MSI support");
>> +MODULE_LICENSE("GPL v2");
>> --
>> 1.8.2.1
>>
>
> Apart from the couple of nits above, this is starting to look good too.
> And as for the PCIe driver, you need to get the DT maintainers to review
> that part.
Okay, added DT maintainers to CC list.

Thanks for reviewing.

Regards
Ley Foon


From gregory.clement at free-electrons.com  Mon Aug 10 04:00:56 2015
From: gregory.clement at free-electrons.com (Gregory CLEMENT)
Date: Mon, 10 Aug 2015 13:00:56 +0200
Subject: [PATCH] ARM: mvebu: update mvebu_v7_defconfig for Armada 38x
 USB3.0
In-Reply-To: <1439200314-26850-1-git-send-email-jaz@semihalf.com>
References: <1439200314-26850-1-git-send-email-jaz@semihalf.com>
Message-ID: <55C88468.2000400@free-electrons.com>

Hi Grzegorz,

On 10/08/2015 11:51, Grzegorz Jaszczyk wrote:
> 	This patch enables the fixed voltage regulator and the gpio PCA953X
> 	drivers in mvebu_v7_defconfig, as they are used for enabling the USB3.0
> 	phy on some of the Armada's 38x boards.
> 

The same patch had already been merged in arm-soc and should be part of
4.3: See: "ARM: mvebu: update mvebu_v7_defconfig with features needed
for Armada 388 GP".
http://thread.gmane.org/gmane.linux.ports.arm.kernel/421082/focus=425086

Thanks,

Gregory

> Signed-off-by: Grzegorz Jaszczyk <jaz at semihalf.com>
> Cc: <stable at vger.kernel.org>
> ---
>  arch/arm/configs/mvebu_v7_defconfig | 3 +++
>  1 file changed, 3 insertions(+)
> 
> diff --git a/arch/arm/configs/mvebu_v7_defconfig b/arch/arm/configs/mvebu_v7_defconfig
> index cacc9f4..1b8ecf4 100644
> --- a/arch/arm/configs/mvebu_v7_defconfig
> +++ b/arch/arm/configs/mvebu_v7_defconfig
> @@ -83,11 +83,14 @@ CONFIG_I2C_MV64XXX=y
>  CONFIG_SPI=y
>  CONFIG_SPI_ORION=y
>  CONFIG_GPIO_SYSFS=y
> +CONFIG_GPIO_PCA953X=y
>  CONFIG_SENSORS_GPIO_FAN=y
>  CONFIG_THERMAL=y
>  CONFIG_ARMADA_THERMAL=y
>  CONFIG_WATCHDOG=y
>  CONFIG_ORION_WATCHDOG=y
> +CONFIG_REGULATOR=y
> +CONFIG_REGULATOR_FIXED_VOLTAGE=y
>  CONFIG_SOUND=y
>  CONFIG_SND=y
>  CONFIG_SND_SOC=y
> 


-- 
Gregory Clement, Free Electrons
Kernel, drivers, real-time and embedded Linux
development, consulting, training and support.
http://free-electrons.com


From lftan at altera.com  Mon Aug 10 04:02:08 2015
From: lftan at altera.com (Ley Foon Tan)
Date: Mon, 10 Aug 2015 19:02:08 +0800
Subject: [PATCH v3 2/5] pci:host: Add Altera PCIe host controller driver
In-Reply-To: <55C4C1E2.7080205@arm.com>
References: <1438933382-2936-1-git-send-email-lftan@altera.com>
 <1438933382-2936-3-git-send-email-lftan@altera.com>
 <55C4C1E2.7080205@arm.com>
Message-ID: <CAFiDJ5-3MTjMQDgXH4Om_-S8d0MTLPeg2V7pQQhzPCow0E9jeQ@mail.gmail.com>

On Fri, Aug 7, 2015 at 10:34 PM, Marc Zyngier <marc.zyngier at arm.com> wrote:
> On 07/08/15 08:42, Ley Foon Tan wrote:
>> This patch adds the Altera PCIe host controller driver.
>>
>> Signed-off-by: Ley Foon Tan <lftan at altera.com>
>> ---
>>  drivers/pci/host/Kconfig       |   7 +
>>  drivers/pci/host/Makefile      |   1 +
>>  drivers/pci/host/pcie-altera.c | 532 +++++++++++++++++++++++++++++++++++++++++
>>  3 files changed, 540 insertions(+)
>>  create mode 100644 drivers/pci/host/pcie-altera.c

<snip>

>> +static int tlp_read_packet(struct altera_pcie *pcie, u32 *value)
>> +{
>> +       u8 loop;
>> +       struct tlp_rp_regpair_t tlp_rp_regdata;
>> +
>> +       for (loop = TLP_LOOP; loop > 0; loop--) {
>
> I'd prefer to see the more common idiom:
>
>         for (loop = 0; loop < TLP_LOOP; loop++) {
Okay, will change this.

>> +               tlp_read_rx(pcie, &tlp_rp_regdata);
>> +               if (tlp_rp_regdata.ctrl & RP_RXCPL_EOP) {
>> +                       if (value)
>> +                               *value = tlp_rp_regdata.reg0;
>> +                       return PCIBIOS_SUCCESSFUL;
>> +               }
>
> Don't you need some form of relaxation here? A delay of some sort?
> Repeatedly polling the HW is usually not helping it to recover...
Yes, will add udelay here.

<snip>

>> +static int altera_pcie_init_irq_domain(struct altera_pcie *pcie)
>> +{
>> +       struct device *dev = &pcie->pdev->dev;
>> +       struct device_node *node = dev->of_node;
>> +
>> +       /* Setup INTx */
>> +       pcie->irq_domain = irq_domain_add_linear(node, INTX_NUM,
>> +                                       &intx_domain_ops, pcie);
>> +       if (!pcie->irq_domain) {
>> +               dev_err(dev, "Failed to get a INTx IRQ domain\n");
>> +               return PTR_ERR(pcie->irq_domain);
>
> Err, no. irq_domain_add returns NULL on error, so PTR_ERR(NULL) is still
> going to be zero.

Change to return -ENOMEM.

>
>> +       }
>> +
>> +       return 0;
>> +}
>> +
>> +static int altera_pcie_parse_dt(struct altera_pcie *pcie)
>> +{
>> +       struct resource *cra;
>> +       struct platform_device *pdev = pcie->pdev;
>> +
>> +       cra = platform_get_resource_byname(pdev, IORESOURCE_MEM, "Cra");
>
> Probably worth checking that this hasn't failed.
Noted. Will add error checking.
>
>> +       pcie->cra_base = devm_ioremap_resource(&pdev->dev, cra);
>> +       if (IS_ERR(pcie->cra_base)) {
>> +               dev_err(&pdev->dev, "get Cra resource failed\n");
>> +               return PTR_ERR(pcie->cra_base);
>> +       }
>> +
>> +       /* setup IRQ */
>> +       pcie->irq = platform_get_irq(pdev, 0);
>> +       if (pcie->irq <= 0) {
>> +               dev_err(&pdev->dev, "failed to get IRQ: %d\n", pcie->irq);
>> +               return -EINVAL;
>> +       }
>> +
>> +       irq_set_chained_handler_and_data(pcie->irq, altera_pcie_isr, pcie);
>> +
>> +       return 0;
>> +}
>> +
>> +static int altera_pcie_probe(struct platform_device *pdev)
>> +{
>> +       struct altera_pcie *pcie;
>> +       struct pci_bus *bus;
>> +       int ret;
>> +
>> +       pcie = devm_kzalloc(&pdev->dev, sizeof(*pcie), GFP_KERNEL);
>> +       if (!pcie)
>> +               return -ENOMEM;
>> +
>> +       pcie->pdev = pdev;
>> +
>> +       ret = altera_pcie_parse_dt(pcie);
>> +       if (ret) {
>> +               dev_err(&pdev->dev, "Parsing DT failed\n");
>> +               return ret;
>> +       }
>> +
>> +       INIT_LIST_HEAD(&pcie->resources);
>> +
>> +       ret = altera_pcie_parse_request_of_pci_ranges(pcie);
>> +       if (ret) {
>> +               dev_err(&pdev->dev, "Failed add resources\n");
>> +               return ret;
>> +       }
>> +
>> +       ret = altera_pcie_init_irq_domain(pcie);
>> +       if (ret) {
>> +               dev_err(&pdev->dev, "Failed creating IRQ Domain\n");
>> +               return ret;
>> +       }
>> +
>> +       pcie->root_bus_nr = 0;
>> +
>> +       /* clear all interrupts */
>> +       cra_writel(pcie, P2A_INT_STS_ALL, P2A_INT_STATUS);
>> +       /* enable all interrupts */
>> +       cra_writel(pcie, P2A_INT_ENA_ALL, P2A_INT_ENABLE);
>> +
>> +       bus = pci_scan_root_bus(&pdev->dev, pcie->root_bus_nr, &altera_pcie_ops,
>> +                               pcie, &pcie->resources);
>> +       if (!bus)
>> +               return -ENOMEM;
>> +
>> +       pci_fixup_irqs(pci_common_swizzle, of_irq_parse_and_map_pci);
>> +       pci_assign_unassigned_bus_resources(bus);
>> +       pci_bus_add_devices(bus);
>> +
>> +       platform_set_drvdata(pdev, pcie);
>> +       return ret;
>> +}
>> +
>> +static int __exit altera_pcie_remove(struct platform_device *pdev)
>> +{
>> +       struct altera_pcie *pcie = platform_get_drvdata(pdev);
>> +
>> +       altera_pcie_free_irq_domain(pcie);
>> +       platform_set_drvdata(pdev, NULL);
>> +       return 0;
>> +}
>> +
>> +static const struct of_device_id altera_pcie_of_match[] = {
>> +       { .compatible = "altr,pcie-root-port-1.0", },
>> +       {},
>> +};
>> +MODULE_DEVICE_TABLE(of, altera_pcie_of_match);
>> +
>> +static struct platform_driver altera_pcie_driver = {
>> +       .probe          = altera_pcie_probe,
>> +       .remove         = altera_pcie_remove,
>> +       .driver = {
>> +               .name   = "altera-pcie",
>> +               .of_match_table = altera_pcie_of_match,
>> +       },
>> +};
>> +
>> +module_platform_driver(altera_pcie_driver);
>> +
>> +MODULE_AUTHOR("Ley Foon Tan <lftan at altera.com>");
>> +MODULE_DESCRIPTION("Altera PCIe host controller driver");
>> +MODULE_LICENSE("GPL v2");
>> --
>> 1.8.2.1
>>
>
> This is starting to look better. You should get someone to review the DT
> parts though.
I have CC-ed DT maintainers. Hope someone can help to review.


Thanks for reviewing.

Regards
Ley Foon


From lftan.linux at gmail.com  Mon Aug 10 04:03:57 2015
From: lftan.linux at gmail.com (Ley Foon Tan)
Date: Mon, 10 Aug 2015 19:03:57 +0800
Subject: [PATCH v3 4/5] Documentation: dt-bindings: pci: altera pcie
 device tree binding
In-Reply-To: <1438933382-2936-5-git-send-email-lftan@altera.com>
References: <1438933382-2936-1-git-send-email-lftan@altera.com>
 <1438933382-2936-5-git-send-email-lftan@altera.com>
Message-ID: <CAFiDJ58b62Q7CnoU1+h2dSf7xBPAhjaY5kaeeOrxRVRZ84WJxw@mail.gmail.com>

On Fri, Aug 7, 2015 at 3:43 PM, Ley Foon Tan <lftan at altera.com> wrote:
> This patch adds the bindings for Altera PCIe host controller driver and
> Altera PCIe MSI driver.
>
> Signed-off-by: Ley Foon Tan <lftan at altera.com>
> ---
>  .../devicetree/bindings/pci/altera-pcie-msi.txt    | 27 ++++++++++++
>  .../devicetree/bindings/pci/altera-pcie.txt        | 49 ++++++++++++++++++++++
>  2 files changed, 76 insertions(+)
>  create mode 100644 Documentation/devicetree/bindings/pci/altera-pcie-msi.txt
>  create mode 100644 Documentation/devicetree/bindings/pci/altera-pcie.txt
>
> diff --git a/Documentation/devicetree/bindings/pci/altera-pcie-msi.txt b/Documentation/devicetree/bindings/pci/altera-pcie-msi.txt
> new file mode 100644
> index 0000000..7f330c9
> --- /dev/null
> +++ b/Documentation/devicetree/bindings/pci/altera-pcie-msi.txt
> @@ -0,0 +1,27 @@
> +* Altera PCIe MSI controller
> +
> +Required properties:
> +- compatible:  should contain "altr,msi-1.0"
> +- reg:         specifies the physical base address of the controller and
> +               the length of the memory mapped region.
> +- reg-names:   Must include the following entries:
> +               "csr": CSR registers
> +               "vector_slave": vectors region
> +-interrupts:   specifies the interrupt source of the parent interrupt
> +               controller. The format of the interrupt specifier depends on the
> +               parent interrupt controller.
> +- num-vectors: Number of vectors, range 1 to 32.
> +- msi-controller:      indicates that this is MSI controller node
> +
> +
> +Example
> +msi0: msi at 0xFF200000 {
> +       compatible = "altr,msi-1.0";
> +       reg = <0xFF200000 0x00000010
> +               0xFF200010 0x00000080>;
> +       reg-names = "csr", "vector_slave";
> +       interrupt-parent = <&hps_0_arm_gic_0>;
> +       interrupts = <0 42 4>;
> +       msi-controller = <1>;
> +       num-vectors = <32>;
> +};
> diff --git a/Documentation/devicetree/bindings/pci/altera-pcie.txt b/Documentation/devicetree/bindings/pci/altera-pcie.txt
> new file mode 100644
> index 0000000..729193d
> --- /dev/null
> +++ b/Documentation/devicetree/bindings/pci/altera-pcie.txt
> @@ -0,0 +1,49 @@
> +* Altera PCIe controller
> +
> +Required properties:
> +- compatible : should contain "altr,pcie-root-port-1.0"
> +- reg:         A list of physical base address and length for TXS and CRA.
> +- reg-names:   Must include the following entries:
> +               "Txs": TXS region
> +               "Cra": Control register access region
> +-interrupts:   specifies the interrupt source of the parent interrupt controller.
> +               The format of the interrupt specifier depends on the parent interrupt
> +               controller.
> +- device_type: must be "pci"
> +- #address-cells:      set to <3>
> +- #size-cells: set to <2>
> +- #interrupt-cells:    set to <1>
> +- ranges:              Describes the translation of addresses for root ports and standard
> +               PCI regions.
> +- interrupt-map-mask and interrupt-map: standard PCI properties
> +       to define the mapping of the PCIe interface to interrupt
> +       numbers.
> +
> +Optional properties:
> +- msi-parent:  Link to the hardware entity that serves as the MSI controller for this PCIe
> +               controller.
> +- bus-range:   PCI bus numbers covered
> +
> +Example
> +       pcie_0: pcie at 0xc00000000 {
> +               compatible = "altr,pcie-root-port-1.0";
> +               reg = <0xc0000000 0x20000000>,
> +                       <0xff220000 0x00004000>;
> +               reg-names = "Txs", "Cra";
> +               interrupt-parent = <&hps_0_arm_gic_0>;
> +               interrupts = <0 40 4>;
> +               interrupt-controller;
> +               #interrupt-cells = <1>;
> +               bus-range = <0x0 0xFF>;
> +               device_type = "pci";
> +               msi-parent = <&msi_to_gic_gen_0>;
> +               #address-cells = <3>;
> +               #size-cells = <2>;
> +               interrupt-map-mask = <0 0 0 7>;
> +               interrupt-map = <0 0 0 1 &pcie_0 1>,
> +                                   <0 0 0 2 &pcie_0 2>,
> +                                   <0 0 0 3 &pcie_0 3>,
> +                                   <0 0 0 4 &pcie_0 4>;
> +               ranges = <0x82000000 0x00000000 0x00000000 0xc0000000 0x00000000 0x10000000
> +                           0x82000000 0x00000000 0x10000000 0xd0000000 0x00000000 0x10000000>;
> +       };
> --

Added DT maintainers to CC list. Please help to review if anything
need to be changed.

Thanks.

Regards
Ley Foon


From monstr at monstr.eu  Mon Aug 10 04:13:26 2015
From: monstr at monstr.eu (Michal Simek)
Date: Mon, 10 Aug 2015 13:13:26 +0200
Subject: [GIT PULL] Xilinx Zynq changes for v4.3
In-Reply-To: <20150808005509.2416.8174@quantum>
References: <55BB31E8.7040806@monstr.eu> <20150805085344.GH6390@localhost>
 <20150808005509.2416.8174@quantum>
Message-ID: <55C88756.1090309@monstr.eu>

Hi,

On 08/08/2015 02:55 AM, Michael Turquette wrote:
> Quoting Olof Johansson (2015-08-05 01:53:44)
>> Hi,
>>
>> On Fri, Jul 31, 2015 at 10:29:28AM +0200, Michal Simek wrote:
>>> Hi,
>>>
>>> please pull these SoC changes to your tree.
>>>
>>> Thanks,
>>> Michal
>>>
>>> The following changes since commit d770e558e21961ad6cfdf0ff7df0eb5d7d4f0754:
>>>
>>>   Linux 4.2-rc1 (2015-07-05 11:01:52 -0700)
>>>
>>> are available in the git repository at:
>>>
>>>   https://github.com/Xilinx/linux-xlnx.git tags/zynq-soc-for-4.3
>>>
>>> for you to fetch changes up to e4a9288942392965bd5cfad93d9996b83c0dc4a6:
>>>
>>>   ARM: zynq: reserve space for jump target in secondary trampoline
>>> (2015-07-31 10:24:41 +0200)
>>
>> Merged, however:
>>
>>> Arun Chandran (1):
>>>       ARM: zynq: Fix earlyprintk in big endian mode
>>>
>>> Masahiro Yamada (1):
>>>       clk: zynq: remove redundant $(CONFIG_ARCH_ZYNQ) in Makefile
>>
>> This should have gone through the clk tree. Seems small and simple enough that
>> I'll take it, but please send patches through appropriate maintainers.
>>
>> (Adding Mike and Stephen on cc so they know about it).
> 
> Olof,
> 
> Thanks for the heads up.
> 
> Michal,
> 
> No reason that patch couldn't have gone through the clk tree. It was
> posted on July 27th, which wasn't that long ago. Please feel free to
> ping Stephen or I on #linux-clk if you think one of your clk patches has
> slipped through the cracks.

I took it because it was pretty simple and there was no reaction from
you. Thanks for sending link to IRC. I wasn't aware that there is any
clk specific IRC.
Next time I will make sure that patches will go in the right direction.

Thanks,
Michal


-- 
Michal Simek, Ing. (M.Eng), OpenPGP -> KeyID: FE3D1F91
w: www.monstr.eu p: +42-0-721842854
Maintainer of Linux kernel - Microblaze cpu - http://www.monstr.eu/fdt/
Maintainer of Linux kernel - Xilinx Zynq ARM architecture
Microblaze U-BOOT custodian and responsible for u-boot arm zynq platform


-------------- next part --------------
A non-text attachment was scrubbed...
Name: signature.asc
Type: application/pgp-signature
Size: 198 bytes
Desc: OpenPGP digital signature
URL: <http://lists.infradead.org/pipermail/linux-arm-kernel/attachments/20150810/b36e9016/attachment.sig>

From stefano.stabellini at eu.citrix.com  Mon Aug 10 04:18:15 2015
From: stefano.stabellini at eu.citrix.com (Stefano Stabellini)
Date: Mon, 10 Aug 2015 12:18:15 +0100
Subject: [PATCH v3 12/20] xen/balloon: Don't rely on the page granularity
 is the same for Xen and Linux
In-Reply-To: <1438966019-19322-13-git-send-email-julien.grall@citrix.com>
References: <1438966019-19322-1-git-send-email-julien.grall@citrix.com>
 <1438966019-19322-13-git-send-email-julien.grall@citrix.com>
Message-ID: <alpine.DEB.2.02.1508101207071.11337@kaball.uk.xensource.com>

On Fri, 7 Aug 2015, Julien Grall wrote:
> For ARM64 guests, Linux is able to support either 64K or 4K page
> granularity. Although, the hypercall interface is always based on 4K
> page granularity.
> 
> With 64K page granularity, a single page will be spread over multiple
> Xen frame.
> 
> To avoid splitting the page into 4K frame, take advantage of the
> extent_order field to directly allocate/free chunk of the Linux page
> size.
> 
> Note that PVMMU is only used for PV guest (which is x86) and the page
> granularity is always 4KB. Some BUILD_BUG_ON has been added to ensure
> that because the code has not been modified.
> 
> Signed-off-by: Julien Grall <julien.grall at citrix.com>

This is much better than the previous version. Good idea using the
extent_order field.

I only have a minor comment below.


> ---
> Cc: Konrad Rzeszutek Wilk <konrad.wilk at oracle.com>
> Cc: Boris Ostrovsky <boris.ostrovsky at oracle.com>
> Cc: David Vrabel <david.vrabel at citrix.com>
> Cc: Wei Liu <wei.liu2 at citrix.com>
> 
>     Changes in v3:
>         - Fix errors reported by checkpatch.pl
>         - s/mfn/gfn/ based on the new naming
>         - Rather than splitting the page into 4KB chunk, use the
>         extent_order field to allocate directly a Linux page size. This
>         is avoid lots of code for no benefits.
> 
>     Changes in v2:
>         - Use xen_apply_to_page to split a page in 4K chunk
>         - It's not necessary to have a smaller frame list. Re-use
>         PAGE_SIZE
>         - Convert reserve_additional_memory to use XEN_... macro
> ---
>  drivers/xen/balloon.c | 47 ++++++++++++++++++++++++++++++++++++-----------
>  1 file changed, 36 insertions(+), 11 deletions(-)
> 
> diff --git a/drivers/xen/balloon.c b/drivers/xen/balloon.c
> index 9734649..c8739c8 100644
> --- a/drivers/xen/balloon.c
> +++ b/drivers/xen/balloon.c
> @@ -70,6 +70,9 @@
>  #include <xen/features.h>
>  #include <xen/page.h>
>  
> +/* Use one extent per PAGE_SIZE to avoid break down into multiple frame */
> +#define EXTENT_ORDER (fls(XEN_PFN_PER_PAGE) - 1)
> +
>  /*
>   * balloon_process() state:
>   *
> @@ -230,6 +233,11 @@ static enum bp_state reserve_additional_memory(long credit)
>  	nid = memory_add_physaddr_to_nid(hotplug_start_paddr);
>  
>  #ifdef CONFIG_XEN_HAVE_PVMMU
> +	/* We don't support PV MMU when Linux and Xen is using
> +	 * different page granularity.
> +	 */
> +	BUILD_BUG_ON(XEN_PAGE_SIZE != PAGE_SIZE);
> +
>          /*
>           * add_memory() will build page tables for the new memory so
>           * the p2m must contain invalid entries so the correct
> @@ -326,11 +334,11 @@ static enum bp_state reserve_additional_memory(long credit)
>  static enum bp_state increase_reservation(unsigned long nr_pages)
>  {
>  	int rc;
> -	unsigned long  pfn, i;
> +	unsigned long i;
>  	struct page   *page;
>  	struct xen_memory_reservation reservation = {
>  		.address_bits = 0,
> -		.extent_order = 0,
> +		.extent_order = EXTENT_ORDER,
>  		.domid        = DOMID_SELF
>  	};
>  
> @@ -352,7 +360,11 @@ static enum bp_state increase_reservation(unsigned long nr_pages)
>  			nr_pages = i;
>  			break;
>  		}
> -		frame_list[i] = page_to_pfn(page);
> +
> +		/* XENMEM_populate_physmap requires a PFN based on Xen
> +		 * granularity.
> +		 */
> +		frame_list[i] = xen_page_to_pfn(page);
>  		page = balloon_next_page(page);
>  	}
>  
> @@ -366,10 +378,15 @@ static enum bp_state increase_reservation(unsigned long nr_pages)
>  		page = balloon_retrieve(false);
>  		BUG_ON(page == NULL);
>  
> -		pfn = page_to_pfn(page);
> -
>  #ifdef CONFIG_XEN_HAVE_PVMMU
> +		/* We don't support PV MMU when Linux and Xen is using
> +		 * different page granularity.
> +		 */
> +		BUILD_BUG_ON(XEN_PAGE_SIZE != PAGE_SIZE);
> +
>  		if (!xen_feature(XENFEAT_auto_translated_physmap)) {
> +			unsigned long pfn = page_to_pfn(page);
> +
>  			set_phys_to_machine(pfn, frame_list[i]);
>  
>  			/* Link back into the page tables if not highmem. */
> @@ -396,14 +413,15 @@ static enum bp_state increase_reservation(unsigned long nr_pages)
>  static enum bp_state decrease_reservation(unsigned long nr_pages, gfp_t gfp)
>  {
>  	enum bp_state state = BP_DONE;
> -	unsigned long  pfn, i;
> +	unsigned long i;
>  	struct page   *page;
>  	int ret;
>  	struct xen_memory_reservation reservation = {
>  		.address_bits = 0,
> -		.extent_order = 0,
> +		.extent_order = EXTENT_ORDER,
>  		.domid        = DOMID_SELF
>  	};
> +	static struct page *pages[ARRAY_SIZE(frame_list)];

This array can be rather large: I would try to avoid it, see below.


>  #ifdef CONFIG_XEN_BALLOON_MEMORY_HOTPLUG
>  	if (balloon_stats.hotplug_pages) {
> @@ -426,7 +444,9 @@ static enum bp_state decrease_reservation(unsigned long nr_pages, gfp_t gfp)
>  		}
>  		scrub_page(page);
>  
> -		frame_list[i] = page_to_pfn(page);
> +		/* XENMEM_decrease_reservation requires a GFN */
> +		frame_list[i] = xen_page_to_gfn(page);
> +		pages[i] = page;
>  	}
>  
>  	/*
> @@ -440,12 +460,17 @@ static enum bp_state decrease_reservation(unsigned long nr_pages, gfp_t gfp)
>  
>  	/* Update direct mapping, invalidate P2M, and add to balloon. */
>  	for (i = 0; i < nr_pages; i++) {
> -		pfn = frame_list[i];
> -		frame_list[i] = pfn_to_gfn(pfn);
> -		page = pfn_to_page(pfn);
> +		page = pages[i];
>  
>  #ifdef CONFIG_XEN_HAVE_PVMMU
> +		/* We don't support PV MMU when Linux and Xen is using
> +		 * different page granularity.
> +		 */
> +		BUILD_BUG_ON(XEN_PAGE_SIZE != PAGE_SIZE);
> +
>  		if (!xen_feature(XENFEAT_auto_translated_physmap)) {
> +			unsigned long pfn = page_to_pfn(page);

I would simply and avoid introducing a new array:
    pfn = (frame_list[i] << XEN_PAGE_SHIFT) >> PAGE_SHIFT;
    page = pfn_to_page(pfn);
    
    
    
>  			if (!PageHighMem(page)) {
>  				ret = HYPERVISOR_update_va_mapping(
>  						(unsigned long)__va(pfn << PAGE_SHIFT),
> -- 
> 2.1.4
> 


From stefan.wahren at i2se.com  Mon Aug 10 04:24:38 2015
From: stefan.wahren at i2se.com (Stefan Wahren)
Date: Mon, 10 Aug 2015 13:24:38 +0200 (CEST)
Subject: [PATCH v9 0/9] Add simple NVMEM Framework via regmap.
In-Reply-To: <55C87EEF.6020609@linaro.org>
References: <1437995567-11203-1-git-send-email-srinivas.kandagatla@linaro.org>
 <1438693367.3793.29.camel@pengutronix.de> <20150809151916.GF14271@lunn.ch>
 <55C87EEF.6020609@linaro.org>
Message-ID: <997560650.82109.1439205878609.JavaMail.open-xchange@oxbsltgw00.schlund.de>

Hi Srinivas,
hi Andrew,

[add Sanchayan and Philipp]

> Srinivas Kandagatla <srinivas.kandagatla at linaro.org> hat am 10. August 2015 um
> 12:37 geschrieben:
>
>
> Hi Andrew,
>
> On 09/08/15 16:19, Andrew Lunn wrote:
> > Hi Srinivas
> >
> > The AT24 eeprom driver contains the comment:
> >
> > /*
> > * Export the EEPROM bytes through sysfs, since that's convenient.
> > * By default, only root should see the data (maybe passwords etc)
> > */
> >
> > and as you would expect from this:
> >
> > # ls -l
> > ./devices/platform/soc/soc:aips-bus at 40000000/40066000.i2c/i2c-0/0-0050/eeprom
> > -rw------- 1 root root 512 Aug 9 10:16
> > ./devices/platform/soc/soc:aips-bus at 40000000/40066000.i2c/i2c-0/0-0050/eeprom
> >
> > The AT25 and the MAX6875 driver are the same.
> >
> > However nvmem has different defaults:
> >
> > # ls -l
> > ./devices/platform/soc/soc:aips-bus at 40000000/40066000.i2c/i2c-0/0-0050/0-00500/nvmem
> > -rw-r--r-- 1 root root 0 Aug 9 10:16
> > ./devices/platform/soc/soc:aips-bus at 40000000/40066000.i2c/i2c-0/0-0050/0-00500/nvmem
> >
> Yes, nvmem by default sets the read permission for everyone S_IRUGO.
> Which was the most common use case.

i can only speak for mxs-ocotp, but root-only access is sufficient.

>
> > Has this been considered and discussed?
> Thanks for bringing this up, No, we did not discuss this explicitly, but
> it should not be an issue to accommodate this. Provider still have
> flexibility to configure such things.

IMHO it would better the default settings of the framework would be compatible
and same restrictive as the eeprom drivers.

In case a provider needs more privileges, it should be his job.

>
> As a first patchset we wanted to keep the framework simple and add
> features as we move on.

That's true, but it's an ABI too. So changing default settings soon is better.

Regards
Stefan

>
> Thanks,
> srini
> >
> > Thanks
> > Andrew
> >
>
> _______________________________________________
> linux-arm-kernel mailing list
> linux-arm-kernel at lists.infradead.org
> http://lists.infradead.org/mailman/listinfo/linux-arm-kernel


From julien.grall at citrix.com  Mon Aug 10 04:24:20 2015
From: julien.grall at citrix.com (Julien Grall)
Date: Mon, 10 Aug 2015 12:24:20 +0100
Subject: [Xen-devel] [PATCH v3 09/20] xen/biomerge: Don't allow biovec
 to be merge when Linux is not using 4KB page
In-Reply-To: <alpine.DEB.2.02.1508101149070.11337@kaball.uk.xensource.com>
References: <1438966019-19322-1-git-send-email-julien.grall@citrix.com>
 <1438966019-19322-10-git-send-email-julien.grall@citrix.com>
 <alpine.DEB.2.02.1508101149070.11337@kaball.uk.xensource.com>
Message-ID: <55C889E4.8050307@citrix.com>

Hi Stefano,

On 10/08/15 11:50, Stefano Stabellini wrote:
> On Fri, 7 Aug 2015, Julien Grall wrote:
>> On ARM all dma-capable devices on a same platform may not be protected
>> by an IOMMU. The DMA requests have to use the BFN (i.e MFN on ARM) in
>> order to use correctly the device.
>>
>> While the DOM0 memory is allocated in a 1:1 fashion (PFN == MFN), grant
>> mapping will screw this contiguous mapping.
>>
>> When Linux is using 64KB page granularitary, the page may be split
>> accross multiple non-contiguous MFN (Xen is using 4KB page
>> granularity). Therefore a DMA request will likely fail.
>>
>> Checking that a 64KB page is using contiguous MFN is tedious. For
>> now, always says that biovec are not mergeable.
>>
>> Signed-off-by: Julien Grall <julien.grall at citrix.com>
> 
> Please fix the grammar in the subject line.

If I made a mistake it's unlikely that I will find myself which one I made.

Anyway, I guess you mean to replace merge by merged? I don't see any
other in the subject.

Regards,

-- 
Julien Grall


From stefano.stabellini at eu.citrix.com  Mon Aug 10 04:25:27 2015
From: stefano.stabellini at eu.citrix.com (Stefano Stabellini)
Date: Mon, 10 Aug 2015 12:25:27 +0100
Subject: [Xen-devel] [PATCH v3 09/20] xen/biomerge: Don't allow biovec
 to be merge when Linux is not using 4KB page
In-Reply-To: <55C889E4.8050307@citrix.com>
References: <1438966019-19322-1-git-send-email-julien.grall@citrix.com>
 <1438966019-19322-10-git-send-email-julien.grall@citrix.com>
 <alpine.DEB.2.02.1508101149070.11337@kaball.uk.xensource.com>
 <55C889E4.8050307@citrix.com>
Message-ID: <alpine.DEB.2.02.1508101224220.11337@kaball.uk.xensource.com>

On Mon, 10 Aug 2015, Julien Grall wrote:
> Hi Stefano,
> 
> On 10/08/15 11:50, Stefano Stabellini wrote:
> > On Fri, 7 Aug 2015, Julien Grall wrote:
> >> On ARM all dma-capable devices on a same platform may not be protected
> >> by an IOMMU. The DMA requests have to use the BFN (i.e MFN on ARM) in
> >> order to use correctly the device.
> >>
> >> While the DOM0 memory is allocated in a 1:1 fashion (PFN == MFN), grant
> >> mapping will screw this contiguous mapping.
> >>
> >> When Linux is using 64KB page granularitary, the page may be split
> >> accross multiple non-contiguous MFN (Xen is using 4KB page
> >> granularity). Therefore a DMA request will likely fail.
> >>
> >> Checking that a 64KB page is using contiguous MFN is tedious. For
> >> now, always says that biovec are not mergeable.
> >>
> >> Signed-off-by: Julien Grall <julien.grall at citrix.com>
> > 
> > Please fix the grammar in the subject line.
> 
> If I made a mistake it's unlikely that I will find myself which one I made.
> 
> Anyway, I guess you mean to replace merge by merged? I don't see any
> other in the subject.

yes and page/pages:

xen/biomerge: Don't allow biovec's to be merged when Linux is not using 4KB pages


From julien.grall at citrix.com  Mon Aug 10 04:31:03 2015
From: julien.grall at citrix.com (Julien Grall)
Date: Mon, 10 Aug 2015 12:31:03 +0100
Subject: [PATCH v3 12/20] xen/balloon: Don't rely on the page granularity
 is the same for Xen and Linux
In-Reply-To: <alpine.DEB.2.02.1508101207071.11337@kaball.uk.xensource.com>
References: <1438966019-19322-1-git-send-email-julien.grall@citrix.com>
 <1438966019-19322-13-git-send-email-julien.grall@citrix.com>
 <alpine.DEB.2.02.1508101207071.11337@kaball.uk.xensource.com>
Message-ID: <55C88B77.8030700@citrix.com>

Hi Stefano,

On 10/08/15 12:18, Stefano Stabellini wrote:
>>  			/* Link back into the page tables if not highmem. */
>> @@ -396,14 +413,15 @@ static enum bp_state increase_reservation(unsigned long nr_pages)
>>  static enum bp_state decrease_reservation(unsigned long nr_pages, gfp_t gfp)
>>  {
>>  	enum bp_state state = BP_DONE;
>> -	unsigned long  pfn, i;
>> +	unsigned long i;
>>  	struct page   *page;
>>  	int ret;
>>  	struct xen_memory_reservation reservation = {
>>  		.address_bits = 0,
>> -		.extent_order = 0,
>> +		.extent_order = EXTENT_ORDER,
>>  		.domid        = DOMID_SELF
>>  	};
>> +	static struct page *pages[ARRAY_SIZE(frame_list)];
> 
> This array can be rather large: I would try to avoid it, see below.

[..]

> 
> I would simply and avoid introducing a new array:
>     pfn = (frame_list[i] << XEN_PAGE_SHIFT) >> PAGE_SHIFT;
>     page = pfn_to_page(pfn);

Which won't work because the frame_list contains a gfn and not a pfn.
We need to translate back the gfn into a pfn and the into a page.

The cost of the translation may be big and I wanted to avoid anymore
XEN_PAGE_SHIFT in the code. In general we should avoid to deal with 4KB
PFN when it's not necessary, it make the code more confusing to read.

If your only concern is the size of the array, we could decrease the
number of frames by batch. Or allocation the variable once a boot time.

Regards,

-- 
Julien Grall


From julien.grall at citrix.com  Mon Aug 10 04:32:40 2015
From: julien.grall at citrix.com (Julien Grall)
Date: Mon, 10 Aug 2015 12:32:40 +0100
Subject: [Xen-devel] [PATCH v3 09/20] xen/biomerge: Don't allow biovec
 to be merge when Linux is not using 4KB page
In-Reply-To: <alpine.DEB.2.02.1508101224220.11337@kaball.uk.xensource.com>
References: <1438966019-19322-1-git-send-email-julien.grall@citrix.com>
 <1438966019-19322-10-git-send-email-julien.grall@citrix.com>
 <alpine.DEB.2.02.1508101149070.11337@kaball.uk.xensource.com>
 <55C889E4.8050307@citrix.com>
 <alpine.DEB.2.02.1508101224220.11337@kaball.uk.xensource.com>
Message-ID: <55C88BD8.7040807@citrix.com>

On 10/08/15 12:25, Stefano Stabellini wrote:
> yes and page/pages:
> 
> xen/biomerge: Don't allow biovec's to be merged when Linux is not using 4KB pages

Why the ' in biovec's ? Shouldn't we says biovecs directly?

Regards,

-- 
Julien Grall


From wei.liu2 at citrix.com  Mon Aug 10 04:39:07 2015
From: wei.liu2 at citrix.com (Wei Liu)
Date: Mon, 10 Aug 2015 12:39:07 +0100
Subject: [PATCH v3 18/20] net/xen-netback: Make it running on 64KB page
 granularity
In-Reply-To: <55C8759C.3010507@citrix.com>
References: <1438966019-19322-1-git-send-email-julien.grall@citrix.com>
 <1438966019-19322-19-git-send-email-julien.grall@citrix.com>
 <20150808145534.GB14214@zion.uk.xensource.com> <55C8759C.3010507@citrix.com>
Message-ID: <20150810113907.GH8857@zion.uk.xensource.com>

On Mon, Aug 10, 2015 at 10:57:48AM +0100, Julien Grall wrote:
[...]
> 
> >>+		info.page = page;
> >>+		gnttab_foreach_grant_in_range(page, offset, bytes,
> >>+					      xenvif_gop_frag_copy_grant,
> >>+					      &info);
> >
> >Looks like I need to at least wait until the API is settle before giving
> >my ack.
> >
> >>  		size -= bytes;
> >>+		offset = 0;
> >
> >This looks wrong. Should be offset += bytes.
> 
> With the new implementation of the loop, each iteration will be on a
> different page.
> So only the first page has an offset different than zero.
> 
> >
> >>
> >>-		/* Next frame */
> >>-		if (offset == PAGE_SIZE && size) {
> >>+		/* Next page */
> >>+		if (size) {
> >>  			BUG_ON(!PageCompound(page));
> >>  			page++;
> >>-			offset = 0;
> >
> >And this should not be deleted, I think.
> >
> >What is the reason for changing offset calculation? I think there is
> >still compound page when using 64K page.
> 
> The compound pages are still working ... gnttab_foreach_grant_in_range is
> called once per page. So the offset can be reset to 0 every time. No need to
> add code which would make the result less clear.
> 
> We only need to know if the size is not 0 to get the next page.
> 
> The patch may not be clear enough to see it's working so I've copied the
> result loop below:
> 
>         while (size > 0) {
>                 BUG_ON(offset >= PAGE_SIZE);
> 
>                 bytes = PAGE_SIZE - offset;
>                 if (bytes > size)
>                         bytes = size;
> 
>                 info.page = page;
>                 gnttab_foreach_grant_in_range(page, offset, bytes,
>                                              xenvif_gop_frag_copy_grant,
>                                               &info);
>                 size -= bytes;
>                 offset = 0;
> 
>                 /* Next page */
>                 if (size) {
>                         BUG_ON(!PageCompound(page));
>                         page++;
>                 }
>         }
> 

Right. That doesn't mean the original code was wrong or anything. But I
don't want to bikeshed about this.

Please add a comment saying that offset is always 0 starting from second
iteration because the gnttab_foreach_grant_in_range makes sure we handle
one page in one go.

Wei.


> Regards,
> 
> -- 
> Julien Grall


From lee.jones at linaro.org  Mon Aug 10 04:42:24 2015
From: lee.jones at linaro.org (Lee Jones)
Date: Mon, 10 Aug 2015 12:42:24 +0100
Subject: [PATCH] mfd: mt6397: Implement wake handler and suspend/resume
 for mt6397-core.c
In-Reply-To: <1438268846-22451-1-git-send-email-henryc.chen@mediatek.com>
References: <1438268846-22451-1-git-send-email-henryc.chen@mediatek.com>
Message-ID: <20150810114224.GD3249@x1>

No need to mention the filename in the subject line.  You already
mentioned which driver is effected by the change.

> Register mt6393_irq as wake up source to pinctrl by flag "IRQF_NO_SUSPEND".
> Implement .irq_set_wake() function of pmic to keep who is wakeup source,
> and enable irq on .suspend()and restore irq on .resume().
> 
> Signed-off-by: Henry Chen <henryc.chen at mediatek.com>
> ---
>  drivers/mfd/mt6397-core.c       | 49 ++++++++++++++++++++++++++++++++++++++++-
>  include/linux/mfd/mt6397/core.h |  1 +
>  2 files changed, 49 insertions(+), 1 deletion(-)
> 
> diff --git a/drivers/mfd/mt6397-core.c b/drivers/mfd/mt6397-core.c
> index 03929a6..aebdee5 100644
> --- a/drivers/mfd/mt6397-core.c
> +++ b/drivers/mfd/mt6397-core.c

[...]

> @@ -142,6 +161,7 @@ static int mt6397_irq_domain_map(struct irq_domain *d, unsigned int irq,
>  	irq_set_chip_data(irq, mt6397);
>  	irq_set_chip_and_handler(irq, &mt6397_irq_chip, handle_level_irq);
>  	irq_set_nested_thread(irq, 1);
> +

Remainder of the patch looks okay, but this irrelevant change, which
has nothing to do with the remainder of the patch will cause issues if
I attempt to apply it.  Please remove and re-submit.

[...]

-- 
Lee Jones
Linaro STMicroelectronics Landing Team Lead
Linaro.org ? Open source software for ARM SoCs
Follow Linaro: Facebook | Twitter | Blog


From maxime.coquelin at st.com  Mon Aug 10 04:59:13 2015
From: maxime.coquelin at st.com (Maxime Coquelin)
Date: Mon, 10 Aug 2015 13:59:13 +0200
Subject: [GIT PULL] STi DT changes for v4.3, round 1
In-Reply-To: <20150727122459.GB14224@localhost>
References: <55AFD16C.7020006@st.com> <20150727122459.GB14224@localhost>
Message-ID: <55C89211.8010600@st.com>

Hi Olof,

On 07/27/2015 02:24 PM, Olof Johansson wrote:
> On Wed, Jul 22, 2015 at 07:22:52PM +0200, Maxime Coquelin wrote:
>> Hi Olof, Arnd and Kevin,
>>
>> Please consider this first round of STi DT updates for v4.3:
>>
>> The following changes since commit d770e558e21961ad6cfdf0ff7df0eb5d7d4f0754:
>>
>>    Linux 4.2-rc1 (2015-07-05 11:01:52 -0700)
>>
>> are available in the git repository at:
>>
>>    https://git.kernel.org/pub/scm/linux/kernel/git/mcoquelin/sti.git
>> tags/sti-dt-for-v4.3-1
>>
>> for you to fetch changes up to 794445095791aa4f92dfd802f08b541167d63ecc:
>>
>>    ARM: DT: STiH410: Add bdisp dt nodes (2015-07-22 15:05:31 +0200)
> Thanks, merged, however:
>
>> Peter Griffin (11):
>>        ARM: STi: DT: Add STiH407 family tsin0 pinctrl configuration
>>        ARM: STi: DT: Add STiH407 family tsin1 pinctrl configuration
>>        ARM: STi: DT: Add STiH407 family tsin2 pinctrl configuration
>>        ARM: STi: DT: Add STiH407 family tsin3 pinctrl configuration
>>        ARM: STi: DT: Add STiH407 family tsin4 pinctrl configuration
>>        ARM: STi: DT: Add STiH407 family tsin5 pinctrl configuration
>>        ARM: STi: DT: Add STiH407 family tsout0 pinctrl configuration
>>        ARM: STi: DT: Add STiH407 family tsout1 pinctrl configuration
>>        ARM: STi: DT: Add STiH407 family mtsin0 pinctrl configuration
>>        ARM: STi: DT: STiH407: Add cpu-release-addr dt property.
>>        ARM: STi: DT: STiH418: Add cpu-release-addr dt property.
> The patch splitting here is a bit excessive. I think squashing these down
> into one to add STiH407 pinctrl configurations would have been just fine.
>
> Anyway, not a big deal.
>
>
Ok, I will avoid that next time.

Thanks!
Maxime


From ryabinin.a.a at gmail.com  Mon Aug 10 05:00:05 2015
From: ryabinin.a.a at gmail.com (Andrey Ryabinin)
Date: Mon, 10 Aug 2015 15:00:05 +0300
Subject: [PATCH v4 2/7] mm: kasan: introduce generic
 kasan_populate_zero_shadow()
In-Reply-To: <87mvxzptqv.fsf@linux.vnet.ibm.com>
References: <1437756119-12817-1-git-send-email-a.ryabinin@samsung.com>
 <1437756119-12817-3-git-send-email-a.ryabinin@samsung.com>
 <87mvxzptqv.fsf@linux.vnet.ibm.com>
Message-ID: <CAPAsAGwsA138f=oNaqJ4qT6Ow9VyoSqAkwZSa_pCDJVsA-JuAg@mail.gmail.com>

2015-08-10 9:01 GMT+03:00 Aneesh Kumar K.V <aneesh.kumar at linux.vnet.ibm.com>:
> Andrey Ryabinin <a.ryabinin at samsung.com> writes:
>
>> Introduce generic kasan_populate_zero_shadow(start, end).
>> This function maps kasan_zero_page to the [start, end] addresses.
>>
>> In follow on patches it will be used for ARMv8 (and maybe other
>> architectures) and will replace x86_64 specific populate_zero_shadow().
>>
>> Signed-off-by: Andrey Ryabinin <a.ryabinin at samsung.com>
>
> This assume that we can have shared pgtable_t in generic code ? Is that
> true for generic code ? Even if it is we may want to allow some arch to
> override this ? On ppc64, we store the hardware hash page table slot
> number in pte_t, Hence we won't be able to share pgtable_t.
>

So, ppc64 could define some config which will disable compilation of
mm/kasan/kasan_init.c.
However, it might be a bad idea to use such never defined config symbol now.
So I think this could be done later, in "KASAN for powerpc" series.

>
>
>> ---
>>  arch/x86/mm/kasan_init_64.c |  14 ----
>>  include/linux/kasan.h       |   8 +++
>>  mm/kasan/Makefile           |   2 +-
>>  mm/kasan/kasan_init.c       | 151 ++++++++++++++++++++++++++++++++++++++++++++
>>  4 files changed, 160 insertions(+), 15 deletions(-)
>>  create mode 100644 mm/kasan/kasan_init.c
>>
>> diff --git a/arch/x86/mm/kasan_init_64.c b/arch/x86/mm/kasan_init_64.c
>> index e1840f3..812086c 100644
>> --- a/arch/x86/mm/kasan_init_64.c
>> +++ b/arch/x86/mm/kasan_init_64.c
>> @@ -12,20 +12,6 @@
>>  extern pgd_t early_level4_pgt[PTRS_PER_PGD];
>>  extern struct range pfn_mapped[E820_X_MAX];
>>
>> -static pud_t kasan_zero_pud[PTRS_PER_PUD] __page_aligned_bss;
>> -static pmd_t kasan_zero_pmd[PTRS_PER_PMD] __page_aligned_bss;
>> -static pte_t kasan_zero_pte[PTRS_PER_PTE] __page_aligned_bss;
>> -
>> -/*
>
> -aneesh
>


From julien.grall at citrix.com  Mon Aug 10 05:00:40 2015
From: julien.grall at citrix.com (Julien Grall)
Date: Mon, 10 Aug 2015 13:00:40 +0100
Subject: [PATCH v3 18/20] net/xen-netback: Make it running on 64KB page
 granularity
In-Reply-To: <20150810113907.GH8857@zion.uk.xensource.com>
References: <1438966019-19322-1-git-send-email-julien.grall@citrix.com>
 <1438966019-19322-19-git-send-email-julien.grall@citrix.com>
 <20150808145534.GB14214@zion.uk.xensource.com> <55C8759C.3010507@citrix.com>
 <20150810113907.GH8857@zion.uk.xensource.com>
Message-ID: <55C89268.2030102@citrix.com>

On 10/08/15 12:39, Wei Liu wrote:
> On Mon, Aug 10, 2015 at 10:57:48AM +0100, Julien Grall wrote:
>>         while (size > 0) {
>>                 BUG_ON(offset >= PAGE_SIZE);
>>
>>                 bytes = PAGE_SIZE - offset;
>>                 if (bytes > size)
>>                         bytes = size;
>>
>>                 info.page = page;
>>                 gnttab_foreach_grant_in_range(page, offset, bytes,
>>                                              xenvif_gop_frag_copy_grant,
>>                                               &info);
>>                 size -= bytes;
>>                 offset = 0;
>>
>>                 /* Next page */
>>                 if (size) {
>>                         BUG_ON(!PageCompound(page));
>>                         page++;
>>                 }
>>         }
>>
> 
> Right. That doesn't mean the original code was wrong or anything. But I
> don't want to bikeshed about this.

I never said the original code was wrong... The original code was
allowing the possibility to copy less data than the length contained in
page.

In the new version, it has been pushed with the callback
xenvif_gop_frag_copy_grant.

> Please add a comment saying that offset is always 0 starting from second
> iteration because the gnttab_foreach_grant_in_range makes sure we handle
> one page in one go.

I think this is superfluous. To be honest, the comment should have been
on the original version and not in the new one. The construction of the
loop was far from obvious that we copied less data.

In this new version, the reason is not because of
gnttab_foreach_grant_in_range is always a page but how the loop has been
constructed.

If you look how bytes has been defined, it will always contain

min(PAGE_SIZE - offset, size)

So for the first page, this will be PAGE_SIZE - offset. A the end of the
loop we reset the offset 0, indeed we copy all the data of the first
page. For the second page and onwards this will always be PAGE_SIZE
except for the last one where we took size.


Regards,

-- 
Julien Grall


From stefano.stabellini at eu.citrix.com  Mon Aug 10 05:03:13 2015
From: stefano.stabellini at eu.citrix.com (Stefano Stabellini)
Date: Mon, 10 Aug 2015 13:03:13 +0100
Subject: [PATCH v3 19/20] xen/privcmd: Add support for Linux 64KB page
 granularity
In-Reply-To: <1438966019-19322-20-git-send-email-julien.grall@citrix.com>
References: <1438966019-19322-1-git-send-email-julien.grall@citrix.com>
 <1438966019-19322-20-git-send-email-julien.grall@citrix.com>
Message-ID: <alpine.DEB.2.02.1508101230260.11337@kaball.uk.xensource.com>

On Fri, 7 Aug 2015, Julien Grall wrote:
> The hypercall interface (as well as the toolstack) is always using 4KB
> page granularity. When the toolstack is asking for mapping a series of
> guest PFN in a batch, it expects to have the page map contiguously in
> its virtual memory.
> 
> When Linux is using 64KB page granularity, the privcmd driver will have
> to map multiple Xen PFN in a single Linux page.
> 
> Note that this solution works on page granularity which is a multiple of
> 4KB.
> 
> Signed-off-by: Julien Grall <julien.grall at citrix.com>
> 
> ---
> Cc: Konrad Rzeszutek Wilk <konrad.wilk at oracle.com>
> Cc: Boris Ostrovsky <boris.ostrovsky at oracle.com>
> Cc: David Vrabel <david.vrabel at citrix.com>
> 
>     I kept the hypercall arguments in remap_data to avoid allocating them on
>     the stack every time that remap_pte_fn is called.
>     I will keep like that unless someone is strongly disagree.
> 
>     Changes in v3:
>         - The function to split a Linux page in mutiple Xen page has
>         been moved internally. It was the only use (not used anymore in
>         the balloon) and it's not quite clear what should be the common
>         interface. Differ the question until someone need to use it.
>         - s/nr_pfn/numgfns/ to make clear that we are dealing with GFN
>         - Use DIV_ROUND_UP rather round_up and fix the usage in
>         xen_xlate_unmap_gfn_range
> 
>     Changes in v2:
>         - Use xen_apply_to_page
> ---
>  drivers/xen/privcmd.c   |   8 ++--
>  drivers/xen/xlate_mmu.c | 124 ++++++++++++++++++++++++++++++++----------------
>  2 files changed, 89 insertions(+), 43 deletions(-)
> 
> diff --git a/drivers/xen/privcmd.c b/drivers/xen/privcmd.c
> index c6deb87..c8798ee 100644
> --- a/drivers/xen/privcmd.c
> +++ b/drivers/xen/privcmd.c
> @@ -446,7 +446,7 @@ static long privcmd_ioctl_mmap_batch(void __user *udata, int version)
>  		return -EINVAL;
>  	}
>  
> -	nr_pages = m.num;
> +	nr_pages = DIV_ROUND_UP(m.num, XEN_PFN_PER_PAGE);
>  	if ((m.num <= 0) || (nr_pages > (LONG_MAX >> PAGE_SHIFT)))
>  		return -EINVAL;
>  
> @@ -494,7 +494,7 @@ static long privcmd_ioctl_mmap_batch(void __user *udata, int version)
>  			goto out_unlock;
>  		}
>  		if (xen_feature(XENFEAT_auto_translated_physmap)) {
> -			ret = alloc_empty_pages(vma, m.num);
> +			ret = alloc_empty_pages(vma, nr_pages);
>  			if (ret < 0)
>  				goto out_unlock;
>  		} else
> @@ -518,6 +518,7 @@ static long privcmd_ioctl_mmap_batch(void __user *udata, int version)
>  	state.global_error  = 0;
>  	state.version       = version;
>  
> +	BUILD_BUG_ON(((PAGE_SIZE / sizeof(xen_pfn_t)) % XEN_PFN_PER_PAGE) != 0);
>  	/* mmap_batch_fn guarantees ret == 0 */
>  	BUG_ON(traverse_pages_block(m.num, sizeof(xen_pfn_t),
>  				    &pagelist, mmap_batch_fn, &state));
> @@ -582,12 +583,13 @@ static void privcmd_close(struct vm_area_struct *vma)
>  {
>  	struct page **pages = vma->vm_private_data;
>  	int numpgs = (vma->vm_end - vma->vm_start) >> PAGE_SHIFT;
> +	int numgfns = (vma->vm_end - vma->vm_start) >> XEN_PAGE_SHIFT;
>  	int rc;
>  
>  	if (!xen_feature(XENFEAT_auto_translated_physmap) || !numpgs || !pages)
>  		return;
>  
> -	rc = xen_unmap_domain_gfn_range(vma, numpgs, pages);
> +	rc = xen_unmap_domain_gfn_range(vma, numgfns, pages);
>  	if (rc == 0)
>  		free_xenballooned_pages(numpgs, pages);
>  	else
> diff --git a/drivers/xen/xlate_mmu.c b/drivers/xen/xlate_mmu.c
> index cff2387..a1d3904 100644
> --- a/drivers/xen/xlate_mmu.c
> +++ b/drivers/xen/xlate_mmu.c
> @@ -38,31 +38,28 @@
>  #include <xen/interface/xen.h>
>  #include <xen/interface/memory.h>
>  
> -/* map fgfn of domid to lpfn in the current domain */
> -static int map_foreign_page(unsigned long lpfn, unsigned long fgfn,
> -			    unsigned int domid)
> -{
> -	int rc;
> -	struct xen_add_to_physmap_range xatp = {
> -		.domid = DOMID_SELF,
> -		.foreign_domid = domid,
> -		.size = 1,
> -		.space = XENMAPSPACE_gmfn_foreign,
> -	};
> -	xen_ulong_t idx = fgfn;
> -	xen_pfn_t gpfn = lpfn;
> -	int err = 0;
> +typedef void (*xen_gfn_fn_t)(unsigned long gfn, void *data);
>  
> -	set_xen_guest_handle(xatp.idxs, &idx);
> -	set_xen_guest_handle(xatp.gpfns, &gpfn);
> -	set_xen_guest_handle(xatp.errs, &err);
> +/* Break down the pages in 4KB chunk and call fn for each gfn */
> +static void xen_for_each_gfn(struct page **pages, unsigned nr_gfn,
> +			     xen_gfn_fn_t fn, void *data)
> +{
> +	unsigned long xen_pfn = 0;
> +	struct page *page;
> +	int i;
>  
> -	rc = HYPERVISOR_memory_op(XENMEM_add_to_physmap_range, &xatp);
> -	return rc < 0 ? rc : err;
> +	for (i = 0; i < nr_gfn; i++) {
> +		if ((i % XEN_PFN_PER_PAGE) == 0) {
> +			page = pages[i / XEN_PFN_PER_PAGE];

If this function is going to be called very frequently you might want to
consider using a shift instead.

    page = pages[i >> 4];

With an appropriate macro of course.


> +			xen_pfn = xen_page_to_pfn(page);
> +		}
> +		fn(pfn_to_gfn(xen_pfn++), data);

What is the purpose of incrementing xen_pfn here?


> +	}
>  }
>  
>  struct remap_data {
>  	xen_pfn_t *fgfn; /* foreign domain's gfn */
> +	int nr_fgfn; /* Number of foreign gfn left to map */
>  	pgprot_t prot;
>  	domid_t  domid;
>  	struct vm_area_struct *vma;
> @@ -71,24 +68,71 @@ struct remap_data {
>  	struct xen_remap_gfn_info *info;
>  	int *err_ptr;
>  	int mapped;
> +
> +	/* Hypercall parameters */
> +	int h_errs[XEN_PFN_PER_PAGE];
> +	xen_ulong_t h_idxs[XEN_PFN_PER_PAGE];
> +	xen_pfn_t h_gpfns[XEN_PFN_PER_PAGE];
> +
> +	int h_iter;	/* Iterator */
>  };
>  
> +static void setup_hparams(unsigned long gfn, void *data)
> +{
> +	struct remap_data *info = data;
> +
> +	info->h_idxs[info->h_iter] = *info->fgfn;
> +	info->h_gpfns[info->h_iter] = gfn;
> +	info->h_errs[info->h_iter] = 0;
> +
> +	info->h_iter++;
> +	info->fgfn++;
> +}
> +
>  static int remap_pte_fn(pte_t *ptep, pgtable_t token, unsigned long addr,
>  			void *data)
>  {
>  	struct remap_data *info = data;
>  	struct page *page = info->pages[info->index++];
> -	unsigned long pfn = page_to_pfn(page);
> -	pte_t pte = pte_mkspecial(pfn_pte(pfn, info->prot));
> -	int rc;
> +	pte_t pte = pte_mkspecial(pfn_pte(page_to_pfn(page), info->prot));
> +	int rc, nr_gfn;
> +	uint32_t i;
> +	struct xen_add_to_physmap_range xatp = {
> +		.domid = DOMID_SELF,
> +		.foreign_domid = info->domid,
> +		.space = XENMAPSPACE_gmfn_foreign,
> +	};
>  
> -	rc = map_foreign_page(pfn, *info->fgfn, info->domid);
> -	*info->err_ptr++ = rc;
> -	if (!rc) {
> -		set_pte_at(info->vma->vm_mm, addr, ptep, pte);
> -		info->mapped++;
> +	nr_gfn = min_t(typeof(info->nr_fgfn), XEN_PFN_PER_PAGE, info->nr_fgfn);
> +	info->nr_fgfn -= nr_gfn;
> +
> +	info->h_iter = 0;
> +	xen_for_each_gfn(&page, nr_gfn, setup_hparams, info);
> +	BUG_ON(info->h_iter != nr_gfn);
> +
> +	set_xen_guest_handle(xatp.idxs, info->h_idxs);
> +	set_xen_guest_handle(xatp.gpfns, info->h_gpfns);
> +	set_xen_guest_handle(xatp.errs, info->h_errs);
> +	xatp.size = nr_gfn;
> +
> +	rc = HYPERVISOR_memory_op(XENMEM_add_to_physmap_range, &xatp);
> +
> +	/* info->err_ptr expect to have one error status per Xen PFN */
> +	for (i = 0; i < nr_gfn; i++) {
> +		int err = (rc < 0) ? rc : info->h_errs[i];
> +
> +		*(info->err_ptr++) = err;
> +		if (!err)
> +			info->mapped++;
>  	}
> -	info->fgfn++;
> +
> +	/*
> +	 * Note: The hypercall will return 0 in most of the case if even if
> +	 * all the fgmfn are not mapped. We still have to update the pte
> +	 * as the userspace may decide to continue.
> +	 */
> +	if (!rc)
> +		set_pte_at(info->vma->vm_mm, addr, ptep, pte);
>  
>  	return 0;
>  }
> @@ -102,13 +146,14 @@ int xen_xlate_remap_gfn_array(struct vm_area_struct *vma,
>  {
>  	int err;
>  	struct remap_data data;
> -	unsigned long range = nr << PAGE_SHIFT;
> +	unsigned long range = DIV_ROUND_UP(nr, XEN_PFN_PER_PAGE) << PAGE_SHIFT;
>  
>  	/* Kept here for the purpose of making sure code doesn't break
>  	   x86 PVOPS */
>  	BUG_ON(!((vma->vm_flags & (VM_PFNMAP | VM_IO)) == (VM_PFNMAP | VM_IO)));
>  
>  	data.fgfn = gfn;
> +	data.nr_fgfn = nr;
>  	data.prot  = prot;
>  	data.domid = domid;
>  	data.vma   = vma;
> @@ -123,21 +168,20 @@ int xen_xlate_remap_gfn_array(struct vm_area_struct *vma,
>  }
>  EXPORT_SYMBOL_GPL(xen_xlate_remap_gfn_array);
>  
> -int xen_xlate_unmap_gfn_range(struct vm_area_struct *vma,
> -			      int nr, struct page **pages)
> +static void unmap_gfn(unsigned long gfn, void *data)
>  {
> -	int i;
> +	struct xen_remove_from_physmap xrp;
>  
> -	for (i = 0; i < nr; i++) {
> -		struct xen_remove_from_physmap xrp;
> -		unsigned long pfn;
> +	xrp.domid = DOMID_SELF;
> +	xrp.gpfn = gfn;
> +	(void)HYPERVISOR_memory_op(XENMEM_remove_from_physmap, &xrp);
> +}
>  
> -		pfn = page_to_pfn(pages[i]);
> +int xen_xlate_unmap_gfn_range(struct vm_area_struct *vma,
> +			      int nr, struct page **pages)
> +{
> +	xen_for_each_gfn(pages, nr, unmap_gfn, NULL);
>  
> -		xrp.domid = DOMID_SELF;
> -		xrp.gpfn = pfn;
> -		(void)HYPERVISOR_memory_op(XENMEM_remove_from_physmap, &xrp);
> -	}
>  	return 0;
>  }
>  EXPORT_SYMBOL_GPL(xen_xlate_unmap_gfn_range);
> -- 
> 2.1.4
> 


From david.vrabel at citrix.com  Mon Aug 10 05:14:32 2015
From: david.vrabel at citrix.com (David Vrabel)
Date: Mon, 10 Aug 2015 13:14:32 +0100
Subject: [Xen-devel] [PATCH v3 19/20] xen/privcmd: Add support for Linux
 64KB page granularity
In-Reply-To: <alpine.DEB.2.02.1508101230260.11337@kaball.uk.xensource.com>
References: <1438966019-19322-1-git-send-email-julien.grall@citrix.com>
 <1438966019-19322-20-git-send-email-julien.grall@citrix.com>
 <alpine.DEB.2.02.1508101230260.11337@kaball.uk.xensource.com>
Message-ID: <55C895A8.9020004@citrix.com>

On 10/08/15 13:03, Stefano Stabellini wrote:
> On Fri, 7 Aug 2015, Julien Grall wrote:
>> -	rc = HYPERVISOR_memory_op(XENMEM_add_to_physmap_range, &xatp);
>> -	return rc < 0 ? rc : err;
>> +	for (i = 0; i < nr_gfn; i++) {
>> +		if ((i % XEN_PFN_PER_PAGE) == 0) {
>> +			page = pages[i / XEN_PFN_PER_PAGE];
> 
> If this function is going to be called very frequently you might want to
> consider using a shift instead.
> 
>     page = pages[i >> 4];
> 
> With an appropriate macro of course.

This change isn't necessary.  Compilers already turn divides into
suitable shifts.

David


From thierry.reding at gmail.com  Mon Aug 10 05:21:36 2015
From: thierry.reding at gmail.com (Thierry Reding)
Date: Mon, 10 Aug 2015 14:21:36 +0200
Subject: [PATCH 00/12] dw-hdmi development
In-Reply-To: <20150808160251.GM7557@n2100.arm.linux.org.uk>
References: <20150808160251.GM7557@n2100.arm.linux.org.uk>
Message-ID: <20150810122135.GZ1262@ulmo.nvidia.com>

On Sat, Aug 08, 2015 at 05:02:51PM +0100, Russell King - ARM Linux wrote:
> This sub-series is a mixture of development:
> 
> * Removing the incorrect pixel repetition configuration code
> * Preventing pixel-doubled modes from being used
> * Adding interlaced video support
> * Implementing the sink_is_hdmi/sink_has_audio flags I suggested a few
>   months ago
> * Only enabling audio support if the sink indicates it has audio
> * Avoiding double-enabling the HDMI interface
> * Fixing the mis-leading name of "dw_hdmi_phy_enable_power"
> * Adding connector mode forcing (important if your monitor bounces
>   RXSENSE and HPD signals while in low-power mode.)
> * Improving the HDMI enable/disabling on sink status
> 
> For review (and testing if people feel like it).  Acks/tested-bys etc
> welcome.  It applies on top of my drm-dwhdmi-devel branch, which is
> waiting for David Airlie to pull (see pull request on dri-devel, 15th
> July.)

Hi Russell,

I have in the past merged patches for the bridge subdirectory via the
drm/panel tree, though lately much of the dw-hdmi patches have gone in
via Philipp or you directly. This seems to have worked fine so far, but
this time around I carry a patch to clean up Kconfig and Makefile a
little and bring more consistency to the subdirectory and I think it's
going to conflict with your series here (and potentially any ongoing
work you have).

Would you be open to me picking up these patches into the drm/panel
tree? It feeds into linux-next, so the code would get some exposure
before Dave's return.

Thierry
-------------- next part --------------
A non-text attachment was scrubbed...
Name: signature.asc
Type: application/pgp-signature
Size: 819 bytes
Desc: not available
URL: <http://lists.infradead.org/pipermail/linux-arm-kernel/attachments/20150810/867cb263/attachment.sig>

From tiwai at suse.de  Mon Aug 10 05:23:07 2015
From: tiwai at suse.de (Takashi Iwai)
Date: Mon, 10 Aug 2015 14:23:07 +0200
Subject: [PATCH 1/9] drm: bridge/dw_hdmi-ahb-audio: add audio driver
In-Reply-To: <20150810103921.GR7557@n2100.arm.linux.org.uk>
References: <20150808160936.GN7557@n2100.arm.linux.org.uk>
 <E1ZO6hC-0003M5-EU@rmk-PC.arm.linux.org.uk>
 <s5hk2t35ui4.wl-tiwai@suse.de>
 <20150810103921.GR7557@n2100.arm.linux.org.uk>
Message-ID: <s5hegjb5o44.wl-tiwai@suse.de>

On Mon, 10 Aug 2015 12:39:21 +0200,
Russell King - ARM Linux wrote:
> 
> On Mon, Aug 10, 2015 at 12:05:07PM +0200, Takashi Iwai wrote:
> > On Sat, 08 Aug 2015 18:10:06 +0200,
> > Russell King wrote:
> > > +static irqreturn_t snd_dw_hdmi_irq(int irq, void *data)
> > > +{
> > > +	struct snd_dw_hdmi *dw = data;
> > > +	struct snd_pcm_substream *substream;
> > > +	unsigned stat;
> > > +
> > > +	stat = readb_relaxed(dw->data.base + HDMI_IH_AHBDMAAUD_STAT0);
> > > +	if (!stat)
> > > +		return IRQ_NONE;
> > > +
> > > +	writeb_relaxed(stat, dw->data.base + HDMI_IH_AHBDMAAUD_STAT0);
> > > +
> > > +	substream = dw->substream;
> > > +	if (stat & HDMI_IH_AHBDMAAUD_STAT0_DONE && substream) {
> > > +		snd_pcm_period_elapsed(substream);
> > > +		if (dw->substream)
> > > +			dw_hdmi_start_dma(dw);
> > > +	}
> > 
> > Don't we need locking?
> 
> Possibly.
> 
> > In theory, the trigger can be issued while the irq is being handled.
> 
> Well, we can't have a lock around the whole of the above, because that
> results in deadlock (as snd_pcm_period_elapsed() can end up calling into
> the trigger method.)

Yes, and a usual workaround is to unlock temporarily at calling
snd_pcm_period_elapsed(), then relock or call it at the end of 
handler.

> I'm not happy to throw a spinlock around this
> because of the in-built format conversion (something else I'm really not
> happy about - which has to exist here because alsalib is soo painful
> to add custom sample reformatting to - such modules have to be built
> as part of alsalib itself rather than an add-on module.)

I admit that alsa-lib code is very horrible to follow -- but I guess
the change you'd need for iec958 plugin would be fairly small.  We can
add a config option and let iec958 behaving slightly differently
depending on it.

Meanwhile, having an in-kernel workaround makes it much easier to
deploy, so I think it's OK to have this in driver for now.

> > > +static int dw_hdmi_trigger(struct snd_pcm_substream *substream, int cmd)
> > > +{
> > > +	struct snd_dw_hdmi *dw = substream->private_data;
> > > +	int ret = 0;
> > > +
> > > +	switch (cmd) {
> > > +	case SNDRV_PCM_TRIGGER_START:
> > > +		dw->buf_offset = 0;
> > > +		dw->substream = substream;
> > > +		dw_hdmi_start_dma(dw);
> > > +		dw_hdmi_audio_enable(dw->data.hdmi);
> > > +		substream->runtime->delay = substream->runtime->period_size;
> > > +		break;
> > > +
> > > +	case SNDRV_PCM_TRIGGER_STOP:
> > > +		dw_hdmi_stop_dma(dw);
> > > +		dw_hdmi_audio_disable(dw->data.hdmi);
> > > +		break;
> > > +
> > > +	default:
> > > +		ret = -EINVAL;
> > > +		break;
> > 
> > SNDRV_PCM_TRIGGER_SUSPEND may be passed at suspend, too.
> 
> I think rather than adding code which would be difficult for me to test,
> I'd instead remove the suspend/resume callbacks, or at least disable them
> until someone can test that feature, or is willing to implement it.

That's fine.

> > > +static snd_pcm_uframes_t dw_hdmi_pointer(struct snd_pcm_substream *substream)
> > > +{
> > > +	struct snd_pcm_runtime *runtime = substream->runtime;
> > > +	struct snd_dw_hdmi *dw = substream->private_data;
> > > +
> > > +	return bytes_to_frames(runtime, dw->buf_offset);
> > 
> > So, this returns the offset that has been reformatted.  Does the
> > hardware support any better position reporting?  We may give the delay
> > from the driver if possible.
> 
> Basically, no.  Reading a 32-bit DMA position as separate bytes while
> DMA is active is racy.
> 
> This is the best we can do, and the way we report the position has been
> arrived at after what's getting on for two years of testing with
> pulseaudio, vlc direct access & spdif pass-through, aplay, etc:
> 
> Author: Russell King <rmk+kernel at arm.linux.org.uk>
> Date:   Thu Nov 7 16:01:45 2013 +0000
> 
>     drm: bridge/dw_hdmi-ahb-audio: add audio driver

OK, then this is a driver with the low update granularity.  Hopefully
we'll get some good API to indicate that in near future, as we've been
discussing about it for a while.


thanks,

Takashi


From HenryC.Chen at mediatek.com  Mon Aug 10 05:23:21 2015
From: HenryC.Chen at mediatek.com (Henry Chen)
Date: Mon, 10 Aug 2015 20:23:21 +0800
Subject: [PATCH] mfd: mt6397: Implement wake handler and suspend/resume
 for mt6397-core.c
In-Reply-To: <20150810114224.GD3249@x1>
References: <1438268846-22451-1-git-send-email-henryc.chen@mediatek.com>
 <20150810114224.GD3249@x1>
Message-ID: <1439209401.32674.16.camel@mtksdaap41>

Hi Jones,

On Mon, 2015-08-10 at 12:42 +0100, Lee Jones wrote:
> No need to mention the filename in the subject line.  You already
> mentioned which driver is effected by the change.
Ok, it will be changed.

> 
> > Register mt6393_irq as wake up source to pinctrl by flag "IRQF_NO_SUSPEND".
> > Implement .irq_set_wake() function of pmic to keep who is wakeup source,
> > and enable irq on .suspend()and restore irq on .resume().
> > 
> > Signed-off-by: Henry Chen <henryc.chen at mediatek.com>
> > ---
> >  drivers/mfd/mt6397-core.c       | 49 ++++++++++++++++++++++++++++++++++++++++-
> >  include/linux/mfd/mt6397/core.h |  1 +
> >  2 files changed, 49 insertions(+), 1 deletion(-)
> > 
> > diff --git a/drivers/mfd/mt6397-core.c b/drivers/mfd/mt6397-core.c
> > index 03929a6..aebdee5 100644
> > --- a/drivers/mfd/mt6397-core.c
> > +++ b/drivers/mfd/mt6397-core.c
> 
> [...]
> 
> > @@ -142,6 +161,7 @@ static int mt6397_irq_domain_map(struct irq_domain *d, unsigned int irq,
> >  	irq_set_chip_data(irq, mt6397);
> >  	irq_set_chip_and_handler(irq, &mt6397_irq_chip, handle_level_irq);
> >  	irq_set_nested_thread(irq, 1);
> > +
> 
> Remainder of the patch looks okay, but this irrelevant change, which
> has nothing to do with the remainder of the patch will cause issues if
> I attempt to apply it.  Please remove and re-submit.
> 
Sorry, I will remove it, thanks.
Henry

> [...]
> 




From david.vrabel at citrix.com  Mon Aug 10 05:41:13 2015
From: david.vrabel at citrix.com (David Vrabel)
Date: Mon, 10 Aug 2015 13:41:13 +0100
Subject: [Xen-devel] [PATCH v3 09/20] xen/biomerge: Don't allow biovec
 to be merge when Linux is not using 4KB page
In-Reply-To: <55C88BD8.7040807@citrix.com>
References: <1438966019-19322-1-git-send-email-julien.grall@citrix.com>
 <1438966019-19322-10-git-send-email-julien.grall@citrix.com>
 <alpine.DEB.2.02.1508101149070.11337@kaball.uk.xensource.com>
 <55C889E4.8050307@citrix.com>
 <alpine.DEB.2.02.1508101224220.11337@kaball.uk.xensource.com>
 <55C88BD8.7040807@citrix.com>
Message-ID: <55C89BE9.4040806@citrix.com>

On 10/08/15 12:32, Julien Grall wrote:
> On 10/08/15 12:25, Stefano Stabellini wrote:
>> yes and page/pages:
>>
>> xen/biomerge: Don't allow biovec's to be merged when Linux is not using 4KB pages
> 
> Why the ' in biovec's ? Shouldn't we says biovecs directly?

Pluralizing named C structures with apostrophes is valid.  It makes it
clear we're talking about "struct biovec" and not "struct biovecs" objects.

You could also consider "biovec's" to be a contraction for "biovec
objects" so the apostrophe is "correct".

David


From linus.walleij at linaro.org  Mon Aug 10 05:43:13 2015
From: linus.walleij at linaro.org (Linus Walleij)
Date: Mon, 10 Aug 2015 14:43:13 +0200
Subject: [PATCH] pinctrl: mediatek: Implement pictrl irq wake handler
In-Reply-To: <1438162601-448-1-git-send-email-maoguang.meng@mediatek.com>
References: <1438162601-448-1-git-send-email-maoguang.meng@mediatek.com>
Message-ID: <CACRpkdZ1RjjSh5J=K724CpbXDXwdHJSdXOTLS8fSOO-34zn=9A@mail.gmail.com>

On Wed, Jul 29, 2015 at 11:36 AM,  <maoguang.meng at mediatek.com> wrote:

> From: Maoguang Meng <maoguang.meng at mediatek.com>
>
> This patch implement irq_set_wake for suspend resume.
>
> Signed-off-by: Maoguang Meng <maoguang.meng at mediatek.com>

Hongzhou/Yingjoe: are you OK with this patch? Can I have your ACKs?

Yours,
Linus Walleij


From alexander.stein at systec-electronic.com  Mon Aug 10 05:45:06 2015
From: alexander.stein at systec-electronic.com (Alexander Stein)
Date: Mon, 10 Aug 2015 14:45:06 +0200
Subject: [RFC] i.MX25/35/SDHCI: switch off DMA usage
In-Reply-To: <20150422073258.GB25437@shlinux1.ap.freescale.net>
References: <201503271152.04348.jbe@pengutronix.de>
 <201504141142.00237.jbe@pengutronix.de>
 <20150422073258.GB25437@shlinux1.ap.freescale.net>
Message-ID: <4555081.2nUx7FPr1R@ws-stein>

Hello,

On Wednesday 22 April 2015 15:33:00, Dong Aisheng wrote:
> > On Friday 27 March 2015 12:44:03 Dong Aisheng wrote:
> > > On Fri, Mar 27, 2015 at 11:52:04AM +0100, Juergen Borleis wrote:
> > > > DMA and the required overhead on very small data blocks seems an
> > > > expensive operation. Due to erratum ENGCM07207 for i.MX25 and i.MX35 SoCs
> > > > the support for multiblock transfers is disabled which results into a
> > > > huge amount of single 512 byte sector transfers and interrupts. This
> > > > slows down the transmission speed to below 500 kiB/s (even at 50 MHz SD
> > > > card clock). Using PIO instead of DMA to avoid ENGCM07207 happens and
> > > > re-enabling multiblock transfers again improve the transmission
> > > > capability up to about 2.5 MiB/s.
> > > >
> > > > I'm still not sure if ENGCM07207 is related to DMA only and can not
> > > > happen when PIO is used instead. Someone out there with experience
> > > > regarding this topic?
> > >
> > > The errata does not state it's related to DMA only.
> > > http://cache.freescale.com/files/dsp/doc/errata/IMX35CE.pdf
> > > I could double check with our IC guys to confirm it.
> > 
> > Gentle ping.
> > 
> 
> Hi Juergen,
> 
> Got the info from our IC guy.
> PIO mode is not related to AHB access, so AHB hang is not exist.
> But, he supposes the incorrect state machine of IP after sending CMD12 should
> also exist on PIO mode. We may still needs reset the controller after sending
> CMD12.(Reset before sending CMD12 should also work)
> 
> BTW the errata already indicates a workaround for AHB hang:
> "To abort data transfers on the AHB, software can reset the eSDHC by
> writing 1 to SYSCTL[24] (RSTA)."
> 
> So the issue could be avoided by reset controller.
> 
> And the current SDHCI driver already does reset if any error(cmd or data)
> happens, and current MMC core seems only sending stop command when meets error.
> (not sending stop during normal transfer).
> So it looks to me the issue may already be workarounded and can not
> be reproduced.
> 
> I'm not sure if anyone really meets the issue.
> 
> By googling the original post of this patch, it seems the patch
> owner also did not reproduce this issue.
> See:
> http://lists.infradead.org/pipermail/linux-arm-kernel/2010-October/029818.html
> 
> I would suggest someone who has the MX35/MX25 boards, to run the test again by
> manually triggering a data error.(e.g: shorting data line to ground during
> transfer). Then to see if the controller can still work well.
> 
> If can not reproduce, then we can remove this errata and back to DMA mode.

I did some timing tests on my imx35 based board by removing the SDHCI_QUIRK_NO_MULTIBLOCK. Patches are inlined below.

Current v4.2-rc6:
# time dd if=/dev/mmcblk0 of=/dev/null bs=1M count=100
100+0 records in
100+0 records out
real    3m 8.40s
user    0m 0.02s
sys     0m 3.67s

Current v4.2-rc6 + patch1:
# time dd if=/dev/mmcblk0 of=/dev/null bs=1M count=100
100+0 records in
100+0 records out
real    0m 5.90s
user    0m 0.02s
sys     0m 1.43s

So apparently using multiblock transfers increases the performance considerably. I tried your suggestion to short a data line (DAT0 in my case) to GND. The transfers fail with data CRC errors. So far as expected. But after releasing short DAT0 to GND the data CRC errors remain. I can only get the transfers back to work when unplugging/pluggin the card or reboot the system. But this behavior is also the case when using SDHCI_QUIRK_NO_MULTIBLOCK, aka. the current state. I have no explanation for that. Sample error message is:
> [  297.671266] mmcblk0: error -84 transferring data, sector 506, nr 6, cmd response 0x900, card status 0x0
So card state 0x900 is fine. I also get the same when doing
# cat /sys/kernel/debug/mmc0/mmc0\:1234/status
00000900

So I cannot say anything if using multiblock transfers has any negative effect. Up to now it has the same behavior regarding data crc errors as running without multiblock.

While at it I was curious why ADMA was disabled at all. So I did another test _with_ multiblock transfer and ADMA.

Current v4.2-rc6 + patch2:
# time dd if=/dev/mmcblk0 of=/dev/null bs=1M count=100
100+0 records in
100+0 records out
real    0m 5.28s
user    0m 0.00s
sys     0m 1.26s

Everything seems ok so far. Why has ADMA been disabled at all? Checking git history this quirk was added with the initial commit 95f25efe0ce22e28d61722d655d2ef582f5f7520 (mmc: sdhci-pltfm: add -pltfm driver for imx35/51).

Any comments regarding multiblock and (not so) broken ADMA?

Best regard,
Alexander

patch1:
8<----------------------------------------------------------------------------------
diff --git a/drivers/mmc/host/sdhci-esdhc-imx.c b/drivers/mmc/host/sdhci-esdhc-imx.c
index c6b9f64..bc82abe 100644
--- a/drivers/mmc/host/sdhci-esdhc-imx.c
+++ b/drivers/mmc/host/sdhci-esdhc-imx.c
@@ -1065,8 +1065,7 @@ static int sdhci_esdhc_imx_probe(struct platform_device *pdev)
 
        if (imx_data->socdata->flags & ESDHC_FLAG_ENGCM07207)
                /* Fix errata ENGcm07207 present on i.MX25 and i.MX35 */
-               host->quirks |= SDHCI_QUIRK_NO_MULTIBLOCK
-                       | SDHCI_QUIRK_BROKEN_ADMA;
+               host->quirks |= SDHCI_QUIRK_BROKEN_ADMA;
 
        /*
         * The imx6q ROM code will change the default watermark level setting
8<----------------------------------------------------------------------------------

patch2:
8<----------------------------------------------------------------------------------
diff --git a/drivers/mmc/host/sdhci-esdhc-imx.c b/drivers/mmc/host/sdhci-esdhc-imx.c
index c6b9f64..74d552c 100644
--- a/drivers/mmc/host/sdhci-esdhc-imx.c
+++ b/drivers/mmc/host/sdhci-esdhc-imx.c
@@ -130,7 +130,7 @@ static struct esdhc_soc_data esdhc_imx25_data = {
 };
 
 static struct esdhc_soc_data esdhc_imx35_data = {
-       .flags = ESDHC_FLAG_ENGCM07207,
+       .flags = 0,
 };
 
 static struct esdhc_soc_data esdhc_imx51_data = {
8<----------------------------------------------------------------------------------
-- 
Dipl.-Inf. Alexander Stein
SYS TEC electronic GmbH
alexander.stein at systec-electronic.com

Legal and Commercial Address:
Am Windrad 2
08468 Heinsdorfergrund
Germany

Office: +49 (0) 3765 38600-0
Fax:    +49 (0) 3765 38600-4100
 
Managing Directors:
	Director Technology/CEO: Dipl.-Phys. Siegmar Schmidt;
	Director Commercial Affairs/COO: Dipl. Ing. (FH) Armin von Collrepp
Commercial Registry:
	Amtsgericht Chemnitz, HRB 28082; USt.-Id Nr. DE150534010



From linux at arm.linux.org.uk  Mon Aug 10 05:50:39 2015
From: linux at arm.linux.org.uk (Russell King - ARM Linux)
Date: Mon, 10 Aug 2015 13:50:39 +0100
Subject: Disabling caches with MMU enabled
Message-ID: <20150810125039.GT7557@n2100.arm.linux.org.uk>

There is an erratum for Cortex-A15 which contains this paragraph:

 2) Do not issue write-back cacheable stores at any time when the cache
 is disabled (SCTLR.C=0) and the MMU is enabled (SCTLR.M=1). Because it
 is implementation defined whether cacheable stores update the cache when
 the cache is disabled it is not expected that any portable code will
 execute cacheable stores when the cache is disabled.

The interesting part is the second sentence, which implies that having the
MMU enabled with writeback mappings, but with the C bit clear is not an
expected use case.  Moreover, it reinforces the ARM ARM statment that a
disabled cache may still be searched, and updated with written data.

However, the v7_exit_coherency_flush() function creates exactly this
scenario by clearing the C bit:

#define v7_exit_coherency_flush(level) \
        asm volatile( \
        ".arch  armv7-a \n\t" \
        "stmfd  sp!, {fp, ip} \n\t" \
        "mrc    p15, 0, r0, c1, c0, 0   @ get SCTLR \n\t" \
        "bic    r0, r0, #"__stringify(CR_C)" \n\t" \
        "mcr    p15, 0, r0, c1, c0, 0   @ set SCTLR \n\t" \
        "isb    \n\t" \

However, v7_exit_coherency_flush() is careful to disable caching, flush
the cache and then disable coherency.  Whether that's sufficient for all
cases is open to question - and where we need this CA15 errata implemented,
it implies that even this sequence is not permissible to use there.

tegra_disable_clean_inv_dcache() is an assembly version of something
similar to the above, and has the same concerns as the above.

Implementations which copy the ARM Ltd platforms CPU hotplug hack also
do this, but in a much more dirty way.  We really need people to stop
copying the ARM Ltd CPU hotplug hack - I'd go as far as saying that
arm-soc must stop merging code which introduces these, or (as I've
already said) which try to turn the ARM CPU hotplug hack into some
generic facility for platforms to make use of:

static inline void cpu_enter_lowpower(void)
{
        "       mrc     p15, 0, %0, c1, c0, 1\n"
        "       bic     %0, %0, %3\n"
        "       mcr     p15, 0, %0, c1, c0, 1\n"
...
          : "=&r" (v)
          : "r" (0), "Ir" (CR_C), "Ir" (0x40)
}

The exynos implementation of v7_exit_coherency() is another instance.

arch/arm/mach-shmobile/platsmp-apmu.c:cpu_enter_lowpower_a15() definitely
looks like it's a problem, because we are talking about Cortex-A15 there,
and the sequence is just turning off the C bit, but then reverting back
to C code to then call the cache flushing.  This is definitely unsafe.

I think all places which clear the C bit need to be re-reviewed and at
least some of them fixed, or converted to use a macro such as the
v7_exit_coherency_flush macro - and they should get a notice placed
on them to discourage copy-n-pasting it.

Incidentally, armada_370_xp_pmsu_idle_enter() should be fixed not to use
hard-coded constants in the assembly.  Use the "Ir" asm() constraint and
pass CR_C in.

Basically, grep for '\<CR_C\>' (quotes and backslashes required for
grep...)

-- 
FTTC broadband for 0.8mile line: currently at 10.5Mbps down 400kbps up
according to speedtest.net.


From stefano.stabellini at eu.citrix.com  Mon Aug 10 05:52:22 2015
From: stefano.stabellini at eu.citrix.com (Stefano Stabellini)
Date: Mon, 10 Aug 2015 13:52:22 +0100
Subject: [PATCH v3 20/20] arm/xen: Add support for 64KB page
 granularity
In-Reply-To: <1438966019-19322-21-git-send-email-julien.grall@citrix.com>
References: <1438966019-19322-1-git-send-email-julien.grall@citrix.com>
 <1438966019-19322-21-git-send-email-julien.grall@citrix.com>
Message-ID: <alpine.DEB.2.02.1508101351410.11337@kaball.uk.xensource.com>

On Fri, 7 Aug 2015, Julien Grall wrote:
> The hypercall interface is always using 4KB page granularity. This is
> requiring to use xen page definition macro when we deal with hypercall.
> 
> Note that pfn_to_gfn is working with a Xen pfn (i.e 4KB). We may want to
> rename pfn_gfn to make this explicit.
> 
> We also allocate a 64KB page for the shared page even though only the
> first 4KB is used. I don't think this is really important for now as it
> helps to have the pointer 4KB aligned (XENMEM_add_to_physmap is taking a
> Xen PFN).
> 
> Signed-off-by: Julien Grall <julien.grall at citrix.com>

Reviewed-by: Stefano Stabellini <stefano.stabellini at eu.citrix.com>


> ---
> Cc: Stefano Stabellini <stefano.stabellini at eu.citrix.com>
> Cc: Russell King <linux at arm.linux.org.uk>
> 
> Stefano, I've dropped your reviewed-by given I've updated the doc and do
> changes to avoid usage of XEN_PAGE_SHIFT
> 
>     Changes in v3:
>         - s/MFN/GFN/ base on the new naming
>         - Use virt_to_gfn to avoid use XEN_PAGE_SHIFT
>         - Drop Stefano's reviewed-by
>         - Add some docs in arch/arm/asm/xen/page.h
> 
>     Changes in v2
>         - Add Stefano's reviewed-by
> ---
>  arch/arm/include/asm/xen/page.h | 15 +++++++++++++--
>  arch/arm/xen/enlighten.c        |  6 +++---
>  2 files changed, 16 insertions(+), 5 deletions(-)
> 
> diff --git a/arch/arm/include/asm/xen/page.h b/arch/arm/include/asm/xen/page.h
> index 98c9fc3..e3d94cf 100644
> --- a/arch/arm/include/asm/xen/page.h
> +++ b/arch/arm/include/asm/xen/page.h
> @@ -28,6 +28,17 @@ typedef struct xpaddr {
>  
>  #define INVALID_P2M_ENTRY      (~0UL)
>  
> +/*
> + * The pseudo-physical frame (pfn) used in all the helpers is always based
> + * on Xen page granularity (i.e 4KB).
> + *
> + * A Linux page may be split across multiple non-contiguous Xen page so we
> + * have to keep track with frame based on 4KB page granularity.
> + *
> + * PV drivers should never make a direct usage of those helpers (particularly
> + * pfn_to_gfn and gfn_to_pfn).
> + */
> +
>  unsigned long __pfn_to_mfn(unsigned long pfn);
>  extern struct rb_root phys_to_mach;
>  
> @@ -64,8 +75,8 @@ static inline unsigned long bfn_to_pfn(unsigned long bfn)
>  #define bfn_to_local_pfn(bfn)	bfn_to_pfn(bfn)
>  
>  /* VIRT <-> GUEST conversion */
> -#define virt_to_gfn(v)		(pfn_to_gfn(virt_to_pfn(v)))
> -#define gfn_to_virt(m)		(__va(gfn_to_pfn(m) << PAGE_SHIFT))
> +#define virt_to_gfn(v)		(pfn_to_gfn(virt_to_phys(v) >> XEN_PAGE_SHIFT))
> +#define gfn_to_virt(m)		(__va(gfn_to_pfn(m) << XEN_PAGE_SHIFT))
>  
>  /* Only used in PV code. But ARM guests are always HVM. */
>  static inline xmaddr_t arbitrary_virt_to_machine(void *vaddr)
> diff --git a/arch/arm/xen/enlighten.c b/arch/arm/xen/enlighten.c
> index eeeab07..50b4769 100644
> --- a/arch/arm/xen/enlighten.c
> +++ b/arch/arm/xen/enlighten.c
> @@ -89,8 +89,8 @@ static void xen_percpu_init(void)
>  	pr_info("Xen: initializing cpu%d\n", cpu);
>  	vcpup = per_cpu_ptr(xen_vcpu_info, cpu);
>  
> -	info.mfn = __pa(vcpup) >> PAGE_SHIFT;
> -	info.offset = offset_in_page(vcpup);
> +	info.mfn = virt_to_gfn(vcpup);
> +	info.offset = xen_offset_in_page(vcpup);
>  
>  	err = HYPERVISOR_vcpu_op(VCPUOP_register_vcpu_info, cpu, &info);
>  	BUG_ON(err);
> @@ -213,7 +213,7 @@ static int __init xen_guest_init(void)
>  	xatp.domid = DOMID_SELF;
>  	xatp.idx = 0;
>  	xatp.space = XENMAPSPACE_shared_info;
> -	xatp.gpfn = __pa(shared_info_page) >> PAGE_SHIFT;
> +	xatp.gpfn = virt_to_gfn(shared_info_page);
>  	if (HYPERVISOR_memory_op(XENMEM_add_to_physmap, &xatp))
>  		BUG();
>  
> -- 
> 2.1.4
> 


From lee.jones at linaro.org  Mon Aug 10 05:56:40 2015
From: lee.jones at linaro.org (Lee Jones)
Date: Mon, 10 Aug 2015 13:56:40 +0100
Subject: [PATCH] mfd: atmel-hlcdc: Add support for new SoCs
In-Reply-To: <1438361154-10596-1-git-send-email-boris.brezillon@free-electrons.com>
References: <1438361154-10596-1-git-send-email-boris.brezillon@free-electrons.com>
Message-ID: <20150810125640.GG3249@x1>

On Fri, 31 Jul 2015, Boris Brezillon wrote:

> Add the compatible strings for the at91sam9x5, at91sam9n12, sama5d4 and
> sama5d2 SoCs.
> Update the documentation accordingly.
> 
> Signed-off-by: Boris Brezillon <boris.brezillon at free-electrons.com>
> Signed-off-by: Nicolas Ferre <nicolas.ferre at atmel.com>
> ---
>  Documentation/devicetree/bindings/mfd/atmel-hlcdc.txt | 4 ++++
>  drivers/mfd/atmel-hlcdc.c                             | 4 ++++
>  2 files changed, 8 insertions(+)

I'll accept this time, but next time please send C and binding patches
separately, as per [0].

Applied, thanks.

[0] Documentation/devicetree/bindings/submitting-patches.txt

-- 
Lee Jones
Linaro STMicroelectronics Landing Team Lead
Linaro.org ? Open source software for ARM SoCs
Follow Linaro: Facebook | Twitter | Blog


From stefano.stabellini at eu.citrix.com  Mon Aug 10 05:55:37 2015
From: stefano.stabellini at eu.citrix.com (Stefano Stabellini)
Date: Mon, 10 Aug 2015 13:55:37 +0100
Subject: [PATCH v3 12/20] xen/balloon: Don't rely on the page granularity
 is the same for Xen and Linux
In-Reply-To: <55C88B77.8030700@citrix.com>
References: <1438966019-19322-1-git-send-email-julien.grall@citrix.com>
 <1438966019-19322-13-git-send-email-julien.grall@citrix.com>
 <alpine.DEB.2.02.1508101207071.11337@kaball.uk.xensource.com>
 <55C88B77.8030700@citrix.com>
Message-ID: <alpine.DEB.2.02.1508101352370.11337@kaball.uk.xensource.com>

On Mon, 10 Aug 2015, Julien Grall wrote:
> Hi Stefano,
> 
> On 10/08/15 12:18, Stefano Stabellini wrote:
> >>  			/* Link back into the page tables if not highmem. */
> >> @@ -396,14 +413,15 @@ static enum bp_state increase_reservation(unsigned long nr_pages)
> >>  static enum bp_state decrease_reservation(unsigned long nr_pages, gfp_t gfp)
> >>  {
> >>  	enum bp_state state = BP_DONE;
> >> -	unsigned long  pfn, i;
> >> +	unsigned long i;
> >>  	struct page   *page;
> >>  	int ret;
> >>  	struct xen_memory_reservation reservation = {
> >>  		.address_bits = 0,
> >> -		.extent_order = 0,
> >> +		.extent_order = EXTENT_ORDER,
> >>  		.domid        = DOMID_SELF
> >>  	};
> >> +	static struct page *pages[ARRAY_SIZE(frame_list)];
> > 
> > This array can be rather large: I would try to avoid it, see below.
> 
> [..]
> 
> > 
> > I would simply and avoid introducing a new array:
> >     pfn = (frame_list[i] << XEN_PAGE_SHIFT) >> PAGE_SHIFT;
> >     page = pfn_to_page(pfn);
> 
> Which won't work because the frame_list contains a gfn and not a pfn.
> We need to translate back the gfn into a pfn and the into a page.
> 
> The cost of the translation may be big and I wanted to avoid anymore
> XEN_PAGE_SHIFT in the code. In general we should avoid to deal with 4KB
> PFN when it's not necessary, it make the code more confusing to read.

That is true


> If your only concern is the size of the array, we could decrease the
> number of frames by batch. Or allocation the variable once a boot time.

Yes, that is my only concern. Allocating only nr_pages new struct page*
would be good enough I guess.


From pankaj.embedded at gmail.com  Mon Aug 10 05:57:30 2015
From: pankaj.embedded at gmail.com (Pankaj Pandey)
Date: Mon, 10 Aug 2015 18:27:30 +0530
Subject: memory leak ?
Message-ID: <CAOdCjQuQ09-UWNjaZncYfC0HASOzuCS-jMU2mv7K7je+shQyoA@mail.gmail.com>

Hi All,

I am using 3.10 kernel on armv7 target board. We  observed  that
Active(file), Inactive(file) and Buffers sections in /proc/meminfo
have shown increase in memory usage even though none of the processes
running in the system show increased memory usage. Please find log
below:


Log at 5 min
Buffers:           23164 kB
Active(file):      35128 kB
Inactive(file):    97032 kB


log at  30 min.
Buffers:           65960 kB
Active(file):      76024 kB
Inactive(file):   117180 kB

Is this a memory leak ? if yes how we can capture who is consuming these
memories.

Regards,
Pankaj


From stefano.stabellini at eu.citrix.com  Mon Aug 10 05:57:31 2015
From: stefano.stabellini at eu.citrix.com (Stefano Stabellini)
Date: Mon, 10 Aug 2015 13:57:31 +0100
Subject: [Xen-devel] [PATCH v3 19/20] xen/privcmd: Add support for Linux
 64KB page granularity
In-Reply-To: <55C895A8.9020004@citrix.com>
References: <1438966019-19322-1-git-send-email-julien.grall@citrix.com>
 <1438966019-19322-20-git-send-email-julien.grall@citrix.com>
 <alpine.DEB.2.02.1508101230260.11337@kaball.uk.xensource.com>
 <55C895A8.9020004@citrix.com>
Message-ID: <alpine.DEB.2.02.1508101356200.11337@kaball.uk.xensource.com>

On Mon, 10 Aug 2015, David Vrabel wrote:
> On 10/08/15 13:03, Stefano Stabellini wrote:
> > On Fri, 7 Aug 2015, Julien Grall wrote:
> >> -	rc = HYPERVISOR_memory_op(XENMEM_add_to_physmap_range, &xatp);
> >> -	return rc < 0 ? rc : err;
> >> +	for (i = 0; i < nr_gfn; i++) {
> >> +		if ((i % XEN_PFN_PER_PAGE) == 0) {
> >> +			page = pages[i / XEN_PFN_PER_PAGE];
> > 
> > If this function is going to be called very frequently you might want to
> > consider using a shift instead.
> > 
> >     page = pages[i >> 4];
> > 
> > With an appropriate macro of course.
> 
> This change isn't necessary.  Compilers already turn divides into
> suitable shifts.

The ARM compiler I used last time I tested this did not, but that was 1
or 2 years ago. In any case to be clear this change is not required.


From javier at dowhile0.org  Mon Aug 10 06:04:16 2015
From: javier at dowhile0.org (Javier Martinez Canillas)
Date: Mon, 10 Aug 2015 15:04:16 +0200
Subject: memory leak ?
In-Reply-To: <CAOdCjQuQ09-UWNjaZncYfC0HASOzuCS-jMU2mv7K7je+shQyoA@mail.gmail.com>
References: <CAOdCjQuQ09-UWNjaZncYfC0HASOzuCS-jMU2mv7K7je+shQyoA@mail.gmail.com>
Message-ID: <CABxcv=nmedvr4jm=ffd135LjVKE8kCLp5xUqiQatvne-aECH4Q@mail.gmail.com>

Hello Pankaj,

On Mon, Aug 10, 2015 at 2:57 PM, Pankaj Pandey
<pankaj.embedded at gmail.com> wrote:
> Hi All,
>
> I am using 3.10 kernel on armv7 target board. We  observed  that
> Active(file), Inactive(file) and Buffers sections in /proc/meminfo
> have shown increase in memory usage even though none of the processes
> running in the system show increased memory usage. Please find log
> below:
>
>
> Log at 5 min
> Buffers:           23164 kB
> Active(file):      35128 kB
> Inactive(file):    97032 kB
>
>
> log at  30 min.
> Buffers:           65960 kB
> Active(file):      76024 kB
> Inactive(file):   117180 kB
>
> Is this a memory leak ? if yes how we can capture who is consuming these
> memories.
>

Did you already try enabling the Kernel Memory Leak Detector [0]?

> Regards,
> Pankaj
>

Best regards,
Javier

[0]: https://www.kernel.org/doc/Documentation/kmemleak.txt


From henryc.chen at mediatek.com  Mon Aug 10 06:10:45 2015
From: henryc.chen at mediatek.com (Henry Chen)
Date: Mon, 10 Aug 2015 21:10:45 +0800
Subject: [PATCH v3] mfd: mt6397: Implement wake handler and suspend/resume to
 handle wake up event.
Message-ID: <1439212245-18935-1-git-send-email-henryc.chen@mediatek.com>

Implement .irq_set_wake() to get who is wakeup source and setup on suspend/reumse. Enable
mt6393_irq as wake up source properly to pinctrl by enable_irq_wake()/enable_irq_wake().

Reviewed-by: Lee Jones <lee.jones at linaro.org>
Signed-off-by: Henry Chen <henryc.chen at mediatek.com>
---
Changes since v2:
Remove the filename of title.
Remove irrelevant change.

Chandes since v1:
Used enable_irq_wake()/disable_irq_wake to handle irq wakeup source.

 drivers/mfd/mt6397-core.c       | 49 +++++++++++++++++++++++++++++++++++++++++
 include/linux/mfd/mt6397/core.h |  1 +
 2 files changed, 50 insertions(+)

diff --git a/drivers/mfd/mt6397-core.c b/drivers/mfd/mt6397-core.c
index 03929a6..e7d5a67 100644
--- a/drivers/mfd/mt6397-core.c
+++ b/drivers/mfd/mt6397-core.c
@@ -93,12 +93,31 @@ static void mt6397_irq_enable(struct irq_data *data)
 	mt6397->irq_masks_cur[reg] |= BIT(shift);
 }
 
+#ifdef CONFIG_PM_SLEEP
+static int mt6397_irq_set_wake(struct irq_data *irq_data, unsigned int on)
+{
+	struct mt6397_chip *mt6397 = irq_data_get_irq_chip_data(irq_data);
+	int shift = irq_data->hwirq & 0xf;
+	int reg = irq_data->hwirq >> 4;
+
+	if (on)
+		mt6397->wake_mask[reg] |= BIT(shift);
+	else
+		mt6397->wake_mask[reg] &= ~BIT(shift);
+
+	return 0;
+}
+#else
+#define mt6397_irq_set_wake NULL
+#endif
+
 static struct irq_chip mt6397_irq_chip = {
 	.name = "mt6397-irq",
 	.irq_bus_lock = mt6397_irq_lock,
 	.irq_bus_sync_unlock = mt6397_irq_sync_unlock,
 	.irq_enable = mt6397_irq_enable,
 	.irq_disable = mt6397_irq_disable,
+	.irq_set_wake = mt6397_irq_set_wake,
 };
 
 static void mt6397_irq_handle_reg(struct mt6397_chip *mt6397, int reg,
@@ -183,6 +202,35 @@ static int mt6397_irq_init(struct mt6397_chip *mt6397)
 	return 0;
 }
 
+#ifdef CONFIG_PM_SLEEP
+static int mt6397_irq_suspend(struct device *dev)
+{
+	struct mt6397_chip *chip = dev_get_drvdata(dev);
+
+	regmap_write(chip->regmap, MT6397_INT_CON0, chip->wake_mask[0]);
+	regmap_write(chip->regmap, MT6397_INT_CON1, chip->wake_mask[1]);
+
+	enable_irq_wake(chip->irq);
+
+	return 0;
+}
+
+static int mt6397_irq_resume(struct device *dev)
+{
+	struct mt6397_chip *chip = dev_get_drvdata(dev);
+
+	regmap_write(chip->regmap, MT6397_INT_CON0, chip->irq_masks_cur[0]);
+	regmap_write(chip->regmap, MT6397_INT_CON1, chip->irq_masks_cur[1]);
+
+	disable_irq_wake(chip->irq);
+
+	return 0;
+}
+#endif
+
+static SIMPLE_DEV_PM_OPS(mt6397_pm_ops, mt6397_irq_suspend,
+			mt6397_irq_resume);
+
 static int mt6397_probe(struct platform_device *pdev)
 {
 	int ret;
@@ -237,6 +285,7 @@ static struct platform_driver mt6397_driver = {
 	.driver = {
 		.name = "mt6397",
 		.of_match_table = of_match_ptr(mt6397_of_match),
+		.pm = &mt6397_pm_ops,
 	},
 };
 
diff --git a/include/linux/mfd/mt6397/core.h b/include/linux/mfd/mt6397/core.h
index cf5265b..45b8e8a 100644
--- a/include/linux/mfd/mt6397/core.h
+++ b/include/linux/mfd/mt6397/core.h
@@ -57,6 +57,7 @@ struct mt6397_chip {
 	int irq;
 	struct irq_domain *irq_domain;
 	struct mutex irqlock;
+	u16 wake_mask[2];
 	u16 irq_masks_cur[2];
 	u16 irq_masks_cache[2];
 };
-- 
1.8.1.1.dirty



From eric.auger at linaro.org  Mon Aug 10 06:20:55 2015
From: eric.auger at linaro.org (Eric Auger)
Date: Mon, 10 Aug 2015 15:20:55 +0200
Subject: [PATCH v3 01/10] VFIO: platform: registration of a dummy IRQ bypass
 producer
In-Reply-To: <1439212864-12954-1-git-send-email-eric.auger@linaro.org>
References: <1439212864-12954-1-git-send-email-eric.auger@linaro.org>
Message-ID: <1439212864-12954-2-git-send-email-eric.auger@linaro.org>

Register a dummy producer with void callbacks

Signed-off-by: Eric Auger <eric.auger at linaro.org>

---

v2 -> v3:
- rename vfio_platform_irq_bypass_resume into *_start
---
 drivers/vfio/platform/vfio_platform_irq.c     | 32 +++++++++++++++++++++++++++
 drivers/vfio/platform/vfio_platform_private.h |  2 ++
 2 files changed, 34 insertions(+)

diff --git a/drivers/vfio/platform/vfio_platform_irq.c b/drivers/vfio/platform/vfio_platform_irq.c
index 88bba57..b5cb8c7 100644
--- a/drivers/vfio/platform/vfio_platform_irq.c
+++ b/drivers/vfio/platform/vfio_platform_irq.c
@@ -20,6 +20,7 @@
 #include <linux/types.h>
 #include <linux/vfio.h>
 #include <linux/irq.h>
+#include <linux/irqbypass.h>
 
 #include "vfio_platform_private.h"
 
@@ -177,6 +178,27 @@ static irqreturn_t vfio_irq_handler(int irq, void *dev_id)
 	return IRQ_HANDLED;
 }
 
+static void vfio_platform_irq_bypass_stop(struct irq_bypass_producer *prod)
+{
+}
+
+static void vfio_platform_irq_bypass_start(struct irq_bypass_producer *prod)
+{
+}
+
+static int vfio_platform_irq_bypass_add_consumer(
+			struct irq_bypass_producer *prod,
+			struct irq_bypass_consumer *cons)
+{
+	return 0;
+}
+
+static void vfio_platform_irq_bypass_del_consumer(
+			struct irq_bypass_producer *prod,
+			struct irq_bypass_consumer *cons)
+{
+}
+
 static int vfio_set_trigger(struct vfio_platform_device *vdev, int index,
 			    int fd, irq_handler_t handler)
 {
@@ -186,6 +208,7 @@ static int vfio_set_trigger(struct vfio_platform_device *vdev, int index,
 
 	if (irq->trigger) {
 		free_irq(irq->hwirq, irq);
+		irq_bypass_unregister_producer(&irq->producer);
 		kfree(irq->name);
 		eventfd_ctx_put(irq->trigger);
 		irq->trigger = NULL;
@@ -216,6 +239,15 @@ static int vfio_set_trigger(struct vfio_platform_device *vdev, int index,
 		return ret;
 	}
 
+	irq->producer.token = (void *)trigger;
+	irq->producer.irq = irq->hwirq;
+	irq->producer.add_consumer = vfio_platform_irq_bypass_add_consumer;
+	irq->producer.del_consumer = vfio_platform_irq_bypass_del_consumer;
+	irq->producer.stop = vfio_platform_irq_bypass_stop;
+	irq->producer.start = vfio_platform_irq_bypass_start;
+	ret = irq_bypass_register_producer(&irq->producer);
+	WARN_ON(ret);
+
 	if (!irq->masked)
 		enable_irq(irq->hwirq);
 
diff --git a/drivers/vfio/platform/vfio_platform_private.h b/drivers/vfio/platform/vfio_platform_private.h
index 1c9b3d5..1d2d4d6 100644
--- a/drivers/vfio/platform/vfio_platform_private.h
+++ b/drivers/vfio/platform/vfio_platform_private.h
@@ -17,6 +17,7 @@
 
 #include <linux/types.h>
 #include <linux/interrupt.h>
+#include <linux/irqbypass.h>
 
 #define VFIO_PLATFORM_OFFSET_SHIFT   40
 #define VFIO_PLATFORM_OFFSET_MASK (((u64)(1) << VFIO_PLATFORM_OFFSET_SHIFT) - 1)
@@ -37,6 +38,7 @@ struct vfio_platform_irq {
 	spinlock_t		lock;
 	struct virqfd		*unmask;
 	struct virqfd		*mask;
+	struct irq_bypass_producer producer;
 };
 
 struct vfio_platform_region {
-- 
1.9.1



From eric.auger at linaro.org  Mon Aug 10 06:20:54 2015
From: eric.auger at linaro.org (Eric Auger)
Date: Mon, 10 Aug 2015 15:20:54 +0200
Subject: [PATCH v3 00/10] ARM IRQ forward control based on IRQ bypass manager
Message-ID: <1439212864-12954-1-git-send-email-eric.auger@linaro.org>

This series allows to set ARM IRQ forwarding between a VFIO platform
device physical IRQ and a guest virtual IRQ. The link is coordinated
by the IRQ bypass manager.

The principle is the VFIO platform driver registers an IRQ bypass producer
struct on VFIO_IRQ_SET_ACTION_TRIGGER while KVM irqfd registers a consumer
struct on the irqfd assignment. This leads to a handshake based on the
eventfd context (used as token) match. When either of the producer/consumer
disappears, an unregistration occurs and the link is disconnected.

This kernel integration deprecates the former kvm-vfio approach:
https://lkml.org/lkml/2015/4/13/353. Some rationale about that change can
be found in IRQ bypass manager thread: https://lkml.org/lkml/2015/6/29/268

Dependencies:
1- [PATCH v4 00/11] arm/arm64: KVM: Active interrupt state switching
   for shared devices (http://www.spinics.net/lists/arm-kernel/msg437884.html)
   except PATCH 11
2- [PATCH 0/6] irqchip: GICv2/v3: Add support for irq_vcpu_affinity
3- [PATCH v4] virt: IRQ bypass manager (https://lkml.org/lkml/2015/8/6/526)
4- [PATCH 0/2] KVM: arm/arm64: Guest synchronous halt/resume
   (https://www.mail-archive.com/linux-kernel at vger.kernel.org/msg950942.html)

All those pieces can be found at:
https://git.linaro.org/people/eric.auger/linux.git/shortlog/refs/heads/v4.2-rc6-irq-forward-v3

More backgroung on ARM IRQ forwarding in the text below and at
http://www.linux-kvm.org/images/a/a8/01x04-ARMdevice.pdf.

A forwarded IRQ is deactivated by the guest and not by the host.
When the guest deactivates the associated virtual IRQ, the interrupt
controller automatically completes the physical IRQ. Obviously
this requires some HW support in the interrupt controller. This is
the case for ARM GICv2.

The direct benefit is that, for a level sensitive IRQ, a VM exit
can be avoided on forwarded IRQ completion.

When the IRQ is forwarded, the VFIO platform driver does not need to
mask the physical IRQ anymore before signaling the eventfd. Indeed
genirq lowers the running priority, enabling other physical IRQ to hit
except that one.

Besides, the injection still is based on irqfd triggering. The only
impact on irqfd process is resamplefd is not called anymore on
virtual IRQ completion since deactivation is not trapped by KVM.

This was tested on Calxeda Midway, assigning the xgmac main IRQ

History:

v2 (RFC) -> v3(PATCH):
- all dependencies now have a patch status
- we dropped the producer active boolean exchanged between the
  VFIO producer and irqfd arm consumer. As a consequence, on
  unforward, if the IRQ is active, this latter is deactivated
  without VFIO-masking it. So we do not exactly come back to the
  exact state where we would be in unforwarded state. A new
  physical IRQ can hit while the previous virtual IRQ is under
  treatment. Its injection in the guest may be rejected thanks
  to the VGIC state machine. This IRQ will be lost but I don't
  think this is a severe issue. In case no new IRQ hits, the
  guest deactivation of the virtual IRQ will trigger the resamplefd
  which will VFIO unmask the non-masked IRQ. This also has no
  consequence.
- VFIO platform driver consumer_add now can fail. It rejects the
  transition for forwarding state in case the IRQ is active
- the series is rebased on new irq_vcpu_affinity series
- no dependency anymore on "chip/vgic adaptations for forwarded irq"
  which was partially integrated into Marc's series. A fix is still
  needed through.
- Guest synchronous halt/resume patch re-integrated into this series
- integrate a new patch file coming mixing
  [PATCH v4 11/11] KVM: arm/arm64: vgic: Allow HW interrupts for
                   non-shared devices &
  [RFC v2 2/4] KVM: arm: vgic: fix state machine for forwarded IRQ

v1 -> v2:
- irq bypass manager and irqfd consumer moved in a separate patch
- kvm_arm_[halt,resume]_guest moved in a separate patch
- remove VFIO external functions since we do not need them anymore
- apply container_of strategy advised by Paolo. Only active field
  remains and discussions will tell whether we get rid of it.
- renamed kvm_arch functions

- kvm-vfio v6 -> RFC v1 based on IRQ bypass manager
  see previous history in https://lkml.org/lkml/2015/4/13/353).

Best Regards

Eric


Eric Auger (9):
  VFIO: platform: registration of a dummy IRQ bypass producer
  VFIO: platform: test forwarded state when selecting the IRQ handler
  VFIO: platform: single handler using function pointer
  VFIO: platform: add vfio_platform_set_automasked
  VFIO: platform: add vfio_platform_is_active
  VFIO: platform: add irq bypass producer management
  KVM: arm/arm64: vgic: support irqfd injection of a forwarded IRQ
  KVM: arm/arm64: vgic: forwarding control
  KVM: arm/arm64: implement IRQ bypass consumer functions

Marc Zyngier (1):
  KVM: arm/arm64: vgic: Allow HW interrupts for non-shared devices

 arch/arm/kvm/Kconfig                          |   1 +
 arch/arm/kvm/arm.c                            |  35 +++++
 arch/arm64/kvm/Kconfig                        |   1 +
 drivers/vfio/platform/vfio_platform_irq.c     | 113 +++++++++++++-
 drivers/vfio/platform/vfio_platform_private.h |   4 +
 include/kvm/arm_vgic.h                        |  12 +-
 virt/kvm/arm/arch_timer.c                     |   3 +-
 virt/kvm/arm/vgic.c                           | 215 ++++++++++++++++++++++++--
 8 files changed, 358 insertions(+), 26 deletions(-)

-- 
1.9.1



From eric.auger at linaro.org  Mon Aug 10 06:20:56 2015
From: eric.auger at linaro.org (Eric Auger)
Date: Mon, 10 Aug 2015 15:20:56 +0200
Subject: [PATCH v3 02/10] VFIO: platform: test forwarded state when selecting
 the IRQ handler
In-Reply-To: <1439212864-12954-1-git-send-email-eric.auger@linaro.org>
References: <1439212864-12954-1-git-send-email-eric.auger@linaro.org>
Message-ID: <1439212864-12954-3-git-send-email-eric.auger@linaro.org>

Add a new forwarded flag in vfio_platform_irq.  In case the IRQ
is forwarded, the VFIO platform IRQ handler does not need to
disable the IRQ anymore.

When setting the IRQ handler we now also test the forwarded state. In
case the IRQ is forwarded we select the vfio_irq_handler.

Signed-off-by: Eric Auger <eric.auger at linaro.org>

---

v2:
- add a new forwarded flag and do not use irqd_irq_forwarded anymore
---
 drivers/vfio/platform/vfio_platform_irq.c     | 3 ++-
 drivers/vfio/platform/vfio_platform_private.h | 1 +
 2 files changed, 3 insertions(+), 1 deletion(-)

diff --git a/drivers/vfio/platform/vfio_platform_irq.c b/drivers/vfio/platform/vfio_platform_irq.c
index b5cb8c7..40f057a 100644
--- a/drivers/vfio/platform/vfio_platform_irq.c
+++ b/drivers/vfio/platform/vfio_platform_irq.c
@@ -262,7 +262,8 @@ static int vfio_platform_set_irq_trigger(struct vfio_platform_device *vdev,
 	struct vfio_platform_irq *irq = &vdev->irqs[index];
 	irq_handler_t handler;
 
-	if (vdev->irqs[index].flags & VFIO_IRQ_INFO_AUTOMASKED)
+	if (vdev->irqs[index].flags & VFIO_IRQ_INFO_AUTOMASKED &&
+			!irq->forwarded)
 		handler = vfio_automasked_irq_handler;
 	else
 		handler = vfio_irq_handler;
diff --git a/drivers/vfio/platform/vfio_platform_private.h b/drivers/vfio/platform/vfio_platform_private.h
index 1d2d4d6..8b4f814 100644
--- a/drivers/vfio/platform/vfio_platform_private.h
+++ b/drivers/vfio/platform/vfio_platform_private.h
@@ -39,6 +39,7 @@ struct vfio_platform_irq {
 	struct virqfd		*unmask;
 	struct virqfd		*mask;
 	struct irq_bypass_producer producer;
+	bool			forwarded;
 };
 
 struct vfio_platform_region {
-- 
1.9.1



From eric.auger at linaro.org  Mon Aug 10 06:20:57 2015
From: eric.auger at linaro.org (Eric Auger)
Date: Mon, 10 Aug 2015 15:20:57 +0200
Subject: [PATCH v3 03/10] VFIO: platform: single handler using function pointer
In-Reply-To: <1439212864-12954-1-git-send-email-eric.auger@linaro.org>
References: <1439212864-12954-1-git-send-email-eric.auger@linaro.org>
Message-ID: <1439212864-12954-4-git-send-email-eric.auger@linaro.org>

A single handler now is registered whatever the use case: automasked
or not. A function pointer is set according to the wished behavior
and the handler calls this function.

The irq lock is taken/released in the root handler. eventfd_signal can
be called in regions not allowed to sleep.

Signed-off-by: Eric Auger <eric.auger at linaro.org>

---

v4: creation
---
 drivers/vfio/platform/vfio_platform_irq.c     | 21 +++++++++++++++------
 drivers/vfio/platform/vfio_platform_private.h |  1 +
 2 files changed, 16 insertions(+), 6 deletions(-)

diff --git a/drivers/vfio/platform/vfio_platform_irq.c b/drivers/vfio/platform/vfio_platform_irq.c
index 40f057a..b31b1f0 100644
--- a/drivers/vfio/platform/vfio_platform_irq.c
+++ b/drivers/vfio/platform/vfio_platform_irq.c
@@ -148,11 +148,8 @@ static int vfio_platform_set_irq_unmask(struct vfio_platform_device *vdev,
 static irqreturn_t vfio_automasked_irq_handler(int irq, void *dev_id)
 {
 	struct vfio_platform_irq *irq_ctx = dev_id;
-	unsigned long flags;
 	int ret = IRQ_NONE;
 
-	spin_lock_irqsave(&irq_ctx->lock, flags);
-
 	if (!irq_ctx->masked) {
 		ret = IRQ_HANDLED;
 
@@ -161,8 +158,6 @@ static irqreturn_t vfio_automasked_irq_handler(int irq, void *dev_id)
 		irq_ctx->masked = true;
 	}
 
-	spin_unlock_irqrestore(&irq_ctx->lock, flags);
-
 	if (ret == IRQ_HANDLED)
 		eventfd_signal(irq_ctx->trigger, 1);
 
@@ -178,6 +173,19 @@ static irqreturn_t vfio_irq_handler(int irq, void *dev_id)
 	return IRQ_HANDLED;
 }
 
+static irqreturn_t vfio_handler(int irq, void *dev_id)
+{
+	struct vfio_platform_irq *irq_ctx = dev_id;
+	unsigned long flags;
+	irqreturn_t ret;
+
+	spin_lock_irqsave(&irq_ctx->lock, flags);
+	ret = irq_ctx->handler(irq, dev_id);
+	spin_unlock_irqrestore(&irq_ctx->lock, flags);
+
+	return ret;
+}
+
 static void vfio_platform_irq_bypass_stop(struct irq_bypass_producer *prod)
 {
 }
@@ -229,9 +237,10 @@ static int vfio_set_trigger(struct vfio_platform_device *vdev, int index,
 	}
 
 	irq->trigger = trigger;
+	irq->handler = handler;
 
 	irq_set_status_flags(irq->hwirq, IRQ_NOAUTOEN);
-	ret = request_irq(irq->hwirq, handler, 0, irq->name, irq);
+	ret = request_irq(irq->hwirq, vfio_handler, 0, irq->name, irq);
 	if (ret) {
 		kfree(irq->name);
 		eventfd_ctx_put(trigger);
diff --git a/drivers/vfio/platform/vfio_platform_private.h b/drivers/vfio/platform/vfio_platform_private.h
index 8b4f814..f848a6b 100644
--- a/drivers/vfio/platform/vfio_platform_private.h
+++ b/drivers/vfio/platform/vfio_platform_private.h
@@ -40,6 +40,7 @@ struct vfio_platform_irq {
 	struct virqfd		*mask;
 	struct irq_bypass_producer producer;
 	bool			forwarded;
+	irqreturn_t (*handler)(int irq, void *dev_id);
 };
 
 struct vfio_platform_region {
-- 
1.9.1



From eric.auger at linaro.org  Mon Aug 10 06:21:00 2015
From: eric.auger at linaro.org (Eric Auger)
Date: Mon, 10 Aug 2015 15:21:00 +0200
Subject: [PATCH v3 06/10] VFIO: platform: add irq bypass producer management
In-Reply-To: <1439212864-12954-1-git-send-email-eric.auger@linaro.org>
References: <1439212864-12954-1-git-send-email-eric.auger@linaro.org>
Message-ID: <1439212864-12954-7-git-send-email-eric.auger@linaro.org>

This patch populates the IRQ bypass callacks:
- stop/start producer simply consist in disabling/enabling the host irq
- add/del consumer: basically set the automasked flag to false/true

Signed-off-by: Eric Auger <eric.auger at linaro.org>

---
v2 -> v3:
- vfio_platform_irq_bypass_add_consumer now returns an error in case
  the IRQ is recognized as active
- active boolean not set anymore
- do not VFIO mask the IRQ anymore on unforward

v1 -> v2:
- device handle caching in vfio_platform_device is introduced in a
  separate patch
- use container_of
---
 drivers/vfio/platform/vfio_platform_irq.c | 23 ++++++++++++++++++++++-
 1 file changed, 22 insertions(+), 1 deletion(-)

diff --git a/drivers/vfio/platform/vfio_platform_irq.c b/drivers/vfio/platform/vfio_platform_irq.c
index efaee58..400a188 100644
--- a/drivers/vfio/platform/vfio_platform_irq.c
+++ b/drivers/vfio/platform/vfio_platform_irq.c
@@ -224,23 +224,44 @@ static int vfio_platform_is_active(struct vfio_platform_irq *irq)
 
 static void vfio_platform_irq_bypass_stop(struct irq_bypass_producer *prod)
 {
+	disable_irq(prod->irq);
 }
 
 static void vfio_platform_irq_bypass_start(struct irq_bypass_producer *prod)
 {
+	enable_irq(prod->irq);
 }
 
 static int vfio_platform_irq_bypass_add_consumer(
 			struct irq_bypass_producer *prod,
 			struct irq_bypass_consumer *cons)
 {
-	return 0;
+	struct vfio_platform_irq *irq =
+		container_of(prod, struct vfio_platform_irq, producer);
+
+	/*
+	 * if the IRQ is active at irqchip level or VFIO (auto)masked
+	 * this means the host IRQ is already under injection in the
+	 * guest and this not safe to change the forwarding state at
+	 * that stage.
+	 * It is not possible to differentiate user-space masking
+	 * from auto-masking, leading to possible false detection of
+	 * active state.
+	 */
+	if (vfio_platform_is_active(irq))
+		return -EAGAIN;
+
+	return vfio_platform_set_automasked(irq, false);
 }
 
 static void vfio_platform_irq_bypass_del_consumer(
 			struct irq_bypass_producer *prod,
 			struct irq_bypass_consumer *cons)
 {
+	struct vfio_platform_irq *irq =
+		container_of(prod, struct vfio_platform_irq, producer);
+
+	vfio_platform_set_automasked(irq, true);
 }
 
 static int vfio_set_trigger(struct vfio_platform_device *vdev, int index,
-- 
1.9.1



From eric.auger at linaro.org  Mon Aug 10 06:20:59 2015
From: eric.auger at linaro.org (Eric Auger)
Date: Mon, 10 Aug 2015 15:20:59 +0200
Subject: [PATCH v3 05/10] VFIO: platform: add vfio_platform_is_active
In-Reply-To: <1439212864-12954-1-git-send-email-eric.auger@linaro.org>
References: <1439212864-12954-1-git-send-email-eric.auger@linaro.org>
Message-ID: <1439212864-12954-6-git-send-email-eric.auger@linaro.org>

This function returns whether the IRQ is active at irqchip level or
VFIO masked. If either is true, it is considered the IRQ is active.
Currently there is no way to differentiate userspace masked IRQ from
automasked IRQ. There might be false detection of activity. However
it is currently acceptable to have false detection.

Signed-off-by: Eric Auger <eric.auger at linaro.org>

---
---
 drivers/vfio/platform/vfio_platform_irq.c | 17 +++++++++++++++++
 1 file changed, 17 insertions(+)

diff --git a/drivers/vfio/platform/vfio_platform_irq.c b/drivers/vfio/platform/vfio_platform_irq.c
index a285384..efaee58 100644
--- a/drivers/vfio/platform/vfio_platform_irq.c
+++ b/drivers/vfio/platform/vfio_platform_irq.c
@@ -205,6 +205,23 @@ static int vfio_platform_set_automasked(struct vfio_platform_irq *irq,
 	return 0;
 }
 
+static int vfio_platform_is_active(struct vfio_platform_irq *irq)
+{
+	unsigned long flags;
+	bool active, masked, outstanding;
+	int ret;
+
+	spin_lock_irqsave(&irq->lock, flags);
+
+	ret = irq_get_irqchip_state(irq->hwirq, IRQCHIP_STATE_ACTIVE, &active);
+	BUG_ON(ret);
+	masked = irq->masked;
+	outstanding = active || masked;
+
+	spin_unlock_irqrestore(&irq->lock, flags);
+	return outstanding;
+}
+
 static void vfio_platform_irq_bypass_stop(struct irq_bypass_producer *prod)
 {
 }
-- 
1.9.1



From eric.auger at linaro.org  Mon Aug 10 06:21:04 2015
From: eric.auger at linaro.org (Eric Auger)
Date: Mon, 10 Aug 2015 15:21:04 +0200
Subject: [PATCH v3 10/10] KVM: arm/arm64: implement IRQ bypass consumer
 functions
In-Reply-To: <1439212864-12954-1-git-send-email-eric.auger@linaro.org>
References: <1439212864-12954-1-git-send-email-eric.auger@linaro.org>
Message-ID: <1439212864-12954-11-git-send-email-eric.auger@linaro.org>

Implement IRQ bypass callbacks for arm/arm64 IRQ forwarding:
- kvm_arch_irq_bypass_add_producer: perform VGIC/irqchip
  settings for forwarding
- kvm_arch_irq_bypass_del_producer: same for inverse operation
- kvm_arch_irq_bypass_stop: halt guest execution
- kvm_arch_irq_bypass_start: resume guest execution

and set CONFIG_HAVE_KVM_IRQ_BYPASS for arm/arm64.

Signed-off-by: Eric Auger <eric.auger at linaro.org>

---

v2 -> v3:
- kvm_arch_irq_bypass_resume renamed into kvm_arch_irq_bypass_start
- kvm_vgic_unset_forward does not take the active bool param anymore
- kvm_arch_irq_bypass_add_producer now returns an error value
- remove kvm_arch_irq_bypass_update

v1 -> v2:
- struct kvm_kernel_irqfd is retrieved with container_of
- function names changed
---
 arch/arm/kvm/Kconfig   |  1 +
 arch/arm/kvm/arm.c     | 35 +++++++++++++++++++++++++++++++++++
 arch/arm64/kvm/Kconfig |  1 +
 3 files changed, 37 insertions(+)

diff --git a/arch/arm/kvm/Kconfig b/arch/arm/kvm/Kconfig
index 3c565b9..655d277 100644
--- a/arch/arm/kvm/Kconfig
+++ b/arch/arm/kvm/Kconfig
@@ -33,6 +33,7 @@ config KVM
 	select HAVE_KVM_EVENTFD
 	select HAVE_KVM_IRQFD
 	select IRQ_BYPASS_MANAGER
+	select HAVE_KVM_IRQ_BYPASS
 	depends on ARM_VIRT_EXT && ARM_LPAE && ARM_ARCH_TIMER
 	---help---
 	  Support hosting virtualized guest machines.
diff --git a/arch/arm/kvm/arm.c b/arch/arm/kvm/arm.c
index 0529b38..7cfc5dc 100644
--- a/arch/arm/kvm/arm.c
+++ b/arch/arm/kvm/arm.c
@@ -27,6 +27,8 @@
 #include <linux/mman.h>
 #include <linux/sched.h>
 #include <linux/kvm.h>
+#include <linux/kvm_irqfd.h>
+#include <linux/irqbypass.h>
 #include <trace/events/kvm.h>
 
 #define CREATE_TRACE_POINTS
@@ -1149,6 +1151,39 @@ struct kvm_vcpu *kvm_mpidr_to_vcpu(struct kvm *kvm, unsigned long mpidr)
 	return NULL;
 }
 
+int kvm_arch_irq_bypass_add_producer(struct irq_bypass_consumer *cons,
+				      struct irq_bypass_producer *prod)
+{
+	struct kvm_kernel_irqfd *irqfd =
+		container_of(cons, struct kvm_kernel_irqfd, consumer);
+
+	return kvm_vgic_set_forward(irqfd->kvm, prod->irq, irqfd->gsi);
+}
+void kvm_arch_irq_bypass_del_producer(struct irq_bypass_consumer *cons,
+				      struct irq_bypass_producer *prod)
+{
+	struct kvm_kernel_irqfd *irqfd =
+		container_of(cons, struct kvm_kernel_irqfd, consumer);
+
+	kvm_vgic_unset_forward(irqfd->kvm, prod->irq, irqfd->gsi);
+}
+
+void kvm_arch_irq_bypass_stop(struct irq_bypass_consumer *cons)
+{
+	struct kvm_kernel_irqfd *irqfd =
+		container_of(cons, struct kvm_kernel_irqfd, consumer);
+
+	kvm_arm_halt_guest(irqfd->kvm);
+}
+
+void kvm_arch_irq_bypass_start(struct irq_bypass_consumer *cons)
+{
+	struct kvm_kernel_irqfd *irqfd =
+		container_of(cons, struct kvm_kernel_irqfd, consumer);
+
+	kvm_arm_resume_guest(irqfd->kvm);
+}
+
 /**
  * Initialize Hyp-mode and memory mappings on all CPUs.
  */
diff --git a/arch/arm64/kvm/Kconfig b/arch/arm64/kvm/Kconfig
index 2509539..6f6e7a5 100644
--- a/arch/arm64/kvm/Kconfig
+++ b/arch/arm64/kvm/Kconfig
@@ -33,6 +33,7 @@ config KVM
 	select HAVE_KVM_EVENTFD
 	select HAVE_KVM_IRQFD
 	select IRQ_BYPASS_MANAGER
+	select HAVE_KVM_IRQ_BYPASS
 	---help---
 	  Support hosting virtualized guest machines.
 
-- 
1.9.1



From eric.auger at linaro.org  Mon Aug 10 06:21:01 2015
From: eric.auger at linaro.org (Eric Auger)
Date: Mon, 10 Aug 2015 15:21:01 +0200
Subject: [PATCH v3 07/10] KVM: arm/arm64: vgic: Allow HW interrupts for
 non-shared devices
In-Reply-To: <1439212864-12954-1-git-send-email-eric.auger@linaro.org>
References: <1439212864-12954-1-git-send-email-eric.auger@linaro.org>
Message-ID: <1439212864-12954-8-git-send-email-eric.auger@linaro.org>

From: Marc Zyngier <marc.zyngier at arm.com>

So far, the only use of the HW interrupt facility was the timer,
implying that the active state is context-switched for each vcpu,
as the device is is shared across all vcpus.

This does not work for a device that has been assigned to a VM,
as the guest is entierely in control of that device (the HW is
not shared). In that case, it makes sense to bypass the whole
active state switching.

Also the VGIC state machine is adapted to support those assigned
(non shared) HW IRQs:
- nly can be sampled when it is pending
- when queueing the IRQ (programming the LR), the pending state is
  removed as for edge sensitive IRQs
- queued state is not modelled. Level state is not modelled
- its injection always is valid since steming from the HW.

Signed-off-by: Marc Zyngier <marc.zyngier at arm.com>
Signed-off-by: Eric Auger <eric.auger at linaro.org>

---

- a mix of
  [PATCH v4 11/11] KVM: arm/arm64: vgic: Allow HW interrupts for
                   non-shared devices
  [RFC v2 2/4] KVM: arm: vgic: fix state machine for forwarded IRQ
---
 include/kvm/arm_vgic.h    |  6 +++--
 virt/kvm/arm/arch_timer.c |  3 ++-
 virt/kvm/arm/vgic.c       | 58 +++++++++++++++++++++++++++++++++++------------
 3 files changed, 49 insertions(+), 18 deletions(-)

diff --git a/include/kvm/arm_vgic.h b/include/kvm/arm_vgic.h
index d901f1a..7ef9ce0 100644
--- a/include/kvm/arm_vgic.h
+++ b/include/kvm/arm_vgic.h
@@ -163,7 +163,8 @@ struct irq_phys_map {
 	u32			virt_irq;
 	u32			phys_irq;
 	u32			irq;
-	bool			active;
+	bool			shared;
+	bool			active; /* Only valid if shared */
 };
 
 struct irq_phys_map_entry {
@@ -356,7 +357,8 @@ void vgic_v3_dispatch_sgi(struct kvm_vcpu *vcpu, u64 reg);
 int kvm_vgic_vcpu_pending_irq(struct kvm_vcpu *vcpu);
 int kvm_vgic_vcpu_active_irq(struct kvm_vcpu *vcpu);
 struct irq_phys_map *kvm_vgic_map_phys_irq(struct kvm_vcpu *vcpu,
-					   int virt_irq, int irq);
+					   int virt_irq, int irq,
+					   bool shared);
 int kvm_vgic_unmap_phys_irq(struct kvm_vcpu *vcpu, struct irq_phys_map *map);
 bool kvm_vgic_get_phys_irq_active(struct irq_phys_map *map);
 void kvm_vgic_set_phys_irq_active(struct irq_phys_map *map, bool active);
diff --git a/virt/kvm/arm/arch_timer.c b/virt/kvm/arm/arch_timer.c
index 76e38d2..db21d8f 100644
--- a/virt/kvm/arm/arch_timer.c
+++ b/virt/kvm/arm/arch_timer.c
@@ -203,7 +203,8 @@ int kvm_timer_vcpu_reset(struct kvm_vcpu *vcpu,
 	 * Tell the VGIC that the virtual interrupt is tied to a
 	 * physical interrupt. We do that once per VCPU.
 	 */
-	map = kvm_vgic_map_phys_irq(vcpu, irq->irq, host_vtimer_irq);
+	map = kvm_vgic_map_phys_irq(vcpu, irq->irq,
+				    host_vtimer_irq, true);
 	if (WARN_ON(IS_ERR(map)))
 		return PTR_ERR(map);
 
diff --git a/virt/kvm/arm/vgic.c b/virt/kvm/arm/vgic.c
index 9eb489a..fbd5ba5 100644
--- a/virt/kvm/arm/vgic.c
+++ b/virt/kvm/arm/vgic.c
@@ -400,7 +400,11 @@ void vgic_cpu_irq_clear(struct kvm_vcpu *vcpu, int irq)
 
 static bool vgic_can_sample_irq(struct kvm_vcpu *vcpu, int irq)
 {
-	return !vgic_irq_is_queued(vcpu, irq);
+	struct irq_phys_map *map = vgic_irq_map_search(vcpu, irq);
+	bool shared_hw = map && !map->shared;
+
+	return !vgic_irq_is_queued(vcpu, irq) ||
+			(shared_hw && vgic_dist_irq_is_pending(vcpu, irq));
 }
 
 /**
@@ -1150,19 +1154,26 @@ static void vgic_queue_irq_to_lr(struct kvm_vcpu *vcpu, int irq,
 		 * active in the physical world. Otherwise the
 		 * physical interrupt will fire and the guest will
 		 * exit before processing the virtual interrupt.
+		 *
+		 * This is of course only valid for a shared
+		 * interrupt. A non shared interrupt should already be
+		 * active.
 		 */
 		if (map) {
-			int ret;
-
-			BUG_ON(!map->active);
 			vlr.hwirq = map->phys_irq;
 			vlr.state |= LR_HW;
 			vlr.state &= ~LR_EOI_INT;
 
-			ret = irq_set_irqchip_state(map->irq,
-						    IRQCHIP_STATE_ACTIVE,
-						    true);
-			WARN_ON(ret);
+			if (map->shared) {
+				int ret;
+
+				BUG_ON(!map->active);
+				ret = irq_set_irqchip_state(
+						map->irq,
+						IRQCHIP_STATE_ACTIVE,
+						true);
+				WARN_ON(ret);
+			}
 
 			/*
 			 * Make sure we're not going to sample this
@@ -1229,10 +1240,13 @@ bool vgic_queue_irq(struct kvm_vcpu *vcpu, u8 sgi_source_id, int irq)
 
 static bool vgic_queue_hwirq(struct kvm_vcpu *vcpu, int irq)
 {
+	struct irq_phys_map *map = vgic_irq_map_search(vcpu, irq);
+	bool shared_hw = map && !map->shared;
+
 	if (!vgic_can_sample_irq(vcpu, irq))
 		return true; /* level interrupt, already queued */
 
-	if (vgic_queue_irq(vcpu, 0, irq)) {
+	if (vgic_queue_irq(vcpu, 0, irq) || shared_hw) {
 		if (vgic_irq_is_edge(vcpu, irq)) {
 			vgic_dist_irq_clear_pending(vcpu, irq);
 			vgic_cpu_irq_clear(vcpu, irq);
@@ -1411,7 +1425,12 @@ static int vgic_sync_hwirq(struct kvm_vcpu *vcpu, struct vgic_lr vlr)
 		return 0;
 
 	map = vgic_irq_map_search(vcpu, vlr.irq);
-	BUG_ON(!map || !map->active);
+	BUG_ON(!map);
+
+	if (!map->shared)
+		return 0;
+
+	BUG_ON(map->shared && !map->active);
 
 	ret = irq_get_irqchip_state(map->irq,
 				    IRQCHIP_STATE_ACTIVE,
@@ -1563,6 +1582,7 @@ static int vgic_update_irq_pending(struct kvm *kvm, int cpuid,
 	int edge_triggered, level_triggered;
 	int enabled;
 	bool ret = true, can_inject = true;
+	bool shared_hw = map && !map->shared;
 
 	if (irq_num >= min(kvm->arch.vgic.nr_irqs, 1020))
 		return -EINVAL;
@@ -1573,7 +1593,8 @@ static int vgic_update_irq_pending(struct kvm *kvm, int cpuid,
 	edge_triggered = vgic_irq_is_edge(vcpu, irq_num);
 	level_triggered = !edge_triggered;
 
-	if (!vgic_validate_injection(vcpu, irq_num, level)) {
+	if (!vgic_validate_injection(vcpu, irq_num, level) &&
+		!shared_hw) {
 		ret = false;
 		goto out;
 	}
@@ -1742,16 +1763,21 @@ static struct list_head *vgic_get_irq_phys_map_list(struct kvm_vcpu *vcpu,
  * @vcpu: The VCPU pointer
  * @virt_irq: The virtual irq number
  * @irq: The Linux IRQ number
+ * @shared: Indicates if the interrupt has to be context-switched or
+ *          if it is private to a VM
  *
  * Establish a mapping between a guest visible irq (@virt_irq) and a
  * Linux irq (@irq). On injection, @virt_irq will be associated with
  * the physical interrupt represented by @irq. This mapping can be
  * established multiple times as long as the parameters are the same.
+ * If @shared is true, the active state of the interrupt will be
+ * context-switched.
  *
  * Returns a valid pointer on success, and an error pointer otherwise
  */
 struct irq_phys_map *kvm_vgic_map_phys_irq(struct kvm_vcpu *vcpu,
-					   int virt_irq, int irq)
+					   int virt_irq, int irq,
+					   bool shared)
 {
 	struct vgic_dist *dist = &vcpu->kvm->arch.vgic;
 	struct list_head *root = vgic_get_irq_phys_map_list(vcpu, virt_irq);
@@ -1785,7 +1811,8 @@ struct irq_phys_map *kvm_vgic_map_phys_irq(struct kvm_vcpu *vcpu,
 	if (map) {
 		/* Make sure this mapping matches */
 		if (map->phys_irq != phys_irq	||
-		    map->irq      != irq)
+		    map->irq      != irq	||
+		    map->shared   != shared)
 			map = ERR_PTR(-EINVAL);
 
 		/* Found an existing, valid mapping */
@@ -1796,6 +1823,7 @@ struct irq_phys_map *kvm_vgic_map_phys_irq(struct kvm_vcpu *vcpu,
 	map->virt_irq = virt_irq;
 	map->phys_irq = phys_irq;
 	map->irq      = irq;
+	map->shared   = shared;
 
 	list_add_tail_rcu(&entry->entry, root);
 
@@ -1846,7 +1874,7 @@ static void vgic_free_phys_irq_map_rcu(struct rcu_head *rcu)
  */
 bool kvm_vgic_get_phys_irq_active(struct irq_phys_map *map)
 {
-	BUG_ON(!map);
+	BUG_ON(!map || !map->shared);
 	return map->active;
 }
 
@@ -1858,7 +1886,7 @@ bool kvm_vgic_get_phys_irq_active(struct irq_phys_map *map)
  */
 void kvm_vgic_set_phys_irq_active(struct irq_phys_map *map, bool active)
 {
-	BUG_ON(!map);
+	BUG_ON(!map || !map->shared);
 	map->active = active;
 }
 
-- 
1.9.1



From eric.auger at linaro.org  Mon Aug 10 06:21:02 2015
From: eric.auger at linaro.org (Eric Auger)
Date: Mon, 10 Aug 2015 15:21:02 +0200
Subject: [PATCH v3 08/10] KVM: arm/arm64: vgic: support irqfd injection of a
 forwarded IRQ
In-Reply-To: <1439212864-12954-1-git-send-email-eric.auger@linaro.org>
References: <1439212864-12954-1-git-send-email-eric.auger@linaro.org>
Message-ID: <1439212864-12954-9-git-send-email-eric.auger@linaro.org>

Currently irqfd injection relies on kvm_vgic_inject_irq function.
However this function cannot be used anymore for mapped IRQs. So
let's change the implementation to use kvm_vgic_inject_mapped_irq
when the IRQ is forwarded.

Signed-off-by: Eric Auger <eric.auger at linaro.org>
---
 virt/kvm/arm/vgic.c | 8 +++++++-
 1 file changed, 7 insertions(+), 1 deletion(-)

diff --git a/virt/kvm/arm/vgic.c b/virt/kvm/arm/vgic.c
index fbd5ba5..03a85b3 100644
--- a/virt/kvm/arm/vgic.c
+++ b/virt/kvm/arm/vgic.c
@@ -2529,13 +2529,19 @@ int kvm_irq_map_chip_pin(struct kvm *kvm, unsigned irqchip, unsigned pin)
 int kvm_set_irq(struct kvm *kvm, int irq_source_id,
 		u32 irq, int level, bool line_status)
 {
+	struct irq_phys_map *map;
 	unsigned int spi = irq + VGIC_NR_PRIVATE_IRQS;
 
 	trace_kvm_set_irq(irq, level, irq_source_id);
 
 	BUG_ON(!vgic_initialized(kvm));
 
-	return kvm_vgic_inject_irq(kvm, 0, spi, level);
+	map = vgic_irq_map_search(kvm_get_vcpu(kvm, 0), spi);
+
+	if (!map)
+		return kvm_vgic_inject_irq(kvm, 0, spi, level);
+	else
+		return kvm_vgic_inject_mapped_irq(kvm, 0, map, level);
 }
 
 /* MSI not implemented yet */
-- 
1.9.1



From eric.auger at linaro.org  Mon Aug 10 06:21:03 2015
From: eric.auger at linaro.org (Eric Auger)
Date: Mon, 10 Aug 2015 15:21:03 +0200
Subject: [PATCH v3 09/10] KVM: arm/arm64: vgic: forwarding control
In-Reply-To: <1439212864-12954-1-git-send-email-eric.auger@linaro.org>
References: <1439212864-12954-1-git-send-email-eric.auger@linaro.org>
Message-ID: <1439212864-12954-10-git-send-email-eric.auger@linaro.org>

Implements kvm_vgic_[set|unset]_forward.

Handle low-level VGIC programming: physical IRQ/guest IRQ mapping,
list register cleanup, VGIC state machine. Also interacts with
the irqchip.

Signed-off-by: Eric Auger <eric.auger at linaro.org>

---

v2 -> v3:
- on unforward, we do not compute & output the active state anymore.
  This means if the unforward happens while the physical IRQ is
  active, we will not VFIO mask the IRQ while deactiving it. If a
  new physical IRQ hits, the corresponding virtual IRQ might not
  be injected (hence lost) due to VGIC state machine.

bypass rfc v2:
- use irq_set_vcpu_affinity API
- use irq_set_irqchip_state instead of chip->irq_eoi

bypass rfc:
- rename kvm_arch_{set|unset}_forward into
  kvm_vgic_{set|unset}_forward. Remove __KVM_HAVE_ARCH_HALT_GUEST.
  The function is bound to be called by ARM code only.

v4 -> v5:
- fix arm64 compilation issues, ie. also defines
  __KVM_HAVE_ARCH_HALT_GUEST for arm64

v3 -> v4:
- code originally located in kvm_vfio_arm.c
- kvm_arch_vfio_{set|unset}_forward renamed into
  kvm_arch_{set|unset}_forward
- split into 2 functions (set/unset) since unset does not fail anymore
- unset can be invoked at whatever time. Extra care is taken to handle
  transition in VGIC state machine, LR cleanup, ...

v2 -> v3:
- renaming of kvm_arch_set_fwd_state into kvm_arch_vfio_set_forward
- takes a bool arg instead of kvm_fwd_irq_action enum
- removal of KVM_VFIO_IRQ_CLEANUP
- platform device check now happens here
- more precise errors returned
- irq_eoi handled externally to this patch (VGIC)
- correct enable_irq bug done twice
- reword the commit message
- correct check of platform_bus_type
- use raw_spin_lock_irqsave and check the validity of the handler
---
 include/kvm/arm_vgic.h |   6 ++
 virt/kvm/arm/vgic.c    | 149 +++++++++++++++++++++++++++++++++++++++++++++++++
 2 files changed, 155 insertions(+)

diff --git a/include/kvm/arm_vgic.h b/include/kvm/arm_vgic.h
index 7ef9ce0..409ac0f 100644
--- a/include/kvm/arm_vgic.h
+++ b/include/kvm/arm_vgic.h
@@ -363,6 +363,12 @@ int kvm_vgic_unmap_phys_irq(struct kvm_vcpu *vcpu, struct irq_phys_map *map);
 bool kvm_vgic_get_phys_irq_active(struct irq_phys_map *map);
 void kvm_vgic_set_phys_irq_active(struct irq_phys_map *map, bool active);
 
+int kvm_vgic_set_forward(struct kvm *kvm,
+			 unsigned int host_irq, unsigned int guest_irq);
+
+void kvm_vgic_unset_forward(struct kvm *kvm,
+			    unsigned int host_irq, unsigned int guest_irq);
+
 #define irqchip_in_kernel(k)	(!!((k)->arch.vgic.in_kernel))
 #define vgic_initialized(k)	(!!((k)->arch.vgic.nr_cpus))
 #define vgic_ready(k)		((k)->arch.vgic.ready)
diff --git a/virt/kvm/arm/vgic.c b/virt/kvm/arm/vgic.c
index 03a85b3..b15999a 100644
--- a/virt/kvm/arm/vgic.c
+++ b/virt/kvm/arm/vgic.c
@@ -2551,3 +2551,152 @@ int kvm_set_msi(struct kvm_kernel_irq_routing_entry *e,
 {
 	return 0;
 }
+
+/**
+ * kvm_vgic_set_forward - Set IRQ forwarding
+ *
+ * @kvm: handle to the VM
+ * @host_irq: physical IRQ number
+ * @guest_irq: virtual IRQ number
+ *
+ * This function is supposed to be called only if the IRQ
+ * is not in progress: ie. not active at GIC level and not
+ * currently under injection in the guest. The physical IRQ must
+ * also be disabled and the guest must have been exited and
+ * prevented from being re-entered.
+ */
+int kvm_vgic_set_forward(struct kvm *kvm,
+			 unsigned int host_irq,
+			 unsigned int guest_irq)
+{
+	struct irq_phys_map *map = NULL;
+	struct kvm_vcpu *vcpu = kvm_get_vcpu(kvm, 0);
+	int spi_id = guest_irq + VGIC_NR_PRIVATE_IRQS;
+
+	kvm_debug("%s host_irq=%d guest_irq=%d\n",
+		__func__, host_irq, guest_irq);
+
+	if (!vcpu)
+		return 0;
+
+	irq_set_vcpu_affinity(host_irq, vcpu);
+	/*
+	 * next physical IRQ will be be handled as forwarded
+	 * by the host (priority drop only)
+	 */
+
+	map = kvm_vgic_map_phys_irq(vcpu, spi_id, host_irq, false);
+	/*
+	 * next guest_irq injection will be considered as
+	 * forwarded and next flush will program LR
+	 * without maintenance IRQ but with HW bit set
+	 */
+	return !map;
+}
+
+/**
+ * kvm_vgic_unset_forward - Unset IRQ forwarding
+ *
+ * @kvm: handle to the VM
+ * @host_irq: physical IRQ number
+ * @guest_irq: virtual IRQ number
+ *
+ * This function must be called when the host_irq is disabled
+ * and guest has been exited and prevented from being re-entered.
+ *
+ */
+void kvm_vgic_unset_forward(struct kvm *kvm,
+			    unsigned int host_irq,
+			    unsigned int guest_irq)
+{
+	struct kvm_vcpu *vcpu = kvm_get_vcpu(kvm, 0);
+	struct vgic_cpu *vgic_cpu = &vcpu->arch.vgic_cpu;
+	struct vgic_dist *dist = &kvm->arch.vgic;
+	int ret, lr;
+	struct vgic_lr vlr;
+	int spi_id = guest_irq + VGIC_NR_PRIVATE_IRQS;
+	bool queued = false, needs_deactivate = true;
+	struct irq_phys_map *map;
+	bool active;
+
+	kvm_debug("%s host_irq=%d guest_irq=%d\n",
+		__func__, host_irq, guest_irq);
+
+	spin_lock(&dist->lock);
+
+	irq_get_irqchip_state(host_irq, IRQCHIP_STATE_ACTIVE, &active);
+
+	if (!vcpu)
+		goto out;
+
+	map = vgic_irq_map_search(vcpu, spi_id);
+	BUG_ON(!map);
+	ret = kvm_vgic_unmap_phys_irq(vcpu, map);
+	BUG_ON(ret);
+	/*
+	 * subsequent update_irq_pending or flush will handle this
+	 * irq as not forwarded
+	 */
+	if (likely(!(active))) {
+		/*
+		 * the IRQ was not active. let's simply prepare the states
+		 * for subsequent non forwarded injection.
+		 */
+		vgic_dist_irq_clear_level(vcpu, spi_id);
+		vgic_dist_irq_clear_pending(vcpu, spi_id);
+		vgic_irq_clear_queued(vcpu, spi_id);
+		needs_deactivate = false;
+		goto out;
+	}
+
+	/* is there any list register with valid state? */
+	lr = vgic_cpu->vgic_irq_lr_map[spi_id];
+	if (lr != LR_EMPTY) {
+		vlr = vgic_get_lr(vcpu, lr);
+		if (vlr.state & LR_STATE_MASK)
+			queued = true;
+	}
+
+	if (!queued) {
+		vgic_irq_clear_queued(vcpu, spi_id);
+		if (vgic_dist_irq_is_pending(vcpu, spi_id)) {
+			/*
+			 * IRQ is injected but not yet queued. LR will be
+			 * written with EOI_INT and process_maintenance will
+			 * reset the states: queued, level(resampler). Pending
+			 * will be reset on flush.
+			 */
+			vgic_dist_irq_set_level(vcpu, spi_id);
+		} else {
+			/*
+			 * We are somewhere before the update_irq_pending.
+			 * we can't be sure the virtual IRQ will ever be
+			 * injected (due to previous disable_irq).
+			 * Let's simply clear the level which was not correctly
+			 * modelled in forwarded state.
+			 */
+			vgic_dist_irq_clear_level(vcpu, spi_id);
+		}
+		goto out;
+	}
+
+	/*
+	 * the virtual IRQ is queued and a valid LR exists, let's patch it so
+	 * that when EOI happens a maintenance IRQ gets triggered
+	 */
+	vlr.state |= LR_EOI_INT;
+	vgic_set_lr(vcpu, lr, vlr);
+
+	vgic_dist_irq_set_level(vcpu, spi_id);
+	vgic_dist_irq_set_pending(vcpu, spi_id);
+	vgic_irq_set_queued(vcpu, spi_id);
+	 /* The maintenance IRQ will reset all states above */
+
+out:
+	irq_set_irqchip_state(host_irq, IRQCHIP_STATE_ACTIVE, false);
+	irq_set_vcpu_affinity(host_irq, NULL);
+	/* next occurrence will be deactivated by the host */
+
+	spin_unlock(&dist->lock);
+}
+
-- 
1.9.1



From lee.jones at linaro.org  Mon Aug 10 06:22:47 2015
From: lee.jones at linaro.org (Lee Jones)
Date: Mon, 10 Aug 2015 14:22:47 +0100
Subject: [PATCH v4 2/2] dt: power: st: Provide bindings for ST's OPPs
In-Reply-To: <20150803034642.GV899@linux>
References: <1438010430-5802-1-git-send-email-lee.jones@linaro.org>
 <1438010430-5802-2-git-send-email-lee.jones@linaro.org>
 <20150728022936.GB1229@linux>
 <20150728225510.GB3159@codeaurora.org> <20150729081403.GH2284@x1>
 <20150729221526.GE3159@codeaurora.org> <20150730084634.GD9319@x1>
 <CAL_JsqKQLQ15qSt95zBZykzzPhcUrtZzhk29a76n+r_3719AiA@mail.gmail.com>
 <20150731163715.GV3159@codeaurora.org> <20150803034642.GV899@linux>
Message-ID: <20150810132247.GH3249@x1>

On Mon, 03 Aug 2015, Viresh Kumar wrote:

> On 31-07-15, 09:37, Stephen Boyd wrote:
> > For qcom platforms, the frequency is almost always constant.
> > There may be some tables where we have a couple higher
> > frequencies than others because the speed bin is different.
> > Otherwise the voltage/current is changing based on the silicon
> > characteristics. So the biggest duplication is the frequency
> > property.
> > 
> > As far as I know there isn't any algorithm to generate the
> > voltage values. It's all hand tuned tables based on the silicon
> > characterization, so we're left to store these tables in DT and
> > pick the right one at runtime. With regards to the table
> > explosion, on qcom platforms we haven't worried that we have ~40
> > tables, but I'm not opposed to expressing it in a smaller set of
> > nodes, tables, etc. if that's what's desired.
> > 
> > Do we need vendor specific properties for that though? Or do we
> > need some sort of extended frequency/voltage properties that are
> > arrays of values that we can index into based on some silicon
> > characteristics? I like the name based approach because it's
> > simple. Use this OPP table because it's called
> > x-y-z-characteristics and be done. Cramming the tables into less
> > lines may save us some typing and dtb space, but I'm not sure
> > what else it does.
> 
> What about something like this:
> 
> diff --git a/Documentation/devicetree/bindings/opp/opp.txt b/Documentation/devicetree/bindings/opp/opp.txt
> index 0cb44dc21f97..bad7a8299b9c 100644
> --- a/Documentation/devicetree/bindings/opp/opp.txt
> +++ b/Documentation/devicetree/bindings/opp/opp.txt
> @@ -74,6 +74,8 @@ This describes the OPPs belonging to a device. This node can have following
>    reference an OPP.
>  
>  Optional properties:
> +- opp-cuts: One or more strings, describing the versions of hardware the OPPs
> +  can support.

This isn't very generic.

I'm guessing some vendors my have quite a few ways to differentiate
between board versions/revisions/cuts etc.

How about another array where a vendor can choose to identify a piece
of hardware however they see fit.

Example 1 (simple version):

/* Version 1 */
opp-version = <1>;

Example 2 (using the kernel's versioning):

/* 2.6.32-rc1 */
opp-version = <2 6 32 1>;

Example 3 (using ST's versioning):

/* Major 2, Minor 0, Cut 2, All substrates */
opp-version = <2 0 2 0xff>;

Qcom (or anyone else wanting to use names to identify their revisions)
can continue to use their node name method, as it doesn't break any
convention.

>  - opp-shared: Indicates that device nodes using this OPP Table Node's phandle
>    switch their DVFS state together, i.e. they share clock/voltage/current lines.
>    Missing property means devices have independent clock/voltage/current lines,
> @@ -100,6 +102,9 @@ properties.
>    Entries for multiple regulators must be present in the same order as
>    regulators are specified in device's DT node.
>  
> +  If used with 'opp-cuts', then the number of entries present here must match
> +  the number of strings present in 'opp-cuts'.
> +
>  - opp-microamp: The maximum current drawn by the device in microamperes
>    considering system specific parameters (such as transients, process, aging,
>    maximum operating temperature range etc.) as necessary. This may be used to
> 

-- 
Lee Jones
Linaro STMicroelectronics Landing Team Lead
Linaro.org ? Open source software for ARM SoCs
Follow Linaro: Facebook | Twitter | Blog


From geert at linux-m68k.org  Mon Aug 10 06:23:54 2015
From: geert at linux-m68k.org (Geert Uytterhoeven)
Date: Mon, 10 Aug 2015 15:23:54 +0200
Subject: [PATCH v3 2/2] ARM: shmobile: r8a7794: add GPIO DT support
In-Reply-To: <10288801.ZnYt2TD47O@wasted.cogentembedded.com>
References: <2265315.MpjeDzrVz2@wasted.cogentembedded.com>
 <10288801.ZnYt2TD47O@wasted.cogentembedded.com>
Message-ID: <CAMuHMdVj4_h8LX=XuWSyhGpSZ2BPxuWe_oJQYTRPFfYbuidm4g@mail.gmail.com>

Hi Sergei,

On Sun, Aug 9, 2015 at 12:09 AM, Sergei Shtylyov
<sergei.shtylyov at cogentembedded.com> wrote:
> Describe GPIO[0-6] controllers in the R8A7794 device tree.
>
> Based on original patch by Hisashi Nakamura <hisashi.nakamura.ak at renesas.com>.
>
> Signed-off-by: Sergei Shtylyov <sergei.shtylyov at cogentembedded.com>
> Acked-by: Geert Uytterhoeven <geert+renesas at glider.be>
>
> ---
> Changes in version 3:
> - added "power-domains" property to the GPIO device nodes.

Thanks, unwithdrawing my ack ;-)

Acked-by: Geert Uytterhoeven <geert+renesas at glider.be>

Gr{oetje,eeting}s,

                        Geert

--
Geert Uytterhoeven -- There's lots of Linux beyond ia32 -- geert at linux-m68k.org

In personal conversations with technical people, I call myself a hacker. But
when I'm talking to journalists I just say "programmer" or something like that.
                                -- Linus Torvalds


From zhichao.huang at linaro.org  Mon Aug 10 06:25:52 2015
From: zhichao.huang at linaro.org (Zhichao Huang)
Date: Mon, 10 Aug 2015 21:25:52 +0800
Subject: [PATCH v4 00/15] KVM: arm: debug infrastructure support
Message-ID: <1439213167-8988-1-git-send-email-zhichao.huang@linaro.org>

This patch series adds debug support, a key feature missing from the
KVM/armv7 port.

The main idea is to keep track of whether the host and the guest have any
break/watch points enabled or not. We only do the world switch for debug
registers when the host or the guest is actually using it.

We add a function reading the break/watch control variables directly to
indicate whether the host has enabled any break/watch points or not. 
We only call the function upon guest entry, after preempt_disable() and
local_irq_disable(), so there is no race for it.

We also tried implementing this series with trapping host use of debug
registers to hyp mode, and keep track of host/guest use of the debug
hardware in that way. This, however, proved to be very difficult,
because it requires us to: First, we have to add a new mechanism to
support trapping host, jump from EL2 to EL1 to run our host_trap_handlers,
and then jump back to the orginal code which trigger the trap.
Second, we have to take specail care when tearing down KVM to disable
the traps, we also impose an ordering requirement of whether KVM or
the breakpoint functionality gets initialized first. In the end we decided
that this was too difficult and convoluted compared to simply read the
values from variables, so we reverted back to this approach.

The amount of registers is properly frightening, but CPUs actually
only implement a subset of them. Also, there is a number of registers
we don't bother emulating (things having to do with external debug and
OSlock).

External debug is when you actually plug a physical JTAG into the CPU.
OSlock is a way to prevent "other software" to play with the debug
registers. My understanding is that it is only useful in combination
with the external debug. In both case, implementing support for this
is probably not worth the effort, at least for the time being.

This has been tested on a Cortex-A15 platform, running 32bit guests.

The patches for this series are based off v4.2-rc6 and can be found
at:

https://git.linaro.org/people/zhichao.huang/linux.git
branch: guest-debug/4.2-rc6-v4

>From v3 [3]:
- Redefine kvm_cpu_context_t as a new struct including the cp14 states
- Save host cp14 states in the vcpu struct intead of memory
- Add a function to keep track of the host use of the debug registers
- Add new lazy world switch mechanism

>From v2 [2]:
- Delete the debug mode enabling/disabling strategy
- Add missing cp14/cp15 trace events

>From v1 [1]:
- Added missing cp14 reset functions
- Disable debug mode if we don't need it to reduce unnecessary switch

[1]: https://lists.cs.columbia.edu/pipermail/kvmarm/2015-May/014729.html
[2]: https://lists.cs.columbia.edu/pipermail/kvmarm/2015-May/014847.html
[3]: https://lists.cs.columbia.edu/pipermail/kvmarm/2015-June/015167.html

Zhichao Huang (15):
  KVM: arm: plug guest debug exploit
  KVM: arm: rename pm_fake handler to trap_raz_wi
  KVM: arm: enable to use the ARM_DSCR_MDBGEN macro from KVM assembly
    code
  KVM: arm: common infrastructure for handling AArch32 CP14/CP15
  KVM: arm: check ordering of all system register tables
  KVM: arm: add trap handlers for 32-bit debug registers
  KVM: arm: add trap handlers for 64-bit debug registers
  KVM: arm: add a trace event for cp14 traps
  KVM: arm: redefine kvm_cpu_context_t to save the host cp14 states
  KVM: arm: implement world switch for debug registers
  KVM: arm: add a function to keep track of host use of the debug
    registers
  KVM: arm: keep track of host use of the debug registers
  KVM: arm: keep track of guest use of the debug registers
  KVM: arm: implement lazy world switch for debug registers
  KVM: arm: enable trapping of all debug registers

 arch/arm/include/asm/hw_breakpoint.h |  59 +++--
 arch/arm/include/asm/kvm_asm.h       |  17 ++
 arch/arm/include/asm/kvm_coproc.h    |   3 +-
 arch/arm/include/asm/kvm_host.h      |  13 +-
 arch/arm/kernel/asm-offsets.c        |   6 +-
 arch/arm/kernel/hw_breakpoint.c      |  21 ++
 arch/arm/kvm/arm.c                   |   2 +
 arch/arm/kvm/coproc.c                | 445 ++++++++++++++++++++++++++++++-----
 arch/arm/kvm/handle_exit.c           |   4 +-
 arch/arm/kvm/interrupts.S            |  18 +-
 arch/arm/kvm/interrupts_head.S       | 188 ++++++++++++++-
 arch/arm/kvm/trace.h                 |  30 +++
 arch/arm64/include/asm/kvm_host.h    |   1 +
 13 files changed, 707 insertions(+), 100 deletions(-)

-- 
1.7.12.4



From julien.grall at citrix.com  Mon Aug 10 06:25:28 2015
From: julien.grall at citrix.com (Julien Grall)
Date: Mon, 10 Aug 2015 14:25:28 +0100
Subject: [Xen-devel] [PATCH v3 19/20] xen/privcmd: Add support for Linux
 64KB page granularity
In-Reply-To: <alpine.DEB.2.02.1508101356200.11337@kaball.uk.xensource.com>
References: <1438966019-19322-1-git-send-email-julien.grall@citrix.com>
 <1438966019-19322-20-git-send-email-julien.grall@citrix.com>
 <alpine.DEB.2.02.1508101230260.11337@kaball.uk.xensource.com>
 <55C895A8.9020004@citrix.com>
 <alpine.DEB.2.02.1508101356200.11337@kaball.uk.xensource.com>
Message-ID: <55C8A648.20103@citrix.com>

Hi Stefano,

On 10/08/15 13:57, Stefano Stabellini wrote:
> On Mon, 10 Aug 2015, David Vrabel wrote:
>> On 10/08/15 13:03, Stefano Stabellini wrote:
>>> On Fri, 7 Aug 2015, Julien Grall wrote:
>>>> -	rc = HYPERVISOR_memory_op(XENMEM_add_to_physmap_range, &xatp);
>>>> -	return rc < 0 ? rc : err;
>>>> +	for (i = 0; i < nr_gfn; i++) {
>>>> +		if ((i % XEN_PFN_PER_PAGE) == 0) {
>>>> +			page = pages[i / XEN_PFN_PER_PAGE];
>>>
>>> If this function is going to be called very frequently you might want to
>>> consider using a shift instead.
>>>
>>>     page = pages[i >> 4];
>>>
>>> With an appropriate macro of course.
>>
>> This change isn't necessary.  Compilers already turn divides into
>> suitable shifts.
> 
> The ARM compiler I used last time I tested this did not, but that was 1
> or 2 years ago. In any case to be clear this change is not required.

I gave a try on the compiler used by Debian Jessy (gcc 4.9.2). It turns
divides into suitable shifts.

Anyway, if it may happen that older ARM compiler doesn't do this change,
I sure we would have to modify many other places in order to make the
code efficient.

Regards,

-- 
Julien Grall


From zhichao.huang at linaro.org  Mon Aug 10 06:25:53 2015
From: zhichao.huang at linaro.org (Zhichao Huang)
Date: Mon, 10 Aug 2015 21:25:53 +0800
Subject: [PATCH v4 01/15] KVM: arm: plug guest debug exploit
In-Reply-To: <1439213167-8988-1-git-send-email-zhichao.huang@linaro.org>
References: <1439213167-8988-1-git-send-email-zhichao.huang@linaro.org>
Message-ID: <1439213167-8988-2-git-send-email-zhichao.huang@linaro.org>

Hardware debugging in guests is not intercepted currently, it means
that a malicious guest can bring down the entire machine by writing
to the debug registers.

This patch enable trapping of all debug registers, preventing the guests
to access the debug registers.

This patch also disable the debug mode(DBGDSCR) in the guest world all
the time, preventing the guests to mess with the host state.

However, it is a precursor for later patches which will need to do
more to world switch debug states while necessary.

Cc: <stable at vger.kernel.org>
Signed-off-by: Zhichao Huang <zhichao.huang at linaro.org>
---
 arch/arm/include/asm/kvm_coproc.h |  3 +-
 arch/arm/kvm/coproc.c             | 82 +++++++++++++++++++++++++++++----------
 arch/arm/kvm/handle_exit.c        |  4 +-
 arch/arm/kvm/interrupts.S         | 12 +++---
 arch/arm/kvm/interrupts_head.S    | 21 ++++++++--
 5 files changed, 89 insertions(+), 33 deletions(-)

diff --git a/arch/arm/include/asm/kvm_coproc.h b/arch/arm/include/asm/kvm_coproc.h
index 4917c2f..e74ab0f 100644
--- a/arch/arm/include/asm/kvm_coproc.h
+++ b/arch/arm/include/asm/kvm_coproc.h
@@ -31,7 +31,8 @@ void kvm_register_target_coproc_table(struct kvm_coproc_target_table *table);
 int kvm_handle_cp10_id(struct kvm_vcpu *vcpu, struct kvm_run *run);
 int kvm_handle_cp_0_13_access(struct kvm_vcpu *vcpu, struct kvm_run *run);
 int kvm_handle_cp14_load_store(struct kvm_vcpu *vcpu, struct kvm_run *run);
-int kvm_handle_cp14_access(struct kvm_vcpu *vcpu, struct kvm_run *run);
+int kvm_handle_cp14_32(struct kvm_vcpu *vcpu, struct kvm_run *run);
+int kvm_handle_cp14_64(struct kvm_vcpu *vcpu, struct kvm_run *run);
 int kvm_handle_cp15_32(struct kvm_vcpu *vcpu, struct kvm_run *run);
 int kvm_handle_cp15_64(struct kvm_vcpu *vcpu, struct kvm_run *run);
 
diff --git a/arch/arm/kvm/coproc.c b/arch/arm/kvm/coproc.c
index f3d88dc..a885cfe 100644
--- a/arch/arm/kvm/coproc.c
+++ b/arch/arm/kvm/coproc.c
@@ -91,12 +91,6 @@ int kvm_handle_cp14_load_store(struct kvm_vcpu *vcpu, struct kvm_run *run)
 	return 1;
 }
 
-int kvm_handle_cp14_access(struct kvm_vcpu *vcpu, struct kvm_run *run)
-{
-	kvm_inject_undefined(vcpu);
-	return 1;
-}
-
 static void reset_mpidr(struct kvm_vcpu *vcpu, const struct coproc_reg *r)
 {
 	/*
@@ -465,12 +459,8 @@ static int emulate_cp15(struct kvm_vcpu *vcpu,
 	return 1;
 }
 
-/**
- * kvm_handle_cp15_64 -- handles a mrrc/mcrr trap on a guest CP15 access
- * @vcpu: The VCPU pointer
- * @run:  The kvm_run struct
- */
-int kvm_handle_cp15_64(struct kvm_vcpu *vcpu, struct kvm_run *run)
+static int kvm_handle_cp_64(struct kvm_vcpu *vcpu, struct kvm_run *run,
+			    bool cp15)
 {
 	struct coproc_params params;
 
@@ -484,7 +474,35 @@ int kvm_handle_cp15_64(struct kvm_vcpu *vcpu, struct kvm_run *run)
 	params.Rt2 = (kvm_vcpu_get_hsr(vcpu) >> 10) & 0xf;
 	params.CRm = 0;
 
-	return emulate_cp15(vcpu, &params);
+	if (cp15)
+		return emulate_cp15(vcpu, &params);
+
+	/* raz_wi cp14 */
+	(void)pm_fake(vcpu, &params, NULL);
+
+	/* handled */
+	kvm_skip_instr(vcpu, kvm_vcpu_trap_il_is32bit(vcpu));
+	return 1;
+}
+
+/**
+ * kvm_handle_cp15_64 -- handles a mrrc/mcrr trap on a guest CP15 access
+ * @vcpu: The VCPU pointer
+ * @run:  The kvm_run struct
+ */
+int kvm_handle_cp15_64(struct kvm_vcpu *vcpu, struct kvm_run *run)
+{
+	return kvm_handle_cp_64(vcpu, run, 1);
+}
+
+/**
+ * kvm_handle_cp14_64 -- handles a mrrc/mcrr trap on a guest CP14 access
+ * @vcpu: The VCPU pointer
+ * @run:  The kvm_run struct
+ */
+int kvm_handle_cp14_64(struct kvm_vcpu *vcpu, struct kvm_run *run)
+{
+	return kvm_handle_cp_64(vcpu, run, 0);
 }
 
 static void reset_coproc_regs(struct kvm_vcpu *vcpu,
@@ -497,12 +515,8 @@ static void reset_coproc_regs(struct kvm_vcpu *vcpu,
 			table[i].reset(vcpu, &table[i]);
 }
 
-/**
- * kvm_handle_cp15_32 -- handles a mrc/mcr trap on a guest CP15 access
- * @vcpu: The VCPU pointer
- * @run:  The kvm_run struct
- */
-int kvm_handle_cp15_32(struct kvm_vcpu *vcpu, struct kvm_run *run)
+static int kvm_handle_cp_32(struct kvm_vcpu *vcpu, struct kvm_run *run,
+			      bool cp15)
 {
 	struct coproc_params params;
 
@@ -516,7 +530,35 @@ int kvm_handle_cp15_32(struct kvm_vcpu *vcpu, struct kvm_run *run)
 	params.Op2 = (kvm_vcpu_get_hsr(vcpu) >> 17) & 0x7;
 	params.Rt2 = 0;
 
-	return emulate_cp15(vcpu, &params);
+	if (cp15)
+		return emulate_cp15(vcpu, &params);
+
+	/* raz_wi cp14 */
+	(void)pm_fake(vcpu, &params, NULL);
+
+	/* handled */
+	kvm_skip_instr(vcpu, kvm_vcpu_trap_il_is32bit(vcpu));
+	return 1;
+}
+
+/**
+ * kvm_handle_cp15_32 -- handles a mrc/mcr trap on a guest CP15 access
+ * @vcpu: The VCPU pointer
+ * @run:  The kvm_run struct
+ */
+int kvm_handle_cp15_32(struct kvm_vcpu *vcpu, struct kvm_run *run)
+{
+	return kvm_handle_cp_32(vcpu, run, 1);
+}
+
+/**
+ * kvm_handle_cp14_32 -- handles a mrc/mcr trap on a guest CP14 access
+ * @vcpu: The VCPU pointer
+ * @run:  The kvm_run struct
+ */
+int kvm_handle_cp14_32(struct kvm_vcpu *vcpu, struct kvm_run *run)
+{
+	return kvm_handle_cp_32(vcpu, run, 0);
 }
 
 /******************************************************************************
diff --git a/arch/arm/kvm/handle_exit.c b/arch/arm/kvm/handle_exit.c
index 95f12b2..357ad1b 100644
--- a/arch/arm/kvm/handle_exit.c
+++ b/arch/arm/kvm/handle_exit.c
@@ -104,9 +104,9 @@ static exit_handle_fn arm_exit_handlers[] = {
 	[HSR_EC_WFI]		= kvm_handle_wfx,
 	[HSR_EC_CP15_32]	= kvm_handle_cp15_32,
 	[HSR_EC_CP15_64]	= kvm_handle_cp15_64,
-	[HSR_EC_CP14_MR]	= kvm_handle_cp14_access,
+	[HSR_EC_CP14_MR]	= kvm_handle_cp14_32,
 	[HSR_EC_CP14_LS]	= kvm_handle_cp14_load_store,
-	[HSR_EC_CP14_64]	= kvm_handle_cp14_access,
+	[HSR_EC_CP14_64]	= kvm_handle_cp14_64,
 	[HSR_EC_CP_0_13]	= kvm_handle_cp_0_13_access,
 	[HSR_EC_CP10_ID]	= kvm_handle_cp10_id,
 	[HSR_EC_SVC_HYP]	= handle_svc_hyp,
diff --git a/arch/arm/kvm/interrupts.S b/arch/arm/kvm/interrupts.S
index 568494d..48333ff 100644
--- a/arch/arm/kvm/interrupts.S
+++ b/arch/arm/kvm/interrupts.S
@@ -112,9 +112,9 @@ ENTRY(__kvm_vcpu_run)
 	restore_vgic_state
 	restore_timer_state
 
-	@ Store hardware CP15 state and load guest state
-	read_cp15_state store_to_vcpu = 0
-	write_cp15_state read_from_vcpu = 1
+	@ Store hardware CP14/CP15 state and load guest state
+	read_coproc_state store_to_vcpu = 0
+	write_coproc_state read_from_vcpu = 1
 
 	@ If the host kernel has not been configured with VFPv3 support,
 	@ then it is safer if we deny guests from using it as well.
@@ -199,9 +199,9 @@ after_vfp_restore:
 	mrc	p15, 0, r2, c0, c0, 5
 	mcr	p15, 4, r2, c0, c0, 5
 
-	@ Store guest CP15 state and restore host state
-	read_cp15_state store_to_vcpu = 1
-	write_cp15_state read_from_vcpu = 0
+	@ Store guest CP14/CP15 state and restore host state
+	read_coproc_state store_to_vcpu = 1
+	write_coproc_state read_from_vcpu = 0
 
 	save_timer_state
 	save_vgic_state
diff --git a/arch/arm/kvm/interrupts_head.S b/arch/arm/kvm/interrupts_head.S
index 702740d..7c4075c 100644
--- a/arch/arm/kvm/interrupts_head.S
+++ b/arch/arm/kvm/interrupts_head.S
@@ -239,7 +239,7 @@ vcpu	.req	r0		@ vcpu pointer always in r0
 	save_guest_regs_mode irq, #VCPU_IRQ_REGS
 .endm
 
-/* Reads cp15 registers from hardware and stores them in memory
+/* Reads cp14/cp15 registers from hardware and stores them in memory
  * @store_to_vcpu: If 0, registers are written in-order to the stack,
  * 		   otherwise to the VCPU struct pointed to by vcpup
  *
@@ -247,7 +247,12 @@ vcpu	.req	r0		@ vcpu pointer always in r0
  *
  * Clobbers r2 - r12
  */
-.macro read_cp15_state store_to_vcpu
+.macro read_coproc_state store_to_vcpu
+	.if \store_to_vcpu == 0
+	mrc	p14, 0, r2, c0, c1, 0	@ DBGDSCR
+	push	{r2}
+	.endif
+
 	mrc	p15, 0, r2, c1, c0, 0	@ SCTLR
 	mrc	p15, 0, r3, c1, c0, 2	@ CPACR
 	mrc	p15, 0, r4, c2, c0, 2	@ TTBCR
@@ -325,7 +330,7 @@ vcpu	.req	r0		@ vcpu pointer always in r0
  *
  * Assumes vcpu pointer in vcpu reg
  */
-.macro write_cp15_state read_from_vcpu
+.macro write_coproc_state read_from_vcpu
 	.if \read_from_vcpu == 0
 	pop	{r2,r4-r7}
 	.else
@@ -394,6 +399,14 @@ vcpu	.req	r0		@ vcpu pointer always in r0
 	mcr	p15, 0, r10, c10, c2, 0	@ PRRR
 	mcr	p15, 0, r11, c10, c2, 1	@ NMRR
 	mcr	p15, 2, r12, c0, c0, 0	@ CSSELR
+
+	.if \read_from_vcpu == 0
+	pop	{r2}
+	.else
+	mov	r2, #0
+	.endif
+
+	mcr	p14, 0, r2, c0, c2, 2	@ DBGDSCR
 .endm
 
 /*
@@ -620,7 +633,7 @@ ARM_BE8(rev	r6, r6  )
  * (hardware reset value is 0) */
 .macro set_hdcr operation
 	mrc	p15, 4, r2, c1, c1, 1
-	ldr	r3, =(HDCR_TPM|HDCR_TPMCR)
+	ldr	r3, =(HDCR_TPM|HDCR_TPMCR|HDCR_TDRA|HDCR_TDOSA|HDCR_TDA)
 	.if \operation == vmentry
 	orr	r2, r2, r3		@ Trap some perfmon accesses
 	.else
-- 
1.7.12.4



From zhichao.huang at linaro.org  Mon Aug 10 06:25:54 2015
From: zhichao.huang at linaro.org (Zhichao Huang)
Date: Mon, 10 Aug 2015 21:25:54 +0800
Subject: [PATCH v4 02/15] KVM: arm: rename pm_fake handler to trap_raz_wi
In-Reply-To: <1439213167-8988-1-git-send-email-zhichao.huang@linaro.org>
References: <1439213167-8988-1-git-send-email-zhichao.huang@linaro.org>
Message-ID: <1439213167-8988-3-git-send-email-zhichao.huang@linaro.org>

pm_fake doesn't quite describe what the handler does (ignoring writes
and returning 0 for reads).

As we're about to use it (a lot) in a different context, rename it
with a (admitedly cryptic) name that make sense for all users.

Signed-off-by: Zhichao Huang <zhichao.huang at linaro.org>
Reviewed-by: Alex Bennee <alex.bennee at linaro.org>
Acked-by: Christoffer Dall <christoffer.dall at linaro.org>
---
 arch/arm/kvm/coproc.c | 32 ++++++++++++++++----------------
 1 file changed, 16 insertions(+), 16 deletions(-)

diff --git a/arch/arm/kvm/coproc.c b/arch/arm/kvm/coproc.c
index a885cfe..4db571d 100644
--- a/arch/arm/kvm/coproc.c
+++ b/arch/arm/kvm/coproc.c
@@ -229,7 +229,7 @@ bool access_vm_reg(struct kvm_vcpu *vcpu,
  * must always support PMCCNTR (the cycle counter): we just RAZ/WI for
  * all PM registers, which doesn't crash the guest kernel at least.
  */
-static bool pm_fake(struct kvm_vcpu *vcpu,
+static bool trap_raz_wi(struct kvm_vcpu *vcpu,
 		    const struct coproc_params *p,
 		    const struct coproc_reg *r)
 {
@@ -239,19 +239,19 @@ static bool pm_fake(struct kvm_vcpu *vcpu,
 		return read_zero(vcpu, p);
 }
 
-#define access_pmcr pm_fake
-#define access_pmcntenset pm_fake
-#define access_pmcntenclr pm_fake
-#define access_pmovsr pm_fake
-#define access_pmselr pm_fake
-#define access_pmceid0 pm_fake
-#define access_pmceid1 pm_fake
-#define access_pmccntr pm_fake
-#define access_pmxevtyper pm_fake
-#define access_pmxevcntr pm_fake
-#define access_pmuserenr pm_fake
-#define access_pmintenset pm_fake
-#define access_pmintenclr pm_fake
+#define access_pmcr trap_raz_wi
+#define access_pmcntenset trap_raz_wi
+#define access_pmcntenclr trap_raz_wi
+#define access_pmovsr trap_raz_wi
+#define access_pmselr trap_raz_wi
+#define access_pmceid0 trap_raz_wi
+#define access_pmceid1 trap_raz_wi
+#define access_pmccntr trap_raz_wi
+#define access_pmxevtyper trap_raz_wi
+#define access_pmxevcntr trap_raz_wi
+#define access_pmuserenr trap_raz_wi
+#define access_pmintenset trap_raz_wi
+#define access_pmintenclr trap_raz_wi
 
 /* Architected CP15 registers.
  * CRn denotes the primary register number, but is copied to the CRm in the
@@ -478,7 +478,7 @@ static int kvm_handle_cp_64(struct kvm_vcpu *vcpu, struct kvm_run *run,
 		return emulate_cp15(vcpu, &params);
 
 	/* raz_wi cp14 */
-	(void)pm_fake(vcpu, &params, NULL);
+	(void)trap_raz_wi(vcpu, &params, NULL);
 
 	/* handled */
 	kvm_skip_instr(vcpu, kvm_vcpu_trap_il_is32bit(vcpu));
@@ -534,7 +534,7 @@ static int kvm_handle_cp_32(struct kvm_vcpu *vcpu, struct kvm_run *run,
 		return emulate_cp15(vcpu, &params);
 
 	/* raz_wi cp14 */
-	(void)pm_fake(vcpu, &params, NULL);
+	(void)trap_raz_wi(vcpu, &params, NULL);
 
 	/* handled */
 	kvm_skip_instr(vcpu, kvm_vcpu_trap_il_is32bit(vcpu));
-- 
1.7.12.4



From zhichao.huang at linaro.org  Mon Aug 10 06:25:56 2015
From: zhichao.huang at linaro.org (Zhichao Huang)
Date: Mon, 10 Aug 2015 21:25:56 +0800
Subject: [PATCH v4 04/15] KVM: arm: common infrastructure for handling AArch32
 CP14/CP15
In-Reply-To: <1439213167-8988-1-git-send-email-zhichao.huang@linaro.org>
References: <1439213167-8988-1-git-send-email-zhichao.huang@linaro.org>
Message-ID: <1439213167-8988-5-git-send-email-zhichao.huang@linaro.org>

As we're about to trap a bunch of CP14 registers, let's rework
the CP15 handling so it can be generalized and work with multiple
tables.

We stop trapping access here, because we haven't finished our trap
handlers. We will enable trapping agian until everything is OK.

Signed-off-by: Zhichao Huang <zhichao.huang at linaro.org>
---
 arch/arm/kvm/coproc.c          | 168 ++++++++++++++++++++++++++---------------
 arch/arm/kvm/interrupts_head.S |   2 +-
 2 files changed, 110 insertions(+), 60 deletions(-)

diff --git a/arch/arm/kvm/coproc.c b/arch/arm/kvm/coproc.c
index 4db571d..d23395b 100644
--- a/arch/arm/kvm/coproc.c
+++ b/arch/arm/kvm/coproc.c
@@ -375,6 +375,9 @@ static const struct coproc_reg cp15_regs[] = {
 	{ CRn(15), CRm( 0), Op1( 4), Op2( 0), is32, access_cbar},
 };
 
+static const struct coproc_reg cp14_regs[] = {
+};
+
 /* Target specific emulation tables */
 static struct kvm_coproc_target_table *target_tables[KVM_ARM_NUM_TARGETS];
 
@@ -424,43 +427,75 @@ static const struct coproc_reg *find_reg(const struct coproc_params *params,
 	return NULL;
 }
 
-static int emulate_cp15(struct kvm_vcpu *vcpu,
-			const struct coproc_params *params)
+/*
+ * emulate_cp --  tries to match a cp14/cp15 access in a handling table,
+ *                and call the corresponding trap handler.
+ *
+ * @params: pointer to the descriptor of the access
+ * @table: array of trap descriptors
+ * @num: size of the trap descriptor array
+ *
+ * Return 0 if the access has been handled, and -1 if not.
+ */
+static int emulate_cp(struct kvm_vcpu *vcpu,
+			const struct coproc_params *params,
+			const struct coproc_reg *table,
+			size_t num)
 {
-	size_t num;
-	const struct coproc_reg *table, *r;
-
-	trace_kvm_emulate_cp15_imp(params->Op1, params->Rt1, params->CRn,
-				   params->CRm, params->Op2, params->is_write);
+	const struct coproc_reg *r;
 
-	table = get_target_table(vcpu->arch.target, &num);
+	if (!table)
+		return -1;	/* Not handled */
 
-	/* Search target-specific then generic table. */
 	r = find_reg(params, table, num);
-	if (!r)
-		r = find_reg(params, cp15_regs, ARRAY_SIZE(cp15_regs));
 
-	if (likely(r)) {
+	if (r) {
 		/* If we don't have an accessor, we should never get here! */
 		BUG_ON(!r->access);
 
 		if (likely(r->access(vcpu, params, r))) {
 			/* Skip instruction, since it was emulated */
 			kvm_skip_instr(vcpu, kvm_vcpu_trap_il_is32bit(vcpu));
-			return 1;
 		}
-		/* If access function fails, it should complain. */
-	} else {
-		kvm_err("Unsupported guest CP15 access at: %08lx\n",
-			*vcpu_pc(vcpu));
-		print_cp_instr(params);
+
+		/* Handled */
+		return 0;
 	}
+
+	/* Not handled */
+	return -1;
+}
+
+static void unhandled_cp_access(struct kvm_vcpu *vcpu,
+				const struct coproc_params *params)
+{
+	u8 hsr_ec = kvm_vcpu_trap_get_class(vcpu);
+	int cp;
+
+	switch (hsr_ec) {
+	case HSR_EC_CP15_32:
+	case HSR_EC_CP15_64:
+		cp = 15;
+		break;
+	case HSR_EC_CP14_MR:
+	case HSR_EC_CP14_64:
+		cp = 14;
+		break;
+	default:
+		WARN_ON((cp = -1));
+	}
+
+	kvm_err("Unsupported guest CP%d access at: %08lx\n",
+		cp, *vcpu_pc(vcpu));
+	print_cp_instr(params);
 	kvm_inject_undefined(vcpu);
-	return 1;
 }
 
-static int kvm_handle_cp_64(struct kvm_vcpu *vcpu, struct kvm_run *run,
-			    bool cp15)
+int kvm_handle_cp_64(struct kvm_vcpu *vcpu,
+			const struct coproc_reg *global,
+			size_t nr_global,
+			const struct coproc_reg *target_specific,
+			size_t nr_specific)
 {
 	struct coproc_params params;
 
@@ -474,37 +509,15 @@ static int kvm_handle_cp_64(struct kvm_vcpu *vcpu, struct kvm_run *run,
 	params.Rt2 = (kvm_vcpu_get_hsr(vcpu) >> 10) & 0xf;
 	params.CRm = 0;
 
-	if (cp15)
-		return emulate_cp15(vcpu, &params);
+	if (!emulate_cp(vcpu, &params, target_specific, nr_specific))
+		return 1;
+	if (!emulate_cp(vcpu, &params, global, nr_global))
+		return 1;
 
-	/* raz_wi cp14 */
-	(void)trap_raz_wi(vcpu, &params, NULL);
-
-	/* handled */
-	kvm_skip_instr(vcpu, kvm_vcpu_trap_il_is32bit(vcpu));
+	unhandled_cp_access(vcpu, &params);
 	return 1;
 }
 
-/**
- * kvm_handle_cp15_64 -- handles a mrrc/mcrr trap on a guest CP15 access
- * @vcpu: The VCPU pointer
- * @run:  The kvm_run struct
- */
-int kvm_handle_cp15_64(struct kvm_vcpu *vcpu, struct kvm_run *run)
-{
-	return kvm_handle_cp_64(vcpu, run, 1);
-}
-
-/**
- * kvm_handle_cp14_64 -- handles a mrrc/mcrr trap on a guest CP14 access
- * @vcpu: The VCPU pointer
- * @run:  The kvm_run struct
- */
-int kvm_handle_cp14_64(struct kvm_vcpu *vcpu, struct kvm_run *run)
-{
-	return kvm_handle_cp_64(vcpu, run, 0);
-}
-
 static void reset_coproc_regs(struct kvm_vcpu *vcpu,
 			      const struct coproc_reg *table, size_t num)
 {
@@ -515,8 +528,11 @@ static void reset_coproc_regs(struct kvm_vcpu *vcpu,
 			table[i].reset(vcpu, &table[i]);
 }
 
-static int kvm_handle_cp_32(struct kvm_vcpu *vcpu, struct kvm_run *run,
-			      bool cp15)
+int kvm_handle_cp_32(struct kvm_vcpu *vcpu,
+			const struct coproc_reg *global,
+			size_t nr_global,
+			const struct coproc_reg *target_specific,
+			size_t nr_specific)
 {
 	struct coproc_params params;
 
@@ -530,25 +546,57 @@ static int kvm_handle_cp_32(struct kvm_vcpu *vcpu, struct kvm_run *run,
 	params.Op2 = (kvm_vcpu_get_hsr(vcpu) >> 17) & 0x7;
 	params.Rt2 = 0;
 
-	if (cp15)
-		return emulate_cp15(vcpu, &params);
-
-	/* raz_wi cp14 */
-	(void)trap_raz_wi(vcpu, &params, NULL);
+	if (!emulate_cp(vcpu, &params, target_specific, nr_specific))
+		return 1;
+	if (!emulate_cp(vcpu, &params, global, nr_global))
+		return 1;
 
-	/* handled */
-	kvm_skip_instr(vcpu, kvm_vcpu_trap_il_is32bit(vcpu));
+	unhandled_cp_access(vcpu, &params);
 	return 1;
 }
 
 /**
+ * kvm_handle_cp15_64 -- handles a mrrc/mcrr trap on a guest CP15 access
+ * @vcpu: The VCPU pointer
+ * @run:  The kvm_run struct
+ */
+int kvm_handle_cp15_64(struct kvm_vcpu *vcpu, struct kvm_run *run)
+{
+	const struct coproc_reg *target_specific;
+	size_t num;
+
+	target_specific = get_target_table(vcpu->arch.target, &num);
+	return kvm_handle_cp_64(vcpu,
+				cp15_regs, ARRAY_SIZE(cp15_regs),
+				target_specific, num);
+}
+
+/**
  * kvm_handle_cp15_32 -- handles a mrc/mcr trap on a guest CP15 access
  * @vcpu: The VCPU pointer
  * @run:  The kvm_run struct
  */
 int kvm_handle_cp15_32(struct kvm_vcpu *vcpu, struct kvm_run *run)
 {
-	return kvm_handle_cp_32(vcpu, run, 1);
+	const struct coproc_reg *target_specific;
+	size_t num;
+
+	target_specific = get_target_table(vcpu->arch.target, &num);
+	return kvm_handle_cp_32(vcpu,
+				cp15_regs, ARRAY_SIZE(cp15_regs),
+				target_specific, num);
+}
+
+/**
+ * kvm_handle_cp14_64 -- handles a mrrc/mcrr trap on a guest CP14 access
+ * @vcpu: The VCPU pointer
+ * @run:  The kvm_run struct
+ */
+int kvm_handle_cp14_64(struct kvm_vcpu *vcpu, struct kvm_run *run)
+{
+	return kvm_handle_cp_64(vcpu,
+				cp14_regs, ARRAY_SIZE(cp14_regs),
+				NULL, 0);
 }
 
 /**
@@ -558,7 +606,9 @@ int kvm_handle_cp15_32(struct kvm_vcpu *vcpu, struct kvm_run *run)
  */
 int kvm_handle_cp14_32(struct kvm_vcpu *vcpu, struct kvm_run *run)
 {
-	return kvm_handle_cp_32(vcpu, run, 0);
+	return kvm_handle_cp_32(vcpu,
+				cp14_regs, ARRAY_SIZE(cp14_regs),
+				NULL, 0);
 }
 
 /******************************************************************************
diff --git a/arch/arm/kvm/interrupts_head.S b/arch/arm/kvm/interrupts_head.S
index 7c4075c..7ac5e51 100644
--- a/arch/arm/kvm/interrupts_head.S
+++ b/arch/arm/kvm/interrupts_head.S
@@ -633,7 +633,7 @@ ARM_BE8(rev	r6, r6  )
  * (hardware reset value is 0) */
 .macro set_hdcr operation
 	mrc	p15, 4, r2, c1, c1, 1
-	ldr	r3, =(HDCR_TPM|HDCR_TPMCR|HDCR_TDRA|HDCR_TDOSA|HDCR_TDA)
+	ldr	r3, =(HDCR_TPM|HDCR_TPMCR)
 	.if \operation == vmentry
 	orr	r2, r2, r3		@ Trap some perfmon accesses
 	.else
-- 
1.7.12.4



From zhichao.huang at linaro.org  Mon Aug 10 06:25:58 2015
From: zhichao.huang at linaro.org (Zhichao Huang)
Date: Mon, 10 Aug 2015 21:25:58 +0800
Subject: [PATCH v4 06/15] KVM: arm: add trap handlers for 32-bit debug
 registers
In-Reply-To: <1439213167-8988-1-git-send-email-zhichao.huang@linaro.org>
References: <1439213167-8988-1-git-send-email-zhichao.huang@linaro.org>
Message-ID: <1439213167-8988-7-git-send-email-zhichao.huang@linaro.org>

Add handlers for all the 32-bit debug registers.

Signed-off-by: Zhichao Huang <zhichao.huang at linaro.org>
---
 arch/arm/include/asm/kvm_asm.h  |  12 ++++
 arch/arm/include/asm/kvm_host.h |   3 +
 arch/arm/kernel/asm-offsets.c   |   1 +
 arch/arm/kvm/coproc.c           | 124 ++++++++++++++++++++++++++++++++++++++++
 4 files changed, 140 insertions(+)

diff --git a/arch/arm/include/asm/kvm_asm.h b/arch/arm/include/asm/kvm_asm.h
index 194c91b..7443a3a 100644
--- a/arch/arm/include/asm/kvm_asm.h
+++ b/arch/arm/include/asm/kvm_asm.h
@@ -52,6 +52,18 @@
 #define c10_AMAIR1	30	/* Auxilary Memory Attribute Indirection Reg1 */
 #define NR_CP15_REGS	31	/* Number of regs (incl. invalid) */
 
+/* 0 is reserved as an invalid value. */
+#define cp14_DBGBVR0	1	/* Debug Breakpoint Control Registers (0-15) */
+#define cp14_DBGBVR15	16
+#define cp14_DBGBCR0	17	/* Debug Breakpoint Value Registers (0-15) */
+#define cp14_DBGBCR15	32
+#define cp14_DBGWVR0	33	/* Debug Watchpoint Control Registers (0-15) */
+#define cp14_DBGWVR15	48
+#define cp14_DBGWCR0	49	/* Debug Watchpoint Value Registers (0-15) */
+#define cp14_DBGWCR15	64
+#define cp14_DBGDSCRext	65	/* Debug Status and Control external */
+#define NR_CP14_REGS	66	/* Number of regs (incl. invalid) */
+
 #define ARM_EXCEPTION_RESET	  0
 #define ARM_EXCEPTION_UNDEFINED   1
 #define ARM_EXCEPTION_SOFTWARE    2
diff --git a/arch/arm/include/asm/kvm_host.h b/arch/arm/include/asm/kvm_host.h
index e896d2c..63ac005 100644
--- a/arch/arm/include/asm/kvm_host.h
+++ b/arch/arm/include/asm/kvm_host.h
@@ -124,6 +124,9 @@ struct kvm_vcpu_arch {
 	struct vgic_cpu vgic_cpu;
 	struct arch_timer_cpu timer_cpu;
 
+	/* System control coprocessor (cp14) */
+	u32 cp14[NR_CP14_REGS];
+
 	/*
 	 * Anything that is not used directly from assembly code goes
 	 * here.
diff --git a/arch/arm/kernel/asm-offsets.c b/arch/arm/kernel/asm-offsets.c
index 871b826..9158de0 100644
--- a/arch/arm/kernel/asm-offsets.c
+++ b/arch/arm/kernel/asm-offsets.c
@@ -172,6 +172,7 @@ int main(void)
 #ifdef CONFIG_KVM_ARM_HOST
   DEFINE(VCPU_KVM,		offsetof(struct kvm_vcpu, kvm));
   DEFINE(VCPU_MIDR,		offsetof(struct kvm_vcpu, arch.midr));
+  DEFINE(VCPU_CP14,		offsetof(struct kvm_vcpu, arch.cp14));
   DEFINE(VCPU_CP15,		offsetof(struct kvm_vcpu, arch.cp15));
   DEFINE(VCPU_VFP_GUEST,	offsetof(struct kvm_vcpu, arch.vfp_guest));
   DEFINE(VCPU_VFP_HOST,		offsetof(struct kvm_vcpu, arch.host_cpu_context));
diff --git a/arch/arm/kvm/coproc.c b/arch/arm/kvm/coproc.c
index 16d5f69..b3627f0 100644
--- a/arch/arm/kvm/coproc.c
+++ b/arch/arm/kvm/coproc.c
@@ -220,6 +220,47 @@ bool access_vm_reg(struct kvm_vcpu *vcpu,
 	return true;
 }
 
+static bool trap_debug32(struct kvm_vcpu *vcpu,
+			const struct coproc_params *p,
+			const struct coproc_reg *r)
+{
+	if (p->is_write)
+		vcpu->arch.cp14[r->reg] = *vcpu_reg(vcpu, p->Rt1);
+	else
+		*vcpu_reg(vcpu, p->Rt1) = vcpu->arch.cp14[r->reg];
+
+	return true;
+}
+
+/* DBGIDR (RO) Debug ID */
+static bool trap_dbgidr(struct kvm_vcpu *vcpu,
+			const struct coproc_params *p,
+			const struct coproc_reg *r)
+{
+	u32 val;
+
+	if (p->is_write)
+		return ignore_write(vcpu, p);
+
+	ARM_DBG_READ(c0, c0, 0, val);
+	*vcpu_reg(vcpu, p->Rt1) = val;
+
+	return true;
+}
+
+/* DBGDSCRint (RO) Debug Status and Control Register */
+static bool trap_dbgdscr(struct kvm_vcpu *vcpu,
+			const struct coproc_params *p,
+			const struct coproc_reg *r)
+{
+	if (p->is_write)
+		return ignore_write(vcpu, p);
+
+	*vcpu_reg(vcpu, p->Rt1) = vcpu->arch.cp14[r->reg];
+
+	return true;
+}
+
 /*
  * We could trap ID_DFR0 and tell the guest we don't support performance
  * monitoring.  Unfortunately the patch to make the kernel check ID_DFR0 was
@@ -375,7 +416,90 @@ static const struct coproc_reg cp15_regs[] = {
 	{ CRn(15), CRm( 0), Op1( 4), Op2( 0), is32, access_cbar},
 };
 
+#define DBG_BCR_BVR_WCR_WVR(n)					\
+	/* DBGBVRn */						\
+	{ CRn( 0), CRm((n)), Op1( 0), Op2( 4), is32,		\
+	  trap_debug32,	reset_val, (cp14_DBGBVR0 + (n)), 0 },	\
+	/* DBGBCRn */						\
+	{ CRn( 0), CRm((n)), Op1( 0), Op2( 5), is32,		\
+	  trap_debug32,	reset_val, (cp14_DBGBCR0 + (n)), 0 },	\
+	/* DBGWVRn */						\
+	{ CRn( 0), CRm((n)), Op1( 0), Op2( 6), is32,		\
+	  trap_debug32,	reset_val, (cp14_DBGWVR0 + (n)), 0 },	\
+	/* DBGWCRn */						\
+	{ CRn( 0), CRm((n)), Op1( 0), Op2( 7), is32,		\
+	  trap_debug32,	reset_val, (cp14_DBGWCR0 + (n)), 0 }
+
+/* No OS DBGBXVR machanism implemented. */
+#define DBGBXVR(n)						\
+	{ CRn( 1), CRm((n)), Op1( 0), Op2( 1), is32, trap_raz_wi }
+
+/*
+ * Architected CP14 registers.
+ *
+ * Trapped cp14 registers. We generally ignore most of the external
+ * debug, on the principle that they don't really make sense to a
+ * guest. Revisit this one day, should this principle change.
+ */
 static const struct coproc_reg cp14_regs[] = {
+	/* DBGIDR */
+	{ CRn( 0), CRm( 0), Op1( 0), Op2( 0), is32, trap_dbgidr},
+	/* DBGDTRRXext */
+	{ CRn( 0), CRm( 0), Op1( 0), Op2( 2), is32, trap_raz_wi },
+	DBG_BCR_BVR_WCR_WVR(0),
+	/* DBGDSCRint */
+	{ CRn( 0), CRm( 1), Op1( 0), Op2( 0), is32, trap_dbgdscr,
+				NULL, cp14_DBGDSCRext },
+	DBG_BCR_BVR_WCR_WVR(1),
+	/* DBGDSCRext */
+	{ CRn( 0), CRm( 2), Op1( 0), Op2( 2), is32, trap_debug32,
+				reset_val, cp14_DBGDSCRext, 0 },
+	DBG_BCR_BVR_WCR_WVR(2),
+	/* DBGDTRTXext */
+	{ CRn( 0), CRm( 3), Op1( 0), Op2( 2), is32, trap_raz_wi },
+	DBG_BCR_BVR_WCR_WVR(3),
+	DBG_BCR_BVR_WCR_WVR(4),
+	/* DBGDTR[RT]Xint */
+	{ CRn( 0), CRm( 5), Op1( 0), Op2( 0), is32, trap_raz_wi },
+	DBG_BCR_BVR_WCR_WVR(5),
+	DBG_BCR_BVR_WCR_WVR(6),
+	/* DBGVCR */
+	{ CRn( 0), CRm( 7), Op1( 0), Op2( 0), is32, trap_debug32 },
+	DBG_BCR_BVR_WCR_WVR(7),
+	DBG_BCR_BVR_WCR_WVR(8),
+	DBG_BCR_BVR_WCR_WVR(9),
+	DBG_BCR_BVR_WCR_WVR(10),
+	DBG_BCR_BVR_WCR_WVR(11),
+	DBG_BCR_BVR_WCR_WVR(12),
+	DBG_BCR_BVR_WCR_WVR(13),
+	DBG_BCR_BVR_WCR_WVR(14),
+	DBG_BCR_BVR_WCR_WVR(15),
+
+	DBGBXVR(0),
+	/* DBGOSLAR */
+	{ CRn( 1), CRm( 0), Op1( 0), Op2( 4), is32, trap_raz_wi },
+	DBGBXVR(1),
+	/* DBGOSLSR */
+	{ CRn( 1), CRm( 1), Op1( 0), Op2( 4), is32, trap_raz_wi },
+	DBGBXVR(2),
+	DBGBXVR(3),
+	/* DBGOSDLRd */
+	{ CRn( 1), CRm( 3), Op1( 0), Op2( 4), is32, trap_raz_wi },
+	DBGBXVR(4),
+	DBGBXVR(5),
+	/* DBGPRSRa */
+	{ CRn( 1), CRm( 5), Op1( 0), Op2( 4), is32, trap_raz_wi },
+
+	DBGBXVR(6),
+	DBGBXVR(7),
+	DBGBXVR(8),
+	DBGBXVR(9),
+	DBGBXVR(10),
+	DBGBXVR(11),
+	DBGBXVR(12),
+	DBGBXVR(13),
+	DBGBXVR(14),
+	DBGBXVR(15),
 };
 
 /* Target specific emulation tables */
-- 
1.7.12.4



From zhichao.huang at linaro.org  Mon Aug 10 06:26:00 2015
From: zhichao.huang at linaro.org (Zhichao Huang)
Date: Mon, 10 Aug 2015 21:26:00 +0800
Subject: [PATCH v4 08/15] KVM: arm: add a trace event for cp14 traps
In-Reply-To: <1439213167-8988-1-git-send-email-zhichao.huang@linaro.org>
References: <1439213167-8988-1-git-send-email-zhichao.huang@linaro.org>
Message-ID: <1439213167-8988-9-git-send-email-zhichao.huang@linaro.org>

There are too many cp15 traps, so we don't reuse the cp15 trace event
but add a new trace event to trace the access of debug registers.

Signed-off-by: Zhichao Huang <zhichao.huang at linaro.org>
Acked-by: Christoffer Dall <christoffer.dall at linaro.org>
---
 arch/arm/kvm/coproc.c | 14 ++++++++++++++
 arch/arm/kvm/trace.h  | 30 ++++++++++++++++++++++++++++++
 2 files changed, 44 insertions(+)

diff --git a/arch/arm/kvm/coproc.c b/arch/arm/kvm/coproc.c
index 2164f4e..d15b250 100644
--- a/arch/arm/kvm/coproc.c
+++ b/arch/arm/kvm/coproc.c
@@ -643,6 +643,13 @@ int kvm_handle_cp_64(struct kvm_vcpu *vcpu,
 	params.Rt2 = (kvm_vcpu_get_hsr(vcpu) >> 10) & 0xf;
 	params.CRm = 0;
 
+	if (global == cp14_regs)
+		trace_kvm_emulate_cp14_imp(params.Op1, params.Rt1, params.CRn,
+			params.CRm, params.Op2, params.is_write);
+	else
+		trace_kvm_emulate_cp15_imp(params.Op1, params.Rt1, params.CRn,
+			params.CRm, params.Op2, params.is_write);
+
 	if (!emulate_cp(vcpu, &params, target_specific, nr_specific))
 		return 1;
 	if (!emulate_cp(vcpu, &params, global, nr_global))
@@ -680,6 +687,13 @@ int kvm_handle_cp_32(struct kvm_vcpu *vcpu,
 	params.Op2 = (kvm_vcpu_get_hsr(vcpu) >> 17) & 0x7;
 	params.Rt2 = 0;
 
+	if (global == cp14_regs)
+		trace_kvm_emulate_cp14_imp(params.Op1, params.Rt1, params.CRn,
+			params.CRm, params.Op2, params.is_write);
+	else
+		trace_kvm_emulate_cp15_imp(params.Op1, params.Rt1, params.CRn,
+			params.CRm, params.Op2, params.is_write);
+
 	if (!emulate_cp(vcpu, &params, target_specific, nr_specific))
 		return 1;
 	if (!emulate_cp(vcpu, &params, global, nr_global))
diff --git a/arch/arm/kvm/trace.h b/arch/arm/kvm/trace.h
index 0ec3539..988da03 100644
--- a/arch/arm/kvm/trace.h
+++ b/arch/arm/kvm/trace.h
@@ -159,6 +159,36 @@ TRACE_EVENT(kvm_emulate_cp15_imp,
 			__entry->CRm, __entry->Op2)
 );
 
+/* Architecturally implementation defined CP14 register access */
+TRACE_EVENT(kvm_emulate_cp14_imp,
+	TP_PROTO(unsigned long Op1, unsigned long Rt1, unsigned long CRn,
+		 unsigned long CRm, unsigned long Op2, bool is_write),
+	TP_ARGS(Op1, Rt1, CRn, CRm, Op2, is_write),
+
+	TP_STRUCT__entry(
+		__field(	unsigned int,	Op1		)
+		__field(	unsigned int,	Rt1		)
+		__field(	unsigned int,	CRn		)
+		__field(	unsigned int,	CRm		)
+		__field(	unsigned int,	Op2		)
+		__field(	bool,		is_write	)
+	),
+
+	TP_fast_assign(
+		__entry->is_write		= is_write;
+		__entry->Op1			= Op1;
+		__entry->Rt1			= Rt1;
+		__entry->CRn			= CRn;
+		__entry->CRm			= CRm;
+		__entry->Op2			= Op2;
+	),
+
+	TP_printk("Implementation defined CP14: %s\tp14, %u, r%u, c%u, c%u, %u",
+			(__entry->is_write) ? "mcr" : "mrc",
+			__entry->Op1, __entry->Rt1, __entry->CRn,
+			__entry->CRm, __entry->Op2)
+);
+
 TRACE_EVENT(kvm_wfx,
 	TP_PROTO(unsigned long vcpu_pc, bool is_wfe),
 	TP_ARGS(vcpu_pc, is_wfe),
-- 
1.7.12.4



From zhichao.huang at linaro.org  Mon Aug 10 06:25:55 2015
From: zhichao.huang at linaro.org (Zhichao Huang)
Date: Mon, 10 Aug 2015 21:25:55 +0800
Subject: [PATCH v4 03/15] KVM: arm: enable to use the ARM_DSCR_MDBGEN macro
 from KVM assembly code
In-Reply-To: <1439213167-8988-1-git-send-email-zhichao.huang@linaro.org>
References: <1439213167-8988-1-git-send-email-zhichao.huang@linaro.org>
Message-ID: <1439213167-8988-4-git-send-email-zhichao.huang@linaro.org>

Add #ifndef __ASSEMBLY__ in hw_breakpoint.h, in order to use
the ARM_DSCR_MDBGEN macro from KVM assembly code.

Signed-off-by: Zhichao Huang <zhichao.huang at linaro.org>
Reviewed-by: Alex Bennee <alex.bennee at linaro.org>
Acked-by: Christoffer Dall <christoffer.dall at linaro.org>
---
 arch/arm/include/asm/hw_breakpoint.h | 54 +++++++++++++++++++-----------------
 1 file changed, 29 insertions(+), 25 deletions(-)

diff --git a/arch/arm/include/asm/hw_breakpoint.h b/arch/arm/include/asm/hw_breakpoint.h
index 8e427c7..f2f4c61 100644
--- a/arch/arm/include/asm/hw_breakpoint.h
+++ b/arch/arm/include/asm/hw_breakpoint.h
@@ -3,6 +3,8 @@
 
 #ifdef __KERNEL__
 
+#ifndef __ASSEMBLY__
+
 struct task_struct;
 
 #ifdef CONFIG_HAVE_HW_BREAKPOINT
@@ -44,6 +46,33 @@ static inline void decode_ctrl_reg(u32 reg,
 	ctrl->mismatch	= reg & 0x1;
 }
 
+struct notifier_block;
+struct perf_event;
+struct pmu;
+
+extern struct pmu perf_ops_bp;
+extern int arch_bp_generic_fields(struct arch_hw_breakpoint_ctrl ctrl,
+				  int *gen_len, int *gen_type);
+extern int arch_check_bp_in_kernelspace(struct perf_event *bp);
+extern int arch_validate_hwbkpt_settings(struct perf_event *bp);
+extern int hw_breakpoint_exceptions_notify(struct notifier_block *unused,
+					   unsigned long val, void *data);
+
+extern u8 arch_get_debug_arch(void);
+extern u8 arch_get_max_wp_len(void);
+extern void clear_ptrace_hw_breakpoint(struct task_struct *tsk);
+
+int arch_install_hw_breakpoint(struct perf_event *bp);
+void arch_uninstall_hw_breakpoint(struct perf_event *bp);
+void hw_breakpoint_pmu_read(struct perf_event *bp);
+int hw_breakpoint_slots(int type);
+
+#else
+static inline void clear_ptrace_hw_breakpoint(struct task_struct *tsk) {}
+
+#endif	/* CONFIG_HAVE_HW_BREAKPOINT */
+#endif  /* __ASSEMBLY */
+
 /* Debug architecture numbers. */
 #define ARM_DEBUG_ARCH_RESERVED	0	/* In case of ptrace ABI updates. */
 #define ARM_DEBUG_ARCH_V6	1
@@ -110,30 +139,5 @@ static inline void decode_ctrl_reg(u32 reg,
 	asm volatile("mcr p14, 0, %0, " #N "," #M ", " #OP2 : : "r" (VAL));\
 } while (0)
 
-struct notifier_block;
-struct perf_event;
-struct pmu;
-
-extern struct pmu perf_ops_bp;
-extern int arch_bp_generic_fields(struct arch_hw_breakpoint_ctrl ctrl,
-				  int *gen_len, int *gen_type);
-extern int arch_check_bp_in_kernelspace(struct perf_event *bp);
-extern int arch_validate_hwbkpt_settings(struct perf_event *bp);
-extern int hw_breakpoint_exceptions_notify(struct notifier_block *unused,
-					   unsigned long val, void *data);
-
-extern u8 arch_get_debug_arch(void);
-extern u8 arch_get_max_wp_len(void);
-extern void clear_ptrace_hw_breakpoint(struct task_struct *tsk);
-
-int arch_install_hw_breakpoint(struct perf_event *bp);
-void arch_uninstall_hw_breakpoint(struct perf_event *bp);
-void hw_breakpoint_pmu_read(struct perf_event *bp);
-int hw_breakpoint_slots(int type);
-
-#else
-static inline void clear_ptrace_hw_breakpoint(struct task_struct *tsk) {}
-
-#endif	/* CONFIG_HAVE_HW_BREAKPOINT */
 #endif	/* __KERNEL__ */
 #endif	/* _ARM_HW_BREAKPOINT_H */
-- 
1.7.12.4



From zhichao.huang at linaro.org  Mon Aug 10 06:25:57 2015
From: zhichao.huang at linaro.org (Zhichao Huang)
Date: Mon, 10 Aug 2015 21:25:57 +0800
Subject: [PATCH v4 05/15] KVM: arm: check ordering of all system register
 tables
In-Reply-To: <1439213167-8988-1-git-send-email-zhichao.huang@linaro.org>
References: <1439213167-8988-1-git-send-email-zhichao.huang@linaro.org>
Message-ID: <1439213167-8988-6-git-send-email-zhichao.huang@linaro.org>

We now have multiple tables for the various system registers
we trap. Make sure we check the order of all of them, as it is
critical that we get the order right (been there, done that...).

Signed-off-by: Zhichao Huang <zhichao.huang at linaro.org>
Reviewed-by: Christoffer Dall <christoffer.dall at linaro.org>
---
 arch/arm/kvm/coproc.c | 26 +++++++++++++++++++++-----
 1 file changed, 21 insertions(+), 5 deletions(-)

diff --git a/arch/arm/kvm/coproc.c b/arch/arm/kvm/coproc.c
index d23395b..16d5f69 100644
--- a/arch/arm/kvm/coproc.c
+++ b/arch/arm/kvm/coproc.c
@@ -737,6 +737,9 @@ static struct coproc_reg invariant_cp15[] = {
 	{ CRn( 0), CRm( 0), Op1( 0), Op2( 3), is32, NULL, get_TLBTR },
 	{ CRn( 0), CRm( 0), Op1( 0), Op2( 6), is32, NULL, get_REVIDR },
 
+	{ CRn( 0), CRm( 0), Op1( 1), Op2( 1), is32, NULL, get_CLIDR },
+	{ CRn( 0), CRm( 0), Op1( 1), Op2( 7), is32, NULL, get_AIDR },
+
 	{ CRn( 0), CRm( 1), Op1( 0), Op2( 0), is32, NULL, get_ID_PFR0 },
 	{ CRn( 0), CRm( 1), Op1( 0), Op2( 1), is32, NULL, get_ID_PFR1 },
 	{ CRn( 0), CRm( 1), Op1( 0), Op2( 2), is32, NULL, get_ID_DFR0 },
@@ -752,9 +755,6 @@ static struct coproc_reg invariant_cp15[] = {
 	{ CRn( 0), CRm( 2), Op1( 0), Op2( 3), is32, NULL, get_ID_ISAR3 },
 	{ CRn( 0), CRm( 2), Op1( 0), Op2( 4), is32, NULL, get_ID_ISAR4 },
 	{ CRn( 0), CRm( 2), Op1( 0), Op2( 5), is32, NULL, get_ID_ISAR5 },
-
-	{ CRn( 0), CRm( 0), Op1( 1), Op2( 1), is32, NULL, get_CLIDR },
-	{ CRn( 0), CRm( 0), Op1( 1), Op2( 7), is32, NULL, get_AIDR },
 };
 
 /*
@@ -1297,13 +1297,29 @@ int kvm_arm_copy_coproc_indices(struct kvm_vcpu *vcpu, u64 __user *uindices)
 	return write_demux_regids(uindices);
 }
 
+static int check_sysreg_table(const struct coproc_reg *table, unsigned int n)
+{
+	unsigned int i;
+
+	for (i = 1; i < n; i++) {
+		if (cmp_reg(&table[i-1], &table[i]) >= 0) {
+			kvm_err("sys_reg table %p out of order (%d)\n",
+					table, i - 1);
+			return 1;
+		}
+	}
+
+	return 0;
+}
+
 void kvm_coproc_table_init(void)
 {
 	unsigned int i;
 
 	/* Make sure tables are unique and in order. */
-	for (i = 1; i < ARRAY_SIZE(cp15_regs); i++)
-		BUG_ON(cmp_reg(&cp15_regs[i-1], &cp15_regs[i]) >= 0);
+	BUG_ON(check_sysreg_table(cp14_regs, ARRAY_SIZE(cp14_regs)));
+	BUG_ON(check_sysreg_table(cp15_regs, ARRAY_SIZE(cp15_regs)));
+	BUG_ON(check_sysreg_table(invariant_cp15, ARRAY_SIZE(invariant_cp15)));
 
 	/* We abuse the reset function to overwrite the table itself. */
 	for (i = 0; i < ARRAY_SIZE(invariant_cp15); i++)
-- 
1.7.12.4



From zhichao.huang at linaro.org  Mon Aug 10 06:25:59 2015
From: zhichao.huang at linaro.org (Zhichao Huang)
Date: Mon, 10 Aug 2015 21:25:59 +0800
Subject: [PATCH v4 07/15] KVM: arm: add trap handlers for 64-bit debug
 registers
In-Reply-To: <1439213167-8988-1-git-send-email-zhichao.huang@linaro.org>
References: <1439213167-8988-1-git-send-email-zhichao.huang@linaro.org>
Message-ID: <1439213167-8988-8-git-send-email-zhichao.huang@linaro.org>

Add handlers for all the 64-bit debug registers.

There is an overlap between 32 and 64bit registers. Make sure that
64-bit registers preceding 32-bit ones.

Signed-off-by: Zhichao Huang <zhichao.huang at linaro.org>
Reviewed-by: Christoffer Dall <christoffer.dall at linaro.org>
---
 arch/arm/kvm/coproc.c | 10 ++++++++++
 1 file changed, 10 insertions(+)

diff --git a/arch/arm/kvm/coproc.c b/arch/arm/kvm/coproc.c
index b3627f0..2164f4e 100644
--- a/arch/arm/kvm/coproc.c
+++ b/arch/arm/kvm/coproc.c
@@ -440,6 +440,12 @@ static const struct coproc_reg cp15_regs[] = {
  * Trapped cp14 registers. We generally ignore most of the external
  * debug, on the principle that they don't really make sense to a
  * guest. Revisit this one day, should this principle change.
+ *
+ * CRn denotes the primary register number, but is copied to the CRm in the
+ * user space API for 64-bit register access in line with the terminology used
+ * in the ARM ARM.
+ * Important: Must be sorted ascending by CRn, CRM, Op1, Op2 and with 64-bit
+ *            registers preceding 32-bit ones.
  */
 static const struct coproc_reg cp14_regs[] = {
 	/* DBGIDR */
@@ -447,10 +453,14 @@ static const struct coproc_reg cp14_regs[] = {
 	/* DBGDTRRXext */
 	{ CRn( 0), CRm( 0), Op1( 0), Op2( 2), is32, trap_raz_wi },
 	DBG_BCR_BVR_WCR_WVR(0),
+	/* DBGDRAR (64bit) */
+	{ CRn( 0), CRm( 1), Op1( 0), Op2( 0), is64, trap_raz_wi },
 	/* DBGDSCRint */
 	{ CRn( 0), CRm( 1), Op1( 0), Op2( 0), is32, trap_dbgdscr,
 				NULL, cp14_DBGDSCRext },
 	DBG_BCR_BVR_WCR_WVR(1),
+	/* DBGDSAR (64bit) */
+	{ CRn( 0), CRm( 2), Op1( 0), Op2( 0), is64, trap_raz_wi },
 	/* DBGDSCRext */
 	{ CRn( 0), CRm( 2), Op1( 0), Op2( 2), is32, trap_debug32,
 				reset_val, cp14_DBGDSCRext, 0 },
-- 
1.7.12.4



From zhichao.huang at linaro.org  Mon Aug 10 06:26:01 2015
From: zhichao.huang at linaro.org (Zhichao Huang)
Date: Mon, 10 Aug 2015 21:26:01 +0800
Subject: [PATCH v4 09/15] KVM: arm: redefine kvm_cpu_context_t to save the
 host cp14 states
In-Reply-To: <1439213167-8988-1-git-send-email-zhichao.huang@linaro.org>
References: <1439213167-8988-1-git-send-email-zhichao.huang@linaro.org>
Message-ID: <1439213167-8988-10-git-send-email-zhichao.huang@linaro.org>

Redefine kvm_cpu_context_t as a new struct that include the cp14 states,
which we used to save the host cp14 states.

Signed-off-by: Zhichao Huang <zhichao.huang at linaro.org>
---
 arch/arm/include/asm/kvm_host.h | 6 +++++-
 arch/arm/kernel/asm-offsets.c   | 4 +++-
 arch/arm/kvm/interrupts.S       | 6 ++++--
 3 files changed, 12 insertions(+), 4 deletions(-)

diff --git a/arch/arm/include/asm/kvm_host.h b/arch/arm/include/asm/kvm_host.h
index 63ac005..fc461ac 100644
--- a/arch/arm/include/asm/kvm_host.h
+++ b/arch/arm/include/asm/kvm_host.h
@@ -91,7 +91,11 @@ struct kvm_vcpu_fault_info {
 	u32 hyp_pc;		/* PC when exception was taken from Hyp mode */
 };
 
-typedef struct vfp_hard_struct kvm_cpu_context_t;
+struct kvm_cpu_context {
+	struct vfp_hard_struct vfp;
+	u32 cp14[NR_CP14_REGS];
+};
+typedef struct kvm_cpu_context kvm_cpu_context_t;
 
 struct kvm_vcpu_arch {
 	struct kvm_regs regs;
diff --git a/arch/arm/kernel/asm-offsets.c b/arch/arm/kernel/asm-offsets.c
index 9158de0..cee4254 100644
--- a/arch/arm/kernel/asm-offsets.c
+++ b/arch/arm/kernel/asm-offsets.c
@@ -175,7 +175,9 @@ int main(void)
   DEFINE(VCPU_CP14,		offsetof(struct kvm_vcpu, arch.cp14));
   DEFINE(VCPU_CP15,		offsetof(struct kvm_vcpu, arch.cp15));
   DEFINE(VCPU_VFP_GUEST,	offsetof(struct kvm_vcpu, arch.vfp_guest));
-  DEFINE(VCPU_VFP_HOST,		offsetof(struct kvm_vcpu, arch.host_cpu_context));
+  DEFINE(VCPU_HOST_CONTEXT,	offsetof(struct kvm_vcpu, arch.host_cpu_context));
+  DEFINE(VCPU_VFP_HOST,		offsetof(struct kvm_cpu_context, vfp));
+  DEFINE(VCPU_CP14_HOST,	offsetof(struct kvm_cpu_context, cp14));
   DEFINE(VCPU_REGS,		offsetof(struct kvm_vcpu, arch.regs));
   DEFINE(VCPU_USR_REGS,		offsetof(struct kvm_vcpu, arch.regs.usr_regs));
   DEFINE(VCPU_SVC_REGS,		offsetof(struct kvm_vcpu, arch.regs.svc_regs));
diff --git a/arch/arm/kvm/interrupts.S b/arch/arm/kvm/interrupts.S
index 48333ff..d4ff22e 100644
--- a/arch/arm/kvm/interrupts.S
+++ b/arch/arm/kvm/interrupts.S
@@ -176,8 +176,9 @@ __kvm_vcpu_return:
 	@ Switch VFP/NEON hardware state to the host's
 	add	r7, vcpu, #VCPU_VFP_GUEST
 	store_vfp_state r7
-	add	r7, vcpu, #VCPU_VFP_HOST
+	add	r7, vcpu, #VCPU_HOST_CONTEXT
 	ldr	r7, [r7]
+	add	r7, r7, #VCPU_VFP_HOST
 	restore_vfp_state r7
 
 after_vfp_restore:
@@ -484,8 +485,9 @@ switch_to_guest_vfp:
 	set_hcptr vmtrap, (HCPTR_TCP(10) | HCPTR_TCP(11))
 
 	@ Switch VFP/NEON hardware state to the guest's
-	add	r7, r0, #VCPU_VFP_HOST
+	add	r7, r0, #VCPU_HOST_CONTEXT
 	ldr	r7, [r7]
+	add	r7, r7, #VCPU_VFP_HOST
 	store_vfp_state r7
 	add	r7, r0, #VCPU_VFP_GUEST
 	restore_vfp_state r7
-- 
1.7.12.4



From zhichao.huang at linaro.org  Mon Aug 10 06:26:04 2015
From: zhichao.huang at linaro.org (Zhichao Huang)
Date: Mon, 10 Aug 2015 21:26:04 +0800
Subject: [PATCH v4 12/15] KVM: arm: keep track of host use of the debug
 registers
In-Reply-To: <1439213167-8988-1-git-send-email-zhichao.huang@linaro.org>
References: <1439213167-8988-1-git-send-email-zhichao.huang@linaro.org>
Message-ID: <1439213167-8988-13-git-send-email-zhichao.huang@linaro.org>

Every guest entry, we need to keep track of host use of the debug
registers.

We only call the function upon guest entry, after preempt_disable()
and local_irq_disable(), so there is no race for it.

Signed-off-by: Zhichao Huang <zhichao.huang at linaro.org>
---
 arch/arm/include/asm/kvm_asm.h    | 3 +++
 arch/arm/include/asm/kvm_host.h   | 4 ++++
 arch/arm/kernel/asm-offsets.c     | 1 +
 arch/arm/kvm/arm.c                | 2 ++
 arch/arm/kvm/coproc.c             | 8 ++++++++
 arch/arm64/include/asm/kvm_host.h | 1 +
 6 files changed, 19 insertions(+)

diff --git a/arch/arm/include/asm/kvm_asm.h b/arch/arm/include/asm/kvm_asm.h
index 7443a3a..5b1c3eb 100644
--- a/arch/arm/include/asm/kvm_asm.h
+++ b/arch/arm/include/asm/kvm_asm.h
@@ -64,6 +64,9 @@
 #define cp14_DBGDSCRext	65	/* Debug Status and Control external */
 #define NR_CP14_REGS	66	/* Number of regs (incl. invalid) */
 
+#define KVM_ARM_DEBUG_HOST_INUSE_SHIFT	0
+#define KVM_ARM_DEBUG_HOST_INUSE	(1 << KVM_ARM_DEBUG_HOST_INUSE_SHIFT)
+
 #define ARM_EXCEPTION_RESET	  0
 #define ARM_EXCEPTION_UNDEFINED   1
 #define ARM_EXCEPTION_SOFTWARE    2
diff --git a/arch/arm/include/asm/kvm_host.h b/arch/arm/include/asm/kvm_host.h
index fc461ac..7338f34 100644
--- a/arch/arm/include/asm/kvm_host.h
+++ b/arch/arm/include/asm/kvm_host.h
@@ -131,6 +131,9 @@ struct kvm_vcpu_arch {
 	/* System control coprocessor (cp14) */
 	u32 cp14[NR_CP14_REGS];
 
+	/* Debug State */
+	u32 debug_flags;
+
 	/*
 	 * Anything that is not used directly from assembly code goes
 	 * here.
@@ -237,5 +240,6 @@ static inline void kvm_arch_hardware_unsetup(void) {}
 static inline void kvm_arch_sync_events(struct kvm *kvm) {}
 static inline void kvm_arch_vcpu_uninit(struct kvm_vcpu *vcpu) {}
 static inline void kvm_arch_sched_in(struct kvm_vcpu *vcpu, int cpu) {}
+void kvm_arm_setup_debug(struct kvm_vcpu *vcpu);
 
 #endif /* __ARM_KVM_HOST_H__ */
diff --git a/arch/arm/kernel/asm-offsets.c b/arch/arm/kernel/asm-offsets.c
index cee4254..7750597 100644
--- a/arch/arm/kernel/asm-offsets.c
+++ b/arch/arm/kernel/asm-offsets.c
@@ -178,6 +178,7 @@ int main(void)
   DEFINE(VCPU_HOST_CONTEXT,	offsetof(struct kvm_vcpu, arch.host_cpu_context));
   DEFINE(VCPU_VFP_HOST,		offsetof(struct kvm_cpu_context, vfp));
   DEFINE(VCPU_CP14_HOST,	offsetof(struct kvm_cpu_context, cp14));
+  DEFINE(VCPU_DEBUG_FLAGS,	offsetof(struct kvm_vcpu, arch.debug_flags));
   DEFINE(VCPU_REGS,		offsetof(struct kvm_vcpu, arch.regs));
   DEFINE(VCPU_USR_REGS,		offsetof(struct kvm_vcpu, arch.regs.usr_regs));
   DEFINE(VCPU_SVC_REGS,		offsetof(struct kvm_vcpu, arch.regs.svc_regs));
diff --git a/arch/arm/kvm/arm.c b/arch/arm/kvm/arm.c
index bc738d2..0129346 100644
--- a/arch/arm/kvm/arm.c
+++ b/arch/arm/kvm/arm.c
@@ -550,6 +550,8 @@ int kvm_arch_vcpu_ioctl_run(struct kvm_vcpu *vcpu, struct kvm_run *run)
 			continue;
 		}
 
+		kvm_arm_setup_debug(vcpu);
+
 		/**************************************************************
 		 * Enter the guest
 		 */
diff --git a/arch/arm/kvm/coproc.c b/arch/arm/kvm/coproc.c
index d15b250..b37afd6 100644
--- a/arch/arm/kvm/coproc.c
+++ b/arch/arm/kvm/coproc.c
@@ -1516,3 +1516,11 @@ void kvm_reset_coprocs(struct kvm_vcpu *vcpu)
 		if (vcpu->arch.cp15[num] == 0x42424242)
 			panic("Didn't reset vcpu->arch.cp15[%zi]", num);
 }
+
+void kvm_arm_setup_debug(struct kvm_vcpu *vcpu)
+{
+	if (hw_breakpoint_enabled())
+		vcpu->arch.debug_flags |= KVM_ARM_DEBUG_HOST_INUSE;
+	else
+		vcpu->arch.debug_flags &= ~KVM_ARM_DEBUG_HOST_INUSE;
+}
diff --git a/arch/arm64/include/asm/kvm_host.h b/arch/arm64/include/asm/kvm_host.h
index 2709db2..84fa4f0 100644
--- a/arch/arm64/include/asm/kvm_host.h
+++ b/arch/arm64/include/asm/kvm_host.h
@@ -226,5 +226,6 @@ static inline void kvm_arch_hardware_unsetup(void) {}
 static inline void kvm_arch_sync_events(struct kvm *kvm) {}
 static inline void kvm_arch_vcpu_uninit(struct kvm_vcpu *vcpu) {}
 static inline void kvm_arch_sched_in(struct kvm_vcpu *vcpu, int cpu) {}
+static inline void kvm_arm_setup_debug(struct kvm_vcpu *vcpu) {}
 
 #endif /* __ARM64_KVM_HOST_H__ */
-- 
1.7.12.4



From zhichao.huang at linaro.org  Mon Aug 10 06:26:02 2015
From: zhichao.huang at linaro.org (Zhichao Huang)
Date: Mon, 10 Aug 2015 21:26:02 +0800
Subject: [PATCH v4 10/15] KVM: arm: implement world switch for debug registers
In-Reply-To: <1439213167-8988-1-git-send-email-zhichao.huang@linaro.org>
References: <1439213167-8988-1-git-send-email-zhichao.huang@linaro.org>
Message-ID: <1439213167-8988-11-git-send-email-zhichao.huang@linaro.org>

Implement switching of the debug registers. While the number
of registers is massive, CPUs usually don't implement them all
(A15 has 6 breakpoints and 4 watchpoints, which gives us a total
of 22 registers "only").

Signed-off-by: Zhichao Huang <zhichao.huang at linaro.org>
---
 arch/arm/kvm/interrupts_head.S | 170 ++++++++++++++++++++++++++++++++++++++---
 1 file changed, 159 insertions(+), 11 deletions(-)

diff --git a/arch/arm/kvm/interrupts_head.S b/arch/arm/kvm/interrupts_head.S
index 7ac5e51..b9e7410 100644
--- a/arch/arm/kvm/interrupts_head.S
+++ b/arch/arm/kvm/interrupts_head.S
@@ -5,6 +5,7 @@
 #define VCPU_USR_SP		(VCPU_USR_REG(13))
 #define VCPU_USR_LR		(VCPU_USR_REG(14))
 #define CP15_OFFSET(_cp15_reg_idx) (VCPU_CP15 + (_cp15_reg_idx * 4))
+#define CP14_OFFSET(_cp14_reg_idx) ((_cp14_reg_idx) * 4)
 
 /*
  * Many of these macros need to access the VCPU structure, which is always
@@ -239,6 +240,136 @@ vcpu	.req	r0		@ vcpu pointer always in r0
 	save_guest_regs_mode irq, #VCPU_IRQ_REGS
 .endm
 
+/* Assume r10/r11/r12 are in use, clobbers r2-r3 */
+.macro cp14_read_and_str base Op2 cp14_reg0 skip_num
+	adr	r3, 1f
+	add	r3, r3, \skip_num, lsl #3
+	bx	r3
+1:
+	mrc	p14, 0, r2, c0, c15, \Op2
+	str     r2, [\base, #CP14_OFFSET(\cp14_reg0+15)]
+	mrc	p14, 0, r2, c0, c14, \Op2
+	str     r2, [\base, #CP14_OFFSET(\cp14_reg0+14)]
+	mrc	p14, 0, r2, c0, c13, \Op2
+	str     r2, [\base, #CP14_OFFSET(\cp14_reg0+13)]
+	mrc	p14, 0, r2, c0, c12, \Op2
+	str     r2, [\base, #CP14_OFFSET(\cp14_reg0+12)]
+	mrc	p14, 0, r2, c0, c11, \Op2
+	str     r2, [\base, #CP14_OFFSET(\cp14_reg0+11)]
+	mrc	p14, 0, r2, c0, c10, \Op2
+	str     r2, [\base, #CP14_OFFSET(\cp14_reg0+10)]
+	mrc	p14, 0, r2, c0, c9, \Op2
+	str     r2, [\base, #CP14_OFFSET(\cp14_reg0+9)]
+	mrc	p14, 0, r2, c0, c8, \Op2
+	str     r2, [\base, #CP14_OFFSET(\cp14_reg0+8)]
+	mrc	p14, 0, r2, c0, c7, \Op2
+	str     r2, [\base, #CP14_OFFSET(\cp14_reg0+7)]
+	mrc	p14, 0, r2, c0, c6, \Op2
+	str     r2, [\base, #CP14_OFFSET(\cp14_reg0+6)]
+	mrc	p14, 0, r2, c0, c5, \Op2
+	str     r2, [\base, #CP14_OFFSET(\cp14_reg0+5)]
+	mrc	p14, 0, r2, c0, c4, \Op2
+	str     r2, [\base, #CP14_OFFSET(\cp14_reg0+4)]
+	mrc	p14, 0, r2, c0, c3, \Op2
+	str     r2, [\base, #CP14_OFFSET(\cp14_reg0+3)]
+	mrc	p14, 0, r2, c0, c2, \Op2
+	str     r2, [\base, #CP14_OFFSET(\cp14_reg0+2)]
+	mrc	p14, 0, r2, c0, c1, \Op2
+	str     r2, [\base, #CP14_OFFSET(\cp14_reg0+1)]
+	mrc	p14, 0, r2, c0, c0, \Op2
+	str     r2, [\base, #CP14_OFFSET(\cp14_reg0)]
+.endm
+
+/* Assume r11/r12 are in use, clobbers r2-r3 */
+.macro cp14_ldr_and_write base Op2 cp14_reg0 skip_num
+	adr	r3, 1f
+	add	r3, r3, \skip_num, lsl #3
+	bx	r3
+1:
+	ldr     r2, [\base, #CP14_OFFSET(\cp14_reg0+15)]
+	mcr	p14, 0, r2, c0, c15, \Op2
+	ldr     r2, [\base, #CP14_OFFSET(\cp14_reg0+14)]
+	mcr	p14, 0, r2, c0, c14, \Op2
+	ldr     r2, [\base, #CP14_OFFSET(\cp14_reg0+13)]
+	mcr	p14, 0, r2, c0, c13, \Op2
+	ldr     r2, [\base, #CP14_OFFSET(\cp14_reg0+12)]
+	mcr	p14, 0, r2, c0, c12, \Op2
+	ldr     r2, [\base, #CP14_OFFSET(\cp14_reg0+11)]
+	mcr	p14, 0, r2, c0, c11, \Op2
+	ldr     r2, [\base, #CP14_OFFSET(\cp14_reg0+10)]
+	mcr	p14, 0, r2, c0, c10, \Op2
+	ldr     r2, [\base, #CP14_OFFSET(\cp14_reg0+9)]
+	mcr	p14, 0, r2, c0, c9, \Op2
+	ldr     r2, [\base, #CP14_OFFSET(\cp14_reg0+8)]
+	mcr	p14, 0, r2, c0, c8, \Op2
+	ldr     r2, [\base, #CP14_OFFSET(\cp14_reg0+7)]
+	mcr	p14, 0, r2, c0, c7, \Op2
+	ldr     r2, [\base, #CP14_OFFSET(\cp14_reg0+6)]
+	mcr	p14, 0, r2, c0, c6, \Op2
+	ldr     r2, [\base, #CP14_OFFSET(\cp14_reg0+5)]
+	mcr	p14, 0, r2, c0, c5, \Op2
+	ldr     r2, [\base, #CP14_OFFSET(\cp14_reg0+4)]
+	mcr	p14, 0, r2, c0, c4, \Op2
+	ldr     r2, [\base, #CP14_OFFSET(\cp14_reg0+3)]
+	mcr	p14, 0, r2, c0, c3, \Op2
+	ldr     r2, [\base, #CP14_OFFSET(\cp14_reg0+2)]
+	mcr	p14, 0, r2, c0, c2, \Op2
+	ldr     r2, [\base, #CP14_OFFSET(\cp14_reg0+1)]
+	mcr	p14, 0, r2, c0, c1, \Op2
+	ldr     r2, [\base, #CP14_OFFSET(\cp14_reg0)]
+	mcr	p14, 0, r2, c0, c0, \Op2
+.endm
+
+/* Get extract number of BRPs and WRPs. Saved in r11/r12 */
+.macro read_hw_dbg_num
+	mrc	p14, 0, r2, c0, c0, 0
+	ubfx	r11, r2, #24, #4
+	add	r11, r11, #1		@ Extract BRPs
+	ubfx	r12, r2, #28, #4
+	add	r12, r12, #1		@ Extract WRPs
+	mov	r2, #16
+	sub	r11, r2, r11		@ How many BPs to skip
+	sub	r12, r2, r12		@ How many WPs to skip
+.endm
+
+/* Reads cp14 registers from hardware.
+ * Writes cp14 registers in-order to the CP14 struct pointed to by r10
+ *
+ * Assumes vcpu pointer in vcpu reg
+ *
+ * Clobbers r2-r12
+ */
+.macro save_debug_state
+	read_hw_dbg_num
+	cp14_read_and_str r10, 4, cp14_DBGBVR0, r11
+	cp14_read_and_str r10, 5, cp14_DBGBCR0, r11
+	cp14_read_and_str r10, 6, cp14_DBGWVR0, r12
+	cp14_read_and_str r10, 7, cp14_DBGWCR0, r12
+
+	/* DBGDSCR reg */
+	mrc	p14, 0, r2, c0, c1, 0
+	str	r2, [r10, #CP14_OFFSET(cp14_DBGDSCRext)]
+.endm
+
+/* Reads cp14 registers in-order from the CP14 struct pointed to by r10
+ * Writes cp14 registers to hardware.
+ *
+ * Assumes vcpu pointer in vcpu reg
+ *
+ * Clobbers r2-r12
+ */
+.macro restore_debug_state
+	read_hw_dbg_num
+	cp14_ldr_and_write r10, 4, cp14_DBGBVR0, r11
+	cp14_ldr_and_write r10, 5, cp14_DBGBCR0, r11
+	cp14_ldr_and_write r10, 6, cp14_DBGWVR0, r12
+	cp14_ldr_and_write r10, 7, cp14_DBGWCR0, r12
+
+	/* DBGDSCR reg */
+	ldr	r2, [r10, #CP14_OFFSET(cp14_DBGDSCRext)]
+	mcr	p14, 0, r2, c0, c2, 2
+.endm
+
 /* Reads cp14/cp15 registers from hardware and stores them in memory
  * @store_to_vcpu: If 0, registers are written in-order to the stack,
  * 		   otherwise to the VCPU struct pointed to by vcpup
@@ -248,11 +379,17 @@ vcpu	.req	r0		@ vcpu pointer always in r0
  * Clobbers r2 - r12
  */
 .macro read_coproc_state store_to_vcpu
-	.if \store_to_vcpu == 0
-	mrc	p14, 0, r2, c0, c1, 0	@ DBGDSCR
-	push	{r2}
+	.if \store_to_vcpu == 1
+	add	r10, vcpu, #VCPU_CP14
+	.else
+	add	r10, vcpu, #VCPU_HOST_CONTEXT
+	ldr	r10, [r10]
+	add	r10, r10, #VCPU_CP14_HOST
 	.endif
 
+	/* Assumes r10 pointer in cp14 regs  */
+	bl __save_debug_state
+
 	mrc	p15, 0, r2, c1, c0, 0	@ SCTLR
 	mrc	p15, 0, r3, c1, c0, 2	@ CPACR
 	mrc	p15, 0, r4, c2, c0, 2	@ TTBCR
@@ -331,6 +468,17 @@ vcpu	.req	r0		@ vcpu pointer always in r0
  * Assumes vcpu pointer in vcpu reg
  */
 .macro write_coproc_state read_from_vcpu
+	.if \read_from_vcpu == 1
+	add	r10, vcpu, #VCPU_CP14
+	.else
+	add	r10, vcpu, #VCPU_HOST_CONTEXT
+	ldr	r10, [r10]
+	add	r10, r10, #VCPU_CP14_HOST
+	.endif
+
+	/* Assumes r10 pointer in cp14 regs  */
+	bl __restore_debug_state
+
 	.if \read_from_vcpu == 0
 	pop	{r2,r4-r7}
 	.else
@@ -399,14 +547,6 @@ vcpu	.req	r0		@ vcpu pointer always in r0
 	mcr	p15, 0, r10, c10, c2, 0	@ PRRR
 	mcr	p15, 0, r11, c10, c2, 1	@ NMRR
 	mcr	p15, 2, r12, c0, c0, 0	@ CSSELR
-
-	.if \read_from_vcpu == 0
-	pop	{r2}
-	.else
-	mov	r2, #0
-	.endif
-
-	mcr	p14, 0, r2, c0, c2, 2	@ DBGDSCR
 .endm
 
 /*
@@ -657,3 +797,11 @@ ARM_BE8(rev	r6, r6  )
 .macro load_vcpu
 	mrc	p15, 4, vcpu, c13, c0, 2	@ HTPIDR
 .endm
+
+__save_debug_state:
+	save_debug_state
+	bx	lr
+
+__restore_debug_state:
+	restore_debug_state
+	bx	lr
-- 
1.7.12.4



From zhichao.huang at linaro.org  Mon Aug 10 06:26:03 2015
From: zhichao.huang at linaro.org (Zhichao Huang)
Date: Mon, 10 Aug 2015 21:26:03 +0800
Subject: [PATCH v4 11/15] KVM: arm: add a function to keep track of host use
 of the debug registers
In-Reply-To: <1439213167-8988-1-git-send-email-zhichao.huang@linaro.org>
References: <1439213167-8988-1-git-send-email-zhichao.huang@linaro.org>
Message-ID: <1439213167-8988-12-git-send-email-zhichao.huang@linaro.org>

As we're about to implement a lazy world switch for debug registers,
we add a function reading the break/watch control variables directly to
indicate whether the host has enabled any break/watch points or not.

Signed-off-by: Zhichao Huang <zhichao.huang at linaro.org>
---
 arch/arm/include/asm/hw_breakpoint.h |  5 +++++
 arch/arm/kernel/hw_breakpoint.c      | 21 +++++++++++++++++++++
 2 files changed, 26 insertions(+)

diff --git a/arch/arm/include/asm/hw_breakpoint.h b/arch/arm/include/asm/hw_breakpoint.h
index f2f4c61..6f375c5 100644
--- a/arch/arm/include/asm/hw_breakpoint.h
+++ b/arch/arm/include/asm/hw_breakpoint.h
@@ -66,9 +66,14 @@ int arch_install_hw_breakpoint(struct perf_event *bp);
 void arch_uninstall_hw_breakpoint(struct perf_event *bp);
 void hw_breakpoint_pmu_read(struct perf_event *bp);
 int hw_breakpoint_slots(int type);
+bool hw_breakpoint_enabled(void);
 
 #else
 static inline void clear_ptrace_hw_breakpoint(struct task_struct *tsk) {}
+static inline bool hw_breakpoint_enabled(void)
+{
+	return false;
+}
 
 #endif	/* CONFIG_HAVE_HW_BREAKPOINT */
 #endif  /* __ASSEMBLY */
diff --git a/arch/arm/kernel/hw_breakpoint.c b/arch/arm/kernel/hw_breakpoint.c
index dc7d0a9..f56788f 100644
--- a/arch/arm/kernel/hw_breakpoint.c
+++ b/arch/arm/kernel/hw_breakpoint.c
@@ -227,6 +227,27 @@ static int get_num_brps(void)
 	return core_has_mismatch_brps() ? brps - 1 : brps;
 }
 
+/* Indicate whether the host has enabled any break/watch points or not. */
+bool hw_breakpoint_enabled(void)
+{
+	struct perf_event **slots;
+	int i;
+
+	slots = this_cpu_ptr(bp_on_reg);
+	for (i = 0; i < core_num_brps; i++) {
+		if (slots[i])
+			return true;
+	}
+
+	slots = this_cpu_ptr(wp_on_reg);
+	for (i = 0; i < core_num_wrps; i++) {
+		if (slots[i])
+			return true;
+	}
+
+	return false;
+}
+
 /*
  * In order to access the breakpoint/watchpoint control registers,
  * we must be running in debug monitor mode. Unfortunately, we can
-- 
1.7.12.4



From zhichao.huang at linaro.org  Mon Aug 10 06:26:05 2015
From: zhichao.huang at linaro.org (Zhichao Huang)
Date: Mon, 10 Aug 2015 21:26:05 +0800
Subject: [PATCH v4 13/15] KVM: arm: keep track of guest use of the debug
 registers
In-Reply-To: <1439213167-8988-1-git-send-email-zhichao.huang@linaro.org>
References: <1439213167-8988-1-git-send-email-zhichao.huang@linaro.org>
Message-ID: <1439213167-8988-14-git-send-email-zhichao.huang@linaro.org>

We trap debug register accesses from guest all the time, and read the
BCR/WCR to indicate whether the guest has enabled any break/watch points
or not.

Signed-off-by: Zhichao Huang <zhichao.huang at linaro.org>
---
 arch/arm/include/asm/kvm_asm.h |  2 ++
 arch/arm/kvm/coproc.c          | 75 +++++++++++++++++++++++++++++++++++++++---
 2 files changed, 72 insertions(+), 5 deletions(-)

diff --git a/arch/arm/include/asm/kvm_asm.h b/arch/arm/include/asm/kvm_asm.h
index 5b1c3eb..e9e1f0a 100644
--- a/arch/arm/include/asm/kvm_asm.h
+++ b/arch/arm/include/asm/kvm_asm.h
@@ -65,7 +65,9 @@
 #define NR_CP14_REGS	66	/* Number of regs (incl. invalid) */
 
 #define KVM_ARM_DEBUG_HOST_INUSE_SHIFT	0
+#define KVM_ARM_DEBUG_GUEST_INUSE_SHIFT	1
 #define KVM_ARM_DEBUG_HOST_INUSE	(1 << KVM_ARM_DEBUG_HOST_INUSE_SHIFT)
+#define KVM_ARM_DEBUG_GUEST_INUSE	(1 << KVM_ARM_DEBUG_GUEST_INUSE_SHIFT)
 
 #define ARM_EXCEPTION_RESET	  0
 #define ARM_EXCEPTION_UNDEFINED   1
diff --git a/arch/arm/kvm/coproc.c b/arch/arm/kvm/coproc.c
index b37afd6..d9dcd28b 100644
--- a/arch/arm/kvm/coproc.c
+++ b/arch/arm/kvm/coproc.c
@@ -220,7 +220,22 @@ bool access_vm_reg(struct kvm_vcpu *vcpu,
 	return true;
 }
 
-static bool trap_debug32(struct kvm_vcpu *vcpu,
+/* Indicate whether the guest has enabled any break/watch points or not. */
+static bool guest_debug_in_use(struct kvm_vcpu *vcpu)
+{
+	unsigned int i;
+
+	for (i = 0; i < ARM_MAX_BRP; i++)
+		if (vcpu->arch.cp14[cp14_DBGBCR0 + i] & 0x1)
+			return true;
+	for (i = 0; i < ARM_MAX_WRP; i++)
+		if (vcpu->arch.cp14[cp14_DBGWCR0 + i] & 0x1)
+			return true;
+
+	return false;
+}
+
+static bool __trap_debug32(struct kvm_vcpu *vcpu,
 			const struct coproc_params *p,
 			const struct coproc_reg *r)
 {
@@ -232,6 +247,56 @@ static bool trap_debug32(struct kvm_vcpu *vcpu,
 	return true;
 }
 
+/*
+ * We want to avoid world-switching all the DBG registers all the
+ * time:
+ *
+ * When we are about to run a guest, we have the following cases:
+ *
+ * 1) Neither the host nor the guest has configured any [WB]points
+ * 2) Only the host has configured any [WB]points
+ * 3) Only the guest has configured any [WB]points
+ * 4) Both the host and the guest have configured any [WB]points
+ *
+ * - In case (1), KVM should enable trapping and swtich the register
+ *   state on guest accesses.
+ * - In cases (2), (3), and (4) we must switch the register state on each
+ *   entry/exit.
+ *
+ * For ARMv7, if the CONFIG_HAVE_HW_BREAKPOINT is set, ARM_DSCR_MDBGEN
+ * is always set(ARM64 use it to indicate that debug registers are actively
+ * in use).
+ *
+ * - We add a function reading the break/watch control variables directly to
+ *   indicate whether the host has enabled any break/watch points or not.
+ *   We only call the function upon guest entry, after preempt_disable() and
+ *   local_irq_disable(), so there is no race for it.
+ *
+ * - We trap debug register accesses from guest all the time, and read the
+ *   BCR/WCR to indicate whether the guest has enabled any break/watch points
+ *   or not.
+ *
+ * For this, we can keep track of the host/guest use of debug registers,
+ * and skip the save/restore dance when neither the host nor the guest has
+ * configured any [WB]points.
+ */
+static bool trap_debug32(struct kvm_vcpu *vcpu,
+			const struct coproc_params *p,
+			const struct coproc_reg *r)
+{
+	__trap_debug32(vcpu, p, r);
+
+	if (p->is_write) {
+		if ((vcpu->arch.cp14[r->reg] & 0x1) ||
+		    guest_debug_in_use(vcpu))
+			vcpu->arch.debug_flags |= KVM_ARM_DEBUG_GUEST_INUSE;
+		else
+			vcpu->arch.debug_flags &= ~KVM_ARM_DEBUG_GUEST_INUSE;
+	}
+
+	return true;
+}
+
 /* DBGIDR (RO) Debug ID */
 static bool trap_dbgidr(struct kvm_vcpu *vcpu,
 			const struct coproc_params *p,
@@ -419,13 +484,13 @@ static const struct coproc_reg cp15_regs[] = {
 #define DBG_BCR_BVR_WCR_WVR(n)					\
 	/* DBGBVRn */						\
 	{ CRn( 0), CRm((n)), Op1( 0), Op2( 4), is32,		\
-	  trap_debug32,	reset_val, (cp14_DBGBVR0 + (n)), 0 },	\
+	  __trap_debug32, reset_val, (cp14_DBGBVR0 + (n)), 0 },	\
 	/* DBGBCRn */						\
 	{ CRn( 0), CRm((n)), Op1( 0), Op2( 5), is32,		\
 	  trap_debug32,	reset_val, (cp14_DBGBCR0 + (n)), 0 },	\
 	/* DBGWVRn */						\
 	{ CRn( 0), CRm((n)), Op1( 0), Op2( 6), is32,		\
-	  trap_debug32,	reset_val, (cp14_DBGWVR0 + (n)), 0 },	\
+	  __trap_debug32, reset_val, (cp14_DBGWVR0 + (n)), 0 },	\
 	/* DBGWCRn */						\
 	{ CRn( 0), CRm((n)), Op1( 0), Op2( 7), is32,		\
 	  trap_debug32,	reset_val, (cp14_DBGWCR0 + (n)), 0 }
@@ -462,7 +527,7 @@ static const struct coproc_reg cp14_regs[] = {
 	/* DBGDSAR (64bit) */
 	{ CRn( 0), CRm( 2), Op1( 0), Op2( 0), is64, trap_raz_wi },
 	/* DBGDSCRext */
-	{ CRn( 0), CRm( 2), Op1( 0), Op2( 2), is32, trap_debug32,
+	{ CRn( 0), CRm( 2), Op1( 0), Op2( 2), is32, __trap_debug32,
 				reset_val, cp14_DBGDSCRext, 0 },
 	DBG_BCR_BVR_WCR_WVR(2),
 	/* DBGDTRTXext */
@@ -474,7 +539,7 @@ static const struct coproc_reg cp14_regs[] = {
 	DBG_BCR_BVR_WCR_WVR(5),
 	DBG_BCR_BVR_WCR_WVR(6),
 	/* DBGVCR */
-	{ CRn( 0), CRm( 7), Op1( 0), Op2( 0), is32, trap_debug32 },
+	{ CRn( 0), CRm( 7), Op1( 0), Op2( 0), is32, __trap_debug32 },
 	DBG_BCR_BVR_WCR_WVR(7),
 	DBG_BCR_BVR_WCR_WVR(8),
 	DBG_BCR_BVR_WCR_WVR(9),
-- 
1.7.12.4



From zhichao.huang at linaro.org  Mon Aug 10 06:26:06 2015
From: zhichao.huang at linaro.org (Zhichao Huang)
Date: Mon, 10 Aug 2015 21:26:06 +0800
Subject: [PATCH v4 14/15] KVM: arm: implement lazy world switch for debug
 registers
In-Reply-To: <1439213167-8988-1-git-send-email-zhichao.huang@linaro.org>
References: <1439213167-8988-1-git-send-email-zhichao.huang@linaro.org>
Message-ID: <1439213167-8988-15-git-send-email-zhichao.huang@linaro.org>

Avoid world-switching all the debug registers when neither the host
nor the guest has configured any [WB]points.

Signed-off-by: Zhichao Huang <zhichao.huang at linaro.org>
---
 arch/arm/kvm/interrupts_head.S | 23 +++++++++++++++++++++--
 1 file changed, 21 insertions(+), 2 deletions(-)

diff --git a/arch/arm/kvm/interrupts_head.S b/arch/arm/kvm/interrupts_head.S
index b9e7410..7ad0adf 100644
--- a/arch/arm/kvm/interrupts_head.S
+++ b/arch/arm/kvm/interrupts_head.S
@@ -332,6 +332,21 @@ vcpu	.req	r0		@ vcpu pointer always in r0
 	sub	r12, r2, r12		@ How many WPs to skip
 .endm
 
+/* If VCPU_DEBUG_FLAGS is not set, it means that neither the host
+ * nor the guest has configured any [WB]points.
+ *
+ * We avoid world-switching all the debug registers in that case.
+ *
+ * Assume vcpu pointer in vcpu reg
+ *
+ * clobbers r2
+ */
+.macro skip_debug_state target
+	ldr	r2, [vcpu, #VCPU_DEBUG_FLAGS]
+	cmp	r2, #0
+	beq	\target
+.endm
+
 /* Reads cp14 registers from hardware.
  * Writes cp14 registers in-order to the CP14 struct pointed to by r10
  *
@@ -340,12 +355,14 @@ vcpu	.req	r0		@ vcpu pointer always in r0
  * Clobbers r2-r12
  */
 .macro save_debug_state
+	skip_debug_state 9999f
+
 	read_hw_dbg_num
 	cp14_read_and_str r10, 4, cp14_DBGBVR0, r11
 	cp14_read_and_str r10, 5, cp14_DBGBCR0, r11
 	cp14_read_and_str r10, 6, cp14_DBGWVR0, r12
 	cp14_read_and_str r10, 7, cp14_DBGWCR0, r12
-
+9999:
 	/* DBGDSCR reg */
 	mrc	p14, 0, r2, c0, c1, 0
 	str	r2, [r10, #CP14_OFFSET(cp14_DBGDSCRext)]
@@ -359,12 +376,14 @@ vcpu	.req	r0		@ vcpu pointer always in r0
  * Clobbers r2-r12
  */
 .macro restore_debug_state
+	skip_debug_state 9999f
+
 	read_hw_dbg_num
 	cp14_ldr_and_write r10, 4, cp14_DBGBVR0, r11
 	cp14_ldr_and_write r10, 5, cp14_DBGBCR0, r11
 	cp14_ldr_and_write r10, 6, cp14_DBGWVR0, r12
 	cp14_ldr_and_write r10, 7, cp14_DBGWCR0, r12
-
+9999:
 	/* DBGDSCR reg */
 	ldr	r2, [r10, #CP14_OFFSET(cp14_DBGDSCRext)]
 	mcr	p14, 0, r2, c0, c2, 2
-- 
1.7.12.4



From eric.auger at linaro.org  Mon Aug 10 06:31:02 2015
From: eric.auger at linaro.org (Eric Auger)
Date: Mon, 10 Aug 2015 15:31:02 +0200
Subject: [PATCH v5 0/5] KVM: irqfd consumer based on IRQ bypass manager
Message-ID: <1439213467-13668-1-git-send-email-eric.auger@linaro.org>

This series transforms irqfd into an IRQ bypass consumer and
introduce the infrastructure shared by Intel posted-interrupts
and ARM forwarded IRQ series.

The bypass manager gets compiled for x86 and arm/arm64 when
KVM is used. A new kvm_irqfd.h header is created to externalize
some irqfd declarations going to be used by architecture specific
code. A new CONFIG_HAVE_KVM_IRQ_BYPASS option is introduced
to enable architecture specific IRQ manager hooks.

the series depends on the IRQ bypass manager:
- [PATCH v4] virt: IRQ bypass manager (https://lkml.org/lkml/2015/8/6/526)

can be found at:
https://git.linaro.org/people/eric.auger/linux.git/shortlog/refs/heads/v4.2-rc6-irq-forward-v3

Best Regards

Eric

History:

v4 -> v5:
- remove kvm_arch static inline stubs
- add pr_info on registration failure

v3 -> v4:
- fix compilation for arm/arm64
- rearrange signoffs/history on some patch files

v2 -> v3 (Feng Wu):
- rebase on IRQ bypass manager [PATCH v2] virt: IRQ bypass manager:
  https://lkml.org/lkml/2015/7/16/810
- Correct some minor errors and typo
- Add something needed for posted-interrupts

v1 -> v2:
- isolate the bypass manager and irqfd consumer in this series
- take into account Paolo's comments and use container_of strategy and
  remove additional fields introduced in v1.
- create kvm_irqfd.h
- add unregistration in irqfd_shutdown

v1: originally part of [RFC 00/17] ARM IRQ forward control based on IRQ
    bypass manager (https://lkml.org/lkml/2015/7/2/268)

Eric Auger (4):
  KVM: arm/arm64: select IRQ_BYPASS_MANAGER
  KVM: create kvm_irqfd.h
  KVM: introduce kvm_arch functions for IRQ bypass
  KVM: eventfd: add irq bypass consumer management

Feng Wu (1):
  KVM: x86: select IRQ_BYPASS_MANAGER

 arch/arm/kvm/Kconfig      |   2 +
 arch/arm/kvm/Makefile     |   1 +
 arch/arm64/kvm/Kconfig    |   2 +
 arch/arm64/kvm/Makefile   |   1 +
 arch/x86/kvm/Kconfig      |   2 +
 arch/x86/kvm/Makefile     |   3 ++
 include/linux/kvm_host.h  |  10 +++++
 include/linux/kvm_irqfd.h |  71 ++++++++++++++++++++++++++++++
 virt/kvm/Kconfig          |   3 ++
 virt/kvm/eventfd.c        | 110 ++++++++++++++++------------------------------
 10 files changed, 133 insertions(+), 72 deletions(-)
 create mode 100644 include/linux/kvm_irqfd.h

-- 
1.9.1



From eric.auger at linaro.org  Mon Aug 10 06:31:04 2015
From: eric.auger at linaro.org (Eric Auger)
Date: Mon, 10 Aug 2015 15:31:04 +0200
Subject: [PATCH v5 2/5] KVM: arm/arm64: select IRQ_BYPASS_MANAGER
In-Reply-To: <1439213467-13668-1-git-send-email-eric.auger@linaro.org>
References: <1439213467-13668-1-git-send-email-eric.auger@linaro.org>
Message-ID: <1439213467-13668-3-git-send-email-eric.auger@linaro.org>

Select IRQ_BYPASS_MANAGER when CONFIG_KVM is set
Also add compilation of virt/lib.

Signed-off-by: Eric Auger <eric.auger at linaro.org>
Signed-off-by: Feng Wu <feng.wu at intel.com>

---

v3 -> v4:
- add compilation of virt/lib in arm/arm64 KVM

v2 -> v3:
- [Feng Wu] Correct a typo in 'arch/arm64/kvm/Kconfig'

v1 -> v2:
- also set IRQ_BYPASS_MANAGER for arm64
---
 arch/arm/kvm/Kconfig    | 2 ++
 arch/arm/kvm/Makefile   | 1 +
 arch/arm64/kvm/Kconfig  | 2 ++
 arch/arm64/kvm/Makefile | 1 +
 4 files changed, 6 insertions(+)

diff --git a/arch/arm/kvm/Kconfig b/arch/arm/kvm/Kconfig
index bfb915d..3c565b9 100644
--- a/arch/arm/kvm/Kconfig
+++ b/arch/arm/kvm/Kconfig
@@ -3,6 +3,7 @@
 #
 
 source "virt/kvm/Kconfig"
+source "virt/lib/Kconfig"
 
 menuconfig VIRTUALIZATION
 	bool "Virtualization"
@@ -31,6 +32,7 @@ config KVM
 	select KVM_VFIO
 	select HAVE_KVM_EVENTFD
 	select HAVE_KVM_IRQFD
+	select IRQ_BYPASS_MANAGER
 	depends on ARM_VIRT_EXT && ARM_LPAE && ARM_ARCH_TIMER
 	---help---
 	  Support hosting virtualized guest machines.
diff --git a/arch/arm/kvm/Makefile b/arch/arm/kvm/Makefile
index c5eef02c..a6a41dd 100644
--- a/arch/arm/kvm/Makefile
+++ b/arch/arm/kvm/Makefile
@@ -24,3 +24,4 @@ obj-y += $(KVM)/arm/vgic.o
 obj-y += $(KVM)/arm/vgic-v2.o
 obj-y += $(KVM)/arm/vgic-v2-emul.o
 obj-y += $(KVM)/arm/arch_timer.o
+obj-y += ../../../virt/lib/
diff --git a/arch/arm64/kvm/Kconfig b/arch/arm64/kvm/Kconfig
index bfffe8f..2509539 100644
--- a/arch/arm64/kvm/Kconfig
+++ b/arch/arm64/kvm/Kconfig
@@ -3,6 +3,7 @@
 #
 
 source "virt/kvm/Kconfig"
+source "virt/lib/Kconfig"
 
 menuconfig VIRTUALIZATION
 	bool "Virtualization"
@@ -31,6 +32,7 @@ config KVM
 	select KVM_VFIO
 	select HAVE_KVM_EVENTFD
 	select HAVE_KVM_IRQFD
+	select IRQ_BYPASS_MANAGER
 	---help---
 	  Support hosting virtualized guest machines.
 
diff --git a/arch/arm64/kvm/Makefile b/arch/arm64/kvm/Makefile
index f90f4aa..55eec69 100644
--- a/arch/arm64/kvm/Makefile
+++ b/arch/arm64/kvm/Makefile
@@ -27,3 +27,4 @@ kvm-$(CONFIG_KVM_ARM_HOST) += $(KVM)/arm/vgic-v3.o
 kvm-$(CONFIG_KVM_ARM_HOST) += $(KVM)/arm/vgic-v3-emul.o
 kvm-$(CONFIG_KVM_ARM_HOST) += vgic-v3-switch.o
 kvm-$(CONFIG_KVM_ARM_HOST) += $(KVM)/arm/arch_timer.o
+kvm-$(CONFIG_KVM_ARM_HOST) += ../../../virt/lib/
-- 
1.9.1



From eric.auger at linaro.org  Mon Aug 10 06:31:06 2015
From: eric.auger at linaro.org (Eric Auger)
Date: Mon, 10 Aug 2015 15:31:06 +0200
Subject: [PATCH v5 4/5] KVM: introduce kvm_arch functions for IRQ bypass
In-Reply-To: <1439213467-13668-1-git-send-email-eric.auger@linaro.org>
References: <1439213467-13668-1-git-send-email-eric.auger@linaro.org>
Message-ID: <1439213467-13668-5-git-send-email-eric.auger@linaro.org>

This patch introduces
- kvm_arch_irq_bypass_add_producer
- kvm_arch_irq_bypass_del_producer
- kvm_arch_irq_bypass_stop
- kvm_arch_irq_bypass_start

They make possible to specialize the KVM IRQ bypass consumer in
case CONFIG_KVM_HAVE_IRQ_BYPASS is set.

Signed-off-by: Eric Auger <eric.auger at linaro.org>
Signed-off-by: Feng Wu <feng.wu at intel.com>

---
v4 -> v5:
- remove static inline stub functions

v2 -> v3 (Feng Wu):
- use 'kvm_arch_irq_bypass_start' instead of 'kvm_arch_irq_bypass_resume'
- Remove 'kvm_arch_irq_bypass_update', which is not needed to be
  a irqbypass callback per Alex's comments.
- Make kvm_arch_irq_bypass_add_producer return 'int'

v1 -> v2:
- use CONFIG_KVM_HAVE_IRQ_BYPASS instead CONFIG_IRQ_BYPASS_MANAGER
- rename all functions according to Paolo's proposal
- add kvm_arch_irq_bypass_update according to Feng's need
---
 include/linux/kvm_host.h | 10 ++++++++++
 virt/kvm/Kconfig         |  3 +++
 2 files changed, 13 insertions(+)

diff --git a/include/linux/kvm_host.h b/include/linux/kvm_host.h
index 05e99b8..5ac8d21 100644
--- a/include/linux/kvm_host.h
+++ b/include/linux/kvm_host.h
@@ -24,6 +24,7 @@
 #include <linux/err.h>
 #include <linux/irqflags.h>
 #include <linux/context_tracking.h>
+#include <linux/irqbypass.h>
 #include <asm/signal.h>
 
 #include <linux/kvm.h>
@@ -1151,5 +1152,14 @@ static inline void kvm_vcpu_set_dy_eligible(struct kvm_vcpu *vcpu, bool val)
 {
 }
 #endif /* CONFIG_HAVE_KVM_CPU_RELAX_INTERCEPT */
+
+#ifdef CONFIG_HAVE_KVM_IRQ_BYPASS
+int kvm_arch_irq_bypass_add_producer(struct irq_bypass_consumer *,
+			   struct irq_bypass_producer *);
+void kvm_arch_irq_bypass_del_producer(struct irq_bypass_consumer *,
+			   struct irq_bypass_producer *);
+void kvm_arch_irq_bypass_stop(struct irq_bypass_consumer *);
+void kvm_arch_irq_bypass_start(struct irq_bypass_consumer *);
+#endif /* CONFIG_HAVE_KVM_IRQ_BYPASS */
 #endif
 
diff --git a/virt/kvm/Kconfig b/virt/kvm/Kconfig
index e2c876d..9f8014d 100644
--- a/virt/kvm/Kconfig
+++ b/virt/kvm/Kconfig
@@ -47,3 +47,6 @@ config KVM_GENERIC_DIRTYLOG_READ_PROTECT
 config KVM_COMPAT
        def_bool y
        depends on COMPAT && !S390
+
+config HAVE_KVM_IRQ_BYPASS
+       bool
-- 
1.9.1



From eric.auger at linaro.org  Mon Aug 10 06:31:07 2015
From: eric.auger at linaro.org (Eric Auger)
Date: Mon, 10 Aug 2015 15:31:07 +0200
Subject: [PATCH v5 5/5] KVM: eventfd: add irq bypass consumer management
In-Reply-To: <1439213467-13668-1-git-send-email-eric.auger@linaro.org>
References: <1439213467-13668-1-git-send-email-eric.auger@linaro.org>
Message-ID: <1439213467-13668-6-git-send-email-eric.auger@linaro.org>

This patch adds the registration/unregistration of an
irq_bypass_consumer on irqfd assignment/deassignment.

Signed-off-by: Eric Auger <eric.auger at linaro.org>
Signed-off-by: Feng Wu <feng.wu at intel.com>

---

v4 -> v5:
- due to removal of static inline stubs, add
  #ifdef CONFIG_HAVE_KVM_IRQ_BYPASS
  around consumer registration/unregistration
- add pr_info when registration fails

v2 -> v3 (Feng Wu):
- Use kvm_arch_irq_bypass_start
- Remove kvm_arch_irq_bypass_update
- Add member 'struct irq_bypass_producer *producer' in
  'struct kvm_kernel_irqfd', it is needed by posted interrupt.
- Remove 'irq_bypass_unregister_consumer' in kvm_irqfd_deassign()

v1 -> v2:
- populate of kvm and gsi removed
- unregister the consumer on irqfd_shutdown
---
 include/linux/kvm_irqfd.h |  2 ++
 virt/kvm/eventfd.c        | 15 +++++++++++++++
 2 files changed, 17 insertions(+)

diff --git a/include/linux/kvm_irqfd.h b/include/linux/kvm_irqfd.h
index f926b39..0c1de05 100644
--- a/include/linux/kvm_irqfd.h
+++ b/include/linux/kvm_irqfd.h
@@ -64,6 +64,8 @@ struct kvm_kernel_irqfd {
 	struct list_head list;
 	poll_table pt;
 	struct work_struct shutdown;
+	struct irq_bypass_consumer consumer;
+	struct irq_bypass_producer *producer;
 };
 
 #endif /* __LINUX_KVM_IRQFD_H */
diff --git a/virt/kvm/eventfd.c b/virt/kvm/eventfd.c
index 647ffb8..d7a230f 100644
--- a/virt/kvm/eventfd.c
+++ b/virt/kvm/eventfd.c
@@ -35,6 +35,7 @@
 #include <linux/srcu.h>
 #include <linux/slab.h>
 #include <linux/seqlock.h>
+#include <linux/irqbypass.h>
 #include <trace/events/kvm.h>
 
 #include <kvm/iodev.h>
@@ -140,6 +141,9 @@ irqfd_shutdown(struct work_struct *work)
 	/*
 	 * It is now safe to release the object's resources
 	 */
+#ifdef CONFIG_HAVE_KVM_IRQ_BYPASS
+	irq_bypass_unregister_consumer(&irqfd->consumer);
+#endif
 	eventfd_ctx_put(irqfd->eventfd);
 	kfree(irqfd);
 }
@@ -379,6 +383,17 @@ kvm_irqfd_assign(struct kvm *kvm, struct kvm_irqfd *args)
 	 * we might race against the POLLHUP
 	 */
 	fdput(f);
+#ifdef CONFIG_HAVE_KVM_IRQ_BYPASS
+	irqfd->consumer.token = (void *)irqfd->eventfd;
+	irqfd->consumer.add_producer = kvm_arch_irq_bypass_add_producer;
+	irqfd->consumer.del_producer = kvm_arch_irq_bypass_del_producer;
+	irqfd->consumer.stop = kvm_arch_irq_bypass_stop;
+	irqfd->consumer.start = kvm_arch_irq_bypass_start;
+	ret = irq_bypass_register_consumer(&irqfd->consumer);
+	if (ret)
+		pr_info("irq bypass consumer (token %p) registration fails: %d\n",
+				irqfd->consumer.token, ret);
+#endif
 
 	return 0;
 
-- 
1.9.1



From eric.auger at linaro.org  Mon Aug 10 06:31:05 2015
From: eric.auger at linaro.org (Eric Auger)
Date: Mon, 10 Aug 2015 15:31:05 +0200
Subject: [PATCH v5 3/5] KVM: create kvm_irqfd.h
In-Reply-To: <1439213467-13668-1-git-send-email-eric.auger@linaro.org>
References: <1439213467-13668-1-git-send-email-eric.auger@linaro.org>
Message-ID: <1439213467-13668-4-git-send-email-eric.auger@linaro.org>

Move _irqfd_resampler and _irqfd struct declarations in a new
public header: kvm_irqfd.h. They are respectively renamed into
kvm_kernel_irqfd_resampler and kvm_kernel_irqfd. Those datatypes
will be used by architecture specific code, in the context of
IRQ bypass manager integration.

Signed-off-by: Eric Auger <eric.auger at linaro.org>
---
 include/linux/kvm_irqfd.h | 69 ++++++++++++++++++++++++++++++++++
 virt/kvm/eventfd.c        | 95 ++++++++++++-----------------------------------
 2 files changed, 92 insertions(+), 72 deletions(-)
 create mode 100644 include/linux/kvm_irqfd.h

diff --git a/include/linux/kvm_irqfd.h b/include/linux/kvm_irqfd.h
new file mode 100644
index 0000000..f926b39
--- /dev/null
+++ b/include/linux/kvm_irqfd.h
@@ -0,0 +1,69 @@
+/*
+ * 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.
+ *
+ * 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.
+ *
+ * irqfd: Allows an fd to be used to inject an interrupt to the guest
+ * Credit goes to Avi Kivity for the original idea.
+ */
+
+#ifndef __LINUX_KVM_IRQFD_H
+#define __LINUX_KVM_IRQFD_H
+
+#include <linux/kvm_host.h>
+#include <linux/poll.h>
+
+/*
+ * Resampling irqfds are a special variety of irqfds used to emulate
+ * level triggered interrupts.  The interrupt is asserted on eventfd
+ * trigger.  On acknowledgment through the irq ack notifier, the
+ * interrupt is de-asserted and userspace is notified through the
+ * resamplefd.  All resamplers on the same gsi are de-asserted
+ * together, so we don't need to track the state of each individual
+ * user.  We can also therefore share the same irq source ID.
+ */
+struct kvm_kernel_irqfd_resampler {
+	struct kvm *kvm;
+	/*
+	 * List of resampling struct _irqfd objects sharing this gsi.
+	 * RCU list modified under kvm->irqfds.resampler_lock
+	 */
+	struct list_head list;
+	struct kvm_irq_ack_notifier notifier;
+	/*
+	 * Entry in list of kvm->irqfd.resampler_list.  Use for sharing
+	 * resamplers among irqfds on the same gsi.
+	 * Accessed and modified under kvm->irqfds.resampler_lock
+	 */
+	struct list_head link;
+};
+
+struct kvm_kernel_irqfd {
+	/* Used for MSI fast-path */
+	struct kvm *kvm;
+	wait_queue_t wait;
+	/* Update side is protected by irqfds.lock */
+	struct kvm_kernel_irq_routing_entry irq_entry;
+	seqcount_t irq_entry_sc;
+	/* Used for level IRQ fast-path */
+	int gsi;
+	struct work_struct inject;
+	/* The resampler used by this irqfd (resampler-only) */
+	struct kvm_kernel_irqfd_resampler *resampler;
+	/* Eventfd notified on resample (resampler-only) */
+	struct eventfd_ctx *resamplefd;
+	/* Entry in list of irqfds for a resampler (resampler-only) */
+	struct list_head resampler_link;
+	/* Used for setup/shutdown */
+	struct eventfd_ctx *eventfd;
+	struct list_head list;
+	poll_table pt;
+	struct work_struct shutdown;
+};
+
+#endif /* __LINUX_KVM_IRQFD_H */
diff --git a/virt/kvm/eventfd.c b/virt/kvm/eventfd.c
index 9ff4193..647ffb8 100644
--- a/virt/kvm/eventfd.c
+++ b/virt/kvm/eventfd.c
@@ -23,6 +23,7 @@
 
 #include <linux/kvm_host.h>
 #include <linux/kvm.h>
+#include <linux/kvm_irqfd.h>
 #include <linux/workqueue.h>
 #include <linux/syscalls.h>
 #include <linux/wait.h>
@@ -39,68 +40,14 @@
 #include <kvm/iodev.h>
 
 #ifdef CONFIG_HAVE_KVM_IRQFD
-/*
- * --------------------------------------------------------------------
- * irqfd: Allows an fd to be used to inject an interrupt to the guest
- *
- * Credit goes to Avi Kivity for the original idea.
- * --------------------------------------------------------------------
- */
-
-/*
- * Resampling irqfds are a special variety of irqfds used to emulate
- * level triggered interrupts.  The interrupt is asserted on eventfd
- * trigger.  On acknowledgement through the irq ack notifier, the
- * interrupt is de-asserted and userspace is notified through the
- * resamplefd.  All resamplers on the same gsi are de-asserted
- * together, so we don't need to track the state of each individual
- * user.  We can also therefore share the same irq source ID.
- */
-struct _irqfd_resampler {
-	struct kvm *kvm;
-	/*
-	 * List of resampling struct _irqfd objects sharing this gsi.
-	 * RCU list modified under kvm->irqfds.resampler_lock
-	 */
-	struct list_head list;
-	struct kvm_irq_ack_notifier notifier;
-	/*
-	 * Entry in list of kvm->irqfd.resampler_list.  Use for sharing
-	 * resamplers among irqfds on the same gsi.
-	 * Accessed and modified under kvm->irqfds.resampler_lock
-	 */
-	struct list_head link;
-};
-
-struct _irqfd {
-	/* Used for MSI fast-path */
-	struct kvm *kvm;
-	wait_queue_t wait;
-	/* Update side is protected by irqfds.lock */
-	struct kvm_kernel_irq_routing_entry irq_entry;
-	seqcount_t irq_entry_sc;
-	/* Used for level IRQ fast-path */
-	int gsi;
-	struct work_struct inject;
-	/* The resampler used by this irqfd (resampler-only) */
-	struct _irqfd_resampler *resampler;
-	/* Eventfd notified on resample (resampler-only) */
-	struct eventfd_ctx *resamplefd;
-	/* Entry in list of irqfds for a resampler (resampler-only) */
-	struct list_head resampler_link;
-	/* Used for setup/shutdown */
-	struct eventfd_ctx *eventfd;
-	struct list_head list;
-	poll_table pt;
-	struct work_struct shutdown;
-};
 
 static struct workqueue_struct *irqfd_cleanup_wq;
 
 static void
 irqfd_inject(struct work_struct *work)
 {
-	struct _irqfd *irqfd = container_of(work, struct _irqfd, inject);
+	struct kvm_kernel_irqfd *irqfd =
+		container_of(work, struct kvm_kernel_irqfd, inject);
 	struct kvm *kvm = irqfd->kvm;
 
 	if (!irqfd->resampler) {
@@ -121,12 +68,13 @@ irqfd_inject(struct work_struct *work)
 static void
 irqfd_resampler_ack(struct kvm_irq_ack_notifier *kian)
 {
-	struct _irqfd_resampler *resampler;
+	struct kvm_kernel_irqfd_resampler *resampler;
 	struct kvm *kvm;
-	struct _irqfd *irqfd;
+	struct kvm_kernel_irqfd *irqfd;
 	int idx;
 
-	resampler = container_of(kian, struct _irqfd_resampler, notifier);
+	resampler = container_of(kian,
+			struct kvm_kernel_irqfd_resampler, notifier);
 	kvm = resampler->kvm;
 
 	kvm_set_irq(kvm, KVM_IRQFD_RESAMPLE_IRQ_SOURCE_ID,
@@ -141,9 +89,9 @@ irqfd_resampler_ack(struct kvm_irq_ack_notifier *kian)
 }
 
 static void
-irqfd_resampler_shutdown(struct _irqfd *irqfd)
+irqfd_resampler_shutdown(struct kvm_kernel_irqfd *irqfd)
 {
-	struct _irqfd_resampler *resampler = irqfd->resampler;
+	struct kvm_kernel_irqfd_resampler *resampler = irqfd->resampler;
 	struct kvm *kvm = resampler->kvm;
 
 	mutex_lock(&kvm->irqfds.resampler_lock);
@@ -168,7 +116,8 @@ irqfd_resampler_shutdown(struct _irqfd *irqfd)
 static void
 irqfd_shutdown(struct work_struct *work)
 {
-	struct _irqfd *irqfd = container_of(work, struct _irqfd, shutdown);
+	struct kvm_kernel_irqfd *irqfd =
+		container_of(work, struct kvm_kernel_irqfd, shutdown);
 	u64 cnt;
 
 	/*
@@ -198,7 +147,7 @@ irqfd_shutdown(struct work_struct *work)
 
 /* assumes kvm->irqfds.lock is held */
 static bool
-irqfd_is_active(struct _irqfd *irqfd)
+irqfd_is_active(struct kvm_kernel_irqfd *irqfd)
 {
 	return list_empty(&irqfd->list) ? false : true;
 }
@@ -209,7 +158,7 @@ irqfd_is_active(struct _irqfd *irqfd)
  * assumes kvm->irqfds.lock is held
  */
 static void
-irqfd_deactivate(struct _irqfd *irqfd)
+irqfd_deactivate(struct kvm_kernel_irqfd *irqfd)
 {
 	BUG_ON(!irqfd_is_active(irqfd));
 
@@ -224,7 +173,8 @@ irqfd_deactivate(struct _irqfd *irqfd)
 static int
 irqfd_wakeup(wait_queue_t *wait, unsigned mode, int sync, void *key)
 {
-	struct _irqfd *irqfd = container_of(wait, struct _irqfd, wait);
+	struct kvm_kernel_irqfd *irqfd =
+		container_of(wait, struct kvm_kernel_irqfd, wait);
 	unsigned long flags = (unsigned long)key;
 	struct kvm_kernel_irq_routing_entry irq;
 	struct kvm *kvm = irqfd->kvm;
@@ -274,12 +224,13 @@ static void
 irqfd_ptable_queue_proc(struct file *file, wait_queue_head_t *wqh,
 			poll_table *pt)
 {
-	struct _irqfd *irqfd = container_of(pt, struct _irqfd, pt);
+	struct kvm_kernel_irqfd *irqfd =
+		container_of(pt, struct kvm_kernel_irqfd, pt);
 	add_wait_queue(wqh, &irqfd->wait);
 }
 
 /* Must be called under irqfds.lock */
-static void irqfd_update(struct kvm *kvm, struct _irqfd *irqfd)
+static void irqfd_update(struct kvm *kvm, struct kvm_kernel_irqfd *irqfd)
 {
 	struct kvm_kernel_irq_routing_entry *e;
 	struct kvm_kernel_irq_routing_entry entries[KVM_NR_IRQCHIPS];
@@ -304,7 +255,7 @@ static void irqfd_update(struct kvm *kvm, struct _irqfd *irqfd)
 static int
 kvm_irqfd_assign(struct kvm *kvm, struct kvm_irqfd *args)
 {
-	struct _irqfd *irqfd, *tmp;
+	struct kvm_kernel_irqfd *irqfd, *tmp;
 	struct fd f;
 	struct eventfd_ctx *eventfd = NULL, *resamplefd = NULL;
 	int ret;
@@ -340,7 +291,7 @@ kvm_irqfd_assign(struct kvm *kvm, struct kvm_irqfd *args)
 	irqfd->eventfd = eventfd;
 
 	if (args->flags & KVM_IRQFD_FLAG_RESAMPLE) {
-		struct _irqfd_resampler *resampler;
+		struct kvm_kernel_irqfd_resampler *resampler;
 
 		resamplefd = eventfd_ctx_fdget(args->resamplefd);
 		if (IS_ERR(resamplefd)) {
@@ -525,7 +476,7 @@ kvm_eventfd_init(struct kvm *kvm)
 static int
 kvm_irqfd_deassign(struct kvm *kvm, struct kvm_irqfd *args)
 {
-	struct _irqfd *irqfd, *tmp;
+	struct kvm_kernel_irqfd *irqfd, *tmp;
 	struct eventfd_ctx *eventfd;
 
 	eventfd = eventfd_ctx_fdget(args->fd);
@@ -581,7 +532,7 @@ kvm_irqfd(struct kvm *kvm, struct kvm_irqfd *args)
 void
 kvm_irqfd_release(struct kvm *kvm)
 {
-	struct _irqfd *irqfd, *tmp;
+	struct kvm_kernel_irqfd *irqfd, *tmp;
 
 	spin_lock_irq(&kvm->irqfds.lock);
 
@@ -604,7 +555,7 @@ kvm_irqfd_release(struct kvm *kvm)
  */
 void kvm_irq_routing_update(struct kvm *kvm)
 {
-	struct _irqfd *irqfd;
+	struct kvm_kernel_irqfd *irqfd;
 
 	spin_lock_irq(&kvm->irqfds.lock);
 
-- 
1.9.1



From zhichao.huang at linaro.org  Mon Aug 10 06:26:07 2015
From: zhichao.huang at linaro.org (Zhichao Huang)
Date: Mon, 10 Aug 2015 21:26:07 +0800
Subject: [PATCH v4 15/15] KVM: arm: enable trapping of all debug registers
In-Reply-To: <1439213167-8988-1-git-send-email-zhichao.huang@linaro.org>
References: <1439213167-8988-1-git-send-email-zhichao.huang@linaro.org>
Message-ID: <1439213167-8988-16-git-send-email-zhichao.huang@linaro.org>

Enable trapping of the debug registers unconditionally, allowing guests to
use the debug infrastructure.

Signed-off-by: Zhichao Huang <zhichao.huang at linaro.org>
Reviewed-by: Christoffer Dall <christoffer.dall at linaro.org>
---
 arch/arm/kvm/interrupts_head.S | 2 +-
 1 file changed, 1 insertion(+), 1 deletion(-)

diff --git a/arch/arm/kvm/interrupts_head.S b/arch/arm/kvm/interrupts_head.S
index 7ad0adf..494991d 100644
--- a/arch/arm/kvm/interrupts_head.S
+++ b/arch/arm/kvm/interrupts_head.S
@@ -792,7 +792,7 @@ ARM_BE8(rev	r6, r6  )
  * (hardware reset value is 0) */
 .macro set_hdcr operation
 	mrc	p15, 4, r2, c1, c1, 1
-	ldr	r3, =(HDCR_TPM|HDCR_TPMCR)
+	ldr	r3, =(HDCR_TPM|HDCR_TPMCR|HDCR_TDRA|HDCR_TDOSA|HDCR_TDA)
 	.if \operation == vmentry
 	orr	r2, r2, r3		@ Trap some perfmon accesses
 	.else
-- 
1.7.12.4



From eric.auger at linaro.org  Mon Aug 10 06:20:58 2015
From: eric.auger at linaro.org (Eric Auger)
Date: Mon, 10 Aug 2015 15:20:58 +0200
Subject: [PATCH v3 04/10] VFIO: platform: add vfio_platform_set_automasked
In-Reply-To: <1439212864-12954-1-git-send-email-eric.auger@linaro.org>
References: <1439212864-12954-1-git-send-email-eric.auger@linaro.org>
Message-ID: <1439212864-12954-5-git-send-email-eric.auger@linaro.org>

This function makes possible to change the automasked mode.

Signed-off-by: Eric Auger <eric.auger at linaro.org>

---

v1 -> v2:
- set forwarded flag
---
 drivers/vfio/platform/vfio_platform_irq.c | 19 +++++++++++++++++++
 1 file changed, 19 insertions(+)

diff --git a/drivers/vfio/platform/vfio_platform_irq.c b/drivers/vfio/platform/vfio_platform_irq.c
index b31b1f0..a285384 100644
--- a/drivers/vfio/platform/vfio_platform_irq.c
+++ b/drivers/vfio/platform/vfio_platform_irq.c
@@ -186,6 +186,25 @@ static irqreturn_t vfio_handler(int irq, void *dev_id)
 	return ret;
 }
 
+static int vfio_platform_set_automasked(struct vfio_platform_irq *irq,
+					   bool automasked)
+{
+	unsigned long flags;
+
+	spin_lock_irqsave(&irq->lock, flags);
+	if (automasked) {
+		irq->forwarded = true;
+		irq->flags |= VFIO_IRQ_INFO_AUTOMASKED;
+		irq->handler = vfio_automasked_irq_handler;
+	} else {
+		irq->forwarded = false;
+		irq->flags &= ~VFIO_IRQ_INFO_AUTOMASKED;
+		irq->handler = vfio_irq_handler;
+	}
+	spin_unlock_irqrestore(&irq->lock, flags);
+	return 0;
+}
+
 static void vfio_platform_irq_bypass_stop(struct irq_bypass_producer *prod)
 {
 }
-- 
1.9.1



From eric.auger at linaro.org  Mon Aug 10 06:31:03 2015
From: eric.auger at linaro.org (Eric Auger)
Date: Mon, 10 Aug 2015 15:31:03 +0200
Subject: [PATCH v5 1/5] KVM: x86: select IRQ_BYPASS_MANAGER
In-Reply-To: <1439213467-13668-1-git-send-email-eric.auger@linaro.org>
References: <1439213467-13668-1-git-send-email-eric.auger@linaro.org>
Message-ID: <1439213467-13668-2-git-send-email-eric.auger@linaro.org>

From: Feng Wu <feng.wu at intel.com>

Select IRQ_BYPASS_MANAGER for x86 when CONFIG_KVM is set

Signed-off-by: Feng Wu <feng.wu at intel.com>
---
 arch/x86/kvm/Kconfig  | 2 ++
 arch/x86/kvm/Makefile | 3 +++
 2 files changed, 5 insertions(+)

diff --git a/arch/x86/kvm/Kconfig b/arch/x86/kvm/Kconfig
index d8a1d56..c951d44 100644
--- a/arch/x86/kvm/Kconfig
+++ b/arch/x86/kvm/Kconfig
@@ -3,6 +3,7 @@
 #
 
 source "virt/kvm/Kconfig"
+source "virt/lib/Kconfig"
 
 menuconfig VIRTUALIZATION
 	bool "Virtualization"
@@ -28,6 +29,7 @@ config KVM
 	select ANON_INODES
 	select HAVE_KVM_IRQCHIP
 	select HAVE_KVM_IRQFD
+	select IRQ_BYPASS_MANAGER
 	select HAVE_KVM_IRQ_ROUTING
 	select HAVE_KVM_EVENTFD
 	select KVM_APIC_ARCHITECTURE
diff --git a/arch/x86/kvm/Makefile b/arch/x86/kvm/Makefile
index 67d215c..05cc2d7 100644
--- a/arch/x86/kvm/Makefile
+++ b/arch/x86/kvm/Makefile
@@ -6,6 +6,9 @@ CFLAGS_svm.o := -I.
 CFLAGS_vmx.o := -I.
 
 KVM := ../../../virt/kvm
+LIB := ../../../virt/lib
+
+obj-$(CONFIG_IRQ_BYPASS_MANAGER)	+= $(LIB)/
 
 kvm-y			+= $(KVM)/kvm_main.o $(KVM)/coalesced_mmio.o \
 				$(KVM)/eventfd.o $(KVM)/irqchip.o $(KVM)/vfio.o
-- 
1.9.1



From julien.grall at citrix.com  Mon Aug 10 06:36:10 2015
From: julien.grall at citrix.com (Julien Grall)
Date: Mon, 10 Aug 2015 14:36:10 +0100
Subject: [PATCH v3 12/20] xen/balloon: Don't rely on the page granularity
 is the same for Xen and Linux
In-Reply-To: <alpine.DEB.2.02.1508101352370.11337@kaball.uk.xensource.com>
References: <1438966019-19322-1-git-send-email-julien.grall@citrix.com>
 <1438966019-19322-13-git-send-email-julien.grall@citrix.com>
 <alpine.DEB.2.02.1508101207071.11337@kaball.uk.xensource.com>
 <55C88B77.8030700@citrix.com>
 <alpine.DEB.2.02.1508101352370.11337@kaball.uk.xensource.com>
Message-ID: <55C8A8CA.7070409@citrix.com>

On 10/08/15 13:55, Stefano Stabellini wrote:
>> If your only concern is the size of the array, we could decrease the
>> number of frames by batch. Or allocation the variable once a boot time.
> 
> Yes, that is my only concern. Allocating only nr_pages new struct page*
> would be good enough I guess.

That would be even worst. We shouldn't allocate the array at every call,
but at boot time.

Note that frame_list is already a static variable use 64KB when 64KB
page is used. I guess this will be unlikely to remove that much frame in
a single batch. But I will keep this optimization for later.

Anyway, I'm wondering if we could re-use the lru field to link the page
when allocate them and retrieve in the second loop in order to avoid the
pages array.

Regards,

-- 
Julien Grall


From eric.auger at linaro.org  Mon Aug 10 06:39:02 2015
From: eric.auger at linaro.org (Eric Auger)
Date: Mon, 10 Aug 2015 15:39:02 +0200
Subject: [PATCH v3 0/7] KVM: arm/arm64: gsi routing support
In-Reply-To: <002401d0d040$5667c530$03374f90$@samsung.com>
References: <1438615889-10892-1-git-send-email-eric.auger@linaro.org>
 <002401d0d040$5667c530$03374f90$@samsung.com>
Message-ID: <55C8A976.1090303@linaro.org>

Hi Pavel,
On 08/06/2015 02:06 PM, Pavel Fedin wrote:
> Tested-by: Pavel Fedin <p.fedin at samsung.com>

Many thanks for testing!

Best Regards

Eric
> 
> Kind regards,
> Pavel Fedin
> Expert Engineer
> Samsung Electronics Research center Russia
> 
>> -----Original Message-----
>> From: Eric Auger [mailto:eric.auger at linaro.org]
>> Sent: Monday, August 03, 2015 6:31 PM
>> To: eric.auger at st.com; eric.auger at linaro.org; linux-arm-kernel at lists.infradead.org;
>> kvmarm at lists.cs.columbia.edu; kvm at vger.kernel.org; christoffer.dall at linaro.org;
>> marc.zyngier at arm.com
>> Cc: linux-kernel at vger.kernel.org; patches at linaro.org; pbonzini at redhat.com;
>> andre.przywara at arm.com; p.fedin at samsung.com
>> Subject: [PATCH v3 0/7] KVM: arm/arm64: gsi routing support
>>
>> With the advent of GICv3 ITS in-kernel emulation, KVM GSI routing
>> appears to be requested. More specifically MSI routing is needed.
>> irqchip routing does not sound to be really useful on arm but usage of
>> MSI routing also mandates to integrate irqchip routing. The initial
>> implementation of irqfd on arm must be upgraded with the integration
>> of kvm irqchip.c code and the implementation of its standard hooks
>> in the architecture specific part.
>>
>> In case KVM_SET_GSI_ROUTING ioctl is not called, a default routing
>> table with flat irqchip routing entries is built enabling to inject gsi
>> corresponding to the SPI indexes seen by the guest.
>>
>> As soon as KVM_SET_GSI_ROUTING is called, user-space overwrites this
>> default routing table and is responsible for building the whole routing
>> table.
>>
>> for arm/arm64 KVM_SET_GSI_ROUTING has a limited support:
>> - only applies to KVM_IRQFD and not to KVM_IRQ_LINE
>>
>> - irqchip routing was tested on Calxeda midway (VFIO with irqfd)
>>   with and without explicit routing
>> - MSI routing without GICv3 ITS was tested using APM Xgene-I
>>   (qemu VIRTIO-PCI vhost-net without gsi_direct_mapping).
>> - MSI routing with GICv3 ITS is *NOT* tested.
>>
>> Code can be found at
> https://git.linaro.org/people/eric.auger/linux.git/shortlog/refs/heads/v4.2-rc4-
>> gsi-routing-v3
>>
>> It applies on Andre's [PATCH v2 00/15] KVM: arm64: GICv3 ITS emulation
>> (http://lists.infradead.org/pipermail/linux-arm-kernel/2015-July/355727.html)
>>
>> History:
>> v2 -> v3:
>> - eventually got rid of KVM_IRQ_ROUTING_EXTENDED_MSI new type at user
>>   api level and use KVM_MSI_VALID_DEVID flag instead
>> - remove usage of KVM_IRQ_ROUTING_EXTENDED_MSI type at kernel level too.
>> - propagate user flags downto the kernel to make sure the userspace
>>   correctly set devid in GICv3 ITS case (still under discussion)
>>
>> v1 -> v2:
>> - user API changed:
>>   x devid id passed in kvm_irq_routing_msi
>>   x kept the new routing entry type: KVM_IRQ_ROUTING_EXTENDED_MSI
>> - kvm_host.h: adopt Andre's proposal to replace the msi_msg by a struct
>>   composed of the msi_msg and devid in kvm_kernel_irq_routing_entry
>> - Fix bug reported by Pavel: Added KVM_IRQ_ROUTING_EXTENDED_MSI handling
>>   in eventfd.c
>> - added vgic_v2m_inject_msi in vgic-v2-emul.c as suggested by Andre
>> - fix bug reported by Andre: bad setting of msi.flags and msi.devid
>>   in kvm_send_userspace_msi
>> - avoid injecting reserved IRQ numbers in vgic_irqfd_set_irq
>>
>> RFC -> PATCH:
>> - clearly state limited support on arm/arm64:
>>   KVM_IRQ_LINE not impacted by GSI routing
>> - add default routing table feature (new patch file)
>> - changed uapi to use padding field area
>> - reword api.txt
>>
>> Eric Auger (7):
>>   KVM: api: pass the devid in the msi routing entry
>>   KVM: kvm_host: add devid in kvm_kernel_irq_routing_entry
>>   KVM: irqchip: convey devid to kvm_set_msi
>>   KVM: arm/arm64: enable irqchip routing
>>   KVM: arm/arm64: build a default routing table
>>   KVM: arm/arm64: enable MSI routing
>>   KVM: arm: enable KVM_SIGNAL_MSI and MSI routing
>>
>>  Documentation/virtual/kvm/api.txt |  35 ++++++++++---
>>  arch/arm/include/asm/kvm_host.h   |   2 +
>>  arch/arm/kvm/Kconfig              |   3 ++
>>  arch/arm/kvm/Makefile             |   2 +-
>>  arch/arm64/include/asm/kvm_host.h |   1 +
>>  arch/arm64/kvm/Kconfig            |   2 +
>>  arch/arm64/kvm/Makefile           |   2 +-
>>  include/kvm/arm_vgic.h            |   2 -
>>  include/linux/kvm_host.h          |   8 ++-
>>  include/uapi/linux/kvm.h          |   5 +-
>>  virt/kvm/arm/vgic-v2-emul.c       |  16 ++++++
>>  virt/kvm/arm/vgic.c               | 107 ++++++++++++++++++++++++++++++--------
>>  virt/kvm/irqchip.c                |   8 ++-
>>  13 files changed, 158 insertions(+), 35 deletions(-)
>>
>> --
>> 1.9.1
> 



From lee.jones at linaro.org  Mon Aug 10 06:47:47 2015
From: lee.jones at linaro.org (Lee Jones)
Date: Mon, 10 Aug 2015 14:47:47 +0100
Subject: [PATCH v3] mfd: mt6397: Implement wake handler and
 suspend/resume to handle wake up event.
In-Reply-To: <1439212245-18935-1-git-send-email-henryc.chen@mediatek.com>
References: <1439212245-18935-1-git-send-email-henryc.chen@mediatek.com>
Message-ID: <20150810134747.GI3249@x1>

On Mon, 10 Aug 2015, Henry Chen wrote:

> Implement .irq_set_wake() to get who is wakeup source and setup on suspend/reumse. Enable
> mt6393_irq as wake up source properly to pinctrl by enable_irq_wake()/enable_irq_wake().
> 
> Reviewed-by: Lee Jones <lee.jones at linaro.org>

I don't think this means what you think it means.

In future, please don't add {Acked,Reviewed,Tested,etc}-bys unless
someone explicitly sends you one, for example:

"Acked-by: Lee Jones <lee.jones at linaro.org>"

I'll remove this and apply the correct tags.

Patch applied, thanks.

> Signed-off-by: Henry Chen <henryc.chen at mediatek.com>
> ---
> Changes since v2:
> Remove the filename of title.
> Remove irrelevant change.
> 
> Chandes since v1:
> Used enable_irq_wake()/disable_irq_wake to handle irq wakeup source.
> 
>  drivers/mfd/mt6397-core.c       | 49 +++++++++++++++++++++++++++++++++++++++++
>  include/linux/mfd/mt6397/core.h |  1 +
>  2 files changed, 50 insertions(+)
> 
> diff --git a/drivers/mfd/mt6397-core.c b/drivers/mfd/mt6397-core.c
> index 03929a6..e7d5a67 100644
> --- a/drivers/mfd/mt6397-core.c
> +++ b/drivers/mfd/mt6397-core.c
> @@ -93,12 +93,31 @@ static void mt6397_irq_enable(struct irq_data *data)
>  	mt6397->irq_masks_cur[reg] |= BIT(shift);
>  }
>  
> +#ifdef CONFIG_PM_SLEEP
> +static int mt6397_irq_set_wake(struct irq_data *irq_data, unsigned int on)
> +{
> +	struct mt6397_chip *mt6397 = irq_data_get_irq_chip_data(irq_data);
> +	int shift = irq_data->hwirq & 0xf;
> +	int reg = irq_data->hwirq >> 4;
> +
> +	if (on)
> +		mt6397->wake_mask[reg] |= BIT(shift);
> +	else
> +		mt6397->wake_mask[reg] &= ~BIT(shift);
> +
> +	return 0;
> +}
> +#else
> +#define mt6397_irq_set_wake NULL
> +#endif
> +
>  static struct irq_chip mt6397_irq_chip = {
>  	.name = "mt6397-irq",
>  	.irq_bus_lock = mt6397_irq_lock,
>  	.irq_bus_sync_unlock = mt6397_irq_sync_unlock,
>  	.irq_enable = mt6397_irq_enable,
>  	.irq_disable = mt6397_irq_disable,
> +	.irq_set_wake = mt6397_irq_set_wake,
>  };
>  
>  static void mt6397_irq_handle_reg(struct mt6397_chip *mt6397, int reg,
> @@ -183,6 +202,35 @@ static int mt6397_irq_init(struct mt6397_chip *mt6397)
>  	return 0;
>  }
>  
> +#ifdef CONFIG_PM_SLEEP
> +static int mt6397_irq_suspend(struct device *dev)
> +{
> +	struct mt6397_chip *chip = dev_get_drvdata(dev);
> +
> +	regmap_write(chip->regmap, MT6397_INT_CON0, chip->wake_mask[0]);
> +	regmap_write(chip->regmap, MT6397_INT_CON1, chip->wake_mask[1]);
> +
> +	enable_irq_wake(chip->irq);
> +
> +	return 0;
> +}
> +
> +static int mt6397_irq_resume(struct device *dev)
> +{
> +	struct mt6397_chip *chip = dev_get_drvdata(dev);
> +
> +	regmap_write(chip->regmap, MT6397_INT_CON0, chip->irq_masks_cur[0]);
> +	regmap_write(chip->regmap, MT6397_INT_CON1, chip->irq_masks_cur[1]);
> +
> +	disable_irq_wake(chip->irq);
> +
> +	return 0;
> +}
> +#endif
> +
> +static SIMPLE_DEV_PM_OPS(mt6397_pm_ops, mt6397_irq_suspend,
> +			mt6397_irq_resume);
> +
>  static int mt6397_probe(struct platform_device *pdev)
>  {
>  	int ret;
> @@ -237,6 +285,7 @@ static struct platform_driver mt6397_driver = {
>  	.driver = {
>  		.name = "mt6397",
>  		.of_match_table = of_match_ptr(mt6397_of_match),
> +		.pm = &mt6397_pm_ops,
>  	},
>  };
>  
> diff --git a/include/linux/mfd/mt6397/core.h b/include/linux/mfd/mt6397/core.h
> index cf5265b..45b8e8a 100644
> --- a/include/linux/mfd/mt6397/core.h
> +++ b/include/linux/mfd/mt6397/core.h
> @@ -57,6 +57,7 @@ struct mt6397_chip {
>  	int irq;
>  	struct irq_domain *irq_domain;
>  	struct mutex irqlock;
> +	u16 wake_mask[2];
>  	u16 irq_masks_cur[2];
>  	u16 irq_masks_cache[2];
>  };

-- 
Lee Jones
Linaro STMicroelectronics Landing Team Lead
Linaro.org ? Open source software for ARM SoCs
Follow Linaro: Facebook | Twitter | Blog


From gregory.clement at free-electrons.com  Mon Aug 10 06:47:51 2015
From: gregory.clement at free-electrons.com (Gregory CLEMENT)
Date: Mon, 10 Aug 2015 15:47:51 +0200
Subject: [PATCH] ARM: mvebu: Use a CR_C constant instead of a hard-coded one
Message-ID: <1439214471-25902-1-git-send-email-gregory.clement@free-electrons.com>

Fix the armada_370_xp_pmsu_idle_enter() function to use a CR_C
constant instead of a hard-coded constant in the assembly part.
This clean-up was suggested by Russell King.

Signed-off-by: Gregory CLEMENT <gregory.clement at free-electrons.com>
---
Hi,

this clean-up is not for 4.2 neither for 4.3 (the rc6 had just been
released), but for 4.4. I send it now to not forget it.

Gregory

 arch/arm/mach-mvebu/pmsu.c | 4 ++--
 1 file changed, 2 insertions(+), 2 deletions(-)

diff --git a/arch/arm/mach-mvebu/pmsu.c b/arch/arm/mach-mvebu/pmsu.c
index 4f4e22206ae5..8efb83cea83d 100644
--- a/arch/arm/mach-mvebu/pmsu.c
+++ b/arch/arm/mach-mvebu/pmsu.c
@@ -296,11 +296,11 @@ int armada_370_xp_pmsu_idle_enter(unsigned long deepidle)
 	/* Test the CR_C bit and set it if it was cleared */
 	asm volatile(
 	"mrc	p15, 0, r0, c1, c0, 0 \n\t"
-	"tst	r0, #(1 << 2) \n\t"
+	"tst	r0, %0 \n\t"
 	"orreq	r0, r0, #(1 << 2) \n\t"
 	"mcreq	p15, 0, r0, c1, c0, 0 \n\t"
 	"isb	"
-	: : : "r0");
+	: : "Ir" (CR_C) : "r0");
 
 	pr_debug("Failed to suspend the system\n");
 
-- 
2.1.0



From maitysanchayan at gmail.com  Mon Aug 10 07:11:28 2015
From: maitysanchayan at gmail.com (Sanchayan Maity)
Date: Mon, 10 Aug 2015 19:41:28 +0530
Subject: [PATCH v8 0/4] Implement OCOTP driver for Vybrid using NVMEM
Message-ID: <cover.1439214648.git.maitysanchayan@gmail.com>

Hello,

This patchset is based on top of v9 of Srinivas's NVMEM framework patches.
Tested using v9 NVMEM patches which got merged after applying them on
shawn's tree for-next branch along with Stefan's NAND driver patchset.

Sample output on Colibri VF50

root at colibri-vf:/sys/bus/nvmem/devices/ocotp0# hexdump nvmem
0000000 0000 0000 0000 0000 0000 0000 0000 0000
*
0000410 72a6 df64 0000 0000 0000 0000 0000 0000
0000420 11d4 2c14 0000 0000 0000 0000 0000 0000
0000430 0000 0000 0000 0000 0000 0000 0000 0000
*
0000450 0280 0000 0000 0000 0000 0000 0000 0000
0000460 0000 0000 0000 0000 0000 0000 0000 0000
*
0000880 8f01 0000 0000 0000 0000 0000 0000 0000
0000890 0000 0000 0000 0000 0000 0000 0000 0000
*
00008c0 0000 1000 0000 0000 0000 0000 0000 0000
00008d0 3202 0800 0000 0000 0000 0000 0000 0000
00008e0 0000 e100 0000 0000 0000 0000 0000 0000
00008f0 0000 0000 0000 0000 0000 0000 0000 0000
*
0000c80 bada bada 0000 0000 0000 0000 0000 0000
*
0000cc0 0000 0000 0000 0000 0000 0000 0000 0000
*
0000cf0

The driver has changed quite a bit from the first version
relying on of_platform_populate in mach file, to using
SoC driver under drivers/soc and finally to NVMEM.

Feedback and comments most welcome.

Version 7 patches can be found here
https://lkml.org/lkml/2015/8/6/440

Version 6 RFC patches can be found here
http://lkml.iu.edu/hypermail/linux/kernel/1506.2/05123.html

Version 5 of the patchset can be found here
http://lkml.iu.edu/hypermail/linux/kernel/1506.0/03787.html

Version 4 of the patchset can be found here
https://lkml.org/lkml/2015/5/26/199

Version 3 of the patchset can be found here
http://www.spinics.net/lists/arm-kernel/msg420847.html

Version 2 of the patchset can be found here
http://www.spinics.net/lists/devicetree/msg80654.html

Version 1 of the patchset can be found here
http://www.spinics.net/lists/devicetree/msg80257.html

The RFC version can be found here
https://lkml.org/lkml/2015/5/11/13

Changes since v7:
1. Add COMPILE_TEST to Kconfig
2. Use GENMASK and BIT macros where applicable
3. Fix a code alignment issue
4. Get the max_register value for regmap config using
resource_size()
5. Also add copyright info as the driver logic is based off
on ocotp code in barebox
6. Add missing info related to clock in DT binding doc

Changes since v6:
1. Use the v9 of NVMEM framework patchset
2. Add a few comments
3. Initialise buffer address not part of the fuse map to 0
instead of only handling buffer locations with valid fuse
addresses.

Changes since v5:
Use NVMEM framework by Srinivas and Maxime

Changes since v4:
1. Use devm_* family of functions and use a struct to get rid of
global variables (suggested by Joachim Eastwood)
2. Make Kconfig govern the compilation with tristate, instead of
earlier bool. Paul Bolle raised a valid point that perhaps this
should have been built in with the bool, however I had not taken
into consideration generic distro kernels and it makes sense to
have this tristated. (comments from Paul Bolle and Andreas Farber)

Changes since v3:
Instead of using the syscon_regmap_lookup_by_compatible function
use a phandle in the device tree along with offsets specified in
this phandle node and then read the offset along with the device
node in the driver for reading from the required region.

Changes since v2:
Implement the SoC bus code as a driver in drivers/soc
by registering with fsl,mscm-cpucfg as per Arnd's feedback

Changes since v1:
Sort the headers in alphabetical order

Changes since RFC:
Use a DT entry for the ROM area while specifying it as syscon.

Thanks & Regards,
Sanchayan Maity.

Sanchayan Maity (4):
  clk: clk-vf610: Add clock for Vybrid OCOTP controller
  ARM: dts: vfxxx: Add OCOTP node
  drivers: nvmem: Add Vybrid OCOTP support
  nvmem: Add DT binding documentation for Vybrid OCOTP driver

 .../devicetree/bindings/nvmem/vf610-ocotp.txt      |  21 ++
 arch/arm/boot/dts/vfxxx.dtsi                       |   9 +
 drivers/clk/imx/clk-vf610.c                        |   1 +
 drivers/nvmem/Kconfig                              |  10 +
 drivers/nvmem/Makefile                             |   2 +
 drivers/nvmem/vf610-ocotp.c                        | 301 +++++++++++++++++++++
 include/dt-bindings/clock/vf610-clock.h            |   3 +-
 7 files changed, 346 insertions(+), 1 deletion(-)
 create mode 100644 Documentation/devicetree/bindings/nvmem/vf610-ocotp.txt
 create mode 100644 drivers/nvmem/vf610-ocotp.c

-- 
2.5.0



From maitysanchayan at gmail.com  Mon Aug 10 07:11:29 2015
From: maitysanchayan at gmail.com (Sanchayan Maity)
Date: Mon, 10 Aug 2015 19:41:29 +0530
Subject: [PATCH v8 1/4] clk: clk-vf610: Add clock for Vybrid OCOTP controller
In-Reply-To: <cover.1439214648.git.maitysanchayan@gmail.com>
References: <cover.1439214648.git.maitysanchayan@gmail.com>
Message-ID: <fe5ec67cc9d29d28eec9da442140b614ca8fecd7.1439214648.git.maitysanchayan@gmail.com>

Add clock support for Vybrid On-Chip One Time Programmable
(OCOTP) controller.

While the OCOTP block does not require explicit clock gating,
for programming the OCOTP timing register the clock rate of
ipg clock is required for timing calculations related to fuse
and shadow register read sequence. We explicitly specify the
ipg clock for OCOTP as a result.

Signed-off-by: Sanchayan Maity <maitysanchayan at gmail.com>
---
 drivers/clk/imx/clk-vf610.c             | 1 +
 include/dt-bindings/clock/vf610-clock.h | 3 ++-
 2 files changed, 3 insertions(+), 1 deletion(-)

diff --git a/drivers/clk/imx/clk-vf610.c b/drivers/clk/imx/clk-vf610.c
index bff45ea..d1b1c95 100644
--- a/drivers/clk/imx/clk-vf610.c
+++ b/drivers/clk/imx/clk-vf610.c
@@ -387,6 +387,7 @@ static void __init vf610_clocks_init(struct device_node *ccm_node)
 
 	clk[VF610_CLK_SNVS] = imx_clk_gate2("snvs-rtc", "ipg_bus", CCM_CCGR6, CCM_CCGRx_CGn(7));
 	clk[VF610_CLK_DAP] = imx_clk_gate("dap", "platform_bus", CCM_CCSR, 24);
+	clk[VF610_CLK_OCOTP] = imx_clk_gate("ocotp", "ipg_bus", CCM_CCGR6, CCM_CCGRx_CGn(5));
 
 	imx_check_clocks(clk, ARRAY_SIZE(clk));
 
diff --git a/include/dt-bindings/clock/vf610-clock.h b/include/dt-bindings/clock/vf610-clock.h
index d197634..56c16aa 100644
--- a/include/dt-bindings/clock/vf610-clock.h
+++ b/include/dt-bindings/clock/vf610-clock.h
@@ -194,6 +194,7 @@
 #define VF610_PLL7_BYPASS		181
 #define VF610_CLK_SNVS			182
 #define VF610_CLK_DAP			183
-#define VF610_CLK_END			184
+#define VF610_CLK_OCOTP         184
+#define VF610_CLK_END			185
 
 #endif /* __DT_BINDINGS_CLOCK_VF610_H */
-- 
2.5.0



From maitysanchayan at gmail.com  Mon Aug 10 07:11:30 2015
From: maitysanchayan at gmail.com (Sanchayan Maity)
Date: Mon, 10 Aug 2015 19:41:30 +0530
Subject: [PATCH v8 2/4] ARM: dts: vfxxx: Add OCOTP node
In-Reply-To: <cover.1439214648.git.maitysanchayan@gmail.com>
References: <cover.1439214648.git.maitysanchayan@gmail.com>
Message-ID: <0ce479474fde4e8e652b144b025f3ecc42786ec7.1439214648.git.maitysanchayan@gmail.com>

Add device tree node for the On-Chip One Time Programmable
controller (OCOTP) on the Vybrid platform.

Signed-off-by: Sanchayan Maity <maitysanchayan at gmail.com>
---
 arch/arm/boot/dts/vfxxx.dtsi | 9 +++++++++
 1 file changed, 9 insertions(+)

diff --git a/arch/arm/boot/dts/vfxxx.dtsi b/arch/arm/boot/dts/vfxxx.dtsi
index 39173bb..8577211 100644
--- a/arch/arm/boot/dts/vfxxx.dtsi
+++ b/arch/arm/boot/dts/vfxxx.dtsi
@@ -419,6 +419,15 @@
 				status = "disabled";
 			};
 
+			ocotp: ocotp at 400a5000 {
+				compatible = "fsl,vf610-ocotp";
+				#address-cells = <1>;
+				#size-cells = <1>;
+				reg = <0x400a5000 0xCF0>;
+				clocks = <&clks VF610_CLK_OCOTP>;
+				clock-names = "ocotp";
+			};
+
 			snvs0: snvs at 400a7000 {
 			    compatible = "fsl,sec-v4.0-mon", "syscon", "simple-mfd";
 				reg = <0x400a7000 0x2000>;
-- 
2.5.0



From maitysanchayan at gmail.com  Mon Aug 10 07:11:32 2015
From: maitysanchayan at gmail.com (Sanchayan Maity)
Date: Mon, 10 Aug 2015 19:41:32 +0530
Subject: [PATCH v8 4/4] nvmem: Add DT binding documentation for Vybrid OCOTP
 driver
In-Reply-To: <cover.1439214648.git.maitysanchayan@gmail.com>
References: <cover.1439214648.git.maitysanchayan@gmail.com>
Message-ID: <3149879671b1b1b0b6fc1fbe62e9f49333deb8ed.1439214648.git.maitysanchayan@gmail.com>

Add the devicetree bindings for the Freescale Vybrid On-Chip
OTP driver.

Signed-off-by: Sanchayan Maity <maitysanchayan at gmail.com>
---
 .../devicetree/bindings/nvmem/vf610-ocotp.txt       | 21 +++++++++++++++++++++
 1 file changed, 21 insertions(+)
 create mode 100644 Documentation/devicetree/bindings/nvmem/vf610-ocotp.txt

diff --git a/Documentation/devicetree/bindings/nvmem/vf610-ocotp.txt b/Documentation/devicetree/bindings/nvmem/vf610-ocotp.txt
new file mode 100644
index 0000000..b29f65f
--- /dev/null
+++ b/Documentation/devicetree/bindings/nvmem/vf610-ocotp.txt
@@ -0,0 +1,21 @@
+On-Chip OTP Memory for Freescale Vybrid
+
+Required Properties:
+  compatible:
+  - "fsl,vf610-ocotp" for VF5xx/VF6xx
+  #address-cells : Should be 1
+  #size-cells : Should be 1
+  reg : Address and length of OTP controller and fuse map registers
+  clocks : ipg clock we associate with the OCOTP peripheral
+  clock-names : Must contain "ocotp" as matching entry
+
+Example for Vybrid VF5xx/VF6xx:
+
+	ocotp: ocotp at 400a5000 {
+		compatible = "fsl,vf610-ocotp";
+		#address-cells = <1>;
+		#size-cells = <1>;
+		reg = <0x400a5000 0xCF0>;
+		clocks = <&clks VF610_CLK_OCOTP>;
+		clock-names = "ocotp";
+	};
-- 
2.5.0



From maitysanchayan at gmail.com  Mon Aug 10 07:11:31 2015
From: maitysanchayan at gmail.com (Sanchayan Maity)
Date: Mon, 10 Aug 2015 19:41:31 +0530
Subject: [PATCH v8 3/4] drivers: nvmem: Add Vybrid OCOTP support
In-Reply-To: <cover.1439214648.git.maitysanchayan@gmail.com>
References: <cover.1439214648.git.maitysanchayan@gmail.com>
Message-ID: <29b527f1897b24a310a3f3acee61c721d3399503.1439214648.git.maitysanchayan@gmail.com>

The patch adds support for the On Chip One Time Programmable Peripheral
(OCOTP) on the Vybrid platform.

Signed-off-by: Sanchayan Maity <maitysanchayan at gmail.com>
---
 drivers/nvmem/Kconfig       |  10 ++
 drivers/nvmem/Makefile      |   2 +
 drivers/nvmem/vf610-ocotp.c | 301 ++++++++++++++++++++++++++++++++++++++++++++
 3 files changed, 313 insertions(+)
 create mode 100644 drivers/nvmem/vf610-ocotp.c

diff --git a/drivers/nvmem/Kconfig b/drivers/nvmem/Kconfig
index 0b33014..7af4c1d 100644
--- a/drivers/nvmem/Kconfig
+++ b/drivers/nvmem/Kconfig
@@ -47,4 +47,14 @@ config NVMEM_IMX_OCOTP
 	  This driver can also be built as a module. If so, the module
 	  will be called nvmem-imx-ocotp.
 
+config NVMEM_VF610_OCOTP
+	tristate "VF610_SoCs OCOTP support"
+	depends on SOC_VF610 || COMPILE_TEST
+	help
+	  This is a driver for the 'OCOTP' peripheral available on Vybrid
+	  devices like VF5xx and VF6xx.
+
+	  This driver can also be built as a module. If so, the module will
+	  be called nvmem-vf610-ocotp.
+
 endif
diff --git a/drivers/nvmem/Makefile b/drivers/nvmem/Makefile
index b512d77..8a1eea8 100644
--- a/drivers/nvmem/Makefile
+++ b/drivers/nvmem/Makefile
@@ -12,3 +12,5 @@ obj-$(CONFIG_NVMEM_SUNXI_SID)	+= nvmem_sunxi_sid.o
 nvmem_sunxi_sid-y		:= sunxi_sid.o
 obj-$(CONFIG_NVMEM_IMX_OCOTP)	+= nvmem-imx-ocotp.o
 nvmem-imx-ocotp-y		:= imx-ocotp.o
+obj-$(CONFIG_NVMEM_VF610_OCOTP)	+= nvmem-vf610-ocotp.o
+nvmem-vf610-ocotp-y		:= vf610-ocotp.o
diff --git a/drivers/nvmem/vf610-ocotp.c b/drivers/nvmem/vf610-ocotp.c
new file mode 100644
index 0000000..9e18156
--- /dev/null
+++ b/drivers/nvmem/vf610-ocotp.c
@@ -0,0 +1,301 @@
+/*
+ * Copyright (C) 2015 Toradex AG.
+ *
+ * Author: Sanchayan Maity <sanchayan.maity at toradex.com>
+ *
+ * Based on the barebox ocotp driver,
+ * Copyright (c) 2010 Baruch Siach <baruch at tkos.co.il>
+ *	Orex Computed Radiography
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License version 2 and
+ * only 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/clk.h>
+#include <linux/delay.h>
+#include <linux/device.h>
+#include <linux/io.h>
+#include <linux/module.h>
+#include <linux/nvmem-provider.h>
+#include <linux/of.h>
+#include <linux/platform_device.h>
+#include <linux/regmap.h>
+#include <linux/slab.h>
+
+/* OCOTP Register Offsets */
+#define OCOTP_CTRL_REG				0x00
+#define OCOTP_CTRL_SET				0x04
+#define OCOTP_CTRL_CLR				0x08
+#define OCOTP_TIMING				0x10
+#define OCOTP_DATA				0x20
+#define OCOTP_READ_CTRL_REG			0x30
+#define OCOTP_READ_FUSE_DATA			0x40
+
+/* OCOTP Register bits and masks */
+#define OCOTP_CTRL_WR_UNLOCK			16
+#define OCOTP_CTRL_WR_UNLOCK_KEY		0x3E77
+#define OCOTP_CTRL_WR_UNLOCK_MASK		GENMASK(31, 16)
+#define OCOTP_CTRL_ADDR				0
+#define OCOTP_CTRL_ADDR_MASK			GENMASK(6, 0)
+#define OCOTP_CTRL_RELOAD_SHADOWS		BIT(10)
+#define OCOTP_CTRL_ERROR			BIT(9)
+#define OCOTP_CTRL_BUSY				BIT(8)
+
+#define OCOTP_TIMING_STROBE_READ		16
+#define OCOTP_TIMING_STROBE_READ_MASK		GENMASK(21, 16)
+#define OCOTP_TIMING_RELAX			12
+#define OCOTP_TIMING_RELAX_MASK			GENMASK(15, 12)
+#define OCOTP_TIMING_STROBE_PROG		0
+#define OCOTP_TIMING_STROBE_PROG_MASK		GENMASK(11, 0)
+
+#define OCOTP_READ_CTRL_READ_FUSE		0x1
+
+#define VF610_OCOTP_TIMEOUT			100000
+
+#define BF(value, field)		(((value) << field) & field##_MASK)
+
+#define DEF_RELAX				20
+
+static const int base_to_fuse_addr_mappings[][2] = {
+	{0x400, 0x00},
+	{0x410, 0x01},
+	{0x420, 0x02},
+	{0x450, 0x05},
+	{0x4F0, 0x0F},
+	{0x600, 0x20},
+	{0x610, 0x21},
+	{0x620, 0x22},
+	{0x630, 0x23},
+	{0x640, 0x24},
+	{0x650, 0x25},
+	{0x660, 0x26},
+	{0x670, 0x27},
+	{0x6F0, 0x2F},
+	{0x880, 0x38},
+	{0x890, 0x39},
+	{0x8A0, 0x3A},
+	{0x8B0, 0x3B},
+	{0x8C0, 0x3C},
+	{0x8D0, 0x3D},
+	{0x8E0, 0x3E},
+	{0x8F0, 0x3F},
+	{0xC80, 0x78},
+	{0xC90, 0x79},
+	{0xCA0, 0x7A},
+	{0xCB0, 0x7B},
+	{0xCC0, 0x7C},
+	{0xCD0, 0x7D},
+	{0xCE0, 0x7E},
+	{0xCF0, 0x7F},
+};
+
+struct vf610_ocotp {
+	void __iomem *base;
+	struct clk *clk;
+	struct device *dev;
+	struct nvmem_device *nvmem;
+	int timing;
+};
+
+static int vf610_ocotp_wait_busy(void __iomem *base)
+{
+	int timeout = VF610_OCOTP_TIMEOUT;
+
+	while ((readl(base) & OCOTP_CTRL_BUSY) && --timeout)
+		udelay(10);
+
+	if (!timeout) {
+		writel(OCOTP_CTRL_ERROR, base + OCOTP_CTRL_CLR);
+		return -ETIMEDOUT;
+	}
+
+	udelay(10);
+
+	return 0;
+}
+
+static int vf610_ocotp_calculate_timing(struct vf610_ocotp *ocotp_dev)
+{
+	u32 clk_rate;
+	u32 relax, strobe_read, strobe_prog;
+	u32 timing;
+
+	clk_rate = clk_get_rate(ocotp_dev->clk);
+
+	/* Refer section OTP read/write timing parameters in TRM */
+	relax = clk_rate / (1000000000 / DEF_RELAX) - 1;
+	strobe_prog = clk_rate / (1000000000 / 10000) + 2 * (DEF_RELAX + 1) - 1;
+	strobe_read = clk_rate / (1000000000 / 40) + 2 * (DEF_RELAX + 1) - 1;
+
+	timing = BF(relax, OCOTP_TIMING_RELAX);
+	timing |= BF(strobe_read, OCOTP_TIMING_STROBE_READ);
+	timing |= BF(strobe_prog, OCOTP_TIMING_STROBE_PROG);
+
+	return timing;
+}
+
+static int vf610_get_fuse_address(int base_addr_offset)
+{
+	int i;
+
+	for (i = 0; i < ARRAY_SIZE(base_to_fuse_addr_mappings); i++) {
+		if (base_to_fuse_addr_mappings[i][0] == base_addr_offset)
+			return base_to_fuse_addr_mappings[i][1];
+	}
+
+	return -EINVAL;
+}
+
+static int vf610_ocotp_write(void *context, const void *data, size_t count)
+{
+	return 0;
+}
+
+static int vf610_ocotp_read(void *context,
+			const void *off, size_t reg_size,
+			void *val, size_t val_size)
+{
+	struct vf610_ocotp *ocotp = context;
+	unsigned int offset = *(u32 *)off;
+	u32 reg, *buf = val;
+	int fuse_addr;
+	int ret;
+
+	while (val_size > 0) {
+		fuse_addr = vf610_get_fuse_address(offset);
+		if (fuse_addr > 0) {
+			writel(ocotp->timing, ocotp->base + OCOTP_TIMING);
+			ret = vf610_ocotp_wait_busy(ocotp->base + OCOTP_CTRL_REG);
+			if (ret)
+				return ret;
+
+			reg = readl(ocotp->base + OCOTP_CTRL_REG);
+			reg &= ~OCOTP_CTRL_ADDR_MASK;
+			reg &= ~OCOTP_CTRL_WR_UNLOCK_MASK;
+			reg |= BF(fuse_addr, OCOTP_CTRL_ADDR);
+			writel(reg, ocotp->base + OCOTP_CTRL_REG);
+
+			writel(OCOTP_READ_CTRL_READ_FUSE,
+				ocotp->base + OCOTP_READ_CTRL_REG);
+			ret = vf610_ocotp_wait_busy(ocotp->base + OCOTP_CTRL_REG);
+			if (ret)
+				return ret;
+
+			if (readl(ocotp->base) & OCOTP_CTRL_ERROR) {
+				dev_dbg(ocotp->dev, "Error reading from fuse address %x\n",
+					fuse_addr);
+				writel(OCOTP_CTRL_ERROR, ocotp->base + OCOTP_CTRL_CLR);
+			}
+
+			/*
+			 * In case of error, we do not abort and expect to read
+			 * 0xBADABADA as mentioned by the TRM. We just read this
+			 * value and return.
+			 */
+			*buf = readl(ocotp->base + OCOTP_READ_FUSE_DATA);
+		} else {
+			*buf = 0;
+		}
+
+		buf++;
+		val_size--;
+		offset += reg_size;
+	}
+
+	return 0;
+}
+
+static struct regmap_bus vf610_ocotp_bus = {
+	.read = vf610_ocotp_read,
+	.write = vf610_ocotp_write,
+	.reg_format_endian_default = REGMAP_ENDIAN_NATIVE,
+	.val_format_endian_default = REGMAP_ENDIAN_NATIVE,
+};
+
+static struct regmap_config ocotp_regmap_config = {
+	.reg_bits = 32,
+	.val_bits = 32,
+	.reg_stride = 4,
+};
+
+static struct nvmem_config ocotp_config = {
+	.name = "ocotp",
+	.owner = THIS_MODULE,
+};
+
+static const struct of_device_id ocotp_of_match[] = {
+	{ .compatible = "fsl,vf610-ocotp", },
+	{/* sentinel */},
+};
+MODULE_DEVICE_TABLE(of, ocotp_of_match);
+
+static int vf610_ocotp_remove(struct platform_device *pdev)
+{
+	struct vf610_ocotp *ocotp_dev = platform_get_drvdata(pdev);
+
+	return nvmem_unregister(ocotp_dev->nvmem);
+}
+
+static int vf610_ocotp_probe(struct platform_device *pdev)
+{
+	struct device *dev = &pdev->dev;
+	struct resource *res;
+	struct regmap *regmap;
+	struct vf610_ocotp *ocotp_dev;
+
+	ocotp_dev = devm_kzalloc(&pdev->dev,
+			sizeof(struct vf610_ocotp), GFP_KERNEL);
+	if (!ocotp_dev)
+		return -ENOMEM;
+
+	res = platform_get_resource(pdev, IORESOURCE_MEM, 0);
+	ocotp_dev->base = devm_ioremap_resource(dev, res);
+	if (IS_ERR(ocotp_dev->base))
+		return PTR_ERR(ocotp_dev->base);
+
+	ocotp_dev->clk = devm_clk_get(dev, "ocotp");
+	if (IS_ERR(ocotp_dev->clk)) {
+		dev_err(dev, "failed getting clock, err = %ld\n",
+			PTR_ERR(ocotp_dev->clk));
+		return PTR_ERR(ocotp_dev->clk);
+	}
+
+	ocotp_regmap_config.max_register = resource_size(res);
+	regmap = devm_regmap_init(dev,
+		&vf610_ocotp_bus, ocotp_dev, &ocotp_regmap_config);
+	if (IS_ERR(regmap)) {
+		dev_err(dev, "regmap init failed\n");
+		return PTR_ERR(regmap);
+	}
+	ocotp_config.dev = dev;
+
+	ocotp_dev->nvmem = nvmem_register(&ocotp_config);
+	if (IS_ERR(ocotp_dev->nvmem))
+		return PTR_ERR(ocotp_dev->nvmem);
+
+	ocotp_dev->dev = dev;
+	platform_set_drvdata(pdev, ocotp_dev);
+
+	ocotp_dev->timing = vf610_ocotp_calculate_timing(ocotp_dev);
+
+	return 0;
+}
+
+static struct platform_driver vf610_ocotp_driver = {
+	.probe = vf610_ocotp_probe,
+	.remove = vf610_ocotp_remove,
+	.driver = {
+		.name = "vf610-ocotp",
+		.of_match_table = ocotp_of_match,
+	},
+};
+module_platform_driver(vf610_ocotp_driver);
+MODULE_AUTHOR("Sanchayan Maity <sanchayan.maity at toradex.com>");
+MODULE_DESCRIPTION("Vybrid OCOTP driver");
+MODULE_LICENSE("GPL v2");
-- 
2.5.0



From alexandre.belloni at free-electrons.com  Mon Aug 10 07:23:09 2015
From: alexandre.belloni at free-electrons.com (Alexandre Belloni)
Date: Mon, 10 Aug 2015 16:23:09 +0200
Subject: [PATCH 1/4] USB: host: ohci-at91: move at91_usbh_data definition in c
 file
In-Reply-To: <1439216592-11381-1-git-send-email-alexandre.belloni@free-electrons.com>
References: <1439216592-11381-1-git-send-email-alexandre.belloni@free-electrons.com>
Message-ID: <1439216592-11381-2-git-send-email-alexandre.belloni@free-electrons.com>

Move struct at91_usbh_data back in ohci-at91.c as this is the only user
left after switching all at91 platforms to DT only.

Signed-off-by: Alexandre Belloni <alexandre.belloni at free-electrons.com>
---
 drivers/usb/host/ohci-at91.c        | 11 +++++++++++
 include/linux/platform_data/atmel.h | 12 ------------
 2 files changed, 11 insertions(+), 12 deletions(-)

diff --git a/drivers/usb/host/ohci-at91.c b/drivers/usb/host/ohci-at91.c
index 15df00cceed9..72dc4f9e2a0f 100644
--- a/drivers/usb/host/ohci-at91.c
+++ b/drivers/usb/host/ohci-at91.c
@@ -36,6 +36,17 @@
 #define hcd_to_ohci_at91_priv(h) \
 	((struct ohci_at91_priv *)hcd_to_ohci(h)->priv)
 
+#define AT91_MAX_USBH_PORTS	3
+struct at91_usbh_data {
+	int vbus_pin[AT91_MAX_USBH_PORTS];	/* port power-control pin */
+	int overcurrent_pin[AT91_MAX_USBH_PORTS];
+	u8 ports;				/* number of ports on root hub */
+	u8 overcurrent_supported;
+	u8 vbus_pin_active_low[AT91_MAX_USBH_PORTS];
+	u8 overcurrent_status[AT91_MAX_USBH_PORTS];
+	u8 overcurrent_changed[AT91_MAX_USBH_PORTS];
+};
+
 struct ohci_at91_priv {
 	struct clk *iclk;
 	struct clk *fclk;
diff --git a/include/linux/platform_data/atmel.h b/include/linux/platform_data/atmel.h
index 4b452c6a2f7b..527a85c61924 100644
--- a/include/linux/platform_data/atmel.h
+++ b/include/linux/platform_data/atmel.h
@@ -46,18 +46,6 @@ struct at91_cf_data {
 #define AT91_IDE_SWAP_A0_A2	0x02
 };
 
- /* USB Host */
-#define AT91_MAX_USBH_PORTS	3
-struct at91_usbh_data {
-	int		vbus_pin[AT91_MAX_USBH_PORTS];	/* port power-control pin */
-	int             overcurrent_pin[AT91_MAX_USBH_PORTS];
-	u8		ports;				/* number of ports on root hub */
-	u8              overcurrent_supported;
-	u8              vbus_pin_active_low[AT91_MAX_USBH_PORTS];
-	u8              overcurrent_status[AT91_MAX_USBH_PORTS];
-	u8              overcurrent_changed[AT91_MAX_USBH_PORTS];
-};
-
  /* NAND / SmartMedia */
 struct atmel_nand_data {
 	int		enable_pin;		/* chip enable */
-- 
2.1.4



From alexandre.belloni at free-electrons.com  Mon Aug 10 07:23:08 2015
From: alexandre.belloni at free-electrons.com (Alexandre Belloni)
Date: Mon, 10 Aug 2015 16:23:08 +0200
Subject: [PATCH 0/4] USB: host: ohci-at91: cleanups
Message-ID: <1439216592-11381-1-git-send-email-alexandre.belloni@free-electrons.com>

Hi,

Here are a few cleanups for ohci-at91. This is the fallout of AT91 now being DT
only.

Alexandre Belloni (4):
  USB: host: ohci-at91: move at91_usbh_data definition in c file
  USB: host: ohci-at91: depend on OF
  USB: host: ohci-at91: merge ohci_at91_of_init in
    ohci_hcd_at91_drv_probe
  USB: host: ohci-at91: merge loops in ohci_hcd_at91_drv_probe

 drivers/usb/host/Kconfig            |   8 +-
 drivers/usb/host/ohci-at91.c        | 179 ++++++++++++++++--------------------
 include/linux/platform_data/atmel.h |  12 ---
 3 files changed, 85 insertions(+), 114 deletions(-)

-- 
2.1.4



From alexandre.belloni at free-electrons.com  Mon Aug 10 07:23:12 2015
From: alexandre.belloni at free-electrons.com (Alexandre Belloni)
Date: Mon, 10 Aug 2015 16:23:12 +0200
Subject: [PATCH 4/4] USB: host: ohci-at91: merge loops in
 ohci_hcd_at91_drv_probe
In-Reply-To: <1439216592-11381-1-git-send-email-alexandre.belloni@free-electrons.com>
References: <1439216592-11381-1-git-send-email-alexandre.belloni@free-electrons.com>
Message-ID: <1439216592-11381-5-git-send-email-alexandre.belloni@free-electrons.com>

ohci_hcd_at91_drv_probe() has four at91_for_each_port. They can be merged
into two loops without changing the driver behaviour.

Signed-off-by: Alexandre Belloni <alexandre.belloni at free-electrons.com>
---
 drivers/usb/host/ohci-at91.c | 34 ++++++++++++++++------------------
 1 file changed, 16 insertions(+), 18 deletions(-)

diff --git a/drivers/usb/host/ohci-at91.c b/drivers/usb/host/ohci-at91.c
index cdd91c551c7b..342ffd140122 100644
--- a/drivers/usb/host/ohci-at91.c
+++ b/drivers/usb/host/ohci-at91.c
@@ -477,33 +477,21 @@ static int ohci_hcd_at91_drv_probe(struct platform_device *pdev)
 		pdata->ports = ports;
 
 	at91_for_each_port(i) {
-		gpio = of_get_named_gpio_flags(np, "atmel,vbus-gpio", i, &flags);
-		pdata->vbus_pin[i] = gpio;
-		if (!gpio_is_valid(gpio))
-			continue;
-		pdata->vbus_pin_active_low[i] = flags & OF_GPIO_ACTIVE_LOW;
-	}
-
-	at91_for_each_port(i)
-		pdata->overcurrent_pin[i] =
-			of_get_named_gpio_flags(np, "atmel,oc-gpio", i, &flags);
-
-	pdev->dev.platform_data = pdata;
-
-	at91_for_each_port(i) {
 		/*
 		 * do not configure PIO if not in relation with
 		 * real USB port on board
 		 */
 		if (i >= pdata->ports) {
 			pdata->vbus_pin[i] = -EINVAL;
-			pdata->overcurrent_pin[i] = -EINVAL;
-			break;
+			continue;
 		}
 
-		if (!gpio_is_valid(pdata->vbus_pin[i]))
+		gpio = of_get_named_gpio_flags(np, "atmel,vbus-gpio", i,
+					       &flags);
+		pdata->vbus_pin[i] = gpio;
+		if (!gpio_is_valid(gpio))
 			continue;
-		gpio = pdata->vbus_pin[i];
+		pdata->vbus_pin_active_low[i] = flags & OF_GPIO_ACTIVE_LOW;
 
 		ret = gpio_request(gpio, "ohci_vbus");
 		if (ret) {
@@ -525,6 +513,14 @@ static int ohci_hcd_at91_drv_probe(struct platform_device *pdev)
 	}
 
 	at91_for_each_port(i) {
+		if (i >= pdata->ports) {
+			pdata->overcurrent_pin[i] = -EINVAL;
+			continue;
+		}
+
+		pdata->overcurrent_pin[i] =
+			of_get_named_gpio_flags(np, "atmel,oc-gpio", i, &flags);
+
 		if (!gpio_is_valid(pdata->overcurrent_pin[i]))
 			continue;
 		gpio = pdata->overcurrent_pin[i];
@@ -556,6 +552,8 @@ static int ohci_hcd_at91_drv_probe(struct platform_device *pdev)
 		}
 	}
 
+	pdev->dev.platform_data = pdata;
+
 	device_init_wakeup(&pdev->dev, 1);
 	return usb_hcd_at91_probe(&ohci_at91_hc_driver, pdev);
 }
-- 
2.1.4



From alexandre.belloni at free-electrons.com  Mon Aug 10 07:23:10 2015
From: alexandre.belloni at free-electrons.com (Alexandre Belloni)
Date: Mon, 10 Aug 2015 16:23:10 +0200
Subject: [PATCH 2/4] USB: host: ohci-at91: depend on OF
In-Reply-To: <1439216592-11381-1-git-send-email-alexandre.belloni@free-electrons.com>
References: <1439216592-11381-1-git-send-email-alexandre.belloni@free-electrons.com>
Message-ID: <1439216592-11381-3-git-send-email-alexandre.belloni@free-electrons.com>

Make the driver depend on CONFIG_OF and remove the now useless #ifdef

Also, fix the Kconfig indentation.

Signed-off-by: Alexandre Belloni <alexandre.belloni at free-electrons.com>
---
 drivers/usb/host/Kconfig     | 8 ++++----
 drivers/usb/host/ohci-at91.c | 9 +--------
 2 files changed, 5 insertions(+), 12 deletions(-)

diff --git a/drivers/usb/host/Kconfig b/drivers/usb/host/Kconfig
index 8afc3c1efdab..7ef56faf09bb 100644
--- a/drivers/usb/host/Kconfig
+++ b/drivers/usb/host/Kconfig
@@ -441,10 +441,10 @@ config USB_OHCI_HCD_PXA27X
 	  PXA27x/PXA3xx chips.
 
 config USB_OHCI_HCD_AT91
-        tristate "Support for Atmel on-chip OHCI USB controller"
-        depends on USB_OHCI_HCD && ARCH_AT91
-        default y
-        ---help---
+	tristate "Support for Atmel on-chip OHCI USB controller"
+	depends on USB_OHCI_HCD && ARCH_AT91 && OF
+	default y
+	---help---
           Enables support for the on-chip OHCI controller on
           Atmel chips.
 
diff --git a/drivers/usb/host/ohci-at91.c b/drivers/usb/host/ohci-at91.c
index 72dc4f9e2a0f..8e17d5ba26c6 100644
--- a/drivers/usb/host/ohci-at91.c
+++ b/drivers/usb/host/ohci-at91.c
@@ -442,7 +442,6 @@ static irqreturn_t ohci_hcd_at91_overcurrent_irq(int irq, void *data)
 	return IRQ_HANDLED;
 }
 
-#ifdef CONFIG_OF
 static const struct of_device_id at91_ohci_dt_ids[] = {
 	{ .compatible = "atmel,at91rm9200-ohci" },
 	{ /* sentinel */ }
@@ -492,12 +491,6 @@ static int ohci_at91_of_init(struct platform_device *pdev)
 
 	return 0;
 }
-#else
-static int ohci_at91_of_init(struct platform_device *pdev)
-{
-	return 0;
-}
-#endif
 
 /*-------------------------------------------------------------------------*/
 
@@ -684,7 +677,7 @@ static struct platform_driver ohci_hcd_at91_driver = {
 	.driver		= {
 		.name	= "at91_ohci",
 		.pm	= &ohci_hcd_at91_pm_ops,
-		.of_match_table	= of_match_ptr(at91_ohci_dt_ids),
+		.of_match_table	= at91_ohci_dt_ids,
 	},
 };
 
-- 
2.1.4



From alexandre.belloni at free-electrons.com  Mon Aug 10 07:23:11 2015
From: alexandre.belloni at free-electrons.com (Alexandre Belloni)
Date: Mon, 10 Aug 2015 16:23:11 +0200
Subject: [PATCH 3/4] USB: host: ohci-at91: merge ohci_at91_of_init in
 ohci_hcd_at91_drv_probe
In-Reply-To: <1439216592-11381-1-git-send-email-alexandre.belloni@free-electrons.com>
References: <1439216592-11381-1-git-send-email-alexandre.belloni@free-electrons.com>
Message-ID: <1439216592-11381-4-git-send-email-alexandre.belloni@free-electrons.com>

As device tree support is now mandatory, merge ohci_at91_of_init() in
ohci_hcd_at91_drv_probe().

Signed-off-by: Alexandre Belloni <alexandre.belloni at free-electrons.com>
---
 drivers/usb/host/ohci-at91.c | 145 +++++++++++++++++++------------------------
 1 file changed, 63 insertions(+), 82 deletions(-)

diff --git a/drivers/usb/host/ohci-at91.c b/drivers/usb/host/ohci-at91.c
index 8e17d5ba26c6..cdd91c551c7b 100644
--- a/drivers/usb/host/ohci-at91.c
+++ b/drivers/usb/host/ohci-at91.c
@@ -449,16 +449,17 @@ static const struct of_device_id at91_ohci_dt_ids[] = {
 
 MODULE_DEVICE_TABLE(of, at91_ohci_dt_ids);
 
-static int ohci_at91_of_init(struct platform_device *pdev)
+/*-------------------------------------------------------------------------*/
+
+static int ohci_hcd_at91_drv_probe(struct platform_device *pdev)
 {
 	struct device_node *np = pdev->dev.of_node;
-	int i, gpio, ret;
-	enum of_gpio_flags flags;
 	struct at91_usbh_data	*pdata;
-	u32 ports;
-
-	if (!np)
-		return 0;
+	int			i;
+	int			gpio;
+	int			ret;
+	enum of_gpio_flags	flags;
+	u32			ports;
 
 	/* Right now device-tree probed devices don't get dma_mask set.
 	 * Since shared usb code relies on it, set it here for now.
@@ -489,89 +490,69 @@ static int ohci_at91_of_init(struct platform_device *pdev)
 
 	pdev->dev.platform_data = pdata;
 
-	return 0;
-}
-
-/*-------------------------------------------------------------------------*/
-
-static int ohci_hcd_at91_drv_probe(struct platform_device *pdev)
-{
-	struct at91_usbh_data	*pdata;
-	int			i;
-	int			gpio;
-	int			ret;
-
-	ret = ohci_at91_of_init(pdev);
-	if (ret)
-		return ret;
+	at91_for_each_port(i) {
+		/*
+		 * do not configure PIO if not in relation with
+		 * real USB port on board
+		 */
+		if (i >= pdata->ports) {
+			pdata->vbus_pin[i] = -EINVAL;
+			pdata->overcurrent_pin[i] = -EINVAL;
+			break;
+		}
 
-	pdata = dev_get_platdata(&pdev->dev);
+		if (!gpio_is_valid(pdata->vbus_pin[i]))
+			continue;
+		gpio = pdata->vbus_pin[i];
 
-	if (pdata) {
-		at91_for_each_port(i) {
-			/*
-			 * do not configure PIO if not in relation with
-			 * real USB port on board
-			 */
-			if (i >= pdata->ports) {
-				pdata->vbus_pin[i] = -EINVAL;
-				pdata->overcurrent_pin[i] = -EINVAL;
-				break;
-			}
+		ret = gpio_request(gpio, "ohci_vbus");
+		if (ret) {
+			dev_err(&pdev->dev,
+				"can't request vbus gpio %d\n", gpio);
+			continue;
+		}
+		ret = gpio_direction_output(gpio,
+					!pdata->vbus_pin_active_low[i]);
+		if (ret) {
+			dev_err(&pdev->dev,
+				"can't put vbus gpio %d as output %d\n",
+				gpio, !pdata->vbus_pin_active_low[i]);
+			gpio_free(gpio);
+			continue;
+		}
 
-			if (!gpio_is_valid(pdata->vbus_pin[i]))
-				continue;
-			gpio = pdata->vbus_pin[i];
+		ohci_at91_usb_set_power(pdata, i, 1);
+	}
 
-			ret = gpio_request(gpio, "ohci_vbus");
-			if (ret) {
-				dev_err(&pdev->dev,
-					"can't request vbus gpio %d\n", gpio);
-				continue;
-			}
-			ret = gpio_direction_output(gpio,
-						!pdata->vbus_pin_active_low[i]);
-			if (ret) {
-				dev_err(&pdev->dev,
-					"can't put vbus gpio %d as output %d\n",
-					gpio, !pdata->vbus_pin_active_low[i]);
-				gpio_free(gpio);
-				continue;
-			}
+	at91_for_each_port(i) {
+		if (!gpio_is_valid(pdata->overcurrent_pin[i]))
+			continue;
+		gpio = pdata->overcurrent_pin[i];
 
-			ohci_at91_usb_set_power(pdata, i, 1);
+		ret = gpio_request(gpio, "ohci_overcurrent");
+		if (ret) {
+			dev_err(&pdev->dev,
+				"can't request overcurrent gpio %d\n",
+				gpio);
+			continue;
 		}
 
-		at91_for_each_port(i) {
-			if (!gpio_is_valid(pdata->overcurrent_pin[i]))
-				continue;
-			gpio = pdata->overcurrent_pin[i];
-
-			ret = gpio_request(gpio, "ohci_overcurrent");
-			if (ret) {
-				dev_err(&pdev->dev,
-					"can't request overcurrent gpio %d\n",
-					gpio);
-				continue;
-			}
-
-			ret = gpio_direction_input(gpio);
-			if (ret) {
-				dev_err(&pdev->dev,
-					"can't configure overcurrent gpio %d as input\n",
-					gpio);
-				gpio_free(gpio);
-				continue;
-			}
+		ret = gpio_direction_input(gpio);
+		if (ret) {
+			dev_err(&pdev->dev,
+				"can't configure overcurrent gpio %d as input\n",
+				gpio);
+			gpio_free(gpio);
+			continue;
+		}
 
-			ret = request_irq(gpio_to_irq(gpio),
-					  ohci_hcd_at91_overcurrent_irq,
-					  IRQF_SHARED, "ohci_overcurrent", pdev);
-			if (ret) {
-				gpio_free(gpio);
-				dev_err(&pdev->dev,
-					"can't get gpio IRQ for overcurrent\n");
-			}
+		ret = request_irq(gpio_to_irq(gpio),
+				  ohci_hcd_at91_overcurrent_irq,
+				  IRQF_SHARED, "ohci_overcurrent", pdev);
+		if (ret) {
+			gpio_free(gpio);
+			dev_err(&pdev->dev,
+				"can't get gpio IRQ for overcurrent\n");
 		}
 	}
 
-- 
2.1.4



From alexandre.belloni at free-electrons.com  Mon Aug 10 07:26:48 2015
From: alexandre.belloni at free-electrons.com (Alexandre Belloni)
Date: Mon, 10 Aug 2015 16:26:48 +0200
Subject: [PATCH] mmc: atmel-mci: remove useless include
Message-ID: <1439216808-11826-1-git-send-email-alexandre.belloni@free-electrons.com>

Definitions from linux/platform_data/atmel.h are not used, remove the
include.

Signed-off-by: Alexandre Belloni <alexandre.belloni at free-electrons.com>
---
 drivers/mmc/host/atmel-mci.c | 1 -
 1 file changed, 1 deletion(-)

diff --git a/drivers/mmc/host/atmel-mci.c b/drivers/mmc/host/atmel-mci.c
index 9a39e0b7e583..bf62e429f7fc 100644
--- a/drivers/mmc/host/atmel-mci.c
+++ b/drivers/mmc/host/atmel-mci.c
@@ -29,7 +29,6 @@
 #include <linux/slab.h>
 #include <linux/stat.h>
 #include <linux/types.h>
-#include <linux/platform_data/atmel.h>
 #include <linux/platform_data/mmc-atmel-mci.h>
 
 #include <linux/mmc/host.h>
-- 
2.1.4



From alexandre.belloni at free-electrons.com  Mon Aug 10 07:28:07 2015
From: alexandre.belloni at free-electrons.com (Alexandre Belloni)
Date: Mon, 10 Aug 2015 16:28:07 +0200
Subject: [PATCH] spi: atmel: remove useless include
Message-ID: <1439216887-11985-1-git-send-email-alexandre.belloni@free-electrons.com>

Definitions from linux/platform_data/atmel.h are not used, remove the
include.

Signed-off-by: Alexandre Belloni <alexandre.belloni at free-electrons.com>
---
 drivers/spi/spi-atmel.c | 1 -
 1 file changed, 1 deletion(-)

diff --git a/drivers/spi/spi-atmel.c b/drivers/spi/spi-atmel.c
index c9eca347787d..bf9ed380bb1c 100644
--- a/drivers/spi/spi-atmel.c
+++ b/drivers/spi/spi-atmel.c
@@ -19,7 +19,6 @@
 #include <linux/interrupt.h>
 #include <linux/spi/spi.h>
 #include <linux/slab.h>
-#include <linux/platform_data/atmel.h>
 #include <linux/platform_data/dma-atmel.h>
 #include <linux/of.h>
 
-- 
2.1.4



From alexandre.belloni at free-electrons.com  Mon Aug 10 07:29:33 2015
From: alexandre.belloni at free-electrons.com (Alexandre Belloni)
Date: Mon, 10 Aug 2015 16:29:33 +0200
Subject: [PATCH] usb: gadget: atmel: remove useless include
Message-ID: <1439216973-12150-1-git-send-email-alexandre.belloni@free-electrons.com>

Definitions from linux/platform_data/atmel.h are not used, remove the
include.

Signed-off-by: Alexandre Belloni <alexandre.belloni at free-electrons.com>
---
 drivers/usb/gadget/udc/atmel_usba_udc.c | 1 -
 1 file changed, 1 deletion(-)

diff --git a/drivers/usb/gadget/udc/atmel_usba_udc.c b/drivers/usb/gadget/udc/atmel_usba_udc.c
index 4095cce05e6a..548192f77dcb 100644
--- a/drivers/usb/gadget/udc/atmel_usba_udc.c
+++ b/drivers/usb/gadget/udc/atmel_usba_udc.c
@@ -22,7 +22,6 @@
 #include <linux/usb/gadget.h>
 #include <linux/usb/atmel_usba_udc.h>
 #include <linux/delay.h>
-#include <linux/platform_data/atmel.h>
 #include <linux/of.h>
 #include <linux/of_gpio.h>
 
-- 
2.1.4



From alexandre.belloni at free-electrons.com  Mon Aug 10 07:31:54 2015
From: alexandre.belloni at free-electrons.com (Alexandre Belloni)
Date: Mon, 10 Aug 2015 16:31:54 +0200
Subject: [PATCH] video: fbdev: atmel_lcdfb: remove useless include
Message-ID: <1439217114-12317-1-git-send-email-alexandre.belloni@free-electrons.com>

Definitions from linux/platform_data/atmel.h are not used, remove the
include.

Signed-off-by: Alexandre Belloni <alexandre.belloni at free-electrons.com>
---
 drivers/video/fbdev/atmel_lcdfb.c | 1 -
 1 file changed, 1 deletion(-)

diff --git a/drivers/video/fbdev/atmel_lcdfb.c b/drivers/video/fbdev/atmel_lcdfb.c
index abadc490fa1f..a5006788647c 100644
--- a/drivers/video/fbdev/atmel_lcdfb.c
+++ b/drivers/video/fbdev/atmel_lcdfb.c
@@ -19,7 +19,6 @@
 #include <linux/backlight.h>
 #include <linux/gfp.h>
 #include <linux/module.h>
-#include <linux/platform_data/atmel.h>
 #include <linux/of.h>
 #include <linux/of_device.h>
 #include <linux/of_gpio.h>
-- 
2.1.4



From alexandre.belloni at free-electrons.com  Mon Aug 10 07:33:39 2015
From: alexandre.belloni at free-electrons.com (Alexandre Belloni)
Date: Mon, 10 Aug 2015 16:33:39 +0200
Subject: [PATCH 1/2] rtc: at91sam9: include linux/of.h
Message-ID: <1439217220-13561-1-git-send-email-alexandre.belloni@free-electrons.com>

This driver is using device tree but is not including of.h

Signed-off-by: Alexandre Belloni <alexandre.belloni at free-electrons.com>
---
 drivers/rtc/rtc-at91sam9.c | 1 +
 1 file changed, 1 insertion(+)

diff --git a/drivers/rtc/rtc-at91sam9.c b/drivers/rtc/rtc-at91sam9.c
index 5ccaee32df72..9f6c3631b8d5 100644
--- a/drivers/rtc/rtc-at91sam9.c
+++ b/drivers/rtc/rtc-at91sam9.c
@@ -25,6 +25,7 @@
 #include <linux/regmap.h>
 #include <linux/suspend.h>
 #include <linux/clk.h>
+#include <linux/of.h>
 
 /*
  * This driver uses two configurable hardware resources that live in the
-- 
2.1.4



From alexandre.belloni at free-electrons.com  Mon Aug 10 07:33:40 2015
From: alexandre.belloni at free-electrons.com (Alexandre Belloni)
Date: Mon, 10 Aug 2015 16:33:40 +0200
Subject: [PATCH 2/2] rtc: at91sam9: remove useless include
In-Reply-To: <1439217220-13561-1-git-send-email-alexandre.belloni@free-electrons.com>
References: <1439217220-13561-1-git-send-email-alexandre.belloni@free-electrons.com>
Message-ID: <1439217220-13561-2-git-send-email-alexandre.belloni@free-electrons.com>

Definitions from linux/platform_data/atmel.h are not used, remove the
include.

Signed-off-by: Alexandre Belloni <alexandre.belloni at free-electrons.com>
---
 drivers/rtc/rtc-at91sam9.c | 1 -
 1 file changed, 1 deletion(-)

diff --git a/drivers/rtc/rtc-at91sam9.c b/drivers/rtc/rtc-at91sam9.c
index 9f6c3631b8d5..7ef30221812c 100644
--- a/drivers/rtc/rtc-at91sam9.c
+++ b/drivers/rtc/rtc-at91sam9.c
@@ -19,7 +19,6 @@
 #include <linux/interrupt.h>
 #include <linux/ioctl.h>
 #include <linux/slab.h>
-#include <linux/platform_data/atmel.h>
 #include <linux/io.h>
 #include <linux/mfd/syscon.h>
 #include <linux/regmap.h>
-- 
2.1.4



From geert at linux-m68k.org  Mon Aug 10 07:35:32 2015
From: geert at linux-m68k.org (Geert Uytterhoeven)
Date: Mon, 10 Aug 2015 16:35:32 +0200
Subject: [PATCH 1/2] ARM: shmobile: r8a7794: add QSPI DT support
In-Reply-To: <5339616.vfIYf6AeR8@wasted.cogentembedded.com>
References: <1898263.zrOs5SAUTS@wasted.cogentembedded.com>
 <5339616.vfIYf6AeR8@wasted.cogentembedded.com>
Message-ID: <CAMuHMdX3F4ecR=BjgUrrEA3P4xpu-Yt_r3qM6SgUdFrYm7h1Rw@mail.gmail.com>

On Sun, Aug 9, 2015 at 12:26 AM, Sergei Shtylyov
<sergei.shtylyov at cogentembedded.com> wrote:
> Define the generic R8A7794 part of the QSPI device node.
>
> Based on original patch by Hisashi Nakamura <hisashi.nakamura.ak at renesas.com>.
>
> Signed-off-by: Sergei Shtylyov <sergei.shtylyov at cogentembedded.com>

Acked-by: Geert Uytterhoeven <geert+renesas at glider.be>

 arch/arm/boot/dts/r8a7794.dtsi |   18 ++++++++++++++++++
>  1 file changed, 18 insertions(+)
>
> Index: renesas/arch/arm/boot/dts/r8a7794.dtsi
> ===================================================================
> --- renesas.orig/arch/arm/boot/dts/r8a7794.dtsi
> +++ renesas/arch/arm/boot/dts/r8a7794.dtsi
> @@ -19,6 +19,10 @@
>         #address-cells = <2>;
>         #size-cells = <2>;
>
> +       aliases {
> +               spi0 = &qspi;
> +       };
> +
>         cpus {
>                 #address-cells = <1>;
>                 #size-cells = <0>;
> @@ -537,6 +541,20 @@
>                 status = "disabled";
>         };
>
> +       qspi: spi at e6b10000 {
> +               compatible = "renesas,qspi-r8a7794", "renesas,qspi";
> +               reg = <0 0xe6b10000 0 0x2c>;
> +               interrupts = <0 184 IRQ_TYPE_LEVEL_HIGH>;
> +               clocks = <&mstp9_clks R8A7794_CLK_QSPI_MOD>;
> +               power-domains = <&cpg_clocks>;

For consistency with the other nodes, I'd add "power-domains" below the
DMA-related properties.

> +               dmas = <&dmac0 0x17>, <&dmac0 0x18>;
> +               dma-names = "tx", "rx";
> +               num-cs = <1>;
> +               #address-cells = <1>;
> +               #size-cells = <0>;
> +               status = "disabled";
> +       };
> +
>         clocks {
>                 #address-cells = <2>;
>                 #size-cells = <2>;

Gr{oetje,eeting}s,

                        Geert

--
Geert Uytterhoeven -- There's lots of Linux beyond ia32 -- geert at linux-m68k.org

In personal conversations with technical people, I call myself a hacker. But
when I'm talking to journalists I just say "programmer" or something like that.
                                -- Linus Torvalds


From geert at linux-m68k.org  Mon Aug 10 07:38:46 2015
From: geert at linux-m68k.org (Geert Uytterhoeven)
Date: Mon, 10 Aug 2015 16:38:46 +0200
Subject: [PATCH 2/2] ARM: shmobile: silk: add QSPI DT support
In-Reply-To: <1768974.jEFIAaInqd@wasted.cogentembedded.com>
References: <1898263.zrOs5SAUTS@wasted.cogentembedded.com>
 <1768974.jEFIAaInqd@wasted.cogentembedded.com>
Message-ID: <CAMuHMdXQJ4Hju477Ys0ujXCNdUjWOa6AuKGzLPc3YFJc_eLz+g@mail.gmail.com>

Hi Sergei,

On Sun, Aug 9, 2015 at 12:27 AM, Sergei Shtylyov
<sergei.shtylyov at cogentembedded.com> wrote:
> Define the SILK board dependent part of the QSPI device node.
> Add device nodes  for Spansion  S25FL512S SPI flash and MTD partitions on it.
>
> Based on the original patch by Vladimir Barinov
> <vladimir.barinov at cogentembedded.com>.
>
> Signed-off-by: Sergei Shtylyov <sergei.shtylyov at cogentembedded.com>

> --- renesas.orig/arch/arm/boot/dts/r8a7794-silk.dts
> +++ renesas/arch/arm/boot/dts/r8a7794-silk.dts

> +&qspi {
> +       pinctrl-0 = <&qspi_pins>;
> +       pinctrl-names = "default";
> +
> +       status = "okay";
> +
> +       flash at 0 {
> +               #address-cells = <1>;
> +               #size-cells = <1>;
> +               compatible = "spansion,s25fl512s";

Please add the "jedec,spi-nor" fallback.

> +               reg = <0>;
> +               spi-max-frequency = <30000000>;
> +               spi-tx-bus-width = <4>;
> +               spi-rx-bus-width = <4>;
> +               m25p,fast-read;

Please keep all "spi-*" properties together.

> +               spi-cpol;
> +               spi-cpha;

> +               partition at 0 {
> +                       label = "loader";
> +                       reg = <0x00000000 0x00040000>;
> +                       read-only;
> +               };
> +               partition at 40000 {
> +                       label = "user";
> +                       reg = <0x00040000 0x00400000>;
> +                       read-only;
> +               };
> +               partition at 440000 {
> +                       label = "flash";
> +                       reg = <0x00440000 0x03bc0000>;
> +               };

The above part I cannot verify, so I have to trust you.

Gr{oetje,eeting}s,

                        Geert

--
Geert Uytterhoeven -- There's lots of Linux beyond ia32 -- geert at linux-m68k.org

In personal conversations with technical people, I call myself a hacker. But
when I'm talking to journalists I just say "programmer" or something like that.
                                -- Linus Torvalds


From alexandre.belloni at free-electrons.com  Mon Aug 10 07:41:45 2015
From: alexandre.belloni at free-electrons.com (Alexandre Belloni)
Date: Mon, 10 Aug 2015 16:41:45 +0200
Subject: [PATCH] ARM: at91: remove useless includes in platform_data/atmel.h
Message-ID: <1439217705-13960-1-git-send-email-alexandre.belloni@free-electrons.com>

include/linux/platform_data/atmel.h has a lot of useless includes, remove
them.

Signed-off-by: Alexandre Belloni <alexandre.belloni at free-electrons.com>
---
 include/linux/platform_data/atmel.h | 8 --------
 1 file changed, 8 deletions(-)

diff --git a/include/linux/platform_data/atmel.h b/include/linux/platform_data/atmel.h
index 527a85c61924..4d67a5e82c83 100644
--- a/include/linux/platform_data/atmel.h
+++ b/include/linux/platform_data/atmel.h
@@ -9,15 +9,7 @@
 
 #include <linux/mtd/nand.h>
 #include <linux/mtd/partitions.h>
-#include <linux/device.h>
-#include <linux/i2c.h>
-#include <linux/leds.h>
-#include <linux/spi/spi.h>
-#include <linux/usb/atmel_usba_udc.h>
-#include <linux/atmel-mci.h>
-#include <sound/atmel-ac97c.h>
 #include <linux/serial.h>
-#include <linux/platform_data/macb.h>
 
 /*
  * at91: 6 USARTs and one DBGU port (SAM9260)
-- 
2.1.4



From alexandre.belloni at free-electrons.com  Mon Aug 10 07:44:54 2015
From: alexandre.belloni at free-electrons.com (Alexandre Belloni)
Date: Mon, 10 Aug 2015 16:44:54 +0200
Subject: [PATCH] can: at91: move at91_can_data to at91_can.c
Message-ID: <1439217894-15230-1-git-send-email-alexandre.belloni@free-electrons.com>

struct at91_can_data is now only used inside the driver, move it to
its c file.

Signed-off-by: Alexandre Belloni <alexandre.belloni at free-electrons.com>
---
 drivers/net/can/at91_can.c          | 5 ++++-
 include/linux/platform_data/atmel.h | 5 -----
 2 files changed, 4 insertions(+), 6 deletions(-)

diff --git a/drivers/net/can/at91_can.c b/drivers/net/can/at91_can.c
index 945c0955a967..83ddf4f46f0d 100644
--- a/drivers/net/can/at91_can.c
+++ b/drivers/net/can/at91_can.c
@@ -33,7 +33,6 @@
 #include <linux/spinlock.h>
 #include <linux/string.h>
 #include <linux/types.h>
-#include <linux/platform_data/atmel.h>
 
 #include <linux/can/dev.h>
 #include <linux/can/error.h>
@@ -136,6 +135,10 @@ struct at91_devtype_data {
 	enum at91_devtype type;
 };
 
+struct at91_can_data {
+	void (*transceiver_switch)(int on);
+};
+
 struct at91_priv {
 	struct can_priv can;		/* must be the first member! */
 	struct napi_struct napi;
diff --git a/include/linux/platform_data/atmel.h b/include/linux/platform_data/atmel.h
index 4b452c6a2f7b..b99d85f56a7d 100644
--- a/include/linux/platform_data/atmel.h
+++ b/include/linux/platform_data/atmel.h
@@ -86,11 +86,6 @@ struct atmel_uart_data {
 	struct serial_rs485	rs485;		/* rs485 settings */
 };
 
-/* CAN */
-struct at91_can_data {
-	void (*transceiver_switch)(int on);
-};
-
 /* FIXME: this needs a better location, but gets stuff building again */
 extern int at91_suspend_entering_slow_clock(void);
 
-- 
2.1.4



From alexandre.belloni at free-electrons.com  Mon Aug 10 07:46:19 2015
From: alexandre.belloni at free-electrons.com (Alexandre Belloni)
Date: Mon, 10 Aug 2015 16:46:19 +0200
Subject: [PATCH] usb: gadget: at91_udc: move at91_udc_data in at91_udc.h
Message-ID: <1439217979-15642-1-git-send-email-alexandre.belloni@free-electrons.com>

struct at91_udc_data is now only used inside the driver, move it to its
include.

Signed-off-by: Alexandre Belloni <alexandre.belloni at free-electrons.com>
---
 drivers/usb/gadget/udc/at91_udc.h   | 8 ++++++++
 include/linux/platform_data/atmel.h | 9 ---------
 2 files changed, 8 insertions(+), 9 deletions(-)

diff --git a/drivers/usb/gadget/udc/at91_udc.h b/drivers/usb/gadget/udc/at91_udc.h
index 2679c8b217cc..0a433e6b346b 100644
--- a/drivers/usb/gadget/udc/at91_udc.h
+++ b/drivers/usb/gadget/udc/at91_udc.h
@@ -112,6 +112,14 @@ struct at91_udc_caps {
 	void (*pullup)(struct at91_udc *udc, int is_on);
 };
 
+struct at91_udc_data {
+	int	vbus_pin;		/* high == host powering us */
+	u8	vbus_active_low;	/* vbus polarity */
+	u8	vbus_polled;		/* Use polling, not interrupt */
+	int	pullup_pin;		/* active == D+ pulled up */
+	u8	pullup_active_low;	/* true == pullup_pin is active low */
+};
+
 /*
  * driver is non-SMP, and just blocks IRQs whenever it needs
  * access protection for chip registers or driver state
diff --git a/include/linux/platform_data/atmel.h b/include/linux/platform_data/atmel.h
index 4b452c6a2f7b..2d67e466c51b 100644
--- a/include/linux/platform_data/atmel.h
+++ b/include/linux/platform_data/atmel.h
@@ -25,15 +25,6 @@
  */
 #define ATMEL_MAX_UART	7
 
- /* USB Device */
-struct at91_udc_data {
-	int	vbus_pin;		/* high == host powering us */
-	u8	vbus_active_low;	/* vbus polarity */
-	u8	vbus_polled;		/* Use polling, not interrupt */
-	int	pullup_pin;		/* active == D+ pulled up */
-	u8	pullup_active_low;	/* true == pullup_pin is active low */
-};
-
  /* Compact Flash */
 struct at91_cf_data {
 	int	irq_pin;		/* I/O IRQ */
-- 
2.1.4



From nico at fluxnic.net  Mon Aug 10 07:49:13 2015
From: nico at fluxnic.net (Nicolas Pitre)
Date: Mon, 10 Aug 2015 10:49:13 -0400 (EDT)
Subject: Disabling caches with MMU enabled
In-Reply-To: <20150810125039.GT7557@n2100.arm.linux.org.uk>
References: <20150810125039.GT7557@n2100.arm.linux.org.uk>
Message-ID: <alpine.LFD.2.20.1508100957080.1515@knanqh.ubzr>

On Mon, 10 Aug 2015, Russell King - ARM Linux wrote:

> There is an erratum for Cortex-A15 which contains this paragraph:
> 
>  2) Do not issue write-back cacheable stores at any time when the cache
>  is disabled (SCTLR.C=0) and the MMU is enabled (SCTLR.M=1). Because it
>  is implementation defined whether cacheable stores update the cache when
>  the cache is disabled it is not expected that any portable code will
>  execute cacheable stores when the cache is disabled.
> 
> The interesting part is the second sentence, which implies that having the
> MMU enabled with writeback mappings, but with the C bit clear is not an
> expected use case.  Moreover, it reinforces the ARM ARM statment that a
> disabled cache may still be searched, and updated with written data.
> 
> However, the v7_exit_coherency_flush() function creates exactly this
> scenario by clearing the C bit:
> 
> #define v7_exit_coherency_flush(level) \
>         asm volatile( \
>         ".arch  armv7-a \n\t" \
>         "stmfd  sp!, {fp, ip} \n\t" \
>         "mrc    p15, 0, r0, c1, c0, 0   @ get SCTLR \n\t" \
>         "bic    r0, r0, #"__stringify(CR_C)" \n\t" \
>         "mcr    p15, 0, r0, c1, c0, 0   @ set SCTLR \n\t" \
>         "isb    \n\t" \
> 
> However, v7_exit_coherency_flush() is careful to disable caching, flush
> the cache and then disable coherency.  Whether that's sufficient for all
> cases is open to question - and where we need this CA15 errata implemented,
> it implies that even this sequence is not permissible to use there.

Just for the record, v7_exit_coherency_flush() was created in the 
context of the MCPM layer used by both the b.L switcher and cpuidle 
driver.  This was developed in collaboration with ARM Ltd people who had 
direct access to the hardware designers when subtle issues like this 
came up.  And they did come up during those months it took to stabilize 
test results indeed.

The v7_exit_coherency_flush() in itself is probably safe given that it 
flushes the cache after disabling it with no writes to memory in 
between.  Subsequent writes won't hit the cache even if it happens to 
still be searched, and it won't be allocated anymore by virtue of not 
being enabled.

Where things becomes interesting is within the MCPM synchronization 
primitives where we do have writes from CPUs with mixed cache states, 
and even MMU states.  This is why we also created sync_cache_w() and 
sync_cache_r().  In the former case, we certainly do have some 
occurrences of MMU enabled with writeback mappings and the C bit clear.  
But the cache for those write is supposed to be clean and not allocated 
when the C bit is clear given v7_exit_coherency_flush() is used 
beforehand.

> The exynos implementation of v7_exit_coherency() is another instance.

This one I can't explain.  It is for an A15 just like the A15 we used on 
TC2 for development and we did not need special erratum handling like 
they apparently do.  When I asked for a justification from a deeper 
investigation _other than_ some automatic citation of the errata 
document I got no answer. At this point in time it appears to be 
impossible for the right people to care.

> I think all places which clear the C bit need to be re-reviewed and at
> least some of them fixed, or converted to use a macro such as the
> v7_exit_coherency_flush macro - and they should get a notice placed
> on them to discourage copy-n-pasting it.

Agreed.  At that level you really must know what you're doing and have 
the validation infrastructure in place.  Merely copying existing code 
that was validated in a different context is not OK if it doesn't come 
with a comprehensive justification.


Nicolas


From srinivas.kandagatla at linaro.org  Mon Aug 10 07:56:54 2015
From: srinivas.kandagatla at linaro.org (Srinivas Kandagatla)
Date: Mon, 10 Aug 2015 15:56:54 +0100
Subject: [PATCH v8 3/4] drivers: nvmem: Add Vybrid OCOTP support
In-Reply-To: <29b527f1897b24a310a3f3acee61c721d3399503.1439214648.git.maitysanchayan@gmail.com>
References: <cover.1439214648.git.maitysanchayan@gmail.com>
 <29b527f1897b24a310a3f3acee61c721d3399503.1439214648.git.maitysanchayan@gmail.com>
Message-ID: <55C8BBB6.1060202@linaro.org>


Hi Sanchayan,

On 10/08/15 15:11, Sanchayan Maity wrote:
> The patch adds support for the On Chip One Time Programmable Peripheral
> (OCOTP) on the Vybrid platform.
>
> Signed-off-by: Sanchayan Maity <maitysanchayan at gmail.com>
> ---
>   drivers/nvmem/Kconfig       |  10 ++
>   drivers/nvmem/Makefile      |   2 +
>   drivers/nvmem/vf610-ocotp.c | 301 ++++++++++++++++++++++++++++++++++++++++++++
>   3 files changed, 313 insertions(+)
>   create mode 100644 drivers/nvmem/vf610-ocotp.c
>
Patch looks good to me,

Acked-by: Srinivas Kandagatla <srinivas.kandagatla at linaro.org>


--srini
> diff --git a/drivers/nvmem/Kconfig b/drivers/nvmem/Kconfig
> index 0b33014..7af4c1d 100644
> --- a/drivers/nvmem/Kconfig
> +++ b/drivers/nvmem/Kconfig
> @@ -47,4 +47,14 @@ config NVMEM_IMX_OCOTP
>   	  This driver can also be built as a module. If so, the module
>   	  will be called nvmem-imx-ocotp.
>
> +config NVMEM_VF610_OCOTP
> +	tristate "VF610_SoCs OCOTP support"
> +	depends on SOC_VF610 || COMPILE_TEST
> +	help
> +	  This is a driver for the 'OCOTP' peripheral available on Vybrid
> +	  devices like VF5xx and VF6xx.
> +
> +	  This driver can also be built as a module. If so, the module will
> +	  be called nvmem-vf610-ocotp.
> +
>   endif
> diff --git a/drivers/nvmem/Makefile b/drivers/nvmem/Makefile
> index b512d77..8a1eea8 100644
> --- a/drivers/nvmem/Makefile
> +++ b/drivers/nvmem/Makefile
> @@ -12,3 +12,5 @@ obj-$(CONFIG_NVMEM_SUNXI_SID)	+= nvmem_sunxi_sid.o
>   nvmem_sunxi_sid-y		:= sunxi_sid.o
>   obj-$(CONFIG_NVMEM_IMX_OCOTP)	+= nvmem-imx-ocotp.o
>   nvmem-imx-ocotp-y		:= imx-ocotp.o
> +obj-$(CONFIG_NVMEM_VF610_OCOTP)	+= nvmem-vf610-ocotp.o
> +nvmem-vf610-ocotp-y		:= vf610-ocotp.o
> diff --git a/drivers/nvmem/vf610-ocotp.c b/drivers/nvmem/vf610-ocotp.c
> new file mode 100644
> index 0000000..9e18156
> --- /dev/null
> +++ b/drivers/nvmem/vf610-ocotp.c
> @@ -0,0 +1,301 @@
> +/*
> + * Copyright (C) 2015 Toradex AG.
> + *
> + * Author: Sanchayan Maity <sanchayan.maity at toradex.com>
> + *
> + * Based on the barebox ocotp driver,
> + * Copyright (c) 2010 Baruch Siach <baruch at tkos.co.il>
> + *	Orex Computed Radiography
> + *
> + * This program is free software; you can redistribute it and/or modify
> + * it under the terms of the GNU General Public License version 2 and
> + * only 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/clk.h>
> +#include <linux/delay.h>
> +#include <linux/device.h>
> +#include <linux/io.h>
> +#include <linux/module.h>
> +#include <linux/nvmem-provider.h>
> +#include <linux/of.h>
> +#include <linux/platform_device.h>
> +#include <linux/regmap.h>
> +#include <linux/slab.h>
> +
> +/* OCOTP Register Offsets */
> +#define OCOTP_CTRL_REG				0x00
> +#define OCOTP_CTRL_SET				0x04
> +#define OCOTP_CTRL_CLR				0x08
> +#define OCOTP_TIMING				0x10
> +#define OCOTP_DATA				0x20
> +#define OCOTP_READ_CTRL_REG			0x30
> +#define OCOTP_READ_FUSE_DATA			0x40
> +
> +/* OCOTP Register bits and masks */
> +#define OCOTP_CTRL_WR_UNLOCK			16
> +#define OCOTP_CTRL_WR_UNLOCK_KEY		0x3E77
> +#define OCOTP_CTRL_WR_UNLOCK_MASK		GENMASK(31, 16)
> +#define OCOTP_CTRL_ADDR				0
> +#define OCOTP_CTRL_ADDR_MASK			GENMASK(6, 0)
> +#define OCOTP_CTRL_RELOAD_SHADOWS		BIT(10)
> +#define OCOTP_CTRL_ERROR			BIT(9)
> +#define OCOTP_CTRL_BUSY				BIT(8)
> +
> +#define OCOTP_TIMING_STROBE_READ		16
> +#define OCOTP_TIMING_STROBE_READ_MASK		GENMASK(21, 16)
> +#define OCOTP_TIMING_RELAX			12
> +#define OCOTP_TIMING_RELAX_MASK			GENMASK(15, 12)
> +#define OCOTP_TIMING_STROBE_PROG		0
> +#define OCOTP_TIMING_STROBE_PROG_MASK		GENMASK(11, 0)
> +
> +#define OCOTP_READ_CTRL_READ_FUSE		0x1
> +
> +#define VF610_OCOTP_TIMEOUT			100000
> +
> +#define BF(value, field)		(((value) << field) & field##_MASK)
> +
> +#define DEF_RELAX				20
> +
> +static const int base_to_fuse_addr_mappings[][2] = {
> +	{0x400, 0x00},
> +	{0x410, 0x01},
> +	{0x420, 0x02},
> +	{0x450, 0x05},
> +	{0x4F0, 0x0F},
> +	{0x600, 0x20},
> +	{0x610, 0x21},
> +	{0x620, 0x22},
> +	{0x630, 0x23},
> +	{0x640, 0x24},
> +	{0x650, 0x25},
> +	{0x660, 0x26},
> +	{0x670, 0x27},
> +	{0x6F0, 0x2F},
> +	{0x880, 0x38},
> +	{0x890, 0x39},
> +	{0x8A0, 0x3A},
> +	{0x8B0, 0x3B},
> +	{0x8C0, 0x3C},
> +	{0x8D0, 0x3D},
> +	{0x8E0, 0x3E},
> +	{0x8F0, 0x3F},
> +	{0xC80, 0x78},
> +	{0xC90, 0x79},
> +	{0xCA0, 0x7A},
> +	{0xCB0, 0x7B},
> +	{0xCC0, 0x7C},
> +	{0xCD0, 0x7D},
> +	{0xCE0, 0x7E},
> +	{0xCF0, 0x7F},
> +};
> +
> +struct vf610_ocotp {
> +	void __iomem *base;
> +	struct clk *clk;
> +	struct device *dev;
> +	struct nvmem_device *nvmem;
> +	int timing;
> +};
> +
> +static int vf610_ocotp_wait_busy(void __iomem *base)
> +{
> +	int timeout = VF610_OCOTP_TIMEOUT;
> +
> +	while ((readl(base) & OCOTP_CTRL_BUSY) && --timeout)
> +		udelay(10);
> +
> +	if (!timeout) {
> +		writel(OCOTP_CTRL_ERROR, base + OCOTP_CTRL_CLR);
> +		return -ETIMEDOUT;
> +	}
> +
> +	udelay(10);
> +
> +	return 0;
> +}
> +
> +static int vf610_ocotp_calculate_timing(struct vf610_ocotp *ocotp_dev)
> +{
> +	u32 clk_rate;
> +	u32 relax, strobe_read, strobe_prog;
> +	u32 timing;
> +
> +	clk_rate = clk_get_rate(ocotp_dev->clk);
> +
> +	/* Refer section OTP read/write timing parameters in TRM */
> +	relax = clk_rate / (1000000000 / DEF_RELAX) - 1;
> +	strobe_prog = clk_rate / (1000000000 / 10000) + 2 * (DEF_RELAX + 1) - 1;
> +	strobe_read = clk_rate / (1000000000 / 40) + 2 * (DEF_RELAX + 1) - 1;
> +
> +	timing = BF(relax, OCOTP_TIMING_RELAX);
> +	timing |= BF(strobe_read, OCOTP_TIMING_STROBE_READ);
> +	timing |= BF(strobe_prog, OCOTP_TIMING_STROBE_PROG);
> +
> +	return timing;
> +}
> +
> +static int vf610_get_fuse_address(int base_addr_offset)
> +{
> +	int i;
> +
> +	for (i = 0; i < ARRAY_SIZE(base_to_fuse_addr_mappings); i++) {
> +		if (base_to_fuse_addr_mappings[i][0] == base_addr_offset)
> +			return base_to_fuse_addr_mappings[i][1];
> +	}
> +
> +	return -EINVAL;
> +}
> +
> +static int vf610_ocotp_write(void *context, const void *data, size_t count)
> +{
> +	return 0;
> +}
> +
> +static int vf610_ocotp_read(void *context,
> +			const void *off, size_t reg_size,
> +			void *val, size_t val_size)
> +{
> +	struct vf610_ocotp *ocotp = context;
> +	unsigned int offset = *(u32 *)off;
> +	u32 reg, *buf = val;
> +	int fuse_addr;
> +	int ret;
> +
> +	while (val_size > 0) {
> +		fuse_addr = vf610_get_fuse_address(offset);
> +		if (fuse_addr > 0) {
> +			writel(ocotp->timing, ocotp->base + OCOTP_TIMING);
> +			ret = vf610_ocotp_wait_busy(ocotp->base + OCOTP_CTRL_REG);
> +			if (ret)
> +				return ret;
> +
> +			reg = readl(ocotp->base + OCOTP_CTRL_REG);
> +			reg &= ~OCOTP_CTRL_ADDR_MASK;
> +			reg &= ~OCOTP_CTRL_WR_UNLOCK_MASK;
> +			reg |= BF(fuse_addr, OCOTP_CTRL_ADDR);
> +			writel(reg, ocotp->base + OCOTP_CTRL_REG);
> +
> +			writel(OCOTP_READ_CTRL_READ_FUSE,
> +				ocotp->base + OCOTP_READ_CTRL_REG);
> +			ret = vf610_ocotp_wait_busy(ocotp->base + OCOTP_CTRL_REG);
> +			if (ret)
> +				return ret;
> +
> +			if (readl(ocotp->base) & OCOTP_CTRL_ERROR) {
> +				dev_dbg(ocotp->dev, "Error reading from fuse address %x\n",
> +					fuse_addr);
> +				writel(OCOTP_CTRL_ERROR, ocotp->base + OCOTP_CTRL_CLR);
> +			}
> +
> +			/*
> +			 * In case of error, we do not abort and expect to read
> +			 * 0xBADABADA as mentioned by the TRM. We just read this
> +			 * value and return.
> +			 */
> +			*buf = readl(ocotp->base + OCOTP_READ_FUSE_DATA);
> +		} else {
> +			*buf = 0;
> +		}
> +
> +		buf++;
> +		val_size--;
> +		offset += reg_size;
> +	}
> +
> +	return 0;
> +}
> +
> +static struct regmap_bus vf610_ocotp_bus = {
> +	.read = vf610_ocotp_read,
> +	.write = vf610_ocotp_write,
> +	.reg_format_endian_default = REGMAP_ENDIAN_NATIVE,
> +	.val_format_endian_default = REGMAP_ENDIAN_NATIVE,
> +};
> +
> +static struct regmap_config ocotp_regmap_config = {
> +	.reg_bits = 32,
> +	.val_bits = 32,
> +	.reg_stride = 4,
> +};
> +
> +static struct nvmem_config ocotp_config = {
> +	.name = "ocotp",
> +	.owner = THIS_MODULE,
> +};
> +
> +static const struct of_device_id ocotp_of_match[] = {
> +	{ .compatible = "fsl,vf610-ocotp", },
> +	{/* sentinel */},
> +};
> +MODULE_DEVICE_TABLE(of, ocotp_of_match);
> +
> +static int vf610_ocotp_remove(struct platform_device *pdev)
> +{
> +	struct vf610_ocotp *ocotp_dev = platform_get_drvdata(pdev);
> +
> +	return nvmem_unregister(ocotp_dev->nvmem);
> +}
> +
> +static int vf610_ocotp_probe(struct platform_device *pdev)
> +{
> +	struct device *dev = &pdev->dev;
> +	struct resource *res;
> +	struct regmap *regmap;
> +	struct vf610_ocotp *ocotp_dev;
> +
> +	ocotp_dev = devm_kzalloc(&pdev->dev,
> +			sizeof(struct vf610_ocotp), GFP_KERNEL);
> +	if (!ocotp_dev)
> +		return -ENOMEM;
> +
> +	res = platform_get_resource(pdev, IORESOURCE_MEM, 0);
> +	ocotp_dev->base = devm_ioremap_resource(dev, res);
> +	if (IS_ERR(ocotp_dev->base))
> +		return PTR_ERR(ocotp_dev->base);
> +
> +	ocotp_dev->clk = devm_clk_get(dev, "ocotp");
> +	if (IS_ERR(ocotp_dev->clk)) {
> +		dev_err(dev, "failed getting clock, err = %ld\n",
> +			PTR_ERR(ocotp_dev->clk));
> +		return PTR_ERR(ocotp_dev->clk);
> +	}
> +
> +	ocotp_regmap_config.max_register = resource_size(res);
> +	regmap = devm_regmap_init(dev,
> +		&vf610_ocotp_bus, ocotp_dev, &ocotp_regmap_config);
> +	if (IS_ERR(regmap)) {
> +		dev_err(dev, "regmap init failed\n");
> +		return PTR_ERR(regmap);
> +	}
> +	ocotp_config.dev = dev;
> +
> +	ocotp_dev->nvmem = nvmem_register(&ocotp_config);
> +	if (IS_ERR(ocotp_dev->nvmem))
> +		return PTR_ERR(ocotp_dev->nvmem);
> +
> +	ocotp_dev->dev = dev;
> +	platform_set_drvdata(pdev, ocotp_dev);
> +
> +	ocotp_dev->timing = vf610_ocotp_calculate_timing(ocotp_dev);
> +
> +	return 0;
> +}
> +
> +static struct platform_driver vf610_ocotp_driver = {
> +	.probe = vf610_ocotp_probe,
> +	.remove = vf610_ocotp_remove,
> +	.driver = {
> +		.name = "vf610-ocotp",
> +		.of_match_table = ocotp_of_match,
> +	},
> +};
> +module_platform_driver(vf610_ocotp_driver);
> +MODULE_AUTHOR("Sanchayan Maity <sanchayan.maity at toradex.com>");
> +MODULE_DESCRIPTION("Vybrid OCOTP driver");
> +MODULE_LICENSE("GPL v2");
>


From srinivas.kandagatla at linaro.org  Mon Aug 10 07:57:59 2015
From: srinivas.kandagatla at linaro.org (Srinivas Kandagatla)
Date: Mon, 10 Aug 2015 15:57:59 +0100
Subject: [PATCH v8 4/4] nvmem: Add DT binding documentation for Vybrid
 OCOTP driver
In-Reply-To: <3149879671b1b1b0b6fc1fbe62e9f49333deb8ed.1439214648.git.maitysanchayan@gmail.com>
References: <cover.1439214648.git.maitysanchayan@gmail.com>
 <3149879671b1b1b0b6fc1fbe62e9f49333deb8ed.1439214648.git.maitysanchayan@gmail.com>
Message-ID: <55C8BBF7.30308@linaro.org>



On 10/08/15 15:11, Sanchayan Maity wrote:
> Add the devicetree bindings for the Freescale Vybrid On-Chip
> OTP driver.
>
> Signed-off-by: Sanchayan Maity <maitysanchayan at gmail.com>
> ---
>   .../devicetree/bindings/nvmem/vf610-ocotp.txt       | 21 +++++++++++++++++++++
>   1 file changed, 21 insertions(+)
>   create mode 100644 Documentation/devicetree/bindings/nvmem/vf610-ocotp.txt
>

Acked-by: Srinivas Kandagatla <srinivas.kandagatla at linaro.org>

> diff --git a/Documentation/devicetree/bindings/nvmem/vf610-ocotp.txt b/Documentation/devicetree/bindings/nvmem/vf610-ocotp.txt
> new file mode 100644
> index 0000000..b29f65f
> --- /dev/null
> +++ b/Documentation/devicetree/bindings/nvmem/vf610-ocotp.txt
> @@ -0,0 +1,21 @@
> +On-Chip OTP Memory for Freescale Vybrid
> +
> +Required Properties:
> +  compatible:
> +  - "fsl,vf610-ocotp" for VF5xx/VF6xx
> +  #address-cells : Should be 1
> +  #size-cells : Should be 1
> +  reg : Address and length of OTP controller and fuse map registers
> +  clocks : ipg clock we associate with the OCOTP peripheral
> +  clock-names : Must contain "ocotp" as matching entry
> +
> +Example for Vybrid VF5xx/VF6xx:
> +
> +	ocotp: ocotp at 400a5000 {
> +		compatible = "fsl,vf610-ocotp";
> +		#address-cells = <1>;
> +		#size-cells = <1>;
> +		reg = <0x400a5000 0xCF0>;
> +		clocks = <&clks VF610_CLK_OCOTP>;
> +		clock-names = "ocotp";
> +	};
>


From catalin.marinas at arm.com  Mon Aug 10 07:58:04 2015
From: catalin.marinas at arm.com (Catalin Marinas)
Date: Mon, 10 Aug 2015 15:58:04 +0100
Subject: [PATCH 2/2] arm64: VDSO: fix coarse clock monotonicity regression
In-Reply-To: <20150810092252.GB1604@arm.com>
References: <1438999403-5770-1-git-send-email-nathan_lynch@mentor.com>
 <1438999403-5770-3-git-send-email-nathan_lynch@mentor.com>
 <20150810092252.GB1604@arm.com>
Message-ID: <20150810145804.GA15394@e104818-lin.cambridge.arm.com>

On Mon, Aug 10, 2015 at 10:22:53AM +0100, Will Deacon wrote:
> On Sat, Aug 08, 2015 at 03:03:23AM +0100, Nathan Lynch wrote:
> > Since 906c55579a63 ("timekeeping: Copy the shadow-timekeeper over the
> > real timekeeper last") it has become possible on arm64 to:
> > 
> > - Obtain a CLOCK_MONOTONIC_COARSE or CLOCK_REALTIME_COARSE timestamp
> >   via syscall.
> > - Subsequently obtain a timestamp for the same clock ID via VDSO which
> >   predates the first timestamp (by one jiffy).
> > 
> > This is because arm64's update_vsyscall is deriving the coarse time
> > using the __current_kernel_time interface, when it should really be
> > using the timekeeper object provided to it by the timekeeping core.
> > It happened to work before only because __current_kernel_time would
> > access the same timekeeper object which had been passed to
> > update_vsyscall.  This is no longer the case.
> > 
> > Signed-off-by: Nathan Lynch <nathan_lynch at mentor.com>
> > ---
> >  arch/arm64/kernel/vdso.c | 7 +++----
> >  1 file changed, 3 insertions(+), 4 deletions(-)
> > 
> > diff --git a/arch/arm64/kernel/vdso.c b/arch/arm64/kernel/vdso.c
> > index ec37ab3f524f..97bc68f4c689 100644
> > --- a/arch/arm64/kernel/vdso.c
> > +++ b/arch/arm64/kernel/vdso.c
> > @@ -199,16 +199,15 @@ int arch_setup_additional_pages(struct linux_binprm *bprm,
> >   */
> >  void update_vsyscall(struct timekeeper *tk)
> >  {
> > -	struct timespec xtime_coarse;
> >  	u32 use_syscall = strcmp(tk->tkr_mono.clock->name, "arch_sys_counter");
> >  
> >  	++vdso_data->tb_seq_count;
> >  	smp_wmb();
> >  
> > -	xtime_coarse = __current_kernel_time();
> >  	vdso_data->use_syscall			= use_syscall;
> > -	vdso_data->xtime_coarse_sec		= xtime_coarse.tv_sec;
> > -	vdso_data->xtime_coarse_nsec		= xtime_coarse.tv_nsec;
> > +	vdso_data->xtime_coarse_sec		= tk->xtime_sec;
> > +	vdso_data->xtime_coarse_nsec		= tk->tkr_mono.xtime_nsec >>
> > +							tk->tkr_mono.shift;
> >  	vdso_data->wtm_clock_sec		= tk->wall_to_monotonic.tv_sec;
> >  	vdso_data->wtm_clock_nsec		= tk->wall_to_monotonic.tv_nsec;
> 
> Looks good,
> 
>   Acked-by: Will Deacon <will.deacon at arm.com>
> 
> There's probably still time for Catalin to pick this up for 4.2.

Applied, I'll send a pull request today/tomorrow. Thanks.

-- 
Catalin


From shawnguo at kernel.org  Mon Aug 10 08:35:42 2015
From: shawnguo at kernel.org (Shawn Guo)
Date: Mon, 10 Aug 2015 23:35:42 +0800
Subject: [GIT PULL] ARM: imx: fixes for 4.2, 3rd round
Message-ID: <20150810153542.GA10035@tiger>

The following changes since commit e053f96b1a00022b4e2c7ceb7ac0229646626507:

  ARM: dts: i.MX35: Fix can support. (2015-07-25 11:35:08 +0800)

are available in the git repository at:

  git://git.kernel.org/pub/scm/linux/kernel/git/shawnguo/linux.git tags/imx-fixes-4.2-3

for you to fetch changes up to 1a9fa190956f45c1e58c4d8bfa5ac051691ea590:

  ARM: imx6: correct i.MX6 PCIe interrupt routing (2015-08-06 16:30:18 +0800)

----------------------------------------------------------------
The i.MX fixes for 4.2, 3rd round:
 - Fix i.MX6 PCIe interrupt routing which gets missed from stacked IRQ
   domain conversion.  The PCIe wakeup support is currently broken
   because of this.

----------------------------------------------------------------
Lucas Stach (1):
      ARM: imx6: correct i.MX6 PCIe interrupt routing

 arch/arm/boot/dts/imx6qdl.dtsi | 8 ++++----
 1 file changed, 4 insertions(+), 4 deletions(-)


From lina.iyer at linaro.org  Mon Aug 10 08:36:24 2015
From: lina.iyer at linaro.org (Lina Iyer)
Date: Mon, 10 Aug 2015 09:36:24 -0600
Subject: [PATCH 6/9] ARM: domain: Add platform handlers for CPU PM domains
In-Reply-To: <CAL_JsqJ_AK6M5WmyFrGVLtpGg=MdAafxX=1873Je_uB_sQkpiA@mail.gmail.com>
References: <1438731339-58317-1-git-send-email-lina.iyer@linaro.org>
 <1438731339-58317-7-git-send-email-lina.iyer@linaro.org>
 <CAL_JsqKWekSGiFbZz6++3ibAzY_8Y6+0nOBQinFVw4cBk6JvEw@mail.gmail.com>
 <20150805192341.GB52339@linaro.org>
 <CAL_JsqJ_AK6M5WmyFrGVLtpGg=MdAafxX=1873Je_uB_sQkpiA@mail.gmail.com>
Message-ID: <20150810153624.GD52339@linaro.org>

On Wed, Aug 05 2015 at 21:01 -0600, Rob Herring wrote:
>On Wed, Aug 5, 2015 at 2:23 PM, Lina Iyer <lina.iyer at linaro.org> wrote:
>> On Wed, Aug 05 2015 at 08:45 -0600, Rob Herring wrote:
>>>
>>> On Tue, Aug 4, 2015 at 6:35 PM, Lina Iyer <lina.iyer at linaro.org> wrote:
>>>>
>>>> In addition to the common power up/down actions of CPU PM domain core,
>>>> platforms may have additional configuration before the CPU domain can be
>>>> powered off or considered active. Allow platform drivers to register
>>>> handlers for CPU PM domains.
>>>>
>>>> Platform drivers may register their callbacks against a compatible
>>>> string defined by their PM domain provider device node in the DT. At
>>>> domain init, the platform driver can initialize the platform specific
>>>> genpd attributes. The init callback would need to return successfully,
>>>> for the platform power_on/off handlers to be registered with the CPU PM
>>>> domain.
>>>>
>>>> The code uses __init section to reduce memory needed for platform
>>>> handlers and therefore can be freed after the driver is initialized, a
>>>> desirable outcome for single kernel image.
>>>
>>>
>>> [...]
>>>
>>>> diff --git a/arch/arm/include/asm/arm-pd.h
>>>> b/arch/arm/include/asm/arm-pd.h
>>>> new file mode 100644
>>>> index 0000000..fc44abf
>>
>>
>> [...]
>>
>>>> +#define ARM_PD_METHOD_OF_DECLARE(_name, _handle, _ops) \
>>>> +       static const struct of_arm_pd_method
>>>> __arm_pd_method_of_table_##_name \
>>>> +       __used __section(__arm_pd_method_of_table)              \
>>>> +       = { .handle = _handle, .ops = _ops }
>>>
>>>
>>> AFAICT, you are not using this in this series. You should add it when
>>> you have a user.
>>>
>>> Ideally, we keep some amount of uniformity across various *_OF_DECLARE
>>> which is why we have OF_DECLARE_1 and OF_DECLARE_2. This makes all the
>>> sections just arrays of struct of_device_id. Not all users follow
>>> this, but most do. So instead of putting the ops in here, platforms
>>> can provide a function callback which can then set the ops. Then you
>>> also don't need the .init() ops function as the callback function can
>>> do any initialization too.
>>>
>> I looked through these and I can switch over to _OF_DECLARE() without any
>> issues, but using OF_DECLARE_1 or OF_DECLARE_2 is pretty limiting.
>
>Well yes, but then we only want to use it for things that will never
>use the driver model.
>
>> If I could set up my own function type for the .data member, then its a
>> lot more easier on the code. Like this -
>>
>> typedef int (*arm_pd_init)(struct device_node *dn, struct
>>                 generic_pm_domain *genpd, struct of_arm_pd_ops *ops);
>
>You alloc the genpd struct just before calling init. You can just as
>easily have the platform specific code call an allocation function and
>a function to set the ops functions. This is more inline with how a
>driver would work when registering with a subsystem.
>
OK. That would mean I have a way of mapping the device_node to the
of_arm_pd_ops, which I currently dont. Was trying to avoid a list. But,
I was able to use list and use OF_DECLARE_1. The platform driver, shall
call up separate API to register the ops or ge the Genpd and modify it.

Will submit it in the next spin, following the discussion on arm,pd.

Thanks,
Lina


>I also don't
>think "arm,pd" is a good compatible string to be matching on. I'll
>comment on that more in patch 5.
>
>Rob


From nathan_lynch at mentor.com  Mon Aug 10 08:46:32 2015
From: nathan_lynch at mentor.com (Nathan Lynch)
Date: Mon, 10 Aug 2015 10:46:32 -0500
Subject: [PATCH v2] ARM: VDSO: fix coarse clock monotonicity regression
In-Reply-To: <1438999403-5770-1-git-send-email-nathan_lynch@mentor.com>
References: <1438999403-5770-1-git-send-email-nathan_lynch@mentor.com>
Message-ID: <1439221592-31875-1-git-send-email-nathan_lynch@mentor.com>

Since 906c55579a63 ("timekeeping: Copy the shadow-timekeeper over the
real timekeeper last") it has become possible on ARM to:

- Obtain a CLOCK_MONOTONIC_COARSE or CLOCK_REALTIME_COARSE timestamp
  via syscall.
- Subsequently obtain a timestamp for the same clock ID via VDSO which
  predates the first timestamp (by one jiffy).

This is because ARM's update_vsyscall is deriving the coarse time
using the __current_kernel_time interface, when it should really be
using the timekeeper object provided to it by the timekeeping core.
It happened to work before only because __current_kernel_time would
access the same timekeeper object which had been passed to
update_vsyscall.  This is no longer the case.

Signed-off-by: Nathan Lynch <nathan_lynch at mentor.com>
---

Changes since v1:
- Add u32 cast to nsec calculation.

 arch/arm/kernel/vdso.c | 7 +++----
 1 file changed, 3 insertions(+), 4 deletions(-)

diff --git a/arch/arm/kernel/vdso.c b/arch/arm/kernel/vdso.c
index efe17dd9b921..54a5aeab988d 100644
--- a/arch/arm/kernel/vdso.c
+++ b/arch/arm/kernel/vdso.c
@@ -296,7 +296,6 @@ static bool tk_is_cntvct(const struct timekeeper *tk)
  */
 void update_vsyscall(struct timekeeper *tk)
 {
-	struct timespec xtime_coarse;
 	struct timespec64 *wtm = &tk->wall_to_monotonic;
 
 	if (!cntvct_ok) {
@@ -308,10 +307,10 @@ void update_vsyscall(struct timekeeper *tk)
 
 	vdso_write_begin(vdso_data);
 
-	xtime_coarse = __current_kernel_time();
 	vdso_data->tk_is_cntvct			= tk_is_cntvct(tk);
-	vdso_data->xtime_coarse_sec		= xtime_coarse.tv_sec;
-	vdso_data->xtime_coarse_nsec		= xtime_coarse.tv_nsec;
+	vdso_data->xtime_coarse_sec		= tk->xtime_sec;
+	vdso_data->xtime_coarse_nsec		= (u32)(tk->tkr_mono.xtime_nsec >>
+							tk->tkr_mono.shift);
 	vdso_data->wtm_clock_sec		= wtm->tv_sec;
 	vdso_data->wtm_clock_nsec		= wtm->tv_nsec;
 
-- 
2.1.0



From will.deacon at arm.com  Mon Aug 10 08:48:16 2015
From: will.deacon at arm.com (Will Deacon)
Date: Mon, 10 Aug 2015 16:48:16 +0100
Subject: [PATCH v2] ARM: VDSO: fix coarse clock monotonicity regression
In-Reply-To: <1439221592-31875-1-git-send-email-nathan_lynch@mentor.com>
References: <1438999403-5770-1-git-send-email-nathan_lynch@mentor.com>
 <1439221592-31875-1-git-send-email-nathan_lynch@mentor.com>
Message-ID: <20150810154815.GH1604@arm.com>

On Mon, Aug 10, 2015 at 04:46:32PM +0100, Nathan Lynch wrote:
> Since 906c55579a63 ("timekeeping: Copy the shadow-timekeeper over the
> real timekeeper last") it has become possible on ARM to:
> 
> - Obtain a CLOCK_MONOTONIC_COARSE or CLOCK_REALTIME_COARSE timestamp
>   via syscall.
> - Subsequently obtain a timestamp for the same clock ID via VDSO which
>   predates the first timestamp (by one jiffy).
> 
> This is because ARM's update_vsyscall is deriving the coarse time
> using the __current_kernel_time interface, when it should really be
> using the timekeeper object provided to it by the timekeeping core.
> It happened to work before only because __current_kernel_time would
> access the same timekeeper object which had been passed to
> update_vsyscall.  This is no longer the case.
> 
> Signed-off-by: Nathan Lynch <nathan_lynch at mentor.com>
> ---
> 
> Changes since v1:
> - Add u32 cast to nsec calculation.

Acked-by: Will Deacon <will.deacon at arm.com>

Probably best sticking it into Russell's patch system with a Cc stable
in case it doesn't make it for 4.2.

Will

>  arch/arm/kernel/vdso.c | 7 +++----
>  1 file changed, 3 insertions(+), 4 deletions(-)
> 
> diff --git a/arch/arm/kernel/vdso.c b/arch/arm/kernel/vdso.c
> index efe17dd9b921..54a5aeab988d 100644
> --- a/arch/arm/kernel/vdso.c
> +++ b/arch/arm/kernel/vdso.c
> @@ -296,7 +296,6 @@ static bool tk_is_cntvct(const struct timekeeper *tk)
>   */
>  void update_vsyscall(struct timekeeper *tk)
>  {
> -	struct timespec xtime_coarse;
>  	struct timespec64 *wtm = &tk->wall_to_monotonic;
>  
>  	if (!cntvct_ok) {
> @@ -308,10 +307,10 @@ void update_vsyscall(struct timekeeper *tk)
>  
>  	vdso_write_begin(vdso_data);
>  
> -	xtime_coarse = __current_kernel_time();
>  	vdso_data->tk_is_cntvct			= tk_is_cntvct(tk);
> -	vdso_data->xtime_coarse_sec		= xtime_coarse.tv_sec;
> -	vdso_data->xtime_coarse_nsec		= xtime_coarse.tv_nsec;
> +	vdso_data->xtime_coarse_sec		= tk->xtime_sec;
> +	vdso_data->xtime_coarse_nsec		= (u32)(tk->tkr_mono.xtime_nsec >>
> +							tk->tkr_mono.shift);
>  	vdso_data->wtm_clock_sec		= wtm->tv_sec;
>  	vdso_data->wtm_clock_nsec		= wtm->tv_nsec;
>  
> -- 
> 2.1.0
> 


From linux at arm.linux.org.uk  Mon Aug 10 08:48:48 2015
From: linux at arm.linux.org.uk (Russell King - ARM Linux)
Date: Mon, 10 Aug 2015 16:48:48 +0100
Subject: [PATCH 9/9] drm: bridge/dw_hdmi-i2s-audio: add audio driver
In-Reply-To: <E1ZO6hr-0003No-RB@rmk-PC.arm.linux.org.uk>
References: <20150808160936.GN7557@n2100.arm.linux.org.uk>
 <E1ZO6hr-0003No-RB@rmk-PC.arm.linux.org.uk>
Message-ID: <20150810154848.GV7557@n2100.arm.linux.org.uk>

On Sat, Aug 08, 2015 at 05:10:47PM +0100, Russell King wrote:
> From: Yakir Yang <ykk at rock-chips.com>
> 
> Add ALSA based HDMI I2S audio driver for dw_hdmi. Sound card
> driver could connect to this codec through the codec dai name
> "dw-hdmi-i2s-audio".
> 
> [Fixed IRQ name, MODULE_DESCRIPTION, MODULE_ALIAS in
>  dw-hdmi-i2s-audio.c, and platform device name in dw-hdmi.c --rmk]
> 
> Signed-off-by: Yakir Yang <ykk at rock-chips.com>
> Signed-off-by: Russell King <rmk+kernel at arm.linux.org.uk>

I'm dropping this patch after all as it no longer builds against modern
kernels due to the reference to the removed snd_soc_jack_new().  Its
replacement is at card level, and I don't think it's a simple case of
replacing it here.

> +static int snd_dw_hdmi_audio_probe(struct snd_soc_codec *codec)
> +{
> +	struct snd_dw_hdmi *dw = snd_soc_codec_get_drvdata(codec);
> +	int ret;
> +
> +	ret = snd_soc_jack_new(codec, "dw Jack", SND_JACK_LINEOUT,
> +			       &dw->jack);
...
> +static const struct snd_soc_codec_driver dw_hdmi_audio = {
> +	.probe = snd_dw_hdmi_audio_probe,
> +	.dapm_widgets = snd_dw_hdmi_audio_widgets,
> +	.num_dapm_widgets = ARRAY_SIZE(snd_dw_hdmi_audio_widgets),
> +	.dapm_routes = snd_dw_hdmi_audio_routes,
> +	.num_dapm_routes = ARRAY_SIZE(snd_dw_hdmi_audio_routes),
> +};
> +
> +static int dw_hdmi_audio_probe(struct platform_device *pdev)
> +{
> +	struct dw_hdmi_audio_data *data = pdev->dev.platform_data;
> +	struct snd_dw_hdmi *dw;
> +	int ret;
> +
> +	dw = devm_kzalloc(&pdev->dev, sizeof(*dw), GFP_KERNEL);
> +	if (!dw)
> +		return -ENOMEM;
> +
> +	dw->data = *data;
> +	dw->dev = &pdev->dev;
> +	dw->is_jack_ready = false;
> +	platform_set_drvdata(pdev, dw);
> +
> +	ret = request_irq(dw->data.irq, snd_dw_hdmi_irq, IRQF_SHARED,
> +			  DRIVER_NAME, dw);
> +	if (ret) {
> +		dev_err(&pdev->dev, "request irq failed (%d)\n", ret);
> +		return -EINVAL;
> +	}
> +
> +	ret = snd_soc_register_codec(&pdev->dev, &dw_hdmi_audio,
> +				     &dw_hdmi_audio_dai, 1);

-- 
FTTC broadband for 0.8mile line: currently at 10.5Mbps down 400kbps up
according to speedtest.net.


From lee.jones at linaro.org  Mon Aug 10 08:49:10 2015
From: lee.jones at linaro.org (Lee Jones)
Date: Mon, 10 Aug 2015 16:49:10 +0100
Subject: [PATCH 1/2] mfd: s2mps11: Add manual shutdown method for Odroid
 XU3
In-Reply-To: <1438605447-6836-2-git-send-email-k.kozlowski.k@gmail.com>
References: <1438605447-6836-1-git-send-email-k.kozlowski.k@gmail.com>
 <1438605447-6836-2-git-send-email-k.kozlowski.k@gmail.com>
Message-ID: <20150810154910.GA12631@x1>

On Mon, 03 Aug 2015, Krzysztof Kozlowski wrote:

> On Odroid XU3 board (with S2MPS11 PMIC) the PWRHOLD bit in CTRL1
> register must be manually set to 0 before initiating power off sequence.
> 
> One of usual power down methods for Exynos based devices looks like:
> 1. PWRHOLD pin of PMIC is connected to PSHOLD of Exynos.
> 2. Exynos holds up this pin during system operation.
> 3. ACOKB pin of PMIC is pulled up to VBATT and optionally to pin in
>    other device.
> 4. When PWRHOLD/PSHOLD goes low, the PMIC will turn off the power if
>    ACOKB goes high.
> 
> On Odroid XU3 family the difference is in (3) - the ACOKB is grounded.
> This means that PMIC must manually set PWRHOLD field to low and then
> wait for signal from Application Processor (the usual change in
> PWRHOLD/PSHOLD pin will actually cut off the power).
> 
> The patch adds respective binding allowing Odroid XU3 device to be
> powered off.
> 
> Signed-off-by: Krzysztof Kozlowski <k.kozlowski.k at gmail.com>
> Reported-by: Anand Moon <linux.amoon at gmail.com>
> 
> ---
> 
> Patch is losely based on patch in Hardkernel repository [0] and previous
> work of Anand Moon [1].
> 
> [0] https://github.com/hardkernel/linux/commit/6897e62ba328bd1c8c095d918101863250cd73e7
> [1] http://www.spinics.net/lists/linux-samsung-soc/msg45959.html
> ---
>  Documentation/devicetree/bindings/mfd/s2mps11.txt |  4 +++
>  drivers/mfd/sec-core.c                            | 31 +++++++++++++++++++++++
>  include/linux/mfd/samsung/core.h                  |  2 ++
>  include/linux/mfd/samsung/s2mps11.h               |  1 +
>  4 files changed, 38 insertions(+)
> 
> diff --git a/Documentation/devicetree/bindings/mfd/s2mps11.txt b/Documentation/devicetree/bindings/mfd/s2mps11.txt
> index 57a045016fca..90eaef393325 100644
> --- a/Documentation/devicetree/bindings/mfd/s2mps11.txt
> +++ b/Documentation/devicetree/bindings/mfd/s2mps11.txt
> @@ -15,6 +15,10 @@ Optional properties:
>  - interrupt-parent: Specifies the phandle of the interrupt controller to which
>    the interrupts from s2mps11 are delivered to.
>  - interrupts: Interrupt specifiers for interrupt sources.

> +- samsung,s2mps11-acokb-ground: Indicates that ACOKB pin of S2MPS11 PMIC is
> +  connected to the ground so the PMIC must manually set PWRHOLD bit in CTRL1
> +  register to turn off the power. Usually the ACOKB is pulled up to VBATT so
> +  when PWRHOLD pin goes low, the rising ACOKB will trigger power off.

Binding looks fine.  Please seperate it into a different patch and
apply my Ack:

Acked-by: Lee Jones <lee.jones at linaro.org>

>  Optional nodes:
>  - clocks: s2mps11, s2mps13 and s5m8767 provide three(AP/CP/BT) buffered 32.768
> diff --git a/drivers/mfd/sec-core.c b/drivers/mfd/sec-core.c
> index d206a3e8fe87..a56ab2102a32 100644
> --- a/drivers/mfd/sec-core.c
> +++ b/drivers/mfd/sec-core.c
> @@ -278,6 +278,8 @@ static struct sec_platform_data *sec_pmic_i2c_parse_dt_pdata(
>  	 * not parsed here.
>  	 */
>  
> +	pd->manual_poweroff = of_property_read_bool(dev->of_node,
> +						"samsung,s2mps11-acokb-ground");
>  	return pd;
>  }
>  #else
> @@ -440,6 +442,34 @@ static int sec_pmic_remove(struct i2c_client *i2c)
>  	return 0;
>  }
>  
> +static void sec_pmic_shutdown(struct i2c_client *i2c)
> +{
> +	struct sec_pmic_dev *sec_pmic = i2c_get_clientdata(i2c);
> +	unsigned int reg, mask;
> +
> +	if (!sec_pmic->pdata->manual_poweroff)
> +		return;
> +
> +	switch (sec_pmic->device_type) {
> +	case S2MPS11X:
> +		reg = S2MPS11_REG_CTRL1;
> +		mask = S2MPS11_CTRL1_PWRHOLD_MASK;
> +		break;
> +	default:
> +		/*
> +		 * Currently only one board with S2MPS11 needs this, so just
> +		 * ignore the rest.
> +		 */
> +		dev_warn(sec_pmic->dev,
> +			"Unsupported device %lu for manual power off\n",
> +			sec_pmic->device_type);
> +		return;
> +	}
> +
> +	regmap_update_bits(sec_pmic->regmap_pmic, reg, mask, 0);
> +}
> +
> +

Remove the extra '\n'.

When you resubmit, apply my Ack:

Acked-by: Lee Jones <lee.jones at linaro.org>

>  #ifdef CONFIG_PM_SLEEP
>  static int sec_pmic_suspend(struct device *dev)
>  {
> @@ -491,6 +521,7 @@ static struct i2c_driver sec_pmic_driver = {
>  	},
>  	.probe = sec_pmic_probe,
>  	.remove = sec_pmic_remove,
> +	.shutdown = sec_pmic_shutdown,
>  	.id_table = sec_pmic_id,
>  };
>  
> diff --git a/include/linux/mfd/samsung/core.h b/include/linux/mfd/samsung/core.h
> index 75115384f3fc..aa78957e092f 100644
> --- a/include/linux/mfd/samsung/core.h
> +++ b/include/linux/mfd/samsung/core.h
> @@ -132,6 +132,8 @@ struct sec_platform_data {
>  	int				buck2_init;
>  	int				buck3_init;
>  	int				buck4_init;
> +	/* Whether or not manually set PWRHOLD to low during shutdown. */
> +	bool				manual_poweroff;
>  };
>  
>  /**
> diff --git a/include/linux/mfd/samsung/s2mps11.h b/include/linux/mfd/samsung/s2mps11.h
> index 7981a9d77d3f..b288965e8101 100644
> --- a/include/linux/mfd/samsung/s2mps11.h
> +++ b/include/linux/mfd/samsung/s2mps11.h
> @@ -179,6 +179,7 @@ enum s2mps11_regulators {
>  #define S2MPS11_BUCK_N_VOLTAGES (S2MPS11_BUCK_VSEL_MASK + 1)
>  #define S2MPS11_RAMP_DELAY	25000		/* uV/us */
>  
> +#define S2MPS11_CTRL1_PWRHOLD_MASK	BIT(4)
>  
>  #define S2MPS11_BUCK2_RAMP_SHIFT	6
>  #define S2MPS11_BUCK34_RAMP_SHIFT	4

-- 
Lee Jones
Linaro STMicroelectronics Landing Team Lead
Linaro.org ? Open source software for ARM SoCs
Follow Linaro: Facebook | Twitter | Blog


From alexandre.belloni at free-electrons.com  Mon Aug 10 08:50:05 2015
From: alexandre.belloni at free-electrons.com (Alexandre Belloni)
Date: Mon, 10 Aug 2015 17:50:05 +0200
Subject: [PATCH 18/23] power/reset: at91-reset: get and use slow clock
In-Reply-To: <20150805182220.GC11315@earth>
References: <1438335599-3301-1-git-send-email-alexandre.belloni@free-electrons.com>
 <1438335599-3301-19-git-send-email-alexandre.belloni@free-electrons.com>
 <20150805182220.GC11315@earth>
Message-ID: <20150810155005.GH3411@piout.net>

On 05/08/2015 at 20:22:20 +0200, Sebastian Reichel wrote :
> Hi,
> 
> On Fri, Jul 31, 2015 at 11:39:54AM +0200, Alexandre Belloni wrote:
> > Commit dca1a4b5ff6e ("clk: at91: keep slow clk enabled to prevent system
> > hang") added a workaround for the slow clock as it is not properly handled
> > by its users.
> > 
> > Get and use the slow clock as it is necessary for the at91 reset
> > controller.
> 
> You call clk_prepare_enable during probe without a matching
> clk_disable_unprepare on module removal.
> 

They will never be compiled as modules as the Kconfig option is a bool
so we don't have a .remove and the module will never be removed.

Do you want me to change at91-reset and at91-poweroff to work as
modules?


-- 
Alexandre Belloni, Free Electrons
Embedded Linux, Kernel and Android engineering
http://free-electrons.com


From catalin.marinas at arm.com  Mon Aug 10 09:06:36 2015
From: catalin.marinas at arm.com (Catalin Marinas)
Date: Mon, 10 Aug 2015 17:06:36 +0100
Subject: [RFC PATCH 01/10] arm64: feature registers: Documentation
In-Reply-To: <1437731037-25795-2-git-send-email-suzuki.poulose@arm.com>
References: <1437731037-25795-1-git-send-email-suzuki.poulose@arm.com>
 <1437731037-25795-2-git-send-email-suzuki.poulose@arm.com>
Message-ID: <20150810160636.GB15394@e104818-lin.cambridge.arm.com>

Hi Suzuki,

On Fri, Jul 24, 2015 at 10:43:47AM +0100, Suzuki K. Poulose wrote:
> From: "Suzuki K. Poulose" <suzuki.poulose at arm.com>
> 
> Documentation of the infrastructure
> 
> Signed-off-by: Suzuki K. Poulose <suzuki.poulose at arm.com>

The implementation looks fine but I think the main discussion will be
around the goal of this feature and the ABI that it introduces. So I'll
just write my thoughts on this patch (I could as well have replied to
the cover letter).

Another question: who's going to use this feature? I know people asked
in private but I'd like to have some public statements.

> --- /dev/null
> +++ b/Documentation/arm64/cpu-feature-registers.txt
> @@ -0,0 +1,185 @@
> +		ARM64 CPU Feature Registers
> +		===========================
> +
> +Author: Suzuki K. Poulose <suzuki.poulose at arm.com>
> +
> +
> +This file describes the API for exporting the AArch64 CPU ID/feature registers
> +to userspace.
> +
> +1. Motivation
> +---------------
> +
> +The ARM architecture defines a set of feature registers, which describe
> +the capabilities of the CPU/system. Access to these system registers is
> +restricted from EL0 and there is no reliable way for an application to
> +extract this information to make better decisions at runtime. There is
> +limited information available to the application via ELF_HWCAPs, however
> +there are some issues with their usage.
> +
> + a) Any change to the HWCAPs requires an update to userspace (e.g libc)
> +    to detect the new changes, which can take a long time to appear in
> +    distributions. Exposing the registers allows applications to get the
> +    information without requiring other userspace components to be updated.

How does it help if you have a new CPUID field or even a new value in an
existing field? Doesn't userspace need to be changed anyway to make use
of the new feature? I don't think that's a valid argument.

> + b) Access to HWCAPs is sometimes restricted (e.g prior to libc, or when ld is
> +    initialised at startup time).

That's useful indeed.

> + c) HWCAPs cannot represent non-boolean information effectively. The
> +    architecture defines a canonical format for representing features
> +    in the ID registers; this is well defined and is capable of
> +    representing all valid architecture variations. Exposing the ID
> +    registers avoids having to come up with HWCAP representations
> +    and parsing code.

So far we've managed to cope with the boolean state of HWCAP, at least
for information relevant to user space. One thing it doesn't cover is
MIDR_EL1.

But the question here is whether we continue to add HWCAP bits even when
we exposed the CPUID registers to user. IMO, we should continue to add
the HWCAP bits matching new CPUID features for a few reasons:

1. It's the current interface that we have and the bits can be checked
   in standard C code without having to issue arm64-specific instructions

2. We still need features listed in /proc/cpuinfo, at least for humans
   reading this file or scripts that can't issue mrs instructions

And to debunk some of the counter arguments:

a) Running out of HWCAP bits - I really doubt this, we can always
   introduce 64 more via a new elf_hwcapX

b) Non-boolean information - The CPUID scheme (not MIDR) is pretty much
   boolean, each increment of the field adding a new feature or
   extending an existing one. We could do the same with HWCAP bits (e.g.
   HWCAP_FEATUREv4)

> +2. Requirements
> +-----------------
> +
> + a) Safety :
> +    Applications should be able to use the information provided by the
> +    infrastructure to run optimally safely across the system. This has
> +    greater implications on a system with heterogeneous CPUs. The
> +    infrastructure exports a value that is safe across all the available
> +    CPU on the system.
> +
> +    e.g, If at least one CPU doesn't implement CRC32 instructions, while others
> +    do, we should report that the CRC32 is not implemented. Otherwise an
> +    application could crash when scheduled on the CPU which doesn't support
> +    CRC32.

Agreed.

> + b) Security :
> +    Applications should only be able to receive information that is relevant
> +    to the normal operation in userspace. Hence, some of the fields
> +    are masked out and the values of the fields are set to indicate the
> +    feature is 'not supported' (See the 'visible' field in the
> +    table in Section 4). Also, the kernel may manipulate the fields based on what
> +    it supports. e.g, If FP is not supported by the kernel, the values
> +    could indicate that the FP is not available (even when the CPU provides
> +    it).

That's fine as well.

What we don't cover is what to do with emulated features. Luckily, we
don't have any for AArch64 currently. If we ever need to do this, do we
fake the CPUID to pretend we have the feature or we don't expose it at
all. I would vote for the latter but that's probably too vague to make
any decision now.

> + c) Implementation Defined Features
> +    The infrastructure doesn't expose any register which is
> +    IMPLEMENTATION DEFINED as per ARMv8-A Architecture and is set to 0.

It may be worth adding somewhere the (unwritten; yet) rules of the CPUID
fields: original 4-bit signed field is RAZ. When a feature is added or
extended, the field is incremented. If an existing feature is removed
for which the CPUID field is 0, the field becomes negative (0xf).

> + d) CPU Identification :
> +    MIDR_EL1 is exposed to help identify the processor. On a heterogeneous
> +    system, this could be racy (just like getcpu()). The process could be
> +    migrated to another CPU by the time we use the register value. Hence,

s/we use/it uses/

> +    there is no guarantee that the value reflects the processor that it is
> +    currently executing on.

You could extend this a bit, something like "unless the CPU affinity is
set".

Anyway, for this reason, we decided not to expose REVIDR since it can
only be read in conjunction with MIDR.

> +The list of supported registers and the attributes of individual
> +feature bits are listed in section 4. Unless there is absolute necessity,
> +we don't encourage the addition of new feature registers to the list.
> +In any case, it should comply to the requirements listed above.
> +
> +3. Implementation
> +--------------------
> +
> +The infrastructure is built on the emulation of the 'MRS' instruction.
> +Accessing a restricted system register from an application generates an
> +exception and ends up in SIGILL being delivered to the process.
> +The infrastructure hooks into the exception handler and emulates the
> +operation if the source belongs to the supported system register space.
> +
> +The infrastructure emulates only the following system register space:
> +	Op0=3, Op1=0, CRn=0
> +
> +(See Table C5-6 'System instruction encodings for System register accesses'
> + in ARMv8 ARM, for the list of registers).
> +
> +
> +The following rules are applied to the value returned by the infrastructure:
> +
> + a) The value of an 'IMPLEMENTATION DEFINED' field is set to 0.
> + b) The value of a reserved field is set to the reserved value(as
> +    defined by the architecture).

Do we expose any IMPLEMENTATION DEFINED or reserved field to user?

> + c) The value of a field marked as not 'visible', is set to indicate
> +    the feature is missing (as defined by the architecture).
> + d) The value of a 'visible' field holds the system wide safe value
> +    for the particular feature(except for MIDR_EL1, see section 4)

I'm slightly confused by the visible/not-visible definition. GIC for
example may be present but we don't want to expose it to user, hence you
marked it as "not visible" in the table. But the feature is definitely
not missing, it may be present and we just decided not to expose it to
EL0 since it is not relevant.

-- 
Catalin


From bhelgaas at google.com  Mon Aug 10 09:18:23 2015
From: bhelgaas at google.com (Bjorn Helgaas)
Date: Mon, 10 Aug 2015 11:18:23 -0500
Subject: X-Gene: Unhandled fault: synchronous external abort in
 pci_generic_config_read32
In-Reply-To: <CADaLNDk=+J_yOer1ferSCNb_xAC42ULtP2FyCLmYMwa+Gj=vfA@mail.gmail.com>
References: <20150724224258.GA23990@google.com>
 <CADaLNDmYZ=8XQt82W_H74QaOiX3UwkVxkE1_EWRgzhkG1boebw@mail.gmail.com>
 <CAErSpo549xfAnx62quCqGHh3DNay5Lfb6EhEG+4EXooEuueQFQ@mail.gmail.com>
 <CADaLNDn95H=g73DKWRsrB4SuWcf+-8mkepbwb_DC-sFsVkrk6g@mail.gmail.com>
 <20150728212944.GA12958@google.com>
 <CADaLNDkOLiyPmVC3VwpnbrfAKFmNwSVJKdChjQFdQqs7XP-Ddg@mail.gmail.com>
 <20150729012255.GA18606@google.com> <20150729155509.GA31170@google.com>
 <CADaLNDk=+J_yOer1ferSCNb_xAC42ULtP2FyCLmYMwa+Gj=vfA@mail.gmail.com>
Message-ID: <CAErSpo4VFh7rv81sCAG-eCXVyZh4ub8Trh-ntZhyfy7BzqTr5g@mail.gmail.com>

On Fri, Jul 31, 2015 at 12:00 PM, Duc Dang <dhdang at apm.com> wrote:
> On Wed, Jul 29, 2015 at 8:55 AM, Bjorn Helgaas <bhelgaas at google.com> wrote:
>> On Tue, Jul 28, 2015 at 08:22:55PM -0500, Bjorn Helgaas wrote:
>>> On Tue, Jul 28, 2015 at 02:50:39PM -0700, Duc Dang wrote:
>>
>>> > Do you have another PCIe card to try on the same reboot test on this board?
>>>
>>> I've seen this on at least two Mellanox cards.  I'm running similar tests
>>> on a different type of card now.
>>
>> FWIW, reboot tests on two machines with Mellanox cards failed, while the
>> same test on a machine with a different proprietary card succeeded.
>
> Thanks, Bjorn.
>
> I don't have the same Mellanox card as yours, but I will also run
> similar reboot test to see if I hit the same issue with my card.

Any more hints on this?  Nothing has changed on my end, so of course
I'm still seeing this, always on machines with Mellanox, and never on
other machines.  Could this be a hardware issue like a signal
integrity or margin issue?  I don't know where to go from here because
I'm not a hardware person, and I don't know anything to do in
software.

Bjorn


From ykk at rock-chips.com  Mon Aug 10 09:26:21 2015
From: ykk at rock-chips.com (Yakir Yang)
Date: Tue, 11 Aug 2015 00:26:21 +0800
Subject: [PATCH 9/9] drm: bridge/dw_hdmi-i2s-audio: add audio driver
In-Reply-To: <20150810154848.GV7557@n2100.arm.linux.org.uk>
References: <20150808160936.GN7557@n2100.arm.linux.org.uk>
 <E1ZO6hr-0003No-RB@rmk-PC.arm.linux.org.uk>
 <20150810154848.GV7557@n2100.arm.linux.org.uk>
Message-ID: <55C8D0AD.3040001@rock-chips.com>

Hi Russell,

? 2015/8/10 23:48, Russell King - ARM Linux ??:
> On Sat, Aug 08, 2015 at 05:10:47PM +0100, Russell King wrote:
>> From: Yakir Yang <ykk at rock-chips.com>
>>
>> Add ALSA based HDMI I2S audio driver for dw_hdmi. Sound card
>> driver could connect to this codec through the codec dai name
>> "dw-hdmi-i2s-audio".
>>
>> [Fixed IRQ name, MODULE_DESCRIPTION, MODULE_ALIAS in
>>   dw-hdmi-i2s-audio.c, and platform device name in dw-hdmi.c --rmk]
>>
>> Signed-off-by: Yakir Yang <ykk at rock-chips.com>
>> Signed-off-by: Russell King <rmk+kernel at arm.linux.org.uk>
> I'm dropping this patch after all as it no longer builds against modern
> kernels due to the reference to the removed snd_soc_jack_new().  Its
> replacement is at card level, and I don't think it's a simple case of
> replacing it here.

Hmm... I would rather to fix it in my side, and then I could rebase on 
your series, is it okay ?

- Yakir

>> +static int snd_dw_hdmi_audio_probe(struct snd_soc_codec *codec)
>> +{
>> +	struct snd_dw_hdmi *dw = snd_soc_codec_get_drvdata(codec);
>> +	int ret;
>> +
>> +	ret = snd_soc_jack_new(codec, "dw Jack", SND_JACK_LINEOUT,
>> +			       &dw->jack);
> ...
>> +static const struct snd_soc_codec_driver dw_hdmi_audio = {
>> +	.probe = snd_dw_hdmi_audio_probe,
>> +	.dapm_widgets = snd_dw_hdmi_audio_widgets,
>> +	.num_dapm_widgets = ARRAY_SIZE(snd_dw_hdmi_audio_widgets),
>> +	.dapm_routes = snd_dw_hdmi_audio_routes,
>> +	.num_dapm_routes = ARRAY_SIZE(snd_dw_hdmi_audio_routes),
>> +};
>> +
>> +static int dw_hdmi_audio_probe(struct platform_device *pdev)
>> +{
>> +	struct dw_hdmi_audio_data *data = pdev->dev.platform_data;
>> +	struct snd_dw_hdmi *dw;
>> +	int ret;
>> +
>> +	dw = devm_kzalloc(&pdev->dev, sizeof(*dw), GFP_KERNEL);
>> +	if (!dw)
>> +		return -ENOMEM;
>> +
>> +	dw->data = *data;
>> +	dw->dev = &pdev->dev;
>> +	dw->is_jack_ready = false;
>> +	platform_set_drvdata(pdev, dw);
>> +
>> +	ret = request_irq(dw->data.irq, snd_dw_hdmi_irq, IRQF_SHARED,
>> +			  DRIVER_NAME, dw);
>> +	if (ret) {
>> +		dev_err(&pdev->dev, "request irq failed (%d)\n", ret);
>> +		return -EINVAL;
>> +	}
>> +
>> +	ret = snd_soc_register_codec(&pdev->dev, &dw_hdmi_audio,
>> +				     &dw_hdmi_audio_dai, 1);




From dann.frazier at canonical.com  Mon Aug 10 09:37:13 2015
From: dann.frazier at canonical.com (Dann Frazier)
Date: Mon, 10 Aug 2015 10:37:13 -0600
Subject: [PATCH v2 0/3] edac: Add L3/SoC support to the APM X-Gene SoC
 EDAC driver
In-Reply-To: <1437808063-17592-1-git-send-email-lho@apm.com>
References: <1437808063-17592-1-git-send-email-lho@apm.com>
Message-ID: <CALdTtnv7P5d0Y6wyKe1SOqXedNhQxMsFZY=m-rxK3zouLcFv-Q@mail.gmail.com>

On Sat, Jul 25, 2015 at 1:07 AM, Loc Ho <lho at apm.com> wrote:
> v2:
> * Update binding documentation accordingly
> * Change all single bit defines to BIT(x)
> * Add support for L3 version 1 and 2 HW's
> * Change to use debug file system for error injection
> * In L3/SoC instance add function, allocate EDAC context after all
>   initalization successed
> * Support raw or detail info for SoC EDAC error reporting
>
> v1:
> * Add L3/SoC support to the APM X-Gene SoC EDAC driver

Loc,
  I tested 4.2-rc5 on a Mustang board with one DIMM, and it hangs (RCU
stall) in xgene_edac_mc_irq_ctl() on modprobe. Same board with 2 DIMMs
boots fine. (U-boot 1.15.12).

 -dann


From linux at arm.linux.org.uk  Mon Aug 10 09:49:41 2015
From: linux at arm.linux.org.uk (Russell King - ARM Linux)
Date: Mon, 10 Aug 2015 17:49:41 +0100
Subject: [PATCH 1/9] drm: bridge/dw_hdmi-ahb-audio: add audio driver
In-Reply-To: <s5hegjb5o44.wl-tiwai@suse.de>
References: <20150808160936.GN7557@n2100.arm.linux.org.uk>
 <E1ZO6hC-0003M5-EU@rmk-PC.arm.linux.org.uk>
 <s5hk2t35ui4.wl-tiwai@suse.de>
 <20150810103921.GR7557@n2100.arm.linux.org.uk>
 <s5hegjb5o44.wl-tiwai@suse.de>
Message-ID: <20150810164941.GW7557@n2100.arm.linux.org.uk>

On Mon, Aug 10, 2015 at 02:23:07PM +0200, Takashi Iwai wrote:
> I admit that alsa-lib code is very horrible to follow -- but I guess
> the change you'd need for iec958 plugin would be fairly small.  We can
> add a config option and let iec958 behaving slightly differently
> depending on it.

Yes, but there's other problems there as well.

The IEC958 plugin does the job of adding the 4 AES bytes and formatting
fairly well, but the problem when the 'default' bytes specified in the
ALSA configuration files are used.

Let's take the old chestnut of PulseAudio, or even aplay, or the miriad
of other audio-only players out there.

Most of them do not supply the AES bytes to be used, so we end up with
the default.

The default is... 0x04 0x82 0x00 0x02, which specifies a sample rate
of 48kHz.  However, the actual sample rate may not be 48kHz.  At least
the HDMI specifications say that the channel status data must be correct,
and there are AV receivers out there which do make use of this, and if
the channel status does not agree with the actual sample rate, they
either refuse to recognise the audio stream (saying there's nothing
there) or they intermittently mute the audio.  Yamaha RX-V677 is one
example which has this behaviour.

The only compliant program that I've found so far is VLC in SPDIF
pass-through mode, which is the only case where VLC passes the
channel status information.  Everything else seems broken in this
regard, by falling back to the default.

Obviously, aplay can be made to work by setting the AES bytes
manually when specifying the device for it to use, but this is not
really user-friendly or programmer friendly - especially as the
current use model expects things to "just work" (the common case
being PCM output on a PC which doesn't care about channel status.)

I'm not sure what the right solution is here: modifying every audio
player out there to make HDMI work sanely is crazy.  Having alsalib
automatically generate the correct AES channel status bytes for
linear audio formats seems to be sensible, but difficult given its
present structure with the defaults - the iec958 plugin has no idea
if the defaults are being used or not.

The advantage of having the horrid conversion in the kernel is that
we can choose to generate proper AES channel status data without
regard to userspace for standard linear PCM, and when the iec958 plugin
is being used with proper channel status (eg, in compressed audio
pass-through mode by VLC) then that works too.

-- 
FTTC broadband for 0.8mile line: currently at 10.5Mbps down 400kbps up
according to speedtest.net.


From santosh.shilimkar at oracle.com  Mon Aug 10 09:55:09 2015
From: santosh.shilimkar at oracle.com (santosh.shilimkar at oracle.com)
Date: Mon, 10 Aug 2015 09:55:09 -0700
Subject: [PATCH 42/74] clockevents/drivers/keystone: Migrate to new
 'set-state' interface
In-Reply-To: <1439200352-26767-42-git-send-email-daniel.lezcano@linaro.org>
References: <55C87382.4070309@linaro.org>
 <1439200352-26767-1-git-send-email-daniel.lezcano@linaro.org>
 <1439200352-26767-42-git-send-email-daniel.lezcano@linaro.org>
Message-ID: <55C8D76D.9020503@oracle.com>

On 8/10/15 2:51 AM, Daniel Lezcano wrote:
> From: Viresh Kumar <viresh.kumar at linaro.org>
>
> Migrate keystone driver to the new 'set-state' interface provided by
> clockevents core, the earlier 'set-mode' interface is marked obsolete
> now.
>
> This also enables us to implement callbacks for new states of clockevent
> devices, for example: ONESHOT_STOPPED.
>
> Also pass the mode-mask to keystone_timer_config() instead of the mode
> as mode macro's aren't valid anymore.
>
> Cc: Santosh Shilimkar <ssantosh at kernel.org>
> Signed-off-by: Viresh Kumar <viresh.kumar at linaro.org>
> Signed-off-by: Daniel Lezcano <daniel.lezcano at linaro.org>
> ---
Acked-by: Santosh Shilimkar <ssantosh at kernel.org>


From timur at codeaurora.org  Mon Aug 10 10:05:31 2015
From: timur at codeaurora.org (Timur Tabi)
Date: Mon, 10 Aug 2015 12:05:31 -0500
Subject: [PATCH v3 15/31] arm64: SMP support
In-Reply-To: <55C8843D.8050600@linaro.org>
References: <1347035226-18649-1-git-send-email-catalin.marinas@arm.com>
 <1347035226-18649-16-git-send-email-catalin.marinas@arm.com>
 <CAOZdJXVoDJM3y2mnKO+91yf2EHogKfMjumjhhi85REAfhcJM=Q@mail.gmail.com>
 <20150806095621.GB17691@e104818-lin.cambridge.arm.com>
 <55C8843D.8050600@linaro.org>
Message-ID: <55C8D9DB.5080207@codeaurora.org>

Hanjun Guo wrote:
>>
>> This code was inherited from arch/arm which initially was always dumping
>> the stack but it later gained the system_state check. Unless it's useful
>> to anyone for debugging purposes, I'm ok with removing it.
>
> Do you have patch for this one? My colleagues said that they met the
> same problem :)

Dropping the call to dump_stack() would probably be sufficient.

-- 
Sent by an employee of the Qualcomm Innovation Center, Inc.
The Qualcomm Innovation Center, Inc. is a member of the
Code Aurora Forum, hosted by The Linux Foundation.


From sre at kernel.org  Mon Aug 10 10:11:49 2015
From: sre at kernel.org (Sebastian Reichel)
Date: Mon, 10 Aug 2015 19:11:49 +0200
Subject: [PATCH 18/23] power/reset: at91-reset: get and use slow clock
In-Reply-To: <20150810155005.GH3411@piout.net>
References: <1438335599-3301-1-git-send-email-alexandre.belloni@free-electrons.com>
 <1438335599-3301-19-git-send-email-alexandre.belloni@free-electrons.com>
 <20150805182220.GC11315@earth> <20150810155005.GH3411@piout.net>
Message-ID: <20150810171148.GA21858@earth>

Hi,

On Mon, Aug 10, 2015 at 05:50:05PM +0200, Alexandre Belloni wrote:
> On 05/08/2015 at 20:22:20 +0200, Sebastian Reichel wrote :
> > On Fri, Jul 31, 2015 at 11:39:54AM +0200, Alexandre Belloni wrote:
> > > Commit dca1a4b5ff6e ("clk: at91: keep slow clk enabled to prevent system
> > > hang") added a workaround for the slow clock as it is not properly handled
> > > by its users.
> > > 
> > > Get and use the slow clock as it is necessary for the at91 reset
> > > controller.
> > 
> > You call clk_prepare_enable during probe without a matching
> > clk_disable_unprepare on module removal.
> 
> They will never be compiled as modules as the Kconfig option is a
> bool so we don't have a .remove and the module will never be removed.

In that case the module_platform_driver() statement at the bottom
should be replaced with builtin_platform_driver().

> Do you want me to change at91-reset and at91-poweroff to work as
> modules?

That would also be fine.

-- Sebastian
-------------- next part --------------
A non-text attachment was scrubbed...
Name: signature.asc
Type: application/pgp-signature
Size: 819 bytes
Desc: Digital signature
URL: <http://lists.infradead.org/pipermail/linux-arm-kernel/attachments/20150810/0d904b01/attachment.sig>

From Suzuki.Poulose at arm.com  Mon Aug 10 10:36:46 2015
From: Suzuki.Poulose at arm.com (Suzuki K. Poulose)
Date: Mon, 10 Aug 2015 18:36:46 +0100
Subject: [RFC PATCH 01/10] arm64: feature registers: Documentation
In-Reply-To: <20150810160636.GB15394@e104818-lin.cambridge.arm.com>
References: <1437731037-25795-1-git-send-email-suzuki.poulose@arm.com>
 <1437731037-25795-2-git-send-email-suzuki.poulose@arm.com>
 <20150810160636.GB15394@e104818-lin.cambridge.arm.com>
Message-ID: <55C8E12E.6030305@arm.com>

On 10/08/15 17:06, Catalin Marinas wrote:
> Hi Suzuki,
>
> On Fri, Jul 24, 2015 at 10:43:47AM +0100, Suzuki K. Poulose wrote:
>> From: "Suzuki K. Poulose" <suzuki.poulose at arm.com>
>>
>> Documentation of the infrastructure
>>
>> Signed-off-by: Suzuki K. Poulose <suzuki.poulose at arm.com>
>
> The implementation looks fine but I think the main discussion will be
> around the goal of this feature and the ABI that it introduces. So I'll
> just write my thoughts on this patch (I could as well have replied to
> the cover letter).
>
> Another question: who's going to use this feature? I know people asked
> in private but I'd like to have some public statements.

Right, I am hoping that folks from glibc / JIT / GCC will respond to
this thread.

>
...

>> + a) Any change to the HWCAPs requires an update to userspace (e.g libc)
>> +    to detect the new changes, which can take a long time to appear in
>> +    distributions. Exposing the registers allows applications to get the
>> +    information without requiring other userspace components to be updated.
>
> How does it help if you have a new CPUID field or even a new value in an
> existing field? Doesn't userspace need to be changed anyway to make use
> of the new feature? I don't think that's a valid argument.
>

Yes, the userspace would need an update to work with the new CPUID field. I understand.
It is just that, "in the enterprise world" updates to the system libraries provided by
the distribution might take a bit longer to provide the changes than a software vendor.
I agree thats not a common case.


>> + b) Access to HWCAPs is sometimes restricted (e.g prior to libc, or when ld is
>> +    initialised at startup time).
>
> That's useful indeed.

OK

>
>> + c) HWCAPs cannot represent non-boolean information effectively. The
>> +    architecture defines a canonical format for representing features
>> +    in the ID registers; this is well defined and is capable of
>> +    representing all valid architecture variations. Exposing the ID
>> +    registers avoids having to come up with HWCAP representations
>> +    and parsing code.
>
> So far we've managed to cope with the boolean state of HWCAP, at least
> for information relevant to user space. One thing it doesn't cover is
> MIDR_EL1.
>
> But the question here is whether we continue to add HWCAP bits even when
> we exposed the CPUID registers to user. IMO, we should continue to add
> the HWCAP bits matching new CPUID features for a few reasons:

I don't have a strong opinion against it.

>
> 1. It's the current interface that we have and the bits can be checked
>     in standard C code without having to issue arm64-specific instructions
>

I agree. May be we could provide library interface for this in the future ?

> 2. We still need features listed in /proc/cpuinfo, at least for humans
>     reading this file or scripts that can't issue mrs instructions
>

Agreed, we still need to provide the features in /proc/cpuinfo. We could do
this without HWCAP if we decide not to update the list.

> And to debunk some of the counter arguments:
>
> a) Running out of HWCAP bits - I really doubt this, we can always
>     introduce 64 more via a new elf_hwcapX

OK :)

>
> b) Non-boolean information - The CPUID scheme (not MIDR) is pretty much
>     boolean, each increment of the field adding a new feature or
>     extending an existing one. We could do the same with HWCAP bits (e.g.
>     HWCAP_FEATUREv4)

OK

>> + b) Security :
>> +    Applications should only be able to receive information that is relevant
>> +    to the normal operation in userspace. Hence, some of the fields
>> +    are masked out and the values of the fields are set to indicate the
>> +    feature is 'not supported' (See the 'visible' field in the
>> +    table in Section 4). Also, the kernel may manipulate the fields based on what
>> +    it supports. e.g, If FP is not supported by the kernel, the values
>> +    could indicate that the FP is not available (even when the CPU provides
>> +    it).
>
> That's fine as well.
>
> What we don't cover is what to do with emulated features. Luckily, we
> don't have any for AArch64 currently. If we ever need to do this, do we
> fake the CPUID to pretend we have the feature or we don't expose it at
> all. I would vote for the latter but that's probably too vague to make
> any decision now.

Right. We could pretend to have a feature which the userspace can safely
operate, given kernel/hardware can handle it.

>
>> + c) Implementation Defined Features
>> +    The infrastructure doesn't expose any register which is
>> +    IMPLEMENTATION DEFINED as per ARMv8-A Architecture and is set to 0.
>
> It may be worth adding somewhere the (unwritten; yet) rules of the CPUID
> fields: original 4-bit signed field is RAZ. When a feature is added or
> extended, the field is incremented. If an existing feature is removed
> for which the CPUID field is 0, the field becomes negative (0xf).

May be I can add it as an 'Notes' section at the end ?

>
>> + d) CPU Identification :
>> +    MIDR_EL1 is exposed to help identify the processor. On a heterogeneous
>> +    system, this could be racy (just like getcpu()). The process could be
>> +    migrated to another CPU by the time we use the register value. Hence,
>
> s/we use/it uses/

Will fix it.
  

>> +    there is no guarantee that the value reflects the processor that it is
>> +    currently executing on.
>
> You could extend this a bit, something like "unless the CPU affinity is
> set".

Sure, makes sense.

>
> Anyway, for this reason, we decided not to expose REVIDR since it can
> only be read in conjunction with MIDR.

Right.

...
>> +3. Implementation
>> +--------------------
>> +
...
>> +The infrastructure emulates only the following system register space:
>> +	Op0=3, Op1=0, CRn=0
>> +
>> +(See Table C5-6 'System instruction encodings for System register accesses'
>> + in ARMv8 ARM, for the list of registers).
>> +
>> +
>> +The following rules are applied to the value returned by the infrastructure:
>> +
>> + a) The value of an 'IMPLEMENTATION DEFINED' field is set to 0.
>> + b) The value of a reserved field is set to the reserved value(as
>> +    defined by the architecture).
>
> Do we expose any IMPLEMENTATION DEFINED or reserved field to user?

We don't. All such fields are marked invisible. The above rules define
how we fill those 'special' (invisible) fields. We 'emulate' all
access to the space (as defined above) with Op0=3, Op1=0 & CRn=0.
Out of this space, there are only a very few 'visible' fields(listed in
section 4). These rules, define how the values are emulated.

>
>> + c) The value of a field marked as not 'visible', is set to indicate
>> +    the feature is missing (as defined by the architecture).
>> + d) The value of a 'visible' field holds the system wide safe value
>> +    for the particular feature(except for MIDR_EL1, see section 4)
>
> I'm slightly confused by the visible/not-visible definition. GIC for
> example may be present but we don't want to expose it to user, hence you
> marked it as "not visible" in the table. But the feature is definitely
> not missing, it may be present and we just decided not to expose it to
> EL0 since it is not relevant.

Thats right. In this case, the userspace will see that 'GIC' is not present
even though it is available. Btw, the system wide value(exposed to the system
wide users) could be different from what the user gets. e.g, if all the CPUs
have GIC system register access, the system view will have 'GIC' available.

Taking another example to explain rule (d), if all CPUs but one supports CRC32
instructions, both the system view and the user view will have CRC32 disabled.


Thanks
Suzuki






From catalin.marinas at arm.com  Mon Aug 10 10:38:09 2015
From: catalin.marinas at arm.com (Catalin Marinas)
Date: Mon, 10 Aug 2015 18:38:09 +0100
Subject: X-Gene: Unhandled fault: synchronous external abort in
 pci_generic_config_read32
In-Reply-To: <CAErSpo4VFh7rv81sCAG-eCXVyZh4ub8Trh-ntZhyfy7BzqTr5g@mail.gmail.com>
References: <20150724224258.GA23990@google.com>
 <CADaLNDmYZ=8XQt82W_H74QaOiX3UwkVxkE1_EWRgzhkG1boebw@mail.gmail.com>
 <CAErSpo549xfAnx62quCqGHh3DNay5Lfb6EhEG+4EXooEuueQFQ@mail.gmail.com>
 <CADaLNDn95H=g73DKWRsrB4SuWcf+-8mkepbwb_DC-sFsVkrk6g@mail.gmail.com>
 <20150728212944.GA12958@google.com>
 <CADaLNDkOLiyPmVC3VwpnbrfAKFmNwSVJKdChjQFdQqs7XP-Ddg@mail.gmail.com>
 <20150729012255.GA18606@google.com>
 <20150729155509.GA31170@google.com>
 <CADaLNDk=+J_yOer1ferSCNb_xAC42ULtP2FyCLmYMwa+Gj=vfA@mail.gmail.com>
 <CAErSpo4VFh7rv81sCAG-eCXVyZh4ub8Trh-ntZhyfy7BzqTr5g@mail.gmail.com>
Message-ID: <20150810173809.GE15394@e104818-lin.cambridge.arm.com>

On Mon, Aug 10, 2015 at 11:18:23AM -0500, Bjorn Helgaas wrote:
> On Fri, Jul 31, 2015 at 12:00 PM, Duc Dang <dhdang at apm.com> wrote:
> > On Wed, Jul 29, 2015 at 8:55 AM, Bjorn Helgaas <bhelgaas at google.com> wrote:
> >> On Tue, Jul 28, 2015 at 08:22:55PM -0500, Bjorn Helgaas wrote:
> >>> On Tue, Jul 28, 2015 at 02:50:39PM -0700, Duc Dang wrote:
> >>
> >>> > Do you have another PCIe card to try on the same reboot test on this board?
> >>>
> >>> I've seen this on at least two Mellanox cards.  I'm running similar tests
> >>> on a different type of card now.
> >>
> >> FWIW, reboot tests on two machines with Mellanox cards failed, while the
> >> same test on a machine with a different proprietary card succeeded.
> >
> > Thanks, Bjorn.
> >
> > I don't have the same Mellanox card as yours, but I will also run
> > similar reboot test to see if I hit the same issue with my card.
> 
> Any more hints on this?  Nothing has changed on my end, so of course
> I'm still seeing this, always on machines with Mellanox, and never on
> other machines.  Could this be a hardware issue like a signal
> integrity or margin issue?  I don't know where to go from here because
> I'm not a hardware person, and I don't know anything to do in
> software.

Silly hack below, not actually a solution (and it may not even work):

diff --git a/arch/arm64/mm/fault.c b/arch/arm64/mm/fault.c
index 94d98cd1aad8..e895e96b3d13 100644
--- a/arch/arm64/mm/fault.c
+++ b/arch/arm64/mm/fault.c
@@ -369,6 +369,14 @@ static int do_bad(unsigned long addr, unsigned int esr, struct pt_regs *regs)
 	return 1;
 }
 
+/*
+ * Retry the faulty access.
+ */
+static int do_good(unsigned long addr, unsigned int esr, struct pt_regs *regs)
+{
+	return 0;
+}
+
 static struct fault_info {
 	int	(*fn)(unsigned long addr, unsigned int esr, struct pt_regs *regs);
 	int	sig;
@@ -391,7 +399,7 @@ static struct fault_info {
 	{ do_page_fault,	SIGSEGV, SEGV_ACCERR,	"level 1 permission fault"	},
 	{ do_page_fault,	SIGSEGV, SEGV_ACCERR,	"level 2 permission fault"	},
 	{ do_page_fault,	SIGSEGV, SEGV_ACCERR,	"level 3 permission fault"	},
-	{ do_bad,		SIGBUS,  0,		"synchronous external abort"	},
+	{ do_good,		SIGBUS,  0,		"synchronous external abort"	},
 	{ do_bad,		SIGBUS,  0,		"asynchronous external abort"	},
 	{ do_bad,		SIGBUS,  0,		"unknown 18"			},
 	{ do_bad,		SIGBUS,  0,		"unknown 19"			},

-- 
Catalin


From bhelgaas at google.com  Mon Aug 10 10:42:19 2015
From: bhelgaas at google.com (Bjorn Helgaas)
Date: Mon, 10 Aug 2015 12:42:19 -0500
Subject: X-Gene: Unhandled fault: synchronous external abort in
 pci_generic_config_read32
In-Reply-To: <CADaLNDkUQHzGACfFmYDeJWnaNrKmJUDx4Rby60OWr4FzOjx3rA@mail.gmail.com>
References: <20150724224258.GA23990@google.com>
 <CADaLNDmYZ=8XQt82W_H74QaOiX3UwkVxkE1_EWRgzhkG1boebw@mail.gmail.com>
 <CAErSpo549xfAnx62quCqGHh3DNay5Lfb6EhEG+4EXooEuueQFQ@mail.gmail.com>
 <CADaLNDn95H=g73DKWRsrB4SuWcf+-8mkepbwb_DC-sFsVkrk6g@mail.gmail.com>
 <20150728212944.GA12958@google.com>
 <CADaLNDkOLiyPmVC3VwpnbrfAKFmNwSVJKdChjQFdQqs7XP-Ddg@mail.gmail.com>
 <20150729012255.GA18606@google.com> <20150729155509.GA31170@google.com>
 <CADaLNDk=+J_yOer1ferSCNb_xAC42ULtP2FyCLmYMwa+Gj=vfA@mail.gmail.com>
 <CAErSpo4VFh7rv81sCAG-eCXVyZh4ub8Trh-ntZhyfy7BzqTr5g@mail.gmail.com>
 <CADaLNDkUQHzGACfFmYDeJWnaNrKmJUDx4Rby60OWr4FzOjx3rA@mail.gmail.com>
Message-ID: <CAErSpo7aDYKwy4MC6ZPf7hNd4MPE-LARiOVKutFfDFFkHY7qjQ@mail.gmail.com>

On Mon, Aug 10, 2015 at 12:16 PM, Duc Dang <dhdang at apm.com> wrote:
> On Monday, August 10, 2015, Bjorn Helgaas <bhelgaas at google.com> wrote:
>>
>> On Fri, Jul 31, 2015 at 12:00 PM, Duc Dang <dhdang at apm.com> wrote:
>> > On Wed, Jul 29, 2015 at 8:55 AM, Bjorn Helgaas <bhelgaas at google.com>
>> > wrote:
>> >> On Tue, Jul 28, 2015 at 08:22:55PM -0500, Bjorn Helgaas wrote:
>> >>> On Tue, Jul 28, 2015 at 02:50:39PM -0700, Duc Dang wrote:
>> >>
>> >>> > Do you have another PCIe card to try on the same reboot test on this
>> >>> > board?
>> >>>
>> >>> I've seen this on at least two Mellanox cards.  I'm running similar
>> >>> tests
>> >>> on a different type of card now.
>> >>
>> >> FWIW, reboot tests on two machines with Mellanox cards failed, while
>> >> the
>> >> same test on a machine with a different proprietary card succeeded.
>> >
>> > Thanks, Bjorn.
>> >
>> > I don't have the same Mellanox card as yours, but I will also run
>> > similar reboot test to see if I hit the same issue with my card.
>>
>> Any more hints on this?  Nothing has changed on my end, so of course
>> I'm still seeing this, always on machines with Mellanox, and never on
>> other machines.  Could this be a hardware issue like a signal
>> integrity or margin issue?  I don't know where to go from here because
>> I'm not a hardware person, and I don't know anything to do in
>> software.
>
>
> Hi Bjorn,
>
> I tried to run similar reboot tests on 2 different Mellanox cards (Connect-X
> family, one card has 2 10G interfaces, the other one has 1 port that
> supports InfiniBand) with U-Boot 1.15.12 and linux 4.2-rc5 and I did not see
> the crash that you encounterred.
>
> Did you check if your Mellanox cards have latest firmware? I did see some
> link issues on my Mellanox cards with its old firmware before.

Good idea; I'll check that, too.  Also, I just learned that these
cards on installed with an extender card because of some space issues,
so we're going to test again without the extender.


From romain.perier at gmail.com  Mon Aug 10 10:44:45 2015
From: romain.perier at gmail.com (Romain Perier)
Date: Mon, 10 Aug 2015 19:44:45 +0200
Subject: [PATCH] soc/rockchip: add handler for usb-uart functionality
In-Reply-To: <1574322.mYky5df1dK@diego>
References: <1574322.mYky5df1dK@diego>
Message-ID: <CABgxDoKVk=gdPET5E7y+JPwe5S2RsWQMDC6xWBBw=waeG+vNhg@mail.gmail.com>

2015-07-08 21:00 GMT+02:00 Heiko St?bner <heiko at sntech.de>:
> Most newer Rockchip SoCs provide the possibility to use a usb-phy
> as passthrough for the debug uart (uart2), making it possible to
> get console output without needing to open the device.
>
> This patch adds an early_initcall to enable this functionality
> conditionally via the commandline and also disables the corresponding
> usb controller in the devicetree.
>
> Currently only data for the rk3288 is provided, but at least the
> rk3188 and arm64 rk3368 also provide this functionality and will be
> enabled later.
>
> On a spliced usb cable the signals are tx on white wire(D+) and
> rx on green wire(D-).
>
> Signed-off-by: Heiko Stuebner <heiko at sntech.de>
> ---
> changes from the version in chromium-review:
> - enable siddq (probably saves a little power to power down plls)
> - cosmetics to make checkpatch happy
>
> Yunzhi Li already gave a Code-Review+1 in the chromium gerrit
> but I'd guess a public Reviewed-by would be better ;-)
>
>
>  Documentation/kernel-parameters.txt      |   6 +
>  drivers/soc/Kconfig                      |   1 +
>  drivers/soc/Makefile                     |   1 +
>  drivers/soc/rockchip/Kconfig             |  13 ++
>  drivers/soc/rockchip/Makefile            |   1 +
>  drivers/soc/rockchip/rockchip_usb_uart.c | 226 +++++++++++++++++++++++++++++++
>  6 files changed, 248 insertions(+)
>  create mode 100644 drivers/soc/rockchip/Kconfig
>  create mode 100644 drivers/soc/rockchip/Makefile
>  create mode 100644 drivers/soc/rockchip/rockchip_usb_uart.c
>
> diff --git a/Documentation/kernel-parameters.txt b/Documentation/kernel-parameters.txt
> index 1d6f045..156911b 100644
> --- a/Documentation/kernel-parameters.txt
> +++ b/Documentation/kernel-parameters.txt
> @@ -3339,6 +3339,12 @@ bytes respectively. Such letter suffixes can also be entirely omitted.
>
>         ro              [KNL] Mount root device read-only on boot
>
> +       rockchip.usb_uart
> +                       Enable the uart passthrough on the designated usb port
> +                       on Rockchip SoCs. When active, the signals of the
> +                       debug-uart get routed to the D+ and D- pins of the usb
> +                       port and the regular usb controller gets disabled.
> +
>         root=           [KNL] Root filesystem
>                         See name_to_dev_t comment in init/do_mounts.c.
>
> diff --git a/drivers/soc/Kconfig b/drivers/soc/Kconfig
> index 96ddecb..ecb1a6c 100644
> --- a/drivers/soc/Kconfig
> +++ b/drivers/soc/Kconfig
> @@ -2,6 +2,7 @@ menu "SOC (System On Chip) specific Drivers"
>
>  source "drivers/soc/mediatek/Kconfig"
>  source "drivers/soc/qcom/Kconfig"
> +source "drivers/soc/rockchip/Kconfig"
>  source "drivers/soc/sunxi/Kconfig"
>  source "drivers/soc/ti/Kconfig"
>  source "drivers/soc/versatile/Kconfig"
> diff --git a/drivers/soc/Makefile b/drivers/soc/Makefile
> index 7dc7c0d..6c0b677 100644
> --- a/drivers/soc/Makefile
> +++ b/drivers/soc/Makefile
> @@ -4,6 +4,7 @@
>
>  obj-$(CONFIG_ARCH_MEDIATEK)    += mediatek/
>  obj-$(CONFIG_ARCH_QCOM)                += qcom/
> +obj-$(CONFIG_ARCH_ROCKCHIP)    += rockchip/
>  obj-$(CONFIG_ARCH_SUNXI)       += sunxi/
>  obj-$(CONFIG_ARCH_TEGRA)       += tegra/
>  obj-$(CONFIG_SOC_TI)           += ti/
> diff --git a/drivers/soc/rockchip/Kconfig b/drivers/soc/rockchip/Kconfig
> new file mode 100644
> index 0000000..24d4e05
> --- /dev/null
> +++ b/drivers/soc/rockchip/Kconfig
> @@ -0,0 +1,13 @@
> +#
> +# Rockchip Soc drivers
> +#
> +config ROCKCHIP_USB_UART
> +       bool "Rockchip usb-uart override"
> +       depends on ARCH_ROCKCHIP
> +       select MFD_SYSCON
> +       help
> +         Say y here to enable usb-uart functionality. Newer Rockchip SoCs
> +         provide means to repurpose one usb phy as uart2 output, making it
> +         possible to get debug output without needing to open a device.
> +         To enable this function on boot, add a rockchip.usb_uart option
> +         to the kernel commandline.
> diff --git a/drivers/soc/rockchip/Makefile b/drivers/soc/rockchip/Makefile
> new file mode 100644
> index 0000000..b5dd6f8
> --- /dev/null
> +++ b/drivers/soc/rockchip/Makefile
> @@ -0,0 +1 @@
> +obj-$(CONFIG_ROCKCHIP_USB_UART)                +=      rockchip_usb_uart.o
> diff --git a/drivers/soc/rockchip/rockchip_usb_uart.c b/drivers/soc/rockchip/rockchip_usb_uart.c
> new file mode 100644
> index 0000000..8e96d46
> --- /dev/null
> +++ b/drivers/soc/rockchip/rockchip_usb_uart.c
> @@ -0,0 +1,226 @@
> +/*
> + * Copyright (c) 2015 Heiko Stuebner <heiko at sntech.de>
> + *
> + * 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/kernel.h>
> +#include <linux/init.h>
> +#include <linux/errno.h>
> +#include <linux/mfd/syscon.h>
> +#include <linux/of_address.h>
> +#include <linux/of_platform.h>
> +#include <linux/regmap.h>
> +#include <linux/slab.h>
> +
> +#define HIWORD_UPDATE(val, mask) \
> +               ((val) | (mask) << 16)
> +
> +struct rockchip_uart_data {
> +       const char *grf_compatible;
> +       const char *usb_compatible;
> +       phys_addr_t usb_phys_addr;
> +       int (*init_uart)(const struct rockchip_uart_data *data,
> +                        struct regmap *grf);
> +};
> +
> +static int enable_usb_uart;
> +
> +#define RK3288_UOC0_CON0                               0x320
> +#define RK3288_UOC0_CON0_COMMON_ON_N                   BIT(0)
> +#define RK3288_UOC0_CON0_DISABLE                       BIT(4)
> +#define RK3288_UOC0_CON0_SIDDQ                         BIT(13)
> +
> +#define RK3288_UOC0_CON2                               0x328
> +#define RK3288_UOC0_CON2_SOFT_CON_SEL                  BIT(2)
> +
> +#define RK3288_UOC0_CON3                               0x32c
> +#define RK3288_UOC0_CON3_UTMI_SUSPENDN                 BIT(0)
> +#define RK3288_UOC0_CON3_UTMI_OPMODE_NODRIVING         (1 << 1)
> +#define RK3288_UOC0_CON3_UTMI_OPMODE_MASK              (3 << 1)
> +#define RK3288_UOC0_CON3_UTMI_XCVRSEELCT_FSTRANSC      (1 << 3)
> +#define RK3288_UOC0_CON3_UTMI_XCVRSEELCT_MASK          (3 << 3)
> +#define RK3288_UOC0_CON3_UTMI_TERMSEL_FULLSPEED                BIT(5)
> +#define RK3288_UOC0_CON3_BYPASSDMEN                    BIT(6)
> +#define RK3288_UOC0_CON3_BYPASSSEL                     BIT(7)

I was wondering why these values are "hardcoded" directly, but as you
said, support for other SoCs will be enabled later.
Keep things simple as beginning is okay for me.

> +
> +/*
> + * Enable the bypass of uart2 data through the otg usb phy.
> + * Original description in the TRM.
> + * 1. Disable the OTG block by setting OTGDISABLE0 to 1?b1.
> + * 2. Disable the pull-up resistance on the D+ line by setting
> + *    OPMODE0[1:0] to 2?b01.
> + * 3. To ensure that the XO, Bias, and PLL blocks are powered down in Suspend
> + *    mode, set COMMONONN to 1?b1.
> + * 4. Place the USB PHY in Suspend mode by setting SUSPENDM0 to 1?b0.
> + * 5. Set BYPASSSEL0 to 1?b1.
> + * 6. To transmit data, controls BYPASSDMEN0, and BYPASSDMDATA0.
> + * To receive data, monitor FSVPLUS0.
> + *
> + * The actual code in the vendor kernel does some things differently.
> + */
> +static int __init rk3288_init_usb_uart(const struct rockchip_uart_data *data,
> +                                      struct regmap *grf)
> +{
> +       u32 val;
> +       int ret;
> +
> +       /*
> +        * COMMON_ON and DISABLE settings are described in the TRM,
> +        * but were not present in the original code.
> +        * Also disable the analog phy components to save power.
> +        */
> +       val = HIWORD_UPDATE(RK3288_UOC0_CON0_COMMON_ON_N
> +                               | RK3288_UOC0_CON0_DISABLE
> +                               | RK3288_UOC0_CON0_SIDDQ,
> +                           RK3288_UOC0_CON0_COMMON_ON_N
> +                               | RK3288_UOC0_CON0_DISABLE
> +                               | RK3288_UOC0_CON0_SIDDQ);
> +       ret = regmap_write(grf, RK3288_UOC0_CON0, val);
> +       if (ret)
> +               return ret;
> +
> +       val = HIWORD_UPDATE(RK3288_UOC0_CON2_SOFT_CON_SEL,
> +                           RK3288_UOC0_CON2_SOFT_CON_SEL);
> +       ret = regmap_write(grf, RK3288_UOC0_CON2, val);
> +       if (ret)
> +               return ret;
> +
> +       val = HIWORD_UPDATE(RK3288_UOC0_CON3_UTMI_OPMODE_NODRIVING
> +                               | RK3288_UOC0_CON3_UTMI_XCVRSEELCT_FSTRANSC
> +                               | RK3288_UOC0_CON3_UTMI_TERMSEL_FULLSPEED,
> +                           RK3288_UOC0_CON3_UTMI_SUSPENDN
> +                               | RK3288_UOC0_CON3_UTMI_OPMODE_MASK
> +                               | RK3288_UOC0_CON3_UTMI_XCVRSEELCT_MASK
> +                               | RK3288_UOC0_CON3_UTMI_TERMSEL_FULLSPEED);
> +       ret = regmap_write(grf, RK3288_UOC0_CON3, val);
> +       if (ret)
> +               return ret;
> +
> +       val = HIWORD_UPDATE(RK3288_UOC0_CON3_BYPASSSEL
> +                               | RK3288_UOC0_CON3_BYPASSDMEN,
> +                           RK3288_UOC0_CON3_BYPASSSEL
> +                               | RK3288_UOC0_CON3_BYPASSDMEN);
> +       ret = regmap_write(grf, RK3288_UOC0_CON3, val);
> +       if (ret)
> +               return ret;
> +
> +       return 0;
> +}
> +
> +static const struct rockchip_uart_data rk3288_uart_data __initconst = {
> +       .grf_compatible = "rockchip,rk3288-grf",
> +       .usb_compatible = "rockchip,rk3288-usb",
> +       .usb_phys_addr = 0xff580000,
> +       .init_uart = rk3288_init_usb_uart,
> +};
> +
> +static const struct of_device_id rockchip_usb_uart_ids[] __initconst = {
> +       { .compatible = "rockchip,rk3288", .data = &rk3288_uart_data },
> +       { }
> +};
> +
> +/*
> + * Find the usb controller using the shared usb-uart-phy in the dts and
> + * disable it.
> + */
> +static int __init
> +rockchip_disable_usb_controller(const struct rockchip_uart_data *data)
> +{
> +       struct device_node *np;
> +
> +       for_each_compatible_node(np, NULL, data->usb_compatible) {
> +               struct property *new_status;
> +               struct resource res;
> +               int ret;
> +
> +               ret = of_address_to_resource(np, 0, &res);
> +               if (ret) {
> +                       pr_err("%s: could not get address of usb controller %s\n",
> +                              __func__, np->full_name);
> +                       continue;
> +               }
> +
> +               /* not the controller we're looking for */
> +               if (res.start != data->usb_phys_addr)
> +                       continue;
> +
> +               pr_debug("%s: disabling usb controller %s\n",
> +                        __func__, np->full_name);
> +
> +               new_status = kzalloc(sizeof(*new_status), GFP_KERNEL);
> +               if (!new_status)
> +                       return -ENOMEM;
> +
> +               new_status->name = kstrdup("status", GFP_KERNEL);
> +               new_status->length = sizeof("disabled");
> +               new_status->value = kstrdup("disabled", GFP_KERNEL);

I understand completly why you need to pass an property allocated
dynamically, however, is it absolutly required to allocate "name" and
"value" dynamically too ? I mean, you could assign const literal
strings directly *BUT* it strongly depends on how properties are freed
by the devicetree subsystem.

> +
> +               return of_update_property(np, new_status);
> +       }
> +
> +       return 0;
> +}
> +
> +static const struct of_device_id __init *rockchip_usb_uart_data_lookup(void)
> +{
> +       struct device_node *root;
> +       const struct of_device_id *id;
> +
> +       root = of_find_node_by_path("/");
> +       if (!root)
> +               return NULL;
> +
> +       id = of_match_node(rockchip_usb_uart_ids, root);
> +       of_node_put(root);
> +
> +       return id;
> +}
> +
> +static int __init rockchip_init_usb_uart(void)
> +{
> +       const struct of_device_id *match;
> +       const struct rockchip_uart_data *data;
> +       struct regmap *grf;
> +       int ret;
> +
> +       if (!enable_usb_uart)
> +               return 0;
> +
> +       match = rockchip_usb_uart_data_lookup();
> +       if (!match)
> +               return -ENOTSUPP;
> +
> +       pr_debug("%s: using settings for %s\n", __func__, match->compatible);
> +       data = match->data;
> +
> +       grf = syscon_regmap_lookup_by_compatible(data->grf_compatible);
> +       if (IS_ERR(grf)) {
> +               pr_err("%s: could not find GRF syscon\n", __func__);
> +               return PTR_ERR(grf);
> +       }
> +
> +       ret = data->init_uart(data, grf);
> +       if (ret) {
> +               pr_err("%s: could not init usb_uart\n", __func__);
> +               return ret;
> +       }
> +
> +       return rockchip_disable_usb_controller(data);
> +}
> +early_initcall(rockchip_init_usb_uart);
> +
> +static int __init rockchip_usb_uart(char *buf)
> +{
> +       enable_usb_uart = true;
> +       return 0;
> +}
> +early_param("rockchip.usb_uart", rockchip_usb_uart);
> --
> 2.1.4
>
>
>
> _______________________________________________
> Linux-rockchip mailing list
> Linux-rockchip at lists.infradead.org
> http://lists.infradead.org/mailman/listinfo/linux-rockchip


I agree with Arnd, it would be better to lose nothing. Some users
might have rk3288-based tv box (assuming that the dts is opened...) or
broken uart... yes you can do low levels tasks on a development board,
but that's not a real solution for me. Each device should be
independent, imho.

Regards,
Romain


From ard.biesheuvel at linaro.org  Mon Aug 10 10:48:48 2015
From: ard.biesheuvel at linaro.org (Ard Biesheuvel)
Date: Mon, 10 Aug 2015 19:48:48 +0200
Subject: [RFC PATCH 01/10] arm64: feature registers: Documentation
In-Reply-To: <55C8E12E.6030305@arm.com>
References: <1437731037-25795-1-git-send-email-suzuki.poulose@arm.com>
 <1437731037-25795-2-git-send-email-suzuki.poulose@arm.com>
 <20150810160636.GB15394@e104818-lin.cambridge.arm.com>
 <55C8E12E.6030305@arm.com>
Message-ID: <CAKv+Gu-9GTzjqyT=NeBKjcaL7q-uFMToqPpprkyD-faG0J3mkQ@mail.gmail.com>

On 10 August 2015 at 19:36, Suzuki K. Poulose <Suzuki.Poulose at arm.com> wrote:
> On 10/08/15 17:06, Catalin Marinas wrote:
>>
>> Hi Suzuki,
>>
>> On Fri, Jul 24, 2015 at 10:43:47AM +0100, Suzuki K. Poulose wrote:
>>>
>>> From: "Suzuki K. Poulose" <suzuki.poulose at arm.com>
>>>
>>> Documentation of the infrastructure
>>>
>>> Signed-off-by: Suzuki K. Poulose <suzuki.poulose at arm.com>
>>
>>
>> The implementation looks fine but I think the main discussion will be
>> around the goal of this feature and the ABI that it introduces. So I'll
>> just write my thoughts on this patch (I could as well have replied to
>> the cover letter).
>>
>> Another question: who's going to use this feature? I know people asked
>> in private but I'd like to have some public statements.
>
>
> Right, I am hoping that folks from glibc / JIT / GCC will respond to
> this thread.
>
>>
> ...
>
>>> + a) Any change to the HWCAPs requires an update to userspace (e.g libc)
>>> +    to detect the new changes, which can take a long time to appear in
>>> +    distributions. Exposing the registers allows applications to get the
>>> +    information without requiring other userspace components to be
>>> updated.
>>
>>
>> How does it help if you have a new CPUID field or even a new value in an
>> existing field? Doesn't userspace need to be changed anyway to make use
>> of the new feature? I don't think that's a valid argument.
>>
>
> Yes, the userspace would need an update to work with the new CPUID field. I
> understand.
> It is just that, "in the enterprise world" updates to the system libraries
> provided by
> the distribution might take a bit longer to provide the changes than a
> software vendor.
> I agree thats not a common case.
>
>
>>> + b) Access to HWCAPs is sometimes restricted (e.g prior to libc, or when
>>> ld is
>>> +    initialised at startup time).
>>
>>
>> That's useful indeed.
>
>
> OK
>
>>
>>> + c) HWCAPs cannot represent non-boolean information effectively. The
>>> +    architecture defines a canonical format for representing features
>>> +    in the ID registers; this is well defined and is capable of
>>> +    representing all valid architecture variations. Exposing the ID
>>> +    registers avoids having to come up with HWCAP representations
>>> +    and parsing code.
>>
>>
>> So far we've managed to cope with the boolean state of HWCAP, at least
>> for information relevant to user space. One thing it doesn't cover is
>> MIDR_EL1.
>>
>> But the question here is whether we continue to add HWCAP bits even when
>> we exposed the CPUID registers to user. IMO, we should continue to add
>> the HWCAP bits matching new CPUID features for a few reasons:
>
>
> I don't have a strong opinion against it.
>
>>
>> 1. It's the current interface that we have and the bits can be checked
>>     in standard C code without having to issue arm64-specific instructions
>>
>
> I agree. May be we could provide library interface for this in the future ?
>
>> 2. We still need features listed in /proc/cpuinfo, at least for humans
>>     reading this file or scripts that can't issue mrs instructions
>>
>
> Agreed, we still need to provide the features in /proc/cpuinfo. We could do
> this without HWCAP if we decide not to update the list.
>
>> And to debunk some of the counter arguments:
>>
>> a) Running out of HWCAP bits - I really doubt this, we can always
>>     introduce 64 more via a new elf_hwcapX
>

Note that ELF_HWCAP is also wired into ifunc resolution of GNU
indirect functions, which looks like a useful feature although it
isn't used that widely yet.

The ifunc prototype for aarch64 has only one 'long' parameter, and I
don't know if it is possible to extend that without having a bit in
HWCAPn to indicate that HWCAPn+1 is valid. Also, the ifunc resolvers
are restricted in the sense that they cannot use shared libraries or
code that uses constructors (AFAIR) so it may require a special static
library to call this CPU feature interface from such a resolver if
features are not covered by HWCAP bits.

So treating HWCAP bits as an endless supply may not be the wisest
approach here. Also, I think some alignment with the libc folks is
indeed in order.

-- 
Ard.


From caschebe at techfak.uni-bielefeld.de  Mon Aug 10 10:49:11 2015
From: caschebe at techfak.uni-bielefeld.de (Christian Ascheberg)
Date: Mon, 10 Aug 2015 19:49:11 +0200
Subject: Problem with ftrace uprobes on ARM
Message-ID: <55C8E417.7080607@techfak.uni-bielefeld.de>

Hello,

I want to trace a program using ftrace uprobes on an Altera Cyclone V 
SoC board which has a ARMv7 processor, but I cannot get it to work. 
Every source I read says that uprobes should be supported on ARM.
So I hope that this is the right place to ask this question. I tried 
different kernel versions from Altera and github.com/torvalds/linux/, 
including 4.0, 4.1 and the latest 4.2-RC6.
The Linux config is the default socfpga_defconfig plus 
CONFIG_UPROBE_EVENT=y. Can somebody tell me if support should be 
available as I expect? These are the commands that I tried:

# objdump -t benchmark | grep "calc_sum"
00008574 g     F .text    00000020              calc_sum

# echo 'p /home/root/benchmark:0x8574' > 
/sys/kernel/debug/tracing/uprobe_events

# echo 1 > 
/sys/kernel/debug/tracing/events/uprobes/p_benchmark_0x8574/enable
-sh: echo: write error: Invalid argument

So the probe point is registered, but I cannot enable it. dmesg tells me 
the same without providing any more details.
I tried to do the same using Perf but it crashed my program, presumably 
when hitting the probe point.

Thanks
Christian


From davem at davemloft.net  Mon Aug 10 10:57:36 2015
From: davem at davemloft.net (David Miller)
Date: Mon, 10 Aug 2015 10:57:36 -0700 (PDT)
Subject: [PATCH 0/3] Fixes for the network driver of Marvell Armada 375 SoC
In-Reply-To: <1438880430-5480-1-git-send-email-mw@semihalf.com>
References: <y>
	<1438880430-5480-1-git-send-email-mw@semihalf.com>
Message-ID: <20150810.105736.226528661515254668.davem@davemloft.net>

From: Marcin Wojtas <mw at semihalf.com>
Date: Thu,  6 Aug 2015 19:00:27 +0200

> This is a set of three patches that fix long-lasting problems implemented in
> the initial support for the Armada 375 network controller.
> 
> Due to an inappropriate concept of handling the per-CPU sent packets'
> processing on TX path the driver numerous problems occured, such as RCU
> stalls. Those have been fixed, of which details you can find in the commit
> logs. The patches were intensively tested on top of v4.2-rc5.
> 
> I'm looking forward to any comments or remarks.

Series applied, thanks.


From alim.akhtar at gmail.com  Mon Aug 10 11:03:21 2015
From: alim.akhtar at gmail.com (Alim Akhtar)
Date: Mon, 10 Aug 2015 23:33:21 +0530
Subject: [RFC PATCH v4 1/9] mmc: dw_mmc: Add external dma interface support
In-Reply-To: <1438843491-23853-1-git-send-email-shawn.lin@rock-chips.com>
References: <1438843469-23807-1-git-send-email-shawn.lin@rock-chips.com>
 <1438843491-23853-1-git-send-email-shawn.lin@rock-chips.com>
Message-ID: <CAGOxZ51NZ2HaULzZWmxT=Lppnuk7Sqipz9ht5KAL20RvfE087A@mail.gmail.com>

Hi Shawn

On Thu, Aug 6, 2015 at 12:14 PM, Shawn Lin <shawn.lin at rock-chips.com> wrote:
> DesignWare MMC Controller can supports two types of DMA
> mode: external dma and internal dma. We get a RK312x platform
> integrated dw_mmc and ARM pl330 dma controller. This patch add
> edmac ops to support these platforms. I've tested it on RK312x
> platform with edmac mode and RK3288 platform with idmac mode.
>
Just curious to know if their are any performance (read/write)
difference with Idmac and edmac?

> Signed-off-by: Shawn Lin <shawn.lin at rock-chips.com>
>
> ---
>
> Changes in v4:
> - remove "host->trans_mode" and use "host->use_dma" to indicate
>   transfer mode.
> - remove all bt-bindings' changes since we don't need new properities.
> - check transfer mode at runtime by reading HCON reg
> - spilt defconfig changes for each sub-architecture
> - fix the title of cover letter
> - reuse some code for reducing code size
>
> Changes in v3:
> - choose transfer mode at runtime
> - remove all CONFIG_MMC_DW_IDMAC config option
> - add supports-idmac property for some platforms
>
> Changes in v2:
> - Fix typo of dev_info msg
> - remove unused dmach from declaration of dw_mci_dma_slave
>
>  drivers/mmc/host/Kconfig        |  11 +-
>  drivers/mmc/host/dw_mmc-pltfm.c |   2 +
>  drivers/mmc/host/dw_mmc.c       | 258 ++++++++++++++++++++++++++++++++--------
>  include/linux/mmc/dw_mmc.h      |  27 ++++-
>  4 files changed, 232 insertions(+), 66 deletions(-)
>
> diff --git a/drivers/mmc/host/Kconfig b/drivers/mmc/host/Kconfig
> index 6a0f9c7..a86c0eb 100644
> --- a/drivers/mmc/host/Kconfig
> +++ b/drivers/mmc/host/Kconfig
> @@ -607,15 +607,7 @@ config MMC_DW
>         help
>           This selects support for the Synopsys DesignWare Mobile Storage IP
>           block, this provides host support for SD and MMC interfaces, in both
> -         PIO and external DMA modes.
> -
> -config MMC_DW_IDMAC
> -       bool "Internal DMAC interface"
> -       depends on MMC_DW
> -       help
> -         This selects support for the internal DMAC block within the Synopsys
> -         Designware Mobile Storage IP block. This disables the external DMA
> -         interface.
> +         PIO, internal DMA mode and external DMA modes.
>
>  config MMC_DW_PLTFM
>         tristate "Synopsys Designware MCI Support as platform device"
> @@ -644,7 +636,6 @@ config MMC_DW_K3
>         tristate "K3 specific extensions for Synopsys DW Memory Card Interface"
>         depends on MMC_DW
>         select MMC_DW_PLTFM
> -       select MMC_DW_IDMAC
>         help
>           This selects support for Hisilicon K3 SoC specific extensions to the
>           Synopsys DesignWare Memory Card Interface driver. Select this option
> diff --git a/drivers/mmc/host/dw_mmc-pltfm.c b/drivers/mmc/host/dw_mmc-pltfm.c
> index ec6dbcd..7e1d13b 100644
> --- a/drivers/mmc/host/dw_mmc-pltfm.c
> +++ b/drivers/mmc/host/dw_mmc-pltfm.c
> @@ -59,6 +59,8 @@ int dw_mci_pltfm_register(struct platform_device *pdev,
>         host->pdata = pdev->dev.platform_data;
>
>         regs = platform_get_resource(pdev, IORESOURCE_MEM, 0);
> +       /* Get registers' physical base address */
> +       host->phy_regs = (void *)(regs->start);
>         host->regs = devm_ioremap_resource(&pdev->dev, regs);
>         if (IS_ERR(host->regs))
>                 return PTR_ERR(host->regs);
> diff --git a/drivers/mmc/host/dw_mmc.c b/drivers/mmc/host/dw_mmc.c
> index 40e9d8e..5d6cdff 100644
> --- a/drivers/mmc/host/dw_mmc.c
> +++ b/drivers/mmc/host/dw_mmc.c
> @@ -56,7 +56,7 @@
>  #define DW_MCI_FREQ_MAX        200000000       /* unit: HZ */
>  #define DW_MCI_FREQ_MIN        400000          /* unit: HZ */
>
> -#ifdef CONFIG_MMC_DW_IDMAC
> +
>  #define IDMAC_INT_CLR          (SDMMC_IDMAC_INT_AI | SDMMC_IDMAC_INT_NI | \
>                                  SDMMC_IDMAC_INT_CES | SDMMC_IDMAC_INT_DU | \
>                                  SDMMC_IDMAC_INT_FBE | SDMMC_IDMAC_INT_RI | \
> @@ -99,7 +99,6 @@ struct idmac_desc {
>
>         __le32          des3;   /* buffer 2 physical address */
>  };
> -#endif /* CONFIG_MMC_DW_IDMAC */
>
>  static bool dw_mci_reset(struct dw_mci *host);
>  static bool dw_mci_ctrl_reset(struct dw_mci *host, u32 reset);
> @@ -403,7 +402,6 @@ static int dw_mci_get_dma_dir(struct mmc_data *data)
>                 return DMA_FROM_DEVICE;
>  }
>
> -#ifdef CONFIG_MMC_DW_IDMAC
>  static void dw_mci_dma_cleanup(struct dw_mci *host)
>  {
>         struct mmc_data *data = host->data;
> @@ -441,12 +439,21 @@ static void dw_mci_idmac_stop_dma(struct dw_mci *host)
>         mci_writel(host, BMOD, temp);
>  }
>
> -static void dw_mci_idmac_complete_dma(struct dw_mci *host)
> +static void dw_mci_dmac_complete_dma(void *arg)
>  {
> +       struct dw_mci *host = arg;
>         struct mmc_data *data = host->data;
>
>         dev_vdbg(host->dev, "DMA complete\n");
>
> +       if (host->use_dma == TRANS_MODE_EDMAC)
> +               if (data && (data->flags & MMC_DATA_READ))
> +                       /* Invalidate cache after read */
> +                       dma_sync_sg_for_cpu(mmc_dev(host->cur_slot->mmc),
> +                                           data->sg,
> +                                           data->sg_len,
> +                                           DMA_FROM_DEVICE);
> +
>         host->dma_ops->cleanup(host);
>
>         /*
> @@ -527,7 +534,7 @@ static void dw_mci_translate_sglist(struct dw_mci *host, struct mmc_data *data,
>         wmb();
>  }
>
> -static void dw_mci_idmac_start_dma(struct dw_mci *host, unsigned int sg_len)
> +static int dw_mci_idmac_start_dma(struct dw_mci *host, unsigned int sg_len)
>  {
>         u32 temp;
>
> @@ -551,6 +558,8 @@ static void dw_mci_idmac_start_dma(struct dw_mci *host, unsigned int sg_len)
>
>         /* Start it running */
>         mci_writel(host, PLDMND, 1);
> +
> +       return 0;
>  }
>
>  static int dw_mci_idmac_init(struct dw_mci *host)
> @@ -629,10 +638,112 @@ static const struct dw_mci_dma_ops dw_mci_idmac_ops = {
>         .init = dw_mci_idmac_init,
>         .start = dw_mci_idmac_start_dma,
>         .stop = dw_mci_idmac_stop_dma,
> -       .complete = dw_mci_idmac_complete_dma,
> +       .complete = dw_mci_dmac_complete_dma,
> +       .cleanup = dw_mci_dma_cleanup,
> +};
> +
> +static void dw_mci_edmac_stop_dma(struct dw_mci *host)
> +{
> +       dmaengine_terminate_all(host->dms->ch);
> +}
> +
> +static int dw_mci_edmac_start_dma(struct dw_mci *host,
> +                                           unsigned int sg_len)
> +{
> +       struct dma_slave_config cfg;
> +       struct dma_async_tx_descriptor *desc = NULL;
> +       struct scatterlist *sgl = host->data->sg;
> +       const u32 mszs[] = {1, 4, 8, 16, 32, 64, 128, 256};
> +       u32 sg_elems = host->data->sg_len;
> +       u32 fifoth_val;
> +       u32 fifo_offset = host->fifo_reg - host->regs;
> +       int ret = 0;
> +
> +       /* Set external dma config: burst size, burst width */
> +       cfg.dst_addr = (dma_addr_t)(host->phy_regs + fifo_offset);
> +       cfg.src_addr = cfg.dst_addr;
> +       cfg.dst_addr_width = DMA_SLAVE_BUSWIDTH_4_BYTES;
> +       cfg.src_addr_width = DMA_SLAVE_BUSWIDTH_4_BYTES;
> +
> +       /* Match burst msize with external dma config */
> +       fifoth_val = mci_readl(host, FIFOTH);
> +       cfg.dst_maxburst = mszs[(fifoth_val >> 28) & 0x7];
> +       cfg.src_maxburst = cfg.dst_maxburst;
> +
> +       if (host->data->flags & MMC_DATA_WRITE)
> +               cfg.direction = DMA_MEM_TO_DEV;
> +       else /* MMC_DATA_READ */
> +               cfg.direction = DMA_DEV_TO_MEM;
> +
> +       ret = dmaengine_slave_config(host->dms->ch, &cfg);
> +       if (ret) {
> +               dev_err(host->dev, "Failed to config edmac.\n");
> +               return -EBUSY;
> +       }
> +
> +       desc = dmaengine_prep_slave_sg(host->dms->ch, sgl,
> +                                      sg_len, cfg.direction,
> +                                      DMA_PREP_INTERRUPT | DMA_CTRL_ACK);
> +       if (!desc) {
> +               dev_err(host->dev, "Can't prepare slave sg.\n");
> +               return -EBUSY;
> +       }
> +
> +       /* Set dw_mci_edmac_complete_dma as callback */
> +       desc->callback = dw_mci_dmac_complete_dma;
> +       desc->callback_param = (void *)host;
> +       dmaengine_submit(desc);
> +
> +       /* Flush cache before write */
> +       if (host->data->flags & MMC_DATA_WRITE)
> +               dma_sync_sg_for_device(mmc_dev(host->cur_slot->mmc), sgl,
> +                                      sg_elems, DMA_TO_DEVICE);
> +
> +       dma_async_issue_pending(host->dms->ch);
> +
> +       return 0;
> +}
> +
> +static int dw_mci_edmac_init(struct dw_mci *host)
> +{
> +       /* Request external dma channel */
> +       host->dms = kzalloc(sizeof(struct dw_mci_dma_slave), GFP_KERNEL);
> +       if (!host->dms)
> +               return -ENOMEM;
> +
> +       host->dms->ch = dma_request_slave_channel(host->dev, "rx-tx");
> +       if (!host->dms->ch) {
> +               dev_err(host->dev,
> +                       "Failed to get external DMA channel %d\n",
> +                       host->dms->ch->chan_id);
> +               kfree(host->dms);
> +               host->dms = NULL;
> +               return -ENXIO;
> +       }
> +
> +       return 0;
> +}
> +
> +static void dw_mci_edmac_exit(struct dw_mci *host)
> +{
> +       if (host->dms) {
> +               if (host->dms->ch) {
> +                       dma_release_channel(host->dms->ch);
> +                       host->dms->ch = NULL;
> +               }
> +               kfree(host->dms);
> +               host->dms = NULL;
> +       }
> +}
> +
> +static const struct dw_mci_dma_ops dw_mci_edmac_ops = {
> +       .init = dw_mci_edmac_init,
> +       .exit = dw_mci_edmac_exit,
> +       .start = dw_mci_edmac_start_dma,
> +       .stop = dw_mci_edmac_stop_dma,
> +       .complete = dw_mci_dmac_complete_dma,
>         .cleanup = dw_mci_dma_cleanup,
>  };
> -#endif /* CONFIG_MMC_DW_IDMAC */
>
>  static int dw_mci_pre_dma_transfer(struct dw_mci *host,
>                                    struct mmc_data *data,
> @@ -712,7 +823,6 @@ static void dw_mci_post_req(struct mmc_host *mmc,
>
>  static void dw_mci_adjust_fifoth(struct dw_mci *host, struct mmc_data *data)
>  {
> -#ifdef CONFIG_MMC_DW_IDMAC
>         unsigned int blksz = data->blksz;
>         const u32 mszs[] = {1, 4, 8, 16, 32, 64, 128, 256};
>         u32 fifo_width = 1 << host->data_shift;
> @@ -720,6 +830,10 @@ static void dw_mci_adjust_fifoth(struct dw_mci *host, struct mmc_data *data)
>         u32 msize = 0, rx_wmark = 1, tx_wmark, tx_wmark_invers;
>         int idx = (sizeof(mszs) / sizeof(mszs[0])) - 1;
>
> +       /* pio should ship this scenario */
> +       if (!host->use_dma)
> +               return;
> +
>         tx_wmark = (host->fifo_depth) / 2;
>         tx_wmark_invers = host->fifo_depth - tx_wmark;
>
> @@ -748,7 +862,6 @@ static void dw_mci_adjust_fifoth(struct dw_mci *host, struct mmc_data *data)
>  done:
>         fifoth_val = SDMMC_SET_FIFOTH(msize, rx_wmark, tx_wmark);
>         mci_writel(host, FIFOTH, fifoth_val);
> -#endif
>  }
>
>  static void dw_mci_ctrl_rd_thld(struct dw_mci *host, struct mmc_data *data)
> @@ -835,7 +948,11 @@ static int dw_mci_submit_data_dma(struct dw_mci *host, struct mmc_data *data)
>         mci_writel(host, INTMASK, temp);
>         spin_unlock_irqrestore(&host->irq_lock, irqflags);
>
> -       host->dma_ops->start(host, sg_len);
> +       if (host->dma_ops->start(host, sg_len)) {
> +               /* We can't do DMA */
> +               dev_err(host->dev, "%s: failed to start DMA.\n", __func__);
> +               return -ENODEV;
> +       }
>
>         return 0;
>  }
> @@ -2256,26 +2373,30 @@ static irqreturn_t dw_mci_interrupt(int irq, void *dev_id)
>
>         }
>
> -#ifdef CONFIG_MMC_DW_IDMAC
> -       /* Handle DMA interrupts */
> -       if (host->dma_64bit_address == 1) {
> -               pending = mci_readl(host, IDSTS64);
> -               if (pending & (SDMMC_IDMAC_INT_TI | SDMMC_IDMAC_INT_RI)) {
> -                       mci_writel(host, IDSTS64, SDMMC_IDMAC_INT_TI |
> -                                                       SDMMC_IDMAC_INT_RI);
> -                       mci_writel(host, IDSTS64, SDMMC_IDMAC_INT_NI);
> -                       host->dma_ops->complete(host);
> -               }
> -       } else {
> -               pending = mci_readl(host, IDSTS);
> -               if (pending & (SDMMC_IDMAC_INT_TI | SDMMC_IDMAC_INT_RI)) {
> -                       mci_writel(host, IDSTS, SDMMC_IDMAC_INT_TI |
> -                                                       SDMMC_IDMAC_INT_RI);
> -                       mci_writel(host, IDSTS, SDMMC_IDMAC_INT_NI);
> -                       host->dma_ops->complete(host);
> +       if (host->use_dma == TRANS_MODE_IDMAC) {
> +               /* Handle DMA interrupts */
> +               if (host->dma_64bit_address == 1) {
> +                       pending = mci_readl(host, IDSTS64);
> +                       if (pending & (SDMMC_IDMAC_INT_TI |
> +                                      SDMMC_IDMAC_INT_RI)) {
> +                               mci_writel(host, IDSTS64,
> +                                          SDMMC_IDMAC_INT_TI |
> +                                          SDMMC_IDMAC_INT_RI);
> +                               mci_writel(host, IDSTS64, SDMMC_IDMAC_INT_NI);
> +                               host->dma_ops->complete((void *)host);
> +                       }
> +               } else {
> +                       pending = mci_readl(host, IDSTS);
> +                       if (pending & (SDMMC_IDMAC_INT_TI |
> +                                      SDMMC_IDMAC_INT_RI)) {
> +                               mci_writel(host, IDSTS,
> +                                          SDMMC_IDMAC_INT_TI |
> +                                          SDMMC_IDMAC_INT_RI);
> +                               mci_writel(host, IDSTS, SDMMC_IDMAC_INT_NI);
> +                               host->dma_ops->complete((void *)host);
> +                       }
>                 }
>         }
> -#endif
>
>         return IRQ_HANDLED;
>  }
> @@ -2391,19 +2512,28 @@ static int dw_mci_init_slot(struct dw_mci *host, unsigned int id)
>                 mmc->max_seg_size = host->pdata->blk_settings->max_seg_size;
>         } else {
>                 /* Useful defaults if platform data is unset. */
> -#ifdef CONFIG_MMC_DW_IDMAC
> -               mmc->max_segs = host->ring_size;
> -               mmc->max_blk_size = 65536;
> -               mmc->max_seg_size = 0x1000;
> -               mmc->max_req_size = mmc->max_seg_size * host->ring_size;
> -               mmc->max_blk_count = mmc->max_req_size / 512;
> -#else
> -               mmc->max_segs = 64;
> -               mmc->max_blk_size = 65536; /* BLKSIZ is 16 bits */
> -               mmc->max_blk_count = 512;
> -               mmc->max_req_size = mmc->max_blk_size * mmc->max_blk_count;
> -               mmc->max_seg_size = mmc->max_req_size;
> -#endif /* CONFIG_MMC_DW_IDMAC */
> +               if (host->use_dma == TRANS_MODE_IDMAC) {
> +                       mmc->max_segs = host->ring_size;
> +                       mmc->max_blk_size = 65536;
> +                       mmc->max_seg_size = 0x1000;
> +                       mmc->max_req_size = mmc->max_seg_size * host->ring_size;
> +                       mmc->max_blk_count = mmc->max_req_size / 512;
> +               } else if (host->use_dma == TRANS_MODE_EDMAC) {
> +                       mmc->max_segs = 64;
> +                       mmc->max_blk_size = 65536;
> +                       mmc->max_blk_count = 65535;
> +                       mmc->max_req_size =
> +                                       mmc->max_blk_size * mmc->max_blk_count;
> +                       mmc->max_seg_size = mmc->max_req_size;
> +               } else {
> +                       /* TRANS_MODE_PIO */
> +                       mmc->max_segs = 64;
> +                       mmc->max_blk_size = 65536; /* BLKSIZ is 16 bits */
> +                       mmc->max_blk_count = 512;
> +                       mmc->max_req_size =
> +                                       mmc->max_blk_size * mmc->max_blk_count;
> +                       mmc->max_seg_size = mmc->max_req_size;
> +               }
>         }
>
>         if (dw_mci_get_cd(mmc))
> @@ -2437,6 +2567,21 @@ static void dw_mci_cleanup_slot(struct dw_mci_slot *slot, unsigned int id)
>  static void dw_mci_init_dma(struct dw_mci *host)
>  {
>         int addr_config;
> +       int trans_mode;
> +       struct device *dev = host->dev;
> +       struct device_node *np = dev->of_node;
> +
> +       /* Check tansfer mode */
> +       trans_mode = (mci_readl(host, HCON) >> 16) & 0x3;
> +       if (trans_mode == 0) {
> +               trans_mode = TRANS_MODE_IDMAC;
> +       } else if (trans_mode == 1 || trans_mode == 2) {
> +               trans_mode = TRANS_MODE_EDMAC;
> +       } else {
> +               trans_mode = TRANS_MODE_PIO;
> +               goto no_dma;
> +       }
> +
>         /* Check ADDR_CONFIG bit in HCON to find IDMAC address bus width */
>         addr_config = (mci_readl(host, HCON) >> 27) & 0x01;
>
> @@ -2462,10 +2607,19 @@ static void dw_mci_init_dma(struct dw_mci *host)
>         }
>
>         /* Determine which DMA interface to use */
> -#ifdef CONFIG_MMC_DW_IDMAC
> -       host->dma_ops = &dw_mci_idmac_ops;
> -       dev_info(host->dev, "Using internal DMA controller.\n");
> -#endif
> +       if (trans_mode == TRANS_MODE_IDMAC) {
> +               host->dma_ops = &dw_mci_idmac_ops;
> +               dev_info(host->dev, "Using internal DMA controller.\n");
> +       } else {
> +               /* TRANS_MODE_EDMAC: check dma bindings again */
> +               if ((of_property_count_strings(np, "dma-names") < 0) ||
> +                   (!of_find_property(np, "dmas", NULL))) {
> +                       trans_mode = TRANS_MODE_PIO;
> +                       goto no_dma;
> +               }
> +               host->dma_ops = &dw_mci_edmac_ops;
> +               dev_info(host->dev, "Using external DMA controller.\n");
> +       }
>
>         if (!host->dma_ops)
>                 goto no_dma;
> @@ -2482,12 +2636,12 @@ static void dw_mci_init_dma(struct dw_mci *host)
>                 goto no_dma;
>         }
>
> -       host->use_dma = 1;
> +       host->use_dma = trans_mode;
>         return;
>
>  no_dma:
>         dev_info(host->dev, "Using PIO mode.\n");
> -       host->use_dma = 0;
> +       host->use_dma = trans_mode;
>         return;
>  }
>
> @@ -2570,10 +2724,9 @@ static bool dw_mci_reset(struct dw_mci *host)
>                 }
>         }
>
> -#if IS_ENABLED(CONFIG_MMC_DW_IDMAC)
> -       /* It is also recommended that we reset and reprogram idmac */
> -       dw_mci_idmac_reset(host);
> -#endif
> +       if (host->use_dma == TRANS_MODE_IDMAC)
> +               /* It is also recommended that we reset and reprogram idmac */
> +               dw_mci_idmac_reset(host);
>
>         ret = true;
>
> @@ -2958,6 +3111,9 @@ EXPORT_SYMBOL(dw_mci_remove);
>   */
>  int dw_mci_suspend(struct dw_mci *host)
>  {
> +       if (host->use_dma && host->dma_ops->exit)
> +               host->dma_ops->exit(host);
> +
>         return 0;
>  }
>  EXPORT_SYMBOL(dw_mci_suspend);
> diff --git a/include/linux/mmc/dw_mmc.h b/include/linux/mmc/dw_mmc.h
> index 5be9767..9ed6257 100644
> --- a/include/linux/mmc/dw_mmc.h
> +++ b/include/linux/mmc/dw_mmc.h
> @@ -16,6 +16,7 @@
>
>  #include <linux/scatterlist.h>
>  #include <linux/mmc/core.h>
> +#include <linux/dmaengine.h>
>
>  #define MAX_MCI_SLOTS  2
>
> @@ -40,6 +41,17 @@ enum {
>
>  struct mmc_data;
>
> +enum {
> +       TRANS_MODE_PIO = 0,
> +       TRANS_MODE_IDMAC,
> +       TRANS_MODE_EDMAC
> +};
> +
> +struct dw_mci_dma_slave {
> +       struct dma_chan *ch;
> +       enum dma_transfer_direction direction;
> +};
> +
>  /**
>   * struct dw_mci - MMC controller state shared between all slots
>   * @lock: Spinlock protecting the queue and associated data.
> @@ -153,11 +165,16 @@ struct dw_mci {
>         dma_addr_t              sg_dma;
>         void                    *sg_cpu;
>         const struct dw_mci_dma_ops     *dma_ops;
> -#ifdef CONFIG_MMC_DW_IDMAC
> +       /* For idmac */
>         unsigned int            ring_size;
> -#else
> +
> +       /* For edmac */
> +       struct dw_mci_dma_slave *dms;
> +       /* Registers's physical base address */
> +       void                    *phy_regs;
> +
>         struct dw_mci_dma_data  *dma_data;
> -#endif
> +
>         u32                     cmd_status;
>         u32                     data_status;
>         u32                     stop_cmdr;
> @@ -210,8 +227,8 @@ struct dw_mci {
>  struct dw_mci_dma_ops {
>         /* DMA Ops */
>         int (*init)(struct dw_mci *host);
> -       void (*start)(struct dw_mci *host, unsigned int sg_len);
> -       void (*complete)(struct dw_mci *host);
> +       int (*start)(struct dw_mci *host, unsigned int sg_len);
> +       void (*complete)(void *host);
>         void (*stop)(struct dw_mci *host);
>         void (*cleanup)(struct dw_mci *host);
>         void (*exit)(struct dw_mci *host);
> --
> 2.3.7
>
>
> --
> To unsubscribe from this list: send the line "unsubscribe linux-mmc" in
> the body of a message to majordomo at vger.kernel.org
> More majordomo info at  http://vger.kernel.org/majordomo-info.html



-- 
Regards,
Alim


From broonie at kernel.org  Mon Aug 10 11:16:41 2015
From: broonie at kernel.org (Mark Brown)
Date: Mon, 10 Aug 2015 19:16:41 +0100
Subject: [PATCH 1/9] drm: bridge/dw_hdmi-ahb-audio: add audio driver
In-Reply-To: <20150810164941.GW7557@n2100.arm.linux.org.uk>
References: <20150808160936.GN7557@n2100.arm.linux.org.uk>
 <E1ZO6hC-0003M5-EU@rmk-PC.arm.linux.org.uk>
 <s5hk2t35ui4.wl-tiwai@suse.de>
 <20150810103921.GR7557@n2100.arm.linux.org.uk>
 <s5hegjb5o44.wl-tiwai@suse.de>
 <20150810164941.GW7557@n2100.arm.linux.org.uk>
Message-ID: <20150810181641.GD10748@sirena.org.uk>

On Mon, Aug 10, 2015 at 05:49:41PM +0100, Russell King - ARM Linux wrote:

> I'm not sure what the right solution is here: modifying every audio
> player out there to make HDMI work sanely is crazy.  Having alsalib
> automatically generate the correct AES channel status bytes for
> linear audio formats seems to be sensible, but difficult given its
> present structure with the defaults - the iec958 plugin has no idea
> if the defaults are being used or not.

> The advantage of having the horrid conversion in the kernel is that
> we can choose to generate proper AES channel status data without
> regard to userspace for standard linear PCM, and when the iec958 plugin
> is being used with proper channel status (eg, in compressed audio
> pass-through mode by VLC) then that works too.

The other advantage of doing it in kernel is that it also fixes tinyalsa
applications (which mainly means Android systems) by default for PCM
data.
-------------- next part --------------
A non-text attachment was scrubbed...
Name: signature.asc
Type: application/pgp-signature
Size: 473 bytes
Desc: Digital signature
URL: <http://lists.infradead.org/pipermail/linux-arm-kernel/attachments/20150810/8d801c69/attachment.sig>

From sergei.shtylyov at cogentembedded.com  Mon Aug 10 11:18:24 2015
From: sergei.shtylyov at cogentembedded.com (Sergei Shtylyov)
Date: Mon, 10 Aug 2015 21:18:24 +0300
Subject: [PATCH 2/2] ARM: shmobile: silk: add QSPI DT support
In-Reply-To: <CAMuHMdXQJ4Hju477Ys0ujXCNdUjWOa6AuKGzLPc3YFJc_eLz+g@mail.gmail.com>
References: <1898263.zrOs5SAUTS@wasted.cogentembedded.com>
 <1768974.jEFIAaInqd@wasted.cogentembedded.com>
 <CAMuHMdXQJ4Hju477Ys0ujXCNdUjWOa6AuKGzLPc3YFJc_eLz+g@mail.gmail.com>
Message-ID: <55C8EAF0.7060600@cogentembedded.com>

Hello.

On 08/10/2015 05:38 PM, Geert Uytterhoeven wrote:

>> Define the SILK board dependent part of the QSPI device node.
>> Add device nodes  for Spansion  S25FL512S SPI flash and MTD partitions on it.

>> Based on the original patch by Vladimir Barinov
>> <vladimir.barinov at cogentembedded.com>.

>> Signed-off-by: Sergei Shtylyov <sergei.shtylyov at cogentembedded.com>

>> --- renesas.orig/arch/arm/boot/dts/r8a7794-silk.dts
>> +++ renesas/arch/arm/boot/dts/r8a7794-silk.dts
>
>> +&qspi {
>> +       pinctrl-0 = <&qspi_pins>;
>> +       pinctrl-names = "default";
>> +
>> +       status = "okay";
>> +
>> +       flash at 0 {
>> +               #address-cells = <1>;
>> +               #size-cells = <1>;
>> +               compatible = "spansion,s25fl512s";

> Please add the "jedec,spi-nor" fallback.

    Hm, spi-nor.c alone can't control this device, it's rather m25p80.c that's 
the real driver. So if a fallback needs to be added indeed it should be 
"st,m25p80" I think...

[...]

> Gr{oetje,eeting}s,

MBR, Sergei



From aph at redhat.com  Mon Aug 10 11:19:03 2015
From: aph at redhat.com (Andrew Haley)
Date: Mon, 10 Aug 2015 19:19:03 +0100
Subject: [RFC PATCH 01/10] arm64: feature registers: Documentation
In-Reply-To: <55C8E12E.6030305@arm.com>
References: <1437731037-25795-1-git-send-email-suzuki.poulose@arm.com>
 <1437731037-25795-2-git-send-email-suzuki.poulose@arm.com>
 <20150810160636.GB15394@e104818-lin.cambridge.arm.com>
 <55C8E12E.6030305@arm.com>
Message-ID: <55C8EB17.7090708@redhat.com>

On 08/10/2015 06:36 PM, Suzuki K. Poulose wrote:
> On 10/08/15 17:06, Catalin Marinas wrote:
>> Hi Suzuki,
>>
>> On Fri, Jul 24, 2015 at 10:43:47AM +0100, Suzuki K. Poulose wrote:
>>> From: "Suzuki K. Poulose" <suzuki.poulose at arm.com>
>>>
>>> Documentation of the infrastructure
>>>
>>> Signed-off-by: Suzuki K. Poulose <suzuki.poulose at arm.com>
>>
>> The implementation looks fine but I think the main discussion will be
>> around the goal of this feature and the ABI that it introduces. So I'll
>> just write my thoughts on this patch (I could as well have replied to
>> the cover letter).
>>
>> Another question: who's going to use this feature? I know people asked
>> in private but I'd like to have some public statements.
> 
> Right, I am hoping that folks from glibc / JIT / GCC will respond to
> this thread.

We certainly need it for OpenJDK.  We need to know the manufacturer,
part number, revision id, etc.  We already have workarounds in
OpenJDK for various bugs, and we also can generate better code if we
know the exact part.

I note that the REVIDR is not in this patch.  That seems odd, because
it can be used to identify minor revisions.

Andrew.




From manabian at gmail.com  Mon Aug 10 11:42:16 2015
From: manabian at gmail.com (Joachim Eastwood)
Date: Mon, 10 Aug 2015 20:42:16 +0200
Subject: [PATCH 5/5] drivers/tty: make serial 8250_lpc18xx.c explicitly
 non-modular
In-Reply-To: <1439081497-14986-6-git-send-email-paul.gortmaker@windriver.com>
References: <1439081497-14986-1-git-send-email-paul.gortmaker@windriver.com>
 <1439081497-14986-6-git-send-email-paul.gortmaker@windriver.com>
Message-ID: <CAGhQ9Vxjymt4z32s3x2B8b6ypgn3Bzh1ncbqxqidfPyM2k87jw@mail.gmail.com>

Hi Paul,

On 9 August 2015 at 02:51, Paul Gortmaker <paul.gortmaker at windriver.com> wrote:
> The Kconfig currently controlling compilation of this code is:
>
> 8250/Kconfig:config SERIAL_8250_LPC18XX
> 8250/Kconfig:        bool "NXP LPC18xx/43xx serial port support"
>
> ...meaning that it currently is not being built as a module by anyone.
>
> Lets remove the modular code that is essentially orphaned, so that
> when reading the driver there is no doubt it is builtin-only.

The bool in KConfig is more or less a copy-paste mistake on my side. I
really meant for this driver to be buildable as module and it builds
just fine with 'm'.

Want me send a patch changing it to tristate or will you handle it?


regards,
Joachim Eastwood


From geert at linux-m68k.org  Mon Aug 10 11:52:03 2015
From: geert at linux-m68k.org (Geert Uytterhoeven)
Date: Mon, 10 Aug 2015 20:52:03 +0200
Subject: [PATCH 2/2] ARM: shmobile: silk: add QSPI DT support
In-Reply-To: <55C8EAF0.7060600@cogentembedded.com>
References: <1898263.zrOs5SAUTS@wasted.cogentembedded.com>
 <1768974.jEFIAaInqd@wasted.cogentembedded.com>
 <CAMuHMdXQJ4Hju477Ys0ujXCNdUjWOa6AuKGzLPc3YFJc_eLz+g@mail.gmail.com>
 <55C8EAF0.7060600@cogentembedded.com>
Message-ID: <CAMuHMdVAjsDJ+fFJnG4WAydCgvW=iRDcyXp9R6xBfn3EHU-tbQ@mail.gmail.com>

Hi Sergei,

On Mon, Aug 10, 2015 at 8:18 PM, Sergei Shtylyov
<sergei.shtylyov at cogentembedded.com> wrote:
> On 08/10/2015 05:38 PM, Geert Uytterhoeven wrote:
>>> +&qspi {
>>> +       pinctrl-0 = <&qspi_pins>;
>>> +       pinctrl-names = "default";
>>> +
>>> +       status = "okay";
>>> +
>>> +       flash at 0 {
>>> +               #address-cells = <1>;
>>> +               #size-cells = <1>;
>>> +               compatible = "spansion,s25fl512s";
>
>> Please add the "jedec,spi-nor" fallback.
>
>    Hm, spi-nor.c alone can't control this device, it's rather m25p80.c
> that's the real driver. So if a fallback needs to be added indeed it should
> be "st,m25p80" I think...

Please have a look at Documentation/devicetree/bindings/mtd/jedec,spi-nor.txt.

Gr{oetje,eeting}s,

                        Geert

--
Geert Uytterhoeven -- There's lots of Linux beyond ia32 -- geert at linux-m68k.org

In personal conversations with technical people, I call myself a hacker. But
when I'm talking to journalists I just say "programmer" or something like that.
                                -- Linus Torvalds


From dhdang at apm.com  Mon Aug 10 12:07:13 2015
From: dhdang at apm.com (Duc Dang)
Date: Mon, 10 Aug 2015 12:07:13 -0700
Subject: X-Gene: Unhandled fault: synchronous external abort in
 pci_generic_config_read32
In-Reply-To: <CAErSpo7aDYKwy4MC6ZPf7hNd4MPE-LARiOVKutFfDFFkHY7qjQ@mail.gmail.com>
References: <20150724224258.GA23990@google.com>
 <CADaLNDmYZ=8XQt82W_H74QaOiX3UwkVxkE1_EWRgzhkG1boebw@mail.gmail.com>
 <CAErSpo549xfAnx62quCqGHh3DNay5Lfb6EhEG+4EXooEuueQFQ@mail.gmail.com>
 <CADaLNDn95H=g73DKWRsrB4SuWcf+-8mkepbwb_DC-sFsVkrk6g@mail.gmail.com>
 <20150728212944.GA12958@google.com>
 <CADaLNDkOLiyPmVC3VwpnbrfAKFmNwSVJKdChjQFdQqs7XP-Ddg@mail.gmail.com>
 <20150729012255.GA18606@google.com> <20150729155509.GA31170@google.com>
 <CADaLNDk=+J_yOer1ferSCNb_xAC42ULtP2FyCLmYMwa+Gj=vfA@mail.gmail.com>
 <CAErSpo4VFh7rv81sCAG-eCXVyZh4ub8Trh-ntZhyfy7BzqTr5g@mail.gmail.com>
 <CADaLNDkUQHzGACfFmYDeJWnaNrKmJUDx4Rby60OWr4FzOjx3rA@mail.gmail.com>
 <CAErSpo7aDYKwy4MC6ZPf7hNd4MPE-LARiOVKutFfDFFkHY7qjQ@mail.gmail.com>
Message-ID: <CADaLNDmnnZOoB1fxO=rQQa-eqT=B9G24rUrN_GzwAkFoC3Acbw@mail.gmail.com>

On Mon, Aug 10, 2015 at 10:42 AM, Bjorn Helgaas <bhelgaas at google.com> wrote:
> On Mon, Aug 10, 2015 at 12:16 PM, Duc Dang <dhdang at apm.com> wrote:
>> On Monday, August 10, 2015, Bjorn Helgaas <bhelgaas at google.com> wrote:
>>>
>>> On Fri, Jul 31, 2015 at 12:00 PM, Duc Dang <dhdang at apm.com> wrote:
>>> > On Wed, Jul 29, 2015 at 8:55 AM, Bjorn Helgaas <bhelgaas at google.com>
>>> > wrote:
>>> >> On Tue, Jul 28, 2015 at 08:22:55PM -0500, Bjorn Helgaas wrote:
>>> >>> On Tue, Jul 28, 2015 at 02:50:39PM -0700, Duc Dang wrote:
>>> >>
>>> >>> > Do you have another PCIe card to try on the same reboot test on this
>>> >>> > board?
>>> >>>
>>> >>> I've seen this on at least two Mellanox cards.  I'm running similar
>>> >>> tests
>>> >>> on a different type of card now.
>>> >>
>>> >> FWIW, reboot tests on two machines with Mellanox cards failed, while
>>> >> the
>>> >> same test on a machine with a different proprietary card succeeded.
>>> >
>>> > Thanks, Bjorn.
>>> >
>>> > I don't have the same Mellanox card as yours, but I will also run
>>> > similar reboot test to see if I hit the same issue with my card.
>>>
>>> Any more hints on this?  Nothing has changed on my end, so of course
>>> I'm still seeing this, always on machines with Mellanox, and never on
>>> other machines.  Could this be a hardware issue like a signal
>>> integrity or margin issue?  I don't know where to go from here because
>>> I'm not a hardware person, and I don't know anything to do in
>>> software.
>>
>>
>> Hi Bjorn,
>>
>> I tried to run similar reboot tests on 2 different Mellanox cards (Connect-X
>> family, one card has 2 10G interfaces, the other one has 1 port that
>> supports InfiniBand) with U-Boot 1.15.12 and linux 4.2-rc5 and I did not see
>> the crash that you encounterred.
>>
>> Did you check if your Mellanox cards have latest firmware? I did see some
>> link issues on my Mellanox cards with its old firmware before.
>
> Good idea; I'll check that, too.  Also, I just learned that these
> cards on installed with an extender card because of some space issues,
> so we're going to test again without the extender.

Hi Bjorn,

Are other cards that passed your test installed directly to the
on-board PCIe slot?
If yes, then this is a good data point and it will be useful to test
the case where
your Mellanox cards are directly installed into the on-board PCIe slot.

-- 
Regards,
Duc Dang.


From rabin at rab.in  Mon Aug 10 12:31:16 2015
From: rabin at rab.in (Rabin Vincent)
Date: Mon, 10 Aug 2015 21:31:16 +0200
Subject: Problem with ftrace uprobes on ARM
In-Reply-To: <55C8E417.7080607@techfak.uni-bielefeld.de>
References: <55C8E417.7080607@techfak.uni-bielefeld.de>
Message-ID: <20150810193116.GA2895@debian>

On Mon, Aug 10, 2015 at 07:49:11PM +0200, Christian Ascheberg wrote:
> # objdump -t benchmark | grep "calc_sum"
> 00008574 g     F .text    00000020              calc_sum
> 
> # echo 'p /home/root/benchmark:0x8574' >
> /sys/kernel/debug/tracing/uprobe_events
> 
> # echo 1 >
> /sys/kernel/debug/tracing/events/uprobes/p_benchmark_0x8574/enable
> -sh: echo: write error: Invalid argument

The offset of the instruction in the file should be used, not the virtual
address.  For example, in the following example ls_main() is at 0x0009aec0 but
to set the breakpoint one actually has to use 0x92ec0:

$ arm-none-linux-gnueabi-nm busybox_unstripped | grep ls_main
0009aec0 T ls_main

$ arm-none-linux-gnueabi-objdump -F -d busybox_unstripped | grep '<ls_main>'
0009aec0 <ls_main> (File Offset: 0x92ec0):

By the way, I hope "benchmark" does not use Thumb instructions, because
uprobes on those aren't supported.  See arch_uprobe_analyze_insn().


From sebastian.hesselbarth at gmail.com  Mon Aug 10 12:44:11 2015
From: sebastian.hesselbarth at gmail.com (Sebastian Hesselbarth)
Date: Mon, 10 Aug 2015 21:44:11 +0200
Subject: [PATCH v2 2/5] Documentation: bindings: document the Berlin PWM
 driver
In-Reply-To: <1438248201-29222-3-git-send-email-antoine.tenart@free-electrons.com>
References: <1438248201-29222-1-git-send-email-antoine.tenart@free-electrons.com>
 <1438248201-29222-3-git-send-email-antoine.tenart@free-electrons.com>
Message-ID: <55C8FF0B.50203@gmail.com>

On 30.07.2015 11:23, Antoine Tenart wrote:
> Following the addition of a Berlin PWM driver, this patch adds the
> corresponding documentation.
>
> Signed-off-by: Antoine Tenart <antoine.tenart at free-electrons.com>
> ---
>   Documentation/devicetree/bindings/pwm/pwm-berlin.txt | 15 +++++++++++++++
>   1 file changed, 15 insertions(+)
>   create mode 100644 Documentation/devicetree/bindings/pwm/pwm-berlin.txt
>
> diff --git a/Documentation/devicetree/bindings/pwm/pwm-berlin.txt b/Documentation/devicetree/bindings/pwm/pwm-berlin.txt
> new file mode 100644
> index 000000000000..3d7ab7bfbf54
> --- /dev/null
> +++ b/Documentation/devicetree/bindings/pwm/pwm-berlin.txt
> @@ -0,0 +1,15 @@
> +Berlin PWM controller

Just a little sentence about "PWM IP found in Marvell Berlin SoCs" ?
Besides that, this looks pretty straight-forward to me. Feel free
to add my

Acked-by: Sebastian Hesselbarth <sebastian.hesselbarth at gmail.com>

for the Berlin part of it.

Sebastian

> +Required properties:
> +- compatible: should be "marvell,berlin-pwm"
> +- reg: physical base address and length of the controller's registers
> +- #pwm-cells: should be 3. See pwm.txt in this directory for a description of
> +  the cells format.
> +
> +Example:
> +
> +pwm: pwm at f7f20000 {
> +	compatible = "marvell,berlin-pwm";
> +	reg = <0xf7f20000 0x40>;
> +	#pwm-cells = <3>;
> +}
>



From sebastian.hesselbarth at gmail.com  Mon Aug 10 12:42:14 2015
From: sebastian.hesselbarth at gmail.com (Sebastian Hesselbarth)
Date: Mon, 10 Aug 2015 21:42:14 +0200
Subject: [PATCH v2 1/5] pwm: add the Berlin pwm controller driver
In-Reply-To: <1438248201-29222-2-git-send-email-antoine.tenart@free-electrons.com>
References: <1438248201-29222-1-git-send-email-antoine.tenart@free-electrons.com>
 <1438248201-29222-2-git-send-email-antoine.tenart@free-electrons.com>
Message-ID: <55C8FE96.8080705@gmail.com>

On 30.07.2015 11:23, Antoine Tenart wrote:
> Add a PWM controller driver for the Marvell Berlin SoCs. This PWM
> controller has 4 channels.
>
> Signed-off-by: Antoine Tenart <antoine.tenart at free-electrons.com>

Antoine,

thanks for providing these patches, some comments below.

> ---
>   drivers/pwm/Kconfig      |   9 +++
>   drivers/pwm/Makefile     |   1 +
>   drivers/pwm/pwm-berlin.c | 207 +++++++++++++++++++++++++++++++++++++++++++++++
>   3 files changed, 217 insertions(+)
>   create mode 100644 drivers/pwm/pwm-berlin.c
>
> diff --git a/drivers/pwm/Kconfig b/drivers/pwm/Kconfig
> index b1541f40fd8d..1773da8145b8 100644
> --- a/drivers/pwm/Kconfig
> +++ b/drivers/pwm/Kconfig
> @@ -92,6 +92,15 @@ config PWM_BCM2835
>   	  To compile this driver as a module, choose M here: the module
>   	  will be called pwm-bcm2835.
>
> +config PWM_BERLIN
> +	tristate "Berlin PWM support"
> +	depends on ARCH_BERLIN
> +	help
> +	  PWM framework driver for Berlin.
> +
> +	  To compile this driver as a module, choose M here: the module
> +	  will be called pwm-berlin.
> +
>   config PWM_BFIN
>   	tristate "Blackfin PWM support"
>   	depends on BFIN_GPTIMERS
> diff --git a/drivers/pwm/Makefile b/drivers/pwm/Makefile
> index ec50eb5b5a8f..670c5fce8bbb 100644
> --- a/drivers/pwm/Makefile
> +++ b/drivers/pwm/Makefile
> @@ -6,6 +6,7 @@ obj-$(CONFIG_PWM_ATMEL_HLCDC_PWM)	+= pwm-atmel-hlcdc.o
>   obj-$(CONFIG_PWM_ATMEL_TCB)	+= pwm-atmel-tcb.o
>   obj-$(CONFIG_PWM_BCM_KONA)	+= pwm-bcm-kona.o
>   obj-$(CONFIG_PWM_BCM2835)	+= pwm-bcm2835.o
> +obj-$(CONFIG_PWM_BERLIN)	+= pwm-berlin.o
>   obj-$(CONFIG_PWM_BFIN)		+= pwm-bfin.o
>   obj-$(CONFIG_PWM_CLPS711X)	+= pwm-clps711x.o
>   obj-$(CONFIG_PWM_EP93XX)	+= pwm-ep93xx.o
> diff --git a/drivers/pwm/pwm-berlin.c b/drivers/pwm/pwm-berlin.c
> new file mode 100644
> index 000000000000..786990c1c750
> --- /dev/null
> +++ b/drivers/pwm/pwm-berlin.c
> @@ -0,0 +1,207 @@
> +/*
> + * Marvell Berlin PWM driver
> + *
> + * Copyright (C) 2015 Marvell Technology Group Ltd.
> + *
> + * Antoine Tenart <antoine.tenart at free-electrons.com>
> + *
> + * This file is licensed under the terms of the GNU General Public
> + * License version 2. This program is licensed "as is" without any
> + * warranty of any kind, whether express or implied.
> + */
> +
> +#include <linux/io.h>
> +#include <linux/kernel.h>
> +#include <linux/module.h>
> +#include <linux/platform_device.h>
> +#include <linux/pwm.h>
> +#include <linux/spinlock.h>
> +
> +#define BERLIN_PWM_EN			0x0
> +#define BERLIN_PWM_CONTROL		0x4
> +#define BERLIN_PWM_DUTY			0x8
> +#define BERLIN_PWM_TCNT			0xc
> +
> +#define BERLIN_PWM_CLK_RATE		100000000
> +#define BERLIN_PWM_PRESCALE_MASK	0x7
> +#define BERLIN_PWM_PRESCALE_MAX		4096

As Jisheng already pointed out: please use a DT provided
input clock to the PWM driver.

> +
> +struct berlin_pwm_chip {
> +	struct pwm_chip chip;
> +	void __iomem *base;
> +	spinlock_t lock;
> +};
> +
> +#define to_berlin_pwm_chip(chip)	\
> +	container_of((chip), struct berlin_pwm_chip, chip)
> +
> +#define berlin_pwm_readl(chip, channel, offset)		\
> +	readl((chip)->base + (channel) * 0x10 + offset)
> +#define berlin_pwm_writel(val, chip, channel, offset)	\
> +	writel(val, (chip)->base + (channel) * 0x10 + offset)

In contrast to Jisheng's comment about _relaxed() versions of
readl/writel, I don't really care much. Writing the PWM registers
is everything but timing critical, so I'd also accept the non-relaxed
versions here.

> +static const u32 prescaler_table[] = {
> +	1,
> +	4,
> +	8,
> +	16,
> +	64,
> +	256,
> +	1024,
> +	4096,
> +};
> +
> +static int berlin_pwm_config(struct pwm_chip *chip, struct pwm_device *pwm,
> +			     int duty_ns, int period_ns)
> +{
> +	struct berlin_pwm_chip *berlin_chip = to_berlin_pwm_chip(chip);
> +	int prescale;
> +	u32 val, duty, period;
> +	u64 tmp;
> +
> +	for (prescale = 0; prescale < ARRAY_SIZE(prescaler_table); prescale++) {
> +		tmp = BERLIN_PWM_CLK_RATE;
> +		do_div(tmp, prescaler_table[prescale]);
> +		tmp *= period_ns;
> +		do_div(tmp, NSEC_PER_SEC);
> +
> +		if (tmp - 1 <= BERLIN_PWM_PRESCALE_MAX)
> +			break;
> +	}
> +
> +	if (tmp - 1 > BERLIN_PWM_PRESCALE_MAX)
> +		return -EINVAL;

Something about the </> BERLIN_PWM_PRESCALE_MAX above looks odd to me.
As soon as you multiply with period_ns you cannot compare against
BERLIN_PWM_PRESCALE_MAX anymore as you ignore that there also is a
TCNT register.

How about you calculate _absolute_ (i.e. w/ prescaler and tcnt) min
and max frequencies on probe or here in _config and bail out early
if requested rate is beyond that range. Then you can find the best
prescaler/tcnt combination with (open-coded):

static const u32 prescaler_diff_table[] = {
/*	1, 4, 8, 16, 64, 256, 1024, 4096 */
	1, 4, 2,  2,  4,   4,    4,    4,
};


u64 cycles;

// assume period_ns = 2500000 (2.5ms for 400Hz)
cycles = clk_get_rate(clk);   // cycles = 100000000 (100MHz)
cycles *= ns_period;          // cycles = 100000000 * 2500000
                               //        = 250 * 10^12
do_div(cycles, NSEC_PER_SEC)  // cycles = 250000

prescale = 0;
while (cycles > BERLIN_PWM_MAX_TCNT)
	do_div(cycles, prescaler_diff_table[++prescale]);

And so on...

Also, it would be nice to have the PWM output frequency
function written down in a comment, e.g.

/*
  * fOUT = fREF / PRESCALE / (TCNT+1)
  * or
  * TCNT = (fOUT * PRESCALE / fREF) - 1
  * and
  * DUTY = duty * TCNT
  */

or something more appropriate.

> +	period = tmp;
> +	tmp *= duty_ns;
> +	do_div(tmp, period_ns);
> +	duty = tmp;
> +
> +	spin_lock(&berlin_chip->lock);

AFAIKS, Jisheng is right about the spin_lock - if the pwm registers
are separate for the different channels you shouldn't need any spinlock
at all - BUT from Documentation/pwm.txt, I read:

"""
Currently the PWM core does not enforce any locking to pwm_enable(),
pwm_disable() and pwm_config(), so the calling context is currently
driver specific. This is an issue derived from the former barebone API
and should be fixed soon.
"""

So, as long as this is not fixed, I suggest to keep the spinlocks - or
wait for Thierry to rule about it.

> +	val = berlin_pwm_readl(berlin_chip, pwm->hwpwm, BERLIN_PWM_CONTROL);
> +	val &= ~BERLIN_PWM_PRESCALE_MASK;
> +	val |= prescale;
> +	berlin_pwm_writel(val, berlin_chip, pwm->hwpwm, BERLIN_PWM_CONTROL);
> +
> +	berlin_pwm_writel(duty, berlin_chip, pwm->hwpwm, BERLIN_PWM_DUTY);
> +	berlin_pwm_writel(period, berlin_chip, pwm->hwpwm, BERLIN_PWM_TCNT);

For the above calculations to make sense, you'll need the max allowed
TCNT/DUTY values. If you cannot derive them from any DS/BSP, you can try
to writel((u32)-1, TCNT) and read-back the result. Usually that should
give you the max allowed value for that register.

> +	spin_unlock(&berlin_chip->lock);
> +
> +	return 0;
> +}
> +
> +static int berlin_pwm_set_polarity(struct pwm_chip *chip,
> +				   struct pwm_device *pwm,
> +				   enum pwm_polarity polarity)
> +{
> +	struct berlin_pwm_chip *berlin_chip = to_berlin_pwm_chip(chip);
> +	u32 val;
> +
> +	spin_lock(&berlin_chip->lock);
> +
> +	val = berlin_pwm_readl(berlin_chip, pwm->hwpwm, BERLIN_PWM_CONTROL);
> +
> +	if (polarity == PWM_POLARITY_NORMAL)
> +		val &= ~BIT(3);
> +	else
> +		val |= BIT(3);

Please use some meaningful name for BIT(3).

> +
> +	berlin_pwm_writel(val, berlin_chip, pwm->hwpwm, BERLIN_PWM_CONTROL);
> +
> +	spin_unlock(&berlin_chip->lock);
> +
> +	return 0;
> +}
> +
> +static int berlin_pwm_enable(struct pwm_chip *chip, struct pwm_device *pwm)
> +{
> +	struct berlin_pwm_chip *berlin_chip = to_berlin_pwm_chip(chip);
> +
> +	spin_lock(&berlin_chip->lock);
> +	berlin_pwm_writel(0x1, berlin_chip, pwm->hwpwm, BERLIN_PWM_EN);

ditto for 0x1 or BIT(0)

> +	spin_unlock(&berlin_chip->lock);
> +
> +	return 0;
> +}
> +
> +static void berlin_pwm_disable(struct pwm_chip *chip, struct pwm_device *pwm)
> +{
> +	struct berlin_pwm_chip *berlin_chip = to_berlin_pwm_chip(chip);
> +
> +	spin_lock(&berlin_chip->lock);
> +	berlin_pwm_writel(0x0, berlin_chip, pwm->hwpwm, BERLIN_PWM_EN);

ditto.

The rest looks fine to me.

Sebastian

> +	spin_unlock(&berlin_chip->lock);
> +}
> +
> +static const struct pwm_ops berlin_pwm_ops = {
> +	.config = berlin_pwm_config,
> +	.set_polarity = berlin_pwm_set_polarity,
> +	.enable = berlin_pwm_enable,
> +	.disable = berlin_pwm_disable,
> +	.owner = THIS_MODULE,
> +};
> +
> +static const struct of_device_id berlin_pwm_match[] = {
> +	{ .compatible = "marvell,berlin-pwm" },
> +	{ },
> +};
> +MODULE_DEVICE_TABLE(of, berlin_pwm_match);
> +
> +static int berlin_pwm_probe(struct platform_device *pdev)
> +{
> +	struct berlin_pwm_chip *pwm;
> +	struct resource *res;
> +	int ret;
> +
> +	pwm = devm_kzalloc(&pdev->dev, sizeof(*pwm), GFP_KERNEL);
> +	if (!pwm)
> +		return -ENOMEM;
> +
> +	res = platform_get_resource(pdev, IORESOURCE_MEM, 0);
> +	pwm->base = devm_ioremap_resource(&pdev->dev, res);
> +	if (IS_ERR(pwm->base))
> +		return PTR_ERR(pwm->base);
> +
> +	pwm->chip.dev = &pdev->dev;
> +	pwm->chip.ops = &berlin_pwm_ops;
> +	pwm->chip.base = -1;
> +	pwm->chip.npwm = 4;
> +	pwm->chip.can_sleep = true;
> +	pwm->chip.of_xlate = of_pwm_xlate_with_flags;
> +	pwm->chip.of_pwm_n_cells = 3;
> +
> +	spin_lock_init(&pwm->lock);
> +
> +	ret = pwmchip_add(&pwm->chip);
> +	if (ret < 0) {
> +		dev_err(&pdev->dev, "Failed to add PWM chip: %d\n", ret);
> +		return ret;
> +	}
> +
> +	platform_set_drvdata(pdev, pwm);
> +
> +	return 0;
> +}
> +
> +static int berlin_pwm_remove(struct platform_device *pdev)
> +{
> +	struct berlin_pwm_chip *pwm = platform_get_drvdata(pdev);
> +
> +	return pwmchip_remove(&pwm->chip);
> +}
> +
> +static struct platform_driver berlin_pwm_driver = {
> +	.probe	= berlin_pwm_probe,
> +	.remove	= berlin_pwm_remove,
> +	.driver	= {
> +		.name	= "berlin-pwm",
> +		.of_match_table = berlin_pwm_match,
> +	},
> +};
> +module_platform_driver(berlin_pwm_driver);
> +
> +MODULE_AUTHOR("Antoine Tenart <antoine.tenart at free-electrons.com>");
> +MODULE_DESCRIPTION("Marvell Berlin PWM driver");
> +MODULE_LICENSE("GPL v2");
>



From sebastian.hesselbarth at gmail.com  Mon Aug 10 12:51:44 2015
From: sebastian.hesselbarth at gmail.com (Sebastian Hesselbarth)
Date: Mon, 10 Aug 2015 21:51:44 +0200
Subject: [PATCH v2 4/5] ARM: berlin: add a PWM node on the BG2
In-Reply-To: <1438248201-29222-5-git-send-email-antoine.tenart@free-electrons.com>
References: <1438248201-29222-1-git-send-email-antoine.tenart@free-electrons.com>
 <1438248201-29222-5-git-send-email-antoine.tenart@free-electrons.com>
Message-ID: <55C900D0.9060606@gmail.com>

On 30.07.2015 11:23, Antoine Tenart wrote:
> This patch adds a PWM node in the Berlin BG2 device tree, using the
> newly added Berlin PWM driver.
>
> Signed-off-by: Antoine Tenart <antoine.tenart at free-electrons.com>
> ---
>   arch/arm/boot/dts/berlin2.dtsi | 6 ++++++
>   1 file changed, 6 insertions(+)
>
> diff --git a/arch/arm/boot/dts/berlin2.dtsi b/arch/arm/boot/dts/berlin2.dtsi
> index ef811de09908..e17bd5faed27 100644
> --- a/arch/arm/boot/dts/berlin2.dtsi
> +++ b/arch/arm/boot/dts/berlin2.dtsi
> @@ -512,5 +512,11 @@
>   				interrupts = <GIC_SPI 15 IRQ_TYPE_LEVEL_HIGH>;
>   			};
>   		};
> +
> +		pwm: pwm at f20000 {
> +			compatible = "marvell,berlin-pwm";
> +			reg = <0xf20000 0x40>;
> +			#pwm-cells = <3>;
> +		};

I only checked berlin2.dtsi:
The top most line with <GIC_SPI 15 ...> belongs to a sub-node of
apb at fc0000 - which means that the pwm node isn't sorted in by
address. Please sort the nodes by address in all three DT patches.

BTW, is there any IRQ from the PWM IP routed to any intc upstream?
A quick look into some BSP code does not reveal any hints maybe
one of the Marvell guys can comment on it.

Sebastian

>   	};
>   };
>



From sebastian.hesselbarth at gmail.com  Mon Aug 10 12:55:16 2015
From: sebastian.hesselbarth at gmail.com (Sebastian Hesselbarth)
Date: Mon, 10 Aug 2015 21:55:16 +0200
Subject: [PATCH 1/3] clk: berlin: add cpuclk
In-Reply-To: <1438259752-16320-2-git-send-email-antoine.tenart@free-electrons.com>
References: <1438259752-16320-1-git-send-email-antoine.tenart@free-electrons.com>
 <1438259752-16320-2-git-send-email-antoine.tenart@free-electrons.com>
Message-ID: <55C901A4.4050605@gmail.com>

On 30.07.2015 14:35, Antoine Tenart wrote:
> Add cpuclk in the Berlin BG2Q clock driver. This clk has a divider
> fixed to 1.
>
> Signed-off-by: Antoine Tenart <antoine.tenart at free-electrons.com>
> ---
>   drivers/clk/berlin/bg2q.c            | 14 +++++++-------
>   include/dt-bindings/clock/berlin2q.h |  3 ++-
>   2 files changed, 9 insertions(+), 8 deletions(-)
>
> diff --git a/drivers/clk/berlin/bg2q.c b/drivers/clk/berlin/bg2q.c
> index 221f40c2b850..72d2f3500db8 100644
> --- a/drivers/clk/berlin/bg2q.c
> +++ b/drivers/clk/berlin/bg2q.c
> @@ -45,7 +45,7 @@
>   #define REG_SDIO0XIN_CLKCTL	0x0158
>   #define REG_SDIO1XIN_CLKCTL	0x015c
>
> -#define	MAX_CLKS 27
> +#define	MAX_CLKS 28

Following Stephen's suggesting, how about moving this to the
dt-bindings include?

>   static struct clk *clks[MAX_CLKS];
>   static struct clk_onecell_data clk_data;
>   static DEFINE_SPINLOCK(lock);
> @@ -356,13 +356,13 @@ static void __init berlin2q_clock_setup(struct device_node *np)
>   			    gd->bit_idx, 0, &lock);
>   	}
>
> -	/*
> -	 * twdclk is derived from cpu/3
> -	 * TODO: use cpupll until cpuclk is not available
> -	 */
> +	/* cpuclk divider is fixed to 1 */
> +	clks[CLKID_CPU] =
> +		clk_register_fixed_factor(NULL, "cpu", clk_names[CPUPLL],
> +					  0, 1, 1);
> +	/* twdclk is derived from cpu/3 */
>   	clks[CLKID_TWD] =
> -		clk_register_fixed_factor(NULL, "twd", clk_names[CPUPLL],
> -					  0, 1, 3);
> +		clk_register_fixed_factor(NULL, "twd", "cpu", 0, 1, 3);
>
>   	/* check for errors on leaf clocks */
>   	for (n = 0; n < MAX_CLKS; n++) {
> diff --git a/include/dt-bindings/clock/berlin2q.h b/include/dt-bindings/clock/berlin2q.h
> index 287fc3b4afb2..a80c3272794d 100644
> --- a/include/dt-bindings/clock/berlin2q.h
> +++ b/include/dt-bindings/clock/berlin2q.h
> @@ -28,4 +28,5 @@
>   #define CLKID_NFC		23
>   #define CLKID_SMEMC		24
>   #define CLKID_PCIE		25
> -#define CLKID_TWD		26
> +#define CLKID_CPU		26
> +#define CLKID_TWD		27

Is there any good reason to brake existing dts[i] by moving TWD to 27
instead of adding CPU as 27?

Sebastian


From lho at apm.com  Mon Aug 10 13:15:49 2015
From: lho at apm.com (Loc Ho)
Date: Mon, 10 Aug 2015 13:15:49 -0700
Subject: [PATCH v2 0/3] edac: Add L3/SoC support to the APM X-Gene SoC
 EDAC driver
In-Reply-To: <CALdTtnv7P5d0Y6wyKe1SOqXedNhQxMsFZY=m-rxK3zouLcFv-Q@mail.gmail.com>
References: <1437808063-17592-1-git-send-email-lho@apm.com>
 <CALdTtnv7P5d0Y6wyKe1SOqXedNhQxMsFZY=m-rxK3zouLcFv-Q@mail.gmail.com>
Message-ID: <CAPw-ZT=9Eq0yc7tzqJAdCvsQTgRkMmGzNOSXgawBTY0gAijr4Q@mail.gmail.com>

Hi Dann,

>> v2:
>> * Update binding documentation accordingly
>> * Change all single bit defines to BIT(x)
>> * Add support for L3 version 1 and 2 HW's
>> * Change to use debug file system for error injection
>> * In L3/SoC instance add function, allocate EDAC context after all
>>   initalization successed
>> * Support raw or detail info for SoC EDAC error reporting
>>
>> v1:
>> * Add L3/SoC support to the APM X-Gene SoC EDAC driver
>
> Loc,
>   I tested 4.2-rc5 on a Mustang board with one DIMM, and it hangs (RCU
> stall) in xgene_edac_mc_irq_ctl() on modprobe. Same board with 2 DIMMs
> boots fine. (U-boot 1.15.12).

I just removed one of the two 16GB DIMM... with 4.2.0-rc1 and some
code clean up in EDAC driver, it boots just fine... I don't believe
the code clean up would affect it. Do you have the dump log?

[root at dhcp-10-76-213-247 ~]# uname -a
Linux dhcp-10-76-213-247 4.2.0-rc1+ #33 SMP PREEMPT Mon Aug 10
13:23:03 MDT 2015 aarch64 GNU/Linux

-Loc


From sebastian.hesselbarth at gmail.com  Mon Aug 10 13:22:44 2015
From: sebastian.hesselbarth at gmail.com (Sebastian Hesselbarth)
Date: Mon, 10 Aug 2015 22:22:44 +0200
Subject: [PATCH 2/3] ARM: berlin: register cpufreq-dt for the BG2Q
In-Reply-To: <20150731141602.28b28f21@xhacker>
References: <1438259752-16320-1-git-send-email-antoine.tenart@free-electrons.com>
 <1438259752-16320-3-git-send-email-antoine.tenart@free-electrons.com>
 <20150731141602.28b28f21@xhacker>
Message-ID: <55C90814.3050505@gmail.com>

On 31.07.2015 08:16, Jisheng Zhang wrote:
> On Thu, 30 Jul 2015 14:35:51 +0200
> Antoine Tenart <antoine.tenart at free-electrons.com> wrote:
>
>> The BG2Q SoC uses cpufreq-dt for cpufreq. Register a platform device for
>> this.
>>
>> Signed-off-by: Antoine Tenart <antoine.tenart at free-electrons.com>
>> ---
[...]
>> diff --git a/arch/arm/mach-berlin/berlin.c b/arch/arm/mach-berlin/berlin.c
>> index ac181c6797ee..0de906374994 100644
>> --- a/arch/arm/mach-berlin/berlin.c
>> +++ b/arch/arm/mach-berlin/berlin.c
>> @@ -15,9 +15,21 @@
[...]
>> +static void __init berlin_init_late(void)
>> +{
>> +	if (of_find_matching_node(NULL, berlin2q_match))
>> +		platform_device_register_simple("cpufreq-dt", -1, NULL, 0);
>
> I'm not sure is it acceptable to always register cpufreq-dt platform device.
> In cpufreq-dt driver, the probe will exit if there's no cpuclk node.

Jisheng,

registering the _device_ without checking for any requirements of
the _driver_ is usual practice. It it the driver's job to check
all of them and report an error or warning. So, I am fine with
adding the device unconditionally.

Using the .init_late() callback seems reasonable - but can you
evaluate if we can have cpufreq-dt also for BG2/BG2CD? I'd also
accept a single, default operating-point.

BTW, there is one true point about Jisheng's comment: try to order
your patches logically correct to avoid unnecessary warnings, i.e.

1/3 add cpuclk
2/3 add cpufreq-dt properties
3/3 register cpufreq-dt device

If you consider a git-bisect run, you can land in between any of the
three patches but they are always in the above order - so ordering is
important.

Sebastian

>> +}
>> +
>>   static const char * const berlin_dt_compat[] = {
>>   	"marvell,berlin",
>>   	NULL,
>> @@ -25,6 +37,7 @@ static const char * const berlin_dt_compat[] = {
>>
>>   DT_MACHINE_START(BERLIN_DT, "Marvell Berlin")
>>   	.dt_compat	= berlin_dt_compat,
>> +	.init_late	= berlin_init_late,
>>   	/*
>>   	 * with DT probing for L2CCs, berlin_init_machine can be removed.
>>   	 * Note: 88DE3005 (Armada 1500-mini) uses pl310 l2cc
>



From dinguyen at opensource.altera.com  Mon Aug 10 14:09:18 2015
From: dinguyen at opensource.altera.com (dinguyen at opensource.altera.com)
Date: Mon, 10 Aug 2015 16:09:18 -0500
Subject: [PATCH] arm64: dts: Add base stratix 10 dtsi
Message-ID: <1439240958-4713-1-git-send-email-dinguyen@opensource.altera.com>

From: Dinh Nguyen <dinguyen at opensource.altera.com>

Add the base DTS for Altera's SoCFPGA Stratix 10 platform.

Signed-off-by: Dinh Nguyen <dinguyen at opensource.altera.com>
---
 arch/arm64/Kconfig                                 |   5 +
 arch/arm64/boot/dts/Makefile                       |   1 +
 arch/arm64/boot/dts/altera/Makefile                |   5 +
 arch/arm64/boot/dts/altera/socfpga_stratix10.dtsi  | 354 +++++++++++++++++++++
 .../boot/dts/altera/socfpga_stratix10_socdk.dts    |  38 +++
 arch/arm64/configs/defconfig                       |   1 +
 6 files changed, 404 insertions(+)
 create mode 100644 arch/arm64/boot/dts/altera/Makefile
 create mode 100644 arch/arm64/boot/dts/altera/socfpga_stratix10.dtsi
 create mode 100644 arch/arm64/boot/dts/altera/socfpga_stratix10_socdk.dts

diff --git a/arch/arm64/Kconfig b/arch/arm64/Kconfig
index 318175f..0f8ab2b 100644
--- a/arch/arm64/Kconfig
+++ b/arch/arm64/Kconfig
@@ -207,6 +207,11 @@ config ARCH_SEATTLE
 	help
 	  This enables support for AMD Seattle SOC Family
 
+config ARCH_STRATIX10
+	bool "Altera's Stratix 10 SoCFPGA Family"
+	help
+	  This enables support for Altera's Stratix 10 SoCFPGA Family
+
 config ARCH_TEGRA
 	bool "NVIDIA Tegra SoC Family"
 	select ARCH_HAS_RESET_CONTROLLER
diff --git a/arch/arm64/boot/dts/Makefile b/arch/arm64/boot/dts/Makefile
index 38913be..7fb421a 100644
--- a/arch/arm64/boot/dts/Makefile
+++ b/arch/arm64/boot/dts/Makefile
@@ -1,3 +1,4 @@
+dts-dirs += altera
 dts-dirs += amd
 dts-dirs += apm
 dts-dirs += arm
diff --git a/arch/arm64/boot/dts/altera/Makefile b/arch/arm64/boot/dts/altera/Makefile
new file mode 100644
index 0000000..d7a6416
--- /dev/null
+++ b/arch/arm64/boot/dts/altera/Makefile
@@ -0,0 +1,5 @@
+dtb-$(CONFIG_ARCH_STRATIX10) += socfpga_stratix10_socdk.dtb
+
+always		:= $(dtb-y)
+subdir-y	:= $(dts-dirs)
+clean-files	:= *.dtb
diff --git a/arch/arm64/boot/dts/altera/socfpga_stratix10.dtsi b/arch/arm64/boot/dts/altera/socfpga_stratix10.dtsi
new file mode 100644
index 0000000..34f6dc3
--- /dev/null
+++ b/arch/arm64/boot/dts/altera/socfpga_stratix10.dtsi
@@ -0,0 +1,354 @@
+/*
+ * Copyright Altera Corporation (C) 2015. All rights reserved.
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms and conditions of the GNU General Public License,
+ * version 2, as published by the Free Software Foundation.
+ *
+ * This program is distributed in the hope 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.
+ *
+ * You should have received a copy of the GNU General Public License along with
+ * this program.  If not, see <http://www.gnu.org/licenses/>.
+ */
+
+/dts-v1/;
+
+/ {
+	compatible = "altr,socfpga-stratix10";
+	#address-cells = <1>;
+	#size-cells = <1>;
+
+	cpus {
+		#address-cells = <1>;
+		#size-cells = <0>;
+
+		cpu at 0 {
+			compatible = "arm,cortex-a53", "arm,armv8";
+			device_type = "cpu";
+			enable-method = "psci";
+			reg = <0x0>;
+		};
+
+		cpu at 1 {
+			compatible = "arm,cortex-a53", "arm,armv8";
+			device_type = "cpu";
+			enable-method = "psci";
+			reg = <0x1>;
+		};
+
+		cpu at 2 {
+			compatible = "arm,cortex-a53", "arm,armv8";
+			device_type = "cpu";
+			enable-method = "psci";
+			reg = <0x2>;
+		};
+
+		cpu at 3 {
+			compatible = "arm,cortex-a53", "arm,armv8";
+			device_type = "cpu";
+			enable-method = "psci";
+			reg = <0x3>;
+		};
+	};
+
+	pmu {
+		compatible = "arm,armv8-pmuv3";
+		interrupts = <0 120 8>,
+			     <0 121 8>,
+			     <0 122 8>,
+			     <0 123 8>;
+	};
+
+	psci {
+		compatible = "arm,psci-0.2";
+		method = "smc";
+	};
+
+	intc: intc at ffff8000 {
+		compatible = "arm,gic-400", "arm,cortex-a15-gic";
+		#interrupt-cells = <3>;
+		interrupt-controller;
+		reg = <0x0 0xffff9000 0x1000>,
+		      <0x0 0xffffa000 0x2000>,
+		      <0x0 0xffffc000 0x1000>,
+		      <0x0 0xffffd000 0x1000>;
+	};
+
+	soc {
+		#address-cells = <1>;
+		#size-cells = <1>;
+		compatible = "simple-bus";
+		device_type = "soc";
+		interrupt-parent = <&intc>;
+		ranges;
+
+		clkmgr at ffd1000 {
+			compatible = "altr,clk-mgr";
+			reg = <0xffd10000 0x1000>;
+		};
+
+		gmac0: ethernet at ff800000 {
+			compatible = "altr,socfpga-stmmac", "snps,dwmac-3.74a", "snps,dwmac";
+			reg = <0xff800000 0x2000>;
+			interrupts = <0 90 4>;
+			interrupt-names = "macirq";
+			mac-address = [00 00 00 00 00 00];
+			status = "disabled";
+		};
+
+		gmac1: ethernet at ff802000 {
+			compatible = "altr,socfpga-stmmac", "snps,dwmac-3.74a", "snps,dwmac";
+			reg = <0xff802000 0x2000>;
+			interrupts = <0 91 4>;
+			interrupt-names = "macirq";
+			mac-address = [00 00 00 00 00 00];
+			status = "disabled";
+		};
+
+		gmac2: ethernet at ff804000 {
+			compatible = "altr,socfpga-stmmac", "snps,dwmac-3.74a", "snps,dwmac";
+			reg = <0xff804000 0x2000>;
+			interrupts = <0 92 4>;
+			interrupt-names = "macirq";
+			mac-address = [00 00 00 00 00 00];
+			status = "disabled";
+		};
+
+		gpio0: gpio at ffc03200 {
+			#address-cells = <1>;
+			#size-cells = <0>;
+			compatible = "snps,dw-apb-gpio";
+			reg = <0xffc03200 0x100>;
+			status = "disabled";
+
+			porta: gpio-controller at 0 {
+				compatible = "snps,dw-apb-gpio-port";
+				gpio-controller;
+				#gpio-cells = <2>;
+				snps,nr-gpios = <24>;
+				reg = <0>;
+				interrupt-controller;
+				#interrupt-cells = <2>;
+				interrupts = <0 110 4>;
+			};
+		};
+
+		gpio1: gpio at ffc03300 {
+			#address-cells = <1>;
+			#size-cells = <0>;
+			compatible = "snps,dw-apb-gpio";
+			reg = <0xffc03300 0x100>;
+			status = "disabled";
+
+			portb: gpio-controller at 0 {
+				compatible = "snps,dw-apb-gpio-port";
+				gpio-controller;
+				#gpio-cells = <2>;
+				snps,nr-gpios = <24>;
+				reg = <0>;
+				interrupt-controller;
+				#interrupt-cells = <2>;
+				interrupts = <0 110 4>;
+			};
+		};
+
+		i2c0: i2c at ffc02800 {
+			#address-cells = <1>;
+			#size-cells = <0>;
+			compatible = "snps,designware-i2c";
+			reg = <0xffc02800 0x100>;
+			interrupts = <0 103 4>;
+			status = "disabled";
+		};
+
+		i2c1: i2c at ffc02900 {
+			#address-cells = <1>;
+			#size-cells = <0>;
+			compatible = "snps,designware-i2c";
+			reg = <0xffc02900 0x100>;
+			interrupts = <0 104 4>;
+			status = "disabled";
+		};
+
+		i2c2: i2c at ffc02a00 {
+			#address-cells = <1>;
+			#size-cells = <0>;
+			compatible = "snps,designware-i2c";
+			reg = <0xffc02a00 0x100>;
+			interrupts = <0 105 4>;
+			status = "disabled";
+		};
+
+		i2c3: i2c at ffc02b00 {
+			#address-cells = <1>;
+			#size-cells = <0>;
+			compatible = "snps,designware-i2c";
+			reg = <0xffc02b00 0x100>;
+			interrupts = <0 106 4>;
+			status = "disabled";
+		};
+
+		i2c4: i2c at ffc02c00 {
+			#address-cells = <1>;
+			#size-cells = <0>;
+			compatible = "snps,designware-i2c";
+			reg = <0xffc02c00 0x100>;
+			interrupts = <0 107 4>;
+			status = "disabled";
+		};
+
+		mmc: dwmmc0 at ff808000 {
+			#address-cells = <1>;
+			#size-cells = <0>;
+			compatible = "altr,socfpga-dw-mshc";
+			reg = <0xff808000 0x1000>;
+			interrupts = <0 96 4>;
+			fifo-depth = <0x400>;
+			status = "disabled";
+		};
+
+		ocram: sram at ffe00000 {
+			compatible = "mmio-sram";
+			reg = <0xffe00000 0x100000>;
+		};
+
+		rst: rstmgr at ffd11000 {
+			#reset-cells = <1>;
+			compatible = "altr,rst-mgr";
+			reg = <0xffd11000 0x1000>;
+		};
+
+		spi0: spi at ffda4000 {
+			compatible = "snps,dw-apb-ssi";
+			#address-cells = <1>;
+			#size-cells = <0>;
+			reg = <0xffda4000 0x1000>;
+			interrupts = <0 101 4>;
+			num-chipselect = <4>;
+			bus-num = <0>;
+			status = "disabled";
+		};
+
+		spi1: spi at ffda5000 {
+			compatible = "snps,dw-apb-ssi";
+			#address-cells = <1>;
+			#size-cells = <0>;
+			reg = <0xffda5000 0x1000>;
+			interrupts = <0 102 4>;
+			num-chipselect = <4>;
+			bus-num = <0>;
+			status = "disabled";
+		};
+
+		sysmgr: sysmgr at ffd12000 {
+			compatible = "altr,sys-mgr", "syscon";
+			reg = <0xffd12000 0x1000>;
+		};
+
+		/* Local timer */
+		timer {
+			compatible = "arm,armv8-timer";
+			interrupts = <1 13 0xf01>,
+				     <1 14 0xf01>,
+				     <1 11 0xf01>,
+				     <1 10 0xf01>;
+		};
+
+		timer0: timer0 at ffc03000 {
+			compatible = "snps,dw-apb-timer";
+			interrupts = <0 113 4>;
+			reg = <0xffc03000 0x100>;
+		};
+
+		timer1: timer1 at ffc03100 {
+			compatible = "snps,dw-apb-timer";
+			interrupts = <0 114 4>;
+			reg = <0xffc03100 0x100>;
+		};
+
+		timer2: timer2 at ffd00000 {
+			compatible = "snps,dw-apb-timer";
+			interrupts = <0 115 4>;
+			reg = <0xffd00000 0x100>;
+		};
+
+		timer3: timer3 at ffd00100 {
+			compatible = "snps,dw-apb-timer";
+			interrupts = <0 116 4>;
+			reg = <0xffd00100 0x100>;
+		};
+
+		uart0: serial0 at ffc02000 {
+			compatible = "snps,dw-apb-uart";
+			reg = <0xffc02000 0x100>;
+			interrupts = <0 108 4>;
+			reg-shift = <2>;
+			reg-io-width = <4>;
+			status = "disabled";
+		};
+
+		uart1: serial1 at ffc02100 {
+			compatible = "snps,dw-apb-uart";
+			reg = <0xffc02100 0x100>;
+			interrupts = <0 109 4>;
+			reg-shift = <2>;
+			reg-io-width = <4>;
+			status = "disabled";
+		};
+
+		usbphy0: usbphy at 0 {
+			#phy-cells = <0>;
+			compatible = "usb-nop-xceiv";
+			status = "okay";
+		};
+
+		usb0: usb at ffb00000 {
+			compatible = "snps,dwc2";
+			reg = <0xffb00000 0x40000>;
+			interrupts = <0 93 4>;
+			phys = <&usbphy0>;
+			phy-names = "usb2-phy";
+			status = "disabled";
+		};
+
+		usb1: usb at ffb40000 {
+			compatible = "snps,dwc2";
+			reg = <0xffb40000 0x40000>;
+			interrupts = <0 94 4>;
+			phys = <&usbphy0>;
+			phy-names = "usb2-phy";
+			status = "disabled";
+		};
+
+		watchdog0: watchdog at ffd00200 {
+			compatible = "snps,dw-wdt";
+			reg = <0xffd00200 0x100>;
+			interrupts = <0 117 4>;
+			status = "disabled";
+		};
+
+		watchdog1: watchdog at ffd00300 {
+			compatible = "snps,dw-wdt";
+			reg = <0xffd00300 0x100>;
+			interrupts = <0 118 4>;
+			status = "disabled";
+		};
+
+		watchdog2: watchdog at ffd00400 {
+			compatible = "snps,dw-wdt";
+			reg = <0xffd00400 0x100>;
+			interrupts = <0 125 4>;
+			status = "disabled";
+		};
+
+		watchdog3: watchdog at ffd00500 {
+			compatible = "snps,dw-wdt";
+			reg = <0xffd00500 0x100>;
+			interrupts = <0 126 4>;
+			status = "disabled";
+		};
+	};
+};
diff --git a/arch/arm64/boot/dts/altera/socfpga_stratix10_socdk.dts b/arch/arm64/boot/dts/altera/socfpga_stratix10_socdk.dts
new file mode 100644
index 0000000..8b162ef
--- /dev/null
+++ b/arch/arm64/boot/dts/altera/socfpga_stratix10_socdk.dts
@@ -0,0 +1,38 @@
+/*
+ * Copyright Altera Corporation (C) 2015. All rights reserved.
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms and conditions of the GNU General Public License,
+ * version 2, as published by the Free Software Foundation.
+ *
+ * This program is distributed in the hope 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.
+ *
+ * You should have received a copy of the GNU General Public License along with
+ * this program.  If not, see <http://www.gnu.org/licenses/>.
+ */
+
+/include/ "socfpga_stratix10.dtsi"
+
+/ {
+	model = "SoCFPGA Stratix 10 SoCDK";
+
+	aliases {
+		serial0 = &uart0;
+	};
+
+	chosen {
+		stdout-path = "serial0:115200n8";
+	};
+
+	memory {
+		device_type = "memory";
+		reg = <0x0 0x40000000>;
+	};
+};
+
+&uart0 {
+	status = "okay";
+};
diff --git a/arch/arm64/configs/defconfig b/arch/arm64/configs/defconfig
index 4e17e7e..ad3b636 100644
--- a/arch/arm64/configs/defconfig
+++ b/arch/arm64/configs/defconfig
@@ -36,6 +36,7 @@ CONFIG_ARCH_FSL_LS2085A=y
 CONFIG_ARCH_HISI=y
 CONFIG_ARCH_MEDIATEK=y
 CONFIG_ARCH_SEATTLE=y
+CONFIG_ARCH_STRATIX10=y
 CONFIG_ARCH_TEGRA=y
 CONFIG_ARCH_TEGRA_132_SOC=y
 CONFIG_ARCH_QCOM=y
-- 
2.4.5



From bhelgaas at google.com  Mon Aug 10 14:39:00 2015
From: bhelgaas at google.com (Bjorn Helgaas)
Date: Mon, 10 Aug 2015 16:39:00 -0500
Subject: [PATCH v5 6/9] PCI: Drop references acquired by of_parse_phandle()
In-Reply-To: <20150804215435.9189.94410.stgit@bhelgaas-glaptop2.roam.corp.google.com>
References: <20150804214234.9189.42548.stgit@bhelgaas-glaptop2.roam.corp.google.com>
 <20150804215435.9189.94410.stgit@bhelgaas-glaptop2.roam.corp.google.com>
Message-ID: <20150810213900.GA9805@google.com>

[+cc Ben, Rob]

On Tue, Aug 04, 2015 at 04:54:35PM -0500, Bjorn Helgaas wrote:
> of_parse_phandle() returns a device_node pointer with the refcount
> incremented.  We should dispose of this reference when we're finished.
> 
> Drop the reference acquired by of_parse_phandle().

I cc'd everybody who wrote or signed off on 0d5a6db3aa46 ("of: pci: add
registry of MSI chips"), which added of_pci_find_msi_chip_by_node().

The existing code (before this patch) looks wrong to me, but I'm not an OF
person.

> Signed-off-by: Bjorn Helgaas <bhelgaas at google.com>
> ---
>  drivers/pci/host/pci-mvebu.c |    1 +
>  drivers/pci/host/pci-xgene.c |    1 +
>  2 files changed, 2 insertions(+)
> 
> diff --git a/drivers/pci/host/pci-mvebu.c b/drivers/pci/host/pci-mvebu.c
> index 70aa095..67ec5e1 100644
> --- a/drivers/pci/host/pci-mvebu.c
> +++ b/drivers/pci/host/pci-mvebu.c
> @@ -879,6 +879,7 @@ static void mvebu_pcie_msi_enable(struct mvebu_pcie *pcie)
>  		return;
>  
>  	pcie->msi = of_pci_find_msi_chip_by_node(msi_node);
> +	of_node_put(msi_node);
>  
>  	if (pcie->msi)
>  		pcie->msi->dev = &pcie->pdev->dev;
> diff --git a/drivers/pci/host/pci-xgene.c b/drivers/pci/host/pci-xgene.c
> index a9dfb70..4c2fb1f 100644
> --- a/drivers/pci/host/pci-xgene.c
> +++ b/drivers/pci/host/pci-xgene.c
> @@ -514,6 +514,7 @@ static int xgene_pcie_msi_enable(struct pci_bus *bus)
>  	if (!bus->msi)
>  		return -ENODEV;
>  
> +	of_node_put(msi_node);
>  	bus->msi->dev = &bus->dev;
>  	return 0;
>  }
> 


From balbi at ti.com  Mon Aug 10 14:41:51 2015
From: balbi at ti.com (Felipe Balbi)
Date: Mon, 10 Aug 2015 16:41:51 -0500
Subject: [RFC/PATCH-v4.2-rc6 5/5] arm: omap2: board-generic: use
 omap4_local_timer_init for AM437x
In-Reply-To: <1439242911-715-1-git-send-email-balbi@ti.com>
References: <1439242911-715-1-git-send-email-balbi@ti.com>
Message-ID: <1439242911-715-6-git-send-email-balbi@ti.com>

AM437x-based boards, can use omap4_local_timer_init()
just fine. Let's use that instead.

Signed-off-by: Felipe Balbi <balbi at ti.com>
---
 arch/arm/mach-omap2/board-generic.c | 2 +-
 1 file changed, 1 insertion(+), 1 deletion(-)

diff --git a/arch/arm/mach-omap2/board-generic.c b/arch/arm/mach-omap2/board-generic.c
index 34ff14b7beab..8acb3b4c84e3 100644
--- a/arch/arm/mach-omap2/board-generic.c
+++ b/arch/arm/mach-omap2/board-generic.c
@@ -279,7 +279,7 @@ DT_MACHINE_START(AM43_DT, "Generic AM43 (Flattened Device Tree)")
 	.init_late	= am43xx_init_late,
 	.init_irq	= omap_gic_of_init,
 	.init_machine	= omap_generic_init,
-	.init_time	= omap3_gptimer_timer_init,
+	.init_time	= omap4_local_timer_init,
 	.dt_compat	= am43_boards_compat,
 	.restart	= omap44xx_restart,
 MACHINE_END
-- 
2.5.0



From balbi at ti.com  Mon Aug 10 14:41:46 2015
From: balbi at ti.com (Felipe Balbi)
Date: Mon, 10 Aug 2015 16:41:46 -0500
Subject: [RFC/PATCH-v4.2-rc6 0/5] arm: am437x: use TWD/Global timers
Message-ID: <1439242911-715-1-git-send-email-balbi@ti.com>

Hi,

with these patches AM437x devices can use TWD/global timers.

At least TWD is now used as sched_clock() which gives better latency as seen
below. Keep in mind that while I ran cyclictest to have a feel for avg latency
this test was not against an RT kernel, so results should be taken with a
grain of salt.

Also, I'm not 100% sure clock rate is correct. According to TRM, this timer
should run as MPU_CLK/2 which would be 1GHz / 2 = 500MHz, but even though
I'm using dpll_mpu_m2_ck clock, it still shows as 1000MHz.

Are there any other tests I could/should run ? BTW, I boot-tested on AM4372
with and without 'nosmp' on cmdline.

pre-patch:
T: 0 (  245) P:95 I:1000 C:   9995 Min:     24 Act:   31 Avg:   36 Max:     596

post-patch:
T: 0 (  253) P:95 I:1000 C:   9995 Min:     10 Act:   12 Avg:   14 Max:      68

Felipe Balbi (5):
  Revert "ARM: 7655/1: smp_twd: make twd_local_timer_of_register() no-op
    for nosmp"
  arm: boot: dts: am4372: add ARM timers and SCU nodes
  arm: omap2: Kconfig: select TWD and global timer on AM43xx devices
  arm: omap2: timer: simplify omap4_local_timer_init()
  arm: omap2: board-generic: use omap4_local_timer_init for AM437x

 arch/arm/boot/dts/am4372.dtsi       | 21 +++++++++++++++++++++
 arch/arm/kernel/smp_twd.c           |  4 ----
 arch/arm/mach-omap2/Kconfig         |  3 +++
 arch/arm/mach-omap2/board-generic.c |  2 +-
 arch/arm/mach-omap2/timer.c         | 16 ++++------------
 5 files changed, 29 insertions(+), 17 deletions(-)

-- 
2.5.0



From balbi at ti.com  Mon Aug 10 14:41:48 2015
From: balbi at ti.com (Felipe Balbi)
Date: Mon, 10 Aug 2015 16:41:48 -0500
Subject: [RFC/PATCH-v4.2-rc6 2/5] arm: boot: dts: am4372: add ARM timers and
 SCU nodes
In-Reply-To: <1439242911-715-1-git-send-email-balbi@ti.com>
References: <1439242911-715-1-git-send-email-balbi@ti.com>
Message-ID: <1439242911-715-3-git-send-email-balbi@ti.com>

AM437x devices sport SCU, TWD and Global timers,
let's add them to DTS so they have a chance to
probe and be used by Linux.

Signed-off-by: Felipe Balbi <balbi at ti.com>
---
 arch/arm/boot/dts/am4372.dtsi | 21 +++++++++++++++++++++
 1 file changed, 21 insertions(+)

diff --git a/arch/arm/boot/dts/am4372.dtsi b/arch/arm/boot/dts/am4372.dtsi
index ade28c790f4b..08bcdc8f0b6f 100644
--- a/arch/arm/boot/dts/am4372.dtsi
+++ b/arch/arm/boot/dts/am4372.dtsi
@@ -59,6 +59,27 @@
 		interrupt-parent = <&gic>;
 	};
 
+	scu: scu at 48240000 {
+		compatible = "arm,cortex-a9-scu";
+		reg = <0x48240000 0x100>;
+	};
+
+	global_timer: timer at 48240200 {
+		compatible = "arm,cortex-a9-global-timer";
+		reg = <0x48240200 0x100>;
+		interrupts = <GIC_PPI 11 IRQ_TYPE_LEVEL_HIGH>;
+		interrupt-parent = <&gic>;
+		clocks = <&dpll_mpu_m2_ck>;
+	};
+
+	local_timer: timer at 48240600 {
+		compatible = "arm,cortex-a9-twd-timer";
+		reg = <0x48240600 0x100>;
+		interrupts = <GIC_PPI 13 IRQ_TYPE_LEVEL_HIGH>;
+		interrupt-parent = <&gic>;
+		clocks = <&dpll_mpu_m2_ck>;
+	};
+
 	l2-cache-controller at 48242000 {
 		compatible = "arm,pl310-cache";
 		reg = <0x48242000 0x1000>;
-- 
2.5.0



From balbi at ti.com  Mon Aug 10 14:41:50 2015
From: balbi at ti.com (Felipe Balbi)
Date: Mon, 10 Aug 2015 16:41:50 -0500
Subject: [RFC/PATCH-v4.2-rc6 4/5] arm: omap2: timer: simplify
 omap4_local_timer_init()
In-Reply-To: <1439242911-715-1-git-send-email-balbi@ti.com>
References: <1439242911-715-1-git-send-email-balbi@ti.com>
Message-ID: <1439242911-715-5-git-send-email-balbi@ti.com>

all users of omap4_local_timer_init() are already
DT-only, so we can remove the check for having
DTB or not.

While at that, fix a typo in comment.

Signed-off-by: Felipe Balbi <balbi at ti.com>
---
 arch/arm/mach-omap2/timer.c | 16 ++++------------
 1 file changed, 4 insertions(+), 12 deletions(-)

diff --git a/arch/arm/mach-omap2/timer.c b/arch/arm/mach-omap2/timer.c
index cac46d852da1..88d39f98e7ff 100644
--- a/arch/arm/mach-omap2/timer.c
+++ b/arch/arm/mach-omap2/timer.c
@@ -649,23 +649,15 @@ static OMAP_SYS_32K_TIMER_INIT(4, 1, "timer_32k_ck", "ti,timer-alwon",
 
 #ifdef CONFIG_ARCH_OMAP4
 #ifdef CONFIG_HAVE_ARM_TWD
-static DEFINE_TWD_LOCAL_TIMER(twd_local_timer, OMAP44XX_LOCAL_TWD_BASE, 29);
 void __init omap4_local_timer_init(void)
 {
 	omap4_sync32k_timer_init();
-	/* Local timers are not supprted on OMAP4430 ES1.0 */
-	if (omap_rev() != OMAP4430_REV_ES1_0) {
-		int err;
 
-		if (of_have_populated_dt()) {
-			clocksource_of_init();
-			return;
-		}
+	/* Local timers are not supported on OMAP4430 ES1.0 */
+	if (omap_rev() == OMAP4430_REV_ES1_0)
+		return;
 
-		err = twd_local_timer_register(&twd_local_timer);
-		if (err)
-			pr_err("twd_local_timer_register failed %d\n", err);
-	}
+	clocksource_of_init();
 }
 #else
 void __init omap4_local_timer_init(void)
-- 
2.5.0



From balbi at ti.com  Mon Aug 10 14:41:49 2015
From: balbi at ti.com (Felipe Balbi)
Date: Mon, 10 Aug 2015 16:41:49 -0500
Subject: [RFC/PATCH-v4.2-rc6 3/5] arm: omap2: Kconfig: select TWD and global
 timer on AM43xx devices
In-Reply-To: <1439242911-715-1-git-send-email-balbi@ti.com>
References: <1439242911-715-1-git-send-email-balbi@ti.com>
Message-ID: <1439242911-715-4-git-send-email-balbi@ti.com>

Make sure to tell the kernel that AM437x has
TWD and global timers.

Signed-off-by: Felipe Balbi <balbi at ti.com>
---
 arch/arm/mach-omap2/Kconfig | 3 +++
 1 file changed, 3 insertions(+)

diff --git a/arch/arm/mach-omap2/Kconfig b/arch/arm/mach-omap2/Kconfig
index 4a023e8d1bdb..eea902280989 100644
--- a/arch/arm/mach-omap2/Kconfig
+++ b/arch/arm/mach-omap2/Kconfig
@@ -61,6 +61,9 @@ config SOC_AM43XX
 	select MACH_OMAP_GENERIC
 	select MIGHT_HAVE_CACHE_L2X0
 	select HAVE_ARM_SCU
+	select HAVE_ARM_TWD
+	select ARM_GLOBAL_TIMER
+	select CLKSRC_ARM_GLOBAL_TIMER_SCHED_CLOCK
 
 config SOC_DRA7XX
 	bool "TI DRA7XX"
-- 
2.5.0



From balbi at ti.com  Mon Aug 10 14:41:47 2015
From: balbi at ti.com (Felipe Balbi)
Date: Mon, 10 Aug 2015 16:41:47 -0500
Subject: [RFC/PATCH-v4.2-rc6 1/5] Revert "ARM: 7655/1: smp_twd: make
 twd_local_timer_of_register() no-op for nosmp"
In-Reply-To: <1439242911-715-1-git-send-email-balbi@ti.com>
References: <1439242911-715-1-git-send-email-balbi@ti.com>
Message-ID: <1439242911-715-2-git-send-email-balbi@ti.com>

This reverts commit 904464b91eca8c665acea033489225af02eeb75a.

The problem pointed out by commit 904464b91eca ("ARM: 7655/1:
smp_twd: make twd_local_timer_of_register() no-op for nosmp")
doesn't exist anymore.

We can safely boot with nosmp and the warning won't show up.

The other side benefit of this patch is that TWD has a chance
to probe on single-core A9 systems such as AM437x which sport
TWD.

Cc: Shawn Guo <shawn.guo at linaro.org>
Cc: Dirk Behme <dirk.behme at de.bosch.com>
Cc: Russell King <rmk+kernel at arm.linux.org.uk>
Signed-off-by: Felipe Balbi <balbi at ti.com>
---
 arch/arm/kernel/smp_twd.c | 4 ----
 1 file changed, 4 deletions(-)

diff --git a/arch/arm/kernel/smp_twd.c b/arch/arm/kernel/smp_twd.c
index 172c6a05d27f..e8f6d241881f 100644
--- a/arch/arm/kernel/smp_twd.c
+++ b/arch/arm/kernel/smp_twd.c
@@ -23,7 +23,6 @@
 #include <linux/of_irq.h>
 #include <linux/of_address.h>
 
-#include <asm/smp_plat.h>
 #include <asm/smp_twd.h>
 
 /* set up by the platform code */
@@ -388,9 +387,6 @@ static void __init twd_local_timer_of_register(struct device_node *np)
 {
 	int err;
 
-	if (!is_smp() || !setup_max_cpus)
-		return;
-
 	twd_ppi = irq_of_parse_and_map(np, 0);
 	if (!twd_ppi) {
 		err = -EINVAL;
-- 
2.5.0



From sergei.shtylyov at cogentembedded.com  Mon Aug 10 14:57:57 2015
From: sergei.shtylyov at cogentembedded.com (Sergei Shtylyov)
Date: Tue, 11 Aug 2015 00:57:57 +0300
Subject: [PATCH v2 0/2] Add R8A7794/SILK QSPI DT support
Message-ID: <4187771.Fb49GBKgyg@wasted.cogentembedded.com>

Hello.

   Here's the set of 2 patches against Simon Horman's 'renesas.git' repo,
'renesas-devel-20150810-v4.2-rc6' tag plus the R8A7794 GPIO patches I've posted
last week. Here we add the QSPI device tree support for the R8A7794/SILK board.

[1/2] ARM: shmobile: r8a7794: add QSPI DT support
[2/2] ARM: shmobile: silk: add QSPI DT support

WBR, Sergei



From sergei.shtylyov at cogentembedded.com  Mon Aug 10 14:59:24 2015
From: sergei.shtylyov at cogentembedded.com (Sergei Shtylyov)
Date: Tue, 11 Aug 2015 00:59:24 +0300
Subject: [PATCH v2 1/2] ARM: shmobile: r8a7794: add QSPI DT support
In-Reply-To: <4187771.Fb49GBKgyg@wasted.cogentembedded.com>
References: <4187771.Fb49GBKgyg@wasted.cogentembedded.com>
Message-ID: <1540672.y3DTbtssP8@wasted.cogentembedded.com>

Define the generic R8A7794 part of the QSPI device node.

Based on original patch by Hisashi Nakamura <hisashi.nakamura.ak at renesas.com>.

Signed-off-by: Sergei Shtylyov <sergei.shtylyov at cogentembedded.com>

---
Changes in version 2:
- moved the "power-domains" property after the DMA properties.

 arch/arm/boot/dts/r8a7794.dtsi |   18 ++++++++++++++++++
 1 file changed, 18 insertions(+)

Index: renesas/arch/arm/boot/dts/r8a7794.dtsi
===================================================================
--- renesas.orig/arch/arm/boot/dts/r8a7794.dtsi
+++ renesas/arch/arm/boot/dts/r8a7794.dtsi
@@ -19,6 +19,10 @@
 	#address-cells = <2>;
 	#size-cells = <2>;
 
+	aliases {
+		spi0 = &qspi;
+	};
+
 	cpus {
 		#address-cells = <1>;
 		#size-cells = <0>;
@@ -537,6 +541,20 @@
 		status = "disabled";
 	};
 
+	qspi: spi at e6b10000 {
+		compatible = "renesas,qspi-r8a7794", "renesas,qspi";
+		reg = <0 0xe6b10000 0 0x2c>;
+		interrupts = <0 184 IRQ_TYPE_LEVEL_HIGH>;
+		clocks = <&mstp9_clks R8A7794_CLK_QSPI_MOD>;
+		dmas = <&dmac0 0x17>, <&dmac0 0x18>;
+		dma-names = "tx", "rx";
+		power-domains = <&cpg_clocks>;
+		num-cs = <1>;
+		#address-cells = <1>;
+		#size-cells = <0>;
+		status = "disabled";
+	};
+
 	clocks {
 		#address-cells = <2>;
 		#size-cells = <2>;



From sergei.shtylyov at cogentembedded.com  Mon Aug 10 15:00:35 2015
From: sergei.shtylyov at cogentembedded.com (Sergei Shtylyov)
Date: Tue, 11 Aug 2015 01:00:35 +0300
Subject: [PATCH v2 2/2] ARM: shmobile: silk: add QSPI DT support
In-Reply-To: <4187771.Fb49GBKgyg@wasted.cogentembedded.com>
References: <4187771.Fb49GBKgyg@wasted.cogentembedded.com>
Message-ID: <7036752.0LCvRcbC9K@wasted.cogentembedded.com>

Define the SILK board dependent part of the QSPI device node.
Add device nodes  for Spansion  S25FL512S SPI flash and MTD partitions on it.

Based on the original patch by Vladimir Barinov
<vladimir.barinov at cogentembedded.com>.

Signed-off-by: Sergei Shtylyov <sergei.shtylyov at cogentembedded.com>

---
Changes in version 2:
- added fallback value to the SPI flash's "compatible" property;
- grouped all SPI-related properties together in the SPI flash node.

 arch/arm/boot/dts/r8a7794-silk.dts |   40 +++++++++++++++++++++++++++++++++++++
 1 file changed, 40 insertions(+)

Index: renesas/arch/arm/boot/dts/r8a7794-silk.dts
===================================================================
--- renesas.orig/arch/arm/boot/dts/r8a7794-silk.dts
+++ renesas/arch/arm/boot/dts/r8a7794-silk.dts
@@ -65,6 +65,11 @@
 		renesas,groups = "mmc_data8", "mmc_ctrl";
 		renesas,function = "mmc";
 	};
+
+	qspi_pins: spi0 {
+		renesas,groups = "qspi_ctrl", "qspi_data4";
+		renesas,function = "qspi";
+	};
 };
 
 &scif2 {
@@ -100,3 +105,38 @@
 	non-removable;
 	status = "okay";
 };
+
+&qspi {
+	pinctrl-0 = <&qspi_pins>;
+	pinctrl-names = "default";
+
+	status = "okay";
+
+	flash at 0 {
+		#address-cells = <1>;
+		#size-cells = <1>;
+		compatible = "spansion,s25fl512s", "jedec,spi-nor";
+		reg = <0>;
+		spi-max-frequency = <30000000>;
+		spi-tx-bus-width = <4>;
+		spi-rx-bus-width = <4>;
+		spi-cpol;
+		spi-cpha;
+		m25p,fast-read;
+
+		partition at 0 {
+			label = "loader";
+			reg = <0x00000000 0x00040000>;
+			read-only;
+		};
+		partition at 40000 {
+			label = "user";
+			reg = <0x00040000 0x00400000>;
+			read-only;
+		};
+		partition at 440000 {
+			label = "flash";
+			reg = <0x00440000 0x03bc0000>;
+		};
+	};
+};



From bhelgaas at google.com  Mon Aug 10 15:04:13 2015
From: bhelgaas at google.com (Bjorn Helgaas)
Date: Mon, 10 Aug 2015 17:04:13 -0500
Subject: [PATCH v5 9/9] PCI: xgene: Use pci_scan_root_bus_msi()
In-Reply-To: <55C37C92.1020509@arm.com>
References: <20150804214234.9189.42548.stgit@bhelgaas-glaptop2.roam.corp.google.com>
 <20150804215457.9189.27595.stgit@bhelgaas-glaptop2.roam.corp.google.com>
 <55C37C92.1020509@arm.com>
Message-ID: <20150810220413.GA13982@google.com>

Hi Marc,

On Thu, Aug 06, 2015 at 04:26:10PM +0100, Marc Zyngier wrote:
> On 04/08/15 22:54, Bjorn Helgaas wrote:
> > Previously there was no way to specify the MSI controller when creating a
> > new PCI root bus, so we had to create the bus, set its MSI controller, then
> > scan the bus.  With the new pci_scan_root_bus_msi() interface, we can
> > specify the MSI controller up front and get rid of that intermediate step.
> > 
> > Look up the MSI controller first, then use pci_scan_root_bus_msi() to
> > create and scan the root PCI bus.
> 
> I'm wondering about these XGene patches.
> 
> With the code that is queued for v4.3 in tip/irq/core, the X-Gene MSI
> driver doesn't export a struct msi_controller anymore, and entirely
> relies on IRQ domains to identify to be matched with the actual PCI driver.
> 
> Do you intend this as a cleanup until everything lands in mainline? At
> that point, we'd be able to remove all traces of struct msi_controller
> from this driver.

I haven't been following the IRQ domain stuff or tip/irq/core, so I
really don't know how this relates to that.  I took a look, and I see
8d63bc7beaee ("PCI/MSI: pci-xgene-msi: Get rid of struct
msi_controller"), which removes an msi_controller pointer from
pci-xgene-msi.c, but I don't see any pci-xgene.c changes in
tip/irq/core.

Are you saying that xgene_pcie_msi_enable() will go away eventually?
And the OF "msi-parent" lookup will go away, or at least be moved
elsewhere?  We currently have:

  xgene_pcie_probe_bridge(...)
  {
    ...
    bus = pci_create_root_bus(...);
    xgene_pcie_msi_enable(...);
    pci_scan_child_bus(bus);
    ...
  }

I'd like to get rid of that arch-specific MSI enable stuff because
then we can use a higher level interface, e.g., pci_scan_root_bus(),
and make the X-Gene code slightly simpler.

> Alternatively, we could ask tglx to add an extra patch to the existing
> queue in order to clean up pci-xgene.c (nuking the whole
> xgene_pcie_msi_enable function).

Ah, I guess you *are* saying that xgene_pcie_msi_enable() will go away
eventually.  I don't know how to do that, but apparently you do, so
I'll just drop these X-Gene-related patches for now.

Bjorn


From robh at kernel.org  Mon Aug 10 15:19:29 2015
From: robh at kernel.org (Rob Herring)
Date: Mon, 10 Aug 2015 17:19:29 -0500
Subject: [PATCH v5 6/9] PCI: Drop references acquired by of_parse_phandle()
In-Reply-To: <20150810213900.GA9805@google.com>
References: <20150804214234.9189.42548.stgit@bhelgaas-glaptop2.roam.corp.google.com>
 <20150804215435.9189.94410.stgit@bhelgaas-glaptop2.roam.corp.google.com>
 <20150810213900.GA9805@google.com>
Message-ID: <CAL_JsqK9oriieG2rEEQdKHTLY=1qEUMnzQ7wKxDusksgiYFc6g@mail.gmail.com>

On Mon, Aug 10, 2015 at 4:39 PM, Bjorn Helgaas <bhelgaas at google.com> wrote:
> [+cc Ben, Rob]
>
> On Tue, Aug 04, 2015 at 04:54:35PM -0500, Bjorn Helgaas wrote:
>> of_parse_phandle() returns a device_node pointer with the refcount
>> incremented.  We should dispose of this reference when we're finished.
>>
>> Drop the reference acquired by of_parse_phandle().
>
> I cc'd everybody who wrote or signed off on 0d5a6db3aa46 ("of: pci: add
> registry of MSI chips"), which added of_pci_find_msi_chip_by_node().
>
> The existing code (before this patch) looks wrong to me, but I'm not an OF
> person.

In general, how DT reference counting works is broken and difficult to
get right. It doesn't really matter for most cases anyway (as nodes
don't get removed). I cannot tell you whether this patch is right or
wrong just looking at the patch. It seems correct based on your
description.

Rob

>
>> Signed-off-by: Bjorn Helgaas <bhelgaas at google.com>
>> ---
>>  drivers/pci/host/pci-mvebu.c |    1 +
>>  drivers/pci/host/pci-xgene.c |    1 +
>>  2 files changed, 2 insertions(+)
>>
>> diff --git a/drivers/pci/host/pci-mvebu.c b/drivers/pci/host/pci-mvebu.c
>> index 70aa095..67ec5e1 100644
>> --- a/drivers/pci/host/pci-mvebu.c
>> +++ b/drivers/pci/host/pci-mvebu.c
>> @@ -879,6 +879,7 @@ static void mvebu_pcie_msi_enable(struct mvebu_pcie *pcie)
>>               return;
>>
>>       pcie->msi = of_pci_find_msi_chip_by_node(msi_node);
>> +     of_node_put(msi_node);
>>
>>       if (pcie->msi)
>>               pcie->msi->dev = &pcie->pdev->dev;
>> diff --git a/drivers/pci/host/pci-xgene.c b/drivers/pci/host/pci-xgene.c
>> index a9dfb70..4c2fb1f 100644
>> --- a/drivers/pci/host/pci-xgene.c
>> +++ b/drivers/pci/host/pci-xgene.c
>> @@ -514,6 +514,7 @@ static int xgene_pcie_msi_enable(struct pci_bus *bus)
>>       if (!bus->msi)
>>               return -ENODEV;
>>
>> +     of_node_put(msi_node);
>>       bus->msi->dev = &bus->dev;
>>       return 0;
>>  }
>>


From ryabinin.a.a at gmail.com  Mon Aug 10 19:18:13 2015
From: ryabinin.a.a at gmail.com (Andrey Ryabinin)
Date: Tue, 11 Aug 2015 05:18:13 +0300
Subject: [PATCH v5 0/6]  KASAN for amr64
Message-ID: <1439259499-13913-1-git-send-email-ryabinin.a.a@gmail.com>

For git users patches are available in git:
        git://github.com/aryabinin/linux.git kasan/arm64v5

Changes since v4:
 - Generate KASAN_SHADOW_OFFSET using 32 bit arithmetic
 - merge patches x86/kasan: switch to generic kasan_populate_zero_shadow()
    and mm: introduce generic kasan_populate_zero_shadow() into one.
 - remove useless check for start != 0 in clear_pgds()
 - Don't generate KASAN_SHADOW_OFFSET in Makefile for x86,
   assign it in Makefile.kasan if CONFIG_KASAN_SHADOW_OFFSET was defined.
 
Changes since v3:
 - Generate KASAN_SHADOW_OFFSET in Makefile
 - zero_p*_populate() functions now return void
 - Switch x86 to generic kasan_populate_zero_shadow() too
 - Add license headers
 - fix memleak in kasan_populate_zero_shadow:
       Following code could leak memory when pgd_populate() is nop:
                void *p = early_alloc(PAGE_SIZE, NUMA_NO_NODE);
                pgd_populate(&init_mm, pgd, p);
        This was replaced by:
                 pgd_populate(&init_mm, pgd, early_alloc(PAGE_SIZE, NUMA_NO_NODE));

Changes since v2:
 - Rebase on top of v4.2-rc3
 - Address feedback from Catalin.
 - Print memory assignment from Linus
 - Add message about KASAN being initialized

Changes since v1:
 - Address feedback from Catalin.
 - Generalize some kasan init code from arch/x86/mm/kasan_init_64.c
    and reuse it for arm64.
 - Some bugfixes, including:
        add missing arm64/include/asm/kasan.h
        add tlb flush after changing ttbr1
 - Add code comments.

Andrey Ryabinin (5):
  x86/kasan: define KASAN_SHADOW_OFFSET per architecture
  x86/kasan, mm: introduce generic kasan_populate_zero_shadow()
  arm64: introduce VA_START macro - the first kernel virtual address.
  arm64: move PGD_SIZE definition to pgalloc.h
  arm64: add KASAN support

Linus Walleij (1):
  ARM64: kasan: print memory assignment

 arch/arm64/Kconfig               |   1 +
 arch/arm64/Makefile              |   7 ++
 arch/arm64/include/asm/kasan.h   |  36 +++++++++
 arch/arm64/include/asm/memory.h  |   2 +
 arch/arm64/include/asm/pgalloc.h |   1 +
 arch/arm64/include/asm/pgtable.h |   9 ++-
 arch/arm64/include/asm/string.h  |  16 ++++
 arch/arm64/kernel/arm64ksyms.c   |   3 +
 arch/arm64/kernel/head.S         |   3 +
 arch/arm64/kernel/module.c       |  16 +++-
 arch/arm64/kernel/setup.c        |   2 +
 arch/arm64/lib/memcpy.S          |   3 +
 arch/arm64/lib/memmove.S         |   7 +-
 arch/arm64/lib/memset.S          |   3 +
 arch/arm64/mm/Makefile           |   3 +
 arch/arm64/mm/init.c             |   6 ++
 arch/arm64/mm/kasan_init.c       | 165 +++++++++++++++++++++++++++++++++++++++
 arch/arm64/mm/pgd.c              |   2 -
 arch/x86/include/asm/kasan.h     |   3 +
 arch/x86/mm/kasan_init_64.c      | 123 ++---------------------------
 include/linux/kasan.h            |  10 ++-
 mm/kasan/Makefile                |   2 +-
 mm/kasan/kasan_init.c            | 152 ++++++++++++++++++++++++++++++++++++
 scripts/Makefile.kasan           |   4 +-
 24 files changed, 450 insertions(+), 129 deletions(-)
 create mode 100644 arch/arm64/include/asm/kasan.h
 create mode 100644 arch/arm64/mm/kasan_init.c
 create mode 100644 mm/kasan/kasan_init.c

-- 
2.4.6



From ryabinin.a.a at gmail.com  Mon Aug 10 19:18:14 2015
From: ryabinin.a.a at gmail.com (Andrey Ryabinin)
Date: Tue, 11 Aug 2015 05:18:14 +0300
Subject: [PATCH v5 1/6] x86/kasan: define KASAN_SHADOW_OFFSET per architecture
In-Reply-To: <1439259499-13913-1-git-send-email-ryabinin.a.a@gmail.com>
References: <1439259499-13913-1-git-send-email-ryabinin.a.a@gmail.com>
Message-ID: <1439259499-13913-2-git-send-email-ryabinin.a.a@gmail.com>

Current definition of  KASAN_SHADOW_OFFSET in include/linux/kasan.h
will not work for upcomming arm64, so move it to the arch header.

Signed-off-by: Andrey Ryabinin <ryabinin.a.a at gmail.com>
---
 arch/x86/include/asm/kasan.h | 3 +++
 include/linux/kasan.h        | 1 -
 2 files changed, 3 insertions(+), 1 deletion(-)

diff --git a/arch/x86/include/asm/kasan.h b/arch/x86/include/asm/kasan.h
index 74a2a8d..1410b56 100644
--- a/arch/x86/include/asm/kasan.h
+++ b/arch/x86/include/asm/kasan.h
@@ -1,6 +1,9 @@
 #ifndef _ASM_X86_KASAN_H
 #define _ASM_X86_KASAN_H
 
+#include <linux/const.h>
+#define KASAN_SHADOW_OFFSET _AC(CONFIG_KASAN_SHADOW_OFFSET, UL)
+
 /*
  * Compiler uses shadow offset assuming that addresses start
  * from 0. Kernel addresses don't start from 0, so shadow
diff --git a/include/linux/kasan.h b/include/linux/kasan.h
index 5486d77..6fb1c7d 100644
--- a/include/linux/kasan.h
+++ b/include/linux/kasan.h
@@ -10,7 +10,6 @@ struct vm_struct;
 #ifdef CONFIG_KASAN
 
 #define KASAN_SHADOW_SCALE_SHIFT 3
-#define KASAN_SHADOW_OFFSET _AC(CONFIG_KASAN_SHADOW_OFFSET, UL)
 
 #include <asm/kasan.h>
 #include <linux/sched.h>
-- 
2.4.6



From ryabinin.a.a at gmail.com  Mon Aug 10 19:18:17 2015
From: ryabinin.a.a at gmail.com (Andrey Ryabinin)
Date: Tue, 11 Aug 2015 05:18:17 +0300
Subject: [PATCH v5 4/6] arm64: move PGD_SIZE definition to pgalloc.h
In-Reply-To: <1439259499-13913-1-git-send-email-ryabinin.a.a@gmail.com>
References: <1439259499-13913-1-git-send-email-ryabinin.a.a@gmail.com>
Message-ID: <1439259499-13913-5-git-send-email-ryabinin.a.a@gmail.com>

This will be used by KASAN latter.

Signed-off-by: Andrey Ryabinin <ryabinin.a.a at gmail.com>
Acked-by: Catalin Marinas <catalin.marinas at arm.com>
---
 arch/arm64/include/asm/pgalloc.h | 1 +
 arch/arm64/mm/pgd.c              | 2 --
 2 files changed, 1 insertion(+), 2 deletions(-)

diff --git a/arch/arm64/include/asm/pgalloc.h b/arch/arm64/include/asm/pgalloc.h
index 7642056..c150539 100644
--- a/arch/arm64/include/asm/pgalloc.h
+++ b/arch/arm64/include/asm/pgalloc.h
@@ -27,6 +27,7 @@
 #define check_pgt_cache()		do { } while (0)
 
 #define PGALLOC_GFP	(GFP_KERNEL | __GFP_NOTRACK | __GFP_REPEAT | __GFP_ZERO)
+#define PGD_SIZE	(PTRS_PER_PGD * sizeof(pgd_t))
 
 #if CONFIG_PGTABLE_LEVELS > 2
 
diff --git a/arch/arm64/mm/pgd.c b/arch/arm64/mm/pgd.c
index 71ca104..cb3ba1b 100644
--- a/arch/arm64/mm/pgd.c
+++ b/arch/arm64/mm/pgd.c
@@ -28,8 +28,6 @@
 
 #include "mm.h"
 
-#define PGD_SIZE	(PTRS_PER_PGD * sizeof(pgd_t))
-
 static struct kmem_cache *pgd_cache;
 
 pgd_t *pgd_alloc(struct mm_struct *mm)
-- 
2.4.6



From ryabinin.a.a at gmail.com  Mon Aug 10 19:18:16 2015
From: ryabinin.a.a at gmail.com (Andrey Ryabinin)
Date: Tue, 11 Aug 2015 05:18:16 +0300
Subject: [PATCH v5 3/6] arm64: introduce VA_START macro - the first kernel
 virtual address.
In-Reply-To: <1439259499-13913-1-git-send-email-ryabinin.a.a@gmail.com>
References: <1439259499-13913-1-git-send-email-ryabinin.a.a@gmail.com>
Message-ID: <1439259499-13913-4-git-send-email-ryabinin.a.a@gmail.com>

In order to not use lengthy (UL(0xffffffffffffffff) << VA_BITS) everywhere,
replace it with VA_START.

Signed-off-by: Andrey Ryabinin <ryabinin.a.a at gmail.com>
Reviewed-by: Catalin Marinas <catalin.marinas at arm.com>
---
 arch/arm64/include/asm/memory.h  | 2 ++
 arch/arm64/include/asm/pgtable.h | 2 +-
 2 files changed, 3 insertions(+), 1 deletion(-)

diff --git a/arch/arm64/include/asm/memory.h b/arch/arm64/include/asm/memory.h
index f800d45..288c19d 100644
--- a/arch/arm64/include/asm/memory.h
+++ b/arch/arm64/include/asm/memory.h
@@ -42,12 +42,14 @@
  * PAGE_OFFSET - the virtual address of the start of the kernel image (top
  *		 (VA_BITS - 1))
  * VA_BITS - the maximum number of bits for virtual addresses.
+ * VA_START - the first kernel virtual address.
  * TASK_SIZE - the maximum size of a user space task.
  * TASK_UNMAPPED_BASE - the lower boundary of the mmap VM area.
  * The module space lives between the addresses given by TASK_SIZE
  * and PAGE_OFFSET - it must be within 128MB of the kernel text.
  */
 #define VA_BITS			(CONFIG_ARM64_VA_BITS)
+#define VA_START		(UL(0xffffffffffffffff) << VA_BITS)
 #define PAGE_OFFSET		(UL(0xffffffffffffffff) << (VA_BITS - 1))
 #define MODULES_END		(PAGE_OFFSET)
 #define MODULES_VADDR		(MODULES_END - SZ_64M)
diff --git a/arch/arm64/include/asm/pgtable.h b/arch/arm64/include/asm/pgtable.h
index 56283f8..a1f9f61 100644
--- a/arch/arm64/include/asm/pgtable.h
+++ b/arch/arm64/include/asm/pgtable.h
@@ -40,7 +40,7 @@
  *	fixed mappings and modules
  */
 #define VMEMMAP_SIZE		ALIGN((1UL << (VA_BITS - PAGE_SHIFT)) * sizeof(struct page), PUD_SIZE)
-#define VMALLOC_START		(UL(0xffffffffffffffff) << VA_BITS)
+#define VMALLOC_START		(VA_START)
 #define VMALLOC_END		(PAGE_OFFSET - PUD_SIZE - VMEMMAP_SIZE - SZ_64K)
 
 #define vmemmap			((struct page *)(VMALLOC_END + SZ_64K))
-- 
2.4.6



From ryabinin.a.a at gmail.com  Mon Aug 10 19:18:15 2015
From: ryabinin.a.a at gmail.com (Andrey Ryabinin)
Date: Tue, 11 Aug 2015 05:18:15 +0300
Subject: [PATCH v5 2/6] x86/kasan,
 mm: introduce generic kasan_populate_zero_shadow()
In-Reply-To: <1439259499-13913-1-git-send-email-ryabinin.a.a@gmail.com>
References: <1439259499-13913-1-git-send-email-ryabinin.a.a@gmail.com>
Message-ID: <1439259499-13913-3-git-send-email-ryabinin.a.a@gmail.com>

Introduce generic kasan_populate_zero_shadow(shadow_start, shadow_end).
This function maps kasan_zero_page to the [shadow_start, shadow_end]
addresses.

This replaces x86_64 specific populate_zero_shadow() and will
be used for ARM64 in follow on patches.

Signed-off-by: Andrey Ryabinin <ryabinin.a.a at gmail.com>
---
 arch/x86/mm/kasan_init_64.c | 123 ++---------------------------------
 include/linux/kasan.h       |   9 +++
 mm/kasan/Makefile           |   2 +-
 mm/kasan/kasan_init.c       | 152 ++++++++++++++++++++++++++++++++++++++++++++
 4 files changed, 167 insertions(+), 119 deletions(-)
 create mode 100644 mm/kasan/kasan_init.c

diff --git a/arch/x86/mm/kasan_init_64.c b/arch/x86/mm/kasan_init_64.c
index e1840f3..9ce5da2 100644
--- a/arch/x86/mm/kasan_init_64.c
+++ b/arch/x86/mm/kasan_init_64.c
@@ -12,20 +12,6 @@
 extern pgd_t early_level4_pgt[PTRS_PER_PGD];
 extern struct range pfn_mapped[E820_X_MAX];
 
-static pud_t kasan_zero_pud[PTRS_PER_PUD] __page_aligned_bss;
-static pmd_t kasan_zero_pmd[PTRS_PER_PMD] __page_aligned_bss;
-static pte_t kasan_zero_pte[PTRS_PER_PTE] __page_aligned_bss;
-
-/*
- * This page used as early shadow. We don't use empty_zero_page
- * at early stages, stack instrumentation could write some garbage
- * to this page.
- * Latter we reuse it as zero shadow for large ranges of memory
- * that allowed to access, but not instrumented by kasan
- * (vmalloc/vmemmap ...).
- */
-static unsigned char kasan_zero_page[PAGE_SIZE] __page_aligned_bss;
-
 static int __init map_range(struct range *range)
 {
 	unsigned long start;
@@ -62,106 +48,6 @@ static void __init kasan_map_early_shadow(pgd_t *pgd)
 	}
 }
 
-static int __init zero_pte_populate(pmd_t *pmd, unsigned long addr,
-				unsigned long end)
-{
-	pte_t *pte = pte_offset_kernel(pmd, addr);
-
-	while (addr + PAGE_SIZE <= end) {
-		WARN_ON(!pte_none(*pte));
-		set_pte(pte, __pte(__pa_nodebug(kasan_zero_page)
-					| __PAGE_KERNEL_RO));
-		addr += PAGE_SIZE;
-		pte = pte_offset_kernel(pmd, addr);
-	}
-	return 0;
-}
-
-static int __init zero_pmd_populate(pud_t *pud, unsigned long addr,
-				unsigned long end)
-{
-	int ret = 0;
-	pmd_t *pmd = pmd_offset(pud, addr);
-
-	while (IS_ALIGNED(addr, PMD_SIZE) && addr + PMD_SIZE <= end) {
-		WARN_ON(!pmd_none(*pmd));
-		set_pmd(pmd, __pmd(__pa_nodebug(kasan_zero_pte)
-					| _KERNPG_TABLE));
-		addr += PMD_SIZE;
-		pmd = pmd_offset(pud, addr);
-	}
-	if (addr < end) {
-		if (pmd_none(*pmd)) {
-			void *p = vmemmap_alloc_block(PAGE_SIZE, NUMA_NO_NODE);
-			if (!p)
-				return -ENOMEM;
-			set_pmd(pmd, __pmd(__pa_nodebug(p) | _KERNPG_TABLE));
-		}
-		ret = zero_pte_populate(pmd, addr, end);
-	}
-	return ret;
-}
-
-
-static int __init zero_pud_populate(pgd_t *pgd, unsigned long addr,
-				unsigned long end)
-{
-	int ret = 0;
-	pud_t *pud = pud_offset(pgd, addr);
-
-	while (IS_ALIGNED(addr, PUD_SIZE) && addr + PUD_SIZE <= end) {
-		WARN_ON(!pud_none(*pud));
-		set_pud(pud, __pud(__pa_nodebug(kasan_zero_pmd)
-					| _KERNPG_TABLE));
-		addr += PUD_SIZE;
-		pud = pud_offset(pgd, addr);
-	}
-
-	if (addr < end) {
-		if (pud_none(*pud)) {
-			void *p = vmemmap_alloc_block(PAGE_SIZE, NUMA_NO_NODE);
-			if (!p)
-				return -ENOMEM;
-			set_pud(pud, __pud(__pa_nodebug(p) | _KERNPG_TABLE));
-		}
-		ret = zero_pmd_populate(pud, addr, end);
-	}
-	return ret;
-}
-
-static int __init zero_pgd_populate(unsigned long addr, unsigned long end)
-{
-	int ret = 0;
-	pgd_t *pgd = pgd_offset_k(addr);
-
-	while (IS_ALIGNED(addr, PGDIR_SIZE) && addr + PGDIR_SIZE <= end) {
-		WARN_ON(!pgd_none(*pgd));
-		set_pgd(pgd, __pgd(__pa_nodebug(kasan_zero_pud)
-					| _KERNPG_TABLE));
-		addr += PGDIR_SIZE;
-		pgd = pgd_offset_k(addr);
-	}
-
-	if (addr < end) {
-		if (pgd_none(*pgd)) {
-			void *p = vmemmap_alloc_block(PAGE_SIZE, NUMA_NO_NODE);
-			if (!p)
-				return -ENOMEM;
-			set_pgd(pgd, __pgd(__pa_nodebug(p) | _KERNPG_TABLE));
-		}
-		ret = zero_pud_populate(pgd, addr, end);
-	}
-	return ret;
-}
-
-
-static void __init populate_zero_shadow(const void *start, const void *end)
-{
-	if (zero_pgd_populate((unsigned long)start, (unsigned long)end))
-		panic("kasan: unable to map zero shadow!");
-}
-
-
 #ifdef CONFIG_KASAN_INLINE
 static int kasan_die_handler(struct notifier_block *self,
 			     unsigned long val,
@@ -213,7 +99,7 @@ void __init kasan_init(void)
 
 	clear_pgds(KASAN_SHADOW_START, KASAN_SHADOW_END);
 
-	populate_zero_shadow((void *)KASAN_SHADOW_START,
+	kasan_populate_zero_shadow((void *)KASAN_SHADOW_START,
 			kasan_mem_to_shadow((void *)PAGE_OFFSET));
 
 	for (i = 0; i < E820_X_MAX; i++) {
@@ -223,14 +109,15 @@ void __init kasan_init(void)
 		if (map_range(&pfn_mapped[i]))
 			panic("kasan: unable to allocate shadow!");
 	}
-	populate_zero_shadow(kasan_mem_to_shadow((void *)PAGE_OFFSET + MAXMEM),
-			kasan_mem_to_shadow((void *)__START_KERNEL_map));
+	kasan_populate_zero_shadow(
+		kasan_mem_to_shadow((void *)PAGE_OFFSET + MAXMEM),
+		kasan_mem_to_shadow((void *)__START_KERNEL_map));
 
 	vmemmap_populate((unsigned long)kasan_mem_to_shadow(_stext),
 			(unsigned long)kasan_mem_to_shadow(_end),
 			NUMA_NO_NODE);
 
-	populate_zero_shadow(kasan_mem_to_shadow((void *)MODULES_END),
+	kasan_populate_zero_shadow(kasan_mem_to_shadow((void *)MODULES_END),
 			(void *)KASAN_SHADOW_END);
 
 	memset(kasan_zero_page, 0, PAGE_SIZE);
diff --git a/include/linux/kasan.h b/include/linux/kasan.h
index 6fb1c7d..4b9f85c 100644
--- a/include/linux/kasan.h
+++ b/include/linux/kasan.h
@@ -12,8 +12,17 @@ struct vm_struct;
 #define KASAN_SHADOW_SCALE_SHIFT 3
 
 #include <asm/kasan.h>
+#include <asm/pgtable.h>
 #include <linux/sched.h>
 
+extern unsigned char kasan_zero_page[PAGE_SIZE];
+extern pte_t kasan_zero_pte[PTRS_PER_PTE];
+extern pmd_t kasan_zero_pmd[PTRS_PER_PMD];
+extern pud_t kasan_zero_pud[PTRS_PER_PUD];
+
+void kasan_populate_zero_shadow(const void *shadow_start,
+				const void *shadow_end);
+
 static inline void *kasan_mem_to_shadow(const void *addr)
 {
 	return (void *)((unsigned long)addr >> KASAN_SHADOW_SCALE_SHIFT)
diff --git a/mm/kasan/Makefile b/mm/kasan/Makefile
index bd837b8..6471014 100644
--- a/mm/kasan/Makefile
+++ b/mm/kasan/Makefile
@@ -5,4 +5,4 @@ CFLAGS_REMOVE_kasan.o = -pg
 # see: https://gcc.gnu.org/bugzilla/show_bug.cgi?id=63533
 CFLAGS_kasan.o := $(call cc-option, -fno-conserve-stack -fno-stack-protector)
 
-obj-y := kasan.o report.o
+obj-y := kasan.o report.o kasan_init.o
diff --git a/mm/kasan/kasan_init.c b/mm/kasan/kasan_init.c
new file mode 100644
index 0000000..3f9a41c
--- /dev/null
+++ b/mm/kasan/kasan_init.c
@@ -0,0 +1,152 @@
+/*
+ * This file contains some kasan initialization code.
+ *
+ * Copyright (c) 2015 Samsung Electronics Co., Ltd.
+ * Author: Andrey Ryabinin <ryabinin.a.a at gmail.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.
+ *
+ */
+
+#include <linux/bootmem.h>
+#include <linux/init.h>
+#include <linux/kasan.h>
+#include <linux/kernel.h>
+#include <linux/memblock.h>
+#include <linux/pfn.h>
+
+#include <asm/page.h>
+#include <asm/pgalloc.h>
+
+/*
+ * This page serves two purposes:
+ *   - It used as early shadow memory. The entire shadow region populated
+ *     with this page, before we will be able to setup normal shadow memory.
+ *   - Latter it reused it as zero shadow to cover large ranges of memory
+ *     that allowed to access, but not handled by kasan (vmalloc/vmemmap ...).
+ */
+unsigned char kasan_zero_page[PAGE_SIZE] __page_aligned_bss;
+
+#if CONFIG_PGTABLE_LEVELS > 3
+pud_t kasan_zero_pud[PTRS_PER_PUD] __page_aligned_bss;
+#endif
+#if CONFIG_PGTABLE_LEVELS > 2
+pmd_t kasan_zero_pmd[PTRS_PER_PMD] __page_aligned_bss;
+#endif
+pte_t kasan_zero_pte[PTRS_PER_PTE] __page_aligned_bss;
+
+static __init void *early_alloc(size_t size, int node)
+{
+	return memblock_virt_alloc_try_nid(size, size, __pa(MAX_DMA_ADDRESS),
+					BOOTMEM_ALLOC_ACCESSIBLE, node);
+}
+
+static void __init zero_pte_populate(pmd_t *pmd, unsigned long addr,
+				unsigned long end)
+{
+	pte_t *pte = pte_offset_kernel(pmd, addr);
+	pte_t zero_pte;
+
+	zero_pte = pfn_pte(PFN_DOWN(__pa(kasan_zero_page)), PAGE_KERNEL);
+	zero_pte = pte_wrprotect(zero_pte);
+
+	while (addr + PAGE_SIZE <= end) {
+		set_pte_at(&init_mm, addr, pte, zero_pte);
+		addr += PAGE_SIZE;
+		pte = pte_offset_kernel(pmd, addr);
+	}
+}
+
+static void __init zero_pmd_populate(pud_t *pud, unsigned long addr,
+				unsigned long end)
+{
+	pmd_t *pmd = pmd_offset(pud, addr);
+	unsigned long next;
+
+	do {
+		next = pmd_addr_end(addr, end);
+
+		if (IS_ALIGNED(addr, PMD_SIZE) && end - addr >= PMD_SIZE) {
+			pmd_populate_kernel(&init_mm, pmd, kasan_zero_pte);
+			continue;
+		}
+
+		if (pmd_none(*pmd)) {
+			pmd_populate_kernel(&init_mm, pmd,
+					early_alloc(PAGE_SIZE, NUMA_NO_NODE));
+		}
+		zero_pte_populate(pmd, addr, next);
+	} while (pmd++, addr = next, addr != end);
+}
+
+static void __init zero_pud_populate(pgd_t *pgd, unsigned long addr,
+				unsigned long end)
+{
+	pud_t *pud = pud_offset(pgd, addr);
+	unsigned long next;
+
+	do {
+		next = pud_addr_end(addr, end);
+		if (IS_ALIGNED(addr, PUD_SIZE) && end - addr >= PUD_SIZE) {
+			pmd_t *pmd;
+
+			pud_populate(&init_mm, pud, kasan_zero_pmd);
+			pmd = pmd_offset(pud, addr);
+			pmd_populate_kernel(&init_mm, pmd, kasan_zero_pte);
+			continue;
+		}
+
+		if (pud_none(*pud)) {
+			pud_populate(&init_mm, pud,
+				early_alloc(PAGE_SIZE, NUMA_NO_NODE));
+		}
+		zero_pmd_populate(pud, addr, next);
+	} while (pud++, addr = next, addr != end);
+}
+
+/**
+ * kasan_populate_zero_shadow - populate shadow memory region with
+ *                               kasan_zero_page
+ * @shadow_start - start of the memory range to populate
+ * @shadow_end   - end of the memory range to populate
+ */
+void __init kasan_populate_zero_shadow(const void *shadow_start,
+				const void *shadow_end)
+{
+	unsigned long addr = (unsigned long)shadow_start;
+	unsigned long end = (unsigned long)shadow_end;
+	pgd_t *pgd = pgd_offset_k(addr);
+	unsigned long next;
+
+	do {
+		next = pgd_addr_end(addr, end);
+
+		if (IS_ALIGNED(addr, PGDIR_SIZE) && end - addr >= PGDIR_SIZE) {
+			pud_t *pud;
+			pmd_t *pmd;
+
+			/*
+			 * kasan_zero_pud should be populated with pmds
+			 * at this moment.
+			 * [pud,pmd]_populate*() below needed only for
+			 * 3,2 - level page tables where we don't have
+			 * puds,pmds, so pgd_populate(), pud_populate()
+			 * is noops.
+			 */
+			pgd_populate(&init_mm, pgd, kasan_zero_pud);
+			pud = pud_offset(pgd, addr);
+			pud_populate(&init_mm, pud, kasan_zero_pmd);
+			pmd = pmd_offset(pud, addr);
+			pmd_populate_kernel(&init_mm, pmd, kasan_zero_pte);
+			continue;
+		}
+
+		if (pgd_none(*pgd)) {
+			pgd_populate(&init_mm, pgd,
+				early_alloc(PAGE_SIZE, NUMA_NO_NODE));
+		}
+		zero_pud_populate(pgd, addr, next);
+	} while (pgd++, addr = next, addr != end);
+}
-- 
2.4.6



From ryabinin.a.a at gmail.com  Mon Aug 10 19:18:19 2015
From: ryabinin.a.a at gmail.com (Andrey Ryabinin)
Date: Tue, 11 Aug 2015 05:18:19 +0300
Subject: [PATCH v5 6/6] ARM64: kasan: print memory assignment
In-Reply-To: <1439259499-13913-1-git-send-email-ryabinin.a.a@gmail.com>
References: <1439259499-13913-1-git-send-email-ryabinin.a.a@gmail.com>
Message-ID: <1439259499-13913-7-git-send-email-ryabinin.a.a@gmail.com>

From: Linus Walleij <linus.walleij at linaro.org>

This prints out the virtual memory assigned to KASan in the
boot crawl along with other memory assignments, if and only
if KASan is activated.

Example dmesg from the Juno Development board:

Memory: 1691156K/2080768K available (5465K kernel code, 444K rwdata,
2160K rodata, 340K init, 217K bss, 373228K reserved, 16384K cma-reserved)
Virtual kernel memory layout:
    kasan   : 0xffffff8000000000 - 0xffffff9000000000   (    64 GB)
    vmalloc : 0xffffff9000000000 - 0xffffffbdbfff0000   (   182 GB)
    vmemmap : 0xffffffbdc0000000 - 0xffffffbfc0000000   (     8 GB maximum)
              0xffffffbdc2000000 - 0xffffffbdc3fc0000   (    31 MB actual)
    fixed   : 0xffffffbffabfd000 - 0xffffffbffac00000   (    12 KB)
    PCI I/O : 0xffffffbffae00000 - 0xffffffbffbe00000   (    16 MB)
    modules : 0xffffffbffc000000 - 0xffffffc000000000   (    64 MB)
    memory  : 0xffffffc000000000 - 0xffffffc07f000000   (  2032 MB)
      .init : 0xffffffc0007f5000 - 0xffffffc00084a000   (   340 KB)
      .text : 0xffffffc000080000 - 0xffffffc0007f45b4   (  7634 KB)
      .data : 0xffffffc000850000 - 0xffffffc0008bf200   (   445 KB)

Signed-off-by: Linus Walleij <linus.walleij at linaro.org>
Signed-off-by: Andrey Ryabinin <ryabinin.a.a at gmail.com>
Acked-by: Catalin Marinas <catalin.marinas at arm.com>
---
 arch/arm64/mm/init.c | 6 ++++++
 1 file changed, 6 insertions(+)

diff --git a/arch/arm64/mm/init.c b/arch/arm64/mm/init.c
index ad87ce8..3930692 100644
--- a/arch/arm64/mm/init.c
+++ b/arch/arm64/mm/init.c
@@ -298,6 +298,9 @@ void __init mem_init(void)
 #define MLK_ROUNDUP(b, t) b, t, DIV_ROUND_UP(((t) - (b)), SZ_1K)
 
 	pr_notice("Virtual kernel memory layout:\n"
+#ifdef CONFIG_KASAN
+		  "    kasan   : 0x%16lx - 0x%16lx   (%6ld GB)\n"
+#endif
 		  "    vmalloc : 0x%16lx - 0x%16lx   (%6ld GB)\n"
 #ifdef CONFIG_SPARSEMEM_VMEMMAP
 		  "    vmemmap : 0x%16lx - 0x%16lx   (%6ld GB maximum)\n"
@@ -310,6 +313,9 @@ void __init mem_init(void)
 		  "      .init : 0x%p" " - 0x%p" "   (%6ld KB)\n"
 		  "      .text : 0x%p" " - 0x%p" "   (%6ld KB)\n"
 		  "      .data : 0x%p" " - 0x%p" "   (%6ld KB)\n",
+#ifdef CONFIG_KASAN
+		  MLG(KASAN_SHADOW_START, KASAN_SHADOW_END),
+#endif
 		  MLG(VMALLOC_START, VMALLOC_END),
 #ifdef CONFIG_SPARSEMEM_VMEMMAP
 		  MLG((unsigned long)vmemmap,
-- 
2.4.6



From ryabinin.a.a at gmail.com  Mon Aug 10 19:18:18 2015
From: ryabinin.a.a at gmail.com (Andrey Ryabinin)
Date: Tue, 11 Aug 2015 05:18:18 +0300
Subject: [PATCH v5 5/6] arm64: add KASAN support
In-Reply-To: <1439259499-13913-1-git-send-email-ryabinin.a.a@gmail.com>
References: <1439259499-13913-1-git-send-email-ryabinin.a.a@gmail.com>
Message-ID: <1439259499-13913-6-git-send-email-ryabinin.a.a@gmail.com>

This patch adds arch specific code for kernel address sanitizer
(see Documentation/kasan.txt).

1/8 of kernel addresses reserved for shadow memory. There was no
big enough hole for this, so virtual addresses for shadow were
stolen from vmalloc area.

At early boot stage the whole shadow region populated with just
one physical page (kasan_zero_page). Later, this page reused
as readonly zero shadow for some memory that KASan currently
don't track (vmalloc).
After mapping the physical memory, pages for shadow memory are
allocated and mapped.

Functions like memset/memmove/memcpy do a lot of memory accesses.
If bad pointer passed to one of these function it is important
to catch this. Compiler's instrumentation cannot do this since
these functions are written in assembly.
KASan replaces memory functions with manually instrumented variants.
Original functions declared as weak symbols so strong definitions
in mm/kasan/kasan.c could replace them. Original functions have aliases
with '__' prefix in name, so we could call non-instrumented variant
if needed.
Some files built without kasan instrumentation (e.g. mm/slub.c).
Original mem* function replaced (via #define) with prefixed variants
to disable memory access checks for such files.

Signed-off-by: Andrey Ryabinin <ryabinin.a.a at gmail.com>
Tested-by: Linus Walleij <linus.walleij at linaro.org>
---
 arch/arm64/Kconfig               |   1 +
 arch/arm64/Makefile              |   7 ++
 arch/arm64/include/asm/kasan.h   |  36 +++++++++
 arch/arm64/include/asm/pgtable.h |   7 ++
 arch/arm64/include/asm/string.h  |  16 ++++
 arch/arm64/kernel/arm64ksyms.c   |   3 +
 arch/arm64/kernel/head.S         |   3 +
 arch/arm64/kernel/module.c       |  16 +++-
 arch/arm64/kernel/setup.c        |   2 +
 arch/arm64/lib/memcpy.S          |   3 +
 arch/arm64/lib/memmove.S         |   7 +-
 arch/arm64/lib/memset.S          |   3 +
 arch/arm64/mm/Makefile           |   3 +
 arch/arm64/mm/kasan_init.c       | 165 +++++++++++++++++++++++++++++++++++++++
 scripts/Makefile.kasan           |   4 +-
 15 files changed, 270 insertions(+), 6 deletions(-)
 create mode 100644 arch/arm64/include/asm/kasan.h
 create mode 100644 arch/arm64/mm/kasan_init.c

diff --git a/arch/arm64/Kconfig b/arch/arm64/Kconfig
index 318175f..b4a379e 100644
--- a/arch/arm64/Kconfig
+++ b/arch/arm64/Kconfig
@@ -46,6 +46,7 @@ config ARM64
 	select HAVE_ARCH_AUDITSYSCALL
 	select HAVE_ARCH_BITREVERSE
 	select HAVE_ARCH_JUMP_LABEL
+	select HAVE_ARCH_KASAN if SPARSEMEM_VMEMMAP
 	select HAVE_ARCH_KGDB
 	select HAVE_ARCH_SECCOMP_FILTER
 	select HAVE_ARCH_TRACEHOOK
diff --git a/arch/arm64/Makefile b/arch/arm64/Makefile
index 4d2a925..4cd8ea7 100644
--- a/arch/arm64/Makefile
+++ b/arch/arm64/Makefile
@@ -40,6 +40,13 @@ else
 TEXT_OFFSET := 0x00080000
 endif
 
+# KASAN_SHADOW_OFFSET = VA_START + (1 << (VA_BITS - 3)) - (1 << 61)
+# in 32-bit arithmetic
+KASAN_SHADOW_OFFSET := $(shell printf "0x%08x00000000\n" $$(( \
+			(0xffffffff & (-1 << ($(CONFIG_ARM64_VA_BITS) - 32))) \
+			+ (1 << ($(CONFIG_ARM64_VA_BITS) - 32 - 3)) \
+			- (1 << (64 - 32 - 3)) )) )
+
 export	TEXT_OFFSET GZFLAGS
 
 core-y		+= arch/arm64/kernel/ arch/arm64/mm/
diff --git a/arch/arm64/include/asm/kasan.h b/arch/arm64/include/asm/kasan.h
new file mode 100644
index 0000000..71dfe14
--- /dev/null
+++ b/arch/arm64/include/asm/kasan.h
@@ -0,0 +1,36 @@
+#ifndef __ASM_KASAN_H
+#define __ASM_KASAN_H
+
+#ifndef __ASSEMBLY__
+
+#ifdef CONFIG_KASAN
+
+#include <asm/memory.h>
+
+/*
+ * KASAN_SHADOW_START: beginning of the kernel virtual addresses.
+ * KASAN_SHADOW_END: KASAN_SHADOW_START + 1/8 of kernel virtual addresses.
+ */
+#define KASAN_SHADOW_START      (VA_START)
+#define KASAN_SHADOW_END        (KASAN_SHADOW_START + (1UL << (VA_BITS - 3)))
+
+/*
+ * This value is used to map an address to the corresponding shadow
+ * address by the following formula:
+ *     shadow_addr = (address >> 3) + KASAN_SHADOW_OFFSET;
+ *
+ * (1 << 61) shadow addresses - [KASAN_SHADOW_OFFSET,KASAN_SHADOW_END]
+ * cover all 64-bits of virtual addresses. So KASAN_SHADOW_OFFSET
+ * should satisfy the following equation:
+ *      KASAN_SHADOW_OFFSET = KASAN_SHADOW_END - (1ULL << 61)
+ */
+#define KASAN_SHADOW_OFFSET     (KASAN_SHADOW_END - (1ULL << (64 - 3)))
+
+void kasan_init(void);
+
+#else
+static inline void kasan_init(void) { }
+#endif
+
+#endif
+#endif
diff --git a/arch/arm64/include/asm/pgtable.h b/arch/arm64/include/asm/pgtable.h
index a1f9f61..a071da4 100644
--- a/arch/arm64/include/asm/pgtable.h
+++ b/arch/arm64/include/asm/pgtable.h
@@ -40,7 +40,14 @@
  *	fixed mappings and modules
  */
 #define VMEMMAP_SIZE		ALIGN((1UL << (VA_BITS - PAGE_SHIFT)) * sizeof(struct page), PUD_SIZE)
+
+#ifndef CONFIG_KASAN
 #define VMALLOC_START		(VA_START)
+#else
+#include <asm/kasan.h>
+#define VMALLOC_START		(KASAN_SHADOW_END + SZ_64K)
+#endif
+
 #define VMALLOC_END		(PAGE_OFFSET - PUD_SIZE - VMEMMAP_SIZE - SZ_64K)
 
 #define vmemmap			((struct page *)(VMALLOC_END + SZ_64K))
diff --git a/arch/arm64/include/asm/string.h b/arch/arm64/include/asm/string.h
index 64d2d48..2eb714c 100644
--- a/arch/arm64/include/asm/string.h
+++ b/arch/arm64/include/asm/string.h
@@ -36,17 +36,33 @@ extern __kernel_size_t strnlen(const char *, __kernel_size_t);
 
 #define __HAVE_ARCH_MEMCPY
 extern void *memcpy(void *, const void *, __kernel_size_t);
+extern void *__memcpy(void *, const void *, __kernel_size_t);
 
 #define __HAVE_ARCH_MEMMOVE
 extern void *memmove(void *, const void *, __kernel_size_t);
+extern void *__memmove(void *, const void *, __kernel_size_t);
 
 #define __HAVE_ARCH_MEMCHR
 extern void *memchr(const void *, int, __kernel_size_t);
 
 #define __HAVE_ARCH_MEMSET
 extern void *memset(void *, int, __kernel_size_t);
+extern void *__memset(void *, int, __kernel_size_t);
 
 #define __HAVE_ARCH_MEMCMP
 extern int memcmp(const void *, const void *, size_t);
 
+
+#if defined(CONFIG_KASAN) && !defined(__SANITIZE_ADDRESS__)
+
+/*
+ * For files that are not instrumented (e.g. mm/slub.c) we
+ * should use not instrumented version of mem* functions.
+ */
+
+#define memcpy(dst, src, len) __memcpy(dst, src, len)
+#define memmove(dst, src, len) __memmove(dst, src, len)
+#define memset(s, c, n) __memset(s, c, n)
+#endif
+
 #endif
diff --git a/arch/arm64/kernel/arm64ksyms.c b/arch/arm64/kernel/arm64ksyms.c
index a85843d..3b6d8cc 100644
--- a/arch/arm64/kernel/arm64ksyms.c
+++ b/arch/arm64/kernel/arm64ksyms.c
@@ -51,6 +51,9 @@ EXPORT_SYMBOL(strnlen);
 EXPORT_SYMBOL(memset);
 EXPORT_SYMBOL(memcpy);
 EXPORT_SYMBOL(memmove);
+EXPORT_SYMBOL(__memset);
+EXPORT_SYMBOL(__memcpy);
+EXPORT_SYMBOL(__memmove);
 EXPORT_SYMBOL(memchr);
 EXPORT_SYMBOL(memcmp);
 
diff --git a/arch/arm64/kernel/head.S b/arch/arm64/kernel/head.S
index c0ff3ce..945bd6d 100644
--- a/arch/arm64/kernel/head.S
+++ b/arch/arm64/kernel/head.S
@@ -449,6 +449,9 @@ __mmap_switched:
 	str_l	x21, __fdt_pointer, x5		// Save FDT pointer
 	str_l	x24, memstart_addr, x6		// Save PHYS_OFFSET
 	mov	x29, #0
+#ifdef CONFIG_KASAN
+	bl	kasan_early_init
+#endif
 	b	start_kernel
 ENDPROC(__mmap_switched)
 
diff --git a/arch/arm64/kernel/module.c b/arch/arm64/kernel/module.c
index 67bf410..7d90c0f 100644
--- a/arch/arm64/kernel/module.c
+++ b/arch/arm64/kernel/module.c
@@ -21,6 +21,7 @@
 #include <linux/bitops.h>
 #include <linux/elf.h>
 #include <linux/gfp.h>
+#include <linux/kasan.h>
 #include <linux/kernel.h>
 #include <linux/mm.h>
 #include <linux/moduleloader.h>
@@ -34,9 +35,18 @@
 
 void *module_alloc(unsigned long size)
 {
-	return __vmalloc_node_range(size, 1, MODULES_VADDR, MODULES_END,
-				    GFP_KERNEL, PAGE_KERNEL_EXEC, 0,
-				    NUMA_NO_NODE, __builtin_return_address(0));
+	void *p;
+
+	p = __vmalloc_node_range(size, MODULE_ALIGN, MODULES_VADDR, MODULES_END,
+				GFP_KERNEL, PAGE_KERNEL_EXEC, 0,
+				NUMA_NO_NODE, __builtin_return_address(0));
+
+	if (p && (kasan_module_alloc(p, size) < 0)) {
+		vfree(p);
+		return NULL;
+	}
+
+	return p;
 }
 
 enum aarch64_reloc_op {
diff --git a/arch/arm64/kernel/setup.c b/arch/arm64/kernel/setup.c
index f3067d4..bf82ab8 100644
--- a/arch/arm64/kernel/setup.c
+++ b/arch/arm64/kernel/setup.c
@@ -54,6 +54,7 @@
 #include <asm/elf.h>
 #include <asm/cpufeature.h>
 #include <asm/cpu_ops.h>
+#include <asm/kasan.h>
 #include <asm/sections.h>
 #include <asm/setup.h>
 #include <asm/smp_plat.h>
@@ -392,6 +393,7 @@ void __init setup_arch(char **cmdline_p)
 	acpi_boot_table_init();
 
 	paging_init();
+	kasan_init();
 	request_standard_resources();
 
 	early_ioremap_reset();
diff --git a/arch/arm64/lib/memcpy.S b/arch/arm64/lib/memcpy.S
index 8a9a96d..42cc4b7 100644
--- a/arch/arm64/lib/memcpy.S
+++ b/arch/arm64/lib/memcpy.S
@@ -56,6 +56,8 @@ C_h	.req	x12
 D_l	.req	x13
 D_h	.req	x14
 
+	.weak memcpy
+ENTRY(__memcpy)
 ENTRY(memcpy)
 	mov	dst, dstin
 	cmp	count, #16
@@ -199,3 +201,4 @@ ENTRY(memcpy)
 	b.ne	.Ltail63
 	ret
 ENDPROC(memcpy)
+ENDPROC(__memcpy)
diff --git a/arch/arm64/lib/memmove.S b/arch/arm64/lib/memmove.S
index 57b19ea..8819433 100644
--- a/arch/arm64/lib/memmove.S
+++ b/arch/arm64/lib/memmove.S
@@ -57,12 +57,14 @@ C_h	.req	x12
 D_l	.req	x13
 D_h	.req	x14
 
+	.weak memmove
+ENTRY(__memmove)
 ENTRY(memmove)
 	cmp	dstin, src
-	b.lo	memcpy
+	b.lo	__memcpy
 	add	tmp1, src, count
 	cmp	dstin, tmp1
-	b.hs	memcpy		/* No overlap.  */
+	b.hs	__memcpy		/* No overlap.  */
 
 	add	dst, dstin, count
 	add	src, src, count
@@ -195,3 +197,4 @@ ENTRY(memmove)
 	b.ne	.Ltail63
 	ret
 ENDPROC(memmove)
+ENDPROC(__memmove)
diff --git a/arch/arm64/lib/memset.S b/arch/arm64/lib/memset.S
index 7c72dfd..edc0e7d 100644
--- a/arch/arm64/lib/memset.S
+++ b/arch/arm64/lib/memset.S
@@ -54,6 +54,8 @@ dst		.req	x8
 tmp3w		.req	w9
 tmp3		.req	x9
 
+	.weak memset
+ENTRY(__memset)
 ENTRY(memset)
 	mov	dst, dstin	/* Preserve return value.  */
 	and	A_lw, val, #255
@@ -214,3 +216,4 @@ ENTRY(memset)
 	b.ne	.Ltail_maybe_long
 	ret
 ENDPROC(memset)
+ENDPROC(__memset)
diff --git a/arch/arm64/mm/Makefile b/arch/arm64/mm/Makefile
index 773d37a..57f57fd 100644
--- a/arch/arm64/mm/Makefile
+++ b/arch/arm64/mm/Makefile
@@ -4,3 +4,6 @@ obj-y				:= dma-mapping.o extable.o fault.o init.o \
 				   context.o proc.o pageattr.o
 obj-$(CONFIG_HUGETLB_PAGE)	+= hugetlbpage.o
 obj-$(CONFIG_ARM64_PTDUMP)	+= dump.o
+
+obj-$(CONFIG_KASAN)		+= kasan_init.o
+KASAN_SANITIZE_kasan_init.o	:= n
diff --git a/arch/arm64/mm/kasan_init.c b/arch/arm64/mm/kasan_init.c
new file mode 100644
index 0000000..3cf1d89
--- /dev/null
+++ b/arch/arm64/mm/kasan_init.c
@@ -0,0 +1,165 @@
+/*
+ * This file contains kasan initialization code for ARM64.
+ *
+ * Copyright (c) 2015 Samsung Electronics Co., Ltd.
+ * Author: Andrey Ryabinin <ryabinin.a.a at gmail.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.
+ *
+ */
+
+#define pr_fmt(fmt) "kasan: " fmt
+#include <linux/kasan.h>
+#include <linux/kernel.h>
+#include <linux/memblock.h>
+#include <linux/start_kernel.h>
+
+#include <asm/page.h>
+#include <asm/pgalloc.h>
+#include <asm/pgtable.h>
+#include <asm/tlbflush.h>
+
+static pgd_t tmp_pg_dir[PTRS_PER_PGD] __initdata __aligned(PGD_SIZE);
+
+static void __init kasan_early_pte_populate(pmd_t *pmd, unsigned long addr,
+					unsigned long end)
+{
+	pte_t *pte;
+	unsigned long next;
+
+	if (pmd_none(*pmd))
+		pmd_populate_kernel(&init_mm, pmd, kasan_zero_pte);
+
+	pte = pte_offset_kernel(pmd, addr);
+	do {
+		next = addr + PAGE_SIZE;
+		set_pte(pte, pfn_pte(virt_to_pfn(kasan_zero_page),
+					PAGE_KERNEL));
+	} while (pte++, addr = next, addr != end && pte_none(*pte));
+}
+
+static void __init kasan_early_pmd_populate(pud_t *pud,
+					unsigned long addr,
+					unsigned long end)
+{
+	pmd_t *pmd;
+	unsigned long next;
+
+	if (pud_none(*pud))
+		pud_populate(&init_mm, pud, kasan_zero_pmd);
+
+	pmd = pmd_offset(pud, addr);
+	do {
+		next = pmd_addr_end(addr, end);
+		kasan_early_pte_populate(pmd, addr, next);
+	} while (pmd++, addr = next, addr != end && pmd_none(*pmd));
+}
+
+static void __init kasan_early_pud_populate(pgd_t *pgd,
+					unsigned long addr,
+					unsigned long end)
+{
+	pud_t *pud;
+	unsigned long next;
+
+	if (pgd_none(*pgd))
+		pgd_populate(&init_mm, pgd, kasan_zero_pud);
+
+	pud = pud_offset(pgd, addr);
+	do {
+		next = pud_addr_end(addr, end);
+		kasan_early_pmd_populate(pud, addr, next);
+	} while (pud++, addr = next, addr != end && pud_none(*pud));
+}
+
+static void __init kasan_map_early_shadow(void)
+{
+	unsigned long addr = KASAN_SHADOW_START;
+	unsigned long end = KASAN_SHADOW_END;
+	unsigned long next;
+	pgd_t *pgd;
+
+	pgd = pgd_offset_k(addr);
+	do {
+		next = pgd_addr_end(addr, end);
+		kasan_early_pud_populate(pgd, addr, next);
+	} while (pgd++, addr = next, addr != end);
+}
+
+void __init kasan_early_init(void)
+{
+	BUILD_BUG_ON(KASAN_SHADOW_OFFSET != KASAN_SHADOW_END - (1UL << 61));
+	BUILD_BUG_ON(!IS_ALIGNED(KASAN_SHADOW_START, PGDIR_SIZE));
+	BUILD_BUG_ON(!IS_ALIGNED(KASAN_SHADOW_END, PGDIR_SIZE));
+	kasan_map_early_shadow();
+}
+
+static void __init clear_pgds(unsigned long start,
+			unsigned long end)
+{
+	/*
+	 * Remove references to kasan page tables from
+	 * swapper_pg_dir. pgd_clear() can't be used
+	 * here because it's nop on 2,3-level pagetable setups
+	 */
+	for (; start < end; start += PGDIR_SIZE)
+		set_pgd(pgd_offset_k(start), __pgd(0));
+}
+
+static void __init cpu_set_ttbr1(unsigned long ttbr1)
+{
+	asm(
+	"	msr	ttbr1_el1, %0\n"
+	"	isb"
+	:
+	: "r" (ttbr1));
+}
+
+void __init kasan_init(void)
+{
+	struct memblock_region *reg;
+
+	/*
+	 * We are going to perform proper setup of shadow memory.
+	 * At first we should unmap early shadow (clear_pgds() call bellow).
+	 * However, instrumented code couldn't execute without shadow memory.
+	 * tmp_pg_dir used to keep early shadow mapped until full shadow
+	 * setup will be finished.
+	 */
+	memcpy(tmp_pg_dir, swapper_pg_dir, sizeof(tmp_pg_dir));
+	cpu_set_ttbr1(__pa(tmp_pg_dir));
+	flush_tlb_all();
+
+	clear_pgds(KASAN_SHADOW_START, KASAN_SHADOW_END);
+
+	kasan_populate_zero_shadow((void *)KASAN_SHADOW_START,
+			kasan_mem_to_shadow((void *)MODULES_VADDR));
+
+	for_each_memblock(memory, reg) {
+		void *start = (void *)__phys_to_virt(reg->base);
+		void *end = (void *)__phys_to_virt(reg->base + reg->size);
+
+		if (start >= end)
+			break;
+
+		/*
+		 * end + 1 here is intentional. We check several shadow bytes in
+		 * advance to slightly speed up fastpath. In some rare cases
+		 * we could cross boundary of mapped shadow, so we just map
+		 * some more here.
+		 */
+		vmemmap_populate((unsigned long)kasan_mem_to_shadow(start),
+				(unsigned long)kasan_mem_to_shadow(end) + 1,
+				pfn_to_nid(virt_to_pfn(start)));
+	}
+
+	memset(kasan_zero_page, 0, PAGE_SIZE);
+	cpu_set_ttbr1(__pa(swapper_pg_dir));
+	flush_tlb_all();
+
+	/* At this point kasan is fully initialized. Enable error messages */
+	init_task.kasan_depth = 0;
+	pr_info("Kernel address sanitizer initialized\n");
+}
diff --git a/scripts/Makefile.kasan b/scripts/Makefile.kasan
index 3f874d2..37323b0 100644
--- a/scripts/Makefile.kasan
+++ b/scripts/Makefile.kasan
@@ -5,10 +5,12 @@ else
 	call_threshold := 0
 endif
 
+KASAN_SHADOW_OFFSET ?= $(CONFIG_KASAN_SHADOW_OFFSET)
+
 CFLAGS_KASAN_MINIMAL := -fsanitize=kernel-address
 
 CFLAGS_KASAN := $(call cc-option, -fsanitize=kernel-address \
-		-fasan-shadow-offset=$(CONFIG_KASAN_SHADOW_OFFSET) \
+		-fasan-shadow-offset=$(KASAN_SHADOW_OFFSET) \
 		--param asan-stack=1 --param asan-globals=1 \
 		--param asan-instrumentation-with-call-threshold=$(call_threshold))
 
-- 
2.4.6



From dhdang at apm.com  Mon Aug 10 15:28:43 2015
From: dhdang at apm.com (Duc Dang)
Date: Mon, 10 Aug 2015 15:28:43 -0700
Subject: [PATCH v5 9/9] PCI: xgene: Use pci_scan_root_bus_msi()
In-Reply-To: <20150810220413.GA13982@google.com>
References: <20150804214234.9189.42548.stgit@bhelgaas-glaptop2.roam.corp.google.com>
 <20150804215457.9189.27595.stgit@bhelgaas-glaptop2.roam.corp.google.com>
 <55C37C92.1020509@arm.com> <20150810220413.GA13982@google.com>
Message-ID: <CADaLNDmAzFhqWcR4mD3+Oi=eTu6zaSeNzZrc186_3Va2QaXw2g@mail.gmail.com>

On Mon, Aug 10, 2015 at 3:04 PM, Bjorn Helgaas <bhelgaas at google.com> wrote:
> Hi Marc,
>
> On Thu, Aug 06, 2015 at 04:26:10PM +0100, Marc Zyngier wrote:
>> On 04/08/15 22:54, Bjorn Helgaas wrote:
>> > Previously there was no way to specify the MSI controller when creating a
>> > new PCI root bus, so we had to create the bus, set its MSI controller, then
>> > scan the bus.  With the new pci_scan_root_bus_msi() interface, we can
>> > specify the MSI controller up front and get rid of that intermediate step.
>> >
>> > Look up the MSI controller first, then use pci_scan_root_bus_msi() to
>> > create and scan the root PCI bus.
>>
>> I'm wondering about these XGene patches.
>>
>> With the code that is queued for v4.3 in tip/irq/core, the X-Gene MSI
>> driver doesn't export a struct msi_controller anymore, and entirely
>> relies on IRQ domains to identify to be matched with the actual PCI driver.
>>
>> Do you intend this as a cleanup until everything lands in mainline? At
>> that point, we'd be able to remove all traces of struct msi_controller
>> from this driver.
>
> I haven't been following the IRQ domain stuff or tip/irq/core, so I
> really don't know how this relates to that.  I took a look, and I see
> 8d63bc7beaee ("PCI/MSI: pci-xgene-msi: Get rid of struct
> msi_controller"), which removes an msi_controller pointer from
> pci-xgene-msi.c, but I don't see any pci-xgene.c changes in
> tip/irq/core.
>
> Are you saying that xgene_pcie_msi_enable() will go away eventually?
> And the OF "msi-parent" lookup will go away, or at least be moved
> elsewhere?  We currently have:
>
>   xgene_pcie_probe_bridge(...)
>   {
>     ...
>     bus = pci_create_root_bus(...);
>     xgene_pcie_msi_enable(...);
>     pci_scan_child_bus(bus);
>     ...
>   }
>
> I'd like to get rid of that arch-specific MSI enable stuff because
> then we can use a higher level interface, e.g., pci_scan_root_bus(),
> and make the X-Gene code slightly simpler.
>
>> Alternatively, we could ask tglx to add an extra patch to the existing
>> queue in order to clean up pci-xgene.c (nuking the whole
>> xgene_pcie_msi_enable function).
>
> Ah, I guess you *are* saying that xgene_pcie_msi_enable() will go away
> eventually.  I don't know how to do that, but apparently you do, so
> I'll just drop these X-Gene-related patches for now.

Hi Bjorn,

I tested PCIe MSI with Marc's patch on X-Gene platform and it was working fine.
xgene_pcie_msi_enable will go away. I will post clean up patch to
remove these msi_controller traces
for X-Gene.

>
> Bjorn



-- 
Regards,
Duc Dang.


From sergei.shtylyov at cogentembedded.com  Mon Aug 10 15:44:03 2015
From: sergei.shtylyov at cogentembedded.com (Sergei Shtylyov)
Date: Tue, 11 Aug 2015 01:44:03 +0300
Subject: [PATCH v2] ARM: shmobile: silk: add SDHI1 DT support
In-Reply-To: <10037494.4LD4T2QGPX@wasted.cogentembedded.com>
References: <10037494.4LD4T2QGPX@wasted.cogentembedded.com>
Message-ID: <2757472.iuyUyRzJ3z@wasted.cogentembedded.com>

Define the SILK board dependent part of the SDHI1 (connected to micro-SD slot)
device nodes along with the necessary voltage regulators.

Based on the original patch by Vladimir Barinov
<vladimir.barinov at cogentembedded.com>.

Signed-off-by: Sergei Shtylyov <sergei.shtylyov at cogentembedded.com>

---
This patch is against 'renesas-devel-20150810-v4.2-rc6' tag of Simon Horman's
'renesas.git' repo plus the R8A7794/SILK QSPI patches just re-posted. It needs
the R8A7794 GPIO patches in order to compile.

Changes in version 2:
- removed not working SDHI0 stuff, renamed the patch;
- replaced SDHI1's "wp-gpios" property with "disable-wp".

 arch/arm/boot/dts/r8a7794-silk.dts |   40 +++++++++++++++++++++++++++++++++++++
 1 file changed, 40 insertions(+)

Index: renesas/arch/arm/boot/dts/r8a7794-silk.dts
===================================================================
--- renesas.orig/arch/arm/boot/dts/r8a7794-silk.dts
+++ renesas/arch/arm/boot/dts/r8a7794-silk.dts
@@ -12,6 +12,7 @@
 
 /dts-v1/;
 #include "r8a7794.dtsi"
+#include <dt-bindings/gpio/gpio.h>
 
 / {
 	model = "SILK";
@@ -39,6 +40,29 @@
 		regulator-boot-on;
 		regulator-always-on;
 	};
+	vcc_sdhi1: regulator at 3 {
+		compatible = "regulator-fixed";
+
+		regulator-name = "SDHI1 Vcc";
+		regulator-min-microvolt = <3300000>;
+		regulator-max-microvolt = <3300000>;
+
+		gpio = <&gpio4 26 GPIO_ACTIVE_HIGH>;
+		enable-active-high;
+	};
+
+	vccq_sdhi1: regulator at 4 {
+		compatible = "regulator-gpio";
+
+		regulator-name = "SDHI1 VccQ";
+		regulator-min-microvolt = <1800000>;
+		regulator-max-microvolt = <3300000>;
+
+		gpios = <&gpio4 29 GPIO_ACTIVE_HIGH>;
+		gpios-states = <1>;
+		states = <3300000 1
+			  1800000 0>;
+	};
 };
 
 &extal_clk {
@@ -66,6 +90,11 @@
 		renesas,function = "mmc";
 	};
 
+	sdhi1_pins: sd1 {
+		renesas,groups = "sdhi1_data4", "sdhi1_ctrl";
+		renesas,function = "sdhi1";
+	};
+
 	qspi_pins: spi0 {
 		renesas,groups = "qspi_ctrl", "qspi_data4";
 		renesas,function = "qspi";
@@ -106,6 +135,17 @@
 	status = "okay";
 };
 
+&sdhi1 {
+	pinctrl-0 = <&sdhi1_pins>;
+	pinctrl-names = "default";
+
+	vmmc-supply = <&vcc_sdhi1>;
+	vqmmc-supply = <&vccq_sdhi1>;
+	cd-gpios = <&gpio6 14 GPIO_ACTIVE_LOW>;
+	disable-wp;
+	status = "okay";
+};
+
 &qspi {
 	pinctrl-0 = <&qspi_pins>;
 	pinctrl-names = "default";



From horms at verge.net.au  Mon Aug 10 16:20:58 2015
From: horms at verge.net.au (Simon Horman)
Date: Tue, 11 Aug 2015 08:20:58 +0900
Subject: [PATCH v3 2/2] ARM: shmobile: r8a7794: add GPIO DT support
In-Reply-To: <CAMuHMdVj4_h8LX=XuWSyhGpSZ2BPxuWe_oJQYTRPFfYbuidm4g@mail.gmail.com>
References: <2265315.MpjeDzrVz2@wasted.cogentembedded.com>
 <10288801.ZnYt2TD47O@wasted.cogentembedded.com>
 <CAMuHMdVj4_h8LX=XuWSyhGpSZ2BPxuWe_oJQYTRPFfYbuidm4g@mail.gmail.com>
Message-ID: <20150810232054.GA9484@verge.net.au>

On Mon, Aug 10, 2015 at 03:23:54PM +0200, Geert Uytterhoeven wrote:
> Hi Sergei,
> 
> On Sun, Aug 9, 2015 at 12:09 AM, Sergei Shtylyov
> <sergei.shtylyov at cogentembedded.com> wrote:
> > Describe GPIO[0-6] controllers in the R8A7794 device tree.
> >
> > Based on original patch by Hisashi Nakamura <hisashi.nakamura.ak at renesas.com>.
> >
> > Signed-off-by: Sergei Shtylyov <sergei.shtylyov at cogentembedded.com>
> > Acked-by: Geert Uytterhoeven <geert+renesas at glider.be>
> >
> > ---
> > Changes in version 3:
> > - added "power-domains" property to the GPIO device nodes.
> 
> Thanks, unwithdrawing my ack ;-)
> 
> Acked-by: Geert Uytterhoeven <geert+renesas at glider.be>

Thanks, I have queued these up for v4.4.


From leif.lindholm at linaro.org  Mon Aug 10 16:23:12 2015
From: leif.lindholm at linaro.org (Leif Lindholm)
Date: Tue, 11 Aug 2015 00:23:12 +0100
Subject: earlycon issues in -next with amba-pl011 updates
Message-ID: <20150810232312.GB10728@bivouac.eciton.net>

Hi all,

The kernelci.org bot picked up a complete boot failure (no output past
UEFI stub) with next-20150806 and Tyler bisected it down to somewhere
in
8cd90e5 uart: pl011: Add support to ZTE ZX296702 uart
09dcc7d uart: pl011: Improve LCRH register access decision
2c096a9 uart: pl011: Introduce register look up table
7b753f3 uart: pl011: Introduce register accessor

The issue only appears with earlycon on command line, for pl011
consoles.

Some investigation shows that the cause lies with
commit 7b753f318d14 ("uart: pl011: Introduce register accessor")
and
commit 2c096a9eedc6 ("uart: pl011: Introduce register look up table")

Specifically, the changes to pl011_putc() are incorrect:
The new pl011_ accessors take a (struct uart_amba_port *) input, but
pl011_putc() directly uses the incoming (struct uart_port *) for this.

Apart from ending up with an unintended/incorrect UART base address,
the introduction of the lookup table for register offsets also means
the accessors try to dereference (struct uart_amba_port *)->reg_lut.

The below is a hack that shows/resolves the issue, but some
refactoring of the original patches might be in order.

/
    Leif

diff --git a/drivers/tty/serial/amba-pl011.c b/drivers/tty/serial/amba-pl011.c
index 2af09ab..452dbba 100644
--- a/drivers/tty/serial/amba-pl011.c
+++ b/drivers/tty/serial/amba-pl011.c
@@ -2348,13 +2348,14 @@ static struct console amba_console = {
 
 static void pl011_putc(struct uart_port *port, int c)
 {
-	struct uart_amba_port *uap =
-	    container_of(port, struct uart_amba_port, port);
+	struct uart_amba_port uap;
+	uap.port = *port;
+	uap.reg_lut = arm_reg;
 
-	while (pl011_readw(uap, REG_FR) & UART01x_FR_TXFF)
+	while (pl011_readw(&uap, REG_FR) & UART01x_FR_TXFF)
 		;
-	pl011_writeb(uap, c, REG_DR);
-	while (pl011_readw(uap, REG_FR) & uap->fr_busy)
+	pl011_writeb(&uap, c, REG_DR);
+	while (pl011_readw(&uap, REG_FR) & UART01x_FR_BUSY)
 		;
 }
 
-- 
2.1.4





From bjorn.andersson at sonymobile.com  Mon Aug 10 16:25:52 2015
From: bjorn.andersson at sonymobile.com (Bjorn Andersson)
Date: Mon, 10 Aug 2015 16:25:52 -0700
Subject: [PATCH v1 7/7] ARM: dts: ifc6410: add inforce LVDS panel support
In-Reply-To: <1438088076-17606-1-git-send-email-srinivas.kandagatla@linaro.org>
References: <1438087956-17307-1-git-send-email-srinivas.kandagatla@linaro.org>
 <1438088076-17606-1-git-send-email-srinivas.kandagatla@linaro.org>
Message-ID: <20150810232552.GB13472@usrtlx11787.corpusers.net>

On Tue 28 Jul 05:54 PDT 2015, Srinivas Kandagatla wrote:

> This patch adds LVDS panel for IFC6410.
> 

My ifc6410 doesn't have a LVDS display, so I don't think these nodes
belong in this dts file.

I was thinking we could have a variant including this dts file adding
the panel, but I assume that you can mount other panels than the auo
panel defined below?


Either way, I think we should keep this file to define the stuff that's
on the IFC6410 itself and then figure out how to aid people in adding
the rest of their additions...

Regards,
Bjorn


From k.kozlowski at samsung.com  Mon Aug 10 16:45:23 2015
From: k.kozlowski at samsung.com (Krzysztof Kozlowski)
Date: Tue, 11 Aug 2015 08:45:23 +0900
Subject: [PATCH 1/2] mfd: s2mps11: Add manual shutdown method for Odroid
 XU3
In-Reply-To: <20150810154910.GA12631@x1>
References: <1438605447-6836-1-git-send-email-k.kozlowski.k@gmail.com>
 <1438605447-6836-2-git-send-email-k.kozlowski.k@gmail.com>
 <20150810154910.GA12631@x1>
Message-ID: <55C93793.2090400@samsung.com>

On 11.08.2015 00:49, Lee Jones wrote:
> On Mon, 03 Aug 2015, Krzysztof Kozlowski wrote:
> 
>> On Odroid XU3 board (with S2MPS11 PMIC) the PWRHOLD bit in CTRL1
>> register must be manually set to 0 before initiating power off sequence.
>>
>> One of usual power down methods for Exynos based devices looks like:
>> 1. PWRHOLD pin of PMIC is connected to PSHOLD of Exynos.
>> 2. Exynos holds up this pin during system operation.
>> 3. ACOKB pin of PMIC is pulled up to VBATT and optionally to pin in
>>    other device.
>> 4. When PWRHOLD/PSHOLD goes low, the PMIC will turn off the power if
>>    ACOKB goes high.
>>
>> On Odroid XU3 family the difference is in (3) - the ACOKB is grounded.
>> This means that PMIC must manually set PWRHOLD field to low and then
>> wait for signal from Application Processor (the usual change in
>> PWRHOLD/PSHOLD pin will actually cut off the power).
>>
>> The patch adds respective binding allowing Odroid XU3 device to be
>> powered off.
>>
>> Signed-off-by: Krzysztof Kozlowski <k.kozlowski.k at gmail.com>
>> Reported-by: Anand Moon <linux.amoon at gmail.com>
>>
>> ---
>>
>> Patch is losely based on patch in Hardkernel repository [0] and previous
>> work of Anand Moon [1].
>>
>> [0] https://github.com/hardkernel/linux/commit/6897e62ba328bd1c8c095d918101863250cd73e7
>> [1] http://www.spinics.net/lists/linux-samsung-soc/msg45959.html
>> ---
>>  Documentation/devicetree/bindings/mfd/s2mps11.txt |  4 +++
>>  drivers/mfd/sec-core.c                            | 31 +++++++++++++++++++++++
>>  include/linux/mfd/samsung/core.h                  |  2 ++
>>  include/linux/mfd/samsung/s2mps11.h               |  1 +
>>  4 files changed, 38 insertions(+)
>>
>> diff --git a/Documentation/devicetree/bindings/mfd/s2mps11.txt b/Documentation/devicetree/bindings/mfd/s2mps11.txt
>> index 57a045016fca..90eaef393325 100644
>> --- a/Documentation/devicetree/bindings/mfd/s2mps11.txt
>> +++ b/Documentation/devicetree/bindings/mfd/s2mps11.txt
>> @@ -15,6 +15,10 @@ Optional properties:
>>  - interrupt-parent: Specifies the phandle of the interrupt controller to which
>>    the interrupts from s2mps11 are delivered to.
>>  - interrupts: Interrupt specifiers for interrupt sources.
> 
>> +- samsung,s2mps11-acokb-ground: Indicates that ACOKB pin of S2MPS11 PMIC is
>> +  connected to the ground so the PMIC must manually set PWRHOLD bit in CTRL1
>> +  register to turn off the power. Usually the ACOKB is pulled up to VBATT so
>> +  when PWRHOLD pin goes low, the rising ACOKB will trigger power off.
> 
> Binding looks fine.  Please seperate it into a different patch and
> apply my Ack:
> 
> Acked-by: Lee Jones <lee.jones at linaro.org>

OK

> 
>>  Optional nodes:
>>  - clocks: s2mps11, s2mps13 and s5m8767 provide three(AP/CP/BT) buffered 32.768
>> diff --git a/drivers/mfd/sec-core.c b/drivers/mfd/sec-core.c
>> index d206a3e8fe87..a56ab2102a32 100644
>> --- a/drivers/mfd/sec-core.c
>> +++ b/drivers/mfd/sec-core.c
>> @@ -278,6 +278,8 @@ static struct sec_platform_data *sec_pmic_i2c_parse_dt_pdata(
>>  	 * not parsed here.
>>  	 */
>>  
>> +	pd->manual_poweroff = of_property_read_bool(dev->of_node,
>> +						"samsung,s2mps11-acokb-ground");
>>  	return pd;
>>  }
>>  #else
>> @@ -440,6 +442,34 @@ static int sec_pmic_remove(struct i2c_client *i2c)
>>  	return 0;
>>  }
>>  
>> +static void sec_pmic_shutdown(struct i2c_client *i2c)
>> +{
>> +	struct sec_pmic_dev *sec_pmic = i2c_get_clientdata(i2c);
>> +	unsigned int reg, mask;
>> +
>> +	if (!sec_pmic->pdata->manual_poweroff)
>> +		return;
>> +
>> +	switch (sec_pmic->device_type) {
>> +	case S2MPS11X:
>> +		reg = S2MPS11_REG_CTRL1;
>> +		mask = S2MPS11_CTRL1_PWRHOLD_MASK;
>> +		break;
>> +	default:
>> +		/*
>> +		 * Currently only one board with S2MPS11 needs this, so just
>> +		 * ignore the rest.
>> +		 */
>> +		dev_warn(sec_pmic->dev,
>> +			"Unsupported device %lu for manual power off\n",
>> +			sec_pmic->device_type);
>> +		return;
>> +	}
>> +
>> +	regmap_update_bits(sec_pmic->regmap_pmic, reg, mask, 0);
>> +}
>> +
>> +
> 
> Remove the extra '\n'.
> 
> When you resubmit, apply my Ack:
> 
> Acked-by: Lee Jones <lee.jones at linaro.org>

Sure, I'll resend. The patch may go through your tree because there are
no external dependencies.

Best regards,
Krzysztof

> 
>>  #ifdef CONFIG_PM_SLEEP
>>  static int sec_pmic_suspend(struct device *dev)
>>  {
>> @@ -491,6 +521,7 @@ static struct i2c_driver sec_pmic_driver = {
>>  	},
>>  	.probe = sec_pmic_probe,
>>  	.remove = sec_pmic_remove,
>> +	.shutdown = sec_pmic_shutdown,
>>  	.id_table = sec_pmic_id,
>>  };
>>  
>> diff --git a/include/linux/mfd/samsung/core.h b/include/linux/mfd/samsung/core.h
>> index 75115384f3fc..aa78957e092f 100644
>> --- a/include/linux/mfd/samsung/core.h
>> +++ b/include/linux/mfd/samsung/core.h
>> @@ -132,6 +132,8 @@ struct sec_platform_data {
>>  	int				buck2_init;
>>  	int				buck3_init;
>>  	int				buck4_init;
>> +	/* Whether or not manually set PWRHOLD to low during shutdown. */
>> +	bool				manual_poweroff;
>>  };
>>  
>>  /**
>> diff --git a/include/linux/mfd/samsung/s2mps11.h b/include/linux/mfd/samsung/s2mps11.h
>> index 7981a9d77d3f..b288965e8101 100644
>> --- a/include/linux/mfd/samsung/s2mps11.h
>> +++ b/include/linux/mfd/samsung/s2mps11.h
>> @@ -179,6 +179,7 @@ enum s2mps11_regulators {
>>  #define S2MPS11_BUCK_N_VOLTAGES (S2MPS11_BUCK_VSEL_MASK + 1)
>>  #define S2MPS11_RAMP_DELAY	25000		/* uV/us */
>>  
>> +#define S2MPS11_CTRL1_PWRHOLD_MASK	BIT(4)
>>  
>>  #define S2MPS11_BUCK2_RAMP_SHIFT	6
>>  #define S2MPS11_BUCK34_RAMP_SHIFT	4
> 



From fcooper at ti.com  Mon Aug 10 16:47:25 2015
From: fcooper at ti.com (Franklin S Cooper Jr.)
Date: Mon, 10 Aug 2015 18:47:25 -0500
Subject: [RESEND][PATCH 3/4] ARM: davinci: Set proper SPI prescale limit
 value
In-Reply-To: <55B22681.3060000@ti.com>
References: <1437568344-18889-1-git-send-email-fcooper@ti.com>
 <1437568344-18889-4-git-send-email-fcooper@ti.com> <55B22681.3060000@ti.com>
Message-ID: <55C9380D.1060802@ti.com>



On 07/24/2015 06:50 AM, Sekhar Nori wrote:
> On Wednesday 22 July 2015 06:02 PM, Franklin S Cooper Jr wrote:
>> SPI Davinci driver has been updated to allow SOCs to specify their minimum
>> prescale value. Update the various SOCs board files that use this driver with
>> their proper prescaler limit.
>>
>> Signed-off-by: Franklin S Cooper Jr <fcooper at ti.com>
> Acked-by: Sekhar Nori <nsekhar at ti.com>
>
> in case Mark is okay to take it through his tree. It does not clash with
> anything else I have for mach-davinci.
>
> Thanks,
> Sekhar
>
ping. Patches 1 and 2 have already been pulled into Mark's spi tree and are currently in in linux-next.



From peter at hurleysoftware.com  Mon Aug 10 17:31:03 2015
From: peter at hurleysoftware.com (Peter Hurley)
Date: Mon, 10 Aug 2015 20:31:03 -0400
Subject: earlycon issues in -next with amba-pl011 updates
In-Reply-To: <20150810232312.GB10728@bivouac.eciton.net>
References: <20150810232312.GB10728@bivouac.eciton.net>
Message-ID: <55C94247.8020701@hurleysoftware.com>

Hi Leif,

On 08/10/2015 07:23 PM, Leif Lindholm wrote:
> Hi all,
> 
> The kernelci.org bot picked up a complete boot failure (no output past
> UEFI stub) with next-20150806 and Tyler bisected it down to somewhere
> in
> 8cd90e5 uart: pl011: Add support to ZTE ZX296702 uart
> 09dcc7d uart: pl011: Improve LCRH register access decision
> 2c096a9 uart: pl011: Introduce register look up table
> 7b753f3 uart: pl011: Introduce register accessor
> 
> The issue only appears with earlycon on command line, for pl011
> consoles.
> 
> Some investigation shows that the cause lies with
> commit 7b753f318d14 ("uart: pl011: Introduce register accessor")
> and
> commit 2c096a9eedc6 ("uart: pl011: Introduce register look up table")
> 
> Specifically, the changes to pl011_putc() are incorrect:
> The new pl011_ accessors take a (struct uart_amba_port *) input, but
> pl011_putc() directly uses the incoming (struct uart_port *) for this.
> 
> Apart from ending up with an unintended/incorrect UART base address,
> the introduction of the lookup table for register offsets also means
> the accessors try to dereference (struct uart_amba_port *)->reg_lut.


Thanks for the bug report and bisect, and apologies for the breakage;
I should have caught that on review.

Would you please test the patch below and see if that resolves the
problem for you?

Regards,
Peter Hurley

PS - _NOT_ even compile-tested, sorry.

--- >% ---
Subject: [PATCH] serial: pl011: Fix earlycon register LUT breakage

Commit 7b753f318d14 ("uart: pl011: Introduce register accessor")
mistakenly used the register LUT i/o accessors for the pl011
earlycon. Since the port has not been probed at earlycon time,
the struct uart_amba_port (and register LUTs) are uninitialized.

Use direct register addressing for pl011 earlycon; other h/w supported
by the amba-pl011 driver should declare an alternate earlycon.

Cc: Jun Nie <jun.nie at linaro.org>
Signed-off-by: Peter Hurley <peter at hurleysoftware.com>
---
 drivers/tty/serial/amba-pl011.c | 9 +++------
 1 file changed, 3 insertions(+), 6 deletions(-)

diff --git a/drivers/tty/serial/amba-pl011.c b/drivers/tty/serial/amba-pl011.c
index 2af09ab..fd54991 100644
--- a/drivers/tty/serial/amba-pl011.c
+++ b/drivers/tty/serial/amba-pl011.c
@@ -2348,13 +2348,10 @@ static struct console amba_console = {
 
 static void pl011_putc(struct uart_port *port, int c)
 {
-	struct uart_amba_port *uap =
-	    container_of(port, struct uart_amba_port, port);
-
-	while (pl011_readw(uap, REG_FR) & UART01x_FR_TXFF)
+	while (readl(port->membase + UART01x_FR) & UART01x_FR_TXFF)
 		;
-	pl011_writeb(uap, c, REG_DR);
-	while (pl011_readw(uap, REG_FR) & uap->fr_busy)
+	writeb(c, port->membase + UART01x_DR);
+	while (readl(port->membase + UART01x_FR) & UART01x_FR_BUSY)
 		;
 }
 
-- 
2.5.0



From robdclark at gmail.com  Mon Aug 10 17:40:52 2015
From: robdclark at gmail.com (Rob Clark)
Date: Mon, 10 Aug 2015 20:40:52 -0400
Subject: [PATCH v1 7/7] ARM: dts: ifc6410: add inforce LVDS panel support
In-Reply-To: <20150810232552.GB13472@usrtlx11787.corpusers.net>
References: <1438087956-17307-1-git-send-email-srinivas.kandagatla@linaro.org>
 <1438088076-17606-1-git-send-email-srinivas.kandagatla@linaro.org>
 <20150810232552.GB13472@usrtlx11787.corpusers.net>
Message-ID: <CAF6AEGumORyT=NimGHFT8jyN4fQ1=xeo31tnvm5X3VndM-J5LA@mail.gmail.com>

On Mon, Aug 10, 2015 at 7:25 PM, Bjorn Andersson
<bjorn.andersson at sonymobile.com> wrote:
> On Tue 28 Jul 05:54 PDT 2015, Srinivas Kandagatla wrote:
>
>> This patch adds LVDS panel for IFC6410.
>>
>
> My ifc6410 doesn't have a LVDS display, so I don't think these nodes
> belong in this dts file.

fwiw, my hope was that we could implement a panel-picker for lvds+ddc,
in a similar way to handling devices that could have multiple
different dsi panels, to make this a bit more automagically
plug-and-play.. srini has done some experiments with probing panel's
edid, so we just need to figure out if vendor+device-id in edid is
reliable enough to have a global table mapping them back to panel
compat strings or whether that table needs to go in dt..

BR,
-R

> I was thinking we could have a variant including this dts file adding
> the panel, but I assume that you can mount other panels than the auo
> panel defined below?
>
>
> Either way, I think we should keep this file to define the stuff that's
> on the IFC6410 itself and then figure out how to aid people in adding
> the rest of their additions...
>
> Regards,
> Bjorn


From dave.long at linaro.org  Mon Aug 10 17:52:37 2015
From: dave.long at linaro.org (David Long)
Date: Mon, 10 Aug 2015 20:52:37 -0400
Subject: [PATCH v8 0/7] arm64: Add kernel probes (kprobes) support
Message-ID: <1439254364-15362-1-git-send-email-dave.long@linaro.org>

From: "David A. Long" <dave.long at linaro.org>

This patchset is heavily based on Sandeepa Prabhu's ARM v8 kprobes patches,
first seen in October 2013. This version attempts to address concerns raised by
reviewers and also fixes problems discovered during testing.

This patchset adds support for kernel probes(kprobes), jump probes(jprobes)
and return probes(kretprobes) support for ARM64.

The kprobes mechanism makes use of software breakpoint and single stepping
support available in the ARM v8 kernel.

This patch depends on:
	[PATCH 1/2] Move the pt_regs_offset struct definition from arch to common include file
	[PATCH 2/2] Consolidate redundant register/stack access code

Changes since v2 include:

1) Removal of NOP padding in kprobe XOL slots. Slots are now exactly one
instruction long.
2) Disabling of interrupts during execution in single-step mode.
3) Fixing of numerous problems in instruction simulation code (mostly
thanks to Will Cohen).
4) Support for the HAVE_REGS_AND_STACK_ACCESS_API feature is added, to allow
access to kprobes through debugfs.
5) kprobes is *not* enabled in defconfig.
6) Numerous complaints from checkpatch have been cleaned up, although a couple
remain as removing the function pointer typedefs results in ugly code.

Changes since v3 include:

1) Remove table-driven instruction parsing and replace with an if statement
calling out to old and new instruction test functions in insn.c.
2) I removed the addition of orig_x0 to ptrace.h.
3) Reorder the patches.
4) Replace the previous interrupt disabling (from Will Cohen) with
an improved solution (from Steve Capper).

Changes since v4 include:

1) Added insn.c functions to detect exception instructions and DAIF
   read/write instructions, and use them to reject probing same.
2) Changed adr detect function to also recognize adrp. Reject both.
3) Added missing __kprobes for some new functions.
4) Added call to kprobes_fault_handler from mm do_page_fault.
5) Reject all non-simulated branch/ret instructions, not just those
   that use an immediate offset.
6) Moved software breakpoint definitions into debug-monitors.h.
7) Removed "!XIP_KERNEL" from Kconfig.
8) changed kprobes_condition_check_t and kprobes_prepare_t to probes_*,
   for future sharing with uprobes.
9) Removed bogus call to kprobes_restore_local_irqflag() from 
   trampoline_probe_handler().

Changes since v5 include:

1) Replaced installation of breakpoint hook with direct call from the
handlers in debug-monitors.c, as requested.
2) Reject probing of instructions that read the interrupt mask, in
addition to instructions that set it.
3) Cleaned up comments describing usage of Debug Mask.
4) Added KPROBE_REENTER case in reenter_kprobe.
5) Corrected the ifdef'd definitions for notify_page_fault() to be
consistent when KPROBES is not configed.
6) Changed "cpsr" to "pstate" for HAVE_REGS_AND_STACK_ACCESS_API feature.
7) Added back in missing new files in previous patch.
8) Changed two instances of pr_warning() to pr_warn().

Note that there seems to be at least a potential issue with kprobes
on multiple (possibly all) platforms having to do with use of kfree
inside of the kretprobes trampoline handler.  This has manifested
occasionally in systemtap testing on arm64.  There does not appear to
be an simple solution to the problem.

Changes since v6 include:

1) New trampoline code from Will Cohen fixes the occasional failure seen
when processing kretprobes by replacing the software breakpoint with
assembly code to implement the return to the original execution stream.
2) Changed ip0, ip1, fp, and lr to plain numbered registers for purposes
of recognizing them as an ascii string in the stack/reg access code.
3) Removed orig_x0.
4) Moved ARM_x* defines from arch/arm64/include/uapi/asm/ptrace.h to
arch/arm64/kernel/ptrace.c.

Changes since v7 include:

1) Move trampoline entry/return code into separate ".S" file instead
of making it a macro in a header file.
2) Add missing register name definitions in asm-offsets.c and use them
in place of hard-coded integer offsets in the trampoline code.
3) Correct the values used to decode MSR immediate instructions, in insn.h.
4) Remove the currently unused simulate_none() function.

David A. Long (2):
  arm64: Add HAVE_REGS_AND_STACK_ACCESS_API feature
  arm64: Add more test functions to insn.c

Sandeepa Prabhu (4):
  arm64: Kprobes with single stepping support
  arm64: kprobes instruction simulation support
  arm64: Add kernel return probes support (kretprobes)
  kprobes: Add arm64 case in kprobe example module

William Cohen (1):
  arm64: Add trampoline code for kretprobes

 arch/arm64/Kconfig                       |   3 +
 arch/arm64/include/asm/debug-monitors.h  |   5 +
 arch/arm64/include/asm/insn.h            |  18 +
 arch/arm64/include/asm/kprobes.h         |  64 +++
 arch/arm64/include/asm/probes.h          |  50 +++
 arch/arm64/include/asm/ptrace.h          |  28 +-
 arch/arm64/kernel/Makefile               |   4 +
 arch/arm64/kernel/asm-offsets.c          |  22 ++
 arch/arm64/kernel/debug-monitors.c       |  35 +-
 arch/arm64/kernel/insn.c                 |  28 ++
 arch/arm64/kernel/kprobes-arm64.c        | 166 ++++++++
 arch/arm64/kernel/kprobes-arm64.h        |  30 ++
 arch/arm64/kernel/kprobes.c              | 644 +++++++++++++++++++++++++++++++
 arch/arm64/kernel/kprobes.h              |  24 ++
 arch/arm64/kernel/kprobes_trampoline.S   |  61 +++
 arch/arm64/kernel/probes-condn-check.c   | 122 ++++++
 arch/arm64/kernel/probes-simulate-insn.c | 170 ++++++++
 arch/arm64/kernel/probes-simulate-insn.h |  32 ++
 arch/arm64/kernel/ptrace.c               |  77 ++++
 arch/arm64/kernel/vmlinux.lds.S          |   1 +
 arch/arm64/mm/fault.c                    |  25 ++
 samples/kprobes/kprobe_example.c         |   8 +
 22 files changed, 1606 insertions(+), 11 deletions(-)
 create mode 100644 arch/arm64/include/asm/kprobes.h
 create mode 100644 arch/arm64/include/asm/probes.h
 create mode 100644 arch/arm64/kernel/kprobes-arm64.c
 create mode 100644 arch/arm64/kernel/kprobes-arm64.h
 create mode 100644 arch/arm64/kernel/kprobes.c
 create mode 100644 arch/arm64/kernel/kprobes.h
 create mode 100644 arch/arm64/kernel/kprobes_trampoline.S
 create mode 100644 arch/arm64/kernel/probes-condn-check.c
 create mode 100644 arch/arm64/kernel/probes-simulate-insn.c
 create mode 100644 arch/arm64/kernel/probes-simulate-insn.h

-- 
1.8.1.2



From dave.long at linaro.org  Mon Aug 10 17:52:38 2015
From: dave.long at linaro.org (David Long)
Date: Mon, 10 Aug 2015 20:52:38 -0400
Subject: [PATCH v8 1/7] arm64: Add HAVE_REGS_AND_STACK_ACCESS_API feature
In-Reply-To: <1439254364-15362-1-git-send-email-dave.long@linaro.org>
References: <1439254364-15362-1-git-send-email-dave.long@linaro.org>
Message-ID: <1439254364-15362-2-git-send-email-dave.long@linaro.org>

From: "David A. Long" <dave.long at linaro.org>

Add HAVE_REGS_AND_STACK_ACCESS_API feature for arm64.

Signed-off-by: David A. Long <dave.long at linaro.org>
---
 arch/arm64/Kconfig              |  1 +
 arch/arm64/include/asm/ptrace.h | 25 +++++++++++++
 arch/arm64/kernel/ptrace.c      | 77 +++++++++++++++++++++++++++++++++++++++++
 3 files changed, 103 insertions(+)

diff --git a/arch/arm64/Kconfig b/arch/arm64/Kconfig
index 318175f..ef5d726 100644
--- a/arch/arm64/Kconfig
+++ b/arch/arm64/Kconfig
@@ -70,6 +70,7 @@ config ARM64
 	select HAVE_PERF_EVENTS
 	select HAVE_PERF_REGS
 	select HAVE_PERF_USER_STACK_DUMP
+	select HAVE_REGS_AND_STACK_ACCESS_API
 	select HAVE_RCU_TABLE_FREE
 	select HAVE_SYSCALL_TRACEPOINTS
 	select IRQ_DOMAIN
diff --git a/arch/arm64/include/asm/ptrace.h b/arch/arm64/include/asm/ptrace.h
index d6dd9fd..8f440e9 100644
--- a/arch/arm64/include/asm/ptrace.h
+++ b/arch/arm64/include/asm/ptrace.h
@@ -118,6 +118,8 @@ struct pt_regs {
 	u64 syscallno;
 };
 
+#define MAX_REG_OFFSET (sizeof(struct user_pt_regs) - sizeof(u64))
+
 #define arch_has_single_step()	(1)
 
 #ifdef CONFIG_COMPAT
@@ -146,6 +148,29 @@ struct pt_regs {
 #define user_stack_pointer(regs) \
 	(!compat_user_mode(regs) ? (regs)->sp : (regs)->compat_sp)
 
+/**
+ * regs_get_register() - get register value from its offset
+ * @regs:	   pt_regs from which register value is gotten
+ * @offset:    offset number of the register.
+ *
+ * regs_get_register returns the value of a register whose offset from @regs.
+ * The @offset is the offset of the register in struct pt_regs.
+ * If @offset is bigger than MAX_REG_OFFSET, this returns 0.
+ */
+static inline u64 regs_get_register(struct pt_regs *regs,
+					      unsigned int offset)
+{
+	if (unlikely(offset > MAX_REG_OFFSET))
+		return 0;
+	return *(u64 *)((u64)regs + offset);
+}
+
+/* Valid only for Kernel mode traps. */
+static inline unsigned long kernel_stack_pointer(struct pt_regs *regs)
+{
+	return regs->sp;
+}
+
 static inline unsigned long regs_return_value(struct pt_regs *regs)
 {
 	return regs->regs[0];
diff --git a/arch/arm64/kernel/ptrace.c b/arch/arm64/kernel/ptrace.c
index d882b83..f6199a5 100644
--- a/arch/arm64/kernel/ptrace.c
+++ b/arch/arm64/kernel/ptrace.c
@@ -48,6 +48,83 @@
 #define CREATE_TRACE_POINTS
 #include <trace/events/syscalls.h>
 
+#define ARM_pstate	pstate
+#define ARM_pc		pc
+#define ARM_sp		sp
+#define ARM_x30		regs[30]
+#define ARM_x29		regs[29]
+#define ARM_x28		regs[28]
+#define ARM_x27		regs[27]
+#define ARM_x26		regs[26]
+#define ARM_x25		regs[25]
+#define ARM_x24		regs[24]
+#define ARM_x23		regs[23]
+#define ARM_x22		regs[22]
+#define ARM_x21		regs[21]
+#define ARM_x20		regs[20]
+#define ARM_x19		regs[19]
+#define ARM_x18		regs[18]
+#define ARM_x17		regs[17]
+#define ARM_x16		regs[16]
+#define ARM_x15		regs[15]
+#define ARM_x14		regs[14]
+#define ARM_x13		regs[13]
+#define ARM_x12		regs[12]
+#define ARM_x11		regs[11]
+#define ARM_x10		regs[10]
+#define ARM_x9		regs[9]
+#define ARM_x8		regs[8]
+#define ARM_x7		regs[7]
+#define ARM_x6		regs[6]
+#define ARM_x5		regs[5]
+#define ARM_x4		regs[4]
+#define ARM_x3		regs[3]
+#define ARM_x2		regs[2]
+#define ARM_x1		regs[1]
+#define ARM_x0		regs[0]
+
+#define REG_OFFSET_NAME(r) \
+	{.name = #r, .offset = offsetof(struct pt_regs, ARM_##r)}
+#define REG_OFFSET_END {.name = NULL, .offset = 0}
+
+const struct pt_regs_offset regs_offset_table[] = {
+	REG_OFFSET_NAME(x0),
+	REG_OFFSET_NAME(x1),
+	REG_OFFSET_NAME(x2),
+	REG_OFFSET_NAME(x3),
+	REG_OFFSET_NAME(x4),
+	REG_OFFSET_NAME(x5),
+	REG_OFFSET_NAME(x6),
+	REG_OFFSET_NAME(x7),
+	REG_OFFSET_NAME(x8),
+	REG_OFFSET_NAME(x9),
+	REG_OFFSET_NAME(x10),
+	REG_OFFSET_NAME(x11),
+	REG_OFFSET_NAME(x12),
+	REG_OFFSET_NAME(x13),
+	REG_OFFSET_NAME(x14),
+	REG_OFFSET_NAME(x15),
+	REG_OFFSET_NAME(x16),
+	REG_OFFSET_NAME(x17),
+	REG_OFFSET_NAME(x18),
+	REG_OFFSET_NAME(x19),
+	REG_OFFSET_NAME(x20),
+	REG_OFFSET_NAME(x21),
+	REG_OFFSET_NAME(x22),
+	REG_OFFSET_NAME(x23),
+	REG_OFFSET_NAME(x24),
+	REG_OFFSET_NAME(x25),
+	REG_OFFSET_NAME(x26),
+	REG_OFFSET_NAME(x27),
+	REG_OFFSET_NAME(x28),
+	REG_OFFSET_NAME(x29),
+	REG_OFFSET_NAME(x30),
+	REG_OFFSET_NAME(sp),
+	REG_OFFSET_NAME(pc),
+	REG_OFFSET_NAME(pstate),
+	REG_OFFSET_END,
+};
+
 /*
  * TODO: does not yet catch signals sent when the child dies.
  * in exit.c or in signal.c.
-- 
1.8.1.2



From dave.long at linaro.org  Mon Aug 10 17:52:39 2015
From: dave.long at linaro.org (David Long)
Date: Mon, 10 Aug 2015 20:52:39 -0400
Subject: [PATCH v8 2/7] arm64: Add more test functions to insn.c
In-Reply-To: <1439254364-15362-1-git-send-email-dave.long@linaro.org>
References: <1439254364-15362-1-git-send-email-dave.long@linaro.org>
Message-ID: <1439254364-15362-3-git-send-email-dave.long@linaro.org>

From: "David A. Long" <dave.long at linaro.org>

Certain instructions are hard to execute correctly out-of-line (as in
kprobes).  Test functions are added to insn.[hc] to identify these.  The
instructions include any that use PC-relative addressing, change the PC,
or change interrupt masking. For efficiency and simplicity test
functions are also added for small collections of related instructions.

Signed-off-by: David A. Long <dave.long at linaro.org>
---
 arch/arm64/include/asm/insn.h | 18 ++++++++++++++++++
 arch/arm64/kernel/insn.c      | 28 ++++++++++++++++++++++++++++
 2 files changed, 46 insertions(+)

diff --git a/arch/arm64/include/asm/insn.h b/arch/arm64/include/asm/insn.h
index 30e50eb..66bfb21 100644
--- a/arch/arm64/include/asm/insn.h
+++ b/arch/arm64/include/asm/insn.h
@@ -223,8 +223,13 @@ static __always_inline bool aarch64_insn_is_##abbr(u32 code) \
 static __always_inline u32 aarch64_insn_get_##abbr##_value(void) \
 { return (val); }
 
+__AARCH64_INSN_FUNCS(adr_adrp,	0x1F000000, 0x10000000)
+__AARCH64_INSN_FUNCS(prfm_lit,	0xFF000000, 0xD8000000)
 __AARCH64_INSN_FUNCS(str_reg,	0x3FE0EC00, 0x38206800)
 __AARCH64_INSN_FUNCS(ldr_reg,	0x3FE0EC00, 0x38606800)
+__AARCH64_INSN_FUNCS(ldr_lit,	0xBF000000, 0x18000000)
+__AARCH64_INSN_FUNCS(ldrsw_lit,	0xFF000000, 0x98000000)
+__AARCH64_INSN_FUNCS(exclusive,	0x3F000000, 0x08000000)
 __AARCH64_INSN_FUNCS(stp_post,	0x7FC00000, 0x28800000)
 __AARCH64_INSN_FUNCS(ldp_post,	0x7FC00000, 0x28C00000)
 __AARCH64_INSN_FUNCS(stp_pre,	0x7FC00000, 0x29800000)
@@ -264,19 +269,29 @@ __AARCH64_INSN_FUNCS(ands,	0x7F200000, 0x6A000000)
 __AARCH64_INSN_FUNCS(bics,	0x7F200000, 0x6A200000)
 __AARCH64_INSN_FUNCS(b,		0xFC000000, 0x14000000)
 __AARCH64_INSN_FUNCS(bl,	0xFC000000, 0x94000000)
+__AARCH64_INSN_FUNCS(b_bl,	0x7C000000, 0x14000000)
+__AARCH64_INSN_FUNCS(cb,	0x7E000000, 0x34000000)
 __AARCH64_INSN_FUNCS(cbz,	0x7F000000, 0x34000000)
 __AARCH64_INSN_FUNCS(cbnz,	0x7F000000, 0x35000000)
+__AARCH64_INSN_FUNCS(tb,	0x7E000000, 0x36000000)
 __AARCH64_INSN_FUNCS(tbz,	0x7F000000, 0x36000000)
 __AARCH64_INSN_FUNCS(tbnz,	0x7F000000, 0x37000000)
+__AARCH64_INSN_FUNCS(b_bl_cb_tb, 0x5C000000, 0x14000000)
 __AARCH64_INSN_FUNCS(bcond,	0xFF000010, 0x54000000)
 __AARCH64_INSN_FUNCS(svc,	0xFFE0001F, 0xD4000001)
 __AARCH64_INSN_FUNCS(hvc,	0xFFE0001F, 0xD4000002)
 __AARCH64_INSN_FUNCS(smc,	0xFFE0001F, 0xD4000003)
 __AARCH64_INSN_FUNCS(brk,	0xFFE0001F, 0xD4200000)
+__AARCH64_INSN_FUNCS(exception,	0xFF000000, 0xD4000000)
 __AARCH64_INSN_FUNCS(hint,	0xFFFFF01F, 0xD503201F)
 __AARCH64_INSN_FUNCS(br,	0xFFFFFC1F, 0xD61F0000)
 __AARCH64_INSN_FUNCS(blr,	0xFFFFFC1F, 0xD63F0000)
+__AARCH64_INSN_FUNCS(br_blr,	0xFFDFFC1F, 0xD61F0000)
 __AARCH64_INSN_FUNCS(ret,	0xFFFFFC1F, 0xD65F0000)
+__AARCH64_INSN_FUNCS(msr_imm,	0xFFF8F01F, 0xD500401F)
+__AARCH64_INSN_FUNCS(msr_reg,	0xFFF00000, 0xD5100000)
+__AARCH64_INSN_FUNCS(set_clr_daif, 0xFFFFF0DF, 0xD50340DF)
+__AARCH64_INSN_FUNCS(rd_wr_daif, 0xFFDFFFE0, 0xD51B4220)
 
 #undef	__AARCH64_INSN_FUNCS
 
@@ -286,6 +301,9 @@ bool aarch64_insn_is_branch_imm(u32 insn);
 int aarch64_insn_read(void *addr, u32 *insnp);
 int aarch64_insn_write(void *addr, u32 insn);
 enum aarch64_insn_encoding_class aarch64_get_insn_class(u32 insn);
+bool aarch64_insn_uses_literal(u32 insn);
+bool aarch64_insn_is_branch(u32 insn);
+bool aarch64_insn_is_daif_access(u32 insn);
 u64 aarch64_insn_decode_immediate(enum aarch64_insn_imm_type type, u32 insn);
 u32 aarch64_insn_encode_immediate(enum aarch64_insn_imm_type type,
 				  u32 insn, u64 imm);
diff --git a/arch/arm64/kernel/insn.c b/arch/arm64/kernel/insn.c
index dd9671c..e532188 100644
--- a/arch/arm64/kernel/insn.c
+++ b/arch/arm64/kernel/insn.c
@@ -163,6 +163,34 @@ static bool __kprobes __aarch64_insn_hotpatch_safe(u32 insn)
 		aarch64_insn_is_nop(insn);
 }
 
+bool __kprobes aarch64_insn_uses_literal(u32 insn)
+{
+	/* ldr/ldrsw (literal), prfm */
+
+	return aarch64_insn_is_ldr_lit(insn) ||
+		aarch64_insn_is_ldrsw_lit(insn) ||
+		aarch64_insn_is_adr_adrp(insn) ||
+		aarch64_insn_is_prfm_lit(insn);
+}
+
+bool __kprobes aarch64_insn_is_branch(u32 insn)
+{
+	/* b, bl, cb*, tb*, b.cond, br, blr */
+
+	return aarch64_insn_is_b_bl_cb_tb(insn) ||
+		aarch64_insn_is_br_blr(insn) ||
+		aarch64_insn_is_ret(insn) ||
+		aarch64_insn_is_bcond(insn);
+}
+
+bool __kprobes aarch64_insn_is_daif_access(u32 insn)
+{
+	/* msr daif, mrs daif, msr daifset, msr daifclr */
+
+	return aarch64_insn_is_rd_wr_daif(insn) ||
+		aarch64_insn_is_set_clr_daif(insn);
+}
+
 /*
  * ARM Architecture Reference Manual for ARMv8 Profile-A, Issue A.a
  * Section B2.6.5 "Concurrent modification and execution of instructions":
-- 
1.8.1.2



From dave.long at linaro.org  Mon Aug 10 17:52:43 2015
From: dave.long at linaro.org (David Long)
Date: Mon, 10 Aug 2015 20:52:43 -0400
Subject: [PATCH v8 6/7] arm64: Add kernel return probes support (kretprobes)
In-Reply-To: <1439254364-15362-1-git-send-email-dave.long@linaro.org>
References: <1439254364-15362-1-git-send-email-dave.long@linaro.org>
Message-ID: <1439254364-15362-7-git-send-email-dave.long@linaro.org>

From: Sandeepa Prabhu <sandeepa.s.prabhu at gmail.com>

The pre-handler of this special 'trampoline' kprobe executes the return
probe handler functions and restores original return address in ELR_EL1.
This way the saved pt_regs still hold the original register context to be
carried back to the probed kernel function.

Signed-off-by: Sandeepa Prabhu <sandeepa.s.prabhu at gmail.com>
Signed-off-by: David A. Long <dave.long at linaro.org>
---
 arch/arm64/Kconfig          |  1 +
 arch/arm64/kernel/kprobes.c | 75 ++++++++++++++++++++++++++++++++++++++++++++-
 2 files changed, 75 insertions(+), 1 deletion(-)

diff --git a/arch/arm64/Kconfig b/arch/arm64/Kconfig
index 1bb07f7..9a589a6 100644
--- a/arch/arm64/Kconfig
+++ b/arch/arm64/Kconfig
@@ -74,6 +74,7 @@ config ARM64
 	select HAVE_RCU_TABLE_FREE
 	select HAVE_SYSCALL_TRACEPOINTS
 	select HAVE_KPROBES
+	select HAVE_KRETPROBES if HAVE_KPROBES
 	select IRQ_DOMAIN
 	select IRQ_FORCED_THREADING
 	select MODULES_USE_ELF_RELA
diff --git a/arch/arm64/kernel/kprobes.c b/arch/arm64/kernel/kprobes.c
index 98db85c..1dadad8 100644
--- a/arch/arm64/kernel/kprobes.c
+++ b/arch/arm64/kernel/kprobes.c
@@ -562,7 +562,80 @@ int __kprobes longjmp_break_handler(struct kprobe *p, struct pt_regs *regs)
 
 void __kprobes __used *trampoline_probe_handler(struct pt_regs *regs)
 {
-	return (void *) 0;
+	struct kretprobe_instance *ri = NULL;
+	struct hlist_head *head, empty_rp;
+	struct hlist_node *tmp;
+	unsigned long flags, orig_ret_addr = 0;
+	unsigned long trampoline_address =
+		(unsigned long)&kretprobe_trampoline;
+
+	INIT_HLIST_HEAD(&empty_rp);
+	kretprobe_hash_lock(current, &head, &flags);
+
+	/*
+	 * It is possible to have multiple instances associated with a given
+	 * task either because multiple functions in the call path have
+	 * a return probe installed on them, and/or more than one return
+	 * probe was registered for a target function.
+	 *
+	 * We can handle this because:
+	 *     - instances are always inserted at the head of the list
+	 *     - when multiple return probes are registered for the same
+	 *       function, the first instance's ret_addr will point to the
+	 *       real return address, and all the rest will point to
+	 *       kretprobe_trampoline
+	 */
+	hlist_for_each_entry_safe(ri, tmp, head, hlist) {
+		if (ri->task != current)
+			/* another task is sharing our hash bucket */
+			continue;
+
+		if (ri->rp && ri->rp->handler) {
+			__this_cpu_write(current_kprobe, &ri->rp->kp);
+			get_kprobe_ctlblk()->kprobe_status = KPROBE_HIT_ACTIVE;
+			ri->rp->handler(ri, regs);
+			__this_cpu_write(current_kprobe, NULL);
+		}
+
+		orig_ret_addr = (unsigned long)ri->ret_addr;
+		recycle_rp_inst(ri, &empty_rp);
+
+		if (orig_ret_addr != trampoline_address)
+			/*
+			 * This is the real return address. Any other
+			 * instances associated with this task are for
+			 * other calls deeper on the call stack
+			 */
+			break;
+	}
+
+	kretprobe_assert(ri, orig_ret_addr, trampoline_address);
+	/* restore the original return address */
+	instruction_pointer(regs) = orig_ret_addr;
+	reset_current_kprobe();
+	kretprobe_hash_unlock(current, &flags);
+
+	hlist_for_each_entry_safe(ri, tmp, &empty_rp, hlist) {
+		hlist_del(&ri->hlist);
+		kfree(ri);
+	}
+
+	/* return 1 so that post handlers not called */
+	return (void *) orig_ret_addr;
+}
+
+void __kprobes arch_prepare_kretprobe(struct kretprobe_instance *ri,
+				      struct pt_regs *regs)
+{
+	ri->ret_addr = (kprobe_opcode_t *)regs->regs[30];
+
+	/* replace return addr (x30) with trampoline */
+	regs->regs[30] = (long)&kretprobe_trampoline;
+}
+
+int __kprobes arch_trampoline_kprobe(struct kprobe *p)
+{
+	return 0;
 }
 
 int __init arch_init_kprobes(void)
-- 
1.8.1.2



From dave.long at linaro.org  Mon Aug 10 17:52:42 2015
From: dave.long at linaro.org (David Long)
Date: Mon, 10 Aug 2015 20:52:42 -0400
Subject: [PATCH v8 5/7] arm64: Add trampoline code for kretprobes
In-Reply-To: <1439254364-15362-1-git-send-email-dave.long@linaro.org>
References: <1439254364-15362-1-git-send-email-dave.long@linaro.org>
Message-ID: <1439254364-15362-6-git-send-email-dave.long@linaro.org>

From: William Cohen <wcohen at redhat.com>

The trampoline code is used by kretprobes to capture a return from a probed
function.  This is done by saving the registers, calling the handler, and
restoring the registers.  The code then returns to the original saved caller
return address.  It is necessary to do this directly instead of using a
software breakpoint because the code used in processing that breakpoint
could itself be kprobe'd and cause a problematic reentry into the debug
exception handler.

Signed-off-by: William Cohen <wcohen at redhat.com>
Signed-off-by: David A. Long <dave.long at linaro.org>
---
 arch/arm64/include/asm/kprobes.h       |  2 ++
 arch/arm64/kernel/Makefile             |  1 +
 arch/arm64/kernel/asm-offsets.c        | 22 ++++++++++++
 arch/arm64/kernel/kprobes.c            |  5 +++
 arch/arm64/kernel/kprobes_trampoline.S | 61 ++++++++++++++++++++++++++++++++++
 5 files changed, 91 insertions(+)
 create mode 100644 arch/arm64/kernel/kprobes_trampoline.S

diff --git a/arch/arm64/include/asm/kprobes.h b/arch/arm64/include/asm/kprobes.h
index af31c4d..83399aa 100644
--- a/arch/arm64/include/asm/kprobes.h
+++ b/arch/arm64/include/asm/kprobes.h
@@ -58,5 +58,7 @@ int kprobe_exceptions_notify(struct notifier_block *self,
 			     unsigned long val, void *data);
 int kprobe_breakpoint_handler(struct pt_regs *regs, unsigned int esr);
 int kprobe_single_step_handler(struct pt_regs *regs, unsigned int esr);
+void kretprobe_trampoline(void);
+void __kprobes *trampoline_probe_handler(struct pt_regs *regs);
 
 #endif /* _ARM_KPROBES_H */
diff --git a/arch/arm64/kernel/Makefile b/arch/arm64/kernel/Makefile
index 5e9d54f..75d5fb0 100644
--- a/arch/arm64/kernel/Makefile
+++ b/arch/arm64/kernel/Makefile
@@ -33,6 +33,7 @@ arm64-obj-$(CONFIG_CPU_IDLE)		+= cpuidle.o
 arm64-obj-$(CONFIG_JUMP_LABEL)		+= jump_label.o
 arm64-obj-$(CONFIG_KGDB)		+= kgdb.o
 arm64-obj-$(CONFIG_KPROBES)		+= kprobes.o kprobes-arm64.o		\
+					   kprobes_trampoline.o			\
 					   probes-simulate-insn.o		\
 					   probes-condn-check.o
 arm64-obj-$(CONFIG_EFI)			+= efi.o efi-stub.o efi-entry.o
diff --git a/arch/arm64/kernel/asm-offsets.c b/arch/arm64/kernel/asm-offsets.c
index c99701a..475c93b 100644
--- a/arch/arm64/kernel/asm-offsets.c
+++ b/arch/arm64/kernel/asm-offsets.c
@@ -49,6 +49,28 @@ int main(void)
   DEFINE(S_X5,			offsetof(struct pt_regs, regs[5]));
   DEFINE(S_X6,			offsetof(struct pt_regs, regs[6]));
   DEFINE(S_X7,			offsetof(struct pt_regs, regs[7]));
+  DEFINE(S_X8,			offsetof(struct pt_regs, regs[8]));
+  DEFINE(S_X9,			offsetof(struct pt_regs, regs[9]));
+  DEFINE(S_X10,			offsetof(struct pt_regs, regs[10]));
+  DEFINE(S_X11,			offsetof(struct pt_regs, regs[11]));
+  DEFINE(S_X12,			offsetof(struct pt_regs, regs[12]));
+  DEFINE(S_X13,			offsetof(struct pt_regs, regs[13]));
+  DEFINE(S_X14,			offsetof(struct pt_regs, regs[14]));
+  DEFINE(S_X15,			offsetof(struct pt_regs, regs[15]));
+  DEFINE(S_X16,			offsetof(struct pt_regs, regs[16]));
+  DEFINE(S_X17,			offsetof(struct pt_regs, regs[17]));
+  DEFINE(S_X18,			offsetof(struct pt_regs, regs[18]));
+  DEFINE(S_X19,			offsetof(struct pt_regs, regs[19]));
+  DEFINE(S_X20,			offsetof(struct pt_regs, regs[20]));
+  DEFINE(S_X21,			offsetof(struct pt_regs, regs[21]));
+  DEFINE(S_X22,			offsetof(struct pt_regs, regs[22]));
+  DEFINE(S_X23,			offsetof(struct pt_regs, regs[23]));
+  DEFINE(S_X24,			offsetof(struct pt_regs, regs[24]));
+  DEFINE(S_X25,			offsetof(struct pt_regs, regs[25]));
+  DEFINE(S_X26,			offsetof(struct pt_regs, regs[26]));
+  DEFINE(S_X27,			offsetof(struct pt_regs, regs[27]));
+  DEFINE(S_X28,			offsetof(struct pt_regs, regs[28]));
+  DEFINE(S_X29,			offsetof(struct pt_regs, regs[29]));
   DEFINE(S_LR,			offsetof(struct pt_regs, regs[30]));
   DEFINE(S_SP,			offsetof(struct pt_regs, sp));
 #ifdef CONFIG_COMPAT
diff --git a/arch/arm64/kernel/kprobes.c b/arch/arm64/kernel/kprobes.c
index 6255814..98db85c 100644
--- a/arch/arm64/kernel/kprobes.c
+++ b/arch/arm64/kernel/kprobes.c
@@ -560,6 +560,11 @@ int __kprobes longjmp_break_handler(struct kprobe *p, struct pt_regs *regs)
 	return 0;
 }
 
+void __kprobes __used *trampoline_probe_handler(struct pt_regs *regs)
+{
+	return (void *) 0;
+}
+
 int __init arch_init_kprobes(void)
 {
 	return 0;
diff --git a/arch/arm64/kernel/kprobes_trampoline.S b/arch/arm64/kernel/kprobes_trampoline.S
new file mode 100644
index 0000000..dd0172b
--- /dev/null
+++ b/arch/arm64/kernel/kprobes_trampoline.S
@@ -0,0 +1,61 @@
+/*
+ * trampoline entry and return code for kretprobes.
+ */
+
+#include <linux/linkage.h>
+#include <generated/asm-offsets.h>
+
+	.text
+
+ENTRY(kretprobe_trampoline)
+
+	sub sp, sp, #S_FRAME_SIZE
+
+	stp x0, x1, [sp, #S_X0]
+	stp x2, x3, [sp, #S_X2]
+	stp x4, x5, [sp, #S_X4]
+	stp x6, x7, [sp, #S_X6]
+	stp x8, x9, [sp, #S_X8]
+	stp x10, x11, [sp, #S_X10]
+	stp x12, x13, [sp, #S_X12]
+	stp x14, x15, [sp, #S_X14]
+	stp x16, x17, [sp, #S_X16]
+	stp x18, x19, [sp, #S_X18]
+	stp x20, x21, [sp, #S_X20]
+	stp x22, x23, [sp, #S_X22]
+	stp x24, x25, [sp, #S_X24]
+	stp x26, x27, [sp, #S_X26]
+	stp x28, x29, [sp, #S_X28]
+	str x30, [sp, #S_LR]
+	mrs x0, nzcv
+	str x0, [sp, #S_PSTATE]
+
+	mov x0, sp
+	bl trampoline_probe_handler
+	/* Replace trampoline address in lr with actual
+	   orig_ret_addr return address. */
+	str x0, [sp, #S_LR]
+
+	ldr x0, [sp, #S_PSTATE]
+	msr nzcv, x0
+	ldp x0, x1, [sp, #S_X0]
+	ldp x2, x3, [sp, #S_X2]
+	ldp x4, x5, [sp, #S_X4]
+	ldp x6, x7, [sp, #S_X6]
+	ldp x8, x9, [sp, #S_X8]
+	ldp x10, x11, [sp, #S_X10]
+	ldp x12, x13, [sp, #S_X12]
+	ldp x14, x15, [sp, #S_X14]
+	ldp x16, x17, [sp, #S_X16]
+	ldp x18, x19, [sp, #S_X18]
+	ldp x20, x21, [sp, #S_X20]
+	ldp x22, x23, [sp, #S_X22]
+	ldp x24, x25, [sp, #S_X24]
+	ldp x26, x27, [sp, #S_X26]
+	ldp x28, x29, [sp, #S_X28]
+	ldr x30, [sp, #S_LR]
+
+	add sp, sp, #S_FRAME_SIZE
+	ret
+
+ENDPROC(kretprobe_trampoline)
-- 
1.8.1.2



From dave.long at linaro.org  Mon Aug 10 17:52:41 2015
From: dave.long at linaro.org (David Long)
Date: Mon, 10 Aug 2015 20:52:41 -0400
Subject: [PATCH v8 4/7] arm64: kprobes instruction simulation support
In-Reply-To: <1439254364-15362-1-git-send-email-dave.long@linaro.org>
References: <1439254364-15362-1-git-send-email-dave.long@linaro.org>
Message-ID: <1439254364-15362-5-git-send-email-dave.long@linaro.org>

From: Sandeepa Prabhu <sandeepa.s.prabhu at gmail.com>

Kprobes needs simulation of instructions that cannot be stepped
from different memory location, e.g.: those instructions
that uses PC-relative addressing. In simulation, the behaviour
of the instruction is implemented using a copy of pt_regs.

Following instruction catagories are simulated:
 - All branching instructions(conditional, register, and immediate)
 - Literal access instructions(load-literal, adr/adrp)

Conditional execution is limited to branching instructions in
ARM v8. If conditions at PSTATE do not match the condition fields
of opcode, the instruction is effectively NOP. Kprobes considers
this case as 'miss'.

Thanks to Will Cohen for assorted suggested changes.

Signed-off-by: Sandeepa Prabhu <sandeepa.s.prabhu at gmail.com>
Signed-off-by: William Cohen <wcohen at redhat.com>
Signed-off-by: David A. Long <dave.long at linaro.org>
---
 arch/arm64/kernel/Makefile               |   4 +-
 arch/arm64/kernel/kprobes-arm64.c        |  98 ++++++++++++++++++
 arch/arm64/kernel/kprobes-arm64.h        |   2 +
 arch/arm64/kernel/kprobes.c              |  35 ++++++-
 arch/arm64/kernel/probes-condn-check.c   | 122 ++++++++++++++++++++++
 arch/arm64/kernel/probes-simulate-insn.c | 170 +++++++++++++++++++++++++++++++
 arch/arm64/kernel/probes-simulate-insn.h |  32 ++++++
 7 files changed, 459 insertions(+), 4 deletions(-)
 create mode 100644 arch/arm64/kernel/probes-condn-check.c
 create mode 100644 arch/arm64/kernel/probes-simulate-insn.c
 create mode 100644 arch/arm64/kernel/probes-simulate-insn.h

diff --git a/arch/arm64/kernel/Makefile b/arch/arm64/kernel/Makefile
index 1319872..5e9d54f 100644
--- a/arch/arm64/kernel/Makefile
+++ b/arch/arm64/kernel/Makefile
@@ -32,7 +32,9 @@ arm64-obj-$(CONFIG_CPU_PM)		+= sleep.o suspend.o
 arm64-obj-$(CONFIG_CPU_IDLE)		+= cpuidle.o
 arm64-obj-$(CONFIG_JUMP_LABEL)		+= jump_label.o
 arm64-obj-$(CONFIG_KGDB)		+= kgdb.o
-arm64-obj-$(CONFIG_KPROBES)		+= kprobes.o kprobes-arm64.o
+arm64-obj-$(CONFIG_KPROBES)		+= kprobes.o kprobes-arm64.o		\
+					   probes-simulate-insn.o		\
+					   probes-condn-check.o
 arm64-obj-$(CONFIG_EFI)			+= efi.o efi-stub.o efi-entry.o
 arm64-obj-$(CONFIG_PCI)			+= pci.o
 arm64-obj-$(CONFIG_ARMV8_DEPRECATED)	+= armv8_deprecated.o
diff --git a/arch/arm64/kernel/kprobes-arm64.c b/arch/arm64/kernel/kprobes-arm64.c
index f958c52..8a7e6b0 100644
--- a/arch/arm64/kernel/kprobes-arm64.c
+++ b/arch/arm64/kernel/kprobes-arm64.c
@@ -20,6 +20,76 @@
 #include <asm/insn.h>
 
 #include "kprobes-arm64.h"
+#include "probes-simulate-insn.h"
+
+/*
+ * condition check functions for kprobes simulation
+ */
+static unsigned long __kprobes
+__check_pstate(struct kprobe *p, struct pt_regs *regs)
+{
+	struct arch_specific_insn *asi = &p->ainsn;
+	unsigned long pstate = regs->pstate & 0xffffffff;
+
+	return asi->pstate_cc(pstate);
+}
+
+static unsigned long __kprobes
+__check_cbz(struct kprobe *p, struct pt_regs *regs)
+{
+	return check_cbz((u32)p->opcode, regs);
+}
+
+static unsigned long __kprobes
+__check_cbnz(struct kprobe *p, struct pt_regs *regs)
+{
+	return check_cbnz((u32)p->opcode, regs);
+}
+
+static unsigned long __kprobes
+__check_tbz(struct kprobe *p, struct pt_regs *regs)
+{
+	return check_tbz((u32)p->opcode, regs);
+}
+
+static unsigned long __kprobes
+__check_tbnz(struct kprobe *p, struct pt_regs *regs)
+{
+	return check_tbnz((u32)p->opcode, regs);
+}
+
+/*
+ * prepare functions for instruction simulation
+ */
+static void __kprobes
+prepare_none(struct kprobe *p, struct arch_specific_insn *asi)
+{
+}
+
+static void __kprobes
+prepare_bcond(struct kprobe *p, struct arch_specific_insn *asi)
+{
+	kprobe_opcode_t insn = p->opcode;
+
+	asi->check_condn = __check_pstate;
+	asi->pstate_cc = kprobe_condition_checks[insn & 0xf];
+}
+
+static void __kprobes
+prepare_cbz_cbnz(struct kprobe *p, struct arch_specific_insn *asi)
+{
+	kprobe_opcode_t insn = p->opcode;
+
+	asi->check_condn = (insn & (1 << 24)) ? __check_cbnz : __check_cbz;
+}
+
+static void __kprobes
+prepare_tbz_tbnz(struct kprobe *p, struct arch_specific_insn *asi)
+{
+	kprobe_opcode_t insn = p->opcode;
+
+	asi->check_condn = (insn & (1 << 24)) ? __check_tbnz : __check_tbz;
+}
 
 static bool __kprobes aarch64_insn_is_steppable(u32 insn)
 {
@@ -63,6 +133,34 @@ arm_kprobe_decode_insn(kprobe_opcode_t insn, struct arch_specific_insn *asi)
 	 */
 	if (aarch64_insn_is_steppable(insn))
 		return INSN_GOOD;
+
+	asi->prepare = prepare_none;
+
+	if (aarch64_insn_is_bcond(insn)) {
+		asi->prepare = prepare_bcond;
+		asi->handler = simulate_b_cond;
+	} else if (aarch64_insn_is_cb(insn)) {
+		asi->prepare = prepare_cbz_cbnz;
+		asi->handler = simulate_cbz_cbnz;
+	} else if (aarch64_insn_is_tb(insn)) {
+		asi->prepare = prepare_tbz_tbnz;
+		asi->handler = simulate_tbz_tbnz;
+	} else if (aarch64_insn_is_adr_adrp(insn))
+		asi->handler = simulate_adr_adrp;
+	else if (aarch64_insn_is_b_bl(insn))
+		asi->handler = simulate_b_bl;
+	else if (aarch64_insn_is_br_blr(insn) || aarch64_insn_is_ret(insn))
+		asi->handler = simulate_br_blr_ret;
+	else if (aarch64_insn_is_ldr_lit(insn))
+		asi->handler = simulate_ldr_literal;
+	else if (aarch64_insn_is_ldrsw_lit(insn))
+		asi->handler = simulate_ldrsw_literal;
 	else
+		/*
+		 * Instruction cannot be stepped out-of-line and we don't
+		 * (yet) simulate it.
+		 */
 		return INSN_REJECTED;
+
+	return INSN_GOOD_NO_SLOT;
 }
diff --git a/arch/arm64/kernel/kprobes-arm64.h b/arch/arm64/kernel/kprobes-arm64.h
index 87e7891..ff8a55f 100644
--- a/arch/arm64/kernel/kprobes-arm64.h
+++ b/arch/arm64/kernel/kprobes-arm64.h
@@ -22,6 +22,8 @@ enum kprobe_insn {
 	INSN_GOOD,
 };
 
+extern kprobes_pstate_check_t * const kprobe_condition_checks[16];
+
 enum kprobe_insn __kprobes
 arm_kprobe_decode_insn(kprobe_opcode_t insn, struct arch_specific_insn *asi);
 
diff --git a/arch/arm64/kernel/kprobes.c b/arch/arm64/kernel/kprobes.c
index 601d2c6..6255814 100644
--- a/arch/arm64/kernel/kprobes.c
+++ b/arch/arm64/kernel/kprobes.c
@@ -38,6 +38,9 @@
 DEFINE_PER_CPU(struct kprobe *, current_kprobe) = NULL;
 DEFINE_PER_CPU(struct kprobe_ctlblk, kprobe_ctlblk);
 
+static void __kprobes
+post_kprobe_handler(struct kprobe_ctlblk *, struct pt_regs *);
+
 static void __kprobes arch_prepare_ss_slot(struct kprobe *p)
 {
 	/* prepare insn slot */
@@ -54,6 +57,27 @@ static void __kprobes arch_prepare_ss_slot(struct kprobe *p)
 	p->ainsn.restore.type = RESTORE_PC;
 }
 
+static void __kprobes arch_prepare_simulate(struct kprobe *p)
+{
+	if (p->ainsn.prepare)
+		p->ainsn.prepare(p, &p->ainsn);
+
+	/* This instructions is not executed xol. No need to adjust the PC */
+	p->ainsn.restore.addr = 0;
+	p->ainsn.restore.type = NO_RESTORE;
+}
+
+static void __kprobes arch_simulate_insn(struct kprobe *p, struct pt_regs *regs)
+{
+	struct kprobe_ctlblk *kcb = get_kprobe_ctlblk();
+
+	if (p->ainsn.handler)
+		p->ainsn.handler((u32)p->opcode, (long)p->addr, regs);
+
+	/* single step simulated, now go for post processing */
+	post_kprobe_handler(kcb, regs);
+}
+
 int __kprobes arch_prepare_kprobe(struct kprobe *p)
 {
 	kprobe_opcode_t insn;
@@ -72,7 +96,8 @@ int __kprobes arch_prepare_kprobe(struct kprobe *p)
 		return -EINVAL;
 
 	case INSN_GOOD_NO_SLOT:	/* insn need simulation */
-		return -EINVAL;
+		p->ainsn.insn = NULL;
+		break;
 
 	case INSN_GOOD:	/* instruction uses slot */
 		p->ainsn.insn = get_insn_slot();
@@ -82,7 +107,10 @@ int __kprobes arch_prepare_kprobe(struct kprobe *p)
 	};
 
 	/* prepare the instruction */
-	arch_prepare_ss_slot(p);
+	if (p->ainsn.insn)
+		arch_prepare_ss_slot(p);
+	else
+		arch_prepare_simulate(p);
 
 	return 0;
 }
@@ -231,7 +259,8 @@ static void __kprobes setup_singlestep(struct kprobe *p,
 		kernel_enable_single_step(regs);
 		instruction_pointer(regs) = slot;
 	} else	{
-		BUG();
+		/* insn simulation */
+		arch_simulate_insn(p, regs);
 	}
 }
 
diff --git a/arch/arm64/kernel/probes-condn-check.c b/arch/arm64/kernel/probes-condn-check.c
new file mode 100644
index 0000000..e68aa0c
--- /dev/null
+++ b/arch/arm64/kernel/probes-condn-check.c
@@ -0,0 +1,122 @@
+/*
+ * arch/arm64/kernel/probes-condn-check.c
+ *
+ * Copyright (C) 2013 Linaro Limited
+ *
+ * Copied from: arch/arm/kernel/kprobes-common.c
+ *
+ * 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.
+ *
+ * Description:
+ *
+ *  AArch64 and AArch32 shares same conditional(CNZV) flags encoding.
+ *  This file implements conditional check helpers compatible with
+ *  both AArch64 and AArch32 modes. Uprobes on v8 can handle both 32-bit
+ *  & 64-bit user-space instructions, so we abstract the common functions
+ *  in this file. While AArch64 and AArch32 specific instruction handling
+ *  are implemented in separate files, this file contains common bits.
+ */
+#include <linux/kernel.h>
+#include <linux/module.h>
+#include <asm/probes.h>
+
+static unsigned long __kprobes __check_eq(unsigned long pstate)
+{
+	return pstate & PSR_Z_BIT;
+}
+
+static unsigned long __kprobes __check_ne(unsigned long pstate)
+{
+	return (~pstate) & PSR_Z_BIT;
+}
+
+static unsigned long __kprobes __check_cs(unsigned long pstate)
+{
+	return pstate & PSR_C_BIT;
+}
+
+static unsigned long __kprobes __check_cc(unsigned long pstate)
+{
+	return (~pstate) & PSR_C_BIT;
+}
+
+static unsigned long __kprobes __check_mi(unsigned long pstate)
+{
+	return pstate & PSR_N_BIT;
+}
+
+static unsigned long __kprobes __check_pl(unsigned long pstate)
+{
+	return (~pstate) & PSR_N_BIT;
+}
+
+static unsigned long __kprobes __check_vs(unsigned long pstate)
+{
+	return pstate & PSR_V_BIT;
+}
+
+static unsigned long __kprobes __check_vc(unsigned long pstate)
+{
+	return (~pstate) & PSR_V_BIT;
+}
+
+static unsigned long __kprobes __check_hi(unsigned long pstate)
+{
+	pstate &= ~(pstate >> 1);	/* PSR_C_BIT &= ~PSR_Z_BIT */
+	return pstate & PSR_C_BIT;
+}
+
+static unsigned long __kprobes __check_ls(unsigned long pstate)
+{
+	pstate &= ~(pstate >> 1);	/* PSR_C_BIT &= ~PSR_Z_BIT */
+	return (~pstate) & PSR_C_BIT;
+}
+
+static unsigned long __kprobes __check_ge(unsigned long pstate)
+{
+	pstate ^= (pstate << 3);	/* PSR_N_BIT ^= PSR_V_BIT */
+	return (~pstate) & PSR_N_BIT;
+}
+
+static unsigned long __kprobes __check_lt(unsigned long pstate)
+{
+	pstate ^= (pstate << 3);	/* PSR_N_BIT ^= PSR_V_BIT */
+	return pstate & PSR_N_BIT;
+}
+
+static unsigned long __kprobes __check_gt(unsigned long pstate)
+{
+	/*PSR_N_BIT ^= PSR_V_BIT */
+	unsigned long temp = pstate ^ (pstate << 3);
+
+	temp |= (pstate << 1);	/*PSR_N_BIT |= PSR_Z_BIT */
+	return (~temp) & PSR_N_BIT;
+}
+
+static unsigned long __kprobes __check_le(unsigned long pstate)
+{
+	/*PSR_N_BIT ^= PSR_V_BIT */
+	unsigned long temp = pstate ^ (pstate << 3);
+
+	temp |= (pstate << 1);	/*PSR_N_BIT |= PSR_Z_BIT */
+	return temp & PSR_N_BIT;
+}
+
+static unsigned long __kprobes __check_al(unsigned long pstate)
+{
+	return true;
+}
+
+kprobes_pstate_check_t * const kprobe_condition_checks[16] = {
+	&__check_eq, &__check_ne, &__check_cs, &__check_cc,
+	&__check_mi, &__check_pl, &__check_vs, &__check_vc,
+	&__check_hi, &__check_ls, &__check_ge, &__check_lt,
+	&__check_gt, &__check_le, &__check_al, &__check_al
+};
diff --git a/arch/arm64/kernel/probes-simulate-insn.c b/arch/arm64/kernel/probes-simulate-insn.c
new file mode 100644
index 0000000..b7d6ab7
--- /dev/null
+++ b/arch/arm64/kernel/probes-simulate-insn.c
@@ -0,0 +1,170 @@
+/*
+ * arch/arm64/kernel/probes-simulate-insn.c
+ *
+ * Copyright (C) 2013 Linaro Limited.
+ *
+ * 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/kernel.h>
+#include <linux/kprobes.h>
+#include <linux/module.h>
+
+#include "probes-simulate-insn.h"
+
+#define sign_extend(x, signbit)		\
+	((x) | (0 - ((x) & (1 << (signbit)))))
+
+#define bbl_displacement(insn)		\
+	sign_extend(((insn) & 0x3ffffff) << 2, 27)
+
+#define bcond_displacement(insn)	\
+	sign_extend(((insn >> 5) & 0x7ffff) << 2, 21)
+
+#define cbz_displacement(insn)	\
+	sign_extend(((insn >> 5) & 0x7ffff) << 2, 21)
+
+#define tbz_displacement(insn)	\
+	sign_extend(((insn >> 5) & 0x3fff) << 2, 15)
+
+#define ldr_displacement(insn)	\
+	sign_extend(((insn >> 5) & 0x7ffff) << 2, 21)
+
+
+unsigned long __kprobes check_cbz(u32 opcode, struct pt_regs *regs)
+{
+	int xn = opcode & 0x1f;
+
+	return (opcode & (1 << 31)) ?
+	    !(regs->regs[xn]) : !(regs->regs[xn] & 0xffffffff);
+}
+
+unsigned long __kprobes check_cbnz(u32 opcode, struct pt_regs *regs)
+{
+	int xn = opcode & 0x1f;
+
+	return (opcode & (1 << 31)) ?
+	    (regs->regs[xn]) : (regs->regs[xn] & 0xffffffff);
+}
+
+unsigned long __kprobes check_tbz(u32 opcode, struct pt_regs *regs)
+{
+	int xn = opcode & 0x1f;
+	int bit_pos = ((opcode & (1 << 31)) >> 26) | ((opcode >> 19) & 0x1f);
+
+	return ~((regs->regs[xn] >> bit_pos) & 0x1);
+}
+
+unsigned long __kprobes check_tbnz(u32 opcode, struct pt_regs *regs)
+{
+	int xn = opcode & 0x1f;
+	int bit_pos = ((opcode & (1 << 31)) >> 26) | ((opcode >> 19) & 0x1f);
+
+	return (regs->regs[xn] >> bit_pos) & 0x1;
+}
+
+/*
+ * instruction simulation functions
+ */
+void __kprobes
+simulate_adr_adrp(u32 opcode, long addr, struct pt_regs *regs)
+{
+	long imm, xn, val;
+
+	xn = opcode & 0x1f;
+	imm = ((opcode >> 3) & 0x1ffffc) | ((opcode >> 29) & 0x3);
+	imm = sign_extend(imm, 20);
+	if (opcode & 0x80000000)
+		val = (imm<<12) + (addr & 0xfffffffffffff000);
+	else
+		val = imm + addr;
+
+	regs->regs[xn] = val;
+
+	instruction_pointer(regs) += 4;
+}
+
+void __kprobes
+simulate_b_bl(u32 opcode, long addr, struct pt_regs *regs)
+{
+	int disp = bbl_displacement(opcode);
+
+	/* Link register is x30 */
+	if (opcode & (1 << 31))
+		regs->regs[30] = addr + 4;
+
+	instruction_pointer(regs) = addr + disp;
+}
+
+void __kprobes
+simulate_b_cond(u32 opcode, long addr, struct pt_regs *regs)
+{
+	int disp = bcond_displacement(opcode);
+
+	instruction_pointer(regs) = addr + disp;
+}
+
+void __kprobes
+simulate_br_blr_ret(u32 opcode, long addr, struct pt_regs *regs)
+{
+	int xn = (opcode >> 5) & 0x1f;
+
+	/* Link register is x30 */
+	if (((opcode >> 21) & 0x3) == 1)
+		regs->regs[30] = addr + 4;
+
+	instruction_pointer(regs) = regs->regs[xn];
+}
+
+void __kprobes
+simulate_cbz_cbnz(u32 opcode, long addr, struct pt_regs *regs)
+{
+	int disp = cbz_displacement(opcode);
+
+	instruction_pointer(regs) = addr + disp;
+}
+
+void __kprobes
+simulate_tbz_tbnz(u32 opcode, long addr, struct pt_regs *regs)
+{
+	int disp = tbz_displacement(opcode);
+
+	instruction_pointer(regs) = addr + disp;
+}
+
+void __kprobes
+simulate_ldr_literal(u32 opcode, long addr, struct pt_regs *regs)
+{
+	u64 *load_addr;
+	int xn = opcode & 0x1f;
+	int disp = ldr_displacement(opcode);
+
+	load_addr = (u64 *) (addr + disp);
+
+	if (opcode & (1 << 30))	/* x0-x31 */
+		regs->regs[xn] = *load_addr;
+	else			/* w0-w31 */
+		*(u32 *) (&regs->regs[xn]) = (*(u32 *) (load_addr));
+
+	instruction_pointer(regs) += 4;
+}
+
+void __kprobes
+simulate_ldrsw_literal(u32 opcode, long addr, struct pt_regs *regs)
+{
+	s32 *load_addr;
+	int xn = opcode & 0x1f;
+	int disp = ldr_displacement(opcode);
+
+	load_addr = (s32 *) (addr + disp);
+	regs->regs[xn] = *load_addr;
+
+	instruction_pointer(regs) += 4;
+}
diff --git a/arch/arm64/kernel/probes-simulate-insn.h b/arch/arm64/kernel/probes-simulate-insn.h
new file mode 100644
index 0000000..0d8873f
--- /dev/null
+++ b/arch/arm64/kernel/probes-simulate-insn.h
@@ -0,0 +1,32 @@
+/*
+ * arch/arm64/kernel/probes-simulate-insn.h
+ *
+ * Copyright (C) 2013 Linaro Limited
+ *
+ * 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.
+ */
+
+#ifndef _ARM_KERNEL_PROBES_SIMULATE_INSN_H
+#define _ARM_KERNEL_PROBES_SIMULATE_INSN_H
+
+unsigned long check_cbz(u32 opcode, struct pt_regs *regs);
+unsigned long check_cbnz(u32 opcode, struct pt_regs *regs);
+unsigned long check_tbz(u32 opcode, struct pt_regs *regs);
+unsigned long check_tbnz(u32 opcode, struct pt_regs *regs);
+void simulate_adr_adrp(u32 opcode, long addr, struct pt_regs *regs);
+void simulate_b_bl(u32 opcode, long addr, struct pt_regs *regs);
+void simulate_b_cond(u32 opcode, long addr, struct pt_regs *regs);
+void simulate_br_blr_ret(u32 opcode, long addr, struct pt_regs *regs);
+void simulate_cbz_cbnz(u32 opcode, long addr, struct pt_regs *regs);
+void simulate_tbz_tbnz(u32 opcode, long addr, struct pt_regs *regs);
+void simulate_ldr_literal(u32 opcode, long addr, struct pt_regs *regs);
+void simulate_ldrsw_literal(u32 opcode, long addr, struct pt_regs *regs);
+
+#endif /* _ARM_KERNEL_PROBES_SIMULATE_INSN_H */
-- 
1.8.1.2



From dave.long at linaro.org  Mon Aug 10 17:52:40 2015
From: dave.long at linaro.org (David Long)
Date: Mon, 10 Aug 2015 20:52:40 -0400
Subject: [PATCH v8 3/7] arm64: Kprobes with single stepping support
In-Reply-To: <1439254364-15362-1-git-send-email-dave.long@linaro.org>
References: <1439254364-15362-1-git-send-email-dave.long@linaro.org>
Message-ID: <1439254364-15362-4-git-send-email-dave.long@linaro.org>

From: Sandeepa Prabhu <sandeepa.s.prabhu at gmail.com>

Add support for basic kernel probes(kprobes) and jump probes
(jprobes) for ARM64.

Kprobes utilizes software breakpoint and single step debug
exceptions supported on ARM v8.

A software breakpoint is placed at the probe address to trap the
kernel execution into the kprobe handler.

ARM v8 supports enabling single stepping before the break exception
return (ERET), with next PC in exception return address (ELR_EL1). The
kprobe handler prepares an executable memory slot for out-of-line
execution with a copy of the original instruction being probed, and
enables single stepping. The PC is set to the out-of-line slot address
before the ERET. With this scheme, the instruction is executed with the
exact same register context except for the PC (and DAIF) registers.

Debug mask (PSTATE.D) is enabled only when single stepping a recursive
kprobe, e.g.: during kprobes reenter so that probed instruction can be
single stepped within the kprobe handler -exception- context.
The recursion depth of kprobe is always 2, i.e. upon probe re-entry,
any further re-entry is prevented by not calling handlers and the case
counted as a missed kprobe).

Single stepping from the x-o-l slot has a drawback for PC-relative accesses
like branching and symbolic literals access as the offset from the new PC
(slot address) may not be ensured to fit in the immediate value of
the opcode. Such instructions need simulation, so reject
probing them.

Instructions generating exceptions or cpu mode change are rejected
for probing.

Instructions using Exclusive Monitor are rejected too.

System instructions are mostly enabled for stepping, except MSR/MRS
accesses to "DAIF" flags in PSTATE, which are not safe for
probing.

Thanks to Steve Capper and Pratyush Anand for several suggested
Changes.

Signed-off-by: Sandeepa Prabhu <sandeepa.s.prabhu at gmail.com>
Signed-off-by: Steve Capper <steve.capper at linaro.org>
Signed-off-by: David A. Long <dave.long at linaro.org>
---
 arch/arm64/Kconfig                      |   1 +
 arch/arm64/include/asm/debug-monitors.h |   5 +
 arch/arm64/include/asm/kprobes.h        |  62 ++++
 arch/arm64/include/asm/probes.h         |  50 +++
 arch/arm64/include/asm/ptrace.h         |   3 +-
 arch/arm64/kernel/Makefile              |   1 +
 arch/arm64/kernel/debug-monitors.c      |  35 ++-
 arch/arm64/kernel/kprobes-arm64.c       |  68 ++++
 arch/arm64/kernel/kprobes-arm64.h       |  28 ++
 arch/arm64/kernel/kprobes.c             | 537 ++++++++++++++++++++++++++++++++
 arch/arm64/kernel/kprobes.h             |  24 ++
 arch/arm64/kernel/vmlinux.lds.S         |   1 +
 arch/arm64/mm/fault.c                   |  25 ++
 13 files changed, 829 insertions(+), 11 deletions(-)
 create mode 100644 arch/arm64/include/asm/kprobes.h
 create mode 100644 arch/arm64/include/asm/probes.h
 create mode 100644 arch/arm64/kernel/kprobes-arm64.c
 create mode 100644 arch/arm64/kernel/kprobes-arm64.h
 create mode 100644 arch/arm64/kernel/kprobes.c
 create mode 100644 arch/arm64/kernel/kprobes.h

diff --git a/arch/arm64/Kconfig b/arch/arm64/Kconfig
index ef5d726..1bb07f7 100644
--- a/arch/arm64/Kconfig
+++ b/arch/arm64/Kconfig
@@ -73,6 +73,7 @@ config ARM64
 	select HAVE_REGS_AND_STACK_ACCESS_API
 	select HAVE_RCU_TABLE_FREE
 	select HAVE_SYSCALL_TRACEPOINTS
+	select HAVE_KPROBES
 	select IRQ_DOMAIN
 	select IRQ_FORCED_THREADING
 	select MODULES_USE_ELF_RELA
diff --git a/arch/arm64/include/asm/debug-monitors.h b/arch/arm64/include/asm/debug-monitors.h
index 40ec68a..92d7cea 100644
--- a/arch/arm64/include/asm/debug-monitors.h
+++ b/arch/arm64/include/asm/debug-monitors.h
@@ -90,6 +90,11 @@
 
 #define CACHE_FLUSH_IS_SAFE		1
 
+/* kprobes BRK opcodes with ESR encoding  */
+#define BRK64_ESR_MASK		0xFFFF
+#define BRK64_ESR_KPROBES	0x0004
+#define BRK64_OPCODE_KPROBES	(AARCH64_BREAK_MON | (BRK64_ESR_KPROBES << 5))
+
 /* AArch32 */
 #define DBG_ESR_EVT_BKPT	0x4
 #define DBG_ESR_EVT_VECC	0x5
diff --git a/arch/arm64/include/asm/kprobes.h b/arch/arm64/include/asm/kprobes.h
new file mode 100644
index 0000000..af31c4d
--- /dev/null
+++ b/arch/arm64/include/asm/kprobes.h
@@ -0,0 +1,62 @@
+/*
+ * arch/arm64/include/asm/kprobes.h
+ *
+ * Copyright (C) 2013 Linaro Limited
+ *
+ * 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.
+ */
+
+#ifndef _ARM_KPROBES_H
+#define _ARM_KPROBES_H
+
+#include <linux/types.h>
+#include <linux/ptrace.h>
+#include <linux/percpu.h>
+
+#define __ARCH_WANT_KPROBES_INSN_SLOT
+#define MAX_INSN_SIZE			1
+#define MAX_STACK_SIZE			128
+
+#define flush_insn_slot(p)		do { } while (0)
+#define kretprobe_blacklist_size	0
+
+#include <asm/probes.h>
+
+struct prev_kprobe {
+	struct kprobe *kp;
+	unsigned int status;
+};
+
+/* Single step context for kprobe */
+struct kprobe_step_ctx {
+#define KPROBES_STEP_NONE	0x0
+#define KPROBES_STEP_PENDING	0x1
+	unsigned long ss_status;
+	unsigned long match_addr;
+};
+
+/* per-cpu kprobe control block */
+struct kprobe_ctlblk {
+	unsigned int kprobe_status;
+	unsigned long saved_irqflag;
+	struct prev_kprobe prev_kprobe;
+	struct kprobe_step_ctx ss_ctx;
+	struct pt_regs jprobe_saved_regs;
+	char jprobes_stack[MAX_STACK_SIZE];
+};
+
+void arch_remove_kprobe(struct kprobe *);
+int kprobe_fault_handler(struct pt_regs *regs, unsigned int fsr);
+int kprobe_exceptions_notify(struct notifier_block *self,
+			     unsigned long val, void *data);
+int kprobe_breakpoint_handler(struct pt_regs *regs, unsigned int esr);
+int kprobe_single_step_handler(struct pt_regs *regs, unsigned int esr);
+
+#endif /* _ARM_KPROBES_H */
diff --git a/arch/arm64/include/asm/probes.h b/arch/arm64/include/asm/probes.h
new file mode 100644
index 0000000..7f5a27f
--- /dev/null
+++ b/arch/arm64/include/asm/probes.h
@@ -0,0 +1,50 @@
+/*
+ * arch/arm64/include/asm/probes.h
+ *
+ * Copyright (C) 2013 Linaro Limited
+ *
+ * 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.
+ */
+#ifndef _ARM_PROBES_H
+#define _ARM_PROBES_H
+
+struct kprobe;
+struct arch_specific_insn;
+
+typedef u32 kprobe_opcode_t;
+typedef unsigned long (kprobes_pstate_check_t)(unsigned long);
+typedef unsigned long
+(probes_condition_check_t)(struct kprobe *p, struct pt_regs *);
+typedef void
+(probes_prepare_t)(struct kprobe *, struct arch_specific_insn *);
+typedef void (kprobes_handler_t) (u32 opcode, long addr, struct pt_regs *);
+
+enum pc_restore_type {
+	NO_RESTORE,
+	RESTORE_PC,
+};
+
+struct kprobe_pc_restore {
+	enum pc_restore_type type;
+	unsigned long addr;
+};
+
+/* architecture specific copy of original instruction */
+struct arch_specific_insn {
+	kprobe_opcode_t *insn;
+	kprobes_pstate_check_t *pstate_cc;
+	probes_condition_check_t *check_condn;
+	probes_prepare_t *prepare;
+	kprobes_handler_t *handler;
+	/* restore address after step xol */
+	struct kprobe_pc_restore restore;
+};
+
+#endif
diff --git a/arch/arm64/include/asm/ptrace.h b/arch/arm64/include/asm/ptrace.h
index 8f440e9..aadf61a 100644
--- a/arch/arm64/include/asm/ptrace.h
+++ b/arch/arm64/include/asm/ptrace.h
@@ -206,7 +206,8 @@ static inline int valid_user_regs(struct user_pt_regs *regs)
 	return 0;
 }
 
-#define instruction_pointer(regs)	((unsigned long)(regs)->pc)
+#define instruction_pointer(regs)	((regs)->pc)
+#define stack_pointer(regs)		((regs)->sp)
 
 #ifdef CONFIG_SMP
 extern unsigned long profile_pc(struct pt_regs *regs);
diff --git a/arch/arm64/kernel/Makefile b/arch/arm64/kernel/Makefile
index 426d076..1319872 100644
--- a/arch/arm64/kernel/Makefile
+++ b/arch/arm64/kernel/Makefile
@@ -32,6 +32,7 @@ arm64-obj-$(CONFIG_CPU_PM)		+= sleep.o suspend.o
 arm64-obj-$(CONFIG_CPU_IDLE)		+= cpuidle.o
 arm64-obj-$(CONFIG_JUMP_LABEL)		+= jump_label.o
 arm64-obj-$(CONFIG_KGDB)		+= kgdb.o
+arm64-obj-$(CONFIG_KPROBES)		+= kprobes.o kprobes-arm64.o
 arm64-obj-$(CONFIG_EFI)			+= efi.o efi-stub.o efi-entry.o
 arm64-obj-$(CONFIG_PCI)			+= pci.o
 arm64-obj-$(CONFIG_ARMV8_DEPRECATED)	+= armv8_deprecated.o
diff --git a/arch/arm64/kernel/debug-monitors.c b/arch/arm64/kernel/debug-monitors.c
index b056369..486ee94 100644
--- a/arch/arm64/kernel/debug-monitors.c
+++ b/arch/arm64/kernel/debug-monitors.c
@@ -23,6 +23,7 @@
 #include <linux/hardirq.h>
 #include <linux/init.h>
 #include <linux/ptrace.h>
+#include <linux/kprobes.h>
 #include <linux/stat.h>
 #include <linux/uaccess.h>
 
@@ -228,6 +229,7 @@ static int single_step_handler(unsigned long addr, unsigned int esr,
 			       struct pt_regs *regs)
 {
 	siginfo_t info;
+	bool handler_found = false;
 
 	/*
 	 * If we are stepping a pending breakpoint, call the hw_breakpoint
@@ -251,15 +253,21 @@ static int single_step_handler(unsigned long addr, unsigned int esr,
 		 */
 		user_rewind_single_step(current);
 	} else {
+#ifdef	CONFIG_KPROBES
+		if (kprobe_single_step_handler(regs, esr) == DBG_HOOK_HANDLED)
+			handler_found = true;
+#endif
 		if (call_step_hook(regs, esr) == DBG_HOOK_HANDLED)
-			return 0;
-
-		pr_warning("Unexpected kernel single-step exception at EL1\n");
-		/*
-		 * Re-enable stepping since we know that we will be
-		 * returning to regs.
-		 */
-		set_regs_spsr_ss(regs);
+			handler_found = true;
+
+		if (!handler_found) {
+			pr_warn("Unexpected kernel single-step exception at EL1\n");
+			/*
+			 * Re-enable stepping since we know that we will be
+			 * returning to regs.
+			 */
+			set_regs_spsr_ss(regs);
+		}
 	}
 
 	return 0;
@@ -315,8 +323,15 @@ static int brk_handler(unsigned long addr, unsigned int esr,
 		};
 
 		force_sig_info(SIGTRAP, &info, current);
-	} else if (call_break_hook(regs, esr) != DBG_HOOK_HANDLED) {
-		pr_warning("Unexpected kernel BRK exception at EL1\n");
+	}
+#ifdef	CONFIG_KPROBES
+	else if ((esr & BRK64_ESR_MASK) == BRK64_ESR_KPROBES) {
+		if (kprobe_breakpoint_handler(regs, esr) != DBG_HOOK_HANDLED)
+			return -EFAULT;
+	}
+#endif
+	else if (call_break_hook(regs, esr) != DBG_HOOK_HANDLED) {
+		pr_warn("Unexpected kernel BRK exception at EL1\n");
 		return -EFAULT;
 	}
 
diff --git a/arch/arm64/kernel/kprobes-arm64.c b/arch/arm64/kernel/kprobes-arm64.c
new file mode 100644
index 0000000..f958c52
--- /dev/null
+++ b/arch/arm64/kernel/kprobes-arm64.c
@@ -0,0 +1,68 @@
+/*
+ * arch/arm64/kernel/kprobes-arm64.c
+ *
+ * Copyright (C) 2013 Linaro Limited.
+ *
+ * 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/kernel.h>
+#include <linux/kprobes.h>
+#include <linux/module.h>
+#include <asm/kprobes.h>
+#include <asm/insn.h>
+
+#include "kprobes-arm64.h"
+
+static bool __kprobes aarch64_insn_is_steppable(u32 insn)
+{
+	if (aarch64_get_insn_class(insn) == AARCH64_INSN_CLS_BR_SYS) {
+		if (aarch64_insn_is_branch(insn))
+			return false;
+
+		/* modification of daif creates issues */
+		if (aarch64_insn_is_daif_access(insn))
+			return false;
+
+		if (aarch64_insn_is_exception(insn))
+			return false;
+
+		if (aarch64_insn_is_hint(insn))
+			return aarch64_insn_is_nop(insn);
+
+		return true;
+	}
+
+	if (aarch64_insn_uses_literal(insn))
+		return false;
+
+	if (aarch64_insn_is_exclusive(insn))
+		return false;
+
+	return true;
+}
+
+/* Return:
+ *   INSN_REJECTED     If instruction is one not allowed to kprobe,
+ *   INSN_GOOD         If instruction is supported and uses instruction slot,
+ *   INSN_GOOD_NO_SLOT If instruction is supported but doesn't use its slot.
+ */
+enum kprobe_insn __kprobes
+arm_kprobe_decode_insn(kprobe_opcode_t insn, struct arch_specific_insn *asi)
+{
+	/*
+	 * Instructions reading or modifying the PC won't work from the XOL
+	 * slot.
+	 */
+	if (aarch64_insn_is_steppable(insn))
+		return INSN_GOOD;
+	else
+		return INSN_REJECTED;
+}
diff --git a/arch/arm64/kernel/kprobes-arm64.h b/arch/arm64/kernel/kprobes-arm64.h
new file mode 100644
index 0000000..87e7891
--- /dev/null
+++ b/arch/arm64/kernel/kprobes-arm64.h
@@ -0,0 +1,28 @@
+/*
+ * arch/arm64/kernel/kprobes-arm64.h
+ *
+ * Copyright (C) 2013 Linaro Limited.
+ *
+ * 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.
+ */
+
+#ifndef _ARM_KERNEL_KPROBES_ARM64_H
+#define _ARM_KERNEL_KPROBES_ARM64_H
+
+enum kprobe_insn {
+	INSN_REJECTED,
+	INSN_GOOD_NO_SLOT,
+	INSN_GOOD,
+};
+
+enum kprobe_insn __kprobes
+arm_kprobe_decode_insn(kprobe_opcode_t insn, struct arch_specific_insn *asi);
+
+#endif /* _ARM_KERNEL_KPROBES_ARM64_H */
diff --git a/arch/arm64/kernel/kprobes.c b/arch/arm64/kernel/kprobes.c
new file mode 100644
index 0000000..601d2c6
--- /dev/null
+++ b/arch/arm64/kernel/kprobes.c
@@ -0,0 +1,537 @@
+/*
+ * arch/arm64/kernel/kprobes.c
+ *
+ * Kprobes support for ARM64
+ *
+ * Copyright (C) 2013 Linaro Limited.
+ * Author: Sandeepa Prabhu <sandeepa.prabhu at linaro.org>
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License version 2 as
+ * published by the Free Software Foundation.
+ *
+ * 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/kernel.h>
+#include <linux/kprobes.h>
+#include <linux/module.h>
+#include <linux/slab.h>
+#include <linux/stop_machine.h>
+#include <linux/stringify.h>
+#include <asm/traps.h>
+#include <asm/ptrace.h>
+#include <asm/cacheflush.h>
+#include <asm/debug-monitors.h>
+#include <asm/system_misc.h>
+#include <asm/insn.h>
+
+#include "kprobes.h"
+#include "kprobes-arm64.h"
+
+#define MIN_STACK_SIZE(addr)	min((unsigned long)MAX_STACK_SIZE,	\
+	(unsigned long)current_thread_info() + THREAD_START_SP - (addr))
+
+DEFINE_PER_CPU(struct kprobe *, current_kprobe) = NULL;
+DEFINE_PER_CPU(struct kprobe_ctlblk, kprobe_ctlblk);
+
+static void __kprobes arch_prepare_ss_slot(struct kprobe *p)
+{
+	/* prepare insn slot */
+	p->ainsn.insn[0] = p->opcode;
+
+	flush_icache_range((uintptr_t) (p->ainsn.insn),
+			   (uintptr_t) (p->ainsn.insn) + MAX_INSN_SIZE);
+
+	/*
+	 * Needs restoring of return address after stepping xol.
+	 */
+	p->ainsn.restore.addr = (unsigned long) p->addr +
+	  sizeof(kprobe_opcode_t);
+	p->ainsn.restore.type = RESTORE_PC;
+}
+
+int __kprobes arch_prepare_kprobe(struct kprobe *p)
+{
+	kprobe_opcode_t insn;
+	unsigned long probe_addr = (unsigned long)p->addr;
+
+	/* copy instruction */
+	insn = *p->addr;
+	p->opcode = insn;
+
+	if (in_exception_text(probe_addr))
+		return -EINVAL;
+
+	/* decode instruction */
+	switch (arm_kprobe_decode_insn(insn, &p->ainsn)) {
+	case INSN_REJECTED:	/* insn not supported */
+		return -EINVAL;
+
+	case INSN_GOOD_NO_SLOT:	/* insn need simulation */
+		return -EINVAL;
+
+	case INSN_GOOD:	/* instruction uses slot */
+		p->ainsn.insn = get_insn_slot();
+		if (!p->ainsn.insn)
+			return -ENOMEM;
+		break;
+	};
+
+	/* prepare the instruction */
+	arch_prepare_ss_slot(p);
+
+	return 0;
+}
+
+static int __kprobes patch_text(kprobe_opcode_t *addr, u32 opcode)
+{
+	void *addrs[1];
+	u32 insns[1];
+
+	addrs[0] = (void *)addr;
+	insns[0] = (u32)opcode;
+
+	return aarch64_insn_patch_text_sync(addrs, insns, 1);
+}
+
+/* arm kprobe: install breakpoint in text */
+void __kprobes arch_arm_kprobe(struct kprobe *p)
+{
+	patch_text(p->addr, BRK64_OPCODE_KPROBES);
+}
+
+/* disarm kprobe: remove breakpoint from text */
+void __kprobes arch_disarm_kprobe(struct kprobe *p)
+{
+	patch_text(p->addr, p->opcode);
+}
+
+void __kprobes arch_remove_kprobe(struct kprobe *p)
+{
+	if (p->ainsn.insn) {
+		free_insn_slot(p->ainsn.insn, 0);
+		p->ainsn.insn = NULL;
+	}
+}
+
+static void __kprobes save_previous_kprobe(struct kprobe_ctlblk *kcb)
+{
+	kcb->prev_kprobe.kp = kprobe_running();
+	kcb->prev_kprobe.status = kcb->kprobe_status;
+}
+
+static void __kprobes restore_previous_kprobe(struct kprobe_ctlblk *kcb)
+{
+	__this_cpu_write(current_kprobe, kcb->prev_kprobe.kp);
+	kcb->kprobe_status = kcb->prev_kprobe.status;
+}
+
+static void __kprobes set_current_kprobe(struct kprobe *p)
+{
+	__this_cpu_write(current_kprobe, p);
+}
+
+/*
+ * The D-flag (Debug mask) is set (masked) upon exception entry.
+ * Kprobes needs to clear (unmask) D-flag -ONLY- in case of recursive
+ * probe i.e. when probe hit from kprobe handler context upon
+ * executing the pre/post handlers. In this case we return with
+ * D-flag clear so that single-stepping can be carried-out.
+ *
+ * Leave D-flag set in all other cases.
+ */
+static void __kprobes
+spsr_set_debug_flag(struct pt_regs *regs, int mask)
+{
+	unsigned long spsr = regs->pstate;
+
+	if (mask)
+		spsr |= PSR_D_BIT;
+	else
+		spsr &= ~PSR_D_BIT;
+
+	regs->pstate = spsr;
+}
+
+/*
+ * Interrupts need to be disabled before single-step mode is set, and not
+ * reenabled until after single-step mode ends.
+ * Without disabling interrupt on local CPU, there is a chance of
+ * interrupt occurrence in the period of exception return and  start of
+ * out-of-line single-step, that result in wrongly single stepping
+ * the interrupt handler.
+ */
+static void __kprobes kprobes_save_local_irqflag(struct pt_regs *regs)
+{
+	struct kprobe_ctlblk *kcb = get_kprobe_ctlblk();
+
+	kcb->saved_irqflag = regs->pstate;
+	regs->pstate |= PSR_I_BIT;
+}
+
+static void __kprobes kprobes_restore_local_irqflag(struct pt_regs *regs)
+{
+	struct kprobe_ctlblk *kcb = get_kprobe_ctlblk();
+
+	if (kcb->saved_irqflag & PSR_I_BIT)
+		regs->pstate |= PSR_I_BIT;
+	else
+		regs->pstate &= ~PSR_I_BIT;
+}
+
+static void __kprobes
+set_ss_context(struct kprobe_ctlblk *kcb, unsigned long addr)
+{
+	kcb->ss_ctx.ss_status = KPROBES_STEP_PENDING;
+	kcb->ss_ctx.match_addr = addr + sizeof(kprobe_opcode_t);
+}
+
+static void __kprobes clear_ss_context(struct kprobe_ctlblk *kcb)
+{
+	kcb->ss_ctx.ss_status = KPROBES_STEP_NONE;
+	kcb->ss_ctx.match_addr = 0;
+}
+
+static void __kprobes
+skip_singlestep_missed(struct kprobe_ctlblk *kcb, struct pt_regs *regs)
+{
+	/* set return addr to next pc to continue */
+	instruction_pointer(regs) += sizeof(kprobe_opcode_t);
+}
+
+static void __kprobes setup_singlestep(struct kprobe *p,
+				       struct pt_regs *regs,
+				       struct kprobe_ctlblk *kcb, int reenter)
+{
+	unsigned long slot;
+
+	if (reenter) {
+		save_previous_kprobe(kcb);
+		set_current_kprobe(p);
+		kcb->kprobe_status = KPROBE_REENTER;
+	} else {
+		kcb->kprobe_status = KPROBE_HIT_SS;
+	}
+
+	if (p->ainsn.insn) {
+		/* prepare for single stepping */
+		slot = (unsigned long)p->ainsn.insn;
+
+		set_ss_context(kcb, slot);	/* mark pending ss */
+
+		if (kcb->kprobe_status == KPROBE_REENTER)
+			spsr_set_debug_flag(regs, 0);
+
+		/* IRQs and single stepping do not mix well. */
+		kprobes_save_local_irqflag(regs);
+		kernel_enable_single_step(regs);
+		instruction_pointer(regs) = slot;
+	} else	{
+		BUG();
+	}
+}
+
+static int __kprobes reenter_kprobe(struct kprobe *p,
+				    struct pt_regs *regs,
+				    struct kprobe_ctlblk *kcb)
+{
+	switch (kcb->kprobe_status) {
+	case KPROBE_HIT_SSDONE:
+	case KPROBE_HIT_ACTIVE:
+		if (!p->ainsn.check_condn || p->ainsn.check_condn(p, regs)) {
+			kprobes_inc_nmissed_count(p);
+			setup_singlestep(p, regs, kcb, 1);
+		} else	{
+			/* condition check failed, skip stepping */
+			skip_singlestep_missed(kcb, regs);
+		}
+		break;
+	case KPROBE_HIT_SS:
+	case KPROBE_REENTER:
+		pr_warn("Unrecoverable kprobe detected at %p.\n", p->addr);
+		dump_kprobe(p);
+		BUG();
+		break;
+	default:
+		WARN_ON(1);
+		return 0;
+	}
+
+	return 1;
+}
+
+static void __kprobes
+post_kprobe_handler(struct kprobe_ctlblk *kcb, struct pt_regs *regs)
+{
+	struct kprobe *cur = kprobe_running();
+
+	if (!cur)
+		return;
+
+	/* return addr restore if non-branching insn */
+	if (cur->ainsn.restore.type == RESTORE_PC) {
+		instruction_pointer(regs) = cur->ainsn.restore.addr;
+		if (!instruction_pointer(regs))
+			BUG();
+	}
+
+	/* restore back original saved kprobe variables and continue */
+	if (kcb->kprobe_status == KPROBE_REENTER) {
+		restore_previous_kprobe(kcb);
+		return;
+	}
+	/* call post handler */
+	kcb->kprobe_status = KPROBE_HIT_SSDONE;
+	if (cur->post_handler)	{
+		/* post_handler can hit breakpoint and single step
+		 * again, so we enable D-flag for recursive exception.
+		 */
+		cur->post_handler(cur, regs, 0);
+	}
+
+	reset_current_kprobe();
+}
+
+int __kprobes kprobe_fault_handler(struct pt_regs *regs, unsigned int fsr)
+{
+	struct kprobe *cur = kprobe_running();
+	struct kprobe_ctlblk *kcb = get_kprobe_ctlblk();
+
+	switch (kcb->kprobe_status) {
+	case KPROBE_HIT_SS:
+	case KPROBE_REENTER:
+		/*
+		 * We are here because the instruction being single
+		 * stepped caused a page fault. We reset the current
+		 * kprobe and the ip points back to the probe address
+		 * and allow the page fault handler to continue as a
+		 * normal page fault.
+		 */
+		instruction_pointer(regs) = (unsigned long)cur->addr;
+		if (!instruction_pointer(regs))
+			BUG();
+		if (kcb->kprobe_status == KPROBE_REENTER)
+			restore_previous_kprobe(kcb);
+		else
+			reset_current_kprobe();
+
+		break;
+	case KPROBE_HIT_ACTIVE:
+	case KPROBE_HIT_SSDONE:
+		/*
+		 * We increment the nmissed count for accounting,
+		 * we can also use npre/npostfault count for accounting
+		 * these specific fault cases.
+		 */
+		kprobes_inc_nmissed_count(cur);
+
+		/*
+		 * We come here because instructions in the pre/post
+		 * handler caused the page_fault, this could happen
+		 * if handler tries to access user space by
+		 * copy_from_user(), get_user() etc. Let the
+		 * user-specified handler try to fix it first.
+		 */
+		if (cur->fault_handler && cur->fault_handler(cur, regs, fsr))
+			return 1;
+
+		/*
+		 * In case the user-specified fault handler returned
+		 * zero, try to fix up.
+		 */
+		if (fixup_exception(regs))
+			return 1;
+
+		break;
+	}
+	return 0;
+}
+
+int __kprobes kprobe_exceptions_notify(struct notifier_block *self,
+				       unsigned long val, void *data)
+{
+	return NOTIFY_DONE;
+}
+
+void __kprobes kprobe_handler(struct pt_regs *regs)
+{
+	struct kprobe *p, *cur;
+	struct kprobe_ctlblk *kcb;
+	unsigned long addr = instruction_pointer(regs);
+
+	kcb = get_kprobe_ctlblk();
+	cur = kprobe_running();
+
+	p = get_kprobe((kprobe_opcode_t *) addr);
+
+	if (p) {
+		if (cur) {
+			if (reenter_kprobe(p, regs, kcb))
+				return;
+		} else if (!p->ainsn.check_condn ||
+			   p->ainsn.check_condn(p, regs)) {
+			/* Probe hit and conditional execution check ok. */
+			set_current_kprobe(p);
+			kcb->kprobe_status = KPROBE_HIT_ACTIVE;
+
+			/*
+			 * If we have no pre-handler or it returned 0, we
+			 * continue with normal processing.  If we have a
+			 * pre-handler and it returned non-zero, it prepped
+			 * for calling the break_handler below on re-entry,
+			 * so get out doing nothing more here.
+			 *
+			 * pre_handler can hit a breakpoint and can step thru
+			 * before return, keep PSTATE D-flag enabled until
+			 * pre_handler return back.
+			 */
+			if (!p->pre_handler || !p->pre_handler(p, regs)) {
+				kcb->kprobe_status = KPROBE_HIT_SS;
+				setup_singlestep(p, regs, kcb, 0);
+				return;
+			}
+		} else {
+			/*
+			 * Breakpoint hit but conditional check failed,
+			 * so just skip the instruction (NOP behaviour)
+			 */
+			skip_singlestep_missed(kcb, regs);
+			return;
+		}
+	} else if (*(kprobe_opcode_t *) addr != BRK64_OPCODE_KPROBES) {
+		/*
+		 * The breakpoint instruction was removed right
+		 * after we hit it.  Another cpu has removed
+		 * either a probepoint or a debugger breakpoint
+		 * at this address.  In either case, no further
+		 * handling of this interrupt is appropriate.
+		 * Return back to original instruction, and continue.
+		 */
+		return;
+	} else if (cur) {
+		/* We probably hit a jprobe.  Call its break handler. */
+		if (cur->break_handler && cur->break_handler(cur, regs)) {
+			kcb->kprobe_status = KPROBE_HIT_SS;
+			setup_singlestep(cur, regs, kcb, 0);
+			return;
+		}
+	} else {
+		/* breakpoint is removed, now in a race
+		 * Return back to original instruction & continue.
+		 */
+	}
+}
+
+static int __kprobes
+kprobe_ss_hit(struct kprobe_ctlblk *kcb, unsigned long addr)
+{
+	if ((kcb->ss_ctx.ss_status == KPROBES_STEP_PENDING)
+	    && (kcb->ss_ctx.match_addr == addr)) {
+		clear_ss_context(kcb);	/* clear pending ss */
+		return DBG_HOOK_HANDLED;
+	}
+	/* not ours, kprobes should ignore it */
+	return DBG_HOOK_ERROR;
+}
+
+int __kprobes
+kprobe_single_step_handler(struct pt_regs *regs, unsigned int esr)
+{
+	struct kprobe_ctlblk *kcb = get_kprobe_ctlblk();
+	int retval;
+
+	/* return error if this is not our step */
+	retval = kprobe_ss_hit(kcb, instruction_pointer(regs));
+
+	if (retval == DBG_HOOK_HANDLED) {
+		kprobes_restore_local_irqflag(regs);
+		kernel_disable_single_step();
+
+		if (kcb->kprobe_status == KPROBE_REENTER)
+			spsr_set_debug_flag(regs, 1);
+
+		post_kprobe_handler(kcb, regs);
+	}
+
+	return retval;
+}
+
+int __kprobes
+kprobe_breakpoint_handler(struct pt_regs *regs, unsigned int esr)
+{
+	kprobe_handler(regs);
+	return DBG_HOOK_HANDLED;
+}
+
+int __kprobes setjmp_pre_handler(struct kprobe *p, struct pt_regs *regs)
+{
+	struct jprobe *jp = container_of(p, struct jprobe, kp);
+	struct kprobe_ctlblk *kcb = get_kprobe_ctlblk();
+	long stack_ptr = stack_pointer(regs);
+
+	kcb->jprobe_saved_regs = *regs;
+	memcpy(kcb->jprobes_stack, (void *)stack_ptr,
+	       MIN_STACK_SIZE(stack_ptr));
+
+	instruction_pointer(regs) = (long)jp->entry;
+	preempt_disable();
+	return 1;
+}
+
+void __kprobes jprobe_return(void)
+{
+	struct kprobe_ctlblk *kcb = get_kprobe_ctlblk();
+
+	/*
+	 * Jprobe handler return by entering break exception,
+	 * encoded same as kprobe, but with following conditions
+	 * -a magic number in x0 to identify from rest of other kprobes.
+	 * -restore stack addr to original saved pt_regs
+	 */
+	asm volatile ("ldr x0, [%0]\n\t"
+		      "mov sp, x0\n\t"
+		      "ldr x0, =" __stringify(JPROBES_MAGIC_NUM) "\n\t"
+		      "BRK %1\n\t"
+		      "NOP\n\t"
+		      :
+		      : "r"(&kcb->jprobe_saved_regs.sp),
+		      "I"(BRK64_ESR_KPROBES)
+		      : "memory");
+}
+
+int __kprobes longjmp_break_handler(struct kprobe *p, struct pt_regs *regs)
+{
+	struct kprobe_ctlblk *kcb = get_kprobe_ctlblk();
+	long stack_addr = kcb->jprobe_saved_regs.sp;
+	long orig_sp = stack_pointer(regs);
+	struct jprobe *jp = container_of(p, struct jprobe, kp);
+
+	if (regs->regs[0] == JPROBES_MAGIC_NUM) {
+		if (orig_sp != stack_addr) {
+			struct pt_regs *saved_regs =
+			    (struct pt_regs *)kcb->jprobe_saved_regs.sp;
+			pr_err("current sp %lx does not match saved sp %lx\n",
+			       orig_sp, stack_addr);
+			pr_err("Saved registers for jprobe %p\n", jp);
+			show_regs(saved_regs);
+			pr_err("Current registers\n");
+			show_regs(regs);
+			BUG();
+		}
+		*regs = kcb->jprobe_saved_regs;
+		memcpy((void *)stack_addr, kcb->jprobes_stack,
+		       MIN_STACK_SIZE(stack_addr));
+		preempt_enable_no_resched();
+		return 1;
+	}
+	return 0;
+}
+
+int __init arch_init_kprobes(void)
+{
+	return 0;
+}
diff --git a/arch/arm64/kernel/kprobes.h b/arch/arm64/kernel/kprobes.h
new file mode 100644
index 0000000..e98ad60
--- /dev/null
+++ b/arch/arm64/kernel/kprobes.h
@@ -0,0 +1,24 @@
+/*
+ * arch/arm64/kernel/kprobes.h
+ *
+ * Copyright (C) 2013 Linaro Limited.
+ *
+ * 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.
+ */
+
+#ifndef _ARM_KERNEL_KPROBES_H
+#define _ARM_KERNEL_KPROBES_H
+
+#define JPROBES_MAGIC_NUM	0xa5a5a5a5a5a5a5a5
+
+/* Move this out to appropriate header file */
+int fixup_exception(struct pt_regs *regs);
+
+#endif /* _ARM_KERNEL_KPROBES_H */
diff --git a/arch/arm64/kernel/vmlinux.lds.S b/arch/arm64/kernel/vmlinux.lds.S
index 9807333..1fa6adc 100644
--- a/arch/arm64/kernel/vmlinux.lds.S
+++ b/arch/arm64/kernel/vmlinux.lds.S
@@ -100,6 +100,7 @@ SECTIONS
 			TEXT_TEXT
 			SCHED_TEXT
 			LOCK_TEXT
+			KPROBES_TEXT
 			HYPERVISOR_TEXT
 			IDMAP_TEXT
 			*(.fixup)
diff --git a/arch/arm64/mm/fault.c b/arch/arm64/mm/fault.c
index 94d98cd..01bf525 100644
--- a/arch/arm64/mm/fault.c
+++ b/arch/arm64/mm/fault.c
@@ -39,6 +39,28 @@
 
 static const char *fault_name(unsigned int esr);
 
+#ifdef CONFIG_KPROBES
+static inline int notify_page_fault(struct pt_regs *regs, unsigned int esr)
+{
+	int ret = 0;
+
+	/* kprobe_running() needs smp_processor_id() */
+	if (!user_mode(regs)) {
+		preempt_disable();
+		if (kprobe_running() && kprobe_fault_handler(regs, esr))
+			ret = 1;
+		preempt_enable();
+	}
+
+	return ret;
+}
+#else
+static inline int notify_page_fault(struct pt_regs *regs, unsigned int esr)
+{
+	return 0;
+}
+#endif
+
 /*
  * Dump out the page tables associated with 'addr' in mm 'mm'.
  */
@@ -199,6 +221,9 @@ static int __kprobes do_page_fault(unsigned long addr, unsigned int esr,
 	unsigned long vm_flags = VM_READ | VM_WRITE | VM_EXEC;
 	unsigned int mm_flags = FAULT_FLAG_ALLOW_RETRY | FAULT_FLAG_KILLABLE;
 
+	if (notify_page_fault(regs, esr))
+		return 0;
+
 	tsk = current;
 	mm  = tsk->mm;
 
-- 
1.8.1.2



From dave.long at linaro.org  Mon Aug 10 17:52:44 2015
From: dave.long at linaro.org (David Long)
Date: Mon, 10 Aug 2015 20:52:44 -0400
Subject: [PATCH v8 7/7] kprobes: Add arm64 case in kprobe example module
In-Reply-To: <1439254364-15362-1-git-send-email-dave.long@linaro.org>
References: <1439254364-15362-1-git-send-email-dave.long@linaro.org>
Message-ID: <1439254364-15362-8-git-send-email-dave.long@linaro.org>

From: Sandeepa Prabhu <sandeepa.s.prabhu at gmail.com>

Add info prints in sample kprobe handlers for ARM64

Signed-off-by: Sandeepa Prabhu <sandeepa.s.prabhu at gmail.com>
---
 samples/kprobes/kprobe_example.c | 8 ++++++++
 1 file changed, 8 insertions(+)

diff --git a/samples/kprobes/kprobe_example.c b/samples/kprobes/kprobe_example.c
index 366db1a..51d459c 100644
--- a/samples/kprobes/kprobe_example.c
+++ b/samples/kprobes/kprobe_example.c
@@ -42,6 +42,10 @@ static int handler_pre(struct kprobe *p, struct pt_regs *regs)
 			" ex1 = 0x%lx\n",
 		p->addr, regs->pc, regs->ex1);
 #endif
+#ifdef CONFIG_ARM64
+	pr_info("pre_handler: p->addr = 0x%p, pc = 0x%lx\n",
+		p->addr, (long)regs->pc);
+#endif
 
 	/* A dump_stack() here will give a stack backtrace */
 	return 0;
@@ -67,6 +71,10 @@ static void handler_post(struct kprobe *p, struct pt_regs *regs,
 	printk(KERN_INFO "post_handler: p->addr = 0x%p, ex1 = 0x%lx\n",
 		p->addr, regs->ex1);
 #endif
+#ifdef CONFIG_ARM64
+	pr_info("post_handler: p->addr = 0x%p, pc = 0x%lx\n",
+		p->addr, (long)regs->pc);
+#endif
 }
 
 /*
-- 
1.8.1.2



From ddaney.cavm at gmail.com  Mon Aug 10 17:58:35 2015
From: ddaney.cavm at gmail.com (David Daney)
Date: Mon, 10 Aug 2015 17:58:35 -0700
Subject: [PATCH v2 0/2] net: thunder: Add ACPI support.
Message-ID: <1439254717-2875-1-git-send-email-ddaney.cavm@gmail.com>

From: David Daney <david.daney at cavium.com>

Change from v1:  Drop PHY binding part, use fwnode_property* APIs.

The first patch (1/2) rearranges the existing code a little with no
functional change to get ready for the second.  The second (2/2) does
the actual work of adding support to extract the needed information
from the ACPI tables.

David Daney (1):
  net, thunder, bgx: Add support to get MAC address from ACPI.

Robert Richter (1):
  net: thunder: Factor out DT specific code in BGX

 drivers/net/ethernet/cavium/thunder/thunder_bgx.c | 134 +++++++++++++++++++---
 1 file changed, 120 insertions(+), 14 deletions(-)

-- 
1.9.1



From ddaney.cavm at gmail.com  Mon Aug 10 17:58:36 2015
From: ddaney.cavm at gmail.com (David Daney)
Date: Mon, 10 Aug 2015 17:58:36 -0700
Subject: [PATCH v2 1/2] net: thunder: Factor out DT specific code in BGX
In-Reply-To: <1439254717-2875-1-git-send-email-ddaney.cavm@gmail.com>
References: <1439254717-2875-1-git-send-email-ddaney.cavm@gmail.com>
Message-ID: <1439254717-2875-2-git-send-email-ddaney.cavm@gmail.com>

From: Robert Richter <rrichter at redhat.com>

Separate DT code in preparation for follow-on ACPI integration.

Based on code from: Tomasz Nowicki <tomasz.nowicki at linaro.org>

Signed-off-by: Robert Richter <rrichter at cavium.com>
Signed-off-by: David Daney <david.daney at cavium.com>
---
 drivers/net/ethernet/cavium/thunder/thunder_bgx.c | 48 +++++++++++++++++------
 1 file changed, 35 insertions(+), 13 deletions(-)

diff --git a/drivers/net/ethernet/cavium/thunder/thunder_bgx.c b/drivers/net/ethernet/cavium/thunder/thunder_bgx.c
index b961a89..615b2af 100644
--- a/drivers/net/ethernet/cavium/thunder/thunder_bgx.c
+++ b/drivers/net/ethernet/cavium/thunder/thunder_bgx.c
@@ -835,18 +835,28 @@ static void bgx_get_qlm_mode(struct bgx *bgx)
 	}
 }
 
-static void bgx_init_of(struct bgx *bgx, struct device_node *np)
+#if IS_ENABLED(CONFIG_OF_MDIO)
+
+static int bgx_init_of_phy(struct bgx *bgx)
 {
+	struct device_node *np;
 	struct device_node *np_child;
 	u8 lmac = 0;
+	char bgx_sel[5];
+	const char *mac;
 
-	for_each_child_of_node(np, np_child) {
-		struct device_node *phy_np;
-		const char *mac;
+	/* Get BGX node from DT */
+	snprintf(bgx_sel, 5, "bgx%d", bgx->bgx_id);
+	np = of_find_node_by_name(NULL, bgx_sel);
+	if (!np)
+		return -ENODEV;
 
-		phy_np = of_parse_phandle(np_child, "phy-handle", 0);
-		if (phy_np)
-			bgx->lmac[lmac].phydev = of_phy_find_device(phy_np);
+	for_each_child_of_node(np, np_child) {
+		struct device_node *phy_np = of_parse_phandle(np_child,
+							      "phy-handle", 0);
+		if (!phy_np)
+			continue;
+		bgx->lmac[lmac].phydev = of_phy_find_device(phy_np);
 
 		mac = of_get_mac_address(np_child);
 		if (mac)
@@ -858,6 +868,21 @@ static void bgx_init_of(struct bgx *bgx, struct device_node *np)
 		if (lmac == MAX_LMAC_PER_BGX)
 			break;
 	}
+	return 0;
+}
+
+#else
+
+static int bgx_init_of_phy(struct bgx *bgx)
+{
+	return -ENODEV;
+}
+
+#endif /* CONFIG_OF_MDIO */
+
+static int bgx_init_phy(struct bgx *bgx)
+{
+	return bgx_init_of_phy(bgx);
 }
 
 static int bgx_probe(struct pci_dev *pdev, const struct pci_device_id *ent)
@@ -865,8 +890,6 @@ static int bgx_probe(struct pci_dev *pdev, const struct pci_device_id *ent)
 	int err;
 	struct device *dev = &pdev->dev;
 	struct bgx *bgx = NULL;
-	struct device_node *np;
-	char bgx_sel[5];
 	u8 lmac;
 
 	bgx = devm_kzalloc(dev, sizeof(*bgx), GFP_KERNEL);
@@ -902,10 +925,9 @@ static int bgx_probe(struct pci_dev *pdev, const struct pci_device_id *ent)
 	bgx_vnic[bgx->bgx_id] = bgx;
 	bgx_get_qlm_mode(bgx);
 
-	snprintf(bgx_sel, 5, "bgx%d", bgx->bgx_id);
-	np = of_find_node_by_name(NULL, bgx_sel);
-	if (np)
-		bgx_init_of(bgx, np);
+	err = bgx_init_phy(bgx);
+	if (err)
+		goto err_enable;
 
 	bgx_init_hw(bgx);
 
-- 
1.9.1



From ddaney.cavm at gmail.com  Mon Aug 10 17:58:37 2015
From: ddaney.cavm at gmail.com (David Daney)
Date: Mon, 10 Aug 2015 17:58:37 -0700
Subject: [PATCH v2 2/2] net, thunder,
 bgx: Add support to get MAC address from ACPI.
In-Reply-To: <1439254717-2875-1-git-send-email-ddaney.cavm@gmail.com>
References: <1439254717-2875-1-git-send-email-ddaney.cavm@gmail.com>
Message-ID: <1439254717-2875-3-git-send-email-ddaney.cavm@gmail.com>

From: David Daney <david.daney at cavium.com>

Currently there is no way to get the MAC address in a firmware
independent manner, so set the MAC address of the device directly from
the ACPI tables.

The binding agrees with the proposed standard here:

http://www.uefi.org/sites/default/files/resources/nic-request-v2.pdf

Based on code from: Narinder Dhillon <ndhillon at cavium.com>
                    Tomasz Nowicki <tomasz.nowicki at linaro.org>
                    Robert Richter <rrichter at cavium.com>

Signed-off-by: Tomasz Nowicki <tomasz.nowicki at linaro.org>
Signed-off-by: Robert Richter <rrichter at cavium.com>
Signed-off-by: David Daney <david.daney at cavium.com>
---
 drivers/net/ethernet/cavium/thunder/thunder_bgx.c | 86 ++++++++++++++++++++++-
 1 file changed, 85 insertions(+), 1 deletion(-)

diff --git a/drivers/net/ethernet/cavium/thunder/thunder_bgx.c b/drivers/net/ethernet/cavium/thunder/thunder_bgx.c
index 615b2af..5e54186 100644
--- a/drivers/net/ethernet/cavium/thunder/thunder_bgx.c
+++ b/drivers/net/ethernet/cavium/thunder/thunder_bgx.c
@@ -6,6 +6,7 @@
  * as published by the Free Software Foundation.
  */
 
+#include <linux/acpi.h>
 #include <linux/module.h>
 #include <linux/interrupt.h>
 #include <linux/pci.h>
@@ -26,7 +27,7 @@
 struct lmac {
 	struct bgx		*bgx;
 	int			dmac;
-	unsigned char		mac[ETH_ALEN];
+	u8			mac[ETH_ALEN];
 	bool			link_up;
 	int			lmacid; /* ID within BGX */
 	int			lmacid_bd; /* ID on board */
@@ -835,6 +836,86 @@ static void bgx_get_qlm_mode(struct bgx *bgx)
 	}
 }
 
+#ifdef CONFIG_ACPI
+
+static int acpi_get_mac_address(struct acpi_device *adev, u8 *dst)
+{
+	u8 mac[ETH_ALEN];
+	int ret;
+
+	ret = fwnode_property_read_u8_array(acpi_fwnode_handle(adev),
+					    "mac-address", mac, ETH_ALEN);
+	if (ret)
+		goto out;
+
+	if (!is_valid_ether_addr(mac)) {
+		ret = -EINVAL;
+		goto out;
+	}
+
+	memcpy(dst, mac, ETH_ALEN);
+out:
+	return ret;
+}
+
+/* Currently only sets the MAC address. */
+static acpi_status bgx_acpi_register_phy(acpi_handle handle,
+					 u32 lvl, void *context, void **rv)
+{
+	struct bgx *bgx = context;
+	struct acpi_device *adev;
+
+	if (acpi_bus_get_device(handle, &adev))
+		goto out;
+
+	acpi_get_mac_address(adev, bgx->lmac[bgx->lmac_count].mac);
+
+	SET_NETDEV_DEV(&bgx->lmac[bgx->lmac_count].netdev, &bgx->pdev->dev);
+
+	bgx->lmac[bgx->lmac_count].lmacid = bgx->lmac_count;
+out:
+	bgx->lmac_count++;
+	return AE_OK;
+}
+
+static acpi_status bgx_acpi_match_id(acpi_handle handle, u32 lvl,
+				     void *context, void **ret_val)
+{
+	struct acpi_buffer string = { ACPI_ALLOCATE_BUFFER, NULL };
+	struct bgx *bgx = context;
+	char bgx_sel[5];
+
+	snprintf(bgx_sel, 5, "BGX%d", bgx->bgx_id);
+	if (ACPI_FAILURE(acpi_get_name(handle, ACPI_SINGLE_NAME, &string))) {
+		pr_warn("Invalid link device\n");
+		return AE_OK;
+	}
+
+	if (strncmp(string.pointer, bgx_sel, 4))
+		return AE_OK;
+
+	acpi_walk_namespace(ACPI_TYPE_DEVICE, handle, 1,
+			    bgx_acpi_register_phy, NULL, bgx, NULL);
+
+	kfree(string.pointer);
+	return AE_CTRL_TERMINATE;
+}
+
+static int bgx_init_acpi_phy(struct bgx *bgx)
+{
+	acpi_get_devices(NULL, bgx_acpi_match_id, bgx, (void **)NULL);
+	return 0;
+}
+
+#else
+
+static int bgx_init_acpi_phy(struct bgx *bgx)
+{
+	return -ENODEV;
+}
+
+#endif /* CONFIG_ACPI */
+
 #if IS_ENABLED(CONFIG_OF_MDIO)
 
 static int bgx_init_of_phy(struct bgx *bgx)
@@ -882,6 +963,9 @@ static int bgx_init_of_phy(struct bgx *bgx)
 
 static int bgx_init_phy(struct bgx *bgx)
 {
+	if (!acpi_disabled)
+		return bgx_init_acpi_phy(bgx);
+
 	return bgx_init_of_phy(bgx);
 }
 
-- 
1.9.1



From jun.nie at linaro.org  Mon Aug 10 18:48:24 2015
From: jun.nie at linaro.org (Jun Nie)
Date: Tue, 11 Aug 2015 09:48:24 +0800
Subject: earlycon issues in -next with amba-pl011 updates
In-Reply-To: <20150810232312.GB10728@bivouac.eciton.net>
References: <20150810232312.GB10728@bivouac.eciton.net>
Message-ID: <CABymUCNYrDxciKrfWhcTp_kJT1cQFEpEYCkaZ7-sgBiJmgXuyQ@mail.gmail.com>

2015-08-11 7:23 GMT+08:00 Leif Lindholm <leif.lindholm at linaro.org>:
> Hi all,
>
> The kernelci.org bot picked up a complete boot failure (no output past
> UEFI stub) with next-20150806 and Tyler bisected it down to somewhere
> in
> 8cd90e5 uart: pl011: Add support to ZTE ZX296702 uart
> 09dcc7d uart: pl011: Improve LCRH register access decision
> 2c096a9 uart: pl011: Introduce register look up table
> 7b753f3 uart: pl011: Introduce register accessor
>
> The issue only appears with earlycon on command line, for pl011
> consoles.
>
> Some investigation shows that the cause lies with
> commit 7b753f318d14 ("uart: pl011: Introduce register accessor")
> and
> commit 2c096a9eedc6 ("uart: pl011: Introduce register look up table")
>
> Specifically, the changes to pl011_putc() are incorrect:
> The new pl011_ accessors take a (struct uart_amba_port *) input, but
> pl011_putc() directly uses the incoming (struct uart_port *) for this.
>
> Apart from ending up with an unintended/incorrect UART base address,
> the introduction of the lookup table for register offsets also means
> the accessors try to dereference (struct uart_amba_port *)->reg_lut.
>
> The below is a hack that shows/resolves the issue, but some
> refactoring of the original patches might be in order.
>
> /
>     Leif

Leif,

Sorry for the inconvenience. I do not have idea of early console till
now and I always have debug console for early panic debug. Learned
more from this issue.

Suppose Peter's patch will resolve your issue.

Jun

>
> diff --git a/drivers/tty/serial/amba-pl011.c b/drivers/tty/serial/amba-pl011.c
> index 2af09ab..452dbba 100644
> --- a/drivers/tty/serial/amba-pl011.c
> +++ b/drivers/tty/serial/amba-pl011.c
> @@ -2348,13 +2348,14 @@ static struct console amba_console = {
>
>  static void pl011_putc(struct uart_port *port, int c)
>  {
> -       struct uart_amba_port *uap =
> -           container_of(port, struct uart_amba_port, port);
> +       struct uart_amba_port uap;
> +       uap.port = *port;
> +       uap.reg_lut = arm_reg;
>
> -       while (pl011_readw(uap, REG_FR) & UART01x_FR_TXFF)
> +       while (pl011_readw(&uap, REG_FR) & UART01x_FR_TXFF)
>                 ;
> -       pl011_writeb(uap, c, REG_DR);
> -       while (pl011_readw(uap, REG_FR) & uap->fr_busy)
> +       pl011_writeb(&uap, c, REG_DR);
> +       while (pl011_readw(&uap, REG_FR) & UART01x_FR_BUSY)
>                 ;
>  }
>
> --
> 2.1.4
>
>
>


From hongzhou.yang at mediatek.com  Mon Aug 10 18:51:50 2015
From: hongzhou.yang at mediatek.com (Hongzhou Yang)
Date: Mon, 10 Aug 2015 18:51:50 -0700
Subject: [PATCH] pinctrl: mediatek: Implement pictrl irq wake handler
In-Reply-To: <CACRpkdZ1RjjSh5J=K724CpbXDXwdHJSdXOTLS8fSOO-34zn=9A@mail.gmail.com>
References: <1438162601-448-1-git-send-email-maoguang.meng@mediatek.com>
 <CACRpkdZ1RjjSh5J=K724CpbXDXwdHJSdXOTLS8fSOO-34zn=9A@mail.gmail.com>
Message-ID: <1439257910.38706.1.camel@mussux00.eus.mediatek.inc>

On Mon, 2015-08-10 at 14:43 +0200, Linus Walleij wrote:
> On Wed, Jul 29, 2015 at 11:36 AM,  <maoguang.meng at mediatek.com> wrote:
> 
> > From: Maoguang Meng <maoguang.meng at mediatek.com>
> >
> > This patch implement irq_set_wake for suspend resume.
> >
> > Signed-off-by: Maoguang Meng <maoguang.meng at mediatek.com>
> 
> Hongzhou/Yingjoe: are you OK with this patch? Can I have your ACKs?
> 
> Yours,
> Linus Walleij

Hi Linus,

Yes, you can. Thank you.

Acked-by: Hongzhou Yang <hongzhou.yang at mediatek.com>

Hongzhou



From k.kozlowski at samsung.com  Mon Aug 10 19:15:54 2015
From: k.kozlowski at samsung.com (Krzysztof Kozlowski)
Date: Tue, 11 Aug 2015 11:15:54 +0900
Subject: [PATCH] ARM: exynos_defconfig: Enable cpufreq-dt driver
Message-ID: <1439259354-32055-1-git-send-email-k.kozlowski@samsung.com>

With the latest patches the cpufreq-dt can be used on multiple
Exynos SoCs: 3250, 4210, 4212, 4412 and 5250.

Enable it along with default ondemand governor to conserve the energy,
reduce temperature while maintaining acceptable performance.

Signed-off-by: Krzysztof Kozlowski <k.kozlowski at samsung.com>
---
 arch/arm/configs/exynos_defconfig | 2 ++
 1 file changed, 2 insertions(+)

diff --git a/arch/arm/configs/exynos_defconfig b/arch/arm/configs/exynos_defconfig
index 67965cedeb69..2263cd94cb93 100644
--- a/arch/arm/configs/exynos_defconfig
+++ b/arch/arm/configs/exynos_defconfig
@@ -27,6 +27,8 @@ CONFIG_ARM_APPENDED_DTB=y
 CONFIG_ARM_ATAG_DTB_COMPAT=y
 CONFIG_CMDLINE="root=/dev/ram0 rw ramdisk=8192 initrd=0x41000000,8M console=ttySAC1,115200 init=/linuxrc mem=256M"
 CONFIG_CPU_FREQ=y
+CONFIG_CPU_FREQ_DEFAULT_GOV_ONDEMAND=y
+CONFIG_CPUFREQ_DT=y
 CONFIG_CPU_IDLE=y
 CONFIG_ARM_EXYNOS_CPUIDLE=y
 CONFIG_VFP=y
-- 
1.9.1



From k.kozlowski at samsung.com  Mon Aug 10 19:20:06 2015
From: k.kozlowski at samsung.com (Krzysztof Kozlowski)
Date: Tue, 11 Aug 2015 11:20:06 +0900
Subject: [PATCH v4 0/6] cpufreq: use generic cpufreq drivers for Exynos4x12
 platform
In-Reply-To: <03ee01d0d30b$b279c490$176d4db0$@kernel.org>
References: <1438868514-8814-1-git-send-email-b.zolnierkie@samsung.com>
 <2359635.Hxe4cb8zKm@amdc1976> <20150807115627.GH6939@linux>
 <1525406.7aXvVQzEDd@vostro.rjw.lan> <20150808020740.GM6939@linux>
 <55C5AF4E.3010500@samsung.com> <03ee01d0d30b$b279c490$176d4db0$@kernel.org>
Message-ID: <55C95BD6.7010200@samsung.com>

On 10.08.2015 10:27, Kukjin Kim wrote:
> Krzysztof Kozlowski wrote:
>>
>> W dniu 08.08.2015 o 11:07, Viresh Kumar pisze:
>>> On 08-08-15, 00:24, Rafael J. Wysocki wrote:
>>>> OK, so please let me know which patches you want me to pick up.
>>>>
>>>> Ideally, I'd prefer them to be resent in a separate series with ACKs and all
>>>> with a cover letter clearly stating whose tree they are being targeted at.
>>>
>>> He already sent it separately, let me send a confirmatory mail in
>>> reply to that.
>>
>> Dear Kukjin,
>>
>> Can you apply the 2-5 of this series to v4.3? It's getting late but
>> maybe they still could go?
>>
> Once my previous pull-request landed into arm-soc, I'll try to send out this
> series 2-5 for v4.3.

Additionally (better late than never):
Patches 2-5 tested on Trats2 board (Exynos4412)

Tested-by: Krzysztof Kozlowski <k.kozlowski at samsung.com>

Best regards,
Krzysztof



From jszhang at marvell.com  Mon Aug 10 19:39:02 2015
From: jszhang at marvell.com (Jisheng Zhang)
Date: Tue, 11 Aug 2015 10:39:02 +0800
Subject: [PATCH] arm64: dts: Add base stratix 10 dtsi
In-Reply-To: <1439240958-4713-1-git-send-email-dinguyen@opensource.altera.com>
References: <1439240958-4713-1-git-send-email-dinguyen@opensource.altera.com>
Message-ID: <20150811103902.38cbcb6d@xhacker>

On Mon, 10 Aug 2015 16:09:18 -0500
<dinguyen at opensource.altera.com> wrote:

> From: Dinh Nguyen <dinguyen at opensource.altera.com>
> 
> Add the base DTS for Altera's SoCFPGA Stratix 10 platform.
> 
> Signed-off-by: Dinh Nguyen <dinguyen at opensource.altera.com>
> ---
>  arch/arm64/Kconfig                                 |   5 +
>  arch/arm64/boot/dts/Makefile                       |   1 +
>  arch/arm64/boot/dts/altera/Makefile                |   5 +
>  arch/arm64/boot/dts/altera/socfpga_stratix10.dtsi  | 354 +++++++++++++++++++++
>  .../boot/dts/altera/socfpga_stratix10_socdk.dts    |  38 +++
>  arch/arm64/configs/defconfig                       |   1 +
>  6 files changed, 404 insertions(+)
>  create mode 100644 arch/arm64/boot/dts/altera/Makefile
>  create mode 100644 arch/arm64/boot/dts/altera/socfpga_stratix10.dtsi
>  create mode 100644 arch/arm64/boot/dts/altera/socfpga_stratix10_socdk.dts
> 
> diff --git a/arch/arm64/Kconfig b/arch/arm64/Kconfig
> index 318175f..0f8ab2b 100644
> --- a/arch/arm64/Kconfig
> +++ b/arch/arm64/Kconfig
> @@ -207,6 +207,11 @@ config ARCH_SEATTLE
>  	help
>  	  This enables support for AMD Seattle SOC Family
>  
> +config ARCH_STRATIX10
> +	bool "Altera's Stratix 10 SoCFPGA Family"
> +	help
> +	  This enables support for Altera's Stratix 10 SoCFPGA Family
> +
>  config ARCH_TEGRA
>  	bool "NVIDIA Tegra SoC Family"
>  	select ARCH_HAS_RESET_CONTROLLER
> diff --git a/arch/arm64/boot/dts/Makefile b/arch/arm64/boot/dts/Makefile
> index 38913be..7fb421a 100644
> --- a/arch/arm64/boot/dts/Makefile
> +++ b/arch/arm64/boot/dts/Makefile
> @@ -1,3 +1,4 @@
> +dts-dirs += altera
>  dts-dirs += amd
>  dts-dirs += apm
>  dts-dirs += arm
> diff --git a/arch/arm64/boot/dts/altera/Makefile b/arch/arm64/boot/dts/altera/Makefile
> new file mode 100644
> index 0000000..d7a6416
> --- /dev/null
> +++ b/arch/arm64/boot/dts/altera/Makefile
> @@ -0,0 +1,5 @@
> +dtb-$(CONFIG_ARCH_STRATIX10) += socfpga_stratix10_socdk.dtb
> +
> +always		:= $(dtb-y)
> +subdir-y	:= $(dts-dirs)
> +clean-files	:= *.dtb
> diff --git a/arch/arm64/boot/dts/altera/socfpga_stratix10.dtsi b/arch/arm64/boot/dts/altera/socfpga_stratix10.dtsi
> new file mode 100644
> index 0000000..34f6dc3
> --- /dev/null
> +++ b/arch/arm64/boot/dts/altera/socfpga_stratix10.dtsi
> @@ -0,0 +1,354 @@
> +/*
> + * Copyright Altera Corporation (C) 2015. All rights reserved.
> + *
> + * This program is free software; you can redistribute it and/or modify
> + * it under the terms and conditions of the GNU General Public License,
> + * version 2, as published by the Free Software Foundation.
> + *
> + * This program is distributed in the hope 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.
> + *
> + * You should have received a copy of the GNU General Public License along with
> + * this program.  If not, see <http://www.gnu.org/licenses/>.
> + */
> +
> +/dts-v1/;
> +
> +/ {
> +	compatible = "altr,socfpga-stratix10";
> +	#address-cells = <1>;
> +	#size-cells = <1>;
> +
[...]
> +
> +	pmu {
> +		compatible = "arm,armv8-pmuv3";
> +		interrupts = <0 120 8>,
> +			     <0 121 8>,
> +			     <0 122 8>,
> +			     <0 123 8>;

it's better to add interrupt-affinity according to Sudeep's suggestions.

> +	};
> +
> +	psci {
> +		compatible = "arm,psci-0.2";
> +		method = "smc";
> +	};
> +
> +	intc: intc at ffff8000 {
> +		compatible = "arm,gic-400", "arm,cortex-a15-gic";
> +		#interrupt-cells = <3>;
> +		interrupt-controller;
> +		reg = <0x0 0xffff9000 0x1000>,
> +		      <0x0 0xffffa000 0x2000>,
> +		      <0x0 0xffffc000 0x1000>,
> +		      <0x0 0xffffd000 0x1000>;
> +	};
> +
> +	soc {
> +		#address-cells = <1>;
> +		#size-cells = <1>;
> +		compatible = "simple-bus";
> +		device_type = "soc";
> +		interrupt-parent = <&intc>;
> +		ranges;
> +
> +		clkmgr at ffd1000 {
> +			compatible = "altr,clk-mgr";
> +			reg = <0xffd10000 0x1000>;
> +		};
> +
> +		gmac0: ethernet at ff800000 {
> +			compatible = "altr,socfpga-stmmac", "snps,dwmac-3.74a", "snps,dwmac";
> +			reg = <0xff800000 0x2000>;
> +			interrupts = <0 90 4>;
> +			interrupt-names = "macirq";
> +			mac-address = [00 00 00 00 00 00];
> +			status = "disabled";
> +		};
> +
> +		gmac1: ethernet at ff802000 {
> +			compatible = "altr,socfpga-stmmac", "snps,dwmac-3.74a", "snps,dwmac";
> +			reg = <0xff802000 0x2000>;
> +			interrupts = <0 91 4>;
> +			interrupt-names = "macirq";
> +			mac-address = [00 00 00 00 00 00];
> +			status = "disabled";
> +		};
> +
> +		gmac2: ethernet at ff804000 {
> +			compatible = "altr,socfpga-stmmac", "snps,dwmac-3.74a", "snps,dwmac";
> +			reg = <0xff804000 0x2000>;
> +			interrupts = <0 92 4>;
> +			interrupt-names = "macirq";
> +			mac-address = [00 00 00 00 00 00];
> +			status = "disabled";
> +		};
> +
> +		gpio0: gpio at ffc03200 {
> +			#address-cells = <1>;
> +			#size-cells = <0>;
> +			compatible = "snps,dw-apb-gpio";
> +			reg = <0xffc03200 0x100>;
> +			status = "disabled";
> +
> +			porta: gpio-controller at 0 {
> +				compatible = "snps,dw-apb-gpio-port";
> +				gpio-controller;
> +				#gpio-cells = <2>;
> +				snps,nr-gpios = <24>;
> +				reg = <0>;
> +				interrupt-controller;
> +				#interrupt-cells = <2>;
> +				interrupts = <0 110 4>;
> +			};
> +		};
> +
> +		gpio1: gpio at ffc03300 {
> +			#address-cells = <1>;
> +			#size-cells = <0>;
> +			compatible = "snps,dw-apb-gpio";
> +			reg = <0xffc03300 0x100>;
> +			status = "disabled";
> +
> +			portb: gpio-controller at 0 {
> +				compatible = "snps,dw-apb-gpio-port";
> +				gpio-controller;
> +				#gpio-cells = <2>;
> +				snps,nr-gpios = <24>;
> +				reg = <0>;
> +				interrupt-controller;
> +				#interrupt-cells = <2>;
> +				interrupts = <0 110 4>;
> +			};
> +		};
> +
> +		i2c0: i2c at ffc02800 {
> +			#address-cells = <1>;
> +			#size-cells = <0>;
> +			compatible = "snps,designware-i2c";
> +			reg = <0xffc02800 0x100>;
> +			interrupts = <0 103 4>;
> +			status = "disabled";
> +		};
> +
> +		i2c1: i2c at ffc02900 {
> +			#address-cells = <1>;
> +			#size-cells = <0>;
> +			compatible = "snps,designware-i2c";
> +			reg = <0xffc02900 0x100>;
> +			interrupts = <0 104 4>;
> +			status = "disabled";
> +		};
> +
> +		i2c2: i2c at ffc02a00 {
> +			#address-cells = <1>;
> +			#size-cells = <0>;
> +			compatible = "snps,designware-i2c";
> +			reg = <0xffc02a00 0x100>;
> +			interrupts = <0 105 4>;
> +			status = "disabled";
> +		};
> +
> +		i2c3: i2c at ffc02b00 {
> +			#address-cells = <1>;
> +			#size-cells = <0>;
> +			compatible = "snps,designware-i2c";
> +			reg = <0xffc02b00 0x100>;
> +			interrupts = <0 106 4>;
> +			status = "disabled";
> +		};
> +
> +		i2c4: i2c at ffc02c00 {
> +			#address-cells = <1>;
> +			#size-cells = <0>;
> +			compatible = "snps,designware-i2c";
> +			reg = <0xffc02c00 0x100>;
> +			interrupts = <0 107 4>;
> +			status = "disabled";
> +		};
> +
> +		mmc: dwmmc0 at ff808000 {
> +			#address-cells = <1>;
> +			#size-cells = <0>;
> +			compatible = "altr,socfpga-dw-mshc";
> +			reg = <0xff808000 0x1000>;
> +			interrupts = <0 96 4>;
> +			fifo-depth = <0x400>;
> +			status = "disabled";
> +		};
> +
> +		ocram: sram at ffe00000 {
> +			compatible = "mmio-sram";
> +			reg = <0xffe00000 0x100000>;
> +		};
> +
> +		rst: rstmgr at ffd11000 {
> +			#reset-cells = <1>;
> +			compatible = "altr,rst-mgr";
> +			reg = <0xffd11000 0x1000>;
> +		};
> +
> +		spi0: spi at ffda4000 {
> +			compatible = "snps,dw-apb-ssi";
> +			#address-cells = <1>;
> +			#size-cells = <0>;
> +			reg = <0xffda4000 0x1000>;
> +			interrupts = <0 101 4>;
> +			num-chipselect = <4>;
> +			bus-num = <0>;
> +			status = "disabled";
> +		};
> +
> +		spi1: spi at ffda5000 {
> +			compatible = "snps,dw-apb-ssi";
> +			#address-cells = <1>;
> +			#size-cells = <0>;
> +			reg = <0xffda5000 0x1000>;
> +			interrupts = <0 102 4>;
> +			num-chipselect = <4>;
> +			bus-num = <0>;
> +			status = "disabled";
> +		};
> +
> +		sysmgr: sysmgr at ffd12000 {
> +			compatible = "altr,sys-mgr", "syscon";
> +			reg = <0xffd12000 0x1000>;
> +		};
> +
> +		/* Local timer */
> +		timer {
> +			compatible = "arm,armv8-timer";
> +			interrupts = <1 13 0xf01>,
> +				     <1 14 0xf01>,
> +				     <1 11 0xf01>,
> +				     <1 10 0xf01>;
> +		};
> +
> +		timer0: timer0 at ffc03000 {
> +			compatible = "snps,dw-apb-timer";
> +			interrupts = <0 113 4>;
> +			reg = <0xffc03000 0x100>;
> +		};
> +
> +		timer1: timer1 at ffc03100 {
> +			compatible = "snps,dw-apb-timer";
> +			interrupts = <0 114 4>;
> +			reg = <0xffc03100 0x100>;
> +		};
> +
> +		timer2: timer2 at ffd00000 {
> +			compatible = "snps,dw-apb-timer";
> +			interrupts = <0 115 4>;
> +			reg = <0xffd00000 0x100>;
> +		};
> +
> +		timer3: timer3 at ffd00100 {
> +			compatible = "snps,dw-apb-timer";
> +			interrupts = <0 116 4>;
> +			reg = <0xffd00100 0x100>;
> +		};
> +
> +		uart0: serial0 at ffc02000 {
> +			compatible = "snps,dw-apb-uart";
> +			reg = <0xffc02000 0x100>;
> +			interrupts = <0 108 4>;
> +			reg-shift = <2>;
> +			reg-io-width = <4>;
> +			status = "disabled";
> +		};
> +
> +		uart1: serial1 at ffc02100 {
> +			compatible = "snps,dw-apb-uart";
> +			reg = <0xffc02100 0x100>;
> +			interrupts = <0 109 4>;
> +			reg-shift = <2>;
> +			reg-io-width = <4>;
> +			status = "disabled";
> +		};
> +
> +		usbphy0: usbphy at 0 {
> +			#phy-cells = <0>;
> +			compatible = "usb-nop-xceiv";
> +			status = "okay";
> +		};
> +
> +		usb0: usb at ffb00000 {
> +			compatible = "snps,dwc2";
> +			reg = <0xffb00000 0x40000>;
> +			interrupts = <0 93 4>;
> +			phys = <&usbphy0>;
> +			phy-names = "usb2-phy";
> +			status = "disabled";
> +		};
> +
> +		usb1: usb at ffb40000 {
> +			compatible = "snps,dwc2";
> +			reg = <0xffb40000 0x40000>;
> +			interrupts = <0 94 4>;
> +			phys = <&usbphy0>;
> +			phy-names = "usb2-phy";
> +			status = "disabled";
> +		};
> +
> +		watchdog0: watchdog at ffd00200 {
> +			compatible = "snps,dw-wdt";
> +			reg = <0xffd00200 0x100>;
> +			interrupts = <0 117 4>;
> +			status = "disabled";
> +		};
> +
> +		watchdog1: watchdog at ffd00300 {
> +			compatible = "snps,dw-wdt";
> +			reg = <0xffd00300 0x100>;
> +			interrupts = <0 118 4>;
> +			status = "disabled";
> +		};
> +
> +		watchdog2: watchdog at ffd00400 {
> +			compatible = "snps,dw-wdt";
> +			reg = <0xffd00400 0x100>;
> +			interrupts = <0 125 4>;
> +			status = "disabled";
> +		};
> +
> +		watchdog3: watchdog at ffd00500 {
> +			compatible = "snps,dw-wdt";
> +			reg = <0xffd00500 0x100>;
> +			interrupts = <0 126 4>;
> +			status = "disabled";
> +		};
> +	};
> +};
> diff --git a/arch/arm64/boot/dts/altera/socfpga_stratix10_socdk.dts b/arch/arm64/boot/dts/altera/socfpga_stratix10_socdk.dts
> new file mode 100644
> index 0000000..8b162ef
> --- /dev/null
> +++ b/arch/arm64/boot/dts/altera/socfpga_stratix10_socdk.dts
> @@ -0,0 +1,38 @@
> +/*
> + * Copyright Altera Corporation (C) 2015. All rights reserved.
> + *
> + * This program is free software; you can redistribute it and/or modify
> + * it under the terms and conditions of the GNU General Public License,
> + * version 2, as published by the Free Software Foundation.
> + *
> + * This program is distributed in the hope 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.
> + *
> + * You should have received a copy of the GNU General Public License along with
> + * this program.  If not, see <http://www.gnu.org/licenses/>.
> + */
> +
> +/include/ "socfpga_stratix10.dtsi"
> +
> +/ {
> +	model = "SoCFPGA Stratix 10 SoCDK";
> +
> +	aliases {
> +		serial0 = &uart0;
> +	};
> +
> +	chosen {
> +		stdout-path = "serial0:115200n8";
> +	};
> +
> +	memory {
> +		device_type = "memory";
> +		reg = <0x0 0x40000000>;
> +	};
> +};
> +
> +&uart0 {
> +	status = "okay";
> +};
> diff --git a/arch/arm64/configs/defconfig b/arch/arm64/configs/defconfig
> index 4e17e7e..ad3b636 100644
> --- a/arch/arm64/configs/defconfig
> +++ b/arch/arm64/configs/defconfig
> @@ -36,6 +36,7 @@ CONFIG_ARCH_FSL_LS2085A=y
>  CONFIG_ARCH_HISI=y
>  CONFIG_ARCH_MEDIATEK=y
>  CONFIG_ARCH_SEATTLE=y
> +CONFIG_ARCH_STRATIX10=y
>  CONFIG_ARCH_TEGRA=y
>  CONFIG_ARCH_TEGRA_132_SOC=y
>  CONFIG_ARCH_QCOM=y



From jszhang at marvell.com  Mon Aug 10 19:44:06 2015
From: jszhang at marvell.com (Jisheng Zhang)
Date: Tue, 11 Aug 2015 10:44:06 +0800
Subject: [PATCH 2/3] ARM: berlin: register cpufreq-dt for the BG2Q
In-Reply-To: <55C90814.3050505@gmail.com>
References: <1438259752-16320-1-git-send-email-antoine.tenart@free-electrons.com>
 <1438259752-16320-3-git-send-email-antoine.tenart@free-electrons.com>
 <20150731141602.28b28f21@xhacker>	<55C90814.3050505@gmail.com>
Message-ID: <20150811104406.77e0a264@xhacker>

Dear Sebastian,

On Mon, 10 Aug 2015 22:22:44 +0200
Sebastian Hesselbarth <sebastian.hesselbarth at gmail.com> wrote:

> On 31.07.2015 08:16, Jisheng Zhang wrote:
> > On Thu, 30 Jul 2015 14:35:51 +0200
> > Antoine Tenart <antoine.tenart at free-electrons.com> wrote:
> >
> >> The BG2Q SoC uses cpufreq-dt for cpufreq. Register a platform device for
> >> this.
> >>
> >> Signed-off-by: Antoine Tenart <antoine.tenart at free-electrons.com>
> >> ---
> [...]
> >> diff --git a/arch/arm/mach-berlin/berlin.c b/arch/arm/mach-berlin/berlin.c
> >> index ac181c6797ee..0de906374994 100644
> >> --- a/arch/arm/mach-berlin/berlin.c
> >> +++ b/arch/arm/mach-berlin/berlin.c
> >> @@ -15,9 +15,21 @@
> [...]
> >> +static void __init berlin_init_late(void)
> >> +{
> >> +	if (of_find_matching_node(NULL, berlin2q_match))
> >> +		platform_device_register_simple("cpufreq-dt", -1, NULL, 0);
> >
> > I'm not sure is it acceptable to always register cpufreq-dt platform device.
> > In cpufreq-dt driver, the probe will exit if there's no cpuclk node.
> 
> Jisheng,
> 
> registering the _device_ without checking for any requirements of
> the _driver_ is usual practice. It it the driver's job to check
> all of them and report an error or warning. So, I am fine with
> adding the device unconditionally.
> 
> Using the .init_late() callback seems reasonable - but can you
> evaluate if we can have cpufreq-dt also for BG2/BG2CD? I'd also
> accept a single, default operating-point.

hmm, if so, we can enable cpufreq-dt for BG2/BG2CD. In fact, there's no any
problem if we don't touch the voltage, only changing the cpufreq should not
introduce stable issues.

> 
> BTW, there is one true point about Jisheng's comment: try to order
> your patches logically correct to avoid unnecessary warnings, i.e.
> 
> 1/3 add cpuclk
> 2/3 add cpufreq-dt properties
> 3/3 register cpufreq-dt device
> 
> If you consider a git-bisect run, you can land in between any of the
> three patches but they are always in the above order - so ordering is
> important.
> 
> Sebastian
> 
> >> +}
> >> +
> >>   static const char * const berlin_dt_compat[] = {
> >>   	"marvell,berlin",
> >>   	NULL,
> >> @@ -25,6 +37,7 @@ static const char * const berlin_dt_compat[] = {
> >>
> >>   DT_MACHINE_START(BERLIN_DT, "Marvell Berlin")
> >>   	.dt_compat	= berlin_dt_compat,
> >> +	.init_late	= berlin_init_late,
> >>   	/*
> >>   	 * with DT probing for L2CCs, berlin_init_machine can be removed.
> >>   	 * Note: 88DE3005 (Armada 1500-mini) uses pl310 l2cc
> >
> 



From jszhang at marvell.com  Mon Aug 10 19:46:50 2015
From: jszhang at marvell.com (Jisheng Zhang)
Date: Tue, 11 Aug 2015 10:46:50 +0800
Subject: [PATCH v2 4/5] ARM: berlin: add a PWM node on the BG2
In-Reply-To: <55C900D0.9060606@gmail.com>
References: <1438248201-29222-1-git-send-email-antoine.tenart@free-electrons.com>
 <1438248201-29222-5-git-send-email-antoine.tenart@free-electrons.com>
 <55C900D0.9060606@gmail.com>
Message-ID: <20150811104650.0e19ba41@xhacker>

Dear Sebastian,

On Mon, 10 Aug 2015 21:51:44 +0200
Sebastian Hesselbarth <sebastian.hesselbarth at gmail.com> wrote:

> On 30.07.2015 11:23, Antoine Tenart wrote:
> > This patch adds a PWM node in the Berlin BG2 device tree, using the
> > newly added Berlin PWM driver.
> >
> > Signed-off-by: Antoine Tenart <antoine.tenart at free-electrons.com>
> > ---
> >   arch/arm/boot/dts/berlin2.dtsi | 6 ++++++
> >   1 file changed, 6 insertions(+)
> >
> > diff --git a/arch/arm/boot/dts/berlin2.dtsi b/arch/arm/boot/dts/berlin2.dtsi
> > index ef811de09908..e17bd5faed27 100644
> > --- a/arch/arm/boot/dts/berlin2.dtsi
> > +++ b/arch/arm/boot/dts/berlin2.dtsi
> > @@ -512,5 +512,11 @@
> >   				interrupts = <GIC_SPI 15 IRQ_TYPE_LEVEL_HIGH>;
> >   			};
> >   		};
> > +
> > +		pwm: pwm at f20000 {
> > +			compatible = "marvell,berlin-pwm";
> > +			reg = <0xf20000 0x40>;
> > +			#pwm-cells = <3>;
> > +		};
> 
> I only checked berlin2.dtsi:
> The top most line with <GIC_SPI 15 ...> belongs to a sub-node of
> apb at fc0000 - which means that the pwm node isn't sorted in by
> address. Please sort the nodes by address in all three DT patches.
> 
> BTW, is there any IRQ from the PWM IP routed to any intc upstream?
> A quick look into some BSP code does not reveal any hints maybe
> one of the Marvell guys can comment on it.

There's no interrupt for the PWM in all berlin SoCs ;)

Thanks,
Jisheng



From djkurtz at chromium.org  Mon Aug 10 20:38:29 2015
From: djkurtz at chromium.org (Daniel Kurtz)
Date: Tue, 11 Aug 2015 11:38:29 +0800
Subject: [PATCH v6 0/3] Add MediaTek display PWM driver
In-Reply-To: <1438582892.19953.4.camel@mtksdaap41>
References: <1437380237-28961-1-git-send-email-yh.huang@mediatek.com>
 <2181696.fQcvS98Cqx@ubix> <1437729058.11386.4.camel@mtksdaap41>
 <1438582892.19953.4.camel@mtksdaap41>
Message-ID: <CAGS+omA6NCM_uwrXqz5W+m-dh9r7S_uSmb=Z8JAakQDTXY7pHQ@mail.gmail.com>

Thierry,

I think these patches are ready.
Will you please consider picking up in your pwm tree?

-Dan


On Mon, Aug 3, 2015 at 2:21 PM, YH Huang <yh.huang at mediatek.com> wrote:
> On Fri, 2015-07-24 at 17:10 +0800, YH Huang wrote:
>> On Fri, 2015-07-24 at 10:42 +0200, Matthias Brugger wrote:
>> > On Monday, July 20, 2015 04:17:14 PM YH Huang wrote:
>> > > This patch series add the use of display PWM driver, documentation
>> > > and device tree for Mediatek SoCs. The driver is used to support
>> > > the backlight of the panel. This is based on v4.2-rc1.
>> > >
>> > > The clock definitions (CLK_MM_DISP_PWM*) are added by James Liao's patch:
>> > > clk: mediatek: Add subsystem clocks of MT8173
>> > >
>> > > Change in v6:
>> > > 1. Enable clocks in the pwm_enable function
>> > > 2. Remove suspend/resume code since pwm-backlight driver has done the same
>> > > things 3. Revise some code to make it easier to read
>> > >
>> >
>> > Can you please provide the whole change log for all versions the next time.
>> > It's easier this way to understand the evolution of the series.
>>
>> Change in v6:
>> 1. Enable clocks in the pwm_enable function.
>> 2. Remove suspend/resume code since pwm-backlight driver has done the
>> same things.
>> 3. Revise some code to make it easier to read.
>>
>> Change in v5:
>> 1. Configure PWM output via pinctrl.
>> 2. Fix the parameter name in dtsi.
>>
>> Change in v4:
>> 1. Codebase is on v4.2-rc1.
>> 2. Add the PWM node in dtsi.
>> 3. Change the dependency in Kconfig.
>> 4. Rewrite some code for readability.
>>
>> Change in v3:
>> 1. Add suspend/resume function.
>> 2. Fix the formula for high_width calculation.
>> 3. Rewrite some code to make it easier to read.
>> 4. Add more information in the commit message.
>>
>> Change in v2:
>> 1. Rewrite descriptions for driver in kconfig to make it much clear.
>> 2. Rename the driver from "pwm-mediatek-disp" to "pwm-mtk-disp".
>> 3. Disable clocks in the error path.
>> 4. Change the shift values in decimal instead of hex.
>> 5. Rename and add some variables or function name for consistency and
>> readability.
>> 6. Drop unnecessary parentheses, spaces, variables and add newlines to
>> make the code easiler to read.
>>
>> Thanks for your suggestion.
>
> Hi Thierry,
>
> Do you have any suggestions?
> Maybe we could apply the patch?
>
> Regards,
> YH Huang
>
> --
> To unsubscribe from this list: send the line "unsubscribe linux-kernel" in
> the body of a message to majordomo at vger.kernel.org
> More majordomo info at  http://vger.kernel.org/majordomo-info.html
> Please read the FAQ at  http://www.tux.org/lkml/


From cw00.choi at samsung.com  Mon Aug 10 20:46:20 2015
From: cw00.choi at samsung.com (Chanwoo Choi)
Date: Tue, 11 Aug 2015 12:46:20 +0900
Subject: [PATCH 0/4] ARM: dts: exynos3250: Add UART2 and MMC2 dt node with
 related clocks
Message-ID: <1439264784-30322-1-git-send-email-cw00.choi@samsung.com>

This patch add the UART2 / MMC2 devicetree node for Exynos3250 SoC and add
the related clocks (mux, divider, gate) of UART2 / MMC2 device.

Chanwoo Choi (4):
  clk: samsung: exynos3250: Add UART2 clock
  clk: samsung: exynos3250: Add MMC2 clock
  ARM: dts: Add UART2 dt node for Exynos3250 SoC
  ARM: dts: Add MSHC2 dt node for Exynos3250 SoC

 arch/arm/boot/dts/exynos3250-pinctrl.dtsi | 42 +++++++++++++++++++++++++++++++
 arch/arm/boot/dts/exynos3250.dtsi         | 25 ++++++++++++++++++
 drivers/clk/samsung/clk-exynos3250.c      | 15 +++++++++++
 include/dt-bindings/clock/exynos3250.h    | 11 +++++++-
 4 files changed, 92 insertions(+), 1 deletion(-)

-- 
1.8.5.5



From cw00.choi at samsung.com  Mon Aug 10 20:46:22 2015
From: cw00.choi at samsung.com (Chanwoo Choi)
Date: Tue, 11 Aug 2015 12:46:22 +0900
Subject: [PATCH 2/4] clk: samsung: exynos3250: Add MMC2 clock
In-Reply-To: <1439264784-30322-1-git-send-email-cw00.choi@samsung.com>
References: <1439264784-30322-1-git-send-email-cw00.choi@samsung.com>
Message-ID: <1439264784-30322-3-git-send-email-cw00.choi@samsung.com>

This patch add the MMC2 clocks (mux, divider, gate) of Exynos3250 SoC.

Cc: Sylwester Nawrocki <s.nawrocki at samsung.com>
Cc: Tomasz Figa <tomasz.figa at gmail.com>
Signed-off-by: Chanwoo Choi <cw00.choi at samsung.com>
---
 drivers/clk/samsung/clk-exynos3250.c   | 9 +++++++++
 include/dt-bindings/clock/exynos3250.h | 7 ++++++-
 2 files changed, 15 insertions(+), 1 deletion(-)

diff --git a/drivers/clk/samsung/clk-exynos3250.c b/drivers/clk/samsung/clk-exynos3250.c
index 2105863a3ace..2683cf03e656 100644
--- a/drivers/clk/samsung/clk-exynos3250.c
+++ b/drivers/clk/samsung/clk-exynos3250.c
@@ -303,6 +303,7 @@ static struct samsung_mux_clock mux_clks[] __initdata = {
 
 	/* SRC_FSYS */
 	MUX(CLK_MOUT_TSADC, "mout_tsadc", group_sclk_p, SRC_FSYS, 28, 4),
+	MUX(CLK_MOUT_MMC2, "mout_mmc2", group_sclk_p, SRC_FSYS, 8, 4),
 	MUX(CLK_MOUT_MMC1, "mout_mmc1", group_sclk_p, SRC_FSYS, 4, 4),
 	MUX(CLK_MOUT_MMC0, "mout_mmc0", group_sclk_p, SRC_FSYS, 0, 4),
 
@@ -389,6 +390,11 @@ static struct samsung_div_clock div_clks[] __initdata = {
 		CLK_SET_RATE_PARENT, 0),
 	DIV(CLK_DIV_MMC0, "div_mmc0", "mout_mmc0", DIV_FSYS1, 0, 4),
 
+	/* DIV_FSYS2 */
+	DIV_F(CLK_DIV_MMC2_PRE, "div_mmc2_pre", "div_mmc2", DIV_FSYS2, 8, 8,
+		CLK_SET_RATE_PARENT, 0),
+	DIV(CLK_DIV_MMC2, "div_mmc2", "mout_mmc2", DIV_FSYS2, 0, 4),
+
 	/* DIV_PERIL0 */
 	DIV(CLK_DIV_UART2, "div_uart2", "mout_uart2", DIV_PERIL0, 8, 4),
 	DIV(CLK_DIV_UART1, "div_uart1", "mout_uart1", DIV_PERIL0, 4, 4),
@@ -539,6 +545,8 @@ static struct samsung_gate_clock gate_clks[] __initdata = {
 		GATE_SCLK_FSYS, 9, CLK_SET_RATE_PARENT, 0),
 	GATE(CLK_SCLK_EBI, "sclk_ebi", "div_ebi",
 		GATE_SCLK_FSYS, 6, CLK_SET_RATE_PARENT, 0),
+	GATE(CLK_SCLK_MMC2, "sclk_mmc2", "div_mmc2_pre",
+		GATE_SCLK_FSYS, 2, CLK_SET_RATE_PARENT, 0),
 	GATE(CLK_SCLK_MMC1, "sclk_mmc1", "div_mmc1_pre",
 		GATE_SCLK_FSYS, 1, CLK_SET_RATE_PARENT, 0),
 	GATE(CLK_SCLK_MMC0, "sclk_mmc0", "div_mmc0_pre",
@@ -634,6 +642,7 @@ static struct samsung_gate_clock gate_clks[] __initdata = {
 	GATE(CLK_USBOTG, "usbotg", "div_aclk_200", GATE_IP_FSYS, 13, 0, 0),
 	GATE(CLK_USBHOST, "usbhost", "div_aclk_200", GATE_IP_FSYS, 12, 0, 0),
 	GATE(CLK_SROMC, "sromc", "div_aclk_200", GATE_IP_FSYS, 11, 0, 0),
+	GATE(CLK_SDMMC2, "sdmmc2", "div_aclk_200", GATE_IP_FSYS, 7, 0, 0),
 	GATE(CLK_SDMMC1, "sdmmc1", "div_aclk_200", GATE_IP_FSYS, 6, 0, 0),
 	GATE(CLK_SDMMC0, "sdmmc0", "div_aclk_200", GATE_IP_FSYS, 5, 0, 0),
 	GATE(CLK_PDMA1, "pdma1", "div_aclk_200", GATE_IP_FSYS, 1, 0, 0),
diff --git a/include/dt-bindings/clock/exynos3250.h b/include/dt-bindings/clock/exynos3250.h
index 89a7d97b002c..fbc9ef61b191 100644
--- a/include/dt-bindings/clock/exynos3250.h
+++ b/include/dt-bindings/clock/exynos3250.h
@@ -79,6 +79,7 @@
 #define CLK_MOUT_APLL			59
 #define CLK_MOUT_ACLK_266_SUB		60
 #define CLK_MOUT_UART2			61
+#define CLK_MOUT_MMC2			62
 
 /* Dividers */
 #define CLK_DIV_GPL			64
@@ -128,6 +129,8 @@
 #define CLK_DIV_HPM			108
 #define CLK_DIV_COPY			109
 #define CLK_DIV_UART2			110
+#define CLK_DIV_MMC2_PRE		111
+#define CLK_DIV_MMC2			112
 
 /* Gates */
 #define CLK_ASYNC_G3D			128
@@ -225,6 +228,7 @@
 #define CLK_BLOCK_CAM			220
 #define CLK_SMIES			221
 #define CLK_UART2			222
+#define CLK_SDMMC2			223
 
 /* Special clocks */
 #define CLK_SCLK_JPEG			224
@@ -252,12 +256,13 @@
 #define CLK_SCLK_UART1			246
 #define CLK_SCLK_UART0			247
 #define CLK_SCLK_UART2			248
+#define CLK_SCLK_MMC2			249
 
 /*
  * Total number of clocks of main CMU.
  * NOTE: Must be equal to last clock ID increased by one.
  */
-#define CLK_NR_CLKS			249
+#define CLK_NR_CLKS			250
 
 /*
  * CMU DMC
-- 
1.8.5.5



From cw00.choi at samsung.com  Mon Aug 10 20:46:23 2015
From: cw00.choi at samsung.com (Chanwoo Choi)
Date: Tue, 11 Aug 2015 12:46:23 +0900
Subject: [PATCH 3/4] ARM: dts: Add UART2 dt node for Exynos3250 SoC
In-Reply-To: <1439264784-30322-1-git-send-email-cw00.choi@samsung.com>
References: <1439264784-30322-1-git-send-email-cw00.choi@samsung.com>
Message-ID: <1439264784-30322-4-git-send-email-cw00.choi@samsung.com>

This patch add the uart2 devicetree node for Exynos3250 SoC.

Cc: Kukjin Kim <kgene at kernel.org>
Cc: Krzysztof Kozlowski <k.kozlowski at samsung.com>
Signed-off-by: Chanwoo Choi <cw00.choi at samsung.com>
---
 arch/arm/boot/dts/exynos3250-pinctrl.dtsi |  7 +++++++
 arch/arm/boot/dts/exynos3250.dtsi         | 12 ++++++++++++
 2 files changed, 19 insertions(+)

diff --git a/arch/arm/boot/dts/exynos3250-pinctrl.dtsi b/arch/arm/boot/dts/exynos3250-pinctrl.dtsi
index 5ab81c39e2c9..eac1d21c10d4 100644
--- a/arch/arm/boot/dts/exynos3250-pinctrl.dtsi
+++ b/arch/arm/boot/dts/exynos3250-pinctrl.dtsi
@@ -120,6 +120,13 @@
 		samsung,pin-drv = <0>;
 	};
 
+	uart2_data: uart2-data {
+		samsung,pins = "gpa1-0", "gpa1-1";
+		samsung,pin-function = <2>;
+		samsung,pin-pud = <0>;
+		samsung,pin-drv = <0>;
+	};
+
 	i2c3_bus: i2c3-bus {
 		samsung,pins = "gpa1-2", "gpa1-3";
 		samsung,pin-function = <3>;
diff --git a/arch/arm/boot/dts/exynos3250.dtsi b/arch/arm/boot/dts/exynos3250.dtsi
index 2db99433e17f..02f3250766c9 100644
--- a/arch/arm/boot/dts/exynos3250.dtsi
+++ b/arch/arm/boot/dts/exynos3250.dtsi
@@ -42,6 +42,7 @@
 		i2c7 = &i2c_7;
 		serial0 = &serial_0;
 		serial1 = &serial_1;
+		serial2 = &serial_2;
 	};
 
 	cpus {
@@ -435,6 +436,17 @@
 			status = "disabled";
 		};
 
+		serial_2: serial at 13820000 {
+			compatible = "samsung,exynos4210-uart";
+			reg = <0x13820000 0x100>;
+			interrupts = <0 111 0>;
+			clocks = <&cmu CLK_UART2>, <&cmu CLK_SCLK_UART2>;
+			clock-names = "uart", "clk_uart_baud0";
+			pinctrl-names = "default";
+			pinctrl-0 = <&uart2_data>;
+			status = "disabled";
+		};
+
 		i2c_0: i2c at 13860000 {
 			#address-cells = <1>;
 			#size-cells = <0>;
-- 
1.8.5.5



From cw00.choi at samsung.com  Mon Aug 10 20:46:21 2015
From: cw00.choi at samsung.com (Chanwoo Choi)
Date: Tue, 11 Aug 2015 12:46:21 +0900
Subject: [PATCH 1/4] clk: samsung: exynos3250: Add UART2 clock
In-Reply-To: <1439264784-30322-1-git-send-email-cw00.choi@samsung.com>
References: <1439264784-30322-1-git-send-email-cw00.choi@samsung.com>
Message-ID: <1439264784-30322-2-git-send-email-cw00.choi@samsung.com>

This patch add the UART2 clocks (mux, divider, gate) of Exynos3250 SoC.

Cc: Sylwester Nawrocki <s.nawrocki at samsung.com>
Cc: Tomasz Figa <tomasz.figa at gmail.com>
Signed-off-by: Chanwoo Choi <cw00.choi at samsung.com>
---
 drivers/clk/samsung/clk-exynos3250.c   | 6 ++++++
 include/dt-bindings/clock/exynos3250.h | 6 +++++-
 2 files changed, 11 insertions(+), 1 deletion(-)

diff --git a/drivers/clk/samsung/clk-exynos3250.c b/drivers/clk/samsung/clk-exynos3250.c
index 538de66a759e..2105863a3ace 100644
--- a/drivers/clk/samsung/clk-exynos3250.c
+++ b/drivers/clk/samsung/clk-exynos3250.c
@@ -307,6 +307,7 @@ static struct samsung_mux_clock mux_clks[] __initdata = {
 	MUX(CLK_MOUT_MMC0, "mout_mmc0", group_sclk_p, SRC_FSYS, 0, 4),
 
 	/* SRC_PERIL0 */
+	MUX(CLK_MOUT_UART2, "mout_uart2", group_sclk_p, SRC_PERIL0, 8, 4),
 	MUX(CLK_MOUT_UART1, "mout_uart1", group_sclk_p, SRC_PERIL0, 4, 4),
 	MUX(CLK_MOUT_UART0, "mout_uart0", group_sclk_p, SRC_PERIL0, 0, 4),
 
@@ -389,6 +390,7 @@ static struct samsung_div_clock div_clks[] __initdata = {
 	DIV(CLK_DIV_MMC0, "div_mmc0", "mout_mmc0", DIV_FSYS1, 0, 4),
 
 	/* DIV_PERIL0 */
+	DIV(CLK_DIV_UART2, "div_uart2", "mout_uart2", DIV_PERIL0, 8, 4),
 	DIV(CLK_DIV_UART1, "div_uart1", "mout_uart1", DIV_PERIL0, 4, 4),
 	DIV(CLK_DIV_UART0, "div_uart0", "mout_uart0", DIV_PERIL0, 0, 4),
 
@@ -551,6 +553,9 @@ static struct samsung_gate_clock gate_clks[] __initdata = {
 		GATE_SCLK_PERIL, 7, CLK_SET_RATE_PARENT, 0),
 	GATE(CLK_SCLK_SPI0, "sclk_spi0", "div_spi0_pre",
 		GATE_SCLK_PERIL, 6, CLK_SET_RATE_PARENT, 0),
+
+	GATE(CLK_SCLK_UART2, "sclk_uart2", "div_uart2",
+		GATE_SCLK_PERIL, 2, CLK_SET_RATE_PARENT, 0),
 	GATE(CLK_SCLK_UART1, "sclk_uart1", "div_uart1",
 		GATE_SCLK_PERIL, 1, CLK_SET_RATE_PARENT, 0),
 	GATE(CLK_SCLK_UART0, "sclk_uart0", "div_uart0",
@@ -648,6 +653,7 @@ static struct samsung_gate_clock gate_clks[] __initdata = {
 	GATE(CLK_I2C2, "i2c2", "div_aclk_100", GATE_IP_PERIL, 8, 0, 0),
 	GATE(CLK_I2C1, "i2c1", "div_aclk_100", GATE_IP_PERIL, 7, 0, 0),
 	GATE(CLK_I2C0, "i2c0", "div_aclk_100", GATE_IP_PERIL, 6, 0, 0),
+	GATE(CLK_UART2, "uart2", "div_aclk_100", GATE_IP_PERIL, 2, 0, 0),
 	GATE(CLK_UART1, "uart1", "div_aclk_100", GATE_IP_PERIL, 1, 0, 0),
 	GATE(CLK_UART0, "uart0", "div_aclk_100", GATE_IP_PERIL, 0, 0, 0),
 };
diff --git a/include/dt-bindings/clock/exynos3250.h b/include/dt-bindings/clock/exynos3250.h
index aab088d30199..89a7d97b002c 100644
--- a/include/dt-bindings/clock/exynos3250.h
+++ b/include/dt-bindings/clock/exynos3250.h
@@ -78,6 +78,7 @@
 #define CLK_MOUT_CORE			58
 #define CLK_MOUT_APLL			59
 #define CLK_MOUT_ACLK_266_SUB		60
+#define CLK_MOUT_UART2			61
 
 /* Dividers */
 #define CLK_DIV_GPL			64
@@ -126,6 +127,7 @@
 #define CLK_DIV_CORE			107
 #define CLK_DIV_HPM			108
 #define CLK_DIV_COPY			109
+#define CLK_DIV_UART2			110
 
 /* Gates */
 #define CLK_ASYNC_G3D			128
@@ -222,6 +224,7 @@
 #define CLK_BLOCK_MFC			219
 #define CLK_BLOCK_CAM			220
 #define CLK_SMIES			221
+#define CLK_UART2			222
 
 /* Special clocks */
 #define CLK_SCLK_JPEG			224
@@ -248,12 +251,13 @@
 #define CLK_SCLK_SPI0			245
 #define CLK_SCLK_UART1			246
 #define CLK_SCLK_UART0			247
+#define CLK_SCLK_UART2			248
 
 /*
  * Total number of clocks of main CMU.
  * NOTE: Must be equal to last clock ID increased by one.
  */
-#define CLK_NR_CLKS			248
+#define CLK_NR_CLKS			249
 
 /*
  * CMU DMC
-- 
1.8.5.5



From cw00.choi at samsung.com  Mon Aug 10 20:46:24 2015
From: cw00.choi at samsung.com (Chanwoo Choi)
Date: Tue, 11 Aug 2015 12:46:24 +0900
Subject: [PATCH 4/4] ARM: dts: Add MSHC2 dt node for Exynos3250 SoC
In-Reply-To: <1439264784-30322-1-git-send-email-cw00.choi@samsung.com>
References: <1439264784-30322-1-git-send-email-cw00.choi@samsung.com>
Message-ID: <1439264784-30322-5-git-send-email-cw00.choi@samsung.com>

This patch add the MSHC2 (Mobile Storage Host Controller) devicetree node for
Exynos3250 SoC.

Cc: Kukjin Kim <kgene at kernel.org>
Cc: Krzysztof Kozlowski <k.kozlowski at samsung.com>
Signed-off-by: Chanwoo Choi <cw00.choi at samsung.com>
---
 arch/arm/boot/dts/exynos3250-pinctrl.dtsi | 35 +++++++++++++++++++++++++++++++
 arch/arm/boot/dts/exynos3250.dtsi         | 13 ++++++++++++
 2 files changed, 48 insertions(+)

diff --git a/arch/arm/boot/dts/exynos3250-pinctrl.dtsi b/arch/arm/boot/dts/exynos3250-pinctrl.dtsi
index eac1d21c10d4..78b995fed6c7 100644
--- a/arch/arm/boot/dts/exynos3250-pinctrl.dtsi
+++ b/arch/arm/boot/dts/exynos3250-pinctrl.dtsi
@@ -452,6 +452,41 @@
 		samsung,pin-drv = <3>;
 	};
 
+	sd2_clk: sd2-clk {
+		samsung,pins = "gpk2-0";
+		samsung,pin-function = <2>;
+		samsung,pin-pud = <0>;
+		samsung,pin-drv = <3>;
+	};
+
+	sd2_cmd: sd2-cmd {
+		samsung,pins = "gpk2-1";
+		samsung,pin-function = <2>;
+		samsung,pin-pud = <0>;
+		samsung,pin-drv = <3>;
+	};
+
+	sd2_cd: sd2-cd {
+		samsung,pins = "gpk2-2";
+		samsung,pin-function = <2>;
+		samsung,pin-pud = <3>;
+		samsung,pin-drv = <3>;
+	};
+
+	sd2_bus1: sd2-bus-width1 {
+		samsung,pins = "gpk2-3";
+		samsung,pin-function = <2>;
+		samsung,pin-pud = <3>;
+		samsung,pin-drv = <3>;
+	};
+
+	sd2_bus4: sd2-bus-width4 {
+		samsung,pins = "gpk2-4", "gpk2-5", "gpk2-6";
+		samsung,pin-function = <2>;
+		samsung,pin-pud = <3>;
+		samsung,pin-drv = <3>;
+	};
+
 	cam_port_b_io: cam-port-b-io {
 		samsung,pins = "gpm0-0", "gpm0-1", "gpm0-2", "gpm0-3",
 				"gpm0-4", "gpm0-5", "gpm0-6", "gpm0-7",
diff --git a/arch/arm/boot/dts/exynos3250.dtsi b/arch/arm/boot/dts/exynos3250.dtsi
index 02f3250766c9..5a91eaa26565 100644
--- a/arch/arm/boot/dts/exynos3250.dtsi
+++ b/arch/arm/boot/dts/exynos3250.dtsi
@@ -30,6 +30,7 @@
 		pinctrl1 = &pinctrl_1;
 		mshc0 = &mshc_0;
 		mshc1 = &mshc_1;
+		mshc2 = &mshc_2;
 		spi0 = &spi_0;
 		spi1 = &spi_1;
 		i2c0 = &i2c_0;
@@ -341,6 +342,18 @@
 			status = "disabled";
 		};
 
+		mshc_2: mshc at 12530000 {
+			compatible = "samsung,exynos5250-dw-mshc";
+			reg = <0x12530000 0x1000>;
+			interrupts = <0 144 0>;
+			clocks = <&cmu CLK_SDMMC2>, <&cmu CLK_SCLK_MMC2>;
+			clock-names = "biu", "ciu";
+			fifo-depth = <0x80>;
+			#address-cells = <1>;
+			#size-cells = <0>;
+			status = "disabled";
+		};
+
 		exynos_usbphy: exynos-usbphy at 125B0000 {
 			compatible = "samsung,exynos3250-usb2-phy";
 			reg = <0x125B0000 0x100>;
-- 
1.8.5.5



From yamada.masahiro at socionext.com  Mon Aug 10 21:00:06 2015
From: yamada.masahiro at socionext.com (Masahiro Yamada)
Date: Tue, 11 Aug 2015 13:00:06 +0900
Subject: [PATCH v4] dtb: Create a common home for cross-architecture dtsi
 files.
In-Reply-To: <1438617993-1012-1-git-send-email-ian.campbell@citrix.com>
References: <1438617993-1012-1-git-send-email-ian.campbell@citrix.com>
Message-ID: <CAK7LNARyEbnOWTis0Nx9zwTcwH_s3GZKg2XYG3+zLnf=FhhctA@mail.gmail.com>

Hi

2015-08-04 1:06 GMT+09:00 Ian Campbell <ian.campbell at citrix.com>:
> Commit 9ccd608070b6 ("arm64: dts: add device tree for ARM SMM-A53x2 on
> LogicTile Express 20MG") added a new dts file to arch/arm64 which
> included "../../../../arm/boot/dts/vexpress-v2m-rs1.dtsi", i.e. a
> .dtsi supplied by arch/arm.
>
> Unfortunately this causes some issues for the split device tree
> repository[0], since things get moved around there. In that context
> the new .dts ends up at src/arm64/arm/vexpress-v2f-1xv7-ca53x2.dts
> while the include is at src/arm/vexpress-v2m-rs1.dtsi.
>
> The sharing of the .dtsi is legitimate since the baseboard is the same
> for various vexpress systems whatever processor they use.
>
> Rather than using ../../ tricks to pickup .dtsi files from another
> arch this patch creates a new directory kernel/dts as a home for such
> cross-arch .dtsi files and arranges for it to be in the include path
> for both dtc and cpp. The dtsi file itself is moved into a vendor
> subdir in this case "arm" (the vendor, not the ARCH=).


Question:
If this patch is applied, which directory will be created in
device-tree-rebasing?
src/kernel/, src/common/, or something else?
Either will do, of course.


Another nit:
I just noticed a period at the end of the commit subject.
Re-post would not be needed only for such a minor thing,
but please try best to remember to drop it when this patch is applied.




-- 
Best Regards
Masahiro Yamada


From djkurtz at chromium.org  Mon Aug 10 21:28:41 2015
From: djkurtz at chromium.org (Daniel Kurtz)
Date: Tue, 11 Aug 2015 12:28:41 +0800
Subject: [PATCH v2 2/2] watchdog: add wdt shutdown callback to disable wdt
 if enabled
In-Reply-To: <1488521.5eJqASov2O@ubix>
References: <1437630551-39650-1-git-send-email-eddie.huang@mediatek.com>
 <1437630551-39650-3-git-send-email-eddie.huang@mediatek.com>
 <1488521.5eJqASov2O@ubix>
Message-ID: <CAGS+omD1UYSTfJ4-vZSE_BYuvGcTvpbC7T4ukaV10xuQxkCChg@mail.gmail.com>

Hi Guenter, Matthias,

On Fri, Jul 24, 2015 at 1:37 AM, Matthias Brugger
<matthias.bgg at gmail.com> wrote:
> On Thursday, July 23, 2015 01:49:11 PM Eddie Huang wrote:
>> From: Greta Zhang <greta.zhang at mediatek.com>
>>
>> Without .shutdown(), watchdog might reset the system during power off.
>> For example, if watchdog's timeout is set to 30s, then it is reset to
>> zero by mtk_wdt_ping(). During power off, no app will ping watchdog,
>> but watchdog is still running and may trigger reset.
>>
>> Signed-off-by: Greta Zhang <greta.zhang at mediatek.com>
>> Signed-off-by: Eddie Huang <eddie.huang at mediatek.com>
>> ---
>>  drivers/watchdog/mtk_wdt.c | 9 +++++++++
>>  1 file changed, 9 insertions(+)
>
> Acked-by: Matthias Brugger <matthias.bgg at gmail.com>

is the plan to land these two patches via Guenter's watchdog tree [0]?
[0] git://www.linux-watchdog.org/linux-watchdog.git

In fact, though, I don't see any new patches in that repository.
The only branches I see are:
  remotes/wdog/master                                      b953c0d Linux 4.1
  remotes/wdog/winbond-superio                             dc89871
Sample Winbond Super-I/O MFD device consisting out of a lowel-level
driver that does the detection and creates the platform-data and a
watchdog driver.

Am I looking in the wrong place?

-Dan

> --
> To unsubscribe from this list: send the line "unsubscribe linux-kernel" in
> the body of a message to majordomo at vger.kernel.org
> More majordomo info at  http://vger.kernel.org/majordomo-info.html
> Please read the FAQ at  http://www.tux.org/lkml/


From linux at roeck-us.net  Mon Aug 10 21:42:20 2015
From: linux at roeck-us.net (Guenter Roeck)
Date: Mon, 10 Aug 2015 21:42:20 -0700
Subject: [PATCH v2 2/2] watchdog: add wdt shutdown callback to disable
 wdt if enabled
In-Reply-To: <CAGS+omD1UYSTfJ4-vZSE_BYuvGcTvpbC7T4ukaV10xuQxkCChg@mail.gmail.com>
References: <1437630551-39650-1-git-send-email-eddie.huang@mediatek.com>
 <1437630551-39650-3-git-send-email-eddie.huang@mediatek.com>
 <1488521.5eJqASov2O@ubix>
 <CAGS+omD1UYSTfJ4-vZSE_BYuvGcTvpbC7T4ukaV10xuQxkCChg@mail.gmail.com>
Message-ID: <55C97D2C.6090505@roeck-us.net>

On 08/10/2015 09:28 PM, Daniel Kurtz wrote:
> Hi Guenter, Matthias,
>
> On Fri, Jul 24, 2015 at 1:37 AM, Matthias Brugger
> <matthias.bgg at gmail.com> wrote:
>> On Thursday, July 23, 2015 01:49:11 PM Eddie Huang wrote:
>>> From: Greta Zhang <greta.zhang at mediatek.com>
>>>
>>> Without .shutdown(), watchdog might reset the system during power off.
>>> For example, if watchdog's timeout is set to 30s, then it is reset to
>>> zero by mtk_wdt_ping(). During power off, no app will ping watchdog,
>>> but watchdog is still running and may trigger reset.
>>>
>>> Signed-off-by: Greta Zhang <greta.zhang at mediatek.com>
>>> Signed-off-by: Eddie Huang <eddie.huang at mediatek.com>
>>> ---
>>>   drivers/watchdog/mtk_wdt.c | 9 +++++++++
>>>   1 file changed, 9 insertions(+)
>>
>> Acked-by: Matthias Brugger <matthias.bgg at gmail.com>
>
> is the plan to land these two patches via Guenter's watchdog tree [0]?
> [0] git://www.linux-watchdog.org/linux-watchdog.git
>
That is Wim's tree, and Wim is the maintainer ;-).

I have the patches queued in my tree [1], and I plan to send a pull request
to Wim this week or early next week.

Guenter

---
[1] https://git.kernel.org/cgit/linux/kernel/git/groeck/linux-staging.git/log/?h=watchdog-next



From djkurtz at chromium.org  Mon Aug 10 21:43:25 2015
From: djkurtz at chromium.org (Daniel Kurtz)
Date: Tue, 11 Aug 2015 12:43:25 +0800
Subject: [PATCH v7 0/9] Fixes and new clocks support for Mediatek MT8173
In-Reply-To: <1439200228-318-1-git-send-email-jamesjj.liao@mediatek.com>
References: <1439200228-318-1-git-send-email-jamesjj.liao@mediatek.com>
Message-ID: <CAGS+omCya_0djzoVGhJchmaTtzo2z+JdnJHDjLipNMsZKV=MLQ@mail.gmail.com>

Hi James,

On Mon, Aug 10, 2015 at 5:50 PM, James Liao <jamesjj.liao at mediatek.com> wrote:
> This patchset is based on 4.2-rc2 and [1], and contains minor fixes and
> subsystem clocks support for Mediatek MT8173.
>
> The previous reviews can be found in [2].
>
> changes since v6:
> - Use DUMMY_RATE (0) instead of typical rate for clocks that we don't care
>   and not controlled in CCF.

For the whole series:
Reviewed-by: Daniel Kurtz <djkurtz at chromium.org>

>
> changes since v5:
> - Rebase to 4.2-rc2.
> - Patch "Fix enabling of critical clocks" had been included in 4.2-rc2,
>   so it need not be included in this patchset.
>
> changes since v4:
> - Add a separated patch to remove unused dpi_ck.
> - Add separated patches to fix clk/mediatek in release 4.2-rc1.
> - Add __init* for initialization data and functions.
> - Rename dummy_clk with oscillator in DT.
> - Remove mtk_clk_register_apmixed_ex(), call mtk_clk_register_ref2usb_tx()
>   directly to register USB clock.
>
> changes since v3:
> - Remove clk_null dependency from root clocks.
> - Use fixed-rate clocks with typical rate to replace clk_null.
> - Separate ref2usb_tx implementation to clk-apmixed.c
> - Use clock-controller as the name of clock providers.
>
> changes since v2:
> - Rebase to 4.2-rc1.
> - Add device tree nodes for subsystem clocks.
> - Fine tune comments of patches.
> - Add __init, __initconst and const to init data and functions.
> - Removed unused code from init functions of subsystem clocks.
>
> changes since v1:
> - Add CA7PLL and CA15PLL as critical clocks.
> - Use the same register descriptor for imgsys, vensys and vencltsys.
> - Generalize apmixedsys special clocks registration.
>
> [1] https://patchwork.kernel.org/patch/6446341/
> [2] https://lkml.org/lkml/2015/8/4/111
>
> James Liao (9):
>   clk: mediatek: Removed unused dpi_ck clock from MT8173
>   clk: mediatek: Remove unused code from MT8173.
>   clk: mediatek: Add __initdata and __init for data and functions
>   clk: mediatek: Add fixed clocks support for Mediatek SoC.
>   clk: mediatek: Fix rate and dependency of MT8173 clocks
>   dt-bindings: ARM: Mediatek: Document devicetree bindings for clock
>     controllers
>   clk: mediatek: Add subsystem clocks of MT8173
>   clk: mediatek: Add USB clock support in MT8173 APMIXEDSYS
>   arm64: dts: mt8173: Add subsystem clock controller device nodes
>
>  .../bindings/arm/mediatek/mediatek,imgsys.txt      |  22 ++
>  .../bindings/arm/mediatek/mediatek,mmsys.txt       |  22 ++
>  .../bindings/arm/mediatek/mediatek,vdecsys.txt     |  22 ++
>  .../bindings/arm/mediatek/mediatek,vencltsys.txt   |  22 ++
>  .../bindings/arm/mediatek/mediatek,vencsys.txt     |  22 ++
>  arch/arm64/boot/dts/mediatek/mt8173.dtsi           |  37 +++
>  drivers/clk/mediatek/Makefile                      |   2 +-
>  drivers/clk/mediatek/clk-apmixed.c                 | 107 +++++++
>  drivers/clk/mediatek/clk-gate.c                    |   2 +-
>  drivers/clk/mediatek/clk-mt8173.c                  | 342 ++++++++++++++++++++-
>  drivers/clk/mediatek/clk-mtk.c                     |  36 ++-
>  drivers/clk/mediatek/clk-mtk.h                     |  24 +-
>  drivers/clk/mediatek/clk-pll.c                     |   7 +-
>  include/dt-bindings/clock/mt8173-clk.h             | 101 +++++-
>  14 files changed, 735 insertions(+), 33 deletions(-)
>  create mode 100644 Documentation/devicetree/bindings/arm/mediatek/mediatek,imgsys.txt
>  create mode 100644 Documentation/devicetree/bindings/arm/mediatek/mediatek,mmsys.txt
>  create mode 100644 Documentation/devicetree/bindings/arm/mediatek/mediatek,vdecsys.txt
>  create mode 100644 Documentation/devicetree/bindings/arm/mediatek/mediatek,vencltsys.txt
>  create mode 100644 Documentation/devicetree/bindings/arm/mediatek/mediatek,vencsys.txt
>  create mode 100644 drivers/clk/mediatek/clk-apmixed.c
>
> --
> 1.8.1.1.dirty
>


From hongzhou.yang at mediatek.com  Mon Aug 10 21:49:31 2015
From: hongzhou.yang at mediatek.com (Hongzhou Yang)
Date: Mon, 10 Aug 2015 21:49:31 -0700
Subject: [PATCH] pinctrl: mediatek: Fix multiple registeration issue.
Message-ID: <1439268571-10895-1-git-send-email-hongzhou.yang@mediatek.com>

Use dynamic allocation to fix multiple registeration issue.

--------------8<--------------------
Since our common driver need support main chip and PMU
at the same time, that means it will register two
pinctrl device, and the pinctrl_desc structure should
be used two times.

But pinctrl_desc use global static definition, then
the latest registered pinctrl device will overwrite
the old one's, all members in pinctrl_desc will set to
the new one's, such as name, pins and pins numbers, etc.
This is a bug. Changing to use devm_kzalloc to fix it.

Cc: stable at vger.kernel.org # v4.1+
Signed-off-by: Hongzhou Yang <hongzhou.yang at mediatek.com>
---
 drivers/pinctrl/mediatek/pinctrl-mtk-common.c |   27 +++++++++++++++----------
 1 file changed, 16 insertions(+), 11 deletions(-)

diff --git a/drivers/pinctrl/mediatek/pinctrl-mtk-common.c b/drivers/pinctrl/mediatek/pinctrl-mtk-common.c
index ad1ea16..2bba504 100644
--- a/drivers/pinctrl/mediatek/pinctrl-mtk-common.c
+++ b/drivers/pinctrl/mediatek/pinctrl-mtk-common.c
@@ -1202,17 +1202,12 @@ static int mtk_pctrl_build_state(struct platform_device *pdev)
 	return 0;
 }
 
-static struct pinctrl_desc mtk_pctrl_desc = {
-	.confops	= &mtk_pconf_ops,
-	.pctlops	= &mtk_pctrl_ops,
-	.pmxops		= &mtk_pmx_ops,
-};
-
 int mtk_pctrl_init(struct platform_device *pdev,
 		const struct mtk_pinctrl_devdata *data,
 		struct regmap *regmap)
 {
 	struct pinctrl_pin_desc *pins;
+	struct pinctrl_desc *mtk_pctrl_desc;
 	struct mtk_pinctrl *pctl;
 	struct device_node *np = pdev->dev.of_node, *node;
 	struct property *prop;
@@ -1265,12 +1260,22 @@ int mtk_pctrl_init(struct platform_device *pdev,
 
 	for (i = 0; i < pctl->devdata->npins; i++)
 		pins[i] = pctl->devdata->pins[i].pin;
-	mtk_pctrl_desc.name = dev_name(&pdev->dev);
-	mtk_pctrl_desc.owner = THIS_MODULE;
-	mtk_pctrl_desc.pins = pins;
-	mtk_pctrl_desc.npins = pctl->devdata->npins;
+
+	mtk_pctrl_desc = devm_kzalloc(&pdev->dev, sizeof(*mtk_pctrl_desc),
+				GFP_KERNEL);
+	if (!mtk_pctrl_desc)
+		return -ENOMEM;
+
+	mtk_pctrl_desc->name = dev_name(&pdev->dev);
+	mtk_pctrl_desc->owner = THIS_MODULE;
+	mtk_pctrl_desc->pins = pins;
+	mtk_pctrl_desc->npins = pctl->devdata->npins;
+	mtk_pctrl_desc->confops = &mtk_pconf_ops;
+	mtk_pctrl_desc->pctlops = &mtk_pctrl_ops;
+	mtk_pctrl_desc->pmxops = &mtk_pmx_ops;
 	pctl->dev = &pdev->dev;
-	pctl->pctl_dev = pinctrl_register(&mtk_pctrl_desc, &pdev->dev, pctl);
+
+	pctl->pctl_dev = pinctrl_register(mtk_pctrl_desc, &pdev->dev, pctl);
 	if (IS_ERR(pctl->pctl_dev)) {
 		dev_err(&pdev->dev, "couldn't register pinctrl driver\n");
 		return PTR_ERR(pctl->pctl_dev);
-- 
1.7.9.5



From wens at csie.org  Mon Aug 10 21:49:54 2015
From: wens at csie.org (Chen-Yu Tsai)
Date: Tue, 11 Aug 2015 12:49:54 +0800
Subject: [PATCH v2 5/7] ARM: sun8i: Add clock indices
In-Reply-To: <CAGb2v64nvA1K=Ya7_99-2G1LtFjcuj+qQbO1GJaqsL+yPF+Xdw@mail.gmail.com>
References: <1438364782-3968-1-git-send-email-maxime.ripard@free-electrons.com>
 <1438364782-3968-6-git-send-email-maxime.ripard@free-electrons.com>
 <CAGb2v64nvA1K=Ya7_99-2G1LtFjcuj+qQbO1GJaqsL+yPF+Xdw@mail.gmail.com>
Message-ID: <CAGb2v64-=1Byzo-h=7Pq=HK9Xx01KaTKT89Nx6jVWUc_kqthyg@mail.gmail.com>

On Sat, Aug 8, 2015 at 12:21 AM, Chen-Yu Tsai <wens at csie.org> wrote:
> On Sat, Aug 1, 2015 at 1:46 AM, Maxime Ripard
> <maxime.ripard at free-electrons.com> wrote:
>> The A23 and A33 gates have a non continuous set of clock IDs that are
>> valid. Add the clock-indices property to the DT to express this.
>>
>> Signed-off-by: Maxime Ripard <maxime.ripard at free-electrons.com>
>> ---
>>  arch/arm/boot/dts/sun8i-a23-a33.dtsi | 15 +++++++++++++++
>>  1 file changed, 15 insertions(+)
>>
>> diff --git a/arch/arm/boot/dts/sun8i-a23-a33.dtsi b/arch/arm/boot/dts/sun8i-a23-a33.dtsi
>> index 7abd0ae3143d..c318c770b6c1 100644
>> --- a/arch/arm/boot/dts/sun8i-a23-a33.dtsi
>> +++ b/arch/arm/boot/dts/sun8i-a23-a33.dtsi
>> @@ -180,6 +180,15 @@
>>                         compatible = "allwinner,sun8i-a23-ahb1-gates-clk";
>>                         reg = <0x01c20060 0x8>;
>>                         clocks = <&ahb1>;
>> +                       clock-indices = <1>, <6>,
>
> Turns out the A33 (and I assume the same with the A23) has
> an ahb1 clock gate for the Security System at clock-index <5>.

Looks like the A23 does not have this one, nor the SS mod clock.

> This is found in the updated A33 user manual.
>
>> +                                       <8>, <9>, <10>,
>> +                                       <13>, <14>,
>> +                                       <19>, <20>,
>> +                                       <21>, <24>, <26>,
>> +                                       <29>, <32>, <36>,
>> +                                       <40>, <44>, <46>,
>> +                                       <52>, <54>,
>
> <53> is ahb1 clock gate for msgbox, again found in A33 manual.

A23 has this one. Found in Allwinner kernel sources.

>> +                                       <57>;
>
> <58> is ahb1 clock gate for SAT, which seems to be part of the
> display pipeline.

This one is A33 only.

I guess we should do a separate compatible for A33 AHB1 clock gates.

ChenYu

>>                         clock-output-names = "ahb1_mipidsi", "ahb1_dma",
>>                                         "ahb1_mmc0", "ahb1_mmc1", "ahb1_mmc2",
>>                                         "ahb1_nand", "ahb1_sdram",
>> @@ -196,6 +205,8 @@
>>                         compatible = "allwinner,sun8i-a23-apb1-gates-clk";
>>                         reg = <0x01c20068 0x4>;
>>                         clocks = <&apb1>;
>> +                       clock-indices = <0>, <5>,
>> +                                       <12>, <13>;
>>                         clock-output-names = "apb1_codec", "apb1_pio",
>>                                         "apb1_daudio0", "apb1_daudio1";
>>                 };
>> @@ -213,6 +224,10 @@
>>                         compatible = "allwinner,sun8i-a23-apb2-gates-clk";
>>                         reg = <0x01c2006c 0x4>;
>>                         clocks = <&apb2>;
>> +                       clock-indices = <0>, <1>,
>> +                                       <2>, <16>,
>> +                                       <17>, <18>,
>> +                                       <19>, <20>;
>>                         clock-output-names = "apb2_i2c0", "apb2_i2c1",
>>                                         "apb2_i2c2", "apb2_uart0",
>>                                         "apb2_uart1", "apb2_uart2",
>> --
>> 2.4.6
>>
>
> Not sure if you want to add the clocks I mentioned together
> in this patch, or do a separate patch.
>
> The rest look good.
>
> ChenYu


From wens at csie.org  Mon Aug 10 22:32:55 2015
From: wens at csie.org (Chen-Yu Tsai)
Date: Tue, 11 Aug 2015 13:32:55 +0800
Subject: [PATCH 1/3] crypto: sunxi-ss: Document optional reset control bindings
In-Reply-To: <1439271177-26523-1-git-send-email-wens@csie.org>
References: <1439271177-26523-1-git-send-email-wens@csie.org>
Message-ID: <1439271177-26523-2-git-send-email-wens@csie.org>

Later Allwinner SoCs split out the reset controls for individual modules
out of the clock gate controls. The "Security System" crypto engine is
no different.

Signed-off-by: Chen-Yu Tsai <wens at csie.org>
---
 Documentation/devicetree/bindings/crypto/sun4i-ss.txt | 4 ++++
 1 file changed, 4 insertions(+)

diff --git a/Documentation/devicetree/bindings/crypto/sun4i-ss.txt b/Documentation/devicetree/bindings/crypto/sun4i-ss.txt
index 1e02d177fea6..5d38e9b7033f 100644
--- a/Documentation/devicetree/bindings/crypto/sun4i-ss.txt
+++ b/Documentation/devicetree/bindings/crypto/sun4i-ss.txt
@@ -9,6 +9,10 @@ Required properties:
 	* "ahb" : AHB gating clock
 	* "mod" : SS controller clock
 
+Optional properties:
+ - resets : phandle + reset specifier pair
+ - reset-names : must contain "ahb"
+
 Example:
 	crypto: crypto-engine at 01c15000 {
 		compatible = "allwinner,sun4i-a10-crypto";
-- 
2.5.0



From wens at csie.org  Mon Aug 10 22:32:57 2015
From: wens at csie.org (Chen-Yu Tsai)
Date: Tue, 11 Aug 2015 13:32:57 +0800
Subject: [PATCH 3/3] ARM: dts: sun6i: Add security system crypto engine clock
 and device nodes
In-Reply-To: <1439271177-26523-1-git-send-email-wens@csie.org>
References: <1439271177-26523-1-git-send-email-wens@csie.org>
Message-ID: <1439271177-26523-4-git-send-email-wens@csie.org>

A31/A31s have the same "Security System" crypto engine as A10/A20,
but with a separate reset control.

Signed-off-by: Chen-Yu Tsai <wens at csie.org>
---
 arch/arm/boot/dts/sun6i-a31.dtsi | 18 ++++++++++++++++++
 1 file changed, 18 insertions(+)

diff --git a/arch/arm/boot/dts/sun6i-a31.dtsi b/arch/arm/boot/dts/sun6i-a31.dtsi
index 39953e76bbfc..7afb80f07dad 100644
--- a/arch/arm/boot/dts/sun6i-a31.dtsi
+++ b/arch/arm/boot/dts/sun6i-a31.dtsi
@@ -346,6 +346,14 @@
 					     "mmc3_sample";
 		};
 
+		ss_clk: clk at 01c2009c {
+			#clock-cells = <0>;
+			compatible = "allwinner,sun4i-a10-mod0-clk";
+			reg = <0x01c2009c 0x4>;
+			clocks = <&osc24M>, <&pll6 0>;
+			clock-output-names = "ss";
+		};
+
 		spi0_clk: clk at 01c200a0 {
 			#clock-cells = <0>;
 			compatible = "allwinner,sun4i-a10-mod0-clk";
@@ -882,6 +890,16 @@
 			#size-cells = <0>;
 		};
 
+		crypto: crypto-engine at 01c15000 {
+			compatible = "allwinner,sun4i-a10-crypto";
+			reg = <0x01c15000 0x1000>;
+			interrupts = <GIC_SPI 80 IRQ_TYPE_LEVEL_HIGH>;
+			clocks = <&ahb1_gates 5>, <&ss_clk>;
+			clock-names = "ahb", "mod";
+			resets = <&ahb1_rst 5>;
+			reset-names = "ahb";
+		};
+
 		timer at 01c60000 {
 			compatible = "allwinner,sun6i-a31-hstimer",
 				     "allwinner,sun7i-a20-hstimer";
-- 
2.5.0



From wens at csie.org  Mon Aug 10 22:32:54 2015
From: wens at csie.org (Chen-Yu Tsai)
Date: Tue, 11 Aug 2015 13:32:54 +0800
Subject: [PATCH 0/3] ARM: sun6i: Support Security System crypto engine
Message-ID: <1439271177-26523-1-git-send-email-wens@csie.org>

Hi everyone,

This series enables support for the crypto engine found in sun6i, or
Allwinner A31/A31s SoCs. The crypto engine is the same hardware as on
earlier sun4i/sun7i (A10/A20), with the only difference being the reset
control is separated out of the clock gate control.

The same hardware is also available on the A33, but not the A23. Support
for this requires additions to the clock driver, and will be submitted
separately once things are clear on how to proceed. I already have a
proof of concept working.


Patch 1 adds an optional reset control property to the sunxi-ss binding.

Patch 2 adds optional reset control support to the sunxi-ss driver.

Patch 3 enables the crypto engine on sun6i, by adding the module clock and
device node.


Regards
ChenYu


Chen-Yu Tsai (3):
  crypto: sunxi-ss: Document optional reset control bindings
  crypto: sunxi-ss: Add optional reset control support
  ARM: dts: sun6i: Add security system crypto engine clock and device
    nodes

 .../devicetree/bindings/crypto/sun4i-ss.txt        |  4 ++++
 arch/arm/boot/dts/sun6i-a31.dtsi                   | 18 ++++++++++++++++++
 drivers/crypto/sunxi-ss/sun4i-ss-core.c            | 22 ++++++++++++++++++++++
 drivers/crypto/sunxi-ss/sun4i-ss.h                 |  2 ++
 4 files changed, 46 insertions(+)

-- 
2.5.0



From wens at csie.org  Mon Aug 10 22:32:56 2015
From: wens at csie.org (Chen-Yu Tsai)
Date: Tue, 11 Aug 2015 13:32:56 +0800
Subject: [PATCH 2/3] crypto: sunxi-ss: Add optional reset control support
In-Reply-To: <1439271177-26523-1-git-send-email-wens@csie.org>
References: <1439271177-26523-1-git-send-email-wens@csie.org>
Message-ID: <1439271177-26523-3-git-send-email-wens@csie.org>

On sun6i and later platforms, the reset control is split out of the
clock gates. Add support for an optional reset control.

Signed-off-by: Chen-Yu Tsai <wens at csie.org>
---
 drivers/crypto/sunxi-ss/sun4i-ss-core.c | 22 ++++++++++++++++++++++
 drivers/crypto/sunxi-ss/sun4i-ss.h      |  2 ++
 2 files changed, 24 insertions(+)

diff --git a/drivers/crypto/sunxi-ss/sun4i-ss-core.c b/drivers/crypto/sunxi-ss/sun4i-ss-core.c
index 0b79b58c913b..eab6fe227fa0 100644
--- a/drivers/crypto/sunxi-ss/sun4i-ss-core.c
+++ b/drivers/crypto/sunxi-ss/sun4i-ss-core.c
@@ -22,6 +22,7 @@
 #include <linux/scatterlist.h>
 #include <linux/interrupt.h>
 #include <linux/delay.h>
+#include <linux/reset.h>
 
 #include "sun4i-ss.h"
 
@@ -253,6 +254,14 @@ static int sun4i_ss_probe(struct platform_device *pdev)
 	}
 	dev_dbg(&pdev->dev, "clock ahb_ss acquired\n");
 
+	ss->reset = devm_reset_control_get_optional(&pdev->dev, "ahb");
+	if (IS_ERR(ss->reset)) {
+		if (PTR_ERR(ss->reset) == -EPROBE_DEFER)
+			return PTR_ERR(ss->reset);
+		dev_info(&pdev->dev, "no reset control found\n");
+		ss->reset = NULL;
+	}
+
 	/* Enable both clocks */
 	err = clk_prepare_enable(ss->busclk);
 	if (err != 0) {
@@ -275,6 +284,15 @@ static int sun4i_ss_probe(struct platform_device *pdev)
 		goto error_clk;
 	}
 
+	/* Deassert reset if we have a reset control */
+	if (ss->reset) {
+		err = reset_control_deassert(ss->reset);
+		if (err) {
+			dev_err(&pdev->dev, "Cannot deassert reset control\n");
+			goto error_clk;
+		}
+	}
+
 	/*
 	 * The only impact on clocks below requirement are bad performance,
 	 * so do not print "errors"
@@ -352,6 +370,8 @@ error_alg:
 			break;
 		}
 	}
+	if (ss->reset)
+		reset_control_assert(ss->reset);
 error_clk:
 	clk_disable_unprepare(ss->ssclk);
 error_ssclk:
@@ -376,6 +396,8 @@ static int sun4i_ss_remove(struct platform_device *pdev)
 	}
 
 	writel(0, ss->base + SS_CTL);
+	if (ss->reset)
+		reset_control_assert(ss->reset);
 	clk_disable_unprepare(ss->busclk);
 	clk_disable_unprepare(ss->ssclk);
 	return 0;
diff --git a/drivers/crypto/sunxi-ss/sun4i-ss.h b/drivers/crypto/sunxi-ss/sun4i-ss.h
index db18b2554e6f..8e9c05f6e4d4 100644
--- a/drivers/crypto/sunxi-ss/sun4i-ss.h
+++ b/drivers/crypto/sunxi-ss/sun4i-ss.h
@@ -18,6 +18,7 @@
 #include <linux/module.h>
 #include <linux/of.h>
 #include <linux/platform_device.h>
+#include <linux/reset.h>
 #include <crypto/scatterwalk.h>
 #include <linux/scatterlist.h>
 #include <linux/interrupt.h>
@@ -129,6 +130,7 @@ struct sun4i_ss_ctx {
 	int irq;
 	struct clk *busclk;
 	struct clk *ssclk;
+	struct reset_control *reset;
 	struct device *dev;
 	struct resource *res;
 	spinlock_t slock; /* control the use of the device */
-- 
2.5.0



From javier at osg.samsung.com  Mon Aug 10 22:54:31 2015
From: javier at osg.samsung.com (Javier Martinez Canillas)
Date: Tue, 11 Aug 2015 07:54:31 +0200
Subject: [PATCH] ARM: exynos_defconfig: Enable cpufreq-dt driver
In-Reply-To: <1439259354-32055-1-git-send-email-k.kozlowski@samsung.com>
References: <1439259354-32055-1-git-send-email-k.kozlowski@samsung.com>
Message-ID: <55C98E17.9040303@osg.samsung.com>

Hello Krzysztof,

On 08/11/2015 04:15 AM, Krzysztof Kozlowski wrote:
> With the latest patches the cpufreq-dt can be used on multiple
> Exynos SoCs: 3250, 4210, 4212, 4412 and 5250.
> 
> Enable it along with default ondemand governor to conserve the energy,
> reduce temperature while maintaining acceptable performance.
> 
> Signed-off-by: Krzysztof Kozlowski <k.kozlowski at samsung.com>
> ---
>  arch/arm/configs/exynos_defconfig | 2 ++
>  1 file changed, 2 insertions(+)
> 
> diff --git a/arch/arm/configs/exynos_defconfig b/arch/arm/configs/exynos_defconfig
> index 67965cedeb69..2263cd94cb93 100644
> --- a/arch/arm/configs/exynos_defconfig
> +++ b/arch/arm/configs/exynos_defconfig
> @@ -27,6 +27,8 @@ CONFIG_ARM_APPENDED_DTB=y
>  CONFIG_ARM_ATAG_DTB_COMPAT=y
>  CONFIG_CMDLINE="root=/dev/ram0 rw ramdisk=8192 initrd=0x41000000,8M console=ttySAC1,115200 init=/linuxrc mem=256M"
>  CONFIG_CPU_FREQ=y
> +CONFIG_CPU_FREQ_DEFAULT_GOV_ONDEMAND=y
> +CONFIG_CPUFREQ_DT=y
>  CONFIG_CPU_IDLE=y
>  CONFIG_ARM_EXYNOS_CPUIDLE=y
>  CONFIG_VFP=y
> 

Reviewed-by: Javier Martinez Canillas <javier at osg.samsung.com>

Best regards,
-- 
Javier Martinez Canillas
Open Source Group
Samsung Research America


From paul.gortmaker at windriver.com  Mon Aug 10 23:05:44 2015
From: paul.gortmaker at windriver.com (Paul Gortmaker)
Date: Tue, 11 Aug 2015 02:05:44 -0400
Subject: [PATCH 5/5] drivers/tty: make serial 8250_lpc18xx.c explicitly
 non-modular
In-Reply-To: <CAGhQ9Vxjymt4z32s3x2B8b6ypgn3Bzh1ncbqxqidfPyM2k87jw@mail.gmail.com>
References: <1439081497-14986-1-git-send-email-paul.gortmaker@windriver.com>
 <1439081497-14986-6-git-send-email-paul.gortmaker@windriver.com>
 <CAGhQ9Vxjymt4z32s3x2B8b6ypgn3Bzh1ncbqxqidfPyM2k87jw@mail.gmail.com>
Message-ID: <20150811060544.GJ9751@windriver.com>

[Re: [PATCH 5/5] drivers/tty: make serial 8250_lpc18xx.c explicitly non-modular] On 10/08/2015 (Mon 20:42) Joachim Eastwood wrote:

> Hi Paul,
> 
> On 9 August 2015 at 02:51, Paul Gortmaker <paul.gortmaker at windriver.com> wrote:
> > The Kconfig currently controlling compilation of this code is:
> >
> > 8250/Kconfig:config SERIAL_8250_LPC18XX
> > 8250/Kconfig:        bool "NXP LPC18xx/43xx serial port support"
> >
> > ...meaning that it currently is not being built as a module by anyone.
> >
> > Lets remove the modular code that is essentially orphaned, so that
> > when reading the driver there is no doubt it is builtin-only.
> 
> The bool in KConfig is more or less a copy-paste mistake on my side. I
> really meant for this driver to be buildable as module and it builds
> just fine with 'm'.
> 
> Want me send a patch changing it to tristate or will you handle it?

I will do a v2 in the next day or so with collected ACKs and this patch
replaced, unless Greg jumps in and indicates he'd like something
different.

Paul.
--

> 
> 
> regards, Joachim Eastwood


From sboyd at codeaurora.org  Mon Aug 10 23:52:24 2015
From: sboyd at codeaurora.org (Stephen Boyd)
Date: Mon, 10 Aug 2015 23:52:24 -0700
Subject: [PATCH v8 11/13] clk: qcom: gdsc: Use PM clocks to control gdsc
 clocks
In-Reply-To: <1438857474-20262-12-git-send-email-rnayak@codeaurora.org>
References: <1438857474-20262-1-git-send-email-rnayak@codeaurora.org>
 <1438857474-20262-12-git-send-email-rnayak@codeaurora.org>
Message-ID: <20150811065224.GA2839@codeaurora.org>

On 08/06, Rajendra Nayak wrote:
> +
> +static int gdsc_attach(struct generic_pm_domain *domain, struct device *dev)
> +{
> +	int ret, i = 0, j = 0;
> +	struct gdsc *sc = domain_to_gdsc(domain);
> +	struct of_phandle_args clkspec;
> +	struct device_node *np = dev->of_node;
> +
> +	if (!sc->clock_count)
> +		return 0;
> +
> +	ret = pm_clk_create(dev);
> +	if (ret) {
> +		dev_dbg(dev, "pm_clk_create failed %d\n", ret);
> +		return ret;
> +	}
> +
> +	sc->clks = devm_kcalloc(dev, sc->clock_count, sizeof(sc->clks),
> +				       GFP_KERNEL);
> +	if (!sc->clks)
> +		return -ENOMEM;
> +
> +	while (!of_parse_phandle_with_args(np, "clocks", "#clock-cells", i,
> +					   &clkspec)) {
> +		if (match(clkspec.args[0], sc->clocks, sc->clock_count)) {

I'm lost. I was hoping we could just make up a clkspec on the
stack and pass it over to of_clk_get_from_provider() without
having to go through the np of the client device. The point being
to avoid forcing this code from knowing about the consumer
binding or connection name choice for each device. Instead, it
assumes that it's a #clock-cells=<1> binding and gets the clocks
by passing the 1 cell data without calling
of_parse_phandle_with_args().

Now, one downside of that approach is that it's DT centric (also
of_clk_get_from_provider() is not an exported symbol yet). So I'm
really starting to lean towards exposing __clk_create_clk() (or
some better named "provider" function) that will allow clk
providers to turn their clk_hw structure into a struct clk
pointer. That avoids the DT centric design, and avoids binding
the provider to the connection ids too.

> +			sc->clks[j] = of_clk_get_from_provider(&clkspec);
> +			pm_clk_add_clk(dev, sc->clks[j]);
> +			j++;
> +		}
> +		i++;
> +	}
> +	return 0;
> +};

-- 
Qualcomm Innovation Center, Inc. is a member of Code Aurora Forum,
a Linux Foundation Collaborative Project


From sboyd at codeaurora.org  Mon Aug 10 23:53:35 2015
From: sboyd at codeaurora.org (Stephen Boyd)
Date: Mon, 10 Aug 2015 23:53:35 -0700
Subject: [PATCH v8 10/13] arm: dts: qcom: Add #power-domain-cells property
In-Reply-To: <1438857474-20262-11-git-send-email-rnayak@codeaurora.org>
References: <1438857474-20262-1-git-send-email-rnayak@codeaurora.org>
 <1438857474-20262-11-git-send-email-rnayak@codeaurora.org>
Message-ID: <20150811065335.GB2839@codeaurora.org>

On 08/06, Rajendra Nayak wrote:
> msm8974 has gcc and mmcc nodes, and apq8084 has a gcc node which
> implement gdsc powerdomains. Add the #power-domain-cells property
> to them.
> 
> Signed-off-by: Rajendra Nayak <rnayak at codeaurora.org>
> ---

This needs to go through  Andy's tree and arm-soc. Also, I don't
see an update for the binding anywhere. Please update the binding
too.

-- 
Qualcomm Innovation Center, Inc. is a member of Code Aurora Forum,
a Linux Foundation Collaborative Project


From geert at linux-m68k.org  Mon Aug 10 23:58:15 2015
From: geert at linux-m68k.org (Geert Uytterhoeven)
Date: Tue, 11 Aug 2015 08:58:15 +0200
Subject: [PATCH v2 1/2] ARM: shmobile: r8a7794: add QSPI DT support
In-Reply-To: <1540672.y3DTbtssP8@wasted.cogentembedded.com>
References: <4187771.Fb49GBKgyg@wasted.cogentembedded.com>
 <1540672.y3DTbtssP8@wasted.cogentembedded.com>
Message-ID: <CAMuHMdVG3R3ThQWPM-tDHTcJZfFB+j3cFhdBNoH4=ZN7ENrXRg@mail.gmail.com>

On Mon, Aug 10, 2015 at 11:59 PM, Sergei Shtylyov
<sergei.shtylyov at cogentembedded.com> wrote:
> Define the generic R8A7794 part of the QSPI device node.
>
> Based on original patch by Hisashi Nakamura <hisashi.nakamura.ak at renesas.com>.
>
> Signed-off-by: Sergei Shtylyov <sergei.shtylyov at cogentembedded.com>

Acked-by: Geert Uytterhoeven <geert+renesas at glider.be>

Gr{oetje,eeting}s,

                        Geert

--
Geert Uytterhoeven -- There's lots of Linux beyond ia32 -- geert at linux-m68k.org

In personal conversations with technical people, I call myself a hacker. But
when I'm talking to journalists I just say "programmer" or something like that.
                                -- Linus Torvalds


From nsekhar at ti.com  Mon Aug 10 23:58:21 2015
From: nsekhar at ti.com (Sekhar Nori)
Date: Tue, 11 Aug 2015 12:28:21 +0530
Subject: [RESEND][PATCH 3/4] ARM: davinci: Set proper SPI prescale limit
 value
In-Reply-To: <55C9380D.1060802@ti.com>
References: <1437568344-18889-1-git-send-email-fcooper@ti.com>
 <1437568344-18889-4-git-send-email-fcooper@ti.com> <55B22681.3060000@ti.com>
 <55C9380D.1060802@ti.com>
Message-ID: <55C99D0D.9050605@ti.com>

On Tuesday 11 August 2015 05:17 AM, Franklin S Cooper Jr. wrote:
> 
> 
> On 07/24/2015 06:50 AM, Sekhar Nori wrote:
>> On Wednesday 22 July 2015 06:02 PM, Franklin S Cooper Jr wrote:
>>> SPI Davinci driver has been updated to allow SOCs to specify their minimum
>>> prescale value. Update the various SOCs board files that use this driver with
>>> their proper prescaler limit.
>>>
>>> Signed-off-by: Franklin S Cooper Jr <fcooper at ti.com>
>> Acked-by: Sekhar Nori <nsekhar at ti.com>
>>
>> in case Mark is okay to take it through his tree. It does not clash with
>> anything else I have for mach-davinci.
>>
>> Thanks,
>> Sekhar
>>
> ping. Patches 1 and 2 have already been pulled into Mark's spi tree and are currently in in linux-next.

Mark, can you apply this patch to your tree as well? Thats the preferred
route for me.

If thats not an option for you, can you confirm that the topic/davinci
branch of your spi tree is an immutable commit I can base my pull
request to ARM-SoC on?

Thanks,
Sekhar



From geert at linux-m68k.org  Mon Aug 10 23:59:08 2015
From: geert at linux-m68k.org (Geert Uytterhoeven)
Date: Tue, 11 Aug 2015 08:59:08 +0200
Subject: [PATCH v2 2/2] ARM: shmobile: silk: add QSPI DT support
In-Reply-To: <7036752.0LCvRcbC9K@wasted.cogentembedded.com>
References: <4187771.Fb49GBKgyg@wasted.cogentembedded.com>
 <7036752.0LCvRcbC9K@wasted.cogentembedded.com>
Message-ID: <CAMuHMdVVGCFheo+Eng2ET8_CJcaUrkXmubrZTDw0CyZ8_s7OHg@mail.gmail.com>

On Tue, Aug 11, 2015 at 12:00 AM, Sergei Shtylyov
<sergei.shtylyov at cogentembedded.com> wrote:
> Define the SILK board dependent part of the QSPI device node.
> Add device nodes  for Spansion  S25FL512S SPI flash and MTD partitions on it.
>
> Based on the original patch by Vladimir Barinov
> <vladimir.barinov at cogentembedded.com>.
>
> Signed-off-by: Sergei Shtylyov <sergei.shtylyov at cogentembedded.com>

Acked-by: Geert Uytterhoeven <geert+renesas at glider.be>

Gr{oetje,eeting}s,

                        Geert

--
Geert Uytterhoeven -- There's lots of Linux beyond ia32 -- geert at linux-m68k.org

In personal conversations with technical people, I call myself a hacker. But
when I'm talking to journalists I just say "programmer" or something like that.
                                -- Linus Torvalds


From sboyd at codeaurora.org  Mon Aug 10 23:59:23 2015
From: sboyd at codeaurora.org (Stephen Boyd)
Date: Mon, 10 Aug 2015 23:59:23 -0700
Subject: [PATCH v8 01/13] clk: qcom: Add support for GDSCs
In-Reply-To: <1438857474-20262-2-git-send-email-rnayak@codeaurora.org>
References: <1438857474-20262-1-git-send-email-rnayak@codeaurora.org>
 <1438857474-20262-2-git-send-email-rnayak@codeaurora.org>
Message-ID: <20150811065923.GC2839@codeaurora.org>

On 08/06, Rajendra Nayak wrote:
> From: Stephen Boyd <sboyd at codeaurora.org>
> 
> GDSCs (Global Distributed Switch Controllers) are responsible for
> safely collapsing and restoring power to peripherals in the SoC.
> These are best modelled as power domains using genpd and given
> the registers are scattered throughout the clock controller register
> space, its best to have the support added through the clock driver.
> 
> Signed-off-by: Stephen Boyd <sboyd at codeaurora.org>
> Signed-off-by: Rajendra Nayak <rnayak at codeaurora.org>
> ---

Applied to clk-next

-- 
Qualcomm Innovation Center, Inc. is a member of Code Aurora Forum,
a Linux Foundation Collaborative Project


From sboyd at codeaurora.org  Mon Aug 10 23:59:32 2015
From: sboyd at codeaurora.org (Stephen Boyd)
Date: Mon, 10 Aug 2015 23:59:32 -0700
Subject: [PATCH v8 03/13] clk: qcom: gdsc: Add support for Memory RET/OFF
In-Reply-To: <1438857474-20262-4-git-send-email-rnayak@codeaurora.org>
References: <1438857474-20262-1-git-send-email-rnayak@codeaurora.org>
 <1438857474-20262-4-git-send-email-rnayak@codeaurora.org>
Message-ID: <20150811065932.GE2839@codeaurora.org>

On 08/06, Rajendra Nayak wrote:
> Along with the GDSC power switch, there is additional control
> to either retain all memory (core and peripheral) within a given
> powerdomain or to turn them off while the GDSC is powered down.
> Add support for these by modelling a RET state where all
> memory is retained and an OFF state where all memory gets turned
> off.
> The controls provided are granular enough to be able to support
> various differnt levels of RET states, like a 'shallow RET' with all memory
> retained and a 'deep RET' with some memory retained while some others
> are lost. The current patch does not support this and considers
> just one RET state where all memory is retained. Futher work, if
> needed can support multiple different levels of RET state.
> 
> Signed-off-by: Rajendra Nayak <rnayak at codeaurora.org>
> ---

Applied to clk-next

-- 
Qualcomm Innovation Center, Inc. is a member of Code Aurora Forum,
a Linux Foundation Collaborative Project


From sboyd at codeaurora.org  Mon Aug 10 23:59:27 2015
From: sboyd at codeaurora.org (Stephen Boyd)
Date: Mon, 10 Aug 2015 23:59:27 -0700
Subject: [PATCH v8 02/13] clk: qcom: gdsc: Prepare common clk probe to
 register gdscs
In-Reply-To: <1438857474-20262-3-git-send-email-rnayak@codeaurora.org>
References: <1438857474-20262-1-git-send-email-rnayak@codeaurora.org>
 <1438857474-20262-3-git-send-email-rnayak@codeaurora.org>
Message-ID: <20150811065927.GD2839@codeaurora.org>

On 08/06, Rajendra Nayak wrote:
> The common clk probe registers a clk provider and a reset controller.
> Update it to register a genpd provider using the gdsc data provided
> by each platform.
> 
> Signed-off-by: Rajendra Nayak <rnayak at codeaurora.org>
> ---

Applied to clk-next

-- 
Qualcomm Innovation Center, Inc. is a member of Code Aurora Forum,
a Linux Foundation Collaborative Project


From sboyd at codeaurora.org  Mon Aug 10 23:59:37 2015
From: sboyd at codeaurora.org (Stephen Boyd)
Date: Mon, 10 Aug 2015 23:59:37 -0700
Subject: [PATCH v8 04/13] clk: qcom: gdsc: Add support for ON only state
In-Reply-To: <1438857474-20262-5-git-send-email-rnayak@codeaurora.org>
References: <1438857474-20262-1-git-send-email-rnayak@codeaurora.org>
 <1438857474-20262-5-git-send-email-rnayak@codeaurora.org>
Message-ID: <20150811065937.GF2839@codeaurora.org>

On 08/06, Rajendra Nayak wrote:
> Certain devices can have GDSCs' which support ON as the only state.
> They can't be power collapsed to either hit RET or OFF.
> The clients drivers for these GDSCs' however would expect the state
> of the core to be reset following a GDSC disable and re-enable.
> To do this assert/deassert reset lines every time the client
> driver would request the GDSC to be powered on/off instead.
> 
> Signed-off-by: Rajendra Nayak <rnayak at codeaurora.org>
> ---

Applied to clk-next

-- 
Qualcomm Innovation Center, Inc. is a member of Code Aurora Forum,
a Linux Foundation Collaborative Project


From sboyd at codeaurora.org  Mon Aug 10 23:59:48 2015
From: sboyd at codeaurora.org (Stephen Boyd)
Date: Mon, 10 Aug 2015 23:59:48 -0700
Subject: [PATCH v8 06/13] clk: qcom: gdsc: Add GDSCs in msm8974 GCC
In-Reply-To: <1438857474-20262-7-git-send-email-rnayak@codeaurora.org>
References: <1438857474-20262-1-git-send-email-rnayak@codeaurora.org>
 <1438857474-20262-7-git-send-email-rnayak@codeaurora.org>
Message-ID: <20150811065948.GH2839@codeaurora.org>

On 08/06, Rajendra Nayak wrote:
> From: Stephen Boyd <sboyd at codeaurora.org>
> 
> There's just one GDSC as part of the msm8974 GCC block.
> 
> Signed-off-by: Stephen Boyd <sboyd at codeaurora.org>
> Signed-off-by: Rajendra Nayak <rnayak at codeaurora.org>
> ---

Applied to clk-next

-- 
Qualcomm Innovation Center, Inc. is a member of Code Aurora Forum,
a Linux Foundation Collaborative Project


From sboyd at codeaurora.org  Mon Aug 10 23:59:59 2015
From: sboyd at codeaurora.org (Stephen Boyd)
Date: Mon, 10 Aug 2015 23:59:59 -0700
Subject: [PATCH v8 07/13] clk: qcom: gdsc: Add GDSCs in msm8974 MMCC
In-Reply-To: <1438857474-20262-8-git-send-email-rnayak@codeaurora.org>
References: <1438857474-20262-1-git-send-email-rnayak@codeaurora.org>
 <1438857474-20262-8-git-send-email-rnayak@codeaurora.org>
Message-ID: <20150811065959.GI2839@codeaurora.org>

On 08/06, Rajendra Nayak wrote:
> From: Stephen Boyd <sboyd at codeaurora.org>
> 
> Add the GDSC instances that exist as part of msm8974 MMCC block
> 
> Signed-off-by: Stephen Boyd <sboyd at codeaurora.org>
> Signed-off-by: Rajendra Nayak <rnayak at codeaurora.org>
> ---

Applied to clk-next

-- 
Qualcomm Innovation Center, Inc. is a member of Code Aurora Forum,
a Linux Foundation Collaborative Project


From sboyd at codeaurora.org  Mon Aug 10 23:59:43 2015
From: sboyd at codeaurora.org (Stephen Boyd)
Date: Mon, 10 Aug 2015 23:59:43 -0700
Subject: [PATCH v8 05/13] clk: qcom: gdsc: Add GDSCs in msm8916 GCC
In-Reply-To: <1438857474-20262-6-git-send-email-rnayak@codeaurora.org>
References: <1438857474-20262-1-git-send-email-rnayak@codeaurora.org>
 <1438857474-20262-6-git-send-email-rnayak@codeaurora.org>
Message-ID: <20150811065943.GG2839@codeaurora.org>

On 08/06, Rajendra Nayak wrote:
> Add all data for the GDSCs which are part of msm8916 GCC block.
> 
> Signed-off-by: Rajendra Nayak <rnayak at codeaurora.org>
> ---

Applied to clk-next

-- 
Qualcomm Innovation Center, Inc. is a member of Code Aurora Forum,
a Linux Foundation Collaborative Project


From sboyd at codeaurora.org  Tue Aug 11 00:01:16 2015
From: sboyd at codeaurora.org (Stephen Boyd)
Date: Tue, 11 Aug 2015 00:01:16 -0700
Subject: [PATCH v8 08/13] clk: qcom: gdsc: Add GDSCs in apq8084 GCC
In-Reply-To: <1438857474-20262-9-git-send-email-rnayak@codeaurora.org>
References: <1438857474-20262-1-git-send-email-rnayak@codeaurora.org>
 <1438857474-20262-9-git-send-email-rnayak@codeaurora.org>
Message-ID: <20150811070116.GJ2839@codeaurora.org>

On 08/06, Rajendra Nayak wrote:
> Add the GDSC instances that exist as part of apq8084 GCC block
> 
> Signed-off-by: Rajendra Nayak <rnayak at codeaurora.org>
> ---

Applied to clk-next

-- 
Qualcomm Innovation Center, Inc. is a member of Code Aurora Forum,
a Linux Foundation Collaborative Project


From sboyd at codeaurora.org  Tue Aug 11 00:02:40 2015
From: sboyd at codeaurora.org (Stephen Boyd)
Date: Tue, 11 Aug 2015 00:02:40 -0700
Subject: [PATCH v8 09/13] clk: qcom: gdsc: Add GDSCs in apq8084 MMCC
In-Reply-To: <1438857474-20262-10-git-send-email-rnayak@codeaurora.org>
References: <1438857474-20262-1-git-send-email-rnayak@codeaurora.org>
 <1438857474-20262-10-git-send-email-rnayak@codeaurora.org>
Message-ID: <20150811070240.GK2839@codeaurora.org>

On 08/06, Rajendra Nayak wrote:
> From: Stephane Viau <sviau at codeaurora.org>
> 
> Add the GDSC instances that exist as part of apq8084 MMCC block.
> 
> Signed-off-by: Stephane Viau <sviau at codeaurora.org>
> Signed-off-by: Rajendra Nayak <rnayak at codeaurora.org>
> ---

Applied to clk-next

-- 
Qualcomm Innovation Center, Inc. is a member of Code Aurora Forum,
a Linux Foundation Collaborative Project


From alexander.stein at systec-electronic.com  Tue Aug 11 00:18:22 2015
From: alexander.stein at systec-electronic.com (Alexander Stein)
Date: Tue, 11 Aug 2015 09:18:22 +0200
Subject: [PATCH 1/1] ARM: imx35: Do not call mxc_timer_init twice when booting
 with DT
Message-ID: <1439277502-16917-1-git-send-email-alexander.stein@systec-electronic.com>

mxc_timer_init must not be called from within mx35_clocks_init_dt. It will
eventually be called by imx31_timer_init_dt
(drivers/clocksources/timer-imx-gpt.c).
This arranges the initialization code similar to clk-imx27.c

Signed-off-by: Alexander Stein <alexander.stein at systec-electronic.com>
---
 drivers/clk/imx/clk-imx35.c | 49 +++++++++++++++++++++++++--------------------
 1 file changed, 27 insertions(+), 22 deletions(-)

diff --git a/drivers/clk/imx/clk-imx35.c b/drivers/clk/imx/clk-imx35.c
index 69138ba..3e7c805 100644
--- a/drivers/clk/imx/clk-imx35.c
+++ b/drivers/clk/imx/clk-imx35.c
@@ -84,7 +84,7 @@ enum mx35_clks {
 
 static struct clk *clk[clk_max];
 
-int __init mx35_clocks_init(void)
+static void __init _mx35_clocks_init(void)
 {
 	void __iomem *base;
 	u32 pdr0, consumer_sel, hsp_sel;
@@ -219,6 +219,30 @@ int __init mx35_clocks_init(void)
 
 	imx_check_clocks(clk, ARRAY_SIZE(clk));
 
+	clk_prepare_enable(clk[spba_gate]);
+	clk_prepare_enable(clk[gpio1_gate]);
+	clk_prepare_enable(clk[gpio2_gate]);
+	clk_prepare_enable(clk[gpio3_gate]);
+	clk_prepare_enable(clk[iim_gate]);
+	clk_prepare_enable(clk[emi_gate]);
+	clk_prepare_enable(clk[max_gate]);
+	clk_prepare_enable(clk[iomuxc_gate]);
+
+	/*
+	 * SCC is needed to boot via mmc after a watchdog reset. The clock code
+	 * before conversion to common clk also enabled UART1 (which isn't
+	 * handled here and not needed for mmc) and IIM (which is enabled
+	 * unconditionally above).
+	 */
+	clk_prepare_enable(clk[scc_gate]);
+
+	imx_print_silicon_rev("i.MX35", mx35_revision());
+}
+
+int __init mx35_clocks_init(void)
+{
+	_mx35_clocks_init();
+
 	clk_register_clkdev(clk[pata_gate], NULL, "pata_imx");
 	clk_register_clkdev(clk[can1_gate], NULL, "flexcan.0");
 	clk_register_clkdev(clk[can2_gate], NULL, "flexcan.1");
@@ -275,25 +299,6 @@ int __init mx35_clocks_init(void)
 	clk_register_clkdev(clk[csi_gate], NULL, "mx3-camera.0");
 	clk_register_clkdev(clk[admux_gate], "audmux", NULL);
 
-	clk_prepare_enable(clk[spba_gate]);
-	clk_prepare_enable(clk[gpio1_gate]);
-	clk_prepare_enable(clk[gpio2_gate]);
-	clk_prepare_enable(clk[gpio3_gate]);
-	clk_prepare_enable(clk[iim_gate]);
-	clk_prepare_enable(clk[emi_gate]);
-	clk_prepare_enable(clk[max_gate]);
-	clk_prepare_enable(clk[iomuxc_gate]);
-
-	/*
-	 * SCC is needed to boot via mmc after a watchdog reset. The clock code
-	 * before conversion to common clk also enabled UART1 (which isn't
-	 * handled here and not needed for mmc) and IIM (which is enabled
-	 * unconditionally above).
-	 */
-	clk_prepare_enable(clk[scc_gate]);
-
-	imx_print_silicon_rev("i.MX35", mx35_revision());
-
 	mxc_timer_init(MX35_GPT1_BASE_ADDR, MX35_INT_GPT, GPT_TYPE_IMX31);
 
 	return 0;
@@ -301,10 +306,10 @@ int __init mx35_clocks_init(void)
 
 static void __init mx35_clocks_init_dt(struct device_node *ccm_node)
 {
+	_mx35_clocks_init();
+
 	clk_data.clks = clk;
 	clk_data.clk_num = ARRAY_SIZE(clk);
 	of_clk_add_provider(ccm_node, of_clk_src_onecell_get, &clk_data);
-
-	mx35_clocks_init();
 }
 CLK_OF_DECLARE(imx35, "fsl,imx35-ccm", mx35_clocks_init_dt);
-- 
2.4.6



From hanjun.guo at linaro.org  Tue Aug 11 00:19:37 2015
From: hanjun.guo at linaro.org (Hanjun Guo)
Date: Tue, 11 Aug 2015 15:19:37 +0800
Subject: [PATCH v4 06/10] irqchip / GICv3: Add ACPI support for GICv3+
 initialization
In-Reply-To: <55C38E59.9090802@arm.com>
References: <1438164539-29256-1-git-send-email-hanjun.guo@linaro.org>
 <1438164539-29256-7-git-send-email-hanjun.guo@linaro.org>
 <55C0BB5E.2080706@arm.com> <55C21709.3070907@linaro.org>
 <55C38E59.9090802@arm.com>
Message-ID: <55C9A209.9060306@linaro.org>

Hi Marc,

On 08/07/2015 12:42 AM, Marc Zyngier wrote:
> On 05/08/15 15:00, Hanjun Guo wrote:
>> On 08/04/2015 09:17 PM, Marc Zyngier wrote:
>>> On 29/07/15 11:08, Hanjun Guo wrote:
>>>> From: Tomasz Nowicki <tomasz.nowicki at linaro.org>
>>>>
>>>> With the refator of gic_of_init(), GICv3/4 can be initialized
>>>> by gic_init_bases() with gic distributor base address and gic
>>>> redistributor region(s).
>>>>
>>>> So get the redistributor region base addresses from MADT GIC
>>>> redistributor subtable, and the distributor base address from
>>>> GICD subtable to init GICv3 irqchip in ACPI way.
>>>>
>>>> Note: GIC redistributor base address may also be provided in
>>>> GICC structures on systems supporting GICv3 and above if the GIC
>>>> Redistributors are not in the always-on power domain, this
>>>> patch didn't implement such feature yet.
>>>>
>>>> Signed-off-by: Tomasz Nowicki <tomasz.nowicki at linaro.org>
>>>> [hj: Rework this patch and fix multi issues]
>>>> Signed-off-by: Hanjun Guo <hanjun.guo at linaro.org>
>>>> ---
>>>>    drivers/irqchip/irq-gic-v3.c | 174 +++++++++++++++++++++++++++++++++++++++++--
>>>>    1 file changed, 169 insertions(+), 5 deletions(-)
>>>>
>>>> diff --git a/drivers/irqchip/irq-gic-v3.c b/drivers/irqchip/irq-gic-v3.c
>>>> index c0b96c6..ebc5604 100644
>>>> --- a/drivers/irqchip/irq-gic-v3.c
>>>> +++ b/drivers/irqchip/irq-gic-v3.c
>>>> @@ -15,6 +15,7 @@
>>>>     * along with this program.  If not, see <http://www.gnu.org/licenses/>.
>>>>     */
>>>>
>>>> +#include <linux/acpi.h>
>>>>    #include <linux/cpu.h>
>>>>    #include <linux/cpu_pm.h>
>>>>    #include <linux/delay.h>
>>>> @@ -25,6 +26,7 @@
>>>>    #include <linux/percpu.h>
>>>>    #include <linux/slab.h>
>>>>
>>>> +#include <linux/irqchip/arm-gic-acpi.h>
>>>>    #include <linux/irqchip/arm-gic-v3.h>
>>>>
>>>>    #include <asm/cputype.h>
>>>> @@ -802,7 +804,8 @@ static int __init gic_init_bases(void __iomem *dist_base,
>>>>       set_handle_irq(gic_handle_irq);
>>>>
>>>>       if (IS_ENABLED(CONFIG_ARM_GIC_V3_ITS) && gic_dist_supports_lpis())
>>>> -            its_init(domain_token, &gic_data.rdists, gic_data.domain);
>>>> +            its_init(irq_domain_token_to_of_node(domain_token),
>>>> +                     &gic_data.rdists, gic_data.domain);
>>>
>>> This doesn't make much sense. The first parameter to its_init is indeed
>>> supposed to be an of_node, but what is the point of calling its_init if
>>> you *know* you don't have the necessary topological information to parse
>>> the firmware tables?
>>>
>>> I don't see *any* code that is going to parse the ITS table in this
>>> series, so please don't call its_init passing a NULL pointer to it. This
>>> is just gross.
>>
>> OK, the ITS ACPI code is in later patch which combined with IORT. How
>> about moving it to the GIC of init code temporary?
>
> Just don't call its_init if irq_domain_token_to_of_node(domain_token) is
> NULL. But don't call it with a NULL parameter.

OK.

[...]

>>>> +}
>>>> +IRQCHIP_ACPI_DECLARE(gic_v3, ACPI_MADT_GIC_VERSION_V3, gic_acpi_init);
>>>> +IRQCHIP_ACPI_DECLARE(gic_v4, ACPI_MADT_GIC_VERSION_V4, gic_acpi_init);
>>>
>>> As mentioned before, this doesn't work.
>>
>> hmm, I think we need more discussion for this one, but we need to match
>> V4 for GICv3 drivers, and everything will be the same in the dirver
>> as I said before.
>
> And as I said before, you don't need to distinguish v3 from v4 in the
> ACPI code. Matching GICv3 is enough.

OK, how about the following code when parsing the GIC version?

/*
  * GICv3 driver can find out it's V3 or V4 itself, just set the
  * gic_version to V3 to match the driver if firmware presented V4.
  */
if (gic_version == ACPI_MADT_GIC_VERSION_V4)
         gic_version = ACPI_MADT_GIC_VERSION_V3;

Thanks
Hanjun




From djkurtz at chromium.org  Tue Aug 11 00:38:55 2015
From: djkurtz at chromium.org (Daniel Kurtz)
Date: Tue, 11 Aug 2015 15:38:55 +0800
Subject: [PATCH v2 2/2] watchdog: add wdt shutdown callback to disable wdt
 if enabled
In-Reply-To: <55C97D2C.6090505@roeck-us.net>
References: <1437630551-39650-1-git-send-email-eddie.huang@mediatek.com>
 <1437630551-39650-3-git-send-email-eddie.huang@mediatek.com>
 <1488521.5eJqASov2O@ubix>
 <CAGS+omD1UYSTfJ4-vZSE_BYuvGcTvpbC7T4ukaV10xuQxkCChg@mail.gmail.com>
 <55C97D2C.6090505@roeck-us.net>
Message-ID: <CAGS+omASBsbMJT0CM5O3SsxTzu52uSW=7jhP9i2m3QWYeu8A3A@mail.gmail.com>

On Tue, Aug 11, 2015 at 12:42 PM, Guenter Roeck <linux at roeck-us.net> wrote:
> On 08/10/2015 09:28 PM, Daniel Kurtz wrote:
>>
>> Hi Guenter, Matthias,
>>
>> On Fri, Jul 24, 2015 at 1:37 AM, Matthias Brugger
>> <matthias.bgg at gmail.com> wrote:
>>>
>>> On Thursday, July 23, 2015 01:49:11 PM Eddie Huang wrote:
>>>>
>>>> From: Greta Zhang <greta.zhang at mediatek.com>
>>>>
>>>> Without .shutdown(), watchdog might reset the system during power off.
>>>> For example, if watchdog's timeout is set to 30s, then it is reset to
>>>> zero by mtk_wdt_ping(). During power off, no app will ping watchdog,
>>>> but watchdog is still running and may trigger reset.
>>>>
>>>> Signed-off-by: Greta Zhang <greta.zhang at mediatek.com>
>>>> Signed-off-by: Eddie Huang <eddie.huang at mediatek.com>
>>>> ---
>>>>   drivers/watchdog/mtk_wdt.c | 9 +++++++++
>>>>   1 file changed, 9 insertions(+)
>>>
>>>
>>> Acked-by: Matthias Brugger <matthias.bgg at gmail.com>
>>
>>
>> is the plan to land these two patches via Guenter's watchdog tree [0]?
>> [0] git://www.linux-watchdog.org/linux-watchdog.git
>>
> That is Wim's tree, and Wim is the maintainer ;-).

No wonder!  Thanks for cluing me in.

> I have the patches queued in my tree [1], and I plan to send a pull request
> to Wim this week or early next week.

Great!

Thanks,
-Dan

> Guenter
>
> ---
> [1]
> https://git.kernel.org/cgit/linux/kernel/git/groeck/linux-staging.git/log/?h=watchdog-next
>


From gabriele.paoloni at huawei.com  Tue Aug 11 00:39:16 2015
From: gabriele.paoloni at huawei.com (Gabriele Paoloni)
Date: Tue, 11 Aug 2015 07:39:16 +0000
Subject: [PATCH v6 0/6] PCI: hisi: Add PCIe host support for HiSilicon
 SoC Hip05
In-Reply-To: <55C449AF.3030303@hisilicon.com>
References: <1438848559-232109-1-git-send-email-wangzhou1@hisilicon.com>
 <55C449AF.3030303@hisilicon.com>
Message-ID: <EE11001F9E5DDD47B7634E2F8A612F2E01D79B34@lhreml503-mbs>

Hi Bjorn and all

Any comment on this patchset?

Thanks

Gab

> -----Original Message-----
> From: Wangzhou (B)
> Sent: Friday, August 07, 2015 7:01 AM
> To: Wangzhou (B)
> Cc: Bjorn Helgaas; Jingoo Han; Pratyush Anand; Arnd Bergmann;
> linux at arm.linux.org.uk; thomas.petazzoni at free-electrons.com; Gabriele
> Paoloni; lorenzo.pieralisi at arm.com; James Morse; Liviu.Dudau at arm.com;
> Jason Cooper; robh at kernel.org; linux-pci at vger.kernel.org; linux-arm-
> kernel at lists.infradead.org; devicetree at vger.kernel.org; Yuanzhichang;
> Zhudacai; zhangjukuo; qiuzhenfa; liudongdong (C); qiujiang;
> Kangfenglong; xuwei (O); Liguozhu (Kenneth)
> Subject: Re: [PATCH v6 0/6] PCI: hisi: Add PCIe host support for
> HiSilicon SoC Hip05
> 
> [+cc jingoohan1 at gmail.com]
> 
> On 2015/8/6 16:09, Zhou Wang wrote:
> > This patchset adds PCIe host support for HiSilicon SoC Hip05. The
> PCIe hosts
> > use PCIe IP core from Synopsys, So this driver is base on designware
> PCIe driver.
> >
> > Hip05 is an ARMv8 architecture SoC. It should be able to use ARM64
> PCIe API in
> > designeware PCIe driver. So this patch also adds ARM64 support for
> designware
> > pcie.
> >
> > This patchset is based on v4.2-rc1.
> >
> > Change from v5:
> > - Merge 1/6 in this series, discussion about this can be found in [1]
> >
> > Change from v4:
> > - Change the author of 1/5 to Gabriele.
> > - Modify problems in 3/5 pointed by Bjorn.
> > - Modify spelling problems in 4/5.
> >
> > Change from v3:
> > - Change 1/5 to what Gabriele suggested.
> > - Use win->__res.start to get *_mod_base in 2/5, this fix a bug in v3
> series.
> >
> > Change from v2:
> > - Move struct pci_dev *dev and struct pci_sys_data *sys in
> >   pcibios_align_resource in 1/5.
> > - Add Gabriele's codes in 2/5 which delete unnecessary information
> parse and
> >   use of_pci_get_host_bridge_resources for both ARM32 and ARM64.
> > - Add maintainer patch 5/5.
> >
> > Change from RFC v1:
> > - Add 1/4 patch by Arnd which removes align_resource callback in ARM
> >   pcibios_align_resource.
> > - Change head file in pcie-designware from asm/hardirq.h to
> linux/hardirq.h.
> > - Set pp->root_bus_nr = 0 in dra7xx, exynos, imx6, keystone,
> layerscape,
> >   spear13xx.
> > - Remove unnecessary parentheses of some macros in pcie-hisi.
> > - Use macro to replace some magic values.
> > - Merge two loops together and add some comments about it in
> context_config
> >   function in pcie-hisi.
> > - Modify some value of items in pcie node example in binding document.
> >
> > Change from RFC:
> > - delete dw_pcie_setup, dw_pcie_scan_bus, dw_pcie_map_irq and struct
> hw_pci,
> >   merge related operations into dw_pcie_host_init.
> >
> > Link of v5:
> > - http://www.spinics.net/lists/devicetree/msg87959.html
> > Link of v4:
> > - http://www.spinics.net/lists/arm-kernel/msg433050.html
> > Link of v3:
> > - http://www.spinics.net/lists/linux-pci/msg42539.html
> > Link of v2:
> > - http://www.spinics.net/lists/linux-pci/msg41844.html
> > Link of RFC v1:
> > - http://www.spinics.net/lists/linux-pci/msg41305.html
> > Link of RFC:
> > - http://www.spinics.net/lists/linux-pci/msg40434.html
> >
> > [1] http://lists.infradead.org/pipermail/linux-arm-kernel/2015-
> July/359741.html
> >
> > Zhou Wang (4):
> >   PCI: designware: Add ARM64 support
> >   PCI: hisi: Add PCIe host support for HiSilicon SoC Hip05
> >   Documentation: DT: Add HiSilicon PCIe host binding
> >   MAINTAINERS: Add pcie-hisi maintainer
> >
> > gabriele paoloni (2):
> >   PCI: designware: move calculation of bus addresses to DRA7xx
> >   ARM/PCI: remove align_resource in pci_sys_data
> >
> >  .../devicetree/bindings/pci/hisilicon-pcie.txt     |  46 ++++
> >  MAINTAINERS                                        |   7 +
> >  arch/arm/include/asm/mach/pci.h                    |   5 -
> >  arch/arm/kernel/bios32.c                           |  12 +-
> >  drivers/pci/host/Kconfig                           |   8 +
> >  drivers/pci/host/Makefile                          |   1 +
> >  drivers/pci/host/pci-dra7xx.c                      |  14 ++
> >  drivers/pci/host/pci-exynos.c                      |   2 +-
> >  drivers/pci/host/pci-imx6.c                        |   2 +-
> >  drivers/pci/host/pci-keystone-dw.c                 |   2 +-
> >  drivers/pci/host/pci-keystone.c                    |   2 +-
> >  drivers/pci/host/pci-layerscape.c                  |   2 +-
> >  drivers/pci/host/pcie-designware.c                 | 236 ++++++-----
> --------
> >  drivers/pci/host/pcie-designware.h                 |  14 +-
> >  drivers/pci/host/pcie-hisi.c                       | 254
> +++++++++++++++++++++
> >  drivers/pci/host/pcie-spear13xx.c                  |   2 +-
> >  16 files changed, 425 insertions(+), 184 deletions(-)
> >  create mode 100644 Documentation/devicetree/bindings/pci/hisilicon-
> pcie.txt
> >  create mode 100644 drivers/pci/host/pcie-hisi.c
> >
> 



From christoffer.dall at linaro.org  Tue Aug 11 00:42:37 2015
From: christoffer.dall at linaro.org (Christoffer Dall)
Date: Tue, 11 Aug 2015 00:42:37 -0700
Subject: [PATCH v4 06/11] KVM: arm/arm64: vgic: Allow dynamic mapping of
 physical/virtual interrupts
In-Reply-To: <1438962347-17541-7-git-send-email-marc.zyngier@arm.com>
References: <1438962347-17541-1-git-send-email-marc.zyngier@arm.com>
 <1438962347-17541-7-git-send-email-marc.zyngier@arm.com>
Message-ID: <20150811074221.GC5007@lvm>

On Fri, Aug 07, 2015 at 04:45:42PM +0100, Marc Zyngier wrote:
> In order to be able to feed physical interrupts to a guest, we need
> to be able to establish the virtual-physical mapping between the two
> worlds.
> 
> The mappings are kept in a set of RCU lists, indexed by virtual interrupts.
> 
> Signed-off-by: Marc Zyngier <marc.zyngier at arm.com>

Thanks for addressing all my concerns:

Reviewed-by: Christoffer Dall <christoffer.dall at linaro.org>


From christoffer.dall at linaro.org  Tue Aug 11 00:44:40 2015
From: christoffer.dall at linaro.org (Christoffer Dall)
Date: Tue, 11 Aug 2015 00:44:40 -0700
Subject: [PATCH v4 09/11] KVM: arm/arm64: vgic: Prevent userspace
 injection of a mapped interrupt
In-Reply-To: <1438962347-17541-10-git-send-email-marc.zyngier@arm.com>
References: <1438962347-17541-1-git-send-email-marc.zyngier@arm.com>
 <1438962347-17541-10-git-send-email-marc.zyngier@arm.com>
Message-ID: <20150811074440.GD5007@lvm>

On Fri, Aug 07, 2015 at 04:45:45PM +0100, Marc Zyngier wrote:
> Virtual interrupts mapped to a HW interrupt should only be triggered
> from inside the kernel. Otherwise, you could end up confusing the
> kernel (and the GIC's) state machine.
> 
> Rearrange the injection path so that kvm_vgic_inject_irq is
> used for non-mapped interrupts, and kvm_vgic_inject_mapped_irq is
> used for mapped interrupts. The latter should only be called from
> inside the kernel (timer, irqfd).
> 
> Signed-off-by: Marc Zyngier <marc.zyngier at arm.com>

Reviewed-by: Christoffer Dall <christoffer.dall at linaro.org>


From djkurtz at chromium.org  Tue Aug 11 00:45:21 2015
From: djkurtz at chromium.org (Daniel Kurtz)
Date: Tue, 11 Aug 2015 15:45:21 +0800
Subject: [PATCH] pinctrl: mediatek: Fix multiple registeration issue.
In-Reply-To: <1439268571-10895-1-git-send-email-hongzhou.yang@mediatek.com>
References: <1439268571-10895-1-git-send-email-hongzhou.yang@mediatek.com>
Message-ID: <CAGS+omAE2AXpwnYtvetcjvP_6jUbE2HDuPfKfy=aLook2M-8LQ@mail.gmail.com>

On Tue, Aug 11, 2015 at 12:49 PM, Hongzhou Yang
<hongzhou.yang at mediatek.com> wrote:
> Use dynamic allocation to fix multiple registeration issue.

s/registeration/registration   - here and in the patch subject.

>
> --------------8<--------------------

I don't think this is required.

> Since our common driver need support main chip and PMU
> at the same time, that means it will register two
> pinctrl device, and the pinctrl_desc structure should
> be used two times.
>
> But pinctrl_desc use global static definition, then
> the latest registered pinctrl device will overwrite
> the old one's, all members in pinctrl_desc will set to
> the new one's, such as name, pins and pins numbers, etc.
> This is a bug. Changing to use devm_kzalloc to fix it.
>
> Cc: stable at vger.kernel.org # v4.1+
> Signed-off-by: Hongzhou Yang <hongzhou.yang at mediatek.com>
> ---
>  drivers/pinctrl/mediatek/pinctrl-mtk-common.c |   27 +++++++++++++++----------
>  1 file changed, 16 insertions(+), 11 deletions(-)
>
> diff --git a/drivers/pinctrl/mediatek/pinctrl-mtk-common.c b/drivers/pinctrl/mediatek/pinctrl-mtk-common.c
> index ad1ea16..2bba504 100644
> --- a/drivers/pinctrl/mediatek/pinctrl-mtk-common.c
> +++ b/drivers/pinctrl/mediatek/pinctrl-mtk-common.c
> @@ -1202,17 +1202,12 @@ static int mtk_pctrl_build_state(struct platform_device *pdev)
>         return 0;
>  }
>
> -static struct pinctrl_desc mtk_pctrl_desc = {
> -       .confops        = &mtk_pconf_ops,
> -       .pctlops        = &mtk_pctrl_ops,
> -       .pmxops         = &mtk_pmx_ops,
> -};
> -
>  int mtk_pctrl_init(struct platform_device *pdev,
>                 const struct mtk_pinctrl_devdata *data,
>                 struct regmap *regmap)
>  {
>         struct pinctrl_pin_desc *pins;
> +       struct pinctrl_desc *mtk_pctrl_desc;
>         struct mtk_pinctrl *pctl;
>         struct device_node *np = pdev->dev.of_node, *node;
>         struct property *prop;
> @@ -1265,12 +1260,22 @@ int mtk_pctrl_init(struct platform_device *pdev,
>
>         for (i = 0; i < pctl->devdata->npins; i++)
>                 pins[i] = pctl->devdata->pins[i].pin;
> -       mtk_pctrl_desc.name = dev_name(&pdev->dev);
> -       mtk_pctrl_desc.owner = THIS_MODULE;
> -       mtk_pctrl_desc.pins = pins;
> -       mtk_pctrl_desc.npins = pctl->devdata->npins;
> +
> +       mtk_pctrl_desc = devm_kzalloc(&pdev->dev, sizeof(*mtk_pctrl_desc),
> +                               GFP_KERNEL);
> +       if (!mtk_pctrl_desc)
> +               return -ENOMEM;

Just embed a struct pinctrl_desc in your struct mtk_pinctrl.

Best Regards,
-Dan

> +
> +       mtk_pctrl_desc->name = dev_name(&pdev->dev);
> +       mtk_pctrl_desc->owner = THIS_MODULE;
> +       mtk_pctrl_desc->pins = pins;
> +       mtk_pctrl_desc->npins = pctl->devdata->npins;
> +       mtk_pctrl_desc->confops = &mtk_pconf_ops;
> +       mtk_pctrl_desc->pctlops = &mtk_pctrl_ops;
> +       mtk_pctrl_desc->pmxops = &mtk_pmx_ops;
>         pctl->dev = &pdev->dev;
> -       pctl->pctl_dev = pinctrl_register(&mtk_pctrl_desc, &pdev->dev, pctl);
> +
> +       pctl->pctl_dev = pinctrl_register(mtk_pctrl_desc, &pdev->dev, pctl);
>         if (IS_ERR(pctl->pctl_dev)) {
>                 dev_err(&pdev->dev, "couldn't register pinctrl driver\n");
>                 return PTR_ERR(pctl->pctl_dev);
> --
> 1.7.9.5
>
>
> _______________________________________________
> Linux-mediatek mailing list
> Linux-mediatek at lists.infradead.org
> http://lists.infradead.org/mailman/listinfo/linux-mediatek


From djkurtz at chromium.org  Tue Aug 11 00:50:47 2015
From: djkurtz at chromium.org (Daniel Kurtz)
Date: Tue, 11 Aug 2015 15:50:47 +0800
Subject: [PATCH] pinctrl: mediatek: Implement pictrl irq wake handler
In-Reply-To: <1439257910.38706.1.camel@mussux00.eus.mediatek.inc>
References: <1438162601-448-1-git-send-email-maoguang.meng@mediatek.com>
 <CACRpkdZ1RjjSh5J=K724CpbXDXwdHJSdXOTLS8fSOO-34zn=9A@mail.gmail.com>
 <1439257910.38706.1.camel@mussux00.eus.mediatek.inc>
Message-ID: <CAGS+omA+yhcSSMPq_Pvc+v9UjwLz8wJNKr9ezcuxnYHAUwNXfQ@mail.gmail.com>

On Tue, Aug 11, 2015 at 9:51 AM, Hongzhou Yang
<hongzhou.yang at mediatek.com> wrote:
> On Mon, 2015-08-10 at 14:43 +0200, Linus Walleij wrote:
>> On Wed, Jul 29, 2015 at 11:36 AM,  <maoguang.meng at mediatek.com> wrote:
>>
>> > From: Maoguang Meng <maoguang.meng at mediatek.com>
>> >
>> > This patch implement irq_set_wake for suspend resume.
>> >
>> > Signed-off-by: Maoguang Meng <maoguang.meng at mediatek.com>
>>
>> Hongzhou/Yingjoe: are you OK with this patch? Can I have your ACKs?
>>
>> Yours,
>> Linus Walleij
>
> Hi Linus,
>
> Yes, you can. Thank you.
>
> Acked-by: Hongzhou Yang <hongzhou.yang at mediatek.com>

NAK.

maoguang removes almost all of this patch in what I think is v2 of
this same patch:
https://patchwork.kernel.org/patch/6967441/

maoguang, please squash the two version of this patch together, and
upload a separate, correct patch.

-Dan

>
> Hongzhou
>
> --
> To unsubscribe from this list: send the line "unsubscribe linux-kernel" in
> the body of a message to majordomo at vger.kernel.org
> More majordomo info at  http://vger.kernel.org/majordomo-info.html
> Please read the FAQ at  http://www.tux.org/lkml/


From kgene at kernel.org  Tue Aug 11 00:51:10 2015
From: kgene at kernel.org (Kukjin Kim)
Date: Tue, 11 Aug 2015 16:51:10 +0900
Subject: [PATCH v4 0/6] cpufreq: use generic cpufreq drivers for Exynos4x12
 platform
In-Reply-To: <55C95BD6.7010200@samsung.com>
References: <1438868514-8814-1-git-send-email-b.zolnierkie@samsung.com>
 <2359635.Hxe4cb8zKm@amdc1976> <20150807115627.GH6939@linux>
 <1525406.7aXvVQzEDd@vostro.rjw.lan> <20150808020740.GM6939@linux>
 <55C5AF4E.3010500@samsung.com> <03ee01d0d30b$b279c490$176d4db0$@kernel.org>
 <55C95BD6.7010200@samsung.com>
Message-ID: <057401d0d40a$7cd241a0$7676c4e0$@kernel.org>

Krzysztof Kozlowski wrote:
> 
> On 10.08.2015 10:27, Kukjin Kim wrote:
> > Krzysztof Kozlowski wrote:
> >>
> >> W dniu 08.08.2015 o 11:07, Viresh Kumar pisze:
> >>> On 08-08-15, 00:24, Rafael J. Wysocki wrote:
> >>>> OK, so please let me know which patches you want me to pick up.
> >>>>
> >>>> Ideally, I'd prefer them to be resent in a separate series with ACKs and all
> >>>> with a cover letter clearly stating whose tree they are being targeted at.
> >>>
> >>> He already sent it separately, let me send a confirmatory mail in
> >>> reply to that.
> >>
> >> Dear Kukjin,
> >>
> >> Can you apply the 2-5 of this series to v4.3? It's getting late but
> >> maybe they still could go?
> >>
> > Once my previous pull-request landed into arm-soc, I'll try to send out this
> > series 2-5 for v4.3.
> 
> Additionally (better late than never):

Sure ;-)

> Patches 2-5 tested on Trats2 board (Exynos4412)
> 
> Tested-by: Krzysztof Kozlowski <k.kozlowski at samsung.com>
> 
Applied with Krzysztof's 'Tested-by'.

Thanks,
Kukjin



From kgene at kernel.org  Tue Aug 11 00:51:36 2015
From: kgene at kernel.org (Kukjin Kim)
Date: Tue, 11 Aug 2015 16:51:36 +0900
Subject: [PATCH] ARM: exynos_defconfig: Enable cpufreq-dt driver
In-Reply-To: <55C98E17.9040303@osg.samsung.com>
References: <1439259354-32055-1-git-send-email-k.kozlowski@samsung.com>
 <55C98E17.9040303@osg.samsung.com>
Message-ID: <057e01d0d40a$8c3a3210$a4ae9630$@kernel.org>

Javier Martinez Canillas wrote:
> 
> Hello Krzysztof,
> 
> On 08/11/2015 04:15 AM, Krzysztof Kozlowski wrote:
> > With the latest patches the cpufreq-dt can be used on multiple
> > Exynos SoCs: 3250, 4210, 4212, 4412 and 5250.
> >
> > Enable it along with default ondemand governor to conserve the energy,
> > reduce temperature while maintaining acceptable performance.
> >
> > Signed-off-by: Krzysztof Kozlowski <k.kozlowski at samsung.com>
> > ---
> >  arch/arm/configs/exynos_defconfig | 2 ++
> >  1 file changed, 2 insertions(+)
> >
> > diff --git a/arch/arm/configs/exynos_defconfig b/arch/arm/configs/exynos_defconfig
> > index 67965cedeb69..2263cd94cb93 100644
> > --- a/arch/arm/configs/exynos_defconfig
> > +++ b/arch/arm/configs/exynos_defconfig
> > @@ -27,6 +27,8 @@ CONFIG_ARM_APPENDED_DTB=y
> >  CONFIG_ARM_ATAG_DTB_COMPAT=y
> >  CONFIG_CMDLINE="root=/dev/ram0 rw ramdisk=8192 initrd=0x41000000,8M console=ttySAC1,115200
> init=/linuxrc mem=256M"
> >  CONFIG_CPU_FREQ=y
> > +CONFIG_CPU_FREQ_DEFAULT_GOV_ONDEMAND=y
> > +CONFIG_CPUFREQ_DT=y
> >  CONFIG_CPU_IDLE=y
> >  CONFIG_ARM_EXYNOS_CPUIDLE=y
> >  CONFIG_VFP=y
> >
> 
> Reviewed-by: Javier Martinez Canillas <javier at osg.samsung.com>
> 
Thanks, applied.

- Kukjin



From viresh.kumar at linaro.org  Tue Aug 11 01:00:23 2015
From: viresh.kumar at linaro.org (Viresh Kumar)
Date: Tue, 11 Aug 2015 13:30:23 +0530
Subject: [PATCH v4 2/2] dt: power: st: Provide bindings for ST's OPPs
In-Reply-To: <20150810132247.GH3249@x1>
References: <1438010430-5802-2-git-send-email-lee.jones@linaro.org>
 <20150728022936.GB1229@linux>
 <20150728225510.GB3159@codeaurora.org> <20150729081403.GH2284@x1>
 <20150729221526.GE3159@codeaurora.org> <20150730084634.GD9319@x1>
 <CAL_JsqKQLQ15qSt95zBZykzzPhcUrtZzhk29a76n+r_3719AiA@mail.gmail.com>
 <20150731163715.GV3159@codeaurora.org> <20150803034642.GV899@linux>
 <20150810132247.GH3249@x1>
Message-ID: <20150811080023.GB5509@linux>

On 10-08-15, 14:22, Lee Jones wrote:
> >  Optional properties:
> > +- opp-cuts: One or more strings, describing the versions of hardware the OPPs
> > +  can support.
> 
> This isn't very generic.
> 
> I'm guessing some vendors my have quite a few ways to differentiate
> between board versions/revisions/cuts etc.
> 
> How about another array where a vendor can choose to identify a piece
> of hardware however they see fit.
> 
> Example 1 (simple version):
> 
> /* Version 1 */
> opp-version = <1>;
> 
> Example 2 (using the kernel's versioning):
> 
> /* 2.6.32-rc1 */
> opp-version = <2 6 32 1>;
> 
> Example 3 (using ST's versioning):
> 
> /* Major 2, Minor 0, Cut 2, All substrates */
> opp-version = <2 0 2 0xff>;

But how will we parse this with generic code ?

-- 
viresh


From linux at arm.linux.org.uk  Tue Aug 11 01:21:05 2015
From: linux at arm.linux.org.uk (Russell King - ARM Linux)
Date: Tue, 11 Aug 2015 09:21:05 +0100
Subject: [GIT PULL v2] Renesas ARM Based SoC Marzen Board Removal for v4.3
In-Reply-To: <20150807012847.GF1145@verge.net.au>
References: <cover.1438581659.git.horms+renesas@verge.net.au>
 <20150806081000.GA16520@localhost>
 <20150807012847.GF1145@verge.net.au>
Message-ID: <20150811082105.GX7557@n2100.arm.linux.org.uk>

On Fri, Aug 07, 2015 at 10:28:47AM +0900, Simon Horman wrote:
> diff --git a/arch/arm/mach-shmobile/Makefile b/arch/arm/mach-shmobile/Makefile
> index 8d1e0b6ac2a2..476de30798d7 100644
> --- a/arch/arm/mach-shmobile/Makefile
> +++ b/arch/arm/mach-shmobile/Makefile
> @@ -53,6 +53,7 @@ obj-$(CONFIG_ARCH_RCAR_GEN2)	+= pm-rcar-gen2.o
>  ifndef CONFIG_ARCH_SHMOBILE_MULTI
>  obj-$(CONFIG_MACH_BOCKW)	+= board-bockw.o
>  obj-$(CONFIG_MACH_BOCKW_REFERENCE)	+= board-bockw-reference.o
> +endif
>  
>  # Framework support
>  obj-$(CONFIG_SMP)		+= $(smp-y)

What's happening to get this fixed?

arch/arm/mach-shmobile/Makefile:59: *** missing 'endif'.  Stop.
Makefile:949: recipe for target 'arch/arm/mach-shmobile' failed
make[1]: *** [arch/arm/mach-shmobile] Error 2

-- 
FTTC broadband for 0.8mile line: currently at 10.5Mbps down 400kbps up
according to speedtest.net.


From srinivas.kandagatla at linaro.org  Tue Aug 11 01:26:02 2015
From: srinivas.kandagatla at linaro.org (Srinivas Kandagatla)
Date: Tue, 11 Aug 2015 09:26:02 +0100
Subject: [PATCH 0/9] qcom: Add support for TSENS driver
In-Reply-To: <1436348838-22671-1-git-send-email-rnayak@codeaurora.org>
References: <1436348838-22671-1-git-send-email-rnayak@codeaurora.org>
Message-ID: <55C9B19A.9040901@linaro.org>

Hi Rajendra,

On 08/07/15 10:47, Rajendra Nayak wrote:
> Changes since RFC:
> * Added support for 8916 and 8084
> * Based off the latest nvmem framework patches [1]
> * Minor review fixes for comments mostly from Lina
>
> ** I have also added irq support using the hardware
> trip point support series [2]. Will post that
> out seperately.
>
> This is an attempt to have a single TSENS driver for
> the different versions of the TSENS IP that exist, on
> different qcom msm/apq SoCs'
> Support is added for msm8916, msm8960 and msm8974 families.
> Based on top of the latest nvmem framework patches [2]
>
> A lot of the work is based of original code from Stephen Boyd
> and Siddartha Mohanadoss. I have also picked some of what
> Narendran Rajan did in his attempt to upstream the support
> for 8960 family. I could not keep the original authorship on
> any of the patches because I ended up moving the code around
> quite a bit in an effort to have a single driver for the
> various devices. I would be glad to change the authorship
> for any of the patches if needed.
>
> [1] https://lkml.org/lkml/2015/6/22/609
> [2] https://lkml.org/lkml/2015/5/20/472
>
> Rajendra Nayak (8):
>    thermal: qcom: tsens: Add a skeletal TSENS drivers
>    thermal: qcom: tsens-8916: Add support for 8916 family of SoCs
>    thermal: qcom: tsens-8974: Add support for 8974 family of SoCs
>    thermal: qcom: tsens-8960: Add support for 8960 family of SoCs
>    arm: dts: msm8974: Add thermal zones, tsens and eeprom nodes
>    arm: dts: apq8064: Add thermal zones, tsens and eeprom nodes
>    arm: dts: apq8084: Add thermal zones, tsens and eeprom nodes
>    arm64: dts: msm8916: Add thermal zones, tsens and eeprom nodes
>
> Srinivas Kandagatla (1):
>    clk: qcom: gcc-msm8960: add child devices support.
>
>   .../devicetree/bindings/thermal/qcom-tsens.txt     |  37 +++
>   arch/arm/boot/dts/qcom-apq8064.dtsi                | 108 ++++++++
>   arch/arm/boot/dts/qcom-apq8084.dtsi                | 105 ++++++++
>   arch/arm/boot/dts/qcom-msm8974.dtsi                | 105 ++++++++
>   arch/arm64/boot/dts/qcom/msm8916.dtsi              |  66 +++++
>   drivers/clk/qcom/gcc-msm8960.c                     |   4 +-
>   drivers/thermal/Kconfig                            |   5 +
>   drivers/thermal/Makefile                           |   1 +
>   drivers/thermal/qcom/Kconfig                       |  10 +
>   drivers/thermal/qcom/Makefile                      |   2 +
>   drivers/thermal/qcom/tsens-8916.c                  | 107 ++++++++
>   drivers/thermal/qcom/tsens-8960.c                  | 291 +++++++++++++++++++++
>   drivers/thermal/qcom/tsens-8974.c                  | 239 +++++++++++++++++
>   drivers/thermal/qcom/tsens-common.c                | 128 +++++++++
>   drivers/thermal/qcom/tsens.c                       | 209 +++++++++++++++
>   drivers/thermal/qcom/tsens.h                       |  69 +++++
>   16 files changed, 1485 insertions(+), 1 deletion(-)
>   create mode 100644 Documentation/devicetree/bindings/thermal/qcom-tsens.txt
>   create mode 100644 drivers/thermal/qcom/Kconfig
>   create mode 100644 drivers/thermal/qcom/Makefile
>   create mode 100644 drivers/thermal/qcom/tsens-8916.c
>   create mode 100644 drivers/thermal/qcom/tsens-8960.c
>   create mode 100644 drivers/thermal/qcom/tsens-8974.c
>   create mode 100644 drivers/thermal/qcom/tsens-common.c
>   create mode 100644 drivers/thermal/qcom/tsens.c
>   create mode 100644 drivers/thermal/qcom/tsens.h
>


Tested-by: Srinivas Kandagatla <srinivas.kandagatla at linaro.org>

NVMEM framework in now available in linux-next.

Do you think we can get this in v4.3?

--srini




From ludovic.desroches at atmel.com  Tue Aug 11 01:28:00 2015
From: ludovic.desroches at atmel.com (Ludovic Desroches)
Date: Tue, 11 Aug 2015 10:28:00 +0200
Subject: [PATCH 0/5] New Atmel PIO4 pinctrl/gpio driver
Message-ID: <1439281685-3020-1-git-send-email-ludovic.desroches@atmel.com>

Hi,

The Atmel PIO4 controller has been introduced with SAMA5D2 chip family. This
drivers manages both pinmux/pinconf and gpio stuff. It is inspired by Mediatek
pinctrl driver.

Ludovic Desroches (5):
  pinctrl: introduce driver for Atmel PIO4 controller
  pinctrl: dt-binding: Add DT binding documentation for Atmel PIO4
  MAINTAINERS: Add an entry for pinctrl-at91-pio4
  ARM: at91/dt: sama5d2: add pio controller node
  ARM: at91/defconfig: sama5: add PIO4 controller support

 .../bindings/pinctrl/atmel,at91-pio4-pinctrl.txt   |   90 ++
 MAINTAINERS                                        |    7 +
 arch/arm/boot/dts/sama5d2.dtsi                     |   14 +
 arch/arm/mach-at91/Kconfig                         |    1 +
 drivers/pinctrl/Kconfig                            |   13 +
 drivers/pinctrl/Makefile                           |    1 +
 drivers/pinctrl/pinctrl-at91-pio4.c                | 1063 ++++++++++++++++++++
 7 files changed, 1189 insertions(+)
 create mode 100644 Documentation/devicetree/bindings/pinctrl/atmel,at91-pio4-pinctrl.txt
 create mode 100644 drivers/pinctrl/pinctrl-at91-pio4.c

-- 
2.5.0



From ludovic.desroches at atmel.com  Tue Aug 11 01:28:01 2015
From: ludovic.desroches at atmel.com (Ludovic Desroches)
Date: Tue, 11 Aug 2015 10:28:01 +0200
Subject: [PATCH 1/5] pinctrl: introduce driver for Atmel PIO4 controller
In-Reply-To: <1439281685-3020-1-git-send-email-ludovic.desroches@atmel.com>
References: <1439281685-3020-1-git-send-email-ludovic.desroches@atmel.com>
Message-ID: <1439281685-3020-2-git-send-email-ludovic.desroches@atmel.com>

Add a pinctrl/gpio driver for Atmel PIO4 controller available on SAMA5D2
chip family.

Signed-off-by: Ludovic Desroches <ludovic.desroches at atmel.com>
---
 drivers/pinctrl/Kconfig             |   13 +
 drivers/pinctrl/Makefile            |    1 +
 drivers/pinctrl/pinctrl-at91-pio4.c | 1063 +++++++++++++++++++++++++++++++++++
 3 files changed, 1077 insertions(+)
 create mode 100644 drivers/pinctrl/pinctrl-at91-pio4.c

diff --git a/drivers/pinctrl/Kconfig b/drivers/pinctrl/Kconfig
index 84dd2ed..b422e4e 100644
--- a/drivers/pinctrl/Kconfig
+++ b/drivers/pinctrl/Kconfig
@@ -67,6 +67,19 @@ config PINCTRL_AT91
 	help
 	  Say Y here to enable the at91 pinctrl driver
 
+config PINCTRL_AT91PIO4
+	bool "AT91 PIO4 pinctrl driver"
+	depends on OF
+	depends on ARCH_AT91
+	select PINMUX
+	select GENERIC_PINCONF
+	select GPIOLIB
+	select GPIOLIB_IRQCHIP
+	select OF_GPIO
+	help
+	  Say Y here to enable the at91 pinctrl/gpio driver for Atmel PIO4
+	  controller available on sama5d2 SoC.
+
 config PINCTRL_AMD
 	bool "AMD GPIO pin control"
 	depends on GPIOLIB
diff --git a/drivers/pinctrl/Makefile b/drivers/pinctrl/Makefile
index cad077c..8bed0c2 100644
--- a/drivers/pinctrl/Makefile
+++ b/drivers/pinctrl/Makefile
@@ -12,6 +12,7 @@ obj-$(CONFIG_PINCTRL_AS3722)	+= pinctrl-as3722.o
 obj-$(CONFIG_PINCTRL_BF54x)	+= pinctrl-adi2-bf54x.o
 obj-$(CONFIG_PINCTRL_BF60x)	+= pinctrl-adi2-bf60x.o
 obj-$(CONFIG_PINCTRL_AT91)	+= pinctrl-at91.o
+obj-$(CONFIG_PINCTRL_AT91PIO4)	+= pinctrl-at91-pio4.o
 obj-$(CONFIG_PINCTRL_AMD)	+= pinctrl-amd.o
 obj-$(CONFIG_PINCTRL_DIGICOLOR)	+= pinctrl-digicolor.o
 obj-$(CONFIG_PINCTRL_FALCON)	+= pinctrl-falcon.o
diff --git a/drivers/pinctrl/pinctrl-at91-pio4.c b/drivers/pinctrl/pinctrl-at91-pio4.c
new file mode 100644
index 0000000..1837ac7
--- /dev/null
+++ b/drivers/pinctrl/pinctrl-at91-pio4.c
@@ -0,0 +1,1063 @@
+/*
+ * Driver for the Atmel PIO4 controller
+ *
+ * Copyright (C) 2015 Atmel,
+ *               2015 Ludovic Desroches <ludovic.desroches at atmel.com>
+ *
+ * This software is licensed under the terms of the GNU General Public
+ * License version 2, as published by the Free Software Foundation, and
+ * may be copied, distributed, and modified under those terms.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ * GNU General Public License for more details.
+ */
+
+#include <linux/clk.h>
+#include <linux/gpio.h>
+#include <linux/io.h>
+#include <linux/module.h>
+#include <linux/of.h>
+#include <linux/platform_device.h>
+#include <linux/pinctrl/pinconf.h>
+#include <linux/pinctrl/pinconf-generic.h>
+#include <linux/pinctrl/pinctrl.h>
+#include <linux/pinctrl/pinmux.h>
+#include <linux/slab.h>
+#include "core.h"
+#include "pinconf.h"
+#include "pinctrl-utils.h"
+
+/*
+ * Warning:
+ * In order to not introduce confusion between Atmel PIO groups and pinctrl
+ * framework groups, Atmel PIO groups will be called banks, line is kept to
+ * designed the pin id into this bank.
+ */
+
+#define ATMEL_PIO_MSKR		0x0000
+#define ATMEL_PIO_CFGR		0x0004
+#define		ATMEL_PIO_CFGR_FUNC_MASK	GENMASK(2, 0)
+#define		ATMEL_PIO_DIR_MASK		BIT(8)
+#define		ATMEL_PIO_PUEN_MASK		BIT(9)
+#define		ATMEL_PIO_PDEN_MASK		BIT(10)
+#define		ATMEL_PIO_IFEN_MASK		BIT(12)
+#define		ATMEL_PIO_IFSCEN_MASK		BIT(13)
+#define		ATMEL_PIO_OPD_MASK		BIT(14)
+#define		ATMEL_PIO_SCHMITT_MASK		BIT(15)
+#define		ATMEL_PIO_CFGR_EVTSEL_MASK	GENMASK(26, 24)
+#define		ATMEL_PIO_CFGR_EVTSEL_FALLING	(0 << 24)
+#define		ATMEL_PIO_CFGR_EVTSEL_RISING	(1 << 24)
+#define		ATMEL_PIO_CFGR_EVTSEL_BOTH	(2 << 24)
+#define		ATMEL_PIO_CFGR_EVTSEL_LOW	(3 << 24)
+#define		ATMEL_PIO_CFGR_EVTSEL_HIGH	(4 << 24)
+#define ATMEL_PIO_PDSR		0x0008
+#define ATMEL_PIO_LOCKSR	0x000C
+#define ATMEL_PIO_SODR		0x0010
+#define ATMEL_PIO_CODR		0x0014
+#define ATMEL_PIO_ODSR		0x0018
+#define ATMEL_PIO_IER		0x0020
+#define ATMEL_PIO_IDR		0x0024
+#define ATMEL_PIO_IMR		0x0028
+#define ATMEL_PIO_ISR		0x002C
+#define ATMEL_PIO_IOFR		0x003C
+
+#define ATMEL_PIO_NPINS_PER_BANK	32
+#define ATMEL_PIO_BANK(pin_id)		(pin_id / ATMEL_PIO_NPINS_PER_BANK)
+#define ATMEL_PIO_LINE(pin_id)		(pin_id % ATMEL_PIO_NPINS_PER_BANK)
+#define ATMEL_PIO_BANK_OFFSET		0x40
+
+#define ATMEL_GET_PIN_NO(pinfunc)	((pinfunc) & 0xff)
+#define ATMEL_GET_PIN_FUNC(pinfunc)	((pinfunc >> 16) & 0xf)
+#define ATMEL_GET_PIN_IOSET(pinfunc)	((pinfunc >> 20) & 0xf)
+
+struct atmel_pioctrl_data {
+	unsigned nbanks;
+};
+
+struct atmel_group {
+	const char *name;
+	u32 pin;
+};
+
+struct atmel_pin {
+	unsigned pin_id;
+	unsigned mux;
+	unsigned ioset;
+	unsigned bank;
+	unsigned line;
+	const char *device;
+};
+
+/**
+ * struct atmel_pioctrl - Atmel PIO controller (pinmux + gpio)
+ * @reg_base: base address of the controller.
+ * @clk: clock of the controller.
+ * @nbanks: number of PIO groups, it can vary depending on the SoC.
+ * @pinctrl_dev: pinctrl device registered.
+ * @groups: groups table to provide group name and pin in the group to pinctrl.
+ * @group_names: group names table to provide all the group/pin names to
+ *     pinctrl or gpio.
+ * @pins: pins table used for both pinctrl and gpio. pin_id, bank and line
+ *     fields are set at probe time. Other ones are set when parsing dt
+ *     pinctrl.
+ * @npins: number of pins.
+ * @gpio_chip: gpio chip registered.
+ * @irq_domain: irq domain for the gpio controller.
+ * @irqs: table containing the hw irq number of the bank. The index of the
+ *     table is the bank id.
+ * @dev: device entry for the Atmel PIO controller.
+ * @node: node of the Atmel PIO controller.
+ */
+struct atmel_pioctrl {
+	void __iomem		*reg_base;
+	struct clk		*clk;
+	unsigned		nbanks;
+	struct pinctrl_dev	*pinctrl_dev;
+	struct atmel_group	*groups;
+	const char * const	*group_names;
+	struct atmel_pin	**pins;
+	unsigned		npins;
+	struct gpio_chip	*gpio_chip;
+	struct irq_domain	*irq_domain;
+	int			*irqs;
+	struct device		*dev;
+	struct device_node	*node;
+};
+
+static const char * const atmel_functions[] = {
+	"GPIO", "A", "B", "C", "D", "E", "F", "G"
+};
+
+/* --- GPIO --- */
+static unsigned int atmel_gpio_read(struct atmel_pioctrl *atmel_pioctrl,
+				    unsigned int bank, unsigned int reg)
+{
+	return readl_relaxed(atmel_pioctrl->reg_base
+			     + ATMEL_PIO_BANK_OFFSET * bank + reg);
+}
+
+static void atmel_gpio_write(struct atmel_pioctrl *atmel_pioctrl,
+			     unsigned int bank, unsigned int reg,
+			     unsigned int val)
+{
+	writel_relaxed(val, atmel_pioctrl->reg_base
+		       + ATMEL_PIO_BANK_OFFSET * bank + reg);
+}
+
+static void atmel_gpio_irq_ack(struct irq_data *d)
+{
+	/*
+	 * Nothing to do, interrupt is cleared when reading the status
+	 * register.
+	 */
+}
+
+static int atmel_gpio_irq_set_type(struct irq_data *d, unsigned type)
+{
+	struct atmel_pioctrl *atmel_pioctrl = irq_data_get_irq_chip_data(d);
+	struct atmel_pin *pin = atmel_pioctrl->pins[d->hwirq];
+	unsigned reg;
+
+	atmel_gpio_write(atmel_pioctrl, pin->bank, ATMEL_PIO_MSKR,
+			 BIT(pin->line));
+	reg = atmel_gpio_read(atmel_pioctrl, pin->bank, ATMEL_PIO_CFGR);
+	reg &= (~ATMEL_PIO_CFGR_EVTSEL_MASK);
+
+	switch (type) {
+	case IRQ_TYPE_EDGE_RISING:
+		__irq_set_handler_locked(d->irq, handle_edge_irq);
+		reg |= ATMEL_PIO_CFGR_EVTSEL_RISING;
+		break;
+	case IRQ_TYPE_EDGE_FALLING:
+		__irq_set_handler_locked(d->irq, handle_edge_irq);
+		reg |= ATMEL_PIO_CFGR_EVTSEL_FALLING;
+		break;
+	case IRQ_TYPE_EDGE_BOTH:
+		__irq_set_handler_locked(d->irq, handle_edge_irq);
+		reg |= ATMEL_PIO_CFGR_EVTSEL_BOTH;
+		break;
+	case IRQ_TYPE_LEVEL_LOW:
+		__irq_set_handler_locked(d->irq, handle_level_irq);
+		reg |= ATMEL_PIO_CFGR_EVTSEL_LOW;
+		break;
+	case IRQ_TYPE_LEVEL_HIGH:
+		__irq_set_handler_locked(d->irq, handle_level_irq);
+		reg |= ATMEL_PIO_CFGR_EVTSEL_HIGH;
+		break;
+	case IRQ_TYPE_NONE:
+	default:
+		return -EINVAL;
+	}
+
+	atmel_gpio_write(atmel_pioctrl, pin->bank, ATMEL_PIO_CFGR, reg);
+
+	return 0;
+}
+
+static void atmel_gpio_irq_mask(struct irq_data *d)
+{
+	struct atmel_pioctrl *atmel_pioctrl = irq_data_get_irq_chip_data(d);
+	struct atmel_pin *pin = atmel_pioctrl->pins[d->hwirq];
+
+	atmel_gpio_write(atmel_pioctrl, pin->bank, ATMEL_PIO_IDR,
+			 BIT(pin->line));
+}
+
+static void atmel_gpio_irq_unmask(struct irq_data *d)
+{
+	struct atmel_pioctrl *atmel_pioctrl = irq_data_get_irq_chip_data(d);
+	struct atmel_pin *pin = atmel_pioctrl->pins[d->hwirq];
+
+	atmel_gpio_write(atmel_pioctrl, pin->bank, ATMEL_PIO_IER,
+			 BIT(pin->line));
+}
+
+static struct irq_chip atmel_gpio_irq_chip = {
+	.name		= "GPIO",
+	.irq_ack	= atmel_gpio_irq_ack,
+	.irq_mask	= atmel_gpio_irq_mask,
+	.irq_unmask	= atmel_gpio_irq_unmask,
+	.irq_set_type	= atmel_gpio_irq_set_type,
+};
+
+static void atmel_gpio_irq_handler(unsigned int irq, struct irq_desc *desc)
+{
+	struct atmel_pioctrl *atmel_pioctrl = irq_get_handler_data(irq);
+	struct irq_chip *chip = irq_desc_get_chip(desc);
+	unsigned long isr;
+	int n, bank = -1;
+
+	/* Find from which bank is the irq received. */
+	for (n = 0; n < atmel_pioctrl->nbanks; n++) {
+		if (atmel_pioctrl->irqs[n] == irq) {
+			bank = n;
+			break;
+		}
+	}
+
+	if (bank < 0) {
+		dev_err(atmel_pioctrl->dev,
+			"no bank associated to irq %u\n", irq);
+		return;
+	}
+
+	chained_irq_enter(chip, desc);
+
+	for (;;) {
+		isr = (unsigned long) atmel_gpio_read(atmel_pioctrl, bank,
+						      ATMEL_PIO_ISR);
+		isr &= (unsigned long) atmel_gpio_read(atmel_pioctrl, bank,
+						       ATMEL_PIO_IMR);
+		if (!isr)
+			break;
+
+		for_each_set_bit(n, &isr, BITS_PER_LONG)
+			generic_handle_irq(gpio_to_irq(bank *
+					ATMEL_PIO_NPINS_PER_BANK + n));
+	}
+
+	chained_irq_exit(chip, desc);
+}
+
+static int atmel_gpio_request(struct gpio_chip *chip, unsigned offset)
+{
+	return pinctrl_request_gpio(chip->base + offset);
+}
+
+static void atmel_gpio_free(struct gpio_chip *chip, unsigned offset)
+{
+	pinctrl_free_gpio(chip->base + offset);
+}
+
+static int atmel_gpio_direction_input(struct gpio_chip *chip, unsigned offset)
+{
+	return pinctrl_gpio_direction_input(chip->base + offset);
+}
+
+static int atmel_gpio_get(struct gpio_chip *chip, unsigned offset)
+{
+	struct atmel_pioctrl *atmel_pioctrl = dev_get_drvdata(chip->dev);
+	struct atmel_pin *pin = atmel_pioctrl->pins[offset];
+	unsigned reg;
+
+	reg = atmel_gpio_read(atmel_pioctrl, pin->bank, ATMEL_PIO_PDSR);
+
+	return !!(reg & BIT(pin->line));
+}
+
+static int atmel_gpio_direction_output(struct gpio_chip *chip, unsigned offset,
+				       int value)
+{
+	struct atmel_pioctrl *atmel_pioctrl = dev_get_drvdata(chip->dev);
+	struct atmel_pin *pin = atmel_pioctrl->pins[offset];
+
+	atmel_gpio_write(atmel_pioctrl, pin->bank,
+			 value ? ATMEL_PIO_SODR : ATMEL_PIO_CODR,
+			 BIT(pin->line));
+
+	return pinctrl_gpio_direction_output(chip->base + offset);
+}
+
+static void atmel_gpio_set(struct gpio_chip *chip, unsigned offset, int val)
+{
+	struct atmel_pioctrl *atmel_pioctrl = dev_get_drvdata(chip->dev);
+	struct atmel_pin *pin = atmel_pioctrl->pins[offset];
+
+	atmel_gpio_write(atmel_pioctrl, pin->bank,
+			 val ? ATMEL_PIO_SODR : ATMEL_PIO_CODR,
+			 BIT(pin->line));
+}
+
+static int atmel_gpio_to_irq(struct gpio_chip *chip, unsigned offset)
+{
+	struct atmel_pioctrl *atmel_pioctrl = dev_get_drvdata(chip->dev);
+
+	return irq_find_mapping(atmel_pioctrl->irq_domain, offset);
+}
+
+static struct gpio_chip atmel_gpio_chip = {
+	.request                = atmel_gpio_request,
+	.free                   = atmel_gpio_free,
+	.direction_input        = atmel_gpio_direction_input,
+	.get                    = atmel_gpio_get,
+	.direction_output       = atmel_gpio_direction_output,
+	.set                    = atmel_gpio_set,
+	.to_irq                 = atmel_gpio_to_irq,
+	.base                   = 0,
+};
+
+/* --- PINCTRL --- */
+static unsigned int atmel_pin_config_read(struct pinctrl_dev *pctldev,
+				unsigned pin_id)
+{
+	struct atmel_pioctrl *atmel_pioctrl = pinctrl_dev_get_drvdata(pctldev);
+	unsigned bank = atmel_pioctrl->pins[pin_id]->bank;
+	unsigned line = atmel_pioctrl->pins[pin_id]->line;
+	void __iomem *addr = atmel_pioctrl->reg_base
+			     + bank * ATMEL_PIO_BANK_OFFSET;
+
+	writel_relaxed(BIT(line), addr + ATMEL_PIO_MSKR);
+	/* Have to set MSKR first, to access the right pin CFGR. */
+	wmb();
+
+	return readl_relaxed(addr + ATMEL_PIO_CFGR);
+}
+
+static void atmel_pin_config_write(struct pinctrl_dev *pctldev,
+					unsigned pin_id, u32 conf)
+{
+	struct atmel_pioctrl *atmel_pioctrl = pinctrl_dev_get_drvdata(pctldev);
+	unsigned bank = atmel_pioctrl->pins[pin_id]->bank;
+	unsigned line = atmel_pioctrl->pins[pin_id]->line;
+	void __iomem *addr = atmel_pioctrl->reg_base
+			     + bank * ATMEL_PIO_BANK_OFFSET;
+
+	writel_relaxed(BIT(line), addr + ATMEL_PIO_MSKR);
+	/* Have to set MSKR first, to access the right pin CFGR. */
+	wmb();
+	writel_relaxed(conf, addr + ATMEL_PIO_CFGR);
+}
+
+static int atmel_pctl_get_groups_count(struct pinctrl_dev *pctldev)
+{
+	struct atmel_pioctrl *atmel_pioctrl = pinctrl_dev_get_drvdata(pctldev);
+
+	return atmel_pioctrl->npins;
+}
+
+static const char *atmel_pctl_get_group_name(struct pinctrl_dev *pctldev,
+					     unsigned selector)
+{
+	struct atmel_pioctrl *atmel_pioctrl = pinctrl_dev_get_drvdata(pctldev);
+
+	return atmel_pioctrl->groups[selector].name;
+}
+
+static int atmel_pctl_get_group_pins(struct pinctrl_dev *pctldev,
+				     unsigned selector, const unsigned **pins,
+				     unsigned *num_pins)
+{
+	struct atmel_pioctrl *atmel_pioctrl = pinctrl_dev_get_drvdata(pctldev);
+
+	*pins = (unsigned *)&atmel_pioctrl->groups[selector].pin;
+	*num_pins = 1;
+
+	return 0;
+}
+
+struct atmel_group *atmel_pctl_find_group_by_pin(struct pinctrl_dev *pctldev,
+						 unsigned pin)
+{
+	struct atmel_pioctrl *atmel_pioctrl = pinctrl_dev_get_drvdata(pctldev);
+	int i;
+
+	for (i = 0; i < atmel_pioctrl->npins; i++) {
+		struct atmel_group *grp = atmel_pioctrl->groups + i;
+
+		if (grp->pin == pin)
+			return grp;
+	}
+
+	return NULL;
+}
+
+static int atmel_pctl_xlate_pinfunc(struct pinctrl_dev *pctldev,
+				    struct device_node *np,
+				    u32 pinfunc, const char **grp_name,
+				    const char **func_name)
+{
+	struct atmel_pioctrl *atmel_pioctrl = pinctrl_dev_get_drvdata(pctldev);
+	unsigned pin_id, func_id;
+	struct atmel_group *grp;
+
+	pin_id = ATMEL_GET_PIN_NO(pinfunc);
+	func_id = ATMEL_GET_PIN_FUNC(pinfunc);
+
+	if (func_id >= ARRAY_SIZE(atmel_functions))
+		return -EINVAL;
+
+	*func_name = atmel_functions[func_id];
+
+	grp = atmel_pctl_find_group_by_pin(pctldev, pin_id);
+	if (!grp)
+		return -EINVAL;
+	*grp_name = grp->name;
+
+	atmel_pioctrl->pins[pin_id]->mux = func_id;
+	atmel_pioctrl->pins[pin_id]->ioset = ATMEL_GET_PIN_IOSET(pinfunc);
+	/* Want the device name not the group one. */
+	if (np->parent == atmel_pioctrl->node)
+		atmel_pioctrl->pins[pin_id]->device = np->name;
+	else
+		atmel_pioctrl->pins[pin_id]->device = np->parent->name;
+
+	return 0;
+}
+
+static int atmel_pctl_dt_subnode_to_map(struct pinctrl_dev *pctldev,
+					struct device_node *np,
+					struct pinctrl_map **map,
+					unsigned *reserved_maps,
+					unsigned *num_maps)
+{
+	unsigned num_pins, num_configs, reserve;
+	unsigned long *configs;
+	struct property	*pins;
+	bool has_config;
+	u32 pinfunc;
+	int ret, i;
+
+	pins = of_find_property(np, "pinmux", NULL);
+	if (!pins)
+		return -EINVAL;
+
+	ret = pinconf_generic_parse_dt_config(np, pctldev, &configs,
+					      &num_configs);
+	if (ret < 0) {
+		dev_err(pctldev->dev, "%s: could not parse node property\n",
+			of_node_full_name(np));
+		return ret;
+	}
+
+	if (num_configs)
+		has_config = true;
+
+	num_pins = pins->length / sizeof(u32);
+	if (!num_pins) {
+		dev_err(pctldev->dev, "no pins found in node %s\n",
+			of_node_full_name(np));
+		return -EINVAL;
+	}
+
+	/*
+	 * Reserve maps, at least there is a mux map and an optional conf
+	 * map for each pin.
+	 */
+	reserve = 1;
+	if (has_config && num_pins >= 1)
+		reserve++;
+	reserve *= num_pins;
+	ret = pinctrl_utils_reserve_map(pctldev, map, reserved_maps, num_maps,
+					reserve);
+	if (ret < 0)
+		return ret;
+
+	for (i = 0; i < num_pins; i++) {
+		const char *group, *func;
+
+		ret = of_property_read_u32_index(np, "pinmux", i, &pinfunc);
+		if (ret)
+			return ret;
+
+		ret = atmel_pctl_xlate_pinfunc(pctldev, np, pinfunc, &group,
+					       &func);
+		if (ret)
+			return ret;
+
+		pinctrl_utils_add_map_mux(pctldev, map, reserved_maps, num_maps,
+					  group, func);
+
+		if (has_config) {
+			ret = pinctrl_utils_add_map_configs(pctldev, map,
+					reserved_maps, num_maps, group,
+					configs, num_configs,
+					PIN_MAP_TYPE_CONFIGS_GROUP);
+			if (ret < 0)
+				return ret;
+		}
+	}
+
+	return 0;
+}
+
+static int atmel_pctl_dt_node_to_map(struct pinctrl_dev *pctldev,
+				      struct device_node *np_config,
+				      struct pinctrl_map **map,
+				      unsigned *num_maps)
+{
+	struct device_node *np;
+	unsigned reserved_maps;
+	int ret;
+
+	*map = NULL;
+	*num_maps = 0;
+	reserved_maps = 0;
+
+	/*
+	 * If all the pins of a device have the same configuration (or no one),
+	 * it is useless to add a subnode, so directly parse node referenced by
+	 * phandle.
+	 */
+	ret = atmel_pctl_dt_subnode_to_map(pctldev, np_config, map,
+			&reserved_maps, num_maps);
+	if (ret) {
+		for_each_child_of_node(np_config, np) {
+			ret = atmel_pctl_dt_subnode_to_map(pctldev, np, map,
+						    &reserved_maps, num_maps);
+			if (ret < 0)
+				break;
+		}
+	}
+
+	if (ret < 0) {
+		pinctrl_utils_dt_free_map(pctldev, *map, *num_maps);
+		dev_err(pctldev->dev, "can't create maps for node %s\n",
+			np_config->full_name);
+	}
+
+	return ret;
+}
+
+static const struct pinctrl_ops atmel_pctlops = {
+	.get_groups_count	= atmel_pctl_get_groups_count,
+	.get_group_name		= atmel_pctl_get_group_name,
+	.get_group_pins		= atmel_pctl_get_group_pins,
+	.dt_node_to_map		= atmel_pctl_dt_node_to_map,
+	.dt_free_map		= pinctrl_utils_dt_free_map,
+};
+
+static int atmel_pmx_get_functions_count(struct pinctrl_dev *pctldev)
+{
+	return ARRAY_SIZE(atmel_functions);
+}
+
+static const char *atmel_pmx_get_function_name(struct pinctrl_dev *pctldev,
+						unsigned selector)
+{
+	return atmel_functions[selector];
+}
+
+static int atmel_pmx_get_function_groups(struct pinctrl_dev *pctldev,
+					   unsigned selector,
+					   const char * const **groups,
+					   unsigned * const num_groups)
+{
+	struct atmel_pioctrl *atmel_pioctrl = pinctrl_dev_get_drvdata(pctldev);
+
+	*groups = atmel_pioctrl->group_names;
+	*num_groups = atmel_pioctrl->npins;
+
+	return 0;
+}
+
+static int atmel_pmx_set_mux(struct pinctrl_dev *pctldev,
+			      unsigned function,
+			      unsigned group)
+{
+	struct atmel_pioctrl *atmel_pioctrl = pinctrl_dev_get_drvdata(pctldev);
+	unsigned pin;
+	u32 conf;
+
+	dev_dbg(pctldev->dev, "enable function %s group %s\n",
+		atmel_functions[function], atmel_pioctrl->groups[group].name);
+
+	pin = atmel_pioctrl->groups[group].pin;
+	conf = atmel_pin_config_read(pctldev, pin);
+	conf &= (~ATMEL_PIO_CFGR_FUNC_MASK);
+	conf |= (function & ATMEL_PIO_CFGR_FUNC_MASK);
+	dev_dbg(pctldev->dev, "pin: %u, conf: 0x%08x\n", pin, conf);
+	atmel_pin_config_write(pctldev, pin, conf);
+
+	return 0;
+}
+
+static int atmel_pmx_gpio_request_enable(struct pinctrl_dev *pctldev,
+					 struct pinctrl_gpio_range *range,
+					 unsigned offset)
+{
+	struct atmel_pioctrl *atmel_pioctrl = pinctrl_dev_get_drvdata(pctldev);
+	u32 conf;
+
+	if (!range || (range->gc != atmel_pioctrl->gpio_chip))
+		return -EINVAL;
+
+	conf = atmel_pin_config_read(pctldev, offset);
+	conf &= (~ATMEL_PIO_CFGR_FUNC_MASK);
+	atmel_pin_config_write(pctldev, offset, conf);
+
+	return 0;
+}
+
+static void atmel_pmx_gpio_disable_free(struct pinctrl_dev *pctldev,
+					struct pinctrl_gpio_range *range,
+					unsigned offset)
+{
+	/*
+	 * Nothing to do, only have to change the pin function. It will be done
+	 * when muxing this pin.
+	 */
+}
+
+static int atmel_pmx_gpio_set_direction(struct pinctrl_dev *pctldev,
+					struct pinctrl_gpio_range *range,
+					unsigned offset, bool input)
+{
+	struct atmel_pioctrl *atmel_pioctrl = pinctrl_dev_get_drvdata(pctldev);
+	u32 conf;
+
+	if (!range || (range->gc != atmel_pioctrl->gpio_chip))
+		return -EINVAL;
+
+	conf = atmel_pin_config_read(pctldev, offset);
+	if (input)
+		conf &= (~ATMEL_PIO_DIR_MASK);
+	else
+		conf |= ATMEL_PIO_DIR_MASK;
+	atmel_pin_config_write(pctldev, offset, conf);
+
+	return 0;
+}
+
+static const struct pinmux_ops atmel_pmxops = {
+	.get_functions_count	= atmel_pmx_get_functions_count,
+	.get_function_name	= atmel_pmx_get_function_name,
+	.get_function_groups	= atmel_pmx_get_function_groups,
+	.set_mux		= atmel_pmx_set_mux,
+	.gpio_request_enable	= atmel_pmx_gpio_request_enable,
+	.gpio_disable_free	= atmel_pmx_gpio_disable_free,
+	.gpio_set_direction	= atmel_pmx_gpio_set_direction,
+};
+
+static int atmel_conf_pin_config_group_get(struct pinctrl_dev *pctldev,
+					   unsigned group,
+					   unsigned long *config)
+{
+	struct atmel_pioctrl *atmel_pioctrl = pinctrl_dev_get_drvdata(pctldev);
+	unsigned param = pinconf_to_config_param(*config), arg = 0;
+	struct atmel_group *grp = atmel_pioctrl->groups + group;
+	unsigned pin_id = grp->pin;
+	u32 res;
+
+	res = atmel_pin_config_read(pctldev, pin_id);
+
+	switch (param) {
+	case PIN_CONFIG_BIAS_PULL_UP:
+		if (!(res & ATMEL_PIO_PUEN_MASK))
+			return -EINVAL;
+		arg = 1;
+		break;
+	case PIN_CONFIG_BIAS_PULL_DOWN:
+		if ((res & ATMEL_PIO_PUEN_MASK)
+		    || (!(res & ATMEL_PIO_PDEN_MASK)))
+			return -EINVAL;
+		arg = 1;
+		break;
+	case PIN_CONFIG_BIAS_DISABLE:
+		if ((res & ATMEL_PIO_PUEN_MASK)
+		    || ((res & ATMEL_PIO_PDEN_MASK)))
+			return -EINVAL;
+		arg = 1;
+		break;
+	case PIN_CONFIG_DRIVE_OPEN_DRAIN:
+		if (!(res & ATMEL_PIO_OPD_MASK))
+			return -EINVAL;
+		arg = 1;
+		break;
+	case PIN_CONFIG_INPUT_SCHMITT_ENABLE:
+		if (!(res & ATMEL_PIO_SCHMITT_MASK))
+			return -EINVAL;
+		arg = 1;
+		break;
+	default:
+		return -ENOTSUPP;
+	}
+
+	*config = pinconf_to_config_packed(param, arg);
+	return 0;
+}
+
+static int atmel_conf_pin_config_group_set(struct pinctrl_dev *pctldev,
+					   unsigned group,
+					   unsigned long *configs,
+					   unsigned num_configs)
+{
+	struct atmel_pioctrl *atmel_pioctrl = pinctrl_dev_get_drvdata(pctldev);
+	struct atmel_group *grp = atmel_pioctrl->groups + group;
+	unsigned bank, pin, pin_id = grp->pin;
+	u32 mask, conf = 0;
+	int i;
+
+	conf = atmel_pin_config_read(pctldev, pin_id);
+
+	for (i = 0; i < num_configs; i++) {
+		unsigned param = pinconf_to_config_param(configs[i]);
+		unsigned arg = pinconf_to_config_argument(configs[i]);
+
+		dev_dbg(pctldev->dev, "%s: pin=%u, config=0x%lx\n",
+			__func__, pin_id, configs[i]);
+
+		switch (param) {
+		case PIN_CONFIG_BIAS_DISABLE:
+			conf &= (~ATMEL_PIO_PUEN_MASK);
+			conf &= (~ATMEL_PIO_PDEN_MASK);
+			break;
+		case PIN_CONFIG_BIAS_PULL_UP:
+			conf |= ATMEL_PIO_PUEN_MASK;
+			break;
+		case PIN_CONFIG_BIAS_PULL_DOWN:
+			conf |= ATMEL_PIO_PDEN_MASK;
+			break;
+		case PIN_CONFIG_DRIVE_OPEN_DRAIN:
+			if (arg == 0)
+				conf &= (~ATMEL_PIO_OPD_MASK);
+			else
+				conf |= ATMEL_PIO_OPD_MASK;
+			break;
+		case PIN_CONFIG_INPUT_SCHMITT_ENABLE:
+			if (arg == 0)
+				conf |= ATMEL_PIO_SCHMITT_MASK;
+			else
+				conf &= (~ATMEL_PIO_SCHMITT_MASK);
+			break;
+		case PIN_CONFIG_INPUT_DEBOUNCE:
+			if (arg == 0) {
+				conf &= (~ATMEL_PIO_IFEN_MASK);
+				conf &= (~ATMEL_PIO_IFSCEN_MASK);
+			} else {
+				/*
+				 * We don't care about the debounce value for several reasons:
+				 * - can't have different debounce periods inside a same group,
+				 * - the register to configure this period is a secure register.
+				 * The debouncing filter can filter a pulse with a duration of less
+				 * than 1/2 slow clock period.
+				 */
+				conf |= ATMEL_PIO_IFEN_MASK;
+				conf |= ATMEL_PIO_IFSCEN_MASK;
+			}
+			break;
+		case PIN_CONFIG_OUTPUT:
+			conf |= ATMEL_PIO_DIR_MASK;
+			bank = ATMEL_PIO_BANK(pin_id);
+			pin = ATMEL_PIO_LINE(pin_id);
+			mask = 1 << pin;
+
+			if (arg == 0) {
+				writel_relaxed(mask, atmel_pioctrl->reg_base +
+					bank * ATMEL_PIO_BANK_OFFSET +
+					ATMEL_PIO_CODR);
+			} else {
+				writel_relaxed(mask, atmel_pioctrl->reg_base +
+					bank * ATMEL_PIO_BANK_OFFSET +
+					ATMEL_PIO_SODR);
+			}
+			break;
+		default:
+			dev_warn(pctldev->dev,
+				 "unsupported configuration parameter: %u\n",
+				 param);
+			continue;
+		}
+	}
+
+	dev_dbg(pctldev->dev, "%s: reg=0x%08x\n", __func__, conf);
+	atmel_pin_config_write(pctldev, pin_id, conf);
+
+	return 0;
+}
+
+static void atmel_conf_pin_config_dbg_show(struct pinctrl_dev *pctldev,
+					   struct seq_file *s, unsigned pin_id)
+{
+	struct atmel_pioctrl *atmel_pioctrl = pinctrl_dev_get_drvdata(pctldev);
+	u32 conf;
+
+	if (!atmel_pioctrl->pins[pin_id]->device)
+		return;
+
+	if (atmel_pioctrl->pins[pin_id])
+		seq_printf(s, " (%s, ioset %u) ",
+			   atmel_pioctrl->pins[pin_id]->device,
+			   atmel_pioctrl->pins[pin_id]->ioset);
+
+	conf = atmel_pin_config_read(pctldev, pin_id);
+	if (conf & ATMEL_PIO_PUEN_MASK)
+		seq_printf(s, "%s ", "pull-up");
+	if (conf & ATMEL_PIO_PDEN_MASK)
+		seq_printf(s, "%s ", "pull-down");
+	if (conf & ATMEL_PIO_IFEN_MASK)
+		seq_printf(s, "%s ", "debounce");
+	if (conf & ATMEL_PIO_OPD_MASK)
+		seq_printf(s, "%s ", "open-drain");
+	if (conf & ATMEL_PIO_SCHMITT_MASK)
+		seq_printf(s, "%s ", "schmitt");
+}
+
+static const struct pinconf_ops atmel_confops = {
+	.pin_config_group_get	= atmel_conf_pin_config_group_get,
+	.pin_config_group_set	= atmel_conf_pin_config_group_set,
+	.pin_config_dbg_show	= atmel_conf_pin_config_dbg_show,
+};
+
+static struct pinctrl_desc atmel_pinctrl_desc = {
+	.name		= "atmel_pinctrl",
+	.confops	= &atmel_confops,
+	.pctlops	= &atmel_pctlops,
+	.pmxops		= &atmel_pmxops,
+};
+
+/*
+ * The number of banks can be different from a SoC to another one.
+ * We can have up to 16 banks.
+ */
+static const struct atmel_pioctrl_data atmel_sama5d2_pioctrl_data = {
+	.nbanks		= 4,
+};
+
+static const struct of_device_id atmel_pctrl_of_match[] = {
+	{
+		.compatible = "atmel,sama5d2-pinctrl",
+		.data = &atmel_sama5d2_pioctrl_data,
+	}, {
+		/* sentinel */
+	}
+};
+MODULE_DEVICE_TABLE(of, atmel_pctrl_of_match);
+
+static int atmel_pinctrl_probe(struct platform_device *pdev)
+{
+	struct device *dev = &pdev->dev;
+	struct pinctrl_pin_desc	*pin_desc;
+	const char **group_names;
+	const struct of_device_id *match;
+	int i, ret;
+	struct resource	*res;
+	struct atmel_pioctrl *atmel_pioctrl;
+	struct atmel_pioctrl_data *atmel_pioctrl_data;
+
+	atmel_pioctrl = devm_kzalloc(dev, sizeof(*atmel_pioctrl), GFP_KERNEL);
+	if (!atmel_pioctrl)
+		return -ENOMEM;
+	atmel_pioctrl->dev = dev;
+	atmel_pioctrl->node = dev->of_node;
+	platform_set_drvdata(pdev, atmel_pioctrl);
+
+	match = of_match_node(atmel_pctrl_of_match, dev->of_node);
+	if (!match) {
+		dev_err(dev, "unknown compatible string\n");
+		return -ENODEV;
+	}
+	atmel_pioctrl_data = (struct atmel_pioctrl_data *) match->data;
+	atmel_pioctrl->nbanks = atmel_pioctrl_data->nbanks;
+	atmel_pioctrl->npins = atmel_pioctrl->nbanks * ATMEL_PIO_NPINS_PER_BANK;
+
+	res = platform_get_resource(pdev, IORESOURCE_MEM, 0);
+	if (!res) {
+		dev_err(dev, "unable to get atmel pinctrl resource\n");
+		return -EINVAL;
+	}
+	atmel_pioctrl->reg_base = devm_ioremap_resource(dev, res);
+	if (IS_ERR(atmel_pioctrl->reg_base))
+		return -EINVAL;
+
+	atmel_pioctrl->clk = devm_clk_get(dev, NULL);
+	if (IS_ERR(atmel_pioctrl->clk)) {
+		dev_err(dev, "failed to get clock\n");
+		return PTR_ERR(atmel_pioctrl->clk);
+	}
+
+	atmel_pioctrl->pins = devm_kzalloc(dev, sizeof(*atmel_pioctrl->pins)
+			* atmel_pioctrl->npins, GFP_KERNEL);
+	if (!atmel_pioctrl->pins)
+		return -ENOMEM;
+
+	pin_desc = devm_kzalloc(dev, sizeof(*pin_desc)
+			* atmel_pioctrl->npins, GFP_KERNEL);
+	if (!pin_desc)
+		return -ENOMEM;
+	atmel_pinctrl_desc.pins = pin_desc;
+	atmel_pinctrl_desc.npins = atmel_pioctrl->npins;
+
+	/* One pin is one group since a pin can achieve all functions. */
+	group_names = devm_kzalloc(dev, sizeof(*group_names)
+			* atmel_pioctrl->npins, GFP_KERNEL);
+	if (!group_names)
+		return -ENOMEM;
+	atmel_pioctrl->group_names = group_names;
+
+	atmel_pioctrl->groups = devm_kzalloc(&pdev->dev,
+			sizeof(*atmel_pioctrl->groups) * atmel_pioctrl->npins,
+			GFP_KERNEL);
+	if (!atmel_pioctrl->groups)
+		return -ENOMEM;
+	for (i = 0 ; i < atmel_pioctrl->npins; i++) {
+		struct atmel_group *group = atmel_pioctrl->groups + i;
+		unsigned bank = ATMEL_PIO_BANK(i);
+		unsigned line = ATMEL_PIO_LINE(i);
+
+		atmel_pioctrl->pins[i] = devm_kzalloc(dev,
+				sizeof(**atmel_pioctrl->pins), GFP_KERNEL);
+		if (!atmel_pioctrl->pins[i])
+			return -ENOMEM;
+
+		atmel_pioctrl->pins[i]->pin_id = i;
+		atmel_pioctrl->pins[i]->bank = bank;
+		atmel_pioctrl->pins[i]->line = line;
+
+		pin_desc[i].number = i;
+		/* Pin naming convention: P(bank_name)(bank_pin_number). */
+		pin_desc[i].name = kasprintf(GFP_KERNEL, "P%c%d",
+					     bank + 'A', line);
+
+		group->name = group_names[i] = pin_desc[i].name;
+		group->pin = pin_desc[i].number;
+
+		dev_dbg(dev, "pin_id=%u, bank=%u, line=%u", i, bank, line);
+	}
+
+	atmel_pioctrl->gpio_chip = &atmel_gpio_chip;
+	atmel_pioctrl->gpio_chip->of_node = dev->of_node;
+	atmel_pioctrl->gpio_chip->ngpio = atmel_pioctrl->npins;
+	atmel_pioctrl->gpio_chip->label = dev_name(dev);
+	atmel_pioctrl->gpio_chip->dev = dev;
+	atmel_pioctrl->gpio_chip->names = atmel_pioctrl->group_names;
+
+	atmel_pioctrl->irqs = devm_kzalloc(dev, sizeof(*atmel_pioctrl->irqs)
+			* atmel_pioctrl->nbanks, GFP_KERNEL);
+	if (!atmel_pioctrl->irqs)
+		return -ENOMEM;
+
+	/* There is one controller but each bank has its own irq line. */
+	for (i = 0; i < atmel_pioctrl->nbanks; i++) {
+		res = platform_get_resource(pdev, IORESOURCE_IRQ, i);
+		if (!res) {
+			dev_err(dev, "missing irq resource for group %c\n",
+				'A' + i);
+			return -EINVAL;
+		}
+		atmel_pioctrl->irqs[i] = res->start;
+		irq_set_chained_handler(res->start, atmel_gpio_irq_handler);
+		irq_set_handler_data(res->start, atmel_pioctrl);
+		dev_dbg(dev, "bank %i: hwirq=%u\n", i, res->start);
+	}
+
+	atmel_pioctrl->irq_domain = irq_domain_add_linear(dev->of_node,
+			atmel_pioctrl->gpio_chip->ngpio,
+			&irq_domain_simple_ops, NULL);
+	if (!atmel_pioctrl->irq_domain) {
+		dev_err(dev, "can't add the irq domain\n");
+		return -ENODEV;
+	}
+	atmel_pioctrl->irq_domain->name = "atmel gpio";
+
+	for (i = 0; i < atmel_pioctrl->npins; i++) {
+		int irq = irq_create_mapping(atmel_pioctrl->irq_domain, i);
+
+		irq_set_chip_and_handler(irq, &atmel_gpio_irq_chip,
+					 handle_simple_irq);
+		irq_set_chip_data(irq, atmel_pioctrl);
+		dev_dbg(dev,
+			"atmel gpio irq domain: hwirq: %d, linux irq: %d\n",
+			i, irq);
+	}
+
+	ret = clk_prepare_enable(atmel_pioctrl->clk);
+	if (ret) {
+		dev_err(dev, "failed to prepare and enable clock\n");
+		goto clk_prepare_enable_error;
+	}
+
+	atmel_pioctrl->pinctrl_dev = pinctrl_register(&atmel_pinctrl_desc,
+						      &pdev->dev,
+						      atmel_pioctrl);
+	if (!atmel_pioctrl->pinctrl_dev) {
+		dev_err(dev, "pinctrl registration failed\n");
+		goto pinctrl_register_error;
+	}
+
+
+	ret = gpiochip_add(atmel_pioctrl->gpio_chip);
+	if (ret) {
+		dev_err(dev, "failed to add gpiochip\n");
+		goto gpiochip_add_error;
+	}
+
+	ret = gpiochip_add_pin_range(atmel_pioctrl->gpio_chip, dev_name(dev),
+				     0, 0, atmel_pioctrl->gpio_chip->ngpio);
+	if (ret) {
+		dev_err(dev, "failed to add gpio pin range\n");
+		goto gpiochip_add_pin_range_error;
+	}
+
+	dev_info(&pdev->dev, "atmel pinctrl initialized\n");
+
+	return 0;
+
+clk_prepare_enable_error:
+	irq_domain_remove(atmel_pioctrl->irq_domain);
+pinctrl_register_error:
+	clk_disable_unprepare(atmel_pioctrl->clk);
+gpiochip_add_error:
+	pinctrl_unregister(atmel_pioctrl->pinctrl_dev);
+gpiochip_add_pin_range_error:
+	gpiochip_remove(atmel_pioctrl->gpio_chip);
+
+	return ret;
+}
+
+int atmel_pinctrl_remove(struct platform_device *pdev)
+{
+	struct atmel_pioctrl *atmel_pioctrl = platform_get_drvdata(pdev);
+
+	irq_domain_remove(atmel_pioctrl->irq_domain);
+	clk_disable_unprepare(atmel_pioctrl->clk);
+	pinctrl_unregister(atmel_pioctrl->pinctrl_dev);
+	gpiochip_remove(atmel_pioctrl->gpio_chip);
+
+	return 0;
+}
+
+static struct platform_driver atmel_pinctrl_driver = {
+	.driver = {
+		.name = "pinctrl-at91-pio4",
+		.of_match_table = atmel_pctrl_of_match,
+	},
+	.probe = atmel_pinctrl_probe,
+	.remove = atmel_pinctrl_remove,
+};
+module_platform_driver(atmel_pinctrl_driver);
+
+MODULE_AUTHOR(Ludovic Desroches <ludovic.desroches at atmel.com>);
+MODULE_DESCRIPTION("Atmel PIO4 pinctrl driver");
+MODULE_LICENSE("GPL v2");
-- 
2.5.0



From ludovic.desroches at atmel.com  Tue Aug 11 01:28:02 2015
From: ludovic.desroches at atmel.com (Ludovic Desroches)
Date: Tue, 11 Aug 2015 10:28:02 +0200
Subject: [PATCH 2/5] pinctrl: dt-binding: Add DT binding documentation for
 Atmel PIO4
In-Reply-To: <1439281685-3020-1-git-send-email-ludovic.desroches@atmel.com>
References: <1439281685-3020-1-git-send-email-ludovic.desroches@atmel.com>
Message-ID: <1439281685-3020-3-git-send-email-ludovic.desroches@atmel.com>

Add documentation for the Atmel PIO4 controller introduced with SAMA5D2
chip family.

Signed-off-by: Ludovic Desroches <ludovic.desroches at atmel.com>
---
 .../bindings/pinctrl/atmel,at91-pio4-pinctrl.txt   | 90 ++++++++++++++++++++++
 1 file changed, 90 insertions(+)
 create mode 100644 Documentation/devicetree/bindings/pinctrl/atmel,at91-pio4-pinctrl.txt

diff --git a/Documentation/devicetree/bindings/pinctrl/atmel,at91-pio4-pinctrl.txt b/Documentation/devicetree/bindings/pinctrl/atmel,at91-pio4-pinctrl.txt
new file mode 100644
index 0000000..61ac757
--- /dev/null
+++ b/Documentation/devicetree/bindings/pinctrl/atmel,at91-pio4-pinctrl.txt
@@ -0,0 +1,90 @@
+* Atmel PIO4 Controller
+
+The Atmel PIO4 controller is used to select the function of a pin and to
+configure it.
+
+Required properties:
+- compatible: "atmel,sama5d2-pinctrl".
+- reg: base address and length of the PIO controller.
+- interrupts: interrupt outputs from the controller, one for each bank.
+- interrupt-controller: mark the device node as an interrupt controller.
+- #interrupt-cells: should be two.
+- gpio-controller: mark the device node as a gpio controller.
+- #gpio-cells: should be two.
+
+Please refer to ../gpio/gpio.txt and ../interrupt-controller/interrupts.txt for
+a general description of GPIO and interrupt bindings.
+
+Please refer to pinctrl-bindings.txt in this directory for details of the
+common pinctrl bindings used by client devices.
+
+Subnode format
+Each node (or subnode) will list the pins it needs and how to configured these
+pins.
+
+	node {
+		pinmux = <PIN_NUMBER_PINMUX>;
+		GENERIC_PINCONFIG;
+	};
+
+Required properties:
+- pinmux: integer array. Each integer represents a pin number plus mux and
+ioset settings. Use the macros from boot/dts/<soc>-pinfunc.h file to get the
+right representation of the pin.
+
+Optional properties:
+- GENERIC_PINCONFIG: generic pinconfig options to use, bias-disable,
+bias-pull-down, bias-pull-up, drive-open-drain, input-schmitt-enable,
+input-debounce, output-low, output-high.
+
+Example:
+
+#include <sama5d2-pinfunc.h>
+
+...
+{
+	pioA: pinctrl at fc038000 {
+		compatible = "atmel,sama5d2-pinctrl";
+		reg = <0xfc038000 0x600>;
+		interrupts = <18 IRQ_TYPE_LEVEL_HIGH 7>,
+			     <68 IRQ_TYPE_LEVEL_HIGH 7>,
+			     <69 IRQ_TYPE_LEVEL_HIGH 7>,
+			     <70 IRQ_TYPE_LEVEL_HIGH 7>;
+		interrupt-controller;
+		#interrupt-cells = <2>;
+		gpio-controller;
+		#gpio-cells = <2>;
+		clocks = <&pioA_clk>;
+
+		pinctrl_i2c0_default: i2c0_default {
+			pinmux = <PIN_PD21__TWD0>,
+				 <PIN_PD22__TWCK0>;
+			bias-disable;
+		};
+
+		pinctrl_led_gpio_default: led_gpio_default {
+			pinmux = <PIN_PB0>,
+				 <PIN_PB5>;
+			bias-pull-up;
+		};
+
+		pinctrl_sdmmc1_default: sdmmc1_default {
+			cmd_data {
+				pinmux = <PIN_PA28__SDMMC1_CMD>,
+					 <PIN_PA18__SDMMC1_DAT0>,
+					 <PIN_PA19__SDMMC1_DAT1>,
+					 <PIN_PA20__SDMMC1_DAT2>,
+					 <PIN_PA21__SDMMC1_DAT3>;
+				bias-pull-up;
+			};
+
+			ck_cd {
+				pinmux = <PIN_PA22__SDMMC1_CK>,
+					 <PIN_PA30__SDMMC1_CD>;
+				bias-disable;
+			};
+		};
+		...
+	};
+};
+...
-- 
2.5.0



From ludovic.desroches at atmel.com  Tue Aug 11 01:28:03 2015
From: ludovic.desroches at atmel.com (Ludovic Desroches)
Date: Tue, 11 Aug 2015 10:28:03 +0200
Subject: [PATCH 3/5] MAINTAINERS: Add an entry for pinctrl-at91-pio4
In-Reply-To: <1439281685-3020-1-git-send-email-ludovic.desroches@atmel.com>
References: <1439281685-3020-1-git-send-email-ludovic.desroches@atmel.com>
Message-ID: <1439281685-3020-4-git-send-email-ludovic.desroches@atmel.com>

Add an entry for the Atmel PIO4 controller driver.

Signed-off-by: Ludovic Desroches <ludovic.desroches at atmel.com>
---
 MAINTAINERS | 7 +++++++
 1 file changed, 7 insertions(+)

diff --git a/MAINTAINERS b/MAINTAINERS
index 8b37fdf..62c243a 100644
--- a/MAINTAINERS
+++ b/MAINTAINERS
@@ -8041,6 +8041,13 @@ L:	linux-arm-kernel at lists.infradead.org (moderated for non-subscribers)
 S:	Maintained
 F:	drivers/pinctrl/pinctrl-at91.*
 
+PIN CONTROLLER - ATMEL AT91 PIO4
+M:	Ludovic Desroches <ludovic.desroches at atmel.com>
+L:	linux-arm-kernel at lists.infradead.org (moderated for non-subscribers)
+L:	linux-gpio at vger.kernel.org
+S:	Supported
+F:	drivers/pinctrl/pinctrl-at91-pio4.*
+
 PIN CONTROLLER - INTEL
 M:	Mika Westerberg <mika.westerberg at linux.intel.com>
 M:	Heikki Krogerus <heikki.krogerus at linux.intel.com>
-- 
2.5.0



From ludovic.desroches at atmel.com  Tue Aug 11 01:28:04 2015
From: ludovic.desroches at atmel.com (Ludovic Desroches)
Date: Tue, 11 Aug 2015 10:28:04 +0200
Subject: [PATCH 4/5] ARM: at91/dt: sama5d2: add pio controller node
In-Reply-To: <1439281685-3020-1-git-send-email-ludovic.desroches@atmel.com>
References: <1439281685-3020-1-git-send-email-ludovic.desroches@atmel.com>
Message-ID: <1439281685-3020-5-git-send-email-ludovic.desroches@atmel.com>

Add pio4 controller node to enable pinmux and gpio.

Signed-off-by: Ludovic Desroches <ludovic.desroches at atmel.com>
---
 arch/arm/boot/dts/sama5d2.dtsi | 14 ++++++++++++++
 1 file changed, 14 insertions(+)

diff --git a/arch/arm/boot/dts/sama5d2.dtsi b/arch/arm/boot/dts/sama5d2.dtsi
index f39258f..55df0ae 100644
--- a/arch/arm/boot/dts/sama5d2.dtsi
+++ b/arch/arm/boot/dts/sama5d2.dtsi
@@ -920,6 +920,20 @@
 				clocks = <&twi1_clk>;
 				status = "disabled";
 			};
+
+			pioA: pinctrl at fc038000 {
+				compatible = "atmel,sama5d2-pinctrl";
+				reg = <0xfc038000 0x600>;
+				interrupts = <18 IRQ_TYPE_LEVEL_HIGH 7>,
+					     <68 IRQ_TYPE_LEVEL_HIGH 7>,
+					     <69 IRQ_TYPE_LEVEL_HIGH 7>,
+					     <70 IRQ_TYPE_LEVEL_HIGH 7>;
+				interrupt-controller;
+				#interrupt-cells = <2>;
+				gpio-controller;
+				#gpio-cells = <2>;
+				clocks = <&pioA_clk>;
+			};
 		};
 	};
 };
-- 
2.5.0



From ludovic.desroches at atmel.com  Tue Aug 11 01:28:05 2015
From: ludovic.desroches at atmel.com (Ludovic Desroches)
Date: Tue, 11 Aug 2015 10:28:05 +0200
Subject: [PATCH 5/5] ARM: at91/defconfig: sama5: add PIO4 controller support
In-Reply-To: <1439281685-3020-1-git-send-email-ludovic.desroches@atmel.com>
References: <1439281685-3020-1-git-send-email-ludovic.desroches@atmel.com>
Message-ID: <1439281685-3020-6-git-send-email-ludovic.desroches@atmel.com>

SAMA5D2 chip family has a new PIO controller.

Signed-off-by: Ludovic Desroches <ludovic.desroches at atmel.com>
---
 arch/arm/mach-at91/Kconfig | 1 +
 1 file changed, 1 insertion(+)

diff --git a/arch/arm/mach-at91/Kconfig b/arch/arm/mach-at91/Kconfig
index 89a755b..9e4067c 100644
--- a/arch/arm/mach-at91/Kconfig
+++ b/arch/arm/mach-at91/Kconfig
@@ -5,6 +5,7 @@ menuconfig ARCH_AT91
 	select COMMON_CLK_AT91
 	select PINCTRL
 	select PINCTRL_AT91
+	select PINCTRL_AT91PIO4
 	select SOC_BUS
 
 if ARCH_AT91
-- 
2.5.0



From djkurtz at chromium.org  Tue Aug 11 01:32:38 2015
From: djkurtz at chromium.org (Daniel Kurtz)
Date: Tue, 11 Aug 2015 16:32:38 +0800
Subject: [PATCH v2 1/2] i2c: mediatek: Reset DMA engine in hardware init
 function
In-Reply-To: <1438845731-17805-2-git-send-email-eddie.huang@mediatek.com>
References: <1438845731-17805-1-git-send-email-eddie.huang@mediatek.com>
 <1438845731-17805-2-git-send-email-eddie.huang@mediatek.com>
Message-ID: <CAGS+omAXRz5obq3si1tOdT5JSLB6m8XcdaN2VGpaLbuqMyqVGw@mail.gmail.com>

On Thu, Aug 6, 2015 at 3:22 PM, Eddie Huang <eddie.huang at mediatek.com> wrote:
> Reset DMA in hardware init function to avoid unknown hardware state
> before do any I2C operation.
>
> Signed-off-by: Liguo Zhang <liguo.zhang at mediatek.com>
> Signed-off-by: Eddie Huang <eddie.huang at mediatek.com>

Reviewed-by: Daniel Kurtz <djkurtz at chromium.org>

> ---
>  drivers/i2c/busses/i2c-mt65xx.c |    6 ++++++
>  1 file changed, 6 insertions(+)
>
> diff --git a/drivers/i2c/busses/i2c-mt65xx.c b/drivers/i2c/busses/i2c-mt65xx.c
> index 9920eef..e28ad4c 100644
> --- a/drivers/i2c/busses/i2c-mt65xx.c
> +++ b/drivers/i2c/busses/i2c-mt65xx.c
> @@ -59,6 +59,7 @@
>  #define I2C_DMA_START_EN               0x0001
>  #define I2C_DMA_INT_FLAG_NONE          0x0000
>  #define I2C_DMA_CLR_FLAG               0x0000
> +#define I2C_DMA_HARD_RST               0x0002
>
>  #define I2C_DEFAULT_SPEED              100000  /* hz */
>  #define MAX_FS_MODE_SPEED              400000
> @@ -81,6 +82,7 @@ enum DMA_REGS_OFFSET {
>         OFFSET_INT_FLAG = 0x0,
>         OFFSET_INT_EN = 0x04,
>         OFFSET_EN = 0x08,
> +       OFFSET_RST = 0x0c,
>         OFFSET_CON = 0x18,
>         OFFSET_TX_MEM_ADDR = 0x1c,
>         OFFSET_RX_MEM_ADDR = 0x20,
> @@ -262,6 +264,10 @@ static void mtk_i2c_init_hw(struct mtk_i2c *i2c)
>                       I2C_CONTROL_CLK_EXT_EN | I2C_CONTROL_DMA_EN;
>         writew(control_reg, i2c->base + OFFSET_CONTROL);
>         writew(I2C_DELAY_LEN, i2c->base + OFFSET_DELAY_LEN);
> +
> +       writel(I2C_DMA_HARD_RST, i2c->pdmabase + OFFSET_RST);
> +       udelay(50);
> +       writel(I2C_DMA_CLR_FLAG, i2c->pdmabase + OFFSET_RST);
>  }
>
>  /*
> --
> 1.7.9.5
>
> --
> To unsubscribe from this list: send the line "unsubscribe linux-kernel" in
> the body of a message to majordomo at vger.kernel.org
> More majordomo info at  http://vger.kernel.org/majordomo-info.html
> Please read the FAQ at  http://www.tux.org/lkml/


From djkurtz at chromium.org  Tue Aug 11 01:32:54 2015
From: djkurtz at chromium.org (Daniel Kurtz)
Date: Tue, 11 Aug 2015 16:32:54 +0800
Subject: [PATCH v2 2/2] i2c: mediatek: Fixup i2c ack error interrupt
 handling
In-Reply-To: <1438845731-17805-3-git-send-email-eddie.huang@mediatek.com>
References: <1438845731-17805-1-git-send-email-eddie.huang@mediatek.com>
 <1438845731-17805-3-git-send-email-eddie.huang@mediatek.com>
Message-ID: <CAGS+omDgCr7Ap3qBsav5AG-1g=+UjCM4ayRP-S0DKPbuKUH=Eg@mail.gmail.com>

On Thu, Aug 6, 2015 at 3:22 PM, Eddie Huang <eddie.huang at mediatek.com> wrote:
> When occur i2c ack error, i2c controller generate two interrupts,
> first is the ack error interrupt, then the complete interrupt.
> i2c interrupt handler should keep the two interrupt value, and only
> call complete() for the complete interrupt.
>
> Signed-off-by: Liguo Zhang <liguo.zhang at mediatek.com>
> Signed-off-by: Eddie Huang <eddie.huang at mediatek.com>

Reviewed-by: Daniel Kurtz <djkurtz at chromium.org>

> ---
>  drivers/i2c/busses/i2c-mt65xx.c |   15 +++++++++++----
>  1 file changed, 11 insertions(+), 4 deletions(-)
>
> diff --git a/drivers/i2c/busses/i2c-mt65xx.c b/drivers/i2c/busses/i2c-mt65xx.c
> index e28ad4c..c02e6c0 100644
> --- a/drivers/i2c/busses/i2c-mt65xx.c
> +++ b/drivers/i2c/busses/i2c-mt65xx.c
> @@ -557,15 +557,22 @@ static irqreturn_t mtk_i2c_irq(int irqno, void *dev_id)
>  {
>         struct mtk_i2c *i2c = dev_id;
>         u16 restart_flag = 0;
> +       u16 intr_stat;
>
>         if (i2c->dev_comp->auto_restart)
>                 restart_flag = I2C_RS_TRANSFER;
>
> -       i2c->irq_stat = readw(i2c->base + OFFSET_INTR_STAT);
> -       writew(restart_flag | I2C_HS_NACKERR | I2C_ACKERR
> -               | I2C_TRANSAC_COMP, i2c->base + OFFSET_INTR_STAT);
> +       intr_stat = readw(i2c->base + OFFSET_INTR_STAT);
> +       writew(intr_stat, i2c->base + OFFSET_INTR_STAT);
>
> -       complete(&i2c->msg_complete);
> +       /*
> +        * when occurs ack error, i2c controller generate two interrupts
> +        * first is the ack error interrupt, then the complete interrupt
> +        * i2c->irq_stat need keep the two interrupt value.
> +        */
> +       i2c->irq_stat |= intr_stat;
> +       if (i2c->irq_stat & (I2C_TRANSAC_COMP | restart_flag))
> +               complete(&i2c->msg_complete);
>
>         return IRQ_HANDLED;
>  }
> --
> 1.7.9.5
>
> --
> To unsubscribe from this list: send the line "unsubscribe linux-kernel" in
> the body of a message to majordomo at vger.kernel.org
> More majordomo info at  http://vger.kernel.org/majordomo-info.html
> Please read the FAQ at  http://www.tux.org/lkml/


From 21cnbao at gmail.com  Tue Aug 11 01:41:32 2015
From: 21cnbao at gmail.com (Barry Song)
Date: Tue, 11 Aug 2015 08:41:32 +0000
Subject: [PATCH 1/2] mmc: core: enable CMD19 tuning for DDR50 mode
Message-ID: <1439282492-6274-1-git-send-email-21cnbao@gmail.com>

From: Weijun Yang <york.yang at csr.com>

As SD Specifications Part1 Physical Layer Specification Version
3.01 says, CMD19 tuning is available for unlocked cards in transfer
state of 1.8V signaling mode. The small difference between v3.00
and 3.01 spec means that CMD19 tuning is also available for DDR50
mode.

Signed-off-by: Weijun Yang <york.yang at csr.com>
Signed-off-by: Barry Song <Baohua.Song at csr.com>
---
 drivers/mmc/core/sd.c    | 1 +
 drivers/mmc/host/sdhci.c | 1 +
 2 files changed, 2 insertions(+)

diff --git a/drivers/mmc/core/sd.c b/drivers/mmc/core/sd.c
index 4e7366a..a1ed24d 100644
--- a/drivers/mmc/core/sd.c
+++ b/drivers/mmc/core/sd.c
@@ -629,6 +629,7 @@ static int mmc_sd_init_uhs_card(struct mmc_card *card)
 	 */
 	if (!mmc_host_is_spi(card->host) &&
 	    (card->sd_bus_speed == UHS_SDR50_BUS_SPEED ||
+	     card->sd_bus_speed == UHS_DDR50_BUS_SPEED ||
 	     card->sd_bus_speed == UHS_SDR104_BUS_SPEED))
 		err = mmc_execute_tuning(card);
 out:
diff --git a/drivers/mmc/host/sdhci.c b/drivers/mmc/host/sdhci.c
index 1dbe932..812c19b 100644
--- a/drivers/mmc/host/sdhci.c
+++ b/drivers/mmc/host/sdhci.c
@@ -1891,6 +1891,7 @@ static int sdhci_execute_tuning(struct mmc_host *mmc, u32 opcode)
 		break;
 
 	case MMC_TIMING_UHS_SDR104:
+	case MMC_TIMING_UHS_DDR50:
 		break;
 
 	case MMC_TIMING_UHS_SDR50:
-- 
1.9.1



From 21cnbao at gmail.com  Tue Aug 11 01:42:47 2015
From: 21cnbao at gmail.com (Barry Song)
Date: Tue, 11 Aug 2015 08:42:47 +0000
Subject: [PATCH 2/2] mmc: sirf: fix the capbility to support DDR50
Message-ID: <1439282567-6362-1-git-send-email-21cnbao@gmail.com>

From: Weijun Yang <york.yang at csr.com>

According to hardware spec, validate DDR50 mode
for SDXC.

Signed-off-by: Weijun Yang <york.yang at csr.com>
Signed-off-by: Barry Song <Baohua.Song at csr.com>
---
 drivers/mmc/host/sdhci-sirf.c | 3 ++-
 1 file changed, 2 insertions(+), 1 deletion(-)

diff --git a/drivers/mmc/host/sdhci-sirf.c b/drivers/mmc/host/sdhci-sirf.c
index 0110bae..03efcfc 100644
--- a/drivers/mmc/host/sdhci-sirf.c
+++ b/drivers/mmc/host/sdhci-sirf.c
@@ -50,7 +50,8 @@ static u32 sdhci_sirf_readl_le(struct sdhci_host *host, int reg)
 	if (unlikely((reg == SDHCI_CAPABILITIES_1) &&
 			(host->mmc->caps & MMC_CAP_UHS_SDR50))) {
 		/* fake CAP_1 register */
-		val = SDHCI_SUPPORT_SDR50 | SDHCI_USE_SDR50_TUNING;
+		val = SDHCI_SUPPORT_DDR50 |
+			SDHCI_SUPPORT_SDR50 | SDHCI_USE_SDR50_TUNING;
 	}
 
 	if (unlikely(reg == SDHCI_SLOT_INT_STATUS)) {
-- 
1.9.1



From Suzuki.Poulose at arm.com  Tue Aug 11 01:41:01 2015
From: Suzuki.Poulose at arm.com (Suzuki K. Poulose)
Date: Tue, 11 Aug 2015 09:41:01 +0100
Subject: [RFC PATCH 01/10] arm64: feature registers: Documentation
In-Reply-To: <55C8EB17.7090708@redhat.com>
References: <1437731037-25795-1-git-send-email-suzuki.poulose@arm.com>
 <1437731037-25795-2-git-send-email-suzuki.poulose@arm.com>
 <20150810160636.GB15394@e104818-lin.cambridge.arm.com>
 <55C8E12E.6030305@arm.com> <55C8EB17.7090708@redhat.com>
Message-ID: <55C9B51D.1060601@arm.com>

On 10/08/15 19:19, Andrew Haley wrote:
> On 08/10/2015 06:36 PM, Suzuki K. Poulose wrote:
>> On 10/08/15 17:06, Catalin Marinas wrote:
>>> Hi Suzuki,
>>>
>>> On Fri, Jul 24, 2015 at 10:43:47AM +0100, Suzuki K. Poulose wrote:
>>>> From: "Suzuki K. Poulose" <suzuki.poulose at arm.com>
>>>>
>>>> Documentation of the infrastructure
>>>>
>>>> Signed-off-by: Suzuki K. Poulose <suzuki.poulose at arm.com>
>>>
>>> The implementation looks fine but I think the main discussion will be
>>> around the goal of this feature and the ABI that it introduces. So I'll
>>> just write my thoughts on this patch (I could as well have replied to
>>> the cover letter).
>>>
>>> Another question: who's going to use this feature? I know people asked
>>> in private but I'd like to have some public statements.
>>
>> Right, I am hoping that folks from glibc / JIT / GCC will respond to
>> this thread.
>
> We certainly need it for OpenJDK.  We need to know the manufacturer,
> part number, revision id, etc.  We already have workarounds in
> OpenJDK for various bugs, and we also can generate better code if we
> know the exact part.

OK.

>
> I note that the REVIDR is not in this patch.  That seems odd, because
> it can be used to identify minor revisions.

The REVIDR has to be used in conjunction with the MIDR to make real sense.
We cannot guarantee that the REVIDR that we read (would) belong to the CPU
where MIDR would have been read (unless the process is pinned) and hence the
user may not be able to make any use of the information. Steve has a patch [1]
to expose the MIDR,REVIDR info via sysfs.

[1] https://lkml.org/lkml/2015/7/24/420

Thanks
Suzuki

>
> Andrew.
>
>



From ian.campbell at citrix.com  Tue Aug 11 01:47:14 2015
From: ian.campbell at citrix.com (Ian Campbell)
Date: Tue, 11 Aug 2015 09:47:14 +0100
Subject: [PATCH v4] dtb: Create a common home for cross-architecture
 dtsi files.
In-Reply-To: <CAK7LNARyEbnOWTis0Nx9zwTcwH_s3GZKg2XYG3+zLnf=FhhctA@mail.gmail.com>
References: <1438617993-1012-1-git-send-email-ian.campbell@citrix.com>
 <CAK7LNARyEbnOWTis0Nx9zwTcwH_s3GZKg2XYG3+zLnf=FhhctA@mail.gmail.com>
Message-ID: <1439282834.9747.189.camel@citrix.com>

On Tue, 2015-08-11 at 13:00 +0900, Masahiro Yamada wrote:
> Hi
> 
> 2015-08-04 1:06 GMT+09:00 Ian Campbell <ian.campbell at citrix.com>:
> > Commit 9ccd608070b6 ("arm64: dts: add device tree for ARM SMM-A53x2 on
> > LogicTile Express 20MG") added a new dts file to arch/arm64 which
> > included "../../../../arm/boot/dts/vexpress-v2m-rs1.dtsi", i.e. a
> > .dtsi supplied by arch/arm.
> > 
> > Unfortunately this causes some issues for the split device tree
> > repository[0], since things get moved around there. In that context
> > the new .dts ends up at src/arm64/arm/vexpress-v2f-1xv7-ca53x2.dts
> > while the include is at src/arm/vexpress-v2m-rs1.dtsi.
> > 
> > The sharing of the .dtsi is legitimate since the baseboard is the same
> > for various vexpress systems whatever processor they use.
> > 
> > Rather than using ../../ tricks to pickup .dtsi files from another
> > arch this patch creates a new directory kernel/dts as a home for such
> > cross-arch .dtsi files and arranges for it to be in the include path
> > for both dtc and cpp. The dtsi file itself is moved into a vendor
> > subdir in this case "arm" (the vendor, not the ARCH=).
> 
> 
> Question:
> If this patch is applied, which directory will be created in
> device-tree-rebasing?
> src/kernel/, src/common/, or something else?
> Either will do, of course.

Below is the patch against the device-tree-rebasing.git, I went (pretty
much arbitrarily) with common at the top level.

commit 0524b00e5bd7b98a2a9ef85c1f5f2a8d93bcbeb6
Author: Ian Campbell <ian.campbell at citrix.com>
Date:   Tue Jul 21 17:27:13 2015 +0100

    Handle new kernel/dts subtree.
    
    Rewrite its contents to common/ and include in the CPP and DTC include
    paths.
    
    Signed-off-by: Ian Campbell <ian.campbell at citrix.com>

diff --git a/Makefile b/Makefile
index 5e8930c..b57107d 100644
--- a/Makefile
+++ b/Makefile
@@ -114,12 +114,13 @@ dtc-tmp = $(subst $(comma),_,$(dot-target).dts.tmp)
 
 dtc_cpp_flags  = -Wp,-MD,$(depfile).pre.tmp -nostdinc	\
                  -Iinclude -I$(src) -Itestcase-data	\
+                 -Icommon				\
                  -undef -D__DTS__
 
 quiet_cmd_dtc = DTC     $@
 cmd_dtc = $(CPP) $(dtc_cpp_flags) -x assembler-with-cpp -o $(dtc-tmp) $< ; \
         $(DTC) -O dtb -o $@ -b 0 \
-                -i $(src) $(DTC_FLAGS) \
+                -i $(src) -i common $(DTC_FLAGS) \
                 -d $(depfile).dtc.tmp $(dtc-tmp) ; \
         cat $(depfile).pre.tmp $(depfile).dtc.tmp > $(depfile)
 
diff --git a/scripts/rewrite-paths.sed b/scripts/rewrite-paths.sed
index b73fbce..5269769 100644
--- a/scripts/rewrite-paths.sed
+++ b/scripts/rewrite-paths.sed
@@ -33,6 +33,7 @@ s,\tarch/\([^/]*\)/boot/dts/\(.*\.h\)$,\tsrc/\1/\2,gp
 # Also rewrite the DTS include paths for dtc+cpp support
 s,\tarch/\([^/]*\)/include/dts/,\tsrc/\1/include/,gp
 s,\tinclude/dt-bindings/,\tinclude/dt-bindings/,gp
+s,\tkernel/dts/,\tcommon/,gp
 
 # Rewrite the bindings subdirectory
 s,\tDocumentation/devicetree/bindings/,\tBindings/,gp



From aph at redhat.com  Tue Aug 11 01:58:00 2015
From: aph at redhat.com (Andrew Haley)
Date: Tue, 11 Aug 2015 09:58:00 +0100
Subject: [RFC PATCH 01/10] arm64: feature registers: Documentation
In-Reply-To: <55C9B51D.1060601@arm.com>
References: <1437731037-25795-1-git-send-email-suzuki.poulose@arm.com>
 <1437731037-25795-2-git-send-email-suzuki.poulose@arm.com>
 <20150810160636.GB15394@e104818-lin.cambridge.arm.com>
 <55C8E12E.6030305@arm.com> <55C8EB17.7090708@redhat.com>
 <55C9B51D.1060601@arm.com>
Message-ID: <55C9B918.90807@redhat.com>

On 11/08/15 09:41, Suzuki K. Poulose wrote:
> The REVIDR has to be used in conjunction with the MIDR to make real sense.

Sure, of course.

> We cannot guarantee that the REVIDR that we read (would) belong to the CPU
> where MIDR would have been read (unless the process is pinned) and hence the
> user may not be able to make any use of the information.

Well, yes, nothing is perfect.  The situation we're in now, for example,
is that if we see Cortex A57 we have to assume Cortex A53 and include
workarounds.  People might mix and match processors.  So it goes.

> Steve has a patch [1]
> to expose the MIDR,REVIDR info via sysfs.
> 
> [1] https://lkml.org/lkml/2015/7/24/420

OK.  As long as I can get at it I'm happy.

Andrew.



From shawnguo at kernel.org  Tue Aug 11 01:59:21 2015
From: shawnguo at kernel.org (Shawn Guo)
Date: Tue, 11 Aug 2015 16:59:21 +0800
Subject: [GIT PULL] i.MX clock updates for 4.2
Message-ID: <20150811085921.GB10035@tiger>

Hi Michael, Stephen,

The i.MX clock drivers were moved into drivers/clk/imx folder since
v4.2-rc1, so I would like to send i.MX clock changes through clock tree
from this cycle.  Here is my first pull request to you guys.  I'm using
signed tags, same as how I work with arm-soc folks.  Let me know if
there is any problem with it.

Also, please keep it stable, because I need to pull it into other
branch as dependency which I will send via arm-soc tree.

Thanks,
Shawn

The following changes since commit d770e558e21961ad6cfdf0ff7df0eb5d7d4f0754:

  Linux 4.2-rc1 (2015-07-05 11:01:52 -0700)

are available in the git repository at:

  git://git.kernel.org/pub/scm/linux/kernel/git/shawnguo/linux.git tags/imx-clk-4.3

for you to fetch changes up to 3713e3f5e9274bbe52e94716bde303071364c1ed:

  clk: imx35: define two clocks for rtc (2015-08-05 20:01:21 +0800)

----------------------------------------------------------------
The i.MX clock updates for 4.3:
 - Provide a better IPU clock initial settings on imx6dl for getting
   HDMI and LVDS at the same time.
 - Add clock driver support for i.MX6UL SoC
 - Add a second clock for RTC device on i.MX31 and i.MX35

----------------------------------------------------------------
Fabio Estevam (1):
      clk: imx: clk-imx6q: Provide initial IPU clock settings for mx6dl

Frank Li (1):
      clk: imx: add imx6ul clk tree support

Philippe Reynes (2):
      clk: imx31: add a second rtc clock
      clk: imx35: define two clocks for rtc

 drivers/clk/imx/Makefile                 |   1 +
 drivers/clk/imx/clk-imx31.c              |   3 +-
 drivers/clk/imx/clk-imx35.c              |   6 +-
 drivers/clk/imx/clk-imx6q.c              |   4 +
 drivers/clk/imx/clk-imx6ul.c             | 432 +++++++++++++++++++++++++++++++
 include/dt-bindings/clock/imx6ul-clock.h | 240 +++++++++++++++++
 6 files changed, 684 insertions(+), 2 deletions(-)
 create mode 100644 drivers/clk/imx/clk-imx6ul.c
 create mode 100644 include/dt-bindings/clock/imx6ul-clock.h


From broonie at kernel.org  Tue Aug 11 02:03:42 2015
From: broonie at kernel.org (Mark Brown)
Date: Tue, 11 Aug 2015 10:03:42 +0100
Subject: [RESEND][PATCH 3/4] ARM: davinci: Set proper SPI prescale limit
 value
In-Reply-To: <55C99D0D.9050605@ti.com>
References: <1437568344-18889-1-git-send-email-fcooper@ti.com>
 <1437568344-18889-4-git-send-email-fcooper@ti.com>
 <55B22681.3060000@ti.com> <55C9380D.1060802@ti.com>
 <55C99D0D.9050605@ti.com>
Message-ID: <20150811090342.GG10748@sirena.org.uk>

On Tue, Aug 11, 2015 at 12:28:21PM +0530, Sekhar Nori wrote:
> On Tuesday 11 August 2015 05:17 AM, Franklin S Cooper Jr. wrote:

> > ping. Patches 1 and 2 have already been pulled into Mark's spi tree and are currently in in linux-next.

> Mark, can you apply this patch to your tree as well? Thats the preferred
> route for me.

> If thats not an option for you, can you confirm that the topic/davinci
> branch of your spi tree is an immutable commit I can base my pull
> request to ARM-SoC on?

Why would there be any interdependency between the the two trees, that
would be very unusual?  Adding a new value to DT doesn't need the kernel
to understand it and the driver should be compatible with existing DTs.
If there *is* some dependency that suggests the driver update has
problems...

In any case I don't have a copy of the patch any more.
-------------- next part --------------
A non-text attachment was scrubbed...
Name: signature.asc
Type: application/pgp-signature
Size: 473 bytes
Desc: Digital signature
URL: <http://lists.infradead.org/pipermail/linux-arm-kernel/attachments/20150811/7da1cd5e/attachment.sig>

From maitysanchayan at gmail.com  Tue Aug 11 02:05:00 2015
From: maitysanchayan at gmail.com (Sanchayan Maity)
Date: Tue, 11 Aug 2015 14:35:00 +0530
Subject: [PATCH v3] Add continuous sampling with IIO buffers for Vybrid
Message-ID: <cover.1439283162.git.maitysanchayan@gmail.com>

Hello,

This patch adds support for continuous sampling provided by the
ADC block on Vybrid by leveraging the IIO triggered buffers
infrastructure.

The patch has been tested on Colibri VF50 and VF61 on shawn's
tree for-next branch with the patches [1] and [2] applied.

The below script was used for testing.

#!/bin/sh
echo 0 > /sys/bus/iio/devices/iio:device0/scan_elements/in_voltage8_en
echo 0 > /sys/bus/iio/devices/iio:device0/scan_elements/in_voltage9_en
echo 1 > /sys/bus/iio/devices/iio:device0/scan_elements/in_temp_en
echo 1 > /sys/bus/iio/devices/iio:device0/scan_elements/in_timestamp_en
echo 0 > /sys/bus/iio/devices/iio_sysfs_trigger/add_trigger
/home/root/generic_buffer -n 4003b000.adc -t sysfstrig0 -l 512 -c 10
echo 0 > /sys/bus/iio/devices/iio:device0/scan_elements/in_timestamp_en
echo 0 > /sys/bus/iio/devices/iio:device0/scan_elements/in_temp_en
echo 0 > /sys/bus/iio/devices/iio:device0/scan_elements/in_voltage8_en
echo 0 > /sys/bus/iio/devices/iio:device0/scan_elements/in_voltage9_en

Feedback and comments are most welcome.

Changes since v2:
1. Fix the wrong buffer size for statically allocated buffer
2. Drop the use of .address field from the iio_chan_spec
3. Use iio_buffer_enabled call inside the lock
4. Drop wrapper function around iio_trigered_* function calls
5. Drop Kconfig select of sysfs trigger
6. Drop Kconfig select IIO_TRIGGER as it is already selected by
IIO_TRIGGERED_BUFFER

Changes since v1:
1. Use a fixed size buffer instead of kmalloc allocated during update
scan mode
2. Remove a write to read only register ADC_HS (COCO bit)

Version 2 patch can be found here
http://www.gossamer-threads.com/lists/linux/kernel/2235178

Version 1 patch can be found here
http://www.spinics.net/lists/linux-iio/msg20053.html

[1]. https://lkml.org/lkml/2015/5/27/350
[2]. https://lkml.org/lkml/2015/7/14/395

Thanks & Regards,
Sanchayan Maity.

Sanchayan Maity (1):
  iio: adc: vf610: Add IIO buffer support for Vybrid ADC

 drivers/iio/adc/Kconfig     |   2 +
 drivers/iio/adc/vf610_adc.c | 102 +++++++++++++++++++++++++++++++++++++++++---
 2 files changed, 97 insertions(+), 7 deletions(-)

-- 
2.5.0



From maitysanchayan at gmail.com  Tue Aug 11 02:05:01 2015
From: maitysanchayan at gmail.com (Sanchayan Maity)
Date: Tue, 11 Aug 2015 14:35:01 +0530
Subject: [PATCH v3] iio: adc: vf610: Add IIO buffer support for Vybrid ADC
In-Reply-To: <cover.1439283162.git.maitysanchayan@gmail.com>
References: <cover.1439283162.git.maitysanchayan@gmail.com>
Message-ID: <d556443a26070be505f9a5f5f0999253b73d9b71.1439283162.git.maitysanchayan@gmail.com>

This patch adds support for IIO buffer to the Vybrid ADC driver.
IIO triggered buffer infrastructure along with iio sysfs trigger
is used to leverage continuous sampling support provided by the
ADC block.

Signed-off-by: Sanchayan Maity <maitysanchayan at gmail.com>
---
 drivers/iio/adc/Kconfig     |   2 +
 drivers/iio/adc/vf610_adc.c | 102 +++++++++++++++++++++++++++++++++++++++++---
 2 files changed, 97 insertions(+), 7 deletions(-)

diff --git a/drivers/iio/adc/Kconfig b/drivers/iio/adc/Kconfig
index 7c55658..660f790 100644
--- a/drivers/iio/adc/Kconfig
+++ b/drivers/iio/adc/Kconfig
@@ -337,6 +337,8 @@ config TWL6030_GPADC
 config VF610_ADC
 	tristate "Freescale vf610 ADC driver"
 	depends on OF
+	select IIO_BUFFER
+	select IIO_TRIGGERED_BUFFER
 	help
 	  Say yes here to support for Vybrid board analog-to-digital converter.
 	  Since the IP is used for i.MX6SLX, the driver also support i.MX6SLX.
diff --git a/drivers/iio/adc/vf610_adc.c b/drivers/iio/adc/vf610_adc.c
index 23b8fb9..de62c48 100644
--- a/drivers/iio/adc/vf610_adc.c
+++ b/drivers/iio/adc/vf610_adc.c
@@ -34,8 +34,11 @@
 #include <linux/err.h>
 
 #include <linux/iio/iio.h>
+#include <linux/iio/buffer.h>
 #include <linux/iio/sysfs.h>
-#include <linux/iio/driver.h>
+#include <linux/iio/trigger.h>
+#include <linux/iio/trigger_consumer.h>
+#include <linux/iio/triggered_buffer.h>
 
 /* This will be the driver name the kernel reports */
 #define DRIVER_NAME "vf610-adc"
@@ -170,6 +173,7 @@ struct vf610_adc {
 	u32 sample_freq_avail[5];
 
 	struct completion completion;
+	u16 buffer[8];
 };
 
 static const u32 vf610_hw_avgs[] = { 1, 4, 8, 16, 32 };
@@ -505,12 +509,24 @@ static const struct iio_chan_spec_ext_info vf610_ext_info[] = {
 	.info_mask_shared_by_type = BIT(IIO_CHAN_INFO_SCALE) |	\
 				BIT(IIO_CHAN_INFO_SAMP_FREQ),	\
 	.ext_info = vf610_ext_info,				\
+	.scan_index = (_idx),			\
+	.scan_type = {					\
+		.sign = 'u',				\
+		.realbits = 12,				\
+		.storagebits = 16,			\
+	},						\
 }
 
 #define VF610_ADC_TEMPERATURE_CHAN(_idx, _chan_type) {	\
 	.type = (_chan_type),	\
 	.channel = (_idx),		\
 	.info_mask_separate = BIT(IIO_CHAN_INFO_PROCESSED),	\
+	.scan_index = (_idx),					\
+	.scan_type = {						\
+		.sign = 'u',					\
+		.realbits = 12,					\
+		.storagebits = 16,				\
+	},							\
 }
 
 static const struct iio_chan_spec vf610_adc_iio_channels[] = {
@@ -531,6 +547,7 @@ static const struct iio_chan_spec vf610_adc_iio_channels[] = {
 	VF610_ADC_CHAN(14, IIO_VOLTAGE),
 	VF610_ADC_CHAN(15, IIO_VOLTAGE),
 	VF610_ADC_TEMPERATURE_CHAN(26, IIO_TEMP),
+	IIO_CHAN_SOFT_TIMESTAMP(32),
 	/* sentinel */
 };
 
@@ -559,13 +576,20 @@ static int vf610_adc_read_data(struct vf610_adc *info)
 
 static irqreturn_t vf610_adc_isr(int irq, void *dev_id)
 {
-	struct vf610_adc *info = (struct vf610_adc *)dev_id;
+	struct iio_dev *indio_dev = (struct iio_dev *)dev_id;
+	struct vf610_adc *info = iio_priv(indio_dev);
 	int coco;
 
 	coco = readl(info->regs + VF610_REG_ADC_HS);
 	if (coco & VF610_ADC_HS_COCO0) {
 		info->value = vf610_adc_read_data(info);
-		complete(&info->completion);
+		if (iio_buffer_enabled(indio_dev)) {
+			info->buffer[0] = info->value;
+			iio_push_to_buffers_with_timestamp(indio_dev,
+					info->buffer, iio_get_time_ns());
+			iio_trigger_notify_done(indio_dev->trig);
+		} else
+			complete(&info->completion);
 	}
 
 	return IRQ_HANDLED;
@@ -613,8 +637,12 @@ static int vf610_read_raw(struct iio_dev *indio_dev,
 	case IIO_CHAN_INFO_RAW:
 	case IIO_CHAN_INFO_PROCESSED:
 		mutex_lock(&indio_dev->mlock);
-		reinit_completion(&info->completion);
+		if (iio_buffer_enabled(indio_dev)) {
+			mutex_unlock(&indio_dev->mlock);
+			return -EBUSY;
+		}
 
+		reinit_completion(&info->completion);
 		hc_cfg = VF610_ADC_ADCHC(chan->channel);
 		hc_cfg |= VF610_ADC_AIEN;
 		writel(hc_cfg, info->regs + VF610_REG_ADC_HC0);
@@ -694,6 +722,57 @@ static int vf610_write_raw(struct iio_dev *indio_dev,
 	return -EINVAL;
 }
 
+static int vf610_adc_buffer_postenable(struct iio_dev *indio_dev)
+{
+	struct vf610_adc *info = iio_priv(indio_dev);
+	unsigned int channel;
+	int ret;
+	int val;
+
+	ret = iio_triggered_buffer_postenable(indio_dev);
+	if (ret)
+		return ret;
+
+	val = readl(info->regs + VF610_REG_ADC_GC);
+	val |= VF610_ADC_ADCON;
+	writel(val, info->regs + VF610_REG_ADC_GC);
+
+	channel = find_first_bit(indio_dev->active_scan_mask,
+						indio_dev->masklength);
+
+	val = VF610_ADC_ADCHC(channel);
+	val |= VF610_ADC_AIEN;
+
+	writel(val, info->regs + VF610_REG_ADC_HC0);
+
+	return 0;
+}
+
+static int vf610_adc_buffer_postdisable(struct iio_dev *indio_dev)
+{
+	struct vf610_adc *info = iio_priv(indio_dev);
+	unsigned int hc_cfg = 0;
+	int val;
+
+	val = readl(info->regs + VF610_REG_ADC_GC);
+	val &= ~VF610_ADC_ADCON;
+	writel(val, info->regs + VF610_REG_ADC_GC);
+
+	hc_cfg |= VF610_ADC_CONV_DISABLE;
+	hc_cfg &= ~VF610_ADC_AIEN;
+
+	writel(hc_cfg, info->regs + VF610_REG_ADC_HC0);
+
+	return 0;
+}
+
+static const struct iio_buffer_setup_ops iio_triggered_buffer_setup_ops = {
+	.postenable = &vf610_adc_buffer_postenable,
+	.predisable = &iio_triggered_buffer_predisable,
+	.postdisable = &vf610_adc_buffer_postdisable,
+	.validate_scan_mask = &iio_validate_scan_mask_onehot,
+};
+
 static int vf610_adc_reg_access(struct iio_dev *indio_dev,
 			unsigned reg, unsigned writeval,
 			unsigned *readval)
@@ -753,7 +832,7 @@ static int vf610_adc_probe(struct platform_device *pdev)
 
 	ret = devm_request_irq(info->dev, irq,
 				vf610_adc_isr, 0,
-				dev_name(&pdev->dev), info);
+				dev_name(&pdev->dev), indio_dev);
 	if (ret < 0) {
 		dev_err(&pdev->dev, "failed requesting irq, irq = %d\n", irq);
 		return ret;
@@ -806,15 +885,23 @@ static int vf610_adc_probe(struct platform_device *pdev)
 	vf610_adc_cfg_init(info);
 	vf610_adc_hw_init(info);
 
+	ret = iio_triggered_buffer_setup(indio_dev, &iio_pollfunc_store_time,
+					NULL, &iio_triggered_buffer_setup_ops);
+	if (ret < 0) {
+		dev_err(&pdev->dev, "Couldn't initialise the buffer\n");
+		goto error_iio_device_register;
+	}
+
 	ret = iio_device_register(indio_dev);
 	if (ret) {
 		dev_err(&pdev->dev, "Couldn't register the device.\n");
-		goto error_iio_device_register;
+		goto error_adc_buffer_init;
 	}
 
 	return 0;
 
-
+error_adc_buffer_init:
+	iio_triggered_buffer_cleanup(indio_dev);
 error_iio_device_register:
 	clk_disable_unprepare(info->clk);
 error_adc_clk_enable:
@@ -829,6 +916,7 @@ static int vf610_adc_remove(struct platform_device *pdev)
 	struct vf610_adc *info = iio_priv(indio_dev);
 
 	iio_device_unregister(indio_dev);
+	iio_triggered_buffer_cleanup(indio_dev);
 	regulator_disable(info->vref);
 	clk_disable_unprepare(info->clk);
 
-- 
2.5.0



From alexandre.belloni at free-electrons.com  Tue Aug 11 02:12:48 2015
From: alexandre.belloni at free-electrons.com (Alexandre Belloni)
Date: Tue, 11 Aug 2015 11:12:48 +0200
Subject: [PATCH v3 3/5] power/reset: at91-reset: get and use slow clock
In-Reply-To: <1439284370-13803-1-git-send-email-alexandre.belloni@free-electrons.com>
References: <1439284370-13803-1-git-send-email-alexandre.belloni@free-electrons.com>
Message-ID: <1439284370-13803-4-git-send-email-alexandre.belloni@free-electrons.com>

Commit dca1a4b5ff6e ("clk: at91: keep slow clk enabled to prevent system
hang") added a workaround for the slow clock as it is not properly handled
by its users.

Get and use the slow clock as it is necessary for the at91 reset
controller.

Signed-off-by: Alexandre Belloni <alexandre.belloni at free-electrons.com>
---
 drivers/power/reset/at91-reset.c | 17 ++++++++++++++++-
 1 file changed, 16 insertions(+), 1 deletion(-)

diff --git a/drivers/power/reset/at91-reset.c b/drivers/power/reset/at91-reset.c
index 120f3dec9574..8f0bcb232149 100644
--- a/drivers/power/reset/at91-reset.c
+++ b/drivers/power/reset/at91-reset.c
@@ -11,6 +11,7 @@
  * warranty of any kind, whether express or implied.
  */
 
+#include <linux/clk.h>
 #include <linux/io.h>
 #include <linux/module.h>
 #include <linux/of_address.h>
@@ -46,6 +47,7 @@ enum reset_type {
 };
 
 static void __iomem *at91_ramc_base[2], *at91_rstc_base;
+static struct clk *sclk;
 
 /*
 * unless the SDRAM is cleanly shutdown before we hit the
@@ -193,9 +195,21 @@ static int __init at91_reset_probe(struct platform_device *pdev)
 	match = of_match_node(at91_reset_of_match, pdev->dev.of_node);
 	at91_restart_nb.notifier_call = match->data;
 
+	sclk = devm_clk_get(&pdev->dev, NULL);
+	if (IS_ERR(sclk))
+		return PTR_ERR(sclk);
+
+	ret = clk_prepare_enable(sclk);
+	if (ret) {
+		dev_err(&pdev->dev, "Could not enable slow clock\n");
+		return ret;
+	}
+
 	ret = register_restart_handler(&at91_restart_nb);
-	if (ret)
+	if (ret) {
+		clk_disable_unprepare(sclk);
 		return ret;
+	}
 
 	at91_reset_status(pdev);
 
@@ -205,6 +219,7 @@ static int __init at91_reset_probe(struct platform_device *pdev)
 static int __exit at91_reset_remove(struct platform_device *pdev)
 {
 	unregister_restart_handler(&at91_restart_nb);
+	clk_disable_unprepare(sclk);
 
 	return 0;
 }
-- 
2.1.4



From alexandre.belloni at free-electrons.com  Tue Aug 11 02:12:49 2015
From: alexandre.belloni at free-electrons.com (Alexandre Belloni)
Date: Tue, 11 Aug 2015 11:12:49 +0200
Subject: [PATCH v3 4/5] power/reset: at91-poweroff: allow compiling as a module
In-Reply-To: <1439284370-13803-1-git-send-email-alexandre.belloni@free-electrons.com>
References: <1439284370-13803-1-git-send-email-alexandre.belloni@free-electrons.com>
Message-ID: <1439284370-13803-5-git-send-email-alexandre.belloni@free-electrons.com>

It was not possible to compile at91-poweroff as a module. Implement
.remove() to allow it. Also switch to module_platform_driver_probe() as it
is not hotpluggable.

Signed-off-by: Alexandre Belloni <alexandre.belloni at free-electrons.com>
---
 drivers/power/reset/Kconfig         |  2 +-
 drivers/power/reset/at91-poweroff.c | 18 +++++++++++++++---
 2 files changed, 16 insertions(+), 4 deletions(-)

diff --git a/drivers/power/reset/Kconfig b/drivers/power/reset/Kconfig
index e41da4a80a05..b3c6191d1847 100644
--- a/drivers/power/reset/Kconfig
+++ b/drivers/power/reset/Kconfig
@@ -15,7 +15,7 @@ config POWER_RESET_AS3722
 	  This driver supports turning off board via a ams AS3722 power-off.
 
 config POWER_RESET_AT91_POWEROFF
-	bool "Atmel AT91 poweroff driver"
+	tristate "Atmel AT91 poweroff driver"
 	depends on ARCH_AT91
 	default SOC_AT91SAM9 || SOC_SAMA5
 	help
diff --git a/drivers/power/reset/at91-poweroff.c b/drivers/power/reset/at91-poweroff.c
index 9847cfb7e23d..3e698d916c4f 100644
--- a/drivers/power/reset/at91-poweroff.c
+++ b/drivers/power/reset/at91-poweroff.c
@@ -119,7 +119,7 @@ static void at91_poweroff_dt_set_wakeup_mode(struct platform_device *pdev)
 	writel(wakeup_mode | mode, at91_shdwc_base + AT91_SHDW_MR);
 }
 
-static int at91_poweroff_probe(struct platform_device *pdev)
+static int __init at91_poweroff_probe(struct platform_device *pdev)
 {
 	struct resource *res;
 
@@ -140,6 +140,14 @@ static int at91_poweroff_probe(struct platform_device *pdev)
 	return 0;
 }
 
+static int __exit at91_poweroff_remove(struct platform_device *pdev)
+{
+	if (pm_power_off == at91_poweroff)
+		pm_power_off = NULL;
+
+	return 0;
+}
+
 static const struct of_device_id at91_poweroff_of_match[] = {
 	{ .compatible = "atmel,at91sam9260-shdwc", },
 	{ .compatible = "atmel,at91sam9rl-shdwc", },
@@ -148,10 +156,14 @@ static const struct of_device_id at91_poweroff_of_match[] = {
 };
 
 static struct platform_driver at91_poweroff_driver = {
-	.probe = at91_poweroff_probe,
+	.remove = __exit_p(at91_poweroff_remove),
 	.driver = {
 		.name = "at91-poweroff",
 		.of_match_table = at91_poweroff_of_match,
 	},
 };
-module_platform_driver(at91_poweroff_driver);
+module_platform_driver_probe(at91_poweroff_driver, at91_poweroff_probe);
+
+MODULE_AUTHOR("Atmel Corporation");
+MODULE_DESCRIPTION("Shutdown driver for Atmel SoCs");
+MODULE_LICENSE("GPL v2");
-- 
2.1.4



From alexandre.belloni at free-electrons.com  Tue Aug 11 02:12:45 2015
From: alexandre.belloni at free-electrons.com (Alexandre Belloni)
Date: Tue, 11 Aug 2015 11:12:45 +0200
Subject: [PATCH v3 0/5] power/reset: at91: cleanups and slow clock
Message-ID: <1439284370-13803-1-git-send-email-alexandre.belloni@free-electrons.com>

Hi,

As discussed this series is now removing non DT initialization, allowing to
compile the drivers as modules and finally adding slow clock support to the
drivers.


Alexandre Belloni (5):
  power/reset: at91-reset: remove useless at91_reset_platform_probe()
  power/reset: at91-reset: allow compiling as a module
  power/reset: at91-reset: get and use slow clock
  power/reset: at91-poweroff: allow compiling as a module
  power/reset: at91-poweroff: get and use slow clock

 drivers/power/reset/Kconfig         |  4 +--
 drivers/power/reset/at91-poweroff.c | 33 ++++++++++++++++--
 drivers/power/reset/at91-reset.c    | 67 ++++++++++++++-----------------------
 3 files changed, 58 insertions(+), 46 deletions(-)

-- 
2.1.4



From alexandre.belloni at free-electrons.com  Tue Aug 11 02:12:46 2015
From: alexandre.belloni at free-electrons.com (Alexandre Belloni)
Date: Tue, 11 Aug 2015 11:12:46 +0200
Subject: [PATCH v3 1/5] power/reset: at91-reset: remove useless
 at91_reset_platform_probe()
In-Reply-To: <1439284370-13803-1-git-send-email-alexandre.belloni@free-electrons.com>
References: <1439284370-13803-1-git-send-email-alexandre.belloni@free-electrons.com>
Message-ID: <1439284370-13803-2-git-send-email-alexandre.belloni@free-electrons.com>

Since all the at91 platforms are now DT only, at91_reset_platform_probe()
is now useless, remove it.

Signed-off-by: Alexandre Belloni <alexandre.belloni at free-electrons.com>
---
 drivers/power/reset/at91-reset.c | 47 +++-------------------------------------
 1 file changed, 3 insertions(+), 44 deletions(-)

diff --git a/drivers/power/reset/at91-reset.c b/drivers/power/reset/at91-reset.c
index 36dc52fb2ec8..3225c8590ed0 100644
--- a/drivers/power/reset/at91-reset.c
+++ b/drivers/power/reset/at91-reset.c
@@ -169,11 +169,11 @@ static struct notifier_block at91_restart_nb = {
 	.priority = 192,
 };
 
-static int at91_reset_of_probe(struct platform_device *pdev)
+static int at91_reset_probe(struct platform_device *pdev)
 {
 	const struct of_device_id *match;
 	struct device_node *np;
-	int idx = 0;
+	int ret, idx = 0;
 
 	at91_rstc_base = of_iomap(pdev->dev.of_node, 0);
 	if (!at91_rstc_base) {
@@ -192,49 +192,8 @@ static int at91_reset_of_probe(struct platform_device *pdev)
 
 	match = of_match_node(at91_reset_of_match, pdev->dev.of_node);
 	at91_restart_nb.notifier_call = match->data;
-	return register_restart_handler(&at91_restart_nb);
-}
-
-static int at91_reset_platform_probe(struct platform_device *pdev)
-{
-	const struct platform_device_id *match;
-	struct resource *res;
-	int idx = 0;
-
-	res = platform_get_resource(pdev, IORESOURCE_MEM, 0);
-	at91_rstc_base = devm_ioremap_resource(&pdev->dev, res);
-	if (IS_ERR(at91_rstc_base)) {
-		dev_err(&pdev->dev, "Could not map reset controller address\n");
-		return PTR_ERR(at91_rstc_base);
-	}
-
-	for (idx = 0; idx < 2; idx++) {
-		res = platform_get_resource(pdev, IORESOURCE_MEM, idx + 1 );
-		at91_ramc_base[idx] = devm_ioremap(&pdev->dev, res->start,
-						   resource_size(res));
-		if (!at91_ramc_base[idx]) {
-			dev_err(&pdev->dev, "Could not map ram controller address\n");
-			return -ENOMEM;
-		}
-	}
-
-	match = platform_get_device_id(pdev);
-	at91_restart_nb.notifier_call =
-		(int (*)(struct notifier_block *,
-			 unsigned long, void *)) match->driver_data;
-
-	return register_restart_handler(&at91_restart_nb);
-}
-
-static int at91_reset_probe(struct platform_device *pdev)
-{
-	int ret;
-
-	if (pdev->dev.of_node)
-		ret = at91_reset_of_probe(pdev);
-	else
-		ret = at91_reset_platform_probe(pdev);
 
+	ret = register_restart_handler(&at91_restart_nb);
 	if (ret)
 		return ret;
 
-- 
2.1.4



From alexandre.belloni at free-electrons.com  Tue Aug 11 02:12:47 2015
From: alexandre.belloni at free-electrons.com (Alexandre Belloni)
Date: Tue, 11 Aug 2015 11:12:47 +0200
Subject: [PATCH v3 2/5] power/reset: at91-reset: allow compiling as a module
In-Reply-To: <1439284370-13803-1-git-send-email-alexandre.belloni@free-electrons.com>
References: <1439284370-13803-1-git-send-email-alexandre.belloni@free-electrons.com>
Message-ID: <1439284370-13803-3-git-send-email-alexandre.belloni@free-electrons.com>

It was not possible to compile at91-reset as a module. Implement .remove()
to allow it. Also switch to module_platform_driver_probe() as it is not
hotpluggable.

Signed-off-by: Alexandre Belloni <alexandre.belloni at free-electrons.com>
---
 drivers/power/reset/Kconfig      |  2 +-
 drivers/power/reset/at91-reset.c | 17 ++++++++++++++---
 2 files changed, 15 insertions(+), 4 deletions(-)

diff --git a/drivers/power/reset/Kconfig b/drivers/power/reset/Kconfig
index 17d93a73c513..e41da4a80a05 100644
--- a/drivers/power/reset/Kconfig
+++ b/drivers/power/reset/Kconfig
@@ -23,7 +23,7 @@ config POWER_RESET_AT91_POWEROFF
 	  SoCs
 
 config POWER_RESET_AT91_RESET
-	bool "Atmel AT91 reset driver"
+	tristate "Atmel AT91 reset driver"
 	depends on ARCH_AT91
 	default SOC_AT91SAM9 || SOC_SAMA5
 	help
diff --git a/drivers/power/reset/at91-reset.c b/drivers/power/reset/at91-reset.c
index 3225c8590ed0..120f3dec9574 100644
--- a/drivers/power/reset/at91-reset.c
+++ b/drivers/power/reset/at91-reset.c
@@ -169,7 +169,7 @@ static struct notifier_block at91_restart_nb = {
 	.priority = 192,
 };
 
-static int at91_reset_probe(struct platform_device *pdev)
+static int __init at91_reset_probe(struct platform_device *pdev)
 {
 	const struct of_device_id *match;
 	struct device_node *np;
@@ -202,6 +202,13 @@ static int at91_reset_probe(struct platform_device *pdev)
 	return 0;
 }
 
+static int __exit at91_reset_remove(struct platform_device *pdev)
+{
+	unregister_restart_handler(&at91_restart_nb);
+
+	return 0;
+}
+
 static const struct platform_device_id at91_reset_plat_match[] = {
 	{ "at91-sam9260-reset", (unsigned long)at91sam9260_restart },
 	{ "at91-sam9g45-reset", (unsigned long)at91sam9g45_restart },
@@ -209,11 +216,15 @@ static const struct platform_device_id at91_reset_plat_match[] = {
 };
 
 static struct platform_driver at91_reset_driver = {
-	.probe = at91_reset_probe,
+	.remove = __exit_p(at91_reset_remove),
 	.driver = {
 		.name = "at91-reset",
 		.of_match_table = at91_reset_of_match,
 	},
 	.id_table = at91_reset_plat_match,
 };
-module_platform_driver(at91_reset_driver);
+module_platform_driver_probe(at91_reset_driver, at91_reset_probe);
+
+MODULE_AUTHOR("Atmel Corporation");
+MODULE_DESCRIPTION("Reset driver for Atmel SoCs");
+MODULE_LICENSE("GPL v2");
-- 
2.1.4



From alexandre.belloni at free-electrons.com  Tue Aug 11 02:12:50 2015
From: alexandre.belloni at free-electrons.com (Alexandre Belloni)
Date: Tue, 11 Aug 2015 11:12:50 +0200
Subject: [PATCH v3 5/5] power/reset: at91-poweroff: get and use slow clock
In-Reply-To: <1439284370-13803-1-git-send-email-alexandre.belloni@free-electrons.com>
References: <1439284370-13803-1-git-send-email-alexandre.belloni@free-electrons.com>
Message-ID: <1439284370-13803-6-git-send-email-alexandre.belloni@free-electrons.com>

Commit dca1a4b5ff6e ("clk: at91: keep slow clk enabled to prevent system
hang") added a workaround for the slow clock as it is not properly handled
by its users.

Get and use the slow clock as it is necessary for the at91 shutdown
controller.

Signed-off-by: Alexandre Belloni <alexandre.belloni at free-electrons.com>
---
 drivers/power/reset/at91-poweroff.c | 15 +++++++++++++++
 1 file changed, 15 insertions(+)

diff --git a/drivers/power/reset/at91-poweroff.c b/drivers/power/reset/at91-poweroff.c
index 3e698d916c4f..e9e24df35f26 100644
--- a/drivers/power/reset/at91-poweroff.c
+++ b/drivers/power/reset/at91-poweroff.c
@@ -10,6 +10,7 @@
  * warranty of any kind, whether express or implied.
  */
 
+#include <linux/clk.h>
 #include <linux/io.h>
 #include <linux/module.h>
 #include <linux/of.h>
@@ -48,6 +49,7 @@ static const char *shdwc_wakeup_modes[] = {
 };
 
 static void __iomem *at91_shdwc_base;
+static struct clk *sclk;
 
 static void __init at91_wakeup_status(void)
 {
@@ -122,6 +124,7 @@ static void at91_poweroff_dt_set_wakeup_mode(struct platform_device *pdev)
 static int __init at91_poweroff_probe(struct platform_device *pdev)
 {
 	struct resource *res;
+	int ret;
 
 	res = platform_get_resource(pdev, IORESOURCE_MEM, 0);
 	at91_shdwc_base = devm_ioremap_resource(&pdev->dev, res);
@@ -130,6 +133,16 @@ static int __init at91_poweroff_probe(struct platform_device *pdev)
 		return PTR_ERR(at91_shdwc_base);
 	}
 
+	sclk = devm_clk_get(&pdev->dev, NULL);
+	if (IS_ERR(sclk))
+		return PTR_ERR(sclk);
+
+	ret = clk_prepare_enable(sclk);
+	if (ret) {
+		dev_err(&pdev->dev, "Could not enable slow clock\n");
+		return ret;
+	}
+
 	at91_wakeup_status();
 
 	if (pdev->dev.of_node)
@@ -145,6 +158,8 @@ static int __exit at91_poweroff_remove(struct platform_device *pdev)
 	if (pm_power_off == at91_poweroff)
 		pm_power_off = NULL;
 
+	clk_disable_unprepare(sclk);
+
 	return 0;
 }
 
-- 
2.1.4



From eric.auger at linaro.org  Tue Aug 11 02:14:40 2015
From: eric.auger at linaro.org (Eric Auger)
Date: Tue, 11 Aug 2015 11:14:40 +0200
Subject: [PATCH 1/6] irqchip: GICv3: Convert to EOImode == 1
In-Reply-To: <1436447951-22357-2-git-send-email-marc.zyngier@arm.com>
References: <1436447951-22357-1-git-send-email-marc.zyngier@arm.com>
 <1436447951-22357-2-git-send-email-marc.zyngier@arm.com>
Message-ID: <55C9BD00.7030901@linaro.org>

Hi Marc,
On 07/09/2015 03:19 PM, Marc Zyngier wrote:
> So far, GICv3 has been used in with EOImode == 0. The effect of this
> mode is to perform the priority drop and the deactivation of the
> interrupt at the same time.
> 
> While this works perfectly for Linux (we only have a single priority),
> it causes issues when an interrupt is forwarded to a guest, and when
> we want the guest to perform the EOI itself.
> 
> For this case, the GIC architecture provides EOImode == 1, where:
> - A write to ICC_EOIR1_EL1 drops the priority of the interrupt and leaves
> it active. Other interrupts at the same priority level can now be taken,
> but the active interrupt cannot be taken again
> - A write to ICC_DIR_EL1 marks the interrupt as inactive, meaning it can
> now be taken again.
> 
> This patch converts the driver to be able to use this new mode, depending
> on whether or not the kernel can behave as a hypervisor. No feature change.
> 
> Signed-off-by: Marc Zyngier <marc.zyngier at arm.com>
> ---
>  drivers/irqchip/irq-gic-v3.c       | 28 +++++++++++++++++++++++++---
>  include/linux/irqchip/arm-gic-v3.h |  9 +++++++++
>  2 files changed, 34 insertions(+), 3 deletions(-)
> 
> diff --git a/drivers/irqchip/irq-gic-v3.c b/drivers/irqchip/irq-gic-v3.c
> index c52f7ba..49768fc 100644
> --- a/drivers/irqchip/irq-gic-v3.c
> +++ b/drivers/irqchip/irq-gic-v3.c
> @@ -30,6 +30,7 @@
>  #include <asm/cputype.h>
>  #include <asm/exception.h>
>  #include <asm/smp_plat.h>
> +#include <asm/virt.h>
>  
>  #include "irq-gic-common.h"
>  #include "irqchip.h"
> @@ -50,6 +51,7 @@ struct gic_chip_data {
>  };
>  
>  static struct gic_chip_data gic_data __read_mostly;
> +static struct static_key supports_deactivate = STATIC_KEY_INIT_TRUE;
>  
>  #define gic_data_rdist()		(this_cpu_ptr(gic_data.rdists.rdist))
>  #define gic_data_rdist_rd_base()	(gic_data_rdist()->rd_base)
> @@ -293,7 +295,10 @@ static int gic_irq_get_irqchip_state(struct irq_data *d,
>  
>  static void gic_eoi_irq(struct irq_data *d)
>  {
> -	gic_write_eoir(gic_irq(d));
> +	if (static_key_true(&supports_deactivate))
> +		gic_write_dir(gic_irq(d));
> +	else
> +		gic_write_eoir(gic_irq(d));
>  }
>  
>  static int gic_set_type(struct irq_data *d, unsigned int type)
> @@ -343,6 +348,10 @@ static asmlinkage void __exception_irq_entry gic_handle_irq(struct pt_regs *regs
>  
>  		if (likely(irqnr > 15 && irqnr < 1020) || irqnr >= 8192) {
>  			int err;
> +
> +			if (static_key_true(&supports_deactivate))
> +				gic_write_eoir(irqnr);
> +
>  			err = handle_domain_irq(gic_data.domain, irqnr, regs);
>  			if (err) {
>  				WARN_ONCE(true, "Unexpected interrupt received!\n");
shouldn't we DIR here as well in case of err (we did EOI before)?
Besides Reviewed-by: Eric Auger <eric.auger at linaro.org> if it can help.

Eric
> @@ -352,6 +361,8 @@ static asmlinkage void __exception_irq_entry gic_handle_irq(struct pt_regs *regs
>  		}
>  		if (irqnr < 16) {
>  			gic_write_eoir(irqnr);
> +			if (static_key_true(&supports_deactivate))
> +				gic_write_dir(irqnr);
>  #ifdef CONFIG_SMP
>  			handle_IPI(irqnr, regs);
>  #else
> @@ -451,8 +462,13 @@ static void gic_cpu_sys_reg_init(void)
>  	/* Set priority mask register */
>  	gic_write_pmr(DEFAULT_PMR_VALUE);
>  
> -	/* EOI deactivates interrupt too (mode 0) */
> -	gic_write_ctlr(ICC_CTLR_EL1_EOImode_drop_dir);
> +	if (static_key_true(&supports_deactivate)) {
> +		/* EOI drops priority only (mode 1) */
> +		gic_write_ctlr(ICC_CTLR_EL1_EOImode_drop);
> +	} else {
> +		/* EOI deactivates interrupt too (mode 0) */
> +		gic_write_ctlr(ICC_CTLR_EL1_EOImode_drop_dir);
> +	}
>  
>  	/* ... and let's hit the road... */
>  	gic_write_grpen1(1);
> @@ -820,6 +836,12 @@ static int __init gic_of_init(struct device_node *node, struct device_node *pare
>  	if (of_property_read_u64(node, "redistributor-stride", &redist_stride))
>  		redist_stride = 0;
>  
> +	if (!is_hyp_mode_available())
> +		static_key_slow_dec(&supports_deactivate);
> +
> +	pr_info ("GIC: Using EOImode == %d\n",
> +		 static_key_true(&supports_deactivate));
> +
>  	gic_data.dist_base = dist_base;
>  	gic_data.redist_regions = rdist_regs;
>  	gic_data.nr_redist_regions = nr_redist_regions;
> diff --git a/include/linux/irqchip/arm-gic-v3.h b/include/linux/irqchip/arm-gic-v3.h
> index ffbc034..bc98832 100644
> --- a/include/linux/irqchip/arm-gic-v3.h
> +++ b/include/linux/irqchip/arm-gic-v3.h
> @@ -104,6 +104,8 @@
>  #define GICR_SYNCR			0x00C0
>  #define GICR_MOVLPIR			0x0100
>  #define GICR_MOVALLR			0x0110
> +#define GICR_ISACTIVER			GICD_ISACTIVER
> +#define GICR_ICACTIVER			GICD_ICACTIVER
>  #define GICR_IDREGS			GICD_IDREGS
>  #define GICR_PIDR2			GICD_PIDR2
>  
> @@ -288,6 +290,7 @@
>  #define ICH_VMCR_PMR_MASK		(0xffUL << ICH_VMCR_PMR_SHIFT)
>  
>  #define ICC_EOIR1_EL1			sys_reg(3, 0, 12, 12, 1)
> +#define ICC_DIR_EL1			sys_reg(3, 0, 12, 11, 1)
>  #define ICC_IAR1_EL1			sys_reg(3, 0, 12, 12, 0)
>  #define ICC_SGI1R_EL1			sys_reg(3, 0, 12, 11, 5)
>  #define ICC_PMR_EL1			sys_reg(3, 0, 4, 6, 0)
> @@ -384,6 +387,12 @@ static inline void gic_write_eoir(u64 irq)
>  	isb();
>  }
>  
> +static inline void gic_write_dir(u64 irq)
> +{
> +	asm volatile("msr_s " __stringify(ICC_DIR_EL1) ", %0" : : "r" (irq));
> +	isb();
> +}
> +
>  struct irq_domain;
>  int its_cpu_init(void);
>  int its_init(struct device_node *node, struct rdists *rdists,
> 



From eric.auger at linaro.org  Tue Aug 11 02:15:16 2015
From: eric.auger at linaro.org (Eric Auger)
Date: Tue, 11 Aug 2015 11:15:16 +0200
Subject: [PATCH 2/6] irqchip: GIC: Convert to EOImode == 1
In-Reply-To: <1436447951-22357-3-git-send-email-marc.zyngier@arm.com>
References: <1436447951-22357-1-git-send-email-marc.zyngier@arm.com>
 <1436447951-22357-3-git-send-email-marc.zyngier@arm.com>
Message-ID: <55C9BD24.10708@linaro.org>

Hi Marc,
On 07/09/2015 03:19 PM, Marc Zyngier wrote:
> So far, GICv2 has been used in with EOImode == 0. The effect of this
> mode is to perform the priority drop and the deactivation of the
> interrupt at the same time.
> 
> While this works perfectly for Linux (we only have a single priority),
> it causes issues when an interrupt is forwarded to a guest, and when
> we want the guest to perform the EOI itself.
> 
> For this case, the GIC architecture provides EOImode == 1, where:
> - A write to the EOI register drops the priority of the interrupt and leaves
> it active. Other interrupts at the same priority level can now be taken,
> but the active interrupt cannot be taken again
> - A write to the DIR marks the interrupt as inactive, meaning it can
> now be taken again.
> 
> We only enable this feature when booted in HYP mode and that
> the device-tree reporte
reported
 a suitable CPU interface. Observable behaviour
> should remain unchanged.
> 
> Signed-off-by: Marc Zyngier <marc.zyngier at arm.com>
> ---
>  drivers/irqchip/irq-gic.c       | 32 +++++++++++++++++++++++++++++---
>  include/linux/irqchip/arm-gic.h |  4 ++++
>  2 files changed, 33 insertions(+), 3 deletions(-)
> 
> diff --git a/drivers/irqchip/irq-gic.c b/drivers/irqchip/irq-gic.c
> index 8d7e1c8..e264675 100644
> --- a/drivers/irqchip/irq-gic.c
> +++ b/drivers/irqchip/irq-gic.c
> @@ -46,6 +46,7 @@
>  #include <asm/irq.h>
>  #include <asm/exception.h>
>  #include <asm/smp_plat.h>
> +#include <asm/virt.h>
>  
>  #include "irq-gic-common.h"
>  #include "irqchip.h"
> @@ -82,6 +83,8 @@ static DEFINE_RAW_SPINLOCK(irq_controller_lock);
>  #define NR_GIC_CPU_IF 8
>  static u8 gic_cpu_map[NR_GIC_CPU_IF] __read_mostly;
>  
> +static struct static_key supports_deactivate = STATIC_KEY_INIT_TRUE;
> +
>  #ifndef MAX_GIC_NR
>  #define MAX_GIC_NR	1
>  #endif
> @@ -164,7 +167,10 @@ static void gic_unmask_irq(struct irq_data *d)
>  
>  static void gic_eoi_irq(struct irq_data *d)
>  {
> -	writel_relaxed(gic_irq(d), gic_cpu_base(d) + GIC_CPU_EOI);
> +	if (static_key_true(&supports_deactivate))
> +		writel_relaxed(gic_irq(d), gic_cpu_base(d) + GIC_CPU_DEACTIVATE);
> +	else
> +		writel_relaxed(gic_irq(d), gic_cpu_base(d) + GIC_CPU_EOI);
>  }
>  
>  static int gic_irq_set_irqchip_state(struct irq_data *d,
> @@ -272,11 +278,15 @@ static void __exception_irq_entry gic_handle_irq(struct pt_regs *regs)
>  		irqnr = irqstat & GICC_IAR_INT_ID_MASK;
>  
>  		if (likely(irqnr > 15 && irqnr < 1021)) {
shouldn't we have < 1020?
> +			if (static_key_true(&supports_deactivate))
> +				writel_relaxed(irqstat, cpu_base + GIC_CPU_EOI);
>  			handle_domain_irq(gic->domain, irqnr, regs);
why don't we handle the returned value of handle_domain_irq as we do in
GICv3?
>  			continue;
>  		}
>  		if (irqnr < 16) {
>  			writel_relaxed(irqstat, cpu_base + GIC_CPU_EOI);
> +			if (static_key_true(&supports_deactivate))
> +				writel_relaxed(irqstat, cpu_base + GIC_CPU_DEACTIVATE);
>  #ifdef CONFIG_SMP
>  			handle_IPI(irqnr, regs);
>  #endif
> @@ -358,7 +368,11 @@ static u8 gic_get_cpumask(struct gic_chip_data *gic)
>  static void gic_cpu_if_up(void)
>  {
>  	void __iomem *cpu_base = gic_data_cpu_base(&gic_data[0]);
> -	u32 bypass = 0;
> +	u32 bypass;
> +	u32 mode = 0;
> +
> +	if (static_key_true(&supports_deactivate))
> +		mode = GIC_CPU_CTRL_EOImodeNS;
>  
>  	/*
>  	* Preserve bypass disable bits to be written back later
> @@ -366,7 +380,7 @@ static void gic_cpu_if_up(void)
>  	bypass = readl(cpu_base + GIC_CPU_CTRL);
>  	bypass &= GICC_DIS_BYPASS_MASK;
>  
> -	writel_relaxed(bypass | GICC_ENABLE, cpu_base + GIC_CPU_CTRL);
> +	writel_relaxed(bypass | mode | GICC_ENABLE, cpu_base + GIC_CPU_CTRL);
>  }
>  
>  
> @@ -986,6 +1000,9 @@ void __init gic_init_bases(unsigned int gic_nr, int irq_start,
>  		register_cpu_notifier(&gic_cpu_notifier);
>  #endif
>  		set_handle_irq(gic_handle_irq);
> +		pr_info ("GIC: Using EOImode == %d\n",
> +			 static_key_true(&supports_deactivate));
> +
>  	}
>  
>  	gic_dist_init(gic);
> @@ -1001,6 +1018,7 @@ gic_of_init(struct device_node *node, struct device_node *parent)
>  {
>  	void __iomem *cpu_base;
>  	void __iomem *dist_base;
> +	struct resource cpu_res;
>  	u32 percpu_offset;
>  	int irq;
>  
> @@ -1013,6 +1031,11 @@ gic_of_init(struct device_node *node, struct device_node *parent)
>  	cpu_base = of_iomap(node, 1);
>  	WARN(!cpu_base, "unable to map gic cpu registers\n");
>  
> +	of_address_to_resource(node, 1, &cpu_res);
> +	if (!gic_cnt &&
> +	    (!is_hyp_mode_available() || resource_size(&cpu_res) < SZ_8K))
I don't understand why we check this size?
in GICv1 EOIMode necessarily is 0, right? is it related?

Best Regards

Eric
> +		static_key_slow_dec(&supports_deactivate);
> +
>  	if (of_property_read_u32(node, "cpu-offset", &percpu_offset))
>  		percpu_offset = 0;
>  
> @@ -1131,6 +1154,9 @@ gic_v2_acpi_init(struct acpi_table_header *table)
>  		return -ENOMEM;
>  	}
>  
> +	if (!is_hyp_mode_available())
> +		static_key_slow_dec(&supports_deactivate);
> +
>  	/*
>  	 * Initialize zero GIC instance (no multi-GIC support). Also, set GIC
>  	 * as default IRQ domain to allow for GSI registration and GSI to IRQ
> diff --git a/include/linux/irqchip/arm-gic.h b/include/linux/irqchip/arm-gic.h
> index 9de976b..b1533c0 100644
> --- a/include/linux/irqchip/arm-gic.h
> +++ b/include/linux/irqchip/arm-gic.h
> @@ -20,9 +20,13 @@
>  #define GIC_CPU_ALIAS_BINPOINT		0x1c
>  #define GIC_CPU_ACTIVEPRIO		0xd0
>  #define GIC_CPU_IDENT			0xfc
> +#define GIC_CPU_DEACTIVATE		0x1000
>  
>  #define GICC_ENABLE			0x1
>  #define GICC_INT_PRI_THRESHOLD		0xf0
> +
> +#define GIC_CPU_CTRL_EOImodeNS		(1 << 9)
> +
>  #define GICC_IAR_INT_ID_MASK		0x3ff
>  #define GICC_INT_SPURIOUS		1023
>  #define GICC_DIS_BYPASS_MASK		0x1e0
> 



From nsekhar at ti.com  Tue Aug 11 02:24:33 2015
From: nsekhar at ti.com (Sekhar Nori)
Date: Tue, 11 Aug 2015 14:54:33 +0530
Subject: [RESEND][PATCH 3/4] ARM: davinci: Set proper SPI prescale limit
 value
In-Reply-To: <20150811090342.GG10748@sirena.org.uk>
References: <1437568344-18889-1-git-send-email-fcooper@ti.com>
 <1437568344-18889-4-git-send-email-fcooper@ti.com> <55B22681.3060000@ti.com>
 <55C9380D.1060802@ti.com> <55C99D0D.9050605@ti.com>
 <20150811090342.GG10748@sirena.org.uk>
Message-ID: <55C9BF51.5080401@ti.com>

On Tuesday 11 August 2015 02:33 PM, Mark Brown wrote:
> On Tue, Aug 11, 2015 at 12:28:21PM +0530, Sekhar Nori wrote:
>> On Tuesday 11 August 2015 05:17 AM, Franklin S Cooper Jr. wrote:
> 
>>> ping. Patches 1 and 2 have already been pulled into Mark's spi tree and are currently in in linux-next.
> 
>> Mark, can you apply this patch to your tree as well? Thats the preferred
>> route for me.
> 
>> If thats not an option for you, can you confirm that the topic/davinci
>> branch of your spi tree is an immutable commit I can base my pull
>> request to ARM-SoC on?
> 
> Why would there be any interdependency between the the two trees, that
> would be very unusual?  Adding a new value to DT doesn't need the kernel
> to understand it and the driver should be compatible with existing DTs.
> If there *is* some dependency that suggests the driver update has
> problems...

The dependency is because of platform data. Patch 2/4 adds a new
platform data member 'prescaler_limit' which this patch populates for
DaVinci devices using legacy booting.

> In any case I don't have a copy of the patch any more.

I can resend this patch to you with my ack included.

Thanks,
Sekhar



From grygorii.strashko at ti.com  Tue Aug 11 02:25:47 2015
From: grygorii.strashko at ti.com (Grygorii Strashko)
Date: Tue, 11 Aug 2015 12:25:47 +0300
Subject: [PATCH] ARM: OMAP: irqdomain_hierarchy: fix arm gic irq type
 configuration
Message-ID: <1439285147-20027-1-git-send-email-grygorii.strashko@ti.com>

It's observed that ARM GIC IRQ triggering type is not configured
properly when IRQ is routed through IRQ domains hierarchy and
system started using DT. As result, system will start using default
ARM GIC configuration, ignore DT IRQ type configuration,
and value of desc->irq_data.state_use_accessors = 0.

In case of TI OMAP the following IRQ hierarchy is defined:
ARM GIC <- OMAP wakeupgen <- TI CBAR

Failed call chain:
 irq_create_of_mapping
 irq_set_irq_type
 __irq_set_trigger
 if (!chip || !chip->irq_set_type) {
    return 0; <- return here
 }
 CBAR has no .irq_set_type() defined and, so, IRQ triggering
 configuration will not be propagated to parent IRQ domain.

Hence, fix it by introducing irq_chip_set_type_parent(), in the
same manner as irq_chip_set_wake_parent(), and use it for IRQ 
triggering type propagation to the parent IRQ domain in
irq-crossbar and omap-wakeupgen.

/ # cat /proc/interrupts -- before
230:          0          0      CBAR  30 Edge    -00000000  48051000.gpio
263:          0          0      CBAR 116 Edge    -00000000  48053000.gpio
296:        246          0      CBAR  67 Edge    -00000000  OMAP UART0
311:        341          0      CBAR  51 Edge    -00000000  48070000.i2c
312:          3          0      CBAR  52 Edge    -00000000  48072000.i2c
313:          0          0      CBAR  56 Edge    -00000000  48060000.i2c
314:        255          0      CBAR  78 Edge    -00000000  mmc0
315:         40          0      CBAR  81 Edge    -00000000  mmc1
316:         13          0      CBAR  91 Edge    -00000000  mmc2
320:          0          0      CBAR  49 Edge    -00000000  4a140000.sata
324:          0          0      CBAR   1 Edge    -00000000  48078000.elm
325:          0          0      CBAR  15 Edge    -00000000  gpmc
333:          0          0      CBAR 335 Edge    -00000000  48484000.ethernet
334:          0          0      CBAR 336 Edge    -00000000  48484000.ethernet
415:          0          0   pcf857x   2 Edge    -00000000  btnUser1
416:          0          0   pcf857x   3 Edge    -00000000  btnUser2
445:          0          0   pinctrl 992 Edge    -00010000  4806a000.seria

/ # cat /proc/interrupts -- after
230:          0          0      CBAR  30 Level   -00002004  48051000.gpio
263:          0          0      CBAR 116 Level   -00002004  48053000.gpio
296:        567          0      CBAR  67 Level   -00002004  OMAP UART0
311:        363          0      CBAR  51 Level   -00002004  48070000.i2c
312:          3          0      CBAR  52 Level   -00002004  48072000.i2c
313:          0          0      CBAR  56 Level   -00002004  48060000.i2c
314:        197          0      CBAR  78 Level   -00002004  mmc0
315:         40          0      CBAR  81 Level   -00002004  mmc1
316:         13          0      CBAR  91 Level   -00002004  mmc2
320:          0          0      CBAR  49 Level   -00002004  4a140000.sata
324:          0          0      CBAR   1 Level   -00002004  48078000.elm
325:          0          0      CBAR  15 Level   -00002004  gpmc
333:          0          0      CBAR 335 Level   -00002004  48484000.ethernet
334:          0          0      CBAR 336 Level   -00002004  48484000.ethernet
415:          0          0   pcf857x   2 Edge    -00000000  btnUser1
416:          4          2   pcf857x   3 Edge    -00000000  btnUser2
445:          0          0   pinctrl 992 Edge    -00010000  4806a000.serial

Fixes: 783d31863fb8 ('irqchip: crossbar: Convert dra7 crossbar to stacked domains')
Signed-off-by: Grygorii Strashko <grygorii.strashko at ti.com>
---
Hi All,

I can split patch if required and overall solution acceptable.


 arch/arm/mach-omap2/omap-wakeupgen.c |  1 +
 drivers/irqchip/irq-crossbar.c       |  1 +
 include/linux/irq.h                  |  1 +
 kernel/irq/chip.c                    | 16 ++++++++++++++++
 4 files changed, 19 insertions(+)

diff --git a/arch/arm/mach-omap2/omap-wakeupgen.c b/arch/arm/mach-omap2/omap-wakeupgen.c
index 8e52621..e1d2e99 100644
--- a/arch/arm/mach-omap2/omap-wakeupgen.c
+++ b/arch/arm/mach-omap2/omap-wakeupgen.c
@@ -392,6 +392,7 @@ static struct irq_chip wakeupgen_chip = {
 	.irq_mask		= wakeupgen_mask,
 	.irq_unmask		= wakeupgen_unmask,
 	.irq_retrigger		= irq_chip_retrigger_hierarchy,
+	.irq_set_type		= irq_chip_set_type_parent,
 	.flags			= IRQCHIP_SKIP_SET_WAKE | IRQCHIP_MASK_ON_SUSPEND,
 #ifdef CONFIG_SMP
 	.irq_set_affinity	= irq_chip_set_affinity_parent,
diff --git a/drivers/irqchip/irq-crossbar.c b/drivers/irqchip/irq-crossbar.c
index 692fe2b..3ba58e7 100644
--- a/drivers/irqchip/irq-crossbar.c
+++ b/drivers/irqchip/irq-crossbar.c
@@ -69,6 +69,7 @@ static struct irq_chip crossbar_chip = {
 	.irq_unmask		= irq_chip_unmask_parent,
 	.irq_retrigger		= irq_chip_retrigger_hierarchy,
 	.irq_set_wake		= irq_chip_set_wake_parent,
+	.irq_set_type		= irq_chip_set_type_parent,
 #ifdef CONFIG_SMP
 	.irq_set_affinity	= irq_chip_set_affinity_parent,
 #endif
diff --git a/include/linux/irq.h b/include/linux/irq.h
index 92188b0..51744bc 100644
--- a/include/linux/irq.h
+++ b/include/linux/irq.h
@@ -484,6 +484,7 @@ extern int irq_chip_set_affinity_parent(struct irq_data *data,
 extern int irq_chip_set_wake_parent(struct irq_data *data, unsigned int on);
 extern int irq_chip_set_vcpu_affinity_parent(struct irq_data *data,
 					     void *vcpu_info);
+extern int irq_chip_set_type_parent(struct irq_data *data, unsigned int type);
 #endif
 
 /* Handling of unhandled and spurious interrupts: */
diff --git a/kernel/irq/chip.c b/kernel/irq/chip.c
index 27f4332..ac3ff8a 100644
--- a/kernel/irq/chip.c
+++ b/kernel/irq/chip.c
@@ -985,6 +985,22 @@ int irq_chip_set_affinity_parent(struct irq_data *data,
 }
 
 /**
+ * irq_chip_set_type_parent - Set IRQ type on the parent interrupt
+ * @data:	Pointer to interrupt specific data
+ * @type:	IRQ_TYPE_{LEVEL,EDGE}_* value - see include/linux/irq.h
+ *
+ * Conditional, as the underlying parent chip might not implement it.
+ */
+int irq_chip_set_type_parent(struct irq_data *data, unsigned int type)
+{
+	data = data->parent_data;
+	if (data->chip->irq_set_type)
+		return data->chip->irq_set_type(data, type);
+
+	return -ENOSYS;
+}
+
+/**
  * irq_chip_retrigger_hierarchy - Retrigger an interrupt in hardware
  * @data:	Pointer to interrupt specific data
  *
-- 
2.5.0



From shengjiu.wang at freescale.com  Tue Aug 11 02:26:51 2015
From: shengjiu.wang at freescale.com (Shengjiu Wang)
Date: Tue, 11 Aug 2015 17:26:51 +0800
Subject: [PATCH V1 0/3] fix clock issue for fsl,spdif
Message-ID: <cover.1439284957.git.shengjiu.wang@freescale.com>

fix clock issue for fsl,spdif

Shengjiu Wang (3):
  ARM: imx6q: Add SPDIF_GCLK clock in clock tree
  ARM: imx6sl: Add SPDIF_GCLK clock in clock tree
  ARM: imx6sx: Add SPDIF_GCLK clock in clock tree

 arch/arm/boot/dts/imx6qdl.dtsi            |  2 +-
 arch/arm/boot/dts/imx6sl.dtsi             | 16 ++++++++++++++++
 arch/arm/boot/dts/imx6sx.dtsi             |  2 +-
 drivers/clk/imx/clk-imx6q.c               |  4 +++-
 drivers/clk/imx/clk-imx6sl.c              |  4 +++-
 drivers/clk/imx/clk-imx6sx.c              |  1 +
 include/dt-bindings/clock/imx6qdl-clock.h |  3 ++-
 include/dt-bindings/clock/imx6sl-clock.h  |  3 ++-
 include/dt-bindings/clock/imx6sx-clock.h  |  3 ++-
 9 files changed, 31 insertions(+), 7 deletions(-)

-- 
1.9.1



From shengjiu.wang at freescale.com  Tue Aug 11 02:26:52 2015
From: shengjiu.wang at freescale.com (Shengjiu Wang)
Date: Tue, 11 Aug 2015 17:26:52 +0800
Subject: [PATCH V1 1/3] ARM: imx6q: Add SPDIF_GCLK clock in clock tree
In-Reply-To: <cover.1439284957.git.shengjiu.wang@freescale.com>
References: <cover.1439284957.git.shengjiu.wang@freescale.com>
Message-ID: <18281cc1d1229dfe5edaf87163dc4dc140663823.1439284957.git.shengjiu.wang@freescale.com>

As spdif driver will register SPDIF clock to regmap, regmap will do
clk_prepare in init function, so SPDIF clock is prepared in probe, then its
root clock (pll clock) is prepared also, which cause the arm can't enter
low power mode.
Add SPDIF_GCLK in clock tree which share same gate bits with SPDIF clock.
Its root clock is ipg clock, and register it to regmap, then the issue cam
be fixed.

Signed-off-by: Shengjiu Wang <shengjiu.wang at freescale.com>
---
 arch/arm/boot/dts/imx6qdl.dtsi            | 2 +-
 drivers/clk/imx/clk-imx6q.c               | 4 +++-
 include/dt-bindings/clock/imx6qdl-clock.h | 3 ++-
 3 files changed, 6 insertions(+), 3 deletions(-)

diff --git a/arch/arm/boot/dts/imx6qdl.dtsi b/arch/arm/boot/dts/imx6qdl.dtsi
index 03858d7..66913ef 100644
--- a/arch/arm/boot/dts/imx6qdl.dtsi
+++ b/arch/arm/boot/dts/imx6qdl.dtsi
@@ -218,7 +218,7 @@
 					dmas = <&sdma 14 18 0>,
 					       <&sdma 15 18 0>;
 					dma-names = "rx", "tx";
-					clocks = <&clks IMX6QDL_CLK_SPDIF>, <&clks IMX6QDL_CLK_OSC>,
+					clocks = <&clks IMX6QDL_CLK_SPDIF_GCLK>, <&clks IMX6QDL_CLK_OSC>,
 						 <&clks IMX6QDL_CLK_SPDIF>, <&clks IMX6QDL_CLK_DUMMY>,
 						 <&clks IMX6QDL_CLK_DUMMY>, <&clks IMX6QDL_CLK_DUMMY>,
 						 <&clks IMX6QDL_CLK_DUMMY>, <&clks IMX6QDL_CLK_DUMMY>,
diff --git a/drivers/clk/imx/clk-imx6q.c b/drivers/clk/imx/clk-imx6q.c
index c507bca..2487cf1 100644
--- a/drivers/clk/imx/clk-imx6q.c
+++ b/drivers/clk/imx/clk-imx6q.c
@@ -119,6 +119,7 @@ static unsigned int share_count_ssi1;
 static unsigned int share_count_ssi2;
 static unsigned int share_count_ssi3;
 static unsigned int share_count_mipi_core_cfg;
+static unsigned int share_count_spdif;
 
 static inline int clk_on_imx6q(void)
 {
@@ -453,7 +454,8 @@ static void __init imx6q_clocks_init(struct device_node *ccm_node)
 	clk[IMX6QDL_CLK_SATA]         = imx_clk_gate2("sata",          "ahb",               base + 0x7c, 4);
 	clk[IMX6QDL_CLK_SDMA]         = imx_clk_gate2("sdma",          "ahb",               base + 0x7c, 6);
 	clk[IMX6QDL_CLK_SPBA]         = imx_clk_gate2("spba",          "ipg",               base + 0x7c, 12);
-	clk[IMX6QDL_CLK_SPDIF]        = imx_clk_gate2("spdif",         "spdif_podf",        base + 0x7c, 14);
+	clk[IMX6QDL_CLK_SPDIF]        = imx_clk_gate2_shared("spdif",     "spdif_podf",     base + 0x7c, 14, &share_count_spdif);
+	clk[IMX6QDL_CLK_SPDIF_GCLK]   = imx_clk_gate2_shared("spdif_gclk", "ipg",           base + 0x7c, 14, &share_count_spdif);
 	clk[IMX6QDL_CLK_SSI1_IPG]     = imx_clk_gate2_shared("ssi1_ipg",      "ipg",        base + 0x7c, 18, &share_count_ssi1);
 	clk[IMX6QDL_CLK_SSI2_IPG]     = imx_clk_gate2_shared("ssi2_ipg",      "ipg",        base + 0x7c, 20, &share_count_ssi2);
 	clk[IMX6QDL_CLK_SSI3_IPG]     = imx_clk_gate2_shared("ssi3_ipg",      "ipg",        base + 0x7c, 22, &share_count_ssi3);
diff --git a/include/dt-bindings/clock/imx6qdl-clock.h b/include/dt-bindings/clock/imx6qdl-clock.h
index 8780868..bc3ad90 100644
--- a/include/dt-bindings/clock/imx6qdl-clock.h
+++ b/include/dt-bindings/clock/imx6qdl-clock.h
@@ -251,6 +251,7 @@
 #define IMX6QDL_CLK_VIDEO_27M			238
 #define IMX6QDL_CLK_MIPI_CORE_CFG		239
 #define IMX6QDL_CLK_MIPI_IPG			240
-#define IMX6QDL_CLK_END				241
+#define IMX6QDL_CLK_SPDIF_GCLK			241
+#define IMX6QDL_CLK_END				242
 
 #endif /* __DT_BINDINGS_CLOCK_IMX6QDL_H */
-- 
1.9.1



From shengjiu.wang at freescale.com  Tue Aug 11 02:26:53 2015
From: shengjiu.wang at freescale.com (Shengjiu Wang)
Date: Tue, 11 Aug 2015 17:26:53 +0800
Subject: [PATCH V1 2/3] ARM: imx6sl: Add SPDIF_GCLK clock in clock tree
In-Reply-To: <cover.1439284957.git.shengjiu.wang@freescale.com>
References: <cover.1439284957.git.shengjiu.wang@freescale.com>
Message-ID: <22e9a375a152703a52895af8d2596f6f58b93249.1439284957.git.shengjiu.wang@freescale.com>

As spdif driver will register SPDIF clock to regmap, regmap will do
clk_prepare in init function, so SPDIF clock is prepared in probe, then its
root clock (pll clock) is prepared also, which cause the arm can't enter
low power mode.
Add SPDIF_GCLK in clock tree which share same gate bits with SPDIF clock.
Its root clock is ipg clock, and register it to regmap, then the issue can
be fixed.

Signed-off-by: Shengjiu Wang <shengjiu.wang at freescale.com>
---
 arch/arm/boot/dts/imx6sl.dtsi            | 16 ++++++++++++++++
 drivers/clk/imx/clk-imx6sl.c             |  4 +++-
 include/dt-bindings/clock/imx6sl-clock.h |  3 ++-
 3 files changed, 21 insertions(+), 2 deletions(-)

diff --git a/arch/arm/boot/dts/imx6sl.dtsi b/arch/arm/boot/dts/imx6sl.dtsi
index 320a27f..c247756 100644
--- a/arch/arm/boot/dts/imx6sl.dtsi
+++ b/arch/arm/boot/dts/imx6sl.dtsi
@@ -135,8 +135,24 @@
 				ranges;
 
 				spdif: spdif at 02004000 {
+					compatible = "fsl,imx6sl-spdif",
+						"fsl,imx35-spdif";
 					reg = <0x02004000 0x4000>;
 					interrupts = <0 52 IRQ_TYPE_LEVEL_HIGH>;
+					dmas = <&sdma 14 18 0>,
+						<&sdma 15 18 0>;
+					dma-names = "rx", "tx";
+					clocks = <&clks IMX6SL_CLK_SPDIF_GCLK>, <&clks IMX6SL_CLK_OSC>,
+						 <&clks IMX6SL_CLK_SPDIF>, <&clks IMX6SL_CLK_DUMMY>,
+						 <&clks IMX6SL_CLK_DUMMY>, <&clks IMX6SL_CLK_DUMMY>,
+						 <&clks IMX6SL_CLK_IPG>, <&clks IMX6SL_CLK_DUMMY>,
+						 <&clks IMX6SL_CLK_DUMMY>, <&clks IMX6SL_CLK_SPBA>;
+					clock-names = "core", "rxtx0",
+						"rxtx1", "rxtx2",
+						"rxtx3", "rxtx4",
+						"rxtx5", "rxtx6",
+						"rxtx7", "dma";
+					status = "disabled";
 				};
 
 				ecspi1: ecspi at 02008000 {
diff --git a/drivers/clk/imx/clk-imx6sl.c b/drivers/clk/imx/clk-imx6sl.c
index a0d4cf2..a73cedd 100644
--- a/drivers/clk/imx/clk-imx6sl.c
+++ b/drivers/clk/imx/clk-imx6sl.c
@@ -97,6 +97,7 @@ static struct clk_div_table video_div_table[] = {
 static unsigned int share_count_ssi1;
 static unsigned int share_count_ssi2;
 static unsigned int share_count_ssi3;
+static unsigned int share_count_spdif;
 
 static struct clk *clks[IMX6SL_CLK_END];
 static struct clk_onecell_data clk_data;
@@ -391,7 +392,8 @@ static void __init imx6sl_clocks_init(struct device_node *ccm_node)
 	clks[IMX6SL_CLK_PWM4]         = imx_clk_gate2("pwm4",         "perclk",            base + 0x78, 22);
 	clks[IMX6SL_CLK_SDMA]         = imx_clk_gate2("sdma",         "ipg",               base + 0x7c, 6);
 	clks[IMX6SL_CLK_SPBA]         = imx_clk_gate2("spba",         "ipg",               base + 0x7c, 12);
-	clks[IMX6SL_CLK_SPDIF]        = imx_clk_gate2("spdif",        "spdif0_podf",       base + 0x7c, 14);
+	clks[IMX6SL_CLK_SPDIF]        = imx_clk_gate2_shared("spdif",     "spdif0_podf",   base + 0x7c, 14, &share_count_spdif);
+	clks[IMX6SL_CLK_SPDIF_GCLK]   = imx_clk_gate2_shared("spdif_gclk",  "ipg",         base + 0x7c, 14, &share_count_spdif);
 	clks[IMX6SL_CLK_SSI1_IPG]     = imx_clk_gate2_shared("ssi1_ipg",     "ipg",        base + 0x7c, 18, &share_count_ssi1);
 	clks[IMX6SL_CLK_SSI2_IPG]     = imx_clk_gate2_shared("ssi2_ipg",     "ipg",        base + 0x7c, 20, &share_count_ssi2);
 	clks[IMX6SL_CLK_SSI3_IPG]     = imx_clk_gate2_shared("ssi3_ipg",     "ipg",        base + 0x7c, 22, &share_count_ssi3);
diff --git a/include/dt-bindings/clock/imx6sl-clock.h b/include/dt-bindings/clock/imx6sl-clock.h
index 9ce4e42..e14573e 100644
--- a/include/dt-bindings/clock/imx6sl-clock.h
+++ b/include/dt-bindings/clock/imx6sl-clock.h
@@ -174,6 +174,7 @@
 #define IMX6SL_CLK_SSI1_IPG		161
 #define IMX6SL_CLK_SSI2_IPG		162
 #define IMX6SL_CLK_SSI3_IPG		163
-#define IMX6SL_CLK_END			164
+#define IMX6SL_CLK_SPDIF_GCLK		164
+#define IMX6SL_CLK_END			165
 
 #endif /* __DT_BINDINGS_CLOCK_IMX6SL_H */
-- 
1.9.1



From shengjiu.wang at freescale.com  Tue Aug 11 02:26:54 2015
From: shengjiu.wang at freescale.com (Shengjiu Wang)
Date: Tue, 11 Aug 2015 17:26:54 +0800
Subject: [PATCH V1 3/3] ARM: imx6sx: Add SPDIF_GCLK clock in clock tree
In-Reply-To: <cover.1439284957.git.shengjiu.wang@freescale.com>
References: <cover.1439284957.git.shengjiu.wang@freescale.com>
Message-ID: <d1ffad5bac99d16c3b8377a2cc9370e35efcc7e7.1439284957.git.shengjiu.wang@freescale.com>

As spdif driver will register SPDIF clock to regmap, regmap will do
clk_prepare in init function, so SPDIF clock is prepared in probe, then its
root clock (pll clock) is prepared also, which cause the arm can't enter
low power mode.
Add SPDIF_GCLK in clock tree which share same gate bits with SPDIF clock.
Its root clock is ipg clock, and register it to regmap, then the issue can
be fixed.

Signed-off-by: Shengjiu Wang <shengjiu.wang at freescale.com>
---
 arch/arm/boot/dts/imx6sx.dtsi            | 2 +-
 drivers/clk/imx/clk-imx6sx.c             | 1 +
 include/dt-bindings/clock/imx6sx-clock.h | 3 ++-
 3 files changed, 4 insertions(+), 2 deletions(-)

diff --git a/arch/arm/boot/dts/imx6sx.dtsi b/arch/arm/boot/dts/imx6sx.dtsi
index e391d63..af9c28e 100644
--- a/arch/arm/boot/dts/imx6sx.dtsi
+++ b/arch/arm/boot/dts/imx6sx.dtsi
@@ -211,7 +211,7 @@
 					dmas = <&sdma 14 18 0>,
 					       <&sdma 15 18 0>;
 					dma-names = "rx", "tx";
-					clocks = <&clks IMX6SX_CLK_SPDIF>,
+					clocks = <&clks IMX6SX_CLK_SPDIF_GCLK>,
 						 <&clks IMX6SX_CLK_OSC>,
 						 <&clks IMX6SX_CLK_SPDIF>,
 						 <&clks 0>, <&clks 0>, <&clks 0>,
diff --git a/drivers/clk/imx/clk-imx6sx.c b/drivers/clk/imx/clk-imx6sx.c
index 5b95c2c..f2bc511 100644
--- a/drivers/clk/imx/clk-imx6sx.c
+++ b/drivers/clk/imx/clk-imx6sx.c
@@ -454,6 +454,7 @@ static void __init imx6sx_clocks_init(struct device_node *ccm_node)
 	clks[IMX6SX_CLK_SPBA]         = imx_clk_gate2("spba",          "ipg",               base + 0x7c, 12);
 	clks[IMX6SX_CLK_AUDIO]        = imx_clk_gate2_shared("audio",  "audio_podf",        base + 0x7c, 14, &share_count_audio);
 	clks[IMX6SX_CLK_SPDIF]        = imx_clk_gate2_shared("spdif",  "spdif_podf",        base + 0x7c, 14, &share_count_audio);
+	clks[IMX6SX_CLK_SPDIF_GCLK]   = imx_clk_gate2_shared("spdif_gclk",    "ipg",        base + 0x7c, 14, &share_count_audio);
 	clks[IMX6SX_CLK_SSI1_IPG]     = imx_clk_gate2_shared("ssi1_ipg",      "ipg",        base + 0x7c, 18, &share_count_ssi1);
 	clks[IMX6SX_CLK_SSI2_IPG]     = imx_clk_gate2_shared("ssi2_ipg",      "ipg",        base + 0x7c, 20, &share_count_ssi2);
 	clks[IMX6SX_CLK_SSI3_IPG]     = imx_clk_gate2_shared("ssi3_ipg",      "ipg",        base + 0x7c, 22, &share_count_ssi3);
diff --git a/include/dt-bindings/clock/imx6sx-clock.h b/include/dt-bindings/clock/imx6sx-clock.h
index 9957091..36f0324 100644
--- a/include/dt-bindings/clock/imx6sx-clock.h
+++ b/include/dt-bindings/clock/imx6sx-clock.h
@@ -274,6 +274,7 @@
 #define IMX6SX_PLL5_BYPASS		261
 #define IMX6SX_PLL6_BYPASS		262
 #define IMX6SX_PLL7_BYPASS		263
-#define IMX6SX_CLK_CLK_END		264
+#define IMX6SX_CLK_SPDIF_GCLK		264
+#define IMX6SX_CLK_CLK_END		265
 
 #endif /* __DT_BINDINGS_CLOCK_IMX6SX_H */
-- 
1.9.1



From broonie at kernel.org  Tue Aug 11 02:28:10 2015
From: broonie at kernel.org (Mark Brown)
Date: Tue, 11 Aug 2015 10:28:10 +0100
Subject: [RESEND][PATCH 3/4] ARM: davinci: Set proper SPI prescale limit
 value
In-Reply-To: <55C9BF51.5080401@ti.com>
References: <1437568344-18889-1-git-send-email-fcooper@ti.com>
 <1437568344-18889-4-git-send-email-fcooper@ti.com>
 <55B22681.3060000@ti.com> <55C9380D.1060802@ti.com>
 <55C99D0D.9050605@ti.com> <20150811090342.GG10748@sirena.org.uk>
 <55C9BF51.5080401@ti.com>
Message-ID: <20150811092810.GK10748@sirena.org.uk>

On Tue, Aug 11, 2015 at 02:54:33PM +0530, Sekhar Nori wrote:
> On Tuesday 11 August 2015 02:33 PM, Mark Brown wrote:

> > Why would there be any interdependency between the the two trees, that
> > would be very unusual?  Adding a new value to DT doesn't need the kernel
> > to understand it and the driver should be compatible with existing DTs.
> > If there *is* some dependency that suggests the driver update has
> > problems...

> The dependency is because of platform data. Patch 2/4 adds a new
> platform data member 'prescaler_limit' which this patch populates for
> DaVinci devices using legacy booting.

Ugh, you still have legacy platforms :(

> > In any case I don't have a copy of the patch any more.

> I can resend this patch to you with my ack included.

I guess.
-------------- next part --------------
A non-text attachment was scrubbed...
Name: signature.asc
Type: application/pgp-signature
Size: 473 bytes
Desc: Digital signature
URL: <http://lists.infradead.org/pipermail/linux-arm-kernel/attachments/20150811/b31df503/attachment.sig>

From lee.jones at linaro.org  Tue Aug 11 02:30:39 2015
From: lee.jones at linaro.org (Lee Jones)
Date: Tue, 11 Aug 2015 10:30:39 +0100
Subject: [PATCH v4 2/2] dt: power: st: Provide bindings for ST's OPPs
In-Reply-To: <20150811080023.GB5509@linux>
References: <20150728022936.GB1229@linux>
 <20150728225510.GB3159@codeaurora.org> <20150729081403.GH2284@x1>
 <20150729221526.GE3159@codeaurora.org> <20150730084634.GD9319@x1>
 <CAL_JsqKQLQ15qSt95zBZykzzPhcUrtZzhk29a76n+r_3719AiA@mail.gmail.com>
 <20150731163715.GV3159@codeaurora.org> <20150803034642.GV899@linux>
 <20150810132247.GH3249@x1> <20150811080023.GB5509@linux>
Message-ID: <20150811093039.GA18282@x1>

On Tue, 11 Aug 2015, Viresh Kumar wrote:

> On 10-08-15, 14:22, Lee Jones wrote:
> > >  Optional properties:
> > > +- opp-cuts: One or more strings, describing the versions of hardware the OPPs
> > > +  can support.
> > 
> > This isn't very generic.
> > 
> > I'm guessing some vendors my have quite a few ways to differentiate
> > between board versions/revisions/cuts etc.
> > 
> > How about another array where a vendor can choose to identify a piece
> > of hardware however they see fit.
> > 
> > Example 1 (simple version):
> > 
> > /* Version 1 */
> > opp-version = <1>;
> > 
> > Example 2 (using the kernel's versioning):
> > 
> > /* 2.6.32-rc1 */
> > opp-version = <2 6 32 1>;
> > 
> > Example 3 (using ST's versioning):
> > 
> > /* Major 2, Minor 0, Cut 2, All substrates */
> > opp-version = <2 0 2 0xff>;
> 
> But how will we parse this with generic code ?

Why would you want to?

-- 
Lee Jones
Linaro STMicroelectronics Landing Team Lead
Linaro.org ? Open source software for ARM SoCs
Follow Linaro: Facebook | Twitter | Blog


From joro at 8bytes.org  Tue Aug 11 02:37:42 2015
From: joro at 8bytes.org (Joerg Roedel)
Date: Tue, 11 Aug 2015 11:37:42 +0200
Subject: [PATCH v5 1/3] iommu: Implement common IOMMU ops for DMA mapping
In-Reply-To: <55C4B4DF.4040608@arm.com>
References: <cover.1438362603.git.robin.murphy@arm.com>
 <6ce6b501501f611297ae0eae31e07b0d2060eaae.1438362603.git.robin.murphy@arm.com>
 <20150807084228.GU14980@8bytes.org> <55C4B4DF.4040608@arm.com>
Message-ID: <20150811093742.GC14980@8bytes.org>

On Fri, Aug 07, 2015 at 02:38:39PM +0100, Robin Murphy wrote:
> Indeed, DMA_DEBUG will check that a driver is making DMA API calls
> to the arch code in the right way; this is a different check, to
> catch things like the arch code passing the wrong domain into this
> layer, or someone else having messed directly with the domain via
> the IOMMU API. If the iommu_unmap doesn't match the IOVA region we
> looked up, that means the IOMMU page tables have somehow become
> inconsistent with the IOVA allocator, so we are in an unrecoverable
> situation where we can no longer be sure what devices have access
> to. That's bad.

Sure, but the BUG_ON would also trigger on things like a double-free,
which is bad to handle as a BUG_ON. A WARN_ON for this is sufficient.

> AFAIK, yes (this is just a slight tidyup of the existing code that
> 32-bit Exynos/Tegra/Rockchip/etc. devices are already using) - the
> display guys want increasingly massive contiguous allocations for
> framebuffers, layers, etc., so having IOMMU magic deal with that
> saves CMA for non-IOMMU devices that really need it.

Makes sense, I thougt about something similar for x86 too to avoid the
high-order allocations we currently do. I guess the buffer will later be
mapped into the vmalloc space for the CPU?


	Joerg



From tomeu.vizoso at collabora.com  Tue Aug 11 02:37:38 2015
From: tomeu.vizoso at collabora.com (Tomeu Vizoso)
Date: Tue, 11 Aug 2015 11:37:38 +0200
Subject: [PATCH v3 02/18] of/platform: add of_platform_probe
In-Reply-To: <20150807121913.GS20873@sirena.org.uk>
References: <1438870315-18689-1-git-send-email-tomeu.vizoso@collabora.com>
 <1438870315-18689-3-git-send-email-tomeu.vizoso@collabora.com>
 <20150807121913.GS20873@sirena.org.uk>
Message-ID: <CAAObsKCrakupiZMQ9AoiWo6fDYT6Cfi_khdssUS6pv61zYS1Zg@mail.gmail.com>

On 7 August 2015 at 14:19, Mark Brown <broonie at kernel.org> wrote:
> On Thu, Aug 06, 2015 at 04:11:39PM +0200, Tomeu Vizoso wrote:
>
>> Walks the OF tree up and finds the closest ancestor that has a platform
>> device associated with it, probing it if isn't bound to a driver yet.
>
>> The above should ensure that the dependency represented by the passed OF
>> node is available, because probing a platform device should cause its
>> descendants to be probed as well.
>
> This sounds like it's going to break in the case where we have MFDs that
> represent their functions in DT (not a pattern I'm a fan of but it's a
> thing people do).  We'll walk back to the platform device for the MFD
> function, try to probe it and then give up.  Perhaps that's good enough
> anyway but it's not clear to me why we don't just try every parent we
> find?

Agreed. In the attempt at probing dependencies before a device is
probed, I considered that a device's parent is also a dependency and
that worked well. From what I saw, few devices will defer their probe
if their parent hasn't been probed yet, assuming that it will have
probed already. But with simple-mfd and simple-bus that shouldn't be
relied upon as things will break if their parents defer their probe.
With async probing enabled this failure scenario becomes more
probable.

> I'm also not a fan of the fact that the interface here is explicitly
> saying that we want to probe a platform device, that's an implementation
> detail that callers shouldn't need to know about.  From the point of
> view of the callers what they're trying to do is kick any dependencies
> into being instantiated, the fact that we currently try to accomplish it
> with platform devices isn't something they care about.

Agreed.

Thanks,

Tomeu


From alexandre.belloni at free-electrons.com  Tue Aug 11 02:38:00 2015
From: alexandre.belloni at free-electrons.com (Alexandre Belloni)
Date: Tue, 11 Aug 2015 11:38:00 +0200
Subject: [PATCH v3 0/4] ARM: at91: Properly handle slow clock
Message-ID: <1439285884-16051-1-git-send-email-alexandre.belloni@free-electrons.com>

Hi,

It was discovered that all the slow clock user were not properly claiming it.
This can end up in a system hang because the last registered user is releasing
it, and it gets disabled.

commit dca1a4b5ff6e ("clk: at91: keep slow clk enabled to prevent system hang")
was a workaround. This series is adding the slow clock to the necessary drivers
to avoid the issue and then removes that workaround.

Changes in v3:
 - dropped patches that were already taken or submitted separately
 - sclk is not a global anymore in timer-atmel-st.c
 - added Greg's ack

Cc: Daniel Lezcano <daniel.lezcano at linaro.org>
Cc: linux-pwm at vger.kernel.org
Cc: linux-watchdog at vger.kernel.org
Cc: Thierry Reding <thierry.reding at gmail.com>
Cc: Thomas Gleixner <tglx at linutronix.de>
Cc: Wim Van Sebroeck <wim at iguana.be>

Alexandre Belloni (2):
  watchdog: at91sam9: get and use slow clock
  clocksource: atmel-st: get and use slow clock

Boris Brezillon (2):
  clocksource: tcb_clksrc: fix setup_clkevents error path
  misc: atmel_tclib: get and use slow clock

 drivers/clocksource/tcb_clksrc.c     | 10 +++++++++-
 drivers/clocksource/timer-atmel-st.c | 31 ++++++++++++++++++++++---------
 drivers/misc/atmel_tclib.c           |  4 ++++
 drivers/pwm/pwm-atmel-tcb.c          | 23 ++++++++++++++++-------
 drivers/watchdog/at91sam9_wdt.c      | 22 ++++++++++++++++++++--
 include/linux/atmel_tc.h             |  1 +
 6 files changed, 72 insertions(+), 19 deletions(-)

-- 
2.1.4



From alexandre.belloni at free-electrons.com  Tue Aug 11 02:38:01 2015
From: alexandre.belloni at free-electrons.com (Alexandre Belloni)
Date: Tue, 11 Aug 2015 11:38:01 +0200
Subject: [PATCH v3 1/4] watchdog: at91sam9: get and use slow clock
In-Reply-To: <1439285884-16051-1-git-send-email-alexandre.belloni@free-electrons.com>
References: <1439285884-16051-1-git-send-email-alexandre.belloni@free-electrons.com>
Message-ID: <1439285884-16051-2-git-send-email-alexandre.belloni@free-electrons.com>

Commit dca1a4b5ff6e ("clk: at91: keep slow clk enabled to prevent system
hang") added a workaround for the slow clock as it is not properly handled
by its users.

Get and use the slow clock as it is necessary for the at91sam9 watchdog.

Signed-off-by: Alexandre Belloni <alexandre.belloni at free-electrons.com>
Reviewed-by: Guenter Roeck <linux at roeck-us.net>
---
Cc: Wim Van Sebroeck <wim at iguana.be>
Cc: linux-watchdog at vger.kernel.org
 drivers/watchdog/at91sam9_wdt.c | 22 ++++++++++++++++++++--
 1 file changed, 20 insertions(+), 2 deletions(-)

diff --git a/drivers/watchdog/at91sam9_wdt.c b/drivers/watchdog/at91sam9_wdt.c
index e4698f7c5f93..7e6acaf3ece4 100644
--- a/drivers/watchdog/at91sam9_wdt.c
+++ b/drivers/watchdog/at91sam9_wdt.c
@@ -17,6 +17,7 @@
 
 #define pr_fmt(fmt) KBUILD_MODNAME ": " fmt
 
+#include <linux/clk.h>
 #include <linux/errno.h>
 #include <linux/init.h>
 #include <linux/interrupt.h>
@@ -90,6 +91,7 @@ struct at91wdt {
 	unsigned long heartbeat;	/* WDT heartbeat in jiffies */
 	bool nowayout;
 	unsigned int irq;
+	struct clk *sclk;
 };
 
 /* ......................................................................... */
@@ -352,15 +354,25 @@ static int __init at91wdt_probe(struct platform_device *pdev)
 	if (IS_ERR(wdt->base))
 		return PTR_ERR(wdt->base);
 
+	wdt->sclk = devm_clk_get(&pdev->dev, NULL);
+	if (IS_ERR(wdt->sclk))
+		return PTR_ERR(wdt->sclk);
+
+	err = clk_prepare_enable(wdt->sclk);
+	if (err) {
+		dev_err(&pdev->dev, "Could not enable slow clock\n");
+		return err;
+	}
+
 	if (pdev->dev.of_node) {
 		err = of_at91wdt_init(pdev->dev.of_node, wdt);
 		if (err)
-			return err;
+			goto err_clk;
 	}
 
 	err = at91_wdt_init(pdev, wdt);
 	if (err)
-		return err;
+		goto err_clk;
 
 	platform_set_drvdata(pdev, wdt);
 
@@ -368,6 +380,11 @@ static int __init at91wdt_probe(struct platform_device *pdev)
 		wdt->wdd.timeout, wdt->nowayout);
 
 	return 0;
+
+err_clk:
+	clk_disable_unprepare(wdt->sclk);
+
+	return err;
 }
 
 static int __exit at91wdt_remove(struct platform_device *pdev)
@@ -377,6 +394,7 @@ static int __exit at91wdt_remove(struct platform_device *pdev)
 
 	pr_warn("I quit now, hardware will probably reboot!\n");
 	del_timer(&wdt->timer);
+	clk_disable_unprepare(wdt->sclk);
 
 	return 0;
 }
-- 
2.1.4



From alexandre.belloni at free-electrons.com  Tue Aug 11 02:38:03 2015
From: alexandre.belloni at free-electrons.com (Alexandre Belloni)
Date: Tue, 11 Aug 2015 11:38:03 +0200
Subject: [PATCH v3 3/4] clocksource: tcb_clksrc: fix setup_clkevents error path
In-Reply-To: <1439285884-16051-1-git-send-email-alexandre.belloni@free-electrons.com>
References: <1439285884-16051-1-git-send-email-alexandre.belloni@free-electrons.com>
Message-ID: <1439285884-16051-4-git-send-email-alexandre.belloni@free-electrons.com>

From: Boris Brezillon <boris.brezillon at free-electrons.com>

t2_clk is already disabled before request_irq(), it must not be disabled
again.

Signed-off-by: Boris Brezillon <boris.brezillon at free-electrons.com>
Signed-off-by: Alexandre Belloni <alexandre.belloni at free-electrons.com>
---
Cc: Daniel Lezcano <daniel.lezcano at linaro.org>
Cc: Thomas Gleixner <tglx at linutronix.de>
 drivers/clocksource/tcb_clksrc.c | 2 +-
 1 file changed, 1 insertion(+), 1 deletion(-)

diff --git a/drivers/clocksource/tcb_clksrc.c b/drivers/clocksource/tcb_clksrc.c
index 8bdbc45c6dad..b9b7277173c2 100644
--- a/drivers/clocksource/tcb_clksrc.c
+++ b/drivers/clocksource/tcb_clksrc.c
@@ -199,7 +199,7 @@ static int __init setup_clkevents(struct atmel_tc *tc, int clk32k_divisor_idx)
 
 	ret = request_irq(irq, ch2_irq, IRQF_TIMER, "tc_clkevt", &clkevt);
 	if (ret) {
-		clk_disable_unprepare(t2_clk);
+		clk_unprepare(t2_clk);
 		return ret;
 	}
 
-- 
2.1.4



From alexandre.belloni at free-electrons.com  Tue Aug 11 02:38:02 2015
From: alexandre.belloni at free-electrons.com (Alexandre Belloni)
Date: Tue, 11 Aug 2015 11:38:02 +0200
Subject: [PATCH v3 2/4] clocksource: atmel-st: get and use slow clock
In-Reply-To: <1439285884-16051-1-git-send-email-alexandre.belloni@free-electrons.com>
References: <1439285884-16051-1-git-send-email-alexandre.belloni@free-electrons.com>
Message-ID: <1439285884-16051-3-git-send-email-alexandre.belloni@free-electrons.com>

The current slow clock rate is hardcoded. Properly get the slow clock
and use its rate.

Signed-off-by: Alexandre Belloni <alexandre.belloni at free-electrons.com>
---
Cc: Daniel Lezcano <daniel.lezcano at linaro.org>
Cc: Thomas Gleixner <tglx at linutronix.de>
 drivers/clocksource/timer-atmel-st.c | 31 ++++++++++++++++++++++---------
 1 file changed, 22 insertions(+), 9 deletions(-)

diff --git a/drivers/clocksource/timer-atmel-st.c b/drivers/clocksource/timer-atmel-st.c
index 1692e17e096b..51dcbae0a654 100644
--- a/drivers/clocksource/timer-atmel-st.c
+++ b/drivers/clocksource/timer-atmel-st.c
@@ -22,6 +22,7 @@
 #include <linux/kernel.h>
 #include <linux/interrupt.h>
 #include <linux/irq.h>
+#include <linux/clk.h>
 #include <linux/clockchips.h>
 #include <linux/export.h>
 #include <linux/mfd/syscon.h>
@@ -33,9 +34,7 @@ static unsigned long last_crtr;
 static u32 irqmask;
 static struct clock_event_device clkevt;
 static struct regmap *regmap_st;
-
-#define AT91_SLOW_CLOCK		32768
-#define RM9200_TIMER_LATCH	((AT91_SLOW_CLOCK + HZ/2) / HZ)
+static int timer_latch;
 
 /*
  * The ST_CRTR is updated asynchronously to the master clock ... but
@@ -82,8 +81,8 @@ static irqreturn_t at91rm9200_timer_interrupt(int irq, void *dev_id)
 	if (sr & AT91_ST_PITS) {
 		u32	crtr = read_CRTR();
 
-		while (((crtr - last_crtr) & AT91_ST_CRTV) >= RM9200_TIMER_LATCH) {
-			last_crtr += RM9200_TIMER_LATCH;
+		while (((crtr - last_crtr) & AT91_ST_CRTV) >= timer_latch) {
+			last_crtr += timer_latch;
 			clkevt.event_handler(&clkevt);
 		}
 		return IRQ_HANDLED;
@@ -120,7 +119,7 @@ clkevt32k_mode(enum clock_event_mode mode, struct clock_event_device *dev)
 	case CLOCK_EVT_MODE_PERIODIC:
 		/* PIT for periodic irqs; fixed rate of 1/HZ */
 		irqmask = AT91_ST_PITS;
-		regmap_write(regmap_st, AT91_ST_PIMR, RM9200_TIMER_LATCH);
+		regmap_write(regmap_st, AT91_ST_PIMR, timer_latch);
 		break;
 	case CLOCK_EVT_MODE_ONESHOT:
 		/* ALM for oneshot irqs, set by next_event()
@@ -182,7 +181,8 @@ static struct clock_event_device clkevt = {
  */
 static void __init atmel_st_timer_init(struct device_node *node)
 {
-	unsigned int val;
+	struct clk *sclk;
+	unsigned int sclk_rate, val;
 	int irq, ret;
 
 	regmap_st = syscon_node_to_regmap(node);
@@ -206,6 +206,19 @@ static void __init atmel_st_timer_init(struct device_node *node)
 	if (ret)
 		panic(pr_fmt("Unable to setup IRQ\n"));
 
+	sclk = of_clk_get(node, 0);
+	if (IS_ERR(sclk))
+		panic(pr_fmt("Unable to get slow clock\n"));
+
+	clk_prepare_enable(sclk);
+	if (ret)
+		panic(pr_fmt("Could not enable slow clock\n"));
+
+	sclk_rate = clk_get_rate(sclk);
+	if (!sclk_rate)
+		panic(pr_fmt("Invalid slow clock rate\n"));
+	timer_latch = (sclk_rate + HZ / 2) / HZ;
+
 	/* The 32KiHz "Slow Clock" (tick every 30517.58 nanoseconds) is used
 	 * directly for the clocksource and all clockevents, after adjusting
 	 * its prescaler from the 1 Hz default.
@@ -214,11 +227,11 @@ static void __init atmel_st_timer_init(struct device_node *node)
 
 	/* Setup timer clockevent, with minimum of two ticks (important!!) */
 	clkevt.cpumask = cpumask_of(0);
-	clockevents_config_and_register(&clkevt, AT91_SLOW_CLOCK,
+	clockevents_config_and_register(&clkevt, sclk_rate,
 					2, AT91_ST_ALMV);
 
 	/* register clocksource */
-	clocksource_register_hz(&clk32k, AT91_SLOW_CLOCK);
+	clocksource_register_hz(&clk32k, sclk_rate);
 }
 CLOCKSOURCE_OF_DECLARE(atmel_st_timer, "atmel,at91rm9200-st",
 		       atmel_st_timer_init);
-- 
2.1.4



From alexandre.belloni at free-electrons.com  Tue Aug 11 02:38:04 2015
From: alexandre.belloni at free-electrons.com (Alexandre Belloni)
Date: Tue, 11 Aug 2015 11:38:04 +0200
Subject: [PATCH v3 4/4] misc: atmel_tclib: get and use slow clock
In-Reply-To: <1439285884-16051-1-git-send-email-alexandre.belloni@free-electrons.com>
References: <1439285884-16051-1-git-send-email-alexandre.belloni@free-electrons.com>
Message-ID: <1439285884-16051-5-git-send-email-alexandre.belloni@free-electrons.com>

From: Boris Brezillon <boris.brezillon at free-electrons.com>

Commit dca1a4b5ff6e ("clk: at91: keep slow clk enabled to prevent system
hang") added a workaround for the slow clock as it is not properly handled
by its users.

Get and use the slow clock as it is necessary for the timer counters.

Signed-off-by: Boris Brezillon <boris.brezillon at free-electrons.com>
Signed-off-by: Alexandre Belloni <alexandre.belloni at free-electrons.com>
Acked-by: Greg Kroah-Hartman <gregkh at linuxfoundation.org>
---
Cc: Daniel Lezcano <daniel.lezcano at linaro.org>
Cc: Thomas Gleixner <tglx at linutronix.de>
Cc: Thierry Reding <thierry.reding at gmail.com>
Cc: linux-pwm at vger.kernel.org

 drivers/clocksource/tcb_clksrc.c |  8 ++++++++
 drivers/misc/atmel_tclib.c       |  4 ++++
 drivers/pwm/pwm-atmel-tcb.c      | 23 ++++++++++++++++-------
 include/linux/atmel_tc.h         |  1 +
 4 files changed, 29 insertions(+), 7 deletions(-)

diff --git a/drivers/clocksource/tcb_clksrc.c b/drivers/clocksource/tcb_clksrc.c
index b9b7277173c2..969ba03633b0 100644
--- a/drivers/clocksource/tcb_clksrc.c
+++ b/drivers/clocksource/tcb_clksrc.c
@@ -188,6 +188,13 @@ static int __init setup_clkevents(struct atmel_tc *tc, int clk32k_divisor_idx)
 	ret = clk_prepare_enable(t2_clk);
 	if (ret)
 		return ret;
+
+	ret = clk_prepare_enable(tc->slow_clk);
+	if (ret) {
+		clk_disable_unprepare(t2_clk);
+		return ret;
+	}
+
 	clk_disable(t2_clk);
 
 	clkevt.regs = tc->regs;
@@ -200,6 +207,7 @@ static int __init setup_clkevents(struct atmel_tc *tc, int clk32k_divisor_idx)
 	ret = request_irq(irq, ch2_irq, IRQF_TIMER, "tc_clkevt", &clkevt);
 	if (ret) {
 		clk_unprepare(t2_clk);
+		clk_disable_unprepare(tc->slow_clk);
 		return ret;
 	}
 
diff --git a/drivers/misc/atmel_tclib.c b/drivers/misc/atmel_tclib.c
index 0ca05c3ec8d6..ac24a4bd63f7 100644
--- a/drivers/misc/atmel_tclib.c
+++ b/drivers/misc/atmel_tclib.c
@@ -125,6 +125,10 @@ static int __init tc_probe(struct platform_device *pdev)
 	if (IS_ERR(clk))
 		return PTR_ERR(clk);
 
+	tc->slow_clk = devm_clk_get(&pdev->dev, "slow_clk");
+	if (IS_ERR(tc->slow_clk))
+		return PTR_ERR(tc->slow_clk);
+
 	r = platform_get_resource(pdev, IORESOURCE_MEM, 0);
 	tc->regs = devm_ioremap_resource(&pdev->dev, r);
 	if (IS_ERR(tc->regs))
diff --git a/drivers/pwm/pwm-atmel-tcb.c b/drivers/pwm/pwm-atmel-tcb.c
index d14e0677c92d..070a32a35295 100644
--- a/drivers/pwm/pwm-atmel-tcb.c
+++ b/drivers/pwm/pwm-atmel-tcb.c
@@ -305,7 +305,7 @@ static int atmel_tcb_pwm_config(struct pwm_chip *chip, struct pwm_device *pwm,
 	 */
 	if (i == 5) {
 		i = slowclk;
-		rate = 32768;
+		rate = clk_get_rate(tc->slow_clk);
 		min = div_u64(NSEC_PER_SEC, rate);
 		max = min << tc->tcb_config->counter_width;
 
@@ -387,9 +387,9 @@ static int atmel_tcb_pwm_probe(struct platform_device *pdev)
 
 	tcbpwm = devm_kzalloc(&pdev->dev, sizeof(*tcbpwm), GFP_KERNEL);
 	if (tcbpwm == NULL) {
-		atmel_tc_free(tc);
+		err = -ENOMEM;
 		dev_err(&pdev->dev, "failed to allocate memory\n");
-		return -ENOMEM;
+		goto err_free_tc;
 	}
 
 	tcbpwm->chip.dev = &pdev->dev;
@@ -400,17 +400,24 @@ static int atmel_tcb_pwm_probe(struct platform_device *pdev)
 	tcbpwm->chip.npwm = NPWM;
 	tcbpwm->tc = tc;
 
+	err = clk_prepare_enable(tc->slow_clk);
+	if (err)
+		goto err_free_tc;
+
 	spin_lock_init(&tcbpwm->lock);
 
 	err = pwmchip_add(&tcbpwm->chip);
-	if (err < 0) {
-		atmel_tc_free(tc);
-		return err;
-	}
+	if (err < 0)
+		goto err_free_tc;
 
 	platform_set_drvdata(pdev, tcbpwm);
 
 	return 0;
+
+err_free_tc:
+	atmel_tc_free(tc);
+
+	return err;
 }
 
 static int atmel_tcb_pwm_remove(struct platform_device *pdev)
@@ -418,6 +425,8 @@ static int atmel_tcb_pwm_remove(struct platform_device *pdev)
 	struct atmel_tcb_pwm_chip *tcbpwm = platform_get_drvdata(pdev);
 	int err;
 
+	clk_disable_unprepare(tcbpwm->tc->slow_clk);
+
 	err = pwmchip_remove(&tcbpwm->chip);
 	if (err < 0)
 		return err;
diff --git a/include/linux/atmel_tc.h b/include/linux/atmel_tc.h
index b87c1c7c242a..468fdfa643f0 100644
--- a/include/linux/atmel_tc.h
+++ b/include/linux/atmel_tc.h
@@ -67,6 +67,7 @@ struct atmel_tc {
 	const struct atmel_tcb_config *tcb_config;
 	int			irq[3];
 	struct clk		*clk[3];
+	struct clk		*slow_clk;
 	struct list_head	node;
 	bool			allocated;
 };
-- 
2.1.4



From eric.auger at linaro.org  Tue Aug 11 02:42:50 2015
From: eric.auger at linaro.org (Eric Auger)
Date: Tue, 11 Aug 2015 11:42:50 +0200
Subject: [PATCH 3/6] irqchip: GICv3: Skip LPI deactivation
In-Reply-To: <1436447951-22357-4-git-send-email-marc.zyngier@arm.com>
References: <1436447951-22357-1-git-send-email-marc.zyngier@arm.com>
 <1436447951-22357-4-git-send-email-marc.zyngier@arm.com>
Message-ID: <55C9C39A.3060208@linaro.org>

On 07/09/2015 03:19 PM, Marc Zyngier wrote:
> Contrary to other GICv3 interrupts, LPIs do not have an active state
> by virtue of being edge-triggered only (they only have a pending state).
> 
> Given this, there is no point trying to deactivate them, and we can
> skip the ICC_DIR_EL1 entierely.
> 
> Signed-off-by: Marc Zyngier <marc.zyngier at arm.com>
> ---
>  drivers/irqchip/irq-gic-v3.c | 8 ++++++--
>  1 file changed, 6 insertions(+), 2 deletions(-)
> 
> diff --git a/drivers/irqchip/irq-gic-v3.c b/drivers/irqchip/irq-gic-v3.c
> index 49768fc..e02592b 100644
> --- a/drivers/irqchip/irq-gic-v3.c
> +++ b/drivers/irqchip/irq-gic-v3.c
> @@ -295,10 +295,14 @@ static int gic_irq_get_irqchip_state(struct irq_data *d,
>  
>  static void gic_eoi_irq(struct irq_data *d)
>  {
> -	if (static_key_true(&supports_deactivate))
> +	if (static_key_true(&supports_deactivate)) {
> +		/* No need to deactivate an LPI */
> +		if (gic_irq(d) >= 8192)
In case of EOIMode == 0, we do not call EOI. I can't understand whether
it is an issue.
In 4.8.3 Properties of LPI, in 2d note it is written:

"SW must issue a write to EOI to clear the active priorities register,
hence the CPU interface still requires an active state for LPIs, even
through this is not necessary within the redistributor"

Eric
> +			return;
>  		gic_write_dir(gic_irq(d));
> -	else
> +	} else {
>  		gic_write_eoir(gic_irq(d));
> +	}
>  }
>  
>  static int gic_set_type(struct irq_data *d, unsigned int type)
> 



From linux at arm.linux.org.uk  Tue Aug 11 02:45:13 2015
From: linux at arm.linux.org.uk (Russell King - ARM Linux)
Date: Tue, 11 Aug 2015 10:45:13 +0100
Subject: [PATCH v3] ARM: appropriate __init annotation for const data
In-Reply-To: <alpine.LFD.2.20.1507271750160.1806@knanqh.ubzr>
References: <alpine.LFD.2.20.1507271750160.1806@knanqh.ubzr>
Message-ID: <20150811094512.GY7557@n2100.arm.linux.org.uk>

On Mon, Jul 27, 2015 at 06:27:52PM -0400, Nicolas Pitre wrote:
> Init data marked const should be annotated with __initconst for
> correctness and not __initdata.  In some cases the array gathering
> references to that data has to be marked const as well. This fixes
> LTO builds that otherwise fail with section mismatch errors.
> 
> Signed-off-by: Nicolas Pitre <nico at linaro.org>

Can we please get a little smarter at splitting up changes between core
ARM code and SoC ARM code please.

This now causes a delete/modify conflict between my tree and arm-soc,
because I'm now carrying ARMs patches which move arch/arm/kernel/psci.c
to drivers/firmware.

Right now, my resolution for that conflict is to just delete the old
file, I'm not even checking to see whether the new one needs this
change applied.  If it does, please submit a change on top of my
tree.

Thanks.

-- 
FTTC broadband for 0.8mile line: currently at 10.5Mbps down 400kbps up
according to speedtest.net.


From eric.auger at linaro.org  Tue Aug 11 02:45:18 2015
From: eric.auger at linaro.org (Eric Auger)
Date: Tue, 11 Aug 2015 11:45:18 +0200
Subject: [PATCH 4/6] irqchip: GIC: Use chip_data instead of handler_data
 for cascaded interrupts
In-Reply-To: <1436447951-22357-5-git-send-email-marc.zyngier@arm.com>
References: <1436447951-22357-1-git-send-email-marc.zyngier@arm.com>
 <1436447951-22357-5-git-send-email-marc.zyngier@arm.com>
Message-ID: <55C9C42E.8070602@linaro.org>

Hi Marc,
On 07/09/2015 03:19 PM, Marc Zyngier wrote:
> When used as a primary interrupt controller, the GIC driver uses
> irq_data->chip_data to extract controller-specific information.
> 
> When used as a secondary interrupt controller, it uses handler_data
> instead. As this difference is relatively pointless and only creates
> confusion, change the secondary path to match what the rest of the
> driver does.
not really related to this series' topic, is it?

Eric
> 
> Signed-off-by: Marc Zyngier <marc.zyngier at arm.com>
> ---
>  drivers/irqchip/irq-gic.c | 4 ++--
>  1 file changed, 2 insertions(+), 2 deletions(-)
> 
> diff --git a/drivers/irqchip/irq-gic.c b/drivers/irqchip/irq-gic.c
> index e264675..3c7f3a4 100644
> --- a/drivers/irqchip/irq-gic.c
> +++ b/drivers/irqchip/irq-gic.c
> @@ -298,7 +298,7 @@ static void __exception_irq_entry gic_handle_irq(struct pt_regs *regs)
>  
>  static void gic_handle_cascade_irq(unsigned int irq, struct irq_desc *desc)
>  {
> -	struct gic_chip_data *chip_data = irq_get_handler_data(irq);
> +	struct gic_chip_data *chip_data = irq_get_chip_data(irq);
>  	struct irq_chip *chip = irq_get_chip(irq);
>  	unsigned int cascade_irq, gic_irq;
>  	unsigned long status;
> @@ -341,7 +341,7 @@ void __init gic_cascade_irq(unsigned int gic_nr, unsigned int irq)
>  {
>  	if (gic_nr >= MAX_GIC_NR)
>  		BUG();
> -	if (irq_set_handler_data(irq, &gic_data[gic_nr]) != 0)
> +	if (irq_set_chip_data(irq, &gic_data[gic_nr]) != 0)
>  		BUG();
>  	irq_set_chained_handler(irq, gic_handle_cascade_irq);
>  }
> 



From Dave.Martin at arm.com  Tue Aug 11 02:47:11 2015
From: Dave.Martin at arm.com (Dave Martin)
Date: Tue, 11 Aug 2015 10:47:11 +0100
Subject: [PATCH REPOST #2] serial/amba-pl011: Disable interrupts around TX
 softirq
Message-ID: <1439286431-7602-1-git-send-email-Dave.Martin@arm.com>

pl011_tx_softirq() currently uses spin_{,un}lock(), which are not
sufficient to inhibit pl011_int() from being triggered by a local
IRQ and trying to re-take the same lock.  This can lead to
deadlocks.

This patch uses the _irq() locking variants instead to ensure that
pl011_int() handling for a given port is deferred until any
pl011_tx_softirq() work for that port is complete.


Notes for stable:

This patch fixes an issue that is fixed by the following upstream
commit, which is a more substantial rewrite of the affected code,
fixing multiple, mostly more minor issues:

        1e84d22322ceed4767db1e5342c830dd60c8210f
        serial/amba-pl011: Refactor and simplify TX FIFO handling

The upstream patch was rejected for stable on the reasonable grounds
that it was too big and complex a patch.  The original buggy code was
merged in v4.1, and the rewrite was merged in v4.2, leaving only v4.1
affected.


This patch replaces the 1e84d22, for 4.1.x only.

Fixes: 734745caeb9f serial/amba-pl011: Activate TX IRQ passively
Signed-off-by: Dave Martin <Dave.Martin at arm.com>
Tested-by: Robin Murphy <robin.murphy at arm.com>
Tested-by: Stefan Wahren <stefan.wahren at i2se.com>
Cc: stable <stable at vger.kernel.org> # 4.1.x
---
 drivers/tty/serial/amba-pl011.c |    4 ++--
 1 file changed, 2 insertions(+), 2 deletions(-)

diff --git a/drivers/tty/serial/amba-pl011.c b/drivers/tty/serial/amba-pl011.c
index 763eb20..0cc622a 100644
--- a/drivers/tty/serial/amba-pl011.c
+++ b/drivers/tty/serial/amba-pl011.c
@@ -1360,9 +1360,9 @@ static void pl011_tx_softirq(struct work_struct *work)
 	struct uart_amba_port *uap =
 		container_of(dwork, struct uart_amba_port, tx_softirq_work);
 
-	spin_lock(&uap->port.lock);
+	spin_lock_irq(&uap->port.lock);
 	while (pl011_tx_chars(uap)) ;
-	spin_unlock(&uap->port.lock);
+	spin_unlock_irq(&uap->port.lock);
 }
 
 static void pl011_tx_irq_seen(struct uart_amba_port *uap)
-- 
1.7.10.4



From joro at 8bytes.org  Tue Aug 11 02:49:51 2015
From: joro at 8bytes.org (Joerg Roedel)
Date: Tue, 11 Aug 2015 11:49:51 +0200
Subject: [PATCH v5 2/3] arm64: Add IOMMU dma_ops
In-Reply-To: <55C4CE7C.7050205@arm.com>
References: <cover.1438362603.git.robin.murphy@arm.com>
 <8a5abd0a9929aae160ccb74d7a8d9c3698f61910.1438362603.git.robin.murphy@arm.com>
 <20150807085233.GV14980@8bytes.org> <55C4CE7C.7050205@arm.com>
Message-ID: <20150811094951.GD14980@8bytes.org>

On Fri, Aug 07, 2015 at 04:27:56PM +0100, Robin Murphy wrote:
> As per the comments, the issue here lies in the order in which the
> OF/driver core code currently calls things for platform devices: as
> it stands we can't attach the device to a domain in
> arch_setup_dma_ops() because it doesn't have a group, and we can't
> even add it to a group ourselves because it isn't fully created and
> doesn't exist in sysfs yet. The only reason arch/arm is currently
> getting away without this workaround is that the few IOMMU drivers
> there hooked up to the generic infrastructure don't actually mind
> that they get an attach_device from arch_setup_dma_ops() before
> they've even seen an add_device (largely because they don't care
> about groups).

Hmm, what about just registering the iommu-driver in arch_setup_dma_ops
with bus_set_iommu and not care about devices? The code will iterate
over the devices already on the bus and tries to attach them to the
iommu driver. But as you said, the devices are not yet on the bus, so
when a device is later added by the OF/driver core code you can do
everything needed for the device in the add_device call-back.

This might include initializing the hardware iommu needed for the
device and setting its per-device dma_ops.

> Laurent's probe-deferral series largely solves these problems in the
> right place - adding identical boilerplate code to every IOMMU
> driver to do something they shouldn't have to know about (and don't
> necessarily have all the right information for) is exactly what we
> don't want to do. As discussed over on another thread, I'm planning
> to pick that series up and polish it off after this, but my top
> priority is getting the basic dma_ops functionality into arm64 that
> people need right now. I will be only too happy when I can submit
> the patch removing this notifier workaround ;)

I've experienced it often that someone promises me to fix things later,
but that it doesn't happen then, so please understand that I am pretty
cautious about adding such hacks ;)

> No driver other than the AMD IOMMU has any support yet. Support for
> IOMMU_DOMAIN_DMA can easily be added to existing drivers based on
> patch 1 of this series, but more generally it's not entirely clear
> how default domains are going to work beyond x86. On systems like
> Juno or Seattle with different sets of masters behind different
> IOMMU instances (with limited domain contexts each), the most
> sensible approach would be to have a single default domain per IOMMU
> (spanning domains across instances would need some hideous
> synchronisation logic for some implementations), but the current
> domain_alloc interface gives us no way to do that. On something like
> RK3288 with two different types of IOMMU on the platform "bus", it
> breaks down even further as there's no way to guarantee that
> iommu_domain_alloc() even gives you a domain from the right *driver*
> (hence bypassing it by going through ops directly here).

Default domain allocation comes down to how the bus organizes its
iommu-groups. For every group (at least in its current design) a default
domain is allocated. An a group is typically only behind a single iommu
instance.

> Only for PCI devices, via iommu_group_get_for_pci_dev(). The code
> here, however, only runs for platform devices - ops will be always
> null for a PCI device since of_iommu_configure() will have bailed
> out (see the silly warning removed by my patch you picked up the
> other day). Once iommu_group_get_for_dev() supports platform
> devices, this too can go away. In the meantime if someone adds PCI
> support to of_iommu_configure() and IOMMU_DOMAIN_DMA support to
> their IOMMU driver, then we'll get a domain back from
> iommu_get_domain_for_dev() and just use that.

What is the plan for getting an iommu-groups implementation for the
platform bus?


	Joerg



From gregory.clement at free-electrons.com  Tue Aug 11 02:58:47 2015
From: gregory.clement at free-electrons.com (Gregory CLEMENT)
Date: Tue, 11 Aug 2015 11:58:47 +0200
Subject: [PATCH] spi: orion: On a38x,
 implement "50MHZ SPI AC timing" Erratum No. FE-9144572
Message-ID: <1439287127-3782-1-git-send-email-gregory.clement@free-electrons.com>

From: Nadav Haklai <nadavh at marvell.com>

Description:
On Armada 38x, the device SPI interface supports frequencies of up to
50 MHz. However, due to this erratum, when the device core clock is
250 MHz and the SPI interfaces is configured for 50MHz SPI clock and
CPOL=CPHA=1, there might occur data corruption on reads from the SPI
device.

Workaround:
Work in one of the following configurations:
1. Set CPOL=CPHA=0 in "SPI Interface Configuration Register".
2. Set TMISO_SAMPLE value to 0x2 in "SPI Timing Parameters 1 Register"
before setting the interface.

[gregory.clement at free-electrons.com}: port to v4.2-rc, use
is_errata_50mhz_ac instead of using a new ARMADA_380_SPI spi type.

Signed-off-by: Nadav Haklai <nadavh at marvell.com>
Signed-off-by: Gregory CLEMENT <gregory.clement at free-electrons.com>
---
 drivers/spi/spi-orion.c | 54 ++++++++++++++++++++++++++++++++++++++++++++++++-
 1 file changed, 53 insertions(+), 1 deletion(-)

diff --git a/drivers/spi/spi-orion.c b/drivers/spi/spi-orion.c
index 8cad107a5b3f..a87cfd4ba17b 100644
--- a/drivers/spi/spi-orion.c
+++ b/drivers/spi/spi-orion.c
@@ -41,6 +41,11 @@
 #define ORION_SPI_DATA_OUT_REG		0x08
 #define ORION_SPI_DATA_IN_REG		0x0c
 #define ORION_SPI_INT_CAUSE_REG		0x10
+#define ORION_SPI_TIMING_PARAMS_REG	0x18
+
+#define ORION_SPI_TMISO_SAMPLE_MASK	(0x3 << 6)
+#define ORION_SPI_TMISO_SAMPLE_1	(1 << 6)
+#define ORION_SPI_TMISO_SAMPLE_2	(2 << 6)
 
 #define ORION_SPI_MODE_CPOL		(1 << 11)
 #define ORION_SPI_MODE_CPHA		(1 << 12)
@@ -70,6 +75,7 @@ struct orion_spi_dev {
 	unsigned int		min_divisor;
 	unsigned int		max_divisor;
 	u32			prescale_mask;
+	bool			is_errata_50mhz_ac;
 };
 
 struct orion_spi {
@@ -195,6 +201,41 @@ orion_spi_mode_set(struct spi_device *spi)
 	writel(reg, spi_reg(orion_spi, ORION_SPI_IF_CONFIG_REG));
 }
 
+static void
+orion_spi_50mhz_ac_timing_erratum(struct spi_device *spi, unsigned int speed)
+{
+	u32 reg;
+	struct orion_spi *orion_spi;
+
+	orion_spi = spi_master_get_devdata(spi->master);
+
+	/*
+	 * Erratum description: (Erratum NO. FE-9144572) The device
+	 * SPI interface supports frequencies of up to 50 MHz.
+	 * However, due to this erratum, when the device core clock is
+	 * 250 MHz and the SPI interfaces is configured for 50MHz SPI
+	 * clock and CPOL=CPHA=1 there might occur data corruption on
+	 * reads from the SPI device.
+	 * Erratum Workaround:
+	 * Work in one of the following configurations:
+	 * 1. Set CPOL=CPHA=0 in "SPI Interface Configuration
+	 * Register".
+	 * 2. Set TMISO_SAMPLE value to 0x2 in "SPI Timing Parameters 1
+	 * Register" before setting the interface.
+	 */
+	reg = readl(spi_reg(orion_spi, ORION_SPI_TIMING_PARAMS_REG));
+	reg &= ~ORION_SPI_TMISO_SAMPLE_MASK;
+
+	if (clk_get_rate(orion_spi->clk) == 250000000 &&
+			speed == 50000000 && spi->mode & SPI_CPOL &&
+			spi->mode & SPI_CPHA)
+		reg |= ORION_SPI_TMISO_SAMPLE_2;
+	else
+		reg |= ORION_SPI_TMISO_SAMPLE_1; /* This is the default value */
+
+	writel(reg, spi_reg(orion_spi, ORION_SPI_TIMING_PARAMS_REG));
+}
+
 /*
  * called only when no transfer is active on the bus
  */
@@ -216,6 +257,9 @@ orion_spi_setup_transfer(struct spi_device *spi, struct spi_transfer *t)
 
 	orion_spi_mode_set(spi);
 
+	if (orion_spi->devdata->is_errata_50mhz_ac)
+		orion_spi_50mhz_ac_timing_erratum(spi, speed);
+
 	rc = orion_spi_baudrate_set(spi, speed);
 	if (rc)
 		return rc;
@@ -413,6 +457,14 @@ static const struct orion_spi_dev armada_375_spi_dev_data = {
 	.prescale_mask = ARMADA_SPI_CLK_PRESCALE_MASK,
 };
 
+static const struct orion_spi_dev armada_380_spi_dev_data = {
+	.typ = ARMADA_SPI,
+	.max_hz = 50000000,
+	.max_divisor = 1920,
+	.prescale_mask = ARMADA_SPI_CLK_PRESCALE_MASK,
+	.is_errata_50mhz_ac = true,
+};
+
 static const struct of_device_id orion_spi_of_match_table[] = {
 	{
 		.compatible = "marvell,orion-spi",
@@ -428,7 +480,7 @@ static const struct of_device_id orion_spi_of_match_table[] = {
 	},
 	{
 		.compatible = "marvell,armada-380-spi",
-		.data = &armada_xp_spi_dev_data,
+		.data = &armada_380_spi_dev_data,
 	},
 	{
 		.compatible = "marvell,armada-390-spi",
-- 
2.1.0



From eric.auger at linaro.org  Tue Aug 11 03:03:12 2015
From: eric.auger at linaro.org (Eric Auger)
Date: Tue, 11 Aug 2015 12:03:12 +0200
Subject: [PATCH 5/6] irqchip: GICv3: Don't deactivate interrupts forwarded
 to a guest
In-Reply-To: <1436447951-22357-6-git-send-email-marc.zyngier@arm.com>
References: <1436447951-22357-1-git-send-email-marc.zyngier@arm.com>
 <1436447951-22357-6-git-send-email-marc.zyngier@arm.com>
Message-ID: <55C9C860.4020107@linaro.org>

On 07/09/2015 03:19 PM, Marc Zyngier wrote:
> Commit 0a4377de3056 ("genirq: Introduce irq_set_vcpu_affinity() to
> target an interrupt to a VCPU") added just what we needed at the
> lowest level to allow an interrupt to be deactivated by a guest.
> 
> When such a request reaches the GIC, it knows it doesn't need to
> perform the deactivation anymore, and can safely leave the guest
> do its magic. This of course requires additional support in both
> VFIO and KVM.
> 
> Signed-off-by: Marc Zyngier <marc.zyngier at arm.com>
> ---
>  drivers/irqchip/irq-gic-v3.c | 29 +++++++++++++++++++++++++++--
>  1 file changed, 27 insertions(+), 2 deletions(-)
> 
> diff --git a/drivers/irqchip/irq-gic-v3.c b/drivers/irqchip/irq-gic-v3.c
> index e02592b..a1ca9e6 100644
> --- a/drivers/irqchip/irq-gic-v3.c
> +++ b/drivers/irqchip/irq-gic-v3.c
> @@ -70,6 +70,11 @@ static inline int gic_irq_in_rdist(struct irq_data *d)
>  	return gic_irq(d) < 32;
>  }
>  
> +static inline bool forwarded_irq(struct irq_data *d)
> +{
> +	return d->handler_data != NULL;
> +}
> +
>  static inline void __iomem *gic_dist_base(struct irq_data *d)
>  {
>  	if (gic_irq_in_rdist(d))	/* SGI+PPI -> SGI_base for this CPU */
> @@ -231,6 +236,12 @@ static void gic_poke_irq(struct irq_data *d, u32 offset)
>  static void gic_mask_irq(struct irq_data *d)
>  {
>  	gic_poke_irq(d, GICD_ICENABLER);
> +	/*
> +	 * When masking a forwarded interrupt, make sure it is
> +	 * deactivated as well.
To me it is not straightforward to understand why a forwarded IRQ would
need to be DIR'ed when masked. This is needed because of the disable_irq
optimisation, I would add a related comment.

Eric
> +	 */
> +	if (static_key_true(&supports_deactivate) && forwarded_irq(d))
> +		gic_poke_irq(d, GICD_ICACTIVER);
>  }
>  
>  static void gic_unmask_irq(struct irq_data *d)
> @@ -296,8 +307,11 @@ static int gic_irq_get_irqchip_state(struct irq_data *d,
>  static void gic_eoi_irq(struct irq_data *d)
>  {
>  	if (static_key_true(&supports_deactivate)) {
> -		/* No need to deactivate an LPI */
> -		if (gic_irq(d) >= 8192)
> +		/*
> +		 * No need to deactivate an LPI, or an interrupt that
> +		 * is is getting forwarded to a vcpu.
> +		 */
> +		if (gic_irq(d) >= 8192 || forwarded_irq(d))
>  			return;
>  		gic_write_dir(gic_irq(d));
>  	} else {
> @@ -331,6 +345,16 @@ static int gic_set_type(struct irq_data *d, unsigned int type)
>  	return gic_configure_irq(irq, type, base, rwp_wait);
>  }
>  
> +static int gic_irq_set_vcpu_affinity(struct irq_data *d, void *vcpu)
> +{
> +	if (static_key_true(&supports_deactivate)) {
> +		d->handler_data = vcpu;
> +		return 0;
> +	}
> +
> +	return -EINVAL;
> +}
> +
>  static u64 gic_mpidr_to_affinity(u64 mpidr)
>  {
>  	u64 aff;
> @@ -678,6 +702,7 @@ static struct irq_chip gic_chip = {
>  	.irq_set_affinity	= gic_set_affinity,
>  	.irq_get_irqchip_state	= gic_irq_get_irqchip_state,
>  	.irq_set_irqchip_state	= gic_irq_set_irqchip_state,
> +	.irq_set_vcpu_affinity	= gic_irq_set_vcpu_affinity,
>  	.flags			= IRQCHIP_SET_TYPE_MASKED,
>  };
>  
> 



From t.remmet at phytec.de  Tue Aug 11 03:04:16 2015
From: t.remmet at phytec.de (Teresa Remmet)
Date: Tue, 11 Aug 2015 12:04:16 +0200
Subject: [PATCH] ARM: dts: am335x-phycore-som: Move NAND partition table
 into board files
In-Reply-To: <1438938599-11252-1-git-send-email-matthias.klein@optimeas.de>
References: <1438938599-11252-1-git-send-email-matthias.klein@optimeas.de>
Message-ID: <1439287456.3733.18.camel@lws-tremmet.phytec.de>

Hello Matthias,

Am Freitag, den 07.08.2015, 11:09 +0200 schrieb Matthias Klein:
> Partitions which are defined in the som file can not be deleted in the
> board file.
> 
> Signed-off-by: Matthias Klein <matthias.klein at optimeas.de>
> ---
>  arch/arm/boot/dts/am335x-phycore-som.dtsi | 37 -------------------------
>  arch/arm/boot/dts/am335x-wega.dtsi        | 45 +++++++++++++++++++++++++++++++
>  2 files changed, 45 insertions(+), 37 deletions(-)
> 
> diff --git a/arch/arm/boot/dts/am335x-phycore-som.dtsi b/arch/arm/boot/dts/am335x-phycore-som.dtsi
> index 4d28fc3..8f12bd54 100644
> --- a/arch/arm/boot/dts/am335x-phycore-som.dtsi
> +++ b/arch/arm/boot/dts/am335x-phycore-som.dtsi
> @@ -189,43 +189,6 @@
>  
>  		#address-cells = <1>;
>  		#size-cells = <1>;
> -
> -		partition at 0 {
> -			label = "xload";
> -			reg = <0x0 0x20000>;
> -		};
> -		partition at 1 {
> -			label = "xload_backup1";
> -			reg = <0x20000 0x20000>;
> -		};
> -		partition at 2 {
> -			label = "xload_backup2";
> -			reg = <0x40000 0x20000>;
> -		};
> -		partition at 3 {
> -			label = "xload_backup3";
> -			reg = <0x60000 0x20000>;
> -		};
> -		partition at 4 {
> -			label = "barebox";
> -			reg = <0x80000 0x80000>;
> -		};
> -		partition at 5 {
> -			label = "bareboxenv";
> -			reg = <0x100000 0x40000>;
> -		};
> -		partition at 6 {
> -			label = "oftree";
> -			reg = <0x140000 0x40000>;
> -		};
> -		partition at 7 {
> -			label = "kernel";
> -			reg = <0x180000 0x800000>;
> -		};
> -		partition at 8 {
> -			label = "root";
> -			reg = <0x980000 0x0>;
> -		};
>  	};
>  };
>  
> diff --git a/arch/arm/boot/dts/am335x-wega.dtsi b/arch/arm/boot/dts/am335x-wega.dtsi
> index 5e541bd..945a41d 100644
> --- a/arch/arm/boot/dts/am335x-wega.dtsi
> +++ b/arch/arm/boot/dts/am335x-wega.dtsi
> @@ -149,3 +149,48 @@
>  &usb1_phy {
>  	status = "okay";
>  };

I don't think that moving the nand partition to the carrier board dtsi is correct.
The nand partition does not have anything to do with the carrier board in first place.
So they should rather be moved to the am335x-wega-rdk.dts which does describe the 
board in a whole. 
If you do this, you should remove the spi partitions from the SoM dtsi also.

And it is generally possible to delete nodes from a device tree with /delete-node/ &my_node; 
But I have actually not tested this when overwriting partitions. Neither know if this whould
be a sane solution.

Regards
Teresa

> +
> +&nandflash {
> +	partition at 0 {
> +		label = "xload";
> +		reg = <0x0 0x20000>;
> +	};
> +
> +	partition at 1 {
> +		label = "xload_backup1";
> +		reg = <0x20000 0x20000>;
> +	};
> +
> +	partition at 2 {
> +		label = "xload_backup2";
> +		reg = <0x40000 0x20000>;
> +	};
> +
> +	partition at 3 {
> +		label = "xload_backup3";
> +		reg = <0x60000 0x20000>;
> +	};
> +
> +	partition at 4 {
> +		label = "barebox";
> +		reg = <0x80000 0x80000>;
> +	};
> +
> +	partition at 5 {
> +		label = "bareboxenv";
> +		reg = <0x100000 0x40000>;
> +	};
> +
> +	partition at 6 {
> +		label = "oftree";
> +		reg = <0x140000 0x40000>;
> +	};
> +	partition at 7 {
> +		label = "kernel";
> +		reg = <0x180000 0x800000>;
> +	};
> +	partition at 8 {
> +		label = "root";
> +		reg = <0x980000 0x0>;
> +	};
> +};




From leif.lindholm at linaro.org  Tue Aug 11 03:07:21 2015
From: leif.lindholm at linaro.org (Leif Lindholm)
Date: Tue, 11 Aug 2015 11:07:21 +0100
Subject: earlycon issues in -next with amba-pl011 updates
In-Reply-To: <55C94247.8020701@hurleysoftware.com>
References: <20150810232312.GB10728@bivouac.eciton.net>
 <55C94247.8020701@hurleysoftware.com>
Message-ID: <20150811100721.GE10728@bivouac.eciton.net>

Hi Peter,

On Mon, Aug 10, 2015 at 08:31:03PM -0400, Peter Hurley wrote:
> > The issue only appears with earlycon on command line, for pl011
> > consoles.
> > 
> > Some investigation shows that the cause lies with
> > commit 7b753f318d14 ("uart: pl011: Introduce register accessor")
> > and
> > commit 2c096a9eedc6 ("uart: pl011: Introduce register look up table")
> > 
> > Specifically, the changes to pl011_putc() are incorrect:
> > The new pl011_ accessors take a (struct uart_amba_port *) input, but
> > pl011_putc() directly uses the incoming (struct uart_port *) for this.
> > 
> > Apart from ending up with an unintended/incorrect UART base address,
> > the introduction of the lookup table for register offsets also means
> > the accessors try to dereference (struct uart_amba_port *)->reg_lut.
> 
> 
> Thanks for the bug report and bisect, and apologies for the breakage;
> I should have caught that on review.

I wouldn't have found it if I didn't have the boot failure to track
down, and I'm _not_ going to tell you how long I spent doing that.
 
> Would you please test the patch below and see if that resolves the
> problem for you?

Yeah, that's a more straightforward fix.

> PS - _NOT_ even compile-tested, sorry.
> 
> --- >% ---
> Subject: [PATCH] serial: pl011: Fix earlycon register LUT breakage
> 
> Commit 7b753f318d14 ("uart: pl011: Introduce register accessor")
> mistakenly used the register LUT i/o accessors for the pl011
> earlycon. Since the port has not been probed at earlycon time,
> the struct uart_amba_port (and register LUTs) are uninitialized.
> 
> Use direct register addressing for pl011 earlycon; other h/w supported
> by the amba-pl011 driver should declare an alternate earlycon.
> 
> Cc: Jun Nie <jun.nie at linaro.org>
> Signed-off-by: Peter Hurley <peter at hurleysoftware.com>
> ---
>  drivers/tty/serial/amba-pl011.c | 9 +++------
>  1 file changed, 3 insertions(+), 6 deletions(-)
> 
> diff --git a/drivers/tty/serial/amba-pl011.c b/drivers/tty/serial/amba-pl011.c
> index 2af09ab..fd54991 100644
> --- a/drivers/tty/serial/amba-pl011.c
> +++ b/drivers/tty/serial/amba-pl011.c
> @@ -2348,13 +2348,10 @@ static struct console amba_console = {
>  
>  static void pl011_putc(struct uart_port *port, int c)
>  {
> -	struct uart_amba_port *uap =
> -	    container_of(port, struct uart_amba_port, port);
> -
> -	while (pl011_readw(uap, REG_FR) & UART01x_FR_TXFF)
> +	while (readl(port->membase + UART01x_FR) & UART01x_FR_TXFF)
>  		;
> -	pl011_writeb(uap, c, REG_DR);
> -	while (pl011_readw(uap, REG_FR) & uap->fr_busy)
> +	writeb(c, port->membase + UART01x_DR);
> +	while (readl(port->membase + UART01x_FR) & UART01x_FR_BUSY)
>  		;
>  }
>  
> -- 
> 2.5.0

It works, but builds with:
drivers/tty/serial/amba-pl011.c:329:13: warning: ?pl011_writeb?
defined but not used [-Wunused-function]
 static void pl011_writeb(struct uart_amba_port *uap, u8 val, int
 index)
             ^
I was dithering about whether having _relaxed accessors in post boot
code and plain ones in earlycon was an issue, but I guess it doesn't
matter much.

/
    Leif


From eric.auger at linaro.org  Tue Aug 11 03:06:49 2015
From: eric.auger at linaro.org (Eric Auger)
Date: Tue, 11 Aug 2015 12:06:49 +0200
Subject: [PATCH 0/6] irqchip: GICv2/v3: Add support for irq_vcpu_affinity
In-Reply-To: <1436447951-22357-1-git-send-email-marc.zyngier@arm.com>
References: <1436447951-22357-1-git-send-email-marc.zyngier@arm.com>
Message-ID: <55C9C939.2020408@linaro.org>

Hi Marc,

The series works fine with KVM platform device passthrough use case
(Calxeda Midway, GICv2, SPI assignment with VFIO). My integration branch
can be found at
https://git.linaro.org/people/eric.auger/linux.git/shortlog/refs/heads/v4.2-rc6-irq-forward-v3
if useful.

Tested-by: Eric Auger <eric.auger at linaro.org>

Best Regards

Eric
On 07/09/2015 03:19 PM, Marc Zyngier wrote:
> The GICv2 and GICv3 architectures allow an active physical interrupt
> to be forwarded to a guest, and the guest to indirectly perform the
> deactivation of the interrupt by performing an EOI on the virtual
> interrupt (see for example the GICv2 spec, 3.2.1).
> 
> This allows some substantial performance improvement for level
> triggered interrupts that otherwise have to be masked/unmasked in
> VFIO, not to mention the required trap back to KVM when the guest
> performs an EOI.
> 
> To enable this, the GICs need to be switched to a different EOImode,
> where a taken interrupt can be left "active" (which prevents the same
> interrupt from being taken again), while other interrupts are still
> being processed normally.
> 
> We also use the new irq_set_vcpu_affinity hook that was introduced for
> Intel's "Posted Interrupts" to determine whether or not to perform the
> deactivation at EOI-time.
> 
> As all of this only makes sense when the kernel can behave as a
> hypervisor, we only enable this mode on detecting that the kernel was
> actually booted in HYP mode, and that the GIC supports this feature.
> 
> This series is a complete rework of a RFC I sent over a year ago:
> 
> http://lists.infradead.org/pipermail/linux-arm-kernel/2014-June/266328.html
> 
> Since then, a lot has been either merged (the irqchip_state) or reworked
> (my active-timer series: http://www.spinics.net/lists/kvm/msg118768.html),
> and this implements the last few bits for Eric Auger's series to
> finally make it into the kernel:
> 
> https://lkml.org/lkml/2015/7/2/268
> https://lkml.org/lkml/2015/7/6/291
> 
> With all these patches combined, physical interrupt routing from the
> kernel into a VM becomes possible.
> 
> This has been tested on Juno (GICv2) and FastModel (GICv3). A branch
> is available at:
> 
> git://git.kernel.org/pub/scm/linux/kernel/git/maz/arm-platforms.git irq/gic-irq-vcpu-affinity
> 
> Marc Zyngier (6):
>   irqchip: GICv3: Convert to EOImode == 1
>   irqchip: GIC: Convert to EOImode == 1
>   irqchip: GICv3: Skip LPI deactivation
>   irqchip: GIC: Use chip_data instead of handler_data for cascaded
>     interrupts
>   irqchip: GICv3: Don't deactivate interrupts forwarded to a guest
>   irqchip: GIC: Don't deactivate interrupts forwarded to a guest
> 
>  drivers/irqchip/irq-gic-v3.c       | 57 +++++++++++++++++++++++++++++++--
>  drivers/irqchip/irq-gic.c          | 64 +++++++++++++++++++++++++++++++++++---
>  include/linux/irqchip/arm-gic-v3.h |  9 ++++++
>  include/linux/irqchip/arm-gic.h    |  4 +++
>  4 files changed, 126 insertions(+), 8 deletions(-)
> 



From ian.campbell at citrix.com  Tue Aug 11 03:07:26 2015
From: ian.campbell at citrix.com (Ian Campbell)
Date: Tue, 11 Aug 2015 11:07:26 +0100
Subject: [PATCH v5] dtb: Create a common home for cross-architecture
 dtsi files.
In-Reply-To: <1438618000-1091-1-git-send-email-ian.campbell@citrix.com>
References: <1438618000-1091-1-git-send-email-ian.campbell@citrix.com>
Message-ID: <1439287646.9747.212.camel@citrix.com>

On Mon, 2015-08-03 at 17:06 +0100, Ian Campbell wrote:
> Commit 9ccd608070b6 ("arm64: dts: add device tree for ARM SMM-A53x2 on
> LogicTile Express 20MG") added a new dts file to arch/arm64 which
> included "../../../../arm/boot/dts/vexpress-v2m-rs1.dtsi", i.e. a
> .dtsi supplied by arch/arm.
> 
> Unfortunately this causes some issues for the split device tree
> repository[0], since things get moved around there. In that context
> the new .dts ends up at src/arm64/arm/vexpress-v2f-1xv7-ca53x2.dts
> while the include is at src/arm/vexpress-v2m-rs1.dtsi.

Hi Grant,

Do you think there is any chance of getting this into 4.2-rc$NEXT or shall
we wait until 4.3? I'm assuming this should go via the DT tree, but maybe
it should go via an ARM tree?

Ian.

> 
> The sharing of the .dtsi is legitimate since the baseboard is the same
> for various vexpress systems whatever processor they use.
> 
> Rather than using ../../ tricks to pickup .dtsi files from another
> arch this patch creates a new directory kernel/dts as a home for such
> cross-arch .dtsi files and arranges for it to be in the include path
> for both dtc and cpp. The dtsi file itself is moved into a vendor
> subdir in this case "arm" (the vendor, not the ARCH=).
> 
> [0] https://git.kernel.org/cgit/linux/kernel/git/devicetree/devicetree
> -rebasing.git/
> 
> Signed-off-by: Ian Campbell <ian.campbell at citrix.com>
> Cc: Rob Herring <robh+dt at kernel.org>
> Cc: Pawel Moll <pawel.moll at arm.com>
> Cc: Mark Rutland <mark.rutland at arm.com>
> Cc: Kumar Gala <galak at codeaurora.org>
> Cc: Liviu Dudau <liviu.dudau at arm.com>
> Cc: Sudeep Holla <sudeep.holla at arm.com>
> Cc: Lorenzo Pieralisi <lorenzo.pieralisi at arm.com>
> Cc: Russell King <linux at arm.linux.org.uk>
> Cc: Catalin Marinas <catalin.marinas at arm.com>
> Cc: Will Deacon <will.deacon at arm.com>
> Cc: Kristina Martsenko <kristina.martsenko at arm.com>
> Cc: Kevin Hilman <khilman at linaro.org>
> Cc: devicetree at vger.kernel.org
> Cc: linux-kernel at vger.kernel.org
> Cc: linux-arm-kernel at lists.infradead.org
> Cc: linux-kbuild at vger.kernel.org
> Acked-by: Mark Rutland <mark.rutland at arm.com>
> Acked-by: Rob Herring <robh at kernel.org>
> Acked-by: Liviu Dudau <Liviu.Dudau at arm.com>
> Reviewed-by: Masahiro Yamada <yamada.masahiro at socionext.com>
> ---
> v2: Move to include/dt-dtsi and introduce a per-vendor subdirectory.
> 
> v3: Move to kernel/dts.
>     Include new directory in DTC include path as well as cpp path, and
>     therefore switch back to /include/.
>     Update MAINTAINERS
> 
> v4: Change path in changelog too.
>     Add ()s to title of 9ccd608070b6.
> 
> v5: Remove stale reference to switching from /include/ to #include.
> ---
>  Documentation/devicetree/bindings/arm/vexpress.txt          | 2 +-
>  MAINTAINERS                                                 | 1 +
>  arch/arm/boot/dts/vexpress-v2p-ca15-tc1.dts                 | 2 +-
>  arch/arm/boot/dts/vexpress-v2p-ca15_a7.dts                  | 2 +-
>  arch/arm/boot/dts/vexpress-v2p-ca5s.dts                     | 2 +-
>  arch/arm64/boot/dts/arm/vexpress-v2f-1xv7-ca53x2.dts        | 2 +-
>  {arch/arm/boot/dts => kernel/dts/arm}/vexpress-v2m-rs1.dtsi | 0
>  scripts/Makefile.lib                                        | 3 ++-
>  8 files changed, 8 insertions(+), 6 deletions(-)
>  rename {arch/arm/boot/dts => kernel/dts/arm}/vexpress-v2m-rs1.dtsi 
> (100%)
> 
> diff --git a/Documentation/devicetree/bindings/arm/vexpress.txt 
> b/Documentation/devicetree/bindings/arm/vexpress.txt
> index 39844cd..b6031d9 100644
> --- a/Documentation/devicetree/bindings/arm/vexpress.txt
> +++ b/Documentation/devicetree/bindings/arm/vexpress.txt
> @@ -223,7 +223,7 @@ Example of a VE tile description (simplified)
>  		/* Active high IRQ 0 is connected to GIC's SPI0 */
>  		interrupt-map = <0 0 0 &gic 0 0 4>;
>  
> -		/include/ "vexpress-v2m-rs1.dtsi"
> +		/include/ "arm/vexpress-v2m-rs1.dtsi"
>  	};
>  };
>  
> diff --git a/MAINTAINERS b/MAINTAINERS
> index a226416..1941078 100644
> --- a/MAINTAINERS
> +++ b/MAINTAINERS
> @@ -7537,6 +7537,7 @@ S:	Maintained
>  F:	Documentation/devicetree/
>  F:	arch/*/boot/dts/
>  F:	include/dt-bindings/
> +F:	kernel/dts/
>  
>  OPEN FIRMWARE AND DEVICE TREE OVERLAYS
>  M:	Pantelis Antoniou <pantelis.antoniou at konsulko.com>
> diff --git a/arch/arm/boot/dts/vexpress-v2p-ca15-tc1.dts 
> b/arch/arm/boot/dts/vexpress-v2p-ca15-tc1.dts
> index 9420053..b144092 100644
> --- a/arch/arm/boot/dts/vexpress-v2p-ca15-tc1.dts
> +++ b/arch/arm/boot/dts/vexpress-v2p-ca15-tc1.dts
> @@ -278,6 +278,6 @@
>  				<0 0 41 &gic 0 41 4>,
>  				<0 0 42 &gic 0 42 4>;
>  
> -		/include/ "vexpress-v2m-rs1.dtsi"
> +		/include/ "arm/vexpress-v2m-rs1.dtsi"
>  	};
>  };
> diff --git a/arch/arm/boot/dts/vexpress-v2p-ca15_a7.dts 
> b/arch/arm/boot/dts/vexpress-v2p-ca15_a7.dts
> index 17f63f7..350f402 100644
> --- a/arch/arm/boot/dts/vexpress-v2p-ca15_a7.dts
> +++ b/arch/arm/boot/dts/vexpress-v2p-ca15_a7.dts
> @@ -636,6 +636,6 @@
>  				<0 0 41 &gic 0 41 4>,
>  				<0 0 42 &gic 0 42 4>;
>  
> -		/include/ "vexpress-v2m-rs1.dtsi"
> +		/include/ "arm/vexpress-v2m-rs1.dtsi"
>  	};
>  };
> diff --git a/arch/arm/boot/dts/vexpress-v2p-ca5s.dts 
> b/arch/arm/boot/dts/vexpress-v2p-ca5s.dts
> index d2709b7..585ced0 100644
> --- a/arch/arm/boot/dts/vexpress-v2p-ca5s.dts
> +++ b/arch/arm/boot/dts/vexpress-v2p-ca5s.dts
> @@ -248,6 +248,6 @@
>  				<0 0 41 &gic 0 41 4>,
>  				<0 0 42 &gic 0 42 4>;
>  
> -		/include/ "vexpress-v2m-rs1.dtsi"
> +		/include/ "arm/vexpress-v2m-rs1.dtsi"
>  	};
>  };
> diff --git a/arch/arm64/boot/dts/arm/vexpress-v2f-1xv7-ca53x2.dts 
> b/arch/arm64/boot/dts/arm/vexpress-v2f-1xv7-ca53x2.dts
> index 5b1d018..c044804 100644
> --- a/arch/arm64/boot/dts/arm/vexpress-v2f-1xv7-ca53x2.dts
> +++ b/arch/arm64/boot/dts/arm/vexpress-v2f-1xv7-ca53x2.dts
> @@ -186,6 +186,6 @@
>  				<0 0 41 &gic GIC_SPI 41 
> IRQ_TYPE_LEVEL_HIGH>,
>  				<0 0 42 &gic GIC_SPI 42 
> IRQ_TYPE_LEVEL_HIGH>;
>  
> -		/include/ "../../../../arm/boot/dts/vexpress-v2m
> -rs1.dtsi"
> +		/include/ "arm/vexpress-v2m-rs1.dtsi"
>  	};
>  };
> diff --git a/arch/arm/boot/dts/vexpress-v2m-rs1.dtsi 
> b/kernel/dts/arm/vexpress-v2m-rs1.dtsi
> similarity index 100%
> rename from arch/arm/boot/dts/vexpress-v2m-rs1.dtsi
> rename to kernel/dts/arm/vexpress-v2m-rs1.dtsi
> diff --git a/scripts/Makefile.lib b/scripts/Makefile.lib
> index 79e8661..b4d9fb6 100644
> --- a/scripts/Makefile.lib
> +++ b/scripts/Makefile.lib
> @@ -163,6 +163,7 @@ dtc_cpp_flags  = -Wp,-MD,$(depfile).pre.tmp -nostdinc
>                     \
>  		 -I$(srctree)/arch/$(SRCARCH)/boot/dts                  
>  \
>  		 -I$(srctree)/arch/$(SRCARCH)/boot/dts/include          
>  \
>  		 -I$(srctree)/drivers/of/testcase-data                  
>  \
> +		 -I$(srctree)/kernel/dts                                
>  \
>  		 -undef -D__DTS__
>  
>  # Finds the multi-part object the current object will be linked into
> @@ -285,7 +286,7 @@ quiet_cmd_dtc = DTC     $@
>  cmd_dtc = mkdir -p $(dir ${dtc-tmp}) ; \
>  	$(CPP) $(dtc_cpp_flags) -x assembler-with-cpp -o $(dtc-tmp) $< ; 
> \
>  	$(objtree)/scripts/dtc/dtc -O dtb -o $@ -b 0 \
> -		-i $(dir $<) $(DTC_FLAGS) \
> +		-i $(dir $<) -i $(srctree)/kernel/dts $(DTC_FLAGS) \
>  		-d $(depfile).dtc.tmp $(dtc-tmp) ; \
>  	cat $(depfile).pre.tmp $(depfile).dtc.tmp > $(depfile)
>  


From viresh.kumar at linaro.org  Tue Aug 11 03:09:41 2015
From: viresh.kumar at linaro.org (Viresh Kumar)
Date: Tue, 11 Aug 2015 15:39:41 +0530
Subject: [PATCH v4 2/2] dt: power: st: Provide bindings for ST's OPPs
In-Reply-To: <20150811093039.GA18282@x1>
References: <20150728225510.GB3159@codeaurora.org> <20150729081403.GH2284@x1>
 <20150729221526.GE3159@codeaurora.org> <20150730084634.GD9319@x1>
 <CAL_JsqKQLQ15qSt95zBZykzzPhcUrtZzhk29a76n+r_3719AiA@mail.gmail.com>
 <20150731163715.GV3159@codeaurora.org> <20150803034642.GV899@linux>
 <20150810132247.GH3249@x1> <20150811080023.GB5509@linux>
 <20150811093039.GA18282@x1>
Message-ID: <20150811100941.GG5509@linux>

On 11-08-15, 10:30, Lee Jones wrote:
> On Tue, 11 Aug 2015, Viresh Kumar wrote:
> 
> > On 10-08-15, 14:22, Lee Jones wrote:
> > > >  Optional properties:
> > > > +- opp-cuts: One or more strings, describing the versions of hardware the OPPs
> > > > +  can support.
> > > 
> > > This isn't very generic.
> > > 
> > > I'm guessing some vendors my have quite a few ways to differentiate
> > > between board versions/revisions/cuts etc.
> > > 
> > > How about another array where a vendor can choose to identify a piece
> > > of hardware however they see fit.
> > > 
> > > Example 1 (simple version):
> > > 
> > > /* Version 1 */
> > > opp-version = <1>;
> > > 
> > > Example 2 (using the kernel's versioning):
> > > 
> > > /* 2.6.32-rc1 */
> > > opp-version = <2 6 32 1>;
> > > 
> > > Example 3 (using ST's versioning):
> > > 
> > > /* Major 2, Minor 0, Cut 2, All substrates */
> > > opp-version = <2 0 2 0xff>;
> > 
> > But how will we parse this with generic code ?
> 
> Why would you want to?

So that individual platforms don't need to reinvent the wheel ?

-- 
viresh


From k.kozlowski.k at gmail.com  Tue Aug 11 03:09:03 2015
From: k.kozlowski.k at gmail.com (Krzysztof Kozlowski)
Date: Tue, 11 Aug 2015 19:09:03 +0900
Subject: [PATCH v2 0/3] mfd: EXYNOS: Properly shutdown Odroid XU3
Message-ID: <1439287746-14034-1-git-send-email-k.kozlowski.k@gmail.com>

Hi,

Changelog put in each patch message.

This fixes shutdown of Odroid XU3 family. More details in patch 2.

Patches are independent, please pick up freely.

Best regards,
Krzysztof


Krzysztof Kozlowski (3):
  mfd: documentation: dt: Document grounded ACOKB pin on S2MPS11
  mfd: s2mps11: Add manual shutdown method for Odroid XU3
  ARM: dts: Fix power off method on exynos5422-odroidxu3

 Documentation/devicetree/bindings/mfd/s2mps11.txt  |  4 +++
 arch/arm/boot/dts/exynos5422-odroidxu3-common.dtsi |  1 +
 drivers/mfd/sec-core.c                             | 30 ++++++++++++++++++++++
 include/linux/mfd/samsung/core.h                   |  2 ++
 include/linux/mfd/samsung/s2mps11.h                |  1 +
 5 files changed, 38 insertions(+)

-- 
2.1.4



From k.kozlowski.k at gmail.com  Tue Aug 11 03:09:04 2015
From: k.kozlowski.k at gmail.com (Krzysztof Kozlowski)
Date: Tue, 11 Aug 2015 19:09:04 +0900
Subject: [PATCH v2 1/3] mfd: documentation: dt: Document grounded ACOKB pin on
 S2MPS11
In-Reply-To: <1439287746-14034-1-git-send-email-k.kozlowski.k@gmail.com>
References: <1439287746-14034-1-git-send-email-k.kozlowski.k@gmail.com>
Message-ID: <1439287746-14034-2-git-send-email-k.kozlowski.k@gmail.com>

Document a new Device Tree property 'samsung,s2mps11-acokb-ground'
indicating that ACOKB pin of S2MPS11 PMIC is connected to the ground so
the PMIC must manually set PWRHOLD bit in CTRL1 register to turn off the
power.

Signed-off-by: Krzysztof Kozlowski <k.kozlowski.k at gmail.com>
Reviewed-by: Javier Martinez Canillas <javier at osg.samsung.com>
Acked-by: Lee Jones <lee.jones at linaro.org>

---

Changes since v1:
1. Split bindings documentation to separate patch (suggested by Lee).
2. Add Javier's reviewed-by and Lee's acked-by.
---
 Documentation/devicetree/bindings/mfd/s2mps11.txt | 4 ++++
 1 file changed, 4 insertions(+)

diff --git a/Documentation/devicetree/bindings/mfd/s2mps11.txt b/Documentation/devicetree/bindings/mfd/s2mps11.txt
index 57a045016fca..90eaef393325 100644
--- a/Documentation/devicetree/bindings/mfd/s2mps11.txt
+++ b/Documentation/devicetree/bindings/mfd/s2mps11.txt
@@ -15,6 +15,10 @@ Optional properties:
 - interrupt-parent: Specifies the phandle of the interrupt controller to which
   the interrupts from s2mps11 are delivered to.
 - interrupts: Interrupt specifiers for interrupt sources.
+- samsung,s2mps11-acokb-ground: Indicates that ACOKB pin of S2MPS11 PMIC is
+  connected to the ground so the PMIC must manually set PWRHOLD bit in CTRL1
+  register to turn off the power. Usually the ACOKB is pulled up to VBATT so
+  when PWRHOLD pin goes low, the rising ACOKB will trigger power off.
 
 Optional nodes:
 - clocks: s2mps11, s2mps13 and s5m8767 provide three(AP/CP/BT) buffered 32.768
-- 
2.1.4



From k.kozlowski.k at gmail.com  Tue Aug 11 03:09:06 2015
From: k.kozlowski.k at gmail.com (Krzysztof Kozlowski)
Date: Tue, 11 Aug 2015 19:09:06 +0900
Subject: [PATCH v2 3/3] ARM: dts: Fix power off method on exynos5422-odroidxu3
In-Reply-To: <1439287746-14034-1-git-send-email-k.kozlowski.k@gmail.com>
References: <1439287746-14034-1-git-send-email-k.kozlowski.k@gmail.com>
Message-ID: <1439287746-14034-4-git-send-email-k.kozlowski.k@gmail.com>

The Odroid XU3 family boards have ACOKB pin of PMIC grounded, instead of
pulled up as usual. This means that PMIC must manually set PWRHOLD field
in its CTRL1 register to low before initiating power down.

This fixes Odroid XU3 powering off:
[   25.966053] reboot: Power down
[   25.967679] Power down.
[   26.070174] Power down failed, please power off system manually.

Signed-off-by: Krzysztof Kozlowski <k.kozlowski.k at gmail.com>
Reported-by: Anand Moon <linux.amoon at gmail.com>
Reviewed-by: Javier Martinez Canillas <javier at osg.samsung.com>

---

Changes since v1:
1. Add Javier's reviewed-by.
---
 arch/arm/boot/dts/exynos5422-odroidxu3-common.dtsi | 1 +
 1 file changed, 1 insertion(+)

diff --git a/arch/arm/boot/dts/exynos5422-odroidxu3-common.dtsi b/arch/arm/boot/dts/exynos5422-odroidxu3-common.dtsi
index 1565667e6f69..48cecc8cf26e 100644
--- a/arch/arm/boot/dts/exynos5422-odroidxu3-common.dtsi
+++ b/arch/arm/boot/dts/exynos5422-odroidxu3-common.dtsi
@@ -159,6 +159,7 @@
 		s2mps11,buck2-ramp-enable = <1>;
 		s2mps11,buck3-ramp-enable = <1>;
 		s2mps11,buck4-ramp-enable = <1>;
+		samsung,s2mps11-acokb-ground;
 
 		interrupt-parent = <&gpx0>;
 		interrupts = <4 IRQ_TYPE_EDGE_FALLING>;
-- 
2.1.4



From k.kozlowski.k at gmail.com  Tue Aug 11 03:09:05 2015
From: k.kozlowski.k at gmail.com (Krzysztof Kozlowski)
Date: Tue, 11 Aug 2015 19:09:05 +0900
Subject: [PATCH v2 2/3] mfd: s2mps11: Add manual shutdown method for Odroid XU3
In-Reply-To: <1439287746-14034-1-git-send-email-k.kozlowski.k@gmail.com>
References: <1439287746-14034-1-git-send-email-k.kozlowski.k@gmail.com>
Message-ID: <1439287746-14034-3-git-send-email-k.kozlowski.k@gmail.com>

On Odroid XU3 board (with S2MPS11 PMIC) the PWRHOLD bit in CTRL1
register must be manually set to 0 before initiating power off sequence.

One of usual power down methods for Exynos based devices looks like:
1. PWRHOLD pin of PMIC is connected to PSHOLD of Exynos.
2. Exynos holds up this pin during system operation.
3. ACOKB pin of PMIC is pulled up to VBATT and optionally to pin in
   other device.
4. When PWRHOLD/PSHOLD goes low, the PMIC will turn off the power if
   ACOKB goes high.

On Odroid XU3 family the difference is in (3) - the ACOKB is grounded.
This means that PMIC must manually set PWRHOLD field to low and then
wait for signal from Application Processor (the usual change in
PWRHOLD/PSHOLD pin will actually cut off the power).

The patch adds respective binding allowing Odroid XU3 device to be
powered off.

Signed-off-by: Krzysztof Kozlowski <k.kozlowski.k at gmail.com>
Reported-by: Anand Moon <linux.amoon at gmail.com>
Tested-by: Anand Moon <linux.amoon at gmail.com>
Reviewed-by: Javier Martinez Canillas <javier at osg.samsung.com>
Acked-by: Lee Jones <lee.jones at linaro.org>

---

Changes since v1:
1. Split bindings documentation to separate patch (suggested by Lee).
2. Fix additional empty line (suggested by Lee).
3. Add Anand's tested-by, Javier's reviewed-by and Lee's acked-by.

Patch is losely based on patch in Hardkernel repository [0] and previous
work of Anand Moon [1].

[0] https://github.com/hardkernel/linux/commit/6897e62ba328bd1c8c095d918101863250cd73e7
[1] http://www.spinics.net/lists/linux-samsung-soc/msg45959.html
---
 drivers/mfd/sec-core.c              | 30 ++++++++++++++++++++++++++++++
 include/linux/mfd/samsung/core.h    |  2 ++
 include/linux/mfd/samsung/s2mps11.h |  1 +
 3 files changed, 33 insertions(+)

diff --git a/drivers/mfd/sec-core.c b/drivers/mfd/sec-core.c
index d206a3e8fe87..2d1137a7a0ee 100644
--- a/drivers/mfd/sec-core.c
+++ b/drivers/mfd/sec-core.c
@@ -278,6 +278,8 @@ static struct sec_platform_data *sec_pmic_i2c_parse_dt_pdata(
 	 * not parsed here.
 	 */
 
+	pd->manual_poweroff = of_property_read_bool(dev->of_node,
+						"samsung,s2mps11-acokb-ground");
 	return pd;
 }
 #else
@@ -440,6 +442,33 @@ static int sec_pmic_remove(struct i2c_client *i2c)
 	return 0;
 }
 
+static void sec_pmic_shutdown(struct i2c_client *i2c)
+{
+	struct sec_pmic_dev *sec_pmic = i2c_get_clientdata(i2c);
+	unsigned int reg, mask;
+
+	if (!sec_pmic->pdata->manual_poweroff)
+		return;
+
+	switch (sec_pmic->device_type) {
+	case S2MPS11X:
+		reg = S2MPS11_REG_CTRL1;
+		mask = S2MPS11_CTRL1_PWRHOLD_MASK;
+		break;
+	default:
+		/*
+		 * Currently only one board with S2MPS11 needs this, so just
+		 * ignore the rest.
+		 */
+		dev_warn(sec_pmic->dev,
+			"Unsupported device %lu for manual power off\n",
+			sec_pmic->device_type);
+		return;
+	}
+
+	regmap_update_bits(sec_pmic->regmap_pmic, reg, mask, 0);
+}
+
 #ifdef CONFIG_PM_SLEEP
 static int sec_pmic_suspend(struct device *dev)
 {
@@ -491,6 +520,7 @@ static struct i2c_driver sec_pmic_driver = {
 	},
 	.probe = sec_pmic_probe,
 	.remove = sec_pmic_remove,
+	.shutdown = sec_pmic_shutdown,
 	.id_table = sec_pmic_id,
 };
 
diff --git a/include/linux/mfd/samsung/core.h b/include/linux/mfd/samsung/core.h
index 75115384f3fc..aa78957e092f 100644
--- a/include/linux/mfd/samsung/core.h
+++ b/include/linux/mfd/samsung/core.h
@@ -132,6 +132,8 @@ struct sec_platform_data {
 	int				buck2_init;
 	int				buck3_init;
 	int				buck4_init;
+	/* Whether or not manually set PWRHOLD to low during shutdown. */
+	bool				manual_poweroff;
 };
 
 /**
diff --git a/include/linux/mfd/samsung/s2mps11.h b/include/linux/mfd/samsung/s2mps11.h
index 7981a9d77d3f..b288965e8101 100644
--- a/include/linux/mfd/samsung/s2mps11.h
+++ b/include/linux/mfd/samsung/s2mps11.h
@@ -179,6 +179,7 @@ enum s2mps11_regulators {
 #define S2MPS11_BUCK_N_VOLTAGES (S2MPS11_BUCK_VSEL_MASK + 1)
 #define S2MPS11_RAMP_DELAY	25000		/* uV/us */
 
+#define S2MPS11_CTRL1_PWRHOLD_MASK	BIT(4)
 
 #define S2MPS11_BUCK2_RAMP_SHIFT	6
 #define S2MPS11_BUCK34_RAMP_SHIFT	4
-- 
2.1.4



From javier at osg.samsung.com  Tue Aug 11 03:26:14 2015
From: javier at osg.samsung.com (Javier Martinez Canillas)
Date: Tue, 11 Aug 2015 12:26:14 +0200
Subject: [PATCH v3 0/4] mfd: Improve DT binding docs for max77686 and
 max77802
In-Reply-To: <1438252327-28427-1-git-send-email-javier@osg.samsung.com>
References: <1438252327-28427-1-git-send-email-javier@osg.samsung.com>
Message-ID: <55C9CDC6.9030903@osg.samsung.com>

Hello Lee and Mark,

On 07/30/2015 12:32 PM, Javier Martinez Canillas wrote:
> Hello Lee,
> 
> This series contains some improvements for the Device Tree bindings of
> the Maxim MAX77686 and MAX77802 multi-function devices.
> 
> This is the third version of the series that addresses issues pointed
> out by Sergei Shtylyov and you.
> 
> Patch #1 changes the max77686 binding to not suggest using a deprecated
> property of the regulator DT binding.
> 
> Patch #2 changes the max77686 example to use a generic node name instead
> of the chip's name.
> 
> Patch #3 adds a DT binding for the mfd portion of the max77802 that was
> missing.
> 
> Patch #4 moves the regulator portion of the max77686 to the regulator's
> DT binding sub-directory since it is a better fit for this information.
> This fourth patch needs an ack from the regulator sub-system maintainer.
>

Any comments on this series?

Best regards,
-- 
Javier Martinez Canillas
Open Source Group
Samsung Research America


From yao.yuan at freescale.com  Tue Aug 11 03:33:39 2015
From: yao.yuan at freescale.com (Yao Yuan)
Date: Tue, 11 Aug 2015 10:33:39 +0000
Subject: [PATCH v2] dmaengine: fsl-edma: add PM suspend/resume support
In-Reply-To: <1437469005-3162-1-git-send-email-yao.yuan@freescale.com>
References: <1437469005-3162-1-git-send-email-yao.yuan@freescale.com>
Message-ID: <CY1PR0301MB15622458B5D0080002FE5E36837F0@CY1PR0301MB1562.namprd03.prod.outlook.com>

Hi Vinod, 

After our discuss, I have already send the v2.
Could you please take some times help to review this patch again? 
Thanks.

Best Regards,
Yuan Yao

> -----Original Message-----
> From: linux-arm-kernel [mailto:linux-arm-kernel-bounces at lists.infradead.org]
> On Behalf Of Yuan Yao
> Sent: Tuesday, July 21, 2015 4:57 PM
> To: vinod.koul at intel.com; stefan at agner.ch; arnd at arndb.de
> Cc: dmaengine at vger.kernel.org; dan.j.williams at intel.com; linux-
> kernel at vger.kernel.org; linux-arm-kernel at lists.infradead.org
> Subject: [PATCH v2] dmaengine: fsl-edma: add PM suspend/resume support
> 
> This add power management suspend/resume support for the fsl-edma driver.
> 
> eDMA acted as a basic function used by others. What it needs to do is the two
> steps below to support power management.
> 
> In fsl_edma_suspend_late:
> Check whether the DMA chan is idle and if it is not idle, stop PM operation.
> 
> In fsl_edma_resume_early:
> Enable the eDMA and wait for being used.
> 
> Signed-off-by: Yuan Yao <yao.yuan at freescale.com>
> ---
>  drivers/dma/fsl-edma.c | 83
> ++++++++++++++++++++++++++++++++++++++++++++++++--
>  1 file changed, 80 insertions(+), 3 deletions(-)
> 
> diff --git a/drivers/dma/fsl-edma.c b/drivers/dma/fsl-edma.c index
> 915eec3..cf8b06c 100644
> --- a/drivers/dma/fsl-edma.c
> +++ b/drivers/dma/fsl-edma.c
> @@ -116,6 +116,10 @@
>  				BIT(DMA_SLAVE_BUSWIDTH_2_BYTES) | \
>  				BIT(DMA_SLAVE_BUSWIDTH_4_BYTES) | \
>  				BIT(DMA_SLAVE_BUSWIDTH_8_BYTES)
> +enum fsl_edma_pm_state {
> +	RUNNING = 0,
> +	SUSPENDED,
> +};
> 
>  struct fsl_edma_hw_tcd {
>  	__le32	saddr;
> @@ -147,6 +151,9 @@ struct fsl_edma_slave_config {  struct fsl_edma_chan {
>  	struct virt_dma_chan		vchan;
>  	enum dma_status			status;
> +	enum fsl_edma_pm_state		pm_state;
> +	bool				idle;
> +	u32				slave_id;
>  	struct fsl_edma_engine		*edma;
>  	struct fsl_edma_desc		*edesc;
>  	struct fsl_edma_slave_config	fsc;
> @@ -298,6 +305,7 @@ static int fsl_edma_terminate_all(struct dma_chan
> *chan)
>  	spin_lock_irqsave(&fsl_chan->vchan.lock, flags);
>  	fsl_edma_disable_request(fsl_chan);
>  	fsl_chan->edesc = NULL;
> +	fsl_chan->idle = true;
>  	vchan_get_all_descriptors(&fsl_chan->vchan, &head);
>  	spin_unlock_irqrestore(&fsl_chan->vchan.lock, flags);
>  	vchan_dma_desc_free_list(&fsl_chan->vchan, &head); @@ -313,6
> +321,7 @@ static int fsl_edma_pause(struct dma_chan *chan)
>  	if (fsl_chan->edesc) {
>  		fsl_edma_disable_request(fsl_chan);
>  		fsl_chan->status = DMA_PAUSED;
> +		fsl_chan->idle = true;
>  	}
>  	spin_unlock_irqrestore(&fsl_chan->vchan.lock, flags);
>  	return 0;
> @@ -327,6 +336,7 @@ static int fsl_edma_resume(struct dma_chan *chan)
>  	if (fsl_chan->edesc) {
>  		fsl_edma_enable_request(fsl_chan);
>  		fsl_chan->status = DMA_IN_PROGRESS;
> +		fsl_chan->idle = false;
>  	}
>  	spin_unlock_irqrestore(&fsl_chan->vchan.lock, flags);
>  	return 0;
> @@ -648,6 +658,7 @@ static void fsl_edma_xfer_desc(struct fsl_edma_chan
> *fsl_chan)
>  	fsl_edma_set_tcd_regs(fsl_chan, fsl_chan->edesc->tcd[0].vtcd);
>  	fsl_edma_enable_request(fsl_chan);
>  	fsl_chan->status = DMA_IN_PROGRESS;
> +	fsl_chan->idle = false;
>  }
> 
>  static irqreturn_t fsl_edma_tx_handler(int irq, void *dev_id) @@ -676,6
> +687,7 @@ static irqreturn_t fsl_edma_tx_handler(int irq, void *dev_id)
>  				vchan_cookie_complete(&fsl_chan->edesc-
> >vdesc);
>  				fsl_chan->edesc = NULL;
>  				fsl_chan->status = DMA_COMPLETE;
> +				fsl_chan->idle = true;
>  			} else {
>  				vchan_cyclic_callback(&fsl_chan->edesc-
> >vdesc);
>  			}
> @@ -704,6 +716,7 @@ static irqreturn_t fsl_edma_err_handler(int irq, void
> *dev_id)
>  			edma_writeb(fsl_edma, EDMA_CERR_CERR(ch),
>  				fsl_edma->membase + EDMA_CERR);
>  			fsl_edma->chans[ch].status = DMA_ERROR;
> +			fsl_edma->chans[ch].idle = true;
>  		}
>  	}
>  	return IRQ_HANDLED;
> @@ -724,6 +737,12 @@ static void fsl_edma_issue_pending(struct dma_chan
> *chan)
> 
>  	spin_lock_irqsave(&fsl_chan->vchan.lock, flags);
> 
> +	if (unlikely(fsl_chan->pm_state != RUNNING)) {
> +		spin_unlock_irqrestore(&fsl_chan->vchan.lock, flags);
> +		/* cannot submit due to suspend */
> +		return;
> +	}
> +
>  	if (vchan_issue_pending(&fsl_chan->vchan) && !fsl_chan->edesc)
>  		fsl_edma_xfer_desc(fsl_chan);
> 
> @@ -735,6 +754,7 @@ static struct dma_chan *fsl_edma_xlate(struct
> of_phandle_args *dma_spec,  {
>  	struct fsl_edma_engine *fsl_edma = ofdma->of_dma_data;
>  	struct dma_chan *chan, *_chan;
> +	struct fsl_edma_chan *fsl_chan;
>  	unsigned long chans_per_mux = fsl_edma->n_chans / DMAMUX_NR;
> 
>  	if (dma_spec->args_count != 2)
> @@ -748,8 +768,10 @@ static struct dma_chan *fsl_edma_xlate(struct
> of_phandle_args *dma_spec,
>  			chan = dma_get_slave_channel(chan);
>  			if (chan) {
>  				chan->device->privatecnt++;
> -				fsl_edma_chan_mux(to_fsl_edma_chan(chan),
> -					dma_spec->args[1], true);
> +				fsl_chan = to_fsl_edma_chan(chan);
> +				fsl_chan->slave_id = dma_spec->args[1];
> +				fsl_edma_chan_mux(fsl_chan, fsl_chan-
> >slave_id,
> +						true);
>  				mutex_unlock(&fsl_edma->fsl_edma_mutex);
>  				return chan;
>  			}
> @@ -888,7 +910,9 @@ static int fsl_edma_probe(struct platform_device *pdev)
>  		struct fsl_edma_chan *fsl_chan = &fsl_edma->chans[i];
> 
>  		fsl_chan->edma = fsl_edma;
> -
> +		fsl_chan->pm_state = RUNNING;
> +		fsl_chan->slave_id = 0;
> +		fsl_chan->idle = true;
>  		fsl_chan->vchan.desc_free = fsl_edma_free_desc;
>  		vchan_init(&fsl_chan->vchan, &fsl_edma->dma_dev);
> 
> @@ -959,6 +983,58 @@ static int fsl_edma_remove(struct platform_device
> *pdev)
>  	return 0;
>  }
> 
> +static int fsl_edma_suspend_late(struct device *dev) {
> +	struct fsl_edma_engine *fsl_edma = dev_get_drvdata(dev);
> +	struct fsl_edma_chan *fsl_chan;
> +	unsigned long flags;
> +	int i;
> +
> +	for (i = 0; i < fsl_edma->n_chans; i++) {
> +		fsl_chan = &fsl_edma->chans[i];
> +		spin_lock_irqsave(&fsl_chan->vchan.lock, flags);
> +		/* Make sure chan is idle or can not into suspend. */
> +		if (unlikely(!fsl_chan->idle))
> +			goto out;
> +		fsl_chan->pm_state = SUSPENDED;
> +		spin_unlock_irqrestore(&fsl_chan->vchan.lock, flags);
> +	}
> +	return 0;
> +
> +out:
> +	for (; i >= 0; i--) {
> +		fsl_chan = &fsl_edma->chans[i];
> +		fsl_chan->pm_state = RUNNING;
> +		spin_unlock_irqrestore(&fsl_chan->vchan.lock, flags);
> +	}
> +	return -EBUSY;
> +}
> +
> +static int fsl_edma_resume_early(struct device *dev) {
> +	struct fsl_edma_engine *fsl_edma = dev_get_drvdata(dev);
> +	struct fsl_edma_chan *fsl_chan;
> +	int i;
> +
> +	for (i = 0; i < fsl_edma->n_chans; i++) {
> +		fsl_chan = &fsl_edma->chans[i];
> +		fsl_chan->pm_state = RUNNING;
> +		edma_writew(fsl_edma, 0x0, fsl_edma->membase +
> EDMA_TCD_CSR(i));
> +		if (fsl_chan->slave_id != 0)
> +			fsl_edma_chan_mux(fsl_chan, fsl_chan->slave_id,
> true);
> +	}
> +
> +	edma_writel(fsl_edma, EDMA_CR_ERGA | EDMA_CR_ERCA,
> +			fsl_edma->membase + EDMA_CR);
> +
> +	return 0;
> +}
> +
> +static const struct dev_pm_ops fsl_edma_pm_ops = {
> +	.suspend_late   = fsl_edma_suspend_late,
> +	.resume_early   = fsl_edma_resume_early,
> +};
> +
>  static const struct of_device_id fsl_edma_dt_ids[] = {
>  	{ .compatible = "fsl,vf610-edma", },
>  	{ /* sentinel */ }
> @@ -969,6 +1045,7 @@ static struct platform_driver fsl_edma_driver = {
>  	.driver		= {
>  		.name	= "fsl-edma",
>  		.of_match_table = fsl_edma_dt_ids,
> +		.pm     = &fsl_edma_pm_ops,
>  	},
>  	.probe          = fsl_edma_probe,
>  	.remove		= fsl_edma_remove,
> --
> 2.1.0.27.g96db324
> 
> 
> _______________________________________________
> linux-arm-kernel mailing list
> linux-arm-kernel at lists.infradead.org
> http://lists.infradead.org/mailman/listinfo/linux-arm-kernel


From tony at atomide.com  Tue Aug 11 03:37:51 2015
From: tony at atomide.com (Tony Lindgren)
Date: Tue, 11 Aug 2015 03:37:51 -0700
Subject: [PATCH 0/3] ARM: multi_v7_defconfig: Enable more OMAP family
 platforms
In-Reply-To: <7hfv3uwvdw.fsf@deeprootsystems.com>
References: <1428614121-3374-1-git-send-email-nm@ti.com>
 <20150805102234.GZ16878@atomide.com>
 <7hfv3uwvdw.fsf@deeprootsystems.com>
Message-ID: <20150811103751.GK4215@atomide.com>

* Kevin Hilman <khilman at kernel.org> [150807 16:10]:
> Tony Lindgren <tony at atomide.com> writes:
> 
> > Ping, looks like these are still pending. Probably should be
> > applied directly by the arm-soc maintainers.
> 
> If these should go through arm-soc, please resend to:arm at kernel.org so
> they make it into our queue of stuff to be reviewed/applied.

OK thanks, up to Nihshant to resend.

Regards,

Tony


From tony at atomide.com  Tue Aug 11 03:40:43 2015
From: tony at atomide.com (Tony Lindgren)
Date: Tue, 11 Aug 2015 03:40:43 -0700
Subject: [PATCH 00/11] omap_hsmmc: voltage switching and tuning
In-Reply-To: <55C4C46E.9080200@ti.com>
References: <1438242394-25599-1-git-send-email-kishon@ti.com>
 <20150805104355.GE16878@atomide.com> <55C22524.5050304@ti.com>
 <20150806064821.GO16878@atomide.com> <55C4C46E.9080200@ti.com>
Message-ID: <20150811104043.GL4215@atomide.com>

* Kishon Vijay Abraham I <kishon at ti.com> [150807 07:48]:
> Hi,
> 
> On Thursday 06 August 2015 12:18 PM, Tony Lindgren wrote:
> > * Kishon Vijay Abraham I <kishon at ti.com> [150805 08:03]:
> >> Hi,
> >>
> >> On Wednesday 05 August 2015 04:13 PM, Tony Lindgren wrote:
> >>> * Kishon Vijay Abraham I <kishon at ti.com> [150730 00:49]:
> >>>> Patch series implements voltage switching and tuning for omap_hsmmc
> >>>> driver.
> >>>>
> >>>> Did basic read/write test in J6, J6 Eco, Beagle-x15, AM437x EVM,
> >>>> Beaglebone black, OMAP5 uEVM and OMAP4 PANDA.
> >>>
> >>> Your tests are missing omap3?
> >>
> >> I don't have one at my disposal :-( I'll try to find one and add omap3 tests.
> > 
> > Great :) Beagle xm is a good one to test the USB PHY stuff on
> > and also MMC. Having USB cable connected or EHCI loaded blocks the PM
> > though, so NFSroot is not very usable for testing on it.
> 
> I found a beagle xm. So I should be able to get back to this early next week.

OK great!

Thanks,

Tony


From leilk.liu at mediatek.com  Tue Aug 11 03:43:09 2015
From: leilk.liu at mediatek.com (Leilk Liu)
Date: Tue, 11 Aug 2015 18:43:09 +0800
Subject: [PATCH] spi: Mediatek: fix endian warnings
Message-ID: <1439289789-29026-1-git-send-email-leilk.liu@mediatek.com>

This patch fixes endian warnings detected by sparse:
- sparse: incorrect type in argument 1 (different base types)
	  expected unsigned int [unsigned] val
	  got restricted __le32 [usertype] <noident>
- sparse: incorrect type in argument 1 (different base types)
	  expected unsigned int [unsigned] val
	  got restricted __le32 [usertype] <noident>

Signed-off-by: Leilk Liu <leilk.liu at mediatek.com>
---
 drivers/spi/spi-mt65xx.c | 6 ++++--
 1 file changed, 4 insertions(+), 2 deletions(-)

diff --git a/drivers/spi/spi-mt65xx.c b/drivers/spi/spi-mt65xx.c
index 4676b01..ae645fa 100644
--- a/drivers/spi/spi-mt65xx.c
+++ b/drivers/spi/spi-mt65xx.c
@@ -359,9 +359,11 @@ static void mtk_spi_setup_dma_addr(struct spi_master *master,
 	struct mtk_spi *mdata = spi_master_get_devdata(master);
 
 	if (mdata->tx_sgl)
-		writel(cpu_to_le32(xfer->tx_dma), mdata->base + SPI_TX_SRC_REG);
+		writel((__force u32)cpu_to_le32(xfer->tx_dma),
+		       mdata->base + SPI_TX_SRC_REG);
 	if (mdata->rx_sgl)
-		writel(cpu_to_le32(xfer->rx_dma), mdata->base + SPI_RX_DST_REG);
+		writel((__force u32)cpu_to_le32(xfer->rx_dma),
+		       mdata->base + SPI_RX_DST_REG);
 }
 
 static int mtk_spi_fifo_transfer(struct spi_master *master,
-- 
1.8.1.1.dirty



From drinkcat at chromium.org  Tue Aug 11 03:52:22 2015
From: drinkcat at chromium.org (Nicolas Boichat)
Date: Tue, 11 Aug 2015 18:52:22 +0800
Subject: [v5,2/3] spi: mediatek: Add spi bus for Mediatek MT8173
In-Reply-To: <1438931991-17044-3-git-send-email-leilk.liu@mediatek.com>
References: <1438931991-17044-3-git-send-email-leilk.liu@mediatek.com>
Message-ID: <CANMq1KBNz7u0XHQBwmJjLbXyT0twxnfFJ7Hn1Cp8HmnKdOdduw@mail.gmail.com>

Hi Leilk,

On Fri, Aug 7, 2015 at 3:19 PM,  <leilk.liu at mediatek.com> wrote:
> This patch adds basic spi bus for MT8173.
>
> Signed-off-by: Leilk Liu <leilk.liu at mediatek.com>
>
> ---
> Change in this patch:
> 1. change "pad-select" to "mediatek,pad-select".
> 2. modify clk relevant implement.
> ---
>  drivers/spi/Kconfig                      |   9 +
>  drivers/spi/Makefile                     |   1 +
>  drivers/spi/spi-mt65xx.c                 | 749 +++++++++++++++++++++++++++++++
>  include/linux/platform_data/spi-mt65xx.h |  22 +
>  4 files changed, 781 insertions(+)
>  create mode 100644 drivers/spi/spi-mt65xx.c
>  create mode 100644 include/linux/platform_data/spi-mt65xx.h
>
> diff --git a/drivers/spi/Kconfig b/drivers/spi/Kconfig
> index 0cae169..38ddfba 100644
> --- a/drivers/spi/Kconfig
> +++ b/drivers/spi/Kconfig
> @@ -326,6 +326,15 @@ config SPI_MESON_SPIFC
>           This enables master mode support for the SPIFC (SPI flash
>           controller) available in Amlogic Meson SoCs.
>
> +config SPI_MT65XX
> +       tristate "MediaTek SPI controller"
> +       depends on ARCH_MEDIATEK || COMPILE_TEST
> +       help
> +         This selects the MediaTek(R) SPI bus driver.
> +         If you want to use MediaTek(R) SPI interface,
> +         say Y or M here.If you are not sure, say N.
> +         SPI drivers for Mediatek MT65XX and MT81XX series ARM SoCs.
> +
>  config SPI_OC_TINY
>         tristate "OpenCores tiny SPI"
>         depends on GPIOLIB || COMPILE_TEST
> diff --git a/drivers/spi/Makefile b/drivers/spi/Makefile
> index 1154dba..9746beb2 100644
> --- a/drivers/spi/Makefile
> +++ b/drivers/spi/Makefile
> @@ -48,6 +48,7 @@ obj-$(CONFIG_SPI_MESON_SPIFC)         += spi-meson-spifc.o
>  obj-$(CONFIG_SPI_MPC512x_PSC)          += spi-mpc512x-psc.o
>  obj-$(CONFIG_SPI_MPC52xx_PSC)          += spi-mpc52xx-psc.o
>  obj-$(CONFIG_SPI_MPC52xx)              += spi-mpc52xx.o
> +obj-$(CONFIG_SPI_MT65XX)                += spi-mt65xx.o
>  obj-$(CONFIG_SPI_MXS)                  += spi-mxs.o
>  obj-$(CONFIG_SPI_NUC900)               += spi-nuc900.o
>  obj-$(CONFIG_SPI_OC_TINY)              += spi-oc-tiny.o
> diff --git a/drivers/spi/spi-mt65xx.c b/drivers/spi/spi-mt65xx.c
> new file mode 100644
> index 0000000..4676b01
> --- /dev/null
> +++ b/drivers/spi/spi-mt65xx.c
> @@ -0,0 +1,749 @@
> +/*
> + * Copyright (c) 2015 MediaTek Inc.
> + * Author: Leilk Liu <leilk.liu at 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/clk.h>
> +#include <linux/device.h>
> +#include <linux/err.h>
> +#include <linux/interrupt.h>

Since you are using readl/writel, please import linux/io.h as well (it
is implicitly imported by spi/spi.h, but better be safe...)

> +#include <linux/ioport.h>
> +#include <linux/module.h>
> +#include <linux/of.h>
> +#include <linux/platform_device.h>
> +#include <linux/platform_data/spi-mt65xx.h>
> +#include <linux/pm_runtime.h>
> +#include <linux/spi/spi.h>
> +
> +#define SPI_CFG0_REG                      0x0000
> +#define SPI_CFG1_REG                      0x0004
> +#define SPI_TX_SRC_REG                    0x0008
> +#define SPI_RX_DST_REG                    0x000c
> +#define SPI_TX_DATA_REG                   0x0010
> +#define SPI_RX_DATA_REG                   0x0014
> +#define SPI_CMD_REG                       0x0018
> +#define SPI_STATUS0_REG                   0x001c
> +#define SPI_PAD_SEL_REG                   0x0024
> +
> +#define SPI_CFG0_SCK_HIGH_OFFSET          0
> +#define SPI_CFG0_SCK_LOW_OFFSET           8
> +#define SPI_CFG0_CS_HOLD_OFFSET           16
> +#define SPI_CFG0_CS_SETUP_OFFSET          24
> +
> +#define SPI_CFG1_CS_IDLE_OFFSET           0
> +#define SPI_CFG1_PACKET_LOOP_OFFSET       8
> +#define SPI_CFG1_PACKET_LENGTH_OFFSET     16
> +#define SPI_CFG1_GET_TICK_DLY_OFFSET      30
> +
> +#define SPI_CFG1_CS_IDLE_MASK             0xff
> +#define SPI_CFG1_PACKET_LOOP_MASK         0xff00
> +#define SPI_CFG1_PACKET_LENGTH_MASK       0x3ff0000
> +
> +#define SPI_CMD_ACT_OFFSET                0
> +#define SPI_CMD_RESUME_OFFSET             1
> +#define SPI_CMD_CPHA_OFFSET               8
> +#define SPI_CMD_CPOL_OFFSET               9
> +#define SPI_CMD_TXMSBF_OFFSET             12
> +#define SPI_CMD_RXMSBF_OFFSET             13
> +#define SPI_CMD_RX_ENDIAN_OFFSET          14
> +#define SPI_CMD_TX_ENDIAN_OFFSET          15

It feels error-prone that you are defining these offsets here, then
redefining the bits just below.

Looking at the code, I think it's better if you remove these
SPI_CMD_*_OFFSET defines, and only use the BIT(x) defines below.

> +#define SPI_CMD_RST                  BIT(2)
> +#define SPI_CMD_PAUSE_EN             BIT(4)
> +#define SPI_CMD_DEASSERT             BIT(5)
> +#define SPI_CMD_CPHA                 BIT(8)
> +#define SPI_CMD_CPOL                 BIT(9)
> +#define SPI_CMD_RX_DMA               BIT(10)
> +#define SPI_CMD_TX_DMA               BIT(11)
> +#define SPI_CMD_TXMSBF               BIT(12)
> +#define SPI_CMD_RXMSBF               BIT(13)
> +#define SPI_CMD_RX_ENDIAN            BIT(14)
> +#define SPI_CMD_TX_ENDIAN            BIT(15)
> +#define SPI_CMD_FINISH_IE            BIT(16)
> +#define SPI_CMD_PAUSE_IE             BIT(17)
> +
> +#define MTK_SPI_QUIRK_PAD_SELECT 1
> +/* Must explicitly send dummy Tx bytes to do Rx only transfer */
> +#define MTK_SPI_QUIRK_MUST_TX 1
> +
> +#define MT8173_SPI_MAX_PAD_SEL 3
> +
> +#define MTK_SPI_IDLE 0
> +#define MTK_SPI_PAUSED 1
> +
> +#define MTK_SPI_MAX_FIFO_SIZE 32
> +#define MTK_SPI_PACKET_SIZE 1024
> +
> +struct mtk_spi_compatible {
> +       u32 need_pad_sel;
> +       u32 must_tx;

Since the quirks are true/false, define these as bool, and remove
MTK_SPI_QUIRK_PAD_SELECT/MTK_SPI_QUIRK_MUST_TX. Move the comment here
too.

> +};
> +
> +struct mtk_spi {
> +       void __iomem *base;
> +       u32 state;
> +       u32 pad_sel;
> +       struct clk *spi_clk, *parent_clk;
> +       struct spi_transfer *cur_transfer;
> +       u32 xfer_len;
> +       struct scatterlist *tx_sgl, *rx_sgl;
> +       u32 tx_sgl_len, rx_sgl_len;
> +       const struct mtk_spi_compatible *dev_comp;
> +};
> +
> +static const struct mtk_spi_compatible mt6589_compat = {
> +       .need_pad_sel = 0,
> +       .must_tx = 0,
> +};
> +
> +static const struct mtk_spi_compatible mt8135_compat = {
> +       .need_pad_sel = 0,
> +       .must_tx = 0,
> +};

You don't need to set these explicitly to 0/false.

> +
> +static const struct mtk_spi_compatible mt8173_compat = {
> +       .need_pad_sel = MTK_SPI_QUIRK_PAD_SELECT,
> +       .must_tx = MTK_SPI_QUIRK_MUST_TX,

Then you can set those as "true".

> +};
> +
> +/*
> + * A piece of default chip info unless the platform
> + * supplies it.
> + */
> +static const struct mtk_chip_config mtk_default_chip_info = {
> +       .rx_mlsb = 1,
> +       .tx_mlsb = 1,
> +       .tx_endian = 0,
> +       .rx_endian = 0,
> +};
> +
> +static const struct of_device_id mtk_spi_of_match[] = {
> +       { .compatible = "mediatek,mt6589-spi", .data = (void *)&mt6589_compat },
> +       { .compatible = "mediatek,mt8135-spi", .data = (void *)&mt8135_compat },
> +       { .compatible = "mediatek,mt8173-spi", .data = (void *)&mt8173_compat },
> +       {}
> +};
> +MODULE_DEVICE_TABLE(of, mtk_spi_of_match);
> +
> +static void mtk_spi_reset(struct mtk_spi *mdata)
> +{
> +       u32 reg_val;
> +
> +       /* set the software reset bit in SPI_CMD_REG. */
> +       reg_val = readl(mdata->base + SPI_CMD_REG);
> +       reg_val |= SPI_CMD_RST;
> +       writel(reg_val, mdata->base + SPI_CMD_REG);
> +
> +       reg_val = readl(mdata->base + SPI_CMD_REG);
> +       reg_val &= ~SPI_CMD_RST;
> +       writel(reg_val, mdata->base + SPI_CMD_REG);
> +}
> +
> +static void mtk_spi_config(struct mtk_spi *mdata,
> +                          struct mtk_chip_config *chip_config)
> +{
> +       u32 reg_val;
> +
> +       reg_val = readl(mdata->base + SPI_CMD_REG);
> +
> +       /* set the mlsbx and mlsbtx */
> +       reg_val &= ~(SPI_CMD_TXMSBF | SPI_CMD_RXMSBF);
> +       reg_val |= (chip_config->tx_mlsb << SPI_CMD_TXMSBF_OFFSET);
> +       reg_val |= (chip_config->rx_mlsb << SPI_CMD_RXMSBF_OFFSET);
> +
> +       /* set the tx/rx endian */
> +       reg_val &= ~(SPI_CMD_TX_ENDIAN | SPI_CMD_RX_ENDIAN);
> +       reg_val |= (chip_config->tx_endian << SPI_CMD_TX_ENDIAN_OFFSET);
> +       reg_val |= (chip_config->rx_endian << SPI_CMD_RX_ENDIAN_OFFSET);
> +
> +       /* set finish and pause interrupt always enable */
> +       reg_val |= SPI_CMD_FINISH_IE | SPI_CMD_PAUSE_EN;
> +
> +       /* disable dma mode */
> +       reg_val &= ~(SPI_CMD_TX_DMA | SPI_CMD_RX_DMA);
> +
> +       /* disable deassert mode */
> +       reg_val &= ~SPI_CMD_DEASSERT;
> +
> +       writel(reg_val, mdata->base + SPI_CMD_REG);
> +
> +       /* pad select */
> +       if (mdata->dev_comp->need_pad_sel)
> +               writel(mdata->pad_sel, mdata->base + SPI_PAD_SEL_REG);
> +}
> +
> +static int mtk_spi_prepare_hardware(struct spi_master *master)
> +{
> +       struct spi_transfer *trans;
> +       struct mtk_spi *mdata = spi_master_get_devdata(master);
> +       struct spi_message *msg = master->cur_msg;
> +       int ret;
> +
> +       ret = clk_prepare_enable(mdata->spi_clk);
> +       if (ret < 0) {
> +               dev_err(&master->dev, "failed to enable clock (%d)\n", ret);
> +               return ret;
> +       }
> +
> +       trans = list_first_entry(&msg->transfers, struct spi_transfer,
> +                                transfer_list);
> +       if (trans->cs_change == 0) {

!trans->cs_change

> +               mdata->state = MTK_SPI_IDLE;
> +               mtk_spi_reset(mdata);
> +       }
> +
> +       return ret;
> +}
> +
> +static int mtk_spi_unprepare_hardware(struct spi_master *master)
> +{
> +       struct mtk_spi *mdata = spi_master_get_devdata(master);
> +
> +       clk_disable_unprepare(mdata->spi_clk);
> +
> +       return 0;
> +}

In this case, prepare_hardware/unprepare_hardware is redundant with
pm_runtime (apart from the cs_change check, possibly).

If PM_RUNTIME is disabled, leave the clock enabled all the time, if
not enable/disable in pm_runtime functions (as you already do)

See https://git.kernel.org/cgit/linux/kernel/git/broonie/spi.git/commit/?id=db91841b58f9ad0ecbb81ed0fa496c3a1b67fd63
"spi/omap100k: Convert to runtime PM" for an example (it's one of the
last driver that used prepare/unprepare calls, and got converted to
pm_runtime)

> +static int mtk_spi_prepare_message(struct spi_master *master,
> +                                  struct spi_message *msg)
> +{
> +       u32 reg_val;
> +       u8 cpha, cpol;
> +       struct mtk_chip_config *chip_config;
> +       struct spi_device *spi = msg->spi;
> +       struct mtk_spi *mdata = spi_master_get_devdata(master);
> +
> +       cpha = spi->mode & SPI_CPHA ? 1 : 0;
> +       cpol = spi->mode & SPI_CPOL ? 1 : 0;
> +
> +       reg_val = readl(mdata->base + SPI_CMD_REG);
> +       reg_val &= ~(SPI_CMD_CPHA | SPI_CMD_CPOL);
> +       reg_val |= (cpha << SPI_CMD_CPHA_OFFSET);
> +       reg_val |= (cpol << SPI_CMD_CPOL_OFFSET);

This can actually be simplified a bit by using
SPI_CMD_CPHA/SPI_CMD_CPOL instead.

> +       writel(reg_val, mdata->base + SPI_CMD_REG);
> +
> +       chip_config = spi->controller_data;
> +       if (!chip_config) {
> +               chip_config = (void *)&mtk_default_chip_info;
> +               spi->controller_data = chip_config;
> +       }
> +       mtk_spi_config(mdata, chip_config);
> +
> +       return 0;
> +}
> +
> +static void mtk_spi_set_cs(struct spi_device *spi, bool enable)
> +{
> +       u32 reg_val;
> +       struct mtk_spi *mdata = spi_master_get_devdata(spi->master);
> +
> +       reg_val = readl(mdata->base + SPI_CMD_REG);
> +       if (!enable)
> +               reg_val |= SPI_CMD_PAUSE_EN;
> +       else
> +               reg_val &= ~SPI_CMD_PAUSE_EN;
> +       writel(reg_val, mdata->base + SPI_CMD_REG);
> +}
> +
> +static void mtk_spi_prepare_transfer(struct spi_master *master,
> +                                    struct spi_transfer *xfer)
> +{
> +       u32 spi_clk_hz, div, high_time, low_time, holdtime,
> +           setuptime, cs_idletime, reg_val = 0;
> +       struct mtk_spi *mdata = spi_master_get_devdata(master);
> +
> +       spi_clk_hz = clk_get_rate(mdata->spi_clk);
> +       if (xfer->speed_hz < spi_clk_hz / 2)
> +               div = DIV_ROUND_UP(spi_clk_hz, xfer->speed_hz);
> +       else
> +               div = 1;
> +
> +       high_time = (div + 1) / 2;
> +       low_time = (div + 1) / 2;
> +       holdtime = (div + 1) / 2 * 2;
> +       setuptime = (div + 1) / 2 * 2;
> +       cs_idletime = (div + 1) / 2 * 2;

Why setting variables with the exact same value? Can you do with just 2?

> +       reg_val |= (((high_time - 1) & 0xff) << SPI_CFG0_SCK_HIGH_OFFSET);
> +       reg_val |= (((low_time - 1) & 0xff) << SPI_CFG0_SCK_LOW_OFFSET);
> +       reg_val |= (((holdtime - 1) & 0xff) << SPI_CFG0_CS_HOLD_OFFSET);
> +       reg_val |= (((setuptime - 1) & 0xff) << SPI_CFG0_CS_SETUP_OFFSET);

Not sure of the details, but can you guarantee this will never
overflow? I.e. can div be larger than 256?

> +       writel(reg_val, mdata->base + SPI_CFG0_REG);
> +
> +       reg_val = readl(mdata->base + SPI_CFG1_REG);
> +       reg_val &= ~SPI_CFG1_CS_IDLE_MASK;
> +       reg_val |= (((cs_idletime - 1) & 0xff) << SPI_CFG1_CS_IDLE_OFFSET);
> +       writel(reg_val, mdata->base + SPI_CFG1_REG);
> +}
> +
> +static void mtk_spi_setup_packet(struct spi_master *master)
> +{
> +       u32 packet_size, packet_loop, reg_val;
> +       struct mtk_spi *mdata = spi_master_get_devdata(master);
> +
> +       packet_size = min_t(unsigned, mdata->xfer_len, MTK_SPI_PACKET_SIZE);

u32 instead of unsigned.

> +       packet_loop = mdata->xfer_len / packet_size;
> +
> +       reg_val = readl(mdata->base + SPI_CFG1_REG);
> +       reg_val &= ~(SPI_CFG1_PACKET_LENGTH_MASK + SPI_CFG1_PACKET_LOOP_MASK);

Use |, not +.

> +       reg_val |= (packet_size - 1) << SPI_CFG1_PACKET_LENGTH_OFFSET;
> +       reg_val |= (packet_loop - 1) << SPI_CFG1_PACKET_LOOP_OFFSET;

Can packet_loop be >256?

> +       writel(reg_val, mdata->base + SPI_CFG1_REG);
> +}
> +
> +static void mtk_spi_enable_transfer(struct spi_master *master)
> +{
> +       int cmd;

u32

> +       struct mtk_spi *mdata = spi_master_get_devdata(master);
> +
> +       cmd = readl(mdata->base + SPI_CMD_REG);
> +       if (mdata->state == MTK_SPI_IDLE)
> +               cmd |= 1 << SPI_CMD_ACT_OFFSET;
> +       else
> +               cmd |= 1 << SPI_CMD_RESUME_OFFSET;
> +       writel(cmd, mdata->base + SPI_CMD_REG);
> +}
> +
> +static int mtk_spi_get_mult_delta(int xfer_len)

xfer_len is a u32, so should be mult_delta.

> +{
> +       int mult_delta;
> +
> +       if (xfer_len > MTK_SPI_PACKET_SIZE)
> +               mult_delta = xfer_len % MTK_SPI_PACKET_SIZE;
> +       else
> +               mult_delta = 0;
> +
> +       return mult_delta;
> +}
> +
> +static void mtk_spi_update_mdata_len(struct spi_master *master)
> +{
> +       int mult_delta;
> +       struct mtk_spi *mdata = spi_master_get_devdata(master);
> +
> +       if (mdata->tx_sgl_len && mdata->rx_sgl_len) {
> +               if (mdata->tx_sgl_len > mdata->rx_sgl_len) {
> +                       mult_delta = mtk_spi_get_mult_delta(mdata->rx_sgl_len);
> +                       mdata->xfer_len = mdata->rx_sgl_len - mult_delta;
> +                       mdata->rx_sgl_len = mult_delta;
> +                       mdata->tx_sgl_len -= mdata->xfer_len;
> +               } else {
> +                       mult_delta = mtk_spi_get_mult_delta(mdata->tx_sgl_len);
> +                       mdata->xfer_len = mdata->tx_sgl_len - mult_delta;
> +                       mdata->tx_sgl_len = mult_delta;
> +                       mdata->rx_sgl_len -= mdata->xfer_len;
> +               }
> +       } else if (mdata->tx_sgl_len) {
> +               mult_delta = mtk_spi_get_mult_delta(mdata->tx_sgl_len);
> +               mdata->xfer_len = mdata->tx_sgl_len - mult_delta;
> +               mdata->tx_sgl_len = mult_delta;
> +       } else if (mdata->rx_sgl_len) {
> +               mult_delta = mtk_spi_get_mult_delta(mdata->rx_sgl_len);
> +               mdata->xfer_len = mdata->rx_sgl_len - mult_delta;
> +               mdata->rx_sgl_len = mult_delta;
> +       }
> +}
> +
> +static void mtk_spi_setup_dma_addr(struct spi_master *master,
> +                                  struct spi_transfer *xfer)
> +{
> +       struct mtk_spi *mdata = spi_master_get_devdata(master);
> +
> +       if (mdata->tx_sgl)
> +               writel(cpu_to_le32(xfer->tx_dma), mdata->base + SPI_TX_SRC_REG);
> +       if (mdata->rx_sgl)
> +               writel(cpu_to_le32(xfer->rx_dma), mdata->base + SPI_RX_DST_REG);
> +}
> +
> +static int mtk_spi_fifo_transfer(struct spi_master *master,
> +                                struct spi_device *spi,
> +                                struct spi_transfer *xfer)
> +{
> +       int cnt, i;
> +       struct mtk_spi *mdata = spi_master_get_devdata(master);
> +
> +       mdata->cur_transfer = xfer;
> +       mdata->xfer_len = xfer->len;
> +       mtk_spi_prepare_transfer(master, xfer);
> +       mtk_spi_setup_packet(master);
> +
> +       if (xfer->len % 4)
> +               cnt = xfer->len / 4 + 1;
> +       else
> +               cnt = xfer->len / 4;
> +
> +       for (i = 0; i < cnt; i++)
> +               writel(*((u32 *)xfer->tx_buf + i),

This will access past the end of tx_buf if len%4 > 0.

> +                      mdata->base + SPI_TX_DATA_REG);
> +
> +       mtk_spi_enable_transfer(master);
> +
> +       return 1;
> +}
> +
> +static int mtk_spi_dma_transfer(struct spi_master *master,
> +                               struct spi_device *spi,
> +                               struct spi_transfer *xfer)
> +{
> +       int cmd;
> +       struct mtk_spi *mdata = spi_master_get_devdata(master);
> +
> +       mdata->tx_sgl = NULL;
> +       mdata->rx_sgl = NULL;
> +       mdata->tx_sgl_len = 0;
> +       mdata->rx_sgl_len = 0;
> +       mdata->cur_transfer = xfer;
> +
> +       mtk_spi_prepare_transfer(master, xfer);
> +
> +       cmd = readl(mdata->base + SPI_CMD_REG);
> +       if (xfer->tx_buf)
> +               cmd |= SPI_CMD_TX_DMA;
> +       if (xfer->rx_buf)
> +               cmd |= SPI_CMD_RX_DMA;
> +       writel(cmd, mdata->base + SPI_CMD_REG);
> +
> +       if (xfer->tx_buf)
> +               mdata->tx_sgl = xfer->tx_sg.sgl;
> +       if (xfer->rx_buf)
> +               mdata->rx_sgl = xfer->rx_sg.sgl;
> +
> +       if (mdata->tx_sgl) {
> +               xfer->tx_dma = sg_dma_address(mdata->tx_sgl);
> +               mdata->tx_sgl_len = sg_dma_len(mdata->tx_sgl);
> +       }
> +       if (mdata->rx_sgl) {
> +               xfer->rx_dma = sg_dma_address(mdata->rx_sgl);
> +               mdata->rx_sgl_len = sg_dma_len(mdata->rx_sgl);
> +       }
> +
> +       mtk_spi_update_mdata_len(master);
> +       mtk_spi_setup_packet(master);
> +       mtk_spi_setup_dma_addr(master, xfer);
> +       mtk_spi_enable_transfer(master);
> +
> +       return 1;
> +}
> +
> +static int mtk_spi_transfer_one(struct spi_master *master,
> +                               struct spi_device *spi,
> +                               struct spi_transfer *xfer)
> +{
> +       if (master->can_dma(master, spi, xfer))
> +               return mtk_spi_dma_transfer(master, spi, xfer);
> +       else
> +               return mtk_spi_fifo_transfer(master, spi, xfer);
> +}
> +
> +static bool mtk_spi_can_dma(struct spi_master *master,
> +                           struct spi_device *spi,
> +                           struct spi_transfer *xfer)
> +{
> +       return xfer->len > MTK_SPI_MAX_FIFO_SIZE;
> +}
> +
> +static irqreturn_t mtk_spi_interrupt(int irq, void *dev_id)
> +{
> +       u32 cmd, reg_val, i;
> +       struct spi_master *master = dev_id;
> +       struct mtk_spi *mdata = spi_master_get_devdata(master);
> +       struct spi_transfer *trans = mdata->cur_transfer;
> +
> +       reg_val = readl(mdata->base + SPI_STATUS0_REG);
> +       if (reg_val & 0x2)

define 0x2?

> +               mdata->state = MTK_SPI_PAUSED;
> +       else
> +               mdata->state = MTK_SPI_IDLE;
> +
> +       if (!master->can_dma(master, master->cur_msg->spi, trans)) {
> +               /* xfer len is not N*4 bytes every time in a transfer,
> +                * but SPI_RX_DATA_REG must reads 4 bytes once,
> +                * so rx buffer byte by byte.
> +                */
> +               if (trans->rx_buf) {
> +                       for (i = 0; i < mdata->xfer_len; i++) {
> +                               if (i % 4 == 0)
> +                                       reg_val =
> +                                       readl(mdata->base + SPI_RX_DATA_REG);

Strange indentation. Might be better to put readl on the same line,
and SPI_RX_DATA_REG on the next one.

> +                               *((u8 *)(trans->rx_buf + i)) =
> +                                       (reg_val >> ((i % 4) * 8)) & 0xff;

This feels a bit awkward... Also, & 0xff is not needed.

> +                       }
> +               }
> +               spi_finalize_current_transfer(master);
> +               return IRQ_HANDLED;
> +       }
> +
> +       if (mdata->tx_sgl)
> +               trans->tx_dma += mdata->xfer_len;
> +       if (mdata->rx_sgl)
> +               trans->rx_dma += mdata->xfer_len;
> +
> +       if (mdata->tx_sgl && (mdata->tx_sgl_len == 0)) {
> +               mdata->tx_sgl = sg_next(mdata->tx_sgl);
> +               if (mdata->tx_sgl) {
> +                       trans->tx_dma = sg_dma_address(mdata->tx_sgl);
> +                       mdata->tx_sgl_len = sg_dma_len(mdata->tx_sgl);
> +               }
> +       }
> +       if (mdata->rx_sgl && (mdata->rx_sgl_len == 0)) {
> +               mdata->rx_sgl = sg_next(mdata->rx_sgl);
> +               if (mdata->rx_sgl) {
> +                       trans->rx_dma = sg_dma_address(mdata->rx_sgl);
> +                       mdata->rx_sgl_len = sg_dma_len(mdata->rx_sgl);
> +               }
> +       }
> +
> +       if (!mdata->tx_sgl && !mdata->rx_sgl) {
> +               /* spi disable dma */
> +               cmd = readl(mdata->base + SPI_CMD_REG);
> +               cmd &= ~SPI_CMD_TX_DMA;
> +               cmd &= ~SPI_CMD_RX_DMA;
> +               writel(cmd, mdata->base + SPI_CMD_REG);
> +
> +               spi_finalize_current_transfer(master);
> +               return IRQ_HANDLED;
> +       }
> +
> +       mtk_spi_update_mdata_len(master);
> +       mtk_spi_setup_packet(master);
> +       mtk_spi_setup_dma_addr(master, trans);
> +       mtk_spi_enable_transfer(master);
> +
> +       return IRQ_HANDLED;
> +}
> +
> +static int mtk_spi_probe(struct platform_device *pdev)
> +{
> +       struct spi_master *master;
> +       struct mtk_spi *mdata;
> +       const struct of_device_id *of_id;
> +       struct resource *res;
> +       int     irq, ret;

Space, not tab, between int and irq.

> +
> +       master = spi_alloc_master(&pdev->dev, sizeof(*mdata));
> +       if (!master) {
> +               dev_err(&pdev->dev, "failed to alloc spi master\n");
> +               return -ENOMEM;
> +       }
> +
> +       master->auto_runtime_pm = true;
> +       master->dev.of_node = pdev->dev.of_node;
> +       master->mode_bits = SPI_CPOL | SPI_CPHA;
> +
> +       master->set_cs = mtk_spi_set_cs;
> +       master->prepare_transfer_hardware = mtk_spi_prepare_hardware;
> +       master->unprepare_transfer_hardware = mtk_spi_unprepare_hardware;
> +       master->prepare_message = mtk_spi_prepare_message;
> +       master->transfer_one = mtk_spi_transfer_one;
> +       master->can_dma = mtk_spi_can_dma;
> +
> +       of_id = of_match_node(mtk_spi_of_match, pdev->dev.of_node);
> +       if (!of_id) {
> +               dev_err(&pdev->dev, "failed to probe of_node\n");
> +               ret = -EINVAL;
> +               goto err_put_master;
> +       }
> +
> +       mdata = spi_master_get_devdata(master);
> +       mdata->dev_comp = of_id->data;
> +       if (mdata->dev_comp->must_tx)
> +               master->flags = SPI_MASTER_MUST_TX;
> +
> +       if (mdata->dev_comp->need_pad_sel) {
> +               ret = of_property_read_u32(pdev->dev.of_node,
> +                                          "mediatek,pad-select",
> +                                          &mdata->pad_sel);
> +               if (ret) {
> +                       dev_err(&pdev->dev, "failed to read pad select: %d\n",
> +                               ret);
> +                       goto err_put_master;
> +               }
> +
> +               if (mdata->pad_sel > MT8173_SPI_MAX_PAD_SEL) {
> +                       dev_err(&pdev->dev, "wrong pad-select: %u\n",
> +                               mdata->pad_sel);
> +                       ret = -EINVAL;
> +                       goto err_put_master;
> +               }
> +       }
> +
> +       platform_set_drvdata(pdev, master);
> +
> +       res = platform_get_resource(pdev, IORESOURCE_MEM, 0);
> +       if (!res) {
> +               ret = -ENODEV;
> +               dev_err(&pdev->dev, "failed to determine base address\n");
> +               goto err_put_master;
> +       }
> +
> +       mdata->base = devm_ioremap_resource(&pdev->dev, res);
> +       if (IS_ERR(mdata->base)) {
> +               ret = PTR_ERR(mdata->base);
> +               goto err_put_master;
> +       }
> +
> +       irq = platform_get_irq(pdev, 0);
> +       if (irq < 0) {
> +               dev_err(&pdev->dev, "failed to get irq (%d)\n", irq);
> +               ret = irq;
> +               goto err_put_master;
> +       }
> +
> +       if (!pdev->dev.dma_mask)
> +               pdev->dev.dma_mask = &pdev->dev.coherent_dma_mask;
> +
> +       ret = devm_request_irq(&pdev->dev, irq, mtk_spi_interrupt,
> +                              IRQF_TRIGGER_NONE, dev_name(&pdev->dev), master);
> +       if (ret) {
> +               dev_err(&pdev->dev, "failed to register irq (%d)\n", ret);
> +               goto err_put_master;
> +       }
> +
> +       mdata->spi_clk = devm_clk_get(&pdev->dev, "spi-clk");
> +       if (IS_ERR(mdata->spi_clk)) {
> +               ret = PTR_ERR(mdata->spi_clk);
> +               dev_err(&pdev->dev, "failed to get spi-clk: %d\n", ret);
> +               goto err_put_master;
> +       }
> +
> +       mdata->parent_clk = devm_clk_get(&pdev->dev, "parent-clk");
> +       if (IS_ERR(mdata->parent_clk)) {
> +               ret = PTR_ERR(mdata->parent_clk);
> +               dev_err(&pdev->dev, "failed to get parent-clk: %d\n", ret);
> +               goto err_put_master;
> +       }
> +
> +       ret = clk_prepare_enable(mdata->spi_clk);
> +       if (ret < 0) {
> +               dev_err(&pdev->dev, "failed to enable spi_clk (%d)\n", ret);
> +               goto err_put_master;
> +       }
> +
> +       ret = clk_set_parent(mdata->spi_clk, mdata->parent_clk);
> +       if (ret < 0) {
> +               dev_err(&pdev->dev, "failed to clk_set_parent (%d)\n", ret);
> +               goto err_disable_clk;
> +       }
> +
> +       clk_disable_unprepare(mdata->spi_clk);
> +
> +       pm_runtime_enable(&pdev->dev);
> +
> +       ret = devm_spi_register_master(&pdev->dev, master);
> +       if (ret) {
> +               dev_err(&pdev->dev, "failed to register master (%d)\n", ret);
> +               goto err_put_master;
> +       }
> +
> +       return 0;
> +
> +err_disable_clk:
> +       clk_disable_unprepare(mdata->spi_clk);
> +err_put_master:
> +       spi_master_put(master);
> +
> +       return ret;
> +}
> +
> +static int mtk_spi_remove(struct platform_device *pdev)
> +{
> +       struct spi_master *master = platform_get_drvdata(pdev);
> +       struct mtk_spi *mdata = spi_master_get_devdata(master);
> +
> +       pm_runtime_disable(&pdev->dev);
> +
> +       mtk_spi_reset(mdata);
> +       clk_disable_unprepare(mdata->spi_clk);
> +       spi_master_put(master);
> +
> +       return 0;
> +}
> +
> +#ifdef CONFIG_PM_SLEEP
> +static int mtk_spi_suspend(struct device *dev)
> +{
> +       int ret;
> +       struct spi_master *master = dev_get_drvdata(dev);
> +       struct mtk_spi *mdata = spi_master_get_devdata(master);
> +
> +       ret = spi_master_suspend(master);
> +       if (ret)
> +               return ret;
> +
> +       if (!pm_runtime_suspended(dev))
> +               clk_disable_unprepare(mdata->spi_clk);
> +
> +       return ret;
> +}
> +
> +static int mtk_spi_resume(struct device *dev)
> +{
> +       int ret;
> +       struct spi_master *master = dev_get_drvdata(dev);
> +       struct mtk_spi *mdata = spi_master_get_devdata(master);
> +
> +       if (!pm_runtime_suspended(dev)) {
> +               ret = clk_prepare_enable(mdata->spi_clk);
> +               if (ret < 0)
> +                       return ret;
> +       }
> +
> +       ret = spi_master_resume(master);
> +       if (ret < 0)
> +               clk_disable_unprepare(mdata->spi_clk);
> +
> +       return ret;
> +}
> +#endif /* CONFIG_PM_SLEEP */
> +
> +#ifdef CONFIG_PM
> +static int mtk_spi_runtime_suspend(struct device *dev)
> +{
> +       struct spi_master *master = dev_get_drvdata(dev);
> +       struct mtk_spi *mdata = spi_master_get_devdata(master);
> +
> +       clk_disable_unprepare(mdata->spi_clk);
> +
> +       return 0;
> +}
> +
> +static int mtk_spi_runtime_resume(struct device *dev)
> +{
> +       struct spi_master *master = dev_get_drvdata(dev);
> +       struct mtk_spi *mdata = spi_master_get_devdata(master);
> +
> +       return clk_prepare_enable(mdata->spi_clk);
> +}
> +#endif /* CONFIG_PM */
> +
> +static const struct dev_pm_ops mtk_spi_pm = {
> +       SET_SYSTEM_SLEEP_PM_OPS(mtk_spi_suspend, mtk_spi_resume)
> +       SET_RUNTIME_PM_OPS(mtk_spi_runtime_suspend,
> +                          mtk_spi_runtime_resume, NULL)
> +};
> +
> +struct platform_driver mtk_spi_driver = {
> +       .driver = {
> +               .name = "mtk-spi",
> +               .pm     = &mtk_spi_pm,
> +               .of_match_table = mtk_spi_of_match,
> +       },
> +       .probe = mtk_spi_probe,
> +       .remove = mtk_spi_remove,
> +};
> +
> +module_platform_driver(mtk_spi_driver);
> +
> +MODULE_DESCRIPTION("MTK SPI Controller driver");
> +MODULE_AUTHOR("Leilk Liu <leilk.liu at mediatek.com>");
> +MODULE_LICENSE("GPL v2");
> +MODULE_ALIAS("platform: mtk_spi");
> diff --git a/include/linux/platform_data/spi-mt65xx.h b/include/linux/platform_data/spi-mt65xx.h
> new file mode 100644
> index 0000000..7512255
> --- /dev/null
> +++ b/include/linux/platform_data/spi-mt65xx.h
> @@ -0,0 +1,22 @@
> +/*
> + *  MTK SPI bus driver definitions
> + *
> + * Copyright (c) 2015 MediaTek Inc.
> + * Author: Leilk Liu <leilk.liu at 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.
> + */
> +
> +#ifndef ____LINUX_PLATFORM_DATA_SPI_MTK_H
> +#define ____LINUX_PLATFORM_DATA_SPI_MTK_H
> +
> +/* Board specific platform_data */
> +struct mtk_chip_config {
> +       u32 tx_mlsb;
> +       u32 rx_mlsb;
> +       u32 tx_endian;
> +       u32 rx_endian;
> +};
> +#endif


From srinivas.kandagatla at linaro.org  Tue Aug 11 04:02:11 2015
From: srinivas.kandagatla at linaro.org (Srinivas Kandagatla)
Date: Tue, 11 Aug 2015 12:02:11 +0100
Subject: [PATCH RFC 0/3] nvmem: make sysfs binary file permissions more
 flexible.
Message-ID: <1439290931-18232-1-git-send-email-srinivas.kandagatla@linaro.org>

Hi All, 

Recent discussion raised by Andrew Lunn and others regarding default permission
set on the nvmem binary sysfs file resulted in this small fixup patchset.

By default nvmem core sets the readonly permission to everyone (S_IRUGO), this
is not desirable by many providers as they would not want everyone to view things
like passwords stored in the nvmem.

This patchset fixes this by making the default as root-only and then the
providers could supply with additional permissions if required. One of
the patch in this set also sets correct size for the binary file too,
so that the user would not even attempt to read past the size.

I have tested this on IFC6410 with qfprom.

Thanks,
srini

Srinivas Kandagatla (3):
  nvmem: make default user binary file root-access only
  nvmem: set the size for the nvmem binary file.
  nvmem: add permission flags in nvmem_config

 drivers/nvmem/core.c           | 55 +++++++++---------------------------------
 include/linux/nvmem-provider.h |  1 +
 2 files changed, 13 insertions(+), 43 deletions(-)

-- 
1.9.1



From srinivas.kandagatla at linaro.org  Tue Aug 11 04:03:12 2015
From: srinivas.kandagatla at linaro.org (Srinivas Kandagatla)
Date: Tue, 11 Aug 2015 12:03:12 +0100
Subject: [PATCH RFC 1/3] nvmem: make default user binary file root-access only
In-Reply-To: <1439290931-18232-1-git-send-email-srinivas.kandagatla@linaro.org>
References: <1439290931-18232-1-git-send-email-srinivas.kandagatla@linaro.org>
Message-ID: <1439290992-18283-1-git-send-email-srinivas.kandagatla@linaro.org>

As required by many providers like at24/at25/mxs-ocotp/qfprom and may be
other providers would want to allow root-only to read the nvmem content.
So making the defaults to be root-only access would address the request
and also provide flexibility to providers to specify there own permissions
on top of the root-only using the perm flag in nvmem_config.
Making this dynamic did cut down lot of static binary attributes in the
code.

Signed-off-by: Srinivas Kandagatla <srinivas.kandagatla at linaro.org>
---
 drivers/nvmem/core.c | 53 ++++++++++------------------------------------------
 1 file changed, 10 insertions(+), 43 deletions(-)

diff --git a/drivers/nvmem/core.c b/drivers/nvmem/core.c
index 35a42bb..103f6aa 100644
--- a/drivers/nvmem/core.c
+++ b/drivers/nvmem/core.c
@@ -31,6 +31,7 @@ struct nvmem_device {
 	struct regmap		*regmap;
 	struct module		*owner;
 	struct device		dev;
+	struct bin_attribute	bin;
 	int			stride;
 	int			word_size;
 	int			ncells;
@@ -109,52 +110,15 @@ static ssize_t bin_attr_nvmem_write(struct file *filp, struct kobject *kobj,
 }
 
 /* default read/write permissions */
-static struct bin_attribute bin_attr_rw_nvmem = {
+static struct bin_attribute bin_attr_template = {
 	.attr	= {
 		.name	= "nvmem",
-		.mode	= S_IWUSR | S_IRUGO,
+		.mode	= S_IRUSR,
 	},
 	.read	= bin_attr_nvmem_read,
 	.write	= bin_attr_nvmem_write,
 };
 
-static struct bin_attribute *nvmem_bin_rw_attributes[] = {
-	&bin_attr_rw_nvmem,
-	NULL,
-};
-
-static const struct attribute_group nvmem_bin_rw_group = {
-	.bin_attrs	= nvmem_bin_rw_attributes,
-};
-
-static const struct attribute_group *nvmem_rw_dev_groups[] = {
-	&nvmem_bin_rw_group,
-	NULL,
-};
-
-/* read only permission */
-static struct bin_attribute bin_attr_ro_nvmem = {
-	.attr	= {
-		.name	= "nvmem",
-		.mode	= S_IRUGO,
-	},
-	.read	= bin_attr_nvmem_read,
-};
-
-static struct bin_attribute *nvmem_bin_ro_attributes[] = {
-	&bin_attr_ro_nvmem,
-	NULL,
-};
-
-static const struct attribute_group nvmem_bin_ro_group = {
-	.bin_attrs	= nvmem_bin_ro_attributes,
-};
-
-static const struct attribute_group *nvmem_ro_dev_groups[] = {
-	&nvmem_bin_ro_group,
-	NULL,
-};
-
 static void nvmem_release(struct device *dev)
 {
 	struct nvmem_device *nvmem = to_nvmem_device(dev);
@@ -346,10 +310,8 @@ struct nvmem_device *nvmem_register(const struct nvmem_config *config)
 
 	nvmem->read_only = of_property_read_bool(np, "read-only") |
 			   config->read_only;
-
-	nvmem->dev.groups = nvmem->read_only ? nvmem_ro_dev_groups :
-					       nvmem_rw_dev_groups;
-
+	nvmem->bin = bin_attr_template;
+	nvmem->bin.attr.mode = nvmem->read_only ? : (S_IRUSR | S_IWUSR);
 	device_initialize(&nvmem->dev);
 
 	dev_dbg(&nvmem->dev, "Registering nvmem device %s\n", config->name);
@@ -361,6 +323,10 @@ struct nvmem_device *nvmem_register(const struct nvmem_config *config)
 		return ERR_PTR(rval);
 	}
 
+	rval = device_create_bin_file(&nvmem->dev, &nvmem->bin);
+	if (rval)
+		dev_err(&nvmem->dev, "Failed to create nvmem binary file\n");
+
 	if (config->cells)
 		nvmem_add_cells(nvmem, config);
 
@@ -385,6 +351,7 @@ int nvmem_unregister(struct nvmem_device *nvmem)
 	mutex_unlock(&nvmem_mutex);
 
 	nvmem_device_remove_all_cells(nvmem);
+	device_remove_bin_file(&nvmem->dev, &nvmem->bin);
 	device_del(&nvmem->dev);
 
 	return 0;
-- 
1.9.1



From srinivas.kandagatla at linaro.org  Tue Aug 11 04:03:36 2015
From: srinivas.kandagatla at linaro.org (Srinivas Kandagatla)
Date: Tue, 11 Aug 2015 12:03:36 +0100
Subject: [PATCH RFC 2/3] nvmem: set the size for the nvmem binary file.
In-Reply-To: <1439290931-18232-1-git-send-email-srinivas.kandagatla@linaro.org>
References: <1439290931-18232-1-git-send-email-srinivas.kandagatla@linaro.org>
Message-ID: <1439291016-18333-1-git-send-email-srinivas.kandagatla@linaro.org>

This patch sets the actual size of binary file to the nvmem size.
Previously this was not possible as the core was using the static global
data structures for attributes.

Signed-off-by: Srinivas Kandagatla <srinivas.kandagatla at linaro.org>
---
 drivers/nvmem/core.c | 1 +
 1 file changed, 1 insertion(+)

diff --git a/drivers/nvmem/core.c b/drivers/nvmem/core.c
index 103f6aa..414ed23 100644
--- a/drivers/nvmem/core.c
+++ b/drivers/nvmem/core.c
@@ -312,6 +312,7 @@ struct nvmem_device *nvmem_register(const struct nvmem_config *config)
 			   config->read_only;
 	nvmem->bin = bin_attr_template;
 	nvmem->bin.attr.mode = nvmem->read_only ? : (S_IRUSR | S_IWUSR);
+	nvmem->bin.size = nvmem->size;
 	device_initialize(&nvmem->dev);
 
 	dev_dbg(&nvmem->dev, "Registering nvmem device %s\n", config->name);
-- 
1.9.1



From srinivas.kandagatla at linaro.org  Tue Aug 11 04:03:44 2015
From: srinivas.kandagatla at linaro.org (Srinivas Kandagatla)
Date: Tue, 11 Aug 2015 12:03:44 +0100
Subject: [PATCH RFC 3/3] nvmem: add permission flags in nvmem_config
In-Reply-To: <1439290931-18232-1-git-send-email-srinivas.kandagatla@linaro.org>
References: <1439290931-18232-1-git-send-email-srinivas.kandagatla@linaro.org>
Message-ID: <1439291024-18375-1-git-send-email-srinivas.kandagatla@linaro.org>

This patch adds perm variable to nvmem_config structure which will allow
providers to specify the permissions required for the sysfs binary file.
This permission is applied on top of root-only access permissions set by
the core.

Signed-off-by: Srinivas Kandagatla <srinivas.kandagatla at linaro.org>
---
 drivers/nvmem/core.c           | 1 +
 include/linux/nvmem-provider.h | 1 +
 2 files changed, 2 insertions(+)

diff --git a/drivers/nvmem/core.c b/drivers/nvmem/core.c
index 414ed23..7481387 100644
--- a/drivers/nvmem/core.c
+++ b/drivers/nvmem/core.c
@@ -312,6 +312,7 @@ struct nvmem_device *nvmem_register(const struct nvmem_config *config)
 			   config->read_only;
 	nvmem->bin = bin_attr_template;
 	nvmem->bin.attr.mode = nvmem->read_only ? : (S_IRUSR | S_IWUSR);
+	nvmem->bin.attr.mode |= config->perm;
 	nvmem->bin.size = nvmem->size;
 	device_initialize(&nvmem->dev);
 
diff --git a/include/linux/nvmem-provider.h b/include/linux/nvmem-provider.h
index 0b68caf..de9a61f 100644
--- a/include/linux/nvmem-provider.h
+++ b/include/linux/nvmem-provider.h
@@ -23,6 +23,7 @@ struct nvmem_config {
 	const struct nvmem_cell_info	*cells;
 	int			ncells;
 	bool			read_only;
+	u16			perm; /* visibility in sysfs */
 };
 
 #if IS_ENABLED(CONFIG_NVMEM)
-- 
1.9.1



From marc.zyngier at arm.com  Tue Aug 11 04:24:56 2015
From: marc.zyngier at arm.com (Marc Zyngier)
Date: Tue, 11 Aug 2015 12:24:56 +0100
Subject: [PATCH] ARM: OMAP: irqdomain_hierarchy: fix arm gic irq type
 configuration
In-Reply-To: <1439285147-20027-1-git-send-email-grygorii.strashko@ti.com>
References: <1439285147-20027-1-git-send-email-grygorii.strashko@ti.com>
Message-ID: <20150811122456.1efe1656@arm.com>

On Tue, 11 Aug 2015 10:25:47 +0100
Grygorii Strashko <grygorii.strashko at ti.com> wrote:

Hi Grygorii,

> It's observed that ARM GIC IRQ triggering type is not configured
> properly when IRQ is routed through IRQ domains hierarchy and
> system started using DT. As result, system will start using default
> ARM GIC configuration, ignore DT IRQ type configuration,
> and value of desc->irq_data.state_use_accessors = 0.
> 
> In case of TI OMAP the following IRQ hierarchy is defined:
> ARM GIC <- OMAP wakeupgen <- TI CBAR
> 
> Failed call chain:
>  irq_create_of_mapping
>  irq_set_irq_type
>  __irq_set_trigger
>  if (!chip || !chip->irq_set_type) {
>     return 0; <- return here
>  }
>  CBAR has no .irq_set_type() defined and, so, IRQ triggering
>  configuration will not be propagated to parent IRQ domain.
> 
> Hence, fix it by introducing irq_chip_set_type_parent(), in the
> same manner as irq_chip_set_wake_parent(), and use it for IRQ 
> triggering type propagation to the parent IRQ domain in
> irq-crossbar and omap-wakeupgen.
> 
> / # cat /proc/interrupts -- before
> 230:          0          0      CBAR  30 Edge    -00000000  48051000.gpio
> 263:          0          0      CBAR 116 Edge    -00000000  48053000.gpio
> 296:        246          0      CBAR  67 Edge    -00000000  OMAP UART0
> 311:        341          0      CBAR  51 Edge    -00000000  48070000.i2c
> 312:          3          0      CBAR  52 Edge    -00000000  48072000.i2c
> 313:          0          0      CBAR  56 Edge    -00000000  48060000.i2c
> 314:        255          0      CBAR  78 Edge    -00000000  mmc0
> 315:         40          0      CBAR  81 Edge    -00000000  mmc1
> 316:         13          0      CBAR  91 Edge    -00000000  mmc2
> 320:          0          0      CBAR  49 Edge    -00000000  4a140000.sata
> 324:          0          0      CBAR   1 Edge    -00000000  48078000.elm
> 325:          0          0      CBAR  15 Edge    -00000000  gpmc
> 333:          0          0      CBAR 335 Edge    -00000000  48484000.ethernet
> 334:          0          0      CBAR 336 Edge    -00000000  48484000.ethernet
> 415:          0          0   pcf857x   2 Edge    -00000000  btnUser1
> 416:          0          0   pcf857x   3 Edge    -00000000  btnUser2
> 445:          0          0   pinctrl 992 Edge    -00010000  4806a000.seria
> 
> / # cat /proc/interrupts -- after
> 230:          0          0      CBAR  30 Level   -00002004  48051000.gpio
> 263:          0          0      CBAR 116 Level   -00002004  48053000.gpio
> 296:        567          0      CBAR  67 Level   -00002004  OMAP UART0
> 311:        363          0      CBAR  51 Level   -00002004  48070000.i2c
> 312:          3          0      CBAR  52 Level   -00002004  48072000.i2c
> 313:          0          0      CBAR  56 Level   -00002004  48060000.i2c
> 314:        197          0      CBAR  78 Level   -00002004  mmc0
> 315:         40          0      CBAR  81 Level   -00002004  mmc1
> 316:         13          0      CBAR  91 Level   -00002004  mmc2
> 320:          0          0      CBAR  49 Level   -00002004  4a140000.sata
> 324:          0          0      CBAR   1 Level   -00002004  48078000.elm
> 325:          0          0      CBAR  15 Level   -00002004  gpmc
> 333:          0          0      CBAR 335 Level   -00002004  48484000.ethernet
> 334:          0          0      CBAR 336 Level   -00002004  48484000.ethernet
> 415:          0          0   pcf857x   2 Edge    -00000000  btnUser1
> 416:          4          2   pcf857x   3 Edge    -00000000  btnUser2
> 445:          0          0   pinctrl 992 Edge    -00010000  4806a000.serial
> 
> Fixes: 783d31863fb8 ('irqchip: crossbar: Convert dra7 crossbar to stacked domains')
> Signed-off-by: Grygorii Strashko <grygorii.strashko at ti.com>
> ---
> Hi All,
> 
> I can split patch if required and overall solution acceptable.

This looks good to me. Please repost it after splitting it in two
patches.

Thanks,

	M.
-- 
Jazz is not dead. It just smells funny.


From haibo.chen at freescale.com  Tue Aug 11 04:38:25 2015
From: haibo.chen at freescale.com (Haibo Chen)
Date: Tue, 11 Aug 2015 19:38:25 +0800
Subject: [PATCH v6 0/6] mmc: imx: a few fixes and new feature
Message-ID: <1439293111-21077-1-git-send-email-haibo.chen@freescale.com>

Changes for v6:
-remove duplicate code in esdhc_set_uhs_signaling().
-fix a typo for patch-2.
-make commit log of patch-3 more specific.

Haibo Chen (6):
  mmc: sdhci-esdhc-imx: add imx7d support and support HS400
  mmc: sdhci-esdhc-imx: add tuning-step setting support
  mmc: sdhci-esdhc-imx: add imx7d support in bingding doc
  ARM: dts: imx7d-sdb: add eMMC5.0 support
  mmc: sdhci-esdhc-imx: set back the burst_length_enable bit to 1
  mmc: sdhci-esdhc-imx: change default watermark level and burst length

 .../devicetree/bindings/mmc/fsl-imx-esdhc.txt      |   6 ++
 arch/arm/boot/dts/imx7d-sdb.dts                    |  13 +++
 drivers/mmc/host/sdhci-esdhc-imx.c                 | 114 ++++++++++++++++++++-
 include/linux/platform_data/mmc-esdhc-imx.h        |   1 +
 4 files changed, 130 insertions(+), 4 deletions(-)

-- 
1.9.1



From haibo.chen at freescale.com  Tue Aug 11 04:38:26 2015
From: haibo.chen at freescale.com (Haibo Chen)
Date: Tue, 11 Aug 2015 19:38:26 +0800
Subject: [PATCH v6 1/6] mmc: sdhci-esdhc-imx: add imx7d support and support
 HS400
In-Reply-To: <1439293111-21077-1-git-send-email-haibo.chen@freescale.com>
References: <1439293111-21077-1-git-send-email-haibo.chen@freescale.com>
Message-ID: <1439293111-21077-2-git-send-email-haibo.chen@freescale.com>

The imx7d usdhc is derived from imx6sx, the difference is that
imx7d support HS400.

So introduce a new compatible string for imx7d and add HS400
support for imx7d usdhc.

Signed-off-by: Haibo Chen <haibo.chen at freescale.com>
---
 drivers/mmc/host/sdhci-esdhc-imx.c | 86 ++++++++++++++++++++++++++++++++++++--
 1 file changed, 83 insertions(+), 3 deletions(-)

diff --git a/drivers/mmc/host/sdhci-esdhc-imx.c b/drivers/mmc/host/sdhci-esdhc-imx.c
index c6b9f64..b8b7e88 100644
--- a/drivers/mmc/host/sdhci-esdhc-imx.c
+++ b/drivers/mmc/host/sdhci-esdhc-imx.c
@@ -44,6 +44,7 @@
 #define  ESDHC_MIX_CTRL_EXE_TUNE	(1 << 22)
 #define  ESDHC_MIX_CTRL_SMPCLK_SEL	(1 << 23)
 #define  ESDHC_MIX_CTRL_FBCLK_SEL	(1 << 25)
+#define  ESDHC_MIX_CTRL_HS400_EN	(1 << 26)
 /* Bits 3 and 6 are not SDHCI standard definitions */
 #define  ESDHC_MIX_CTRL_SDHCI_MASK	0xb7
 /* Tuning bits */
@@ -60,6 +61,16 @@
 #define  ESDHC_TUNE_CTRL_MIN		0
 #define  ESDHC_TUNE_CTRL_MAX		((1 << 7) - 1)
 
+/* strobe dll register */
+#define ESDHC_STROBE_DLL_CTRL		0x70
+#define ESDHC_STROBE_DLL_CTRL_ENABLE	(1 << 0)
+#define ESDHC_STROBE_DLL_CTRL_RESET	(1 << 1)
+#define ESDHC_STROBE_DLL_CTRL_SLV_DLY_TARGET_SHIFT	3
+
+#define ESDHC_STROBE_DLL_STATUS		0x74
+#define ESDHC_STROBE_DLL_STS_REF_LOCK	(1 << 1)
+#define ESDHC_STROBE_DLL_STS_SLV_LOCK	0x1
+
 #define ESDHC_TUNING_CTRL		0xcc
 #define ESDHC_STD_TUNING_EN		(1 << 24)
 /* NOTE: the minimum valid tuning start tap for mx6sl is 1 */
@@ -120,6 +131,11 @@
 #define ESDHC_FLAG_ERR004536		BIT(7)
 /* The IP supports HS200 mode */
 #define ESDHC_FLAG_HS200		BIT(8)
+/* The IP supports HS400 mode */
+#define ESDHC_FLAG_HS400		BIT(9)
+
+/* A higher clock ferquency than this rate requires strobell dll control */
+#define ESDHC_STROBE_DLL_CLK_FREQ	100000000
 
 struct esdhc_soc_data {
 	u32 flags;
@@ -156,6 +172,12 @@ static struct esdhc_soc_data usdhc_imx6sx_data = {
 			| ESDHC_FLAG_HAVE_CAP1 | ESDHC_FLAG_HS200,
 };
 
+static struct esdhc_soc_data usdhc_imx7d_data = {
+	.flags = ESDHC_FLAG_USDHC | ESDHC_FLAG_STD_TUNING
+			| ESDHC_FLAG_HAVE_CAP1 | ESDHC_FLAG_HS200
+			| ESDHC_FLAG_HS400,
+};
+
 struct pltfm_imx_data {
 	u32 scratchpad;
 	struct pinctrl *pinctrl;
@@ -199,6 +221,7 @@ static const struct of_device_id imx_esdhc_dt_ids[] = {
 	{ .compatible = "fsl,imx6sx-usdhc", .data = &usdhc_imx6sx_data, },
 	{ .compatible = "fsl,imx6sl-usdhc", .data = &usdhc_imx6sl_data, },
 	{ .compatible = "fsl,imx6q-usdhc", .data = &usdhc_imx6q_data, },
+	{ .compatible = "fsl,imx7d-usdhc", .data = &usdhc_imx7d_data, },
 	{ /* sentinel */ }
 };
 MODULE_DEVICE_TABLE(of, imx_esdhc_dt_ids);
@@ -274,6 +297,9 @@ static u32 esdhc_readl_le(struct sdhci_host *host, int reg)
 				val = SDHCI_SUPPORT_DDR50 | SDHCI_SUPPORT_SDR104
 					| SDHCI_SUPPORT_SDR50
 					| SDHCI_USE_SDR50_TUNING;
+
+			if (imx_data->socdata->flags & ESDHC_FLAG_HS400)
+				val |= SDHCI_SUPPORT_HS400;
 		}
 	}
 
@@ -774,6 +800,7 @@ static int esdhc_change_pinstate(struct sdhci_host *host,
 		break;
 	case MMC_TIMING_UHS_SDR104:
 	case MMC_TIMING_MMC_HS200:
+	case MMC_TIMING_MMC_HS400:
 		pinctrl = imx_data->pins_200mhz;
 		break;
 	default:
@@ -784,24 +811,68 @@ static int esdhc_change_pinstate(struct sdhci_host *host,
 	return pinctrl_select_state(imx_data->pinctrl, pinctrl);
 }
 
+/*
+ * For HS400 eMMC, there is a data_strobe line, this signal is generated
+ * by the device and used for data output and CRC status response output
+ * in HS400 mode. The frequency of this signal follows the frequency of
+ * CLK generated by host. Host receive the data which is aligned to the
+ * edge of data_strobe line. Due to the time delay between CLK line and
+ * data_strobe line, if the delay time is larger than one clock cycle,
+ * then CLK and data_strobe line will misaligned, read error shows up.
+ * So when the CLK is higher than 100MHz, each clock cycle is short enough,
+ * host should config the delay target.
+ */
+static void esdhc_set_strobe_dll(struct sdhci_host *host)
+{
+	u32 v;
+
+	if (host->mmc->actual_clock > ESDHC_STROBE_DLL_CLK_FREQ) {
+		/* force a reset on strobe dll */
+		writel(ESDHC_STROBE_DLL_CTRL_RESET,
+			host->ioaddr + ESDHC_STROBE_DLL_CTRL);
+		/*
+		 * enable strobe dll ctrl and adjust the delay target
+		 * for the uSDHC loopback read clock
+		 */
+		v = ESDHC_STROBE_DLL_CTRL_ENABLE |
+			(7 << ESDHC_STROBE_DLL_CTRL_SLV_DLY_TARGET_SHIFT);
+		writel(v, host->ioaddr + ESDHC_STROBE_DLL_CTRL);
+		/* wait 1us to make sure strobe dll status register stable */
+		udelay(1);
+		v = readl(host->ioaddr + ESDHC_STROBE_DLL_STATUS);
+		if (!(v & ESDHC_STROBE_DLL_STS_REF_LOCK))
+			dev_warn(mmc_dev(host->mmc),
+				"warning! HS400 strobe DLL status REF not lock!\n");
+		if (!(v & ESDHC_STROBE_DLL_STS_SLV_LOCK))
+			dev_warn(mmc_dev(host->mmc),
+				"warning! HS400 strobe DLL status SLV not lock!\n");
+	}
+}
+
 static void esdhc_set_uhs_signaling(struct sdhci_host *host, unsigned timing)
 {
+	u32 m;
 	struct sdhci_pltfm_host *pltfm_host = sdhci_priv(host);
 	struct pltfm_imx_data *imx_data = pltfm_host->priv;
 	struct esdhc_platform_data *boarddata = &imx_data->boarddata;
 
+	/* disable ddr mode and disable HS400 mode */
+	m = readl(host->ioaddr + ESDHC_MIX_CTRL);
+	m &= ~(ESDHC_MIX_CTRL_DDREN | ESDHC_MIX_CTRL_HS400_EN);
+	imx_data->is_ddr = 0;
+
 	switch (timing) {
 	case MMC_TIMING_UHS_SDR12:
 	case MMC_TIMING_UHS_SDR25:
 	case MMC_TIMING_UHS_SDR50:
 	case MMC_TIMING_UHS_SDR104:
 	case MMC_TIMING_MMC_HS200:
+		writel(m, host->ioaddr + ESDHC_MIX_CTRL);
 		break;
 	case MMC_TIMING_UHS_DDR50:
 	case MMC_TIMING_MMC_DDR52:
-		writel(readl(host->ioaddr + ESDHC_MIX_CTRL) |
-				ESDHC_MIX_CTRL_DDREN,
-				host->ioaddr + ESDHC_MIX_CTRL);
+		m |= ESDHC_MIX_CTRL_DDREN;
+		writel(m, host->ioaddr + ESDHC_MIX_CTRL);
 		imx_data->is_ddr = 1;
 		if (boarddata->delay_line) {
 			u32 v;
@@ -813,6 +884,12 @@ static void esdhc_set_uhs_signaling(struct sdhci_host *host, unsigned timing)
 			writel(v, host->ioaddr + ESDHC_DLL_CTRL);
 		}
 		break;
+	case MMC_TIMING_MMC_HS400:
+		m |= ESDHC_MIX_CTRL_DDREN | ESDHC_MIX_CTRL_HS400_EN;
+		writel(m, host->ioaddr + ESDHC_MIX_CTRL);
+		imx_data->is_ddr = 1;
+		esdhc_set_strobe_dll(host);
+		break;
 	}
 
 	esdhc_change_pinstate(host, timing);
@@ -1100,6 +1177,9 @@ static int sdhci_esdhc_imx_probe(struct platform_device *pdev)
 	if (imx_data->socdata->flags & ESDHC_FLAG_ERR004536)
 		host->quirks |= SDHCI_QUIRK_BROKEN_ADMA;
 
+	if (imx_data->socdata->flags & ESDHC_FLAG_HS400)
+		host->quirks2 |= SDHCI_QUIRK2_CAPS_BIT63_FOR_HS400;
+
 	if (of_id)
 		err = sdhci_esdhc_imx_probe_dt(pdev, host, imx_data);
 	else
-- 
1.9.1



From haibo.chen at freescale.com  Tue Aug 11 04:38:27 2015
From: haibo.chen at freescale.com (Haibo Chen)
Date: Tue, 11 Aug 2015 19:38:27 +0800
Subject: [PATCH v6 2/6] mmc: sdhci-esdhc-imx: add tuning-step setting support
In-Reply-To: <1439293111-21077-1-git-send-email-haibo.chen@freescale.com>
References: <1439293111-21077-1-git-send-email-haibo.chen@freescale.com>
Message-ID: <1439293111-21077-3-git-send-email-haibo.chen@freescale.com>

tuning-step is the delay cell steps in tuning procedure. The default value
of tuning-step is 1. Some boards or cards need another value to pass the
tuning procedure. For example, imx7d-sdb board need the tuning-step value
as 2, otherwise it can't pass the tuning procedure.

So this patch add the tuning-step setting in driver, so that user can set
the tuning-step value in dts.

Signed-off-by: Haibo Chen <haibo.chen at freescale.com>
---
 drivers/mmc/host/sdhci-esdhc-imx.c          | 9 +++++++++
 include/linux/platform_data/mmc-esdhc-imx.h | 1 +
 2 files changed, 10 insertions(+)

diff --git a/drivers/mmc/host/sdhci-esdhc-imx.c b/drivers/mmc/host/sdhci-esdhc-imx.c
index b8b7e88..298551d 100644
--- a/drivers/mmc/host/sdhci-esdhc-imx.c
+++ b/drivers/mmc/host/sdhci-esdhc-imx.c
@@ -75,6 +75,7 @@
 #define ESDHC_STD_TUNING_EN		(1 << 24)
 /* NOTE: the minimum valid tuning start tap for mx6sl is 1 */
 #define ESDHC_TUNING_START_TAP		0x1
+#define ESDHC_TUNING_STEP_SHIFT		16
 
 /* pinctrl state */
 #define ESDHC_PINCTRL_STATE_100MHZ	"state_100mhz"
@@ -474,6 +475,7 @@ static void esdhc_writew_le(struct sdhci_host *host, u16 val, int reg)
 		} else if (imx_data->socdata->flags & ESDHC_FLAG_STD_TUNING) {
 			u32 v = readl(host->ioaddr + SDHCI_ACMD12_ERR);
 			u32 m = readl(host->ioaddr + ESDHC_MIX_CTRL);
+			u32 tuning_ctrl;
 			if (val & SDHCI_CTRL_TUNED_CLK) {
 				v |= ESDHC_MIX_CTRL_SMPCLK_SEL;
 			} else {
@@ -484,6 +486,11 @@ static void esdhc_writew_le(struct sdhci_host *host, u16 val, int reg)
 			if (val & SDHCI_CTRL_EXEC_TUNING) {
 				v |= ESDHC_MIX_CTRL_EXE_TUNE;
 				m |= ESDHC_MIX_CTRL_FBCLK_SEL;
+				tuning_ctrl = readl(host->ioaddr + ESDHC_TUNING_CTRL);
+				tuning_ctrl |= ESDHC_STD_TUNING_EN | ESDHC_TUNING_START_TAP;
+				if (imx_data->boarddata.tuning_step)
+					tuning_ctrl |= imx_data->boarddata.tuning_step << ESDHC_TUNING_STEP_SHIFT;
+					writel(tuning_ctrl, host->ioaddr + ESDHC_TUNING_CTRL);
 			} else {
 				v &= ~ESDHC_MIX_CTRL_EXE_TUNE;
 			}
@@ -963,6 +970,8 @@ sdhci_esdhc_imx_probe_dt(struct platform_device *pdev,
 	if (gpio_is_valid(boarddata->wp_gpio))
 		boarddata->wp_type = ESDHC_WP_GPIO;
 
+	of_property_read_u32(np, "fsl,tuning-step", &boarddata->tuning_step);
+
 	if (of_find_property(np, "no-1-8-v", NULL))
 		boarddata->support_vsel = false;
 	else
diff --git a/include/linux/platform_data/mmc-esdhc-imx.h b/include/linux/platform_data/mmc-esdhc-imx.h
index e1571ef..95ccab3 100644
--- a/include/linux/platform_data/mmc-esdhc-imx.h
+++ b/include/linux/platform_data/mmc-esdhc-imx.h
@@ -45,5 +45,6 @@ struct esdhc_platform_data {
 	int max_bus_width;
 	bool support_vsel;
 	unsigned int delay_line;
+	unsigned int tuning_step;       /* The delay cell steps in tuning procedure */
 };
 #endif /* __ASM_ARCH_IMX_ESDHC_H */
-- 
1.9.1



From haibo.chen at freescale.com  Tue Aug 11 04:38:28 2015
From: haibo.chen at freescale.com (Haibo Chen)
Date: Tue, 11 Aug 2015 19:38:28 +0800
Subject: [PATCH v6 3/6] mmc: sdhci-esdhc-imx: add imx7d support in bingding doc
In-Reply-To: <1439293111-21077-1-git-send-email-haibo.chen@freescale.com>
References: <1439293111-21077-1-git-send-email-haibo.chen@freescale.com>
Message-ID: <1439293111-21077-4-git-send-email-haibo.chen@freescale.com>

Add a required property "fsl,imx7d-usdhc" in binding doc.
Add an optional property "fsl,tuning-step" in binding doc.

Signed-off-by: Haibo Chen <haibo.chen at freescale.com>
---
 Documentation/devicetree/bindings/mmc/fsl-imx-esdhc.txt | 6 ++++++
 1 file changed, 6 insertions(+)

diff --git a/Documentation/devicetree/bindings/mmc/fsl-imx-esdhc.txt b/Documentation/devicetree/bindings/mmc/fsl-imx-esdhc.txt
index 211e778..dca56d6 100644
--- a/Documentation/devicetree/bindings/mmc/fsl-imx-esdhc.txt
+++ b/Documentation/devicetree/bindings/mmc/fsl-imx-esdhc.txt
@@ -15,6 +15,7 @@ Required properties:
 	       "fsl,imx6q-usdhc"
 	       "fsl,imx6sl-usdhc"
 	       "fsl,imx6sx-usdhc"
+	       "fsl,imx7d-usdhc"
 
 Optional properties:
 - fsl,wp-controller : Indicate to use controller internal write protection
@@ -27,6 +28,11 @@ Optional properties:
   transparent level shifters on the outputs of the controller. Two cells are
   required, first cell specifies minimum slot voltage (mV), second cell
   specifies maximum slot voltage (mV). Several ranges could be specified.
+- fsl,tuning-step: Specify the increasing delay cell steps in tuning procedure.
+  The uSDHC use one delay cell as default increasing step to do tuning process.
+  This property allows user to change the tuning step to more than one delay
+  cells which is useful for some special boards or cards when the default
+  tuning step can't find the proper delay window within limited tuning retries.
 
 Examples:
 
-- 
1.9.1



From haibo.chen at freescale.com  Tue Aug 11 04:38:29 2015
From: haibo.chen at freescale.com (Haibo Chen)
Date: Tue, 11 Aug 2015 19:38:29 +0800
Subject: [PATCH v6 4/6] ARM: dts: imx7d-sdb: add eMMC5.0 support
In-Reply-To: <1439293111-21077-1-git-send-email-haibo.chen@freescale.com>
References: <1439293111-21077-1-git-send-email-haibo.chen@freescale.com>
Message-ID: <1439293111-21077-5-git-send-email-haibo.chen@freescale.com>

imx7d-sdb board has a eMMC5.0 on usdhc3. This eMMC support HS400.
This patch add usdhc3 support for HS400

Signed-off-by: Haibo Chen <haibo.chen at freescale.com>
---
 arch/arm/boot/dts/imx7d-sdb.dts | 13 +++++++++++++
 1 file changed, 13 insertions(+)

diff --git a/arch/arm/boot/dts/imx7d-sdb.dts b/arch/arm/boot/dts/imx7d-sdb.dts
index fdd1d7c..8059458 100644
--- a/arch/arm/boot/dts/imx7d-sdb.dts
+++ b/arch/arm/boot/dts/imx7d-sdb.dts
@@ -241,6 +241,19 @@
 	status = "okay";
 };
 
+&usdhc3 {
+	pinctrl-names = "default", "state_100mhz", "state_200mhz";
+	pinctrl-0 = <&pinctrl_usdhc3>;
+	pinctrl-1 = <&pinctrl_usdhc3_100mhz>;
+	pinctrl-2 = <&pinctrl_usdhc3_200mhz>;
+	assigned-clocks = <&clks IMX7D_USDHC3_ROOT_CLK>;
+	assigned-clock-rates = <400000000>;
+	bus-width = <8>;
+	fsl,tuning-step = <2>;
+	non-removable;
+	status = "okay";
+};
+
 &iomuxc {
 	pinctrl-names = "default";
 	pinctrl-0 = <&pinctrl_hog>;
-- 
1.9.1



From haibo.chen at freescale.com  Tue Aug 11 04:38:30 2015
From: haibo.chen at freescale.com (Haibo Chen)
Date: Tue, 11 Aug 2015 19:38:30 +0800
Subject: [PATCH v6 5/6] mmc: sdhci-esdhc-imx: set back the burst_length_enable
 bit to 1
In-Reply-To: <1439293111-21077-1-git-send-email-haibo.chen@freescale.com>
References: <1439293111-21077-1-git-send-email-haibo.chen@freescale.com>
Message-ID: <1439293111-21077-6-git-send-email-haibo.chen@freescale.com>

Currently we find that if a usdhc is choosed to boot system, then ROM
code will set the burst length enable bit of this usdhc as 0.

This will make performance drop a lot if this usdhc's burst length is
configed. So this patch set back the burst_length_enable bit as 1,
which is the default value, and means burst length is enabled for INCR.

Signed-off-by: Haibo Chen <haibo.chen at freescale.com>
---
 drivers/mmc/host/sdhci-esdhc-imx.c | 16 ++++++++++++++++
 1 file changed, 16 insertions(+)

diff --git a/drivers/mmc/host/sdhci-esdhc-imx.c b/drivers/mmc/host/sdhci-esdhc-imx.c
index 298551d..ac8ec01 100644
--- a/drivers/mmc/host/sdhci-esdhc-imx.c
+++ b/drivers/mmc/host/sdhci-esdhc-imx.c
@@ -32,6 +32,7 @@
 #include "sdhci-esdhc.h"
 
 #define	ESDHC_CTRL_D3CD			0x08
+#define ESDHC_BURST_LEN_EN_INCR		(1 << 27)
 /* VENDOR SPEC register */
 #define ESDHC_VENDOR_SPEC		0xc0
 #define  ESDHC_VENDOR_SPEC_SDIO_QUIRK	(1 << 1)
@@ -1163,6 +1164,21 @@ static int sdhci_esdhc_imx_probe(struct platform_device *pdev)
 		host->quirks2 |= SDHCI_QUIRK2_PRESET_VALUE_BROKEN;
 		host->mmc->caps |= MMC_CAP_1_8V_DDR;
 
+		/*
+		 * ROM code will change the bit burst_length_enable setting
+		 * to zero if this usdhc is choosed to boot system. Change
+		 * it back here, otherwise it will impact the performance a
+		 * lot. This bit is used to enable/disable the burst length
+		 * for the external AHB2AXI bridge, it's usefully especially
+		 * for INCR transfer because without burst length indicator,
+		 * the AHB2AXI bridge does not know the burst length in
+		 * advance. And without burst length indicator, AHB INCR
+		 * transfer can only be converted to singles on the AXI side.
+		 */
+		writel(readl(host->ioaddr + SDHCI_HOST_CONTROL)
+			| ESDHC_BURST_LEN_EN_INCR,
+			host->ioaddr + SDHCI_HOST_CONTROL);
+
 		if (!(imx_data->socdata->flags & ESDHC_FLAG_HS200))
 			host->quirks2 |= SDHCI_QUIRK2_BROKEN_HS200;
 
-- 
1.9.1



From haibo.chen at freescale.com  Tue Aug 11 04:38:31 2015
From: haibo.chen at freescale.com (Haibo Chen)
Date: Tue, 11 Aug 2015 19:38:31 +0800
Subject: [PATCH v6 6/6] mmc: sdhci-esdhc-imx: change default watermark level
 and burst length
In-Reply-To: <1439293111-21077-1-git-send-email-haibo.chen@freescale.com>
References: <1439293111-21077-1-git-send-email-haibo.chen@freescale.com>
Message-ID: <1439293111-21077-7-git-send-email-haibo.chen@freescale.com>

By default, for all imx SoC types, the watermark level is 16, and the
burst length is 8. But if the SDIO/SD/MMC I/O speed is fast enough,
this default watermark level and burst length will be the performance
bottleneck.

For example, i.MX7D support eMMC HS400 mode, this mode can run in 8 bit,
200MHZ DDR mode. So the I/O speed improve a lot compare to SD3.0.
The default burst length is 8, if we don't change this value, in
HS400 mode, when we do eMMC read operation, we can find that the
clock signal will stop for a period of time. This means the speed
of data moving on AHB bus is slower than I/O speed. So we should
improve the speed of data moving on AHB bus.

This patch set the default burst length as 16, and set the default
watermark level as 64. The test result is the clock signal has
no stop during the eMMC HS400 operation.

Signed-off-by: Haibo Chen <haibo.chen at freescale.com>
---
 drivers/mmc/host/sdhci-esdhc-imx.c | 3 ++-
 1 file changed, 2 insertions(+), 1 deletion(-)

diff --git a/drivers/mmc/host/sdhci-esdhc-imx.c b/drivers/mmc/host/sdhci-esdhc-imx.c
index ac8ec01..886d230 100644
--- a/drivers/mmc/host/sdhci-esdhc-imx.c
+++ b/drivers/mmc/host/sdhci-esdhc-imx.c
@@ -1160,7 +1160,8 @@ static int sdhci_esdhc_imx_probe(struct platform_device *pdev)
 	 * to something insane.  Change it back here.
 	 */
 	if (esdhc_is_usdhc(imx_data)) {
-		writel(0x08100810, host->ioaddr + ESDHC_WTMK_LVL);
+		writel(0x10401040, host->ioaddr + ESDHC_WTMK_LVL);
+
 		host->quirks2 |= SDHCI_QUIRK2_PRESET_VALUE_BROKEN;
 		host->mmc->caps |= MMC_CAP_1_8V_DDR;
 
-- 
1.9.1



From lee.jones at linaro.org  Tue Aug 11 04:47:36 2015
From: lee.jones at linaro.org (Lee Jones)
Date: Tue, 11 Aug 2015 12:47:36 +0100
Subject: [PATCH v3 3/4] mfd: Add DT binding for Maxim MAX77802 IC
In-Reply-To: <1438252327-28427-4-git-send-email-javier@osg.samsung.com>
References: <1438252327-28427-1-git-send-email-javier@osg.samsung.com>
 <1438252327-28427-4-git-send-email-javier@osg.samsung.com>
Message-ID: <20150811114736.GB18282@x1>

On Thu, 30 Jul 2015, Javier Martinez Canillas wrote:

> The MAX77802 is a chip that contains regulators, 2 32kHz clocks,
> a RTC and an I2C interface to program the individual components.
> 
> The are already DT bindings for the regulators and clocks and
> these reference to a bindings/mfd/max77802.txt file, that didn't
> exist, for the details about the PMIC.
> 
> Signed-off-by: Javier Martinez Canillas <javier at osg.samsung.com>
> Reviewed-by: Krzysztof Kozlowski <k.kozlowski at samsung.com>
> 
> ---
> 
> Changes in v3:
> - Add Krzysztof Kozlowski Reviewed-by tag to patch #3.
> - Capitalise all acronyms. Suggested by Lee Jones.
> - Use relative path to refer other bindings. Suggested by Lee Jones.
> - Use IRQ_TYPE_NONE instead of 0 in example. Suggested by Lee Jones.
> 
> Changes in v2:
> - Use the correct "maxim,max77802" compatible string.
>   Suggested by Krzysztof Kozlowski
> - Use a pmic generic node name for the max77802 node example.
>   Suggested by Sergei Shtylyov.
> 
>  Documentation/devicetree/bindings/mfd/max77802.txt | 26 ++++++++++++++++++++++
>  1 file changed, 26 insertions(+)
>  create mode 100644 Documentation/devicetree/bindings/mfd/max77802.txt
> 
> diff --git a/Documentation/devicetree/bindings/mfd/max77802.txt b/Documentation/devicetree/bindings/mfd/max77802.txt
> new file mode 100644
> index 000000000000..911ec5fcaefd
> --- /dev/null
> +++ b/Documentation/devicetree/bindings/mfd/max77802.txt
> @@ -0,0 +1,26 @@
> +Maxim MAX77802 multi-function device
> +
> +The Maxim MAX77802 is a Power Management IC (PMIC) that contains 10 high
> +efficiency Buck regulators, 32 Low-DropOut (LDO) regulators used to power
> +up application processors and peripherals, a 2-channel 32kHz clock outputs,
> +a Real-Time-Clock (RTC) and a I2C interface to program the individual
> +regulators, clocks outputs and the RTC.
> +
> +Binding for the built-in 32k clock generator block is defined separately
> +in the ../clk/maxim,max77802.txt file and binding for the regulators
> +is defined in the ../regulator/max77802.txt file.

  "Bindings for the built-in 32k clock generator block and
   regulators are defined in ../clk/maxim,max77802.txt and
   ../regulator/max77802.txt respectively."

> +Required properties:
> +- compatible : Must be "maxim,max77802";

';' ?

> +- reg : Specifies the I2C slave address of PMIC block.
> +- interrupts : This I2C device has an IRQ line connected to the main SoC.
> +- interrupt-parent : The parent interrupt controller.

I always find this easier on the eye when you:

Required properties:
- compatible		: Must be "maxim,max77802"
- reg			: Specifies the I2C slave address of PMIC block.
- interrupts		: This I2C device has an IRQ line connected to the main SoC.
- interrupt-parent	: The parent interrupt controller.

> +Example:
> +
> +	max77802: pmic at 09 {
> +		compatible = "maxim,max77802";
> +		interrupt-parent = <&intc>;
> +		interrupts = <26 IRQ_TYPE_NONE>;
> +		reg = <0x09>;
> +	};

-- 
Lee Jones
Linaro STMicroelectronics Landing Team Lead
Linaro.org ? Open source software for ARM SoCs
Follow Linaro: Facebook | Twitter | Blog


From lee.jones at linaro.org  Tue Aug 11 04:48:40 2015
From: lee.jones at linaro.org (Lee Jones)
Date: Tue, 11 Aug 2015 12:48:40 +0100
Subject: [PATCH v3 2/4] mfd: max77686: Use a generic name for the PMIC
 node in the example
In-Reply-To: <1438252327-28427-3-git-send-email-javier@osg.samsung.com>
References: <1438252327-28427-1-git-send-email-javier@osg.samsung.com>
 <1438252327-28427-3-git-send-email-javier@osg.samsung.com>
Message-ID: <20150811114840.GC18282@x1>

On Thu, 30 Jul 2015, Javier Martinez Canillas wrote:

> The ePAPR standard says that: "the name of a node should be somewhat
> generic, reflecting the function of the device and not its precise
> programming model."
> 
> So, change the max77686 binding document example to use a generic
> node name instead of using the chip's name.
> 
> Suggested-by: Sergei Shtylyov <sergei.shtylyov at cogentembedded.com>
> Signed-off-by: Javier Martinez Canillas <javier at osg.samsung.com>
> 
> ---
> 
> Changes in v3:
>  - Fix typo in ePAPR document name. Suggested by Sergei Shtylyov
> 
> Changes in v2: None
> 
>  Documentation/devicetree/bindings/mfd/max77686.txt | 2 +-
>  1 file changed, 1 insertion(+), 1 deletion(-)

Acked-by: Lee Jones <lee.jones at linaro.org>

> diff --git a/Documentation/devicetree/bindings/mfd/max77686.txt b/Documentation/devicetree/bindings/mfd/max77686.txt
> index 8221102d3fc2..d2ed3c20a5c3 100644
> --- a/Documentation/devicetree/bindings/mfd/max77686.txt
> +++ b/Documentation/devicetree/bindings/mfd/max77686.txt
> @@ -48,7 +48,7 @@ to get matched with their hardware counterparts as follow:
>  
>  Example:
>  
> -	max77686 at 09 {
> +	max77686: pmic at 09 {
>  		compatible = "maxim,max77686";
>  		interrupt-parent = <&wakeup_eint>;
>  		interrupts = <26 0>;

-- 
Lee Jones
Linaro STMicroelectronics Landing Team Lead
Linaro.org ? Open source software for ARM SoCs
Follow Linaro: Facebook | Twitter | Blog


From lee.jones at linaro.org  Tue Aug 11 04:49:18 2015
From: lee.jones at linaro.org (Lee Jones)
Date: Tue, 11 Aug 2015 12:49:18 +0100
Subject: [PATCH v3 1/4] mfd: max77686: Don't suggest in binding to use a
 deprecated property
In-Reply-To: <1438252327-28427-2-git-send-email-javier@osg.samsung.com>
References: <1438252327-28427-1-git-send-email-javier@osg.samsung.com>
 <1438252327-28427-2-git-send-email-javier@osg.samsung.com>
Message-ID: <20150811114918.GD18282@x1>

On Thu, 30 Jul 2015, Javier Martinez Canillas wrote:

> The regulator-compatible property from the regulator DT binding was
> deprecated. But the max77686 DT binding doc still suggest to use it
> instead of the regulator node name's which is the correct approach.
> 
> Signed-off-by: Javier Martinez Canillas <javier at osg.samsung.com>
> Reviewed-by: Krzysztof Kozlowski <k.kozlowski at samsung.com>
> 
> ---
> 
> Changes in v3: None
> Changes in v2:
> - Add Krzysztof Kozlowski Reviewed-by tag in patch #1.
> 
>  Documentation/devicetree/bindings/mfd/max77686.txt | 11 ++++-------
>  1 file changed, 4 insertions(+), 7 deletions(-)

Acked-by: Lee Jones <lee.jones at linaro.org>

> diff --git a/Documentation/devicetree/bindings/mfd/max77686.txt b/Documentation/devicetree/bindings/mfd/max77686.txt
> index 163bd81a4607..8221102d3fc2 100644
> --- a/Documentation/devicetree/bindings/mfd/max77686.txt
> +++ b/Documentation/devicetree/bindings/mfd/max77686.txt
> @@ -26,7 +26,7 @@ Optional node:
>  	};
>  	refer Documentation/devicetree/bindings/regulator/regulator.txt
>  
> -  The regulator-compatible property of regulator should initialized with string
> +  The regulator node's name should be initialized with a string
>  to get matched with their hardware counterparts as follow:
>  
>  	-LDOn 	:	for LDOs, where n can lie in range 1 to 26.
> @@ -55,16 +55,14 @@ Example:
>  		reg = <0x09>;
>  
>  		voltage-regulators {
> -			ldo11_reg {
> -				regulator-compatible = "LDO11";
> +			ldo11_reg: LDO11 {
>  				regulator-name = "vdd_ldo11";
>  				regulator-min-microvolt = <1900000>;
>  				regulator-max-microvolt = <1900000>;
>  				regulator-always-on;
>  			};
>  
> -			buck1_reg {
> -				regulator-compatible = "BUCK1";
> +			buck1_reg: BUCK1 {
>  				regulator-name = "vdd_mif";
>  				regulator-min-microvolt = <950000>;
>  				regulator-max-microvolt = <1300000>;
> @@ -72,8 +70,7 @@ Example:
>  				regulator-boot-on;
>  			};
>  
> -			buck9_reg {
> -				regulator-compatible = "BUCK9";
> +			buck9_reg: BUCK9 {
>  				regulator-name = "CAM_ISP_CORE_1.2V";
>  				regulator-min-microvolt = <1000000>;
>  				regulator-max-microvolt = <1200000>;

-- 
Lee Jones
Linaro STMicroelectronics Landing Team Lead
Linaro.org ? Open source software for ARM SoCs
Follow Linaro: Facebook | Twitter | Blog


From lee.jones at linaro.org  Tue Aug 11 04:54:25 2015
From: lee.jones at linaro.org (Lee Jones)
Date: Tue, 11 Aug 2015 12:54:25 +0100
Subject: [PATCH v4 2/2] dt: power: st: Provide bindings for ST's OPPs
In-Reply-To: <20150811100941.GG5509@linux>
References: <20150729081403.GH2284@x1> <20150729221526.GE3159@codeaurora.org>
 <20150730084634.GD9319@x1>
 <CAL_JsqKQLQ15qSt95zBZykzzPhcUrtZzhk29a76n+r_3719AiA@mail.gmail.com>
 <20150731163715.GV3159@codeaurora.org> <20150803034642.GV899@linux>
 <20150810132247.GH3249@x1> <20150811080023.GB5509@linux>
 <20150811093039.GA18282@x1> <20150811100941.GG5509@linux>
Message-ID: <20150811115425.GE18282@x1>

On Tue, 11 Aug 2015, Viresh Kumar wrote:
> On 11-08-15, 10:30, Lee Jones wrote:
> > On Tue, 11 Aug 2015, Viresh Kumar wrote:
> > 
> > > On 10-08-15, 14:22, Lee Jones wrote:
> > > > >  Optional properties:
> > > > > +- opp-cuts: One or more strings, describing the versions of hardware the OPPs
> > > > > +  can support.
> > > > 
> > > > This isn't very generic.
> > > > 
> > > > I'm guessing some vendors my have quite a few ways to differentiate
> > > > between board versions/revisions/cuts etc.
> > > > 
> > > > How about another array where a vendor can choose to identify a piece
> > > > of hardware however they see fit.
> > > > 
> > > > Example 1 (simple version):
> > > > 
> > > > /* Version 1 */
> > > > opp-version = <1>;
> > > > 
> > > > Example 2 (using the kernel's versioning):
> > > > 
> > > > /* 2.6.32-rc1 */
> > > > opp-version = <2 6 32 1>;
> > > > 
> > > > Example 3 (using ST's versioning):
> > > > 
> > > > /* Major 2, Minor 0, Cut 2, All substrates */
> > > > opp-version = <2 0 2 0xff>;
> > > 
> > > But how will we parse this with generic code ?
> > 
> > Why would you want to?
> 
> So that individual platforms don't need to reinvent the wheel ?

The framework does not need to parse this information.  It is used
solely by the platform driver, whose job it is to decide which OPPs
are appropriate for the running platform.

Back to my question; how would you like arbitrary version information,
which means different things to different vendors to be used in
shared/generic/framework code?

-- 
Lee Jones
Linaro STMicroelectronics Landing Team Lead
Linaro.org ? Open source software for ARM SoCs
Follow Linaro: Facebook | Twitter | Blog


From viresh.kumar at linaro.org  Tue Aug 11 05:01:24 2015
From: viresh.kumar at linaro.org (Viresh Kumar)
Date: Tue, 11 Aug 2015 17:31:24 +0530
Subject: [PATCH v4 2/2] dt: power: st: Provide bindings for ST's OPPs
In-Reply-To: <20150811115425.GE18282@x1>
References: <20150729221526.GE3159@codeaurora.org> <20150730084634.GD9319@x1>
 <CAL_JsqKQLQ15qSt95zBZykzzPhcUrtZzhk29a76n+r_3719AiA@mail.gmail.com>
 <20150731163715.GV3159@codeaurora.org> <20150803034642.GV899@linux>
 <20150810132247.GH3249@x1> <20150811080023.GB5509@linux>
 <20150811093039.GA18282@x1> <20150811100941.GG5509@linux>
 <20150811115425.GE18282@x1>
Message-ID: <20150811120124.GH5509@linux>

On 11-08-15, 12:54, Lee Jones wrote:
> The framework does not need to parse this information.  It is used
> solely by the platform driver, whose job it is to decide which OPPs
> are appropriate for the running platform.

The OPP layer needs to parse OPP nodes in DT. But for doing that it
needs to know which OPPs to pick from the table as, in cases like
yours or qcom, not all OPPs might be available.

One of the ways to do that is:
- the platform reads its efuses (or whatever) and encodes the
  information into a string.
- This string should match with the strings present (somewhere) in the
  OPP table. That location can be like what I proposed few mails back.
- Then the *generic* OPP code can parse only those OPP nodes which
  match with that string.

This way, we can avoid pushing the platform code to parse OPP tables.

> Back to my question; how would you like arbitrary version information,
> which means different things to different vendors to be used in
> shared/generic/framework code?

Exactly like I wrote above. The platform just needs to give a string
that should match with the OPPs ..

-- 
viresh


From mchehab at osg.samsung.com  Tue Aug 11 05:09:15 2015
From: mchehab at osg.samsung.com (Mauro Carvalho Chehab)
Date: Tue, 11 Aug 2015 09:09:15 -0300
Subject: [PATCH RFC v2 09/16] media: use media_graph_obj for link endpoints
In-Reply-To: <cover.1438954897.git.mchehab@osg.samsung.com>
References: <cover.1438954897.git.mchehab@osg.samsung.com>
Message-ID: <6d02794028ea4f7ad33e3ba0e07e0c690e2feee2.1439292977.git.mchehab@osg.samsung.com>

As we'll need to create links between entities and interfaces,
we need to identify the link endpoints by the media_graph_obj.

Most of the changes here was done by this small script:

for i in `find drivers/media -type f` `find drivers/staging/media -type f`; do
	perl -ne 's,([\w]+)\-\>(source|sink)\-\>entity,gobj_to_pad($1->$2)->entity,; print $_;' <$i >a && mv a $i
done

Please note that, while we're now using graph_obj to reference
the link endpoints, we're still assuming that all endpoints are
pads. This is true for all existing links, so no problems
are expected so far.

Yet, as we introduce links between entities and interfaces,
we may need to change some existing code to work with links
that aren't pad to pad.

Signed-off-by: Mauro Carvalho Chehab <mchehab at osg.samsung.com>

diff --git a/drivers/media/dvb-core/dvb_frontend.c b/drivers/media/dvb-core/dvb_frontend.c
index 842b9c8f80c6..4de93d6b203e 100644
--- a/drivers/media/dvb-core/dvb_frontend.c
+++ b/drivers/media/dvb-core/dvb_frontend.c
@@ -635,7 +635,9 @@ static int dvb_enable_media_tuner(struct dvb_frontend *fe)
 
 	for (i = 0; i < entity->num_links; i++) {
 		link = &entity->links[i];
-		if (link->sink->entity == entity) {
+		if (link->sink.type != MEDIA_GRAPH_PAD)
+			continue;
+		if (gobj_to_pad(link->sink)->entity == entity) {
 			found_link = link;
 			n_links++;
 			if (link->flags & MEDIA_LNK_FL_ENABLED)
@@ -658,14 +660,16 @@ static int dvb_enable_media_tuner(struct dvb_frontend *fe)
 		return -EINVAL;
 	}
 
-	source = found_link->source->entity;
+	source = gobj_to_pad(found_link->source)->entity;
 	fepriv->pipe_start_entity = source;
 	for (i = 0; i < source->num_links; i++) {
 		struct media_entity *sink;
 		int flags = 0;
 
 		link = &source->links[i];
-		sink = link->sink->entity;
+		if (link->sink.type != MEDIA_GRAPH_PAD)
+			continue;
+		sink = gobj_to_pad(link->sink)->entity;
 
 		if (sink == entity)
 			flags = MEDIA_LNK_FL_ENABLED;
diff --git a/drivers/media/media-device.c b/drivers/media/media-device.c
index a95ca981aabb..40597e9a0ff0 100644
--- a/drivers/media/media-device.c
+++ b/drivers/media/media-device.c
@@ -155,14 +155,19 @@ static long __media_device_enum_links(struct media_device *mdev,
 		list_for_each_entry(ent_link, &entity->links, list) {
 			struct media_link_desc link;
 
+			/* Only PAD to PAD links should be enumerated with legacy API */
+			if (ent_link->source->type != MEDIA_GRAPH_PAD ||
+			    ent_link->sink->type != MEDIA_GRAPH_PAD)
+				continue;
+
 			/* Ignore backlinks. */
-			if (ent_link->source->entity != entity)
+			if (gobj_to_pad(ent_link->source)->entity != entity)
 				continue;
 
 			memset(&link, 0, sizeof(link));
-			media_device_kpad_to_upad(ent_link->source,
+			media_device_kpad_to_upad(gobj_to_pad(ent_link->source),
 						  &link.source);
-			media_device_kpad_to_upad(ent_link->sink,
+			media_device_kpad_to_upad(gobj_to_pad(ent_link->sink),
 						  &link.sink);
 			link.flags = ent_link->flags;
 			if (copy_to_user(ulink, &link, sizeof(*ulink)))
diff --git a/drivers/media/media-entity.c b/drivers/media/media-entity.c
index 4a42ccfeffab..c8bbf122f4a6 100644
--- a/drivers/media/media-entity.c
+++ b/drivers/media/media-entity.c
@@ -121,10 +121,15 @@ EXPORT_SYMBOL_GPL(media_entity_cleanup);
 static struct media_entity *
 media_entity_other(struct media_entity *entity, struct media_link *link)
 {
-	if (link->source->entity == entity)
-		return link->sink->entity;
+	/* For now, we only do graph traversal with PADs */
+	if (link->sink->type != MEDIA_GRAPH_PAD ||
+	    link->source->type != MEDIA_GRAPH_PAD)
+		return NULL;
+
+	if (gobj_to_pad(link->source)->entity == entity)
+		return gobj_to_pad(link->sink)->entity;
 	else
-		return link->source->entity;
+		return gobj_to_pad(link->source)->entity;
 }
 
 /* push an entity to traversal stack */
@@ -217,6 +222,10 @@ media_entity_graph_walk_next(struct media_entity_graph *graph)
 
 		/* Get the entity in the other end of the link . */
 		next = media_entity_other(entity, link);
+		if (!next) {
+			list_rotate_left(&link_top(graph));
+			continue;
+		}
 		if (WARN_ON(next->id >= MEDIA_ENTITY_ENUM_MAX_ID))
 			return NULL;
 
@@ -285,8 +294,16 @@ __must_check int media_entity_pipeline_start(struct media_entity *entity,
 		bitmap_fill(has_no_links, entity->num_pads);
 
 		list_for_each_entry(link, &entity->links, list) {
-			struct media_pad *pad = link->sink->entity == entity
+			struct media_graph_obj *gobj;
+			struct media_pad *pad;
+
+			/* For now, ignore interface<->entity links */
+			if (link->sink->type != MEDIA_GRAPH_PAD)
+				continue;
+
+			gobj = gobj_to_pad(link->sink)->entity == entity
 						? link->sink : link->source;
+			pad = gobj_to_pad(gobj);
 
 			/* Mark that a pad is connected by a link. */
 			bitmap_clear(has_no_links, pad->index, 1);
@@ -304,7 +321,7 @@ __must_check int media_entity_pipeline_start(struct media_entity *entity,
 			 * Link validation will only take place for
 			 * sink ends of the link that are enabled.
 			 */
-			if (link->sink != pad ||
+			if (link->sink != gobj ||
 			    !(link->flags & MEDIA_LNK_FL_ENABLED))
 				continue;
 
@@ -312,9 +329,10 @@ __must_check int media_entity_pipeline_start(struct media_entity *entity,
 			if (ret < 0 && ret != -ENOIOCTLCMD) {
 				dev_dbg(entity->parent->dev,
 					"link validation failed for \"%s\":%u -> \"%s\":%u, error %d\n",
-					entity->name, link->source->index,
-					link->sink->entity->name,
-					link->sink->index, ret);
+					entity->name,
+					gobj_to_pad(link->source)->index,
+					gobj_to_pad(link->sink)->entity->name,
+					gobj_to_pad(link->sink)->index, ret);
 				goto error;
 			}
 		}
@@ -477,8 +495,8 @@ media_entity_create_link(struct media_entity *source, u16 source_pad,
 	if (link == NULL)
 		return -ENOMEM;
 
-	link->source = &source->pads[source_pad];
-	link->sink = &sink->pads[sink_pad];
+	link->source = &source->pads[source_pad].graph_obj;
+	link->sink = &sink->pads[sink_pad].graph_obj;
 	link->flags = flags;
 
 	/* Create the backlink. Backlinks are used to help graph traversal and
@@ -490,8 +508,8 @@ media_entity_create_link(struct media_entity *source, u16 source_pad,
 		return -ENOMEM;
 	}
 
-	backlink->source = &source->pads[source_pad];
-	backlink->sink = &sink->pads[sink_pad];
+	backlink->source = &source->pads[source_pad].graph_obj;
+	backlink->sink = &sink->pads[sink_pad].graph_obj;
 	backlink->flags = flags;
 
 	link->reverse = backlink;
@@ -510,10 +528,10 @@ static void __media_entity_remove_link(struct media_entity *entity,
 	struct media_entity *remote;
 	unsigned int r = 0;
 
-	if (link->source->entity == entity)
-		remote = link->sink->entity;
+	if (gobj_to_pad(link->source)->entity == entity)
+		remote = gobj_to_pad(link->sink)->entity;
 	else
-		remote = link->source->entity;
+		remote = gobj_to_pad(link->source)->entity;
 
 	list_for_each_entry_safe(rlink, tmp, &remote->links, list) {
 		if (rlink != link->reverse) {
@@ -521,7 +539,7 @@ static void __media_entity_remove_link(struct media_entity *entity,
 			continue;
 		}
 
-		if (link->source->entity == entity)
+		if (gobj_to_pad(link->source)->entity == entity)
 			remote->num_backlinks--;
 
 		if (--remote->num_links == 0)
@@ -564,16 +582,19 @@ static int __media_entity_setup_link_notify(struct media_link *link, u32 flags)
 	int ret;
 
 	/* Notify both entities. */
-	ret = media_entity_call(link->source->entity, link_setup,
-				link->source, link->sink, flags);
+	ret = media_entity_call(gobj_to_pad(link->source)->entity, link_setup,
+				gobj_to_pad(link->source),
+				gobj_to_pad(link->sink), flags);
 	if (ret < 0 && ret != -ENOIOCTLCMD)
 		return ret;
 
-	ret = media_entity_call(link->sink->entity, link_setup,
-				link->sink, link->source, flags);
+	ret = media_entity_call(gobj_to_pad(link->sink)->entity, link_setup,
+				gobj_to_pad(link->sink),
+				gobj_to_pad(link->source), flags);
 	if (ret < 0 && ret != -ENOIOCTLCMD) {
-		media_entity_call(link->source->entity, link_setup,
-				  link->source, link->sink, link->flags);
+		media_entity_call(gobj_to_pad(link->source)->entity, link_setup,
+				  gobj_to_pad(link->source),
+				  gobj_to_pad(link->sink), link->flags);
 		return ret;
 	}
 
@@ -617,8 +638,8 @@ int __media_entity_setup_link(struct media_link *link, u32 flags)
 	if (link->flags == flags)
 		return 0;
 
-	source = link->source->entity;
-	sink = link->sink->entity;
+	source = gobj_to_pad(link->source)->entity;
+	sink = gobj_to_pad(link->sink)->entity;
 
 	if (!(link->flags & MEDIA_LNK_FL_DYNAMIC) &&
 	    (source->stream_count || sink->stream_count))
@@ -645,9 +666,9 @@ int media_entity_setup_link(struct media_link *link, u32 flags)
 {
 	int ret;
 
-	mutex_lock(&link->source->entity->parent->graph_mutex);
+	mutex_lock(&gobj_to_pad(link->source)->entity->parent->graph_mutex);
 	ret = __media_entity_setup_link(link, flags);
-	mutex_unlock(&link->source->entity->parent->graph_mutex);
+	mutex_unlock(&gobj_to_pad(link->source)->entity->parent->graph_mutex);
 
 	return ret;
 }
@@ -667,10 +688,10 @@ media_entity_find_link(struct media_pad *source, struct media_pad *sink)
 	struct media_link *link;
 
 	list_for_each_entry(link, &source->entity->links, list) {
-		if (link->source->entity == source->entity &&
-		    link->source->index == source->index &&
-		    link->sink->entity == sink->entity &&
-		    link->sink->index == sink->index)
+		if (gobj_to_pad(link->source)->entity == source->entity &&
+		    gobj_to_pad(link->source)->index == source->index &&
+		    gobj_to_pad(link->sink)->entity == sink->entity &&
+		    gobj_to_pad(link->sink)->index == sink->index)
 			return link;
 	}
 
@@ -696,11 +717,11 @@ struct media_pad *media_entity_remote_pad(struct media_pad *pad)
 		if (!(link->flags & MEDIA_LNK_FL_ENABLED))
 			continue;
 
-		if (link->source == pad)
-			return link->sink;
+		if (gobj_to_pad(link->source) == pad)
+			return gobj_to_pad(link->sink);
 
-		if (link->sink == pad)
-			return link->source;
+		if (gobj_to_pad(link->sink) == pad)
+			return gobj_to_pad(link->source);
 	}
 
 	return NULL;
diff --git a/drivers/media/platform/exynos4-is/media-dev.c b/drivers/media/platform/exynos4-is/media-dev.c
index 4f5586a4cbff..f924148767ba 100644
--- a/drivers/media/platform/exynos4-is/media-dev.c
+++ b/drivers/media/platform/exynos4-is/media-dev.c
@@ -1091,7 +1091,7 @@ static int __fimc_md_modify_pipelines(struct media_entity *entity, bool enable)
 static int fimc_md_link_notify(struct media_link *link, unsigned int flags,
 				unsigned int notification)
 {
-	struct media_entity *sink = link->sink->entity;
+	struct media_entity *sink = gobj_to_pad(link->sink)->entity;
 	int ret = 0;
 
 	/* Before link disconnection */
diff --git a/drivers/media/platform/omap3isp/isp.c b/drivers/media/platform/omap3isp/isp.c
index 12be830d704f..7e2f4c9c0eef 100644
--- a/drivers/media/platform/omap3isp/isp.c
+++ b/drivers/media/platform/omap3isp/isp.c
@@ -822,8 +822,8 @@ int omap3isp_pipeline_pm_use(struct media_entity *entity, int use)
 static int isp_pipeline_link_notify(struct media_link *link, u32 flags,
 				    unsigned int notification)
 {
-	struct media_entity *source = link->source->entity;
-	struct media_entity *sink = link->sink->entity;
+	struct media_entity *source = gobj_to_pad(link->source)->entity;
+	struct media_entity *sink = gobj_to_pad(link->sink)->entity;
 	int source_use = isp_pipeline_pm_use_count(source);
 	int sink_use = isp_pipeline_pm_use_count(sink);
 	int ret;
diff --git a/drivers/media/platform/omap3isp/ispccdc.c b/drivers/media/platform/omap3isp/ispccdc.c
index 3b10304b580b..f01b540d1841 100644
--- a/drivers/media/platform/omap3isp/ispccdc.c
+++ b/drivers/media/platform/omap3isp/ispccdc.c
@@ -2419,7 +2419,7 @@ static int ccdc_link_validate(struct v4l2_subdev *sd,
 	if (ccdc->input == CCDC_INPUT_PARALLEL) {
 		struct isp_parallel_cfg *parcfg =
 			&((struct isp_bus_cfg *)
-			  media_entity_to_v4l2_subdev(link->source->entity)
+			  media_entity_to_v4l2_subdev(gobj_to_pad(link->source)->entity)
 			  ->host_priv)->bus.parallel;
 		parallel_shift = parcfg->data_lane_shift * 2;
 	} else {
diff --git a/drivers/media/usb/cx231xx/cx231xx-video.c b/drivers/media/usb/cx231xx/cx231xx-video.c
index e8baff4d6290..55b41113426c 100644
--- a/drivers/media/usb/cx231xx/cx231xx-video.c
+++ b/drivers/media/usb/cx231xx/cx231xx-video.c
@@ -128,7 +128,7 @@ static int cx231xx_enable_analog_tuner(struct cx231xx *dev)
 		return 0;
 
 	list_for_each_entry(link, &decoder->links, list) {
-		if (link->sink->entity == decoder) {
+		if (gobj_to_pad(link->sink)->entity == decoder) {
 			found_link = link;
 			if (link->flags & MEDIA_LNK_FL_ENABLED)
 				active_links++;
@@ -139,12 +139,12 @@ static int cx231xx_enable_analog_tuner(struct cx231xx *dev)
 	if (active_links == 1 || !found_link)
 		return 0;
 
-	source = found_link->source->entity;
+	source = gobj_to_pad(found_link->source)->entity;
 	list_for_each_entry(link, &source->links, list) {
 		struct media_entity *sink;
 		int flags = 0;
 
-		sink = link->sink->entity;
+		sink = gobj_to_pad(link->sink)->entity;
 
 		if (sink == entity)
 			flags = MEDIA_LNK_FL_ENABLED;
diff --git a/drivers/media/v4l2-core/v4l2-subdev.c b/drivers/media/v4l2-core/v4l2-subdev.c
index 83615b8fb46a..87de18a7b1c4 100644
--- a/drivers/media/v4l2-core/v4l2-subdev.c
+++ b/drivers/media/v4l2-core/v4l2-subdev.c
@@ -523,9 +523,11 @@ int v4l2_subdev_link_validate_default(struct v4l2_subdev *sd,
 EXPORT_SYMBOL_GPL(v4l2_subdev_link_validate_default);
 
 static int
-v4l2_subdev_link_validate_get_format(struct media_pad *pad,
+v4l2_subdev_link_validate_get_format(struct media_graph_obj *gobj,
 				     struct v4l2_subdev_format *fmt)
 {
+	struct media_pad *pad = gobj_to_pad(gobj);
+
 	if (media_entity_type(pad->entity) == MEDIA_ENT_T_V4L2_SUBDEV) {
 		struct v4l2_subdev *sd =
 			media_entity_to_v4l2_subdev(pad->entity);
@@ -558,7 +560,7 @@ int v4l2_subdev_link_validate(struct media_link *link)
 	if (rval < 0)
 		return 0;
 
-	sink = media_entity_to_v4l2_subdev(link->sink->entity);
+	sink = media_entity_to_v4l2_subdev(gobj_to_pad(link->sink)->entity);
 
 	rval = v4l2_subdev_call(sink, pad, link_validate, link,
 				&source_fmt, &sink_fmt);
diff --git a/drivers/staging/media/omap4iss/iss.c b/drivers/staging/media/omap4iss/iss.c
index 9bfb725b9986..5556ffbd7619 100644
--- a/drivers/staging/media/omap4iss/iss.c
+++ b/drivers/staging/media/omap4iss/iss.c
@@ -142,7 +142,7 @@ int omap4iss_get_external_info(struct iss_pipeline *pipe,
 
 	fmt.pad = link->source->index;
 	fmt.which = V4L2_SUBDEV_FORMAT_ACTIVE;
-	ret = v4l2_subdev_call(media_entity_to_v4l2_subdev(link->sink->entity),
+	ret = v4l2_subdev_call(media_entity_to_v4l2_subdev(gobj_to_pad(link->sink)->entity),
 			       pad, get_fmt, NULL, &fmt);
 	if (ret < 0)
 		return -EPIPE;
@@ -526,8 +526,8 @@ int omap4iss_pipeline_pm_use(struct media_entity *entity, int use)
 static int iss_pipeline_link_notify(struct media_link *link, u32 flags,
 				    unsigned int notification)
 {
-	struct media_entity *source = link->source->entity;
-	struct media_entity *sink = link->sink->entity;
+	struct media_entity *source = gobj_to_pad(link->source)->entity;
+	struct media_entity *sink = gobj_to_pad(link->sink)->entity;
 	int source_use = iss_pipeline_pm_use_count(source);
 	int sink_use = iss_pipeline_pm_use_count(sink);
 	int ret;
diff --git a/drivers/staging/media/omap4iss/iss_csi2.c b/drivers/staging/media/omap4iss/iss_csi2.c
index e936cfc218cb..47df6be236bc 100644
--- a/drivers/staging/media/omap4iss/iss_csi2.c
+++ b/drivers/staging/media/omap4iss/iss_csi2.c
@@ -1026,7 +1026,7 @@ static int csi2_link_validate(struct v4l2_subdev *sd, struct media_link *link,
 	struct iss_pipeline *pipe = to_iss_pipeline(&csi2->subdev.entity);
 	int rval;
 
-	pipe->external = media_entity_to_v4l2_subdev(link->source->entity);
+	pipe->external = media_entity_to_v4l2_subdev(gobj_to_pad(link->source)->entity);
 	rval = omap4iss_get_external_info(pipe, link);
 	if (rval < 0)
 		return rval;
diff --git a/include/media/media-entity.h b/include/media/media-entity.h
index 403019035424..f6e2136480f1 100644
--- a/include/media/media-entity.h
+++ b/include/media/media-entity.h
@@ -43,6 +43,17 @@ enum media_graph_type {
 	MEDIA_GRAPH_LINK,
 };
 
+/**
+ * enum media_graph_link_dir - direction of a link
+ *
+ * @MEDIA_LINK_DIR_BIDIRECTIONAL	Link is bidirectional
+ * @MEDIA_LINK_DIR_PAD_0_TO_1		Link is unidirectional,
+ *					from port 0 (source) to port 1 (sink)
+ */
+enum media_graph_link_dir {
+	MEDIA_LINK_DIR_BIDIRECTIONAL,
+	MEDIA_LINK_DIR_PORT0_TO_PORT1,
+};
 
 /* Structs to represent the objects that belong to a media graph */
 
@@ -72,9 +83,9 @@ struct media_pipeline {
 
 struct media_link {
 	struct list_head list;
-	struct media_graph_obj			graph_obj;
-	struct media_pad *source;	/* Source pad */
-	struct media_pad *sink;		/* Sink pad  */
+	struct media_graph_obj		graph_obj;
+	enum media_graph_link_dir	dir;
+	struct media_graph_obj		*source, *sink;
 	struct media_link *reverse;	/* Link in the reverse direction */
 	unsigned long flags;		/* Link flags (MEDIA_LNK_FL_*) */
 };
@@ -115,6 +126,11 @@ struct media_entity {
 	u32 group_id;			/* Entity group ID */
 
 	u16 num_pads;			/* Number of sink and source pads */
+
+	/*
+	 * Both num_links and num_backlinks are used only to report
+	 * the number of links via MEDIA_IOC_ENUM_ENTITIES at media_device.c
+	 */
 	u16 num_links;			/* Number of existing links, both
 					 * enabled and disabled */
 	u16 num_backlinks;		/* Number of backlinks */
@@ -171,6 +187,12 @@ struct media_entity_graph {
 #define gobj_to_entity(gobj) \
 		container_of(gobj, struct media_entity, graph_obj)
 
+#define gobj_to_link(gobj) \
+		container_of(gobj, struct media_link, graph_obj)
+
+#define gobj_to_pad(gobj) \
+		container_of(gobj, struct media_pad, graph_obj)
+
 void graph_obj_init(struct media_device *mdev,
 		    enum media_graph_type type,
 		    struct media_graph_obj *gobj);
-- 
2.4.3



From mchehab at osg.samsung.com  Tue Aug 11 05:09:16 2015
From: mchehab at osg.samsung.com (Mauro Carvalho Chehab)
Date: Tue, 11 Aug 2015 09:09:16 -0300
Subject: [PATCH RFC v2 10/16] media: rename the function that create pad links
In-Reply-To: <6d02794028ea4f7ad33e3ba0e07e0c690e2feee2.1439292977.git.mchehab@osg.samsung.com>
References: <cover.1438954897.git.mchehab@osg.samsung.com>
 <6d02794028ea4f7ad33e3ba0e07e0c690e2feee2.1439292977.git.mchehab@osg.samsung.com>
Message-ID: <84656f961ad8ffc424e984f93f828f21bd57576e.1439294756.git.mchehab@osg.samsung.com>

Now that a link can be either between two different graph
objects, we'll need to add more functions to create links.
So, rename the existing one that create links only between
two pads as media_create_pad_link().

No functional changes.

This patch was created via this shell script:
	for i in $(find drivers/media -name '*.[ch]' -type f) $(find drivers/staging/media -name '*.[ch]' -type f) $(find include/ -name '*.h' -type f) ; do sed s,media_entity_create_link,media_create_pad_link,g <$i >a && mv a $i; done

Signed-off-by: Mauro Carvalho Chehab <mchehab at osg.samsung.com>

diff --git a/drivers/media/dvb-core/dvbdev.c b/drivers/media/dvb-core/dvbdev.c
index 2fdcbb5f000a..65f59f2124b4 100644
--- a/drivers/media/dvb-core/dvbdev.c
+++ b/drivers/media/dvb-core/dvbdev.c
@@ -412,16 +412,16 @@ void dvb_create_media_graph(struct dvb_adapter *adap)
 	}
 
 	if (tuner && fe)
-		media_entity_create_link(tuner, 0, fe, 0, 0);
+		media_create_pad_link(tuner, 0, fe, 0, 0);
 
 	if (fe && demux)
-		media_entity_create_link(fe, 1, demux, 0, MEDIA_LNK_FL_ENABLED);
+		media_create_pad_link(fe, 1, demux, 0, MEDIA_LNK_FL_ENABLED);
 
 	if (demux && dvr)
-		media_entity_create_link(demux, 1, dvr, 0, MEDIA_LNK_FL_ENABLED);
+		media_create_pad_link(demux, 1, dvr, 0, MEDIA_LNK_FL_ENABLED);
 
 	if (demux && ca)
-		media_entity_create_link(demux, 1, ca, 0, MEDIA_LNK_FL_ENABLED);
+		media_create_pad_link(demux, 1, ca, 0, MEDIA_LNK_FL_ENABLED);
 }
 EXPORT_SYMBOL_GPL(dvb_create_media_graph);
 #endif
diff --git a/drivers/media/i2c/s5c73m3/s5c73m3-core.c b/drivers/media/i2c/s5c73m3/s5c73m3-core.c
index 6d167428727d..c81bfbfea32f 100644
--- a/drivers/media/i2c/s5c73m3/s5c73m3-core.c
+++ b/drivers/media/i2c/s5c73m3/s5c73m3-core.c
@@ -1482,11 +1482,11 @@ static int s5c73m3_oif_registered(struct v4l2_subdev *sd)
 		return ret;
 	}
 
-	ret = media_entity_create_link(&state->sensor_sd.entity,
+	ret = media_create_pad_link(&state->sensor_sd.entity,
 			S5C73M3_ISP_PAD, &state->oif_sd.entity, OIF_ISP_PAD,
 			MEDIA_LNK_FL_IMMUTABLE | MEDIA_LNK_FL_ENABLED);
 
-	ret = media_entity_create_link(&state->sensor_sd.entity,
+	ret = media_create_pad_link(&state->sensor_sd.entity,
 			S5C73M3_JPEG_PAD, &state->oif_sd.entity, OIF_JPEG_PAD,
 			MEDIA_LNK_FL_IMMUTABLE | MEDIA_LNK_FL_ENABLED);
 
diff --git a/drivers/media/i2c/s5k5baf.c b/drivers/media/i2c/s5k5baf.c
index 30a9ca62e034..d3bff30bcb6f 100644
--- a/drivers/media/i2c/s5k5baf.c
+++ b/drivers/media/i2c/s5k5baf.c
@@ -1756,7 +1756,7 @@ static int s5k5baf_registered(struct v4l2_subdev *sd)
 		v4l2_err(sd, "failed to register subdev %s\n",
 			 state->cis_sd.name);
 	else
-		ret = media_entity_create_link(&state->cis_sd.entity, PAD_CIS,
+		ret = media_create_pad_link(&state->cis_sd.entity, PAD_CIS,
 					       &state->sd.entity, PAD_CIS,
 					       MEDIA_LNK_FL_IMMUTABLE |
 					       MEDIA_LNK_FL_ENABLED);
diff --git a/drivers/media/i2c/smiapp/smiapp-core.c b/drivers/media/i2c/smiapp/smiapp-core.c
index 308613ea0aed..5aa49eb393a9 100644
--- a/drivers/media/i2c/smiapp/smiapp-core.c
+++ b/drivers/media/i2c/smiapp/smiapp-core.c
@@ -2495,7 +2495,7 @@ static int smiapp_register_subdevs(struct smiapp_sensor *sensor)
 			return rval;
 		}
 
-		rval = media_entity_create_link(&this->sd.entity,
+		rval = media_create_pad_link(&this->sd.entity,
 						this->source_pad,
 						&last->sd.entity,
 						last->sink_pad,
@@ -2503,7 +2503,7 @@ static int smiapp_register_subdevs(struct smiapp_sensor *sensor)
 						MEDIA_LNK_FL_IMMUTABLE);
 		if (rval) {
 			dev_err(&client->dev,
-				"media_entity_create_link failed\n");
+				"media_create_pad_link failed\n");
 			return rval;
 		}
 
diff --git a/drivers/media/media-entity.c b/drivers/media/media-entity.c
index c8bbf122f4a6..bdeb6e804c7e 100644
--- a/drivers/media/media-entity.c
+++ b/drivers/media/media-entity.c
@@ -481,7 +481,7 @@ static struct media_link *media_entity_add_link(struct media_entity *entity)
 }
 
 int
-media_entity_create_link(struct media_entity *source, u16 source_pad,
+media_create_pad_link(struct media_entity *source, u16 source_pad,
 			 struct media_entity *sink, u16 sink_pad, u32 flags)
 {
 	struct media_link *link;
@@ -519,7 +519,7 @@ media_entity_create_link(struct media_entity *source, u16 source_pad,
 
 	return 0;
 }
-EXPORT_SYMBOL_GPL(media_entity_create_link);
+EXPORT_SYMBOL_GPL(media_create_pad_link);
 
 static void __media_entity_remove_link(struct media_entity *entity,
 				       struct media_link *link)
diff --git a/drivers/media/platform/exynos4-is/media-dev.c b/drivers/media/platform/exynos4-is/media-dev.c
index f924148767ba..1be705fd3551 100644
--- a/drivers/media/platform/exynos4-is/media-dev.c
+++ b/drivers/media/platform/exynos4-is/media-dev.c
@@ -729,7 +729,7 @@ static int __fimc_md_create_fimc_sink_links(struct fimc_md *fmd,
 		flags = ((1 << i) & link_mask) ? MEDIA_LNK_FL_ENABLED : 0;
 
 		sink = &fmd->fimc[i]->vid_cap.subdev.entity;
-		ret = media_entity_create_link(source, pad, sink,
+		ret = media_create_pad_link(source, pad, sink,
 					      FIMC_SD_PAD_SINK_CAM, flags);
 		if (ret)
 			return ret;
@@ -749,7 +749,7 @@ static int __fimc_md_create_fimc_sink_links(struct fimc_md *fmd,
 			continue;
 
 		sink = &fmd->fimc_lite[i]->subdev.entity;
-		ret = media_entity_create_link(source, pad, sink,
+		ret = media_create_pad_link(source, pad, sink,
 					       FLITE_SD_PAD_SINK, 0);
 		if (ret)
 			return ret;
@@ -781,13 +781,13 @@ static int __fimc_md_create_flite_source_links(struct fimc_md *fmd)
 		source = &fimc->subdev.entity;
 		sink = &fimc->ve.vdev.entity;
 		/* FIMC-LITE's subdev and video node */
-		ret = media_entity_create_link(source, FLITE_SD_PAD_SOURCE_DMA,
+		ret = media_create_pad_link(source, FLITE_SD_PAD_SOURCE_DMA,
 					       sink, 0, 0);
 		if (ret)
 			break;
 		/* Link from FIMC-LITE to IS-ISP subdev */
 		sink = &fmd->fimc_is->isp.subdev.entity;
-		ret = media_entity_create_link(source, FLITE_SD_PAD_SOURCE_ISP,
+		ret = media_create_pad_link(source, FLITE_SD_PAD_SOURCE_ISP,
 					       sink, 0, 0);
 		if (ret)
 			break;
@@ -811,7 +811,7 @@ static int __fimc_md_create_fimc_is_links(struct fimc_md *fmd)
 
 		/* Link from FIMC-IS-ISP subdev to FIMC */
 		sink = &fmd->fimc[i]->vid_cap.subdev.entity;
-		ret = media_entity_create_link(source, FIMC_ISP_SD_PAD_SRC_FIFO,
+		ret = media_create_pad_link(source, FIMC_ISP_SD_PAD_SRC_FIFO,
 					       sink, FIMC_SD_PAD_SINK_FIFO, 0);
 		if (ret)
 			return ret;
@@ -824,7 +824,7 @@ static int __fimc_md_create_fimc_is_links(struct fimc_md *fmd)
 	if (sink->num_pads == 0)
 		return 0;
 
-	return media_entity_create_link(source, FIMC_ISP_SD_PAD_SRC_DMA,
+	return media_create_pad_link(source, FIMC_ISP_SD_PAD_SRC_DMA,
 					sink, 0, 0);
 }
 
@@ -873,7 +873,7 @@ static int fimc_md_create_links(struct fimc_md *fmd)
 				return -EINVAL;
 
 			pad = sensor->entity.num_pads - 1;
-			ret = media_entity_create_link(&sensor->entity, pad,
+			ret = media_create_pad_link(&sensor->entity, pad,
 					      &csis->entity, CSIS_PAD_SINK,
 					      MEDIA_LNK_FL_IMMUTABLE |
 					      MEDIA_LNK_FL_ENABLED);
@@ -927,7 +927,7 @@ static int fimc_md_create_links(struct fimc_md *fmd)
 		source = &fmd->fimc[i]->vid_cap.subdev.entity;
 		sink = &fmd->fimc[i]->vid_cap.ve.vdev.entity;
 
-		ret = media_entity_create_link(source, FIMC_SD_PAD_SOURCE,
+		ret = media_create_pad_link(source, FIMC_SD_PAD_SOURCE,
 					      sink, 0, flags);
 		if (ret)
 			break;
diff --git a/drivers/media/platform/omap3isp/isp.c b/drivers/media/platform/omap3isp/isp.c
index 7e2f4c9c0eef..b9e2a3b410dc 100644
--- a/drivers/media/platform/omap3isp/isp.c
+++ b/drivers/media/platform/omap3isp/isp.c
@@ -1905,7 +1905,7 @@ static int isp_link_entity(
 		return -EINVAL;
 	}
 
-	return media_entity_create_link(entity, i, input, pad, flags);
+	return media_create_pad_link(entity, i, input, pad, flags);
 }
 
 static int isp_register_entities(struct isp_device *isp)
@@ -2077,51 +2077,51 @@ static int isp_initialize_modules(struct isp_device *isp)
 	}
 
 	/* Connect the submodules. */
-	ret = media_entity_create_link(
+	ret = media_create_pad_link(
 			&isp->isp_csi2a.subdev.entity, CSI2_PAD_SOURCE,
 			&isp->isp_ccdc.subdev.entity, CCDC_PAD_SINK, 0);
 	if (ret < 0)
 		goto error_link;
 
-	ret = media_entity_create_link(
+	ret = media_create_pad_link(
 			&isp->isp_ccp2.subdev.entity, CCP2_PAD_SOURCE,
 			&isp->isp_ccdc.subdev.entity, CCDC_PAD_SINK, 0);
 	if (ret < 0)
 		goto error_link;
 
-	ret = media_entity_create_link(
+	ret = media_create_pad_link(
 			&isp->isp_ccdc.subdev.entity, CCDC_PAD_SOURCE_VP,
 			&isp->isp_prev.subdev.entity, PREV_PAD_SINK, 0);
 	if (ret < 0)
 		goto error_link;
 
-	ret = media_entity_create_link(
+	ret = media_create_pad_link(
 			&isp->isp_ccdc.subdev.entity, CCDC_PAD_SOURCE_OF,
 			&isp->isp_res.subdev.entity, RESZ_PAD_SINK, 0);
 	if (ret < 0)
 		goto error_link;
 
-	ret = media_entity_create_link(
+	ret = media_create_pad_link(
 			&isp->isp_prev.subdev.entity, PREV_PAD_SOURCE,
 			&isp->isp_res.subdev.entity, RESZ_PAD_SINK, 0);
 	if (ret < 0)
 		goto error_link;
 
-	ret = media_entity_create_link(
+	ret = media_create_pad_link(
 			&isp->isp_ccdc.subdev.entity, CCDC_PAD_SOURCE_VP,
 			&isp->isp_aewb.subdev.entity, 0,
 			MEDIA_LNK_FL_ENABLED | MEDIA_LNK_FL_IMMUTABLE);
 	if (ret < 0)
 		goto error_link;
 
-	ret = media_entity_create_link(
+	ret = media_create_pad_link(
 			&isp->isp_ccdc.subdev.entity, CCDC_PAD_SOURCE_VP,
 			&isp->isp_af.subdev.entity, 0,
 			MEDIA_LNK_FL_ENABLED | MEDIA_LNK_FL_IMMUTABLE);
 	if (ret < 0)
 		goto error_link;
 
-	ret = media_entity_create_link(
+	ret = media_create_pad_link(
 			&isp->isp_ccdc.subdev.entity, CCDC_PAD_SOURCE_VP,
 			&isp->isp_hist.subdev.entity, 0,
 			MEDIA_LNK_FL_ENABLED | MEDIA_LNK_FL_IMMUTABLE);
diff --git a/drivers/media/platform/omap3isp/ispccdc.c b/drivers/media/platform/omap3isp/ispccdc.c
index f01b540d1841..cb694c095be1 100644
--- a/drivers/media/platform/omap3isp/ispccdc.c
+++ b/drivers/media/platform/omap3isp/ispccdc.c
@@ -2667,7 +2667,7 @@ static int ccdc_init_entities(struct isp_ccdc_device *ccdc)
 		goto error_video;
 
 	/* Connect the CCDC subdev to the video node. */
-	ret = media_entity_create_link(&ccdc->subdev.entity, CCDC_PAD_SOURCE_OF,
+	ret = media_create_pad_link(&ccdc->subdev.entity, CCDC_PAD_SOURCE_OF,
 			&ccdc->video_out.video.entity, 0, 0);
 	if (ret < 0)
 		goto error_link;
diff --git a/drivers/media/platform/omap3isp/ispccp2.c b/drivers/media/platform/omap3isp/ispccp2.c
index e1b5f5bea541..b215eb5049d6 100644
--- a/drivers/media/platform/omap3isp/ispccp2.c
+++ b/drivers/media/platform/omap3isp/ispccp2.c
@@ -1100,7 +1100,7 @@ static int ccp2_init_entities(struct isp_ccp2_device *ccp2)
 		goto error_video;
 
 	/* Connect the video node to the ccp2 subdev. */
-	ret = media_entity_create_link(&ccp2->video_in.video.entity, 0,
+	ret = media_create_pad_link(&ccp2->video_in.video.entity, 0,
 				       &ccp2->subdev.entity, CCP2_PAD_SINK, 0);
 	if (ret < 0)
 		goto error_link;
diff --git a/drivers/media/platform/omap3isp/ispcsi2.c b/drivers/media/platform/omap3isp/ispcsi2.c
index 6fff92f0813a..fcefc1e74881 100644
--- a/drivers/media/platform/omap3isp/ispcsi2.c
+++ b/drivers/media/platform/omap3isp/ispcsi2.c
@@ -1265,7 +1265,7 @@ static int csi2_init_entities(struct isp_csi2_device *csi2)
 		goto error_video;
 
 	/* Connect the CSI2 subdev to the video node. */
-	ret = media_entity_create_link(&csi2->subdev.entity, CSI2_PAD_SOURCE,
+	ret = media_create_pad_link(&csi2->subdev.entity, CSI2_PAD_SOURCE,
 				       &csi2->video_out.video.entity, 0, 0);
 	if (ret < 0)
 		goto error_link;
diff --git a/drivers/media/platform/omap3isp/isppreview.c b/drivers/media/platform/omap3isp/isppreview.c
index b440c6342ca4..ad38d20c7770 100644
--- a/drivers/media/platform/omap3isp/isppreview.c
+++ b/drivers/media/platform/omap3isp/isppreview.c
@@ -2312,12 +2312,12 @@ static int preview_init_entities(struct isp_prev_device *prev)
 		goto error_video_out;
 
 	/* Connect the video nodes to the previewer subdev. */
-	ret = media_entity_create_link(&prev->video_in.video.entity, 0,
+	ret = media_create_pad_link(&prev->video_in.video.entity, 0,
 			&prev->subdev.entity, PREV_PAD_SINK, 0);
 	if (ret < 0)
 		goto error_link;
 
-	ret = media_entity_create_link(&prev->subdev.entity, PREV_PAD_SOURCE,
+	ret = media_create_pad_link(&prev->subdev.entity, PREV_PAD_SOURCE,
 			&prev->video_out.video.entity, 0, 0);
 	if (ret < 0)
 		goto error_link;
diff --git a/drivers/media/platform/omap3isp/ispresizer.c b/drivers/media/platform/omap3isp/ispresizer.c
index 3deb1ec4a973..b48ad4d4b834 100644
--- a/drivers/media/platform/omap3isp/ispresizer.c
+++ b/drivers/media/platform/omap3isp/ispresizer.c
@@ -1756,12 +1756,12 @@ static int resizer_init_entities(struct isp_res_device *res)
 	res->video_out.video.entity.flags |= MEDIA_ENT_FL_DEFAULT;
 
 	/* Connect the video nodes to the resizer subdev. */
-	ret = media_entity_create_link(&res->video_in.video.entity, 0,
+	ret = media_create_pad_link(&res->video_in.video.entity, 0,
 			&res->subdev.entity, RESZ_PAD_SINK, 0);
 	if (ret < 0)
 		goto error_link;
 
-	ret = media_entity_create_link(&res->subdev.entity, RESZ_PAD_SOURCE,
+	ret = media_create_pad_link(&res->subdev.entity, RESZ_PAD_SOURCE,
 			&res->video_out.video.entity, 0, 0);
 	if (ret < 0)
 		goto error_link;
diff --git a/drivers/media/platform/s3c-camif/camif-core.c b/drivers/media/platform/s3c-camif/camif-core.c
index f47b332f0418..3e33c60be004 100644
--- a/drivers/media/platform/s3c-camif/camif-core.c
+++ b/drivers/media/platform/s3c-camif/camif-core.c
@@ -263,7 +263,7 @@ static int camif_create_media_links(struct camif_dev *camif)
 {
 	int i, ret;
 
-	ret = media_entity_create_link(&camif->sensor.sd->entity, 0,
+	ret = media_create_pad_link(&camif->sensor.sd->entity, 0,
 				&camif->subdev.entity, CAMIF_SD_PAD_SINK,
 				MEDIA_LNK_FL_IMMUTABLE |
 				MEDIA_LNK_FL_ENABLED);
@@ -271,7 +271,7 @@ static int camif_create_media_links(struct camif_dev *camif)
 		return ret;
 
 	for (i = 1; i < CAMIF_SD_PADS_NUM && !ret; i++) {
-		ret = media_entity_create_link(&camif->subdev.entity, i,
+		ret = media_create_pad_link(&camif->subdev.entity, i,
 				&camif->vp[i - 1].vdev.entity, 0,
 				MEDIA_LNK_FL_IMMUTABLE |
 				MEDIA_LNK_FL_ENABLED);
diff --git a/drivers/media/platform/vsp1/vsp1_drv.c b/drivers/media/platform/vsp1/vsp1_drv.c
index 4e61886384e3..9cd94a76a9ed 100644
--- a/drivers/media/platform/vsp1/vsp1_drv.c
+++ b/drivers/media/platform/vsp1/vsp1_drv.c
@@ -101,7 +101,7 @@ static int vsp1_create_links(struct vsp1_device *vsp1, struct vsp1_entity *sink)
 			if (!(entity->pads[pad].flags & MEDIA_PAD_FL_SINK))
 				continue;
 
-			ret = media_entity_create_link(&source->subdev.entity,
+			ret = media_create_pad_link(&source->subdev.entity,
 						       source->source_pad,
 						       entity, pad, flags);
 			if (ret < 0)
@@ -262,7 +262,7 @@ static int vsp1_create_entities(struct vsp1_device *vsp1)
 	}
 
 	if (vsp1->pdata.features & VSP1_HAS_LIF) {
-		ret = media_entity_create_link(
+		ret = media_create_pad_link(
 			&vsp1->wpf[0]->entity.subdev.entity, RWPF_PAD_SOURCE,
 			&vsp1->lif->entity.subdev.entity, LIF_PAD_SINK, 0);
 		if (ret < 0)
diff --git a/drivers/media/platform/vsp1/vsp1_rpf.c b/drivers/media/platform/vsp1/vsp1_rpf.c
index 3294529a3108..b60a528a8fe8 100644
--- a/drivers/media/platform/vsp1/vsp1_rpf.c
+++ b/drivers/media/platform/vsp1/vsp1_rpf.c
@@ -278,7 +278,7 @@ struct vsp1_rwpf *vsp1_rpf_create(struct vsp1_device *vsp1, unsigned int index)
 	rpf->entity.video = video;
 
 	/* Connect the video device to the RPF. */
-	ret = media_entity_create_link(&rpf->video.video.entity, 0,
+	ret = media_create_pad_link(&rpf->video.video.entity, 0,
 				       &rpf->entity.subdev.entity,
 				       RWPF_PAD_SINK,
 				       MEDIA_LNK_FL_ENABLED |
diff --git a/drivers/media/platform/vsp1/vsp1_wpf.c b/drivers/media/platform/vsp1/vsp1_wpf.c
index 1d2b3a2f1573..d39aa4b8aea1 100644
--- a/drivers/media/platform/vsp1/vsp1_wpf.c
+++ b/drivers/media/platform/vsp1/vsp1_wpf.c
@@ -284,7 +284,7 @@ struct vsp1_rwpf *vsp1_wpf_create(struct vsp1_device *vsp1, unsigned int index)
 	if (!(vsp1->pdata.features & VSP1_HAS_LIF) || index != 0)
 		flags |= MEDIA_LNK_FL_IMMUTABLE;
 
-	ret = media_entity_create_link(&wpf->entity.subdev.entity,
+	ret = media_create_pad_link(&wpf->entity.subdev.entity,
 				       RWPF_PAD_SOURCE,
 				       &wpf->video.video.entity, 0, flags);
 	if (ret < 0)
diff --git a/drivers/media/platform/xilinx/xilinx-vipp.c b/drivers/media/platform/xilinx/xilinx-vipp.c
index 7b7cb9c28d2c..79d4be7ce9a5 100644
--- a/drivers/media/platform/xilinx/xilinx-vipp.c
+++ b/drivers/media/platform/xilinx/xilinx-vipp.c
@@ -156,7 +156,7 @@ static int xvip_graph_build_one(struct xvip_composite_device *xdev,
 			local->name, local_pad->index,
 			remote->name, remote_pad->index);
 
-		ret = media_entity_create_link(local, local_pad->index,
+		ret = media_create_pad_link(local, local_pad->index,
 					       remote, remote_pad->index,
 					       link_flags);
 		if (ret < 0) {
@@ -270,7 +270,7 @@ static int xvip_graph_build_dma(struct xvip_composite_device *xdev)
 			source->name, source_pad->index,
 			sink->name, sink_pad->index);
 
-		ret = media_entity_create_link(source, source_pad->index,
+		ret = media_create_pad_link(source, source_pad->index,
 					       sink, sink_pad->index,
 					       link_flags);
 		if (ret < 0) {
diff --git a/drivers/media/usb/cx231xx/cx231xx-cards.c b/drivers/media/usb/cx231xx/cx231xx-cards.c
index 4a117a58c39a..3b5c9ae39ad3 100644
--- a/drivers/media/usb/cx231xx/cx231xx-cards.c
+++ b/drivers/media/usb/cx231xx/cx231xx-cards.c
@@ -1264,11 +1264,11 @@ static void cx231xx_create_media_graph(struct cx231xx *dev)
 		return;
 
 	if (tuner)
-		media_entity_create_link(tuner, 0, decoder, 0,
+		media_create_pad_link(tuner, 0, decoder, 0,
 					 MEDIA_LNK_FL_ENABLED);
-	media_entity_create_link(decoder, 1, &dev->vdev.entity, 0,
+	media_create_pad_link(decoder, 1, &dev->vdev.entity, 0,
 				 MEDIA_LNK_FL_ENABLED);
-	media_entity_create_link(decoder, 2, &dev->vbi_dev.entity, 0,
+	media_create_pad_link(decoder, 2, &dev->vbi_dev.entity, 0,
 				 MEDIA_LNK_FL_ENABLED);
 #endif
 }
diff --git a/drivers/media/usb/uvc/uvc_entity.c b/drivers/media/usb/uvc/uvc_entity.c
index 245445491516..429e428ccd93 100644
--- a/drivers/media/usb/uvc/uvc_entity.c
+++ b/drivers/media/usb/uvc/uvc_entity.c
@@ -56,7 +56,7 @@ static int uvc_mc_register_entity(struct uvc_video_chain *chain,
 			continue;
 
 		remote_pad = remote->num_pads - 1;
-		ret = media_entity_create_link(source, remote_pad,
+		ret = media_create_pad_link(source, remote_pad,
 					       sink, i, flags);
 		if (ret < 0)
 			return ret;
diff --git a/drivers/staging/media/davinci_vpfe/dm365_ipipeif.c b/drivers/staging/media/davinci_vpfe/dm365_ipipeif.c
index 8fb676186898..d96bdaaae50e 100644
--- a/drivers/staging/media/davinci_vpfe/dm365_ipipeif.c
+++ b/drivers/staging/media/davinci_vpfe/dm365_ipipeif.c
@@ -971,7 +971,7 @@ vpfe_ipipeif_register_entities(struct vpfe_ipipeif_device *ipipeif,
 	ipipeif->video_in.vpfe_dev = vpfe_dev;
 
 	flags = 0;
-	ret = media_entity_create_link(&ipipeif->video_in.video_dev.entity, 0,
+	ret = media_create_pad_link(&ipipeif->video_in.video_dev.entity, 0,
 					&ipipeif->subdev.entity, 0, flags);
 	if (ret < 0)
 		goto fail;
diff --git a/drivers/staging/media/davinci_vpfe/dm365_isif.c b/drivers/staging/media/davinci_vpfe/dm365_isif.c
index b1f01adfa7c8..df77288b0ec0 100644
--- a/drivers/staging/media/davinci_vpfe/dm365_isif.c
+++ b/drivers/staging/media/davinci_vpfe/dm365_isif.c
@@ -1817,7 +1817,7 @@ int vpfe_isif_register_entities(struct vpfe_isif_device *isif,
 	isif->video_out.vpfe_dev = vpfe_dev;
 	flags = 0;
 	/* connect isif to video node */
-	ret = media_entity_create_link(&isif->subdev.entity, 1,
+	ret = media_create_pad_link(&isif->subdev.entity, 1,
 				       &isif->video_out.video_dev.entity,
 				       0, flags);
 	if (ret < 0)
diff --git a/drivers/staging/media/davinci_vpfe/dm365_resizer.c b/drivers/staging/media/davinci_vpfe/dm365_resizer.c
index 692789aa22f4..ae942de3a23d 100644
--- a/drivers/staging/media/davinci_vpfe/dm365_resizer.c
+++ b/drivers/staging/media/davinci_vpfe/dm365_resizer.c
@@ -1831,27 +1831,27 @@ int vpfe_resizer_register_entities(struct vpfe_resizer_device *resizer,
 	resizer->resizer_b.video_out.vpfe_dev = vpfe_dev;
 
 	/* create link between Resizer Crop----> Resizer A*/
-	ret = media_entity_create_link(&resizer->crop_resizer.subdev.entity, 1,
+	ret = media_create_pad_link(&resizer->crop_resizer.subdev.entity, 1,
 				&resizer->resizer_a.subdev.entity,
 				0, flags);
 	if (ret < 0)
 		goto out_create_link;
 
 	/* create link between Resizer Crop----> Resizer B*/
-	ret = media_entity_create_link(&resizer->crop_resizer.subdev.entity, 2,
+	ret = media_create_pad_link(&resizer->crop_resizer.subdev.entity, 2,
 				&resizer->resizer_b.subdev.entity,
 				0, flags);
 	if (ret < 0)
 		goto out_create_link;
 
 	/* create link between Resizer A ----> video out */
-	ret = media_entity_create_link(&resizer->resizer_a.subdev.entity, 1,
+	ret = media_create_pad_link(&resizer->resizer_a.subdev.entity, 1,
 		&resizer->resizer_a.video_out.video_dev.entity, 0, flags);
 	if (ret < 0)
 		goto out_create_link;
 
 	/* create link between Resizer B ----> video out */
-	ret = media_entity_create_link(&resizer->resizer_b.subdev.entity, 1,
+	ret = media_create_pad_link(&resizer->resizer_b.subdev.entity, 1,
 		&resizer->resizer_b.video_out.video_dev.entity, 0, flags);
 	if (ret < 0)
 		goto out_create_link;
diff --git a/drivers/staging/media/davinci_vpfe/vpfe_mc_capture.c b/drivers/staging/media/davinci_vpfe/vpfe_mc_capture.c
index 57426199ad7a..08c8a5f967d3 100644
--- a/drivers/staging/media/davinci_vpfe/vpfe_mc_capture.c
+++ b/drivers/staging/media/davinci_vpfe/vpfe_mc_capture.c
@@ -445,32 +445,32 @@ static int vpfe_register_entities(struct vpfe_device *vpfe_dev)
 		/* if entity has no pads (ex: amplifier),
 		   cant establish link */
 		if (vpfe_dev->sd[i]->entity.num_pads) {
-			ret = media_entity_create_link(&vpfe_dev->sd[i]->entity,
+			ret = media_create_pad_link(&vpfe_dev->sd[i]->entity,
 				0, &vpfe_dev->vpfe_isif.subdev.entity,
 				0, flags);
 			if (ret < 0)
 				goto out_resizer_register;
 		}
 
-	ret = media_entity_create_link(&vpfe_dev->vpfe_isif.subdev.entity, 1,
+	ret = media_create_pad_link(&vpfe_dev->vpfe_isif.subdev.entity, 1,
 				       &vpfe_dev->vpfe_ipipeif.subdev.entity,
 				       0, flags);
 	if (ret < 0)
 		goto out_resizer_register;
 
-	ret = media_entity_create_link(&vpfe_dev->vpfe_ipipeif.subdev.entity, 1,
+	ret = media_create_pad_link(&vpfe_dev->vpfe_ipipeif.subdev.entity, 1,
 				       &vpfe_dev->vpfe_ipipe.subdev.entity,
 				       0, flags);
 	if (ret < 0)
 		goto out_resizer_register;
 
-	ret = media_entity_create_link(&vpfe_dev->vpfe_ipipe.subdev.entity,
+	ret = media_create_pad_link(&vpfe_dev->vpfe_ipipe.subdev.entity,
 			1, &vpfe_dev->vpfe_resizer.crop_resizer.subdev.entity,
 			0, flags);
 	if (ret < 0)
 		goto out_resizer_register;
 
-	ret = media_entity_create_link(&vpfe_dev->vpfe_ipipeif.subdev.entity, 1,
+	ret = media_create_pad_link(&vpfe_dev->vpfe_ipipeif.subdev.entity, 1,
 			&vpfe_dev->vpfe_resizer.crop_resizer.subdev.entity,
 			0, flags);
 	if (ret < 0)
diff --git a/drivers/staging/media/omap4iss/iss.c b/drivers/staging/media/omap4iss/iss.c
index 5556ffbd7619..617918e35d61 100644
--- a/drivers/staging/media/omap4iss/iss.c
+++ b/drivers/staging/media/omap4iss/iss.c
@@ -1259,7 +1259,7 @@ static int iss_register_entities(struct iss_device *iss)
 			goto done;
 		}
 
-		ret = media_entity_create_link(&sensor->entity, 0, input, pad,
+		ret = media_create_pad_link(&sensor->entity, 0, input, pad,
 					       flags);
 		if (ret < 0)
 			goto done;
@@ -1317,31 +1317,31 @@ static int iss_initialize_modules(struct iss_device *iss)
 	}
 
 	/* Connect the submodules. */
-	ret = media_entity_create_link(
+	ret = media_create_pad_link(
 			&iss->csi2a.subdev.entity, CSI2_PAD_SOURCE,
 			&iss->ipipeif.subdev.entity, IPIPEIF_PAD_SINK, 0);
 	if (ret < 0)
 		goto error_link;
 
-	ret = media_entity_create_link(
+	ret = media_create_pad_link(
 			&iss->csi2b.subdev.entity, CSI2_PAD_SOURCE,
 			&iss->ipipeif.subdev.entity, IPIPEIF_PAD_SINK, 0);
 	if (ret < 0)
 		goto error_link;
 
-	ret = media_entity_create_link(
+	ret = media_create_pad_link(
 			&iss->ipipeif.subdev.entity, IPIPEIF_PAD_SOURCE_VP,
 			&iss->resizer.subdev.entity, RESIZER_PAD_SINK, 0);
 	if (ret < 0)
 		goto error_link;
 
-	ret = media_entity_create_link(
+	ret = media_create_pad_link(
 			&iss->ipipeif.subdev.entity, IPIPEIF_PAD_SOURCE_VP,
 			&iss->ipipe.subdev.entity, IPIPE_PAD_SINK, 0);
 	if (ret < 0)
 		goto error_link;
 
-	ret = media_entity_create_link(
+	ret = media_create_pad_link(
 			&iss->ipipe.subdev.entity, IPIPE_PAD_SOURCE_VP,
 			&iss->resizer.subdev.entity, RESIZER_PAD_SINK, 0);
 	if (ret < 0)
diff --git a/drivers/staging/media/omap4iss/iss_csi2.c b/drivers/staging/media/omap4iss/iss_csi2.c
index 47df6be236bc..bcdaec07a43a 100644
--- a/drivers/staging/media/omap4iss/iss_csi2.c
+++ b/drivers/staging/media/omap4iss/iss_csi2.c
@@ -1291,7 +1291,7 @@ static int csi2_init_entities(struct iss_csi2_device *csi2, const char *subname)
 		goto error_video;
 
 	/* Connect the CSI2 subdev to the video node. */
-	ret = media_entity_create_link(&csi2->subdev.entity, CSI2_PAD_SOURCE,
+	ret = media_create_pad_link(&csi2->subdev.entity, CSI2_PAD_SOURCE,
 				       &csi2->video_out.video.entity, 0, 0);
 	if (ret < 0)
 		goto error_link;
diff --git a/drivers/staging/media/omap4iss/iss_ipipeif.c b/drivers/staging/media/omap4iss/iss_ipipeif.c
index be5f80d7b5dc..44c432ef2ac5 100644
--- a/drivers/staging/media/omap4iss/iss_ipipeif.c
+++ b/drivers/staging/media/omap4iss/iss_ipipeif.c
@@ -762,7 +762,7 @@ static int ipipeif_init_entities(struct iss_ipipeif_device *ipipeif)
 		return ret;
 
 	/* Connect the IPIPEIF subdev to the video node. */
-	ret = media_entity_create_link(&ipipeif->subdev.entity,
+	ret = media_create_pad_link(&ipipeif->subdev.entity,
 				       IPIPEIF_PAD_SOURCE_ISIF_SF,
 				       &ipipeif->video_out.video.entity, 0, 0);
 	if (ret < 0)
diff --git a/drivers/staging/media/omap4iss/iss_resizer.c b/drivers/staging/media/omap4iss/iss_resizer.c
index 91e724085dba..b659e465cb56 100644
--- a/drivers/staging/media/omap4iss/iss_resizer.c
+++ b/drivers/staging/media/omap4iss/iss_resizer.c
@@ -806,7 +806,7 @@ static int resizer_init_entities(struct iss_resizer_device *resizer)
 		return ret;
 
 	/* Connect the RESIZER subdev to the video node. */
-	ret = media_entity_create_link(&resizer->subdev.entity,
+	ret = media_create_pad_link(&resizer->subdev.entity,
 				       RESIZER_PAD_SOURCE_MEM,
 				       &resizer->video_out.video.entity, 0, 0);
 	if (ret < 0)
diff --git a/include/media/media-entity.h b/include/media/media-entity.h
index f6e2136480f1..75fe769e4d85 100644
--- a/include/media/media-entity.h
+++ b/include/media/media-entity.h
@@ -202,7 +202,7 @@ int media_entity_init(struct media_entity *entity, u16 num_pads,
 		      struct media_pad *pads);
 void media_entity_cleanup(struct media_entity *entity);
 
-int media_entity_create_link(struct media_entity *source, u16 source_pad,
+int media_create_pad_link(struct media_entity *source, u16 source_pad,
 		struct media_entity *sink, u16 sink_pad, u32 flags);
 void __media_entity_remove_links(struct media_entity *entity);
 void media_entity_remove_links(struct media_entity *entity);
-- 
2.4.3



From grygorii.strashko at ti.com  Tue Aug 11 05:16:13 2015
From: grygorii.strashko at ti.com (Grygorii Strashko)
Date: Tue, 11 Aug 2015 15:16:13 +0300
Subject: [PATCH] ARM: OMAP: irqdomain_hierarchy: fix arm gic irq type
 configuration
In-Reply-To: <20150811122456.1efe1656@arm.com>
References: <1439285147-20027-1-git-send-email-grygorii.strashko@ti.com>
 <20150811122456.1efe1656@arm.com>
Message-ID: <55C9E78D.7040404@ti.com>

On 08/11/2015 02:24 PM, Marc Zyngier wrote:
> On Tue, 11 Aug 2015 10:25:47 +0100
> Grygorii Strashko <grygorii.strashko at ti.com> wrote:
>
> Hi Grygorii,
>
>> It's observed that ARM GIC IRQ triggering type is not configured
>> properly when IRQ is routed through IRQ domains hierarchy and
>> system started using DT. As result, system will start using default
>> ARM GIC configuration, ignore DT IRQ type configuration,
>> and value of desc->irq_data.state_use_accessors = 0.
>>
>> In case of TI OMAP the following IRQ hierarchy is defined:
>> ARM GIC <- OMAP wakeupgen <- TI CBAR
>>
>> Failed call chain:
>>   irq_create_of_mapping
>>   irq_set_irq_type
>>   __irq_set_trigger
>>   if (!chip || !chip->irq_set_type) {
>>      return 0; <- return here
>>   }
>>   CBAR has no .irq_set_type() defined and, so, IRQ triggering
>>   configuration will not be propagated to parent IRQ domain.
>>
>> Hence, fix it by introducing irq_chip_set_type_parent(), in the
>> same manner as irq_chip_set_wake_parent(), and use it for IRQ
>> triggering type propagation to the parent IRQ domain in
>> irq-crossbar and omap-wakeupgen.
>>
>> / # cat /proc/interrupts -- before
>> 230:          0          0      CBAR  30 Edge    -00000000  48051000.gpio
>> 263:          0          0      CBAR 116 Edge    -00000000  48053000.gpio
>> 296:        246          0      CBAR  67 Edge    -00000000  OMAP UART0
>> 311:        341          0      CBAR  51 Edge    -00000000  48070000.i2c
>> 312:          3          0      CBAR  52 Edge    -00000000  48072000.i2c
>> 313:          0          0      CBAR  56 Edge    -00000000  48060000.i2c
>> 314:        255          0      CBAR  78 Edge    -00000000  mmc0
>> 315:         40          0      CBAR  81 Edge    -00000000  mmc1
>> 316:         13          0      CBAR  91 Edge    -00000000  mmc2
>> 320:          0          0      CBAR  49 Edge    -00000000  4a140000.sata
>> 324:          0          0      CBAR   1 Edge    -00000000  48078000.elm
>> 325:          0          0      CBAR  15 Edge    -00000000  gpmc
>> 333:          0          0      CBAR 335 Edge    -00000000  48484000.ethernet
>> 334:          0          0      CBAR 336 Edge    -00000000  48484000.ethernet
>> 415:          0          0   pcf857x   2 Edge    -00000000  btnUser1
>> 416:          0          0   pcf857x   3 Edge    -00000000  btnUser2
>> 445:          0          0   pinctrl 992 Edge    -00010000  4806a000.seria
>>
>> / # cat /proc/interrupts -- after
>> 230:          0          0      CBAR  30 Level   -00002004  48051000.gpio
>> 263:          0          0      CBAR 116 Level   -00002004  48053000.gpio
>> 296:        567          0      CBAR  67 Level   -00002004  OMAP UART0
>> 311:        363          0      CBAR  51 Level   -00002004  48070000.i2c
>> 312:          3          0      CBAR  52 Level   -00002004  48072000.i2c
>> 313:          0          0      CBAR  56 Level   -00002004  48060000.i2c
>> 314:        197          0      CBAR  78 Level   -00002004  mmc0
>> 315:         40          0      CBAR  81 Level   -00002004  mmc1
>> 316:         13          0      CBAR  91 Level   -00002004  mmc2
>> 320:          0          0      CBAR  49 Level   -00002004  4a140000.sata
>> 324:          0          0      CBAR   1 Level   -00002004  48078000.elm
>> 325:          0          0      CBAR  15 Level   -00002004  gpmc
>> 333:          0          0      CBAR 335 Level   -00002004  48484000.ethernet
>> 334:          0          0      CBAR 336 Level   -00002004  48484000.ethernet
>> 415:          0          0   pcf857x   2 Edge    -00000000  btnUser1
>> 416:          4          2   pcf857x   3 Edge    -00000000  btnUser2
>> 445:          0          0   pinctrl 992 Edge    -00010000  4806a000.serial
>>
>> Fixes: 783d31863fb8 ('irqchip: crossbar: Convert dra7 crossbar to stacked domains')
>> Signed-off-by: Grygorii Strashko <grygorii.strashko at ti.com>
>> ---
>> Hi All,
>>
>> I can split patch if required and overall solution acceptable.
>
> This looks good to me. Please repost it after splitting it in two
> patches.

just to clarify - Do you want to see two or three patches?

2) or 3) arch/arm/mach-omap2/omap-wakeupgen.c |  1 +
2) drivers/irqchip/irq-crossbar.c       |  1 +
1) include/linux/irq.h                  |  1 +
1) kernel/irq/chip.c                    | 16 ++++++++++++++++



-- 
regards,
-grygorii


From oliver+list at schinagl.nl  Tue Aug 11 05:16:52 2015
From: oliver+list at schinagl.nl (Olliver Schinagl)
Date: Tue, 11 Aug 2015 14:16:52 +0200
Subject: ARM: sunxi: Experiences NAND flash
Message-ID: <55C9E7B4.9090906@schinagl.nl>

Hello everybody,

We are working with Boris and Roy's patch series on getting the NAND 
flash chip working on Olimex OLinuXino Lime2 boards. Initially, 
everything looks fine, but we noticed that occasionally (after 
power/cycle or power cut) ubi fails to mount the partition. It is not 
something easily enough to reproduce, but it has failed on 5 boards out 
of 30 we have.

U-boot reports the following:
UBI: default fastmap pool size: 100
UBI: default fastmap WL pool size: 25
UBI: attaching mtd1 to ubi0
UBI: scanning is finished
UBI init error 22
Error reading superblock on volume 'ubi:boot' errno=-19!
ubifsmount - mount UBIFS volume

whereas the linux kernel booted from sd card gives:
ubiattach /dev/ubi_ctrl -m 0
[  100.560704] ubi0: default fastmap pool size: 8
[  100.565186] ubi0: default fastmap WL pool size: 4
[  100.570100] ubi0: attaching mtd0
[  100.590469] ubi0: scanning is finished
[  100.594732] ubi0 error: ubi_read_volume_table: the layout volume was 
not found
[  100.602675] ubi0 error: ubi_attach_mtd_dev: failed to attach mtd0, 
error -22
ubiattach: error!: cannot attach mtd0
            error 22 (Invalid argument)

The u-boot version we are using is a few months out of date
U-Boot 2015.07-rc2-g2540c39 (Aug 04 2015 - 16:09:02 +0200) Allwinner 
Technology
arm-none-eabi-gcc (4.8.4-1+11-1) 4.8.4 20141219 (release)
GNU ld (2.25-5+5+b1) 2.25

but the kernel is fairly up to date:
4.2.0-rc4-opinicus-g8ec3671


Now I know that the mtd stuff is all very new and all very untested, 
what I am curious about is a) have other people actually tried the mtd 
stuff on Allwinner hardware, and b) has anybody encountered this issue 
as well?

It's not something very easily reproducible (toggling a machine on/off 
repeatedly did not trigger it yet) but it does happen.

Olliver


From nicolas.pitre at linaro.org  Tue Aug 11 05:16:34 2015
From: nicolas.pitre at linaro.org (Nicolas Pitre)
Date: Tue, 11 Aug 2015 08:16:34 -0400 (EDT)
Subject: [PATCH v3] ARM: appropriate __init annotation for const data
In-Reply-To: <20150811094512.GY7557@n2100.arm.linux.org.uk>
References: <alpine.LFD.2.20.1507271750160.1806@knanqh.ubzr>
 <20150811094512.GY7557@n2100.arm.linux.org.uk>
Message-ID: <alpine.LFD.2.20.1508110813130.1515@knanqh.ubzr>

On Tue, 11 Aug 2015, Russell King - ARM Linux wrote:

> On Mon, Jul 27, 2015 at 06:27:52PM -0400, Nicolas Pitre wrote:
> > Init data marked const should be annotated with __initconst for
> > correctness and not __initdata.  In some cases the array gathering
> > references to that data has to be marked const as well. This fixes
> > LTO builds that otherwise fail with section mismatch errors.
> > 
> > Signed-off-by: Nicolas Pitre <nico at linaro.org>
> 
> Can we please get a little smarter at splitting up changes between core
> ARM code and SoC ARM code please.
> 
> This now causes a delete/modify conflict between my tree and arm-soc,
> because I'm now carrying ARMs patches which move arch/arm/kernel/psci.c
> to drivers/firmware.

This is the only occurrence in the core code so it slipped through.  
Sorry about that.

> Right now, my resolution for that conflict is to just delete the old
> file, I'm not even checking to see whether the new one needs this
> change applied.  If it does, please submit a change on top of my
> tree.

No problem.


Nicolas


From hansverk at cisco.com  Tue Aug 11 05:25:18 2015
From: hansverk at cisco.com (Hans Verkuil)
Date: Tue, 11 Aug 2015 14:25:18 +0200
Subject: [PATCH RFC v2 09/16] media: use media_graph_obj for link endpoints
In-Reply-To: <6d02794028ea4f7ad33e3ba0e07e0c690e2feee2.1439292977.git.mchehab@osg.samsung.com>
References: <cover.1439292977.git.mchehab@osg.samsung.com>
 <6d02794028ea4f7ad33e3ba0e07e0c690e2feee2.1439292977.git.mchehab@osg.samsung.com>
Message-ID: <55C9E9AE.5020602@cisco.com>

Hi Mauro,

Thanks for posting the missing patches.

On 08/11/15 14:09, Mauro Carvalho Chehab wrote:
> As we'll need to create links between entities and interfaces,
> we need to identify the link endpoints by the media_graph_obj.
> 
> Most of the changes here was done by this small script:
> 
> for i in `find drivers/media -type f` `find drivers/staging/media -type f`; do
> 	perl -ne 's,([\w]+)\-\>(source|sink)\-\>entity,gobj_to_pad($1->$2)->entity,; print $_;' <$i >a && mv a $i
> done
> 
> Please note that, while we're now using graph_obj to reference
> the link endpoints, we're still assuming that all endpoints are
> pads. This is true for all existing links, so no problems
> are expected so far.
> 
> Yet, as we introduce links between entities and interfaces,
> we may need to change some existing code to work with links
> that aren't pad to pad.
> 
> Signed-off-by: Mauro Carvalho Chehab <mchehab at osg.samsung.com>
> 

<snip>

> diff --git a/include/media/media-entity.h b/include/media/media-entity.h
> index 403019035424..f6e2136480f1 100644
> --- a/include/media/media-entity.h
> +++ b/include/media/media-entity.h
> @@ -43,6 +43,17 @@ enum media_graph_type {
>  	MEDIA_GRAPH_LINK,
>  };
>  
> +/**
> + * enum media_graph_link_dir - direction of a link
> + *
> + * @MEDIA_LINK_DIR_BIDIRECTIONAL	Link is bidirectional
> + * @MEDIA_LINK_DIR_PAD_0_TO_1		Link is unidirectional,
> + *					from port 0 (source) to port 1 (sink)
> + */
> +enum media_graph_link_dir {
> +	MEDIA_LINK_DIR_BIDIRECTIONAL,
> +	MEDIA_LINK_DIR_PORT0_TO_PORT1,
> +};

1) the comment and the actual enum are out-of-sync
2) why not just make a 'BIRECTIONAL' link flag instead of inventing
   a new enum? Adding yet another field seems overkill to me. Have a
   'BIDIRECTIONAL' flag seems perfectly OK to me (and useful for the
   application as well).

>  
>  /* Structs to represent the objects that belong to a media graph */
>  
> @@ -72,9 +83,9 @@ struct media_pipeline {
>  
>  struct media_link {
>  	struct list_head list;
> -	struct media_graph_obj			graph_obj;
> -	struct media_pad *source;	/* Source pad */
> -	struct media_pad *sink;		/* Sink pad  */
> +	struct media_graph_obj		graph_obj;
> +	enum media_graph_link_dir	dir;
> +	struct media_graph_obj		*source, *sink;

I'm not too keen about all the gobj_to_foo(obj) macros that this requires. It
is rather ugly code.

What about this:

	union {
		struct media_graph_obj *source;
		struct media_pad *source_pad;
		struct media_interface *source_intf;
	};
	union {
		struct media_graph_obj *sink;
		struct media_pad *sink_pad;
		struct media_entity *sink_ent;
	};

Now the code can just use ->source_pad etc.

>  	struct media_link *reverse;	/* Link in the reverse direction */
>  	unsigned long flags;		/* Link flags (MEDIA_LNK_FL_*) */
>  };
> @@ -115,6 +126,11 @@ struct media_entity {
>  	u32 group_id;			/* Entity group ID */
>  
>  	u16 num_pads;			/* Number of sink and source pads */
> +
> +	/*
> +	 * Both num_links and num_backlinks are used only to report
> +	 * the number of links via MEDIA_IOC_ENUM_ENTITIES at media_device.c
> +	 */
>  	u16 num_links;			/* Number of existing links, both
>  					 * enabled and disabled */
>  	u16 num_backlinks;		/* Number of backlinks */
> @@ -171,6 +187,12 @@ struct media_entity_graph {
>  #define gobj_to_entity(gobj) \
>  		container_of(gobj, struct media_entity, graph_obj)
>  
> +#define gobj_to_link(gobj) \
> +		container_of(gobj, struct media_link, graph_obj)
> +
> +#define gobj_to_pad(gobj) \
> +		container_of(gobj, struct media_pad, graph_obj)
> +

I saw a lot of type checks (if (link->sink.type != MEDIA_GRAPH_PAD))
that I think would look cleaner if there was a simple static inline
helper:

static inline bool is_pad(const struct media_graph_obj *obj)
{
	return obj->type == MEDIA_GRAPH_PAD;
}

media_is_pad() will work as well, but I think brevity is more useful
in this case. Personal opinion, though.

>  void graph_obj_init(struct media_device *mdev,
>  		    enum media_graph_type type,
>  		    struct media_graph_obj *gobj);
> 

Regards,

	Hans


From djkurtz at chromium.org  Tue Aug 11 05:37:36 2015
From: djkurtz at chromium.org (Daniel Kurtz)
Date: Tue, 11 Aug 2015 20:37:36 +0800
Subject: [PATCH v5 3/3] arm64: dts: Add spi bus dts
In-Reply-To: <1438931991-17044-4-git-send-email-leilk.liu@mediatek.com>
References: <1438931991-17044-1-git-send-email-leilk.liu@mediatek.com>
 <1438931991-17044-4-git-send-email-leilk.liu@mediatek.com>
Message-ID: <CAGS+omA0dabyGkCB2JYORn1CjXvgMs_3x7nqSOOJKMg4HRhCSg@mail.gmail.com>

On Fri, Aug 7, 2015 at 3:19 PM, Leilk Liu <leilk.liu at mediatek.com> wrote:
> This patch adds MT8173 spi bus controllers into device tree.
>
> Signed-off-by: Leilk Liu <leilk.liu at mediatek.com>
> ---
> Change in this patch:
> 1. "pad-select" is a vendor property, so change it to "mediatek,pad-select".
> 2. modify the property of clocks and clock-names.
> ---
>  arch/arm64/boot/dts/mediatek/mt8173.dtsi | 23 +++++++++++++++++++++++
>  1 file changed, 23 insertions(+)
>
> diff --git a/arch/arm64/boot/dts/mediatek/mt8173.dtsi b/arch/arm64/boot/dts/mediatek/mt8173.dtsi
> index d18ee42..066bd6a 100644
> --- a/arch/arm64/boot/dts/mediatek/mt8173.dtsi
> +++ b/arch/arm64/boot/dts/mediatek/mt8173.dtsi
> @@ -220,6 +220,15 @@
>                                         bias-disable;
>                                 };
>                         };
> +
> +                       spi_pins_a: spi0 {
> +                               pins_spi {
> +                                       pinmux = <MT8173_PIN_69_SPI_CK__FUNC_SPI_CK_0_>,
> +                                               <MT8173_PIN_70_SPI_MI__FUNC_SPI_MI_0_>,
> +                                               <MT8173_PIN_71_SPI_MO__FUNC_SPI_MO_0_>,
> +                                               <MT8173_PIN_72_SPI_CS__FUNC_SPI_CS_0_>;
> +                               };
> +                       };
>                 };
>
>                 scpsys: scpsys at 10006000 {
> @@ -365,6 +374,20 @@
>                         status = "disabled";
>                 };
>
> +               spi: spi at 1100a000 {
> +                       compatible = "mediatek,mt8173-spi";
> +                       #address-cells = <1>;
> +                       #size-cells = <0>;
> +                       reg = <0 0x1100a000 0 0x1000>;
> +                       interrupts = <GIC_SPI 110 IRQ_TYPE_LEVEL_LOW>;
> +                       clocks = <&topckgen CLK_TOP_SPI_SEL>, <&topckgen CLK_TOP_SYSPLL3_D2>;
> +                       clock-names = "spi-clk", "parent-clk";
> +                       pinctrl-names = "default";
> +                       pinctrl-0 = <&spi_pins_a>;
> +                       mediatek,pad-select = <0>;

The pinctl and pad-select fields are board specific.
Please move to mt8173-evb.dtsi, along with status = "okay";

> +                       status = "disabled";
> +               };
> +
>                 i2c3: i2c3 at 11010000 {
>                         compatible = "mediatek,mt8173-i2c";
>                         reg = <0 0x11010000 0 0x70>,
> --
> 1.8.1.1.dirty
>
> --
> To unsubscribe from this list: send the line "unsubscribe linux-kernel" in
> the body of a message to majordomo at vger.kernel.org
> More majordomo info at  http://vger.kernel.org/majordomo-info.html
> Please read the FAQ at  http://www.tux.org/lkml/


From linux at arm.linux.org.uk  Tue Aug 11 05:40:43 2015
From: linux at arm.linux.org.uk (Russell King - ARM Linux)
Date: Tue, 11 Aug 2015 13:40:43 +0100
Subject: earlycon issues in -next with amba-pl011 updates
In-Reply-To: <55C94247.8020701@hurleysoftware.com>
References: <20150810232312.GB10728@bivouac.eciton.net>
 <55C94247.8020701@hurleysoftware.com>
Message-ID: <20150811124043.GZ7557@n2100.arm.linux.org.uk>

On Mon, Aug 10, 2015 at 08:31:03PM -0400, Peter Hurley wrote:
> diff --git a/drivers/tty/serial/amba-pl011.c b/drivers/tty/serial/amba-pl011.c
> index 2af09ab..fd54991 100644
> --- a/drivers/tty/serial/amba-pl011.c
> +++ b/drivers/tty/serial/amba-pl011.c
> @@ -2348,13 +2348,10 @@ static struct console amba_console = {
>  
>  static void pl011_putc(struct uart_port *port, int c)
>  {
> -	struct uart_amba_port *uap =
> -	    container_of(port, struct uart_amba_port, port);
> -
> -	while (pl011_readw(uap, REG_FR) & UART01x_FR_TXFF)
> +	while (readl(port->membase + UART01x_FR) & UART01x_FR_TXFF)
>  		;
> -	pl011_writeb(uap, c, REG_DR);
> -	while (pl011_readw(uap, REG_FR) & uap->fr_busy)
> +	writeb(c, port->membase + UART01x_DR);
> +	while (readl(port->membase + UART01x_FR) & UART01x_FR_BUSY)
>  		;

These loops are wrong.  Kernel coding style is that loops like this
will use cpu_relax() in them, just like the driver used to.  This
was introduced by:

commit 0d3c673e7881e691991b2a4745bd4f149603baa2
Author: Rob Herring <robh at kernel.org>
Date:   Fri Apr 18 17:19:57 2014 -0500

    tty/serial: pl011: add generic earlycon support

Also, the above readl()s should be readl_relaxed(), we don't need
barriered reads or to hit the L2 cache on those reads in the above code.

-- 
FTTC broadband for 0.8mile line: currently at 10.5Mbps down 400kbps up
according to speedtest.net.


From linus.walleij at linaro.org  Tue Aug 11 05:53:30 2015
From: linus.walleij at linaro.org (Linus Walleij)
Date: Tue, 11 Aug 2015 14:53:30 +0200
Subject: [PATCH 0/2] drivers: PL061: Add platform driver probing support
In-Reply-To: <20150807022141.GD25067@kroah.com>
References: <1438585198-8764-1-git-send-email-zhaoshenglong@huawei.com>
 <20150803075848.GH7557@n2100.arm.linux.org.uk>
 <55BF33AD.5040502@huawei.com>
 <20150803094923.GI7557@n2100.arm.linux.org.uk>
 <20150803162623.GB30867@kroah.com>
 <20150803190935.GL7557@n2100.arm.linux.org.uk>
 <20150807022141.GD25067@kroah.com>
Message-ID: <CACRpkdYd_oWsx23h4-Hjk8rqcgnuMqd47SEg+4ubtR08jgQY9g@mail.gmail.com>

On Fri, Aug 7, 2015 at 4:21 AM, Greg Kroah-Hartman
<gregkh at linuxfoundation.org> wrote:
> On Mon, Aug 03, 2015 at 08:09:35PM +0100, Russell King - ARM Linux wrote:

>> Right now, there seems to be a move to convert _all_ AMBA device drivers
>> to become dual-drivers: an amba bus driver and a platform driver.  Is
>> that something you really want to see, irrespective of ACPI issues?
>
> Ick, no, I don't think that's wise at all.  Why not just make the needed
> resources availble to _all_ bus drivers, then it doesn't matter if it's
> AMBA, or ACPI, or USB, or anything else?

Amen to that.

> I thought that is what some recent patches did to the acpi/of core, but
> maybe I was mistaken.

I think you're referring to the initiative to provide query functions that will
work the same on device trees and ACPI devices, that is to get a key/value
from a certain struct device * no matter if it came from a DT or ACPI.

This is about how the core hardware description spawns devices. While
DT will (correctly) spawn AMBA devices, the ACPI code apparently
doesn't. But it should. of_amba_device_create() even shows exactly
how to do it.

What I fear is that ACPI actually has no way to tell whether a device is
an AMBA device but rather thinks the whole world consists of
platform_devices, and then *THAT* needs to be fixed.

Yours,
Linus Walleij


From olof at lixom.net  Tue Aug 11 05:39:28 2015
From: olof at lixom.net (Olof Johansson)
Date: Tue, 11 Aug 2015 14:39:28 +0200
Subject: [GIT PULL 1/5] Samsung non-critical-fixes for v4.3
In-Reply-To: <55C06995.2030600@kernel.org>
References: <55C06995.2030600@kernel.org>
Message-ID: <20150811123928.GA24495@localhost>

On Tue, Aug 04, 2015 at 04:28:21PM +0900, Kukjin Kim wrote:
> Hi Arnd, Olof, Kevin,
> 
> Here is Samsung non-critical-fixes for v4.3.
> Please pull.
> 
> Thanks,
> Kukjin
> 
> The following changes since commit d770e558e21961ad6cfdf0ff7df0eb5d7d4f0754:
> 
>   Linux 4.2-rc1 (2015-07-05 11:01:52 -0700)
> 
> are available in the git repository at:
> 
>   git://git.kernel.org/pub/scm/linux/kernel/git/kgene/linux-samsung.git
> tags/samsung-non-critical-1


Merged, thanks.


-Olof


From olof at lixom.net  Tue Aug 11 05:55:27 2015
From: olof at lixom.net (Olof Johansson)
Date: Tue, 11 Aug 2015 14:55:27 +0200
Subject: [GIT PULL v2] Renesas ARM Based SoC Marzen Board Removal for v4.3
In-Reply-To: <20150811082105.GX7557@n2100.arm.linux.org.uk>
References: <cover.1438581659.git.horms+renesas@verge.net.au>
 <20150806081000.GA16520@localhost>
 <20150807012847.GF1145@verge.net.au>
 <20150811082105.GX7557@n2100.arm.linux.org.uk>
Message-ID: <20150811125527.GB24495@localhost>

On Tue, Aug 11, 2015 at 09:21:05AM +0100, Russell King - ARM Linux wrote:
> On Fri, Aug 07, 2015 at 10:28:47AM +0900, Simon Horman wrote:
> > diff --git a/arch/arm/mach-shmobile/Makefile b/arch/arm/mach-shmobile/Makefile
> > index 8d1e0b6ac2a2..476de30798d7 100644
> > --- a/arch/arm/mach-shmobile/Makefile
> > +++ b/arch/arm/mach-shmobile/Makefile
> > @@ -53,6 +53,7 @@ obj-$(CONFIG_ARCH_RCAR_GEN2)	+= pm-rcar-gen2.o
> >  ifndef CONFIG_ARCH_SHMOBILE_MULTI
> >  obj-$(CONFIG_MACH_BOCKW)	+= board-bockw.o
> >  obj-$(CONFIG_MACH_BOCKW_REFERENCE)	+= board-bockw-reference.o
> > +endif
> >  
> >  # Framework support
> >  obj-$(CONFIG_SMP)		+= $(smp-y)
> 
> What's happening to get this fixed?
> 
> arch/arm/mach-shmobile/Makefile:59: *** missing 'endif'.  Stop.
> Makefile:949: recipe for target 'arch/arm/mach-shmobile' failed
> make[1]: *** [arch/arm/mach-shmobile] Error 2

I've fixed up and pushed out for-next now. Will keep an eye on the build
results in a bit.


-Olof


From geert at linux-m68k.org  Tue Aug 11 06:07:52 2015
From: geert at linux-m68k.org (Geert Uytterhoeven)
Date: Tue, 11 Aug 2015 15:07:52 +0200
Subject: [PATCH 5/9] ARM: common: Introduce PM domains for CPUs/clusters
In-Reply-To: <7hd1yyvf1b.fsf@deeprootsystems.com>
References: <1438731339-58317-1-git-send-email-lina.iyer@linaro.org>
 <1438731339-58317-6-git-send-email-lina.iyer@linaro.org>
 <CAL_JsqK67=DTtjZwwnonObLDjLbahkREfm0RvyXVV95bhR-d4Q@mail.gmail.com>
 <7hd1yyvf1b.fsf@deeprootsystems.com>
Message-ID: <CAMuHMdWRoUOBvz7MEGgF1oHz95D-GhaYG1yHr_kGe5NUQ0EnrQ@mail.gmail.com>

On Sat, Aug 8, 2015 at 1:45 AM, Kevin Hilman <khilman at kernel.org> wrote:
> Rob Herring <robherring2 at gmail.com> writes:
>> On Tue, Aug 4, 2015 at 6:35 PM, Lina Iyer <lina.iyer at linaro.org> wrote:
>>> +ARM CPU Power domains
>>> +
>>> +The device tree allows describing of CPU power domains in a SoC. In ARM SoC,
>>> +CPUs may be grouped as clusters. A cluster may have CPUs, GIC, Coresight,
>>> +caches, VFP and power controller and other peripheral hardware. Generally,
>>> +when the CPUs in the cluster are idle/suspended, the shared resources may also
>>> +be suspended and resumed before any of the CPUs resume execution.
>>> +
>>> +CPUs are the defined as the PM domain consumers and there is a PM domain
>>> +provider for the CPUs. Bindings for generic PM domains (genpd) is described in
>>> +[1].
>>> +
>>> +The ARM CPU PM domain follows the same binding convention as any generic PM
>>> +domain. Additional binding properties are -
>>> +
>>> +- compatible:
>>> +       Usage: required
>>> +       Value type: <string>
>>> +       Definition: Must also have
>>> +                       "arm,pd"
>>> +               inorder to initialize the genpd provider as ARM CPU PM domain.
>>
>> A compatible string should represent a particular h/w block. If it is
>> generic, it should represent some sort of standard programming
>> interface (e.g, AHCI, EHCI, etc.). This doesn't seem to be either and
>> is rather just a mapping of what "driver" you want to use.
>>
>> I would expect that identifying a cpu's or cluster's power domain
>> would be done by a phandle between the cpu/cluster node and power
>> domain node.
>
> That's correct, the CPU nodes (and other nodes in the cluster like GIC,
> Coresight, etc.) would have phandles to the cluster power domain node.

Indeed.

> But this series is meant to create the driver & binding for those cluster
> power domain(s), so the question is how exactly describe it.

I don't think I can add an "arm,pd" compatible property to e.g. a2sl
(for CA15-CPUx) and a3sm (for CA15-SCU) in arch/arm/boot/dts/r8a73a4.dtsi,
as these are just subdomains in a power domain hierarchy, all driven by a
single hardware block.

I can call e.g. a special registration method, or set up some ops pointer,
for the a2sl and a3sm subdomains from within the "renesas,sysc-rmobile"
driver.

Gr{oetje,eeting}s,

                        Geert

--
Geert Uytterhoeven -- There's lots of Linux beyond ia32 -- geert at linux-m68k.org

In personal conversations with technical people, I call myself a hacker. But
when I'm talking to journalists I just say "programmer" or something like that.
                                -- Linus Torvalds


From geert at linux-m68k.org  Tue Aug 11 06:11:29 2015
From: geert at linux-m68k.org (Geert Uytterhoeven)
Date: Tue, 11 Aug 2015 15:11:29 +0200
Subject: [GIT PULL v2] Renesas ARM Based SoC Marzen Board Removal for v4.3
In-Reply-To: <20150811125527.GB24495@localhost>
References: <cover.1438581659.git.horms+renesas@verge.net.au>
 <20150806081000.GA16520@localhost>
 <20150807012847.GF1145@verge.net.au>
 <20150811082105.GX7557@n2100.arm.linux.org.uk>
 <20150811125527.GB24495@localhost>
Message-ID: <CAMuHMdVioBOnJNu3FvmwjB2mJ_3rqv595qak6TZG-GaOEj3sfQ@mail.gmail.com>

Hi Olof,

On Tue, Aug 11, 2015 at 2:55 PM, Olof Johansson <olof at lixom.net> wrote:
> On Tue, Aug 11, 2015 at 09:21:05AM +0100, Russell King - ARM Linux wrote:
>> On Fri, Aug 07, 2015 at 10:28:47AM +0900, Simon Horman wrote:
>> > diff --git a/arch/arm/mach-shmobile/Makefile b/arch/arm/mach-shmobile/Makefile
>> > index 8d1e0b6ac2a2..476de30798d7 100644
>> > --- a/arch/arm/mach-shmobile/Makefile
>> > +++ b/arch/arm/mach-shmobile/Makefile
>> > @@ -53,6 +53,7 @@ obj-$(CONFIG_ARCH_RCAR_GEN2)      += pm-rcar-gen2.o
>> >  ifndef CONFIG_ARCH_SHMOBILE_MULTI
>> >  obj-$(CONFIG_MACH_BOCKW)   += board-bockw.o
>> >  obj-$(CONFIG_MACH_BOCKW_REFERENCE) += board-bockw-reference.o
>> > +endif
>> >
>> >  # Framework support
>> >  obj-$(CONFIG_SMP)          += $(smp-y)
>>
>> What's happening to get this fixed?
>>
>> arch/arm/mach-shmobile/Makefile:59: *** missing 'endif'.  Stop.
>> Makefile:949: recipe for target 'arch/arm/mach-shmobile' failed
>> make[1]: *** [arch/arm/mach-shmobile] Error 2
>
> I've fixed up and pushed out for-next now. Will keep an eye on the build
> results in a bit.

Thank you, that looks fine to me.

Gr{oetje,eeting}s,

                        Geert

--
Geert Uytterhoeven -- There's lots of Linux beyond ia32 -- geert at linux-m68k.org

In personal conversations with technical people, I call myself a hacker. But
when I'm talking to journalists I just say "programmer" or something like that.
                                -- Linus Torvalds


From mchehab at osg.samsung.com  Tue Aug 11 06:22:01 2015
From: mchehab at osg.samsung.com (Mauro Carvalho Chehab)
Date: Tue, 11 Aug 2015 10:22:01 -0300
Subject: [PATCH RFC v2 09/16] media: use media_graph_obj for link endpoints
In-Reply-To: <55C9E9AE.5020602@cisco.com>
References: <cover.1439292977.git.mchehab@osg.samsung.com>
 <6d02794028ea4f7ad33e3ba0e07e0c690e2feee2.1439292977.git.mchehab@osg.samsung.com>
 <55C9E9AE.5020602@cisco.com>
Message-ID: <20150811102201.5abaf64d@recife.lan>

Em Tue, 11 Aug 2015 14:25:18 +0200
Hans Verkuil <hansverk at cisco.com> escreveu:

> Hi Mauro,
> 
> Thanks for posting the missing patches.

Thanks for reviewing this patch series!

> 
> On 08/11/15 14:09, Mauro Carvalho Chehab wrote:
> > As we'll need to create links between entities and interfaces,
> > we need to identify the link endpoints by the media_graph_obj.
> > 
> > Most of the changes here was done by this small script:
> > 
> > for i in `find drivers/media -type f` `find drivers/staging/media -type f`; do
> > 	perl -ne 's,([\w]+)\-\>(source|sink)\-\>entity,gobj_to_pad($1->$2)->entity,; print $_;' <$i >a && mv a $i
> > done
> > 
> > Please note that, while we're now using graph_obj to reference
> > the link endpoints, we're still assuming that all endpoints are
> > pads. This is true for all existing links, so no problems
> > are expected so far.
> > 
> > Yet, as we introduce links between entities and interfaces,
> > we may need to change some existing code to work with links
> > that aren't pad to pad.
> > 
> > Signed-off-by: Mauro Carvalho Chehab <mchehab at osg.samsung.com>
> > 
> 
> <snip>
> 
> > diff --git a/include/media/media-entity.h b/include/media/media-entity.h
> > index 403019035424..f6e2136480f1 100644
> > --- a/include/media/media-entity.h
> > +++ b/include/media/media-entity.h
> > @@ -43,6 +43,17 @@ enum media_graph_type {
> >  	MEDIA_GRAPH_LINK,
> >  };
> >  
> > +/**
> > + * enum media_graph_link_dir - direction of a link
> > + *
> > + * @MEDIA_LINK_DIR_BIDIRECTIONAL	Link is bidirectional
> > + * @MEDIA_LINK_DIR_PAD_0_TO_1		Link is unidirectional,
> > + *					from port 0 (source) to port 1 (sink)
> > + */
> > +enum media_graph_link_dir {
> > +	MEDIA_LINK_DIR_BIDIRECTIONAL,
> > +	MEDIA_LINK_DIR_PORT0_TO_PORT1,
> > +};
> 
> 1) the comment and the actual enum are out-of-sync

Ah, yes. I was in doubt about using PAD or PORT here. I ended by using
port at the links, as the endpoints can either be an interface/entity
or a pad. So, I decided to use port.

> 2) why not just make a 'BIRECTIONAL' link flag instead of inventing
>    a new enum? Adding yet another field seems overkill to me. Have a
>    'BIDIRECTIONAL' flag seems perfectly OK to me (and useful for the
>    application as well).

Yeah, we can use flags, instead. I decided to use an enum here just
to make it clearer about the two possible options.

I was actually considering to rename media_link source/sink to
port0/port1, as using "source"/"sink" names on a bidirection link
doesn't make sense. I'm still in doubt about such rename, though,
as it would make harder to inspect the graph traversal routines.

Also, I want to force all places that create a link to choose
between either BIRECTIONAL or PORT0_TO_PORT1, as this makes easier
to review if the code is doing the right thing when inspecting it.

In summary, I would prefer to keep this internally as a separate
 enum, at least for now. We can latter simplify it and use a flag
for that (or maybe two flags?).

> 
> >  
> >  /* Structs to represent the objects that belong to a media graph */
> >  
> > @@ -72,9 +83,9 @@ struct media_pipeline {
> >  
> >  struct media_link {
> >  	struct list_head list;
> > -	struct media_graph_obj			graph_obj;
> > -	struct media_pad *source;	/* Source pad */
> > -	struct media_pad *sink;		/* Sink pad  */
> > +	struct media_graph_obj		graph_obj;
> > +	enum media_graph_link_dir	dir;
> > +	struct media_graph_obj		*source, *sink;
> 
> I'm not too keen about all the gobj_to_foo(obj) macros that this requires. It
> is rather ugly code.
> 
> What about this:
> 
> 	union {
> 		struct media_graph_obj *source;
> 		struct media_pad *source_pad;
> 		struct media_interface *source_intf;
> 	};
> 	union {
> 		struct media_graph_obj *sink;
> 		struct media_pad *sink_pad;
> 		struct media_entity *sink_ent;
> 	};
> 
> Now the code can just use ->source_pad etc.

good idea. Will do that on a version 3. I think that, in this case, the
best is to write a note that the first element at pad/entity/interface
should be the graph_obj.

I would actually call port0_intf and port1_ent on the above structs,
as it makes no sense to call sink/source for interface->entity links.

> >  	struct media_link *reverse;	/* Link in the reverse direction */
> >  	unsigned long flags;		/* Link flags (MEDIA_LNK_FL_*) */
> >  };
> > @@ -115,6 +126,11 @@ struct media_entity {
> >  	u32 group_id;			/* Entity group ID */
> >  
> >  	u16 num_pads;			/* Number of sink and source pads */
> > +
> > +	/*
> > +	 * Both num_links and num_backlinks are used only to report
> > +	 * the number of links via MEDIA_IOC_ENUM_ENTITIES at media_device.c
> > +	 */
> >  	u16 num_links;			/* Number of existing links, both
> >  					 * enabled and disabled */
> >  	u16 num_backlinks;		/* Number of backlinks */
> > @@ -171,6 +187,12 @@ struct media_entity_graph {
> >  #define gobj_to_entity(gobj) \
> >  		container_of(gobj, struct media_entity, graph_obj)
> >  
> > +#define gobj_to_link(gobj) \
> > +		container_of(gobj, struct media_link, graph_obj)
> > +
> > +#define gobj_to_pad(gobj) \
> > +		container_of(gobj, struct media_pad, graph_obj)
> > +
> 
> I saw a lot of type checks (if (link->sink.type != MEDIA_GRAPH_PAD))
> that I think would look cleaner if there was a simple static inline
> helper:
> 
> static inline bool is_pad(const struct media_graph_obj *obj)
> {
> 	return obj->type == MEDIA_GRAPH_PAD;
> }
> 
> media_is_pad() will work as well, but I think brevity is more useful
> in this case. Personal opinion, though.

I would use media_is_pad() instead, to avoid namespace conflicts. We may
eventually need other inline functions for other types in the future.

> 
> >  void graph_obj_init(struct media_device *mdev,
> >  		    enum media_graph_type type,
> >  		    struct media_graph_obj *gobj);
> > 
> 
> Regards,
> 
> 	Hans


From daniel.lezcano at linaro.org  Tue Aug 11 06:27:11 2015
From: daniel.lezcano at linaro.org (Daniel Lezcano)
Date: Tue, 11 Aug 2015 15:27:11 +0200
Subject: [PATCH v3 2/4] clocksource: atmel-st: get and use slow clock
In-Reply-To: <1439285884-16051-3-git-send-email-alexandre.belloni@free-electrons.com>
References: <1439285884-16051-1-git-send-email-alexandre.belloni@free-electrons.com>
 <1439285884-16051-3-git-send-email-alexandre.belloni@free-electrons.com>
Message-ID: <55C9F82F.1000400@linaro.org>

On 08/11/2015 11:38 AM, Alexandre Belloni wrote:
> The current slow clock rate is hardcoded. Properly get the slow clock
> and use its rate.
>
> Signed-off-by: Alexandre Belloni <alexandre.belloni at free-electrons.com>

Acked-by: Daniel Lezcano <daniel.lezcano at linaro.org>

-- 
  <http://www.linaro.org/> Linaro.org ? Open source software for ARM SoCs

Follow Linaro:  <http://www.facebook.com/pages/Linaro> Facebook |
<http://twitter.com/#!/linaroorg> Twitter |
<http://www.linaro.org/linaro-blog/> Blog



From daniel.lezcano at linaro.org  Tue Aug 11 06:27:45 2015
From: daniel.lezcano at linaro.org (Daniel Lezcano)
Date: Tue, 11 Aug 2015 15:27:45 +0200
Subject: [PATCH v3 3/4] clocksource: tcb_clksrc: fix setup_clkevents error
 path
In-Reply-To: <1439285884-16051-4-git-send-email-alexandre.belloni@free-electrons.com>
References: <1439285884-16051-1-git-send-email-alexandre.belloni@free-electrons.com>
 <1439285884-16051-4-git-send-email-alexandre.belloni@free-electrons.com>
Message-ID: <55C9F851.1000204@linaro.org>

On 08/11/2015 11:38 AM, Alexandre Belloni wrote:
> From: Boris Brezillon <boris.brezillon at free-electrons.com>
>
> t2_clk is already disabled before request_irq(), it must not be disabled
> again.
>
> Signed-off-by: Boris Brezillon <boris.brezillon at free-electrons.com>
> Signed-off-by: Alexandre Belloni <alexandre.belloni at free-electrons.com>
> ---

Acked-by: Daniel Lezcano <daniel.lezcano at linaro.org>


-- 
  <http://www.linaro.org/> Linaro.org ? Open source software for ARM SoCs

Follow Linaro:  <http://www.facebook.com/pages/Linaro> Facebook |
<http://twitter.com/#!/linaroorg> Twitter |
<http://www.linaro.org/linaro-blog/> Blog



From lee.jones at linaro.org  Tue Aug 11 06:27:57 2015
From: lee.jones at linaro.org (Lee Jones)
Date: Tue, 11 Aug 2015 14:27:57 +0100
Subject: [PATCH v4 2/2] dt: power: st: Provide bindings for ST's OPPs
In-Reply-To: <20150811120124.GH5509@linux>
References: <20150730084634.GD9319@x1>
 <CAL_JsqKQLQ15qSt95zBZykzzPhcUrtZzhk29a76n+r_3719AiA@mail.gmail.com>
 <20150731163715.GV3159@codeaurora.org> <20150803034642.GV899@linux>
 <20150810132247.GH3249@x1> <20150811080023.GB5509@linux>
 <20150811093039.GA18282@x1> <20150811100941.GG5509@linux>
 <20150811115425.GE18282@x1> <20150811120124.GH5509@linux>
Message-ID: <20150811132756.GG18282@x1>

On Tue, 11 Aug 2015, Viresh Kumar wrote:
> On 11-08-15, 12:54, Lee Jones wrote:
> > The framework does not need to parse this information.  It is used
> > solely by the platform driver, whose job it is to decide which OPPs
> > are appropriate for the running platform.
> 
> The OPP layer needs to parse OPP nodes in DT. But for doing that it
> needs to know which OPPs to pick from the table as, in cases like
> yours or qcom, not all OPPs might be available.
> 
> One of the ways to do that is:
> - the platform reads its efuses (or whatever) and encodes the
>   information into a string.
> - This string should match with the strings present (somewhere) in the
>   OPP table. That location can be like what I proposed few mails back.
> - Then the *generic* OPP code can parse only those OPP nodes which
>   match with that string.
> 
> This way, we can avoid pushing the platform code to parse OPP tables.

Okay, so what you're saying is that you've already made the decision
to create a separate node for every OPP permutation, despite the fact
that I've told you this could lead to more nodes than anyone would
care to successfully write or maintain?

Perhaps an example might help explain the issue.

Using the current driver, we need to place the following in DT and the
driver does the rest:

opp-list {
	opp1 {
		opp-hz = <1500000000>;
		st,avs = <1200 1200 1200 1200 1170 1140 1100 1070>;
		st,substrate = <0xff>;
		st,cuts = <0xff>;
	};
	opp0 {
		opp-hz = <1200000000>;
		st,avs = <1110 1150 1100 1080 1040 1020 980 930>;
		st,substrate = <0xff>;
		st,cuts = <0x2>;
	};
};

However, what you're suggesting, even for this very simple example
(imagine what this would look like with 5 or more frequencies where
two or more of them were only appropriate to run on particular
variants) requires this to be broken out to:

opp-list {
	pcode0-cut2-allsubstrates {
		opp0 {
			opp-hz = <1200000000>;
			opp-microvolt = <1110000>;
		};
	};

	pcode0-allcuts-allsubstrates {
		opp0 {
			opp-hz = <1500000000>;
			opp-microvolt = <1200000>;
		};
	};

	pcode1-cut2-allsubstrates {
		opp0 {
			opp-hz = <1200000000>;
			opp-microvolt = <1150000>;
		};
	};

	pcode1-allcuts-allsubstrates {
		opp0 {
			opp-hz = <1500000000>;
			opp-microvolt = <1200000>;
		};
	};

	pcode2-cut2-allsubstrates {
		opp0 {
			opp-hz = <1200000000>;
			opp-microvolt = <1100000>;
		};
	};

	pcode2-allcuts-allsubstrates {
		opp0 {
			opp-hz = <1500000000>;
			opp-microvolt = <1200000>;
		};
	};

	pcode3-cut2-allsubstrates {
		opp0 {
			opp-hz = <1200000000>;
			opp-microvolt = <1080000>;
		};
	};

	pcode3-allcuts-allsubstrates {
		opp0 {
			opp-hz = <1500000000>;
			opp-microvolt = <1200000>;
		};
	};

	pcode4-cut2-allsubstrates {
		opp0 {
			opp-hz = <1200000000>;
			opp-microvolt = <1040000>;
		};

	pcode4-allcuts-allsubstrates {
		opp0 {
			opp-hz = <1500000000>;
			opp-microvolt = <1170000>;
		};
	};

	pcode5-cut2-allsubstrates {
		opp0 {
			opp-hz = <1200000000>;
			opp-microvolt = <1020000>;
		};
	};

	pcode5-allcuts-allsubstrates {
		opp0 {
			opp-hz = <1500000000>;
			opp-microvolt = <1140000>;
		};
	};

	pcode6-cut2-allsubstrates {
		opp0 {
			opp-hz = <1200000000>;
			opp-microvolt = <980000>;
		};
	};

	pcode6-allcuts-allsubstrates {
		opp0 {
			opp-hz = <1500000000>;
			opp-microvolt = <1100000>;
		};
	};

	pcode7-cut2-allsubstrates {
		opp0 {
			opp-hz = <1200000000>;
			opp-microvolt = <930000>;
		};
	};

	pcode7-allcuts-allsubstrates {
		opp0 {
			opp-hz = <1500000000>;
			opp-microvolt = <1070000>;
		};
	};
};


These will soon multiply once you start providing more complex
examples.  And how do you plan on handling this in the framework?  Can
the driver submit more than one variations of the string?  In the
current example the driver would need to submit four strings to
provide all acceptable variations; "pcodeX-cutY-substrateZ",
"pcodeX-allcuts-substrateZ", "pcodeX-cutY-allsubstrates" and
"pcodeX-allcuts-allsubstrates"

-- 
Lee Jones
Linaro STMicroelectronics Landing Team Lead
Linaro.org ? Open source software for ARM SoCs
Follow Linaro: Facebook | Twitter | Blog


From dinguyen at opensource.altera.com  Tue Aug 11 06:32:36 2015
From: dinguyen at opensource.altera.com (Dinh Nguyen)
Date: Tue, 11 Aug 2015 08:32:36 -0500
Subject: [PATCH] arm64: dts: Add base stratix 10 dtsi
In-Reply-To: <20150811103902.38cbcb6d@xhacker>
References: <1439240958-4713-1-git-send-email-dinguyen@opensource.altera.com>
 <20150811103902.38cbcb6d@xhacker>
Message-ID: <55C9F974.90102@opensource.altera.com>

Hi Jisheng,

On 8/10/15 9:39 PM, Jisheng Zhang wrote:
> On Mon, 10 Aug 2015 16:09:18 -0500
> <dinguyen at opensource.altera.com> wrote:
> 
>> From: Dinh Nguyen <dinguyen at opensource.altera.com>
>>
>> Add the base DTS for Altera's SoCFPGA Stratix 10 platform.
>>
>> Signed-off-by: Dinh Nguyen <dinguyen at opensource.altera.com>
>> ---
>>  arch/arm64/Kconfig                                 |   5 +
>>  arch/arm64/boot/dts/Makefile                       |   1 +
>>  arch/arm64/boot/dts/altera/Makefile                |   5 +
>>  arch/arm64/boot/dts/altera/socfpga_stratix10.dtsi  | 354 +++++++++++++++++++++
>>  .../boot/dts/altera/socfpga_stratix10_socdk.dts    |  38 +++
>>  arch/arm64/configs/defconfig                       |   1 +
>>  6 files changed, 404 insertions(+)
>>  create mode 100644 arch/arm64/boot/dts/altera/Makefile
>>  create mode 100644 arch/arm64/boot/dts/altera/socfpga_stratix10.dtsi
>>  create mode 100644 arch/arm64/boot/dts/altera/socfpga_stratix10_socdk.dts
>>
>> diff --git a/arch/arm64/Kconfig b/arch/arm64/Kconfig
>> index 318175f..0f8ab2b 100644
>> --- a/arch/arm64/Kconfig
>> +++ b/arch/arm64/Kconfig
>> @@ -207,6 +207,11 @@ config ARCH_SEATTLE
>>  	help
>>  	  This enables support for AMD Seattle SOC Family
>>  
>> +config ARCH_STRATIX10
>> +	bool "Altera's Stratix 10 SoCFPGA Family"
>> +	help
>> +	  This enables support for Altera's Stratix 10 SoCFPGA Family
>> +
>>  config ARCH_TEGRA
>>  	bool "NVIDIA Tegra SoC Family"
>>  	select ARCH_HAS_RESET_CONTROLLER
>> diff --git a/arch/arm64/boot/dts/Makefile b/arch/arm64/boot/dts/Makefile
>> index 38913be..7fb421a 100644
>> --- a/arch/arm64/boot/dts/Makefile
>> +++ b/arch/arm64/boot/dts/Makefile
>> @@ -1,3 +1,4 @@
>> +dts-dirs += altera
>>  dts-dirs += amd
>>  dts-dirs += apm
>>  dts-dirs += arm
>> diff --git a/arch/arm64/boot/dts/altera/Makefile b/arch/arm64/boot/dts/altera/Makefile
>> new file mode 100644
>> index 0000000..d7a6416
>> --- /dev/null
>> +++ b/arch/arm64/boot/dts/altera/Makefile
>> @@ -0,0 +1,5 @@
>> +dtb-$(CONFIG_ARCH_STRATIX10) += socfpga_stratix10_socdk.dtb
>> +
>> +always		:= $(dtb-y)
>> +subdir-y	:= $(dts-dirs)
>> +clean-files	:= *.dtb
>> diff --git a/arch/arm64/boot/dts/altera/socfpga_stratix10.dtsi b/arch/arm64/boot/dts/altera/socfpga_stratix10.dtsi
>> new file mode 100644
>> index 0000000..34f6dc3
>> --- /dev/null
>> +++ b/arch/arm64/boot/dts/altera/socfpga_stratix10.dtsi
>> @@ -0,0 +1,354 @@
>> +/*
>> + * Copyright Altera Corporation (C) 2015. All rights reserved.
>> + *
>> + * This program is free software; you can redistribute it and/or modify
>> + * it under the terms and conditions of the GNU General Public License,
>> + * version 2, as published by the Free Software Foundation.
>> + *
>> + * This program is distributed in the hope 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.
>> + *
>> + * You should have received a copy of the GNU General Public License along with
>> + * this program.  If not, see <http://www.gnu.org/licenses/>.
>> + */
>> +
>> +/dts-v1/;
>> +
>> +/ {
>> +	compatible = "altr,socfpga-stratix10";
>> +	#address-cells = <1>;
>> +	#size-cells = <1>;
>> +
> [...]
>> +
>> +	pmu {
>> +		compatible = "arm,armv8-pmuv3";
>> +		interrupts = <0 120 8>,
>> +			     <0 121 8>,
>> +			     <0 122 8>,
>> +			     <0 123 8>;
> 
> it's better to add interrupt-affinity according to Sudeep's suggestions.
> 

Ok, will update in V2. Thanks for reviewing.

Dinh


From stefan.wahren at i2se.com  Tue Aug 11 06:30:16 2015
From: stefan.wahren at i2se.com (Stefan Wahren)
Date: Tue, 11 Aug 2015 13:30:16 +0000
Subject: [PATCH V5 1/3] DT: nvmem: add binding for mxs-ocotp
In-Reply-To: <1439299818-8495-1-git-send-email-stefan.wahren@i2se.com>
References: <1439299818-8495-1-git-send-email-stefan.wahren@i2se.com>
Message-ID: <1439299818-8495-2-git-send-email-stefan.wahren@i2se.com>

This patch adds the devicetree bindings for the Freescale MXS On Chip
OTP driver.

Signed-off-by: Stefan Wahren <stefan.wahren at i2se.com>
---
 .../devicetree/bindings/nvmem/mxs-ocotp.txt        |   24 ++++++++++++++++++++
 1 file changed, 24 insertions(+)
 create mode 100644 Documentation/devicetree/bindings/nvmem/mxs-ocotp.txt

diff --git a/Documentation/devicetree/bindings/nvmem/mxs-ocotp.txt b/Documentation/devicetree/bindings/nvmem/mxs-ocotp.txt
new file mode 100644
index 0000000..cd2a8cd
--- /dev/null
+++ b/Documentation/devicetree/bindings/nvmem/mxs-ocotp.txt
@@ -0,0 +1,24 @@
+On-Chip OTP Memory for Freescale i.MX23/i.MX28
+
+Required properties:
+- compatible:
+  - "fsl,imx23-ocotp" for i.MX23
+  - "fsl,imx28-ocotp" for i.MX28
+- #address-cells : Should be 1
+- #size-cells : Should be 1
+- reg : Address and length of OTP controller registers
+- clocks : Should contain a reference to the HBus clock
+
+= Data cells =
+Are child nodes of mxs-ocotp, bindings of which as described in
+bindings/nvmem/nvmem.txt
+
+Example for i.MX28:
+
+	ocotp: ocotp at 8002c000 {
+		compatible = "fsl,imx28-ocotp", "fsl,ocotp";
+		#address-cells = <1>;
+		#size-cells = <1>;
+		reg = <0x8002c000 0x2000>;
+		clocks = <&clks 25>;
+	};
-- 
1.7.9.5



From stefan.wahren at i2se.com  Tue Aug 11 06:30:17 2015
From: stefan.wahren at i2se.com (Stefan Wahren)
Date: Tue, 11 Aug 2015 13:30:17 +0000
Subject: [PATCH V5 2/3] nvmem: add driver for ocotp in i.MX23 and i.MX28
In-Reply-To: <1439299818-8495-1-git-send-email-stefan.wahren@i2se.com>
References: <1439299818-8495-1-git-send-email-stefan.wahren@i2se.com>
Message-ID: <1439299818-8495-3-git-send-email-stefan.wahren@i2se.com>

This patch brings read-only support for the On-Chip OTP cells
in the i.MX23 and i.MX28 processor. The driver implements the
new NVMEM provider API.

Signed-off-by: Stefan Wahren <stefan.wahren at i2se.com>
---
 drivers/nvmem/Kconfig     |   11 ++
 drivers/nvmem/Makefile    |    2 +
 drivers/nvmem/mxs-ocotp.c |  252 +++++++++++++++++++++++++++++++++++++++++++++
 3 files changed, 265 insertions(+)
 create mode 100644 drivers/nvmem/mxs-ocotp.c

diff --git a/drivers/nvmem/Kconfig b/drivers/nvmem/Kconfig
index 8db2978..01ff8a6 100644
--- a/drivers/nvmem/Kconfig
+++ b/drivers/nvmem/Kconfig
@@ -36,4 +36,15 @@ config NVMEM_SUNXI_SID
 	  This driver can also be built as a module. If so, the module
 	  will be called nvmem_sunxi_sid.
 
+config NVMEM_MXS_OCOTP
+	tristate "Freescale MXS On-Chip OTP Memory Support"
+	depends on ARCH_MXS
+	help
+	  If you say Y here, you will get readonly access to the
+	  One Time Programmable memory pages that are stored
+	  on the Freescale i.MX23/i.MX28 processor.
+
+	  This driver can also be built as a module. If so, the module
+	  will be called nvmem-mxs-ocotp.
+
 endif
diff --git a/drivers/nvmem/Makefile b/drivers/nvmem/Makefile
index 4328b93..e9b6f3c 100644
--- a/drivers/nvmem/Makefile
+++ b/drivers/nvmem/Makefile
@@ -10,3 +10,5 @@ obj-$(CONFIG_QCOM_QFPROM)	+= nvmem_qfprom.o
 nvmem_qfprom-y			:= qfprom.o
 obj-$(CONFIG_NVMEM_SUNXI_SID)	+= nvmem_sunxi_sid.o
 nvmem_sunxi_sid-y		:= sunxi_sid.o
+obj-$(CONFIG_NVMEM_MXS_OCOTP)	+= nvmem-mxs-ocotp.o
+nvmem-mxs-ocotp-y		:= mxs-ocotp.o
diff --git a/drivers/nvmem/mxs-ocotp.c b/drivers/nvmem/mxs-ocotp.c
new file mode 100644
index 0000000..9ee146b
--- /dev/null
+++ b/drivers/nvmem/mxs-ocotp.c
@@ -0,0 +1,252 @@
+/*
+ * Freescale MXS On-Chip OTP driver
+ *
+ * Copyright (C) 2015 Stefan Wahren <stefan.wahren at i2se.com>
+ *
+ * Based on the driver from Huang Shijie and Christoph G. Baumann
+ *
+ * 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.h>
+#include <linux/delay.h>
+#include <linux/device.h>
+#include <linux/err.h>
+#include <linux/io.h>
+#include <linux/module.h>
+#include <linux/mutex.h>
+#include <linux/nvmem-provider.h>
+#include <linux/of_address.h>
+#include <linux/of_device.h>
+#include <linux/platform_device.h>
+#include <linux/regmap.h>
+#include <linux/slab.h>
+#include <linux/stmp_device.h>
+
+/* OCOTP registers and bits */
+
+#define BM_OCOTP_CTRL_RD_BANK_OPEN	BIT(12)
+#define BM_OCOTP_CTRL_ERROR		BIT(9)
+#define BM_OCOTP_CTRL_BUSY		BIT(8)
+
+#define OCOTP_TIMEOUT		10000
+#define OCOTP_DATA_OFFSET	0x20
+
+struct mxs_ocotp {
+	struct clk *clk;
+	void __iomem *base;
+	struct nvmem_device *nvmem;
+};
+
+static int mxs_ocotp_wait(struct mxs_ocotp *otp)
+{
+	int timeout = OCOTP_TIMEOUT;
+	unsigned int status = 0;
+
+	while (timeout--) {
+		status = readl(otp->base);
+
+		if (!(status & (BM_OCOTP_CTRL_BUSY | BM_OCOTP_CTRL_ERROR)))
+			break;
+
+		cpu_relax();
+	}
+
+	if (status & BM_OCOTP_CTRL_BUSY)
+		return -EBUSY;
+	else if (status & BM_OCOTP_CTRL_ERROR)
+		return -EIO;
+
+	return 0;
+}
+
+static int mxs_ocotp_read(void *context, const void *reg, size_t reg_size,
+			  void *val, size_t val_size)
+{
+	struct mxs_ocotp *otp = context;
+	unsigned int offset = *(u32 *)reg;
+	u32 *buf = val;
+	int ret = 0;
+
+	writel(BM_OCOTP_CTRL_ERROR, otp->base + STMP_OFFSET_REG_CLR);
+
+	ret = mxs_ocotp_wait(otp);
+	if (ret)
+		return ret;
+
+	/* open OCOTP banks for read */
+	writel(BM_OCOTP_CTRL_RD_BANK_OPEN, otp->base + STMP_OFFSET_REG_SET);
+
+	/* approximately wait 33 hclk cycles */
+	udelay(1);
+
+	ret = mxs_ocotp_wait(otp);
+	if (ret)
+		goto close_banks;
+
+	while (val_size) {
+		if ((offset < OCOTP_DATA_OFFSET) || (offset % 16)) {
+			/* fill up non-data register */
+			*buf = 0;
+		} else {
+			*buf = readl(otp->base + offset);
+		}
+
+		buf++;
+		val_size--;
+		offset += reg_size;
+	}
+
+close_banks:
+	/* close banks for power saving */
+	writel(BM_OCOTP_CTRL_RD_BANK_OPEN, otp->base + STMP_OFFSET_REG_CLR);
+
+	return ret;
+}
+
+static int mxs_ocotp_write(void *context, const void *data, size_t count)
+{
+	/* We don't want to support writing */
+	return 0;
+}
+
+static bool mxs_ocotp_writeable_reg(struct device *dev, unsigned int reg)
+{
+	return false;
+}
+
+static struct nvmem_config ocotp_config = {
+	.name = "mxs-ocotp",
+	.owner = THIS_MODULE,
+};
+
+static const struct regmap_range imx23_ranges[] = {
+	regmap_reg_range(OCOTP_DATA_OFFSET, 0x210),
+};
+
+static const struct regmap_access_table imx23_access = {
+	.yes_ranges = imx23_ranges,
+	.n_yes_ranges = ARRAY_SIZE(imx23_ranges),
+};
+
+static const struct regmap_range imx28_ranges[] = {
+	regmap_reg_range(OCOTP_DATA_OFFSET, 0x290),
+};
+
+static const struct regmap_access_table imx28_access = {
+	.yes_ranges = imx28_ranges,
+	.n_yes_ranges = ARRAY_SIZE(imx28_ranges),
+};
+
+static struct regmap_bus mxs_ocotp_bus = {
+	.read = mxs_ocotp_read,
+	.write = mxs_ocotp_write, /* make regmap_init() happy */
+	.reg_format_endian_default = REGMAP_ENDIAN_NATIVE,
+	.val_format_endian_default = REGMAP_ENDIAN_NATIVE,
+};
+
+static struct regmap_config mxs_ocotp_config = {
+	.reg_bits = 32,
+	.val_bits = 32,
+	.reg_stride = 16,
+	.writeable_reg = mxs_ocotp_writeable_reg,
+};
+
+static const struct of_device_id mxs_ocotp_match[] = {
+	{ .compatible = "fsl,imx23-ocotp", .data = &imx23_access },
+	{ .compatible = "fsl,imx28-ocotp", .data = &imx28_access },
+	{ /* sentinel */},
+};
+MODULE_DEVICE_TABLE(of, mxs_ocotp_match);
+
+static int mxs_ocotp_probe(struct platform_device *pdev)
+{
+	struct device *dev = &pdev->dev;
+	struct mxs_ocotp *otp;
+	struct resource *res;
+	const struct of_device_id *match;
+	struct regmap *regmap;
+	const struct regmap_access_table *access;
+	int ret;
+
+	match = of_match_device(dev->driver->of_match_table, dev);
+	if (!match || !match->data)
+		return -EINVAL;
+
+	otp = devm_kzalloc(dev, sizeof(*otp), GFP_KERNEL);
+	if (!otp)
+		return -ENOMEM;
+
+	res = platform_get_resource(pdev, IORESOURCE_MEM, 0);
+	otp->base = devm_ioremap_resource(dev, res);
+	if (IS_ERR(otp->base))
+		return PTR_ERR(otp->base);
+
+	otp->clk = devm_clk_get(&pdev->dev, NULL);
+	if (IS_ERR(otp->clk))
+		return PTR_ERR(otp->clk);
+
+	ret = clk_prepare(otp->clk);
+	if (ret < 0) {
+		dev_err(dev, "failed to prepare clk: %d\n", ret);
+		return ret;
+	}
+
+	access = match->data;
+	mxs_ocotp_config.rd_table = access;
+	mxs_ocotp_config.max_register = access->yes_ranges[0].range_max;
+
+	regmap = devm_regmap_init(dev, &mxs_ocotp_bus, otp, &mxs_ocotp_config);
+	if (IS_ERR(regmap)) {
+		dev_err(dev, "regmap init failed\n");
+		ret = PTR_ERR(regmap);
+		goto err_clk;
+	}
+
+	ocotp_config.dev = dev;
+	otp->nvmem = nvmem_register(&ocotp_config);
+	if (IS_ERR(otp->nvmem)) {
+		ret = PTR_ERR(otp->nvmem);
+		goto err_clk;
+	}
+
+	platform_set_drvdata(pdev, otp);
+
+	return 0;
+
+err_clk:
+	clk_unprepare(otp->clk);
+
+	return ret;
+}
+
+static int mxs_ocotp_remove(struct platform_device *pdev)
+{
+	struct mxs_ocotp *otp = platform_get_drvdata(pdev);
+
+	clk_unprepare(otp->clk);
+
+	return nvmem_unregister(otp->nvmem);
+}
+
+static struct platform_driver mxs_ocotp_driver = {
+	.probe = mxs_ocotp_probe,
+	.remove = mxs_ocotp_remove,
+	.driver = {
+		.name = "mxs-ocotp",
+		.of_match_table = mxs_ocotp_match,
+	},
+};
+
+module_platform_driver(mxs_ocotp_driver);
+MODULE_AUTHOR("Stefan Wahren <stefan.wahren at i2se.com>");
+MODULE_DESCRIPTION("driver for OCOTP in i.MX23/i.MX28");
+MODULE_LICENSE("GPL");
-- 
1.7.9.5



From stefan.wahren at i2se.com  Tue Aug 11 06:30:15 2015
From: stefan.wahren at i2se.com (Stefan Wahren)
Date: Tue, 11 Aug 2015 13:30:15 +0000
Subject: [PATCH V5 0/3] nvmem: add ocotp support for i.MX23 and i.MX28
Message-ID: <1439299818-8495-1-git-send-email-stefan.wahren@i2se.com>

This patch series brings read-only support for the On-Chip OTP cells
in the i.MX23 and i.MX28 processor.

changes in V5:
- rebase to char-misc-next
- add nvmem prefix to module name
- set status in dtsi files

changes in V4:
- rename fsl_ocotp.c to mxs-ocotp.c
- adapt driver to use NVMEM framework V7
- take care of hbus clock
- increase too small timeout
- implement a wait function
- use defines from stmp_device.h
- remove owner init
- more code cleanup

changes in V3:
- drop write support
- take care of i.MX23 which has less registers
- drop unnecessary header file
- move static variables into driver data
- add devicetree probing
- fix missing bank closing in error case
- use kobj from platform device for sysfs
- add SYSFS to Kconfig
- add binding file
- code cleanup

Stefan Wahren (3):
  DT: nvmem: add binding for mxs-ocotp
  nvmem: add driver for ocotp in i.MX23 and i.MX28
  ARM: mxs: enable ocotp for i.MX23 and i.MX28

 .../devicetree/bindings/nvmem/mxs-ocotp.txt        |   24 ++
 arch/arm/boot/dts/imx23.dtsi                       |    7 +-
 arch/arm/boot/dts/imx28.dtsi                       |    7 +-
 drivers/nvmem/Kconfig                              |   11 +
 drivers/nvmem/Makefile                             |    2 +
 drivers/nvmem/mxs-ocotp.c                          |  252 ++++++++++++++++++++
 6 files changed, 299 insertions(+), 4 deletions(-)
 create mode 100644 Documentation/devicetree/bindings/nvmem/mxs-ocotp.txt
 create mode 100644 drivers/nvmem/mxs-ocotp.c

-- 
1.7.9.5



From stefan.wahren at i2se.com  Tue Aug 11 06:30:18 2015
From: stefan.wahren at i2se.com (Stefan Wahren)
Date: Tue, 11 Aug 2015 13:30:18 +0000
Subject: [PATCH V5 3/3] ARM: mxs: enable ocotp for i.MX23 and i.MX28
In-Reply-To: <1439299818-8495-1-git-send-email-stefan.wahren@i2se.com>
References: <1439299818-8495-1-git-send-email-stefan.wahren@i2se.com>
Message-ID: <1439299818-8495-4-git-send-email-stefan.wahren@i2se.com>

This patch enables On Chip OTP support for i.MX23 and i.MX28 SoCs,
but keeps the old compatible string.

Signed-off-by: Stefan Wahren <stefan.wahren at i2se.com>
---
 arch/arm/boot/dts/imx23.dtsi |    7 +++++--
 arch/arm/boot/dts/imx28.dtsi |    7 +++++--
 2 files changed, 10 insertions(+), 4 deletions(-)

diff --git a/arch/arm/boot/dts/imx23.dtsi b/arch/arm/boot/dts/imx23.dtsi
index b995333..0541563 100644
--- a/arch/arm/boot/dts/imx23.dtsi
+++ b/arch/arm/boot/dts/imx23.dtsi
@@ -383,9 +383,12 @@
 			};
 
 			ocotp at 8002c000 {
-				compatible = "fsl,ocotp";
+				compatible = "fsl,imx23-ocotp", "fsl,ocotp";
+				#address-cells = <1>;
+				#size-cells = <1>;
 				reg = <0x8002c000 0x2000>;
-				status = "disabled";
+				clocks = <&clks 15>;
+				status = "okay";
 			};
 
 			axi-ahb at 8002e000 {
diff --git a/arch/arm/boot/dts/imx28.dtsi b/arch/arm/boot/dts/imx28.dtsi
index 4e073e8..648d790 100644
--- a/arch/arm/boot/dts/imx28.dtsi
+++ b/arch/arm/boot/dts/imx28.dtsi
@@ -936,9 +936,12 @@
 			};
 
 			ocotp: ocotp at 8002c000 {
-				compatible = "fsl,ocotp";
+				compatible = "fsl,imx28-ocotp", "fsl,ocotp";
+				#address-cells = <1>;
+				#size-cells = <1>;
 				reg = <0x8002c000 0x2000>;
-				status = "disabled";
+				clocks = <&clks 25>;
+				status = "okay";
 			};
 
 			axi-ahb at 8002e000 {
-- 
1.7.9.5



From robin.murphy at arm.com  Tue Aug 11 06:31:34 2015
From: robin.murphy at arm.com (Robin Murphy)
Date: Tue, 11 Aug 2015 14:31:34 +0100
Subject: [PATCH v5 1/3] iommu: Implement common IOMMU ops for DMA mapping
In-Reply-To: <20150811093742.GC14980@8bytes.org>
References: <cover.1438362603.git.robin.murphy@arm.com>
 <6ce6b501501f611297ae0eae31e07b0d2060eaae.1438362603.git.robin.murphy@arm.com>
 <20150807084228.GU14980@8bytes.org> <55C4B4DF.4040608@arm.com>
 <20150811093742.GC14980@8bytes.org>
Message-ID: <55C9F936.8080201@arm.com>

Hi Joerg,

On 11/08/15 10:37, Joerg Roedel wrote:
> On Fri, Aug 07, 2015 at 02:38:39PM +0100, Robin Murphy wrote:
>> Indeed, DMA_DEBUG will check that a driver is making DMA API calls
>> to the arch code in the right way; this is a different check, to
>> catch things like the arch code passing the wrong domain into this
>> layer, or someone else having messed directly with the domain via
>> the IOMMU API. If the iommu_unmap doesn't match the IOVA region we
>> looked up, that means the IOMMU page tables have somehow become
>> inconsistent with the IOVA allocator, so we are in an unrecoverable
>> situation where we can no longer be sure what devices have access
>> to. That's bad.
>
> Sure, but the BUG_ON would also trigger on things like a double-free,
> which is bad to handle as a BUG_ON. A WARN_ON for this is sufficient.

Oh dear, it gets even better than that; in the case of a simple 
double-unmap where the IOVA is already free, we wouldn't even get as far 
as that check because we'd die calling iova_size(NULL). How on Earth did 
I get to v5 without spotting that? :(

Anyway, on reflection I think you're probably right; I've clearly been 
working on this for long enough to start falling into the "my thing is 
obviously more important than all the other things" trap.

>> AFAIK, yes (this is just a slight tidyup of the existing code that
>> 32-bit Exynos/Tegra/Rockchip/etc. devices are already using) - the
>> display guys want increasingly massive contiguous allocations for
>> framebuffers, layers, etc., so having IOMMU magic deal with that
>> saves CMA for non-IOMMU devices that really need it.
>
> Makes sense, I thougt about something similar for x86 too to avoid the
> high-order allocations we currently do. I guess the buffer will later be
> mapped into the vmalloc space for the CPU?

Indeed - for non-coherent devices we have to remap all allocations 
(IOMMU or not) anyway in order to get a non-cacheable CPU mapping of the 
buffer, so having non-contiguous pages is no bother; for coherent 
devices we can just do the same thing but keep the vmalloc mapping 
cacheable. There's also the DMA_ATTR_NO_KERNEL_MAPPING case (e.g. GPU 
just wants a big buffer to render into and read back out again) where we 
wouldn't need a CPU address at all, although on arm64 vmalloc space is 
cheap enough that we've no plans to implement that at the moment.

Robin.



From hansverk at cisco.com  Tue Aug 11 06:32:46 2015
From: hansverk at cisco.com (Hans Verkuil)
Date: Tue, 11 Aug 2015 15:32:46 +0200
Subject: [PATCH RFC v2 09/16] media: use media_graph_obj for link endpoints
In-Reply-To: <20150811102201.5abaf64d@recife.lan>
References: <cover.1439292977.git.mchehab@osg.samsung.com>	<6d02794028ea4f7ad33e3ba0e07e0c690e2feee2.1439292977.git.mchehab@osg.samsung.com>	<55C9E9AE.5020602@cisco.com>
 <20150811102201.5abaf64d@recife.lan>
Message-ID: <55C9F97E.7070601@cisco.com>

>>> diff --git a/include/media/media-entity.h b/include/media/media-entity.h
>>> index 403019035424..f6e2136480f1 100644
>>> --- a/include/media/media-entity.h
>>> +++ b/include/media/media-entity.h
>>> @@ -43,6 +43,17 @@ enum media_graph_type {
>>>  	MEDIA_GRAPH_LINK,
>>>  };
>>>  
>>> +/**
>>> + * enum media_graph_link_dir - direction of a link
>>> + *
>>> + * @MEDIA_LINK_DIR_BIDIRECTIONAL	Link is bidirectional
>>> + * @MEDIA_LINK_DIR_PAD_0_TO_1		Link is unidirectional,
>>> + *					from port 0 (source) to port 1 (sink)
>>> + */
>>> +enum media_graph_link_dir {
>>> +	MEDIA_LINK_DIR_BIDIRECTIONAL,
>>> +	MEDIA_LINK_DIR_PORT0_TO_PORT1,
>>> +};
>>
>> 1) the comment and the actual enum are out-of-sync
> 
> Ah, yes. I was in doubt about using PAD or PORT here. I ended by using
> port at the links, as the endpoints can either be an interface/entity
> or a pad. So, I decided to use port.

It's either bi-directional (between interface and entity) or directional
(between two pads), so I think PAD is better here. We don't use the term
port anywhere else in the MC, so I think it is a bit confusing to
introduce a new name here.

> 
>> 2) why not just make a 'BIRECTIONAL' link flag instead of inventing
>>    a new enum? Adding yet another field seems overkill to me. Have a
>>    'BIDIRECTIONAL' flag seems perfectly OK to me (and useful for the
>>    application as well).
> 
> Yeah, we can use flags, instead. I decided to use an enum here just
> to make it clearer about the two possible options.
> 
> I was actually considering to rename media_link source/sink to
> port0/port1, as using "source"/"sink" names on a bidirection link
> doesn't make sense. I'm still in doubt about such rename, though,
> as it would make harder to inspect the graph traversal routines.

Right. I really wouldn't rename it. As suggested below using an
anonymous union would allow you to create proper names.

> Also, I want to force all places that create a link to choose
> between either BIRECTIONAL or PORT0_TO_PORT1, as this makes easier
> to review if the code is doing the right thing when inspecting it.

By creating two different functions? I think that would be very useful.
E.g. make_pad_link() and make_intf_to_ent_link() or something like
that. That would also hide the link direction. I still prefer a flag,
though :-) That's mostly personal preference, though.

> 
> In summary, I would prefer to keep this internally as a separate
>  enum, at least for now. We can latter simplify it and use a flag
> for that (or maybe two flags?).
> 
>>
>>>  
>>>  /* Structs to represent the objects that belong to a media graph */
>>>  
>>> @@ -72,9 +83,9 @@ struct media_pipeline {
>>>  
>>>  struct media_link {
>>>  	struct list_head list;
>>> -	struct media_graph_obj			graph_obj;
>>> -	struct media_pad *source;	/* Source pad */
>>> -	struct media_pad *sink;		/* Sink pad  */
>>> +	struct media_graph_obj		graph_obj;
>>> +	enum media_graph_link_dir	dir;
>>> +	struct media_graph_obj		*source, *sink;
>>
>> I'm not too keen about all the gobj_to_foo(obj) macros that this requires. It
>> is rather ugly code.
>>
>> What about this:
>>
>> 	union {
>> 		struct media_graph_obj *source;
>> 		struct media_pad *source_pad;
>> 		struct media_interface *source_intf;
>> 	};
>> 	union {
>> 		struct media_graph_obj *sink;
>> 		struct media_pad *sink_pad;
>> 		struct media_entity *sink_ent;
>> 	};
>>
>> Now the code can just use ->source_pad etc.
> 
> good idea. Will do that on a version 3. I think that, in this case, the
> best is to write a note that the first element at pad/entity/interface
> should be the graph_obj.
> 
> I would actually call port0_intf and port1_ent on the above structs,
> as it makes no sense to call sink/source for interface->entity links.

How about this:

 	union {
 		struct media_graph_obj *port0;
 		struct media_interface *port0_intf;	// perhaps just intf or interface?
 		struct media_pad *source;
 	};
 	union {
 		struct media_graph_obj *port1;
 		struct media_entity *port1_ent;	// perhaps just ent or entity?
 		struct media_pad *sink;
 	};

This has the advantage that the source/sink pads are still called source and
sink and you don't have to rename the existing code.

Regards,

	Hans


From daniel.lezcano at linaro.org  Tue Aug 11 06:40:45 2015
From: daniel.lezcano at linaro.org (Daniel Lezcano)
Date: Tue, 11 Aug 2015 15:40:45 +0200
Subject: [PATCH v3 4/4] misc: atmel_tclib: get and use slow clock
In-Reply-To: <1439285884-16051-5-git-send-email-alexandre.belloni@free-electrons.com>
References: <1439285884-16051-1-git-send-email-alexandre.belloni@free-electrons.com>
 <1439285884-16051-5-git-send-email-alexandre.belloni@free-electrons.com>
Message-ID: <55C9FB5D.7030607@linaro.org>

On 08/11/2015 11:38 AM, Alexandre Belloni wrote:
> From: Boris Brezillon <boris.brezillon at free-electrons.com>
>
> Commit dca1a4b5ff6e ("clk: at91: keep slow clk enabled to prevent system
> hang") added a workaround for the slow clock as it is not properly handled
> by its users.
>
> Get and use the slow clock as it is necessary for the timer counters.
>
> Signed-off-by: Boris Brezillon <boris.brezillon at free-electrons.com>
> Signed-off-by: Alexandre Belloni <alexandre.belloni at free-electrons.com>
> Acked-by: Greg Kroah-Hartman <gregkh at linuxfoundation.org>
> ---
> Cc: Daniel Lezcano <daniel.lezcano at linaro.org>
> Cc: Thomas Gleixner <tglx at linutronix.de>
> Cc: Thierry Reding <thierry.reding at gmail.com>
> Cc: linux-pwm at vger.kernel.org
>
>   drivers/clocksource/tcb_clksrc.c |  8 ++++++++
>   drivers/misc/atmel_tclib.c       |  4 ++++
>   drivers/pwm/pwm-atmel-tcb.c      | 23 ++++++++++++++++-------
>   include/linux/atmel_tc.h         |  1 +
>   4 files changed, 29 insertions(+), 7 deletions(-)
>
> diff --git a/drivers/clocksource/tcb_clksrc.c b/drivers/clocksource/tcb_clksrc.c
> index b9b7277173c2..969ba03633b0 100644
> --- a/drivers/clocksource/tcb_clksrc.c
> +++ b/drivers/clocksource/tcb_clksrc.c
> @@ -188,6 +188,13 @@ static int __init setup_clkevents(struct atmel_tc *tc, int clk32k_divisor_idx)
>   	ret = clk_prepare_enable(t2_clk);
>   	if (ret)
>   		return ret;
> +
> +	ret = clk_prepare_enable(tc->slow_clk);
> +	if (ret) {
> +		clk_disable_unprepare(t2_clk);
> +		return ret;
> +	}
> +
>   	clk_disable(t2_clk);

Do you need t2_clk to be enabled in order to enable tc->slow_clk ?

>   	clkevt.regs = tc->regs;
> @@ -200,6 +207,7 @@ static int __init setup_clkevents(struct atmel_tc *tc, int clk32k_divisor_idx)
>   	ret = request_irq(irq, ch2_irq, IRQF_TIMER, "tc_clkevt", &clkevt);
>   	if (ret) {
>   		clk_unprepare(t2_clk);
> +		clk_disable_unprepare(tc->slow_clk);
>   		return ret;
>   	}
>
> diff --git a/drivers/misc/atmel_tclib.c b/drivers/misc/atmel_tclib.c
> index 0ca05c3ec8d6..ac24a4bd63f7 100644
> --- a/drivers/misc/atmel_tclib.c
> +++ b/drivers/misc/atmel_tclib.c

[ ... ]

> @@ -387,9 +387,9 @@ static int atmel_tcb_pwm_probe(struct platform_device *pdev)
>
>   	tcbpwm = devm_kzalloc(&pdev->dev, sizeof(*tcbpwm), GFP_KERNEL);
>   	if (tcbpwm == NULL) {
> -		atmel_tc_free(tc);
> +		err = -ENOMEM;
>   		dev_err(&pdev->dev, "failed to allocate memory\n");
> -		return -ENOMEM;
> +		goto err_free_tc;
>   	}
>
>   	tcbpwm->chip.dev = &pdev->dev;
> @@ -400,17 +400,24 @@ static int atmel_tcb_pwm_probe(struct platform_device *pdev)
>   	tcbpwm->chip.npwm = NPWM;
>   	tcbpwm->tc = tc;
>
> +	err = clk_prepare_enable(tc->slow_clk);
> +	if (err)
> +		goto err_free_tc;
> +
>   	spin_lock_init(&tcbpwm->lock);
>
>   	err = pwmchip_add(&tcbpwm->chip);
> -	if (err < 0) {
> -		atmel_tc_free(tc);
> -		return err;
> -	}
> +	if (err < 0)
> +		goto err_free_tc;
>
>   	platform_set_drvdata(pdev, tcbpwm);
>
>   	return 0;
> +
> +err_free_tc:
> +	atmel_tc_free(tc);
> +
> +	return err;

What about clk_unprepare_disable(tc->slow_clk) ?

>   }
>

[ ... ]


-- 
  <http://www.linaro.org/> Linaro.org ? Open source software for ARM SoCs

Follow Linaro:  <http://www.facebook.com/pages/Linaro> Facebook |
<http://twitter.com/#!/linaroorg> Twitter |
<http://www.linaro.org/linaro-blog/> Blog



From olof at lixom.net  Tue Aug 11 06:00:51 2015
From: olof at lixom.net (Olof Johansson)
Date: Tue, 11 Aug 2015 15:00:51 +0200
Subject: [GIT PULL 2/5] Samsung cleanup for v4.3
In-Reply-To: <55C069AF.5050300@kernel.org>
References: <55C069AF.5050300@kernel.org>
Message-ID: <20150811130051.GA30181@localhost>

On Tue, Aug 04, 2015 at 04:28:47PM +0900, Kukjin Kim wrote:
> Hi,
> 
> Please pull Samsung cleanup for v4.3.
> Note I'm going to cleanup non-used definitions based on this soon.
> 
> Thanks,
> Kukjin
> 
> 
> The following changes since commit d770e558e21961ad6cfdf0ff7df0eb5d7d4f0754:
> 
>   Linux 4.2-rc1 (2015-07-05 11:01:52 -0700)
> 
> are available in the git repository at:
> 
>   git://git.kernel.org/pub/scm/linux/kernel/git/kgene/linux-samsung.git
> tags/samsung-cleanup
> 
> for you to fetch changes up to d306d08f07183fe1504257101b25b5b33d77bae9:
> 
>   ARM: SAMSUNG: remove keypad-core header in plat-samsung (2015-07-30
> 02:02:06 +0900)

Merged, thanks.


-Olof


From olof at lixom.net  Tue Aug 11 06:02:38 2015
From: olof at lixom.net (Olof Johansson)
Date: Tue, 11 Aug 2015 15:02:38 +0200
Subject: [GIT PULL 3/5] Samsung DT updates for v4.3
In-Reply-To: <55C069C2.7040208@kernel.org>
References: <55C069C2.7040208@kernel.org>
Message-ID: <20150811130238.GB30181@localhost>

On Tue, Aug 04, 2015 at 04:29:06PM +0900, Kukjin Kim wrote:
> Hi,
> 
> Please pull Samsung DT updates for v4.3.
> 
> Thanks,
> Kukjin
> 
> 
> The following changes since commit d770e558e21961ad6cfdf0ff7df0eb5d7d4f0754:
> 
>   Linux 4.2-rc1 (2015-07-05 11:01:52 -0700)
> 
> are available in the git repository at:
> 
>   git://git.kernel.org/pub/scm/linux/kernel/git/kgene/linux-samsung.git
> tags/samsung-dt-1
> 
> for you to fetch changes up to 5e080b078fa1f929d9aa5586985d5e7c0739d207:
> 
>   ARM: dts: Extend exynos5420-pinctrl nodes using labels instead of
> paths (2015-07-21 13:01:23 +0900)

Merged, thanks.


-Olof


From olof at lixom.net  Tue Aug 11 06:06:55 2015
From: olof at lixom.net (Olof Johansson)
Date: Tue, 11 Aug 2015 15:06:55 +0200
Subject: [PATCH 0/3] Device Tree updates of UniPhier SoCs for Linux 4.3
In-Reply-To: <1438687264-26538-1-git-send-email-yamada.masahiro@socionext.com>
References: <1438687264-26538-1-git-send-email-yamada.masahiro@socionext.com>
Message-ID: <20150811130655.GC30181@localhost>

On Tue, Aug 04, 2015 at 08:21:01PM +0900, Masahiro Yamada wrote:
> Hi Olof and Arnd,
> 
> 
> Here are a little more updates for device trees for UniPhier SoCs.
> 
> Please consider applying this series to your ARM-SOC tree.
> 
> Thanks!
> 
> 
> 
> Masahiro Yamada (3):
>   ARM: dts: UniPhier: add I2C controller device nodes
>   ARM: dts: UniPhier: add PH1-Pro5 SoC support
>   ARM: dts: UniPhier: add ProXstream2 and PH1-LD6b SoC/board support

Thanks, applied all 3 to next/dt with minor tweaks to the subject line.


-Olof


From olof at lixom.net  Tue Aug 11 06:07:39 2015
From: olof at lixom.net (Olof Johansson)
Date: Tue, 11 Aug 2015 15:07:39 +0200
Subject: [PATCH 3/3] ARM: dts: UniPhier: add ProXstream2 and PH1-LD6b
 SoC/board support
In-Reply-To: <1438687264-26538-4-git-send-email-yamada.masahiro@socionext.com>
References: <1438687264-26538-1-git-send-email-yamada.masahiro@socionext.com>
 <1438687264-26538-4-git-send-email-yamada.masahiro@socionext.com>
Message-ID: <20150811130739.GD30181@localhost>

Hi,

On Tue, Aug 04, 2015 at 08:21:04PM +0900, Masahiro Yamada wrote:
> Initial version of DTSI for ProXstream2 and PH1-LD6b and DTS for
> PH1-LD6b reference board.
> 
> Signed-off-by: Masahiro Yamada <yamada.masahiro at socionext.com>
> ---
> 
>  arch/arm/boot/dts/Makefile                  |   3 +-
>  arch/arm/boot/dts/uniphier-ph1-ld6b-ref.dts | 105 +++++++++++
>  arch/arm/boot/dts/uniphier-ph1-ld6b.dtsi    |  67 +++++++
>  arch/arm/boot/dts/uniphier-proxstream2.dtsi | 273 ++++++++++++++++++++++++++++
>  4 files changed, 447 insertions(+), 1 deletion(-)
>  create mode 100644 arch/arm/boot/dts/uniphier-ph1-ld6b-ref.dts
>  create mode 100644 arch/arm/boot/dts/uniphier-ph1-ld6b.dtsi
>  create mode 100644 arch/arm/boot/dts/uniphier-proxstream2.dtsi
> 
> diff --git a/arch/arm/boot/dts/Makefile b/arch/arm/boot/dts/Makefile
> index 246473a..6eb3f2f 100644
> --- a/arch/arm/boot/dts/Makefile
> +++ b/arch/arm/boot/dts/Makefile
> @@ -645,7 +645,8 @@ dtb-$(CONFIG_ARCH_UNIPHIER) += \
>  	uniphier-ph1-sld3-ref.dtb \
>  	uniphier-ph1-ld4-ref.dtb \
>  	uniphier-ph1-pro4-ref.dtb \
> -	uniphier-ph1-sld8-ref.dtb
> +	uniphier-ph1-sld8-ref.dtb \
> +	uniphier-ph1-ld6b-ref.dtb

Please always add entries here sorted, don't just append. I've fixed it
up for you this time.


-Olof


From olof at lixom.net  Tue Aug 11 06:10:15 2015
From: olof at lixom.net (Olof Johansson)
Date: Tue, 11 Aug 2015 15:10:15 +0200
Subject: [GIT PULL] CSR SiRFSoC DT for 4.3
In-Reply-To: <CAGsJ_4yxiytb3bUVsG5jTWKQdY7xE8HKBz7Og_Se=mB_cr3ZEQ@mail.gmail.com>
References: <CAGsJ_4yxiytb3bUVsG5jTWKQdY7xE8HKBz7Og_Se=mB_cr3ZEQ@mail.gmail.com>
Message-ID: <20150811131015.GE30181@localhost>

On Wed, Aug 05, 2015 at 03:15:08PM +0800, Barry Song wrote:
> Hi Arnd, Kevin, Olof,
> 
> The following changes since commit bc0195aad0daa2ad5b0d76cce22b167bc3435590:
> 
>   Linux 4.2-rc2 (2015-07-12 15:10:30 -0700)
> 
> are available in the git repository at:
> 
>   git://git.kernel.org/pub/scm/linux/kernel/git/baohua/linux.git
> tags/sirf-dts-for-4.3
> 
> for you to fetch changes up to 2cd212427fa9cbf19c1f353d6e14b959e8f112f7:
> 
>   ARM: dts: atlas7: add a GPIO key for rearview button (2015-08-05
> 22:44:21 +0800)

Thanks, merged.


-Olof



From olof at lixom.net  Tue Aug 11 06:16:53 2015
From: olof at lixom.net (Olof Johansson)
Date: Tue, 11 Aug 2015 15:16:53 +0200
Subject: [GIT PULL] Broadcom Device Tree changes for 4.3 (part 2)
In-Reply-To: <1438796683-18581-1-git-send-email-f.fainelli@gmail.com>
References: <1438796683-18581-1-git-send-email-f.fainelli@gmail.com>
Message-ID: <20150811131653.GH30181@localhost>

Hi,

On Wed, Aug 05, 2015 at 10:44:41AM -0700, Florian Fainelli wrote:
> The following changes since commit ee224e175e9d837b3d572e863ac96109b58707ac:
> 
>   Merge tag 'mvebu-dt-4.3-2' of git://git.infradead.org/linux-mvebu into next/dt (2015-08-05 11:10:30 +0200)

This isn't quite right. Please don't base your branches on top of our
next/* branches. Instead they should be based on a plain -rc from upstream
or, if needed, preceding versions of your own branches.

In this case I've just taken the three patches and applied them directly, so
no need to respin the branch this time.


-Olof



From olof at lixom.net  Tue Aug 11 06:17:56 2015
From: olof at lixom.net (Olof Johansson)
Date: Tue, 11 Aug 2015 15:17:56 +0200
Subject: [GIT PULL] Broadcom SoC changes for 4.3 (part 2, try2)
In-Reply-To: <1439063444-12466-1-git-send-email-f.fainelli@gmail.com>
References: <55C4E8C8.7030503@broadcom.com>
 <1439063444-12466-1-git-send-email-f.fainelli@gmail.com>
Message-ID: <20150811131756.GI30181@localhost>

Hi,


On Sat, Aug 08, 2015 at 12:50:44PM -0700, Florian Fainelli wrote:
> The following changes since commit 39aa437e18cac7acae55481ed73feea0de497399:
> 
>   Merge branch 'queue/irq/arm' of git://git.kernel.org/pub/scm/linux/kernel/git/tip/tip into next/cleanup (2015-08-05 17:24:11 +0200)
> 
> are available in the git repository at:
> 
>   http://github.com/broadcom/stblinux tags/arm-soc/for-4.3/soc-part2
> 
> for you to fetch changes up to cf1140515b3b94ef5aa06a085e94ddd814a8cd78:
> 
>   ARM: brcmstb: select ARCH_DMA_ADDR_T_64BIT for LPAE (2015-08-06 21:38:13 -0700)

Same thing here, please don't base your branch on top of our next/*. I've also
cherry-picked these patches over, so no need to respin this time.


Thanks,

-Olof



From olof at lixom.net  Tue Aug 11 06:19:24 2015
From: olof at lixom.net (Olof Johansson)
Date: Tue, 11 Aug 2015 15:19:24 +0200
Subject: [PATCH] ARM/EP93xx/timer: Migrate to new 'set-state' interface
In-Reply-To: <20150810090334.GB5766@linux>
References: <744dca162a7626694770a9f51457566a33c3e08f.1438852023.git.viresh.kumar@linaro.org>
 <CACRpkdZknzqgH+-F0MZgZywtoOL1hhbg=7w1RSC5aZohXtDB3A@mail.gmail.com>
 <20150810090334.GB5766@linux>
Message-ID: <20150811131924.GJ30181@localhost>

On Mon, Aug 10, 2015 at 02:33:34PM +0530, Viresh Kumar wrote:
> On 10-08-15, 11:01, Linus Walleij wrote:
> > Sure, but does it work right off or does Olof have to
> > pull a branch from your tree in for it to work? In that
> > case I suggest you take this in the -rc phase. Anyways:
> > Acked-by: Linus Walleij <linus.walleij at linaro.org>
> 
> It should work with latest 4.2 rc..

Latest? We don't base our tree on the latest -- instead we try to keep
back on -rc2/3 if we can. Right now our tree is on -rc2.


Please confirm that this is still OK to merge with that as base. Thanks.


-Olof


From olof at lixom.net  Tue Aug 11 06:13:23 2015
From: olof at lixom.net (Olof Johansson)
Date: Tue, 11 Aug 2015 15:13:23 +0200
Subject: [GIT PULL] Broadcom MAINTAINERS file updates for 4.3
In-Reply-To: <1438796683-18581-2-git-send-email-f.fainelli@gmail.com>
References: <1438796683-18581-1-git-send-email-f.fainelli@gmail.com>
 <1438796683-18581-2-git-send-email-f.fainelli@gmail.com>
Message-ID: <20150811131323.GG30181@localhost>

On Wed, Aug 05, 2015 at 10:44:42AM -0700, Florian Fainelli wrote:
> The following changes since commit d770e558e21961ad6cfdf0ff7df0eb5d7d4f0754:
> 
>   Linux 4.2-rc1 (2015-07-05 11:01:52 -0700)
> 
> are available in the git repository at:
> 
>   http://github.com/broadcom/stblinux tags/arm-soc/for-4.3/maintainers
> 
> for you to fetch changes up to 824811293538f5cafaa6d19e3458a13eafa92a32:
> 
>   MAINTAINERS: Explicitly add linux-arm-kernel for bcm2835 (2015-08-05 10:14:00 -0700)
> 
> ----------------------------------------------------------------
> This pull request contains the following changes to the MAINTAINERS file:
> 
> - Add Eric Anholt as a 3rd maintainer for the Raspberry Pi platform code/drivers
> - Add linux-arm-kernel for all bcm2835 related drivers

Merged, thanks.


-Olof


From olof at lixom.net  Tue Aug 11 06:31:27 2015
From: olof at lixom.net (Olof Johansson)
Date: Tue, 11 Aug 2015 15:31:27 +0200
Subject: [GIT PULL] Nomadik improvements and cleanups for v4.3
In-Reply-To: <CACRpkdbN6ZDhH56PSUmPD5_uYJhk_o+mCqAvi5GVEtys=AftNg@mail.gmail.com>
References: <CACRpkdbN6ZDhH56PSUmPD5_uYJhk_o+mCqAvi5GVEtys=AftNg@mail.gmail.com>
Message-ID: <20150811133127.GN30181@localhost>

Hi Linus,

On Thu, Aug 06, 2015 at 04:50:13PM +0200, Linus Walleij wrote:
> Hi ARM SoC folks,
> 
> these are a four patches of Nomadik cleanups and improvements
> targeted for v4.2.
> 
> Since there is a cross-dependency between the board files and the
> device tree files I just kept them all on the same branch. Also it seems
> a bit overzealous to split patches for this small platform.
> 
> Please pull it in as cleanup/development for v4.3.
> 
> Yours,
> Linus Walleij
> 
> The following changes since commit 74d33293e467df61de1b1d8b2fbe29e550dec33b:
> 
>   Linux 4.2-rc5 (2015-08-02 18:34:55 -0700)

This is 3 -rcs newer than we have our tree based on to date (-rc2).

I don't see any conflict with -rc2 though, so I've cherry-picked these over
instead of merging the branch.


Thanks!

-Olof


From olof at lixom.net  Tue Aug 11 06:38:43 2015
From: olof at lixom.net (Olof Johansson)
Date: Tue, 11 Aug 2015 15:38:43 +0200
Subject: [GIT PULL] Renesas ARM Based SoC CPG MSTP Clock Domain Updates
 for v4.3
In-Reply-To: <cover.1438911559.git.horms+renesas@verge.net.au>
References: <cover.1438911559.git.horms+renesas@verge.net.au>
Message-ID: <20150811133843.GP30181@localhost>

On Fri, Aug 07, 2015 at 11:12:03AM +0900, Simon Horman wrote:
> Hi Olof, Hi Kevin, Hi Arnd,
> 
> Please consider these Renesas ARM based SoC CPG MSTP clock domain updates
> for v4.3.
> 
> This pull request is based on "Third Round of Renesas ARM Based SoC DT
> Updates for v4.3", tagged as renesas-dt3-for-v4.3, which I have also sent a
> pull-request for.
> 
> The reason for that base is that the DT changes in this series update nodes
> added in that tag.
> 
> This series begins with driver changes and follows up with DT changes.
> The latter depend on the former.

I see the acked-by tags on the clk patches, but it took some searching to find
the ack email from Stephen.

Can you please make our homework a bit easier when providing that in
the future?

Thanks,


-Olof



From olof at lixom.net  Tue Aug 11 06:20:49 2015
From: olof at lixom.net (Olof Johansson)
Date: Tue, 11 Aug 2015 15:20:49 +0200
Subject: [PATCH v2 0/4] Device Tree updates of UniPhier SoCs for Linux 4.3
In-Reply-To: <1438857468-9740-1-git-send-email-yamada.masahiro@socionext.com>
References: <1438857468-9740-1-git-send-email-yamada.masahiro@socionext.com>
Message-ID: <20150811132049.GK30181@localhost>

On Thu, Aug 06, 2015 at 07:37:44PM +0900, Masahiro Yamada wrote:
> Hi Olof and Arnd,
> 
> Here are a little more updates for device trees for UniPhier SoCs.
> 
> Please consider applying this series to your ARM-SOC tree.
> 
> Thanks!

Hi,

Please always comment on when the previous when you respin. I didn't
see this thread until after I had applied v1.

I've taken 2/4 directly now, since it's the only difference.


Thanks!


-Olof


From olof at lixom.net  Tue Aug 11 06:23:00 2015
From: olof at lixom.net (Olof Johansson)
Date: Tue, 11 Aug 2015 15:23:00 +0200
Subject: [GIT PULL] omap pbias regulator regression fixes against v4.2-rc5
In-Reply-To: <20150806104031.GE4215@atomide.com>
References: <20150806104031.GE4215@atomide.com>
Message-ID: <20150811132300.GL30181@localhost>

On Thu, Aug 06, 2015 at 03:40:31AM -0700, Tony Lindgren wrote:
> The following changes since commit 9908ac3daa3da2d236b5406b95d0865ddb8b29c4:
> 
>   ARM: dts: Correct audio input route & set mic bias for am335x-pepper (2015-07-15 03:03:01 -0700)
> 
> are available in the git repository at:
> 
>   git://git.kernel.org/pub/scm/linux/kernel/git/tmlind/linux-omap tags/omap-for-v4.2/fixes-rc5
> 
> for you to fetch changes up to cd4556733b30cc363adc7b1cea3bffa7e2dd0c7c:
> 
>   ARM: dts: dra7: Fix broken pbias device creation (2015-08-05 03:04:07 -0700)

Thanks, merged.


-Olof



From srinivas.kandagatla at linaro.org  Tue Aug 11 06:54:56 2015
From: srinivas.kandagatla at linaro.org (Srinivas Kandagatla)
Date: Tue, 11 Aug 2015 14:54:56 +0100
Subject: [PATCH V5 2/3] nvmem: add driver for ocotp in i.MX23 and i.MX28
In-Reply-To: <1439299818-8495-3-git-send-email-stefan.wahren@i2se.com>
References: <1439299818-8495-1-git-send-email-stefan.wahren@i2se.com>
 <1439299818-8495-3-git-send-email-stefan.wahren@i2se.com>
Message-ID: <55C9FEB0.2070501@linaro.org>

Hi Stefan,

few nits.

On 11/08/15 14:30, Stefan Wahren wrote:
> This patch brings read-only support for the On-Chip OTP cells
> in the i.MX23 and i.MX28 processor. The driver implements the
> new NVMEM provider API.
>
> Signed-off-by: Stefan Wahren <stefan.wahren at i2se.com>
> ---
>   drivers/nvmem/Kconfig     |   11 ++
>   drivers/nvmem/Makefile    |    2 +
>   drivers/nvmem/mxs-ocotp.c |  252 +++++++++++++++++++++++++++++++++++++++++++++
>   3 files changed, 265 insertions(+)
>   create mode 100644 drivers/nvmem/mxs-ocotp.c
>
> diff --git a/drivers/nvmem/Kconfig b/drivers/nvmem/Kconfig
> index 8db2978..01ff8a6 100644
> --- a/drivers/nvmem/Kconfig
> +++ b/drivers/nvmem/Kconfig
> @@ -36,4 +36,15 @@ config NVMEM_SUNXI_SID
>   	  This driver can also be built as a module. If so, the module
>   	  will be called nvmem_sunxi_sid.
>
> +config NVMEM_MXS_OCOTP
> +	tristate "Freescale MXS On-Chip OTP Memory Support"
> +	depends on ARCH_MXS

Adding COMPILE_TEST here would enable the driver to be compile checked 
on buildrobots.

> +	help
> +	  If you say Y here, you will get readonly access to the
> +	  One Time Programmable memory pages that are stored
> +	  on the Freescale i.MX23/i.MX28 processor.
> +
> +	  This driver can also be built as a module. If so, the module
> +	  will be called nvmem-mxs-ocotp.
> +
>   endif
> diff --git a/drivers/nvmem/Makefile b/drivers/nvmem/Makefile
> index 4328b93..e9b6f3c 100644
> --- a/drivers/nvmem/Makefile
> +++ b/drivers/nvmem/Makefile
> @@ -10,3 +10,5 @@ obj-$(CONFIG_QCOM_QFPROM)	+= nvmem_qfprom.o
>   nvmem_qfprom-y			:= qfprom.o
>   obj-$(CONFIG_NVMEM_SUNXI_SID)	+= nvmem_sunxi_sid.o
>   nvmem_sunxi_sid-y		:= sunxi_sid.o
> +obj-$(CONFIG_NVMEM_MXS_OCOTP)	+= nvmem-mxs-ocotp.o
> +nvmem-mxs-ocotp-y		:= mxs-ocotp.o
> diff --git a/drivers/nvmem/mxs-ocotp.c b/drivers/nvmem/mxs-ocotp.c
> new file mode 100644
> index 0000000..9ee146b
> --- /dev/null
> +++ b/drivers/nvmem/mxs-ocotp.c
> @@ -0,0 +1,252 @@
> +/*
> + * Freescale MXS On-Chip OTP driver
> + *
> + * Copyright (C) 2015 Stefan Wahren <stefan.wahren at i2se.com>
> + *
> + * Based on the driver from Huang Shijie and Christoph G. Baumann
> + *
> + * 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.h>
> +#include <linux/delay.h>
> +#include <linux/device.h>
> +#include <linux/err.h>
> +#include <linux/io.h>
> +#include <linux/module.h>
> +#include <linux/mutex.h>
??
> +#include <linux/nvmem-provider.h>
> +#include <linux/of_address.h>
??
> +#include <linux/of_device.h>
> +#include <linux/platform_device.h>
> +#include <linux/regmap.h>
> +#include <linux/slab.h>
> +#include <linux/stmp_device.h>
> +
> +/* OCOTP registers and bits */
> +
> +#define BM_OCOTP_CTRL_RD_BANK_OPEN	BIT(12)
> +#define BM_OCOTP_CTRL_ERROR		BIT(9)
> +#define BM_OCOTP_CTRL_BUSY		BIT(8)
> +
> +#define OCOTP_TIMEOUT		10000
> +#define OCOTP_DATA_OFFSET	0x20
> +
> +struct mxs_ocotp {
> +	struct clk *clk;
> +	void __iomem *base;
> +	struct nvmem_device *nvmem;
> +};
> +
> +static int mxs_ocotp_wait(struct mxs_ocotp *otp)
> +{
> +	int timeout = OCOTP_TIMEOUT;
> +	unsigned int status = 0;
> +
> +	while (timeout--) {
> +		status = readl(otp->base);
> +
> +		if (!(status & (BM_OCOTP_CTRL_BUSY | BM_OCOTP_CTRL_ERROR)))
> +			break;
> +
> +		cpu_relax();
> +	}
> +
> +	if (status & BM_OCOTP_CTRL_BUSY)
> +		return -EBUSY;
> +	else if (status & BM_OCOTP_CTRL_ERROR)
> +		return -EIO;
> +
> +	return 0;
> +}
> +
> +static int mxs_ocotp_read(void *context, const void *reg, size_t reg_size,
> +			  void *val, size_t val_size)
> +{
> +	struct mxs_ocotp *otp = context;
> +	unsigned int offset = *(u32 *)reg;
> +	u32 *buf = val;
> +	int ret = 0;
> +
> +	writel(BM_OCOTP_CTRL_ERROR, otp->base + STMP_OFFSET_REG_CLR);
> +
> +	ret = mxs_ocotp_wait(otp);
> +	if (ret)
> +		return ret;
> +
> +	/* open OCOTP banks for read */
> +	writel(BM_OCOTP_CTRL_RD_BANK_OPEN, otp->base + STMP_OFFSET_REG_SET);
> +
> +	/* approximately wait 33 hclk cycles */
> +	udelay(1);
> +
> +	ret = mxs_ocotp_wait(otp);
> +	if (ret)
> +		goto close_banks;
> +
> +	while (val_size) {
> +		if ((offset < OCOTP_DATA_OFFSET) || (offset % 16)) {
> +			/* fill up non-data register */
> +			*buf = 0;
> +		} else {
> +			*buf = readl(otp->base + offset);
> +		}
> +
> +		buf++;
> +		val_size--;
> +		offset += reg_size;
> +	}
> +
> +close_banks:
> +	/* close banks for power saving */
> +	writel(BM_OCOTP_CTRL_RD_BANK_OPEN, otp->base + STMP_OFFSET_REG_CLR);
> +
> +	return ret;
> +}
> +
> +static int mxs_ocotp_write(void *context, const void *data, size_t count)
> +{
> +	/* We don't want to support writing */
> +	return 0;
> +}
> +
> +static bool mxs_ocotp_writeable_reg(struct device *dev, unsigned int reg)
> +{
> +	return false;
> +}
> +
> +static struct nvmem_config ocotp_config = {
> +	.name = "mxs-ocotp",
> +	.owner = THIS_MODULE,
> +};
> +
> +static const struct regmap_range imx23_ranges[] = {
> +	regmap_reg_range(OCOTP_DATA_OFFSET, 0x210),
> +};
> +
> +static const struct regmap_access_table imx23_access = {
> +	.yes_ranges = imx23_ranges,
> +	.n_yes_ranges = ARRAY_SIZE(imx23_ranges),
> +};
> +
> +static const struct regmap_range imx28_ranges[] = {
> +	regmap_reg_range(OCOTP_DATA_OFFSET, 0x290),
> +};
> +
> +static const struct regmap_access_table imx28_access = {
> +	.yes_ranges = imx28_ranges,
> +	.n_yes_ranges = ARRAY_SIZE(imx28_ranges),
> +};
> +
> +static struct regmap_bus mxs_ocotp_bus = {
> +	.read = mxs_ocotp_read,
> +	.write = mxs_ocotp_write, /* make regmap_init() happy */
> +	.reg_format_endian_default = REGMAP_ENDIAN_NATIVE,
> +	.val_format_endian_default = REGMAP_ENDIAN_NATIVE,
> +};
> +
> +static struct regmap_config mxs_ocotp_config = {
> +	.reg_bits = 32,
> +	.val_bits = 32,
> +	.reg_stride = 16,
> +	.writeable_reg = mxs_ocotp_writeable_reg,
> +};
> +
> +static const struct of_device_id mxs_ocotp_match[] = {
> +	{ .compatible = "fsl,imx23-ocotp", .data = &imx23_access },
> +	{ .compatible = "fsl,imx28-ocotp", .data = &imx28_access },
> +	{ /* sentinel */},
> +};
> +MODULE_DEVICE_TABLE(of, mxs_ocotp_match);
> +
> +static int mxs_ocotp_probe(struct platform_device *pdev)
> +{
> +	struct device *dev = &pdev->dev;
> +	struct mxs_ocotp *otp;
> +	struct resource *res;
> +	const struct of_device_id *match;
> +	struct regmap *regmap;
> +	const struct regmap_access_table *access;
> +	int ret;
> +
> +	match = of_match_device(dev->driver->of_match_table, dev);
> +	if (!match || !match->data)
> +		return -EINVAL;
> +
> +	otp = devm_kzalloc(dev, sizeof(*otp), GFP_KERNEL);
> +	if (!otp)
> +		return -ENOMEM;
> +
> +	res = platform_get_resource(pdev, IORESOURCE_MEM, 0);
> +	otp->base = devm_ioremap_resource(dev, res);
> +	if (IS_ERR(otp->base))
> +		return PTR_ERR(otp->base);
> +
> +	otp->clk = devm_clk_get(&pdev->dev, NULL);
> +	if (IS_ERR(otp->clk))
> +		return PTR_ERR(otp->clk);
> +
> +	ret = clk_prepare(otp->clk);
> +	if (ret < 0) {
> +		dev_err(dev, "failed to prepare clk: %d\n", ret);
> +		return ret;
> +	}

Clk prepare will not really enable the clock, and I dont see a call to 
clk_enable() anywhere in this driver.

I dont see the point?

> +
> +	access = match->data;
> +	mxs_ocotp_config.rd_table = access;
> +	mxs_ocotp_config.max_register = access->yes_ranges[0].range_max;
> +
> +	regmap = devm_regmap_init(dev, &mxs_ocotp_bus, otp, &mxs_ocotp_config);
> +	if (IS_ERR(regmap)) {
> +		dev_err(dev, "regmap init failed\n");
> +		ret = PTR_ERR(regmap);
> +		goto err_clk;
> +	}
> +
> +	ocotp_config.dev = dev;
> +	otp->nvmem = nvmem_register(&ocotp_config);
> +	if (IS_ERR(otp->nvmem)) {
> +		ret = PTR_ERR(otp->nvmem);
> +		goto err_clk;
> +	}
> +
> +	platform_set_drvdata(pdev, otp);
> +
> +	return 0;
> +
> +err_clk:
> +	clk_unprepare(otp->clk);
> +
> +	return ret;
> +}
> +
> +static int mxs_ocotp_remove(struct platform_device *pdev)
> +{
> +	struct mxs_ocotp *otp = platform_get_drvdata(pdev);
> +
> +	clk_unprepare(otp->clk);
> +
> +	return nvmem_unregister(otp->nvmem);
> +}
> +
> +static struct platform_driver mxs_ocotp_driver = {
> +	.probe = mxs_ocotp_probe,
> +	.remove = mxs_ocotp_remove,
> +	.driver = {
> +		.name = "mxs-ocotp",
> +		.of_match_table = mxs_ocotp_match,
> +	},
> +};
> +
> +module_platform_driver(mxs_ocotp_driver);
> +MODULE_AUTHOR("Stefan Wahren <stefan.wahren at i2se.com>");
> +MODULE_DESCRIPTION("driver for OCOTP in i.MX23/i.MX28");
> +MODULE_LICENSE("GPL");

GPL v2??

>


From maxime.coquelin at st.com  Tue Aug 11 06:56:45 2015
From: maxime.coquelin at st.com (Maxime Coquelin)
Date: Tue, 11 Aug 2015 15:56:45 +0200
Subject: [PATCH 2/2] drm: sti: adapt DT to fix probe/bind issues in DRM
 driver
In-Reply-To: <55A8EC3F.6050903@st.com>
References: <1437133510-13615-1-git-send-email-benjamin.gaignard@linaro.org>
 <1437133510-13615-2-git-send-email-benjamin.gaignard@linaro.org>
 <55A8EC3F.6050903@st.com>
Message-ID: <55C9FF1D.8050702@st.com>

Hi Olof,

On 07/17/2015 01:51 PM, Maxime Coquelin wrote:
> Dear ARM SoC Maintainers,
>
> On 07/17/2015 01:45 PM, Benjamin Gaignard wrote:
>> STI drm drivers probe and bind using component framework was incorrect.
>> In addition to drivers fix DT update is needed to make all 
>> sub-components
>> become childs of sti-display-subsystem.
>>
>> Signed-off-by: Benjamin Gaignard <benjamin.gaignard at linaro.org>
>> ---
>>   arch/arm/boot/dts/stih407.dtsi | 82 
>> +++++++++++++++++++++---------------------
>>   arch/arm/boot/dts/stih410.dtsi | 82 
>> +++++++++++++++++++++---------------------
>>   2 files changed, 80 insertions(+), 84 deletions(-)
>>
>>
>
> This patch solves an issue preventing DRM driver probing, but it 
> breaks the DT ABI.
> For now, this driver and its DT node are only used by a few identified 
> people.
>
> Since these people only use aligned version of Kernel and DT, do you 
> accept we break the ABI for this time?
>

Just a gentle reminder.
Can we derogate for this patch?

Thanks in advance,
Maxime


From olof at lixom.net  Tue Aug 11 06:42:49 2015
From: olof at lixom.net (Olof Johansson)
Date: Tue, 11 Aug 2015 15:42:49 +0200
Subject: [GIT PULL] Renesas ARM Based SoC CPG MSTP Clock Domain Updates
 for v4.3
In-Reply-To: <cover.1438911559.git.horms+renesas@verge.net.au>
References: <cover.1438911559.git.horms+renesas@verge.net.au>
Message-ID: <20150811134249.GQ30181@localhost>

On Fri, Aug 07, 2015 at 11:12:03AM +0900, Simon Horman wrote:
> Hi Olof, Hi Kevin, Hi Arnd,
> 
> Please consider these Renesas ARM based SoC CPG MSTP clock domain updates
> for v4.3.
> 
> This pull request is based on "Third Round of Renesas ARM Based SoC DT
> Updates for v4.3", tagged as renesas-dt3-for-v4.3, which I have also sent a
> pull-request for.
> 
> The reason for that base is that the DT changes in this series update nodes
> added in that tag.
> 
> This series begins with driver changes and follows up with DT changes.
> The latter depend on the former.
> 
> 
> The following changes since commit 94bdc48d55ca10f90b4a625f0e443197e0013557:
> 
>   ARM: shmobile: sh73a0 dtsi: Add missing "gpio-ranges" to gpio node (2015-08-05 06:39:28 +0900)
> 
> are available in the git repository at:
> 
>   git://git.kernel.org/pub/scm/linux/kernel/git/horms/renesas.git tags/renesas-cpg-mstp-clock-domain-for-v4.3
> 
> for you to fetch changes up to 2daa8a5a8c0994893c2ca456303f0bf53e881cb9:
> 
>   ARM: shmobile: r8a7794 dtsi: Add CPG/MSTP Clock Domain (2015-08-05 06:42:51 +0900)

We normally prefer to see drivers separately from DT. If you've looked at how
we organize arm-soc, you've maybe seen that we have a separate topic for
next/driver and one for next/dt. In other words, we try to keep them apart
where it makes sense.

In this case, that would mean having the clk changes in a drivers branch, and
include that in this dt4 branch.

If you want a reminder for when you might have looked at the branch sorting
wrong: If you're naming the branch after a feature instead of the type of
patches in it (when you send it to us), then chances are that we would ideally
like to see the contents sorted differently -- at least in the cases where they
cross the category boundaries that we organize our tree in.

So, while it's not a huge deal I think it makes sense to revisit this
and do that sorting for consistency's sake. Can I please ask that you
respin this pull request with that in mind? I'd cherry-pick them apart
but I know you tend to base branches on each other so that might mess
you up and I don't want to do that.


Thanks,


-Olof


From olof at lixom.net  Tue Aug 11 06:24:17 2015
From: olof at lixom.net (Olof Johansson)
Date: Tue, 11 Aug 2015 15:24:17 +0200
Subject: [GIT PULL] omap dts changes for v4.3 merge window, part 3
In-Reply-To: <20150806104516.GF4215@atomide.com>
References: <20150806104516.GF4215@atomide.com>
Message-ID: <20150811132417.GM30181@localhost>

On Thu, Aug 06, 2015 at 03:45:16AM -0700, Tony Lindgren wrote:
> The following changes since commit f5887fe5d14181aef0653ab04f60988252d42461:
> 
>   ARM: OMAP2+: Add custom abort handler for t410 (2015-07-23 22:33:19 -0700)
> 
> are available in the git repository at:
> 
>   git://git.kernel.org/pub/scm/linux/kernel/git/tmlind/linux-omap tags/omap-for-v4.3/dt-pt3
> 
> for you to fetch changes up to ed05637c30e6d13e5793aab64d6a6e57e30228af:
> 
>   ARM: dts: omap3-devkit8000: Add ADS7846 Touchscreen support (2015-08-06 02:43:09 -0700)

Thanks, merged.


-Olof



From olof at lixom.net  Tue Aug 11 06:32:17 2015
From: olof at lixom.net (Olof Johansson)
Date: Tue, 11 Aug 2015 15:32:17 +0200
Subject: [GIT PULL] Third Round of Renesas ARM Based SoC DT Updates for
 v4.3
In-Reply-To: <cover.1438911334.git.horms+renesas@verge.net.au>
References: <cover.1438911334.git.horms+renesas@verge.net.au>
Message-ID: <20150811133217.GO30181@localhost>

On Fri, Aug 07, 2015 at 11:11:31AM +0900, Simon Horman wrote:
> Hi Olof, Hi Kevin, Hi Arnd,
> 
> Please consider these third round of Renesas ARM based SoC DT updates for v4.3.
> 
> This pull request is based on the previous round of
> such requests, tagged as renesas-dt2-for-v4.3,
> which I have already sent a pull-request for.
> 
> 
> The following changes since commit 7fd6e11dca09b21efbe2b9db4eff08c8f4a16125:
> 
>   ARM: shmobile: r8a7791: Add Audio MIX support on DTSI (2015-07-22 09:36:49 +0900)
> 
> are available in the git repository at:
> 
>   git://git.kernel.org/pub/scm/linux/kernel/git/horms/renesas.git tags/renesas-dt3-for-v4.3
> 
> for you to fetch changes up to 94bdc48d55ca10f90b4a625f0e443197e0013557:
> 
>   ARM: shmobile: sh73a0 dtsi: Add missing "gpio-ranges" to gpio node (2015-08-05 06:39:28 +0900)

Merged, thanks.


-Olof


From viresh.kumar at linaro.org  Tue Aug 11 07:07:47 2015
From: viresh.kumar at linaro.org (Viresh Kumar)
Date: Tue, 11 Aug 2015 19:37:47 +0530
Subject: [PATCH] ARM/EP93xx/timer: Migrate to new 'set-state' interface
In-Reply-To: <20150811131924.GJ30181@localhost>
References: <744dca162a7626694770a9f51457566a33c3e08f.1438852023.git.viresh.kumar@linaro.org>
 <CACRpkdZknzqgH+-F0MZgZywtoOL1hhbg=7w1RSC5aZohXtDB3A@mail.gmail.com>
 <20150810090334.GB5766@linux> <20150811131924.GJ30181@localhost>
Message-ID: <20150811140747.GI5509@linux>

On 11-08-15, 15:19, Olof Johansson wrote:
> Latest? We don't base our tree on the latest -- instead we try to keep
> back on -rc2/3 if we can. Right now our tree is on -rc2.
> 
> 
> Please confirm that this is still OK to merge with that as base. Thanks.

Yeah, rc2 should be fine.

-- 
viresh


From lee.jones at linaro.org  Tue Aug 11 07:17:55 2015
From: lee.jones at linaro.org (Lee Jones)
Date: Tue, 11 Aug 2015 15:17:55 +0100
Subject: [PATCH v4 1/2] mfd: axp20x: Add missing registers, and mark more
 registers volatile
In-Reply-To: <1439049521-30766-1-git-send-email-hdegoede@redhat.com>
References: <1439049521-30766-1-git-send-email-hdegoede@redhat.com>
Message-ID: <20150811141754.GL18282@x1>

On Sat, 08 Aug 2015, Hans de Goede wrote:

> From: Bruno Pr?mont <bonbons at linux-vserver.org>
> 
> Add an extra set of registers which is necessary tu support the PMICs
> battery charger function, and mark registers which contain status bits,
> gpio status, and adc readings as volatile.
> 
> Cc: Bruno Pr?mont <bonbons at linux-vserver.org>
> Signed-off-by: Bruno Pr?mont <bonbons at linux-vserver.org>
> Signed-off-by: Hans de Goede <hdegoede at redhat.com>
> Acked-by: Lee Jones <lee.jones at linaro.org>
> Acked-by: Maxime Ripard <maxime.ripard at free-electrons.com>
> ---
> Changes in v2:
> -Add a AXP20X_OCV_MAX define
> Changes in v3:
> -Add Bruno's S-o-b
> Changes in v4:
> -Consistently use AXP20X_OCV_MAX everywhere
> ---
>  drivers/mfd/axp20x.c       | 8 +++++++-
>  include/linux/mfd/axp20x.h | 6 ++++++
>  2 files changed, 13 insertions(+), 1 deletion(-)

Applied, thanks.

> diff --git a/drivers/mfd/axp20x.c b/drivers/mfd/axp20x.c
> index b369cfc..d9f2f96 100644
> --- a/drivers/mfd/axp20x.c
> +++ b/drivers/mfd/axp20x.c
> @@ -61,10 +61,16 @@ static const struct regmap_access_table axp152_volatile_table = {
>  static const struct regmap_range axp20x_writeable_ranges[] = {
>  	regmap_reg_range(AXP20X_DATACACHE(0), AXP20X_IRQ5_STATE),
>  	regmap_reg_range(AXP20X_DCDC_MODE, AXP20X_FG_RES),
> +	regmap_reg_range(AXP20X_RDC_H, AXP20X_OCV(AXP20X_OCV_MAX)),
>  };
>  
>  static const struct regmap_range axp20x_volatile_ranges[] = {
> +	regmap_reg_range(AXP20X_PWR_INPUT_STATUS, AXP20X_USB_OTG_STATUS),
> +	regmap_reg_range(AXP20X_CHRG_CTRL1, AXP20X_CHRG_CTRL2),
>  	regmap_reg_range(AXP20X_IRQ1_EN, AXP20X_IRQ5_STATE),
> +	regmap_reg_range(AXP20X_ACIN_V_ADC_H, AXP20X_IPSOUT_V_HIGH_L),
> +	regmap_reg_range(AXP20X_GPIO20_SS, AXP20X_GPIO3_CTRL),
> +	regmap_reg_range(AXP20X_FG_RES, AXP20X_RDC_L),
>  };
>  
>  static const struct regmap_access_table axp20x_writeable_table = {
> @@ -195,7 +201,7 @@ static const struct regmap_config axp20x_regmap_config = {
>  	.val_bits	= 8,
>  	.wr_table	= &axp20x_writeable_table,
>  	.volatile_table	= &axp20x_volatile_table,
> -	.max_register	= AXP20X_FG_RES,
> +	.max_register	= AXP20X_OCV(AXP20X_OCV_MAX),
>  	.cache_type	= REGCACHE_RBTREE,
>  };
>  
> diff --git a/include/linux/mfd/axp20x.h b/include/linux/mfd/axp20x.h
> index 52203d5..cc8ad1e 100644
> --- a/include/linux/mfd/axp20x.h
> +++ b/include/linux/mfd/axp20x.h
> @@ -190,6 +190,12 @@ enum {
>  #define AXP20X_CC_CTRL			0xb8
>  #define AXP20X_FG_RES			0xb9
>  
> +/* OCV */
> +#define AXP20X_RDC_H			0xba
> +#define AXP20X_RDC_L			0xbb
> +#define AXP20X_OCV(m)			(0xc0 + (m))
> +#define AXP20X_OCV_MAX			0xf
> +
>  /* AXP22X specific registers */
>  #define AXP22X_BATLOW_THRES1		0xe6
>  

-- 
Lee Jones
Linaro STMicroelectronics Landing Team Lead
Linaro.org ? Open source software for ARM SoCs
Follow Linaro: Facebook | Twitter | Blog


From lee.jones at linaro.org  Tue Aug 11 07:18:11 2015
From: lee.jones at linaro.org (Lee Jones)
Date: Tue, 11 Aug 2015 15:18:11 +0100
Subject: [PATCH v4 2/2] mfd: axp20x: Add a cell for the usb power_supply
 part of the axp20x PMICs
In-Reply-To: <1439049521-30766-2-git-send-email-hdegoede@redhat.com>
References: <1439049521-30766-1-git-send-email-hdegoede@redhat.com>
 <1439049521-30766-2-git-send-email-hdegoede@redhat.com>
Message-ID: <20150811141811.GM18282@x1>

On Sat, 08 Aug 2015, Hans de Goede wrote:

> Add a cell for the usb power_supply part of the axp20x PMICs.
> 
> Note that this cell is only for the usb power_supply part and not the
> ac-power / battery-charger / rtc-backup-bat-charger bits.
> 
> Depending on the board each of those must be enabled / disabled separately
> in devicetree as most boards do not use all 4. So in dt each one needs its
> own child-node of the axp20x node. Another reason for using separate child
> nodes for each is so that other devicetree nodes can have a power-supply
> property with a phandle referencing a node representing a single
> power-supply.
> 
> The decision to use a separate devicetree node for each is reflected on
> the kernel side by each getting its own mfd-cell / platform_device and
> platform-driver.
> 
> Note this commit also makes some whitespace changes to the intialization
> of existing cells in axp20x_cells, these are pure whitespace changes,
> functionally nothing changes.
> 
> Cc: Bruno Pr?mont <bonbons at linux-vserver.org>
> Signed-off-by: Bruno Pr?mont <bonbons at linux-vserver.org>
> Signed-off-by: Hans de Goede <hdegoede at redhat.com>
> Acked-by: Maxime Ripard <maxime.ripard at free-electrons.com>
> Acked-by: Lee Jones <lee.jones at linaro.org>
> ---
> Changes in v2:
> -Use DEFINE_RES_IRQ_NAMED
> -Change indentation of axp20x_cells initializers to avoid line wrapping
> Changes in v3:
> -Improve commit message
> -Add Bruno's S-o-b
> ---
>  drivers/mfd/axp20x.c | 20 ++++++++++++++++----
>  1 file changed, 16 insertions(+), 4 deletions(-)

Applied, thanks.

> diff --git a/drivers/mfd/axp20x.c b/drivers/mfd/axp20x.c
> index d9f2f96..3f576b7 100644
> --- a/drivers/mfd/axp20x.c
> +++ b/drivers/mfd/axp20x.c
> @@ -140,6 +140,13 @@ static struct resource axp20x_pek_resources[] = {
>  	},
>  };
>  
> +static struct resource axp20x_usb_power_supply_resources[] = {
> +	DEFINE_RES_IRQ_NAMED(AXP20X_IRQ_VBUS_PLUGIN, "VBUS_PLUGIN"),
> +	DEFINE_RES_IRQ_NAMED(AXP20X_IRQ_VBUS_REMOVAL, "VBUS_REMOVAL"),
> +	DEFINE_RES_IRQ_NAMED(AXP20X_IRQ_VBUS_VALID, "VBUS_VALID"),
> +	DEFINE_RES_IRQ_NAMED(AXP20X_IRQ_VBUS_NOT_VALID, "VBUS_NOT_VALID"),
> +};
> +
>  static struct resource axp22x_pek_resources[] = {
>  	{
>  		.name   = "PEK_DBR",
> @@ -432,11 +439,16 @@ static const struct regmap_irq_chip axp288_regmap_irq_chip = {
>  
>  static struct mfd_cell axp20x_cells[] = {
>  	{
> -		.name			= "axp20x-pek",
> -		.num_resources		= ARRAY_SIZE(axp20x_pek_resources),
> -		.resources		= axp20x_pek_resources,
> +		.name		= "axp20x-pek",
> +		.num_resources	= ARRAY_SIZE(axp20x_pek_resources),
> +		.resources	= axp20x_pek_resources,
>  	}, {
> -		.name			= "axp20x-regulator",
> +		.name		= "axp20x-regulator",
> +	}, {
> +		.name		= "axp20x-usb-power-supply",
> +		.of_compatible	= "x-powers,axp202-usb-power-supply",
> +		.num_resources	= ARRAY_SIZE(axp20x_usb_power_supply_resources),
> +		.resources	= axp20x_usb_power_supply_resources,
>  	},
>  };
>  

-- 
Lee Jones
Linaro STMicroelectronics Landing Team Lead
Linaro.org ? Open source software for ARM SoCs
Follow Linaro: Facebook | Twitter | Blog


From catalin.marinas at arm.com  Tue Aug 11 07:23:01 2015
From: catalin.marinas at arm.com (Catalin Marinas)
Date: Tue, 11 Aug 2015 15:23:01 +0100
Subject: [RFC PATCH 01/10] arm64: feature registers: Documentation
In-Reply-To: <CAKv+Gu-9GTzjqyT=NeBKjcaL7q-uFMToqPpprkyD-faG0J3mkQ@mail.gmail.com>
References: <1437731037-25795-1-git-send-email-suzuki.poulose@arm.com>
 <1437731037-25795-2-git-send-email-suzuki.poulose@arm.com>
 <20150810160636.GB15394@e104818-lin.cambridge.arm.com>
 <55C8E12E.6030305@arm.com>
 <CAKv+Gu-9GTzjqyT=NeBKjcaL7q-uFMToqPpprkyD-faG0J3mkQ@mail.gmail.com>
Message-ID: <20150811142301.GE23307@e104818-lin.cambridge.arm.com>

On Mon, Aug 10, 2015 at 07:48:48PM +0200, Ard Biesheuvel wrote:
> > On 10/08/15 17:06, Catalin Marinas wrote:
> >> And to debunk some of the counter arguments:
> >>
> >> a) Running out of HWCAP bits - I really doubt this, we can always
> >>     introduce 64 more via a new elf_hwcapX
> 
> Note that ELF_HWCAP is also wired into ifunc resolution of GNU
> indirect functions, which looks like a useful feature although it
> isn't used that widely yet.

I forgot to mention, we also need an HWCAP_CPUID with these patches when
we expose the MRS interface. The ifunc resolver could use MRS when
available. But I would still keep adding HWCAP bits for new features,
even if we risk running out of the 64-bit we have now.

> The ifunc prototype for aarch64 has only one 'long' parameter, and I
> don't know if it is possible to extend that without having a bit in
> HWCAPn to indicate that HWCAPn+1 is valid. Also, the ifunc resolvers
> are restricted in the sense that they cannot use shared libraries or
> code that uses constructors (AFAIR) so it may require a special static
> library to call this CPU feature interface from such a resolver if
> features are not covered by HWCAP bits.

Or we could get some compiler intrinsics that generate the instruction
inline, just to avoid explicit asm.

> So treating HWCAP bits as an endless supply may not be the wisest
> approach here.

Probably not for ifunc, otherwise I don't think it hurts.

> Also, I think some alignment with the libc folks is indeed in order.

I agree (not sure how they feel about cross-posting though).

-- 
Catalin


From sjg at chromium.org  Tue Aug 11 07:25:53 2015
From: sjg at chromium.org (Simon Glass)
Date: Tue, 11 Aug 2015 08:25:53 -0600
Subject: [PATCH] arm: rpi: Device tree modifications for U-Boot
Message-ID: <1439303153-12171-1-git-send-email-sjg@chromium.org>

This updates the device tree from the kernel version to something suitable
for U-Boot:

- Add stdout-path alias for console
- Mark the /soc node to be available pre-relocation so that the early
serial console works (we need the 'ranges' property to be available)

Signed-off-by: Simon Glass <sjg at chromium.org>
---

 arch/arm/boot/dts/bcm2835.dtsi | 4 +++-
 1 file changed, 3 insertions(+), 1 deletion(-)

diff --git a/arch/arm/boot/dts/bcm2835.dtsi b/arch/arm/boot/dts/bcm2835.dtsi
index 301c73f..bd6bff6 100644
--- a/arch/arm/boot/dts/bcm2835.dtsi
+++ b/arch/arm/boot/dts/bcm2835.dtsi
@@ -8,6 +8,7 @@
 
 	chosen {
 		bootargs = "earlyprintk console=ttyAMA0";
+		stdout-path = &uart;
 	};
 
 	soc {
@@ -16,6 +17,7 @@
 		#size-cells = <1>;
 		ranges = <0x7e000000 0x20000000 0x02000000>;
 		dma-ranges = <0x40000000 0x00000000 0x20000000>;
+		u-boot,dm-pre-reloc;
 
 		timer at 7e003000 {
 			compatible = "brcm,bcm2835-system-timer";
@@ -92,7 +94,7 @@
 			#interrupt-cells = <2>;
 		};
 
-		uart at 7e201000 {
+		uart: uart at 7e201000 {
 			compatible = "brcm,bcm2835-pl011", "arm,pl011", "arm,primecell";
 			reg = <0x7e201000 0x1000>;
 			interrupts = <2 25>;
-- 
2.5.0.rc2.392.g76e840b



From viresh.kumar at linaro.org  Tue Aug 11 07:28:12 2015
From: viresh.kumar at linaro.org (Viresh Kumar)
Date: Tue, 11 Aug 2015 19:58:12 +0530
Subject: [PATCH v4 2/2] dt: power: st: Provide bindings for ST's OPPs
In-Reply-To: <20150811132756.GG18282@x1>
References: <CAL_JsqKQLQ15qSt95zBZykzzPhcUrtZzhk29a76n+r_3719AiA@mail.gmail.com>
 <20150731163715.GV3159@codeaurora.org> <20150803034642.GV899@linux>
 <20150810132247.GH3249@x1> <20150811080023.GB5509@linux>
 <20150811093039.GA18282@x1> <20150811100941.GG5509@linux>
 <20150811115425.GE18282@x1> <20150811120124.GH5509@linux>
 <20150811132756.GG18282@x1>
Message-ID: <20150811142812.GJ5509@linux>

On 11-08-15, 14:27, Lee Jones wrote:
> Okay, so what you're saying is that you've already made the decision
> to create a separate node for every OPP permutation,

Absolutely not.

> despite the fact
> that I've told you this could lead to more nodes than anyone would
> care to successfully write or maintain?

I have enough fear of yours and then I have to see you in another
month as well. I wouldn't dare to disobey your command SIR :)

> Perhaps an example might help explain the issue.
> 
> Using the current driver, we need to place the following in DT and the
> driver does the rest:
> 
> opp-list {
> 	opp1 {
> 		opp-hz = <1500000000>;
> 		st,avs = <1200 1200 1200 1200 1170 1140 1100 1070>;
> 		st,substrate = <0xff>;
> 		st,cuts = <0xff>;
> 	};
> 	opp0 {
> 		opp-hz = <1200000000>;
> 		st,avs = <1110 1150 1100 1080 1040 1020 980 930>;
> 		st,substrate = <0xff>;
> 		st,cuts = <0x2>;
> 	};
> };

Nothing is fixed as of now but this is what I am thinking of:

	cpu0_opp_table: opp_table0 {
		compatible = "operating-points-v2";
                opp-cuts = "10", "3c", "f0";
		supply-names = "vcc0", "vcc1", "vcc2";
		opp-shared;

		opp00 {
			opp-hz = /bits/ 64 <1000000000>;
			clock-latency-ns = <300000>;
			opp-microvolt-10 = <970000>;
			opp-microvolt-3c = <950000>;
			opp-microvolt-f0 = <930000>;
		};

		/* OR */

		opp00 {
			opp-hz = /bits/ 64 <1000000000>;
			clock-latency-ns = <300000>;
                        opp-microvolt = <970000>, <950000>, <930000>;
		};
        };

And then the platform code needs to tell OPP layer:
"Use OPPs for cut f0 for device X", and OPP layer will store that
somewhere.

And then it will only initialize OPPs after matching this string with
the values.

Out of the earlier two options, I may prefer the first one. As we will
be soon adding support for multiple regulators, and a single regulator
can have min/max/target values.. So, a single list will become too
long.

But, something like this should be generic enough to capture most of
the cases.

@Stephen/Rob ??

-- 
viresh


From rmk+kernel at arm.linux.org.uk  Tue Aug 11 07:32:33 2015
From: rmk+kernel at arm.linux.org.uk (Russell King)
Date: Tue, 11 Aug 2015 15:32:33 +0100
Subject: [PATCH] ARM: make highpte an expert option
Message-ID: <E1ZPAbR-00005g-Op@rmk-PC.arm.linux.org.uk>

When highmem is enabled, there's little reason not to also enable
highpte support as well.  Rather than leaving this to chance, make
it an expert option, and default it to be enabled if highmem is
enabled.

Signed-off-by: Russell King <rmk+kernel at arm.linux.org.uk>
---
 arch/arm/Kconfig | 3 ++-
 1 file changed, 2 insertions(+), 1 deletion(-)

diff --git a/arch/arm/Kconfig b/arch/arm/Kconfig
index adf2412ba4d4..f418885d9c3d 100644
--- a/arch/arm/Kconfig
+++ b/arch/arm/Kconfig
@@ -1708,8 +1708,9 @@ config HIGHMEM
 	  If unsure, say n.
 
 config HIGHPTE
-	bool "Allocate 2nd-level pagetables from highmem"
+	bool "Allocate 2nd-level pagetables from highmem" if EXPERT
 	depends on HIGHMEM
+	default y
 	help
 	  The VM uses one page of physical memory for each page table.
 	  For systems with a lot of processes, this can use a lot of
-- 
2.1.0



From marc.zyngier at arm.com  Tue Aug 11 07:33:38 2015
From: marc.zyngier at arm.com (Marc Zyngier)
Date: Tue, 11 Aug 2015 15:33:38 +0100
Subject: [PATCH] ARM: OMAP: irqdomain_hierarchy: fix arm gic irq type
 configuration
In-Reply-To: <55C9E78D.7040404@ti.com>
References: <1439285147-20027-1-git-send-email-grygorii.strashko@ti.com>
 <20150811122456.1efe1656@arm.com> <55C9E78D.7040404@ti.com>
Message-ID: <20150811153338.7e67e6ba@arm.com>

On Tue, 11 Aug 2015 13:16:13 +0100
Grygorii Strashko <grygorii.strashko at ti.com> wrote:

> On 08/11/2015 02:24 PM, Marc Zyngier wrote:
> > On Tue, 11 Aug 2015 10:25:47 +0100
> > Grygorii Strashko <grygorii.strashko at ti.com> wrote:
> >
> > Hi Grygorii,
> >
> >> It's observed that ARM GIC IRQ triggering type is not configured
> >> properly when IRQ is routed through IRQ domains hierarchy and
> >> system started using DT. As result, system will start using default
> >> ARM GIC configuration, ignore DT IRQ type configuration,
> >> and value of desc->irq_data.state_use_accessors = 0.
> >>
> >> In case of TI OMAP the following IRQ hierarchy is defined:
> >> ARM GIC <- OMAP wakeupgen <- TI CBAR
> >>
> >> Failed call chain:
> >>   irq_create_of_mapping
> >>   irq_set_irq_type
> >>   __irq_set_trigger
> >>   if (!chip || !chip->irq_set_type) {
> >>      return 0; <- return here
> >>   }
> >>   CBAR has no .irq_set_type() defined and, so, IRQ triggering
> >>   configuration will not be propagated to parent IRQ domain.
> >>
> >> Hence, fix it by introducing irq_chip_set_type_parent(), in the
> >> same manner as irq_chip_set_wake_parent(), and use it for IRQ
> >> triggering type propagation to the parent IRQ domain in
> >> irq-crossbar and omap-wakeupgen.
> >>
> >> / # cat /proc/interrupts -- before
> >> 230:          0          0      CBAR  30 Edge    -00000000  48051000.gpio
> >> 263:          0          0      CBAR 116 Edge    -00000000  48053000.gpio
> >> 296:        246          0      CBAR  67 Edge    -00000000  OMAP UART0
> >> 311:        341          0      CBAR  51 Edge    -00000000  48070000.i2c
> >> 312:          3          0      CBAR  52 Edge    -00000000  48072000.i2c
> >> 313:          0          0      CBAR  56 Edge    -00000000  48060000.i2c
> >> 314:        255          0      CBAR  78 Edge    -00000000  mmc0
> >> 315:         40          0      CBAR  81 Edge    -00000000  mmc1
> >> 316:         13          0      CBAR  91 Edge    -00000000  mmc2
> >> 320:          0          0      CBAR  49 Edge    -00000000  4a140000.sata
> >> 324:          0          0      CBAR   1 Edge    -00000000  48078000.elm
> >> 325:          0          0      CBAR  15 Edge    -00000000  gpmc
> >> 333:          0          0      CBAR 335 Edge    -00000000  48484000.ethernet
> >> 334:          0          0      CBAR 336 Edge    -00000000  48484000.ethernet
> >> 415:          0          0   pcf857x   2 Edge    -00000000  btnUser1
> >> 416:          0          0   pcf857x   3 Edge    -00000000  btnUser2
> >> 445:          0          0   pinctrl 992 Edge    -00010000  4806a000.seria
> >>
> >> / # cat /proc/interrupts -- after
> >> 230:          0          0      CBAR  30 Level   -00002004  48051000.gpio
> >> 263:          0          0      CBAR 116 Level   -00002004  48053000.gpio
> >> 296:        567          0      CBAR  67 Level   -00002004  OMAP UART0
> >> 311:        363          0      CBAR  51 Level   -00002004  48070000.i2c
> >> 312:          3          0      CBAR  52 Level   -00002004  48072000.i2c
> >> 313:          0          0      CBAR  56 Level   -00002004  48060000.i2c
> >> 314:        197          0      CBAR  78 Level   -00002004  mmc0
> >> 315:         40          0      CBAR  81 Level   -00002004  mmc1
> >> 316:         13          0      CBAR  91 Level   -00002004  mmc2
> >> 320:          0          0      CBAR  49 Level   -00002004  4a140000.sata
> >> 324:          0          0      CBAR   1 Level   -00002004  48078000.elm
> >> 325:          0          0      CBAR  15 Level   -00002004  gpmc
> >> 333:          0          0      CBAR 335 Level   -00002004  48484000.ethernet
> >> 334:          0          0      CBAR 336 Level   -00002004  48484000.ethernet
> >> 415:          0          0   pcf857x   2 Edge    -00000000  btnUser1
> >> 416:          4          2   pcf857x   3 Edge    -00000000  btnUser2
> >> 445:          0          0   pinctrl 992 Edge    -00010000  4806a000.serial
> >>
> >> Fixes: 783d31863fb8 ('irqchip: crossbar: Convert dra7 crossbar to stacked domains')
> >> Signed-off-by: Grygorii Strashko <grygorii.strashko at ti.com>
> >> ---
> >> Hi All,
> >>
> >> I can split patch if required and overall solution acceptable.
> >
> > This looks good to me. Please repost it after splitting it in two
> > patches.
> 
> just to clarify - Do you want to see two or three patches?
> 
> 2) or 3) arch/arm/mach-omap2/omap-wakeupgen.c |  1 +
> 2) drivers/irqchip/irq-crossbar.c       |  1 +
> 1) include/linux/irq.h                  |  1 +
> 1) kernel/irq/chip.c                    | 16 ++++++++++++++++

Ah, I forgot wakeupgen lived in the omap-specific directory.

Please cut it in 3 then (generic implementation, crossbar and
wakeupgen).

Thanks,

	M.


-- 
Jazz is not dead. It just smells funny.


From dann.frazier at canonical.com  Tue Aug 11 07:36:57 2015
From: dann.frazier at canonical.com (Dann Frazier)
Date: Tue, 11 Aug 2015 08:36:57 -0600
Subject: [PATCH v2 0/3] edac: Add L3/SoC support to the APM X-Gene SoC
 EDAC driver
In-Reply-To: <CAPw-ZT=9Eq0yc7tzqJAdCvsQTgRkMmGzNOSXgawBTY0gAijr4Q@mail.gmail.com>
References: <1437808063-17592-1-git-send-email-lho@apm.com>
 <CALdTtnv7P5d0Y6wyKe1SOqXedNhQxMsFZY=m-rxK3zouLcFv-Q@mail.gmail.com>
 <CAPw-ZT=9Eq0yc7tzqJAdCvsQTgRkMmGzNOSXgawBTY0gAijr4Q@mail.gmail.com>
Message-ID: <CALdTtnsfQ1GsZqCN470hdvsJtr_Fi5BU2L1xfAo4cqb=S9yfqA@mail.gmail.com>

On Mon, Aug 10, 2015 at 2:15 PM, Loc Ho <lho at apm.com> wrote:
> Hi Dann,
>
>>> v2:
>>> * Update binding documentation accordingly
>>> * Change all single bit defines to BIT(x)
>>> * Add support for L3 version 1 and 2 HW's
>>> * Change to use debug file system for error injection
>>> * In L3/SoC instance add function, allocate EDAC context after all
>>>   initalization successed
>>> * Support raw or detail info for SoC EDAC error reporting
>>>
>>> v1:
>>> * Add L3/SoC support to the APM X-Gene SoC EDAC driver
>>
>> Loc,
>>   I tested 4.2-rc5 on a Mustang board with one DIMM, and it hangs (RCU
>> stall) in xgene_edac_mc_irq_ctl() on modprobe. Same board with 2 DIMMs
>> boots fine. (U-boot 1.15.12).
>
> I just removed one of the two 16GB DIMM... with 4.2.0-rc1 and some
> code clean up in EDAC driver, it boots just fine... I don't believe
> the code clean up would affect it. Do you have the dump log?
>
> [root at dhcp-10-76-213-247 ~]# uname -a
> Linux dhcp-10-76-213-247 4.2.0-rc1+ #33 SMP PREEMPT Mon Aug 10
> 13:23:03 MDT 2015 aarch64 GNU/Linux

Sure:
  http://paste.ubuntu.com/12055821/
I've reproduced this on two machines. In both cases, we removed the
DIMM furthest from the CPU (in case that matters).

 -dann

> -Loc


From catalin.marinas at arm.com  Tue Aug 11 07:46:42 2015
From: catalin.marinas at arm.com (Catalin Marinas)
Date: Tue, 11 Aug 2015 15:46:42 +0100
Subject: [RFC PATCH 01/10] arm64: feature registers: Documentation
In-Reply-To: <55C8E12E.6030305@arm.com>
References: <1437731037-25795-1-git-send-email-suzuki.poulose@arm.com>
 <1437731037-25795-2-git-send-email-suzuki.poulose@arm.com>
 <20150810160636.GB15394@e104818-lin.cambridge.arm.com>
 <55C8E12E.6030305@arm.com>
Message-ID: <20150811144642.GF23307@e104818-lin.cambridge.arm.com>

On Mon, Aug 10, 2015 at 06:36:46PM +0100, Suzuki K. Poulose wrote:
> On 10/08/15 17:06, Catalin Marinas wrote:
> >On Fri, Jul 24, 2015 at 10:43:47AM +0100, Suzuki K. Poulose wrote:
> >>From: "Suzuki K. Poulose" <suzuki.poulose at arm.com>
> >>
> >>Documentation of the infrastructure
> >>
> >>Signed-off-by: Suzuki K. Poulose <suzuki.poulose at arm.com>
> >
> >The implementation looks fine but I think the main discussion will be
> >around the goal of this feature and the ABI that it introduces. So I'll
> >just write my thoughts on this patch (I could as well have replied to
> >the cover letter).
> >
> >Another question: who's going to use this feature? I know people asked
> >in private but I'd like to have some public statements.
> 
> Right, I am hoping that folks from glibc / JIT / GCC will respond to
> this thread.

Some of them didn't even want to be cc'ed ;)

> >>+ a) Any change to the HWCAPs requires an update to userspace (e.g libc)
> >>+    to detect the new changes, which can take a long time to appear in
> >>+    distributions. Exposing the registers allows applications to get the
> >>+    information without requiring other userspace components to be updated.
> >
> >How does it help if you have a new CPUID field or even a new value in an
> >existing field? Doesn't userspace need to be changed anyway to make use
> >of the new feature? I don't think that's a valid argument.
> 
> Yes, the userspace would need an update to work with the new CPUID field. I understand.
> It is just that, "in the enterprise world" updates to the system libraries provided by
> the distribution might take a bit longer to provide the changes than a software vendor.
> I agree thats not a common case.

What I meant is that for a new CPU feature, the user space needs
updating anyway to make use of (add support for) it, whether it checks
its presence via HWCAP or MRS. Let's say we get new crypto instructions,
existing user space won't even check for it because it doesn't know
there is a new CPUID field (or HWCAP bit).

> >2. We still need features listed in /proc/cpuinfo, at least for humans
> >    reading this file or scripts that can't issue mrs instructions
> 
> Agreed, we still need to provide the features in /proc/cpuinfo. We could do
> this without HWCAP if we decide not to update the list.

I agree, /proc/cpuinfo is doable without HWCAP. But since some software
ends up parsing /proc/cpuinfo anyway, I don't see why we should hide
HWCAP.

> >>+ c) Implementation Defined Features
> >>+    The infrastructure doesn't expose any register which is
> >>+    IMPLEMENTATION DEFINED as per ARMv8-A Architecture and is set to 0.
> >
> >It may be worth adding somewhere the (unwritten; yet) rules of the CPUID
> >fields: original 4-bit signed field is RAZ. When a feature is added or
> >extended, the field is incremented. If an existing feature is removed
> >for which the CPUID field is 0, the field becomes negative (0xf).
> 
> May be I can add it as an 'Notes' section at the end ?

Fine.

> >>+3. Implementation
> >>+--------------------
> >>+
> ...
> >>+The infrastructure emulates only the following system register space:
> >>+	Op0=3, Op1=0, CRn=0
> >>+
> >>+(See Table C5-6 'System instruction encodings for System register accesses'
> >>+ in ARMv8 ARM, for the list of registers).
> >>+
> >>+
> >>+The following rules are applied to the value returned by the infrastructure:
> >>+
> >>+ a) The value of an 'IMPLEMENTATION DEFINED' field is set to 0.
> >>+ b) The value of a reserved field is set to the reserved value(as
> >>+    defined by the architecture).
> >
> >Do we expose any IMPLEMENTATION DEFINED or reserved field to user?
> 
> We don't. All such fields are marked invisible. The above rules define
> how we fill those 'special' (invisible) fields. We 'emulate' all
> access to the space (as defined above) with Op0=3, Op1=0 & CRn=0.
> Out of this space, there are only a very few 'visible' fields(listed in
> section 4). These rules, define how the values are emulated.

Point b) above is a bit confusing - reserved field is set to the
reserved value. If the reserved value is non-zero, do we expose such
value to user or we return zero as for other invisible fields?

> >>+ c) The value of a field marked as not 'visible', is set to indicate
> >>+    the feature is missing (as defined by the architecture).
> >>+ d) The value of a 'visible' field holds the system wide safe value
> >>+    for the particular feature(except for MIDR_EL1, see section 4)
> >
> >I'm slightly confused by the visible/not-visible definition. GIC for
> >example may be present but we don't want to expose it to user, hence you
> >marked it as "not visible" in the table. But the feature is definitely
> >not missing, it may be present and we just decided not to expose it to
> >EL0 since it is not relevant.
> 
> Thats right. In this case, the userspace will see that 'GIC' is not present
> even though it is available. Btw, the system wide value(exposed to the system
> wide users) could be different from what the user gets. e.g, if all the CPUs
> have GIC system register access, the system view will have 'GIC' available.
> 
> Taking another example to explain rule (d), if all CPUs but one supports CRC32
> instructions, both the system view and the user view will have CRC32 disabled.

OK. I missed the difference between "system wide view" and "user view".
I guess the former is not exposed to user.

As I mentioned in my reply to Ard, we need a HWCAP entry to inform the
user of the MRS emulation. My question is whether to use a single
HWCAP_CPUID or multiple for each ID register (e.g.
HWCAP_ID_AA64ISAR0_EL1 or a shorter HWCAP_ID_ISAR0). The advantage of
the latter is that we can expose new CPUID registers if any of them
appear (or there is a useful feature in a register we don't expose).

-- 
Catalin


From jungseoklee85 at gmail.com  Tue Aug 11 07:52:00 2015
From: jungseoklee85 at gmail.com (Jungseok Lee)
Date: Tue, 11 Aug 2015 23:52:00 +0900
Subject: [RFC v2 0/4] arm64: ftrace: fix incorrect output from stack tracer
In-Reply-To: <1438674249-3447-1-git-send-email-takahiro.akashi@linaro.org>
References: <1438674249-3447-1-git-send-email-takahiro.akashi@linaro.org>
Message-ID: <50B298B0-1978-471B-BCE7-BC433E9993C1@gmail.com>

On Aug 4, 2015, at 4:44 PM, AKASHI Takahiro wrote:

Hi Akashi,

> See the following threads [1],[2] for the background.
> 
> With this patch series, I'm trying to fix several problems I noticed
> with stack tracer on arm64. But it is rather experimental, and there still
> remained are several issues. 
> 
> Patch #1 modifies ftrace framework so that we can provide arm64-specific
> stack tracer later.
> (Well, I know there is some room for further refactoring, but this is
> just a prototype code.)
> Patch #2 implements this arch_check_stack() using unwind_stackframe() to
> traverse stack frames and identify a stack index for each traced function.
> Patch #3 addresses an issue that stack tracer doesn't work well in
> conjuction with function graph tracer.
> Patch #4 addresses an issue that unwind_stackframe() misses a function
> that is the one when an exception happens by setting up a stack frame
> for exception handler.
> 
> See below for the result with those patches.
> Issues include:
> a) Size of gic_handle_irq() is 48 (#13), but should be 64.
> b) We cannot identify a location of function which is being returned
>   and hooked temporarily by return_to_handler() (#18)
> c) A meaningless entry (#62) as well as a bogus size for the first
>   function, el0_svc (#61)
> d) Size doesn't contain a function's "dynamically allocated local
>   variables," if any, but instead is sumed up in child's size.
>   (See details in [3].)
> 
> I'm afraid that we cannot fix issue b) unless we can do *atomically*
> push/pop a return adress in current->ret_stack[], increment/decrement
> current->curr_ret_stack and restore lr register.
> 
> We will be able to fix issue d) once we know all the locations in
> the list, including b).
> 
> [1] http://lists.infradead.org/pipermail/linux-arm-kernel/2015-July/354126.html
> [2] http://lists.infradead.org/pipermail/linux-arm-kernel/2015-July/355920.html
> [3] http://lists.infradead.org/pipermail/linux-arm-kernel/2015-July/358034.html

I hope I'm not too late..

This series looks written on top of the hunk in the end of this reply.

I've strongly agreed with your opinion as digging out this issue. We need to analyse
the first instruction of each function, "stp x29, x30, [sp, #val]!", in order to
solve this problem clearly.

How about decoding the store-pair instruction? If so, we could record a correct position
into stack_dump_index. That is, in your ascii art, top-sp0 and top-sp1 are written into
stack_dump_index[i+1] and stack_dump_index[i] respectively.

sp2     +-------+ <--------- func-2's stackframe
        |       |
        |       |
fp2     +-------+
        |  fp1  |
        +-------+ <-- p1 (*p1 == stack_dump_trace[i] == lr1)
        |  lr1  |
        +-------+
        |       |
        |  func-2's local variables
        |       |
sp1     +-------+ <--------- func-1(lr1)'s stackframe
        |       |             (stack_dump_index[i] = top - p1)
        |  func-1's dynamic local variables
        |       |
fp1     +-------+
        |  fp0  |
        +-------+ <-- p0 (*p0 == stack_dump_trace[i+1] == lr0)
        |  lr0  |
        +-------+
        |       |
        |  func-1's local variables
        |       |
sp0     +-------+ <--------- func-0(lr0)'s stackframe
        |       |             (stack_dump_index[i+1] = top - p0)
        |       |
        *-------+ top

Best Regards
Jungseok Lee

----8<----
diff --git a/arch/arm64/include/asm/ftrace.h b/arch/arm64/include/asm/ftrace.h
index c5534fa..2b43e20 100644
--- a/arch/arm64/include/asm/ftrace.h
+++ b/arch/arm64/include/asm/ftrace.h
@@ -13,8 +13,9 @@

#include <asm/insn.h>

-#define MCOUNT_ADDR		((unsigned long)_mcount)
-#define MCOUNT_INSN_SIZE	AARCH64_INSN_SIZE
+#define MCOUNT_ADDR			((unsigned long)_mcount)
+#define MCOUNT_INSN_SIZE		AARCH64_INSN_SIZE
+#define FTRACE_STACK_FRAME_OFFSET	AARCH64_INSN_SIZE

#ifndef __ASSEMBLY__
#include <linux/compat.h>
diff --git a/arch/arm64/kernel/stacktrace.c b/arch/arm64/kernel/stacktrace.c
index 407991b..9ab67af 100644
--- a/arch/arm64/kernel/stacktrace.c
+++ b/arch/arm64/kernel/stacktrace.c
@@ -20,6 +20,7 @@
#include <linux/sched.h>
#include <linux/stacktrace.h>

+#include <asm/insn.h>
#include <asm/stacktrace.h>

/*
@@ -52,7 +53,7 @@ int notrace unwind_frame(struct stackframe *frame)
	 * -4 here because we care about the PC at time of bl,
	 * not where the return will go.
	 */
-	frame->pc = *(unsigned long *)(fp + 8) - 4;
+	frame->pc = *(unsigned long *)(fp + 8) - AARCH64_INSN_SIZE;

	return 0;
}
diff --git a/include/linux/ftrace.h b/include/linux/ftrace.h
index 1da6029..6566201 100644
--- a/include/linux/ftrace.h
+++ b/include/linux/ftrace.h
@@ -260,6 +260,9 @@ static inline void ftrace_kill(void) { }
#endif /* CONFIG_FUNCTION_TRACER */

#ifdef CONFIG_STACK_TRACER
+#ifndef FTRACE_STACK_FRAME_OFFSET
+#define FTRACE_STACK_FRAME_OFFSET 0
+#endif
extern int stack_tracer_enabled;
int
stack_trace_sysctl(struct ctl_table *table, int write,
diff --git a/kernel/trace/trace_stack.c b/kernel/trace/trace_stack.c
index b746399..30521ea 100644
--- a/kernel/trace/trace_stack.c
+++ b/kernel/trace/trace_stack.c
@@ -105,7 +105,7 @@ check_stack(unsigned long ip, unsigned long *stack)

	/* Skip over the overhead of the stack tracer itself */
	for (i = 0; i < max_stack_trace.nr_entries; i++) {
-		if (stack_dump_trace[i] == ip)
+		if ((stack_dump_trace[i] + FTRACE_STACK_FRAME_OFFSET) == ip)
			break;
	}

@@ -133,7 +133,8 @@ check_stack(unsigned long ip, unsigned long *stack)
		for (; p < top && i < max_stack_trace.nr_entries; p++) {
			if (stack_dump_trace[i] == ULONG_MAX)
				break;
-			if (*p == stack_dump_trace[i]) {
+			if (*p == (stack_dump_trace[i]
+					+ FTRACE_STACK_FRAME_OFFSET)) {
				stack_dump_trace[x] = stack_dump_trace[i++];
				this_size = stack_dump_index[x++] =
					(top - p) * sizeof(unsigned long);
----8<----



From wsa at the-dreams.de  Tue Aug 11 07:55:12 2015
From: wsa at the-dreams.de (Wolfram Sang)
Date: Tue, 11 Aug 2015 16:55:12 +0200
Subject: [PATCH v2 1/2] i2c: mediatek: Reset DMA engine in hardware init
 function
In-Reply-To: <1438845731-17805-2-git-send-email-eddie.huang@mediatek.com>
References: <1438845731-17805-1-git-send-email-eddie.huang@mediatek.com>
 <1438845731-17805-2-git-send-email-eddie.huang@mediatek.com>
Message-ID: <20150811145512.GA1525@katana>

On Thu, Aug 06, 2015 at 03:22:10PM +0800, Eddie Huang wrote:
> Reset DMA in hardware init function to avoid unknown hardware state
> before do any I2C operation.
> 
> Signed-off-by: Liguo Zhang <liguo.zhang at mediatek.com>
> Signed-off-by: Eddie Huang <eddie.huang at mediatek.com>

Applied to for-next, thanks!

-------------- next part --------------
A non-text attachment was scrubbed...
Name: signature.asc
Type: application/pgp-signature
Size: 819 bytes
Desc: Digital signature
URL: <http://lists.infradead.org/pipermail/linux-arm-kernel/attachments/20150811/34345e43/attachment.sig>

From wsa at the-dreams.de  Tue Aug 11 07:55:21 2015
From: wsa at the-dreams.de (Wolfram Sang)
Date: Tue, 11 Aug 2015 16:55:21 +0200
Subject: [PATCH v2 2/2] i2c: mediatek: Fixup i2c ack error interrupt
 handling
In-Reply-To: <1438845731-17805-3-git-send-email-eddie.huang@mediatek.com>
References: <1438845731-17805-1-git-send-email-eddie.huang@mediatek.com>
 <1438845731-17805-3-git-send-email-eddie.huang@mediatek.com>
Message-ID: <20150811145521.GB1525@katana>

On Thu, Aug 06, 2015 at 03:22:11PM +0800, Eddie Huang wrote:
> When occur i2c ack error, i2c controller generate two interrupts,
> first is the ack error interrupt, then the complete interrupt.
> i2c interrupt handler should keep the two interrupt value, and only
> call complete() for the complete interrupt.
> 
> Signed-off-by: Liguo Zhang <liguo.zhang at mediatek.com>
> Signed-off-by: Eddie Huang <eddie.huang at mediatek.com>

Applied to for-next, thanks!

-------------- next part --------------
A non-text attachment was scrubbed...
Name: signature.asc
Type: application/pgp-signature
Size: 819 bytes
Desc: Digital signature
URL: <http://lists.infradead.org/pipermail/linux-arm-kernel/attachments/20150811/05b4bbc5/attachment.sig>

From joro at 8bytes.org  Tue Aug 11 07:56:33 2015
From: joro at 8bytes.org (Joerg Roedel)
Date: Tue, 11 Aug 2015 16:56:33 +0200
Subject: [PATCH v4 4/6] memory: mediatek: Add SMI driver
In-Reply-To: <1438597279-2937-5-git-send-email-yong.wu@mediatek.com>
References: <1438597279-2937-1-git-send-email-yong.wu@mediatek.com>
 <1438597279-2937-5-git-send-email-yong.wu@mediatek.com>
Message-ID: <20150811145633.GE14980@8bytes.org>

On Mon, Aug 03, 2015 at 06:21:17PM +0800, Yong Wu wrote:
> +static int mtk_smi_common_get(struct device *smidev)
> +{
> +	struct mtk_smi_common *smipriv = dev_get_drvdata(smidev);
> +	int ret;
> +
> +	ret = pm_runtime_get_sync(smidev);
> +	if (ret < 0)
> +		return ret;
> +
> +	ret = clk_prepare_enable(smipriv->clk_apb);
> +	if (ret) {
> +		dev_err(smidev, "Failed to enable the apb clock\n");
> +		goto err_put_pm;
> +	}
> +	ret = clk_prepare_enable(smipriv->clk_smi);
> +	if (ret) {
> +		dev_err(smidev, "Failed to enable the smi clock\n");
> +		goto err_disable_apb;
> +	}
> +	return ret;
> +
> +err_disable_apb:
> +	clk_disable_unprepare(smipriv->clk_apb);
> +err_put_pm:
> +	pm_runtime_put(smidev);
> +	return ret;
> +}

[...]

> +int mtk_smi_larb_get(struct device *larbdev)
> +{
> +	struct mtk_smi_larb *larbpriv = dev_get_drvdata(larbdev);
> +	struct mtk_larb_mmu *mmucfg = larbdev->archdata.iommu;
> +	int ret;
> +
> +	ret = mtk_smi_common_get(larbpriv->smi);
> +	if (ret)
> +		return ret;
> +
> +	ret = pm_runtime_get_sync(larbdev);
> +	if (ret < 0)
> +		goto err_put_smicommon;
> +
> +	ret = clk_prepare_enable(larbpriv->clk_apb);
> +	if (ret) {
> +		dev_err(larbdev, "Failed to enable the apb clock\n");
> +		goto err_put_pm;
> +	}
> +
> +	ret = clk_prepare_enable(larbpriv->clk_smi);
> +	if (ret) {
> +		dev_err(larbdev, "Failed to enable the smi clock\n");
> +		goto err_disable_apb;
> +	}

The clock enablement looks similar to the function above, maybe move it
to a helper function?


	Joerg



From jungseoklee85 at gmail.com  Tue Aug 11 07:57:56 2015
From: jungseoklee85 at gmail.com (Jungseok Lee)
Date: Tue, 11 Aug 2015 23:57:56 +0900
Subject: [RFC v2 4/4] arm64: ftrace: add a stack frame for exception
 handler
In-Reply-To: <1438674249-3447-5-git-send-email-takahiro.akashi@linaro.org>
References: <1438674249-3447-1-git-send-email-takahiro.akashi@linaro.org>
 <1438674249-3447-5-git-send-email-takahiro.akashi@linaro.org>
Message-ID: <6399AE18-786B-41C2-B1C7-428567D9CF47@gmail.com>

On Aug 4, 2015, at 4:44 PM, AKASHI Takahiro wrote:

Hi Akashi,

> On arm64, an exception handler use the same stack as in non-exception
> contexts, but doesn't create a stack frame for elx_xx entry, only updating
> sp register. This behavior results in save_stace_trace() missing a function
> that is the one when an exception happens.
> 
> This patch creates a stack frame for this case, and puts an additional
> entry for the function  in a stack trace list.
> 
> Signed-off-by: AKASHI Takahiro <takahiro.akashi at linaro.org>
> ---
> arch/arm64/kernel/entry.S      |    4 ++++
> arch/arm64/kernel/stacktrace.c |   17 +++++++++++++++++
> 2 files changed, 21 insertions(+)
> 
> diff --git a/arch/arm64/kernel/entry.S b/arch/arm64/kernel/entry.S
> index f860bfd..aacb6c6 100644
> --- a/arch/arm64/kernel/entry.S
> +++ b/arch/arm64/kernel/entry.S
> @@ -107,6 +107,8 @@
> 	str	x21, [sp, #S_SYSCALLNO]
> 	.endif
> 
> +	/* create a stack frame for stack tracer */
> +	mov	x29, sp
> 	/*
> 	 * Registers that may be useful after this macro is invoked:
> 	 *
> @@ -737,3 +739,5 @@ ENTRY(sys_rt_sigreturn_wrapper)
> 	mov	x0, sp
> 	b	sys_rt_sigreturn
> ENDPROC(sys_rt_sigreturn_wrapper)
> +
> +ENTRY(end_of_vectors)
> diff --git a/arch/arm64/kernel/stacktrace.c b/arch/arm64/kernel/stacktrace.c
> index d1790eb..22ce7c9 100644
> --- a/arch/arm64/kernel/stacktrace.c
> +++ b/arch/arm64/kernel/stacktrace.c
> @@ -25,6 +25,10 @@
> #include <asm/stacktrace.h>
> 
> #define S_FRAME_SIZE sizeof(struct pt_regs) /* asm-offsets.h */
> +#define S_FP offsetof(struct pt_regs, regs[29])
> +#define S_LR offsetof(struct pt_regs, regs[30])
> +
> +extern unsigned int *vectors, *end_of_vectors;
> 
> /*
>  * AArch64 PCS assigns the frame pointer to x29.
> @@ -50,6 +54,19 @@ int notrace unwind_frame(struct stackframe *frame)
> 	if (fp < low || fp > high - 0x18 || fp & 0xf)
> 		return -EINVAL;
> 
> +	if ((frame->pc >= (unsigned long)&vectors) &&
> +			(frame->pc < (unsigned long)&end_of_vectors)) {
> +		/*
> +		 * Expection handler does not use a normal format of
> +		 * stack frame, but allocates struct pt_regs.
> +		 */
> +		frame->sp = frame->sp + S_FRAME_SIZE;
> +		frame->fp = *(unsigned long *)(fp + S_FP);
> +		frame->pc = *(unsigned long *)(fp + S_LR);

Not frame->pc = *(unsigned long *)(fp + S_PC)? Don't we need to look up elr_el1
since this is an exception?

> +
> +		return 0;
> +	}
> +
> 	frame->sp = fp + 0x10;

I'm just curious about this constant, 0x10. Do you have an idea on this value?
As reviewing objdump of vmlinux, it looks needed to analyze the first store-pair
instruction of each function.

Please correct me if I'm wrong.

Best Regards
Jungseok Lee

From linus.walleij at linaro.org  Tue Aug 11 08:12:21 2015
From: linus.walleij at linaro.org (Linus Walleij)
Date: Tue, 11 Aug 2015 17:12:21 +0200
Subject: [PATCH] pinctrl: nomadik: reflect current input value
Message-ID: <1439305941-29948-1-git-send-email-linus.walleij@linaro.org>

Let us see the current value on the input line in debugfs.

Signed-off-by: Linus Walleij <linus.walleij at linaro.org>
---
 drivers/pinctrl/nomadik/pinctrl-nomadik.c | 5 +++++
 1 file changed, 5 insertions(+)

diff --git a/drivers/pinctrl/nomadik/pinctrl-nomadik.c b/drivers/pinctrl/nomadik/pinctrl-nomadik.c
index 809d88445db5..ad43ea8fd67e 100644
--- a/drivers/pinctrl/nomadik/pinctrl-nomadik.c
+++ b/drivers/pinctrl/nomadik/pinctrl-nomadik.c
@@ -1012,6 +1012,7 @@ static void nmk_gpio_dbg_show_one(struct seq_file *s,
 		int irq = gpio_to_irq(gpio);
 		struct irq_desc	*desc = irq_to_desc(irq);
 		int pullidx = 0;
+		int val;
 
 		if (pull)
 			pullidx = data_out ? 1 : 2;
@@ -1021,6 +1022,10 @@ static void nmk_gpio_dbg_show_one(struct seq_file *s,
 			   label ?: "(none)",
 			   pulls[pullidx],
 			   (mode < 0) ? "unknown" : modes[mode]);
+
+		val = nmk_gpio_get_input(chip, offset);
+		seq_printf(s, " VAL %d", val);
+
 		/*
 		 * This races with request_irq(), set_irq_type(),
 		 * and set_irq_wake() ... but those are "rare".
-- 
2.4.3



From benjamin.gaignard at linaro.org  Tue Aug 11 08:12:44 2015
From: benjamin.gaignard at linaro.org (Benjamin Gaignard)
Date: Tue, 11 Aug 2015 17:12:44 +0200
Subject: [PATCH] enable HQVDP for stih410 platform
Message-ID: <1439305964-15641-1-git-send-email-benjamin.gaignard@linaro.org>

From: Vincent Abriou <vincent.abriou at st.com>

Add HQVDP in stih410 devicetree to enable it.
HQVDP bindings have been describe in
Documentation/devicetree/bindings/gpu/st,stih4xx.txt file.

Signed-off-by: Vincent Abriou <vincent.abriou at st.com>
---
 arch/arm/boot/dts/stih410.dtsi | 10 ++++++++++
 1 file changed, 10 insertions(+)

diff --git a/arch/arm/boot/dts/stih410.dtsi b/arch/arm/boot/dts/stih410.dtsi
index 6620bba..33cc933 100644
--- a/arch/arm/boot/dts/stih410.dtsi
+++ b/arch/arm/boot/dts/stih410.dtsi
@@ -163,6 +163,16 @@
 				st,vtg = <&vtg_main>, <&vtg_aux>;
 			};
 
+			sti-hqvdp at 9c000000 {
+				compatible = "st,stih407-hqvdp";
+				reg = <0x9C00000 0x100000>;
+				clock-names = "hqvdp", "pix_main";
+				clocks = <&clk_s_c0_flexgen CLK_MAIN_DISP>, <&clk_s_d2_flexgen CLK_PIX_MAIN_DISP>;
+				reset-names = "hqvdp";
+				resets = <&softreset STIH407_HDQVDP_SOFTRESET>;
+				st,vtg = <&vtg_main>;
+			};
+
 			sti-tvout at 8d08000 {
 				compatible = "st,stih407-tvout";
 				reg = <0x8d08000 0x1000>;
-- 
1.9.1



From linus.walleij at linaro.org  Tue Aug 11 08:17:18 2015
From: linus.walleij at linaro.org (Linus Walleij)
Date: Tue, 11 Aug 2015 17:17:18 +0200
Subject: [PATCH] ARM/fb: ep93xx: switch framebuffer to use modedb only
Message-ID: <1439306238-30655-1-git-send-email-linus.walleij@linaro.org>

All the EP93xx boards exclusively use modedb to look up video
modes from the command line. Root out the parametrization of
custom video modes from the platform data and board files
and simplify the driver.

Cc: Jean-Christophe Plagniol-Villard <plagnioj at jcrosoft.com>
Reviewed-by: H Hartley Sweeten <hsweeten at visionengravers.com>
Acked-by: Tomi Valkeinen <tomi.valkeinen at ti.com>
Signed-off-by: Linus Walleij <linus.walleij at linaro.org>
---
Hi ARM SoC maintainers, please apply this directly to the
EP93xx/cleanup branch now that I have Tomi's ACK.
---
 arch/arm/mach-ep93xx/edb93xx.c             |  2 --
 arch/arm/mach-ep93xx/simone.c              |  2 --
 arch/arm/mach-ep93xx/snappercl15.c         |  2 --
 arch/arm/mach-ep93xx/vision_ep9307.c       |  2 --
 drivers/video/fbdev/ep93xx-fb.c            | 30 ++++--------------------------
 include/linux/platform_data/video-ep93xx.h |  8 --------
 6 files changed, 4 insertions(+), 42 deletions(-)

diff --git a/arch/arm/mach-ep93xx/edb93xx.c b/arch/arm/mach-ep93xx/edb93xx.c
index 27b14ae92c7e..ad92d9f7e4df 100644
--- a/arch/arm/mach-ep93xx/edb93xx.c
+++ b/arch/arm/mach-ep93xx/edb93xx.c
@@ -205,8 +205,6 @@ static void __init edb93xx_register_pwm(void)
  * EDB93xx framebuffer
  *************************************************************************/
 static struct ep93xxfb_mach_info __initdata edb93xxfb_info = {
-	.num_modes	= EP93XXFB_USE_MODEDB,
-	.bpp		= 16,
 	.flags		= 0,
 };
 
diff --git a/arch/arm/mach-ep93xx/simone.c b/arch/arm/mach-ep93xx/simone.c
index d0938a219443..7bb540c421ee 100644
--- a/arch/arm/mach-ep93xx/simone.c
+++ b/arch/arm/mach-ep93xx/simone.c
@@ -40,8 +40,6 @@ static struct ep93xx_eth_data __initdata simone_eth_data = {
 };
 
 static struct ep93xxfb_mach_info __initdata simone_fb_info = {
-	.num_modes	= EP93XXFB_USE_MODEDB,
-	.bpp		= 16,
 	.flags		= EP93XXFB_USE_SDCSN0 | EP93XXFB_PCLK_FALLING,
 };
 
diff --git a/arch/arm/mach-ep93xx/snappercl15.c b/arch/arm/mach-ep93xx/snappercl15.c
index aa86f86638dd..c4904264256a 100644
--- a/arch/arm/mach-ep93xx/snappercl15.c
+++ b/arch/arm/mach-ep93xx/snappercl15.c
@@ -144,8 +144,6 @@ static struct i2c_board_info __initdata snappercl15_i2c_data[] = {
 };
 
 static struct ep93xxfb_mach_info __initdata snappercl15_fb_info = {
-	.num_modes		= EP93XXFB_USE_MODEDB,
-	.bpp			= 16,
 };
 
 static struct platform_device snappercl15_audio_device = {
diff --git a/arch/arm/mach-ep93xx/vision_ep9307.c b/arch/arm/mach-ep93xx/vision_ep9307.c
index ff22a6a6e2bf..5cced5988498 100644
--- a/arch/arm/mach-ep93xx/vision_ep9307.c
+++ b/arch/arm/mach-ep93xx/vision_ep9307.c
@@ -106,8 +106,6 @@ static void vision_lcd_blank(int blank_mode, struct fb_info *info)
 }
 
 static struct ep93xxfb_mach_info ep93xxfb_info __initdata = {
-	.num_modes	= EP93XXFB_USE_MODEDB,
-	.bpp		= 16,
 	.flags		= EP93XXFB_USE_SDCSN0 | EP93XXFB_PCLK_FALLING,
 	.setup		= vision_lcd_setup,
 	.teardown	= vision_lcd_teardown,
diff --git a/drivers/video/fbdev/ep93xx-fb.c b/drivers/video/fbdev/ep93xx-fb.c
index 7ec251cc9c03..5b1081030cbb 100644
--- a/drivers/video/fbdev/ep93xx-fb.c
+++ b/drivers/video/fbdev/ep93xx-fb.c
@@ -419,36 +419,15 @@ static struct fb_ops ep93xxfb_ops = {
 	.fb_mmap	= ep93xxfb_mmap,
 };
 
-static int ep93xxfb_calc_fbsize(struct ep93xxfb_mach_info *mach_info)
-{
-	int i, fb_size = 0;
-
-	if (mach_info->num_modes == EP93XXFB_USE_MODEDB) {
-		fb_size = EP93XXFB_MAX_XRES * EP93XXFB_MAX_YRES *
-			mach_info->bpp / 8;
-	} else {
-		for (i = 0; i < mach_info->num_modes; i++) {
-			const struct fb_videomode *mode;
-			int size;
-
-			mode = &mach_info->modes[i];
-			size = mode->xres * mode->yres * mach_info->bpp / 8;
-			if (size > fb_size)
-				fb_size = size;
-		}
-	}
-
-	return fb_size;
-}
-
 static int ep93xxfb_alloc_videomem(struct fb_info *info)
 {
-	struct ep93xx_fbi *fbi = info->par;
 	char __iomem *virt_addr;
 	dma_addr_t phys_addr;
 	unsigned int fb_size;
 
-	fb_size = ep93xxfb_calc_fbsize(fbi->mach_info);
+	/* Maximum 16bpp -> used memory is maximum x*y*2 bytes */
+	fb_size = EP93XXFB_MAX_XRES * EP93XXFB_MAX_YRES * 2;
+
 	virt_addr = dma_alloc_writecombine(info->dev, fb_size,
 					   &phys_addr, GFP_KERNEL);
 	if (!virt_addr)
@@ -550,8 +529,7 @@ static int ep93xxfb_probe(struct platform_device *pdev)
 
 	fb_get_options("ep93xx-fb", &video_mode);
 	err = fb_find_mode(&info->var, info, video_mode,
-			   fbi->mach_info->modes, fbi->mach_info->num_modes,
-			   fbi->mach_info->default_mode, fbi->mach_info->bpp);
+			   NULL, 0, NULL, 16);
 	if (err == 0) {
 		dev_err(info->dev, "No suitable video mode found\n");
 		err = -EINVAL;
diff --git a/include/linux/platform_data/video-ep93xx.h b/include/linux/platform_data/video-ep93xx.h
index 92fc2b2232e7..699ac4109366 100644
--- a/include/linux/platform_data/video-ep93xx.h
+++ b/include/linux/platform_data/video-ep93xx.h
@@ -2,11 +2,8 @@
 #define __VIDEO_EP93XX_H
 
 struct platform_device;
-struct fb_videomode;
 struct fb_info;
 
-#define EP93XXFB_USE_MODEDB		0
-
 /* VideoAttributes flags */
 #define EP93XXFB_STATE_MACHINE_ENABLE	(1 << 0)
 #define EP93XXFB_PIXEL_CLOCK_ENABLE	(1 << 1)
@@ -38,12 +35,7 @@ struct fb_info;
 					 EP93XXFB_PIXEL_DATA_ENABLE)
 
 struct ep93xxfb_mach_info {
-	unsigned int			num_modes;
-	const struct fb_videomode	*modes;
-	const struct fb_videomode	*default_mode;
-	int				bpp;
 	unsigned int			flags;
-
 	int	(*setup)(struct platform_device *pdev);
 	void	(*teardown)(struct platform_device *pdev);
 	void	(*blank)(int blank_mode, struct fb_info *info);
-- 
2.4.3



From lee.jones at linaro.org  Tue Aug 11 08:17:36 2015
From: lee.jones at linaro.org (Lee Jones)
Date: Tue, 11 Aug 2015 16:17:36 +0100
Subject: [PATCH v4 2/2] dt: power: st: Provide bindings for ST's OPPs
In-Reply-To: <20150811142812.GJ5509@linux>
References: <20150731163715.GV3159@codeaurora.org> <20150803034642.GV899@linux>
 <20150810132247.GH3249@x1> <20150811080023.GB5509@linux>
 <20150811093039.GA18282@x1> <20150811100941.GG5509@linux>
 <20150811115425.GE18282@x1> <20150811120124.GH5509@linux>
 <20150811132756.GG18282@x1> <20150811142812.GJ5509@linux>
Message-ID: <20150811151736.GO18282@x1>

On Tue, 11 Aug 2015, Viresh Kumar wrote:
> On 11-08-15, 14:27, Lee Jones wrote:
> > Okay, so what you're saying is that you've already made the decision
> > to create a separate node for every OPP permutation,
> 
> Absolutely not.
> 
> > despite the fact
> > that I've told you this could lead to more nodes than anyone would
> > care to successfully write or maintain?
> 
> I have enough fear of yours and then I have to see you in another
> month as well. I wouldn't dare to disobey your command SIR :)

Funny guy! ;)

> > Perhaps an example might help explain the issue.
> > 
> > Using the current driver, we need to place the following in DT and the
> > driver does the rest:
> > 
> > opp-list {
> > 	opp1 {
> > 		opp-hz = <1500000000>;
> > 		st,avs = <1200 1200 1200 1200 1170 1140 1100 1070>;
> > 		st,substrate = <0xff>;
> > 		st,cuts = <0xff>;
> > 	};
> > 	opp0 {
> > 		opp-hz = <1200000000>;
> > 		st,avs = <1110 1150 1100 1080 1040 1020 980 930>;
> > 		st,substrate = <0xff>;
> > 		st,cuts = <0x2>;
> > 	};
> > };
> 
> Nothing is fixed as of now but this is what I am thinking of:
> 
> 	cpu0_opp_table: opp_table0 {
> 		compatible = "operating-points-v2";
>                 opp-cuts = "10", "3c", "f0";
> 		supply-names = "vcc0", "vcc1", "vcc2";
> 		opp-shared;
> 
> 		opp00 {
> 			opp-hz = /bits/ 64 <1000000000>;
> 			clock-latency-ns = <300000>;
> 			opp-microvolt-10 = <970000>;
> 			opp-microvolt-3c = <950000>;
> 			opp-microvolt-f0 = <930000>;
> 		};
> 
> 		/* OR */
> 
> 		opp00 {
> 			opp-hz = /bits/ 64 <1000000000>;
> 			clock-latency-ns = <300000>;
>                         opp-microvolt = <970000>, <950000>, <930000>;
> 		};
>         };
> 
> And then the platform code needs to tell OPP layer:
> "Use OPPs for cut f0 for device X", and OPP layer will store that
> somewhere.
> 
> And then it will only initialize OPPs after matching this string with
> the values.
> 
> Out of the earlier two options, I may prefer the first one. As we will
> be soon adding support for multiple regulators, and a single regulator
> can have min/max/target values.. So, a single list will become too
> long.

This would work if we only had a single variable to contend with, but
what I showed you in my previous example is that we have 3 variables
to consider; cut (version), pcode and substrate.

Using the two (simple) examples I provided, how would your suggestion
look in our case?

> But, something like this should be generic enough to capture most of
> the cases.
> 
> @Stephen/Rob ??
> 

-- 
Lee Jones
Linaro STMicroelectronics Landing Team Lead
Linaro.org ? Open source software for ARM SoCs
Follow Linaro: Facebook | Twitter | Blog


From Suzuki.Poulose at arm.com  Tue Aug 11 08:18:33 2015
From: Suzuki.Poulose at arm.com (Suzuki K. Poulose)
Date: Tue, 11 Aug 2015 16:18:33 +0100
Subject: [RFC PATCH 01/10] arm64: feature registers: Documentation
In-Reply-To: <20150811144642.GF23307@e104818-lin.cambridge.arm.com>
References: <1437731037-25795-1-git-send-email-suzuki.poulose@arm.com>
 <1437731037-25795-2-git-send-email-suzuki.poulose@arm.com>
 <20150810160636.GB15394@e104818-lin.cambridge.arm.com>
 <55C8E12E.6030305@arm.com>
 <20150811144642.GF23307@e104818-lin.cambridge.arm.com>
Message-ID: <55CA1249.9080508@arm.com>

On 11/08/15 15:46, Catalin Marinas wrote:
> On Mon, Aug 10, 2015 at 06:36:46PM +0100, Suzuki K. Poulose wrote:
>> On 10/08/15 17:06, Catalin Marinas wrote:
>>> On Fri, Jul 24, 2015 at 10:43:47AM +0100, Suzuki K. Poulose wrote:
>>>> From: "Suzuki K. Poulose" <suzuki.poulose at arm.com>
>>>>
>>>> Documentation of the infrastructure
>>>>
>>>> Signed-off-by: Suzuki K. Poulose <suzuki.poulose at arm.com>

...

>>> + a) Any change to the HWCAPs requires an update to userspace (e.g libc)
>>>> +    to detect the new changes, which can take a long time to appear in
>>>> +    distributions. Exposing the registers allows applications to get the
>>>> +    information without requiring other userspace components to be updated.
>>>
>>> How does it help if you have a new CPUID field or even a new value in an
>>> existing field? Doesn't userspace need to be changed anyway to make use
>>> of the new feature? I don't think that's a valid argument.
>>
>> Yes, the userspace would need an update to work with the new CPUID field. I understand.
>> It is just that, "in the enterprise world" updates to the system libraries provided by
>> the distribution might take a bit longer to provide the changes than a software vendor.
>> I agree thats not a common case.
>
> What I meant is that for a new CPU feature, the user space needs
> updating anyway to make use of (add support for) it, whether it checks
> its presence via HWCAP or MRS. Let's say we get new crypto instructions,
> existing user space won't even check for it because it doesn't know
> there is a new CPUID field (or HWCAP bit).
>

I understand that, thats why I mentioned a 'software vendor' could roll out an
update independent of the 'system libraries' provided by the distribution, where
standard distributions might have their own schedule. But, I agree that the userspace
needs update and my 'story' is not common :)

>>> 2. We still need features listed in /proc/cpuinfo, at least for humans
>>>     reading this file or scripts that can't issue mrs instructions
>>
>> Agreed, we still need to provide the features in /proc/cpuinfo. We could do
>> this without HWCAP if we decide not to update the list.
>
> I agree, /proc/cpuinfo is doable without HWCAP. But since some software
> ends up parsing /proc/cpuinfo anyway, I don't see why we should hide
> HWCAP.
>

Right.

>>>> +3. Implementation
>>>> +--------------------
>>>> +
>> ...
>>>> +The infrastructure emulates only the following system register space:
>>>> +	Op0=3, Op1=0, CRn=0
>>>> +
>>>> +(See Table C5-6 'System instruction encodings for System register accesses'
>>>> + in ARMv8 ARM, for the list of registers).
>>>> +
>>>> +
>>>> +The following rules are applied to the value returned by the infrastructure:
>>>> +
>>>> + a) The value of an 'IMPLEMENTATION DEFINED' field is set to 0.
>>>> + b) The value of a reserved field is set to the reserved value(as
>>>> +    defined by the architecture).
>>>
>>> Do we expose any IMPLEMENTATION DEFINED or reserved field to user?
>>
>> We don't. All such fields are marked invisible. The above rules define
>> how we fill those 'special' (invisible) fields. We 'emulate' all
>> access to the space (as defined above) with Op0=3, Op1=0 & CRn=0.
>> Out of this space, there are only a very few 'visible' fields(listed in
>> section 4). These rules, define how the values are emulated.
>
> Point b) above is a bit confusing - reserved field is set to the
> reserved value. If the reserved value is non-zero, do we expose such
> value to user or we return zero as for other invisible fields?

At the moment, we are exposing the reserved values to not confuse the user, which
- I thought - is safer than exposing 0. Value 0 could have a different meaning in
the future(if it is not RES0 already).

>>>> + c) The value of a field marked as not 'visible', is set to indicate
>>>> +    the feature is missing (as defined by the architecture).
>>>> + d) The value of a 'visible' field holds the system wide safe value
>>>> +    for the particular feature(except for MIDR_EL1, see section 4)
>>>
>>> I'm slightly confused by the visible/not-visible definition. GIC for
>>> example may be present but we don't want to expose it to user, hence you
>>> marked it as "not visible" in the table. But the feature is definitely
>>> not missing, it may be present and we just decided not to expose it to
>>> EL0 since it is not relevant.
>>
>> Thats right. In this case, the userspace will see that 'GIC' is not present
>> even though it is available. Btw, the system wide value(exposed to the system
>> wide users) could be different from what the user gets. e.g, if all the CPUs
>> have GIC system register access, the system view will have 'GIC' available.
>>
>> Taking another example to explain rule (d), if all CPUs but one supports CRC32
>> instructions, both the system view and the user view will have CRC32 disabled.
>
> OK. I missed the difference between "system wide view" and "user view".
> I guess the former is not exposed to user.

Right, the system view and the user view are different. User view will only get the
visible parts from the 'System view'.

>
> As I mentioned in my reply to Ard, we need a HWCAP entry to inform the
> user of the MRS emulation. My question is whether to use a single
> HWCAP_CPUID or multiple for each ID register (e.g.
> HWCAP_ID_AA64ISAR0_EL1 or a shorter HWCAP_ID_ISAR0). The advantage of
> the latter is that we can expose new CPUID registers if any of them
> appear (or there is a useful feature in a register we don't expose).

The current implementation, kind of solves the issue. i.e, we expose
a safe value(which implies 'feature not available') for all the registers
in the id space (including the reserved ids) we plan to emulate. So if we
decide to expose something, userspace need not make any change. It could
continue to read the register safely and decide if the feature is available or not
and take appropriate decisions.


Thanks
Suzuki



From javier at osg.samsung.com  Tue Aug 11 08:25:21 2015
From: javier at osg.samsung.com (Javier Martinez Canillas)
Date: Tue, 11 Aug 2015 17:25:21 +0200
Subject: [PATCH v3 3/4] mfd: Add DT binding for Maxim MAX77802 IC
In-Reply-To: <20150811114736.GB18282@x1>
References: <1438252327-28427-1-git-send-email-javier@osg.samsung.com>
 <1438252327-28427-4-git-send-email-javier@osg.samsung.com>
 <20150811114736.GB18282@x1>
Message-ID: <55CA13E1.9090403@osg.samsung.com>

Hello Lee,

On 08/11/2015 01:47 PM, Lee Jones wrote:
> On Thu, 30 Jul 2015, Javier Martinez Canillas wrote:
> 
>> The MAX77802 is a chip that contains regulators, 2 32kHz clocks,
>> a RTC and an I2C interface to program the individual components.
>>
>> The are already DT bindings for the regulators and clocks and
>> these reference to a bindings/mfd/max77802.txt file, that didn't
>> exist, for the details about the PMIC.
>>
>> Signed-off-by: Javier Martinez Canillas <javier at osg.samsung.com>
>> Reviewed-by: Krzysztof Kozlowski <k.kozlowski at samsung.com>
>>
>> ---
>>
>> Changes in v3:
>> - Add Krzysztof Kozlowski Reviewed-by tag to patch #3.
>> - Capitalise all acronyms. Suggested by Lee Jones.
>> - Use relative path to refer other bindings. Suggested by Lee Jones.
>> - Use IRQ_TYPE_NONE instead of 0 in example. Suggested by Lee Jones.
>>
>> Changes in v2:
>> - Use the correct "maxim,max77802" compatible string.
>>   Suggested by Krzysztof Kozlowski
>> - Use a pmic generic node name for the max77802 node example.
>>   Suggested by Sergei Shtylyov.
>>
>>  Documentation/devicetree/bindings/mfd/max77802.txt | 26 ++++++++++++++++++++++
>>  1 file changed, 26 insertions(+)
>>  create mode 100644 Documentation/devicetree/bindings/mfd/max77802.txt
>>
>> diff --git a/Documentation/devicetree/bindings/mfd/max77802.txt b/Documentation/devicetree/bindings/mfd/max77802.txt
>> new file mode 100644
>> index 000000000000..911ec5fcaefd
>> --- /dev/null
>> +++ b/Documentation/devicetree/bindings/mfd/max77802.txt
>> @@ -0,0 +1,26 @@
>> +Maxim MAX77802 multi-function device
>> +
>> +The Maxim MAX77802 is a Power Management IC (PMIC) that contains 10 high
>> +efficiency Buck regulators, 32 Low-DropOut (LDO) regulators used to power
>> +up application processors and peripherals, a 2-channel 32kHz clock outputs,
>> +a Real-Time-Clock (RTC) and a I2C interface to program the individual
>> +regulators, clocks outputs and the RTC.
>> +
>> +Binding for the built-in 32k clock generator block is defined separately
>> +in the ../clk/maxim,max77802.txt file and binding for the regulators
>> +is defined in the ../regulator/max77802.txt file.
> 
>   "Bindings for the built-in 32k clock generator block and
>    regulators are defined in ../clk/maxim,max77802.txt and
>    ../regulator/max77802.txt respectively."
> 
>> +Required properties:
>> +- compatible : Must be "maxim,max77802";
> 
> ';' ?
>

err... I've no idea how that ended there. It seems I didn't completely
context switch from coding :-)
 
>> +- reg : Specifies the I2C slave address of PMIC block.
>> +- interrupts : This I2C device has an IRQ line connected to the main SoC.
>> +- interrupt-parent : The parent interrupt controller.
> 
> I always find this easier on the eye when you:
>
> Required properties:
> - compatible		: Must be "maxim,max77802"
> - reg			: Specifies the I2C slave address of PMIC block.
> - interrupts		: This I2C device has an IRQ line connected to the main SoC.
> - interrupt-parent	: The parent interrupt controller.
>

Ok, I'll wait for Mark's feedback and repost with your suggestions. Thanks!

>> +Example:
>> +
>> +	max77802: pmic at 09 {
>> +		compatible = "maxim,max77802";
>> +		interrupt-parent = <&intc>;
>> +		interrupts = <26 IRQ_TYPE_NONE>;
>> +		reg = <0x09>;
>> +	};
> 

Best regards,
-- 
Javier Martinez Canillas
Open Source Group
Samsung Research America


From alexandre.belloni at free-electrons.com  Tue Aug 11 08:27:24 2015
From: alexandre.belloni at free-electrons.com (Alexandre Belloni)
Date: Tue, 11 Aug 2015 17:27:24 +0200
Subject: [PATCH v3 4/4] misc: atmel_tclib: get and use slow clock
In-Reply-To: <55C9FB5D.7030607@linaro.org>
References: <1439285884-16051-1-git-send-email-alexandre.belloni@free-electrons.com>
 <1439285884-16051-5-git-send-email-alexandre.belloni@free-electrons.com>
 <55C9FB5D.7030607@linaro.org>
Message-ID: <20150811152724.GR3411@piout.net>

On 11/08/2015 at 15:40:45 +0200, Daniel Lezcano wrote :
> On 08/11/2015 11:38 AM, Alexandre Belloni wrote:
> >From: Boris Brezillon <boris.brezillon at free-electrons.com>
> >
> >Commit dca1a4b5ff6e ("clk: at91: keep slow clk enabled to prevent system
> >hang") added a workaround for the slow clock as it is not properly handled
> >by its users.
> >
> >Get and use the slow clock as it is necessary for the timer counters.
> >
> >Signed-off-by: Boris Brezillon <boris.brezillon at free-electrons.com>
> >Signed-off-by: Alexandre Belloni <alexandre.belloni at free-electrons.com>
> >Acked-by: Greg Kroah-Hartman <gregkh at linuxfoundation.org>
> >---
> >Cc: Daniel Lezcano <daniel.lezcano at linaro.org>
> >Cc: Thomas Gleixner <tglx at linutronix.de>
> >Cc: Thierry Reding <thierry.reding at gmail.com>
> >Cc: linux-pwm at vger.kernel.org
> >
> >  drivers/clocksource/tcb_clksrc.c |  8 ++++++++
> >  drivers/misc/atmel_tclib.c       |  4 ++++
> >  drivers/pwm/pwm-atmel-tcb.c      | 23 ++++++++++++++++-------
> >  include/linux/atmel_tc.h         |  1 +
> >  4 files changed, 29 insertions(+), 7 deletions(-)
> >
> >diff --git a/drivers/clocksource/tcb_clksrc.c b/drivers/clocksource/tcb_clksrc.c
> >index b9b7277173c2..969ba03633b0 100644
> >--- a/drivers/clocksource/tcb_clksrc.c
> >+++ b/drivers/clocksource/tcb_clksrc.c
> >@@ -188,6 +188,13 @@ static int __init setup_clkevents(struct atmel_tc *tc, int clk32k_divisor_idx)
> >  	ret = clk_prepare_enable(t2_clk);
> >  	if (ret)
> >  		return ret;
> >+
> >+	ret = clk_prepare_enable(tc->slow_clk);
> >+	if (ret) {
> >+		clk_disable_unprepare(t2_clk);
> >+		return ret;
> >+	}
> >+
> >  	clk_disable(t2_clk);
> 
> Do you need t2_clk to be enabled in order to enable tc->slow_clk ?

No, I'll move clk_prepare_enable for tc->slow_clk before t2_clk.

> >+
> >+err_free_tc:
> >+	atmel_tc_free(tc);
> >+
> >+	return err;
> 
> What about clk_unprepare_disable(tc->slow_clk) ?
> 

Indeed, I trusted Boris a bit too much ;)

-- 
Alexandre Belloni, Free Electrons
Embedded Linux, Kernel and Android engineering
http://free-electrons.com


From Suzuki.Poulose at arm.com  Tue Aug 11 08:37:46 2015
From: Suzuki.Poulose at arm.com (Suzuki K. Poulose)
Date: Tue, 11 Aug 2015 16:37:46 +0100
Subject: [RFC PATCH 01/10] arm64: feature registers: Documentation
In-Reply-To: <20150811142301.GE23307@e104818-lin.cambridge.arm.com>
References: <1437731037-25795-1-git-send-email-suzuki.poulose@arm.com>
 <1437731037-25795-2-git-send-email-suzuki.poulose@arm.com>
 <20150810160636.GB15394@e104818-lin.cambridge.arm.com>
 <55C8E12E.6030305@arm.com>
 <CAKv+Gu-9GTzjqyT=NeBKjcaL7q-uFMToqPpprkyD-faG0J3mkQ@mail.gmail.com>
 <20150811142301.GE23307@e104818-lin.cambridge.arm.com>
Message-ID: <55CA16CA.8060609@arm.com>

On 11/08/15 15:23, Catalin Marinas wrote:
> On Mon, Aug 10, 2015 at 07:48:48PM +0200, Ard Biesheuvel wrote:
>>> On 10/08/15 17:06, Catalin Marinas wrote:
>>>> And to debunk some of the counter arguments:
>>>>
>>>> a) Running out of HWCAP bits - I really doubt this, we can always
>>>>      introduce 64 more via a new elf_hwcapX
>>
>> Note that ELF_HWCAP is also wired into ifunc resolution of GNU
>> indirect functions, which looks like a useful feature although it
>> isn't used that widely yet.
>
> I forgot to mention, we also need an HWCAP_CPUID with these patches when
> we expose the MRS interface. The ifunc resolver could use MRS when
> available. But I would still keep adding HWCAP bits for new features,
> even if we risk running out of the 64-bit we have now.
>

Sure, I will add the HWCAP_CPUID in the next version of the series.

Thanks
Suzuki



From joro at 8bytes.org  Tue Aug 11 08:39:47 2015
From: joro at 8bytes.org (Joerg Roedel)
Date: Tue, 11 Aug 2015 17:39:47 +0200
Subject: [PATCH v4 5/6] iommu/mediatek: Add mt8173 IOMMU driver
In-Reply-To: <1438597279-2937-6-git-send-email-yong.wu@mediatek.com>
References: <1438597279-2937-1-git-send-email-yong.wu@mediatek.com>
 <1438597279-2937-6-git-send-email-yong.wu@mediatek.com>
Message-ID: <20150811153947.GF14980@8bytes.org>

On Mon, Aug 03, 2015 at 06:21:18PM +0800, Yong Wu wrote:
> +/*
> + * There is only one iommu domain called the m4u domain that
> + * all Multimedia modules share.
> + */
> +static struct mtk_iommu_domain	*m4udom;

What is the reason you only implement one domain? Can't the IOMMU
isolate different devices from each other?


> +static struct iommu_domain *mtk_iommu_domain_alloc(unsigned type)
> +{
> +	struct mtk_iommu_domain *priv;
> +
> +	if (type != IOMMU_DOMAIN_UNMANAGED && type != IOMMU_DOMAIN_DMA)
> +		return NULL;
> +
> +	if (m4udom)/* The m4u domain exist. */
> +		return &m4udom->domain;

This is not going to work. If you always return the same domain the
iommu core might re-initialize domain state (and overwrite changed
state). At the moment this is only the domain-type which will change
every time this function is called, but there might be more.

> +static int mtk_iommu_add_device(struct device *dev)
> +{
> +	struct iommu_group *group;
> +	int ret;
> +
> +	if (!dev->archdata.iommu) /* Not a iommu client device */
> +		return -ENODEV;
> +
> +	group = iommu_group_get(dev);
> +	if (!group) {
> +		group = iommu_group_alloc();
> +		if (IS_ERR(group)) {
> +			dev_err(dev, "Failed to allocate IOMMU group\n");
> +			return PTR_ERR(group);
> +		}
> +	}
> +
> +	ret = iommu_group_add_device(group, dev);
> +	if (ret) {
> +		dev_err(dev, "Failed to add IOMMU group\n");
> +		goto err_group_put;
> +	}
> +
> +	ret = iommu_attach_group(&m4udom->domain, group);
> +	if (ret)
> +		dev_err(dev, "Failed to attach IOMMU group\n");
> +
> +err_group_put:
> +	iommu_group_put(group);
> +	return ret;
> +}

Putting every device into its own group indicates that the IOMMU can
isolate between single devices on the bus, which makes it even more
questionable that you only allow one domain for the whole driver.


	Joerg



From catalin.marinas at arm.com  Tue Aug 11 08:41:18 2015
From: catalin.marinas at arm.com (Catalin Marinas)
Date: Tue, 11 Aug 2015 16:41:18 +0100
Subject: [PATCH v5 2/6] x86/kasan, mm: introduce generic
 kasan_populate_zero_shadow()
In-Reply-To: <1439259499-13913-3-git-send-email-ryabinin.a.a@gmail.com>
References: <1439259499-13913-1-git-send-email-ryabinin.a.a@gmail.com>
 <1439259499-13913-3-git-send-email-ryabinin.a.a@gmail.com>
Message-ID: <20150811154117.GH23307@e104818-lin.cambridge.arm.com>

On Tue, Aug 11, 2015 at 05:18:15AM +0300, Andrey Ryabinin wrote:
> --- /dev/null
> +++ b/mm/kasan/kasan_init.c
[...]
> +#if CONFIG_PGTABLE_LEVELS > 3
> +pud_t kasan_zero_pud[PTRS_PER_PUD] __page_aligned_bss;
> +#endif
> +#if CONFIG_PGTABLE_LEVELS > 2
> +pmd_t kasan_zero_pmd[PTRS_PER_PMD] __page_aligned_bss;
> +#endif
> +pte_t kasan_zero_pte[PTRS_PER_PTE] __page_aligned_bss;

Is there any problem if you don't add the #ifs here? Wouldn't the linker
remove them if they are not used?

Original hunk copied here for easy comparison:

> -static int __init zero_pte_populate(pmd_t *pmd, unsigned long addr,
> -				unsigned long end)
> -{
> -	pte_t *pte = pte_offset_kernel(pmd, addr);
> -
> -	while (addr + PAGE_SIZE <= end) {
> -		WARN_ON(!pte_none(*pte));
> -		set_pte(pte, __pte(__pa_nodebug(kasan_zero_page)
> -					| __PAGE_KERNEL_RO));
> -		addr += PAGE_SIZE;
> -		pte = pte_offset_kernel(pmd, addr);
> -	}
> -	return 0;
> -}
[...]
> +static void __init zero_pte_populate(pmd_t *pmd, unsigned long addr,
> +				unsigned long end)
> +{
> +	pte_t *pte = pte_offset_kernel(pmd, addr);
> +	pte_t zero_pte;
> +
> +	zero_pte = pfn_pte(PFN_DOWN(__pa(kasan_zero_page)), PAGE_KERNEL);
> +	zero_pte = pte_wrprotect(zero_pte);
> +
> +	while (addr + PAGE_SIZE <= end) {
> +		set_pte_at(&init_mm, addr, pte, zero_pte);
> +		addr += PAGE_SIZE;
> +		pte = pte_offset_kernel(pmd, addr);
> +	}
> +}

I think there are some differences with the original x86 code. The first
one is the use of __pa_nodebug, does it cause any problems if
CONFIG_DEBUG_VIRTUAL is enabled?

The second is the use of a read-only attribute when mapping
kasan_zero_page on x86. Can it cope with a writable mapping?

If there are no issues, it should be documented in the commit log.

-- 
Catalin


From alexandre.belloni at free-electrons.com  Tue Aug 11 08:43:27 2015
From: alexandre.belloni at free-electrons.com (Alexandre Belloni)
Date: Tue, 11 Aug 2015 17:43:27 +0200
Subject: [PATCH] drivers/rtc/rtc-pl031.c: fix typo for author email
In-Reply-To: <1438150420-15035-1-git-send-email-leo.yan@linaro.org>
References: <1438150420-15035-1-git-send-email-leo.yan@linaro.org>
Message-ID: <20150811154327.GS3411@piout.net>

On 29/07/2015 at 14:13:40 +0800, Leo Yan wrote :
> The email address missed character ">", so add it.
> 
> Signed-off-by: Leo Yan <leo.yan at linaro.org>
> ---
>  drivers/rtc/rtc-pl031.c | 2 +-
>  1 file changed, 1 insertion(+), 1 deletion(-)
> 
Applied, thanks.

-- 
Alexandre Belloni, Free Electrons
Embedded Linux, Kernel and Android engineering
http://free-electrons.com


From will.deacon at arm.com  Tue Aug 11 08:48:32 2015
From: will.deacon at arm.com (Will Deacon)
Date: Tue, 11 Aug 2015 16:48:32 +0100
Subject: [PATCH] iommu/io-pgtable-arm: Unmap and free table when overwriting
 with block
Message-ID: <1439308112-29758-1-git-send-email-will.deacon@arm.com>

When installing a block mapping, we unconditionally overwrite a non-leaf
PTE if we find one. However, this can cause a problem if the following
sequence of events occur:

  (1) iommu_map called for a 4k (i.e. PAGE_SIZE) mapping at some address
      - We initialise the page table all the way down to a leaf entry
      - No TLB maintenance is required, because we're going from invalid
        to valid.

  (2) iommu_unmap is called on the mapping installed in (1)
      - We walk the page table to the final (leaf) entry and zero it
      - We only changed a valid leaf entry, so we invalidate leaf-only

  (3) iommu_map is called on the same address as (1), but this time for
      a 2MB (i.e. BLOCK_SIZE) mapping)
      - We walk the page table down to the penultimate level, where we
        find a table entry
      - We overwrite the table entry with a block mapping and return
        without any TLB maintenance and without freeing the memory used
        by the now-orphaned table.

This last step can lead to a walk-cache caching the overwritten table
entry, causing unexpected faults when the new mapping is accessed by a
device. One way to fix this would be to collapse the page table when
freeing the last page at a given level, but this would require expensive
iteration on every map call. Instead, this patch detects the case when
we are overwriting a table entry and explicitly unmaps the table first,
which takes care of both freeing and TLB invalidation.

Cc: <stable at vger.kernel.org>
Reported-by: Brian Starkey <brian.starkey at arm.com>
Tested-by: Brian Starkey <brian.starkey at arm.com>
Signed-off-by: Will Deacon <will.deacon at arm.com>
---

Joerg, could you queue this up for 4.3 please? It's a fix, but it's late
in the day for 4.2 and doesn't backport cleanly. Merging it with the Cc
stable tag is probably the easiest thing to do, then I can fix up the
conflicts as they arise.

 drivers/iommu/io-pgtable-arm.c | 17 ++++++++++++++++-
 1 file changed, 16 insertions(+), 1 deletion(-)

diff --git a/drivers/iommu/io-pgtable-arm.c b/drivers/iommu/io-pgtable-arm.c
index e4bc2b23ab96..73c07482f487 100644
--- a/drivers/iommu/io-pgtable-arm.c
+++ b/drivers/iommu/io-pgtable-arm.c
@@ -263,6 +263,10 @@ static void __arm_lpae_set_pte(arm_lpae_iopte *ptep, arm_lpae_iopte pte,
 					   sizeof(pte), DMA_TO_DEVICE);
 }
 
+static int __arm_lpae_unmap(struct arm_lpae_io_pgtable *data,
+			    unsigned long iova, size_t size, int lvl,
+			    arm_lpae_iopte *ptep);
+
 static int arm_lpae_init_pte(struct arm_lpae_io_pgtable *data,
 			     unsigned long iova, phys_addr_t paddr,
 			     arm_lpae_iopte prot, int lvl,
@@ -271,10 +275,21 @@ static int arm_lpae_init_pte(struct arm_lpae_io_pgtable *data,
 	arm_lpae_iopte pte = prot;
 	struct io_pgtable_cfg *cfg = &data->iop.cfg;
 
-	/* We require an unmap first */
 	if (iopte_leaf(*ptep, lvl)) {
+		/* We require an unmap first */
 		WARN_ON(!selftest_running);
 		return -EEXIST;
+	} else if (iopte_type(*ptep, lvl) == ARM_LPAE_PTE_TYPE_TABLE) {
+		/*
+		 * We need to unmap and free the old table before
+		 * overwriting it with a block entry.
+		 */
+		arm_lpae_iopte *tblp;
+		size_t sz = ARM_LPAE_BLOCK_SIZE(lvl, data);
+
+		tblp = ptep - ARM_LPAE_LVL_IDX(iova, lvl, data);
+		if (WARN_ON(__arm_lpae_unmap(data, iova, sz, lvl, tblp) != sz))
+			return -EINVAL;
 	}
 
 	if (cfg->quirks & IO_PGTABLE_QUIRK_ARM_NS)
-- 
2.1.4



From djkurtz at chromium.org  Tue Aug 11 08:54:02 2015
From: djkurtz at chromium.org (Daniel Kurtz)
Date: Tue, 11 Aug 2015 23:54:02 +0800
Subject: [PATCH 0/5] add GPT timer support for mt8173
In-Reply-To: <1436779969-18610-1-git-send-email-yingjoe.chen@mediatek.com>
References: <1436779969-18610-1-git-send-email-yingjoe.chen@mediatek.com>
Message-ID: <CAGS+omAeYhXDpBueG-F_gYBccqeaejN9k5bRKC78aDLfvHfnBA@mail.gmail.com>

On Mon, Jul 13, 2015 at 5:32 PM, Yingjoe Chen <yingjoe.chen at mediatek.com> wrote:
> This series add GPT timer support for mt8173. This is based on v4.2-rc1
> and Matthias' next branch (for dts parts).
>
> The first 2 patches comes from 'Add SMP bringup support for mt65xx socs'
> series [1]. I decide to move these 2 patches to this series, since it
> is more relevent here. They are changed based on Matthias' and Daniel's
> comments.
>
> [1] http://lists.infradead.org/pipermail/linux-mediatek/2015-May/000714.html
>
> Daniel Kurtz (1):
>   arm64: dts: mt8173: add timer node
>
> Yingjoe Chen (4):
>   clocksource: mediatek: do not enable GPT_CLK_EVT when setup
>   clocksource: mediatek: Use GPT as sched clock source
>   arm64: mediatek: enable MTK_TIMER
>   clk: mediatek: add 13mhz clock for MT8173

Was this mediatek clocksource patch set get forgotten again?
All 5 patches have have been reviewed, and I think the ones that need
it have been Ack'ed by Matthias and/or Stephen.
What is the plan for merging them?

Thanks,
-Dan

>
>  arch/arm64/Kconfig                       |  1 +
>  arch/arm64/boot/dts/mediatek/mt8173.dtsi |  9 +++++++++
>  drivers/clk/mediatek/clk-mt8173.c        |  5 +++++
>  drivers/clocksource/mtk_timer.c          | 26 ++++++++++++++++++++------
>  include/dt-bindings/clock/mt8173-clk.h   |  3 ++-
>  5 files changed, 37 insertions(+), 7 deletions(-)
>


From alexandre.belloni at free-electrons.com  Tue Aug 11 08:54:34 2015
From: alexandre.belloni at free-electrons.com (Alexandre Belloni)
Date: Tue, 11 Aug 2015 17:54:34 +0200
Subject: [PATCH 9/15 V2] drivers: rtc: Drop (un)likely before
 IS_ERR(_OR_NULL)
In-Reply-To: <b8be698a8625ceb9adc8da51cd9474626db7c3d1.1438339891.git.viresh.kumar@linaro.org>
References: <cdfa3fb76901fe1c4a5756e7e64cb3370cf6317a.1438331416.git.viresh.kumar@linaro.org>
 <b8be698a8625ceb9adc8da51cd9474626db7c3d1.1438339891.git.viresh.kumar@linaro.org>
Message-ID: <20150811155434.GT3411@piout.net>

On 31/07/2015 at 16:23:43 +0530, Viresh Kumar wrote :
> IS_ERR(_OR_NULL) already contain an 'unlikely' compiler flag and there
> is no need to do that again from its callers. Drop it.
> 
> gemini driver was using likely() for a failure case while the rtc driver
> is getting registered. That looks wrong and it should really be
> unlikely. But because we are killing all the unlikely() flags, lets kill
> that too.
> 
> Signed-off-by: Viresh Kumar <viresh.kumar at linaro.org>
> ---
> V1->V2:
> - Removed the likely() part from gemini driver and the changelog wasn't
>   updated to match that. Fixed the changelog now.
> 
>  drivers/rtc/interface.c  | 2 +-
>  drivers/rtc/rtc-bfin.c   | 2 +-
>  drivers/rtc/rtc-gemini.c | 2 +-
>  3 files changed, 3 insertions(+), 3 deletions(-)
> 

Applied, thanks.

-- 
Alexandre Belloni, Free Electrons
Embedded Linux, Kernel and Android engineering
http://free-electrons.com


From alexandre.belloni at free-electrons.com  Tue Aug 11 08:54:48 2015
From: alexandre.belloni at free-electrons.com (Alexandre Belloni)
Date: Tue, 11 Aug 2015 17:54:48 +0200
Subject: [PATCH] drivers: rtc: fix ptr_ret.cocci warnings
In-Reply-To: <20150731091703.GA140615@lkp-ib03>
References: <cdfa3fb76901fe1c4a5756e7e64cb3370cf6317a.1438331416.git.viresh.kumar@linaro.org>
 <20150731091703.GA140615@lkp-ib03>
Message-ID: <20150811155448.GU3411@piout.net>

On 31/07/2015 at 15:01:04 +0530, Viresh Kumar wrote :
> From: kbuild test robot <fengguang.wu at intel.com>
> 
> drivers/rtc/rtc-gemini.c:151:1-3: WARNING: PTR_ERR_OR_ZERO can be used
> 
> 
>  Use PTR_ERR_OR_ZERO rather than if(IS_ERR(...)) + PTR_ERR
> 
> Generated by: scripts/coccinelle/api/ptr_ret.cocci
> 
> Signed-off-by: Fengguang Wu <fengguang.wu at intel.com>
> Signed-off-by: Viresh Kumar <viresh.kumar at linaro.org>
> ---
> Got a cleanup patch from Fengguang, maybe we can apply this too.
> 
>  rtc-gemini.c |    5 +----
>  1 file changed, 1 insertion(+), 4 deletions(-)
> 
Applied, thanks.

-- 
Alexandre Belloni, Free Electrons
Embedded Linux, Kernel and Android engineering
http://free-electrons.com


From dinguyen at opensource.altera.com  Tue Aug 11 08:48:47 2015
From: dinguyen at opensource.altera.com (dinguyen at opensource.altera.com)
Date: Tue, 11 Aug 2015 10:48:47 -0500
Subject: [PATCHv2] arm64: dts: Add base stratix 10 dtsi
Message-ID: <1439308127-7412-1-git-send-email-dinguyen@opensource.altera.com>

From: Dinh Nguyen <dinguyen at opensource.altera.com>

Add the base DTS for Altera's SoCFPGA Stratix 10 platform.

Signed-off-by: Dinh Nguyen <dinguyen at opensource.altera.com>
---
v2: use interrupt-affinity for pmu node
---
 arch/arm64/Kconfig                                 |   5 +
 arch/arm64/boot/dts/Makefile                       |   1 +
 arch/arm64/boot/dts/altera/Makefile                |   5 +
 arch/arm64/boot/dts/altera/socfpga_stratix10.dtsi  | 358 +++++++++++++++++++++
 .../boot/dts/altera/socfpga_stratix10_socdk.dts    |  38 +++
 arch/arm64/configs/defconfig                       |   1 +
 6 files changed, 408 insertions(+)
 create mode 100644 arch/arm64/boot/dts/altera/Makefile
 create mode 100644 arch/arm64/boot/dts/altera/socfpga_stratix10.dtsi
 create mode 100644 arch/arm64/boot/dts/altera/socfpga_stratix10_socdk.dts

diff --git a/arch/arm64/Kconfig b/arch/arm64/Kconfig
index 318175f..0f8ab2b 100644
--- a/arch/arm64/Kconfig
+++ b/arch/arm64/Kconfig
@@ -207,6 +207,11 @@ config ARCH_SEATTLE
 	help
 	  This enables support for AMD Seattle SOC Family
 
+config ARCH_STRATIX10
+	bool "Altera's Stratix 10 SoCFPGA Family"
+	help
+	  This enables support for Altera's Stratix 10 SoCFPGA Family
+
 config ARCH_TEGRA
 	bool "NVIDIA Tegra SoC Family"
 	select ARCH_HAS_RESET_CONTROLLER
diff --git a/arch/arm64/boot/dts/Makefile b/arch/arm64/boot/dts/Makefile
index 38913be..7fb421a 100644
--- a/arch/arm64/boot/dts/Makefile
+++ b/arch/arm64/boot/dts/Makefile
@@ -1,3 +1,4 @@
+dts-dirs += altera
 dts-dirs += amd
 dts-dirs += apm
 dts-dirs += arm
diff --git a/arch/arm64/boot/dts/altera/Makefile b/arch/arm64/boot/dts/altera/Makefile
new file mode 100644
index 0000000..d7a6416
--- /dev/null
+++ b/arch/arm64/boot/dts/altera/Makefile
@@ -0,0 +1,5 @@
+dtb-$(CONFIG_ARCH_STRATIX10) += socfpga_stratix10_socdk.dtb
+
+always		:= $(dtb-y)
+subdir-y	:= $(dts-dirs)
+clean-files	:= *.dtb
diff --git a/arch/arm64/boot/dts/altera/socfpga_stratix10.dtsi b/arch/arm64/boot/dts/altera/socfpga_stratix10.dtsi
new file mode 100644
index 0000000..d67de22
--- /dev/null
+++ b/arch/arm64/boot/dts/altera/socfpga_stratix10.dtsi
@@ -0,0 +1,358 @@
+/*
+ * Copyright Altera Corporation (C) 2015. All rights reserved.
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms and conditions of the GNU General Public License,
+ * version 2, as published by the Free Software Foundation.
+ *
+ * This program is distributed in the hope 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.
+ *
+ * You should have received a copy of the GNU General Public License along with
+ * this program.  If not, see <http://www.gnu.org/licenses/>.
+ */
+
+/dts-v1/;
+
+/ {
+	compatible = "altr,socfpga-stratix10";
+	#address-cells = <1>;
+	#size-cells = <1>;
+
+	cpus {
+		#address-cells = <1>;
+		#size-cells = <0>;
+
+		cpu0: cpu at 0 {
+			compatible = "arm,cortex-a53", "arm,armv8";
+			device_type = "cpu";
+			enable-method = "psci";
+			reg = <0x0>;
+		};
+
+		cpu1: cpu at 1 {
+			compatible = "arm,cortex-a53", "arm,armv8";
+			device_type = "cpu";
+			enable-method = "psci";
+			reg = <0x1>;
+		};
+
+		cpu2: cpu at 2 {
+			compatible = "arm,cortex-a53", "arm,armv8";
+			device_type = "cpu";
+			enable-method = "psci";
+			reg = <0x2>;
+		};
+
+		cpu3: cpu at 3 {
+			compatible = "arm,cortex-a53", "arm,armv8";
+			device_type = "cpu";
+			enable-method = "psci";
+			reg = <0x3>;
+		};
+	};
+
+	pmu {
+		compatible = "arm,armv8-pmuv3";
+		interrupts = <0 120 8>,
+			     <0 121 8>,
+			     <0 122 8>,
+			     <0 123 8>;
+		interrupt-affinity = <&cpu0>,
+				     <&cpu1>,
+				     <&cpu2>,
+				     <&cpu3>;
+	};
+
+	psci {
+		compatible = "arm,psci-0.2";
+		method = "smc";
+	};
+
+	intc: intc at ffff8000 {
+		compatible = "arm,gic-400", "arm,cortex-a15-gic";
+		#interrupt-cells = <3>;
+		interrupt-controller;
+		reg = <0x0 0xffff9000 0x1000>,
+		      <0x0 0xffffa000 0x2000>,
+		      <0x0 0xffffc000 0x1000>,
+		      <0x0 0xffffd000 0x1000>;
+	};
+
+	soc {
+		#address-cells = <1>;
+		#size-cells = <1>;
+		compatible = "simple-bus";
+		device_type = "soc";
+		interrupt-parent = <&intc>;
+		ranges;
+
+		clkmgr at ffd1000 {
+			compatible = "altr,clk-mgr";
+			reg = <0xffd10000 0x1000>;
+		};
+
+		gmac0: ethernet at ff800000 {
+			compatible = "altr,socfpga-stmmac", "snps,dwmac-3.74a", "snps,dwmac";
+			reg = <0xff800000 0x2000>;
+			interrupts = <0 90 4>;
+			interrupt-names = "macirq";
+			mac-address = [00 00 00 00 00 00];
+			status = "disabled";
+		};
+
+		gmac1: ethernet at ff802000 {
+			compatible = "altr,socfpga-stmmac", "snps,dwmac-3.74a", "snps,dwmac";
+			reg = <0xff802000 0x2000>;
+			interrupts = <0 91 4>;
+			interrupt-names = "macirq";
+			mac-address = [00 00 00 00 00 00];
+			status = "disabled";
+		};
+
+		gmac2: ethernet at ff804000 {
+			compatible = "altr,socfpga-stmmac", "snps,dwmac-3.74a", "snps,dwmac";
+			reg = <0xff804000 0x2000>;
+			interrupts = <0 92 4>;
+			interrupt-names = "macirq";
+			mac-address = [00 00 00 00 00 00];
+			status = "disabled";
+		};
+
+		gpio0: gpio at ffc03200 {
+			#address-cells = <1>;
+			#size-cells = <0>;
+			compatible = "snps,dw-apb-gpio";
+			reg = <0xffc03200 0x100>;
+			status = "disabled";
+
+			porta: gpio-controller at 0 {
+				compatible = "snps,dw-apb-gpio-port";
+				gpio-controller;
+				#gpio-cells = <2>;
+				snps,nr-gpios = <24>;
+				reg = <0>;
+				interrupt-controller;
+				#interrupt-cells = <2>;
+				interrupts = <0 110 4>;
+			};
+		};
+
+		gpio1: gpio at ffc03300 {
+			#address-cells = <1>;
+			#size-cells = <0>;
+			compatible = "snps,dw-apb-gpio";
+			reg = <0xffc03300 0x100>;
+			status = "disabled";
+
+			portb: gpio-controller at 0 {
+				compatible = "snps,dw-apb-gpio-port";
+				gpio-controller;
+				#gpio-cells = <2>;
+				snps,nr-gpios = <24>;
+				reg = <0>;
+				interrupt-controller;
+				#interrupt-cells = <2>;
+				interrupts = <0 110 4>;
+			};
+		};
+
+		i2c0: i2c at ffc02800 {
+			#address-cells = <1>;
+			#size-cells = <0>;
+			compatible = "snps,designware-i2c";
+			reg = <0xffc02800 0x100>;
+			interrupts = <0 103 4>;
+			status = "disabled";
+		};
+
+		i2c1: i2c at ffc02900 {
+			#address-cells = <1>;
+			#size-cells = <0>;
+			compatible = "snps,designware-i2c";
+			reg = <0xffc02900 0x100>;
+			interrupts = <0 104 4>;
+			status = "disabled";
+		};
+
+		i2c2: i2c at ffc02a00 {
+			#address-cells = <1>;
+			#size-cells = <0>;
+			compatible = "snps,designware-i2c";
+			reg = <0xffc02a00 0x100>;
+			interrupts = <0 105 4>;
+			status = "disabled";
+		};
+
+		i2c3: i2c at ffc02b00 {
+			#address-cells = <1>;
+			#size-cells = <0>;
+			compatible = "snps,designware-i2c";
+			reg = <0xffc02b00 0x100>;
+			interrupts = <0 106 4>;
+			status = "disabled";
+		};
+
+		i2c4: i2c at ffc02c00 {
+			#address-cells = <1>;
+			#size-cells = <0>;
+			compatible = "snps,designware-i2c";
+			reg = <0xffc02c00 0x100>;
+			interrupts = <0 107 4>;
+			status = "disabled";
+		};
+
+		mmc: dwmmc0 at ff808000 {
+			#address-cells = <1>;
+			#size-cells = <0>;
+			compatible = "altr,socfpga-dw-mshc";
+			reg = <0xff808000 0x1000>;
+			interrupts = <0 96 4>;
+			fifo-depth = <0x400>;
+			status = "disabled";
+		};
+
+		ocram: sram at ffe00000 {
+			compatible = "mmio-sram";
+			reg = <0xffe00000 0x100000>;
+		};
+
+		rst: rstmgr at ffd11000 {
+			#reset-cells = <1>;
+			compatible = "altr,rst-mgr";
+			reg = <0xffd11000 0x1000>;
+		};
+
+		spi0: spi at ffda4000 {
+			compatible = "snps,dw-apb-ssi";
+			#address-cells = <1>;
+			#size-cells = <0>;
+			reg = <0xffda4000 0x1000>;
+			interrupts = <0 101 4>;
+			num-chipselect = <4>;
+			bus-num = <0>;
+			status = "disabled";
+		};
+
+		spi1: spi at ffda5000 {
+			compatible = "snps,dw-apb-ssi";
+			#address-cells = <1>;
+			#size-cells = <0>;
+			reg = <0xffda5000 0x1000>;
+			interrupts = <0 102 4>;
+			num-chipselect = <4>;
+			bus-num = <0>;
+			status = "disabled";
+		};
+
+		sysmgr: sysmgr at ffd12000 {
+			compatible = "altr,sys-mgr", "syscon";
+			reg = <0xffd12000 0x1000>;
+		};
+
+		/* Local timer */
+		timer {
+			compatible = "arm,armv8-timer";
+			interrupts = <1 13 0xf01>,
+				     <1 14 0xf01>,
+				     <1 11 0xf01>,
+				     <1 10 0xf01>;
+		};
+
+		timer0: timer0 at ffc03000 {
+			compatible = "snps,dw-apb-timer";
+			interrupts = <0 113 4>;
+			reg = <0xffc03000 0x100>;
+		};
+
+		timer1: timer1 at ffc03100 {
+			compatible = "snps,dw-apb-timer";
+			interrupts = <0 114 4>;
+			reg = <0xffc03100 0x100>;
+		};
+
+		timer2: timer2 at ffd00000 {
+			compatible = "snps,dw-apb-timer";
+			interrupts = <0 115 4>;
+			reg = <0xffd00000 0x100>;
+		};
+
+		timer3: timer3 at ffd00100 {
+			compatible = "snps,dw-apb-timer";
+			interrupts = <0 116 4>;
+			reg = <0xffd00100 0x100>;
+		};
+
+		uart0: serial0 at ffc02000 {
+			compatible = "snps,dw-apb-uart";
+			reg = <0xffc02000 0x100>;
+			interrupts = <0 108 4>;
+			reg-shift = <2>;
+			reg-io-width = <4>;
+			status = "disabled";
+		};
+
+		uart1: serial1 at ffc02100 {
+			compatible = "snps,dw-apb-uart";
+			reg = <0xffc02100 0x100>;
+			interrupts = <0 109 4>;
+			reg-shift = <2>;
+			reg-io-width = <4>;
+			status = "disabled";
+		};
+
+		usbphy0: usbphy at 0 {
+			#phy-cells = <0>;
+			compatible = "usb-nop-xceiv";
+			status = "okay";
+		};
+
+		usb0: usb at ffb00000 {
+			compatible = "snps,dwc2";
+			reg = <0xffb00000 0x40000>;
+			interrupts = <0 93 4>;
+			phys = <&usbphy0>;
+			phy-names = "usb2-phy";
+			status = "disabled";
+		};
+
+		usb1: usb at ffb40000 {
+			compatible = "snps,dwc2";
+			reg = <0xffb40000 0x40000>;
+			interrupts = <0 94 4>;
+			phys = <&usbphy0>;
+			phy-names = "usb2-phy";
+			status = "disabled";
+		};
+
+		watchdog0: watchdog at ffd00200 {
+			compatible = "snps,dw-wdt";
+			reg = <0xffd00200 0x100>;
+			interrupts = <0 117 4>;
+			status = "disabled";
+		};
+
+		watchdog1: watchdog at ffd00300 {
+			compatible = "snps,dw-wdt";
+			reg = <0xffd00300 0x100>;
+			interrupts = <0 118 4>;
+			status = "disabled";
+		};
+
+		watchdog2: watchdog at ffd00400 {
+			compatible = "snps,dw-wdt";
+			reg = <0xffd00400 0x100>;
+			interrupts = <0 125 4>;
+			status = "disabled";
+		};
+
+		watchdog3: watchdog at ffd00500 {
+			compatible = "snps,dw-wdt";
+			reg = <0xffd00500 0x100>;
+			interrupts = <0 126 4>;
+			status = "disabled";
+		};
+	};
+};
diff --git a/arch/arm64/boot/dts/altera/socfpga_stratix10_socdk.dts b/arch/arm64/boot/dts/altera/socfpga_stratix10_socdk.dts
new file mode 100644
index 0000000..8b162ef
--- /dev/null
+++ b/arch/arm64/boot/dts/altera/socfpga_stratix10_socdk.dts
@@ -0,0 +1,38 @@
+/*
+ * Copyright Altera Corporation (C) 2015. All rights reserved.
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms and conditions of the GNU General Public License,
+ * version 2, as published by the Free Software Foundation.
+ *
+ * This program is distributed in the hope 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.
+ *
+ * You should have received a copy of the GNU General Public License along with
+ * this program.  If not, see <http://www.gnu.org/licenses/>.
+ */
+
+/include/ "socfpga_stratix10.dtsi"
+
+/ {
+	model = "SoCFPGA Stratix 10 SoCDK";
+
+	aliases {
+		serial0 = &uart0;
+	};
+
+	chosen {
+		stdout-path = "serial0:115200n8";
+	};
+
+	memory {
+		device_type = "memory";
+		reg = <0x0 0x40000000>;
+	};
+};
+
+&uart0 {
+	status = "okay";
+};
diff --git a/arch/arm64/configs/defconfig b/arch/arm64/configs/defconfig
index 4e17e7e..ad3b636 100644
--- a/arch/arm64/configs/defconfig
+++ b/arch/arm64/configs/defconfig
@@ -36,6 +36,7 @@ CONFIG_ARCH_FSL_LS2085A=y
 CONFIG_ARCH_HISI=y
 CONFIG_ARCH_MEDIATEK=y
 CONFIG_ARCH_SEATTLE=y
+CONFIG_ARCH_STRATIX10=y
 CONFIG_ARCH_TEGRA=y
 CONFIG_ARCH_TEGRA_132_SOC=y
 CONFIG_ARCH_QCOM=y
-- 
2.4.5



From lina.iyer at linaro.org  Tue Aug 11 08:58:19 2015
From: lina.iyer at linaro.org (Lina Iyer)
Date: Tue, 11 Aug 2015 09:58:19 -0600
Subject: [PATCH 5/9] ARM: common: Introduce PM domains for CPUs/clusters
In-Reply-To: <CAMuHMdWRoUOBvz7MEGgF1oHz95D-GhaYG1yHr_kGe5NUQ0EnrQ@mail.gmail.com>
References: <1438731339-58317-1-git-send-email-lina.iyer@linaro.org>
 <1438731339-58317-6-git-send-email-lina.iyer@linaro.org>
 <CAL_JsqK67=DTtjZwwnonObLDjLbahkREfm0RvyXVV95bhR-d4Q@mail.gmail.com>
 <7hd1yyvf1b.fsf@deeprootsystems.com>
 <CAMuHMdWRoUOBvz7MEGgF1oHz95D-GhaYG1yHr_kGe5NUQ0EnrQ@mail.gmail.com>
Message-ID: <20150811155819.GH52339@linaro.org>

On Tue, Aug 11 2015 at 07:07 -0600, Geert Uytterhoeven wrote:
>On Sat, Aug 8, 2015 at 1:45 AM, Kevin Hilman <khilman at kernel.org> wrote:
>> Rob Herring <robherring2 at gmail.com> writes:
>>> On Tue, Aug 4, 2015 at 6:35 PM, Lina Iyer <lina.iyer at linaro.org> wrote:
>>>> +ARM CPU Power domains
>>>> +
>>>> +The device tree allows describing of CPU power domains in a SoC. In ARM SoC,
>>>> +CPUs may be grouped as clusters. A cluster may have CPUs, GIC, Coresight,
>>>> +caches, VFP and power controller and other peripheral hardware. Generally,
>>>> +when the CPUs in the cluster are idle/suspended, the shared resources may also
>>>> +be suspended and resumed before any of the CPUs resume execution.
>>>> +
>>>> +CPUs are the defined as the PM domain consumers and there is a PM domain
>>>> +provider for the CPUs. Bindings for generic PM domains (genpd) is described in
>>>> +[1].
>>>> +
>>>> +The ARM CPU PM domain follows the same binding convention as any generic PM
>>>> +domain. Additional binding properties are -
>>>> +
>>>> +- compatible:
>>>> +       Usage: required
>>>> +       Value type: <string>
>>>> +       Definition: Must also have
>>>> +                       "arm,pd"
>>>> +               inorder to initialize the genpd provider as ARM CPU PM domain.
>>>
>>> A compatible string should represent a particular h/w block. If it is
>>> generic, it should represent some sort of standard programming
>>> interface (e.g, AHCI, EHCI, etc.). This doesn't seem to be either and
>>> is rather just a mapping of what "driver" you want to use.
>>>
>>> I would expect that identifying a cpu's or cluster's power domain
>>> would be done by a phandle between the cpu/cluster node and power
>>> domain node.
>>
>> That's correct, the CPU nodes (and other nodes in the cluster like GIC,
>> Coresight, etc.) would have phandles to the cluster power domain node.
>
>Indeed.
>
>> But this series is meant to create the driver & binding for those cluster
>> power domain(s), so the question is how exactly describe it.
>
>I don't think I can add an "arm,pd" compatible property to e.g. a2sl
>(for CA15-CPUx) and a3sm (for CA15-SCU) in arch/arm/boot/dts/r8a73a4.dtsi,
>as these are just subdomains in a power domain hierarchy, all driven by a
>single hardware block.
>
>I can call e.g. a special registration method, or set up some ops pointer,
>for the a2sl and a3sm subdomains from within the "renesas,sysc-rmobile"
>driver.
>
I was hoping the macro would help in such a case. But since your domain
cannot be defined as arm,pd (could you explain why, I seem to missing
the obvious) would it help if I export a function like that the
renesas,sysc-rmobile driver could call and setup the CPU PM domain?
There is catch to it though.

The problem is -

To be generic and not have every driver write code to do this generic
functionality, the common code would want to instantiate the
arm_pm_domain and therefore the embedded genpd. A pointer instead of
actual object, would mean maintaining a list and iterating through it,
everytime the domain is suspended/resumed. With an object, I could just
do container_of and get the arm_pd. But, we also want to give the
platform an option to define certain aspects of the CPU's generic PM
domain like the flags, genpd callbacks etc, before the genpd is
registered with the framework.

Would such a function work for you? What does everyone think about the
@template?

struct generic_pm_domain *of_arm_cpu_domain(struct device_node *dn,
                struct of_arm_pd_ops *ops, struct generic_pm_domain *template)
{
        struct arm_pm_domain *pd;

        if (!of_device_is_available(dn))
                return NULL;

	/* This creates the memory for pd and setup basic stuff */
        pd = setup_arm_pd(dn);

	/* copy the platform's template genpd over to the pd's genpd */
        memcpy(&pd.genpd, template, sizeof(*template));

	/* 
	 * Now set up the additional ops and flags and register with
	 * genpd framework
	 */
        register_arm_pd(dn, pd);

	/* 
	 * Returning the genpd back to the platform so it can be added
	 * as subdomains to other domains etc.
	 */
        return &pd.genpd;
}
EXPORT_SYMBOL(of_arm_cpu_domain);

The catch is that platform drivers have to provide a template for the
genpd. The @template would never be registered, but would just be used
to create the common code's genpd.

Any other ideas?

Thanks,
Lina


From lee at kernel.org  Tue Aug 11 09:06:42 2015
From: lee at kernel.org (Lee Jones)
Date: Tue, 11 Aug 2015 17:06:42 +0100
Subject: [GIT PULL] RPi DT changes due for v4.3
Message-ID: <20150811160642.GQ18282@x1>

ARM SoC Chaps,

Please find a couple of simple RPi changes pertaining to Firmware.

The following changes since commit bc0195aad0daa2ad5b0d76cce22b167bc3435590:

  Linux 4.2-rc2 (2015-07-12 15:10:30 -0700)

are available in the git repository at:

  git://git.kernel.org/pub/scm/linux/kernel/git/rpi/linux-rpi.git tags/rpi-dt-for-armsoc-4.3

for you to fetch changes up to fd26f8830979de48eb3f1c253eb9d2ee2e468eb6:

  dt/bindings: Add binding for the Raspberry Pi firmware driver (2015-08-11 16:56:41 +0100)

----------------------------------------------------------------
 - New Firmware node and accompanying binding document

----------------------------------------------------------------
Eric Anholt (2):
      ARM: bcm2835: Add the firmware driver information to the RPi DT
      dt/bindings: Add binding for the Raspberry Pi firmware driver

 Documentation/devicetree/bindings/arm/bcm/raspberrypi,bcm2835-firmware.txt | 14 ++++++++++++++
 arch/arm/boot/dts/bcm2835-rpi.dtsi                                         |  7 +++++++
 2 files changed, 21 insertions(+)
 create mode 100644 Documentation/devicetree/bindings/arm/bcm/raspberrypi,bcm2835-firmware.txt


From stefan at agner.ch  Tue Aug 11 09:15:53 2015
From: stefan at agner.ch (Stefan Agner)
Date: Tue, 11 Aug 2015 18:15:53 +0200
Subject: [PATCH v5] ARM: early fixmap support for earlycon
Message-ID: <1439309753-30864-1-git-send-email-stefan@agner.ch>

Add early fixmap support, initially to support permanent, fixed
mapping support for early console. A temporary, early pte is
created which is migrated to a permanent mapping in paging_init.
This is also needed since the attributes may change as the memory
types are initialized. The 3MiB range of fixmap spans two pte
tables, but currently only one pte is created for early fixmap
support.

Re-add FIX_KMAP_BEGIN to the index calculation in highmem.c since
the index for kmap does not start at zero anymore. This reverts
4221e2e6b316 ("ARM: 8031/1: fixmap: remove FIX_KMAP_BEGIN and
FIX_KMAP_END") to some extent.

Cc: Mark Salter <msalter at redhat.com>
Cc: Russell King <linux at arm.linux.org.uk>
Cc: Kees Cook <keescook at chromium.org>
Cc: Laura Abbott <lauraa at codeaurora.org>
Cc: Arnd Bergmann <arnd at arndb.de>
Cc: Ard Biesheuvel <ard.biesheuvel at linaro.org>
Signed-off-by: Rob Herring <robh at kernel.org>
Signed-off-by: Stefan Agner <stefan at agner.ch>
---
Hi Russel,

All three compile issues were related to MMU/!MMU differences. The solution
is rather simple: This patch now only configures FIX_EARLYCON_MEM if the
MMU is available. This makes sense since on !MMU platform we can use ioremap
very early...

--
Stefan

Changes since v4:
- Add MMU dependency for FIX_EARLYCON_MEM
- Call early_fixmap_init conditionally, only if FIX_EARLYCON_MEM is set

Changes since v3:
- Remove address of on functions
- Clear all pmd's except early fixmap pmd in devicemaps_init
- Update comment in devicemaps_init since earlycon works now as debug method
- Add comment regarding FIXMAP_PAGE_IO/FIXMAP_PAGE_NOCACHE use

Changes since v2:
- Rebased and tested on rmk/for-next
- Flush TLB's when clearing the temporary PMD in early_fixmap_shutdown

Changes since v1 (RFC):
- Rebased and tested on v3.19-rc5
- Spelling errors in comments and commit message
- Added Rob's SOB

 arch/arm/Kconfig              |  3 ++
 arch/arm/include/asm/fixmap.h | 15 +++++++-
 arch/arm/kernel/setup.c       |  4 ++
 arch/arm/mm/highmem.c         |  6 +--
 arch/arm/mm/mmu.c             | 88 +++++++++++++++++++++++++++++++++++++++----
 5 files changed, 105 insertions(+), 11 deletions(-)

diff --git a/arch/arm/Kconfig b/arch/arm/Kconfig
index a750c14..1bcda7c 100644
--- a/arch/arm/Kconfig
+++ b/arch/arm/Kconfig
@@ -188,6 +188,9 @@ config ARCH_HAS_ILOG2_U64
 config ARCH_HAS_BANDGAP
 	bool
 
+config FIX_EARLYCON_MEM
+	def_bool y if MMU
+
 config GENERIC_HWEIGHT
 	bool
 	default y
diff --git a/arch/arm/include/asm/fixmap.h b/arch/arm/include/asm/fixmap.h
index 0415eae..58cfe9f 100644
--- a/arch/arm/include/asm/fixmap.h
+++ b/arch/arm/include/asm/fixmap.h
@@ -6,9 +6,13 @@
 #define FIXADDR_TOP		(FIXADDR_END - PAGE_SIZE)
 
 #include <asm/kmap_types.h>
+#include <asm/pgtable.h>
 
 enum fixed_addresses {
-	FIX_KMAP_BEGIN,
+	FIX_EARLYCON_MEM_BASE,
+	__end_of_permanent_fixed_addresses,
+
+	FIX_KMAP_BEGIN = __end_of_permanent_fixed_addresses,
 	FIX_KMAP_END = FIX_KMAP_BEGIN + (KM_TYPE_NR * NR_CPUS) - 1,
 
 	/* Support writing RO kernel text via kprobes, jump labels, etc. */
@@ -18,7 +22,16 @@ enum fixed_addresses {
 	__end_of_fixed_addresses
 };
 
+#define FIXMAP_PAGE_COMMON	(L_PTE_YOUNG | L_PTE_PRESENT | L_PTE_XN | L_PTE_DIRTY)
+
+#define FIXMAP_PAGE_NORMAL	(FIXMAP_PAGE_COMMON | L_PTE_MT_WRITEBACK)
+
+/* Used by set_fixmap_(io|nocache), both meant for mapping a device */
+#define FIXMAP_PAGE_IO		(FIXMAP_PAGE_COMMON | L_PTE_MT_DEV_SHARED | L_PTE_SHARED)
+#define FIXMAP_PAGE_NOCACHE	FIXMAP_PAGE_IO
+
 void __set_fixmap(enum fixed_addresses idx, phys_addr_t phys, pgprot_t prot);
+void __init early_fixmap_init(void);
 
 #include <asm-generic/fixmap.h>
 
diff --git a/arch/arm/kernel/setup.c b/arch/arm/kernel/setup.c
index 36c18b7..b3b7831 100644
--- a/arch/arm/kernel/setup.c
+++ b/arch/arm/kernel/setup.c
@@ -37,6 +37,7 @@
 #include <asm/cpu.h>
 #include <asm/cputype.h>
 #include <asm/elf.h>
+#include <asm/fixmap.h>
 #include <asm/procinfo.h>
 #include <asm/psci.h>
 #include <asm/sections.h>
@@ -954,6 +955,9 @@ void __init setup_arch(char **cmdline_p)
 	strlcpy(cmd_line, boot_command_line, COMMAND_LINE_SIZE);
 	*cmdline_p = cmd_line;
 
+	if (IS_ENABLED(CONFIG_FIX_EARLYCON_MEM))
+		early_fixmap_init();
+
 	parse_early_param();
 
 #ifdef CONFIG_MMU
diff --git a/arch/arm/mm/highmem.c b/arch/arm/mm/highmem.c
index ee8dfa7..9df5f09 100644
--- a/arch/arm/mm/highmem.c
+++ b/arch/arm/mm/highmem.c
@@ -79,7 +79,7 @@ void *kmap_atomic(struct page *page)
 
 	type = kmap_atomic_idx_push();
 
-	idx = type + KM_TYPE_NR * smp_processor_id();
+	idx = FIX_KMAP_BEGIN + type + KM_TYPE_NR * smp_processor_id();
 	vaddr = __fix_to_virt(idx);
 #ifdef CONFIG_DEBUG_HIGHMEM
 	/*
@@ -106,7 +106,7 @@ void __kunmap_atomic(void *kvaddr)
 
 	if (kvaddr >= (void *)FIXADDR_START) {
 		type = kmap_atomic_idx();
-		idx = type + KM_TYPE_NR * smp_processor_id();
+		idx = FIX_KMAP_BEGIN + type + KM_TYPE_NR * smp_processor_id();
 
 		if (cache_is_vivt())
 			__cpuc_flush_dcache_area((void *)vaddr, PAGE_SIZE);
@@ -138,7 +138,7 @@ void *kmap_atomic_pfn(unsigned long pfn)
 		return page_address(page);
 
 	type = kmap_atomic_idx_push();
-	idx = type + KM_TYPE_NR * smp_processor_id();
+	idx = FIX_KMAP_BEGIN + type + KM_TYPE_NR * smp_processor_id();
 	vaddr = __fix_to_virt(idx);
 #ifdef CONFIG_DEBUG_HIGHMEM
 	BUG_ON(!pte_none(get_fixmap_pte(vaddr)));
diff --git a/arch/arm/mm/mmu.c b/arch/arm/mm/mmu.c
index 6ca7d9a..fb9e817 100644
--- a/arch/arm/mm/mmu.c
+++ b/arch/arm/mm/mmu.c
@@ -357,6 +357,47 @@ const struct mem_type *get_mem_type(unsigned int type)
 }
 EXPORT_SYMBOL(get_mem_type);
 
+static pte_t *(*pte_offset_fixmap)(pmd_t *dir, unsigned long addr);
+
+static pte_t bm_pte[PTRS_PER_PTE + PTE_HWTABLE_PTRS]
+	__aligned(PTE_HWTABLE_OFF + PTE_HWTABLE_SIZE) __initdata;
+
+static pte_t * __init pte_offset_early_fixmap(pmd_t *dir, unsigned long addr)
+{
+	return &bm_pte[pte_index(addr)];
+}
+
+static pte_t *pte_offset_late_fixmap(pmd_t *dir, unsigned long addr)
+{
+	return pte_offset_kernel(dir, addr);
+}
+
+static inline pmd_t * __init fixmap_pmd(unsigned long addr)
+{
+	pgd_t *pgd = pgd_offset_k(addr);
+	pud_t *pud = pud_offset(pgd, addr);
+	pmd_t *pmd = pmd_offset(pud, addr);
+
+	return pmd;
+}
+
+void __init early_fixmap_init(void)
+{
+	pmd_t *pmd;
+
+	/*
+	 * The early fixmap range spans multiple pmds, for which
+	 * we are not prepared:
+	 */
+	BUILD_BUG_ON((__fix_to_virt(__end_of_permanent_fixed_addresses) >> PMD_SHIFT)
+		     != FIXADDR_TOP >> PMD_SHIFT);
+
+	pmd = fixmap_pmd(FIXADDR_TOP);
+	pmd_populate_kernel(&init_mm, pmd, bm_pte);
+
+	pte_offset_fixmap = pte_offset_early_fixmap;
+}
+
 /*
  * To avoid TLB flush broadcasts, this uses local_flush_tlb_kernel_range().
  * As a result, this can only be called with preemption disabled, as under
@@ -365,7 +406,7 @@ EXPORT_SYMBOL(get_mem_type);
 void __set_fixmap(enum fixed_addresses idx, phys_addr_t phys, pgprot_t prot)
 {
 	unsigned long vaddr = __fix_to_virt(idx);
-	pte_t *pte = pte_offset_kernel(pmd_off_k(vaddr), vaddr);
+	pte_t *pte = pte_offset_fixmap(pmd_off_k(vaddr), vaddr);
 
 	/* Make sure fixmap region does not exceed available allocation. */
 	BUILD_BUG_ON(FIXADDR_START + (__end_of_fixed_addresses * PAGE_SIZE) >
@@ -855,7 +896,7 @@ static void __init create_mapping(struct map_desc *md)
 	}
 
 	if ((md->type == MT_DEVICE || md->type == MT_ROM) &&
-	    md->virtual >= PAGE_OFFSET &&
+	    md->virtual >= PAGE_OFFSET && md->virtual < FIXADDR_START &&
 	    (md->virtual < VMALLOC_START || md->virtual >= VMALLOC_END)) {
 		pr_warn("BUG: mapping for 0x%08llx at 0x%08lx out of vmalloc space\n",
 			(long long)__pfn_to_phys((u64)md->pfn), md->virtual);
@@ -1213,10 +1254,10 @@ void __init arm_mm_memblock_reserve(void)
 
 /*
  * Set up the device mappings.  Since we clear out the page tables for all
- * mappings above VMALLOC_START, we will remove any debug device mappings.
- * This means you have to be careful how you debug this function, or any
- * called function.  This means you can't use any function or debugging
- * method which may touch any device, otherwise the kernel _will_ crash.
+ * mappings above VMALLOC_START, except early fixmap, we might remove debug
+ * device mappings.  This means earlycon can be used to debug this function
+ * Any other function or debugging method which may touch any device _will_
+ * crash the kernel.
  */
 static void __init devicemaps_init(const struct machine_desc *mdesc)
 {
@@ -1231,7 +1272,10 @@ static void __init devicemaps_init(const struct machine_desc *mdesc)
 
 	early_trap_init(vectors);
 
-	for (addr = VMALLOC_START; addr; addr += PMD_SIZE)
+	/*
+	 * Clear page table except top pmd used by early fixmaps
+	 */
+	for (addr = VMALLOC_START; addr < (FIXADDR_TOP & PMD_MASK); addr += PMD_SIZE)
 		pmd_clear(pmd_off_k(addr));
 
 	/*
@@ -1483,6 +1527,35 @@ void __init early_paging_init(const struct machine_desc *mdesc)
 
 #endif
 
+static void __init early_fixmap_shutdown(void)
+{
+	int i;
+	unsigned long va = fix_to_virt(__end_of_permanent_fixed_addresses - 1);
+
+	pte_offset_fixmap = pte_offset_late_fixmap;
+	pmd_clear(fixmap_pmd(va));
+	local_flush_tlb_kernel_page(va);
+
+	for (i = 0; i < __end_of_permanent_fixed_addresses; i++) {
+		pte_t *pte;
+		struct map_desc map;
+
+		map.virtual = fix_to_virt(i);
+		pte = pte_offset_early_fixmap(pmd_off_k(map.virtual), map.virtual);
+
+		/* Only i/o device mappings are supported ATM */
+		if (pte_none(*pte) ||
+		    (pte_val(*pte) & L_PTE_MT_MASK) != L_PTE_MT_DEV_SHARED)
+			continue;
+
+		map.pfn = pte_pfn(*pte);
+		map.type = MT_DEVICE;
+		map.length = PAGE_SIZE;
+
+		create_mapping(&map);
+	}
+}
+
 /*
  * paging_init() sets up the page tables, initialises the zone memory
  * maps, and sets up the zero page, bad page and bad page tables.
@@ -1495,6 +1568,7 @@ void __init paging_init(const struct machine_desc *mdesc)
 	prepare_page_table();
 	map_lowmem();
 	dma_contiguous_remap();
+	early_fixmap_shutdown();
 	devicemaps_init(mdesc);
 	kmap_init();
 	tcm_init();
-- 
2.5.0



From khilman at kernel.org  Tue Aug 11 09:16:43 2015
From: khilman at kernel.org (Kevin Hilman)
Date: Tue, 11 Aug 2015 09:16:43 -0700
Subject: [PATCH stable/3.14] ARM: sunxi: fix build for THUMB2_KERNEL
Message-ID: <1439309803-20163-1-git-send-email-khilman@kernel.org>

From: Arnd Bergmann <arnd at arndb.de>

Building an SMP kernel for the sunxi platform with THUMB2 instructions
fails with this error at the moment:

headsmp.S:7: Error: Thumb encoding does not support an immediate here -- `msr cpsr_fsxc,#0xd3'

Since the generic secondary_startup function already does
the same thing in a safe way, we can just drop the private
sunxi implementation and jump straight to secondary_startup.

Signed-off-by: Arnd Bergmann <arnd at arndb.de>
Cc: Maxime Ripard <maxime.ripard at free-electrons.com>
Cc: <stable at vger.kernel.org> # v3.14
(cherry picked from commit 1146b600044de64af0ef775025731eeef1fa2189)
Signed-off-by: Kevin Hilman <khilman at linaro.org>
---
 arch/arm/include/asm/smp.h    | 1 +
 arch/arm/mach-sunxi/Makefile  | 2 +-
 arch/arm/mach-sunxi/headsmp.S | 9 ---------
 arch/arm/mach-sunxi/platsmp.c | 2 +-
 4 files changed, 3 insertions(+), 11 deletions(-)
 delete mode 100644 arch/arm/mach-sunxi/headsmp.S

diff --git a/arch/arm/include/asm/smp.h b/arch/arm/include/asm/smp.h
index 22a3b9b5d4a1..4157aec4e307 100644
--- a/arch/arm/include/asm/smp.h
+++ b/arch/arm/include/asm/smp.h
@@ -74,6 +74,7 @@ struct secondary_data {
 };
 extern struct secondary_data secondary_data;
 extern volatile int pen_release;
+extern void secondary_startup(void);
 
 extern int __cpu_disable(void);
 
diff --git a/arch/arm/mach-sunxi/Makefile b/arch/arm/mach-sunxi/Makefile
index d9397202d6ec..27b168f121a1 100644
--- a/arch/arm/mach-sunxi/Makefile
+++ b/arch/arm/mach-sunxi/Makefile
@@ -1,2 +1,2 @@
 obj-$(CONFIG_ARCH_SUNXI) += sunxi.o
-obj-$(CONFIG_SMP) += platsmp.o headsmp.o
+obj-$(CONFIG_SMP) += platsmp.o
diff --git a/arch/arm/mach-sunxi/headsmp.S b/arch/arm/mach-sunxi/headsmp.S
deleted file mode 100644
index a10d494fb37b..000000000000
--- a/arch/arm/mach-sunxi/headsmp.S
+++ /dev/null
@@ -1,9 +0,0 @@
-#include <linux/linkage.h>
-#include <linux/init.h>
-
-        .section ".text.head", "ax"
-
-ENTRY(sun6i_secondary_startup)
-	msr	cpsr_fsxc, #0xd3
-	b	secondary_startup
-ENDPROC(sun6i_secondary_startup)
diff --git a/arch/arm/mach-sunxi/platsmp.c b/arch/arm/mach-sunxi/platsmp.c
index 7b141d8342a1..0c7dbce033cc 100644
--- a/arch/arm/mach-sunxi/platsmp.c
+++ b/arch/arm/mach-sunxi/platsmp.c
@@ -82,7 +82,7 @@ static int sun6i_smp_boot_secondary(unsigned int cpu,
 	spin_lock(&cpu_lock);
 
 	/* Set CPU boot address */
-	writel(virt_to_phys(sun6i_secondary_startup),
+	writel(virt_to_phys(secondary_startup),
 	       cpucfg_membase + CPUCFG_PRIVATE0_REG);
 
 	/* Assert the CPU core in reset */
-- 
2.4.5



From codekipper at gmail.com  Tue Aug 11 09:19:25 2015
From: codekipper at gmail.com (codekipper at gmail.com)
Date: Tue, 11 Aug 2015 18:19:25 +0200
Subject: [PATCH] pinctrl: sun4i: add spdif to pin description.
Message-ID: <1439309965-9530-1-git-send-email-codekipper@gmail.com>

From: Marcus Cooper <codekipper at gmail.com>

Signed-off-by: Marcus Cooper <codekipper at gmail.com>
---
 drivers/pinctrl/sunxi/pinctrl-sun4i-a10.c | 9 ++++++---
 1 file changed, 6 insertions(+), 3 deletions(-)

diff --git a/drivers/pinctrl/sunxi/pinctrl-sun4i-a10.c b/drivers/pinctrl/sunxi/pinctrl-sun4i-a10.c
index 7376a97..daf7dec 100644
--- a/drivers/pinctrl/sunxi/pinctrl-sun4i-a10.c
+++ b/drivers/pinctrl/sunxi/pinctrl-sun4i-a10.c
@@ -135,7 +135,8 @@ static const struct sunxi_desc_pin sun4i_a10_pins[] = {
 	SUNXI_PIN(SUNXI_PINCTRL_PIN(B, 3),
 		  SUNXI_FUNCTION(0x0, "gpio_in"),
 		  SUNXI_FUNCTION(0x1, "gpio_out"),
-		  SUNXI_FUNCTION(0x2, "ir0")),		/* TX */
+		  SUNXI_FUNCTION(0x2, "ir0"),		/* TX */
+		  SUNXI_FUNCTION(0x4, "spdif")),        /* MCLK */
 	SUNXI_PIN(SUNXI_PINCTRL_PIN(B, 4),
 		  SUNXI_FUNCTION(0x0, "gpio_in"),
 		  SUNXI_FUNCTION(0x1, "gpio_out"),
@@ -176,11 +177,13 @@ static const struct sunxi_desc_pin sun4i_a10_pins[] = {
 		  SUNXI_FUNCTION(0x0, "gpio_in"),
 		  SUNXI_FUNCTION(0x1, "gpio_out"),
 		  SUNXI_FUNCTION(0x2, "i2s"),		/* DI */
-		  SUNXI_FUNCTION(0x3, "ac97")),		/* DI */
+		  SUNXI_FUNCTION(0x3, "ac97"),		/* DI */
+		  SUNXI_FUNCTION(0x4, "spdif")),        /* DI */
 	SUNXI_PIN(SUNXI_PINCTRL_PIN(B, 13),
 		  SUNXI_FUNCTION(0x0, "gpio_in"),
 		  SUNXI_FUNCTION(0x1, "gpio_out"),
-		  SUNXI_FUNCTION(0x2, "spi2")),		/* CS1 */
+		  SUNXI_FUNCTION(0x2, "spi2"),		/* CS1 */
+		  SUNXI_FUNCTION(0x4, "spdif")),        /* DO */
 	SUNXI_PIN(SUNXI_PINCTRL_PIN(B, 14),
 		  SUNXI_FUNCTION(0x0, "gpio_in"),
 		  SUNXI_FUNCTION(0x1, "gpio_out"),
-- 
2.5.0



From ryabinin.a.a at gmail.com  Tue Aug 11 09:25:12 2015
From: ryabinin.a.a at gmail.com (Andrey Ryabinin)
Date: Tue, 11 Aug 2015 19:25:12 +0300
Subject: [PATCH v5 2/6] x86/kasan, mm: introduce generic
 kasan_populate_zero_shadow()
In-Reply-To: <20150811154117.GH23307@e104818-lin.cambridge.arm.com>
References: <1439259499-13913-1-git-send-email-ryabinin.a.a@gmail.com>
 <1439259499-13913-3-git-send-email-ryabinin.a.a@gmail.com>
 <20150811154117.GH23307@e104818-lin.cambridge.arm.com>
Message-ID: <55CA21E8.2060704@gmail.com>



On 08/11/2015 06:41 PM, Catalin Marinas wrote:
> On Tue, Aug 11, 2015 at 05:18:15AM +0300, Andrey Ryabinin wrote:
>> --- /dev/null
>> +++ b/mm/kasan/kasan_init.c
> [...]
>> +#if CONFIG_PGTABLE_LEVELS > 3
>> +pud_t kasan_zero_pud[PTRS_PER_PUD] __page_aligned_bss;
>> +#endif
>> +#if CONFIG_PGTABLE_LEVELS > 2
>> +pmd_t kasan_zero_pmd[PTRS_PER_PMD] __page_aligned_bss;
>> +#endif
>> +pte_t kasan_zero_pte[PTRS_PER_PTE] __page_aligned_bss;
> 
> Is there any problem if you don't add the #ifs here? Wouldn't the linker
> remove them if they are not used?
> 


> Original hunk copied here for easy comparison:
> 
>> -static int __init zero_pte_populate(pmd_t *pmd, unsigned long addr,
>> -				unsigned long end)
>> -{
>> -	pte_t *pte = pte_offset_kernel(pmd, addr);
>> -
>> -	while (addr + PAGE_SIZE <= end) {
>> -		WARN_ON(!pte_none(*pte));
>> -		set_pte(pte, __pte(__pa_nodebug(kasan_zero_page)
>> -					| __PAGE_KERNEL_RO));
>> -		addr += PAGE_SIZE;
>> -		pte = pte_offset_kernel(pmd, addr);
>> -	}
>> -	return 0;
>> -}
> [...]
>> +static void __init zero_pte_populate(pmd_t *pmd, unsigned long addr,
>> +				unsigned long end)
>> +{
>> +	pte_t *pte = pte_offset_kernel(pmd, addr);
>> +	pte_t zero_pte;
>> +
>> +	zero_pte = pfn_pte(PFN_DOWN(__pa(kasan_zero_page)), PAGE_KERNEL);
>> +	zero_pte = pte_wrprotect(zero_pte);
>> +
>> +	while (addr + PAGE_SIZE <= end) {
>> +		set_pte_at(&init_mm, addr, pte, zero_pte);
>> +		addr += PAGE_SIZE;
>> +		pte = pte_offset_kernel(pmd, addr);
>> +	}
>> +}
> 
> I think there are some differences with the original x86 code. The first
> one is the use of __pa_nodebug, does it cause any problems if
> CONFIG_DEBUG_VIRTUAL is enabled?
> 
__pa_nodebug() should be used before kasan_early_init(), this piece of code
executed far later, so it's ok to use __pa() here.
This was actually a mistake in original code to use __pa_nodebug().

> The second is the use of a read-only attribute when mapping
> kasan_zero_page on x86. Can it cope with a writable mapping?
> 

Did you miss this line:

+	zero_pte = pte_wrprotect(zero_pte);

?


> If there are no issues, it should be documented in the commit log.
> 


From ryabinin.a.a at gmail.com  Tue Aug 11 09:30:42 2015
From: ryabinin.a.a at gmail.com (Andrey Ryabinin)
Date: Tue, 11 Aug 2015 19:30:42 +0300
Subject: [PATCH v5 2/6] x86/kasan, mm: introduce generic
 kasan_populate_zero_shadow()
In-Reply-To: <20150811154117.GH23307@e104818-lin.cambridge.arm.com>
References: <1439259499-13913-1-git-send-email-ryabinin.a.a@gmail.com>
 <1439259499-13913-3-git-send-email-ryabinin.a.a@gmail.com>
 <20150811154117.GH23307@e104818-lin.cambridge.arm.com>
Message-ID: <55CA2332.7040206@gmail.com>



On 08/11/2015 06:41 PM, Catalin Marinas wrote:
> On Tue, Aug 11, 2015 at 05:18:15AM +0300, Andrey Ryabinin wrote:
>> --- /dev/null
>> +++ b/mm/kasan/kasan_init.c
> [...]
>> +#if CONFIG_PGTABLE_LEVELS > 3
>> +pud_t kasan_zero_pud[PTRS_PER_PUD] __page_aligned_bss;
>> +#endif
>> +#if CONFIG_PGTABLE_LEVELS > 2
>> +pmd_t kasan_zero_pmd[PTRS_PER_PMD] __page_aligned_bss;
>> +#endif
>> +pte_t kasan_zero_pte[PTRS_PER_PTE] __page_aligned_bss;
> 
> Is there any problem if you don't add the #ifs here? Wouldn't the linker
> remove them if they are not used?
> 

AFAIK such optimization is possible if we build with -fdata-sections flag and
use --gc-sections flag in linker, but we don't do this.


From catalin.marinas at arm.com  Tue Aug 11 09:37:10 2015
From: catalin.marinas at arm.com (Catalin Marinas)
Date: Tue, 11 Aug 2015 17:37:10 +0100
Subject: [PATCH v5 5/6] arm64: add KASAN support
In-Reply-To: <1439259499-13913-6-git-send-email-ryabinin.a.a@gmail.com>
References: <1439259499-13913-1-git-send-email-ryabinin.a.a@gmail.com>
 <1439259499-13913-6-git-send-email-ryabinin.a.a@gmail.com>
Message-ID: <20150811163709.GI23307@e104818-lin.cambridge.arm.com>

On Tue, Aug 11, 2015 at 05:18:18AM +0300, Andrey Ryabinin wrote:
> This patch adds arch specific code for kernel address sanitizer
> (see Documentation/kasan.txt).
> 
> 1/8 of kernel addresses reserved for shadow memory. There was no
> big enough hole for this, so virtual addresses for shadow were
> stolen from vmalloc area.
> 
> At early boot stage the whole shadow region populated with just
> one physical page (kasan_zero_page). Later, this page reused
> as readonly zero shadow for some memory that KASan currently
> don't track (vmalloc).
> After mapping the physical memory, pages for shadow memory are
> allocated and mapped.
> 
> Functions like memset/memmove/memcpy do a lot of memory accesses.
> If bad pointer passed to one of these function it is important
> to catch this. Compiler's instrumentation cannot do this since
> these functions are written in assembly.
> KASan replaces memory functions with manually instrumented variants.
> Original functions declared as weak symbols so strong definitions
> in mm/kasan/kasan.c could replace them. Original functions have aliases
> with '__' prefix in name, so we could call non-instrumented variant
> if needed.
> Some files built without kasan instrumentation (e.g. mm/slub.c).
> Original mem* function replaced (via #define) with prefixed variants
> to disable memory access checks for such files.
> 
> Signed-off-by: Andrey Ryabinin <ryabinin.a.a at gmail.com>
> Tested-by: Linus Walleij <linus.walleij at linaro.org>

Reviewed-by: Catalin Marinas <catalin.marinas at arm.com>


From catalin.marinas at arm.com  Tue Aug 11 09:40:11 2015
From: catalin.marinas at arm.com (Catalin Marinas)
Date: Tue, 11 Aug 2015 17:40:11 +0100
Subject: [PATCH v5 2/6] x86/kasan, mm: introduce generic
 kasan_populate_zero_shadow()
In-Reply-To: <55CA21E8.2060704@gmail.com>
References: <1439259499-13913-1-git-send-email-ryabinin.a.a@gmail.com>
 <1439259499-13913-3-git-send-email-ryabinin.a.a@gmail.com>
 <20150811154117.GH23307@e104818-lin.cambridge.arm.com>
 <55CA21E8.2060704@gmail.com>
Message-ID: <20150811164010.GJ23307@e104818-lin.cambridge.arm.com>

On Tue, Aug 11, 2015 at 07:25:12PM +0300, Andrey Ryabinin wrote:
> On 08/11/2015 06:41 PM, Catalin Marinas wrote:
> > On Tue, Aug 11, 2015 at 05:18:15AM +0300, Andrey Ryabinin wrote:
> >> --- /dev/null
> >> +++ b/mm/kasan/kasan_init.c
> > [...]
> >> +#if CONFIG_PGTABLE_LEVELS > 3
> >> +pud_t kasan_zero_pud[PTRS_PER_PUD] __page_aligned_bss;
> >> +#endif
> >> +#if CONFIG_PGTABLE_LEVELS > 2
> >> +pmd_t kasan_zero_pmd[PTRS_PER_PMD] __page_aligned_bss;
> >> +#endif
> >> +pte_t kasan_zero_pte[PTRS_PER_PTE] __page_aligned_bss;
> > 
> > Is there any problem if you don't add the #ifs here? Wouldn't the linker
> > remove them if they are not used?
> 
> > Original hunk copied here for easy comparison:
> > 
> >> -static int __init zero_pte_populate(pmd_t *pmd, unsigned long addr,
> >> -				unsigned long end)
> >> -{
> >> -	pte_t *pte = pte_offset_kernel(pmd, addr);
> >> -
> >> -	while (addr + PAGE_SIZE <= end) {
> >> -		WARN_ON(!pte_none(*pte));
> >> -		set_pte(pte, __pte(__pa_nodebug(kasan_zero_page)
> >> -					| __PAGE_KERNEL_RO));
> >> -		addr += PAGE_SIZE;
> >> -		pte = pte_offset_kernel(pmd, addr);
> >> -	}
> >> -	return 0;
> >> -}
> > [...]
> >> +static void __init zero_pte_populate(pmd_t *pmd, unsigned long addr,
> >> +				unsigned long end)
> >> +{
> >> +	pte_t *pte = pte_offset_kernel(pmd, addr);
> >> +	pte_t zero_pte;
> >> +
> >> +	zero_pte = pfn_pte(PFN_DOWN(__pa(kasan_zero_page)), PAGE_KERNEL);
> >> +	zero_pte = pte_wrprotect(zero_pte);
> >> +
> >> +	while (addr + PAGE_SIZE <= end) {
> >> +		set_pte_at(&init_mm, addr, pte, zero_pte);
> >> +		addr += PAGE_SIZE;
> >> +		pte = pte_offset_kernel(pmd, addr);
> >> +	}
> >> +}
> > 
> > I think there are some differences with the original x86 code. The first
> > one is the use of __pa_nodebug, does it cause any problems if
> > CONFIG_DEBUG_VIRTUAL is enabled?
> 
> __pa_nodebug() should be used before kasan_early_init(), this piece of code
> executed far later, so it's ok to use __pa() here.
> This was actually a mistake in original code to use __pa_nodebug().

OK. So please add a comment in the commit log.

> > The second is the use of a read-only attribute when mapping
> > kasan_zero_page on x86. Can it cope with a writable mapping?
> > 
> 
> Did you miss this line:
> 
> +	zero_pte = pte_wrprotect(zero_pte);

Ah, yes, I missed this.

Anyway, for this patch:

Acked-by: Catalin Marinas <catalin.marinas at arm.com>

Not sure how you plan to merge it though since there are x86
dependencies. I could send the whole series via tip or the mm tree (and
I guess it's pretty late for 4.3).


From shawnguo at kernel.org  Tue Aug 11 09:42:29 2015
From: shawnguo at kernel.org (Shawn Guo)
Date: Wed, 12 Aug 2015 00:42:29 +0800
Subject: [GIT PULL 1/3] ARM: imx: soc updates for 4.3
Message-ID: <1439311351-5268-1-git-send-email-shawnguo@kernel.org>

Hi arm-soc maintainers,

This is the i.MX SoC changes for 4.3.  There are some input and rtc
changes, because they are applied as a series.  Subsystem maintainers
have ACKed these changes, so it should be fine to send them via arm-soc
tree.

Shawn

The following changes since commit d770e558e21961ad6cfdf0ff7df0eb5d7d4f0754:

  Linux 4.2-rc1 (2015-07-05 11:01:52 -0700)

are available in the git repository at:

  git://git.kernel.org/pub/scm/linux/kernel/git/shawnguo/linux.git tags/imx-soc-4.3

for you to fetch changes up to 8a0fa1843638c5078e6606114ed8bdf9ea56fab1:

  rtc: snvs: select option REGMAP_MMIO (2015-08-11 23:04:47 +0800)

----------------------------------------------------------------
The i.MX SoC changes for 4.3:
 - Add i.MX6 Ultralite SoC support, which is the newest addition to
   i.MX6 family.  It integrates a single Cortex-A7 core and a power
   management module that reduces the complexity of external power
   supply and simplifies power sequencing.
 - Change SNVS RTC driver to use syscon interface for register access,
   and add SNVS power key driver support.
 - Add a second clock for mxc rtc driver, and support device tree probe
   for the driver.
 - Add FEC MAC reference clock and phy fixup initialization for i.MX6UL
   platform.

----------------------------------------------------------------
Anson Huang (1):
      ARM: imx: add low-level debug support for i.mx6ul

Frank Li (4):
      ARM: imx: add i.mx6ul msl support
      rtc: snvs: use syscon to access register
      Document: dt: fsl: snvs: change support syscon
      Document: devicetree: input: imx: i.mx snvs power device tree bindings

Fugang Duan (2):
      ARM: imx6ul: add fec bits to GPR syscon definition
      ARM: imx6ul: add fec MAC refrence clock and phy fixup init

Philippe Reynes (3):
      rtc: mxc: use a second rtc clock
      dt-binding: document the binding for mxc rtc
      rtc: mxc: add support of device tree

Robin Gong (1):
      input: keyboard: imx: add snvs power key driver

Shawn Guo (2):
      input: snvs_pwrkey: use "wakeup-source" as deivce tree property name
      rtc: snvs: select option REGMAP_MMIO

 .../devicetree/bindings/crypto/fsl-sec4.txt        |  91 +++++++--
 .../devicetree/bindings/input/snvs-pwrkey.txt      |   1 +
 Documentation/devicetree/bindings/rtc/rtc-mxc.txt  |  26 +++
 arch/arm/Kconfig.debug                             |   9 +
 arch/arm/include/debug/imx-uart.h                  |  13 ++
 arch/arm/mach-imx/Kconfig                          |   8 +
 arch/arm/mach-imx/Makefile                         |   1 +
 arch/arm/mach-imx/cpu.c                            |   3 +
 arch/arm/mach-imx/mach-imx6ul.c                    |  86 ++++++++
 arch/arm/mach-imx/mxc.h                            |   6 +
 drivers/input/keyboard/Kconfig                     |  11 +
 drivers/input/keyboard/Makefile                    |   1 +
 drivers/input/keyboard/snvs_pwrkey.c               | 227 +++++++++++++++++++++
 drivers/rtc/Kconfig                                |   1 +
 drivers/rtc/rtc-mxc.c                              |  60 ++++--
 drivers/rtc/rtc-snvs.c                             | 132 ++++++------
 include/linux/mfd/syscon/imx6q-iomuxc-gpr.h        |   8 +
 17 files changed, 592 insertions(+), 92 deletions(-)
 create mode 100644 Documentation/devicetree/bindings/input/snvs-pwrkey.txt
 create mode 100644 Documentation/devicetree/bindings/rtc/rtc-mxc.txt
 create mode 100644 arch/arm/mach-imx/mach-imx6ul.c
 create mode 100644 drivers/input/keyboard/snvs_pwrkey.c


From shawnguo at kernel.org  Tue Aug 11 09:42:30 2015
From: shawnguo at kernel.org (Shawn Guo)
Date: Wed, 12 Aug 2015 00:42:30 +0800
Subject: [GIT PULL 2/3] ARM: imx: device tree changes for 4.3
In-Reply-To: <1439311351-5268-1-git-send-email-shawnguo@kernel.org>
References: <1439311351-5268-1-git-send-email-shawnguo@kernel.org>
Message-ID: <1439311351-5268-2-git-send-email-shawnguo@kernel.org>

Hi arm-soc maintainers,

This is the i.MX device tree updates for 4.3.  To resolve the dependency
between imx6ul clock driver and DTS files on those clock ID definitions,
the i.MX clock changes are pulled into the branch.  But since i.MX clock
drivers are now in drivers/clk/imx/ folder, I sent the clock changes to
Mike and Stephen.  I've already asked them to keep my clock branch
stable/non-reabasable.  So it should be safe pull this DT change set
into arm-soc.

Shawn

The following changes since commit 787b4271a6a0c09775241770782b22762f40bd6e:

  clk: imx: add imx6ul clk tree support (2015-07-14 15:02:13 +0800)

are available in the git repository at:

  git://git.kernel.org/pub/scm/linux/kernel/git/shawnguo/linux.git tags/imx-dt-4.3

for you to fetch changes up to 360325755336893869c419013ec0e33757432cbb:

  ARM: dts: imx6ul: add snvs power key support (2015-08-11 23:15:27 +0800)

----------------------------------------------------------------
The i.MX device tree updates for 4.3:
 - Add audio and eTSEC device support and update dspi node for LS1021A.
 - Add initial i.MX6UL and imx6ul-14x14-evk board support, and enable
   a bunch of device support for i.MX6UL, including RTC, power key, USB,
   QSPI, and dual FEC.
 - Enable HDMI and LVDS dual display support for a few imx6qdl boards.
 - Support of imx6sl-warp board rev1.12, the version which will be
   publicly available for the customers.
 - A few i.MX7D device additions, watchdog, cortex-a7 coresight
   components, RTC, power key, power off.
 - Some Vybrid updates: add device support for I2C, QSPI, eSDHC etc.,
   update ADC node, and define stdout-path property.
 - A few random updates for i.MX27 and i.MX53 devices.

----------------------------------------------------------------
Alison Wang (1):
      ARM: dts: ls1021a: Add dts nodes for audio on LS1021A

Anson Huang (4):
      ARM: dts: imx6sx: correct property name for wakeup source
      ARM: dts: imx6ul: enable GPC as extended interrupt controller
      ARM: dts: imx6ul: add RTC support
      ARM: dts: imx6ul: add snvs power key support

Claudiu Manoil (2):
      ARM: dts: ls1021a: Add the eTSEC controller nodes
      ARM: dts: ls1021a: Enable the eTSEC ports on QDS and TWR

Cory Tusar (4):
      ARM: dts: vf610: Extend I2C support to all available buses.
      ARM: dts: vf610: Add missing QuadSPI register mapping and names.
      ARM: dts: vfxxx: Include support for qspi1 functionality.
      ARM: dts: vfxxx: Include support for esdhc0 functionality.

Fabio Estevam (7):
      ARM: dts: imx6sl-warp: Add the SD2_RESET pin
      ARM: dts: imx6qdl-sabreauto: Add HDMI support
      ARM: dts: imx6qdl-sabresd: Allow HDMI and LVDS to work simultaneously
      ARM: dts: imx6sl-warp: Add changes for rev1.12
      ARM: dts: imx6qdl-sabrelite: Allow HDMI and LVDS to work simultaneously
      ARM: dts: imx6qdl-nitrogen6x: Allow HDMI and LVDS to work simultaneously
      ARM: dts: imx6qdl-sabreauto: Allow HDMI and LVDS to work simultaneously

Frank Li (11):
      ARM: dts: imx7d: add watch dog support
      ARM: dts: imx6sx: enable snvs power key
      ARM: dts: imx7d: add cortex-a7 coresight component
      Document: dt: binding: imx: update document for imx6ul support
      ARM: dts: add i.mx6ul pin function include file
      ARM: dts: imx: add imx6ul and imx6ul evk board support
      ARM: dts: imx: update snvs to use syscon access register
      ARM: dts: imx6ul: add usb host and function support
      ARM: dts: imx6ul: fix low case define in imx6ul-pinfunc.h
      ARM: dts: imx6ul: add qspi support
      ARM: dts: imx7d: enable snvs rtc, onoffkey and power off

Fugang Duan (2):
      ARM: dts: imx: add fec1 and fec2 nodes for SOC i.MX6UL
      ARM: dts: imx6ul-14x14-evk: add fec1 and fec2 support

Haikun Wang (1):
      ARM: dts: ls1021a: Update 'dspi' device node compatible string

Lucas Stach (1):
      ARM: dts: imx53-qsb: select open-drain mode for i2c1 pads

Peter Chen (1):
      ARM: imx6qdl-sabreauto.dtsi: enable USB support

Peter Seiderer (2):
      ARM: dts: nitrogen6x: add CAN support
      ARM: dts: sabrelite: add CAN support

Philippe Reynes (1):
      ARM: dts: imx27: add support of internal rtc

Sanchayan Maity (1):
      ARM: dts: vfxxx: Add io-channel-cells property for ADC node

Shengjiu Wang (1):
      ARM: dts: imx6qdl-sabreauto: Add audio support

Stefan Agner (2):
      ARM: dts: vf-colibri: define stdout-path property
      ARM: dts: add property for maximum ADC clock frequencies

Tim Harvey (1):
      ARM: dts: ventana: add UHS-I support for Ventana boards

 .../devicetree/bindings/clock/imx6ul-clock.txt     |  13 +
 .../bindings/pinctrl/fsl,imx6ul-pinctrl.txt        |  36 +
 arch/arm/boot/dts/Makefile                         |   2 +
 arch/arm/boot/dts/imx27.dtsi                       |   9 +
 arch/arm/boot/dts/imx53-qsb-common.dtsi            |   5 +-
 arch/arm/boot/dts/imx53-qsrb.dts                   |  14 +-
 arch/arm/boot/dts/imx6qdl-gw51xx.dtsi              |   1 -
 arch/arm/boot/dts/imx6qdl-gw52xx.dtsi              |  35 +-
 arch/arm/boot/dts/imx6qdl-gw53xx.dtsi              |  35 +-
 arch/arm/boot/dts/imx6qdl-gw54xx.dtsi              |  34 +-
 arch/arm/boot/dts/imx6qdl-gw551x.dtsi              |   1 -
 arch/arm/boot/dts/imx6qdl-gw552x.dtsi              |   1 -
 arch/arm/boot/dts/imx6qdl-nitrogen6x.dtsi          |  39 +
 arch/arm/boot/dts/imx6qdl-sabreauto.dtsi           | 137 +++
 arch/arm/boot/dts/imx6qdl-sabrelite.dtsi           |  39 +
 arch/arm/boot/dts/imx6qdl-sabresd.dtsi             |   7 +
 arch/arm/boot/dts/imx6qdl.dtsi                     |  52 +-
 arch/arm/boot/dts/imx6sl-warp.dts                  |  32 +-
 arch/arm/boot/dts/imx6sl.dtsi                      |  21 +-
 arch/arm/boot/dts/imx6sx.dtsi                      |  28 +-
 arch/arm/boot/dts/imx6ul-14x14-evk.dts             | 343 ++++++++
 arch/arm/boot/dts/imx6ul-pinfunc.h                 | 938 +++++++++++++++++++++
 arch/arm/boot/dts/imx6ul.dtsi                      | 707 ++++++++++++++++
 arch/arm/boot/dts/imx7d.dtsi                       | 260 +++++-
 arch/arm/boot/dts/ls1021a-qds.dts                  |  89 ++
 arch/arm/boot/dts/ls1021a-twr.dts                  |  81 ++
 arch/arm/boot/dts/ls1021a.dtsi                     | 106 ++-
 arch/arm/boot/dts/vf-colibri-eval-v3.dtsi          |   2 +-
 arch/arm/boot/dts/vfxxx.dtsi                       |  85 +-
 29 files changed, 3062 insertions(+), 90 deletions(-)
 create mode 100644 Documentation/devicetree/bindings/clock/imx6ul-clock.txt
 create mode 100644 Documentation/devicetree/bindings/pinctrl/fsl,imx6ul-pinctrl.txt
 create mode 100644 arch/arm/boot/dts/imx6ul-14x14-evk.dts
 create mode 100644 arch/arm/boot/dts/imx6ul-pinfunc.h
 create mode 100644 arch/arm/boot/dts/imx6ul.dtsi


From shawnguo at kernel.org  Tue Aug 11 09:42:31 2015
From: shawnguo at kernel.org (Shawn Guo)
Date: Wed, 12 Aug 2015 00:42:31 +0800
Subject: [GIT PULL 3/3] ARM: imx: defconfig updates for 4.3
In-Reply-To: <1439311351-5268-1-git-send-email-shawnguo@kernel.org>
References: <1439311351-5268-1-git-send-email-shawnguo@kernel.org>
Message-ID: <1439311351-5268-3-git-send-email-shawnguo@kernel.org>

The following changes since commit d770e558e21961ad6cfdf0ff7df0eb5d7d4f0754:

  Linux 4.2-rc1 (2015-07-05 11:01:52 -0700)

are available in the git repository at:

  git://git.kernel.org/pub/scm/linux/kernel/git/shawnguo/linux.git tags/imx-defconfig-4.3

for you to fetch changes up to 9559b3a38b26ab8410aeb822cf0596ea0b4adde4:

  ARM: imx_v6_v7_defconfig: Select CONFIG_IKCONFIG_PROC (2015-07-27 22:33:50 +0800)

----------------------------------------------------------------
The i.MX defconfig updates for 4.3:
 - Enable i.MX6UL SoC build
 - Enable powerkey and syscon poweroff support
 - Build in multi-channel audio support, including i.MX ASRC and CS42xx8
   codec drivers.
 - Enable kexec build, HCIUART_H4 and IKCONFIG_PROC support.

----------------------------------------------------------------
Fabio Estevam (3):
      ARM: imx_v6_v7_defconfig: Enable kexec support
      ARM: imx_v6_v7_defconfig: Select HCIUART_H4
      ARM: imx_v6_v7_defconfig: Select CONFIG_IKCONFIG_PROC

Frank Li (2):
      ARM: imx_v6_v7_defconfig: enable powerkey and syscon power off
      ARM: imx: imx_v6_v7_defconfig enable imx6ul support

Shengjiu Wang (1):
      ARM: imx_v6_v7_defconfig: build in audio driver

 arch/arm/configs/imx_v6_v7_defconfig | 31 ++++++++++++++++++-------------
 1 file changed, 18 insertions(+), 13 deletions(-)


From wens at csie.org  Tue Aug 11 09:48:50 2015
From: wens at csie.org (Chen-Yu Tsai)
Date: Wed, 12 Aug 2015 00:48:50 +0800
Subject: [linux-sunxi] [PATCH] pinctrl: sun4i: add spdif to pin
 description.
In-Reply-To: <1439309965-9530-1-git-send-email-codekipper@gmail.com>
References: <1439309965-9530-1-git-send-email-codekipper@gmail.com>
Message-ID: <CAGb2v64Ptt5NgeicsYtiR8At+K4aDd3Lb3U4kijQ5UM+UafSrA@mail.gmail.com>

On Wed, Aug 12, 2015 at 12:19 AM,  <codekipper at gmail.com> wrote:
> From: Marcus Cooper <codekipper at gmail.com>
>
> Signed-off-by: Marcus Cooper <codekipper at gmail.com>
> ---
>  drivers/pinctrl/sunxi/pinctrl-sun4i-a10.c | 9 ++++++---
>  1 file changed, 6 insertions(+), 3 deletions(-)
>
> diff --git a/drivers/pinctrl/sunxi/pinctrl-sun4i-a10.c b/drivers/pinctrl/sunxi/pinctrl-sun4i-a10.c
> index 7376a97..daf7dec 100644
> --- a/drivers/pinctrl/sunxi/pinctrl-sun4i-a10.c
> +++ b/drivers/pinctrl/sunxi/pinctrl-sun4i-a10.c
> @@ -135,7 +135,8 @@ static const struct sunxi_desc_pin sun4i_a10_pins[] = {
>         SUNXI_PIN(SUNXI_PINCTRL_PIN(B, 3),
>                   SUNXI_FUNCTION(0x0, "gpio_in"),
>                   SUNXI_FUNCTION(0x1, "gpio_out"),
> -                 SUNXI_FUNCTION(0x2, "ir0")),          /* TX */
> +                 SUNXI_FUNCTION(0x2, "ir0"),           /* TX */
> +                 SUNXI_FUNCTION(0x4, "spdif")),        /* MCLK */
>         SUNXI_PIN(SUNXI_PINCTRL_PIN(B, 4),
>                   SUNXI_FUNCTION(0x0, "gpio_in"),
>                   SUNXI_FUNCTION(0x1, "gpio_out"),
> @@ -176,11 +177,13 @@ static const struct sunxi_desc_pin sun4i_a10_pins[] = {
>                   SUNXI_FUNCTION(0x0, "gpio_in"),
>                   SUNXI_FUNCTION(0x1, "gpio_out"),
>                   SUNXI_FUNCTION(0x2, "i2s"),           /* DI */
> -                 SUNXI_FUNCTION(0x3, "ac97")),         /* DI */
> +                 SUNXI_FUNCTION(0x3, "ac97"),          /* DI */
> +                 SUNXI_FUNCTION(0x4, "spdif")),        /* DI */
>         SUNXI_PIN(SUNXI_PINCTRL_PIN(B, 13),
>                   SUNXI_FUNCTION(0x0, "gpio_in"),
>                   SUNXI_FUNCTION(0x1, "gpio_out"),
> -                 SUNXI_FUNCTION(0x2, "spi2")),         /* CS1 */
> +                 SUNXI_FUNCTION(0x2, "spi2"),          /* CS1 */
> +                 SUNXI_FUNCTION(0x4, "spdif")),        /* DO */

The datasheet and manual list them as NC or Reserved. Maybe mention how you knew
they were available?

Given that the S/PDIF block is not documented either, you should do
the same for the
actual driver, like mention Allwinner kernel sources.


ChenYu

>         SUNXI_PIN(SUNXI_PINCTRL_PIN(B, 14),
>                   SUNXI_FUNCTION(0x0, "gpio_in"),
>                   SUNXI_FUNCTION(0x1, "gpio_out"),
> --
> 2.5.0
>
> --
> You received this message because you are subscribed to the Google Groups "linux-sunxi" group.
> To unsubscribe from this group and stop receiving emails from it, send an email to linux-sunxi+unsubscribe at googlegroups.com.
> For more options, visit https://groups.google.com/d/optout.


From will.deacon at arm.com  Tue Aug 11 09:56:45 2015
From: will.deacon at arm.com (Will Deacon)
Date: Tue, 11 Aug 2015 17:56:45 +0100
Subject: [PATCH v8 0/7] arm64: Add kernel probes (kprobes) support
In-Reply-To: <1439254364-15362-1-git-send-email-dave.long@linaro.org>
References: <1439254364-15362-1-git-send-email-dave.long@linaro.org>
Message-ID: <20150811165645.GA29880@arm.com>

Hi David,

On Tue, Aug 11, 2015 at 01:52:37AM +0100, David Long wrote:
> From: "David A. Long" <dave.long at linaro.org>
> 
> This patchset is heavily based on Sandeepa Prabhu's ARM v8 kprobes patches,
> first seen in October 2013. This version attempts to address concerns raised by
> reviewers and also fixes problems discovered during testing.
> 
> This patchset adds support for kernel probes(kprobes), jump probes(jprobes)
> and return probes(kretprobes) support for ARM64.
> 
> The kprobes mechanism makes use of software breakpoint and single stepping
> support available in the ARM v8 kernel.
> 
> This patch depends on:
> 	[PATCH 1/2] Move the pt_regs_offset struct definition from arch to common include file
> 	[PATCH 2/2] Consolidate redundant register/stack access code

Are these two queued somewhere? This series doesn't even build without
them.

Will


From will.deacon at arm.com  Tue Aug 11 10:03:22 2015
From: will.deacon at arm.com (Will Deacon)
Date: Tue, 11 Aug 2015 18:03:22 +0100
Subject: [RFC v2 1/4] ftrace: allow arch-specific check_stack()
In-Reply-To: <1438674249-3447-2-git-send-email-takahiro.akashi@linaro.org>
References: <1438674249-3447-1-git-send-email-takahiro.akashi@linaro.org>
 <1438674249-3447-2-git-send-email-takahiro.akashi@linaro.org>
Message-ID: <20150811170321.GB29880@arm.com>

On Tue, Aug 04, 2015 at 08:44:06AM +0100, AKASHI Takahiro wrote:
> A stack frame pointer may be used in a different way depending on
> cpu architecture. Thus it is not always appropriate to slurp the stack
> contents, as currently done in check_stack(), in order to calcurate
> a stack index (height) at a given function call. At least not on arm64.
> 
> This patch extract potentially arch-specific code from check_stack()
> and puts it into a new arch_check_stack(), which is declared as weak.
> So we will be able to add arch-specific and most efficient way of
> stack traversing Later.
> 
> Signed-off-by: AKASHI Takahiro <takahiro.akashi at linaro.org>

If arm64 is the only architecture behaving differently, then I'm happy
to reconsider the fix to unwind_frame that we merged in e306dfd06fcb
("ARM64: unwind: Fix PC calculation"). I'd have thought any architecture
with a branch-and-link instruction would potentially have the same issue,
so we could just be fixing things in the wrong place if ftrace works
everywhere else.

Will


From dave.long at linaro.org  Tue Aug 11 10:03:46 2015
From: dave.long at linaro.org (David Long)
Date: Tue, 11 Aug 2015 13:03:46 -0400
Subject: [PATCH v8 0/7] arm64: Add kernel probes (kprobes) support
In-Reply-To: <20150811165645.GA29880@arm.com>
References: <1439254364-15362-1-git-send-email-dave.long@linaro.org>
 <20150811165645.GA29880@arm.com>
Message-ID: <55CA2AF2.6040202@linaro.org>

On 08/11/15 12:56, Will Deacon wrote:
> Hi David,
>
> On Tue, Aug 11, 2015 at 01:52:37AM +0100, David Long wrote:
>> From: "David A. Long" <dave.long at linaro.org>
>>
>> This patchset is heavily based on Sandeepa Prabhu's ARM v8 kprobes patches,
>> first seen in October 2013. This version attempts to address concerns raised by
>> reviewers and also fixes problems discovered during testing.
>>
>> This patchset adds support for kernel probes(kprobes), jump probes(jprobes)
>> and return probes(kretprobes) support for ARM64.
>>
>> The kprobes mechanism makes use of software breakpoint and single stepping
>> support available in the ARM v8 kernel.
>>
>> This patch depends on:
>> 	[PATCH 1/2] Move the pt_regs_offset struct definition from arch to common include file
>> 	[PATCH 2/2] Consolidate redundant register/stack access code
>
> Are these two queued somewhere? This series doesn't even build without
> them.
>
> Will
>

I posted the last revision of that on July 27.  I don't know if they're 
"queued" somewhere.  They do affect multiple architectures so I'm not 
certain where they would get queued. They also live in a branch in my 
own Linaro repo.

Was there a better way for me to deal with this dependency?  I was 
reluctant to make this into one patch set as the other patch really does 
stand alone as a useful fix.

-dl



From gregory.clement at free-electrons.com  Tue Aug 11 10:03:35 2015
From: gregory.clement at free-electrons.com (Gregory CLEMENT)
Date: Tue, 11 Aug 2015 19:03:35 +0200
Subject: [PATCH] ARM: mm: fix support for HW coherent systems in PL310 cache
Message-ID: <1439312615-6160-1-git-send-email-gregory.clement@free-electrons.com>

From: Nadav Haklai <nadavh at marvell.com>

When a PL310 cache is used in a system that provides hardware
coherency, the entire outer cache operations are useless, and can be
skipped.  Moreover, on some systems, it is harmful as it causes
deadlocks between the Marvell coherency mechanism, the Marvell PCIe
controller and the Cortex-A9.

This commit extends a previous commit:
98ea2dba65932ffc456b6d7b11b8a0624e2f7b95 which added the io-coherent
support for the PL310 cache by also disabling the outer cache flush
range operation.

In the current kernel implementation, the outer cache flush range
operation is triggered by the dma_alloc function.
This operation can be take place during runtime and in some
circumstances may lead to the PCIe/PL310 deadlock on Armada 375/38x
SoCs.

Signed-off-by: Nadav Haklai <nadavh at marvell.com>
Reviewed-by: Ofer Heifetz <oferh at marvell.com>
Signed-off-by: Gregory CLEMENT <gregory.clement at free-electrons.com>
---
 arch/arm/mm/cache-l2x0.c | 7 +++----
 1 file changed, 3 insertions(+), 4 deletions(-)

diff --git a/arch/arm/mm/cache-l2x0.c b/arch/arm/mm/cache-l2x0.c
index 71b3d3309024..5c3148675597 100644
--- a/arch/arm/mm/cache-l2x0.c
+++ b/arch/arm/mm/cache-l2x0.c
@@ -1266,9 +1266,9 @@ static const struct l2c_init_data of_l2c310_data __initconst = {
 };
 
 /*
- * This is a variant of the of_l2c310_data with .sync set to
- * NULL. Outer sync operations are not needed when the system is I/O
- * coherent, and potentially harmful in certain situations (PCIe/PL310
+ * This is a variant of the of_l2c310_data with .sync and .flush_range set to
+ * NULL. Outer sync and flush range operations are not needed when the system
+ * is I/O coherent, and potentially harmful in certain situations (PCIe/PL310
  * deadlock on Armada 375/38x due to hardware I/O coherency). The
  * other operations are kept because they are infrequent (therefore do
  * not cause the deadlock in practice) and needed for secondary CPU
@@ -1287,7 +1287,6 @@ static const struct l2c_init_data of_l2c310_coherent_data __initconst = {
 	.outer_cache = {
 		.inv_range   = l2c210_inv_range,
 		.clean_range = l2c210_clean_range,
-		.flush_range = l2c210_flush_range,
 		.flush_all   = l2c210_flush_all,
 		.disable     = l2c310_disable,
 		.resume      = l2c310_resume,
-- 
2.1.0



From linux at arm.linux.org.uk  Tue Aug 11 10:03:57 2015
From: linux at arm.linux.org.uk (Russell King - ARM Linux)
Date: Tue, 11 Aug 2015 18:03:57 +0100
Subject: 3.18: lockdep problems in cpufreq
In-Reply-To: <2574268.XBqpdL2VLI@vostro.rjw.lan>
References: <20141214213655.GA11285@n2100.arm.linux.org.uk>
 <CAKohponhkk9BK6-7ScHeZa4R43iooWQFV8YoPLv6LjO40GNq=A@mail.gmail.com>
 <20150518185645.GA28053@n2100.arm.linux.org.uk>
 <2574268.XBqpdL2VLI@vostro.rjw.lan>
Message-ID: <20150811170357.GA24529@n2100.arm.linux.org.uk>

On Tue, May 19, 2015 at 12:05:55AM +0200, Rafael J. Wysocki wrote:
> On Monday, May 18, 2015 07:56:45 PM Russell King - ARM Linux wrote:
> > On Tue, Dec 16, 2014 at 09:11:53AM +0530, Viresh Kumar wrote:
> > > On 16 December 2014 at 04:39, Russell King - ARM Linux
> > > <linux at arm.linux.org.uk> wrote:
> > > > Well, here's a patch which I'm running on top of 3.18 at the moment,
> > > > which is basically what I described in my email, and I'm running with it
> > > > and it is without any lockdep complaint.
> > > 
> > > We need two separate patches now, one for 3.18 and other one for 3.19-rc.
> > > 3.19 has see lots of changes in this particular file and so we need to
> > > change few things here.
> > 
> > What happened with this?  I'm still carrying the patch.
> 
> This should go in through the thermal tree.  Eduardo?

Having waited a long time for any kind of response from Eduardo, I've
given up.  My conclusion is that Eduardo isn't interested in this.

I've re-checked, and the AB-BA deadlock is still there in the latest
code.  So, I've taken it upon myself to throw this into my for-next
branch to force the issue - not something I _want_ to do, but I'm doing
this out of frustration.  It's clear to me that "playing nice" by email
does _not_ work with some people.

I'm rather hoping that Stephen reports a merge conflict with linux-next
this evening to highlight this situation.  I've added additional commentry
to the commit message on the patch giving the reason why I've done this,
and the relevant message IDs showing the past history.

I've not decided whether I'm going to ask Linus to take this patch
directly or not, that rather depends whether there's any co-operation
from Eduardo on this.  I'd rather Eduardo took the patch.

The patch I have has had to be updated again for changes to the driver,
but I really don't see the point of re-posting it just for it to be
ignored yet again.

I'm really disappointed by this dysfunctional state of affairs, and
that what should be an urgent fix for an observable problem is still
not merged some nine months after it was first identified.

-- 
FTTC broadband for 0.8mile line: currently at 10.5Mbps down 400kbps up
according to speedtest.net.


From gregory.clement at free-electrons.com  Tue Aug 11 10:05:27 2015
From: gregory.clement at free-electrons.com (Gregory CLEMENT)
Date: Tue, 11 Aug 2015 19:05:27 +0200
Subject: [PATCH] ARM: mm: fix support for HW coherent systems in PL310
 cache
In-Reply-To: <1439312615-6160-1-git-send-email-gregory.clement@free-electrons.com>
References: <1439312615-6160-1-git-send-email-gregory.clement@free-electrons.com>
Message-ID: <55CA2B57.2080600@free-electrons.com>

Hi Russell,

please ignore this one it is the wrong version.

Sorry for the noise

Gregory


On 11/08/2015 19:03, Gregory CLEMENT wrote:
> From: Nadav Haklai <nadavh at marvell.com>
> 
> When a PL310 cache is used in a system that provides hardware
> coherency, the entire outer cache operations are useless, and can be
> skipped.  Moreover, on some systems, it is harmful as it causes
> deadlocks between the Marvell coherency mechanism, the Marvell PCIe
> controller and the Cortex-A9.
> 
> This commit extends a previous commit:
> 98ea2dba65932ffc456b6d7b11b8a0624e2f7b95 which added the io-coherent
> support for the PL310 cache by also disabling the outer cache flush
> range operation.
> 
> In the current kernel implementation, the outer cache flush range
> operation is triggered by the dma_alloc function.
> This operation can be take place during runtime and in some
> circumstances may lead to the PCIe/PL310 deadlock on Armada 375/38x
> SoCs.
> 
> Signed-off-by: Nadav Haklai <nadavh at marvell.com>
> Reviewed-by: Ofer Heifetz <oferh at marvell.com>
> Signed-off-by: Gregory CLEMENT <gregory.clement at free-electrons.com>
> ---
>  arch/arm/mm/cache-l2x0.c | 7 +++----
>  1 file changed, 3 insertions(+), 4 deletions(-)
> 
> diff --git a/arch/arm/mm/cache-l2x0.c b/arch/arm/mm/cache-l2x0.c
> index 71b3d3309024..5c3148675597 100644
> --- a/arch/arm/mm/cache-l2x0.c
> +++ b/arch/arm/mm/cache-l2x0.c
> @@ -1266,9 +1266,9 @@ static const struct l2c_init_data of_l2c310_data __initconst = {
>  };
>  
>  /*
> - * This is a variant of the of_l2c310_data with .sync set to
> - * NULL. Outer sync operations are not needed when the system is I/O
> - * coherent, and potentially harmful in certain situations (PCIe/PL310
> + * This is a variant of the of_l2c310_data with .sync and .flush_range set to
> + * NULL. Outer sync and flush range operations are not needed when the system
> + * is I/O coherent, and potentially harmful in certain situations (PCIe/PL310
>   * deadlock on Armada 375/38x due to hardware I/O coherency). The
>   * other operations are kept because they are infrequent (therefore do
>   * not cause the deadlock in practice) and needed for secondary CPU
> @@ -1287,7 +1287,6 @@ static const struct l2c_init_data of_l2c310_coherent_data __initconst = {
>  	.outer_cache = {
>  		.inv_range   = l2c210_inv_range,
>  		.clean_range = l2c210_clean_range,
> -		.flush_range = l2c210_flush_range,
>  		.flush_all   = l2c210_flush_all,
>  		.disable     = l2c310_disable,
>  		.resume      = l2c310_resume,
> 


-- 
Gregory Clement, Free Electrons
Kernel, drivers, real-time and embedded Linux
development, consulting, training and support.
http://free-electrons.com


From dev at lynxeye.de  Tue Aug 11 10:05:01 2015
From: dev at lynxeye.de (Lucas Stach)
Date: Tue, 11 Aug 2015 19:05:01 +0200
Subject: [PATCH] arm: rpi: Device tree modifications for U-Boot
In-Reply-To: <1439303153-12171-1-git-send-email-sjg@chromium.org>
References: <1439303153-12171-1-git-send-email-sjg@chromium.org>
Message-ID: <1439312701.2451.3.camel@lynxeye.de>

Hi Simon,

why did you send this to the Tegra ML?

Am Dienstag, den 11.08.2015, 08:25 -0600 schrieb Simon Glass:
> This updates the device tree from the kernel version to something suitable
> for U-Boot:
> 
> - Add stdout-path alias for console
> - Mark the /soc node to be available pre-relocation so that the early
> serial console works (we need the 'ranges' property to be available)
> 
> Signed-off-by: Simon Glass <sjg at chromium.org>
> ---
> 
>  arch/arm/boot/dts/bcm2835.dtsi | 4 +++-
>  1 file changed, 3 insertions(+), 1 deletion(-)
> 
> diff --git a/arch/arm/boot/dts/bcm2835.dtsi b/arch/arm/boot/dts/bcm2835.dtsi
> index 301c73f..bd6bff6 100644
> --- a/arch/arm/boot/dts/bcm2835.dtsi
> +++ b/arch/arm/boot/dts/bcm2835.dtsi
> @@ -8,6 +8,7 @@
>  
>  	chosen {
>  		bootargs = "earlyprintk console=ttyAMA0";
> +		stdout-path = &uart;
>  	};
>  
>  	soc {
> @@ -16,6 +17,7 @@
>  		#size-cells = <1>;
>  		ranges = <0x7e000000 0x20000000 0x02000000>;
>  		dma-ranges = <0x40000000 0x00000000 0x20000000>;
> +		u-boot,dm-pre-reloc;

Why do you need this and why should upstream carry your favourite
bootloaders configuration? This is in no way hardware description.

Regards,
Lucas



From gregory.clement at free-electrons.com  Tue Aug 11 10:05:43 2015
From: gregory.clement at free-electrons.com (Gregory CLEMENT)
Date: Tue, 11 Aug 2015 19:05:43 +0200
Subject: [PATCH] ARM: l2c: fix support for HW coherent systems in PL310 cache
Message-ID: <1439312743-6237-1-git-send-email-gregory.clement@free-electrons.com>

From: Nadav Haklai <nadavh at marvell.com>

When a PL310 cache is used in a system that provides hardware
coherency, the entire outer cache operations are useless, and can be
skipped.  Moreover, on some systems, it is harmful as it causes
deadlocks between the Marvell coherency mechanism, the Marvell PCIe
controller and the Cortex-A9.

This commit extends a previous commit:
98ea2dba65932ffc456b6d7b11b8a0624e2f7b95 which added the io-coherent
support for the PL310 cache by also disabling the outer cache flush
range operation.

In the current kernel implementation, the outer cache flush range
operation is triggered by the dma_alloc function.
This operation can be take place during runtime and in some
circumstances may lead to the PCIe/PL310 deadlock on Armada 375/38x
SoCs.

[gregory.clement at free-electrons.com]: fix title s/mm/l2c/, add the
				      stable flag

Signed-off-by: Nadav Haklai <nadavh at marvell.com>
Reviewed-by: Ofer Heifetz <oferh at marvell.com>
Signed-off-by: Gregory CLEMENT <gregory.clement at free-electrons.com>
Fixes: 98ea2dba6593 ("ARM: 8076/1: mm: add support for HW coherent
systems in PL310 cache")
Cc: <stable at vger.kernel.org>
---
 arch/arm/mm/cache-l2x0.c | 7 +++----
 1 file changed, 3 insertions(+), 4 deletions(-)

diff --git a/arch/arm/mm/cache-l2x0.c b/arch/arm/mm/cache-l2x0.c
index 71b3d3309024..5c3148675597 100644
--- a/arch/arm/mm/cache-l2x0.c
+++ b/arch/arm/mm/cache-l2x0.c
@@ -1266,9 +1266,9 @@ static const struct l2c_init_data of_l2c310_data __initconst = {
 };
 
 /*
- * This is a variant of the of_l2c310_data with .sync set to
- * NULL. Outer sync operations are not needed when the system is I/O
- * coherent, and potentially harmful in certain situations (PCIe/PL310
+ * This is a variant of the of_l2c310_data with .sync and .flush_range set to
+ * NULL. Outer sync and flush range operations are not needed when the system
+ * is I/O coherent, and potentially harmful in certain situations (PCIe/PL310
  * deadlock on Armada 375/38x due to hardware I/O coherency). The
  * other operations are kept because they are infrequent (therefore do
  * not cause the deadlock in practice) and needed for secondary CPU
@@ -1287,7 +1287,6 @@ static const struct l2c_init_data of_l2c310_coherent_data __initconst = {
 	.outer_cache = {
 		.inv_range   = l2c210_inv_range,
 		.clean_range = l2c210_clean_range,
-		.flush_range = l2c210_flush_range,
 		.flush_all   = l2c210_flush_all,
 		.disable     = l2c310_disable,
 		.resume      = l2c310_resume,
-- 
2.1.0



From catalin.marinas at arm.com  Tue Aug 11 10:26:20 2015
From: catalin.marinas at arm.com (Catalin Marinas)
Date: Tue, 11 Aug 2015 18:26:20 +0100
Subject: [PATCH] ARM: l2c: fix support for HW coherent systems in PL310
 cache
In-Reply-To: <1439312743-6237-1-git-send-email-gregory.clement@free-electrons.com>
References: <1439312743-6237-1-git-send-email-gregory.clement@free-electrons.com>
Message-ID: <20150811172620.GK23307@e104818-lin.cambridge.arm.com>

On Tue, Aug 11, 2015 at 07:05:43PM +0200, Gregory CLEMENT wrote:
> From: Nadav Haklai <nadavh at marvell.com>
> 
> When a PL310 cache is used in a system that provides hardware
> coherency, the entire outer cache operations are useless, and can be
> skipped.  Moreover, on some systems, it is harmful as it causes
> deadlocks between the Marvell coherency mechanism, the Marvell PCIe
> controller and the Cortex-A9.
> 
> This commit extends a previous commit:
> 98ea2dba65932ffc456b6d7b11b8a0624e2f7b95 which added the io-coherent
> support for the PL310 cache by also disabling the outer cache flush
> range operation.
> 
> In the current kernel implementation, the outer cache flush range
> operation is triggered by the dma_alloc function.
> This operation can be take place during runtime and in some
> circumstances may lead to the PCIe/PL310 deadlock on Armada 375/38x
> SoCs.

While this may work around the issue for your specific SoC, I think a
better fix is in DMA alloc code to avoid flushing caches for coherent
devices. This would be the __dma_clear_buffer() implementation which
isn't aware of whether the device is coherent or not.

-- 
Catalin


From swarren at wwwdotorg.org  Tue Aug 11 10:29:55 2015
From: swarren at wwwdotorg.org (Stephen Warren)
Date: Tue, 11 Aug 2015 11:29:55 -0600
Subject: [PATCH] arm: rpi: Device tree modifications for U-Boot
In-Reply-To: <1439312701.2451.3.camel@lynxeye.de>
References: <1439303153-12171-1-git-send-email-sjg@chromium.org>
 <1439312701.2451.3.camel@lynxeye.de>
Message-ID: <55CA3113.1010601@wwwdotorg.org>

On 08/11/2015 11:05 AM, Lucas Stach wrote:
> Hi Simon,
>
> why did you send this to the Tegra ML?

At my request, so that the DT changes could be reviewed by the kernel DT 
reviewers and added to the copy of the DT files in the kernel source 
tree if approved.

My assertion is that DT content should be independent of SW stack. Or 
put another way, all SW stacks should use the same DT content. As such, 
if these properties are needed by U-Boot, and contained in the copy of 
the DT files in the U-Boot source tree, they should also be present in 
the copy of the DT files in the kernel source tree, so the two do not 
become out of sync.

> Am Dienstag, den 11.08.2015, 08:25 -0600 schrieb Simon Glass:
>> This updates the device tree from the kernel version to something suitable
>> for U-Boot:
>>
>> - Add stdout-path alias for console
>> - Mark the /soc node to be available pre-relocation so that the early
>> serial console works (we need the 'ranges' property to be available)

>> diff --git a/arch/arm/boot/dts/bcm2835.dtsi b/arch/arm/boot/dts/bcm2835.dtsi
>> index 301c73f..bd6bff6 100644
>> --- a/arch/arm/boot/dts/bcm2835.dtsi
>> +++ b/arch/arm/boot/dts/bcm2835.dtsi
>> @@ -8,6 +8,7 @@
>>
>>   	chosen {
>>   		bootargs = "earlyprintk console=ttyAMA0";
>> +		stdout-path = &uart;
>>   	};
>>
>>   	soc {
>> @@ -16,6 +17,7 @@
>>   		#size-cells = <1>;
>>   		ranges = <0x7e000000 0x20000000 0x02000000>;
>>   		dma-ranges = <0x40000000 0x00000000 0x20000000>;
>> +		u-boot,dm-pre-reloc;
>
> Why do you need this and why should upstream carry your favourite
> bootloaders configuration? This is in no way hardware description.




From will.deacon at arm.com  Tue Aug 11 10:31:21 2015
From: will.deacon at arm.com (Will Deacon)
Date: Tue, 11 Aug 2015 18:31:21 +0100
Subject: [PATCH v8 1/7] arm64: Add HAVE_REGS_AND_STACK_ACCESS_API feature
In-Reply-To: <1439254364-15362-2-git-send-email-dave.long@linaro.org>
References: <1439254364-15362-1-git-send-email-dave.long@linaro.org>
 <1439254364-15362-2-git-send-email-dave.long@linaro.org>
Message-ID: <20150811173121.GC29880@arm.com>

Hi David,

On Tue, Aug 11, 2015 at 01:52:38AM +0100, David Long wrote:
> From: "David A. Long" <dave.long at linaro.org>
> 
> Add HAVE_REGS_AND_STACK_ACCESS_API feature for arm64.
> 
> Signed-off-by: David A. Long <dave.long at linaro.org>
> ---
>  arch/arm64/Kconfig              |  1 +
>  arch/arm64/include/asm/ptrace.h | 25 +++++++++++++
>  arch/arm64/kernel/ptrace.c      | 77 +++++++++++++++++++++++++++++++++++++++++
>  3 files changed, 103 insertions(+)
> 
> diff --git a/arch/arm64/Kconfig b/arch/arm64/Kconfig
> index 318175f..ef5d726 100644
> --- a/arch/arm64/Kconfig
> +++ b/arch/arm64/Kconfig
> @@ -70,6 +70,7 @@ config ARM64
>  	select HAVE_PERF_EVENTS
>  	select HAVE_PERF_REGS
>  	select HAVE_PERF_USER_STACK_DUMP
> +	select HAVE_REGS_AND_STACK_ACCESS_API
>  	select HAVE_RCU_TABLE_FREE
>  	select HAVE_SYSCALL_TRACEPOINTS
>  	select IRQ_DOMAIN
> diff --git a/arch/arm64/include/asm/ptrace.h b/arch/arm64/include/asm/ptrace.h
> index d6dd9fd..8f440e9 100644
> --- a/arch/arm64/include/asm/ptrace.h
> +++ b/arch/arm64/include/asm/ptrace.h
> @@ -118,6 +118,8 @@ struct pt_regs {
>  	u64 syscallno;
>  };
>  
> +#define MAX_REG_OFFSET (sizeof(struct user_pt_regs) - sizeof(u64))

Can you not use offset_of(struct user_pt_regs, pstate) here?

> +
>  #define arch_has_single_step()	(1)
>  
>  #ifdef CONFIG_COMPAT
> @@ -146,6 +148,29 @@ struct pt_regs {
>  #define user_stack_pointer(regs) \
>  	(!compat_user_mode(regs) ? (regs)->sp : (regs)->compat_sp)
>  
> +/**
> + * regs_get_register() - get register value from its offset
> + * @regs:	   pt_regs from which register value is gotten
> + * @offset:    offset number of the register.
> + *
> + * regs_get_register returns the value of a register whose offset from @regs.
> + * The @offset is the offset of the register in struct pt_regs.
> + * If @offset is bigger than MAX_REG_OFFSET, this returns 0.
> + */
> +static inline u64 regs_get_register(struct pt_regs *regs,
> +					      unsigned int offset)
> +{
> +	if (unlikely(offset > MAX_REG_OFFSET))
> +		return 0;
> +	return *(u64 *)((u64)regs + offset);
> +}

Is this guaranteed only to be called on kernel-mode regs, or do we need
to deal with compat tasks too?

> +
> +/* Valid only for Kernel mode traps. */
> +static inline unsigned long kernel_stack_pointer(struct pt_regs *regs)
> +{
> +	return regs->sp;
> +}
> +
>  static inline unsigned long regs_return_value(struct pt_regs *regs)
>  {
>  	return regs->regs[0];
> diff --git a/arch/arm64/kernel/ptrace.c b/arch/arm64/kernel/ptrace.c
> index d882b83..f6199a5 100644
> --- a/arch/arm64/kernel/ptrace.c
> +++ b/arch/arm64/kernel/ptrace.c
> @@ -48,6 +48,83 @@
>  #define CREATE_TRACE_POINTS
>  #include <trace/events/syscalls.h>
>  
> +#define ARM_pstate	pstate
> +#define ARM_pc		pc
> +#define ARM_sp		sp
> +#define ARM_x30		regs[30]
> +#define ARM_x29		regs[29]
> +#define ARM_x28		regs[28]
> +#define ARM_x27		regs[27]
> +#define ARM_x26		regs[26]
> +#define ARM_x25		regs[25]
> +#define ARM_x24		regs[24]
> +#define ARM_x23		regs[23]
> +#define ARM_x22		regs[22]
> +#define ARM_x21		regs[21]
> +#define ARM_x20		regs[20]
> +#define ARM_x19		regs[19]
> +#define ARM_x18		regs[18]
> +#define ARM_x17		regs[17]
> +#define ARM_x16		regs[16]
> +#define ARM_x15		regs[15]
> +#define ARM_x14		regs[14]
> +#define ARM_x13		regs[13]
> +#define ARM_x12		regs[12]
> +#define ARM_x11		regs[11]
> +#define ARM_x10		regs[10]
> +#define ARM_x9		regs[9]
> +#define ARM_x8		regs[8]
> +#define ARM_x7		regs[7]
> +#define ARM_x6		regs[6]
> +#define ARM_x5		regs[5]
> +#define ARM_x4		regs[4]
> +#define ARM_x3		regs[3]
> +#define ARM_x2		regs[2]
> +#define ARM_x1		regs[1]
> +#define ARM_x0		regs[0]

I've said it before, but I really don't like these macros. I'd rather
rework the following REG_OFFSET_NAME to be GPR_OFFSET_NAME which could
prefix the "x" in the name field.

> +
> +#define REG_OFFSET_NAME(r) \
> +	{.name = #r, .offset = offsetof(struct pt_regs, ARM_##r)}
> +#define REG_OFFSET_END {.name = NULL, .offset = 0}
> +
> +const struct pt_regs_offset regs_offset_table[] = {
> +	REG_OFFSET_NAME(x0),
> +	REG_OFFSET_NAME(x1),
> +	REG_OFFSET_NAME(x2),
> +	REG_OFFSET_NAME(x3),
> +	REG_OFFSET_NAME(x4),
> +	REG_OFFSET_NAME(x5),
> +	REG_OFFSET_NAME(x6),
> +	REG_OFFSET_NAME(x7),
> +	REG_OFFSET_NAME(x8),
> +	REG_OFFSET_NAME(x9),
> +	REG_OFFSET_NAME(x10),
> +	REG_OFFSET_NAME(x11),
> +	REG_OFFSET_NAME(x12),
> +	REG_OFFSET_NAME(x13),
> +	REG_OFFSET_NAME(x14),
> +	REG_OFFSET_NAME(x15),
> +	REG_OFFSET_NAME(x16),
> +	REG_OFFSET_NAME(x17),
> +	REG_OFFSET_NAME(x18),
> +	REG_OFFSET_NAME(x19),
> +	REG_OFFSET_NAME(x20),
> +	REG_OFFSET_NAME(x21),
> +	REG_OFFSET_NAME(x22),
> +	REG_OFFSET_NAME(x23),
> +	REG_OFFSET_NAME(x24),
> +	REG_OFFSET_NAME(x25),
> +	REG_OFFSET_NAME(x26),
> +	REG_OFFSET_NAME(x27),
> +	REG_OFFSET_NAME(x28),
> +	REG_OFFSET_NAME(x29),
> +	REG_OFFSET_NAME(x30),

Does this interact badly with perf tools, which expect to pass "lr" for
x30? (see tools/perf/arch/arm64/include/perf_regs.h).

Will


From will.deacon at arm.com  Tue Aug 11 10:36:01 2015
From: will.deacon at arm.com (Will Deacon)
Date: Tue, 11 Aug 2015 18:36:01 +0100
Subject: [PATCH v8 0/7] arm64: Add kernel probes (kprobes) support
In-Reply-To: <55CA2AF2.6040202@linaro.org>
References: <1439254364-15362-1-git-send-email-dave.long@linaro.org>
 <20150811165645.GA29880@arm.com> <55CA2AF2.6040202@linaro.org>
Message-ID: <20150811173601.GD29880@arm.com>

On Tue, Aug 11, 2015 at 06:03:46PM +0100, David Long wrote:
> On 08/11/15 12:56, Will Deacon wrote:
> > On Tue, Aug 11, 2015 at 01:52:37AM +0100, David Long wrote:
> >> From: "David A. Long" <dave.long at linaro.org>
> >>
> >> This patchset is heavily based on Sandeepa Prabhu's ARM v8 kprobes patches,
> >> first seen in October 2013. This version attempts to address concerns raised by
> >> reviewers and also fixes problems discovered during testing.
> >>
> >> This patchset adds support for kernel probes(kprobes), jump probes(jprobes)
> >> and return probes(kretprobes) support for ARM64.
> >>
> >> The kprobes mechanism makes use of software breakpoint and single stepping
> >> support available in the ARM v8 kernel.
> >>
> >> This patch depends on:
> >> 	[PATCH 1/2] Move the pt_regs_offset struct definition from arch to common include file
> >> 	[PATCH 2/2] Consolidate redundant register/stack access code
> >
> > Are these two queued somewhere? This series doesn't even build without
> > them.
> 
> I posted the last revision of that on July 27.  I don't know if they're 
> "queued" somewhere.  They do affect multiple architectures so I'm not 
> certain where they would get queued. They also live in a branch in my 
> own Linaro repo.

Well they're not in linux-next, so I guess they're not currently destined
for mainline :(

> Was there a better way for me to deal with this dependency?  I was 
> reluctant to make this into one patch set as the other patch really does 
> stand alone as a useful fix.

I agree (well, it's a cleanup not a fix). Perhaps it's worth reposting
them with akpm also on Cc, as he sometimes picks up tree-wide patches
like that.

Will


From david.vrabel at citrix.com  Tue Aug 11 10:37:25 2015
From: david.vrabel at citrix.com (David Vrabel)
Date: Tue, 11 Aug 2015 18:37:25 +0100
Subject: [Xen-devel] [PATCH v3 0/9] Use correctly the Xen memory
 terminologies
In-Reply-To: <1438965282-19103-1-git-send-email-julien.grall@citrix.com>
References: <1438965282-19103-1-git-send-email-julien.grall@citrix.com>
Message-ID: <55CA32D5.606@citrix.com>

On 07/08/15 17:34, Julien Grall wrote:
> Hi all,
> 
> This patch series aims to use the memory terminologies described in
> include/xen/mm.h [1] for Linux xen code.

Applied to for-linus-4.3, thanks.

David


From mturquette at baylibre.com  Tue Aug 11 10:46:57 2015
From: mturquette at baylibre.com (Michael Turquette)
Date: Tue, 11 Aug 2015 10:46:57 -0700
Subject: [GIT PULL] i.MX clock updates for 4.2
In-Reply-To: <20150811085921.GB10035@tiger>
References: <20150811085921.GB10035@tiger>
Message-ID: <20150811174657.2416.1270@quantum>

Hi Shawn,

Quoting Shawn Guo (2015-08-11 01:59:21)
> Hi Michael, Stephen,
> 
> The i.MX clock drivers were moved into drivers/clk/imx folder since
> v4.2-rc1, so I would like to send i.MX clock changes through clock tree
> from this cycle.  Here is my first pull request to you guys.  I'm using
> signed tags, same as how I work with arm-soc folks.  Let me know if
> there is any problem with it.

Everything looks good. Pulled.

> 
> Also, please keep it stable, because I need to pull it into other
> branch as dependency which I will send via arm-soc tree.

Will do.

Also, the clock driver was not Cc'd to linux-clk mailing list nor did it
Cc myself or Stephen. I've taken a quick look at it and it seems fine,
but please post clk patches to the linux-clk mailing list in the future.

Thanks,
Mike

> 
> Thanks,
> Shawn
> 
> The following changes since commit d770e558e21961ad6cfdf0ff7df0eb5d7d4f0754:
> 
>   Linux 4.2-rc1 (2015-07-05 11:01:52 -0700)
> 
> are available in the git repository at:
> 
>   git://git.kernel.org/pub/scm/linux/kernel/git/shawnguo/linux.git tags/imx-clk-4.3
> 
> for you to fetch changes up to 3713e3f5e9274bbe52e94716bde303071364c1ed:
> 
>   clk: imx35: define two clocks for rtc (2015-08-05 20:01:21 +0800)
> 
> ----------------------------------------------------------------
> The i.MX clock updates for 4.3:
>  - Provide a better IPU clock initial settings on imx6dl for getting
>    HDMI and LVDS at the same time.
>  - Add clock driver support for i.MX6UL SoC
>  - Add a second clock for RTC device on i.MX31 and i.MX35
> 
> ----------------------------------------------------------------
> Fabio Estevam (1):
>       clk: imx: clk-imx6q: Provide initial IPU clock settings for mx6dl
> 
> Frank Li (1):
>       clk: imx: add imx6ul clk tree support
> 
> Philippe Reynes (2):
>       clk: imx31: add a second rtc clock
>       clk: imx35: define two clocks for rtc
> 
>  drivers/clk/imx/Makefile                 |   1 +
>  drivers/clk/imx/clk-imx31.c              |   3 +-
>  drivers/clk/imx/clk-imx35.c              |   6 +-
>  drivers/clk/imx/clk-imx6q.c              |   4 +
>  drivers/clk/imx/clk-imx6ul.c             | 432 +++++++++++++++++++++++++++++++
>  include/dt-bindings/clock/imx6ul-clock.h | 240 +++++++++++++++++
>  6 files changed, 684 insertions(+), 2 deletions(-)
>  create mode 100644 drivers/clk/imx/clk-imx6ul.c
>  create mode 100644 include/dt-bindings/clock/imx6ul-clock.h
> 
> _______________________________________________
> linux-arm-kernel mailing list
> linux-arm-kernel at lists.infradead.org
> http://lists.infradead.org/mailman/listinfo/linux-arm-kernel


From msalter at redhat.com  Tue Aug 11 10:48:10 2015
From: msalter at redhat.com (Mark Salter)
Date: Tue, 11 Aug 2015 13:48:10 -0400
Subject: arm kernel oops in highmem.c with 4.2
In-Reply-To: <20150805112713.GY7557@n2100.arm.linux.org.uk>
References: <CALeDE9Ox3=sh3AXQ0NUG6BBfU5i5YrMY=LDpcTHQWqz2=60F2g@mail.gmail.com>
 <20150805100701.GV7557@n2100.arm.linux.org.uk>
 <CALeDE9PXF=gQCaBCiHpHy2nXOooQOmsCQvSgOv+wQw3mta=P6A@mail.gmail.com>
 <20150805112713.GY7557@n2100.arm.linux.org.uk>
Message-ID: <1439315290.3153.11.camel@redhat.com>

On Wed, 2015-08-05 at 12:27 +0100, Russell King - ARM Linux wrote:
> On Wed, Aug 05, 2015 at 11:13:07AM +0100, Peter Robinson wrote:
> > On Wed, Aug 5, 2015 at 11:07 AM, Russell King - ARM Linux
> > <linux at arm.linux.org.uk> wrote:
> > > On Wed, Aug 05, 2015 at 11:01:01AM +0100, Peter Robinson wrote:
> > > > Hi All,
> > > > 
> > > > On Fedora 23 with recent 4.2 kernels we're seeing a crash (below) 
> > > > in
> > > > highmem.c on a fairly regular occurrence across a number of 
> > > > different
> > > > SoCs, I've seen it with at least AllWinner A20, i.MX6Q, Tegra2 and 
> > > > 124
> > > > with both a LPAE and non LPAE kernel, seen it happen when doing a
> > > > number of different things but regenerating a initrd, applying 
> > > > updates
> > > > (dnf/yum) and starting X are all pretty good triggers.
> > > 
> > > I've yet to see any problems with mainline 4.2-rc5 kernels on any of 
> > > my
> > > iMX6 platforms, which includes initramfs regeneration, apt-get 
> > > updates
> > > and X.
> > > 
> > > > [71751.658105] ------------[ cut here ]------------
> > > > [71751.658153] kernel BUG at arch/arm/mm/highmem.c:114!
> > > 
> > > Well, in mainline kernels, the BUG is on line 113, not line 114.  So 
> > > at
> > > least this file is modified from mainline kernels.  Maybe the problem 
> > > is
> > > caused by patches applied to Fedora kernels?
> > 
> > We apply a crash driver patch [1] which has been there forever (long
> > enough that I'd forgotten it) but other than that for arm kernels we
> > currently don't apply any arm specific patches in 4.2.
> 
> It helps if I look at 4.2 rather than an older kernel :)
> 
> However, I've checked that I have DEBUG_HIGHMEM enabled, which I do, and
> I'm unable to reproduce this here.  My kernels are built with gcc 4.7.4.
> 
> What it looks like from your oops is that the address which was passed
> in was 0xffedf000, but the address we calculated via the following for
> the current index was 0xfff00000:
> 
> type = kmap_atomic_idx();
> idx = type + KM_TYPE_NR * smp_processor_id();
> __fix_to_virt(idx)
> 
> Doing a bit of maths... the address 0xffedf000 corresponds to a fixmap
> index of... (0xffeff000 - 0xffedf000) >> 12 = 32.  KM_TYPE_NR is 16 on
> ARM, so the mapping was created by CPU 2, and type was zero.
> 
> On unmap, 0xfff00000 gives... (0xffeff000 - 0xfff00000) >> 12 = -1.
> That suggests we're on CPU 0, and type is -1 - in other words, there
> are no atomically mapped mappings on CPU 0.
> 
> Since kmap_atomic() disables preemption and page faults, how did your
> kernel migrate this thread from CPU 2 to CPU 0... and I can't see how
> that happened.
> 

The fedora kernel is using PREEMPT_VOLUNTARY with !PREEMPT and
!PREEMPT_CPOUNT. So preempt_disable() is a nop. I added some code
to catch the kernel scheduling between kmap_atomic() and
kunmap_atomic() and got this straightaway:

[    2.958651] ------------[ cut here ]------------
[    2.963263] kernel BUG at arch/arm/mm/highmem.c:61!
[    2.968132] Internal error: Oops - BUG: 0 [#1] SMP ARM
[    2.973261] Modules linked in:
[    2.976313] CPU: 0 PID: 199 Comm: systemd-udevd Tainted: G        W       4.2.0-rc5 #9
[    2.984218] Hardware name: Highbank
[    2.987699] task: ecb9bf40 ti: eccce000 task.ti: eccce000
[    2.993097] PC is at check_kmap_atomic+0x20/0x2c
[    2.997710] LR is at __schedule+0x254/0x60c
[    3.001885] pc : [<c022318c>]    lr : [<c08d49a0>]    psr: 200d0093
[    3.001885] sp : ecccfdd8  ip : 00000000  fp : ecccfe1c
[    3.013350] r10: c0d508a0  r9 : ecb9c244  r8 : ffeff000
[    3.018565] r7 : c0d4a140  r6 : ec90a280  r5 : ed3b7140  r4 : ecb9bf40
[    3.025081] r3 : 00000001  r2 : 2c66d000  r1 : eccce000  r0 : 00000000
[    3.031599] Flags: nzCv  IRQs off  FIQs on  Mode SVC_32  ISA ARM  Segment user
[    3.038810] Control: 10c5387d  Table: 2cc9c04a  DAC: 00000015
[    3.044546] Process systemd-udevd (pid: 199, stack limit = 0xeccce220)
[    3.051063] Stack: (0xecccfdd8 to 0xeccd0000)
[    3.055410] fdc0:                                                       eccad500 00000000
[    3.063580] fde0: ecc83e80 eccbc488 ecc83e80 c08d5030 2c66d000 00000000 00000002 eccce000
[    3.071749] fe00: 00000000 0000012a b6fe0000 ffeff000 ecccff14 ecccff0c ecccfe2c c08d5030
[    3.079918] fe20: ecb5f538 00000000 ecccfe34 c08d5088 b6fe0000 c08d6a14 00000000 c05285a0
[    3.088086] fe40: b6fe0000 ffeff000 0000012a 0000012a 00000000 ec3da524 ffeff000 0000012a
[    3.096255] fe60: ecccff14 c052dcec ef7b1678 ffeff000 0000012a 00000000 eccbc480 ec3da524
[    3.104423] fe80: ef7b1678 00000000 0000012a ecccff28 00000000 c032add4 00000000 c04b6804
[    3.112592] fea0: ecccff14 ffffffff 00000fff ec3da438 eccbc4e8 00000001 00000129 00000000
[    3.120760] fec0: ecc72c18 00000000 00000000 000b6fe0 00000000 00000000 b6fe1000 eccbc480
[    3.128929] fee0: 00000000 ecccff88 00001000 c020fae4 eccce000 00000200 00000000 c037ff08
[    3.137098] ff00: 00001000 c020fae4 eccce000 b6fe0000 00001000 00000000 00000000 00001000
[    3.145266] ff20: ecccff0c 00000001 eccbc480 00000000 00000000 00000000 00000000 00000000
[    3.153435] ff40: 00000000 00000000 00000000 b6fe0000 eccbc480 ecccff88 00001000 c03805d0
[    3.161603] ff60: eccbc480 b6fe0000 00001000 eccbc480 eccbc480 b6fe0000 00001000 c020fae4
[    3.169772] ff80: eccce000 c0380e84 00000000 00000000 00001000 8066e1c0 00003ffe 8066e1c0
[    3.177940] ffa0: 00000003 c020fad0 8066e1c0 00003ffe 00000006 b6fe0000 00001000 00000040
[    3.186109] ffc0: 8066e1c0 00003ffe 8066e1c0 00000003 0000000a bee856e4 00000000 00000000
[    3.194277] ffe0: 00000000 bee8528c b6daa470 b6e0f5b0 600d0010 00000006 00000000 00000000
[    3.202454] [<c022318c>] (check_kmap_atomic) from [<c08d49a0>] (__schedule+0x254/0x60c)
[    3.210454] [<c08d49a0>] (__schedule) from [<c08d5030>] (preempt_schedule_common+0x24/0x40)
[    3.218799] [<c08d5030>] (preempt_schedule_common) from [<c08d5088>] (_cond_resched+0x3c/0x4c)
[    3.227404] [<c08d5088>] (_cond_resched) from [<c08d6a14>] (down_read+0x14/0x48)
[    3.234799] [<c08d6a14>] (down_read) from [<c05285a0>] (__copy_to_user_memcpy+0x54/0x17c)
[    3.242974] [<c05285a0>] (__copy_to_user_memcpy) from [<c052dcec>] (copy_page_to_iter+0xd8/0x258)
[    3.251844] [<c052dcec>] (copy_page_to_iter) from [<c032add4>] (generic_file_read_iter+0x370/0x5dc)
[    3.260885] [<c032add4>] (generic_file_read_iter) from [<c037ff08>] (__vfs_read+0xb0/0xd8)
[    3.269142] [<c037ff08>] (__vfs_read) from [<c03805d0>] (vfs_read+0x8c/0x13c)
[    3.276270] [<c03805d0>] (vfs_read) from [<c0380e84>] (SyS_read+0x48/0x88)
[    3.283141] [<c0380e84>] (SyS_read) from [<c020fad0>] (__sys_trace_return+0x0/0x10)
[    3.290790] Code: e7922100 e7923003 e3530000 012fff1e (e7f001f2) 
[    3.296876] ---[ end trace cb88537fdc8fa202 ]---
[    3.301485] note: systemd-udevd[199] exited with preempt_count 2097152




From mturquette at baylibre.com  Tue Aug 11 10:50:19 2015
From: mturquette at baylibre.com (Michael Turquette)
Date: Tue, 11 Aug 2015 10:50:19 -0700
Subject: [PATCH v2 5/7] ARM: sun8i: Add clock indices
In-Reply-To: <CAGb2v64-=1Byzo-h=7Pq=HK9Xx01KaTKT89Nx6jVWUc_kqthyg@mail.gmail.com>
References: <1438364782-3968-1-git-send-email-maxime.ripard@free-electrons.com>
 <1438364782-3968-6-git-send-email-maxime.ripard@free-electrons.com>
 <CAGb2v64nvA1K=Ya7_99-2G1LtFjcuj+qQbO1GJaqsL+yPF+Xdw@mail.gmail.com>
 <CAGb2v64-=1Byzo-h=7Pq=HK9Xx01KaTKT89Nx6jVWUc_kqthyg@mail.gmail.com>
Message-ID: <20150811175019.2416.93864@quantum>

Quoting Chen-Yu Tsai (2015-08-10 21:49:54)
> On Sat, Aug 8, 2015 at 12:21 AM, Chen-Yu Tsai <wens at csie.org> wrote:
> > On Sat, Aug 1, 2015 at 1:46 AM, Maxime Ripard
> > <maxime.ripard at free-electrons.com> wrote:
> >> The A23 and A33 gates have a non continuous set of clock IDs that are
> >> valid. Add the clock-indices property to the DT to express this.
> >>
> >> Signed-off-by: Maxime Ripard <maxime.ripard at free-electrons.com>
> >> ---
> >>  arch/arm/boot/dts/sun8i-a23-a33.dtsi | 15 +++++++++++++++
> >>  1 file changed, 15 insertions(+)
> >>
> >> diff --git a/arch/arm/boot/dts/sun8i-a23-a33.dtsi b/arch/arm/boot/dts/sun8i-a23-a33.dtsi
> >> index 7abd0ae3143d..c318c770b6c1 100644
> >> --- a/arch/arm/boot/dts/sun8i-a23-a33.dtsi
> >> +++ b/arch/arm/boot/dts/sun8i-a23-a33.dtsi
> >> @@ -180,6 +180,15 @@
> >>                         compatible = "allwinner,sun8i-a23-ahb1-gates-clk";
> >>                         reg = <0x01c20060 0x8>;
> >>                         clocks = <&ahb1>;
> >> +                       clock-indices = <1>, <6>,
> >
> > Turns out the A33 (and I assume the same with the A23) has
> > an ahb1 clock gate for the Security System at clock-index <5>.
> 
> Looks like the A23 does not have this one, nor the SS mod clock.
> 
> > This is found in the updated A33 user manual.
> >
> >> +                                       <8>, <9>, <10>,
> >> +                                       <13>, <14>,
> >> +                                       <19>, <20>,
> >> +                                       <21>, <24>, <26>,
> >> +                                       <29>, <32>, <36>,
> >> +                                       <40>, <44>, <46>,
> >> +                                       <52>, <54>,
> >
> > <53> is ahb1 clock gate for msgbox, again found in A33 manual.
> 
> A23 has this one. Found in Allwinner kernel sources.
> 
> >> +                                       <57>;
> >
> > <58> is ahb1 clock gate for SAT, which seems to be part of the
> > display pipeline.
> 
> This one is A33 only.
> 
> I guess we should do a separate compatible for A33 AHB1 clock gates.

ChenYu,

I believe Maxime is on vacation. I told him that I would pick these
patches directly. It looks like your comments can be fixed up in
follow-up patches at a later date, correct?

If so then I will apply them to clk-next.

Regards,
Mike

> 
> ChenYu
> 
> >>                         clock-output-names = "ahb1_mipidsi", "ahb1_dma",
> >>                                         "ahb1_mmc0", "ahb1_mmc1", "ahb1_mmc2",
> >>                                         "ahb1_nand", "ahb1_sdram",
> >> @@ -196,6 +205,8 @@
> >>                         compatible = "allwinner,sun8i-a23-apb1-gates-clk";
> >>                         reg = <0x01c20068 0x4>;
> >>                         clocks = <&apb1>;
> >> +                       clock-indices = <0>, <5>,
> >> +                                       <12>, <13>;
> >>                         clock-output-names = "apb1_codec", "apb1_pio",
> >>                                         "apb1_daudio0", "apb1_daudio1";
> >>                 };
> >> @@ -213,6 +224,10 @@
> >>                         compatible = "allwinner,sun8i-a23-apb2-gates-clk";
> >>                         reg = <0x01c2006c 0x4>;
> >>                         clocks = <&apb2>;
> >> +                       clock-indices = <0>, <1>,
> >> +                                       <2>, <16>,
> >> +                                       <17>, <18>,
> >> +                                       <19>, <20>;
> >>                         clock-output-names = "apb2_i2c0", "apb2_i2c1",
> >>                                         "apb2_i2c2", "apb2_uart0",
> >>                                         "apb2_uart1", "apb2_uart2",
> >> --
> >> 2.4.6
> >>
> >
> > Not sure if you want to add the clocks I mentioned together
> > in this patch, or do a separate patch.
> >
> > The rest look good.
> >
> > ChenYu
> 
> _______________________________________________
> linux-arm-kernel mailing list
> linux-arm-kernel at lists.infradead.org
> http://lists.infradead.org/mailman/listinfo/linux-arm-kernel


From will.deacon at arm.com  Tue Aug 11 11:00:12 2015
From: will.deacon at arm.com (Will Deacon)
Date: Tue, 11 Aug 2015 19:00:12 +0100
Subject: [PATCH v8 2/7] arm64: Add more test functions to insn.c
In-Reply-To: <1439254364-15362-3-git-send-email-dave.long@linaro.org>
References: <1439254364-15362-1-git-send-email-dave.long@linaro.org>
 <1439254364-15362-3-git-send-email-dave.long@linaro.org>
Message-ID: <20150811180012.GE29880@arm.com>

On Tue, Aug 11, 2015 at 01:52:39AM +0100, David Long wrote:
> From: "David A. Long" <dave.long at linaro.org>
> 
> Certain instructions are hard to execute correctly out-of-line (as in
> kprobes).  Test functions are added to insn.[hc] to identify these.  The
> instructions include any that use PC-relative addressing, change the PC,
> or change interrupt masking. For efficiency and simplicity test
> functions are also added for small collections of related instructions.
> 
> Signed-off-by: David A. Long <dave.long at linaro.org>
> ---
>  arch/arm64/include/asm/insn.h | 18 ++++++++++++++++++
>  arch/arm64/kernel/insn.c      | 28 ++++++++++++++++++++++++++++
>  2 files changed, 46 insertions(+)
> 
> diff --git a/arch/arm64/include/asm/insn.h b/arch/arm64/include/asm/insn.h
> index 30e50eb..66bfb21 100644
> --- a/arch/arm64/include/asm/insn.h
> +++ b/arch/arm64/include/asm/insn.h
> @@ -223,8 +223,13 @@ static __always_inline bool aarch64_insn_is_##abbr(u32 code) \
>  static __always_inline u32 aarch64_insn_get_##abbr##_value(void) \
>  { return (val); }
>  
> +__AARCH64_INSN_FUNCS(adr_adrp,	0x1F000000, 0x10000000)
> +__AARCH64_INSN_FUNCS(prfm_lit,	0xFF000000, 0xD8000000)
>  __AARCH64_INSN_FUNCS(str_reg,	0x3FE0EC00, 0x38206800)
>  __AARCH64_INSN_FUNCS(ldr_reg,	0x3FE0EC00, 0x38606800)
> +__AARCH64_INSN_FUNCS(ldr_lit,	0xBF000000, 0x18000000)
> +__AARCH64_INSN_FUNCS(ldrsw_lit,	0xFF000000, 0x98000000)
> +__AARCH64_INSN_FUNCS(exclusive,	0x3F000000, 0x08000000)

Hmm, so this class also pulls in load-acquire and store-release, which
we *should* be able to single-step, no? Maybe it's worth splitting this
category up (or at least changing aarch64_insn_is_exclusive to be more
permissive).

>  __AARCH64_INSN_FUNCS(stp_post,	0x7FC00000, 0x28800000)
>  __AARCH64_INSN_FUNCS(ldp_post,	0x7FC00000, 0x28C00000)
>  __AARCH64_INSN_FUNCS(stp_pre,	0x7FC00000, 0x29800000)
> @@ -264,19 +269,29 @@ __AARCH64_INSN_FUNCS(ands,	0x7F200000, 0x6A000000)
>  __AARCH64_INSN_FUNCS(bics,	0x7F200000, 0x6A200000)
>  __AARCH64_INSN_FUNCS(b,		0xFC000000, 0x14000000)
>  __AARCH64_INSN_FUNCS(bl,	0xFC000000, 0x94000000)
> +__AARCH64_INSN_FUNCS(b_bl,	0x7C000000, 0x14000000)

Why do we need this when we already have checks for b and bl?

> +__AARCH64_INSN_FUNCS(cb,	0x7E000000, 0x34000000)

Likewise for cbz and cbnz...

>  __AARCH64_INSN_FUNCS(cbz,	0x7F000000, 0x34000000)
>  __AARCH64_INSN_FUNCS(cbnz,	0x7F000000, 0x35000000)
> +__AARCH64_INSN_FUNCS(tb,	0x7E000000, 0x36000000)

... there's a pattern here!

>  __AARCH64_INSN_FUNCS(tbz,	0x7F000000, 0x36000000)
>  __AARCH64_INSN_FUNCS(tbnz,	0x7F000000, 0x37000000)
> +__AARCH64_INSN_FUNCS(b_bl_cb_tb, 0x5C000000, 0x14000000)

I must be missing something :)

>  __AARCH64_INSN_FUNCS(bcond,	0xFF000010, 0x54000000)
>  __AARCH64_INSN_FUNCS(svc,	0xFFE0001F, 0xD4000001)
>  __AARCH64_INSN_FUNCS(hvc,	0xFFE0001F, 0xD4000002)
>  __AARCH64_INSN_FUNCS(smc,	0xFFE0001F, 0xD4000003)
>  __AARCH64_INSN_FUNCS(brk,	0xFFE0001F, 0xD4200000)
> +__AARCH64_INSN_FUNCS(exception,	0xFF000000, 0xD4000000)
>  __AARCH64_INSN_FUNCS(hint,	0xFFFFF01F, 0xD503201F)
>  __AARCH64_INSN_FUNCS(br,	0xFFFFFC1F, 0xD61F0000)
>  __AARCH64_INSN_FUNCS(blr,	0xFFFFFC1F, 0xD63F0000)
> +__AARCH64_INSN_FUNCS(br_blr,	0xFFDFFC1F, 0xD61F0000)
>  __AARCH64_INSN_FUNCS(ret,	0xFFFFFC1F, 0xD65F0000)
> +__AARCH64_INSN_FUNCS(msr_imm,	0xFFF8F01F, 0xD500401F)
> +__AARCH64_INSN_FUNCS(msr_reg,	0xFFF00000, 0xD5100000)
> +__AARCH64_INSN_FUNCS(set_clr_daif, 0xFFFFF0DF, 0xD50340DF)
> +__AARCH64_INSN_FUNCS(rd_wr_daif, 0xFFDFFFE0, 0xD51B4220)

I think I'd rather have separate decoders to decode the register field
of an mrs/msr instruction than overload each encoding here.

Anyway, on the whole this looks pretty good, I'd just prefer not to build
compound instruction checks at the encoding level (even though it looks
like you did a good job on the values).

Will


From linux at arm.linux.org.uk  Tue Aug 11 11:10:09 2015
From: linux at arm.linux.org.uk (Russell King - ARM Linux)
Date: Tue, 11 Aug 2015 19:10:09 +0100
Subject: arm kernel oops in highmem.c with 4.2
In-Reply-To: <1439315290.3153.11.camel@redhat.com>
References: <CALeDE9Ox3=sh3AXQ0NUG6BBfU5i5YrMY=LDpcTHQWqz2=60F2g@mail.gmail.com>
 <20150805100701.GV7557@n2100.arm.linux.org.uk>
 <CALeDE9PXF=gQCaBCiHpHy2nXOooQOmsCQvSgOv+wQw3mta=P6A@mail.gmail.com>
 <20150805112713.GY7557@n2100.arm.linux.org.uk>
 <1439315290.3153.11.camel@redhat.com>
Message-ID: <20150811181008.GA7557@n2100.arm.linux.org.uk>

On Tue, Aug 11, 2015 at 01:48:10PM -0400, Mark Salter wrote:
> On Wed, 2015-08-05 at 12:27 +0100, Russell King - ARM Linux wrote:
> > It helps if I look at 4.2 rather than an older kernel :)
> > 
> > However, I've checked that I have DEBUG_HIGHMEM enabled, which I do, and
> > I'm unable to reproduce this here.  My kernels are built with gcc 4.7.4.
> > 
> > What it looks like from your oops is that the address which was passed
> > in was 0xffedf000, but the address we calculated via the following for
> > the current index was 0xfff00000:
> > 
> > type = kmap_atomic_idx();
> > idx = type + KM_TYPE_NR * smp_processor_id();
> > __fix_to_virt(idx)
> > 
> > Doing a bit of maths... the address 0xffedf000 corresponds to a fixmap
> > index of... (0xffeff000 - 0xffedf000) >> 12 = 32.  KM_TYPE_NR is 16 on
> > ARM, so the mapping was created by CPU 2, and type was zero.
> > 
> > On unmap, 0xfff00000 gives... (0xffeff000 - 0xfff00000) >> 12 = -1.
> > That suggests we're on CPU 0, and type is -1 - in other words, there
> > are no atomically mapped mappings on CPU 0.
> > 
> > Since kmap_atomic() disables preemption and page faults, how did your
> > kernel migrate this thread from CPU 2 to CPU 0... and I can't see how
> > that happened.
> > 
> 
> The fedora kernel is using PREEMPT_VOLUNTARY with !PREEMPT and
> !PREEMPT_CPOUNT. So preempt_disable() is a nop. I added some code
> to catch the kernel scheduling between kmap_atomic() and
> kunmap_atomic() and got this straightaway:

Looking at the backtrace, and grepping for __copy_to_user_memcpy, it
seems to imply that you're using the uaccess-with-memcpy code.

This code is relatively unmaintained, and probably mostly unused by
people today, so I doubt it gets much in the way of testing - and
you've certainly found a bug in there.

        /* the mmap semaphore is taken only if not in an atomic context */
        atomic = in_atomic();

        if (!atomic)
                down_read(&current->mm->mmap_sem);

is not sufficient to tell whether we can take the semaphore.

We _could_ replace the above with:

	int ret;

	ret = down_read_trylock(&current->mm->mmap_sem);
	if (!ret) {
		__copy_to_user_std(to, from, n);
		return;
	}

but that's just a guess.  I'm not a big fan of this code, and given
that it probably doesn't get much use, we may be better off deleting
it so it doesn't sit around rotting...  Code like this really needs
regular testing.

-- 
FTTC broadband for 0.8mile line: currently at 10.5Mbps down 400kbps up
according to speedtest.net.


From mturquette at linaro.org  Tue Aug 11 11:25:35 2015
From: mturquette at linaro.org (Michael Turquette)
Date: Tue, 11 Aug 2015 11:25:35 -0700
Subject: [RFC PATCH 0/8] clk: qoriq: Move chip-specific knowledge into
 driver
In-Reply-To: <1434682158-7243-1-git-send-email-scottwood@freescale.com>
References: <1434682158-7243-1-git-send-email-scottwood@freescale.com>
Message-ID: <20150811182535.31346.52965@quantum>

Hi Scott,

Quoting Scott Wood (2015-06-18 19:49:10)
> The existing device tree bindings are error-prone and inflexible. 
> Correct the mistake by moving the knowledge into the driver, which
> has more flexibility in describing the quirks of each chip.  This leaves
> the device tree to its proper role of identifying a programming interface
> rather than describing its individual registers.

Sorry for not responding to this one sooner. Fell through the cracks.

All of the changes to drives/clk/clk-qoriq.c look great to me. I assume
you need to keep all of these patches together and want to the take
through the freescale tree? If so feel free to add,

Acked-by: Michael Turquette <mturquette at baylibre.com>

Regards,
Mike

> 
> For more detail, see the commit message of patch 4.
> 
> Scott Wood (8):
>   ARM: dts: ls1021a: Fix clockgen node
>   cpufreq: qoriq: Don't look at clock implementation details
>   powerpc/fsl: Move fsl_guts.h out of arch/powerpc
>   clk: qoriq: Move chip-specific knowledge into driver
>   clk: qoriq: Redirect legacy clock nodes to new clocks
>   cpufreq: qoriq: Remove frequency masking and minimum
>   clk: qoriq: Expose OF clocks directly from the clockgen node
>   powerpc/fsl: Use new clockgen binding
> 
>  .../devicetree/bindings/clock/qoriq-clock.txt      |   57 +-
>  arch/arm/boot/dts/ls1021a.dtsi                     |    3 +
>  arch/powerpc/boot/dts/fsl/b4420si-pre.dtsi         |    4 +-
>  arch/powerpc/boot/dts/fsl/b4860si-pre.dtsi         |    8 +-
>  arch/powerpc/boot/dts/fsl/b4si-post.dtsi           |   15 -
>  arch/powerpc/boot/dts/fsl/p2041si-post.dtsi        |   18 -
>  arch/powerpc/boot/dts/fsl/p2041si-pre.dtsi         |    8 +-
>  arch/powerpc/boot/dts/fsl/p3041si-post.dtsi        |   18 -
>  arch/powerpc/boot/dts/fsl/p3041si-pre.dtsi         |    8 +-
>  arch/powerpc/boot/dts/fsl/p4080si-post.dtsi        |   70 --
>  arch/powerpc/boot/dts/fsl/p4080si-pre.dtsi         |   16 +-
>  arch/powerpc/boot/dts/fsl/p5020si-pre.dtsi         |    4 +-
>  arch/powerpc/boot/dts/fsl/p5040si-post.dtsi        |   18 -
>  arch/powerpc/boot/dts/fsl/p5040si-pre.dtsi         |    8 +-
>  arch/powerpc/boot/dts/fsl/qoriq-clockgen1.dtsi     |   50 +-
>  arch/powerpc/boot/dts/fsl/qoriq-clockgen2.dtsi     |   33 +-
>  arch/powerpc/boot/dts/fsl/t1023si-post.dtsi        |   16 -
>  arch/powerpc/boot/dts/fsl/t102xsi-pre.dtsi         |    4 +-
>  arch/powerpc/boot/dts/fsl/t1040si-post.dtsi        |   44 -
>  arch/powerpc/boot/dts/fsl/t104xsi-pre.dtsi         |    8 +-
>  arch/powerpc/boot/dts/fsl/t2081si-post.dtsi        |   22 -
>  arch/powerpc/boot/dts/fsl/t208xsi-pre.dtsi         |    8 +-
>  arch/powerpc/boot/dts/fsl/t4240si-post.dtsi        |   61 -
>  arch/powerpc/boot/dts/fsl/t4240si-pre.dtsi         |   24 +-
>  arch/powerpc/platforms/85xx/mpc85xx_mds.c          |    2 +-
>  arch/powerpc/platforms/85xx/mpc85xx_rdb.c          |    2 +-
>  arch/powerpc/platforms/85xx/p1022_ds.c             |    2 +-
>  arch/powerpc/platforms/85xx/p1022_rdk.c            |    2 +-
>  arch/powerpc/platforms/85xx/smp.c                  |    2 +-
>  arch/powerpc/platforms/85xx/twr_p102x.c            |    2 +-
>  arch/powerpc/platforms/86xx/mpc8610_hpcd.c         |    2 +-
>  drivers/clk/clk-qoriq.c                            | 1191 ++++++++++++++++----
>  drivers/cpufreq/qoriq-cpufreq.c                    |  139 +--
>  drivers/iommu/fsl_pamu.c                           |    2 +-
>  .../asm/fsl_guts.h => include/linux/fsl/guts.h     |    6 +-
>  sound/soc/fsl/mpc8610_hpcd.c                       |    2 +-
>  sound/soc/fsl/p1022_ds.c                           |    2 +-
>  sound/soc/fsl/p1022_rdk.c                          |    2 +-
>  38 files changed, 1107 insertions(+), 776 deletions(-)
>  rename arch/powerpc/include/asm/fsl_guts.h => include/linux/fsl/guts.h (98%)
> 
> -- 
> 2.1.4
> 


From alexandre.belloni at free-electrons.com  Tue Aug 11 11:31:31 2015
From: alexandre.belloni at free-electrons.com (Alexandre Belloni)
Date: Tue, 11 Aug 2015 20:31:31 +0200
Subject: [rtc-linux] [PATCH v2 2/2] drivers: rtc: add xilinx zynqmp rtc
 driver
In-Reply-To: <1438336757-23404-2-git-send-email-suneel.garapati@xilinx.com>
References: <1438336757-23404-1-git-send-email-suneel.garapati@xilinx.com>
 <1438336757-23404-2-git-send-email-suneel.garapati@xilinx.com>
Message-ID: <20150811183131.GW3411@piout.net>

Hi,

Please run checkpatch --strict and fix the issues.

On 31/07/2015 at 15:29:17 +0530, Suneel Garapati wrote :
> +#include <linux/init.h>
> +#include <linux/module.h>
> +#include <linux/of.h>
> +#include <linux/platform_device.h>
> +#include <linux/io.h>
> +#include <linux/delay.h>
> +#include <linux/rtc.h>
> +

The includes hav to be sorted alphabetically.

> +static int xlnx_rtc_set_time(struct device *dev, struct rtc_time *tm)
> +{
> +	struct xlnx_rtc_dev *xrtcdev = dev_get_drvdata(dev);
> +	unsigned long new_time;
> +
> +	rtc_tm_to_time(tm, &new_time);

You should use rtc_tm_to_time64() and rtc_time64_to_tm() throughout the
file.

> +	writel(new_time, xrtcdev->reg_base + RTC_SET_TM_WR);
> +

Is that a 32bits register? If yes, you probably want to return an error
if the year is 2106 or after.

> +	return 0;
> +}
> +

[...]

> +static int xlnx_rtc_set_alarm(struct device *dev, struct rtc_wkalrm *alrm)
> +{
> +	struct xlnx_rtc_dev *xrtcdev = dev_get_drvdata(dev);
> +	unsigned long alarm_time;
> +

Same comment, you probably want to error out if the time overflows a
32bits register.

> +	rtc_tm_to_time(&alrm->time, &alarm_time);
> +
> +	writel((u32) alarm_time, (xrtcdev->reg_base + RTC_ALRM));
> +
> +	xlnx_rtc_alarm_irq_enable(dev, alrm->enabled);
> +
> +	return 0;
> +}
> +
> +static void xlnx_init_rtc(struct xlnx_rtc_dev *xrtcdev, u32 calibval)
> +{
> +	/*
> +	 * Based on crystal freq of 33.330 KHz
> +	 * set the secounds counter and enable, set fractions counter
typo --------------^

> +	 * to default value suggested as per design spec
> +	 * to correct RTC delay in frequency over period of time.
> +	 */
> +	calibval &= RTC_CALIB_MASK;
> +	writel(calibval, (xrtcdev->reg_base + RTC_CALIB_WR));
> +}
> +
> +static const struct rtc_class_ops xlnx_rtc_ops = {
> +	.set_time	  = xlnx_rtc_set_time,
> +	.read_time	  = xlnx_rtc_read_time,
> +	.read_alarm	  = xlnx_rtc_read_alarm,
> +	.set_alarm	  = xlnx_rtc_set_alarm,
> +	.alarm_irq_enable = xlnx_rtc_alarm_irq_enable,
> +};
> +
> +static irqreturn_t xlnx_rtc_interrupt(int irq, void *id)
> +{
> +	struct xlnx_rtc_dev *xrtcdev = (struct xlnx_rtc_dev *) id;
> +	unsigned int status;
> +
> +	status = readl(xrtcdev->reg_base + RTC_INT_STS);
> +	/* Check if interrupt asserted */
> +	if (!(status & (RTC_INT_SEC | RTC_INT_ALRM)))
> +		return IRQ_NONE;
> +
> +	/* Clear interrupt */
> +	writel(status, xrtcdev->reg_base + RTC_INT_STS);
> +
> +	if (status & RTC_INT_SEC)
> +		rtc_update_irq(xrtcdev->rtc, 1, RTC_IRQF | RTC_UF);
> +	if (status & RTC_INT_ALRM)
> +		rtc_update_irq(xrtcdev->rtc, 1, RTC_IRQF | RTC_AF);
> +	if (status & RTC_INT_ALRM)
> +		printk("alarm interrupt\n");

I guess this is a debug message that you forgot to remove.

> +static int xlnx_rtc_probe(struct platform_device *pdev)
> +{
> +	struct xlnx_rtc_dev *xrtcdev;
> +	struct resource *res;
> +	int ret;
> +	unsigned int calibvalue;
> +
> +	xrtcdev = devm_kzalloc(&pdev->dev, sizeof(*xrtcdev), GFP_KERNEL);
> +	if (!xrtcdev)
> +		return -ENOMEM;
> +
> +	platform_set_drvdata(pdev, xrtcdev);
> +
> +	res = platform_get_resource(pdev, IORESOURCE_MEM, 0);
> +
> +	xrtcdev->reg_base = devm_ioremap_resource(&pdev->dev, res);
> +	if (IS_ERR(xrtcdev->reg_base))
> +		return PTR_ERR(xrtcdev->reg_base);
> +
> +	xrtcdev->alarm_irq = platform_get_irq_byname(pdev, "alarm");
> +	if (xrtcdev->alarm_irq < 0) {
> +		dev_err(&pdev->dev, "no irq resource\n");
> +		return xrtcdev->alarm_irq;
> +	}
> +	ret = devm_request_irq(&pdev->dev, xrtcdev->alarm_irq,
> +				xlnx_rtc_interrupt, 0,
> +				dev_name(&pdev->dev), xrtcdev);
> +	if (ret) {
> +		dev_err(&pdev->dev, "request irq failed\n");
> +		return ret;
> +	}
> +
> +	xrtcdev->sec_irq = platform_get_irq_byname(pdev, "sec");
> +	if (xrtcdev->sec_irq < 0) {
> +		dev_err(&pdev->dev, "no irq resource\n");
> +		return xrtcdev->sec_irq;
> +	}
> +	ret = devm_request_irq(&pdev->dev, xrtcdev->sec_irq,
> +				xlnx_rtc_interrupt, 0,
> +				dev_name(&pdev->dev), xrtcdev);
> +	if (ret) {
> +		dev_err(&pdev->dev, "request irq failed\n");
> +		return ret;
> +	}
> +
> +	ret = of_property_read_u32(pdev->dev.of_node, "calibration",
> +					&calibvalue);
> +	if (ret)
> +		calibvalue = RTC_CALIB_DEF;
> +
> +	xlnx_init_rtc(xrtcdev, calibvalue);
> +
> +	device_init_wakeup(&pdev->dev, 1);
> +
> +	xrtcdev->rtc = devm_rtc_device_register(&pdev->dev, pdev->name,
> +					 &xlnx_rtc_ops, THIS_MODULE);
> +	if (IS_ERR(xrtcdev->rtc)) {
> +		return PTR_ERR(xrtcdev->rtc);
> +	}
> +
> +	return 0;

You should use PTR_ERR_OR_ZERO here.

Thanks,

-- 
Alexandre Belloni, Free Electrons
Embedded Linux, Kernel and Android engineering
http://free-electrons.com


From alexandre.belloni at free-electrons.com  Tue Aug 11 11:32:09 2015
From: alexandre.belloni at free-electrons.com (Alexandre Belloni)
Date: Tue, 11 Aug 2015 20:32:09 +0200
Subject: [rtc-linux] Re: [PATCH v2 1/2] devicetree: bindings: rtc: add
 bindings for xilinx zynqmp rtc
In-Reply-To: <7f57f610-7eea-434c-b7b8-3fb15cea18c0@googlegroups.com>
References: <1438336757-23404-1-git-send-email-suneel.garapati@xilinx.com>
 <7f57f610-7eea-434c-b7b8-3fb15cea18c0@googlegroups.com>
Message-ID: <20150811183209.GX3411@piout.net>

Hi,

On 06/08/2015 at 21:53:09 -0700, suneelgarapati at gmail.com wrote :
> Hi Alexandre Belloni,
> 
> Any review comments on v2 series?
> 

Done. It would probably help if I was in copy of your mails ;)


-- 
Alexandre Belloni, Free Electrons
Embedded Linux, Kernel and Android engineering
http://free-electrons.com


From sboyd at codeaurora.org  Tue Aug 11 11:34:25 2015
From: sboyd at codeaurora.org (Stephen Boyd)
Date: Tue, 11 Aug 2015 11:34:25 -0700
Subject: [GIT PULL] i.MX clock updates for 4.2
In-Reply-To: <20150811174657.2416.1270@quantum>
References: <20150811085921.GB10035@tiger> <20150811174657.2416.1270@quantum>
Message-ID: <20150811183425.GL2839@codeaurora.org>

On 08/11, Michael Turquette wrote:
> > 
> > Also, please keep it stable, because I need to pull it into other
> > branch as dependency which I will send via arm-soc tree.
> 
> Will do.
> 
> Also, the clock driver was not Cc'd to linux-clk mailing list nor did it
> Cc myself or Stephen. I've taken a quick look at it and it seems fine,
> but please post clk patches to the linux-clk mailing list in the future.
> 

Yes. We would have found this unused include too. I'll apply this
after we merge it into clk-next.

----8<----
From: Stephen Boyd <sboyd at codeaurora.org>
Subject: [PATCH] clk: imx: Remove unused clkdev.h include

Signed-off-by: Stephen Boyd <sboyd at codeaurora.org>
---
 drivers/clk/imx/clk-imx6ul.c | 1 -
 1 file changed, 1 deletion(-)

diff --git a/drivers/clk/imx/clk-imx6ul.c b/drivers/clk/imx/clk-imx6ul.c
index aaa36650695f..c498f558e942 100644
--- a/drivers/clk/imx/clk-imx6ul.c
+++ b/drivers/clk/imx/clk-imx6ul.c
@@ -11,7 +11,6 @@
 
 #include <dt-bindings/clock/imx6ul-clock.h>
 #include <linux/clk.h>
-#include <linux/clkdev.h>
 #include <linux/err.h>
 #include <linux/init.h>
 #include <linux/io.h>
-- 
Qualcomm Innovation Center, Inc. is a member of Code Aurora Forum,
a Linux Foundation Collaborative Project


From lho at apm.com  Tue Aug 11 11:43:24 2015
From: lho at apm.com (Loc Ho)
Date: Tue, 11 Aug 2015 11:43:24 -0700
Subject: [PATCH v2 0/3] edac: Add L3/SoC support to the APM X-Gene SoC
 EDAC driver
In-Reply-To: <CALdTtnsfQ1GsZqCN470hdvsJtr_Fi5BU2L1xfAo4cqb=S9yfqA@mail.gmail.com>
References: <1437808063-17592-1-git-send-email-lho@apm.com>
 <CALdTtnv7P5d0Y6wyKe1SOqXedNhQxMsFZY=m-rxK3zouLcFv-Q@mail.gmail.com>
 <CAPw-ZT=9Eq0yc7tzqJAdCvsQTgRkMmGzNOSXgawBTY0gAijr4Q@mail.gmail.com>
 <CALdTtnsfQ1GsZqCN470hdvsJtr_Fi5BU2L1xfAo4cqb=S9yfqA@mail.gmail.com>
Message-ID: <CAPw-ZTkMR3Kx=dhaZ0BZWMUU027f4X7STTSZV6JA0ne0W3-JPQ@mail.gmail.com>

Hi Dann,

On Tue, Aug 11, 2015 at 7:36 AM, Dann Frazier
<dann.frazier at canonical.com> wrote:
> On Mon, Aug 10, 2015 at 2:15 PM, Loc Ho <lho at apm.com> wrote:
>> Hi Dann,
>>
>>>> v2:
>>>> * Update binding documentation accordingly
>>>> * Change all single bit defines to BIT(x)
>>>> * Add support for L3 version 1 and 2 HW's
>>>> * Change to use debug file system for error injection
>>>> * In L3/SoC instance add function, allocate EDAC context after all
>>>>   initalization successed
>>>> * Support raw or detail info for SoC EDAC error reporting
>>>>
>>>> v1:
>>>> * Add L3/SoC support to the APM X-Gene SoC EDAC driver
>>>
>>> Loc,
>>>   I tested 4.2-rc5 on a Mustang board with one DIMM, and it hangs (RCU
>>> stall) in xgene_edac_mc_irq_ctl() on modprobe. Same board with 2 DIMMs
>>> boots fine. (U-boot 1.15.12).
>>
>> I just removed one of the two 16GB DIMM... with 4.2.0-rc1 and some
>> code clean up in EDAC driver, it boots just fine... I don't believe
>> the code clean up would affect it. Do you have the dump log?
>>
>> [root at dhcp-10-76-213-247 ~]# uname -a
>> Linux dhcp-10-76-213-247 4.2.0-rc1+ #33 SMP PREEMPT Mon Aug 10
>> 13:23:03 MDT 2015 aarch64 GNU/Linux
>
> Sure:
>   http://paste.ubuntu.com/12055821/
> I've reproduced this on two machines. In both cases, we removed the
> DIMM furthest from the CPU (in case that matters).

This is an un-supported configuration. In the latest FW, the FW will
flag this and won't boot. Please remove the DIMM closest to the CPU.
FYI... I will be posting another version soon.

-Loc


From davem at davemloft.net  Tue Aug 11 11:49:08 2015
From: davem at davemloft.net (David Miller)
Date: Tue, 11 Aug 2015 11:49:08 -0700 (PDT)
Subject: [PATCH v2 0/2] net: thunder: Add ACPI support.
In-Reply-To: <1439254717-2875-1-git-send-email-ddaney.cavm@gmail.com>
References: <1439254717-2875-1-git-send-email-ddaney.cavm@gmail.com>
Message-ID: <20150811.114908.1384923604512568161.davem@davemloft.net>

From: David Daney <ddaney.cavm at gmail.com>
Date: Mon, 10 Aug 2015 17:58:35 -0700

> Change from v1:  Drop PHY binding part, use fwnode_property* APIs.
> 
> The first patch (1/2) rearranges the existing code a little with no
> functional change to get ready for the second.  The second (2/2) does
> the actual work of adding support to extract the needed information
> from the ACPI tables.

Series applied.

In the future it might be better structured to try and get the OF
node, and if that fails then try and use the ACPI method to obtain
these values.



From m-karicheri2 at ti.com  Tue Aug 11 12:13:29 2015
From: m-karicheri2 at ti.com (Murali Karicheri)
Date: Tue, 11 Aug 2015 15:13:29 -0400
Subject: [PATCH] ARM: keystone: add a work around to handle asynchronous
 external abort
Message-ID: <1439320409-20084-1-git-send-email-m-karicheri2@ti.com>

Currently on some devices, an asynchronous external abort exception
happens during boot up when exception handlers are enabled in kernel
before switching to user space. This patch adds a workaround to handle
this once during boot. Many customers are already using this
with out any issues and is required to workaround the above issue.

Signed-off-by: Murali Karicheri <m-karicheri2 at ti.com>
---
 arch/arm/mach-keystone/keystone.c | 26 ++++++++++++++++++++++++++
 1 file changed, 26 insertions(+)

diff --git a/arch/arm/mach-keystone/keystone.c b/arch/arm/mach-keystone/keystone.c
index e2880105..c1d0fe5 100644
--- a/arch/arm/mach-keystone/keystone.c
+++ b/arch/arm/mach-keystone/keystone.c
@@ -15,6 +15,7 @@
 #include <linux/of_platform.h>
 #include <linux/of_address.h>
 #include <linux/memblock.h>
+#include <linux/signal.h>
 
 #include <asm/setup.h>
 #include <asm/mach/map.h>
@@ -52,6 +53,24 @@ static struct notifier_block platform_nb = {
 	.notifier_call = keystone_platform_notifier,
 };
 
+static bool ignore_first = true;
+static int keystone_async_ext_abort_fault(unsigned long addr, unsigned int fsr,
+					  struct pt_regs *regs)
+{
+	/*
+	 * if first time, ignore this as this is a asynchronous external abort
+	 * happening only some devices that couldn't be root caused and we add
+	 * this work around to handle this first time.
+	 */
+	if (ignore_first) {
+		ignore_first = false;
+		return 0;
+	}
+
+	/* Subsequent ones should be handled as fault */
+	return 1;
+}
+
 static void __init keystone_init(void)
 {
 	if (PHYS_OFFSET >= KEYSTONE_HIGH_PHYS_START) {
@@ -61,6 +80,13 @@ static void __init keystone_init(void)
 	}
 	keystone_pm_runtime_init();
 	of_platform_populate(NULL, of_default_bus_match_table, NULL, NULL);
+
+	/*
+	 * Add a one time exception handler to catch asynchronous external
+	 * abort
+	 */
+	hook_fault_code(17, keystone_async_ext_abort_fault, SIGBUS, 0,
+			"async external abort handler");
 }
 
 static phys_addr_t keystone_virt_to_idmap(unsigned long x)
-- 
1.9.1



From mchehab at osg.samsung.com  Tue Aug 11 12:15:38 2015
From: mchehab at osg.samsung.com (Mauro Carvalho Chehab)
Date: Tue, 11 Aug 2015 16:15:38 -0300
Subject: [PATCH] c8sectpfe: don't go past channel_data array
Message-ID: <298d59cd52c4ecce188439fcd19946ffafe682fc.1439320535.git.mchehab@osg.samsung.com>

As reported by smatch:
	drivers/media/platform/sti/c8sectpfe/c8sectpfe-core.c:365 find_channel() error: buffer overflow 'fei->channel_data' 8 <= 63

It seems that a cut-and-paste type of error occurred here:
the channel_data array size is C8SECTPFE_MAX_TSIN_CHAN, and not
C8SECTPFE_MAXCHANNEL.

Signed-off-by: Mauro Carvalho Chehab <mchehab at osg.samsung.com>

diff --git a/drivers/media/platform/sti/c8sectpfe/c8sectpfe-core.c b/drivers/media/platform/sti/c8sectpfe/c8sectpfe-core.c
index 3a9109356e67..955d8daf055f 100644
--- a/drivers/media/platform/sti/c8sectpfe/c8sectpfe-core.c
+++ b/drivers/media/platform/sti/c8sectpfe/c8sectpfe-core.c
@@ -361,7 +361,7 @@ static struct channel_info *find_channel(struct c8sectpfei *fei, int tsin_num)
 {
 	int i;
 
-	for (i = 0; i < C8SECTPFE_MAXCHANNEL; i++) {
+	for (i = 0; i < C8SECTPFE_MAX_TSIN_CHAN; i++) {
 		if (!fei->channel_data[i])
 			continue;
 
-- 
2.4.3



From bhelgaas at google.com  Tue Aug 11 12:28:39 2015
From: bhelgaas at google.com (Bjorn Helgaas)
Date: Tue, 11 Aug 2015 14:28:39 -0500
Subject: X-Gene: Unhandled fault: synchronous external abort in
 pci_generic_config_read32
In-Reply-To: <CADaLNDmnnZOoB1fxO=rQQa-eqT=B9G24rUrN_GzwAkFoC3Acbw@mail.gmail.com>
References: <20150724224258.GA23990@google.com>
 <CADaLNDmYZ=8XQt82W_H74QaOiX3UwkVxkE1_EWRgzhkG1boebw@mail.gmail.com>
 <CAErSpo549xfAnx62quCqGHh3DNay5Lfb6EhEG+4EXooEuueQFQ@mail.gmail.com>
 <CADaLNDn95H=g73DKWRsrB4SuWcf+-8mkepbwb_DC-sFsVkrk6g@mail.gmail.com>
 <20150728212944.GA12958@google.com>
 <CADaLNDkOLiyPmVC3VwpnbrfAKFmNwSVJKdChjQFdQqs7XP-Ddg@mail.gmail.com>
 <20150729012255.GA18606@google.com> <20150729155509.GA31170@google.com>
 <CADaLNDk=+J_yOer1ferSCNb_xAC42ULtP2FyCLmYMwa+Gj=vfA@mail.gmail.com>
 <CAErSpo4VFh7rv81sCAG-eCXVyZh4ub8Trh-ntZhyfy7BzqTr5g@mail.gmail.com>
 <CADaLNDkUQHzGACfFmYDeJWnaNrKmJUDx4Rby60OWr4FzOjx3rA@mail.gmail.com>
 <CAErSpo7aDYKwy4MC6ZPf7hNd4MPE-LARiOVKutFfDFFkHY7qjQ@mail.gmail.com>
 <CADaLNDmnnZOoB1fxO=rQQa-eqT=B9G24rUrN_GzwAkFoC3Acbw@mail.gmail.com>
Message-ID: <CAErSpo59jH3qeqThG-OO_dqB0fU5gmgC89Xued5QKrbB0dt2yg@mail.gmail.com>

On Mon, Aug 10, 2015 at 2:07 PM, Duc Dang <dhdang at apm.com> wrote:
> On Mon, Aug 10, 2015 at 10:42 AM, Bjorn Helgaas <bhelgaas at google.com> wrote:
>> On Mon, Aug 10, 2015 at 12:16 PM, Duc Dang <dhdang at apm.com> wrote:
>>> On Monday, August 10, 2015, Bjorn Helgaas <bhelgaas at google.com> wrote:
>>>>
>>>> On Fri, Jul 31, 2015 at 12:00 PM, Duc Dang <dhdang at apm.com> wrote:
>>>> > On Wed, Jul 29, 2015 at 8:55 AM, Bjorn Helgaas <bhelgaas at google.com>
>>>> > wrote:
>>>> >> On Tue, Jul 28, 2015 at 08:22:55PM -0500, Bjorn Helgaas wrote:
>>>> >>> On Tue, Jul 28, 2015 at 02:50:39PM -0700, Duc Dang wrote:
>>>> >>
>>>> >>> > Do you have another PCIe card to try on the same reboot test on this
>>>> >>> > board?
>>>> >>>
>>>> >>> I've seen this on at least two Mellanox cards.  I'm running similar
>>>> >>> tests
>>>> >>> on a different type of card now.
>>>> >>
>>>> >> FWIW, reboot tests on two machines with Mellanox cards failed, while
>>>> >> the
>>>> >> same test on a machine with a different proprietary card succeeded.
>>>> >
>>>> > Thanks, Bjorn.
>>>> >
>>>> > I don't have the same Mellanox card as yours, but I will also run
>>>> > similar reboot test to see if I hit the same issue with my card.
>>>>
>>>> Any more hints on this?  Nothing has changed on my end, so of course
>>>> I'm still seeing this, always on machines with Mellanox, and never on
>>>> other machines.  Could this be a hardware issue like a signal
>>>> integrity or margin issue?  I don't know where to go from here because
>>>> I'm not a hardware person, and I don't know anything to do in
>>>> software.
>>>
>>>
>>> Hi Bjorn,
>>>
>>> I tried to run similar reboot tests on 2 different Mellanox cards (Connect-X
>>> family, one card has 2 10G interfaces, the other one has 1 port that
>>> supports InfiniBand) with U-Boot 1.15.12 and linux 4.2-rc5 and I did not see
>>> the crash that you encounterred.
>>>
>>> Did you check if your Mellanox cards have latest firmware? I did see some
>>> link issues on my Mellanox cards with its old firmware before.
>>
>> Good idea; I'll check that, too.  Also, I just learned that these
>> cards on installed with an extender card because of some space issues,
>> so we're going to test again without the extender.
>
> Hi Bjorn,
>
> Are other cards that passed your test installed directly to the
> on-board PCIe slot?
> If yes, then this is a good data point and it will be useful to test
> the case where
> your Mellanox cards are directly installed into the on-board PCIe slot.

The cards that passed the test were installed directly, with  no
extender.  We removed the extender from one of the machines with the
Mellanox card and have not seen this issue since then.  I think it's
very likely that the problem is related to using the extender.

Bjorn


From suneel.garapati at xilinx.com  Tue Aug 11 12:29:54 2015
From: suneel.garapati at xilinx.com (Suneel Garapati)
Date: Tue, 11 Aug 2015 19:29:54 +0000
Subject: [rtc-linux] Re: [PATCH v2 1/2] devicetree: bindings: rtc: add
 bindings for xilinx zynqmp rtc
In-Reply-To: <20150811183209.GX3411@piout.net>
References: <1438336757-23404-1-git-send-email-suneel.garapati@xilinx.com>
 <7f57f610-7eea-434c-b7b8-3fb15cea18c0@googlegroups.com>
 <20150811183209.GX3411@piout.net>
Message-ID: <EE0C027E1B1062419E7D6F61B9CF3AF65EDC2845@XAP-PVEXMBX01.xlnx.xilinx.com>

Hi Alexandre,

For unknown reason, Alessandro zummo is shown by get_maintainer.pl.
I will fix and send v3 with all comments addressed.

Regards,
Suneel

> -----Original Message-----
> From: Alexandre Belloni [mailto:alexandre.belloni at free-electrons.com]
> Sent: Wednesday, August 12, 2015 0:02 AM
> To: suneelgarapati at gmail.com
> Cc: rtc-linux; linux-arm-kernel at lists.infradead.org; linux-
> kernel at vger.kernel.org; Michal Simek; Soren Brinkmann;
> a.zummo at towertech.it; Suneel Garapati; Anirudha Sarangi
> Subject: Re: [rtc-linux] Re: [PATCH v2 1/2] devicetree: bindings: rtc: add
> bindings for xilinx zynqmp rtc
>
> Hi,
>
> On 06/08/2015 at 21:53:09 -0700, suneelgarapati at gmail.com wrote :
> > Hi Alexandre Belloni,
> >
> > Any review comments on v2 series?
> >
>
> Done. It would probably help if I was in copy of your mails ;)
>
>
> --
> Alexandre Belloni, Free Electrons
> Embedded Linux, Kernel and Android engineering http://free-electrons.com


This email and any attachments are intended for the sole use of the named recipient(s) and contain(s) confidential information that may be proprietary, privileged or copyrighted under applicable law. If you are not the intended recipient, do not read, copy, or forward this email message or any attachments. Delete this email message and any attachments immediately.



From dev at lynxeye.de  Tue Aug 11 12:38:38 2015
From: dev at lynxeye.de (Lucas Stach)
Date: Tue, 11 Aug 2015 21:38:38 +0200
Subject: [PATCH] arm: rpi: Device tree modifications for U-Boot
In-Reply-To: <55CA3113.1010601@wwwdotorg.org>
References: <1439303153-12171-1-git-send-email-sjg@chromium.org>
 <1439312701.2451.3.camel@lynxeye.de> <55CA3113.1010601@wwwdotorg.org>
Message-ID: <1439321918.2214.6.camel@lynxeye.de>

Am Dienstag, den 11.08.2015, 11:29 -0600 schrieb Stephen Warren:
> On 08/11/2015 11:05 AM, Lucas Stach wrote:
> > Hi Simon,
> >
> > why did you send this to the Tegra ML?
> 
> At my request, so that the DT changes could be reviewed by the kernel DT 
> reviewers and added to the copy of the DT files in the kernel source 
> tree if approved.
> 
This doesn't really answer the question why it was sent to the Tegra
list if it is an RPi change, but that's just a side note.

> My assertion is that DT content should be independent of SW stack. Or 
> put another way, all SW stacks should use the same DT content. As such, 
> if these properties are needed by U-Boot, and contained in the copy of 
> the DT files in the U-Boot source tree, they should also be present in 
> the copy of the DT files in the kernel source tree, so the two do not 
> become out of sync.
> 
I agree with that overall goal to have a common DT base between
different software stacks. After all I lobbied for keeping the Tegra
pinctrl setting in the DT even though Linux doesn't use them any more.

For my question below I honestly want an answer as to why U-Boot needs
those DT changes and why it can't work with the current DT contents.
It's really just the same question we also have to answer for each and
every DT addition that we do for Linux.

Regards,
Lucas

> > Am Dienstag, den 11.08.2015, 08:25 -0600 schrieb Simon Glass:
> >> This updates the device tree from the kernel version to something suitable
> >> for U-Boot:
> >>
> >> - Add stdout-path alias for console
> >> - Mark the /soc node to be available pre-relocation so that the early
> >> serial console works (we need the 'ranges' property to be available)
> 
> >> diff --git a/arch/arm/boot/dts/bcm2835.dtsi b/arch/arm/boot/dts/bcm2835.dtsi
> >> index 301c73f..bd6bff6 100644
> >> --- a/arch/arm/boot/dts/bcm2835.dtsi
> >> +++ b/arch/arm/boot/dts/bcm2835.dtsi
> >> @@ -8,6 +8,7 @@
> >>
> >>   	chosen {
> >>   		bootargs = "earlyprintk console=ttyAMA0";
> >> +		stdout-path = &uart;
> >>   	};
> >>
> >>   	soc {
> >> @@ -16,6 +17,7 @@
> >>   		#size-cells = <1>;
> >>   		ranges = <0x7e000000 0x20000000 0x02000000>;
> >>   		dma-ranges = <0x40000000 0x00000000 0x20000000>;
> >> +		u-boot,dm-pre-reloc;
> >
> > Why do you need this and why should upstream carry your favourite
> > bootloaders configuration? This is in no way hardware description.
> 
> 




From nico at fluxnic.net  Tue Aug 11 12:41:52 2015
From: nico at fluxnic.net (Nicolas Pitre)
Date: Tue, 11 Aug 2015 15:41:52 -0400 (EDT)
Subject: arm kernel oops in highmem.c with 4.2
In-Reply-To: <20150811181008.GA7557@n2100.arm.linux.org.uk>
References: <CALeDE9Ox3=sh3AXQ0NUG6BBfU5i5YrMY=LDpcTHQWqz2=60F2g@mail.gmail.com>
 <20150805100701.GV7557@n2100.arm.linux.org.uk>
 <CALeDE9PXF=gQCaBCiHpHy2nXOooQOmsCQvSgOv+wQw3mta=P6A@mail.gmail.com>
 <20150805112713.GY7557@n2100.arm.linux.org.uk>
 <1439315290.3153.11.camel@redhat.com>
 <20150811181008.GA7557@n2100.arm.linux.org.uk>
Message-ID: <alpine.LFD.2.20.1508111501130.1515@knanqh.ubzr>

On Tue, 11 Aug 2015, Russell King - ARM Linux wrote:

> On Tue, Aug 11, 2015 at 01:48:10PM -0400, Mark Salter wrote:
> > On Wed, 2015-08-05 at 12:27 +0100, Russell King - ARM Linux wrote:
> > > It helps if I look at 4.2 rather than an older kernel :)
> > > 
> > > However, I've checked that I have DEBUG_HIGHMEM enabled, which I do, and
> > > I'm unable to reproduce this here.  My kernels are built with gcc 4.7.4.
> > > 
> > > What it looks like from your oops is that the address which was passed
> > > in was 0xffedf000, but the address we calculated via the following for
> > > the current index was 0xfff00000:
> > > 
> > > type = kmap_atomic_idx();
> > > idx = type + KM_TYPE_NR * smp_processor_id();
> > > __fix_to_virt(idx)
> > > 
> > > Doing a bit of maths... the address 0xffedf000 corresponds to a fixmap
> > > index of... (0xffeff000 - 0xffedf000) >> 12 = 32.  KM_TYPE_NR is 16 on
> > > ARM, so the mapping was created by CPU 2, and type was zero.
> > > 
> > > On unmap, 0xfff00000 gives... (0xffeff000 - 0xfff00000) >> 12 = -1.
> > > That suggests we're on CPU 0, and type is -1 - in other words, there
> > > are no atomically mapped mappings on CPU 0.
> > > 
> > > Since kmap_atomic() disables preemption and page faults, how did your
> > > kernel migrate this thread from CPU 2 to CPU 0... and I can't see how
> > > that happened.
> > > 
> > 
> > The fedora kernel is using PREEMPT_VOLUNTARY with !PREEMPT and
> > !PREEMPT_CPOUNT. So preempt_disable() is a nop. I added some code
> > to catch the kernel scheduling between kmap_atomic() and
> > kunmap_atomic() and got this straightaway:
> 
> Looking at the backtrace, and grepping for __copy_to_user_memcpy, it
> seems to imply that you're using the uaccess-with-memcpy code.
> 
> This code is relatively unmaintained, and probably mostly unused by
> people today, so I doubt it gets much in the way of testing - and
> you've certainly found a bug in there.
> 
>         /* the mmap semaphore is taken only if not in an atomic context */
>         atomic = in_atomic();
> 
>         if (!atomic)
>                 down_read(&current->mm->mmap_sem);
> 
> is not sufficient to tell whether we can take the semaphore.
> 
> We _could_ replace the above with:
> 
> 	int ret;
> 
> 	ret = down_read_trylock(&current->mm->mmap_sem);
> 	if (!ret) {
> 		__copy_to_user_std(to, from, n);
> 		return;
> 	}
> 
> but that's just a guess.  I'm not a big fan of this code, and given
> that it probably doesn't get much use, we may be better off deleting
> it so it doesn't sit around rotting...  Code like this really needs
> regular testing.

I'd agree.  But first I'd like to know why the fedora kernel is using 
CONFIG_UACCESS_WITH_MEMCPY?  If it's just because it sounded cool then 
that's a bad reason.

That code was created to work around inneficiency in the Orion CPU core 
that didn't coalesce writes from STRT instructions, and by using plain 
STR and/or STM the actual throughput was more than doubled.  This was 
fixed in later cores. However Orion users (if they still exist) might 
like the added performance. I don't have Orion-based targets anymore 
(they took the way of the recycling facility a while ago).

To be sure you really need it, you may try something like:

	dd if=/dev/zero of=/dev/null bs=4k

and compare the reported speed with and without 
CONFIG_UACCESS_WITH_MEMCPY.


Nicolas


From marex at denx.de  Tue Aug 11 09:54:30 2015
From: marex at denx.de (Marek Vasut)
Date: Tue, 11 Aug 2015 18:54:30 +0200
Subject: [PATCH V5 0/3] nvmem: add ocotp support for i.MX23 and i.MX28
In-Reply-To: <1439299818-8495-1-git-send-email-stefan.wahren@i2se.com>
References: <1439299818-8495-1-git-send-email-stefan.wahren@i2se.com>
Message-ID: <201508111854.30933.marex@denx.de>

On Tuesday, August 11, 2015 at 03:30:15 PM, Stefan Wahren wrote:
> This patch series brings read-only support for the On-Chip OTP cells
> in the i.MX23 and i.MX28 processor.
> 
> changes in V5:
> - rebase to char-misc-next
> - add nvmem prefix to module name
> - set status in dtsi files
> 
> changes in V4:
> - rename fsl_ocotp.c to mxs-ocotp.c
> - adapt driver to use NVMEM framework V7
> - take care of hbus clock
> - increase too small timeout
> - implement a wait function
> - use defines from stmp_device.h
> - remove owner init
> - more code cleanup
> 
> changes in V3:
> - drop write support
> - take care of i.MX23 which has less registers
> - drop unnecessary header file
> - move static variables into driver data
> - add devicetree probing
> - fix missing bank closing in error case
> - use kobj from platform device for sysfs
> - add SYSFS to Kconfig
> - add binding file
> - code cleanup
> 
> Stefan Wahren (3):
>   DT: nvmem: add binding for mxs-ocotp
>   nvmem: add driver for ocotp in i.MX23 and i.MX28
>   ARM: mxs: enable ocotp for i.MX23 and i.MX28
> 
>  .../devicetree/bindings/nvmem/mxs-ocotp.txt        |   24 ++
>  arch/arm/boot/dts/imx23.dtsi                       |    7 +-
>  arch/arm/boot/dts/imx28.dtsi                       |    7 +-
>  drivers/nvmem/Kconfig                              |   11 +
>  drivers/nvmem/Makefile                             |    2 +
>  drivers/nvmem/mxs-ocotp.c                          |  252
> ++++++++++++++++++++ 6 files changed, 299 insertions(+), 4 deletions(-)
>  create mode 100644 Documentation/devicetree/bindings/nvmem/mxs-ocotp.txt
>  create mode 100644 drivers/nvmem/mxs-ocotp.c

Very nice, other than the comments from Srinivas, you can add my

Reviewed-by: Marek Vasut <marex at denx.de>

Best regards,
Marek Vasut


From linux at arm.linux.org.uk  Tue Aug 11 12:56:38 2015
From: linux at arm.linux.org.uk (Russell King - ARM Linux)
Date: Tue, 11 Aug 2015 20:56:38 +0100
Subject: arm kernel oops in highmem.c with 4.2
In-Reply-To: <alpine.LFD.2.20.1508111501130.1515@knanqh.ubzr>
References: <CALeDE9Ox3=sh3AXQ0NUG6BBfU5i5YrMY=LDpcTHQWqz2=60F2g@mail.gmail.com>
 <20150805100701.GV7557@n2100.arm.linux.org.uk>
 <CALeDE9PXF=gQCaBCiHpHy2nXOooQOmsCQvSgOv+wQw3mta=P6A@mail.gmail.com>
 <20150805112713.GY7557@n2100.arm.linux.org.uk>
 <1439315290.3153.11.camel@redhat.com>
 <20150811181008.GA7557@n2100.arm.linux.org.uk>
 <alpine.LFD.2.20.1508111501130.1515@knanqh.ubzr>
Message-ID: <20150811195638.GC7557@n2100.arm.linux.org.uk>

On Tue, Aug 11, 2015 at 03:41:52PM -0400, Nicolas Pitre wrote:
> I'd agree.  But first I'd like to know why the fedora kernel is using 
> CONFIG_UACCESS_WITH_MEMCPY?  If it's just because it sounded cool then 
> that's a bad reason.
> 
> That code was created to work around inneficiency in the Orion CPU core 
> that didn't coalesce writes from STRT instructions, and by using plain 
> STR and/or STM the actual throughput was more than doubled.  This was 
> fixed in later cores. However Orion users (if they still exist) might 
> like the added performance. I don't have Orion-based targets anymore 
> (they took the way of the recycling facility a while ago).

Irrespective of that, what has been found is that the implementation is
unsafe - it is taking a semaphore when page faults are disabled.  In
other words, notwithstanding the above, it's buggy no matter if it's
an Orion CPU core, or highmem, or what.  Any place in the kernel which
uses pagefault_disable() and then calls into this code will be buggy.

It needs fixing or removing.

Even if it is fixed, making it _depend_ on CPU_FEROCEON sounds like a
good idea if non-orion stuff isn't supposed to be enabling it.  Or
something like that.

-- 
FTTC broadband for 0.8mile line: currently at 10.5Mbps down 400kbps up
according to speedtest.net.


From ddaney at caviumnetworks.com  Tue Aug 11 13:04:55 2015
From: ddaney at caviumnetworks.com (David Daney)
Date: Tue, 11 Aug 2015 13:04:55 -0700
Subject: [PATCH v2 0/2] net: thunder: Add ACPI support.
In-Reply-To: <20150811.114908.1384923604512568161.davem@davemloft.net>
References: <1439254717-2875-1-git-send-email-ddaney.cavm@gmail.com>
 <20150811.114908.1384923604512568161.davem@davemloft.net>
Message-ID: <55CA5567.9010002@caviumnetworks.com>

On 08/11/2015 11:49 AM, David Miller wrote:
> From: David Daney <ddaney.cavm at gmail.com>
> Date: Mon, 10 Aug 2015 17:58:35 -0700
>
>> Change from v1:  Drop PHY binding part, use fwnode_property* APIs.
>>
>> The first patch (1/2) rearranges the existing code a little with no
>> functional change to get ready for the second.  The second (2/2) does
>> the actual work of adding support to extract the needed information
>> from the ACPI tables.
>
> Series applied.

Thank you very much.

>
> In the future it might be better structured to try and get the OF
> node, and if that fails then try and use the ACPI method to obtain
> these values.

Our current approach, as you can see in the patch, is the opposite.  If 
ACPI is being used, prefer that over the OF device tree.

You seem to be recommending precedence for OF.  It should be consistent 
across all drivers/sub-systems, so do you really think that OF before 
ACPI is the way to go?

Thanks,
David Daney




From robherring2 at gmail.com  Tue Aug 11 13:12:54 2015
From: robherring2 at gmail.com (Rob Herring)
Date: Tue, 11 Aug 2015 15:12:54 -0500
Subject: [PATCH 5/9] ARM: common: Introduce PM domains for CPUs/clusters
In-Reply-To: <20150811155819.GH52339@linaro.org>
References: <1438731339-58317-1-git-send-email-lina.iyer@linaro.org>
 <1438731339-58317-6-git-send-email-lina.iyer@linaro.org>
 <CAL_JsqK67=DTtjZwwnonObLDjLbahkREfm0RvyXVV95bhR-d4Q@mail.gmail.com>
 <7hd1yyvf1b.fsf@deeprootsystems.com>
 <CAMuHMdWRoUOBvz7MEGgF1oHz95D-GhaYG1yHr_kGe5NUQ0EnrQ@mail.gmail.com>
 <20150811155819.GH52339@linaro.org>
Message-ID: <CAL_JsqLhHy5gO=usm1HLf8h6iz_5FguCDo-Qz2Km+XEwaCODUA@mail.gmail.com>

On Tue, Aug 11, 2015 at 10:58 AM, Lina Iyer <lina.iyer at linaro.org> wrote:
> On Tue, Aug 11 2015 at 07:07 -0600, Geert Uytterhoeven wrote:
>>
>> On Sat, Aug 8, 2015 at 1:45 AM, Kevin Hilman <khilman at kernel.org> wrote:
>>>
>>> Rob Herring <robherring2 at gmail.com> writes:
>>>>
>>>> On Tue, Aug 4, 2015 at 6:35 PM, Lina Iyer <lina.iyer at linaro.org> wrote:
>>>>>
>>>>> +ARM CPU Power domains
>>>>> +
>>>>> +The device tree allows describing of CPU power domains in a SoC. In
>>>>> ARM SoC,
>>>>> +CPUs may be grouped as clusters. A cluster may have CPUs, GIC,
>>>>> Coresight,
>>>>> +caches, VFP and power controller and other peripheral hardware.
>>>>> Generally,
>>>>> +when the CPUs in the cluster are idle/suspended, the shared resources
>>>>> may also
>>>>> +be suspended and resumed before any of the CPUs resume execution.
>>>>> +
>>>>> +CPUs are the defined as the PM domain consumers and there is a PM
>>>>> domain
>>>>> +provider for the CPUs. Bindings for generic PM domains (genpd) is
>>>>> described in
>>>>> +[1].
>>>>> +
>>>>> +The ARM CPU PM domain follows the same binding convention as any
>>>>> generic PM
>>>>> +domain. Additional binding properties are -
>>>>> +
>>>>> +- compatible:
>>>>> +       Usage: required
>>>>> +       Value type: <string>
>>>>> +       Definition: Must also have
>>>>> +                       "arm,pd"
>>>>> +               inorder to initialize the genpd provider as ARM CPU PM
>>>>> domain.
>>>>
>>>>
>>>> A compatible string should represent a particular h/w block. If it is
>>>> generic, it should represent some sort of standard programming
>>>> interface (e.g, AHCI, EHCI, etc.). This doesn't seem to be either and
>>>> is rather just a mapping of what "driver" you want to use.
>>>>
>>>> I would expect that identifying a cpu's or cluster's power domain
>>>> would be done by a phandle between the cpu/cluster node and power
>>>> domain node.
>>>
>>>
>>> That's correct, the CPU nodes (and other nodes in the cluster like GIC,
>>> Coresight, etc.) would have phandles to the cluster power domain node.
>>
>>
>> Indeed.
>>
>>> But this series is meant to create the driver & binding for those cluster
>>> power domain(s), so the question is how exactly describe it.
>>
>>
>> I don't think I can add an "arm,pd" compatible property to e.g. a2sl
>> (for CA15-CPUx) and a3sm (for CA15-SCU) in arch/arm/boot/dts/r8a73a4.dtsi,
>> as these are just subdomains in a power domain hierarchy, all driven by a
>> single hardware block.
>>
>> I can call e.g. a special registration method, or set up some ops pointer,
>> for the a2sl and a3sm subdomains from within the "renesas,sysc-rmobile"
>> driver.
>>
> I was hoping the macro would help in such a case. But since your domain
> cannot be defined as arm,pd (could you explain why, I seem to missing
> the obvious) would it help if I export a function like that the
> renesas,sysc-rmobile driver could call and setup the CPU PM domain?
> There is catch to it though.
>
> The problem is -
>
> To be generic and not have every driver write code to do this generic
> functionality, the common code would want to instantiate the
> arm_pm_domain and therefore the embedded genpd. A pointer instead of
> actual object, would mean maintaining a list and iterating through it,
> everytime the domain is suspended/resumed. With an object, I could just
> do container_of and get the arm_pd. But, we also want to give the
> platform an option to define certain aspects of the CPU's generic PM
> domain like the flags, genpd callbacks etc, before the genpd is
> registered with the framework.

The problem here is what part of the hardware is generic? It is
generic, but yet ARM specific (presumably not as Kevin pointed out)?
I'm not exactly clear what the problem is, but it seems you are after
a common API/subsystem for managing power domains of CPU/clusters. I
fail to see how the problem is different than any other subsystem
where you have a core providing common API with hardware specific
drivers registering their ops with the core.

>
> Would such a function work for you? What does everyone think about the
> @template?
>
> struct generic_pm_domain *of_arm_cpu_domain(struct device_node *dn,

This is missing a verb. What does it do?

I don't think I really get what you are trying to solve to comment
whether this looks good or not.

Rob

>                struct of_arm_pd_ops *ops, struct generic_pm_domain
> *template)
> {
>        struct arm_pm_domain *pd;
>
>        if (!of_device_is_available(dn))
>                return NULL;
>
>         /* This creates the memory for pd and setup basic stuff */
>        pd = setup_arm_pd(dn);
>
>         /* copy the platform's template genpd over to the pd's genpd */
>        memcpy(&pd.genpd, template, sizeof(*template));
>
>         /*       * Now set up the additional ops and flags and register with
>          * genpd framework
>          */
>        register_arm_pd(dn, pd);
>
>         /*       * Returning the genpd back to the platform so it can be
> added
>          * as subdomains to other domains etc.
>          */
>        return &pd.genpd;
> }
> EXPORT_SYMBOL(of_arm_cpu_domain);
>
> The catch is that platform drivers have to provide a template for the
> genpd. The @template would never be registered, but would just be used
> to create the common code's genpd.
>
> Any other ideas?
>
> Thanks,
> Lina


From robert.richter at caviumnetworks.com  Tue Aug 11 13:12:37 2015
From: robert.richter at caviumnetworks.com (Robert Richter)
Date: Tue, 11 Aug 2015 22:12:37 +0200
Subject: [PATCH v2 0/2] net: thunder: Add ACPI support.
In-Reply-To: <55CA5567.9010002@caviumnetworks.com>
References: <1439254717-2875-1-git-send-email-ddaney.cavm@gmail.com>
 <20150811.114908.1384923604512568161.davem@davemloft.net>
 <55CA5567.9010002@caviumnetworks.com>
Message-ID: <20150811201237.GW4914@rric.localhost>

On 11.08.15 13:04:55, David Daney wrote:
> >In the future it might be better structured to try and get the OF
> >node, and if that fails then try and use the ACPI method to obtain
> >these values.
> 
> Our current approach, as you can see in the patch, is the opposite.  If ACPI
> is being used, prefer that over the OF device tree.
> 
> You seem to be recommending precedence for OF.  It should be consistent
> across all drivers/sub-systems, so do you really think that OF before ACPI
> is the way to go?

If ACPI is enabled then no OF function may be called at all.

With !ACPI or acpi=no kernel parameter, then acpi_disabled is set and
no ACPI function should be called. It always falls back to and only
uses OF/devicetree in this case.

So there is now way to try devicetree first and then use acpi or vice
versa. There is no mixup using acpi or devicetree with the same boot,
either one or the other.

-Robert


From robin.murphy at arm.com  Tue Aug 11 13:15:51 2015
From: robin.murphy at arm.com (Robin Murphy)
Date: Tue, 11 Aug 2015 21:15:51 +0100
Subject: [PATCH v5 2/3] arm64: Add IOMMU dma_ops
In-Reply-To: <20150811094951.GD14980@8bytes.org>
References: <cover.1438362603.git.robin.murphy@arm.com>
 <8a5abd0a9929aae160ccb74d7a8d9c3698f61910.1438362603.git.robin.murphy@arm.com>
 <20150807085233.GV14980@8bytes.org> <55C4CE7C.7050205@arm.com>
 <20150811094951.GD14980@8bytes.org>
Message-ID: <55CA57F7.1070000@arm.com>

Hi Joerg,

On 11/08/15 10:49, Joerg Roedel wrote:
> On Fri, Aug 07, 2015 at 04:27:56PM +0100, Robin Murphy wrote:
>> As per the comments, the issue here lies in the order in which the
>> OF/driver core code currently calls things for platform devices: as
>> it stands we can't attach the device to a domain in
>> arch_setup_dma_ops() because it doesn't have a group, and we can't
>> even add it to a group ourselves because it isn't fully created and
>> doesn't exist in sysfs yet. The only reason arch/arm is currently
>> getting away without this workaround is that the few IOMMU drivers
>> there hooked up to the generic infrastructure don't actually mind
>> that they get an attach_device from arch_setup_dma_ops() before
>> they've even seen an add_device (largely because they don't care
>> about groups).
>
> Hmm, what about just registering the iommu-driver in arch_setup_dma_ops
> with bus_set_iommu and not care about devices? The code will iterate
> over the devices already on the bus and tries to attach them to the
> iommu driver. But as you said, the devices are not yet on the bus, so
> when a device is later added by the OF/driver core code you can do
> everything needed for the device in the add_device call-back.

The main problem here is that "the bus" turns out to be a nebulous and 
poorly-defined thing. "The PCI bus" breaks down as soon as you have 
multiple host controllers - you could quite easily build a SoC/chipset 
where not all the host controllers/root complexes are behind IOMMUs, or 
some are behind different types of IOMMU, and then what? The "platform 
bus" is just a glorified holding pen for device structures and utterly 
useless as any kind of abstraction.

Since I'm not concerning myself with PCI at the moment; considering the 
perspective of "the" IOMMU driver on the platform bus (assuming said 
driver is up and running first, either via OF_DECLARE or deferred 
probing of masters), the issues with relying on the add_device callback 
from the bus notifier alone are:

1) We get these callbacks for everything - devices behind one of our 
IOMMUs, devices behind different IOMMUs, devices with no IOMMU in their 
path at all - with nothing but a struct device pointer to try to 
distinguish one from the other.

2) Even for the devices actually relevant to us, we don't easily have 
the details we need to be able to set it up. In the PCI case, it's 
simple because the device has one bus ID which can trivially be looked 
up by common code; if you have driver-specific ACPI tables that identify 
platform devices and give them a single ID that you can kind of handle 
like a PCI device, fair enough; in the more general DT case, though, 
devices are going to have have any number of arbitrary IDs plus who 
knows what other associated data.

Now, both of those could probably be handled by having a big mess of 
open-coded DT parsing in every IOMMU driver's add_device, but that's 
exactly the kind of thing that having a generic DT binding should avoid. 
The generic binding is good enough to express most such arbitrary data 
pretty well, and even crazy stuff like a single device mastering through 
multiple IOMMUs with different IDs, so there's every argument for 
keeping the DT parsing generic and in core code. That's what the 
of_xlate infrastructure does: the appropriate IOMMU driver gets one or 
more of_xlate calls for a master device, from which it can collate all 
the "bus" information it needs, then later it gets the add_device 
callback once the device exists, at which point it can retrieve that 
data and use it to set up the device, allocate a group, etc.

If allocating a group for a platform device automatically set up a DMA 
mapping domain and attached it, then we wouldn't need to do anything 
with domains in arch_setup_dma_ops and the ordering problem vanishes. 
However, the drivers can't support DMA domains without a dma_ops 
implementation to back them up, which needs the DMA mapping code, which 
needs DMA domains in order to work... Hence the initial need to 
bootstrap the process via fake DMA domains in the arch code, enabling 
steady incremental development instead of one massive wide-reaching 
patch dump that's virtually impossible for me to test well and for 
others to develop against.

> This might include initializing the hardware iommu needed for the
> device and setting its per-device dma_ops.

I'm not sure that feels appropriate for our situation - If your IOMMU is 
tightly integrated into the I/O hub which forms your CPU's only 
connection to the outside world, then having it do architectural things 
seems reasonable. The kind of IOMMUs I'm dealing with here, however, are 
either just some IP block that you stitch into your SoC's mess of 
interconnects somewhere like any other peripheral (to keep your legacy 
32-bit devices behind), or even just a simple TLB with a page table 
walker and some control registers which you integrate directly into your 
own bigger devices. The latter are not really even general-purpose 
enough for arbitrary IOMMU API use, but treating them as separate IOMMUs 
makes sense from a common-driver perspective.

Having drivers for those kinds of IOMMU do things like setting dma_ops 
directly when they aren't even necessarily tied to a particular CPU 
architecture, and may have to coexist with drivers for incompatible 
IOMMUs in the same system, sounds like a recipe for tons of duplicated 
code and horrible hacks. I think on DT-based systems we *have* to keep 
system topology and device infrastructure handling in the core OF code 
and not have IOMMU drivers reinventing funnily-shaped and conflicting 
wheels all over the place.

>> Laurent's probe-deferral series largely solves these problems in the
>> right place - adding identical boilerplate code to every IOMMU
>> driver to do something they shouldn't have to know about (and don't
>> necessarily have all the right information for) is exactly what we
>> don't want to do. As discussed over on another thread, I'm planning
>> to pick that series up and polish it off after this, but my top
>> priority is getting the basic dma_ops functionality into arm64 that
>> people need right now. I will be only too happy when I can submit
>> the patch removing this notifier workaround ;)
>
> I've experienced it often that someone promises me to fix things later,
> but that it doesn't happen then, so please understand that I am pretty
> cautious about adding such hacks ;)

Oh, I understand completely - that's why I've tried as much as possible 
to keep all the workarounds out of the core code and local to arm64 
where it's easier for us to remove them cleanly. If it's any 
consolation, said patch is already written:

http://www.linux-arm.org/git?p=linux-rm.git;a=commitdiff;h=af0110ed070c13417023ca7a560dc43e9d1c46f7

(the aforementioned rough WIP branch, from which I'm hoping to pull 
together an RFC for -rc1)

>> No driver other than the AMD IOMMU has any support yet. Support for
>> IOMMU_DOMAIN_DMA can easily be added to existing drivers based on
>> patch 1 of this series, but more generally it's not entirely clear
>> how default domains are going to work beyond x86. On systems like
>> Juno or Seattle with different sets of masters behind different
>> IOMMU instances (with limited domain contexts each), the most
>> sensible approach would be to have a single default domain per IOMMU
>> (spanning domains across instances would need some hideous
>> synchronisation logic for some implementations), but the current
>> domain_alloc interface gives us no way to do that. On something like
>> RK3288 with two different types of IOMMU on the platform "bus", it
>> breaks down even further as there's no way to guarantee that
>> iommu_domain_alloc() even gives you a domain from the right *driver*
>> (hence bypassing it by going through ops directly here).
>
> Default domain allocation comes down to how the bus organizes its
> iommu-groups. For every group (at least in its current design) a default
> domain is allocated. An a group is typically only behind a single iommu
> instance.

Default-domain-per-group is great for device isolation, but the main 
thing people seem to want on ARM is the opposite of that - assembling 
big bits of virtually-contiguous memory that are visible to all the 
devices that need to share them. Per-IOMMU (or even per-system if 
appropriate) default domains provide a really neat solution for that 
use-case and mean we could mostly completely remove the IOMMU-specific 
code from GPU drivers, which is one of the things standing in the way of 
having arch/arm share the common implementation.

I'll note that limited contexts aren't a made-up consideration either. 
The PCIe SMMU in my Juno can support a maximum of 4 domains, yet the bus 
has onboard LAN and SATA plus 4 slots...

>> Only for PCI devices, via iommu_group_get_for_pci_dev(). The code
>> here, however, only runs for platform devices - ops will be always
>> null for a PCI device since of_iommu_configure() will have bailed
>> out (see the silly warning removed by my patch you picked up the
>> other day). Once iommu_group_get_for_dev() supports platform
>> devices, this too can go away. In the meantime if someone adds PCI
>> support to of_iommu_configure() and IOMMU_DOMAIN_DMA support to
>> their IOMMU driver, then we'll get a domain back from
>> iommu_get_domain_for_dev() and just use that.
>
> What is the plan for getting an iommu-groups implementation for the
> platform bus?

The realistic options are trying to handle it with logic in the drivers 
(engenders code duplication, has potentially unsolvable ordering issues) 
or defining groups statically in DT via a new binding (needs to avoid 
being too much of a Linux-specific implementation detail). I tried 
prototyping the former ages ago and it got overcomplicated very quickly. 
Having considered the static DT method more recently, I've sketched out 
some ideas for a binding and a rough design for the code, but nothing's 
actually written yet. It is another of the "make stuff work on arm64" 
balls I have in the air, though, if only because the USB SMMU on Juno is 
otherwise unusable (well, unless you hack out one or other of the 
EHCI/OHCI pair).

Robin.



From sergei.shtylyov at cogentembedded.com  Tue Aug 11 13:16:31 2015
From: sergei.shtylyov at cogentembedded.com (Sergei Shtylyov)
Date: Tue, 11 Aug 2015 23:16:31 +0300
Subject: [PATCH v2 1/2] ARM: shmobile: r8a7794: add QSPI DT support
In-Reply-To: <CAMuHMdVG3R3ThQWPM-tDHTcJZfFB+j3cFhdBNoH4=ZN7ENrXRg@mail.gmail.com>
References: <4187771.Fb49GBKgyg@wasted.cogentembedded.com>
 <1540672.y3DTbtssP8@wasted.cogentembedded.com>
 <CAMuHMdVG3R3ThQWPM-tDHTcJZfFB+j3cFhdBNoH4=ZN7ENrXRg@mail.gmail.com>
Message-ID: <55CA581F.60407@cogentembedded.com>

Hello.

On 08/11/2015 09:58 AM, Geert Uytterhoeven wrote:

>> Define the generic R8A7794 part of the QSPI device node.
>>
>> Based on original patch by Hisashi Nakamura <hisashi.nakamura.ak at renesas.com>.
>>
>> Signed-off-by: Sergei Shtylyov <sergei.shtylyov at cogentembedded.com>
>
> Acked-by: Geert Uytterhoeven <geert+renesas at glider.be>

    Sorry, forgot to add your ACK when re-posting. Thank you!

> Gr{oetje,eeting}s,
>
>                          Geert

MBR, Sergei



From nico at fluxnic.net  Tue Aug 11 13:20:05 2015
From: nico at fluxnic.net (Nicolas Pitre)
Date: Tue, 11 Aug 2015 16:20:05 -0400 (EDT)
Subject: arm kernel oops in highmem.c with 4.2
In-Reply-To: <20150811195638.GC7557@n2100.arm.linux.org.uk>
References: <CALeDE9Ox3=sh3AXQ0NUG6BBfU5i5YrMY=LDpcTHQWqz2=60F2g@mail.gmail.com>
 <20150805100701.GV7557@n2100.arm.linux.org.uk>
 <CALeDE9PXF=gQCaBCiHpHy2nXOooQOmsCQvSgOv+wQw3mta=P6A@mail.gmail.com>
 <20150805112713.GY7557@n2100.arm.linux.org.uk>
 <1439315290.3153.11.camel@redhat.com>
 <20150811181008.GA7557@n2100.arm.linux.org.uk>
 <alpine.LFD.2.20.1508111501130.1515@knanqh.ubzr>
 <20150811195638.GC7557@n2100.arm.linux.org.uk>
Message-ID: <alpine.LFD.2.20.1508111558210.1515@knanqh.ubzr>

On Tue, 11 Aug 2015, Russell King - ARM Linux wrote:

> On Tue, Aug 11, 2015 at 03:41:52PM -0400, Nicolas Pitre wrote:
> > I'd agree.  But first I'd like to know why the fedora kernel is using 
> > CONFIG_UACCESS_WITH_MEMCPY?  If it's just because it sounded cool then 
> > that's a bad reason.
> > 
> > That code was created to work around inneficiency in the Orion CPU core 
> > that didn't coalesce writes from STRT instructions, and by using plain 
> > STR and/or STM the actual throughput was more than doubled.  This was 
> > fixed in later cores. However Orion users (if they still exist) might 
> > like the added performance. I don't have Orion-based targets anymore 
> > (they took the way of the recycling facility a while ago).
> 
> Irrespective of that, what has been found is that the implementation is
> unsafe - it is taking a semaphore when page faults are disabled.  In
> other words, notwithstanding the above, it's buggy no matter if it's
> an Orion CPU core, or highmem, or what.  Any place in the kernel which
> uses pagefault_disable() and then calls into this code will be buggy.
> 
> It needs fixing or removing.

Absolutely. I'm not disputing that. I'm only asking so we can wisely 
choose between fixing or removing.  Personally I'd be inclined towards 
the later, unless the following is sufficient to fix it:

diff --git a/arch/arm/lib/uaccess_with_memcpy.c b/arch/arm/lib/uaccess_with_memcpy.c
index 3e58d71001..4b39af2dfd 100644
--- a/arch/arm/lib/uaccess_with_memcpy.c
+++ b/arch/arm/lib/uaccess_with_memcpy.c
@@ -96,7 +96,7 @@ __copy_to_user_memcpy(void __user *to, const void *from, unsigned long n)
 	}
 
 	/* the mmap semaphore is taken only if not in an atomic context */
-	atomic = in_atomic();
+	atomic = faulthandler_disabled();
 
 	if (!atomic)
 		down_read(&current->mm->mmap_sem);

> Even if it is fixed, making it _depend_ on CPU_FEROCEON sounds like a
> good idea if non-orion stuff isn't supposed to be enabling it.  Or
> something like that.

It is not clear to me exactly which cores are affected.  That's why the 
Kconfig entry was left open to all, in case it could benefit others.
In theory it shouldn't be harmful to anyone notwithstanding the caveat
mentioned in the help text.


Nicolas


From bhelgaas at google.com  Tue Aug 11 13:20:27 2015
From: bhelgaas at google.com (Bjorn Helgaas)
Date: Tue, 11 Aug 2015 15:20:27 -0500
Subject: [PATCH v3] PCI: kill off set_irq_flags usage
In-Reply-To: <1438030523-15853-9-git-send-email-robh@kernel.org>
References: <1438030523-15853-1-git-send-email-robh@kernel.org>
 <1438030523-15853-9-git-send-email-robh@kernel.org>
Message-ID: <20150811202027.GG13982@google.com>

On Mon, Jul 27, 2015 at 03:55:21PM -0500, Rob Herring wrote:
> set_irq_flags is ARM specific with custom flags which have genirq
> equivalents. Convert drivers to use the genirq interfaces directly, so we
> can kill off set_irq_flags. The translation of flags is as follows:
> 
> IRQF_VALID -> !IRQ_NOREQUEST
> IRQF_PROBE -> !IRQ_NOPROBE
> IRQF_NOAUTOEN -> IRQ_NOAUTOEN
> 
> For IRQs managed by an irqdomain, the irqdomain core code handles clearing
> and setting IRQ_NOREQUEST already, so there is no need to do this in
> .map() functions and we can simply remove the set_irq_flags calls. Some
> users also modify IRQ_NOPROBE and this has been maintained although it
> is not clear that is really needed. There appears to be a great deal of
> blind copy and paste of this code.
> 
> Signed-off-by: Rob Herring <robh at kernel.org>
> Cc: Kishon Vijay Abraham I <kishon at ti.com>
> Acked-by: Bjorn Helgaas <bhelgaas at google.com>
> Cc: Murali Karicheri <m-karicheri2 at ti.com>
> Cc: Thierry Reding <thierry.reding at gmail.com>
> Cc: Stephen Warren <swarren at wwwdotorg.org>
> Cc: Alexandre Courbot <gnurou at gmail.com>
> Cc: Jingoo Han <jingoohan1 at gmail.com>
> Cc: Pratyush Anand <pratyush.anand at gmail.com>
> Cc: Simon Horman <horms at verge.net.au>
> Cc: Michal Simek <michal.simek at xilinx.com>
> Cc: "S?ren Brinkmann" <soren.brinkmann at xilinx.com>
> Cc: linux-omap at vger.kernel.org
> Cc: linux-pci at vger.kernel.org
> Cc: linux-arm-kernel at lists.infradead.org
> Cc: linux-tegra at vger.kernel.org
> Cc: linux-sh at vger.kernel.org
> ---
> Thomas asked that this be merged thru subsystem trees instead of arm-soc,
> so please apply this to your tree.

Applied with Jingoo's ack to pci/irq for v4.3, thanks!

>  drivers/pci/host/pci-dra7xx.c      | 1 -
>  drivers/pci/host/pci-keystone-dw.c | 2 --
>  drivers/pci/host/pci-tegra.c       | 1 -
>  drivers/pci/host/pci-xgene-msi.c   | 1 -
>  drivers/pci/host/pcie-designware.c | 1 -
>  drivers/pci/host/pcie-rcar.c       | 1 -
>  drivers/pci/host/pcie-xilinx.c     | 2 --
>  7 files changed, 9 deletions(-)
> 
> diff --git a/drivers/pci/host/pci-dra7xx.c b/drivers/pci/host/pci-dra7xx.c
> index 80db09e..1a0d124 100644
> --- a/drivers/pci/host/pci-dra7xx.c
> +++ b/drivers/pci/host/pci-dra7xx.c
> @@ -155,7 +155,6 @@ static int dra7xx_pcie_intx_map(struct irq_domain *domain, unsigned int irq,
>  {
>  	irq_set_chip_and_handler(irq, &dummy_irq_chip, handle_simple_irq);
>  	irq_set_chip_data(irq, domain->host_data);
> -	set_irq_flags(irq, IRQF_VALID);
> 
>  	return 0;
>  }
> diff --git a/drivers/pci/host/pci-keystone-dw.c b/drivers/pci/host/pci-keystone-dw.c
> index f34892e..f1d0749 100644
> --- a/drivers/pci/host/pci-keystone-dw.c
> +++ b/drivers/pci/host/pci-keystone-dw.c
> @@ -196,7 +196,6 @@ static int ks_dw_pcie_msi_map(struct irq_domain *domain, unsigned int irq,
>  	irq_set_chip_and_handler(irq, &ks_dw_pcie_msi_irq_chip,
>  				 handle_level_irq);
>  	irq_set_chip_data(irq, domain->host_data);
> -	set_irq_flags(irq, IRQF_VALID);
> 
>  	return 0;
>  }
> @@ -277,7 +276,6 @@ static int ks_dw_pcie_init_legacy_irq_map(struct irq_domain *d,
>  	irq_set_chip_and_handler(irq, &ks_dw_pcie_legacy_irq_chip,
>  				 handle_level_irq);
>  	irq_set_chip_data(irq, d->host_data);
> -	set_irq_flags(irq, IRQF_VALID);
> 
>  	return 0;
>  }
> diff --git a/drivers/pci/host/pci-tegra.c b/drivers/pci/host/pci-tegra.c
> index 10c0571..81df0c1 100644
> --- a/drivers/pci/host/pci-tegra.c
> +++ b/drivers/pci/host/pci-tegra.c
> @@ -1248,7 +1248,6 @@ static int tegra_msi_map(struct irq_domain *domain, unsigned int irq,
>  {
>  	irq_set_chip_and_handler(irq, &tegra_msi_irq_chip, handle_simple_irq);
>  	irq_set_chip_data(irq, domain->host_data);
> -	set_irq_flags(irq, IRQF_VALID);
> 
>  	tegra_cpuidle_pcie_irqs_in_use();
> 
> diff --git a/drivers/pci/host/pci-xgene-msi.c b/drivers/pci/host/pci-xgene-msi.c
> index 2d31d4d..8e559d1 100644
> --- a/drivers/pci/host/pci-xgene-msi.c
> +++ b/drivers/pci/host/pci-xgene-msi.c
> @@ -223,7 +223,6 @@ static int xgene_irq_domain_alloc(struct irq_domain *domain, unsigned int virq,
>  	irq_domain_set_info(domain, virq, msi_irq,
>  			    &xgene_msi_bottom_irq_chip, domain->host_data,
>  			    handle_simple_irq, NULL, NULL);
> -	set_irq_flags(virq, IRQF_VALID);
> 
>  	return 0;
>  }
> diff --git a/drivers/pci/host/pcie-designware.c b/drivers/pci/host/pcie-designware.c
> index 69486be..5c6b562 100644
> --- a/drivers/pci/host/pcie-designware.c
> +++ b/drivers/pci/host/pcie-designware.c
> @@ -350,7 +350,6 @@ static int dw_pcie_msi_map(struct irq_domain *domain, unsigned int irq,
>  {
>  	irq_set_chip_and_handler(irq, &dw_msi_irq_chip, handle_simple_irq);
>  	irq_set_chip_data(irq, domain->host_data);
> -	set_irq_flags(irq, IRQF_VALID);
> 
>  	return 0;
>  }
> diff --git a/drivers/pci/host/pcie-rcar.c b/drivers/pci/host/pcie-rcar.c
> index c086210..7678fe0 100644
> --- a/drivers/pci/host/pcie-rcar.c
> +++ b/drivers/pci/host/pcie-rcar.c
> @@ -664,7 +664,6 @@ static int rcar_msi_map(struct irq_domain *domain, unsigned int irq,
>  {
>  	irq_set_chip_and_handler(irq, &rcar_msi_irq_chip, handle_simple_irq);
>  	irq_set_chip_data(irq, domain->host_data);
> -	set_irq_flags(irq, IRQF_VALID);
> 
>  	return 0;
>  }
> diff --git a/drivers/pci/host/pcie-xilinx.c b/drivers/pci/host/pcie-xilinx.c
> index f1a06a0..72015119 100644
> --- a/drivers/pci/host/pcie-xilinx.c
> +++ b/drivers/pci/host/pcie-xilinx.c
> @@ -338,7 +338,6 @@ static int xilinx_pcie_msi_map(struct irq_domain *domain, unsigned int irq,
>  {
>  	irq_set_chip_and_handler(irq, &xilinx_msi_irq_chip, handle_simple_irq);
>  	irq_set_chip_data(irq, domain->host_data);
> -	set_irq_flags(irq, IRQF_VALID);
> 
>  	return 0;
>  }
> @@ -377,7 +376,6 @@ static int xilinx_pcie_intx_map(struct irq_domain *domain, unsigned int irq,
>  {
>  	irq_set_chip_and_handler(irq, &dummy_irq_chip, handle_simple_irq);
>  	irq_set_chip_data(irq, domain->host_data);
> -	set_irq_flags(irq, IRQF_VALID);
> 
>  	return 0;
>  }
> --
> 2.1.0
> 


From robert.jarzmik at free.fr  Tue Aug 11 13:16:32 2015
From: robert.jarzmik at free.fr (Robert Jarzmik)
Date: Tue, 11 Aug 2015 22:16:32 +0200
Subject: [PATCH] dma: pxa_dma: don't use config direction parameter
Message-ID: <1439324192-9148-1-git-send-email-robert.jarzmik@free.fr>

From: Robert Jarzmik <rj at valbob.noip.me>

Don't use the direction passed in the configuration, and rely on each
transfer's direction to prepare the transfers. This will enable
future removal of direction parameter from dma_slave_config.

Signed-off-by: Robert Jarzmik <robert.jarzmik at free.fr>
---
 drivers/dma/pxa_dma.c | 6 +++---
 1 file changed, 3 insertions(+), 3 deletions(-)

diff --git a/drivers/dma/pxa_dma.c b/drivers/dma/pxa_dma.c
index be5b5248b7b6..5cb61ce01036 100644
--- a/drivers/dma/pxa_dma.c
+++ b/drivers/dma/pxa_dma.c
@@ -905,21 +905,21 @@ static void pxad_get_config(struct pxad_chan *chan,
 	enum dma_slave_buswidth width = DMA_SLAVE_BUSWIDTH_UNDEFINED;
 
 	*dcmd = 0;
-	if (chan->cfg.direction == DMA_DEV_TO_MEM) {
+	if (dir == DMA_DEV_TO_MEM) {
 		maxburst = chan->cfg.src_maxburst;
 		width = chan->cfg.src_addr_width;
 		dev_addr = chan->cfg.src_addr;
 		*dev_src = dev_addr;
 		*dcmd |= PXA_DCMD_INCTRGADDR | PXA_DCMD_FLOWSRC;
 	}
-	if (chan->cfg.direction == DMA_MEM_TO_DEV) {
+	if (dir == DMA_MEM_TO_DEV) {
 		maxburst = chan->cfg.dst_maxburst;
 		width = chan->cfg.dst_addr_width;
 		dev_addr = chan->cfg.dst_addr;
 		*dev_dst = dev_addr;
 		*dcmd |= PXA_DCMD_INCSRCADDR | PXA_DCMD_FLOWTRG;
 	}
-	if (chan->cfg.direction == DMA_MEM_TO_MEM)
+	if (dir == DMA_MEM_TO_MEM)
 		*dcmd |= PXA_DCMD_BURST32 | PXA_DCMD_INCTRGADDR |
 			PXA_DCMD_INCSRCADDR;
 
-- 
2.1.4



From mturquette at baylibre.com  Tue Aug 11 13:41:27 2015
From: mturquette at baylibre.com (Michael Turquette)
Date: Tue, 11 Aug 2015 13:41:27 -0700
Subject: [PATCH 1/2] clk: add lpc18xx creg clk driver
In-Reply-To: <1436651307-24098-2-git-send-email-manabian@gmail.com>
References: <1436651307-24098-1-git-send-email-manabian@gmail.com>
 <1436651307-24098-2-git-send-email-manabian@gmail.com>
Message-ID: <20150811204127.31346.16729@quantum>

Hi Joachim,

Quoting Joachim Eastwood (2015-07-11 14:48:26)
> +static void __init lpc18xx_creg_clk_init(struct device_node *np)
> +{
> +       const char *clk_32khz_parent;
> +       struct regmap *syscon;
> +
> +       syscon = syscon_node_to_regmap(np->parent);
> +       if (IS_ERR(syscon)) {
> +               pr_err("%s: syscon lookup failed\n", __func__);
> +               return;
> +       }
> +
> +       clk_32khz_parent = of_clk_get_parent_name(np, 0);
> +
> +       clk_creg[CREG_CLK_32KHZ] =
> +               clk_register_creg_clk(&clk_creg_clocks[CREG_CLK_32KHZ],
> +                                     &clk_32khz_parent, syscon);
> +
> +       clk_creg[CREG_CLK_1KHZ] =
> +               clk_register_creg_clk(&clk_creg_clocks[CREG_CLK_1KHZ],
> +                                     &clk_creg_clocks[CREG_CLK_32KHZ].name,
> +                                     syscon);
> +
> +       of_clk_add_provider(np, of_clk_src_onecell_get, &clk_base_data);
> +}
> +CLK_OF_DECLARE(lpc18xx_creg_clk, "nxp,lpc1850-creg-clk", lpc18xx_creg_clk_init);

I'll ask the same question that Stephen asked in your CCU/CGU driver
series: is it necessary to use CLK_OF_DECLARE here or can you use the
platform device model?

Thanks,
Mike


From lho at apm.com  Tue Aug 11 13:47:53 2015
From: lho at apm.com (Loc Ho)
Date: Tue, 11 Aug 2015 14:47:53 -0600
Subject: [PATCH v3 0/4] edac: Add L3/SoC support to the APM X-Gene SoC EDAC
 driver
Message-ID: <1439326077-25507-1-git-send-email-lho@apm.com>

v3:
* Add an function to retrieve the EDAC debugfs node
* Move all debugfs node under EDAC code debugfs node
* Update L3 to check for v1 errata
* Rename error label for L3/SoC add routines
* Re-structure SoC EDAC functions for code readability
* Inline the function xgene_edac_soc_mem_data
* Remove un-necessary { }

v2:
* Update binding documentation accordingly
* Change all single bit defines to BIT(x)
* Add support for L3 version 1 and 2 HW's
* Change to use debug file system for error injection
* In L3/SoC instance add function, allocate EDAC context after all
  initalization successed
* Support raw or detail info for SoC EDAC error reporting

v1:
* Add L3/SoC support to the APM X-Gene SoC EDAC driver
---
Loc Ho (4):
  edac: Add an function to retrieve the EDAC debugfs node
  Documentation: Update the APM X-Gene SoC EDAC DTS binding for L3/SoC
    subnodes
  edac: Add L3/SoC EDAC support to the APM X-Gene SoC EDAC driver
  arm64: Add L3/SoC DT subnodes to the APM X-Gene SoC EDAC node

 .../devicetree/bindings/edac/apm-xgene-edac.txt    |   23 +
 arch/arm64/boot/dts/apm/apm-storm.dtsi             |   10 +
 drivers/edac/edac_core.h                           |    1 +
 drivers/edac/edac_mc_sysfs.c                       |   10 +
 drivers/edac/xgene_edac.c                          |  827 +++++++++++++++++++-
 5 files changed, 859 insertions(+), 12 deletions(-)



From lho at apm.com  Tue Aug 11 13:47:54 2015
From: lho at apm.com (Loc Ho)
Date: Tue, 11 Aug 2015 14:47:54 -0600
Subject: [PATCH v3 1/4] edac: Add an function to retrieve the EDAC debugfs node
In-Reply-To: <1439326077-25507-1-git-send-email-lho@apm.com>
References: <1439326077-25507-1-git-send-email-lho@apm.com>
Message-ID: <1439326077-25507-2-git-send-email-lho@apm.com>

This patch adds an function to retrieve the EDAC debugfs node. This allows
EDAC driver to create debugfs node under the EDAC debugfs node.

Signed-off-by: Loc Ho <lho at apm.com>
---
 drivers/edac/edac_core.h     |    1 +
 drivers/edac/edac_mc_sysfs.c |   10 ++++++++++
 2 files changed, 11 insertions(+), 0 deletions(-)

diff --git a/drivers/edac/edac_core.h b/drivers/edac/edac_core.h
index ad42587..6771e64 100644
--- a/drivers/edac/edac_core.h
+++ b/drivers/edac/edac_core.h
@@ -511,5 +511,6 @@ extern void edac_pci_remove_sysfs(struct edac_pci_ctl_info *pci);
  * edac misc APIs
  */
 extern char *edac_op_state_to_string(int op_state);
+extern struct dentry *edac_get_debugfs(void);
 
 #endif				/* _EDAC_CORE_H_ */
diff --git a/drivers/edac/edac_mc_sysfs.c b/drivers/edac/edac_mc_sysfs.c
index 33df7d9..b76afe0 100644
--- a/drivers/edac/edac_mc_sysfs.c
+++ b/drivers/edac/edac_mc_sysfs.c
@@ -959,6 +959,16 @@ nomem:
 	debugfs_remove(mci->debugfs);
 	return -ENOMEM;
 }
+
+struct dentry *edac_get_debugfs(void)
+{
+	return edac_debugfs;
+}
+#else
+struct dentry *edac_get_debugfs(void)
+{
+	return NULL;
+}
 #endif
 
 /*
-- 
1.7.1



From lho at apm.com  Tue Aug 11 13:47:55 2015
From: lho at apm.com (Loc Ho)
Date: Tue, 11 Aug 2015 14:47:55 -0600
Subject: [PATCH v3 2/4] Documentation: Update the APM X-Gene SoC EDAC DTS
 binding for L3/SoC subnodes
In-Reply-To: <1439326077-25507-2-git-send-email-lho@apm.com>
References: <1439326077-25507-1-git-send-email-lho@apm.com>
 <1439326077-25507-2-git-send-email-lho@apm.com>
Message-ID: <1439326077-25507-3-git-send-email-lho@apm.com>

This patch updates documentation for the APM X-Gene SoC EDAC DTS binding
for L3/SoC subnodes.

Signed-off-by: Loc Ho <lho at apm.com>
---
 .../devicetree/bindings/edac/apm-xgene-edac.txt    |   23 ++++++++++++++++++++
 1 files changed, 23 insertions(+), 0 deletions(-)

diff --git a/Documentation/devicetree/bindings/edac/apm-xgene-edac.txt b/Documentation/devicetree/bindings/edac/apm-xgene-edac.txt
index 78edb80..78e2a31 100644
--- a/Documentation/devicetree/bindings/edac/apm-xgene-edac.txt
+++ b/Documentation/devicetree/bindings/edac/apm-xgene-edac.txt
@@ -5,6 +5,8 @@ The follow error types are supported:
 
   memory controller	- Memory controller
   PMD (L1/L2)		- Processor module unit (PMD) L1/L2 cache
+  L3			- L3 cache controller
+  SoC			- SoC IP's such as Ethernet, SATA, and etc
 
 The following section describes the EDAC DT node binding.
 
@@ -30,6 +32,17 @@ Required properties for PMD subnode:
 - reg			: First resource shall be the PMD resource.
 - pmd-controller	: Instance number of the PMD controller.
 
+Required properties for L3 subnode:
+- compatible		: Shall be "apm,xgene-edac-l3" or
+                          "apm,xgene-edac-l3-v2".
+- reg			: First resource shall be the L3 EDAC resource.
+
+Required properties for SoC subnode:
+- compatible		: Shall be "apm,xgene-edac-soc-v1" for revision 1 or
+                          "apm,xgene-edac-l3-soc" for general value reporting
+                          only.
+- reg			: First resource shall be the SoC EDAC resource.
+
 Example:
 	csw: csw at 7e200000 {
 		compatible = "apm,xgene-csw", "syscon";
@@ -76,4 +89,14 @@ Example:
 			reg = <0x0 0x7c000000 0x0 0x200000>;
 			pmd-controller = <0>;
 		};
+
+		edacl3 at 7e600000 {
+			compatible = "apm,xgene-edac-l3";
+			reg = <0x0 0x7e600000 0x0 0x1000>;
+		};
+
+		edacsoc at 7e930000 {
+			compatible = "apm,xgene-edac-soc-v1";
+			reg = <0x0 0x7e930000 0x0 0x1000>;
+		};
 	};
-- 
1.7.1



From lho at apm.com  Tue Aug 11 13:47:56 2015
From: lho at apm.com (Loc Ho)
Date: Tue, 11 Aug 2015 14:47:56 -0600
Subject: [PATCH v3 3/4] edac: Add L3/SoC EDAC support to the APM X-Gene SoC
 EDAC driver
In-Reply-To: <1439326077-25507-3-git-send-email-lho@apm.com>
References: <1439326077-25507-1-git-send-email-lho@apm.com>
 <1439326077-25507-2-git-send-email-lho@apm.com>
 <1439326077-25507-3-git-send-email-lho@apm.com>
Message-ID: <1439326077-25507-4-git-send-email-lho@apm.com>

This patch adds EDAC support for the L3 and SoC components.

Signed-off-by: Loc Ho <lho at apm.com>
---
 drivers/edac/xgene_edac.c |  827 ++++++++++++++++++++++++++++++++++++++++++++-
 1 files changed, 815 insertions(+), 12 deletions(-)

diff --git a/drivers/edac/xgene_edac.c b/drivers/edac/xgene_edac.c
index ba06904..d5e33bf 100644
--- a/drivers/edac/xgene_edac.c
+++ b/drivers/edac/xgene_edac.c
@@ -66,6 +66,8 @@ struct xgene_edac {
 
 	struct list_head	mcus;
 	struct list_head	pmds;
+	struct list_head	l3s;
+	struct list_head	socs;
 
 	struct mutex		mc_lock;
 	int			mc_active_mask;
@@ -877,8 +879,8 @@ static const struct file_operations xgene_edac_pmd_debug_inject_fops[] = {
 	{ }
 };
 
-static void xgene_edac_pmd_create_debugfs_nodes(
-	struct edac_device_ctl_info *edac_dev)
+static void
+xgene_edac_pmd_create_debugfs_nodes(struct edac_device_ctl_info *edac_dev)
 {
 	struct xgene_edac_pmd_ctx *ctx = edac_dev->pvt_info;
 	struct dentry *edac_debugfs;
@@ -887,10 +889,6 @@ static void xgene_edac_pmd_create_debugfs_nodes(
 	if (!IS_ENABLED(CONFIG_EDAC_DEBUG))
 		return;
 
-	/*
-	 * Todo: Switch to common EDAC debug file system for edac device
-	 *       when available.
-	 */
 	if (!ctx->edac->dfs) {
 		ctx->edac->dfs = debugfs_create_dir(edac_dev->dev->kobj.name,
 						    NULL);
@@ -1016,10 +1014,791 @@ static int xgene_edac_pmd_remove(struct xgene_edac_pmd_ctx *pmd)
 	return 0;
 }
 
+/* L3 Error device */
+#define L3C_ESR				(0x0A * 4)
+#define  L3C_ESR_DATATAG_MASK		BIT(9)
+#define  L3C_ESR_MULTIHIT_MASK		BIT(8)
+#define  L3C_ESR_UCEVICT_MASK		BIT(6)
+#define  L3C_ESR_MULTIUCERR_MASK	BIT(5)
+#define  L3C_ESR_MULTICERR_MASK		BIT(4)
+#define  L3C_ESR_UCERR_MASK		BIT(3)
+#define  L3C_ESR_CERR_MASK		BIT(2)
+#define  L3C_ESR_UCERRINTR_MASK		BIT(1)
+#define  L3C_ESR_CERRINTR_MASK		BIT(0)
+#define L3C_ECR				(0x0B * 4)
+#define  L3C_ECR_UCINTREN		BIT(3)
+#define  L3C_ECR_CINTREN		BIT(2)
+#define  L3C_UCERREN			BIT(1)
+#define  L3C_CERREN			BIT(0)
+#define L3C_ELR				(0x0C * 4)
+#define  L3C_ELR_ERRSYN(src)		((src & 0xFF800000) >> 23)
+#define  L3C_ELR_ERRWAY(src)		((src & 0x007E0000) >> 17)
+#define  L3C_ELR_AGENTID(src)		((src & 0x0001E000) >> 13)
+#define  L3C_ELR_ERRGRP(src)		((src & 0x00000F00) >> 8)
+#define  L3C_ELR_OPTYPE(src)		((src & 0x000000F0) >> 4)
+#define  L3C_ELR_PADDRHIGH(src)		(src & 0x0000000F)
+#define L3C_AELR			(0x0D * 4)
+#define L3C_BELR			(0x0E * 4)
+#define  L3C_BELR_BANK(src)		(src & 0x0000000F)
+
+struct xgene_edac_dev_ctx {
+	struct list_head	next;
+	struct device		ddev;
+	char			*name;
+	struct xgene_edac	*edac;
+	struct edac_device_ctl_info *edac_dev;
+	int			edac_idx;
+	void __iomem		*dev_csr;
+	int			version;
+};
+
+static bool xgene_edac_l3_v1_errata_chk(u32 l3cesr, u32 l3celr)
+{
+	/*
+	 * L3 version 1 has certain conditions in which correctable error
+	 * needs to be flagged as un-correctable error. This function
+	 * check for such conditions.
+	 */
+	if (l3cesr & L3C_ESR_DATATAG_MASK) {
+		switch (L3C_ELR_ERRSYN(l3celr)) {
+		case 0x13C:
+		case 0x0B4:
+		case 0x007:
+		case 0x00D:
+		case 0x00E:
+		case 0x019:
+		case 0x01A:
+		case 0x01C:
+		case 0x04E:
+		case 0x041:
+			return true;
+		}
+	} else if (L3C_ELR_ERRSYN(l3celr) == 9) {
+		return true;
+	}
+
+	return false;
+}
+
+static void xgene_edac_l3_check(struct edac_device_ctl_info *edac_dev)
+{
+	struct xgene_edac_dev_ctx *ctx = edac_dev->pvt_info;
+	u32 l3cesr;
+	u32 l3celr;
+	u32 l3caelr;
+	u32 l3cbelr;
+
+	l3cesr = readl(ctx->dev_csr + L3C_ESR);
+	if (!(l3cesr & (L3C_ESR_UCERR_MASK | L3C_ESR_CERR_MASK)))
+		return;
+
+	if (l3cesr & L3C_ESR_UCERR_MASK)
+		dev_err(edac_dev->dev, "L3C uncorrectable error\n");
+	if (l3cesr & L3C_ESR_CERR_MASK)
+		dev_warn(edac_dev->dev, "L3C correctable error\n");
+
+	l3celr = readl(ctx->dev_csr + L3C_ELR);
+	l3caelr = readl(ctx->dev_csr + L3C_AELR);
+	l3cbelr = readl(ctx->dev_csr + L3C_BELR);
+	if (l3cesr & L3C_ESR_MULTIHIT_MASK)
+		dev_err(edac_dev->dev, "L3C multiple hit error\n");
+	if (l3cesr & L3C_ESR_UCEVICT_MASK)
+		dev_err(edac_dev->dev,
+			"L3C dropped eviction of line with error\n");
+	if (l3cesr & L3C_ESR_MULTIUCERR_MASK)
+		dev_err(edac_dev->dev, "L3C multiple uncorrectable error\n");
+	if (l3cesr & L3C_ESR_DATATAG_MASK)
+		dev_err(edac_dev->dev,
+			"L3C data error syndrome 0x%X group 0x%X\n",
+			L3C_ELR_ERRSYN(l3celr), L3C_ELR_ERRGRP(l3celr));
+	else
+		dev_err(edac_dev->dev,
+			"L3C tag error syndrome 0x%X Way of Tag 0x%X Agent ID 0x%X Operation type 0x%X\n",
+			L3C_ELR_ERRSYN(l3celr), L3C_ELR_ERRWAY(l3celr),
+			L3C_ELR_AGENTID(l3celr), L3C_ELR_OPTYPE(l3celr));
+	/*
+	 * NOTE: Address [41:38] in L3C_ELR_PADDRHIGH(l3celr).
+	 *       Address [37:6] in l3caelr. Lower 6 bits are zero.
+	 */
+	dev_err(edac_dev->dev, "L3C error address 0x%08X.%08X bank %d\n",
+		L3C_ELR_PADDRHIGH(l3celr) << 6 | (l3caelr >> 26),
+		(l3caelr & 0x3FFFFFFF) << 6, L3C_BELR_BANK(l3cbelr));
+	dev_err(edac_dev->dev,
+		"L3C error status register value 0x%X\n", l3cesr);
+
+	/* Clear L3C error interrupt */
+	writel(0, ctx->dev_csr + L3C_ESR);
+
+	if (ctx->version <= 1 &&
+	    xgene_edac_l3_v1_errata_chk(l3cesr, l3celr)) {
+		/*
+		 * Version 1 of the L3C has broken single bit correctable
+		 * logic for certain condition. When such condition is
+		 * detected, map them as uncorrectable.
+		 */
+		edac_device_handle_ue(edac_dev, 0, 0, edac_dev->ctl_name);
+		return;
+	}
+	if (l3cesr & L3C_ESR_CERR_MASK)
+		edac_device_handle_ce(edac_dev, 0, 0, edac_dev->ctl_name);
+	if (l3cesr & L3C_ESR_UCERR_MASK)
+		edac_device_handle_ue(edac_dev, 0, 0, edac_dev->ctl_name);
+}
+
+static void xgene_edac_l3_hw_init(struct edac_device_ctl_info *edac_dev,
+				  bool enable)
+{
+	struct xgene_edac_dev_ctx *ctx = edac_dev->pvt_info;
+	u32 val;
+
+	val = readl(ctx->dev_csr + L3C_ECR);
+	val |= L3C_UCERREN | L3C_CERREN;
+	/* On disable, we just disable interrupt but keep error enabled */
+	if (edac_dev->op_state == OP_RUNNING_INTERRUPT) {
+		if (enable)
+			val |= L3C_ECR_UCINTREN | L3C_ECR_CINTREN;
+		else
+			val &= ~(L3C_ECR_UCINTREN | L3C_ECR_CINTREN);
+	}
+	writel(val, ctx->dev_csr + L3C_ECR);
+
+	if (edac_dev->op_state == OP_RUNNING_INTERRUPT) {
+		/* Enable/disable L3 error top level interrupt */
+		if (enable) {
+			xgene_edac_pcp_clrbits(ctx->edac, PCPHPERRINTMSK,
+					       L3C_UNCORR_ERR_MASK);
+			xgene_edac_pcp_clrbits(ctx->edac, PCPLPERRINTMSK,
+					       L3C_CORR_ERR_MASK);
+		} else {
+			xgene_edac_pcp_setbits(ctx->edac, PCPHPERRINTMSK,
+					       L3C_UNCORR_ERR_MASK);
+			xgene_edac_pcp_setbits(ctx->edac, PCPLPERRINTMSK,
+					       L3C_CORR_ERR_MASK);
+		}
+	}
+}
+
+static ssize_t xgene_edac_l3_inject_ctrl_write(struct file *file,
+					       const char __user *data,
+					       size_t count, loff_t *ppos)
+{
+	struct edac_device_ctl_info *edac_dev = file->private_data;
+	struct xgene_edac_dev_ctx *ctx = edac_dev->pvt_info;
+
+	/* Generate all errors */
+	writel(0xFFFFFFFF, ctx->dev_csr + L3C_ESR);
+	return count;
+}
+
+static const struct file_operations xgene_edac_l3_debug_inject_fops = {
+	.open = simple_open,
+	.write = xgene_edac_l3_inject_ctrl_write,
+	.llseek = generic_file_llseek
+};
+
+static void xgene_edac_l3_create_debugfs_nodes(
+	struct edac_device_ctl_info *edac_dev)
+{
+	struct xgene_edac_dev_ctx *ctx = edac_dev->pvt_info;
+	struct dentry *edac_debugfs;
+	char name[30];
+
+	if (!IS_ENABLED(CONFIG_EDAC_DEBUG))
+		return;
+
+	if (!ctx->edac->dfs) {
+		ctx->edac->dfs = debugfs_create_dir(edac_dev->dev->kobj.name,
+						    NULL);
+		if (!ctx->edac->dfs)
+			return;
+	}
+	sprintf(name, "l3c%d", ctx->edac_idx);
+	edac_debugfs = debugfs_create_dir(name, ctx->edac->dfs);
+	if (!edac_debugfs)
+		return;
+
+	debugfs_create_file("l3_inject_ctrl", S_IWUSR, edac_debugfs, edac_dev,
+			    &xgene_edac_l3_debug_inject_fops);
+}
+
+static int xgene_edac_l3_add(struct xgene_edac *edac, struct device_node *np,
+			     int version)
+{
+	struct edac_device_ctl_info *edac_dev;
+	struct xgene_edac_dev_ctx *ctx;
+	struct resource res;
+	void __iomem *dev_csr;
+	int edac_idx;
+	int rc = 0;
+
+	if (!devres_open_group(edac->dev, xgene_edac_l3_add, GFP_KERNEL))
+		return -ENOMEM;
+
+	rc = of_address_to_resource(np, 0, &res);
+	if (rc < 0) {
+		dev_err(edac->dev, "no L3 resource address\n");
+		goto err_release_group;
+	}
+	dev_csr = devm_ioremap_resource(edac->dev, &res);
+	if (IS_ERR(dev_csr)) {
+		dev_err(edac->dev,
+			"devm_ioremap_resource failed for L3 resource address\n");
+		rc = PTR_ERR(dev_csr);
+		goto err_release_group;
+	}
+
+	edac_idx = edac_device_alloc_index();
+	edac_dev = edac_device_alloc_ctl_info(sizeof(*ctx),
+					      "l3c", 1, "l3c", 1, 0, NULL, 0,
+					      edac_idx);
+	if (!edac_dev) {
+		rc = -ENOMEM;
+		goto err_release_group;
+	}
+
+	ctx = edac_dev->pvt_info;
+	ctx->dev_csr = dev_csr;
+	ctx->name = "xgene_l3_err";
+	ctx->edac_idx = edac_idx;
+	ctx->edac = edac;
+	ctx->edac_dev = edac_dev;
+	ctx->ddev = *edac->dev;
+	ctx->version = version;
+	edac_dev->dev = &ctx->ddev;
+	edac_dev->ctl_name = ctx->name;
+	edac_dev->dev_name = ctx->name;
+	edac_dev->mod_name = EDAC_MOD_STR;
+
+	if (edac_op_state == EDAC_OPSTATE_POLL)
+		edac_dev->edac_check = xgene_edac_l3_check;
+
+	xgene_edac_l3_create_debugfs_nodes(edac_dev);
+
+	rc = edac_device_add_device(edac_dev);
+	if (rc > 0) {
+		dev_err(edac->dev, "failed edac_device_add_device()\n");
+		rc = -ENOMEM;
+		goto err_ctl_free;
+	}
+
+	if (edac_op_state == EDAC_OPSTATE_INT)
+		edac_dev->op_state = OP_RUNNING_INTERRUPT;
+
+	list_add(&ctx->next, &edac->l3s);
+
+	xgene_edac_l3_hw_init(edac_dev, 1);
+
+	devres_remove_group(edac->dev, xgene_edac_l3_add);
+
+	dev_info(edac->dev, "X-Gene EDAC L3 registered\n");
+	return 0;
+
+err_ctl_free:
+	edac_device_free_ctl_info(edac_dev);
+err_release_group:
+	devres_release_group(edac->dev, xgene_edac_l3_add);
+	return rc;
+}
+
+static int xgene_edac_l3_remove(struct xgene_edac_dev_ctx *l3)
+{
+	struct edac_device_ctl_info *edac_dev = l3->edac_dev;
+
+	xgene_edac_l3_hw_init(edac_dev, 0);
+	edac_device_del_device(l3->edac->dev);
+	edac_device_free_ctl_info(edac_dev);
+	return 0;
+}
+
+/* SoC Error device */
+#define IOBAXIS0TRANSERRINTSTS		0x0000
+#define  IOBAXIS0_M_ILLEGAL_ACCESS_MASK	BIT(1)
+#define  IOBAXIS0_ILLEGAL_ACCESS_MASK	BIT(0)
+#define IOBAXIS0TRANSERRINTMSK		0x0004
+#define IOBAXIS0TRANSERRREQINFOL	0x0008
+#define IOBAXIS0TRANSERRREQINFOH	0x000c
+#define  REQTYPE_RD(src)		(((src) & BIT(0)))
+#define  ERRADDRH_RD(src)		(((src) & 0xffc00000) >> 22)
+#define IOBAXIS1TRANSERRINTSTS		0x0010
+#define IOBAXIS1TRANSERRINTMSK		0x0014
+#define IOBAXIS1TRANSERRREQINFOL	0x0018
+#define IOBAXIS1TRANSERRREQINFOH	0x001c
+#define IOBPATRANSERRINTSTS		0x0020
+#define  IOBPA_M_REQIDRAM_CORRUPT_MASK	BIT(7)
+#define  IOBPA_REQIDRAM_CORRUPT_MASK	BIT(6)
+#define  IOBPA_M_TRANS_CORRUPT_MASK	BIT(5)
+#define  IOBPA_TRANS_CORRUPT_MASK	BIT(4)
+#define  IOBPA_M_WDATA_CORRUPT_MASK	BIT(3)
+#define  IOBPA_WDATA_CORRUPT_MASK	BIT(2)
+#define  IOBPA_M_RDATA_CORRUPT_MASK	BIT(1)
+#define  IOBPA_RDATA_CORRUPT_MASK	BIT(0)
+#define IOBBATRANSERRINTSTS		0x0030
+#define  M_ILLEGAL_ACCESS_MASK		BIT(15)
+#define  ILLEGAL_ACCESS_MASK		BIT(14)
+#define  M_WIDRAM_CORRUPT_MASK		BIT(13)
+#define  WIDRAM_CORRUPT_MASK		BIT(12)
+#define  M_RIDRAM_CORRUPT_MASK		BIT(11)
+#define  RIDRAM_CORRUPT_MASK		BIT(10)
+#define  M_TRANS_CORRUPT_MASK		BIT(9)
+#define  TRANS_CORRUPT_MASK		BIT(8)
+#define  M_WDATA_CORRUPT_MASK		BIT(7)
+#define  WDATA_CORRUPT_MASK		BIT(6)
+#define  M_RBM_POISONED_REQ_MASK	BIT(5)
+#define  RBM_POISONED_REQ_MASK		BIT(4)
+#define  M_XGIC_POISONED_REQ_MASK	BIT(3)
+#define  XGIC_POISONED_REQ_MASK		BIT(2)
+#define  M_WRERR_RESP_MASK		BIT(1)
+#define  WRERR_RESP_MASK		BIT(0)
+#define IOBBATRANSERRREQINFOL		0x0038
+#define IOBBATRANSERRREQINFOH		0x003c
+#define  REQTYPE_F2_RD(src)		((src) & BIT(0))
+#define  ERRADDRH_F2_RD(src)		(((src) & 0xffc00000) >> 22)
+#define IOBBATRANSERRCSWREQID		0x0040
+#define XGICTRANSERRINTSTS		0x0050
+#define  M_WR_ACCESS_ERR_MASK		BIT(3)
+#define  WR_ACCESS_ERR_MASK		BIT(2)
+#define  M_RD_ACCESS_ERR_MASK		BIT(1)
+#define  RD_ACCESS_ERR_MASK		BIT(0)
+#define XGICTRANSERRINTMSK		0x0054
+#define XGICTRANSERRREQINFO		0x0058
+#define  REQTYPE_MASK			BIT(26)
+#define  ERRADDR_RD(src)		((src) & 0x03ffffff)
+#define GLBL_ERR_STS			0x0800
+#define  MDED_ERR_MASK			BIT(3)
+#define  DED_ERR_MASK			BIT(2)
+#define  MSEC_ERR_MASK			BIT(1)
+#define  SEC_ERR_MASK			BIT(0)
+#define GLBL_SEC_ERRL			0x0810
+#define GLBL_SEC_ERRH			0x0818
+#define GLBL_MSEC_ERRL			0x0820
+#define GLBL_MSEC_ERRH			0x0828
+#define GLBL_DED_ERRL			0x0830
+#define GLBL_DED_ERRLMASK		0x0834
+#define GLBL_DED_ERRH			0x0838
+#define GLBL_DED_ERRHMASK		0x083c
+#define GLBL_MDED_ERRL			0x0840
+#define GLBL_MDED_ERRLMASK		0x0844
+#define GLBL_MDED_ERRH			0x0848
+#define GLBL_MDED_ERRHMASK		0x084c
+
+static const char * const soc_mem_err_v1[] = {
+	"10GbE0",
+	"10GbE1",
+	"Security",
+	"SATA45",
+	"SATA23/ETH23",
+	"SATA01/ETH01",
+	"USB1",
+	"USB0",
+	"QML",
+	"QM0",
+	"QM1 (XGbE01)",
+	"PCIE4",
+	"PCIE3",
+	"PCIE2",
+	"PCIE1",
+	"PCIE0",
+	"CTX Manager",
+	"OCM",
+	"1GbE",
+	"CLE",
+	"AHBC",
+	"PktDMA",
+	"GFC",
+	"MSLIM",
+	"10GbE2",
+	"10GbE3",
+	"QM2 (XGbE23)",
+	"IOB",
+	"unknown",
+	"unknown",
+	"unknown",
+	"unknown",
+};
+
+static void xgene_edac_iob_gic_report(struct edac_device_ctl_info *edac_dev)
+{
+	struct xgene_edac_dev_ctx *ctx = edac_dev->pvt_info;
+	u32 err_addr_lo;
+	u32 err_addr_hi;
+	u32 reg;
+	u32 info;
+
+	/* GIC transaction error interrupt */
+	reg = readl(ctx->dev_csr + XGICTRANSERRINTSTS);
+	if (!reg)
+		goto chk_iob_err;
+	dev_err(edac_dev->dev, "XGIC transaction error\n");
+	if (reg & RD_ACCESS_ERR_MASK)
+		dev_err(edac_dev->dev, "XGIC read size error\n");
+	if (reg & M_RD_ACCESS_ERR_MASK)
+		dev_err(edac_dev->dev, "Multiple XGIC read size error\n");
+	if (reg & WR_ACCESS_ERR_MASK)
+		dev_err(edac_dev->dev, "XGIC write size error\n");
+	if (reg & M_WR_ACCESS_ERR_MASK)
+		dev_err(edac_dev->dev, "Multiple XGIC write size error\n");
+	info = readl(ctx->dev_csr + XGICTRANSERRREQINFO);
+	dev_err(edac_dev->dev, "XGIC %s access @ 0x%08X (0x%08X)\n",
+		info & REQTYPE_MASK ? "read" : "write", ERRADDR_RD(info),
+		info);
+	writel(reg, ctx->dev_csr + XGICTRANSERRINTSTS);
+
+chk_iob_err:
+	/* IOB memory error */
+	reg = readl(ctx->dev_csr + GLBL_ERR_STS);
+	if (!reg)
+		return;
+	if (reg & SEC_ERR_MASK) {
+		err_addr_lo = readl(ctx->dev_csr + GLBL_SEC_ERRL);
+		err_addr_hi = readl(ctx->dev_csr + GLBL_SEC_ERRH);
+		dev_err(edac_dev->dev,
+			"IOB single-bit correctable memory at 0x%08X.%08X error\n",
+			err_addr_lo, err_addr_hi);
+		writel(err_addr_lo, ctx->dev_csr + GLBL_SEC_ERRL);
+		writel(err_addr_hi, ctx->dev_csr + GLBL_SEC_ERRH);
+	}
+	if (reg & MSEC_ERR_MASK) {
+		err_addr_lo = readl(ctx->dev_csr + GLBL_MSEC_ERRL);
+		err_addr_hi = readl(ctx->dev_csr + GLBL_MSEC_ERRH);
+		dev_err(edac_dev->dev,
+			"IOB multiple single-bit correctable memory at 0x%08X.%08X error\n",
+			err_addr_lo, err_addr_hi);
+		writel(err_addr_lo, ctx->dev_csr + GLBL_MSEC_ERRL);
+		writel(err_addr_hi, ctx->dev_csr + GLBL_MSEC_ERRH);
+	}
+	if (reg & (SEC_ERR_MASK | MSEC_ERR_MASK))
+		edac_device_handle_ce(edac_dev, 0, 0, edac_dev->ctl_name);
+
+	if (reg & DED_ERR_MASK) {
+		err_addr_lo = readl(ctx->dev_csr + GLBL_DED_ERRL);
+		err_addr_hi = readl(ctx->dev_csr + GLBL_DED_ERRH);
+		dev_err(edac_dev->dev,
+			"IOB double-bit uncorrectable memory at 0x%08X.%08X error\n",
+			err_addr_lo, err_addr_hi);
+		writel(err_addr_lo, ctx->dev_csr + GLBL_DED_ERRL);
+		writel(err_addr_hi, ctx->dev_csr + GLBL_DED_ERRH);
+	}
+	if (reg & MDED_ERR_MASK) {
+		err_addr_lo = readl(ctx->dev_csr + GLBL_MDED_ERRL);
+		err_addr_hi = readl(ctx->dev_csr + GLBL_MDED_ERRH);
+		dev_err(edac_dev->dev,
+			"Multiple IOB double-bit uncorrectable memory at 0x%08X.%08X error\n",
+			err_addr_lo, err_addr_hi);
+		writel(err_addr_lo, ctx->dev_csr + GLBL_MDED_ERRL);
+		writel(err_addr_hi, ctx->dev_csr + GLBL_MDED_ERRH);
+	}
+	if (reg & (DED_ERR_MASK | MDED_ERR_MASK))
+		edac_device_handle_ue(edac_dev, 0, 0, edac_dev->ctl_name);
+}
+
+static void xgene_edac_rb_report(struct edac_device_ctl_info *edac_dev)
+{
+	struct xgene_edac_dev_ctx *ctx = edac_dev->pvt_info;
+	u32 err_addr_lo;
+	u32 err_addr_hi;
+	u32 reg;
+
+	/* IOB Bridge agent transaction error interrupt */
+	reg = readl(ctx->dev_csr + IOBBATRANSERRINTSTS);
+	if (!reg)
+		return;
+
+	dev_err(edac_dev->dev, "IOB bridge agent (BA) transaction error\n");
+	if (reg & WRERR_RESP_MASK)
+		dev_err(edac_dev->dev, "IOB BA write response error\n");
+	if (reg & M_WRERR_RESP_MASK)
+		dev_err(edac_dev->dev,
+			"Multiple IOB BA write response error\n");
+	if (reg & XGIC_POISONED_REQ_MASK)
+		dev_err(edac_dev->dev, "IOB BA XGIC poisoned write error\n");
+	if (reg & M_XGIC_POISONED_REQ_MASK)
+		dev_err(edac_dev->dev,
+			"Multiple IOB BA XGIC poisoned write error\n");
+	if (reg & RBM_POISONED_REQ_MASK)
+		dev_err(edac_dev->dev, "IOB BA RBM poisoned write error\n");
+	if (reg & M_RBM_POISONED_REQ_MASK)
+		dev_err(edac_dev->dev,
+			"Multiple IOB BA RBM poisoned write error\n");
+	if (reg & WDATA_CORRUPT_MASK)
+		dev_err(edac_dev->dev, "IOB BA write error\n");
+	if (reg & M_WDATA_CORRUPT_MASK)
+		dev_err(edac_dev->dev, "Multiple IOB BA write error\n");
+	if (reg & TRANS_CORRUPT_MASK)
+		dev_err(edac_dev->dev, "IOB BA transaction error\n");
+	if (reg & M_TRANS_CORRUPT_MASK)
+		dev_err(edac_dev->dev, "Multiple IOB BA transaction error\n");
+	if (reg & RIDRAM_CORRUPT_MASK)
+		dev_err(edac_dev->dev,
+			"IOB BA RDIDRAM read transaction ID error\n");
+	if (reg & M_RIDRAM_CORRUPT_MASK)
+		dev_err(edac_dev->dev,
+			"Multiple IOB BA RDIDRAM read transaction ID error\n");
+	if (reg & WIDRAM_CORRUPT_MASK)
+		dev_err(edac_dev->dev,
+			"IOB BA RDIDRAM write transaction ID error\n");
+	if (reg & M_WIDRAM_CORRUPT_MASK)
+		dev_err(edac_dev->dev,
+			"Multiple IOB BA RDIDRAM write transaction ID error\n");
+	if (reg & ILLEGAL_ACCESS_MASK)
+		dev_err(edac_dev->dev,
+			"IOB BA XGIC/RB illegal access error\n");
+	if (reg & M_ILLEGAL_ACCESS_MASK)
+		dev_err(edac_dev->dev,
+			"Multiple IOB BA XGIC/RB illegal access error\n");
+
+	err_addr_lo = readl(ctx->dev_csr + IOBBATRANSERRREQINFOL);
+	err_addr_hi = readl(ctx->dev_csr + IOBBATRANSERRREQINFOH);
+	dev_err(edac_dev->dev, "IOB BA %s access at 0x%02X.%08X (0x%08X)\n",
+		REQTYPE_F2_RD(err_addr_hi) ? "read" : "write",
+		ERRADDRH_F2_RD(err_addr_hi), err_addr_lo, err_addr_hi);
+	if (reg & WRERR_RESP_MASK)
+		dev_err(edac_dev->dev, "IOB BA requestor ID 0x%08X\n",
+			readl(ctx->dev_csr + IOBBATRANSERRCSWREQID));
+	writel(reg, ctx->dev_csr + IOBBATRANSERRINTSTS);
+}
+
+static void xgene_edac_pa_report(struct edac_device_ctl_info *edac_dev)
+{
+	struct xgene_edac_dev_ctx *ctx = edac_dev->pvt_info;
+	u32 err_addr_lo;
+	u32 err_addr_hi;
+	u32 reg;
+
+	/* IOB Processing agent transaction error interrupt */
+	reg = readl(ctx->dev_csr + IOBPATRANSERRINTSTS);
+	if (!reg)
+		goto chk_iob_axi0;
+	dev_err(edac_dev->dev, "IOB procesing agent (PA) transaction error\n");
+	if (reg & IOBPA_RDATA_CORRUPT_MASK)
+		dev_err(edac_dev->dev, "IOB PA read data RAM error\n");
+	if (reg & IOBPA_M_RDATA_CORRUPT_MASK)
+		dev_err(edac_dev->dev,
+			"Mutilple IOB PA read data RAM error\n");
+	if (reg & IOBPA_WDATA_CORRUPT_MASK)
+		dev_err(edac_dev->dev, "IOB PA write data RAM error\n");
+	if (reg & IOBPA_M_WDATA_CORRUPT_MASK)
+		dev_err(edac_dev->dev,
+			"Mutilple IOB PA write data RAM error\n");
+	if (reg & IOBPA_TRANS_CORRUPT_MASK)
+		dev_err(edac_dev->dev, "IOB PA transaction error\n");
+	if (reg & IOBPA_M_TRANS_CORRUPT_MASK)
+		dev_err(edac_dev->dev, "Mutilple IOB PA transaction error\n");
+	if (reg & IOBPA_REQIDRAM_CORRUPT_MASK)
+		dev_err(edac_dev->dev, "IOB PA transaction ID RAM error\n");
+	if (reg & IOBPA_M_REQIDRAM_CORRUPT_MASK)
+		dev_err(edac_dev->dev,
+			"Multiple IOB PA transaction ID RAM error\n");
+	writel(reg, ctx->dev_csr + IOBPATRANSERRINTSTS);
+
+chk_iob_axi0:
+	/* IOB AXI0 Error */
+	reg = readl(ctx->dev_csr + IOBAXIS0TRANSERRINTSTS);
+	if (!reg)
+		goto chk_iob_axi1;
+	err_addr_lo = readl(ctx->dev_csr + IOBAXIS0TRANSERRREQINFOL);
+	err_addr_hi = readl(ctx->dev_csr + IOBAXIS0TRANSERRREQINFOH);
+	dev_err(edac_dev->dev,
+		"%sAXI slave 0 illegal %s access @ 0x%02X.%08X (0x%08X)\n",
+		reg & IOBAXIS0_M_ILLEGAL_ACCESS_MASK ? "Multiple " : "",
+		REQTYPE_RD(err_addr_hi) ? "read" : "write",
+		ERRADDRH_RD(err_addr_hi), err_addr_lo, err_addr_hi);
+	writel(reg, ctx->dev_csr + IOBAXIS0TRANSERRINTSTS);
+
+chk_iob_axi1:
+	/* IOB AXI1 Error */
+	reg = readl(ctx->dev_csr + IOBAXIS1TRANSERRINTSTS);
+	if (!reg)
+		return;
+	err_addr_lo = readl(ctx->dev_csr + IOBAXIS1TRANSERRREQINFOL);
+	err_addr_hi = readl(ctx->dev_csr + IOBAXIS1TRANSERRREQINFOH);
+	dev_err(edac_dev->dev,
+		"%sAXI slave 1 illegal %s access @ 0x%02X.%08X (0x%08X)\n",
+		reg & IOBAXIS0_M_ILLEGAL_ACCESS_MASK ? "Multiple " : "",
+		REQTYPE_RD(err_addr_hi) ? "read" : "write",
+		ERRADDRH_RD(err_addr_hi), err_addr_lo, err_addr_hi);
+	writel(reg, ctx->dev_csr + IOBAXIS1TRANSERRINTSTS);
+}
+
+static void xgene_edac_soc_check(struct edac_device_ctl_info *edac_dev)
+{
+	struct xgene_edac_dev_ctx *ctx = edac_dev->pvt_info;
+	const char * const *soc_mem_err = NULL;
+	u32 pcp_hp_stat;
+	u32 pcp_lp_stat;
+	u32 reg;
+	int i;
+
+	xgene_edac_pcp_rd(ctx->edac, PCPHPERRINTSTS, &pcp_hp_stat);
+	xgene_edac_pcp_rd(ctx->edac, PCPLPERRINTSTS, &pcp_lp_stat);
+	xgene_edac_pcp_rd(ctx->edac, MEMERRINTSTS, &reg);
+	if (!((pcp_hp_stat & (IOB_PA_ERR_MASK | IOB_BA_ERR_MASK |
+			     IOB_XGIC_ERR_MASK | IOB_RB_ERR_MASK)) ||
+	      (pcp_lp_stat & CSW_SWITCH_TRACE_ERR_MASK) || reg))
+		return;
+
+	if (pcp_hp_stat & IOB_XGIC_ERR_MASK)
+		xgene_edac_iob_gic_report(edac_dev);
+
+	if (pcp_hp_stat & (IOB_RB_ERR_MASK | IOB_BA_ERR_MASK))
+		xgene_edac_rb_report(edac_dev);
+
+	if (pcp_hp_stat & IOB_PA_ERR_MASK)
+		xgene_edac_pa_report(edac_dev);
+
+	if (pcp_lp_stat & CSW_SWITCH_TRACE_ERR_MASK) {
+		dev_info(edac_dev->dev,
+			 "CSW switch trace correctable memory parity error\n");
+		edac_device_handle_ce(edac_dev, 0, 0, edac_dev->ctl_name);
+	}
+
+	if (ctx->version == 1)
+		soc_mem_err = soc_mem_err_v1;
+	if (!soc_mem_err) {
+		dev_err(edac_dev->dev, "SoC memory parity error 0x%08X\n",
+			reg);
+		edac_device_handle_ue(edac_dev, 0, 0, edac_dev->ctl_name);
+		return;
+	}
+	for (i = 0; i < 31; i++) {
+		if (reg & (1 << i)) {
+			dev_err(edac_dev->dev, "%s memory parity error\n",
+				soc_mem_err[i]);
+			edac_device_handle_ue(edac_dev, 0, 0,
+					      edac_dev->ctl_name);
+		}
+	}
+}
+
+static void xgene_edac_soc_hw_init(struct edac_device_ctl_info *edac_dev,
+				   bool enable)
+{
+	struct xgene_edac_dev_ctx *ctx = edac_dev->pvt_info;
+
+	/* Enable SoC IP error interrupt */
+	if (edac_dev->op_state == OP_RUNNING_INTERRUPT) {
+		if (enable) {
+			xgene_edac_pcp_clrbits(ctx->edac, PCPHPERRINTMSK,
+					       IOB_PA_ERR_MASK |
+					       IOB_BA_ERR_MASK |
+					       IOB_XGIC_ERR_MASK |
+					       IOB_RB_ERR_MASK);
+			xgene_edac_pcp_clrbits(ctx->edac, PCPLPERRINTMSK,
+					       CSW_SWITCH_TRACE_ERR_MASK);
+		} else {
+			xgene_edac_pcp_setbits(ctx->edac, PCPHPERRINTMSK,
+					       IOB_PA_ERR_MASK |
+					       IOB_BA_ERR_MASK |
+					       IOB_XGIC_ERR_MASK |
+					       IOB_RB_ERR_MASK);
+			xgene_edac_pcp_setbits(ctx->edac, PCPLPERRINTMSK,
+					       CSW_SWITCH_TRACE_ERR_MASK);
+		}
+
+		writel(enable ? 0x0 : 0xFFFFFFFF,
+		       ctx->dev_csr + IOBAXIS0TRANSERRINTMSK);
+		writel(enable ? 0x0 : 0xFFFFFFFF,
+		       ctx->dev_csr + IOBAXIS1TRANSERRINTMSK);
+		writel(enable ? 0x0 : 0xFFFFFFFF,
+		       ctx->dev_csr + XGICTRANSERRINTMSK);
+
+		xgene_edac_pcp_setbits(ctx->edac, MEMERRINTMSK,
+				       enable ? 0x0 : 0xFFFFFFFF);
+	}
+}
+
+static int xgene_edac_soc_add(struct xgene_edac *edac, struct device_node *np,
+			      int version)
+{
+	struct edac_device_ctl_info *edac_dev;
+	struct xgene_edac_dev_ctx *ctx;
+	void __iomem *dev_csr;
+	struct resource res;
+	int edac_idx;
+	int rc = 0;
+
+	if (!devres_open_group(edac->dev, xgene_edac_soc_add, GFP_KERNEL))
+		return -ENOMEM;
+
+	rc = of_address_to_resource(np, 0, &res);
+	if (rc < 0) {
+		dev_err(edac->dev, "no SoC resource address\n");
+		goto err_release_group;
+	}
+	dev_csr = devm_ioremap_resource(edac->dev, &res);
+	if (IS_ERR(dev_csr)) {
+		dev_err(edac->dev,
+			"devm_ioremap_resource failed for soc resource address\n");
+		rc = PTR_ERR(dev_csr);
+		goto err_release_group;
+	}
+
+	edac_idx = edac_device_alloc_index();
+	edac_dev = edac_device_alloc_ctl_info(sizeof(*ctx),
+					      "SOC", 1, "SOC", 1, 2, NULL, 0,
+					      edac_idx);
+	if (!edac_dev) {
+		rc = -ENOMEM;
+		goto err_release_group;
+	}
+
+	ctx = edac_dev->pvt_info;
+	ctx->dev_csr = dev_csr;
+	ctx->name = "xgene_soc_err";
+	ctx->edac_idx = edac_idx;
+	ctx->edac = edac;
+	ctx->edac_dev = edac_dev;
+	ctx->ddev = *edac->dev;
+	ctx->version = version;
+	edac_dev->dev = &ctx->ddev;
+	edac_dev->ctl_name = ctx->name;
+	edac_dev->dev_name = ctx->name;
+	edac_dev->mod_name = EDAC_MOD_STR;
+
+	if (edac_op_state == EDAC_OPSTATE_POLL)
+		edac_dev->edac_check = xgene_edac_soc_check;
+
+	rc = edac_device_add_device(edac_dev);
+	if (rc > 0) {
+		dev_err(edac->dev, "failed edac_device_add_device()\n");
+		rc = -ENOMEM;
+		goto err_ctl_free;
+	}
+
+	if (edac_op_state == EDAC_OPSTATE_INT)
+		edac_dev->op_state = OP_RUNNING_INTERRUPT;
+
+	list_add(&ctx->next, &edac->socs);
+
+	xgene_edac_soc_hw_init(edac_dev, 1);
+
+	devres_remove_group(edac->dev, xgene_edac_soc_add);
+
+	dev_info(edac->dev, "X-Gene EDAC SoC registered\n");
+
+	return 0;
+
+err_ctl_free:
+	edac_device_free_ctl_info(edac_dev);
+err_release_group:
+	devres_release_group(edac->dev, xgene_edac_soc_add);
+	return rc;
+}
+
+static int xgene_edac_soc_remove(struct xgene_edac_dev_ctx *soc)
+{
+	struct edac_device_ctl_info *edac_dev = soc->edac_dev;
+
+	xgene_edac_soc_hw_init(edac_dev, 0);
+	edac_device_del_device(soc->edac->dev);
+	edac_device_free_ctl_info(edac_dev);
+	return 0;
+}
+
 static irqreturn_t xgene_edac_isr(int irq, void *dev_id)
 {
 	struct xgene_edac *ctx = dev_id;
 	struct xgene_edac_pmd_ctx *pmd;
+	struct xgene_edac_dev_ctx *node;
 	unsigned int pcp_hp_stat;
 	unsigned int pcp_lp_stat;
 
@@ -1030,9 +1809,8 @@ static irqreturn_t xgene_edac_isr(int irq, void *dev_id)
 	    (MCU_CORR_ERR_MASK & pcp_lp_stat)) {
 		struct xgene_edac_mc_ctx *mcu;
 
-		list_for_each_entry(mcu, &ctx->mcus, next) {
+		list_for_each_entry(mcu, &ctx->mcus, next)
 			xgene_edac_mc_check(mcu->mci);
-		}
 	}
 
 	list_for_each_entry(pmd, &ctx->pmds, next) {
@@ -1040,6 +1818,12 @@ static irqreturn_t xgene_edac_isr(int irq, void *dev_id)
 			xgene_edac_pmd_check(pmd->edac_dev);
 	}
 
+	list_for_each_entry(node, &ctx->l3s, next)
+		xgene_edac_l3_check(node->edac_dev);
+
+	list_for_each_entry(node, &ctx->socs, next)
+		xgene_edac_soc_check(node->edac_dev);
+
 	return IRQ_HANDLED;
 }
 
@@ -1058,6 +1842,8 @@ static int xgene_edac_probe(struct platform_device *pdev)
 	platform_set_drvdata(pdev, edac);
 	INIT_LIST_HEAD(&edac->mcus);
 	INIT_LIST_HEAD(&edac->pmds);
+	INIT_LIST_HEAD(&edac->l3s);
+	INIT_LIST_HEAD(&edac->socs);
 	spin_lock_init(&edac->lock);
 	mutex_init(&edac->mc_lock);
 
@@ -1122,6 +1908,8 @@ static int xgene_edac_probe(struct platform_device *pdev)
 		}
 	}
 
+	edac->dfs = edac_get_debugfs();
+
 	for_each_child_of_node(pdev->dev.of_node, child) {
 		if (!of_device_is_available(child))
 			continue;
@@ -1131,6 +1919,14 @@ static int xgene_edac_probe(struct platform_device *pdev)
 			xgene_edac_pmd_add(edac, child, 1);
 		if (of_device_is_compatible(child, "apm,xgene-edac-pmd-v2"))
 			xgene_edac_pmd_add(edac, child, 2);
+		if (of_device_is_compatible(child, "apm,xgene-edac-l3"))
+			xgene_edac_l3_add(edac, child, 1);
+		if (of_device_is_compatible(child, "apm,xgene-edac-l3-v2"))
+			xgene_edac_l3_add(edac, child, 2);
+		if (of_device_is_compatible(child, "apm,xgene-edac-soc"))
+			xgene_edac_soc_add(edac, child, 0);
+		if (of_device_is_compatible(child, "apm,xgene-edac-soc-v1"))
+			xgene_edac_soc_add(edac, child, 1);
 	}
 
 	return 0;
@@ -1146,14 +1942,21 @@ static int xgene_edac_remove(struct platform_device *pdev)
 	struct xgene_edac_mc_ctx *temp_mcu;
 	struct xgene_edac_pmd_ctx *pmd;
 	struct xgene_edac_pmd_ctx *temp_pmd;
+	struct xgene_edac_dev_ctx *node;
+	struct xgene_edac_dev_ctx *temp_node;
 
-	list_for_each_entry_safe(mcu, temp_mcu, &edac->mcus, next) {
+	list_for_each_entry_safe(mcu, temp_mcu, &edac->mcus, next)
 		xgene_edac_mc_remove(mcu);
-	}
 
-	list_for_each_entry_safe(pmd, temp_pmd, &edac->pmds, next) {
+	list_for_each_entry_safe(pmd, temp_pmd, &edac->pmds, next)
 		xgene_edac_pmd_remove(pmd);
-	}
+
+	list_for_each_entry_safe(node, temp_node, &edac->l3s, next)
+		xgene_edac_l3_remove(node);
+
+	list_for_each_entry_safe(node, temp_node, &edac->socs, next)
+		xgene_edac_soc_remove(node);
+
 	return 0;
 }
 
-- 
1.7.1



From lho at apm.com  Tue Aug 11 13:47:57 2015
From: lho at apm.com (Loc Ho)
Date: Tue, 11 Aug 2015 14:47:57 -0600
Subject: [PATCH v3 4/4] arm64: Add L3/SoC DT subnodes to the APM X-Gene SoC
 EDAC node
In-Reply-To: <1439326077-25507-4-git-send-email-lho@apm.com>
References: <1439326077-25507-1-git-send-email-lho@apm.com>
 <1439326077-25507-2-git-send-email-lho@apm.com>
 <1439326077-25507-3-git-send-email-lho@apm.com>
 <1439326077-25507-4-git-send-email-lho@apm.com>
Message-ID: <1439326077-25507-5-git-send-email-lho@apm.com>

This patch adds L3/SoC DT subnodes to the APM X-Gene SoC EDAC node.

Signed-off-by: Loc Ho <lho at apm.com>
---
 arch/arm64/boot/dts/apm/apm-storm.dtsi |   10 ++++++++++
 1 files changed, 10 insertions(+), 0 deletions(-)

diff --git a/arch/arm64/boot/dts/apm/apm-storm.dtsi b/arch/arm64/boot/dts/apm/apm-storm.dtsi
index 58093ed..8ab6b0e 100644
--- a/arch/arm64/boot/dts/apm/apm-storm.dtsi
+++ b/arch/arm64/boot/dts/apm/apm-storm.dtsi
@@ -477,6 +477,16 @@
 				reg = <0x0 0x7c600000 0x0 0x200000>;
 				pmd-controller = <3>;
 			};
+
+			edacl3 at 7e600000 {
+				compatible = "apm,xgene-edac-l3";
+				reg = <0x0 0x7e600000 0x0 0x1000>;
+			};
+
+			edacsoc at 7e930000 {
+				compatible = "apm,xgene-edac-soc-v1";
+				reg = <0x0 0x7e930000 0x0 0x1000>;
+			};
 		};
 
 		pcie0: pcie at 1f2b0000 {
-- 
1.7.1



From davem at davemloft.net  Tue Aug 11 13:49:11 2015
From: davem at davemloft.net (David Miller)
Date: Tue, 11 Aug 2015 13:49:11 -0700 (PDT)
Subject: [PATCH v2 0/2] net: thunder: Add ACPI support.
In-Reply-To: <55CA5567.9010002@caviumnetworks.com>
References: <1439254717-2875-1-git-send-email-ddaney.cavm@gmail.com>
 <20150811.114908.1384923604512568161.davem@davemloft.net>
 <55CA5567.9010002@caviumnetworks.com>
Message-ID: <20150811.134911.568429332024299359.davem@davemloft.net>

From: David Daney <ddaney at caviumnetworks.com>
Date: Tue, 11 Aug 2015 13:04:55 -0700

> You seem to be recommending precedence for OF.  It should be
> consistent across all drivers/sub-systems, so do you really think
> that OF before ACPI is the way to go?

I just think it's more hackish to test acpi_disabled than to
simply see if the matching OF node even exists.

If ACPI is enabled, no OF node will be found.

It could just be my preference for such things.

I really wish it just fell out from the probing method, but
we're using PCI for that.


From davem at davemloft.net  Tue Aug 11 13:50:19 2015
From: davem at davemloft.net (David Miller)
Date: Tue, 11 Aug 2015 13:50:19 -0700 (PDT)
Subject: [PATCH v2 0/2] net: thunder: Add ACPI support.
In-Reply-To: <20150811201237.GW4914@rric.localhost>
References: <20150811.114908.1384923604512568161.davem@davemloft.net>
 <55CA5567.9010002@caviumnetworks.com>
 <20150811201237.GW4914@rric.localhost>
Message-ID: <20150811.135019.576312282566025940.davem@davemloft.net>

From: Robert Richter <robert.richter at caviumnetworks.com>
Date: Tue, 11 Aug 2015 22:12:37 +0200

> On 11.08.15 13:04:55, David Daney wrote:
>> >In the future it might be better structured to try and get the OF
>> >node, and if that fails then try and use the ACPI method to obtain
>> >these values.
>> 
>> Our current approach, as you can see in the patch, is the opposite.  If ACPI
>> is being used, prefer that over the OF device tree.
>> 
>> You seem to be recommending precedence for OF.  It should be consistent
>> across all drivers/sub-systems, so do you really think that OF before ACPI
>> is the way to go?
> 
> If ACPI is enabled then no OF function may be called at all.

That makes no sense to me at all.

If ACPI is enabled, the OF routines should return no nodes etc.


From bhelgaas at google.com  Tue Aug 11 14:02:10 2015
From: bhelgaas at google.com (Bjorn Helgaas)
Date: Tue, 11 Aug 2015 16:02:10 -0500
Subject: [PATCH 0/2] pci: am57xx-evm: Fix PCIe card enumeration issue
In-Reply-To: <1438090750-11604-1-git-send-email-kishon@ti.com>
References: <1438090750-11604-1-git-send-email-kishon@ti.com>
Message-ID: <20150811210210.GK13982@google.com>

On Tue, Jul 28, 2015 at 07:09:08PM +0530, Kishon Vijay Abraham I wrote:
> This series fixes PCIe card enumeration issue in am57xx-evm.
> 
> In the case of am57xx-evm, the PERST# line is connected to a gpio line
> and this has to be driven low in order to perform a fundamental reset
> of the card. If the gpio line is driven high, there is no way the card
> can come out of reset.
> 
> Add support in the pcie-dra7xx driver to make gpio drive PERST# line.
> 
> The PERST# line can be used to perform reset not during the power on
> sequence too (warm reset) but we are not adding support for this as the
> PCIe express base sepcification doesn't explain how to perform warm
> reset
> 
> "In some cases, it may be possible for the Fundamental Reset mechanism
> to be triggered by hardware without the removal and re-application of
> power to the component. This is called a warm reset. This document does
> not specify a means for generating a warm reset."
> 
> Kishon Vijay Abraham I (2):
>   pci: host: pci-dra7xx: Add support to make gpio drive PERST# line
>   ARM: dts: am57xx-evm: Add 'gpios' property with gpio2_8
> 
>  Documentation/devicetree/bindings/pci/ti-pci.txt |    3 +++
>  arch/arm/boot/dts/am57xx-beagle-x15.dts          |    5 +++++
>  arch/arm/boot/dts/dra7.dtsi                      |    2 +-
>  drivers/pci/host/pci-dra7xx.c                    |   24 ++++++++++++++++++++--
>  4 files changed, 31 insertions(+), 3 deletions(-)

Applied with Tony's ack (for patch 2) to pci/host-dra7xx for v4.3, thanks!


From msalter at redhat.com  Tue Aug 11 14:17:25 2015
From: msalter at redhat.com (Mark Salter)
Date: Tue, 11 Aug 2015 17:17:25 -0400
Subject: arm kernel oops in highmem.c with 4.2
In-Reply-To: <alpine.LFD.2.20.1508111558210.1515@knanqh.ubzr>
References: <CALeDE9Ox3=sh3AXQ0NUG6BBfU5i5YrMY=LDpcTHQWqz2=60F2g@mail.gmail.com>
 <20150805100701.GV7557@n2100.arm.linux.org.uk>
 <CALeDE9PXF=gQCaBCiHpHy2nXOooQOmsCQvSgOv+wQw3mta=P6A@mail.gmail.com>
 <20150805112713.GY7557@n2100.arm.linux.org.uk>
 <1439315290.3153.11.camel@redhat.com>
 <20150811181008.GA7557@n2100.arm.linux.org.uk>
 <alpine.LFD.2.20.1508111501130.1515@knanqh.ubzr>
 <20150811195638.GC7557@n2100.arm.linux.org.uk>
 <alpine.LFD.2.20.1508111558210.1515@knanqh.ubzr>
Message-ID: <1439327845.3153.17.camel@redhat.com>

On Tue, 2015-08-11 at 16:20 -0400, Nicolas Pitre wrote:
> On Tue, 11 Aug 2015, Russell King - ARM Linux wrote:
> 
> > On Tue, Aug 11, 2015 at 03:41:52PM -0400, Nicolas Pitre wrote:
> > > I'd agree.  But first I'd like to know why the fedora kernel is using 
> > > CONFIG_UACCESS_WITH_MEMCPY?  If it's just because it sounded cool 
> > > then 
> > > that's a bad reason.
> > > 
> > > That code was created to work around inneficiency in the Orion CPU 
> > > core 
> > > that didn't coalesce writes from STRT instructions, and by using 
> > > plain 
> > > STR and/or STM the actual throughput was more than doubled.  This was 
> > > fixed in later cores. However Orion users (if they still exist) might 
> > > like the added performance. I don't have Orion-based targets anymore 
> > > (they took the way of the recycling facility a while ago).
> > 
> > Irrespective of that, what has been found is that the implementation is
> > unsafe - it is taking a semaphore when page faults are disabled.  In
> > other words, notwithstanding the above, it's buggy no matter if it's
> > an Orion CPU core, or highmem, or what.  Any place in the kernel which
> > uses pagefault_disable() and then calls into this code will be buggy.
> > 
> > It needs fixing or removing.
> 
> Absolutely. I'm not disputing that. I'm only asking so we can wisely 
> choose between fixing or removing.  Personally I'd be inclined towards 
> the later, unless the following is sufficient to fix it:
> 
> diff --git a/arch/arm/lib/uaccess_with_memcpy.c 
> b/arch/arm/lib/uaccess_with_memcpy.c
> index 3e58d71001..4b39af2dfd 100644
> --- a/arch/arm/lib/uaccess_with_memcpy.c
> +++ b/arch/arm/lib/uaccess_with_memcpy.c
> @@ -96,7 +96,7 @@ __copy_to_user_memcpy(void __user *to, const void 
> *from, unsigned long n)
>  	}
>  
>  	/* the mmap semaphore is taken only if not in an atomic context 
> */
> -	atomic = in_atomic();
> +	atomic = faulthandler_disabled();
>  
>  	if (!atomic)
>  		down_read(&current->mm->mmap_sem);

Yeah, that fixes the problem I was seeing.

> 
> > Even if it is fixed, making it _depend_ on CPU_FEROCEON sounds like a
> > good idea if non-orion stuff isn't supposed to be enabling it.  Or
> > something like that.
> 
> It is not clear to me exactly which cores are affected.  That's why the 
> Kconfig entry was left open to all, in case it could benefit others.
> In theory it shouldn't be harmful to anyone notwithstanding the caveat
> mentioned in the help text.

This was on a calxeda highbank.

With CONFIG_UACCESS_WITH_MEMCPY, the dd copy test reported 1.8GB/s
Without CONFIG_UACCESS_WITH_MEMCPY, 2.1GB/s




From mturquette at linaro.org  Tue Aug 11 14:17:33 2015
From: mturquette at linaro.org (Michael Turquette)
Date: Tue, 11 Aug 2015 14:17:33 -0700
Subject: [PATCH v4 2/8] clk: Add a Raspberry Pi-specific clock driver.
In-Reply-To: <1437420787-32137-3-git-send-email-eric@anholt.net>
References: <1437420787-32137-1-git-send-email-eric@anholt.net>
 <1437420787-32137-3-git-send-email-eric@anholt.net>
Message-ID: <20150811211733.31346.11122@quantum>

Hi Eric,

Quoting Eric Anholt (2015-07-20 12:33:01)
> +void __init rpi_firmware_init_clock_provider(struct device_node *node)
> +{
> +       /* We delay construction of our struct clks until get time,
> +        * because we need to be able to return -EPROBE_DEFER if the
> +        * firmware driver isn't up yet.  clk core doesn't support
> +        * re-probing on -EPROBE_DEFER, but callers of clk_get can.
> +        */
> +       of_clk_add_provider(node, rpi_firmware_delayed_get_clk, node);
> +}
> +
> +CLK_OF_DECLARE(rpi_firmware_clocks, "raspberrypi,bcm2835-firmware-clocks",
> +              rpi_firmware_init_clock_provider);

Do you require CLK_OF_DECLARE here? Could this be a platform driver
instead?

Regards,
Mike

> -- 
> 2.1.4
> 


From mturquette at linaro.org  Tue Aug 11 14:18:40 2015
From: mturquette at linaro.org (Michael Turquette)
Date: Tue, 11 Aug 2015 14:18:40 -0700
Subject: [PATCH v4 1/8] clk: bcm2835: Add binding docs for the Raspberry
 Pi clock provider
In-Reply-To: <1437420787-32137-2-git-send-email-eric@anholt.net>
References: <1437420787-32137-1-git-send-email-eric@anholt.net>
 <1437420787-32137-2-git-send-email-eric@anholt.net>
Message-ID: <20150811211840.31346.28666@quantum>

Quoting Eric Anholt (2015-07-20 12:33:00)
> The hardware clocks are not controllable by the ARM, so we have to
> make requests to the firmware to do so from the VPU side.  This will
> let us replace fixed clocks in our DT with actual clock control (and
> correct frequency information).
> 
> Signed-off-by: Eric Anholt <eric at anholt.net>
> Acked-by: Stephen Warren <swarren at wwwdotorg.org>
> Acked-by: Lee Jones <lee at kernel.org>

Looks good to me. Do you want the clk patches to go through the clk tree
or do you want them all together? For this patch feel free to add:

Acked-by: Michael Turquette <mturquette at baylibre.com>

Regards,
Mike

> ---
> 
> v2: Include the dt-bindings header in this commit instead of the next
>     one.  Make the clock indices match the firmware clock IDs.  Rename
>     the binding's compat string.  Move the firmware phandle to be
>     under a vendor-specific namespace.
> v4: Mention 'clk' in the subject instead of the more generic
>     dt/bindings.
> 
>  .../clock/raspberrypi,bcm2835-firmware-clocks.txt  | 25 ++++++++++++++++++++++
>  include/dt-bindings/clk/raspberrypi.h              | 23 ++++++++++++++++++++
>  2 files changed, 48 insertions(+)
>  create mode 100644 Documentation/devicetree/bindings/clock/raspberrypi,bcm2835-firmware-clocks.txt
>  create mode 100644 include/dt-bindings/clk/raspberrypi.h
> 
> diff --git a/Documentation/devicetree/bindings/clock/raspberrypi,bcm2835-firmware-clocks.txt b/Documentation/devicetree/bindings/clock/raspberrypi,bcm2835-firmware-clocks.txt
> new file mode 100644
> index 0000000..0972602
> --- /dev/null
> +++ b/Documentation/devicetree/bindings/clock/raspberrypi,bcm2835-firmware-clocks.txt
> @@ -0,0 +1,25 @@
> +Raspberry Pi firmware clock provider.
> +
> +The Raspberry Pi architecture doesn't provide direct access to the
> +CLOCKMAN peripheral from the ARM side, so Linux has to make requests
> +to the VPU firmware to program them.
> +
> +This binding uses the common clock binding:
> +Documentation/devicetree/bindings/clock/clock-bindings.txt
> +
> +Required properties:
> +- compatible:          Should be "raspberrypi,bcm2835-firmware-clocks"
> +
> +- #clock-cells:                Shall have value <1>.  The permitted clock-specifier
> +                         values can be found in
> +                         include/dt-bindings/clk/raspberrypi.h.
> +
> +- raspberrypi,firmware:        Phandle to the firmware driver node.
> +
> +Example:
> +
> +firmware_clocks: firmware-clocks {
> +       compatible = "raspberrypi,bcm2835-firmware-clocks";
> +       #clock-cells = <1>;
> +       raspberrypi,firmware = <&firmware>;
> +};
> diff --git a/include/dt-bindings/clk/raspberrypi.h b/include/dt-bindings/clk/raspberrypi.h
> new file mode 100644
> index 0000000..ceec90f
> --- /dev/null
> +++ b/include/dt-bindings/clk/raspberrypi.h
> @@ -0,0 +1,23 @@
> +#/*
> + *  Copyright ?? 2015 Broadcom
> + *
> + * 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.
> + */
> +
> +#ifndef _DT_BINDINGS_CLK_RASPBERRYPI_H
> +#define _DT_BINDINGS_CLK_RASPBERRYPI_H
> +
> +#define RPI_CLOCK_EMMC 1
> +#define RPI_CLOCK_UART0        2
> +#define RPI_CLOCK_ARM  3
> +#define RPI_CLOCK_CORE 4
> +#define RPI_CLOCK_V3D  5
> +#define RPI_CLOCK_H264 6
> +#define RPI_CLOCK_ISP  7
> +#define RPI_CLOCK_SDRAM        8
> +#define RPI_CLOCK_PIXEL        9
> +#define RPI_CLOCK_PWM  10
> +
> +#endif
> -- 
> 2.1.4
> 


From mturquette at linaro.org  Tue Aug 11 14:19:46 2015
From: mturquette at linaro.org (Michael Turquette)
Date: Tue, 11 Aug 2015 14:19:46 -0700
Subject: [PATCH v4 5/8] clk: bcm2835: Drop the fixed sys_pclk.
In-Reply-To: <1437420787-32137-6-git-send-email-eric@anholt.net>
References: <1437420787-32137-1-git-send-email-eric@anholt.net>
 <1437420787-32137-6-git-send-email-eric@anholt.net>
Message-ID: <20150811211946.31346.8021@quantum>

Quoting Eric Anholt (2015-07-20 12:33:04)
> Nothing uses it, and I can't find any evidence that anything ever has.
> Its role is now filled by the core clock in the firmware driver.
> 
> Signed-off-by: Eric Anholt <eric at anholt.net>
> Acked-by: Stephen Warren <swarren at wwwdotorg.org>

Applied to clk-next.

Regards,
Mike

> ---
>  drivers/clk/clk-bcm2835.c | 5 -----
>  1 file changed, 5 deletions(-)
> 
> diff --git a/drivers/clk/clk-bcm2835.c b/drivers/clk/clk-bcm2835.c
> index 6b950ca..dd295e4 100644
> --- a/drivers/clk/clk-bcm2835.c
> +++ b/drivers/clk/clk-bcm2835.c
> @@ -32,11 +32,6 @@ void __init bcm2835_init_clocks(void)
>         struct clk *clk;
>         int ret;
>  
> -       clk = clk_register_fixed_rate(NULL, "sys_pclk", NULL, CLK_IS_ROOT,
> -                                       250000000);
> -       if (IS_ERR(clk))
> -               pr_err("sys_pclk not registered\n");
> -
>         clk = clk_register_fixed_rate(NULL, "apb_pclk", NULL, CLK_IS_ROOT,
>                                         126000000);
>         if (IS_ERR(clk))
> -- 
> 2.1.4
> 


From alexandre.belloni at free-electrons.com  Tue Aug 11 14:20:01 2015
From: alexandre.belloni at free-electrons.com (Alexandre Belloni)
Date: Tue, 11 Aug 2015 23:20:01 +0200
Subject: [rtc-linux] Re: [PATCH v2 1/2] devicetree: bindings: rtc: add
 bindings for xilinx zynqmp rtc
In-Reply-To: <EE0C027E1B1062419E7D6F61B9CF3AF65EDC2845@XAP-PVEXMBX01.xlnx.xilinx.com>
References: <1438336757-23404-1-git-send-email-suneel.garapati@xilinx.com>
 <7f57f610-7eea-434c-b7b8-3fb15cea18c0@googlegroups.com>
 <20150811183209.GX3411@piout.net>
 <EE0C027E1B1062419E7D6F61B9CF3AF65EDC2845@XAP-PVEXMBX01.xlnx.xilinx.com>
Message-ID: <20150811212001.GY3411@piout.net>

On 11/08/2015 at 19:29:54 +0000, Suneel Garapati wrote :
> For unknown reason, Alessandro zummo is shown by get_maintainer.pl.

Because he is the original RTC subsystem maintainer. Are you working on
an older kernel and my name doesn't appear?

-- 
Alexandre Belloni, Free Electrons
Embedded Linux, Kernel and Android engineering
http://free-electrons.com


From mcgrof at suse.com  Tue Aug 11 14:30:21 2015
From: mcgrof at suse.com (Luis R. Rodriguez)
Date: Tue, 11 Aug 2015 23:30:21 +0200
Subject: [PATCH v2 08/25] arch: introduce memremap()
In-Reply-To: <1438214404.3214.438.camel@hp.com>
References: <20150726172527.GA29513@lst.de>
 <CAPcyv4igoopDPpcCRU1TNYdwPhiYdcDiRA7L9Jdian=0rtexRg@mail.gmail.com>
 <20150727051258.GB15836@lst.de>
 <CAPcyv4jN6jYzw11qOOR-xd_w6s5dguQSoHyvmPFSWtL9S+tz3w@mail.gmail.com>
 <20150729065004.GA17162@lst.de>
 <20150729182712.GI30479@wotan.suse.de>
 <CAPcyv4iAeMAmU1QRZ1=WTav0cg2=-gqzzrt3nMC1QoD1+hOeBg@mail.gmail.com>
 <1438203638.3214.418.camel@hp.com>
 <20150729214358.GK30479@wotan.suse.de>
 <1438214404.3214.438.camel@hp.com>
Message-ID: <20150811213021.GD30479@wotan.suse.de>

On Wed, Jul 29, 2015 at 06:00:04PM -0600, Toshi Kani wrote:
> On Wed, 2015-07-29 at 23:43 +0200, Luis R. Rodriguez wrote:
> > On Wed, Jul 29, 2015 at 03:00:38PM -0600, Toshi Kani wrote:
> > > On Wed, 2015-07-29 at 11:33 -0700, Dan Williams wrote:
> > > > On Wed, Jul 29, 2015 at 11:27 AM, Luis R. Rodriguez <mcgrof at suse.com> 
> > > > wrote:
> > > > > On Wed, Jul 29, 2015 at 08:50:04AM +0200, Christoph Hellwig wrote:
> > > > > > On Mon, Jul 27, 2015 at 04:26:03PM -0700, Dan Williams wrote:
> > > > > > > Oh, because all we have at this point is ioremap_cache() which
> > > > > > > silently falls back.  It's not until the introduction of
> > > > > > > arch_memremp() where we update the arch code to break that 
> > > > > > > behavior.
> > > > > > 
> > > > > > Ok, makes sense.  Might be worth to document in the changelog.
> > > > > > 
> > > > > > > That said, I think it may be beneficial to allow a fallback if 
> > > > > > > the user cares.  So maybe memremap() can call plain ioremap() if
> > > > > > > MEMREMAP_STRICT is not set and none of the other mapping types 
> > > > > > > are satisfied.
> > > > > > 
> > > > > > Is there a real use case for it?  Fallback APIs always seem 
> > > > > > confusing and it might make more sense to do this in the caller(s) 
> > > > > > that actually need it.
> > > > > 
> > > > > It seems semantics-wise we are trying to separate these two really, 
> > > > > so I agree with this. Having a fallback would onloy make things more
> > > > > complicated for any sanitizer / checker / etc, and I don't think the 
> > > > > practical gains of having a fallback outweight the gains of having a 
> > > > > clear semantic separation on intended memory type and interactions 
> > > > > with it.
> > > > > 
> > > > 
> > > > Yup, consider it dropped.  Drivers that want fallback behavior can do
> > > > it explicitly.
> > > 
> > > I agree in general.  However, for the drivers to be able to fall back
> > > properly, they will need to know the cache type they can fall back with. 
> > > 
> > 
> > That would depend on the purpose of the region and the driver developer 
> > should in theory know best. One issue with this of course is that, as 
> > we've discovered, the semantics of on the ioremap*() variant front 
> > regarding cache types is not clearly well defined, or at least it may be 
> > only well defined implicitly on x86 only, so the driver developer can only 
> > *hope* for the best across architectures. Our ambiguity on our semantics 
> > on ioremap*() variants therefore means driver developers can resonably be 
> > puzzled by what fallbacks to use. That also means architectures 
> > maintainers should not whip driver developers for any misuse. Such 
> > considerations are why although we're now revisiting semantics for 
> > ioremap*() variants I was in hopes we could be at least somewhat
> > pedantic about memremap() semantics.
> 
> I agree.  However, there are a few exceptions like /dev/mem, which can map a
> target range without knowledge.

Still, the expectation to require support for overlapping ioremap() calls would
seem to be more of an exception than the norm, so I'd argue that requiring
callers who know they do need overlapping support to be explicit about it may
help us simplify expecations on semantics in other areas of the kernel.

> > For instance since memremap() only has 2 types right now can a respective
> > fallback be documented as an alternative to help with this ? Or can we not
> > generalize this ?  One for MEMREMAP_WB and one for MEMREMAP_WT ?
> 
> Yes, if a target range can be only mapped by memremap().  However, there is
> no restriction that a range can be mapped with a single interface alone. 
>  For example, a range can be mapped with remap_pfn_range() to user space
> with any cache type.  So, in theory, memremap() can overlap with any other
> types.

Shouldn't that be an issue or area of concern ? It seems the flakiness on
ioremap() and its wide array flexibility would spill over the any semantics
which folks would be trying to set out with memremap(). That should not stop
the evolution of memremap() though, just pointing out that perhaps we should be
a bit more restrictive over how things can criss-cross and who areas can do it.

> > > ioremap() falls back to the cache type of an existing mapping to avoid
> > > aliasing.
> > 
> > Does that assume an existing ioremap*() call was used on a bigger range?
> > Do you know if that happens to only be the case for x86 (I'd think so)
> > or if its the same for other architectures ?
> 
> In the /dev/mem example, it is remap_pfn_range().  I think other archs have
> the same issue, but I do not know if they fall back in case of overlapping
> call. 

What should happen if remap_pfn_range() was used with pgprot_writecombine()
and later memremap() is used for instance with a smaller overlappin section,
or perhaps bigger?

  Luis


From mturquette at baylibre.com  Tue Aug 11 14:30:41 2015
From: mturquette at baylibre.com (Michael Turquette)
Date: Tue, 11 Aug 2015 14:30:41 -0700
Subject: [PATCH v2 1/7] clk: Add a basic factor clock
In-Reply-To: <20150725073925.GK2564@lukather>
References: <1432241646-9511-1-git-send-email-maxime.ripard@free-electrons.com>
 <1432241646-9511-2-git-send-email-maxime.ripard@free-electrons.com>
 <CAGb2v64rqRC24wPWz5xYZv=w2QAtsCb-pd76Qynkb5NBCptXhQ@mail.gmail.com>
 <20150523074930.GI8557@lukather> <20150724000001.642.84690@quantum>
 <20150724065017.GJ2373@lukather> <20150724182619.642.11590@quantum>
 <20150725073925.GK2564@lukather>
Message-ID: <20150811213041.31346.58562@quantum>

Quoting Maxime Ripard (2015-07-25 00:39:25)
> Hi Mike,
> 
> On Fri, Jul 24, 2015 at 11:26:19AM -0700, Michael Turquette wrote:
> > > What are the issues with maintaining them? The only drawback I'm
> > > seeing with introducing such a driver is that you can't really have a
> > > clock that is both a divider and a multiplier, but that can be solved
> > > by splitting it into two sub-clocks.
> > 
> > There are a bunch of problems with the basic clock types. First is that
> > there is some feature creep every merge window that subtly breaks an
> > existing user (e.g. the round_rate stuff in clk-divider.c), and then
> > there are the growing number of flags to handle corner cases that are
> > one-off quirks for a single chip.
> > 
> > These make it harder to maintain, but it is possible.
> 
> Ok. It's the downside of having common code I guess, everyone wants to
> use it, and the clocks are just more subject to it than other drivers :/
> 
> > The real problem with these basic clock types is that they are an
> > abstraction layer at the wrong level. Each clock type implements both
> > the policy of a given clock, as well as the machine-specific details.
> > For example clk-divider.c has made some assumptions in the past about
> > rounding the rate, or how to calculate the best divider; this is a
> > matter of policy and is useful on its own. But additionally that same
> > policy is glued to a specific implementation: memory-mapped register
> > controls for a clock divider.
> > 
> > The I/O accessor stuff needs to be addressed at some point.  Currently
> > the basic clock types assume specific patterns of access to
> > memory-mapped clock registers. There are lots of other clock controls
> > out there that talk to firmware, or over i2c, or whatever. The amount of
> > code that has to be copy/pasted for each different type of access is
> > 100%; i.e. we do not have abstractions at the right level such as
> > .get_best_div(struct clk_hw *hw, unsigned long rate).
> > 
> > What I would like to see in time is a re-usable layer for clock policy
> > (e.g. common rules for how dividers or multipliers should behave), and
> > then have that sit on top of the machine-specific callbacks that
> > directly touch the hardware, such as the .get_best_div callback above.
> 
> Can't that be solved by moving to regmap using Matthias' patches, or
> at least the IO method abstraction?

I need to look at those patches again, but I do not think they address
the problem I described above: abstraction at the wrong level (or more
specifically, combining two abstract layers into one).

I'll have more bandwidth to look at this problem after the next merge
window. The clk framework is slowly be rewritten in bits and pieces here
on the list (shh don't tell anybody) and this is on my radar and
Stephen's.

Regards,
Mike

> 
> We would then have to only provide an additional callback then for
> providers that have specific requirements about the divider
> calculation.
> 
> So far, I haven't had any usecase where I needed anything but having
> the as-close-as-possible rate, so I would expect to not provide
> anything beside whether I'd like to round down or round up, but I do
> understand that some other might have different requirements.
> 
> > For this reason I like to limit the number of new basic clock types. If
> > there is a single user then I'm inclined to have the author put it with
> > the machine-specific code. But in this case since there are two users, I
> > see the value in making a new basic clock type.
> 
> That makes sense.
> 
> Maxime
> 
> -- 
> Maxime Ripard, Free Electrons
> Embedded Linux, Kernel and Android engineering
> http://free-electrons.com
> 
> 
> _______________________________________________
> linux-arm-kernel mailing list
> linux-arm-kernel at lists.infradead.org
> http://lists.infradead.org/mailman/listinfo/linux-arm-kernel


From mturquette at baylibre.com  Tue Aug 11 14:34:33 2015
From: mturquette at baylibre.com (Michael Turquette)
Date: Tue, 11 Aug 2015 14:34:33 -0700
Subject: [PATCH] clk: rockchip: Fix SPIF special clock definition
In-Reply-To: <2030894.j0VJujBTor@diego>
References: <1438077162-27623-1-git-send-email-sjoerd.simons@collabora.co.uk>
 <2030894.j0VJujBTor@diego>
Message-ID: <20150811213433.31346.58424@quantum>

Quoting Heiko St?bner (2015-07-28 03:08:54)
> Am Dienstag, 28. Juli 2015, 11:52:42 schrieb Sjoerd Simons:
> > Neither spdif_src nor spdif_pll exists, judging by the vendor kernel in
> > both cases spdif_pre was meant. This brings the naming in line and
> > hierachy in line with that of sclk_i2s0.
> > 
> > Also allow sclk_spdif and spdif_frac to change their parents rate as
> > that the upstream dividers are purely there to feed sclk_spdif
> > 
> > Signed-off-by: Sjoerd Simons <sjoerd.simons at collabora.co.uk>
> 
> I guess there was one rename to many back in the time :-) .
> Verified this with the CRU documentation, so
> 
> Reviewed-by: Heiko Stuebner <heiko at sntech.de>

Applied to clk-next.

Regards,
Mike

> 
> > ---
> >  drivers/clk/rockchip/clk-rk3188.c | 6 +++---
> >  1 file changed, 3 insertions(+), 3 deletions(-)
> > 
> > diff --git a/drivers/clk/rockchip/clk-rk3188.c
> > b/drivers/clk/rockchip/clk-rk3188.c index 0abf22d..ed02bbc 100644
> > --- a/drivers/clk/rockchip/clk-rk3188.c
> > +++ b/drivers/clk/rockchip/clk-rk3188.c
> > @@ -202,7 +202,7 @@ PNAME(mux_pll_src_cpll_gpll_p)    = { "cpll", "gpll" };
> >  PNAME(mux_aclk_cpu_p)                = { "apll", "gpll" };
> >  PNAME(mux_sclk_cif0_p)               = { "cif0_pre", "xin24m" };
> >  PNAME(mux_sclk_i2s0_p)               = { "i2s0_pre", "i2s0_frac", "xin12m" };
> > -PNAME(mux_sclk_spdif_p)              = { "spdif_src", "spdif_frac", "xin12m" };
> > +PNAME(mux_sclk_spdif_p)              = { "spdif_pre", "spdif_frac", "xin12m" };
> >  PNAME(mux_sclk_uart0_p)              = { "uart0_pre", "uart0_frac", "xin24m" };
> >  PNAME(mux_sclk_uart1_p)              = { "uart1_pre", "uart1_frac", "xin24m" };
> >  PNAME(mux_sclk_uart2_p)              = { "uart2_pre", "uart2_frac", "xin24m" };
> > @@ -350,10 +350,10 @@ static struct rockchip_clk_branch
> > common_clk_branches[] __initdata = { COMPOSITE_NOMUX(0, "spdif_pre",
> > "i2s_src", 0,
> >                       RK2928_CLKSEL_CON(5), 0, 7, DFLAGS,
> >                       RK2928_CLKGATE_CON(0), 13, GFLAGS),
> > -     COMPOSITE_FRAC(0, "spdif_frac", "spdif_pll", 0,
> > +     COMPOSITE_FRAC(0, "spdif_frac", "spdif_pre", CLK_SET_RATE_PARENT,
> >                       RK2928_CLKSEL_CON(9), 0,
> >                       RK2928_CLKGATE_CON(0), 14, GFLAGS),
> > -     MUX(SCLK_SPDIF, "sclk_spdif", mux_sclk_spdif_p, 0,
> > +     MUX(SCLK_SPDIF, "sclk_spdif", mux_sclk_spdif_p, CLK_SET_RATE_PARENT,
> >                       RK2928_CLKSEL_CON(5), 8, 2, MFLAGS),
> > 
> >       /*
> 
> 
> _______________________________________________
> linux-arm-kernel mailing list
> linux-arm-kernel at lists.infradead.org
> http://lists.infradead.org/mailman/listinfo/linux-arm-kernel


From timur at codeaurora.org  Tue Aug 11 15:01:57 2015
From: timur at codeaurora.org (Timur Tabi)
Date: Tue, 11 Aug 2015 17:01:57 -0500
Subject: [PATCH v4 00/10] ACPI GIC Self-probing, GICv2m and GICv3 support
In-Reply-To: <1438164539-29256-1-git-send-email-hanjun.guo@linaro.org>
References: <1438164539-29256-1-git-send-email-hanjun.guo@linaro.org>
Message-ID: <55CA70D5.6040300@codeaurora.org>

On 07/29/2015 05:08 AM, Hanjun Guo wrote:
> Patches are on top of Marc's branch irq/gsi-irq-domain-v2, and available
> at:
>
> git://git.linaro.org/leg/acpi/acpi.git gsi-irqdomain

Is it my imagination, or is Marc's branch based on v3.9-rc7?

Also, shouldn't this code be based on the upstream kernel, and not the 
LEG kernel?

-- 
Qualcomm Innovation Center, Inc.
The Qualcomm Innovation Center, Inc. is a member of the
Code Aurora Forum, a Linux Foundation Collaborative Project.


From graeme.gregory at linaro.org  Tue Aug 11 15:24:56 2015
From: graeme.gregory at linaro.org (G Gregory)
Date: Tue, 11 Aug 2015 23:24:56 +0100
Subject: [Linaro-acpi] [PATCH v4 00/10] ACPI GIC Self-probing, GICv2m and
 GICv3 support
In-Reply-To: <55CA70D5.6040300@codeaurora.org>
References: <1438164539-29256-1-git-send-email-hanjun.guo@linaro.org>
 <55CA70D5.6040300@codeaurora.org>
Message-ID: <CAGCh1+mPLhk24bTTkJ2+k5M9UFO2Sf=aVGipSgf1W+3DwTHiuA@mail.gmail.com>

On 11 August 2015 at 23:01, Timur Tabi <timur at codeaurora.org> wrote:
> On 07/29/2015 05:08 AM, Hanjun Guo wrote:
>>
>> Patches are on top of Marc's branch irq/gsi-irq-domain-v2, and available
>> at:
>>
>> git://git.linaro.org/leg/acpi/acpi.git gsi-irqdomain
>
>
> Is it my imagination, or is Marc's branch based on v3.9-rc7?
>
Looks like 4.2-rc2 to me.

> Also, shouldn't this code be based on the upstream kernel, and not the LEG
> kernel?
>
Nothing LEG kernelly in there.

Graeme


From marc.zyngier at arm.com  Tue Aug 11 15:25:23 2015
From: marc.zyngier at arm.com (Marc Zyngier)
Date: Tue, 11 Aug 2015 23:25:23 +0100
Subject: [PATCH v4 00/10] ACPI GIC Self-probing, GICv2m and GICv3 support
In-Reply-To: <55CA70D5.6040300@codeaurora.org>
References: <1438164539-29256-1-git-send-email-hanjun.guo@linaro.org>
 <55CA70D5.6040300@codeaurora.org>
Message-ID: <20150811232523.60d192d2@arm.com>

On Tue, 11 Aug 2015 23:01:57 +0100
Timur Tabi <timur at codeaurora.org> wrote:

> On 07/29/2015 05:08 AM, Hanjun Guo wrote:
> > Patches are on top of Marc's branch irq/gsi-irq-domain-v2, and available
> > at:
> >
> > git://git.linaro.org/leg/acpi/acpi.git gsi-irqdomain
> 
> Is it my imagination, or is Marc's branch based on v3.9-rc7?

That's definitely your imagination. I've stopped working on 3.9 over
two years ago...

> Also, shouldn't this code be based on the upstream kernel, and not the 
> LEG kernel?

My branch, as far as I can tell by looking at my own git tree, is based
on v4.2-rc2. As for "the LEG kernel", I have no idea what that is. I
only work on this thing called "the Linux kernel". You may have heard
of it! ;-)

Thanks,

	M.
-- 
Jazz is not dead. It just smells funny.


From lina.iyer at linaro.org  Tue Aug 11 15:29:46 2015
From: lina.iyer at linaro.org (Lina Iyer)
Date: Tue, 11 Aug 2015 16:29:46 -0600
Subject: [PATCH 5/9] ARM: common: Introduce PM domains for CPUs/clusters
In-Reply-To: <CAL_JsqLhHy5gO=usm1HLf8h6iz_5FguCDo-Qz2Km+XEwaCODUA@mail.gmail.com>
References: <1438731339-58317-1-git-send-email-lina.iyer@linaro.org>
 <1438731339-58317-6-git-send-email-lina.iyer@linaro.org>
 <CAL_JsqK67=DTtjZwwnonObLDjLbahkREfm0RvyXVV95bhR-d4Q@mail.gmail.com>
 <7hd1yyvf1b.fsf@deeprootsystems.com>
 <CAMuHMdWRoUOBvz7MEGgF1oHz95D-GhaYG1yHr_kGe5NUQ0EnrQ@mail.gmail.com>
 <20150811155819.GH52339@linaro.org>
 <CAL_JsqLhHy5gO=usm1HLf8h6iz_5FguCDo-Qz2Km+XEwaCODUA@mail.gmail.com>
Message-ID: <20150811222946.GJ52339@linaro.org>

On Tue, Aug 11 2015 at 14:13 -0600, Rob Herring wrote:
>On Tue, Aug 11, 2015 at 10:58 AM, Lina Iyer <lina.iyer at linaro.org> wrote:
>> On Tue, Aug 11 2015 at 07:07 -0600, Geert Uytterhoeven wrote:
>>> On Sat, Aug 8, 2015 at 1:45 AM, Kevin Hilman <khilman at kernel.org> wrote:
>>>> Rob Herring <robherring2 at gmail.com> writes:
>>>>> On Tue, Aug 4, 2015 at 6:35 PM, Lina Iyer <lina.iyer at linaro.org> wrote:
>>>>>>
>>>>>> +ARM CPU Power domains
>>>>>> +
>>>>>> +The device tree allows describing of CPU power domains in a SoC. In
>>>>>> ARM SoC,
>>>>>> +CPUs may be grouped as clusters. A cluster may have CPUs, GIC,
>>>>>> Coresight,
>>>>>> +caches, VFP and power controller and other peripheral hardware.
>>>>>> Generally,
>>>>>> +when the CPUs in the cluster are idle/suspended, the shared resources
>>>>>> may also
>>>>>> +be suspended and resumed before any of the CPUs resume execution.
>>>>>> +
>>>>>> +CPUs are the defined as the PM domain consumers and there is a PM
>>>>>> domain
>>>>>> +provider for the CPUs. Bindings for generic PM domains (genpd) is
>>>>>> described in
>>>>>> +[1].
>>>>>> +
>>>>>> +The ARM CPU PM domain follows the same binding convention as any
>>>>>> generic PM
>>>>>> +domain. Additional binding properties are -
>>>>>> +
>>>>>> +- compatible:
>>>>>> +       Usage: required
>>>>>> +       Value type: <string>
>>>>>> +       Definition: Must also have
>>>>>> +                       "arm,pd"
>>>>>> +               inorder to initialize the genpd provider as ARM CPU PM
>>>>>> domain.
>>>>>
>>>>>
>>>>> A compatible string should represent a particular h/w block. If it is
>>>>> generic, it should represent some sort of standard programming
>>>>> interface (e.g, AHCI, EHCI, etc.). This doesn't seem to be either and
>>>>> is rather just a mapping of what "driver" you want to use.
>>>>>
>>>>> I would expect that identifying a cpu's or cluster's power domain
>>>>> would be done by a phandle between the cpu/cluster node and power
>>>>> domain node.
>>>>
>>>>
>>>> That's correct, the CPU nodes (and other nodes in the cluster like GIC,
>>>> Coresight, etc.) would have phandles to the cluster power domain node.
>>>
>>>
>>> Indeed.
>>>
>>>> But this series is meant to create the driver & binding for those cluster
>>>> power domain(s), so the question is how exactly describe it.
>>>
>>>
>>> I don't think I can add an "arm,pd" compatible property to e.g. a2sl
>>> (for CA15-CPUx) and a3sm (for CA15-SCU) in arch/arm/boot/dts/r8a73a4.dtsi,
>>> as these are just subdomains in a power domain hierarchy, all driven by a
>>> single hardware block.
>>>
>>> I can call e.g. a special registration method, or set up some ops pointer,
>>> for the a2sl and a3sm subdomains from within the "renesas,sysc-rmobile"
>>> driver.
>>>
>> I was hoping the macro would help in such a case. But since your domain
>> cannot be defined as arm,pd (could you explain why, I seem to missing
>> the obvious) would it help if I export a function like that the
>> renesas,sysc-rmobile driver could call and setup the CPU PM domain?
>> There is catch to it though.
>>
>> The problem is -
>>
>> To be generic and not have every driver write code to do this generic
>> functionality, the common code would want to instantiate the
>> arm_pm_domain and therefore the embedded genpd. A pointer instead of
>> actual object, would mean maintaining a list and iterating through it,
>> everytime the domain is suspended/resumed. With an object, I could just
>> do container_of and get the arm_pd. But, we also want to give the
>> platform an option to define certain aspects of the CPU's generic PM
>> domain like the flags, genpd callbacks etc, before the genpd is
>> registered with the framework.
>
>The problem here is what part of the hardware is generic? It is
>generic, but yet ARM specific (presumably not as Kevin pointed out)?
>
CPU is the generic device that we are currently interested in. It is not
ARM specific and I am open to any better compatible description for such
domain providers.

>I'm not exactly clear what the problem is, but it seems you are after
>a common API/subsystem for managing power domains of CPU/clusters.
>
Partly yes. The common code is just managing common activities during
on/off of the power domain.
Platform driver needs to be involved to power on/off the power domain
hardware.

>I fail to see how the problem is different than any other subsystem
>where you have a core providing common API with hardware specific
>drivers registering their ops with the core.
>
Platform drivers today, directly use PM domains. They setup genpd
properties and callbacks (.power_on, .power_off) before registering with
the PM domain framework. For ex, renesas driver does this - 
 
struct generic_pm_domain *genpd;

genpd->flags = GENPD_FLAG_PM_CLK;
pm_genpd_init(genpd, gov ? : &simple_qos_governor, false);
genpd->dev_ops.active_wakeup    = rmobile_pd_active_wakeup;
genpd->power_off                = rmobile_pd_power_down;
genpd->power_on                 = rmobile_pd_power_up;
genpd->attach_dev               = rmobile_pd_attach_dev;
genpd->detach_dev               = rmobile_pd_detach_dev;

The common code also uses genpd and has some additional properties. It 
would also like to receive callbacks for .power_on and .power_off. On
the *same* genpd object -

genpd->flags |= GENPD_FLAG_IRQ_SAFE;
genpd->power_off = arm_pd_power_down;
genpd->power_on = arm_pd_power_up;

Most of the times the platform driver just would set the power_on,
power_off callbacks. In which case they could just register platform ops
with the core , during the OF_DECLARE_1() callback. The core would set
up the genpd->power_xxx to arm_pd_power_xxx and would relay the callback
to the platform using the callbacks registered the core.

But in the case like Renesas, where the genpd object created by the
core, needs to be modified by the platform driver before registering
with PM domain framework, the complexity arises. This where OF_DECLARE_1
lacks argument. The core code would like to pass the genpd object for the
platform code to amend and when the callback returns, use the genpd to
register with PM domain framework.

>>
>> Would such a function work for you? What does everyone think about the
>> @template?
>>
>> struct generic_pm_domain *of_arm_cpu_domain(struct device_node *dn,
>
>This is missing a verb. What does it do?
>
Sorry. /s/of_arm_cpu_domain/of_arm_init_cpu_domain/

>I don't think I really get what you are trying to solve to comment
>whether this looks good or not.
>
Let me know if this helps clarify.

Thanks,
Lina

>Rob
>
>>                struct of_arm_pd_ops *ops, struct generic_pm_domain
>> *template)
>> {
>>        struct arm_pm_domain *pd;
>>
>>        if (!of_device_is_available(dn))
>>                return NULL;
>>
>>         /* This creates the memory for pd and setup basic stuff */
>>        pd = setup_arm_pd(dn);
>>
>>         /* copy the platform's template genpd over to the pd's genpd */
>>        memcpy(&pd.genpd, template, sizeof(*template));
>>
>>         /*       * Now set up the additional ops and flags and register with
>>          * genpd framework
>>          */
>>        register_arm_pd(dn, pd);
>>
>>         /*       * Returning the genpd back to the platform so it can be
>> added
>>          * as subdomains to other domains etc.
>>          */
>>        return &pd.genpd;
>> }
>> EXPORT_SYMBOL(of_arm_cpu_domain);
>>
>> The catch is that platform drivers have to provide a template for the
>> genpd. The @template would never be registered, but would just be used
>> to create the common code's genpd.
>>
>> Any other ideas?
>>
>> Thanks,
>> Lina


From sboyd at codeaurora.org  Tue Aug 11 15:34:09 2015
From: sboyd at codeaurora.org (Stephen Boyd)
Date: Tue, 11 Aug 2015 15:34:09 -0700
Subject: [PATCH v3 0/2] clk: improve handling of orphan clocks
In-Reply-To: <20150730100908.GI2564@lukather>
References: <1429735986-18592-1-git-send-email-heiko@sntech.de>
 <554BD33D.7050907@codeaurora.org> <20150508100247.GQ11057@lukather>
 <4099394.C7vEjTFs8V@diego> <20150730100908.GI2564@lukather>
Message-ID: <20150811223409.GN2839@codeaurora.org>

On 07/30, Maxime Ripard wrote:
> On Mon, Jul 27, 2015 at 10:57:33AM +0200, Heiko St?bner wrote:
> > 
> > did this lead anywhere meanwhile.
> > 
> > Last I remember the change to orphan handling made sunxi fail, but
> > I'm still hoping to get this usable at some point :-)
> 
> To be honest, I don't know what the current status is. I haven't get
> any news since that mail.
> 
> I started to move a significant portion of our clocks to
> CLK_OF_DECLARE, but not all of them are (which probably make the
> situation worse for the time being).
> 

Sorry, I think we're still waiting for the critical clocks stuff
to settle down so that Sunxi can use that instead of calling
clk_prepare_enable() in init code. For now, I've put the first
patch of the two into clk-next so that we can have proper orphan
tracking. Hopefully we resolve critical clocks soon so that we
can merge the defer part.

-- 
Qualcomm Innovation Center, Inc. is a member of Code Aurora Forum,
a Linux Foundation Collaborative Project


From timur at codeaurora.org  Tue Aug 11 15:36:14 2015
From: timur at codeaurora.org (Timur Tabi)
Date: Tue, 11 Aug 2015 17:36:14 -0500
Subject: [PATCH v4 00/10] ACPI GIC Self-probing, GICv2m and GICv3 support
In-Reply-To: <20150811232523.60d192d2@arm.com>
References: <1438164539-29256-1-git-send-email-hanjun.guo@linaro.org>	<55CA70D5.6040300@codeaurora.org>
 <20150811232523.60d192d2@arm.com>
Message-ID: <55CA78DE.1000306@codeaurora.org>

On 08/11/2015 05:25 PM, Marc Zyngier wrote:
> My branch, as far as I can tell by looking at my own git tree, is based
> on v4.2-rc2. As for "the LEG kernel", I have no idea what that is. I
> only work on this thing called "the Linux kernel". You may have heard
> of it!;-)

Then what is this:

git://git.linaro.org/leg/acpi/acpi.git
                      ^^^

This is your tree, isn't it?  Hanjun said, "Patches are on top of Marc's 
branch irq/gsi-irq-domain-v2, and available at: 
git://git.linaro.org/leg/acpi/acpi.git gsi-irqdomain".


-- 
Qualcomm Innovation Center, Inc.
The Qualcomm Innovation Center, Inc. is a member of the
Code Aurora Forum, a Linux Foundation Collaborative Project.


From mchehab at osg.samsung.com  Tue Aug 11 15:39:04 2015
From: mchehab at osg.samsung.com (Mauro Carvalho Chehab)
Date: Tue, 11 Aug 2015 19:39:04 -0300
Subject: [PATCH 1/3] [media] c8sectpfe: fix pinctrl dependencies
Message-ID: <53cc7c9043f0a68a66e53623b114c86051a7250c.1439332733.git.mchehab@osg.samsung.com>

compiling on some archs fail with:

drivers/media/platform/sti/c8sectpfe/c8sectpfe-core.c:540:8: error: implicit declaration of function ?pinctrl_select_state? [-Werror=implicit-function-declaration]
  ret = pinctrl_select_state(fei->pinctrl, tsin->pstate);

That's due the need of including pinctrl.h header and because
CONFIG_PINCTRL needs to be true.

Signed-off-by: Mauro Carvalho Chehab <mchehab at osg.samsung.com>

diff --git a/drivers/media/platform/sti/c8sectpfe/Kconfig b/drivers/media/platform/sti/c8sectpfe/Kconfig
index a7227d2ab6cc..1b1110d7374f 100644
--- a/drivers/media/platform/sti/c8sectpfe/Kconfig
+++ b/drivers/media/platform/sti/c8sectpfe/Kconfig
@@ -1,6 +1,7 @@
 config DVB_C8SECTPFE
 	tristate "STMicroelectronics C8SECTPFE DVB support"
-	depends on DVB_CORE && I2C && (ARCH_STI || ARCH_MULTIPLATFORM || COMPILE_TEST)
+	depends on PINCTRL && DVB_CORE && I2C
+	depends on ARCH_STI || ARCH_MULTIPLATFORM || COMPILE_TEST
 	select LIBELF_32
 	select FW_LOADER
 	select FW_LOADER_USER_HELPER_FALLBACK
diff --git a/drivers/media/platform/sti/c8sectpfe/c8sectpfe-core.c b/drivers/media/platform/sti/c8sectpfe/c8sectpfe-core.c
index 955d8daf055f..1586a1e6836d 100644
--- a/drivers/media/platform/sti/c8sectpfe/c8sectpfe-core.c
+++ b/drivers/media/platform/sti/c8sectpfe/c8sectpfe-core.c
@@ -33,6 +33,7 @@
 #include <linux/time.h>
 #include <linux/version.h>
 #include <linux/wait.h>
+#include <linux/pinctrl/pinctrl.h>
 
 #include "c8sectpfe-core.h"
 #include "c8sectpfe-common.h"
-- 
2.4.3



From toshi.kani at hp.com  Tue Aug 11 15:40:57 2015
From: toshi.kani at hp.com (Toshi Kani)
Date: Tue, 11 Aug 2015 16:40:57 -0600
Subject: [PATCH v2 08/25] arch: introduce memremap()
In-Reply-To: <20150811213021.GD30479@wotan.suse.de>
References: <20150726172527.GA29513@lst.de>
 <CAPcyv4igoopDPpcCRU1TNYdwPhiYdcDiRA7L9Jdian=0rtexRg@mail.gmail.com>
 <20150727051258.GB15836@lst.de>
 <CAPcyv4jN6jYzw11qOOR-xd_w6s5dguQSoHyvmPFSWtL9S+tz3w@mail.gmail.com>
 <20150729065004.GA17162@lst.de> <20150729182712.GI30479@wotan.suse.de>
 <CAPcyv4iAeMAmU1QRZ1=WTav0cg2=-gqzzrt3nMC1QoD1+hOeBg@mail.gmail.com>
 <1438203638.3214.418.camel@hp.com> <20150729214358.GK30479@wotan.suse.de>
 <1438214404.3214.438.camel@hp.com> <20150811213021.GD30479@wotan.suse.de>
Message-ID: <1439332857.24434.37.camel@hp.com>

On Tue, 2015-08-11 at 23:30 +0200, Luis R. Rodriguez wrote:
> On Wed, Jul 29, 2015 at 06:00:04PM -0600, Toshi Kani wrote:
> > On Wed, 2015-07-29 at 23:43 +0200, Luis R. Rodriguez wrote:
> > > On Wed, Jul 29, 2015 at 03:00:38PM -0600, Toshi Kani wrote:
> > > > On Wed, 2015-07-29 at 11:33 -0700, Dan Williams wrote:
  :
> > > That would depend on the purpose of the region and the driver 
> > > developer should in theory know best. One issue with this of course is 
> > > that, as we've discovered, the semantics of on the ioremap*() variant 
> > > front regarding cache types is not clearly well defined, or at least 
> > > it may be only well defined implicitly on x86 only, so the driver 
> > > developer can only *hope* for the best across architectures. Our 
> > > ambiguity on our semantics on ioremap*() variants therefore means 
> > > driver developers can resonably be puzzled by what fallbacks to use. 
> > > That also means architectures maintainers should not whip driver 
> > > developers for any misuse. Such considerations are why although we're 
> > > now revisiting semantics for ioremap*() variants I was in hopes we 
> > > could be at least somewhat pedantic about memremap() semantics.
> > 
> > I agree.  However, there are a few exceptions like /dev/mem, which can 
> > map a target range without knowledge.
> 
> Still, the expectation to require support for overlapping ioremap() calls 
> would seem to be more of an exception than the norm, so I'd argue that 
> requiring callers who know they do need overlapping support to be explicit 
> about it may help us simplify expecations on semantics in other areas of 
> the kernel.

Again, I agree.  I am simply saying that the fallback in an overlapping case
may need to remain supported for such exceptional cases, possibly with a
separate interface.

> > > For instance since memremap() only has 2 types right now can a 
> > > respective fallback be documented as an alternative to help with this 
> > > ? Or can we not generalize this ?  One for MEMREMAP_WB and one for 
> > > MEMREMAP_WT ?
> > 
> > Yes, if a target range can be only mapped by memremap().  However, there 
> > is no restriction that a range can be mapped with a single interface 
> > alone.  For example, a range can be mapped with remap_pfn_range() to 
> > user space with any cache type.  So, in theory, memremap() can overlap 
> > with any other types.
> 
> Shouldn't that be an issue or area of concern ? It seems the flakiness on
> ioremap() and its wide array flexibility would spill over the any 
> semantics which folks would be trying to set out with memremap(). That 
> should not stop the evolution of memremap() though, just pointing out that 
> perhaps we should be a bit more restrictive over how things can criss
> -cross and who areas can do it.

reserve_pfn_range() allows the caller to specify if the fallback needs to be
enabled or disabled with 'strict_prot'.  track_pfn_remap() called from
remap_pfn_range() enables it, and track_pfn_copy() disables it.  I think we
can do similar for the memremap and ioremap families as well.  The fallback
could be set disabled in the regular interfaces, and enabled in some
interface as necessary.  This also allows gradual transition, ex. disable in
memremap while ioremap remains enabled for now. 

> > > > ioremap() falls back to the cache type of an existing mapping to 
> > > > avoid aliasing.
> > > 
> > > Does that assume an existing ioremap*() call was used on a bigger 
> > > range?  Do you know if that happens to only be the case for x86 (I'd 
> > > think so) or if its the same for other architectures ?
> > 
> > In the /dev/mem example, it is remap_pfn_range().  I think other archs 
> > have the same issue, but I do not know if they fall back in case of
> > overlapping call.
> 
> What should happen if remap_pfn_range() was used with 
> pgprot_writecombine() and later memremap() is used for instance with a 
> smaller overlappin section, or perhaps bigger?

With the fallback disabled, memremap() should fail in this case. 

Thanks,
-Toshi


From marc.zyngier at arm.com  Tue Aug 11 15:48:01 2015
From: marc.zyngier at arm.com (Marc Zyngier)
Date: Tue, 11 Aug 2015 23:48:01 +0100
Subject: [PATCH v4 00/10] ACPI GIC Self-probing, GICv2m and GICv3 support
In-Reply-To: <55CA78DE.1000306@codeaurora.org>
References: <1438164539-29256-1-git-send-email-hanjun.guo@linaro.org>
 <55CA70D5.6040300@codeaurora.org> <20150811232523.60d192d2@arm.com>
 <55CA78DE.1000306@codeaurora.org>
Message-ID: <20150811234801.51108784@arm.com>

On Tue, 11 Aug 2015 23:36:14 +0100
Timur Tabi <timur at codeaurora.org> wrote:

> On 08/11/2015 05:25 PM, Marc Zyngier wrote:
> > My branch, as far as I can tell by looking at my own git tree, is based
> > on v4.2-rc2. As for "the LEG kernel", I have no idea what that is. I
> > only work on this thing called "the Linux kernel". You may have heard
> > of it!;-)
> 
> Then what is this:
> 
> git://git.linaro.org/leg/acpi/acpi.git
>                       ^^^
> 
> This is your tree, isn't it?  

My tree would have "maz" in it, and would rather be hosted on
kernel.org.

> Hanjun said, "Patches are on top of Marc's 
> branch irq/gsi-irq-domain-v2, and available at: 
> git://git.linaro.org/leg/acpi/acpi.git gsi-irqdomain".

I don't see any contradiction here. Hanjun picked the patches from my
own branch in my own tree, put his own patches on top, and pushed that
out on an branch called gsi-irqdomain that is definitely based on
4.2-rc2. I have no idea where your 3.9-rc7 comes from.

	M.
-- 
Jazz is not dead. It just smells funny.


From sboyd at codeaurora.org  Tue Aug 11 15:49:02 2015
From: sboyd at codeaurora.org (Stephen Boyd)
Date: Tue, 11 Aug 2015 15:49:02 -0700
Subject: [PATCH 5/9] clk: qcom: gcc-msm8960: add child devices support.
In-Reply-To: <1436348838-22671-6-git-send-email-rnayak@codeaurora.org>
References: <1436348838-22671-1-git-send-email-rnayak@codeaurora.org>
 <1436348838-22671-6-git-send-email-rnayak@codeaurora.org>
Message-ID: <20150811224902.GO2839@codeaurora.org>

On 07/08, Rajendra Nayak wrote:
> diff --git a/drivers/clk/qcom/gcc-msm8960.c b/drivers/clk/qcom/gcc-msm8960.c
> index eb6a4f9..2c80d03 100644
> --- a/drivers/clk/qcom/gcc-msm8960.c
> +++ b/drivers/clk/qcom/gcc-msm8960.c
> @@ -15,6 +15,7 @@
>  #include <linux/bitops.h>
>  #include <linux/err.h>
>  #include <linux/platform_device.h>
> +#include <linux/of_platform.h>
>  #include <linux/module.h>
>  #include <linux/of.h>
>  #include <linux/of_device.h>
> @@ -3520,7 +3521,8 @@ static int gcc_msm8960_probe(struct platform_device *pdev)
>  	if (IS_ERR(clk))
>  		return PTR_ERR(clk);
>  
> -	return qcom_cc_probe(pdev, match->data);
> +	qcom_cc_probe(pdev, match->data);
> +	return of_platform_populate(pdev->dev.of_node, NULL, NULL, &pdev->dev);

We just lost the error code from qcom_cc_probe()...

Also, I don't like having a subnode in DT. Why can't we use the
same node as the GCC node and create a virtual child device here
for tsens? We can assign the same of_node that this platform
device has so that DT keeps working correctly.

-- 
Qualcomm Innovation Center, Inc. is a member of Code Aurora Forum,
a Linux Foundation Collaborative Project


From dianders at chromium.org  Tue Aug 11 15:52:36 2015
From: dianders at chromium.org (Doug Anderson)
Date: Tue, 11 Aug 2015 15:52:36 -0700
Subject: [PATCH v5 1/2] clk: rockchip: add pclk_pd_pmu to the list of
 rk3288 critical clocks
In-Reply-To: <1439287924-6988-1-git-send-email-hl@rock-chips.com>
References: <1439287924-6988-1-git-send-email-hl@rock-chips.com>
Message-ID: <CAD=FV=Wm1NMqoGvCZ4pimB2d9gQEF9PJCCCdqdEBDa5Q=bHcCw@mail.gmail.com>

Hi,

On Tue, Aug 11, 2015 at 3:12 AM, Lin Huang <hl at rock-chips.com> wrote:
> From: Heiko Stuebner <heiko at sntech.de>
>
> pclk_pd_pmu needs to keep running and with the upcoming gpio clock
> handling this is not always the case anymore. So add it to the list
> of critical clocks for now.
>
> Signed-off-by: Heiko Stuebner <heiko at sntech.de>
> Signed-off-by: Lin Huang <hl at rock-chips.com>
> ---
> Changes in v5:
> - Add From: Heiko Stuebner <heiko at sntech.de>
> - Add Signed-off-by: Heiko Stuebner <heiko at sntech.de>
>
>  drivers/clk/rockchip/clk-rk3288.c | 1 +
>  1 file changed, 1 insertion(+)

You forgot to carry forward my reviewed by:

Reviewed-by: Douglas Anderson <dianders at chromium.org>


From mcgrof at suse.com  Tue Aug 11 15:52:51 2015
From: mcgrof at suse.com (Luis R. Rodriguez)
Date: Tue, 11 Aug 2015 15:52:51 -0700
Subject: [PATCH v2 08/25] arch: introduce memremap()
In-Reply-To: <1439332857.24434.37.camel@hp.com>
References: <20150726172527.GA29513@lst.de>
 <CAPcyv4igoopDPpcCRU1TNYdwPhiYdcDiRA7L9Jdian=0rtexRg@mail.gmail.com>
 <20150727051258.GB15836@lst.de>
 <CAPcyv4jN6jYzw11qOOR-xd_w6s5dguQSoHyvmPFSWtL9S+tz3w@mail.gmail.com>
 <20150729065004.GA17162@lst.de> <20150729182712.GI30479@wotan.suse.de>
 <CAPcyv4iAeMAmU1QRZ1=WTav0cg2=-gqzzrt3nMC1QoD1+hOeBg@mail.gmail.com>
 <1438203638.3214.418.camel@hp.com> <20150729214358.GK30479@wotan.suse.de>
 <1438214404.3214.438.camel@hp.com> <20150811213021.GD30479@wotan.suse.de>
 <1439332857.24434.37.camel@hp.com>
Message-ID: <CAB=NE6U+k5mucfGOhuFoayZB48YMJ0d6o0o8Xe4jH=3ZNgrf-g@mail.gmail.com>

On Tue, Aug 11, 2015 at 3:40 PM, Toshi Kani <toshi.kani at hp.com> wrote:
> On Tue, 2015-08-11 at 23:30 +0200, Luis R. Rodriguez wrote:
>> On Wed, Jul 29, 2015 at 06:00:04PM -0600, Toshi Kani wrote:
>> > On Wed, 2015-07-29 at 23:43 +0200, Luis R. Rodriguez wrote:
>> > > On Wed, Jul 29, 2015 at 03:00:38PM -0600, Toshi Kani wrote:
>> > > > On Wed, 2015-07-29 at 11:33 -0700, Dan Williams wrote:
>   :
>> > > That would depend on the purpose of the region and the driver
>> > > developer should in theory know best. One issue with this of course is
>> > > that, as we've discovered, the semantics of on the ioremap*() variant
>> > > front regarding cache types is not clearly well defined, or at least
>> > > it may be only well defined implicitly on x86 only, so the driver
>> > > developer can only *hope* for the best across architectures. Our
>> > > ambiguity on our semantics on ioremap*() variants therefore means
>> > > driver developers can resonably be puzzled by what fallbacks to use.
>> > > That also means architectures maintainers should not whip driver
>> > > developers for any misuse. Such considerations are why although we're
>> > > now revisiting semantics for ioremap*() variants I was in hopes we
>> > > could be at least somewhat pedantic about memremap() semantics.
>> >
>> > I agree.  However, there are a few exceptions like /dev/mem, which can
>> > map a target range without knowledge.
>>
>> Still, the expectation to require support for overlapping ioremap() calls
>> would seem to be more of an exception than the norm, so I'd argue that
>> requiring callers who know they do need overlapping support to be explicit
>> about it may help us simplify expecations on semantics in other areas of
>> the kernel.
>
> Again, I agree.  I am simply saying that the fallback in an overlapping case
> may need to remain supported for such exceptional cases, possibly with a
> separate interface.

Great.

>> > > For instance since memremap() only has 2 types right now can a
>> > > respective fallback be documented as an alternative to help with this
>> > > ? Or can we not generalize this ?  One for MEMREMAP_WB and one for
>> > > MEMREMAP_WT ?
>> >
>> > Yes, if a target range can be only mapped by memremap().  However, there
>> > is no restriction that a range can be mapped with a single interface
>> > alone.  For example, a range can be mapped with remap_pfn_range() to
>> > user space with any cache type.  So, in theory, memremap() can overlap
>> > with any other types.
>>
>> Shouldn't that be an issue or area of concern ? It seems the flakiness on
>> ioremap() and its wide array flexibility would spill over the any
>> semantics which folks would be trying to set out with memremap(). That
>> should not stop the evolution of memremap() though, just pointing out that
>> perhaps we should be a bit more restrictive over how things can criss
>> -cross and who areas can do it.
>
> reserve_pfn_range() allows the caller to specify if the fallback needs to be
> enabled or disabled with 'strict_prot'.  track_pfn_remap() called from
> remap_pfn_range() enables it, and track_pfn_copy() disables it.  I think we
> can do similar for the memremap and ioremap families as well.  The fallback
> could be set disabled in the regular interfaces, and enabled in some
> interface as necessary.  This also allows gradual transition, ex. disable in
> memremap while ioremap remains enabled for now.

Sounds sexy to me.

>> > > > ioremap() falls back to the cache type of an existing mapping to
>> > > > avoid aliasing.
>> > >
>> > > Does that assume an existing ioremap*() call was used on a bigger
>> > > range?  Do you know if that happens to only be the case for x86 (I'd
>> > > think so) or if its the same for other architectures ?
>> >
>> > In the /dev/mem example, it is remap_pfn_range().  I think other archs
>> > have the same issue, but I do not know if they fall back in case of
>> > overlapping call.
>>
>> What should happen if remap_pfn_range() was used with
>> pgprot_writecombine() and later memremap() is used for instance with a
>> smaller overlappin section, or perhaps bigger?
>
> With the fallback disabled, memremap() should fail in this case.

Excellent.

 Luis


From dianders at chromium.org  Tue Aug 11 15:56:48 2015
From: dianders at chromium.org (Doug Anderson)
Date: Tue, 11 Aug 2015 15:56:48 -0700
Subject: [PATCH v5 2/2] pinctrl: rockchip: only enable gpio clock when it
 setting
In-Reply-To: <1439287924-6988-2-git-send-email-hl@rock-chips.com>
References: <1439287924-6988-1-git-send-email-hl@rock-chips.com>
 <1439287924-6988-2-git-send-email-hl@rock-chips.com>
Message-ID: <CAD=FV=VpmoiqoNi2pEQpgbC1R6E7_+Noh0vWGE_9UyK8NZHorw@mail.gmail.com>

Hi,

On Tue, Aug 11, 2015 at 3:12 AM, Lin Huang <hl at rock-chips.com> wrote:
> gpio can keep state even the clock disable, for save power
> consumption, only enable gpio clock when it setting
>
> Signed-off-by: Lin Huang <hl at rock-chips.com>
> Reviewed-by: Heiko Stuebner <heiko at sntech.de>
> ---
> Changes in v5:
> -rebase patch
>
>  drivers/pinctrl/pinctrl-rockchip.c | 55 +++++++++++++++++++++++++++++++++++---
>  1 file changed, 51 insertions(+), 4 deletions(-)

Reviewed-by: Douglas Anderson <dianders at chromium.org>

Also in the ChromeOS 3.14 tree (where this patch has been backported):

Tested-by: Douglas Anderson <dianders at chromium.org>


From xander.huff at ni.com  Tue Aug 11 16:00:49 2015
From: xander.huff at ni.com (Xander Huff)
Date: Tue, 11 Aug 2015 18:00:49 -0500
Subject: [PATCH v4] iio: adc: xilinx-xadc: Push interrupts into hardirq context
In-Reply-To: <55C07160.5040907@metafoo.de>
References: <55C07160.5040907@metafoo.de>
Message-ID: <1439334049-28671-1-git-send-email-xander.huff@ni.com>

The driver currently registers a pair of irq handlers using
request_threaded_irq(), however the synchronization mechanism between the
hardirq and the threadedirq handler is a regular spinlock.

Unfortunately, this breaks PREEMPT_RT builds, where a spinlock can sleep,
and is thus not able to be acquired from a hardirq handler. This patch gets
rid of the threaded handler and pushes all interrupt handling into the
hardirq context, and uses request_irq().

To validate that this change has no impact on RT performance, here are
cyclictest values with no processes running:

$ sudo cyclictest -S -m -p 98
# /dev/cpu_dma_latency set to 0us
policy: fifo: loadavg: 0.00 0.01 0.05 1/174 2539
T: 0 ( 1405) P:98 I:1000 C:167010520 Min: 9 Act: 12 Avg: 12 Max: 75
T: 1 ( 1862) P:98 I:1500 C:111340339 Min: 9 Act: 12 Avg: 12 Max: 73

Then, all xadc raw handles were accessed in a continuous loop via
/sys/bus/iio/devices/iio:device0:

$ sudo cyclictest -S -m -p 98
# /dev/cpu_dma_latency set to 0us
policy: fifo: loadavg: 7.84 7.70 7.63 3/182 4260
T: 0 ( 2559) P:98 I:1000 C:241557018 Min: 11 Act: 18 Avg: 21 Max: 74
T: 1 ( 2560) P:98 I:1500 C:161038006 Min: 10 Act: 21 Avg: 20 Max: 73

Signed-off-by: Xander Huff <xander.huff at ni.com>
---
 drivers/iio/adc/xilinx-xadc-core.c | 37 ++++++++++---------------------------
 drivers/iio/adc/xilinx-xadc.h      |  2 --
 2 files changed, 10 insertions(+), 29 deletions(-)

diff --git a/drivers/iio/adc/xilinx-xadc-core.c b/drivers/iio/adc/xilinx-xadc-core.c
index ce93bd8..0370624 100644
--- a/drivers/iio/adc/xilinx-xadc-core.c
+++ b/drivers/iio/adc/xilinx-xadc-core.c
@@ -273,33 +273,13 @@ static void xadc_zynq_unmask_worker(struct work_struct *work)
 		schedule_delayed_work(&xadc->zynq_unmask_work,
 				msecs_to_jiffies(XADC_ZYNQ_UNMASK_TIMEOUT));
 	}
-}
-
-static irqreturn_t xadc_zynq_threaded_interrupt_handler(int irq, void *devid)
-{
-	struct iio_dev *indio_dev = devid;
-	struct xadc *xadc = iio_priv(indio_dev);
-	unsigned int alarm;
-
-	spin_lock_irq(&xadc->lock);
-	alarm = xadc->zynq_alarm;
-	xadc->zynq_alarm = 0;
-	spin_unlock_irq(&xadc->lock);
-
-	xadc_handle_events(indio_dev, xadc_zynq_transform_alarm(alarm));
 
-	/* unmask the required interrupts in timer. */
-	schedule_delayed_work(&xadc->zynq_unmask_work,
-			msecs_to_jiffies(XADC_ZYNQ_UNMASK_TIMEOUT));
-
-	return IRQ_HANDLED;
 }
 
 static irqreturn_t xadc_zynq_interrupt_handler(int irq, void *devid)
 {
 	struct iio_dev *indio_dev = devid;
 	struct xadc *xadc = iio_priv(indio_dev);
-	irqreturn_t ret = IRQ_HANDLED;
 	uint32_t status;
 
 	xadc_read_reg(xadc, XADC_ZYNQ_REG_INTSTS, &status);
@@ -321,18 +301,23 @@ static irqreturn_t xadc_zynq_interrupt_handler(int irq, void *devid)
 
 	status &= XADC_ZYNQ_INT_ALARM_MASK;
 	if (status) {
-		xadc->zynq_alarm |= status;
 		xadc->zynq_masked_alarm |= status;
 		/*
 		 * mask the current event interrupt,
 		 * unmask it when the interrupt is no more active.
 		 */
 		xadc_zynq_update_intmsk(xadc, 0, 0);
-		ret = IRQ_WAKE_THREAD;
+
+		xadc_handle_events(indio_dev,
+				xadc_zynq_transform_alarm(status));
+
+		/* unmask the required interrupts in timer. */
+		schedule_delayed_work(&xadc->zynq_unmask_work,
+				msecs_to_jiffies(XADC_ZYNQ_UNMASK_TIMEOUT));
 	}
 	spin_unlock(&xadc->lock);
 
-	return ret;
+	return IRQ_HANDLED;
 }
 
 #define XADC_ZYNQ_TCK_RATE_MAX 50000000
@@ -437,7 +422,6 @@ static const struct xadc_ops xadc_zynq_ops = {
 	.setup = xadc_zynq_setup,
 	.get_dclk_rate = xadc_zynq_get_dclk_rate,
 	.interrupt_handler = xadc_zynq_interrupt_handler,
-	.threaded_interrupt_handler = xadc_zynq_threaded_interrupt_handler,
 	.update_alarm = xadc_zynq_update_alarm,
 };
 
@@ -1225,9 +1209,8 @@ static int xadc_probe(struct platform_device *pdev)
 	if (ret)
 		goto err_free_samplerate_trigger;
 
-	ret = request_threaded_irq(irq, xadc->ops->interrupt_handler,
-				xadc->ops->threaded_interrupt_handler,
-				0, dev_name(&pdev->dev), indio_dev);
+	ret = request_irq(irq, xadc->ops->interrupt_handler, 0,
+			dev_name(&pdev->dev), indio_dev);
 	if (ret)
 		goto err_clk_disable_unprepare;
 
diff --git a/drivers/iio/adc/xilinx-xadc.h b/drivers/iio/adc/xilinx-xadc.h
index 54adc50..f6f0819 100644
--- a/drivers/iio/adc/xilinx-xadc.h
+++ b/drivers/iio/adc/xilinx-xadc.h
@@ -60,7 +60,6 @@ struct xadc {
 
 	enum xadc_external_mux_mode external_mux_mode;
 
-	unsigned int zynq_alarm;
 	unsigned int zynq_masked_alarm;
 	unsigned int zynq_intmask;
 	struct delayed_work zynq_unmask_work;
@@ -79,7 +78,6 @@ struct xadc_ops {
 	void (*update_alarm)(struct xadc *, unsigned int);
 	unsigned long (*get_dclk_rate)(struct xadc *);
 	irqreturn_t (*interrupt_handler)(int, void *);
-	irqreturn_t (*threaded_interrupt_handler)(int, void *);
 
 	unsigned int flags;
 };
-- 
1.9.1



From sboyd at codeaurora.org  Tue Aug 11 16:01:43 2015
From: sboyd at codeaurora.org (Stephen Boyd)
Date: Tue, 11 Aug 2015 16:01:43 -0700
Subject: [PATCH v5 1/2] clk: rockchip: add pclk_pd_pmu to the list of
 rk3288 critical clocks
In-Reply-To: <1439287924-6988-1-git-send-email-hl@rock-chips.com>
References: <1439287924-6988-1-git-send-email-hl@rock-chips.com>
Message-ID: <55CA7ED7.90003@codeaurora.org>

On 08/11/2015 03:12 AM, Lin Huang wrote:
> From: Heiko Stuebner <heiko at sntech.de>
>
> pclk_pd_pmu needs to keep running and with the upcoming gpio clock
> handling this is not always the case anymore. So add it to the list
> of critical clocks for now.
>
> Signed-off-by: Heiko Stuebner <heiko at sntech.de>
> Signed-off-by: Lin Huang <hl at rock-chips.com>
> ---
>

Acked-by: Stephen Boyd <sboyd at codeaurora.org>

-- 
Qualcomm Innovation Center, Inc. is a member of Code Aurora Forum,
a Linux Foundation Collaborative Project



From dan.j.williams at intel.com  Tue Aug 11 16:13:44 2015
From: dan.j.williams at intel.com (Dan Williams)
Date: Tue, 11 Aug 2015 16:13:44 -0700
Subject: [PATCH v2 08/25] arch: introduce memremap()
In-Reply-To: <CAB=NE6U+k5mucfGOhuFoayZB48YMJ0d6o0o8Xe4jH=3ZNgrf-g@mail.gmail.com>
References: <20150726172527.GA29513@lst.de>
 <CAPcyv4igoopDPpcCRU1TNYdwPhiYdcDiRA7L9Jdian=0rtexRg@mail.gmail.com>
 <20150727051258.GB15836@lst.de>
 <CAPcyv4jN6jYzw11qOOR-xd_w6s5dguQSoHyvmPFSWtL9S+tz3w@mail.gmail.com>
 <20150729065004.GA17162@lst.de>
 <20150729182712.GI30479@wotan.suse.de>
 <CAPcyv4iAeMAmU1QRZ1=WTav0cg2=-gqzzrt3nMC1QoD1+hOeBg@mail.gmail.com>
 <1438203638.3214.418.camel@hp.com>
 <20150729214358.GK30479@wotan.suse.de>
 <1438214404.3214.438.camel@hp.com>
 <20150811213021.GD30479@wotan.suse.de>
 <1439332857.24434.37.camel@hp.com>
 <CAB=NE6U+k5mucfGOhuFoayZB48YMJ0d6o0o8Xe4jH=3ZNgrf-g@mail.gmail.com>
Message-ID: <CAPcyv4g0-CcFRCWPBdKB7h0zZEO5qzT-N9YLYJw9sb=_HYnXiA@mail.gmail.com>

On Tue, Aug 11, 2015 at 3:52 PM, Luis R. Rodriguez <mcgrof at suse.com> wrote:
> On Tue, Aug 11, 2015 at 3:40 PM, Toshi Kani <toshi.kani at hp.com> wrote:
>> On Tue, 2015-08-11 at 23:30 +0200, Luis R. Rodriguez wrote:
>>> On Wed, Jul 29, 2015 at 06:00:04PM -0600, Toshi Kani wrote:
>>> > On Wed, 2015-07-29 at 23:43 +0200, Luis R. Rodriguez wrote:
>>> > > On Wed, Jul 29, 2015 at 03:00:38PM -0600, Toshi Kani wrote:
>>> > > > On Wed, 2015-07-29 at 11:33 -0700, Dan Williams wrote:
>>   :
>>> > > That would depend on the purpose of the region and the driver
>>> > > developer should in theory know best. One issue with this of course is
>>> > > that, as we've discovered, the semantics of on the ioremap*() variant
>>> > > front regarding cache types is not clearly well defined, or at least
>>> > > it may be only well defined implicitly on x86 only, so the driver
>>> > > developer can only *hope* for the best across architectures. Our
>>> > > ambiguity on our semantics on ioremap*() variants therefore means
>>> > > driver developers can resonably be puzzled by what fallbacks to use.
>>> > > That also means architectures maintainers should not whip driver
>>> > > developers for any misuse. Such considerations are why although we're
>>> > > now revisiting semantics for ioremap*() variants I was in hopes we
>>> > > could be at least somewhat pedantic about memremap() semantics.
>>> >
>>> > I agree.  However, there are a few exceptions like /dev/mem, which can
>>> > map a target range without knowledge.
>>>
>>> Still, the expectation to require support for overlapping ioremap() calls
>>> would seem to be more of an exception than the norm, so I'd argue that
>>> requiring callers who know they do need overlapping support to be explicit
>>> about it may help us simplify expecations on semantics in other areas of
>>> the kernel.
>>
>> Again, I agree.  I am simply saying that the fallback in an overlapping case
>> may need to remain supported for such exceptional cases, possibly with a
>> separate interface.
>
> Great.
>
>>> > > For instance since memremap() only has 2 types right now can a
>>> > > respective fallback be documented as an alternative to help with this
>>> > > ? Or can we not generalize this ?  One for MEMREMAP_WB and one for
>>> > > MEMREMAP_WT ?
>>> >
>>> > Yes, if a target range can be only mapped by memremap().  However, there
>>> > is no restriction that a range can be mapped with a single interface
>>> > alone.  For example, a range can be mapped with remap_pfn_range() to
>>> > user space with any cache type.  So, in theory, memremap() can overlap
>>> > with any other types.
>>>
>>> Shouldn't that be an issue or area of concern ? It seems the flakiness on
>>> ioremap() and its wide array flexibility would spill over the any
>>> semantics which folks would be trying to set out with memremap(). That
>>> should not stop the evolution of memremap() though, just pointing out that
>>> perhaps we should be a bit more restrictive over how things can criss
>>> -cross and who areas can do it.
>>
>> reserve_pfn_range() allows the caller to specify if the fallback needs to be
>> enabled or disabled with 'strict_prot'.  track_pfn_remap() called from
>> remap_pfn_range() enables it, and track_pfn_copy() disables it.  I think we
>> can do similar for the memremap and ioremap families as well.  The fallback
>> could be set disabled in the regular interfaces, and enabled in some
>> interface as necessary.  This also allows gradual transition, ex. disable in
>> memremap while ioremap remains enabled for now.
>
> Sounds sexy to me.

Cool, sounds like something we can tackle in 4.4 along with the
ioremap_cache removal cleanups.


From mturquette at baylibre.com  Tue Aug 11 16:14:16 2015
From: mturquette at baylibre.com (Michael Turquette)
Date: Tue, 11 Aug 2015 16:14:16 -0700
Subject: [PATCH] drivers/clk: appropriate __init annotation for const data
In-Reply-To: <alpine.LFD.2.20.1507281430130.26147@knanqh.ubzr>
References: <alpine.LFD.2.20.1507281430130.26147@knanqh.ubzr>
Message-ID: <20150811231416.31346.83289@quantum>

Quoting Nicolas Pitre (2015-07-28 16:43:20)
> 
> Init data marked const should be annotated with __initconst for
> correctness and not __initdata.  This also fixes LTO builds that
> otherwise fail with section mismatch errors.
> 
> Signed-off-by: Nicolas Pitre <nico at linaro.org>

Thanks for the patch Nico. Applied.

Regards,
Mike

> 
> diff --git a/drivers/clk/clk-asm9260.c b/drivers/clk/clk-asm9260.c
> index 90897af8d9..25308ce09a 100644
> --- a/drivers/clk/clk-asm9260.c
> +++ b/drivers/clk/clk-asm9260.c
> @@ -244,10 +244,10 @@ static const struct asm9260_gate_data asm9260_ahb_gates[] __initconst = {
>                 HW_AHBCLKCTRL1, 16 },
>  };
>  
> -static const char __initdata *main_mux_p[] =   { NULL, NULL };
> -static const char __initdata *i2s0_mux_p[] =   { NULL, NULL, "i2s0m_div"};
> -static const char __initdata *i2s1_mux_p[] =   { NULL, NULL, "i2s1m_div"};
> -static const char __initdata *clkout_mux_p[] = { NULL, NULL, "rtc"};
> +static const char *const main_mux_p[] __initconst =   { NULL, NULL };
> +static const char *const i2s0_mux_p[] __initconst =   { NULL, NULL, "i2s0m_div"};
> +static const char *const i2s1_mux_p[] __initconst =   { NULL, NULL, "i2s1m_div"};
> +static const char *const clkout_mux_p[] __initconst = { NULL, NULL, "rtc"};
>  static u32 three_mux_table[] = {0, 1, 3};
>  
>  static struct asm9260_mux_clock asm9260_mux_clks[] __initdata = {
> diff --git a/drivers/clk/clk-stm32f4.c b/drivers/clk/clk-stm32f4.c
> index 3f6f7ad394..c316454ef8 100644
> --- a/drivers/clk/clk-stm32f4.c
> +++ b/drivers/clk/clk-stm32f4.c
> @@ -293,7 +293,7 @@ stm32f4_rcc_lookup_clk(struct of_phandle_args *clkspec, void *data)
>         return clks[i];
>  }
>  
> -static const char *sys_parents[] __initdata =   { "hsi", NULL, "pll" };
> +static const char *const sys_parents[] __initconst =   { "hsi", NULL, "pll" };
>  
>  static const struct clk_div_table ahb_div_table[] = {
>         { 0x0,   1 }, { 0x1,   1 }, { 0x2,   1 }, { 0x3,   1 },
> diff --git a/drivers/clk/hisilicon/clk-hi6220.c b/drivers/clk/hisilicon/clk-hi6220.c
> index 4563343b64..d7c7d73bd3 100644
> --- a/drivers/clk/hisilicon/clk-hi6220.c
> +++ b/drivers/clk/hisilicon/clk-hi6220.c
> @@ -91,23 +91,23 @@ CLK_OF_DECLARE(hi6220_clk_ao, "hisilicon,hi6220-aoctrl", hi6220_clk_ao_init);
>  
>  
>  /* clocks in sysctrl */
> -static const char *mmc0_mux0_p[] __initdata = { "pll_ddr_gate", "syspll", };
> -static const char *mmc0_mux1_p[] __initdata = { "mmc0_mux0", "pll_media_gate", };
> -static const char *mmc0_src_p[] __initdata = { "mmc0srcsel", "mmc0_div", };
> -static const char *mmc1_mux0_p[] __initdata = { "pll_ddr_gate", "syspll", };
> -static const char *mmc1_mux1_p[] __initdata = { "mmc1_mux0", "pll_media_gate", };
> -static const char *mmc1_src_p[]  __initdata = { "mmc1srcsel", "mmc1_div", };
> -static const char *mmc2_mux0_p[] __initdata = { "pll_ddr_gate", "syspll", };
> -static const char *mmc2_mux1_p[] __initdata = { "mmc2_mux0", "pll_media_gate", };
> -static const char *mmc2_src_p[]  __initdata = { "mmc2srcsel", "mmc2_div", };
> -static const char *mmc0_sample_in[] __initdata = { "mmc0_sample", "mmc0_pad", };
> -static const char *mmc1_sample_in[] __initdata = { "mmc1_sample", "mmc1_pad", };
> -static const char *mmc2_sample_in[] __initdata = { "mmc2_sample", "mmc2_pad", };
> -static const char *uart1_src[] __initdata = { "clk_tcxo", "clk_150m", };
> -static const char *uart2_src[] __initdata = { "clk_tcxo", "clk_150m", };
> -static const char *uart3_src[] __initdata = { "clk_tcxo", "clk_150m", };
> -static const char *uart4_src[] __initdata = { "clk_tcxo", "clk_150m", };
> -static const char *hifi_src[] __initdata = { "syspll", "pll_media_gate", };
> +static const char *const mmc0_mux0_p[] __initconst = { "pll_ddr_gate", "syspll", };
> +static const char *const mmc0_mux1_p[] __initconst = { "mmc0_mux0", "pll_media_gate", };
> +static const char *const mmc0_src_p[] __initconst = { "mmc0srcsel", "mmc0_div", };
> +static const char *const mmc1_mux0_p[] __initconst = { "pll_ddr_gate", "syspll", };
> +static const char *const mmc1_mux1_p[] __initconst = { "mmc1_mux0", "pll_media_gate", };
> +static const char *const mmc1_src_p[]  __initconst = { "mmc1srcsel", "mmc1_div", };
> +static const char *const mmc2_mux0_p[] __initconst = { "pll_ddr_gate", "syspll", };
> +static const char *const mmc2_mux1_p[] __initconst = { "mmc2_mux0", "pll_media_gate", };
> +static const char *const mmc2_src_p[]  __initconst = { "mmc2srcsel", "mmc2_div", };
> +static const char *const mmc0_sample_in[] __initconst = { "mmc0_sample", "mmc0_pad", };
> +static const char *const mmc1_sample_in[] __initconst = { "mmc1_sample", "mmc1_pad", };
> +static const char *const mmc2_sample_in[] __initconst = { "mmc2_sample", "mmc2_pad", };
> +static const char *const uart1_src[] __initconst = { "clk_tcxo", "clk_150m", };
> +static const char *const uart2_src[] __initconst = { "clk_tcxo", "clk_150m", };
> +static const char *const uart3_src[] __initconst = { "clk_tcxo", "clk_150m", };
> +static const char *const uart4_src[] __initconst = { "clk_tcxo", "clk_150m", };
> +static const char *const hifi_src[] __initconst = { "syspll", "pll_media_gate", };
>  
>  static struct hisi_gate_clock hi6220_separated_gate_clks_sys[] __initdata = {
>         { HI6220_MMC0_CLK,      "mmc0_clk",      "mmc0_src",       CLK_SET_RATE_PARENT|CLK_IGNORE_UNUSED, 0x200, 0,  0, },
> @@ -197,9 +197,9 @@ CLK_OF_DECLARE(hi6220_clk_sys, "hisilicon,hi6220-sysctrl", hi6220_clk_sys_init);
>  
>  
>  /* clocks in media controller */
> -static const char *clk_1000_1200_src[] __initdata = { "pll_gpu_gate", "media_syspll_src", };
> -static const char *clk_1440_1200_src[] __initdata = { "media_syspll_src", "media_pll_src", };
> -static const char *clk_1000_1440_src[] __initdata = { "pll_gpu_gate", "media_pll_src", };
> +static const char *const clk_1000_1200_src[] __initconst = { "pll_gpu_gate", "media_syspll_src", };
> +static const char *const clk_1440_1200_src[] __initconst = { "media_syspll_src", "media_pll_src", };
> +static const char *const clk_1000_1440_src[] __initconst = { "pll_gpu_gate", "media_pll_src", };
>  
>  static struct hisi_gate_clock hi6220_separated_gate_clks_media[] __initdata = {
>         { HI6220_DSI_PCLK,       "dsi_pclk",         "vpucodec",      CLK_SET_RATE_PARENT|CLK_IGNORE_UNUSED, 0x520, 0,  0, },
> diff --git a/drivers/clk/versatile/clk-realview.c b/drivers/clk/versatile/clk-realview.c
> index c8b523117f..0c1f224515 100644
> --- a/drivers/clk/versatile/clk-realview.c
> +++ b/drivers/clk/versatile/clk-realview.c
> @@ -33,13 +33,13 @@ static const struct icst_params realview_oscvco_params = {
>         .idx2s          = icst307_idx2s,
>  };
>  
> -static const struct clk_icst_desc __initdata realview_osc0_desc = {
> +static const struct clk_icst_desc realview_osc0_desc __initconst = {
>         .params = &realview_oscvco_params,
>         .vco_offset = REALVIEW_SYS_OSC0_OFFSET,
>         .lock_offset = REALVIEW_SYS_LOCK_OFFSET,
>  };
>  
> -static const struct clk_icst_desc __initdata realview_osc4_desc = {
> +static const struct clk_icst_desc realview_osc4_desc __initconst = {
>         .params = &realview_oscvco_params,
>         .vco_offset = REALVIEW_SYS_OSC4_OFFSET,
>         .lock_offset = REALVIEW_SYS_LOCK_OFFSET,
> diff --git a/drivers/clk/versatile/clk-versatile.c b/drivers/clk/versatile/clk-versatile.c
> index 7a4f8635bd..81d59eada2 100644
> --- a/drivers/clk/versatile/clk-versatile.c
> +++ b/drivers/clk/versatile/clk-versatile.c
> @@ -35,7 +35,7 @@ static const struct icst_params cp_auxosc_params = {
>         .idx2s          = icst525_idx2s,
>  };
>  
> -static const struct clk_icst_desc __initdata cm_auxosc_desc = {
> +static const struct clk_icst_desc cm_auxosc_desc __initconst = {
>         .params = &cp_auxosc_params,
>         .vco_offset = 0x1c,
>         .lock_offset = INTEGRATOR_HDR_LOCK_OFFSET,
> 
> _______________________________________________
> linux-arm-kernel mailing list
> linux-arm-kernel at lists.infradead.org
> http://lists.infradead.org/mailman/listinfo/linux-arm-kernel


From mturquette at baylibre.com  Tue Aug 11 16:19:32 2015
From: mturquette at baylibre.com (Michael Turquette)
Date: Tue, 11 Aug 2015 16:19:32 -0700
Subject: [PATCH v2 7/7] clk: sunxi: Add a simple gates driver
In-Reply-To: <1438364782-3968-8-git-send-email-maxime.ripard@free-electrons.com>
References: <1438364782-3968-1-git-send-email-maxime.ripard@free-electrons.com>
 <1438364782-3968-8-git-send-email-maxime.ripard@free-electrons.com>
Message-ID: <CAEG3pNB8k-kjAPNSFAOJbkNYRp5zNc6UCh3CLLiQZ2R=rGvhqQ@mail.gmail.com>

On Fri, Jul 31, 2015 at 10:46 AM, Maxime Ripard
<maxime.ripard at free-electrons.com> wrote:
> The gates were handled with a common piece of framework that was
> registering all gates array, that was not using the CLK_OF_DECLARE logic,
> and was not using clock-indices but some private masks that were pretty
> much equivalent.
>
> Move this code in a new driver that handles all the gates array and solves
> both these issues.
>
> Signed-off-by: Maxime Ripard <maxime.ripard at free-electrons.com>

FYI a small fix was rolled into this patch. It was missing clk.h since
we removed that from clk-provider.h.

Regards,
Mike

> ---
>  drivers/clk/sunxi/Makefile           |   1 +
>  drivers/clk/sunxi/clk-simple-gates.c | 157 +++++++++++++++++++++++++++++++
>  drivers/clk/sunxi/clk-sunxi.c        | 177 -----------------------------------
>  3 files changed, 158 insertions(+), 177 deletions(-)
>  create mode 100644 drivers/clk/sunxi/clk-simple-gates.c
>
> diff --git a/drivers/clk/sunxi/Makefile b/drivers/clk/sunxi/Makefile
> index 058f273d6154..f5a35b82cc1a 100644
> --- a/drivers/clk/sunxi/Makefile
> +++ b/drivers/clk/sunxi/Makefile
> @@ -6,6 +6,7 @@ obj-y += clk-sunxi.o clk-factors.o
>  obj-y += clk-a10-hosc.o
>  obj-y += clk-a20-gmac.o
>  obj-y += clk-mod0.o
> +obj-y += clk-simple-gates.o
>  obj-y += clk-sun8i-mbus.o
>  obj-y += clk-sun9i-core.o
>  obj-y += clk-sun9i-mmc.o
> diff --git a/drivers/clk/sunxi/clk-simple-gates.c b/drivers/clk/sunxi/clk-simple-gates.c
> new file mode 100644
> index 000000000000..39e57e3d745c
> --- /dev/null
> +++ b/drivers/clk/sunxi/clk-simple-gates.c
> @@ -0,0 +1,157 @@
> +/*
> + * Copyright 2015 Maxime Ripard
> + *
> + * Maxime Ripard <maxime.ripard at free-electrons.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/slab.h>
> +#include <linux/spinlock.h>
> +
> +static DEFINE_SPINLOCK(gates_lock);
> +
> +static void __init sunxi_simple_gates_setup(struct device_node *node,
> +                                           const int protected[],
> +                                           int nprotected)
> +{
> +       struct clk_onecell_data *clk_data;
> +       const char *clk_parent, *clk_name;
> +       struct property *prop;
> +       struct resource res;
> +       void __iomem *clk_reg;
> +       void __iomem *reg;
> +       const __be32 *p;
> +       int number, i = 0, j;
> +       u8 clk_bit;
> +       u32 index;
> +
> +       reg = of_io_request_and_map(node, 0, of_node_full_name(node));
> +       if (IS_ERR(reg))
> +               return;
> +
> +       clk_parent = of_clk_get_parent_name(node, 0);
> +
> +       clk_data = kmalloc(sizeof(struct clk_onecell_data), GFP_KERNEL);
> +       if (!clk_data)
> +               goto err_unmap;
> +
> +       number = of_property_count_u32_elems(node, "clock-indices");
> +       of_property_read_u32_index(node, "clock-indices", number - 1, &number);
> +
> +       clk_data->clks = kcalloc(number + 1, sizeof(struct clk *), GFP_KERNEL);
> +       if (!clk_data->clks)
> +               goto err_free_data;
> +
> +       of_property_for_each_u32(node, "clock-indices", prop, p, index) {
> +               of_property_read_string_index(node, "clock-output-names",
> +                                             i, &clk_name);
> +
> +               clk_reg = reg + 4 * (index / 32);
> +               clk_bit = index % 32;
> +
> +               clk_data->clks[index] = clk_register_gate(NULL, clk_name,
> +                                                         clk_parent, 0,
> +                                                         clk_reg,
> +                                                         clk_bit,
> +                                                         0, &gates_lock);
> +               i++;
> +
> +               if (IS_ERR(clk_data->clks[index])) {
> +                       WARN_ON(true);
> +                       continue;
> +               }
> +
> +               for (j = 0; j < nprotected; j++)
> +                       if (protected[j] == index)
> +                               clk_prepare_enable(clk_data->clks[index]);
> +
> +       }
> +
> +       clk_data->clk_num = number + 1;
> +       of_clk_add_provider(node, of_clk_src_onecell_get, clk_data);
> +
> +       return;
> +
> +err_free_data:
> +       kfree(clk_data);
> +err_unmap:
> +       iounmap(reg);
> +       of_address_to_resource(node, 0, &res);
> +       release_mem_region(res.start, resource_size(&res));
> +}
> +
> +static void __init sunxi_simple_gates_init(struct device_node *node)
> +{
> +       sunxi_simple_gates_setup(node, NULL, 0);
> +}
> +
> +CLK_OF_DECLARE(sun4i_a10_apb0, "allwinner,sun4i-a10-apb0-gates-clk",
> +              sunxi_simple_gates_init);
> +CLK_OF_DECLARE(sun4i_a10_apb1, "allwinner,sun4i-a10-apb1-gates-clk",
> +              sunxi_simple_gates_init);
> +CLK_OF_DECLARE(sun4i_a10_axi, "allwinner,sun4i-a10-axi-gates-clk",
> +              sunxi_simple_gates_init);
> +CLK_OF_DECLARE(sun5i_a10s_apb0, "allwinner,sun5i-a10s-apb0-gates-clk",
> +              sunxi_simple_gates_init);
> +CLK_OF_DECLARE(sun5i_a10s_apb1, "allwinner,sun5i-a10s-apb1-gates-clk",
> +              sunxi_simple_gates_init);
> +CLK_OF_DECLARE(sun5i_a13_apb0, "allwinner,sun5i-a13-apb0-gates-clk",
> +              sunxi_simple_gates_init);
> +CLK_OF_DECLARE(sun5i_a13_apb1, "allwinner,sun5i-a13-apb1-gates-clk",
> +              sunxi_simple_gates_init);
> +CLK_OF_DECLARE(sun6i_a31_ahb1, "allwinner,sun6i-a31-ahb1-gates-clk",
> +              sunxi_simple_gates_init);
> +CLK_OF_DECLARE(sun6i_a31_apb1, "allwinner,sun6i-a31-apb1-gates-clk",
> +              sunxi_simple_gates_init);
> +CLK_OF_DECLARE(sun6i_a31_apb2, "allwinner,sun6i-a31-apb2-gates-clk",
> +              sunxi_simple_gates_init);
> +CLK_OF_DECLARE(sun7i_a20_apb0, "allwinner,sun7i-a20-apb0-gates-clk",
> +              sunxi_simple_gates_init);
> +CLK_OF_DECLARE(sun7i_a20_apb1, "allwinner,sun7i-a20-apb1-gates-clk",
> +              sunxi_simple_gates_init);
> +CLK_OF_DECLARE(sun8i_a23_ahb1, "allwinner,sun8i-a23-ahb1-gates-clk",
> +              sunxi_simple_gates_init);
> +CLK_OF_DECLARE(sun8i_a23_apb1, "allwinner,sun8i-a23-apb1-gates-clk",
> +              sunxi_simple_gates_init);
> +CLK_OF_DECLARE(sun8i_a23_apb2, "allwinner,sun8i-a23-apb2-gates-clk",
> +              sunxi_simple_gates_init);
> +CLK_OF_DECLARE(sun9i_a80_ahb0, "allwinner,sun9i-a80-ahb0-gates-clk",
> +              sunxi_simple_gates_init);
> +CLK_OF_DECLARE(sun9i_a80_ahb1, "allwinner,sun9i-a80-ahb1-gates-clk",
> +              sunxi_simple_gates_init);
> +CLK_OF_DECLARE(sun9i_a80_ahb2, "allwinner,sun9i-a80-ahb2-gates-clk",
> +              sunxi_simple_gates_init);
> +CLK_OF_DECLARE(sun9i_a80_apb0, "allwinner,sun9i-a80-apb0-gates-clk",
> +              sunxi_simple_gates_init);
> +CLK_OF_DECLARE(sun9i_a80_apb1, "allwinner,sun9i-a80-apb1-gates-clk",
> +              sunxi_simple_gates_init);
> +
> +static const int sun4i_a10_ahb_critical_clocks[] __initconst = {
> +       14,     /* ahb_sdram */
> +};
> +
> +static void __init sun4i_a10_ahb_init(struct device_node *node)
> +{
> +       sunxi_simple_gates_setup(node, sun4i_a10_ahb_critical_clocks,
> +                                ARRAY_SIZE(sun4i_a10_ahb_critical_clocks));
> +}
> +CLK_OF_DECLARE(sun4i_a10_ahb, "allwinner,sun4i-a10-ahb-gates-clk",
> +              sun4i_a10_ahb_init);
> +CLK_OF_DECLARE(sun5i_a10s_ahb, "allwinner,sun5i-a10s-ahb-gates-clk",
> +              sun4i_a10_ahb_init);
> +CLK_OF_DECLARE(sun5i_a13_ahb, "allwinner,sun5i-a13-ahb-gates-clk",
> +              sun4i_a10_ahb_init);
> +CLK_OF_DECLARE(sun7i_a20_ahb, "allwinner,sun7i-a20-ahb-gates-clk",
> +              sun4i_a10_ahb_init);
> diff --git a/drivers/clk/sunxi/clk-sunxi.c b/drivers/clk/sunxi/clk-sunxi.c
> index abf7b37faf73..1fec91093fcd 100644
> --- a/drivers/clk/sunxi/clk-sunxi.c
> +++ b/drivers/clk/sunxi/clk-sunxi.c
> @@ -900,150 +900,6 @@ struct gates_data {
>         DECLARE_BITMAP(mask, SUNXI_GATES_MAX_SIZE);
>  };
>
> -static const struct gates_data sun4i_axi_gates_data __initconst = {
> -       .mask = {1},
> -};
> -
> -static const struct gates_data sun4i_ahb_gates_data __initconst = {
> -       .mask = {0x7F77FFF, 0x14FB3F},
> -};
> -
> -static const struct gates_data sun5i_a10s_ahb_gates_data __initconst = {
> -       .mask = {0x147667e7, 0x185915},
> -};
> -
> -static const struct gates_data sun5i_a13_ahb_gates_data __initconst = {
> -       .mask = {0x107067e7, 0x185111},
> -};
> -
> -static const struct gates_data sun6i_a31_ahb1_gates_data __initconst = {
> -       .mask = {0xEDFE7F62, 0x794F931},
> -};
> -
> -static const struct gates_data sun7i_a20_ahb_gates_data __initconst = {
> -       .mask = { 0x12f77fff, 0x16ff3f },
> -};
> -
> -static const struct gates_data sun8i_a23_ahb1_gates_data __initconst = {
> -       .mask = {0x25386742, 0x2505111},
> -};
> -
> -static const struct gates_data sun9i_a80_ahb0_gates_data __initconst = {
> -       .mask = {0xF5F12B},
> -};
> -
> -static const struct gates_data sun9i_a80_ahb1_gates_data __initconst = {
> -       .mask = {0x1E20003},
> -};
> -
> -static const struct gates_data sun9i_a80_ahb2_gates_data __initconst = {
> -       .mask = {0x9B7},
> -};
> -
> -static const struct gates_data sun4i_apb0_gates_data __initconst = {
> -       .mask = {0x4EF},
> -};
> -
> -static const struct gates_data sun5i_a10s_apb0_gates_data __initconst = {
> -       .mask = {0x469},
> -};
> -
> -static const struct gates_data sun5i_a13_apb0_gates_data __initconst = {
> -       .mask = {0x61},
> -};
> -
> -static const struct gates_data sun7i_a20_apb0_gates_data __initconst = {
> -       .mask = { 0x4ff },
> -};
> -
> -static const struct gates_data sun9i_a80_apb0_gates_data __initconst = {
> -       .mask = {0xEB822},
> -};
> -
> -static const struct gates_data sun4i_apb1_gates_data __initconst = {
> -       .mask = {0xFF00F7},
> -};
> -
> -static const struct gates_data sun5i_a10s_apb1_gates_data __initconst = {
> -       .mask = {0xf0007},
> -};
> -
> -static const struct gates_data sun5i_a13_apb1_gates_data __initconst = {
> -       .mask = {0xa0007},
> -};
> -
> -static const struct gates_data sun6i_a31_apb1_gates_data __initconst = {
> -       .mask = {0x3031},
> -};
> -
> -static const struct gates_data sun8i_a23_apb1_gates_data __initconst = {
> -       .mask = {0x3021},
> -};
> -
> -static const struct gates_data sun6i_a31_apb2_gates_data __initconst = {
> -       .mask = {0x3F000F},
> -};
> -
> -static const struct gates_data sun7i_a20_apb1_gates_data __initconst = {
> -       .mask = { 0xff80ff },
> -};
> -
> -static const struct gates_data sun9i_a80_apb1_gates_data __initconst = {
> -       .mask = {0x3F001F},
> -};
> -
> -static const struct gates_data sun8i_a23_apb2_gates_data __initconst = {
> -       .mask = {0x1F0007},
> -};
> -
> -static void __init sunxi_gates_clk_setup(struct device_node *node,
> -                                        struct gates_data *data)
> -{
> -       struct clk_onecell_data *clk_data;
> -       const char *clk_parent;
> -       const char *clk_name;
> -       void __iomem *reg;
> -       int qty;
> -       int i = 0;
> -       int j = 0;
> -
> -       reg = of_iomap(node, 0);
> -
> -       clk_parent = of_clk_get_parent_name(node, 0);
> -
> -       /* Worst-case size approximation and memory allocation */
> -       qty = find_last_bit(data->mask, SUNXI_GATES_MAX_SIZE);
> -       clk_data = kmalloc(sizeof(struct clk_onecell_data), GFP_KERNEL);
> -       if (!clk_data)
> -               return;
> -       clk_data->clks = kzalloc((qty+1) * sizeof(struct clk *), GFP_KERNEL);
> -       if (!clk_data->clks) {
> -               kfree(clk_data);
> -               return;
> -       }
> -
> -       for_each_set_bit(i, data->mask, SUNXI_GATES_MAX_SIZE) {
> -               of_property_read_string_index(node, "clock-output-names",
> -                                             j, &clk_name);
> -
> -               clk_data->clks[i] = clk_register_gate(NULL, clk_name,
> -                                                     clk_parent, 0,
> -                                                     reg + 4 * (i/32), i % 32,
> -                                                     0, &clk_lock);
> -               WARN_ON(IS_ERR(clk_data->clks[i]));
> -               clk_register_clkdev(clk_data->clks[i], clk_name, NULL);
> -
> -               j++;
> -       }
> -
> -       /* Adjust to the real max */
> -       clk_data->clk_num = i;
> -
> -       of_clk_add_provider(node, of_clk_src_onecell_get, clk_data);
> -}
> -
> -
> -
>  /**
>   * sunxi_divs_clk_setup() helper data
>   */
> @@ -1281,34 +1137,6 @@ static const struct of_device_id clk_mux_match[] __initconst = {
>         {}
>  };
>
> -/* Matches for gate clocks */
> -static const struct of_device_id clk_gates_match[] __initconst = {
> -       {.compatible = "allwinner,sun4i-a10-axi-gates-clk", .data = &sun4i_axi_gates_data,},
> -       {.compatible = "allwinner,sun4i-a10-ahb-gates-clk", .data = &sun4i_ahb_gates_data,},
> -       {.compatible = "allwinner,sun5i-a10s-ahb-gates-clk", .data = &sun5i_a10s_ahb_gates_data,},
> -       {.compatible = "allwinner,sun5i-a13-ahb-gates-clk", .data = &sun5i_a13_ahb_gates_data,},
> -       {.compatible = "allwinner,sun6i-a31-ahb1-gates-clk", .data = &sun6i_a31_ahb1_gates_data,},
> -       {.compatible = "allwinner,sun7i-a20-ahb-gates-clk", .data = &sun7i_a20_ahb_gates_data,},
> -       {.compatible = "allwinner,sun8i-a23-ahb1-gates-clk", .data = &sun8i_a23_ahb1_gates_data,},
> -       {.compatible = "allwinner,sun9i-a80-ahb0-gates-clk", .data = &sun9i_a80_ahb0_gates_data,},
> -       {.compatible = "allwinner,sun9i-a80-ahb1-gates-clk", .data = &sun9i_a80_ahb1_gates_data,},
> -       {.compatible = "allwinner,sun9i-a80-ahb2-gates-clk", .data = &sun9i_a80_ahb2_gates_data,},
> -       {.compatible = "allwinner,sun4i-a10-apb0-gates-clk", .data = &sun4i_apb0_gates_data,},
> -       {.compatible = "allwinner,sun5i-a10s-apb0-gates-clk", .data = &sun5i_a10s_apb0_gates_data,},
> -       {.compatible = "allwinner,sun5i-a13-apb0-gates-clk", .data = &sun5i_a13_apb0_gates_data,},
> -       {.compatible = "allwinner,sun7i-a20-apb0-gates-clk", .data = &sun7i_a20_apb0_gates_data,},
> -       {.compatible = "allwinner,sun9i-a80-apb0-gates-clk", .data = &sun9i_a80_apb0_gates_data,},
> -       {.compatible = "allwinner,sun4i-a10-apb1-gates-clk", .data = &sun4i_apb1_gates_data,},
> -       {.compatible = "allwinner,sun5i-a10s-apb1-gates-clk", .data = &sun5i_a10s_apb1_gates_data,},
> -       {.compatible = "allwinner,sun5i-a13-apb1-gates-clk", .data = &sun5i_a13_apb1_gates_data,},
> -       {.compatible = "allwinner,sun6i-a31-apb1-gates-clk", .data = &sun6i_a31_apb1_gates_data,},
> -       {.compatible = "allwinner,sun7i-a20-apb1-gates-clk", .data = &sun7i_a20_apb1_gates_data,},
> -       {.compatible = "allwinner,sun8i-a23-apb1-gates-clk", .data = &sun8i_a23_apb1_gates_data,},
> -       {.compatible = "allwinner,sun9i-a80-apb1-gates-clk", .data = &sun9i_a80_apb1_gates_data,},
> -       {.compatible = "allwinner,sun6i-a31-apb2-gates-clk", .data = &sun6i_a31_apb2_gates_data,},
> -       {.compatible = "allwinner,sun8i-a23-apb2-gates-clk", .data = &sun8i_a23_apb2_gates_data,},
> -       {}
> -};
>
>  static void __init of_sunxi_table_clock_setup(const struct of_device_id *clk_match,
>                                               void *function)
> @@ -1340,9 +1168,6 @@ static void __init sunxi_init_clocks(const char *clocks[], int nclocks)
>         /* Register mux clocks */
>         of_sunxi_table_clock_setup(clk_mux_match, sunxi_mux_clk_setup);
>
> -       /* Register gate clocks */
> -       of_sunxi_table_clock_setup(clk_gates_match, sunxi_gates_clk_setup);
> -
>         /* Protect the clocks that needs to stay on */
>         for (i = 0; i < nclocks; i++) {
>                 struct clk *clk = clk_get(NULL, clocks[i]);
> @@ -1354,7 +1179,6 @@ static void __init sunxi_init_clocks(const char *clocks[], int nclocks)
>
>  static const char *sun4i_a10_critical_clocks[] __initdata = {
>         "pll5_ddr",
> -       "ahb_sdram",
>  };
>
>  static void __init sun4i_a10_init_clocks(struct device_node *node)
> @@ -1367,7 +1191,6 @@ CLK_OF_DECLARE(sun4i_a10_clk_init, "allwinner,sun4i-a10", sun4i_a10_init_clocks)
>  static const char *sun5i_critical_clocks[] __initdata = {
>         "cpu",
>         "pll5_ddr",
> -       "ahb_sdram",
>  };
>
>  static void __init sun5i_init_clocks(struct device_node *node)
> --
> 2.4.6
>



-- 
Michael Turquette
CEO
BayLibre - At the Heart of Embedded Linux
http://baylibre.com/


From mturquette at baylibre.com  Tue Aug 11 16:26:49 2015
From: mturquette at baylibre.com (Michael Turquette)
Date: Tue, 11 Aug 2015 16:26:49 -0700
Subject: [PATCH 20/20] clk: at91: Revert "keep slow clk enabled to prevent
 system hang"
In-Reply-To: <1438215726-27452-21-git-send-email-alexandre.belloni@free-electrons.com>
References: <1438215726-27452-1-git-send-email-alexandre.belloni@free-electrons.com>
 <1438215726-27452-21-git-send-email-alexandre.belloni@free-electrons.com>
Message-ID: <20150811232649.31346.37488@quantum>

Quoting Alexandre Belloni (2015-07-29 17:22:06)
> Commit dca1a4b5ff6e ("clk: at91: keep slow clk enabled to prevent system
> hang") added a workaround for the slow clock as it is not properly handled
> by its users.
> 
> Now that the slow clock is taken properly by the drivers, this workaround
> is not necessary anymore, revert it.
> 
> Signed-off-by: Alexandre Belloni <alexandre.belloni at free-electrons.com>
> ---
> Cc: Michael Turquette <mturquette at baylibre.com>
> Cc: Stephen Boyd <sboyd at codeaurora.org>
> Cc: linux-clk at vger.kernel.org
>  drivers/clk/at91/clk-slow.c | 27 ---------------------------
>  1 file changed, 27 deletions(-)
> 
> diff --git a/drivers/clk/at91/clk-slow.c b/drivers/clk/at91/clk-slow.c
> index 98a84a865fe1..2c59d6a64dd5 100644
> --- a/drivers/clk/at91/clk-slow.c
> +++ b/drivers/clk/at91/clk-slow.c
> @@ -70,7 +70,6 @@ struct clk_sam9x5_slow {
>  
>  #define to_clk_sam9x5_slow(hw) container_of(hw, struct clk_sam9x5_slow, hw)
>  
> -static struct clk *slow_clk;
>  

Might want to remove one extra line of white space?

>  static int clk_slow_osc_prepare(struct clk_hw *hw)
>  {
> @@ -358,8 +357,6 @@ at91_clk_register_sam9x5_slow(void __iomem *sckcr,
>         clk = clk_register(NULL, &slowck->hw);
>         if (IS_ERR(clk))
>                 kfree(slowck);
> -       else
> -               slow_clk = clk;
>  
>         return clk;
>  }
> @@ -436,8 +433,6 @@ at91_clk_register_sam9260_slow(struct at91_pmc *pmc,
>         clk = clk_register(NULL, &slowck->hw);
>         if (IS_ERR(clk))
>                 kfree(slowck);
> -       else
> -               slow_clk = clk;
>  
>         return clk;
>  }
> @@ -470,25 +465,3 @@ void __init of_at91sam9260_clk_slow_setup(struct device_node *np,
>  
>         of_clk_add_provider(np, of_clk_src_simple_get, clk);
>  }
> -
> -/*
> - * FIXME: All slow clk users are not properly claiming it (get + prepare +
> - * enable) before using it.
> - * If all users properly claiming this clock decide that they don't need it
> - * anymore (or are removed), it is disabled while faulty users are still
> - * requiring it, and the system hangs.
> - * Prevent this clock from being disabled until all users are properly
> - * requesting it.
> - * Once this is done we should remove this function and the slow_clk variable.
> - */
> -static int __init of_at91_clk_slow_retain(void)
> -{
> -       if (!slow_clk)
> -               return 0;
> -
> -       __clk_get(slow_clk);
> -       clk_prepare_enable(slow_clk);
> -
> -       return 0;
> -}
> -arch_initcall(of_at91_clk_slow_retain);

This is a cool series. Thanks. Feel free to add my Ack, or we can take
this through clk-next once the other patches are applied.

Regards,
Mike

> -- 
> 2.1.4
> 
> --
> To unsubscribe from this list: send the line "unsubscribe linux-kernel" in
> the body of a message to majordomo at vger.kernel.org
> More majordomo info at  http://vger.kernel.org/majordomo-info.html
> Please read the FAQ at  http://www.tux.org/lkml/


From timur at codeaurora.org  Tue Aug 11 16:33:44 2015
From: timur at codeaurora.org (Timur Tabi)
Date: Tue, 11 Aug 2015 18:33:44 -0500
Subject: [PATCH v4 00/10] ACPI GIC Self-probing, GICv2m and GICv3 support
In-Reply-To: <20150811234801.51108784@arm.com>
References: <1438164539-29256-1-git-send-email-hanjun.guo@linaro.org>	<55CA70D5.6040300@codeaurora.org>	<20150811232523.60d192d2@arm.com>	<55CA78DE.1000306@codeaurora.org>
 <20150811234801.51108784@arm.com>
Message-ID: <55CA8658.80202@codeaurora.org>

On 08/11/2015 05:48 PM, Marc Zyngier wrote:
> I don't see any contradiction here. Hanjun picked the patches from my
> own branch in my own tree, put his own patches on top, and pushed that
> out on an branch called gsi-irqdomain that is definitely based on
> 4.2-rc2. I have no idea where your 3.9-rc7 comes from.

Ok, so that's not your kernel, but the LEG kernel instead.

The top commits show this:

Follows: tracking-mainline-llct-20130415.0, 
tracking-mainline-llct-20130417.0, v3.9-rc7

Also,
	$ git tag | grep v4

shows no v4.x tags.

Anyway, I don't want to make a big deal about this.

-- 
Qualcomm Innovation Center, Inc.
The Qualcomm Innovation Center, Inc. is a member of the
Code Aurora Forum, a Linux Foundation Collaborative Project.


From sfr at canb.auug.org.au  Tue Aug 11 16:48:34 2015
From: sfr at canb.auug.org.au (Stephen Rothwell)
Date: Wed, 12 Aug 2015 09:48:34 +1000
Subject: linux-next: manual merge of the arm-soc tree with the arm tree
Message-ID: <20150812094834.0b0b2af1@canb.auug.org.au>

Hi all,

Today's linux-next merge of the arm-soc tree got a conflict in:

  arch/arm/kernel/psci.c

between commit:

  be120397e770 ("ARM: migrate to common PSCI client code")

from the arm tree and commit:

  19c233b79d1a ("ARM: appropriate __init annotation for const data")

from the arm-soc tree.

I fixed it up (the former removed the file, so I did that, then added
the following patch) and can carry the fix as necessary (no action
is required).

From: Stephen Rothwell <sfr at canb.auug.org.au>
Date: Wed, 12 Aug 2015 09:39:15 +1000
Subject: [PATCH] ARM: fix for PSCI code movement

Signed-off-by: Stephen Rothwell <sfr at canb.auug.org.au>
---
 drivers/firmware/psci.c | 2 +-
 1 file changed, 1 insertion(+), 1 deletion(-)

diff --git a/drivers/firmware/psci.c b/drivers/firmware/psci.c
index a6956007dd38..42700f09a8c5 100644
--- a/drivers/firmware/psci.c
+++ b/drivers/firmware/psci.c
@@ -337,7 +337,7 @@ out_put_node:
 	return err;
 }
 
-static const struct of_device_id psci_of_match[] __initconst = {
+static const struct of_device_id const psci_of_match[] __initconst = {
 	{ .compatible = "arm,psci",	.data = psci_0_1_init},
 	{ .compatible = "arm,psci-0.2",	.data = psci_0_2_init},
 	{},
-- 
2.5.0

-- 
Cheers,
Stephen Rothwell                    sfr at canb.auug.org.au


From nicolas.pitre at linaro.org  Tue Aug 11 16:53:27 2015
From: nicolas.pitre at linaro.org (Nicolas Pitre)
Date: Tue, 11 Aug 2015 19:53:27 -0400 (EDT)
Subject: linux-next: manual merge of the arm-soc tree with the arm tree
In-Reply-To: <20150812094834.0b0b2af1@canb.auug.org.au>
References: <20150812094834.0b0b2af1@canb.auug.org.au>
Message-ID: <alpine.LFD.2.20.1508111952260.1515@knanqh.ubzr>

On Wed, 12 Aug 2015, Stephen Rothwell wrote:

> Hi all,
> 
> Today's linux-next merge of the arm-soc tree got a conflict in:
> 
>   arch/arm/kernel/psci.c
> 
> between commit:
> 
>   be120397e770 ("ARM: migrate to common PSCI client code")
> 
> from the arm tree and commit:
> 
>   19c233b79d1a ("ARM: appropriate __init annotation for const data")
> 
> from the arm-soc tree.
> 
> I fixed it up (the former removed the file, so I did that, then added
> the following patch) and can carry the fix as necessary (no action
> is required).

The fix is correct, thanks.


> 
> From: Stephen Rothwell <sfr at canb.auug.org.au>
> Date: Wed, 12 Aug 2015 09:39:15 +1000
> Subject: [PATCH] ARM: fix for PSCI code movement
> 
> Signed-off-by: Stephen Rothwell <sfr at canb.auug.org.au>
> ---
>  drivers/firmware/psci.c | 2 +-
>  1 file changed, 1 insertion(+), 1 deletion(-)
> 
> diff --git a/drivers/firmware/psci.c b/drivers/firmware/psci.c
> index a6956007dd38..42700f09a8c5 100644
> --- a/drivers/firmware/psci.c
> +++ b/drivers/firmware/psci.c
> @@ -337,7 +337,7 @@ out_put_node:
>  	return err;
>  }
>  
> -static const struct of_device_id psci_of_match[] __initconst = {
> +static const struct of_device_id const psci_of_match[] __initconst = {
>  	{ .compatible = "arm,psci",	.data = psci_0_1_init},
>  	{ .compatible = "arm,psci-0.2",	.data = psci_0_2_init},
>  	{},
> -- 
> 2.5.0
> 
> -- 
> Cheers,
> Stephen Rothwell                    sfr at canb.auug.org.au
> 
> 


From sboyd at codeaurora.org  Tue Aug 11 17:02:29 2015
From: sboyd at codeaurora.org (Stephen Boyd)
Date: Tue, 11 Aug 2015 17:02:29 -0700
Subject: [PATCH 5/7] clk: atlas7: fix the clock tree for bluetooth stuff
In-Reply-To: <CAGsJ_4y=TC1LXC1CPB=c1bfY7ZR0ktMD+hVuUZWxXXpyRR9zEw@mail.gmail.com>
References: <1438064845-17894-1-git-send-email-21cnbao@gmail.com>
 <1438064845-17894-6-git-send-email-21cnbao@gmail.com>
 <55B7FD22.10609@codeaurora.org>
 <CAGsJ_4wg1+5KrwTJRzE-iaSTvgvgFrM6cDyUTL16gx6Hk+tdPw@mail.gmail.com>
 <55C2BBED.4050608@codeaurora.org>
 <CAGsJ_4y=TC1LXC1CPB=c1bfY7ZR0ktMD+hVuUZWxXXpyRR9zEw@mail.gmail.com>
Message-ID: <20150812000229.GB26614@codeaurora.org>

On 08/10, Barry Song wrote:
> 2015-08-06 9:44 GMT+08:00 Stephen Boyd <sboyd at codeaurora.org>:
> >
> > This actually points out a big problem we have right now in Linux, which is
> > the lack of proper power management for the type of bus topology you see in
> > embedded systems. Some of the genpd work going on may also be another
> > solution to this problem, where we could group multiple devices into generic
> > power domains that know to turn on 2 or 3 of the clocks. For example, the
> > DMAC, USP, and UART device could all be in the APB power domain so that the
> > a7ca_io_clk is enabled whenever one of those devices is active. And there
> > could be another power domain for the NOC that encompasses all devices that
> > are sitting on that NOC.
> >
> 
> Stephen, this should be a possible option, i will talk with HW guys to
> figure out the relationship of power domain, and check whether we
> handle this issue by the power domain solution.
> 
> btw, would you apply other patches in this series at first? we can
> hold on this one to find a final solution.
> 

Yes. I'll apply the rest to clk-next.

-- 
Qualcomm Innovation Center, Inc. is a member of Code Aurora Forum,
a Linux Foundation Collaborative Project


From sboyd at codeaurora.org  Tue Aug 11 17:27:02 2015
From: sboyd at codeaurora.org (Stephen Boyd)
Date: Tue, 11 Aug 2015 17:27:02 -0700
Subject: [PATCH 1/7 v2] clk: atlas7: add lost pwm unit clks
In-Reply-To: <1438699532-13860-2-git-send-email-21cnbao@gmail.com>
References: <1438699532-13860-1-git-send-email-21cnbao@gmail.com>
 <1438699532-13860-2-git-send-email-21cnbao@gmail.com>
Message-ID: <20150812002702.GC26614@codeaurora.org>

On 08/04, Barry Song wrote:
> diff --git a/drivers/clk/sirf/clk-atlas7.c b/drivers/clk/sirf/clk-atlas7.c
> index db8ab69..a92e7ea 100644
> --- a/drivers/clk/sirf/clk-atlas7.c
> +++ b/drivers/clk/sirf/clk-atlas7.c
> @@ -1174,6 +1174,10 @@ static struct atlas7_unit_init_data unit_list[] __initdata = {
>  	{ 135, "thbtm_io", "btm_io", 0, SIRFSOC_CLKC_LEAF_CLK_EN8_SET, 7, &leaf8_gate_lock },
>  	{ 136, "btslow", "xinw_fixdiv_btslow", 0, SIRFSOC_CLKC_ROOT_CLK_EN1_SET, 25, &root1_gate_lock },
>  	{ 137, "a7ca_btslow", "btslow", 0, SIRFSOC_CLKC_LEAF_CLK_EN8_SET, 0, &leaf8_gate_lock },
> +	{ 138 , "pwm_io", "io_mux", 0, SIRFSOC_CLKC_LEAF_CLK_EN0_SET, 0, &leaf0_gate_lock },
> +	{ 139 , "pwm_xin", "xin", 0, SIRFSOC_CLKC_LEAF_CLK_EN0_SET, 1, &leaf0_gate_lock },
> +	{ 140 , "pwm_xinw", "xinw", 0, SIRFSOC_CLKC_LEAF_CLK_EN0_SET, 2, &leaf0_gate_lock },
> +	{ 141 , "thcgum_sys", "sys_mux", 0, SIRFSOC_CLKC_LEAF_CLK_EN0_SET, 3, &leaf0_gate_lock },

The extra space made checkpatch complain. I silenced it and
applied to clk-next.

-- 
Qualcomm Innovation Center, Inc. is a member of Code Aurora Forum,
a Linux Foundation Collaborative Project


From sboyd at codeaurora.org  Tue Aug 11 17:27:09 2015
From: sboyd at codeaurora.org (Stephen Boyd)
Date: Tue, 11 Aug 2015 17:27:09 -0700
Subject: [PATCH 2/7 v2] clk: atlas7: export mux clks so that consumers
 can get them
In-Reply-To: <1438699532-13860-3-git-send-email-21cnbao@gmail.com>
References: <1438699532-13860-1-git-send-email-21cnbao@gmail.com>
 <1438699532-13860-3-git-send-email-21cnbao@gmail.com>
Message-ID: <20150812002708.GD26614@codeaurora.org>

On 08/04, Barry Song wrote:
> From: Guo Zeng <guo.zeng at csr.com>
> 
> this patch makes mux clks can be referenced by device drivers.
> 
> Signed-off-by: Guo Zeng <guo.zeng at csr.com>
> Signed-off-by: Barry Song <Barry.Song at csr.com>
> ---

Applied to clk-next

-- 
Qualcomm Innovation Center, Inc. is a member of Code Aurora Forum,
a Linux Foundation Collaborative Project


From sboyd at codeaurora.org  Tue Aug 11 17:27:15 2015
From: sboyd at codeaurora.org (Stephen Boyd)
Date: Tue, 11 Aug 2015 17:27:15 -0700
Subject: [PATCH 3/7 v2] clk: atlas7: fix integer overflow in dto rate
 calculation
In-Reply-To: <1438699532-13860-4-git-send-email-21cnbao@gmail.com>
References: <1438699532-13860-1-git-send-email-21cnbao@gmail.com>
 <1438699532-13860-4-git-send-email-21cnbao@gmail.com>
Message-ID: <20150812002715.GE26614@codeaurora.org>

On 08/04, Barry Song wrote:
> From: Yibo Cai <yibo.cai at csr.com>
> 
> I cannot believe that I spend quite a lot time in finding this bug.
> It seems a pitfall people tend to fall in.
> 
> In "int64 = int32 * int32", conversion from 32-bits to 64-bits comes
> after the multiplication. So this statement may not work as expected.
> 
> Signed-off-by: Yibo Cai <yibo.cai at csr.com>
> Signed-off-by: Barry Song <Baohua.Song at csr.com>
> ---

Applied to clk-next

-- 
Qualcomm Innovation Center, Inc. is a member of Code Aurora Forum,
a Linux Foundation Collaborative Project


From sboyd at codeaurora.org  Tue Aug 11 17:27:26 2015
From: sboyd at codeaurora.org (Stephen Boyd)
Date: Tue, 11 Aug 2015 17:27:26 -0700
Subject: [PATCH 4/7 v2] clk: atlas7: replace dto resolution magic number
 by macro
In-Reply-To: <1438699532-13860-5-git-send-email-21cnbao@gmail.com>
References: <1438699532-13860-1-git-send-email-21cnbao@gmail.com>
 <1438699532-13860-5-git-send-email-21cnbao@gmail.com>
Message-ID: <20150812002726.GF26614@codeaurora.org>

On 08/04, Barry Song wrote:
> From: Yibo Cai <yibo.cai at csr.com>
> 
> Signed-off-by: Yibo Cai <yibo.cai at csr.com>
> Signed-off-by: Barry Song <Baohua.Song at csr.com>
> ---

Applied to clk-next

-- 
Qualcomm Innovation Center, Inc. is a member of Code Aurora Forum,
a Linux Foundation Collaborative Project


From sboyd at codeaurora.org  Tue Aug 11 17:27:58 2015
From: sboyd at codeaurora.org (Stephen Boyd)
Date: Tue, 11 Aug 2015 17:27:58 -0700
Subject: [PATCH 6/7 v2] clk: atlas7: fix bit field and its root clk for
 coresight_tpiu
In-Reply-To: <1438699532-13860-7-git-send-email-21cnbao@gmail.com>
References: <1438699532-13860-1-git-send-email-21cnbao@gmail.com>
 <1438699532-13860-7-git-send-email-21cnbao@gmail.com>
Message-ID: <20150812002758.GG26614@codeaurora.org>

On 08/04, Barry Song wrote:
> diff --git a/drivers/clk/sirf/clk-atlas7.c b/drivers/clk/sirf/clk-atlas7.c
> index c1788df..4fc33da 100644
> --- a/drivers/clk/sirf/clk-atlas7.c
> +++ b/drivers/clk/sirf/clk-atlas7.c
> @@ -1164,7 +1164,7 @@ static struct atlas7_unit_init_data unit_list[] __initdata = {
>  	{ 122, "spram1_cpudiv2", "cpum_cpu", 0, SIRFSOC_CLKC_LEAF_CLK_EN6_SET, 0, &leaf6_gate_lock },
>  	{ 123, "spram2_cpudiv2", "cpum_cpu", 0, SIRFSOC_CLKC_LEAF_CLK_EN6_SET, 1, &leaf6_gate_lock },
>  	{ 124, "coresight_cpudiv2", "cpum_cpu", 0, SIRFSOC_CLKC_LEAF_CLK_EN6_SET, 2, &leaf6_gate_lock },
> -	{ 125, "thcpum_cpudiv4", "cpum_cpu", 0, SIRFSOC_CLKC_LEAF_CLK_EN6_SET, 3, &leaf6_gate_lock },
> +	{ 125 , "coresight_tpiu", "cpum_tpiu", 0, SIRFSOC_CLKC_LEAF_CLK_EN6_SET, 3, &leaf6_gate_lock },

This one too. Silenced checkpatch error by removing space after
125. Applied to clk-next.

-- 
Qualcomm Innovation Center, Inc. is a member of Code Aurora Forum,
a Linux Foundation Collaborative Project


From sboyd at codeaurora.org  Tue Aug 11 17:30:54 2015
From: sboyd at codeaurora.org (Stephen Boyd)
Date: Tue, 11 Aug 2015 17:30:54 -0700
Subject: [PATCH 7/7] clk: atlas7: fix pll missed divide NR in fraction mode
In-Reply-To: <1438699532-13860-8-git-send-email-21cnbao@gmail.com>
References: <1438699532-13860-1-git-send-email-21cnbao@gmail.com>
 <1438699532-13860-8-git-send-email-21cnbao@gmail.com>
Message-ID: <20150812002805.GH26614@codeaurora.org>

On 08/04, Barry Song wrote:
> From: Guo Zeng <guo.zeng at csr.com>
> 
> PLL VCO frequency is given by Fvco = Fref * 2 * NF / NR
> in integer-N mode, or by Fvco = Fref * SSN / NR in Spread
> Spectrum (fractional-N) mode. Thus fix the missing part
> of NR
> 
> Signed-off-by: Guo Zeng <guo.zeng at csr.com>
> Signed-off-by: Barry Song <Baohua.Song at csr.com>
> ---

Applied to clk-next

-- 
Qualcomm Innovation Center, Inc. is a member of Code Aurora Forum,
a Linux Foundation Collaborative Project


From sboyd at codeaurora.org  Tue Aug 11 17:38:17 2015
From: sboyd at codeaurora.org (Stephen Boyd)
Date: Tue, 11 Aug 2015 17:38:17 -0700
Subject: [PATCH v4 0/4] clk: hisilicon: support stub clock
In-Reply-To: <1438673249-6051-1-git-send-email-leo.yan@linaro.org>
References: <1438673249-6051-1-git-send-email-leo.yan@linaro.org>
Message-ID: <20150812003817.GI26614@codeaurora.org>

On 08/04, Leo Yan wrote:
> This series adds support for hisilicon stub clock driver. On hi6220,
> the bootloader needs load the firmware image and set info for OPPs;
> after run into kernel, the stub clock driver is used to communicate
> w/t firmware for cpu dynamic frequency scaling.
> 
> In patch series v1/v2, the stub clock driver simply writes request in
> sram and send ipc to firmware; For patch series v3, the firmware has
> been upgraded to use mailbox, so stub clock driver will call standard
> mailbox APIs to request mailbox channel and send message to firmware.
> 
> Patch 4 adds stub clock node into dts and it references mailbox with
> phandle, so patch 4 will depend on mailbox driver's patch series [1].
> These patches have been tested on 96board hikey and is used by cpufreq
> driver.

The To: list is everyone, so I'm not sure who is supposed to
apply these patches. I'd like to take patches 1, 2, and 3 through
the clk tree though.

-- 
Qualcomm Innovation Center, Inc. is a member of Code Aurora Forum,
a Linux Foundation Collaborative Project


From katsuki.uwatoko at toshiba.co.jp  Tue Aug 11 17:56:25 2015
From: katsuki.uwatoko at toshiba.co.jp (katsuki.uwatoko at toshiba.co.jp)
Date: Wed, 12 Aug 2015 00:56:25 +0000
Subject: PROBLEM: XFS on ARM corruption 'Structure needs cleaning'
In-Reply-To: <20150612225209.GA20262@dastard>
References: <5579B804.9050707@skylable.com>
 <20150612122108.GB60661@bfoster.bfoster> <557AD4D4.3010901@skylable.com>
 <20150612225209.GA20262@dastard>
Message-ID: <C6D0D499B56584katsuki.uwatoko@toshiba.co.jp>

On Sat, 13 Jun 2015 08:52:09 +1000, Dave Chinner wrote:

> Yup, that's looking like a toolchain bug. Thread about arm directory
> read corruption:

I think that this is not a toolchain bug, this is related to 
Subject: [PATCH v2 1/1] ARM : missing corrupted reg in __do_div_asm
http://www.spinics.net/lists/arm-kernel/msg426684.html

--

The problematic line in xfs is: 
irecs->br_startblock = XFS_DADDR_TO_FSB(mp, mappedbno)
in xfs_dabuf_map()/fs/xfs/xfs_da_btree.c.

The expansion of it is: 

  ld = mappedbno >> mp->m_blkbb_log;
  do_div(ld, mp->m_sb.sb_agblocks);
  startblock = ld << mp->m_sb.sb_agblklog;
  ld = mappedbno >> mp->m_blkbb_log;
  startblock |= do_div(ld, mp->m_sb.sb_agblocks);
  irecs->br_startblock = startblock;

The assembler of these are:

:
	bl	__do_div64
	ldr	r1, [sp, #44]
	subs	r3, r7, #32
	orr	r1, r1, r2, lsr r5
	add	r5, sp, #80
	str	r5, [sp, #64]
	ldr	r5, [sp, #60]
	movpl	r1, r2, asl r3
	mov	r2, r2, asl r7
	str	r2, [sp, #40]
	str	r1, [sp, #44]
	mov	r1, r9
	str	r5, [sp, #96]
	mov	r7, #0
	ldr	r2, [sp, #96]
	mov	r5, #1
	ldr	fp, [sp, #64]
	str	r7, [sp, #84]
	mov	r9, r2, asr #31
	str	r7, [sp, #104]
	bl	__do_div64
:

by GCC 4.7.2 with -O2 option.

Because a result of do_div is stored in the 1st arg (r0),
r0, which is "ld" in the C,  must be reloaded after the 1st call of do_div, before the 2nd call of do_div.
But it is not reloaded in the above assembler.
The problem is macro __do_div_asm, as the patch describes.

I confirmed that the patch fixed this problem.

	mov	r1, sl
	str	r2, [sp, #56]
	mov	r0, fp
	bl	__do_div64
	ldr	ip, [sp, #36]
	rsb	r6, r5, #32
	subs	r3, r5, #32
	ldr	r1, [sp, #56]
	orr	ip, ip, r2, lsr r6
	str	r7, [sp, #96]
	mov	r6, #1
	str	r8, [sp, #80]
	mov	r0, ip
	str	r1, [sp, #52]
	movpl	r0, r2, asl r3
	mov	r2, r2, asl r5
	str	r0, [sp, #36]
	mov	r1, sl
	str	r2, [sp, #32]
	mov	r0, fp
	bl	__do_div64

by GCC 4.7.2 with -O2 option and the patch.

Thank you,
-- 
UWATOKO

From robh at kernel.org  Tue Aug 11 18:07:50 2015
From: robh at kernel.org (Rob Herring)
Date: Tue, 11 Aug 2015 20:07:50 -0500
Subject: [PATCH] ARM: config: Switch PXA27x platforms to use PXA RTC driver
In-Reply-To: <1437757375-9113-1-git-send-email-robh@kernel.org>
References: <1437757375-9113-1-git-send-email-robh@kernel.org>
Message-ID: <CAL_JsqKxUjg+zPJ=_Wvd+zTh7UuT=dkECEh=Hy7QdZsqn4B+8w@mail.gmail.com>

On Fri, Jul 24, 2015 at 12:02 PM, Rob Herring <robh at kernel.org> wrote:
> With the SA1100 and PXA RTC drivers be mutually exclusive and no
> longer sharing hardware, PXA27x/PXA3xx platforms must use the PXA RTC
> driver as the SA1100 platform device is no longer registered.
>
> This change should be almost transparent to userspace. Former users of
> pxa-rtc should be aware that 2 RTCs will be available on their kernels,
> rtc0 being sa1100-rtc and rtc1 being pxa-rtc. Any userspace relying on
> the fact that rtc0 was pxa-rtc should be fixed.
>
> As a consequence:
>  - the first reboot after the switch will have the wrong time,
>  - on dual boot platform where the other OS programs some logic into the
>    sa1100 rtc IP, a lack of fix in userspace, ie. a kernel changing
>    sa1100-rtc thinking it is pxa-rtc could have dire consequence, such
>    as wiping the other OS data partition.
>
> (Thanks to Robert Jarmik for help on the above commit text.)
>
> Signed-off-by: Rob Herring <robh at kernel.org>
> Cc: Robert Jarzmik <robert.jarzmik at free.fr>
> Cc: Daniel Mack <daniel at zonque.org>
> Cc: Haojian Zhuang <haojian.zhuang at gmail.com>
> Cc: Sergey Lapin <slapin at ossfans.org>
> Cc: Russell King <linux at arm.linux.org.uk>
> Cc: Mike Rapoport <mike at compulab.co.il>
> Cc: Philipp Zabel <philipp.zabel at gmail.com>
> ---
> PXA Maintainers,
>
> This is dependent on my SA1100 RTC cleanup series[1]. Please comment on
> this patch and that series. The full series is available from a git
> branch here[2]. I've rebased it to 4.2-rc3, but otherwise there is no
> change from v4.

Any comments on this? If not, I plan to send Alexandre a pull request
for this series this week.

Rob

>
> Rob
>
> [1] http://lists.infradead.org/pipermail/linux-arm-kernel/2015-June/349262.html
> [2] git://git.kernel.org/pub/scm/linux/kernel/git/robh/linux.git marvell/rtc
>
>  arch/arm/configs/cm_x2xx_defconfig  | 2 +-
>  arch/arm/configs/em_x270_defconfig  | 2 +-
>  arch/arm/configs/magician_defconfig | 2 +-
>  arch/arm/configs/palmz72_defconfig  | 2 +-
>  arch/arm/configs/pcm027_defconfig   | 2 +-
>  arch/arm/configs/trizeps4_defconfig | 2 +-
>  6 files changed, 6 insertions(+), 6 deletions(-)
>
> diff --git a/arch/arm/configs/cm_x2xx_defconfig b/arch/arm/configs/cm_x2xx_defconfig
> index dc01c04..3b32d5f 100644
> --- a/arch/arm/configs/cm_x2xx_defconfig
> +++ b/arch/arm/configs/cm_x2xx_defconfig
> @@ -157,7 +157,7 @@ CONFIG_LEDS_TRIGGERS=y
>  CONFIG_LEDS_TRIGGER_HEARTBEAT=y
>  CONFIG_RTC_CLASS=y
>  CONFIG_RTC_DRV_V3020=y
> -CONFIG_RTC_DRV_SA1100=y
> +CONFIG_RTC_DRV_PXA=y
>  CONFIG_EXT2_FS=y
>  CONFIG_EXT3_FS=y
>  CONFIG_INOTIFY=y
> diff --git a/arch/arm/configs/em_x270_defconfig b/arch/arm/configs/em_x270_defconfig
> index 4560c9c..8e10df7 100644
> --- a/arch/arm/configs/em_x270_defconfig
> +++ b/arch/arm/configs/em_x270_defconfig
> @@ -157,7 +157,7 @@ CONFIG_LEDS_TRIGGERS=y
>  CONFIG_LEDS_TRIGGER_HEARTBEAT=y
>  CONFIG_RTC_CLASS=y
>  CONFIG_RTC_DRV_V3020=y
> -CONFIG_RTC_DRV_SA1100=y
> +CONFIG_RTC_DRV_PXA=y
>  CONFIG_EXT2_FS=y
>  CONFIG_EXT3_FS=y
>  CONFIG_INOTIFY=y
> diff --git a/arch/arm/configs/magician_defconfig b/arch/arm/configs/magician_defconfig
> index 557dd29..a5b4920 100644
> --- a/arch/arm/configs/magician_defconfig
> +++ b/arch/arm/configs/magician_defconfig
> @@ -150,7 +150,7 @@ CONFIG_LEDS_TRIGGERS=y
>  CONFIG_LEDS_TRIGGER_BACKLIGHT=y
>  CONFIG_RTC_CLASS=y
>  CONFIG_RTC_DEBUG=y
> -CONFIG_RTC_DRV_SA1100=y
> +CONFIG_RTC_DRV_PXA=y
>  CONFIG_EXT2_FS=y
>  CONFIG_INOTIFY=y
>  CONFIG_MSDOS_FS=m
> diff --git a/arch/arm/configs/palmz72_defconfig b/arch/arm/configs/palmz72_defconfig
> index 4baa83c..83c135e 100644
> --- a/arch/arm/configs/palmz72_defconfig
> +++ b/arch/arm/configs/palmz72_defconfig
> @@ -67,7 +67,7 @@ CONFIG_MMC=y
>  CONFIG_MMC_DEBUG=y
>  CONFIG_MMC_PXA=y
>  CONFIG_RTC_CLASS=y
> -CONFIG_RTC_DRV_SA1100=y
> +CONFIG_RTC_DRV_PXA=y
>  CONFIG_EXT2_FS=y
>  CONFIG_EXT3_FS=y
>  # CONFIG_DNOTIFY is not set
> diff --git a/arch/arm/configs/pcm027_defconfig b/arch/arm/configs/pcm027_defconfig
> index 0a847d0..b5624e3 100644
> --- a/arch/arm/configs/pcm027_defconfig
> +++ b/arch/arm/configs/pcm027_defconfig
> @@ -82,7 +82,7 @@ CONFIG_MMC=y
>  CONFIG_MMC_PXA=y
>  CONFIG_RTC_CLASS=y
>  CONFIG_RTC_DRV_PCF8563=m
> -CONFIG_RTC_DRV_SA1100=m
> +CONFIG_RTC_DRV_PXA=m
>  CONFIG_EXT2_FS=m
>  CONFIG_EXT3_FS=m
>  # CONFIG_DNOTIFY is not set
> diff --git a/arch/arm/configs/trizeps4_defconfig b/arch/arm/configs/trizeps4_defconfig
> index 932ee4e..4bc8700 100644
> --- a/arch/arm/configs/trizeps4_defconfig
> +++ b/arch/arm/configs/trizeps4_defconfig
> @@ -177,7 +177,7 @@ CONFIG_NEW_LEDS=y
>  CONFIG_RTC_CLASS=y
>  # CONFIG_RTC_HCTOSYS is not set
>  CONFIG_RTC_DRV_PCF8583=m
> -CONFIG_RTC_DRV_SA1100=y
> +CONFIG_RTC_DRV_PXA=y
>  CONFIG_EXT2_FS=y
>  CONFIG_EXT2_FS_XATTR=y
>  CONFIG_EXT2_FS_POSIX_ACL=y
> --
> 2.1.0
>


From horms at verge.net.au  Tue Aug 11 18:17:50 2015
From: horms at verge.net.au (Simon Horman)
Date: Wed, 12 Aug 2015 10:17:50 +0900
Subject: [PATCH v2 0/2] Add R8A7794/SILK QSPI DT support
In-Reply-To: <4187771.Fb49GBKgyg@wasted.cogentembedded.com>
References: <4187771.Fb49GBKgyg@wasted.cogentembedded.com>
Message-ID: <20150812011750.GG15957@verge.net.au>

On Tue, Aug 11, 2015 at 12:57:57AM +0300, Sergei Shtylyov wrote:
> Hello.
> 
>    Here's the set of 2 patches against Simon Horman's 'renesas.git' repo,
> 'renesas-devel-20150810-v4.2-rc6' tag plus the R8A7794 GPIO patches I've posted
> last week. Here we add the QSPI device tree support for the R8A7794/SILK board.
> 
> [1/2] ARM: shmobile: r8a7794: add QSPI DT support
> [2/2] ARM: shmobile: silk: add QSPI DT support

Thanks, both patches queued up for v4.4.


From horms at verge.net.au  Tue Aug 11 18:26:52 2015
From: horms at verge.net.au (Simon Horman)
Date: Wed, 12 Aug 2015 10:26:52 +0900
Subject: [PATCH v2] ARM: shmobile: silk: add SDHI1 DT support
In-Reply-To: <2757472.iuyUyRzJ3z@wasted.cogentembedded.com>
References: <10037494.4LD4T2QGPX@wasted.cogentembedded.com>
 <2757472.iuyUyRzJ3z@wasted.cogentembedded.com>
Message-ID: <20150812012652.GH15957@verge.net.au>

Hi Sergei,

On Tue, Aug 11, 2015 at 01:44:03AM +0300, Sergei Shtylyov wrote:
> Define the SILK board dependent part of the SDHI1 (connected to micro-SD slot)
> device nodes along with the necessary voltage regulators.
> 
> Based on the original patch by Vladimir Barinov
> <vladimir.barinov at cogentembedded.com>.
> 
> Signed-off-by: Sergei Shtylyov <sergei.shtylyov at cogentembedded.com>
> 
> ---
> This patch is against 'renesas-devel-20150810-v4.2-rc6' tag of Simon Horman's
> 'renesas.git' repo plus the R8A7794/SILK QSPI patches just re-posted. It needs
> the R8A7794 GPIO patches in order to compile.
> 
> Changes in version 2:
> - removed not working SDHI0 stuff, renamed the patch;
> - replaced SDHI1's "wp-gpios" property with "disable-wp".

I am wondering if you could explain the motivation for the "disable-wp"
update and weather it is appropriate for other r8a779* dts files.

Thanks.


From djkurtz at chromium.org  Tue Aug 11 18:32:40 2015
From: djkurtz at chromium.org (Daniel Kurtz)
Date: Wed, 12 Aug 2015 09:32:40 +0800
Subject: [PATCH v2 2/2] i2c: mediatek: Fixup i2c ack error interrupt
 handling
In-Reply-To: <20150811145521.GB1525@katana>
References: <1438845731-17805-1-git-send-email-eddie.huang@mediatek.com>
 <1438845731-17805-3-git-send-email-eddie.huang@mediatek.com>
 <20150811145521.GB1525@katana>
Message-ID: <CAGS+omBrDWd7hwn=0qYBLK=6L-hORwrKQ9ecL4k3wSSGEPZ64g@mail.gmail.com>

Hi Wolfram,

On Tue, Aug 11, 2015 at 10:55 PM, Wolfram Sang <wsa at the-dreams.de> wrote:
> On Thu, Aug 06, 2015 at 03:22:11PM +0800, Eddie Huang wrote:
>> When occur i2c ack error, i2c controller generate two interrupts,
>> first is the ack error interrupt, then the complete interrupt.
>> i2c interrupt handler should keep the two interrupt value, and only
>> call complete() for the complete interrupt.
>>
>> Signed-off-by: Liguo Zhang <liguo.zhang at mediatek.com>
>> Signed-off-by: Eddie Huang <eddie.huang at mediatek.com>
>
> Applied to for-next, thanks!

I don't see them in [0].
[0] https://git.kernel.org/cgit/linux/kernel/git/wsa/linux.git/log/?h=i2c/for-next

Am I not looking in the right place?
Or, did I not wait long enough?

Thanks!
-Dan


From sboyd at codeaurora.org  Tue Aug 11 18:36:50 2015
From: sboyd at codeaurora.org (Stephen Boyd)
Date: Tue, 11 Aug 2015 18:36:50 -0700
Subject: [PATCH 1/2] ARM: dts: vexpress: Use assigned-clock-parents for sp810
Message-ID: <1439343411-29168-1-git-send-email-sboyd@codeaurora.org>

The sp810 clk driver is calling the clk consumer APIs from
clk_prepare ops to change the parent to a 1 MHz fixed rate clock
for each of the clocks that the driver provides. Use
assigned-clock-parents for this instead of doing it in the driver
to avoid using the consumer API in provider code. This also
allows us to remove the usage of clk provider APIs that take a
struct clk as an argument from the sp810 driver.

Cc: Pawel Moll <pawel.moll at arm.com>
Cc: Linus Walleij <linus.walleij at linaro.org>
Tested-by: Sudeep Holla <sudeep.holla at arm.com>
Signed-off-by: Stephen Boyd <sboyd at codeaurora.org>
---

This came out of a larger series to change this binding[1]. This
patch can go through arm-soc independently though, so please apply.

[1] http://lkml.kernel.org/r/1438386285-5070-1-git-send-email-sboyd at codeaurora.org

 arch/arm/boot/dts/vexpress-v2m-rs1.dtsi | 2 ++
 arch/arm/boot/dts/vexpress-v2m.dtsi     | 2 ++
 2 files changed, 4 insertions(+)

diff --git a/arch/arm/boot/dts/vexpress-v2m-rs1.dtsi b/arch/arm/boot/dts/vexpress-v2m-rs1.dtsi
index 2efb2058ba49..21b02874bea3 100644
--- a/arch/arm/boot/dts/vexpress-v2m-rs1.dtsi
+++ b/arch/arm/boot/dts/vexpress-v2m-rs1.dtsi
@@ -101,6 +101,8 @@
 				clock-names = "refclk", "timclk", "apb_pclk";
 				#clock-cells = <1>;
 				clock-output-names = "timerclken0", "timerclken1", "timerclken2", "timerclken3";
+				assigned-clocks = <&v2m_sysctl 0>, <&v2m_sysctl 1>, <&v2m_sysctl 3>, <&v2m_sysctl 3>;
+				assigned-clock-parents = <&v2m_refclk1mhz>, <&v2m_refclk1mhz>, <&v2m_refclk1mhz>, <&v2m_refclk1mhz>;
 			};
 
 			/* PCI-E I2C bus */
diff --git a/arch/arm/boot/dts/vexpress-v2m.dtsi b/arch/arm/boot/dts/vexpress-v2m.dtsi
index cb3090f919a7..e712c0af149b 100644
--- a/arch/arm/boot/dts/vexpress-v2m.dtsi
+++ b/arch/arm/boot/dts/vexpress-v2m.dtsi
@@ -100,6 +100,8 @@
 				clock-names = "refclk", "timclk", "apb_pclk";
 				#clock-cells = <1>;
 				clock-output-names = "timerclken0", "timerclken1", "timerclken2", "timerclken3";
+				assigned-clocks = <&v2m_sysctl 0>, <&v2m_sysctl 1>, <&v2m_sysctl 3>, <&v2m_sysctl 3>;
+				assigned-clock-parents = <&v2m_refclk1mhz>, <&v2m_refclk1mhz>, <&v2m_refclk1mhz>, <&v2m_refclk1mhz>;
 			};
 
 			/* PCI-E I2C bus */
-- 
The Qualcomm Innovation Center, Inc. is a member of the Code Aurora Forum,
a Linux Foundation Collaborative Project



From sboyd at codeaurora.org  Tue Aug 11 18:36:51 2015
From: sboyd at codeaurora.org (Stephen Boyd)
Date: Tue, 11 Aug 2015 18:36:51 -0700
Subject: [PATCH 2/2] ARM64: dts: vexpress: Use assigned-clock-parents for sp810
In-Reply-To: <1439343411-29168-1-git-send-email-sboyd@codeaurora.org>
References: <1439343411-29168-1-git-send-email-sboyd@codeaurora.org>
Message-ID: <1439343411-29168-2-git-send-email-sboyd@codeaurora.org>

The sp810 clk driver is calling the clk consumer APIs from
clk_prepare ops to change the parent to a 1 MHz fixed rate clock
for each of the clocks that the driver provides. Use
assigned-clock-parents for this instead of doing it in the driver
to avoid using the consumer API in provider code. This also
allows us to remove the usage of clk provider APIs that take a
struct clk as an argument from the sp810 driver.

Cc: Pawel Moll <pawel.moll at arm.com>
Cc: Linus Walleij <linus.walleij at linaro.org>
Tested-by: Sudeep Holla <sudeep.holla at arm.com>
Signed-off-by: Stephen Boyd <sboyd at codeaurora.org>
---

This came out of a larger series to change this binding[1]. This
patch can go through arm-soc independently though, so please apply.

[1] http://lkml.kernel.org/r/1438386285-5070-1-git-send-email-sboyd at codeaurora.org

 arch/arm64/boot/dts/arm/juno-motherboard.dtsi    | 2 ++
 arch/arm64/boot/dts/arm/rtsm_ve-motherboard.dtsi | 2 ++
 2 files changed, 4 insertions(+)

diff --git a/arch/arm64/boot/dts/arm/juno-motherboard.dtsi b/arch/arm64/boot/dts/arm/juno-motherboard.dtsi
index 021e0f40f419..637e046f0e36 100644
--- a/arch/arm64/boot/dts/arm/juno-motherboard.dtsi
+++ b/arch/arm64/boot/dts/arm/juno-motherboard.dtsi
@@ -136,6 +136,8 @@
 					clock-names = "refclk", "timclk", "apb_pclk";
 					#clock-cells = <1>;
 					clock-output-names = "timerclken0", "timerclken1", "timerclken2", "timerclken3";
+					assigned-clocks = <&v2m_sysctl 0>, <&v2m_sysctl 1>, <&v2m_sysctl 3>, <&v2m_sysctl 3>;
+					assigned-clock-parents = <&v2m_refclk1mhz>, <&v2m_refclk1mhz>, <&v2m_refclk1mhz>, <&v2m_refclk1mhz>;
 				};
 
 				apbregs at 010000 {
diff --git a/arch/arm64/boot/dts/arm/rtsm_ve-motherboard.dtsi b/arch/arm64/boot/dts/arm/rtsm_ve-motherboard.dtsi
index c46cbb29f3c6..88a7583ed7a7 100644
--- a/arch/arm64/boot/dts/arm/rtsm_ve-motherboard.dtsi
+++ b/arch/arm64/boot/dts/arm/rtsm_ve-motherboard.dtsi
@@ -74,6 +74,8 @@
 				clock-names = "refclk", "timclk", "apb_pclk";
 				#clock-cells = <1>;
 				clock-output-names = "timerclken0", "timerclken1", "timerclken2", "timerclken3";
+				assigned-clocks = <&v2m_sysctl 0>, <&v2m_sysctl 1>, <&v2m_sysctl 3>, <&v2m_sysctl 3>;
+				assigned-clock-parents = <&v2m_refclk1mhz>, <&v2m_refclk1mhz>, <&v2m_refclk1mhz>, <&v2m_refclk1mhz>;
 			};
 
 			aaci at 040000 {
-- 
The Qualcomm Innovation Center, Inc. is a member of the Code Aurora Forum,
a Linux Foundation Collaborative Project



From wsa at the-dreams.de  Tue Aug 11 18:40:40 2015
From: wsa at the-dreams.de (Wolfram Sang)
Date: Wed, 12 Aug 2015 03:40:40 +0200
Subject: [PATCH v2 2/2] i2c: mediatek: Fixup i2c ack error interrupt
 handling
In-Reply-To: <CAGS+omBrDWd7hwn=0qYBLK=6L-hORwrKQ9ecL4k3wSSGEPZ64g@mail.gmail.com>
References: <1438845731-17805-1-git-send-email-eddie.huang@mediatek.com>
 <1438845731-17805-3-git-send-email-eddie.huang@mediatek.com>
 <20150811145521.GB1525@katana>
 <CAGS+omBrDWd7hwn=0qYBLK=6L-hORwrKQ9ecL4k3wSSGEPZ64g@mail.gmail.com>
Message-ID: <20150812014039.GB1602@katana>


> Or, did I not wait long enough?

This.

-------------- next part --------------
A non-text attachment was scrubbed...
Name: signature.asc
Type: application/pgp-signature
Size: 819 bytes
Desc: Digital signature
URL: <http://lists.infradead.org/pipermail/linux-arm-kernel/attachments/20150812/caa9c2bf/attachment.sig>

From leo.yan at linaro.org  Tue Aug 11 18:49:54 2015
From: leo.yan at linaro.org (Leo Yan)
Date: Wed, 12 Aug 2015 09:49:54 +0800
Subject: [PATCH v4 0/4] clk: hisilicon: support stub clock
In-Reply-To: <20150812003817.GI26614@codeaurora.org>
References: <1438673249-6051-1-git-send-email-leo.yan@linaro.org>
 <20150812003817.GI26614@codeaurora.org>
Message-ID: <20150812014954.GA6215@leoy-linaro>

Hi Stephen,

On Tue, Aug 11, 2015 at 05:38:17PM -0700, Stephen Boyd wrote:
> On 08/04, Leo Yan wrote:
> > This series adds support for hisilicon stub clock driver. On hi6220,
> > the bootloader needs load the firmware image and set info for OPPs;
> > after run into kernel, the stub clock driver is used to communicate
> > w/t firmware for cpu dynamic frequency scaling.
> > 
> > In patch series v1/v2, the stub clock driver simply writes request in
> > sram and send ipc to firmware; For patch series v3, the firmware has
> > been upgraded to use mailbox, so stub clock driver will call standard
> > mailbox APIs to request mailbox channel and send message to firmware.
> > 
> > Patch 4 adds stub clock node into dts and it references mailbox with
> > phandle, so patch 4 will depend on mailbox driver's patch series [1].
> > These patches have been tested on 96board hikey and is used by cpufreq
> > driver.
> 
> The To: list is everyone, so I'm not sure who is supposed to
> apply these patches. I'd like to take patches 1, 2, and 3 through
> the clk tree though.

Thanks, you could take first three patches. For patch 4, i will
re-send it after mailbox driver's patches have been merged.

Wei Xu, is this okay for you?

Thanks,
Leo Yan


From nico at fluxnic.net  Tue Aug 11 19:18:26 2015
From: nico at fluxnic.net (Nicolas Pitre)
Date: Tue, 11 Aug 2015 22:18:26 -0400 (EDT)
Subject: arm kernel oops in highmem.c with 4.2
In-Reply-To: <1439327845.3153.17.camel@redhat.com>
References: <CALeDE9Ox3=sh3AXQ0NUG6BBfU5i5YrMY=LDpcTHQWqz2=60F2g@mail.gmail.com>
 <20150805100701.GV7557@n2100.arm.linux.org.uk>
 <CALeDE9PXF=gQCaBCiHpHy2nXOooQOmsCQvSgOv+wQw3mta=P6A@mail.gmail.com>
 <20150805112713.GY7557@n2100.arm.linux.org.uk>
 <1439315290.3153.11.camel@redhat.com>
 <20150811181008.GA7557@n2100.arm.linux.org.uk>
 <alpine.LFD.2.20.1508111501130.1515@knanqh.ubzr>
 <20150811195638.GC7557@n2100.arm.linux.org.uk>
 <alpine.LFD.2.20.1508111558210.1515@knanqh.ubzr>
 <1439327845.3153.17.camel@redhat.com>
Message-ID: <alpine.LFD.2.20.1508112116320.1515@knanqh.ubzr>

On Tue, 11 Aug 2015, Mark Salter wrote:

> On Tue, 2015-08-11 at 16:20 -0400, Nicolas Pitre wrote:
> > On Tue, 11 Aug 2015, Russell King - ARM Linux wrote:
> > 
> > > It needs fixing or removing.
> > 
> > Absolutely. I'm not disputing that. I'm only asking so we can wisely 
> > choose between fixing or removing.  Personally I'd be inclined towards 
> > the later, unless the following is sufficient to fix it:
> > 
> > diff --git a/arch/arm/lib/uaccess_with_memcpy.c 
> > b/arch/arm/lib/uaccess_with_memcpy.c
> > index 3e58d71001..4b39af2dfd 100644
> > --- a/arch/arm/lib/uaccess_with_memcpy.c
> > +++ b/arch/arm/lib/uaccess_with_memcpy.c
> > @@ -96,7 +96,7 @@ __copy_to_user_memcpy(void __user *to, const void 
> > *from, unsigned long n)
> >  	}
> >  
> >  	/* the mmap semaphore is taken only if not in an atomic context 
> > */
> > -	atomic = in_atomic();
> > +	atomic = faulthandler_disabled();
> >  
> >  	if (!atomic)
> >  		down_read(&current->mm->mmap_sem);
> 
> Yeah, that fixes the problem I was seeing.

Good!  Then I'll add it to RMK's patch system.  May I add a tested-by 
tag with your name?

> This was on a calxeda highbank.

Any idea why this option was set?

> With CONFIG_UACCESS_WITH_MEMCPY, the dd copy test reported 1.8GB/s
> Without CONFIG_UACCESS_WITH_MEMCPY, 2.1GB/s

Therefore this is of no benefit to you.


Nicolas


From shawnguo at kernel.org  Tue Aug 11 19:34:57 2015
From: shawnguo at kernel.org (Shawn Guo)
Date: Wed, 12 Aug 2015 10:34:57 +0800
Subject: [GIT PULL] i.MX clock updates for 4.2
In-Reply-To: <20150811174657.2416.1270@quantum>
References: <20150811085921.GB10035@tiger> <20150811174657.2416.1270@quantum>
Message-ID: <20150812023456.GC10035@tiger>

On Tue, Aug 11, 2015 at 10:46:57AM -0700, Michael Turquette wrote:
> Hi Shawn,
> 
> Quoting Shawn Guo (2015-08-11 01:59:21)
> > Hi Michael, Stephen,
> > 
> > The i.MX clock drivers were moved into drivers/clk/imx folder since
> > v4.2-rc1, so I would like to send i.MX clock changes through clock tree
> > from this cycle.  Here is my first pull request to you guys.  I'm using
> > signed tags, same as how I work with arm-soc folks.  Let me know if
> > there is any problem with it.
> 
> Everything looks good. Pulled.

Thanks, Mike.

> 
> > 
> > Also, please keep it stable, because I need to pull it into other
> > branch as dependency which I will send via arm-soc tree.
> 
> Will do.
> 
> Also, the clock driver was not Cc'd to linux-clk mailing list nor did it
> Cc myself or Stephen. I've taken a quick look at it and it seems fine,
> but please post clk patches to the linux-clk mailing list in the future.

I will ensure that all i.MX clock patches get Cc'd to linux-clk and you
guys in the future.

Shawn


From shawnguo at kernel.org  Tue Aug 11 19:36:10 2015
From: shawnguo at kernel.org (Shawn Guo)
Date: Wed, 12 Aug 2015 10:36:10 +0800
Subject: [GIT PULL] i.MX clock updates for 4.2
In-Reply-To: <20150811183425.GL2839@codeaurora.org>
References: <20150811085921.GB10035@tiger> <20150811174657.2416.1270@quantum>
 <20150811183425.GL2839@codeaurora.org>
Message-ID: <20150812023609.GD10035@tiger>

On Tue, Aug 11, 2015 at 11:34:25AM -0700, Stephen Boyd wrote:
> Yes. We would have found this unused include too. I'll apply this
> after we merge it into clk-next.

Thanks Stephen for the fixup.  I will make sure that i.MX clock patches
get Cc'd to you and Mike.

Shawn

> 
> ----8<----
> From: Stephen Boyd <sboyd at codeaurora.org>
> Subject: [PATCH] clk: imx: Remove unused clkdev.h include
> 
> Signed-off-by: Stephen Boyd <sboyd at codeaurora.org>
> ---
>  drivers/clk/imx/clk-imx6ul.c | 1 -
>  1 file changed, 1 deletion(-)
> 
> diff --git a/drivers/clk/imx/clk-imx6ul.c b/drivers/clk/imx/clk-imx6ul.c
> index aaa36650695f..c498f558e942 100644
> --- a/drivers/clk/imx/clk-imx6ul.c
> +++ b/drivers/clk/imx/clk-imx6ul.c
> @@ -11,7 +11,6 @@
>  
>  #include <dt-bindings/clock/imx6ul-clock.h>
>  #include <linux/clk.h>
> -#include <linux/clkdev.h>
>  #include <linux/err.h>
>  #include <linux/init.h>
>  #include <linux/io.h>
> -- 
> Qualcomm Innovation Center, Inc. is a member of Code Aurora Forum,
> a Linux Foundation Collaborative Project


From 21cnbao at gmail.com  Tue Aug 11 19:39:09 2015
From: 21cnbao at gmail.com (Barry Song)
Date: Wed, 12 Aug 2015 10:39:09 +0800
Subject: [PATCH 5/7] clk: atlas7: fix the clock tree for bluetooth stuff
In-Reply-To: <20150812000229.GB26614@codeaurora.org>
References: <1438064845-17894-1-git-send-email-21cnbao@gmail.com>
 <1438064845-17894-6-git-send-email-21cnbao@gmail.com>
 <55B7FD22.10609@codeaurora.org>
 <CAGsJ_4wg1+5KrwTJRzE-iaSTvgvgFrM6cDyUTL16gx6Hk+tdPw@mail.gmail.com>
 <55C2BBED.4050608@codeaurora.org>
 <CAGsJ_4y=TC1LXC1CPB=c1bfY7ZR0ktMD+hVuUZWxXXpyRR9zEw@mail.gmail.com>
 <20150812000229.GB26614@codeaurora.org>
Message-ID: <CAGsJ_4x3L=p1tR7bg=d8WwLe_2ojZgCw4aiuN5quM7YtP150tg@mail.gmail.com>

2015-08-12 8:02 GMT+08:00 Stephen Boyd <sboyd at codeaurora.org>:
> On 08/10, Barry Song wrote:
>> 2015-08-06 9:44 GMT+08:00 Stephen Boyd <sboyd at codeaurora.org>:
>> >
>> > This actually points out a big problem we have right now in Linux, which is
>> > the lack of proper power management for the type of bus topology you see in
>> > embedded systems. Some of the genpd work going on may also be another
>> > solution to this problem, where we could group multiple devices into generic
>> > power domains that know to turn on 2 or 3 of the clocks. For example, the
>> > DMAC, USP, and UART device could all be in the APB power domain so that the
>> > a7ca_io_clk is enabled whenever one of those devices is active. And there
>> > could be another power domain for the NOC that encompasses all devices that
>> > are sitting on that NOC.
>> >
>>
>> Stephen, this should be a possible option, i will talk with HW guys to
>> figure out the relationship of power domain, and check whether we
>> handle this issue by the power domain solution.
>>
>> btw, would you apply other patches in this series at first? we can
>> hold on this one to find a final solution.
>>
>
> Yes. I'll apply the rest to clk-next.

Stephen, thanks a lot. i think more about the power domain solution.
we can re-look at the attached diagram(btm.png) again.

usp3 requires btm_io_clk and uart6_io_clk;
uart6_io requires btm_io_clk and dmac4_io_clk;
dmac4_io requires btm_io_clk and a7ca_io_clk;
a7ca_io requires btm_io_clk and btm_noc_clk;

if we put these things in a power domain, it seems we can enable these
clocks together or disable them together. but it seems we can't
describe the dependency how.

for example, if someone wants to use usp3, it means all clocks should
be enabled.
but if someone only wants to use a7ca_io, it means only btm_io_clk and
btm_noc_clk should be enabled, others should be disabled.
and if someone wants to use dmac4_io, then btm_io_clk , btm_noc_clk
and a7ca_io_clk should be enabled, others should be disabled.

it is difficult to find any power domain things can really resolve the
right dependency of the clock except that we can do such a power
domain as diagram pd.png. but the problem is this is the powerdomain
design in the real hardware.

it turns out the current patch really resolves all problems except
that it is not a right description to clock tree. but it does build a
good dependency map for the relationship of the clocks.

-barry
-------------- next part --------------
A non-text attachment was scrubbed...
Name: btm.PNG
Type: image/png
Size: 5993 bytes
Desc: not available
URL: <http://lists.infradead.org/pipermail/linux-arm-kernel/attachments/20150812/0795135e/attachment.png>
-------------- next part --------------
A non-text attachment was scrubbed...
Name: pd.png
Type: image/png
Size: 4527 bytes
Desc: not available
URL: <http://lists.infradead.org/pipermail/linux-arm-kernel/attachments/20150812/0795135e/attachment-0001.png>

From david at fromorbit.com  Tue Aug 11 20:14:07 2015
From: david at fromorbit.com (Dave Chinner)
Date: Wed, 12 Aug 2015 13:14:07 +1000
Subject: PROBLEM: XFS on ARM corruption 'Structure needs cleaning'
In-Reply-To: <C6D0D499B56584katsuki.uwatoko@toshiba.co.jp>
References: <5579B804.9050707@skylable.com>
 <20150612122108.GB60661@bfoster.bfoster>
 <557AD4D4.3010901@skylable.com> <20150612225209.GA20262@dastard>
 <C6D0D499B56584katsuki.uwatoko@toshiba.co.jp>
Message-ID: <20150812031407.GB20596@dastard>

On Wed, Aug 12, 2015 at 12:56:25AM +0000, katsuki.uwatoko at toshiba.co.jp wrote:
> On Sat, 13 Jun 2015 08:52:09 +1000, Dave Chinner wrote:
> 
> > Yup, that's looking like a toolchain bug. Thread about arm directory
> > read corruption:
> 
> I think that this is not a toolchain bug, this is related to 
> Subject: [PATCH v2 1/1] ARM : missing corrupted reg in __do_div_asm
> http://www.spinics.net/lists/arm-kernel/msg426684.html

Interesting! Very good work finding that bug, Katsuki-san. 

FWIW, I suspect this fix will need to go back into stable kernels,
too.

> --
> 
> The problematic line in xfs is: 
> irecs->br_startblock = XFS_DADDR_TO_FSB(mp, mappedbno)
> in xfs_dabuf_map()/fs/xfs/xfs_da_btree.c.
> 
> The expansion of it is: 
> 
>   ld = mappedbno >> mp->m_blkbb_log;
>   do_div(ld, mp->m_sb.sb_agblocks);
>   startblock = ld << mp->m_sb.sb_agblklog;
>   ld = mappedbno >> mp->m_blkbb_log;
>   startblock |= do_div(ld, mp->m_sb.sb_agblocks);
>   irecs->br_startblock = startblock;
> 
> The assembler of these are:
> 
> :
> 	bl	__do_div64
> 	ldr	r1, [sp, #44]
> 	subs	r3, r7, #32
> 	orr	r1, r1, r2, lsr r5
> 	add	r5, sp, #80
> 	str	r5, [sp, #64]
> 	ldr	r5, [sp, #60]
> 	movpl	r1, r2, asl r3
> 	mov	r2, r2, asl r7
> 	str	r2, [sp, #40]
> 	str	r1, [sp, #44]
> 	mov	r1, r9
> 	str	r5, [sp, #96]
> 	mov	r7, #0
> 	ldr	r2, [sp, #96]
> 	mov	r5, #1
> 	ldr	fp, [sp, #64]
> 	str	r7, [sp, #84]
> 	mov	r9, r2, asr #31
> 	str	r7, [sp, #104]
> 	bl	__do_div64
> :
> 
> by GCC 4.7.2 with -O2 option.

To close the loop, what code do the other versions GCC produce for
this macro?  Evidence so far says that the result depends on the
compiler version, so I would like to have confirmation that other
versions of the compiler generate working code.  There are other
XFS_DADDR_TO_FSB() calls in the XFS code, too - do they demonstrate
the same problem, maybe with different compiler versions?

Basically I'm asking what is the scope of the problem you've found?
i.e. when was the bug introduced, what compilers expose it, etc
so that when ARM users report XFS corruptions we have some idea of
whether their kernel/compiler combination might have caused the
issue they are seeing...

Cheers,

Dave.
-- 
Dave Chinner
david at fromorbit.com


From long.wanglong at huawei.com  Tue Aug 11 20:14:23 2015
From: long.wanglong at huawei.com (long.wanglong)
Date: Wed, 12 Aug 2015 11:14:23 +0800
Subject: How to support multiple watchpoints on kernel after 3.10 when using
 arm debug architectures prior to 7.1?
Message-ID: <55CABA0F.9020901@huawei.com>

Hi, all

The linux kernel after 3.10 (after the commit c512de95 "ARM:
hw_breakpoint: reserve one breakpoint for watchpoint stepping" )
reserve a single breakpoint, regardless of the number of watchpoints,
when the hardware use the ARM Debug architectures prior to 7.1.

On these older CPUS, how to support multiple watchpoints when
using kernel after 3.10?

Are there any risks if we change the function 'get_num_wrps(void)'
and force it returning the number of watchpoints the hardware have?

Best Regards
Wang Long



From wens at csie.org  Tue Aug 11 20:17:11 2015
From: wens at csie.org (Chen-Yu Tsai)
Date: Wed, 12 Aug 2015 11:17:11 +0800
Subject: [PATCH v2 5/7] ARM: sun8i: Add clock indices
In-Reply-To: <20150811175019.2416.93864@quantum>
References: <1438364782-3968-1-git-send-email-maxime.ripard@free-electrons.com>
 <1438364782-3968-6-git-send-email-maxime.ripard@free-electrons.com>
 <CAGb2v64nvA1K=Ya7_99-2G1LtFjcuj+qQbO1GJaqsL+yPF+Xdw@mail.gmail.com>
 <CAGb2v64-=1Byzo-h=7Pq=HK9Xx01KaTKT89Nx6jVWUc_kqthyg@mail.gmail.com>
 <20150811175019.2416.93864@quantum>
Message-ID: <CAGb2v65AtLwsnk11qHj6K_JzO2+2C9tcp3QBUeSzVBuJZ+Feeg@mail.gmail.com>

On Wed, Aug 12, 2015 at 1:50 AM, Michael Turquette
<mturquette at baylibre.com> wrote:
> Quoting Chen-Yu Tsai (2015-08-10 21:49:54)
>> On Sat, Aug 8, 2015 at 12:21 AM, Chen-Yu Tsai <wens at csie.org> wrote:
>> > On Sat, Aug 1, 2015 at 1:46 AM, Maxime Ripard
>> > <maxime.ripard at free-electrons.com> wrote:
>> >> The A23 and A33 gates have a non continuous set of clock IDs that are
>> >> valid. Add the clock-indices property to the DT to express this.
>> >>
>> >> Signed-off-by: Maxime Ripard <maxime.ripard at free-electrons.com>
>> >> ---
>> >>  arch/arm/boot/dts/sun8i-a23-a33.dtsi | 15 +++++++++++++++
>> >>  1 file changed, 15 insertions(+)
>> >>
>> >> diff --git a/arch/arm/boot/dts/sun8i-a23-a33.dtsi b/arch/arm/boot/dts/sun8i-a23-a33.dtsi
>> >> index 7abd0ae3143d..c318c770b6c1 100644
>> >> --- a/arch/arm/boot/dts/sun8i-a23-a33.dtsi
>> >> +++ b/arch/arm/boot/dts/sun8i-a23-a33.dtsi
>> >> @@ -180,6 +180,15 @@
>> >>                         compatible = "allwinner,sun8i-a23-ahb1-gates-clk";
>> >>                         reg = <0x01c20060 0x8>;
>> >>                         clocks = <&ahb1>;
>> >> +                       clock-indices = <1>, <6>,
>> >
>> > Turns out the A33 (and I assume the same with the A23) has
>> > an ahb1 clock gate for the Security System at clock-index <5>.
>>
>> Looks like the A23 does not have this one, nor the SS mod clock.
>>
>> > This is found in the updated A33 user manual.
>> >
>> >> +                                       <8>, <9>, <10>,
>> >> +                                       <13>, <14>,
>> >> +                                       <19>, <20>,
>> >> +                                       <21>, <24>, <26>,
>> >> +                                       <29>, <32>, <36>,
>> >> +                                       <40>, <44>, <46>,
>> >> +                                       <52>, <54>,
>> >
>> > <53> is ahb1 clock gate for msgbox, again found in A33 manual.
>>
>> A23 has this one. Found in Allwinner kernel sources.
>>
>> >> +                                       <57>;
>> >
>> > <58> is ahb1 clock gate for SAT, which seems to be part of the
>> > display pipeline.
>>
>> This one is A33 only.
>>
>> I guess we should do a separate compatible for A33 AHB1 clock gates.
>
> ChenYu,
>
> I believe Maxime is on vacation. I told him that I would pick these
> patches directly. It looks like your comments can be fixed up in
> follow-up patches at a later date, correct?

That's right. I was mostly asking how to proceed with adding them.

> If so then I will apply them to clk-next.

Please do. (I see they are already in.)

Thanks
ChenYu


> Regards,
> Mike
>
>>
>> ChenYu
>>
>> >>                         clock-output-names = "ahb1_mipidsi", "ahb1_dma",
>> >>                                         "ahb1_mmc0", "ahb1_mmc1", "ahb1_mmc2",
>> >>                                         "ahb1_nand", "ahb1_sdram",
>> >> @@ -196,6 +205,8 @@
>> >>                         compatible = "allwinner,sun8i-a23-apb1-gates-clk";
>> >>                         reg = <0x01c20068 0x4>;
>> >>                         clocks = <&apb1>;
>> >> +                       clock-indices = <0>, <5>,
>> >> +                                       <12>, <13>;
>> >>                         clock-output-names = "apb1_codec", "apb1_pio",
>> >>                                         "apb1_daudio0", "apb1_daudio1";
>> >>                 };
>> >> @@ -213,6 +224,10 @@
>> >>                         compatible = "allwinner,sun8i-a23-apb2-gates-clk";
>> >>                         reg = <0x01c2006c 0x4>;
>> >>                         clocks = <&apb2>;
>> >> +                       clock-indices = <0>, <1>,
>> >> +                                       <2>, <16>,
>> >> +                                       <17>, <18>,
>> >> +                                       <19>, <20>;
>> >>                         clock-output-names = "apb2_i2c0", "apb2_i2c1",
>> >>                                         "apb2_i2c2", "apb2_uart0",
>> >>                                         "apb2_uart1", "apb2_uart2",
>> >> --
>> >> 2.4.6
>> >>
>> >
>> > Not sure if you want to add the clocks I mentioned together
>> > in this patch, or do a separate patch.
>> >
>> > The rest look good.
>> >
>> > ChenYu
>>
>> _______________________________________________
>> linux-arm-kernel mailing list
>> linux-arm-kernel at lists.infradead.org
>> http://lists.infradead.org/mailman/listinfo/linux-arm-kernel


From dongsheng.wang at freescale.com  Tue Aug 11 21:01:00 2015
From: dongsheng.wang at freescale.com (Dongsheng Wang)
Date: Wed, 12 Aug 2015 12:01:00 +0800
Subject: [PATCH v3 1/2] Documentation: DT: FTM: add FTM0 be used as alarm timer
Message-ID: <1439352061-14656-1-git-send-email-dongsheng.wang@freescale.com>

From: Wang Dongsheng <dongsheng.wang at freescale.com>

In freescale layerscape platform there is only FTM0 can be used as
alarm timer to wake up system. So add FTM0 description for devicetree
document.

Signed-off-by: Wang Dongsheng <dongsheng.wang at freescale.com>
---
V3:
Include this patch in V3.

diff --git a/Documentation/devicetree/bindings/timer/fsl,ftm-timer.txt b/Documentation/devicetree/bindings/timer/fsl,ftm-timer.txt
index aa8c402..380a0b3d 100644
--- a/Documentation/devicetree/bindings/timer/fsl,ftm-timer.txt
+++ b/Documentation/devicetree/bindings/timer/fsl,ftm-timer.txt
@@ -1,5 +1,7 @@
 Freescale FlexTimer Module (FTM) Timer
 
+* Default FTM Timer
+
 Required properties:
 
 - compatible : should be "fsl,ftm-timer"
@@ -29,3 +31,26 @@ ftm: ftm at 400b8000 {
 		<&clks VF610_CLK_FTM3_EXT_FIX_EN>;
 	big-endian;
 };
+
+* FTM Alarm Timer
+  The default FTM device contains eight FlexTimer modules. FlexTimer1 is in
+  on-domain(power is not switched off in deep sleep mode). Other seven FlexTimer
+  modules(flextimer2/3/4/5/6/7/8) are in off-domain (power is switched off in
+  deep sleep mode).
+
+Required properties:
+
+- compatible : should be "fsl,ftm-alarm".
+- reg : should contain base address and length of FTM timer 0 register.
+- interrupts : Should contain FTM 0 interrupt.
+- big-endian: One boolean property, the big endian mode will be in use if it is
+  present, or the little endian mode will be in use for all the device registers.
+
+Example:
+ftm0: ftm0 at 29d0000 {
+	compatible = "fsl,ftm-alarm";
+	reg = <0x0 0x29d0000 0x0 0x10000>;
+	interrupts = <GIC_SPI 118 IRQ_TYPE_LEVEL_HIGH>;
+	big-endian;
+	status = "disabled";
+};
-- 
2.1.0.27.g96db324



From dongsheng.wang at freescale.com  Tue Aug 11 21:01:01 2015
From: dongsheng.wang at freescale.com (Dongsheng Wang)
Date: Wed, 12 Aug 2015 12:01:01 +0800
Subject: [PATCH v3 2/2] ARM: dts: ls1021a: add wakeup device ftm0 node for
 ls1021a
In-Reply-To: <1439352061-14656-1-git-send-email-dongsheng.wang@freescale.com>
References: <1439352061-14656-1-git-send-email-dongsheng.wang@freescale.com>
Message-ID: <1439352061-14656-2-git-send-email-dongsheng.wang@freescale.com>

From: Wang Dongsheng <dongsheng.wang at freescale.com>

Add ftm0 node, cause of ftm0 can be set as a alarm before system going
to deep sleep.

Signed-off-by: Wang Dongsheng <dongsheng.wang at freescale.com>
Signed-off-by: Alison Wang <alison.wang at freescale.com>
---
*V3*
- No changes.

*V2*
- Add my SoB.
- Use "ARM:" as subject prefix.

diff --git a/arch/arm/boot/dts/ls1021a-qds.dts b/arch/arm/boot/dts/ls1021a-qds.dts
index 9c5e16b..f14731b 100644
--- a/arch/arm/boot/dts/ls1021a-qds.dts
+++ b/arch/arm/boot/dts/ls1021a-qds.dts
@@ -75,6 +75,10 @@
 	};
 };
 
+&ftm0 {
+	status = "okay";
+};
+
 &i2c0 {
 	status = "okay";
 
diff --git a/arch/arm/boot/dts/ls1021a.dtsi b/arch/arm/boot/dts/ls1021a.dtsi
index c70bb27..7e9e122 100644
--- a/arch/arm/boot/dts/ls1021a.dtsi
+++ b/arch/arm/boot/dts/ls1021a.dtsi
@@ -332,6 +332,14 @@
 			status = "disabled";
 		};
 
+		ftm0: ftm0 at 29d0000 {
+			compatible = "fsl,ftm-alarm";
+			reg = <0x0 0x29d0000 0x0 0x10000>;
+			interrupts = <GIC_SPI 118 IRQ_TYPE_LEVEL_HIGH>;
+			big-endian;
+			status = "disabled";
+		};
+
 		wdog0: watchdog at 2ad0000 {
 			compatible = "fsl,imx21-wdt";
 			reg = <0x0 0x2ad0000 0x0 0x10000>;
-- 
2.1.0.27.g96db324



From wxt at rock-chips.com  Tue Aug 11 21:42:28 2015
From: wxt at rock-chips.com (Caesar Wang)
Date: Wed, 12 Aug 2015 12:42:28 +0800
Subject: [PATCH v16 0/4] ARM: rk3288: Add PM Domain support
Message-ID: <1439354552-20098-1-git-send-email-wxt@rock-chips.com>

Add power domain drivers based on generic power domain for
Rockchip platform, and support RK3288 SoCs.

Verified on url =
https://chromium.googlesource.com/chromiumos/third_party/kernel/+/v3.14
localhost / # cat /sys/kernel/debug/pm_genpd/pm_genpd_summary
    domain                      status         slaves
    /device                      runtime        status
               ----------------------------------------------------------------------
    pd_video                        off
    /devices/ff9a0800.iommu                     suspended
    /devices/ff9a0000.video-codec               suspended
    pd_vio                          on
    /devices/ff930300.iommu                     suspended
    /devices/ff940300.iommu                     suspended
    /devices/ff930000.vop                       suspended
    /devices/ff940000.vop                       suspended
    /devices/ff980000.hdmi                      unsupported
    /devices/rockchip-edp                       unsupported
    pd_hevc                         off
    pd_gpu                          off
    /devices/ffa30000.gpu                       suspended

The following is the easy example.

vopb: vop at ff930000 {
    compatible = "rockchip,rk3288-vop";
    ...
    iommus = <&vopb_mmu>;
    power-domains = <&power RK3288_PD_VIO>;
    status = "disabled";
    ...
};

vopb_mmu: iommu at ff930300 {
    compatible = "rockchip,iommu";
    ...
    interrupt-names = "vopb_mmu";
    power-domains = <&power RK3288_PD_VIO>;
    #iommu-cells = <0>;
    status = "disabled";
    ...
};

vopl: vop at ff940000 {
    compatible = "rockchip,rk3288-vop";
    reg = <0xff940000 0x19c>;
    ...
    iommus = <&vopl_mmu>;
    power-domains = <&power RK3288_PD_VIO>;
    status = "disabled";
    ...
};

vopl_mmu: iommu at ff940300 {
    compatible = "rockchip,iommu";
    ...
    interrupt-names = "vopl_mmu";
    power-domains = <&power RK3288_PD_VIO>;
    #iommu-cells = <0>;
    status = "disabled";
};

Others, we can verify this driver for the EDP.
We can apply the following these patchs.

6967631 New          [v2,1/8] drm: exynos/dp: fix code style
6967741 New          [v2,2/8] drm: exynos/dp: convert to drm bridge mode
6967801 New          [v2,3/8] drm: bridge: analogix_dp: split exynos dp driver to bridge dir
6967791 New          [v2,4/8] drm: rockchip/dp: add rockchip platform dp driver
6968031 New          [v2,5/8] drm: bridge/analogix_dp: add platform device type support
6968141 New          [v2,6/8] drm: bridge: analogix_dp: add some rk3288 special registers setting
6967941 New          [v2,7/8] drm: bridge: analogix_dp: try force hpd after plug in lookup failed
6967971 New          [v2,8/8] drm: bridge/analogix_dp: expand the delay time for hpd detect

There is a recent addition from Linus Walleij,
called simple-mfd [a] that is supposed to get added real early for kernel 4.2

[a]:
https://git.kernel.org/cgit/linux/kernel/git/linusw/linux-integrator.git/commit/?h=simple-mfd&id=fcf294c020ff7ee4e3b1e96159e4dc7a17ad59d1

Here is my branch, Tested by chromeos-3.14 and next-kernel.

2b82899 ARM: dts: add RK3288 power-domain node
69d0b5b soc: rockchip: power-domain: support power domain driver for
RK3288 SoCs
66f8758 ARM: power-domain: rockchip: add all the domain type on RK3288
SoCs
c5f12a3 dt-bindings: add document of Rockchip power domain
7a834ba Merge branch 'for-linus' of
git://git.kernel.org/pub/scm/linux/kernel/git/jikos/hid
0be0171 HID: wacom: Report correct device resolution when using the
wireless adapater
2b9bea0 Merge tag 'mfd-fixes-4.2' of
git://git.kernel.org/pub/scm/linux/kernel/git/lee/mfd
016a9f5 Merge tag 'ntb-4.2-rc7' of git://github.com/jonmason/ntb
a3ca013 Merge branch 'for-linus' of
git://git.kernel.org/pub/scm/linux/kernel/git/viro/vfs
......

Caesar Wang (4):
  dt-bindings: add document of Rockchip power domain
  ARM: power-domain: rockchip: add all the domain type on RK3288 SoCs
  soc: rockchip: power-domain: Add power domain driver
  ARM: dts: add the support power-domain node on RK3288 SoCs

 .../bindings/soc/rockchip/power_domain.txt         |  46 ++
 arch/arm/boot/dts/rk3288.dtsi                      |  60 ++-
 drivers/soc/Kconfig                                |   1 +
 drivers/soc/Makefile                               |   1 +
 drivers/soc/rockchip/Kconfig                       |  13 +
 drivers/soc/rockchip/Makefile                      |   4 +
 drivers/soc/rockchip/pm_domains.c                  | 485 +++++++++++++++++++++
 include/dt-bindings/power-domain/rk3288.h          |  31 ++
 8 files changed, 640 insertions(+), 1 deletion(-)
 create mode 100644 Documentation/devicetree/bindings/soc/rockchip/power_domain.txt
 create mode 100644 drivers/soc/rockchip/Kconfig
 create mode 100644 drivers/soc/rockchip/Makefile
 create mode 100644 drivers/soc/rockchip/pm_domains.c
 create mode 100644 include/dt-bindings/power-domain/rk3288.h

-- 
1.9.1



From wxt at rock-chips.com  Tue Aug 11 21:42:29 2015
From: wxt at rock-chips.com (Caesar Wang)
Date: Wed, 12 Aug 2015 12:42:29 +0800
Subject: [PATCH v16 1/4] dt-bindings: add document of Rockchip power domain
In-Reply-To: <1439354552-20098-1-git-send-email-wxt@rock-chips.com>
References: <1439354552-20098-1-git-send-email-wxt@rock-chips.com>
Message-ID: <1439354552-20098-2-git-send-email-wxt@rock-chips.com>

This add the necessary binding documentation for the power domain
found on Rockchip Socs.

Signed-off-by: jinkun.hong <jinkun.hong at rock-chips.com>
Signed-off-by: Caesar Wang <wxt at rock-chips.com>

---

Changes in v16:
- remove the pmu node.
Series-changes:9
- add document decription.
Series-changes: 8
- document go back to v2.
Series-changes: 3
- DT structure has changed.
Series-changes: 2
- move clocks to "optional".

 .../bindings/soc/rockchip/power_domain.txt         | 46 ++++++++++++++++++++++
 1 file changed, 46 insertions(+)
 create mode 100644 Documentation/devicetree/bindings/soc/rockchip/power_domain.txt

diff --git a/Documentation/devicetree/bindings/soc/rockchip/power_domain.txt b/Documentation/devicetree/bindings/soc/rockchip/power_domain.txt
new file mode 100644
index 0000000..138754d
--- /dev/null
+++ b/Documentation/devicetree/bindings/soc/rockchip/power_domain.txt
@@ -0,0 +1,46 @@
+* Rockchip Power Domains
+
+Rockchip processors include support for multiple power domains which can be
+powered up/down by software based on different application scenes to save power.
+
+Required properties for power domain controller:
+- compatible: Should be one of the following.
+	"rockchip,rk3288-power-controller" - for RK3288 SoCs.
+- #power-domain-cells: Number of cells in a power-domain specifier.
+	Should be 1 for multiple PM domains.
+- #address-cells: Should be 1.
+- #size-cells: Should be 0.
+
+Required properties for power domain sub nodes:
+- reg: index of the power domain, should use macros in:
+	"include/dt-bindings/power-domain/rk3288.h" - for rk3288 type power domain.
+- clocks (optional): phandles to clocks which need to be enabled while power domain
+	switches state.
+
+Example:
+
+	power: power-controller {
+		compatible = "rockchip,rk3288-power-controller";
+		#power-domain-cells = <1>;
+		#address-cells = <1>;
+		#size-cells = <0>;
+
+		pd_gpu {
+			reg = <RK3288_PD_GPU>;
+			clocks = <&cru ACLK_GPU>;
+		};
+	};
+
+Node of a device using power domains must have a power-domains property,
+containing a phandle to the power device node and an index specifying which
+power domain to use.
+The index should use macros in:
+	"include/dt-bindings/power-domain/rk3288.h" - for rk3288 type power domain.
+
+Example of the node using power domain:
+
+	node {
+		/* ... */
+		power-domains = <&power RK3288_PD_GPU>;
+		/* ... */
+	};
-- 
1.9.1



From wxt at rock-chips.com  Tue Aug 11 21:42:30 2015
From: wxt at rock-chips.com (Caesar Wang)
Date: Wed, 12 Aug 2015 12:42:30 +0800
Subject: [PATCH v16 2/4] ARM: power-domain: rockchip: add all the domain type
 on RK3288 SoCs
In-Reply-To: <1439354552-20098-1-git-send-email-wxt@rock-chips.com>
References: <1439354552-20098-1-git-send-email-wxt@rock-chips.com>
Message-ID: <1439354552-20098-3-git-send-email-wxt@rock-chips.com>

According to a description from TRM, the following table lists
all the power domains.

------------------------   -------------------------
|VD_CORE               |   |VD_LOGIC    |  PD_VIO  |
|xxxxxxxxxxxxxxxxxxxx  |   |xxxxxxxx    -----------|
|xxxxxxxxxxxxxxxxxxxx  |   |xxxxxxxx               |
|xxxxxxxxxxxxxxxxxxxx  |   |                       |
|xxxxxxxxxxxxxxxxxxxx  |   |---------   -----------|
|                      |   |PD_PERI  |  | PD_VIDEO |
|                      |   |---------   -----------|
|                      |   |---------   -----------|
|                      |   |PD_ALIVE |  | PD_HEVC  |
|---------- ---------- |   |---------   -----------|
||PD_A17_1| |PD_A17_2| |   -------------------------
|---------- ---------- |   |VD_GPU      |PD_GPU    |
|---------- ---------- |   -------------------------
||PD_A17_3| |PD_DEBUG| |   -------------------------
|---------- ---------- |   |VD_PMU      |PD_PMU    |
------------------------   -------------------------
VD_* :  voltage domain
PD_* :  power domain

At the moment, we can support some power-domain type on RK3288.
We can add more types on RK3288 in the future, that's need to do.

Signed-off-by: Caesar Wang <wxt at rock-chips.com>

---

Changes in v16:
- Add more domain decription.
Series-changes: 15
- change the comment.

 include/dt-bindings/power-domain/rk3288.h | 31 +++++++++++++++++++++++++++++++
 1 file changed, 31 insertions(+)
 create mode 100644 include/dt-bindings/power-domain/rk3288.h

diff --git a/include/dt-bindings/power-domain/rk3288.h b/include/dt-bindings/power-domain/rk3288.h
new file mode 100644
index 0000000..db5e810
--- /dev/null
+++ b/include/dt-bindings/power-domain/rk3288.h
@@ -0,0 +1,31 @@
+#ifndef __DT_BINDINGS_POWER_DOMAIN_RK3288_H__
+#define __DT_BINDINGS_POWER_DOMAIN_RK3288_H__
+
+/**
+ * RK3288 Power Domain and Voltage Domain Summary.
+ */
+
+/* VD_CORE */
+#define RK3288_PD_A17_0		0
+#define RK3288_PD_A17_1		1
+#define RK3288_PD_A17_2		2
+#define RK3288_PD_A17_3		3
+#define RK3288_PD_SCU		4
+#define RK3288_PD_DEBUG		5
+#define RK3288_PD_MEM		6
+
+/* VD_LOGIC */
+#define RK3288_PD_BUS		7
+#define RK3288_PD_PERI		8
+#define RK3288_PD_VIO		9
+#define RK3288_PD_ALIVE		10
+#define RK3288_PD_HEVC		11
+#define RK3288_PD_VIDEO		12
+
+/* VD_GPU */
+#define RK3288_PD_GPU		13
+
+/* VD_PMU */
+#define RK3288_PD_PMU		14
+
+#endif
-- 
1.9.1



From wxt at rock-chips.com  Tue Aug 11 21:42:31 2015
From: wxt at rock-chips.com (Caesar Wang)
Date: Wed, 12 Aug 2015 12:42:31 +0800
Subject: [PATCH v16 3/4] soc: rockchip: power-domain: Add power domain driver
In-Reply-To: <1439354552-20098-1-git-send-email-wxt@rock-chips.com>
References: <1439354552-20098-1-git-send-email-wxt@rock-chips.com>
Message-ID: <1439354552-20098-4-git-send-email-wxt@rock-chips.com>

This driver is found on RK3288 SoCs.

In order to meet high performance and low power requirements, a power
management unit is designed or saving power when RK3288 in low power
mode.
The RK3288 PMU is dedicated for managing the power of the whole chip.

PMU can work in the Low Power Mode by setting bit[0] of PMU_PWRMODE_CON
register. After setting the register, PMU would enter the Low Power mode.
In the low power mode, pmu will auto power on/off the specified power
domain, send idle req to specified power domain, shut down/up pll and
so on. All of above are configurable by setting corresponding registers.

Signed-off-by: jinkun.hong <jinkun.hong at rock-chips.com>
Signed-off-by: Caesar Wang <wxt at rock-chips.com>

---

Changes in v16:
- the driver type from tristate to bool.
- Letter misspelled.
- As Ulf suggestion, remove #include <linux/clk-provider.h>,
  use "%pC" as the formatting string for the dev_dbg().
- As the Ulf suggestion, set the genpd->flags to assign the
  ->stop|start() callbacks.
Series-changes: 15
- As the kevin suggestion, put the power-domain driver into driver/soc/vendor.
- As Heiko suggestion, Patch 1: binding doc, 2: binding-header, 3: driver,
  4: dts-changes.
- return -ENXIO --> return -ENODEV.
Series-changes: 14
- does not need to set an owner,remove the "THIS_MODULE".
Series-changes: 13
- Remove essential clocks from rk3288 PD_VIO domain Some clocks are essential
  for the system health and should not be turned down. However there is no owner
  for them so if they listed as belonging to power domain we'll try toggling them
  up and down during power domain.
- Device drivers expect their devices to be powered on before their
  probing code is invoked. To achieve that we should start with
  power domains powered on (we may turn them off later once all devices enable
  runtime powermanagment and go idle).
- This change switches Rockchip power domain driver to use updated
  device_attach and device_detach API.
- set the gpu/core power domain power delay time.
- fix enumerating PM clocks for devices.
- fix use after free We can't use clk after we did clk_put(clk).
Series-changes: 12
- fix the title doamin->domain.
- updated device_attach and device_detach API,otherwise it will
  compile fail on next kernel.
Series-changes: 11
- fix pm_genpd_init(&pd->genpd, NULL, false).
Series-changes: 10
- this switches over domain infos to use masks instead of recomputing
  them each time and also gets rid of custom domain translator and
  uses standard onecell on.
Series-changes: 9
- fix v8 changes as follows:
- This reconciles the v2 and v7 code so that we power domain have lists of clocks
  they trigger on and off during power transitions and independently from power
  domains clocks. We attach clocks to devices comprising power domain and prepare
  them so they are turn on and off by runtime PM.
- add rockchip_pm_add_one_domain() to control domains.
- add pd_start/pd_stop interface to control clocks.
Series-changes: 8
- This reconciles the v2 and v7 code so that we power domain have
  lists of clocks they toggle on and off during power transitions
  and independently from power domains clocks we attach clocks to
  devices comprising power domain and prepare them so they are
  turn on and off by runtime PM.
Series-changes: 7
 - Delete unused variables
Series-changes: 6
- delete pmu_lock.
- modify dev_lock using mutex.
- pm_clk_resume(pd->dev) change to pm_clk_resume(ed->dev).
- pm_clk_suspend(pd->dev) change to pm_clk_suspend(ed->dev).
- add devm_kfree(pd->dev, de) in rockchip_pm_domain_detach_dev.
Series-changes: 5
- delete idle_lock.
- add timeout in rockchip_pmu_set_idle_request().
Series-changes: 4
- use list storage dev.
Series-changes: 3
- change use pm_clk_resume() and pm_clk_suspend().
Series-changes: 2
- remove the "pd->pd.of_node = np".

 drivers/soc/Kconfig               |   1 +
 drivers/soc/Makefile              |   1 +
 drivers/soc/rockchip/Kconfig      |  13 +
 drivers/soc/rockchip/Makefile     |   4 +
 drivers/soc/rockchip/pm_domains.c | 485 ++++++++++++++++++++++++++++++++++++++
 5 files changed, 504 insertions(+)
 create mode 100644 drivers/soc/rockchip/Kconfig
 create mode 100644 drivers/soc/rockchip/Makefile
 create mode 100644 drivers/soc/rockchip/pm_domains.c

diff --git a/drivers/soc/Kconfig b/drivers/soc/Kconfig
index 96ddecb..ecb1a6c 100644
--- a/drivers/soc/Kconfig
+++ b/drivers/soc/Kconfig
@@ -2,6 +2,7 @@ menu "SOC (System On Chip) specific Drivers"
 
 source "drivers/soc/mediatek/Kconfig"
 source "drivers/soc/qcom/Kconfig"
+source "drivers/soc/rockchip/Kconfig"
 source "drivers/soc/sunxi/Kconfig"
 source "drivers/soc/ti/Kconfig"
 source "drivers/soc/versatile/Kconfig"
diff --git a/drivers/soc/Makefile b/drivers/soc/Makefile
index 7dc7c0d..ff8bbfb 100644
--- a/drivers/soc/Makefile
+++ b/drivers/soc/Makefile
@@ -4,6 +4,7 @@
 
 obj-$(CONFIG_ARCH_MEDIATEK)	+= mediatek/
 obj-$(CONFIG_ARCH_QCOM)		+= qcom/
+obj-$(CONFIG_ARCH_ROCKCHIP)		+= rockchip/
 obj-$(CONFIG_ARCH_SUNXI)	+= sunxi/
 obj-$(CONFIG_ARCH_TEGRA)	+= tegra/
 obj-$(CONFIG_SOC_TI)		+= ti/
diff --git a/drivers/soc/rockchip/Kconfig b/drivers/soc/rockchip/Kconfig
new file mode 100644
index 0000000..87a09c3
--- /dev/null
+++ b/drivers/soc/rockchip/Kconfig
@@ -0,0 +1,13 @@
+#
+# Rockchip Soc drivers
+#
+config PM_GENERIC_DOMAINS
+        bool "Rockchip generic power domain"
+        depends on PM
+        help
+          Say y here to enable power domain support.
+          In order to meet high performance and low power requirements, a power
+          management unit is designed or saving power when RK3288 in low power
+          mode. The RK3288 PMU is dedicated for managing the power of the whole chip.
+
+          If unsure, say N.
diff --git a/drivers/soc/rockchip/Makefile b/drivers/soc/rockchip/Makefile
new file mode 100644
index 0000000..1c0fd91
--- /dev/null
+++ b/drivers/soc/rockchip/Makefile
@@ -0,0 +1,4 @@
+#
+# Rockchip Soc drivers
+#
+obj-$(CONFIG_PM_GENERIC_DOMAINS) += pm_domains.o
diff --git a/drivers/soc/rockchip/pm_domains.c b/drivers/soc/rockchip/pm_domains.c
new file mode 100644
index 0000000..fd772d2
--- /dev/null
+++ b/drivers/soc/rockchip/pm_domains.c
@@ -0,0 +1,485 @@
+/*
+ * Rockchip Generic power domain support.
+ *
+ * Copyright (c) 2015 ROCKCHIP, Co. Ltd.
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License version 2 as
+ * published by the Free Software Foundation.
+ */
+
+#include <linux/io.h>
+#include <linux/err.h>
+#include <linux/pm_clock.h>
+#include <linux/pm_domain.h>
+#include <linux/of_address.h>
+#include <linux/of_platform.h>
+#include <linux/clk.h>
+#include <linux/regmap.h>
+#include <linux/mfd/syscon.h>
+#include <dt-bindings/power-domain/rk3288.h>
+
+struct rockchip_domain_info {
+	int pwr_mask;
+	int status_mask;
+	int req_mask;
+	int idle_mask;
+	int ack_mask;
+};
+
+struct rockchip_pmu_info {
+	u32 pwr_offset;
+	u32 status_offset;
+	u32 req_offset;
+	u32 idle_offset;
+	u32 ack_offset;
+
+	u32 core_pwrcnt_offset;
+	u32 gpu_pwrcnt_offset;
+
+	unsigned int core_power_transition_time;
+	unsigned int gpu_power_transition_time;
+
+	int num_domains;
+	const struct rockchip_domain_info *domain_info;
+};
+
+struct rockchip_pm_domain {
+	struct generic_pm_domain genpd;
+	const struct rockchip_domain_info *info;
+	struct rockchip_pmu *pmu;
+	int num_clks;
+	struct clk *clks[];
+};
+
+struct rockchip_pmu {
+	struct device *dev;
+	struct regmap *regmap;
+	const struct rockchip_pmu_info *info;
+	struct mutex mutex; /* mutex lock for pmu */
+	struct genpd_onecell_data genpd_data;
+	struct generic_pm_domain *domains[];
+};
+
+#define to_rockchip_pd(gpd) container_of(gpd, struct rockchip_pm_domain, genpd)
+
+#define DOMAIN(pwr, status, req, idle, ack)	\
+{						\
+	.pwr_mask = BIT(pwr),			\
+	.status_mask = BIT(status),		\
+	.req_mask = BIT(req),			\
+	.idle_mask = BIT(idle),			\
+	.ack_mask = BIT(ack),			\
+}
+
+#define DOMAIN_RK3288(pwr, status, req)		\
+	DOMAIN(pwr, status, req, req, (req) + 16)
+
+static bool rockchip_pmu_domain_is_idle(struct rockchip_pm_domain *pd)
+{
+	struct rockchip_pmu *pmu = pd->pmu;
+	const struct rockchip_domain_info *pd_info = pd->info;
+	unsigned int val;
+
+	regmap_read(pmu->regmap, pmu->info->idle_offset, &val);
+	return (val & pd_info->idle_mask) == pd_info->idle_mask;
+}
+
+static int rockchip_pmu_set_idle_request(struct rockchip_pm_domain *pd,
+					 bool idle)
+{
+	const struct rockchip_domain_info *pd_info = pd->info;
+	struct rockchip_pmu *pmu = pd->pmu;
+	unsigned int val;
+
+	regmap_update_bits(pmu->regmap, pmu->info->req_offset,
+			   pd_info->req_mask, idle ? -1U : 0);
+
+	dsb();
+
+	do {
+		regmap_read(pmu->regmap, pmu->info->ack_offset, &val);
+	} while ((val & pd_info->ack_mask) != (idle ? pd_info->ack_mask : 0));
+
+	while (rockchip_pmu_domain_is_idle(pd) != idle)
+		cpu_relax();
+
+	return 0;
+}
+
+static bool rockchip_pmu_domain_is_on(struct rockchip_pm_domain *pd)
+{
+	struct rockchip_pmu *pmu = pd->pmu;
+	unsigned int val;
+
+	regmap_read(pmu->regmap, pmu->info->status_offset, &val);
+
+	/* 1'b0: power on, 1'b1: power off */
+	return !(val & pd->info->status_mask);
+}
+
+static void rockchip_do_pmu_set_power_domain(struct rockchip_pm_domain *pd,
+					     bool on)
+{
+	struct rockchip_pmu *pmu = pd->pmu;
+
+	regmap_update_bits(pmu->regmap, pmu->info->pwr_offset,
+			   pd->info->pwr_mask, on ? 0 : -1U);
+
+	dsb();
+
+	while (rockchip_pmu_domain_is_on(pd) != on)
+		cpu_relax();
+}
+
+static int rockchip_pd_power(struct rockchip_pm_domain *pd, bool power_on)
+{
+	int i;
+
+	mutex_lock(&pd->pmu->mutex);
+
+	if (rockchip_pmu_domain_is_on(pd) != power_on) {
+		for (i = 0; i < pd->num_clks; i++)
+			clk_enable(pd->clks[i]);
+
+		if (!power_on) {
+			/* FIXME: add code to save AXI_QOS */
+
+			/* if powering down, idle request to NIU first */
+			rockchip_pmu_set_idle_request(pd, true);
+		}
+
+		rockchip_do_pmu_set_power_domain(pd, power_on);
+
+		if (power_on) {
+			/* if powering up, leave idle mode */
+			rockchip_pmu_set_idle_request(pd, false);
+
+			/* FIXME: add code to restore AXI_QOS */
+		}
+
+		for (i = pd->num_clks - 1; i >= 0; i--)
+			clk_disable(pd->clks[i]);
+	}
+
+	mutex_unlock(&pd->pmu->mutex);
+	return 0;
+}
+
+static int rockchip_pd_power_on(struct generic_pm_domain *domain)
+{
+	struct rockchip_pm_domain *pd = to_rockchip_pd(domain);
+
+	return rockchip_pd_power(pd, true);
+}
+
+static int rockchip_pd_power_off(struct generic_pm_domain *domain)
+{
+	struct rockchip_pm_domain *pd = to_rockchip_pd(domain);
+
+	return rockchip_pd_power(pd, false);
+}
+
+static int rockchip_pd_attach_dev(struct generic_pm_domain *genpd,
+				  struct device *dev)
+{
+	struct clk *clk;
+	int i;
+	int error;
+
+	dev_dbg(dev, "attaching to power domain '%s'\n", genpd->name);
+
+	error = pm_clk_create(dev);
+	if (error) {
+		dev_err(dev, "pm_clk_create failed %d\n", error);
+		return error;
+	}
+
+	i = 0;
+	while ((clk = of_clk_get(dev->of_node, i++)) && !IS_ERR(clk)) {
+		dev_dbg(dev, "adding clock '%pC' to list of PM clocks\n", clk);
+		error = pm_clk_add_clk(dev, clk);
+		clk_put(clk);
+		if (error) {
+			dev_err(dev, "pm_clk_add_clk failed %d\n", error);
+			pm_clk_destroy(dev);
+			return error;
+		}
+	}
+
+	return 0;
+}
+
+static void rockchip_pd_detach_dev(struct generic_pm_domain *genpd,
+				   struct device *dev)
+{
+	dev_dbg(dev, "detaching from power domain '%s'\n", genpd->name);
+
+	pm_clk_destroy(dev);
+}
+
+static int rockchip_pm_add_one_domain(struct rockchip_pmu *pmu,
+				      struct device_node *node)
+{
+	const struct rockchip_domain_info *pd_info;
+	struct rockchip_pm_domain *pd;
+	struct clk *clk;
+	int clk_cnt;
+	int i;
+	u32 id;
+	int error;
+
+	error = of_property_read_u32(node, "reg", &id);
+	if (error) {
+		dev_err(pmu->dev,
+			"%s: failed to retrieve domain id (reg): %d\n",
+			node->name, error);
+		return -EINVAL;
+	}
+
+	if (id >= pmu->info->num_domains) {
+		dev_err(pmu->dev, "%s: invalid domain id %d\n",
+			node->name, id);
+		return -EINVAL;
+	}
+
+	pd_info = &pmu->info->domain_info[id];
+	if (!pd_info) {
+		dev_err(pmu->dev, "%s: undefined domain id %d\n",
+			node->name, id);
+		return -EINVAL;
+	}
+
+	clk_cnt = of_count_phandle_with_args(node, "clocks", "#clock-cells");
+	pd = devm_kzalloc(pmu->dev,
+			  sizeof(*pd) + clk_cnt * sizeof(pd->clks[0]),
+			  GFP_KERNEL);
+	if (!pd)
+		return -ENOMEM;
+
+	pd->info = pd_info;
+	pd->pmu = pmu;
+
+	for (i = 0; i < clk_cnt; i++) {
+		clk = of_clk_get(node, i);
+		if (IS_ERR(clk)) {
+			error = PTR_ERR(clk);
+			dev_err(pmu->dev,
+				"%s: failed to get clk %pC (index %d): %d\n",
+				node->name, clk, i, error);
+			goto err_out;
+		}
+
+		error = clk_prepare(clk);
+		if (error) {
+			dev_err(pmu->dev,
+				"%s: failed to prepare clk %pC (index %d): %d\n",
+				node->name, clk, i, error);
+			clk_put(clk);
+			goto err_out;
+		}
+
+		pd->clks[pd->num_clks++] = clk;
+
+		dev_dbg(pmu->dev, "added clock '%pC' to domain '%s'\n",
+			clk, node->name);
+	}
+
+	error = rockchip_pd_power(pd, true);
+	if (error) {
+		dev_err(pmu->dev,
+			"failed to power on domain '%s': %d\n",
+			node->name, error);
+		goto err_out;
+	}
+
+	pd->genpd.name = node->name;
+	pd->genpd.power_off = rockchip_pd_power_off;
+	pd->genpd.power_on = rockchip_pd_power_on;
+	pd->genpd.attach_dev = rockchip_pd_attach_dev;
+	pd->genpd.detach_dev = rockchip_pd_detach_dev;
+	pd->genpd.flags = GENPD_FLAG_PM_CLK;
+	pm_genpd_init(&pd->genpd, NULL, false);
+
+	pmu->genpd_data.domains[id] = &pd->genpd;
+	return 0;
+
+err_out:
+	while (--i >= 0) {
+		clk_unprepare(pd->clks[i]);
+		clk_put(pd->clks[i]);
+	}
+	return error;
+}
+
+static void rockchip_pm_remove_one_domain(struct rockchip_pm_domain *pd)
+{
+	int i;
+
+	for (i = 0; i < pd->num_clks; i++) {
+		clk_unprepare(pd->clks[i]);
+		clk_put(pd->clks[i]);
+	}
+
+	/* devm will free our memory */
+}
+
+static void rockchip_pm_domain_cleanup(struct rockchip_pmu *pmu)
+{
+	struct generic_pm_domain *genpd;
+	struct rockchip_pm_domain *pd;
+	int i;
+
+	for (i = 0; i < pmu->genpd_data.num_domains; i++) {
+		genpd = pmu->genpd_data.domains[i];
+		if (genpd) {
+			pd = to_rockchip_pd(genpd);
+			rockchip_pm_remove_one_domain(pd);
+		}
+	}
+
+	/* devm will free our memory */
+}
+
+static void rockchip_configure_pd_cnt(struct rockchip_pmu *pmu,
+				      u32 domain_reg_offset,
+				      unsigned int count)
+{
+	/* First configure domain power down transition count ... */
+	regmap_write(pmu->regmap, domain_reg_offset, count);
+	/* ... and then power up count. */
+	regmap_write(pmu->regmap, domain_reg_offset + 4, count);
+}
+
+static int rockchip_pm_domain_probe(struct platform_device *pdev)
+{
+	struct device *dev = &pdev->dev;
+	struct device_node *np = dev->of_node;
+	struct device_node *node;
+	struct device *parent;
+	struct rockchip_pmu *pmu;
+	const struct of_device_id *match;
+	const struct rockchip_pmu_info *pmu_info;
+	int error;
+
+	if (!np) {
+		dev_err(dev, "device tree node not found\n");
+		return -ENODEV;
+	}
+
+	match = of_match_device(dev->driver->of_match_table, dev);
+	if (!match || !match->data) {
+		dev_err(dev, "missing pmu data\n");
+		return -EINVAL;
+	}
+
+	pmu_info = match->data;
+
+	pmu = devm_kzalloc(dev,
+			   sizeof(*pmu) +
+				pmu_info->num_domains * sizeof(pmu->domains[0]),
+			   GFP_KERNEL);
+	if (!pmu)
+		return -ENOMEM;
+
+	pmu->dev = &pdev->dev;
+	mutex_init(&pmu->mutex);
+
+	pmu->info = pmu_info;
+
+	pmu->genpd_data.domains = pmu->domains;
+	pmu->genpd_data.num_domains = pmu_info->num_domains;
+
+	parent = dev->parent;
+	if (!parent) {
+		dev_err(dev, "no parent for syscon devices\n");
+		return -ENODEV;
+	}
+
+	pmu->regmap = syscon_node_to_regmap(parent->of_node);
+
+	/*
+	 * Configure power up and down transition delays for CORE
+	 * and GPU domains.
+	 */
+	rockchip_configure_pd_cnt(pmu, pmu_info->core_pwrcnt_offset,
+				  pmu_info->core_power_transition_time);
+	rockchip_configure_pd_cnt(pmu, pmu_info->gpu_pwrcnt_offset,
+				  pmu_info->gpu_power_transition_time);
+
+	error = -ENODEV;
+
+	for_each_available_child_of_node(np, node) {
+		error = rockchip_pm_add_one_domain(pmu, node);
+		if (error) {
+			dev_err(dev, "failed to handle node %s: %d\n",
+				node->name, error);
+			goto err_out;
+		}
+	}
+
+	if (error) {
+		dev_dbg(dev, "no power domains defined\n");
+		goto err_out;
+	}
+
+	of_genpd_add_provider_onecell(np, &pmu->genpd_data);
+
+	return 0;
+
+err_out:
+	rockchip_pm_domain_cleanup(pmu);
+	return error;
+}
+
+static const struct rockchip_domain_info rk3288_pm_domains[] = {
+	[RK3288_PD_GPU]		= DOMAIN_RK3288(9, 9, 2),
+	[RK3288_PD_VIO]		= DOMAIN_RK3288(7, 7, 4),
+	[RK3288_PD_VIDEO]	= DOMAIN_RK3288(8, 8, 3),
+	[RK3288_PD_HEVC]	= DOMAIN_RK3288(14, 10, 9),
+};
+
+static const struct rockchip_pmu_info rk3288_pmu = {
+	.pwr_offset = 0x08,
+	.status_offset = 0x0c,
+	.req_offset = 0x10,
+	.idle_offset = 0x14,
+	.ack_offset = 0x14,
+
+	.core_pwrcnt_offset = 0x34,
+	.gpu_pwrcnt_offset = 0x3c,
+
+	.core_power_transition_time = 24, /* 1us */
+	.gpu_power_transition_time = 24, /* 1us */
+
+	.num_domains = ARRAY_SIZE(rk3288_pm_domains),
+	.domain_info = rk3288_pm_domains,
+};
+
+static const struct of_device_id rockchip_pm_domain_dt_match[] = {
+	{
+		.compatible = "rockchip,rk3288-power-controller",
+		.data = (void *)&rk3288_pmu,
+	},
+	{ /* sentinel */ },
+};
+
+static struct platform_driver rockchip_pm_domain_driver = {
+	.probe = rockchip_pm_domain_probe,
+	.driver = {
+		.name   = "rockchip-pm-domain",
+		.of_match_table = rockchip_pm_domain_dt_match,
+		/*
+		 * We can't forcibly eject devices form power domain,
+		 * so we can't really remove power domains once they
+		 * were added.
+		 */
+		.suppress_bind_attrs = true,
+	},
+};
+
+static int __init rockchip_pm_domain_drv_register(void)
+{
+	return platform_driver_register(&rockchip_pm_domain_driver);
+}
+postcore_initcall(rockchip_pm_domain_drv_register);
-- 
1.9.1



From wxt at rock-chips.com  Tue Aug 11 21:42:32 2015
From: wxt at rock-chips.com (Caesar Wang)
Date: Wed, 12 Aug 2015 12:42:32 +0800
Subject: [PATCH v16 4/4] ARM: dts: add the support power-domain node on RK3288
 SoCs
In-Reply-To: <1439354552-20098-1-git-send-email-wxt@rock-chips.com>
References: <1439354552-20098-1-git-send-email-wxt@rock-chips.com>
Message-ID: <1439354552-20098-5-git-send-email-wxt@rock-chips.com>

We can add more domains node in the future.
This patch add the needed clocks into power-controller.
As the discuess about all the device clocks being listed in
the power-domains itself.

There are several reasons as follows:

Firstly, the clocks need be turned off to save power when
the system enter the suspend state. So we need to enumerate
the clocks in the dts. In order to power domain can turn on and off.

Secondly, the reset-circuit should reset be synchronous on RK3288,
then sync revoked. So we need to enable clocks of all devices.
In other words, we have to enable the clocks before you operate them
if all the device clocks are included in someone domians.

Someone wish was to get the clocks by reading the clocks from the
device nodes, We can do that but we can solve the above issues.

Anyway, the best ideas we can fix it in the future SoCs.

Signed-off-by: jinkun.hong <jinkun.hong at rock-chips.com>
Signed-off-by: Caesar Wang <wxt at rock-chips.com>

---

Changes in v16:
- Manually copy the problem in patch v15.
- rebase the description.
Series-changes: 15
- As Tomasz remarked previously the dts should represent the hardware
  and the power-domains are part of the pmu.
Series-changes: 12
- Remove essential clocks from rk3288 PD_VIO domain, Some clocks are
  essential for the system health and should not be turned down.
  However there is no owner for them so if they listed as belonging to power
  domain we'll try toggling them up and down during power domain transition.
  As a result we either fail to suspend or resume the system.
Series-changes: 10
- fix missing the #include <dt-bindings/power-domain/rk3288.h>.
- remove the notes.
Series-changes: 9
- add decription for power-doamin node.
Series-changes: 8
- DTS go back to v2.
Series-changes: 3
- Decomposition power-controller, changed to multiple controller
  (gpu-power-controller, hevc-power-controller).
Series-changes: 2
- make pd_vio clocks all one entry per line and alphabetize.
- power: power-controller move back to pinctrl: pinctrl.

 arch/arm/boot/dts/rk3288.dtsi | 60 ++++++++++++++++++++++++++++++++++++++++++-
 1 file changed, 59 insertions(+), 1 deletion(-)

diff --git a/arch/arm/boot/dts/rk3288.dtsi b/arch/arm/boot/dts/rk3288.dtsi
index 22316d0..161931d 100644
--- a/arch/arm/boot/dts/rk3288.dtsi
+++ b/arch/arm/boot/dts/rk3288.dtsi
@@ -44,6 +44,7 @@
 #include <dt-bindings/pinctrl/rockchip.h>
 #include <dt-bindings/clock/rk3288-cru.h>
 #include <dt-bindings/thermal/thermal.h>
+#include <dt-bindings/power-domain/rk3288.h>
 #include "skeleton.dtsi"
 
 / {
@@ -590,8 +591,65 @@
 	};
 
 	pmu: power-management at ff730000 {
-		compatible = "rockchip,rk3288-pmu", "syscon";
+		compatible = "rockchip,rk3288-pmu", "syscon", "simple-mfd";
 		reg = <0xff730000 0x100>;
+
+		power: power-controller {
+			compatible = "rockchip,rk3288-power-controller";
+			#power-domain-cells = <1>;
+			#address-cells = <1>;
+			#size-cells = <0>;
+
+			pd_gpu {
+				reg = <RK3288_PD_GPU>;
+				clocks = <&cru ACLK_GPU>;
+			};
+
+			pd_hevc {
+				reg = <RK3288_PD_HEVC>;
+				clocks = <&cru ACLK_HEVC>,
+					 <&cru SCLK_HEVC_CABAC>,
+					 <&cru SCLK_HEVC_CORE>,
+					 <&cru HCLK_HEVC>;
+			};
+
+			pd_vio {
+				reg = <RK3288_PD_VIO>;
+				clocks = <&cru ACLK_IEP>,
+					 <&cru ACLK_ISP>,
+					 <&cru ACLK_RGA>,
+					 <&cru ACLK_VIP>,
+					 <&cru ACLK_VOP0>,
+					 <&cru ACLK_VOP1>,
+					 <&cru DCLK_VOP0>,
+					 <&cru DCLK_VOP1>,
+					 <&cru HCLK_IEP>,
+					 <&cru HCLK_ISP>,
+					 <&cru HCLK_RGA>,
+					 <&cru HCLK_VIP>,
+					 <&cru HCLK_VOP0>,
+					 <&cru HCLK_VOP1>,
+					 <&cru PCLK_EDP_CTRL>,
+					 <&cru PCLK_HDMI_CTRL>,
+					 <&cru PCLK_LVDS_PHY>,
+					 <&cru PCLK_MIPI_CSI>,
+					 <&cru PCLK_MIPI_DSI0>,
+					 <&cru PCLK_MIPI_DSI1>,
+					 <&cru SCLK_EDP_24M>,
+					 <&cru SCLK_EDP>,
+					 <&cru SCLK_HDMI_CEC>,
+					 <&cru SCLK_HDMI_HDCP>,
+					 <&cru SCLK_ISP_JPE>,
+					 <&cru SCLK_ISP>,
+					 <&cru SCLK_RGA>;
+			};
+
+			pd_video {
+				reg = <RK3288_PD_VIDEO>;
+				clocks = <&cru ACLK_VCODEC>,
+					 <&cru HCLK_VCODEC>;
+			};
+		};
 	};
 
 	sgrf: syscon at ff740000 {
-- 
1.9.1



From viresh.kumar at linaro.org  Tue Aug 11 22:16:59 2015
From: viresh.kumar at linaro.org (Viresh Kumar)
Date: Wed, 12 Aug 2015 10:46:59 +0530
Subject: 3.18: lockdep problems in cpufreq
In-Reply-To: <20150811170357.GA24529@n2100.arm.linux.org.uk>
References: <20141214213655.GA11285@n2100.arm.linux.org.uk>
 <CAKohponhkk9BK6-7ScHeZa4R43iooWQFV8YoPLv6LjO40GNq=A@mail.gmail.com>
 <20150518185645.GA28053@n2100.arm.linux.org.uk>
 <2574268.XBqpdL2VLI@vostro.rjw.lan>
 <20150811170357.GA24529@n2100.arm.linux.org.uk>
Message-ID: <20150812051659.GI32049@linux>

On 11-08-15, 18:03, Russell King - ARM Linux wrote:
> On Tue, May 19, 2015 at 12:05:55AM +0200, Rafael J. Wysocki wrote:
> > On Monday, May 18, 2015 07:56:45 PM Russell King - ARM Linux wrote:
> > > On Tue, Dec 16, 2014 at 09:11:53AM +0530, Viresh Kumar wrote:
> > > > On 16 December 2014 at 04:39, Russell King - ARM Linux
> > > > <linux at arm.linux.org.uk> wrote:
> > > > > Well, here's a patch which I'm running on top of 3.18 at the moment,
> > > > > which is basically what I described in my email, and I'm running with it
> > > > > and it is without any lockdep complaint.
> > > > 
> > > > We need two separate patches now, one for 3.18 and other one for 3.19-rc.
> > > > 3.19 has see lots of changes in this particular file and so we need to
> > > > change few things here.

Was the patch for latest kernel ever circulated ? Probably that's why
Eduardo never got back to it.

-- 
viresh


From robert.jarzmik at free.fr  Tue Aug 11 22:45:36 2015
From: robert.jarzmik at free.fr (Robert Jarzmik)
Date: Wed, 12 Aug 2015 07:45:36 +0200
Subject: [PATCH] ARM: config: Switch PXA27x platforms to use PXA RTC driver
In-Reply-To: <CAL_JsqKxUjg+zPJ=_Wvd+zTh7UuT=dkECEh=Hy7QdZsqn4B+8w@mail.gmail.com>
 (Rob Herring's message of "Tue, 11 Aug 2015 20:07:50 -0500")
References: <1437757375-9113-1-git-send-email-robh@kernel.org>
 <CAL_JsqKxUjg+zPJ=_Wvd+zTh7UuT=dkECEh=Hy7QdZsqn4B+8w@mail.gmail.com>
Message-ID: <8737zpjbzz.fsf@belgarion.home>

Rob Herring <robh at kernel.org> writes:

> On Fri, Jul 24, 2015 at 12:02 PM, Rob Herring <robh at kernel.org> wrote:
>> With the SA1100 and PXA RTC drivers be mutually exclusive and no
>> longer sharing hardware, PXA27x/PXA3xx platforms must use the PXA RTC
>> driver as the SA1100 platform device is no longer registered.
>>
>> This change should be almost transparent to userspace. Former users of
>> pxa-rtc should be aware that 2 RTCs will be available on their kernels,
>> rtc0 being sa1100-rtc and rtc1 being pxa-rtc. Any userspace relying on
>> the fact that rtc0 was pxa-rtc should be fixed.
>>
>> As a consequence:
>>  - the first reboot after the switch will have the wrong time,
>>  - on dual boot platform where the other OS programs some logic into the
>>    sa1100 rtc IP, a lack of fix in userspace, ie. a kernel changing
>>    sa1100-rtc thinking it is pxa-rtc could have dire consequence, such
>>    as wiping the other OS data partition.
>>
>> (Thanks to Robert Jarmik for help on the above commit text.)
>>
>> Signed-off-by: Rob Herring <robh at kernel.org>
>> Cc: Robert Jarzmik <robert.jarzmik at free.fr>
>> Cc: Daniel Mack <daniel at zonque.org>
>> Cc: Haojian Zhuang <haojian.zhuang at gmail.com>
>> Cc: Sergey Lapin <slapin at ossfans.org>
>> Cc: Russell King <linux at arm.linux.org.uk>
>> Cc: Mike Rapoport <mike at compulab.co.il>
>> Cc: Philipp Zabel <philipp.zabel at gmail.com>
>> ---
>> PXA Maintainers,
>>
>> This is dependent on my SA1100 RTC cleanup series[1]. Please comment on
>> this patch and that series. The full series is available from a git
>> branch here[2]. I've rebased it to 4.2-rc3, but otherwise there is no
>> change from v4.
>
> Any comments on this? If not, I plan to send Alexandre a pull request
> for this series this week.
Hi Rob,

I think you waited long enough, nobody can tell now they were not aware of the
situation. Please go ahead and request pull.

Acked-by: Robert Jarzmik <robert.jarzmik at free.fr>

Cheers.

--
Robert


From dongsheng.wang at freescale.com  Tue Aug 11 22:53:26 2015
From: dongsheng.wang at freescale.com (Dongsheng Wang)
Date: Wed, 12 Aug 2015 13:53:26 +0800
Subject: [PATCH v2 1/2] soc/fsl: add freescale dir for SOC specific drivers
Message-ID: <1439358807-9024-1-git-send-email-dongsheng.wang@freescale.com>

From: Wang Dongsheng <dongsheng.wang at freescale.com>

Some Freescale device drivers need to move to soc/, because these
drivers are specific drivers. Before the soc/ to be created, the
drivers had been there arch/ or drivers/misc/, but now soc/ dir
is a better choice.

Signed-off-by: Wang Dongsheng <dongsheng.wang at freescale.com>
---
*V2*
Rebase for last kernel. Resend this patch, this patch is one year ago.
Sorry I haven't had the time to push this patch before.

diff --git a/drivers/soc/Kconfig b/drivers/soc/Kconfig
index 96ddecb..b5c5179 100644
--- a/drivers/soc/Kconfig
+++ b/drivers/soc/Kconfig
@@ -5,5 +5,6 @@ source "drivers/soc/qcom/Kconfig"
 source "drivers/soc/sunxi/Kconfig"
 source "drivers/soc/ti/Kconfig"
 source "drivers/soc/versatile/Kconfig"
+source "drivers/soc/fsl/Kconfig"
 
 endmenu
diff --git a/drivers/soc/Makefile b/drivers/soc/Makefile
index 7dc7c0d..1caf1d6 100644
--- a/drivers/soc/Makefile
+++ b/drivers/soc/Makefile
@@ -8,3 +8,4 @@ obj-$(CONFIG_ARCH_SUNXI)	+= sunxi/
 obj-$(CONFIG_ARCH_TEGRA)	+= tegra/
 obj-$(CONFIG_SOC_TI)		+= ti/
 obj-$(CONFIG_PLAT_VERSATILE)	+= versatile/
+obj-$(CONFIG_FSL_SOC_DRIVERS)	+= fsl/
diff --git a/drivers/soc/fsl/Kconfig b/drivers/soc/fsl/Kconfig
new file mode 100644
index 0000000..863d1ef
--- /dev/null
+++ b/drivers/soc/fsl/Kconfig
@@ -0,0 +1,18 @@
+#
+# Freescale SOC drivers
+#
+menuconfig FSL_SOC_DRIVERS
+	bool "Freescale Soc Drivers"
+	default n
+	help
+	  Say y here to enable Freescale Soc Device Drivers support.
+	  The Soc Drivers provides the device driver that is a specific
+	  block or feature on Freescale platform.
+
+if FSL_SOC_DRIVERS
+
+if ARM
+source "drivers/soc/fsl/Kconfig.arm"
+endif
+
+endif
diff --git a/drivers/soc/fsl/Kconfig.arm b/drivers/soc/fsl/Kconfig.arm
new file mode 100644
index 0000000..8c90b82
--- /dev/null
+++ b/drivers/soc/fsl/Kconfig.arm
@@ -0,0 +1,16 @@
+#
+# Freescale ARM SOC Drivers
+#
+
+config	LS1_SOC_DRIVERS
+	bool "LS1021A Soc Drivers"
+	depends on SOC_LS1021A
+	default n
+	help
+	Say y here to enable Freescale LS1021A Soc Device Drivers support.
+	The Soc Drivers provides the device driver that is a specific block
+	or feature on LS1021A platform.
+
+if LS1_SOC_DRIVERS
+	source "drivers/soc/fsl/ls1/Kconfig"
+endif
diff --git a/drivers/soc/fsl/Makefile b/drivers/soc/fsl/Makefile
new file mode 100644
index 0000000..b4215dd
--- /dev/null
+++ b/drivers/soc/fsl/Makefile
@@ -0,0 +1,6 @@
+#
+# Makefile for Freescale Soc specific device drivers.
+#
+
+obj-$(CONFIG_LS1_SOC_DRIVERS) += ls1/
+
diff --git a/drivers/soc/fsl/ls1/Kconfig b/drivers/soc/fsl/ls1/Kconfig
new file mode 100644
index 0000000..7556f44
--- /dev/null
+++ b/drivers/soc/fsl/ls1/Kconfig
@@ -0,0 +1,3 @@
+#
+# LS-1 Soc drivers
+#
-- 
2.1.0.27.g96db324



From dongsheng.wang at freescale.com  Tue Aug 11 22:53:27 2015
From: dongsheng.wang at freescale.com (Dongsheng Wang)
Date: Wed, 12 Aug 2015 13:53:27 +0800
Subject: [PATCH 2/2] soc/fsl: add ftm alarm driver for ls1021a platform
In-Reply-To: <1439358807-9024-1-git-send-email-dongsheng.wang@freescale.com>
References: <1439358807-9024-1-git-send-email-dongsheng.wang@freescale.com>
Message-ID: <1439358807-9024-2-git-send-email-dongsheng.wang@freescale.com>

From: Wang Dongsheng <dongsheng.wang at freescale.com>

Only Ftm0 can be used when system going to deep sleep. So this driver
to support ftm0 as a wakeup source.

Signed-off-by: Wang Dongsheng <dongsheng.wang at freescale.com>
---
*V2*
Change Copyright 2014 to 2015.

diff --git a/drivers/soc/fsl/ls1/Kconfig b/drivers/soc/fsl/ls1/Kconfig
index 7556f44..e6282dc 100644
--- a/drivers/soc/fsl/ls1/Kconfig
+++ b/drivers/soc/fsl/ls1/Kconfig
@@ -1,3 +1,11 @@
 #
 # LS-1 Soc drivers
 #
+config	FTM_ALARM
+	bool "FTM alarm driver"
+	depends on SOC_LS1021A
+	default n
+	help
+	  Say y here to enable FTM alarm support.  The FTM alarm provides
+	  alarm functions for wakeup system from deep sleep.  There is only
+	  one FTM can be used in ALARM(FTM 0).
diff --git a/drivers/soc/fsl/ls1/Makefile b/drivers/soc/fsl/ls1/Makefile
new file mode 100644
index 0000000..6299aa1
--- /dev/null
+++ b/drivers/soc/fsl/ls1/Makefile
@@ -0,0 +1 @@
+obj-$(CONFIG_FTM_ALARM) += ftm_alarm.o
diff --git a/drivers/soc/fsl/ls1/ftm_alarm.c b/drivers/soc/fsl/ls1/ftm_alarm.c
new file mode 100644
index 0000000..f7629cd
--- /dev/null
+++ b/drivers/soc/fsl/ls1/ftm_alarm.c
@@ -0,0 +1,272 @@
+/*
+ * Freescale FlexTimer Module (FTM) Alarm driver.
+ *
+ * Copyright 2015 Freescale Semiconductor, Inc.
+ *
+ * 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.
+ */
+
+#include <linux/device.h>
+#include <linux/err.h>
+#include <linux/interrupt.h>
+#include <linux/io.h>
+#include <linux/of_address.h>
+#include <linux/of_irq.h>
+#include <linux/platform_device.h>
+
+#define FTM_SC			0x00
+#define FTM_SC_CLK_SHIFT	3
+#define FTM_SC_CLK_MASK		(0x3 << FTM_SC_CLK_SHIFT)
+#define FTM_SC_CLK(c)		((c) << FTM_SC_CLK_SHIFT)
+#define FTM_SC_PS_MASK		0x7
+#define FTM_SC_TOIE		BIT(6)
+#define FTM_SC_TOF		BIT(7)
+
+#define FTM_SC_CLKS_FIXED_FREQ	0x02
+
+#define FTM_CNT			0x04
+#define FTM_MOD			0x08
+#define FTM_CNTIN		0x4C
+
+#define FIXED_FREQ_CLK		32000
+#define MAX_FREQ_DIV		(1 << FTM_SC_PS_MASK)
+#define MAX_COUNT_VAL		0xffff
+
+static void __iomem *ftm1_base;
+static u32 alarm_freq;
+static bool big_endian;
+
+static inline u32 ftm_readl(void __iomem *addr)
+{
+	if (big_endian)
+		return ioread32be(addr);
+
+	return ioread32(addr);
+}
+
+static inline void ftm_writel(u32 val, void __iomem *addr)
+{
+	if (big_endian)
+		iowrite32be(val, addr);
+	else
+		iowrite32(val, addr);
+}
+
+static inline void ftm_counter_enable(void __iomem *base)
+{
+	u32 val;
+
+	/* select and enable counter clock source */
+	val = ftm_readl(base + FTM_SC);
+	val &= ~(FTM_SC_PS_MASK | FTM_SC_CLK_MASK);
+	val |= (FTM_SC_PS_MASK | FTM_SC_CLK(FTM_SC_CLKS_FIXED_FREQ));
+	ftm_writel(val, base + FTM_SC);
+}
+
+static inline void ftm_counter_disable(void __iomem *base)
+{
+	u32 val;
+
+	/* disable counter clock source */
+	val = ftm_readl(base + FTM_SC);
+	val &= ~(FTM_SC_PS_MASK | FTM_SC_CLK_MASK);
+	ftm_writel(val, base + FTM_SC);
+}
+
+static inline void ftm_irq_acknowledge(void __iomem *base)
+{
+	u32 val;
+
+	val = ftm_readl(base + FTM_SC);
+	val &= ~FTM_SC_TOF;
+	ftm_writel(val, base + FTM_SC);
+}
+
+static inline void ftm_irq_enable(void __iomem *base)
+{
+	u32 val;
+
+	val = ftm_readl(base + FTM_SC);
+	val |= FTM_SC_TOIE;
+	ftm_writel(val, base + FTM_SC);
+}
+
+static inline void ftm_irq_disable(void __iomem *base)
+{
+	u32 val;
+
+	val = ftm_readl(base + FTM_SC);
+	val &= ~FTM_SC_TOIE;
+	ftm_writel(val, base + FTM_SC);
+}
+
+static inline void ftm_reset_counter(void __iomem *base)
+{
+	/*
+	 * The CNT register contains the FTM counter value.
+	 * Reset clears the CNT register. Writing any value to COUNT
+	 * updates the counter with its initial value, CNTIN.
+	 */
+	ftm_writel(0x00, base + FTM_CNT);
+}
+
+static u32 time_to_cycle(unsigned long time)
+{
+	u32 cycle;
+
+	cycle = time * alarm_freq;
+	if (cycle > MAX_COUNT_VAL) {
+		pr_err("Out of alarm range.\n");
+		cycle = 0;
+	}
+
+	return cycle;
+}
+
+static u32 cycle_to_time(u32 cycle)
+{
+	return cycle / alarm_freq + 1;
+}
+
+static void ftm_clean_alarm(void)
+{
+	ftm_counter_disable(ftm1_base);
+
+	ftm_writel(0x00, ftm1_base + FTM_CNTIN);
+	ftm_writel(~0UL, ftm1_base + FTM_MOD);
+
+	ftm_reset_counter(ftm1_base);
+}
+
+static int ftm_set_alarm(u64 cycle)
+{
+	ftm_irq_disable(ftm1_base);
+
+	/*
+	 * The counter increments until the value of MOD is reached,
+	 * at which point the counter is reloaded with the value of CNTIN.
+	 * The TOF (the overflow flag) bit is set when the FTM counter
+	 * changes from MOD to CNTIN. So we should using the cycle - 1.
+	 */
+	ftm_writel(cycle - 1, ftm1_base + FTM_MOD);
+
+	ftm_counter_enable(ftm1_base);
+
+	ftm_irq_enable(ftm1_base);
+
+	return 0;
+}
+
+static irqreturn_t ftm_alarm_interrupt(int irq, void *dev_id)
+{
+	ftm_irq_acknowledge(ftm1_base);
+	ftm_irq_disable(ftm1_base);
+	ftm_clean_alarm();
+
+	return IRQ_HANDLED;
+}
+
+static ssize_t ftm_alarm_show(struct device *dev,
+			      struct device_attribute *attr,
+			      char *buf)
+{
+	u32 count, val;
+
+	count = ftm_readl(ftm1_base + FTM_MOD);
+	val = ftm_readl(ftm1_base + FTM_CNT);
+	val = (count & MAX_COUNT_VAL) - val;
+	val = cycle_to_time(val);
+
+	return sprintf(buf, "%u\n", val);
+}
+
+static ssize_t ftm_alarm_store(struct device *dev,
+			       struct device_attribute *attr,
+			       const char *buf, size_t count)
+{
+	u32 cycle;
+	unsigned long time;
+
+	if (kstrtoul(buf, 0, &time))
+		return -EINVAL;
+
+	ftm_clean_alarm();
+
+	cycle = time_to_cycle(time);
+	if (!cycle)
+		return -EINVAL;
+
+	ftm_set_alarm(cycle);
+
+	return count;
+}
+
+static struct device_attribute ftm_alarm_attributes = __ATTR(ftm_alarm, 0644,
+			ftm_alarm_show, ftm_alarm_store);
+
+static int ftm_alarm_probe(struct platform_device *pdev)
+{
+	struct device_node *np = pdev->dev.of_node;
+	struct resource *r;
+	int irq;
+	int ret;
+
+	r = platform_get_resource(pdev, IORESOURCE_MEM, 0);
+	if (!r)
+		return -ENODEV;
+
+	ftm1_base = devm_ioremap_resource(&pdev->dev, r);
+	if (IS_ERR(ftm1_base))
+		return PTR_ERR(ftm1_base);
+
+	irq = irq_of_parse_and_map(np, 0);
+	if (irq <= 0) {
+		pr_err("ftm: unable to get IRQ from DT, %d\n", irq);
+		return -EINVAL;
+	}
+
+	big_endian = of_property_read_bool(np, "big-endian");
+
+	ret = devm_request_irq(&pdev->dev, irq, ftm_alarm_interrupt,
+			       IRQF_NO_SUSPEND, dev_name(&pdev->dev), NULL);
+	if (ret < 0) {
+		dev_err(&pdev->dev, "failed to request irq\n");
+		return ret;
+	}
+
+	ret = device_create_file(&pdev->dev, &ftm_alarm_attributes);
+	if (ret) {
+		dev_err(&pdev->dev, "create sysfs fail.\n");
+		return ret;
+	}
+
+	alarm_freq = (u32)FIXED_FREQ_CLK / (u32)MAX_FREQ_DIV;
+
+	ftm_clean_alarm();
+
+	return ret;
+}
+
+static const struct of_device_id ftm_alarm_match[] = {
+	{ .compatible = "fsl,ftm-alarm", },
+	{ .compatible = "fsl,ftm-timer", },
+	{ },
+};
+
+static struct platform_driver ftm_alarm_driver = {
+	.probe		= ftm_alarm_probe,
+	.driver		= {
+		.name	= "ftm-alarm",
+		.owner	= THIS_MODULE,
+		.of_match_table = ftm_alarm_match,
+	},
+};
+
+static int __init ftm_alarm_init(void)
+{
+	return platform_driver_register(&ftm_alarm_driver);
+}
+device_initcall(ftm_alarm_init);
-- 
2.1.0.27.g96db324



From katsuki.uwatoko at toshiba.co.jp  Tue Aug 11 23:19:07 2015
From: katsuki.uwatoko at toshiba.co.jp (katsuki.uwatoko at toshiba.co.jp)
Date: Wed, 12 Aug 2015 06:19:07 +0000
Subject: PROBLEM: XFS on ARM corruption 'Structure needs cleaning'
In-Reply-To: <20150812031407.GB20596@dastard>
References: <557AD4D4.3010901@skylable.com> <20150612225209.GA20262@dastard>
 <C6D0D499B56584katsuki.uwatoko@toshiba.co.jp>
 <20150812031407.GB20596@dastard>
Message-ID: <CCD0D4C6CA7758katsuki.uwatoko@toshiba.co.jp>

On Wed, 12 Aug 2015 13:14:07 +1000, Dave Chinner wrote:

> To close the loop, what code do the other versions GCC produce for
> this macro?  Evidence so far says that the result depends on the
> compiler version, so I would like to have confirmation that other
> versions of the compiler generate working code.  There are other
> XFS_DADDR_TO_FSB() calls in the XFS code, too - do they demonstrate
> the same problem, maybe with different compiler versions?
> 
> Basically I'm asking what is the scope of the problem you've found?
> i.e. when was the bug introduced, what compilers expose it, etc
> so that when ARM users report XFS corruptions we have some idea of
> whether their kernel/compiler combination might have caused the
> issue they are seeing...

I have the following versions of GCC now.
	4.5.1
	4.6.4
	4.7.2
# Sorry I don't have the recent versions of GCC.

And the results are:
	4.5.1 (-O2)	OK.
	4.6.4 (-O2)	BAD.
	4.7.2 (-O2)	BAD.

But even using gcc 4.7, this bug does not happen with -Os instead of -O2.
It means that when CONFIG_CC_OPTIMIZE_FOR_SIZE Kernel option is used, it does not happen.

As for the version of kernel, I am using 3.10 now. At least. it is the same as 2.6.32.

--
The following are codes generated by GCCs.

GCC 4.5.1 with -O2 (OK)
     178:       41a00003        movmi   r0, r3
     17c:       51a00057        asrpl   r0, r7, r0
     180:       e58da02c        str     sl, [sp, #44]   ; 0x2c
     184:       ebfffffe        bl      0 <__do_div64>
     188:       e1cd26f8        strd    r2, [sp, #104]  ; 0x68
     18c:       e3a08000        mov     r8, #0
     190:       e5d51175        ldrb    r1, [r5, #373]  ; 0x175
     194:       e59d2068        ldr     r2, [sp, #104]  ; 0x68
     198:       e251e020        subs    lr, r1, #32
     19c:       e5d5308c        ldrb    r3, [r5, #140]  ; 0x8c
     1a0:       e261c020        rsb     ip, r1, #32
     1a4:       e1a00136        lsr     r0, r6, r1
     1a8:       e1800c17        orr     r0, r0, r7, lsl ip
     1ac:       e2634020        rsb     r4, r3, #32
     1b0:       51a00e57        asrpl   r0, r7, lr
     1b4:       e253c020        subs    ip, r3, #32
     1b8:       e1a0b432        lsr     fp, r2, r4
     1bc:       e1a0a312        lsl     sl, r2, r3
     1c0:       51a0bc12        lslpl   fp, r2, ip
     1c4:       e59dc024        ldr     ip, [sp, #36]   ; 0x24
     1c8:       e5954064        ldr     r4, [r5, #100]  ; 0x64
     1cc:       e1a01157        asr     r1, r7, r1
     1d0:       e58d804c        str     r8, [sp, #76]   ; 0x4c
     1d4:       e58dc048        str     ip, [sp, #72]   ; 0x48
     1d8:       ebfffffe        bl      0 <__do_div64>

GCC 4.6.4 with -O2 (BAD)
     19c:       51a0025e        asrpl   r0, lr, r2
     1a0:       e3a0a001        mov     sl, #1
     1a4:       ebfffffe        bl      0 <__do_div64>
     1a8:       e1a0bb32        lsr     fp, r2, fp
     1ac:       e2553020        subs    r3, r5, #32
     1b0:       e1a01008        mov     r1, r8
     1b4:       e58d704c        str     r7, [sp, #76]   ; 0x4c
     1b8:       e1a0800b        mov     r8, fp
     1bc:       e58d7060        str     r7, [sp, #96]   ; 0x60
     1c0:       51a08312        lslpl   r8, r2, r3
     1c4:       e1a02512        lsl     r2, r2, r5
     1c8:       e58d8034        str     r8, [sp, #52]   ; 0x34
     1cc:       e1a0500a        mov     r5, sl
     1d0:       e58d2030        str     r2, [sp, #48]   ; 0x30
     1d4:       e28d8048        add     r8, sp, #72     ; 0x48
     1d8:       ebfffffe        bl      0 <__do_div64>

GCC 4.7.2 with -Os (OK)
     1a0:       e1cd02d8        ldrd    r0, [sp, #40]   ; 0x28
     1a4:       e1a0200b        mov     r2, fp
     1a8:       ebfffffe        bl      0 <__aeabi_lasr>
     1ac:       e5954064        ldr     r4, [r5, #100]  ; 0x64
     1b0:       ebfffffe        bl      0 <__do_div64>
     1b4:       e3a01000        mov     r1, #0
     1b8:       e1a00002        mov     r0, r2
     1bc:       e5d5208c        ldrb    r2, [r5, #140]  ; 0x8c
     1c0:       ebfffffe        bl      0 <__aeabi_llsl>
     1c4:       e1a0200b        mov     r2, fp
     1c8:       e1a06000        mov     r6, r0
     1cc:       e1a07001        mov     r7, r1
     1d0:       e1cd02d8        ldrd    r0, [sp, #40]   ; 0x28
     1d4:       ebfffffe        bl      0 <__aeabi_lasr>
     1d8:       e58da040        str     sl, [sp, #64]   ; 0x40
     1dc:       ebfffffe        bl      0 <__do_div64>

Thank you,
-- 
UWATOKO


From hch at infradead.org  Tue Aug 11 23:24:45 2015
From: hch at infradead.org (Christoph Hellwig)
Date: Tue, 11 Aug 2015 23:24:45 -0700
Subject: enabling libgcc for 64-bit divisions, was Re: PROBLEM: XFS on ARM
 corruption 'Structure needs cleaning'
In-Reply-To: <C6D0D499B56584katsuki.uwatoko@toshiba.co.jp>
References: <5579B804.9050707@skylable.com>
 <20150612122108.GB60661@bfoster.bfoster>
 <557AD4D4.3010901@skylable.com> <20150612225209.GA20262@dastard>
 <C6D0D499B56584katsuki.uwatoko@toshiba.co.jp>
Message-ID: <20150812062445.GA4520@infradead.org>

On Wed, Aug 12, 2015 at 12:56:25AM +0000, katsuki.uwatoko at toshiba.co.jp wrote:
> On Sat, 13 Jun 2015 08:52:09 +1000, Dave Chinner wrote:
> 
> > Yup, that's looking like a toolchain bug. Thread about arm directory
> > read corruption:
> 
> I think that this is not a toolchain bug, this is related to 
> Subject: [PATCH v2 1/1] ARM : missing corrupted reg in __do_div_asm
> http://www.spinics.net/lists/arm-kernel/msg426684.html

Maybe it's time to rely on gcc to handle 64 bit divisions now?

I've been pretty annoyed at the amount of 32-bit architecture build
failures due to the lack of support for native 64-bit divisions, and
the ugly do_div hackery to work around it.

We're living in a world where we are using a lot of 64-bit CPUs and
people optimize for them, so it might be a good time to start relying
on the compiler to get these right on older CPUs.

How bad is gcc's code for 64-bit divisions on arm and x86 these days?
Is there still a good case for offloading work the compiler should be
doing on the programmer?


From p.fedin at samsung.com  Wed Aug 12 00:11:29 2015
From: p.fedin at samsung.com (Pavel Fedin)
Date: Wed, 12 Aug 2015 10:11:29 +0300
Subject: [PATCH v4 1/3] PCI: generic: remove dependency on hw_pci
In-Reply-To: <20150804234956.GF17327@google.com>
References: <1438721620-15493-1-git-send-email-jchandra@broadcom.com>
 <20150804234956.GF17327@google.com>
Message-ID: <007501d0d4ce$1d2dd9c0$57898d40$@samsung.com>

 Hello!

> I dropped the acks and tested-by because of that change, but I'll happily
> add them back if Lorenzo and Pavel confirm.  

 Confirm.
 Tested-by: Pavel Fedin <p.fedin at samsung.com>

 I also added MSI support. Can i post it as patch on top of your branch?

Kind regards,
Pavel Fedin
Expert Engineer
Samsung Electronics Research center Russia



From tony at atomide.com  Wed Aug 12 00:14:24 2015
From: tony at atomide.com (Tony Lindgren)
Date: Wed, 12 Aug 2015 00:14:24 -0700
Subject: [RFC/PATCH-v4.2-rc6 4/5] arm: omap2: timer: simplify
 omap4_local_timer_init()
In-Reply-To: <1439242911-715-5-git-send-email-balbi@ti.com>
References: <1439242911-715-1-git-send-email-balbi@ti.com>
 <1439242911-715-5-git-send-email-balbi@ti.com>
Message-ID: <20150812071424.GO4215@atomide.com>

* Felipe Balbi <balbi at ti.com> [150810 14:44]:
> all users of omap4_local_timer_init() are already
> DT-only, so we can remove the check for having
> DTB or not.
> 
> While at that, fix a typo in comment.

We already have d1dabab2841d ("ARM: OMAP2+: Clean up
omap4_local_timer_init") in Linux next reviewed-by you :)

Tony


From tony at atomide.com  Wed Aug 12 00:15:27 2015
From: tony at atomide.com (Tony Lindgren)
Date: Wed, 12 Aug 2015 00:15:27 -0700
Subject: [RFC/PATCH-v4.2-rc6 1/5] Revert "ARM: 7655/1: smp_twd: make
 twd_local_timer_of_register() no-op for nosmp"
In-Reply-To: <1439242911-715-2-git-send-email-balbi@ti.com>
References: <1439242911-715-1-git-send-email-balbi@ti.com>
 <1439242911-715-2-git-send-email-balbi@ti.com>
Message-ID: <20150812071527.GP4215@atomide.com>

* Felipe Balbi <balbi at ti.com> [150810 14:45]:
> This reverts commit 904464b91eca8c665acea033489225af02eeb75a.
> 
> The problem pointed out by commit 904464b91eca ("ARM: 7655/1:
> smp_twd: make twd_local_timer_of_register() no-op for nosmp")
> doesn't exist anymore.
> 
> We can safely boot with nosmp and the warning won't show up.
> 
> The other side benefit of this patch is that TWD has a chance
> to probe on single-core A9 systems such as AM437x which sport
> TWD.

Can you please upload this into Russell's patch tracking system
if no comments? Please also feel free to add:

Acked-by: Tony Lindgren <tony at atomide.com>


From linux at arm.linux.org.uk  Wed Aug 12 00:21:29 2015
From: linux at arm.linux.org.uk (Russell King - ARM Linux)
Date: Wed, 12 Aug 2015 08:21:29 +0100
Subject: 3.18: lockdep problems in cpufreq
In-Reply-To: <20150812051659.GI32049@linux>
References: <20141214213655.GA11285@n2100.arm.linux.org.uk>
 <CAKohponhkk9BK6-7ScHeZa4R43iooWQFV8YoPLv6LjO40GNq=A@mail.gmail.com>
 <20150518185645.GA28053@n2100.arm.linux.org.uk>
 <2574268.XBqpdL2VLI@vostro.rjw.lan>
 <20150811170357.GA24529@n2100.arm.linux.org.uk>
 <20150812051659.GI32049@linux>
Message-ID: <20150812072129.GD7557@n2100.arm.linux.org.uk>

On Wed, Aug 12, 2015 at 10:46:59AM +0530, Viresh Kumar wrote:
> On 11-08-15, 18:03, Russell King - ARM Linux wrote:
> > On Tue, May 19, 2015 at 12:05:55AM +0200, Rafael J. Wysocki wrote:
> > > On Monday, May 18, 2015 07:56:45 PM Russell King - ARM Linux wrote:
> > > > On Tue, Dec 16, 2014 at 09:11:53AM +0530, Viresh Kumar wrote:
> > > > > On 16 December 2014 at 04:39, Russell King - ARM Linux
> > > > > <linux at arm.linux.org.uk> wrote:
> > > > > > Well, here's a patch which I'm running on top of 3.18 at the moment,
> > > > > > which is basically what I described in my email, and I'm running with it
> > > > > > and it is without any lockdep complaint.
> > > > > 
> > > > > We need two separate patches now, one for 3.18 and other one for 3.19-rc.
> > > > > 3.19 has see lots of changes in this particular file and so we need to
> > > > > change few things here.
> 
> Was the patch for latest kernel ever circulated ? Probably that's why
> Eduardo never got back to it.

Maybe not - I often lose track of which patches are in what state -
tracking the state of 250+ patches over many months and in some cases
_years_ is not easy.

That's still no reason for Eduardo to _completely_ ignore this thread,
especially when Rafael explicitly tried to get comment from Eduardo.

-- 
FTTC broadband for 0.8mile line: currently at 10.5Mbps down 400kbps up
according to speedtest.net.


From marc.zyngier at arm.com  Wed Aug 12 00:21:38 2015
From: marc.zyngier at arm.com (Marc Zyngier)
Date: Wed, 12 Aug 2015 08:21:38 +0100
Subject: [PATCH v4 00/10] ACPI GIC Self-probing, GICv2m and GICv3 support
In-Reply-To: <55CA8658.80202@codeaurora.org>
References: <1438164539-29256-1-git-send-email-hanjun.guo@linaro.org>
 <55CA70D5.6040300@codeaurora.org> <20150811232523.60d192d2@arm.com>
 <55CA78DE.1000306@codeaurora.org> <20150811234801.51108784@arm.com>
 <55CA8658.80202@codeaurora.org>
Message-ID: <20150812082138.6a80c71d@arm.com>

On Wed, 12 Aug 2015 00:33:44 +0100
Timur Tabi <timur at codeaurora.org> wrote:

> On 08/11/2015 05:48 PM, Marc Zyngier wrote:
> > I don't see any contradiction here. Hanjun picked the patches from my
> > own branch in my own tree, put his own patches on top, and pushed that
> > out on an branch called gsi-irqdomain that is definitely based on
> > 4.2-rc2. I have no idea where your 3.9-rc7 comes from.
> 
> Ok, so that's not your kernel, but the LEG kernel instead.
> 
> The top commits show this:
> 
> Follows: tracking-mainline-llct-20130415.0, 
> tracking-mainline-llct-20130417.0, v3.9-rc7
> 
> Also,
> 	$ git tag | grep v4
> 
> shows no v4.x tags.
> 
> Anyway, I don't want to make a big deal about this.

I just cloned this repository, and none of the branches I received have
this as their top commit. I can only guess that you're looking at
something else.

Thanks,

	M.
-- 
Jazz is not dead. It just smells funny.


From tony at atomide.com  Wed Aug 12 00:25:36 2015
From: tony at atomide.com (Tony Lindgren)
Date: Wed, 12 Aug 2015 00:25:36 -0700
Subject: [PATCH] ARM: OMAP3: clock: remove un-used core dpll re-program
 code
In-Reply-To: <1437034091-18306-1-git-send-email-t-kristo@ti.com>
References: <1437034091-18306-1-git-send-email-t-kristo@ti.com>
Message-ID: <20150812072535.GQ4215@atomide.com>

* Tero Kristo <t-kristo at ti.com> [150716 01:10]:
> Remove the OMAP3 core DPLL re-program code, and the associated SRAM
> code that does the low-level programming of the DPLL divider, idling
> of the SDRAM etc.
> 
> This code was never fully implemented in the kernel; things missing
> were driver side handling of core clock changes (they need to account
> for their functional clock rate being changed on-the-fly), and the whole
> framework required for handling this. Thus, there is not much point
> to keep carrying the low-level support code either.

OK I'm applying this into omap-for-v4.3/soc. If we ever need the code
it will be in the git history.

Regards,

Tony


From Haibo.Chen at freescale.com  Wed Aug 12 00:26:21 2015
From: Haibo.Chen at freescale.com (Chen Bough)
Date: Wed, 12 Aug 2015 07:26:21 +0000
Subject: [PATCH v2 0/5] Add imx6ul touch screen controller support
In-Reply-To: <1438077521-12857-1-git-send-email-haibo.chen@freescale.com>
References: <1438077521-12857-1-git-send-email-haibo.chen@freescale.com>
Message-ID: <BY1PR03MB13883A9E89CE57A8A1CE02A19A7E0@BY1PR03MB1388.namprd03.prod.outlook.com>


Hi all,

Any suggestion about these patch set? Since half month passed without any response.



> -----Original Message-----
> From: Haibo Chen [mailto:haibo.chen at freescale.com]
> Sent: Tuesday, July 28, 2015 5:59 PM
> To: robh+dt at kernel.org; pawel.moll at arm.com; mark.rutland at arm.com;
> ijc+devicetree at hellion.org.uk; galak at codeaurora.org; shawnguo at kernel.org;
> kernel at pengutronix.de; linux at arm.linux.org.uk; dmitry.torokhov at gmail.com
> Cc: Chen Haibo-B51421; hans.verkuil at cisco.com; hadess at hadess.net;
> mchehab at osg.samsung.com; mamlinav at gmail.com; arnd at arndb.de;
> jonathar at broadcom.com; hdegoede at redhat.com; christian.gmeiner at gmail.com;
> scott.liu at emc.com.tw; geert at linux-m68k.org; benjamin.tissoires at redhat.com;
> sebastien.szymanski at armadeus.com; sbranden at broadcom.com;
> devicetree at vger.kernel.org; linux-kernel at vger.kernel.org; linux-arm-
> kernel at lists.infradead.org; linux-input at vger.kernel.org
> Subject: [PATCH v2 0/5] Add imx6ul touch screen controller support
> 
> i.MX6UL contains a touch screen controller. This patch set add imx6ul
> touch screen controller driver support.
> 
> Changes for v2:
> -Add property in devicetree Documentation.
> -Add tsc disable code in tsc_remove function.
> -Remove some redundant code.
> 
> 
> Haibo Chen (5):
>   input: touchscreen: add imx6ul_tsc driver support
>   Documentation: Detail permitted DT properties for the imx6ul_tsc
>   ARM: imx_v6_v7_defconfig: enable imx6ul_tsc
>   ARM: dts: imx6ul.dtsi: add TSC support
>   ARM: dts: imx6ul-14x14-evk.dts: add tsc support
> 
>  .../bindings/input/touchscreen/imx6ul_tsc.txt      |  36 ++
>  arch/arm/boot/dts/imx6ul-14x14-evk.dts             |  18 +
>  arch/arm/boot/dts/imx6ul.dtsi                      |  11 +
>  arch/arm/configs/imx_v6_v7_defconfig               |   1 +
>  drivers/input/touchscreen/Kconfig                  |  12 +
>  drivers/input/touchscreen/Makefile                 |   1 +
>  drivers/input/touchscreen/imx6ul_tsc.c             | 504
> +++++++++++++++++++++
>  7 files changed, 583 insertions(+)
>  create mode 100644
> Documentation/devicetree/bindings/input/touchscreen/imx6ul_tsc.txt
>  create mode 100644 drivers/input/touchscreen/imx6ul_tsc.c
> 
> --
> 1.9.1



From tony at atomide.com  Wed Aug 12 00:28:16 2015
From: tony at atomide.com (Tony Lindgren)
Date: Wed, 12 Aug 2015 00:28:16 -0700
Subject: [RFC/PATCH-v4.2-rc6 2/5] arm: boot: dts: am4372: add ARM timers
 and SCU nodes
In-Reply-To: <1439242911-715-3-git-send-email-balbi@ti.com>
References: <1439242911-715-1-git-send-email-balbi@ti.com>
 <1439242911-715-3-git-send-email-balbi@ti.com>
Message-ID: <20150812072816.GR4215@atomide.com>

* Felipe Balbi <balbi at ti.com> [150810 14:44]:
> AM437x devices sport SCU, TWD and Global timers,
> let's add them to DTS so they have a chance to
> probe and be used by Linux.

Is this one safe to apply already without the Kconfig change?

Or will it cause multi_v7_defconfig with the timers selected
to not boot properly?

Regards,

Tony


From linux at arm.linux.org.uk  Wed Aug 12 00:35:15 2015
From: linux at arm.linux.org.uk (Russell King - ARM Linux)
Date: Wed, 12 Aug 2015 08:35:15 +0100
Subject: My boot farm
Message-ID: <20150812073515.GE7557@n2100.arm.linux.org.uk>

... will be offline for a while as, on the face of it, the Digi TS16
rack (terminal server) internal power supply seems to have died.  I'll
investigate further on Friday, but in the mean time, I'm taking the
boot tests completely offline until it's resolved.

As such, I'll be less inclined to merge new code as it'll get less
testing before being pushed out.

-- 
FTTC broadband for 0.8mile line: currently at 10.5Mbps down 400kbps up
according to speedtest.net.


From viresh.kumar at linaro.org  Wed Aug 12 00:35:30 2015
From: viresh.kumar at linaro.org (Viresh Kumar)
Date: Wed, 12 Aug 2015 13:05:30 +0530
Subject: 3.18: lockdep problems in cpufreq
In-Reply-To: <20150812072129.GD7557@n2100.arm.linux.org.uk>
References: <20141214213655.GA11285@n2100.arm.linux.org.uk>
 <CAKohponhkk9BK6-7ScHeZa4R43iooWQFV8YoPLv6LjO40GNq=A@mail.gmail.com>
 <20150518185645.GA28053@n2100.arm.linux.org.uk>
 <2574268.XBqpdL2VLI@vostro.rjw.lan>
 <20150811170357.GA24529@n2100.arm.linux.org.uk>
 <20150812051659.GI32049@linux>
 <20150812072129.GD7557@n2100.arm.linux.org.uk>
Message-ID: <20150812073530.GA16445@linux>

On 12-08-15, 08:21, Russell King - ARM Linux wrote:
> Maybe not - I often lose track of which patches are in what state -
> tracking the state of 250+ patches over many months and in some cases
> _years_ is not easy.

I agree..

> That's still no reason for Eduardo to _completely_ ignore this thread,
> especially when Rafael explicitly tried to get comment from Eduardo.

Oh, no. I am not trying to be anybody's advocate here. I was just
highlighting the point here, that I remembered.

Even I was quite busy then and couldn't get back to it.

Lets fix this now. I believe you have a patch for this based on latest
kernel? Mind pasting that here for quick review?

-- 
viresh


From rmk+kernel at arm.linux.org.uk  Wed Aug 12 00:41:49 2015
From: rmk+kernel at arm.linux.org.uk (Russell King)
Date: Wed, 12 Aug 2015 08:41:49 +0100
Subject: [PATCH] thermal: cpu_cooling: fix lockdep problems in cpu_cooling
In-Reply-To: <20150812073530.GA16445@linux>
References: <20150812073530.GA16445@linux>
Message-ID: <E1ZPQfV-0005nb-DN@rmk-PC.arm.linux.org.uk>

A recent change to the cpu_cooling code introduced a AB-BA deadlock
scenario between the cpufreq_policy_notifier_list rwsem and the
cooling_cpufreq_lock.  This is caused by cooling_cpufreq_lock being held
before the registration/removal of the notifier block (an operation
which takes the rwsem), and the notifier code itself which takes the
locks in the reverse order:

======================================================
[ INFO: possible circular locking dependency detected ]
3.18.0+ #1453 Not tainted
-------------------------------------------------------
rc.local/770 is trying to acquire lock:
 (cooling_cpufreq_lock){+.+.+.}, at: [<c04abfc4>] cpufreq_thermal_notifier+0x34/0xfc

but task is already holding lock:
 ((cpufreq_policy_notifier_list).rwsem){++++.+}, at: [<c0042f04>]  __blocking_notifier_call_chain+0x34/0x68

which lock already depends on the new lock.

the existing dependency chain (in reverse order) is:

-> #1 ((cpufreq_policy_notifier_list).rwsem){++++.+}:
       [<c06bc3b0>] down_write+0x44/0x9c
       [<c0043444>] blocking_notifier_chain_register+0x28/0xd8
       [<c04ad610>] cpufreq_register_notifier+0x68/0x90
       [<c04abe4c>] __cpufreq_cooling_register.part.1+0x120/0x180
       [<c04abf44>] __cpufreq_cooling_register+0x98/0xa4
       [<c04abf8c>] cpufreq_cooling_register+0x18/0x1c
       [<bf0046f8>] imx_thermal_probe+0x1c0/0x470 [imx_thermal]
       [<c037cef8>] platform_drv_probe+0x50/0xac
       [<c037b710>] driver_probe_device+0x114/0x234
       [<c037b8cc>] __driver_attach+0x9c/0xa0
       [<c0379d68>] bus_for_each_dev+0x5c/0x90
       [<c037b204>] driver_attach+0x24/0x28
       [<c037ae7c>] bus_add_driver+0xe0/0x1d8
       [<c037c0cc>] driver_register+0x80/0xfc
       [<c037cd80>] __platform_driver_register+0x50/0x64
       [<bf007018>] 0xbf007018
       [<c0008a5c>] do_one_initcall+0x88/0x1d8
       [<c0095da4>] load_module+0x1768/0x1ef8
       [<c0096614>] SyS_init_module+0xe0/0xf4
       [<c000ec00>] ret_fast_syscall+0x0/0x48

-> #0 (cooling_cpufreq_lock){+.+.+.}:
       [<c00619f8>] lock_acquire+0xb0/0x124
       [<c06ba3b4>] mutex_lock_nested+0x5c/0x3d8
       [<c04abfc4>] cpufreq_thermal_notifier+0x34/0xfc
       [<c0042bf4>] notifier_call_chain+0x4c/0x8c
       [<c0042f20>] __blocking_notifier_call_chain+0x50/0x68
       [<c0042f58>] blocking_notifier_call_chain+0x20/0x28
       [<c04ae62c>] cpufreq_set_policy+0x7c/0x1d0
       [<c04af3cc>] store_scaling_governor+0x74/0x9c
       [<c04ad418>] store+0x90/0xc0
       [<c0175384>] sysfs_kf_write+0x54/0x58
       [<c01746b4>] kernfs_fop_write+0xdc/0x190
       [<c010dcc0>] vfs_write+0xac/0x1b4
       [<c010dfec>] SyS_write+0x44/0x90
       [<c000ec00>] ret_fast_syscall+0x0/0x48

other info that might help us debug this:

 Possible unsafe locking scenario:

       CPU0                    CPU1
       ----                    ----
  lock((cpufreq_policy_notifier_list).rwsem);
                               lock(cooling_cpufreq_lock);
                               lock((cpufreq_policy_notifier_list).rwsem);
  lock(cooling_cpufreq_lock);

 *** DEADLOCK ***

7 locks held by rc.local/770:
 #0:  (sb_writers#6){.+.+.+}, at: [<c010dda0>] vfs_write+0x18c/0x1b4
 #1:  (&of->mutex){+.+.+.}, at: [<c0174678>] kernfs_fop_write+0xa0/0x190
 #2:  (s_active#52){.+.+.+}, at: [<c0174680>] kernfs_fop_write+0xa8/0x190
 #3:  (cpu_hotplug.lock){++++++}, at: [<c0026a60>] get_online_cpus+0x34/0x90
 #4:  (cpufreq_rwsem){.+.+.+}, at: [<c04ad3e0>] store+0x58/0xc0
 #5:  (&policy->rwsem){+.+.+.}, at: [<c04ad3f8>] store+0x70/0xc0
 #6:  ((cpufreq_policy_notifier_list).rwsem){++++.+}, at: [<c0042f04>] __blocking_notifier_call_chain+0x34/0x68

stack backtrace:
CPU: 0 PID: 770 Comm: rc.local Not tainted 3.18.0+ #1453
Hardware name: Freescale i.MX6 Quad/DualLite (Device Tree)
Backtrace:
[<c00121c8>] (dump_backtrace) from [<c0012360>] (show_stack+0x18/0x1c)
 r6:c0b85a80 r5:c0b75630 r4:00000000 r3:00000000
[<c0012348>] (show_stack) from [<c06b6c48>] (dump_stack+0x7c/0x98)
[<c06b6bcc>] (dump_stack) from [<c06b42a4>] (print_circular_bug+0x28c/0x2d8)
 r4:c0b85a80 r3:d0071d40
[<c06b4018>] (print_circular_bug) from [<c00613b0>] (__lock_acquire+0x1acc/0x1bb0)
 r10:c0b50660 r8:c09e6d80 r7:d0071d40 r6:c11d0f0c r5:00000007 r4:d0072240
[<c005f8e4>] (__lock_acquire) from [<c00619f8>] (lock_acquire+0xb0/0x124)
 r10:00000000 r9:c04abfc4 r8:00000000 r7:00000000 r6:00000000 r5:c0a06f0c
 r4:00000000
[<c0061948>] (lock_acquire) from [<c06ba3b4>] (mutex_lock_nested+0x5c/0x3d8)
 r10:ec853800 r9:c0a06ed4 r8:d0071d40 r7:c0a06ed4 r6:c11d0f0c r5:00000000
 r4:c04abfc4
[<c06ba358>] (mutex_lock_nested) from [<c04abfc4>] (cpufreq_thermal_notifier+0x34/0xfc)
 r10:ec853800 r9:ec85380c r8:d00d7d3c r7:c0a06ed4 r6:d00d7d3c r5:00000000
 r4:fffffffe
[<c04abf90>] (cpufreq_thermal_notifier) from [<c0042bf4>] (notifier_call_chain+0x4c/0x8c)
 r7:00000000 r6:00000000 r5:00000000 r4:fffffffe
[<c0042ba8>] (notifier_call_chain) from [<c0042f20>] (__blocking_notifier_call_chain+0x50/0x68)
 r8:c0a072a4 r7:00000000 r6:d00d7d3c r5:ffffffff r4:c0a06fc8 r3:ffffffff
[<c0042ed0>] (__blocking_notifier_call_chain) from [<c0042f58>] (blocking_notifier_call_chain+0x20/0x28)
 r7:ec98b540 r6:c13ebc80 r5:ed76e600 r4:d00d7d3c
[<c0042f38>] (blocking_notifier_call_chain) from [<c04ae62c>] (cpufreq_set_policy+0x7c/0x1d0)
[<c04ae5b0>] (cpufreq_set_policy) from [<c04af3cc>] (store_scaling_governor+0x74/0x9c)
 r7:ec98b540 r6:0000000c r5:ec98b540 r4:ed76e600
[<c04af358>] (store_scaling_governor) from [<c04ad418>] (store+0x90/0xc0)
 r6:0000000c r5:ed76e6d4 r4:ed76e600
[<c04ad388>] (store) from [<c0175384>] (sysfs_kf_write+0x54/0x58)
 r8:0000000c r7:d00d7f78 r6:ec98b540 r5:0000000c r4:ec853800 r3:0000000c
[<c0175330>] (sysfs_kf_write) from [<c01746b4>] (kernfs_fop_write+0xdc/0x190)
 r6:ec98b540 r5:00000000 r4:00000000 r3:c0175330
[<c01745d8>] (kernfs_fop_write) from [<c010dcc0>] (vfs_write+0xac/0x1b4)
 r10:0162aa70 r9:d00d6000 r8:0000000c r7:d00d7f78 r6:0162aa70 r5:0000000c
 r4:eccde500
[<c010dc14>] (vfs_write) from [<c010dfec>] (SyS_write+0x44/0x90)
 r10:0162aa70 r8:0000000c r7:eccde500 r6:eccde500 r5:00000000 r4:00000000
[<c010dfa8>] (SyS_write) from [<c000ec00>] (ret_fast_syscall+0x0/0x48)
 r10:00000000 r8:c000edc4 r7:00000004 r6:000216cc r5:0000000c r4:0162aa70

Solve this by moving to finer grained locking - use one mutex to protect
the cpufreq_dev_list as a whole, and a separate lock to ensure correct
ordering of cpufreq notifier registration and removal.

I considered taking the cooling_list_lock within cooling_cpufreq_lock to
protect the registration sequence as a whole, but that adds a dependency
between these two locks which is best avoided (lest someone tries to
take those two new locks in the reverse order.)  In any case, it's safer
to have an empty cpufreq_dev_list than to have unnecessary dependencies
between locks.

Fixes: 2dcd851fe4b4 ("thermal: cpu_cooling: Update always cpufreq policy with
Reviewed-by: Viresh Kumar <viresh.kumar at linaro.org>
Signed-off-by: Russell King <rmk+kernel at arm.linux.org.uk>

For some reason, despite Rafael saying that this should go in, despite it
having been reviewed, Eduardo appears to be ignoring basic fixes to code
under his control.  Having waited more than a reasonable amount of time,
it is now time to take some action against this blockage.  Hence, I'm
putting this into linux-next in the hope that it'll conflict and elicit
a response for this important bug fix.

Relevant message IDs:
20141214213655.GA11285 at n2100.arm.linux.org.uk
7573578.UE8ufgjWuX at vostro.rjw.lan
20141215230922.GL11285 at n2100.arm.linux.org.uk
CAKohponhkk9BK6-7ScHeZa4R43iooWQFV8YoPLv6LjO40GNq=A at mail.gmail.com
20150518185645.GA28053 at n2100.arm.linux.org.uk
2574268.XBqpdL2VLI at vostro.rjw.lan
---
 drivers/thermal/cpu_cooling.c | 22 ++++++++++++++++------
 1 file changed, 16 insertions(+), 6 deletions(-)

diff --git a/drivers/thermal/cpu_cooling.c b/drivers/thermal/cpu_cooling.c
index 6509c61b9648..d1fd02eec58d 100644
--- a/drivers/thermal/cpu_cooling.c
+++ b/drivers/thermal/cpu_cooling.c
@@ -107,6 +107,9 @@ struct cpufreq_cooling_device {
 static DEFINE_IDR(cpufreq_idr);
 static DEFINE_MUTEX(cooling_cpufreq_lock);
 
+static unsigned int cpufreq_dev_count;
+
+static DEFINE_MUTEX(cooling_list_lock);
 static LIST_HEAD(cpufreq_dev_list);
 
 /**
@@ -221,7 +224,7 @@ static int cpufreq_thermal_notifier(struct notifier_block *nb,
 	switch (event) {
 
 	case CPUFREQ_ADJUST:
-		mutex_lock(&cooling_cpufreq_lock);
+		mutex_lock(&cooling_list_lock);
 		list_for_each_entry(cpufreq_dev, &cpufreq_dev_list, node) {
 			if (!cpumask_test_cpu(policy->cpu,
 					      &cpufreq_dev->allowed_cpus))
@@ -233,7 +236,7 @@ static int cpufreq_thermal_notifier(struct notifier_block *nb,
 				cpufreq_verify_within_limits(policy, 0,
 							     max_freq);
 		}
-		mutex_unlock(&cooling_cpufreq_lock);
+		mutex_unlock(&cooling_list_lock);
 		break;
 	default:
 		return NOTIFY_DONE;
@@ -865,12 +868,15 @@ __cpufreq_cooling_register(struct device_node *np,
 	cpufreq_dev->cool_dev = cool_dev;
 
 	mutex_lock(&cooling_cpufreq_lock);
+	mutex_lock(&cooling_list_lock);
+	list_add(&cpufreq_dev->node, &cpufreq_dev_list);
+	mutex_unlock(&cooling_list_lock);
 
 	/* Register the notifier for first cpufreq cooling device */
-	if (list_empty(&cpufreq_dev_list))
+	if (cpufreq_dev_count == 0)
 		cpufreq_register_notifier(&thermal_cpufreq_notifier_block,
 					  CPUFREQ_POLICY_NOTIFIER);
-	list_add(&cpufreq_dev->node, &cpufreq_dev_list);
+	cpufreq_dev_count++;
 
 	mutex_unlock(&cooling_cpufreq_lock);
 
@@ -1014,14 +1020,18 @@ void cpufreq_cooling_unregister(struct thermal_cooling_device *cdev)
 
 	cpufreq_dev = cdev->devdata;
 	mutex_lock(&cooling_cpufreq_lock);
-	list_del(&cpufreq_dev->node);
+	cpufreq_dev_count--;
 
 	/* Unregister the notifier for the last cpufreq cooling device */
-	if (list_empty(&cpufreq_dev_list))
+	if (cpufreq_dev_count == 0)
 		cpufreq_unregister_notifier(&thermal_cpufreq_notifier_block,
 					    CPUFREQ_POLICY_NOTIFIER);
 	mutex_unlock(&cooling_cpufreq_lock);
 
+	mutex_lock(&cooling_list_lock);
+	list_del(&cpufreq_dev->node);
+	mutex_unlock(&cooling_list_lock);
+
 	thermal_cooling_device_unregister(cpufreq_dev->cool_dev);
 	release_idr(&cpufreq_idr, cpufreq_dev->id);
 	kfree(cpufreq_dev->time_in_idle_timestamp);
-- 
2.1.0



From horia.geanta at freescale.com  Wed Aug 12 00:42:41 2015
From: horia.geanta at freescale.com (=?UTF-8?q?Horia=20Geant=C4=83?=)
Date: Wed, 12 Aug 2015 10:42:41 +0300
Subject: [PATCH] ARM: dts: ls1021a: add crypto node
Message-ID: <1439365361-24129-1-git-send-email-horia.geanta@freescale.com>

Signed-off-by: Horia Geant? <horia.geanta at freescale.com>
---
 arch/arm/boot/dts/ls1021a.dtsi | 40 ++++++++++++++++++++++++++++++++++++++++
 1 file changed, 40 insertions(+)

diff --git a/arch/arm/boot/dts/ls1021a.dtsi b/arch/arm/boot/dts/ls1021a.dtsi
index 973a496207fc..5bd64a4df4d3 100644
--- a/arch/arm/boot/dts/ls1021a.dtsi
+++ b/arch/arm/boot/dts/ls1021a.dtsi
@@ -63,6 +63,7 @@
 		serial4 = &lpuart4;
 		serial5 = &lpuart5;
 		sysclk = &sysclk;
+		crypto = &crypto;
 	};
 
 	cpus {
@@ -148,6 +149,45 @@
 			big-endian;
 		};
 
+		crypto: crypto at 1700000 {
+			compatible = "fsl,sec-v5.0", "fsl,sec-v4.0";
+			fsl,sec-era = <7>;
+			#address-cells = <1>;
+			#size-cells = <1>;
+			reg		 = <0x0 0x1700000 0x0 0x100000>;
+			ranges		 = <0x0 0x0 0x1700000 0x100000>;
+			interrupts	 = <GIC_SPI 107 IRQ_TYPE_LEVEL_HIGH>;
+
+			sec_jr0: jr at 10000 {
+				compatible = "fsl,sec-v5.0-job-ring",
+				     "fsl,sec-v4.0-job-ring";
+				reg = <0x10000 0x10000>;
+				interrupts = <GIC_SPI 103 IRQ_TYPE_LEVEL_HIGH>;
+			};
+
+			sec_jr1: jr at 20000 {
+				compatible = "fsl,sec-v5.0-job-ring",
+				     "fsl,sec-v4.0-job-ring";
+				reg = <0x20000 0x10000>;
+				interrupts = <GIC_SPI 104 IRQ_TYPE_LEVEL_HIGH>;
+			};
+
+			sec_jr2: jr at 30000 {
+				compatible = "fsl,sec-v5.0-job-ring",
+				     "fsl,sec-v4.0-job-ring";
+				reg = <0x30000 0x10000>;
+				interrupts = <GIC_SPI 105 IRQ_TYPE_LEVEL_HIGH>;
+			};
+
+			sec_jr3: jr at 40000 {
+				compatible = "fsl,sec-v5.0-job-ring",
+				     "fsl,sec-v4.0-job-ring";
+				reg = <0x40000 0x10000>;
+				interrupts = <GIC_SPI 106 IRQ_TYPE_LEVEL_HIGH>;
+			};
+
+		};
+
 		clockgen: clocking at 1ee1000 {
 			#address-cells = <1>;
 			#size-cells = <1>;
-- 
2.4.4



From linux at arm.linux.org.uk  Wed Aug 12 00:44:39 2015
From: linux at arm.linux.org.uk (Russell King - ARM Linux)
Date: Wed, 12 Aug 2015 08:44:39 +0100
Subject: [PATCH v2 1/2] soc/fsl: add freescale dir for SOC specific drivers
In-Reply-To: <1439358807-9024-1-git-send-email-dongsheng.wang@freescale.com>
References: <1439358807-9024-1-git-send-email-dongsheng.wang@freescale.com>
Message-ID: <20150812074439.GF7557@n2100.arm.linux.org.uk>

On Wed, Aug 12, 2015 at 01:53:26PM +0800, Dongsheng Wang wrote:
> diff --git a/drivers/soc/fsl/Kconfig b/drivers/soc/fsl/Kconfig
> new file mode 100644
> index 0000000..863d1ef
> --- /dev/null
> +++ b/drivers/soc/fsl/Kconfig
> @@ -0,0 +1,18 @@
> +#
> +# Freescale SOC drivers
> +#
> +menuconfig FSL_SOC_DRIVERS
> +	bool "Freescale Soc Drivers"
> +	default n

No need for default n.

> diff --git a/drivers/soc/fsl/Kconfig.arm b/drivers/soc/fsl/Kconfig.arm
> new file mode 100644
> index 0000000..8c90b82
> --- /dev/null
> +++ b/drivers/soc/fsl/Kconfig.arm
> @@ -0,0 +1,16 @@
> +#
> +# Freescale ARM SOC Drivers
> +#
> +
> +config	LS1_SOC_DRIVERS
> +	bool "LS1021A Soc Drivers"
> +	depends on SOC_LS1021A
> +	default n

Ditto.

> +	help
> +	Say y here to enable Freescale LS1021A Soc Device Drivers support.
> +	The Soc Drivers provides the device driver that is a specific block
> +	or feature on LS1021A platform.

Help text should be indented by two spaces as per almost every other
help text.

> +
> +if LS1_SOC_DRIVERS
> +	source "drivers/soc/fsl/ls1/Kconfig"
> +endif
> diff --git a/drivers/soc/fsl/Makefile b/drivers/soc/fsl/Makefile
> new file mode 100644
> index 0000000..b4215dd
> --- /dev/null
> +++ b/drivers/soc/fsl/Makefile
> @@ -0,0 +1,6 @@
> +#
> +# Makefile for Freescale Soc specific device drivers.
> +#
> +
> +obj-$(CONFIG_LS1_SOC_DRIVERS) += ls1/
> +
> diff --git a/drivers/soc/fsl/ls1/Kconfig b/drivers/soc/fsl/ls1/Kconfig
> new file mode 100644
> index 0000000..7556f44
> --- /dev/null
> +++ b/drivers/soc/fsl/ls1/Kconfig
> @@ -0,0 +1,3 @@
> +#
> +# LS-1 Soc drivers
> +#

Doesn't this directory need a Makefile as well?

-- 
FTTC broadband for 0.8mile line: currently at 10.5Mbps down 400kbps up
according to speedtest.net.


From linux at arm.linux.org.uk  Wed Aug 12 00:49:25 2015
From: linux at arm.linux.org.uk (Russell King - ARM Linux)
Date: Wed, 12 Aug 2015 08:49:25 +0100
Subject: 3.18: lockdep problems in cpufreq
In-Reply-To: <20150812073530.GA16445@linux>
References: <20141214213655.GA11285@n2100.arm.linux.org.uk>
 <CAKohponhkk9BK6-7ScHeZa4R43iooWQFV8YoPLv6LjO40GNq=A@mail.gmail.com>
 <20150518185645.GA28053@n2100.arm.linux.org.uk>
 <2574268.XBqpdL2VLI@vostro.rjw.lan>
 <20150811170357.GA24529@n2100.arm.linux.org.uk>
 <20150812051659.GI32049@linux>
 <20150812072129.GD7557@n2100.arm.linux.org.uk>
 <20150812073530.GA16445@linux>
Message-ID: <20150812074925.GG7557@n2100.arm.linux.org.uk>

On Wed, Aug 12, 2015 at 01:05:30PM +0530, Viresh Kumar wrote:
> On 12-08-15, 08:21, Russell King - ARM Linux wrote:
> > Maybe not - I often lose track of which patches are in what state -
> > tracking the state of 250+ patches over many months and in some cases
> > _years_ is not easy.
> 
> I agree..
> 
> > That's still no reason for Eduardo to _completely_ ignore this thread,
> > especially when Rafael explicitly tried to get comment from Eduardo.
> 
> Oh, no. I am not trying to be anybody's advocate here. I was just
> highlighting the point here, that I remembered.
> 
> Even I was quite busy then and couldn't get back to it.
> 
> Lets fix this now. I believe you have a patch for this based on latest
> kernel? Mind pasting that here for quick review?

I don't think it's changed much since the original, but I've posted
what's in linux-next as of today, and it doesn't conflict with anything.
So there's no excuse about getting it merged.

The problem will be back-porting it to stable kernels, because I think
it's had to be updated at least a couple of times.  I don't have the old
versions anymore, so I'm just going to say "not my problem" - sorry.

-- 
FTTC broadband for 0.8mile line: currently at 10.5Mbps down 400kbps up
according to speedtest.net.


From Dongsheng.Wang at freescale.com  Wed Aug 12 01:01:32 2015
From: Dongsheng.Wang at freescale.com (Wang Dongsheng)
Date: Wed, 12 Aug 2015 08:01:32 +0000
Subject: [PATCH v2 1/2] soc/fsl: add freescale dir for SOC specific drivers
In-Reply-To: <20150812074439.GF7557@n2100.arm.linux.org.uk>
References: <1439358807-9024-1-git-send-email-dongsheng.wang@freescale.com>
 <20150812074439.GF7557@n2100.arm.linux.org.uk>
Message-ID: <SN1PR0301MB1616C942574FB3261B811DB19D7E0@SN1PR0301MB1616.namprd03.prod.outlook.com>

Hi Russell,

Thanks for your review. :)

> -----Original Message-----
> From: Russell King - ARM Linux [mailto:linux at arm.linux.org.uk]
> Sent: Wednesday, August 12, 2015 3:45 PM
> To: Wang Dongsheng-B40534
> Cc: shawn.guo at linaro.org; Wang Huan-B18965; linus.walleij at linaro.org; linux-
> kernel at vger.kernel.org; sandeep_n at ti.com; hdegoede at redhat.com; linux-arm-
> kernel at lists.infradead.org
> Subject: Re: [PATCH v2 1/2] soc/fsl: add freescale dir for SOC specific drivers
> 
> On Wed, Aug 12, 2015 at 01:53:26PM +0800, Dongsheng Wang wrote:
> > diff --git a/drivers/soc/fsl/Kconfig b/drivers/soc/fsl/Kconfig new
> > file mode 100644 index 0000000..863d1ef
> > --- /dev/null
> > +++ b/drivers/soc/fsl/Kconfig
> > @@ -0,0 +1,18 @@
> > +#
> > +# Freescale SOC drivers
> > +#
> > +menuconfig FSL_SOC_DRIVERS
> > +	bool "Freescale Soc Drivers"
> > +	default n
> 
> No need for default n.

Thanks. Fix it in next version.

> > +	help
> > +	Say y here to enable Freescale LS1021A Soc Device Drivers support.
> > +	The Soc Drivers provides the device driver that is a specific block
> > +	or feature on LS1021A platform.
> 
> Help text should be indented by two spaces as per almost every other help text.
> 

Thanks. My mistake...

> > +
> > +if LS1_SOC_DRIVERS
> > +	source "drivers/soc/fsl/ls1/Kconfig"
> > +endif
> > diff --git a/drivers/soc/fsl/Makefile b/drivers/soc/fsl/Makefile new
> > file mode 100644 index 0000000..b4215dd
> > --- /dev/null
> > +++ b/drivers/soc/fsl/Makefile
> > @@ -0,0 +1,6 @@
> > +#
> > +# Makefile for Freescale Soc specific device drivers.
> > +#
> > +
> > +obj-$(CONFIG_LS1_SOC_DRIVERS) += ls1/
> > +
> > diff --git a/drivers/soc/fsl/ls1/Kconfig b/drivers/soc/fsl/ls1/Kconfig
> > new file mode 100644 index 0000000..7556f44
> > --- /dev/null
> > +++ b/drivers/soc/fsl/ls1/Kconfig
> > @@ -0,0 +1,3 @@
> > +#
> > +# LS-1 Soc drivers
> > +#
> 
> Doesn't this directory need a Makefile as well?
> 

2/2 patch add a config option and Makefile for this.

Regards,
-Dongsheng


From linux at arm.linux.org.uk  Wed Aug 12 01:03:54 2015
From: linux at arm.linux.org.uk (Russell King - ARM Linux)
Date: Wed, 12 Aug 2015 09:03:54 +0100
Subject: [PATCH v2 1/2] soc/fsl: add freescale dir for SOC specific drivers
In-Reply-To: <SN1PR0301MB1616C942574FB3261B811DB19D7E0@SN1PR0301MB1616.namprd03.prod.outlook.com>
References: <1439358807-9024-1-git-send-email-dongsheng.wang@freescale.com>
 <20150812074439.GF7557@n2100.arm.linux.org.uk>
 <SN1PR0301MB1616C942574FB3261B811DB19D7E0@SN1PR0301MB1616.namprd03.prod.outlook.com>
Message-ID: <20150812080354.GH7557@n2100.arm.linux.org.uk>

On Wed, Aug 12, 2015 at 08:01:32AM +0000, Wang Dongsheng wrote:
> Hi Russell,
> 
> Thanks for your review. :)
> 
> > -----Original Message-----
> > From: Russell King - ARM Linux [mailto:linux at arm.linux.org.uk]
> > Sent: Wednesday, August 12, 2015 3:45 PM
> > To: Wang Dongsheng-B40534
> > Cc: shawn.guo at linaro.org; Wang Huan-B18965; linus.walleij at linaro.org; linux-
> > kernel at vger.kernel.org; sandeep_n at ti.com; hdegoede at redhat.com; linux-arm-
> > kernel at lists.infradead.org
> > Subject: Re: [PATCH v2 1/2] soc/fsl: add freescale dir for SOC specific drivers
> > 
> > On Wed, Aug 12, 2015 at 01:53:26PM +0800, Dongsheng Wang wrote:
> > > diff --git a/drivers/soc/fsl/Kconfig b/drivers/soc/fsl/Kconfig new
> > > file mode 100644 index 0000000..863d1ef
> > > --- /dev/null
> > > +++ b/drivers/soc/fsl/Kconfig
> > > @@ -0,0 +1,18 @@
> > > +#
> > > +# Freescale SOC drivers
> > > +#
> > > +menuconfig FSL_SOC_DRIVERS
> > > +	bool "Freescale Soc Drivers"
> > > +	default n
> > 
> > No need for default n.
> 
> Thanks. Fix it in next version.
> 
> > > +	help
> > > +	Say y here to enable Freescale LS1021A Soc Device Drivers support.
> > > +	The Soc Drivers provides the device driver that is a specific block
> > > +	or feature on LS1021A platform.
> > 
> > Help text should be indented by two spaces as per almost every other help text.
> > 
> 
> Thanks. My mistake...
> 
> > > +
> > > +if LS1_SOC_DRIVERS
> > > +	source "drivers/soc/fsl/ls1/Kconfig"
> > > +endif
> > > diff --git a/drivers/soc/fsl/Makefile b/drivers/soc/fsl/Makefile new
> > > file mode 100644 index 0000000..b4215dd
> > > --- /dev/null
> > > +++ b/drivers/soc/fsl/Makefile
> > > @@ -0,0 +1,6 @@
> > > +#
> > > +# Makefile for Freescale Soc specific device drivers.
> > > +#
> > > +
> > > +obj-$(CONFIG_LS1_SOC_DRIVERS) += ls1/
> > > +
> > > diff --git a/drivers/soc/fsl/ls1/Kconfig b/drivers/soc/fsl/ls1/Kconfig
> > > new file mode 100644 index 0000000..7556f44
> > > --- /dev/null
> > > +++ b/drivers/soc/fsl/ls1/Kconfig
> > > @@ -0,0 +1,3 @@
> > > +#
> > > +# LS-1 Soc drivers
> > > +#
> > 
> > Doesn't this directory need a Makefile as well?
> > 
> 
> 2/2 patch add a config option and Makefile for this.

If _just_ this patch is merged, it creates a build problem as
CONFIG_LS1_SOC_DRIVERS can be enabled, which will cause the kbuild to
decend into drivers/soc/fsl/ls1, where it will stop due to the missing
build error.

Please fix this by adding at least an empty Makefile to this directory.
Do not rely on patch 2 being merged to "fix" this.

-- 
FTTC broadband for 0.8mile line: currently at 10.5Mbps down 400kbps up
according to speedtest.net.


From Dongsheng.Wang at freescale.com  Wed Aug 12 01:10:12 2015
From: Dongsheng.Wang at freescale.com (Wang Dongsheng)
Date: Wed, 12 Aug 2015 08:10:12 +0000
Subject: [PATCH v2 1/2] soc/fsl: add freescale dir for SOC specific drivers
In-Reply-To: <20150812080354.GH7557@n2100.arm.linux.org.uk>
References: <1439358807-9024-1-git-send-email-dongsheng.wang@freescale.com>
 <20150812074439.GF7557@n2100.arm.linux.org.uk>
 <SN1PR0301MB1616C942574FB3261B811DB19D7E0@SN1PR0301MB1616.namprd03.prod.outlook.com>
 <20150812080354.GH7557@n2100.arm.linux.org.uk>
Message-ID: <SN1PR0301MB16166F525E73A892C673F2C19D7E0@SN1PR0301MB1616.namprd03.prod.outlook.com>



> -----Original Message-----
> From: Russell King - ARM Linux [mailto:linux at arm.linux.org.uk]
> Sent: Wednesday, August 12, 2015 4:04 PM
> To: Wang Dongsheng-B40534
> Cc: shawn.guo at linaro.org; Wang Huan-B18965; linus.walleij at linaro.org; linux-
> kernel at vger.kernel.org; sandeep_n at ti.com; hdegoede at redhat.com; linux-arm-
> kernel at lists.infradead.org
> Subject: Re: [PATCH v2 1/2] soc/fsl: add freescale dir for SOC specific drivers
> 
> On Wed, Aug 12, 2015 at 08:01:32AM +0000, Wang Dongsheng wrote:
> > Hi Russell,
> >
> > Thanks for your review. :)
> >
> > > -----Original Message-----
> > > From: Russell King - ARM Linux [mailto:linux at arm.linux.org.uk]
> > > Sent: Wednesday, August 12, 2015 3:45 PM
> > > To: Wang Dongsheng-B40534
> > > Cc: shawn.guo at linaro.org; Wang Huan-B18965;
> > > linus.walleij at linaro.org; linux- kernel at vger.kernel.org;
> > > sandeep_n at ti.com; hdegoede at redhat.com; linux-arm-
> > > kernel at lists.infradead.org
> > > Subject: Re: [PATCH v2 1/2] soc/fsl: add freescale dir for SOC
> > > specific drivers
> > >
> > > On Wed, Aug 12, 2015 at 01:53:26PM +0800, Dongsheng Wang wrote:
> > > > diff --git a/drivers/soc/fsl/Kconfig b/drivers/soc/fsl/Kconfig new
> > > > file mode 100644 index 0000000..863d1ef
> > > > --- /dev/null
> > > > +++ b/drivers/soc/fsl/Kconfig
> > > > @@ -0,0 +1,18 @@
> > > > +#
> > > > +# Freescale SOC drivers
> > > > +#
> > > > +menuconfig FSL_SOC_DRIVERS
> > > > +	bool "Freescale Soc Drivers"
> > > > +	default n
> > >
> > > No need for default n.
> >
> > Thanks. Fix it in next version.
> >
> > > > +	help
> > > > +	Say y here to enable Freescale LS1021A Soc Device Drivers support.
> > > > +	The Soc Drivers provides the device driver that is a specific block
> > > > +	or feature on LS1021A platform.
> > >
> > > Help text should be indented by two spaces as per almost every other help
> text.
> > >
> >
> > Thanks. My mistake...
> >
> > > > +
> > > > +if LS1_SOC_DRIVERS
> > > > +	source "drivers/soc/fsl/ls1/Kconfig"
> > > > +endif
> > > > diff --git a/drivers/soc/fsl/Makefile b/drivers/soc/fsl/Makefile
> > > > new file mode 100644 index 0000000..b4215dd
> > > > --- /dev/null
> > > > +++ b/drivers/soc/fsl/Makefile
> > > > @@ -0,0 +1,6 @@
> > > > +#
> > > > +# Makefile for Freescale Soc specific device drivers.
> > > > +#
> > > > +
> > > > +obj-$(CONFIG_LS1_SOC_DRIVERS) += ls1/
> > > > +
> > > > diff --git a/drivers/soc/fsl/ls1/Kconfig
> > > > b/drivers/soc/fsl/ls1/Kconfig new file mode 100644 index
> > > > 0000000..7556f44
> > > > --- /dev/null
> > > > +++ b/drivers/soc/fsl/ls1/Kconfig
> > > > @@ -0,0 +1,3 @@
> > > > +#
> > > > +# LS-1 Soc drivers
> > > > +#
> > >
> > > Doesn't this directory need a Makefile as well?
> > >
> >
> > 2/2 patch add a config option and Makefile for this.
> 
> If _just_ this patch is merged, it creates a build problem as
> CONFIG_LS1_SOC_DRIVERS can be enabled, which will cause the kbuild to decend
> into drivers/soc/fsl/ls1, where it will stop due to the missing build error.
> 
> Please fix this by adding at least an empty Makefile to this directory.
> Do not rely on patch 2 being merged to "fix" this.
> 

Um..Yes, miss it. Fix it in next version. :)

Regards,
-Dongsheng



From viresh.kumar at linaro.org  Wed Aug 12 01:11:43 2015
From: viresh.kumar at linaro.org (Viresh Kumar)
Date: Wed, 12 Aug 2015 13:41:43 +0530
Subject: [PATCH] thermal: cpu_cooling: fix lockdep problems in cpu_cooling
In-Reply-To: <E1ZPQfV-0005nb-DN@rmk-PC.arm.linux.org.uk>
References: <20150812073530.GA16445@linux>
 <E1ZPQfV-0005nb-DN@rmk-PC.arm.linux.org.uk>
Message-ID: <20150812081142.GB16445@linux>

On 12-08-15, 08:41, Russell King wrote:
> diff --git a/drivers/thermal/cpu_cooling.c b/drivers/thermal/cpu_cooling.c
>  /**
> @@ -221,7 +224,7 @@ static int cpufreq_thermal_notifier(struct notifier_block *nb,
>  	switch (event) {
>  
>  	case CPUFREQ_ADJUST:
> -		mutex_lock(&cooling_cpufreq_lock);
> +		mutex_lock(&cooling_list_lock);

There is one more place where the list's locking needs update:
cpufreq_cooling_get_level().

>  		list_for_each_entry(cpufreq_dev, &cpufreq_dev_list, node) {
>  			if (!cpumask_test_cpu(policy->cpu,
>  					      &cpufreq_dev->allowed_cpus))
> @@ -233,7 +236,7 @@ static int cpufreq_thermal_notifier(struct notifier_block *nb,
>  				cpufreq_verify_within_limits(policy, 0,
>  							     max_freq);
>  		}
> -		mutex_unlock(&cooling_cpufreq_lock);
> +		mutex_unlock(&cooling_list_lock);
>  		break;
>  	default:
>  		return NOTIFY_DONE;
> @@ -865,12 +868,15 @@ __cpufreq_cooling_register(struct device_node *np,
>  	cpufreq_dev->cool_dev = cool_dev;
>  
>  	mutex_lock(&cooling_cpufreq_lock);
> +	mutex_lock(&cooling_list_lock);

Why is the list lock taken from within the existing lock here? and ...

> +	list_add(&cpufreq_dev->node, &cpufreq_dev_list);
> +	mutex_unlock(&cooling_list_lock);
>  
>  	/* Register the notifier for first cpufreq cooling device */
> -	if (list_empty(&cpufreq_dev_list))
> +	if (cpufreq_dev_count == 0)
>  		cpufreq_register_notifier(&thermal_cpufreq_notifier_block,
>  					  CPUFREQ_POLICY_NOTIFIER);
> -	list_add(&cpufreq_dev->node, &cpufreq_dev_list);
> +	cpufreq_dev_count++;

Maybe:
        if (!cpufreq_dev_count++)
                cpufreq_register_notifier();

>  
>  	mutex_unlock(&cooling_cpufreq_lock);
>  
> @@ -1014,14 +1020,18 @@ void cpufreq_cooling_unregister(struct thermal_cooling_device *cdev)
>  
>  	cpufreq_dev = cdev->devdata;
>  	mutex_lock(&cooling_cpufreq_lock);
> -	list_del(&cpufreq_dev->node);
> +	cpufreq_dev_count--;
>  
>  	/* Unregister the notifier for the last cpufreq cooling device */
> -	if (list_empty(&cpufreq_dev_list))
> +	if (cpufreq_dev_count == 0)

Maybe:
        if (!--cpufreq_dev_count)
                cpufreq_register_notifier();

>  		cpufreq_unregister_notifier(&thermal_cpufreq_notifier_block,
>  					    CPUFREQ_POLICY_NOTIFIER);
>  	mutex_unlock(&cooling_cpufreq_lock);
>  
> +	mutex_lock(&cooling_list_lock);

... The same list lock is not taken from within the earlier critical
section?

> +	list_del(&cpufreq_dev->node);
> +	mutex_unlock(&cooling_list_lock);
> +
>  	thermal_cooling_device_unregister(cpufreq_dev->cool_dev);
>  	release_idr(&cpufreq_idr, cpufreq_dev->id);
>  	kfree(cpufreq_dev->time_in_idle_timestamp);
> -- 
> 2.1.0

-- 
viresh


From viresh.kumar at linaro.org  Wed Aug 12 01:12:57 2015
From: viresh.kumar at linaro.org (Viresh Kumar)
Date: Wed, 12 Aug 2015 13:42:57 +0530
Subject: 3.18: lockdep problems in cpufreq
In-Reply-To: <20150812074925.GG7557@n2100.arm.linux.org.uk>
References: <20141214213655.GA11285@n2100.arm.linux.org.uk>
 <CAKohponhkk9BK6-7ScHeZa4R43iooWQFV8YoPLv6LjO40GNq=A@mail.gmail.com>
 <20150518185645.GA28053@n2100.arm.linux.org.uk>
 <2574268.XBqpdL2VLI@vostro.rjw.lan>
 <20150811170357.GA24529@n2100.arm.linux.org.uk>
 <20150812051659.GI32049@linux>
 <20150812072129.GD7557@n2100.arm.linux.org.uk>
 <20150812073530.GA16445@linux>
 <20150812074925.GG7557@n2100.arm.linux.org.uk>
Message-ID: <20150812081257.GC16445@linux>

On 12-08-15, 08:49, Russell King - ARM Linux wrote:
> The problem will be back-porting it to stable kernels, because I think
> it's had to be updated at least a couple of times.  I don't have the old
> versions anymore, so I'm just going to say "not my problem" - sorry.

Your old 3.18 version :)

8<===
From: Russell King <rmk+kernel at arm.linux.org.uk>
thermal: cpu_cooling: fix lockdep problems in cpu_cooling

A recent change to the cpu_cooling code introduced a AB-BA deadlock
scenario between the cpufreq_policy_notifier_list rwsem and the
cooling_cpufreq_lock.  This is caused by cooling_cpufreq_lock being held
before the registration/removal of the notifier block (an operation
which takes the rwsem), and the notifier code itself which takes the
locks in the reverse order.

Solve this by moving to finer grained locking - use one mutex to protect
the cpufreq_dev_list as a whole, and a separate lock to ensure correct
ordering of cpufreq notifier registration and removal.

I considered taking the cooling_list_lock within cooling_cpufreq_lock to
protect the registration sequence as a whole, but that adds a dependency
between these two locks which is best avoided (lest someone tries to
take those two new locks in the reverse order.)  In any case, it's safer
to have an empty cpufreq_dev_list than to have unnecessary dependencies
between locks.

Fixes: 2dcd851fe4b4 ("thermal: cpu_cooling: Update always cpufreq policy with thermal constraints")
Reviewed-by: Viresh Kumar <viresh.kumar at linaro.org>
Signed-off-by: Russell King <rmk+kernel at arm.linux.org.uk>
---

 drivers/thermal/cpu_cooling.c | 16 ++++++++++++----
 1 file changed, 12 insertions(+), 4 deletions(-)

diff --git a/drivers/thermal/cpu_cooling.c b/drivers/thermal/cpu_cooling.c
index ad09e51ffae4..9e42c6f30785 100644
--- a/drivers/thermal/cpu_cooling.c
+++ b/drivers/thermal/cpu_cooling.c
@@ -57,6 +57,7 @@ static DEFINE_MUTEX(cooling_cpufreq_lock);
 
 static unsigned int cpufreq_dev_count;
 
+static DEFINE_MUTEX(cooling_list_lock);
 static LIST_HEAD(cpufreq_dev_list);
 
 /**
@@ -317,7 +318,7 @@ static int cpufreq_thermal_notifier(struct notifier_block *nb,
 	if (event != CPUFREQ_ADJUST)
 		return 0;
 
-	mutex_lock(&cooling_cpufreq_lock);
+	mutex_lock(&cooling_list_lock);
 	list_for_each_entry(cpufreq_dev, &cpufreq_dev_list, node) {
 		if (!cpumask_test_cpu(policy->cpu,
 					&cpufreq_dev->allowed_cpus))
@@ -333,7 +334,7 @@ static int cpufreq_thermal_notifier(struct notifier_block *nb,
 		if (policy->max != max_freq)
 			cpufreq_verify_within_limits(policy, 0, max_freq);
 	}
-	mutex_unlock(&cooling_cpufreq_lock);
+	mutex_unlock(&cooling_list_lock);
 
 	return 0;
 }
@@ -482,6 +483,11 @@ __cpufreq_cooling_register(struct device_node *np,
 	}
 	cpufreq_dev->cool_dev = cool_dev;
 	cpufreq_dev->cpufreq_state = 0;
+
+	mutex_lock(&cooling_list_lock);
+	list_add(&cpufreq_dev->node, &cpufreq_dev_list);
+	mutex_unlock(&cooling_list_lock);
+
 	mutex_lock(&cooling_cpufreq_lock);
 
 	/* Register the notifier for first cpufreq cooling device */
@@ -489,7 +495,6 @@ __cpufreq_cooling_register(struct device_node *np,
 		cpufreq_register_notifier(&thermal_cpufreq_notifier_block,
 					  CPUFREQ_POLICY_NOTIFIER);
 	cpufreq_dev_count++;
-	list_add(&cpufreq_dev->node, &cpufreq_dev_list);
 
 	mutex_unlock(&cooling_cpufreq_lock);
 
@@ -553,7 +558,6 @@ void cpufreq_cooling_unregister(struct thermal_cooling_device *cdev)
 
 	cpufreq_dev = cdev->devdata;
 	mutex_lock(&cooling_cpufreq_lock);
-	list_del(&cpufreq_dev->node);
 	cpufreq_dev_count--;
 
 	/* Unregister the notifier for the last cpufreq cooling device */
@@ -562,6 +566,10 @@ void cpufreq_cooling_unregister(struct thermal_cooling_device *cdev)
 					    CPUFREQ_POLICY_NOTIFIER);
 	mutex_unlock(&cooling_cpufreq_lock);
 
+	mutex_lock(&cooling_list_lock);
+	list_del(&cpufreq_dev->node);
+	mutex_unlock(&cooling_list_lock);
+
 	thermal_cooling_device_unregister(cpufreq_dev->cool_dev);
 	release_idr(&cpufreq_idr, cpufreq_dev->id);
 	kfree(cpufreq_dev);



From gregory.clement at free-electrons.com  Wed Aug 12 01:14:25 2015
From: gregory.clement at free-electrons.com (Gregory CLEMENT)
Date: Wed, 12 Aug 2015 10:14:25 +0200
Subject: [PATCH] ARM: l2c: fix support for HW coherent systems in PL310
 cache
In-Reply-To: <20150811172620.GK23307@e104818-lin.cambridge.arm.com>
References: <1439312743-6237-1-git-send-email-gregory.clement@free-electrons.com>
 <20150811172620.GK23307@e104818-lin.cambridge.arm.com>
Message-ID: <55CB0061.2010602@free-electrons.com>

Hi Catalin,

On 11/08/2015 19:26, Catalin Marinas wrote:
> On Tue, Aug 11, 2015 at 07:05:43PM +0200, Gregory CLEMENT wrote:
>> From: Nadav Haklai <nadavh at marvell.com>
>>
>> When a PL310 cache is used in a system that provides hardware
>> coherency, the entire outer cache operations are useless, and can be
>> skipped.  Moreover, on some systems, it is harmful as it causes
>> deadlocks between the Marvell coherency mechanism, the Marvell PCIe
>> controller and the Cortex-A9.
>>
>> This commit extends a previous commit:
>> 98ea2dba65932ffc456b6d7b11b8a0624e2f7b95 which added the io-coherent
>> support for the PL310 cache by also disabling the outer cache flush
>> range operation.
>>
>> In the current kernel implementation, the outer cache flush range
>> operation is triggered by the dma_alloc function.
>> This operation can be take place during runtime and in some
>> circumstances may lead to the PCIe/PL310 deadlock on Armada 375/38x
>> SoCs.
> 
> While this may work around the issue for your specific SoC, I think a
> better fix is in DMA alloc code to avoid flushing caches for coherent
> devices. This would be the __dma_clear_buffer() implementation which
> isn't aware of whether the device is coherent or not.

Indeed, the other use of the outer cache flush range is done pretty
early in the boot and should not be a problem.

What do you think of the following patch?

I am not totally happy with it because I added a variable to a struct
dedicated for the outer cache functions. But using a function at the
l2cc driver level would be too much. At the opposite we could directly
set a boolean from the l2cc driver. From my point of view it would
violate the layer but I might be wrong.


Thanks,

Gregory



 arch/arm/include/asm/outercache.h | 9 +++++++++
 arch/arm/mm/cache-l2x0.c          | 1 +
 arch/arm/mm/dma-mapping.c         | 6 ++++--
 3 files changed, 14 insertions(+), 2 deletions(-)

diff --git a/arch/arm/include/asm/outercache.h b/arch/arm/include/asm/outercache.h
index 563b92fc2f41..7f7bbfcf1d32 100644
--- a/arch/arm/include/asm/outercache.h
+++ b/arch/arm/include/asm/outercache.h
@@ -35,6 +35,7 @@ struct outer_cache_fns {
 	void (*sync)(void);
 #endif
 	void (*resume)(void);
+	bool is_coherent;

 	/* This is an ARM L2C thing */
 	void (*write_sec)(unsigned long, unsigned);
@@ -56,6 +57,14 @@ static inline void outer_inv_range(phys_addr_t start, phys_addr_t end)
 }

 /**
+ * outer_is_coherent - tell if the outer cache is io coherent
+ */
+static inline bool outer_is_coherent(void)
+{
+	return outer_cache.is_coherent;
+}
+
+/**
  * outer_clean_range - clean dirty outer cache lines
  * @start: starting physical address, inclusive
  * @end: end physical address, exclusive
diff --git a/arch/arm/mm/cache-l2x0.c b/arch/arm/mm/cache-l2x0.c
index 71b3d3309024..0071e276adc0 100644
--- a/arch/arm/mm/cache-l2x0.c
+++ b/arch/arm/mm/cache-l2x0.c
@@ -1291,6 +1291,7 @@ static const struct l2c_init_data of_l2c310_coherent_data __initconst = {
 		.flush_all   = l2c210_flush_all,
 		.disable     = l2c310_disable,
 		.resume      = l2c310_resume,
+		.is_coherent = true,
 	},
 };

diff --git a/arch/arm/mm/dma-mapping.c b/arch/arm/mm/dma-mapping.c
index 1ced8a0f7a52..4d87df2c16f9 100644
--- a/arch/arm/mm/dma-mapping.c
+++ b/arch/arm/mm/dma-mapping.c
@@ -241,12 +241,14 @@ static void __dma_clear_buffer(struct page *page, size_t size)
 			page++;
 			size -= PAGE_SIZE;
 		}
-		outer_flush_range(base, end);
+		if (!outer_is_coherent())
+			outer_flush_range(base, end);
 	} else {
 		void *ptr = page_address(page);
 		memset(ptr, 0, size);
 		dmac_flush_range(ptr, ptr + size);
-		outer_flush_range(__pa(ptr), __pa(ptr) + size);
+		if (!outer_is_coherent())
+			outer_flush_range(__pa(ptr), __pa(ptr) + size);
 	}
 }

-- 
Gregory Clement, Free Electrons
Kernel, drivers, real-time and embedded Linux
development, consulting, training and support.
http://free-electrons.com


From horms+renesas at verge.net.au  Wed Aug 12 01:15:13 2015
From: horms+renesas at verge.net.au (Simon Horman)
Date: Wed, 12 Aug 2015 17:15:13 +0900
Subject: [GIT PULL] Renesas ARM Based SoC CPG/MSTP Clock Driver Updates for
 v4.3
Message-ID: <cover.1439365731.git.horms+renesas@verge.net.au>

Hi Olof, Hi Kevin, Hi Arnd,

Please consider these Renesas ARM based SoC CPG/MSTP clock driver updates
for v4.3.

As requested by Olof, this is a repost of patches broken out of a now
defunct pull-request, "Renesas ARM Based SoC CPG MSTP Clock Domain Updates
for v4.3".  The motivation being to have driver changes in a separate
branch to DT changes.

* These patches were Acked by Stephen Boyd in a reply to:
  [PATCH v2 00/14] ARM: shmobile: Add CPG Clock Domains
  https://lkml.org/lkml/2015/6/8/622
* The patch subjects were subsequently updated with other changes in:
  [PATCH v3 00/16] ARM: shmobile: Add CPG/MSTP Clock Domain
  https://lkml.org/lkml/2015/7/1/408
* And further updates were made in the patchset I queued up:
  [PATCH v4 00/16] ARM: shmobile: Add CPG/MSTP Clock Domain
  https://lkml.org/lkml/2015/8/4/389


The following changes since commit d770e558e21961ad6cfdf0ff7df0eb5d7d4f0754:

  Linux 4.2-rc1 (2015-07-05 11:01:52 -0700)

are available in the git repository at:

  git://git.kernel.org/pub/scm/linux/kernel/git/horms/renesas.git tags/renesas-clk-for-v4.3

for you to fetch changes up to f04b486d34ac6bab2aaa3988ee098b2bad3950de:

  clk: shmobile: rz: Add CPG/MSTP Clock Domain support (2015-08-12 10:31:28 +0900)

----------------------------------------------------------------
Renesas ARM Based SoC CPG/MSTP Clock Driver Updates for v4.3

* Add Clock Domain support to the Clock Pulse Generator
  (CPG) Module Stop (MSTP) Clocks driver using the generic PM Domain.

----------------------------------------------------------------
Geert Uytterhoeven (5):
      clk: shmobile: Add CPG/MSTP Clock Domain support
      clk: shmobile: r8a7778: Add CPG/MSTP Clock Domain support
      clk: shmobile: r8a7779: Add CPG/MSTP Clock Domain support
      clk: shmobile: rcar-gen2: Add CPG/MSTP Clock Domain support
      clk: shmobile: rz: Add CPG/MSTP Clock Domain support

 .../bindings/clock/renesas,r8a7778-cpg-clocks.txt  | 29 +++++++-
 .../bindings/clock/renesas,r8a7779-cpg-clocks.txt  | 30 +++++++-
 .../clock/renesas,rcar-gen2-cpg-clocks.txt         | 26 ++++++-
 .../bindings/clock/renesas,rz-cpg-clocks.txt       | 29 +++++++-
 arch/arm/mach-shmobile/Kconfig                     |  2 +
 drivers/clk/shmobile/clk-mstp.c                    | 87 ++++++++++++++++++++++
 drivers/clk/shmobile/clk-r8a7778.c                 |  2 +
 drivers/clk/shmobile/clk-r8a7779.c                 |  2 +
 drivers/clk/shmobile/clk-rcar-gen2.c               |  2 +
 drivers/clk/shmobile/clk-rz.c                      |  3 +
 include/linux/clk/shmobile.h                       | 12 +++
 11 files changed, 213 insertions(+), 11 deletions(-)


From horms+renesas at verge.net.au  Wed Aug 12 01:15:15 2015
From: horms+renesas at verge.net.au (Simon Horman)
Date: Wed, 12 Aug 2015 17:15:15 +0900
Subject: [PATCH 1/5] clk: shmobile: Add CPG/MSTP Clock Domain support
In-Reply-To: <cover.1439365731.git.horms+renesas@verge.net.au>
References: <cover.1439365731.git.horms+renesas@verge.net.au>
Message-ID: <752b5ed5f6998e118626feea7375782c4cf5aad6.1439365731.git.horms+renesas@verge.net.au>

From: Geert Uytterhoeven <geert+renesas at glider.be>

Add Clock Domain support to the Clock Pulse Generator (CPG) Module Stop
(MSTP) Clocks driver using the generic PM Domain.  This allows to
power-manage the module clocks of SoC devices that are part of the
CPG/MSTP Clock Domain using Runtime PM, or for system suspend/resume.

SoC devices that are part of the CPG/MSTP Clock Domain and can be
power-managed through an MSTP clock should be tagged in DT with a
proper "power-domains" property.

The CPG/MSTP Clock Domain code will scan such devices for clocks that
are suitable for power-managing the device, by looking for a clock that
is compatible with "renesas,cpg-mstp-clocks".

Signed-off-by: Geert Uytterhoeven <geert+renesas at glider.be>
Acked-by: Laurent Pinchart <laurent.pinchart at ideasonboard.com>
Acked-by: Stephen Boyd <sboyd at codeaurora.org>
Reviewed-by: Ulf Hansson <ulf.hansson at linaro.org>
Reviewed-by: Kevin Hilman <khilman at linaro.org>
Signed-off-by: Simon Horman <horms+renesas at verge.net.au>
---
 drivers/clk/shmobile/clk-mstp.c | 87 +++++++++++++++++++++++++++++++++++++++++
 include/linux/clk/shmobile.h    | 12 ++++++
 2 files changed, 99 insertions(+)

diff --git a/drivers/clk/shmobile/clk-mstp.c b/drivers/clk/shmobile/clk-mstp.c
index 2d2fe773ac81..b1df7b2f1e97 100644
--- a/drivers/clk/shmobile/clk-mstp.c
+++ b/drivers/clk/shmobile/clk-mstp.c
@@ -2,6 +2,7 @@
  * R-Car MSTP clocks
  *
  * Copyright (C) 2013 Ideas On Board SPRL
+ * Copyright (C) 2015 Glider bvba
  *
  * Contact: Laurent Pinchart <laurent.pinchart at ideasonboard.com>
  *
@@ -10,11 +11,16 @@
  * the Free Software Foundation; version 2 of the License.
  */
 
+#include <linux/clk.h>
 #include <linux/clk-provider.h>
 #include <linux/clkdev.h>
+#include <linux/clk/shmobile.h>
+#include <linux/device.h>
 #include <linux/io.h>
 #include <linux/of.h>
 #include <linux/of_address.h>
+#include <linux/pm_clock.h>
+#include <linux/pm_domain.h>
 #include <linux/spinlock.h>
 
 /*
@@ -236,3 +242,84 @@ static void __init cpg_mstp_clocks_init(struct device_node *np)
 	of_clk_add_provider(np, of_clk_src_onecell_get, &group->data);
 }
 CLK_OF_DECLARE(cpg_mstp_clks, "renesas,cpg-mstp-clocks", cpg_mstp_clocks_init);
+
+
+#ifdef CONFIG_PM_GENERIC_DOMAINS_OF
+int cpg_mstp_attach_dev(struct generic_pm_domain *domain, struct device *dev)
+{
+	struct device_node *np = dev->of_node;
+	struct of_phandle_args clkspec;
+	struct clk *clk;
+	int i = 0;
+	int error;
+
+	while (!of_parse_phandle_with_args(np, "clocks", "#clock-cells", i,
+					   &clkspec)) {
+		if (of_device_is_compatible(clkspec.np,
+					    "renesas,cpg-mstp-clocks"))
+			goto found;
+
+		of_node_put(clkspec.np);
+		i++;
+	}
+
+	return 0;
+
+found:
+	clk = of_clk_get_from_provider(&clkspec);
+	of_node_put(clkspec.np);
+
+	if (IS_ERR(clk))
+		return PTR_ERR(clk);
+
+	error = pm_clk_create(dev);
+	if (error) {
+		dev_err(dev, "pm_clk_create failed %d\n", error);
+		goto fail_put;
+	}
+
+	error = pm_clk_add_clk(dev, clk);
+	if (error) {
+		dev_err(dev, "pm_clk_add_clk %pC failed %d\n", clk, error);
+		goto fail_destroy;
+	}
+
+	return 0;
+
+fail_destroy:
+	pm_clk_destroy(dev);
+fail_put:
+	clk_put(clk);
+	return error;
+}
+
+void cpg_mstp_detach_dev(struct generic_pm_domain *domain, struct device *dev)
+{
+	if (!list_empty(&dev->power.subsys_data->clock_list))
+		pm_clk_destroy(dev);
+}
+
+void __init cpg_mstp_add_clk_domain(struct device_node *np)
+{
+	struct generic_pm_domain *pd;
+	u32 ncells;
+
+	if (of_property_read_u32(np, "#power-domain-cells", &ncells)) {
+		pr_warn("%s lacks #power-domain-cells\n", np->full_name);
+		return;
+	}
+
+	pd = kzalloc(sizeof(*pd), GFP_KERNEL);
+	if (!pd)
+		return;
+
+	pd->name = np->name;
+
+	pd->flags = GENPD_FLAG_PM_CLK;
+	pm_genpd_init(pd, &simple_qos_governor, false);
+	pd->attach_dev = cpg_mstp_attach_dev;
+	pd->detach_dev = cpg_mstp_detach_dev;
+
+	of_genpd_add_provider_simple(np, pd);
+}
+#endif /* !CONFIG_PM_GENERIC_DOMAINS_OF */
diff --git a/include/linux/clk/shmobile.h b/include/linux/clk/shmobile.h
index 63a8159c4e64..cb19cc1865ca 100644
--- a/include/linux/clk/shmobile.h
+++ b/include/linux/clk/shmobile.h
@@ -16,8 +16,20 @@
 
 #include <linux/types.h>
 
+struct device;
+struct device_node;
+struct generic_pm_domain;
+
 void r8a7778_clocks_init(u32 mode);
 void r8a7779_clocks_init(u32 mode);
 void rcar_gen2_clocks_init(u32 mode);
 
+#ifdef CONFIG_PM_GENERIC_DOMAINS_OF
+void cpg_mstp_add_clk_domain(struct device_node *np);
+int cpg_mstp_attach_dev(struct generic_pm_domain *domain, struct device *dev);
+void cpg_mstp_detach_dev(struct generic_pm_domain *domain, struct device *dev);
+#else
+static inline void cpg_mstp_add_clk_domain(struct device_node *np) {}
+#endif
+
 #endif
-- 
2.1.4



From horms+renesas at verge.net.au  Wed Aug 12 01:15:16 2015
From: horms+renesas at verge.net.au (Simon Horman)
Date: Wed, 12 Aug 2015 17:15:16 +0900
Subject: [PATCH 2/5] clk: shmobile: r8a7778: Add CPG/MSTP Clock Domain support
In-Reply-To: <cover.1439365731.git.horms+renesas@verge.net.au>
References: <cover.1439365731.git.horms+renesas@verge.net.au>
Message-ID: <8bc964aa25e56b7445ffebffccd455f959370a16.1439365731.git.horms+renesas@verge.net.au>

From: Geert Uytterhoeven <geert+renesas at glider.be>

Add Clock Domain support to the R-Car M1A Clock Pulse Generator (CPG)
driver using the generic PM Domain.  This allows to power-manage the
module clocks of SoC devices that are part of the CPG/MSTP Clock Domain
using Runtime PM, or for system suspend/resume.

SoC devices that are part of the CPG/MSTP Clock Domain and can be
power-managed through an MSTP clock should be tagged in DT with a proper
"power-domains" property.

Signed-off-by: Geert Uytterhoeven <geert+renesas at glider.be>
Acked-by: Stephen Boyd <sboyd at codeaurora.org>
Reviewed-by: Ulf Hansson <ulf.hansson at linaro.org>
Signed-off-by: Simon Horman <horms+renesas at verge.net.au>
---
 .../bindings/clock/renesas,r8a7778-cpg-clocks.txt  | 29 +++++++++++++++++++---
 arch/arm/mach-shmobile/Kconfig                     |  1 +
 drivers/clk/shmobile/clk-r8a7778.c                 |  2 ++
 3 files changed, 29 insertions(+), 3 deletions(-)

diff --git a/Documentation/devicetree/bindings/clock/renesas,r8a7778-cpg-clocks.txt b/Documentation/devicetree/bindings/clock/renesas,r8a7778-cpg-clocks.txt
index 2f3747fdcf1c..e4cdaf1cb333 100644
--- a/Documentation/devicetree/bindings/clock/renesas,r8a7778-cpg-clocks.txt
+++ b/Documentation/devicetree/bindings/clock/renesas,r8a7778-cpg-clocks.txt
@@ -1,7 +1,9 @@
 * Renesas R8A7778 Clock Pulse Generator (CPG)
 
 The CPG generates core clocks for the R8A7778. It includes two PLLs and
-several fixed ratio dividers
+several fixed ratio dividers.
+The CPG also provides a Clock Domain for SoC devices, in combination with the
+CPG Module Stop (MSTP) Clocks.
 
 Required Properties:
 
@@ -10,10 +12,18 @@ Required Properties:
   - #clock-cells: Must be 1
   - clock-output-names: The names of the clocks. Supported clocks are
     "plla", "pllb", "b", "out", "p", "s", and "s1".
+  - #power-domain-cells: Must be 0
 
+SoC devices that are part of the CPG/MSTP Clock Domain and can be power-managed
+through an MSTP clock should refer to the CPG device node in their
+"power-domains" property, as documented by the generic PM domain bindings in
+Documentation/devicetree/bindings/power/power_domain.txt.
 
-Example
--------
+
+Examples
+--------
+
+  - CPG device node:
 
 	cpg_clocks: cpg_clocks at ffc80000 {
 		compatible = "renesas,r8a7778-cpg-clocks";
@@ -22,4 +32,17 @@ Example
 		clocks = <&extal_clk>;
 		clock-output-names = "plla", "pllb", "b",
 				     "out", "p", "s", "s1";
+		#power-domain-cells = <0>;
+	};
+
+
+  - CPG/MSTP Clock Domain member device node:
+
+	sdhi0: sd at ffe4c000 {
+		compatible = "renesas,sdhi-r8a7778";
+		reg = <0xffe4c000 0x100>;
+		interrupts = <0 87 IRQ_TYPE_LEVEL_HIGH>;
+		clocks = <&mstp3_clks R8A7778_CLK_SDHI0>;
+		power-domains = <&cpg_clocks>;
+		status = "disabled";
 	};
diff --git a/arch/arm/mach-shmobile/Kconfig b/arch/arm/mach-shmobile/Kconfig
index 45006479d461..e14fa5e87475 100644
--- a/arch/arm/mach-shmobile/Kconfig
+++ b/arch/arm/mach-shmobile/Kconfig
@@ -4,6 +4,7 @@ config ARCH_SHMOBILE
 
 config PM_RCAR
 	bool
+	select PM_GENERIC_DOMAINS if PM
 
 config PM_RMOBILE
 	bool
diff --git a/drivers/clk/shmobile/clk-r8a7778.c b/drivers/clk/shmobile/clk-r8a7778.c
index cb33b57274bf..fa45684e220c 100644
--- a/drivers/clk/shmobile/clk-r8a7778.c
+++ b/drivers/clk/shmobile/clk-r8a7778.c
@@ -124,6 +124,8 @@ static void __init r8a7778_cpg_clocks_init(struct device_node *np)
 	}
 
 	of_clk_add_provider(np, of_clk_src_onecell_get, &cpg->data);
+
+	cpg_mstp_add_clk_domain(np);
 }
 
 CLK_OF_DECLARE(r8a7778_cpg_clks, "renesas,r8a7778-cpg-clocks",
-- 
2.1.4



From horms+renesas at verge.net.au  Wed Aug 12 01:15:17 2015
From: horms+renesas at verge.net.au (Simon Horman)
Date: Wed, 12 Aug 2015 17:15:17 +0900
Subject: [PATCH 3/5] clk: shmobile: r8a7779: Add CPG/MSTP Clock Domain support
In-Reply-To: <cover.1439365731.git.horms+renesas@verge.net.au>
References: <cover.1439365731.git.horms+renesas@verge.net.au>
Message-ID: <b31fc90c14d9e584ac19983686cecab3e0764289.1439365731.git.horms+renesas@verge.net.au>

From: Geert Uytterhoeven <geert+renesas at glider.be>

Add Clock Domain support to the R-Car H1 Clock Pulse Generator (CPG)
driver using the generic PM Domain.  This allows to power-manage the
module clocks of SoC devices that are part of the CPG/MSTP Clock Domain
using Runtime PM, or for system suspend/resume.

SoC devices that are part of the CPG/MSTP Clock Domain and can be
power-managed through an MSTP clock should be tagged in DT with a proper
"power-domains" property.

Also update the reg property in the DT binding doc example to match the
actual dtsi, which uses #address-cells and #size-cells == 1, not 2.

Signed-off-by: Geert Uytterhoeven <geert+renesas at glider.be>
Acked-by: Stephen Boyd <sboyd at codeaurora.org>
Reviewed-by: Ulf Hansson <ulf.hansson at linaro.org>
Signed-off-by: Simon Horman <horms+renesas at verge.net.au>
---
 .../bindings/clock/renesas,r8a7779-cpg-clocks.txt  | 30 +++++++++++++++++++---
 drivers/clk/shmobile/clk-r8a7779.c                 |  2 ++
 2 files changed, 28 insertions(+), 4 deletions(-)

diff --git a/Documentation/devicetree/bindings/clock/renesas,r8a7779-cpg-clocks.txt b/Documentation/devicetree/bindings/clock/renesas,r8a7779-cpg-clocks.txt
index ed3c8cb12f4e..8c81547c29f5 100644
--- a/Documentation/devicetree/bindings/clock/renesas,r8a7779-cpg-clocks.txt
+++ b/Documentation/devicetree/bindings/clock/renesas,r8a7779-cpg-clocks.txt
@@ -1,7 +1,9 @@
 * Renesas R8A7779 Clock Pulse Generator (CPG)
 
 The CPG generates core clocks for the R8A7779. It includes one PLL and
-several fixed ratio dividers
+several fixed ratio dividers.
+The CPG also provides a Clock Domain for SoC devices, in combination with the
+CPG Module Stop (MSTP) Clocks.
 
 Required Properties:
 
@@ -12,16 +14,36 @@ Required Properties:
   - #clock-cells: Must be 1
   - clock-output-names: The names of the clocks. Supported clocks are "plla",
     "z", "zs", "s", "s1", "p", "b", "out".
+  - #power-domain-cells: Must be 0
 
+SoC devices that are part of the CPG/MSTP Clock Domain and can be power-managed
+through an MSTP clock should refer to the CPG device node in their
+"power-domains" property, as documented by the generic PM domain bindings in
+Documentation/devicetree/bindings/power/power_domain.txt.
 
-Example
--------
+
+Examples
+--------
+
+  - CPG device node:
 
 	cpg_clocks: cpg_clocks at ffc80000 {
 		compatible = "renesas,r8a7779-cpg-clocks";
-		reg = <0 0xffc80000 0 0x30>;
+		reg = <0xffc80000 0x30>;
 		clocks = <&extal_clk>;
 		#clock-cells = <1>;
 		clock-output-names = "plla", "z", "zs", "s", "s1", "p",
 		                     "b", "out";
+		#power-domain-cells = <0>;
+	};
+
+
+  - CPG/MSTP Clock Domain member device node:
+
+	sata: sata at fc600000 {
+		compatible = "renesas,sata-r8a7779", "renesas,rcar-sata";
+		reg = <0xfc600000 0x2000>;
+		interrupts = <0 100 IRQ_TYPE_LEVEL_HIGH>;
+		clocks = <&mstp1_clks R8A7779_CLK_SATA>;
+		power-domains = <&cpg_clocks>;
 	};
diff --git a/drivers/clk/shmobile/clk-r8a7779.c b/drivers/clk/shmobile/clk-r8a7779.c
index 652ecacb6daf..e42a63a2ad25 100644
--- a/drivers/clk/shmobile/clk-r8a7779.c
+++ b/drivers/clk/shmobile/clk-r8a7779.c
@@ -168,6 +168,8 @@ static void __init r8a7779_cpg_clocks_init(struct device_node *np)
 	}
 
 	of_clk_add_provider(np, of_clk_src_onecell_get, &cpg->data);
+
+	cpg_mstp_add_clk_domain(np);
 }
 CLK_OF_DECLARE(r8a7779_cpg_clks, "renesas,r8a7779-cpg-clocks",
 	       r8a7779_cpg_clocks_init);
-- 
2.1.4



From horms+renesas at verge.net.au  Wed Aug 12 01:15:18 2015
From: horms+renesas at verge.net.au (Simon Horman)
Date: Wed, 12 Aug 2015 17:15:18 +0900
Subject: [PATCH 4/5] clk: shmobile: rcar-gen2: Add CPG/MSTP Clock Domain
 support
In-Reply-To: <cover.1439365731.git.horms+renesas@verge.net.au>
References: <cover.1439365731.git.horms+renesas@verge.net.au>
Message-ID: <63e05d9365dc25ae71bdde436b27c49daedf1977.1439365731.git.horms+renesas@verge.net.au>

From: Geert Uytterhoeven <geert+renesas at glider.be>

Add Clock Domain support to the R-Car Gen2 Clock Pulse Generator (CPG)
driver using the generic PM Domain.  This allows to power-manage the
module clocks of SoC devices that are part of the CPG/MSTP Clock Domain
using Runtime PM, or for system suspend/resume.

SoC devices that are part of the CPG/MSTP Clock Domain and can be
power-managed through an MSTP clock should be tagged in DT with a proper
"power-domains" property.

Signed-off-by: Geert Uytterhoeven <geert+renesas at glider.be>
Acked-by: Stephen Boyd <sboyd at codeaurora.org>
Reviewed-by: Ulf Hansson <ulf.hansson at linaro.org>
Signed-off-by: Simon Horman <horms+renesas at verge.net.au>
---
 .../clock/renesas,rcar-gen2-cpg-clocks.txt         | 26 ++++++++++++++++++++--
 drivers/clk/shmobile/clk-rcar-gen2.c               |  2 ++
 2 files changed, 26 insertions(+), 2 deletions(-)

diff --git a/Documentation/devicetree/bindings/clock/renesas,rcar-gen2-cpg-clocks.txt b/Documentation/devicetree/bindings/clock/renesas,rcar-gen2-cpg-clocks.txt
index 56f111bd3e45..2a9a8edc8f35 100644
--- a/Documentation/devicetree/bindings/clock/renesas,rcar-gen2-cpg-clocks.txt
+++ b/Documentation/devicetree/bindings/clock/renesas,rcar-gen2-cpg-clocks.txt
@@ -2,6 +2,8 @@
 
 The CPG generates core clocks for the R-Car Gen2 SoCs. It includes three PLLs
 and several fixed ratio dividers.
+The CPG also provides a Clock Domain for SoC devices, in combination with the
+CPG Module Stop (MSTP) Clocks.
 
 Required Properties:
 
@@ -20,10 +22,18 @@ Required Properties:
   - clock-output-names: The names of the clocks. Supported clocks are "main",
     "pll0", "pll1", "pll3", "lb", "qspi", "sdh", "sd0", "sd1", "z", "rcan", and
     "adsp"
+  - #power-domain-cells: Must be 0
 
+SoC devices that are part of the CPG/MSTP Clock Domain and can be power-managed
+through an MSTP clock should refer to the CPG device node in their
+"power-domains" property, as documented by the generic PM domain bindings in
+Documentation/devicetree/bindings/power/power_domain.txt.
 
-Example
--------
+
+Examples
+--------
+
+  - CPG device node:
 
 	cpg_clocks: cpg_clocks at e6150000 {
 		compatible = "renesas,r8a7790-cpg-clocks",
@@ -34,4 +44,16 @@ Example
 		clock-output-names = "main", "pll0, "pll1", "pll3",
 				     "lb", "qspi", "sdh", "sd0", "sd1", "z",
 				     "rcan", "adsp";
+		#power-domain-cells = <0>;
+	};
+
+
+  - CPG/MSTP Clock Domain member device node:
+
+	thermal at e61f0000 {
+		compatible = "renesas,thermal-r8a7790", "renesas,rcar-thermal";
+		reg = <0 0xe61f0000 0 0x14>, <0 0xe61f0100 0 0x38>;
+		interrupts = <0 69 IRQ_TYPE_LEVEL_HIGH>;
+		clocks = <&mstp5_clks R8A7790_CLK_THERMAL>;
+		power-domains = <&cpg_clocks>;
 	};
diff --git a/drivers/clk/shmobile/clk-rcar-gen2.c b/drivers/clk/shmobile/clk-rcar-gen2.c
index acfb6d7dbd6b..f2c457f494eb 100644
--- a/drivers/clk/shmobile/clk-rcar-gen2.c
+++ b/drivers/clk/shmobile/clk-rcar-gen2.c
@@ -415,6 +415,8 @@ static void __init rcar_gen2_cpg_clocks_init(struct device_node *np)
 	}
 
 	of_clk_add_provider(np, of_clk_src_onecell_get, &cpg->data);
+
+	cpg_mstp_add_clk_domain(np);
 }
 CLK_OF_DECLARE(rcar_gen2_cpg_clks, "renesas,rcar-gen2-cpg-clocks",
 	       rcar_gen2_cpg_clocks_init);
-- 
2.1.4



From horms+renesas at verge.net.au  Wed Aug 12 01:15:19 2015
From: horms+renesas at verge.net.au (Simon Horman)
Date: Wed, 12 Aug 2015 17:15:19 +0900
Subject: [PATCH 5/5] clk: shmobile: rz: Add CPG/MSTP Clock Domain support
In-Reply-To: <cover.1439365731.git.horms+renesas@verge.net.au>
References: <cover.1439365731.git.horms+renesas@verge.net.au>
Message-ID: <f04b486d34ac6bab2aaa3988ee098b2bad3950de.1439365731.git.horms+renesas@verge.net.au>

From: Geert Uytterhoeven <geert+renesas at glider.be>

Add Clock Domain support to the RZ Clock Pulse Generator (CPG) driver
using the generic PM Domain.  This allows to power-manage the module
clocks of SoC devices that are part of the CPG/MSTP Clock Domain using
Runtime PM, or for system suspend/resume.

SoC devices that are part of the CPG/MSTP Clock Domain and can be
power-managed through an MSTP clock should be tagged in DT with a proper
"power-domains" property.

Signed-off-by: Geert Uytterhoeven <geert+renesas at glider.be>
Acked-by: Stephen Boyd <sboyd at codeaurora.org>
Reviewed-by: Ulf Hansson <ulf.hansson at linaro.org>
Signed-off-by: Simon Horman <horms+renesas at verge.net.au>
---
 .../bindings/clock/renesas,rz-cpg-clocks.txt       | 29 ++++++++++++++++++++--
 arch/arm/mach-shmobile/Kconfig                     |  1 +
 drivers/clk/shmobile/clk-rz.c                      |  3 +++
 3 files changed, 31 insertions(+), 2 deletions(-)

diff --git a/Documentation/devicetree/bindings/clock/renesas,rz-cpg-clocks.txt b/Documentation/devicetree/bindings/clock/renesas,rz-cpg-clocks.txt
index b0f7ddb8cdb1..bb51a33a1fbf 100644
--- a/Documentation/devicetree/bindings/clock/renesas,rz-cpg-clocks.txt
+++ b/Documentation/devicetree/bindings/clock/renesas,rz-cpg-clocks.txt
@@ -2,6 +2,8 @@
 
 The CPG generates core clocks for the RZ SoCs. It includes the PLL, variable
 CPU and GPU clocks, and several fixed ratio dividers.
+The CPG also provides a Clock Domain for SoC devices, in combination with the
+CPG Module Stop (MSTP) Clocks.
 
 Required Properties:
 
@@ -14,10 +16,18 @@ Required Properties:
   - #clock-cells: Must be 1
   - clock-output-names: The names of the clocks. Supported clocks are "pll",
     "i", and "g"
+  - #power-domain-cells: Must be 0
 
+SoC devices that are part of the CPG/MSTP Clock Domain and can be power-managed
+through an MSTP clock should refer to the CPG device node in their
+"power-domains" property, as documented by the generic PM domain bindings in
+Documentation/devicetree/bindings/power/power_domain.txt.
 
-Example
--------
+
+Examples
+--------
+
+  - CPG device node:
 
 	cpg_clocks: cpg_clocks at fcfe0000 {
 		#clock-cells = <1>;
@@ -26,4 +36,19 @@ Example
 		reg = <0xfcfe0000 0x18>;
 		clocks = <&extal_clk>, <&usb_x1_clk>;
 		clock-output-names = "pll", "i", "g";
+		#power-domain-cells = <0>;
+	};
+
+
+  - CPG/MSTP Clock Domain member device node:
+
+	mtu2: timer at fcff0000 {
+		compatible = "renesas,mtu2-r7s72100", "renesas,mtu2";
+		reg = <0xfcff0000 0x400>;
+		interrupts = <0 107 IRQ_TYPE_LEVEL_HIGH>;
+		interrupt-names = "tgi0a";
+		clocks = <&mstp3_clks R7S72100_CLK_MTU2>;
+		clock-names = "fck";
+		power-domains = <&cpg_clocks>;
+		status = "disabled";
 	};
diff --git a/arch/arm/mach-shmobile/Kconfig b/arch/arm/mach-shmobile/Kconfig
index e14fa5e87475..34eac88a9889 100644
--- a/arch/arm/mach-shmobile/Kconfig
+++ b/arch/arm/mach-shmobile/Kconfig
@@ -51,6 +51,7 @@ config ARCH_EMEV2
 
 config ARCH_R7S72100
 	bool "RZ/A1H (R7S72100)"
+	select PM_GENERIC_DOMAINS if PM
 	select SYS_SUPPORTS_SH_MTU2
 
 config ARCH_R8A73A4
diff --git a/drivers/clk/shmobile/clk-rz.c b/drivers/clk/shmobile/clk-rz.c
index 7e68e8630962..9766e3cb595f 100644
--- a/drivers/clk/shmobile/clk-rz.c
+++ b/drivers/clk/shmobile/clk-rz.c
@@ -10,6 +10,7 @@
  */
 
 #include <linux/clk-provider.h>
+#include <linux/clk/shmobile.h>
 #include <linux/init.h>
 #include <linux/kernel.h>
 #include <linux/of.h>
@@ -99,5 +100,7 @@ static void __init rz_cpg_clocks_init(struct device_node *np)
 	}
 
 	of_clk_add_provider(np, of_clk_src_onecell_get, &cpg->data);
+
+	cpg_mstp_add_clk_domain(np);
 }
 CLK_OF_DECLARE(rz_cpg_clks, "renesas,rz-cpg-clocks", rz_cpg_clocks_init);
-- 
2.1.4



From horms+renesas at verge.net.au  Wed Aug 12 01:15:25 2015
From: horms+renesas at verge.net.au (Simon Horman)
Date: Wed, 12 Aug 2015 17:15:25 +0900
Subject: [GIT PULL] Fourth Round of Renesas ARM Based SoC DT Updates for v4.3
Message-ID: <cover.1439366241.git.horms+renesas@verge.net.au>

Hi Olof, Hi Kevin, Hi Arnd,

Please consider these fourth round of Renesas ARM based SoC DT updates for v4.3.

As requested by Olof, this is a repost of patches broken out of a now
defunct pull-request, "Renesas ARM Based SoC CPG MSTP Clock Domain Updates
for v4.3".  The motivation being to have driver changes in a separate
branch to DT changes.


This pull request is based on a merge of:

* "Renesas ARM Based SoC CPG/MSTP Clock Driver Updates for v4.3",
  tagged as renesas-clk-for-v4.3, which I have also sent a pull request for.

  The patches in this pull request depend on driver changes in
  renesas-clk-for-v4.3.

* "Third Round of Renesas ARM Based SoC DT Updates for v4.3",
  tagged as renesas-dt3-for-v4.3, which you have already merged.

  The patches in this pull request update nodes added by patches
  present in renesas-dt3-for-v4.3.


The following changes since commit 3f3f0ea0afe031ca20e48a212f4faa00f9920450:

  Merge branch 'clk-for-v4.3' into dt-for-v4.3 (2015-08-12 11:15:19 +0900)

are available in the git repository at:

  git://git.kernel.org/pub/scm/linux/kernel/git/horms/renesas.git tags/renesas-dt4-for-v4.3

for you to fetch changes up to 60c0745a80be075bbd4e0925e4b740b3e588a445:

  ARM: shmobile: r8a7794 dtsi: Add CPG/MSTP Clock Domain (2015-08-12 11:15:28 +0900)

----------------------------------------------------------------
Fourth Round of Renesas ARM Based SoC DT Updates for v4.3

* Enable Clock Domain support of the Clock Pulse Generator (CPG)
  Module Stop (MSTP) Clocks driver.

----------------------------------------------------------------
Geert Uytterhoeven (7):
      ARM: shmobile: r7s72100 dtsi: Add CPG/MSTP Clock Domain
      ARM: shmobile: r8a7778 dtsi: Add CPG/MSTP Clock Domain
      ARM: shmobile: r8a7779 dtsi: Add CPG/MSTP Clock Domain
      ARM: shmobile: r8a7790 dtsi: Add CPG/MSTP Clock Domain
      ARM: shmobile: r8a7791 dtsi: Add CPG/MSTP Clock Domain
      ARM: shmobile: r8a7793 dtsi: Add CPG/MSTP Clock Domain
      ARM: shmobile: r8a7794 dtsi: Add CPG/MSTP Clock Domain

 arch/arm/boot/dts/r7s72100.dtsi | 19 +++++++++
 arch/arm/boot/dts/r8a7778.dtsi  | 22 +++++++++++
 arch/arm/boot/dts/r8a7779.dtsi  | 23 +++++++++++
 arch/arm/boot/dts/r8a7790.dtsi  | 86 +++++++++++++++++++++++++++++++++++-----
 arch/arm/boot/dts/r8a7791.dtsi  | 88 +++++++++++++++++++++++++++++++++++++----
 arch/arm/boot/dts/r8a7793.dtsi  |  7 ++++
 arch/arm/boot/dts/r8a7794.dtsi  | 29 ++++++++++++++
 7 files changed, 257 insertions(+), 17 deletions(-)


From horms+renesas at verge.net.au  Wed Aug 12 01:15:21 2015
From: horms+renesas at verge.net.au (Simon Horman)
Date: Wed, 12 Aug 2015 17:15:21 +0900
Subject: [PATCH 1/7] ARM: shmobile: r7s72100 dtsi: Add CPG/MSTP Clock Domain
In-Reply-To: <cover.1439366241.git.horms+renesas@verge.net.au>
References: <cover.1439366241.git.horms+renesas@verge.net.au>
Message-ID: <cbe1f83818c6e2c05fca5045fcc4807177988d61.1439366241.git.horms+renesas@verge.net.au>

From: Geert Uytterhoeven <geert+renesas at glider.be>

Add an appropriate "#power-domain-cells" property to the cpg_clocks
device node, to create the CPG/MSTP Clock Domain.

Add "power-domains" properties to all device nodes for devices that are
part of the CPG/MSTP Clock Domain and can be power-managed through an
MSTP clock.  This applies to most on-SoC devices, which have a
one-to-one mapping from SoC device to DT device node.

Signed-off-by: Geert Uytterhoeven <geert+renesas at glider.be>
Reviewed-by: Ulf Hansson <ulf.hansson at linaro.org>
Signed-off-by: Simon Horman <horms+renesas at verge.net.au>
---
 arch/arm/boot/dts/r7s72100.dtsi | 19 +++++++++++++++++++
 1 file changed, 19 insertions(+)

diff --git a/arch/arm/boot/dts/r7s72100.dtsi b/arch/arm/boot/dts/r7s72100.dtsi
index 277e73c110e5..060c32cbd669 100644
--- a/arch/arm/boot/dts/r7s72100.dtsi
+++ b/arch/arm/boot/dts/r7s72100.dtsi
@@ -86,6 +86,7 @@
 			reg = <0xfcfe0000 0x18>;
 			clocks = <&extal_clk>, <&usb_x1_clk>;
 			clock-output-names = "pll", "i", "g";
+			#power-domain-cells = <0>;
 		};
 
 		/* MSTP clocks */
@@ -157,6 +158,7 @@
 			     <0 189 IRQ_TYPE_LEVEL_HIGH>;
 		clocks = <&mstp4_clks R7S72100_CLK_SCIF0>;
 		clock-names = "sci_ick";
+		power-domains = <&cpg_clocks>;
 		status = "disabled";
 	};
 
@@ -169,6 +171,7 @@
 			     <0 193 IRQ_TYPE_LEVEL_HIGH>;
 		clocks = <&mstp4_clks R7S72100_CLK_SCIF1>;
 		clock-names = "sci_ick";
+		power-domains = <&cpg_clocks>;
 		status = "disabled";
 	};
 
@@ -181,6 +184,7 @@
 			     <0 197 IRQ_TYPE_LEVEL_HIGH>;
 		clocks = <&mstp4_clks R7S72100_CLK_SCIF2>;
 		clock-names = "sci_ick";
+		power-domains = <&cpg_clocks>;
 		status = "disabled";
 	};
 
@@ -193,6 +197,7 @@
 			     <0 201 IRQ_TYPE_LEVEL_HIGH>;
 		clocks = <&mstp4_clks R7S72100_CLK_SCIF3>;
 		clock-names = "sci_ick";
+		power-domains = <&cpg_clocks>;
 		status = "disabled";
 	};
 
@@ -205,6 +210,7 @@
 			     <0 205 IRQ_TYPE_LEVEL_HIGH>;
 		clocks = <&mstp4_clks R7S72100_CLK_SCIF4>;
 		clock-names = "sci_ick";
+		power-domains = <&cpg_clocks>;
 		status = "disabled";
 	};
 
@@ -217,6 +223,7 @@
 			     <0 209 IRQ_TYPE_LEVEL_HIGH>;
 		clocks = <&mstp4_clks R7S72100_CLK_SCIF5>;
 		clock-names = "sci_ick";
+		power-domains = <&cpg_clocks>;
 		status = "disabled";
 	};
 
@@ -229,6 +236,7 @@
 			     <0 213 IRQ_TYPE_LEVEL_HIGH>;
 		clocks = <&mstp4_clks R7S72100_CLK_SCIF6>;
 		clock-names = "sci_ick";
+		power-domains = <&cpg_clocks>;
 		status = "disabled";
 	};
 
@@ -241,6 +249,7 @@
 			     <0 217 IRQ_TYPE_LEVEL_HIGH>;
 		clocks = <&mstp4_clks R7S72100_CLK_SCIF7>;
 		clock-names = "sci_ick";
+		power-domains = <&cpg_clocks>;
 		status = "disabled";
 	};
 
@@ -252,6 +261,7 @@
 			     <0 240 IRQ_TYPE_LEVEL_HIGH>;
 		interrupt-names = "error", "rx", "tx";
 		clocks = <&mstp10_clks R7S72100_CLK_SPI0>;
+		power-domains = <&cpg_clocks>;
 		num-cs = <1>;
 		#address-cells = <1>;
 		#size-cells = <0>;
@@ -266,6 +276,7 @@
 			     <0 243 IRQ_TYPE_LEVEL_HIGH>;
 		interrupt-names = "error", "rx", "tx";
 		clocks = <&mstp10_clks R7S72100_CLK_SPI1>;
+		power-domains = <&cpg_clocks>;
 		num-cs = <1>;
 		#address-cells = <1>;
 		#size-cells = <0>;
@@ -280,6 +291,7 @@
 			     <0 246 IRQ_TYPE_LEVEL_HIGH>;
 		interrupt-names = "error", "rx", "tx";
 		clocks = <&mstp10_clks R7S72100_CLK_SPI2>;
+		power-domains = <&cpg_clocks>;
 		num-cs = <1>;
 		#address-cells = <1>;
 		#size-cells = <0>;
@@ -294,6 +306,7 @@
 			     <0 249 IRQ_TYPE_LEVEL_HIGH>;
 		interrupt-names = "error", "rx", "tx";
 		clocks = <&mstp10_clks R7S72100_CLK_SPI3>;
+		power-domains = <&cpg_clocks>;
 		num-cs = <1>;
 		#address-cells = <1>;
 		#size-cells = <0>;
@@ -308,6 +321,7 @@
 			     <0 252 IRQ_TYPE_LEVEL_HIGH>;
 		interrupt-names = "error", "rx", "tx";
 		clocks = <&mstp10_clks R7S72100_CLK_SPI4>;
+		power-domains = <&cpg_clocks>;
 		num-cs = <1>;
 		#address-cells = <1>;
 		#size-cells = <0>;
@@ -338,6 +352,7 @@
 			     <0 164 IRQ_TYPE_LEVEL_HIGH>;
 		clocks = <&mstp9_clks R7S72100_CLK_I2C0>;
 		clock-frequency = <100000>;
+		power-domains = <&cpg_clocks>;
 		status = "disabled";
 	};
 
@@ -356,6 +371,7 @@
 			     <0 172 IRQ_TYPE_LEVEL_HIGH>;
 		clocks = <&mstp9_clks R7S72100_CLK_I2C1>;
 		clock-frequency = <100000>;
+		power-domains = <&cpg_clocks>;
 		status = "disabled";
 	};
 
@@ -374,6 +390,7 @@
 			     <0 180 IRQ_TYPE_LEVEL_HIGH>;
 		clocks = <&mstp9_clks R7S72100_CLK_I2C2>;
 		clock-frequency = <100000>;
+		power-domains = <&cpg_clocks>;
 		status = "disabled";
 	};
 
@@ -392,6 +409,7 @@
 			     <0 188 IRQ_TYPE_LEVEL_HIGH>;
 		clocks = <&mstp9_clks R7S72100_CLK_I2C3>;
 		clock-frequency = <100000>;
+		power-domains = <&cpg_clocks>;
 		status = "disabled";
 	};
 
@@ -402,6 +420,7 @@
 		interrupt-names = "tgi0a";
 		clocks = <&mstp3_clks R7S72100_CLK_MTU2>;
 		clock-names = "fck";
+		power-domains = <&cpg_clocks>;
 		status = "disabled";
 	};
 };
-- 
2.1.4



From horms+renesas at verge.net.au  Wed Aug 12 01:15:22 2015
From: horms+renesas at verge.net.au (Simon Horman)
Date: Wed, 12 Aug 2015 17:15:22 +0900
Subject: [PATCH 2/7] ARM: shmobile: r8a7778 dtsi: Add CPG/MSTP Clock Domain
In-Reply-To: <cover.1439366241.git.horms+renesas@verge.net.au>
References: <cover.1439366241.git.horms+renesas@verge.net.au>
Message-ID: <a670f3667a0ad53eef1f66fde41acca890462ec9.1439366241.git.horms+renesas@verge.net.au>

From: Geert Uytterhoeven <geert+renesas at glider.be>

Add an appropriate "#power-domain-cells" property to the cpg_clocks
device node, to create the CPG/MSTP Clock Domain.

Add "power-domains" properties to all device nodes for devices that are
part of the CPG/MSTP Clock Domain and can be power-managed through an
MSTP clock.  This applies to most on-SoC devices, which have a
one-to-one mapping from SoC device to DT device node.  A notable
exception is the "sound" node, which represents multiple SoC devices,
each having their own MSTP clocks.

Signed-off-by: Geert Uytterhoeven <geert+renesas at glider.be>
Reviewed-by: Ulf Hansson <ulf.hansson at linaro.org>
Signed-off-by: Simon Horman <horms+renesas at verge.net.au>
---
 arch/arm/boot/dts/r8a7778.dtsi | 22 ++++++++++++++++++++++
 1 file changed, 22 insertions(+)

diff --git a/arch/arm/boot/dts/r8a7778.dtsi b/arch/arm/boot/dts/r8a7778.dtsi
index 7ce9f5fd5865..4b1fa9f42ad5 100644
--- a/arch/arm/boot/dts/r8a7778.dtsi
+++ b/arch/arm/boot/dts/r8a7778.dtsi
@@ -53,6 +53,7 @@
 		reg = <0xfde00000 0x400>;
 		interrupts = <0 105 IRQ_TYPE_LEVEL_HIGH>;
 		clocks = <&mstp1_clks R8A7778_CLK_ETHER>;
+		power-domains = <&cpg_clocks>;
 		phy-mode = "rmii";
 		#address-cells = <1>;
 		#size-cells = <0>;
@@ -152,6 +153,7 @@
 		reg = <0xffc70000 0x1000>;
 		interrupts = <0 67 IRQ_TYPE_LEVEL_HIGH>;
 		clocks = <&mstp0_clks R8A7778_CLK_I2C0>;
+		power-domains = <&cpg_clocks>;
 		status = "disabled";
 	};
 
@@ -162,6 +164,7 @@
 		reg = <0xffc71000 0x1000>;
 		interrupts = <0 78 IRQ_TYPE_LEVEL_HIGH>;
 		clocks = <&mstp0_clks R8A7778_CLK_I2C1>;
+		power-domains = <&cpg_clocks>;
 		status = "disabled";
 	};
 
@@ -172,6 +175,7 @@
 		reg = <0xffc72000 0x1000>;
 		interrupts = <0 76 IRQ_TYPE_LEVEL_HIGH>;
 		clocks = <&mstp0_clks R8A7778_CLK_I2C2>;
+		power-domains = <&cpg_clocks>;
 		status = "disabled";
 	};
 
@@ -182,6 +186,7 @@
 		reg = <0xffc73000 0x1000>;
 		interrupts = <0 77 IRQ_TYPE_LEVEL_HIGH>;
 		clocks = <&mstp0_clks R8A7778_CLK_I2C3>;
+		power-domains = <&cpg_clocks>;
 		status = "disabled";
 	};
 
@@ -193,6 +198,7 @@
 			     <0 34 IRQ_TYPE_LEVEL_HIGH>;
 		clocks = <&mstp0_clks R8A7778_CLK_TMU0>;
 		clock-names = "fck";
+		power-domains = <&cpg_clocks>;
 
 		#renesas,channels = <3>;
 
@@ -207,6 +213,7 @@
 			     <0 38 IRQ_TYPE_LEVEL_HIGH>;
 		clocks = <&mstp0_clks R8A7778_CLK_TMU1>;
 		clock-names = "fck";
+		power-domains = <&cpg_clocks>;
 
 		#renesas,channels = <3>;
 
@@ -221,6 +228,7 @@
 			     <0 42 IRQ_TYPE_LEVEL_HIGH>;
 		clocks = <&mstp0_clks R8A7778_CLK_TMU2>;
 		clock-names = "fck";
+		power-domains = <&cpg_clocks>;
 
 		#renesas,channels = <3>;
 
@@ -288,6 +296,7 @@
 		interrupts = <0 70 IRQ_TYPE_LEVEL_HIGH>;
 		clocks = <&mstp0_clks R8A7778_CLK_SCIF0>;
 		clock-names = "sci_ick";
+		power-domains = <&cpg_clocks>;
 		status = "disabled";
 	};
 
@@ -297,6 +306,7 @@
 		interrupts = <0 71 IRQ_TYPE_LEVEL_HIGH>;
 		clocks = <&mstp0_clks R8A7778_CLK_SCIF1>;
 		clock-names = "sci_ick";
+		power-domains = <&cpg_clocks>;
 		status = "disabled";
 	};
 
@@ -306,6 +316,7 @@
 		interrupts = <0 72 IRQ_TYPE_LEVEL_HIGH>;
 		clocks = <&mstp0_clks R8A7778_CLK_SCIF2>;
 		clock-names = "sci_ick";
+		power-domains = <&cpg_clocks>;
 		status = "disabled";
 	};
 
@@ -315,6 +326,7 @@
 		interrupts = <0 73 IRQ_TYPE_LEVEL_HIGH>;
 		clocks = <&mstp0_clks R8A7778_CLK_SCIF3>;
 		clock-names = "sci_ick";
+		power-domains = <&cpg_clocks>;
 		status = "disabled";
 	};
 
@@ -324,6 +336,7 @@
 		interrupts = <0 74 IRQ_TYPE_LEVEL_HIGH>;
 		clocks = <&mstp0_clks R8A7778_CLK_SCIF4>;
 		clock-names = "sci_ick";
+		power-domains = <&cpg_clocks>;
 		status = "disabled";
 	};
 
@@ -333,6 +346,7 @@
 		interrupts = <0 75 IRQ_TYPE_LEVEL_HIGH>;
 		clocks = <&mstp0_clks R8A7778_CLK_SCIF5>;
 		clock-names = "sci_ick";
+		power-domains = <&cpg_clocks>;
 		status = "disabled";
 	};
 
@@ -341,6 +355,7 @@
 		reg = <0xffe4e000 0x100>;
 		interrupts = <0 61 IRQ_TYPE_LEVEL_HIGH>;
 		clocks = <&mstp3_clks R8A7778_CLK_MMC>;
+		power-domains = <&cpg_clocks>;
 		status = "disabled";
 	};
 
@@ -349,6 +364,7 @@
 		reg = <0xffe4c000 0x100>;
 		interrupts = <0 87 IRQ_TYPE_LEVEL_HIGH>;
 		clocks = <&mstp3_clks R8A7778_CLK_SDHI0>;
+		power-domains = <&cpg_clocks>;
 		status = "disabled";
 	};
 
@@ -357,6 +373,7 @@
 		reg = <0xffe4d000 0x100>;
 		interrupts = <0 88 IRQ_TYPE_LEVEL_HIGH>;
 		clocks = <&mstp3_clks R8A7778_CLK_SDHI1>;
+		power-domains = <&cpg_clocks>;
 		status = "disabled";
 	};
 
@@ -365,6 +382,7 @@
 		reg = <0xffe4f000 0x100>;
 		interrupts = <0 86 IRQ_TYPE_LEVEL_HIGH>;
 		clocks = <&mstp3_clks R8A7778_CLK_SDHI2>;
+		power-domains = <&cpg_clocks>;
 		status = "disabled";
 	};
 
@@ -373,6 +391,7 @@
 		reg = <0xfffc7000 0x18>;
 		interrupts = <0 63 IRQ_TYPE_LEVEL_HIGH>;
 		clocks = <&mstp0_clks R8A7778_CLK_HSPI>;
+		power-domains = <&cpg_clocks>;
 		#address-cells = <1>;
 		#size-cells = <0>;
 		status = "disabled";
@@ -383,6 +402,7 @@
 		reg = <0xfffc8000 0x18>;
 		interrupts = <0 84 IRQ_TYPE_LEVEL_HIGH>;
 		clocks = <&mstp0_clks R8A7778_CLK_HSPI>;
+		power-domains = <&cpg_clocks>;
 		#address-cells = <1>;
 		#size-cells = <0>;
 		status = "disabled";
@@ -393,6 +413,7 @@
 		reg = <0xfffc6000 0x18>;
 		interrupts = <0 85 IRQ_TYPE_LEVEL_HIGH>;
 		clocks = <&mstp0_clks R8A7778_CLK_HSPI>;
+		power-domains = <&cpg_clocks>;
 		#address-cells = <1>;
 		#size-cells = <0>;
 		status = "disabled";
@@ -419,6 +440,7 @@
 			clocks = <&extal_clk>;
 			clock-output-names = "plla", "pllb", "b",
 					     "out", "p", "s", "s1";
+			#power-domain-cells = <0>;
 		};
 
 		/* Audio clocks; frequencies are set by boards if applicable. */
-- 
2.1.4



From horms+renesas at verge.net.au  Wed Aug 12 01:15:27 2015
From: horms+renesas at verge.net.au (Simon Horman)
Date: Wed, 12 Aug 2015 17:15:27 +0900
Subject: [PATCH 7/7] ARM: shmobile: r8a7794 dtsi: Add CPG/MSTP Clock Domain
In-Reply-To: <cover.1439366241.git.horms+renesas@verge.net.au>
References: <cover.1439366241.git.horms+renesas@verge.net.au>
Message-ID: <60c0745a80be075bbd4e0925e4b740b3e588a445.1439366241.git.horms+renesas@verge.net.au>

From: Geert Uytterhoeven <geert+renesas at glider.be>

Add an appropriate "#power-domain-cells" property to the cpg_clocks
device node, to create the CPG/MSTP Clock Domain.

Add "power-domains" properties to all device nodes for devices that are
part of the CPG/MSTP Clock Domain and can be power-managed through an
MSTP clock.  This applies to most on-SoC devices, which have a
one-to-one mapping from SoC device to DT device node.

Signed-off-by: Geert Uytterhoeven <geert+renesas at glider.be>
Reviewed-by: Ulf Hansson <ulf.hansson at linaro.org>
Signed-off-by: Simon Horman <horms+renesas at verge.net.au>
---
 arch/arm/boot/dts/r8a7794.dtsi | 29 +++++++++++++++++++++++++++++
 1 file changed, 29 insertions(+)

diff --git a/arch/arm/boot/dts/r8a7794.dtsi b/arch/arm/boot/dts/r8a7794.dtsi
index 43acf185ecc4..97c8e9ace5eb 100644
--- a/arch/arm/boot/dts/r8a7794.dtsi
+++ b/arch/arm/boot/dts/r8a7794.dtsi
@@ -57,6 +57,7 @@
 			     <0 143 IRQ_TYPE_LEVEL_HIGH>;
 		clocks = <&mstp1_clks R8A7794_CLK_CMT0>;
 		clock-names = "fck";
+		power-domains = <&cpg_clocks>;
 
 		renesas,channels-mask = <0x60>;
 
@@ -76,6 +77,7 @@
 			     <0 127 IRQ_TYPE_LEVEL_HIGH>;
 		clocks = <&mstp3_clks R8A7794_CLK_CMT1>;
 		clock-names = "fck";
+		power-domains = <&cpg_clocks>;
 
 		renesas,channels-mask = <0xff>;
 
@@ -106,6 +108,7 @@
 			     <0 16 IRQ_TYPE_LEVEL_HIGH>,
 			     <0 17 IRQ_TYPE_LEVEL_HIGH>;
 		clocks = <&mstp4_clks R8A7794_CLK_IRQC>;
+		power-domains = <&cpg_clocks>;
 	};
 
 	pfc: pin-controller at e6060000 {
@@ -140,6 +143,7 @@
 				"ch12", "ch13", "ch14";
 		clocks = <&mstp2_clks R8A7794_CLK_SYS_DMAC0>;
 		clock-names = "fck";
+		power-domains = <&cpg_clocks>;
 		#dma-cells = <1>;
 		dma-channels = <15>;
 	};
@@ -170,6 +174,7 @@
 				"ch12", "ch13", "ch14";
 		clocks = <&mstp2_clks R8A7794_CLK_SYS_DMAC1>;
 		clock-names = "fck";
+		power-domains = <&cpg_clocks>;
 		#dma-cells = <1>;
 		dma-channels = <15>;
 	};
@@ -182,6 +187,7 @@
 		clock-names = "sci_ick";
 		dmas = <&dmac0 0x21>, <&dmac0 0x22>;
 		dma-names = "tx", "rx";
+		power-domains = <&cpg_clocks>;
 		status = "disabled";
 	};
 
@@ -193,6 +199,7 @@
 		clock-names = "sci_ick";
 		dmas = <&dmac0 0x25>, <&dmac0 0x26>;
 		dma-names = "tx", "rx";
+		power-domains = <&cpg_clocks>;
 		status = "disabled";
 	};
 
@@ -204,6 +211,7 @@
 		clock-names = "sci_ick";
 		dmas = <&dmac0 0x27>, <&dmac0 0x28>;
 		dma-names = "tx", "rx";
+		power-domains = <&cpg_clocks>;
 		status = "disabled";
 	};
 
@@ -215,6 +223,7 @@
 		clock-names = "sci_ick";
 		dmas = <&dmac0 0x1b>, <&dmac0 0x1c>;
 		dma-names = "tx", "rx";
+		power-domains = <&cpg_clocks>;
 		status = "disabled";
 	};
 
@@ -226,6 +235,7 @@
 		clock-names = "sci_ick";
 		dmas = <&dmac0 0x1f>, <&dmac0 0x20>;
 		dma-names = "tx", "rx";
+		power-domains = <&cpg_clocks>;
 		status = "disabled";
 	};
 
@@ -237,6 +247,7 @@
 		clock-names = "sci_ick";
 		dmas = <&dmac0 0x23>, <&dmac0 0x24>;
 		dma-names = "tx", "rx";
+		power-domains = <&cpg_clocks>;
 		status = "disabled";
 	};
 
@@ -248,6 +259,7 @@
 		clock-names = "sci_ick";
 		dmas = <&dmac0 0x3d>, <&dmac0 0x3e>;
 		dma-names = "tx", "rx";
+		power-domains = <&cpg_clocks>;
 		status = "disabled";
 	};
 
@@ -259,6 +271,7 @@
 		clock-names = "sci_ick";
 		dmas = <&dmac0 0x19>, <&dmac0 0x1a>;
 		dma-names = "tx", "rx";
+		power-domains = <&cpg_clocks>;
 		status = "disabled";
 	};
 
@@ -270,6 +283,7 @@
 		clock-names = "sci_ick";
 		dmas = <&dmac0 0x1d>, <&dmac0 0x1e>;
 		dma-names = "tx", "rx";
+		power-domains = <&cpg_clocks>;
 		status = "disabled";
 	};
 
@@ -281,6 +295,7 @@
 		clock-names = "sci_ick";
 		dmas = <&dmac0 0x29>, <&dmac0 0x2a>;
 		dma-names = "tx", "rx";
+		power-domains = <&cpg_clocks>;
 		status = "disabled";
 	};
 
@@ -292,6 +307,7 @@
 		clock-names = "sci_ick";
 		dmas = <&dmac0 0x2d>, <&dmac0 0x2e>;
 		dma-names = "tx", "rx";
+		power-domains = <&cpg_clocks>;
 		status = "disabled";
 	};
 
@@ -303,6 +319,7 @@
 		clock-names = "sci_ick";
 		dmas = <&dmac0 0x2b>, <&dmac0 0x2c>;
 		dma-names = "tx", "rx";
+		power-domains = <&cpg_clocks>;
 		status = "disabled";
 	};
 
@@ -314,6 +331,7 @@
 		clock-names = "sci_ick";
 		dmas = <&dmac0 0x2f>, <&dmac0 0x30>;
 		dma-names = "tx", "rx";
+		power-domains = <&cpg_clocks>;
 		status = "disabled";
 	};
 
@@ -325,6 +343,7 @@
 		clock-names = "sci_ick";
 		dmas = <&dmac0 0xfb>, <&dmac0 0xfc>;
 		dma-names = "tx", "rx";
+		power-domains = <&cpg_clocks>;
 		status = "disabled";
 	};
 
@@ -336,6 +355,7 @@
 		clock-names = "sci_ick";
 		dmas = <&dmac0 0xfd>, <&dmac0 0xfe>;
 		dma-names = "tx", "rx";
+		power-domains = <&cpg_clocks>;
 		status = "disabled";
 	};
 
@@ -347,6 +367,7 @@
 		clock-names = "sci_ick";
 		dmas = <&dmac0 0x39>, <&dmac0 0x3a>;
 		dma-names = "tx", "rx";
+		power-domains = <&cpg_clocks>;
 		status = "disabled";
 	};
 
@@ -358,6 +379,7 @@
 		clock-names = "sci_ick";
 		dmas = <&dmac0 0x4d>, <&dmac0 0x4e>;
 		dma-names = "tx", "rx";
+		power-domains = <&cpg_clocks>;
 		status = "disabled";
 	};
 
@@ -369,6 +391,7 @@
 		clock-names = "sci_ick";
 		dmas = <&dmac0 0x3b>, <&dmac0 0x3c>;
 		dma-names = "tx", "rx";
+		power-domains = <&cpg_clocks>;
 		status = "disabled";
 	};
 
@@ -377,6 +400,7 @@
 		reg = <0 0xee700000 0 0x400>;
 		interrupts = <0 162 IRQ_TYPE_LEVEL_HIGH>;
 		clocks = <&mstp8_clks R8A7794_CLK_ETHER>;
+		power-domains = <&cpg_clocks>;
 		phy-mode = "rmii";
 		#address-cells = <1>;
 		#size-cells = <0>;
@@ -390,6 +414,7 @@
 		clocks = <&mstp3_clks R8A7794_CLK_MMCIF0>;
 		dmas = <&dmac0 0xd1>, <&dmac0 0xd2>;
 		dma-names = "tx", "rx";
+		power-domains = <&cpg_clocks>;
 		reg-io-width = <4>;
 		status = "disabled";
 	};
@@ -399,6 +424,7 @@
 		reg = <0 0xee100000 0 0x200>;
 		interrupts = <0 165 IRQ_TYPE_LEVEL_HIGH>;
 		clocks = <&mstp3_clks R8A7794_CLK_SDHI0>;
+		power-domains = <&cpg_clocks>;
 		status = "disabled";
 	};
 
@@ -407,6 +433,7 @@
 		reg = <0 0xee140000 0 0x100>;
 		interrupts = <0 167 IRQ_TYPE_LEVEL_HIGH>;
 		clocks = <&mstp3_clks R8A7794_CLK_SDHI1>;
+		power-domains = <&cpg_clocks>;
 		status = "disabled";
 	};
 
@@ -415,6 +442,7 @@
 		reg = <0 0xee160000 0 0x100>;
 		interrupts = <0 168 IRQ_TYPE_LEVEL_HIGH>;
 		clocks = <&mstp3_clks R8A7794_CLK_SDHI2>;
+		power-domains = <&cpg_clocks>;
 		status = "disabled";
 	};
 
@@ -441,6 +469,7 @@
 			#clock-cells = <1>;
 			clock-output-names = "main", "pll0", "pll1", "pll3",
 					     "lb", "qspi", "sdh", "sd0", "z";
+			#power-domain-cells = <0>;
 		};
 		/* Variable factor clocks */
 		sd2_clk: sd2_clk at e6150078 {
-- 
2.1.4



From horms+renesas at verge.net.au  Wed Aug 12 01:15:26 2015
From: horms+renesas at verge.net.au (Simon Horman)
Date: Wed, 12 Aug 2015 17:15:26 +0900
Subject: [PATCH 6/7] ARM: shmobile: r8a7793 dtsi: Add CPG/MSTP Clock Domain
In-Reply-To: <cover.1439366241.git.horms+renesas@verge.net.au>
References: <cover.1439366241.git.horms+renesas@verge.net.au>
Message-ID: <4b31bad51f83bcce039e43f1659ffcb4bff454dc.1439366241.git.horms+renesas@verge.net.au>

From: Geert Uytterhoeven <geert+renesas at glider.be>

Add an appropriate "#power-domain-cells" property to the cpg_clocks
device node, to create the CPG/MSTP Clock Domain.

Add "power-domains" properties to all device nodes for devices that are
part of the CPG/MSTP Clock Domain and can be power-managed through an
MSTP clock.  This applies to most on-SoC devices, which have a
one-to-one mapping from SoC device to DT device node.

Signed-off-by: Geert Uytterhoeven <geert+renesas at glider.be>
Reviewed-by: Ulf Hansson <ulf.hansson at linaro.org>
Signed-off-by: Simon Horman <horms+renesas at verge.net.au>
---
 arch/arm/boot/dts/r8a7793.dtsi | 7 +++++++
 1 file changed, 7 insertions(+)

diff --git a/arch/arm/boot/dts/r8a7793.dtsi b/arch/arm/boot/dts/r8a7793.dtsi
index 3355c487d108..c4654047e684 100644
--- a/arch/arm/boot/dts/r8a7793.dtsi
+++ b/arch/arm/boot/dts/r8a7793.dtsi
@@ -68,6 +68,7 @@
 			     <0 143 IRQ_TYPE_LEVEL_HIGH>;
 		clocks = <&mstp1_clks R8A7793_CLK_CMT0>;
 		clock-names = "fck";
+		power-domains = <&cpg_clocks>;
 
 		renesas,channels-mask = <0x60>;
 
@@ -87,6 +88,7 @@
 			     <0 127 IRQ_TYPE_LEVEL_HIGH>;
 		clocks = <&mstp3_clks R8A7793_CLK_CMT1>;
 		clock-names = "fck";
+		power-domains = <&cpg_clocks>;
 
 		renesas,channels-mask = <0xff>;
 
@@ -109,6 +111,7 @@
 			     <0 16 IRQ_TYPE_LEVEL_HIGH>,
 			     <0 17 IRQ_TYPE_LEVEL_HIGH>;
 		clocks = <&mstp4_clks R8A7793_CLK_IRQC>;
+		power-domains = <&cpg_clocks>;
 	};
 
 	scif0: serial at e6e60000 {
@@ -117,6 +120,7 @@
 		interrupts = <0 152 IRQ_TYPE_LEVEL_HIGH>;
 		clocks = <&mstp7_clks R8A7793_CLK_SCIF0>;
 		clock-names = "sci_ick";
+		power-domains = <&cpg_clocks>;
 		status = "disabled";
 	};
 
@@ -126,6 +130,7 @@
 		interrupts = <0 153 IRQ_TYPE_LEVEL_HIGH>;
 		clocks = <&mstp7_clks R8A7793_CLK_SCIF1>;
 		clock-names = "sci_ick";
+		power-domains = <&cpg_clocks>;
 		status = "disabled";
 	};
 
@@ -134,6 +139,7 @@
 		reg = <0 0xee700000 0 0x400>;
 		interrupts = <0 162 IRQ_TYPE_LEVEL_HIGH>;
 		clocks = <&mstp8_clks R8A7793_CLK_ETHER>;
+		power-domains = <&cpg_clocks>;
 		phy-mode = "rmii";
 		#address-cells = <1>;
 		#size-cells = <0>;
@@ -164,6 +170,7 @@
 			clock-output-names = "main", "pll0", "pll1", "pll3",
 					     "lb", "qspi", "sdh", "sd0", "z",
 					     "rcan", "adsp";
+			#power-domain-cells = <0>;
 		};
 
 		/* Variable factor clocks */
-- 
2.1.4



From horms+renesas at verge.net.au  Wed Aug 12 01:15:23 2015
From: horms+renesas at verge.net.au (Simon Horman)
Date: Wed, 12 Aug 2015 17:15:23 +0900
Subject: [PATCH 3/7] ARM: shmobile: r8a7779 dtsi: Add CPG/MSTP Clock Domain
In-Reply-To: <cover.1439366241.git.horms+renesas@verge.net.au>
References: <cover.1439366241.git.horms+renesas@verge.net.au>
Message-ID: <33c3632a3f692d82ee0d080350bcd6d1c4cd151f.1439366241.git.horms+renesas@verge.net.au>

From: Geert Uytterhoeven <geert+renesas at glider.be>

Add an appropriate "#power-domain-cells" property to the cpg_clocks
device node, to create the CPG/MSTP Clock Domain.

Add "power-domains" properties to all device nodes for devices that are
part of the CPG/MSTP Clock Domain and can be power-managed through an
MSTP clock.  This applies to most on-SoC devices, which have a
one-to-one mapping from SoC device to DT device node.

Signed-off-by: Geert Uytterhoeven <geert+renesas at glider.be>
Reviewed-by: Ulf Hansson <ulf.hansson at linaro.org>
Signed-off-by: Simon Horman <horms+renesas at verge.net.au>
---
 arch/arm/boot/dts/r8a7779.dtsi | 23 +++++++++++++++++++++++
 1 file changed, 23 insertions(+)

diff --git a/arch/arm/boot/dts/r8a7779.dtsi b/arch/arm/boot/dts/r8a7779.dtsi
index a2b5430d3257..6afa909865b5 100644
--- a/arch/arm/boot/dts/r8a7779.dtsi
+++ b/arch/arm/boot/dts/r8a7779.dtsi
@@ -173,6 +173,7 @@
 		reg = <0xffc70000 0x1000>;
 		interrupts = <0 79 IRQ_TYPE_LEVEL_HIGH>;
 		clocks = <&mstp0_clks R8A7779_CLK_I2C0>;
+		power-domains = <&cpg_clocks>;
 		status = "disabled";
 	};
 
@@ -183,6 +184,7 @@
 		reg = <0xffc71000 0x1000>;
 		interrupts = <0 82 IRQ_TYPE_LEVEL_HIGH>;
 		clocks = <&mstp0_clks R8A7779_CLK_I2C1>;
+		power-domains = <&cpg_clocks>;
 		status = "disabled";
 	};
 
@@ -193,6 +195,7 @@
 		reg = <0xffc72000 0x1000>;
 		interrupts = <0 80 IRQ_TYPE_LEVEL_HIGH>;
 		clocks = <&mstp0_clks R8A7779_CLK_I2C2>;
+		power-domains = <&cpg_clocks>;
 		status = "disabled";
 	};
 
@@ -203,6 +206,7 @@
 		reg = <0xffc73000 0x1000>;
 		interrupts = <0 81 IRQ_TYPE_LEVEL_HIGH>;
 		clocks = <&mstp0_clks R8A7779_CLK_I2C3>;
+		power-domains = <&cpg_clocks>;
 		status = "disabled";
 	};
 
@@ -212,6 +216,7 @@
 		interrupts = <0 88 IRQ_TYPE_LEVEL_HIGH>;
 		clocks = <&mstp0_clks R8A7779_CLK_SCIF0>;
 		clock-names = "sci_ick";
+		power-domains = <&cpg_clocks>;
 		status = "disabled";
 	};
 
@@ -221,6 +226,7 @@
 		interrupts = <0 89 IRQ_TYPE_LEVEL_HIGH>;
 		clocks = <&mstp0_clks R8A7779_CLK_SCIF1>;
 		clock-names = "sci_ick";
+		power-domains = <&cpg_clocks>;
 		status = "disabled";
 	};
 
@@ -230,6 +236,7 @@
 		interrupts = <0 90 IRQ_TYPE_LEVEL_HIGH>;
 		clocks = <&mstp0_clks R8A7779_CLK_SCIF2>;
 		clock-names = "sci_ick";
+		power-domains = <&cpg_clocks>;
 		status = "disabled";
 	};
 
@@ -239,6 +246,7 @@
 		interrupts = <0 91 IRQ_TYPE_LEVEL_HIGH>;
 		clocks = <&mstp0_clks R8A7779_CLK_SCIF3>;
 		clock-names = "sci_ick";
+		power-domains = <&cpg_clocks>;
 		status = "disabled";
 	};
 
@@ -248,6 +256,7 @@
 		interrupts = <0 92 IRQ_TYPE_LEVEL_HIGH>;
 		clocks = <&mstp0_clks R8A7779_CLK_SCIF4>;
 		clock-names = "sci_ick";
+		power-domains = <&cpg_clocks>;
 		status = "disabled";
 	};
 
@@ -257,6 +266,7 @@
 		interrupts = <0 93 IRQ_TYPE_LEVEL_HIGH>;
 		clocks = <&mstp0_clks R8A7779_CLK_SCIF5>;
 		clock-names = "sci_ick";
+		power-domains = <&cpg_clocks>;
 		status = "disabled";
 	};
 
@@ -278,6 +288,7 @@
 			     <0 34 IRQ_TYPE_LEVEL_HIGH>;
 		clocks = <&mstp0_clks R8A7779_CLK_TMU0>;
 		clock-names = "fck";
+		power-domains = <&cpg_clocks>;
 
 		#renesas,channels = <3>;
 
@@ -292,6 +303,7 @@
 			     <0 38 IRQ_TYPE_LEVEL_HIGH>;
 		clocks = <&mstp0_clks R8A7779_CLK_TMU1>;
 		clock-names = "fck";
+		power-domains = <&cpg_clocks>;
 
 		#renesas,channels = <3>;
 
@@ -306,6 +318,7 @@
 			     <0 42 IRQ_TYPE_LEVEL_HIGH>;
 		clocks = <&mstp0_clks R8A7779_CLK_TMU2>;
 		clock-names = "fck";
+		power-domains = <&cpg_clocks>;
 
 		#renesas,channels = <3>;
 
@@ -317,6 +330,7 @@
 		reg = <0xfc600000 0x2000>;
 		interrupts = <0 100 IRQ_TYPE_LEVEL_HIGH>;
 		clocks = <&mstp1_clks R8A7779_CLK_SATA>;
+		power-domains = <&cpg_clocks>;
 	};
 
 	sdhi0: sd at ffe4c000 {
@@ -324,6 +338,7 @@
 		reg = <0xffe4c000 0x100>;
 		interrupts = <0 104 IRQ_TYPE_LEVEL_HIGH>;
 		clocks = <&mstp3_clks R8A7779_CLK_SDHI0>;
+		power-domains = <&cpg_clocks>;
 		status = "disabled";
 	};
 
@@ -332,6 +347,7 @@
 		reg = <0xffe4d000 0x100>;
 		interrupts = <0 105 IRQ_TYPE_LEVEL_HIGH>;
 		clocks = <&mstp3_clks R8A7779_CLK_SDHI1>;
+		power-domains = <&cpg_clocks>;
 		status = "disabled";
 	};
 
@@ -340,6 +356,7 @@
 		reg = <0xffe4e000 0x100>;
 		interrupts = <0 107 IRQ_TYPE_LEVEL_HIGH>;
 		clocks = <&mstp3_clks R8A7779_CLK_SDHI2>;
+		power-domains = <&cpg_clocks>;
 		status = "disabled";
 	};
 
@@ -348,6 +365,7 @@
 		reg = <0xffe4f000 0x100>;
 		interrupts = <0 106 IRQ_TYPE_LEVEL_HIGH>;
 		clocks = <&mstp3_clks R8A7779_CLK_SDHI3>;
+		power-domains = <&cpg_clocks>;
 		status = "disabled";
 	};
 
@@ -358,6 +376,7 @@
 		#address-cells = <1>;
 		#size-cells = <0>;
 		clocks = <&mstp0_clks R8A7779_CLK_HSPI>;
+		power-domains = <&cpg_clocks>;
 		status = "disabled";
 	};
 
@@ -368,6 +387,7 @@
 		#address-cells = <1>;
 		#size-cells = <0>;
 		clocks = <&mstp0_clks R8A7779_CLK_HSPI>;
+		power-domains = <&cpg_clocks>;
 		status = "disabled";
 	};
 
@@ -378,6 +398,7 @@
 		#address-cells = <1>;
 		#size-cells = <0>;
 		clocks = <&mstp0_clks R8A7779_CLK_HSPI>;
+		power-domains = <&cpg_clocks>;
 		status = "disabled";
 	};
 
@@ -386,6 +407,7 @@
 		reg = <0 0xfff80000 0 0x40000>;
 		interrupts = <0 31 IRQ_TYPE_LEVEL_HIGH>;
 		clocks = <&mstp1_clks R8A7779_CLK_DU>;
+		power-domains = <&cpg_clocks>;
 		status = "disabled";
 
 		ports {
@@ -427,6 +449,7 @@
 			#clock-cells = <1>;
 			clock-output-names = "plla", "z", "zs", "s",
 					     "s1", "p", "b", "out";
+			#power-domain-cells = <0>;
 		};
 
 		/* Fixed factor clocks */
-- 
2.1.4



From horms+renesas at verge.net.au  Wed Aug 12 01:15:24 2015
From: horms+renesas at verge.net.au (Simon Horman)
Date: Wed, 12 Aug 2015 17:15:24 +0900
Subject: [PATCH 4/7] ARM: shmobile: r8a7790 dtsi: Add CPG/MSTP Clock Domain
In-Reply-To: <cover.1439366241.git.horms+renesas@verge.net.au>
References: <cover.1439366241.git.horms+renesas@verge.net.au>
Message-ID: <484adb005886b1db79050afc7074d2356618b0c2.1439366241.git.horms+renesas@verge.net.au>

From: Geert Uytterhoeven <geert+renesas at glider.be>

Add an appropriate "#power-domain-cells" property to the cpg_clocks
device node, to create the CPG/MSTP Clock Domain.

Add "power-domains" properties to all device nodes for devices that are
part of the CPG/MSTP Clock Domain and can be power-managed through an
MSTP clock.  This applies to most on-SoC devices, which have a
one-to-one mapping from SoC device to DT device node.  Notable
exceptions are the "display" and "sound" nodes, which represent multiple
SoC devices, each having their own MSTP clocks.

Signed-off-by: Geert Uytterhoeven <geert+renesas at glider.be>
Reviewed-by: Ulf Hansson <ulf.hansson at linaro.org>
Signed-off-by: Simon Horman <horms+renesas at verge.net.au>
---
 arch/arm/boot/dts/r8a7790.dtsi | 86 +++++++++++++++++++++++++++++++++++++-----
 1 file changed, 77 insertions(+), 9 deletions(-)

diff --git a/arch/arm/boot/dts/r8a7790.dtsi b/arch/arm/boot/dts/r8a7790.dtsi
index 5b2952d5c700..a0b2a79cbfbd 100644
--- a/arch/arm/boot/dts/r8a7790.dtsi
+++ b/arch/arm/boot/dts/r8a7790.dtsi
@@ -134,6 +134,7 @@
 		#interrupt-cells = <2>;
 		interrupt-controller;
 		clocks = <&mstp9_clks R8A7790_CLK_GPIO0>;
+		power-domains = <&cpg_clocks>;
 	};
 
 	gpio1: gpio at e6051000 {
@@ -146,6 +147,7 @@
 		#interrupt-cells = <2>;
 		interrupt-controller;
 		clocks = <&mstp9_clks R8A7790_CLK_GPIO1>;
+		power-domains = <&cpg_clocks>;
 	};
 
 	gpio2: gpio at e6052000 {
@@ -158,6 +160,7 @@
 		#interrupt-cells = <2>;
 		interrupt-controller;
 		clocks = <&mstp9_clks R8A7790_CLK_GPIO2>;
+		power-domains = <&cpg_clocks>;
 	};
 
 	gpio3: gpio at e6053000 {
@@ -170,6 +173,7 @@
 		#interrupt-cells = <2>;
 		interrupt-controller;
 		clocks = <&mstp9_clks R8A7790_CLK_GPIO3>;
+		power-domains = <&cpg_clocks>;
 	};
 
 	gpio4: gpio at e6054000 {
@@ -182,6 +186,7 @@
 		#interrupt-cells = <2>;
 		interrupt-controller;
 		clocks = <&mstp9_clks R8A7790_CLK_GPIO4>;
+		power-domains = <&cpg_clocks>;
 	};
 
 	gpio5: gpio at e6055000 {
@@ -194,6 +199,7 @@
 		#interrupt-cells = <2>;
 		interrupt-controller;
 		clocks = <&mstp9_clks R8A7790_CLK_GPIO5>;
+		power-domains = <&cpg_clocks>;
 	};
 
 	thermal at e61f0000 {
@@ -201,6 +207,7 @@
 		reg = <0 0xe61f0000 0 0x14>, <0 0xe61f0100 0 0x38>;
 		interrupts = <0 69 IRQ_TYPE_LEVEL_HIGH>;
 		clocks = <&mstp5_clks R8A7790_CLK_THERMAL>;
+		power-domains = <&cpg_clocks>;
 	};
 
 	timer {
@@ -218,6 +225,7 @@
 			     <0 143 IRQ_TYPE_LEVEL_HIGH>;
 		clocks = <&mstp1_clks R8A7790_CLK_CMT0>;
 		clock-names = "fck";
+		power-domains = <&cpg_clocks>;
 
 		renesas,channels-mask = <0x60>;
 
@@ -237,6 +245,7 @@
 			     <0 127 IRQ_TYPE_LEVEL_HIGH>;
 		clocks = <&mstp3_clks R8A7790_CLK_CMT1>;
 		clock-names = "fck";
+		power-domains = <&cpg_clocks>;
 
 		renesas,channels-mask = <0xff>;
 
@@ -253,6 +262,7 @@
 			     <0 2 IRQ_TYPE_LEVEL_HIGH>,
 			     <0 3 IRQ_TYPE_LEVEL_HIGH>;
 		clocks = <&mstp4_clks R8A7790_CLK_IRQC>;
+		power-domains = <&cpg_clocks>;
 	};
 
 	dmac0: dma-controller at e6700000 {
@@ -281,6 +291,7 @@
 				"ch12", "ch13", "ch14";
 		clocks = <&mstp2_clks R8A7790_CLK_SYS_DMAC0>;
 		clock-names = "fck";
+		power-domains = <&cpg_clocks>;
 		#dma-cells = <1>;
 		dma-channels = <15>;
 	};
@@ -311,6 +322,7 @@
 				"ch12", "ch13", "ch14";
 		clocks = <&mstp2_clks R8A7790_CLK_SYS_DMAC1>;
 		clock-names = "fck";
+		power-domains = <&cpg_clocks>;
 		#dma-cells = <1>;
 		dma-channels = <15>;
 	};
@@ -339,6 +351,7 @@
 				"ch12";
 		clocks = <&mstp5_clks R8A7790_CLK_AUDIO_DMAC0>;
 		clock-names = "fck";
+		power-domains = <&cpg_clocks>;
 		#dma-cells = <1>;
 		dma-channels = <13>;
 	};
@@ -367,6 +380,7 @@
 				"ch12";
 		clocks = <&mstp5_clks R8A7790_CLK_AUDIO_DMAC1>;
 		clock-names = "fck";
+		power-domains = <&cpg_clocks>;
 		#dma-cells = <1>;
 		dma-channels = <13>;
 	};
@@ -378,6 +392,7 @@
 			      0 109 IRQ_TYPE_LEVEL_HIGH>;
 		interrupt-names = "ch0", "ch1";
 		clocks = <&mstp3_clks R8A7790_CLK_USBDMAC0>;
+		power-domains = <&cpg_clocks>;
 		#dma-cells = <1>;
 		dma-channels = <2>;
 	};
@@ -389,6 +404,7 @@
 			      0 110 IRQ_TYPE_LEVEL_HIGH>;
 		interrupt-names = "ch0", "ch1";
 		clocks = <&mstp3_clks R8A7790_CLK_USBDMAC1>;
+		power-domains = <&cpg_clocks>;
 		#dma-cells = <1>;
 		dma-channels = <2>;
 	};
@@ -400,6 +416,7 @@
 		reg = <0 0xe6508000 0 0x40>;
 		interrupts = <0 287 IRQ_TYPE_LEVEL_HIGH>;
 		clocks = <&mstp9_clks R8A7790_CLK_I2C0>;
+		power-domains = <&cpg_clocks>;
 		status = "disabled";
 	};
 
@@ -410,6 +427,7 @@
 		reg = <0 0xe6518000 0 0x40>;
 		interrupts = <0 288 IRQ_TYPE_LEVEL_HIGH>;
 		clocks = <&mstp9_clks R8A7790_CLK_I2C1>;
+		power-domains = <&cpg_clocks>;
 		status = "disabled";
 	};
 
@@ -420,6 +438,7 @@
 		reg = <0 0xe6530000 0 0x40>;
 		interrupts = <0 286 IRQ_TYPE_LEVEL_HIGH>;
 		clocks = <&mstp9_clks R8A7790_CLK_I2C2>;
+		power-domains = <&cpg_clocks>;
 		status = "disabled";
 	};
 
@@ -430,6 +449,7 @@
 		reg = <0 0xe6540000 0 0x40>;
 		interrupts = <0 290 IRQ_TYPE_LEVEL_HIGH>;
 		clocks = <&mstp9_clks R8A7790_CLK_I2C3>;
+		power-domains = <&cpg_clocks>;
 		status = "disabled";
 	};
 
@@ -442,6 +462,7 @@
 		clocks = <&mstp3_clks R8A7790_CLK_IIC0>;
 		dmas = <&dmac0 0x61>, <&dmac0 0x62>;
 		dma-names = "tx", "rx";
+		power-domains = <&cpg_clocks>;
 		status = "disabled";
 	};
 
@@ -454,6 +475,7 @@
 		clocks = <&mstp3_clks R8A7790_CLK_IIC1>;
 		dmas = <&dmac0 0x65>, <&dmac0 0x66>;
 		dma-names = "tx", "rx";
+		power-domains = <&cpg_clocks>;
 		status = "disabled";
 	};
 
@@ -466,6 +488,7 @@
 		clocks = <&mstp3_clks R8A7790_CLK_IIC2>;
 		dmas = <&dmac0 0x69>, <&dmac0 0x6a>;
 		dma-names = "tx", "rx";
+		power-domains = <&cpg_clocks>;
 		status = "disabled";
 	};
 
@@ -478,6 +501,7 @@
 		clocks = <&mstp9_clks R8A7790_CLK_IICDVFS>;
 		dmas = <&dmac0 0x77>, <&dmac0 0x78>;
 		dma-names = "tx", "rx";
+		power-domains = <&cpg_clocks>;
 		status = "disabled";
 	};
 
@@ -488,6 +512,7 @@
 		clocks = <&mstp3_clks R8A7790_CLK_MMCIF0>;
 		dmas = <&dmac0 0xd1>, <&dmac0 0xd2>;
 		dma-names = "tx", "rx";
+		power-domains = <&cpg_clocks>;
 		reg-io-width = <4>;
 		status = "disabled";
 		max-frequency = <97500000>;
@@ -500,6 +525,7 @@
 		clocks = <&mstp3_clks R8A7790_CLK_MMCIF1>;
 		dmas = <&dmac0 0xe1>, <&dmac0 0xe2>;
 		dma-names = "tx", "rx";
+		power-domains = <&cpg_clocks>;
 		reg-io-width = <4>;
 		status = "disabled";
 		max-frequency = <97500000>;
@@ -517,6 +543,7 @@
 		clocks = <&mstp3_clks R8A7790_CLK_SDHI0>;
 		dmas = <&dmac1 0xcd>, <&dmac1 0xce>;
 		dma-names = "tx", "rx";
+		power-domains = <&cpg_clocks>;
 		status = "disabled";
 	};
 
@@ -527,6 +554,7 @@
 		clocks = <&mstp3_clks R8A7790_CLK_SDHI1>;
 		dmas = <&dmac1 0xc9>, <&dmac1 0xca>;
 		dma-names = "tx", "rx";
+		power-domains = <&cpg_clocks>;
 		status = "disabled";
 	};
 
@@ -537,6 +565,7 @@
 		clocks = <&mstp3_clks R8A7790_CLK_SDHI2>;
 		dmas = <&dmac1 0xc1>, <&dmac1 0xc2>;
 		dma-names = "tx", "rx";
+		power-domains = <&cpg_clocks>;
 		status = "disabled";
 	};
 
@@ -547,6 +576,7 @@
 		clocks = <&mstp3_clks R8A7790_CLK_SDHI3>;
 		dmas = <&dmac1 0xd3>, <&dmac1 0xd4>;
 		dma-names = "tx", "rx";
+		power-domains = <&cpg_clocks>;
 		status = "disabled";
 	};
 
@@ -558,6 +588,7 @@
 		clock-names = "sci_ick";
 		dmas = <&dmac0 0x21>, <&dmac0 0x22>;
 		dma-names = "tx", "rx";
+		power-domains = <&cpg_clocks>;
 		status = "disabled";
 	};
 
@@ -569,6 +600,7 @@
 		clock-names = "sci_ick";
 		dmas = <&dmac0 0x25>, <&dmac0 0x26>;
 		dma-names = "tx", "rx";
+		power-domains = <&cpg_clocks>;
 		status = "disabled";
 	};
 
@@ -580,6 +612,7 @@
 		clock-names = "sci_ick";
 		dmas = <&dmac0 0x27>, <&dmac0 0x28>;
 		dma-names = "tx", "rx";
+		power-domains = <&cpg_clocks>;
 		status = "disabled";
 	};
 
@@ -591,6 +624,7 @@
 		clock-names = "sci_ick";
 		dmas = <&dmac0 0x3d>, <&dmac0 0x3e>;
 		dma-names = "tx", "rx";
+		power-domains = <&cpg_clocks>;
 		status = "disabled";
 	};
 
@@ -602,6 +636,7 @@
 		clock-names = "sci_ick";
 		dmas = <&dmac0 0x19>, <&dmac0 0x1a>;
 		dma-names = "tx", "rx";
+		power-domains = <&cpg_clocks>;
 		status = "disabled";
 	};
 
@@ -613,6 +648,7 @@
 		clock-names = "sci_ick";
 		dmas = <&dmac0 0x1d>, <&dmac0 0x1e>;
 		dma-names = "tx", "rx";
+		power-domains = <&cpg_clocks>;
 		status = "disabled";
 	};
 
@@ -624,6 +660,7 @@
 		clock-names = "sci_ick";
 		dmas = <&dmac0 0x29>, <&dmac0 0x2a>;
 		dma-names = "tx", "rx";
+		power-domains = <&cpg_clocks>;
 		status = "disabled";
 	};
 
@@ -635,6 +672,7 @@
 		clock-names = "sci_ick";
 		dmas = <&dmac0 0x2d>, <&dmac0 0x2e>;
 		dma-names = "tx", "rx";
+		power-domains = <&cpg_clocks>;
 		status = "disabled";
 	};
 
@@ -646,6 +684,7 @@
 		clock-names = "sci_ick";
 		dmas = <&dmac0 0x39>, <&dmac0 0x3a>;
 		dma-names = "tx", "rx";
+		power-domains = <&cpg_clocks>;
 		status = "disabled";
 	};
 
@@ -657,6 +696,7 @@
 		clock-names = "sci_ick";
 		dmas = <&dmac0 0x4d>, <&dmac0 0x4e>;
 		dma-names = "tx", "rx";
+		power-domains = <&cpg_clocks>;
 		status = "disabled";
 	};
 
@@ -665,6 +705,7 @@
 		reg = <0 0xee700000 0 0x400>;
 		interrupts = <0 162 IRQ_TYPE_LEVEL_HIGH>;
 		clocks = <&mstp8_clks R8A7790_CLK_ETHER>;
+		power-domains = <&cpg_clocks>;
 		phy-mode = "rmii";
 		#address-cells = <1>;
 		#size-cells = <0>;
@@ -676,6 +717,7 @@
 		reg = <0 0xe6800000 0 0x800>, <0 0xee0e8000 0 0x4000>;
 		interrupts = <0 163 IRQ_TYPE_LEVEL_HIGH>;
 		clocks = <&mstp8_clks R8A7790_CLK_ETHERAVB>;
+		power-domains = <&cpg_clocks>;
 		#address-cells = <1>;
 		#size-cells = <0>;
 		status = "disabled";
@@ -686,6 +728,7 @@
 		reg = <0 0xee300000 0 0x2000>;
 		interrupts = <0 105 IRQ_TYPE_LEVEL_HIGH>;
 		clocks = <&mstp8_clks R8A7790_CLK_SATA0>;
+		power-domains = <&cpg_clocks>;
 		status = "disabled";
 	};
 
@@ -694,6 +737,7 @@
 		reg = <0 0xee500000 0 0x2000>;
 		interrupts = <0 106 IRQ_TYPE_LEVEL_HIGH>;
 		clocks = <&mstp8_clks R8A7790_CLK_SATA1>;
+		power-domains = <&cpg_clocks>;
 		status = "disabled";
 	};
 
@@ -702,12 +746,13 @@
 		reg = <0 0xe6590000 0 0x100>;
 		interrupts = <0 107 IRQ_TYPE_LEVEL_HIGH>;
 		clocks = <&mstp7_clks R8A7790_CLK_HSUSB>;
-		renesas,buswait = <4>;
-		phys = <&usb0 1>;
-		phy-names = "usb";
 		dmas = <&usb_dmac0 0>, <&usb_dmac0 1>,
 		       <&usb_dmac1 0>, <&usb_dmac1 1>;
 		dma-names = "ch0", "ch1", "ch2", "ch3";
+		power-domains = <&cpg_clocks>;
+		renesas,buswait = <4>;
+		phys = <&usb0 1>;
+		phy-names = "usb";
 		status = "disabled";
 	};
 
@@ -718,6 +763,7 @@
 		#size-cells = <0>;
 		clocks = <&mstp7_clks R8A7790_CLK_HSUSB>;
 		clock-names = "usbhs";
+		power-domains = <&cpg_clocks>;
 		status = "disabled";
 
 		usb0: usb-channel at 0 {
@@ -732,33 +778,37 @@
 
 	vin0: video at e6ef0000 {
 		compatible = "renesas,vin-r8a7790";
-		clocks = <&mstp8_clks R8A7790_CLK_VIN0>;
 		reg = <0 0xe6ef0000 0 0x1000>;
 		interrupts = <0 188 IRQ_TYPE_LEVEL_HIGH>;
+		clocks = <&mstp8_clks R8A7790_CLK_VIN0>;
+		power-domains = <&cpg_clocks>;
 		status = "disabled";
 	};
 
 	vin1: video at e6ef1000 {
 		compatible = "renesas,vin-r8a7790";
-		clocks = <&mstp8_clks R8A7790_CLK_VIN1>;
 		reg = <0 0xe6ef1000 0 0x1000>;
 		interrupts = <0 189 IRQ_TYPE_LEVEL_HIGH>;
+		clocks = <&mstp8_clks R8A7790_CLK_VIN1>;
+		power-domains = <&cpg_clocks>;
 		status = "disabled";
 	};
 
 	vin2: video at e6ef2000 {
 		compatible = "renesas,vin-r8a7790";
-		clocks = <&mstp8_clks R8A7790_CLK_VIN2>;
 		reg = <0 0xe6ef2000 0 0x1000>;
 		interrupts = <0 190 IRQ_TYPE_LEVEL_HIGH>;
+		clocks = <&mstp8_clks R8A7790_CLK_VIN2>;
+		power-domains = <&cpg_clocks>;
 		status = "disabled";
 	};
 
 	vin3: video at e6ef3000 {
 		compatible = "renesas,vin-r8a7790";
-		clocks = <&mstp8_clks R8A7790_CLK_VIN3>;
 		reg = <0 0xe6ef3000 0 0x1000>;
 		interrupts = <0 191 IRQ_TYPE_LEVEL_HIGH>;
+		clocks = <&mstp8_clks R8A7790_CLK_VIN3>;
+		power-domains = <&cpg_clocks>;
 		status = "disabled";
 	};
 
@@ -767,6 +817,7 @@
 		reg = <0 0xfe920000 0 0x8000>;
 		interrupts = <0 266 IRQ_TYPE_LEVEL_HIGH>;
 		clocks = <&mstp1_clks R8A7790_CLK_VSP1_R>;
+		power-domains = <&cpg_clocks>;
 
 		renesas,has-sru;
 		renesas,#rpf = <5>;
@@ -779,6 +830,7 @@
 		reg = <0 0xfe928000 0 0x8000>;
 		interrupts = <0 267 IRQ_TYPE_LEVEL_HIGH>;
 		clocks = <&mstp1_clks R8A7790_CLK_VSP1_S>;
+		power-domains = <&cpg_clocks>;
 
 		renesas,has-lut;
 		renesas,has-sru;
@@ -792,6 +844,7 @@
 		reg = <0 0xfe930000 0 0x8000>;
 		interrupts = <0 246 IRQ_TYPE_LEVEL_HIGH>;
 		clocks = <&mstp1_clks R8A7790_CLK_VSP1_DU0>;
+		power-domains = <&cpg_clocks>;
 
 		renesas,has-lif;
 		renesas,has-lut;
@@ -805,6 +858,7 @@
 		reg = <0 0xfe938000 0 0x8000>;
 		interrupts = <0 247 IRQ_TYPE_LEVEL_HIGH>;
 		clocks = <&mstp1_clks R8A7790_CLK_VSP1_DU1>;
+		power-domains = <&cpg_clocks>;
 
 		renesas,has-lif;
 		renesas,has-lut;
@@ -859,6 +913,7 @@
 		clocks = <&mstp9_clks R8A7790_CLK_RCAN0>,
 			 <&cpg_clocks R8A7790_CLK_RCAN>, <&can_clk>;
 		clock-names = "clkp1", "clkp2", "can_clk";
+		power-domains = <&cpg_clocks>;
 		status = "disabled";
 	};
 
@@ -869,6 +924,7 @@
 		clocks = <&mstp9_clks R8A7790_CLK_RCAN1>,
 			 <&cpg_clocks R8A7790_CLK_RCAN>, <&can_clk>;
 		clock-names = "clkp1", "clkp2", "can_clk";
+		power-domains = <&cpg_clocks>;
 		status = "disabled";
 	};
 
@@ -877,6 +933,7 @@
 		reg = <0 0xfe980000 0 0x10300>;
 		interrupts = <0 272 IRQ_TYPE_LEVEL_HIGH>;
 		clocks = <&mstp1_clks R8A7790_CLK_JPU>;
+		power-domains = <&cpg_clocks>;
 	};
 
 	clocks {
@@ -953,6 +1010,7 @@
 			clock-output-names = "main", "pll0", "pll1", "pll3",
 					     "lb", "qspi", "sdh", "sd0", "sd1",
 					     "z", "rcan", "adsp";
+			#power-domain-cells = <0>;
 		};
 
 		/* Variable factor clocks */
@@ -1343,6 +1401,7 @@
 		clocks = <&mstp9_clks R8A7790_CLK_QSPI_MOD>;
 		dmas = <&dmac0 0x17>, <&dmac0 0x18>;
 		dma-names = "tx", "rx";
+		power-domains = <&cpg_clocks>;
 		num-cs = <1>;
 		#address-cells = <1>;
 		#size-cells = <0>;
@@ -1356,6 +1415,7 @@
 		clocks = <&mstp0_clks R8A7790_CLK_MSIOF0>;
 		dmas = <&dmac0 0x51>, <&dmac0 0x52>;
 		dma-names = "tx", "rx";
+		power-domains = <&cpg_clocks>;
 		#address-cells = <1>;
 		#size-cells = <0>;
 		status = "disabled";
@@ -1368,6 +1428,7 @@
 		clocks = <&mstp2_clks R8A7790_CLK_MSIOF1>;
 		dmas = <&dmac0 0x55>, <&dmac0 0x56>;
 		dma-names = "tx", "rx";
+		power-domains = <&cpg_clocks>;
 		#address-cells = <1>;
 		#size-cells = <0>;
 		status = "disabled";
@@ -1380,6 +1441,7 @@
 		clocks = <&mstp2_clks R8A7790_CLK_MSIOF2>;
 		dmas = <&dmac0 0x41>, <&dmac0 0x42>;
 		dma-names = "tx", "rx";
+		power-domains = <&cpg_clocks>;
 		#address-cells = <1>;
 		#size-cells = <0>;
 		status = "disabled";
@@ -1392,6 +1454,7 @@
 		clocks = <&mstp2_clks R8A7790_CLK_MSIOF3>;
 		dmas = <&dmac0 0x45>, <&dmac0 0x46>;
 		dma-names = "tx", "rx";
+		power-domains = <&cpg_clocks>;
 		#address-cells = <1>;
 		#size-cells = <0>;
 		status = "disabled";
@@ -1402,6 +1465,7 @@
 		reg = <0 0xee000000 0 0xc00>;
 		interrupts = <0 101 IRQ_TYPE_LEVEL_HIGH>;
 		clocks = <&mstp3_clks R8A7790_CLK_SSUSB>;
+		power-domains = <&cpg_clocks>;
 		phys = <&usb2 1>;
 		phy-names = "usb";
 		status = "disabled";
@@ -1410,10 +1474,11 @@
 	pci0: pci at ee090000 {
 		compatible = "renesas,pci-r8a7790";
 		device_type = "pci";
-		clocks = <&mstp7_clks R8A7790_CLK_EHCI>;
 		reg = <0 0xee090000 0 0xc00>,
 		      <0 0xee080000 0 0x1100>;
 		interrupts = <0 108 IRQ_TYPE_LEVEL_HIGH>;
+		clocks = <&mstp7_clks R8A7790_CLK_EHCI>;
+		power-domains = <&cpg_clocks>;
 		status = "disabled";
 
 		bus-range = <0 0>;
@@ -1444,10 +1509,11 @@
 	pci1: pci at ee0b0000 {
 		compatible = "renesas,pci-r8a7790";
 		device_type = "pci";
-		clocks = <&mstp7_clks R8A7790_CLK_EHCI>;
 		reg = <0 0xee0b0000 0 0xc00>,
 		      <0 0xee0a0000 0 0x1100>;
 		interrupts = <0 112 IRQ_TYPE_LEVEL_HIGH>;
+		clocks = <&mstp7_clks R8A7790_CLK_EHCI>;
+		power-domains = <&cpg_clocks>;
 		status = "disabled";
 
 		bus-range = <1 1>;
@@ -1465,6 +1531,7 @@
 		compatible = "renesas,pci-r8a7790";
 		device_type = "pci";
 		clocks = <&mstp7_clks R8A7790_CLK_EHCI>;
+		power-domains = <&cpg_clocks>;
 		reg = <0 0xee0d0000 0 0xc00>,
 		      <0 0xee0c0000 0 0x1100>;
 		interrupts = <0 113 IRQ_TYPE_LEVEL_HIGH>;
@@ -1517,6 +1584,7 @@
 		interrupt-map = <0 0 0 0 &gic 0 116 IRQ_TYPE_LEVEL_HIGH>;
 		clocks = <&mstp3_clks R8A7790_CLK_PCIEC>, <&pcie_bus_clk>;
 		clock-names = "pcie", "pcie_bus";
+		power-domains = <&cpg_clocks>;
 		status = "disabled";
 	};
 
-- 
2.1.4



From horms+renesas at verge.net.au  Wed Aug 12 01:15:25 2015
From: horms+renesas at verge.net.au (Simon Horman)
Date: Wed, 12 Aug 2015 17:15:25 +0900
Subject: [PATCH 5/7] ARM: shmobile: r8a7791 dtsi: Add CPG/MSTP Clock Domain
In-Reply-To: <cover.1439366241.git.horms+renesas@verge.net.au>
References: <cover.1439366241.git.horms+renesas@verge.net.au>
Message-ID: <797a0626e08ca4af539cd4888ebbc8c5aacc993d.1439366241.git.horms+renesas@verge.net.au>

From: Geert Uytterhoeven <geert+renesas at glider.be>

Add an appropriate "#power-domain-cells" property to the cpg_clocks
device node, to create the CPG/MSTP Clock Domain.

Add "power-domains" properties to all device nodes for devices that are
part of the CPG/MSTP Clock Domain and can be power-managed through an
MSTP clock.  This applies to most on-SoC devices, which have a
one-to-one mapping from SoC device to DT device node.  Notable
exceptions are the "display" and "sound" nodes, which represent multiple
SoC devices, each having their own MSTP clocks.

Signed-off-by: Geert Uytterhoeven <geert+renesas at glider.be>
Reviewed-by: Ulf Hansson <ulf.hansson at linaro.org>
Signed-off-by: Simon Horman <horms+renesas at verge.net.au>
---
 arch/arm/boot/dts/r8a7791.dtsi | 88 ++++++++++++++++++++++++++++++++++++++----
 1 file changed, 80 insertions(+), 8 deletions(-)

diff --git a/arch/arm/boot/dts/r8a7791.dtsi b/arch/arm/boot/dts/r8a7791.dtsi
index 1cb6c2d07933..831525dd39a6 100644
--- a/arch/arm/boot/dts/r8a7791.dtsi
+++ b/arch/arm/boot/dts/r8a7791.dtsi
@@ -91,6 +91,7 @@
 		#interrupt-cells = <2>;
 		interrupt-controller;
 		clocks = <&mstp9_clks R8A7791_CLK_GPIO0>;
+		power-domains = <&cpg_clocks>;
 	};
 
 	gpio1: gpio at e6051000 {
@@ -103,6 +104,7 @@
 		#interrupt-cells = <2>;
 		interrupt-controller;
 		clocks = <&mstp9_clks R8A7791_CLK_GPIO1>;
+		power-domains = <&cpg_clocks>;
 	};
 
 	gpio2: gpio at e6052000 {
@@ -115,6 +117,7 @@
 		#interrupt-cells = <2>;
 		interrupt-controller;
 		clocks = <&mstp9_clks R8A7791_CLK_GPIO2>;
+		power-domains = <&cpg_clocks>;
 	};
 
 	gpio3: gpio at e6053000 {
@@ -127,6 +130,7 @@
 		#interrupt-cells = <2>;
 		interrupt-controller;
 		clocks = <&mstp9_clks R8A7791_CLK_GPIO3>;
+		power-domains = <&cpg_clocks>;
 	};
 
 	gpio4: gpio at e6054000 {
@@ -139,6 +143,7 @@
 		#interrupt-cells = <2>;
 		interrupt-controller;
 		clocks = <&mstp9_clks R8A7791_CLK_GPIO4>;
+		power-domains = <&cpg_clocks>;
 	};
 
 	gpio5: gpio at e6055000 {
@@ -151,6 +156,7 @@
 		#interrupt-cells = <2>;
 		interrupt-controller;
 		clocks = <&mstp9_clks R8A7791_CLK_GPIO5>;
+		power-domains = <&cpg_clocks>;
 	};
 
 	gpio6: gpio at e6055400 {
@@ -163,6 +169,7 @@
 		#interrupt-cells = <2>;
 		interrupt-controller;
 		clocks = <&mstp9_clks R8A7791_CLK_GPIO6>;
+		power-domains = <&cpg_clocks>;
 	};
 
 	gpio7: gpio at e6055800 {
@@ -175,6 +182,7 @@
 		#interrupt-cells = <2>;
 		interrupt-controller;
 		clocks = <&mstp9_clks R8A7791_CLK_GPIO7>;
+		power-domains = <&cpg_clocks>;
 	};
 
 	thermal at e61f0000 {
@@ -182,6 +190,7 @@
 		reg = <0 0xe61f0000 0 0x14>, <0 0xe61f0100 0 0x38>;
 		interrupts = <0 69 IRQ_TYPE_LEVEL_HIGH>;
 		clocks = <&mstp5_clks R8A7791_CLK_THERMAL>;
+		power-domains = <&cpg_clocks>;
 	};
 
 	timer {
@@ -199,6 +208,7 @@
 			     <0 143 IRQ_TYPE_LEVEL_HIGH>;
 		clocks = <&mstp1_clks R8A7791_CLK_CMT0>;
 		clock-names = "fck";
+		power-domains = <&cpg_clocks>;
 
 		renesas,channels-mask = <0x60>;
 
@@ -218,6 +228,7 @@
 			     <0 127 IRQ_TYPE_LEVEL_HIGH>;
 		clocks = <&mstp3_clks R8A7791_CLK_CMT1>;
 		clock-names = "fck";
+		power-domains = <&cpg_clocks>;
 
 		renesas,channels-mask = <0xff>;
 
@@ -240,6 +251,7 @@
 			     <0 16 IRQ_TYPE_LEVEL_HIGH>,
 			     <0 17 IRQ_TYPE_LEVEL_HIGH>;
 		clocks = <&mstp4_clks R8A7791_CLK_IRQC>;
+		power-domains = <&cpg_clocks>;
 	};
 
 	dmac0: dma-controller at e6700000 {
@@ -268,6 +280,7 @@
 				"ch12", "ch13", "ch14";
 		clocks = <&mstp2_clks R8A7791_CLK_SYS_DMAC0>;
 		clock-names = "fck";
+		power-domains = <&cpg_clocks>;
 		#dma-cells = <1>;
 		dma-channels = <15>;
 	};
@@ -298,6 +311,7 @@
 				"ch12", "ch13", "ch14";
 		clocks = <&mstp2_clks R8A7791_CLK_SYS_DMAC1>;
 		clock-names = "fck";
+		power-domains = <&cpg_clocks>;
 		#dma-cells = <1>;
 		dma-channels = <15>;
 	};
@@ -326,6 +340,7 @@
 				"ch12";
 		clocks = <&mstp5_clks R8A7791_CLK_AUDIO_DMAC0>;
 		clock-names = "fck";
+		power-domains = <&cpg_clocks>;
 		#dma-cells = <1>;
 		dma-channels = <13>;
 	};
@@ -354,6 +369,7 @@
 				"ch12";
 		clocks = <&mstp5_clks R8A7791_CLK_AUDIO_DMAC1>;
 		clock-names = "fck";
+		power-domains = <&cpg_clocks>;
 		#dma-cells = <1>;
 		dma-channels = <13>;
 	};
@@ -365,6 +381,7 @@
 			      0 109 IRQ_TYPE_LEVEL_HIGH>;
 		interrupt-names = "ch0", "ch1";
 		clocks = <&mstp3_clks R8A7791_CLK_USBDMAC0>;
+		power-domains = <&cpg_clocks>;
 		#dma-cells = <1>;
 		dma-channels = <2>;
 	};
@@ -376,6 +393,7 @@
 			      0 110 IRQ_TYPE_LEVEL_HIGH>;
 		interrupt-names = "ch0", "ch1";
 		clocks = <&mstp3_clks R8A7791_CLK_USBDMAC1>;
+		power-domains = <&cpg_clocks>;
 		#dma-cells = <1>;
 		dma-channels = <2>;
 	};
@@ -388,6 +406,7 @@
 		reg = <0 0xe6508000 0 0x40>;
 		interrupts = <0 287 IRQ_TYPE_LEVEL_HIGH>;
 		clocks = <&mstp9_clks R8A7791_CLK_I2C0>;
+		power-domains = <&cpg_clocks>;
 		status = "disabled";
 	};
 
@@ -398,6 +417,7 @@
 		reg = <0 0xe6518000 0 0x40>;
 		interrupts = <0 288 IRQ_TYPE_LEVEL_HIGH>;
 		clocks = <&mstp9_clks R8A7791_CLK_I2C1>;
+		power-domains = <&cpg_clocks>;
 		status = "disabled";
 	};
 
@@ -408,6 +428,7 @@
 		reg = <0 0xe6530000 0 0x40>;
 		interrupts = <0 286 IRQ_TYPE_LEVEL_HIGH>;
 		clocks = <&mstp9_clks R8A7791_CLK_I2C2>;
+		power-domains = <&cpg_clocks>;
 		status = "disabled";
 	};
 
@@ -418,6 +439,7 @@
 		reg = <0 0xe6540000 0 0x40>;
 		interrupts = <0 290 IRQ_TYPE_LEVEL_HIGH>;
 		clocks = <&mstp9_clks R8A7791_CLK_I2C3>;
+		power-domains = <&cpg_clocks>;
 		status = "disabled";
 	};
 
@@ -428,6 +450,7 @@
 		reg = <0 0xe6520000 0 0x40>;
 		interrupts = <0 19 IRQ_TYPE_LEVEL_HIGH>;
 		clocks = <&mstp9_clks R8A7791_CLK_I2C4>;
+		power-domains = <&cpg_clocks>;
 		status = "disabled";
 	};
 
@@ -439,6 +462,7 @@
 		reg = <0 0xe6528000 0 0x40>;
 		interrupts = <0 20 IRQ_TYPE_LEVEL_HIGH>;
 		clocks = <&mstp9_clks R8A7791_CLK_I2C5>;
+		power-domains = <&cpg_clocks>;
 		status = "disabled";
 	};
 
@@ -452,6 +476,7 @@
 		clocks = <&mstp9_clks R8A7791_CLK_IICDVFS>;
 		dmas = <&dmac0 0x77>, <&dmac0 0x78>;
 		dma-names = "tx", "rx";
+		power-domains = <&cpg_clocks>;
 		status = "disabled";
 	};
 
@@ -464,6 +489,7 @@
 		clocks = <&mstp3_clks R8A7791_CLK_IIC0>;
 		dmas = <&dmac0 0x61>, <&dmac0 0x62>;
 		dma-names = "tx", "rx";
+		power-domains = <&cpg_clocks>;
 		status = "disabled";
 	};
 
@@ -476,6 +502,7 @@
 		clocks = <&mstp3_clks R8A7791_CLK_IIC1>;
 		dmas = <&dmac0 0x65>, <&dmac0 0x66>;
 		dma-names = "tx", "rx";
+		power-domains = <&cpg_clocks>;
 		status = "disabled";
 	};
 
@@ -492,6 +519,7 @@
 		clocks = <&mstp3_clks R8A7791_CLK_MMCIF0>;
 		dmas = <&dmac0 0xd1>, <&dmac0 0xd2>;
 		dma-names = "tx", "rx";
+		power-domains = <&cpg_clocks>;
 		reg-io-width = <4>;
 		status = "disabled";
 		max-frequency = <97500000>;
@@ -504,6 +532,7 @@
 		clocks = <&mstp3_clks R8A7791_CLK_SDHI0>;
 		dmas = <&dmac1 0xcd>, <&dmac1 0xce>;
 		dma-names = "tx", "rx";
+		power-domains = <&cpg_clocks>;
 		status = "disabled";
 	};
 
@@ -514,6 +543,7 @@
 		clocks = <&mstp3_clks R8A7791_CLK_SDHI1>;
 		dmas = <&dmac1 0xc1>, <&dmac1 0xc2>;
 		dma-names = "tx", "rx";
+		power-domains = <&cpg_clocks>;
 		status = "disabled";
 	};
 
@@ -524,6 +554,7 @@
 		clocks = <&mstp3_clks R8A7791_CLK_SDHI2>;
 		dmas = <&dmac1 0xd3>, <&dmac1 0xd4>;
 		dma-names = "tx", "rx";
+		power-domains = <&cpg_clocks>;
 		status = "disabled";
 	};
 
@@ -535,6 +566,7 @@
 		clock-names = "sci_ick";
 		dmas = <&dmac0 0x21>, <&dmac0 0x22>;
 		dma-names = "tx", "rx";
+		power-domains = <&cpg_clocks>;
 		status = "disabled";
 	};
 
@@ -546,6 +578,7 @@
 		clock-names = "sci_ick";
 		dmas = <&dmac0 0x25>, <&dmac0 0x26>;
 		dma-names = "tx", "rx";
+		power-domains = <&cpg_clocks>;
 		status = "disabled";
 	};
 
@@ -557,6 +590,7 @@
 		clock-names = "sci_ick";
 		dmas = <&dmac0 0x27>, <&dmac0 0x28>;
 		dma-names = "tx", "rx";
+		power-domains = <&cpg_clocks>;
 		status = "disabled";
 	};
 
@@ -568,6 +602,7 @@
 		clock-names = "sci_ick";
 		dmas = <&dmac0 0x1b>, <&dmac0 0x1c>;
 		dma-names = "tx", "rx";
+		power-domains = <&cpg_clocks>;
 		status = "disabled";
 	};
 
@@ -579,6 +614,7 @@
 		clock-names = "sci_ick";
 		dmas = <&dmac0 0x1f>, <&dmac0 0x20>;
 		dma-names = "tx", "rx";
+		power-domains = <&cpg_clocks>;
 		status = "disabled";
 	};
 
@@ -590,6 +626,7 @@
 		clock-names = "sci_ick";
 		dmas = <&dmac0 0x23>, <&dmac0 0x24>;
 		dma-names = "tx", "rx";
+		power-domains = <&cpg_clocks>;
 		status = "disabled";
 	};
 
@@ -601,6 +638,7 @@
 		clock-names = "sci_ick";
 		dmas = <&dmac0 0x3d>, <&dmac0 0x3e>;
 		dma-names = "tx", "rx";
+		power-domains = <&cpg_clocks>;
 		status = "disabled";
 	};
 
@@ -612,6 +650,7 @@
 		clock-names = "sci_ick";
 		dmas = <&dmac0 0x19>, <&dmac0 0x1a>;
 		dma-names = "tx", "rx";
+		power-domains = <&cpg_clocks>;
 		status = "disabled";
 	};
 
@@ -623,6 +662,7 @@
 		clock-names = "sci_ick";
 		dmas = <&dmac0 0x1d>, <&dmac0 0x1e>;
 		dma-names = "tx", "rx";
+		power-domains = <&cpg_clocks>;
 		status = "disabled";
 	};
 
@@ -634,6 +674,7 @@
 		clock-names = "sci_ick";
 		dmas = <&dmac0 0x29>, <&dmac0 0x2a>;
 		dma-names = "tx", "rx";
+		power-domains = <&cpg_clocks>;
 		status = "disabled";
 	};
 
@@ -645,6 +686,7 @@
 		clock-names = "sci_ick";
 		dmas = <&dmac0 0x2d>, <&dmac0 0x2e>;
 		dma-names = "tx", "rx";
+		power-domains = <&cpg_clocks>;
 		status = "disabled";
 	};
 
@@ -656,6 +698,7 @@
 		clock-names = "sci_ick";
 		dmas = <&dmac0 0x2b>, <&dmac0 0x2c>;
 		dma-names = "tx", "rx";
+		power-domains = <&cpg_clocks>;
 		status = "disabled";
 	};
 
@@ -667,6 +710,7 @@
 		clock-names = "sci_ick";
 		dmas = <&dmac0 0x2f>, <&dmac0 0x30>;
 		dma-names = "tx", "rx";
+		power-domains = <&cpg_clocks>;
 		status = "disabled";
 	};
 
@@ -678,6 +722,7 @@
 		clock-names = "sci_ick";
 		dmas = <&dmac0 0xfb>, <&dmac0 0xfc>;
 		dma-names = "tx", "rx";
+		power-domains = <&cpg_clocks>;
 		status = "disabled";
 	};
 
@@ -689,6 +734,7 @@
 		clock-names = "sci_ick";
 		dmas = <&dmac0 0xfd>, <&dmac0 0xfe>;
 		dma-names = "tx", "rx";
+		power-domains = <&cpg_clocks>;
 		status = "disabled";
 	};
 
@@ -700,6 +746,7 @@
 		clock-names = "sci_ick";
 		dmas = <&dmac0 0x39>, <&dmac0 0x3a>;
 		dma-names = "tx", "rx";
+		power-domains = <&cpg_clocks>;
 		status = "disabled";
 	};
 
@@ -711,6 +758,7 @@
 		clock-names = "sci_ick";
 		dmas = <&dmac0 0x4d>, <&dmac0 0x4e>;
 		dma-names = "tx", "rx";
+		power-domains = <&cpg_clocks>;
 		status = "disabled";
 	};
 
@@ -722,6 +770,7 @@
 		clock-names = "sci_ick";
 		dmas = <&dmac0 0x3b>, <&dmac0 0x3c>;
 		dma-names = "tx", "rx";
+		power-domains = <&cpg_clocks>;
 		status = "disabled";
 	};
 
@@ -730,6 +779,7 @@
 		reg = <0 0xee700000 0 0x400>;
 		interrupts = <0 162 IRQ_TYPE_LEVEL_HIGH>;
 		clocks = <&mstp8_clks R8A7791_CLK_ETHER>;
+		power-domains = <&cpg_clocks>;
 		phy-mode = "rmii";
 		#address-cells = <1>;
 		#size-cells = <0>;
@@ -741,6 +791,7 @@
 		reg = <0 0xee300000 0 0x2000>;
 		interrupts = <0 105 IRQ_TYPE_LEVEL_HIGH>;
 		clocks = <&mstp8_clks R8A7791_CLK_SATA0>;
+		power-domains = <&cpg_clocks>;
 		status = "disabled";
 	};
 
@@ -749,6 +800,7 @@
 		reg = <0 0xee500000 0 0x2000>;
 		interrupts = <0 106 IRQ_TYPE_LEVEL_HIGH>;
 		clocks = <&mstp8_clks R8A7791_CLK_SATA1>;
+		power-domains = <&cpg_clocks>;
 		status = "disabled";
 	};
 
@@ -757,12 +809,13 @@
 		reg = <0 0xe6590000 0 0x100>;
 		interrupts = <0 107 IRQ_TYPE_LEVEL_HIGH>;
 		clocks = <&mstp7_clks R8A7791_CLK_HSUSB>;
-		renesas,buswait = <4>;
-		phys = <&usb0 1>;
-		phy-names = "usb";
 		dmas = <&usb_dmac0 0>, <&usb_dmac0 1>,
 		       <&usb_dmac1 0>, <&usb_dmac1 1>;
 		dma-names = "ch0", "ch1", "ch2", "ch3";
+		power-domains = <&cpg_clocks>;
+		renesas,buswait = <4>;
+		phys = <&usb0 1>;
+		phy-names = "usb";
 		status = "disabled";
 	};
 
@@ -773,6 +826,7 @@
 		#size-cells = <0>;
 		clocks = <&mstp7_clks R8A7791_CLK_HSUSB>;
 		clock-names = "usbhs";
+		power-domains = <&cpg_clocks>;
 		status = "disabled";
 
 		usb0: usb-channel at 0 {
@@ -787,25 +841,28 @@
 
 	vin0: video at e6ef0000 {
 		compatible = "renesas,vin-r8a7791";
-		clocks = <&mstp8_clks R8A7791_CLK_VIN0>;
 		reg = <0 0xe6ef0000 0 0x1000>;
 		interrupts = <0 188 IRQ_TYPE_LEVEL_HIGH>;
+		clocks = <&mstp8_clks R8A7791_CLK_VIN0>;
+		power-domains = <&cpg_clocks>;
 		status = "disabled";
 	};
 
 	vin1: video at e6ef1000 {
 		compatible = "renesas,vin-r8a7791";
-		clocks = <&mstp8_clks R8A7791_CLK_VIN1>;
 		reg = <0 0xe6ef1000 0 0x1000>;
 		interrupts = <0 189 IRQ_TYPE_LEVEL_HIGH>;
+		clocks = <&mstp8_clks R8A7791_CLK_VIN1>;
+		power-domains = <&cpg_clocks>;
 		status = "disabled";
 	};
 
 	vin2: video at e6ef2000 {
 		compatible = "renesas,vin-r8a7791";
-		clocks = <&mstp8_clks R8A7791_CLK_VIN2>;
 		reg = <0 0xe6ef2000 0 0x1000>;
 		interrupts = <0 190 IRQ_TYPE_LEVEL_HIGH>;
+		clocks = <&mstp8_clks R8A7791_CLK_VIN2>;
+		power-domains = <&cpg_clocks>;
 		status = "disabled";
 	};
 
@@ -814,6 +871,7 @@
 		reg = <0 0xfe928000 0 0x8000>;
 		interrupts = <0 267 IRQ_TYPE_LEVEL_HIGH>;
 		clocks = <&mstp1_clks R8A7791_CLK_VSP1_S>;
+		power-domains = <&cpg_clocks>;
 
 		renesas,has-lut;
 		renesas,has-sru;
@@ -827,6 +885,7 @@
 		reg = <0 0xfe930000 0 0x8000>;
 		interrupts = <0 246 IRQ_TYPE_LEVEL_HIGH>;
 		clocks = <&mstp1_clks R8A7791_CLK_VSP1_DU0>;
+		power-domains = <&cpg_clocks>;
 
 		renesas,has-lif;
 		renesas,has-lut;
@@ -840,6 +899,7 @@
 		reg = <0 0xfe938000 0 0x8000>;
 		interrupts = <0 247 IRQ_TYPE_LEVEL_HIGH>;
 		clocks = <&mstp1_clks R8A7791_CLK_VSP1_DU1>;
+		power-domains = <&cpg_clocks>;
 
 		renesas,has-lif;
 		renesas,has-lut;
@@ -885,6 +945,7 @@
 		clocks = <&mstp9_clks R8A7791_CLK_RCAN0>,
 			 <&cpg_clocks R8A7791_CLK_RCAN>, <&can_clk>;
 		clock-names = "clkp1", "clkp2", "can_clk";
+		power-domains = <&cpg_clocks>;
 		status = "disabled";
 	};
 
@@ -895,6 +956,7 @@
 		clocks = <&mstp9_clks R8A7791_CLK_RCAN1>,
 			 <&cpg_clocks R8A7791_CLK_RCAN>, <&can_clk>;
 		clock-names = "clkp1", "clkp2", "can_clk";
+		power-domains = <&cpg_clocks>;
 		status = "disabled";
 	};
 
@@ -903,6 +965,7 @@
 		reg = <0 0xfe980000 0 0x10300>;
 		interrupts = <0 272 IRQ_TYPE_LEVEL_HIGH>;
 		clocks = <&mstp1_clks R8A7791_CLK_JPU>;
+		power-domains = <&cpg_clocks>;
 	};
 
 	clocks {
@@ -979,6 +1042,7 @@
 			clock-output-names = "main", "pll0", "pll1", "pll3",
 					     "lb", "qspi", "sdh", "sd0", "z",
 					     "rcan", "adsp";
+			#power-domain-cells = <0>;
 		};
 
 		/* Variable factor clocks */
@@ -1361,6 +1425,7 @@
 		clocks = <&mstp9_clks R8A7791_CLK_QSPI_MOD>;
 		dmas = <&dmac0 0x17>, <&dmac0 0x18>;
 		dma-names = "tx", "rx";
+		power-domains = <&cpg_clocks>;
 		num-cs = <1>;
 		#address-cells = <1>;
 		#size-cells = <0>;
@@ -1374,6 +1439,7 @@
 		clocks = <&mstp0_clks R8A7791_CLK_MSIOF0>;
 		dmas = <&dmac0 0x51>, <&dmac0 0x52>;
 		dma-names = "tx", "rx";
+		power-domains = <&cpg_clocks>;
 		#address-cells = <1>;
 		#size-cells = <0>;
 		status = "disabled";
@@ -1386,6 +1452,7 @@
 		clocks = <&mstp2_clks R8A7791_CLK_MSIOF1>;
 		dmas = <&dmac0 0x55>, <&dmac0 0x56>;
 		dma-names = "tx", "rx";
+		power-domains = <&cpg_clocks>;
 		#address-cells = <1>;
 		#size-cells = <0>;
 		status = "disabled";
@@ -1398,6 +1465,7 @@
 		clocks = <&mstp2_clks R8A7791_CLK_MSIOF2>;
 		dmas = <&dmac0 0x41>, <&dmac0 0x42>;
 		dma-names = "tx", "rx";
+		power-domains = <&cpg_clocks>;
 		#address-cells = <1>;
 		#size-cells = <0>;
 		status = "disabled";
@@ -1408,6 +1476,7 @@
 		reg = <0 0xee000000 0 0xc00>;
 		interrupts = <0 101 IRQ_TYPE_LEVEL_HIGH>;
 		clocks = <&mstp3_clks R8A7791_CLK_SSUSB>;
+		power-domains = <&cpg_clocks>;
 		phys = <&usb2 1>;
 		phy-names = "usb";
 		status = "disabled";
@@ -1416,10 +1485,11 @@
 	pci0: pci at ee090000 {
 		compatible = "renesas,pci-r8a7791";
 		device_type = "pci";
-		clocks = <&mstp7_clks R8A7791_CLK_EHCI>;
 		reg = <0 0xee090000 0 0xc00>,
 		      <0 0xee080000 0 0x1100>;
 		interrupts = <0 108 IRQ_TYPE_LEVEL_HIGH>;
+		clocks = <&mstp7_clks R8A7791_CLK_EHCI>;
+		power-domains = <&cpg_clocks>;
 		status = "disabled";
 
 		bus-range = <0 0>;
@@ -1450,10 +1520,11 @@
 	pci1: pci at ee0d0000 {
 		compatible = "renesas,pci-r8a7791";
 		device_type = "pci";
-		clocks = <&mstp7_clks R8A7791_CLK_EHCI>;
 		reg = <0 0xee0d0000 0 0xc00>,
 		      <0 0xee0c0000 0 0x1100>;
 		interrupts = <0 113 IRQ_TYPE_LEVEL_HIGH>;
+		clocks = <&mstp7_clks R8A7791_CLK_EHCI>;
+		power-domains = <&cpg_clocks>;
 		status = "disabled";
 
 		bus-range = <1 1>;
@@ -1503,6 +1574,7 @@
 		interrupt-map = <0 0 0 0 &gic 0 116 IRQ_TYPE_LEVEL_HIGH>;
 		clocks = <&mstp3_clks R8A7791_CLK_PCIEC>, <&pcie_bus_clk>;
 		clock-names = "pcie", "pcie_bus";
+		power-domains = <&cpg_clocks>;
 		status = "disabled";
 	};
 
-- 
2.1.4



From chaotian.jing at mediatek.com  Wed Aug 12 01:24:03 2015
From: chaotian.jing at mediatek.com (Chaotian Jing)
Date: Wed, 12 Aug 2015 16:24:03 +0800
Subject: [PATCH 2/4] mmc: mediatek: Add HS400 support
In-Reply-To: <1439367845-5891-1-git-send-email-chaotian.jing@mediatek.com>
References: <1439367845-5891-1-git-send-email-chaotian.jing@mediatek.com>
Message-ID: <1439367845-5891-3-git-send-email-chaotian.jing@mediatek.com>

Support HS400 mode in driver

Signed-off-by: Chaotian Jing <chaotian.jing at mediatek.com>
---
 drivers/mmc/host/mtk-sd.c | 108 ++++++++++++++++++++++++++++++++++++----------
 1 file changed, 86 insertions(+), 22 deletions(-)

diff --git a/drivers/mmc/host/mtk-sd.c b/drivers/mmc/host/mtk-sd.c
index eb44fe1..457d919 100644
--- a/drivers/mmc/host/mtk-sd.c
+++ b/drivers/mmc/host/mtk-sd.c
@@ -72,6 +72,8 @@
 #define MSDC_PATCH_BIT   0xb0
 #define MSDC_PATCH_BIT1  0xb4
 #define MSDC_PAD_TUNE    0xec
+#define PAD_DS_TUNE      0x188
+#define EMMC50_CFG0      0x208
 
 /*--------------------------------------------------------------------------*/
 /* Register Mask                                                            */
@@ -205,6 +207,14 @@
 #define MSDC_PATCH_BIT_SPCPUSH    (0x1 << 29)	/* RW */
 #define MSDC_PATCH_BIT_DECRCTMO   (0x1 << 30)	/* RW */
 
+#define PAD_DS_TUNE_DLY1	  (0x1f << 2)
+#define PAD_DS_TUNE_DLY2	  (0x1f << 7)
+#define PAD_DS_TUNE_DLY3	  (0x1f << 12)
+
+#define EMMC50_CFG_PADCMD_LATCHCK (0x1 << 0)
+#define EMMC50_CFG_CRCSTS_EDGE    (0x1 << 3)
+#define EMMC50_CFG_CFCSTS_SEL     (0x1 << 4)
+
 #define REQ_CMD_EIO  (0x1 << 0)
 #define REQ_CMD_TMO  (0x1 << 1)
 #define REQ_DAT_ERR  (0x1 << 2)
@@ -266,6 +276,8 @@ struct msdc_save_para {
 	u32 pad_tune;
 	u32 patch_bit0;
 	u32 patch_bit1;
+	u32 pad_ds_tune;
+	u32 emmc50_cfg0;
 };
 
 struct msdc_host {
@@ -295,14 +307,17 @@ struct msdc_host {
 	struct work_struct repeat_req;
 	struct mmc_request *repeat_mrq;
 	u32 tune_cmd_counter;
+	u32 tune_hs400_rw_counter;
 	int irq;		/* host interrupt */
 
 	struct clk *src_clk;	/* msdc source clock */
+	struct clk *src_clk_parent; /* src_clk's parent */
+	struct clk *hs400_src;	/* 400Mhz source clock */
 	struct clk *h_clk;      /* msdc h_clk */
 	u32 mclk;		/* mmc subsystem clock frequency */
 	u32 src_clk_freq;	/* source clock frequency */
 	u32 sclk;		/* SD/MS bus clock frequency */
-	bool ddr;
+	unsigned char timing;
 	bool vqmmc_enabled;
 	struct msdc_save_para save_para; /* used when gate HCLK */
 };
@@ -493,7 +508,7 @@ static void msdc_ungate_clock(struct msdc_host *host)
 		cpu_relax();
 }
 
-static void msdc_set_mclk(struct msdc_host *host, int ddr, u32 hz)
+static void msdc_set_mclk(struct msdc_host *host, unsigned char timing, u32 hz)
 {
 	u32 mode;
 	u32 flags;
@@ -509,8 +524,13 @@ static void msdc_set_mclk(struct msdc_host *host, int ddr, u32 hz)
 
 	flags = readl(host->base + MSDC_INTEN);
 	sdr_clr_bits(host->base + MSDC_INTEN, flags);
-	if (ddr) { /* may need to modify later */
-		mode = 0x2; /* ddr mode and use divisor */
+	if (timing == MMC_TIMING_UHS_DDR50 ||
+	    timing == MMC_TIMING_MMC_DDR52 ||
+	    timing == MMC_TIMING_MMC_HS400) { /* may need to modify later */
+		if (timing == MMC_TIMING_MMC_HS400)
+			mode = 0x3;
+		else
+			mode = 0x2; /* ddr mode and use divisor */
 		if (hz >= (host->src_clk_freq >> 2)) {
 			div = 0; /* mean div = 1/4 */
 			sclk = host->src_clk_freq >> 2; /* sclk = clk / 4 */
@@ -540,12 +560,12 @@ static void msdc_set_mclk(struct msdc_host *host, int ddr, u32 hz)
 		cpu_relax();
 	host->sclk = sclk;
 	host->mclk = hz;
-	host->ddr = ddr;
+	host->timing = timing;
 	/* need because clk changed. */
 	msdc_set_timeout(host, host->timeout_ns, host->timeout_clks);
 	sdr_set_bits(host->base + MSDC_INTEN, flags);
 
-	dev_dbg(host->dev, "sclk: %d, ddr: %d\n", host->sclk, ddr);
+	dev_dbg(host->dev, "sclk: %d, timing: %d\n", host->sclk, timing);
 }
 
 static inline u32 msdc_cmd_find_resp(struct msdc_host *host,
@@ -710,6 +730,7 @@ static void msdc_request_done(struct msdc_host *host, struct mmc_request *mrq)
 		}
 	}
 	host->tune_cmd_counter = 0;
+	host->tune_hs400_rw_counter = 0;
 	mmc_request_done(host->mmc, mrq);
 
 	pm_runtime_mark_last_busy(host->dev);
@@ -1132,6 +1153,7 @@ static void msdc_init_hw(struct msdc_host *host)
 	writel(0x403c0046, host->base + MSDC_PATCH_BIT);
 	sdr_set_field(host->base + MSDC_PATCH_BIT, MSDC_CKGEN_MSDC_DLY_SEL, 1);
 	writel(0xffff0089, host->base + MSDC_PATCH_BIT1);
+	sdr_set_bits(host->base + EMMC50_CFG0, EMMC50_CFG_CFCSTS_SEL);
 	/* Configure to enable SDIO mode.
 	 * it's must otherwise sdio cmd5 failed
 	 */
@@ -1163,11 +1185,14 @@ static void msdc_init_gpd_bd(struct msdc_host *host, struct msdc_dma *dma)
 	struct mt_bdma_desc *bd = dma->bd;
 	int i;
 
-	memset(gpd, 0, sizeof(struct mt_gpdma_desc));
+	memset(gpd, 0, sizeof(struct mt_gpdma_desc) * 2);
 
 	gpd->gpd_info = GPDMA_DESC_BDP; /* hwo, cs, bd pointer */
 	gpd->ptr = (u32)dma->bd_addr; /* physical address */
-
+	/* gpd->next is must set for desc DMA
+	 * That's why must alloc 2 gpd structure.
+	 */
+	gpd->next = (u32)dma->gpd_addr + sizeof(struct mt_gpdma_desc);
 	memset(bd, 0, sizeof(struct mt_bdma_desc) * MAX_BD_NUM);
 	for (i = 0; i < (MAX_BD_NUM - 1); i++)
 		bd[i].next = (u32)dma->bd_addr + sizeof(*bd) * (i + 1);
@@ -1177,14 +1202,9 @@ static void msdc_ops_set_ios(struct mmc_host *mmc, struct mmc_ios *ios)
 {
 	struct msdc_host *host = mmc_priv(mmc);
 	int ret;
-	u32 ddr = 0;
 
 	pm_runtime_get_sync(host->dev);
 
-	if (ios->timing == MMC_TIMING_UHS_DDR50 ||
-	    ios->timing == MMC_TIMING_MMC_DDR52)
-		ddr = 1;
-
 	msdc_set_buswidth(host, ios->bus_width);
 
 	/* Suspend/Resume will do power off/on */
@@ -1222,8 +1242,8 @@ static void msdc_ops_set_ios(struct mmc_host *mmc, struct mmc_ios *ios)
 		break;
 	}
 
-	if (host->mclk != ios->clock || host->ddr != ddr)
-		msdc_set_mclk(host, ddr, ios->clock);
+	if (host->mclk != ios->clock || host->timing != ios->timing)
+		msdc_set_mclk(host, ios->timing, ios->clock);
 
 end:
 	pm_runtime_mark_last_busy(host->dev);
@@ -1290,7 +1310,6 @@ static void msdc_tune_request(struct msdc_host *host)
 {
 	u32 orig_rsmpl, orig_cksel;
 	u32 cur_rsmpl, cur_cksel = 0;
-	u32 ddr, clkmode;
 	struct mmc_ios ios = host->mmc->ios;
 
 	sdr_get_field(host->base + MSDC_IOCON, MSDC_IOCON_RSPL, &orig_rsmpl);
@@ -1318,9 +1337,38 @@ static void msdc_tune_request(struct msdc_host *host)
 		sdr_set_field(host->base + MSDC_IOCON, MSDC_IOCON_RSPL, 0);
 		sdr_set_field(host->base + MSDC_PATCH_BIT,
 			      MSDC_CKGEN_MSDC_DLY_SEL, 0);
-		sdr_get_field(host->base + MSDC_CFG, MSDC_CFG_CKMOD, &clkmode);
-		ddr = (clkmode == 2) ? 1 : 0;
-		msdc_set_mclk(host, ddr, host->mclk / 2);
+		msdc_set_mclk(host, host->timing, host->mclk / 2);
+	}
+}
+
+static void emmc_hs400_tune_rw(struct msdc_host *host)
+{
+	int cur_ds_dly1, cur_ds_dly3, orig_ds_dly1, orig_ds_dly3;
+
+	sdr_get_field(host->base + PAD_DS_TUNE, PAD_DS_TUNE_DLY1, &orig_ds_dly1);
+	sdr_get_field(host->base + PAD_DS_TUNE, PAD_DS_TUNE_DLY3, &orig_ds_dly3);
+
+	cur_ds_dly1 = orig_ds_dly1 - 1;
+	cur_ds_dly3 = orig_ds_dly3;
+	if (cur_ds_dly1 < 0) {
+		cur_ds_dly1 = 31;
+		cur_ds_dly3 = orig_ds_dly3 + 1;
+		if (cur_ds_dly3 >= 32)
+			cur_ds_dly3 = 0;
+	}
+
+	if (++host->tune_hs400_rw_counter >= 32 * 32) {
+		dev_warn(host->dev, "HS400 tune fail at %dhz\n", host->mclk);
+		host->tune_hs400_rw_counter = 0;
+		msdc_set_mclk(host, host->timing, host->mclk / 2);
+	} else {
+		sdr_set_field(host->base + PAD_DS_TUNE, PAD_DS_TUNE_DLY1, cur_ds_dly1);
+		if (cur_ds_dly3 != orig_ds_dly3) {
+			sdr_set_field(host->base + PAD_DS_TUNE, PAD_DS_TUNE_DLY3,
+				      cur_ds_dly3);
+		}
+		dev_dbg(host->dev, "cur_ds_dly1<0x%x>, cur_ds_dly3<0x%x>\n",
+				cur_ds_dly1, cur_ds_dly3);
 	}
 }
 
@@ -1336,10 +1384,15 @@ static void msdc_repeat_request(struct work_struct *work)
 	spin_unlock_irqrestore(&host->lock, flags);
 	msdc_send_stop(host);
 	msdc_wait_card_not_busy(host);
-	if (mrq->data && mrq->data->error == -ETIMEDOUT)
+	if (mrq->data && mrq->data->error == -ETIMEDOUT) {
 		mmc_hw_reset(host->mmc);
-	else
-		msdc_tune_request(host);
+	} else {
+		if (mrq->data && mrq->data->error == -EILSEQ &&
+		    host->timing == MMC_TIMING_MMC_HS400)
+			emmc_hs400_tune_rw(host);
+		else
+			msdc_tune_request(host);
+	}
 	msdc_reset_mrq(mrq);
 	msdc_ops_request(host->mmc, mrq);
 }
@@ -1389,6 +1442,13 @@ static int msdc_drv_probe(struct platform_device *pdev)
 	if (IS_ERR(host->src_clk)) {
 		ret = PTR_ERR(host->src_clk);
 		goto host_free;
+	} else {
+		host->src_clk_parent = clk_get_parent(host->src_clk);
+		host->hs400_src = devm_clk_get(&pdev->dev, "400Mhz_clk");
+		if (IS_ERR(host->hs400_src))
+			dev_dbg(&pdev->dev, "Cannot find 400Mhz_clk at dts!\n");
+		else if (clk_set_parent(host->src_clk_parent, host->hs400_src) < 0)
+				dev_err(host->dev, "Failed to set 400Mhz source clock!\n");
 	}
 
 	host->h_clk = devm_clk_get(&pdev->dev, "hclk");
@@ -1541,6 +1601,8 @@ static void msdc_save_reg(struct msdc_host *host)
 	host->save_para.pad_tune = readl(host->base + MSDC_PAD_TUNE);
 	host->save_para.patch_bit0 = readl(host->base + MSDC_PATCH_BIT);
 	host->save_para.patch_bit1 = readl(host->base + MSDC_PATCH_BIT1);
+	host->save_para.pad_ds_tune = readl(host->base + PAD_DS_TUNE);
+	host->save_para.emmc50_cfg0 = readl(host->base + EMMC50_CFG0);
 }
 
 static void msdc_restore_reg(struct msdc_host *host)
@@ -1551,6 +1613,8 @@ static void msdc_restore_reg(struct msdc_host *host)
 	writel(host->save_para.pad_tune, host->base + MSDC_PAD_TUNE);
 	writel(host->save_para.patch_bit0, host->base + MSDC_PATCH_BIT);
 	writel(host->save_para.patch_bit1, host->base + MSDC_PATCH_BIT1);
+	writel(host->save_para.pad_ds_tune, host->base + PAD_DS_TUNE);
+	writel(host->save_para.emmc50_cfg0, host->base + EMMC50_CFG0);
 }
 
 static int msdc_runtime_suspend(struct device *dev)
-- 
1.8.1.1.dirty



From heiko at sntech.de  Wed Aug 12 01:26:00 2015
From: heiko at sntech.de (Heiko =?ISO-8859-1?Q?St=FCbner?=)
Date: Wed, 12 Aug 2015 10:26 +0200
Subject: [PATCH v3 0/2] clk: improve handling of orphan clocks
In-Reply-To: <20150811223409.GN2839@codeaurora.org>
References: <1429735986-18592-1-git-send-email-heiko@sntech.de>
 <20150730100908.GI2564@lukather> <20150811223409.GN2839@codeaurora.org>
Message-ID: <3547940.Og2cC25c4G@diego>

Am Dienstag, 11. August 2015, 15:34:09 schrieb Stephen Boyd:
> On 07/30, Maxime Ripard wrote:
> > On Mon, Jul 27, 2015 at 10:57:33AM +0200, Heiko St?bner wrote:
> > > did this lead anywhere meanwhile.
> > > 
> > > Last I remember the change to orphan handling made sunxi fail, but
> > > I'm still hoping to get this usable at some point :-)
> > 
> > To be honest, I don't know what the current status is. I haven't get
> > any news since that mail.
> > 
> > I started to move a significant portion of our clocks to
> > CLK_OF_DECLARE, but not all of them are (which probably make the
> > situation worse for the time being).
> 
> Sorry, I think we're still waiting for the critical clocks stuff
> to settle down so that Sunxi can use that instead of calling
> clk_prepare_enable() in init code. For now, I've put the first
> patch of the two into clk-next so that we can have proper orphan
> tracking. Hopefully we resolve critical clocks soon so that we
> can merge the defer part.

great :-)

For the defer-part you came up with a better solution than mine anyway, if I 
remember correctly.


From chaotian.jing at mediatek.com  Wed Aug 12 01:24:01 2015
From: chaotian.jing at mediatek.com (Chaotian Jing)
Date: Wed, 12 Aug 2015 16:24:01 +0800
Subject: [PATCH 0/4] msdc: Add tuning support of Mediatek MMC host
Message-ID: <1439367845-5891-1-git-send-email-chaotian.jing@mediatek.com>

This series add tuning support for EMMC/SD transfer.
The tuning thread was start when CMD/DAT crc error deteted,
for some SD card, tune DAT crc error may occur data timeout,
in this case, try to reset card to recover.
With tuning support, can support SDR104/HS200/HS400 modes

Chaotian Jing (4):
  mmc: mediatek: Add online-tuning support of EMMC/SD
  mmc: mediatek: Add HS400 support
  arm64: dts: mediatek: Support SD/EMMC SDR104/HS200/HS400
  mmc: dt-bindings:  Add 400Mhz clock source

 Documentation/devicetree/bindings/mmc/mtk-sd.txt |  10 +-
 arch/arm64/boot/dts/mediatek/mt8173-evb.dts      |  10 +-
 arch/arm64/boot/dts/mediatek/mt8173.dtsi         |   5 +-
 drivers/mmc/host/mtk-sd.c                        | 256 ++++++++++++++++++++---
 4 files changed, 248 insertions(+), 33 deletions(-)



From chaotian.jing at mediatek.com  Wed Aug 12 01:24:04 2015
From: chaotian.jing at mediatek.com (Chaotian Jing)
Date: Wed, 12 Aug 2015 16:24:04 +0800
Subject: [PATCH 3/4] arm64: dts: mediatek: Support SD/EMMC SDR104/HS200/HS400
In-Reply-To: <1439367845-5891-1-git-send-email-chaotian.jing@mediatek.com>
References: <1439367845-5891-1-git-send-email-chaotian.jing@mediatek.com>
Message-ID: <1439367845-5891-4-git-send-email-chaotian.jing@mediatek.com>

Add 400Mhz source clock for EMMC HS400 mode
Support EMMC DDR50/HS200/HS400 of mt8173-evb
Support SD SDR25/SDR50/DDR50/SDR104 of mt8173-evb

Signed-off-by: Chaotian Jing <chaotian.jing at mediatek.com>
---
 arch/arm64/boot/dts/mediatek/mt8173-evb.dts | 10 ++++++++--
 arch/arm64/boot/dts/mediatek/mt8173.dtsi    |  5 +++--
 2 files changed, 11 insertions(+), 4 deletions(-)

diff --git a/arch/arm64/boot/dts/mediatek/mt8173-evb.dts b/arch/arm64/boot/dts/mediatek/mt8173-evb.dts
index 4be66ca..cd5317f 100644
--- a/arch/arm64/boot/dts/mediatek/mt8173-evb.dts
+++ b/arch/arm64/boot/dts/mediatek/mt8173-evb.dts
@@ -70,8 +70,11 @@
 	pinctrl-0 = <&mmc0_pins_default>;
 	pinctrl-1 = <&mmc0_pins_uhs>;
 	bus-width = <8>;
-	max-frequency = <50000000>;
+	max-frequency = <200000000>;
 	cap-mmc-highspeed;
+	mmc-ddr-1_8v;
+	mmc-hs200-1_8v;
+	mmc-hs400-1_8v;
 	vmmc-supply = <&mt6397_vemc_3v3_reg>;
 	vqmmc-supply = <&mt6397_vio18_reg>;
 	non-removable;
@@ -83,9 +86,12 @@
 	pinctrl-0 = <&mmc1_pins_default>;
 	pinctrl-1 = <&mmc1_pins_uhs>;
 	bus-width = <4>;
-	max-frequency = <50000000>;
+	max-frequency = <200000000>;
 	cap-sd-highspeed;
 	sd-uhs-sdr25;
+	sd-uhs-sdr50;
+	sd-uhs-ddr50;
+	sd-uhs-sdr104;
 	cd-gpios = <&pio 132 0>;
 	vmmc-supply = <&mt6397_vmch_reg>;
 	vqmmc-supply = <&mt6397_vmc_reg>;
diff --git a/arch/arm64/boot/dts/mediatek/mt8173.dtsi b/arch/arm64/boot/dts/mediatek/mt8173.dtsi
index d18ee42..495ed94 100644
--- a/arch/arm64/boot/dts/mediatek/mt8173.dtsi
+++ b/arch/arm64/boot/dts/mediatek/mt8173.dtsi
@@ -450,8 +450,9 @@
 			reg = <0 0x11230000 0 0x1000>;
 			interrupts = <GIC_SPI 71 IRQ_TYPE_LEVEL_LOW>;
 			clocks = <&pericfg CLK_PERI_MSDC30_0>,
-				 <&topckgen CLK_TOP_MSDC50_0_H_SEL>;
-			clock-names = "source", "hclk";
+				 <&topckgen CLK_TOP_MSDC50_0_H_SEL>,
+				 <&topckgen CLK_TOP_MSDCPLL_D2>;
+			clock-names = "source", "hclk", "400Mhz_clk";
 			status = "disabled";
 		};
 
-- 
1.8.1.1.dirty



From chaotian.jing at mediatek.com  Wed Aug 12 01:24:05 2015
From: chaotian.jing at mediatek.com (Chaotian Jing)
Date: Wed, 12 Aug 2015 16:24:05 +0800
Subject: [PATCH 4/4] mmc: dt-bindings:  Add 400Mhz clock source
In-Reply-To: <1439367845-5891-1-git-send-email-chaotian.jing@mediatek.com>
References: <1439367845-5891-1-git-send-email-chaotian.jing@mediatek.com>
Message-ID: <1439367845-5891-5-git-send-email-chaotian.jing@mediatek.com>

Add 400Mhz clock source for HS400 mode

Signed-off-by: Chaotian Jing <chaotian.jing at mediatek.com>
---
 Documentation/devicetree/bindings/mmc/mtk-sd.txt | 10 ++++++++--
 1 file changed, 8 insertions(+), 2 deletions(-)

diff --git a/Documentation/devicetree/bindings/mmc/mtk-sd.txt b/Documentation/devicetree/bindings/mmc/mtk-sd.txt
index a1adfa4..2c28305 100644
--- a/Documentation/devicetree/bindings/mmc/mtk-sd.txt
+++ b/Documentation/devicetree/bindings/mmc/mtk-sd.txt
@@ -17,6 +17,10 @@ Required properties:
 - vmmc-supply: power to the Core
 - vqmmc-supply: power to the IO
 
+Optional properties:
+- clocks: 400Mhz clk, used for HS400 mode, 400Mhz source clock
+- clock-name: "400Mhz_clk"
+
 Examples:
 mmc0: mmc at 11230000 {
 	compatible = "mediatek,mt8173-mmc", "mediatek,mt8135-mmc";
@@ -24,8 +28,10 @@ mmc0: mmc at 11230000 {
 	interrupts = <GIC_SPI 39 IRQ_TYPE_LEVEL_LOW>;
 	vmmc-supply = <&mt6397_vemc_3v3_reg>;
 	vqmmc-supply = <&mt6397_vio18_reg>;
-	clocks = <&pericfg CLK_PERI_MSDC30_0>, <&topckgen CLK_TOP_MSDC50_0_H_SEL>;
-	clock-names = "source", "hclk";
+	clocks = <&pericfg CLK_PERI_MSDC30_0>,
+	         <&topckgen CLK_TOP_MSDC50_0_H_SEL>,
+	         <&topckgen CLK_TOP_MSDCPLL_D2>;
+	clock-names = "source", "hclk", "400Mhz_clk";
 	pinctrl-names = "default", "state_uhs";
 	pinctrl-0 = <&mmc0_pins_default>;
 	pinctrl-1 = <&mmc0_pins_uhs>;
-- 
1.8.1.1.dirty



From sboyd at codeaurora.org  Wed Aug 12 01:33:29 2015
From: sboyd at codeaurora.org (Stephen Boyd)
Date: Wed, 12 Aug 2015 01:33:29 -0700
Subject: [PATCH v4 1/4] dt-bindings: arm: Hi6220: add doc for SRAM
 controller
In-Reply-To: <1438673249-6051-2-git-send-email-leo.yan@linaro.org>
References: <1438673249-6051-1-git-send-email-leo.yan@linaro.org>
 <1438673249-6051-2-git-send-email-leo.yan@linaro.org>
Message-ID: <20150812083329.GA13623@codeaurora.org>

On 08/04, Leo Yan wrote:
> Document "hisilicon,hi6220-sramctrl" for SRAM controller.
> 
> Signed-off-by: Leo Yan <leo.yan at linaro.org>
> ---

Applied to clk-next

-- 
Qualcomm Innovation Center, Inc. is a member of Code Aurora Forum,
a Linux Foundation Collaborative Project


From sboyd at codeaurora.org  Wed Aug 12 01:33:36 2015
From: sboyd at codeaurora.org (Stephen Boyd)
Date: Wed, 12 Aug 2015 01:33:36 -0700
Subject: [PATCH v4 3/4] clk: Hi6220: add stub clock driver
In-Reply-To: <1438673249-6051-4-git-send-email-leo.yan@linaro.org>
References: <1438673249-6051-1-git-send-email-leo.yan@linaro.org>
 <1438673249-6051-4-git-send-email-leo.yan@linaro.org>
Message-ID: <20150812083336.GC13623@codeaurora.org>

On 08/04, Leo Yan wrote:
> On Hi6220, there have some clocks which can use mailbox channel to send
> messages to power controller to change frequency; this includes CPU, GPU
> and DDR clocks.
> 
> For dynamic frequency scaling, firstly need write the frequency value to
> SRAM region, and then send message to mailbox to trigger power controller
> to handle this requirement. This driver will use syscon APIs to pass SRAM
> memory region and use common mailbox APIs for channels accessing.
> 
> This init driver will support cpu frequency change firstly.
> 
> Signed-off-by: Leo Yan <leo.yan at linaro.org>
> ---

Applied to clk-next

-- 
Qualcomm Innovation Center, Inc. is a member of Code Aurora Forum,
a Linux Foundation Collaborative Project


From sboyd at codeaurora.org  Wed Aug 12 01:33:33 2015
From: sboyd at codeaurora.org (Stephen Boyd)
Date: Wed, 12 Aug 2015 01:33:33 -0700
Subject: [PATCH v4 2/4] dt-bindings: clk: Hi6220: Document stub clock
 driver
In-Reply-To: <1438673249-6051-3-git-send-email-leo.yan@linaro.org>
References: <1438673249-6051-1-git-send-email-leo.yan@linaro.org>
 <1438673249-6051-3-git-send-email-leo.yan@linaro.org>
Message-ID: <20150812083333.GB13623@codeaurora.org>

On 08/04, Leo Yan wrote:
> Document the new compatible for stub clock driver which is used for CPU
> and DDR's dynamic frequency scaling.
> 
> Signed-off-by: Leo Yan <leo.yan at linaro.org>
> ---

Applied to clk-next

-- 
Qualcomm Innovation Center, Inc. is a member of Code Aurora Forum,
a Linux Foundation Collaborative Project


From hdegoede at redhat.com  Wed Aug 12 01:34:37 2015
From: hdegoede at redhat.com (Hans de Goede)
Date: Wed, 12 Aug 2015 10:34:37 +0200
Subject: [linux-sunxi] [PATCH] pinctrl: sun4i: add spdif to pin
 description.
In-Reply-To: <CAEKpxBmS6YJMjREc3gmeSQOzBXFKw=Sb-xPK57oUn6BtmASErg@mail.gmail.com>
References: <1439309965-9530-1-git-send-email-codekipper@gmail.com>
 <CAGb2v64Ptt5NgeicsYtiR8At+K4aDd3Lb3U4kijQ5UM+UafSrA@mail.gmail.com>
 <CAEKpxBmS6YJMjREc3gmeSQOzBXFKw=Sb-xPK57oUn6BtmASErg@mail.gmail.com>
Message-ID: <55CB051D.3090109@redhat.com>

Hi,

On 12-08-15 07:31, Code Kipper wrote:
> On 11 August 2015 at 18:48, Chen-Yu Tsai <wens at csie.org> wrote:
>
>> On Wed, Aug 12, 2015 at 12:19 AM,  <codekipper at gmail.com> wrote:
>>> From: Marcus Cooper <codekipper at gmail.com>
>>>
>>> Signed-off-by: Marcus Cooper <codekipper at gmail.com>
>>> ---
>>>   drivers/pinctrl/sunxi/pinctrl-sun4i-a10.c | 9 ++++++---
>>>   1 file changed, 6 insertions(+), 3 deletions(-)
>>>
>>> diff --git a/drivers/pinctrl/sunxi/pinctrl-sun4i-a10.c
>> b/drivers/pinctrl/sunxi/pinctrl-sun4i-a10.c
>>> index 7376a97..daf7dec 100644
>>> --- a/drivers/pinctrl/sunxi/pinctrl-sun4i-a10.c
>>> +++ b/drivers/pinctrl/sunxi/pinctrl-sun4i-a10.c
>>> @@ -135,7 +135,8 @@ static const struct sunxi_desc_pin sun4i_a10_pins[]
>> = {
>>>          SUNXI_PIN(SUNXI_PINCTRL_PIN(B, 3),
>>>                    SUNXI_FUNCTION(0x0, "gpio_in"),
>>>                    SUNXI_FUNCTION(0x1, "gpio_out"),
>>> -                 SUNXI_FUNCTION(0x2, "ir0")),          /* TX */
>>> +                 SUNXI_FUNCTION(0x2, "ir0"),           /* TX */
>>> +                 SUNXI_FUNCTION(0x4, "spdif")),        /* MCLK */
>>>          SUNXI_PIN(SUNXI_PINCTRL_PIN(B, 4),
>>>                    SUNXI_FUNCTION(0x0, "gpio_in"),
>>>                    SUNXI_FUNCTION(0x1, "gpio_out"),
>>> @@ -176,11 +177,13 @@ static const struct sunxi_desc_pin
>> sun4i_a10_pins[] = {
>>>                    SUNXI_FUNCTION(0x0, "gpio_in"),
>>>                    SUNXI_FUNCTION(0x1, "gpio_out"),
>>>                    SUNXI_FUNCTION(0x2, "i2s"),           /* DI */
>>> -                 SUNXI_FUNCTION(0x3, "ac97")),         /* DI */
>>> +                 SUNXI_FUNCTION(0x3, "ac97"),          /* DI */
>>> +                 SUNXI_FUNCTION(0x4, "spdif")),        /* DI */
>>>          SUNXI_PIN(SUNXI_PINCTRL_PIN(B, 13),
>>>                    SUNXI_FUNCTION(0x0, "gpio_in"),
>>>                    SUNXI_FUNCTION(0x1, "gpio_out"),
>>> -                 SUNXI_FUNCTION(0x2, "spi2")),         /* CS1 */
>>> +                 SUNXI_FUNCTION(0x2, "spi2"),          /* CS1 */
>>> +                 SUNXI_FUNCTION(0x4, "spdif")),        /* DO */
>>
>> The datasheet and manual list them as NC or Reserved. Maybe mention how
>> you knew
>> they were available?
>>
> Not sure if this deserves to be in the commit message but I can definitely
> put together a covering letter with links etc.

I dear to say it belongs right there in the source code, use a multi-line
comment above the SUNXI_FUNCTION(0x4, "spdif")) to explain where the mux
info comes from. someday sooner or later someone is going to compare the
kernel mux table to the datasheet and think "huh, that is not right",
that person will be saved an immense amount of time by simply having a
comment there.

And do NOT say that this will not happen, because I've already done
such a comparison once in the past.

Regards,

Hans


From hdegoede at redhat.com  Wed Aug 12 01:37:01 2015
From: hdegoede at redhat.com (Hans de Goede)
Date: Wed, 12 Aug 2015 10:37:01 +0200
Subject: [PATCH v4 2/2] mfd: axp20x: Add a cell for the usb power_supply
 part of the axp20x PMICs
In-Reply-To: <20150811141811.GM18282@x1>
References: <1439049521-30766-1-git-send-email-hdegoede@redhat.com>
 <1439049521-30766-2-git-send-email-hdegoede@redhat.com>
 <20150811141811.GM18282@x1>
Message-ID: <55CB05AD.1030707@redhat.com>

Hi,

On 11-08-15 16:18, Lee Jones wrote:
> On Sat, 08 Aug 2015, Hans de Goede wrote:
>
>> Add a cell for the usb power_supply part of the axp20x PMICs.
>>
>> Note that this cell is only for the usb power_supply part and not the
>> ac-power / battery-charger / rtc-backup-bat-charger bits.
>>
>> Depending on the board each of those must be enabled / disabled separately
>> in devicetree as most boards do not use all 4. So in dt each one needs its
>> own child-node of the axp20x node. Another reason for using separate child
>> nodes for each is so that other devicetree nodes can have a power-supply
>> property with a phandle referencing a node representing a single
>> power-supply.
>>
>> The decision to use a separate devicetree node for each is reflected on
>> the kernel side by each getting its own mfd-cell / platform_device and
>> platform-driver.
>>
>> Note this commit also makes some whitespace changes to the intialization
>> of existing cells in axp20x_cells, these are pure whitespace changes,
>> functionally nothing changes.
>>
>> Cc: Bruno Pr?mont <bonbons at linux-vserver.org>
>> Signed-off-by: Bruno Pr?mont <bonbons at linux-vserver.org>
>> Signed-off-by: Hans de Goede <hdegoede at redhat.com>
>> Acked-by: Maxime Ripard <maxime.ripard at free-electrons.com>
>> Acked-by: Lee Jones <lee.jones at linaro.org>
>> ---
>> Changes in v2:
>> -Use DEFINE_RES_IRQ_NAMED
>> -Change indentation of axp20x_cells initializers to avoid line wrapping
>> Changes in v3:
>> -Improve commit message
>> -Add Bruno's S-o-b
>> ---
>>   drivers/mfd/axp20x.c | 20 ++++++++++++++++----
>>   1 file changed, 16 insertions(+), 4 deletions(-)
>
> Applied, thanks.

Great, but I'm not seeing this in:

https://git.kernel.org/cgit/linux/kernel/git/lee/mfd.git/log/?h=for-mfd-next

?

Regards,

Hans


>
>> diff --git a/drivers/mfd/axp20x.c b/drivers/mfd/axp20x.c
>> index d9f2f96..3f576b7 100644
>> --- a/drivers/mfd/axp20x.c
>> +++ b/drivers/mfd/axp20x.c
>> @@ -140,6 +140,13 @@ static struct resource axp20x_pek_resources[] = {
>>   	},
>>   };
>>
>> +static struct resource axp20x_usb_power_supply_resources[] = {
>> +	DEFINE_RES_IRQ_NAMED(AXP20X_IRQ_VBUS_PLUGIN, "VBUS_PLUGIN"),
>> +	DEFINE_RES_IRQ_NAMED(AXP20X_IRQ_VBUS_REMOVAL, "VBUS_REMOVAL"),
>> +	DEFINE_RES_IRQ_NAMED(AXP20X_IRQ_VBUS_VALID, "VBUS_VALID"),
>> +	DEFINE_RES_IRQ_NAMED(AXP20X_IRQ_VBUS_NOT_VALID, "VBUS_NOT_VALID"),
>> +};
>> +
>>   static struct resource axp22x_pek_resources[] = {
>>   	{
>>   		.name   = "PEK_DBR",
>> @@ -432,11 +439,16 @@ static const struct regmap_irq_chip axp288_regmap_irq_chip = {
>>
>>   static struct mfd_cell axp20x_cells[] = {
>>   	{
>> -		.name			= "axp20x-pek",
>> -		.num_resources		= ARRAY_SIZE(axp20x_pek_resources),
>> -		.resources		= axp20x_pek_resources,
>> +		.name		= "axp20x-pek",
>> +		.num_resources	= ARRAY_SIZE(axp20x_pek_resources),
>> +		.resources	= axp20x_pek_resources,
>>   	}, {
>> -		.name			= "axp20x-regulator",
>> +		.name		= "axp20x-regulator",
>> +	}, {
>> +		.name		= "axp20x-usb-power-supply",
>> +		.of_compatible	= "x-powers,axp202-usb-power-supply",
>> +		.num_resources	= ARRAY_SIZE(axp20x_usb_power_supply_resources),
>> +		.resources	= axp20x_usb_power_supply_resources,
>>   	},
>>   };
>>
>


From tony at atomide.com  Wed Aug 12 01:40:51 2015
From: tony at atomide.com (Tony Lindgren)
Date: Wed, 12 Aug 2015 01:40:51 -0700
Subject: [GIT PULL] omap clock dts changes for v4.3 merge window
In-Reply-To: <55C34026.20101@ti.com>
References: <55C34026.20101@ti.com>
Message-ID: <20150812084051.GT4215@atomide.com>

* Tero Kristo <t-kristo at ti.com> [150806 04:10]:
> The following changes since commit bc0195aad0daa2ad5b0d76cce22b167bc3435590:
> 
>   Linux 4.2-rc2 (2015-07-12 15:10:30 -0700)
> 
> are available in the git repository at:
> 
>   https://github.com/t-kristo/linux-pm.git for-4.3/ti-clk-dt
> 
> for you to fetch changes up to dff8a207815a605872dfc5bffc1bae1cad29d87c:
> 
>   ARM: dts: am4372: Set the default clock rate for dpll_clksel_mac_clk clock
> (2015-07-31 12:13:18 +0300)
> 
> ----------------------------------------------------------------
> Keerthy (2):
>       ARM: dts: AM437X: add dpll_clksel_mac_clk node
>       ARM: dts: am4372: Set the default clock rate for dpll_clksel_mac_clk
> clock
> 
>  arch/arm/boot/dts/am4372.dtsi        |    7 +++++--
>  arch/arm/boot/dts/am43xx-clocks.dtsi |    9 +++++++++
>  drivers/clk/ti/clk-43xx.c            |    1 +
>  3 files changed, 15 insertions(+), 2 deletions(-)

Pulling this into omap-for-v4.3/dt-v2 thanks. We're getting close
to the merge window so guarantees it will get merged.

Regards,

Tony 


From chaotian.jing at mediatek.com  Wed Aug 12 01:24:02 2015
From: chaotian.jing at mediatek.com (Chaotian Jing)
Date: Wed, 12 Aug 2015 16:24:02 +0800
Subject: [PATCH 1/4] mmc: mediatek: Add online-tuning support of EMMC/SD
In-Reply-To: <1439367845-5891-1-git-send-email-chaotian.jing@mediatek.com>
References: <1439367845-5891-1-git-send-email-chaotian.jing@mediatek.com>
Message-ID: <1439367845-5891-2-git-send-email-chaotian.jing@mediatek.com>

Schedule a workqueue to do tuning when CRC error
Call mmc_hw_reset to re-init card when data timeout

Signed-off-by: Chaotian Jing <chaotian.jing at mediatek.com>
---
 drivers/mmc/host/mtk-sd.c | 162 ++++++++++++++++++++++++++++++++++++++++++----
 1 file changed, 150 insertions(+), 12 deletions(-)

diff --git a/drivers/mmc/host/mtk-sd.c b/drivers/mmc/host/mtk-sd.c
index 7153500..eb44fe1 100644
--- a/drivers/mmc/host/mtk-sd.c
+++ b/drivers/mmc/host/mtk-sd.c
@@ -27,6 +27,7 @@
 #include <linux/pm_runtime.h>
 #include <linux/regulator/consumer.h>
 #include <linux/spinlock.h>
+#include <linux/workqueue.h>
 
 #include <linux/mmc/card.h>
 #include <linux/mmc/core.h>
@@ -290,6 +291,10 @@ struct msdc_host {
 	struct pinctrl_state *pins_default;
 	struct pinctrl_state *pins_uhs;
 	struct delayed_work req_timeout;
+	struct workqueue_struct *repeat_workqueue;
+	struct work_struct repeat_req;
+	struct mmc_request *repeat_mrq;
+	u32 tune_cmd_counter;
 	int irq;		/* host interrupt */
 
 	struct clk *src_clk;	/* msdc source clock */
@@ -353,7 +358,10 @@ static void msdc_reset_hw(struct msdc_host *host)
 static void msdc_cmd_next(struct msdc_host *host,
 		struct mmc_request *mrq, struct mmc_command *cmd);
 
-static u32 data_ints_mask = MSDC_INTEN_XFER_COMPL | MSDC_INTEN_DATTMO |
+static const u32 cmd_ints_mask = MSDC_INTEN_CMDRDY | MSDC_INTEN_RSPCRCERR |
+			MSDC_INTEN_CMDTMO | MSDC_INTEN_ACMDRDY |
+			MSDC_INTEN_ACMDCRCERR | MSDC_INTEN_ACMDTMO;
+static const u32 data_ints_mask = MSDC_INTEN_XFER_COMPL | MSDC_INTEN_DATTMO |
 			MSDC_INTEN_DATCRCERR | MSDC_INTEN_DMA_BDCSERR |
 			MSDC_INTEN_DMA_GPDCSERR | MSDC_INTEN_DMA_PROTECT;
 
@@ -690,6 +698,18 @@ static void msdc_request_done(struct msdc_host *host, struct mmc_request *mrq)
 	msdc_track_cmd_data(host, mrq->cmd, mrq->data);
 	if (mrq->data)
 		msdc_unprepare_data(host, mrq);
+	if (host->error && host->mmc->card &&
+	    !mmc_card_sdio(host->mmc->card)) {
+		if (mrq->cmd->error == (unsigned int)-EILSEQ ||
+		    (mrq->stop && mrq->stop->error == (unsigned int)-EILSEQ) ||
+		    (mrq->sbc && mrq->sbc->error == (unsigned int)-EILSEQ) ||
+		    (mrq->data && mrq->data->error))  {
+			host->repeat_mrq = mrq;
+			queue_work(host->repeat_workqueue, &host->repeat_req);
+			return;
+		}
+	}
+	host->tune_cmd_counter = 0;
 	mmc_request_done(host->mmc, mrq);
 
 	pm_runtime_mark_last_busy(host->dev);
@@ -725,11 +745,7 @@ static bool msdc_cmd_done(struct msdc_host *host, int events,
 	if (done)
 		return true;
 
-	sdr_clr_bits(host->base + MSDC_INTEN, MSDC_INTEN_CMDRDY |
-			MSDC_INTEN_RSPCRCERR | MSDC_INTEN_CMDTMO |
-			MSDC_INTEN_ACMDRDY | MSDC_INTEN_ACMDCRCERR |
-			MSDC_INTEN_ACMDTMO);
-	writel(cmd->arg, host->base + SDC_ARG);
+	sdr_clr_bits(host->base + MSDC_INTEN, cmd_ints_mask);
 
 	if (cmd->flags & MMC_RSP_PRESENT) {
 		if (cmd->flags & MMC_RSP_136) {
@@ -819,10 +835,7 @@ static void msdc_start_command(struct msdc_host *host,
 	rawcmd = msdc_cmd_prepare_raw_cmd(host, mrq, cmd);
 	mod_delayed_work(system_wq, &host->req_timeout, DAT_TIMEOUT);
 
-	sdr_set_bits(host->base + MSDC_INTEN, MSDC_INTEN_CMDRDY |
-			MSDC_INTEN_RSPCRCERR | MSDC_INTEN_CMDTMO |
-			MSDC_INTEN_ACMDRDY | MSDC_INTEN_ACMDCRCERR |
-			MSDC_INTEN_ACMDTMO);
+	sdr_set_bits(host->base + MSDC_INTEN, cmd_ints_mask);
 	writel(cmd->arg, host->base + SDC_ARG);
 	writel(rawcmd, host->base + SDC_CMD);
 }
@@ -942,6 +955,8 @@ static bool msdc_data_xfer_done(struct msdc_host *host, u32 events,
 
 			if (events & MSDC_INT_DATTMO)
 				data->error = -ETIMEDOUT;
+			else if (events & MSDC_INT_DATCRCERR)
+				data->error = -EILSEQ;
 
 			dev_err(host->dev, "%s: cmd=%d; blocks=%d",
 				__func__, mrq->cmd->opcode, data->blocks);
@@ -1113,8 +1128,8 @@ static void msdc_init_hw(struct msdc_host *host)
 
 	writel(0, host->base + MSDC_PAD_TUNE);
 	writel(0, host->base + MSDC_IOCON);
-	sdr_set_field(host->base + MSDC_IOCON, MSDC_IOCON_DDLSEL, 1);
-	writel(0x403c004f, host->base + MSDC_PATCH_BIT);
+	sdr_set_field(host->base + MSDC_IOCON, MSDC_IOCON_DDLSEL, 0);
+	writel(0x403c0046, host->base + MSDC_PATCH_BIT);
 	sdr_set_field(host->base + MSDC_PATCH_BIT, MSDC_CKGEN_MSDC_DLY_SEL, 1);
 	writel(0xffff0089, host->base + MSDC_PATCH_BIT1);
 	/* Configure to enable SDIO mode.
@@ -1176,6 +1191,7 @@ static void msdc_ops_set_ios(struct mmc_host *mmc, struct mmc_ios *ios)
 	switch (ios->power_mode) {
 	case MMC_POWER_UP:
 		if (!IS_ERR(mmc->supply.vmmc)) {
+			msdc_init_hw(host);
 			ret = mmc_regulator_set_ocr(mmc, mmc->supply.vmmc,
 					ios->vdd);
 			if (ret) {
@@ -1214,6 +1230,120 @@ end:
 	pm_runtime_put_autosuspend(host->dev);
 }
 
+static void msdc_reset_mrq(struct mmc_request *mrq)
+{
+	mrq->cmd->error = 0;
+	if (mrq->sbc)
+		mrq->sbc->error = 0;
+	if (mrq->data)
+		mrq->data->error = 0;
+	if (mrq->stop)
+		mrq->stop->error = 0;
+}
+
+/* Send CMD12 when tuning, do not check CRC error and timeout */
+static void msdc_send_stop(struct msdc_host *host)
+{
+	u32 opcode = MMC_STOP_TRANSMISSION;
+	u32 arg = 0;
+	u32 rawcmd = 0;
+	u32 intsts = 0;
+
+	/* Reset host first */
+	msdc_reset_hw(host);
+
+	rawcmd = (opcode & 0x3f) | (7 << 7);
+	rawcmd |= (1 << 14); /* stop cmd */
+
+	sdr_clr_bits(host->base + MSDC_INTEN, cmd_ints_mask);
+	writel(arg, host->base + SDC_ARG);
+	writel(rawcmd, host->base + SDC_CMD);
+
+	while (1) {
+		intsts = readl(host->base + MSDC_INT);
+		if (intsts) {
+			writel(intsts, host->base + MSDC_INT);
+			if (intsts & cmd_ints_mask) {
+				dev_dbg(host->dev, "result of cmd12: %x\n",
+						intsts);
+				break;
+			}
+		}
+		udelay(1);
+	}
+}
+
+/* When tuning, CMD13 may also get crc error, so use MSDC_PS to get card status */
+static void msdc_wait_card_not_busy(struct msdc_host *host)
+{
+	while (1) {
+		if ((readl(host->base + MSDC_PS) & BIT(16)) == 0) { /* check dat0 status */
+			msleep_interruptible(10);
+			dev_dbg(host->dev, "MSDC_PS: %08x, SDC_STS: %08x\n",
+				readl(host->base + MSDC_PS), readl(host->base + SDC_STS));
+		} else
+			break;
+	}
+}
+
+static void msdc_tune_request(struct msdc_host *host)
+{
+	u32 orig_rsmpl, orig_cksel;
+	u32 cur_rsmpl, cur_cksel = 0;
+	u32 ddr, clkmode;
+	struct mmc_ios ios = host->mmc->ios;
+
+	sdr_get_field(host->base + MSDC_IOCON, MSDC_IOCON_RSPL, &orig_rsmpl);
+	sdr_get_field(host->base + MSDC_PATCH_BIT, MSDC_CKGEN_MSDC_DLY_SEL,
+		      &orig_cksel);
+	cur_rsmpl = (orig_rsmpl + 1);
+	sdr_set_field(host->base + MSDC_IOCON, MSDC_IOCON_RSPL, cur_rsmpl % 2);
+
+	if (ios.timing != MMC_TIMING_MMC_HS400) {
+		sdr_set_field(host->base + MSDC_IOCON, MSDC_IOCON_DSPL,
+			      cur_rsmpl % 2);
+		sdr_set_field(host->base + MSDC_IOCON, MSDC_IOCON_W_DSPL,
+			      cur_rsmpl % 2);
+	}
+
+	if (cur_rsmpl >= 2) {
+		cur_cksel = orig_cksel + 1;
+		sdr_set_field(host->base + MSDC_PATCH_BIT,
+			      MSDC_CKGEN_MSDC_DLY_SEL, cur_cksel % 16);
+	}
+
+	if (host->tune_cmd_counter++ >= 2 * 16) {
+		dev_warn(host->dev, "Tune fail at %dhz\n", host->mclk);
+		host->tune_cmd_counter = 0;
+		sdr_set_field(host->base + MSDC_IOCON, MSDC_IOCON_RSPL, 0);
+		sdr_set_field(host->base + MSDC_PATCH_BIT,
+			      MSDC_CKGEN_MSDC_DLY_SEL, 0);
+		sdr_get_field(host->base + MSDC_CFG, MSDC_CFG_CKMOD, &clkmode);
+		ddr = (clkmode == 2) ? 1 : 0;
+		msdc_set_mclk(host, ddr, host->mclk / 2);
+	}
+}
+
+static void msdc_repeat_request(struct work_struct *work)
+{
+	struct msdc_host *host = container_of(work, struct msdc_host, repeat_req);
+	struct mmc_request *mrq;
+	unsigned long flags;
+
+	spin_lock_irqsave(&host->lock, flags);
+	mrq = host->repeat_mrq;
+	host->repeat_mrq = NULL;
+	spin_unlock_irqrestore(&host->lock, flags);
+	msdc_send_stop(host);
+	msdc_wait_card_not_busy(host);
+	if (mrq->data && mrq->data->error == -ETIMEDOUT)
+		mmc_hw_reset(host->mmc);
+	else
+		msdc_tune_request(host);
+	msdc_reset_mrq(mrq);
+	msdc_ops_request(host->mmc, mrq);
+}
+
 static struct mmc_host_ops mt_msdc_ops = {
 	.post_req = msdc_post_req,
 	.pre_req = msdc_pre_req,
@@ -1324,6 +1454,12 @@ static int msdc_drv_probe(struct platform_device *pdev)
 	}
 	msdc_init_gpd_bd(host, &host->dma);
 	INIT_DELAYED_WORK(&host->req_timeout, msdc_request_timeout);
+	host->repeat_workqueue = create_singlethread_workqueue("repeat_workqueue");
+	if (!host->repeat_workqueue) {
+		ret = -ENOMEM;
+		goto release_mem;
+	}
+	INIT_WORK(&host->repeat_req, msdc_repeat_request);
 	spin_lock_init(&host->lock);
 
 	platform_set_drvdata(pdev, mmc);
@@ -1348,6 +1484,7 @@ static int msdc_drv_probe(struct platform_device *pdev)
 end:
 	pm_runtime_disable(host->dev);
 release:
+	destroy_workqueue(host->repeat_workqueue);
 	platform_set_drvdata(pdev, NULL);
 	msdc_deinit_hw(host);
 	msdc_gate_clock(host);
@@ -1383,6 +1520,7 @@ static int msdc_drv_remove(struct platform_device *pdev)
 
 	pm_runtime_disable(host->dev);
 	pm_runtime_put_noidle(host->dev);
+	destroy_workqueue(host->repeat_workqueue);
 	dma_free_coherent(&pdev->dev,
 			sizeof(struct mt_gpdma_desc),
 			host->dma.gpd, host->dma.gpd_addr);
-- 
1.8.1.1.dirty



From horms at verge.net.au  Wed Aug 12 01:46:40 2015
From: horms at verge.net.au (Simon Horman)
Date: Wed, 12 Aug 2015 17:46:40 +0900
Subject: [GIT PULL] Renesas ARM Based SoC CPG MSTP Clock Domain Updates
 for v4.3
In-Reply-To: <20150811134249.GQ30181@localhost>
References: <cover.1438911559.git.horms+renesas@verge.net.au>
 <20150811134249.GQ30181@localhost>
Message-ID: <20150812084638.GA16058@verge.net.au>

Hi Olof,

On Tue, Aug 11, 2015 at 03:42:49PM +0200, Olof Johansson wrote:
> On Fri, Aug 07, 2015 at 11:12:03AM +0900, Simon Horman wrote:
> > Hi Olof, Hi Kevin, Hi Arnd,
> > 
> > Please consider these Renesas ARM based SoC CPG MSTP clock domain updates
> > for v4.3.
> > 
> > This pull request is based on "Third Round of Renesas ARM Based SoC DT
> > Updates for v4.3", tagged as renesas-dt3-for-v4.3, which I have also sent a
> > pull-request for.
> > 
> > The reason for that base is that the DT changes in this series update nodes
> > added in that tag.
> > 
> > This series begins with driver changes and follows up with DT changes.
> > The latter depend on the former.
> > 
> > 
> > The following changes since commit 94bdc48d55ca10f90b4a625f0e443197e0013557:
> > 
> >   ARM: shmobile: sh73a0 dtsi: Add missing "gpio-ranges" to gpio node (2015-08-05 06:39:28 +0900)
> > 
> > are available in the git repository at:
> > 
> >   git://git.kernel.org/pub/scm/linux/kernel/git/horms/renesas.git tags/renesas-cpg-mstp-clock-domain-for-v4.3
> > 
> > for you to fetch changes up to 2daa8a5a8c0994893c2ca456303f0bf53e881cb9:
> > 
> >   ARM: shmobile: r8a7794 dtsi: Add CPG/MSTP Clock Domain (2015-08-05 06:42:51 +0900)
> 
> We normally prefer to see drivers separately from DT. If you've looked at how
> we organize arm-soc, you've maybe seen that we have a separate topic for
> next/driver and one for next/dt. In other words, we try to keep them apart
> where it makes sense.
> 
> In this case, that would mean having the clk changes in a drivers branch, and
> include that in this dt4 branch.
> 
> If you want a reminder for when you might have looked at the branch sorting
> wrong: If you're naming the branch after a feature instead of the type of
> patches in it (when you send it to us), then chances are that we would ideally
> like to see the contents sorted differently -- at least in the cases where they
> cross the category boundaries that we organize our tree in.
> 
> So, while it's not a huge deal I think it makes sense to revisit this
> and do that sorting for consistency's sake. Can I please ask that you
> respin this pull request with that in mind? I'd cherry-pick them apart
> but I know you tend to base branches on each other so that might mess
> you up and I don't want to do that.

Thanks for the detailed feedback.

I have split the pull-request and reposted as you suggest above.
And I'll try to keep your 'reminder' in mind in future.


From horms at verge.net.au  Wed Aug 12 01:48:22 2015
From: horms at verge.net.au (Simon Horman)
Date: Wed, 12 Aug 2015 17:48:22 +0900
Subject: [GIT PULL] Renesas ARM Based SoC CPG MSTP Clock Domain Updates
 for v4.3
In-Reply-To: <20150811133843.GP30181@localhost>
References: <cover.1438911559.git.horms+renesas@verge.net.au>
 <20150811133843.GP30181@localhost>
Message-ID: <20150812084822.GB16058@verge.net.au>

On Tue, Aug 11, 2015 at 03:38:43PM +0200, Olof Johansson wrote:
> On Fri, Aug 07, 2015 at 11:12:03AM +0900, Simon Horman wrote:
> > Hi Olof, Hi Kevin, Hi Arnd,
> > 
> > Please consider these Renesas ARM based SoC CPG MSTP clock domain updates
> > for v4.3.
> > 
> > This pull request is based on "Third Round of Renesas ARM Based SoC DT
> > Updates for v4.3", tagged as renesas-dt3-for-v4.3, which I have also sent a
> > pull-request for.
> > 
> > The reason for that base is that the DT changes in this series update nodes
> > added in that tag.
> > 
> > This series begins with driver changes and follows up with DT changes.
> > The latter depend on the former.
> 
> I see the acked-by tags on the clk patches, but it took some searching to find
> the ack email from Stephen.
> 
> Can you please make our homework a bit easier when providing that in
> the future?

Sure, I hadn't realised that you liked to track down Acks to that extent.

As practice for myself I've included some notes in the repost of the
patches in question.  Please let me know if you need something different.


From lee.jones at linaro.org  Wed Aug 12 01:53:09 2015
From: lee.jones at linaro.org (Lee Jones)
Date: Wed, 12 Aug 2015 09:53:09 +0100
Subject: [PATCH v2 2/6] mailbox: dt-bindings: Add shared [driver <=>
 device tree] defines
In-Reply-To: <CABb+yY3jUKXXJys32bHY1u+dbdsix71Xq_H1Lrkkt27vZzmf7w@mail.gmail.com>
References: <1437990272-23111-1-git-send-email-lee.jones@linaro.org>
 <1437990272-23111-3-git-send-email-lee.jones@linaro.org>
 <CABb+yY2asjH-c+VJXvG+RK0=2p=P4Y21pznNP0riaKMWLxYZog@mail.gmail.com>
 <20150810082445.GA3249@x1>
 <CABb+yY3jUKXXJys32bHY1u+dbdsix71Xq_H1Lrkkt27vZzmf7w@mail.gmail.com>
Message-ID: <20150812085309.GB18282@x1>

On Mon, 10 Aug 2015, Jassi Brar wrote:

> On Mon, Aug 10, 2015 at 1:54 PM, Lee Jones <lee.jones at linaro.org> wrote:
> > On Mon, 10 Aug 2015, Jassi Brar wrote:
> >> On Mon, Jul 27, 2015 at 3:14 PM, Lee Jones <lee.jones at linaro.org> wrote:
> >> > This header is currently only used for defines pertaining to data
> >> > direction i.e. Rx, Tx or Loopback.
> >> >
> >> > Signed-off-by: Lee Jones <lee.jones at linaro.org>
> >> > ---
> >> >  include/dt-bindings/mailbox/mailbox.h | 14 ++++++++++++++
> >> >  1 file changed, 14 insertions(+)
> >> >  create mode 100644 include/dt-bindings/mailbox/mailbox.h
> >> >
> >> > diff --git a/include/dt-bindings/mailbox/mailbox.h b/include/dt-bindings/mailbox/mailbox.h
> >> > new file mode 100644
> >> > index 0000000..82e929a
> >> > --- /dev/null
> >> > +++ b/include/dt-bindings/mailbox/mailbox.h
> >> > @@ -0,0 +1,14 @@
> >> > +/*
> >> > + * 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.
> >> > + */
> >> > +
> >> > +#ifndef __MAILBOX_CONTROLLER_DT_BINDINGS_H
> >> > +#define __MAILBOX_CONTROLLER_DT_BINDINGS_H
> >> > +
> >> > +#define MBOX_TX                0x1
> >> > +#define MBOX_RX                0x2
> >> > +#define MBOX_LOOPBACK  (MBOX_RX | MBOX_TX)
> >> > +
> >> Not sure I understand 'loopback'.  Does it mean h/w has some
> >> 'loopback' mode for testing purposes? Or it simply means the
> >> controller can send as well as receive messages?
> >
> > 'loopback' allows firmware to conduct some early function tests.
> > However, channels are simplex, so we provide protection against
> > multiple allocation of single channel.  By allocating a LOOPBACK
> > channel we over-ride this protection and allow a single channel to be
> > allocated twice, once for Rx and the other for Tx.
> >
> So basically hardware is half-duplex, not simplex. I think maybe you
> should simply allow for RX and TX always. It should work. Just
> handover any received data before send_data (reflecting the h/w
> limitation). That way you don't need any such special flag.

Unfortunately no, that's not correct.  Only Mailbox 0 is half-duplex.
The others are simplex (Rx only).  Ideally I'd like to keep the
LOOPBACK flag, as it's easier to figure out if what someone is
attempting to do is actually valid.  It is only ever used for
'loopback' testing anyway, so it's a perfectly reasonable
description of the channel configuration.

-- 
Lee Jones
Linaro STMicroelectronics Landing Team Lead
Linaro.org ? Open source software for ARM SoCs
Follow Linaro: Facebook | Twitter | Blog


From srinivas.kandagatla at linaro.org  Wed Aug 12 02:00:22 2015
From: srinivas.kandagatla at linaro.org (Srinivas Kandagatla)
Date: Wed, 12 Aug 2015 10:00:22 +0100
Subject: [PATCH 5/9] clk: qcom: gcc-msm8960: add child devices support.
In-Reply-To: <20150811224902.GO2839@codeaurora.org>
References: <1436348838-22671-1-git-send-email-rnayak@codeaurora.org>
 <1436348838-22671-6-git-send-email-rnayak@codeaurora.org>
 <20150811224902.GO2839@codeaurora.org>
Message-ID: <55CB0B26.2020105@linaro.org>



On 11/08/15 23:49, Stephen Boyd wrote:
> On 07/08, Rajendra Nayak wrote:
>> diff --git a/drivers/clk/qcom/gcc-msm8960.c b/drivers/clk/qcom/gcc-msm8960.c
>> index eb6a4f9..2c80d03 100644
>> --- a/drivers/clk/qcom/gcc-msm8960.c
>> +++ b/drivers/clk/qcom/gcc-msm8960.c
>> @@ -15,6 +15,7 @@
>>   #include <linux/bitops.h>
>>   #include <linux/err.h>
>>   #include <linux/platform_device.h>
>> +#include <linux/of_platform.h>
>>   #include <linux/module.h>
>>   #include <linux/of.h>
>>   #include <linux/of_device.h>
>> @@ -3520,7 +3521,8 @@ static int gcc_msm8960_probe(struct platform_device *pdev)
>>   	if (IS_ERR(clk))
>>   		return PTR_ERR(clk);
>>
>> -	return qcom_cc_probe(pdev, match->data);
>> +	qcom_cc_probe(pdev, match->data);
>> +	return of_platform_populate(pdev->dev.of_node, NULL, NULL, &pdev->dev);
>
> We just lost the error code from qcom_cc_probe()...
>
I think Rajendra picked up the wrong patch for this series, I did submit 
a v2 (https://patches.linaro.org/44033/) with the above fixed.

> Also, I don't like having a subnode in DT. Why can't we use the
> same node as the GCC node and create a virtual child device here
> for tsens? We can assign the same of_node that this platform
> device has so that DT keeps working correctly.

I don't mind either way, if that makes things moving :-)

--srini
>


From eric.auger at linaro.org  Wed Aug 12 02:01:52 2015
From: eric.auger at linaro.org (Eric Auger)
Date: Wed, 12 Aug 2015 11:01:52 +0200
Subject: [PATCH v2 01/15] KVM: arm/arm64: VGIC: don't track used LRs in
 the distributor
In-Reply-To: <1436538111-4294-2-git-send-email-andre.przywara@arm.com>
References: <1436538111-4294-1-git-send-email-andre.przywara@arm.com>
 <1436538111-4294-2-git-send-email-andre.przywara@arm.com>
Message-ID: <55CB0B80.5040508@linaro.org>

Hi Andre,
On 07/10/2015 04:21 PM, Andre Przywara wrote:
> Currently we track which IRQ has been mapped to which VGIC list
> register and also have to synchronize both. We used to do this
> to hold some extra state (for instance the active bit).
> It turns out that this extra state in the LRs is no longer needed and
> this extra tracking causes some pain later.
> Remove the tracking feature (lr_map and lr_used) and get rid of
> quite some code on the way.
> On a guest exit we pick up all still pending IRQs from the LRs and put
> them back in the distributor. We don't care about active-only IRQs,
> so we keep them in the LRs. They will be retired either by our
> vgic_process_maintenance() routine or by the GIC hardware in case of
> edge triggered interrupts.
> In places where we scan LRs we now use our shadow copy of the ELRSR
> register directly.
> This code change means we lose the "piggy-back" optimization, which
> would re-use an active-only LR to inject the pending state on top of
> it. Tracing with various workloads shows that this actually occurred
> very rarely, the ballpark figure is about once every 10,000 exits
> in a disk I/O heavy workload. Also the list registers don't seem to
> as scarce as assumed, with all 4 LRs on the popular implementations
> used less than once every 100,000 exits.
> 
> This has been briefly tested on Midway, Juno and the model (the latter
> both with GICv2 and GICv3 guests).
> 
> Signed-off-by: Andre Przywara <andre.przywara at arm.com>
> ---
>  include/kvm/arm_vgic.h |   6 ---
>  virt/kvm/arm/vgic-v2.c |   1 +
>  virt/kvm/arm/vgic-v3.c |   1 +
>  virt/kvm/arm/vgic.c    | 143 ++++++++++++++++++++++---------------------------
>  4 files changed, 66 insertions(+), 85 deletions(-)
> 
> diff --git a/include/kvm/arm_vgic.h b/include/kvm/arm_vgic.h
> index 133ea00..2ccfa9a 100644
> --- a/include/kvm/arm_vgic.h
> +++ b/include/kvm/arm_vgic.h
> @@ -279,9 +279,6 @@ struct vgic_v3_cpu_if {
>  };
>  
>  struct vgic_cpu {
> -	/* per IRQ to LR mapping */
> -	u8		*vgic_irq_lr_map;
> -
>  	/* Pending/active/both interrupts on this VCPU */
>  	DECLARE_BITMAP(	pending_percpu, VGIC_NR_PRIVATE_IRQS);
>  	DECLARE_BITMAP(	active_percpu, VGIC_NR_PRIVATE_IRQS);
> @@ -292,9 +289,6 @@ struct vgic_cpu {
>  	unsigned long   *active_shared;
>  	unsigned long   *pend_act_shared;
>  
> -	/* Bitmap of used/free list registers */
> -	DECLARE_BITMAP(	lr_used, VGIC_V2_MAX_LRS);
> -
>  	/* Number of list registers on this CPU */
>  	int		nr_lr;
>  
> diff --git a/virt/kvm/arm/vgic-v2.c b/virt/kvm/arm/vgic-v2.c
> index f9b9c7c..f723710 100644
> --- a/virt/kvm/arm/vgic-v2.c
> +++ b/virt/kvm/arm/vgic-v2.c
> @@ -144,6 +144,7 @@ static void vgic_v2_enable(struct kvm_vcpu *vcpu)
>  	 * anyway.
>  	 */
>  	vcpu->arch.vgic_cpu.vgic_v2.vgic_vmcr = 0;
> +	vcpu->arch.vgic_cpu.vgic_v2.vgic_elrsr = ~0;
>  
>  	/* Get the show on the road... */
>  	vcpu->arch.vgic_cpu.vgic_v2.vgic_hcr = GICH_HCR_EN;
> diff --git a/virt/kvm/arm/vgic-v3.c b/virt/kvm/arm/vgic-v3.c
> index dff0602..21e5d28 100644
> --- a/virt/kvm/arm/vgic-v3.c
> +++ b/virt/kvm/arm/vgic-v3.c
> @@ -178,6 +178,7 @@ static void vgic_v3_enable(struct kvm_vcpu *vcpu)
>  	 * anyway.
>  	 */
>  	vgic_v3->vgic_vmcr = 0;
> +	vgic_v3->vgic_elrsr = ~0;
>  
>  	/*
>  	 * If we are emulating a GICv3, we do it in an non-GICv2-compatible
> diff --git a/virt/kvm/arm/vgic.c b/virt/kvm/arm/vgic.c
> index bc40137..394622c 100644
> --- a/virt/kvm/arm/vgic.c
> +++ b/virt/kvm/arm/vgic.c
> @@ -79,7 +79,6 @@
>  #include "vgic.h"
>  
>  static void vgic_retire_disabled_irqs(struct kvm_vcpu *vcpu);
> -static void vgic_retire_lr(int lr_nr, int irq, struct kvm_vcpu *vcpu);
>  static struct vgic_lr vgic_get_lr(const struct kvm_vcpu *vcpu, int lr);
>  static void vgic_set_lr(struct kvm_vcpu *vcpu, int lr, struct vgic_lr lr_desc);
>  
> @@ -647,6 +646,17 @@ bool vgic_handle_cfg_reg(u32 *reg, struct kvm_exit_mmio *mmio,
>  	return false;
>  }
>  
> +static void vgic_sync_lr_elrsr(struct kvm_vcpu *vcpu, int lr,
> +			       struct vgic_lr vlr)
> +{
> +	vgic_ops->sync_lr_elrsr(vcpu, lr, vlr);
> +}
why not renaming this into vgic_set_elrsr. This would be homogeneous
with other virtual interface control register setters?
> +
> +static inline u64 vgic_get_elrsr(struct kvm_vcpu *vcpu)
> +{
> +	return vgic_ops->get_elrsr(vcpu);
> +}
If I am not wrong, each time you manipulate the elrsr you handle the
bitmap. why not directly returning an unsigned long * then (elrsr_ptr)?
> +
>  /**
>   * vgic_unqueue_irqs - move pending/active IRQs from LRs to the distributor
>   * @vgic_cpu: Pointer to the vgic_cpu struct holding the LRs
> @@ -658,9 +668,11 @@ bool vgic_handle_cfg_reg(u32 *reg, struct kvm_exit_mmio *mmio,
>  void vgic_unqueue_irqs(struct kvm_vcpu *vcpu)
>  {
>  	struct vgic_cpu *vgic_cpu = &vcpu->arch.vgic_cpu;
> +	u64 elrsr = vgic_get_elrsr(vcpu);
> +	unsigned long *elrsr_ptr = u64_to_bitmask(&elrsr);
>  	int i;
>  
> -	for_each_set_bit(i, vgic_cpu->lr_used, vgic_cpu->nr_lr) {
> +	for_each_clear_bit(i, elrsr_ptr, vgic_cpu->nr_lr) {
>  		struct vgic_lr lr = vgic_get_lr(vcpu, i);
>  
>  		/*
> @@ -703,7 +715,7 @@ void vgic_unqueue_irqs(struct kvm_vcpu *vcpu)
>  		 * Mark the LR as free for other use.
>  		 */
>  		BUG_ON(lr.state & LR_STATE_MASK);
> -		vgic_retire_lr(i, lr.irq, vcpu);
> +		vgic_sync_lr_elrsr(vcpu, i, lr);
>  		vgic_irq_clear_queued(vcpu, lr.irq);
>  
>  		/* Finally update the VGIC state. */
> @@ -1011,17 +1023,6 @@ static void vgic_set_lr(struct kvm_vcpu *vcpu, int lr,
>  	vgic_ops->set_lr(vcpu, lr, vlr);
>  }
>  
> -static void vgic_sync_lr_elrsr(struct kvm_vcpu *vcpu, int lr,
> -			       struct vgic_lr vlr)
> -{
> -	vgic_ops->sync_lr_elrsr(vcpu, lr, vlr);
> -}
> -
> -static inline u64 vgic_get_elrsr(struct kvm_vcpu *vcpu)
> -{
> -	return vgic_ops->get_elrsr(vcpu);
> -}
> -
>  static inline u64 vgic_get_eisr(struct kvm_vcpu *vcpu)
>  {
>  	return vgic_ops->get_eisr(vcpu);
> @@ -1062,18 +1063,6 @@ static inline void vgic_enable(struct kvm_vcpu *vcpu)
>  	vgic_ops->enable(vcpu);
>  }
>  
> -static void vgic_retire_lr(int lr_nr, int irq, struct kvm_vcpu *vcpu)
> -{
> -	struct vgic_cpu *vgic_cpu = &vcpu->arch.vgic_cpu;
> -	struct vgic_lr vlr = vgic_get_lr(vcpu, lr_nr);
> -
> -	vlr.state = 0;
> -	vgic_set_lr(vcpu, lr_nr, vlr);
> -	clear_bit(lr_nr, vgic_cpu->lr_used);
> -	vgic_cpu->vgic_irq_lr_map[irq] = LR_EMPTY;
> -	vgic_sync_lr_elrsr(vcpu, lr_nr, vlr);
> -}
> -
>  /*
>   * An interrupt may have been disabled after being made pending on the
>   * CPU interface (the classic case is a timer running while we're
> @@ -1085,23 +1074,32 @@ static void vgic_retire_lr(int lr_nr, int irq, struct kvm_vcpu *vcpu)
>   */
>  static void vgic_retire_disabled_irqs(struct kvm_vcpu *vcpu)
>  {
> -	struct vgic_cpu *vgic_cpu = &vcpu->arch.vgic_cpu;
> +	u64 elrsr = vgic_get_elrsr(vcpu);
> +	unsigned long *elrsr_ptr = u64_to_bitmask(&elrsr);
if you agree with above modif I would simply rename elrsr_ptr into elrsr.
>  	int lr;
> +	struct vgic_lr vlr;
why moving this declaration here. I think this can remain in the block.
>  
> -	for_each_set_bit(lr, vgic_cpu->lr_used, vgic->nr_lr) {
> -		struct vgic_lr vlr = vgic_get_lr(vcpu, lr);
> +	for_each_clear_bit(lr, elrsr_ptr, vgic->nr_lr) {
> +		vlr = vgic_get_lr(vcpu, lr);
>  
>  		if (!vgic_irq_is_enabled(vcpu, vlr.irq)) {
> -			vgic_retire_lr(lr, vlr.irq, vcpu);
> -			if (vgic_irq_is_queued(vcpu, vlr.irq))
> -				vgic_irq_clear_queued(vcpu, vlr.irq);
> +			vlr.state = 0;
> +			vgic_set_lr(vcpu, lr, vlr);
> +			vgic_sync_lr_elrsr(vcpu, lr, vlr);
vgic_set_elrsr?

the "if (vgic_irq_is_queued(vcpu, vlr.irq))" check disappeared. This
change might be introduced separately.
> +			vgic_irq_clear_queued(vcpu, vlr.irq);
>  		}
>  	}
>  }
>  
>  static void vgic_queue_irq_to_lr(struct kvm_vcpu *vcpu, int irq,
> -				 int lr_nr, struct vgic_lr vlr)
I don't think this change of proto is compatible with Marc's "KVM:
arm/arm64: vgic: Allow HW interrupts to be queued to a guest".
I think we need to keep former signature.
> +				 int lr_nr, int sgi_source_id)
>  {
> +	struct vgic_lr vlr;
> +
> +	vlr.state = 0;
> +	vlr.irq = irq;
> +	vlr.source = sgi_source_id;
> +
>  	if (vgic_irq_is_active(vcpu, irq)) {
>  		vlr.state |= LR_STATE_ACTIVE;
>  		kvm_debug("Set active, clear distributor: 0x%x\n", vlr.state);
> @@ -1126,9 +1124,9 @@ static void vgic_queue_irq_to_lr(struct kvm_vcpu *vcpu, int irq,
>   */
>  bool vgic_queue_irq(struct kvm_vcpu *vcpu, u8 sgi_source_id, int irq)
>  {
> -	struct vgic_cpu *vgic_cpu = &vcpu->arch.vgic_cpu;
>  	struct vgic_dist *dist = &vcpu->kvm->arch.vgic;
> -	struct vgic_lr vlr;
> +	u64 elrsr = vgic_get_elrsr(vcpu);
> +	unsigned long *elrsr_ptr = u64_to_bitmask(&elrsr);
>  	int lr;
>  
>  	/* Sanitize the input... */
> @@ -1138,42 +1136,20 @@ bool vgic_queue_irq(struct kvm_vcpu *vcpu, u8 sgi_source_id, int irq)
>  
>  	kvm_debug("Queue IRQ%d\n", irq);
>  
> -	lr = vgic_cpu->vgic_irq_lr_map[irq];
> -
> -	/* Do we have an active interrupt for the same CPUID? */
> -	if (lr != LR_EMPTY) {
> -		vlr = vgic_get_lr(vcpu, lr);
> -		if (vlr.source == sgi_source_id) {
> -			kvm_debug("LR%d piggyback for IRQ%d\n", lr, vlr.irq);
> -			BUG_ON(!test_bit(lr, vgic_cpu->lr_used));
> -			vgic_queue_irq_to_lr(vcpu, irq, lr, vlr);
> -			return true;
> -		}
> -	}
> +	lr = find_first_bit(elrsr_ptr, vgic->nr_lr);
>  
> -	/* Try to use another LR for this interrupt */
> -	lr = find_first_zero_bit((unsigned long *)vgic_cpu->lr_used,
> -			       vgic->nr_lr);
>  	if (lr >= vgic->nr_lr)
>  		return false;
>  
>  	kvm_debug("LR%d allocated for IRQ%d %x\n", lr, irq, sgi_source_id);
> -	vgic_cpu->vgic_irq_lr_map[irq] = lr;
> -	set_bit(lr, vgic_cpu->lr_used);
>  
> -	vlr.irq = irq;
> -	vlr.source = sgi_source_id;
> -	vlr.state = 0;
> -	vgic_queue_irq_to_lr(vcpu, irq, lr, vlr);
> +	vgic_queue_irq_to_lr(vcpu, irq, lr, sgi_source_id);
>  
>  	return true;
>  }
>  
>  static bool vgic_queue_hwirq(struct kvm_vcpu *vcpu, int irq)
>  {
> -	if (!vgic_can_sample_irq(vcpu, irq))
> -		return true; /* level interrupt, already queued */
> -
I think that change needs to be introduced in a separate patch as the
other one mentioned above and justified since it affects the state machine.

Best Regards

Eric
>  	if (vgic_queue_irq(vcpu, 0, irq)) {
>  		if (vgic_irq_is_edge(vcpu, irq)) {
>  			vgic_dist_irq_clear_pending(vcpu, irq);
> @@ -1346,29 +1322,44 @@ static void __kvm_vgic_sync_hwstate(struct kvm_vcpu *vcpu)
>  	struct vgic_dist *dist = &vcpu->kvm->arch.vgic;
>  	u64 elrsr;
>  	unsigned long *elrsr_ptr;
> -	int lr, pending;
> -	bool level_pending;
> +	struct vgic_lr vlr;
> +	int lr_nr;
> +	bool pending;
> +
> +	pending = vgic_process_maintenance(vcpu);
>  
> -	level_pending = vgic_process_maintenance(vcpu);
>  	elrsr = vgic_get_elrsr(vcpu);
>  	elrsr_ptr = u64_to_bitmask(&elrsr);
>  
> -	/* Clear mappings for empty LRs */
> -	for_each_set_bit(lr, elrsr_ptr, vgic->nr_lr) {
> -		struct vgic_lr vlr;
> +	for_each_clear_bit(lr_nr, elrsr_ptr, vgic_cpu->nr_lr) {
> +		vlr = vgic_get_lr(vcpu, lr_nr);
> +
> +		BUG_ON(!(vlr.state & LR_STATE_MASK));
> +		pending = true;
>  
> -		if (!test_and_clear_bit(lr, vgic_cpu->lr_used))
> +		/* Reestablish SGI source for pending and active SGIs */
> +		if (vlr.irq < VGIC_NR_SGIS)
> +			add_sgi_source(vcpu, vlr.irq, vlr.source);
> +
> +		/*
> +		 * If the LR holds a pure active (10) interrupt then keep it
> +		 * in the LR without mirroring this status in the emulation.
> +		 */
> +		if (vlr.state == LR_STATE_ACTIVE)
>  			continue;
>  
> -		vlr = vgic_get_lr(vcpu, lr);
> +		if (vlr.state & LR_STATE_PENDING)
> +			vgic_dist_irq_set_pending(vcpu, vlr.irq);
>  
> -		BUG_ON(vlr.irq >= dist->nr_irqs);
> -		vgic_cpu->vgic_irq_lr_map[vlr.irq] = LR_EMPTY;
> +		/* Mark this LR as empty now. */
> +		vlr.state = 0;
> +		vgic_set_lr(vcpu, lr_nr, vlr);
> +		vgic_sync_lr_elrsr(vcpu, lr_nr, vlr);
>  	}
> +	vgic_update_state(vcpu->kvm);
>  
> -	/* Check if we still have something up our sleeve... */
> -	pending = find_first_zero_bit(elrsr_ptr, vgic->nr_lr);
> -	if (level_pending || pending < vgic->nr_lr)
> +	/* vgic_update_state would not cover only-active IRQs */
> +	if (pending)
>  		set_bit(vcpu->vcpu_id, dist->irq_pending_on_cpu);
>  }
>  
> @@ -1590,11 +1581,9 @@ void kvm_vgic_vcpu_destroy(struct kvm_vcpu *vcpu)
>  	kfree(vgic_cpu->pending_shared);
>  	kfree(vgic_cpu->active_shared);
>  	kfree(vgic_cpu->pend_act_shared);
> -	kfree(vgic_cpu->vgic_irq_lr_map);
>  	vgic_cpu->pending_shared = NULL;
>  	vgic_cpu->active_shared = NULL;
>  	vgic_cpu->pend_act_shared = NULL;
> -	vgic_cpu->vgic_irq_lr_map = NULL;
>  }
>  
>  static int vgic_vcpu_init_maps(struct kvm_vcpu *vcpu, int nr_irqs)
> @@ -1605,18 +1594,14 @@ static int vgic_vcpu_init_maps(struct kvm_vcpu *vcpu, int nr_irqs)
>  	vgic_cpu->pending_shared = kzalloc(sz, GFP_KERNEL);
>  	vgic_cpu->active_shared = kzalloc(sz, GFP_KERNEL);
>  	vgic_cpu->pend_act_shared = kzalloc(sz, GFP_KERNEL);
> -	vgic_cpu->vgic_irq_lr_map = kmalloc(nr_irqs, GFP_KERNEL);
>  
>  	if (!vgic_cpu->pending_shared
>  		|| !vgic_cpu->active_shared
> -		|| !vgic_cpu->pend_act_shared
> -		|| !vgic_cpu->vgic_irq_lr_map) {
> +		|| !vgic_cpu->pend_act_shared) {
>  		kvm_vgic_vcpu_destroy(vcpu);
>  		return -ENOMEM;
>  	}
>  
> -	memset(vgic_cpu->vgic_irq_lr_map, LR_EMPTY, nr_irqs);
> -
>  	/*
>  	 * Store the number of LRs per vcpu, so we don't have to go
>  	 * all the way to the distributor structure to find out. Only
> 



From will.deacon at arm.com  Wed Aug 12 02:04:50 2015
From: will.deacon at arm.com (Will Deacon)
Date: Wed, 12 Aug 2015 10:04:50 +0100
Subject: [PATCH v4 1/3] PCI: generic: remove dependency on hw_pci
In-Reply-To: <007501d0d4ce$1d2dd9c0$57898d40$@samsung.com>
References: <1438721620-15493-1-git-send-email-jchandra@broadcom.com>
 <20150804234956.GF17327@google.com>
 <007501d0d4ce$1d2dd9c0$57898d40$@samsung.com>
Message-ID: <20150812090449.GA22485@arm.com>

On Wed, Aug 12, 2015 at 08:11:29AM +0100, Pavel Fedin wrote:
>  Hello!

Hi Pavel,

> > I dropped the acks and tested-by because of that change, but I'll happily
> > add them back if Lorenzo and Pavel confirm.  
> 
>  Confirm.
>  Tested-by: Pavel Fedin <p.fedin at samsung.com>
> 
>  I also added MSI support. Can i post it as patch on top of your branch?

There shouldn't be any need with the changes queued in tip/irq/core. Can
you give the following branch a go, please (it doesn't look like Bjorn's
stuff is in linux-next, unfortunately)?

  git://git.kernel.org/pub/scm/linux/kernel/git/arm64/linux.git devel

It's a temporary testing branch (subject to rebasing), but it should be
indicative of what's queued for 4.3.

Will


From linux at arm.linux.org.uk  Wed Aug 12 02:08:11 2015
From: linux at arm.linux.org.uk (Russell King - ARM Linux)
Date: Wed, 12 Aug 2015 10:08:11 +0100
Subject: [PATCH] thermal: cpu_cooling: fix lockdep problems in cpu_cooling
In-Reply-To: <20150812081142.GB16445@linux>
References: <20150812073530.GA16445@linux>
 <E1ZPQfV-0005nb-DN@rmk-PC.arm.linux.org.uk>
 <20150812081142.GB16445@linux>
Message-ID: <20150812090811.GI7557@n2100.arm.linux.org.uk>

On Wed, Aug 12, 2015 at 01:41:43PM +0530, Viresh Kumar wrote:
> On 12-08-15, 08:41, Russell King wrote:
> > diff --git a/drivers/thermal/cpu_cooling.c b/drivers/thermal/cpu_cooling.c
> >  /**
> > @@ -221,7 +224,7 @@ static int cpufreq_thermal_notifier(struct notifier_block *nb,
> >  	switch (event) {
> >  
> >  	case CPUFREQ_ADJUST:
> > -		mutex_lock(&cooling_cpufreq_lock);
> > +		mutex_lock(&cooling_list_lock);
> 
> There is one more place where the list's locking needs update:
> cpufreq_cooling_get_level().
> 
> >  		list_for_each_entry(cpufreq_dev, &cpufreq_dev_list, node) {
> >  			if (!cpumask_test_cpu(policy->cpu,
> >  					      &cpufreq_dev->allowed_cpus))
> > @@ -233,7 +236,7 @@ static int cpufreq_thermal_notifier(struct notifier_block *nb,
> >  				cpufreq_verify_within_limits(policy, 0,
> >  							     max_freq);
> >  		}
> > -		mutex_unlock(&cooling_cpufreq_lock);
> > +		mutex_unlock(&cooling_list_lock);
> >  		break;
> >  	default:
> >  		return NOTIFY_DONE;
> > @@ -865,12 +868,15 @@ __cpufreq_cooling_register(struct device_node *np,
> >  	cpufreq_dev->cool_dev = cool_dev;
> >  
> >  	mutex_lock(&cooling_cpufreq_lock);
> > +	mutex_lock(&cooling_list_lock);
> 
> Why is the list lock taken from within the existing lock here? and ...

To preserve the behaviour of the code, which is to atomically add to
the list and register the notifier.

> > +	list_add(&cpufreq_dev->node, &cpufreq_dev_list);
> > +	mutex_unlock(&cooling_list_lock);
> >  
> >  	/* Register the notifier for first cpufreq cooling device */
> > -	if (list_empty(&cpufreq_dev_list))
> > +	if (cpufreq_dev_count == 0)
> >  		cpufreq_register_notifier(&thermal_cpufreq_notifier_block,
> >  					  CPUFREQ_POLICY_NOTIFIER);
> > -	list_add(&cpufreq_dev->node, &cpufreq_dev_list);
> > +	cpufreq_dev_count++;
> 
> Maybe:
>         if (!cpufreq_dev_count++)
>                 cpufreq_register_notifier();

Possibly, had the code previously been like that.  See:

commit 2479bb6443d6a793f896219a34bfab0cc410f0b4
Author: Viresh Kumar <viresh.kumar at linaro.org>
Date:   Thu Dec 4 09:42:04 2014 +0530

which post-dates this patch, and removes this "style" in favour of using
the broken list mechanism.  Frankly... you don't have a leg to stand on
because _you_ knew about this problem, and you saw my patch.  So removing
something that my patch to fix a serious bug relied upon...

You know what?  At this point, I'm just not going to bother.  You fix
this lockdep problem, I'm obviously useless at kernel stuff.

-- 
FTTC broadband for 0.8mile line: currently at 10.5Mbps down 400kbps up
according to speedtest.net.


From linux at arm.linux.org.uk  Wed Aug 12 02:08:57 2015
From: linux at arm.linux.org.uk (Russell King - ARM Linux)
Date: Wed, 12 Aug 2015 10:08:57 +0100
Subject: 3.18: lockdep problems in cpufreq
In-Reply-To: <20150812081257.GC16445@linux>
References: <20141214213655.GA11285@n2100.arm.linux.org.uk>
 <CAKohponhkk9BK6-7ScHeZa4R43iooWQFV8YoPLv6LjO40GNq=A@mail.gmail.com>
 <20150518185645.GA28053@n2100.arm.linux.org.uk>
 <2574268.XBqpdL2VLI@vostro.rjw.lan>
 <20150811170357.GA24529@n2100.arm.linux.org.uk>
 <20150812051659.GI32049@linux>
 <20150812072129.GD7557@n2100.arm.linux.org.uk>
 <20150812073530.GA16445@linux>
 <20150812074925.GG7557@n2100.arm.linux.org.uk>
 <20150812081257.GC16445@linux>
Message-ID: <20150812090857.GJ7557@n2100.arm.linux.org.uk>

On Wed, Aug 12, 2015 at 01:42:57PM +0530, Viresh Kumar wrote:
> On 12-08-15, 08:49, Russell King - ARM Linux wrote:
> > The problem will be back-porting it to stable kernels, because I think
> > it's had to be updated at least a couple of times.  I don't have the old
> > versions anymore, so I'm just going to say "not my problem" - sorry.
> 
> Your old 3.18 version :)

And now generate versions for all the stable kernels inbetween.  Now
your problem.  I'm sick of this.

-- 
FTTC broadband for 0.8mile line: currently at 10.5Mbps down 400kbps up
according to speedtest.net.


From lorenzo.pieralisi at arm.com  Wed Aug 12 02:15:51 2015
From: lorenzo.pieralisi at arm.com (Lorenzo Pieralisi)
Date: Wed, 12 Aug 2015 10:15:51 +0100
Subject: [PATCH v4 1/3] PCI: generic: remove dependency on hw_pci
In-Reply-To: <20150804234956.GF17327@google.com>
References: <1438721620-15493-1-git-send-email-jchandra@broadcom.com>
 <20150804234956.GF17327@google.com>
Message-ID: <20150812091551.GA23483@red-moon>

On Wed, Aug 05, 2015 at 12:49:56AM +0100, Bjorn Helgaas wrote:
> On Wed, Aug 05, 2015 at 02:23:38AM +0530, Jayachandran C wrote:
> > The current code in pci-host-generic.c uses pci_common_init_dev()
> > from arm architecture to do some part of the PCI setup, and this
> > prevents it from being used with arm64 architecture.
> > 
> > The part of pci_common_init_dev() that is really needed by
> > pci-host-generic.c is very limited and can be done in the same
> > file without using hw_pci API of ARM. The ARM platform requires
> > a pci_sys_data as sysdata for the PCI bus, this can be handled by
> > setting up gen_pci to have a pci_sys_data variable as the first
> > element.
> > 
> > Signed-off-by: Jayachandran C <jchandra at broadcom.com>
> > Acked-by: Lorenzo Pieralisi <lorenzo.pieralisi at arm.com>
> > Tested-by: Lorenzo Pieralisi <lorenzo.pieralisi at arm.com>
> > Tested-by: Pavel Fedin <p.fedin at samsung.com>
> 
> I applied all three of these to my pci/enumeration branch for v4.3.
> 
> I made a few changes, the most important being to call
> pcie_bus_configure_settings() before pci_bus_add_devices(), because drivers
> may claim devices in pci_bus_add_devices(), and the PCI core shouldn't
> touch devices after drivers claim them.
> 
> I dropped the acks and tested-by because of that change, but I'll happily
> add them back if Lorenzo and Pavel confirm.  The patches are here if you
> want to review/test them:
> 
> https://git.kernel.org/cgit/linux/kernel/git/helgaas/pci.git/log/?h=pci/enumeration
> 

I am happy with your changes so you can certainly add my acked-by/tested-by
tags back, with thanks.

Thank you !
Lorenzo

> I'm sure the other patches on that branch will need some tweaks, too, so I
> don't have any problem with updating these.


From viresh.kumar at linaro.org  Wed Aug 12 02:18:03 2015
From: viresh.kumar at linaro.org (Viresh Kumar)
Date: Wed, 12 Aug 2015 14:48:03 +0530
Subject: [PATCH] thermal: cpu_cooling: fix lockdep problems in cpu_cooling
In-Reply-To: <20150812090811.GI7557@n2100.arm.linux.org.uk>
References: <20150812073530.GA16445@linux>
 <E1ZPQfV-0005nb-DN@rmk-PC.arm.linux.org.uk>
 <20150812081142.GB16445@linux>
 <20150812090811.GI7557@n2100.arm.linux.org.uk>
Message-ID: <20150812091803.GG16445@linux>

On 12-08-15, 10:08, Russell King - ARM Linux wrote:
> Possibly, had the code previously been like that.  See:
> 
> commit 2479bb6443d6a793f896219a34bfab0cc410f0b4
> Author: Viresh Kumar <viresh.kumar at linaro.org>
> Date:   Thu Dec 4 09:42:04 2014 +0530
> 
> which post-dates this patch, and removes this "style" in favour of using
> the broken list mechanism.

Just to make sure I understand it properly, do you want to say that I
added 2479bb6 patch after you reported this problem & your patch?

If yes, then I don't see how my patch came after yours. Mine was
written on 4/Dec/2014 and committed on 8/Dec/2014 and you first
reported the problem on 14/Dec/2014.

> Frankly... you don't have a leg to stand on

I can accept that :)

> because _you_ knew about this problem, and you saw my patch.  So removing
> something that my patch to fix a serious bug relied upon...

I don't think I removed that stuff after your patch.

> You know what?  At this point, I'm just not going to bother.  You fix
> this lockdep problem, I'm obviously useless at kernel stuff.

Okay, leave it on me. I will re-circulate your patch.

-- 
viresh


From wens at csie.org  Wed Aug 12 02:18:14 2015
From: wens at csie.org (Chen-Yu Tsai)
Date: Wed, 12 Aug 2015 17:18:14 +0800
Subject: [linux-sunxi] [PATCH] pinctrl: sun4i: add spdif to pin
 description.
In-Reply-To: <CAEKpxB=UQYEnwXYAzMZA4noR9Xg8wnSjD+H0bNO5GV3dtZQtTg@mail.gmail.com>
References: <1439309965-9530-1-git-send-email-codekipper@gmail.com>
 <CAGb2v64Ptt5NgeicsYtiR8At+K4aDd3Lb3U4kijQ5UM+UafSrA@mail.gmail.com>
 <CAEKpxBmS6YJMjREc3gmeSQOzBXFKw=Sb-xPK57oUn6BtmASErg@mail.gmail.com>
 <55CB051D.3090109@redhat.com>
 <CAEKpxB=UQYEnwXYAzMZA4noR9Xg8wnSjD+H0bNO5GV3dtZQtTg@mail.gmail.com>
Message-ID: <CAGb2v64A+T1aE622uvW6nCmJACWrtLVaLRfoLgh=CppGDrEX2A@mail.gmail.com>

On Wed, Aug 12, 2015 at 5:13 PM, Code Kipper <codekipper at gmail.com> wrote:
> On 12 August 2015 at 10:34, Hans de Goede <hdegoede at redhat.com> wrote:
>>
>> Hi,
>>
>>
>> On 12-08-15 07:31, Code Kipper wrote:
>>>
>>> On 11 August 2015 at 18:48, Chen-Yu Tsai <wens at csie.org> wrote:
>>>
>>>> On Wed, Aug 12, 2015 at 12:19 AM,  <codekipper at gmail.com> wrote:
>>>>>
>>>>> From: Marcus Cooper <codekipper at gmail.com>
>>>>>
>>>>> Signed-off-by: Marcus Cooper <codekipper at gmail.com>
>>>>> ---
>>>>>   drivers/pinctrl/sunxi/pinctrl-sun4i-a10.c | 9 ++++++---
>>>>>   1 file changed, 6 insertions(+), 3 deletions(-)
>>>>>
>>>>> diff --git a/drivers/pinctrl/sunxi/pinctrl-sun4i-a10.c
>>>>
>>>> b/drivers/pinctrl/sunxi/pinctrl-sun4i-a10.c
>>>>>
>>>>> index 7376a97..daf7dec 100644
>>>>> --- a/drivers/pinctrl/sunxi/pinctrl-sun4i-a10.c
>>>>> +++ b/drivers/pinctrl/sunxi/pinctrl-sun4i-a10.c
>>>>> @@ -135,7 +135,8 @@ static const struct sunxi_desc_pin sun4i_a10_pins[]
>>>>
>>>> = {
>>>>>
>>>>>          SUNXI_PIN(SUNXI_PINCTRL_PIN(B, 3),
>>>>>                    SUNXI_FUNCTION(0x0, "gpio_in"),
>>>>>                    SUNXI_FUNCTION(0x1, "gpio_out"),
>>>>> -                 SUNXI_FUNCTION(0x2, "ir0")),          /* TX */
>>>>> +                 SUNXI_FUNCTION(0x2, "ir0"),           /* TX */
>>>>> +                 SUNXI_FUNCTION(0x4, "spdif")),        /* MCLK */
>>>>>          SUNXI_PIN(SUNXI_PINCTRL_PIN(B, 4),
>>>>>                    SUNXI_FUNCTION(0x0, "gpio_in"),
>>>>>                    SUNXI_FUNCTION(0x1, "gpio_out"),
>>>>> @@ -176,11 +177,13 @@ static const struct sunxi_desc_pin
>>>>
>>>> sun4i_a10_pins[] = {
>>>>>
>>>>>                    SUNXI_FUNCTION(0x0, "gpio_in"),
>>>>>                    SUNXI_FUNCTION(0x1, "gpio_out"),
>>>>>                    SUNXI_FUNCTION(0x2, "i2s"),           /* DI */
>>>>> -                 SUNXI_FUNCTION(0x3, "ac97")),         /* DI */
>>>>> +                 SUNXI_FUNCTION(0x3, "ac97"),          /* DI */
>>>>> +                 SUNXI_FUNCTION(0x4, "spdif")),        /* DI */
>>>>>          SUNXI_PIN(SUNXI_PINCTRL_PIN(B, 13),
>>>>>                    SUNXI_FUNCTION(0x0, "gpio_in"),
>>>>>                    SUNXI_FUNCTION(0x1, "gpio_out"),
>>>>> -                 SUNXI_FUNCTION(0x2, "spi2")),         /* CS1 */
>>>>> +                 SUNXI_FUNCTION(0x2, "spi2"),          /* CS1 */
>>>>> +                 SUNXI_FUNCTION(0x4, "spdif")),        /* DO */
>>>>
>>>>
>>>> The datasheet and manual list them as NC or Reserved. Maybe mention how
>>>> you knew
>>>> they were available?
>>>>
>>> Not sure if this deserves to be in the commit message but I can
>>> definitely
>>> put together a covering letter with links etc.
>>
>>
>> I dear to say it belongs right there in the source code, use a multi-line
>> comment above the SUNXI_FUNCTION(0x4, "spdif")) to explain where the mux
>> info comes from. someday sooner or later someone is going to compare the
>> kernel mux table to the datasheet and think "huh, that is not right",
>> that person will be saved an immense amount of time by simply having a
>> comment there.
>
> Good point I was thinking something along the lines of this
> /*
>  * The SPDIF block is not referenced at all in the A10 user
>  * manual. However it is described in the code leaked and the
>  * pin descriptions are declared in the A20 user manual which
>  * is pin compatible with this device.
>  */
> Thing is do I add this above every spdif pin, the first change(MCLK) or the
> pin most likely to be used(SPDIF DO)?

I'd say put it before the first pin, and then reference it (like
"undocumented, see the comment for pin P??? above", for the rest.

ChenYu

> Thanks,
> CK
>>
>>
>> And do NOT say that this will not happen, because I've already done
>> such a comparison once in the past.
>>
>> Regards,
>>
>> Hans
>
>


From viresh.kumar at linaro.org  Wed Aug 12 02:19:14 2015
From: viresh.kumar at linaro.org (Viresh Kumar)
Date: Wed, 12 Aug 2015 14:49:14 +0530
Subject: 3.18: lockdep problems in cpufreq
In-Reply-To: <20150812090857.GJ7557@n2100.arm.linux.org.uk>
References: <CAKohponhkk9BK6-7ScHeZa4R43iooWQFV8YoPLv6LjO40GNq=A@mail.gmail.com>
 <20150518185645.GA28053@n2100.arm.linux.org.uk>
 <2574268.XBqpdL2VLI@vostro.rjw.lan>
 <20150811170357.GA24529@n2100.arm.linux.org.uk>
 <20150812051659.GI32049@linux>
 <20150812072129.GD7557@n2100.arm.linux.org.uk>
 <20150812073530.GA16445@linux>
 <20150812074925.GG7557@n2100.arm.linux.org.uk>
 <20150812081257.GC16445@linux>
 <20150812090857.GJ7557@n2100.arm.linux.org.uk>
Message-ID: <20150812091914.GH16445@linux>

On 12-08-15, 10:08, Russell King - ARM Linux wrote:
> And now generate versions for all the stable kernels inbetween.  Now
> your problem.  I'm sick of this.

Haha.. There wouldn't be many. 3.19 got large number of changes (from
me) and so we required a newer version. But after that should be
somewhat stable.

-- 
viresh


From caschebe at techfak.uni-bielefeld.de  Wed Aug 12 02:27:35 2015
From: caschebe at techfak.uni-bielefeld.de (Christian Ascheberg)
Date: Wed, 12 Aug 2015 11:27:35 +0200
Subject: Problem with ftrace uprobes on ARM
In-Reply-To: <20150810193116.GA2895@debian>
References: <55C8E417.7080607@techfak.uni-bielefeld.de>
 <20150810193116.GA2895@debian>
Message-ID: <55CB1187.6030301@techfak.uni-bielefeld.de>

Thanks, your answer was really helpful. I did not know that Thumb 
instructions were not supported, which solved my initial problem when 
using Perf as well.

Is there any documentation regarding limitations of perf/ftrace support 
on ARM (compared to x86)?

For example, I also noticed that 'perf help' lists 'trace' command, but 
running 'perf trace' says 'is not a perf-command'.


From vigneshr at ti.com  Wed Aug 12 02:27:03 2015
From: vigneshr at ti.com (Vignesh R)
Date: Wed, 12 Aug 2015 14:57:03 +0530
Subject: [RFC PATCH 1/5] spi: introduce flag for memory mapped read
In-Reply-To: <CAOMqctScUybdoZPgqH185qzDxB=TyutDMARextHx0XwC7L3Xmw@mail.gmail.com>
References: <20150805115013.GJ20873@sirena.org.uk>
 <CAOMqctQXwcHyiWBwtugSDSE_k65qrNfrwnhjQMDJkLoJMmGzUw@mail.gmail.com>
 <20150805124412.GN20873@sirena.org.uk>
 <CAOMqctS9Y5FxpUCCJew6+cnjH5iTvbzkH3g-8yrXs4OuS2pSGA@mail.gmail.com>
 <20150806090202.GO20873@sirena.org.uk>
 <CAOMqctQZRZ4zG_yYy=CeX3DX4NVNWN1COP4Q-2YvMun9xYOA7g@mail.gmail.com>
 <20150806102225.GI7576@n2100.arm.linux.org.uk> <55C35233.2000105@ti.com>
 <20150806135129.GJ7576@n2100.arm.linux.org.uk>
 <CAMuHMdWWDwZ=ziGQXFCnOX8pErXpsEi533J73_Hh=sEqq4hR6Q@mail.gmail.com>
 <20150806213340.GK7576@n2100.arm.linux.org.uk> <55C46B84.3010304@sperl.org>
 <CAOMqctScUybdoZPgqH185qzDxB=TyutDMARextHx0XwC7L3Xmw@mail.gmail.com>
Message-ID: <55CB1167.7010804@ti.com>



On 08/07/2015 03:46 PM, Michal Suchanek wrote:
[snip]
> On 7 August 2015 at 10:35, Vignesh R <vigneshr at ti.com> wrote:
>>
>>
>> On 08/07/2015 01:08 PM, Michal Suchanek wrote:
>>
>>> Now since the description is clearer it's obvious that ti-qspi cannot
>>> work fully mmapped as fsl-qspi does because the setup has to be done
>>> over normal spi access and using non-m25p80 devices on the same bus is
>>> a requirement.
>>>
>>> The place where it is known if a transfer can use the mmap access is m25p80.c
>>>
>>> So my suggestion is
>>>
>>>  - add a new method for spi master that gets the read opcode, dummy
>>> length, address, address length, buffer, buffer length and performs
>>> read from the flash memory in a hardware-specific way
>>>
>>> - add a check in m25p80.c that the master supports this feature and if
>>> so use it (eg check that the method is non-null)
>>>
>>> Presumably if some new SPI controllers with similar feature are
>>> supported in the future they can use the same inteface because you
>>> pass on everything the m25p80 read knows.
>>>
>>
>> Ok... Do you mean something like this?
>>
>> I will take m25p80 as example but can be expanded for any flash.
>>
>> In include/linux/mtd.h:
>>         struct spi_mtd_config_info {
>>                 struct spi_device       *spi;
>>                 u32                     page_size;
>>                 u8                      addr_width;
>>                 u8                      erase_opcode;
>>                 u8                      read_opcode;
>>                 u8                      read_dummy;
>>                 u8                      program_opcode;
>>                 enum read_mode          flash_read;
>>
>>         } /* subset of struct spi_nor */
>>
> 
> I would just pass these as separate arguments to the function but whatver.
> 
>> In m25p80.c:
>>
>>         static int m25p80_read(struct spi_nor *nor, loff_t from,
>>                                 size_t len, size_t *retlen,
>>                                 u_char *buf)
>>         {
>>                 struct spi_mtd_config_info info;
>>                 struct spi_device *spi;
>>
>>                 if (spi->master->spi_mtd_mmap_read) {
>>                   /* Populate spi_mtd_config_info */
>>                   spi->master->spi_mtd_mmap_read(&info, from, len,
>>                                                  retlen, buf);
>>                 }
>>                 else {
>>                 /* no mtd specific acceleration supported try normal
>>                  * SPI way of communicating with flash
>>                  * continue with current code
>>                  * set up spi_message and call spi_sync()
>>                  */
>>         }
>>
>>       }
>>
>> In spi-ti-qspi.c:
>> Implement spi_mtd_mmap_read while holding master->bus_lock mutex.
>>
> 

I will re-submit patches based on the above idea, if there are no
further comments..

-- 
Thanks
Vignesh


From xuwei5 at hisilicon.com  Wed Aug 12 02:20:13 2015
From: xuwei5 at hisilicon.com (Wei Xu)
Date: Wed, 12 Aug 2015 10:20:13 +0100
Subject: [PATCH v4 0/4] clk: hisilicon: support stub clock
In-Reply-To: <20150812014954.GA6215@leoy-linaro>
References: <1438673249-6051-1-git-send-email-leo.yan@linaro.org>
 <20150812003817.GI26614@codeaurora.org> <20150812014954.GA6215@leoy-linaro>
Message-ID: <55CB0FCD.7050303@hisilicon.com>



On 8/12/2015 2:49 AM, Leo Yan wrote:
> Hi Stephen,
> 
> On Tue, Aug 11, 2015 at 05:38:17PM -0700, Stephen Boyd wrote:
>> On 08/04, Leo Yan wrote:
>>> This series adds support for hisilicon stub clock driver. On hi6220,
>>> the bootloader needs load the firmware image and set info for OPPs;
>>> after run into kernel, the stub clock driver is used to communicate
>>> w/t firmware for cpu dynamic frequency scaling.
>>>
>>> In patch series v1/v2, the stub clock driver simply writes request in
>>> sram and send ipc to firmware; For patch series v3, the firmware has
>>> been upgraded to use mailbox, so stub clock driver will call standard
>>> mailbox APIs to request mailbox channel and send message to firmware.
>>>
>>> Patch 4 adds stub clock node into dts and it references mailbox with
>>> phandle, so patch 4 will depend on mailbox driver's patch series [1].
>>> These patches have been tested on 96board hikey and is used by cpufreq
>>> driver.
>>
>> The To: list is everyone, so I'm not sure who is supposed to
>> apply these patches. I'd like to take patches 1, 2, and 3 through
>> the clk tree though.
> 
> Thanks, you could take first three patches. For patch 4, i will
> re-send it after mailbox driver's patches have been merged.

Hi Leo,

> Wei Xu, is this okay for you?

OK :)

Best Regards,
Wei

> 
> Thanks,
> Leo Yan
> 
> .
> 



From lee.jones at linaro.org  Wed Aug 12 02:29:00 2015
From: lee.jones at linaro.org (Lee Jones)
Date: Wed, 12 Aug 2015 10:29:00 +0100
Subject: [PATCH v4 2/2] mfd: axp20x: Add a cell for the usb power_supply
 part of the axp20x PMICs
In-Reply-To: <55CB05AD.1030707@redhat.com>
References: <1439049521-30766-1-git-send-email-hdegoede@redhat.com>
 <1439049521-30766-2-git-send-email-hdegoede@redhat.com>
 <20150811141811.GM18282@x1> <55CB05AD.1030707@redhat.com>
Message-ID: <20150812092900.GC18282@x1>

On Wed, 12 Aug 2015, Hans de Goede wrote:

> Hi,
> 
> On 11-08-15 16:18, Lee Jones wrote:
> >On Sat, 08 Aug 2015, Hans de Goede wrote:
> >
> >>Add a cell for the usb power_supply part of the axp20x PMICs.
> >>
> >>Note that this cell is only for the usb power_supply part and not the
> >>ac-power / battery-charger / rtc-backup-bat-charger bits.
> >>
> >>Depending on the board each of those must be enabled / disabled separately
> >>in devicetree as most boards do not use all 4. So in dt each one needs its
> >>own child-node of the axp20x node. Another reason for using separate child
> >>nodes for each is so that other devicetree nodes can have a power-supply
> >>property with a phandle referencing a node representing a single
> >>power-supply.
> >>
> >>The decision to use a separate devicetree node for each is reflected on
> >>the kernel side by each getting its own mfd-cell / platform_device and
> >>platform-driver.
> >>
> >>Note this commit also makes some whitespace changes to the intialization
> >>of existing cells in axp20x_cells, these are pure whitespace changes,
> >>functionally nothing changes.
> >>
> >>Cc: Bruno Pr?mont <bonbons at linux-vserver.org>
> >>Signed-off-by: Bruno Pr?mont <bonbons at linux-vserver.org>
> >>Signed-off-by: Hans de Goede <hdegoede at redhat.com>
> >>Acked-by: Maxime Ripard <maxime.ripard at free-electrons.com>
> >>Acked-by: Lee Jones <lee.jones at linaro.org>
> >>---
> >>Changes in v2:
> >>-Use DEFINE_RES_IRQ_NAMED
> >>-Change indentation of axp20x_cells initializers to avoid line wrapping
> >>Changes in v3:
> >>-Improve commit message
> >>-Add Bruno's S-o-b
> >>---
> >>  drivers/mfd/axp20x.c | 20 ++++++++++++++++----
> >>  1 file changed, 16 insertions(+), 4 deletions(-)
> >
> >Applied, thanks.
> 
> Great, but I'm not seeing this in:
> 
> https://git.kernel.org/cgit/linux/kernel/git/lee/mfd.git/log/?h=for-mfd-next

Well it does usually take me a day or two push my local branch out,
however in this case I had actually dropped a ball somewhere.  I've
been through my backlog of 'applied' patches and these two are the
only ones I failed to pick.  I have now, re-picked, re-applied and
pushed the branch out.  Let me know if something is still not right.

Sorry for the inconvenience.

> >>diff --git a/drivers/mfd/axp20x.c b/drivers/mfd/axp20x.c
> >>index d9f2f96..3f576b7 100644
> >>--- a/drivers/mfd/axp20x.c
> >>+++ b/drivers/mfd/axp20x.c
> >>@@ -140,6 +140,13 @@ static struct resource axp20x_pek_resources[] = {
> >>  	},
> >>  };
> >>
> >>+static struct resource axp20x_usb_power_supply_resources[] = {
> >>+	DEFINE_RES_IRQ_NAMED(AXP20X_IRQ_VBUS_PLUGIN, "VBUS_PLUGIN"),
> >>+	DEFINE_RES_IRQ_NAMED(AXP20X_IRQ_VBUS_REMOVAL, "VBUS_REMOVAL"),
> >>+	DEFINE_RES_IRQ_NAMED(AXP20X_IRQ_VBUS_VALID, "VBUS_VALID"),
> >>+	DEFINE_RES_IRQ_NAMED(AXP20X_IRQ_VBUS_NOT_VALID, "VBUS_NOT_VALID"),
> >>+};
> >>+
> >>  static struct resource axp22x_pek_resources[] = {
> >>  	{
> >>  		.name   = "PEK_DBR",
> >>@@ -432,11 +439,16 @@ static const struct regmap_irq_chip axp288_regmap_irq_chip = {
> >>
> >>  static struct mfd_cell axp20x_cells[] = {
> >>  	{
> >>-		.name			= "axp20x-pek",
> >>-		.num_resources		= ARRAY_SIZE(axp20x_pek_resources),
> >>-		.resources		= axp20x_pek_resources,
> >>+		.name		= "axp20x-pek",
> >>+		.num_resources	= ARRAY_SIZE(axp20x_pek_resources),
> >>+		.resources	= axp20x_pek_resources,
> >>  	}, {
> >>-		.name			= "axp20x-regulator",
> >>+		.name		= "axp20x-regulator",
> >>+	}, {
> >>+		.name		= "axp20x-usb-power-supply",
> >>+		.of_compatible	= "x-powers,axp202-usb-power-supply",
> >>+		.num_resources	= ARRAY_SIZE(axp20x_usb_power_supply_resources),
> >>+		.resources	= axp20x_usb_power_supply_resources,
> >>  	},
> >>  };
> >>
> >

-- 
Lee Jones
Linaro STMicroelectronics Landing Team Lead
Linaro.org ? Open source software for ARM SoCs
Follow Linaro: Facebook | Twitter | Blog


From ryabinin.a.a at gmail.com  Wed Aug 12 02:30:37 2015
From: ryabinin.a.a at gmail.com (Andrey Ryabinin)
Date: Wed, 12 Aug 2015 12:30:37 +0300
Subject: [PATCH v5 2/6] x86/kasan,
 mm: introduce generic kasan_populate_zero_shadow()
In-Reply-To: <20150811164010.GJ23307@e104818-lin.cambridge.arm.com>
References: <1439259499-13913-1-git-send-email-ryabinin.a.a@gmail.com>
 <1439259499-13913-3-git-send-email-ryabinin.a.a@gmail.com>
 <20150811154117.GH23307@e104818-lin.cambridge.arm.com>
 <55CA21E8.2060704@gmail.com>
 <20150811164010.GJ23307@e104818-lin.cambridge.arm.com>
Message-ID: <CAPAsAGwDNpRBLAvyCSpR9ZO9tAmHx-XYjVDZPECeQkU0WOw5jg@mail.gmail.com>

2015-08-11 19:40 GMT+03:00 Catalin Marinas <catalin.marinas at arm.com>:
>
> Not sure how you plan to merge it though since there are x86
> dependencies. I could send the whole series via tip or the mm tree (and
> I guess it's pretty late for 4.3).

Via mm tree, I guess.
If this is too late for 4.3, then I'll update changelog and send v6
after 4.3-rc1 release.


From will.deacon at arm.com  Wed Aug 12 02:37:02 2015
From: will.deacon at arm.com (Will Deacon)
Date: Wed, 12 Aug 2015 10:37:02 +0100
Subject: [PATCH v5 2/6] x86/kasan, mm: introduce generic
 kasan_populate_zero_shadow()
In-Reply-To: <CAPAsAGwDNpRBLAvyCSpR9ZO9tAmHx-XYjVDZPECeQkU0WOw5jg@mail.gmail.com>
References: <1439259499-13913-1-git-send-email-ryabinin.a.a@gmail.com>
 <1439259499-13913-3-git-send-email-ryabinin.a.a@gmail.com>
 <20150811154117.GH23307@e104818-lin.cambridge.arm.com>
 <55CA21E8.2060704@gmail.com>
 <20150811164010.GJ23307@e104818-lin.cambridge.arm.com>
 <CAPAsAGwDNpRBLAvyCSpR9ZO9tAmHx-XYjVDZPECeQkU0WOw5jg@mail.gmail.com>
Message-ID: <20150812093701.GH22485@arm.com>

On Wed, Aug 12, 2015 at 10:30:37AM +0100, Andrey Ryabinin wrote:
> 2015-08-11 19:40 GMT+03:00 Catalin Marinas <catalin.marinas at arm.com>:
> >
> > Not sure how you plan to merge it though since there are x86
> > dependencies. I could send the whole series via tip or the mm tree (and
> > I guess it's pretty late for 4.3).
> 
> Via mm tree, I guess.
> If this is too late for 4.3, then I'll update changelog and send v6
> after 4.3-rc1 release.

That's probably the best bet, as I suspect we'll get some non-trivial
conflicts with the arm64 tree at this stage.

Will


From mhocko at kernel.org  Wed Aug 12 02:45:58 2015
From: mhocko at kernel.org (Michal Hocko)
Date: Wed, 12 Aug 2015 11:45:58 +0200
Subject: [PATCH v7 2/6] mm: mlock: Add new mlock system call
In-Reply-To: <1439097776-27695-3-git-send-email-emunson@akamai.com>
References: <1439097776-27695-1-git-send-email-emunson@akamai.com>
 <1439097776-27695-3-git-send-email-emunson@akamai.com>
Message-ID: <20150812094558.GD14940@dhcp22.suse.cz>

On Sun 09-08-15 01:22:52, Eric B Munson wrote:
> With the refactored mlock code, introduce a new system call for mlock.
> The new call will allow the user to specify what lock states are being
> added.  mlock2 is trivial at the moment, but a follow on patch will add
> a new mlock state making it useful.

Looks good to me

Acked-by: Michal Hocko <mhocko at suse.com>

> Signed-off-by: Eric B Munson <emunson at akamai.com>
> Acked-by: Vlastimil Babka <vbabka at suse.cz>
> Cc: Michal Hocko <mhocko at suse.cz>
> Cc: Vlastimil Babka <vbabka at suse.cz>
> Cc: Heiko Carstens <heiko.carstens at de.ibm.com>
> Cc: Geert Uytterhoeven <geert at linux-m68k.org>
> Cc: Catalin Marinas <catalin.marinas at arm.com>
> Cc: Stephen Rothwell <sfr at canb.auug.org.au>
> Cc: Guenter Roeck <linux at roeck-us.net>
> Cc: Andrea Arcangeli <aarcange at redhat.com>
> Cc: linux-alpha at vger.kernel.org
> Cc: linux-kernel at vger.kernel.org
> Cc: linux-arm-kernel at lists.infradead.org
> Cc: adi-buildroot-devel at lists.sourceforge.net
> Cc: linux-cris-kernel at axis.com
> Cc: linux-ia64 at vger.kernel.org
> Cc: linux-m68k at lists.linux-m68k.org
> Cc: linux-am33-list at redhat.com
> Cc: linux-parisc at vger.kernel.org
> Cc: linuxppc-dev at lists.ozlabs.org
> Cc: linux-s390 at vger.kernel.org
> Cc: linux-sh at vger.kernel.org
> Cc: sparclinux at vger.kernel.org
> Cc: linux-xtensa at linux-xtensa.org
> Cc: linux-api at vger.kernel.org
> Cc: linux-arch at vger.kernel.org
> Cc: linux-mm at kvack.org
> ---
>  arch/x86/entry/syscalls/syscall_32.tbl | 1 +
>  arch/x86/entry/syscalls/syscall_64.tbl | 1 +
>  include/linux/syscalls.h               | 2 ++
>  include/uapi/asm-generic/unistd.h      | 4 +++-
>  kernel/sys_ni.c                        | 1 +
>  mm/mlock.c                             | 8 ++++++++
>  6 files changed, 16 insertions(+), 1 deletion(-)
> 
> diff --git a/arch/x86/entry/syscalls/syscall_32.tbl b/arch/x86/entry/syscalls/syscall_32.tbl
> index ef8187f..8e06da6 100644
> --- a/arch/x86/entry/syscalls/syscall_32.tbl
> +++ b/arch/x86/entry/syscalls/syscall_32.tbl
> @@ -365,3 +365,4 @@
>  356	i386	memfd_create		sys_memfd_create
>  357	i386	bpf			sys_bpf
>  358	i386	execveat		sys_execveat			stub32_execveat
> +360	i386	mlock2			sys_mlock2
> diff --git a/arch/x86/entry/syscalls/syscall_64.tbl b/arch/x86/entry/syscalls/syscall_64.tbl
> index 9ef32d5..67601e7 100644
> --- a/arch/x86/entry/syscalls/syscall_64.tbl
> +++ b/arch/x86/entry/syscalls/syscall_64.tbl
> @@ -329,6 +329,7 @@
>  320	common	kexec_file_load		sys_kexec_file_load
>  321	common	bpf			sys_bpf
>  322	64	execveat		stub_execveat
> +324	common	mlock2			sys_mlock2
>  
>  #
>  # x32-specific system call numbers start at 512 to avoid cache impact
> diff --git a/include/linux/syscalls.h b/include/linux/syscalls.h
> index b45c45b..56a3d59 100644
> --- a/include/linux/syscalls.h
> +++ b/include/linux/syscalls.h
> @@ -884,4 +884,6 @@ asmlinkage long sys_execveat(int dfd, const char __user *filename,
>  			const char __user *const __user *argv,
>  			const char __user *const __user *envp, int flags);
>  
> +asmlinkage long sys_mlock2(unsigned long start, size_t len, int flags);
> +
>  #endif
> diff --git a/include/uapi/asm-generic/unistd.h b/include/uapi/asm-generic/unistd.h
> index e016bd9..14a6013 100644
> --- a/include/uapi/asm-generic/unistd.h
> +++ b/include/uapi/asm-generic/unistd.h
> @@ -709,9 +709,11 @@ __SYSCALL(__NR_memfd_create, sys_memfd_create)
>  __SYSCALL(__NR_bpf, sys_bpf)
>  #define __NR_execveat 281
>  __SC_COMP(__NR_execveat, sys_execveat, compat_sys_execveat)
> +#define __NR_mlock2 282
> +__SYSCALL(__NR_mlock2, sys_mlock2)
>  
>  #undef __NR_syscalls
> -#define __NR_syscalls 282
> +#define __NR_syscalls 283
>  
>  /*
>   * All syscalls below here should go away really,
> diff --git a/kernel/sys_ni.c b/kernel/sys_ni.c
> index 7995ef5..4818b71 100644
> --- a/kernel/sys_ni.c
> +++ b/kernel/sys_ni.c
> @@ -193,6 +193,7 @@ cond_syscall(sys_mlock);
>  cond_syscall(sys_munlock);
>  cond_syscall(sys_mlockall);
>  cond_syscall(sys_munlockall);
> +cond_syscall(sys_mlock2);
>  cond_syscall(sys_mincore);
>  cond_syscall(sys_madvise);
>  cond_syscall(sys_mremap);
> diff --git a/mm/mlock.c b/mm/mlock.c
> index 5692ee5..3094f27 100644
> --- a/mm/mlock.c
> +++ b/mm/mlock.c
> @@ -643,6 +643,14 @@ SYSCALL_DEFINE2(mlock, unsigned long, start, size_t, len)
>  	return do_mlock(start, len, VM_LOCKED);
>  }
>  
> +SYSCALL_DEFINE3(mlock2, unsigned long, start, size_t, len, int, flags)
> +{
> +	if (flags)
> +		return -EINVAL;
> +
> +	return do_mlock(start, len, VM_LOCKED);
> +}
> +
>  SYSCALL_DEFINE2(munlock, unsigned long, start, size_t, len)
>  {
>  	int ret;
> -- 
> 1.9.1

-- 
Michal Hocko
SUSE Labs


From viresh.kumar at linaro.org  Wed Aug 12 02:52:16 2015
From: viresh.kumar at linaro.org (Viresh Kumar)
Date: Wed, 12 Aug 2015 15:22:16 +0530
Subject: [PATCH V2] thermal: cpu_cooling: fix lockdep problems in cpu_cooling
Message-ID: <16e7d7d811fa2b0f8dcf6cade345a5f2f3e3c36a.1439372926.git.viresh.kumar@linaro.org>

From: Russell King <rmk+kernel at arm.linux.org.uk>

A recent change to the cpu_cooling code introduced a AB-BA deadlock
scenario between the cpufreq_policy_notifier_list rwsem and the
cooling_cpufreq_lock.  This is caused by cooling_cpufreq_lock being held
before the registration/removal of the notifier block (an operation
which takes the rwsem), and the notifier code itself which takes the
locks in the reverse order:

======================================================
[ INFO: possible circular locking dependency detected ]
3.18.0+ #1453 Not tainted
-------------------------------------------------------
rc.local/770 is trying to acquire lock:
 (cooling_cpufreq_lock){+.+.+.}, at: [<c04abfc4>] cpufreq_thermal_notifier+0x34/0xfc

but task is already holding lock:
 ((cpufreq_policy_notifier_list).rwsem){++++.+}, at: [<c0042f04>]  __blocking_notifier_call_chain+0x34/0x68

which lock already depends on the new lock.

the existing dependency chain (in reverse order) is:

-> #1 ((cpufreq_policy_notifier_list).rwsem){++++.+}:
       [<c06bc3b0>] down_write+0x44/0x9c
       [<c0043444>] blocking_notifier_chain_register+0x28/0xd8
       [<c04ad610>] cpufreq_register_notifier+0x68/0x90
       [<c04abe4c>] __cpufreq_cooling_register.part.1+0x120/0x180
       [<c04abf44>] __cpufreq_cooling_register+0x98/0xa4
       [<c04abf8c>] cpufreq_cooling_register+0x18/0x1c
       [<bf0046f8>] imx_thermal_probe+0x1c0/0x470 [imx_thermal]
       [<c037cef8>] platform_drv_probe+0x50/0xac
       [<c037b710>] driver_probe_device+0x114/0x234
       [<c037b8cc>] __driver_attach+0x9c/0xa0
       [<c0379d68>] bus_for_each_dev+0x5c/0x90
       [<c037b204>] driver_attach+0x24/0x28
       [<c037ae7c>] bus_add_driver+0xe0/0x1d8
       [<c037c0cc>] driver_register+0x80/0xfc
       [<c037cd80>] __platform_driver_register+0x50/0x64
       [<bf007018>] 0xbf007018
       [<c0008a5c>] do_one_initcall+0x88/0x1d8
       [<c0095da4>] load_module+0x1768/0x1ef8
       [<c0096614>] SyS_init_module+0xe0/0xf4
       [<c000ec00>] ret_fast_syscall+0x0/0x48

-> #0 (cooling_cpufreq_lock){+.+.+.}:
       [<c00619f8>] lock_acquire+0xb0/0x124
       [<c06ba3b4>] mutex_lock_nested+0x5c/0x3d8
       [<c04abfc4>] cpufreq_thermal_notifier+0x34/0xfc
       [<c0042bf4>] notifier_call_chain+0x4c/0x8c
       [<c0042f20>] __blocking_notifier_call_chain+0x50/0x68
       [<c0042f58>] blocking_notifier_call_chain+0x20/0x28
       [<c04ae62c>] cpufreq_set_policy+0x7c/0x1d0
       [<c04af3cc>] store_scaling_governor+0x74/0x9c
       [<c04ad418>] store+0x90/0xc0
       [<c0175384>] sysfs_kf_write+0x54/0x58
       [<c01746b4>] kernfs_fop_write+0xdc/0x190
       [<c010dcc0>] vfs_write+0xac/0x1b4
       [<c010dfec>] SyS_write+0x44/0x90
       [<c000ec00>] ret_fast_syscall+0x0/0x48

other info that might help us debug this:

 Possible unsafe locking scenario:

       CPU0                    CPU1
       ----                    ----
  lock((cpufreq_policy_notifier_list).rwsem);
                               lock(cooling_cpufreq_lock);
                               lock((cpufreq_policy_notifier_list).rwsem);
  lock(cooling_cpufreq_lock);

 *** DEADLOCK ***

7 locks held by rc.local/770:
 #0:  (sb_writers#6){.+.+.+}, at: [<c010dda0>] vfs_write+0x18c/0x1b4
 #1:  (&of->mutex){+.+.+.}, at: [<c0174678>] kernfs_fop_write+0xa0/0x190
 #2:  (s_active#52){.+.+.+}, at: [<c0174680>] kernfs_fop_write+0xa8/0x190
 #3:  (cpu_hotplug.lock){++++++}, at: [<c0026a60>] get_online_cpus+0x34/0x90
 #4:  (cpufreq_rwsem){.+.+.+}, at: [<c04ad3e0>] store+0x58/0xc0
 #5:  (&policy->rwsem){+.+.+.}, at: [<c04ad3f8>] store+0x70/0xc0
 #6:  ((cpufreq_policy_notifier_list).rwsem){++++.+}, at: [<c0042f04>] __blocking_notifier_call_chain+0x34/0x68

stack backtrace:
CPU: 0 PID: 770 Comm: rc.local Not tainted 3.18.0+ #1453
Hardware name: Freescale i.MX6 Quad/DualLite (Device Tree)
Backtrace:
[<c00121c8>] (dump_backtrace) from [<c0012360>] (show_stack+0x18/0x1c)
 r6:c0b85a80 r5:c0b75630 r4:00000000 r3:00000000
[<c0012348>] (show_stack) from [<c06b6c48>] (dump_stack+0x7c/0x98)
[<c06b6bcc>] (dump_stack) from [<c06b42a4>] (print_circular_bug+0x28c/0x2d8)
 r4:c0b85a80 r3:d0071d40
[<c06b4018>] (print_circular_bug) from [<c00613b0>] (__lock_acquire+0x1acc/0x1bb0)
 r10:c0b50660 r8:c09e6d80 r7:d0071d40 r6:c11d0f0c r5:00000007 r4:d0072240
[<c005f8e4>] (__lock_acquire) from [<c00619f8>] (lock_acquire+0xb0/0x124)
 r10:00000000 r9:c04abfc4 r8:00000000 r7:00000000 r6:00000000 r5:c0a06f0c
 r4:00000000
[<c0061948>] (lock_acquire) from [<c06ba3b4>] (mutex_lock_nested+0x5c/0x3d8)
 r10:ec853800 r9:c0a06ed4 r8:d0071d40 r7:c0a06ed4 r6:c11d0f0c r5:00000000
 r4:c04abfc4
[<c06ba358>] (mutex_lock_nested) from [<c04abfc4>] (cpufreq_thermal_notifier+0x34/0xfc)
 r10:ec853800 r9:ec85380c r8:d00d7d3c r7:c0a06ed4 r6:d00d7d3c r5:00000000
 r4:fffffffe
[<c04abf90>] (cpufreq_thermal_notifier) from [<c0042bf4>] (notifier_call_chain+0x4c/0x8c)
 r7:00000000 r6:00000000 r5:00000000 r4:fffffffe
[<c0042ba8>] (notifier_call_chain) from [<c0042f20>] (__blocking_notifier_call_chain+0x50/0x68)
 r8:c0a072a4 r7:00000000 r6:d00d7d3c r5:ffffffff r4:c0a06fc8 r3:ffffffff
[<c0042ed0>] (__blocking_notifier_call_chain) from [<c0042f58>] (blocking_notifier_call_chain+0x20/0x28)
 r7:ec98b540 r6:c13ebc80 r5:ed76e600 r4:d00d7d3c
[<c0042f38>] (blocking_notifier_call_chain) from [<c04ae62c>] (cpufreq_set_policy+0x7c/0x1d0)
[<c04ae5b0>] (cpufreq_set_policy) from [<c04af3cc>] (store_scaling_governor+0x74/0x9c)
 r7:ec98b540 r6:0000000c r5:ec98b540 r4:ed76e600
[<c04af358>] (store_scaling_governor) from [<c04ad418>] (store+0x90/0xc0)
 r6:0000000c r5:ed76e6d4 r4:ed76e600
[<c04ad388>] (store) from [<c0175384>] (sysfs_kf_write+0x54/0x58)
 r8:0000000c r7:d00d7f78 r6:ec98b540 r5:0000000c r4:ec853800 r3:0000000c
[<c0175330>] (sysfs_kf_write) from [<c01746b4>] (kernfs_fop_write+0xdc/0x190)
 r6:ec98b540 r5:00000000 r4:00000000 r3:c0175330
[<c01745d8>] (kernfs_fop_write) from [<c010dcc0>] (vfs_write+0xac/0x1b4)
 r10:0162aa70 r9:d00d6000 r8:0000000c r7:d00d7f78 r6:0162aa70 r5:0000000c
 r4:eccde500
[<c010dc14>] (vfs_write) from [<c010dfec>] (SyS_write+0x44/0x90)
 r10:0162aa70 r8:0000000c r7:eccde500 r6:eccde500 r5:00000000 r4:00000000
[<c010dfa8>] (SyS_write) from [<c000ec00>] (ret_fast_syscall+0x0/0x48)
 r10:00000000 r8:c000edc4 r7:00000004 r6:000216cc r5:0000000c r4:0162aa70

Solve this by moving to finer grained locking - use one mutex to protect
the cpufreq_dev_list as a whole, and a separate lock to ensure correct
ordering of cpufreq notifier registration and removal.

cooling_list_lock is taken within cooling_cpufreq_lock on
(un)registration to preserve the behavior of the code, i.e. to
atomically add/remove to the list and (un)register the notifier.

Fixes: 2dcd851fe4b4 ("thermal: cpu_cooling: Update always cpufreq policy with
Reviewed-by: Viresh Kumar <viresh.kumar at linaro.org>
Signed-off-by: Russell King <rmk+kernel at arm.linux.org.uk>
Signed-off-by: Viresh Kumar <viresh.kumar at linaro.org>
---

Hi Eduardo/Zhang,

This is 4.2-rc material, please apply soon.

V1->V2:
- V1 was posted by Russell this morning and I made few minor changes to
  it.
- Some sections (specially the Rant) of the commit log are dropped and
  the last one is updated, as we do take cooling_list_lock within
  cooling_cpufreq_lock.
- Above is updated in code during unregister sequence
- cooling_list_lock taken at few more places
- Minor reorganization of the code

 drivers/thermal/cpu_cooling.c | 31 ++++++++++++++++++++-----------
 1 file changed, 20 insertions(+), 11 deletions(-)

diff --git a/drivers/thermal/cpu_cooling.c b/drivers/thermal/cpu_cooling.c
index 6509c61b9648..5ae0524bed19 100644
--- a/drivers/thermal/cpu_cooling.c
+++ b/drivers/thermal/cpu_cooling.c
@@ -107,6 +107,9 @@ struct cpufreq_cooling_device {
 static DEFINE_IDR(cpufreq_idr);
 static DEFINE_MUTEX(cooling_cpufreq_lock);
 
+static unsigned int cpufreq_dev_count;
+
+static DEFINE_MUTEX(cooling_list_lock);
 static LIST_HEAD(cpufreq_dev_list);
 
 /**
@@ -185,14 +188,14 @@ unsigned long cpufreq_cooling_get_level(unsigned int cpu, unsigned int freq)
 {
 	struct cpufreq_cooling_device *cpufreq_dev;
 
-	mutex_lock(&cooling_cpufreq_lock);
+	mutex_lock(&cooling_list_lock);
 	list_for_each_entry(cpufreq_dev, &cpufreq_dev_list, node) {
 		if (cpumask_test_cpu(cpu, &cpufreq_dev->allowed_cpus)) {
-			mutex_unlock(&cooling_cpufreq_lock);
+			mutex_unlock(&cooling_list_lock);
 			return get_level(cpufreq_dev, freq);
 		}
 	}
-	mutex_unlock(&cooling_cpufreq_lock);
+	mutex_unlock(&cooling_list_lock);
 
 	pr_err("%s: cpu:%d not part of any cooling device\n", __func__, cpu);
 	return THERMAL_CSTATE_INVALID;
@@ -221,7 +224,7 @@ static int cpufreq_thermal_notifier(struct notifier_block *nb,
 	switch (event) {
 
 	case CPUFREQ_ADJUST:
-		mutex_lock(&cooling_cpufreq_lock);
+		mutex_lock(&cooling_list_lock);
 		list_for_each_entry(cpufreq_dev, &cpufreq_dev_list, node) {
 			if (!cpumask_test_cpu(policy->cpu,
 					      &cpufreq_dev->allowed_cpus))
@@ -233,7 +236,7 @@ static int cpufreq_thermal_notifier(struct notifier_block *nb,
 				cpufreq_verify_within_limits(policy, 0,
 							     max_freq);
 		}
-		mutex_unlock(&cooling_cpufreq_lock);
+		mutex_unlock(&cooling_list_lock);
 		break;
 	default:
 		return NOTIFY_DONE;
@@ -866,12 +869,14 @@ __cpufreq_cooling_register(struct device_node *np,
 
 	mutex_lock(&cooling_cpufreq_lock);
 
+	mutex_lock(&cooling_list_lock);
+	list_add(&cpufreq_dev->node, &cpufreq_dev_list);
+	mutex_unlock(&cooling_list_lock);
+
 	/* Register the notifier for first cpufreq cooling device */
-	if (list_empty(&cpufreq_dev_list))
+	if (!cpufreq_dev_count++)
 		cpufreq_register_notifier(&thermal_cpufreq_notifier_block,
 					  CPUFREQ_POLICY_NOTIFIER);
-	list_add(&cpufreq_dev->node, &cpufreq_dev_list);
-
 	mutex_unlock(&cooling_cpufreq_lock);
 
 	return cool_dev;
@@ -1013,13 +1018,17 @@ void cpufreq_cooling_unregister(struct thermal_cooling_device *cdev)
 		return;
 
 	cpufreq_dev = cdev->devdata;
-	mutex_lock(&cooling_cpufreq_lock);
-	list_del(&cpufreq_dev->node);
 
 	/* Unregister the notifier for the last cpufreq cooling device */
-	if (list_empty(&cpufreq_dev_list))
+	mutex_lock(&cooling_cpufreq_lock);
+	if (!--cpufreq_dev_count)
 		cpufreq_unregister_notifier(&thermal_cpufreq_notifier_block,
 					    CPUFREQ_POLICY_NOTIFIER);
+
+	mutex_lock(&cooling_list_lock);
+	list_del(&cpufreq_dev->node);
+	mutex_unlock(&cooling_list_lock);
+
 	mutex_unlock(&cooling_cpufreq_lock);
 
 	thermal_cooling_device_unregister(cpufreq_dev->cool_dev);
-- 
2.4.0



From will.deacon at arm.com  Wed Aug 12 02:53:50 2015
From: will.deacon at arm.com (Will Deacon)
Date: Wed, 12 Aug 2015 10:53:50 +0100
Subject: How to support multiple watchpoints on kernel after 3.10 when
 using arm debug architectures prior to 7.1?
In-Reply-To: <55CABA0F.9020901@huawei.com>
References: <55CABA0F.9020901@huawei.com>
Message-ID: <20150812095350.GI22485@arm.com>

On Wed, Aug 12, 2015 at 04:14:23AM +0100, long.wanglong wrote:
> The linux kernel after 3.10 (after the commit c512de95 "ARM:
> hw_breakpoint: reserve one breakpoint for watchpoint stepping" )
> reserve a single breakpoint, regardless of the number of watchpoints,
> when the hardware use the ARM Debug architectures prior to 7.1.
> 
> On these older CPUS, how to support multiple watchpoints when
> using kernel after 3.10?
> 
> Are there any risks if we change the function 'get_num_wrps(void)'
> and force it returning the number of watchpoints the hardware have?

Please read the comment in the file:

	/*
	 * On debug architectures prior to 7.1, when a watchpoint fires, the
	 * only way to work out which watchpoint it was is by disassembling
	 * the faulting instruction and working out the address of the memory
	 * access.
	 *
	 * Furthermore, we can only do this if the watchpoint was precise
	 * since imprecise watchpoints prevent us from calculating register
	 * based addresses.
	 *
	 * Providing we have more than 1 breakpoint register, we only report
	 * a single watchpoint register for the time being. This way, we always
	 * know which watchpoint fired. In the future we can either add a
	 * disassembler and address generation emulator, or we can insert a
	 * check to see if the DFAR is set on watchpoint exception entry
	 * [the ARM ARM states that the DFAR is UNKNOWN, but experience shows
	 * that it is set on some implementations].
	 */

So you need to write a disassembler + partial emulator (to compute
addresses) for all memory access instructions (including neon and vfp)
so that you can figure out which handler to call when you get a debug
exception. The mismatched stepping code would also need some work to
deal with overlapping watchpoints correctly so that we don't get stuck.

A hackier way is to probe whether or not the DFAR appears to be set
correctly on a watchpoint exception and use it anyway, but I'd definitely
want a way to disable that.

It's annoying, because sending a SIGTRAP to GDB is probably the common
case and userspace might be able to figure things out, but we can't make
that assumption in general since we can have multiple clients (e.g. perf)
owning different watchpoints.

As I've said before, divorcing the ptrace interface to hw_breakpoint
from perf would probably help somewhat, but it's a tricky challenge.

Will


From marc.zyngier at arm.com  Wed Aug 12 02:56:38 2015
From: marc.zyngier at arm.com (Marc Zyngier)
Date: Wed, 12 Aug 2015 10:56:38 +0100
Subject: [PATCH v4 06/11] KVM: arm/arm64: vgic: Allow dynamic mapping of
 physical/virtual interrupts
In-Reply-To: <20150811074221.GC5007@lvm>
References: <1438962347-17541-1-git-send-email-marc.zyngier@arm.com>
 <1438962347-17541-7-git-send-email-marc.zyngier@arm.com>
 <20150811074221.GC5007@lvm>
Message-ID: <20150812105638.67de9423@arm.com>

On Tue, 11 Aug 2015 08:42:37 +0100
Christoffer Dall <christoffer.dall at linaro.org> wrote:

> On Fri, Aug 07, 2015 at 04:45:42PM +0100, Marc Zyngier wrote:
> > In order to be able to feed physical interrupts to a guest, we need
> > to be able to establish the virtual-physical mapping between the two
> > worlds.
> > 
> > The mappings are kept in a set of RCU lists, indexed by virtual interrupts.
> > 
> > Signed-off-by: Marc Zyngier <marc.zyngier at arm.com>
> 
> Thanks for addressing all my concerns:
> 
> Reviewed-by: Christoffer Dall <christoffer.dall at linaro.org>

Thanks a lot for all the reviewing, much appreciated.

Unless someone has an objection, I'm going put this series (minus
the last patch) into -next so it gets a bit more exposure.

	M.
-- 
Jazz is not dead. It just smells funny.


From bp at alien8.de  Wed Aug 12 03:12:19 2015
From: bp at alien8.de (Borislav Petkov)
Date: Wed, 12 Aug 2015 12:12:19 +0200
Subject: [PATCH v3 1/4] edac: Add an function to retrieve the EDAC
 debugfs node
In-Reply-To: <1439326077-25507-2-git-send-email-lho@apm.com>
References: <1439326077-25507-1-git-send-email-lho@apm.com>
 <1439326077-25507-2-git-send-email-lho@apm.com>
Message-ID: <20150812101219.GC14011@nazgul.tnic>

On Tue, Aug 11, 2015 at 02:47:54PM -0600, Loc Ho wrote:
> This patch adds an function to retrieve the EDAC debugfs node. This allows
> EDAC driver to create debugfs node under the EDAC debugfs node.
> 
> Signed-off-by: Loc Ho <lho at apm.com>
> ---
>  drivers/edac/edac_core.h     |    1 +
>  drivers/edac/edac_mc_sysfs.c |   10 ++++++++++
>  2 files changed, 11 insertions(+), 0 deletions(-)
> 
> diff --git a/drivers/edac/edac_core.h b/drivers/edac/edac_core.h
> index ad42587..6771e64 100644
> --- a/drivers/edac/edac_core.h
> +++ b/drivers/edac/edac_core.h
> @@ -511,5 +511,6 @@ extern void edac_pci_remove_sysfs(struct edac_pci_ctl_info *pci);
>   * edac misc APIs
>   */
>  extern char *edac_op_state_to_string(int op_state);
> +extern struct dentry *edac_get_debugfs(void);
>  
>  #endif				/* _EDAC_CORE_H_ */
> diff --git a/drivers/edac/edac_mc_sysfs.c b/drivers/edac/edac_mc_sysfs.c
> index 33df7d9..b76afe0 100644
> --- a/drivers/edac/edac_mc_sysfs.c
> +++ b/drivers/edac/edac_mc_sysfs.c
> @@ -959,6 +959,16 @@ nomem:
>  	debugfs_remove(mci->debugfs);
>  	return -ENOMEM;
>  }
> +
> +struct dentry *edac_get_debugfs(void)
> +{
> +	return edac_debugfs;
> +}

EXPORT_SYMBOL_GPL() if it is going to be used by modules.

> +#else
> +struct dentry *edac_get_debugfs(void)

static inline struct ...

> +{
> +	return NULL;
> +}
>  #endif
>  
>  /*
> -- 
> 1.7.1
> 
> --
> To unsubscribe from this list: send the line "unsubscribe linux-edac" in
> the body of a message to majordomo at vger.kernel.org
> More majordomo info at  http://vger.kernel.org/majordomo-info.html
> 

-- 
Regards/Gruss,
    Boris.

ECO tip #101: Trim your mails when you reply.
--


From mpa at pengutronix.de  Wed Aug 12 03:12:36 2015
From: mpa at pengutronix.de (Markus Pargmann)
Date: Wed, 12 Aug 2015 12:12:36 +0200
Subject: [PATCH 11/20] regmap: _regmap_raw_read: Add handling of busses
 without bus->read()
In-Reply-To: <1439374365-20623-1-git-send-email-mpa@pengutronix.de>
References: <1439374365-20623-1-git-send-email-mpa@pengutronix.de>
Message-ID: <1439374365-20623-12-git-send-email-mpa@pengutronix.de>

Handle easy reads by using bus->reg_read(). Return with an error value
if a read is requested that can not be handled with reg_read().

Signed-off-by: Markus Pargmann <mpa at pengutronix.de>
---
 drivers/base/regmap/regmap.c | 15 +++++++++++++++
 1 file changed, 15 insertions(+)

diff --git a/drivers/base/regmap/regmap.c b/drivers/base/regmap/regmap.c
index 87f15fb60bc5..3b663350c573 100644
--- a/drivers/base/regmap/regmap.c
+++ b/drivers/base/regmap/regmap.c
@@ -2071,6 +2071,21 @@ static int _regmap_raw_read(struct regmap *map, unsigned int reg, void *val,
 
 	WARN_ON(!map->bus);
 
+	/*
+	 * There are busses that do not have a read function as it is optional.
+	 * Use their reg_read function instead if the requested number of bytes
+	 * is correct.
+	 */
+	if (!map->bus->read) {
+		/*
+		 * bus_reg_read() does not support reading values that are not
+		 * exactly the size of format.val_bytes
+		 */
+		if (val_len != map->format.val_bytes)
+			return -EINVAL;
+		return _regmap_bus_reg_read(map, reg, val);
+	}
+
 	range = _regmap_range_lookup(map, reg);
 	if (range) {
 		ret = _regmap_select_page(map, &reg, range,
-- 
2.4.6



From mpa at pengutronix.de  Wed Aug 12 03:12:35 2015
From: mpa at pengutronix.de (Markus Pargmann)
Date: Wed, 12 Aug 2015 12:12:35 +0200
Subject: [PATCH 10/20] regmap: _regmap_raw_multi_reg_write: Add reg_write()
 support
In-Reply-To: <1439374365-20623-1-git-send-email-mpa@pengutronix.de>
References: <1439374365-20623-1-git-send-email-mpa@pengutronix.de>
Message-ID: <1439374365-20623-11-git-send-email-mpa@pengutronix.de>

Define a fallback for busses which do not define a write() function.
Instead we write one register at a time using reg_write().

Without this patch, _regmap_raw_multi_reg_write would break as it tries
to call bus->write() without checking if it exists before.

Signed-off-by: Markus Pargmann <mpa at pengutronix.de>
---
 drivers/base/regmap/regmap.c | 14 ++++++++++++++
 1 file changed, 14 insertions(+)

diff --git a/drivers/base/regmap/regmap.c b/drivers/base/regmap/regmap.c
index 78eb96288a68..87f15fb60bc5 100644
--- a/drivers/base/regmap/regmap.c
+++ b/drivers/base/regmap/regmap.c
@@ -1778,6 +1778,20 @@ static int _regmap_raw_multi_reg_write(struct regmap *map,
 	if (!len)
 		return -EINVAL;
 
+	/*
+	 * If bus->write is not supported we have to use reg_write for each
+	 * register value.
+	 */
+	if (!map->bus->write) {
+		for (i = 0; i < num_regs; i++) {
+			ret = map->reg_write(map, regs[i].reg, regs[i].def);
+			if (ret)
+				return ret;
+		}
+
+		return 0;
+	}
+
 	buf = kzalloc(len, GFP_KERNEL);
 	if (!buf)
 		return -ENOMEM;
-- 
2.4.6



From mpa at pengutronix.de  Wed Aug 12 03:12:33 2015
From: mpa at pengutronix.de (Markus Pargmann)
Date: Wed, 12 Aug 2015 12:12:33 +0200
Subject: [PATCH 08/20] regmap: Fix regmap_can_raw_write check
In-Reply-To: <1439374365-20623-1-git-send-email-mpa@pengutronix.de>
References: <1439374365-20623-1-git-send-email-mpa@pengutronix.de>
Message-ID: <1439374365-20623-9-git-send-email-mpa@pengutronix.de>

This function is missing a check if map->bus->write is implemented. If
it is not implemented arbitrary raw writes are not possible.

Signed-off-by: Markus Pargmann <mpa at pengutronix.de>
---
 drivers/base/regmap/regmap.c | 3 ++-
 1 file changed, 2 insertions(+), 1 deletion(-)

diff --git a/drivers/base/regmap/regmap.c b/drivers/base/regmap/regmap.c
index 35ad3783da70..510dab052a95 100644
--- a/drivers/base/regmap/regmap.c
+++ b/drivers/base/regmap/regmap.c
@@ -1382,7 +1382,8 @@ int _regmap_raw_write(struct regmap *map, unsigned int reg,
  */
 bool regmap_can_raw_write(struct regmap *map)
 {
-	return map->bus && map->format.format_val && map->format.format_reg;
+	return map->bus && map->bus->write && map->format.format_val &&
+		map->format.format_reg;
 }
 EXPORT_SYMBOL_GPL(regmap_can_raw_write);
 
-- 
2.4.6



From mpa at pengutronix.de  Wed Aug 12 03:12:34 2015
From: mpa at pengutronix.de (Markus Pargmann)
Date: Wed, 12 Aug 2015 12:12:34 +0200
Subject: [PATCH 09/20] regmap: _regmap_raw_write fix for busses without write()
In-Reply-To: <1439374365-20623-1-git-send-email-mpa@pengutronix.de>
References: <1439374365-20623-1-git-send-email-mpa@pengutronix.de>
Message-ID: <1439374365-20623-10-git-send-email-mpa@pengutronix.de>

Some busses don't have a write() function defined. However we can use
reg_write() in special cases.

This patch adds support for reg_write() and throws errors if it was
unsuccessful.

Signed-off-by: Markus Pargmann <mpa at pengutronix.de>
---
 drivers/base/regmap/regmap.c | 9 +++++++--
 1 file changed, 7 insertions(+), 2 deletions(-)

diff --git a/drivers/base/regmap/regmap.c b/drivers/base/regmap/regmap.c
index 510dab052a95..78eb96288a68 100644
--- a/drivers/base/regmap/regmap.c
+++ b/drivers/base/regmap/regmap.c
@@ -1229,6 +1229,11 @@ int _regmap_raw_write(struct regmap *map, unsigned int reg,
 		}
 	}
 
+	if (!map->bus->write && val_len == map->format.val_bytes) {
+		ret = _regmap_bus_reg_write(map, reg, *(unsigned int *)val);
+		return ret;
+	}
+
 	range = _regmap_range_lookup(map, reg);
 	if (range) {
 		int val_num = val_len / map->format.val_bytes;
@@ -1340,7 +1345,7 @@ int _regmap_raw_write(struct regmap *map, unsigned int reg,
 	 * send the work_buf directly, otherwise try to do a gather
 	 * write.
 	 */
-	if (val == work_val) {
+	if (val == work_val && map->bus->write) {
 		ret = map->bus->write(map->bus_context, map->work_buf,
 				      map->format.reg_bytes +
 				      map->format.pad_bytes +
@@ -1354,7 +1359,7 @@ int _regmap_raw_write(struct regmap *map, unsigned int reg,
 						     val, val_len);
 
 		/* If that didn't work fall back on linearising by hand. */
-		if (ret == -ENOTSUPP) {
+		if (ret == -ENOTSUPP && map->bus->write) {
 			len = map->format.reg_bytes + map->format.pad_bytes +
 				val_len;
 			buf = kzalloc(len, GFP_KERNEL);
-- 
2.4.6



From mpa at pengutronix.de  Wed Aug 12 03:12:27 2015
From: mpa at pengutronix.de (Markus Pargmann)
Date: Wed, 12 Aug 2015 12:12:27 +0200
Subject: [PATCH 02/20] regmap: Remove regmap_bulk_write 64bit support
In-Reply-To: <1439374365-20623-1-git-send-email-mpa@pengutronix.de>
References: <1439374365-20623-1-git-send-email-mpa@pengutronix.de>
Message-ID: <1439374365-20623-3-git-send-email-mpa@pengutronix.de>

Regmap does not support 64bit. The ival that is used to write the 64bit
data to, is unsigned int and can't hold 64bit. _regmap_write also just
supports unsigend int.

This patch removes the 64bit case as it may lead to compile warnings.

Cc: Stephen Boyd <sboyd at codeaurora.org>
Signed-off-by: Markus Pargmann <mpa at pengutronix.de>
---
 drivers/base/regmap/regmap.c | 5 -----
 1 file changed, 5 deletions(-)

diff --git a/drivers/base/regmap/regmap.c b/drivers/base/regmap/regmap.c
index 7111d04f2621..64a106af174f 100644
--- a/drivers/base/regmap/regmap.c
+++ b/drivers/base/regmap/regmap.c
@@ -1694,11 +1694,6 @@ int regmap_bulk_write(struct regmap *map, unsigned int reg, const void *val,
 			case 4:
 				ival = *(u32 *)(val + (i * val_bytes));
 				break;
-#ifdef CONFIG_64BIT
-			case 8:
-				ival = *(u64 *)(val + (i * val_bytes));
-				break;
-#endif
 			default:
 				ret = -EINVAL;
 				goto out;
-- 
2.4.6



From mpa at pengutronix.de  Wed Aug 12 03:12:26 2015
From: mpa at pengutronix.de (Markus Pargmann)
Date: Wed, 12 Aug 2015 12:12:26 +0200
Subject: [PATCH 01/20] regmap: Add missing comments about struct regmap_bus
In-Reply-To: <1439374365-20623-1-git-send-email-mpa@pengutronix.de>
References: <1439374365-20623-1-git-send-email-mpa@pengutronix.de>
Message-ID: <1439374365-20623-2-git-send-email-mpa@pengutronix.de>

There are some fields of this struct undocumented or old. This patch
updates the missing comments.

Signed-off-by: Markus Pargmann <mpa at pengutronix.de>
---
 include/linux/regmap.h | 4 +++-
 1 file changed, 3 insertions(+), 1 deletion(-)

diff --git a/include/linux/regmap.h b/include/linux/regmap.h
index 59c55ea0f0b5..6ff83c9ddb45 100644
--- a/include/linux/regmap.h
+++ b/include/linux/regmap.h
@@ -296,8 +296,11 @@ typedef void (*regmap_hw_free_context)(void *context);
  *                if not implemented  on a given device.
  * @async_write: Write operation which completes asynchronously, optional and
  *               must serialise with respect to non-async I/O.
+ * @reg_write: Write operation for a register. Writes value to register.
  * @read: Read operation.  Data is returned in the buffer used to transmit
  *         data.
+ * @reg_read: Read operation for a register. Reads a value from a register.
+ * @free_conetext: Free context.
  * @async_alloc: Allocate a regmap_async() structure.
  * @read_flag_mask: Mask to be set in the top byte of the register when doing
  *                  a read.
@@ -307,7 +310,6 @@ typedef void (*regmap_hw_free_context)(void *context);
  * @val_format_endian_default: Default endianness for formatted register
  *     values. Used when the regmap_config specifies DEFAULT. If this is
  *     DEFAULT, BIG is assumed.
- * @async_size: Size of struct used for async work.
  */
 struct regmap_bus {
 	bool fast_io;
-- 
2.4.6



From mpa at pengutronix.de  Wed Aug 12 03:12:42 2015
From: mpa at pengutronix.de (Markus Pargmann)
Date: Wed, 12 Aug 2015 12:12:42 +0200
Subject: [PATCH 17/20] iio: bmc150: Use i2c regmap
In-Reply-To: <1439374365-20623-1-git-send-email-mpa@pengutronix.de>
References: <1439374365-20623-1-git-send-email-mpa@pengutronix.de>
Message-ID: <1439374365-20623-18-git-send-email-mpa@pengutronix.de>

This replaces all usage of direct i2c accesses with regmap accesses.

Signed-off-by: Markus Pargmann <mpa at pengutronix.de>
---
 drivers/iio/accel/Kconfig        |   2 +
 drivers/iio/accel/bmc150-accel.c | 225 +++++++++++++++++----------------------
 2 files changed, 101 insertions(+), 126 deletions(-)

diff --git a/drivers/iio/accel/Kconfig b/drivers/iio/accel/Kconfig
index 00e7bcbdbe24..01dd03d194d1 100644
--- a/drivers/iio/accel/Kconfig
+++ b/drivers/iio/accel/Kconfig
@@ -22,6 +22,8 @@ config BMC150_ACCEL
 	depends on I2C
 	select IIO_BUFFER
 	select IIO_TRIGGERED_BUFFER
+	select REGMAP
+	select REGMAP_I2C
 	help
 	  Say yes here to build support for the following Bosch accelerometers:
 	  BMC150, BMI055, BMA250E, BMA222E, BMA255, BMA280.
diff --git a/drivers/iio/accel/bmc150-accel.c b/drivers/iio/accel/bmc150-accel.c
index fe2d2316158f..1484e956482e 100644
--- a/drivers/iio/accel/bmc150-accel.c
+++ b/drivers/iio/accel/bmc150-accel.c
@@ -35,6 +35,7 @@
 #include <linux/iio/trigger.h>
 #include <linux/iio/trigger_consumer.h>
 #include <linux/iio/triggered_buffer.h>
+#include <linux/regmap.h>
 
 #define BMC150_ACCEL_DRV_NAME			"bmc150_accel"
 #define BMC150_ACCEL_IRQ_NAME			"bmc150_accel_event"
@@ -185,6 +186,8 @@ enum bmc150_accel_trigger_id {
 
 struct bmc150_accel_data {
 	struct i2c_client *client;
+	struct regmap *regmap;
+	struct device *dev;
 	struct bmc150_accel_interrupt interrupts[BMC150_ACCEL_INTERRUPTS];
 	atomic_t active_intr;
 	struct bmc150_accel_trigger triggers[BMC150_ACCEL_TRIGGERS];
@@ -241,6 +244,14 @@ static const struct {
 				       {500000, BMC150_ACCEL_SLEEP_500_MS},
 				       {1000000, BMC150_ACCEL_SLEEP_1_SEC} };
 
+static const struct regmap_config bmc150_i2c_regmap_conf = {
+	.reg_bits = 8,
+	.val_bits = 8,
+	.max_register = 0x3f,
+
+	.use_single_rw = false,
+	.cache_type = REGCACHE_NONE,
+};
 
 static int bmc150_accel_set_mode(struct bmc150_accel_data *data,
 				 enum bmc150_power_modes mode,
@@ -270,8 +281,7 @@ static int bmc150_accel_set_mode(struct bmc150_accel_data *data,
 
 	dev_dbg(&data->client->dev, "Set Mode bits %x\n", lpw_bits);
 
-	ret = i2c_smbus_write_byte_data(data->client,
-					BMC150_ACCEL_REG_PMU_LPW, lpw_bits);
+	ret = regmap_write(data->regmap, BMC150_ACCEL_REG_PMU_LPW, lpw_bits);
 	if (ret < 0) {
 		dev_err(&data->client->dev, "Error writing reg_pmu_lpw\n");
 		return ret;
@@ -289,8 +299,7 @@ static int bmc150_accel_set_bw(struct bmc150_accel_data *data, int val,
 	for (i = 0; i < ARRAY_SIZE(bmc150_accel_samp_freq_table); ++i) {
 		if (bmc150_accel_samp_freq_table[i].val == val &&
 				bmc150_accel_samp_freq_table[i].val2 == val2) {
-			ret = i2c_smbus_write_byte_data(
-				data->client,
+			ret = regmap_write(data->regmap,
 				BMC150_ACCEL_REG_PMU_BW,
 				bmc150_accel_samp_freq_table[i].bw_bits);
 			if (ret < 0)
@@ -307,26 +316,19 @@ static int bmc150_accel_set_bw(struct bmc150_accel_data *data, int val,
 
 static int bmc150_accel_update_slope(struct bmc150_accel_data *data)
 {
-	int ret, val;
+	int ret;
 
-	ret = i2c_smbus_write_byte_data(data->client, BMC150_ACCEL_REG_INT_6,
+	ret = regmap_write(data->regmap, BMC150_ACCEL_REG_INT_6,
 					data->slope_thres);
 	if (ret < 0) {
 		dev_err(&data->client->dev, "Error writing reg_int_6\n");
 		return ret;
 	}
 
-	ret = i2c_smbus_read_byte_data(data->client, BMC150_ACCEL_REG_INT_5);
+	ret = regmap_update_bits(data->regmap, BMC150_ACCEL_REG_INT_5,
+				 BMC150_ACCEL_SLOPE_DUR_MASK, data->slope_dur);
 	if (ret < 0) {
-		dev_err(&data->client->dev, "Error reading reg_int_5\n");
-		return ret;
-	}
-
-	val = (ret & ~BMC150_ACCEL_SLOPE_DUR_MASK) | data->slope_dur;
-	ret = i2c_smbus_write_byte_data(data->client, BMC150_ACCEL_REG_INT_5,
-					val);
-	if (ret < 0) {
-		dev_err(&data->client->dev, "Error write reg_int_5\n");
+		dev_err(&data->client->dev, "Error updating reg_int_5\n");
 		return ret;
 	}
 
@@ -348,17 +350,18 @@ static int bmc150_accel_any_motion_setup(struct bmc150_accel_trigger *t,
 static int bmc150_accel_chip_init(struct bmc150_accel_data *data)
 {
 	int ret;
+	unsigned int val;
 
-	ret = i2c_smbus_read_byte_data(data->client, BMC150_ACCEL_REG_CHIP_ID);
+	ret = regmap_read(data->regmap, BMC150_ACCEL_REG_CHIP_ID, &val);
 	if (ret < 0) {
 		dev_err(&data->client->dev,
 			"Error: Reading chip id\n");
 		return ret;
 	}
 
-	dev_dbg(&data->client->dev, "Chip Id %x\n", ret);
-	if (ret != data->chip_info->chip_id) {
-		dev_err(&data->client->dev, "Invalid chip %x\n", ret);
+	dev_dbg(&data->client->dev, "Chip Id %x\n", val);
+	if (val != data->chip_info->chip_id) {
+		dev_err(&data->client->dev, "Invalid chip %x\n", val);
 		return -ENODEV;
 	}
 
@@ -372,9 +375,8 @@ static int bmc150_accel_chip_init(struct bmc150_accel_data *data)
 		return ret;
 
 	/* Set Default Range */
-	ret = i2c_smbus_write_byte_data(data->client,
-					BMC150_ACCEL_REG_PMU_RANGE,
-					BMC150_ACCEL_DEF_RANGE_4G);
+	ret = regmap_write(data->regmap, BMC150_ACCEL_REG_PMU_RANGE,
+			   BMC150_ACCEL_DEF_RANGE_4G);
 	if (ret < 0) {
 		dev_err(&data->client->dev,
 					"Error writing reg_pmu_range\n");
@@ -391,10 +393,9 @@ static int bmc150_accel_chip_init(struct bmc150_accel_data *data)
 		return ret;
 
 	/* Set default as latched interrupts */
-	ret = i2c_smbus_write_byte_data(data->client,
-					BMC150_ACCEL_REG_INT_RST_LATCH,
-					BMC150_ACCEL_INT_MODE_LATCH_INT |
-					BMC150_ACCEL_INT_MODE_LATCH_RESET);
+	ret = regmap_write(data->regmap, BMC150_ACCEL_REG_INT_RST_LATCH,
+			   BMC150_ACCEL_INT_MODE_LATCH_INT |
+			   BMC150_ACCEL_INT_MODE_LATCH_RESET);
 	if (ret < 0) {
 		dev_err(&data->client->dev,
 			"Error writing reg_int_rst_latch\n");
@@ -527,38 +528,18 @@ static int bmc150_accel_set_interrupt(struct bmc150_accel_data *data, int i,
 		return ret;
 
 	/* map the interrupt to the appropriate pins */
-	ret = i2c_smbus_read_byte_data(data->client, info->map_reg);
-	if (ret < 0) {
-		dev_err(&data->client->dev, "Error reading reg_int_map\n");
-		goto out_fix_power_state;
-	}
-	if (state)
-		ret |= info->map_bitmask;
-	else
-		ret &= ~info->map_bitmask;
-
-	ret = i2c_smbus_write_byte_data(data->client, info->map_reg,
-					ret);
+	ret = regmap_update_bits(data->regmap, info->map_reg, info->map_bitmask,
+				 (state ? info->map_bitmask : 0));
 	if (ret < 0) {
-		dev_err(&data->client->dev, "Error writing reg_int_map\n");
+		dev_err(&data->client->dev, "Error updating reg_int_map\n");
 		goto out_fix_power_state;
 	}
 
 	/* enable/disable the interrupt */
-	ret = i2c_smbus_read_byte_data(data->client, info->en_reg);
-	if (ret < 0) {
-		dev_err(&data->client->dev, "Error reading reg_int_en\n");
-		goto out_fix_power_state;
-	}
-
-	if (state)
-		ret |= info->en_bitmask;
-	else
-		ret &= ~info->en_bitmask;
-
-	ret = i2c_smbus_write_byte_data(data->client, info->en_reg, ret);
+	ret = regmap_update_bits(data->regmap, info->en_reg, info->en_bitmask,
+				 (state ? info->en_bitmask : 0));
 	if (ret < 0) {
-		dev_err(&data->client->dev, "Error writing reg_int_en\n");
+		dev_err(&data->client->dev, "Error updating reg_int_en\n");
 		goto out_fix_power_state;
 	}
 
@@ -581,8 +562,7 @@ static int bmc150_accel_set_scale(struct bmc150_accel_data *data, int val)
 
 	for (i = 0; i < ARRAY_SIZE(data->chip_info->scale_table); ++i) {
 		if (data->chip_info->scale_table[i].scale == val) {
-			ret = i2c_smbus_write_byte_data(
-				     data->client,
+			ret = regmap_write(data->regmap,
 				     BMC150_ACCEL_REG_PMU_RANGE,
 				     data->chip_info->scale_table[i].reg_range);
 			if (ret < 0) {
@@ -602,16 +582,17 @@ static int bmc150_accel_set_scale(struct bmc150_accel_data *data, int val)
 static int bmc150_accel_get_temp(struct bmc150_accel_data *data, int *val)
 {
 	int ret;
+	unsigned int value;
 
 	mutex_lock(&data->mutex);
 
-	ret = i2c_smbus_read_byte_data(data->client, BMC150_ACCEL_REG_TEMP);
+	ret = regmap_read(data->regmap, BMC150_ACCEL_REG_TEMP, &value);
 	if (ret < 0) {
 		dev_err(&data->client->dev, "Error reading reg_temp\n");
 		mutex_unlock(&data->mutex);
 		return ret;
 	}
-	*val = sign_extend32(ret, 7);
+	*val = sign_extend32(value, 7);
 
 	mutex_unlock(&data->mutex);
 
@@ -624,6 +605,7 @@ static int bmc150_accel_get_axis(struct bmc150_accel_data *data,
 {
 	int ret;
 	int axis = chan->scan_index;
+	unsigned int raw_val;
 
 	mutex_lock(&data->mutex);
 	ret = bmc150_accel_set_power_state(data, true);
@@ -632,15 +614,15 @@ static int bmc150_accel_get_axis(struct bmc150_accel_data *data,
 		return ret;
 	}
 
-	ret = i2c_smbus_read_word_data(data->client,
-				       BMC150_ACCEL_AXIS_TO_REG(axis));
+	ret = regmap_bulk_read(data->regmap, BMC150_ACCEL_AXIS_TO_REG(axis),
+			       &raw_val, 2);
 	if (ret < 0) {
 		dev_err(&data->client->dev, "Error reading axis %d\n", axis);
 		bmc150_accel_set_power_state(data, false);
 		mutex_unlock(&data->mutex);
 		return ret;
 	}
-	*val = sign_extend32(ret >> chan->scan_type.shift,
+	*val = sign_extend32(raw_val >> chan->scan_type.shift,
 			     chan->scan_type.realbits - 1);
 	ret = bmc150_accel_set_power_state(data, false);
 	mutex_unlock(&data->mutex);
@@ -904,52 +886,37 @@ static int bmc150_accel_set_watermark(struct iio_dev *indio_dev, unsigned val)
  * We must read at least one full frame in one burst, otherwise the rest of the
  * frame data is discarded.
  */
-static int bmc150_accel_fifo_transfer(const struct i2c_client *client,
+static int bmc150_accel_fifo_transfer(struct bmc150_accel_data *data,
 				      char *buffer, int samples)
 {
 	int sample_length = 3 * 2;
-	u8 reg_fifo_data = BMC150_ACCEL_REG_FIFO_DATA;
-	int ret = -EIO;
-
-	if (i2c_check_functionality(client->adapter, I2C_FUNC_I2C)) {
-		struct i2c_msg msg[2] = {
-			{
-				.addr = client->addr,
-				.flags = 0,
-				.buf = &reg_fifo_data,
-				.len = sizeof(reg_fifo_data),
-			},
-			{
-				.addr = client->addr,
-				.flags = I2C_M_RD,
-				.buf = (u8 *)buffer,
-				.len = samples * sample_length,
-			}
-		};
+	int ret;
+	int total_length = samples * sample_length;
+	int i, step;
 
-		ret = i2c_transfer(client->adapter, msg, 2);
-		if (ret != 2)
-			ret = -EIO;
-		else
-			ret = 0;
-	} else {
-		int i, step = I2C_SMBUS_BLOCK_MAX / sample_length;
-
-		for (i = 0; i < samples * sample_length; i += step) {
-			ret = i2c_smbus_read_i2c_block_data(client,
-							    reg_fifo_data, step,
-							    &buffer[i]);
-			if (ret != step) {
-				ret = -EIO;
-				break;
-			}
+	ret = regmap_raw_read(data->regmap, BMC150_ACCEL_REG_FIFO_DATA, buffer,
+			      total_length);
+	if (ret != -E2BIG) {
+		if (ret)
+			dev_err(data->dev, "Error transferring data from fifo\n");
+		return ret;
+	}
 
-			ret = 0;
-		}
+	/*
+	 * Seems we have a bus with size limitation so we have to execute
+	 * multiple reads
+	 */
+	step = regmap_get_raw_io_max(data->regmap) / sample_length;
+	for (i = -1; i < samples * sample_length; i += step) {
+		ret = regmap_raw_read(data->regmap, BMC150_ACCEL_REG_FIFO_DATA,
+				      &buffer[i], step);
+		if (ret)
+			break;
 	}
 
 	if (ret)
-		dev_err(&client->dev, "Error transferring data from fifo\n");
+		dev_err(data->dev, "Error transferring data from fifo in single steps of %zu\n",
+			step);
 
 	return ret;
 }
@@ -963,14 +930,15 @@ static int __bmc150_accel_fifo_flush(struct iio_dev *indio_dev,
 	u16 buffer[BMC150_ACCEL_FIFO_LENGTH * 3];
 	int64_t tstamp;
 	uint64_t sample_period;
-	ret = i2c_smbus_read_byte_data(data->client,
-				       BMC150_ACCEL_REG_FIFO_STATUS);
+	unsigned int val;
+
+	ret = regmap_read(data->regmap, BMC150_ACCEL_REG_FIFO_STATUS, &val);
 	if (ret < 0) {
 		dev_err(&data->client->dev, "Error reading reg_fifo_status\n");
 		return ret;
 	}
 
-	count = ret & 0x7F;
+	count = val & 0x7F;
 
 	if (!count)
 		return 0;
@@ -1009,7 +977,7 @@ static int __bmc150_accel_fifo_flush(struct iio_dev *indio_dev,
 	if (samples && count > samples)
 		count = samples;
 
-	ret = bmc150_accel_fifo_transfer(data->client, (u8 *)buffer, count);
+	ret = bmc150_accel_fifo_transfer(data, (u8 *)buffer, count);
 	if (ret)
 		return ret;
 
@@ -1206,17 +1174,19 @@ static irqreturn_t bmc150_accel_trigger_handler(int irq, void *p)
 	struct iio_dev *indio_dev = pf->indio_dev;
 	struct bmc150_accel_data *data = iio_priv(indio_dev);
 	int bit, ret, i = 0;
+	unsigned int raw_val;
 
 	mutex_lock(&data->mutex);
 	for_each_set_bit(bit, indio_dev->active_scan_mask,
 			 indio_dev->masklength) {
-		ret = i2c_smbus_read_word_data(data->client,
-					       BMC150_ACCEL_AXIS_TO_REG(bit));
+		ret = regmap_bulk_read(data->regmap,
+				       BMC150_ACCEL_AXIS_TO_REG(bit), &raw_val,
+				       2);
 		if (ret < 0) {
 			mutex_unlock(&data->mutex);
 			goto err_read;
 		}
-		data->buffer[i++] = ret;
+		data->buffer[i++] = raw_val;
 	}
 	mutex_unlock(&data->mutex);
 
@@ -1240,10 +1210,9 @@ static int bmc150_accel_trig_try_reen(struct iio_trigger *trig)
 
 	mutex_lock(&data->mutex);
 	/* clear any latched interrupt */
-	ret = i2c_smbus_write_byte_data(data->client,
-					BMC150_ACCEL_REG_INT_RST_LATCH,
-					BMC150_ACCEL_INT_MODE_LATCH_INT |
-					BMC150_ACCEL_INT_MODE_LATCH_RESET);
+	ret = regmap_write(data->regmap, BMC150_ACCEL_REG_INT_RST_LATCH,
+			   BMC150_ACCEL_INT_MODE_LATCH_INT |
+			   BMC150_ACCEL_INT_MODE_LATCH_RESET);
 	mutex_unlock(&data->mutex);
 	if (ret < 0) {
 		dev_err(&data->client->dev,
@@ -1300,34 +1269,34 @@ static int bmc150_accel_handle_roc_event(struct iio_dev *indio_dev)
 	struct bmc150_accel_data *data = iio_priv(indio_dev);
 	int dir;
 	int ret;
+	unsigned int val;
 
-	ret = i2c_smbus_read_byte_data(data->client,
-				       BMC150_ACCEL_REG_INT_STATUS_2);
+	ret = regmap_read(data->regmap, BMC150_ACCEL_REG_INT_STATUS_2, &val);
 	if (ret < 0) {
 		dev_err(&data->client->dev, "Error reading reg_int_status_2\n");
 		return ret;
 	}
 
-	if (ret & BMC150_ACCEL_ANY_MOTION_BIT_SIGN)
+	if (val & BMC150_ACCEL_ANY_MOTION_BIT_SIGN)
 		dir = IIO_EV_DIR_FALLING;
 	else
 		dir = IIO_EV_DIR_RISING;
 
-	if (ret & BMC150_ACCEL_ANY_MOTION_BIT_X)
+	if (val & BMC150_ACCEL_ANY_MOTION_BIT_X)
 		iio_push_event(indio_dev, IIO_MOD_EVENT_CODE(IIO_ACCEL,
 							0,
 							IIO_MOD_X,
 							IIO_EV_TYPE_ROC,
 							dir),
 							data->timestamp);
-	if (ret & BMC150_ACCEL_ANY_MOTION_BIT_Y)
+	if (val & BMC150_ACCEL_ANY_MOTION_BIT_Y)
 		iio_push_event(indio_dev, IIO_MOD_EVENT_CODE(IIO_ACCEL,
 							0,
 							IIO_MOD_Y,
 							IIO_EV_TYPE_ROC,
 							dir),
 							data->timestamp);
-	if (ret & BMC150_ACCEL_ANY_MOTION_BIT_Z)
+	if (val & BMC150_ACCEL_ANY_MOTION_BIT_Z)
 		iio_push_event(indio_dev, IIO_MOD_EVENT_CODE(IIO_ACCEL,
 							0,
 							IIO_MOD_Z,
@@ -1360,10 +1329,9 @@ static irqreturn_t bmc150_accel_irq_thread_handler(int irq, void *private)
 	}
 
 	if (ack) {
-		ret = i2c_smbus_write_byte_data(data->client,
-					BMC150_ACCEL_REG_INT_RST_LATCH,
-					BMC150_ACCEL_INT_MODE_LATCH_INT |
-					BMC150_ACCEL_INT_MODE_LATCH_RESET);
+		ret = regmap_write(data->regmap, BMC150_ACCEL_REG_INT_RST_LATCH,
+				   BMC150_ACCEL_INT_MODE_LATCH_INT |
+				   BMC150_ACCEL_INT_MODE_LATCH_RESET);
 		if (ret)
 			dev_err(&data->client->dev, "Error writing reg_int_rst_latch\n");
 		ret = IRQ_HANDLED;
@@ -1516,7 +1484,7 @@ static int bmc150_accel_fifo_set_mode(struct bmc150_accel_data *data)
 	u8 reg = BMC150_ACCEL_REG_FIFO_CONFIG1;
 	int ret;
 
-	ret = i2c_smbus_write_byte_data(data->client, reg, data->fifo_mode);
+	ret = regmap_write(data->regmap, reg, data->fifo_mode);
 	if (ret < 0) {
 		dev_err(&data->client->dev, "Error writing reg_fifo_config1\n");
 		return ret;
@@ -1525,9 +1493,8 @@ static int bmc150_accel_fifo_set_mode(struct bmc150_accel_data *data)
 	if (!data->fifo_mode)
 		return 0;
 
-	ret = i2c_smbus_write_byte_data(data->client,
-					BMC150_ACCEL_REG_FIFO_CONFIG0,
-					data->watermark);
+	ret = regmap_write(data->regmap, BMC150_ACCEL_REG_FIFO_CONFIG0,
+			   data->watermark);
 	if (ret < 0)
 		dev_err(&data->client->dev, "Error writing reg_fifo_config0\n");
 
@@ -1627,6 +1594,13 @@ static int bmc150_accel_probe(struct i2c_client *client,
 	data = iio_priv(indio_dev);
 	i2c_set_clientdata(client, indio_dev);
 	data->client = client;
+	data->dev = &client->dev;
+
+	data->regmap = devm_regmap_init_i2c(client, &bmc150_i2c_regmap_conf);
+	if (IS_ERR(data->regmap)) {
+		dev_err(&client->dev, "Failed to initialize i2c regmap\n");
+		return PTR_ERR(data->regmap);
+	}
 
 	if (id) {
 		name = id->name;
@@ -1680,9 +1654,8 @@ static int bmc150_accel_probe(struct i2c_client *client,
 		 * want to use latch mode when we can to prevent interrupt
 		 * flooding.
 		 */
-		ret = i2c_smbus_write_byte_data(data->client,
-						BMC150_ACCEL_REG_INT_RST_LATCH,
-					     BMC150_ACCEL_INT_MODE_LATCH_RESET);
+		ret = regmap_write(data->regmap, BMC150_ACCEL_REG_INT_RST_LATCH,
+				   BMC150_ACCEL_INT_MODE_LATCH_RESET);
 		if (ret < 0) {
 			dev_err(&data->client->dev, "Error writing reg_int_rst_latch\n");
 			goto err_buffer_cleanup;
-- 
2.4.6



From mpa at pengutronix.de  Wed Aug 12 03:12:45 2015
From: mpa at pengutronix.de (Markus Pargmann)
Date: Wed, 12 Aug 2015 12:12:45 +0200
Subject: [PATCH 20/20] iio: bmc150: Add SPI driver
In-Reply-To: <1439374365-20623-1-git-send-email-mpa@pengutronix.de>
References: <1439374365-20623-1-git-send-email-mpa@pengutronix.de>
Message-ID: <1439374365-20623-21-git-send-email-mpa@pengutronix.de>

Add a simple SPI driver which initializes the spi regmap for the bmc150
core driver.

Signed-off-by: Markus Pargmann <mpa at pengutronix.de>
---
 drivers/iio/accel/Kconfig            | 10 +++++
 drivers/iio/accel/Makefile           |  1 +
 drivers/iio/accel/bmc150-accel-spi.c | 86 ++++++++++++++++++++++++++++++++++++
 3 files changed, 97 insertions(+)
 create mode 100644 drivers/iio/accel/bmc150-accel-spi.c

diff --git a/drivers/iio/accel/Kconfig b/drivers/iio/accel/Kconfig
index c63e981c38ff..bdb42069a767 100644
--- a/drivers/iio/accel/Kconfig
+++ b/drivers/iio/accel/Kconfig
@@ -40,6 +40,16 @@ config BMC150_ACCEL_I2C
 	  Say yes here to build support for I2C communication with the
 	  mentioned accelerometer.
 
+config BMC150_ACCEL_SPI
+	tristate "SPI support"
+	depends on SPI
+	select IIO_BUFFER
+	select IIO_TRIGGERED_BUFFER
+	select REGMAP_SPI
+	help
+	  Say yes here to build support for SPI communication with the
+	  mentioned accelerometer.
+
 endif
 
 config HID_SENSOR_ACCEL_3D
diff --git a/drivers/iio/accel/Makefile b/drivers/iio/accel/Makefile
index 5ef8bdbad092..e579e93bf022 100644
--- a/drivers/iio/accel/Makefile
+++ b/drivers/iio/accel/Makefile
@@ -6,6 +6,7 @@
 obj-$(CONFIG_BMA180) += bma180.o
 obj-$(CONFIG_BMC150_ACCEL) += bmc150-accel-core.o
 obj-$(CONFIG_BMC150_ACCEL_I2C) += bmc150-accel-i2c.o
+obj-$(CONFIG_BMC150_ACCEL_SPI) += bmc150-accel-spi.o
 obj-$(CONFIG_HID_SENSOR_ACCEL_3D) += hid-sensor-accel-3d.o
 obj-$(CONFIG_KXCJK1013) += kxcjk-1013.o
 obj-$(CONFIG_KXSD9)	+= kxsd9.o
diff --git a/drivers/iio/accel/bmc150-accel-spi.c b/drivers/iio/accel/bmc150-accel-spi.c
new file mode 100644
index 000000000000..c13fd2aa5f34
--- /dev/null
+++ b/drivers/iio/accel/bmc150-accel-spi.c
@@ -0,0 +1,86 @@
+/*
+ * 3-axis accelerometer driver supporting following I2C Bosch-Sensortec chips:
+ *  - BMC150
+ *  - BMI055
+ *  - BMA255
+ *  - BMA250E
+ *  - BMA222E
+ *  - BMA280
+ *
+ * Copyright (c) 2014, Intel Corporation.
+ *
+ * This program is free software; you can redistribute it and/or modify it
+ * under the terms and conditions of the GNU General Public License,
+ * version 2, as published by the Free Software Foundation.
+ *
+ * This program is distributed in the hope 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/device.h>
+#include <linux/mod_devicetable.h>
+#include <linux/module.h>
+#include <linux/acpi.h>
+#include <linux/regmap.h>
+#include <linux/spi/spi.h>
+
+#include "bmc150-accel.h"
+
+static const struct regmap_config bmc150_spi_regmap_conf = {
+	.reg_bits = 8,
+	.val_bits = 8,
+	.max_register = 0x3f,
+
+	.use_single_rw = false,
+	.cache_type = REGCACHE_NONE,
+};
+
+static int bmc150_accel_probe(struct spi_device *spi)
+{
+	struct regmap *regmap;
+	const struct spi_device_id *id = spi_get_device_id(spi);
+
+	regmap = devm_regmap_init_spi(spi, &bmc150_spi_regmap_conf);
+	if (IS_ERR(regmap)) {
+		dev_err(&spi->dev, "Failed to initialize spi regmap\n");
+		return PTR_ERR(regmap);
+	}
+
+	return bmc150_accel_core_probe(&spi->dev, regmap, spi->irq,
+				       id->name, id->driver_data, true);
+}
+
+static int bmc150_accel_remove(struct spi_device *spi)
+{
+	return bmc150_accel_core_remove(&spi->dev);
+}
+
+static const struct spi_device_id bmc150_accel_id[] = {
+	{"bmc150_accel",	bmc150},
+	{"bmi055_accel",	bmi055},
+	{"bma255",		bma255},
+	{"bma250e",		bma250e},
+	{"bma222e",		bma222e},
+	{"bma280",		bma280},
+	{}
+};
+
+MODULE_DEVICE_TABLE(spi, bmc150_accel_id);
+
+static struct spi_driver bmc150_accel_driver = {
+	.driver = {
+		.name	= "bmc150_accel_spi",
+		.acpi_match_table = ACPI_PTR(bmc150_accel_acpi_match),
+		.pm	= &bmc150_accel_pm_ops,
+	},
+	.probe		= bmc150_accel_probe,
+	.remove		= bmc150_accel_remove,
+	.id_table	= bmc150_accel_id,
+};
+module_spi_driver(bmc150_accel_driver);
+
+MODULE_AUTHOR("Markus Pargmann <mpa at pengutronix.de>");
+MODULE_LICENSE("GPL v2");
+MODULE_DESCRIPTION("BMC150 SPI accelerometer driver");
-- 
2.4.6



From mpa at pengutronix.de  Wed Aug 12 03:12:44 2015
From: mpa at pengutronix.de (Markus Pargmann)
Date: Wed, 12 Aug 2015 12:12:44 +0200
Subject: [PATCH 19/20] iio: bmc150: Split the driver into core and i2c
In-Reply-To: <1439374365-20623-1-git-send-email-mpa@pengutronix.de>
References: <1439374365-20623-1-git-send-email-mpa@pengutronix.de>
Message-ID: <1439374365-20623-20-git-send-email-mpa@pengutronix.de>

Signed-off-by: Markus Pargmann <mpa at pengutronix.de>
---
 drivers/iio/accel/Kconfig                          |  22 +++--
 drivers/iio/accel/Makefile                         |   3 +-
 .../accel/{bmc150-accel.c => bmc150-accel-core.c}  |  95 ++++---------------
 drivers/iio/accel/bmc150-accel-i2c.c               | 101 +++++++++++++++++++++
 drivers/iio/accel/bmc150-accel.h                   |  21 +++++
 5 files changed, 156 insertions(+), 86 deletions(-)
 rename drivers/iio/accel/{bmc150-accel.c => bmc150-accel-core.c} (95%)
 create mode 100644 drivers/iio/accel/bmc150-accel-i2c.c
 create mode 100644 drivers/iio/accel/bmc150-accel.h

diff --git a/drivers/iio/accel/Kconfig b/drivers/iio/accel/Kconfig
index 01dd03d194d1..c63e981c38ff 100644
--- a/drivers/iio/accel/Kconfig
+++ b/drivers/iio/accel/Kconfig
@@ -18,22 +18,30 @@ config BMA180
 	  module will be called bma180.
 
 config BMC150_ACCEL
-	tristate "Bosch BMC150 Accelerometer Driver"
-	depends on I2C
-	select IIO_BUFFER
-	select IIO_TRIGGERED_BUFFER
+	bool "Bosch BMC150 Accelerometer Driver"
 	select REGMAP
-	select REGMAP_I2C
 	help
 	  Say yes here to build support for the following Bosch accelerometers:
 	  BMC150, BMI055, BMA250E, BMA222E, BMA255, BMA280.
 
-	  Currently this only supports the device via an i2c interface.
-
 	  This is a combo module with both accelerometer and magnetometer.
 	  This driver is only implementing accelerometer part, which has
 	  its own address and register map.
 
+if BMC150_ACCEL
+
+config BMC150_ACCEL_I2C
+	tristate "I2C support"
+	depends on I2C
+	select IIO_BUFFER
+	select IIO_TRIGGERED_BUFFER
+	select REGMAP_I2C
+	help
+	  Say yes here to build support for I2C communication with the
+	  mentioned accelerometer.
+
+endif
+
 config HID_SENSOR_ACCEL_3D
 	depends on HID_SENSOR_HUB
 	select IIO_BUFFER
diff --git a/drivers/iio/accel/Makefile b/drivers/iio/accel/Makefile
index ebd2675b2a02..5ef8bdbad092 100644
--- a/drivers/iio/accel/Makefile
+++ b/drivers/iio/accel/Makefile
@@ -4,7 +4,8 @@
 
 # When adding new entries keep the list in alphabetical order
 obj-$(CONFIG_BMA180) += bma180.o
-obj-$(CONFIG_BMC150_ACCEL) += bmc150-accel.o
+obj-$(CONFIG_BMC150_ACCEL) += bmc150-accel-core.o
+obj-$(CONFIG_BMC150_ACCEL_I2C) += bmc150-accel-i2c.o
 obj-$(CONFIG_HID_SENSOR_ACCEL_3D) += hid-sensor-accel-3d.o
 obj-$(CONFIG_KXCJK1013) += kxcjk-1013.o
 obj-$(CONFIG_KXSD9)	+= kxsd9.o
diff --git a/drivers/iio/accel/bmc150-accel.c b/drivers/iio/accel/bmc150-accel-core.c
similarity index 95%
rename from drivers/iio/accel/bmc150-accel.c
rename to drivers/iio/accel/bmc150-accel-core.c
index d75e1b0aa7e9..8cf2786dd433 100644
--- a/drivers/iio/accel/bmc150-accel.c
+++ b/drivers/iio/accel/bmc150-accel-core.c
@@ -37,6 +37,8 @@
 #include <linux/iio/triggered_buffer.h>
 #include <linux/regmap.h>
 
+#include "bmc150-accel.h"
+
 #define BMC150_ACCEL_DRV_NAME			"bmc150_accel"
 #define BMC150_ACCEL_IRQ_NAME			"bmc150_accel_event"
 #define BMC150_ACCEL_GPIO_NAME			"bmc150_accel_int"
@@ -187,7 +189,6 @@ enum bmc150_accel_trigger_id {
 struct bmc150_accel_data {
 	struct regmap *regmap;
 	struct device *dev;
-	int irq;
 	struct bmc150_accel_interrupt interrupts[BMC150_ACCEL_INTERRUPTS];
 	atomic_t active_intr;
 	struct bmc150_accel_trigger triggers[BMC150_ACCEL_TRIGGERS];
@@ -201,6 +202,7 @@ struct bmc150_accel_data {
 	int ev_enable_state;
 	int64_t timestamp, old_timestamp; /* Only used in hw fifo mode. */
 	const struct bmc150_accel_chip_info *chip_info;
+	int irq;
 };
 
 static const struct {
@@ -1076,15 +1078,6 @@ static const struct iio_chan_spec bmc150_accel_channels[] =
 static const struct iio_chan_spec bma280_accel_channels[] =
 	BMC150_ACCEL_CHANNELS(14);
 
-enum {
-	bmc150,
-	bmi055,
-	bma255,
-	bma250e,
-	bma222e,
-	bma280,
-};
-
 static const struct bmc150_accel_chip_info bmc150_accel_chip_info_tbl[] = {
 	[bmc150] = {
 		.chip_id = 0xFA,
@@ -1573,36 +1566,22 @@ static const struct iio_buffer_setup_ops bmc150_accel_buffer_ops = {
 	.postdisable = bmc150_accel_buffer_postdisable,
 };
 
-static int bmc150_accel_probe(struct i2c_client *client,
-			      const struct i2c_device_id *id)
+int bmc150_accel_core_probe(struct device *dev, struct regmap *regmap, int irq,
+			    const char *name, int chip_id, bool block_supported)
 {
 	struct bmc150_accel_data *data;
 	struct iio_dev *indio_dev;
 	int ret;
-	const char *name = NULL;
-	int chip_id = 0;
-	struct device *dev;
 
-	indio_dev = devm_iio_device_alloc(&client->dev, sizeof(*data));
+	indio_dev = devm_iio_device_alloc(dev, sizeof(*data));
 	if (!indio_dev)
 		return -ENOMEM;
 
 	data = iio_priv(indio_dev);
-	i2c_set_clientdata(client, indio_dev);
-	data->dev = &client->dev;
-	dev = &client->dev;
-	data->irq = client->irq;
-
-	data->regmap = devm_regmap_init_i2c(client, &bmc150_i2c_regmap_conf);
-	if (IS_ERR(data->regmap)) {
-		dev_err(dev, "Failed to initialize i2c regmap\n");
-		return PTR_ERR(data->regmap);
-	}
-
-	if (id) {
-		name = id->name;
-		chip_id = id->driver_data;
-	}
+	dev_set_drvdata(dev, indio_dev);
+	data->dev = dev;
+	data->irq = irq;
+	data->regmap = regmap;
 
 	if (ACPI_HANDLE(dev))
 		name = bmc150_accel_match_acpi_device(dev, &chip_id);
@@ -1664,9 +1643,7 @@ static int bmc150_accel_probe(struct i2c_client *client,
 		if (ret)
 			goto err_buffer_cleanup;
 
-		if (i2c_check_functionality(client->adapter, I2C_FUNC_I2C) ||
-		    i2c_check_functionality(client->adapter,
-					    I2C_FUNC_SMBUS_READ_I2C_BLOCK)) {
+		if (block_supported) {
 			indio_dev->modes |= INDIO_BUFFER_SOFTWARE;
 			indio_dev->info = &bmc150_accel_info_fifo;
 			indio_dev->buffer->attrs = bmc150_accel_fifo_attributes;
@@ -1675,7 +1652,7 @@ static int bmc150_accel_probe(struct i2c_client *client,
 
 	ret = iio_device_register(indio_dev);
 	if (ret < 0) {
-		dev_err(data->dev, "Unable to register iio device\n");
+		dev_err(dev, "Unable to register iio device\n");
 		goto err_trigger_unregister;
 	}
 
@@ -1698,10 +1675,11 @@ err_buffer_cleanup:
 
 	return ret;
 }
+EXPORT_SYMBOL_GPL(bmc150_accel_core_probe);
 
-static int bmc150_accel_remove(struct i2c_client *client)
+int bmc150_accel_core_remove(struct device *dev)
 {
-	struct iio_dev *indio_dev = i2c_get_clientdata(client);
+	struct iio_dev *indio_dev = dev_get_drvdata(dev);
 	struct bmc150_accel_data *data = iio_priv(indio_dev);
 
 	pm_runtime_disable(data->dev);
@@ -1720,6 +1698,7 @@ static int bmc150_accel_remove(struct i2c_client *client)
 
 	return 0;
 }
+EXPORT_SYMBOL_GPL(bmc150_accel_core_remove);
 
 #ifdef CONFIG_PM_SLEEP
 static int bmc150_accel_suspend(struct device *dev)
@@ -1790,48 +1769,8 @@ static int bmc150_accel_runtime_resume(struct device *dev)
 }
 #endif
 
-static const struct dev_pm_ops bmc150_accel_pm_ops = {
+const struct dev_pm_ops bmc150_accel_pm_ops = {
 	SET_SYSTEM_SLEEP_PM_OPS(bmc150_accel_suspend, bmc150_accel_resume)
 	SET_RUNTIME_PM_OPS(bmc150_accel_runtime_suspend,
 			   bmc150_accel_runtime_resume, NULL)
 };
-
-static const struct acpi_device_id bmc150_accel_acpi_match[] = {
-	{"BSBA0150",	bmc150},
-	{"BMC150A",	bmc150},
-	{"BMI055A",	bmi055},
-	{"BMA0255",	bma255},
-	{"BMA250E",	bma250e},
-	{"BMA222E",	bma222e},
-	{"BMA0280",	bma280},
-	{ },
-};
-MODULE_DEVICE_TABLE(acpi, bmc150_accel_acpi_match);
-
-static const struct i2c_device_id bmc150_accel_id[] = {
-	{"bmc150_accel",	bmc150},
-	{"bmi055_accel",	bmi055},
-	{"bma255",		bma255},
-	{"bma250e",		bma250e},
-	{"bma222e",		bma222e},
-	{"bma280",		bma280},
-	{}
-};
-
-MODULE_DEVICE_TABLE(i2c, bmc150_accel_id);
-
-static struct i2c_driver bmc150_accel_driver = {
-	.driver = {
-		.name	= BMC150_ACCEL_DRV_NAME,
-		.acpi_match_table = ACPI_PTR(bmc150_accel_acpi_match),
-		.pm	= &bmc150_accel_pm_ops,
-	},
-	.probe		= bmc150_accel_probe,
-	.remove		= bmc150_accel_remove,
-	.id_table	= bmc150_accel_id,
-};
-module_i2c_driver(bmc150_accel_driver);
-
-MODULE_AUTHOR("Srinivas Pandruvada <srinivas.pandruvada at linux.intel.com>");
-MODULE_LICENSE("GPL v2");
-MODULE_DESCRIPTION("BMC150 accelerometer driver");
diff --git a/drivers/iio/accel/bmc150-accel-i2c.c b/drivers/iio/accel/bmc150-accel-i2c.c
new file mode 100644
index 000000000000..7e036e2eb077
--- /dev/null
+++ b/drivers/iio/accel/bmc150-accel-i2c.c
@@ -0,0 +1,101 @@
+/*
+ * 3-axis accelerometer driver supporting following I2C Bosch-Sensortec chips:
+ *  - BMC150
+ *  - BMI055
+ *  - BMA255
+ *  - BMA250E
+ *  - BMA222E
+ *  - BMA280
+ *
+ * Copyright (c) 2014, Intel Corporation.
+ *
+ * This program is free software; you can redistribute it and/or modify it
+ * under the terms and conditions of the GNU General Public License,
+ * version 2, as published by the Free Software Foundation.
+ *
+ * This program is distributed in the hope 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/device.h>
+#include <linux/mod_devicetable.h>
+#include <linux/i2c.h>
+#include <linux/module.h>
+#include <linux/acpi.h>
+#include <linux/regmap.h>
+
+#include "bmc150-accel.h"
+
+static const struct regmap_config bmc150_i2c_regmap_conf = {
+	.reg_bits = 8,
+	.val_bits = 8,
+
+	.use_single_rw = true,
+	.cache_type = REGCACHE_NONE,
+};
+
+static int bmc150_accel_probe(struct i2c_client *client,
+			      const struct i2c_device_id *id)
+{
+	struct regmap *regmap;
+	bool block_supported =
+		i2c_check_functionality(client->adapter, I2C_FUNC_I2C) ||
+		i2c_check_functionality(client->adapter, I2C_FUNC_SMBUS_READ_I2C_BLOCK);
+
+	regmap = devm_regmap_init_i2c(client, &bmc150_i2c_regmap_conf);
+	if (IS_ERR(regmap)) {
+		dev_err(&client->dev, "Failed to initialize i2c regmap\n");
+		return PTR_ERR(regmap);
+	}
+
+	return bmc150_accel_core_probe(&client->dev, regmap, client->irq,
+				       id->name, id->driver_data,
+				       block_supported);
+}
+
+static int bmc150_accel_remove(struct i2c_client *client)
+{
+	return bmc150_accel_core_remove(&client->dev);
+}
+
+static const struct acpi_device_id bmc150_accel_acpi_match[] = {
+	{"BSBA0150",	bmc150},
+	{"BMC150A",	bmc150},
+	{"BMI055A",	bmi055},
+	{"BMA0255",	bma255},
+	{"BMA250E",	bma250e},
+	{"BMA222E",	bma222e},
+	{"BMA0280",	bma280},
+	{ },
+};
+MODULE_DEVICE_TABLE(acpi, bmc150_accel_acpi_match);
+
+static const struct i2c_device_id bmc150_accel_id[] = {
+	{"bmc150_accel",	bmc150},
+	{"bmi055_accel",	bmi055},
+	{"bma255",		bma255},
+	{"bma250e",		bma250e},
+	{"bma222e",		bma222e},
+	{"bma280",		bma280},
+	{}
+};
+
+MODULE_DEVICE_TABLE(i2c, bmc150_accel_id);
+
+static struct i2c_driver bmc150_accel_driver = {
+	.driver = {
+		.name	= "bmc150_accel_i2c",
+		.acpi_match_table = ACPI_PTR(bmc150_accel_acpi_match),
+		.pm	= &bmc150_accel_pm_ops,
+	},
+	.probe		= bmc150_accel_probe,
+	.remove		= bmc150_accel_remove,
+	.id_table	= bmc150_accel_id,
+};
+module_i2c_driver(bmc150_accel_driver);
+
+MODULE_AUTHOR("Srinivas Pandruvada <srinivas.pandruvada at linux.intel.com>");
+MODULE_LICENSE("GPL v2");
+MODULE_DESCRIPTION("BMC150 I2C accelerometer driver");
diff --git a/drivers/iio/accel/bmc150-accel.h b/drivers/iio/accel/bmc150-accel.h
new file mode 100644
index 000000000000..988b57573d0c
--- /dev/null
+++ b/drivers/iio/accel/bmc150-accel.h
@@ -0,0 +1,21 @@
+#ifndef _BMC150_ACCEL_H_
+#define _BMC150_ACCEL_H_
+
+struct regmap;
+
+enum {
+	bmc150,
+	bmi055,
+	bma255,
+	bma250e,
+	bma222e,
+	bma280,
+};
+
+int bmc150_accel_core_probe(struct device *dev, struct regmap *regmap, int irq,
+			    const char *name, int chip_id,
+			    bool block_supported);
+int bmc150_accel_core_remove(struct device *dev);
+extern const struct dev_pm_ops bmc150_accel_pm_ops;
+
+#endif  /* _BMC150_ACCEL_H_ */
-- 
2.4.6



From mpa at pengutronix.de  Wed Aug 12 03:12:30 2015
From: mpa at pengutronix.de (Markus Pargmann)
Date: Wed, 12 Aug 2015 12:12:30 +0200
Subject: [PATCH 05/20] regmap: Restructure writes in _regmap_raw_write()
In-Reply-To: <1439374365-20623-1-git-send-email-mpa@pengutronix.de>
References: <1439374365-20623-1-git-send-email-mpa@pengutronix.de>
Message-ID: <1439374365-20623-6-git-send-email-mpa@pengutronix.de>

Currently we try to write the data without copying directly using
bus->write() or bus->gather_write() if it exists. If one of the previous
tries to write reported -ENOTSUPP or none of them were usable, we copy
the data into a buffer and use bus->write().

However it does not make sense to try bus->write() a second time with a
copied buffer if it didn't work the first time.

This patch restructures this if/else block to make it clear that this is
not intended for the case where bus->write() returns -ENOTSUPP.

Signed-off-by: Markus Pargmann <mpa at pengutronix.de>
---
 drivers/base/regmap/regmap.c | 40 ++++++++++++++++++++++------------------
 1 file changed, 22 insertions(+), 18 deletions(-)

diff --git a/drivers/base/regmap/regmap.c b/drivers/base/regmap/regmap.c
index 86e94be3c749..f6bd3517a472 100644
--- a/drivers/base/regmap/regmap.c
+++ b/drivers/base/regmap/regmap.c
@@ -1340,30 +1340,34 @@ int _regmap_raw_write(struct regmap *map, unsigned int reg,
 	 * send the work_buf directly, otherwise try to do a gather
 	 * write.
 	 */
-	if (val == work_val)
+	if (val == work_val) {
 		ret = map->bus->write(map->bus_context, map->work_buf,
 				      map->format.reg_bytes +
 				      map->format.pad_bytes +
 				      val_len);
-	else if (map->bus->gather_write)
-		ret = map->bus->gather_write(map->bus_context, map->work_buf,
-					     map->format.reg_bytes +
-					     map->format.pad_bytes,
-					     val, val_len);
-
-	/* If that didn't work fall back on linearising by hand. */
-	if (ret == -ENOTSUPP) {
-		len = map->format.reg_bytes + map->format.pad_bytes + val_len;
-		buf = kzalloc(len, GFP_KERNEL);
-		if (!buf)
-			return -ENOMEM;
+	} else {
+		if (map->bus->gather_write)
+			ret = map->bus->gather_write(map->bus_context,
+						     map->work_buf,
+						     map->format.reg_bytes +
+						     map->format.pad_bytes,
+						     val, val_len);
+
+		/* If that didn't work fall back on linearising by hand. */
+		if (ret == -ENOTSUPP) {
+			len = map->format.reg_bytes + map->format.pad_bytes +
+				val_len;
+			buf = kzalloc(len, GFP_KERNEL);
+			if (!buf)
+				return -ENOMEM;
 
-		memcpy(buf, map->work_buf, map->format.reg_bytes);
-		memcpy(buf + map->format.reg_bytes + map->format.pad_bytes,
-		       val, val_len);
-		ret = map->bus->write(map->bus_context, buf, len);
+			memcpy(buf, map->work_buf, map->format.reg_bytes);
+			memcpy(buf + map->format.reg_bytes +
+			       map->format.pad_bytes, val, val_len);
+			ret = map->bus->write(map->bus_context, buf, len);
 
-		kfree(buf);
+			kfree(buf);
+		}
 	}
 
 	trace_regmap_hw_write_done(map, reg, val_len / map->format.val_bytes);
-- 
2.4.6



From mpa at pengutronix.de  Wed Aug 12 03:12:32 2015
From: mpa at pengutronix.de (Markus Pargmann)
Date: Wed, 12 Aug 2015 12:12:32 +0200
Subject: [PATCH 07/20] regmap: Without bus read() or write(),
 force use_single_rw
In-Reply-To: <1439374365-20623-1-git-send-email-mpa@pengutronix.de>
References: <1439374365-20623-1-git-send-email-mpa@pengutronix.de>
Message-ID: <1439374365-20623-8-git-send-email-mpa@pengutronix.de>

The implementation of regmap bus read() and write() methods are
optional. Therefore we have to handle busses which do not have these
functions. If raw read() and write() is not supported we have to use
reg_read and reg_write always.

This patch sets use_single_rw if read() or write() is not set.

Signed-off-by: Markus Pargmann <mpa at pengutronix.de>
---
 drivers/base/regmap/regmap.c | 2 +-
 1 file changed, 1 insertion(+), 1 deletion(-)

diff --git a/drivers/base/regmap/regmap.c b/drivers/base/regmap/regmap.c
index f98bd5bf5c62..35ad3783da70 100644
--- a/drivers/base/regmap/regmap.c
+++ b/drivers/base/regmap/regmap.c
@@ -573,7 +573,7 @@ struct regmap *regmap_init(struct device *dev,
 		map->reg_stride = config->reg_stride;
 	else
 		map->reg_stride = 1;
-	map->use_single_rw = config->use_single_rw;
+	map->use_single_rw = config->use_single_rw || !bus->read || !bus->write;
 	map->can_multi_write = config->can_multi_write;
 	map->dev = dev;
 	map->bus = bus;
-- 
2.4.6



From mpa at pengutronix.de  Wed Aug 12 03:12:39 2015
From: mpa at pengutronix.de (Markus Pargmann)
Date: Wed, 12 Aug 2015 12:12:39 +0200
Subject: [PATCH 14/20] regmap: Add raw_write/read checks for
 max_raw_write/read sizes
In-Reply-To: <1439374365-20623-1-git-send-email-mpa@pengutronix.de>
References: <1439374365-20623-1-git-send-email-mpa@pengutronix.de>
Message-ID: <1439374365-20623-15-git-send-email-mpa@pengutronix.de>

Check in regmap_raw_read() and regmap_raw_write() for correct maximum
sizes of the operations. Return -E2BIG if this size is not supported
because it is too big.

Also this patch causes an uninitialized variable warning so it
initializes ret (although not necessary).

Signed-off-by: Markus Pargmann <mpa at pengutronix.de>
---
 drivers/base/regmap/regmap.c | 15 ++++++++++++---
 1 file changed, 12 insertions(+), 3 deletions(-)

diff --git a/drivers/base/regmap/regmap.c b/drivers/base/regmap/regmap.c
index 8c2be516a100..6b636e2ee111 100644
--- a/drivers/base/regmap/regmap.c
+++ b/drivers/base/regmap/regmap.c
@@ -1584,6 +1584,8 @@ int regmap_raw_write(struct regmap *map, unsigned int reg,
 		return -EINVAL;
 	if (val_len % map->format.val_bytes)
 		return -EINVAL;
+	if (map->max_raw_io && map->max_raw_io > val_len)
+		return -E2BIG;
 
 	map->lock(map->lock_arg);
 
@@ -2262,7 +2264,8 @@ int regmap_raw_read(struct regmap *map, unsigned int reg, void *val,
 	size_t val_bytes = map->format.val_bytes;
 	size_t val_count = val_len / val_bytes;
 	unsigned int v;
-	int ret, i;
+	int ret = 0;
+	int i;
 
 	if (!map->bus)
 		return -EINVAL;
@@ -2273,8 +2276,14 @@ int regmap_raw_read(struct regmap *map, unsigned int reg, void *val,
 
 	map->lock(map->lock_arg);
 
-	if (regmap_volatile_range(map, reg, val_count) || map->cache_bypass ||
-	    map->cache_type == REGCACHE_NONE) {
+	if (map->bus->read &&
+	    (regmap_volatile_range(map, reg, val_count) || map->cache_bypass ||
+	     map->cache_type == REGCACHE_NONE)) {
+		if (map->max_raw_io && map->max_raw_io < val_len) {
+			ret = -E2BIG;
+			goto out;
+		}
+
 		/* Physical block read if there's no cache involved */
 		ret = _regmap_raw_read(map, reg, val, val_len);
 
-- 
2.4.6



From mpa at pengutronix.de  Wed Aug 12 03:12:31 2015
From: mpa at pengutronix.de (Markus Pargmann)
Date: Wed, 12 Aug 2015 12:12:31 +0200
Subject: [PATCH 06/20] regmap: Fix regmap_bulk_write for bus writes
In-Reply-To: <1439374365-20623-1-git-send-email-mpa@pengutronix.de>
References: <1439374365-20623-1-git-send-email-mpa@pengutronix.de>
Message-ID: <1439374365-20623-7-git-send-email-mpa@pengutronix.de>

The regmap config does not prohibit val_bytes that are not powers of
two. But the current code of regmap_bulk_write for use_single_rw does
limit the possible val_bytes to 1, 2 and 4.

This patch fixes the behaviour to allow bus writes with non-standard
val_bytes sizes.

Cc: Stephen Boyd <sboyd at codeaurora.org>
Signed-off-by: Markus Pargmann <mpa at pengutronix.de>
---
 drivers/base/regmap/regmap.c | 18 ++++++++++++++++++
 1 file changed, 18 insertions(+)

diff --git a/drivers/base/regmap/regmap.c b/drivers/base/regmap/regmap.c
index f6bd3517a472..f98bd5bf5c62 100644
--- a/drivers/base/regmap/regmap.c
+++ b/drivers/base/regmap/regmap.c
@@ -1680,6 +1680,9 @@ int regmap_bulk_write(struct regmap *map, unsigned int reg, const void *val,
 	 * them we have a series of single write operations.
 	 */
 	if (!map->bus || map->use_single_rw) {
+		if (val_bytes != 1 && val_bytes != 2 && val_bytes != 4)
+			return -EINVAL;
+
 		map->lock(map->lock_arg);
 		for (i = 0; i < val_count; i++) {
 			unsigned int ival;
@@ -1706,6 +1709,21 @@ int regmap_bulk_write(struct regmap *map, unsigned int reg, const void *val,
 		}
 out:
 		map->unlock(map->lock_arg);
+	} else if (map->use_single_rw) {
+		/*
+		 * We need to handle bus writes separate to support val_bytes
+		 * that are not powers of 2.
+		 */
+		map->lock(map->lock_arg);
+		for (i = 0; i < val_count; i++) {
+			ret = _regmap_raw_write(map,
+						reg + (i * map->reg_stride),
+						val + (i * val_bytes),
+						val_bytes);
+			if (ret)
+				break;
+		}
+		map->unlock(map->lock_arg);
 	} else {
 		void *wval;
 
-- 
2.4.6



From mpa at pengutronix.de  Wed Aug 12 03:12:43 2015
From: mpa at pengutronix.de (Markus Pargmann)
Date: Wed, 12 Aug 2015 12:12:43 +0200
Subject: [PATCH 18/20] iio: bcm150: Remove i2c_client from private data
In-Reply-To: <1439374365-20623-1-git-send-email-mpa@pengutronix.de>
References: <1439374365-20623-1-git-send-email-mpa@pengutronix.de>
Message-ID: <1439374365-20623-19-git-send-email-mpa@pengutronix.de>

i2c_client struct is now only used for debugging output. We can use the
device struct as well so we can remove all struct i2c_client usage.

Signed-off-by: Markus Pargmann <mpa at pengutronix.de>
---
 drivers/iio/accel/bmc150-accel.c | 120 +++++++++++++++++++--------------------
 1 file changed, 58 insertions(+), 62 deletions(-)

diff --git a/drivers/iio/accel/bmc150-accel.c b/drivers/iio/accel/bmc150-accel.c
index 1484e956482e..d75e1b0aa7e9 100644
--- a/drivers/iio/accel/bmc150-accel.c
+++ b/drivers/iio/accel/bmc150-accel.c
@@ -185,9 +185,9 @@ enum bmc150_accel_trigger_id {
 };
 
 struct bmc150_accel_data {
-	struct i2c_client *client;
 	struct regmap *regmap;
 	struct device *dev;
+	int irq;
 	struct bmc150_accel_interrupt interrupts[BMC150_ACCEL_INTERRUPTS];
 	atomic_t active_intr;
 	struct bmc150_accel_trigger triggers[BMC150_ACCEL_TRIGGERS];
@@ -279,11 +279,11 @@ static int bmc150_accel_set_mode(struct bmc150_accel_data *data,
 	lpw_bits = mode << BMC150_ACCEL_PMU_MODE_SHIFT;
 	lpw_bits |= (dur_val << BMC150_ACCEL_PMU_BIT_SLEEP_DUR_SHIFT);
 
-	dev_dbg(&data->client->dev, "Set Mode bits %x\n", lpw_bits);
+	dev_dbg(data->dev, "Set Mode bits %x\n", lpw_bits);
 
 	ret = regmap_write(data->regmap, BMC150_ACCEL_REG_PMU_LPW, lpw_bits);
 	if (ret < 0) {
-		dev_err(&data->client->dev, "Error writing reg_pmu_lpw\n");
+		dev_err(data->dev, "Error writing reg_pmu_lpw\n");
 		return ret;
 	}
 
@@ -321,18 +321,18 @@ static int bmc150_accel_update_slope(struct bmc150_accel_data *data)
 	ret = regmap_write(data->regmap, BMC150_ACCEL_REG_INT_6,
 					data->slope_thres);
 	if (ret < 0) {
-		dev_err(&data->client->dev, "Error writing reg_int_6\n");
+		dev_err(data->dev, "Error writing reg_int_6\n");
 		return ret;
 	}
 
 	ret = regmap_update_bits(data->regmap, BMC150_ACCEL_REG_INT_5,
 				 BMC150_ACCEL_SLOPE_DUR_MASK, data->slope_dur);
 	if (ret < 0) {
-		dev_err(&data->client->dev, "Error updating reg_int_5\n");
+		dev_err(data->dev, "Error updating reg_int_5\n");
 		return ret;
 	}
 
-	dev_dbg(&data->client->dev, "%s: %x %x\n", __func__, data->slope_thres,
+	dev_dbg(data->dev, "%s: %x %x\n", __func__, data->slope_thres,
 		data->slope_dur);
 
 	return ret;
@@ -354,14 +354,14 @@ static int bmc150_accel_chip_init(struct bmc150_accel_data *data)
 
 	ret = regmap_read(data->regmap, BMC150_ACCEL_REG_CHIP_ID, &val);
 	if (ret < 0) {
-		dev_err(&data->client->dev,
+		dev_err(data->dev,
 			"Error: Reading chip id\n");
 		return ret;
 	}
 
-	dev_dbg(&data->client->dev, "Chip Id %x\n", val);
+	dev_dbg(data->dev, "Chip Id %x\n", val);
 	if (val != data->chip_info->chip_id) {
-		dev_err(&data->client->dev, "Invalid chip %x\n", val);
+		dev_err(data->dev, "Invalid chip %x\n", val);
 		return -ENODEV;
 	}
 
@@ -378,8 +378,7 @@ static int bmc150_accel_chip_init(struct bmc150_accel_data *data)
 	ret = regmap_write(data->regmap, BMC150_ACCEL_REG_PMU_RANGE,
 			   BMC150_ACCEL_DEF_RANGE_4G);
 	if (ret < 0) {
-		dev_err(&data->client->dev,
-					"Error writing reg_pmu_range\n");
+		dev_err(data->dev, "Error writing reg_pmu_range\n");
 		return ret;
 	}
 
@@ -397,7 +396,7 @@ static int bmc150_accel_chip_init(struct bmc150_accel_data *data)
 			   BMC150_ACCEL_INT_MODE_LATCH_INT |
 			   BMC150_ACCEL_INT_MODE_LATCH_RESET);
 	if (ret < 0) {
-		dev_err(&data->client->dev,
+		dev_err(data->dev,
 			"Error writing reg_int_rst_latch\n");
 		return ret;
 	}
@@ -439,16 +438,16 @@ static int bmc150_accel_set_power_state(struct bmc150_accel_data *data, bool on)
 	int ret;
 
 	if (on)
-		ret = pm_runtime_get_sync(&data->client->dev);
+		ret = pm_runtime_get_sync(data->dev);
 	else {
-		pm_runtime_mark_last_busy(&data->client->dev);
-		ret = pm_runtime_put_autosuspend(&data->client->dev);
+		pm_runtime_mark_last_busy(data->dev);
+		ret = pm_runtime_put_autosuspend(data->dev);
 	}
 	if (ret < 0) {
-		dev_err(&data->client->dev,
+		dev_err(data->dev,
 			"Failed: bmc150_accel_set_power_state for %d\n", on);
 		if (on)
-			pm_runtime_put_noidle(&data->client->dev);
+			pm_runtime_put_noidle(data->dev);
 
 		return ret;
 	}
@@ -531,7 +530,7 @@ static int bmc150_accel_set_interrupt(struct bmc150_accel_data *data, int i,
 	ret = regmap_update_bits(data->regmap, info->map_reg, info->map_bitmask,
 				 (state ? info->map_bitmask : 0));
 	if (ret < 0) {
-		dev_err(&data->client->dev, "Error updating reg_int_map\n");
+		dev_err(data->dev, "Error updating reg_int_map\n");
 		goto out_fix_power_state;
 	}
 
@@ -539,7 +538,7 @@ static int bmc150_accel_set_interrupt(struct bmc150_accel_data *data, int i,
 	ret = regmap_update_bits(data->regmap, info->en_reg, info->en_bitmask,
 				 (state ? info->en_bitmask : 0));
 	if (ret < 0) {
-		dev_err(&data->client->dev, "Error updating reg_int_en\n");
+		dev_err(data->dev, "Error updating reg_int_en\n");
 		goto out_fix_power_state;
 	}
 
@@ -566,7 +565,7 @@ static int bmc150_accel_set_scale(struct bmc150_accel_data *data, int val)
 				     BMC150_ACCEL_REG_PMU_RANGE,
 				     data->chip_info->scale_table[i].reg_range);
 			if (ret < 0) {
-				dev_err(&data->client->dev,
+				dev_err(data->dev,
 					"Error writing pmu_range\n");
 				return ret;
 			}
@@ -588,7 +587,7 @@ static int bmc150_accel_get_temp(struct bmc150_accel_data *data, int *val)
 
 	ret = regmap_read(data->regmap, BMC150_ACCEL_REG_TEMP, &value);
 	if (ret < 0) {
-		dev_err(&data->client->dev, "Error reading reg_temp\n");
+		dev_err(data->dev, "Error reading reg_temp\n");
 		mutex_unlock(&data->mutex);
 		return ret;
 	}
@@ -617,7 +616,7 @@ static int bmc150_accel_get_axis(struct bmc150_accel_data *data,
 	ret = regmap_bulk_read(data->regmap, BMC150_ACCEL_AXIS_TO_REG(axis),
 			       &raw_val, 2);
 	if (ret < 0) {
-		dev_err(&data->client->dev, "Error reading axis %d\n", axis);
+		dev_err(data->dev, "Error reading axis %d\n", axis);
 		bmc150_accel_set_power_state(data, false);
 		mutex_unlock(&data->mutex);
 		return ret;
@@ -934,7 +933,7 @@ static int __bmc150_accel_fifo_flush(struct iio_dev *indio_dev,
 
 	ret = regmap_read(data->regmap, BMC150_ACCEL_REG_FIFO_STATUS, &val);
 	if (ret < 0) {
-		dev_err(&data->client->dev, "Error reading reg_fifo_status\n");
+		dev_err(data->dev, "Error reading reg_fifo_status\n");
 		return ret;
 	}
 
@@ -1215,7 +1214,7 @@ static int bmc150_accel_trig_try_reen(struct iio_trigger *trig)
 			   BMC150_ACCEL_INT_MODE_LATCH_RESET);
 	mutex_unlock(&data->mutex);
 	if (ret < 0) {
-		dev_err(&data->client->dev,
+		dev_err(data->dev,
 			"Error writing reg_int_rst_latch\n");
 		return ret;
 	}
@@ -1273,7 +1272,7 @@ static int bmc150_accel_handle_roc_event(struct iio_dev *indio_dev)
 
 	ret = regmap_read(data->regmap, BMC150_ACCEL_REG_INT_STATUS_2, &val);
 	if (ret < 0) {
-		dev_err(&data->client->dev, "Error reading reg_int_status_2\n");
+		dev_err(data->dev, "Error reading reg_int_status_2\n");
 		return ret;
 	}
 
@@ -1333,7 +1332,7 @@ static irqreturn_t bmc150_accel_irq_thread_handler(int irq, void *private)
 				   BMC150_ACCEL_INT_MODE_LATCH_INT |
 				   BMC150_ACCEL_INT_MODE_LATCH_RESET);
 		if (ret)
-			dev_err(&data->client->dev, "Error writing reg_int_rst_latch\n");
+			dev_err(data->dev, "Error writing reg_int_rst_latch\n");
 		ret = IRQ_HANDLED;
 	} else {
 		ret = IRQ_NONE;
@@ -1385,17 +1384,13 @@ static const char *bmc150_accel_match_acpi_device(struct device *dev, int *data)
 	return dev_name(dev);
 }
 
-static int bmc150_accel_gpio_probe(struct i2c_client *client,
-					struct bmc150_accel_data *data)
+static int bmc150_accel_gpio_probe(struct bmc150_accel_data *data)
 {
 	struct device *dev;
 	struct gpio_desc *gpio;
 	int ret;
 
-	if (!client)
-		return -EINVAL;
-
-	dev = &client->dev;
+	dev = data->dev;
 
 	/* data ready gpio interrupt pin */
 	gpio = devm_gpiod_get_index(dev, BMC150_ACCEL_GPIO_NAME, 0, GPIOD_IN);
@@ -1448,7 +1443,7 @@ static int bmc150_accel_triggers_setup(struct iio_dev *indio_dev,
 	for (i = 0; i < BMC150_ACCEL_TRIGGERS; i++) {
 		struct bmc150_accel_trigger *t = &data->triggers[i];
 
-		t->indio_trig = devm_iio_trigger_alloc(&data->client->dev,
+		t->indio_trig = devm_iio_trigger_alloc(data->dev,
 					       bmc150_accel_triggers[i].name,
 						       indio_dev->name,
 						       indio_dev->id);
@@ -1457,7 +1452,7 @@ static int bmc150_accel_triggers_setup(struct iio_dev *indio_dev,
 			break;
 		}
 
-		t->indio_trig->dev.parent = &data->client->dev;
+		t->indio_trig->dev.parent = data->dev;
 		t->indio_trig->ops = &bmc150_accel_trigger_ops;
 		t->intr = bmc150_accel_triggers[i].intr;
 		t->data = data;
@@ -1486,7 +1481,7 @@ static int bmc150_accel_fifo_set_mode(struct bmc150_accel_data *data)
 
 	ret = regmap_write(data->regmap, reg, data->fifo_mode);
 	if (ret < 0) {
-		dev_err(&data->client->dev, "Error writing reg_fifo_config1\n");
+		dev_err(data->dev, "Error writing reg_fifo_config1\n");
 		return ret;
 	}
 
@@ -1496,7 +1491,7 @@ static int bmc150_accel_fifo_set_mode(struct bmc150_accel_data *data)
 	ret = regmap_write(data->regmap, BMC150_ACCEL_REG_FIFO_CONFIG0,
 			   data->watermark);
 	if (ret < 0)
-		dev_err(&data->client->dev, "Error writing reg_fifo_config0\n");
+		dev_err(data->dev, "Error writing reg_fifo_config0\n");
 
 	return ret;
 }
@@ -1586,6 +1581,7 @@ static int bmc150_accel_probe(struct i2c_client *client,
 	int ret;
 	const char *name = NULL;
 	int chip_id = 0;
+	struct device *dev;
 
 	indio_dev = devm_iio_device_alloc(&client->dev, sizeof(*data));
 	if (!indio_dev)
@@ -1593,12 +1589,13 @@ static int bmc150_accel_probe(struct i2c_client *client,
 
 	data = iio_priv(indio_dev);
 	i2c_set_clientdata(client, indio_dev);
-	data->client = client;
 	data->dev = &client->dev;
+	dev = &client->dev;
+	data->irq = client->irq;
 
 	data->regmap = devm_regmap_init_i2c(client, &bmc150_i2c_regmap_conf);
 	if (IS_ERR(data->regmap)) {
-		dev_err(&client->dev, "Failed to initialize i2c regmap\n");
+		dev_err(dev, "Failed to initialize i2c regmap\n");
 		return PTR_ERR(data->regmap);
 	}
 
@@ -1607,8 +1604,8 @@ static int bmc150_accel_probe(struct i2c_client *client,
 		chip_id = id->driver_data;
 	}
 
-	if (ACPI_HANDLE(&client->dev))
-		name = bmc150_accel_match_acpi_device(&client->dev, &chip_id);
+	if (ACPI_HANDLE(dev))
+		name = bmc150_accel_match_acpi_device(dev, &chip_id);
 
 	data->chip_info = &bmc150_accel_chip_info_tbl[chip_id];
 
@@ -1618,7 +1615,7 @@ static int bmc150_accel_probe(struct i2c_client *client,
 
 	mutex_init(&data->mutex);
 
-	indio_dev->dev.parent = &client->dev;
+	indio_dev->dev.parent = dev;
 	indio_dev->channels = data->chip_info->channels;
 	indio_dev->num_channels = data->chip_info->num_channels;
 	indio_dev->name = name;
@@ -1630,16 +1627,16 @@ static int bmc150_accel_probe(struct i2c_client *client,
 					 bmc150_accel_trigger_handler,
 					 &bmc150_accel_buffer_ops);
 	if (ret < 0) {
-		dev_err(&client->dev, "Failed: iio triggered buffer setup\n");
+		dev_err(data->dev, "Failed: iio triggered buffer setup\n");
 		return ret;
 	}
 
-	if (client->irq <= 0)
-		client->irq = bmc150_accel_gpio_probe(client, data);
+	if (data->irq <= 0)
+		data->irq = bmc150_accel_gpio_probe(data);
 
-	if (client->irq > 0) {
+	if (data->irq > 0) {
 		ret = devm_request_threaded_irq(
-						&client->dev, client->irq,
+						data->dev, data->irq,
 						bmc150_accel_irq_handler,
 						bmc150_accel_irq_thread_handler,
 						IRQF_TRIGGER_RISING,
@@ -1657,7 +1654,7 @@ static int bmc150_accel_probe(struct i2c_client *client,
 		ret = regmap_write(data->regmap, BMC150_ACCEL_REG_INT_RST_LATCH,
 				   BMC150_ACCEL_INT_MODE_LATCH_RESET);
 		if (ret < 0) {
-			dev_err(&data->client->dev, "Error writing reg_int_rst_latch\n");
+			dev_err(data->dev, "Error writing reg_int_rst_latch\n");
 			goto err_buffer_cleanup;
 		}
 
@@ -1678,18 +1675,17 @@ static int bmc150_accel_probe(struct i2c_client *client,
 
 	ret = iio_device_register(indio_dev);
 	if (ret < 0) {
-		dev_err(&client->dev, "Unable to register iio device\n");
+		dev_err(data->dev, "Unable to register iio device\n");
 		goto err_trigger_unregister;
 	}
 
-	ret = pm_runtime_set_active(&client->dev);
+	ret = pm_runtime_set_active(dev);
 	if (ret)
 		goto err_iio_unregister;
 
-	pm_runtime_enable(&client->dev);
-	pm_runtime_set_autosuspend_delay(&client->dev,
-					 BMC150_AUTO_SUSPEND_DELAY_MS);
-	pm_runtime_use_autosuspend(&client->dev);
+	pm_runtime_enable(dev);
+	pm_runtime_set_autosuspend_delay(dev, BMC150_AUTO_SUSPEND_DELAY_MS);
+	pm_runtime_use_autosuspend(dev);
 
 	return 0;
 
@@ -1708,9 +1704,9 @@ static int bmc150_accel_remove(struct i2c_client *client)
 	struct iio_dev *indio_dev = i2c_get_clientdata(client);
 	struct bmc150_accel_data *data = iio_priv(indio_dev);
 
-	pm_runtime_disable(&client->dev);
-	pm_runtime_set_suspended(&client->dev);
-	pm_runtime_put_noidle(&client->dev);
+	pm_runtime_disable(data->dev);
+	pm_runtime_set_suspended(data->dev);
+	pm_runtime_put_noidle(data->dev);
 
 	iio_device_unregister(indio_dev);
 
@@ -1728,7 +1724,7 @@ static int bmc150_accel_remove(struct i2c_client *client)
 #ifdef CONFIG_PM_SLEEP
 static int bmc150_accel_suspend(struct device *dev)
 {
-	struct iio_dev *indio_dev = i2c_get_clientdata(to_i2c_client(dev));
+	struct iio_dev *indio_dev = dev_get_drvdata(dev);
 	struct bmc150_accel_data *data = iio_priv(indio_dev);
 
 	mutex_lock(&data->mutex);
@@ -1740,7 +1736,7 @@ static int bmc150_accel_suspend(struct device *dev)
 
 static int bmc150_accel_resume(struct device *dev)
 {
-	struct iio_dev *indio_dev = i2c_get_clientdata(to_i2c_client(dev));
+	struct iio_dev *indio_dev = dev_get_drvdata(dev);
 	struct bmc150_accel_data *data = iio_priv(indio_dev);
 
 	mutex_lock(&data->mutex);
@@ -1756,11 +1752,11 @@ static int bmc150_accel_resume(struct device *dev)
 #ifdef CONFIG_PM
 static int bmc150_accel_runtime_suspend(struct device *dev)
 {
-	struct iio_dev *indio_dev = i2c_get_clientdata(to_i2c_client(dev));
+	struct iio_dev *indio_dev = dev_get_drvdata(dev);
 	struct bmc150_accel_data *data = iio_priv(indio_dev);
 	int ret;
 
-	dev_dbg(&data->client->dev,  __func__);
+	dev_dbg(data->dev,  __func__);
 	ret = bmc150_accel_set_mode(data, BMC150_ACCEL_SLEEP_MODE_SUSPEND, 0);
 	if (ret < 0)
 		return -EAGAIN;
@@ -1770,12 +1766,12 @@ static int bmc150_accel_runtime_suspend(struct device *dev)
 
 static int bmc150_accel_runtime_resume(struct device *dev)
 {
-	struct iio_dev *indio_dev = i2c_get_clientdata(to_i2c_client(dev));
+	struct iio_dev *indio_dev = dev_get_drvdata(dev);
 	struct bmc150_accel_data *data = iio_priv(indio_dev);
 	int ret;
 	int sleep_val;
 
-	dev_dbg(&data->client->dev,  __func__);
+	dev_dbg(data->dev,  __func__);
 
 	ret = bmc150_accel_set_mode(data, BMC150_ACCEL_SLEEP_MODE_NORMAL, 0);
 	if (ret < 0)
-- 
2.4.6



From mpa at pengutronix.de  Wed Aug 12 03:12:41 2015
From: mpa at pengutronix.de (Markus Pargmann)
Date: Wed, 12 Aug 2015 12:12:41 +0200
Subject: [PATCH 16/20] iio: bmc150: Fix irq checks
In-Reply-To: <1439374365-20623-1-git-send-email-mpa@pengutronix.de>
References: <1439374365-20623-1-git-send-email-mpa@pengutronix.de>
Message-ID: <1439374365-20623-17-git-send-email-mpa@pengutronix.de>

Valid irqs are > 0. This patch fixes the check which fails for the new
spi driver part if no interrupt was given.

Signed-off-by: Markus Pargmann <mpa at pengutronix.de>
---
 drivers/iio/accel/bmc150-accel.c | 4 ++--
 1 file changed, 2 insertions(+), 2 deletions(-)

diff --git a/drivers/iio/accel/bmc150-accel.c b/drivers/iio/accel/bmc150-accel.c
index 4e70f51c2370..fe2d2316158f 100644
--- a/drivers/iio/accel/bmc150-accel.c
+++ b/drivers/iio/accel/bmc150-accel.c
@@ -1660,10 +1660,10 @@ static int bmc150_accel_probe(struct i2c_client *client,
 		return ret;
 	}
 
-	if (client->irq < 0)
+	if (client->irq <= 0)
 		client->irq = bmc150_accel_gpio_probe(client, data);
 
-	if (client->irq >= 0) {
+	if (client->irq > 0) {
 		ret = devm_request_threaded_irq(
 						&client->dev, client->irq,
 						bmc150_accel_irq_handler,
-- 
2.4.6



From mpa at pengutronix.de  Wed Aug 12 03:12:37 2015
From: mpa at pengutronix.de (Markus Pargmann)
Date: Wed, 12 Aug 2015 12:12:37 +0200
Subject: [PATCH 12/20] regmap: Introduce max_raw_io for regmap_bulk_read/write
In-Reply-To: <1439374365-20623-1-git-send-email-mpa@pengutronix.de>
References: <1439374365-20623-1-git-send-email-mpa@pengutronix.de>
Message-ID: <1439374365-20623-13-git-send-email-mpa@pengutronix.de>

There are some busses which have a limit on the maximum number of bytes
that can be send/received. An example for this is
I2C_FUNC_SMBUS_I2C_BLOCK which does not support any reads/writes of more
than 32 bytes. The regmap_bulk operations should still be able to
utilize the full 32 bytes.

Signed-off-by: Markus Pargmann <mpa at pengutronix.de>
---
 drivers/base/regmap/internal.h |  3 ++
 drivers/base/regmap/regmap.c   | 82 ++++++++++++++++++++++++++++++++----------
 include/linux/regmap.h         |  2 ++
 3 files changed, 69 insertions(+), 18 deletions(-)

diff --git a/drivers/base/regmap/internal.h b/drivers/base/regmap/internal.h
index b2b2849fc6d3..f94041658397 100644
--- a/drivers/base/regmap/internal.h
+++ b/drivers/base/regmap/internal.h
@@ -144,6 +144,9 @@ struct regmap {
 	/* if set, the device supports multi write mode */
 	bool can_multi_write;
 
+	/* if set, raw reads/writes are limited to this size */
+	size_t max_raw_io;
+
 	struct rb_root range_tree;
 	void *selector_work_buf;	/* Scratch buffer used for selector */
 };
diff --git a/drivers/base/regmap/regmap.c b/drivers/base/regmap/regmap.c
index 3b663350c573..6ad4ca849055 100644
--- a/drivers/base/regmap/regmap.c
+++ b/drivers/base/regmap/regmap.c
@@ -574,6 +574,7 @@ struct regmap *regmap_init(struct device *dev,
 	else
 		map->reg_stride = 1;
 	map->use_single_rw = config->use_single_rw || !bus->read || !bus->write;
+	map->max_raw_io = bus->max_raw_io;
 	map->can_multi_write = config->can_multi_write;
 	map->dev = dev;
 	map->bus = bus;
@@ -1675,6 +1676,7 @@ int regmap_bulk_write(struct regmap *map, unsigned int reg, const void *val,
 {
 	int ret = 0, i;
 	size_t val_bytes = map->format.val_bytes;
+	size_t total_bytes = val_bytes * val_count;
 
 	if (map->bus && !map->format.parse_inplace)
 		return -EINVAL;
@@ -1715,20 +1717,39 @@ int regmap_bulk_write(struct regmap *map, unsigned int reg, const void *val,
 		}
 out:
 		map->unlock(map->lock_arg);
-	} else if (map->use_single_rw) {
+	} else if (map->use_single_rw ||
+		   (map->max_raw_io && map->max_raw_io < total_bytes)) {
 		/*
 		 * We need to handle bus writes separate to support val_bytes
 		 * that are not powers of 2.
 		 */
+		int reg_stride = map->reg_stride;
+		size_t write_bytes = val_bytes;
+		size_t write_count = val_count;
+
+		if (!map->use_single_rw) {
+			write_count = total_bytes / map->max_raw_io;
+			write_bytes = map->max_raw_io;
+			reg_stride *= write_bytes / val_bytes;
+		}
+
 		map->lock(map->lock_arg);
+		/* Write as many bytes as possible with maximum write size */
 		for (i = 0; i < val_count; i++) {
 			ret = _regmap_raw_write(map,
-						reg + (i * map->reg_stride),
-						val + (i * val_bytes),
-						val_bytes);
+						reg + (i * reg_stride),
+						val + (i * write_bytes),
+						write_bytes);
 			if (ret)
 				break;
 		}
+
+		/* Write remaining bytes */
+		if (!ret && write_bytes * i < total_bytes) {
+			ret = _regmap_raw_write(map, reg + (i * reg_stride),
+						val + (i * write_bytes),
+						total_bytes - i * write_bytes);
+		}
 		map->unlock(map->lock_arg);
 	} else {
 		void *wval;
@@ -2336,24 +2357,49 @@ int regmap_bulk_read(struct regmap *map, unsigned int reg, void *val,
 		return -EINVAL;
 
 	if (map->bus && map->format.parse_inplace && (vol || map->cache_type == REGCACHE_NONE)) {
-		/*
-		 * Some devices does not support bulk read, for
-		 * them we have a series of single read operations.
-		 */
-		if (map->use_single_rw) {
-			for (i = 0; i < val_count; i++) {
-				ret = regmap_raw_read(map,
-						reg + (i * map->reg_stride),
-						val + (i * val_bytes),
-						val_bytes);
-				if (ret != 0)
-					return ret;
-			}
-		} else {
+		size_t total_size = val_bytes * val_count;
+
+		if (!map->use_single_rw &&
+		    (!map->max_raw_io || map->max_raw_io > total_size)) {
 			ret = regmap_raw_read(map, reg, val,
 					      val_bytes * val_count);
 			if (ret != 0)
 				return ret;
+		} else {
+			/*
+			 * Some devices do not support bulk read or do not
+			 * support large bulk reads, for them we have a series
+			 * of read operations.
+			 */
+			int reg_stride = map->reg_stride;
+			size_t read_bytes = val_bytes;
+			size_t read_count = val_count;
+
+			if (!map->use_single_rw) {
+				read_count = total_size / map->max_raw_io;
+				read_bytes = map->max_raw_io;
+				reg_stride *= read_bytes / val_bytes;
+			}
+
+			/* Read bytes that fit into the max_raw_io size */
+			for (i = 0; i < read_count; i++) {
+				ret = regmap_raw_read(map,
+						      reg + (i * reg_stride),
+						      val + (i * read_bytes),
+						      read_bytes);
+				if (ret != 0)
+					return ret;
+			}
+
+			/* Read remaining bytes */
+			if (read_bytes * i < total_size) {
+				ret = regmap_raw_read(map,
+						      reg + (i * reg_stride),
+						      val + (i * read_bytes),
+						      total_size - i * read_bytes);
+				if (ret != 0)
+					return ret;
+			}
 		}
 
 		for (i = 0; i < val_count * val_bytes; i += val_bytes)
diff --git a/include/linux/regmap.h b/include/linux/regmap.h
index 6ff83c9ddb45..2cb62d141761 100644
--- a/include/linux/regmap.h
+++ b/include/linux/regmap.h
@@ -310,6 +310,7 @@ typedef void (*regmap_hw_free_context)(void *context);
  * @val_format_endian_default: Default endianness for formatted register
  *     values. Used when the regmap_config specifies DEFAULT. If this is
  *     DEFAULT, BIG is assumed.
+ * @max_raw_io: Max raw read/write size that can be used on the bus.
  */
 struct regmap_bus {
 	bool fast_io;
@@ -324,6 +325,7 @@ struct regmap_bus {
 	u8 read_flag_mask;
 	enum regmap_endian reg_format_endian_default;
 	enum regmap_endian val_format_endian_default;
+	size_t max_raw_io;
 };
 
 struct regmap *regmap_init(struct device *dev,
-- 
2.4.6



From mpa at pengutronix.de  Wed Aug 12 03:12:28 2015
From: mpa at pengutronix.de (Markus Pargmann)
Date: Wed, 12 Aug 2015 12:12:28 +0200
Subject: [PATCH 03/20] regmap: Fix integertypes for register address and value
In-Reply-To: <1439374365-20623-1-git-send-email-mpa@pengutronix.de>
References: <1439374365-20623-1-git-send-email-mpa@pengutronix.de>
Message-ID: <1439374365-20623-4-git-send-email-mpa@pengutronix.de>

These values are defined as unsigned int in the struct and are assigned
to int values.

This patch fixes the type to be unsigned int instead.

Signed-off-by: Markus Pargmann <mpa at pengutronix.de>
---
 drivers/base/regmap/regmap.c | 4 ++--
 1 file changed, 2 insertions(+), 2 deletions(-)

diff --git a/drivers/base/regmap/regmap.c b/drivers/base/regmap/regmap.c
index 64a106af174f..4fe5f63edb54 100644
--- a/drivers/base/regmap/regmap.c
+++ b/drivers/base/regmap/regmap.c
@@ -1763,8 +1763,8 @@ static int _regmap_raw_multi_reg_write(struct regmap *map,
 	u8 = buf;
 
 	for (i = 0; i < num_regs; i++) {
-		int reg = regs[i].reg;
-		int val = regs[i].def;
+		unsigned int reg = regs[i].reg;
+		unsigned int val = regs[i].def;
 		trace_regmap_hw_write_start(map, reg, 1);
 		map->format.format_reg(u8, reg, map->reg_shift);
 		u8 += reg_bytes + pad_bytes;
-- 
2.4.6



From mpa at pengutronix.de  Wed Aug 12 03:12:40 2015
From: mpa at pengutronix.de (Markus Pargmann)
Date: Wed, 12 Aug 2015 12:12:40 +0200
Subject: [PATCH 15/20] regmap-i2c: Add smbus i2c block support
In-Reply-To: <1439374365-20623-1-git-send-email-mpa@pengutronix.de>
References: <1439374365-20623-1-git-send-email-mpa@pengutronix.de>
Message-ID: <1439374365-20623-16-git-send-email-mpa@pengutronix.de>

This allows to read/write up to 32 bytes of data and is to be prefered
if supported before the register read/write smbus support.

Signed-off-by: Markus Pargmann <mpa at pengutronix.de>
---
 drivers/base/regmap/regmap-i2c.c | 46 ++++++++++++++++++++++++++++++++++++++++
 1 file changed, 46 insertions(+)

diff --git a/drivers/base/regmap/regmap-i2c.c b/drivers/base/regmap/regmap-i2c.c
index 4b76e33110a2..2de6eb4e6ec3 100644
--- a/drivers/base/regmap/regmap-i2c.c
+++ b/drivers/base/regmap/regmap-i2c.c
@@ -209,11 +209,57 @@ static struct regmap_bus regmap_i2c = {
 	.val_format_endian_default = REGMAP_ENDIAN_BIG,
 };
 
+static int regmap_i2c_smbus_i2c_write(void *context, const void *data,
+				      size_t count)
+{
+	struct device *dev = context;
+	struct i2c_client *i2c = to_i2c_client(dev);
+
+	if (count < 1 || count >= I2C_SMBUS_BLOCK_MAX)
+		return -EINVAL;
+
+	--count;
+	return i2c_smbus_write_i2c_block_data(i2c, ((u8 *)data)[0], count,
+					      ((u8 *)data + 1));
+}
+
+static int regmap_i2c_smbus_i2c_read(void *context, const void *reg,
+				     size_t reg_size, void *val,
+				     size_t val_size)
+{
+	struct device *dev = context;
+	struct i2c_client *i2c = to_i2c_client(dev);
+	int ret;
+
+	if (reg_size != 1)
+		return -EINVAL;
+	if (val_size < 1 || val_size >= I2C_SMBUS_BLOCK_MAX)
+		return -EINVAL;
+
+	ret = i2c_smbus_read_i2c_block_data(i2c, ((u8 *)reg)[0], val_size, val);
+	if (ret == val_size)
+		return 0;
+	else if (ret < 0)
+		return ret;
+	else
+		return -EIO;
+}
+
+static struct regmap_bus regmap_i2c_smbus_i2c_block = {
+	.write = regmap_i2c_smbus_i2c_write,
+	.read = regmap_i2c_smbus_i2c_read,
+	.max_raw_io = I2C_SMBUS_BLOCK_MAX,
+};
+
 static const struct regmap_bus *regmap_get_i2c_bus(struct i2c_client *i2c,
 					const struct regmap_config *config)
 {
 	if (i2c_check_functionality(i2c->adapter, I2C_FUNC_I2C))
 		return &regmap_i2c;
+	else if (config->reg_bits == 8 &&
+		 i2c_check_functionality(i2c->adapter,
+					 I2C_FUNC_SMBUS_I2C_BLOCK))
+		return &regmap_i2c_smbus_i2c_block;
 	else if (config->val_bits == 16 && config->reg_bits == 8 &&
 		 i2c_check_functionality(i2c->adapter,
 					 I2C_FUNC_SMBUS_WORD_DATA))
-- 
2.4.6



From jassisinghbrar at gmail.com  Wed Aug 12 03:16:06 2015
From: jassisinghbrar at gmail.com (Jassi Brar)
Date: Wed, 12 Aug 2015 15:46:06 +0530
Subject: [PATCH v2 2/6] mailbox: dt-bindings: Add shared [driver <=>
 device tree] defines
In-Reply-To: <20150812085309.GB18282@x1>
References: <1437990272-23111-1-git-send-email-lee.jones@linaro.org>
 <1437990272-23111-3-git-send-email-lee.jones@linaro.org>
 <CABb+yY2asjH-c+VJXvG+RK0=2p=P4Y21pznNP0riaKMWLxYZog@mail.gmail.com>
 <20150810082445.GA3249@x1>
 <CABb+yY3jUKXXJys32bHY1u+dbdsix71Xq_H1Lrkkt27vZzmf7w@mail.gmail.com>
 <20150812085309.GB18282@x1>
Message-ID: <CABb+yY3LdX1Lk7jfPbdXr4Zw=zKGJ=TsRRhB5a4CeYHOsjb90A@mail.gmail.com>

On Wed, Aug 12, 2015 at 2:23 PM, Lee Jones <lee.jones at linaro.org> wrote:
> On Mon, 10 Aug 2015, Jassi Brar wrote:
>
>> On Mon, Aug 10, 2015 at 1:54 PM, Lee Jones <lee.jones at linaro.org> wrote:
>> > On Mon, 10 Aug 2015, Jassi Brar wrote:
>> >> On Mon, Jul 27, 2015 at 3:14 PM, Lee Jones <lee.jones at linaro.org> wrote:
>> >> > This header is currently only used for defines pertaining to data
>> >> > direction i.e. Rx, Tx or Loopback.
>> >> >
>> >> > Signed-off-by: Lee Jones <lee.jones at linaro.org>
>> >> > ---
>> >> >  include/dt-bindings/mailbox/mailbox.h | 14 ++++++++++++++
>> >> >  1 file changed, 14 insertions(+)
>> >> >  create mode 100644 include/dt-bindings/mailbox/mailbox.h
>> >> >
>> >> > diff --git a/include/dt-bindings/mailbox/mailbox.h b/include/dt-bindings/mailbox/mailbox.h
>> >> > new file mode 100644
>> >> > index 0000000..82e929a
>> >> > --- /dev/null
>> >> > +++ b/include/dt-bindings/mailbox/mailbox.h
>> >> > @@ -0,0 +1,14 @@
>> >> > +/*
>> >> > + * 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.
>> >> > + */
>> >> > +
>> >> > +#ifndef __MAILBOX_CONTROLLER_DT_BINDINGS_H
>> >> > +#define __MAILBOX_CONTROLLER_DT_BINDINGS_H
>> >> > +
>> >> > +#define MBOX_TX                0x1
>> >> > +#define MBOX_RX                0x2
>> >> > +#define MBOX_LOOPBACK  (MBOX_RX | MBOX_TX)
>> >> > +
>> >> Not sure I understand 'loopback'.  Does it mean h/w has some
>> >> 'loopback' mode for testing purposes? Or it simply means the
>> >> controller can send as well as receive messages?
>> >
>> > 'loopback' allows firmware to conduct some early function tests.
>> > However, channels are simplex, so we provide protection against
>> > multiple allocation of single channel.  By allocating a LOOPBACK
>> > channel we over-ride this protection and allow a single channel to be
>> > allocated twice, once for Rx and the other for Tx.
>> >
>> So basically hardware is half-duplex, not simplex. I think maybe you
>> should simply allow for RX and TX always. It should work. Just
>> handover any received data before send_data (reflecting the h/w
>> limitation). That way you don't need any such special flag.
>
> Unfortunately no, that's not correct.  Only Mailbox 0 is half-duplex.
> The others are simplex (Rx only).
>
Assuming that is indeed the case (though code and comments suggest
otherwise), it is still not a matter of choice for clients to 'make' a
channel RX or TX or RXTX. That is the property/constraint of the
controller and the controller driver should simply check for channel
ID to be zero in send_data() and return error if its non-zero.

>  Ideally I'd like to keep the
> LOOPBACK flag, as it's easier to figure out if what someone is
> attempting to do is actually valid.
>
I am not for such paranoia. Provider drivers is not the place to check
for valid user data.
The controller driver should simply reject send_data() request on any
mailbox > 0 while the consumer driver should scream for attention
because that's where the problem is.

Please note, what I suggest will only make the code simpler while not
breaking anything.

Thanks.


From hdegoede at redhat.com  Wed Aug 12 03:18:43 2015
From: hdegoede at redhat.com (Hans de Goede)
Date: Wed, 12 Aug 2015 12:18:43 +0200
Subject: [linux-sunxi] [PATCH] pinctrl: sun4i: add spdif to pin
 description.
In-Reply-To: <CAGb2v64A+T1aE622uvW6nCmJACWrtLVaLRfoLgh=CppGDrEX2A@mail.gmail.com>
References: <1439309965-9530-1-git-send-email-codekipper@gmail.com>
 <CAGb2v64Ptt5NgeicsYtiR8At+K4aDd3Lb3U4kijQ5UM+UafSrA@mail.gmail.com>
 <CAEKpxBmS6YJMjREc3gmeSQOzBXFKw=Sb-xPK57oUn6BtmASErg@mail.gmail.com>
 <55CB051D.3090109@redhat.com>
 <CAEKpxB=UQYEnwXYAzMZA4noR9Xg8wnSjD+H0bNO5GV3dtZQtTg@mail.gmail.com>
 <CAGb2v64A+T1aE622uvW6nCmJACWrtLVaLRfoLgh=CppGDrEX2A@mail.gmail.com>
Message-ID: <55CB1D83.2050106@redhat.com>

Hi,

On 12-08-15 11:18, Chen-Yu Tsai wrote:
> On Wed, Aug 12, 2015 at 5:13 PM, Code Kipper <codekipper at gmail.com> wrote:
>> On 12 August 2015 at 10:34, Hans de Goede <hdegoede at redhat.com> wrote:
>>>
>>> Hi,
>>>
>>>
>>> On 12-08-15 07:31, Code Kipper wrote:
>>>>
>>>> On 11 August 2015 at 18:48, Chen-Yu Tsai <wens at csie.org> wrote:
>>>>
>>>>> On Wed, Aug 12, 2015 at 12:19 AM,  <codekipper at gmail.com> wrote:
>>>>>>
>>>>>> From: Marcus Cooper <codekipper at gmail.com>
>>>>>>
>>>>>> Signed-off-by: Marcus Cooper <codekipper at gmail.com>
>>>>>> ---
>>>>>>    drivers/pinctrl/sunxi/pinctrl-sun4i-a10.c | 9 ++++++---
>>>>>>    1 file changed, 6 insertions(+), 3 deletions(-)
>>>>>>
>>>>>> diff --git a/drivers/pinctrl/sunxi/pinctrl-sun4i-a10.c
>>>>>
>>>>> b/drivers/pinctrl/sunxi/pinctrl-sun4i-a10.c
>>>>>>
>>>>>> index 7376a97..daf7dec 100644
>>>>>> --- a/drivers/pinctrl/sunxi/pinctrl-sun4i-a10.c
>>>>>> +++ b/drivers/pinctrl/sunxi/pinctrl-sun4i-a10.c
>>>>>> @@ -135,7 +135,8 @@ static const struct sunxi_desc_pin sun4i_a10_pins[]
>>>>>
>>>>> = {
>>>>>>
>>>>>>           SUNXI_PIN(SUNXI_PINCTRL_PIN(B, 3),
>>>>>>                     SUNXI_FUNCTION(0x0, "gpio_in"),
>>>>>>                     SUNXI_FUNCTION(0x1, "gpio_out"),
>>>>>> -                 SUNXI_FUNCTION(0x2, "ir0")),          /* TX */
>>>>>> +                 SUNXI_FUNCTION(0x2, "ir0"),           /* TX */
>>>>>> +                 SUNXI_FUNCTION(0x4, "spdif")),        /* MCLK */
>>>>>>           SUNXI_PIN(SUNXI_PINCTRL_PIN(B, 4),
>>>>>>                     SUNXI_FUNCTION(0x0, "gpio_in"),
>>>>>>                     SUNXI_FUNCTION(0x1, "gpio_out"),
>>>>>> @@ -176,11 +177,13 @@ static const struct sunxi_desc_pin
>>>>>
>>>>> sun4i_a10_pins[] = {
>>>>>>
>>>>>>                     SUNXI_FUNCTION(0x0, "gpio_in"),
>>>>>>                     SUNXI_FUNCTION(0x1, "gpio_out"),
>>>>>>                     SUNXI_FUNCTION(0x2, "i2s"),           /* DI */
>>>>>> -                 SUNXI_FUNCTION(0x3, "ac97")),         /* DI */
>>>>>> +                 SUNXI_FUNCTION(0x3, "ac97"),          /* DI */
>>>>>> +                 SUNXI_FUNCTION(0x4, "spdif")),        /* DI */
>>>>>>           SUNXI_PIN(SUNXI_PINCTRL_PIN(B, 13),
>>>>>>                     SUNXI_FUNCTION(0x0, "gpio_in"),
>>>>>>                     SUNXI_FUNCTION(0x1, "gpio_out"),
>>>>>> -                 SUNXI_FUNCTION(0x2, "spi2")),         /* CS1 */
>>>>>> +                 SUNXI_FUNCTION(0x2, "spi2"),          /* CS1 */
>>>>>> +                 SUNXI_FUNCTION(0x4, "spdif")),        /* DO */
>>>>>
>>>>>
>>>>> The datasheet and manual list them as NC or Reserved. Maybe mention how
>>>>> you knew
>>>>> they were available?
>>>>>
>>>> Not sure if this deserves to be in the commit message but I can
>>>> definitely
>>>> put together a covering letter with links etc.
>>>
>>>
>>> I dear to say it belongs right there in the source code, use a multi-line
>>> comment above the SUNXI_FUNCTION(0x4, "spdif")) to explain where the mux
>>> info comes from. someday sooner or later someone is going to compare the
>>> kernel mux table to the datasheet and think "huh, that is not right",
>>> that person will be saved an immense amount of time by simply having a
>>> comment there.
>>
>> Good point I was thinking something along the lines of this
>> /*
>>   * The SPDIF block is not referenced at all in the A10 user
>>   * manual. However it is described in the code leaked and the
>>   * pin descriptions are declared in the A20 user manual which
>>   * is pin compatible with this device.
>>   */
>> Thing is do I add this above every spdif pin, the first change(MCLK) or the
>> pin most likely to be used(SPDIF DO)?
>
> I'd say put it before the first pin, and then reference it (like
> "undocumented, see the comment for pin P??? above", for the rest.

Ack / +1 exactly what I was thinking :)

Regards,

Hans


>
> ChenYu
>
>> Thanks,
>> CK
>>>
>>>
>>> And do NOT say that this will not happen, because I've already done
>>> such a comparison once in the past.
>>>
>>> Regards,
>>>
>>> Hans
>>
>>


From lee.jones at linaro.org  Wed Aug 12 03:23:28 2015
From: lee.jones at linaro.org (Lee Jones)
Date: Wed, 12 Aug 2015 11:23:28 +0100
Subject: [PATCH v2 5/6] mailbox: Add generic mechanism for testing
 Mailbox Controllers
In-Reply-To: <CABb+yY20nQbiEEZeRvWTMUsJ2qgwRn8CrWvnFDSB-b1dgVaAuw@mail.gmail.com>
References: <1437990272-23111-1-git-send-email-lee.jones@linaro.org>
 <1437990272-23111-6-git-send-email-lee.jones@linaro.org>
 <CABb+yY20nQbiEEZeRvWTMUsJ2qgwRn8CrWvnFDSB-b1dgVaAuw@mail.gmail.com>
Message-ID: <20150812102328.GD18282@x1>

On Mon, 10 Aug 2015, Jassi Brar wrote:

> On Mon, Jul 27, 2015 at 3:14 PM, Lee Jones <lee.jones at linaro.org> wrote:
> > This particular Client implementation uses shared memory in order
> > to pass messages between Mailbox users; however, it can be easily
> > hacked to support any type of Controller.
> >
> > Signed-off-by: Lee Jones <lee.jones at linaro.org>
> > ---
> >  drivers/mailbox/Kconfig        |   7 ++
> >  drivers/mailbox/Makefile       |   2 +
> >  drivers/mailbox/mailbox-test.c | 210 +++++++++++++++++++++++++++++++++++++++++
> >  3 files changed, 219 insertions(+)
> >  create mode 100644 drivers/mailbox/mailbox-test.c
> >
> > diff --git a/drivers/mailbox/Kconfig b/drivers/mailbox/Kconfig
> > index 2cc4c39..7720bde 100644
> > --- a/drivers/mailbox/Kconfig
> > +++ b/drivers/mailbox/Kconfig
> > @@ -77,4 +77,11 @@ config STI_MBOX
> >           Mailbox implementation for STMicroelectonics family chips with
> >           hardware for interprocessor communication.
> >
> > +config MAILBOX_TEST
> > +       tristate "Mailbox Test Client"
> > +       depends on OF
> > +       help
> > +         Test client to help with testing new Controller driver
> > +         implementations.
> > +
> >  endif
> > diff --git a/drivers/mailbox/Makefile b/drivers/mailbox/Makefile
> > index 7cb4766..92435ef 100644
> > --- a/drivers/mailbox/Makefile
> > +++ b/drivers/mailbox/Makefile
> > @@ -2,6 +2,8 @@
> >
> >  obj-$(CONFIG_MAILBOX)          += mailbox.o
> >
> > +obj-$(CONFIG_MAILBOX_TEST)     += mailbox-test.o
> > +
> >  obj-$(CONFIG_ARM_MHU)  += arm_mhu.o
> >
> >  obj-$(CONFIG_PL320_MBOX)       += pl320-ipc.o
> > diff --git a/drivers/mailbox/mailbox-test.c b/drivers/mailbox/mailbox-test.c
> > new file mode 100644
> > index 0000000..10bfe3a
> > --- /dev/null
> > +++ b/drivers/mailbox/mailbox-test.c
> > @@ -0,0 +1,210 @@
> > +/*
> > + * Copyright (C) 2015 ST Microelectronics
> > + *
> > + * Author: Lee Jones <lee.jones at linaro.org>
> > + *
> > + * This program is free software; you can redistribute it and/or modify
> > + * it under the terms of the GNU General Public License as published by
> > + * the Free Software Foundation; either version 2 of the License, or
> > + * (at your option) any later version.
> > + */
> > +
> > +#include <linux/debugfs.h>
> > +#include <linux/err.h>
> > +#include <linux/kernel.h>
> > +#include <linux/mailbox_client.h>
> > +#include <linux/module.h>
> > +#include <linux/of.h>
> > +#include <linux/platform_device.h>
> > +#include <linux/slab.h>
> > +#include <linux/uaccess.h>
> > +
> > +#define MBOX_MAX_MSG_LEN 128
> > +
> > +static struct dentry *root_debugfs_dir;
> > +
> > +struct mbox_test_device {
> > +       struct device           *dev;
> > +       struct mbox_chan        *tx_channel;
> > +       struct mbox_chan        *rx_channel;
> > +       void __iomem            *mmio;
> > +
> > +};
> > +
> > +static ssize_t mbox_test_write(struct file *filp,
> > +                              const char __user *userbuf,
> > +                              size_t count, loff_t *ppos)
> > +{
> > +       struct mbox_test_device *tdev = filp->private_data;
> > +       char *message;
> > +       int ret;
> > +
> > +       if (count > MBOX_MAX_MSG_LEN) {
> > +               dev_err(tdev->dev,
> > +                       "Message length %d greater than max allowed %d\n",
> > +                       count, MBOX_MAX_MSG_LEN);
> > +               return -EINVAL;
> > +       }
> > +
> > +       message = kzalloc(count, GFP_KERNEL);
> > +       if (!message)
> > +               return -ENOMEM;
> > +
> > +       ret = copy_from_user(message, userbuf, count);
> > +       if (ret)
> > +               return -EFAULT;
> > +
> > +       print_hex_dump(KERN_ERR, "Client: Sending: ", DUMP_PREFIX_ADDRESS,
> > +                      16, 1, message, 16, true);
> > +
> > +       ret = mbox_send_message(tdev->tx_channel, message);
> > +       if (ret < 0)
> > +               dev_err(tdev->dev, "Failed to send message via mailbox\n");
> > +
> > +       kfree(message);
> > +
> > +       return ret < 0 ? ret : count;
> > +}
> > +
> > +static const struct file_operations mbox_test_ops = {
> > +       .write  = mbox_test_write,
> > +       .open   = simple_open,
> > +       .llseek = generic_file_llseek,
> > +};
> > +
> > +static int mbox_test_add_debugfs(struct platform_device *pdev,
> > +                                struct mbox_test_device *tdev)
> > +{
> > +       if (!debugfs_initialized())
> > +               return 0;
> > +
> > +       root_debugfs_dir = debugfs_create_dir("mailbox", NULL);
> > +       if (!root_debugfs_dir) {
> > +               dev_err(&pdev->dev, "Failed to create Mailbox debugfs\n");
> > +               return -EINVAL;
> > +       }
> > +
> > +       debugfs_create_file("send-message", 0200, root_debugfs_dir,
> > +                           tdev, &mbox_test_ops);
> > +
> > +       return 0;
> > +}
> > +
> > +static void mbox_test_receive_message(struct mbox_client *client, void *message)
> > +{
> > +       struct mbox_test_device *tdev = dev_get_drvdata(client->dev);
> > +
> > +       if (!tdev->mmio) {
> > +               dev_info(tdev->dev, "Client: Recived something [read mmio]\n");
> > +               return;
> > +       }
> > +
> > +       print_hex_dump(KERN_ERR, "Client: from co-proc: ", DUMP_PREFIX_ADDRESS,
> > +                      16, 1, tdev->mmio, MBOX_MAX_MSG_LEN, true);
> > +}
> > +
> > +static void mbox_test_prepare_message(struct mbox_client *client, void *message)
> > +{
> > +       struct mbox_test_device *tdev = dev_get_drvdata(client->dev);
> > +
> > +       if (tdev->mmio)
> > +               memcpy(tdev->mmio, message, MBOX_MAX_MSG_LEN);
> >
> This is unlikely to work. Those platforms that need to send a 2 part
> message, they do :
> (a) Signal/Command/Target code via some controller register (via
> mbox_send_message).
> (b) Setup the payload in Shared-Memory (via tx_prepare).
> 
> This test driver assumes both are the same. I think you have to
> declare something like

This driver assumes that the framework will call client->tx_prepare()
first, which satisfies (b).  It then assumes controller->send_data()
will be invoked, which will send the platform specific
signal/command/target code, which then satisfies (a).

In what way does it assume they are the same?

> struct mbox_test_message { /* same for TX and RX */
>           unsigned sig_len;
>           void *signal;               /* rx/tx via mailbox api */
>           unsigned pl_len;
>           void *payload;           /* rx/tx via shared-memory */
> };

How do you think this should be set and use these?

> > +
> > +static void mbox_test_message_sent(struct mbox_client *client,
> > +                                  void *message, int r)
> > +{
> > +       if (r)
> > +               dev_warn(client->dev,
> > +                        "Client: Message could not be sent: %d\n", r);
> > +       else
> > +               dev_info(client->dev,
> > +                        "Client: Message sent\n");
> > +}
> > +
> > +static struct mbox_chan *
> > +mbox_test_request_channel(struct platform_device *pdev, const char *name)
> > +{
> > +       struct mbox_client *client;
> > +
> > +       client = devm_kzalloc(&pdev->dev, sizeof(*client), GFP_KERNEL);
> > +       if (!client)
> > +               return ERR_PTR(-ENOMEM);
> > +
> > +       client->dev             = &pdev->dev;
> > +       client->rx_callback     = mbox_test_receive_message;
> > +       client->tx_prepare      = mbox_test_prepare_message;
> > +       client->tx_done         = mbox_test_message_sent;
> > +       client->tx_block        = true;
> > +       client->knows_txdone    = false;
> > +       client->tx_tout         = 500;
> > +
> > +       return mbox_request_channel_byname(client, name);
> > +}
> > +
> > +static int mbox_test_probe(struct platform_device *pdev)
> > +{
> > +       struct mbox_test_device *tdev;
> > +       struct resource *res;
> > +       int ret;
> > +
> > +       tdev = devm_kzalloc(&pdev->dev, sizeof(*tdev), GFP_KERNEL);
> > +       if (!tdev)
> > +               return -ENOMEM;
> > +
> > +       /* It's okay for MMIO to be NULL */
> > +       res = platform_get_resource(pdev, IORESOURCE_MEM, 0);
> > +       tdev->mmio = devm_ioremap_resource(&pdev->dev, res);
> > +       if (IS_ERR(tdev->mmio))
> > +               tdev->mmio = NULL;
> > +
> > +       tdev->tx_channel = mbox_test_request_channel(pdev, "tx");
> > +       if (IS_ERR(tdev->tx_channel))
> > +               return PTR_ERR(tdev->tx_channel);
> > +
> > +       tdev->rx_channel = mbox_test_request_channel(pdev, "rx");
> > +       if (IS_ERR(tdev->rx_channel))
> > +               return PTR_ERR(tdev->rx_channel);
> > +
> Should it really fail on TX or RX only clients?

Good question.  Probably not, but I guess we'd need a flag for that.

> It takes write from userspace but shouldn't it also provide data
> received to the userspace?

Currently we only print the returning message.  If you want me to put
it in a userspace file too, that's not an issue.

-- 
Lee Jones
Linaro STMicroelectronics Landing Team Lead
Linaro.org ? Open source software for ARM SoCs
Follow Linaro: Facebook | Twitter | Blog


From hdegoede at redhat.com  Wed Aug 12 03:20:15 2015
From: hdegoede at redhat.com (Hans de Goede)
Date: Wed, 12 Aug 2015 12:20:15 +0200
Subject: [PATCH v4 2/2] mfd: axp20x: Add a cell for the usb power_supply
 part of the axp20x PMICs
In-Reply-To: <20150812092900.GC18282@x1>
References: <1439049521-30766-1-git-send-email-hdegoede@redhat.com>
 <1439049521-30766-2-git-send-email-hdegoede@redhat.com>
 <20150811141811.GM18282@x1> <55CB05AD.1030707@redhat.com>
 <20150812092900.GC18282@x1>
Message-ID: <55CB1DDF.7000201@redhat.com>

Hi,

On 12-08-15 11:29, Lee Jones wrote:
> On Wed, 12 Aug 2015, Hans de Goede wrote:
>
>> Hi,
>>
>> On 11-08-15 16:18, Lee Jones wrote:
>>> On Sat, 08 Aug 2015, Hans de Goede wrote:
>>>
>>>> Add a cell for the usb power_supply part of the axp20x PMICs.
>>>>
>>>> Note that this cell is only for the usb power_supply part and not the
>>>> ac-power / battery-charger / rtc-backup-bat-charger bits.
>>>>
>>>> Depending on the board each of those must be enabled / disabled separately
>>>> in devicetree as most boards do not use all 4. So in dt each one needs its
>>>> own child-node of the axp20x node. Another reason for using separate child
>>>> nodes for each is so that other devicetree nodes can have a power-supply
>>>> property with a phandle referencing a node representing a single
>>>> power-supply.
>>>>
>>>> The decision to use a separate devicetree node for each is reflected on
>>>> the kernel side by each getting its own mfd-cell / platform_device and
>>>> platform-driver.
>>>>
>>>> Note this commit also makes some whitespace changes to the intialization
>>>> of existing cells in axp20x_cells, these are pure whitespace changes,
>>>> functionally nothing changes.
>>>>
>>>> Cc: Bruno Pr?mont <bonbons at linux-vserver.org>
>>>> Signed-off-by: Bruno Pr?mont <bonbons at linux-vserver.org>
>>>> Signed-off-by: Hans de Goede <hdegoede at redhat.com>
>>>> Acked-by: Maxime Ripard <maxime.ripard at free-electrons.com>
>>>> Acked-by: Lee Jones <lee.jones at linaro.org>
>>>> ---
>>>> Changes in v2:
>>>> -Use DEFINE_RES_IRQ_NAMED
>>>> -Change indentation of axp20x_cells initializers to avoid line wrapping
>>>> Changes in v3:
>>>> -Improve commit message
>>>> -Add Bruno's S-o-b
>>>> ---
>>>>   drivers/mfd/axp20x.c | 20 ++++++++++++++++----
>>>>   1 file changed, 16 insertions(+), 4 deletions(-)
>>>
>>> Applied, thanks.
>>
>> Great, but I'm not seeing this in:
>>
>> https://git.kernel.org/cgit/linux/kernel/git/lee/mfd.git/log/?h=for-mfd-next
>
> Well it does usually take me a day or two push my local branch out,
> however in this case I had actually dropped a ball somewhere.  I've
> been through my backlog of 'applied' patches and these two are the
> only ones I failed to pick.  I have now, re-picked, re-applied and
> pushed the branch out.  Let me know if something is still not right.

Looks good now, thanks.

> Sorry for the inconvenience.

No problem, thanks for all the great work you are doing on maintaining
the mfd subsys.

Regards,

Hans


>
>>>> diff --git a/drivers/mfd/axp20x.c b/drivers/mfd/axp20x.c
>>>> index d9f2f96..3f576b7 100644
>>>> --- a/drivers/mfd/axp20x.c
>>>> +++ b/drivers/mfd/axp20x.c
>>>> @@ -140,6 +140,13 @@ static struct resource axp20x_pek_resources[] = {
>>>>   	},
>>>>   };
>>>>
>>>> +static struct resource axp20x_usb_power_supply_resources[] = {
>>>> +	DEFINE_RES_IRQ_NAMED(AXP20X_IRQ_VBUS_PLUGIN, "VBUS_PLUGIN"),
>>>> +	DEFINE_RES_IRQ_NAMED(AXP20X_IRQ_VBUS_REMOVAL, "VBUS_REMOVAL"),
>>>> +	DEFINE_RES_IRQ_NAMED(AXP20X_IRQ_VBUS_VALID, "VBUS_VALID"),
>>>> +	DEFINE_RES_IRQ_NAMED(AXP20X_IRQ_VBUS_NOT_VALID, "VBUS_NOT_VALID"),
>>>> +};
>>>> +
>>>>   static struct resource axp22x_pek_resources[] = {
>>>>   	{
>>>>   		.name   = "PEK_DBR",
>>>> @@ -432,11 +439,16 @@ static const struct regmap_irq_chip axp288_regmap_irq_chip = {
>>>>
>>>>   static struct mfd_cell axp20x_cells[] = {
>>>>   	{
>>>> -		.name			= "axp20x-pek",
>>>> -		.num_resources		= ARRAY_SIZE(axp20x_pek_resources),
>>>> -		.resources		= axp20x_pek_resources,
>>>> +		.name		= "axp20x-pek",
>>>> +		.num_resources	= ARRAY_SIZE(axp20x_pek_resources),
>>>> +		.resources	= axp20x_pek_resources,
>>>>   	}, {
>>>> -		.name			= "axp20x-regulator",
>>>> +		.name		= "axp20x-regulator",
>>>> +	}, {
>>>> +		.name		= "axp20x-usb-power-supply",
>>>> +		.of_compatible	= "x-powers,axp202-usb-power-supply",
>>>> +		.num_resources	= ARRAY_SIZE(axp20x_usb_power_supply_resources),
>>>> +		.resources	= axp20x_usb_power_supply_resources,
>>>>   	},
>>>>   };
>>>>
>>>
>


From broonie at kernel.org  Wed Aug 12 03:25:50 2015
From: broonie at kernel.org (Mark Brown)
Date: Wed, 12 Aug 2015 11:25:50 +0100
Subject: [PATCH 02/20] regmap: Remove regmap_bulk_write 64bit support
In-Reply-To: <1439374365-20623-3-git-send-email-mpa@pengutronix.de>
References: <1439374365-20623-1-git-send-email-mpa@pengutronix.de>
 <1439374365-20623-3-git-send-email-mpa@pengutronix.de>
Message-ID: <20150812102550.GQ10748@sirena.org.uk>

On Wed, Aug 12, 2015 at 12:12:27PM +0200, Markus Pargmann wrote:
> Regmap does not support 64bit. The ival that is used to write the 64bit
> data to, is unsigned int and can't hold 64bit. _regmap_write also just
> supports unsigend int.

What makes you say that unsigned int can't hold 64 bit?  An architecture
can have 64 bit ints if it likes.
-------------- next part --------------
A non-text attachment was scrubbed...
Name: signature.asc
Type: application/pgp-signature
Size: 473 bytes
Desc: Digital signature
URL: <http://lists.infradead.org/pipermail/linux-arm-kernel/attachments/20150812/055cdde2/attachment-0001.sig>

From lee.jones at linaro.org  Wed Aug 12 03:26:25 2015
From: lee.jones at linaro.org (Lee Jones)
Date: Wed, 12 Aug 2015 11:26:25 +0100
Subject: [PATCH v4 2/2] mfd: axp20x: Add a cell for the usb power_supply
 part of the axp20x PMICs
In-Reply-To: <55CB1DDF.7000201@redhat.com>
References: <1439049521-30766-1-git-send-email-hdegoede@redhat.com>
 <1439049521-30766-2-git-send-email-hdegoede@redhat.com>
 <20150811141811.GM18282@x1> <55CB05AD.1030707@redhat.com>
 <20150812092900.GC18282@x1> <55CB1DDF.7000201@redhat.com>
Message-ID: <20150812102625.GE18282@x1>

On Wed, 12 Aug 2015, Hans de Goede wrote:

> Hi,
> 
> On 12-08-15 11:29, Lee Jones wrote:
> >On Wed, 12 Aug 2015, Hans de Goede wrote:
> >
> >>Hi,
> >>
> >>On 11-08-15 16:18, Lee Jones wrote:
> >>>On Sat, 08 Aug 2015, Hans de Goede wrote:
> >>>
> >>>>Add a cell for the usb power_supply part of the axp20x PMICs.
> >>>>
> >>>>Note that this cell is only for the usb power_supply part and not the
> >>>>ac-power / battery-charger / rtc-backup-bat-charger bits.
> >>>>
> >>>>Depending on the board each of those must be enabled / disabled separately
> >>>>in devicetree as most boards do not use all 4. So in dt each one needs its
> >>>>own child-node of the axp20x node. Another reason for using separate child
> >>>>nodes for each is so that other devicetree nodes can have a power-supply
> >>>>property with a phandle referencing a node representing a single
> >>>>power-supply.
> >>>>
> >>>>The decision to use a separate devicetree node for each is reflected on
> >>>>the kernel side by each getting its own mfd-cell / platform_device and
> >>>>platform-driver.
> >>>>
> >>>>Note this commit also makes some whitespace changes to the intialization
> >>>>of existing cells in axp20x_cells, these are pure whitespace changes,
> >>>>functionally nothing changes.
> >>>>
> >>>>Cc: Bruno Pr?mont <bonbons at linux-vserver.org>
> >>>>Signed-off-by: Bruno Pr?mont <bonbons at linux-vserver.org>
> >>>>Signed-off-by: Hans de Goede <hdegoede at redhat.com>
> >>>>Acked-by: Maxime Ripard <maxime.ripard at free-electrons.com>
> >>>>Acked-by: Lee Jones <lee.jones at linaro.org>
> >>>>---
> >>>>Changes in v2:
> >>>>-Use DEFINE_RES_IRQ_NAMED
> >>>>-Change indentation of axp20x_cells initializers to avoid line wrapping
> >>>>Changes in v3:
> >>>>-Improve commit message
> >>>>-Add Bruno's S-o-b
> >>>>---
> >>>>  drivers/mfd/axp20x.c | 20 ++++++++++++++++----
> >>>>  1 file changed, 16 insertions(+), 4 deletions(-)
> >>>
> >>>Applied, thanks.
> >>
> >>Great, but I'm not seeing this in:
> >>
> >>https://git.kernel.org/cgit/linux/kernel/git/lee/mfd.git/log/?h=for-mfd-next
> >
> >Well it does usually take me a day or two push my local branch out,
> >however in this case I had actually dropped a ball somewhere.  I've
> >been through my backlog of 'applied' patches and these two are the
> >only ones I failed to pick.  I have now, re-picked, re-applied and
> >pushed the branch out.  Let me know if something is still not right.
> 
> Looks good now, thanks.

You're welcome.

> >Sorry for the inconvenience.
> 
> No problem, thanks for all the great work you are doing on maintaining
> the mfd subsys.

Thanks. :)

I should print and frame this, to look at when I think about not doing
it anymore.

> >>>>diff --git a/drivers/mfd/axp20x.c b/drivers/mfd/axp20x.c
> >>>>index d9f2f96..3f576b7 100644
> >>>>--- a/drivers/mfd/axp20x.c
> >>>>+++ b/drivers/mfd/axp20x.c
> >>>>@@ -140,6 +140,13 @@ static struct resource axp20x_pek_resources[] = {
> >>>>  	},
> >>>>  };
> >>>>
> >>>>+static struct resource axp20x_usb_power_supply_resources[] = {
> >>>>+	DEFINE_RES_IRQ_NAMED(AXP20X_IRQ_VBUS_PLUGIN, "VBUS_PLUGIN"),
> >>>>+	DEFINE_RES_IRQ_NAMED(AXP20X_IRQ_VBUS_REMOVAL, "VBUS_REMOVAL"),
> >>>>+	DEFINE_RES_IRQ_NAMED(AXP20X_IRQ_VBUS_VALID, "VBUS_VALID"),
> >>>>+	DEFINE_RES_IRQ_NAMED(AXP20X_IRQ_VBUS_NOT_VALID, "VBUS_NOT_VALID"),
> >>>>+};
> >>>>+
> >>>>  static struct resource axp22x_pek_resources[] = {
> >>>>  	{
> >>>>  		.name   = "PEK_DBR",
> >>>>@@ -432,11 +439,16 @@ static const struct regmap_irq_chip axp288_regmap_irq_chip = {
> >>>>
> >>>>  static struct mfd_cell axp20x_cells[] = {
> >>>>  	{
> >>>>-		.name			= "axp20x-pek",
> >>>>-		.num_resources		= ARRAY_SIZE(axp20x_pek_resources),
> >>>>-		.resources		= axp20x_pek_resources,
> >>>>+		.name		= "axp20x-pek",
> >>>>+		.num_resources	= ARRAY_SIZE(axp20x_pek_resources),
> >>>>+		.resources	= axp20x_pek_resources,
> >>>>  	}, {
> >>>>-		.name			= "axp20x-regulator",
> >>>>+		.name		= "axp20x-regulator",
> >>>>+	}, {
> >>>>+		.name		= "axp20x-usb-power-supply",
> >>>>+		.of_compatible	= "x-powers,axp202-usb-power-supply",
> >>>>+		.num_resources	= ARRAY_SIZE(axp20x_usb_power_supply_resources),
> >>>>+		.resources	= axp20x_usb_power_supply_resources,
> >>>>  	},
> >>>>  };
> >>>>
> >>>
> >

-- 
Lee Jones
Linaro STMicroelectronics Landing Team Lead
Linaro.org ? Open source software for ARM SoCs
Follow Linaro: Facebook | Twitter | Blog


From viresh.kumar at linaro.org  Wed Aug 12 03:29:43 2015
From: viresh.kumar at linaro.org (Viresh Kumar)
Date: Wed, 12 Aug 2015 15:59:43 +0530
Subject: [PATCH V1 Resend 06/10] drivers: rtc: Drop (un)likely before
 IS_ERR(_OR_NULL)
In-Reply-To: <cover.1439375087.git.viresh.kumar@linaro.org>
References: <cover.1439375087.git.viresh.kumar@linaro.org>
Message-ID: <1a92f2e1af5309ece9736f79f312e90486a98825.1439375087.git.viresh.kumar@linaro.org>

IS_ERR(_OR_NULL) already contain an 'unlikely' compiler flag and there
is no need to do that again from its callers. Drop it.

gemini driver was using likely() for a failure case while the rtc driver
is getting registered. That looks wrong and it should really be
unlikely. But because we are killing all the unlikely() flags, lets kill
that too.

Acked-by: Hans Ulli Kroll <ulli.kroll at googlemail.com> (gemini)
Signed-off-by: Viresh Kumar <viresh.kumar at linaro.org>
---
 drivers/rtc/interface.c  | 2 +-
 drivers/rtc/rtc-bfin.c   | 2 +-
 drivers/rtc/rtc-gemini.c | 2 +-
 3 files changed, 3 insertions(+), 3 deletions(-)

diff --git a/drivers/rtc/interface.c b/drivers/rtc/interface.c
index 11b639067312..5836751b8203 100644
--- a/drivers/rtc/interface.c
+++ b/drivers/rtc/interface.c
@@ -564,7 +564,7 @@ enum hrtimer_restart rtc_pie_update_irq(struct hrtimer *timer)
 void rtc_update_irq(struct rtc_device *rtc,
 		unsigned long num, unsigned long events)
 {
-	if (unlikely(IS_ERR_OR_NULL(rtc)))
+	if (IS_ERR_OR_NULL(rtc))
 		return;
 
 	pm_stay_awake(rtc->dev.parent);
diff --git a/drivers/rtc/rtc-bfin.c b/drivers/rtc/rtc-bfin.c
index 3d44b11721ea..535a5f9338d0 100644
--- a/drivers/rtc/rtc-bfin.c
+++ b/drivers/rtc/rtc-bfin.c
@@ -361,7 +361,7 @@ static int bfin_rtc_probe(struct platform_device *pdev)
 	/* Register our RTC with the RTC framework */
 	rtc->rtc_dev = devm_rtc_device_register(dev, pdev->name, &bfin_rtc_ops,
 						THIS_MODULE);
-	if (unlikely(IS_ERR(rtc->rtc_dev)))
+	if (IS_ERR(rtc->rtc_dev))
 		return PTR_ERR(rtc->rtc_dev);
 
 	/* Grab the IRQ and init the hardware */
diff --git a/drivers/rtc/rtc-gemini.c b/drivers/rtc/rtc-gemini.c
index 35f4486738fc..2fed93e1114a 100644
--- a/drivers/rtc/rtc-gemini.c
+++ b/drivers/rtc/rtc-gemini.c
@@ -148,7 +148,7 @@ static int gemini_rtc_probe(struct platform_device *pdev)
 
 	rtc->rtc_dev = rtc_device_register(pdev->name, dev,
 					   &gemini_rtc_ops, THIS_MODULE);
-	if (likely(IS_ERR(rtc->rtc_dev)))
+	if (IS_ERR(rtc->rtc_dev))
 		return PTR_ERR(rtc->rtc_dev);
 
 	return 0;
-- 
2.4.0



From mpa at pengutronix.de  Wed Aug 12 03:12:25 2015
From: mpa at pengutronix.de (Markus Pargmann)
Date: Wed, 12 Aug 2015 12:12:25 +0200
Subject: [PATCH 00/20] Regmap max_raw_io and bmc150 SPI support
Message-ID: <1439374365-20623-1-git-send-email-mpa@pengutronix.de>

Hi,

this series was created to add SPI support to the bmc150 accelerometer driver.
To not add any regressions, I had to add some infrastructure that allows to use
regmap with busses that do limit the size of transfers (block smbus). I hope
this is sufficient to not break anything.

The series has several different parts for regmap and the iio driver:

Patches 1-4 fix some minor things in the regmap core code.

Patches 5-11 fix some issues with regmap busses that do not have an
implementation of read() or write(). Currently a lot of the regmap API
functions simply fail for those busses.

Patches 12-14 introduce 'max_raw_io' for busses which defines the max number of
bytes that may be send or received by this bus. This includes handling in
regmap_bulk_read/write and reporting an error for raw_read/writes that are
above this limit (E2BIG).

Patch 15 makes use of max_raw_io by adding smbus i2c block bus driver. This
patch is created to avoid regressions in the bmc150 driver.

Patches 16-20 move bmc150 to use regmap and add SPI support.


As I don't have a bmc150 connected via smbus I am not able to test Patch 14 and
the resulting I2C part of the bmc150 driver. It would be great if someone with
the hardware could test it. Also it would be great to have some test coverage
for all other regmap setups.

Best Regards,

Markus



Markus Pargmann (20):
  regmap: Add missing comments about struct regmap_bus
  regmap: Remove regmap_bulk_write 64bit support
  regmap: Fix integertypes for register address and value
  regmap: Do not skip format initialization
  regmap: Restructure writes in _regmap_raw_write()
  regmap: Fix regmap_bulk_write for bus writes
  regmap: Without bus read() or write(), force use_single_rw
  regmap: Fix regmap_can_raw_write check
  regmap: _regmap_raw_write fix for busses without write()
  regmap: _regmap_raw_multi_reg_write: Add reg_write() support
  regmap: _regmap_raw_read: Add handling of busses without bus->read()
  regmap: Introduce max_raw_io for regmap_bulk_read/write
  regmap: regmap max_raw_io getter function
  regmap: Add raw_write/read checks for max_raw_write/read sizes
  regmap-i2c: Add smbus i2c block support
  iio: bmc150: Fix irq checks
  iio: bmc150: Use i2c regmap
  iio: bcm150: Remove i2c_client from private data
  iio: bmc150: Split the driver into core and i2c
  iio: bmc150: Add SPI driver

 drivers/base/regmap/internal.h                     |   3 +
 drivers/base/regmap/regmap-i2c.c                   |  46 +++
 drivers/base/regmap/regmap.c                       | 221 ++++++++---
 drivers/iio/accel/Kconfig                          |  32 +-
 drivers/iio/accel/Makefile                         |   4 +-
 .../accel/{bmc150-accel.c => bmc150-accel-core.c}  | 404 ++++++++-------------
 drivers/iio/accel/bmc150-accel-i2c.c               | 101 ++++++
 drivers/iio/accel/bmc150-accel-spi.c               |  86 +++++
 drivers/iio/accel/bmc150-accel.h                   |  21 ++
 include/linux/regmap.h                             |   8 +-
 10 files changed, 622 insertions(+), 304 deletions(-)
 rename drivers/iio/accel/{bmc150-accel.c => bmc150-accel-core.c} (82%)
 create mode 100644 drivers/iio/accel/bmc150-accel-i2c.c
 create mode 100644 drivers/iio/accel/bmc150-accel-spi.c
 create mode 100644 drivers/iio/accel/bmc150-accel.h

-- 
2.4.6



From mpa at pengutronix.de  Wed Aug 12 03:12:29 2015
From: mpa at pengutronix.de (Markus Pargmann)
Date: Wed, 12 Aug 2015 12:12:29 +0200
Subject: [PATCH 04/20] regmap: Do not skip format initialization
In-Reply-To: <1439374365-20623-1-git-send-email-mpa@pengutronix.de>
References: <1439374365-20623-1-git-send-email-mpa@pengutronix.de>
Message-ID: <1439374365-20623-5-git-send-email-mpa@pengutronix.de>

It is not obvious why format initialization is skipped here. format
functions are used for example in regmap_bulk_read even if bus is not
set. So they are used even if skipped here which leads to null pointer
errors.

This patch adds format initialization for !bus and !bus->read/write.

Signed-off-by: Markus Pargmann <mpa at pengutronix.de>
---
 drivers/base/regmap/regmap.c | 4 ----
 1 file changed, 4 deletions(-)

diff --git a/drivers/base/regmap/regmap.c b/drivers/base/regmap/regmap.c
index 4fe5f63edb54..86e94be3c749 100644
--- a/drivers/base/regmap/regmap.c
+++ b/drivers/base/regmap/regmap.c
@@ -607,13 +607,11 @@ struct regmap *regmap_init(struct device *dev,
 		map->reg_write = config->reg_write;
 
 		map->defer_caching = false;
-		goto skip_format_initialization;
 	} else if (!bus->read || !bus->write) {
 		map->reg_read = _regmap_bus_reg_read;
 		map->reg_write = _regmap_bus_reg_write;
 
 		map->defer_caching = false;
-		goto skip_format_initialization;
 	} else {
 		map->reg_read  = _regmap_bus_read;
 	}
@@ -784,8 +782,6 @@ struct regmap *regmap_init(struct device *dev,
 		map->reg_write = _regmap_bus_raw_write;
 	}
 
-skip_format_initialization:
-
 	map->range_tree = RB_ROOT;
 	for (i = 0; i < config->num_ranges; i++) {
 		const struct regmap_range_cfg *range_cfg = &config->ranges[i];
-- 
2.4.6



From mpa at pengutronix.de  Wed Aug 12 03:12:38 2015
From: mpa at pengutronix.de (Markus Pargmann)
Date: Wed, 12 Aug 2015 12:12:38 +0200
Subject: [PATCH 13/20] regmap: regmap max_raw_io getter function
In-Reply-To: <1439374365-20623-1-git-send-email-mpa@pengutronix.de>
References: <1439374365-20623-1-git-send-email-mpa@pengutronix.de>
Message-ID: <1439374365-20623-14-git-send-email-mpa@pengutronix.de>

Signed-off-by: Markus Pargmann <mpa at pengutronix.de>
---
 drivers/base/regmap/regmap.c | 22 ++++++++++++++++++++++
 include/linux/regmap.h       |  2 ++
 2 files changed, 24 insertions(+)

diff --git a/drivers/base/regmap/regmap.c b/drivers/base/regmap/regmap.c
index 6ad4ca849055..8c2be516a100 100644
--- a/drivers/base/regmap/regmap.c
+++ b/drivers/base/regmap/regmap.c
@@ -1393,6 +1393,28 @@ bool regmap_can_raw_write(struct regmap *map)
 }
 EXPORT_SYMBOL_GPL(regmap_can_raw_write);
 
+/**
+ * regmap_get_raw_io_max - Get the maximum size we can read/write
+ *
+ * @map: Map to check.
+ */
+size_t regmap_get_raw_io_max(struct regmap *map)
+{
+	return map->max_raw_io;
+}
+EXPORT_SYMBOL_GPL(regmap_get_raw_io_max);
+
+/**
+ * regmap_get_raw_read_max - Get the maximum size we can read
+ *
+ * @map: Map to check.
+ */
+size_t regmap_get_raw_read_max(struct regmap *map)
+{
+	return map->max_raw_io;
+}
+EXPORT_SYMBOL_GPL(regmap_get_raw_read_max);
+
 static int _regmap_bus_formatted_write(void *context, unsigned int reg,
 				       unsigned int val)
 {
diff --git a/include/linux/regmap.h b/include/linux/regmap.h
index 2cb62d141761..b236f884f642 100644
--- a/include/linux/regmap.h
+++ b/include/linux/regmap.h
@@ -441,6 +441,8 @@ int regmap_get_max_register(struct regmap *map);
 int regmap_get_reg_stride(struct regmap *map);
 int regmap_async_complete(struct regmap *map);
 bool regmap_can_raw_write(struct regmap *map);
+size_t regmap_get_raw_write_max(struct regmap *map);
+size_t regmap_get_raw_io_max(struct regmap *map);
 
 int regcache_sync(struct regmap *map);
 int regcache_sync_region(struct regmap *map, unsigned int min,
-- 
2.4.6



From djkurtz at chromium.org  Wed Aug 12 03:33:55 2015
From: djkurtz at chromium.org (Daniel Kurtz)
Date: Wed, 12 Aug 2015 18:33:55 +0800
Subject: [PATCH 07/20] regmap: Without bus read() or write(),
 force use_single_rw
In-Reply-To: <1439374365-20623-8-git-send-email-mpa@pengutronix.de>
References: <1439374365-20623-1-git-send-email-mpa@pengutronix.de>
 <1439374365-20623-8-git-send-email-mpa@pengutronix.de>
Message-ID: <CAGS+omC6dFVnzWmQN2XGy31s1nm-hQJ6DigJREynCAf7A-PcFg@mail.gmail.com>

Hi Markus,

On Wed, Aug 12, 2015 at 6:12 PM, Markus Pargmann <mpa at pengutronix.de> wrote:
>
> The implementation of regmap bus read() and write() methods are
> optional. Therefore we have to handle busses which do not have these
> functions. If raw read() and write() is not supported we have to use
> reg_read and reg_write always.
>
> This patch sets use_single_rw if read() or write() is not set.
>
> Signed-off-by: Markus Pargmann <mpa at pengutronix.de>
> ---
>  drivers/base/regmap/regmap.c | 2 +-
>  1 file changed, 1 insertion(+), 1 deletion(-)
>
> diff --git a/drivers/base/regmap/regmap.c b/drivers/base/regmap/regmap.c
> index f98bd5bf5c62..35ad3783da70 100644
> --- a/drivers/base/regmap/regmap.c
> +++ b/drivers/base/regmap/regmap.c
> @@ -573,7 +573,7 @@ struct regmap *regmap_init(struct device *dev,
>                 map->reg_stride = config->reg_stride;
>         else
>                 map->reg_stride = 1;
> -       map->use_single_rw = config->use_single_rw;
> +       map->use_single_rw = config->use_single_rw || !bus->read || !bus->write;

What if bus is NULL?

-Dan

>         map->can_multi_write = config->can_multi_write;
>         map->dev = dev;
>         map->bus = bus;
> --
> 2.4.6
>
> --
> To unsubscribe from this list: send the line "unsubscribe linux-kernel" in
> the body of a message to majordomo at vger.kernel.org
> More majordomo info at  http://vger.kernel.org/majordomo-info.html
> Please read the FAQ at  http://www.tux.org/lkml/


From broonie at kernel.org  Wed Aug 12 03:37:36 2015
From: broonie at kernel.org (Mark Brown)
Date: Wed, 12 Aug 2015 11:37:36 +0100
Subject: [PATCH 00/20] Regmap max_raw_io and bmc150 SPI support
In-Reply-To: <1439374365-20623-1-git-send-email-mpa@pengutronix.de>
References: <1439374365-20623-1-git-send-email-mpa@pengutronix.de>
Message-ID: <20150812103736.GR10748@sirena.org.uk>

On Wed, Aug 12, 2015 at 12:12:25PM +0200, Markus Pargmann wrote:
> Hi,
> 
> this series was created to add SPI support to the bmc150 accelerometer driver.
> To not add any regressions, I had to add some infrastructure that allows to use
> regmap with busses that do limit the size of transfers (block smbus). I hope
> this is sufficient to not break anything.

This is a really big series but looking at at least the initial patches
there's a lot of unrelated cleanups mixed in with it.  Please don't do
this, send things like cleanups separately so that your series is
focused on the relevant topic.  This makes things much easier to work
with.
-------------- next part --------------
A non-text attachment was scrubbed...
Name: signature.asc
Type: application/pgp-signature
Size: 473 bytes
Desc: Digital signature
URL: <http://lists.infradead.org/pipermail/linux-arm-kernel/attachments/20150812/8f2eb69e/attachment.sig>

From alexandre.belloni at free-electrons.com  Wed Aug 12 03:41:33 2015
From: alexandre.belloni at free-electrons.com (Alexandre Belloni)
Date: Wed, 12 Aug 2015 12:41:33 +0200
Subject: [PATCH V1 Resend 06/10] drivers: rtc: Drop (un)likely before
 IS_ERR(_OR_NULL)
In-Reply-To: <1a92f2e1af5309ece9736f79f312e90486a98825.1439375087.git.viresh.kumar@linaro.org>
References: <cover.1439375087.git.viresh.kumar@linaro.org>
 <1a92f2e1af5309ece9736f79f312e90486a98825.1439375087.git.viresh.kumar@linaro.org>
Message-ID: <20150812104133.GE3411@piout.net>

Hi Viresh,

Why are you resending?

On 12/08/2015 at 15:59:43 +0530, Viresh Kumar wrote :
> IS_ERR(_OR_NULL) already contain an 'unlikely' compiler flag and there
> is no need to do that again from its callers. Drop it.
> 
> gemini driver was using likely() for a failure case while the rtc driver
> is getting registered. That looks wrong and it should really be
> unlikely. But because we are killing all the unlikely() flags, lets kill
> that too.
> 
> Acked-by: Hans Ulli Kroll <ulli.kroll at googlemail.com> (gemini)
> Signed-off-by: Viresh Kumar <viresh.kumar at linaro.org>
> ---
>  drivers/rtc/interface.c  | 2 +-
>  drivers/rtc/rtc-bfin.c   | 2 +-
>  drivers/rtc/rtc-gemini.c | 2 +-
>  3 files changed, 3 insertions(+), 3 deletions(-)
> 
> diff --git a/drivers/rtc/interface.c b/drivers/rtc/interface.c
> index 11b639067312..5836751b8203 100644
> --- a/drivers/rtc/interface.c
> +++ b/drivers/rtc/interface.c
> @@ -564,7 +564,7 @@ enum hrtimer_restart rtc_pie_update_irq(struct hrtimer *timer)
>  void rtc_update_irq(struct rtc_device *rtc,
>  		unsigned long num, unsigned long events)
>  {
> -	if (unlikely(IS_ERR_OR_NULL(rtc)))
> +	if (IS_ERR_OR_NULL(rtc))
>  		return;
>  
>  	pm_stay_awake(rtc->dev.parent);
> diff --git a/drivers/rtc/rtc-bfin.c b/drivers/rtc/rtc-bfin.c
> index 3d44b11721ea..535a5f9338d0 100644
> --- a/drivers/rtc/rtc-bfin.c
> +++ b/drivers/rtc/rtc-bfin.c
> @@ -361,7 +361,7 @@ static int bfin_rtc_probe(struct platform_device *pdev)
>  	/* Register our RTC with the RTC framework */
>  	rtc->rtc_dev = devm_rtc_device_register(dev, pdev->name, &bfin_rtc_ops,
>  						THIS_MODULE);
> -	if (unlikely(IS_ERR(rtc->rtc_dev)))
> +	if (IS_ERR(rtc->rtc_dev))
>  		return PTR_ERR(rtc->rtc_dev);
>  
>  	/* Grab the IRQ and init the hardware */
> diff --git a/drivers/rtc/rtc-gemini.c b/drivers/rtc/rtc-gemini.c
> index 35f4486738fc..2fed93e1114a 100644
> --- a/drivers/rtc/rtc-gemini.c
> +++ b/drivers/rtc/rtc-gemini.c
> @@ -148,7 +148,7 @@ static int gemini_rtc_probe(struct platform_device *pdev)
>  
>  	rtc->rtc_dev = rtc_device_register(pdev->name, dev,
>  					   &gemini_rtc_ops, THIS_MODULE);
> -	if (likely(IS_ERR(rtc->rtc_dev)))
> +	if (IS_ERR(rtc->rtc_dev))
>  		return PTR_ERR(rtc->rtc_dev);
>  
>  	return 0;
> -- 
> 2.4.0
> 

-- 
Alexandre Belloni, Free Electrons
Embedded Linux, Kernel and Android engineering
http://free-electrons.com


From srinivas.kandagatla at linaro.org  Wed Aug 12 03:41:55 2015
From: srinivas.kandagatla at linaro.org (Srinivas Kandagatla)
Date: Wed, 12 Aug 2015 11:41:55 +0100
Subject: [PATCH v8 3/4] drivers: nvmem: Add Vybrid OCOTP support
In-Reply-To: <29b527f1897b24a310a3f3acee61c721d3399503.1439214648.git.maitysanchayan@gmail.com>
References: <cover.1439214648.git.maitysanchayan@gmail.com>
 <29b527f1897b24a310a3f3acee61c721d3399503.1439214648.git.maitysanchayan@gmail.com>
Message-ID: <55CB22F3.2000702@linaro.org>

Hi Sanchayan,

Please run checkpatch before you send the patch next time.
Look at Documentation/SubmittingPatches for more details.

WARNING: line over 80 characters
#225: FILE: drivers/nvmem/vf610-ocotp.c:174:
+			ret = vf610_ocotp_wait_busy(ocotp->base + OCOTP_CTRL_REG);

WARNING: line over 80 characters
#237: FILE: drivers/nvmem/vf610-ocotp.c:186:
+			ret = vf610_ocotp_wait_busy(ocotp->base + OCOTP_CTRL_REG);

WARNING: line over 80 characters
#244: FILE: drivers/nvmem/vf610-ocotp.c:193:
+				writel(OCOTP_CTRL_ERROR, ocotp->base + OCOTP_CTRL_CLR);


On 10/08/15 15:11, Sanchayan Maity wrote:
> The patch adds support for the On Chip One Time Programmable Peripheral
> (OCOTP) on the Vybrid platform.
>
> Signed-off-by: Sanchayan Maity <maitysanchayan at gmail.com>
> ---
>   drivers/nvmem/Kconfig       |  10 ++
>   drivers/nvmem/Makefile      |   2 +
>   drivers/nvmem/vf610-ocotp.c | 301 ++++++++++++++++++++++++++++++++++++++++++++
>   3 files changed, 313 insertions(+)
>   create mode 100644 drivers/nvmem/vf610-ocotp.c
>
> diff --git a/drivers/nvmem/Kconfig b/drivers/nvmem/Kconfig
> index 0b33014..7af4c1d 100644
> --- a/drivers/nvmem/Kconfig
> +++ b/drivers/nvmem/Kconfig
> @@ -47,4 +47,14 @@ config NVMEM_IMX_OCOTP
>   	  This driver can also be built as a module. If so, the module
>   	  will be called nvmem-imx-ocotp.
>

Also please can you rebase it on top of char-misc-next?, This patch 
would not apply as it is because of the above context.


> +config NVMEM_VF610_OCOTP
> +	tristate "VF610_SoCs OCOTP support"
> +	depends on SOC_VF610 || COMPILE_TEST
> +	help
> +	  This is a driver for the 'OCOTP' peripheral available on Vybrid
> +	  devices like VF5xx and VF6xx.
> +
> +	  This driver can also be built as a module. If so, the module will
> +	  be called nvmem-vf610-ocotp.
> +
>   endif
> diff --git a/drivers/nvmem/Makefile b/drivers/nvmem/Makefile
> index b512d77..8a1eea8 100644
> --- a/drivers/nvmem/Makefile
> +++ b/drivers/nvmem/Makefile
> @@ -12,3 +12,5 @@ obj-$(CONFIG_NVMEM_SUNXI_SID)	+= nvmem_sunxi_sid.o
>   nvmem_sunxi_sid-y		:= sunxi_sid.o
>   obj-$(CONFIG_NVMEM_IMX_OCOTP)	+= nvmem-imx-ocotp.o
>   nvmem-imx-ocotp-y		:= imx-ocotp.o
> +obj-$(CONFIG_NVMEM_VF610_OCOTP)	+= nvmem-vf610-ocotp.o
> +nvmem-vf610-ocotp-y		:= vf610-ocotp.o
> diff --git a/drivers/nvmem/vf610-ocotp.c b/drivers/nvmem/vf610-ocotp.c
> new file mode 100644
> index 0000000..9e18156
> --- /dev/null
> +++ b/drivers/nvmem/vf610-ocotp.c
> @@ -0,0 +1,301 @@
> +/*
> + * Copyright (C) 2015 Toradex AG.
> + *
> + * Author: Sanchayan Maity <sanchayan.maity at toradex.com>
> + *
> + * Based on the barebox ocotp driver,
> + * Copyright (c) 2010 Baruch Siach <baruch at tkos.co.il>
> + *	Orex Computed Radiography
> + *
> + * This program is free software; you can redistribute it and/or modify
> + * it under the terms of the GNU General Public License version 2 and
> + * only 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/clk.h>
> +#include <linux/delay.h>
> +#include <linux/device.h>
> +#include <linux/io.h>
> +#include <linux/module.h>
> +#include <linux/nvmem-provider.h>
> +#include <linux/of.h>
> +#include <linux/platform_device.h>
> +#include <linux/regmap.h>
> +#include <linux/slab.h>
> +
> +/* OCOTP Register Offsets */
> +#define OCOTP_CTRL_REG				0x00
> +#define OCOTP_CTRL_SET				0x04
> +#define OCOTP_CTRL_CLR				0x08
> +#define OCOTP_TIMING				0x10
> +#define OCOTP_DATA				0x20
> +#define OCOTP_READ_CTRL_REG			0x30
> +#define OCOTP_READ_FUSE_DATA			0x40
> +
> +/* OCOTP Register bits and masks */
> +#define OCOTP_CTRL_WR_UNLOCK			16
> +#define OCOTP_CTRL_WR_UNLOCK_KEY		0x3E77
> +#define OCOTP_CTRL_WR_UNLOCK_MASK		GENMASK(31, 16)
> +#define OCOTP_CTRL_ADDR				0
> +#define OCOTP_CTRL_ADDR_MASK			GENMASK(6, 0)
> +#define OCOTP_CTRL_RELOAD_SHADOWS		BIT(10)
> +#define OCOTP_CTRL_ERROR			BIT(9)
> +#define OCOTP_CTRL_BUSY				BIT(8)
> +
> +#define OCOTP_TIMING_STROBE_READ		16
> +#define OCOTP_TIMING_STROBE_READ_MASK		GENMASK(21, 16)
> +#define OCOTP_TIMING_RELAX			12
> +#define OCOTP_TIMING_RELAX_MASK			GENMASK(15, 12)
> +#define OCOTP_TIMING_STROBE_PROG		0
> +#define OCOTP_TIMING_STROBE_PROG_MASK		GENMASK(11, 0)
> +
> +#define OCOTP_READ_CTRL_READ_FUSE		0x1
> +
> +#define VF610_OCOTP_TIMEOUT			100000
> +
> +#define BF(value, field)		(((value) << field) & field##_MASK)
> +
> +#define DEF_RELAX				20
> +
> +static const int base_to_fuse_addr_mappings[][2] = {
> +	{0x400, 0x00},
> +	{0x410, 0x01},
> +	{0x420, 0x02},
> +	{0x450, 0x05},
> +	{0x4F0, 0x0F},
> +	{0x600, 0x20},
> +	{0x610, 0x21},
> +	{0x620, 0x22},
> +	{0x630, 0x23},
> +	{0x640, 0x24},
> +	{0x650, 0x25},
> +	{0x660, 0x26},
> +	{0x670, 0x27},
> +	{0x6F0, 0x2F},
> +	{0x880, 0x38},
> +	{0x890, 0x39},
> +	{0x8A0, 0x3A},
> +	{0x8B0, 0x3B},
> +	{0x8C0, 0x3C},
> +	{0x8D0, 0x3D},
> +	{0x8E0, 0x3E},
> +	{0x8F0, 0x3F},
> +	{0xC80, 0x78},
> +	{0xC90, 0x79},
> +	{0xCA0, 0x7A},
> +	{0xCB0, 0x7B},
> +	{0xCC0, 0x7C},
> +	{0xCD0, 0x7D},
> +	{0xCE0, 0x7E},
> +	{0xCF0, 0x7F},
> +};
> +
> +struct vf610_ocotp {
> +	void __iomem *base;
> +	struct clk *clk;
> +	struct device *dev;
> +	struct nvmem_device *nvmem;
> +	int timing;
> +};
> +
> +static int vf610_ocotp_wait_busy(void __iomem *base)
> +{
> +	int timeout = VF610_OCOTP_TIMEOUT;
> +
> +	while ((readl(base) & OCOTP_CTRL_BUSY) && --timeout)
> +		udelay(10);
> +
> +	if (!timeout) {
> +		writel(OCOTP_CTRL_ERROR, base + OCOTP_CTRL_CLR);
> +		return -ETIMEDOUT;
> +	}
> +
> +	udelay(10);
> +
> +	return 0;
> +}
> +
> +static int vf610_ocotp_calculate_timing(struct vf610_ocotp *ocotp_dev)
> +{
> +	u32 clk_rate;
> +	u32 relax, strobe_read, strobe_prog;
> +	u32 timing;
> +
> +	clk_rate = clk_get_rate(ocotp_dev->clk);
> +
> +	/* Refer section OTP read/write timing parameters in TRM */
> +	relax = clk_rate / (1000000000 / DEF_RELAX) - 1;
> +	strobe_prog = clk_rate / (1000000000 / 10000) + 2 * (DEF_RELAX + 1) - 1;
> +	strobe_read = clk_rate / (1000000000 / 40) + 2 * (DEF_RELAX + 1) - 1;
> +
> +	timing = BF(relax, OCOTP_TIMING_RELAX);
> +	timing |= BF(strobe_read, OCOTP_TIMING_STROBE_READ);
> +	timing |= BF(strobe_prog, OCOTP_TIMING_STROBE_PROG);
> +
> +	return timing;
> +}
> +
> +static int vf610_get_fuse_address(int base_addr_offset)
> +{
> +	int i;
> +
> +	for (i = 0; i < ARRAY_SIZE(base_to_fuse_addr_mappings); i++) {
> +		if (base_to_fuse_addr_mappings[i][0] == base_addr_offset)
> +			return base_to_fuse_addr_mappings[i][1];
> +	}
> +
> +	return -EINVAL;
> +}
> +
> +static int vf610_ocotp_write(void *context, const void *data, size_t count)
> +{
> +	return 0;
> +}
> +
> +static int vf610_ocotp_read(void *context,
> +			const void *off, size_t reg_size,
> +			void *val, size_t val_size)
> +{
> +	struct vf610_ocotp *ocotp = context;
> +	unsigned int offset = *(u32 *)off;
> +	u32 reg, *buf = val;
> +	int fuse_addr;
> +	int ret;
> +
> +	while (val_size > 0) {
> +		fuse_addr = vf610_get_fuse_address(offset);
> +		if (fuse_addr > 0) {
> +			writel(ocotp->timing, ocotp->base + OCOTP_TIMING);
> +			ret = vf610_ocotp_wait_busy(ocotp->base + OCOTP_CTRL_REG);
> +			if (ret)
> +				return ret;
> +
> +			reg = readl(ocotp->base + OCOTP_CTRL_REG);
> +			reg &= ~OCOTP_CTRL_ADDR_MASK;
> +			reg &= ~OCOTP_CTRL_WR_UNLOCK_MASK;
> +			reg |= BF(fuse_addr, OCOTP_CTRL_ADDR);
> +			writel(reg, ocotp->base + OCOTP_CTRL_REG);
> +
> +			writel(OCOTP_READ_CTRL_READ_FUSE,
> +				ocotp->base + OCOTP_READ_CTRL_REG);
> +			ret = vf610_ocotp_wait_busy(ocotp->base + OCOTP_CTRL_REG);
> +			if (ret)
> +				return ret;
> +
> +			if (readl(ocotp->base) & OCOTP_CTRL_ERROR) {
> +				dev_dbg(ocotp->dev, "Error reading from fuse address %x\n",
> +					fuse_addr);
> +				writel(OCOTP_CTRL_ERROR, ocotp->base + OCOTP_CTRL_CLR);
> +			}
> +
> +			/*
> +			 * In case of error, we do not abort and expect to read
> +			 * 0xBADABADA as mentioned by the TRM. We just read this
> +			 * value and return.
> +			 */
> +			*buf = readl(ocotp->base + OCOTP_READ_FUSE_DATA);
> +		} else {
> +			*buf = 0;
> +		}
> +
> +		buf++;
> +		val_size--;
> +		offset += reg_size;
> +	}
> +
> +	return 0;
> +}
> +
> +static struct regmap_bus vf610_ocotp_bus = {
> +	.read = vf610_ocotp_read,
> +	.write = vf610_ocotp_write,
> +	.reg_format_endian_default = REGMAP_ENDIAN_NATIVE,
> +	.val_format_endian_default = REGMAP_ENDIAN_NATIVE,
> +};
> +
> +static struct regmap_config ocotp_regmap_config = {
> +	.reg_bits = 32,
> +	.val_bits = 32,
> +	.reg_stride = 4,
> +};
> +
> +static struct nvmem_config ocotp_config = {
> +	.name = "ocotp",
> +	.owner = THIS_MODULE,
> +};
> +
> +static const struct of_device_id ocotp_of_match[] = {
> +	{ .compatible = "fsl,vf610-ocotp", },
> +	{/* sentinel */},
> +};
> +MODULE_DEVICE_TABLE(of, ocotp_of_match);
> +
> +static int vf610_ocotp_remove(struct platform_device *pdev)
> +{
> +	struct vf610_ocotp *ocotp_dev = platform_get_drvdata(pdev);
> +
> +	return nvmem_unregister(ocotp_dev->nvmem);
> +}
> +
> +static int vf610_ocotp_probe(struct platform_device *pdev)
> +{
> +	struct device *dev = &pdev->dev;
> +	struct resource *res;
> +	struct regmap *regmap;
> +	struct vf610_ocotp *ocotp_dev;
> +
> +	ocotp_dev = devm_kzalloc(&pdev->dev,
> +			sizeof(struct vf610_ocotp), GFP_KERNEL);
> +	if (!ocotp_dev)
> +		return -ENOMEM;
> +
> +	res = platform_get_resource(pdev, IORESOURCE_MEM, 0);
> +	ocotp_dev->base = devm_ioremap_resource(dev, res);
> +	if (IS_ERR(ocotp_dev->base))
> +		return PTR_ERR(ocotp_dev->base);
> +
> +	ocotp_dev->clk = devm_clk_get(dev, "ocotp");
> +	if (IS_ERR(ocotp_dev->clk)) {
> +		dev_err(dev, "failed getting clock, err = %ld\n",
> +			PTR_ERR(ocotp_dev->clk));
> +		return PTR_ERR(ocotp_dev->clk);
> +	}
> +
> +	ocotp_regmap_config.max_register = resource_size(res);
> +	regmap = devm_regmap_init(dev,
> +		&vf610_ocotp_bus, ocotp_dev, &ocotp_regmap_config);
> +	if (IS_ERR(regmap)) {
> +		dev_err(dev, "regmap init failed\n");
> +		return PTR_ERR(regmap);
> +	}
> +	ocotp_config.dev = dev;
> +
> +	ocotp_dev->nvmem = nvmem_register(&ocotp_config);
> +	if (IS_ERR(ocotp_dev->nvmem))
> +		return PTR_ERR(ocotp_dev->nvmem);
> +
> +	ocotp_dev->dev = dev;
> +	platform_set_drvdata(pdev, ocotp_dev);
> +
> +	ocotp_dev->timing = vf610_ocotp_calculate_timing(ocotp_dev);
> +
> +	return 0;
> +}
> +
> +static struct platform_driver vf610_ocotp_driver = {
> +	.probe = vf610_ocotp_probe,
> +	.remove = vf610_ocotp_remove,
> +	.driver = {
> +		.name = "vf610-ocotp",
> +		.of_match_table = ocotp_of_match,
> +	},
> +};
> +module_platform_driver(vf610_ocotp_driver);
> +MODULE_AUTHOR("Sanchayan Maity <sanchayan.maity at toradex.com>");
> +MODULE_DESCRIPTION("Vybrid OCOTP driver");
> +MODULE_LICENSE("GPL v2");
>


From lee.jones at linaro.org  Wed Aug 12 03:43:50 2015
From: lee.jones at linaro.org (Lee Jones)
Date: Wed, 12 Aug 2015 11:43:50 +0100
Subject: [PATCH v2 2/6] mailbox: dt-bindings: Add shared [driver <=>
 device tree] defines
In-Reply-To: <CABb+yY3LdX1Lk7jfPbdXr4Zw=zKGJ=TsRRhB5a4CeYHOsjb90A@mail.gmail.com>
References: <1437990272-23111-1-git-send-email-lee.jones@linaro.org>
 <1437990272-23111-3-git-send-email-lee.jones@linaro.org>
 <CABb+yY2asjH-c+VJXvG+RK0=2p=P4Y21pznNP0riaKMWLxYZog@mail.gmail.com>
 <20150810082445.GA3249@x1>
 <CABb+yY3jUKXXJys32bHY1u+dbdsix71Xq_H1Lrkkt27vZzmf7w@mail.gmail.com>
 <20150812085309.GB18282@x1>
 <CABb+yY3LdX1Lk7jfPbdXr4Zw=zKGJ=TsRRhB5a4CeYHOsjb90A@mail.gmail.com>
Message-ID: <20150812104350.GF18282@x1>

On Wed, 12 Aug 2015, Jassi Brar wrote:

> On Wed, Aug 12, 2015 at 2:23 PM, Lee Jones <lee.jones at linaro.org> wrote:
> > On Mon, 10 Aug 2015, Jassi Brar wrote:
> >
> >> On Mon, Aug 10, 2015 at 1:54 PM, Lee Jones <lee.jones at linaro.org> wrote:
> >> > On Mon, 10 Aug 2015, Jassi Brar wrote:
> >> >> On Mon, Jul 27, 2015 at 3:14 PM, Lee Jones <lee.jones at linaro.org> wrote:
> >> >> > This header is currently only used for defines pertaining to data
> >> >> > direction i.e. Rx, Tx or Loopback.
> >> >> >
> >> >> > Signed-off-by: Lee Jones <lee.jones at linaro.org>
> >> >> > ---
> >> >> >  include/dt-bindings/mailbox/mailbox.h | 14 ++++++++++++++
> >> >> >  1 file changed, 14 insertions(+)
> >> >> >  create mode 100644 include/dt-bindings/mailbox/mailbox.h
> >> >> >
> >> >> > diff --git a/include/dt-bindings/mailbox/mailbox.h b/include/dt-bindings/mailbox/mailbox.h
> >> >> > new file mode 100644
> >> >> > index 0000000..82e929a
> >> >> > --- /dev/null
> >> >> > +++ b/include/dt-bindings/mailbox/mailbox.h
> >> >> > @@ -0,0 +1,14 @@
> >> >> > +/*
> >> >> > + * 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.
> >> >> > + */
> >> >> > +
> >> >> > +#ifndef __MAILBOX_CONTROLLER_DT_BINDINGS_H
> >> >> > +#define __MAILBOX_CONTROLLER_DT_BINDINGS_H
> >> >> > +
> >> >> > +#define MBOX_TX                0x1
> >> >> > +#define MBOX_RX                0x2
> >> >> > +#define MBOX_LOOPBACK  (MBOX_RX | MBOX_TX)
> >> >> > +
> >> >> Not sure I understand 'loopback'.  Does it mean h/w has some
> >> >> 'loopback' mode for testing purposes? Or it simply means the
> >> >> controller can send as well as receive messages?
> >> >
> >> > 'loopback' allows firmware to conduct some early function tests.
> >> > However, channels are simplex, so we provide protection against
> >> > multiple allocation of single channel.  By allocating a LOOPBACK
> >> > channel we over-ride this protection and allow a single channel to be
> >> > allocated twice, once for Rx and the other for Tx.
> >> >
> >> So basically hardware is half-duplex, not simplex. I think maybe you
> >> should simply allow for RX and TX always. It should work. Just
> >> handover any received data before send_data (reflecting the h/w
> >> limitation). That way you don't need any such special flag.
> >
> > Unfortunately no, that's not correct.  Only Mailbox 0 is half-duplex.
> > The others are simplex (Rx only).
> >
> Assuming that is indeed the case (though code and comments suggest
> otherwise),

Sorry, that should have read "Tx only".  Only the A9 (Mbox 0) can Rx.

> it is still not a matter of choice for clients to 'make' a
> channel RX or TX or RXTX. That is the property/constraint of the
> controller and the controller driver should simply check for channel
> ID to be zero in send_data() and return error if its non-zero.

The client is not 'making' the channel Rx or Tx.  It's requesting a
specific Rx or Tx channel.  It's the controller's responsibility to
tell the client if the configuration it has requested is invalid or
already in use.

You're suggesting I remove configuration checking during
mbox_request_channel(), which is not a good suggestion.  That will
fool the client into thinking it has successfully obtained a channel
with the configuration it desires, only to fail later when it attempts
to actually send a message.  Either that, or it will be waiting
forever for a message that it will never receive because it has
selected a Tx only channel to receive from.

That doesn't sound reasonable to me.

> >  Ideally I'd like to keep the
> > LOOPBACK flag, as it's easier to figure out if what someone is
> > attempting to do is actually valid.
> >
> I am not for such paranoia. Provider drivers is not the place to check
> for valid user data.

No one is checking data here.  We are checking channel confirmation,
which is absolutely a controller's responsibility.

> The controller driver should simply reject send_data() request on any
> mailbox > 0 while the consumer driver should scream for attention
> because that's where the problem is.

That would make debugging very difficult, due to the fact that we've
already insinuated that the client had successfully received the
channel/configuration it desired, when in actual fact, the provider of
that channel would know full well that it was actually invalid.

> Please note, what I suggest will only make the code simpler while not
> breaking anything.

Simpler yes.  We could remove all error checking and the driver would
be simpler still, but the fact remains that it would not be doing its
job and debugging would become neigh impossible.

-- 
Lee Jones
Linaro STMicroelectronics Landing Team Lead
Linaro.org ? Open source software for ARM SoCs
Follow Linaro: Facebook | Twitter | Blog


From broonie at kernel.org  Wed Aug 12 03:43:55 2015
From: broonie at kernel.org (Mark Brown)
Date: Wed, 12 Aug 2015 11:43:55 +0100
Subject: [PATCH 04/20] regmap: Do not skip format initialization
In-Reply-To: <1439374365-20623-5-git-send-email-mpa@pengutronix.de>
References: <1439374365-20623-1-git-send-email-mpa@pengutronix.de>
 <1439374365-20623-5-git-send-email-mpa@pengutronix.de>
Message-ID: <20150812104355.GS10748@sirena.org.uk>

On Wed, Aug 12, 2015 at 12:12:29PM +0200, Markus Pargmann wrote:

> It is not obvious why format initialization is skipped here. format
> functions are used for example in regmap_bulk_read even if bus is not
> set. So they are used even if skipped here which leads to null pointer
> errors.

> This patch adds format initialization for !bus and !bus->read/write.

Format initialisation is skipped because it is not clear what the wire
format actually is if we're not using the regmap internal marshalling.
Someone needs to do a survey of what the existing users are trying to do
before changing anything here.
-------------- next part --------------
A non-text attachment was scrubbed...
Name: signature.asc
Type: application/pgp-signature
Size: 473 bytes
Desc: Digital signature
URL: <http://lists.infradead.org/pipermail/linux-arm-kernel/attachments/20150812/6e232e0c/attachment.sig>

From mpa at pengutronix.de  Wed Aug 12 03:44:36 2015
From: mpa at pengutronix.de (Markus Pargmann)
Date: Wed, 12 Aug 2015 12:44:36 +0200
Subject: [PATCH 02/20] regmap: Remove regmap_bulk_write 64bit support
In-Reply-To: <20150812102550.GQ10748@sirena.org.uk>
References: <1439374365-20623-1-git-send-email-mpa@pengutronix.de>
 <1439374365-20623-3-git-send-email-mpa@pengutronix.de>
 <20150812102550.GQ10748@sirena.org.uk>
Message-ID: <20150812104436.GA19600@pengutronix.de>

On Wed, Aug 12, 2015 at 11:25:50AM +0100, Mark Brown wrote:
> On Wed, Aug 12, 2015 at 12:12:27PM +0200, Markus Pargmann wrote:
> > Regmap does not support 64bit. The ival that is used to write the 64bit
> > data to, is unsigned int and can't hold 64bit. _regmap_write also just
> > supports unsigend int.
> 
> What makes you say that unsigned int can't hold 64 bit?  An architecture
> can have 64 bit ints if it likes.

I wasn't aware that any 64 bit architecture actually has unsigned ints
that are 64 bit in size. So wouldn't at least on x86_64 this would lead
to a compiler warning as unsigned int is 4 byte and u64 8 bytes?

Best Regards,

Markus

-- 
Pengutronix e.K.                           |                             |
Industrial Linux Solutions                 | http://www.pengutronix.de/  |
Peiner Str. 6-8, 31137 Hildesheim, Germany | Phone: +49-5121-206917-0    |
Amtsgericht Hildesheim, HRA 2686           | Fax:   +49-5121-206917-5555 |
-------------- next part --------------
A non-text attachment was scrubbed...
Name: signature.asc
Type: application/pgp-signature
Size: 819 bytes
Desc: Digital signature
URL: <http://lists.infradead.org/pipermail/linux-arm-kernel/attachments/20150812/a9e797d9/attachment.sig>

From mpa at pengutronix.de  Wed Aug 12 03:45:45 2015
From: mpa at pengutronix.de (Markus Pargmann)
Date: Wed, 12 Aug 2015 12:45:45 +0200
Subject: [PATCH 07/20] regmap: Without bus read() or write(), force
 use_single_rw
In-Reply-To: <CAGS+omC6dFVnzWmQN2XGy31s1nm-hQJ6DigJREynCAf7A-PcFg@mail.gmail.com>
References: <1439374365-20623-1-git-send-email-mpa@pengutronix.de>
 <1439374365-20623-8-git-send-email-mpa@pengutronix.de>
 <CAGS+omC6dFVnzWmQN2XGy31s1nm-hQJ6DigJREynCAf7A-PcFg@mail.gmail.com>
Message-ID: <20150812104545.GB19600@pengutronix.de>

Hi,

On Wed, Aug 12, 2015 at 06:33:55PM +0800, Daniel Kurtz wrote:
> Hi Markus,
> 
> On Wed, Aug 12, 2015 at 6:12 PM, Markus Pargmann <mpa at pengutronix.de> wrote:
> >
> > The implementation of regmap bus read() and write() methods are
> > optional. Therefore we have to handle busses which do not have these
> > functions. If raw read() and write() is not supported we have to use
> > reg_read and reg_write always.
> >
> > This patch sets use_single_rw if read() or write() is not set.
> >
> > Signed-off-by: Markus Pargmann <mpa at pengutronix.de>
> > ---
> >  drivers/base/regmap/regmap.c | 2 +-
> >  1 file changed, 1 insertion(+), 1 deletion(-)
> >
> > diff --git a/drivers/base/regmap/regmap.c b/drivers/base/regmap/regmap.c
> > index f98bd5bf5c62..35ad3783da70 100644
> > --- a/drivers/base/regmap/regmap.c
> > +++ b/drivers/base/regmap/regmap.c
> > @@ -573,7 +573,7 @@ struct regmap *regmap_init(struct device *dev,
> >                 map->reg_stride = config->reg_stride;
> >         else
> >                 map->reg_stride = 1;
> > -       map->use_single_rw = config->use_single_rw;
> > +       map->use_single_rw = config->use_single_rw || !bus->read || !bus->write;
> 
> What if bus is NULL?

Yes thanks, that has to be checked.

Best Regards,

Markus

> 
> -Dan
> 
> >         map->can_multi_write = config->can_multi_write;
> >         map->dev = dev;
> >         map->bus = bus;
> > --
> > 2.4.6
> >
> > --
> > To unsubscribe from this list: send the line "unsubscribe linux-kernel" in
> > the body of a message to majordomo at vger.kernel.org
> > More majordomo info at  http://vger.kernel.org/majordomo-info.html
> > Please read the FAQ at  http://www.tux.org/lkml/
> 

-- 
Pengutronix e.K.                           |                             |
Industrial Linux Solutions                 | http://www.pengutronix.de/  |
Peiner Str. 6-8, 31137 Hildesheim, Germany | Phone: +49-5121-206917-0    |
Amtsgericht Hildesheim, HRA 2686           | Fax:   +49-5121-206917-5555 |
-------------- next part --------------
A non-text attachment was scrubbed...
Name: signature.asc
Type: application/pgp-signature
Size: 819 bytes
Desc: Digital signature
URL: <http://lists.infradead.org/pipermail/linux-arm-kernel/attachments/20150812/2cb7711c/attachment.sig>

From viresh.kumar at linaro.org  Wed Aug 12 03:46:25 2015
From: viresh.kumar at linaro.org (Viresh Kumar)
Date: Wed, 12 Aug 2015 16:16:25 +0530
Subject: [PATCH V1 Resend 06/10] drivers: rtc: Drop (un)likely before
 IS_ERR(_OR_NULL)
In-Reply-To: <20150812104133.GE3411@piout.net>
References: <cover.1439375087.git.viresh.kumar@linaro.org>
 <1a92f2e1af5309ece9736f79f312e90486a98825.1439375087.git.viresh.kumar@linaro.org>
 <20150812104133.GE3411@piout.net>
Message-ID: <20150812104625.GB20238@linux>

On 12-08-15, 12:41, Alexandre Belloni wrote:
> Hi Viresh,
> 
> Why are you resending?

I never got a reply from Andrew Morton on V1, so resent it again. And
today Andrew asked me to take this via trivial tree.

So the resent.

I need to find a sane way to get few more people to the cover-letter.
The problem is that I am generating the cc-list with get_maintainers,
and if I combine that list for all the patches, it becomes huge. And
really can't send the cover-letter to those people then. Few lists may
block it as well, due to high number of cc'd people.

I am telling this because, the cover-letter did contain the reason for
resend.

-- 
viresh


From mpa at pengutronix.de  Wed Aug 12 03:47:39 2015
From: mpa at pengutronix.de (Markus Pargmann)
Date: Wed, 12 Aug 2015 12:47:39 +0200
Subject: [PATCH 00/20] Regmap max_raw_io and bmc150 SPI support
In-Reply-To: <20150812103736.GR10748@sirena.org.uk>
References: <1439374365-20623-1-git-send-email-mpa@pengutronix.de>
 <20150812103736.GR10748@sirena.org.uk>
Message-ID: <20150812104739.GC19600@pengutronix.de>

On Wed, Aug 12, 2015 at 11:37:36AM +0100, Mark Brown wrote:
> On Wed, Aug 12, 2015 at 12:12:25PM +0200, Markus Pargmann wrote:
> > Hi,
> > 
> > this series was created to add SPI support to the bmc150 accelerometer driver.
> > To not add any regressions, I had to add some infrastructure that allows to use
> > regmap with busses that do limit the size of transfers (block smbus). I hope
> > this is sufficient to not break anything.
> 
> This is a really big series but looking at at least the initial patches
> there's a lot of unrelated cleanups mixed in with it.  Please don't do
> this, send things like cleanups separately so that your series is
> focused on the relevant topic.  This makes things much easier to work
> with.

Ok. I can try to separate them but there are lots of dependencies
between the patches and most of them touch regmap.c so I thought it may
be better to put it in one series.

I will try my best to separate them for the next version.

Best Regards,

Markus

-- 
Pengutronix e.K.                           |                             |
Industrial Linux Solutions                 | http://www.pengutronix.de/  |
Peiner Str. 6-8, 31137 Hildesheim, Germany | Phone: +49-5121-206917-0    |
Amtsgericht Hildesheim, HRA 2686           | Fax:   +49-5121-206917-5555 |
-------------- next part --------------
A non-text attachment was scrubbed...
Name: signature.asc
Type: application/pgp-signature
Size: 819 bytes
Desc: Digital signature
URL: <http://lists.infradead.org/pipermail/linux-arm-kernel/attachments/20150812/22dbb89b/attachment.sig>

From bp at alien8.de  Wed Aug 12 03:49:54 2015
From: bp at alien8.de (Borislav Petkov)
Date: Wed, 12 Aug 2015 12:49:54 +0200
Subject: [PATCH v3 1/4] edac: Add an function to retrieve the EDAC
 debugfs node
In-Reply-To: <20150812101219.GC14011@nazgul.tnic>
References: <1439326077-25507-1-git-send-email-lho@apm.com>
 <1439326077-25507-2-git-send-email-lho@apm.com>
 <20150812101219.GC14011@nazgul.tnic>
Message-ID: <20150812104954.GD14011@nazgul.tnic>

On Wed, Aug 12, 2015 at 12:12:19PM +0200, Borislav Petkov wrote:
> EXPORT_SYMBOL_GPL() if it is going to be used by modules.

Better yet, move it to the header.

-- 
Regards/Gruss,
    Boris.

ECO tip #101: Trim your mails when you reply.
--


From bp at alien8.de  Wed Aug 12 03:51:21 2015
From: bp at alien8.de (Borislav Petkov)
Date: Wed, 12 Aug 2015 12:51:21 +0200
Subject: [PATCH v3 3/4] edac: Add L3/SoC EDAC support to the APM X-Gene
 SoC EDAC driver
In-Reply-To: <1439326077-25507-4-git-send-email-lho@apm.com>
References: <1439326077-25507-1-git-send-email-lho@apm.com>
 <1439326077-25507-2-git-send-email-lho@apm.com>
 <1439326077-25507-3-git-send-email-lho@apm.com>
 <1439326077-25507-4-git-send-email-lho@apm.com>
Message-ID: <20150812105121.GE14011@nazgul.tnic>

On Tue, Aug 11, 2015 at 02:47:56PM -0600, Loc Ho wrote:
> This patch adds EDAC support for the L3 and SoC components.
> 
> Signed-off-by: Loc Ho <lho at apm.com>
> ---
>  drivers/edac/xgene_edac.c |  827 ++++++++++++++++++++++++++++++++++++++++++++-
>  1 files changed, 815 insertions(+), 12 deletions(-)
> 
> diff --git a/drivers/edac/xgene_edac.c b/drivers/edac/xgene_edac.c
> index ba06904..d5e33bf 100644
> --- a/drivers/edac/xgene_edac.c
> +++ b/drivers/edac/xgene_edac.c
> @@ -66,6 +66,8 @@ struct xgene_edac {
>  
>  	struct list_head	mcus;
>  	struct list_head	pmds;
> +	struct list_head	l3s;
> +	struct list_head	socs;
>  
>  	struct mutex		mc_lock;
>  	int			mc_active_mask;
> @@ -877,8 +879,8 @@ static const struct file_operations xgene_edac_pmd_debug_inject_fops[] = {
>  	{ }
>  };
>  
> -static void xgene_edac_pmd_create_debugfs_nodes(
> -	struct edac_device_ctl_info *edac_dev)
> +static void
> +xgene_edac_pmd_create_debugfs_nodes(struct edac_device_ctl_info *edac_dev)
>  {
>  	struct xgene_edac_pmd_ctx *ctx = edac_dev->pvt_info;
>  	struct dentry *edac_debugfs;
> @@ -887,10 +889,6 @@ static void xgene_edac_pmd_create_debugfs_nodes(
>  	if (!IS_ENABLED(CONFIG_EDAC_DEBUG))
>  		return;
>  
> -	/*
> -	 * Todo: Switch to common EDAC debug file system for edac device
> -	 *       when available.
> -	 */
>  	if (!ctx->edac->dfs) {
>  		ctx->edac->dfs = debugfs_create_dir(edac_dev->dev->kobj.name,
>  						    NULL);

Why is this removing only the comment and not the debugfs_create_dir()
and the rest of the gunk?

xgene_edac_l3_create_debugfs_nodes() does call debugfs_create_dir()
creating a top-level edac debugfs node too. Why?

Please go through the previous comments I had and make sure you've
incorporated them all. I'm not wasting time reviewing half-baked stuff.

-- 
Regards/Gruss,
    Boris.

ECO tip #101: Trim your mails when you reply.
--


From broonie at kernel.org  Wed Aug 12 03:54:43 2015
From: broonie at kernel.org (Mark Brown)
Date: Wed, 12 Aug 2015 11:54:43 +0100
Subject: [PATCH 05/20] regmap: Restructure writes in _regmap_raw_write()
In-Reply-To: <1439374365-20623-6-git-send-email-mpa@pengutronix.de>
References: <1439374365-20623-1-git-send-email-mpa@pengutronix.de>
 <1439374365-20623-6-git-send-email-mpa@pengutronix.de>
Message-ID: <20150812105443.GT10748@sirena.org.uk>

On Wed, Aug 12, 2015 at 12:12:30PM +0200, Markus Pargmann wrote:
> Currently we try to write the data without copying directly using
> bus->write() or bus->gather_write() if it exists. If one of the previous
> tries to write reported -ENOTSUPP or none of them were usable, we copy
> the data into a buffer and use bus->write().
> 
> However it does not make sense to try bus->write() a second time with a
> copied buffer if it didn't work the first time.
> 
> This patch restructures this if/else block to make it clear that this is
> not intended for the case where bus->write() returns -ENOTSUPP.

I'm not entirely convinced that this is an improvement.  The main effect
that I'm seeing is an increase in the indentation level and there are
potential issues with the write operation being unable to work with some
kinds of memory (like restrictions about dmaing from stack or unalinged
memory for example) which mean that copying into a newly allocated
buffer may actually help.  I don't think we detect any such restrictions
at the minute but the defensiveness is nice and I'd really hope that the
failed write case isn't any kind of fast path.
-------------- next part --------------
A non-text attachment was scrubbed...
Name: signature.asc
Type: application/pgp-signature
Size: 473 bytes
Desc: Digital signature
URL: <http://lists.infradead.org/pipermail/linux-arm-kernel/attachments/20150812/ffeed222/attachment.sig>

From tony at atomide.com  Wed Aug 12 03:56:42 2015
From: tony at atomide.com (Tony Lindgren)
Date: Wed, 12 Aug 2015 03:56:42 -0700
Subject: [PATCH] ARM: OMAP3: clock: remove un-used core dpll re-program
 code
In-Reply-To: <20150812072535.GQ4215@atomide.com>
References: <1437034091-18306-1-git-send-email-t-kristo@ti.com>
 <20150812072535.GQ4215@atomide.com>
Message-ID: <20150812105642.GW4215@atomide.com>

* Tony Lindgren <tony at atomide.com> [150812 00:29]:
> * Tero Kristo <t-kristo at ti.com> [150716 01:10]:
> > Remove the OMAP3 core DPLL re-program code, and the associated SRAM
> > code that does the low-level programming of the DPLL divider, idling
> > of the SDRAM etc.
> > 
> > This code was never fully implemented in the kernel; things missing
> > were driver side handling of core clock changes (they need to account
> > for their functional clock rate being changed on-the-fly), and the whole
> > framework required for handling this. Thus, there is not much point
> > to keep carrying the low-level support code either.
> 
> OK I'm applying this into omap-for-v4.3/soc. If we ever need the code
> it will be in the git history.

Actually I'll wait on this one and apply it later on as it currently
adds merge conflicts into Linux next.

Regards,

Tony


From broonie at kernel.org  Wed Aug 12 03:57:58 2015
From: broonie at kernel.org (Mark Brown)
Date: Wed, 12 Aug 2015 11:57:58 +0100
Subject: [PATCH 02/20] regmap: Remove regmap_bulk_write 64bit support
In-Reply-To: <20150812104436.GA19600@pengutronix.de>
References: <1439374365-20623-1-git-send-email-mpa@pengutronix.de>
 <1439374365-20623-3-git-send-email-mpa@pengutronix.de>
 <20150812102550.GQ10748@sirena.org.uk>
 <20150812104436.GA19600@pengutronix.de>
Message-ID: <20150812105758.GU10748@sirena.org.uk>

On Wed, Aug 12, 2015 at 12:44:36PM +0200, Markus Pargmann wrote:

> I wasn't aware that any 64 bit architecture actually has unsigned ints
> that are 64 bit in size. So wouldn't at least on x86_64 this would lead
> to a compiler warning as unsigned int is 4 byte and u64 8 bytes?

Nobody complained about warnings yet.  The compiler probably shouldn't
be complaining given the casts, they're supposed to be an "I know what
I'm doing" thing.  If you want to change something here it's changing
the test to be based on sizeof(unsigned int).
-------------- next part --------------
A non-text attachment was scrubbed...
Name: signature.asc
Type: application/pgp-signature
Size: 473 bytes
Desc: Digital signature
URL: <http://lists.infradead.org/pipermail/linux-arm-kernel/attachments/20150812/a6280ed6/attachment.sig>

From viresh.kumar at linaro.org  Wed Aug 12 04:08:41 2015
From: viresh.kumar at linaro.org (Viresh Kumar)
Date: Wed, 12 Aug 2015 16:38:41 +0530
Subject: [PATCH v4 2/2] dt: power: st: Provide bindings for ST's OPPs
In-Reply-To: <20150811151736.GO18282@x1>
References: <20150803034642.GV899@linux> <20150810132247.GH3249@x1>
 <20150811080023.GB5509@linux> <20150811093039.GA18282@x1>
 <20150811100941.GG5509@linux> <20150811115425.GE18282@x1>
 <20150811120124.GH5509@linux> <20150811132756.GG18282@x1>
 <20150811142812.GJ5509@linux> <20150811151736.GO18282@x1>
Message-ID: <20150812110841.GC20238@linux>

On 11-08-15, 16:17, Lee Jones wrote:
> This would work if we only had a single variable to contend with, but
> what I showed you in my previous example is that we have 3 variables
> to consider; cut (version), pcode and substrate.
> 
> Using the two (simple) examples I provided, how would your suggestion
> look in our case?

So the solution I gave is for picking the microvolt based on pcode.
The other two (cut, substrate) aren't about picking microvolt, but if
the OPP is available or not. Right?

If these terms are generic enough, then we can add something similar
to what you have added..

@Stephen ?

-- 
viresh


From broonie at kernel.org  Wed Aug 12 04:10:31 2015
From: broonie at kernel.org (Mark Brown)
Date: Wed, 12 Aug 2015 12:10:31 +0100
Subject: [PATCH 06/20] regmap: Fix regmap_bulk_write for bus writes
In-Reply-To: <1439374365-20623-7-git-send-email-mpa@pengutronix.de>
References: <1439374365-20623-1-git-send-email-mpa@pengutronix.de>
 <1439374365-20623-7-git-send-email-mpa@pengutronix.de>
Message-ID: <20150812111031.GV10748@sirena.org.uk>

On Wed, Aug 12, 2015 at 12:12:31PM +0200, Markus Pargmann wrote:

> Cc: Stephen Boyd <sboyd at codeaurora.org>

I'm not sure why you're putting this in these commit messages...

>  	if (!map->bus || map->use_single_rw) {
> +		if (val_bytes != 1 && val_bytes != 2 && val_bytes != 4)
> +			return -EINVAL;
> +

switch statement please.  This also looks like a separate change to the
handling of single writes.

> +	} else if (map->use_single_rw) {
> +		/*

How are we ever going to fall into this else case?  The first check has
an || map->use_single_rw it so if this is true then the first check will
be too so we'd never end up in this else case.
-------------- next part --------------
A non-text attachment was scrubbed...
Name: signature.asc
Type: application/pgp-signature
Size: 473 bytes
Desc: Digital signature
URL: <http://lists.infradead.org/pipermail/linux-arm-kernel/attachments/20150812/6c5fa1df/attachment.sig>

From broonie at kernel.org  Wed Aug 12 04:13:24 2015
From: broonie at kernel.org (Mark Brown)
Date: Wed, 12 Aug 2015 12:13:24 +0100
Subject: [PATCH 07/20] regmap: Without bus read() or write(), force
 use_single_rw
In-Reply-To: <1439374365-20623-8-git-send-email-mpa@pengutronix.de>
References: <1439374365-20623-1-git-send-email-mpa@pengutronix.de>
 <1439374365-20623-8-git-send-email-mpa@pengutronix.de>
Message-ID: <20150812111324.GW10748@sirena.org.uk>

On Wed, Aug 12, 2015 at 12:12:32PM +0200, Markus Pargmann wrote:
> The implementation of regmap bus read() and write() methods are
> optional. Therefore we have to handle busses which do not have these
> functions. If raw read() and write() is not supported we have to use
> reg_read and reg_write always.
> 
> This patch sets use_single_rw if read() or write() is not set.

> -	map->use_single_rw = config->use_single_rw;
> +	map->use_single_rw = config->use_single_rw || !bus->read || !bus->write;

This doesn't follow, we should be able to support write only or read
only buses.  There are some out there.
-------------- next part --------------
A non-text attachment was scrubbed...
Name: signature.asc
Type: application/pgp-signature
Size: 473 bytes
Desc: Digital signature
URL: <http://lists.infradead.org/pipermail/linux-arm-kernel/attachments/20150812/cf8e2b54/attachment-0001.sig>

From broonie at kernel.org  Wed Aug 12 04:20:35 2015
From: broonie at kernel.org (Mark Brown)
Date: Wed, 12 Aug 2015 12:20:35 +0100
Subject: [PATCH 09/20] regmap: _regmap_raw_write fix for busses without
 write()
In-Reply-To: <1439374365-20623-10-git-send-email-mpa@pengutronix.de>
References: <1439374365-20623-1-git-send-email-mpa@pengutronix.de>
 <1439374365-20623-10-git-send-email-mpa@pengutronix.de>
Message-ID: <20150812112035.GX10748@sirena.org.uk>

On Wed, Aug 12, 2015 at 12:12:34PM +0200, Markus Pargmann wrote:

> @@ -1229,6 +1229,11 @@ int _regmap_raw_write(struct regmap *map, unsigned int reg,
>  		}
>  	}
>  
> +	if (!map->bus->write && val_len == map->format.val_bytes) {
> +		ret = _regmap_bus_reg_write(map, reg, *(unsigned int *)val);
> +		return ret;
> +	}

This is broken - you can't use a raw value as a register value.  The
endianness of the device may not be the same as the endianness of the
system and you can't cast a value to unsigned int, the value may be of
any size.

> @@ -1340,7 +1345,7 @@ int _regmap_raw_write(struct regmap *map, unsigned int reg,
>  	 * send the work_buf directly, otherwise try to do a gather
>  	 * write.
>  	 */
> -	if (val == work_val) {
> +	if (val == work_val && map->bus->write) {
>  		ret = map->bus->write(map->bus_context, map->work_buf,
>  				      map->format.reg_bytes +
>  				      map->format.pad_bytes +

This appears to be another case of merging an unrelated change :(
-------------- next part --------------
A non-text attachment was scrubbed...
Name: signature.asc
Type: application/pgp-signature
Size: 473 bytes
Desc: Digital signature
URL: <http://lists.infradead.org/pipermail/linux-arm-kernel/attachments/20150812/42cd50dd/attachment.sig>

From lorenzo.pieralisi at arm.com  Wed Aug 12 04:24:28 2015
From: lorenzo.pieralisi at arm.com (Lorenzo Pieralisi)
Date: Wed, 12 Aug 2015 12:24:28 +0100
Subject: [PATCH v5 6/9] PCI: Drop references acquired by of_parse_phandle()
In-Reply-To: <20150804215435.9189.94410.stgit@bhelgaas-glaptop2.roam.corp.google.com>
References: <20150804214234.9189.42548.stgit@bhelgaas-glaptop2.roam.corp.google.com>
 <20150804215435.9189.94410.stgit@bhelgaas-glaptop2.roam.corp.google.com>
Message-ID: <20150812112428.GC5674@e107981-lin.cambridge.arm.com>

On Tue, Aug 04, 2015 at 10:54:35PM +0100, Bjorn Helgaas wrote:
> of_parse_phandle() returns a device_node pointer with the refcount
> incremented.  We should dispose of this reference when we're finished.
> 
> Drop the reference acquired by of_parse_phandle().
> 
> Signed-off-by: Bjorn Helgaas <bhelgaas at google.com>
> ---
>  drivers/pci/host/pci-mvebu.c |    1 +
>  drivers/pci/host/pci-xgene.c |    1 +
>  2 files changed, 2 insertions(+)

It looks fine to me:

Reviewed-by: Lorenzo Pieralisi <lorenzo.pieralisi at arm.com>

> diff --git a/drivers/pci/host/pci-mvebu.c b/drivers/pci/host/pci-mvebu.c
> index 70aa095..67ec5e1 100644
> --- a/drivers/pci/host/pci-mvebu.c
> +++ b/drivers/pci/host/pci-mvebu.c
> @@ -879,6 +879,7 @@ static void mvebu_pcie_msi_enable(struct mvebu_pcie *pcie)
>  		return;
>  
>  	pcie->msi = of_pci_find_msi_chip_by_node(msi_node);
> +	of_node_put(msi_node);
>  
>  	if (pcie->msi)
>  		pcie->msi->dev = &pcie->pdev->dev;
> diff --git a/drivers/pci/host/pci-xgene.c b/drivers/pci/host/pci-xgene.c
> index a9dfb70..4c2fb1f 100644
> --- a/drivers/pci/host/pci-xgene.c
> +++ b/drivers/pci/host/pci-xgene.c
> @@ -514,6 +514,7 @@ static int xgene_pcie_msi_enable(struct pci_bus *bus)
>  	if (!bus->msi)
>  		return -ENODEV;
>  
> +	of_node_put(msi_node);
>  	bus->msi->dev = &bus->dev;
>  	return 0;
>  }
> 


From broonie at kernel.org  Wed Aug 12 04:27:07 2015
From: broonie at kernel.org (Mark Brown)
Date: Wed, 12 Aug 2015 12:27:07 +0100
Subject: [PATCH 11/20] regmap: _regmap_raw_read: Add handling of busses
 without bus->read()
In-Reply-To: <1439374365-20623-12-git-send-email-mpa@pengutronix.de>
References: <1439374365-20623-1-git-send-email-mpa@pengutronix.de>
 <1439374365-20623-12-git-send-email-mpa@pengutronix.de>
Message-ID: <20150812112707.GY10748@sirena.org.uk>

On Wed, Aug 12, 2015 at 12:12:36PM +0200, Markus Pargmann wrote:

> +	/*
> +	 * There are busses that do not have a read function as it is optional.
> +	 * Use their reg_read function instead if the requested number of bytes
> +	 * is correct.
> +	 */
> +	if (!map->bus->read) {
> +		/*
> +		 * bus_reg_read() does not support reading values that are not
> +		 * exactly the size of format.val_bytes
> +		 */
> +		if (val_len != map->format.val_bytes)
> +			return -EINVAL;
> +		return _regmap_bus_reg_read(map, reg, val);
> +	}

No, this makes no sense - if the device doesn't have a read operation
then it doesn't support a raw data stream and hence can't support raw
access sensibly.  Callers that want to access a lot of registers at once
without knowing what the wire format for the device is should be using
the bulk or multi interfaces.
-------------- next part --------------
A non-text attachment was scrubbed...
Name: signature.asc
Type: application/pgp-signature
Size: 473 bytes
Desc: Digital signature
URL: <http://lists.infradead.org/pipermail/linux-arm-kernel/attachments/20150812/10f82529/attachment.sig>

From aballier at gentoo.org  Wed Aug 12 04:27:51 2015
From: aballier at gentoo.org (Alexis Ballier)
Date: Wed, 12 Aug 2015 13:27:51 +0200
Subject: [PATCH] ARM: dts: exynos4412-odroidu3: Enable SPI1.
Message-ID: <1439378871-28117-1-git-send-email-aballier@gentoo.org>

SPI1 is available on IO Port #2 (as depicted on their website) in
PCB Revision 0.5 of Hardkernel Odroid U3 board.
The shield connects a 256KiB spi-nor flash on that bus.

Signed-off-by: Alexis Ballier <aballier at gentoo.org>
---
 arch/arm/boot/dts/exynos4412-odroidu3.dts | 7 +++++++
 1 file changed, 7 insertions(+)

diff --git a/arch/arm/boot/dts/exynos4412-odroidu3.dts b/arch/arm/boot/dts/exynos4412-odroidu3.dts
index 44684e5..37698e4 100644
--- a/arch/arm/boot/dts/exynos4412-odroidu3.dts
+++ b/arch/arm/boot/dts/exynos4412-odroidu3.dts
@@ -61,3 +61,10 @@
 		"Speakers", "SPKL",
 		"Speakers", "SPKR";
 };
+
+&spi_1 {
+	pinctrl-names = "default";
+	pinctrl-0 = <&spi1_bus>;
+	cs-gpios = <&gpb 5 0>;
+	status = "okay";
+};
-- 
2.5.0



From maitysanchayan at gmail.com  Wed Aug 12 04:32:03 2015
From: maitysanchayan at gmail.com (maitysanchayan at gmail.com)
Date: Wed, 12 Aug 2015 17:02:03 +0530
Subject: [PATCH v8 3/4] drivers: nvmem: Add Vybrid OCOTP support
In-Reply-To: <55CB22F3.2000702@linaro.org>
References: <cover.1439214648.git.maitysanchayan@gmail.com>
 <29b527f1897b24a310a3f3acee61c721d3399503.1439214648.git.maitysanchayan@gmail.com>
 <55CB22F3.2000702@linaro.org>
Message-ID: <20150812113203.GA15470@Sanchayan-Arch.toradex.int>

Hello,

On 15-08-12 11:41:55, Srinivas Kandagatla wrote:
> Hi Sanchayan,
> 
> Please run checkpatch before you send the patch next time.
> Look at Documentation/SubmittingPatches for more details.
> 
> WARNING: line over 80 characters
> #225: FILE: drivers/nvmem/vf610-ocotp.c:174:
> +			ret = vf610_ocotp_wait_busy(ocotp->base + OCOTP_CTRL_REG);
> 
> WARNING: line over 80 characters
> #237: FILE: drivers/nvmem/vf610-ocotp.c:186:
> +			ret = vf610_ocotp_wait_busy(ocotp->base + OCOTP_CTRL_REG);
> 
> WARNING: line over 80 characters
> #244: FILE: drivers/nvmem/vf610-ocotp.c:193:
> +				writel(OCOTP_CTRL_ERROR, ocotp->base + OCOTP_CTRL_CLR);
> 

I had. However splitting these lines seemed odd. Will split and fix.

> 
> On 10/08/15 15:11, Sanchayan Maity wrote:
> > The patch adds support for the On Chip One Time Programmable Peripheral
> > (OCOTP) on the Vybrid platform.
> >
> > Signed-off-by: Sanchayan Maity <maitysanchayan at gmail.com>
> > ---
> >   drivers/nvmem/Kconfig       |  10 ++
> >   drivers/nvmem/Makefile      |   2 +
> >   drivers/nvmem/vf610-ocotp.c | 301 ++++++++++++++++++++++++++++++++++++++++++++
> >   3 files changed, 313 insertions(+)
> >   create mode 100644 drivers/nvmem/vf610-ocotp.c
> >
> > diff --git a/drivers/nvmem/Kconfig b/drivers/nvmem/Kconfig
> > index 0b33014..7af4c1d 100644
> > --- a/drivers/nvmem/Kconfig
> > +++ b/drivers/nvmem/Kconfig
> > @@ -47,4 +47,14 @@ config NVMEM_IMX_OCOTP
> >   	  This driver can also be built as a module. If so, the module
> >   	  will be called nvmem-imx-ocotp.
> >
> 
> Also please can you rebase it on top of char-misc-next?, This patch 
> would not apply as it is because of the above context.

Sure. Will rebase and send.

Thanks.

Regards,
Sanchayan.

> 
> 
> > +config NVMEM_VF610_OCOTP
> > +	tristate "VF610_SoCs OCOTP support"
> > +	depends on SOC_VF610 || COMPILE_TEST
> > +	help
> > +	  This is a driver for the 'OCOTP' peripheral available on Vybrid
> > +	  devices like VF5xx and VF6xx.
> > +
> > +	  This driver can also be built as a module. If so, the module will
> > +	  be called nvmem-vf610-ocotp.
> > +
> >   endif
> > diff --git a/drivers/nvmem/Makefile b/drivers/nvmem/Makefile
> > index b512d77..8a1eea8 100644
> > --- a/drivers/nvmem/Makefile
> > +++ b/drivers/nvmem/Makefile
> > @@ -12,3 +12,5 @@ obj-$(CONFIG_NVMEM_SUNXI_SID)	+= nvmem_sunxi_sid.o
> >   nvmem_sunxi_sid-y		:= sunxi_sid.o
> >   obj-$(CONFIG_NVMEM_IMX_OCOTP)	+= nvmem-imx-ocotp.o
> >   nvmem-imx-ocotp-y		:= imx-ocotp.o
> > +obj-$(CONFIG_NVMEM_VF610_OCOTP)	+= nvmem-vf610-ocotp.o
> > +nvmem-vf610-ocotp-y		:= vf610-ocotp.o
> > diff --git a/drivers/nvmem/vf610-ocotp.c b/drivers/nvmem/vf610-ocotp.c
> > new file mode 100644
> > index 0000000..9e18156
> > --- /dev/null
> > +++ b/drivers/nvmem/vf610-ocotp.c
> > @@ -0,0 +1,301 @@
> > +/*
> > + * Copyright (C) 2015 Toradex AG.
> > + *
> > + * Author: Sanchayan Maity <sanchayan.maity at toradex.com>
> > + *
> > + * Based on the barebox ocotp driver,
> > + * Copyright (c) 2010 Baruch Siach <baruch at tkos.co.il>
> > + *	Orex Computed Radiography
> > + *
> > + * This program is free software; you can redistribute it and/or modify
> > + * it under the terms of the GNU General Public License version 2 and
> > + * only 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/clk.h>
> > +#include <linux/delay.h>
> > +#include <linux/device.h>
> > +#include <linux/io.h>
> > +#include <linux/module.h>
> > +#include <linux/nvmem-provider.h>
> > +#include <linux/of.h>
> > +#include <linux/platform_device.h>
> > +#include <linux/regmap.h>
> > +#include <linux/slab.h>
> > +
> > +/* OCOTP Register Offsets */
> > +#define OCOTP_CTRL_REG				0x00
> > +#define OCOTP_CTRL_SET				0x04
> > +#define OCOTP_CTRL_CLR				0x08
> > +#define OCOTP_TIMING				0x10
> > +#define OCOTP_DATA				0x20
> > +#define OCOTP_READ_CTRL_REG			0x30
> > +#define OCOTP_READ_FUSE_DATA			0x40
> > +
> > +/* OCOTP Register bits and masks */
> > +#define OCOTP_CTRL_WR_UNLOCK			16
> > +#define OCOTP_CTRL_WR_UNLOCK_KEY		0x3E77
> > +#define OCOTP_CTRL_WR_UNLOCK_MASK		GENMASK(31, 16)
> > +#define OCOTP_CTRL_ADDR				0
> > +#define OCOTP_CTRL_ADDR_MASK			GENMASK(6, 0)
> > +#define OCOTP_CTRL_RELOAD_SHADOWS		BIT(10)
> > +#define OCOTP_CTRL_ERROR			BIT(9)
> > +#define OCOTP_CTRL_BUSY				BIT(8)
> > +
> > +#define OCOTP_TIMING_STROBE_READ		16
> > +#define OCOTP_TIMING_STROBE_READ_MASK		GENMASK(21, 16)
> > +#define OCOTP_TIMING_RELAX			12
> > +#define OCOTP_TIMING_RELAX_MASK			GENMASK(15, 12)
> > +#define OCOTP_TIMING_STROBE_PROG		0
> > +#define OCOTP_TIMING_STROBE_PROG_MASK		GENMASK(11, 0)
> > +
> > +#define OCOTP_READ_CTRL_READ_FUSE		0x1
> > +
> > +#define VF610_OCOTP_TIMEOUT			100000
> > +
> > +#define BF(value, field)		(((value) << field) & field##_MASK)
> > +
> > +#define DEF_RELAX				20
> > +
> > +static const int base_to_fuse_addr_mappings[][2] = {
> > +	{0x400, 0x00},
> > +	{0x410, 0x01},
> > +	{0x420, 0x02},
> > +	{0x450, 0x05},
> > +	{0x4F0, 0x0F},
> > +	{0x600, 0x20},
> > +	{0x610, 0x21},
> > +	{0x620, 0x22},
> > +	{0x630, 0x23},
> > +	{0x640, 0x24},
> > +	{0x650, 0x25},
> > +	{0x660, 0x26},
> > +	{0x670, 0x27},
> > +	{0x6F0, 0x2F},
> > +	{0x880, 0x38},
> > +	{0x890, 0x39},
> > +	{0x8A0, 0x3A},
> > +	{0x8B0, 0x3B},
> > +	{0x8C0, 0x3C},
> > +	{0x8D0, 0x3D},
> > +	{0x8E0, 0x3E},
> > +	{0x8F0, 0x3F},
> > +	{0xC80, 0x78},
> > +	{0xC90, 0x79},
> > +	{0xCA0, 0x7A},
> > +	{0xCB0, 0x7B},
> > +	{0xCC0, 0x7C},
> > +	{0xCD0, 0x7D},
> > +	{0xCE0, 0x7E},
> > +	{0xCF0, 0x7F},
> > +};
> > +
> > +struct vf610_ocotp {
> > +	void __iomem *base;
> > +	struct clk *clk;
> > +	struct device *dev;
> > +	struct nvmem_device *nvmem;
> > +	int timing;
> > +};
> > +
> > +static int vf610_ocotp_wait_busy(void __iomem *base)
> > +{
> > +	int timeout = VF610_OCOTP_TIMEOUT;
> > +
> > +	while ((readl(base) & OCOTP_CTRL_BUSY) && --timeout)
> > +		udelay(10);
> > +
> > +	if (!timeout) {
> > +		writel(OCOTP_CTRL_ERROR, base + OCOTP_CTRL_CLR);
> > +		return -ETIMEDOUT;
> > +	}
> > +
> > +	udelay(10);
> > +
> > +	return 0;
> > +}
> > +
> > +static int vf610_ocotp_calculate_timing(struct vf610_ocotp *ocotp_dev)
> > +{
> > +	u32 clk_rate;
> > +	u32 relax, strobe_read, strobe_prog;
> > +	u32 timing;
> > +
> > +	clk_rate = clk_get_rate(ocotp_dev->clk);
> > +
> > +	/* Refer section OTP read/write timing parameters in TRM */
> > +	relax = clk_rate / (1000000000 / DEF_RELAX) - 1;
> > +	strobe_prog = clk_rate / (1000000000 / 10000) + 2 * (DEF_RELAX + 1) - 1;
> > +	strobe_read = clk_rate / (1000000000 / 40) + 2 * (DEF_RELAX + 1) - 1;
> > +
> > +	timing = BF(relax, OCOTP_TIMING_RELAX);
> > +	timing |= BF(strobe_read, OCOTP_TIMING_STROBE_READ);
> > +	timing |= BF(strobe_prog, OCOTP_TIMING_STROBE_PROG);
> > +
> > +	return timing;
> > +}
> > +
> > +static int vf610_get_fuse_address(int base_addr_offset)
> > +{
> > +	int i;
> > +
> > +	for (i = 0; i < ARRAY_SIZE(base_to_fuse_addr_mappings); i++) {
> > +		if (base_to_fuse_addr_mappings[i][0] == base_addr_offset)
> > +			return base_to_fuse_addr_mappings[i][1];
> > +	}
> > +
> > +	return -EINVAL;
> > +}
> > +
> > +static int vf610_ocotp_write(void *context, const void *data, size_t count)
> > +{
> > +	return 0;
> > +}
> > +
> > +static int vf610_ocotp_read(void *context,
> > +			const void *off, size_t reg_size,
> > +			void *val, size_t val_size)
> > +{
> > +	struct vf610_ocotp *ocotp = context;
> > +	unsigned int offset = *(u32 *)off;
> > +	u32 reg, *buf = val;
> > +	int fuse_addr;
> > +	int ret;
> > +
> > +	while (val_size > 0) {
> > +		fuse_addr = vf610_get_fuse_address(offset);
> > +		if (fuse_addr > 0) {
> > +			writel(ocotp->timing, ocotp->base + OCOTP_TIMING);
> > +			ret = vf610_ocotp_wait_busy(ocotp->base + OCOTP_CTRL_REG);
> > +			if (ret)
> > +				return ret;
> > +
> > +			reg = readl(ocotp->base + OCOTP_CTRL_REG);
> > +			reg &= ~OCOTP_CTRL_ADDR_MASK;
> > +			reg &= ~OCOTP_CTRL_WR_UNLOCK_MASK;
> > +			reg |= BF(fuse_addr, OCOTP_CTRL_ADDR);
> > +			writel(reg, ocotp->base + OCOTP_CTRL_REG);
> > +
> > +			writel(OCOTP_READ_CTRL_READ_FUSE,
> > +				ocotp->base + OCOTP_READ_CTRL_REG);
> > +			ret = vf610_ocotp_wait_busy(ocotp->base + OCOTP_CTRL_REG);
> > +			if (ret)
> > +				return ret;
> > +
> > +			if (readl(ocotp->base) & OCOTP_CTRL_ERROR) {
> > +				dev_dbg(ocotp->dev, "Error reading from fuse address %x\n",
> > +					fuse_addr);
> > +				writel(OCOTP_CTRL_ERROR, ocotp->base + OCOTP_CTRL_CLR);
> > +			}
> > +
> > +			/*
> > +			 * In case of error, we do not abort and expect to read
> > +			 * 0xBADABADA as mentioned by the TRM. We just read this
> > +			 * value and return.
> > +			 */
> > +			*buf = readl(ocotp->base + OCOTP_READ_FUSE_DATA);
> > +		} else {
> > +			*buf = 0;
> > +		}
> > +
> > +		buf++;
> > +		val_size--;
> > +		offset += reg_size;
> > +	}
> > +
> > +	return 0;
> > +}
> > +
> > +static struct regmap_bus vf610_ocotp_bus = {
> > +	.read = vf610_ocotp_read,
> > +	.write = vf610_ocotp_write,
> > +	.reg_format_endian_default = REGMAP_ENDIAN_NATIVE,
> > +	.val_format_endian_default = REGMAP_ENDIAN_NATIVE,
> > +};
> > +
> > +static struct regmap_config ocotp_regmap_config = {
> > +	.reg_bits = 32,
> > +	.val_bits = 32,
> > +	.reg_stride = 4,
> > +};
> > +
> > +static struct nvmem_config ocotp_config = {
> > +	.name = "ocotp",
> > +	.owner = THIS_MODULE,
> > +};
> > +
> > +static const struct of_device_id ocotp_of_match[] = {
> > +	{ .compatible = "fsl,vf610-ocotp", },
> > +	{/* sentinel */},
> > +};
> > +MODULE_DEVICE_TABLE(of, ocotp_of_match);
> > +
> > +static int vf610_ocotp_remove(struct platform_device *pdev)
> > +{
> > +	struct vf610_ocotp *ocotp_dev = platform_get_drvdata(pdev);
> > +
> > +	return nvmem_unregister(ocotp_dev->nvmem);
> > +}
> > +
> > +static int vf610_ocotp_probe(struct platform_device *pdev)
> > +{
> > +	struct device *dev = &pdev->dev;
> > +	struct resource *res;
> > +	struct regmap *regmap;
> > +	struct vf610_ocotp *ocotp_dev;
> > +
> > +	ocotp_dev = devm_kzalloc(&pdev->dev,
> > +			sizeof(struct vf610_ocotp), GFP_KERNEL);
> > +	if (!ocotp_dev)
> > +		return -ENOMEM;
> > +
> > +	res = platform_get_resource(pdev, IORESOURCE_MEM, 0);
> > +	ocotp_dev->base = devm_ioremap_resource(dev, res);
> > +	if (IS_ERR(ocotp_dev->base))
> > +		return PTR_ERR(ocotp_dev->base);
> > +
> > +	ocotp_dev->clk = devm_clk_get(dev, "ocotp");
> > +	if (IS_ERR(ocotp_dev->clk)) {
> > +		dev_err(dev, "failed getting clock, err = %ld\n",
> > +			PTR_ERR(ocotp_dev->clk));
> > +		return PTR_ERR(ocotp_dev->clk);
> > +	}
> > +
> > +	ocotp_regmap_config.max_register = resource_size(res);
> > +	regmap = devm_regmap_init(dev,
> > +		&vf610_ocotp_bus, ocotp_dev, &ocotp_regmap_config);
> > +	if (IS_ERR(regmap)) {
> > +		dev_err(dev, "regmap init failed\n");
> > +		return PTR_ERR(regmap);
> > +	}
> > +	ocotp_config.dev = dev;
> > +
> > +	ocotp_dev->nvmem = nvmem_register(&ocotp_config);
> > +	if (IS_ERR(ocotp_dev->nvmem))
> > +		return PTR_ERR(ocotp_dev->nvmem);
> > +
> > +	ocotp_dev->dev = dev;
> > +	platform_set_drvdata(pdev, ocotp_dev);
> > +
> > +	ocotp_dev->timing = vf610_ocotp_calculate_timing(ocotp_dev);
> > +
> > +	return 0;
> > +}
> > +
> > +static struct platform_driver vf610_ocotp_driver = {
> > +	.probe = vf610_ocotp_probe,
> > +	.remove = vf610_ocotp_remove,
> > +	.driver = {
> > +		.name = "vf610-ocotp",
> > +		.of_match_table = ocotp_of_match,
> > +	},
> > +};
> > +module_platform_driver(vf610_ocotp_driver);
> > +MODULE_AUTHOR("Sanchayan Maity <sanchayan.maity at toradex.com>");
> > +MODULE_DESCRIPTION("Vybrid OCOTP driver");
> > +MODULE_LICENSE("GPL v2");
> >


From srinivas.kandagatla at linaro.org  Wed Aug 12 04:41:31 2015
From: srinivas.kandagatla at linaro.org (Srinivas Kandagatla)
Date: Wed, 12 Aug 2015 12:41:31 +0100
Subject: [PATCH v8 3/4] drivers: nvmem: Add Vybrid OCOTP support
In-Reply-To: <20150812113203.GA15470@Sanchayan-Arch.toradex.int>
References: <cover.1439214648.git.maitysanchayan@gmail.com>
 <29b527f1897b24a310a3f3acee61c721d3399503.1439214648.git.maitysanchayan@gmail.com>
 <55CB22F3.2000702@linaro.org>
 <20150812113203.GA15470@Sanchayan-Arch.toradex.int>
Message-ID: <55CB30EB.3050006@linaro.org>



On 12/08/15 12:32, maitysanchayan at gmail.com wrote:
> Hello,
>
> On 15-08-12 11:41:55, Srinivas Kandagatla wrote:
>> >Hi Sanchayan,
>> >
>> >Please run checkpatch before you send the patch next time.
>> >Look at Documentation/SubmittingPatches for more details.
>> >
>> >WARNING: line over 80 characters
>> >#225: FILE: drivers/nvmem/vf610-ocotp.c:174:
>> >+			ret = vf610_ocotp_wait_busy(ocotp->base + OCOTP_CTRL_REG);
>> >
>> >WARNING: line over 80 characters
>> >#237: FILE: drivers/nvmem/vf610-ocotp.c:186:
>> >+			ret = vf610_ocotp_wait_busy(ocotp->base + OCOTP_CTRL_REG);
>> >
>> >WARNING: line over 80 characters
>> >#244: FILE: drivers/nvmem/vf610-ocotp.c:193:
>> >+				writel(OCOTP_CTRL_ERROR, ocotp->base + OCOTP_CTRL_CLR);
>> >
> I had. However splitting these lines seemed odd. Will split and fix.
>
Just get the base to a local variable, which should make it look neat 
and this will avoid de-referencing the octop in the all the time in loop.

--srini


From alexandre.belloni at free-electrons.com  Wed Aug 12 04:42:56 2015
From: alexandre.belloni at free-electrons.com (Alexandre Belloni)
Date: Wed, 12 Aug 2015 13:42:56 +0200
Subject: [PATCH V1 Resend 06/10] drivers: rtc: Drop (un)likely before
 IS_ERR(_OR_NULL)
In-Reply-To: <20150812104625.GB20238@linux>
References: <cover.1439375087.git.viresh.kumar@linaro.org>
 <1a92f2e1af5309ece9736f79f312e90486a98825.1439375087.git.viresh.kumar@linaro.org>
 <20150812104133.GE3411@piout.net> <20150812104625.GB20238@linux>
Message-ID: <20150812114256.GF3411@piout.net>

On 12/08/2015 at 16:16:25 +0530, Viresh Kumar wrote :
> On 12-08-15, 12:41, Alexandre Belloni wrote:
> > Hi Viresh,
> > 
> > Why are you resending?
> 
> I never got a reply from Andrew Morton on V1, so resent it again. And
> today Andrew asked me to take this via trivial tree.
> 
> So the resent.
> 
> I need to find a sane way to get few more people to the cover-letter.
> The problem is that I am generating the cc-list with get_maintainers,
> and if I combine that list for all the patches, it becomes huge. And
> really can't send the cover-letter to those people then. Few lists may
> block it as well, due to high number of cc'd people.
> 
> I am telling this because, the cover-letter did contain the reason for
> resend.
> 

The fact is that I sent you a mail yesterday stating that I applied that
particular patch.

-- 
Alexandre Belloni, Free Electrons
Embedded Linux, Kernel and Android engineering
http://free-electrons.com


From christoffer.dall at linaro.org  Wed Aug 12 04:45:43 2015
From: christoffer.dall at linaro.org (Christoffer Dall)
Date: Wed, 12 Aug 2015 13:45:43 +0200
Subject: [PATCH v4 06/11] KVM: arm/arm64: vgic: Allow dynamic mapping of
 physical/virtual interrupts
In-Reply-To: <20150812105638.67de9423@arm.com>
References: <1438962347-17541-1-git-send-email-marc.zyngier@arm.com>
 <1438962347-17541-7-git-send-email-marc.zyngier@arm.com>
 <20150811074221.GC5007@lvm> <20150812105638.67de9423@arm.com>
Message-ID: <20150812114543.GA15085@cbox>

On Wed, Aug 12, 2015 at 10:56:38AM +0100, Marc Zyngier wrote:
> On Tue, 11 Aug 2015 08:42:37 +0100
> Christoffer Dall <christoffer.dall at linaro.org> wrote:
> 
> > On Fri, Aug 07, 2015 at 04:45:42PM +0100, Marc Zyngier wrote:
> > > In order to be able to feed physical interrupts to a guest, we need
> > > to be able to establish the virtual-physical mapping between the two
> > > worlds.
> > > 
> > > The mappings are kept in a set of RCU lists, indexed by virtual interrupts.
> > > 
> > > Signed-off-by: Marc Zyngier <marc.zyngier at arm.com>
> > 
> > Thanks for addressing all my concerns:
> > 
> > Reviewed-by: Christoffer Dall <christoffer.dall at linaro.org>
> 
> Thanks a lot for all the reviewing, much appreciated.
> 
> Unless someone has an objection, I'm going put this series (minus
> the last patch) into -next so it gets a bit more exposure.
> 

Sounds good to me, when I'm back from this paper writing business
tomorrow/friday, I'll give it a spin and test the UEFI reboot issue with
it as well.

-Christoffer


From viresh.kumar at linaro.org  Wed Aug 12 04:47:32 2015
From: viresh.kumar at linaro.org (Viresh Kumar)
Date: Wed, 12 Aug 2015 17:17:32 +0530
Subject: [PATCH V1 Resend 06/10] drivers: rtc: Drop (un)likely before
 IS_ERR(_OR_NULL)
In-Reply-To: <20150812114256.GF3411@piout.net>
References: <cover.1439375087.git.viresh.kumar@linaro.org>
 <1a92f2e1af5309ece9736f79f312e90486a98825.1439375087.git.viresh.kumar@linaro.org>
 <20150812104133.GE3411@piout.net> <20150812104625.GB20238@linux>
 <20150812114256.GF3411@piout.net>
Message-ID: <20150812114732.GE20238@linux>

On 12-08-15, 13:42, Alexandre Belloni wrote:
> The fact is that I sent you a mail yesterday stating that I applied that
> particular patch.

Urg ..

I looked at the 'V1 Resend' series to see which all are applied, and
missed your reply on the first version.

Sorry about that.

-- 
viresh


From broonie at kernel.org  Wed Aug 12 04:49:31 2015
From: broonie at kernel.org (Mark Brown)
Date: Wed, 12 Aug 2015 12:49:31 +0100
Subject: [PATCH 12/20] regmap: Introduce max_raw_io for
 regmap_bulk_read/write
In-Reply-To: <1439374365-20623-13-git-send-email-mpa@pengutronix.de>
References: <1439374365-20623-1-git-send-email-mpa@pengutronix.de>
 <1439374365-20623-13-git-send-email-mpa@pengutronix.de>
Message-ID: <20150812114931.GZ10748@sirena.org.uk>

On Wed, Aug 12, 2015 at 12:12:37PM +0200, Markus Pargmann wrote:

> +	/* if set, raw reads/writes are limited to this size */
> +	size_t max_raw_io;
> +

Do this separately for read and write, there's doubtless going to be
something that has asymmetry.

> +		if (!map->use_single_rw) {
> +			write_count = total_bytes / map->max_raw_io;
> +			write_bytes = map->max_raw_io;

We may not be able to fit a whole number of values into whatever the
constraint that the bus has is and partial values don't seem like a good
idea.

> +			reg_stride *= write_bytes / val_bytes;
> +		}

This is very confusing, regmap already has a concept of stride and this
isn't the same thing.
-------------- next part --------------
A non-text attachment was scrubbed...
Name: signature.asc
Type: application/pgp-signature
Size: 473 bytes
Desc: Digital signature
URL: <http://lists.infradead.org/pipermail/linux-arm-kernel/attachments/20150812/c337ed3f/attachment.sig>

From broonie at kernel.org  Wed Aug 12 04:51:36 2015
From: broonie at kernel.org (Mark Brown)
Date: Wed, 12 Aug 2015 12:51:36 +0100
Subject: [PATCH 13/20] regmap: regmap max_raw_io getter function
In-Reply-To: <1439374365-20623-14-git-send-email-mpa@pengutronix.de>
References: <1439374365-20623-1-git-send-email-mpa@pengutronix.de>
 <1439374365-20623-14-git-send-email-mpa@pengutronix.de>
Message-ID: <20150812115136.GA10748@sirena.org.uk>

On Wed, Aug 12, 2015 at 12:12:38PM +0200, Markus Pargmann wrote:
> Signed-off-by: Markus Pargmann <mpa at pengutronix.de>

Your changelog doesn't mention why anything would reasonably want to use
this and...

> +size_t regmap_get_raw_io_max(struct regmap *map)
> +{
> +	return map->max_raw_io;
> +}
> +EXPORT_SYMBOL_GPL(regmap_get_raw_io_max);
> +
> +/**
> + * regmap_get_raw_read_max - Get the maximum size we can read
> + *
> + * @map: Map to check.
> + */

...it is adding two functions which don't seem very symmetrically named.

> @@ -441,6 +441,8 @@ int regmap_get_max_register(struct regmap *map);
>  int regmap_get_reg_stride(struct regmap *map);
>  int regmap_async_complete(struct regmap *map);
>  bool regmap_can_raw_write(struct regmap *map);
> +size_t regmap_get_raw_write_max(struct regmap *map);
> +size_t regmap_get_raw_io_max(struct regmap *map);

Do we want stubs here?
-------------- next part --------------
A non-text attachment was scrubbed...
Name: signature.asc
Type: application/pgp-signature
Size: 473 bytes
Desc: Digital signature
URL: <http://lists.infradead.org/pipermail/linux-arm-kernel/attachments/20150812/0fc84067/attachment.sig>

From oliver+list at schinagl.nl  Wed Aug 12 04:55:59 2015
From: oliver+list at schinagl.nl (Olliver Schinagl)
Date: Wed, 12 Aug 2015 13:55:59 +0200
Subject: [linux-sunxi] MMC clock gating broken on a20
In-Reply-To: <55CB3095.9050509@schinagl.nl>
References: <CAOMqctRhQHv1idY0ci6uzDxnv5oj7dbHtc4CTfo75ipXkXd1gw@mail.gmail.com>
 <55CB3095.9050509@schinagl.nl>
Message-ID: <55CB344F.6050608@schinagl.nl>

Actually, I've reverted hans's

mmc: sunxi: Don't start commands while the card is busy

and that makes it disapear as well. So it looks like that patch triggers 
the aggressiveness more?

I'll apply your patch and undo the revert to see if that fixes the root 
issue.

Olliver

On 12-08-15 13:40, Olliver Schinagl wrote:
> Hey all,
>
> I'm noticing the exact same thing using hans's sunxi-wip from a few 
> days ago.
>
> I did see a patch from you about this very issue I belive
> mmc: sunxi: fix timeout in sunxi_mmc_oclk_onoff
>
> but can't find it in any of the repo's. Has it been merged yet and did 
> that actually solve the problem eventually?
>
>
> On 24-05-15 14:37, Michal Suchanek wrote:
>> Hello,
>>
>> I tried to update the kernel on my cubieboards to something recent and
>> while the a10 cubieboard works fine the a20 one won't boot.
>>
>> Looking at the console I found that the culprit is mmc clock so I
>> disabled mmc clock gating and the board works.
>>
>> I went as far back as 3.19 and the issue is pretty much the same. The
>> difference is that with linus master the clock gating seems more
>> aggressive so the board does not even boot whereas with 3.19 it
>> crashes shortly after booting fully.
>>
>> Anyone has some idea why the clock would fail re-enabling after gated?
>>
>> Supposedly the clock was already set up by the kernel when probing 
>> the mmc.
>>
>> Thanks
>>
>> Michal
>>
>> root at sunxi-a20:~# sunxi-mmc 1c0f000.mmc: fatal err update clk timeout
>> mmcblk0: error -5 requesting status
>> blk_update_request: I/O error, dev mmcblk0, sector 2048
>> Buffer I/O error on dev mmcblk0p1, logical block 0, lost async page 
>> write
>> blk_update_request: I/O error, dev mmcblk0, sector 2056
>> Buffer I/O error on dev mmcblk0p1, logical block 1, lost async page 
>> write
>> mmcblk0: error -5 sending status command, retrying
>> mmcblk0: error -5 sending status command, retrying
>> mmcblk0: error -5 sending status command, aborting
>> blk_update_request: I/O error, dev mmcblk0, sector 6776
>> Buffer I/O error on dev mmcblk0p1, logical block 591, lost async page 
>> write
>> mmcblk0: error -5 sending status command, retrying
>> mmcblk0: error -5 sending status command, retrying
>> mmcblk0: error -5 sending status command, aborting
>>
>



From broonie at kernel.org  Wed Aug 12 04:57:59 2015
From: broonie at kernel.org (Mark Brown)
Date: Wed, 12 Aug 2015 12:57:59 +0100
Subject: [PATCH 14/20] regmap: Add raw_write/read checks for
 max_raw_write/read sizes
In-Reply-To: <1439374365-20623-15-git-send-email-mpa@pengutronix.de>
References: <1439374365-20623-1-git-send-email-mpa@pengutronix.de>
 <1439374365-20623-15-git-send-email-mpa@pengutronix.de>
Message-ID: <20150812115759.GB10748@sirena.org.uk>

On Wed, Aug 12, 2015 at 12:12:39PM +0200, Markus Pargmann wrote:

> Check in regmap_raw_read() and regmap_raw_write() for correct maximum
> sizes of the operations. Return -E2BIG if this size is not supported
> because it is too big.

Why not just split the transaction up like your other changes did?

> Also this patch causes an uninitialized variable warning so it
> initializes ret (although not necessary).

That's just shutting the warning up without understanding where it came
from or why this is a good way of handling it :(

> @@ -2273,8 +2276,14 @@ int regmap_raw_read(struct regmap *map, unsigned int reg, void *val,
>  
>  	map->lock(map->lock_arg);
>  
> -	if (regmap_volatile_range(map, reg, val_count) || map->cache_bypass ||
> -	    map->cache_type == REGCACHE_NONE) {
> +	if (map->bus->read &&

This change doesn't match your commit log...
-------------- next part --------------
A non-text attachment was scrubbed...
Name: signature.asc
Type: application/pgp-signature
Size: 473 bytes
Desc: Digital signature
URL: <http://lists.infradead.org/pipermail/linux-arm-kernel/attachments/20150812/7c830a6d/attachment.sig>

From broonie at kernel.org  Wed Aug 12 04:59:37 2015
From: broonie at kernel.org (Mark Brown)
Date: Wed, 12 Aug 2015 12:59:37 +0100
Subject: [PATCH 15/20] regmap-i2c: Add smbus i2c block support
In-Reply-To: <1439374365-20623-16-git-send-email-mpa@pengutronix.de>
References: <1439374365-20623-1-git-send-email-mpa@pengutronix.de>
 <1439374365-20623-16-git-send-email-mpa@pengutronix.de>
Message-ID: <20150812115936.GC10748@sirena.org.uk>

On Wed, Aug 12, 2015 at 12:12:40PM +0200, Markus Pargmann wrote:

> +	if (count < 1 || count >= I2C_SMBUS_BLOCK_MAX)
> +		return -EINVAL;

Elsewhere you added returns of -E2BIG if the transfer was too big, why
not do that here as well?
-------------- next part --------------
A non-text attachment was scrubbed...
Name: signature.asc
Type: application/pgp-signature
Size: 473 bytes
Desc: Digital signature
URL: <http://lists.infradead.org/pipermail/linux-arm-kernel/attachments/20150812/ccefdfa7/attachment.sig>

From broonie at kernel.org  Wed Aug 12 05:01:46 2015
From: broonie at kernel.org (Mark Brown)
Date: Wed, 12 Aug 2015 13:01:46 +0100
Subject: [PATCH 17/20] iio: bmc150: Use i2c regmap
In-Reply-To: <1439374365-20623-18-git-send-email-mpa@pengutronix.de>
References: <1439374365-20623-1-git-send-email-mpa@pengutronix.de>
 <1439374365-20623-18-git-send-email-mpa@pengutronix.de>
Message-ID: <20150812120146.GD10748@sirena.org.uk>

On Wed, Aug 12, 2015 at 12:12:42PM +0200, Markus Pargmann wrote:

> +	select REGMAP
> +	select REGMAP_I2C

You don't need to select regmap, only REGMAP_I2C.
-------------- next part --------------
A non-text attachment was scrubbed...
Name: signature.asc
Type: application/pgp-signature
Size: 473 bytes
Desc: Digital signature
URL: <http://lists.infradead.org/pipermail/linux-arm-kernel/attachments/20150812/5b88d48e/attachment.sig>

From broonie at kernel.org  Wed Aug 12 05:03:00 2015
From: broonie at kernel.org (Mark Brown)
Date: Wed, 12 Aug 2015 13:03:00 +0100
Subject: [PATCH 20/20] iio: bmc150: Add SPI driver
In-Reply-To: <1439374365-20623-21-git-send-email-mpa@pengutronix.de>
References: <1439374365-20623-1-git-send-email-mpa@pengutronix.de>
 <1439374365-20623-21-git-send-email-mpa@pengutronix.de>
Message-ID: <20150812120300.GE10748@sirena.org.uk>

On Wed, Aug 12, 2015 at 12:12:45PM +0200, Markus Pargmann wrote:

> +	.use_single_rw = false,
> +	.cache_type = REGCACHE_NONE,
> +};

No need to initialise defaults.
-------------- next part --------------
A non-text attachment was scrubbed...
Name: signature.asc
Type: application/pgp-signature
Size: 473 bytes
Desc: Digital signature
URL: <http://lists.infradead.org/pipermail/linux-arm-kernel/attachments/20150812/f0330e21/attachment.sig>

From mpa at pengutronix.de  Wed Aug 12 05:07:09 2015
From: mpa at pengutronix.de (Markus Pargmann)
Date: Wed, 12 Aug 2015 14:07:09 +0200
Subject: [PATCH 06/20] regmap: Fix regmap_bulk_write for bus writes
In-Reply-To: <20150812111031.GV10748@sirena.org.uk>
References: <1439374365-20623-1-git-send-email-mpa@pengutronix.de>
 <1439374365-20623-7-git-send-email-mpa@pengutronix.de>
 <20150812111031.GV10748@sirena.org.uk>
Message-ID: <20150812120709.GD19600@pengutronix.de>

On Wed, Aug 12, 2015 at 12:10:31PM +0100, Mark Brown wrote:
> On Wed, Aug 12, 2015 at 12:12:31PM +0200, Markus Pargmann wrote:
> 
> > Cc: Stephen Boyd <sboyd at codeaurora.org>
> 
> I'm not sure why you're putting this in these commit messages...

Just to not forget that Stephen should be in Cc as he introduced the
switch case which removed the code that I add here again:
	f4298360a5c2 (regmap: Allow regmap_bulk_write() to work for "no-bus" regmaps)

> 
> >  	if (!map->bus || map->use_single_rw) {
> > +		if (val_bytes != 1 && val_bytes != 2 && val_bytes != 4)
> > +			return -EINVAL;
> > +
> 
> switch statement please.  This also looks like a separate change to the
> handling of single writes.

Sorry this was a left-over of a previous arrangement. Will remove it.

> 
> > +	} else if (map->use_single_rw) {
> > +		/*
> 
> How are we ever going to fall into this else case?  The first check has
> an || map->use_single_rw it so if this is true then the first check will
> be too so we'd never end up in this else case.

Oh right, seems like another leftover of rebases :-/ sorry. The above
condition should just be
 	if (!map->bus) {

Otherwise we fall into to this second case which is also able to handle
for example 3 byte values.

Thanks,

Markus

-- 
Pengutronix e.K.                           |                             |
Industrial Linux Solutions                 | http://www.pengutronix.de/  |
Peiner Str. 6-8, 31137 Hildesheim, Germany | Phone: +49-5121-206917-0    |
Amtsgericht Hildesheim, HRA 2686           | Fax:   +49-5121-206917-5555 |
-------------- next part --------------
A non-text attachment was scrubbed...
Name: signature.asc
Type: application/pgp-signature
Size: 819 bytes
Desc: Digital signature
URL: <http://lists.infradead.org/pipermail/linux-arm-kernel/attachments/20150812/5ca1592e/attachment.sig>

From ryabinin.a.a at gmail.com  Wed Aug 12 05:19:03 2015
From: ryabinin.a.a at gmail.com (Andrey Ryabinin)
Date: Wed, 12 Aug 2015 15:19:03 +0300
Subject: [PATCH v5 2/6] x86/kasan,
 mm: introduce generic kasan_populate_zero_shadow()
In-Reply-To: <20150812093701.GH22485@arm.com>
References: <1439259499-13913-1-git-send-email-ryabinin.a.a@gmail.com>
 <1439259499-13913-3-git-send-email-ryabinin.a.a@gmail.com>
 <20150811154117.GH23307@e104818-lin.cambridge.arm.com>
 <55CA21E8.2060704@gmail.com>
 <20150811164010.GJ23307@e104818-lin.cambridge.arm.com>
 <CAPAsAGwDNpRBLAvyCSpR9ZO9tAmHx-XYjVDZPECeQkU0WOw5jg@mail.gmail.com>
 <20150812093701.GH22485@arm.com>
Message-ID: <CAPAsAGwnhnqJCh=sc97-=qrYHNQnDSjVR-xGertoMiNWHDbhrw@mail.gmail.com>

2015-08-12 12:37 GMT+03:00 Will Deacon <will.deacon at arm.com>:
> On Wed, Aug 12, 2015 at 10:30:37AM +0100, Andrey Ryabinin wrote:
>> 2015-08-11 19:40 GMT+03:00 Catalin Marinas <catalin.marinas at arm.com>:
>> >
>> > Not sure how you plan to merge it though since there are x86
>> > dependencies. I could send the whole series via tip or the mm tree (and
>> > I guess it's pretty late for 4.3).
>>
>> Via mm tree, I guess.
>> If this is too late for 4.3, then I'll update changelog and send v6
>> after 4.3-rc1 release.
>
> That's probably the best bet, as I suspect we'll get some non-trivial
> conflicts with the arm64 tree at this stage.
>
> Will

Or, if x86 maintainers are agree to take first 2 patches in 4.3,
the rest of the series could go into arm64 tree later.


From mpa at pengutronix.de  Wed Aug 12 05:20:11 2015
From: mpa at pengutronix.de (Markus Pargmann)
Date: Wed, 12 Aug 2015 14:20:11 +0200
Subject: [PATCH 09/20] regmap: _regmap_raw_write fix for busses without
 write()
In-Reply-To: <20150812112035.GX10748@sirena.org.uk>
References: <1439374365-20623-1-git-send-email-mpa@pengutronix.de>
 <1439374365-20623-10-git-send-email-mpa@pengutronix.de>
 <20150812112035.GX10748@sirena.org.uk>
Message-ID: <20150812122011.GE19600@pengutronix.de>

On Wed, Aug 12, 2015 at 12:20:35PM +0100, Mark Brown wrote:
> On Wed, Aug 12, 2015 at 12:12:34PM +0200, Markus Pargmann wrote:
> 
> > @@ -1229,6 +1229,11 @@ int _regmap_raw_write(struct regmap *map, unsigned int reg,
> >  		}
> >  	}
> >  
> > +	if (!map->bus->write && val_len == map->format.val_bytes) {
> > +		ret = _regmap_bus_reg_write(map, reg, *(unsigned int *)val);
> > +		return ret;
> > +	}
> 
> This is broken - you can't use a raw value as a register value.  The

I am not sure what you mean here?

The register value given to _regmap_raw_write is the real register
value, not formatted differenty. This is given directly towards
bus->reg_write() which should handle the rest.

At least that's how I understood the code. For example regmap_read()
directly calls _regmap_read() which in turn calls directly
bus->reg_read() without any formating.

> endianness of the device may not be the same as the endianness of the
> system and you can't cast a value to unsigned int, the value may be of
> any size.

Yes right. On the other hand if bus->read() and bus->write() was not set
in the init method (before this patch series) no formatting functions at
all were assigned. So it was always ignored for bus->reg_read() and
bus->reg_write()?!

> 
> > @@ -1340,7 +1345,7 @@ int _regmap_raw_write(struct regmap *map, unsigned int reg,
> >  	 * send the work_buf directly, otherwise try to do a gather
> >  	 * write.
> >  	 */
> > -	if (val == work_val) {
> > +	if (val == work_val && map->bus->write) {
> >  		ret = map->bus->write(map->bus_context, map->work_buf,
> >  				      map->format.reg_bytes +
> >  				      map->format.pad_bytes +
> 
> This appears to be another case of merging an unrelated change :(

Yes, will fix.

Thanks,

Markus

-- 
Pengutronix e.K.                           |                             |
Industrial Linux Solutions                 | http://www.pengutronix.de/  |
Peiner Str. 6-8, 31137 Hildesheim, Germany | Phone: +49-5121-206917-0    |
Amtsgericht Hildesheim, HRA 2686           | Fax:   +49-5121-206917-5555 |
-------------- next part --------------
A non-text attachment was scrubbed...
Name: signature.asc
Type: application/pgp-signature
Size: 819 bytes
Desc: Digital signature
URL: <http://lists.infradead.org/pipermail/linux-arm-kernel/attachments/20150812/ac1570c7/attachment-0001.sig>

From hdegoede at redhat.com  Wed Aug 12 05:22:00 2015
From: hdegoede at redhat.com (Hans de Goede)
Date: Wed, 12 Aug 2015 14:22:00 +0200
Subject: [PATCH v3 4/4] power: Add an axp20x-usb-power driver
In-Reply-To: <20150724151020.GH27569@earth>
References: <1435316357-26606-1-git-send-email-hdegoede@redhat.com>
 <1435316357-26606-4-git-send-email-hdegoede@redhat.com>
 <20150724151020.GH27569@earth>
Message-ID: <55CB3A68.5080001@redhat.com>

Hi Sebastian,

On 24-07-15 17:10, Sebastian Reichel wrote:
> Hi,
>
> On Fri, Jun 26, 2015 at 12:59:17PM +0200, Hans de Goede wrote:
>> This adds a driver for the usb power_supply bits of the axp20x PMICs.
>>
>> I initially started writing my own driver, before coming aware of
>> Bruno Pr?mont's excellent earlier RFC with a driver for this.
>>
>> My driver was lacking CURRENT_MAX and VOLTAGE_MIN support Bruno's
>> drvier has, so I've copied the code for those from his driver.
>>
>> Note that the AC-power-supply and battery charger bits will need separate
>> drivers. Each one needs its own devictree child-node so that other
>> devicetree nodes can reference the right power-supply, and thus each one
>> will get its own mfd-cell / platform_device and platform-driver.
>
> Once the other comments have been taken care of, the driver looks ok
> to me.

I send out a v4 taking care of the other comments a while back, any
news on this? Anything I need todo from my side to get things moving?

Thanks & Regards,

Hans


From hramrach at gmail.com  Wed Aug 12 05:10:23 2015
From: hramrach at gmail.com (Michal Suchanek)
Date: Wed, 12 Aug 2015 14:10:23 +0200
Subject: [PATCH 0/3] misc MMC fixes
Message-ID: <cover.1439381423.git.hramrach@gmail.com>

Hello,

The first sunxi patch from this series was rejected on the basis that this clock
gating functionality is obsolete and should be eventually removed.

However, the function still exists in the current code and until removed it
should be corrected to work properly. Turning off the clock may be used for
something other than the clock gating feature, too.

The next sunxi patch is for automatic clock gating on the controller which
should replace the in-kernel mmc clock gating we have now.

I looked at dw_mmc for how this is supposed to work and it turns out it's not
exactly clean there either.

Thanks

Michal

Michal Suchanek (3):
  mmc: sunxi: fix timeout in sunxi_mmc_oclk_onoff
  mmc: dw_mmc: simplify the SDMMC_CLKEN_LOW_PWR logic
  mmc: sunxi: use controller automatic clock gating.

 drivers/mmc/host/dw_mmc.c    | 33 +++++++++++++++------------------
 drivers/mmc/host/sunxi-mmc.c | 29 +++++++++++++++++++++++++----
 2 files changed, 40 insertions(+), 22 deletions(-)

-- 
2.1.4



From hramrach at gmail.com  Wed Aug 12 05:23:10 2015
From: hramrach at gmail.com (Michal Suchanek)
Date: 12 Aug 2015 12:23:10 -0000
Subject: [PATCH 2/3] mmc: dw_mmc: simplify the SDMMC_CLKEN_LOW_PWR logic
In-Reply-To: <cover.1439381423.git.hramrach@gmail.com>
References: <cover.1439381423.git.hramrach@gmail.com>
Message-ID: <3d03bfe2c18789eefa038018467c9c63c94ae4a2.1439381423.git.hramrach@gmail.com>

The driver has open-coded test for SDIO cards. Use the mmc core provided
MMC_QUIRK_BROKEN_CLK_GATING flag instead.

As a bonus this may enable clock gating on SDIO cards that are known to
work with it.

Signed-off-by: Michal Suchanek <hramrach at gmail.com>
---
 drivers/mmc/host/dw_mmc.c | 33 +++++++++++++++------------------
 1 file changed, 15 insertions(+), 18 deletions(-)

diff --git a/drivers/mmc/host/dw_mmc.c b/drivers/mmc/host/dw_mmc.c
index 40e9d8e..3bc9fd7 100644
--- a/drivers/mmc/host/dw_mmc.c
+++ b/drivers/mmc/host/dw_mmc.c
@@ -1335,27 +1335,24 @@ static void dw_mci_init_card(struct mmc_host *mmc, struct mmc_card *card)
 	 * description of the CLKENA register we should disable low power mode
 	 * for SDIO cards if we need SDIO interrupts to work.
 	 */
-	if (mmc->caps & MMC_CAP_SDIO_IRQ) {
-		const u32 clken_low_pwr = SDMMC_CLKEN_LOW_PWR << slot->id;
-		u32 clk_en_a_old;
-		u32 clk_en_a;
+	const u32 clken_low_pwr = SDMMC_CLKEN_LOW_PWR << slot->id;
+	u32 clk_en_a_old;
+	u32 clk_en_a;
 
-		clk_en_a_old = mci_readl(host, CLKENA);
+	clk_en_a_old = mci_readl(host, CLKENA);
 
-		if (card->type == MMC_TYPE_SDIO ||
-		    card->type == MMC_TYPE_SD_COMBO) {
-			set_bit(DW_MMC_CARD_NO_LOW_PWR, &slot->flags);
-			clk_en_a = clk_en_a_old & ~clken_low_pwr;
-		} else {
-			clear_bit(DW_MMC_CARD_NO_LOW_PWR, &slot->flags);
-			clk_en_a = clk_en_a_old | clken_low_pwr;
-		}
+	if (card->quirks & MMC_QUIRK_BROKEN_CLK_GATING) {
+		set_bit(DW_MMC_CARD_NO_LOW_PWR, &slot->flags);
+		clk_en_a = clk_en_a_old & ~clken_low_pwr;
+	} else {
+		clear_bit(DW_MMC_CARD_NO_LOW_PWR, &slot->flags);
+		clk_en_a = clk_en_a_old | clken_low_pwr;
+	}
 
-		if (clk_en_a != clk_en_a_old) {
-			mci_writel(host, CLKENA, clk_en_a);
-			mci_send_cmd(slot, SDMMC_CMD_UPD_CLK |
-				     SDMMC_CMD_PRV_DAT_WAIT, 0);
-		}
+	if (clk_en_a != clk_en_a_old) {
+		mci_writel(host, CLKENA, clk_en_a);
+		mci_send_cmd(slot, SDMMC_CMD_UPD_CLK |
+				SDMMC_CMD_PRV_DAT_WAIT, 0);
 	}
 }
 
-- 
2.1.4



From hramrach at gmail.com  Wed Aug 12 05:23:11 2015
From: hramrach at gmail.com (Michal Suchanek)
Date: 12 Aug 2015 12:23:11 -0000
Subject: [PATCH 3/3] mmc: sunxi: use controller automatic clock gating.
In-Reply-To: <cover.1439381423.git.hramrach@gmail.com>
References: <cover.1439381423.git.hramrach@gmail.com>
Message-ID: <c33b221f9b622e3bad9d855a7ad1887b82827244.1439381423.git.hramrach@gmail.com>

When core does not set the MMC_QUIRK_BROKEN_CLK_GATING flag enable
automatic hardware controlled clock gating on the mmc interface.

Signed-off-by: Michal Suchanek <hramrach at gmail.com>
---
 drivers/mmc/host/sunxi-mmc.c | 7 ++++++-
 1 file changed, 6 insertions(+), 1 deletion(-)

diff --git a/drivers/mmc/host/sunxi-mmc.c b/drivers/mmc/host/sunxi-mmc.c
index f808a02..443cab5 100644
--- a/drivers/mmc/host/sunxi-mmc.c
+++ b/drivers/mmc/host/sunxi-mmc.c
@@ -601,8 +601,13 @@ static int sunxi_mmc_oclk_onoff(struct sunxi_mmc_host *host, u32 oclk_en)
 	rval = mmc_readl(host, REG_CLKCR);
 	rval &= ~(SDXC_CARD_CLOCK_ON | SDXC_LOW_POWER_ON);
 
-	if (oclk_en)
+	if (oclk_en) {
 		rval |= SDXC_CARD_CLOCK_ON;
+		if (!host->mmc->card ||
+		     !(host->mmc->card->quirks & MMC_QUIRK_BROKEN_CLK_GATING))
+
+			rval |= SDXC_LOW_POWER_ON;
+	}
 
 	start = jiffies;
 	end = start + msecs_to_jiffies(750);
-- 
2.1.4



From michal.suchanek at ruk.cuni.cz  Wed Aug 12 05:23:10 2015
From: michal.suchanek at ruk.cuni.cz (michal.suchanek at ruk.cuni.cz)
Date: 12 Aug 2015 12:23:10 -0000
Subject: [PATCH resend 1/3] mmc: sunxi: fix timeout in sunxi_mmc_oclk_onoff
In-Reply-To: <cover.1439381423.git.hramrach@gmail.com>
References: <cover.1439381423.git.hramrach@gmail.com>
Message-ID: <7f9c6f99b31702c02436ef3356b3ebffa4754260.1439381423.git.hramrach@gmail.com>

The 250ms timeout is too short.

On my system enabling the oclk takes under 50ms and disabling slightly
over 100ms when idle. Under load disabling the clock can take over
350ms.

This does not make mmc clock gating look like good option to have on
sunxi but the system should not crash with mmc clock gating enabled
nonetheless.

This patch sets the timeout to 750ms and adds debug prints which show
how long enabling/disabling the clock took so more data can be collected
from other systems.

Signed-off-by: Michal Suchanek <hramrach at gmail.com>

--

 - fix formatting
---
 drivers/mmc/host/sunxi-mmc.c | 22 +++++++++++++++++++---
 1 file changed, 19 insertions(+), 3 deletions(-)

diff --git a/drivers/mmc/host/sunxi-mmc.c b/drivers/mmc/host/sunxi-mmc.c
index 4d3e1ff..f808a02 100644
--- a/drivers/mmc/host/sunxi-mmc.c
+++ b/drivers/mmc/host/sunxi-mmc.c
@@ -595,7 +595,7 @@ static irqreturn_t sunxi_mmc_handle_manual_stop(int irq, void *dev_id)
 
 static int sunxi_mmc_oclk_onoff(struct sunxi_mmc_host *host, u32 oclk_en)
 {
-	unsigned long expire = jiffies + msecs_to_jiffies(250);
+	unsigned long start, end;
 	u32 rval;
 
 	rval = mmc_readl(host, REG_CLKCR);
@@ -604,6 +604,8 @@ static int sunxi_mmc_oclk_onoff(struct sunxi_mmc_host *host, u32 oclk_en)
 	if (oclk_en)
 		rval |= SDXC_CARD_CLOCK_ON;
 
+	start = jiffies;
+	end = start + msecs_to_jiffies(750);
 	mmc_writel(host, REG_CLKCR, rval);
 
 	rval = SDXC_START | SDXC_UPCLK_ONLY | SDXC_WAIT_PRE_OVER;
@@ -611,15 +613,29 @@ static int sunxi_mmc_oclk_onoff(struct sunxi_mmc_host *host, u32 oclk_en)
 
 	do {
 		rval = mmc_readl(host, REG_CMDR);
-	} while (time_before(jiffies, expire) && (rval & SDXC_START));
+	} while (time_before(jiffies, end) && (rval & SDXC_START));
+	end = jiffies;
 
 	/* clear irq status bits set by the command */
 	mmc_writel(host, REG_RINTR,
 		   mmc_readl(host, REG_RINTR) & ~SDXC_SDIO_INTERRUPT);
 
 	if (rval & SDXC_START) {
-		dev_err(mmc_dev(host->mmc), "fatal err update clk timeout\n");
+		dev_err(mmc_dev(host->mmc),
+			"fatal err update oclk timeout. Could not %s in %ims.\n",
+			oclk_en ? "enable" : "disable",
+			jiffies_to_msecs(end - start));
 		return -EIO;
+	} else {
+		int msecs = jiffies_to_msecs(end - start);
+		const char *ing = oclk_en ? "enabling" : "disabling";
+
+		if ((msecs > 150) || (oclk_en && (msecs > 50)))
+			dev_warn(mmc_dev(host->mmc),
+				 "%s oclk took %ims", ing, msecs);
+		else
+			dev_dbg(mmc_dev(host->mmc),
+				 "%s oclk took %ims", ing, msecs);
 	}
 
 	return 0;
-- 
2.1.4



From horia.geanta at freescale.com  Wed Aug 12 05:24:35 2015
From: horia.geanta at freescale.com (=?UTF-8?q?Horia=20Geant=C4=83?=)
Date: Wed, 12 Aug 2015 15:24:35 +0300
Subject: [PATCH] arm64: add ioread64be and iowrite64be macros
Message-ID: <1439382275-21678-1-git-send-email-horia.geanta@freescale.com>

Signed-off-by: Alex Porosanu <alexandru.porosanu at freescale.com>
Signed-off-by: Horia Geant? <horia.geanta at freescale.com>
---
 arch/arm64/include/asm/io.h | 4 +++-
 1 file changed, 3 insertions(+), 1 deletion(-)

diff --git a/arch/arm64/include/asm/io.h b/arch/arm64/include/asm/io.h
index 44be1e03ed65..9b6e408cfa51 100644
--- a/arch/arm64/include/asm/io.h
+++ b/arch/arm64/include/asm/io.h
@@ -174,13 +174,15 @@ extern void __iomem *ioremap_cache(phys_addr_t phys_addr, size_t size);
 #define iounmap				__iounmap
 
 /*
- * io{read,write}{16,32}be() macros
+ * io{read,write}{16,32,64}be() macros
  */
 #define ioread16be(p)		({ __u16 __v = be16_to_cpu((__force __be16)__raw_readw(p)); __iormb(); __v; })
 #define ioread32be(p)		({ __u32 __v = be32_to_cpu((__force __be32)__raw_readl(p)); __iormb(); __v; })
+#define ioread64be(p)		({ __u64 __v = be64_to_cpu((__force __be64)__raw_readq(p)); __iormb(); __v; })
 
 #define iowrite16be(v,p)	({ __iowmb(); __raw_writew((__force __u16)cpu_to_be16(v), p); })
 #define iowrite32be(v,p)	({ __iowmb(); __raw_writel((__force __u32)cpu_to_be32(v), p); })
+#define iowrite64be(v,p)	({ __iowmb(); __raw_writeq((__force __u64)cpu_to_be64(v), p); })
 
 /*
  * Convert a physical pointer to a virtual kernel pointer for /dev/mem
-- 
2.4.4



From eric.auger at linaro.org  Wed Aug 12 05:26:34 2015
From: eric.auger at linaro.org (Eric Auger)
Date: Wed, 12 Aug 2015 14:26:34 +0200
Subject: [PATCH v2 04/15] KVM: arm/arm64: extend arch CAP checks to allow
 per-VM capabilities
In-Reply-To: <1436538111-4294-5-git-send-email-andre.przywara@arm.com>
References: <1436538111-4294-1-git-send-email-andre.przywara@arm.com>
 <1436538111-4294-5-git-send-email-andre.przywara@arm.com>
Message-ID: <55CB3B7A.3070300@linaro.org>

Reviewed-by: Eric Auger <eric.auger at linaro.org>

Best Regards

Eric

On 07/10/2015 04:21 PM, Andre Przywara wrote:
> KVM capabilities can be a per-VM property, though ARM/ARM64 currently
> does not pass on the VM pointer to the architecture specific
> capability handlers.
> Add a "struct kvm*" parameter to those function to later allow proper
> per-VM capability reporting.
> 
> Signed-off-by: Andre Przywara <andre.przywara at arm.com>
> ---
>  arch/arm/include/asm/kvm_host.h   | 2 +-
>  arch/arm/kvm/arm.c                | 2 +-
>  arch/arm64/include/asm/kvm_host.h | 2 +-
>  arch/arm64/kvm/reset.c            | 2 +-
>  4 files changed, 4 insertions(+), 4 deletions(-)
> 
> diff --git a/arch/arm/include/asm/kvm_host.h b/arch/arm/include/asm/kvm_host.h
> index e896d2c..56cac05 100644
> --- a/arch/arm/include/asm/kvm_host.h
> +++ b/arch/arm/include/asm/kvm_host.h
> @@ -213,7 +213,7 @@ static inline void __cpu_init_hyp_mode(phys_addr_t boot_pgd_ptr,
>  	kvm_call_hyp((void*)hyp_stack_ptr, vector_ptr, pgd_ptr);
>  }
>  
> -static inline int kvm_arch_dev_ioctl_check_extension(long ext)
> +static inline int kvm_arch_dev_ioctl_check_extension(struct kvm *kvm, long ext)
>  {
>  	return 0;
>  }
> diff --git a/arch/arm/kvm/arm.c b/arch/arm/kvm/arm.c
> index bc738d2..7c65353 100644
> --- a/arch/arm/kvm/arm.c
> +++ b/arch/arm/kvm/arm.c
> @@ -196,7 +196,7 @@ int kvm_vm_ioctl_check_extension(struct kvm *kvm, long ext)
>  		r = KVM_MAX_VCPUS;
>  		break;
>  	default:
> -		r = kvm_arch_dev_ioctl_check_extension(ext);
> +		r = kvm_arch_dev_ioctl_check_extension(kvm, ext);
>  		break;
>  	}
>  	return r;
> diff --git a/arch/arm64/include/asm/kvm_host.h b/arch/arm64/include/asm/kvm_host.h
> index 2709db2..8d78a72 100644
> --- a/arch/arm64/include/asm/kvm_host.h
> +++ b/arch/arm64/include/asm/kvm_host.h
> @@ -47,7 +47,7 @@
>  
>  int __attribute_const__ kvm_target_cpu(void);
>  int kvm_reset_vcpu(struct kvm_vcpu *vcpu);
> -int kvm_arch_dev_ioctl_check_extension(long ext);
> +int kvm_arch_dev_ioctl_check_extension(struct kvm *kvm, long ext);
>  
>  struct kvm_arch {
>  	/* The VMID generation used for the virt. memory system */
> diff --git a/arch/arm64/kvm/reset.c b/arch/arm64/kvm/reset.c
> index 0b43265..866502b 100644
> --- a/arch/arm64/kvm/reset.c
> +++ b/arch/arm64/kvm/reset.c
> @@ -56,7 +56,7 @@ static bool cpu_has_32bit_el1(void)
>  	return !!(pfr0 & 0x20);
>  }
>  
> -int kvm_arch_dev_ioctl_check_extension(long ext)
> +int kvm_arch_dev_ioctl_check_extension(struct kvm *kvm, long ext)
>  {
>  	int r;
>  
> 



From yong.wu at mediatek.com  Wed Aug 12 05:28:08 2015
From: yong.wu at mediatek.com (Yong Wu)
Date: Wed, 12 Aug 2015 20:28:08 +0800
Subject: [PATCH v4 5/6] iommu/mediatek: Add mt8173 IOMMU driver
In-Reply-To: <20150811153947.GF14980@8bytes.org>
References: <1438597279-2937-1-git-send-email-yong.wu@mediatek.com>
 <1438597279-2937-6-git-send-email-yong.wu@mediatek.com>
 <20150811153947.GF14980@8bytes.org>
Message-ID: <1439382488.7382.23.camel@mhfsdcap03>

On Tue, 2015-08-11 at 17:39 +0200, Joerg Roedel wrote:
> On Mon, Aug 03, 2015 at 06:21:18PM +0800, Yong Wu wrote:
> > +/*
> > + * There is only one iommu domain called the m4u domain that
> > + * all Multimedia modules share.
> > + */
> > +static struct mtk_iommu_domain	*m4udom;
> 
> What is the reason you only implement one domain? Can't the IOMMU
> isolate different devices from each other?
Hi Joerg,

  Thanks for your review.
  From your comment, you may care that we use only one domain.

  Our HW is called m4u(MultiMedia Memory Management Unit) which
help all the multimedia hardware access the dram, include display,video
decode,video encode,camera,mdp,etc. And the m4u has only one pagetable.
(Actually there is two pagetables in m4u, one is the normal pagetable,
the other is security pagetable. Currently We don't implement the
security one, so there is only one pagetable here.)
That is to say all the multimedia devices are in the m4u domain and
share the m4u?s pagetable.

So We have only one domain here..

> > +static struct iommu_domain *mtk_iommu_domain_alloc(unsigned type)
> > +{
> > +	struct mtk_iommu_domain *priv;
> > +
> > +	if (type != IOMMU_DOMAIN_UNMANAGED && type != IOMMU_DOMAIN_DMA)
> > +		return NULL;
> > +
> > +	if (m4udom)/* The m4u domain exist. */
> > +		return &m4udom->domain;
> 
> This is not going to work. If you always return the same domain the
> iommu core might re-initialize domain state (and overwrite changed
> state). At the moment this is only the domain-type which will change
> every time this function is called, but there might be more.

In our v3[1],  I didn't return the same domain, Then I have to trick in
attach_device like below:
//============
static int mtk_iommu_attach_device(struct iommu_domain *domain,
                                  struct device *dev)
{
        struct device *imudev = xxxx;
        /*
         * Reserve one iommu domain as the m4u domain which
         * all Multimedia modules share and free the others.
         */
        if (!imudev->archdata.iommu)
               imudev->archdata.iommu = priv;
        else if (imudev->archdata.iommu != priv)
               iommu_domain_free(domain);
        xxxx
}
//==============
In this version, I used a global variable to record the m4u domain then
I can delete these code and make it simple.

Then how should I do in our case? .
If we can't return the same domain here, We have to add some code like
above in the attach_device.

[1]:http://lists.linuxfoundation.org/pipermail/iommu/2015-July/013631.html
 
> 
> > +static int mtk_iommu_add_device(struct device *dev)
> > +{
> > +	struct iommu_group *group;
> > +	int ret;
> > +
> > +	if (!dev->archdata.iommu) /* Not a iommu client device */
> > +		return -ENODEV;
> > +
> > +	group = iommu_group_get(dev);
> > +	if (!group) {
> > +		group = iommu_group_alloc();
> > +		if (IS_ERR(group)) {
> > +			dev_err(dev, "Failed to allocate IOMMU group\n");
> > +			return PTR_ERR(group);
> > +		}
> > +	}
> > +
> > +	ret = iommu_group_add_device(group, dev);
> > +	if (ret) {
> > +		dev_err(dev, "Failed to add IOMMU group\n");
> > +		goto err_group_put;
> > +	}
> > +
> > +	ret = iommu_attach_group(&m4udom->domain, group);
> > +	if (ret)
> > +		dev_err(dev, "Failed to attach IOMMU group\n");
> > +
> > +err_group_put:
> > +	iommu_group_put(group);
> > +	return ret;
> > +}
> 
> Putting every device into its own group indicates that the IOMMU can
> isolate between single devices on the bus, which makes it even more
> questionable that you only allow one domain for the whole driver.
> 
> 
> 	Joerg
> 




From mpa at pengutronix.de  Wed Aug 12 05:28:56 2015
From: mpa at pengutronix.de (Markus Pargmann)
Date: Wed, 12 Aug 2015 14:28:56 +0200
Subject: [PATCH 02/20] regmap: Remove regmap_bulk_write 64bit support
In-Reply-To: <20150812105758.GU10748@sirena.org.uk>
References: <1439374365-20623-1-git-send-email-mpa@pengutronix.de>
 <1439374365-20623-3-git-send-email-mpa@pengutronix.de>
 <20150812102550.GQ10748@sirena.org.uk>
 <20150812104436.GA19600@pengutronix.de>
 <20150812105758.GU10748@sirena.org.uk>
Message-ID: <20150812122856.GF19600@pengutronix.de>

On Wed, Aug 12, 2015 at 11:57:58AM +0100, Mark Brown wrote:
> On Wed, Aug 12, 2015 at 12:44:36PM +0200, Markus Pargmann wrote:
> 
> > I wasn't aware that any 64 bit architecture actually has unsigned ints
> > that are 64 bit in size. So wouldn't at least on x86_64 this would lead
> > to a compiler warning as unsigned int is 4 byte and u64 8 bytes?
> 
> Nobody complained about warnings yet.  The compiler probably shouldn't
> be complaining given the casts, they're supposed to be an "I know what
> I'm doing" thing.  If you want to change something here it's changing
> the test to be based on sizeof(unsigned int).

Ok, would work for me as well although sizeof is not a preprocessor
macro so I would probably leave it as it is. The whole regmap framework
just didn't seem to support 64bit so I thought this was just not
working.

Thanks,

Markus

-- 
Pengutronix e.K.                           |                             |
Industrial Linux Solutions                 | http://www.pengutronix.de/  |
Peiner Str. 6-8, 31137 Hildesheim, Germany | Phone: +49-5121-206917-0    |
Amtsgericht Hildesheim, HRA 2686           | Fax:   +49-5121-206917-5555 |
-------------- next part --------------
A non-text attachment was scrubbed...
Name: signature.asc
Type: application/pgp-signature
Size: 819 bytes
Desc: Digital signature
URL: <http://lists.infradead.org/pipermail/linux-arm-kernel/attachments/20150812/a8047f85/attachment.sig>

From hramrach at gmail.com  Wed Aug 12 05:30:19 2015
From: hramrach at gmail.com (Michal Suchanek)
Date: Wed, 12 Aug 2015 14:30:19 +0200
Subject: [linux-sunxi] MMC clock gating broken on a20
In-Reply-To: <55CB344F.6050608@schinagl.nl>
References: <CAOMqctRhQHv1idY0ci6uzDxnv5oj7dbHtc4CTfo75ipXkXd1gw@mail.gmail.com>
 <55CB3095.9050509@schinagl.nl> <55CB344F.6050608@schinagl.nl>
Message-ID: <CAOMqctSSyJs_yAkjDd0OCM2c3BanaBd7cr5kREn6b5ckStyzSg@mail.gmail.com>

On 12 August 2015 at 13:55, Olliver Schinagl <oliver+list at schinagl.nl> wrote:
> Actually, I've reverted hans's
>
> mmc: sunxi: Don't start commands while the card is busy
>
> and that makes it disapear as well. So it looks like that patch triggers the
> aggressiveness more?

It probably inserts delays which trigger the mmc power saving.

Still the delay should not be needed on the mmc interface which is
connected to the card slot, should it?

Thanks

Michal


From daniel.lezcano at linaro.org  Wed Aug 12 05:32:11 2015
From: daniel.lezcano at linaro.org (Daniel Lezcano)
Date: Wed, 12 Aug 2015 14:32:11 +0200
Subject: [PATCH 0/5] add GPT timer support for mt8173
In-Reply-To: <CAGS+omAeYhXDpBueG-F_gYBccqeaejN9k5bRKC78aDLfvHfnBA@mail.gmail.com>
References: <1436779969-18610-1-git-send-email-yingjoe.chen@mediatek.com>
 <CAGS+omAeYhXDpBueG-F_gYBccqeaejN9k5bRKC78aDLfvHfnBA@mail.gmail.com>
Message-ID: <55CB3CCB.6020607@linaro.org>

On 08/11/2015 05:54 PM, Daniel Kurtz wrote:
> On Mon, Jul 13, 2015 at 5:32 PM, Yingjoe Chen <yingjoe.chen at mediatek.com> wrote:
>> This series add GPT timer support for mt8173. This is based on v4.2-rc1
>> and Matthias' next branch (for dts parts).
>>
>> The first 2 patches comes from 'Add SMP bringup support for mt65xx socs'
>> series [1]. I decide to move these 2 patches to this series, since it
>> is more relevent here. They are changed based on Matthias' and Daniel's
>> comments.
>>
>> [1] http://lists.infradead.org/pipermail/linux-mediatek/2015-May/000714.html
>>
>> Daniel Kurtz (1):
>>    arm64: dts: mt8173: add timer node
>>
>> Yingjoe Chen (4):
>>    clocksource: mediatek: do not enable GPT_CLK_EVT when setup
>>    clocksource: mediatek: Use GPT as sched clock source
>>    arm64: mediatek: enable MTK_TIMER
>>    clk: mediatek: add 13mhz clock for MT8173
>
> Was this mediatek clocksource patch set get forgotten again?

Yep. Sounds like it felt at the wrong moment.

> All 5 patches have have been reviewed, and I think the ones that need
> it have been Ack'ed by Matthias and/or Stephen.
> What is the plan for merging them?

So if I am not wrong we have two patches I can take in my tree as a 
couple of fixes (1 and 2), right ?




-- 
  <http://www.linaro.org/> Linaro.org ? Open source software for ARM SoCs

Follow Linaro:  <http://www.facebook.com/pages/Linaro> Facebook |
<http://twitter.com/#!/linaroorg> Twitter |
<http://www.linaro.org/linaro-blog/> Blog



From hdegoede at redhat.com  Wed Aug 12 05:32:23 2015
From: hdegoede at redhat.com (Hans de Goede)
Date: Wed, 12 Aug 2015 14:32:23 +0200
Subject: [PATCH resend 1/3] mmc: sunxi: fix timeout in sunxi_mmc_oclk_onoff
In-Reply-To: <7f9c6f99b31702c02436ef3356b3ebffa4754260.1439381423.git.hramrach@gmail.com>
References: <cover.1439381423.git.hramrach@gmail.com>
 <7f9c6f99b31702c02436ef3356b3ebffa4754260.1439381423.git.hramrach@gmail.com>
Message-ID: <55CB3CD7.2050200@redhat.com>

Hi,

On 12-08-15 14:23, michal.suchanek at ruk.cuni.cz wrote:
> The 250ms timeout is too short.
>
> On my system enabling the oclk takes under 50ms and disabling slightly
> over 100ms when idle. Under load disabling the clock can take over
> 350ms.
>
> This does not make mmc clock gating look like good option to have on
> sunxi but the system should not crash with mmc clock gating enabled
> nonetheless.
>
> This patch sets the timeout to 750ms and adds debug prints which show
> how long enabling/disabling the clock took so more data can be collected
> from other systems.
>
> Signed-off-by: Michal Suchanek <hramrach at gmail.com>

This is a big patch for just changing a timeout, most of this is in
extra verbosity which IMHO has little value, in the error path w
know we will have waited aprox 750 ms, so printing the waiting
time there is not worth all the extra code.

As for adding the warning I'm even less of a big fan of that,
if we need higher timeouts, we need higher timeouts, spamming the
kernel logs with that we are actually hitting the higher timeouts
is not productive IMHO.

Can you please resend this as a one-liner just changing the timeout ?

Regards,

Hans


>
> --
>
>   - fix formatting
> ---
>   drivers/mmc/host/sunxi-mmc.c | 22 +++++++++++++++++++---
>   1 file changed, 19 insertions(+), 3 deletions(-)
>
> diff --git a/drivers/mmc/host/sunxi-mmc.c b/drivers/mmc/host/sunxi-mmc.c
> index 4d3e1ff..f808a02 100644
> --- a/drivers/mmc/host/sunxi-mmc.c
> +++ b/drivers/mmc/host/sunxi-mmc.c
> @@ -595,7 +595,7 @@ static irqreturn_t sunxi_mmc_handle_manual_stop(int irq, void *dev_id)
>
>   static int sunxi_mmc_oclk_onoff(struct sunxi_mmc_host *host, u32 oclk_en)
>   {
> -	unsigned long expire = jiffies + msecs_to_jiffies(250);
> +	unsigned long start, end;
>   	u32 rval;
>
>   	rval = mmc_readl(host, REG_CLKCR);
> @@ -604,6 +604,8 @@ static int sunxi_mmc_oclk_onoff(struct sunxi_mmc_host *host, u32 oclk_en)
>   	if (oclk_en)
>   		rval |= SDXC_CARD_CLOCK_ON;
>
> +	start = jiffies;
> +	end = start + msecs_to_jiffies(750);
>   	mmc_writel(host, REG_CLKCR, rval);
>
>   	rval = SDXC_START | SDXC_UPCLK_ONLY | SDXC_WAIT_PRE_OVER;
> @@ -611,15 +613,29 @@ static int sunxi_mmc_oclk_onoff(struct sunxi_mmc_host *host, u32 oclk_en)
>
>   	do {
>   		rval = mmc_readl(host, REG_CMDR);
> -	} while (time_before(jiffies, expire) && (rval & SDXC_START));
> +	} while (time_before(jiffies, end) && (rval & SDXC_START));
> +	end = jiffies;
>
>   	/* clear irq status bits set by the command */
>   	mmc_writel(host, REG_RINTR,
>   		   mmc_readl(host, REG_RINTR) & ~SDXC_SDIO_INTERRUPT);
>
>   	if (rval & SDXC_START) {
> -		dev_err(mmc_dev(host->mmc), "fatal err update clk timeout\n");
> +		dev_err(mmc_dev(host->mmc),
> +			"fatal err update oclk timeout. Could not %s in %ims.\n",
> +			oclk_en ? "enable" : "disable",
> +			jiffies_to_msecs(end - start));
>   		return -EIO;
> +	} else {
> +		int msecs = jiffies_to_msecs(end - start);
> +		const char *ing = oclk_en ? "enabling" : "disabling";
> +
> +		if ((msecs > 150) || (oclk_en && (msecs > 50)))
> +			dev_warn(mmc_dev(host->mmc),
> +				 "%s oclk took %ims", ing, msecs);
> +		else
> +			dev_dbg(mmc_dev(host->mmc),
> +				 "%s oclk took %ims", ing, msecs);
>   	}
>
>   	return 0;
>


From mpa at pengutronix.de  Wed Aug 12 05:34:12 2015
From: mpa at pengutronix.de (Markus Pargmann)
Date: Wed, 12 Aug 2015 14:34:12 +0200
Subject: [PATCH 11/20] regmap: _regmap_raw_read: Add handling of busses
 without bus->read()
In-Reply-To: <20150812112707.GY10748@sirena.org.uk>
References: <1439374365-20623-1-git-send-email-mpa@pengutronix.de>
 <1439374365-20623-12-git-send-email-mpa@pengutronix.de>
 <20150812112707.GY10748@sirena.org.uk>
Message-ID: <20150812123412.GG19600@pengutronix.de>

On Wed, Aug 12, 2015 at 12:27:07PM +0100, Mark Brown wrote:
> On Wed, Aug 12, 2015 at 12:12:36PM +0200, Markus Pargmann wrote:
> 
> > +	/*
> > +	 * There are busses that do not have a read function as it is optional.
> > +	 * Use their reg_read function instead if the requested number of bytes
> > +	 * is correct.
> > +	 */
> > +	if (!map->bus->read) {
> > +		/*
> > +		 * bus_reg_read() does not support reading values that are not
> > +		 * exactly the size of format.val_bytes
> > +		 */
> > +		if (val_len != map->format.val_bytes)
> > +			return -EINVAL;
> > +		return _regmap_bus_reg_read(map, reg, val);
> > +	}
> 
> No, this makes no sense - if the device doesn't have a read operation
> then it doesn't support a raw data stream and hence can't support raw
> access sensibly.  Callers that want to access a lot of registers at once
> without knowing what the wire format for the device is should be using
> the bulk or multi interfaces.

Yes okay. Then I will reduce this patch to the following and put it
into regmap_read() instead?
	if (!map->bus->read) {
		return -EINVAL;

Is -EINVAL the right thing to return or would you prefer -ENOTSUPP?

Thanks,

Markus

-- 
Pengutronix e.K.                           |                             |
Industrial Linux Solutions                 | http://www.pengutronix.de/  |
Peiner Str. 6-8, 31137 Hildesheim, Germany | Phone: +49-5121-206917-0    |
Amtsgericht Hildesheim, HRA 2686           | Fax:   +49-5121-206917-5555 |
-------------- next part --------------
A non-text attachment was scrubbed...
Name: signature.asc
Type: application/pgp-signature
Size: 819 bytes
Desc: Digital signature
URL: <http://lists.infradead.org/pipermail/linux-arm-kernel/attachments/20150812/f467f32e/attachment.sig>

From broonie at kernel.org  Wed Aug 12 05:34:06 2015
From: broonie at kernel.org (Mark Brown)
Date: Wed, 12 Aug 2015 13:34:06 +0100
Subject: [PATCH 09/20] regmap: _regmap_raw_write fix for busses without
 write()
In-Reply-To: <20150812122011.GE19600@pengutronix.de>
References: <1439374365-20623-1-git-send-email-mpa@pengutronix.de>
 <1439374365-20623-10-git-send-email-mpa@pengutronix.de>
 <20150812112035.GX10748@sirena.org.uk>
 <20150812122011.GE19600@pengutronix.de>
Message-ID: <20150812123406.GG10748@sirena.org.uk>

On Wed, Aug 12, 2015 at 02:20:11PM +0200, Markus Pargmann wrote:
> On Wed, Aug 12, 2015 at 12:20:35PM +0100, Mark Brown wrote:
> > On Wed, Aug 12, 2015 at 12:12:34PM +0200, Markus Pargmann wrote:
> > 
> > > @@ -1229,6 +1229,11 @@ int _regmap_raw_write(struct regmap *map, unsigned int reg,
> > >  		}
> > >  	}
> > >  
> > > +	if (!map->bus->write && val_len == map->format.val_bytes) {
> > > +		ret = _regmap_bus_reg_write(map, reg, *(unsigned int *)val);
> > > +		return ret;
> > > +	}

> > This is broken - you can't use a raw value as a register value.  The

> I am not sure what you mean here?

> The register value given to _regmap_raw_write is the real register
> value, not formatted differenty. This is given directly towards
> bus->reg_write() which should handle the rest.

I mean the value for the register, not the register address.

> At least that's how I understood the code. For example regmap_read()
> directly calls _regmap_read() which in turn calls directly
> bus->reg_read() without any formating.

You're adding this code to regmap_raw_write() which takes raw register
values for the device, not unsigned integers.

> > endianness of the device may not be the same as the endianness of the
> > system and you can't cast a value to unsigned int, the value may be of
> > any size.

> Yes right. On the other hand if bus->read() and bus->write() was not set
> in the init method (before this patch series) no formatting functions at
> all were assigned. So it was always ignored for bus->reg_read() and
> bus->reg_write()?!

I'm not sure what the "it" you're talking about here is, sorry.  There
are unsupported features in the API especially for cases that don't make
a huge amount of sense, the error handling isn't always complete.  It
sounds like you might be trying to support one of these nonsensical
cases - it's not obvious what raw I/O on a device where we don't know
the raw format of the device should mean or how anything could sensibly
use that.
-------------- next part --------------
A non-text attachment was scrubbed...
Name: signature.asc
Type: application/pgp-signature
Size: 473 bytes
Desc: Digital signature
URL: <http://lists.infradead.org/pipermail/linux-arm-kernel/attachments/20150812/e2d08482/attachment.sig>

From hdegoede at redhat.com  Wed Aug 12 05:35:30 2015
From: hdegoede at redhat.com (Hans de Goede)
Date: Wed, 12 Aug 2015 14:35:30 +0200
Subject: [linux-sunxi] [PATCH 3/3] mmc: sunxi: use controller automatic
 clock gating.
In-Reply-To: <c33b221f9b622e3bad9d855a7ad1887b82827244.1439381423.git.hramrach@gmail.com>
References: <cover.1439381423.git.hramrach@gmail.com>
 <c33b221f9b622e3bad9d855a7ad1887b82827244.1439381423.git.hramrach@gmail.com>
Message-ID: <55CB3D92.6040403@redhat.com>

Hi,

On 12-08-15 14:23, Michal Suchanek wrote:
> When core does not set the MMC_QUIRK_BROKEN_CLK_GATING flag enable
> automatic hardware controlled clock gating on the mmc interface.
>
> Signed-off-by: Michal Suchanek <hramrach at gmail.com>

In general this looks good, but I wonder how intensively this has
been tested ? Also given the long latencies when using manual
clock on/off support, have you done any testing to check what
sort of latencies this adds, e.g. Both with and without
the patch, dump all the filesystem caches:

echo 3 > /proc/sys/vm/drop_caches

And then do:

time cat /some/small/file/on/the/sdcard

Do this at least 3 time both with and without the patch, and see
if there are any noticable differences ?

Regards,

Hans



> ---
>   drivers/mmc/host/sunxi-mmc.c | 7 ++++++-
>   1 file changed, 6 insertions(+), 1 deletion(-)
>
> diff --git a/drivers/mmc/host/sunxi-mmc.c b/drivers/mmc/host/sunxi-mmc.c
> index f808a02..443cab5 100644
> --- a/drivers/mmc/host/sunxi-mmc.c
> +++ b/drivers/mmc/host/sunxi-mmc.c
> @@ -601,8 +601,13 @@ static int sunxi_mmc_oclk_onoff(struct sunxi_mmc_host *host, u32 oclk_en)
>   	rval = mmc_readl(host, REG_CLKCR);
>   	rval &= ~(SDXC_CARD_CLOCK_ON | SDXC_LOW_POWER_ON);
>
> -	if (oclk_en)
> +	if (oclk_en) {
>   		rval |= SDXC_CARD_CLOCK_ON;
> +		if (!host->mmc->card ||
> +		     !(host->mmc->card->quirks & MMC_QUIRK_BROKEN_CLK_GATING))
> +
> +			rval |= SDXC_LOW_POWER_ON;
> +	}
>
>   	start = jiffies;
>   	end = start + msecs_to_jiffies(750);
>


From broonie at kernel.org  Wed Aug 12 05:35:37 2015
From: broonie at kernel.org (Mark Brown)
Date: Wed, 12 Aug 2015 13:35:37 +0100
Subject: [PATCH 02/20] regmap: Remove regmap_bulk_write 64bit support
In-Reply-To: <20150812122856.GF19600@pengutronix.de>
References: <1439374365-20623-1-git-send-email-mpa@pengutronix.de>
 <1439374365-20623-3-git-send-email-mpa@pengutronix.de>
 <20150812102550.GQ10748@sirena.org.uk>
 <20150812104436.GA19600@pengutronix.de>
 <20150812105758.GU10748@sirena.org.uk>
 <20150812122856.GF19600@pengutronix.de>
Message-ID: <20150812123537.GH10748@sirena.org.uk>

On Wed, Aug 12, 2015 at 02:28:56PM +0200, Markus Pargmann wrote:

> Ok, would work for me as well although sizeof is not a preprocessor
> macro so I would probably leave it as it is. The whole regmap framework
> just didn't seem to support 64bit so I thought this was just not
> working.

I'd expect the framework to cope with things when ints are 64 bit.  We
don't try to support anything else, though.
-------------- next part --------------
A non-text attachment was scrubbed...
Name: signature.asc
Type: application/pgp-signature
Size: 473 bytes
Desc: Digital signature
URL: <http://lists.infradead.org/pipermail/linux-arm-kernel/attachments/20150812/0cdbdd89/attachment.sig>

From oliver+list at schinagl.nl  Wed Aug 12 05:37:18 2015
From: oliver+list at schinagl.nl (Olliver Schinagl)
Date: Wed, 12 Aug 2015 14:37:18 +0200
Subject: [PATCH v2] mmc: sunxi: fix timeout in sunxi_mmc_oclk_onoff
Message-ID: <55CB3DFE.8060508@schinagl.nl>

Hey all

A few months ago, Michal Suchanek submitted the attached patch fixing 
the gating timeout issue. Until recently, about v4.0.0 I hadn't noticed 
any issues and ran all boards from SD card.

Recently I upgraded to Hans's 4.2 tree where he added

mmc: sunxi: Don't start commands while the card is busy

which started to trigger the timeout very aggressively causing a pretty 
much unusable system.
While reverting the commands patch also removed the problem for some 
reason, that is of course not the real fix.

Applying Michal's patch on top of the commands patch appears to fix the 
issue on atleast the A20 Lime2.

Attached I have Michal's original patch, rebased to 4.2.0-rc5, with 
Hans's patch applied before hand.

Changed since v1
* Whitespace cleanup as suggested by Maxime Ripard, no functional 
changes from that patch

Olliver
-------------- next part --------------
A non-text attachment was scrubbed...
Name: 0001-mmc-sunxi-fix-timeout-in-sunxi_mmc_oclk_onoff.patch
Type: text/x-patch
Size: 3023 bytes
Desc: not available
URL: <http://lists.infradead.org/pipermail/linux-arm-kernel/attachments/20150812/8931b61f/attachment.bin>

From marc.zyngier at arm.com  Wed Aug 12 05:38:27 2015
From: marc.zyngier at arm.com (Marc Zyngier)
Date: Wed, 12 Aug 2015 13:38:27 +0100
Subject: [PATCH 1/6] irqchip: GICv3: Convert to EOImode == 1
In-Reply-To: <55C9BD00.7030901@linaro.org>
References: <1436447951-22357-1-git-send-email-marc.zyngier@arm.com>
 <1436447951-22357-2-git-send-email-marc.zyngier@arm.com>
 <55C9BD00.7030901@linaro.org>
Message-ID: <55CB3E43.3010209@arm.com>

On 11/08/15 10:14, Eric Auger wrote:
> Hi Marc,
> On 07/09/2015 03:19 PM, Marc Zyngier wrote:
>> So far, GICv3 has been used in with EOImode == 0. The effect of this
>> mode is to perform the priority drop and the deactivation of the
>> interrupt at the same time.
>>
>> While this works perfectly for Linux (we only have a single priority),
>> it causes issues when an interrupt is forwarded to a guest, and when
>> we want the guest to perform the EOI itself.
>>
>> For this case, the GIC architecture provides EOImode == 1, where:
>> - A write to ICC_EOIR1_EL1 drops the priority of the interrupt and leaves
>> it active. Other interrupts at the same priority level can now be taken,
>> but the active interrupt cannot be taken again
>> - A write to ICC_DIR_EL1 marks the interrupt as inactive, meaning it can
>> now be taken again.
>>
>> This patch converts the driver to be able to use this new mode, depending
>> on whether or not the kernel can behave as a hypervisor. No feature change.
>>
>> Signed-off-by: Marc Zyngier <marc.zyngier at arm.com>
>> ---
>>  drivers/irqchip/irq-gic-v3.c       | 28 +++++++++++++++++++++++++---
>>  include/linux/irqchip/arm-gic-v3.h |  9 +++++++++
>>  2 files changed, 34 insertions(+), 3 deletions(-)
>>
>> diff --git a/drivers/irqchip/irq-gic-v3.c b/drivers/irqchip/irq-gic-v3.c
>> index c52f7ba..49768fc 100644
>> --- a/drivers/irqchip/irq-gic-v3.c
>> +++ b/drivers/irqchip/irq-gic-v3.c
>> @@ -30,6 +30,7 @@
>>  #include <asm/cputype.h>
>>  #include <asm/exception.h>
>>  #include <asm/smp_plat.h>
>> +#include <asm/virt.h>
>>  
>>  #include "irq-gic-common.h"
>>  #include "irqchip.h"
>> @@ -50,6 +51,7 @@ struct gic_chip_data {
>>  };
>>  
>>  static struct gic_chip_data gic_data __read_mostly;
>> +static struct static_key supports_deactivate = STATIC_KEY_INIT_TRUE;
>>  
>>  #define gic_data_rdist()		(this_cpu_ptr(gic_data.rdists.rdist))
>>  #define gic_data_rdist_rd_base()	(gic_data_rdist()->rd_base)
>> @@ -293,7 +295,10 @@ static int gic_irq_get_irqchip_state(struct irq_data *d,
>>  
>>  static void gic_eoi_irq(struct irq_data *d)
>>  {
>> -	gic_write_eoir(gic_irq(d));
>> +	if (static_key_true(&supports_deactivate))
>> +		gic_write_dir(gic_irq(d));
>> +	else
>> +		gic_write_eoir(gic_irq(d));
>>  }
>>  
>>  static int gic_set_type(struct irq_data *d, unsigned int type)
>> @@ -343,6 +348,10 @@ static asmlinkage void __exception_irq_entry gic_handle_irq(struct pt_regs *regs
>>  
>>  		if (likely(irqnr > 15 && irqnr < 1020) || irqnr >= 8192) {
>>  			int err;
>> +
>> +			if (static_key_true(&supports_deactivate))
>> +				gic_write_eoir(irqnr);
>> +
>>  			err = handle_domain_irq(gic_data.domain, irqnr, regs);
>>  			if (err) {
>>  				WARN_ONCE(true, "Unexpected interrupt received!\n");
> shouldn't we DIR here as well in case of err (we did EOI before)?

Yes, we should, very good point. I'll fix that up.

> Besides Reviewed-by: Eric Auger <eric.auger at linaro.org> if it can help.
> 

Thanks!

	M.
-- 
Jazz is not dead. It just smells funny...


From mpa at pengutronix.de  Wed Aug 12 05:38:44 2015
From: mpa at pengutronix.de (Markus Pargmann)
Date: Wed, 12 Aug 2015 14:38:44 +0200
Subject: [PATCH 12/20] regmap: Introduce max_raw_io for
 regmap_bulk_read/write
In-Reply-To: <20150812114931.GZ10748@sirena.org.uk>
References: <1439374365-20623-1-git-send-email-mpa@pengutronix.de>
 <1439374365-20623-13-git-send-email-mpa@pengutronix.de>
 <20150812114931.GZ10748@sirena.org.uk>
Message-ID: <20150812123844.GH19600@pengutronix.de>

On Wed, Aug 12, 2015 at 12:49:31PM +0100, Mark Brown wrote:
> On Wed, Aug 12, 2015 at 12:12:37PM +0200, Markus Pargmann wrote:
> 
> > +	/* if set, raw reads/writes are limited to this size */
> > +	size_t max_raw_io;
> > +
> 
> Do this separately for read and write, there's doubtless going to be
> something that has asymmetry.

Okay.

> 
> > +		if (!map->use_single_rw) {
> > +			write_count = total_bytes / map->max_raw_io;
> > +			write_bytes = map->max_raw_io;
> 
> We may not be able to fit a whole number of values into whatever the
> constraint that the bus has is and partial values don't seem like a good
> idea.

Oh right. Will change the calculation so that there are no partial
values being written.

> 
> > +			reg_stride *= write_bytes / val_bytes;
> > +		}
> 
> This is very confusing, regmap already has a concept of stride and this
> isn't the same thing.

Okay, will rename it.

Thanks,

Markus

-- 
Pengutronix e.K.                           |                             |
Industrial Linux Solutions                 | http://www.pengutronix.de/  |
Peiner Str. 6-8, 31137 Hildesheim, Germany | Phone: +49-5121-206917-0    |
Amtsgericht Hildesheim, HRA 2686           | Fax:   +49-5121-206917-5555 |
-------------- next part --------------
A non-text attachment was scrubbed...
Name: signature.asc
Type: application/pgp-signature
Size: 819 bytes
Desc: Digital signature
URL: <http://lists.infradead.org/pipermail/linux-arm-kernel/attachments/20150812/a6dbd200/attachment.sig>

From linus.walleij at linaro.org  Wed Aug 12 05:39:20 2015
From: linus.walleij at linaro.org (Linus Walleij)
Date: Wed, 12 Aug 2015 14:39:20 +0200
Subject: [GIT PULL] Nomadik improvements and cleanups for v4.3
In-Reply-To: <20150811133127.GN30181@localhost>
References: <CACRpkdbN6ZDhH56PSUmPD5_uYJhk_o+mCqAvi5GVEtys=AftNg@mail.gmail.com>
 <20150811133127.GN30181@localhost>
Message-ID: <CACRpkdYJ7BjppY=mRQRVpEgKTOEWRjGwLE5a=dcH0rVHJsZyRw@mail.gmail.com>

On Tue, Aug 11, 2015 at 3:31 PM, Olof Johansson <olof at lixom.net> wrote:

>> The following changes since commit 74d33293e467df61de1b1d8b2fbe29e550dec33b:
>>
>>   Linux 4.2-rc5 (2015-08-02 18:34:55 -0700)
>
> This is 3 -rcs newer than we have our tree based on to date (-rc2).

Sorry, I did it like this because I wanted to avoid possible collisions
with the Nomadik fix that was merged in -rc5.

> I don't see any conflict with -rc2 though, so I've cherry-picked these over
> instead of merging the branch.

If that works, thanks and go ahead!

Yours,
Linus Walleij


From broonie at kernel.org  Wed Aug 12 05:39:23 2015
From: broonie at kernel.org (Mark Brown)
Date: Wed, 12 Aug 2015 13:39:23 +0100
Subject: [PATCH 10/20] regmap: _regmap_raw_multi_reg_write: Add
 reg_write() support
In-Reply-To: <1439374365-20623-11-git-send-email-mpa@pengutronix.de>
References: <1439374365-20623-1-git-send-email-mpa@pengutronix.de>
 <1439374365-20623-11-git-send-email-mpa@pengutronix.de>
Message-ID: <20150812123923.GI10748@sirena.org.uk>

On Wed, Aug 12, 2015 at 12:12:35PM +0200, Markus Pargmann wrote:
> Define a fallback for busses which do not define a write() function.
> Instead we write one register at a time using reg_write().
> 
> Without this patch, _regmap_raw_multi_reg_write would break as it tries
> to call bus->write() without checking if it exists before.

Why are we trying to use multi write APIs in the first place if we can't
do raw I/O?
-------------- next part --------------
A non-text attachment was scrubbed...
Name: signature.asc
Type: application/pgp-signature
Size: 473 bytes
Desc: Digital signature
URL: <http://lists.infradead.org/pipermail/linux-arm-kernel/attachments/20150812/59a4ff51/attachment.sig>

From yong.wu at mediatek.com  Wed Aug 12 05:39:34 2015
From: yong.wu at mediatek.com (Yong Wu)
Date: Wed, 12 Aug 2015 20:39:34 +0800
Subject: [PATCH v4 4/6] memory: mediatek: Add SMI driver
In-Reply-To: <20150811145633.GE14980@8bytes.org>
References: <1438597279-2937-1-git-send-email-yong.wu@mediatek.com>
 <1438597279-2937-5-git-send-email-yong.wu@mediatek.com>
 <20150811145633.GE14980@8bytes.org>
Message-ID: <1439383174.7382.24.camel@mhfsdcap03>

On Tue, 2015-08-11 at 16:56 +0200, Joerg Roedel wrote:
> On Mon, Aug 03, 2015 at 06:21:17PM +0800, Yong Wu wrote:
> > +static int mtk_smi_common_get(struct device *smidev)
> > +{
> > +	struct mtk_smi_common *smipriv = dev_get_drvdata(smidev);
> > +	int ret;
> > +
> > +	ret = pm_runtime_get_sync(smidev);
> > +	if (ret < 0)
> > +		return ret;
> > +
> > +	ret = clk_prepare_enable(smipriv->clk_apb);
> > +	if (ret) {
> > +		dev_err(smidev, "Failed to enable the apb clock\n");
> > +		goto err_put_pm;
> > +	}
> > +	ret = clk_prepare_enable(smipriv->clk_smi);
> > +	if (ret) {
> > +		dev_err(smidev, "Failed to enable the smi clock\n");
> > +		goto err_disable_apb;
> > +	}
> > +	return ret;
> > +
> > +err_disable_apb:
> > +	clk_disable_unprepare(smipriv->clk_apb);
> > +err_put_pm:
> > +	pm_runtime_put(smidev);
> > +	return ret;
> > +}
> 
> [...]
> 
> > +int mtk_smi_larb_get(struct device *larbdev)
> > +{
> > +	struct mtk_smi_larb *larbpriv = dev_get_drvdata(larbdev);
> > +	struct mtk_larb_mmu *mmucfg = larbdev->archdata.iommu;
> > +	int ret;
> > +
> > +	ret = mtk_smi_common_get(larbpriv->smi);
> > +	if (ret)
> > +		return ret;
> > +
> > +	ret = pm_runtime_get_sync(larbdev);
> > +	if (ret < 0)
> > +		goto err_put_smicommon;
> > +
> > +	ret = clk_prepare_enable(larbpriv->clk_apb);
> > +	if (ret) {
> > +		dev_err(larbdev, "Failed to enable the apb clock\n");
> > +		goto err_put_pm;
> > +	}
> > +
> > +	ret = clk_prepare_enable(larbpriv->clk_smi);
> > +	if (ret) {
> > +		dev_err(larbdev, "Failed to enable the smi clock\n");
> > +		goto err_disable_apb;
> > +	}
> 
> The clock enablement looks similar to the function above, maybe move it
> to a helper function?

Thanks. I will improve it in next version.

> 
> 
> 	Joerg
> 




From oliver+list at schinagl.nl  Wed Aug 12 05:40:52 2015
From: oliver+list at schinagl.nl (Olliver Schinagl)
Date: Wed, 12 Aug 2015 14:40:52 +0200
Subject: [linux-sunxi] Re: [PATCH resend 1/3] mmc: sunxi: fix timeout
 in sunxi_mmc_oclk_onoff
In-Reply-To: <55CB3CD7.2050200@redhat.com>
References: <cover.1439381423.git.hramrach@gmail.com>
 <7f9c6f99b31702c02436ef3356b3ebffa4754260.1439381423.git.hramrach@gmail.com>
 <55CB3CD7.2050200@redhat.com>
Message-ID: <55CB3ED4.9000201@schinagl.nl>

While I can't speak for Michal obviously,

I left the debugging bit (in my v2 that i sent 2 minutes ago) as both 
you and Hans where content with it back then and both acked it.

Michal, feel free to send the v3 without the debug info, unless you want 
me to do it ;)

Olliver

On 12-08-15 14:32, Hans de Goede wrote:
> Hi,
>
> On 12-08-15 14:23, michal.suchanek at ruk.cuni.cz wrote:
>> The 250ms timeout is too short.
>>
>> On my system enabling the oclk takes under 50ms and disabling slightly
>> over 100ms when idle. Under load disabling the clock can take over
>> 350ms.
>>
>> This does not make mmc clock gating look like good option to have on
>> sunxi but the system should not crash with mmc clock gating enabled
>> nonetheless.
>>
>> This patch sets the timeout to 750ms and adds debug prints which show
>> how long enabling/disabling the clock took so more data can be collected
>> from other systems.
>>
>> Signed-off-by: Michal Suchanek <hramrach at gmail.com>
>
> This is a big patch for just changing a timeout, most of this is in
> extra verbosity which IMHO has little value, in the error path w
> know we will have waited aprox 750 ms, so printing the waiting
> time there is not worth all the extra code.
>
> As for adding the warning I'm even less of a big fan of that,
> if we need higher timeouts, we need higher timeouts, spamming the
> kernel logs with that we are actually hitting the higher timeouts
> is not productive IMHO.
>
> Can you please resend this as a one-liner just changing the timeout ?
>
> Regards,
>
> Hans
>
>
>>
>> -- 
>>
>>   - fix formatting
>> ---
>>   drivers/mmc/host/sunxi-mmc.c | 22 +++++++++++++++++++---
>>   1 file changed, 19 insertions(+), 3 deletions(-)
>>
>> diff --git a/drivers/mmc/host/sunxi-mmc.c b/drivers/mmc/host/sunxi-mmc.c
>> index 4d3e1ff..f808a02 100644
>> --- a/drivers/mmc/host/sunxi-mmc.c
>> +++ b/drivers/mmc/host/sunxi-mmc.c
>> @@ -595,7 +595,7 @@ static irqreturn_t 
>> sunxi_mmc_handle_manual_stop(int irq, void *dev_id)
>>
>>   static int sunxi_mmc_oclk_onoff(struct sunxi_mmc_host *host, u32 
>> oclk_en)
>>   {
>> -    unsigned long expire = jiffies + msecs_to_jiffies(250);
>> +    unsigned long start, end;
>>       u32 rval;
>>
>>       rval = mmc_readl(host, REG_CLKCR);
>> @@ -604,6 +604,8 @@ static int sunxi_mmc_oclk_onoff(struct 
>> sunxi_mmc_host *host, u32 oclk_en)
>>       if (oclk_en)
>>           rval |= SDXC_CARD_CLOCK_ON;
>>
>> +    start = jiffies;
>> +    end = start + msecs_to_jiffies(750);
>>       mmc_writel(host, REG_CLKCR, rval);
>>
>>       rval = SDXC_START | SDXC_UPCLK_ONLY | SDXC_WAIT_PRE_OVER;
>> @@ -611,15 +613,29 @@ static int sunxi_mmc_oclk_onoff(struct 
>> sunxi_mmc_host *host, u32 oclk_en)
>>
>>       do {
>>           rval = mmc_readl(host, REG_CMDR);
>> -    } while (time_before(jiffies, expire) && (rval & SDXC_START));
>> +    } while (time_before(jiffies, end) && (rval & SDXC_START));
>> +    end = jiffies;
>>
>>       /* clear irq status bits set by the command */
>>       mmc_writel(host, REG_RINTR,
>>              mmc_readl(host, REG_RINTR) & ~SDXC_SDIO_INTERRUPT);
>>
>>       if (rval & SDXC_START) {
>> -        dev_err(mmc_dev(host->mmc), "fatal err update clk timeout\n");
>> +        dev_err(mmc_dev(host->mmc),
>> +            "fatal err update oclk timeout. Could not %s in %ims.\n",
>> +            oclk_en ? "enable" : "disable",
>> +            jiffies_to_msecs(end - start));
>>           return -EIO;
>> +    } else {
>> +        int msecs = jiffies_to_msecs(end - start);
>> +        const char *ing = oclk_en ? "enabling" : "disabling";
>> +
>> +        if ((msecs > 150) || (oclk_en && (msecs > 50)))
>> +            dev_warn(mmc_dev(host->mmc),
>> +                 "%s oclk took %ims", ing, msecs);
>> +        else
>> +            dev_dbg(mmc_dev(host->mmc),
>> +                 "%s oclk took %ims", ing, msecs);
>>       }
>>
>>       return 0;
>>
>



From mpa at pengutronix.de  Wed Aug 12 05:47:06 2015
From: mpa at pengutronix.de (Markus Pargmann)
Date: Wed, 12 Aug 2015 14:47:06 +0200
Subject: [PATCH 14/20] regmap: Add raw_write/read checks for
 max_raw_write/read sizes
In-Reply-To: <20150812115759.GB10748@sirena.org.uk>
References: <1439374365-20623-1-git-send-email-mpa@pengutronix.de>
 <1439374365-20623-15-git-send-email-mpa@pengutronix.de>
 <20150812115759.GB10748@sirena.org.uk>
Message-ID: <20150812124706.GI19600@pengutronix.de>

On Wed, Aug 12, 2015 at 12:57:59PM +0100, Mark Brown wrote:
> On Wed, Aug 12, 2015 at 12:12:39PM +0200, Markus Pargmann wrote:
> 
> > Check in regmap_raw_read() and regmap_raw_write() for correct maximum
> > sizes of the operations. Return -E2BIG if this size is not supported
> > because it is too big.
> 
> Why not just split the transaction up like your other changes did?

My intention was to keep these raw functions as close to the actual
hardware as possible also reporting proper error values. For
transactions that are split up you could still use the bulk functions.

The actual use case is the bmc150 driver. This chip has a FIFO behind
one of its registers. At exactly that register there is no autoincrement
of the address or anything, it is just a much larger register. But you
have to read from it in bigger chunks than normal. If you read in
chunks that do not have the correct size samples from the sensor get
discarded.

> 
> > Also this patch causes an uninitialized variable warning so it
> > initializes ret (although not necessary).
> 
> That's just shutting the warning up without understanding where it came
> from or why this is a good way of handling it :(

Yes, will have a look if I can find the issue.

> 
> > @@ -2273,8 +2276,14 @@ int regmap_raw_read(struct regmap *map, unsigned int reg, void *val,
> >  
> >  	map->lock(map->lock_arg);
> >  
> > -	if (regmap_volatile_range(map, reg, val_count) || map->cache_bypass ||
> > -	    map->cache_type == REGCACHE_NONE) {
> > +	if (map->bus->read &&
> 
> This change doesn't match your commit log...

Sorry.

Thanks,

Markus



-- 
Pengutronix e.K.                           |                             |
Industrial Linux Solutions                 | http://www.pengutronix.de/  |
Peiner Str. 6-8, 31137 Hildesheim, Germany | Phone: +49-5121-206917-0    |
Amtsgericht Hildesheim, HRA 2686           | Fax:   +49-5121-206917-5555 |
-------------- next part --------------
A non-text attachment was scrubbed...
Name: signature.asc
Type: application/pgp-signature
Size: 819 bytes
Desc: Digital signature
URL: <http://lists.infradead.org/pipermail/linux-arm-kernel/attachments/20150812/a186bb60/attachment-0001.sig>

From mpa at pengutronix.de  Wed Aug 12 05:51:19 2015
From: mpa at pengutronix.de (Markus Pargmann)
Date: Wed, 12 Aug 2015 14:51:19 +0200
Subject: [PATCH 13/20] regmap: regmap max_raw_io getter function
In-Reply-To: <20150812115136.GA10748@sirena.org.uk>
References: <1439374365-20623-1-git-send-email-mpa@pengutronix.de>
 <1439374365-20623-14-git-send-email-mpa@pengutronix.de>
 <20150812115136.GA10748@sirena.org.uk>
Message-ID: <20150812125119.GJ19600@pengutronix.de>

On Wed, Aug 12, 2015 at 12:51:36PM +0100, Mark Brown wrote:
> On Wed, Aug 12, 2015 at 12:12:38PM +0200, Markus Pargmann wrote:
> > Signed-off-by: Markus Pargmann <mpa at pengutronix.de>
> 
> Your changelog doesn't mention why anything would reasonably want to use
> this and...

Right, this is used later in the driver code of bmc150 to find out how
much we can read from the sensor in one run.

> 
> > +size_t regmap_get_raw_io_max(struct regmap *map)
> > +{
> > +	return map->max_raw_io;
> > +}
> > +EXPORT_SYMBOL_GPL(regmap_get_raw_io_max);
> > +
> > +/**
> > + * regmap_get_raw_read_max - Get the maximum size we can read
> > + *
> > + * @map: Map to check.
> > + */
> 
> ...it is adding two functions which don't seem very symmetrically named.

Oh, this is half of my previous version where raw_read_max and
raw_write_max where separate. Will fix it along with your comment that
these should be different values for read and write.

Thanks,

Markus

> 
> > @@ -441,6 +441,8 @@ int regmap_get_max_register(struct regmap *map);
> >  int regmap_get_reg_stride(struct regmap *map);
> >  int regmap_async_complete(struct regmap *map);
> >  bool regmap_can_raw_write(struct regmap *map);
> > +size_t regmap_get_raw_write_max(struct regmap *map);
> > +size_t regmap_get_raw_io_max(struct regmap *map);
> 
> Do we want stubs here?



-- 
Pengutronix e.K.                           |                             |
Industrial Linux Solutions                 | http://www.pengutronix.de/  |
Peiner Str. 6-8, 31137 Hildesheim, Germany | Phone: +49-5121-206917-0    |
Amtsgericht Hildesheim, HRA 2686           | Fax:   +49-5121-206917-5555 |
-------------- next part --------------
A non-text attachment was scrubbed...
Name: signature.asc
Type: application/pgp-signature
Size: 819 bytes
Desc: Digital signature
URL: <http://lists.infradead.org/pipermail/linux-arm-kernel/attachments/20150812/9654dff2/attachment.sig>

From mpa at pengutronix.de  Wed Aug 12 05:52:02 2015
From: mpa at pengutronix.de (Markus Pargmann)
Date: Wed, 12 Aug 2015 14:52:02 +0200
Subject: [PATCH 15/20] regmap-i2c: Add smbus i2c block support
In-Reply-To: <20150812115936.GC10748@sirena.org.uk>
References: <1439374365-20623-1-git-send-email-mpa@pengutronix.de>
 <1439374365-20623-16-git-send-email-mpa@pengutronix.de>
 <20150812115936.GC10748@sirena.org.uk>
Message-ID: <20150812125202.GK19600@pengutronix.de>

On Wed, Aug 12, 2015 at 12:59:37PM +0100, Mark Brown wrote:
> On Wed, Aug 12, 2015 at 12:12:40PM +0200, Markus Pargmann wrote:
> 
> > +	if (count < 1 || count >= I2C_SMBUS_BLOCK_MAX)
> > +		return -EINVAL;
> 
> Elsewhere you added returns of -E2BIG if the transfer was too big, why
> not do that here as well?

Sounds good to use E2BIG here as well.

Best Regards,

Markus

-- 
Pengutronix e.K.                           |                             |
Industrial Linux Solutions                 | http://www.pengutronix.de/  |
Peiner Str. 6-8, 31137 Hildesheim, Germany | Phone: +49-5121-206917-0    |
Amtsgericht Hildesheim, HRA 2686           | Fax:   +49-5121-206917-5555 |
-------------- next part --------------
A non-text attachment was scrubbed...
Name: signature.asc
Type: application/pgp-signature
Size: 819 bytes
Desc: Digital signature
URL: <http://lists.infradead.org/pipermail/linux-arm-kernel/attachments/20150812/0c10fb64/attachment.sig>

From mpa at pengutronix.de  Wed Aug 12 05:52:56 2015
From: mpa at pengutronix.de (Markus Pargmann)
Date: Wed, 12 Aug 2015 14:52:56 +0200
Subject: [PATCH 17/20] iio: bmc150: Use i2c regmap
In-Reply-To: <20150812120146.GD10748@sirena.org.uk>
References: <1439374365-20623-1-git-send-email-mpa@pengutronix.de>
 <1439374365-20623-18-git-send-email-mpa@pengutronix.de>
 <20150812120146.GD10748@sirena.org.uk>
Message-ID: <20150812125256.GL19600@pengutronix.de>

On Wed, Aug 12, 2015 at 01:01:46PM +0100, Mark Brown wrote:
> On Wed, Aug 12, 2015 at 12:12:42PM +0200, Markus Pargmann wrote:
> 
> > +	select REGMAP
> > +	select REGMAP_I2C
> 
> You don't need to select regmap, only REGMAP_I2C.

Ok, thanks, will fix.

Best Regards,

Markus

-- 
Pengutronix e.K.                           |                             |
Industrial Linux Solutions                 | http://www.pengutronix.de/  |
Peiner Str. 6-8, 31137 Hildesheim, Germany | Phone: +49-5121-206917-0    |
Amtsgericht Hildesheim, HRA 2686           | Fax:   +49-5121-206917-5555 |
-------------- next part --------------
A non-text attachment was scrubbed...
Name: signature.asc
Type: application/pgp-signature
Size: 819 bytes
Desc: Digital signature
URL: <http://lists.infradead.org/pipermail/linux-arm-kernel/attachments/20150812/02310db8/attachment.sig>

From hramrach at gmail.com  Wed Aug 12 05:53:42 2015
From: hramrach at gmail.com (Michal Suchanek)
Date: Wed, 12 Aug 2015 14:53:42 +0200
Subject: [linux-sunxi] [PATCH 3/3] mmc: sunxi: use controller automatic
 clock gating.
In-Reply-To: <55CB3D92.6040403@redhat.com>
References: <cover.1439381423.git.hramrach@gmail.com>
 <c33b221f9b622e3bad9d855a7ad1887b82827244.1439381423.git.hramrach@gmail.com>
 <55CB3D92.6040403@redhat.com>
Message-ID: <CAOMqctSVN5y+Hs0_+aaZ=Gu_kr6_-1WONO585Y1bUEg79WJoAw@mail.gmail.com>

On 12 August 2015 at 14:35, Hans de Goede <hdegoede at redhat.com> wrote:
> Hi,
>
> On 12-08-15 14:23, Michal Suchanek wrote:
>>
>> When core does not set the MMC_QUIRK_BROKEN_CLK_GATING flag enable
>> automatic hardware controlled clock gating on the mmc interface.
>>
>> Signed-off-by: Michal Suchanek <hramrach at gmail.com>
>
>
> In general this looks good, but I wonder how intensively this has
> been tested ?

Unlike the wrong timeout it does not cause the boards to crash frequently ;-)

It would be nice if somebody actively using some board atm tested this.

> Also given the long latencies when using manual
> clock on/off support, have you done any testing to check what

I suspect the long latency is due to the controller flushing data to
the card or something like that since it happens only under load.

> sort of latencies this adds, e.g. Both with and without
> the patch, dump all the filesystem caches:
>
> echo 3 > /proc/sys/vm/drop_caches
>
> And then do:
>
> time cat /some/small/file/on/the/sdcard
>
> Do this at least 3 time both with and without the patch, and see
> if there are any noticable differences ?

Yes, it would be good idea to test.

Thanks

Michal


From eric.auger at linaro.org  Wed Aug 12 06:02:51 2015
From: eric.auger at linaro.org (Eric Auger)
Date: Wed, 12 Aug 2015 15:02:51 +0200
Subject: [PATCH v2 05/15] KVM: arm/arm64: make GIC frame address
 initialization model specific
In-Reply-To: <1436538111-4294-6-git-send-email-andre.przywara@arm.com>
References: <1436538111-4294-1-git-send-email-andre.przywara@arm.com>
 <1436538111-4294-6-git-send-email-andre.przywara@arm.com>
Message-ID: <55CB43FB.4070400@linaro.org>

On 07/10/2015 04:21 PM, Andre Przywara wrote:
> Currently we initialize all the possible GIC frame addresses in one
> function, without looking at the specific GIC model we instantiate
> for the guest.
> As this gets confusing when adding another VGIC model later, lets
> move these initializations into the respective model's init 
nit: tobe more precise the init emulation function (not the
vgic_v2/v3_init_model model's init function). pfouh?! ;-)
functions.
> 
> Signed-off-by: Andre Przywara <andre.przywara at arm.com>
> ---
>  virt/kvm/arm/vgic-v2-emul.c | 3 +++
>  virt/kvm/arm/vgic-v3-emul.c | 3 +++
>  virt/kvm/arm/vgic.c         | 3 ---
>  3 files changed, 6 insertions(+), 3 deletions(-)
> 
> diff --git a/virt/kvm/arm/vgic-v2-emul.c b/virt/kvm/arm/vgic-v2-emul.c
> index 1390797..8faa28c 100644
> --- a/virt/kvm/arm/vgic-v2-emul.c
> +++ b/virt/kvm/arm/vgic-v2-emul.c
> @@ -567,6 +567,9 @@ void vgic_v2_init_emulation(struct kvm *kvm)
>  	dist->vm_ops.init_model = vgic_v2_init_model;
>  	dist->vm_ops.map_resources = vgic_v2_map_resources;
>  
> +	dist->vgic_cpu_base = VGIC_ADDR_UNDEF;
> +	dist->vgic_dist_base = VGIC_ADDR_UNDEF;
Looks strange to see the common dist_base here. Why don't you leave it
in common part, kvm_vgic_create; all the more so you left
kvm->arch.vgic.vctrl_base = vgic->vctrl_base in kvm_vgic_create.

Eric
> +
>  	kvm->arch.max_vcpus = VGIC_V2_MAX_CPUS;
>  }
>  
> diff --git a/virt/kvm/arm/vgic-v3-emul.c b/virt/kvm/arm/vgic-v3-emul.c
> index d2eeb20..1f42348 100644
> --- a/virt/kvm/arm/vgic-v3-emul.c
> +++ b/virt/kvm/arm/vgic-v3-emul.c
> @@ -885,6 +885,9 @@ void vgic_v3_init_emulation(struct kvm *kvm)
>  	dist->vm_ops.destroy_model = vgic_v3_destroy_model;
>  	dist->vm_ops.map_resources = vgic_v3_map_resources;
>  
> +	dist->vgic_dist_base = VGIC_ADDR_UNDEF;
> +	dist->vgic_redist_base = VGIC_ADDR_UNDEF;
> +
>  	kvm->arch.max_vcpus = KVM_MAX_VCPUS;
>  }
>  
> diff --git a/virt/kvm/arm/vgic.c b/virt/kvm/arm/vgic.c
> index cc8f5ed..59f1801 100644
> --- a/virt/kvm/arm/vgic.c
> +++ b/virt/kvm/arm/vgic.c
> @@ -1830,9 +1830,6 @@ int kvm_vgic_create(struct kvm *kvm, u32 type)
>  	kvm->arch.vgic.in_kernel = true;
>  	kvm->arch.vgic.vgic_model = type;
>  	kvm->arch.vgic.vctrl_base = vgic->vctrl_base;
> -	kvm->arch.vgic.vgic_dist_base = VGIC_ADDR_UNDEF;
> -	kvm->arch.vgic.vgic_cpu_base = VGIC_ADDR_UNDEF;
> -	kvm->arch.vgic.vgic_redist_base = VGIC_ADDR_UNDEF;
>  
>  out_unlock:
>  	for (; vcpu_lock_idx >= 0; vcpu_lock_idx--) {
> 



From hramrach at gmail.com  Wed Aug 12 06:04:22 2015
From: hramrach at gmail.com (Michal Suchanek)
Date: Wed, 12 Aug 2015 15:04:22 +0200
Subject: [linux-sunxi] Re: [PATCH resend 1/3] mmc: sunxi: fix timeout in
 sunxi_mmc_oclk_onoff
In-Reply-To: <55CB3ED4.9000201@schinagl.nl>
References: <cover.1439381423.git.hramrach@gmail.com>
 <7f9c6f99b31702c02436ef3356b3ebffa4754260.1439381423.git.hramrach@gmail.com>
 <55CB3CD7.2050200@redhat.com> <55CB3ED4.9000201@schinagl.nl>
Message-ID: <CAOMqctRo8Kp6e33qVqVLNYt9pMmMAuoUHTwmqoBLGSpdQ_vu9Q@mail.gmail.com>

On 12 August 2015 at 14:40, Olliver Schinagl <oliver+list at schinagl.nl> wrote:

>
> On 12-08-15 14:32, Hans de Goede wrote:
>>
>> Hi,
>>
>> On 12-08-15 14:23, michal.suchanek at ruk.cuni.cz wrote:
>>>
>>> The 250ms timeout is too short.
>>>
>>> On my system enabling the oclk takes under 50ms and disabling slightly
>>> over 100ms when idle. Under load disabling the clock can take over
>>> 350ms.
>>>
>>> This does not make mmc clock gating look like good option to have on
>>> sunxi but the system should not crash with mmc clock gating enabled
>>> nonetheless.
>>>
>>> This patch sets the timeout to 750ms and adds debug prints which show
>>> how long enabling/disabling the clock took so more data can be collected
>>> from other systems.
>>>
>>> Signed-off-by: Michal Suchanek <hramrach at gmail.com>
>>
>>
>> This is a big patch for just changing a timeout, most of this is in
>> extra verbosity which IMHO has little value, in the error path w
>> know we will have waited aprox 750 ms, so printing the waiting
>> time there is not worth all the extra code.
>>
>> As for adding the warning I'm even less of a big fan of that,
>> if we need higher timeouts, we need higher timeouts, spamming the
>> kernel logs with that we are actually hitting the higher timeouts
>> is not productive IMHO.
>>
>> Can you please resend this as a one-liner just changing the timeout ?
>>

If we expect the timeout to be short and it isn't that means something is wrong.

The user is probably experiencing degraded performance in that case so
it's good to have a diagnostic for it IMHO.

Yes, printing of the timeout in the error case does not have that much
value but since it's calculated anyway I just pasted it there.

> While I can't speak for Michal obviously,
>
> I left the debugging bit (in my v2 that i sent 2 minutes ago) as both you
> and Hans where content with it back then and both acked it.
>
> Michal, feel free to send the v3 without the debug info, unless you want me
> to do it ;)
>

I don't really care either way so long as the boards do not crash.

Thanks

Michal


From mpa at pengutronix.de  Wed Aug 12 06:05:18 2015
From: mpa at pengutronix.de (Markus Pargmann)
Date: Wed, 12 Aug 2015 15:05:18 +0200
Subject: [PATCH 09/20] regmap: _regmap_raw_write fix for busses without
 write()
In-Reply-To: <20150812123406.GG10748@sirena.org.uk>
References: <1439374365-20623-1-git-send-email-mpa@pengutronix.de>
 <1439374365-20623-10-git-send-email-mpa@pengutronix.de>
 <20150812112035.GX10748@sirena.org.uk>
 <20150812122011.GE19600@pengutronix.de>
 <20150812123406.GG10748@sirena.org.uk>
Message-ID: <20150812130518.GM19600@pengutronix.de>

On Wed, Aug 12, 2015 at 01:34:06PM +0100, Mark Brown wrote:
> On Wed, Aug 12, 2015 at 02:20:11PM +0200, Markus Pargmann wrote:
> > On Wed, Aug 12, 2015 at 12:20:35PM +0100, Mark Brown wrote:
> > > On Wed, Aug 12, 2015 at 12:12:34PM +0200, Markus Pargmann wrote:
> > > 
> > > > @@ -1229,6 +1229,11 @@ int _regmap_raw_write(struct regmap *map, unsigned int reg,
> > > >  		}
> > > >  	}
> > > >  
> > > > +	if (!map->bus->write && val_len == map->format.val_bytes) {
> > > > +		ret = _regmap_bus_reg_write(map, reg, *(unsigned int *)val);
> > > > +		return ret;
> > > > +	}
> 
> > > This is broken - you can't use a raw value as a register value.  The
> 
> > I am not sure what you mean here?
> 
> > The register value given to _regmap_raw_write is the real register
> > value, not formatted differenty. This is given directly towards
> > bus->reg_write() which should handle the rest.
> 
> I mean the value for the register, not the register address.
> 
> > At least that's how I understood the code. For example regmap_read()
> > directly calls _regmap_read() which in turn calls directly
> > bus->reg_read() without any formating.
> 
> You're adding this code to regmap_raw_write() which takes raw register
> values for the device, not unsigned integers.

Ah yes, I see.

> 
> > > endianness of the device may not be the same as the endianness of the
> > > system and you can't cast a value to unsigned int, the value may be of
> > > any size.
> 
> > Yes right. On the other hand if bus->read() and bus->write() was not set
> > in the init method (before this patch series) no formatting functions at
> > all were assigned. So it was always ignored for bus->reg_read() and
> > bus->reg_write()?!
> 
> I'm not sure what the "it" you're talking about here is, sorry.  There
> are unsupported features in the API especially for cases that don't make
> a huge amount of sense, the error handling isn't always complete.  It
> sounds like you might be trying to support one of these nonsensical
> cases - it's not obvious what raw I/O on a device where we don't know
> the raw format of the device should mean or how anything could sensibly
> use that.

The bus and the regmap user are separate. So as a regmap user, I am not
able to know if the bus the device is connected to actually supports raw
reads/writes. At least it should not fail with a null pointer when using
these functions anyway so yes error handling is missing a bit here.

Also the real use of this function is regmap_bulk_write() which always
uses _regmap_raw_write() regardless of a missing bus->write() function.
So regmap_bulk_write will fail for those as well and this should be
supported.

But it is probably better to handle this in regmap_bulk_write() and
add a simple check for bus->write() here.

Best Regards,

Markus

-- 
Pengutronix e.K.                           |                             |
Industrial Linux Solutions                 | http://www.pengutronix.de/  |
Peiner Str. 6-8, 31137 Hildesheim, Germany | Phone: +49-5121-206917-0    |
Amtsgericht Hildesheim, HRA 2686           | Fax:   +49-5121-206917-5555 |
-------------- next part --------------
A non-text attachment was scrubbed...
Name: signature.asc
Type: application/pgp-signature
Size: 819 bytes
Desc: Digital signature
URL: <http://lists.infradead.org/pipermail/linux-arm-kernel/attachments/20150812/a9d32853/attachment.sig>

From mpa at pengutronix.de  Wed Aug 12 06:08:38 2015
From: mpa at pengutronix.de (Markus Pargmann)
Date: Wed, 12 Aug 2015 15:08:38 +0200
Subject: [PATCH 02/20] regmap: Remove regmap_bulk_write 64bit support
In-Reply-To: <20150812123537.GH10748@sirena.org.uk>
References: <1439374365-20623-1-git-send-email-mpa@pengutronix.de>
 <1439374365-20623-3-git-send-email-mpa@pengutronix.de>
 <20150812102550.GQ10748@sirena.org.uk>
 <20150812104436.GA19600@pengutronix.de>
 <20150812105758.GU10748@sirena.org.uk>
 <20150812122856.GF19600@pengutronix.de>
 <20150812123537.GH10748@sirena.org.uk>
Message-ID: <20150812130838.GN19600@pengutronix.de>

On Wed, Aug 12, 2015 at 01:35:37PM +0100, Mark Brown wrote:
> On Wed, Aug 12, 2015 at 02:28:56PM +0200, Markus Pargmann wrote:
> 
> > Ok, would work for me as well although sizeof is not a preprocessor
> > macro so I would probably leave it as it is. The whole regmap framework
> > just didn't seem to support 64bit so I thought this was just not
> > working.
> 
> I'd expect the framework to cope with things when ints are 64 bit.  We
> don't try to support anything else, though.

For all non-busses it probably will. All the format functions are not
working for 64bit at the moment. But that's something different, also I
didn't see a bus device with 64bit yet.

Best Regards,

Markus

-- 
Pengutronix e.K.                           |                             |
Industrial Linux Solutions                 | http://www.pengutronix.de/  |
Peiner Str. 6-8, 31137 Hildesheim, Germany | Phone: +49-5121-206917-0    |
Amtsgericht Hildesheim, HRA 2686           | Fax:   +49-5121-206917-5555 |
-------------- next part --------------
A non-text attachment was scrubbed...
Name: signature.asc
Type: application/pgp-signature
Size: 819 bytes
Desc: Digital signature
URL: <http://lists.infradead.org/pipermail/linux-arm-kernel/attachments/20150812/f8619d20/attachment.sig>

From yamada.masahiro at socionext.com  Wed Aug 12 06:14:18 2015
From: yamada.masahiro at socionext.com (Masahiro Yamada)
Date: Wed, 12 Aug 2015 22:14:18 +0900
Subject: [PATCH 3/3] ARM: dts: UniPhier: add ProXstream2 and PH1-LD6b
 SoC/board support
In-Reply-To: <20150811130739.GD30181@localhost>
References: <1438687264-26538-1-git-send-email-yamada.masahiro@socionext.com>
 <1438687264-26538-4-git-send-email-yamada.masahiro@socionext.com>
 <20150811130739.GD30181@localhost>
Message-ID: <CAK7LNAQ+6tQ9Ci6LKsAB7kLj0o60Hizo2gOokDH9qW=FnO0gEA@mail.gmail.com>

Hi Olof,


2015-08-11 22:07 GMT+09:00 Olof Johansson <olof at lixom.net>:
> Hi,
>
> On Tue, Aug 04, 2015 at 08:21:04PM +0900, Masahiro Yamada wrote:
>> Initial version of DTSI for ProXstream2 and PH1-LD6b and DTS for
>> PH1-LD6b reference board.
>>
>> Signed-off-by: Masahiro Yamada <yamada.masahiro at socionext.com>
>> ---
>>
>>  arch/arm/boot/dts/Makefile                  |   3 +-
>>  arch/arm/boot/dts/uniphier-ph1-ld6b-ref.dts | 105 +++++++++++
>>  arch/arm/boot/dts/uniphier-ph1-ld6b.dtsi    |  67 +++++++
>>  arch/arm/boot/dts/uniphier-proxstream2.dtsi | 273 ++++++++++++++++++++++++++++
>>  4 files changed, 447 insertions(+), 1 deletion(-)
>>  create mode 100644 arch/arm/boot/dts/uniphier-ph1-ld6b-ref.dts
>>  create mode 100644 arch/arm/boot/dts/uniphier-ph1-ld6b.dtsi
>>  create mode 100644 arch/arm/boot/dts/uniphier-proxstream2.dtsi
>>
>> diff --git a/arch/arm/boot/dts/Makefile b/arch/arm/boot/dts/Makefile
>> index 246473a..6eb3f2f 100644
>> --- a/arch/arm/boot/dts/Makefile
>> +++ b/arch/arm/boot/dts/Makefile
>> @@ -645,7 +645,8 @@ dtb-$(CONFIG_ARCH_UNIPHIER) += \
>>       uniphier-ph1-sld3-ref.dtb \
>>       uniphier-ph1-ld4-ref.dtb \
>>       uniphier-ph1-pro4-ref.dtb \
>> -     uniphier-ph1-sld8-ref.dtb
>> +     uniphier-ph1-sld8-ref.dtb \
>> +     uniphier-ph1-ld6b-ref.dtb
>
> Please always add entries here sorted, don't just append. I've fixed it
> up for you this time.
>
>

Please do not do that (without my ack).

It was already sorted from old SoC to new SoC.

Sorting chronologically (in other words, in the order of chip ID)
makes more sense than sorting alphabetically.



-- 
Best Regards
Masahiro Yamada


From mpa at pengutronix.de  Wed Aug 12 06:17:50 2015
From: mpa at pengutronix.de (Markus Pargmann)
Date: Wed, 12 Aug 2015 15:17:50 +0200
Subject: [PATCH 10/20] regmap: _regmap_raw_multi_reg_write: Add
 reg_write() support
In-Reply-To: <20150812123923.GI10748@sirena.org.uk>
References: <1439374365-20623-1-git-send-email-mpa@pengutronix.de>
 <1439374365-20623-11-git-send-email-mpa@pengutronix.de>
 <20150812123923.GI10748@sirena.org.uk>
Message-ID: <20150812131750.GO19600@pengutronix.de>

On Wed, Aug 12, 2015 at 01:39:23PM +0100, Mark Brown wrote:
> On Wed, Aug 12, 2015 at 12:12:35PM +0200, Markus Pargmann wrote:
> > Define a fallback for busses which do not define a write() function.
> > Instead we write one register at a time using reg_write().
> > 
> > Without this patch, _regmap_raw_multi_reg_write would break as it tries
> > to call bus->write() without checking if it exists before.
> 
> Why are we trying to use multi write APIs in the first place if we can't
> do raw I/O?

Because we may not know if the bus supports raw IO and I would prefer
if it is not necessary to know in the driver that just uses the regmap
API if the underlying bus supports it.

Sorry this patch is wrong, instead it should set can_multi_write
properly depending on the availability of map->bus->write(). The code
would already handle multi writes then.

Thanks,

Markus

-- 
Pengutronix e.K.                           |                             |
Industrial Linux Solutions                 | http://www.pengutronix.de/  |
Peiner Str. 6-8, 31137 Hildesheim, Germany | Phone: +49-5121-206917-0    |
Amtsgericht Hildesheim, HRA 2686           | Fax:   +49-5121-206917-5555 |
-------------- next part --------------
A non-text attachment was scrubbed...
Name: signature.asc
Type: application/pgp-signature
Size: 819 bytes
Desc: Digital signature
URL: <http://lists.infradead.org/pipermail/linux-arm-kernel/attachments/20150812/24bf2036/attachment.sig>

From oliver+list at schinagl.nl  Wed Aug 12 06:19:20 2015
From: oliver+list at schinagl.nl (Olliver Schinagl)
Date: Wed, 12 Aug 2015 15:19:20 +0200
Subject: [linux-sunxi] [PATCH 3/3] mmc: sunxi: use controller automatic
 clock gating.
In-Reply-To: <55CB3D92.6040403@redhat.com>
References: <cover.1439381423.git.hramrach@gmail.com>
 <c33b221f9b622e3bad9d855a7ad1887b82827244.1439381423.git.hramrach@gmail.com>
 <55CB3D92.6040403@redhat.com>
Message-ID: <55CB47D8.4010207@schinagl.nl>

Hey,

On 12-08-15 14:35, Hans de Goede wrote:
> Hi,
>
> On 12-08-15 14:23, Michal Suchanek wrote:
>> When core does not set the MMC_QUIRK_BROKEN_CLK_GATING flag enable
>> automatic hardware controlled clock gating on the mmc interface.
>>
>> Signed-off-by: Michal Suchanek <hramrach at gmail.com>
>
> In general this looks good, but I wonder how intensively this has
> been tested ?
It doesn't matter actually, it took some time longer, but the mmc still 
craps out even with Michal's 3 patches. I'll revert hans's earlier patch 
again and do a bit more extensive testing.
> Also given the long latencies when using manual
> clock on/off support, have you done any testing to check what
> sort of latencies this adds, e.g. Both with and without
> the patch, dump all the filesystem caches:
>
> echo 3 > /proc/sys/vm/drop_caches
>
> And then do:
>
> time cat /some/small/file/on/the/sdcard
>
> Do this at least 3 time both with and without the patch, and see
> if there are any noticable differences ?
>
> Regards,
>
> Hans
>
>
>
>> ---
>>   drivers/mmc/host/sunxi-mmc.c | 7 ++++++-
>>   1 file changed, 6 insertions(+), 1 deletion(-)
>>
>> diff --git a/drivers/mmc/host/sunxi-mmc.c b/drivers/mmc/host/sunxi-mmc.c
>> index f808a02..443cab5 100644
>> --- a/drivers/mmc/host/sunxi-mmc.c
>> +++ b/drivers/mmc/host/sunxi-mmc.c
>> @@ -601,8 +601,13 @@ static int sunxi_mmc_oclk_onoff(struct 
>> sunxi_mmc_host *host, u32 oclk_en)
>>       rval = mmc_readl(host, REG_CLKCR);
>>       rval &= ~(SDXC_CARD_CLOCK_ON | SDXC_LOW_POWER_ON);
>>
>> -    if (oclk_en)
>> +    if (oclk_en) {
>>           rval |= SDXC_CARD_CLOCK_ON;
>> +        if (!host->mmc->card ||
>> +             !(host->mmc->card->quirks & MMC_QUIRK_BROKEN_CLK_GATING))
>> +
>> +            rval |= SDXC_LOW_POWER_ON;
>> +    }
>>
>>       start = jiffies;
>>       end = start + msecs_to_jiffies(750);
>>
>



From horia.geanta at freescale.com  Wed Aug 12 06:20:41 2015
From: horia.geanta at freescale.com (=?UTF-8?Q?Horia_Geant=c4=83?=)
Date: Wed, 12 Aug 2015 16:20:41 +0300
Subject: [PATCH v3] ARM: configs: Add Freescale LS1021A defconfig
In-Reply-To: <1438941784-38403-1-git-send-email-b18965@freescale.com>
References: <1438941784-38403-1-git-send-email-b18965@freescale.com>
Message-ID: <55CB4829.40204@freescale.com>

On 8/7/2015 1:03 PM, Alison Wang wrote:
> Add Freescale LS1021A initial defconfig file.
> The LS1021A SoC is a dual-core Cortex-A7 based processor.
> 
> LS1021A has some special configure options against common V7 SOCs,
> such as CONFIG_THUMB2_KERNEL, CONFIG_VMSPLIT_2G, CONFIG_VFP...
> 
> Enable I2C, LPUART, eDMA, WDT, GIANFAR, Sound, DSPI at default.
> 
> Signed-off-by: Haikun Wang <haikun.wang at freescale.com>
> Signed-off-by: Alison Wang <alison.wang at freescale.com>
> ---
> Changes since v2:
> - Enable PSCI, as PSCI is enabled in u-boot.
> Changes since v1:
> - Enable GIANFAR, Sound and DSPI.

Looks like CONFIG_ARCH_DMA_ADDR_T_64BIT=y is missing.
For e.g. CAAM (crypto engine) is a DMA device able to use 40-bit bus
addresses.
Note that ARCH_DMA_ADDR_T_64BIT does not depend / is not selected by
ARM_LPAE.

Thanks,
Horia




From sjg at chromium.org  Wed Aug 12 06:21:32 2015
From: sjg at chromium.org (Simon Glass)
Date: Wed, 12 Aug 2015 07:21:32 -0600
Subject: [PATCH] arm: rpi: Device tree modifications for U-Boot
In-Reply-To: <1439312701.2451.3.camel@lynxeye.de>
References: <1439303153-12171-1-git-send-email-sjg@chromium.org>
 <1439312701.2451.3.camel@lynxeye.de>
Message-ID: <CAPnjgZ3ztXnkxZJvitiXiKMzq5+x46hbv0PW4HcF7yGgsXUV+Q@mail.gmail.com>

Hi Lucas,

On 11 August 2015 at 11:05, Lucas Stach <dev at lynxeye.de> wrote:
> Hi Simon,
>
> why did you send this to the Tegra ML?
>
> Am Dienstag, den 11.08.2015, 08:25 -0600 schrieb Simon Glass:
>> This updates the device tree from the kernel version to something suitable
>> for U-Boot:
>>
>> - Add stdout-path alias for console
>> - Mark the /soc node to be available pre-relocation so that the early
>> serial console works (we need the 'ranges' property to be available)
>>
>> Signed-off-by: Simon Glass <sjg at chromium.org>
>> ---
>>
>>  arch/arm/boot/dts/bcm2835.dtsi | 4 +++-
>>  1 file changed, 3 insertions(+), 1 deletion(-)
>>
>> diff --git a/arch/arm/boot/dts/bcm2835.dtsi b/arch/arm/boot/dts/bcm2835.dtsi
>> index 301c73f..bd6bff6 100644
>> --- a/arch/arm/boot/dts/bcm2835.dtsi
>> +++ b/arch/arm/boot/dts/bcm2835.dtsi
>> @@ -8,6 +8,7 @@
>>
>>       chosen {
>>               bootargs = "earlyprintk console=ttyAMA0";
>> +             stdout-path = &uart;
>>       };
>>
>>       soc {
>> @@ -16,6 +17,7 @@
>>               #size-cells = <1>;
>>               ranges = <0x7e000000 0x20000000 0x02000000>;
>>               dma-ranges = <0x40000000 0x00000000 0x20000000>;
>> +             u-boot,dm-pre-reloc;
>
> Why do you need this and why should upstream carry your favourite
> bootloaders configuration? This is in no way hardware description.

I'm not sure how much you know about U-Boot, so let me know if you
need more info.

U-Boot normally starts up by setting up its serial UART and displaying
a banner message. At this stage typically only a few devices are
initialised (e.g. maybe just the UART). It then relocates itself to
the top of memory and starts up all the devices. It throws away any
previous devices that it set up before relocation and starts again.

U-Boot uses a thing called driver model (dm) which handles driver
binding and probing. Driver model has the device tree and would
normally scan through it and create devices for everything it finds.

Before relocation we don't need every device. Also the CPU is often
running slowly, perhaps without the cache enabled. SDRAM may not be
available yet so space is short. We want to avoid starting up things
that will not be used.

So this property indicates that the device is needed before relocation
and should be set up by driver model. We need it to avoid a very slow
and memory-hungry startup.

As to why upstream should accept it, my understanding of upstream is
that people can send patches to it and in fact are encouraged to do
so, to avoid misunderstandings and duplication. The device tree files
are stored in Linux so any binding or source file changes should end
up there. Otherwise the files tend to diverge and we end up with
multiple bindings and multiple versions of the same source file.

Regards,
Simon


From maitysanchayan at gmail.com  Wed Aug 12 06:19:17 2015
From: maitysanchayan at gmail.com (Sanchayan Maity)
Date: Wed, 12 Aug 2015 18:49:17 +0530
Subject: [PATCH v9 0/4] Implement OCOTP driver for Vybrid using NVMEM
Message-ID: <cover.1439384645.git.maitysanchayan@gmail.com>

Hello,

This patchset is based on top of v9 of Srinivas's NVMEM framework patches.
Tested on Greg's tree char-misc-next branch along with Stefan's NAND driver
patchset.

Sample output on Colibri VF50

root at colibri-vf:/sys/bus/nvmem/devices/ocotp0# uname -a
Linux colibri-vf 4.2.0-rc6-00130-g24fcfdc #3 SMP Wed Aug 12 18:31:24 IST 2015 armv7l GNU/Linux

root at colibri-vf:/sys/bus/nvmem/devices/ocotp0# hexdump nvmem
0000000 0000 0000 0000 0000 0000 0000 0000 0000
*
0000410 72a6 df64 0000 0000 0000 0000 0000 0000
0000420 11d4 2c14 0000 0000 0000 0000 0000 0000
0000430 0000 0000 0000 0000 0000 0000 0000 0000
*
0000450 0280 0000 0000 0000 0000 0000 0000 0000
0000460 0000 0000 0000 0000 0000 0000 0000 0000
*
0000880 8f01 0000 0000 0000 0000 0000 0000 0000
0000890 0000 0000 0000 0000 0000 0000 0000 0000
*
00008c0 0000 1000 0000 0000 0000 0000 0000 0000
00008d0 3202 0800 0000 0000 0000 0000 0000 0000
00008e0 0000 e100 0000 0000 0000 0000 0000 0000
00008f0 0000 0000 0000 0000 0000 0000 0000 0000
*
0000c80 bada bada 0000 0000 0000 0000 0000 0000
*
0000cc0 0000 0000 0000 0000 0000 0000 0000 0000
*
0000cf0

The driver has changed quite a bit from the first version
relying on of_platform_populate in mach file, to using
SoC driver under drivers/soc and finally to NVMEM.

Feedback and comments most welcome.

Version 8 patches can be found here
https://lkml.org/lkml/2015/8/10/566

Version 7 patches can be found here
https://lkml.org/lkml/2015/8/6/440

Version 6 RFC patches can be found here
http://lkml.iu.edu/hypermail/linux/kernel/1506.2/05123.html

Version 5 of the patchset can be found here
http://lkml.iu.edu/hypermail/linux/kernel/1506.0/03787.html

Version 4 of the patchset can be found here
https://lkml.org/lkml/2015/5/26/199

Version 3 of the patchset can be found here
http://www.spinics.net/lists/arm-kernel/msg420847.html

Version 2 of the patchset can be found here
http://www.spinics.net/lists/devicetree/msg80654.html

Version 1 of the patchset can be found here
http://www.spinics.net/lists/devicetree/msg80257.html

The RFC version can be found here
https://lkml.org/lkml/2015/5/11/13

Changes since v8:
1. Fix three lines over 80 characters
2. Rebase on top of Greg's char-misc-next branch

Changes since v7:
1. Add COMPILE_TEST to Kconfig
2. Use GENMASK and BIT macros where applicable
3. Fix a code alignment issue
4. Get the max_register value for regmap config using
resource_size()
5. Also add copyright info as the driver logic is based off
on ocotp code in barebox
6. Add missing info related to clock in DT binding doc

Changes since v6:
1. Use the v9 of NVMEM framework patchset
2. Add a few comments
3. Initialise buffer address not part of the fuse map to 0
instead of only handling buffer locations with valid fuse
addresses.

Changes since v5:
Use NVMEM framework by Srinivas and Maxime

Changes since v4:
1. Use devm_* family of functions and use a struct to get rid of
global variables (suggested by Joachim Eastwood)
2. Make Kconfig govern the compilation with tristate, instead of
earlier bool. Paul Bolle raised a valid point that perhaps this
should have been built in with the bool, however I had not taken
into consideration generic distro kernels and it makes sense to
have this tristated. (comments from Paul Bolle and Andreas Farber)

Changes since v3:
Instead of using the syscon_regmap_lookup_by_compatible function
use a phandle in the device tree along with offsets specified in
this phandle node and then read the offset along with the device
node in the driver for reading from the required region.

Changes since v2:
Implement the SoC bus code as a driver in drivers/soc
by registering with fsl,mscm-cpucfg as per Arnd's feedback

Changes since v1:
Sort the headers in alphabetical order

Changes since RFC:
Use a DT entry for the ROM area while specifying it as syscon.

Thanks & Regards,
Sanchayan Maity.

Sanchayan Maity (4):
  clk: clk-vf610: Add clock for Vybrid OCOTP controller
  ARM: dts: vfxxx: Add OCOTP node
  drivers: nvmem: Add Vybrid OCOTP support
  nvmem: Add DT binding documentation for Vybrid OCOTP driver

 .../devicetree/bindings/nvmem/vf610-ocotp.txt      |  21 ++
 arch/arm/boot/dts/vfxxx.dtsi                       |   9 +
 drivers/clk/imx/clk-vf610.c                        |   1 +
 drivers/nvmem/Kconfig                              |  10 +
 drivers/nvmem/Makefile                             |   2 +
 drivers/nvmem/vf610-ocotp.c                        | 302 +++++++++++++++++++++
 include/dt-bindings/clock/vf610-clock.h            |   3 +-
 7 files changed, 347 insertions(+), 1 deletion(-)
 create mode 100644 Documentation/devicetree/bindings/nvmem/vf610-ocotp.txt
 create mode 100644 drivers/nvmem/vf610-ocotp.c

-- 
2.5.0



From maitysanchayan at gmail.com  Wed Aug 12 06:19:18 2015
From: maitysanchayan at gmail.com (Sanchayan Maity)
Date: Wed, 12 Aug 2015 18:49:18 +0530
Subject: [PATCH v9 1/4] clk: clk-vf610: Add clock for Vybrid OCOTP controller
In-Reply-To: <cover.1439384645.git.maitysanchayan@gmail.com>
References: <cover.1439384645.git.maitysanchayan@gmail.com>
Message-ID: <e38870196e689bd4edcaf43f36df899d63a6851c.1439384645.git.maitysanchayan@gmail.com>

Add clock support for Vybrid On-Chip One Time Programmable
(OCOTP) controller.

While the OCOTP block does not require explicit clock gating,
for programming the OCOTP timing register the clock rate of
ipg clock is required for timing calculations related to fuse
and shadow register read sequence. We explicitly specify the
ipg clock for OCOTP as a result.

Signed-off-by: Sanchayan Maity <maitysanchayan at gmail.com>
---
 drivers/clk/imx/clk-vf610.c             | 1 +
 include/dt-bindings/clock/vf610-clock.h | 3 ++-
 2 files changed, 3 insertions(+), 1 deletion(-)

diff --git a/drivers/clk/imx/clk-vf610.c b/drivers/clk/imx/clk-vf610.c
index bff45ea..d1b1c95 100644
--- a/drivers/clk/imx/clk-vf610.c
+++ b/drivers/clk/imx/clk-vf610.c
@@ -387,6 +387,7 @@ static void __init vf610_clocks_init(struct device_node *ccm_node)
 
 	clk[VF610_CLK_SNVS] = imx_clk_gate2("snvs-rtc", "ipg_bus", CCM_CCGR6, CCM_CCGRx_CGn(7));
 	clk[VF610_CLK_DAP] = imx_clk_gate("dap", "platform_bus", CCM_CCSR, 24);
+	clk[VF610_CLK_OCOTP] = imx_clk_gate("ocotp", "ipg_bus", CCM_CCGR6, CCM_CCGRx_CGn(5));
 
 	imx_check_clocks(clk, ARRAY_SIZE(clk));
 
diff --git a/include/dt-bindings/clock/vf610-clock.h b/include/dt-bindings/clock/vf610-clock.h
index d197634..56c16aa 100644
--- a/include/dt-bindings/clock/vf610-clock.h
+++ b/include/dt-bindings/clock/vf610-clock.h
@@ -194,6 +194,7 @@
 #define VF610_PLL7_BYPASS		181
 #define VF610_CLK_SNVS			182
 #define VF610_CLK_DAP			183
-#define VF610_CLK_END			184
+#define VF610_CLK_OCOTP         184
+#define VF610_CLK_END			185
 
 #endif /* __DT_BINDINGS_CLOCK_VF610_H */
-- 
2.5.0



From maitysanchayan at gmail.com  Wed Aug 12 06:19:19 2015
From: maitysanchayan at gmail.com (Sanchayan Maity)
Date: Wed, 12 Aug 2015 18:49:19 +0530
Subject: [PATCH v9 2/4] ARM: dts: vfxxx: Add OCOTP node
In-Reply-To: <cover.1439384645.git.maitysanchayan@gmail.com>
References: <cover.1439384645.git.maitysanchayan@gmail.com>
Message-ID: <e633124a9b343d89742d6ece18814742189229ce.1439384645.git.maitysanchayan@gmail.com>

Add device tree node for the On-Chip One Time Programmable
controller (OCOTP) on the Vybrid platform.

Signed-off-by: Sanchayan Maity <maitysanchayan at gmail.com>
---
 arch/arm/boot/dts/vfxxx.dtsi | 9 +++++++++
 1 file changed, 9 insertions(+)

diff --git a/arch/arm/boot/dts/vfxxx.dtsi b/arch/arm/boot/dts/vfxxx.dtsi
index 2f4b04d..ee06c12 100644
--- a/arch/arm/boot/dts/vfxxx.dtsi
+++ b/arch/arm/boot/dts/vfxxx.dtsi
@@ -403,6 +403,15 @@
 				status = "disabled";
 			};
 
+			ocotp: ocotp at 400a5000 {
+				compatible = "fsl,vf610-ocotp";
+				#address-cells = <1>;
+				#size-cells = <1>;
+				reg = <0x400a5000 0xCF0>;
+				clocks = <&clks VF610_CLK_OCOTP>;
+				clock-names = "ocotp";
+			};
+
 			snvs0: snvs at 400a7000 {
 			    compatible = "fsl,sec-v4.0-mon", "simple-bus";
 				#address-cells = <1>;
-- 
2.5.0



From maitysanchayan at gmail.com  Wed Aug 12 06:19:20 2015
From: maitysanchayan at gmail.com (Sanchayan Maity)
Date: Wed, 12 Aug 2015 18:49:20 +0530
Subject: [PATCH v9 3/4] drivers: nvmem: Add Vybrid OCOTP support
In-Reply-To: <cover.1439384645.git.maitysanchayan@gmail.com>
References: <cover.1439384645.git.maitysanchayan@gmail.com>
Message-ID: <c6e32b85e71e03b8f0f844b857285c1d26f2d834.1439384645.git.maitysanchayan@gmail.com>

The patch adds support for the On Chip One Time Programmable Peripheral
(OCOTP) on the Vybrid platform.

Signed-off-by: Sanchayan Maity <maitysanchayan at gmail.com>
Acked-by: Srinivas Kandagatla <srinivas.kandagatla at linaro.org>
---
 drivers/nvmem/Kconfig       |  10 ++
 drivers/nvmem/Makefile      |   2 +
 drivers/nvmem/vf610-ocotp.c | 302 ++++++++++++++++++++++++++++++++++++++++++++
 3 files changed, 314 insertions(+)
 create mode 100644 drivers/nvmem/vf610-ocotp.c

diff --git a/drivers/nvmem/Kconfig b/drivers/nvmem/Kconfig
index 8db2978..1d4f2b4 100644
--- a/drivers/nvmem/Kconfig
+++ b/drivers/nvmem/Kconfig
@@ -36,4 +36,14 @@ config NVMEM_SUNXI_SID
 	  This driver can also be built as a module. If so, the module
 	  will be called nvmem_sunxi_sid.
 
+config NVMEM_VF610_OCOTP
+	tristate "VF610 SoC OCOTP support"
+	depends on SOC_VF610 || COMPILE_TEST
+	help
+	  This is a driver for the 'OCOTP' peripheral available on Vybrid
+	  devices like VF5xx and VF6xx.
+
+	  This driver can also be build as a module. If so, the module will
+	  be called nvmem-vf610-ocotp.
+
 endif
diff --git a/drivers/nvmem/Makefile b/drivers/nvmem/Makefile
index 4328b93..3bdcfd4 100644
--- a/drivers/nvmem/Makefile
+++ b/drivers/nvmem/Makefile
@@ -10,3 +10,5 @@ obj-$(CONFIG_QCOM_QFPROM)	+= nvmem_qfprom.o
 nvmem_qfprom-y			:= qfprom.o
 obj-$(CONFIG_NVMEM_SUNXI_SID)	+= nvmem_sunxi_sid.o
 nvmem_sunxi_sid-y		:= sunxi_sid.o
+obj-$(CONFIG_NVMEM_VF610_OCOTP)	+= nvmem-vf610-ocotp.o
+nvmem-vf610-ocotp-y		:= vf610-ocotp.o
diff --git a/drivers/nvmem/vf610-ocotp.c b/drivers/nvmem/vf610-ocotp.c
new file mode 100644
index 0000000..66acd69
--- /dev/null
+++ b/drivers/nvmem/vf610-ocotp.c
@@ -0,0 +1,302 @@
+/*
+ * Copyright (C) 2015 Toradex AG.
+ *
+ * Author: Sanchayan Maity <sanchayan.maity at toradex.com>
+ *
+ * Based on the barebox ocotp driver,
+ * Copyright (c) 2010 Baruch Siach <baruch at tkos.co.il>
+ *	Orex Computed Radiography
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License version 2 and
+ * only 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/clk.h>
+#include <linux/delay.h>
+#include <linux/device.h>
+#include <linux/io.h>
+#include <linux/module.h>
+#include <linux/nvmem-provider.h>
+#include <linux/of.h>
+#include <linux/platform_device.h>
+#include <linux/regmap.h>
+#include <linux/slab.h>
+
+/* OCOTP Register Offsets */
+#define OCOTP_CTRL_REG				0x00
+#define OCOTP_CTRL_SET				0x04
+#define OCOTP_CTRL_CLR				0x08
+#define OCOTP_TIMING				0x10
+#define OCOTP_DATA				0x20
+#define OCOTP_READ_CTRL_REG			0x30
+#define OCOTP_READ_FUSE_DATA			0x40
+
+/* OCOTP Register bits and masks */
+#define OCOTP_CTRL_WR_UNLOCK			16
+#define OCOTP_CTRL_WR_UNLOCK_KEY		0x3E77
+#define OCOTP_CTRL_WR_UNLOCK_MASK		GENMASK(31, 16)
+#define OCOTP_CTRL_ADDR				0
+#define OCOTP_CTRL_ADDR_MASK			GENMASK(6, 0)
+#define OCOTP_CTRL_RELOAD_SHADOWS		BIT(10)
+#define OCOTP_CTRL_ERR				BIT(9)
+#define OCOTP_CTRL_BUSY				BIT(8)
+
+#define OCOTP_TIMING_STROBE_READ		16
+#define OCOTP_TIMING_STROBE_READ_MASK		GENMASK(21, 16)
+#define OCOTP_TIMING_RELAX			12
+#define OCOTP_TIMING_RELAX_MASK			GENMASK(15, 12)
+#define OCOTP_TIMING_STROBE_PROG		0
+#define OCOTP_TIMING_STROBE_PROG_MASK		GENMASK(11, 0)
+
+#define OCOTP_READ_CTRL_READ_FUSE		0x1
+
+#define VF610_OCOTP_TIMEOUT			100000
+
+#define BF(value, field)		(((value) << field) & field##_MASK)
+
+#define DEF_RELAX				20
+
+static const int base_to_fuse_addr_mappings[][2] = {
+	{0x400, 0x00},
+	{0x410, 0x01},
+	{0x420, 0x02},
+	{0x450, 0x05},
+	{0x4F0, 0x0F},
+	{0x600, 0x20},
+	{0x610, 0x21},
+	{0x620, 0x22},
+	{0x630, 0x23},
+	{0x640, 0x24},
+	{0x650, 0x25},
+	{0x660, 0x26},
+	{0x670, 0x27},
+	{0x6F0, 0x2F},
+	{0x880, 0x38},
+	{0x890, 0x39},
+	{0x8A0, 0x3A},
+	{0x8B0, 0x3B},
+	{0x8C0, 0x3C},
+	{0x8D0, 0x3D},
+	{0x8E0, 0x3E},
+	{0x8F0, 0x3F},
+	{0xC80, 0x78},
+	{0xC90, 0x79},
+	{0xCA0, 0x7A},
+	{0xCB0, 0x7B},
+	{0xCC0, 0x7C},
+	{0xCD0, 0x7D},
+	{0xCE0, 0x7E},
+	{0xCF0, 0x7F},
+};
+
+struct vf610_ocotp {
+	void __iomem *base;
+	struct clk *clk;
+	struct device *dev;
+	struct nvmem_device *nvmem;
+	int timing;
+};
+
+static int vf610_ocotp_wait_busy(void __iomem *base)
+{
+	int timeout = VF610_OCOTP_TIMEOUT;
+
+	while ((readl(base) & OCOTP_CTRL_BUSY) && --timeout)
+		udelay(10);
+
+	if (!timeout) {
+		writel(OCOTP_CTRL_ERR, base + OCOTP_CTRL_CLR);
+		return -ETIMEDOUT;
+	}
+
+	udelay(10);
+
+	return 0;
+}
+
+static int vf610_ocotp_calculate_timing(struct vf610_ocotp *ocotp_dev)
+{
+	u32 clk_rate;
+	u32 relax, strobe_read, strobe_prog;
+	u32 timing;
+
+	clk_rate = clk_get_rate(ocotp_dev->clk);
+
+	/* Refer section OTP read/write timing parameters in TRM */
+	relax = clk_rate / (1000000000 / DEF_RELAX) - 1;
+	strobe_prog = clk_rate / (1000000000 / 10000) + 2 * (DEF_RELAX + 1) - 1;
+	strobe_read = clk_rate / (1000000000 / 40) + 2 * (DEF_RELAX + 1) - 1;
+
+	timing = BF(relax, OCOTP_TIMING_RELAX);
+	timing |= BF(strobe_read, OCOTP_TIMING_STROBE_READ);
+	timing |= BF(strobe_prog, OCOTP_TIMING_STROBE_PROG);
+
+	return timing;
+}
+
+static int vf610_get_fuse_address(int base_addr_offset)
+{
+	int i;
+
+	for (i = 0; i < ARRAY_SIZE(base_to_fuse_addr_mappings); i++) {
+		if (base_to_fuse_addr_mappings[i][0] == base_addr_offset)
+			return base_to_fuse_addr_mappings[i][1];
+	}
+
+	return -EINVAL;
+}
+
+static int vf610_ocotp_write(void *context, const void *data, size_t count)
+{
+	return 0;
+}
+
+static int vf610_ocotp_read(void *context,
+			const void *off, size_t reg_size,
+			void *val, size_t val_size)
+{
+	struct vf610_ocotp *ocotp = context;
+	void __iomem *base = ocotp->base;
+	unsigned int offset = *(u32 *)off;
+	u32 reg, *buf = val;
+	int fuse_addr;
+	int ret;
+
+	while (val_size > 0) {
+		fuse_addr = vf610_get_fuse_address(offset);
+		if (fuse_addr > 0) {
+			writel(ocotp->timing, base + OCOTP_TIMING);
+			ret = vf610_ocotp_wait_busy(base + OCOTP_CTRL_REG);
+			if (ret)
+				return ret;
+
+			reg = readl(base + OCOTP_CTRL_REG);
+			reg &= ~OCOTP_CTRL_ADDR_MASK;
+			reg &= ~OCOTP_CTRL_WR_UNLOCK_MASK;
+			reg |= BF(fuse_addr, OCOTP_CTRL_ADDR);
+			writel(reg, base + OCOTP_CTRL_REG);
+
+			writel(OCOTP_READ_CTRL_READ_FUSE,
+				base + OCOTP_READ_CTRL_REG);
+			ret = vf610_ocotp_wait_busy(base + OCOTP_CTRL_REG);
+			if (ret)
+				return ret;
+
+			if (readl(base) & OCOTP_CTRL_ERR) {
+				dev_dbg(ocotp->dev, "Error reading from fuse address %x\n",
+					fuse_addr);
+				writel(OCOTP_CTRL_ERR, base + OCOTP_CTRL_CLR);
+			}
+
+			/*
+			 * In case of error, we do not abort and expect to read
+			 * 0xBADABADA as mentioned by the TRM. We just read this
+			 * value and return.
+			 */
+			*buf = readl(base + OCOTP_READ_FUSE_DATA);
+		} else {
+			*buf = 0;
+		}
+
+		buf++;
+		val_size--;
+		offset += reg_size;
+	}
+
+	return 0;
+}
+
+static struct regmap_bus vf610_ocotp_bus = {
+	.read = vf610_ocotp_read,
+	.write = vf610_ocotp_write,
+	.reg_format_endian_default = REGMAP_ENDIAN_NATIVE,
+	.val_format_endian_default = REGMAP_ENDIAN_NATIVE,
+};
+
+static struct regmap_config ocotp_regmap_config = {
+	.reg_bits = 32,
+	.val_bits = 32,
+	.reg_stride = 4,
+};
+
+static struct nvmem_config ocotp_config = {
+	.name = "ocotp",
+	.owner = THIS_MODULE,
+};
+
+static const struct of_device_id ocotp_of_match[] = {
+	{ .compatible = "fsl,vf610-ocotp", },
+	{/* sentinel */},
+};
+MODULE_DEVICE_TABLE(of, ocotp_of_match);
+
+static int vf610_ocotp_remove(struct platform_device *pdev)
+{
+	struct vf610_ocotp *ocotp_dev = platform_get_drvdata(pdev);
+
+	return nvmem_unregister(ocotp_dev->nvmem);
+}
+
+static int vf610_ocotp_probe(struct platform_device *pdev)
+{
+	struct device *dev = &pdev->dev;
+	struct resource *res;
+	struct regmap *regmap;
+	struct vf610_ocotp *ocotp_dev;
+
+	ocotp_dev = devm_kzalloc(&pdev->dev,
+			sizeof(struct vf610_ocotp), GFP_KERNEL);
+	if (!ocotp_dev)
+		return -ENOMEM;
+
+	res = platform_get_resource(pdev, IORESOURCE_MEM, 0);
+	ocotp_dev->base = devm_ioremap_resource(dev, res);
+	if (IS_ERR(ocotp_dev->base))
+		return PTR_ERR(ocotp_dev->base);
+
+	ocotp_dev->clk = devm_clk_get(dev, "ocotp");
+	if (IS_ERR(ocotp_dev->clk)) {
+		dev_err(dev, "failed getting clock, err = %ld\n",
+			PTR_ERR(ocotp_dev->clk));
+		return PTR_ERR(ocotp_dev->clk);
+	}
+
+	ocotp_regmap_config.max_register = resource_size(res);
+	regmap = devm_regmap_init(dev,
+		&vf610_ocotp_bus, ocotp_dev, &ocotp_regmap_config);
+	if (IS_ERR(regmap)) {
+		dev_err(dev, "regmap init failed\n");
+		return PTR_ERR(regmap);
+	}
+	ocotp_config.dev = dev;
+
+	ocotp_dev->nvmem = nvmem_register(&ocotp_config);
+	if (IS_ERR(ocotp_dev->nvmem))
+		return PTR_ERR(ocotp_dev->nvmem);
+
+	ocotp_dev->dev = dev;
+	platform_set_drvdata(pdev, ocotp_dev);
+
+	ocotp_dev->timing = vf610_ocotp_calculate_timing(ocotp_dev);
+
+	return 0;
+}
+
+static struct platform_driver vf610_ocotp_driver = {
+	.probe = vf610_ocotp_probe,
+	.remove = vf610_ocotp_remove,
+	.driver = {
+		.name = "vf610-ocotp",
+		.of_match_table = ocotp_of_match,
+	},
+};
+module_platform_driver(vf610_ocotp_driver);
+MODULE_AUTHOR("Sanchayan Maity <sanchayan.maity at toradex.com>");
+MODULE_DESCRIPTION("Vybrid OCOTP driver");
+MODULE_LICENSE("GPL v2");
-- 
2.5.0



From maitysanchayan at gmail.com  Wed Aug 12 06:19:21 2015
From: maitysanchayan at gmail.com (Sanchayan Maity)
Date: Wed, 12 Aug 2015 18:49:21 +0530
Subject: [PATCH v9 4/4] nvmem: Add DT binding documentation for Vybrid OCOTP
 driver
In-Reply-To: <cover.1439384645.git.maitysanchayan@gmail.com>
References: <cover.1439384645.git.maitysanchayan@gmail.com>
Message-ID: <24fcfdc695907103e8f4602b7dc6b8fa38e85ec1.1439384645.git.maitysanchayan@gmail.com>

Add the devicetree bindings for the Freescale Vybrid On-Chip
OTP driver.

Signed-off-by: Sanchayan Maity <maitysanchayan at gmail.com>
Acked-by: Srinivas Kandagatla <srinivas.kandagatla at linaro.org>
---
 .../devicetree/bindings/nvmem/vf610-ocotp.txt       | 21 +++++++++++++++++++++
 1 file changed, 21 insertions(+)
 create mode 100644 Documentation/devicetree/bindings/nvmem/vf610-ocotp.txt

diff --git a/Documentation/devicetree/bindings/nvmem/vf610-ocotp.txt b/Documentation/devicetree/bindings/nvmem/vf610-ocotp.txt
new file mode 100644
index 0000000..b29f65f
--- /dev/null
+++ b/Documentation/devicetree/bindings/nvmem/vf610-ocotp.txt
@@ -0,0 +1,21 @@
+On-Chip OTP Memory for Freescale Vybrid
+
+Required Properties:
+  compatible:
+  - "fsl,vf610-ocotp" for VF5xx/VF6xx
+  #address-cells : Should be 1
+  #size-cells : Should be 1
+  reg : Address and length of OTP controller and fuse map registers
+  clocks : ipg clock we associate with the OCOTP peripheral
+  clock-names : Must contain "ocotp" as matching entry
+
+Example for Vybrid VF5xx/VF6xx:
+
+	ocotp: ocotp at 400a5000 {
+		compatible = "fsl,vf610-ocotp";
+		#address-cells = <1>;
+		#size-cells = <1>;
+		reg = <0x400a5000 0xCF0>;
+		clocks = <&clks VF610_CLK_OCOTP>;
+		clock-names = "ocotp";
+	};
-- 
2.5.0



From hramrach at gmail.com  Wed Aug 12 06:29:31 2015
From: hramrach at gmail.com (Michal Suchanek)
Date: 12 Aug 2015 13:29:31 -0000
Subject: [PATCH v3 1/3] mmc: sunxi: fix timeout in sunxi_mmc_oclk_onoff
In-Reply-To: <55CB3CD7.2050200@redhat.com>
References: <cover.1439381423.git.hramrach@gmail.com>
 <7f9c6f99b31702c02436ef3356b3ebffa4754260.1439381423.git.hramrach@gmail.com>
Message-ID: <bdcb7ce26f359b7fedbd8559eb275c324bfb52bb.1439386047.git.hramrach@gmail.com>

The 250ms timeout is too short.

On my system enabling the oclk takes under 50ms and disabling slightly
over 100ms when idle. Under load disabling the clock can take over
350ms.

This does not make mmc clock gating look like good option to have on
sunxi but the system should not crash with mmc clock gating enabled
nonetheless.

This patch sets the timeout to 750ms.

Signed-off-by: Michal Suchanek <hramrach at gmail.com>

---
v3
 - remove debug message
v2
 - fix formatting
---
 drivers/mmc/host/sunxi-mmc.c | 2 +-
 1 file changed, 1 insertion(+), 1 deletion(-)

diff --git a/drivers/mmc/host/sunxi-mmc.c b/drivers/mmc/host/sunxi-mmc.c
index 4d3e1ff..a7b7a67 100644
--- a/drivers/mmc/host/sunxi-mmc.c
+++ b/drivers/mmc/host/sunxi-mmc.c
@@ -595,7 +595,7 @@ static irqreturn_t sunxi_mmc_handle_manual_stop(int irq, void *dev_id)
 
 static int sunxi_mmc_oclk_onoff(struct sunxi_mmc_host *host, u32 oclk_en)
 {
-	unsigned long expire = jiffies + msecs_to_jiffies(250);
+	unsigned long expire = jiffies + msecs_to_jiffies(750);
 	u32 rval;
 
 	rval = mmc_readl(host, REG_CLKCR);
-- 
2.1.4



From marc.zyngier at arm.com  Wed Aug 12 06:31:47 2015
From: marc.zyngier at arm.com (Marc Zyngier)
Date: Wed, 12 Aug 2015 14:31:47 +0100
Subject: [PATCH 2/6] irqchip: GIC: Convert to EOImode == 1
In-Reply-To: <55C9BD24.10708@linaro.org>
References: <1436447951-22357-1-git-send-email-marc.zyngier@arm.com>
 <1436447951-22357-3-git-send-email-marc.zyngier@arm.com>
 <55C9BD24.10708@linaro.org>
Message-ID: <55CB4AC3.6040400@arm.com>

Hi Eric,

On 11/08/15 10:15, Eric Auger wrote:
> Hi Marc,
> On 07/09/2015 03:19 PM, Marc Zyngier wrote:
>> So far, GICv2 has been used in with EOImode == 0. The effect of this
>> mode is to perform the priority drop and the deactivation of the
>> interrupt at the same time.
>>
>> While this works perfectly for Linux (we only have a single priority),
>> it causes issues when an interrupt is forwarded to a guest, and when
>> we want the guest to perform the EOI itself.
>>
>> For this case, the GIC architecture provides EOImode == 1, where:
>> - A write to the EOI register drops the priority of the interrupt and leaves
>> it active. Other interrupts at the same priority level can now be taken,
>> but the active interrupt cannot be taken again
>> - A write to the DIR marks the interrupt as inactive, meaning it can
>> now be taken again.
>>
>> We only enable this feature when booted in HYP mode and that
>> the device-tree reporte
> reported
>  a suitable CPU interface. Observable behaviour
>> should remain unchanged.
>>
>> Signed-off-by: Marc Zyngier <marc.zyngier at arm.com>
>> ---
>>  drivers/irqchip/irq-gic.c       | 32 +++++++++++++++++++++++++++++---
>>  include/linux/irqchip/arm-gic.h |  4 ++++
>>  2 files changed, 33 insertions(+), 3 deletions(-)
>>
>> diff --git a/drivers/irqchip/irq-gic.c b/drivers/irqchip/irq-gic.c
>> index 8d7e1c8..e264675 100644
>> --- a/drivers/irqchip/irq-gic.c
>> +++ b/drivers/irqchip/irq-gic.c
>> @@ -46,6 +46,7 @@
>>  #include <asm/irq.h>
>>  #include <asm/exception.h>
>>  #include <asm/smp_plat.h>
>> +#include <asm/virt.h>
>>  
>>  #include "irq-gic-common.h"
>>  #include "irqchip.h"
>> @@ -82,6 +83,8 @@ static DEFINE_RAW_SPINLOCK(irq_controller_lock);
>>  #define NR_GIC_CPU_IF 8
>>  static u8 gic_cpu_map[NR_GIC_CPU_IF] __read_mostly;
>>  
>> +static struct static_key supports_deactivate = STATIC_KEY_INIT_TRUE;
>> +
>>  #ifndef MAX_GIC_NR
>>  #define MAX_GIC_NR	1
>>  #endif
>> @@ -164,7 +167,10 @@ static void gic_unmask_irq(struct irq_data *d)
>>  
>>  static void gic_eoi_irq(struct irq_data *d)
>>  {
>> -	writel_relaxed(gic_irq(d), gic_cpu_base(d) + GIC_CPU_EOI);
>> +	if (static_key_true(&supports_deactivate))
>> +		writel_relaxed(gic_irq(d), gic_cpu_base(d) + GIC_CPU_DEACTIVATE);
>> +	else
>> +		writel_relaxed(gic_irq(d), gic_cpu_base(d) + GIC_CPU_EOI);
>>  }
>>  
>>  static int gic_irq_set_irqchip_state(struct irq_data *d,
>> @@ -272,11 +278,15 @@ static void __exception_irq_entry gic_handle_irq(struct pt_regs *regs)
>>  		irqnr = irqstat & GICC_IAR_INT_ID_MASK;
>>  
>>  		if (likely(irqnr > 15 && irqnr < 1021)) {
> shouldn't we have < 1020?

Looks like you have unearthed a very long standing (though not fatal)
bug - I can trace it back to 2005 and the inclusion of the Realview
support (see include/asm-arm/arch-realview/entry-macro.S in 8ad68bbf for
the details).

It may be that the original GIC didn't make number 1020 a special one,
though the earliest spec I have access to (GICv1) is already making 1020
a reserved interrupt number. And looking at the pre-existing code
(arch/arm/common/gic.c), 1020 seems to already be considered an invalid
number.

CC-ing Catalin, as he was the one who introduced it... ;-) Unless he
says otherwise, I'll cook a patch for that.

>> +			if (static_key_true(&supports_deactivate))
>> +				writel_relaxed(irqstat, cpu_base + GIC_CPU_EOI);
>>  			handle_domain_irq(gic->domain, irqnr, regs);
> why don't we handle the returned value of handle_domain_irq as we do in
> GICv3?

Because I wrote the GICv3 code with my paranoia hat on... This really
should never fail.

>>  			continue;
>>  		}
>>  		if (irqnr < 16) {
>>  			writel_relaxed(irqstat, cpu_base + GIC_CPU_EOI);
>> +			if (static_key_true(&supports_deactivate))
>> +				writel_relaxed(irqstat, cpu_base + GIC_CPU_DEACTIVATE);
>>  #ifdef CONFIG_SMP
>>  			handle_IPI(irqnr, regs);
>>  #endif
>> @@ -358,7 +368,11 @@ static u8 gic_get_cpumask(struct gic_chip_data *gic)
>>  static void gic_cpu_if_up(void)
>>  {
>>  	void __iomem *cpu_base = gic_data_cpu_base(&gic_data[0]);
>> -	u32 bypass = 0;
>> +	u32 bypass;
>> +	u32 mode = 0;
>> +
>> +	if (static_key_true(&supports_deactivate))
>> +		mode = GIC_CPU_CTRL_EOImodeNS;
>>  
>>  	/*
>>  	* Preserve bypass disable bits to be written back later
>> @@ -366,7 +380,7 @@ static void gic_cpu_if_up(void)
>>  	bypass = readl(cpu_base + GIC_CPU_CTRL);
>>  	bypass &= GICC_DIS_BYPASS_MASK;
>>  
>> -	writel_relaxed(bypass | GICC_ENABLE, cpu_base + GIC_CPU_CTRL);
>> +	writel_relaxed(bypass | mode | GICC_ENABLE, cpu_base + GIC_CPU_CTRL);
>>  }
>>  
>>  
>> @@ -986,6 +1000,9 @@ void __init gic_init_bases(unsigned int gic_nr, int irq_start,
>>  		register_cpu_notifier(&gic_cpu_notifier);
>>  #endif
>>  		set_handle_irq(gic_handle_irq);
>> +		pr_info ("GIC: Using EOImode == %d\n",
>> +			 static_key_true(&supports_deactivate));
>> +
>>  	}
>>  
>>  	gic_dist_init(gic);
>> @@ -1001,6 +1018,7 @@ gic_of_init(struct device_node *node, struct device_node *parent)
>>  {
>>  	void __iomem *cpu_base;
>>  	void __iomem *dist_base;
>> +	struct resource cpu_res;
>>  	u32 percpu_offset;
>>  	int irq;
>>  
>> @@ -1013,6 +1031,11 @@ gic_of_init(struct device_node *node, struct device_node *parent)
>>  	cpu_base = of_iomap(node, 1);
>>  	WARN(!cpu_base, "unable to map gic cpu registers\n");
>>  
>> +	of_address_to_resource(node, 1, &cpu_res);
>> +	if (!gic_cnt &&
>> +	    (!is_hyp_mode_available() || resource_size(&cpu_res) < SZ_8K))
> I don't understand why we check this size?
> in GICv1 EOIMode necessarily is 0, right? is it related?

This is indeed related. For a GIC to support EOIMode==1, you need to
have access to the DIR register, which has the good idea of being
located on a separate 4k page, making the size of the CPU interface 8k
in total. Anything smaller means you don't have a DIR register.

It is worth noticing that most of the DTS files containing a reference
to GICv2 are wrong, and are only exposing a 4k CPU interface. These
platforms won't be able to use this feature until they are fixed.
Basically anything with an A7/A15/A53/A57/X-Gene.

Thanks,

	M.
-- 
Jazz is not dead. It just smells funny...


From msalter at redhat.com  Wed Aug 12 06:33:56 2015
From: msalter at redhat.com (Mark Salter)
Date: Wed, 12 Aug 2015 09:33:56 -0400
Subject: arm kernel oops in highmem.c with 4.2
In-Reply-To: <alpine.LFD.2.20.1508112116320.1515@knanqh.ubzr>
References: <CALeDE9Ox3=sh3AXQ0NUG6BBfU5i5YrMY=LDpcTHQWqz2=60F2g@mail.gmail.com>
 <20150805100701.GV7557@n2100.arm.linux.org.uk>
 <CALeDE9PXF=gQCaBCiHpHy2nXOooQOmsCQvSgOv+wQw3mta=P6A@mail.gmail.com>
 <20150805112713.GY7557@n2100.arm.linux.org.uk>
 <1439315290.3153.11.camel@redhat.com>
 <20150811181008.GA7557@n2100.arm.linux.org.uk>
 <alpine.LFD.2.20.1508111501130.1515@knanqh.ubzr>
 <20150811195638.GC7557@n2100.arm.linux.org.uk>
 <alpine.LFD.2.20.1508111558210.1515@knanqh.ubzr>
 <1439327845.3153.17.camel@redhat.com>
 <alpine.LFD.2.20.1508112116320.1515@knanqh.ubzr>
Message-ID: <1439386436.3153.23.camel@redhat.com>

On Tue, 2015-08-11 at 22:18 -0400, Nicolas Pitre wrote:
> On Tue, 11 Aug 2015, Mark Salter wrote:
> 
> > On Tue, 2015-08-11 at 16:20 -0400, Nicolas Pitre wrote:
> > > On Tue, 11 Aug 2015, Russell King - ARM Linux wrote:
> > > 
> > > > It needs fixing or removing.
> > > 
> > > Absolutely. I'm not disputing that. I'm only asking so we can wisely 
> > > choose between fixing or removing.  Personally I'd be inclined 
> > > towards 
> > > the later, unless the following is sufficient to fix it:
> > > 
> > > diff --git a/arch/arm/lib/uaccess_with_memcpy.c 
> > > b/arch/arm/lib/uaccess_with_memcpy.c
> > > index 3e58d71001..4b39af2dfd 100644
> > > --- a/arch/arm/lib/uaccess_with_memcpy.c
> > > +++ b/arch/arm/lib/uaccess_with_memcpy.c
> > > @@ -96,7 +96,7 @@ __copy_to_user_memcpy(void __user *to, const void 
> > > *from, unsigned long n)
> > >  	}
> > >  
> > >  	/* the mmap semaphore is taken only if not in an atomic 
> > > context 
> > > */
> > > -	atomic = in_atomic();
> > > +	atomic = faulthandler_disabled();
> > >  
> > >  	if (!atomic)
> > >  		down_read(&current->mm->mmap_sem);
> > 
> > Yeah, that fixes the problem I was seeing.
> 
> Good!  Then I'll add it to RMK's patch system.  May I add a tested-by 
> tag with your name?

Yes

> 
> > This was on a calxeda highbank.
> 
> Any idea why this option was set?

None. It seems to have been there in the original fedora config
for v7 kernels. But nothing in the config turns on CPU_FEROCEON
so there is no real need for it.

> 
> > With CONFIG_UACCESS_WITH_MEMCPY, the dd copy test reported 1.8GB/s
> > Without CONFIG_UACCESS_WITH_MEMCPY, 2.1GB/s
> 
> Therefore this is of no benefit to you.
> 
> 
> Nicolas



From marc.zyngier at arm.com  Wed Aug 12 06:34:58 2015
From: marc.zyngier at arm.com (Marc Zyngier)
Date: Wed, 12 Aug 2015 14:34:58 +0100
Subject: [PATCH 3/6] irqchip: GICv3: Skip LPI deactivation
In-Reply-To: <55C9C39A.3060208@linaro.org>
References: <1436447951-22357-1-git-send-email-marc.zyngier@arm.com>
 <1436447951-22357-4-git-send-email-marc.zyngier@arm.com>
 <55C9C39A.3060208@linaro.org>
Message-ID: <55CB4B82.9060601@arm.com>

On 11/08/15 10:42, Eric Auger wrote:
> On 07/09/2015 03:19 PM, Marc Zyngier wrote:
>> Contrary to other GICv3 interrupts, LPIs do not have an active state
>> by virtue of being edge-triggered only (they only have a pending state).
>>
>> Given this, there is no point trying to deactivate them, and we can
>> skip the ICC_DIR_EL1 entierely.
>>
>> Signed-off-by: Marc Zyngier <marc.zyngier at arm.com>
>> ---
>>  drivers/irqchip/irq-gic-v3.c | 8 ++++++--
>>  1 file changed, 6 insertions(+), 2 deletions(-)
>>
>> diff --git a/drivers/irqchip/irq-gic-v3.c b/drivers/irqchip/irq-gic-v3.c
>> index 49768fc..e02592b 100644
>> --- a/drivers/irqchip/irq-gic-v3.c
>> +++ b/drivers/irqchip/irq-gic-v3.c
>> @@ -295,10 +295,14 @@ static int gic_irq_get_irqchip_state(struct irq_data *d,
>>  
>>  static void gic_eoi_irq(struct irq_data *d)
>>  {
>> -	if (static_key_true(&supports_deactivate))
>> +	if (static_key_true(&supports_deactivate)) {
>> +		/* No need to deactivate an LPI */
>> +		if (gic_irq(d) >= 8192)
> In case of EOIMode == 0, we do not call EOI. I can't understand whether
> it is an issue.

What do you mean? We definitely perform an EOI in both EOImodes...

> In 4.8.3 Properties of LPI, in 2d note it is written:
> 
> "SW must issue a write to EOI to clear the active priorities register,
> hence the CPU interface still requires an active state for LPIs, even
> through this is not necessary within the redistributor"
> 
> Eric
>> +			return;
>>  		gic_write_dir(gic_irq(d));
>> -	else
>> +	} else {
>>  		gic_write_eoir(gic_irq(d));

... right here.

Of am I missing something completely obvious?

Thanks,

	M.
-- 
Jazz is not dead. It just smells funny...


From will.deacon at arm.com  Wed Aug 12 06:37:16 2015
From: will.deacon at arm.com (Will Deacon)
Date: Wed, 12 Aug 2015 14:37:16 +0100
Subject: [PATCH v8 3/7] arm64: Kprobes with single stepping support
In-Reply-To: <1439254364-15362-4-git-send-email-dave.long@linaro.org>
References: <1439254364-15362-1-git-send-email-dave.long@linaro.org>
 <1439254364-15362-4-git-send-email-dave.long@linaro.org>
Message-ID: <20150812133716.GA23540@arm.com>

Hi David,

Thanks for the patch. Took me a while to get through it and I suspect
I missed things, but comments inline all the same.

On Tue, Aug 11, 2015 at 01:52:40AM +0100, David Long wrote:
> From: Sandeepa Prabhu <sandeepa.s.prabhu at gmail.com>
>
> Add support for basic kernel probes(kprobes) and jump probes
> (jprobes) for ARM64.
>
> Kprobes utilizes software breakpoint and single step debug
> exceptions supported on ARM v8.
>
> A software breakpoint is placed at the probe address to trap the
> kernel execution into the kprobe handler.
>
> ARM v8 supports enabling single stepping before the break exception
> return (ERET), with next PC in exception return address (ELR_EL1). The
> kprobe handler prepares an executable memory slot for out-of-line
> execution with a copy of the original instruction being probed, and
> enables single stepping. The PC is set to the out-of-line slot address
> before the ERET. With this scheme, the instruction is executed with the
> exact same register context except for the PC (and DAIF) registers.
>
> Debug mask (PSTATE.D) is enabled only when single stepping a recursive
> kprobe, e.g.: during kprobes reenter so that probed instruction can be
> single stepped within the kprobe handler -exception- context.
> The recursion depth of kprobe is always 2, i.e. upon probe re-entry,
> any further re-entry is prevented by not calling handlers and the case
> counted as a missed kprobe).
>
> Single stepping from the x-o-l slot has a drawback for PC-relative accesses
> like branching and symbolic literals access as the offset from the new PC
> (slot address) may not be ensured to fit in the immediate value of
> the opcode. Such instructions need simulation, so reject
> probing them.
>
> Instructions generating exceptions or cpu mode change are rejected
> for probing.
>
> Instructions using Exclusive Monitor are rejected too.
>
> System instructions are mostly enabled for stepping, except MSR/MRS
> accesses to "DAIF" flags in PSTATE, which are not safe for
> probing.

I can imagine other MSR instructions that aren't safe for probing too
For example, disabling the MMU. Maybe we should just blanket-ban these
guys for now?

> diff --git a/arch/arm64/include/asm/debug-monitors.h b/arch/arm64/include/asm/debug-monitors.h
> index 40ec68a..92d7cea 100644
> --- a/arch/arm64/include/asm/debug-monitors.h
> +++ b/arch/arm64/include/asm/debug-monitors.h
> @@ -90,6 +90,11 @@
>
>  #define CACHE_FLUSH_IS_SAFE            1
>
> +/* kprobes BRK opcodes with ESR encoding  */
> +#define BRK64_ESR_MASK         0xFFFF
> +#define BRK64_ESR_KPROBES      0x0004
> +#define BRK64_OPCODE_KPROBES   (AARCH64_BREAK_MON | (BRK64_ESR_KPROBES << 5))

These are probably due some slight renaming with the BRK clean-up we've
got queued for 4.3.

>  /* AArch32 */
>  #define DBG_ESR_EVT_BKPT       0x4
>  #define DBG_ESR_EVT_VECC       0x5
> diff --git a/arch/arm64/include/asm/kprobes.h b/arch/arm64/include/asm/kprobes.h
> new file mode 100644
> index 0000000..af31c4d
> --- /dev/null
> +++ b/arch/arm64/include/asm/kprobes.h
> @@ -0,0 +1,62 @@
> +/*
> + * arch/arm64/include/asm/kprobes.h
> + *
> + * Copyright (C) 2013 Linaro Limited
> + *
> + * 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.
> + */
> +
> +#ifndef _ARM_KPROBES_H
> +#define _ARM_KPROBES_H
> +
> +#include <linux/types.h>
> +#include <linux/ptrace.h>
> +#include <linux/percpu.h>
> +
> +#define __ARCH_WANT_KPROBES_INSN_SLOT
> +#define MAX_INSN_SIZE                  1
> +#define MAX_STACK_SIZE                 128
> +
> +#define flush_insn_slot(p)             do { } while (0)
> +#define kretprobe_blacklist_size       0
> +
> +#include <asm/probes.h>
> +
> +struct prev_kprobe {
> +       struct kprobe *kp;
> +       unsigned int status;
> +};
> +
> +/* Single step context for kprobe */
> +struct kprobe_step_ctx {
> +#define KPROBES_STEP_NONE      0x0
> +#define KPROBES_STEP_PENDING   0x1
> +       unsigned long ss_status;

Why not bool ss_pending?

> +       unsigned long match_addr;
> +};
> +
> +/* per-cpu kprobe control block */
> +struct kprobe_ctlblk {
> +       unsigned int kprobe_status;
> +       unsigned long saved_irqflag;
> +       struct prev_kprobe prev_kprobe;
> +       struct kprobe_step_ctx ss_ctx;
> +       struct pt_regs jprobe_saved_regs;
> +       char jprobes_stack[MAX_STACK_SIZE];
> +};
> +
> +void arch_remove_kprobe(struct kprobe *);
> +int kprobe_fault_handler(struct pt_regs *regs, unsigned int fsr);
> +int kprobe_exceptions_notify(struct notifier_block *self,
> +                            unsigned long val, void *data);
> +int kprobe_breakpoint_handler(struct pt_regs *regs, unsigned int esr);
> +int kprobe_single_step_handler(struct pt_regs *regs, unsigned int esr);
> +
> +#endif /* _ARM_KPROBES_H */
> diff --git a/arch/arm64/include/asm/probes.h b/arch/arm64/include/asm/probes.h
> new file mode 100644
> index 0000000..7f5a27f
> --- /dev/null
> +++ b/arch/arm64/include/asm/probes.h
> @@ -0,0 +1,50 @@
> +/*
> + * arch/arm64/include/asm/probes.h
> + *
> + * Copyright (C) 2013 Linaro Limited
> + *
> + * 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.
> + */
> +#ifndef _ARM_PROBES_H
> +#define _ARM_PROBES_H
> +
> +struct kprobe;
> +struct arch_specific_insn;
> +
> +typedef u32 kprobe_opcode_t;
> +typedef unsigned long (kprobes_pstate_check_t)(unsigned long);
> +typedef unsigned long
> +(probes_condition_check_t)(struct kprobe *p, struct pt_regs *);
> +typedef void
> +(probes_prepare_t)(struct kprobe *, struct arch_specific_insn *);
> +typedef void (kprobes_handler_t) (u32 opcode, long addr, struct pt_regs *);
> +
> +enum pc_restore_type {
> +       NO_RESTORE,
> +       RESTORE_PC,
> +};
> +
> +struct kprobe_pc_restore {
> +       enum pc_restore_type type;
> +       unsigned long addr;
> +};
> +
> +/* architecture specific copy of original instruction */
> +struct arch_specific_insn {
> +       kprobe_opcode_t *insn;
> +       kprobes_pstate_check_t *pstate_cc;
> +       probes_condition_check_t *check_condn;
> +       probes_prepare_t *prepare;
> +       kprobes_handler_t *handler;
> +       /* restore address after step xol */
> +       struct kprobe_pc_restore restore;
> +};
> +
> +#endif
> diff --git a/arch/arm64/include/asm/ptrace.h b/arch/arm64/include/asm/ptrace.h
> index 8f440e9..aadf61a 100644
> --- a/arch/arm64/include/asm/ptrace.h
> +++ b/arch/arm64/include/asm/ptrace.h
> @@ -206,7 +206,8 @@ static inline int valid_user_regs(struct user_pt_regs *regs)
>         return 0;
>  }
>
> -#define instruction_pointer(regs)      ((unsigned long)(regs)->pc)
> +#define instruction_pointer(regs)      ((regs)->pc)
> +#define stack_pointer(regs)            ((regs)->sp)

We already have kernel_stack_pointer (I think you added it in patch 1),
so can't you just use that?

>  #ifdef CONFIG_SMP
>  extern unsigned long profile_pc(struct pt_regs *regs);
> diff --git a/arch/arm64/kernel/Makefile b/arch/arm64/kernel/Makefile
> index 426d076..1319872 100644
> --- a/arch/arm64/kernel/Makefile
> +++ b/arch/arm64/kernel/Makefile
> @@ -32,6 +32,7 @@ arm64-obj-$(CONFIG_CPU_PM)            += sleep.o suspend.o
>  arm64-obj-$(CONFIG_CPU_IDLE)           += cpuidle.o
>  arm64-obj-$(CONFIG_JUMP_LABEL)         += jump_label.o
>  arm64-obj-$(CONFIG_KGDB)               += kgdb.o
> +arm64-obj-$(CONFIG_KPROBES)            += kprobes.o kprobes-arm64.o
>  arm64-obj-$(CONFIG_EFI)                        += efi.o efi-stub.o efi-entry.o
>  arm64-obj-$(CONFIG_PCI)                        += pci.o
>  arm64-obj-$(CONFIG_ARMV8_DEPRECATED)   += armv8_deprecated.o
> diff --git a/arch/arm64/kernel/debug-monitors.c b/arch/arm64/kernel/debug-monitors.c
> index b056369..486ee94 100644
> --- a/arch/arm64/kernel/debug-monitors.c
> +++ b/arch/arm64/kernel/debug-monitors.c
> @@ -23,6 +23,7 @@
>  #include <linux/hardirq.h>
>  #include <linux/init.h>
>  #include <linux/ptrace.h>
> +#include <linux/kprobes.h>
>  #include <linux/stat.h>
>  #include <linux/uaccess.h>
>
> @@ -228,6 +229,7 @@ static int single_step_handler(unsigned long addr, unsigned int esr,
>                                struct pt_regs *regs)
>  {
>         siginfo_t info;
> +       bool handler_found = false;
>
>         /*
>          * If we are stepping a pending breakpoint, call the hw_breakpoint
> @@ -251,15 +253,21 @@ static int single_step_handler(unsigned long addr, unsigned int esr,
>                  */
>                 user_rewind_single_step(current);
>         } else {
> +#ifdef CONFIG_KPROBES
> +               if (kprobe_single_step_handler(regs, esr) == DBG_HOOK_HANDLED)
> +                       handler_found = true;
> +#endif
>                 if (call_step_hook(regs, esr) == DBG_HOOK_HANDLED)

Is this because you need to called first? If so, maybe we could extend the
step hook to take an optional priority and reject duplicate entries with
the same value?

Even then, it's not clear that you do always want to be called first. For
example, if the instruction you're single-stepping in the x-o-l buffer
triggers a hardware watchpoint, then you probably want to handle the
watchpoint single-step exception before the kprobe.

> -                       return 0;
> -
> -               pr_warning("Unexpected kernel single-step exception at EL1\n");
> -               /*
> -                * Re-enable stepping since we know that we will be
> -                * returning to regs.
> -                */
> -               set_regs_spsr_ss(regs);
> +                       handler_found = true;
> +
> +               if (!handler_found) {
> +                       pr_warn("Unexpected kernel single-step exception at EL1\n");
> +                       /*
> +                        * Re-enable stepping since we know that we will be
> +                        * returning to regs.
> +                        */
> +                       set_regs_spsr_ss(regs);
> +               }
>         }
>
>         return 0;
> @@ -315,8 +323,15 @@ static int brk_handler(unsigned long addr, unsigned int esr,
>                 };
>
>                 force_sig_info(SIGTRAP, &info, current);
> -       } else if (call_break_hook(regs, esr) != DBG_HOOK_HANDLED) {
> -               pr_warning("Unexpected kernel BRK exception at EL1\n");
> +       }
> +#ifdef CONFIG_KPROBES
> +       else if ((esr & BRK64_ESR_MASK) == BRK64_ESR_KPROBES) {
> +               if (kprobe_breakpoint_handler(regs, esr) != DBG_HOOK_HANDLED)
> +                       return -EFAULT;
> +       }
> +#endif
> +       else if (call_break_hook(regs, esr) != DBG_HOOK_HANDLED) {
> +               pr_warn("Unexpected kernel BRK exception at EL1\n");

Same here.

Also, we now use BRK to implement BUG(), but I *think* that's ok because
you reject kprobes on exception generating instructions.

>                 return -EFAULT;
>         }
>
> diff --git a/arch/arm64/kernel/kprobes-arm64.c b/arch/arm64/kernel/kprobes-arm64.c
> new file mode 100644
> index 0000000..f958c52
> --- /dev/null
> +++ b/arch/arm64/kernel/kprobes-arm64.c
> @@ -0,0 +1,68 @@
> +/*
> + * arch/arm64/kernel/kprobes-arm64.c
> + *
> + * Copyright (C) 2013 Linaro Limited.
> + *
> + * 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/kernel.h>
> +#include <linux/kprobes.h>
> +#include <linux/module.h>
> +#include <asm/kprobes.h>
> +#include <asm/insn.h>
> +
> +#include "kprobes-arm64.h"
> +
> +static bool __kprobes aarch64_insn_is_steppable(u32 insn)
> +{
> +       if (aarch64_get_insn_class(insn) == AARCH64_INSN_CLS_BR_SYS) {
> +               if (aarch64_insn_is_branch(insn))
> +                       return false;
> +
> +               /* modification of daif creates issues */
> +               if (aarch64_insn_is_daif_access(insn))
> +                       return false;
> +
> +               if (aarch64_insn_is_exception(insn))
> +                       return false;
> +
> +               if (aarch64_insn_is_hint(insn))
> +                       return aarch64_insn_is_nop(insn);
> +
> +               return true;
> +       }
> +
> +       if (aarch64_insn_uses_literal(insn))
> +               return false;
> +
> +       if (aarch64_insn_is_exclusive(insn))
> +               return false;
> +
> +       return true;
> +}
> +
> +/* Return:
> + *   INSN_REJECTED     If instruction is one not allowed to kprobe,
> + *   INSN_GOOD         If instruction is supported and uses instruction slot,
> + *   INSN_GOOD_NO_SLOT If instruction is supported but doesn't use its slot.
> + */
> +enum kprobe_insn __kprobes
> +arm_kprobe_decode_insn(kprobe_opcode_t insn, struct arch_specific_insn *asi)
> +{
> +       /*
> +        * Instructions reading or modifying the PC won't work from the XOL
> +        * slot.
> +        */
> +       if (aarch64_insn_is_steppable(insn))
> +               return INSN_GOOD;
> +       else
> +               return INSN_REJECTED;
> +}
> diff --git a/arch/arm64/kernel/kprobes-arm64.h b/arch/arm64/kernel/kprobes-arm64.h
> new file mode 100644
> index 0000000..87e7891
> --- /dev/null
> +++ b/arch/arm64/kernel/kprobes-arm64.h
> @@ -0,0 +1,28 @@
> +/*
> + * arch/arm64/kernel/kprobes-arm64.h
> + *
> + * Copyright (C) 2013 Linaro Limited.
> + *
> + * 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.
> + */
> +
> +#ifndef _ARM_KERNEL_KPROBES_ARM64_H
> +#define _ARM_KERNEL_KPROBES_ARM64_H
> +
> +enum kprobe_insn {
> +       INSN_REJECTED,
> +       INSN_GOOD_NO_SLOT,
> +       INSN_GOOD,
> +};
> +
> +enum kprobe_insn __kprobes
> +arm_kprobe_decode_insn(kprobe_opcode_t insn, struct arch_specific_insn *asi);
> +
> +#endif /* _ARM_KERNEL_KPROBES_ARM64_H */
> diff --git a/arch/arm64/kernel/kprobes.c b/arch/arm64/kernel/kprobes.c
> new file mode 100644
> index 0000000..601d2c6
> --- /dev/null
> +++ b/arch/arm64/kernel/kprobes.c
> @@ -0,0 +1,537 @@
> +/*
> + * arch/arm64/kernel/kprobes.c
> + *
> + * Kprobes support for ARM64
> + *
> + * Copyright (C) 2013 Linaro Limited.
> + * Author: Sandeepa Prabhu <sandeepa.prabhu at linaro.org>
> + *
> + * This program is free software; you can redistribute it and/or modify
> + * it under the terms of the GNU General Public License version 2 as
> + * published by the Free Software Foundation.
> + *
> + * 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/kernel.h>
> +#include <linux/kprobes.h>
> +#include <linux/module.h>
> +#include <linux/slab.h>
> +#include <linux/stop_machine.h>
> +#include <linux/stringify.h>
> +#include <asm/traps.h>
> +#include <asm/ptrace.h>
> +#include <asm/cacheflush.h>
> +#include <asm/debug-monitors.h>
> +#include <asm/system_misc.h>
> +#include <asm/insn.h>
> +
> +#include "kprobes.h"
> +#include "kprobes-arm64.h"
> +
> +#define MIN_STACK_SIZE(addr)   min((unsigned long)MAX_STACK_SIZE,      \
> +       (unsigned long)current_thread_info() + THREAD_START_SP - (addr))

You can avoid the cast by using task_stack_page(current).

That said, I don't fully understand what this is for. Given that we don't
probe the exception text, we should always have at least MAX_STACK_SIZE
pushed on the stack thanks to the pt_regs structure, so when does this
condition ever evaluate to something less?

> +DEFINE_PER_CPU(struct kprobe *, current_kprobe) = NULL;
> +DEFINE_PER_CPU(struct kprobe_ctlblk, kprobe_ctlblk);
> +
> +static void __kprobes arch_prepare_ss_slot(struct kprobe *p)
> +{
> +       /* prepare insn slot */
> +       p->ainsn.insn[0] = p->opcode;
> +
> +       flush_icache_range((uintptr_t) (p->ainsn.insn),
> +                          (uintptr_t) (p->ainsn.insn) + MAX_INSN_SIZE);

Hmm, is this right? MAX_INSN_SIZE is 1, so I don't think you're flushing
enough (but in reality you'll flush a whole cacheline and get away with
it).

> +
> +       /*
> +        * Needs restoring of return address after stepping xol.
> +        */
> +       p->ainsn.restore.addr = (unsigned long) p->addr +
> +         sizeof(kprobe_opcode_t);
> +       p->ainsn.restore.type = RESTORE_PC;
> +}
> +
> +int __kprobes arch_prepare_kprobe(struct kprobe *p)
> +{
> +       kprobe_opcode_t insn;
> +       unsigned long probe_addr = (unsigned long)p->addr;

x86 has some complications to deal with multiple kprobes on the same
address afaict. Do we care about that at all?

> +       /* copy instruction */
> +       insn = *p->addr;

Instructions are always little-endian, so I think you need an le32_to_cpu
here to work on a big-endian kernel. I suspect you may have a few other
endianness bugs lurking, so it would be worth testing this in big-endian
(you can run a big-endian kvm guest easily enough under kvmtool).

> +       p->opcode = insn;
> +
> +       if (in_exception_text(probe_addr))
> +               return -EINVAL;
> +
> +       /* decode instruction */
> +       switch (arm_kprobe_decode_insn(insn, &p->ainsn)) {
> +       case INSN_REJECTED:     /* insn not supported */
> +               return -EINVAL;
> +
> +       case INSN_GOOD_NO_SLOT: /* insn need simulation */
> +               return -EINVAL;
> +
> +       case INSN_GOOD: /* instruction uses slot */
> +               p->ainsn.insn = get_insn_slot();
> +               if (!p->ainsn.insn)
> +                       return -ENOMEM;
> +               break;
> +       };
> +
> +       /* prepare the instruction */
> +       arch_prepare_ss_slot(p);
> +
> +       return 0;
> +}
> +
> +static int __kprobes patch_text(kprobe_opcode_t *addr, u32 opcode)
> +{
> +       void *addrs[1];
> +       u32 insns[1];
> +
> +       addrs[0] = (void *)addr;
> +       insns[0] = (u32)opcode;
> +
> +       return aarch64_insn_patch_text_sync(addrs, insns, 1);

Any reason not to use aarch64_insn_patch_text here?

> +}
> +
> +/* arm kprobe: install breakpoint in text */
> +void __kprobes arch_arm_kprobe(struct kprobe *p)
> +{
> +       patch_text(p->addr, BRK64_OPCODE_KPROBES);
> +}
> +
> +/* disarm kprobe: remove breakpoint from text */
> +void __kprobes arch_disarm_kprobe(struct kprobe *p)
> +{
> +       patch_text(p->addr, p->opcode);
> +}
> +
> +void __kprobes arch_remove_kprobe(struct kprobe *p)
> +{
> +       if (p->ainsn.insn) {
> +               free_insn_slot(p->ainsn.insn, 0);
> +               p->ainsn.insn = NULL;
> +       }
> +}
> +
> +static void __kprobes save_previous_kprobe(struct kprobe_ctlblk *kcb)
> +{
> +       kcb->prev_kprobe.kp = kprobe_running();
> +       kcb->prev_kprobe.status = kcb->kprobe_status;
> +}
> +
> +static void __kprobes restore_previous_kprobe(struct kprobe_ctlblk *kcb)
> +{
> +       __this_cpu_write(current_kprobe, kcb->prev_kprobe.kp);
> +       kcb->kprobe_status = kcb->prev_kprobe.status;
> +}
> +
> +static void __kprobes set_current_kprobe(struct kprobe *p)
> +{
> +       __this_cpu_write(current_kprobe, p);
> +}
> +
> +/*
> + * The D-flag (Debug mask) is set (masked) upon exception entry.

To avoid confusing the casual reader, can we specify that we're talking
about *debug* exception entry, please?

> + * Kprobes needs to clear (unmask) D-flag -ONLY- in case of recursive
> + * probe i.e. when probe hit from kprobe handler context upon
> + * executing the pre/post handlers. In this case we return with
> + * D-flag clear so that single-stepping can be carried-out.
> + *
> + * Leave D-flag set in all other cases.
> + */
> +static void __kprobes
> +spsr_set_debug_flag(struct pt_regs *regs, int mask)
> +{
> +       unsigned long spsr = regs->pstate;
> +
> +       if (mask)
> +               spsr |= PSR_D_BIT;
> +       else
> +               spsr &= ~PSR_D_BIT;
> +
> +       regs->pstate = spsr;
> +}

This continues to melt my brain, but I think it's the right thing to do
as long as the krpobes recursion is bound (as you stated in the commit
log).

> +
> +/*
> + * Interrupts need to be disabled before single-step mode is set, and not
> + * reenabled until after single-step mode ends.
> + * Without disabling interrupt on local CPU, there is a chance of
> + * interrupt occurrence in the period of exception return and  start of
> + * out-of-line single-step, that result in wrongly single stepping
> + * the interrupt handler.

*into* the interrupt handler.

Curious: what happens if the instruction aborts for some other reason?
I assume we forbid probing copy_from_user etc?

> + */
> +static void __kprobes kprobes_save_local_irqflag(struct pt_regs *regs)
> +{
> +       struct kprobe_ctlblk *kcb = get_kprobe_ctlblk();
> +
> +       kcb->saved_irqflag = regs->pstate;
> +       regs->pstate |= PSR_I_BIT;
> +}
> +
> +static void __kprobes kprobes_restore_local_irqflag(struct pt_regs *regs)
> +{
> +       struct kprobe_ctlblk *kcb = get_kprobe_ctlblk();
> +
> +       if (kcb->saved_irqflag & PSR_I_BIT)
> +               regs->pstate |= PSR_I_BIT;
> +       else
> +               regs->pstate &= ~PSR_I_BIT;
> +}
> +
> +static void __kprobes
> +set_ss_context(struct kprobe_ctlblk *kcb, unsigned long addr)
> +{
> +       kcb->ss_ctx.ss_status = KPROBES_STEP_PENDING;
> +       kcb->ss_ctx.match_addr = addr + sizeof(kprobe_opcode_t);
> +}
> +
> +static void __kprobes clear_ss_context(struct kprobe_ctlblk *kcb)
> +{
> +       kcb->ss_ctx.ss_status = KPROBES_STEP_NONE;
> +       kcb->ss_ctx.match_addr = 0;
> +}
> +
> +static void __kprobes
> +skip_singlestep_missed(struct kprobe_ctlblk *kcb, struct pt_regs *regs)
> +{
> +       /* set return addr to next pc to continue */
> +       instruction_pointer(regs) += sizeof(kprobe_opcode_t);
> +}
> +
> +static void __kprobes setup_singlestep(struct kprobe *p,
> +                                      struct pt_regs *regs,
> +                                      struct kprobe_ctlblk *kcb, int reenter)
> +{
> +       unsigned long slot;
> +
> +       if (reenter) {
> +               save_previous_kprobe(kcb);
> +               set_current_kprobe(p);
> +               kcb->kprobe_status = KPROBE_REENTER;
> +       } else {
> +               kcb->kprobe_status = KPROBE_HIT_SS;
> +       }
> +
> +       if (p->ainsn.insn) {
> +               /* prepare for single stepping */
> +               slot = (unsigned long)p->ainsn.insn;
> +
> +               set_ss_context(kcb, slot);      /* mark pending ss */
> +
> +               if (kcb->kprobe_status == KPROBE_REENTER)
> +                       spsr_set_debug_flag(regs, 0);
> +
> +               /* IRQs and single stepping do not mix well. */
> +               kprobes_save_local_irqflag(regs);
> +               kernel_enable_single_step(regs);
> +               instruction_pointer(regs) = slot;

Have you tried this with CONFIG_DEBUG_RODATA=y? I'm not sure that the
buffer will be executable in that case.

> +       } else  {
> +               BUG();
> +       }
> +}
> +
> +static int __kprobes reenter_kprobe(struct kprobe *p,
> +                                   struct pt_regs *regs,
> +                                   struct kprobe_ctlblk *kcb)
> +{
> +       switch (kcb->kprobe_status) {
> +       case KPROBE_HIT_SSDONE:
> +       case KPROBE_HIT_ACTIVE:
> +               if (!p->ainsn.check_condn || p->ainsn.check_condn(p, regs)) {
> +                       kprobes_inc_nmissed_count(p);
> +                       setup_singlestep(p, regs, kcb, 1);
> +               } else  {
> +                       /* condition check failed, skip stepping */
> +                       skip_singlestep_missed(kcb, regs);
> +               }
> +               break;
> +       case KPROBE_HIT_SS:
> +       case KPROBE_REENTER:
> +               pr_warn("Unrecoverable kprobe detected at %p.\n", p->addr);
> +               dump_kprobe(p);
> +               BUG();
> +               break;
> +       default:
> +               WARN_ON(1);
> +               return 0;
> +       }
> +
> +       return 1;
> +}
> +
> +static void __kprobes
> +post_kprobe_handler(struct kprobe_ctlblk *kcb, struct pt_regs *regs)
> +{
> +       struct kprobe *cur = kprobe_running();
> +
> +       if (!cur)
> +               return;
> +
> +       /* return addr restore if non-branching insn */
> +       if (cur->ainsn.restore.type == RESTORE_PC) {
> +               instruction_pointer(regs) = cur->ainsn.restore.addr;
> +               if (!instruction_pointer(regs))
> +                       BUG();
> +       }
> +
> +       /* restore back original saved kprobe variables and continue */
> +       if (kcb->kprobe_status == KPROBE_REENTER) {
> +               restore_previous_kprobe(kcb);
> +               return;
> +       }
> +       /* call post handler */
> +       kcb->kprobe_status = KPROBE_HIT_SSDONE;
> +       if (cur->post_handler)  {
> +               /* post_handler can hit breakpoint and single step
> +                * again, so we enable D-flag for recursive exception.
> +                */
> +               cur->post_handler(cur, regs, 0);
> +       }
> +
> +       reset_current_kprobe();
> +}
> +
> +int __kprobes kprobe_fault_handler(struct pt_regs *regs, unsigned int fsr)
> +{
> +       struct kprobe *cur = kprobe_running();
> +       struct kprobe_ctlblk *kcb = get_kprobe_ctlblk();
> +
> +       switch (kcb->kprobe_status) {
> +       case KPROBE_HIT_SS:
> +       case KPROBE_REENTER:
> +               /*
> +                * We are here because the instruction being single
> +                * stepped caused a page fault. We reset the current
> +                * kprobe and the ip points back to the probe address
> +                * and allow the page fault handler to continue as a
> +                * normal page fault.
> +                */
> +               instruction_pointer(regs) = (unsigned long)cur->addr;
> +               if (!instruction_pointer(regs))
> +                       BUG();
> +               if (kcb->kprobe_status == KPROBE_REENTER)
> +                       restore_previous_kprobe(kcb);
> +               else
> +                       reset_current_kprobe();
> +
> +               break;
> +       case KPROBE_HIT_ACTIVE:
> +       case KPROBE_HIT_SSDONE:
> +               /*
> +                * We increment the nmissed count for accounting,
> +                * we can also use npre/npostfault count for accounting
> +                * these specific fault cases.
> +                */
> +               kprobes_inc_nmissed_count(cur);
> +
> +               /*
> +                * We come here because instructions in the pre/post
> +                * handler caused the page_fault, this could happen
> +                * if handler tries to access user space by
> +                * copy_from_user(), get_user() etc. Let the
> +                * user-specified handler try to fix it first.
> +                */
> +               if (cur->fault_handler && cur->fault_handler(cur, regs, fsr))
> +                       return 1;
> +
> +               /*
> +                * In case the user-specified fault handler returned
> +                * zero, try to fix up.
> +                */
> +               if (fixup_exception(regs))
> +                       return 1;

Won't this get dealt with in do_page_fault if we just return 1? (i.e.
__do_kernel_fault would get called, which would then call fixup_exception).

> +
> +               break;
> +       }
> +       return 0;
> +}
> +
> +int __kprobes kprobe_exceptions_notify(struct notifier_block *self,
> +                                      unsigned long val, void *data)
> +{
> +       return NOTIFY_DONE;
> +}
> +
> +void __kprobes kprobe_handler(struct pt_regs *regs)

static? (or inline into kprobe_breakpoint_handler)

> +{
> +       struct kprobe *p, *cur;
> +       struct kprobe_ctlblk *kcb;
> +       unsigned long addr = instruction_pointer(regs);
> +
> +       kcb = get_kprobe_ctlblk();
> +       cur = kprobe_running();

I keep getting this confused with current. Can you give it a better name
please?

> +
> +       p = get_kprobe((kprobe_opcode_t *) addr);
> +
> +       if (p) {
> +               if (cur) {
> +                       if (reenter_kprobe(p, regs, kcb))
> +                               return;
> +               } else if (!p->ainsn.check_condn ||
> +                          p->ainsn.check_condn(p, regs)) {
> +                       /* Probe hit and conditional execution check ok. */
> +                       set_current_kprobe(p);
> +                       kcb->kprobe_status = KPROBE_HIT_ACTIVE;
> +
> +                       /*
> +                        * If we have no pre-handler or it returned 0, we
> +                        * continue with normal processing.  If we have a
> +                        * pre-handler and it returned non-zero, it prepped
> +                        * for calling the break_handler below on re-entry,
> +                        * so get out doing nothing more here.
> +                        *
> +                        * pre_handler can hit a breakpoint and can step thru
> +                        * before return, keep PSTATE D-flag enabled until
> +                        * pre_handler return back.
> +                        */
> +                       if (!p->pre_handler || !p->pre_handler(p, regs)) {
> +                               kcb->kprobe_status = KPROBE_HIT_SS;
> +                               setup_singlestep(p, regs, kcb, 0);
> +                               return;
> +                       }
> +               } else {
> +                       /*
> +                        * Breakpoint hit but conditional check failed,
> +                        * so just skip the instruction (NOP behaviour)
> +                        */
> +                       skip_singlestep_missed(kcb, regs);

Why is this necessary? (i.e. why doesn't the condition get honoured
during the single-step?).

> +                       return;
> +               }
> +       } else if (*(kprobe_opcode_t *) addr != BRK64_OPCODE_KPROBES) {
> +               /*
> +                * The breakpoint instruction was removed right
> +                * after we hit it.  Another cpu has removed
> +                * either a probepoint or a debugger breakpoint
> +                * at this address.  In either case, no further
> +                * handling of this interrupt is appropriate.
> +                * Return back to original instruction, and continue.
> +                */
> +               return;
> +       } else if (cur) {
> +               /* We probably hit a jprobe.  Call its break handler. */
> +               if (cur->break_handler && cur->break_handler(cur, regs)) {
> +                       kcb->kprobe_status = KPROBE_HIT_SS;
> +                       setup_singlestep(cur, regs, kcb, 0);
> +                       return;
> +               }
> +       } else {
> +               /* breakpoint is removed, now in a race
> +                * Return back to original instruction & continue.
> +                */

Can you tidy this up by combining the "do nothing" case with the
"*(kprobe_opcode_t *) addr != BRK64_OPCODE_KPROBES" case?

> +       }
> +}
> +
> +static int __kprobes
> +kprobe_ss_hit(struct kprobe_ctlblk *kcb, unsigned long addr)
> +{
> +       if ((kcb->ss_ctx.ss_status == KPROBES_STEP_PENDING)
> +           && (kcb->ss_ctx.match_addr == addr)) {
> +               clear_ss_context(kcb);  /* clear pending ss */
> +               return DBG_HOOK_HANDLED;
> +       }
> +       /* not ours, kprobes should ignore it */
> +       return DBG_HOOK_ERROR;
> +}
> +
> +int __kprobes
> +kprobe_single_step_handler(struct pt_regs *regs, unsigned int esr)
> +{
> +       struct kprobe_ctlblk *kcb = get_kprobe_ctlblk();
> +       int retval;
> +
> +       /* return error if this is not our step */
> +       retval = kprobe_ss_hit(kcb, instruction_pointer(regs));
> +
> +       if (retval == DBG_HOOK_HANDLED) {
> +               kprobes_restore_local_irqflag(regs);
> +               kernel_disable_single_step();
> +
> +               if (kcb->kprobe_status == KPROBE_REENTER)
> +                       spsr_set_debug_flag(regs, 1);
> +
> +               post_kprobe_handler(kcb, regs);
> +       }
> +
> +       return retval;
> +}
> +
> +int __kprobes
> +kprobe_breakpoint_handler(struct pt_regs *regs, unsigned int esr)
> +{
> +       kprobe_handler(regs);
> +       return DBG_HOOK_HANDLED;
> +}
> +
> +int __kprobes setjmp_pre_handler(struct kprobe *p, struct pt_regs *regs)
> +{
> +       struct jprobe *jp = container_of(p, struct jprobe, kp);
> +       struct kprobe_ctlblk *kcb = get_kprobe_ctlblk();
> +       long stack_ptr = stack_pointer(regs);
> +
> +       kcb->jprobe_saved_regs = *regs;
> +       memcpy(kcb->jprobes_stack, (void *)stack_ptr,
> +              MIN_STACK_SIZE(stack_ptr));
> +
> +       instruction_pointer(regs) = (long)jp->entry;
> +       preempt_disable();
> +       return 1;
> +}
> +
> +void __kprobes jprobe_return(void)
> +{
> +       struct kprobe_ctlblk *kcb = get_kprobe_ctlblk();
> +
> +       /*
> +        * Jprobe handler return by entering break exception,
> +        * encoded same as kprobe, but with following conditions
> +        * -a magic number in x0 to identify from rest of other kprobes.
> +        * -restore stack addr to original saved pt_regs
> +        */
> +       asm volatile ("ldr x0, [%0]\n\t"
> +                     "mov sp, x0\n\t"
> +                     "ldr x0, =" __stringify(JPROBES_MAGIC_NUM) "\n\t"

This feels flakey to me and I worry that we could end up invoking the
jprobe_return handler thanks to a kprobe with the right "magic" value in
x0 and a race with the kprobe getting removed.

Why can't we do what x86 does and check the originating PC falls inside
the return code?

> +                     "BRK %1\n\t"
> +                     "NOP\n\t"

No need to capitalise these two instructions. Also, what's the nop for?

> +                     :
> +                     : "r"(&kcb->jprobe_saved_regs.sp),

Why do you need to do this indirectly? (as opposed to just moving straight
to sp).

> +                     "I"(BRK64_ESR_KPROBES)
> +                     : "memory");

unreachable()?

> +}
> +
> +int __kprobes longjmp_break_handler(struct kprobe *p, struct pt_regs *regs)
> +{
> +       struct kprobe_ctlblk *kcb = get_kprobe_ctlblk();
> +       long stack_addr = kcb->jprobe_saved_regs.sp;
> +       long orig_sp = stack_pointer(regs);
> +       struct jprobe *jp = container_of(p, struct jprobe, kp);
> +
> +       if (regs->regs[0] == JPROBES_MAGIC_NUM) {

Change the polarity with early return and lose a level of indentation below.

> +               if (orig_sp != stack_addr) {
> +                       struct pt_regs *saved_regs =
> +                           (struct pt_regs *)kcb->jprobe_saved_regs.sp;
> +                       pr_err("current sp %lx does not match saved sp %lx\n",
> +                              orig_sp, stack_addr);
> +                       pr_err("Saved registers for jprobe %p\n", jp);
> +                       show_regs(saved_regs);
> +                       pr_err("Current registers\n");
> +                       show_regs(regs);
> +                       BUG();
> +               }
> +               *regs = kcb->jprobe_saved_regs;
> +               memcpy((void *)stack_addr, kcb->jprobes_stack,
> +                      MIN_STACK_SIZE(stack_addr));
> +               preempt_enable_no_resched();
> +               return 1;
> +       }
> +       return 0;
> +}
> +
> +int __init arch_init_kprobes(void)
> +{
> +       return 0;
> +}
> diff --git a/arch/arm64/kernel/kprobes.h b/arch/arm64/kernel/kprobes.h
> new file mode 100644
> index 0000000..e98ad60
> --- /dev/null
> +++ b/arch/arm64/kernel/kprobes.h
> @@ -0,0 +1,24 @@
> +/*
> + * arch/arm64/kernel/kprobes.h
> + *
> + * Copyright (C) 2013 Linaro Limited.
> + *
> + * 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.
> + */
> +
> +#ifndef _ARM_KERNEL_KPROBES_H
> +#define _ARM_KERNEL_KPROBES_H
> +
> +#define JPROBES_MAGIC_NUM      0xa5a5a5a5a5a5a5a5
> +
> +/* Move this out to appropriate header file */
> +int fixup_exception(struct pt_regs *regs);
> +
> +#endif /* _ARM_KERNEL_KPROBES_H */

I don't think this warrants an extra header. Use uaccess.h and stick
the magic number somewhere else if you still need it.

> diff --git a/arch/arm64/kernel/vmlinux.lds.S b/arch/arm64/kernel/vmlinux.lds.S
> index 9807333..1fa6adc 100644
> --- a/arch/arm64/kernel/vmlinux.lds.S
> +++ b/arch/arm64/kernel/vmlinux.lds.S
> @@ -100,6 +100,7 @@ SECTIONS
>                         TEXT_TEXT
>                         SCHED_TEXT
>                         LOCK_TEXT
> +                       KPROBES_TEXT
>                         HYPERVISOR_TEXT
>                         IDMAP_TEXT
>                         *(.fixup)
> diff --git a/arch/arm64/mm/fault.c b/arch/arm64/mm/fault.c
> index 94d98cd..01bf525 100644
> --- a/arch/arm64/mm/fault.c
> +++ b/arch/arm64/mm/fault.c
> @@ -39,6 +39,28 @@
>
>  static const char *fault_name(unsigned int esr);
>
> +#ifdef CONFIG_KPROBES
> +static inline int notify_page_fault(struct pt_regs *regs, unsigned int esr)
> +{

The function name isn't very descriptive. Why not follow x86 with
"kprobes_fault"?

> +       int ret = 0;
> +
> +       /* kprobe_running() needs smp_processor_id() */

But we could already be running on a different core from the one that
triggered the fault, so isn't this racy?

> +       if (!user_mode(regs)) {
> +               preempt_disable();
> +               if (kprobe_running() && kprobe_fault_handler(regs, esr))
> +                       ret = 1;
> +               preempt_enable();
> +       }
> +
> +       return ret;
> +}

Will


From paul at pwsan.com  Wed Aug 12 06:37:35 2015
From: paul at pwsan.com (Paul Walmsley)
Date: Wed, 12 Aug 2015 13:37:35 +0000 (UTC)
Subject: OMAP baseline test results for v4.2-rc5
Message-ID: <alpine.DEB.2.02.1508121336330.7154@utopia.booyaka.com>


Here are some basic OMAP test results for Linux v4.2-rc5.
Logs and other details at:

    http://www.pwsan.com/omap/testlogs/test_v4.2-rc5/20150809200304/


Test summary
------------

Build: uImage:
    Pass ( 3/ 3): omap1_defconfig, omap1_defconfig_1510innovator_only,
		  omap1_defconfig_5912osk_only

Build: uImage+dtb:
    Pass (13/13): omap2plus_defconfig_am33xx_only/am335x-bone,
		  omap2plus_defconfig/omap4-panda,
		  omap2plus_defconfig/omap4-panda-es,
		  omap2plus_defconfig/omap4-var-stk-om44,
		  omap2plus_defconfig/omap3-evm-37xx,
		  omap2plus_defconfig_n800_only_a/omap2420-n800,
		  omap2plus_defconfig/omap2430-sdp,
		  omap2plus_defconfig/am3517-evm,
		  omap2plus_defconfig/omap3-beagle,
		  omap2plus_defconfig/omap3-beagle-xm,
		  omap2plus_defconfig/omap3-sbc-t3517,
		  omap2plus_defconfig/omap5-uevm,
		  omap2plus_defconfig/omap5-sbc-t54

Build: zImage:
    Pass (17/17): omap2plus_defconfig, omap2plus_defconfig_am33xx_only,
		  omap2plus_defconfig_n800_only_a,
		  omap2plus_defconfig_n800_multi_omap2xxx,
		  omap2plus_defconfig_2430sdp_only,
		  omap2plus_defconfig_cpupm, omap2plus_defconfig_no_pm,
		  omap2plus_defconfig_omap2_4_only,
		  omap2plus_defconfig_omap3_4_only,
		  omap2plus_defconfig_omap5_only,
		  omap2plus_defconfig_dra7xx_only,
		  omap2plus_defconfig_am43xx_only,
		  rmk_omap3430_ldp_oldconfig,
		  rmk_omap3430_ldp_allnoconfig,
		  rmk_omap4430_sdp_oldconfig,
		  rmk_omap4430_sdp_allnoconfig, multi_v7_defconfig

Build warnings from toolchain: uImage:
    (none)

Build warnings from toolchain: uImage+dtb:
    (none)

Build warnings from toolchain: zImage:
    FAIL (10/17): omap2plus_defconfig, omap2plus_defconfig_am33xx_only,
		  omap2plus_defconfig_2430sdp_only,
		  omap2plus_defconfig_cpupm, omap2plus_defconfig_no_pm,
		  omap2plus_defconfig_omap2_4_only,
		  omap2plus_defconfig_omap3_4_only,
		  omap2plus_defconfig_omap5_only,
		  omap2plus_defconfig_dra7xx_only,
		  omap2plus_defconfig_am43xx_only

Boot to userspace:
    FAIL ( 1/17): 2430sdp
    skip ( 3/17): 5912osk, 3517evm, 5430es2sbct54
    Pass (13/17): am335xbonelt, am335xbone, 4430es2panda, 4460pandaes,
		  4460varsomom, 37xxevm, 3530es3beagle, 3530es31beagle,
		  3730beaglexm, 3730es12beaglexm, cmt3517, 5430es2uevm,
		  2420n800

Kernel warnings during boot to userspace:
    FAIL ( 2/17): 4430es2panda, cmt3517

PM: chip retention via suspend:
    FAIL ( 6/11): am335xbonelt, 4430es2panda, 4460varsomom, 37xxevm,
		  2430sdp, 5430es2uevm
    Pass ( 5/11): 4460pandaes, 3530es3beagle, 3530es31beagle,
		  3730beaglexm, 3730es12beaglexm

PM: chip retention via dynamic idle:
    FAIL ( 6/11): am335xbonelt, 4430es2panda, 4460varsomom, 37xxevm,
		  2430sdp, 5430es2uevm
    Pass ( 5/11): 4460pandaes, 3530es3beagle, 3530es31beagle,
		  3730beaglexm, 3730es12beaglexm

PM: chip off (except CORE, due to errata) via suspend:
    Pass ( 1/ 1): 3730beaglexm

PM: chip off (except CORE, due to errata) via dynamic idle:
    Pass ( 1/ 1): 3730beaglexm

PM: chip off via suspend:
    FAIL ( 1/ 4): 37xxevm
    Pass ( 3/ 4): 3530es3beagle, 3530es31beagle, 3730es12beaglexm

PM: chip off via dynamic idle:
    FAIL ( 1/ 4): 37xxevm
    Pass ( 3/ 4): 3530es3beagle, 3530es31beagle, 3730es12beaglexm

Kernel warnings during PM test:
    FAIL ( 1/17): 4430es2panda

Obsolete Kconfig symbols:
    FAIL ( 1/20): multi_v7_defconfig


vmlinux object size
(delta in bytes from test_v4.2-rc5 (74d33293e467df61de1b1d8b2fbe29e550dec33b)):
   text     data      bss    total  kernel
      0        0        0        0  omap1_defconfig
      0        0        0        0  omap1_defconfig_1510innovator_only
      0        0        0        0  omap1_defconfig_5912osk_only
      0        0        0        0  multi_v7_defconfig
      0        0        0        0  omap2plus_defconfig
      0        0        0        0  omap2plus_defconfig_2430sdp_only
      0        0        0        0  omap2plus_defconfig_am33xx_only
      0        0        0        0  omap2plus_defconfig_am43xx_only
      0        0        0        0  omap2plus_defconfig_cpupm
      0        0        0        0  omap2plus_defconfig_dra7xx_only
      0        0        0        0  omap2plus_defconfig_n800_multi_omap2xxx
      0        0        0        0  omap2plus_defconfig_n800_only_a
      0        0        0        0  omap2plus_defconfig_no_pm
      0        0        0        0  omap2plus_defconfig_omap2_4_only
      0        0        0        0  omap2plus_defconfig_omap3_4_only
      0        0        0        0  omap2plus_defconfig_omap5_only
      0        0        0        0  rmk_omap3430_ldp_allnoconfig
      0        0        0        0  rmk_omap3430_ldp_oldconfig
      0        0        0        0  rmk_omap4430_sdp_allnoconfig
      0        0        0        0  rmk_omap4430_sdp_oldconfig

Boot-time memory difference
(delta in bytes from test_v4.2-rc5 (74d33293e467df61de1b1d8b2fbe29e550dec33b))
  avail  rsrvd   high  freed  board          kconfig
  (no differences)



From hramrach at gmail.com  Wed Aug 12 06:37:27 2015
From: hramrach at gmail.com (Michal Suchanek)
Date: Wed, 12 Aug 2015 15:37:27 +0200
Subject: [linux-sunxi] [PATCH 3/3] mmc: sunxi: use controller automatic
 clock gating.
In-Reply-To: <55CB47D8.4010207@schinagl.nl>
References: <cover.1439381423.git.hramrach@gmail.com>
 <c33b221f9b622e3bad9d855a7ad1887b82827244.1439381423.git.hramrach@gmail.com>
 <55CB3D92.6040403@redhat.com> <55CB47D8.4010207@schinagl.nl>
Message-ID: <CAOMqctSdkPgDfBCNsGNsNnoh4GqVW59oZC3q9HX3gY_NneMPKw@mail.gmail.com>

On 12 August 2015 at 15:19, Olliver Schinagl <oliver+list at schinagl.nl> wrote:
> Hey,
>
> On 12-08-15 14:35, Hans de Goede wrote:
>>
>> Hi,
>>
>> On 12-08-15 14:23, Michal Suchanek wrote:
>>>
>>> When core does not set the MMC_QUIRK_BROKEN_CLK_GATING flag enable
>>> automatic hardware controlled clock gating on the mmc interface.
>>>
>>> Signed-off-by: Michal Suchanek <hramrach at gmail.com>
>>
>>
>> In general this looks good, but I wonder how intensively this has
>> been tested ?
>
> It doesn't matter actually, it took some time longer, but the mmc still
> craps out even with Michal's 3 patches. I'll revert hans's earlier patch
> again and do a bit more extensive testing.

Does the oclk switch timeout even after 750ms?

In some earlier tests I tried to enable/disable the clock repeatedly
when it failed but it seemed to have little effect on the total time
it took to disable the clock in the end.

Maybe it would be worh trying to set the timeout to some insanely long
value and test stability with that. I picked 750 as around twice the
maximum time it ever took on my board.

Thanks

Michal


From yamada.masahiro at socionext.com  Wed Aug 12 06:39:47 2015
From: yamada.masahiro at socionext.com (Masahiro Yamada)
Date: Wed, 12 Aug 2015 22:39:47 +0900
Subject: [PATCH v2 0/4] Device Tree updates of UniPhier SoCs for Linux 4.3
In-Reply-To: <20150811132049.GK30181@localhost>
References: <1438857468-9740-1-git-send-email-yamada.masahiro@socionext.com>
 <20150811132049.GK30181@localhost>
Message-ID: <CAK7LNAS_Tx=-it9LFg1K7i-URu1Dx_2xnHPkgM1KJkBFb9q4ig@mail.gmail.com>

2015-08-11 22:20 GMT+09:00 Olof Johansson <olof at lixom.net>:
> On Thu, Aug 06, 2015 at 07:37:44PM +0900, Masahiro Yamada wrote:
>> Hi Olof and Arnd,
>>
>> Here are a little more updates for device trees for UniPhier SoCs.
>>
>> Please consider applying this series to your ARM-SOC tree.
>>
>> Thanks!
>
> Hi,
>
> Please always comment on when the previous when you respin. I didn't
> see this thread until after I had applied v1.
>
> I've taken 2/4 directly now, since it's the only difference.


Instead, build fails between commit a5e921b4771 and 63ef577d9
because 2/4 is a pre-requisite patch for 3/4 and /4/4.


Maybe I should have sent a pull-request instead of patches.





-- 
Best Regards
Masahiro Yamada


From will.deacon at arm.com  Wed Aug 12 06:41:16 2015
From: will.deacon at arm.com (Will Deacon)
Date: Wed, 12 Aug 2015 14:41:16 +0100
Subject: [PATCH v5 2/6] x86/kasan, mm: introduce generic
 kasan_populate_zero_shadow()
In-Reply-To: <CAPAsAGwnhnqJCh=sc97-=qrYHNQnDSjVR-xGertoMiNWHDbhrw@mail.gmail.com>
References: <1439259499-13913-1-git-send-email-ryabinin.a.a@gmail.com>
 <1439259499-13913-3-git-send-email-ryabinin.a.a@gmail.com>
 <20150811154117.GH23307@e104818-lin.cambridge.arm.com>
 <55CA21E8.2060704@gmail.com>
 <20150811164010.GJ23307@e104818-lin.cambridge.arm.com>
 <CAPAsAGwDNpRBLAvyCSpR9ZO9tAmHx-XYjVDZPECeQkU0WOw5jg@mail.gmail.com>
 <20150812093701.GH22485@arm.com>
 <CAPAsAGwnhnqJCh=sc97-=qrYHNQnDSjVR-xGertoMiNWHDbhrw@mail.gmail.com>
Message-ID: <20150812134116.GB23540@arm.com>

On Wed, Aug 12, 2015 at 01:19:03PM +0100, Andrey Ryabinin wrote:
> 2015-08-12 12:37 GMT+03:00 Will Deacon <will.deacon at arm.com>:
> > On Wed, Aug 12, 2015 at 10:30:37AM +0100, Andrey Ryabinin wrote:
> >> 2015-08-11 19:40 GMT+03:00 Catalin Marinas <catalin.marinas at arm.com>:
> >> >
> >> > Not sure how you plan to merge it though since there are x86
> >> > dependencies. I could send the whole series via tip or the mm tree (and
> >> > I guess it's pretty late for 4.3).
> >>
> >> Via mm tree, I guess.
> >> If this is too late for 4.3, then I'll update changelog and send v6
> >> after 4.3-rc1 release.
> >
> > That's probably the best bet, as I suspect we'll get some non-trivial
> > conflicts with the arm64 tree at this stage.
> >
> Or, if x86 maintainers are agree to take first 2 patches in 4.3,
> the rest of the series could go into arm64 tree later.

Yup, that would be even better for us!

Will


From marc.zyngier at arm.com  Wed Aug 12 06:41:42 2015
From: marc.zyngier at arm.com (Marc Zyngier)
Date: Wed, 12 Aug 2015 14:41:42 +0100
Subject: [PATCH 4/6] irqchip: GIC: Use chip_data instead of handler_data
 for cascaded interrupts
In-Reply-To: <55C9C42E.8070602@linaro.org>
References: <1436447951-22357-1-git-send-email-marc.zyngier@arm.com>
 <1436447951-22357-5-git-send-email-marc.zyngier@arm.com>
 <55C9C42E.8070602@linaro.org>
Message-ID: <55CB4D16.9070608@arm.com>

On 11/08/15 10:45, Eric Auger wrote:
> Hi Marc,
> On 07/09/2015 03:19 PM, Marc Zyngier wrote:
>> When used as a primary interrupt controller, the GIC driver uses
>> irq_data->chip_data to extract controller-specific information.
>>
>> When used as a secondary interrupt controller, it uses handler_data
>> instead. As this difference is relatively pointless and only creates
>> confusion, change the secondary path to match what the rest of the
>> driver does.
> not really related to this series' topic, is it?

It is. Or was. We use the handler_data field to hold the vcpu
information, but that's also used by the chained interrupt handler to
find out which secondary it is.

But this patch is wrong anyway, as it entirely breaks secondary GICs (I
found out when I merged this with a patch from Jon Hunter fixing some
other related stuff). Took me hours to get an EB up and running!

I have a working version now, which makes this patch irrelevant.

Thanks,

	M.
-- 
Jazz is not dead. It just smells funny...


From will.deacon at arm.com  Wed Aug 12 06:45:26 2015
From: will.deacon at arm.com (Will Deacon)
Date: Wed, 12 Aug 2015 14:45:26 +0100
Subject: [PATCH] arm64: add ioread64be and iowrite64be macros
In-Reply-To: <1439382275-21678-1-git-send-email-horia.geanta@freescale.com>
References: <1439382275-21678-1-git-send-email-horia.geanta@freescale.com>
Message-ID: <20150812134526.GD23540@arm.com>

On Wed, Aug 12, 2015 at 01:24:35PM +0100, Horia Geant? wrote:

Please add a commit message here, preferably explaining why you appear
to be adding a macro that doesn't have any callers in mainline linux.

Will

> Signed-off-by: Alex Porosanu <alexandru.porosanu at freescale.com>
> Signed-off-by: Horia Geant? <horia.geanta at freescale.com>
> ---
>  arch/arm64/include/asm/io.h | 4 +++-
>  1 file changed, 3 insertions(+), 1 deletion(-)
> 
> diff --git a/arch/arm64/include/asm/io.h b/arch/arm64/include/asm/io.h
> index 44be1e03ed65..9b6e408cfa51 100644
> --- a/arch/arm64/include/asm/io.h
> +++ b/arch/arm64/include/asm/io.h
> @@ -174,13 +174,15 @@ extern void __iomem *ioremap_cache(phys_addr_t phys_addr, size_t size);
>  #define iounmap				__iounmap
>  
>  /*
> - * io{read,write}{16,32}be() macros
> + * io{read,write}{16,32,64}be() macros
>   */
>  #define ioread16be(p)		({ __u16 __v = be16_to_cpu((__force __be16)__raw_readw(p)); __iormb(); __v; })
>  #define ioread32be(p)		({ __u32 __v = be32_to_cpu((__force __be32)__raw_readl(p)); __iormb(); __v; })
> +#define ioread64be(p)		({ __u64 __v = be64_to_cpu((__force __be64)__raw_readq(p)); __iormb(); __v; })
>  
>  #define iowrite16be(v,p)	({ __iowmb(); __raw_writew((__force __u16)cpu_to_be16(v), p); })
>  #define iowrite32be(v,p)	({ __iowmb(); __raw_writel((__force __u32)cpu_to_be32(v), p); })
> +#define iowrite64be(v,p)	({ __iowmb(); __raw_writeq((__force __u64)cpu_to_be64(v), p); })
>  
>  /*
>   * Convert a physical pointer to a virtual kernel pointer for /dev/mem
> -- 
> 2.4.4
> 


From antoine.tenart at free-electrons.com  Wed Aug 12 06:51:35 2015
From: antoine.tenart at free-electrons.com (Antoine Tenart)
Date: Wed, 12 Aug 2015 15:51:35 +0200
Subject: [PATCH v3 3/5] ARM: berlin: add a PWM node on the BG2Q
In-Reply-To: <1439387497-6863-1-git-send-email-antoine.tenart@free-electrons.com>
References: <1439387497-6863-1-git-send-email-antoine.tenart@free-electrons.com>
Message-ID: <1439387497-6863-4-git-send-email-antoine.tenart@free-electrons.com>

This patch adds a PWM node in the Berlin BG2Q device tree, using the
newly added Berlin PWM driver.

Signed-off-by: Antoine Tenart <antoine.tenart at free-electrons.com>
---
 arch/arm/boot/dts/berlin2q.dtsi | 7 +++++++
 1 file changed, 7 insertions(+)

diff --git a/arch/arm/boot/dts/berlin2q.dtsi b/arch/arm/boot/dts/berlin2q.dtsi
index 63a48490e2f9..5bfa71a87617 100644
--- a/arch/arm/boot/dts/berlin2q.dtsi
+++ b/arch/arm/boot/dts/berlin2q.dtsi
@@ -477,6 +477,13 @@
 			status = "disabled";
 		};
 
+		pwm: pwm at f20000 {
+			compatible = "marvell,berlin-pwm";
+			reg = <0xf20000 0x40>;
+			clocks = <&chip_clk CLKID_CFG>;
+			#pwm-cells = <3>;
+		};
+
 		apb at fc0000 {
 			compatible = "simple-bus";
 			#address-cells = <1>;
-- 
2.5.0



From antoine.tenart at free-electrons.com  Wed Aug 12 06:51:36 2015
From: antoine.tenart at free-electrons.com (Antoine Tenart)
Date: Wed, 12 Aug 2015 15:51:36 +0200
Subject: [PATCH v3 4/5] ARM: berlin: add a PWM node on the BG2
In-Reply-To: <1439387497-6863-1-git-send-email-antoine.tenart@free-electrons.com>
References: <1439387497-6863-1-git-send-email-antoine.tenart@free-electrons.com>
Message-ID: <1439387497-6863-5-git-send-email-antoine.tenart@free-electrons.com>

This patch adds a PWM node in the Berlin BG2 device tree, using the
newly added Berlin PWM driver.

Signed-off-by: Antoine Tenart <antoine.tenart at free-electrons.com>
---
 arch/arm/boot/dts/berlin2.dtsi | 7 +++++++
 1 file changed, 7 insertions(+)

diff --git a/arch/arm/boot/dts/berlin2.dtsi b/arch/arm/boot/dts/berlin2.dtsi
index ef811de09908..f094b06d16aa 100644
--- a/arch/arm/boot/dts/berlin2.dtsi
+++ b/arch/arm/boot/dts/berlin2.dtsi
@@ -404,6 +404,13 @@
 			};
 		};
 
+		pwm: pwm at f20000 {
+			compatible = "marvell,berlin-pwm";
+			reg = <0xf20000 0x40>;
+			clocks = <&chip_clk CLKID_CFG>;
+			#pwm-cells = <3>;
+		};
+
 		apb at fc0000 {
 			compatible = "simple-bus";
 			#address-cells = <1>;
-- 
2.5.0



From antoine.tenart at free-electrons.com  Wed Aug 12 06:51:34 2015
From: antoine.tenart at free-electrons.com (Antoine Tenart)
Date: Wed, 12 Aug 2015 15:51:34 +0200
Subject: [PATCH v3 2/5] Documentation: bindings: document the Berlin PWM driver
In-Reply-To: <1439387497-6863-1-git-send-email-antoine.tenart@free-electrons.com>
References: <1439387497-6863-1-git-send-email-antoine.tenart@free-electrons.com>
Message-ID: <1439387497-6863-3-git-send-email-antoine.tenart@free-electrons.com>

Following the addition of a Berlin PWM driver, this patch adds the
corresponding documentation.

Signed-off-by: Antoine Tenart <antoine.tenart at free-electrons.com>
Acked-by: Sebastian Hesselbarth <sebastian.hesselbarth at gmail.com>
---
 Documentation/devicetree/bindings/pwm/pwm-berlin.txt | 19 +++++++++++++++++++
 1 file changed, 19 insertions(+)
 create mode 100644 Documentation/devicetree/bindings/pwm/pwm-berlin.txt

diff --git a/Documentation/devicetree/bindings/pwm/pwm-berlin.txt b/Documentation/devicetree/bindings/pwm/pwm-berlin.txt
new file mode 100644
index 000000000000..8f9bc11f8c4c
--- /dev/null
+++ b/Documentation/devicetree/bindings/pwm/pwm-berlin.txt
@@ -0,0 +1,19 @@
+Berlin PWM controller
+
+PWM IP found in Marvell Berlin SoCs.
+
+Required properties:
+- compatible: should be "marvell,berlin-pwm"
+- reg: physical base address and length of the controller's registers
+- clocks: phandle to the input clock
+- #pwm-cells: should be 3. See pwm.txt in this directory for a description of
+  the cells format.
+
+Example:
+
+pwm: pwm at f7f20000 {
+	compatible = "marvell,berlin-pwm";
+	reg = <0xf7f20000 0x40>;
+	clocks = <&chip_clk CLKID_CFG>;
+	#pwm-cells = <3>;
+}
-- 
2.5.0



From antoine.tenart at free-electrons.com  Wed Aug 12 06:51:32 2015
From: antoine.tenart at free-electrons.com (Antoine Tenart)
Date: Wed, 12 Aug 2015 15:51:32 +0200
Subject: [PATCH v3 0/5] ARM: berlin: PWM support
Message-ID: <1439387497-6863-1-git-send-email-antoine.tenart@free-electrons.com>

Hi all,

This series adds a driver for the Marvell Berlin PWM controller, which
has 4 channels.

This has been tested on a BG2Q DMP.

Thanks,

Antoine

Changes since v2:
	- Reworked the prescaler/tcnt calculation
	- Added an input clock
	- Updated the documentation
	- Reordered the pwm node
	- Added some definition for BIT()

Changes since v1:
        - Added a sentinel in berlin_pwm_match[]

Antoine Tenart (5):
  pwm: add the Berlin pwm controller driver
  Documentation: bindings: document the Berlin PWM driver
  ARM: berlin: add a PWM node on the BG2Q
  ARM: berlin: add a PWM node on the BG2
  ARM: berlin: add a PWM node on the BG2CD

 .../devicetree/bindings/pwm/pwm-berlin.txt         |  19 ++
 arch/arm/boot/dts/berlin2.dtsi                     |   7 +
 arch/arm/boot/dts/berlin2cd.dtsi                   |   7 +
 arch/arm/boot/dts/berlin2q.dtsi                    |   7 +
 drivers/pwm/Kconfig                                |   9 +
 drivers/pwm/Makefile                               |   1 +
 drivers/pwm/pwm-berlin.c                           | 227 +++++++++++++++++++++
 7 files changed, 277 insertions(+)
 create mode 100644 Documentation/devicetree/bindings/pwm/pwm-berlin.txt
 create mode 100644 drivers/pwm/pwm-berlin.c

-- 
2.5.0



From antoine.tenart at free-electrons.com  Wed Aug 12 06:51:33 2015
From: antoine.tenart at free-electrons.com (Antoine Tenart)
Date: Wed, 12 Aug 2015 15:51:33 +0200
Subject: [PATCH v3 1/5] pwm: add the Berlin pwm controller driver
In-Reply-To: <1439387497-6863-1-git-send-email-antoine.tenart@free-electrons.com>
References: <1439387497-6863-1-git-send-email-antoine.tenart@free-electrons.com>
Message-ID: <1439387497-6863-2-git-send-email-antoine.tenart@free-electrons.com>

Add a PWM controller driver for the Marvell Berlin SoCs. This PWM
controller has 4 channels.

Signed-off-by: Antoine Tenart <antoine.tenart at free-electrons.com>
---
 drivers/pwm/Kconfig      |   9 ++
 drivers/pwm/Makefile     |   1 +
 drivers/pwm/pwm-berlin.c | 227 +++++++++++++++++++++++++++++++++++++++++++++++
 3 files changed, 237 insertions(+)
 create mode 100644 drivers/pwm/pwm-berlin.c

diff --git a/drivers/pwm/Kconfig b/drivers/pwm/Kconfig
index b1541f40fd8d..1773da8145b8 100644
--- a/drivers/pwm/Kconfig
+++ b/drivers/pwm/Kconfig
@@ -92,6 +92,15 @@ config PWM_BCM2835
 	  To compile this driver as a module, choose M here: the module
 	  will be called pwm-bcm2835.
 
+config PWM_BERLIN
+	tristate "Berlin PWM support"
+	depends on ARCH_BERLIN
+	help
+	  PWM framework driver for Berlin.
+
+	  To compile this driver as a module, choose M here: the module
+	  will be called pwm-berlin.
+
 config PWM_BFIN
 	tristate "Blackfin PWM support"
 	depends on BFIN_GPTIMERS
diff --git a/drivers/pwm/Makefile b/drivers/pwm/Makefile
index ec50eb5b5a8f..670c5fce8bbb 100644
--- a/drivers/pwm/Makefile
+++ b/drivers/pwm/Makefile
@@ -6,6 +6,7 @@ obj-$(CONFIG_PWM_ATMEL_HLCDC_PWM)	+= pwm-atmel-hlcdc.o
 obj-$(CONFIG_PWM_ATMEL_TCB)	+= pwm-atmel-tcb.o
 obj-$(CONFIG_PWM_BCM_KONA)	+= pwm-bcm-kona.o
 obj-$(CONFIG_PWM_BCM2835)	+= pwm-bcm2835.o
+obj-$(CONFIG_PWM_BERLIN)	+= pwm-berlin.o
 obj-$(CONFIG_PWM_BFIN)		+= pwm-bfin.o
 obj-$(CONFIG_PWM_CLPS711X)	+= pwm-clps711x.o
 obj-$(CONFIG_PWM_EP93XX)	+= pwm-ep93xx.o
diff --git a/drivers/pwm/pwm-berlin.c b/drivers/pwm/pwm-berlin.c
new file mode 100644
index 000000000000..f89e25ea5c6d
--- /dev/null
+++ b/drivers/pwm/pwm-berlin.c
@@ -0,0 +1,227 @@
+/*
+ * Marvell Berlin PWM driver
+ *
+ * Copyright (C) 2015 Marvell Technology Group Ltd.
+ *
+ * Antoine Tenart <antoine.tenart at free-electrons.com>
+ *
+ * This file is licensed under the terms of the GNU General Public
+ * License version 2. This program is licensed "as is" without any
+ * warranty of any kind, whether express or implied.
+ */
+
+#include <linux/clk.h>
+#include <linux/io.h>
+#include <linux/kernel.h>
+#include <linux/module.h>
+#include <linux/platform_device.h>
+#include <linux/pwm.h>
+#include <linux/spinlock.h>
+
+#define BERLIN_PWM_EN			0x0
+#define BERLIN_PWM_CONTROL		0x4
+#define BERLIN_PWM_DUTY			0x8
+#define BERLIN_PWM_TCNT			0xc
+
+#define BERLIN_PWM_ENABLE		BIT(0)
+#define BERLIN_PWM_DISABLE		0x0
+#define BERLIN_PWM_INVERT_POLARITY	BIT(3)
+#define BERLIN_PWM_PRESCALE_MASK	0x7
+#define BERLIN_PWM_PRESCALE_MAX		4096
+#define BERLIN_PWM_MAX_TCNT		65535
+
+struct berlin_pwm_chip {
+	struct pwm_chip chip;
+	struct clk *clk;
+	void __iomem *base;
+	spinlock_t lock;
+};
+
+#define to_berlin_pwm_chip(chip)	\
+	container_of((chip), struct berlin_pwm_chip, chip)
+
+#define berlin_pwm_readl(chip, channel, offset)		\
+	readl((chip)->base + (channel) * 0x10 + offset)
+#define berlin_pwm_writel(val, chip, channel, offset)	\
+	writel(val, (chip)->base + (channel) * 0x10 + offset)
+
+/* prescaler table: {1, 4, 8, 16, 64, 256, 1024, 4096} */
+static const u32 prescaler_diff_table[] = {
+	1, 4, 2, 2, 4, 4, 4, 4,
+};
+
+static int berlin_pwm_config(struct pwm_chip *chip, struct pwm_device *pwm,
+			     int duty_ns, int period_ns)
+{
+	struct berlin_pwm_chip *berlin_chip = to_berlin_pwm_chip(chip);
+	int ret, prescale = 0;
+	u32 val, duty, period;
+	u64 cycles;
+
+	cycles = clk_get_rate(berlin_chip->clk);
+	cycles *= period_ns;
+	do_div(cycles, NSEC_PER_SEC);
+
+	while (cycles > BERLIN_PWM_MAX_TCNT)
+		do_div(cycles, prescaler_diff_table[++prescale]);
+
+	if (cycles > BERLIN_PWM_MAX_TCNT)
+		return -EINVAL;
+
+	period = cycles;
+	cycles *= duty_ns;
+	do_div(cycles, period_ns);
+	duty = cycles;
+
+	ret = clk_prepare_enable(berlin_chip->clk);
+	if (ret)
+		return ret;
+
+	spin_lock(&berlin_chip->lock);
+
+	val = berlin_pwm_readl(berlin_chip, pwm->hwpwm, BERLIN_PWM_CONTROL);
+	val &= ~BERLIN_PWM_PRESCALE_MASK;
+	val |= prescale;
+	berlin_pwm_writel(val, berlin_chip, pwm->hwpwm, BERLIN_PWM_CONTROL);
+
+	berlin_pwm_writel(duty, berlin_chip, pwm->hwpwm, BERLIN_PWM_DUTY);
+	berlin_pwm_writel(period, berlin_chip, pwm->hwpwm, BERLIN_PWM_TCNT);
+
+	spin_unlock(&berlin_chip->lock);
+
+	clk_disable_unprepare(berlin_chip->clk);
+
+	return 0;
+}
+
+static int berlin_pwm_set_polarity(struct pwm_chip *chip,
+				   struct pwm_device *pwm,
+				   enum pwm_polarity polarity)
+{
+	struct berlin_pwm_chip *berlin_chip = to_berlin_pwm_chip(chip);
+	int ret;
+	u32 val;
+
+	ret = clk_prepare_enable(berlin_chip->clk);
+	if (ret)
+		return ret;
+
+	spin_lock(&berlin_chip->lock);
+
+	val = berlin_pwm_readl(berlin_chip, pwm->hwpwm, BERLIN_PWM_CONTROL);
+
+	if (polarity == PWM_POLARITY_NORMAL)
+		val &= ~BERLIN_PWM_INVERT_POLARITY;
+	else
+		val |= BERLIN_PWM_INVERT_POLARITY;
+
+	berlin_pwm_writel(val, berlin_chip, pwm->hwpwm, BERLIN_PWM_CONTROL);
+
+	spin_unlock(&berlin_chip->lock);
+
+	clk_disable_unprepare(berlin_chip->clk);
+
+	return 0;
+}
+
+static int berlin_pwm_enable(struct pwm_chip *chip, struct pwm_device *pwm)
+{
+	struct berlin_pwm_chip *berlin_chip = to_berlin_pwm_chip(chip);
+	int ret;
+
+	ret = clk_prepare_enable(berlin_chip->clk);
+	if (ret)
+		return ret;
+
+	spin_lock(&berlin_chip->lock);
+	berlin_pwm_writel(BERLIN_PWM_ENABLE, berlin_chip, pwm->hwpwm, BERLIN_PWM_EN);
+	spin_unlock(&berlin_chip->lock);
+
+	return 0;
+}
+
+static void berlin_pwm_disable(struct pwm_chip *chip, struct pwm_device *pwm)
+{
+	struct berlin_pwm_chip *berlin_chip = to_berlin_pwm_chip(chip);
+
+	spin_lock(&berlin_chip->lock);
+	berlin_pwm_writel(BERLIN_PWM_DISABLE, berlin_chip, pwm->hwpwm, BERLIN_PWM_EN);
+	spin_unlock(&berlin_chip->lock);
+
+	clk_disable_unprepare(berlin_chip->clk);
+}
+
+static const struct pwm_ops berlin_pwm_ops = {
+	.config = berlin_pwm_config,
+	.set_polarity = berlin_pwm_set_polarity,
+	.enable = berlin_pwm_enable,
+	.disable = berlin_pwm_disable,
+	.owner = THIS_MODULE,
+};
+
+static const struct of_device_id berlin_pwm_match[] = {
+	{ .compatible = "marvell,berlin-pwm" },
+	{ },
+};
+MODULE_DEVICE_TABLE(of, berlin_pwm_match);
+
+static int berlin_pwm_probe(struct platform_device *pdev)
+{
+	struct berlin_pwm_chip *pwm;
+	struct resource *res;
+	int ret;
+
+	pwm = devm_kzalloc(&pdev->dev, sizeof(*pwm), GFP_KERNEL);
+	if (!pwm)
+		return -ENOMEM;
+
+	res = platform_get_resource(pdev, IORESOURCE_MEM, 0);
+	pwm->base = devm_ioremap_resource(&pdev->dev, res);
+	if (IS_ERR(pwm->base))
+		return PTR_ERR(pwm->base);
+
+	pwm->clk = devm_clk_get(&pdev->dev, NULL);
+	if (IS_ERR(pwm->clk))
+		return PTR_ERR(pwm->clk);
+
+	pwm->chip.dev = &pdev->dev;
+	pwm->chip.ops = &berlin_pwm_ops;
+	pwm->chip.base = -1;
+	pwm->chip.npwm = 4;
+	pwm->chip.can_sleep = true;
+	pwm->chip.of_xlate = of_pwm_xlate_with_flags;
+	pwm->chip.of_pwm_n_cells = 3;
+
+	spin_lock_init(&pwm->lock);
+
+	ret = pwmchip_add(&pwm->chip);
+	if (ret < 0) {
+		dev_err(&pdev->dev, "Failed to add PWM chip: %d\n", ret);
+		return ret;
+	}
+
+	platform_set_drvdata(pdev, pwm);
+
+	return 0;
+}
+
+static int berlin_pwm_remove(struct platform_device *pdev)
+{
+	struct berlin_pwm_chip *pwm = platform_get_drvdata(pdev);
+
+	return pwmchip_remove(&pwm->chip);
+}
+
+static struct platform_driver berlin_pwm_driver = {
+	.probe	= berlin_pwm_probe,
+	.remove	= berlin_pwm_remove,
+	.driver	= {
+		.name	= "berlin-pwm",
+		.of_match_table = berlin_pwm_match,
+	},
+};
+module_platform_driver(berlin_pwm_driver);
+
+MODULE_AUTHOR("Antoine Tenart <antoine.tenart at free-electrons.com>");
+MODULE_DESCRIPTION("Marvell Berlin PWM driver");
+MODULE_LICENSE("GPL v2");
-- 
2.5.0



From antoine.tenart at free-electrons.com  Wed Aug 12 06:51:37 2015
From: antoine.tenart at free-electrons.com (Antoine Tenart)
Date: Wed, 12 Aug 2015 15:51:37 +0200
Subject: [PATCH v3 5/5] ARM: berlin: add a PWM node on the BG2CD
In-Reply-To: <1439387497-6863-1-git-send-email-antoine.tenart@free-electrons.com>
References: <1439387497-6863-1-git-send-email-antoine.tenart@free-electrons.com>
Message-ID: <1439387497-6863-6-git-send-email-antoine.tenart@free-electrons.com>

This patch adds a PWM node in the Berlin BG2CD device tree, using the
newly added Berlin PWM driver.

Signed-off-by: Antoine Tenart <antoine.tenart at free-electrons.com>
---
 arch/arm/boot/dts/berlin2cd.dtsi | 7 +++++++
 1 file changed, 7 insertions(+)

diff --git a/arch/arm/boot/dts/berlin2cd.dtsi b/arch/arm/boot/dts/berlin2cd.dtsi
index 900213d78a32..5d984f58dde7 100644
--- a/arch/arm/boot/dts/berlin2cd.dtsi
+++ b/arch/arm/boot/dts/berlin2cd.dtsi
@@ -368,6 +368,13 @@
 			status = "disabled";
 		};
 
+		pwm: pwm at f20000 {
+			compatible = "marvell,berlin-pwm";
+			reg = <0xf20000 0x40>;
+			clocks = <&chip_clk CLKID_CFG>;
+			#pwm-cells = <3>;
+		};
+
 		apb at fc0000 {
 			compatible = "simple-bus";
 			#address-cells = <1>;
-- 
2.5.0



From horia.geanta at freescale.com  Wed Aug 12 07:12:39 2015
From: horia.geanta at freescale.com (=?UTF-8?q?Horia=20Geant=C4=83?=)
Date: Wed, 12 Aug 2015 17:12:39 +0300
Subject: [PATCH v2] arm64: add ioread64be and iowrite64be macros
In-Reply-To: <20150812134526.GD23540@arm.com>
References: <20150812134526.GD23540@arm.com>
Message-ID: <1439388759-4299-1-git-send-email-horia.geanta@freescale.com>

This will allow device drivers to consistently use io{read,write}XXbe
macros in all cases.

Signed-off-by: Alex Porosanu <alexandru.porosanu at freescale.com>
Signed-off-by: Horia Geant? <horia.geanta at freescale.com>
---

I am planning to use the macros in a subsequent patch that revamps
the I/O accessors in drivers/crypto/caam/regs.h

Let me know if you prefer having this change submitted as part of a
patchset (bundled with the caller/user of the macros).

 arch/arm64/include/asm/io.h | 4 +++-
 1 file changed, 3 insertions(+), 1 deletion(-)

diff --git a/arch/arm64/include/asm/io.h b/arch/arm64/include/asm/io.h
index 44be1e03ed65..9b6e408cfa51 100644
--- a/arch/arm64/include/asm/io.h
+++ b/arch/arm64/include/asm/io.h
@@ -174,13 +174,15 @@ extern void __iomem *ioremap_cache(phys_addr_t phys_addr, size_t size);
 #define iounmap				__iounmap
 
 /*
- * io{read,write}{16,32}be() macros
+ * io{read,write}{16,32,64}be() macros
  */
 #define ioread16be(p)		({ __u16 __v = be16_to_cpu((__force __be16)__raw_readw(p)); __iormb(); __v; })
 #define ioread32be(p)		({ __u32 __v = be32_to_cpu((__force __be32)__raw_readl(p)); __iormb(); __v; })
+#define ioread64be(p)		({ __u64 __v = be64_to_cpu((__force __be64)__raw_readq(p)); __iormb(); __v; })
 
 #define iowrite16be(v,p)	({ __iowmb(); __raw_writew((__force __u16)cpu_to_be16(v), p); })
 #define iowrite32be(v,p)	({ __iowmb(); __raw_writel((__force __u32)cpu_to_be32(v), p); })
+#define iowrite64be(v,p)	({ __iowmb(); __raw_writeq((__force __u64)cpu_to_be64(v), p); })
 
 /*
  * Convert a physical pointer to a virtual kernel pointer for /dev/mem
-- 
2.4.4



From paul at pwsan.com  Wed Aug 12 07:15:17 2015
From: paul at pwsan.com (Paul Walmsley)
Date: Wed, 12 Aug 2015 14:15:17 +0000 (UTC)
Subject: OMAP baseline test results for v4.2-rc6
Message-ID: <alpine.DEB.2.02.1508121337410.7154@utopia.booyaka.com>


Here are some basic OMAP test results for Linux v4.2-rc6.
Logs and other details at:

    http://www.pwsan.com/omap/testlogs/test_v4.2-rc6/20150810114017/


Test summary
------------

Build: uImage:
    Pass ( 3/ 3): omap1_defconfig, omap1_defconfig_1510innovator_only,
		  omap1_defconfig_5912osk_only

Build: uImage+dtb:
    Pass (13/13): omap2plus_defconfig_am33xx_only/am335x-bone,
		  omap2plus_defconfig/omap4-panda,
		  omap2plus_defconfig/omap4-panda-es,
		  omap2plus_defconfig/omap4-var-stk-om44,
		  omap2plus_defconfig/omap3-evm-37xx,
		  omap2plus_defconfig_n800_only_a/omap2420-n800,
		  omap2plus_defconfig/omap2430-sdp,
		  omap2plus_defconfig/am3517-evm,
		  omap2plus_defconfig/omap3-beagle,
		  omap2plus_defconfig/omap3-beagle-xm,
		  omap2plus_defconfig/omap3-sbc-t3517,
		  omap2plus_defconfig/omap5-uevm,
		  omap2plus_defconfig/omap5-sbc-t54

Build: zImage:
    Pass (17/17): omap2plus_defconfig, omap2plus_defconfig_am33xx_only,
		  omap2plus_defconfig_n800_only_a,
		  omap2plus_defconfig_n800_multi_omap2xxx,
		  omap2plus_defconfig_2430sdp_only,
		  omap2plus_defconfig_cpupm, omap2plus_defconfig_no_pm,
		  omap2plus_defconfig_omap2_4_only,
		  omap2plus_defconfig_omap3_4_only,
		  omap2plus_defconfig_omap5_only,
		  omap2plus_defconfig_dra7xx_only,
		  omap2plus_defconfig_am43xx_only,
		  rmk_omap3430_ldp_oldconfig,
		  rmk_omap3430_ldp_allnoconfig,
		  rmk_omap4430_sdp_oldconfig,
		  rmk_omap4430_sdp_allnoconfig, multi_v7_defconfig

Build warnings from toolchain: uImage:
    (none)

Build warnings from toolchain: uImage+dtb:
    (none)

Build warnings from toolchain: zImage:
    FAIL (10/17): omap2plus_defconfig, omap2plus_defconfig_am33xx_only,
		  omap2plus_defconfig_2430sdp_only,
		  omap2plus_defconfig_cpupm, omap2plus_defconfig_no_pm,
		  omap2plus_defconfig_omap2_4_only,
		  omap2plus_defconfig_omap3_4_only,
		  omap2plus_defconfig_omap5_only,
		  omap2plus_defconfig_dra7xx_only,
		  omap2plus_defconfig_am43xx_only

Boot to userspace:
    FAIL ( 1/17): 2430sdp
    skip ( 3/17): 5912osk, 3517evm, 5430es2sbct54
    Pass (13/17): am335xbonelt, am335xbone, 4430es2panda, 4460pandaes,
		  4460varsomom, 37xxevm, 3530es3beagle, 3530es31beagle,
		  3730beaglexm, 3730es12beaglexm, cmt3517, 5430es2uevm,
		  2420n800

Kernel warnings during boot to userspace:
    FAIL ( 2/17): 4430es2panda, cmt3517

PM: chip retention via suspend:
    FAIL ( 6/11): am335xbonelt, 4430es2panda, 4460varsomom, 37xxevm,
		  2430sdp, 5430es2uevm
    Pass ( 5/11): 4460pandaes, 3530es3beagle, 3530es31beagle,
		  3730beaglexm, 3730es12beaglexm

PM: chip retention via dynamic idle:
    FAIL ( 6/11): am335xbonelt, 4430es2panda, 4460varsomom, 37xxevm,
		  2430sdp, 5430es2uevm
    Pass ( 5/11): 4460pandaes, 3530es3beagle, 3530es31beagle,
		  3730beaglexm, 3730es12beaglexm

PM: chip off (except CORE, due to errata) via suspend:
    Pass ( 1/ 1): 3730beaglexm

PM: chip off (except CORE, due to errata) via dynamic idle:
    Pass ( 1/ 1): 3730beaglexm

PM: chip off via suspend:
    FAIL ( 1/ 4): 37xxevm
    Pass ( 3/ 4): 3530es3beagle, 3530es31beagle, 3730es12beaglexm

PM: chip off via dynamic idle:
    FAIL ( 1/ 4): 37xxevm
    Pass ( 3/ 4): 3530es3beagle, 3530es31beagle, 3730es12beaglexm

Kernel warnings during PM test:
    FAIL ( 1/17): 4430es2panda

Obsolete Kconfig symbols:
    FAIL ( 1/20): multi_v7_defconfig


vmlinux object size
(delta in bytes from test_v4.2-rc5 (74d33293e467df61de1b1d8b2fbe29e550dec33b)):
   text     data      bss    total  kernel
   +251        0        0     +251  omap1_defconfig
   +251        0        0     +251  omap1_defconfig_1510innovator_only
   +251        0        0     +251  omap1_defconfig_5912osk_only
   +540        0        0     +540  multi_v7_defconfig
  +4443        0        0    +4443  omap2plus_defconfig
   +127        0        0     +127  omap2plus_defconfig_2430sdp_only
   +347        0        0     +347  omap2plus_defconfig_am33xx_only
   +347        0        0     +347  omap2plus_defconfig_am43xx_only
   +347        0        0     +347  omap2plus_defconfig_cpupm
   +347        0        0     +347  omap2plus_defconfig_dra7xx_only
   +415        0        0     +415  omap2plus_defconfig_n800_multi_omap2xxx
   +435        0        0     +435  omap2plus_defconfig_n800_only_a
   +347        0        0     +347  omap2plus_defconfig_no_pm
   +347        0        0     +347  omap2plus_defconfig_omap2_4_only
   +415        0        0     +415  omap2plus_defconfig_omap3_4_only
   +411        0        0     +411  omap2plus_defconfig_omap5_only
   +116      +20      -16     +120  rmk_omap3430_ldp_allnoconfig
   +339        0        0     +339  rmk_omap3430_ldp_oldconfig
   +100      +20      -16     +104  rmk_omap4430_sdp_allnoconfig
   +419        0        0     +419  rmk_omap4430_sdp_oldconfig

Boot-time memory difference
(delta in bytes from test_v4.2-rc5 (74d33293e467df61de1b1d8b2fbe29e550dec33b))
  avail  rsrvd   high  freed  board          kconfig
    -8k     8k      .      .  2430sdp        omap2plus_defconfig
    -8k     8k      .     4k  3530es31beagle omap2plus_defconfig
    -8k     8k      .     4k  3530es3beagle  omap2plus_defconfig
    -8k     8k      .     4k  3730beaglexm   omap2plus_defconfig
    -8k     8k      .     4k  3730es12beaglexmomap2plus_defconfig
    -8k     8k      .     4k  37xxevm        omap2plus_defconfig
    -8k     8k      .     4k  4430es2panda   omap2plus_defconfig
    -8k     8k      .     4k  4460pandaes    omap2plus_defconfig
    -4k     4k      .     4k  4460varsomom   omap2plus_defconfig
    -8k     8k      .     4k  5430es2uevm    omap2plus_defconfig
    -8k     8k      .     4k  am335xbonelt   omap2plus_defconfig



From jungseoklee85 at gmail.com  Wed Aug 12 07:16:19 2015
From: jungseoklee85 at gmail.com (Jungseok Lee)
Date: Wed, 12 Aug 2015 14:16:19 +0000
Subject: [PATCH] arm64: Add __exception_irq_entry definition for function graph
Message-ID: <1439388979-1518-1-git-send-email-jungseoklee85@gmail.com>

The gic_handle_irq() is defined with __exception_irq_entry attribute.
A single remaining work is to add its definition as ARM did. Below
shows how function graph data is changed with these hunks.

A prologue of an interrupt handler is drawn as follows.

- current status

 0)   0.208 us    |  cpuidle_not_available();
 0)               |  default_idle_call() {
 0)               |    arch_cpu_idle() {
 0)               |      __handle_domain_irq() {
 0)               |        irq_enter() {
 0)   0.313 us    |          rcu_irq_enter();
 0)   0.261 us    |          __local_bh_disable_ip();

- with this change

 0)   0.625 us    |  cpuidle_not_available();
 0)               |  default_idle_call() {
 0)               |    arch_cpu_idle() {
 0)   ==========> |
 0)               |      gic_handle_irq() {
 0)               |        __handle_domain_irq() {
 0)               |          irq_enter() {
 0)   0.885 us    |            rcu_irq_enter();
 0)   0.781 us    |            __local_bh_disable_ip();

An epilogue of an interrupt handler is recorded as follows.

- current status

 0)   0.261 us    |          idle_cpu();
 0)               |          rcu_irq_exit() {
 0)   0.521 us    |            rcu_eqs_enter_common.isra.46();
 0)   2.552 us    |          }
 0) ! 322.448 us  |        }
 0) ! 583.437 us  |      }
 0) # 1656.041 us |    }
 0) # 1658.073 us |  }

- with this change

 0)   0.677 us    |            idle_cpu();
 0)               |            rcu_irq_exit() {
 0)   1.770 us    |              rcu_eqs_enter_common.isra.46();
 0)   7.968 us    |            }
 0) # 1803.541 us |          }
 0) # 2626.667 us |        }
 0) # 2632.969 us |      }
 0)   <========== |
 0) # 14425.00 us |    }
 0) # 14430.98 us |  }

Cc: AKASHI Takahiro <takahiro.akashi at linaro.org>
Cc: Marc Zyngier <marc.zyngier at arm.com>
Cc: Rabin Vincent <rabin at rab.in>
Cc: Steven Rostedt <rostedt at goodmis.org>
Signed-off-by: Jungseok Lee <jungseoklee85 at gmail.com>
---
 arch/arm64/include/asm/exception.h |  6 +++++
 arch/arm64/include/asm/traps.h     | 23 ++++++++++++++++--
 2 files changed, 27 insertions(+), 2 deletions(-)

diff --git a/arch/arm64/include/asm/exception.h b/arch/arm64/include/asm/exception.h
index 0303705..6cb7e1a 100644
--- a/arch/arm64/include/asm/exception.h
+++ b/arch/arm64/include/asm/exception.h
@@ -18,7 +18,13 @@
 #ifndef __ASM_EXCEPTION_H
 #define __ASM_EXCEPTION_H
 
+#include <linux/ftrace.h>
+
 #define __exception	__attribute__((section(".exception.text")))
+#ifdef CONFIG_FUNCTION_GRAPH_TRACER
+#define __exception_irq_entry	__irq_entry
+#else
 #define __exception_irq_entry	__exception
+#endif
 
 #endif	/* __ASM_EXCEPTION_H */
diff --git a/arch/arm64/include/asm/traps.h b/arch/arm64/include/asm/traps.h
index 232e4ba..0cc2f29 100644
--- a/arch/arm64/include/asm/traps.h
+++ b/arch/arm64/include/asm/traps.h
@@ -34,13 +34,32 @@ struct undef_hook {
 void register_undef_hook(struct undef_hook *hook);
 void unregister_undef_hook(struct undef_hook *hook);
 
+#ifdef CONFIG_FUNCTION_GRAPH_TRACER
+static inline int __in_irqentry_text(unsigned long ptr)
+{
+	extern char __irqentry_text_start[];
+	extern char __irqentry_text_end[];
+
+	return ptr >= (unsigned long)&__irqentry_text_start &&
+	       ptr < (unsigned long)&__irqentry_text_end;
+}
+#else
+static inline int __in_irqentry_text(unsigned long ptr)
+{
+	return 0;
+}
+#endif
+
 static inline int in_exception_text(unsigned long ptr)
 {
 	extern char __exception_text_start[];
 	extern char __exception_text_end[];
+	int in;
+
+	in = ptr >= (unsigned long)&__exception_text_start &&
+	     ptr < (unsigned long)&__exception_text_end;
 
-	return ptr >= (unsigned long)&__exception_text_start &&
-	       ptr < (unsigned long)&__exception_text_end;
+	return in ? : __in_irqentry_text(ptr);
 }
 
 #endif
-- 
1.9.1



From marc.zyngier at arm.com  Wed Aug 12 07:20:07 2015
From: marc.zyngier at arm.com (Marc Zyngier)
Date: Wed, 12 Aug 2015 15:20:07 +0100
Subject: [PATCH 5/6] irqchip: GICv3: Don't deactivate interrupts forwarded
 to a guest
In-Reply-To: <55C9C860.4020107@linaro.org>
References: <1436447951-22357-1-git-send-email-marc.zyngier@arm.com>
 <1436447951-22357-6-git-send-email-marc.zyngier@arm.com>
 <55C9C860.4020107@linaro.org>
Message-ID: <55CB5617.1030901@arm.com>

On 11/08/15 11:03, Eric Auger wrote:
> On 07/09/2015 03:19 PM, Marc Zyngier wrote:
>> Commit 0a4377de3056 ("genirq: Introduce irq_set_vcpu_affinity() to
>> target an interrupt to a VCPU") added just what we needed at the
>> lowest level to allow an interrupt to be deactivated by a guest.
>>
>> When such a request reaches the GIC, it knows it doesn't need to
>> perform the deactivation anymore, and can safely leave the guest
>> do its magic. This of course requires additional support in both
>> VFIO and KVM.
>>
>> Signed-off-by: Marc Zyngier <marc.zyngier at arm.com>
>> ---
>>  drivers/irqchip/irq-gic-v3.c | 29 +++++++++++++++++++++++++++--
>>  1 file changed, 27 insertions(+), 2 deletions(-)
>>
>> diff --git a/drivers/irqchip/irq-gic-v3.c b/drivers/irqchip/irq-gic-v3.c
>> index e02592b..a1ca9e6 100644
>> --- a/drivers/irqchip/irq-gic-v3.c
>> +++ b/drivers/irqchip/irq-gic-v3.c
>> @@ -70,6 +70,11 @@ static inline int gic_irq_in_rdist(struct irq_data *d)
>>  	return gic_irq(d) < 32;
>>  }
>>  
>> +static inline bool forwarded_irq(struct irq_data *d)
>> +{
>> +	return d->handler_data != NULL;
>> +}
>> +
>>  static inline void __iomem *gic_dist_base(struct irq_data *d)
>>  {
>>  	if (gic_irq_in_rdist(d))	/* SGI+PPI -> SGI_base for this CPU */
>> @@ -231,6 +236,12 @@ static void gic_poke_irq(struct irq_data *d, u32 offset)
>>  static void gic_mask_irq(struct irq_data *d)
>>  {
>>  	gic_poke_irq(d, GICD_ICENABLER);
>> +	/*
>> +	 * When masking a forwarded interrupt, make sure it is
>> +	 * deactivated as well.
> To me it is not straightforward to understand why a forwarded IRQ would
> need to be DIR'ed when masked. This is needed because of the disable_irq
> optimisation, I would add a related comment.
> 

The lazy disable_irq is just an optimization.

The real reason is that if we mask an interrupt on the host, it is
because we don't want the guest to process it at all. There is three cases:

1) The interrupt was inactive: no problem
2) The interrupt was active, but not presented to the guest yet: no
problem either. The interrupt will be taken again on unmask.
3) The interrupt was active and presented to the guest: we might get a
double deactivate, which shouldn't be a big deal (but mostly should not
occur at all).

Would something like this make sense?

On a related note, I wonder if we need to mark the interrupt pending if
it is configured as edge. Otherwise, we could loose an interrupt in case
2 (mask, deactivate, unmask, oh look nothing triggers). Thoughts?

Thanks,

	M.
-- 
Jazz is not dead. It just smells funny...


From djkurtz at chromium.org  Wed Aug 12 07:20:57 2015
From: djkurtz at chromium.org (Daniel Kurtz)
Date: Wed, 12 Aug 2015 22:20:57 +0800
Subject: [PATCH] regmap: Add function check before called format_val
In-Reply-To: <1437458845.30329.51.camel@mtksdaap41>
References: <1437396110-5192-1-git-send-email-henryc.chen@mediatek.com>
 <20150720150254.GC11162@sirena.org.uk> <1437458845.30329.51.camel@mtksdaap41>
Message-ID: <CAGS+omDa+FhKD2u_VwBG3cWvN+ZiHneqFVz=mtdYuPsiQu4JEQ@mail.gmail.com>

Hi Henry & Mark,

On Tue, Jul 21, 2015 at 2:07 PM, Henry Chen <HenryC.Chen at mediatek.com> wrote:
> On Mon, 2015-07-20 at 16:02 +0100, Mark Brown wrote:
>> On Mon, Jul 20, 2015 at 08:41:50PM +0800, Henry Chen wrote:
>> > The regmap_format will not be initialize since regmap_bus is not assgined
>> > on regmap_init(). It should has a function check before using
>> > format_val() to avoid null function called on regmap_bulk_read().
>>
>> > -                   map->format.format_val(val + (i * val_bytes), ival, 0);
>> > +                   if (map->format.format_val)
>> > +                           map->format.format_val(val + (i * val_bytes), ival, 0);
>> > +                   else
>> > +                           memcpy(val + (i * val_bytes), &ival, val_bytes);
>>
>> Your changelog doesn't explan why we are in this code path in the first
>> place without a format_val() and why a memcpy() is an appropriate
>> replacement.  It should, it's not clear to me that this is a good fix
>> but I don't feel I fully understand the problem.
>
> Sorry for being unclear for issue, the call flow as following,
>
> First, in drivers/mfd/mtk_pmic_wrap.c which registered regmap without
> rebmap_bus.
> devm_regmap_init(wrp->dev, NULL, wrp, &pwrap_regmap_config);
>
> It call to regmap_init() and go to "skip_format_initialization" because
> regmap_bus didn't assign by driver.
>
> if (!bus) {
>         map->reg_read  = config->reg_read;
>         map->reg_write = config->reg_write;
>
>         map->defer_caching = false;
>         goto skip_format_initialization;"
>
> Then in driver rtc-mt6397.c, it used regmap_bulk_read() to get the time
> of PMIC, and hit the null function of format_val(), because the
> regmap_bus was null.
>
> It skipped the initialization of format_val() because bus == null, but
> called the format_val() at regmap_bulk_read() if bus == null.
>
> Maybe it was not the good fix for this, but should be a problem need to
> be reported, or should I need to give the regmap_bus on mtk_pmic_wrap.c?

I ran into this bug when testing Matthias' v4.2-next/for-next branch
on mt8173.  It now crashes on boot.

Since I didn't see it elsewhere in this discussion, I'll point out
that the "regression" here was introduced by commit [0], which added
the call to map->format.format_val from regmap_bulk_read() when
map->bus == NULL.

[0] commit 15b8d2c41fe5839582029f65c5f7004db451cc2b
  Author: Arun Chandran <achandran at mvista.com>
  regmap: Fix regmap_bulk_read in BE mode

Perhaps the easiest work around to unbreak v4.2 is, as Henry mentions,
for mtk_pmic_wrap to define its own regmap_bus, with .read() &
.write() handlers.  This way they will inherit the default built-in
format_val() from the regmap core.

Making mtk_pmic-wrap into a regmap_bus makes a bit of sense
architecturally, too, since it is essentially just a bus for accessing
the registers of an off-chip PMIC.  The CPU sees a platform bus, but
the registers of the remote PMIC are accessed over a dedicated SPI
bus.

WDYT?

Henry, can you try to implement this?

Thanks,
-Dan


From sebastian.hesselbarth at gmail.com  Wed Aug 12 07:21:16 2015
From: sebastian.hesselbarth at gmail.com (Sebastian Hesselbarth)
Date: Wed, 12 Aug 2015 16:21:16 +0200
Subject: [PATCH v3 1/5] pwm: add the Berlin pwm controller driver
In-Reply-To: <1439387497-6863-2-git-send-email-antoine.tenart@free-electrons.com>
References: <1439387497-6863-1-git-send-email-antoine.tenart@free-electrons.com>
 <1439387497-6863-2-git-send-email-antoine.tenart@free-electrons.com>
Message-ID: <55CB565C.8050906@gmail.com>

On 08/12/2015 03:51 PM, Antoine Tenart wrote:
> Add a PWM controller driver for the Marvell Berlin SoCs. This PWM
> controller has 4 channels.
>
> Signed-off-by: Antoine Tenart <antoine.tenart at free-electrons.com>

Antoine,

nice rework, but...

[...]
> diff --git a/drivers/pwm/pwm-berlin.c b/drivers/pwm/pwm-berlin.c
> new file mode 100644
> index 000000000000..f89e25ea5c6d
> --- /dev/null
> +++ b/drivers/pwm/pwm-berlin.c
> @@ -0,0 +1,227 @@
[...]
> +#define BERLIN_PWM_ENABLE		BIT(0)
> +#define BERLIN_PWM_DISABLE		0x0

I'd drop BERLIN_PWM_DISABLE and use reg & ~BERLIN_PWM_ENABLE below.
Even if there are no more writable bits in that register, IMHO it
is good practice to affect as little bits as possible.

[...]
> +/* prescaler table: {1, 4, 8, 16, 64, 256, 1024, 4096} */
> +static const u32 prescaler_diff_table[] = {
> +	1, 4, 2, 2, 4, 4, 4, 4,
> +};
> +
> +static int berlin_pwm_config(struct pwm_chip *chip, struct pwm_device *pwm,
> +			     int duty_ns, int period_ns)
> +{
> +	struct berlin_pwm_chip *berlin_chip = to_berlin_pwm_chip(chip);
> +	int ret, prescale = 0;
> +	u32 val, duty, period;
> +	u64 cycles;
> +
> +	cycles = clk_get_rate(berlin_chip->clk);
> +	cycles *= period_ns;
> +	do_div(cycles, NSEC_PER_SEC);
> +
> +	while (cycles > BERLIN_PWM_MAX_TCNT)
> +		do_div(cycles, prescaler_diff_table[++prescale]);
> +
> +	if (cycles > BERLIN_PWM_MAX_TCNT)
> +		return -EINVAL;

Does my idea actually work? Did you test it with some different
pwm frequencies?

> +	period = cycles;
> +	cycles *= duty_ns;
> +	do_div(cycles, period_ns);
> +	duty = cycles;
> +
> +	ret = clk_prepare_enable(berlin_chip->clk);
> +	if (ret)
> +		return ret;

Hmm. I understand that this may be required as the pwm framework
calls .pwm_config before .pwm_enable, but...

> +
> +	spin_lock(&berlin_chip->lock);
> +
> +	val = berlin_pwm_readl(berlin_chip, pwm->hwpwm, BERLIN_PWM_CONTROL);
> +	val &= ~BERLIN_PWM_PRESCALE_MASK;
> +	val |= prescale;
> +	berlin_pwm_writel(val, berlin_chip, pwm->hwpwm, BERLIN_PWM_CONTROL);
> +
> +	berlin_pwm_writel(duty, berlin_chip, pwm->hwpwm, BERLIN_PWM_DUTY);
> +	berlin_pwm_writel(period, berlin_chip, pwm->hwpwm, BERLIN_PWM_TCNT);
> +
> +	spin_unlock(&berlin_chip->lock);
> +
> +	clk_disable_unprepare(berlin_chip->clk);

Are you sure that register contents are retained after disabling the
clock? I understand that cfg_clk is the _ip_ input clock and pwm gets
derived from it.

Actually, since cfg_clk seems to be an important, internal SoC clock
I'd say to clk_prepare_enable() in _probe() before reading any
registers and clk_disable_unprepare() on _remove() (see below).

Internal low-frequency clocks don't consume that much power that it
is worth the pain ;)

> +	return 0;
> +}
> +
> +static int berlin_pwm_set_polarity(struct pwm_chip *chip,
> +				   struct pwm_device *pwm,
> +				   enum pwm_polarity polarity)
> +{
> +	struct berlin_pwm_chip *berlin_chip = to_berlin_pwm_chip(chip);
> +	int ret;
> +	u32 val;
> +
> +	ret = clk_prepare_enable(berlin_chip->clk);
> +	if (ret)
> +		return ret;

These would become unnecessary then.

> +	spin_lock(&berlin_chip->lock);
> +
> +	val = berlin_pwm_readl(berlin_chip, pwm->hwpwm, BERLIN_PWM_CONTROL);
> +
> +	if (polarity == PWM_POLARITY_NORMAL)
> +		val &= ~BERLIN_PWM_INVERT_POLARITY;
> +	else
> +		val |= BERLIN_PWM_INVERT_POLARITY;
> +
> +	berlin_pwm_writel(val, berlin_chip, pwm->hwpwm, BERLIN_PWM_CONTROL);
> +
> +	spin_unlock(&berlin_chip->lock);
> +
> +	clk_disable_unprepare(berlin_chip->clk);

ditto.

> +	return 0;
> +}
> +
> +static int berlin_pwm_enable(struct pwm_chip *chip, struct pwm_device *pwm)
> +{
> +	struct berlin_pwm_chip *berlin_chip = to_berlin_pwm_chip(chip);
> +	int ret;
> +
> +	ret = clk_prepare_enable(berlin_chip->clk);
> +	if (ret)
> +		return ret;

ditto.

> +	spin_lock(&berlin_chip->lock);
> +	berlin_pwm_writel(BERLIN_PWM_ENABLE, berlin_chip, pwm->hwpwm, BERLIN_PWM_EN);
> +	spin_unlock(&berlin_chip->lock);
> +
> +	return 0;
> +}
> +
> +static void berlin_pwm_disable(struct pwm_chip *chip, struct pwm_device *pwm)
> +{
> +	struct berlin_pwm_chip *berlin_chip = to_berlin_pwm_chip(chip);
> +
> +	spin_lock(&berlin_chip->lock);
> +	berlin_pwm_writel(BERLIN_PWM_DISABLE, berlin_chip, pwm->hwpwm, BERLIN_PWM_EN);
> +	spin_unlock(&berlin_chip->lock);
> +
> +	clk_disable_unprepare(berlin_chip->clk);

ditto.

> +}
> +
> +static const struct pwm_ops berlin_pwm_ops = {
> +	.config = berlin_pwm_config,
> +	.set_polarity = berlin_pwm_set_polarity,
> +	.enable = berlin_pwm_enable,
> +	.disable = berlin_pwm_disable,
> +	.owner = THIS_MODULE,
> +};
> +
> +static const struct of_device_id berlin_pwm_match[] = {
> +	{ .compatible = "marvell,berlin-pwm" },
> +	{ },
> +};
> +MODULE_DEVICE_TABLE(of, berlin_pwm_match);
> +
> +static int berlin_pwm_probe(struct platform_device *pdev)
> +{
> +	struct berlin_pwm_chip *pwm;
> +	struct resource *res;
> +	int ret;
> +
> +	pwm = devm_kzalloc(&pdev->dev, sizeof(*pwm), GFP_KERNEL);
> +	if (!pwm)
> +		return -ENOMEM;
> +
> +	res = platform_get_resource(pdev, IORESOURCE_MEM, 0);
> +	pwm->base = devm_ioremap_resource(&pdev->dev, res);
> +	if (IS_ERR(pwm->base))
> +		return PTR_ERR(pwm->base);
> +
> +	pwm->clk = devm_clk_get(&pdev->dev, NULL);
> +	if (IS_ERR(pwm->clk))
> +		return PTR_ERR(pwm->clk);
> +
> +	pwm->chip.dev = &pdev->dev;
> +	pwm->chip.ops = &berlin_pwm_ops;
> +	pwm->chip.base = -1;
> +	pwm->chip.npwm = 4;
> +	pwm->chip.can_sleep = true;
> +	pwm->chip.of_xlate = of_pwm_xlate_with_flags;
> +	pwm->chip.of_pwm_n_cells = 3;
> +
> +	spin_lock_init(&pwm->lock);

add clk_prepare_enable() before adding the pwmchip...

> +	ret = pwmchip_add(&pwm->chip);
> +	if (ret < 0) {
> +		dev_err(&pdev->dev, "Failed to add PWM chip: %d\n", ret);
> +		return ret;
> +	}
> +
> +	platform_set_drvdata(pdev, pwm);
> +
> +	return 0;
> +}
> +
> +static int berlin_pwm_remove(struct platform_device *pdev)
> +{
> +	struct berlin_pwm_chip *pwm = platform_get_drvdata(pdev);
> +
> +	return pwmchip_remove(&pwm->chip);

... and clk_disable_unprepare after removing it.

Besides the comments, for Berlin you get my

Acked-by: Sebastian Hesselbarth <sebastian.hesselbarth at gmail.com>

Thanks!

> +}
> +
> +static struct platform_driver berlin_pwm_driver = {
> +	.probe	= berlin_pwm_probe,
> +	.remove	= berlin_pwm_remove,
> +	.driver	= {
> +		.name	= "berlin-pwm",
> +		.of_match_table = berlin_pwm_match,
> +	},
> +};
> +module_platform_driver(berlin_pwm_driver);
> +
> +MODULE_AUTHOR("Antoine Tenart <antoine.tenart at free-electrons.com>");
> +MODULE_DESCRIPTION("Marvell Berlin PWM driver");
> +MODULE_LICENSE("GPL v2");
>


From marc.zyngier at arm.com  Wed Aug 12 07:21:40 2015
From: marc.zyngier at arm.com (Marc Zyngier)
Date: Wed, 12 Aug 2015 15:21:40 +0100
Subject: [PATCH 0/6] irqchip: GICv2/v3: Add support for irq_vcpu_affinity
In-Reply-To: <55C9C939.2020408@linaro.org>
References: <1436447951-22357-1-git-send-email-marc.zyngier@arm.com>
 <55C9C939.2020408@linaro.org>
Message-ID: <55CB5674.2080209@arm.com>

On 11/08/15 11:06, Eric Auger wrote:
> Hi Marc,
> 
> The series works fine with KVM platform device passthrough use case
> (Calxeda Midway, GICv2, SPI assignment with VFIO). My integration branch
> can be found at
> https://git.linaro.org/people/eric.auger/linux.git/shortlog/refs/heads/v4.2-rc6-irq-forward-v3
> if useful.
> 
> Tested-by: Eric Auger <eric.auger at linaro.org>

Many thanks for trying it (and for the review). I'll post an updated
version soon.

Thanks,

	M.
-- 
Jazz is not dead. It just smells funny...


From mike.looijmans at topic.nl  Wed Aug 12 07:22:12 2015
From: mike.looijmans at topic.nl (Mike Looijmans)
Date: Wed, 12 Aug 2015 16:22:12 +0200
Subject: [PATCH] pinctrl-zynq.c: Fix typos in smc0_nand_grp and smc0_nor_grp
Message-ID: <1439389332-9373-1-git-send-email-mike.looijmans@topic.nl>

Group names should be smc0_nand_grp and smc0_nor_grp, otherwise you'll
get errors like this if you try to pinmux them via the devicetree:
zynq-pinctrl 700.pinctrl: invalid group "smc0_nand_grp" for function "smc0_nand"

Probably a typo while creating these tables.

Signed-off-by: Mike Looijmans <mike.looijmans at topic.nl>
Acked-by: S?ren Brinkmann <soren.brinkmann at xilinx.com>
---
 drivers/pinctrl/pinctrl-zynq.c | 4 ++--
 1 file changed, 2 insertions(+), 2 deletions(-)

diff --git a/drivers/pinctrl/pinctrl-zynq.c b/drivers/pinctrl/pinctrl-zynq.c
index 7ce23b6..5aafea8 100644
--- a/drivers/pinctrl/pinctrl-zynq.c
+++ b/drivers/pinctrl/pinctrl-zynq.c
@@ -706,10 +706,10 @@ static const char * const sdio1_wp_groups[] = {"gpio0_0_grp",
 		"gpio0_39_grp", "gpio0_41_grp", "gpio0_43_grp",
 		"gpio0_45_grp", "gpio0_47_grp", "gpio0_49_grp",
 		"gpio0_51_grp", "gpio0_53_grp", "sdio1_emio_wp_grp"};
-static const char * const smc0_nor_groups[] = {"smc0_nor"};
+static const char * const smc0_nor_groups[] = {"smc0_nor_grp"};
 static const char * const smc0_nor_cs1_groups[] = {"smc0_nor_cs1_grp"};
 static const char * const smc0_nor_addr25_groups[] = {"smc0_nor_addr25_grp"};
-static const char * const smc0_nand_groups[] = {"smc0_nand"};
+static const char * const smc0_nand_groups[] = {"smc0_nand_grp"};
 static const char * const can0_groups[] = {"can0_0_grp", "can0_1_grp",
 		"can0_2_grp", "can0_3_grp", "can0_4_grp", "can0_5_grp",
 		"can0_6_grp", "can0_7_grp", "can0_8_grp", "can0_9_grp",
-- 
1.9.1



From eric.auger at linaro.org  Wed Aug 12 07:28:59 2015
From: eric.auger at linaro.org (Eric Auger)
Date: Wed, 12 Aug 2015 16:28:59 +0200
Subject: [PATCH 3/6] irqchip: GICv3: Skip LPI deactivation
In-Reply-To: <55CB4B82.9060601@arm.com>
References: <1436447951-22357-1-git-send-email-marc.zyngier@arm.com>
 <1436447951-22357-4-git-send-email-marc.zyngier@arm.com>
 <55C9C39A.3060208@linaro.org> <55CB4B82.9060601@arm.com>
Message-ID: <55CB582B.50007@linaro.org>

On 08/12/2015 03:34 PM, Marc Zyngier wrote:
> On 11/08/15 10:42, Eric Auger wrote:
>> On 07/09/2015 03:19 PM, Marc Zyngier wrote:
>>> Contrary to other GICv3 interrupts, LPIs do not have an active state
>>> by virtue of being edge-triggered only (they only have a pending state).
>>>
>>> Given this, there is no point trying to deactivate them, and we can
>>> skip the ICC_DIR_EL1 entierely.
>>>
>>> Signed-off-by: Marc Zyngier <marc.zyngier at arm.com>
>>> ---
>>>  drivers/irqchip/irq-gic-v3.c | 8 ++++++--
>>>  1 file changed, 6 insertions(+), 2 deletions(-)
>>>
>>> diff --git a/drivers/irqchip/irq-gic-v3.c b/drivers/irqchip/irq-gic-v3.c
>>> index 49768fc..e02592b 100644
>>> --- a/drivers/irqchip/irq-gic-v3.c
>>> +++ b/drivers/irqchip/irq-gic-v3.c
>>> @@ -295,10 +295,14 @@ static int gic_irq_get_irqchip_state(struct irq_data *d,
>>>  
>>>  static void gic_eoi_irq(struct irq_data *d)
>>>  {
>>> -	if (static_key_true(&supports_deactivate))
>>> +	if (static_key_true(&supports_deactivate)) {
>>> +		/* No need to deactivate an LPI */
>>> +		if (gic_irq(d) >= 8192)
>> In case of EOIMode == 0, we do not call EOI. I can't understand whether
>> it is an issue.
> 
> What do you mean? We definitely perform an EOI in both EOImodes...
> 
>> In 4.8.3 Properties of LPI, in 2d note it is written:
>>
>> "SW must issue a write to EOI to clear the active priorities register,
>> hence the CPU interface still requires an active state for LPIs, even
>> through this is not necessary within the redistributor"
>>
>> Eric
>>> +			return;
>>>  		gic_write_dir(gic_irq(d));
>>> -	else
>>> +	} else {
>>>  		gic_write_eoir(gic_irq(d));
> 
> ... right here.
> 
> Of am I missing something completely obvious?
yes sorry please forget this. I think I meant EOImode == 1 instead and
anyway the EOI is done in gic_handle_irq.

Apologies

Eric
> 
> Thanks,
> 
> 	M.
> 



From will.deacon at arm.com  Wed Aug 12 07:29:45 2015
From: will.deacon at arm.com (Will Deacon)
Date: Wed, 12 Aug 2015 15:29:45 +0100
Subject: [PATCH v8 4/7] arm64: kprobes instruction simulation support
In-Reply-To: <1439254364-15362-5-git-send-email-dave.long@linaro.org>
References: <1439254364-15362-1-git-send-email-dave.long@linaro.org>
 <1439254364-15362-5-git-send-email-dave.long@linaro.org>
Message-ID: <20150812142945.GF23540@arm.com>

Hi David,

On Tue, Aug 11, 2015 at 01:52:41AM +0100, David Long wrote:
> From: Sandeepa Prabhu <sandeepa.s.prabhu at gmail.com>
> 
> Kprobes needs simulation of instructions that cannot be stepped
> from different memory location, e.g.: those instructions
> that uses PC-relative addressing. In simulation, the behaviour
> of the instruction is implemented using a copy of pt_regs.
> 
> Following instruction catagories are simulated:
>  - All branching instructions(conditional, register, and immediate)
>  - Literal access instructions(load-literal, adr/adrp)
> 
> Conditional execution is limited to branching instructions in
> ARM v8. If conditions at PSTATE do not match the condition fields
> of opcode, the instruction is effectively NOP. Kprobes considers
> this case as 'miss'.
> 
> Thanks to Will Cohen for assorted suggested changes.
> 
> Signed-off-by: Sandeepa Prabhu <sandeepa.s.prabhu at gmail.com>
> Signed-off-by: William Cohen <wcohen at redhat.com>
> Signed-off-by: David A. Long <dave.long at linaro.org>

[...]

> diff --git a/arch/arm64/kernel/probes-condn-check.c b/arch/arm64/kernel/probes-condn-check.c
> new file mode 100644
> index 0000000..e68aa0c
> --- /dev/null
> +++ b/arch/arm64/kernel/probes-condn-check.c
> @@ -0,0 +1,122 @@
> +/*
> + * arch/arm64/kernel/probes-condn-check.c
> + *
> + * Copyright (C) 2013 Linaro Limited
> + *
> + * Copied from: arch/arm/kernel/kprobes-common.c
> + *
> + * 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.
> + *
> + * Description:
> + *
> + *  AArch64 and AArch32 shares same conditional(CNZV) flags encoding.
> + *  This file implements conditional check helpers compatible with
> + *  both AArch64 and AArch32 modes. Uprobes on v8 can handle both 32-bit
> + *  & 64-bit user-space instructions, so we abstract the common functions
> + *  in this file. While AArch64 and AArch32 specific instruction handling
> + *  are implemented in separate files, this file contains common bits.
> + */
> +#include <linux/kernel.h>
> +#include <linux/module.h>
> +#include <asm/probes.h>
> +
> +static unsigned long __kprobes __check_eq(unsigned long pstate)
> +{
> +       return pstate & PSR_Z_BIT;
> +}
> +
> +static unsigned long __kprobes __check_ne(unsigned long pstate)
> +{
> +       return (~pstate) & PSR_Z_BIT;
> +}
> +
> +static unsigned long __kprobes __check_cs(unsigned long pstate)
> +{
> +       return pstate & PSR_C_BIT;
> +}
> +
> +static unsigned long __kprobes __check_cc(unsigned long pstate)
> +{
> +       return (~pstate) & PSR_C_BIT;
> +}
> +
> +static unsigned long __kprobes __check_mi(unsigned long pstate)
> +{
> +       return pstate & PSR_N_BIT;
> +}
> +
> +static unsigned long __kprobes __check_pl(unsigned long pstate)
> +{
> +       return (~pstate) & PSR_N_BIT;
> +}
> +
> +static unsigned long __kprobes __check_vs(unsigned long pstate)
> +{
> +       return pstate & PSR_V_BIT;
> +}
> +
> +static unsigned long __kprobes __check_vc(unsigned long pstate)
> +{
> +       return (~pstate) & PSR_V_BIT;
> +}
> +
> +static unsigned long __kprobes __check_hi(unsigned long pstate)
> +{
> +       pstate &= ~(pstate >> 1);       /* PSR_C_BIT &= ~PSR_Z_BIT */
> +       return pstate & PSR_C_BIT;
> +}
> +
> +static unsigned long __kprobes __check_ls(unsigned long pstate)
> +{
> +       pstate &= ~(pstate >> 1);       /* PSR_C_BIT &= ~PSR_Z_BIT */
> +       return (~pstate) & PSR_C_BIT;
> +}
> +
> +static unsigned long __kprobes __check_ge(unsigned long pstate)
> +{
> +       pstate ^= (pstate << 3);        /* PSR_N_BIT ^= PSR_V_BIT */
> +       return (~pstate) & PSR_N_BIT;
> +}
> +
> +static unsigned long __kprobes __check_lt(unsigned long pstate)
> +{
> +       pstate ^= (pstate << 3);        /* PSR_N_BIT ^= PSR_V_BIT */
> +       return pstate & PSR_N_BIT;
> +}
> +
> +static unsigned long __kprobes __check_gt(unsigned long pstate)
> +{
> +       /*PSR_N_BIT ^= PSR_V_BIT */
> +       unsigned long temp = pstate ^ (pstate << 3);
> +
> +       temp |= (pstate << 1);  /*PSR_N_BIT |= PSR_Z_BIT */
> +       return (~temp) & PSR_N_BIT;
> +}
> +
> +static unsigned long __kprobes __check_le(unsigned long pstate)
> +{
> +       /*PSR_N_BIT ^= PSR_V_BIT */
> +       unsigned long temp = pstate ^ (pstate << 3);
> +
> +       temp |= (pstate << 1);  /*PSR_N_BIT |= PSR_Z_BIT */
> +       return temp & PSR_N_BIT;
> +}
> +
> +static unsigned long __kprobes __check_al(unsigned long pstate)
> +{
> +       return true;
> +}
> +
> +kprobes_pstate_check_t * const kprobe_condition_checks[16] = {
> +       &__check_eq, &__check_ne, &__check_cs, &__check_cc,
> +       &__check_mi, &__check_pl, &__check_vs, &__check_vc,
> +       &__check_hi, &__check_ls, &__check_ge, &__check_lt,
> +       &__check_gt, &__check_le, &__check_al, &__check_al
> +};

I *much* prefer this to our current inclusion / compilation of opcode.[ch]
from arch/arm/. Do you think you could put this somewhere like insn.h and
move armv8_deprecated.c over to using it?

Will


From jogo at openwrt.org  Wed Aug 12 07:45:25 2015
From: jogo at openwrt.org (Jonas Gorski)
Date: Wed, 12 Aug 2015 16:45:25 +0200
Subject: [PATCH] spi: Mediatek: fix endian warnings
In-Reply-To: <1439289789-29026-1-git-send-email-leilk.liu@mediatek.com>
References: <1439289789-29026-1-git-send-email-leilk.liu@mediatek.com>
Message-ID: <CAOiHx=mrDhxkMd5WVTpayyyxXHUDRTELubErynN3qd-v5qpCfw@mail.gmail.com>

Hi,

On Tue, Aug 11, 2015 at 12:43 PM, Leilk Liu <leilk.liu at mediatek.com> wrote:
> This patch fixes endian warnings detected by sparse:
> - sparse: incorrect type in argument 1 (different base types)
>           expected unsigned int [unsigned] val
>           got restricted __le32 [usertype] <noident>
> - sparse: incorrect type in argument 1 (different base types)
>           expected unsigned int [unsigned] val
>           got restricted __le32 [usertype] <noident>

This doesn't "fix" the warning, it only hides the warning and leaves
the actual issue unfixed.

>
> Signed-off-by: Leilk Liu <leilk.liu at mediatek.com>
> ---
>  drivers/spi/spi-mt65xx.c | 6 ++++--
>  1 file changed, 4 insertions(+), 2 deletions(-)
>
> diff --git a/drivers/spi/spi-mt65xx.c b/drivers/spi/spi-mt65xx.c
> index 4676b01..ae645fa 100644
> --- a/drivers/spi/spi-mt65xx.c
> +++ b/drivers/spi/spi-mt65xx.c
> @@ -359,9 +359,11 @@ static void mtk_spi_setup_dma_addr(struct spi_master *master,
>         struct mtk_spi *mdata = spi_master_get_devdata(master);
>
>         if (mdata->tx_sgl)
> -               writel(cpu_to_le32(xfer->tx_dma), mdata->base + SPI_TX_SRC_REG);
> +               writel((__force u32)cpu_to_le32(xfer->tx_dma),
> +                      mdata->base + SPI_TX_SRC_REG);
>         if (mdata->rx_sgl)
> -               writel(cpu_to_le32(xfer->rx_dma), mdata->base + SPI_RX_DST_REG);
> +               writel((__force u32)cpu_to_le32(xfer->rx_dma),
> +                      mdata->base + SPI_RX_DST_REG);

The issue here is that writel already does a cpu_to_le32 conversion,
so the extra cpu_to_le32 calls are actually bogus and need to be
removed. Else it will do a double conversion on big endian systems,
resulting in the data being written in big endian.


Jonas


From will.deacon at arm.com  Wed Aug 12 07:47:38 2015
From: will.deacon at arm.com (Will Deacon)
Date: Wed, 12 Aug 2015 15:47:38 +0100
Subject: [PATCH v8 5/7] arm64: Add trampoline code for kretprobes
In-Reply-To: <1439254364-15362-6-git-send-email-dave.long@linaro.org>
References: <1439254364-15362-1-git-send-email-dave.long@linaro.org>
 <1439254364-15362-6-git-send-email-dave.long@linaro.org>
Message-ID: <20150812144738.GG23540@arm.com>

Hi Will,

On Tue, Aug 11, 2015 at 01:52:42AM +0100, David Long wrote:
> From: William Cohen <wcohen at redhat.com>
> 
> The trampoline code is used by kretprobes to capture a return from a probed
> function.  This is done by saving the registers, calling the handler, and
> restoring the registers.  The code then returns to the original saved caller
> return address.  It is necessary to do this directly instead of using a
> software breakpoint because the code used in processing that breakpoint
> could itself be kprobe'd and cause a problematic reentry into the debug
> exception handler.
> 
> Signed-off-by: William Cohen <wcohen at redhat.com>
> Signed-off-by: David A. Long <dave.long at linaro.org>

[...]

> diff --git a/arch/arm64/kernel/kprobes_trampoline.S b/arch/arm64/kernel/kprobes_trampoline.S
> new file mode 100644
> index 0000000..dd0172b
> --- /dev/null
> +++ b/arch/arm64/kernel/kprobes_trampoline.S
> @@ -0,0 +1,61 @@
> +/*
> + * trampoline entry and return code for kretprobes.
> + */
> +
> +#include <linux/linkage.h>
> +#include <generated/asm-offsets.h>
> +
> +	.text
> +
> +ENTRY(kretprobe_trampoline)
> +
> +	sub sp, sp, #S_FRAME_SIZE
> +
> +	stp x0, x1, [sp, #S_X0]
> +	stp x2, x3, [sp, #S_X2]
> +	stp x4, x5, [sp, #S_X4]
> +	stp x6, x7, [sp, #S_X6]
> +	stp x8, x9, [sp, #S_X8]
> +	stp x10, x11, [sp, #S_X10]
> +	stp x12, x13, [sp, #S_X12]
> +	stp x14, x15, [sp, #S_X14]
> +	stp x16, x17, [sp, #S_X16]
> +	stp x18, x19, [sp, #S_X18]
> +	stp x20, x21, [sp, #S_X20]
> +	stp x22, x23, [sp, #S_X22]
> +	stp x24, x25, [sp, #S_X24]
> +	stp x26, x27, [sp, #S_X26]
> +	stp x28, x29, [sp, #S_X28]
> +	str x30, [sp, #S_LR]
> +	mrs x0, nzcv
> +	str x0, [sp, #S_PSTATE]

I'm slightly wary of this, as it means user_mode(regs) will return true
for the pt_regs passed into the handler. Do we need to force the mode?
What about things like the I bit?

Similarly, why don't you save the stack pointer?

> +
> +	mov x0, sp
> +	bl trampoline_probe_handler
> +	/* Replace trampoline address in lr with actual
> +	   orig_ret_addr return address. */
> +	str x0, [sp, #S_LR]

Why can't the trampoline_probe_handler update the pt_regs directly?

Will


From sricharan at codeaurora.org  Wed Aug 12 07:47:44 2015
From: sricharan at codeaurora.org (Sricharan R)
Date: Wed, 12 Aug 2015 20:17:44 +0530
Subject: [PATCH 0/5] iommu/msm: Add DT adaptation and generic bindings support
Message-ID: <1439390869-6347-1-git-send-email-sricharan@codeaurora.org>

The msm_iommu.c driver currently works based on platform data. A single master
device can be connected to more than one iommu and multiple contexts in each
of the iommu. This association between master and iommus was represented
from platform data using parent/child devices. The master drivers were
responsible for attaching all of the iommus/context to a domain. Now the
platform data support is removed and DT support is added. The master/iommus
are added through generic iommu bindings.

This is essentially rework of the patch posted earlier by
Rob Clark <robdclark at gmail.com>. This series folds the changes
in to the existing driver with the addition of generic bindings.

        http://www.spinics.net/lists/linux-arm-msm/msg10077.html

This series is based on the IOMMU probe deferral series from
Laurent Pinchart <laurent.pinchart at ideasonboard.com>

        https://lkml.org/lkml/2015/5/14/786

Tested this series on ifc6410 board.

Sricharan R (5):
  iommu/msm: Add DT adaptation
  iommu/msm: Move the contents from msm_iommu_dev.c to msm_iommu.c
  iommu/msm: Add support for generic master bindings
  iommu/msm: Set cacheability attributes without tex remap
  iommu/msm: Remove driver BROKEN

 .../devicetree/bindings/iommu/msm,iommu-v0.txt     |  59 +++
 drivers/iommu/Kconfig                              |   1 -
 drivers/iommu/Makefile                             |   2 +-
 drivers/iommu/msm_iommu.c                          | 508 ++++++++++++++-------
 drivers/iommu/msm_iommu.h                          |  73 ++-
 drivers/iommu/msm_iommu_dev.c                      | 392 ----------------
 drivers/iommu/msm_iommu_hw-8xxx.h                  |  10 +-
 7 files changed, 432 insertions(+), 613 deletions(-)
 create mode 100644 Documentation/devicetree/bindings/iommu/msm,iommu-v0.txt
 delete mode 100644 drivers/iommu/msm_iommu_dev.c

-- 
QUALCOMM INDIA, on behalf of Qualcomm Innovation Center, Inc. is a member of Code Aurora Forum, hosted by The Linux Foundation



From sricharan at codeaurora.org  Wed Aug 12 07:47:45 2015
From: sricharan at codeaurora.org (Sricharan R)
Date: Wed, 12 Aug 2015 20:17:45 +0530
Subject: [PATCH 1/5] iommu/msm: Add DT adaptation
In-Reply-To: <1439390869-6347-1-git-send-email-sricharan@codeaurora.org>
References: <1439390869-6347-1-git-send-email-sricharan@codeaurora.org>
Message-ID: <1439390869-6347-2-git-send-email-sricharan@codeaurora.org>

The driver currently works based on platform data. Remove this
and add support for DT. A single master can have multiple ports
connected to more than one iommu.

	  	      master
        	        |
	                |
	                |
	   ------------------------
           |  			  |
	IOMMU0			IOMMU1
           |			  |
      ctx0   ctx1	     ctx0   ctx1

This association of master and iommus/contexts were previously
represented by platform data parent/child device details. The client
drivers were responsible for programming all of the iommus/contexts
for the device. Now while adapting to generic DT bindings we maintain the
list of iommus, contexts that each master domain is connected to and
program all of them on attach/detach.

Signed-off-by: Sricharan R <sricharan at codeaurora.org>
---
 .../devicetree/bindings/iommu/msm,iommu-v0.txt     |  59 ++++
 drivers/iommu/msm_iommu.c                          | 252 ++++++++--------
 drivers/iommu/msm_iommu.h                          |  73 ++---
 drivers/iommu/msm_iommu_dev.c                      | 320 +++++----------------
 4 files changed, 289 insertions(+), 415 deletions(-)
 create mode 100644 Documentation/devicetree/bindings/iommu/msm,iommu-v0.txt

diff --git a/Documentation/devicetree/bindings/iommu/msm,iommu-v0.txt b/Documentation/devicetree/bindings/iommu/msm,iommu-v0.txt
new file mode 100644
index 0000000..21bfbfc
--- /dev/null
+++ b/Documentation/devicetree/bindings/iommu/msm,iommu-v0.txt
@@ -0,0 +1,59 @@
+* QCOM IOMMU
+
+The QCOM IOMMU is an implementation compatible with the ARM VMSA short
+descriptor page tables. It provides address translation for bus masters outside
+of the CPU, each connected to the IOMMU through a port called micro-TLB.
+
+Required Properties:
+
+  - compatible: Must contain "qcom,iommu-v0".
+  - reg: Base address and size of the IOMMU registers.
+  - interrupts: Specifiers for the MMU fault interrupts. For instances that
+    support secure mode two interrupts must be specified, for non-secure and
+    secure mode, in that order. For instances that don't support secure mode a
+    single interrupt must be specified.
+  - #iommu-cells: This is the total number of stream ids that a master would
+		  use during transactions which will be specified as a list
+		  as a part of iommus property below.
+  - ncb: The total number of context banks in the IOMMU.
+  - clocks	: List of clocks to be used during SMMU register access. See
+		  Documentation/devicetree/bindings/clock/clock-bindings.txt
+		  for information about the format. For each clock specified
+		  here, there must be a corresponding entry in clock-names
+		  (see below).
+
+  - clock-names	: List of clock names corresponding to the clocks specified in
+		  the "clocks" property (above). See
+		  Documentation/devicetree/bindings/clock/clock-bindings.txt
+		  for more info.
+
+Each bus master connected to an IOMMU must reference the IOMMU in its device
+node with the following property:
+
+  - iommus: A reference to the IOMMU in multiple cells. The first cell is a
+	    phandle to the IOMMU and the second cell is the list of the
+	    stream ids used by the device.
+
+Example: mdp iommu and its bus master
+
+                mdp_port0: qcom,iommu at 7500000 {
+			compatible = "qcom,iommu-v0";
+			#iommu-cells = <2>;
+			clock-names =
+			    "smmu_pclk",
+			    "iommu_clk";
+			clocks =
+			    <&mmcc SMMU_AHB_CLK>,
+			    <&mmcc MDP_AXI_CLK>;
+			reg = <0x07500000 0x100000>;
+			interrupts =
+			    <GIC_SPI 63 0>,
+			    <GIC_SPI 64 0>;
+			ncb = <2>;
+		};
+
+		mdp: qcom,mdp at 5100000 {
+			compatible = "qcom,mdp";
+			...
+			iommus = <&mdp_port0 0 2>;
+		};
diff --git a/drivers/iommu/msm_iommu.c b/drivers/iommu/msm_iommu.c
index 15a2063..6024d71 100644
--- a/drivers/iommu/msm_iommu.c
+++ b/drivers/iommu/msm_iommu.c
@@ -48,6 +48,7 @@ __asm__ __volatile__ (							\
 static int msm_iommu_tex_class[4];
 
 DEFINE_SPINLOCK(msm_iommu_lock);
+static LIST_HEAD(qcom_iommu_devices);
 
 struct msm_priv {
 	unsigned long *pgtable;
@@ -60,35 +61,37 @@ static struct msm_priv *to_msm_priv(struct iommu_domain *dom)
 	return container_of(dom, struct msm_priv, domain);
 }
 
-static int __enable_clocks(struct msm_iommu_drvdata *drvdata)
+static int __enable_clocks(struct msm_iommu_dev *iommu)
 {
 	int ret;
 
-	ret = clk_enable(drvdata->pclk);
+	ret = clk_prepare_enable(iommu->pclk);
 	if (ret)
 		goto fail;
 
-	if (drvdata->clk) {
-		ret = clk_enable(drvdata->clk);
+	if (iommu->clk) {
+		ret = clk_prepare_enable(iommu->clk);
 		if (ret)
-			clk_disable(drvdata->pclk);
+			clk_disable_unprepare(iommu->pclk);
 	}
 fail:
 	return ret;
 }
 
-static void __disable_clocks(struct msm_iommu_drvdata *drvdata)
+static void __disable_clocks(struct msm_iommu_dev *iommu)
 {
-	clk_disable(drvdata->clk);
-	clk_disable(drvdata->pclk);
+	if (iommu->clk)
+		clk_disable_unprepare(iommu->clk);
+	clk_disable_unprepare(iommu->pclk);
 }
 
 static int __flush_iotlb(struct iommu_domain *domain)
 {
 	struct msm_priv *priv = to_msm_priv(domain);
-	struct msm_iommu_drvdata *iommu_drvdata;
-	struct msm_iommu_ctx_drvdata *ctx_drvdata;
+	struct msm_iommu_dev *iommu = NULL;
+	struct msm_iommu_ctx_dev *master;
 	int ret = 0;
+
 #ifndef CONFIG_IOMMU_PGTABLES_L2
 	unsigned long *fl_table = priv->pgtable;
 	int i;
@@ -105,24 +108,67 @@ static int __flush_iotlb(struct iommu_domain *domain)
 	}
 #endif
 
-	list_for_each_entry(ctx_drvdata, &priv->list_attached, attached_elm) {
-		if (!ctx_drvdata->pdev || !ctx_drvdata->pdev->dev.parent)
-			BUG();
-
-		iommu_drvdata = dev_get_drvdata(ctx_drvdata->pdev->dev.parent);
-		BUG_ON(!iommu_drvdata);
-
-		ret = __enable_clocks(iommu_drvdata);
+	list_for_each_entry(iommu, &priv->list_attached, dom_node) {
+		ret = __enable_clocks(iommu);
 		if (ret)
 			goto fail;
 
-		SET_CTX_TLBIALL(iommu_drvdata->base, ctx_drvdata->num, 0);
-		__disable_clocks(iommu_drvdata);
+		list_for_each_entry(master, &iommu->ctx_list, list)
+			SET_CTX_TLBIALL(iommu->base, master->num, 0);
+
+		__disable_clocks(iommu);
 	}
 fail:
 	return ret;
 }
 
+static int msm_iommu_alloc_ctx(unsigned long *map, int start, int end)
+{
+	int idx;
+
+	do {
+		idx = find_next_zero_bit(map, end, start);
+		if (idx == end)
+			return -ENOSPC;
+	} while (test_and_set_bit(idx, map));
+
+	return idx;
+}
+
+static void msm_iommu_free_ctx(unsigned long *map, int idx)
+{
+	clear_bit(idx, map);
+}
+
+static void config_mids(struct msm_iommu_dev *iommu,
+			struct msm_iommu_ctx_dev *master)
+{
+	int mid, ctx, i;
+
+	for (i = 0; i < master->num_mids; i++) {
+		mid = master->mids[i];
+		ctx = master->num;
+
+		SET_M2VCBR_N(iommu->base, mid, 0);
+		SET_CBACR_N(iommu->base, ctx, 0);
+
+		/* Set VMID = 0 */
+		SET_VMID(iommu->base, mid, 0);
+
+		/* Set the context number for that MID to this context */
+		SET_CBNDX(iommu->base, mid, ctx);
+
+		/* Set MID associated with this context bank to 0*/
+		SET_CBVMID(iommu->base, ctx, 0);
+
+		/* Set the ASID for TLB tagging for this context */
+		SET_CONTEXTIDR_ASID(iommu->base, ctx, ctx);
+
+		/* Set security bit override to be Non-secure */
+		SET_NSCFG(iommu->base, mid, 3);
+	}
+}
+
 static void __reset_context(void __iomem *base, int ctx)
 {
 	SET_BPRCOSH(base, ctx, 0);
@@ -272,94 +318,76 @@ static void msm_iommu_domain_free(struct iommu_domain *domain)
 
 static int msm_iommu_attach_dev(struct iommu_domain *domain, struct device *dev)
 {
-	struct msm_priv *priv;
-	struct msm_iommu_ctx_dev *ctx_dev;
-	struct msm_iommu_drvdata *iommu_drvdata;
-	struct msm_iommu_ctx_drvdata *ctx_drvdata;
-	struct msm_iommu_ctx_drvdata *tmp_drvdata;
 	int ret = 0;
 	unsigned long flags;
+	struct msm_iommu_dev *iommu;
+	struct msm_priv *priv = to_msm_priv(domain);
+	struct msm_iommu_ctx_dev *master;
 
 	spin_lock_irqsave(&msm_iommu_lock, flags);
-
-	priv = to_msm_priv(domain);
-
-	if (!dev) {
-		ret = -EINVAL;
-		goto fail;
-	}
-
-	iommu_drvdata = dev_get_drvdata(dev->parent);
-	ctx_drvdata = dev_get_drvdata(dev);
-	ctx_dev = dev->platform_data;
-
-	if (!iommu_drvdata || !ctx_drvdata || !ctx_dev) {
-		ret = -EINVAL;
-		goto fail;
-	}
-
-	if (!list_empty(&ctx_drvdata->attached_elm)) {
-		ret = -EBUSY;
-		goto fail;
-	}
-
-	list_for_each_entry(tmp_drvdata, &priv->list_attached, attached_elm)
-		if (tmp_drvdata == ctx_drvdata) {
-			ret = -EBUSY;
-			goto fail;
+	list_for_each_entry(iommu, &qcom_iommu_devices, dev_node) {
+		master = list_first_entry(&iommu->ctx_list,
+					  struct msm_iommu_ctx_dev,
+					  list);
+		if (master->of_node == dev->of_node) {
+			ret = __enable_clocks(iommu);
+			if (ret)
+				goto fail;
+
+			list_for_each_entry(master, &iommu->ctx_list, list) {
+				if (master->num) {
+					dev_err(dev, "domain already attached");
+					ret = -EEXIST;
+					goto fail;
+				}
+				master->num =
+					msm_iommu_alloc_ctx(iommu->context_map,
+							    0, iommu->ncb);
+					if (IS_ERR_VALUE(master->num)) {
+						ret = -ENODEV;
+						goto fail;
+					}
+				config_mids(iommu, master);
+				__program_context(iommu->base, master->num,
+						  __pa(priv->pgtable));
+			}
+			__disable_clocks(iommu);
+			list_add(&iommu->dom_node, &priv->list_attached);
 		}
+	}
 
-	ret = __enable_clocks(iommu_drvdata);
-	if (ret)
-		goto fail;
-
-	__program_context(iommu_drvdata->base, ctx_dev->num,
-			  __pa(priv->pgtable));
-
-	__disable_clocks(iommu_drvdata);
-	list_add(&(ctx_drvdata->attached_elm), &priv->list_attached);
 	ret = __flush_iotlb(domain);
-
 fail:
 	spin_unlock_irqrestore(&msm_iommu_lock, flags);
+
 	return ret;
 }
 
 static void msm_iommu_detach_dev(struct iommu_domain *domain,
 				 struct device *dev)
 {
-	struct msm_priv *priv;
-	struct msm_iommu_ctx_dev *ctx_dev;
-	struct msm_iommu_drvdata *iommu_drvdata;
-	struct msm_iommu_ctx_drvdata *ctx_drvdata;
+	struct msm_priv *priv = to_msm_priv(domain);
 	unsigned long flags;
+	struct msm_iommu_dev *iommu;
+	struct msm_iommu_ctx_dev *master;
 	int ret;
 
 	spin_lock_irqsave(&msm_iommu_lock, flags);
-	priv = to_msm_priv(domain);
-
-	if (!dev)
-		goto fail;
-
-	iommu_drvdata = dev_get_drvdata(dev->parent);
-	ctx_drvdata = dev_get_drvdata(dev);
-	ctx_dev = dev->platform_data;
-
-	if (!iommu_drvdata || !ctx_drvdata || !ctx_dev)
-		goto fail;
-
 	ret = __flush_iotlb(domain);
 	if (ret)
 		goto fail;
 
-	ret = __enable_clocks(iommu_drvdata);
-	if (ret)
-		goto fail;
-
-	__reset_context(iommu_drvdata->base, ctx_dev->num);
-	__disable_clocks(iommu_drvdata);
-	list_del_init(&ctx_drvdata->attached_elm);
+	list_for_each_entry(iommu, &priv->list_attached, dom_node) {
+		ret = __enable_clocks(iommu);
+		if (ret)
+			goto fail;
 
+		list_for_each_entry(master, &iommu->ctx_list, list) {
+			msm_iommu_free_ctx(iommu->context_map, master->num);
+			__reset_context(iommu->base, master->num);
+		}
+		__disable_clocks(iommu);
+	}
 fail:
 	spin_unlock_irqrestore(&msm_iommu_lock, flags);
 }
@@ -555,47 +583,46 @@ static phys_addr_t msm_iommu_iova_to_phys(struct iommu_domain *domain,
 					  dma_addr_t va)
 {
 	struct msm_priv *priv;
-	struct msm_iommu_drvdata *iommu_drvdata;
-	struct msm_iommu_ctx_drvdata *ctx_drvdata;
+	struct msm_iommu_dev *iommu;
+	struct msm_iommu_ctx_dev *master;
 	unsigned int par;
 	unsigned long flags;
-	void __iomem *base;
 	phys_addr_t ret = 0;
-	int ctx;
 
 	spin_lock_irqsave(&msm_iommu_lock, flags);
 
 	priv = to_msm_priv(domain);
-	if (list_empty(&priv->list_attached))
-		goto fail;
+	iommu = list_first_entry(&priv->list_attached,
+				 struct msm_iommu_dev, dom_node);
 
-	ctx_drvdata = list_entry(priv->list_attached.next,
-				 struct msm_iommu_ctx_drvdata, attached_elm);
-	iommu_drvdata = dev_get_drvdata(ctx_drvdata->pdev->dev.parent);
+	if (list_empty(&iommu->ctx_list))
+		goto fail;
 
-	base = iommu_drvdata->base;
-	ctx = ctx_drvdata->num;
+	master = list_first_entry(&iommu->ctx_list,
+				  struct msm_iommu_ctx_dev, list);
+	if (!master)
+		goto fail;
 
-	ret = __enable_clocks(iommu_drvdata);
+	ret = __enable_clocks(iommu);
 	if (ret)
 		goto fail;
 
 	/* Invalidate context TLB */
-	SET_CTX_TLBIALL(base, ctx, 0);
-	SET_V2PPR(base, ctx, va & V2Pxx_VA);
+	SET_CTX_TLBIALL(iommu->base, master->num, 0);
+	SET_V2PPR(iommu->base, master->num, va & V2Pxx_VA);
 
-	par = GET_PAR(base, ctx);
+	par = GET_PAR(iommu->base, master->num);
 
 	/* We are dealing with a supersection */
-	if (GET_NOFAULT_SS(base, ctx))
+	if (GET_NOFAULT_SS(iommu->base, master->num))
 		ret = (par & 0xFF000000) | (va & 0x00FFFFFF);
 	else	/* Upper 20 bits from PAR, lower 12 from VA */
 		ret = (par & 0xFFFFF000) | (va & 0x00000FFF);
 
-	if (GET_FAULT(base, ctx))
+	if (GET_FAULT(iommu->base, master->num))
 		ret = 0;
 
-	__disable_clocks(iommu_drvdata);
+	__disable_clocks(iommu);
 fail:
 	spin_unlock_irqrestore(&msm_iommu_lock, flags);
 	return ret;
@@ -635,37 +662,34 @@ static void print_ctx_regs(void __iomem *base, int ctx)
 
 irqreturn_t msm_iommu_fault_handler(int irq, void *dev_id)
 {
-	struct msm_iommu_drvdata *drvdata = dev_id;
-	void __iomem *base;
+	struct msm_iommu_dev *iommu = dev_id;
 	unsigned int fsr;
 	int i, ret;
 
 	spin_lock(&msm_iommu_lock);
 
-	if (!drvdata) {
+	if (!iommu) {
 		pr_err("Invalid device ID in context interrupt handler\n");
 		goto fail;
 	}
 
-	base = drvdata->base;
-
 	pr_err("Unexpected IOMMU page fault!\n");
-	pr_err("base = %08x\n", (unsigned int) base);
+	pr_err("base = %08x\n", (unsigned int)iommu->base);
 
-	ret = __enable_clocks(drvdata);
+	ret = __enable_clocks(iommu);
 	if (ret)
 		goto fail;
 
-	for (i = 0; i < drvdata->ncb; i++) {
-		fsr = GET_FSR(base, i);
+	for (i = 0; i < iommu->ncb; i++) {
+		fsr = GET_FSR(iommu->base, i);
 		if (fsr) {
 			pr_err("Fault occurred in context %d.\n", i);
 			pr_err("Interesting registers:\n");
-			print_ctx_regs(base, i);
-			SET_FSR(base, i, 0x4000000F);
+			print_ctx_regs(iommu->base, i);
+			SET_FSR(iommu->base, i, 0x4000000F);
 		}
 	}
-	__disable_clocks(drvdata);
+	__disable_clocks(iommu);
 fail:
 	spin_unlock(&msm_iommu_lock);
 	return 0;
diff --git a/drivers/iommu/msm_iommu.h b/drivers/iommu/msm_iommu.h
index 5c7c955..4ca25d5 100644
--- a/drivers/iommu/msm_iommu.h
+++ b/drivers/iommu/msm_iommu.h
@@ -42,74 +42,53 @@
  */
 #define MAX_NUM_MIDS	32
 
+/* Maximum number of context banks that can be present in IOMMU */
+#define IOMMU_MAX_CBS	128
+
 /**
  * struct msm_iommu_dev - a single IOMMU hardware instance
- * name		Human-readable name given to this IOMMU HW instance
  * ncb		Number of context banks present on this IOMMU HW instance
+ * dev:		IOMMU device
+ * irq:		Interrupt number
+ * clk:		The bus clock for this IOMMU hardware instance
+ * pclk:	The clock for the IOMMU bus interconnect
+ * dev_node:	list head in qcom_iommu_device_list
+ * dom_node:	list head for domain
+ * ctx_list:	list of 'struct msm_iommu_ctx_dev'
+ * context_map: Bitmap to track allocated context banks
  */
 struct msm_iommu_dev {
-	const char *name;
+	void __iomem *base;
 	int ncb;
+	struct device *dev;
+	int irq;
+	struct clk *clk;
+	struct clk *pclk;
+	struct list_head dev_node;
+	struct list_head dom_node;
+	struct list_head ctx_list;
+	DECLARE_BITMAP(context_map, IOMMU_MAX_CBS);
 };
 
 /**
  * struct msm_iommu_ctx_dev - an IOMMU context bank instance
- * name		Human-readable name given to this context bank
+ * of_node	node ptr of client device
  * num		Index of this context bank within the hardware
  * mids		List of Machine IDs that are to be mapped into this context
  *		bank, terminated by -1. The MID is a set of signals on the
  *		AXI bus that identifies the function associated with a specific
  *		memory request. (See ARM spec).
+ * num_mids	Total number of mids
+ * node		list head in ctx_list
  */
 struct msm_iommu_ctx_dev {
-	const char *name;
+	struct device_node *of_node;
 	int num;
 	int mids[MAX_NUM_MIDS];
+	int num_mids;
+	struct list_head list;
 };
 
-
-/**
- * struct msm_iommu_drvdata - A single IOMMU hardware instance
- * @base:	IOMMU config port base address (VA)
- * @ncb		The number of contexts on this IOMMU
- * @irq:	Interrupt number
- * @clk:	The bus clock for this IOMMU hardware instance
- * @pclk:	The clock for the IOMMU bus interconnect
- *
- * A msm_iommu_drvdata holds the global driver data about a single piece
- * of an IOMMU hardware instance.
- */
-struct msm_iommu_drvdata {
-	void __iomem *base;
-	int irq;
-	int ncb;
-	struct clk *clk;
-	struct clk *pclk;
-};
-
-/**
- * struct msm_iommu_ctx_drvdata - an IOMMU context bank instance
- * @num:		Hardware context number of this context
- * @pdev:		Platform device associated wit this HW instance
- * @attached_elm:	List element for domains to track which devices are
- *			attached to them
- *
- * A msm_iommu_ctx_drvdata holds the driver data for a single context bank
- * within each IOMMU hardware instance
- */
-struct msm_iommu_ctx_drvdata {
-	int num;
-	struct platform_device *pdev;
-	struct list_head attached_elm;
-};
-
-/*
- * Look up an IOMMU context device by its context name. NULL if none found.
- * Useful for testing and drivers that do not yet fully have IOMMU stuff in
- * their platform devices.
- */
-struct device *msm_iommu_get_ctx(const char *ctx_name);
-
 /*
  * Interrupt handler for the IOMMU context fault interrupt. Hooking the
  * interrupt is not supported in the API yet, but this will print an error
diff --git a/drivers/iommu/msm_iommu_dev.c b/drivers/iommu/msm_iommu_dev.c
index b6d01f9..68bb453 100644
--- a/drivers/iommu/msm_iommu_dev.c
+++ b/drivers/iommu/msm_iommu_dev.c
@@ -30,60 +30,6 @@
 #include "msm_iommu_hw-8xxx.h"
 #include "msm_iommu.h"
 
-struct iommu_ctx_iter_data {
-	/* input */
-	const char *name;
-
-	/* output */
-	struct device *dev;
-};
-
-static struct platform_device *msm_iommu_root_dev;
-
-static int each_iommu_ctx(struct device *dev, void *data)
-{
-	struct iommu_ctx_iter_data *res = data;
-	struct msm_iommu_ctx_dev *c = dev->platform_data;
-
-	if (!res || !c || !c->name || !res->name)
-		return -EINVAL;
-
-	if (!strcmp(res->name, c->name)) {
-		res->dev = dev;
-		return 1;
-	}
-	return 0;
-}
-
-static int each_iommu(struct device *dev, void *data)
-{
-	return device_for_each_child(dev, data, each_iommu_ctx);
-}
-
-struct device *msm_iommu_get_ctx(const char *ctx_name)
-{
-	struct iommu_ctx_iter_data r;
-	int found;
-
-	if (!msm_iommu_root_dev) {
-		pr_err("No root IOMMU device.\n");
-		goto fail;
-	}
-
-	r.name = ctx_name;
-	found = device_for_each_child(&msm_iommu_root_dev->dev, &r, each_iommu);
-
-	if (!found) {
-		pr_err("Could not find context <%s>\n", ctx_name);
-		goto fail;
-	}
-
-	return r.dev;
-fail:
-	return NULL;
-}
-EXPORT_SYMBOL(msm_iommu_get_ctx);
-
 static void msm_iommu_reset(void __iomem *base, int ncb)
 {
 	int ctx;
@@ -128,260 +74,126 @@ static void msm_iommu_reset(void __iomem *base, int ncb)
 static int msm_iommu_probe(struct platform_device *pdev)
 {
 	struct resource *r;
-	struct clk *iommu_clk;
-	struct clk *iommu_pclk;
-	struct msm_iommu_drvdata *drvdata;
-	struct msm_iommu_dev *iommu_dev = dev_get_platdata(&pdev->dev);
-	void __iomem *regs_base;
-	int ret, irq, par;
+	struct msm_iommu_dev *iommu;
+	int ret, par, val;
 
-	if (pdev->id == -1) {
-		msm_iommu_root_dev = pdev;
-		return 0;
+	iommu = devm_kzalloc(&pdev->dev, sizeof(*iommu), GFP_KERNEL);
+	if (!iommu) {
+		ret = -ENODEV;
+		goto fail;
 	}
 
-	drvdata = kzalloc(sizeof(*drvdata), GFP_KERNEL);
+	iommu->dev = &pdev->dev;
+	INIT_LIST_HEAD(&iommu->ctx_list);
 
-	if (!drvdata) {
-		ret = -ENOMEM;
+	iommu->pclk = devm_clk_get(iommu->dev, "smmu_pclk");
+	if (IS_ERR(iommu->pclk)) {
+		dev_err(iommu->dev, "could not get smmu_pclk\n");
+		ret = PTR_ERR(iommu->pclk);
 		goto fail;
 	}
 
-	if (!iommu_dev) {
-		ret = -ENODEV;
+	iommu->clk = devm_clk_get(iommu->dev, "iommu_clk");
+	if (IS_ERR(iommu->clk)) {
+		dev_err(iommu->dev, "could not get iommu_clk\n");
+		ret = PTR_ERR(iommu->clk);
+		iommu->pclk = NULL;
 		goto fail;
 	}
 
-	iommu_pclk = clk_get(NULL, "smmu_pclk");
-	if (IS_ERR(iommu_pclk)) {
+	r = platform_get_resource(pdev, IORESOURCE_MEM, 0);
+	iommu->base = devm_ioremap_resource(iommu->dev, r);
+	if (IS_ERR(iommu->base)) {
+		dev_err(iommu->dev, "could not get iommu base\n");
+		ret = PTR_ERR(iommu->base);
+		goto fail;
+	}
+
+	iommu->irq = platform_get_irq(pdev, 0);
+	if (iommu->irq < 0) {
+		dev_err(iommu->dev, "could not get iommu irq\n");
 		ret = -ENODEV;
 		goto fail;
 	}
 
-	ret = clk_prepare_enable(iommu_pclk);
+	ret = clk_prepare_enable(iommu->pclk);
 	if (ret)
-		goto fail_enable;
-
-	iommu_clk = clk_get(&pdev->dev, "iommu_clk");
-
-	if (!IS_ERR(iommu_clk))	{
-		if (clk_get_rate(iommu_clk) == 0)
-			clk_set_rate(iommu_clk, 1);
-
-		ret = clk_prepare_enable(iommu_clk);
-		if (ret) {
-			clk_put(iommu_clk);
-			goto fail_pclk;
-		}
-	} else
-		iommu_clk = NULL;
+		goto fail;
 
-	r = platform_get_resource_byname(pdev, IORESOURCE_MEM, "physbase");
-	regs_base = devm_ioremap_resource(&pdev->dev, r);
-	if (IS_ERR(regs_base)) {
-		ret = PTR_ERR(regs_base);
-		goto fail_clk;
+	ret = clk_prepare_enable(iommu->clk);
+	if (ret) {
+		clk_disable_unprepare(iommu->pclk);
+		goto fail;
 	}
 
-	irq = platform_get_irq_byname(pdev, "secure_irq");
-	if (irq < 0) {
-		ret = -ENODEV;
-		goto fail_clk;
+	ret = of_property_read_u32(iommu->dev->of_node, "ncb", &val);
+	if (ret) {
+		dev_err(iommu->dev, "could not get ncb\n");
+		goto fail;
 	}
+	iommu->ncb = val;
 
-	msm_iommu_reset(regs_base, iommu_dev->ncb);
+	msm_iommu_reset(iommu->base, iommu->ncb);
+	SET_M(iommu->base, 0, 1);
+	SET_PAR(iommu->base, 0, 0);
+	SET_V2PCFG(iommu->base, 0, 1);
+	SET_V2PPR(iommu->base, 0, 0);
+	par = GET_PAR(iommu->base, 0);
+	SET_V2PCFG(iommu->base, 0, 0);
+	SET_M(iommu->base, 0, 0);
 
-	SET_M(regs_base, 0, 1);
-	SET_PAR(regs_base, 0, 0);
-	SET_V2PCFG(regs_base, 0, 1);
-	SET_V2PPR(regs_base, 0, 0);
-	par = GET_PAR(regs_base, 0);
-	SET_V2PCFG(regs_base, 0, 0);
-	SET_M(regs_base, 0, 0);
+	clk_disable_unprepare(iommu->clk);
+	clk_disable_unprepare(iommu->pclk);
 
 	if (!par) {
-		pr_err("%s: Invalid PAR value detected\n", iommu_dev->name);
+		pr_err("Invalid PAR value detected\n");
 		ret = -ENODEV;
-		goto fail_clk;
+		goto fail;
 	}
 
-	ret = request_irq(irq, msm_iommu_fault_handler, 0,
-			"msm_iommu_secure_irpt_handler", drvdata);
+	ret = devm_request_threaded_irq(iommu->dev, iommu->irq, NULL,
+					msm_iommu_fault_handler,
+					IRQF_ONESHOT | IRQF_SHARED,
+					"msm_iommu_secure_irpt_handler",
+					iommu);
 	if (ret) {
-		pr_err("Request IRQ %d failed with ret=%d\n", irq, ret);
-		goto fail_clk;
-	}
-
-
-	drvdata->pclk = iommu_pclk;
-	drvdata->clk = iommu_clk;
-	drvdata->base = regs_base;
-	drvdata->irq = irq;
-	drvdata->ncb = iommu_dev->ncb;
-
-	pr_info("device %s mapped at %p, irq %d with %d ctx banks\n",
-		iommu_dev->name, regs_base, irq, iommu_dev->ncb);
-
-	platform_set_drvdata(pdev, drvdata);
-
-	clk_disable(iommu_clk);
-
-	clk_disable(iommu_pclk);
-
-	return 0;
-fail_clk:
-	if (iommu_clk) {
-		clk_disable(iommu_clk);
-		clk_put(iommu_clk);
-	}
-fail_pclk:
-	clk_disable_unprepare(iommu_pclk);
-fail_enable:
-	clk_put(iommu_pclk);
-fail:
-	kfree(drvdata);
-	return ret;
-}
-
-static int msm_iommu_remove(struct platform_device *pdev)
-{
-	struct msm_iommu_drvdata *drv = NULL;
-
-	drv = platform_get_drvdata(pdev);
-	if (drv) {
-		if (drv->clk) {
-			clk_unprepare(drv->clk);
-			clk_put(drv->clk);
-		}
-		clk_unprepare(drv->pclk);
-		clk_put(drv->pclk);
-		memset(drv, 0, sizeof(*drv));
-		kfree(drv);
-	}
-	return 0;
-}
-
-static int msm_iommu_ctx_probe(struct platform_device *pdev)
-{
-	struct msm_iommu_ctx_dev *c = dev_get_platdata(&pdev->dev);
-	struct msm_iommu_drvdata *drvdata;
-	struct msm_iommu_ctx_drvdata *ctx_drvdata;
-	int i, ret;
-
-	if (!c || !pdev->dev.parent)
-		return -EINVAL;
-
-	drvdata = dev_get_drvdata(pdev->dev.parent);
-	if (!drvdata)
-		return -ENODEV;
-
-	ctx_drvdata = kzalloc(sizeof(*ctx_drvdata), GFP_KERNEL);
-	if (!ctx_drvdata)
-		return -ENOMEM;
-
-	ctx_drvdata->num = c->num;
-	ctx_drvdata->pdev = pdev;
-
-	INIT_LIST_HEAD(&ctx_drvdata->attached_elm);
-	platform_set_drvdata(pdev, ctx_drvdata);
-
-	ret = clk_prepare_enable(drvdata->pclk);
-	if (ret)
+		pr_err("Request IRQ %d failed with ret=%d\n", iommu->irq, ret);
 		goto fail;
-
-	if (drvdata->clk) {
-		ret = clk_prepare_enable(drvdata->clk);
-		if (ret) {
-			clk_disable_unprepare(drvdata->pclk);
-			goto fail;
-		}
 	}
 
-	/* Program the M2V tables for this context */
-	for (i = 0; i < MAX_NUM_MIDS; i++) {
-		int mid = c->mids[i];
-		if (mid == -1)
-			break;
-
-		SET_M2VCBR_N(drvdata->base, mid, 0);
-		SET_CBACR_N(drvdata->base, c->num, 0);
-
-		/* Set VMID = 0 */
-		SET_VMID(drvdata->base, mid, 0);
-
-		/* Set the context number for that MID to this context */
-		SET_CBNDX(drvdata->base, mid, c->num);
-
-		/* Set MID associated with this context bank to 0*/
-		SET_CBVMID(drvdata->base, c->num, 0);
+	list_add(&iommu->dev_node, &qcom_iommu_devices);
 
-		/* Set the ASID for TLB tagging for this context */
-		SET_CONTEXTIDR_ASID(drvdata->base, c->num, c->num);
-
-		/* Set security bit override to be Non-secure */
-		SET_NSCFG(drvdata->base, mid, 3);
-	}
-
-	clk_disable(drvdata->clk);
-	clk_disable(drvdata->pclk);
-
-	dev_info(&pdev->dev, "context %s using bank %d\n", c->name, c->num);
-	return 0;
+	pr_info("device mapped at %p, irq %d with %d ctx banks\n",
+		iommu->base, iommu->irq, iommu->ncb);
 fail:
-	kfree(ctx_drvdata);
 	return ret;
 }
 
-static int msm_iommu_ctx_remove(struct platform_device *pdev)
-{
-	struct msm_iommu_ctx_drvdata *drv = NULL;
-	drv = platform_get_drvdata(pdev);
-	if (drv) {
-		memset(drv, 0, sizeof(struct msm_iommu_ctx_drvdata));
-		kfree(drv);
-	}
-	return 0;
-}
+static const struct of_device_id msm_iommu_dt_match[] = {
+	{ .compatible = "qcom,iommu-v0" },
+	{}
+};
 
 static struct platform_driver msm_iommu_driver = {
 	.driver = {
 		.name	= "msm_iommu",
+		.of_match_table = msm_iommu_dt_match,
 	},
 	.probe		= msm_iommu_probe,
-	.remove		= msm_iommu_remove,
-};
-
-static struct platform_driver msm_iommu_ctx_driver = {
-	.driver = {
-		.name	= "msm_iommu_ctx",
-	},
-	.probe		= msm_iommu_ctx_probe,
-	.remove		= msm_iommu_ctx_remove,
 };
 
 static int __init msm_iommu_driver_init(void)
 {
 	int ret;
 	ret = platform_driver_register(&msm_iommu_driver);
-	if (ret != 0) {
+	if (ret != 0)
 		pr_err("Failed to register IOMMU driver\n");
-		goto error;
-	}
-
-	ret = platform_driver_register(&msm_iommu_ctx_driver);
-	if (ret != 0) {
-		platform_driver_unregister(&msm_iommu_driver);
-		pr_err("Failed to register IOMMU context driver\n");
-		goto error;
-	}
 
-error:
 	return ret;
 }
 
 static void __exit msm_iommu_driver_exit(void)
 {
-	platform_driver_unregister(&msm_iommu_ctx_driver);
 	platform_driver_unregister(&msm_iommu_driver);
 }
 
-- 
QUALCOMM INDIA, on behalf of Qualcomm Innovation Center, Inc. is a member of Code Aurora Forum, hosted by The Linux Foundation



From sricharan at codeaurora.org  Wed Aug 12 07:47:46 2015
From: sricharan at codeaurora.org (Sricharan R)
Date: Wed, 12 Aug 2015 20:17:46 +0530
Subject: [PATCH 2/5] iommu/msm: Move the contents from msm_iommu_dev.c to
 msm_iommu.c
In-Reply-To: <1439390869-6347-1-git-send-email-sricharan@codeaurora.org>
References: <1439390869-6347-1-git-send-email-sricharan@codeaurora.org>
Message-ID: <1439390869-6347-3-git-send-email-sricharan@codeaurora.org>

There are only two functions left in msm_iommu_dev.c. Move it to
msm_iommu.c and delete the file.

Signed-off-by: Sricharan R <sricharan at codeaurora.org>
---
 drivers/iommu/Makefile        |   2 +-
 drivers/iommu/msm_iommu.c     | 163 +++++++++++++++++++++++++++++++++
 drivers/iommu/msm_iommu_dev.c | 204 ------------------------------------------
 3 files changed, 164 insertions(+), 205 deletions(-)
 delete mode 100644 drivers/iommu/msm_iommu_dev.c

diff --git a/drivers/iommu/Makefile b/drivers/iommu/Makefile
index c6dcc51..83ee0bf 100644
--- a/drivers/iommu/Makefile
+++ b/drivers/iommu/Makefile
@@ -5,7 +5,7 @@ obj-$(CONFIG_IOMMU_IO_PGTABLE) += io-pgtable.o
 obj-$(CONFIG_IOMMU_IO_PGTABLE_LPAE) += io-pgtable-arm.o
 obj-$(CONFIG_IOMMU_IOVA) += iova.o
 obj-$(CONFIG_OF_IOMMU)	+= of_iommu.o
-obj-$(CONFIG_MSM_IOMMU) += msm_iommu.o msm_iommu_dev.o
+obj-$(CONFIG_MSM_IOMMU) += msm_iommu.o
 obj-$(CONFIG_AMD_IOMMU) += amd_iommu.o amd_iommu_init.o
 obj-$(CONFIG_AMD_IOMMU_V2) += amd_iommu_v2.o
 obj-$(CONFIG_ARM_SMMU) += arm-smmu.o
diff --git a/drivers/iommu/msm_iommu.c b/drivers/iommu/msm_iommu.c
index 6024d71..1210152 100644
--- a/drivers/iommu/msm_iommu.c
+++ b/drivers/iommu/msm_iommu.c
@@ -27,6 +27,7 @@
 #include <linux/slab.h>
 #include <linux/iommu.h>
 #include <linux/clk.h>
+#include <linux/err.h>
 
 #include <asm/cacheflush.h>
 #include <asm/sizes.h>
@@ -85,6 +86,47 @@ static void __disable_clocks(struct msm_iommu_dev *iommu)
 	clk_disable_unprepare(iommu->pclk);
 }
 
+static void msm_iommu_reset(void __iomem *base, int ncb)
+{
+	int ctx;
+
+	SET_RPUE(base, 0);
+	SET_RPUEIE(base, 0);
+	SET_ESRRESTORE(base, 0);
+	SET_TBE(base, 0);
+	SET_CR(base, 0);
+	SET_SPDMBE(base, 0);
+	SET_TESTBUSCR(base, 0);
+	SET_TLBRSW(base, 0);
+	SET_GLOBAL_TLBIALL(base, 0);
+	SET_RPU_ACR(base, 0);
+	SET_TLBLKCRWE(base, 1);
+
+	for (ctx = 0; ctx < ncb; ctx++) {
+		SET_BPRCOSH(base, ctx, 0);
+		SET_BPRCISH(base, ctx, 0);
+		SET_BPRCNSH(base, ctx, 0);
+		SET_BPSHCFG(base, ctx, 0);
+		SET_BPMTCFG(base, ctx, 0);
+		SET_ACTLR(base, ctx, 0);
+		SET_SCTLR(base, ctx, 0);
+		SET_FSRRESTORE(base, ctx, 0);
+		SET_TTBR0(base, ctx, 0);
+		SET_TTBR1(base, ctx, 0);
+		SET_TTBCR(base, ctx, 0);
+		SET_BFBCR(base, ctx, 0);
+		SET_PAR(base, ctx, 0);
+		SET_FAR(base, ctx, 0);
+		SET_CTX_TLBIALL(base, ctx, 0);
+		SET_TLBFLPTER(base, ctx, 0);
+		SET_TLBSLPTER(base, ctx, 0);
+		SET_TLBLKCR(base, ctx, 0);
+		SET_PRRR(base, ctx, 0);
+		SET_NMRR(base, ctx, 0);
+		SET_CONTEXTIDR(base, ctx, 0);
+	}
+}
+
 static int __flush_iotlb(struct iommu_domain *domain)
 {
 	struct msm_priv *priv = to_msm_priv(domain);
@@ -708,6 +750,127 @@ static const struct iommu_ops msm_iommu_ops = {
 	.pgsize_bitmap = MSM_IOMMU_PGSIZES,
 };
 
+static int msm_iommu_probe(struct platform_device *pdev)
+{
+	struct resource *r;
+	struct msm_iommu_dev *iommu;
+	int ret, par, val;
+
+	iommu = devm_kzalloc(&pdev->dev, sizeof(*iommu), GFP_KERNEL);
+	if (!iommu) {
+		ret = -ENODEV;
+		goto fail;
+	}
+
+	iommu->dev = &pdev->dev;
+	INIT_LIST_HEAD(&iommu->ctx_list);
+
+	iommu->pclk = devm_clk_get(iommu->dev, "smmu_pclk");
+	if (IS_ERR(iommu->pclk)) {
+		dev_err(iommu->dev, "could not get smmu_pclk\n");
+		ret = PTR_ERR(iommu->pclk);
+		goto fail;
+	}
+
+	iommu->clk = devm_clk_get(iommu->dev, "iommu_clk");
+	if (IS_ERR(iommu->clk)) {
+		dev_err(iommu->dev, "could not get iommu_clk\n");
+		ret = PTR_ERR(iommu->clk);
+		iommu->pclk = NULL;
+		goto fail;
+	}
+
+	r = platform_get_resource(pdev, IORESOURCE_MEM, 0);
+	iommu->base = devm_ioremap_resource(iommu->dev, r);
+	if (IS_ERR(iommu->base)) {
+		dev_err(iommu->dev, "could not get iommu base\n");
+		ret = PTR_ERR(iommu->base);
+		goto fail;
+	}
+
+	iommu->irq = platform_get_irq(pdev, 0);
+	if (iommu->irq < 0) {
+		dev_err(iommu->dev, "could not get iommu irq\n");
+		ret = -ENODEV;
+		goto fail;
+	}
+
+	ret = of_property_read_u32(iommu->dev->of_node, "ncb", &val);
+	if (ret) {
+		dev_err(iommu->dev, "could not get ncb\n");
+		goto fail;
+	}
+	iommu->ncb = val;
+
+	__enable_clocks(iommu);
+
+	msm_iommu_reset(iommu->base, iommu->ncb);
+	SET_M(iommu->base, 0, 1);
+	SET_PAR(iommu->base, 0, 0);
+	SET_V2PCFG(iommu->base, 0, 1);
+	SET_V2PPR(iommu->base, 0, 0);
+	par = GET_PAR(iommu->base, 0);
+	SET_V2PCFG(iommu->base, 0, 0);
+	SET_M(iommu->base, 0, 0);
+
+	__disable_clocks(iommu);
+
+	if (!par) {
+		pr_err("Invalid PAR value detected\n");
+		ret = -ENODEV;
+		goto fail;
+	}
+
+	ret = devm_request_threaded_irq(iommu->dev, iommu->irq, NULL,
+					msm_iommu_fault_handler,
+					IRQF_ONESHOT | IRQF_SHARED,
+					"msm_iommu_secure_irpt_handler",
+					iommu);
+	if (ret) {
+		pr_err("Request IRQ %d failed with ret=%d\n", iommu->irq, ret);
+		goto fail;
+	}
+
+	list_add(&iommu->dev_node, &qcom_iommu_devices);
+
+	pr_info("device mapped at %p, irq %d with %d ctx banks\n",
+		iommu->base, iommu->irq, iommu->ncb);
+fail:
+	return ret;
+}
+
+static const struct of_device_id msm_iommu_dt_match[] = {
+	{ .compatible = "qcom,iommu-v0"},
+	{}
+};
+
+static struct platform_driver msm_iommu_driver = {
+	.driver = {
+		.name	= "msm_iommu",
+		.of_match_table = msm_iommu_dt_match,
+	},
+	.probe		= msm_iommu_probe,
+};
+
+static int __init msm_iommu_driver_init(void)
+{
+	int ret;
+
+	ret = platform_driver_register(&msm_iommu_driver);
+	if (ret != 0)
+		pr_err("Failed to register IOMMU driver\n");
+
+	return ret;
+}
+
+static void __exit msm_iommu_driver_exit(void)
+{
+	platform_driver_unregister(&msm_iommu_driver);
+}
+
+subsys_initcall(msm_iommu_driver_init);
+module_exit(msm_iommu_driver_exit);
+
 static int __init get_tex_class(int icp, int ocp, int mt, int nos)
 {
 	int i = 0;
diff --git a/drivers/iommu/msm_iommu_dev.c b/drivers/iommu/msm_iommu_dev.c
deleted file mode 100644
index 68bb453..0000000
--- a/drivers/iommu/msm_iommu_dev.c
+++ /dev/null
@@ -1,204 +0,0 @@
-/* Copyright (c) 2010-2011, Code Aurora Forum. All rights reserved.
- *
- * This program is free software; you can redistribute it and/or modify
- * it under the terms of the GNU General Public License version 2 and
- * only 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.
- *
- * You should have received a copy of the GNU General Public License
- * along with this program; if not, write to the Free Software
- * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA
- * 02110-1301, USA.
- */
-
-#define pr_fmt(fmt)	KBUILD_MODNAME ": " fmt
-
-#include <linux/kernel.h>
-#include <linux/module.h>
-#include <linux/platform_device.h>
-#include <linux/io.h>
-#include <linux/clk.h>
-#include <linux/iommu.h>
-#include <linux/interrupt.h>
-#include <linux/err.h>
-#include <linux/slab.h>
-
-#include "msm_iommu_hw-8xxx.h"
-#include "msm_iommu.h"
-
-static void msm_iommu_reset(void __iomem *base, int ncb)
-{
-	int ctx;
-
-	SET_RPUE(base, 0);
-	SET_RPUEIE(base, 0);
-	SET_ESRRESTORE(base, 0);
-	SET_TBE(base, 0);
-	SET_CR(base, 0);
-	SET_SPDMBE(base, 0);
-	SET_TESTBUSCR(base, 0);
-	SET_TLBRSW(base, 0);
-	SET_GLOBAL_TLBIALL(base, 0);
-	SET_RPU_ACR(base, 0);
-	SET_TLBLKCRWE(base, 1);
-
-	for (ctx = 0; ctx < ncb; ctx++) {
-		SET_BPRCOSH(base, ctx, 0);
-		SET_BPRCISH(base, ctx, 0);
-		SET_BPRCNSH(base, ctx, 0);
-		SET_BPSHCFG(base, ctx, 0);
-		SET_BPMTCFG(base, ctx, 0);
-		SET_ACTLR(base, ctx, 0);
-		SET_SCTLR(base, ctx, 0);
-		SET_FSRRESTORE(base, ctx, 0);
-		SET_TTBR0(base, ctx, 0);
-		SET_TTBR1(base, ctx, 0);
-		SET_TTBCR(base, ctx, 0);
-		SET_BFBCR(base, ctx, 0);
-		SET_PAR(base, ctx, 0);
-		SET_FAR(base, ctx, 0);
-		SET_CTX_TLBIALL(base, ctx, 0);
-		SET_TLBFLPTER(base, ctx, 0);
-		SET_TLBSLPTER(base, ctx, 0);
-		SET_TLBLKCR(base, ctx, 0);
-		SET_PRRR(base, ctx, 0);
-		SET_NMRR(base, ctx, 0);
-		SET_CONTEXTIDR(base, ctx, 0);
-	}
-}
-
-static int msm_iommu_probe(struct platform_device *pdev)
-{
-	struct resource *r;
-	struct msm_iommu_dev *iommu;
-	int ret, par, val;
-
-	iommu = devm_kzalloc(&pdev->dev, sizeof(*iommu), GFP_KERNEL);
-	if (!iommu) {
-		ret = -ENODEV;
-		goto fail;
-	}
-
-	iommu->dev = &pdev->dev;
-	INIT_LIST_HEAD(&iommu->ctx_list);
-
-	iommu->pclk = devm_clk_get(iommu->dev, "smmu_pclk");
-	if (IS_ERR(iommu->pclk)) {
-		dev_err(iommu->dev, "could not get smmu_pclk\n");
-		ret = PTR_ERR(iommu->pclk);
-		goto fail;
-	}
-
-	iommu->clk = devm_clk_get(iommu->dev, "iommu_clk");
-	if (IS_ERR(iommu->clk)) {
-		dev_err(iommu->dev, "could not get iommu_clk\n");
-		ret = PTR_ERR(iommu->clk);
-		iommu->pclk = NULL;
-		goto fail;
-	}
-
-	r = platform_get_resource(pdev, IORESOURCE_MEM, 0);
-	iommu->base = devm_ioremap_resource(iommu->dev, r);
-	if (IS_ERR(iommu->base)) {
-		dev_err(iommu->dev, "could not get iommu base\n");
-		ret = PTR_ERR(iommu->base);
-		goto fail;
-	}
-
-	iommu->irq = platform_get_irq(pdev, 0);
-	if (iommu->irq < 0) {
-		dev_err(iommu->dev, "could not get iommu irq\n");
-		ret = -ENODEV;
-		goto fail;
-	}
-
-	ret = clk_prepare_enable(iommu->pclk);
-	if (ret)
-		goto fail;
-
-	ret = clk_prepare_enable(iommu->clk);
-	if (ret) {
-		clk_disable_unprepare(iommu->pclk);
-		goto fail;
-	}
-
-	ret = of_property_read_u32(iommu->dev->of_node, "ncb", &val);
-	if (ret) {
-		dev_err(iommu->dev, "could not get ncb\n");
-		goto fail;
-	}
-	iommu->ncb = val;
-
-	msm_iommu_reset(iommu->base, iommu->ncb);
-	SET_M(iommu->base, 0, 1);
-	SET_PAR(iommu->base, 0, 0);
-	SET_V2PCFG(iommu->base, 0, 1);
-	SET_V2PPR(iommu->base, 0, 0);
-	par = GET_PAR(iommu->base, 0);
-	SET_V2PCFG(iommu->base, 0, 0);
-	SET_M(iommu->base, 0, 0);
-
-	clk_disable_unprepare(iommu->clk);
-	clk_disable_unprepare(iommu->pclk);
-
-	if (!par) {
-		pr_err("Invalid PAR value detected\n");
-		ret = -ENODEV;
-		goto fail;
-	}
-
-	ret = devm_request_threaded_irq(iommu->dev, iommu->irq, NULL,
-					msm_iommu_fault_handler,
-					IRQF_ONESHOT | IRQF_SHARED,
-					"msm_iommu_secure_irpt_handler",
-					iommu);
-	if (ret) {
-		pr_err("Request IRQ %d failed with ret=%d\n", iommu->irq, ret);
-		goto fail;
-	}
-
-	list_add(&iommu->dev_node, &qcom_iommu_devices);
-
-	pr_info("device mapped at %p, irq %d with %d ctx banks\n",
-		iommu->base, iommu->irq, iommu->ncb);
-fail:
-	return ret;
-}
-
-static const struct of_device_id msm_iommu_dt_match[] = {
-	{ .compatible = "qcom,iommu-v0" },
-	{}
-};
-
-static struct platform_driver msm_iommu_driver = {
-	.driver = {
-		.name	= "msm_iommu",
-		.of_match_table = msm_iommu_dt_match,
-	},
-	.probe		= msm_iommu_probe,
-};
-
-static int __init msm_iommu_driver_init(void)
-{
-	int ret;
-	ret = platform_driver_register(&msm_iommu_driver);
-	if (ret != 0)
-		pr_err("Failed to register IOMMU driver\n");
-
-	return ret;
-}
-
-static void __exit msm_iommu_driver_exit(void)
-{
-	platform_driver_unregister(&msm_iommu_driver);
-}
-
-subsys_initcall(msm_iommu_driver_init);
-module_exit(msm_iommu_driver_exit);
-
-MODULE_LICENSE("GPL v2");
-MODULE_AUTHOR("Stepan Moskovchenko <stepanm at codeaurora.org>");
-- 
QUALCOMM INDIA, on behalf of Qualcomm Innovation Center, Inc. is a member of Code Aurora Forum, hosted by The Linux Foundation



From sricharan at codeaurora.org  Wed Aug 12 07:47:47 2015
From: sricharan at codeaurora.org (Sricharan R)
Date: Wed, 12 Aug 2015 20:17:47 +0530
Subject: [PATCH 3/5] iommu/msm: Add support for generic master bindings
In-Reply-To: <1439390869-6347-1-git-send-email-sricharan@codeaurora.org>
References: <1439390869-6347-1-git-send-email-sricharan@codeaurora.org>
Message-ID: <1439390869-6347-4-git-send-email-sricharan@codeaurora.org>

This adds the xlate callback which gets invoked during
device registration from DT. The master devices gets added
through this. Also adding the iommu_of_setup callback here.

Signed-off-by: Sricharan R <sricharan at codeaurora.org>
---
 drivers/iommu/msm_iommu.c | 51 +++++++++++++++++++++++++++++++++++++++++++++--
 1 file changed, 49 insertions(+), 2 deletions(-)

diff --git a/drivers/iommu/msm_iommu.c b/drivers/iommu/msm_iommu.c
index 1210152..1d95d7c 100644
--- a/drivers/iommu/msm_iommu.c
+++ b/drivers/iommu/msm_iommu.c
@@ -28,6 +28,7 @@
 #include <linux/iommu.h>
 #include <linux/clk.h>
 #include <linux/err.h>
+#include <linux/of_iommu.h>
 
 #include <asm/cacheflush.h>
 #include <asm/sizes.h>
@@ -702,6 +703,44 @@ static void print_ctx_regs(void __iomem *base, int ctx)
 	       GET_PRRR(base, ctx), GET_NMRR(base, ctx));
 }
 
+static void insert_iommu_master(struct device *dev,
+				struct msm_iommu_dev *iommu,
+				struct of_phandle_args *spec)
+{
+	struct msm_iommu_ctx_dev *master;
+	int sid;
+
+	master = kzalloc(sizeof(*master), GFP_KERNEL);
+	master->of_node = dev->of_node;
+	list_add(&master->list, &iommu->ctx_list);
+
+	for (sid = 0; sid < spec->args_count; sid++)
+		master->mids[sid] = spec->args[sid];
+
+	master->num_mids = spec->args_count;
+}
+
+static int qcom_iommu_of_xlate(struct device *dev,
+			       struct of_phandle_args *spec)
+{
+	struct msm_iommu_dev *iommu;
+	unsigned long flags;
+
+	spin_lock_irqsave(&msm_iommu_lock, flags);
+	list_for_each_entry(iommu, &qcom_iommu_devices, dev_node) {
+		if (iommu->dev->of_node == spec->np)
+			break;
+	}
+
+	if (!iommu || (iommu->dev->of_node != spec->np))
+		return -ENODEV;
+
+	insert_iommu_master(dev, iommu, spec);
+	spin_unlock_irqrestore(&msm_iommu_lock, flags);
+
+	return 0;
+}
+
 irqreturn_t msm_iommu_fault_handler(int irq, void *dev_id)
 {
 	struct msm_iommu_dev *iommu = dev_id;
@@ -737,7 +776,7 @@ fail:
 	return 0;
 }
 
-static const struct iommu_ops msm_iommu_ops = {
+static struct iommu_ops msm_iommu_ops = {
 	.capable = msm_iommu_capable,
 	.domain_alloc = msm_iommu_domain_alloc,
 	.domain_free = msm_iommu_domain_free,
@@ -748,6 +787,7 @@ static const struct iommu_ops msm_iommu_ops = {
 	.map_sg = default_iommu_map_sg,
 	.iova_to_phys = msm_iommu_iova_to_phys,
 	.pgsize_bitmap = MSM_IOMMU_PGSIZES,
+	.of_xlate = qcom_iommu_of_xlate,
 };
 
 static int msm_iommu_probe(struct platform_device *pdev)
@@ -832,6 +872,7 @@ static int msm_iommu_probe(struct platform_device *pdev)
 	}
 
 	list_add(&iommu->dev_node, &qcom_iommu_devices);
+	of_iommu_set_ops(pdev->dev.of_node, &msm_iommu_ops);
 
 	pr_info("device mapped at %p, irq %d with %d ctx banks\n",
 		iommu->base, iommu->irq, iommu->ncb);
@@ -916,7 +957,13 @@ static int __init msm_iommu_init(void)
 	return 0;
 }
 
-subsys_initcall(msm_iommu_init);
+static int __init msm_iommu_of_setup(struct device_node *np)
+{
+	msm_iommu_init();
+	return 0;
+}
+
+IOMMU_OF_DECLARE(msm_iommu_of, "qcom,iommu-v0", msm_iommu_of_setup);
 
 MODULE_LICENSE("GPL v2");
 MODULE_AUTHOR("Stepan Moskovchenko <stepanm at codeaurora.org>");
-- 
QUALCOMM INDIA, on behalf of Qualcomm Innovation Center, Inc. is a member of Code Aurora Forum, hosted by The Linux Foundation



From sricharan at codeaurora.org  Wed Aug 12 07:47:48 2015
From: sricharan at codeaurora.org (Sricharan R)
Date: Wed, 12 Aug 2015 20:17:48 +0530
Subject: [PATCH 4/5] iommu/msm: Set cacheability attributes without tex remap
In-Reply-To: <1439390869-6347-1-git-send-email-sricharan@codeaurora.org>
References: <1439390869-6347-1-git-send-email-sricharan@codeaurora.org>
Message-ID: <1439390869-6347-5-git-send-email-sricharan@codeaurora.org>

The cacheablity attributes are set when IOMMU_CACHE property
is true. So cachebility is set as either noncached (normal)
or cached (normal WBWA) directly and avoid setting using
tex remap.

Signed-off-by: Sricharan R <sricharan at codeaurora.org>
---
 drivers/iommu/msm_iommu.c         | 66 +++------------------------------------
 drivers/iommu/msm_iommu_hw-8xxx.h | 10 ++----
 2 files changed, 8 insertions(+), 68 deletions(-)

diff --git a/drivers/iommu/msm_iommu.c b/drivers/iommu/msm_iommu.c
index 1d95d7c..d554ffa 100644
--- a/drivers/iommu/msm_iommu.c
+++ b/drivers/iommu/msm_iommu.c
@@ -41,14 +41,9 @@ __asm__ __volatile__ (							\
 "   mrc   "   #processor "," #op1 ", %0,"  #crn "," #crm "," #op2 "\n"  \
 : "=r" (reg))
 
-#define RCP15_PRRR(reg)		MRC(reg, p15, 0, c10, c2, 0)
-#define RCP15_NMRR(reg)		MRC(reg, p15, 0, c10, c2, 1)
-
 /* bitmap of the page sizes currently supported */
 #define MSM_IOMMU_PGSIZES	(SZ_4K | SZ_64K | SZ_1M | SZ_16M)
 
-static int msm_iommu_tex_class[4];
-
 DEFINE_SPINLOCK(msm_iommu_lock);
 static LIST_HEAD(qcom_iommu_devices);
 
@@ -122,8 +117,6 @@ static void msm_iommu_reset(void __iomem *base, int ncb)
 		SET_TLBFLPTER(base, ctx, 0);
 		SET_TLBSLPTER(base, ctx, 0);
 		SET_TLBLKCR(base, ctx, 0);
-		SET_PRRR(base, ctx, 0);
-		SET_NMRR(base, ctx, 0);
 		SET_CONTEXTIDR(base, ctx, 0);
 	}
 }
@@ -232,13 +225,10 @@ static void __reset_context(void __iomem *base, int ctx)
 	SET_TLBFLPTER(base, ctx, 0);
 	SET_TLBSLPTER(base, ctx, 0);
 	SET_TLBLKCR(base, ctx, 0);
-	SET_PRRR(base, ctx, 0);
-	SET_NMRR(base, ctx, 0);
 }
 
 static void __program_context(void __iomem *base, int ctx, phys_addr_t pgtable)
 {
-	unsigned int prrr, nmrr;
 	__reset_context(base, ctx);
 
 	/* Set up HTW mode */
@@ -268,15 +258,6 @@ static void __program_context(void __iomem *base, int ctx, phys_addr_t pgtable)
 	SET_RCOSH(base, ctx, 1);
 	SET_RCNSH(base, ctx, 1);
 
-	/* Turn on TEX Remap */
-	SET_TRE(base, ctx, 1);
-
-	/* Set TEX remap attributes */
-	RCP15_PRRR(prrr);
-	RCP15_NMRR(nmrr);
-	SET_PRRR(base, ctx, prrr);
-	SET_NMRR(base, ctx, nmrr);
-
 	/* Turn on BFB prefetch */
 	SET_BFBDFE(base, ctx, 1);
 
@@ -452,7 +433,11 @@ static int msm_iommu_map(struct iommu_domain *domain, unsigned long va,
 	spin_lock_irqsave(&msm_iommu_lock, flags);
 
 	sh = (prot & MSM_IOMMU_ATTR_SH) ? 1 : 0;
-	tex = msm_iommu_tex_class[prot & MSM_IOMMU_CP_MASK];
+
+	tex = TEX_0;
+
+	if (prot & IOMMU_CACHE)
+		tex |= BUFFERABLE | CACHEABLE;
 
 	if (tex < 0 || tex > NUM_TEX_CLASS - 1) {
 		ret = -EINVAL;
@@ -699,8 +684,6 @@ static void print_ctx_regs(void __iomem *base, int ctx)
 	       GET_TTBR0(base, ctx), GET_TTBR1(base, ctx));
 	pr_err("SCTLR  = %08x    ACTLR  = %08x\n",
 	       GET_SCTLR(base, ctx), GET_ACTLR(base, ctx));
-	pr_err("PRRR   = %08x    NMRR   = %08x\n",
-	       GET_PRRR(base, ctx), GET_NMRR(base, ctx));
 }
 
 static void insert_iommu_master(struct device *dev,
@@ -912,47 +895,8 @@ static void __exit msm_iommu_driver_exit(void)
 subsys_initcall(msm_iommu_driver_init);
 module_exit(msm_iommu_driver_exit);
 
-static int __init get_tex_class(int icp, int ocp, int mt, int nos)
-{
-	int i = 0;
-	unsigned int prrr = 0;
-	unsigned int nmrr = 0;
-	int c_icp, c_ocp, c_mt, c_nos;
-
-	RCP15_PRRR(prrr);
-	RCP15_NMRR(nmrr);
-
-	for (i = 0; i < NUM_TEX_CLASS; i++) {
-		c_nos = PRRR_NOS(prrr, i);
-		c_mt = PRRR_MT(prrr, i);
-		c_icp = NMRR_ICP(nmrr, i);
-		c_ocp = NMRR_OCP(nmrr, i);
-
-		if (icp == c_icp && ocp == c_ocp && c_mt == mt && c_nos == nos)
-			return i;
-	}
-
-	return -ENODEV;
-}
-
-static void __init setup_iommu_tex_classes(void)
-{
-	msm_iommu_tex_class[MSM_IOMMU_ATTR_NONCACHED] =
-			get_tex_class(CP_NONCACHED, CP_NONCACHED, MT_NORMAL, 1);
-
-	msm_iommu_tex_class[MSM_IOMMU_ATTR_CACHED_WB_WA] =
-			get_tex_class(CP_WB_WA, CP_WB_WA, MT_NORMAL, 1);
-
-	msm_iommu_tex_class[MSM_IOMMU_ATTR_CACHED_WB_NWA] =
-			get_tex_class(CP_WB_NWA, CP_WB_NWA, MT_NORMAL, 1);
-
-	msm_iommu_tex_class[MSM_IOMMU_ATTR_CACHED_WT] =
-			get_tex_class(CP_WT, CP_WT, MT_NORMAL, 1);
-}
-
 static int __init msm_iommu_init(void)
 {
-	setup_iommu_tex_classes();
 	bus_set_iommu(&platform_bus_type, &msm_iommu_ops);
 	return 0;
 }
diff --git a/drivers/iommu/msm_iommu_hw-8xxx.h b/drivers/iommu/msm_iommu_hw-8xxx.h
index fc16010..5be99cb 100644
--- a/drivers/iommu/msm_iommu_hw-8xxx.h
+++ b/drivers/iommu/msm_iommu_hw-8xxx.h
@@ -85,13 +85,9 @@ do { \
 #define SL_NG			(1 << 11)
 
 /* Memory type and cache policy attributes */
-#define MT_SO			0
-#define MT_DEV			1
-#define MT_NORMAL		2
-#define CP_NONCACHED		0
-#define CP_WB_WA		1
-#define CP_WT			2
-#define CP_WB_NWA		3
+#define BUFFERABLE		(1 << 0)
+#define CACHEABLE		(1 << 1)
+#define TEX_0			(1 << 2)
 
 /* Global register setters / getters */
 #define SET_M2VCBR_N(b, N, v)	 SET_GLOBAL_REG_N(M2VCBR_N, N, (b), (v))
-- 
QUALCOMM INDIA, on behalf of Qualcomm Innovation Center, Inc. is a member of Code Aurora Forum, hosted by The Linux Foundation



From sricharan at codeaurora.org  Wed Aug 12 07:47:49 2015
From: sricharan at codeaurora.org (Sricharan R)
Date: Wed, 12 Aug 2015 20:17:49 +0530
Subject: [PATCH 5/5] iommu/msm: Remove driver BROKEN
In-Reply-To: <1439390869-6347-1-git-send-email-sricharan@codeaurora.org>
References: <1439390869-6347-1-git-send-email-sricharan@codeaurora.org>
Message-ID: <1439390869-6347-6-git-send-email-sricharan@codeaurora.org>

Now that the driver is DT adapted, bus_set_iommu gets called
only when on compatible matching. So the driver should not
break multiplatform  builds now. So remove the BROKEN config.

Signed-off-by: Sricharan R <sricharan at codeaurora.org>
---
 drivers/iommu/Kconfig | 1 -
 1 file changed, 1 deletion(-)

diff --git a/drivers/iommu/Kconfig b/drivers/iommu/Kconfig
index f1fb1d3..147de52 100644
--- a/drivers/iommu/Kconfig
+++ b/drivers/iommu/Kconfig
@@ -64,7 +64,6 @@ config MSM_IOMMU
 	bool "MSM IOMMU Support"
 	depends on ARM
 	depends on ARCH_MSM8X60 || ARCH_MSM8960 || COMPILE_TEST
-	depends on BROKEN
 	select IOMMU_API
 	help
 	  Support for the IOMMUs found on certain Qualcomm SOCs.
-- 
QUALCOMM INDIA, on behalf of Qualcomm Innovation Center, Inc. is a member of Code Aurora Forum, hosted by The Linux Foundation



From hdegoede at redhat.com  Wed Aug 12 07:49:10 2015
From: hdegoede at redhat.com (Hans de Goede)
Date: Wed, 12 Aug 2015 16:49:10 +0200
Subject: [linux-sunxi] [PATCH v3 1/3] mmc: sunxi: fix timeout in
 sunxi_mmc_oclk_onoff
In-Reply-To: <bdcb7ce26f359b7fedbd8559eb275c324bfb52bb.1439386047.git.hramrach@gmail.com>
References: <cover.1439381423.git.hramrach@gmail.com>
 <7f9c6f99b31702c02436ef3356b3ebffa4754260.1439381423.git.hramrach@gmail.com>
 <bdcb7ce26f359b7fedbd8559eb275c324bfb52bb.1439386047.git.hramrach@gmail.com>
Message-ID: <55CB5CE6.1000303@redhat.com>

Hi,

On 08/12/2015 03:29 PM, Michal Suchanek wrote:
> The 250ms timeout is too short.
>
> On my system enabling the oclk takes under 50ms and disabling slightly
> over 100ms when idle. Under load disabling the clock can take over
> 350ms.
>
> This does not make mmc clock gating look like good option to have on
> sunxi but the system should not crash with mmc clock gating enabled
> nonetheless.
>
> This patch sets the timeout to 750ms.
>
> Signed-off-by: Michal Suchanek <hramrach at gmail.com>
>
> ---
> v3
>   - remove debug message

Thanks, this one looks good to me:

Acked-by: Hans de Goede <hdegoede at redhat.com>

Ulf, can you apply this one please?

Thanks & Regards,

Hans


> v2
>   - fix formatting
> ---
>   drivers/mmc/host/sunxi-mmc.c | 2 +-
>   1 file changed, 1 insertion(+), 1 deletion(-)
>
> diff --git a/drivers/mmc/host/sunxi-mmc.c b/drivers/mmc/host/sunxi-mmc.c
> index 4d3e1ff..a7b7a67 100644
> --- a/drivers/mmc/host/sunxi-mmc.c
> +++ b/drivers/mmc/host/sunxi-mmc.c
> @@ -595,7 +595,7 @@ static irqreturn_t sunxi_mmc_handle_manual_stop(int irq, void *dev_id)
>
>   static int sunxi_mmc_oclk_onoff(struct sunxi_mmc_host *host, u32 oclk_en)
>   {
> -	unsigned long expire = jiffies + msecs_to_jiffies(250);
> +	unsigned long expire = jiffies + msecs_to_jiffies(750);
>   	u32 rval;
>
>   	rval = mmc_readl(host, REG_CLKCR);
>


From balbi at ti.com  Wed Aug 12 07:52:16 2015
From: balbi at ti.com (Felipe Balbi)
Date: Wed, 12 Aug 2015 09:52:16 -0500
Subject: [RFC/PATCH-v4.2-rc6 2/5] arm: boot: dts: am4372: add ARM timers
 and SCU nodes
In-Reply-To: <20150812072816.GR4215@atomide.com>
References: <1439242911-715-1-git-send-email-balbi@ti.com>
 <1439242911-715-3-git-send-email-balbi@ti.com>
 <20150812072816.GR4215@atomide.com>
Message-ID: <20150812145216.GB13884@saruman.tx.rr.com>

On Wed, Aug 12, 2015 at 12:28:16AM -0700, Tony Lindgren wrote:
> * Felipe Balbi <balbi at ti.com> [150810 14:44]:
> > AM437x devices sport SCU, TWD and Global timers,
> > let's add them to DTS so they have a chance to
> > probe and be used by Linux.
> 
> Is this one safe to apply already without the Kconfig change?
> 
> Or will it cause multi_v7_defconfig with the timers selected
> to not boot properly?

I'd have to try :-) But it should be safe, just the timers won't be
chosen for anything :-)

-- 
balbi
-------------- next part --------------
A non-text attachment was scrubbed...
Name: signature.asc
Type: application/pgp-signature
Size: 819 bytes
Desc: Digital signature
URL: <http://lists.infradead.org/pipermail/linux-arm-kernel/attachments/20150812/adb93b17/attachment.sig>

From balbi at ti.com  Wed Aug 12 07:53:28 2015
From: balbi at ti.com (Felipe Balbi)
Date: Wed, 12 Aug 2015 09:53:28 -0500
Subject: [RFC/PATCH-v4.2-rc6 4/5] arm: omap2: timer: simplify
 omap4_local_timer_init()
In-Reply-To: <20150812071424.GO4215@atomide.com>
References: <1439242911-715-1-git-send-email-balbi@ti.com>
 <1439242911-715-5-git-send-email-balbi@ti.com>
 <20150812071424.GO4215@atomide.com>
Message-ID: <20150812145328.GC13884@saruman.tx.rr.com>

On Wed, Aug 12, 2015 at 12:14:24AM -0700, Tony Lindgren wrote:
> * Felipe Balbi <balbi at ti.com> [150810 14:44]:
> > all users of omap4_local_timer_init() are already
> > DT-only, so we can remove the check for having
> > DTB or not.
> > 
> > While at that, fix a typo in comment.
> 
> We already have d1dabab2841d ("ARM: OMAP2+: Clean up
> omap4_local_timer_init") in Linux next reviewed-by you :)

hehe, I had forgotten about that sorry. I'll rebase this on today's
next and resend the series. I'll also test $subject without the other
patches.

-- 
balbi
-------------- next part --------------
A non-text attachment was scrubbed...
Name: signature.asc
Type: application/pgp-signature
Size: 819 bytes
Desc: Digital signature
URL: <http://lists.infradead.org/pipermail/linux-arm-kernel/attachments/20150812/68c7e75a/attachment.sig>

From will.deacon at arm.com  Wed Aug 12 07:53:46 2015
From: will.deacon at arm.com (Will Deacon)
Date: Wed, 12 Aug 2015 15:53:46 +0100
Subject: [PATCH 4/5] iommu/msm: Set cacheability attributes without tex
 remap
In-Reply-To: <1439390869-6347-5-git-send-email-sricharan@codeaurora.org>
References: <1439390869-6347-1-git-send-email-sricharan@codeaurora.org>
 <1439390869-6347-5-git-send-email-sricharan@codeaurora.org>
Message-ID: <20150812145346.GH23540@arm.com>

On Wed, Aug 12, 2015 at 03:47:48PM +0100, Sricharan R wrote:
> The cacheablity attributes are set when IOMMU_CACHE property
> is true. So cachebility is set as either noncached (normal)
> or cached (normal WBWA) directly and avoid setting using
> tex remap.

Does this IOMMU support the ARMv7 short descriptor format? If so, would
it work with Yong's patch here:

  http://lists.infradead.org/pipermail/linux-arm-kernel/2015-August/361615.html

I've not gotten around to reviewing the latest version yet, but having
other IOMMUs consolidate on one set of page table code would be a good
thing.

Will


From broonie at kernel.org  Wed Aug 12 07:56:33 2015
From: broonie at kernel.org (Mark Brown)
Date: Wed, 12 Aug 2015 15:56:33 +0100
Subject: [PATCH 02/20] regmap: Remove regmap_bulk_write 64bit support
In-Reply-To: <20150812130838.GN19600@pengutronix.de>
References: <1439374365-20623-1-git-send-email-mpa@pengutronix.de>
 <1439374365-20623-3-git-send-email-mpa@pengutronix.de>
 <20150812102550.GQ10748@sirena.org.uk>
 <20150812104436.GA19600@pengutronix.de>
 <20150812105758.GU10748@sirena.org.uk>
 <20150812122856.GF19600@pengutronix.de>
 <20150812123537.GH10748@sirena.org.uk>
 <20150812130838.GN19600@pengutronix.de>
Message-ID: <20150812145633.GJ10748@sirena.org.uk>

On Wed, Aug 12, 2015 at 03:08:38PM +0200, Markus Pargmann wrote:
> On Wed, Aug 12, 2015 at 01:35:37PM +0100, Mark Brown wrote:

> > I'd expect the framework to cope with things when ints are 64 bit.  We
> > don't try to support anything else, though.

> For all non-busses it probably will. All the format functions are not
> working for 64bit at the moment. But that's something different, also I
> didn't see a bus device with 64bit yet.

This is expected to be used by memory mapped devices.
-------------- next part --------------
A non-text attachment was scrubbed...
Name: signature.asc
Type: application/pgp-signature
Size: 473 bytes
Desc: Digital signature
URL: <http://lists.infradead.org/pipermail/linux-arm-kernel/attachments/20150812/fe1cad71/attachment.sig>

From oliver+list at schinagl.nl  Wed Aug 12 07:57:27 2015
From: oliver+list at schinagl.nl (Olliver Schinagl)
Date: Wed, 12 Aug 2015 16:57:27 +0200
Subject: [linux-sunxi] [PATCH 3/3] mmc: sunxi: use controller automatic
 clock gating.
In-Reply-To: <CAOMqctSdkPgDfBCNsGNsNnoh4GqVW59oZC3q9HX3gY_NneMPKw@mail.gmail.com>
References: <cover.1439381423.git.hramrach@gmail.com>
 <c33b221f9b622e3bad9d855a7ad1887b82827244.1439381423.git.hramrach@gmail.com>
 <55CB3D92.6040403@redhat.com> <55CB47D8.4010207@schinagl.nl>
 <CAOMqctSdkPgDfBCNsGNsNnoh4GqVW59oZC3q9HX3gY_NneMPKw@mail.gmail.com>
Message-ID: <55CB5ED7.40406@schinagl.nl>

The thing is, I never saw the prints in my console (i assume that it 
prints on the console by default with earlyprintk/debug stuff enabled as 
per sunxi-usual)?

P.S. what I do as a basic test, is on our very very minimal empty debian 
image (think < 150 mb) i do a apt-get build-essential that installs 
about 150mb worth of packages.

Without these patches, everything works as before. All packages 
successfully installed. I can do more intense testing later, but I 
figured that this is pretty intense.

Olliver

On 12-08-15 15:37, Michal Suchanek wrote:
> On 12 August 2015 at 15:19, Olliver Schinagl <oliver+list at schinagl.nl> wrote:
>> Hey,
>>
>> On 12-08-15 14:35, Hans de Goede wrote:
>>> Hi,
>>>
>>> On 12-08-15 14:23, Michal Suchanek wrote:
>>>> When core does not set the MMC_QUIRK_BROKEN_CLK_GATING flag enable
>>>> automatic hardware controlled clock gating on the mmc interface.
>>>>
>>>> Signed-off-by: Michal Suchanek <hramrach at gmail.com>
>>>
>>> In general this looks good, but I wonder how intensively this has
>>> been tested ?
>> It doesn't matter actually, it took some time longer, but the mmc still
>> craps out even with Michal's 3 patches. I'll revert hans's earlier patch
>> again and do a bit more extensive testing.
> Does the oclk switch timeout even after 750ms?
>
> In some earlier tests I tried to enable/disable the clock repeatedly
> when it failed but it seemed to have little effect on the total time
> it took to disable the clock in the end.
>
> Maybe it would be worh trying to set the timeout to some insanely long
> value and test stability with that. I picked 750 as around twice the
> maximum time it ever took on my board.
>
> Thanks
>
> Michal
>



From paul at pwsan.com  Wed Aug 12 08:01:21 2015
From: paul at pwsan.com (Paul Walmsley)
Date: Wed, 12 Aug 2015 15:01:21 +0000 (UTC)
Subject: [PATCH] [ARM][TEGRA] Fix AHB base address on tegra20, tegra30
 and tegra114
In-Reply-To: <1439042292-19912-1-git-send-email-kwizart@gmail.com>
References: <1439042292-19912-1-git-send-email-kwizart@gmail.com>
Message-ID: <alpine.DEB.2.02.1508121500300.7154@utopia.booyaka.com>

On Sat, 8 Aug 2015, Nicolas Chauvet wrote:

> Current base address is wrong by 0x04 bytes for AHB bus device as shown in dmesg:
>  tegra-ahb 6000c004.ahb: incorrect AHB base address in DT data - enabling workaround
> 
> To correct old dtbs,  the commit ce7a10b0ff3db63 checks for the low bit
> of the base address and removes theses 0x04 bytes at runtime.
> 
> This patch fix the original dts, so upstream version doesn't need
> the workaround of the base address.
> 
> As both addresses are valid, this patch doesn't break compatibility
> 
> Tested on tegra20-paz00 (aka ac100)
> 
> Signed-off-by: Nicolas Chauvet <kwizart at gmail.com>

Reviewed-by: Paul Walmsley <paul at pwsan.com>


- Paul


From will.deacon at arm.com  Wed Aug 12 08:02:32 2015
From: will.deacon at arm.com (Will Deacon)
Date: Wed, 12 Aug 2015 16:02:32 +0100
Subject: [PATCH] arm64: Add __exception_irq_entry definition for function
 graph
In-Reply-To: <1439388979-1518-1-git-send-email-jungseoklee85@gmail.com>
References: <1439388979-1518-1-git-send-email-jungseoklee85@gmail.com>
Message-ID: <20150812150232.GI23540@arm.com>

On Wed, Aug 12, 2015 at 03:16:19PM +0100, Jungseok Lee wrote:
> The gic_handle_irq() is defined with __exception_irq_entry attribute.
> A single remaining work is to add its definition as ARM did. Below
> shows how function graph data is changed with these hunks.

[...]

> diff --git a/arch/arm64/include/asm/traps.h b/arch/arm64/include/asm/traps.h
> index 232e4ba..0cc2f29 100644
> --- a/arch/arm64/include/asm/traps.h
> +++ b/arch/arm64/include/asm/traps.h
> @@ -34,13 +34,32 @@ struct undef_hook {
>  void register_undef_hook(struct undef_hook *hook);
>  void unregister_undef_hook(struct undef_hook *hook);
>  
> +#ifdef CONFIG_FUNCTION_GRAPH_TRACER
> +static inline int __in_irqentry_text(unsigned long ptr)
> +{
> +	extern char __irqentry_text_start[];
> +	extern char __irqentry_text_end[];
> +
> +	return ptr >= (unsigned long)&__irqentry_text_start &&
> +	       ptr < (unsigned long)&__irqentry_text_end;
> +}
> +#else
> +static inline int __in_irqentry_text(unsigned long ptr)
> +{
> +	return 0;
> +}
> +#endif
> +
>  static inline int in_exception_text(unsigned long ptr)
>  {
>  	extern char __exception_text_start[];
>  	extern char __exception_text_end[];
> +	int in;
> +
> +	in = ptr >= (unsigned long)&__exception_text_start &&
> +	     ptr < (unsigned long)&__exception_text_end;
>  
> -	return ptr >= (unsigned long)&__exception_text_start &&
> -	       ptr < (unsigned long)&__exception_text_end;
> +	return in ? : __in_irqentry_text(ptr);
>  }

On arm64, this function is only called from dump_backtrace, so I'm
struggling to see why this change makes any difference to the ftrace
output.

What am I missing?

Will


From eric.auger at linaro.org  Wed Aug 12 08:09:54 2015
From: eric.auger at linaro.org (Eric Auger)
Date: Wed, 12 Aug 2015 17:09:54 +0200
Subject: [PATCH 5/6] irqchip: GICv3: Don't deactivate interrupts forwarded
 to a guest
In-Reply-To: <55CB5617.1030901@arm.com>
References: <1436447951-22357-1-git-send-email-marc.zyngier@arm.com>
 <1436447951-22357-6-git-send-email-marc.zyngier@arm.com>
 <55C9C860.4020107@linaro.org> <55CB5617.1030901@arm.com>
Message-ID: <55CB61C2.3010306@linaro.org>

On 08/12/2015 04:20 PM, Marc Zyngier wrote:
> On 11/08/15 11:03, Eric Auger wrote:
>> On 07/09/2015 03:19 PM, Marc Zyngier wrote:
>>> Commit 0a4377de3056 ("genirq: Introduce irq_set_vcpu_affinity() to
>>> target an interrupt to a VCPU") added just what we needed at the
>>> lowest level to allow an interrupt to be deactivated by a guest.
>>>
>>> When such a request reaches the GIC, it knows it doesn't need to
>>> perform the deactivation anymore, and can safely leave the guest
>>> do its magic. This of course requires additional support in both
>>> VFIO and KVM.
>>>
>>> Signed-off-by: Marc Zyngier <marc.zyngier at arm.com>
>>> ---
>>>  drivers/irqchip/irq-gic-v3.c | 29 +++++++++++++++++++++++++++--
>>>  1 file changed, 27 insertions(+), 2 deletions(-)
>>>
>>> diff --git a/drivers/irqchip/irq-gic-v3.c b/drivers/irqchip/irq-gic-v3.c
>>> index e02592b..a1ca9e6 100644
>>> --- a/drivers/irqchip/irq-gic-v3.c
>>> +++ b/drivers/irqchip/irq-gic-v3.c
>>> @@ -70,6 +70,11 @@ static inline int gic_irq_in_rdist(struct irq_data *d)
>>>  	return gic_irq(d) < 32;
>>>  }
>>>  
>>> +static inline bool forwarded_irq(struct irq_data *d)
>>> +{
>>> +	return d->handler_data != NULL;
>>> +}
>>> +
>>>  static inline void __iomem *gic_dist_base(struct irq_data *d)
>>>  {
>>>  	if (gic_irq_in_rdist(d))	/* SGI+PPI -> SGI_base for this CPU */
>>> @@ -231,6 +236,12 @@ static void gic_poke_irq(struct irq_data *d, u32 offset)
>>>  static void gic_mask_irq(struct irq_data *d)
>>>  {
>>>  	gic_poke_irq(d, GICD_ICENABLER);
>>> +	/*
>>> +	 * When masking a forwarded interrupt, make sure it is
>>> +	 * deactivated as well.
>> To me it is not straightforward to understand why a forwarded IRQ would
>> need to be DIR'ed when masked. This is needed because of the disable_irq
>> optimisation, I would add a related comment.
>>
> 
> The lazy disable_irq is just an optimization.
yes that's true but it causes a real problem here since although you
disabled the IRQ, a new one can show up, we do not call the actual
handler (that was supposed to forward it to the guest) but still you
expect the guest to complete it. Practically that's why the host must
take in charge the deactivation in that case, and this happens during
the masking with this implementation.
> 
> The real reason is that if we mask an interrupt on the host, it is
> because we don't want the guest to process it at all. There is three cases:
> 
> 1) The interrupt was inactive: no problem
> 2) The interrupt was active, but not presented to the guest yet: no
> problem either. The interrupt will be taken again on unmask.
> 3) The interrupt was active and presented to the guest: we might get a
> double deactivate, which shouldn't be a big deal (but mostly should not
> occur at all).
> 
> Would something like this make sense?
yes makes sense. The only thing that scares me a bit is 3: when
masking/DIR an edge irq (#n) we can have the same new physical IRQ
showing up when unmasking (#n+1); when guest deactivates the #nth
virtual IRQ it is going to DIR #n+1 physical IRQ.

Also with VGIC state machine, we must be attention not to inject the
second forwarded edge irq while there is one programmed in the LR. We
said "it comes from the HW so it must be true"? Not safe anymore here ...

> 
> On a related note, I wonder if we need to mark the interrupt pending if
> it is configured as edge. Otherwise, we could loose an interrupt in case
> 2 (mask, deactivate, unmask, oh look nothing triggers). Thoughts?
Yes I think this makes sense indeed. Definitively this one will be lost.

Eric
> 
> Thanks,
> 
> 	M.
> 



From lars at metafoo.de  Wed Aug 12 08:17:37 2015
From: lars at metafoo.de (Lars-Peter Clausen)
Date: Wed, 12 Aug 2015 17:17:37 +0200
Subject: [PATCH v4] iio: adc: xilinx-xadc: Push interrupts into hardirq
 context
In-Reply-To: <1439334049-28671-1-git-send-email-xander.huff@ni.com>
References: <55C07160.5040907@metafoo.de>
 <1439334049-28671-1-git-send-email-xander.huff@ni.com>
Message-ID: <55CB6391.7060502@metafoo.de>

On 08/12/2015 01:00 AM, Xander Huff wrote:
> The driver currently registers a pair of irq handlers using
> request_threaded_irq(), however the synchronization mechanism between the
> hardirq and the threadedirq handler is a regular spinlock.
> 
> Unfortunately, this breaks PREEMPT_RT builds, where a spinlock can sleep,
> and is thus not able to be acquired from a hardirq handler. This patch gets
> rid of the threaded handler and pushes all interrupt handling into the
> hardirq context, and uses request_irq().
> 
> To validate that this change has no impact on RT performance, here are
> cyclictest values with no processes running:
> 
> $ sudo cyclictest -S -m -p 98
> # /dev/cpu_dma_latency set to 0us
> policy: fifo: loadavg: 0.00 0.01 0.05 1/174 2539
> T: 0 ( 1405) P:98 I:1000 C:167010520 Min: 9 Act: 12 Avg: 12 Max: 75
> T: 1 ( 1862) P:98 I:1500 C:111340339 Min: 9 Act: 12 Avg: 12 Max: 73
> 
> Then, all xadc raw handles were accessed in a continuous loop via
> /sys/bus/iio/devices/iio:device0:
> 
> $ sudo cyclictest -S -m -p 98
> # /dev/cpu_dma_latency set to 0us
> policy: fifo: loadavg: 7.84 7.70 7.63 3/182 4260
> T: 0 ( 2559) P:98 I:1000 C:241557018 Min: 11 Act: 18 Avg: 21 Max: 74
> T: 1 ( 2560) P:98 I:1500 C:161038006 Min: 10 Act: 21 Avg: 20 Max: 73
> 
> Signed-off-by: Xander Huff <xander.huff at ni.com>

Looks good, thanks.

Acked-by: Lars-Peter Clausen <lars at metafoo.de>


From jungseoklee85 at gmail.com  Wed Aug 12 08:18:49 2015
From: jungseoklee85 at gmail.com (Jungseok Lee)
Date: Thu, 13 Aug 2015 00:18:49 +0900
Subject: [PATCH] arm64: Add __exception_irq_entry definition for function
 graph
In-Reply-To: <20150812150232.GI23540@arm.com>
References: <1439388979-1518-1-git-send-email-jungseoklee85@gmail.com>
 <20150812150232.GI23540@arm.com>
Message-ID: <9C0002C4-EEC5-415F-A0BC-2284E662D308@gmail.com>

On Aug 13, 2015, at 12:02 AM, Will Deacon wrote:

Hi Will,

> On Wed, Aug 12, 2015 at 03:16:19PM +0100, Jungseok Lee wrote:
>> The gic_handle_irq() is defined with __exception_irq_entry attribute.
>> A single remaining work is to add its definition as ARM did. Below
>> shows how function graph data is changed with these hunks.
> 
> [...]
> 
>> diff --git a/arch/arm64/include/asm/traps.h b/arch/arm64/include/asm/traps.h
>> index 232e4ba..0cc2f29 100644
>> --- a/arch/arm64/include/asm/traps.h
>> +++ b/arch/arm64/include/asm/traps.h
>> @@ -34,13 +34,32 @@ struct undef_hook {
>> void register_undef_hook(struct undef_hook *hook);
>> void unregister_undef_hook(struct undef_hook *hook);
>> 
>> +#ifdef CONFIG_FUNCTION_GRAPH_TRACER
>> +static inline int __in_irqentry_text(unsigned long ptr)
>> +{
>> +	extern char __irqentry_text_start[];
>> +	extern char __irqentry_text_end[];
>> +
>> +	return ptr >= (unsigned long)&__irqentry_text_start &&
>> +	       ptr < (unsigned long)&__irqentry_text_end;
>> +}
>> +#else
>> +static inline int __in_irqentry_text(unsigned long ptr)
>> +{
>> +	return 0;
>> +}
>> +#endif
>> +
>> static inline int in_exception_text(unsigned long ptr)
>> {
>> 	extern char __exception_text_start[];
>> 	extern char __exception_text_end[];
>> +	int in;
>> +
>> +	in = ptr >= (unsigned long)&__exception_text_start &&
>> +	     ptr < (unsigned long)&__exception_text_end;
>> 
>> -	return ptr >= (unsigned long)&__exception_text_start &&
>> -	       ptr < (unsigned long)&__exception_text_end;
>> +	return in ? : __in_irqentry_text(ptr);
>> }
> 
> On arm64, this function is only called from dump_backtrace, so I'm
> struggling to see why this change makes any difference to the ftrace
> output.
> 
> What am I missing?

As you mentioned, the above hunk does not change the ftrace behavior.

The first diff directly affects the first condition check in print_graph_irq
function in kernel/trace/trace_functions_graph.c. The code snippet is as follows.

if (addr < (unsigned long)__irqentry_text_start ||
	addr >= (unsigned long)__irqentry_text_end)
	return;

I hope it would be helpful.

Best Regards
Jungseok Lee

From catalin.marinas at arm.com  Wed Aug 12 08:23:38 2015
From: catalin.marinas at arm.com (Catalin Marinas)
Date: Wed, 12 Aug 2015 16:23:38 +0100
Subject: [PATCH v2 0/2] net: thunder: Add ACPI support.
In-Reply-To: <55CA5567.9010002@caviumnetworks.com>
References: <1439254717-2875-1-git-send-email-ddaney.cavm@gmail.com>
 <20150811.114908.1384923604512568161.davem@davemloft.net>
 <55CA5567.9010002@caviumnetworks.com>
Message-ID: <20150812152337.GB5393@e104818-lin.cambridge.arm.com>

On Tue, Aug 11, 2015 at 01:04:55PM -0700, David Daney wrote:
> On 08/11/2015 11:49 AM, David Miller wrote:
> >From: David Daney <ddaney.cavm at gmail.com>
> >Date: Mon, 10 Aug 2015 17:58:35 -0700
> >
> >>Change from v1:  Drop PHY binding part, use fwnode_property* APIs.
> >>
> >>The first patch (1/2) rearranges the existing code a little with no
> >>functional change to get ready for the second.  The second (2/2) does
> >>the actual work of adding support to extract the needed information
> >>from the ACPI tables.
> >
> >Series applied.
> 
> Thank you very much.
> 
> >In the future it might be better structured to try and get the OF
> >node, and if that fails then try and use the ACPI method to obtain
> >these values.
> 
> Our current approach, as you can see in the patch, is the opposite.  If ACPI
> is being used, prefer that over the OF device tree.
> 
> You seem to be recommending precedence for OF.  It should be consistent
> across all drivers/sub-systems, so do you really think that OF before ACPI
> is the way to go?

On arm64 (unless you use a vendor kernel), DT takes precedence over ACPI
if both arm provided to the kernel (and it's a fair assumption given
that ACPI on ARM is still in the early days). You could also force ACPI
with acpi=force on the kernel cmd line and the arch code will not
unflatten the DT even if it is provided, therefore is_of_node(fwnode)
returning false.

I haven't looked at your driver in detail but something like AMD's
xgbe_probe() uses a single function for both DT and ACPI with
device_property_read_*() functions getting the information from the
correct place in either case. The ACPI vs DT precedence is handled by
the arch boot code, we never mix the two and confuse the drivers.

-- 
Catalin


From ddaney at caviumnetworks.com  Wed Aug 12 08:36:04 2015
From: ddaney at caviumnetworks.com (David Daney)
Date: Wed, 12 Aug 2015 08:36:04 -0700
Subject: [PATCH v2 0/2] net: thunder: Add ACPI support.
In-Reply-To: <20150812152337.GB5393@e104818-lin.cambridge.arm.com>
References: <1439254717-2875-1-git-send-email-ddaney.cavm@gmail.com>
 <20150811.114908.1384923604512568161.davem@davemloft.net>
 <55CA5567.9010002@caviumnetworks.com>
 <20150812152337.GB5393@e104818-lin.cambridge.arm.com>
Message-ID: <55CB67E4.8030001@caviumnetworks.com>

On 08/12/2015 08:23 AM, Catalin Marinas wrote:
> On Tue, Aug 11, 2015 at 01:04:55PM -0700, David Daney wrote:
>> On 08/11/2015 11:49 AM, David Miller wrote:
>>> From: David Daney <ddaney.cavm at gmail.com>
>>> Date: Mon, 10 Aug 2015 17:58:35 -0700
>>>
>>>> Change from v1:  Drop PHY binding part, use fwnode_property* APIs.
>>>>
>>>> The first patch (1/2) rearranges the existing code a little with no
>>>> functional change to get ready for the second.  The second (2/2) does
>>>> the actual work of adding support to extract the needed information
>>> >from the ACPI tables.
>>>
>>> Series applied.
>>
>> Thank you very much.
>>
>>> In the future it might be better structured to try and get the OF
>>> node, and if that fails then try and use the ACPI method to obtain
>>> these values.
>>
>> Our current approach, as you can see in the patch, is the opposite.  If ACPI
>> is being used, prefer that over the OF device tree.
>>
>> You seem to be recommending precedence for OF.  It should be consistent
>> across all drivers/sub-systems, so do you really think that OF before ACPI
>> is the way to go?
>
> On arm64 (unless you use a vendor kernel), DT takes precedence over ACPI
> if both arm provided to the kernel (and it's a fair assumption given
> that ACPI on ARM is still in the early days). You could also force ACPI
> with acpi=force on the kernel cmd line and the arch code will not
> unflatten the DT even if it is provided, therefore is_of_node(fwnode)
> returning false.
>
> I haven't looked at your driver in detail but something like AMD's
> xgbe_probe() uses a single function for both DT and ACPI with
> device_property_read_*() functions getting the information from the
> correct place in either case. The ACPI vs DT precedence is handled by
> the arch boot code, we never mix the two and confuse the drivers.
>

My long term plan is to create something like 
firmware_get_mac_address(), that would encapsulate  of_get_mac_address() 
and the ACPI equivalent.

Same for firmware_phy_find_device().

These would function as you suggest, but lacking this infrastructure, we 
implemented this patch set instead.

Thanks,
David Daney


From pratyush.anand at gmail.com  Wed Aug 12 08:40:20 2015
From: pratyush.anand at gmail.com (Pratyush Anand)
Date: Wed, 12 Aug 2015 21:10:20 +0530
Subject: [PATCH v6 1/6] PCI: designware: move calculation of bus addresses
 to DRA7xx
In-Reply-To: <55C44A80.20308@hisilicon.com>
References: <1438848559-232109-1-git-send-email-wangzhou1@hisilicon.com>
 <1438848559-232109-2-git-send-email-wangzhou1@hisilicon.com>
 <55C44A80.20308@hisilicon.com>
Message-ID: <CAHM4w1muj4+OBcsDQ9ePjV77t+iPh7TYY8h5MF66GjD=2ktRew@mail.gmail.com>

On Fri, Aug 7, 2015 at 11:34 AM, Zhou Wang <wangzhou1 at hisilicon.com> wrote:
> [+cc jingoohan1 at gmail.com]
>
> On 2015/8/6 16:09, Zhou Wang wrote:
>> From: gabriele paoloni <gabriele.paoloni at huawei.com>
>>
>> Commit f4c55c5a3f7f "PCI: designware: Program ATU with untranslated
>> address" added the calculation of PCI BUS addresses in designware,
>> storing them in new fields added in "struct pcie_port". This
>> calculation is done for every designware user even if is only
>> applicable to DRA7xx.
>> This patch moves the calculation of the bus addresses to the DRA7xx
>> driver and is needed to allow the rework of designware to use
>> the new DT parsing API.
>>
>> Signed-off-by: Gabriele Paoloni <gabriele.paoloni at huawei.com>
>> Signed-off-by: Zhou Wang <wangzhou1 at hisilicon.com>


Looks fine to me
Acked-by: Pratyush Anand <pratyush.anand at gmail.com>


From marc.zyngier at arm.com  Wed Aug 12 08:40:19 2015
From: marc.zyngier at arm.com (Marc Zyngier)
Date: Wed, 12 Aug 2015 16:40:19 +0100
Subject: [PATCH 5/6] irqchip: GICv3: Don't deactivate interrupts forwarded
 to a guest
In-Reply-To: <55CB61C2.3010306@linaro.org>
References: <1436447951-22357-1-git-send-email-marc.zyngier@arm.com>
 <1436447951-22357-6-git-send-email-marc.zyngier@arm.com>
 <55C9C860.4020107@linaro.org> <55CB5617.1030901@arm.com>
 <55CB61C2.3010306@linaro.org>
Message-ID: <55CB68E3.8020508@arm.com>

On 12/08/15 16:09, Eric Auger wrote:
> On 08/12/2015 04:20 PM, Marc Zyngier wrote:
>> On 11/08/15 11:03, Eric Auger wrote:
>>> On 07/09/2015 03:19 PM, Marc Zyngier wrote:
>>>> Commit 0a4377de3056 ("genirq: Introduce irq_set_vcpu_affinity() to
>>>> target an interrupt to a VCPU") added just what we needed at the
>>>> lowest level to allow an interrupt to be deactivated by a guest.
>>>>
>>>> When such a request reaches the GIC, it knows it doesn't need to
>>>> perform the deactivation anymore, and can safely leave the guest
>>>> do its magic. This of course requires additional support in both
>>>> VFIO and KVM.
>>>>
>>>> Signed-off-by: Marc Zyngier <marc.zyngier at arm.com>
>>>> ---
>>>>  drivers/irqchip/irq-gic-v3.c | 29 +++++++++++++++++++++++++++--
>>>>  1 file changed, 27 insertions(+), 2 deletions(-)
>>>>
>>>> diff --git a/drivers/irqchip/irq-gic-v3.c b/drivers/irqchip/irq-gic-v3.c
>>>> index e02592b..a1ca9e6 100644
>>>> --- a/drivers/irqchip/irq-gic-v3.c
>>>> +++ b/drivers/irqchip/irq-gic-v3.c
>>>> @@ -70,6 +70,11 @@ static inline int gic_irq_in_rdist(struct irq_data *d)
>>>>  	return gic_irq(d) < 32;
>>>>  }
>>>>  
>>>> +static inline bool forwarded_irq(struct irq_data *d)
>>>> +{
>>>> +	return d->handler_data != NULL;
>>>> +}
>>>> +
>>>>  static inline void __iomem *gic_dist_base(struct irq_data *d)
>>>>  {
>>>>  	if (gic_irq_in_rdist(d))	/* SGI+PPI -> SGI_base for this CPU */
>>>> @@ -231,6 +236,12 @@ static void gic_poke_irq(struct irq_data *d, u32 offset)
>>>>  static void gic_mask_irq(struct irq_data *d)
>>>>  {
>>>>  	gic_poke_irq(d, GICD_ICENABLER);
>>>> +	/*
>>>> +	 * When masking a forwarded interrupt, make sure it is
>>>> +	 * deactivated as well.
>>> To me it is not straightforward to understand why a forwarded IRQ would
>>> need to be DIR'ed when masked. This is needed because of the disable_irq
>>> optimisation, I would add a related comment.
>>>
>>
>> The lazy disable_irq is just an optimization.
> yes that's true but it causes a real problem here since although you
> disabled the IRQ, a new one can show up, we do not call the actual
> handler (that was supposed to forward it to the guest) but still you
> expect the guest to complete it. Practically that's why the host must
> take in charge the deactivation in that case, and this happens during
> the masking with this implementation.

Yeah, I see what you mean. If we end-up here with an active interrupt,
that's because the lazy interrupt masking has been used, and we need to
fix up things.

>>
>> The real reason is that if we mask an interrupt on the host, it is
>> because we don't want the guest to process it at all. There is three cases:
>>
>> 1) The interrupt was inactive: no problem
>> 2) The interrupt was active, but not presented to the guest yet: no
>> problem either. The interrupt will be taken again on unmask.
>> 3) The interrupt was active and presented to the guest: we might get a
>> double deactivate, which shouldn't be a big deal (but mostly should not
>> occur at all).
>>
>> Would something like this make sense?
> yes makes sense. The only thing that scares me a bit is 3: when
> masking/DIR an edge irq (#n) we can have the same new physical IRQ
> showing up when unmasking (#n+1); when guest deactivates the #nth
> virtual IRQ it is going to DIR #n+1 physical IRQ.

That bit is not worrying me too much for a few reasons reasons:
- You normally don't mask a forwarded interrupt. You only do that on
specific events like guest termination. At that point, it doesn't matter
anymore.
- Edge interrupts can always be coalesced. So getting one event instead
of two is not a problem.
- Deactivation (specially on EOI from a guest) is not "refcounted". It
just clears the active bit.

> Also with VGIC state machine, we must be attention not to inject the
> second forwarded edge irq while there is one programmed in the LR. We
> said "it comes from the HW so it must be true"? Not safe anymore here ...

I don't believe this is a problem. You should never end-up masking the
interrupt if you don't intend to tear it down (this is why we have the
active bit - to avoid masking thing in normal operations).

> 
>>
>> On a related note, I wonder if we need to mark the interrupt pending if
>> it is configured as edge. Otherwise, we could loose an interrupt in case
>> 2 (mask, deactivate, unmask, oh look nothing triggers). Thoughts?
> Yes I think this makes sense indeed. Definitively this one will be lost.

Depends. If we are to restore a working interrupt flow, then we need it.
If we just mask to allow an interrupt to be "unforwarded", then we do
not have to care.

Thanks,

	M.
-- 
Jazz is not dead. It just smells funny...


From pratyush.anand at gmail.com  Wed Aug 12 08:42:01 2015
From: pratyush.anand at gmail.com (Pratyush Anand)
Date: Wed, 12 Aug 2015 21:12:01 +0530
Subject: [PATCH v6 2/6] ARM/PCI: remove align_resource in pci_sys_data
In-Reply-To: <55C44AF2.8040807@hisilicon.com>
References: <1438848559-232109-1-git-send-email-wangzhou1@hisilicon.com>
 <1438848559-232109-3-git-send-email-wangzhou1@hisilicon.com>
 <55C44AF2.8040807@hisilicon.com>
Message-ID: <CAHM4w1=s_3A8L+XXyLCoxUphOed13CzShUiWwkK7vv8XJCBgjg@mail.gmail.com>

On Fri, Aug 7, 2015 at 11:36 AM, Zhou Wang <wangzhou1 at hisilicon.com> wrote:
> [+cc jingoohan1 at gmail.com]
>
> On 2015/8/6 16:09, Zhou Wang wrote:
>> From: gabriele paoloni <gabriele.paoloni at huawei.com>
>>
>> This patch is needed in order to unify the PCIe designware framework for ARM and
>> ARM64 architectures. In the PCIe designware unification process we are calling
>> pci_create_root_bus() passing a "sysdata" parameter that is the same for both
>> ARM and ARM64 and is of type "struct pcie_port*". In the ARM case this will
>> cause a problem with the function pcibios_align_resource(); in fact this will
>> cast "dev->sysdata" to "struct pci_sys_data*", whereas designware had passed a
>> "struct pcie_port*" pointer.
>>
>> This patch solves the issue by removing "align_resource" from "pci_sys_data"
>> struct and defining a static global function pointer in "bios32.c"
>>
>> Signed-off-by: Gabriele Paoloni <gabriele.paoloni at huawei.com>

Acked-by: Pratyush Anand <pratyush.anand at gmail.com>


From Shenwei.Wang at freescale.com  Wed Aug 12 08:47:09 2015
From: Shenwei.Wang at freescale.com (Shenwei Wang)
Date: Wed, 12 Aug 2015 15:47:09 +0000
Subject: [PATCH v3 1/1] misc: sram: add dev_pm_ops to support module power
 gate
In-Reply-To: <1438272681-29338-1-git-send-email-shenwei.wang@freescale.com>
References: <1438272681-29338-1-git-send-email-shenwei.wang@freescale.com>
Message-ID: <CY1PR0301MB08436DD71E719BC9622879B3837E0@CY1PR0301MB0843.namprd03.prod.outlook.com>

2nd Ping.

Regards,
Shenwei

> -----Original Message-----
> From: linux-arm-kernel [mailto:linux-arm-kernel-bounces at lists.infradead.org] On
> Behalf Of Shenwei Wang
> Sent: 2015?7?30? 11:11
> To: gregkh at linuxfoundation.org; arnd at arndb.de
> Cc: Huang Yongcai-B20788; linux-arm-kernel at lists.infradead.org
> Subject: [PATCH v3 1/1] misc: sram: add dev_pm_ops to support module power
> gate
> 
> When system goes into low power states like SUSPEND_MEM and HIBERNATION,
> the hardware IP block may be powered off to reduce the power consumption.
> This power down will lost all the data inside the ram. This patch added the
> dev_pm_ops and implemented two callbacks: suspend_noirq and resume_noirq,
> which will save the data in the on-chip-ram right before power down and restore
> it after system resumes.
> 
> A new property string named "can-power-gate" is added to the devicetree
> bindings too.
> 
> Signed-off-by: Shenwei Wang <shenwei.wang at freescale.com>
> Signed-off-by: Anson Huang <b20788 at freescale.com>
> ---
> Change log:
> 
> PATCH v3
> 	Removed the unnecessary clk_enable/clk_disable.
> 
> PATCH v2
> 	Use vmalloc to allocate the SRAM backup memory.
> 	Code clean up.
> 
>  Documentation/devicetree/bindings/misc/sram.txt |  2 ++
>  drivers/misc/sram.c                             | 42
> +++++++++++++++++++++++++
>  2 files changed, 44 insertions(+)
> 
> diff --git a/Documentation/devicetree/bindings/misc/sram.txt
> b/Documentation/devicetree/bindings/misc/sram.txt
> index 36cbe5a..1170086 100644
> --- a/Documentation/devicetree/bindings/misc/sram.txt
> +++ b/Documentation/devicetree/bindings/misc/sram.txt
> @@ -33,6 +33,8 @@ Optional properties in the area nodes:
> 
>  - compatible : standard definition, should contain a vendor specific string
>                 in the form <vendor>,[<device>-]<usage>
> +- can-power-gate: a property to tell the driver that the sram can support
> +		power gate
> 
>  Example:
> 
> diff --git a/drivers/misc/sram.c b/drivers/misc/sram.c index 15c33cc..db9f1fa
> 100644
> --- a/drivers/misc/sram.c
> +++ b/drivers/misc/sram.c
> @@ -30,7 +30,9 @@
> 
>  struct sram_dev {
>  	struct device *dev;
> +	void *power_off_save;
>  	void __iomem *virt_base;
> +	u32 size;
> 
>  	struct gen_pool *pool;
>  	struct clk *clk;
> @@ -156,6 +158,33 @@ static int sram_reserve_regions(struct sram_dev
> *sram, struct resource *res)
>  	return ret;
>  }
> 
> +static int sram_suspend_noirq(struct device *dev) {
> +	struct platform_device *pdev = to_platform_device(dev);
> +	struct sram_dev *sram = platform_get_drvdata(pdev);
> +
> +	if (!sram->power_off_save)
> +		return 0;
> +
> +	/* Save necessary regs */
> +	memcpy(sram->power_off_save, sram->virt_base, sram->size);
> +
> +	return 0;
> +}
> +
> +static int sram_resume_noirq(struct device *dev) {
> +	struct platform_device *pdev = to_platform_device(dev);
> +	struct sram_dev *sram = platform_get_drvdata(pdev);
> +
> +	if (!sram->power_off_save)
> +		return 0;
> +
> +	memcpy(sram->virt_base, sram->power_off_save, sram->size);
> +
> +	return 0;
> +}
> +
>  static int sram_probe(struct platform_device *pdev)  {
>  	struct sram_dev *sram;
> @@ -176,6 +205,7 @@ static int sram_probe(struct platform_device *pdev)
>  	}
> 
>  	size = resource_size(res);
> +	sram->size = size;
> 
>  	if (!devm_request_mem_region(sram->dev, res->start, size, pdev->name)) {
>  		dev_err(sram->dev, "could not request region for resource\n"); @@
> -203,6 +233,9 @@ static int sram_probe(struct platform_device *pdev)
> 
>  	platform_set_drvdata(pdev, sram);
> 
> +	if (of_property_read_bool(pdev->dev.of_node, "can-power-gate"))
> +		sram->power_off_save = vmalloc(size);
> +
>  	dev_dbg(sram->dev, "SRAM pool: %zu KiB @ 0x%p\n",
>  		gen_pool_size(sram->pool) / 1024, sram->virt_base);
> 
> @@ -219,6 +252,9 @@ static int sram_remove(struct platform_device *pdev)
>  	if (sram->clk)
>  		clk_disable_unprepare(sram->clk);
> 
> +	if (sram->power_off_save)
> +		vfree(sram->power_off_save);
> +
>  	return 0;
>  }
> 
> @@ -229,10 +265,16 @@ static const struct of_device_id sram_dt_ids[] = {  };
> #endif
> 
> +static const struct dev_pm_ops sram_pm_ops = {
> +	.suspend_noirq = sram_suspend_noirq,
> +	.resume_noirq = sram_resume_noirq,
> +};
> +
>  static struct platform_driver sram_driver = {
>  	.driver = {
>  		.name = "sram",
>  		.of_match_table = of_match_ptr(sram_dt_ids),
> +		.pm	= &sram_pm_ops,
>  	},
>  	.probe = sram_probe,
>  	.remove = sram_remove,
> --
> 2.5.0.rc2
> 
> 
> 
> _______________________________________________
> linux-arm-kernel mailing list
> linux-arm-kernel at lists.infradead.org
> http://lists.infradead.org/mailman/listinfo/linux-arm-kernel

From torvalds at linux-foundation.org  Wed Aug 12 08:49:45 2015
From: torvalds at linux-foundation.org (Linus Torvalds)
Date: Wed, 12 Aug 2015 08:49:45 -0700
Subject: enabling libgcc for 64-bit divisions, was Re: PROBLEM: XFS on ARM
 corruption 'Structure needs cleaning'
In-Reply-To: <20150812062445.GA4520@infradead.org>
References: <5579B804.9050707@skylable.com>
 <20150612122108.GB60661@bfoster.bfoster>
 <557AD4D4.3010901@skylable.com> <20150612225209.GA20262@dastard>
 <C6D0D499B56584katsuki.uwatoko@toshiba.co.jp>
 <20150812062445.GA4520@infradead.org>
Message-ID: <CA+55aFxcoXkaa1syBVxwb9-bn3rfyFam9fcNY438bkhHjHq+Vw@mail.gmail.com>

On Tue, Aug 11, 2015 at 11:24 PM, Christoph Hellwig <hch at infradead.org> wrote:
>
> Maybe it's time to rely on gcc to handle 64 bit divisions now?

Ugh. gcc still does a pretty horrible job at it. While gcc knows that
a widening 32x32->64 multiplication can be simplified, it doesn't do
the same thing for a 64/32->64 division, and always calls __udivdi3
for it.

Now, __udivdi3 does avoid the general nasty case by then testing the
upper 32 bits of the divisor against zero, so it's not entirely
disastrous. It's just ugly.

But perhaps more importantly, I'm not at all sure libgcc is
kernel-safe. In particular, I'm not at all sure it *remains*
kernel-safe. Just as an example: can you guarantee that libgcc doesn't
implement integer division on some architecture by using the FP
hardware?

There's been a few cases where not having libgcc saved us headaches. I
forget the exact details, but it was something like several years ago
that we had gcc start to generate some insane crap exception handling
for C code generation, and the fact that we didn't include libgcc was
what made us catch it because of the resulting link error.

libgcc just isn't reliable in kernel space. I'm not opposed to some
random architecture using it (arch/tile does include "-lgcc" for
example), but I _do_ object to the notion that we say "let's use
libgcc in general".

So no. I do not believe that the occasional pain of a few people who
do 64-bit divides incorrectly is a good enough argument to start using
libgcc.

                 Linus


From nico at fluxnic.net  Wed Aug 12 08:50:46 2015
From: nico at fluxnic.net (Nicolas Pitre)
Date: Wed, 12 Aug 2015 11:50:46 -0400 (EDT)
Subject: arm kernel oops in highmem.c with 4.2
In-Reply-To: <1439386436.3153.23.camel@redhat.com>
References: <CALeDE9Ox3=sh3AXQ0NUG6BBfU5i5YrMY=LDpcTHQWqz2=60F2g@mail.gmail.com>
 <20150805100701.GV7557@n2100.arm.linux.org.uk>
 <CALeDE9PXF=gQCaBCiHpHy2nXOooQOmsCQvSgOv+wQw3mta=P6A@mail.gmail.com>
 <20150805112713.GY7557@n2100.arm.linux.org.uk>
 <1439315290.3153.11.camel@redhat.com>
 <20150811181008.GA7557@n2100.arm.linux.org.uk>
 <alpine.LFD.2.20.1508111501130.1515@knanqh.ubzr>
 <20150811195638.GC7557@n2100.arm.linux.org.uk>
 <alpine.LFD.2.20.1508111558210.1515@knanqh.ubzr>
 <1439327845.3153.17.camel@redhat.com>
 <alpine.LFD.2.20.1508112116320.1515@knanqh.ubzr>
 <1439386436.3153.23.camel@redhat.com>
Message-ID: <alpine.LFD.2.20.1508121147430.1515@knanqh.ubzr>

On Wed, 12 Aug 2015, Mark Salter wrote:

> On Tue, 2015-08-11 at 22:18 -0400, Nicolas Pitre wrote:
> > On Tue, 11 Aug 2015, Mark Salter wrote:
> > 
> > > On Tue, 2015-08-11 at 16:20 -0400, Nicolas Pitre wrote:
> > > > diff --git a/arch/arm/lib/uaccess_with_memcpy.c 
> > > > b/arch/arm/lib/uaccess_with_memcpy.c
> > > > index 3e58d71001..4b39af2dfd 100644
> > > > --- a/arch/arm/lib/uaccess_with_memcpy.c
> > > > +++ b/arch/arm/lib/uaccess_with_memcpy.c
> > > > @@ -96,7 +96,7 @@ __copy_to_user_memcpy(void __user *to, const void 
> > > > *from, unsigned long n)
> > > >  	}
> > > >  
> > > >  	/* the mmap semaphore is taken only if not in an atomic 
> > > > context 
> > > > */
> > > > -	atomic = in_atomic();
> > > > +	atomic = faulthandler_disabled();
> > > >  
> > > >  	if (!atomic)
> > > >  		down_read(&current->mm->mmap_sem);
> > > 
> > > Yeah, that fixes the problem I was seeing.
> > 
> > Good!  Then I'll add it to RMK's patch system.  May I add a tested-by 
> > tag with your name?
> 
> Yes

Queued as patch #8414/1.


Nicolas


From eric.auger at linaro.org  Wed Aug 12 08:51:58 2015
From: eric.auger at linaro.org (Eric Auger)
Date: Wed, 12 Aug 2015 17:51:58 +0200
Subject: [PATCH 5/6] irqchip: GICv3: Don't deactivate interrupts forwarded
 to a guest
In-Reply-To: <55CB68E3.8020508@arm.com>
References: <1436447951-22357-1-git-send-email-marc.zyngier@arm.com>
 <1436447951-22357-6-git-send-email-marc.zyngier@arm.com>
 <55C9C860.4020107@linaro.org> <55CB5617.1030901@arm.com>
 <55CB61C2.3010306@linaro.org> <55CB68E3.8020508@arm.com>
Message-ID: <55CB6B9E.9020900@linaro.org>

On 08/12/2015 05:40 PM, Marc Zyngier wrote:
> On 12/08/15 16:09, Eric Auger wrote:
>> On 08/12/2015 04:20 PM, Marc Zyngier wrote:
>>> On 11/08/15 11:03, Eric Auger wrote:
>>>> On 07/09/2015 03:19 PM, Marc Zyngier wrote:
>>>>> Commit 0a4377de3056 ("genirq: Introduce irq_set_vcpu_affinity() to
>>>>> target an interrupt to a VCPU") added just what we needed at the
>>>>> lowest level to allow an interrupt to be deactivated by a guest.
>>>>>
>>>>> When such a request reaches the GIC, it knows it doesn't need to
>>>>> perform the deactivation anymore, and can safely leave the guest
>>>>> do its magic. This of course requires additional support in both
>>>>> VFIO and KVM.
>>>>>
>>>>> Signed-off-by: Marc Zyngier <marc.zyngier at arm.com>
>>>>> ---
>>>>>  drivers/irqchip/irq-gic-v3.c | 29 +++++++++++++++++++++++++++--
>>>>>  1 file changed, 27 insertions(+), 2 deletions(-)
>>>>>
>>>>> diff --git a/drivers/irqchip/irq-gic-v3.c b/drivers/irqchip/irq-gic-v3.c
>>>>> index e02592b..a1ca9e6 100644
>>>>> --- a/drivers/irqchip/irq-gic-v3.c
>>>>> +++ b/drivers/irqchip/irq-gic-v3.c
>>>>> @@ -70,6 +70,11 @@ static inline int gic_irq_in_rdist(struct irq_data *d)
>>>>>  	return gic_irq(d) < 32;
>>>>>  }
>>>>>  
>>>>> +static inline bool forwarded_irq(struct irq_data *d)
>>>>> +{
>>>>> +	return d->handler_data != NULL;
>>>>> +}
>>>>> +
>>>>>  static inline void __iomem *gic_dist_base(struct irq_data *d)
>>>>>  {
>>>>>  	if (gic_irq_in_rdist(d))	/* SGI+PPI -> SGI_base for this CPU */
>>>>> @@ -231,6 +236,12 @@ static void gic_poke_irq(struct irq_data *d, u32 offset)
>>>>>  static void gic_mask_irq(struct irq_data *d)
>>>>>  {
>>>>>  	gic_poke_irq(d, GICD_ICENABLER);
>>>>> +	/*
>>>>> +	 * When masking a forwarded interrupt, make sure it is
>>>>> +	 * deactivated as well.
>>>> To me it is not straightforward to understand why a forwarded IRQ would
>>>> need to be DIR'ed when masked. This is needed because of the disable_irq
>>>> optimisation, I would add a related comment.
>>>>
>>>
>>> The lazy disable_irq is just an optimization.
>> yes that's true but it causes a real problem here since although you
>> disabled the IRQ, a new one can show up, we do not call the actual
>> handler (that was supposed to forward it to the guest) but still you
>> expect the guest to complete it. Practically that's why the host must
>> take in charge the deactivation in that case, and this happens during
>> the masking with this implementation.
> 
> Yeah, I see what you mean. If we end-up here with an active interrupt,
> that's because the lazy interrupt masking has been used, and we need to
> fix up things.
> 
>>>
>>> The real reason is that if we mask an interrupt on the host, it is
>>> because we don't want the guest to process it at all. There is three cases:
>>>
>>> 1) The interrupt was inactive: no problem
>>> 2) The interrupt was active, but not presented to the guest yet: no
>>> problem either. The interrupt will be taken again on unmask.
>>> 3) The interrupt was active and presented to the guest: we might get a
>>> double deactivate, which shouldn't be a big deal (but mostly should not
>>> occur at all).
>>>
>>> Would something like this make sense?
>> yes makes sense. The only thing that scares me a bit is 3: when
>> masking/DIR an edge irq (#n) we can have the same new physical IRQ
>> showing up when unmasking (#n+1); when guest deactivates the #nth
>> virtual IRQ it is going to DIR #n+1 physical IRQ.
> 
> That bit is not worrying me too much for a few reasons reasons:
> - You normally don't mask a forwarded interrupt. You only do that on
> specific events like guest termination. At that point, it doesn't matter
> anymore.
> - Edge interrupts can always be coalesced. So getting one event instead
> of two is not a problem.
> - Deactivation (specially on EOI from a guest) is not "refcounted". It
> just clears the active bit.
> 
>> Also with VGIC state machine, we must be attention not to inject the
>> second forwarded edge irq while there is one programmed in the LR. We
>> said "it comes from the HW so it must be true"? Not safe anymore here ...
> 
> I don't believe this is a problem. You should never end-up masking the
> interrupt if you don't intend to tear it down (this is why we have the
> active bit - to avoid masking thing in normal operations).

OK
> 
>>
>>>
>>> On a related note, I wonder if we need to mark the interrupt pending if
>>> it is configured as edge. Otherwise, we could loose an interrupt in case
>>> 2 (mask, deactivate, unmask, oh look nothing triggers). Thoughts?
>> Yes I think this makes sense indeed. Definitively this one will be lost.
> 
> Depends. If we are to restore a working interrupt flow, then we need it.
> If we just mask to allow an interrupt to be "unforwarded", then we do
> not have to care.

yes. I am currently focused on unforwarding and effectively that works
fine since, as you explained before, I am tearing down the system.

Best Regards

Eric
> 
> Thanks,
> 
> 	M.
> 



From ricardo.ribalda at gmail.com  Wed Aug 12 09:04:04 2015
From: ricardo.ribalda at gmail.com (Ricardo Ribalda Delgado)
Date: Wed, 12 Aug 2015 18:04:04 +0200
Subject: [PATCH] spi/spi-xilinx: Fix mixed poll/irq mode
Message-ID: <1439395444-25599-1-git-send-email-ricardo.ribalda@gmail.com>

Once the module process a transfer in irq mode, the next poll transfer
will not work because the transmitter is left in inhibited state.

Fixes: 22417352f6b7f623 (Use polling mode on small transfers)
Reported-by: Edward Kigwana <ekigwana at scires.com>
Signed-off-by: Ricardo Ribalda Delgado <ricardo.ribalda at gmail.com>
---
 drivers/spi/spi-xilinx.c | 4 +++-
 1 file changed, 3 insertions(+), 1 deletion(-)

diff --git a/drivers/spi/spi-xilinx.c b/drivers/spi/spi-xilinx.c
index 133f53a9c1d4..7abf6792cc11 100644
--- a/drivers/spi/spi-xilinx.c
+++ b/drivers/spi/spi-xilinx.c
@@ -302,8 +302,10 @@ static int xilinx_spi_txrx_bufs(struct spi_device *spi, struct spi_transfer *t)
 		remaining_words -= n_words;
 	}
 
-	if (use_irq)
+	if (use_irq) {
 		xspi->write_fn(0, xspi->regs + XIPIF_V123B_DGIER_OFFSET);
+		xspi->write_fn(cr, xspi->regs + XSPI_CR_OFFSET);
+	}
 
 	return t->len;
 }
-- 
2.5.0



From steve.capper at linaro.org  Wed Aug 12 09:22:18 2015
From: steve.capper at linaro.org (Steve Capper)
Date: Wed, 12 Aug 2015 17:22:18 +0100
Subject: [PATCH v8 7/7] kprobes: Add arm64 case in kprobe example module
In-Reply-To: <1439254364-15362-8-git-send-email-dave.long@linaro.org>
References: <1439254364-15362-1-git-send-email-dave.long@linaro.org>
 <1439254364-15362-8-git-send-email-dave.long@linaro.org>
Message-ID: <CAPvkgC0DF5qkMgbVkgBZj8B3oyX47E5JUkr6nL+es-x5HJbK5A@mail.gmail.com>

On 11 August 2015 at 01:52, David Long <dave.long at linaro.org> wrote:
> From: Sandeepa Prabhu <sandeepa.s.prabhu at gmail.com>
>
> Add info prints in sample kprobe handlers for ARM64
>
> Signed-off-by: Sandeepa Prabhu <sandeepa.s.prabhu at gmail.com>
> ---
>  samples/kprobes/kprobe_example.c | 8 ++++++++
>  1 file changed, 8 insertions(+)

I'm not going through this series backwards, but I did run the kprobe
sample modules first, and nothing happened... (i.e. nothing fired).

The kernel usage of do_fork (which is used as an example by the sample
code) has been changed by:
3033f14a clone: support passing tls argument via C rather than pt_regs magic

Now everything appears to go through _do_fork rather than do_fork.

I'll send a fixup shortly, but if anyone else is running these modules
and worrying about a lack of events... worry less :-).

Cheers,
--
Steve


From moritz.fischer at ettus.com  Wed Aug 12 09:27:40 2015
From: moritz.fischer at ettus.com (Moritz Fischer)
Date: Wed, 12 Aug 2015 09:27:40 -0700
Subject: [PATCH] pinctrl-zynq.c: Fix typos in smc0_nand_grp and
 smc0_nor_grp
In-Reply-To: <1439389332-9373-1-git-send-email-mike.looijmans@topic.nl>
References: <1439389332-9373-1-git-send-email-mike.looijmans@topic.nl>
Message-ID: <CAAtXAHdbHoqMQP0wHpHiUbD6d6W8WcDaB=5VR2D5Nh29Seue9A@mail.gmail.com>

Acked-by: Moritz Fischer <moritz.fischer at ettus.com>

On Wed, Aug 12, 2015 at 7:22 AM, Mike Looijmans <mike.looijmans at topic.nl> wrote:
> Group names should be smc0_nand_grp and smc0_nor_grp, otherwise you'll
> get errors like this if you try to pinmux them via the devicetree:
> zynq-pinctrl 700.pinctrl: invalid group "smc0_nand_grp" for function "smc0_nand"
>
> Probably a typo while creating these tables.
>
> Signed-off-by: Mike Looijmans <mike.looijmans at topic.nl>
> Acked-by: S?ren Brinkmann <soren.brinkmann at xilinx.com>
> ---
>  drivers/pinctrl/pinctrl-zynq.c | 4 ++--
>  1 file changed, 2 insertions(+), 2 deletions(-)
>
> diff --git a/drivers/pinctrl/pinctrl-zynq.c b/drivers/pinctrl/pinctrl-zynq.c
> index 7ce23b6..5aafea8 100644
> --- a/drivers/pinctrl/pinctrl-zynq.c
> +++ b/drivers/pinctrl/pinctrl-zynq.c
> @@ -706,10 +706,10 @@ static const char * const sdio1_wp_groups[] = {"gpio0_0_grp",
>                 "gpio0_39_grp", "gpio0_41_grp", "gpio0_43_grp",
>                 "gpio0_45_grp", "gpio0_47_grp", "gpio0_49_grp",
>                 "gpio0_51_grp", "gpio0_53_grp", "sdio1_emio_wp_grp"};
> -static const char * const smc0_nor_groups[] = {"smc0_nor"};
> +static const char * const smc0_nor_groups[] = {"smc0_nor_grp"};
>  static const char * const smc0_nor_cs1_groups[] = {"smc0_nor_cs1_grp"};
>  static const char * const smc0_nor_addr25_groups[] = {"smc0_nor_addr25_grp"};
> -static const char * const smc0_nand_groups[] = {"smc0_nand"};
> +static const char * const smc0_nand_groups[] = {"smc0_nand_grp"};
>  static const char * const can0_groups[] = {"can0_0_grp", "can0_1_grp",
>                 "can0_2_grp", "can0_3_grp", "can0_4_grp", "can0_5_grp",
>                 "can0_6_grp", "can0_7_grp", "can0_8_grp", "can0_9_grp",
> --
> 1.9.1
>
>
> _______________________________________________
> linux-arm-kernel mailing list
> linux-arm-kernel at lists.infradead.org
> http://lists.infradead.org/mailman/listinfo/linux-arm-kernel


From bigeasy at linutronix.de  Wed Aug 12 09:33:28 2015
From: bigeasy at linutronix.de (Sebastian Andrzej Siewior)
Date: Wed, 12 Aug 2015 18:33:28 +0200
Subject: [PATCH v4] iio: adc: xilinx-xadc: Push interrupts into hardirq
 context
In-Reply-To: <55CB6391.7060502@metafoo.de>
References: <55C07160.5040907@metafoo.de>
 <1439334049-28671-1-git-send-email-xander.huff@ni.com>
 <55CB6391.7060502@metafoo.de>
Message-ID: <55CB7558.3090608@linutronix.de>

On 08/12/2015 05:17 PM, Lars-Peter Clausen wrote:
> On 08/12/2015 01:00 AM, Xander Huff wrote:
>> Unfortunately, this breaks PREEMPT_RT builds, where a spinlock can sleep,
>> and is thus not able to be acquired from a hardirq handler. This patch gets
>> rid of the threaded handler and pushes all interrupt handling into the
>> hardirq context, and uses request_irq().
>>
>> To validate that this change has no impact on RT performance, here are
>> cyclictest values with no processes running:
> 
> Looks good, thanks.
> 
> Acked-by: Lars-Peter Clausen <lars at metafoo.de>

Yes, I'm fine with the rework, too.

Sebastian


From HartleyS at visionengravers.com  Wed Aug 12 09:39:46 2015
From: HartleyS at visionengravers.com (Hartley Sweeten)
Date: Wed, 12 Aug 2015 16:39:46 +0000
Subject: [PATCH] ARM/EP93xx/timer: Migrate to new 'set-state' interface
In-Reply-To: <744dca162a7626694770a9f51457566a33c3e08f.1438852023.git.viresh.kumar@linaro.org>
References: <744dca162a7626694770a9f51457566a33c3e08f.1438852023.git.viresh.kumar@linaro.org>
Message-ID: <BN3PR0101MB10579524DEE61E49B8725469D07E0@BN3PR0101MB1057.prod.exchangelabs.com>

On Thursday, August 06, 2015 2:11 AM, Viresh Kumar wrote:
> Migrate EP93xx driver to the new 'set-state' interface provided by
> clockevents core, the earlier 'set-mode' interface is marked obsolete
> now.
>
> This also enables us to implement callbacks for new states of clockevent
> devices, for example: ONESHOT_STOPPED.
>
> Signed-off-by: Viresh Kumar <viresh.kumar at linaro.org>

Reviewed-by: H Hartley Sweeten <hsweeten at visionengravers.com>



From will.deacon at arm.com  Wed Aug 12 09:53:24 2015
From: will.deacon at arm.com (Will Deacon)
Date: Wed, 12 Aug 2015 17:53:24 +0100
Subject: [PATCH] arm64: Add __exception_irq_entry definition for function
 graph
In-Reply-To: <9C0002C4-EEC5-415F-A0BC-2284E662D308@gmail.com>
References: <1439388979-1518-1-git-send-email-jungseoklee85@gmail.com>
 <20150812150232.GI23540@arm.com>
 <9C0002C4-EEC5-415F-A0BC-2284E662D308@gmail.com>
Message-ID: <20150812165324.GK23540@arm.com>

On Wed, Aug 12, 2015 at 04:18:49PM +0100, Jungseok Lee wrote:
> On Aug 13, 2015, at 12:02 AM, Will Deacon wrote:
> > On Wed, Aug 12, 2015 at 03:16:19PM +0100, Jungseok Lee wrote:
> >> diff --git a/arch/arm64/include/asm/traps.h b/arch/arm64/include/asm/traps.h
> >> index 232e4ba..0cc2f29 100644
> >> --- a/arch/arm64/include/asm/traps.h
> >> +++ b/arch/arm64/include/asm/traps.h
> >> @@ -34,13 +34,32 @@ struct undef_hook {
> >> void register_undef_hook(struct undef_hook *hook);
> >> void unregister_undef_hook(struct undef_hook *hook);
> >> 
> >> +#ifdef CONFIG_FUNCTION_GRAPH_TRACER
> >> +static inline int __in_irqentry_text(unsigned long ptr)
> >> +{
> >> +	extern char __irqentry_text_start[];
> >> +	extern char __irqentry_text_end[];
> >> +
> >> +	return ptr >= (unsigned long)&__irqentry_text_start &&
> >> +	       ptr < (unsigned long)&__irqentry_text_end;
> >> +}
> >> +#else
> >> +static inline int __in_irqentry_text(unsigned long ptr)
> >> +{
> >> +	return 0;
> >> +}
> >> +#endif
> >> +
> >> static inline int in_exception_text(unsigned long ptr)
> >> {
> >> 	extern char __exception_text_start[];
> >> 	extern char __exception_text_end[];
> >> +	int in;
> >> +
> >> +	in = ptr >= (unsigned long)&__exception_text_start &&
> >> +	     ptr < (unsigned long)&__exception_text_end;
> >> 
> >> -	return ptr >= (unsigned long)&__exception_text_start &&
> >> -	       ptr < (unsigned long)&__exception_text_end;
> >> +	return in ? : __in_irqentry_text(ptr);
> >> }
> > 
> > On arm64, this function is only called from dump_backtrace, so I'm
> > struggling to see why this change makes any difference to the ftrace
> > output.
> > 
> > What am I missing?
> 
> As you mentioned, the above hunk does not change the ftrace behavior.
> 
> The first diff directly affects the first condition check in print_graph_irq
> function in kernel/trace/trace_functions_graph.c. The code snippet is as follows.
> 
> if (addr < (unsigned long)__irqentry_text_start ||
> 	addr >= (unsigned long)__irqentry_text_end)
> 	return;
> 
> I hope it would be helpful.

Gotcha, thanks for the explanation.

Will


From catalin.marinas at arm.com  Wed Aug 12 09:57:11 2015
From: catalin.marinas at arm.com (Catalin Marinas)
Date: Wed, 12 Aug 2015 17:57:11 +0100
Subject: [PATCH] ARM: l2c: fix support for HW coherent systems in PL310
 cache
In-Reply-To: <55CB0061.2010602@free-electrons.com>
References: <1439312743-6237-1-git-send-email-gregory.clement@free-electrons.com>
 <20150811172620.GK23307@e104818-lin.cambridge.arm.com>
 <55CB0061.2010602@free-electrons.com>
Message-ID: <20150812165711.GF5393@e104818-lin.cambridge.arm.com>

On Wed, Aug 12, 2015 at 10:14:25AM +0200, Gregory CLEMENT wrote:
> On 11/08/2015 19:26, Catalin Marinas wrote:
> > On Tue, Aug 11, 2015 at 07:05:43PM +0200, Gregory CLEMENT wrote:
> >> From: Nadav Haklai <nadavh at marvell.com>
> >>
> >> When a PL310 cache is used in a system that provides hardware
> >> coherency, the entire outer cache operations are useless, and can be
> >> skipped.  Moreover, on some systems, it is harmful as it causes
> >> deadlocks between the Marvell coherency mechanism, the Marvell PCIe
> >> controller and the Cortex-A9.
> >>
> >> This commit extends a previous commit:
> >> 98ea2dba65932ffc456b6d7b11b8a0624e2f7b95 which added the io-coherent
> >> support for the PL310 cache by also disabling the outer cache flush
> >> range operation.
> >>
> >> In the current kernel implementation, the outer cache flush range
> >> operation is triggered by the dma_alloc function.
> >> This operation can be take place during runtime and in some
> >> circumstances may lead to the PCIe/PL310 deadlock on Armada 375/38x
> >> SoCs.
> > 
> > While this may work around the issue for your specific SoC, I think a
> > better fix is in DMA alloc code to avoid flushing caches for coherent
> > devices. This would be the __dma_clear_buffer() implementation which
> > isn't aware of whether the device is coherent or not.
> 
> Indeed, the other use of the outer cache flush range is done pretty
> early in the boot and should not be a problem.
> 
> What do you think of the following patch?
[...]
>  arch/arm/include/asm/outercache.h | 9 +++++++++
>  arch/arm/mm/cache-l2x0.c          | 1 +
>  arch/arm/mm/dma-mapping.c         | 6 ++++--
>  3 files changed, 14 insertions(+), 2 deletions(-)
> 
> diff --git a/arch/arm/include/asm/outercache.h b/arch/arm/include/asm/outercache.h
> index 563b92fc2f41..7f7bbfcf1d32 100644
> --- a/arch/arm/include/asm/outercache.h
> +++ b/arch/arm/include/asm/outercache.h
> @@ -35,6 +35,7 @@ struct outer_cache_fns {
>  	void (*sync)(void);
>  #endif
>  	void (*resume)(void);
> +	bool is_coherent;
> 
>  	/* This is an ARM L2C thing */
>  	void (*write_sec)(unsigned long, unsigned);
> @@ -56,6 +57,14 @@ static inline void outer_inv_range(phys_addr_t start, phys_addr_t end)
>  }
> 
>  /**
> + * outer_is_coherent - tell if the outer cache is io coherent
> + */
> +static inline bool outer_is_coherent(void)
> +{
> +	return outer_cache.is_coherent;
> +}
> +
> +/**
>   * outer_clean_range - clean dirty outer cache lines
>   * @start: starting physical address, inclusive
>   * @end: end physical address, exclusive
> diff --git a/arch/arm/mm/cache-l2x0.c b/arch/arm/mm/cache-l2x0.c
> index 71b3d3309024..0071e276adc0 100644
> --- a/arch/arm/mm/cache-l2x0.c
> +++ b/arch/arm/mm/cache-l2x0.c
> @@ -1291,6 +1291,7 @@ static const struct l2c_init_data of_l2c310_coherent_data __initconst = {
>  		.flush_all   = l2c210_flush_all,
>  		.disable     = l2c310_disable,
>  		.resume      = l2c310_resume,
> +		.is_coherent = true,
>  	},
>  };

I don't really think we need these. If you need to check a device, we
already have is_device_dma_coherent(). Just pass bool argument to
__dma_clear_buffer() and fix the calling places. The __dma_alloc()
function also takes a "bool coherent" but in this case
__alloc_simple_buffer() is only ever used on coherent devices, so you
may not even need to check is_device_dma_coherent() (however, there are
some patches to add CMA support for coherent devices, I don't know
whether they are queued yet).

> diff --git a/arch/arm/mm/dma-mapping.c b/arch/arm/mm/dma-mapping.c
> index 1ced8a0f7a52..4d87df2c16f9 100644
> --- a/arch/arm/mm/dma-mapping.c
> +++ b/arch/arm/mm/dma-mapping.c
> @@ -241,12 +241,14 @@ static void __dma_clear_buffer(struct page *page, size_t size)
>  			page++;
>  			size -= PAGE_SIZE;
>  		}
> -		outer_flush_range(base, end);
> +		if (!outer_is_coherent())
> +			outer_flush_range(base, end);
>  	} else {
>  		void *ptr = page_address(page);
>  		memset(ptr, 0, size);
>  		dmac_flush_range(ptr, ptr + size);
> -		outer_flush_range(__pa(ptr), __pa(ptr) + size);
> +		if (!outer_is_coherent())
> +			outer_flush_range(__pa(ptr), __pa(ptr) + size);
>  	}
>  }

This would make sense if we have a device which is outer coherent but
inner non-coherent, though I doubt this is the case you are trying to
fix.

-- 
Catalin


From lho at apm.com  Wed Aug 12 10:23:11 2015
From: lho at apm.com (Loc Ho)
Date: Wed, 12 Aug 2015 10:23:11 -0700
Subject: [PATCH v3 1/4] edac: Add an function to retrieve the EDAC debugfs
 node
In-Reply-To: <20150812104954.GD14011@nazgul.tnic>
References: <1439326077-25507-1-git-send-email-lho@apm.com>
 <1439326077-25507-2-git-send-email-lho@apm.com>
 <20150812101219.GC14011@nazgul.tnic>
 <20150812104954.GD14011@nazgul.tnic>
Message-ID: <CAPw-ZT=AFtyLt4CNGBzLZcdPr-ekJpQxKA4Y_AiDzqKfhF1-=w@mail.gmail.com>

Hi Borislav,

>> EXPORT_SYMBOL_GPL() if it is going to be used by modules.
>
> Better yet, move it to the header.

I can't move it completely to the header and make it static. It will
generate a lot of compiler warning as it isn't used by other modules.
I will add EXPORT_SYMBOL_GPL() in the next version.

-Loc


From codekipper at gmail.com  Wed Aug 12 10:27:47 2015
From: codekipper at gmail.com (codekipper at gmail.com)
Date: Wed, 12 Aug 2015 19:27:47 +0200
Subject: [PATCH v2] pinctrl: sun4i: add spdif to pin description
Message-ID: <1439400468-1563-1-git-send-email-codekipper@gmail.com>

From: Marcus Cooper <codekipper at gmail.com>

The Allwinner A20(sun7i) SoC is pin to pin compatible with the Allwinner
A10(sun4i) SoC. However the user manual for the A10 devices does not make
any reference to the SPDIF whereas the pins, clocks, DMAs and Interrupts
are mentioned in the A20 documentation.

As products exist based on the A10 with an SPDIF transmitter and with the
code exposed then it is safe to assume that we can include SPDIF in the
pin definitions.

We can also look at the fex file of such a device where the SPDIF pin is
defined.
For example
https://github.com/linux-sunxi/sunxi-boards/blob/master/sys_config/a10/mele_a1000.fex#L822
shows
spdif_dout = port:PB13<4><1><default><default>.

Referring to the http://sunxi.org/Fex_Guide#Port_Definitions this shows
that the spdif out pin is PB13 using multiplex function 4. The enabling
of the pull up will be done in the device tree includes and this will be
delivered in a future patch series.

Changes in v2:
-Add comments to highlight that the spdif pins are not officially documented.

Marcus Cooper (1):
  pinctrl: sun4i: add spdif to pin description.

 drivers/pinctrl/sunxi/pinctrl-sun4i-a10.c | 17 ++++++++++++++---
 1 file changed, 14 insertions(+), 3 deletions(-)

-- 
2.5.0



From codekipper at gmail.com  Wed Aug 12 10:27:48 2015
From: codekipper at gmail.com (codekipper at gmail.com)
Date: Wed, 12 Aug 2015 19:27:48 +0200
Subject: [PATCH v2] pinctrl: sun4i: add spdif to pin description.
In-Reply-To: <1439400468-1563-1-git-send-email-codekipper@gmail.com>
References: <1439400468-1563-1-git-send-email-codekipper@gmail.com>
Message-ID: <1439400468-1563-2-git-send-email-codekipper@gmail.com>

From: Marcus Cooper <codekipper at gmail.com>

Signed-off-by: Marcus Cooper <codekipper at gmail.com>
---
 drivers/pinctrl/sunxi/pinctrl-sun4i-a10.c | 17 ++++++++++++++---
 1 file changed, 14 insertions(+), 3 deletions(-)

diff --git a/drivers/pinctrl/sunxi/pinctrl-sun4i-a10.c b/drivers/pinctrl/sunxi/pinctrl-sun4i-a10.c
index 7376a97..862a096 100644
--- a/drivers/pinctrl/sunxi/pinctrl-sun4i-a10.c
+++ b/drivers/pinctrl/sunxi/pinctrl-sun4i-a10.c
@@ -135,7 +135,14 @@ static const struct sunxi_desc_pin sun4i_a10_pins[] = {
 	SUNXI_PIN(SUNXI_PINCTRL_PIN(B, 3),
 		  SUNXI_FUNCTION(0x0, "gpio_in"),
 		  SUNXI_FUNCTION(0x1, "gpio_out"),
-		  SUNXI_FUNCTION(0x2, "ir0")),		/* TX */
+		  SUNXI_FUNCTION(0x2, "ir0"),		/* TX */
+		/*
+		 * The SPDIF block is not referenced at all in the A10 user
+		 * manual. However it is described in the code leaked and the
+		 * pin descriptions are declared in the A20 user manual which
+		 * is pin compatible with this device.
+		 */
+		  SUNXI_FUNCTION(0x4, "spdif")),        /* SPDIF MCLK */
 	SUNXI_PIN(SUNXI_PINCTRL_PIN(B, 4),
 		  SUNXI_FUNCTION(0x0, "gpio_in"),
 		  SUNXI_FUNCTION(0x1, "gpio_out"),
@@ -176,11 +183,15 @@ static const struct sunxi_desc_pin sun4i_a10_pins[] = {
 		  SUNXI_FUNCTION(0x0, "gpio_in"),
 		  SUNXI_FUNCTION(0x1, "gpio_out"),
 		  SUNXI_FUNCTION(0x2, "i2s"),		/* DI */
-		  SUNXI_FUNCTION(0x3, "ac97")),		/* DI */
+		  SUNXI_FUNCTION(0x3, "ac97"),		/* DI */
+		/* Undocumented mux function - See SPDIF MCLK above */
+		  SUNXI_FUNCTION(0x4, "spdif")),        /* SPDIF IN */
 	SUNXI_PIN(SUNXI_PINCTRL_PIN(B, 13),
 		  SUNXI_FUNCTION(0x0, "gpio_in"),
 		  SUNXI_FUNCTION(0x1, "gpio_out"),
-		  SUNXI_FUNCTION(0x2, "spi2")),		/* CS1 */
+		  SUNXI_FUNCTION(0x2, "spi2"),		/* CS1 */
+		/* Undocumented mux function - See SPDIF MCLK above */
+		  SUNXI_FUNCTION(0x4, "spdif")),        /* SPDIF OUT */
 	SUNXI_PIN(SUNXI_PINCTRL_PIN(B, 14),
 		  SUNXI_FUNCTION(0x0, "gpio_in"),
 		  SUNXI_FUNCTION(0x1, "gpio_out"),
-- 
2.5.0



From rabin at rab.in  Wed Aug 12 10:33:07 2015
From: rabin at rab.in (Rabin Vincent)
Date: Wed, 12 Aug 2015 19:33:07 +0200
Subject: Problem with ftrace uprobes on ARM
In-Reply-To: <55CB1187.6030301@techfak.uni-bielefeld.de>
References: <55C8E417.7080607@techfak.uni-bielefeld.de>
 <20150810193116.GA2895@debian>
 <55CB1187.6030301@techfak.uni-bielefeld.de>
Message-ID: <20150812173307.GA19814@debian>

On Wed, Aug 12, 2015 at 11:27:35AM +0200, Christian Ascheberg wrote:
> Is there any documentation regarding limitations of perf/ftrace support on
> ARM (compared to x86)?

There's Documentation/features/ which lists the status of architecture
support for various kernel options.  I don't know of any other
documentation.

> For example, I also noticed that 'perf help' lists 'trace' command, but
> running 'perf trace' says 'is not a perf-command'.

That doesn't have anything to do with something missing in ARM afaics.
It's probably because your perf wasn't built with libaudit.  Information
is printed about this when you build perf.  The fact that 'perf help'
lists unavailable commands is probably a bug.

 ~/dev/linux/tools/perf$ make
   BUILD:   Doing 'make -j8' parallel build
 config/Makefile:366: No libaudit.h found, disables 'trace' tool, please install audit-libs-devel or libaudit-dev


From catalin.marinas at arm.com  Wed Aug 12 10:40:14 2015
From: catalin.marinas at arm.com (Catalin Marinas)
Date: Wed, 12 Aug 2015 18:40:14 +0100
Subject: [PATCH 2/6] irqchip: GIC: Convert to EOImode == 1
In-Reply-To: <55CB4AC3.6040400@arm.com>
References: <1436447951-22357-1-git-send-email-marc.zyngier@arm.com>
 <1436447951-22357-3-git-send-email-marc.zyngier@arm.com>
 <55C9BD24.10708@linaro.org> <55CB4AC3.6040400@arm.com>
Message-ID: <20150812174014.GG5393@e104818-lin.cambridge.arm.com>

On Wed, Aug 12, 2015 at 02:31:47PM +0100, Marc Zyngier wrote:
> On 11/08/15 10:15, Eric Auger wrote:
> > On 07/09/2015 03:19 PM, Marc Zyngier wrote:
> >>  static int gic_irq_set_irqchip_state(struct irq_data *d,
> >> @@ -272,11 +278,15 @@ static void __exception_irq_entry gic_handle_irq(struct pt_regs *regs)
> >>  		irqnr = irqstat & GICC_IAR_INT_ID_MASK;
> >>  
> >>  		if (likely(irqnr > 15 && irqnr < 1021)) {
> > shouldn't we have < 1020?
> 
> Looks like you have unearthed a very long standing (though not fatal)
> bug - I can trace it back to 2005 and the inclusion of the Realview
> support (see include/asm-arm/arch-realview/entry-macro.S in 8ad68bbf for
> the details).
> 
> It may be that the original GIC didn't make number 1020 a special one,
> though the earliest spec I have access to (GICv1) is already making 1020
> a reserved interrupt number. And looking at the pre-existing code
> (arch/arm/common/gic.c), 1020 seems to already be considered an invalid
> number.
> 
> CC-ing Catalin, as he was the one who introduced it... ;-) Unless he
> says otherwise, I'll cook a patch for that.

I really have no idea where it came from. The code probably pre-dates
the existence of a GIC architecture spec (the GIC spec used to be part
of the board or CPU TRM).

I don't see any problem with using 1020 here.

-- 
Catalin


From grygorii.strashko at ti.com  Wed Aug 12 10:46:02 2015
From: grygorii.strashko at ti.com (Grygorii Strashko)
Date: Wed, 12 Aug 2015 20:46:02 +0300
Subject: [PATCH v2 6/6] irqchip: crossbar: fix irq masking at suspend
In-Reply-To: <1439401562-28874-1-git-send-email-grygorii.strashko@ti.com>
References: <1439401562-28874-1-git-send-email-grygorii.strashko@ti.com>
Message-ID: <1439401562-28874-7-git-send-email-grygorii.strashko@ti.com>

All ARM GIC IRQs have to masked during suspend if they are not
wakeup source. Now this is not happen, since switching to
use IRQ domain hierarchy, because suspend_device_irq() only checks flags
in the last IRQ chip in hierarchy for IRQCHIP_MASK_ON_SUSPEND
bit set. And in the case of TI OMAP DRA7 the last IRQ chip is TI Crossbar
which do not have this flag set.

In case of TI OMAP DRA7 the following IRQ hierarchy is defined:
  ARM GIC <- OMAP wakeupgen <- TI CBAR
ARM GIC - IRQCHIP_MASK_ON_SUSPEND=n
OMAP wakeupgen - IRQCHIP_MASK_ON_SUSPEND=y
TI CBAR - IRQCHIP_MASK_ON_SUSPEND=n

Hence, fix by adding IRQCHIP_MASK_ON_SUSPEND for
TI Crossbar IRQ chip.

Signed-off-by: Grygorii Strashko <grygorii.strashko at ti.com>
---
 drivers/irqchip/irq-crossbar.c | 1 +
 1 file changed, 1 insertion(+)

diff --git a/drivers/irqchip/irq-crossbar.c b/drivers/irqchip/irq-crossbar.c
index 3ba58e7..f5a72cc 100644
--- a/drivers/irqchip/irq-crossbar.c
+++ b/drivers/irqchip/irq-crossbar.c
@@ -70,6 +70,7 @@ static struct irq_chip crossbar_chip = {
 	.irq_retrigger		= irq_chip_retrigger_hierarchy,
 	.irq_set_wake		= irq_chip_set_wake_parent,
 	.irq_set_type		= irq_chip_set_type_parent,
+	.flags			= IRQCHIP_MASK_ON_SUSPEND,
 #ifdef CONFIG_SMP
 	.irq_set_affinity	= irq_chip_set_affinity_parent,
 #endif
-- 
2.5.0



From grygorii.strashko at ti.com  Wed Aug 12 10:45:58 2015
From: grygorii.strashko at ti.com (Grygorii Strashko)
Date: Wed, 12 Aug 2015 20:45:58 +0300
Subject: [PATCH v2 2/6] genirq: fix irqchip_set_wake_parent if
 IRQCHIP_SKIP_SET_WAKE
In-Reply-To: <1439401562-28874-1-git-send-email-grygorii.strashko@ti.com>
References: <1439401562-28874-1-git-send-email-grygorii.strashko@ti.com>
Message-ID: <1439401562-28874-3-git-send-email-grygorii.strashko@ti.com>

The irqchip_set_wake_parent should not fail if IRQ chip
specifies IRQCHIP_SKIP_SET_WAKE. Otherwise, IRQ wakeup
configuration can't be propagated properly through IRQ
domains hierarchy.

In case of TI OMAP DRA7 the issue reproduced with following
configuration:
ARM GIC<-OMAP wakeupgen<-TI CBAR<-GPIO<-GPIO pcf857x<-gpio_key

gpio_key is wakeup source

Failure is reproduced during suspend/resume to RAM:
suspend:
 - gpio_keys_suspend
   enable_irq_wake
     + pcf857x_irq_set_wake
       + omap_gpio_wake_enable
         + TI CBAR irq_chip_set_wake_parent
           + OMAP wakeupgen has no .irq_set_wake()
           and -ENOSYS will be returned

resume:
 - gpio_keys_resume
   + disable_irq_wake
     + irq_set_irq_wake
       + WARN(1, "Unbalanced IRQ %d wake disable\n", irq);

Fixes: 08b55e2a9208 ('genirq: Add irqchip_set_wake_parent')
Signed-off-by: Grygorii Strashko <grygorii.strashko at ti.com>
---
 kernel/irq/chip.c | 4 ++++
 1 file changed, 4 insertions(+)

diff --git a/kernel/irq/chip.c b/kernel/irq/chip.c
index 6de638b..bdb1b9d 100644
--- a/kernel/irq/chip.c
+++ b/kernel/irq/chip.c
@@ -1024,6 +1024,10 @@ int irq_chip_set_vcpu_affinity_parent(struct irq_data *data, void *vcpu_info)
 int irq_chip_set_wake_parent(struct irq_data *data, unsigned int on)
 {
 	data = data->parent_data;
+
+	if (irq_data_get_irq_chip(data)->flags & IRQCHIP_SKIP_SET_WAKE)
+		return 0;
+
 	if (data->chip->irq_set_wake)
 		return data->chip->irq_set_wake(data, on);
 
-- 
2.5.0



From grygorii.strashko at ti.com  Wed Aug 12 10:45:59 2015
From: grygorii.strashko at ti.com (Grygorii Strashko)
Date: Wed, 12 Aug 2015 20:45:59 +0300
Subject: [PATCH v2 3/6] genirq: introduce irq_chip_set_type_parent() helper
In-Reply-To: <1439401562-28874-1-git-send-email-grygorii.strashko@ti.com>
References: <1439401562-28874-1-git-send-email-grygorii.strashko@ti.com>
Message-ID: <1439401562-28874-4-git-send-email-grygorii.strashko@ti.com>

It's expected to use this helper when the current
domain doesn't implement .irq_set_type(),  but expect
the parent to do so.

Signed-off-by: Grygorii Strashko <grygorii.strashko at ti.com>
---
 include/linux/irq.h |  1 +
 kernel/irq/chip.c   | 20 ++++++++++++++++++++
 2 files changed, 21 insertions(+)

diff --git a/include/linux/irq.h b/include/linux/irq.h
index 92188b0..51744bc 100644
--- a/include/linux/irq.h
+++ b/include/linux/irq.h
@@ -484,6 +484,7 @@ extern int irq_chip_set_affinity_parent(struct irq_data *data,
 extern int irq_chip_set_wake_parent(struct irq_data *data, unsigned int on);
 extern int irq_chip_set_vcpu_affinity_parent(struct irq_data *data,
 					     void *vcpu_info);
+extern int irq_chip_set_type_parent(struct irq_data *data, unsigned int type);
 #endif
 
 /* Handling of unhandled and spurious interrupts: */
diff --git a/kernel/irq/chip.c b/kernel/irq/chip.c
index bdb1b9d..b48938b 100644
--- a/kernel/irq/chip.c
+++ b/kernel/irq/chip.c
@@ -985,6 +985,26 @@ int irq_chip_set_affinity_parent(struct irq_data *data,
 }
 
 /**
+ * irq_chip_set_type_parent - Set IRQ type on the parent interrupt
+ * @data:	Pointer to interrupt specific data
+ * @type:	IRQ_TYPE_{LEVEL,EDGE}_* value - see include/linux/irq.h
+ *
+ * Conditional, as the underlying parent chip might not implement it.
+ */
+int irq_chip_set_type_parent(struct irq_data *data, unsigned int type)
+{
+	data = data->parent_data;
+
+	if (irq_data_get_irq_chip(data)->flags & IRQCHIP_SKIP_SET_WAKE)
+		return 0;
+
+	if (data->chip->irq_set_type)
+		return data->chip->irq_set_type(data, type);
+
+	return -ENOSYS;
+}
+
+/**
  * irq_chip_retrigger_hierarchy - Retrigger an interrupt in hardware
  * @data:	Pointer to interrupt specific data
  *
-- 
2.5.0



From grygorii.strashko at ti.com  Wed Aug 12 10:46:01 2015
From: grygorii.strashko at ti.com (Grygorii Strashko)
Date: Wed, 12 Aug 2015 20:46:01 +0300
Subject: [PATCH v2 5/6] ARM: OMAP: wakeupgen: fix arm gic irq type
 configuration
In-Reply-To: <1439401562-28874-1-git-send-email-grygorii.strashko@ti.com>
References: <1439401562-28874-1-git-send-email-grygorii.strashko@ti.com>
Message-ID: <1439401562-28874-6-git-send-email-grygorii.strashko@ti.com>

It's observed that ARM GIC IRQ triggering type is not configured
properly when IRQ is routed through IRQ domain hierarchy and
system started using DT. As result, system will start using default
ARM GIC configuration, ignore DT IRQ triggering configuration,
and value of desc->irq_data.state_use_accessors = 0.

In case of TI OMAP DRA7 the following IRQ hierarchy is defined:
ARM GIC <- OMAP wakeupgen <- TI CBAR

Failed call chain:
     irq_create_of_mapping
     irq_set_irq_type
     __irq_set_trigger
     if (!chip || !chip->irq_set_type) {
        return 0; <- return here
     }
OMAP wakeupgen has no .irq_set_type() defined and, so, IRQ triggering
configuration will not be propagated to parent IRQ domain.

Hence, fix it by using irq_chip_set_type_parent() for
propagation IRQ triggering type to parent IRQ domains.

Fixes: 7136d457f365 ('ARM: omap: convert wakeupgen to stacked domains')
Signed-off-by: Grygorii Strashko <grygorii.strashko at ti.com>
---
 arch/arm/mach-omap2/omap-wakeupgen.c | 1 +
 1 file changed, 1 insertion(+)

diff --git a/arch/arm/mach-omap2/omap-wakeupgen.c b/arch/arm/mach-omap2/omap-wakeupgen.c
index 8e52621..e1d2e99 100644
--- a/arch/arm/mach-omap2/omap-wakeupgen.c
+++ b/arch/arm/mach-omap2/omap-wakeupgen.c
@@ -392,6 +392,7 @@ static struct irq_chip wakeupgen_chip = {
 	.irq_mask		= wakeupgen_mask,
 	.irq_unmask		= wakeupgen_unmask,
 	.irq_retrigger		= irq_chip_retrigger_hierarchy,
+	.irq_set_type		= irq_chip_set_type_parent,
 	.flags			= IRQCHIP_SKIP_SET_WAKE | IRQCHIP_MASK_ON_SUSPEND,
 #ifdef CONFIG_SMP
 	.irq_set_affinity	= irq_chip_set_affinity_parent,
-- 
2.5.0



From grygorii.strashko at ti.com  Wed Aug 12 10:45:56 2015
From: grygorii.strashko at ti.com (Grygorii Strashko)
Date: Wed, 12 Aug 2015 20:45:56 +0300
Subject: [PATCH v2 0/6] genirq: irqdomain_hierarchy: fixes
Message-ID: <1439401562-28874-1-git-send-email-grygorii.strashko@ti.com>

Hi All,

I've had able to identify and reproduce four issues related to switching on
using IRQ domain hierarchy on TI OMAP DRA7 (dra7-evm). Most of them were
discovered during testing of Suspend to RAM and IRQ wakeup functionality.
In my opinion, most of these issue could also affect on other ARM SoC if
they are using IRQ domain hierarchy.

In case of TI OMAP DRA7 the following IRQ hierarchy is defined:
 ARM GIC <- OMAP wakeupgen <- TI CBAR

Issue 1 - patch 1(new): IRQ re-triggering is not working if IRQ domain
hierarchy used in combination with ARM GIC and irq_chip_retrigger_hierarchy()
is used by child IRQ domain.

Issue 2 - patch 2(new): IRQ wakeup configuration is not propagated properly
through IRQ domains hierarchy if irq_chip_set_wake_parent() is used and
parent IRQ domain don't implement .irq_set_wake(), but has 
IRQCHIP_SKIP_SET_WAKE flag set.

Issue 3 - patches 3-5: ARM GIC IRQ triggering type is not configured
properly when IRQ is routed through IRQ domain hierarchy and
system started using DT. As result, system will start using default
ARM GIC configuration, ignore DT IRQ triggering configuration,
and value of desc->irq_data.state_use_accessors = 0.

/ # cat /proc/interrupts -- before
230:          0          0      CBAR  30 Edge    -00000000  48051000.gpio
263:          0          0      CBAR 116 Edge    -00000000  48053000.gpio
296:        246          0      CBAR  67 Edge    -00000000  OMAP UART0
311:        341          0      CBAR  51 Edge    -00000000  48070000.i2c
312:          3          0      CBAR  52 Edge    -00000000  48072000.i2c
313:          0          0      CBAR  56 Edge    -00000000  48060000.i2c
314:        255          0      CBAR  78 Edge    -00000000  mmc0
315:         40          0      CBAR  81 Edge    -00000000  mmc1
316:         13          0      CBAR  91 Edge    -00000000  mmc2
320:          0          0      CBAR  49 Edge    -00000000  4a140000.sata
324:          0          0      CBAR   1 Edge    -00000000  48078000.elm
325:          0          0      CBAR  15 Edge    -00000000  gpmc
333:          0          0      CBAR 335 Edge    -00000000  48484000.ethernet
334:          0          0      CBAR 336 Edge    -00000000  48484000.ethernet
415:          0          0   pcf857x   2 Edge    -00000000  btnUser1
416:          0          0   pcf857x   3 Edge    -00000000  btnUser2
445:          0          0   pinctrl 992 Edge    -00010000  4806a000.seria

/ # cat /proc/interrupts -- after
230:          0          0      CBAR  30 Level   -00002004  48051000.gpio
263:          0          0      CBAR 116 Level   -00002004  48053000.gpio
296:        567          0      CBAR  67 Level   -00002004  OMAP UART0
311:        363          0      CBAR  51 Level   -00002004  48070000.i2c
312:          3          0      CBAR  52 Level   -00002004  48072000.i2c
313:          0          0      CBAR  56 Level   -00002004  48060000.i2c
314:        197          0      CBAR  78 Level   -00002004  mmc0
315:         40          0      CBAR  81 Level   -00002004  mmc1
316:         13          0      CBAR  91 Level   -00002004  mmc2
320:          0          0      CBAR  49 Level   -00002004  4a140000.sata
324:          0          0      CBAR   1 Level   -00002004  48078000.elm
325:          0          0      CBAR  15 Level   -00002004  gpmc
333:          0          0      CBAR 335 Level   -00002004  48484000.ethernet
334:          0          0      CBAR 336 Level   -00002004  48484000.ethernet
415:          0          0   pcf857x   2 Edge    -00000000  btnUser1
416:          4          2   pcf857x   3 Edge    -00000000  btnUser2
445:          0          0   pinctrl 992 Edge    -00010000  4806a000.serial

-xxxxxxxx are current values of desc->irq_data.state_use_accessors

Issue 4 - patch 5(new): ARM GIC IRQs are not masked during suspend even
if they are not wakeup source. 
	This issue related to IRQCHIP MASK ON SUSPEND flag usage and,
honestly, it's not clear how this flag has to be processed in
case of IRQ domain hierarchy - previously there was one IRQ chip per IRQ
desc and if it has IRQCHIP MASK ON SUSPEND flag set we had to mask IRQ.
But now there are up to three (DRA7) IRQ chip per IRQ desc, and all of them
could have different IRQCHIP MASK ON SUSPEND flag's configuration.
	Here, to fix an issue, I've just added IRQCHIP MASK ON SUSPEND flag
to TI Crossbar which is the last IRQ domain in hierarchy.

IRQ domain hierarchy code was merged in 4.1, so it seems these patches
are material for stable 4.1+.

Tested on:
 TI OMAP DRA7, dra7-evm

Series based on:
 Linux 4.2-rc6

Changes in v2:
- initial patch has been split on three;
- added three more patechs.

Link on v1:
 https://lkml.org/lkml/2015/8/11/179

Grygorii Strashko (6):
  genirq: fix irq_chip_retrigger_hierarchy
  genirq: fix irqchip_set_wake_parent if IRQCHIP_SKIP_SET_WAKE
  genirq: introduce irq_chip_set_type_parent() helper
  irqchip: crossbar: fix arm gic irq type configuration
  ARM: OMAP: wakeupgen: fix arm gic irq type configuration
  irqchip: crossbar: fix irq masking at suspend

 arch/arm/mach-omap2/omap-wakeupgen.c |  1 +
 drivers/irqchip/irq-crossbar.c       |  2 ++
 include/linux/irq.h                  |  1 +
 kernel/irq/chip.c                    | 26 +++++++++++++++++++++++++-
 4 files changed, 29 insertions(+), 1 deletion(-)

-- 
2.5.0



From grygorii.strashko at ti.com  Wed Aug 12 10:45:57 2015
From: grygorii.strashko at ti.com (Grygorii Strashko)
Date: Wed, 12 Aug 2015 20:45:57 +0300
Subject: [PATCH v2 1/6] genirq: fix irq_chip_retrigger_hierarchy
In-Reply-To: <1439401562-28874-1-git-send-email-grygorii.strashko@ti.com>
References: <1439401562-28874-1-git-send-email-grygorii.strashko@ti.com>
Message-ID: <1439401562-28874-2-git-send-email-grygorii.strashko@ti.com>

Now irq_chip_retrigger_hierarchy() returns -ENOSYS if it
was not able to find at least one .irq_retrigger() callback
implemented in IRQ domain hierarchy. As result, IRQ
re-triggering is not working now on ARM (TI OMAP) where
ARM GIC is not implemented this callback.
The .irq_retrigger() is optional (see check_irq_resend())
and there are no reasons to fail if it was not found, hence
lets return 0 in this case.

In case of TI OMAP DRA7 the following IRQ hierarchy is defined:
ARM GIC <- OMAP wakeupgen <- TI CBAR

Failure is reproduced during resume from suspend to RAM:
- wakeup by IRQx
- suspend_enter
  + arch_suspend_enable_irqs
    + handle_fasteoi_irq
      + irq_may_run
        + irq_pm_check_wakeup
          + irq_disable(IRQx)
  + dpm_resume_noirq()
    + resume_device_irqs
      + resume_irqs
        + resume_irq
          + __enable_irq <== IRQx is not re-triggered

Fixes: 85f08c17de26 ('genirq: Introduce helper functions...')
Signed-off-by: Grygorii Strashko <grygorii.strashko at ti.com>
---
 kernel/irq/chip.c | 2 +-
 1 file changed, 1 insertion(+), 1 deletion(-)

diff --git a/kernel/irq/chip.c b/kernel/irq/chip.c
index 27f4332..6de638b 100644
--- a/kernel/irq/chip.c
+++ b/kernel/irq/chip.c
@@ -997,7 +997,7 @@ int irq_chip_retrigger_hierarchy(struct irq_data *data)
 		if (data->chip && data->chip->irq_retrigger)
 			return data->chip->irq_retrigger(data);
 
-	return -ENOSYS;
+	return 0;
 }
 
 /**
-- 
2.5.0



From grygorii.strashko at ti.com  Wed Aug 12 10:46:00 2015
From: grygorii.strashko at ti.com (Grygorii Strashko)
Date: Wed, 12 Aug 2015 20:46:00 +0300
Subject: [PATCH v2 4/6] irqchip: crossbar: fix arm gic irq type configuration
In-Reply-To: <1439401562-28874-1-git-send-email-grygorii.strashko@ti.com>
References: <1439401562-28874-1-git-send-email-grygorii.strashko@ti.com>
Message-ID: <1439401562-28874-5-git-send-email-grygorii.strashko@ti.com>

It's observed that ARM GIC IRQ triggering type is not configured
properly when IRQ is routed through IRQ domain hierarchy and
system started using DT. As result, system will start using default
ARM GIC configuration, ignore DT IRQ triggering configuration,
and value of desc->irq_data.state_use_accessors = 0.

In case of TI OMAP DRA7 the following IRQ hierarchy is defined:
ARM GIC <- OMAP wakeupgen <- TI CBAR

Failed call chain:
     irq_create_of_mapping
     irq_set_irq_type
     __irq_set_trigger
     if (!chip || !chip->irq_set_type) {
        return 0; <- return here
     }
Crossbar has no .irq_set_type() defined and, so, IRQ triggering
configuration will not be propagated to parent IRQ domain.

Hence, fix it by using irq_chip_set_type_parent() for
propagation IRQ triggering type to parent IRQ domains.

Fixes: 783d31863fb8 ('irqchip: crossbar: Convert dra7 crossbar...')
Signed-off-by: Grygorii Strashko <grygorii.strashko at ti.com>
---
 drivers/irqchip/irq-crossbar.c | 1 +
 1 file changed, 1 insertion(+)

diff --git a/drivers/irqchip/irq-crossbar.c b/drivers/irqchip/irq-crossbar.c
index 692fe2b..3ba58e7 100644
--- a/drivers/irqchip/irq-crossbar.c
+++ b/drivers/irqchip/irq-crossbar.c
@@ -69,6 +69,7 @@ static struct irq_chip crossbar_chip = {
 	.irq_unmask		= irq_chip_unmask_parent,
 	.irq_retrigger		= irq_chip_retrigger_hierarchy,
 	.irq_set_wake		= irq_chip_set_wake_parent,
+	.irq_set_type		= irq_chip_set_type_parent,
 #ifdef CONFIG_SMP
 	.irq_set_affinity	= irq_chip_set_affinity_parent,
 #endif
-- 
2.5.0



From grygorii.strashko at ti.com  Wed Aug 12 10:48:16 2015
From: grygorii.strashko at ti.com (Grygorii Strashko)
Date: Wed, 12 Aug 2015 20:48:16 +0300
Subject: [PATCH] ARM: OMAP: irqdomain_hierarchy: fix arm gic irq type
 configuration
In-Reply-To: <20150811153338.7e67e6ba@arm.com>
References: <1439285147-20027-1-git-send-email-grygorii.strashko@ti.com>	<20150811122456.1efe1656@arm.com>	<55C9E78D.7040404@ti.com>
 <20150811153338.7e67e6ba@arm.com>
Message-ID: <55CB86E0.1030306@ti.com>

Hi Marc,

On 08/11/2015 05:33 PM, Marc Zyngier wrote:
> On Tue, 11 Aug 2015 13:16:13 +0100
> Grygorii Strashko <grygorii.strashko at ti.com> wrote:
>> On 08/11/2015 02:24 PM, Marc Zyngier wrote:
>>> On Tue, 11 Aug 2015 10:25:47 +0100
>>> Grygorii Strashko <grygorii.strashko at ti.com> wrote:
>>>> It's observed that ARM GIC IRQ triggering type is not configured
>>>> properly when IRQ is routed through IRQ domains hierarchy and
>>>> system started using DT. As result, system will start using default
>>>> ARM GIC configuration, ignore DT IRQ type configuration,
>>>> and value of desc->irq_data.state_use_accessors = 0.
>>>>
>>>> In case of TI OMAP the following IRQ hierarchy is defined:
>>>> ARM GIC <- OMAP wakeupgen <- TI CBAR
>>>>
>>>> Failed call chain:
>>>>    irq_create_of_mapping
>>>>    irq_set_irq_type
>>>>    __irq_set_trigger
>>>>    if (!chip || !chip->irq_set_type) {
>>>>       return 0; <- return here
>>>>    }
>>>>    CBAR has no .irq_set_type() defined and, so, IRQ triggering
>>>>    configuration will not be propagated to parent IRQ domain.
>>>>
>>>> Hence, fix it by introducing irq_chip_set_type_parent(), in the
>>>> same manner as irq_chip_set_wake_parent(), and use it for IRQ
>>>> triggering type propagation to the parent IRQ domain in
>>>> irq-crossbar and omap-wakeupgen.
>>>>
>>>> / # cat /proc/interrupts -- before
>>>> 230:          0          0      CBAR  30 Edge    -00000000  48051000.gpio
>>>> 263:          0          0      CBAR 116 Edge    -00000000  48053000.gpio
>>>> 296:        246          0      CBAR  67 Edge    -00000000  OMAP UART0
>>>> 311:        341          0      CBAR  51 Edge    -00000000  48070000.i2c
>>>> 312:          3          0      CBAR  52 Edge    -00000000  48072000.i2c
>>>> 313:          0          0      CBAR  56 Edge    -00000000  48060000.i2c
>>>> 314:        255          0      CBAR  78 Edge    -00000000  mmc0
>>>> 315:         40          0      CBAR  81 Edge    -00000000  mmc1
>>>> 316:         13          0      CBAR  91 Edge    -00000000  mmc2
>>>> 320:          0          0      CBAR  49 Edge    -00000000  4a140000.sata
>>>> 324:          0          0      CBAR   1 Edge    -00000000  48078000.elm
>>>> 325:          0          0      CBAR  15 Edge    -00000000  gpmc
>>>> 333:          0          0      CBAR 335 Edge    -00000000  48484000.ethernet
>>>> 334:          0          0      CBAR 336 Edge    -00000000  48484000.ethernet
>>>> 415:          0          0   pcf857x   2 Edge    -00000000  btnUser1
>>>> 416:          0          0   pcf857x   3 Edge    -00000000  btnUser2
>>>> 445:          0          0   pinctrl 992 Edge    -00010000  4806a000.seria
>>>>
>>>> / # cat /proc/interrupts -- after
>>>> 230:          0          0      CBAR  30 Level   -00002004  48051000.gpio
>>>> 263:          0          0      CBAR 116 Level   -00002004  48053000.gpio
>>>> 296:        567          0      CBAR  67 Level   -00002004  OMAP UART0
>>>> 311:        363          0      CBAR  51 Level   -00002004  48070000.i2c
>>>> 312:          3          0      CBAR  52 Level   -00002004  48072000.i2c
>>>> 313:          0          0      CBAR  56 Level   -00002004  48060000.i2c
>>>> 314:        197          0      CBAR  78 Level   -00002004  mmc0
>>>> 315:         40          0      CBAR  81 Level   -00002004  mmc1
>>>> 316:         13          0      CBAR  91 Level   -00002004  mmc2
>>>> 320:          0          0      CBAR  49 Level   -00002004  4a140000.sata
>>>> 324:          0          0      CBAR   1 Level   -00002004  48078000.elm
>>>> 325:          0          0      CBAR  15 Level   -00002004  gpmc
>>>> 333:          0          0      CBAR 335 Level   -00002004  48484000.ethernet
>>>> 334:          0          0      CBAR 336 Level   -00002004  48484000.ethernet
>>>> 415:          0          0   pcf857x   2 Edge    -00000000  btnUser1
>>>> 416:          4          2   pcf857x   3 Edge    -00000000  btnUser2
>>>> 445:          0          0   pinctrl 992 Edge    -00010000  4806a000.serial
>>>>
>>>> Fixes: 783d31863fb8 ('irqchip: crossbar: Convert dra7 crossbar to stacked domains')
>>>> Signed-off-by: Grygorii Strashko <grygorii.strashko at ti.com>
>>>> ---
>>>> Hi All,
>>>>
>>>> I can split patch if required and overall solution acceptable.
>>>
>>> This looks good to me. Please repost it after splitting it in two
>>> patches.
>>
>> just to clarify - Do you want to see two or three patches?
>>
>> 2) or 3) arch/arm/mach-omap2/omap-wakeupgen.c |  1 +
>> 2) drivers/irqchip/irq-crossbar.c       |  1 +
>> 1) include/linux/irq.h                  |  1 +
>> 1) kernel/irq/chip.c                    | 16 ++++++++++++++++
>
> Ah, I forgot wakeupgen lived in the omap-specific directory.
>
> Please cut it in 3 then (generic implementation, crossbar and
> wakeupgen).

Sry for delay - found three more problems. Just posted patches.

-- 
regards,
-grygorii


From lho at apm.com  Wed Aug 12 10:50:52 2015
From: lho at apm.com (Loc Ho)
Date: Wed, 12 Aug 2015 10:50:52 -0700
Subject: [PATCH v3 3/4] edac: Add L3/SoC EDAC support to the APM X-Gene
 SoC EDAC driver
In-Reply-To: <20150812105121.GE14011@nazgul.tnic>
References: <1439326077-25507-1-git-send-email-lho@apm.com>
 <1439326077-25507-2-git-send-email-lho@apm.com>
 <1439326077-25507-3-git-send-email-lho@apm.com>
 <1439326077-25507-4-git-send-email-lho@apm.com>
 <20150812105121.GE14011@nazgul.tnic>
Message-ID: <CAPw-ZTkRytHUsUsDmTkfzzTYbcZnmTVRMkzNzg_9ZpdQH76rZw@mail.gmail.com>

Hi Borislav,

>> ---
>>  drivers/edac/xgene_edac.c |  827 ++++++++++++++++++++++++++++++++++++++++++++-
>>  1 files changed, 815 insertions(+), 12 deletions(-)
>>
>> diff --git a/drivers/edac/xgene_edac.c b/drivers/edac/xgene_edac.c
>> index ba06904..d5e33bf 100644
>> --- a/drivers/edac/xgene_edac.c
>> +++ b/drivers/edac/xgene_edac.c
>> @@ -66,6 +66,8 @@ struct xgene_edac {
>>
>>       struct list_head        mcus;
>>       struct list_head        pmds;
>> +     struct list_head        l3s;
>> +     struct list_head        socs;
>>
>>       struct mutex            mc_lock;
>>       int                     mc_active_mask;
>> @@ -877,8 +879,8 @@ static const struct file_operations xgene_edac_pmd_debug_inject_fops[] = {
>>       { }
>>  };
>>
>> -static void xgene_edac_pmd_create_debugfs_nodes(
>> -     struct edac_device_ctl_info *edac_dev)
>> +static void
>> +xgene_edac_pmd_create_debugfs_nodes(struct edac_device_ctl_info *edac_dev)
>>  {
>>       struct xgene_edac_pmd_ctx *ctx = edac_dev->pvt_info;
>>       struct dentry *edac_debugfs;
>> @@ -887,10 +889,6 @@ static void xgene_edac_pmd_create_debugfs_nodes(
>>       if (!IS_ENABLED(CONFIG_EDAC_DEBUG))
>>               return;
>>
>> -     /*
>> -      * Todo: Switch to common EDAC debug file system for edac device
>> -      *       when available.
>> -      */
>>       if (!ctx->edac->dfs) {
>>               ctx->edac->dfs = debugfs_create_dir(edac_dev->dev->kobj.name,
>>                                                   NULL);
>
> Why is this removing only the comment and not the debugfs_create_dir()
> and the rest of the gunk?

I intentional left this code as is so that the driver will still works
with older version of the EDAC code. Since you don't want this, I will
get rip of this.

>
> xgene_edac_l3_create_debugfs_nodes() does call debugfs_create_dir()
> creating a top-level edac debugfs node too. Why?

Each subnode will create an folder under the edac debug fs. It is no
different than the EDAC MC debug file system. You will see:

/sys/kernel/debug/edac/mc0, ..
/sys/kernel/debug/edac/mc2
/sys/kernel/debug/edac/pmd0, ...
/sys/kernel/debug/edac/pmd3
/sys/kernel/debug/edac/l3c4

>
> Please go through the previous comments I had and make sure you've
> incorporated them all. I'm not wasting time reviewing half-baked stuff.

As for your comments from previous v2 email:

>> +static void xgene_edac_l3_hw_init(struct edac_device_ctl_info *edac_dev,
>> +                               bool enable)
>
>arg alignment. It should be
>
>function name(arg1, arg2,
>              arg3, arg4,
>              arg5...
>
> Check your other functions too.

[Loc Ho]
I looked over the entire v3 driver and they are all aligned correct.

>> +static void xgene_edac_l3_create_debugfs_nodes(
>> +     struct edac_device_ctl_info *edac_dev)
>
>This "(" brace at the end looks ugly. Simply leave it on the same line,
>even if if it is longer than 80-cols.
>
>You can do:
>
>static void xgene_edac_l3_create_debugfs_nodes(struct edac_device_ctl_info *edac_dev)
>{
>
>or:
>
>static void
>xgene_edac_l3_create_debugfs_nodes(struct edac_device_ctl_info *edac_dev)
>{
>
>which is more readable.

[Loc Ho]
I looked over the entire v3 driver and they are all aligned correct.

>> +     /*
>> +      * Todo: Switch to common EDAC debug file system for edac device
>> +      *       when available.
>> +      */
>
>What is that?

[Loc Ho]
This one was change in v3.

>> +
>> +     if (edac_op_state == EDAC_OPSTATE_POLL)
>> +             edac_dev->edac_check = xgene_edac_l3_check;
>
>So depending on what SoC elements you detect, the last one's check
>function will win?
>
>If xgene_edac loads on multiple SoC elements, you need a global xgene
>check function for which l3, soc, mc, etc register...

[Loc Ho]
I already commented on this one. It is per subnode type.

>> +     dev_info(edac->dev, "X-Gene EDAC L3 registered\n");
>> +     return 0;
>> +
>> +err1:
>> +     edac_device_free_ctl_info(edac_dev);
>> +err:
>
>Those labels need to be better named.

[Loc Ho]
I looked over the entire v3 driver and they are with proper naming.

>> +             if (reg & (DED_ERR_MASK | MDED_ERR_MASK))
>> +                     edac_device_handle_ue(edac_dev, 0, 0,
>> +                                           edac_dev->ctl_name);
>> +     }
>
>You can flip the logic in that function:
>
>        if (!reg)
>
>and use goto labels and thus save an indentation level. Which looks like
>you could use it.

[Loc Ho]

I had already reversed the logic for the L3 and SoC. Are you asking
for the MC/PMD (earlier posting)? The MC/PMD routine isn't that big.
Functions in general fit in an screen of 80 column?

>> +static const char * const *xgene_edac_soc_mem_data(
>> +     struct xgene_edac_dev_ctx *ctx)
>> +{
>> +     switch (ctx->version) {
>> +     case 1:
>> +             return soc_mem_err_v1;
>> +     default:
>> +             return NULL;
>> +     }
>> +}
>
>That's one badly formatted function used only once. Just move the logic
>there and kill it.

[Loc Ho]
I already killed this function.

>> +     list_for_each_entry(node, &ctx->socs, next) {
>> +             xgene_edac_soc_check(node->edac_dev);
>> +     }
>
>Loops with single statements don't need {}

[Loc Ho]
I already got rip of un-necessary { }

So, is there something that I am missing?

-Loc


From eric at anholt.net  Wed Aug 12 10:56:58 2015
From: eric at anholt.net (Eric Anholt)
Date: Wed, 12 Aug 2015 10:56:58 -0700
Subject: [PATCH v4 1/8] clk: bcm2835: Add binding docs for the Raspberry
 Pi clock provider
In-Reply-To: <20150811211840.31346.28666@quantum>
References: <1437420787-32137-1-git-send-email-eric@anholt.net>
 <1437420787-32137-2-git-send-email-eric@anholt.net>
 <20150811211840.31346.28666@quantum>
Message-ID: <87zj1w4cgl.fsf@eliezer.anholt.net>

Michael Turquette <mturquette at linaro.org> writes:

> Quoting Eric Anholt (2015-07-20 12:33:00)
>> The hardware clocks are not controllable by the ARM, so we have to
>> make requests to the firmware to do so from the VPU side.  This will
>> let us replace fixed clocks in our DT with actual clock control (and
>> correct frequency information).
>> 
>> Signed-off-by: Eric Anholt <eric at anholt.net>
>> Acked-by: Stephen Warren <swarren at wwwdotorg.org>
>> Acked-by: Lee Jones <lee at kernel.org>
>
> Looks good to me. Do you want the clk patches to go through the clk tree
> or do you want them all together? For this patch feel free to add:
>
> Acked-by: Michael Turquette <mturquette at baylibre.com>

It would be nice to do them all together in the arm-soc tree, since the
later DT changes require that the clock driver be present.  (And, since
this is a dependency of the RPi2 work, it would let us stack that on
top, too).
-------------- next part --------------
A non-text attachment was scrubbed...
Name: signature.asc
Type: application/pgp-signature
Size: 818 bytes
Desc: not available
URL: <http://lists.infradead.org/pipermail/linux-arm-kernel/attachments/20150812/0d1a7c0d/attachment-0001.sig>

From eric at anholt.net  Wed Aug 12 11:04:05 2015
From: eric at anholt.net (Eric Anholt)
Date: Wed, 12 Aug 2015 11:04:05 -0700
Subject: [PATCH v4 2/8] clk: Add a Raspberry Pi-specific clock driver.
In-Reply-To: <20150811211733.31346.11122@quantum>
References: <1437420787-32137-1-git-send-email-eric@anholt.net>
 <1437420787-32137-3-git-send-email-eric@anholt.net>
 <20150811211733.31346.11122@quantum>
Message-ID: <87wpx04c4q.fsf@eliezer.anholt.net>

Michael Turquette <mturquette at linaro.org> writes:

> Hi Eric,
>
> Quoting Eric Anholt (2015-07-20 12:33:01)
>> +void __init rpi_firmware_init_clock_provider(struct device_node *node)
>> +{
>> +       /* We delay construction of our struct clks until get time,
>> +        * because we need to be able to return -EPROBE_DEFER if the
>> +        * firmware driver isn't up yet.  clk core doesn't support
>> +        * re-probing on -EPROBE_DEFER, but callers of clk_get can.
>> +        */
>> +       of_clk_add_provider(node, rpi_firmware_delayed_get_clk, node);
>> +}
>> +
>> +CLK_OF_DECLARE(rpi_firmware_clocks, "raspberrypi,bcm2835-firmware-clocks",
>> +              rpi_firmware_init_clock_provider);
>
> Do you require CLK_OF_DECLARE here? Could this be a platform driver
> instead?

I'm not actually sure.  The common pattern seemed to be using
CLK_OF_DECLARE (130 files using it versus declaring a struct
platform_driver), and it seems to avoid a whole lot of boilerplate.
What would the advantage be?
-------------- next part --------------
A non-text attachment was scrubbed...
Name: signature.asc
Type: application/pgp-signature
Size: 818 bytes
Desc: not available
URL: <http://lists.infradead.org/pipermail/linux-arm-kernel/attachments/20150812/82521ee8/attachment.sig>

From catalin.marinas at arm.com  Wed Aug 12 11:08:46 2015
From: catalin.marinas at arm.com (Catalin Marinas)
Date: Wed, 12 Aug 2015 19:08:46 +0100
Subject: [GIT PULL] arm64 fixes for 4.2
Message-ID: <20150812180844.GA32301@e104818-lin.cambridge.arm.com>

Hi Linus,

Please pull the arm64 fix below. Thanks.

The following changes since commit f7644cbfcdf03528f0f450f3940c4985b2291f49:

  Linux 4.2-rc6 (2015-08-09 15:54:30 -0400)

are available in the git repository at:

  git://git.kernel.org/pub/scm/linux/kernel/git/arm64/linux tags/arm64-fixes

for you to fetch changes up to 878854a374620a3f5e8c0a3c418e82a429bc2cff:

  arm64: VDSO: fix coarse clock monotonicity regression (2015-08-10 15:37:45 +0100)

----------------------------------------------------------------
Fix coarse clock monotonicity (VDSO timestamp off by one jiffy compared
to the syscall one).

----------------------------------------------------------------
Nathan Lynch (1):
      arm64: VDSO: fix coarse clock monotonicity regression

 arch/arm64/kernel/vdso.c | 7 +++----
 1 file changed, 3 insertions(+), 4 deletions(-)

-- 
Catalin



From grygorii.strashko at ti.com  Wed Aug 12 11:25:50 2015
From: grygorii.strashko at ti.com (Grygorii Strashko)
Date: Wed, 12 Aug 2015 21:25:50 +0300
Subject: [4.1.3-rt3] [report][suspend to ram] BUG: sleeping function called
 from invalid context at kernel/locking/rtmutex.c:917
Message-ID: <55CB8FAE.9020309@ti.com>

Hi All,

I can constantly see below error report with RT-kernel on TI ARM dra7-evm 
if I'm trying to do Suspend to RAM.

Sometimes, It's displayed alone (Log1) and sometimes in combination with 
"INFO: suspicious RCU usage" (Log2).
Below error was not reproduced on vanilla kernel (4.2-rc6).
I don't know if there are any relations, but on vanilla kernel (4.2-rc6)
i can see issue listed in log 3 (just in case).

I'm not familiar with affected code parts and would be appreciated for any comments.

===== LOG 1 =====
 Disabling non-boot CPUs ...
 PM: noirq suspend of devices complete after 7.295 msecs
[  100.285729] Disabling non-boot CPUs ...
[  100.287575] BUG: sleeping function called from invalid context at kernel/locking/rtmutex.c:917
[  100.287580] in_atomic(): 1, irqs_disabled(): 128, pid: 18, name: migration/1
[  100.287583] INFO: lockdep is turned off.
[  100.287586] irq event stamp: 122
[  100.287600] hardirqs last  enabled at (121): [<c06ac0ac>] _raw_spin_unlock_irqrestore+0x88/0x90
[  100.287609] hardirqs last disabled at (122): [<c06abed0>] _raw_spin_lock_irq+0x28/0x5c
[  100.287620] softirqs last  enabled at (0): [<c003d294>] copy_process.part.52+0x410/0x19d8
[  100.287625] softirqs last disabled at (0): [<  (null)>]   (null)
[  100.287630] Preemption disabled at:[<  (null)>]   (null)
[  100.287631] 
[  100.287639] CPU: 1 PID: 18 Comm: migration/1 Tainted: G        W       4.1.4-rt3-01046-g96ac8da #204
[  100.287642] Hardware name: Generic DRA74X (Flattened Device Tree)
[  100.287659] [<c0019134>] (unwind_backtrace) from [<c0014774>] (show_stack+0x20/0x24)
[  100.287671] [<c0014774>] (show_stack) from [<c06a70f4>] (dump_stack+0x88/0xdc)
[  100.287681] [<c06a70f4>] (dump_stack) from [<c006cab8>] (___might_sleep+0x198/0x2a8)
[  100.287689] [<c006cab8>] (___might_sleep) from [<c06ac4dc>] (rt_spin_lock+0x30/0x70)
[  100.287699] [<c06ac4dc>] (rt_spin_lock) from [<c013f790>] (find_lock_task_mm+0x9c/0x174)
[  100.287710] [<c013f790>] (find_lock_task_mm) from [<c00409ac>] (clear_tasks_mm_cpumask+0xb4/0x1ac)
[  100.287720] [<c00409ac>] (clear_tasks_mm_cpumask) from [<c00166a4>] (__cpu_disable+0x98/0xbc)
[  100.287728] [<c00166a4>] (__cpu_disable) from [<c06a2e8c>] (take_cpu_down+0x1c/0x50)
[  100.287742] [<c06a2e8c>] (take_cpu_down) from [<c00f2600>] (multi_cpu_stop+0x11c/0x158)
[  100.287754] [<c00f2600>] (multi_cpu_stop) from [<c00f2a9c>] (cpu_stopper_thread+0xc4/0x184)
[  100.287767] [<c00f2a9c>] (cpu_stopper_thread) from [<c0069058>] (smpboot_thread_fn+0x18c/0x324)
[  100.287779] [<c0069058>] (smpboot_thread_fn) from [<c00649c4>] (kthread+0xe8/0x104)
[  100.287791] [<c00649c4>] (kthread) from [<c0010058>] (ret_from_fork+0x14/0x3c)
[  100.288114] CPU1: shutdown
[  100.317696] PM: Calling sched_clock_suspend+0x0/0x40
[  100.317698] PM: Calling timekeeping_suspend+0x0/0x2e0
[  100.317698] PM: Calling irq_gc_suspend+0x0/0x68
[  100.317698] PM: Calling fw_suspend+0x0/0x2c
[  100.317698] PM: Calling cpu_pm_suspend+0x0/0x28

==== LOG 2 ====
[  156.125122] PM: noirq suspend of devices complete after 16.499 msecs
[  156.125250] Disabling non-boot CPUs ...
[  156.153626] NOHZ: local_softirq_pending 02
[  156.154939] BUG: sleeping function called from invalid context at kernel/locking/rtmutex.c:917
[  156.154943] in_atomic(): 1, irissueqs_disabled(): 128, pid: 18, name: migration/1
[  156.154948] 2 locks held by migration/1/18:
[  156.154974]  #0:  (rcu_read_lock){......}, at: [<c004093c>] clear_tasks_mm_cpumask+0x44/0x1ac
[  156.154992]  #1:  (rcu_read_lock){......}, at: [<c013f6f4>] find_lock_task_mm+0x0/0x174
[  156.154995] irq event stamp: 126
[  156.155005] hardirqs last  enabled at (125): [<c06ac0e8>] _raw_spin_unlock_irq+0x34/0x78
[  156.155016] hardirqs last disabled at (126): [<c00f25d8>] multi_cpu_stop+0xf4/0x158
[  156.155025] softirqs last  enabled at (0): [<c003d294>] copy_process.part.52+0x410/0x19d8
[  156.155031] softirqs last disabled at (0): [<  (null)>]   (null)
[  156.155036] Preemption disabled at:[<  (null)>]   (null)
[  156.155038] 
[  156.155046] CPU: 1 PID: 18 Comm: migration/1 Tainted: G        W       4.1.4-rt3-01046-g96ac8da #204
[  156.155049] Hardware name: Generic DRA74X (Flattened Device Tree)
[  156.155062] [<c0019134>] (unwind_backtrace) from [<c0014774>] (show_stack+0x20/0x24)
[  156.155074] [<c0014774>] (show_stack) from [<c06a70f4>] (dump_stack+0x88/0xdc)
[  156.155084] [<c06a70f4>] (dump_stack) from [<c006cab8>] (___might_sleep+0x198/0x2a8)
[  156.155091] [<c006cab8>] (___might_sleep) from [<c06ac4dc>] (rt_spin_lock+0x30/0x70)
[  156.155099] [<c06ac4dc>] (rt_spin_lock) from [<c013f790>] (find_lock_task_mm+0x9c/0x174)
[  156.155109] [<c013f790>] (find_lock_task_mm) from [<c00409ac>] (clear_tasks_mm_cpumask+0xb4/0x1ac)
[  156.155118] [<c00409ac>] (clear_tasks_mm_cpumask) from [<c00166a4>] (__cpu_disable+0x98/0xbc)
[  156.155126] [<c00166a4>] (__cpu_disable) from [<c06a2e8c>] (take_cpu_down+0x1c/0x50)
[  156.155136] [<c06a2e8c>] (take_cpu_down) from [<c00f2600>] (multi_cpu_stop+0x11c/0x158)
[  156.155147] [<c00f2600>] (multi_cpu_stop) from [<c00f2a9c>] (cpu_stopper_thread+0xc4/0x184)
[  156.155158] [<c00f2a9c>] (cpu_stopper_thread) from [<c0069058>] (smpboot_thread_fn+0x18c/0x324)
[  156.155170] [<c0069058>] (smpboot_thread_fn) from [<c00649c4>] (kthread+0xe8/0x104)
[  156.155181] [<c00649c4>] (kthread) from [<c0010058>] (ret_from_fork+0x14/0x3c)
[  156.156643] 
[  156.156646] ===============================
[  156.156648] [ INFO: suspicious RCU usage. ]
[  156.156653] 4.1.4-rt3-01046-g96ac8da #204 Tainted: G        W      
[  156.156655] -------------------------------
[  156.156660] include/trace/events/power.h:297 suspicious rcu_dereference_check() usage!
[  156.156662] 
[  156.156662] other info that might help us debug this:
[  156.156662] 
[  156.156666] 
[  156.156666] RCU used illegally from offline CPU!
[  156.156666] rcu_scheduler_active = 1, debug_locks = 0
[  156.156670] no locks held by swapper/1/0.
[  156.156671] 
[  156.156671] stack backtrace:
[  156.156678] CPU: 1 PID: 0 Comm: swapper/1 Tainted: G        W       4.1.4-rt3-01046-g96ac8da #204
[  156.156681] Hardware name: Generic DRA74X (Flattened Device Tree)
[  156.156692] [<c0019134>] (unwind_backtrace) from [<c0014774>] (show_stack+0x20/0x24)
[  156.156702] [<c0014774>] (show_stack) from [<c06a70f4>] (dump_stack+0x88/0xdc)
[  156.156715] [<c06a70f4>] (dump_stack) from [<c0091258>] (lockdep_rcu_suspicious+0xbc/0x11c)
[  156.156728] [<c0091258>] (lockdep_rcu_suspicious) from [<c00334d0>] (pwrdm_set_next_pwrst+0x134/0x2ec)
[  156.156740] [<c00334d0>] (pwrdm_set_next_pwrst) from [<c002f8ac>] (omap4_hotplug_cpu+0x68/0xd4)
[  156.156751] [<c002f8ac>] (omap4_hotplug_cpu) from [<c06a2d48>] (omap4_cpu_die+0x54/0x9c)
[  156.156759] [<c06a2d48>] (omap4_cpu_die) from [<c06a2cac>] (cpu_die+0x5c/0xa4)
[  156.156769] [<c06a2cac>] (cpu_die) from [<c0010bdc>] (arch_cpu_idle_dead+0x18/0x1c)
[  156.156780] [<c0010bdc>] (arch_cpu_idle_dead) from [<c008d7d4>] (cpu_startup_entry+0x22c/0x4f0)
[  156.156789] [<c008d7d4>] (cpu_startup_entry) from [<c001688c>] (secondary_start_kernel+0x130/0x14c)
[  156.156792] CPU1: shutdown
[  156.156799] [<c001688c>] (secondary_start_kernel) from [<8000970c>] (0x8000970c)
[  156.186995] PM: Calling sched_clock_suspend+0x0/0x40
[  156.186997] PM: Calling timekeeping_suspend+0x0/0x2e0
[  156.186997] PM: Calling irq_gc_suspend+0x0/0x68
[  156.186997] PM: Calling fw_suspend+0x0/0x2c
[  156.186997] PM: Calling cpu_pm_suspend+0x0/0x28

===== LOG 3 =====
[    8.099469] PM: suspend of devices complete after 7.968 msecs
[    8.103121] PM: late suspend of devices complete after 3.642 msecs
[    8.114611] PM: noirq suspend of devices complete after 11.481 msecs
[    8.114670] Disabling non-boot CPUs ...
[    8.119535] 
[    8.119538] ===============================
[    8.119540] [ INFO: suspicious RCU usage. ]
[    8.119545] 4.2.0-rc6-00011-g4a7ab45-dirty #50 Not tainted
[    8.119548] -------------------------------
[    8.119552] kernel/sched/fair.c:5032 suspicious rcu_dereference_check() usage!
[    8.119554] 
[    8.119554] other info that might help us debug this:
[    8.119554] 
[    8.119558] 
[    8.119558] RCU used illegally from offline CPU!
[    8.119558] rcu_scheduler_active = 1, debug_locks = 0
[    8.119562] 3 locks held by swapper/1/0:
[    8.119585]  #0:  ((cpu_died).wait.lock){......}, at: [<c00837a4>] complete+0x14/0x44
[    8.119606]  #1:  (&p->pi_lock){-.-.-.}, at: [<c006ab00>] try_to_wake_up+0x2c/0x410
[    8.119622]  #2:  (rcu_read_lock){......}, at: [<c0072c84>] select_task_rq_fair+0x60/0xae0
[    8.119625] 
[    8.119625] stack backtrace:
[    8.119631] CPU: 1 PID: 0 Comm: swapper/1 Not tainted 4.2.0-rc6-00011-g4a7ab45-dirty #50
[    8.119634] Hardware name: Generic DRA74X (Flattened Device Tree)
[    8.119646] [<c0016e24>] (unwind_backtrace) from [<c0013338>] (show_stack+0x10/0x14)
[    8.119656] [<c0013338>] (show_stack) from [<c05f6b2c>] (dump_stack+0x84/0x9c)
[    8.119665] [<c05f6b2c>] (dump_stack) from [<c0073338>] (select_task_rq_fair+0x714/0xae0)
[    8.119675] [<c0073338>] (select_task_rq_fair) from [<c006abf0>] (try_to_wake_up+0x11c/0x410)
[    8.119684] [<c006abf0>] (try_to_wake_up) from [<c0082fe8>] (__wake_up_common+0x4c/0x80)
[    8.119690] [<c0082fe8>] (__wake_up_common) from [<c0083030>] (__wake_up_locked+0x14/0x1c)
[    8.119697] [<c0083030>] (__wake_up_locked) from [<c00837c4>] (complete+0x34/0x44)
[    8.119705] [<c00837c4>] (complete) from [<c05f2d34>] (cpu_die+0x34/0x9c)
[    8.119713] [<c05f2d34>] (cpu_die) from [<c0083be0>] (cpu_startup_entry+0x204/0x314)
[    8.119720] [<c0083be0>] (cpu_startup_entry) from [<800095ac>] (0x800095ac)
[    8.119748] CPU1: shutdown

-- 
regards,
-grygorii


From eric at anholt.net  Wed Aug 12 11:45:13 2015
From: eric at anholt.net (Eric Anholt)
Date: Wed, 12 Aug 2015 11:45:13 -0700
Subject: [GIT PULL] RPi SOC changes for v4.3
Message-ID: <87oaic8hxi.fsf@eliezer.anholt.net>

Following Lee's forwarding of the DT changes for the firmware driver for
4.3, here's the associated driver for the brcm arm-soc tree.

I think this is the first time RPi changes have been forwarded through
Florian.  It was suggested by Florian when I was discussing RPi
upstreaming with him and Arnd.  I think it makes sense, since general
-next trees for Broadcom are maintained there, and he's willing to
accept pull requests at any point.

The following changes since commit d770e558e21961ad6cfdf0ff7df0eb5d7d4f0754:

  Linux 4.2-rc1 (2015-07-05 11:01:52 -0700)

are available in the git repository at:

  http://github.com/anholt/linux tags/rpi-soc-for-4.3-v1

for you to fetch changes up to d39ae82e65dc538295eea0384ed1ad8752dabbae:

  ARM: bcm2835: Add the Raspberry Pi firmware driver (2015-08-11 11:27:13 -0700)

----------------------------------------------------------------
This pull request contains the Raspberry Pi firmware driver, for
communicating with the VPU which has exclusive control of some of the
peripherals.

----------------------------------------------------------------
Eric Anholt (1):
      ARM: bcm2835: Add the Raspberry Pi firmware driver

 drivers/firmware/Kconfig                   |   7 +
 drivers/firmware/Makefile                  |   1 +
 drivers/firmware/raspberrypi.c             | 260 +++++++++++++++++++++++++++++
 include/soc/bcm2835/raspberrypi-firmware.h | 115 +++++++++++++
 4 files changed, 383 insertions(+)
 create mode 100644 drivers/firmware/raspberrypi.c
 create mode 100644 include/soc/bcm2835/raspberrypi-firmware.h
-------------- next part --------------
A non-text attachment was scrubbed...
Name: signature.asc
Type: application/pgp-signature
Size: 818 bytes
Desc: not available
URL: <http://lists.infradead.org/pipermail/linux-arm-kernel/attachments/20150812/b876ccd9/attachment.sig>

From alex.williamson at redhat.com  Wed Aug 12 11:56:10 2015
From: alex.williamson at redhat.com (Alex Williamson)
Date: Wed, 12 Aug 2015 12:56:10 -0600
Subject: [PATCH v3 01/10] VFIO: platform: registration of a dummy IRQ
 bypass producer
In-Reply-To: <1439212864-12954-2-git-send-email-eric.auger@linaro.org>
References: <1439212864-12954-1-git-send-email-eric.auger@linaro.org>
 <1439212864-12954-2-git-send-email-eric.auger@linaro.org>
Message-ID: <1439405770.4023.526.camel@redhat.com>

On Mon, 2015-08-10 at 15:20 +0200, Eric Auger wrote:
> Register a dummy producer with void callbacks
> 
> Signed-off-by: Eric Auger <eric.auger at linaro.org>
> 
> ---
> 
> v2 -> v3:
> - rename vfio_platform_irq_bypass_resume into *_start
> ---
>  drivers/vfio/platform/vfio_platform_irq.c     | 32 +++++++++++++++++++++++++++
>  drivers/vfio/platform/vfio_platform_private.h |  2 ++
>  2 files changed, 34 insertions(+)
> 
> diff --git a/drivers/vfio/platform/vfio_platform_irq.c b/drivers/vfio/platform/vfio_platform_irq.c
> index 88bba57..b5cb8c7 100644
> --- a/drivers/vfio/platform/vfio_platform_irq.c
> +++ b/drivers/vfio/platform/vfio_platform_irq.c
> @@ -20,6 +20,7 @@
>  #include <linux/types.h>
>  #include <linux/vfio.h>
>  #include <linux/irq.h>
> +#include <linux/irqbypass.h>
>  
>  #include "vfio_platform_private.h"
>  
> @@ -177,6 +178,27 @@ static irqreturn_t vfio_irq_handler(int irq, void *dev_id)
>  	return IRQ_HANDLED;
>  }
>  
> +static void vfio_platform_irq_bypass_stop(struct irq_bypass_producer *prod)
> +{
> +}
> +
> +static void vfio_platform_irq_bypass_start(struct irq_bypass_producer *prod)
> +{
> +}
> +
> +static int vfio_platform_irq_bypass_add_consumer(
> +			struct irq_bypass_producer *prod,
> +			struct irq_bypass_consumer *cons)
> +{
> +	return 0;
> +}
> +
> +static void vfio_platform_irq_bypass_del_consumer(
> +			struct irq_bypass_producer *prod,
> +			struct irq_bypass_consumer *cons)
> +{
> +}
> +
>  static int vfio_set_trigger(struct vfio_platform_device *vdev, int index,
>  			    int fd, irq_handler_t handler)
>  {
> @@ -186,6 +208,7 @@ static int vfio_set_trigger(struct vfio_platform_device *vdev, int index,
>  
>  	if (irq->trigger) {
>  		free_irq(irq->hwirq, irq);
> +		irq_bypass_unregister_producer(&irq->producer);
>  		kfree(irq->name);
>  		eventfd_ctx_put(irq->trigger);
>  		irq->trigger = NULL;
> @@ -216,6 +239,15 @@ static int vfio_set_trigger(struct vfio_platform_device *vdev, int index,
>  		return ret;
>  	}
>  
> +	irq->producer.token = (void *)trigger;
> +	irq->producer.irq = irq->hwirq;
> +	irq->producer.add_consumer = vfio_platform_irq_bypass_add_consumer;
> +	irq->producer.del_consumer = vfio_platform_irq_bypass_del_consumer;
> +	irq->producer.stop = vfio_platform_irq_bypass_stop;
> +	irq->producer.start = vfio_platform_irq_bypass_start;
> +	ret = irq_bypass_register_producer(&irq->producer);
> +	WARN_ON(ret);

For what purpose?

> +
>  	if (!irq->masked)
>  		enable_irq(irq->hwirq);
>  
> diff --git a/drivers/vfio/platform/vfio_platform_private.h b/drivers/vfio/platform/vfio_platform_private.h
> index 1c9b3d5..1d2d4d6 100644
> --- a/drivers/vfio/platform/vfio_platform_private.h
> +++ b/drivers/vfio/platform/vfio_platform_private.h
> @@ -17,6 +17,7 @@
>  
>  #include <linux/types.h>
>  #include <linux/interrupt.h>
> +#include <linux/irqbypass.h>
>  
>  #define VFIO_PLATFORM_OFFSET_SHIFT   40
>  #define VFIO_PLATFORM_OFFSET_MASK (((u64)(1) << VFIO_PLATFORM_OFFSET_SHIFT) - 1)
> @@ -37,6 +38,7 @@ struct vfio_platform_irq {
>  	spinlock_t		lock;
>  	struct virqfd		*unmask;
>  	struct virqfd		*mask;
> +	struct irq_bypass_producer producer;
>  };
>  
>  struct vfio_platform_region {





From alex.williamson at redhat.com  Wed Aug 12 11:56:20 2015
From: alex.williamson at redhat.com (Alex Williamson)
Date: Wed, 12 Aug 2015 12:56:20 -0600
Subject: [PATCH v3 03/10] VFIO: platform: single handler using function
 pointer
In-Reply-To: <1439212864-12954-4-git-send-email-eric.auger@linaro.org>
References: <1439212864-12954-1-git-send-email-eric.auger@linaro.org>
 <1439212864-12954-4-git-send-email-eric.auger@linaro.org>
Message-ID: <1439405780.4023.527.camel@redhat.com>

On Mon, 2015-08-10 at 15:20 +0200, Eric Auger wrote:
> A single handler now is registered whatever the use case: automasked
> or not. A function pointer is set according to the wished behavior
> and the handler calls this function.
> 
> The irq lock is taken/released in the root handler. eventfd_signal can
> be called in regions not allowed to sleep.
> 
> Signed-off-by: Eric Auger <eric.auger at linaro.org>
> 
> ---
> 
> v4: creation
> ---
>  drivers/vfio/platform/vfio_platform_irq.c     | 21 +++++++++++++++------
>  drivers/vfio/platform/vfio_platform_private.h |  1 +
>  2 files changed, 16 insertions(+), 6 deletions(-)
> 
> diff --git a/drivers/vfio/platform/vfio_platform_irq.c b/drivers/vfio/platform/vfio_platform_irq.c
> index 40f057a..b31b1f0 100644
> --- a/drivers/vfio/platform/vfio_platform_irq.c
> +++ b/drivers/vfio/platform/vfio_platform_irq.c
> @@ -148,11 +148,8 @@ static int vfio_platform_set_irq_unmask(struct vfio_platform_device *vdev,
>  static irqreturn_t vfio_automasked_irq_handler(int irq, void *dev_id)
>  {
>  	struct vfio_platform_irq *irq_ctx = dev_id;
> -	unsigned long flags;
>  	int ret = IRQ_NONE;
>  
> -	spin_lock_irqsave(&irq_ctx->lock, flags);
> -
>  	if (!irq_ctx->masked) {
>  		ret = IRQ_HANDLED;
>  
> @@ -161,8 +158,6 @@ static irqreturn_t vfio_automasked_irq_handler(int irq, void *dev_id)
>  		irq_ctx->masked = true;
>  	}
>  
> -	spin_unlock_irqrestore(&irq_ctx->lock, flags);
> -
>  	if (ret == IRQ_HANDLED)
>  		eventfd_signal(irq_ctx->trigger, 1);

Has this been run with lockdep to check whether this is safe to call
with spinlock_irqsave held?

>  
> @@ -178,6 +173,19 @@ static irqreturn_t vfio_irq_handler(int irq, void *dev_id)
>  	return IRQ_HANDLED;
>  }
>  
> +static irqreturn_t vfio_handler(int irq, void *dev_id)
> +{
> +	struct vfio_platform_irq *irq_ctx = dev_id;
> +	unsigned long flags;
> +	irqreturn_t ret;
> +
> +	spin_lock_irqsave(&irq_ctx->lock, flags);
> +	ret = irq_ctx->handler(irq, dev_id);
> +	spin_unlock_irqrestore(&irq_ctx->lock, flags);
> +
> +	return ret;
> +}
> +
>  static void vfio_platform_irq_bypass_stop(struct irq_bypass_producer *prod)
>  {
>  }
> @@ -229,9 +237,10 @@ static int vfio_set_trigger(struct vfio_platform_device *vdev, int index,
>  	}
>  
>  	irq->trigger = trigger;
> +	irq->handler = handler;
>  
>  	irq_set_status_flags(irq->hwirq, IRQ_NOAUTOEN);
> -	ret = request_irq(irq->hwirq, handler, 0, irq->name, irq);
> +	ret = request_irq(irq->hwirq, vfio_handler, 0, irq->name, irq);
>  	if (ret) {
>  		kfree(irq->name);
>  		eventfd_ctx_put(trigger);
> diff --git a/drivers/vfio/platform/vfio_platform_private.h b/drivers/vfio/platform/vfio_platform_private.h
> index 8b4f814..f848a6b 100644
> --- a/drivers/vfio/platform/vfio_platform_private.h
> +++ b/drivers/vfio/platform/vfio_platform_private.h
> @@ -40,6 +40,7 @@ struct vfio_platform_irq {
>  	struct virqfd		*mask;
>  	struct irq_bypass_producer producer;
>  	bool			forwarded;
> +	irqreturn_t (*handler)(int irq, void *dev_id);
>  };
>  
>  struct vfio_platform_region {





From alex.williamson at redhat.com  Wed Aug 12 11:56:34 2015
From: alex.williamson at redhat.com (Alex Williamson)
Date: Wed, 12 Aug 2015 12:56:34 -0600
Subject: [PATCH v3 04/10] VFIO: platform: add vfio_platform_set_automasked
In-Reply-To: <1439212864-12954-5-git-send-email-eric.auger@linaro.org>
References: <1439212864-12954-1-git-send-email-eric.auger@linaro.org>
 <1439212864-12954-5-git-send-email-eric.auger@linaro.org>
Message-ID: <1439405794.4023.528.camel@redhat.com>

On Mon, 2015-08-10 at 15:20 +0200, Eric Auger wrote:
> This function makes possible to change the automasked mode.
> 
> Signed-off-by: Eric Auger <eric.auger at linaro.org>
> 
> ---
> 
> v1 -> v2:
> - set forwarded flag
> ---
>  drivers/vfio/platform/vfio_platform_irq.c | 19 +++++++++++++++++++
>  1 file changed, 19 insertions(+)
> 
> diff --git a/drivers/vfio/platform/vfio_platform_irq.c b/drivers/vfio/platform/vfio_platform_irq.c
> index b31b1f0..a285384 100644
> --- a/drivers/vfio/platform/vfio_platform_irq.c
> +++ b/drivers/vfio/platform/vfio_platform_irq.c
> @@ -186,6 +186,25 @@ static irqreturn_t vfio_handler(int irq, void *dev_id)
>  	return ret;
>  }
>  
> +static int vfio_platform_set_automasked(struct vfio_platform_irq *irq,
> +					   bool automasked)
> +{
> +	unsigned long flags;
> +
> +	spin_lock_irqsave(&irq->lock, flags);
> +	if (automasked) {
> +		irq->forwarded = true;
> +		irq->flags |= VFIO_IRQ_INFO_AUTOMASKED;
> +		irq->handler = vfio_automasked_irq_handler;
> +	} else {
> +		irq->forwarded = false;
> +		irq->flags &= ~VFIO_IRQ_INFO_AUTOMASKED;
> +		irq->handler = vfio_irq_handler;
> +	}
> +	spin_unlock_irqrestore(&irq->lock, flags);
> +	return 0;

In vfio-speak, automasked means level and we're not magically changing
the IRQ from level to edge, we're simply able to handle level
differently based on a hardware optimization.  Should the user visible
flags therefore change based on this?  Aren't we really setting the
forwarded state rather than the automasked state?

> +}
> +
>  static void vfio_platform_irq_bypass_stop(struct irq_bypass_producer *prod)
>  {
>  }





From alex.williamson at redhat.com  Wed Aug 12 11:56:45 2015
From: alex.williamson at redhat.com (Alex Williamson)
Date: Wed, 12 Aug 2015 12:56:45 -0600
Subject: [PATCH v3 05/10] VFIO: platform: add vfio_platform_is_active
In-Reply-To: <1439212864-12954-6-git-send-email-eric.auger@linaro.org>
References: <1439212864-12954-1-git-send-email-eric.auger@linaro.org>
 <1439212864-12954-6-git-send-email-eric.auger@linaro.org>
Message-ID: <1439405805.4023.529.camel@redhat.com>

On Mon, 2015-08-10 at 15:20 +0200, Eric Auger wrote:
> This function returns whether the IRQ is active at irqchip level or
> VFIO masked. If either is true, it is considered the IRQ is active.
> Currently there is no way to differentiate userspace masked IRQ from
> automasked IRQ. There might be false detection of activity. However
> it is currently acceptable to have false detection.
> 
> Signed-off-by: Eric Auger <eric.auger at linaro.org>
> 
> ---
> ---
>  drivers/vfio/platform/vfio_platform_irq.c | 17 +++++++++++++++++
>  1 file changed, 17 insertions(+)
> 
> diff --git a/drivers/vfio/platform/vfio_platform_irq.c b/drivers/vfio/platform/vfio_platform_irq.c
> index a285384..efaee58 100644
> --- a/drivers/vfio/platform/vfio_platform_irq.c
> +++ b/drivers/vfio/platform/vfio_platform_irq.c
> @@ -205,6 +205,23 @@ static int vfio_platform_set_automasked(struct vfio_platform_irq *irq,
>  	return 0;
>  }
>  
> +static int vfio_platform_is_active(struct vfio_platform_irq *irq)

vfio_platform_irq_is_active()?

> +{
> +	unsigned long flags;
> +	bool active, masked, outstanding;
> +	int ret;
> +
> +	spin_lock_irqsave(&irq->lock, flags);
> +
> +	ret = irq_get_irqchip_state(irq->hwirq, IRQCHIP_STATE_ACTIVE, &active);
> +	BUG_ON(ret);

Why can't we propagate this error to the caller and let them decide?

> +	masked = irq->masked;
> +	outstanding = active || masked;
> +
> +	spin_unlock_irqrestore(&irq->lock, flags);
> +	return outstanding;
> +}
> +
>  static void vfio_platform_irq_bypass_stop(struct irq_bypass_producer *prod)
>  {
>  }





From alex.williamson at redhat.com  Wed Aug 12 11:56:52 2015
From: alex.williamson at redhat.com (Alex Williamson)
Date: Wed, 12 Aug 2015 12:56:52 -0600
Subject: [PATCH v3 06/10] VFIO: platform: add irq bypass producer
 management
In-Reply-To: <1439212864-12954-7-git-send-email-eric.auger@linaro.org>
References: <1439212864-12954-1-git-send-email-eric.auger@linaro.org>
 <1439212864-12954-7-git-send-email-eric.auger@linaro.org>
Message-ID: <1439405812.4023.530.camel@redhat.com>

On Mon, 2015-08-10 at 15:21 +0200, Eric Auger wrote:
> This patch populates the IRQ bypass callacks:
> - stop/start producer simply consist in disabling/enabling the host irq
> - add/del consumer: basically set the automasked flag to false/true
> 
> Signed-off-by: Eric Auger <eric.auger at linaro.org>
> 
> ---
> v2 -> v3:
> - vfio_platform_irq_bypass_add_consumer now returns an error in case
>   the IRQ is recognized as active
> - active boolean not set anymore
> - do not VFIO mask the IRQ anymore on unforward
> 
> v1 -> v2:
> - device handle caching in vfio_platform_device is introduced in a
>   separate patch
> - use container_of
> ---
>  drivers/vfio/platform/vfio_platform_irq.c | 23 ++++++++++++++++++++++-
>  1 file changed, 22 insertions(+), 1 deletion(-)
> 
> diff --git a/drivers/vfio/platform/vfio_platform_irq.c b/drivers/vfio/platform/vfio_platform_irq.c
> index efaee58..400a188 100644
> --- a/drivers/vfio/platform/vfio_platform_irq.c
> +++ b/drivers/vfio/platform/vfio_platform_irq.c
> @@ -224,23 +224,44 @@ static int vfio_platform_is_active(struct vfio_platform_irq *irq)
>  
>  static void vfio_platform_irq_bypass_stop(struct irq_bypass_producer *prod)
>  {
> +	disable_irq(prod->irq);
>  }
>  
>  static void vfio_platform_irq_bypass_start(struct irq_bypass_producer *prod)
>  {
> +	enable_irq(prod->irq);
>  }
>  
>  static int vfio_platform_irq_bypass_add_consumer(
>  			struct irq_bypass_producer *prod,
>  			struct irq_bypass_consumer *cons)
>  {
> -	return 0;
> +	struct vfio_platform_irq *irq =
> +		container_of(prod, struct vfio_platform_irq, producer);
> +
> +	/*
> +	 * if the IRQ is active at irqchip level or VFIO (auto)masked
> +	 * this means the host IRQ is already under injection in the
> +	 * guest and this not safe to change the forwarding state at
> +	 * that stage.
> +	 * It is not possible to differentiate user-space masking
> +	 * from auto-masking, leading to possible false detection of
> +	 * active state.
> +	 */
> +	if (vfio_platform_is_active(irq))
> +		return -EAGAIN;

Here's an example of why we don't want WARN_ON if a registration fails,
this is effectively random.  When and how is a re-try going to happen?

> +
> +	return vfio_platform_set_automasked(irq, false);

set_forwarded just seems so much more logical here.

>  }
>  
>  static void vfio_platform_irq_bypass_del_consumer(
>  			struct irq_bypass_producer *prod,
>  			struct irq_bypass_consumer *cons)
>  {
> +	struct vfio_platform_irq *irq =
> +		container_of(prod, struct vfio_platform_irq, producer);
> +
> +	vfio_platform_set_automasked(irq, true);
>  }
>  
>  static int vfio_set_trigger(struct vfio_platform_device *vdev, int index,





From mturquette at baylibre.com  Wed Aug 12 12:00:14 2015
From: mturquette at baylibre.com (Michael Turquette)
Date: Wed, 12 Aug 2015 12:00:14 -0700
Subject: [PATCH v4 2/8] clk: Add a Raspberry Pi-specific clock driver.
In-Reply-To: <87wpx04c4q.fsf@eliezer.anholt.net>
References: <1437420787-32137-1-git-send-email-eric@anholt.net>
 <1437420787-32137-3-git-send-email-eric@anholt.net>
 <20150811211733.31346.11122@quantum> <87wpx04c4q.fsf@eliezer.anholt.net>
Message-ID: <20150812190014.31346.89987@quantum>

Quoting Eric Anholt (2015-08-12 11:04:05)
> Michael Turquette <mturquette at linaro.org> writes:
> 
> > Hi Eric,
> >
> > Quoting Eric Anholt (2015-07-20 12:33:01)
> >> +void __init rpi_firmware_init_clock_provider(struct device_node *node)
> >> +{
> >> +       /* We delay construction of our struct clks until get time,
> >> +        * because we need to be able to return -EPROBE_DEFER if the
> >> +        * firmware driver isn't up yet.  clk core doesn't support
> >> +        * re-probing on -EPROBE_DEFER, but callers of clk_get can.
> >> +        */
> >> +       of_clk_add_provider(node, rpi_firmware_delayed_get_clk, node);
> >> +}
> >> +
> >> +CLK_OF_DECLARE(rpi_firmware_clocks, "raspberrypi,bcm2835-firmware-clocks",
> >> +              rpi_firmware_init_clock_provider);
> >
> > Do you require CLK_OF_DECLARE here? Could this be a platform driver
> > instead?
> 
> I'm not actually sure.  The common pattern seemed to be using
> CLK_OF_DECLARE (130 files using it versus declaring a struct
> platform_driver), and it seems to avoid a whole lot of boilerplate.
> What would the advantage be?

Correctly using the Linux driver model, having a nice struct device and
things like supsend and resume handlers, etc.

There is a lot of CLK_OF_DECLARE going on in drivers/clk, but I am
hoping we can fix that. The main reason for CLK_OF_DECLARE is when you
need to register clocks very early (e.g. timers). This is often not the
case.

Regards,
Mike


From lina.iyer at linaro.org  Wed Aug 12 12:00:23 2015
From: lina.iyer at linaro.org (Lina Iyer)
Date: Wed, 12 Aug 2015 13:00:23 -0600
Subject: [PATCH v2 1/2] ARM: common: Introduce PM domains for CPUs/clusters
In-Reply-To: <CAL_JsqLhHy5gO=usm1HLf8h6iz_5FguCDo-Qz2Km+XEwaCODUA@mail.gmail.com>
References: <CAL_JsqLhHy5gO=usm1HLf8h6iz_5FguCDo-Qz2Km+XEwaCODUA@mail.gmail.com>
Message-ID: <1439406024-41893-1-git-send-email-lina.iyer@linaro.org>

Define and add Generic PM domains (genpd) for CPU clusters. Many new
SoCs group CPUs as clusters. Clusters share common resources like GIC,
power rail, caches, VFP, Coresight etc. When all CPUs in the cluster are
idle, these shared resources may also be put in their idle state.

The idle time between the last CPU entering idle and a CPU resuming
execution is an opportunity for these shared resources to be powered
down. Generic PM domain provides a framework for defining such power
domains and attach devices to the domain. When the devices in the domain
are idle at runtime, the domain would also be suspended and resumed
before the first of the devices resume execution.

We define a generic PM domain for each cluster and attach CPU devices in
the cluster to that PM domain. The DT definitions for the SoC describe
this relationship. Genpd callbacks for power_on and power_off can then
be used to power up/down the shared resources for the domain.

Cc: Stephen Boyd <sboyd at codeaurora.org>
Cc: Kevin Hilman <khilman at linaro.org>
Cc: Ulf Hansson <ulf.hansson at linaro.org>
Cc: Catalin Marinas <catalin.marinas at arm.com>
Cc: Daniel Lezcano <daniel.lezcano at linaro.org>
Cc: Mark Rutland <mark.rutland at arm.com>
Cc: Lorenzo Pieralisi <lorenzo.pieralisi at arm.com>
Signed-off-by: Kevin Hilman <khilman at linaro.org>
Signed-off-by: Lina Iyer <lina.iyer at linaro.org>
---
Changes since v1:

- Function name changes and split out common code
- Use cpu,pd for now. Removed references to ARM. Open to recommendations.
- Still located in arch/arm/common/. May move to a more appropriate location.
- Platform drivers can directly call of_init_cpu_domain() without using
  compatibles.
- Now maintains a list of CPU PM domains.
---
 Documentation/arm/cpu-domains.txt                  |  49 +++++
 .../devicetree/bindings/arm/cpudomains.txt         |  23 +++
 arch/arm/common/Makefile                           |   1 +
 arch/arm/common/domains.c                          | 225 +++++++++++++++++++++
 arch/arm/include/asm/cpu-pd.h                      |  27 +++
 5 files changed, 325 insertions(+)
 create mode 100644 Documentation/arm/cpu-domains.txt
 create mode 100644 Documentation/devicetree/bindings/arm/cpudomains.txt
 create mode 100644 arch/arm/common/domains.c
 create mode 100644 arch/arm/include/asm/cpu-pd.h

diff --git a/Documentation/arm/cpu-domains.txt b/Documentation/arm/cpu-domains.txt
new file mode 100644
index 0000000..49bd0d7
--- /dev/null
+++ b/Documentation/arm/cpu-domains.txt
@@ -0,0 +1,49 @@
+CPU Clusters and PM domain
+
+Newer CPUs are grouped in a SoC as clusters. A cluster in addition to the
+CPUs may have caches, GIC, VFP and architecture specific power controller to
+power the cluster. A cluster may also be nested in another cluster, the
+hierarchy of which is depicted in the device tree. CPUIdle frameworks enables
+the CPUs to determine the sleep time and enter low power state to save power
+during periods of idle. CPUs in a cluster may enter and exit idle state
+independently. During the time when all the CPUs are in idle state, the
+cluster can safely be in idle state as well. When the last of the CPUs is
+powered off as a result of idle, the cluster may also be powered down, but the
+domain must be powered on before the first of the CPUs in the cluster resumes
+execution.
+
+SoCs can power down the CPU and resume execution in a few uSecs and the domain
+that powers the CPU cluster also have comparable idle latencies. The CPU WFI
+signal in ARM CPUs is used as a hardware trigger for the cluster hardware to
+enter their idle state. The hardware can be programmed in advance to put the
+cluster in the desired idle state befitting the wakeup latency requested by
+the CPUs. When all the CPUs in a cluster have executed their WFI instruction,
+the state machine for the power controller may put the cluster components in
+their power down or idle state. Generally, the domains would power on with the
+hardware sensing the CPU's interrupts. The domains may however, need to be
+reconfigured by the CPU to remain active, until the last CPU is ready to enter
+idle again. To power down a cluster, it is generally required to power down
+all the CPUs. The caches would also need to be flushed. The hardware state of
+some of the components may need to be saved and restored when powered back on.
+SoC vendors may also have hardware specific configuration that must be done
+before the cluster can be powered off. When the cluster is powered off,
+notifications may be sent out to other SoC components to scale down or even
+power off their resources.
+
+Power management domains represent relationship of devices and their power
+controllers. They are represented in the DT as domain consumers and providers.
+A device may have a domain provider and a domain provider may support multiple
+domain consumers. Domains like clusters, may also be nested inside one
+another. A domain that has no active consumer, may be powered off and any
+resuming consumer would trigger the domain back to active. Parent domains may
+be powered off when the child domains are powered off. The CPU cluster can be
+fashioned as a PM domain. When the CPU devices are powered off, the PM domain
+may be powered off.
+
+The code in Generic PM domains handles the hierarchy of devices, domains and
+the reference counting of objects leading to last man down and first man up.
+The CPU domains core code defines PM domains for each CPU cluster and attaches
+the domains' CPU devices to as specified in the DT. This happens automatically
+at kernel init, when the domain is specified as compatible with "cpu,pd".
+Powering on/off the common cluster hardware would also be done when the PM
+domain is runtime suspended or resumed.
diff --git a/Documentation/devicetree/bindings/arm/cpudomains.txt b/Documentation/devicetree/bindings/arm/cpudomains.txt
new file mode 100644
index 0000000..54be393
--- /dev/null
+++ b/Documentation/devicetree/bindings/arm/cpudomains.txt
@@ -0,0 +1,23 @@
+CPU Power domains
+
+The device tree allows describing of CPU power domains in a SoC. In many SoCs,
+CPUs are be grouped as clusters. A cluster may have CPUs, GIC, Coresight,
+caches, VFP and power controller and other peripheral hardware. Generally,
+when the CPUs in the cluster are idle/suspended, the shared resources may also
+be suspended and resumed before any of the CPUs resume execution.
+
+CPUs are the defined as the PM domain consumers and there is a PM domain
+provider for the CPUs. Bindings for generic PM domains (genpd) is described in
+[1].
+
+The CPU PM domain follows the same binding convention as any generic PM
+domain. Additional binding properties are -
+
+- compatible:
+	Usage: required
+	Value type: <string>
+	Definition: Should also have
+			"cpu,pd"
+		inorder to initialize the genpd provider as CPU PM domain.
+
+[1]. Documentation/devicetree/bindings/power/power_domain.txt
diff --git a/arch/arm/common/Makefile b/arch/arm/common/Makefile
index 6764ed0..af0cd04 100644
--- a/arch/arm/common/Makefile
+++ b/arch/arm/common/Makefile
@@ -19,3 +19,4 @@ AFLAGS_vlock.o			:= -march=armv7-a
 obj-$(CONFIG_TI_PRIV_EDMA)	+= edma.o
 obj-$(CONFIG_BL_SWITCHER)	+= bL_switcher.o
 obj-$(CONFIG_BL_SWITCHER_DUMMY_IF) += bL_switcher_dummy_if.o
+obj-$(CONFIG_PM_GENERIC_DOMAINS) += domains.o
diff --git a/arch/arm/common/domains.c b/arch/arm/common/domains.c
new file mode 100644
index 0000000..4bc32a5
--- /dev/null
+++ b/arch/arm/common/domains.c
@@ -0,0 +1,225 @@
+/*
+ * CPU Generic PM Domain.
+ *
+ * Copyright (C) 2015 Linaro Ltd.
+ *
+ * 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.
+ */
+
+#define DEBUG
+
+#include <linux/kernel.h>
+#include <linux/module.h>
+#include <linux/cpu_pm.h>
+#include <linux/device.h>
+#include <linux/of_platform.h>
+#include <linux/platform_device.h>
+#include <linux/pm_runtime.h>
+#include <linux/slab.h>
+
+#include <asm/cpu-pd.h>
+
+#define NAME_MAX 36
+
+/* List of CPU PM domains we care about */
+static LIST_HEAD(of_cpu_pd_list);
+
+static int cpu_pd_power_down(struct generic_pm_domain *genpd)
+{
+	/*
+	 * Notify CPU PM domain power down
+	 * TODO: Call the notificated directly from here.
+	 */
+	cpu_cluster_pm_enter();
+
+	return 0;
+}
+
+static int cpu_pd_power_up(struct generic_pm_domain *genpd)
+{
+	/* Notify CPU PM domain power up */
+	cpu_cluster_pm_exit();
+
+	return 0;
+}
+
+static void __init run_cpu(void *unused)
+{
+	struct device *cpu_dev = get_cpu_device(smp_processor_id());
+
+	/* We are running, increment the usage count */
+	pm_runtime_get_noresume(cpu_dev);
+}
+
+static int __init of_pm_domain_attach_cpus(void)
+{
+	int cpuid, ret;
+
+	/* Find any CPU nodes with a phandle to this power domain */
+	for_each_possible_cpu(cpuid) {
+		struct device *cpu_dev;
+		struct of_phandle_args pd_args;
+
+		cpu_dev = get_cpu_device(cpuid);
+		if (!cpu_dev) {
+			pr_warn("%s: Unable to get device for CPU%d\n",
+					__func__, cpuid);
+			return -ENODEV;
+		}
+
+		/*
+		 * We are only interested in CPUs that can be attached to
+		 * PM domains that are cpu,pd compatible.
+		 */
+		ret = of_parse_phandle_with_args(cpu_dev->of_node,
+				"power-domains", "#power-domain-cells",
+				0, &pd_args);
+		if (ret) {
+			dev_dbg(cpu_dev,
+				"%s: Did not find a valid PM domain\n",
+					__func__);
+			continue;
+		}
+
+		if (!of_device_is_compatible(pd_args.np, "cpu,pd")) {
+			dev_dbg(cpu_dev, "%s: does not have an CPU PD\n",
+					__func__);
+			continue;
+		}
+
+		if (cpu_online(cpuid)) {
+			pm_runtime_set_active(cpu_dev);
+			/*
+			 * Execute the below on that 'cpu' to ensure that the
+			 * reference counting is correct. Its possible that
+			 * while this code is executing, the 'cpu' may be
+			 * powered down, but we may incorrectly increment the
+			 * usage. By executing the get_cpu on the 'cpu',
+			 * we can ensure that the 'cpu' and its usage count are
+			 * matched.
+			 */
+			smp_call_function_single(cpuid, run_cpu, NULL, true);
+		} else {
+			pm_runtime_set_suspended(cpu_dev);
+		}
+		pm_runtime_irq_safe(cpu_dev);
+		pm_runtime_enable(cpu_dev);
+
+		/*
+		 * We attempt to attach the device to genpd again. We would
+		 * have failed in our earlier attempt to attach to the domain
+		 * provider as the CPU device would not have been IRQ safe,
+		 * while the domain is defined as IRQ safe. IRQ safe domains
+		 * can only have IRQ safe devices.
+		 */
+		ret = genpd_dev_pm_attach(cpu_dev);
+		if (ret) {
+			dev_warn(cpu_dev,
+				"%s: Unable to attach to power-domain: %d\n",
+				__func__, ret);
+			pm_runtime_disable(cpu_dev);
+		}
+	}
+
+	return 0;
+}
+
+static struct cpu_pm_domain __init *setup_cpu_pd(struct device_node *dn)
+{
+	struct cpu_pm_domain *pd;
+
+	pd = kzalloc(sizeof(*pd), GFP_KERNEL);
+	if (!pd)
+		return NULL;
+
+	pd->genpd = kzalloc(sizeof(*(pd->genpd)), GFP_KERNEL);
+	if (!pd->genpd) {
+		kfree(pd);
+		return NULL;
+	}
+
+	INIT_LIST_HEAD(&pd->link);
+	list_add(&pd->link, &of_cpu_pd_list);
+	pd->dn = dn;
+	pd->genpd->name = kstrndup(dn->full_name, NAME_MAX, GFP_KERNEL);
+
+	return pd;
+}
+
+static void __init of_register_cpu_pd(struct device_node *dn,
+		struct cpu_pm_domain *pd)
+{
+	pd->genpd->power_off = cpu_pd_power_down;
+	pd->genpd->power_on = cpu_pd_power_up;
+	pd->genpd->flags |= GENPD_FLAG_IRQ_SAFE;
+
+	/* Register the CPU genpd */
+	pr_debug("adding %s as generic power domain.\n", pd->genpd->name);
+	pm_genpd_init(pd->genpd, &simple_qos_governor, false);
+	of_genpd_add_provider_simple(dn, pd->genpd);
+}
+
+/**
+ * of_init_cpu_pm_domain() - Initialize a CPU PM domain using the CPU pd
+ * provided
+ * @dn: PM domain provider device node
+ * @pd: CPU PM domain to be initialized with genpd framework.
+ */
+int __init of_init_cpu_domain(struct device_node *dn, struct cpu_pm_domain *pd)
+{
+	if (!of_device_is_available(dn))
+		return -ENODEV;
+
+	if (!pd)
+		return -EINVAL;
+
+	of_register_cpu_pd(dn, pd);
+	of_pm_domain_attach_cpus();
+
+	return 0;
+}
+EXPORT_SYMBOL(of_init_cpu_domain);
+
+/**
+ * of_get_cpu_pm_domain() - Returns the CPU PD associated with the device node
+ * @dn: PM domain provider device node
+ */
+struct cpu_pm_domain __init *of_get_cpu_domain(struct device_node *dn)
+{
+	struct cpu_pm_domain *pd;
+
+	list_for_each_entry(pd, &of_cpu_pd_list, link) {
+		if (pd->dn == dn)
+			return pd;
+	}
+
+	return NULL;
+}
+EXPORT_SYMBOL(of_get_cpu_domain);
+
+static int __init of_cpu_pd_init(void)
+{
+	struct device_node *dn;
+	struct cpu_pm_domain *pd;
+
+	for_each_compatible_node(dn, NULL, "cpu,pd") {
+
+		if (!of_device_is_available(dn))
+			continue;
+
+		pd = setup_cpu_pd(dn);
+		if (!pd)
+			return -ENOMEM;
+
+		of_register_cpu_pd(dn, pd);
+	}
+
+	/* We have CPU PD(s), attach CPUs to their domain */
+	if (!list_empty(&of_cpu_pd_list))
+		return of_pm_domain_attach_cpus();
+
+	return 0;
+}
+device_initcall(of_cpu_pd_init);
diff --git a/arch/arm/include/asm/cpu-pd.h b/arch/arm/include/asm/cpu-pd.h
new file mode 100644
index 0000000..4785260
--- /dev/null
+++ b/arch/arm/include/asm/cpu-pd.h
@@ -0,0 +1,27 @@
+/*
+ * linux/arch/arm/include/asm/cpu-pd.h
+ *
+ * Copyright (C) 2015 Linaro Ltd.
+ *
+ * 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.
+ */
+
+#ifndef __CPU_PD_H__
+#define __CPU_PD_H__
+
+#include <linux/list.h>
+#include <linux/of.h>
+#include <linux/pm_domain.h>
+
+struct cpu_pm_domain {
+	struct list_head link;
+	struct generic_pm_domain *genpd;
+	struct device_node *dn;
+};
+
+extern int of_init_cpu_domain(struct device_node *dn, struct cpu_pm_domain *pd);
+extern struct cpu_pm_domain *of_get_cpu_domain(struct device_node *dn);
+
+#endif /* __CPU_PD_H__ */
-- 
2.1.4



From lina.iyer at linaro.org  Wed Aug 12 12:00:24 2015
From: lina.iyer at linaro.org (Lina Iyer)
Date: Wed, 12 Aug 2015 13:00:24 -0600
Subject: [PATCH v2 2/2] ARM: domain: Add platform handlers for CPU PM domains
In-Reply-To: <1439406024-41893-1-git-send-email-lina.iyer@linaro.org>
References: <1439406024-41893-1-git-send-email-lina.iyer@linaro.org>
Message-ID: <1439406024-41893-2-git-send-email-lina.iyer@linaro.org>

In addition to the common power up/down actions of CPU PM domain core,
platforms may have additional configuration before the CPU domain can b
powered off or considered active. Allow platform drivers to register
handlers for CPU PM domains.

Platform drivers may register their callbacks against a compatible
string defined by their PM domain provider device node in the DT. At
domain init, the platform driver can initialize the platform specific
genpd attributes. The init callback would need to return successfully,
for the platform power_on/off handlers to be registered with the CPU PM
domain.

The code uses __init section to reduce memory needed for platform
handlers and therefore can be freed after the driver is initialized, a
desirable outcome for single kernel image.

Cc: Rob Herring <robh at kernel.org>
Cc: Stephen Boyd <sboyd at codeaurora.org>
Cc: Kevin Hilman <khilman at linaro.org>
Cc: Ulf Hansson <ulf.hansson at linaro.org>
Cc: Catalin Marinas <catalin.marinas at arm.com>
Cc: Mark Rutland <mark.rutland at arm.com>
Cc: Lorenzo Pieralisi <lorenzo.pieralisi at arm.com>
Signed-off-by: Lina Iyer <lina.iyer at linaro.org>
---
Changes since v1:

- Removed references to ARM
- Use OF_DECLARE_1 for __init section tables
---
 arch/arm/common/domains.c         | 38 ++++++++++++++++++++++++++++++++++++++
 arch/arm/include/asm/cpu-pd.h     | 11 +++++++++++
 include/asm-generic/vmlinux.lds.h |  2 ++
 3 files changed, 51 insertions(+)

diff --git a/arch/arm/common/domains.c b/arch/arm/common/domains.c
index 4bc32a5..b1d9cc0 100644
--- a/arch/arm/common/domains.c
+++ b/arch/arm/common/domains.c
@@ -26,8 +26,28 @@
 /* List of CPU PM domains we care about */
 static LIST_HEAD(of_cpu_pd_list);
 
+static const struct of_device_id __cpu_pd_of_table_sentinel
+	__used __section(__cpu_pd_of_table_end);
+
+static inline
+struct cpu_pm_domain *to_cpu_pd(struct generic_pm_domain *d)
+{
+	struct cpu_pm_domain *pd;
+
+	list_for_each_entry(pd, &of_cpu_pd_list, link) {
+		if (pd->genpd == d)
+			return pd;
+	}
+
+	return NULL;
+}
+
 static int cpu_pd_power_down(struct generic_pm_domain *genpd)
 {
+	struct cpu_pm_domain *pd = to_cpu_pd(genpd);
+
+	if (pd->platform_ops.power_off)
+		pd->platform_ops.power_off(genpd);
 	/*
 	 * Notify CPU PM domain power down
 	 * TODO: Call the notificated directly from here.
@@ -39,6 +59,11 @@ static int cpu_pd_power_down(struct generic_pm_domain *genpd)
 
 static int cpu_pd_power_up(struct generic_pm_domain *genpd)
 {
+	struct cpu_pm_domain *pd = to_cpu_pd(genpd);
+
+	if (pd->platform_ops.power_on)
+		pd->platform_ops.power_on(genpd);
+
 	/* Notify CPU PM domain power up */
 	cpu_cluster_pm_exit();
 
@@ -203,6 +228,8 @@ static int __init of_cpu_pd_init(void)
 {
 	struct device_node *dn;
 	struct cpu_pm_domain *pd;
+	const struct of_device_id *m = &__cpu_pd_of_table;
+	void (*pd_init)(struct device_node *) = NULL;
 
 	for_each_compatible_node(dn, NULL, "cpu,pd") {
 
@@ -213,6 +240,17 @@ static int __init of_cpu_pd_init(void)
 		if (!pd)
 			return -ENOMEM;
 
+		/* Find a compatible platform driver */
+		for (; m->compatible; m++) {
+			if (of_device_is_compatible(dn, m->compatible)) {
+				pd_init = m->data;
+				break;
+			}
+		}
+
+		if (pd_init)
+			pd_init(dn);
+
 		of_register_cpu_pd(dn, pd);
 	}
 
diff --git a/arch/arm/include/asm/cpu-pd.h b/arch/arm/include/asm/cpu-pd.h
index 4785260..65db517 100644
--- a/arch/arm/include/asm/cpu-pd.h
+++ b/arch/arm/include/asm/cpu-pd.h
@@ -15,13 +15,24 @@
 #include <linux/of.h>
 #include <linux/pm_domain.h>
 
+struct cpu_pd_ops {
+	int (*power_on)(struct generic_pm_domain *d);
+	int (*power_off)(struct generic_pm_domain *d);
+};
+
 struct cpu_pm_domain {
 	struct list_head link;
 	struct generic_pm_domain *genpd;
+	struct cpu_pd_ops platform_ops;
 	struct device_node *dn;
 };
 
 extern int of_init_cpu_domain(struct device_node *dn, struct cpu_pm_domain *pd);
 extern struct cpu_pm_domain *of_get_cpu_domain(struct device_node *dn);
 
+extern const struct of_device_id __cpu_pd_of_table;
+
+#define CPU_PD_METHOD_OF_DECLARE(name, compat, fn)     \
+			OF_DECLARE_1(cpu_pd, name, compat, fn)
+
 #endif /* __CPU_PD_H__ */
diff --git a/include/asm-generic/vmlinux.lds.h b/include/asm-generic/vmlinux.lds.h
index 8bd374d..f952933 100644
--- a/include/asm-generic/vmlinux.lds.h
+++ b/include/asm-generic/vmlinux.lds.h
@@ -179,6 +179,7 @@
 #define RESERVEDMEM_OF_TABLES()	OF_TABLE(CONFIG_OF_RESERVED_MEM, reservedmem)
 #define CPU_METHOD_OF_TABLES()	OF_TABLE(CONFIG_SMP, cpu_method)
 #define CPUIDLE_METHOD_OF_TABLES() OF_TABLE(CONFIG_CPU_IDLE, cpuidle_method)
+#define CPU_PD_OF_TABLES()	OF_TABLE(CONFIG_PM_GENERIC_DOMAINS, cpu_pd)
 #define EARLYCON_OF_TABLES()	OF_TABLE(CONFIG_SERIAL_EARLYCON, earlycon)
 
 #define KERNEL_DTB()							\
@@ -514,6 +515,7 @@
 	IOMMU_OF_TABLES()						\
 	CPU_METHOD_OF_TABLES()						\
 	CPUIDLE_METHOD_OF_TABLES()					\
+	CPU_PD_OF_TABLES()						\
 	KERNEL_DTB()							\
 	IRQCHIP_OF_MATCH_TABLE()					\
 	EARLYCON_TABLE()						\
-- 
2.1.4



From alex.williamson at redhat.com  Wed Aug 12 12:05:07 2015
From: alex.williamson at redhat.com (Alex Williamson)
Date: Wed, 12 Aug 2015 13:05:07 -0600
Subject: [PATCH v5 5/5] KVM: eventfd: add irq bypass consumer management
In-Reply-To: <1439213467-13668-6-git-send-email-eric.auger@linaro.org>
References: <1439213467-13668-1-git-send-email-eric.auger@linaro.org>
 <1439213467-13668-6-git-send-email-eric.auger@linaro.org>
Message-ID: <1439406307.4023.532.camel@redhat.com>

On Mon, 2015-08-10 at 15:31 +0200, Eric Auger wrote:
> This patch adds the registration/unregistration of an
> irq_bypass_consumer on irqfd assignment/deassignment.
> 
> Signed-off-by: Eric Auger <eric.auger at linaro.org>
> Signed-off-by: Feng Wu <feng.wu at intel.com>
> 
> ---
> 
> v4 -> v5:
> - due to removal of static inline stubs, add
>   #ifdef CONFIG_HAVE_KVM_IRQ_BYPASS
>   around consumer registration/unregistration
> - add pr_info when registration fails
> 
> v2 -> v3 (Feng Wu):
> - Use kvm_arch_irq_bypass_start
> - Remove kvm_arch_irq_bypass_update
> - Add member 'struct irq_bypass_producer *producer' in
>   'struct kvm_kernel_irqfd', it is needed by posted interrupt.
> - Remove 'irq_bypass_unregister_consumer' in kvm_irqfd_deassign()
> 
> v1 -> v2:
> - populate of kvm and gsi removed
> - unregister the consumer on irqfd_shutdown
> ---
>  include/linux/kvm_irqfd.h |  2 ++
>  virt/kvm/eventfd.c        | 15 +++++++++++++++
>  2 files changed, 17 insertions(+)
> 
> diff --git a/include/linux/kvm_irqfd.h b/include/linux/kvm_irqfd.h
> index f926b39..0c1de05 100644
> --- a/include/linux/kvm_irqfd.h
> +++ b/include/linux/kvm_irqfd.h
> @@ -64,6 +64,8 @@ struct kvm_kernel_irqfd {
>  	struct list_head list;
>  	poll_table pt;
>  	struct work_struct shutdown;
> +	struct irq_bypass_consumer consumer;
> +	struct irq_bypass_producer *producer;
>  };
>  
>  #endif /* __LINUX_KVM_IRQFD_H */
> diff --git a/virt/kvm/eventfd.c b/virt/kvm/eventfd.c
> index 647ffb8..d7a230f 100644
> --- a/virt/kvm/eventfd.c
> +++ b/virt/kvm/eventfd.c
> @@ -35,6 +35,7 @@
>  #include <linux/srcu.h>
>  #include <linux/slab.h>
>  #include <linux/seqlock.h>
> +#include <linux/irqbypass.h>
>  #include <trace/events/kvm.h>
>  
>  #include <kvm/iodev.h>
> @@ -140,6 +141,9 @@ irqfd_shutdown(struct work_struct *work)
>  	/*
>  	 * It is now safe to release the object's resources
>  	 */
> +#ifdef CONFIG_HAVE_KVM_IRQ_BYPASS
> +	irq_bypass_unregister_consumer(&irqfd->consumer);
> +#endif
>  	eventfd_ctx_put(irqfd->eventfd);
>  	kfree(irqfd);
>  }
> @@ -379,6 +383,17 @@ kvm_irqfd_assign(struct kvm *kvm, struct kvm_irqfd *args)
>  	 * we might race against the POLLHUP
>  	 */
>  	fdput(f);
> +#ifdef CONFIG_HAVE_KVM_IRQ_BYPASS
> +	irqfd->consumer.token = (void *)irqfd->eventfd;
> +	irqfd->consumer.add_producer = kvm_arch_irq_bypass_add_producer;
> +	irqfd->consumer.del_producer = kvm_arch_irq_bypass_del_producer;
> +	irqfd->consumer.stop = kvm_arch_irq_bypass_stop;
> +	irqfd->consumer.start = kvm_arch_irq_bypass_start;
> +	ret = irq_bypass_register_consumer(&irqfd->consumer);
> +	if (ret)
> +		pr_info("irq bypass consumer (token %p) registration fails: %d\n",
> +				irqfd->consumer.token, ret);
> +#endif

Does this series compile on its own?  Aren't all these arch function
unresolved?

>  
>  	return 0;
>  





From sboyd at codeaurora.org  Wed Aug 12 12:11:57 2015
From: sboyd at codeaurora.org (Stephen Boyd)
Date: Wed, 12 Aug 2015 12:11:57 -0700
Subject: [PATCH 3/5] iommu/msm: Add support for generic master bindings
In-Reply-To: <1439390869-6347-4-git-send-email-sricharan@codeaurora.org>
References: <1439390869-6347-1-git-send-email-sricharan@codeaurora.org>
 <1439390869-6347-4-git-send-email-sricharan@codeaurora.org>
Message-ID: <55CB9A7D.7080206@codeaurora.org>

On 08/12/2015 07:47 AM, Sricharan R wrote:
> @@ -702,6 +703,44 @@ static void print_ctx_regs(void __iomem *base, int ctx)
>   	       GET_PRRR(base, ctx), GET_NMRR(base, ctx));
>   }
>   
> +static void insert_iommu_master(struct device *dev,
> +				struct msm_iommu_dev *iommu,
> +				struct of_phandle_args *spec)
> +{
> +	struct msm_iommu_ctx_dev *master;
> +	int sid;
> +
> +	master = kzalloc(sizeof(*master), GFP_KERNEL);

This is called with irqs disabled, but it's not GFP_ATOMIC. Please test 
with DEBUG_ATOMIC_SLEEP=y.

> +	master->of_node = dev->of_node;
> +	list_add(&master->list, &iommu->ctx_list);
> +
> +	for (sid = 0; sid < spec->args_count; sid++)
> +		master->mids[sid] = spec->args[sid];
> +
> +	master->num_mids = spec->args_count;
> +}
> +
> +static int qcom_iommu_of_xlate(struct device *dev,
> +			       struct of_phandle_args *spec)
> +{
> +	struct msm_iommu_dev *iommu;
> +	unsigned long flags;
> +
> +	spin_lock_irqsave(&msm_iommu_lock, flags);
> +	list_for_each_entry(iommu, &qcom_iommu_devices, dev_node) {
> +		if (iommu->dev->of_node == spec->np)
> +			break;
> +	}

The braces are unnecessary here.

> +
> +	if (!iommu || (iommu->dev->of_node != spec->np))

Please remove extraneous parentheses.

> +		return -ENODEV;
> +
> +	insert_iommu_master(dev, iommu, spec);
> +	spin_unlock_irqrestore(&msm_iommu_lock, flags);
> +
> +	return 0;
> +}
> +
>   irqreturn_t msm_iommu_fault_handler(int irq, void *dev_id)
>   {
>   	struct msm_iommu_dev *iommu = dev_id;
> @@ -737,7 +776,7 @@ fail:
>   	return 0;
>   }
>   
> -static const struct iommu_ops msm_iommu_ops = {
> +static struct iommu_ops msm_iommu_ops = {

Is there a reason why we can't make of_iommu_set_ops() take a const ops 
pointer?

-- 
Qualcomm Innovation Center, Inc. is a member of Code Aurora Forum,
a Linux Foundation Collaborative Project



From timur at codeaurora.org  Wed Aug 12 12:20:16 2015
From: timur at codeaurora.org (Timur Tabi)
Date: Wed, 12 Aug 2015 14:20:16 -0500
Subject: [PATCH v4 00/10] ACPI GIC Self-probing, GICv2m and GICv3 support
In-Reply-To: <20150812082138.6a80c71d@arm.com>
References: <1438164539-29256-1-git-send-email-hanjun.guo@linaro.org>	<55CA70D5.6040300@codeaurora.org>	<20150811232523.60d192d2@arm.com>	<55CA78DE.1000306@codeaurora.org>	<20150811234801.51108784@arm.com>	<55CA8658.80202@codeaurora.org>
 <20150812082138.6a80c71d@arm.com>
Message-ID: <55CB9C70.8040601@codeaurora.org>

On 08/12/2015 02:21 AM, Marc Zyngier wrote:
> I just cloned this repository, and none of the branches I received have
> this as their top commit. I can only guess that you're looking at
> something else.

It took me way too long, but I can see the v4.2-rc2 merge commit now.  I 
blame sunspots for my poor git-fu.  Sorry for all the noise.

-- 
Qualcomm Innovation Center, Inc.
The Qualcomm Innovation Center, Inc. is a member of the
Code Aurora Forum, a Linux Foundation Collaborative Project.


From hongzhou.yang at mediatek.com  Wed Aug 12 12:19:59 2015
From: hongzhou.yang at mediatek.com (Hongzhou Yang)
Date: Wed, 12 Aug 2015 12:19:59 -0700
Subject: [PATCH] pinctrl: mediatek: Fix multiple registeration issue.
In-Reply-To: <CAGS+omAE2AXpwnYtvetcjvP_6jUbE2HDuPfKfy=aLook2M-8LQ@mail.gmail.com>
References: <1439268571-10895-1-git-send-email-hongzhou.yang@mediatek.com>
 <CAGS+omAE2AXpwnYtvetcjvP_6jUbE2HDuPfKfy=aLook2M-8LQ@mail.gmail.com>
Message-ID: <1439407199.38706.3.camel@mussux00.eus.mediatek.inc>

On Tue, 2015-08-11 at 15:45 +0800, Daniel Kurtz wrote:
> On Tue, Aug 11, 2015 at 12:49 PM, Hongzhou Yang
> <hongzhou.yang at mediatek.com> wrote:
> > Use dynamic allocation to fix multiple registeration issue.
> 
> s/registeration/registration   - here and in the patch subject.
> 
> >
> > --------------8<--------------------
> 
> I don't think this is required.
> 
> > Since our common driver need support main chip and PMU
> > at the same time, that means it will register two
> > pinctrl device, and the pinctrl_desc structure should
> > be used two times.
> >
> > But pinctrl_desc use global static definition, then
> > the latest registered pinctrl device will overwrite
> > the old one's, all members in pinctrl_desc will set to
> > the new one's, such as name, pins and pins numbers, etc.
> > This is a bug. Changing to use devm_kzalloc to fix it.
> >
> > Cc: stable at vger.kernel.org # v4.1+
> > Signed-off-by: Hongzhou Yang <hongzhou.yang at mediatek.com>
> > ---
> >  drivers/pinctrl/mediatek/pinctrl-mtk-common.c |   27 +++++++++++++++----------
> >  1 file changed, 16 insertions(+), 11 deletions(-)
> >
> > diff --git a/drivers/pinctrl/mediatek/pinctrl-mtk-common.c b/drivers/pinctrl/mediatek/pinctrl-mtk-common.c
> > index ad1ea16..2bba504 100644
> > --- a/drivers/pinctrl/mediatek/pinctrl-mtk-common.c
> > +++ b/drivers/pinctrl/mediatek/pinctrl-mtk-common.c
> > @@ -1202,17 +1202,12 @@ static int mtk_pctrl_build_state(struct platform_device *pdev)
> >         return 0;
> >  }
> >
> > -static struct pinctrl_desc mtk_pctrl_desc = {
> > -       .confops        = &mtk_pconf_ops,
> > -       .pctlops        = &mtk_pctrl_ops,
> > -       .pmxops         = &mtk_pmx_ops,
> > -};
> > -
> >  int mtk_pctrl_init(struct platform_device *pdev,
> >                 const struct mtk_pinctrl_devdata *data,
> >                 struct regmap *regmap)
> >  {
> >         struct pinctrl_pin_desc *pins;
> > +       struct pinctrl_desc *mtk_pctrl_desc;
> >         struct mtk_pinctrl *pctl;
> >         struct device_node *np = pdev->dev.of_node, *node;
> >         struct property *prop;
> > @@ -1265,12 +1260,22 @@ int mtk_pctrl_init(struct platform_device *pdev,
> >
> >         for (i = 0; i < pctl->devdata->npins; i++)
> >                 pins[i] = pctl->devdata->pins[i].pin;
> > -       mtk_pctrl_desc.name = dev_name(&pdev->dev);
> > -       mtk_pctrl_desc.owner = THIS_MODULE;
> > -       mtk_pctrl_desc.pins = pins;
> > -       mtk_pctrl_desc.npins = pctl->devdata->npins;
> > +
> > +       mtk_pctrl_desc = devm_kzalloc(&pdev->dev, sizeof(*mtk_pctrl_desc),
> > +                               GFP_KERNEL);
> > +       if (!mtk_pctrl_desc)
> > +               return -ENOMEM;
> 
> Just embed a struct pinctrl_desc in your struct mtk_pinctrl.
> 
> Best Regards,
> -Dan

Ok, I will send another patch to fix them, thank you.

Yours,
Hongzhou




From khilman at kernel.org  Wed Aug 12 12:47:37 2015
From: khilman at kernel.org (Kevin Hilman)
Date: Wed, 12 Aug 2015 12:47:37 -0700
Subject: [PATCH 1/9] PM / Domains: Allocate memory outside domain locks
In-Reply-To: <1438731339-58317-2-git-send-email-lina.iyer@linaro.org> (Lina
 Iyer's message of "Tue, 4 Aug 2015 17:35:31 -0600")
References: <1438731339-58317-1-git-send-email-lina.iyer@linaro.org>
 <1438731339-58317-2-git-send-email-lina.iyer@linaro.org>
Message-ID: <7hoaicnvae.fsf@deeprootsystems.com>

Lina Iyer <lina.iyer at linaro.org> writes:

> In preparation for supporting IRQ-safe domains, allocate domain data
> outside the domain locks. These functions are not called in an atomic
> context, so we can always allocate memory using GFP_KERNEL. By
> allocating memory before the locks, we can safely lock the domain using
> spinlocks instead of mutexes.
>
> Cc: Ulf Hansson <ulf.hansson at linaro.org>
> Cc: Rafael J. Wysocki <rjw at rjwysocki.net>
> Cc: Kevin Hilman <khilman at linaro.org>
> Cc: Geert Uytterhoeven <geert at linux-m68k.org>
> Cc: Krzysztof Koz?owski <k.kozlowski at samsung.com>
> Signed-off-by: Lina Iyer <lina.iyer at linaro.org>

Reviewed-by: Kevin Hilman <khilman at linaro.org>

> ---
>  drivers/base/power/domain.c | 30 +++++++++++++++---------------
>  1 file changed, 15 insertions(+), 15 deletions(-)
>
> diff --git a/drivers/base/power/domain.c b/drivers/base/power/domain.c
> index 7666a1c..5fd1306 100644
> --- a/drivers/base/power/domain.c
> +++ b/drivers/base/power/domain.c
> @@ -1382,13 +1382,17 @@ int pm_genpd_remove_device(struct generic_pm_domain *genpd,
>  int pm_genpd_add_subdomain(struct generic_pm_domain *genpd,
>  			   struct generic_pm_domain *subdomain)
>  {
> -	struct gpd_link *link;
> +	struct gpd_link *link, *itr;
>  	int ret = 0;
>  
>  	if (IS_ERR_OR_NULL(genpd) || IS_ERR_OR_NULL(subdomain)
>  	    || genpd == subdomain)
>  		return -EINVAL;
>  
> +	link = kzalloc(sizeof(*link), GFP_KERNEL);
> +	if (!link)
> +		return -ENOMEM;
> +
>  	mutex_lock(&genpd->lock);
>  	mutex_lock_nested(&subdomain->lock, SINGLE_DEPTH_NESTING);
>  
> @@ -1398,18 +1402,13 @@ int pm_genpd_add_subdomain(struct generic_pm_domain *genpd,
>  		goto out;
>  	}
>  
> -	list_for_each_entry(link, &genpd->master_links, master_node) {
> -		if (link->slave == subdomain && link->master == genpd) {
> +	list_for_each_entry(itr, &genpd->master_links, master_node) {
> +		if (itr->slave == subdomain && itr->master == genpd) {
>  			ret = -EINVAL;
>  			goto out;
>  		}
>  	}
>  
> -	link = kzalloc(sizeof(*link), GFP_KERNEL);
> -	if (!link) {
> -		ret = -ENOMEM;
> -		goto out;
> -	}
>  	link->master = genpd;
>  	list_add_tail(&link->master_node, &genpd->master_links);
>  	link->slave = subdomain;
> @@ -1420,7 +1419,8 @@ int pm_genpd_add_subdomain(struct generic_pm_domain *genpd,
>   out:
>  	mutex_unlock(&subdomain->lock);
>  	mutex_unlock(&genpd->lock);
> -
> +	if (ret)
> +		kfree(link);
>  	return ret;
>  }
>  
> @@ -1511,17 +1511,17 @@ int pm_genpd_attach_cpuidle(struct generic_pm_domain *genpd, int state)
>  	if (IS_ERR_OR_NULL(genpd) || state < 0)
>  		return -EINVAL;
>  
> +	cpuidle_data = kzalloc(sizeof(*cpuidle_data), GFP_KERNEL);
> +	if (!cpuidle_data)
> +		return -ENOMEM;
> +
>  	mutex_lock(&genpd->lock);
>  
>  	if (genpd->cpuidle_data) {
>  		ret = -EEXIST;
> -		goto out;
> -	}
> -	cpuidle_data = kzalloc(sizeof(*cpuidle_data), GFP_KERNEL);
> -	if (!cpuidle_data) {
> -		ret = -ENOMEM;
> -		goto out;
> +		goto err_drv;
>  	}
> +
>  	cpuidle_drv = cpuidle_driver_ref();
>  	if (!cpuidle_drv) {
>  		ret = -ENODEV;


From khilman at kernel.org  Wed Aug 12 12:50:39 2015
From: khilman at kernel.org (Kevin Hilman)
Date: Wed, 12 Aug 2015 12:50:39 -0700
Subject: [PATCH 2/9] PM / Domains: Remove dev->driver check for runtime PM
In-Reply-To: <1438731339-58317-3-git-send-email-lina.iyer@linaro.org> (Lina
 Iyer's message of "Tue, 4 Aug 2015 17:35:32 -0600")
References: <1438731339-58317-1-git-send-email-lina.iyer@linaro.org>
 <1438731339-58317-3-git-send-email-lina.iyer@linaro.org>
Message-ID: <7hfv3onv5c.fsf@deeprootsystems.com>

Lina Iyer <lina.iyer at linaro.org> writes:

> Remove check for driver of a device, for runtime PM. Device may be
> suspended without an explicit driver. This check seems to be vestigial
> and incorrect in the current context.

This one should probably have been RFC.

For a little more context here, this was uncovered when experimenting
with using runtime PM for CPU devices which don't have a dev->driver.

This check might have made sense before PM domains, but with PM domains,
it's entirely possible to have a simple device without a driver and the
PM domain handles all the necesary PM, so I think this check
could/should be removed.

Thoughts?

Kevin

> Reviewed-by: Krzysztof Kozlowski <k.kozlowski at samsung.com>
> Signed-off-by: Kevin Hilman <khilman at linaro.org>
> Signed-off-by: Lina Iyer <lina.iyer at linaro.org>
> ---
>  drivers/base/power/domain.c | 3 +--
>  1 file changed, 1 insertion(+), 2 deletions(-)
>
> diff --git a/drivers/base/power/domain.c b/drivers/base/power/domain.c
> index 5fd1306..ef8d19f 100644
> --- a/drivers/base/power/domain.c
> +++ b/drivers/base/power/domain.c
> @@ -394,8 +394,7 @@ static int pm_genpd_poweroff(struct generic_pm_domain *genpd)
>  		if (stat > PM_QOS_FLAGS_NONE)
>  			return -EBUSY;
>  
> -		if (pdd->dev->driver && (!pm_runtime_suspended(pdd->dev)
> -		    || pdd->dev->power.irq_safe))
> +		if (!pm_runtime_suspended(pdd->dev) || pdd->dev->power.irq_safe)
>  			not_suspended++;
>  	}


From balbi at ti.com  Wed Aug 12 12:54:01 2015
From: balbi at ti.com (Felipe Balbi)
Date: Wed, 12 Aug 2015 14:54:01 -0500
Subject: [RFC/PATCH-v4.2-rc6 2/5] arm: boot: dts: am4372: add ARM timers
 and SCU nodes
In-Reply-To: <20150812145216.GB13884@saruman.tx.rr.com>
References: <1439242911-715-1-git-send-email-balbi@ti.com>
 <1439242911-715-3-git-send-email-balbi@ti.com>
 <20150812072816.GR4215@atomide.com>
 <20150812145216.GB13884@saruman.tx.rr.com>
Message-ID: <20150812195401.GB20972@saruman.tx.rr.com>

Hi,

On Wed, Aug 12, 2015 at 09:52:16AM -0500, Felipe Balbi wrote:
> On Wed, Aug 12, 2015 at 12:28:16AM -0700, Tony Lindgren wrote:
> > * Felipe Balbi <balbi at ti.com> [150810 14:44]:
> > > AM437x devices sport SCU, TWD and Global timers,
> > > let's add them to DTS so they have a chance to
> > > probe and be used by Linux.
> > 
> > Is this one safe to apply already without the Kconfig change?
> > 
> > Or will it cause multi_v7_defconfig with the timers selected
> > to not boot properly?
> 
> I'd have to try :-) But it should be safe, just the timers won't be
> chosen for anything :-)

Just booted with only $subject and patch 1/5, it works just fine.

I'll resend the series (now, 4 patches only) and if RMK is fine with
patch 1, then I'll add to his patch system.

-- 
balbi
-------------- next part --------------
A non-text attachment was scrubbed...
Name: signature.asc
Type: application/pgp-signature
Size: 819 bytes
Desc: Digital signature
URL: <http://lists.infradead.org/pipermail/linux-arm-kernel/attachments/20150812/a8b0a932/attachment.sig>

From balbi at ti.com  Wed Aug 12 12:56:54 2015
From: balbi at ti.com (Felipe Balbi)
Date: Wed, 12 Aug 2015 14:56:54 -0500
Subject: [PATCH-next 2/4] arm: boot: dts: am4372: add ARM timers and SCU nodes
In-Reply-To: <1439409416-32673-1-git-send-email-balbi@ti.com>
References: <1439409416-32673-1-git-send-email-balbi@ti.com>
Message-ID: <1439409416-32673-3-git-send-email-balbi@ti.com>

AM437x devices sport SCU, TWD and Global timers,
let's add them to DTS so they have a chance to
probe and be used by Linux.

Signed-off-by: Felipe Balbi <balbi at ti.com>
---
 arch/arm/boot/dts/am4372.dtsi | 21 +++++++++++++++++++++
 1 file changed, 21 insertions(+)

diff --git a/arch/arm/boot/dts/am4372.dtsi b/arch/arm/boot/dts/am4372.dtsi
index 51feccfa0e0a..7dfc9d8bd003 100644
--- a/arch/arm/boot/dts/am4372.dtsi
+++ b/arch/arm/boot/dts/am4372.dtsi
@@ -64,6 +64,27 @@
 		interrupt-parent = <&gic>;
 	};
 
+	scu: scu at 48240000 {
+		compatible = "arm,cortex-a9-scu";
+		reg = <0x48240000 0x100>;
+	};
+
+	global_timer: timer at 48240200 {
+		compatible = "arm,cortex-a9-global-timer";
+		reg = <0x48240200 0x100>;
+		interrupts = <GIC_PPI 11 IRQ_TYPE_LEVEL_HIGH>;
+		interrupt-parent = <&gic>;
+		clocks = <&dpll_mpu_m2_ck>;
+	};
+
+	local_timer: timer at 48240600 {
+		compatible = "arm,cortex-a9-twd-timer";
+		reg = <0x48240600 0x100>;
+		interrupts = <GIC_PPI 13 IRQ_TYPE_LEVEL_HIGH>;
+		interrupt-parent = <&gic>;
+		clocks = <&dpll_mpu_m2_ck>;
+	};
+
 	l2-cache-controller at 48242000 {
 		compatible = "arm,pl310-cache";
 		reg = <0x48242000 0x1000>;
-- 
2.5.0



From balbi at ti.com  Wed Aug 12 12:56:52 2015
From: balbi at ti.com (Felipe Balbi)
Date: Wed, 12 Aug 2015 14:56:52 -0500
Subject: [PATCH-next 0/4] arm: am437x: use TWD/Global timers
Message-ID: <1439409416-32673-1-git-send-email-balbi@ti.com>

Hi,

with these patches AM437x devices can use TWD/global timers.

At least TWD is now used as sched_clock() which gives better latency as seen
below. Keep in mind that while I ran cyclictest to have a feel for avg latency
this test was not against an RT kernel, so results should be taken with a
grain of salt.

Also, I'm not 100% sure clock rate is correct. According to TRM, this timer
should run as MPU_CLK/2 which would be 1GHz / 2 = 500MHz, but even though
I'm using dpll_mpu_m2_ck clock, it still shows as 1000MHz.

Are there any other tests I could/should run ? BTW, I boot-tested on AM4372
with and without 'nosmp' on cmdline.

pre-patch:
T: 0 (  245) P:95 I:1000 C:   9995 Min:     24 Act:   31 Avg:   36 Max:     596

post-patch:
T: 0 (  253) P:95 I:1000 C:   9995 Min:     10 Act:   12 Avg:   14 Max:      68


Changes since v1:
	- Rebased on top of today's linux-next (c1a0c66f231d Add linux-next
	  specific files for 20150812)

Felipe Balbi (4):
  Revert "ARM: 7655/1: smp_twd: make twd_local_timer_of_register() no-op
    for nosmp"
  arm: boot: dts: am4372: add ARM timers and SCU nodes
  arm: omap2: Kconfig: select TWD and global timer on AM43xx devices
  arm: omap2: board-generic: use omap4_local_timer_init for AM437x

 arch/arm/boot/dts/am4372.dtsi       | 21 +++++++++++++++++++++
 arch/arm/kernel/smp_twd.c           |  4 ----
 arch/arm/mach-omap2/Kconfig         |  3 +++
 arch/arm/mach-omap2/board-generic.c |  2 +-
 4 files changed, 25 insertions(+), 5 deletions(-)

-- 
2.5.0



From balbi at ti.com  Wed Aug 12 12:56:55 2015
From: balbi at ti.com (Felipe Balbi)
Date: Wed, 12 Aug 2015 14:56:55 -0500
Subject: [PATCH-next 3/4] arm: omap2: Kconfig: select TWD and global timer on
 AM43xx devices
In-Reply-To: <1439409416-32673-1-git-send-email-balbi@ti.com>
References: <1439409416-32673-1-git-send-email-balbi@ti.com>
Message-ID: <1439409416-32673-4-git-send-email-balbi@ti.com>

Make sure to tell the kernel that AM437x has
TWD and global timers.

Signed-off-by: Felipe Balbi <balbi at ti.com>
---
 arch/arm/mach-omap2/Kconfig | 3 +++
 1 file changed, 3 insertions(+)

diff --git a/arch/arm/mach-omap2/Kconfig b/arch/arm/mach-omap2/Kconfig
index 07d2e100caab..88ef10b2d415 100644
--- a/arch/arm/mach-omap2/Kconfig
+++ b/arch/arm/mach-omap2/Kconfig
@@ -63,6 +63,9 @@ config SOC_AM43XX
 	select MACH_OMAP_GENERIC
 	select MIGHT_HAVE_CACHE_L2X0
 	select HAVE_ARM_SCU
+	select HAVE_ARM_TWD
+	select ARM_GLOBAL_TIMER
+	select CLKSRC_ARM_GLOBAL_TIMER_SCHED_CLOCK
 
 config SOC_DRA7XX
 	bool "TI DRA7XX"
-- 
2.5.0



From balbi at ti.com  Wed Aug 12 12:56:56 2015
From: balbi at ti.com (Felipe Balbi)
Date: Wed, 12 Aug 2015 14:56:56 -0500
Subject: [PATCH-next 4/4] arm: omap2: board-generic: use
 omap4_local_timer_init for AM437x
In-Reply-To: <1439409416-32673-1-git-send-email-balbi@ti.com>
References: <1439409416-32673-1-git-send-email-balbi@ti.com>
Message-ID: <1439409416-32673-5-git-send-email-balbi@ti.com>

AM437x-based boards, can use omap4_local_timer_init()
just fine. Let's use that instead.

Signed-off-by: Felipe Balbi <balbi at ti.com>
---
 arch/arm/mach-omap2/board-generic.c | 2 +-
 1 file changed, 1 insertion(+), 1 deletion(-)

diff --git a/arch/arm/mach-omap2/board-generic.c b/arch/arm/mach-omap2/board-generic.c
index 24c9afc9e8a7..89bf39663d61 100644
--- a/arch/arm/mach-omap2/board-generic.c
+++ b/arch/arm/mach-omap2/board-generic.c
@@ -279,7 +279,7 @@ DT_MACHINE_START(AM43_DT, "Generic AM43 (Flattened Device Tree)")
 	.init_late	= am43xx_init_late,
 	.init_irq	= omap_gic_of_init,
 	.init_machine	= omap_generic_init,
-	.init_time	= omap3_gptimer_timer_init,
+	.init_time	= omap4_local_timer_init,
 	.dt_compat	= am43_boards_compat,
 	.restart	= omap44xx_restart,
 MACHINE_END
-- 
2.5.0



From balbi at ti.com  Wed Aug 12 12:56:53 2015
From: balbi at ti.com (Felipe Balbi)
Date: Wed, 12 Aug 2015 14:56:53 -0500
Subject: [PATCH-next 1/4] Revert "ARM: 7655/1: smp_twd: make
 twd_local_timer_of_register() no-op for nosmp"
In-Reply-To: <1439409416-32673-1-git-send-email-balbi@ti.com>
References: <1439409416-32673-1-git-send-email-balbi@ti.com>
Message-ID: <1439409416-32673-2-git-send-email-balbi@ti.com>

This reverts commit 904464b91eca8c665acea033489225af02eeb75a.

The problem pointed out by commit 904464b91eca ("ARM: 7655/1:
smp_twd: make twd_local_timer_of_register() no-op for nosmp")
doesn't exist anymore.

We can safely boot with nosmp and the warning won't show up.

The other side benefit of this patch is that TWD has a chance
to probe on single-core A9 systems such as AM437x which sport
TWD.

Cc: Shawn Guo <shawn.guo at linaro.org>
Cc: Dirk Behme <dirk.behme at de.bosch.com>
Cc: Russell King <rmk+kernel at arm.linux.org.uk>
Acked-by: Tony Lindgren <tony at atomide.com>
Signed-off-by: Felipe Balbi <balbi at ti.com>
---
 arch/arm/kernel/smp_twd.c | 4 ----
 1 file changed, 4 deletions(-)

diff --git a/arch/arm/kernel/smp_twd.c b/arch/arm/kernel/smp_twd.c
index e9035cda1485..662ed88bc1f9 100644
--- a/arch/arm/kernel/smp_twd.c
+++ b/arch/arm/kernel/smp_twd.c
@@ -23,7 +23,6 @@
 #include <linux/of_irq.h>
 #include <linux/of_address.h>
 
-#include <asm/smp_plat.h>
 #include <asm/smp_twd.h>
 
 /* set up by the platform code */
@@ -392,9 +391,6 @@ static void __init twd_local_timer_of_register(struct device_node *np)
 {
 	int err;
 
-	if (!is_smp() || !setup_max_cpus)
-		return;
-
 	twd_ppi = irq_of_parse_and_map(np, 0);
 	if (!twd_ppi) {
 		err = -EINVAL;
-- 
2.5.0



From john.stultz at linaro.org  Wed Aug 12 13:00:04 2015
From: john.stultz at linaro.org (John Stultz)
Date: Wed, 12 Aug 2015 13:00:04 -0700
Subject: [PATCH v2] ARM: VDSO: fix coarse clock monotonicity regression
In-Reply-To: <1439221592-31875-1-git-send-email-nathan_lynch@mentor.com>
References: <1438999403-5770-1-git-send-email-nathan_lynch@mentor.com>
 <1439221592-31875-1-git-send-email-nathan_lynch@mentor.com>
Message-ID: <CALAqxLUxishMSb3A+PR_W0bSeFD9tWyETKM=Senk1_9A9GR2EA@mail.gmail.com>

On Mon, Aug 10, 2015 at 8:46 AM, Nathan Lynch <nathan_lynch at mentor.com> wrote:
> Since 906c55579a63 ("timekeeping: Copy the shadow-timekeeper over the
> real timekeeper last") it has become possible on ARM to:

Apologies I didn't catch that the core change caused a regression for
ARM. Though fixing the ARM vdso logic in this way is a good idea to
avoid future problems.


> - Obtain a CLOCK_MONOTONIC_COARSE or CLOCK_REALTIME_COARSE timestamp
>   via syscall.
> - Subsequently obtain a timestamp for the same clock ID via VDSO which
>   predates the first timestamp (by one jiffy).
>
> This is because ARM's update_vsyscall is deriving the coarse time
> using the __current_kernel_time interface, when it should really be
> using the timekeeper object provided to it by the timekeeping core.
> It happened to work before only because __current_kernel_time would
> access the same timekeeper object which had been passed to
> update_vsyscall.  This is no longer the case.
>
> Signed-off-by: Nathan Lynch <nathan_lynch at mentor.com>
> ---
>
> Changes since v1:
> - Add u32 cast to nsec calculation.
>
>  arch/arm/kernel/vdso.c | 7 +++----
>  1 file changed, 3 insertions(+), 4 deletions(-)
>
> diff --git a/arch/arm/kernel/vdso.c b/arch/arm/kernel/vdso.c
> index efe17dd9b921..54a5aeab988d 100644
> --- a/arch/arm/kernel/vdso.c
> +++ b/arch/arm/kernel/vdso.c
> @@ -296,7 +296,6 @@ static bool tk_is_cntvct(const struct timekeeper *tk)
>   */
>  void update_vsyscall(struct timekeeper *tk)
>  {
> -       struct timespec xtime_coarse;
>         struct timespec64 *wtm = &tk->wall_to_monotonic;
>
>         if (!cntvct_ok) {
> @@ -308,10 +307,10 @@ void update_vsyscall(struct timekeeper *tk)
>
>         vdso_write_begin(vdso_data);
>
> -       xtime_coarse = __current_kernel_time();
>         vdso_data->tk_is_cntvct                 = tk_is_cntvct(tk);
> -       vdso_data->xtime_coarse_sec             = xtime_coarse.tv_sec;
> -       vdso_data->xtime_coarse_nsec            = xtime_coarse.tv_nsec;
> +       vdso_data->xtime_coarse_sec             = tk->xtime_sec;
> +       vdso_data->xtime_coarse_nsec            = (u32)(tk->tkr_mono.xtime_nsec >>
> +                                                       tk->tkr_mono.shift);
>         vdso_data->wtm_clock_sec                = wtm->tv_sec;
>         vdso_data->wtm_clock_nsec               = wtm->tv_nsec;

Acked-by: John Stultz <john.stultz at linaro.org>

thanks
-john


From khilman at kernel.org  Wed Aug 12 13:12:21 2015
From: khilman at kernel.org (Kevin Hilman)
Date: Wed, 12 Aug 2015 13:12:21 -0700
Subject: [PATCH 3/9] PM / Domains: Support IRQ safe PM domains
In-Reply-To: <1438731339-58317-4-git-send-email-lina.iyer@linaro.org> (Lina
 Iyer's message of "Tue, 4 Aug 2015 17:35:33 -0600")
References: <1438731339-58317-1-git-send-email-lina.iyer@linaro.org>
 <1438731339-58317-4-git-send-email-lina.iyer@linaro.org>
Message-ID: <7hy4hgmfkq.fsf@deeprootsystems.com>

Lina Iyer <lina.iyer at linaro.org> writes:

> Generic Power Domains currently support turning on/off only in process
> context. This prevents the usage of PM domains for domains that could be
> powered on/off in a context where IRQs are disabled. Many such domains
> exist today and do not get powered off, when the IRQ safe devices in
> that domain are powered off, because of this limitation.
>
> However, not all domains can operate in IRQ safe contexts. Genpd
> therefore, has to support both cases where the domain may or may not
> operate in IRQ safe contexts. Configuring genpd to use an appropriate
> lock for that domain, would allow domains that have IRQ safe devices to
> runtime suspend and resume, in atomic context.
>
> To achieve domain specific locking, set the domain's ->flag to
> GENPD_FLAG_IRQ_SAFE while defining the domain. This indicates that genpd
> should use a spinlock instead of a mutex for locking the domain. Locking
> is abstracted through genpd_lock() and genpd_unlock() functions that use
> the flag to determine the appropriate lock to be used for that domain.
> Domains that have lower latency to suspend and resume and can operate
> with IRQs disabled may now be able to save power, when the component
> devices and sub-domains are idle at runtime.
>
> The restriction this imposes on the domain hierarchy is that sub-domains
> and all devices in the IRQ safe domain's hierarchy also have to be IRQ
> safe, so that we dont try to lock a mutex, while holding a spinlock.
> Non-IRQ safe domains may continue to have devices and sub-domains that
> may or may not be IRQ safe.
>
> Cc: Ulf Hansson <ulf.hansson at linaro.org>
> Cc: Kevin Hilman <khilman at linaro.org>
> Cc: Rafael J. Wysocki <rjw at rjwysocki.net>
> Cc: Geert Uytterhoeven <geert at linux-m68k.org>
> Cc: Krzysztof Koz?owski <k.kozlowski at samsung.com>
> Signed-off-by: Lina Iyer <lina.iyer at linaro.org>

Approach seems good to me, some cosmetic issues below...

> ---
>  Documentation/power/devices.txt |  11 ++-
>  drivers/base/power/domain.c     | 201 +++++++++++++++++++++++++++++++---------
>  include/linux/pm_domain.h       |  11 ++-
>  3 files changed, 178 insertions(+), 45 deletions(-)
>
> diff --git a/Documentation/power/devices.txt b/Documentation/power/devices.txt
> index 8ba6625..6d8318c 100644
> --- a/Documentation/power/devices.txt
> +++ b/Documentation/power/devices.txt
> @@ -607,7 +607,16 @@ individually.  Instead, a set of devices sharing a power resource can be put
>  into a low-power state together at the same time by turning off the shared
>  power resource.  Of course, they also need to be put into the full-power state
>  together, by turning the shared power resource on.  A set of devices with this
> -property is often referred to as a power domain.
> +property is often referred to as a power domain. A power domain may also be
> +nested inside another power domain.
> +
> +Devices, by default, operate in process context and if a device can operate in
> +IRQ safe context, has to be explicitly set as IRQ safe. Power domains by
> +default, operate in process context but could have devices that are IRQ safe.
> +Such power domains cannot be powered on/off during runtime PM. On the other
> +hand, an IRQ safe PM domain that can be powered on/off and suspend or resumed
> +in an atomic context, may contain IRQ safe devices. Such domains may only
> +contain IRQ safe devices or IRQ safe sub-domains.
>  
>  Support for power domains is provided through the pm_domain field of struct
>  device.  This field is a pointer to an object of type struct dev_pm_domain,
> diff --git a/drivers/base/power/domain.c b/drivers/base/power/domain.c
> index ef8d19f..221feb0 100644
> --- a/drivers/base/power/domain.c
> +++ b/drivers/base/power/domain.c
> @@ -53,6 +53,74 @@
>  static LIST_HEAD(gpd_list);
>  static DEFINE_MUTEX(gpd_list_lock);
>  
> +static inline int genpd_lock_noirq(struct generic_pm_domain *genpd,
> +					unsigned int subclass)

I don't like the _noirq naming, as in the context of suspend/resume,
that means no *device* IRQs, not no IRQs at all.  Maybe _atomic is
better, or _nosleep? or ...

> +	__acquires(&genpd->slock)
> +{
> +	unsigned long flags;
> +
> +	if (subclass > 0)
> +		spin_lock_irqsave_nested(&genpd->slock, flags, subclass);
> +	else
> +		spin_lock_irqsave(&genpd->slock, flags);
> +
> +	genpd->lock_flags = flags;
> +	return 0;
> +}
> +
> +static inline void genpd_unlock_noirq(struct generic_pm_domain *genpd)
> +	__releases(&genpd->slock)
> +{
> +	spin_unlock_irqrestore(&genpd->slock, genpd->lock_flags);
> +}
> +
> +static inline int genpd_lock_irq(struct generic_pm_domain *genpd,
> +					unsigned int subclass)
> +	__acquires(&genpd->mlock)
> +{
> +	if (subclass > 0)
> +		mutex_lock_nested(&genpd->mlock, subclass);
> +	else
> +		mutex_lock(&genpd->mlock);
> +	return 0;
> +}
> +
> +static inline int genpd_lock_interruptible_irq(struct generic_pm_domain *genpd)
> +	__acquires(&genpd->mlock)
> +{
> +	return mutex_lock_interruptible(&genpd->mlock);
> +}
> +
> +static inline void genpd_unlock_irq(struct generic_pm_domain *genpd)
> +	__releases(&genpd->mlock)
> +{
> +	mutex_unlock(&genpd->mlock);
> +}
> +
> +static inline int genpd_lock(struct generic_pm_domain *genpd)
> +{
> +	return genpd->irq_safe ? genpd_lock_noirq(genpd, 0)
> +			: genpd_lock_irq(genpd, 0);
> +}
> +
> +static inline int genpd_lock_nested(struct generic_pm_domain *genpd)
> +{
> +	return genpd->irq_safe ? genpd_lock_noirq(genpd, SINGLE_DEPTH_NESTING)
> +			: genpd_lock_irq(genpd, SINGLE_DEPTH_NESTING);
> +}
> +
> +static inline int genpd_lock_interruptible(struct generic_pm_domain *genpd)
> +{
> +	return genpd->irq_safe ? genpd_lock_noirq(genpd, 0)
> +			: genpd_lock_interruptible_irq(genpd);
> +}
> +
> +static inline void genpd_unlock(struct generic_pm_domain *genpd)
> +{
> +	return genpd->irq_safe ? genpd_unlock_noirq(genpd)
> +			: genpd_unlock_irq(genpd);
> +}
> +
>  static struct generic_pm_domain *pm_genpd_lookup_name(const char *domain_name)
>  {
>  	struct generic_pm_domain *genpd = NULL, *gpd;
> @@ -273,9 +341,9 @@ int pm_genpd_poweron(struct generic_pm_domain *genpd)
>  {
>  	int ret;
>  
> -	mutex_lock(&genpd->lock);
> +	genpd_lock(genpd);
>  	ret = __pm_genpd_poweron(genpd);
> -	mutex_unlock(&genpd->lock);
> +	genpd_unlock(genpd);
>  	return ret;
>  }
>  
> @@ -335,9 +403,9 @@ static int genpd_dev_pm_qos_notifier(struct notifier_block *nb,
>  		spin_unlock_irq(&dev->power.lock);
>  
>  		if (!IS_ERR(genpd)) {
> -			mutex_lock(&genpd->lock);
> +			genpd_lock(genpd);
>  			genpd->max_off_time_changed = true;
> -			mutex_unlock(&genpd->lock);
> +			genpd_unlock(genpd);
>  		}
>  
>  		dev = dev->parent;
> @@ -394,7 +462,13 @@ static int pm_genpd_poweroff(struct generic_pm_domain *genpd)
>  		if (stat > PM_QOS_FLAGS_NONE)
>  			return -EBUSY;
>  
> -		if (!pm_runtime_suspended(pdd->dev) || pdd->dev->power.irq_safe)
> +		/*
> +		 * We do not want to power off the domain if the device is
> +		 * not suspended or an IRQ safe device is part of this
> +		 * non-IRQ safe domain.
> +		 */
> +		if (!pm_runtime_suspended(pdd->dev) ||
> +			(pdd->dev->power.irq_safe && !genpd->irq_safe))
>  			not_suspended++;

The !irq_safe check should maybe spit a warning via WARN_ONCE(), as this
would be useful in debugging domains that are not shutting down.

>  	}
>  
> @@ -460,9 +534,9 @@ static void genpd_power_off_work_fn(struct work_struct *work)
>  
>  	genpd = container_of(work, struct generic_pm_domain, power_off_work);
>  
> -	mutex_lock(&genpd->lock);
> +	genpd_lock(genpd);
>  	pm_genpd_poweroff(genpd);
> -	mutex_unlock(&genpd->lock);
> +	genpd_unlock(genpd);
>  }
>  
>  /**
> @@ -500,17 +574,19 @@ static int pm_genpd_runtime_suspend(struct device *dev)
>  	}
>  
>  	/*
> -	 * If power.irq_safe is set, this routine will be run with interrupts
> -	 * off, so it can't use mutexes.
> +	 * If power.irq_safe is set, this routine may be run with
> +	 * IRQ disabled, so suspend only if the power domain is
> +	 * irq_safe.
>  	 */
> -	if (dev->power.irq_safe)
> +	if (dev->power.irq_safe && !genpd->irq_safe)
>  		return 0;

Similarily, a WARN_ONCE() will probably be helpful here.

> -	mutex_lock(&genpd->lock);
> +	genpd_lock(genpd);
> +
>  	genpd->in_progress++;
>  	pm_genpd_poweroff(genpd);
>  	genpd->in_progress--;
> -	mutex_unlock(&genpd->lock);
> +	genpd_unlock(genpd);
>  
>  	return 0;
>  }
> @@ -535,15 +611,18 @@ static int pm_genpd_runtime_resume(struct device *dev)
>  	if (IS_ERR(genpd))
>  		return -EINVAL;
>  
> -	/* If power.irq_safe, the PM domain is never powered off. */
> -	if (dev->power.irq_safe) {
> +	/*
> +	 * As we dont power off a non IRQ safe domain, which holds
> +	 * an IRQ safe device, we dont need to restore power to it.
> +	 */
> +	if (dev->power.irq_safe && !genpd->irq_safe) {
>  		timed = false;
>  		goto out;
>  	}
>  
> -	mutex_lock(&genpd->lock);
> +	genpd_lock(genpd);
>  	ret = __pm_genpd_poweron(genpd);
> -	mutex_unlock(&genpd->lock);
> +	genpd_unlock(genpd);
>  
>  	if (ret)
>  		return ret;
> @@ -743,14 +822,14 @@ static int pm_genpd_prepare(struct device *dev)
>  	if (resume_needed(dev, genpd))
>  		pm_runtime_resume(dev);
>  
> -	mutex_lock(&genpd->lock);
> +	genpd_lock(genpd);
>  
>  	if (genpd->prepared_count++ == 0) {
>  		genpd->suspended_count = 0;
>  		genpd->suspend_power_off = genpd->status == GPD_STATE_POWER_OFF;
>  	}
>  
> -	mutex_unlock(&genpd->lock);
> +	genpd_unlock(genpd);
>  
>  	if (genpd->suspend_power_off) {
>  		pm_runtime_put_noidle(dev);
> @@ -768,12 +847,12 @@ static int pm_genpd_prepare(struct device *dev)
>  
>  	ret = pm_generic_prepare(dev);
>  	if (ret) {
> -		mutex_lock(&genpd->lock);
> +		genpd_lock(genpd);
>  
>  		if (--genpd->prepared_count == 0)
>  			genpd->suspend_power_off = false;
>  
> -		mutex_unlock(&genpd->lock);
> +		genpd_unlock(genpd);
>  		pm_runtime_enable(dev);
>  	}
>  
> @@ -1130,13 +1209,13 @@ static void pm_genpd_complete(struct device *dev)
>  	if (IS_ERR(genpd))
>  		return;
>  
> -	mutex_lock(&genpd->lock);
> +	genpd_lock(genpd);
>  
>  	run_complete = !genpd->suspend_power_off;
>  	if (--genpd->prepared_count == 0)
>  		genpd->suspend_power_off = false;
>  
> -	mutex_unlock(&genpd->lock);
> +	genpd_unlock(genpd);
>  
>  	if (run_complete) {
>  		pm_generic_complete(dev);
> @@ -1280,11 +1359,17 @@ int __pm_genpd_add_device(struct generic_pm_domain *genpd, struct device *dev,
>  	if (IS_ERR_OR_NULL(genpd) || IS_ERR_OR_NULL(dev))
>  		return -EINVAL;
>  
> +	if (genpd->irq_safe && !dev->power.irq_safe) {
> +		dev_err(dev,
> +			"Devices in an IRQ safe domain have to be IRQ safe.\n");

This should also dump the PM domain, something like:

            dev_err(dev, "PM domain %s is IRQ safe; device has to be IRQ safe.\n")

> +		return -EINVAL;
> +	}
> +
>  	gpd_data = genpd_alloc_dev_data(dev, genpd, td);
>  	if (IS_ERR(gpd_data))
>  		return PTR_ERR(gpd_data);
>  
> -	mutex_lock(&genpd->lock);
> +	genpd_lock(genpd);
>  
>  	if (genpd->prepared_count > 0) {
>  		ret = -EAGAIN;
> @@ -1301,7 +1386,7 @@ int __pm_genpd_add_device(struct generic_pm_domain *genpd, struct device *dev,
>  	list_add_tail(&gpd_data->base.list_node, &genpd->dev_list);
>  
>   out:
> -	mutex_unlock(&genpd->lock);
> +	genpd_unlock(genpd);
>  
>  	if (ret)
>  		genpd_free_dev_data(dev, gpd_data);
> @@ -1345,7 +1430,7 @@ int pm_genpd_remove_device(struct generic_pm_domain *genpd,
>  	gpd_data = to_gpd_data(pdd);
>  	dev_pm_qos_remove_notifier(dev, &gpd_data->nb);
>  
> -	mutex_lock(&genpd->lock);
> +	genpd_lock(genpd);
>  
>  	if (genpd->prepared_count > 0) {
>  		ret = -EAGAIN;
> @@ -1360,14 +1445,14 @@ int pm_genpd_remove_device(struct generic_pm_domain *genpd,
>  
>  	list_del_init(&pdd->list_node);
>  
> -	mutex_unlock(&genpd->lock);
> +	genpd_unlock(genpd);
>  
>  	genpd_free_dev_data(dev, gpd_data);
>  
>  	return 0;
>  
>   out:
> -	mutex_unlock(&genpd->lock);
> +	genpd_unlock(genpd);
>  	dev_pm_qos_add_notifier(dev, &gpd_data->nb);
>  
>  	return ret;
> @@ -1388,12 +1473,24 @@ int pm_genpd_add_subdomain(struct generic_pm_domain *genpd,
>  	    || genpd == subdomain)
>  		return -EINVAL;
>  
> +	/*
> +	 * If the domain can be powered on/off in an IRQ safe
> +	 * context, ensure that the subdomain can also be
> +	 * powered on/off in that context.
> +	 */
> +	if (genpd->irq_safe && !subdomain->irq_safe) {
> +		WARN("Sub-domain (%s) in an IRQ-safe domain (%s)"
> +				"have to be IRQ safe\n",

s/have/has/

> +				subdomain->name, genpd->name);
> +		return -EINVAL;
> +	}
> +

Kevin


From knaack.h at gmx.de  Wed Aug 12 13:12:22 2015
From: knaack.h at gmx.de (Hartmut Knaack)
Date: Wed, 12 Aug 2015 22:12:22 +0200
Subject: [PATCH 01/20] regmap: Add missing comments about struct regmap_bus
In-Reply-To: <1439374365-20623-2-git-send-email-mpa@pengutronix.de>
References: <1439374365-20623-1-git-send-email-mpa@pengutronix.de>
 <1439374365-20623-2-git-send-email-mpa@pengutronix.de>
Message-ID: <55CBA8A6.7020404@gmx.de>

Markus Pargmann schrieb am 12.08.2015 um 12:12:
> There are some fields of this struct undocumented or old. This patch
> updates the missing comments.
> 
> Signed-off-by: Markus Pargmann <mpa at pengutronix.de>
> ---
>  include/linux/regmap.h | 4 +++-
>  1 file changed, 3 insertions(+), 1 deletion(-)
> 
> diff --git a/include/linux/regmap.h b/include/linux/regmap.h
> index 59c55ea0f0b5..6ff83c9ddb45 100644
> --- a/include/linux/regmap.h
> +++ b/include/linux/regmap.h
> @@ -296,8 +296,11 @@ typedef void (*regmap_hw_free_context)(void *context);
>   *                if not implemented  on a given device.
>   * @async_write: Write operation which completes asynchronously, optional and
>   *               must serialise with respect to non-async I/O.
> + * @reg_write: Write operation for a register. Writes value to register.
>   * @read: Read operation.  Data is returned in the buffer used to transmit
>   *         data.
> + * @reg_read: Read operation for a register. Reads a value from a register.
> + * @free_conetext: Free context.

Typo: free_context

>   * @async_alloc: Allocate a regmap_async() structure.
>   * @read_flag_mask: Mask to be set in the top byte of the register when doing
>   *                  a read.
> @@ -307,7 +310,6 @@ typedef void (*regmap_hw_free_context)(void *context);
>   * @val_format_endian_default: Default endianness for formatted register
>   *     values. Used when the regmap_config specifies DEFAULT. If this is
>   *     DEFAULT, BIG is assumed.
> - * @async_size: Size of struct used for async work.
>   */
>  struct regmap_bus {
>  	bool fast_io;
> 



From khilman at kernel.org  Wed Aug 12 13:13:15 2015
From: khilman at kernel.org (Kevin Hilman)
Date: Wed, 12 Aug 2015 13:13:15 -0700
Subject: [PATCH 4/9] kernel/cpu_pm: fix cpu_cluster_pm_exit comment
In-Reply-To: <1438731339-58317-5-git-send-email-lina.iyer@linaro.org> (Lina
 Iyer's message of "Tue, 4 Aug 2015 17:35:34 -0600")
References: <1438731339-58317-1-git-send-email-lina.iyer@linaro.org>
 <1438731339-58317-5-git-send-email-lina.iyer@linaro.org>
Message-ID: <7htws4mfj8.fsf@deeprootsystems.com>

Lina Iyer <lina.iyer at linaro.org> writes:

> cpu_cluster_pm_exit() must be sent after cpu_cluster_pm_enter() has been
> sent for the cluster and before any cpu_pm_exit() notifications are sent
> for any CPU.
>
> Cc: Nicolas Pitre <nicolas.pitre at linaro.org>
> Signed-off-by: Lina Iyer <lina.iyer at linaro.org>

Acked-by: Kevin Hilman <khilman at linaro.org>

> ---
>  kernel/cpu_pm.c | 2 +-
>  1 file changed, 1 insertion(+), 1 deletion(-)
>
> diff --git a/kernel/cpu_pm.c b/kernel/cpu_pm.c
> index 9656a3c..009cc9a 100644
> --- a/kernel/cpu_pm.c
> +++ b/kernel/cpu_pm.c
> @@ -180,7 +180,7 @@ EXPORT_SYMBOL_GPL(cpu_cluster_pm_enter);
>   * low power state that may have caused some blocks in the same power domain
>   * to reset.
>   *
> - * Must be called after cpu_pm_exit has been called on all cpus in the power
> + * Must be called after cpu_cluster_pm_enter has been called for the power
>   * domain, and before cpu_pm_exit has been called on any cpu in the power
>   * domain. Notified drivers can include VFP co-processor, interrupt controller
>   * and its PM extensions, local CPU timers context save/restore which


From mchehab at osg.samsung.com  Wed Aug 12 13:14:54 2015
From: mchehab at osg.samsung.com (Mauro Carvalho Chehab)
Date: Wed, 12 Aug 2015 17:14:54 -0300
Subject: [PATCH RFC v3 10/16] media: rename link source/sink to
 pad0_source/pad1_sink
In-Reply-To: <cover.1439410053.git.mchehab@osg.samsung.com>
References: <cover.1439410053.git.mchehab@osg.samsung.com>
Message-ID: <30472f0a7f52ee834978c70cbecc5c035ce20f71.1439410053.git.mchehab@osg.samsung.com>

Change the internal namespace for links between two pads to
have the "pad" there.

We're also numbering it, as a common constructor is to do
things like:

 	if (link->port1.type != MEDIA_GRAPH_PAD)
 		continue;
 	if (link->pad1_sink->entity == entity)
		/* do something */

by preserving the number, we keep consistency between
port1 and pad1_sink, and port0 and pad0_source.

This was generated via this script:
	for i in $(find drivers/media -name '*.[ch]' -type f) $(find drivers/staging/media -name '*.[ch]' -type f) $(find include/ -name '*.h' -type f) ; do sed "s,link->sink,link->pad1_sink,g; s,link->source,link->pad0_source,g;" <$i >a && mv a $i; done

Signed-off-by: Mauro Carvalho Chehab <mchehab at osg.samsung.com>

diff --git a/drivers/media/dvb-core/dvb_frontend.c b/drivers/media/dvb-core/dvb_frontend.c
index 3c97ebdf9f2a..e673f6f7c398 100644
--- a/drivers/media/dvb-core/dvb_frontend.c
+++ b/drivers/media/dvb-core/dvb_frontend.c
@@ -637,7 +637,7 @@ static int dvb_enable_media_tuner(struct dvb_frontend *fe)
 		link = &entity->links[i];
 		if (link->port1.type != MEDIA_GRAPH_PAD)
 			continue;
-		if (link->sink->entity == entity) {
+		if (link->pad1_sink->entity == entity) {
 			found_link = link;
 			n_links++;
 			if (link->flags & MEDIA_LNK_FL_ENABLED)
@@ -660,7 +660,7 @@ static int dvb_enable_media_tuner(struct dvb_frontend *fe)
 		return -EINVAL;
 	}
 
-	source = found_link->source->entity;
+	source = found_link->pad0_source->entity;
 	fepriv->pipe_start_entity = source;
 	for (i = 0; i < source->num_links; i++) {
 		struct media_entity *sink;
@@ -669,7 +669,7 @@ static int dvb_enable_media_tuner(struct dvb_frontend *fe)
 		link = &source->links[i];
 		if (link->port1.type != MEDIA_GRAPH_PAD)
 			continue;
-		sink = link->sink->entity;
+		sink = link->pad1_sink->entity;
 
 		if (sink == entity)
 			flags = MEDIA_LNK_FL_ENABLED;
diff --git a/drivers/media/media-device.c b/drivers/media/media-device.c
index b4bd718ad736..2c29c4600c3a 100644
--- a/drivers/media/media-device.c
+++ b/drivers/media/media-device.c
@@ -160,13 +160,13 @@ static long __media_device_enum_links(struct media_device *mdev,
 			    ent_link->port1->type != MEDIA_GRAPH_PAD)
 				continue;
 			/* Ignore backlinks. */
-			if (ent_link->source->entity != entity)
+			if (ent_link->pad0_source->entity != entity)
 				continue;
 
 			memset(&link, 0, sizeof(link));
-			media_device_kpad_to_upad(ent_link->source,
+			media_device_kpad_to_upad(ent_link->pad0_source,
 						  &link.source);
-			media_device_kpad_to_upad(ent_link->sink,
+			media_device_kpad_to_upad(ent_link->pad1_sink,
 						  &link.sink);
 			link.flags = ent_link->flags;
 			if (copy_to_user(ulink, &link, sizeof(*ulink)))
diff --git a/drivers/media/media-entity.c b/drivers/media/media-entity.c
index fc2e4886c830..aafa1119fba7 100644
--- a/drivers/media/media-entity.c
+++ b/drivers/media/media-entity.c
@@ -125,10 +125,10 @@ media_entity_other(struct media_entity *entity, struct media_link *link)
 	if (link->port0->type != MEDIA_GRAPH_PAD ||
 	    link->port1->type != MEDIA_GRAPH_PAD)
 		return NULL;
-	if (link->source->entity == entity)
-		return link->sink->entity;
+	if (link->pad0_source->entity == entity)
+		return link->pad1_sink->entity;
 	else
-		return link->source->entity;
+		return link->pad0_source->entity;
 }
 
 /* push an entity to traversal stack */
@@ -299,8 +299,8 @@ __must_check int media_entity_pipeline_start(struct media_entity *entity,
 			if (link->port0->type != MEDIA_GRAPH_PAD)
 				continue;
 
-			pad = link->sink->entity == entity
-				? link->sink : link->source;
+			pad = link->pad1_sink->entity == entity
+				? link->pad1_sink : link->pad0_source;
 
 			/* Mark that a pad is connected by a link. */
 			bitmap_clear(has_no_links, pad->index, 1);
@@ -318,7 +318,7 @@ __must_check int media_entity_pipeline_start(struct media_entity *entity,
 			 * Link validation will only take place for
 			 * sink ends of the link that are enabled.
 			 */
-			if (link->sink != pad ||
+			if (link->pad1_sink != pad ||
 			    !(link->flags & MEDIA_LNK_FL_ENABLED))
 				continue;
 
@@ -326,9 +326,9 @@ __must_check int media_entity_pipeline_start(struct media_entity *entity,
 			if (ret < 0 && ret != -ENOIOCTLCMD) {
 				dev_dbg(entity->parent->dev,
 					"link validation failed for \"%s\":%u -> \"%s\":%u, error %d\n",
-					entity->name, link->source->index,
-					link->sink->entity->name,
-					link->sink->index, ret);
+					entity->name, link->pad0_source->index,
+					link->pad1_sink->entity->name,
+					link->pad1_sink->index, ret);
 				goto error;
 			}
 		}
@@ -493,8 +493,8 @@ media_entity_create_link(struct media_entity *source, u16 source_pad,
 	if (link == NULL)
 		return -ENOMEM;
 
-	link->source = &source->pads[source_pad];
-	link->sink = &sink->pads[sink_pad];
+	link->pad0_source = &source->pads[source_pad];
+	link->pad1_sink = &sink->pads[sink_pad];
 	link->flags = flags;
 
 	/* Create the backlink. Backlinks are used to help graph traversal and
@@ -506,8 +506,8 @@ media_entity_create_link(struct media_entity *source, u16 source_pad,
 		return -ENOMEM;
 	}
 
-	backlink->source = &source->pads[source_pad];
-	backlink->sink = &sink->pads[sink_pad];
+	backlink->pad0_source = &source->pads[source_pad];
+	backlink->pad1_sink = &sink->pads[sink_pad];
 	backlink->flags = flags;
 
 	link->reverse = backlink;
@@ -526,10 +526,10 @@ static void __media_entity_remove_link(struct media_entity *entity,
 	struct media_entity *remote;
 	unsigned int r = 0;
 
-	if (link->source->entity == entity)
-		remote = link->sink->entity;
+	if (link->pad0_source->entity == entity)
+		remote = link->pad1_sink->entity;
 	else
-		remote = link->source->entity;
+		remote = link->pad0_source->entity;
 
 	list_for_each_entry_safe(rlink, tmp, &remote->links, list) {
 		if (rlink != link->reverse) {
@@ -537,7 +537,7 @@ static void __media_entity_remove_link(struct media_entity *entity,
 			continue;
 		}
 
-		if (link->source->entity == entity)
+		if (link->pad0_source->entity == entity)
 			remote->num_backlinks--;
 
 		if (--remote->num_links == 0)
@@ -580,16 +580,16 @@ static int __media_entity_setup_link_notify(struct media_link *link, u32 flags)
 	int ret;
 
 	/* Notify both entities. */
-	ret = media_entity_call(link->source->entity, link_setup,
-				link->source, link->sink, flags);
+	ret = media_entity_call(link->pad0_source->entity, link_setup,
+				link->pad0_source, link->pad1_sink, flags);
 	if (ret < 0 && ret != -ENOIOCTLCMD)
 		return ret;
 
-	ret = media_entity_call(link->sink->entity, link_setup,
-				link->sink, link->source, flags);
+	ret = media_entity_call(link->pad1_sink->entity, link_setup,
+				link->pad1_sink, link->pad0_source, flags);
 	if (ret < 0 && ret != -ENOIOCTLCMD) {
-		media_entity_call(link->source->entity, link_setup,
-				  link->source, link->sink, link->flags);
+		media_entity_call(link->pad0_source->entity, link_setup,
+				  link->pad0_source, link->pad1_sink, link->flags);
 		return ret;
 	}
 
@@ -610,7 +610,7 @@ static int __media_entity_setup_link_notify(struct media_link *link, u32 flags)
  * If the link is immutable or if the current and new configuration are
  * identical, return immediately.
  *
- * The user is expected to hold link->source->parent->mutex. If not,
+ * The user is expected to hold link->pad0_source->parent->mutex. If not,
  * media_entity_setup_link() should be used instead.
  */
 int __media_entity_setup_link(struct media_link *link, u32 flags)
@@ -633,8 +633,8 @@ int __media_entity_setup_link(struct media_link *link, u32 flags)
 	if (link->flags == flags)
 		return 0;
 
-	source = link->source->entity;
-	sink = link->sink->entity;
+	source = link->pad0_source->entity;
+	sink = link->pad1_sink->entity;
 
 	if (!(link->flags & MEDIA_LNK_FL_DYNAMIC) &&
 	    (source->stream_count || sink->stream_count))
@@ -661,9 +661,9 @@ int media_entity_setup_link(struct media_link *link, u32 flags)
 {
 	int ret;
 
-	mutex_lock(&link->source->entity->parent->graph_mutex);
+	mutex_lock(&link->pad0_source->entity->parent->graph_mutex);
 	ret = __media_entity_setup_link(link, flags);
-	mutex_unlock(&link->source->entity->parent->graph_mutex);
+	mutex_unlock(&link->pad0_source->entity->parent->graph_mutex);
 
 	return ret;
 }
@@ -683,10 +683,10 @@ media_entity_find_link(struct media_pad *source, struct media_pad *sink)
 	struct media_link *link;
 
 	list_for_each_entry(link, &source->entity->links, list) {
-		if (link->source->entity == source->entity &&
-		    link->source->index == source->index &&
-		    link->sink->entity == sink->entity &&
-		    link->sink->index == sink->index)
+		if (link->pad0_source->entity == source->entity &&
+		    link->pad0_source->index == source->index &&
+		    link->pad1_sink->entity == sink->entity &&
+		    link->pad1_sink->index == sink->index)
 			return link;
 	}
 
@@ -712,11 +712,11 @@ struct media_pad *media_entity_remote_pad(struct media_pad *pad)
 		if (!(link->flags & MEDIA_LNK_FL_ENABLED))
 			continue;
 
-		if (link->source == pad)
-			return link->sink;
+		if (link->pad0_source == pad)
+			return link->pad1_sink;
 
-		if (link->sink == pad)
-			return link->source;
+		if (link->pad1_sink == pad)
+			return link->pad0_source;
 	}
 
 	return NULL;
diff --git a/drivers/media/platform/exynos4-is/media-dev.c b/drivers/media/platform/exynos4-is/media-dev.c
index 4f5586a4cbff..3cafcf85cafc 100644
--- a/drivers/media/platform/exynos4-is/media-dev.c
+++ b/drivers/media/platform/exynos4-is/media-dev.c
@@ -1091,7 +1091,7 @@ static int __fimc_md_modify_pipelines(struct media_entity *entity, bool enable)
 static int fimc_md_link_notify(struct media_link *link, unsigned int flags,
 				unsigned int notification)
 {
-	struct media_entity *sink = link->sink->entity;
+	struct media_entity *sink = link->pad1_sink->entity;
 	int ret = 0;
 
 	/* Before link disconnection */
diff --git a/drivers/media/platform/omap3isp/isp.c b/drivers/media/platform/omap3isp/isp.c
index 12be830d704f..cbd22a422bd3 100644
--- a/drivers/media/platform/omap3isp/isp.c
+++ b/drivers/media/platform/omap3isp/isp.c
@@ -822,8 +822,8 @@ int omap3isp_pipeline_pm_use(struct media_entity *entity, int use)
 static int isp_pipeline_link_notify(struct media_link *link, u32 flags,
 				    unsigned int notification)
 {
-	struct media_entity *source = link->source->entity;
-	struct media_entity *sink = link->sink->entity;
+	struct media_entity *source = link->pad0_source->entity;
+	struct media_entity *sink = link->pad1_sink->entity;
 	int source_use = isp_pipeline_pm_use_count(source);
 	int sink_use = isp_pipeline_pm_use_count(sink);
 	int ret;
diff --git a/drivers/media/platform/omap3isp/ispccdc.c b/drivers/media/platform/omap3isp/ispccdc.c
index 3b10304b580b..cb236b54d770 100644
--- a/drivers/media/platform/omap3isp/ispccdc.c
+++ b/drivers/media/platform/omap3isp/ispccdc.c
@@ -2419,7 +2419,7 @@ static int ccdc_link_validate(struct v4l2_subdev *sd,
 	if (ccdc->input == CCDC_INPUT_PARALLEL) {
 		struct isp_parallel_cfg *parcfg =
 			&((struct isp_bus_cfg *)
-			  media_entity_to_v4l2_subdev(link->source->entity)
+			  media_entity_to_v4l2_subdev(link->pad0_source->entity)
 			  ->host_priv)->bus.parallel;
 		parallel_shift = parcfg->data_lane_shift * 2;
 	} else {
diff --git a/drivers/media/usb/cx231xx/cx231xx-video.c b/drivers/media/usb/cx231xx/cx231xx-video.c
index e8baff4d6290..9416a8b7d575 100644
--- a/drivers/media/usb/cx231xx/cx231xx-video.c
+++ b/drivers/media/usb/cx231xx/cx231xx-video.c
@@ -128,7 +128,7 @@ static int cx231xx_enable_analog_tuner(struct cx231xx *dev)
 		return 0;
 
 	list_for_each_entry(link, &decoder->links, list) {
-		if (link->sink->entity == decoder) {
+		if (link->pad1_sink->entity == decoder) {
 			found_link = link;
 			if (link->flags & MEDIA_LNK_FL_ENABLED)
 				active_links++;
@@ -139,12 +139,12 @@ static int cx231xx_enable_analog_tuner(struct cx231xx *dev)
 	if (active_links == 1 || !found_link)
 		return 0;
 
-	source = found_link->source->entity;
+	source = found_link->pad0_source->entity;
 	list_for_each_entry(link, &source->links, list) {
 		struct media_entity *sink;
 		int flags = 0;
 
-		sink = link->sink->entity;
+		sink = link->pad1_sink->entity;
 
 		if (sink == entity)
 			flags = MEDIA_LNK_FL_ENABLED;
diff --git a/drivers/media/v4l2-core/v4l2-subdev.c b/drivers/media/v4l2-core/v4l2-subdev.c
index 83615b8fb46a..53729ccdea80 100644
--- a/drivers/media/v4l2-core/v4l2-subdev.c
+++ b/drivers/media/v4l2-core/v4l2-subdev.c
@@ -549,16 +549,16 @@ int v4l2_subdev_link_validate(struct media_link *link)
 	int rval;
 
 	rval = v4l2_subdev_link_validate_get_format(
-		link->source, &source_fmt);
+		link->pad0_source, &source_fmt);
 	if (rval < 0)
 		return 0;
 
 	rval = v4l2_subdev_link_validate_get_format(
-		link->sink, &sink_fmt);
+		link->pad1_sink, &sink_fmt);
 	if (rval < 0)
 		return 0;
 
-	sink = media_entity_to_v4l2_subdev(link->sink->entity);
+	sink = media_entity_to_v4l2_subdev(link->pad1_sink->entity);
 
 	rval = v4l2_subdev_call(sink, pad, link_validate, link,
 				&source_fmt, &sink_fmt);
diff --git a/drivers/staging/media/omap4iss/iss.c b/drivers/staging/media/omap4iss/iss.c
index 9bfb725b9986..37694999d189 100644
--- a/drivers/staging/media/omap4iss/iss.c
+++ b/drivers/staging/media/omap4iss/iss.c
@@ -140,9 +140,9 @@ int omap4iss_get_external_info(struct iss_pipeline *pipe,
 
 	memset(&fmt, 0, sizeof(fmt));
 
-	fmt.pad = link->source->index;
+	fmt.pad = link->pad0_source->index;
 	fmt.which = V4L2_SUBDEV_FORMAT_ACTIVE;
-	ret = v4l2_subdev_call(media_entity_to_v4l2_subdev(link->sink->entity),
+	ret = v4l2_subdev_call(media_entity_to_v4l2_subdev(link->pad1_sink->entity),
 			       pad, get_fmt, NULL, &fmt);
 	if (ret < 0)
 		return -EPIPE;
@@ -526,8 +526,8 @@ int omap4iss_pipeline_pm_use(struct media_entity *entity, int use)
 static int iss_pipeline_link_notify(struct media_link *link, u32 flags,
 				    unsigned int notification)
 {
-	struct media_entity *source = link->source->entity;
-	struct media_entity *sink = link->sink->entity;
+	struct media_entity *source = link->pad0_source->entity;
+	struct media_entity *sink = link->pad1_sink->entity;
 	int source_use = iss_pipeline_pm_use_count(source);
 	int sink_use = iss_pipeline_pm_use_count(sink);
 	int ret;
diff --git a/drivers/staging/media/omap4iss/iss_csi2.c b/drivers/staging/media/omap4iss/iss_csi2.c
index e936cfc218cb..e39f1bbbdae1 100644
--- a/drivers/staging/media/omap4iss/iss_csi2.c
+++ b/drivers/staging/media/omap4iss/iss_csi2.c
@@ -1026,7 +1026,7 @@ static int csi2_link_validate(struct v4l2_subdev *sd, struct media_link *link,
 	struct iss_pipeline *pipe = to_iss_pipeline(&csi2->subdev.entity);
 	int rval;
 
-	pipe->external = media_entity_to_v4l2_subdev(link->source->entity);
+	pipe->external = media_entity_to_v4l2_subdev(link->pad0_source->entity);
 	rval = omap4iss_get_external_info(pipe, link);
 	if (rval < 0)
 		return rval;
diff --git a/include/media/media-entity.h b/include/media/media-entity.h
index a6464499902e..412cf5d00315 100644
--- a/include/media/media-entity.h
+++ b/include/media/media-entity.h
@@ -87,12 +87,12 @@ struct media_link {
 	enum media_graph_link_dir	dir;
 	union {
 		struct media_graph_obj *port0;
-		struct media_pad *source;
+		struct media_pad *pad0_source;
 		struct media_interface *port0_intf;
 	};
 	union {
 		struct media_graph_obj *port1;
-		struct media_pad *sink;
+		struct media_pad *pad1_sink;
 		struct media_entity *port1_entity;
 	};
 	struct media_link *reverse;	/* Link in the reverse direction */
-- 
2.4.3



From mchehab at osg.samsung.com  Wed Aug 12 13:14:55 2015
From: mchehab at osg.samsung.com (Mauro Carvalho Chehab)
Date: Wed, 12 Aug 2015 17:14:55 -0300
Subject: [PATCH RFC v3 11/16] media: rename the function that create pad links
In-Reply-To: <cover.1439410053.git.mchehab@osg.samsung.com>
References: <cover.1439410053.git.mchehab@osg.samsung.com>
Message-ID: <a83a3cdb48e7c8be67c0eb22d61f47f1d6d2eb28.1439410053.git.mchehab@osg.samsung.com>

Now that a link can be either between two different graph
objects, we'll need to add more functions to create links.
So, rename the existing one that create links only between
two pads as media_create_pad_link().

No functional changes.

This patch was created via this shell script:
	for i in $(find drivers/media -name '*.[ch]' -type f) $(find drivers/staging/media -name '*.[ch]' -type f) $(find include/ -name '*.h' -type f) ; do sed s,media_entity_create_link,media_create_pad_link,g <$i >a && mv a $i; done

Signed-off-by: Mauro Carvalho Chehab <mchehab at osg.samsung.com>

diff --git a/drivers/media/dvb-core/dvbdev.c b/drivers/media/dvb-core/dvbdev.c
index 2fdcbb5f000a..65f59f2124b4 100644
--- a/drivers/media/dvb-core/dvbdev.c
+++ b/drivers/media/dvb-core/dvbdev.c
@@ -412,16 +412,16 @@ void dvb_create_media_graph(struct dvb_adapter *adap)
 	}
 
 	if (tuner && fe)
-		media_entity_create_link(tuner, 0, fe, 0, 0);
+		media_create_pad_link(tuner, 0, fe, 0, 0);
 
 	if (fe && demux)
-		media_entity_create_link(fe, 1, demux, 0, MEDIA_LNK_FL_ENABLED);
+		media_create_pad_link(fe, 1, demux, 0, MEDIA_LNK_FL_ENABLED);
 
 	if (demux && dvr)
-		media_entity_create_link(demux, 1, dvr, 0, MEDIA_LNK_FL_ENABLED);
+		media_create_pad_link(demux, 1, dvr, 0, MEDIA_LNK_FL_ENABLED);
 
 	if (demux && ca)
-		media_entity_create_link(demux, 1, ca, 0, MEDIA_LNK_FL_ENABLED);
+		media_create_pad_link(demux, 1, ca, 0, MEDIA_LNK_FL_ENABLED);
 }
 EXPORT_SYMBOL_GPL(dvb_create_media_graph);
 #endif
diff --git a/drivers/media/i2c/s5c73m3/s5c73m3-core.c b/drivers/media/i2c/s5c73m3/s5c73m3-core.c
index 6d167428727d..c81bfbfea32f 100644
--- a/drivers/media/i2c/s5c73m3/s5c73m3-core.c
+++ b/drivers/media/i2c/s5c73m3/s5c73m3-core.c
@@ -1482,11 +1482,11 @@ static int s5c73m3_oif_registered(struct v4l2_subdev *sd)
 		return ret;
 	}
 
-	ret = media_entity_create_link(&state->sensor_sd.entity,
+	ret = media_create_pad_link(&state->sensor_sd.entity,
 			S5C73M3_ISP_PAD, &state->oif_sd.entity, OIF_ISP_PAD,
 			MEDIA_LNK_FL_IMMUTABLE | MEDIA_LNK_FL_ENABLED);
 
-	ret = media_entity_create_link(&state->sensor_sd.entity,
+	ret = media_create_pad_link(&state->sensor_sd.entity,
 			S5C73M3_JPEG_PAD, &state->oif_sd.entity, OIF_JPEG_PAD,
 			MEDIA_LNK_FL_IMMUTABLE | MEDIA_LNK_FL_ENABLED);
 
diff --git a/drivers/media/i2c/s5k5baf.c b/drivers/media/i2c/s5k5baf.c
index 30a9ca62e034..d3bff30bcb6f 100644
--- a/drivers/media/i2c/s5k5baf.c
+++ b/drivers/media/i2c/s5k5baf.c
@@ -1756,7 +1756,7 @@ static int s5k5baf_registered(struct v4l2_subdev *sd)
 		v4l2_err(sd, "failed to register subdev %s\n",
 			 state->cis_sd.name);
 	else
-		ret = media_entity_create_link(&state->cis_sd.entity, PAD_CIS,
+		ret = media_create_pad_link(&state->cis_sd.entity, PAD_CIS,
 					       &state->sd.entity, PAD_CIS,
 					       MEDIA_LNK_FL_IMMUTABLE |
 					       MEDIA_LNK_FL_ENABLED);
diff --git a/drivers/media/i2c/smiapp/smiapp-core.c b/drivers/media/i2c/smiapp/smiapp-core.c
index 308613ea0aed..5aa49eb393a9 100644
--- a/drivers/media/i2c/smiapp/smiapp-core.c
+++ b/drivers/media/i2c/smiapp/smiapp-core.c
@@ -2495,7 +2495,7 @@ static int smiapp_register_subdevs(struct smiapp_sensor *sensor)
 			return rval;
 		}
 
-		rval = media_entity_create_link(&this->sd.entity,
+		rval = media_create_pad_link(&this->sd.entity,
 						this->source_pad,
 						&last->sd.entity,
 						last->sink_pad,
@@ -2503,7 +2503,7 @@ static int smiapp_register_subdevs(struct smiapp_sensor *sensor)
 						MEDIA_LNK_FL_IMMUTABLE);
 		if (rval) {
 			dev_err(&client->dev,
-				"media_entity_create_link failed\n");
+				"media_create_pad_link failed\n");
 			return rval;
 		}
 
diff --git a/drivers/media/media-entity.c b/drivers/media/media-entity.c
index aafa1119fba7..03c0ebdd8026 100644
--- a/drivers/media/media-entity.c
+++ b/drivers/media/media-entity.c
@@ -479,7 +479,7 @@ static void __media_entity_remove_link(struct media_entity *entity,
 				       struct media_link *link);
 
 int
-media_entity_create_link(struct media_entity *source, u16 source_pad,
+media_create_pad_link(struct media_entity *source, u16 source_pad,
 			 struct media_entity *sink, u16 sink_pad, u32 flags)
 {
 	struct media_link *link;
@@ -517,7 +517,7 @@ media_entity_create_link(struct media_entity *source, u16 source_pad,
 
 	return 0;
 }
-EXPORT_SYMBOL_GPL(media_entity_create_link);
+EXPORT_SYMBOL_GPL(media_create_pad_link);
 
 static void __media_entity_remove_link(struct media_entity *entity,
 				       struct media_link *link)
diff --git a/drivers/media/platform/exynos4-is/media-dev.c b/drivers/media/platform/exynos4-is/media-dev.c
index 3cafcf85cafc..f6ccca232c86 100644
--- a/drivers/media/platform/exynos4-is/media-dev.c
+++ b/drivers/media/platform/exynos4-is/media-dev.c
@@ -729,7 +729,7 @@ static int __fimc_md_create_fimc_sink_links(struct fimc_md *fmd,
 		flags = ((1 << i) & link_mask) ? MEDIA_LNK_FL_ENABLED : 0;
 
 		sink = &fmd->fimc[i]->vid_cap.subdev.entity;
-		ret = media_entity_create_link(source, pad, sink,
+		ret = media_create_pad_link(source, pad, sink,
 					      FIMC_SD_PAD_SINK_CAM, flags);
 		if (ret)
 			return ret;
@@ -749,7 +749,7 @@ static int __fimc_md_create_fimc_sink_links(struct fimc_md *fmd,
 			continue;
 
 		sink = &fmd->fimc_lite[i]->subdev.entity;
-		ret = media_entity_create_link(source, pad, sink,
+		ret = media_create_pad_link(source, pad, sink,
 					       FLITE_SD_PAD_SINK, 0);
 		if (ret)
 			return ret;
@@ -781,13 +781,13 @@ static int __fimc_md_create_flite_source_links(struct fimc_md *fmd)
 		source = &fimc->subdev.entity;
 		sink = &fimc->ve.vdev.entity;
 		/* FIMC-LITE's subdev and video node */
-		ret = media_entity_create_link(source, FLITE_SD_PAD_SOURCE_DMA,
+		ret = media_create_pad_link(source, FLITE_SD_PAD_SOURCE_DMA,
 					       sink, 0, 0);
 		if (ret)
 			break;
 		/* Link from FIMC-LITE to IS-ISP subdev */
 		sink = &fmd->fimc_is->isp.subdev.entity;
-		ret = media_entity_create_link(source, FLITE_SD_PAD_SOURCE_ISP,
+		ret = media_create_pad_link(source, FLITE_SD_PAD_SOURCE_ISP,
 					       sink, 0, 0);
 		if (ret)
 			break;
@@ -811,7 +811,7 @@ static int __fimc_md_create_fimc_is_links(struct fimc_md *fmd)
 
 		/* Link from FIMC-IS-ISP subdev to FIMC */
 		sink = &fmd->fimc[i]->vid_cap.subdev.entity;
-		ret = media_entity_create_link(source, FIMC_ISP_SD_PAD_SRC_FIFO,
+		ret = media_create_pad_link(source, FIMC_ISP_SD_PAD_SRC_FIFO,
 					       sink, FIMC_SD_PAD_SINK_FIFO, 0);
 		if (ret)
 			return ret;
@@ -824,7 +824,7 @@ static int __fimc_md_create_fimc_is_links(struct fimc_md *fmd)
 	if (sink->num_pads == 0)
 		return 0;
 
-	return media_entity_create_link(source, FIMC_ISP_SD_PAD_SRC_DMA,
+	return media_create_pad_link(source, FIMC_ISP_SD_PAD_SRC_DMA,
 					sink, 0, 0);
 }
 
@@ -873,7 +873,7 @@ static int fimc_md_create_links(struct fimc_md *fmd)
 				return -EINVAL;
 
 			pad = sensor->entity.num_pads - 1;
-			ret = media_entity_create_link(&sensor->entity, pad,
+			ret = media_create_pad_link(&sensor->entity, pad,
 					      &csis->entity, CSIS_PAD_SINK,
 					      MEDIA_LNK_FL_IMMUTABLE |
 					      MEDIA_LNK_FL_ENABLED);
@@ -927,7 +927,7 @@ static int fimc_md_create_links(struct fimc_md *fmd)
 		source = &fmd->fimc[i]->vid_cap.subdev.entity;
 		sink = &fmd->fimc[i]->vid_cap.ve.vdev.entity;
 
-		ret = media_entity_create_link(source, FIMC_SD_PAD_SOURCE,
+		ret = media_create_pad_link(source, FIMC_SD_PAD_SOURCE,
 					      sink, 0, flags);
 		if (ret)
 			break;
diff --git a/drivers/media/platform/omap3isp/isp.c b/drivers/media/platform/omap3isp/isp.c
index cbd22a422bd3..df9b3cb8ad60 100644
--- a/drivers/media/platform/omap3isp/isp.c
+++ b/drivers/media/platform/omap3isp/isp.c
@@ -1905,7 +1905,7 @@ static int isp_link_entity(
 		return -EINVAL;
 	}
 
-	return media_entity_create_link(entity, i, input, pad, flags);
+	return media_create_pad_link(entity, i, input, pad, flags);
 }
 
 static int isp_register_entities(struct isp_device *isp)
@@ -2077,51 +2077,51 @@ static int isp_initialize_modules(struct isp_device *isp)
 	}
 
 	/* Connect the submodules. */
-	ret = media_entity_create_link(
+	ret = media_create_pad_link(
 			&isp->isp_csi2a.subdev.entity, CSI2_PAD_SOURCE,
 			&isp->isp_ccdc.subdev.entity, CCDC_PAD_SINK, 0);
 	if (ret < 0)
 		goto error_link;
 
-	ret = media_entity_create_link(
+	ret = media_create_pad_link(
 			&isp->isp_ccp2.subdev.entity, CCP2_PAD_SOURCE,
 			&isp->isp_ccdc.subdev.entity, CCDC_PAD_SINK, 0);
 	if (ret < 0)
 		goto error_link;
 
-	ret = media_entity_create_link(
+	ret = media_create_pad_link(
 			&isp->isp_ccdc.subdev.entity, CCDC_PAD_SOURCE_VP,
 			&isp->isp_prev.subdev.entity, PREV_PAD_SINK, 0);
 	if (ret < 0)
 		goto error_link;
 
-	ret = media_entity_create_link(
+	ret = media_create_pad_link(
 			&isp->isp_ccdc.subdev.entity, CCDC_PAD_SOURCE_OF,
 			&isp->isp_res.subdev.entity, RESZ_PAD_SINK, 0);
 	if (ret < 0)
 		goto error_link;
 
-	ret = media_entity_create_link(
+	ret = media_create_pad_link(
 			&isp->isp_prev.subdev.entity, PREV_PAD_SOURCE,
 			&isp->isp_res.subdev.entity, RESZ_PAD_SINK, 0);
 	if (ret < 0)
 		goto error_link;
 
-	ret = media_entity_create_link(
+	ret = media_create_pad_link(
 			&isp->isp_ccdc.subdev.entity, CCDC_PAD_SOURCE_VP,
 			&isp->isp_aewb.subdev.entity, 0,
 			MEDIA_LNK_FL_ENABLED | MEDIA_LNK_FL_IMMUTABLE);
 	if (ret < 0)
 		goto error_link;
 
-	ret = media_entity_create_link(
+	ret = media_create_pad_link(
 			&isp->isp_ccdc.subdev.entity, CCDC_PAD_SOURCE_VP,
 			&isp->isp_af.subdev.entity, 0,
 			MEDIA_LNK_FL_ENABLED | MEDIA_LNK_FL_IMMUTABLE);
 	if (ret < 0)
 		goto error_link;
 
-	ret = media_entity_create_link(
+	ret = media_create_pad_link(
 			&isp->isp_ccdc.subdev.entity, CCDC_PAD_SOURCE_VP,
 			&isp->isp_hist.subdev.entity, 0,
 			MEDIA_LNK_FL_ENABLED | MEDIA_LNK_FL_IMMUTABLE);
diff --git a/drivers/media/platform/omap3isp/ispccdc.c b/drivers/media/platform/omap3isp/ispccdc.c
index cb236b54d770..a69a5615f060 100644
--- a/drivers/media/platform/omap3isp/ispccdc.c
+++ b/drivers/media/platform/omap3isp/ispccdc.c
@@ -2667,7 +2667,7 @@ static int ccdc_init_entities(struct isp_ccdc_device *ccdc)
 		goto error_video;
 
 	/* Connect the CCDC subdev to the video node. */
-	ret = media_entity_create_link(&ccdc->subdev.entity, CCDC_PAD_SOURCE_OF,
+	ret = media_create_pad_link(&ccdc->subdev.entity, CCDC_PAD_SOURCE_OF,
 			&ccdc->video_out.video.entity, 0, 0);
 	if (ret < 0)
 		goto error_link;
diff --git a/drivers/media/platform/omap3isp/ispccp2.c b/drivers/media/platform/omap3isp/ispccp2.c
index e1b5f5bea541..b215eb5049d6 100644
--- a/drivers/media/platform/omap3isp/ispccp2.c
+++ b/drivers/media/platform/omap3isp/ispccp2.c
@@ -1100,7 +1100,7 @@ static int ccp2_init_entities(struct isp_ccp2_device *ccp2)
 		goto error_video;
 
 	/* Connect the video node to the ccp2 subdev. */
-	ret = media_entity_create_link(&ccp2->video_in.video.entity, 0,
+	ret = media_create_pad_link(&ccp2->video_in.video.entity, 0,
 				       &ccp2->subdev.entity, CCP2_PAD_SINK, 0);
 	if (ret < 0)
 		goto error_link;
diff --git a/drivers/media/platform/omap3isp/ispcsi2.c b/drivers/media/platform/omap3isp/ispcsi2.c
index 6fff92f0813a..fcefc1e74881 100644
--- a/drivers/media/platform/omap3isp/ispcsi2.c
+++ b/drivers/media/platform/omap3isp/ispcsi2.c
@@ -1265,7 +1265,7 @@ static int csi2_init_entities(struct isp_csi2_device *csi2)
 		goto error_video;
 
 	/* Connect the CSI2 subdev to the video node. */
-	ret = media_entity_create_link(&csi2->subdev.entity, CSI2_PAD_SOURCE,
+	ret = media_create_pad_link(&csi2->subdev.entity, CSI2_PAD_SOURCE,
 				       &csi2->video_out.video.entity, 0, 0);
 	if (ret < 0)
 		goto error_link;
diff --git a/drivers/media/platform/omap3isp/isppreview.c b/drivers/media/platform/omap3isp/isppreview.c
index b440c6342ca4..ad38d20c7770 100644
--- a/drivers/media/platform/omap3isp/isppreview.c
+++ b/drivers/media/platform/omap3isp/isppreview.c
@@ -2312,12 +2312,12 @@ static int preview_init_entities(struct isp_prev_device *prev)
 		goto error_video_out;
 
 	/* Connect the video nodes to the previewer subdev. */
-	ret = media_entity_create_link(&prev->video_in.video.entity, 0,
+	ret = media_create_pad_link(&prev->video_in.video.entity, 0,
 			&prev->subdev.entity, PREV_PAD_SINK, 0);
 	if (ret < 0)
 		goto error_link;
 
-	ret = media_entity_create_link(&prev->subdev.entity, PREV_PAD_SOURCE,
+	ret = media_create_pad_link(&prev->subdev.entity, PREV_PAD_SOURCE,
 			&prev->video_out.video.entity, 0, 0);
 	if (ret < 0)
 		goto error_link;
diff --git a/drivers/media/platform/omap3isp/ispresizer.c b/drivers/media/platform/omap3isp/ispresizer.c
index 3deb1ec4a973..b48ad4d4b834 100644
--- a/drivers/media/platform/omap3isp/ispresizer.c
+++ b/drivers/media/platform/omap3isp/ispresizer.c
@@ -1756,12 +1756,12 @@ static int resizer_init_entities(struct isp_res_device *res)
 	res->video_out.video.entity.flags |= MEDIA_ENT_FL_DEFAULT;
 
 	/* Connect the video nodes to the resizer subdev. */
-	ret = media_entity_create_link(&res->video_in.video.entity, 0,
+	ret = media_create_pad_link(&res->video_in.video.entity, 0,
 			&res->subdev.entity, RESZ_PAD_SINK, 0);
 	if (ret < 0)
 		goto error_link;
 
-	ret = media_entity_create_link(&res->subdev.entity, RESZ_PAD_SOURCE,
+	ret = media_create_pad_link(&res->subdev.entity, RESZ_PAD_SOURCE,
 			&res->video_out.video.entity, 0, 0);
 	if (ret < 0)
 		goto error_link;
diff --git a/drivers/media/platform/s3c-camif/camif-core.c b/drivers/media/platform/s3c-camif/camif-core.c
index f47b332f0418..3e33c60be004 100644
--- a/drivers/media/platform/s3c-camif/camif-core.c
+++ b/drivers/media/platform/s3c-camif/camif-core.c
@@ -263,7 +263,7 @@ static int camif_create_media_links(struct camif_dev *camif)
 {
 	int i, ret;
 
-	ret = media_entity_create_link(&camif->sensor.sd->entity, 0,
+	ret = media_create_pad_link(&camif->sensor.sd->entity, 0,
 				&camif->subdev.entity, CAMIF_SD_PAD_SINK,
 				MEDIA_LNK_FL_IMMUTABLE |
 				MEDIA_LNK_FL_ENABLED);
@@ -271,7 +271,7 @@ static int camif_create_media_links(struct camif_dev *camif)
 		return ret;
 
 	for (i = 1; i < CAMIF_SD_PADS_NUM && !ret; i++) {
-		ret = media_entity_create_link(&camif->subdev.entity, i,
+		ret = media_create_pad_link(&camif->subdev.entity, i,
 				&camif->vp[i - 1].vdev.entity, 0,
 				MEDIA_LNK_FL_IMMUTABLE |
 				MEDIA_LNK_FL_ENABLED);
diff --git a/drivers/media/platform/vsp1/vsp1_drv.c b/drivers/media/platform/vsp1/vsp1_drv.c
index 4e61886384e3..9cd94a76a9ed 100644
--- a/drivers/media/platform/vsp1/vsp1_drv.c
+++ b/drivers/media/platform/vsp1/vsp1_drv.c
@@ -101,7 +101,7 @@ static int vsp1_create_links(struct vsp1_device *vsp1, struct vsp1_entity *sink)
 			if (!(entity->pads[pad].flags & MEDIA_PAD_FL_SINK))
 				continue;
 
-			ret = media_entity_create_link(&source->subdev.entity,
+			ret = media_create_pad_link(&source->subdev.entity,
 						       source->source_pad,
 						       entity, pad, flags);
 			if (ret < 0)
@@ -262,7 +262,7 @@ static int vsp1_create_entities(struct vsp1_device *vsp1)
 	}
 
 	if (vsp1->pdata.features & VSP1_HAS_LIF) {
-		ret = media_entity_create_link(
+		ret = media_create_pad_link(
 			&vsp1->wpf[0]->entity.subdev.entity, RWPF_PAD_SOURCE,
 			&vsp1->lif->entity.subdev.entity, LIF_PAD_SINK, 0);
 		if (ret < 0)
diff --git a/drivers/media/platform/vsp1/vsp1_rpf.c b/drivers/media/platform/vsp1/vsp1_rpf.c
index 3294529a3108..b60a528a8fe8 100644
--- a/drivers/media/platform/vsp1/vsp1_rpf.c
+++ b/drivers/media/platform/vsp1/vsp1_rpf.c
@@ -278,7 +278,7 @@ struct vsp1_rwpf *vsp1_rpf_create(struct vsp1_device *vsp1, unsigned int index)
 	rpf->entity.video = video;
 
 	/* Connect the video device to the RPF. */
-	ret = media_entity_create_link(&rpf->video.video.entity, 0,
+	ret = media_create_pad_link(&rpf->video.video.entity, 0,
 				       &rpf->entity.subdev.entity,
 				       RWPF_PAD_SINK,
 				       MEDIA_LNK_FL_ENABLED |
diff --git a/drivers/media/platform/vsp1/vsp1_wpf.c b/drivers/media/platform/vsp1/vsp1_wpf.c
index 1d2b3a2f1573..d39aa4b8aea1 100644
--- a/drivers/media/platform/vsp1/vsp1_wpf.c
+++ b/drivers/media/platform/vsp1/vsp1_wpf.c
@@ -284,7 +284,7 @@ struct vsp1_rwpf *vsp1_wpf_create(struct vsp1_device *vsp1, unsigned int index)
 	if (!(vsp1->pdata.features & VSP1_HAS_LIF) || index != 0)
 		flags |= MEDIA_LNK_FL_IMMUTABLE;
 
-	ret = media_entity_create_link(&wpf->entity.subdev.entity,
+	ret = media_create_pad_link(&wpf->entity.subdev.entity,
 				       RWPF_PAD_SOURCE,
 				       &wpf->video.video.entity, 0, flags);
 	if (ret < 0)
diff --git a/drivers/media/platform/xilinx/xilinx-vipp.c b/drivers/media/platform/xilinx/xilinx-vipp.c
index 7b7cb9c28d2c..79d4be7ce9a5 100644
--- a/drivers/media/platform/xilinx/xilinx-vipp.c
+++ b/drivers/media/platform/xilinx/xilinx-vipp.c
@@ -156,7 +156,7 @@ static int xvip_graph_build_one(struct xvip_composite_device *xdev,
 			local->name, local_pad->index,
 			remote->name, remote_pad->index);
 
-		ret = media_entity_create_link(local, local_pad->index,
+		ret = media_create_pad_link(local, local_pad->index,
 					       remote, remote_pad->index,
 					       link_flags);
 		if (ret < 0) {
@@ -270,7 +270,7 @@ static int xvip_graph_build_dma(struct xvip_composite_device *xdev)
 			source->name, source_pad->index,
 			sink->name, sink_pad->index);
 
-		ret = media_entity_create_link(source, source_pad->index,
+		ret = media_create_pad_link(source, source_pad->index,
 					       sink, sink_pad->index,
 					       link_flags);
 		if (ret < 0) {
diff --git a/drivers/media/usb/cx231xx/cx231xx-cards.c b/drivers/media/usb/cx231xx/cx231xx-cards.c
index 4a117a58c39a..3b5c9ae39ad3 100644
--- a/drivers/media/usb/cx231xx/cx231xx-cards.c
+++ b/drivers/media/usb/cx231xx/cx231xx-cards.c
@@ -1264,11 +1264,11 @@ static void cx231xx_create_media_graph(struct cx231xx *dev)
 		return;
 
 	if (tuner)
-		media_entity_create_link(tuner, 0, decoder, 0,
+		media_create_pad_link(tuner, 0, decoder, 0,
 					 MEDIA_LNK_FL_ENABLED);
-	media_entity_create_link(decoder, 1, &dev->vdev.entity, 0,
+	media_create_pad_link(decoder, 1, &dev->vdev.entity, 0,
 				 MEDIA_LNK_FL_ENABLED);
-	media_entity_create_link(decoder, 2, &dev->vbi_dev.entity, 0,
+	media_create_pad_link(decoder, 2, &dev->vbi_dev.entity, 0,
 				 MEDIA_LNK_FL_ENABLED);
 #endif
 }
diff --git a/drivers/media/usb/uvc/uvc_entity.c b/drivers/media/usb/uvc/uvc_entity.c
index 245445491516..429e428ccd93 100644
--- a/drivers/media/usb/uvc/uvc_entity.c
+++ b/drivers/media/usb/uvc/uvc_entity.c
@@ -56,7 +56,7 @@ static int uvc_mc_register_entity(struct uvc_video_chain *chain,
 			continue;
 
 		remote_pad = remote->num_pads - 1;
-		ret = media_entity_create_link(source, remote_pad,
+		ret = media_create_pad_link(source, remote_pad,
 					       sink, i, flags);
 		if (ret < 0)
 			return ret;
diff --git a/drivers/staging/media/davinci_vpfe/dm365_ipipeif.c b/drivers/staging/media/davinci_vpfe/dm365_ipipeif.c
index 8fb676186898..d96bdaaae50e 100644
--- a/drivers/staging/media/davinci_vpfe/dm365_ipipeif.c
+++ b/drivers/staging/media/davinci_vpfe/dm365_ipipeif.c
@@ -971,7 +971,7 @@ vpfe_ipipeif_register_entities(struct vpfe_ipipeif_device *ipipeif,
 	ipipeif->video_in.vpfe_dev = vpfe_dev;
 
 	flags = 0;
-	ret = media_entity_create_link(&ipipeif->video_in.video_dev.entity, 0,
+	ret = media_create_pad_link(&ipipeif->video_in.video_dev.entity, 0,
 					&ipipeif->subdev.entity, 0, flags);
 	if (ret < 0)
 		goto fail;
diff --git a/drivers/staging/media/davinci_vpfe/dm365_isif.c b/drivers/staging/media/davinci_vpfe/dm365_isif.c
index b1f01adfa7c8..df77288b0ec0 100644
--- a/drivers/staging/media/davinci_vpfe/dm365_isif.c
+++ b/drivers/staging/media/davinci_vpfe/dm365_isif.c
@@ -1817,7 +1817,7 @@ int vpfe_isif_register_entities(struct vpfe_isif_device *isif,
 	isif->video_out.vpfe_dev = vpfe_dev;
 	flags = 0;
 	/* connect isif to video node */
-	ret = media_entity_create_link(&isif->subdev.entity, 1,
+	ret = media_create_pad_link(&isif->subdev.entity, 1,
 				       &isif->video_out.video_dev.entity,
 				       0, flags);
 	if (ret < 0)
diff --git a/drivers/staging/media/davinci_vpfe/dm365_resizer.c b/drivers/staging/media/davinci_vpfe/dm365_resizer.c
index 692789aa22f4..ae942de3a23d 100644
--- a/drivers/staging/media/davinci_vpfe/dm365_resizer.c
+++ b/drivers/staging/media/davinci_vpfe/dm365_resizer.c
@@ -1831,27 +1831,27 @@ int vpfe_resizer_register_entities(struct vpfe_resizer_device *resizer,
 	resizer->resizer_b.video_out.vpfe_dev = vpfe_dev;
 
 	/* create link between Resizer Crop----> Resizer A*/
-	ret = media_entity_create_link(&resizer->crop_resizer.subdev.entity, 1,
+	ret = media_create_pad_link(&resizer->crop_resizer.subdev.entity, 1,
 				&resizer->resizer_a.subdev.entity,
 				0, flags);
 	if (ret < 0)
 		goto out_create_link;
 
 	/* create link between Resizer Crop----> Resizer B*/
-	ret = media_entity_create_link(&resizer->crop_resizer.subdev.entity, 2,
+	ret = media_create_pad_link(&resizer->crop_resizer.subdev.entity, 2,
 				&resizer->resizer_b.subdev.entity,
 				0, flags);
 	if (ret < 0)
 		goto out_create_link;
 
 	/* create link between Resizer A ----> video out */
-	ret = media_entity_create_link(&resizer->resizer_a.subdev.entity, 1,
+	ret = media_create_pad_link(&resizer->resizer_a.subdev.entity, 1,
 		&resizer->resizer_a.video_out.video_dev.entity, 0, flags);
 	if (ret < 0)
 		goto out_create_link;
 
 	/* create link between Resizer B ----> video out */
-	ret = media_entity_create_link(&resizer->resizer_b.subdev.entity, 1,
+	ret = media_create_pad_link(&resizer->resizer_b.subdev.entity, 1,
 		&resizer->resizer_b.video_out.video_dev.entity, 0, flags);
 	if (ret < 0)
 		goto out_create_link;
diff --git a/drivers/staging/media/davinci_vpfe/vpfe_mc_capture.c b/drivers/staging/media/davinci_vpfe/vpfe_mc_capture.c
index 57426199ad7a..08c8a5f967d3 100644
--- a/drivers/staging/media/davinci_vpfe/vpfe_mc_capture.c
+++ b/drivers/staging/media/davinci_vpfe/vpfe_mc_capture.c
@@ -445,32 +445,32 @@ static int vpfe_register_entities(struct vpfe_device *vpfe_dev)
 		/* if entity has no pads (ex: amplifier),
 		   cant establish link */
 		if (vpfe_dev->sd[i]->entity.num_pads) {
-			ret = media_entity_create_link(&vpfe_dev->sd[i]->entity,
+			ret = media_create_pad_link(&vpfe_dev->sd[i]->entity,
 				0, &vpfe_dev->vpfe_isif.subdev.entity,
 				0, flags);
 			if (ret < 0)
 				goto out_resizer_register;
 		}
 
-	ret = media_entity_create_link(&vpfe_dev->vpfe_isif.subdev.entity, 1,
+	ret = media_create_pad_link(&vpfe_dev->vpfe_isif.subdev.entity, 1,
 				       &vpfe_dev->vpfe_ipipeif.subdev.entity,
 				       0, flags);
 	if (ret < 0)
 		goto out_resizer_register;
 
-	ret = media_entity_create_link(&vpfe_dev->vpfe_ipipeif.subdev.entity, 1,
+	ret = media_create_pad_link(&vpfe_dev->vpfe_ipipeif.subdev.entity, 1,
 				       &vpfe_dev->vpfe_ipipe.subdev.entity,
 				       0, flags);
 	if (ret < 0)
 		goto out_resizer_register;
 
-	ret = media_entity_create_link(&vpfe_dev->vpfe_ipipe.subdev.entity,
+	ret = media_create_pad_link(&vpfe_dev->vpfe_ipipe.subdev.entity,
 			1, &vpfe_dev->vpfe_resizer.crop_resizer.subdev.entity,
 			0, flags);
 	if (ret < 0)
 		goto out_resizer_register;
 
-	ret = media_entity_create_link(&vpfe_dev->vpfe_ipipeif.subdev.entity, 1,
+	ret = media_create_pad_link(&vpfe_dev->vpfe_ipipeif.subdev.entity, 1,
 			&vpfe_dev->vpfe_resizer.crop_resizer.subdev.entity,
 			0, flags);
 	if (ret < 0)
diff --git a/drivers/staging/media/omap4iss/iss.c b/drivers/staging/media/omap4iss/iss.c
index 37694999d189..c0455220f441 100644
--- a/drivers/staging/media/omap4iss/iss.c
+++ b/drivers/staging/media/omap4iss/iss.c
@@ -1259,7 +1259,7 @@ static int iss_register_entities(struct iss_device *iss)
 			goto done;
 		}
 
-		ret = media_entity_create_link(&sensor->entity, 0, input, pad,
+		ret = media_create_pad_link(&sensor->entity, 0, input, pad,
 					       flags);
 		if (ret < 0)
 			goto done;
@@ -1317,31 +1317,31 @@ static int iss_initialize_modules(struct iss_device *iss)
 	}
 
 	/* Connect the submodules. */
-	ret = media_entity_create_link(
+	ret = media_create_pad_link(
 			&iss->csi2a.subdev.entity, CSI2_PAD_SOURCE,
 			&iss->ipipeif.subdev.entity, IPIPEIF_PAD_SINK, 0);
 	if (ret < 0)
 		goto error_link;
 
-	ret = media_entity_create_link(
+	ret = media_create_pad_link(
 			&iss->csi2b.subdev.entity, CSI2_PAD_SOURCE,
 			&iss->ipipeif.subdev.entity, IPIPEIF_PAD_SINK, 0);
 	if (ret < 0)
 		goto error_link;
 
-	ret = media_entity_create_link(
+	ret = media_create_pad_link(
 			&iss->ipipeif.subdev.entity, IPIPEIF_PAD_SOURCE_VP,
 			&iss->resizer.subdev.entity, RESIZER_PAD_SINK, 0);
 	if (ret < 0)
 		goto error_link;
 
-	ret = media_entity_create_link(
+	ret = media_create_pad_link(
 			&iss->ipipeif.subdev.entity, IPIPEIF_PAD_SOURCE_VP,
 			&iss->ipipe.subdev.entity, IPIPE_PAD_SINK, 0);
 	if (ret < 0)
 		goto error_link;
 
-	ret = media_entity_create_link(
+	ret = media_create_pad_link(
 			&iss->ipipe.subdev.entity, IPIPE_PAD_SOURCE_VP,
 			&iss->resizer.subdev.entity, RESIZER_PAD_SINK, 0);
 	if (ret < 0)
diff --git a/drivers/staging/media/omap4iss/iss_csi2.c b/drivers/staging/media/omap4iss/iss_csi2.c
index e39f1bbbdae1..206fb57703c7 100644
--- a/drivers/staging/media/omap4iss/iss_csi2.c
+++ b/drivers/staging/media/omap4iss/iss_csi2.c
@@ -1291,7 +1291,7 @@ static int csi2_init_entities(struct iss_csi2_device *csi2, const char *subname)
 		goto error_video;
 
 	/* Connect the CSI2 subdev to the video node. */
-	ret = media_entity_create_link(&csi2->subdev.entity, CSI2_PAD_SOURCE,
+	ret = media_create_pad_link(&csi2->subdev.entity, CSI2_PAD_SOURCE,
 				       &csi2->video_out.video.entity, 0, 0);
 	if (ret < 0)
 		goto error_link;
diff --git a/drivers/staging/media/omap4iss/iss_ipipeif.c b/drivers/staging/media/omap4iss/iss_ipipeif.c
index be5f80d7b5dc..44c432ef2ac5 100644
--- a/drivers/staging/media/omap4iss/iss_ipipeif.c
+++ b/drivers/staging/media/omap4iss/iss_ipipeif.c
@@ -762,7 +762,7 @@ static int ipipeif_init_entities(struct iss_ipipeif_device *ipipeif)
 		return ret;
 
 	/* Connect the IPIPEIF subdev to the video node. */
-	ret = media_entity_create_link(&ipipeif->subdev.entity,
+	ret = media_create_pad_link(&ipipeif->subdev.entity,
 				       IPIPEIF_PAD_SOURCE_ISIF_SF,
 				       &ipipeif->video_out.video.entity, 0, 0);
 	if (ret < 0)
diff --git a/drivers/staging/media/omap4iss/iss_resizer.c b/drivers/staging/media/omap4iss/iss_resizer.c
index 91e724085dba..b659e465cb56 100644
--- a/drivers/staging/media/omap4iss/iss_resizer.c
+++ b/drivers/staging/media/omap4iss/iss_resizer.c
@@ -806,7 +806,7 @@ static int resizer_init_entities(struct iss_resizer_device *resizer)
 		return ret;
 
 	/* Connect the RESIZER subdev to the video node. */
-	ret = media_entity_create_link(&resizer->subdev.entity,
+	ret = media_create_pad_link(&resizer->subdev.entity,
 				       RESIZER_PAD_SOURCE_MEM,
 				       &resizer->video_out.video.entity, 0, 0);
 	if (ret < 0)
diff --git a/include/media/media-entity.h b/include/media/media-entity.h
index 412cf5d00315..8400c517ff1f 100644
--- a/include/media/media-entity.h
+++ b/include/media/media-entity.h
@@ -211,7 +211,7 @@ int media_entity_init(struct media_entity *entity, u16 num_pads,
 		      struct media_pad *pads);
 void media_entity_cleanup(struct media_entity *entity);
 
-int media_entity_create_link(struct media_entity *source, u16 source_pad,
+int media_create_pad_link(struct media_entity *source, u16 source_pad,
 		struct media_entity *sink, u16 sink_pad, u32 flags);
 void __media_entity_remove_links(struct media_entity *entity);
 void media_entity_remove_links(struct media_entity *entity);
-- 
2.4.3



From mchehab at osg.samsung.com  Wed Aug 12 13:14:51 2015
From: mchehab at osg.samsung.com (Mauro Carvalho Chehab)
Date: Wed, 12 Aug 2015 17:14:51 -0300
Subject: [PATCH RFC v3 07/16] media: get rid of unused "extra_links" param on
 media_entity_init()
In-Reply-To: <cover.1439410053.git.mchehab@osg.samsung.com>
References: <cover.1439410053.git.mchehab@osg.samsung.com>
Message-ID: <7b9f2654888f0fd54c290c50f50248a367768da7.1439410053.git.mchehab@osg.samsung.com>

Currently, media_entity_init() creates an array with the links,
allocated at init time. It provides a parameter (extra_links)
that would allocate more links than the current needs, but this
is not used by any driver.

As we want to be able to do dynamic link allocation/removal,
we'll need to change the implementation of the links. So,
before doing that, let's first remove that extra unused
parameter, in order to cleanup the interface first.

Signed-off-by: Mauro Carvalho Chehab <mchehab at osg.samsung.com>

diff --git a/Documentation/media-framework.txt b/Documentation/media-framework.txt
index f552a75c0e70..2cc6019f7147 100644
--- a/Documentation/media-framework.txt
+++ b/Documentation/media-framework.txt
@@ -104,7 +104,7 @@ although drivers can allocate entities directly.
 Drivers initialize entities by calling
 
 	media_entity_init(struct media_entity *entity, u16 num_pads,
-			  struct media_pad *pads, u16 extra_links);
+			  struct media_pad *pads);
 
 The media_entity name, type, flags, revision and group_id fields can be
 initialized before or after calling media_entity_init. Entities embedded in
diff --git a/Documentation/video4linux/v4l2-framework.txt b/Documentation/video4linux/v4l2-framework.txt
index 75d5c18d689a..109cc3792534 100644
--- a/Documentation/video4linux/v4l2-framework.txt
+++ b/Documentation/video4linux/v4l2-framework.txt
@@ -300,7 +300,7 @@ calling media_entity_init():
 	struct media_pad *pads = &my_sd->pads;
 	int err;
 
-	err = media_entity_init(&sd->entity, npads, pads, 0);
+	err = media_entity_init(&sd->entity, npads, pads);
 
 The pads array must have been previously initialized. There is no need to
 manually set the struct media_entity type and name fields, but the revision
@@ -700,7 +700,7 @@ calling media_entity_init():
 	struct media_pad *pad = &my_vdev->pad;
 	int err;
 
-	err = media_entity_init(&vdev->entity, 1, pad, 0);
+	err = media_entity_init(&vdev->entity, 1, pad);
 
 The pads array must have been previously initialized. There is no need to
 manually set the struct media_entity type and name fields.
diff --git a/Documentation/zh_CN/video4linux/v4l2-framework.txt b/Documentation/zh_CN/video4linux/v4l2-framework.txt
index 2b828e631e31..ff815cb92031 100644
--- a/Documentation/zh_CN/video4linux/v4l2-framework.txt
+++ b/Documentation/zh_CN/video4linux/v4l2-framework.txt
@@ -295,7 +295,7 @@ owner ??????????????? i2c ?????????????????????????????????????????????
 	struct media_pad *pads = &my_sd->pads;
 	int err;
 
-	err = media_entity_init(&sd->entity, npads, pads, 0);
+	err = media_entity_init(&sd->entity, npads, pads);
 
 pads ???????????????????????????????????????????????? media_entity ??? type ???
 name ????????????????????????revision ?????????????????????
@@ -602,7 +602,7 @@ v4l2_file_operations ???????????? file_operations ???????????????????????????
 	struct media_pad *pad = &my_vdev->pad;
 	int err;
 
-	err = media_entity_init(&vdev->entity, 1, pad, 0);
+	err = media_entity_init(&vdev->entity, 1, pad);
 
 pads ?????????????????????????????????????????????????????? media_entity ??? type ???
 name ??????
diff --git a/drivers/media/dvb-core/dvbdev.c b/drivers/media/dvb-core/dvbdev.c
index 13bb57f0457f..2fdcbb5f000a 100644
--- a/drivers/media/dvb-core/dvbdev.c
+++ b/drivers/media/dvb-core/dvbdev.c
@@ -249,7 +249,7 @@ static void dvb_register_media_device(struct dvb_device *dvbdev,
 	}
 
 	if (npads)
-		ret = media_entity_init(dvbdev->entity, npads, dvbdev->pads, 0);
+		ret = media_entity_init(dvbdev->entity, npads, dvbdev->pads);
 	if (!ret)
 		ret = media_device_register_entity(dvbdev->adapter->mdev,
 						   dvbdev->entity);
diff --git a/drivers/media/i2c/ad9389b.c b/drivers/media/i2c/ad9389b.c
index 69094ab047b1..39d6ee681aeb 100644
--- a/drivers/media/i2c/ad9389b.c
+++ b/drivers/media/i2c/ad9389b.c
@@ -1158,7 +1158,7 @@ static int ad9389b_probe(struct i2c_client *client, const struct i2c_device_id *
 	state->rgb_quantization_range_ctrl->is_private = true;
 
 	state->pad.flags = MEDIA_PAD_FL_SINK;
-	err = media_entity_init(&sd->entity, 1, &state->pad, 0);
+	err = media_entity_init(&sd->entity, 1, &state->pad);
 	if (err)
 		goto err_hdl;
 
diff --git a/drivers/media/i2c/adp1653.c b/drivers/media/i2c/adp1653.c
index c70ababce954..5f76997f6e07 100644
--- a/drivers/media/i2c/adp1653.c
+++ b/drivers/media/i2c/adp1653.c
@@ -512,7 +512,7 @@ static int adp1653_probe(struct i2c_client *client,
 	if (ret)
 		goto free_and_quit;
 
-	ret = media_entity_init(&flash->subdev.entity, 0, NULL, 0);
+	ret = media_entity_init(&flash->subdev.entity, 0, NULL);
 	if (ret < 0)
 		goto free_and_quit;
 
diff --git a/drivers/media/i2c/adv7180.c b/drivers/media/i2c/adv7180.c
index 09a96df170d1..cd15336260a3 100644
--- a/drivers/media/i2c/adv7180.c
+++ b/drivers/media/i2c/adv7180.c
@@ -1214,7 +1214,7 @@ static int adv7180_probe(struct i2c_client *client,
 
 	state->pad.flags = MEDIA_PAD_FL_SOURCE;
 	sd->entity.flags |= MEDIA_ENT_T_V4L2_SUBDEV_DECODER;
-	ret = media_entity_init(&sd->entity, 1, &state->pad, 0);
+	ret = media_entity_init(&sd->entity, 1, &state->pad);
 	if (ret)
 		goto err_free_ctrl;
 
diff --git a/drivers/media/i2c/adv7511.c b/drivers/media/i2c/adv7511.c
index 95bcd4026451..e70aa56a0b11 100644
--- a/drivers/media/i2c/adv7511.c
+++ b/drivers/media/i2c/adv7511.c
@@ -1482,7 +1482,7 @@ static int adv7511_probe(struct i2c_client *client, const struct i2c_device_id *
 	state->rgb_quantization_range_ctrl->is_private = true;
 
 	state->pad.flags = MEDIA_PAD_FL_SINK;
-	err = media_entity_init(&sd->entity, 1, &state->pad, 0);
+	err = media_entity_init(&sd->entity, 1, &state->pad);
 	if (err)
 		goto err_hdl;
 
diff --git a/drivers/media/i2c/adv7604.c b/drivers/media/i2c/adv7604.c
index bfb0b6a72bbc..dcefa810c8ac 100644
--- a/drivers/media/i2c/adv7604.c
+++ b/drivers/media/i2c/adv7604.c
@@ -3198,7 +3198,7 @@ static int adv76xx_probe(struct i2c_client *client,
 	state->pads[state->source_pad].flags = MEDIA_PAD_FL_SOURCE;
 
 	err = media_entity_init(&sd->entity, state->source_pad + 1,
-				state->pads, 0);
+				state->pads);
 	if (err)
 		goto err_work_queues;
 
diff --git a/drivers/media/i2c/adv7842.c b/drivers/media/i2c/adv7842.c
index 897d68c78b06..8a1ecc6ab36c 100644
--- a/drivers/media/i2c/adv7842.c
+++ b/drivers/media/i2c/adv7842.c
@@ -3309,7 +3309,7 @@ static int adv7842_probe(struct i2c_client *client,
 			adv7842_delayed_work_enable_hotplug);
 
 	state->pad.flags = MEDIA_PAD_FL_SOURCE;
-	err = media_entity_init(&sd->entity, 1, &state->pad, 0);
+	err = media_entity_init(&sd->entity, 1, &state->pad);
 	if (err)
 		goto err_work_queues;
 
diff --git a/drivers/media/i2c/as3645a.c b/drivers/media/i2c/as3645a.c
index 301084b07887..9d579a836f79 100644
--- a/drivers/media/i2c/as3645a.c
+++ b/drivers/media/i2c/as3645a.c
@@ -827,7 +827,7 @@ static int as3645a_probe(struct i2c_client *client,
 	if (ret < 0)
 		goto done;
 
-	ret = media_entity_init(&flash->subdev.entity, 0, NULL, 0);
+	ret = media_entity_init(&flash->subdev.entity, 0, NULL);
 	if (ret < 0)
 		goto done;
 
diff --git a/drivers/media/i2c/cx25840/cx25840-core.c b/drivers/media/i2c/cx25840/cx25840-core.c
index e15a789ad596..7a2cf352d9c5 100644
--- a/drivers/media/i2c/cx25840/cx25840-core.c
+++ b/drivers/media/i2c/cx25840/cx25840-core.c
@@ -5211,7 +5211,7 @@ static int cx25840_probe(struct i2c_client *client,
 	sd->entity.type = MEDIA_ENT_T_V4L2_SUBDEV_DECODER;
 
 	ret = media_entity_init(&sd->entity, ARRAY_SIZE(state->pads),
-				state->pads, 0);
+				state->pads);
 	if (ret < 0) {
 		v4l_info(client, "failed to initialize media entity!\n");
 		return ret;
diff --git a/drivers/media/i2c/lm3560.c b/drivers/media/i2c/lm3560.c
index d9ece4b2d047..9bd9def0852c 100644
--- a/drivers/media/i2c/lm3560.c
+++ b/drivers/media/i2c/lm3560.c
@@ -365,7 +365,7 @@ static int lm3560_subdev_init(struct lm3560_flash *flash,
 	rval = lm3560_init_controls(flash, led_no);
 	if (rval)
 		goto err_out;
-	rval = media_entity_init(&flash->subdev_led[led_no].entity, 0, NULL, 0);
+	rval = media_entity_init(&flash->subdev_led[led_no].entity, 0, NULL);
 	if (rval < 0)
 		goto err_out;
 	flash->subdev_led[led_no].entity.type = MEDIA_ENT_T_V4L2_SUBDEV_FLASH;
diff --git a/drivers/media/i2c/lm3646.c b/drivers/media/i2c/lm3646.c
index 626fb4679c02..4160e18af607 100644
--- a/drivers/media/i2c/lm3646.c
+++ b/drivers/media/i2c/lm3646.c
@@ -282,7 +282,7 @@ static int lm3646_subdev_init(struct lm3646_flash *flash)
 	rval = lm3646_init_controls(flash);
 	if (rval)
 		goto err_out;
-	rval = media_entity_init(&flash->subdev_led.entity, 0, NULL, 0);
+	rval = media_entity_init(&flash->subdev_led.entity, 0, NULL);
 	if (rval < 0)
 		goto err_out;
 	flash->subdev_led.entity.type = MEDIA_ENT_T_V4L2_SUBDEV_FLASH;
diff --git a/drivers/media/i2c/m5mols/m5mols_core.c b/drivers/media/i2c/m5mols/m5mols_core.c
index 6404c0d93e7a..f718a1009e4c 100644
--- a/drivers/media/i2c/m5mols/m5mols_core.c
+++ b/drivers/media/i2c/m5mols/m5mols_core.c
@@ -975,7 +975,7 @@ static int m5mols_probe(struct i2c_client *client,
 
 	sd->internal_ops = &m5mols_subdev_internal_ops;
 	info->pad.flags = MEDIA_PAD_FL_SOURCE;
-	ret = media_entity_init(&sd->entity, 1, &info->pad, 0);
+	ret = media_entity_init(&sd->entity, 1, &info->pad);
 	if (ret < 0)
 		return ret;
 	sd->entity.type = MEDIA_ENT_T_V4L2_SUBDEV_SENSOR;
diff --git a/drivers/media/i2c/mt9m032.c b/drivers/media/i2c/mt9m032.c
index c7747bd0cabb..1493ab6e7fb3 100644
--- a/drivers/media/i2c/mt9m032.c
+++ b/drivers/media/i2c/mt9m032.c
@@ -799,7 +799,7 @@ static int mt9m032_probe(struct i2c_client *client,
 
 	sensor->subdev.ctrl_handler = &sensor->ctrls;
 	sensor->pad.flags = MEDIA_PAD_FL_SOURCE;
-	ret = media_entity_init(&sensor->subdev.entity, 1, &sensor->pad, 0);
+	ret = media_entity_init(&sensor->subdev.entity, 1, &sensor->pad);
 	if (ret < 0)
 		goto error_ctrl;
 
diff --git a/drivers/media/i2c/mt9p031.c b/drivers/media/i2c/mt9p031.c
index 0db15f528ac1..e3c5af82b7c1 100644
--- a/drivers/media/i2c/mt9p031.c
+++ b/drivers/media/i2c/mt9p031.c
@@ -1112,7 +1112,7 @@ static int mt9p031_probe(struct i2c_client *client,
 	mt9p031->subdev.internal_ops = &mt9p031_subdev_internal_ops;
 
 	mt9p031->pad.flags = MEDIA_PAD_FL_SOURCE;
-	ret = media_entity_init(&mt9p031->subdev.entity, 1, &mt9p031->pad, 0);
+	ret = media_entity_init(&mt9p031->subdev.entity, 1, &mt9p031->pad);
 	if (ret < 0)
 		goto done;
 
diff --git a/drivers/media/i2c/mt9t001.c b/drivers/media/i2c/mt9t001.c
index 8ae99f7f254c..1dae1a98bc85 100644
--- a/drivers/media/i2c/mt9t001.c
+++ b/drivers/media/i2c/mt9t001.c
@@ -933,7 +933,7 @@ static int mt9t001_probe(struct i2c_client *client,
 	mt9t001->subdev.flags |= V4L2_SUBDEV_FL_HAS_DEVNODE;
 
 	mt9t001->pad.flags = MEDIA_PAD_FL_SOURCE;
-	ret = media_entity_init(&mt9t001->subdev.entity, 1, &mt9t001->pad, 0);
+	ret = media_entity_init(&mt9t001->subdev.entity, 1, &mt9t001->pad);
 
 done:
 	if (ret < 0) {
diff --git a/drivers/media/i2c/mt9v032.c b/drivers/media/i2c/mt9v032.c
index 977f4006edbd..980011aa039d 100644
--- a/drivers/media/i2c/mt9v032.c
+++ b/drivers/media/i2c/mt9v032.c
@@ -1046,7 +1046,7 @@ static int mt9v032_probe(struct i2c_client *client,
 	mt9v032->subdev.flags |= V4L2_SUBDEV_FL_HAS_DEVNODE;
 
 	mt9v032->pad.flags = MEDIA_PAD_FL_SOURCE;
-	ret = media_entity_init(&mt9v032->subdev.entity, 1, &mt9v032->pad, 0);
+	ret = media_entity_init(&mt9v032->subdev.entity, 1, &mt9v032->pad);
 	if (ret < 0)
 		goto err;
 
diff --git a/drivers/media/i2c/noon010pc30.c b/drivers/media/i2c/noon010pc30.c
index f197b6cbd407..a9761251b970 100644
--- a/drivers/media/i2c/noon010pc30.c
+++ b/drivers/media/i2c/noon010pc30.c
@@ -780,7 +780,7 @@ static int noon010_probe(struct i2c_client *client,
 
 	info->pad.flags = MEDIA_PAD_FL_SOURCE;
 	sd->entity.type = MEDIA_ENT_T_V4L2_SUBDEV_SENSOR;
-	ret = media_entity_init(&sd->entity, 1, &info->pad, 0);
+	ret = media_entity_init(&sd->entity, 1, &info->pad);
 	if (ret < 0)
 		goto np_err;
 
diff --git a/drivers/media/i2c/ov2659.c b/drivers/media/i2c/ov2659.c
index 6edffc7b74e3..39f2d2cfdc9c 100644
--- a/drivers/media/i2c/ov2659.c
+++ b/drivers/media/i2c/ov2659.c
@@ -1450,7 +1450,7 @@ static int ov2659_probe(struct i2c_client *client,
 #if defined(CONFIG_MEDIA_CONTROLLER)
 	ov2659->pad.flags = MEDIA_PAD_FL_SOURCE;
 	sd->entity.type = MEDIA_ENT_T_V4L2_SUBDEV_SENSOR;
-	ret = media_entity_init(&sd->entity, 1, &ov2659->pad, 0);
+	ret = media_entity_init(&sd->entity, 1, &ov2659->pad);
 	if (ret < 0) {
 		v4l2_ctrl_handler_free(&ov2659->ctrls);
 		return ret;
diff --git a/drivers/media/i2c/ov9650.c b/drivers/media/i2c/ov9650.c
index 2bc473385c91..6a6747343512 100644
--- a/drivers/media/i2c/ov9650.c
+++ b/drivers/media/i2c/ov9650.c
@@ -1501,7 +1501,7 @@ static int ov965x_probe(struct i2c_client *client,
 
 	ov965x->pad.flags = MEDIA_PAD_FL_SOURCE;
 	sd->entity.type = MEDIA_ENT_T_V4L2_SUBDEV_SENSOR;
-	ret = media_entity_init(&sd->entity, 1, &ov965x->pad, 0);
+	ret = media_entity_init(&sd->entity, 1, &ov965x->pad);
 	if (ret < 0)
 		return ret;
 
diff --git a/drivers/media/i2c/s5c73m3/s5c73m3-core.c b/drivers/media/i2c/s5c73m3/s5c73m3-core.c
index 53c5ea89f0b9..6d167428727d 100644
--- a/drivers/media/i2c/s5c73m3/s5c73m3-core.c
+++ b/drivers/media/i2c/s5c73m3/s5c73m3-core.c
@@ -1691,7 +1691,7 @@ static int s5c73m3_probe(struct i2c_client *client,
 	sd->entity.type = MEDIA_ENT_T_V4L2_SUBDEV;
 
 	ret = media_entity_init(&sd->entity, S5C73M3_NUM_PADS,
-							state->sensor_pads, 0);
+							state->sensor_pads);
 	if (ret < 0)
 		return ret;
 
@@ -1707,7 +1707,7 @@ static int s5c73m3_probe(struct i2c_client *client,
 	oif_sd->entity.type = MEDIA_ENT_T_V4L2_SUBDEV;
 
 	ret = media_entity_init(&oif_sd->entity, OIF_NUM_PADS,
-							state->oif_pads, 0);
+							state->oif_pads);
 	if (ret < 0)
 		return ret;
 
diff --git a/drivers/media/i2c/s5k4ecgx.c b/drivers/media/i2c/s5k4ecgx.c
index 97084237275d..d207ddce31b6 100644
--- a/drivers/media/i2c/s5k4ecgx.c
+++ b/drivers/media/i2c/s5k4ecgx.c
@@ -962,7 +962,7 @@ static int s5k4ecgx_probe(struct i2c_client *client,
 
 	priv->pad.flags = MEDIA_PAD_FL_SOURCE;
 	sd->entity.type = MEDIA_ENT_T_V4L2_SUBDEV_SENSOR;
-	ret = media_entity_init(&sd->entity, 1, &priv->pad, 0);
+	ret = media_entity_init(&sd->entity, 1, &priv->pad);
 	if (ret)
 		return ret;
 
diff --git a/drivers/media/i2c/s5k5baf.c b/drivers/media/i2c/s5k5baf.c
index 774e0d0c94cb..30a9ca62e034 100644
--- a/drivers/media/i2c/s5k5baf.c
+++ b/drivers/media/i2c/s5k5baf.c
@@ -1905,7 +1905,7 @@ static int s5k5baf_configure_subdevs(struct s5k5baf *state,
 
 	state->cis_pad.flags = MEDIA_PAD_FL_SOURCE;
 	sd->entity.type = MEDIA_ENT_T_V4L2_SUBDEV_SENSOR;
-	ret = media_entity_init(&sd->entity, NUM_CIS_PADS, &state->cis_pad, 0);
+	ret = media_entity_init(&sd->entity, NUM_CIS_PADS, &state->cis_pad);
 	if (ret < 0)
 		goto err;
 
@@ -1920,7 +1920,7 @@ static int s5k5baf_configure_subdevs(struct s5k5baf *state,
 	state->pads[PAD_CIS].flags = MEDIA_PAD_FL_SINK;
 	state->pads[PAD_OUT].flags = MEDIA_PAD_FL_SOURCE;
 	sd->entity.type = MEDIA_ENT_T_V4L2_SUBDEV;
-	ret = media_entity_init(&sd->entity, NUM_ISP_PADS, state->pads, 0);
+	ret = media_entity_init(&sd->entity, NUM_ISP_PADS, state->pads);
 
 	if (!ret)
 		return 0;
diff --git a/drivers/media/i2c/s5k6a3.c b/drivers/media/i2c/s5k6a3.c
index bc389d5e42ae..617a065bde6f 100644
--- a/drivers/media/i2c/s5k6a3.c
+++ b/drivers/media/i2c/s5k6a3.c
@@ -333,7 +333,7 @@ static int s5k6a3_probe(struct i2c_client *client,
 	sensor->format.height = S5K6A3_DEFAULT_HEIGHT;
 
 	sensor->pad.flags = MEDIA_PAD_FL_SOURCE;
-	ret = media_entity_init(&sd->entity, 1, &sensor->pad, 0);
+	ret = media_entity_init(&sd->entity, 1, &sensor->pad);
 	if (ret < 0)
 		return ret;
 
diff --git a/drivers/media/i2c/s5k6aa.c b/drivers/media/i2c/s5k6aa.c
index d0ad6a25bdab..39a461f9d9bb 100644
--- a/drivers/media/i2c/s5k6aa.c
+++ b/drivers/media/i2c/s5k6aa.c
@@ -1578,7 +1578,7 @@ static int s5k6aa_probe(struct i2c_client *client,
 
 	s5k6aa->pad.flags = MEDIA_PAD_FL_SOURCE;
 	sd->entity.type = MEDIA_ENT_T_V4L2_SUBDEV_SENSOR;
-	ret = media_entity_init(&sd->entity, 1, &s5k6aa->pad, 0);
+	ret = media_entity_init(&sd->entity, 1, &s5k6aa->pad);
 	if (ret)
 		return ret;
 
diff --git a/drivers/media/i2c/smiapp/smiapp-core.c b/drivers/media/i2c/smiapp/smiapp-core.c
index 636ebd6fe5dc..308613ea0aed 100644
--- a/drivers/media/i2c/smiapp/smiapp-core.c
+++ b/drivers/media/i2c/smiapp/smiapp-core.c
@@ -2488,7 +2488,7 @@ static int smiapp_register_subdevs(struct smiapp_sensor *sensor)
 			continue;
 
 		rval = media_entity_init(&this->sd.entity,
-					 this->npads, this->pads, 0);
+					 this->npads, this->pads);
 		if (rval) {
 			dev_err(&client->dev,
 				"media_entity_init failed\n");
@@ -3078,7 +3078,7 @@ static int smiapp_probe(struct i2c_client *client,
 
 	sensor->src->pads[0].flags = MEDIA_PAD_FL_SOURCE;
 	rval = media_entity_init(&sensor->src->sd.entity, 2,
-				 sensor->src->pads, 0);
+				 sensor->src->pads);
 	if (rval < 0)
 		return rval;
 
diff --git a/drivers/media/i2c/tc358743.c b/drivers/media/i2c/tc358743.c
index d0dd83d7a38e..39f47044af24 100644
--- a/drivers/media/i2c/tc358743.c
+++ b/drivers/media/i2c/tc358743.c
@@ -1880,7 +1880,7 @@ static int tc358743_probe(struct i2c_client *client,
 	}
 
 	state->pad.flags = MEDIA_PAD_FL_SOURCE;
-	err = media_entity_init(&sd->entity, 1, &state->pad, 0);
+	err = media_entity_init(&sd->entity, 1, &state->pad);
 	if (err < 0)
 		goto err_hdl;
 
diff --git a/drivers/media/i2c/tvp514x.c b/drivers/media/i2c/tvp514x.c
index a93985a9b070..11801636d901 100644
--- a/drivers/media/i2c/tvp514x.c
+++ b/drivers/media/i2c/tvp514x.c
@@ -1097,7 +1097,7 @@ tvp514x_probe(struct i2c_client *client, const struct i2c_device_id *id)
 	decoder->sd.flags |= V4L2_SUBDEV_FL_HAS_DEVNODE;
 	decoder->sd.entity.flags |= MEDIA_ENT_T_V4L2_SUBDEV_DECODER;
 
-	ret = media_entity_init(&decoder->sd.entity, 1, &decoder->pad, 0);
+	ret = media_entity_init(&decoder->sd.entity, 1, &decoder->pad);
 	if (ret < 0) {
 		v4l2_err(sd, "%s decoder driver failed to register !!\n",
 			 sd->name);
diff --git a/drivers/media/i2c/tvp7002.c b/drivers/media/i2c/tvp7002.c
index f617d8b745ee..3630f3e2a4c7 100644
--- a/drivers/media/i2c/tvp7002.c
+++ b/drivers/media/i2c/tvp7002.c
@@ -1014,7 +1014,7 @@ static int tvp7002_probe(struct i2c_client *c, const struct i2c_device_id *id)
 	device->sd.flags |= V4L2_SUBDEV_FL_HAS_DEVNODE;
 	device->sd.entity.flags |= MEDIA_ENT_T_V4L2_SUBDEV_DECODER;
 
-	error = media_entity_init(&device->sd.entity, 1, &device->pad, 0);
+	error = media_entity_init(&device->sd.entity, 1, &device->pad);
 	if (error < 0)
 		return error;
 #endif
diff --git a/drivers/media/media-entity.c b/drivers/media/media-entity.c
index 6985d5c53632..e8451a4a403b 100644
--- a/drivers/media/media-entity.c
+++ b/drivers/media/media-entity.c
@@ -68,7 +68,6 @@ void graph_obj_remove(struct media_graph_obj *gobj)
  * media_entity_init - Initialize a media entity
  *
  * @num_pads: Total number of sink and source pads.
- * @extra_links: Initial estimate of the number of extra links.
  * @pads: Array of 'num_pads' pads.
  *
  * The total number of pads is an intrinsic property of entities known by the
@@ -90,10 +89,10 @@ void graph_obj_remove(struct media_graph_obj *gobj)
  */
 int
 media_entity_init(struct media_entity *entity, u16 num_pads,
-		  struct media_pad *pads, u16 extra_links)
+		  struct media_pad *pads)
 {
 	struct media_link *links;
-	unsigned int max_links = num_pads + extra_links;
+	unsigned int max_links = num_pads;
 	unsigned int i;
 
 	links = kzalloc(max_links * sizeof(links[0]), GFP_KERNEL);
diff --git a/drivers/media/platform/exynos4-is/fimc-capture.c b/drivers/media/platform/exynos4-is/fimc-capture.c
index cfebf292e15a..0627a93b2f3b 100644
--- a/drivers/media/platform/exynos4-is/fimc-capture.c
+++ b/drivers/media/platform/exynos4-is/fimc-capture.c
@@ -1804,7 +1804,7 @@ static int fimc_register_capture_device(struct fimc_dev *fimc,
 	vid_cap->wb_fmt.code = fmt->mbus_code;
 
 	vid_cap->vd_pad.flags = MEDIA_PAD_FL_SINK;
-	ret = media_entity_init(&vfd->entity, 1, &vid_cap->vd_pad, 0);
+	ret = media_entity_init(&vfd->entity, 1, &vid_cap->vd_pad);
 	if (ret)
 		goto err_free_ctx;
 
@@ -1897,7 +1897,7 @@ int fimc_initialize_capture_subdev(struct fimc_dev *fimc)
 	fimc->vid_cap.sd_pads[FIMC_SD_PAD_SINK_FIFO].flags = MEDIA_PAD_FL_SINK;
 	fimc->vid_cap.sd_pads[FIMC_SD_PAD_SOURCE].flags = MEDIA_PAD_FL_SOURCE;
 	ret = media_entity_init(&sd->entity, FIMC_SD_PADS_NUM,
-				fimc->vid_cap.sd_pads, 0);
+				fimc->vid_cap.sd_pads);
 	if (ret)
 		return ret;
 
diff --git a/drivers/media/platform/exynos4-is/fimc-isp-video.c b/drivers/media/platform/exynos4-is/fimc-isp-video.c
index 76b6b4d14616..b7dc5ac66e36 100644
--- a/drivers/media/platform/exynos4-is/fimc-isp-video.c
+++ b/drivers/media/platform/exynos4-is/fimc-isp-video.c
@@ -618,7 +618,7 @@ int fimc_isp_video_device_register(struct fimc_isp *isp,
 	vdev->lock = &isp->video_lock;
 
 	iv->pad.flags = MEDIA_PAD_FL_SINK;
-	ret = media_entity_init(&vdev->entity, 1, &iv->pad, 0);
+	ret = media_entity_init(&vdev->entity, 1, &iv->pad);
 	if (ret < 0)
 		return ret;
 
diff --git a/drivers/media/platform/exynos4-is/fimc-isp.c b/drivers/media/platform/exynos4-is/fimc-isp.c
index 5d78f5716f3b..f52eebf765c1 100644
--- a/drivers/media/platform/exynos4-is/fimc-isp.c
+++ b/drivers/media/platform/exynos4-is/fimc-isp.c
@@ -709,7 +709,7 @@ int fimc_isp_subdev_create(struct fimc_isp *isp)
 	isp->subdev_pads[FIMC_ISP_SD_PAD_SRC_FIFO].flags = MEDIA_PAD_FL_SOURCE;
 	isp->subdev_pads[FIMC_ISP_SD_PAD_SRC_DMA].flags = MEDIA_PAD_FL_SOURCE;
 	ret = media_entity_init(&sd->entity, FIMC_ISP_SD_PADS_NUM,
-				isp->subdev_pads, 0);
+				isp->subdev_pads);
 	if (ret)
 		return ret;
 
diff --git a/drivers/media/platform/exynos4-is/fimc-lite.c b/drivers/media/platform/exynos4-is/fimc-lite.c
index ca6261a86a5f..e8f707d1729b 100644
--- a/drivers/media/platform/exynos4-is/fimc-lite.c
+++ b/drivers/media/platform/exynos4-is/fimc-lite.c
@@ -1322,7 +1322,7 @@ static int fimc_lite_subdev_registered(struct v4l2_subdev *sd)
 		return ret;
 
 	fimc->vd_pad.flags = MEDIA_PAD_FL_SINK;
-	ret = media_entity_init(&vfd->entity, 1, &fimc->vd_pad, 0);
+	ret = media_entity_init(&vfd->entity, 1, &fimc->vd_pad);
 	if (ret < 0)
 		return ret;
 
@@ -1437,7 +1437,7 @@ static int fimc_lite_create_capture_subdev(struct fimc_lite *fimc)
 	fimc->subdev_pads[FLITE_SD_PAD_SOURCE_DMA].flags = MEDIA_PAD_FL_SOURCE;
 	fimc->subdev_pads[FLITE_SD_PAD_SOURCE_ISP].flags = MEDIA_PAD_FL_SOURCE;
 	ret = media_entity_init(&sd->entity, FLITE_SD_PADS_NUM,
-				fimc->subdev_pads, 0);
+				fimc->subdev_pads);
 	if (ret)
 		return ret;
 
diff --git a/drivers/media/platform/exynos4-is/fimc-m2m.c b/drivers/media/platform/exynos4-is/fimc-m2m.c
index 0ad1b6f84a27..b57daec48b21 100644
--- a/drivers/media/platform/exynos4-is/fimc-m2m.c
+++ b/drivers/media/platform/exynos4-is/fimc-m2m.c
@@ -738,7 +738,7 @@ int fimc_register_m2m_device(struct fimc_dev *fimc,
 		return PTR_ERR(fimc->m2m.m2m_dev);
 	}
 
-	ret = media_entity_init(&vfd->entity, 0, NULL, 0);
+	ret = media_entity_init(&vfd->entity, 0, NULL);
 	if (ret)
 		goto err_me;
 
diff --git a/drivers/media/platform/exynos4-is/mipi-csis.c b/drivers/media/platform/exynos4-is/mipi-csis.c
index d74e1bec3d86..cf10cd783a86 100644
--- a/drivers/media/platform/exynos4-is/mipi-csis.c
+++ b/drivers/media/platform/exynos4-is/mipi-csis.c
@@ -866,7 +866,7 @@ static int s5pcsis_probe(struct platform_device *pdev)
 	state->pads[CSIS_PAD_SINK].flags = MEDIA_PAD_FL_SINK;
 	state->pads[CSIS_PAD_SOURCE].flags = MEDIA_PAD_FL_SOURCE;
 	ret = media_entity_init(&state->sd.entity,
-				CSIS_PADS_NUM, state->pads, 0);
+				CSIS_PADS_NUM, state->pads);
 	if (ret < 0)
 		goto e_clkdis;
 
diff --git a/drivers/media/platform/omap3isp/ispccdc.c b/drivers/media/platform/omap3isp/ispccdc.c
index a6a61cce43dd..3b10304b580b 100644
--- a/drivers/media/platform/omap3isp/ispccdc.c
+++ b/drivers/media/platform/omap3isp/ispccdc.c
@@ -2650,7 +2650,7 @@ static int ccdc_init_entities(struct isp_ccdc_device *ccdc)
 	pads[CCDC_PAD_SOURCE_OF].flags = MEDIA_PAD_FL_SOURCE;
 
 	me->ops = &ccdc_media_ops;
-	ret = media_entity_init(me, CCDC_PADS_NUM, pads, 0);
+	ret = media_entity_init(me, CCDC_PADS_NUM, pads);
 	if (ret < 0)
 		return ret;
 
diff --git a/drivers/media/platform/omap3isp/ispccp2.c b/drivers/media/platform/omap3isp/ispccp2.c
index 38e6a974c5b1..e1b5f5bea541 100644
--- a/drivers/media/platform/omap3isp/ispccp2.c
+++ b/drivers/media/platform/omap3isp/ispccp2.c
@@ -1071,7 +1071,7 @@ static int ccp2_init_entities(struct isp_ccp2_device *ccp2)
 	pads[CCP2_PAD_SOURCE].flags = MEDIA_PAD_FL_SOURCE;
 
 	me->ops = &ccp2_media_ops;
-	ret = media_entity_init(me, CCP2_PADS_NUM, pads, 0);
+	ret = media_entity_init(me, CCP2_PADS_NUM, pads);
 	if (ret < 0)
 		return ret;
 
diff --git a/drivers/media/platform/omap3isp/ispcsi2.c b/drivers/media/platform/omap3isp/ispcsi2.c
index a78338d012b4..6fff92f0813a 100644
--- a/drivers/media/platform/omap3isp/ispcsi2.c
+++ b/drivers/media/platform/omap3isp/ispcsi2.c
@@ -1245,7 +1245,7 @@ static int csi2_init_entities(struct isp_csi2_device *csi2)
 				    | MEDIA_PAD_FL_MUST_CONNECT;
 
 	me->ops = &csi2_media_ops;
-	ret = media_entity_init(me, CSI2_PADS_NUM, pads, 0);
+	ret = media_entity_init(me, CSI2_PADS_NUM, pads);
 	if (ret < 0)
 		return ret;
 
diff --git a/drivers/media/platform/omap3isp/isppreview.c b/drivers/media/platform/omap3isp/isppreview.c
index 13803270d104..b440c6342ca4 100644
--- a/drivers/media/platform/omap3isp/isppreview.c
+++ b/drivers/media/platform/omap3isp/isppreview.c
@@ -2282,7 +2282,7 @@ static int preview_init_entities(struct isp_prev_device *prev)
 	pads[PREV_PAD_SOURCE].flags = MEDIA_PAD_FL_SOURCE;
 
 	me->ops = &preview_media_ops;
-	ret = media_entity_init(me, PREV_PADS_NUM, pads, 0);
+	ret = media_entity_init(me, PREV_PADS_NUM, pads);
 	if (ret < 0)
 		return ret;
 
diff --git a/drivers/media/platform/omap3isp/ispresizer.c b/drivers/media/platform/omap3isp/ispresizer.c
index 7cfb43dc0ffd..3deb1ec4a973 100644
--- a/drivers/media/platform/omap3isp/ispresizer.c
+++ b/drivers/media/platform/omap3isp/ispresizer.c
@@ -1728,7 +1728,7 @@ static int resizer_init_entities(struct isp_res_device *res)
 	pads[RESZ_PAD_SOURCE].flags = MEDIA_PAD_FL_SOURCE;
 
 	me->ops = &resizer_media_ops;
-	ret = media_entity_init(me, RESZ_PADS_NUM, pads, 0);
+	ret = media_entity_init(me, RESZ_PADS_NUM, pads);
 	if (ret < 0)
 		return ret;
 
diff --git a/drivers/media/platform/omap3isp/ispstat.c b/drivers/media/platform/omap3isp/ispstat.c
index 20434e83e801..92a31dd28ace 100644
--- a/drivers/media/platform/omap3isp/ispstat.c
+++ b/drivers/media/platform/omap3isp/ispstat.c
@@ -1029,7 +1029,7 @@ static int isp_stat_init_entities(struct ispstat *stat, const char *name,
 	stat->pad.flags = MEDIA_PAD_FL_SINK | MEDIA_PAD_FL_MUST_CONNECT;
 	me->ops = NULL;
 
-	return media_entity_init(me, 1, &stat->pad, 0);
+	return media_entity_init(me, 1, &stat->pad);
 }
 
 int omap3isp_stat_init(struct ispstat *stat, const char *name,
diff --git a/drivers/media/platform/omap3isp/ispvideo.c b/drivers/media/platform/omap3isp/ispvideo.c
index d285af18df7f..1809e52d2df9 100644
--- a/drivers/media/platform/omap3isp/ispvideo.c
+++ b/drivers/media/platform/omap3isp/ispvideo.c
@@ -1368,7 +1368,7 @@ int omap3isp_video_init(struct isp_video *video, const char *name)
 	if (IS_ERR(video->alloc_ctx))
 		return PTR_ERR(video->alloc_ctx);
 
-	ret = media_entity_init(&video->video.entity, 1, &video->pad, 0);
+	ret = media_entity_init(&video->video.entity, 1, &video->pad);
 	if (ret < 0) {
 		vb2_dma_contig_cleanup_ctx(video->alloc_ctx);
 		return ret;
diff --git a/drivers/media/platform/s3c-camif/camif-capture.c b/drivers/media/platform/s3c-camif/camif-capture.c
index 76e6289a5612..eae667eab1b9 100644
--- a/drivers/media/platform/s3c-camif/camif-capture.c
+++ b/drivers/media/platform/s3c-camif/camif-capture.c
@@ -1159,7 +1159,7 @@ int s3c_camif_register_video_node(struct camif_dev *camif, int idx)
 		goto err_vd_rel;
 
 	vp->pad.flags = MEDIA_PAD_FL_SINK;
-	ret = media_entity_init(&vfd->entity, 1, &vp->pad, 0);
+	ret = media_entity_init(&vfd->entity, 1, &vp->pad);
 	if (ret)
 		goto err_vd_rel;
 
@@ -1575,7 +1575,7 @@ int s3c_camif_create_subdev(struct camif_dev *camif)
 	camif->pads[CAMIF_SD_PAD_SOURCE_P].flags = MEDIA_PAD_FL_SOURCE;
 
 	ret = media_entity_init(&sd->entity, CAMIF_SD_PADS_NUM,
-				camif->pads, 0);
+				camif->pads);
 	if (ret)
 		return ret;
 
diff --git a/drivers/media/platform/vsp1/vsp1_entity.c b/drivers/media/platform/vsp1/vsp1_entity.c
index fd95a75b04f4..619942ff2058 100644
--- a/drivers/media/platform/vsp1/vsp1_entity.c
+++ b/drivers/media/platform/vsp1/vsp1_entity.c
@@ -220,7 +220,7 @@ int vsp1_entity_init(struct vsp1_device *vsp1, struct vsp1_entity *entity,
 
 	/* Initialize the media entity. */
 	return media_entity_init(&entity->subdev.entity, num_pads,
-				 entity->pads, 0);
+				 entity->pads);
 }
 
 void vsp1_entity_destroy(struct vsp1_entity *entity)
diff --git a/drivers/media/platform/vsp1/vsp1_video.c b/drivers/media/platform/vsp1/vsp1_video.c
index 3c124c14ce14..17f08973f835 100644
--- a/drivers/media/platform/vsp1/vsp1_video.c
+++ b/drivers/media/platform/vsp1/vsp1_video.c
@@ -1221,7 +1221,7 @@ int vsp1_video_init(struct vsp1_video *video, struct vsp1_entity *rwpf)
 	video->pipe.state = VSP1_PIPELINE_STOPPED;
 
 	/* Initialize the media entity... */
-	ret = media_entity_init(&video->video.entity, 1, &video->pad, 0);
+	ret = media_entity_init(&video->video.entity, 1, &video->pad);
 	if (ret < 0)
 		return ret;
 
diff --git a/drivers/media/platform/xilinx/xilinx-dma.c b/drivers/media/platform/xilinx/xilinx-dma.c
index e779c93cb015..f7f9aa353a55 100644
--- a/drivers/media/platform/xilinx/xilinx-dma.c
+++ b/drivers/media/platform/xilinx/xilinx-dma.c
@@ -676,7 +676,7 @@ int xvip_dma_init(struct xvip_composite_device *xdev, struct xvip_dma *dma,
 	dma->pad.flags = type == V4L2_BUF_TYPE_VIDEO_CAPTURE
 		       ? MEDIA_PAD_FL_SINK : MEDIA_PAD_FL_SOURCE;
 
-	ret = media_entity_init(&dma->video.entity, 1, &dma->pad, 0);
+	ret = media_entity_init(&dma->video.entity, 1, &dma->pad);
 	if (ret < 0)
 		goto error;
 
diff --git a/drivers/media/platform/xilinx/xilinx-tpg.c b/drivers/media/platform/xilinx/xilinx-tpg.c
index b5f7d5ecb7f6..285976aa0f4d 100644
--- a/drivers/media/platform/xilinx/xilinx-tpg.c
+++ b/drivers/media/platform/xilinx/xilinx-tpg.c
@@ -836,7 +836,7 @@ static int xtpg_probe(struct platform_device *pdev)
 	subdev->flags |= V4L2_SUBDEV_FL_HAS_DEVNODE;
 	subdev->entity.ops = &xtpg_media_ops;
 
-	ret = media_entity_init(&subdev->entity, xtpg->npads, xtpg->pads, 0);
+	ret = media_entity_init(&subdev->entity, xtpg->npads, xtpg->pads);
 	if (ret < 0)
 		goto error;
 
diff --git a/drivers/media/usb/cx231xx/cx231xx-video.c b/drivers/media/usb/cx231xx/cx231xx-video.c
index c6ff8968286a..8f04b125486f 100644
--- a/drivers/media/usb/cx231xx/cx231xx-video.c
+++ b/drivers/media/usb/cx231xx/cx231xx-video.c
@@ -2175,7 +2175,7 @@ int cx231xx_register_analog_devices(struct cx231xx *dev)
 	cx231xx_vdev_init(dev, &dev->vdev, &cx231xx_video_template, "video");
 #if defined(CONFIG_MEDIA_CONTROLLER)
 	dev->video_pad.flags = MEDIA_PAD_FL_SINK;
-	ret = media_entity_init(&dev->vdev.entity, 1, &dev->video_pad, 0);
+	ret = media_entity_init(&dev->vdev.entity, 1, &dev->video_pad);
 	if (ret < 0)
 		dev_err(dev->dev, "failed to initialize video media entity!\n");
 #endif
@@ -2202,7 +2202,7 @@ int cx231xx_register_analog_devices(struct cx231xx *dev)
 
 #if defined(CONFIG_MEDIA_CONTROLLER)
 	dev->vbi_pad.flags = MEDIA_PAD_FL_SINK;
-	ret = media_entity_init(&dev->vbi_dev.entity, 1, &dev->vbi_pad, 0);
+	ret = media_entity_init(&dev->vbi_dev.entity, 1, &dev->vbi_pad);
 	if (ret < 0)
 		dev_err(dev->dev, "failed to initialize vbi media entity!\n");
 #endif
diff --git a/drivers/media/usb/uvc/uvc_entity.c b/drivers/media/usb/uvc/uvc_entity.c
index dc56a59ecadc..245445491516 100644
--- a/drivers/media/usb/uvc/uvc_entity.c
+++ b/drivers/media/usb/uvc/uvc_entity.c
@@ -89,10 +89,10 @@ static int uvc_mc_init_entity(struct uvc_entity *entity)
 			sizeof(entity->subdev.name));
 
 		ret = media_entity_init(&entity->subdev.entity,
-					entity->num_pads, entity->pads, 0);
+					entity->num_pads, entity->pads);
 	} else if (entity->vdev != NULL) {
 		ret = media_entity_init(&entity->vdev->entity,
-					entity->num_pads, entity->pads, 0);
+					entity->num_pads, entity->pads);
 		if (entity->flags & UVC_ENTITY_FLAG_DEFAULT)
 			entity->vdev->entity.flags |= MEDIA_ENT_FL_DEFAULT;
 	} else
diff --git a/drivers/media/v4l2-core/tuner-core.c b/drivers/media/v4l2-core/tuner-core.c
index abdcffabcb59..0ccf9a903e1e 100644
--- a/drivers/media/v4l2-core/tuner-core.c
+++ b/drivers/media/v4l2-core/tuner-core.c
@@ -699,7 +699,7 @@ register_client:
 	t->sd.entity.type = MEDIA_ENT_T_V4L2_SUBDEV_TUNER;
 	t->sd.entity.name = t->name;
 
-	ret = media_entity_init(&t->sd.entity, 1, &t->pad, 0);
+	ret = media_entity_init(&t->sd.entity, 1, &t->pad);
 	if (ret < 0) {
 		tuner_err("failed to initialize media entity!\n");
 		kfree(t);
diff --git a/drivers/media/v4l2-core/v4l2-flash-led-class.c b/drivers/media/v4l2-core/v4l2-flash-led-class.c
index 5bdfb8d5263a..34c489fed55e 100644
--- a/drivers/media/v4l2-core/v4l2-flash-led-class.c
+++ b/drivers/media/v4l2-core/v4l2-flash-led-class.c
@@ -651,7 +651,7 @@ struct v4l2_flash *v4l2_flash_init(
 	sd->flags |= V4L2_SUBDEV_FL_HAS_DEVNODE;
 	strlcpy(sd->name, config->dev_name, sizeof(sd->name));
 
-	ret = media_entity_init(&sd->entity, 0, NULL, 0);
+	ret = media_entity_init(&sd->entity, 0, NULL);
 	if (ret < 0)
 		return ERR_PTR(ret);
 
diff --git a/drivers/staging/media/davinci_vpfe/dm365_ipipe.c b/drivers/staging/media/davinci_vpfe/dm365_ipipe.c
index 1bbb90ce0086..b89a057b8b7e 100644
--- a/drivers/staging/media/davinci_vpfe/dm365_ipipe.c
+++ b/drivers/staging/media/davinci_vpfe/dm365_ipipe.c
@@ -1839,7 +1839,7 @@ vpfe_ipipe_init(struct vpfe_ipipe_device *ipipe, struct platform_device *pdev)
 	v4l2_ctrl_handler_setup(&ipipe->ctrls);
 	sd->ctrl_handler = &ipipe->ctrls;
 
-	return media_entity_init(me, IPIPE_PADS_NUM, pads, 0);
+	return media_entity_init(me, IPIPE_PADS_NUM, pads);
 }
 
 /*
diff --git a/drivers/staging/media/davinci_vpfe/dm365_ipipeif.c b/drivers/staging/media/davinci_vpfe/dm365_ipipeif.c
index 8b230541b1d1..8fb676186898 100644
--- a/drivers/staging/media/davinci_vpfe/dm365_ipipeif.c
+++ b/drivers/staging/media/davinci_vpfe/dm365_ipipeif.c
@@ -1026,7 +1026,7 @@ int vpfe_ipipeif_init(struct vpfe_ipipeif_device *ipipeif,
 	ipipeif->output = IPIPEIF_OUTPUT_NONE;
 	me->ops = &ipipeif_media_ops;
 
-	ret = media_entity_init(me, IPIPEIF_NUM_PADS, pads, 0);
+	ret = media_entity_init(me, IPIPEIF_NUM_PADS, pads);
 	if (ret)
 		goto fail;
 
diff --git a/drivers/staging/media/davinci_vpfe/dm365_isif.c b/drivers/staging/media/davinci_vpfe/dm365_isif.c
index 80907b464412..b1f01adfa7c8 100644
--- a/drivers/staging/media/davinci_vpfe/dm365_isif.c
+++ b/drivers/staging/media/davinci_vpfe/dm365_isif.c
@@ -2052,7 +2052,7 @@ int vpfe_isif_init(struct vpfe_isif_device *isif, struct platform_device *pdev)
 	isif->input = ISIF_INPUT_NONE;
 	isif->output = ISIF_OUTPUT_NONE;
 	me->ops = &isif_media_ops;
-	status = media_entity_init(me, ISIF_PADS_NUM, pads, 0);
+	status = media_entity_init(me, ISIF_PADS_NUM, pads);
 	if (status)
 		goto isif_fail;
 	isif->video_out.type = V4L2_BUF_TYPE_VIDEO_CAPTURE;
diff --git a/drivers/staging/media/davinci_vpfe/dm365_resizer.c b/drivers/staging/media/davinci_vpfe/dm365_resizer.c
index acb293ed9c91..692789aa22f4 100644
--- a/drivers/staging/media/davinci_vpfe/dm365_resizer.c
+++ b/drivers/staging/media/davinci_vpfe/dm365_resizer.c
@@ -1915,7 +1915,7 @@ int vpfe_resizer_init(struct vpfe_resizer_device *vpfe_rsz,
 	vpfe_rsz->crop_resizer.output2 = RESIZER_CROP_OUTPUT_NONE;
 	vpfe_rsz->crop_resizer.rsz_device = vpfe_rsz;
 	me->ops = &resizer_media_ops;
-	ret = media_entity_init(me, RESIZER_CROP_PADS_NUM, pads, 0);
+	ret = media_entity_init(me, RESIZER_CROP_PADS_NUM, pads);
 	if (ret)
 		return ret;
 
@@ -1937,7 +1937,7 @@ int vpfe_resizer_init(struct vpfe_resizer_device *vpfe_rsz,
 	vpfe_rsz->resizer_a.output = RESIZER_OUTPUT_NONE;
 	vpfe_rsz->resizer_a.rsz_device = vpfe_rsz;
 	me->ops = &resizer_media_ops;
-	ret = media_entity_init(me, RESIZER_PADS_NUM, pads, 0);
+	ret = media_entity_init(me, RESIZER_PADS_NUM, pads);
 	if (ret)
 		return ret;
 
@@ -1959,7 +1959,7 @@ int vpfe_resizer_init(struct vpfe_resizer_device *vpfe_rsz,
 	vpfe_rsz->resizer_b.output = RESIZER_OUTPUT_NONE;
 	vpfe_rsz->resizer_b.rsz_device = vpfe_rsz;
 	me->ops = &resizer_media_ops;
-	ret = media_entity_init(me, RESIZER_PADS_NUM, pads, 0);
+	ret = media_entity_init(me, RESIZER_PADS_NUM, pads);
 	if (ret)
 		return ret;
 
diff --git a/drivers/staging/media/davinci_vpfe/vpfe_video.c b/drivers/staging/media/davinci_vpfe/vpfe_video.c
index 87048a14c34d..61a8d5beff58 100644
--- a/drivers/staging/media/davinci_vpfe/vpfe_video.c
+++ b/drivers/staging/media/davinci_vpfe/vpfe_video.c
@@ -1594,7 +1594,7 @@ int vpfe_video_init(struct vpfe_video_device *video, const char *name)
 	spin_lock_init(&video->dma_queue_lock);
 	mutex_init(&video->lock);
 	ret = media_entity_init(&video->video_dev.entity,
-				1, &video->pad, 0);
+				1, &video->pad);
 	if (ret < 0)
 		return ret;
 
diff --git a/drivers/staging/media/omap4iss/iss_csi2.c b/drivers/staging/media/omap4iss/iss_csi2.c
index bc83f8246101..e936cfc218cb 100644
--- a/drivers/staging/media/omap4iss/iss_csi2.c
+++ b/drivers/staging/media/omap4iss/iss_csi2.c
@@ -1271,7 +1271,7 @@ static int csi2_init_entities(struct iss_csi2_device *csi2, const char *subname)
 	pads[CSI2_PAD_SINK].flags = MEDIA_PAD_FL_SINK;
 
 	me->ops = &csi2_media_ops;
-	ret = media_entity_init(me, CSI2_PADS_NUM, pads, 0);
+	ret = media_entity_init(me, CSI2_PADS_NUM, pads);
 	if (ret < 0)
 		return ret;
 
diff --git a/drivers/staging/media/omap4iss/iss_ipipe.c b/drivers/staging/media/omap4iss/iss_ipipe.c
index f94a59299a83..e1a7b7ba7362 100644
--- a/drivers/staging/media/omap4iss/iss_ipipe.c
+++ b/drivers/staging/media/omap4iss/iss_ipipe.c
@@ -513,7 +513,7 @@ static int ipipe_init_entities(struct iss_ipipe_device *ipipe)
 	pads[IPIPE_PAD_SOURCE_VP].flags = MEDIA_PAD_FL_SOURCE;
 
 	me->ops = &ipipe_media_ops;
-	ret = media_entity_init(me, IPIPE_PADS_NUM, pads, 0);
+	ret = media_entity_init(me, IPIPE_PADS_NUM, pads);
 	if (ret < 0)
 		return ret;
 
diff --git a/drivers/staging/media/omap4iss/iss_ipipeif.c b/drivers/staging/media/omap4iss/iss_ipipeif.c
index c0da13d55865..be5f80d7b5dc 100644
--- a/drivers/staging/media/omap4iss/iss_ipipeif.c
+++ b/drivers/staging/media/omap4iss/iss_ipipeif.c
@@ -743,7 +743,7 @@ static int ipipeif_init_entities(struct iss_ipipeif_device *ipipeif)
 	pads[IPIPEIF_PAD_SOURCE_VP].flags = MEDIA_PAD_FL_SOURCE;
 
 	me->ops = &ipipeif_media_ops;
-	ret = media_entity_init(me, IPIPEIF_PADS_NUM, pads, 0);
+	ret = media_entity_init(me, IPIPEIF_PADS_NUM, pads);
 	if (ret < 0)
 		return ret;
 
diff --git a/drivers/staging/media/omap4iss/iss_resizer.c b/drivers/staging/media/omap4iss/iss_resizer.c
index 5030cf3cd34c..91e724085dba 100644
--- a/drivers/staging/media/omap4iss/iss_resizer.c
+++ b/drivers/staging/media/omap4iss/iss_resizer.c
@@ -787,7 +787,7 @@ static int resizer_init_entities(struct iss_resizer_device *resizer)
 	pads[RESIZER_PAD_SOURCE_MEM].flags = MEDIA_PAD_FL_SOURCE;
 
 	me->ops = &resizer_media_ops;
-	ret = media_entity_init(me, RESIZER_PADS_NUM, pads, 0);
+	ret = media_entity_init(me, RESIZER_PADS_NUM, pads);
 	if (ret < 0)
 		return ret;
 
diff --git a/drivers/staging/media/omap4iss/iss_video.c b/drivers/staging/media/omap4iss/iss_video.c
index 40405d8710a6..bae67742706f 100644
--- a/drivers/staging/media/omap4iss/iss_video.c
+++ b/drivers/staging/media/omap4iss/iss_video.c
@@ -1104,7 +1104,7 @@ int omap4iss_video_init(struct iss_video *video, const char *name)
 		return -EINVAL;
 	}
 
-	ret = media_entity_init(&video->video.entity, 1, &video->pad, 0);
+	ret = media_entity_init(&video->video.entity, 1, &video->pad);
 	if (ret < 0)
 		return ret;
 
diff --git a/include/media/media-entity.h b/include/media/media-entity.h
index 738e1d5d25dc..be6885e7c8ed 100644
--- a/include/media/media-entity.h
+++ b/include/media/media-entity.h
@@ -177,7 +177,7 @@ void graph_obj_init(struct media_device *mdev,
 void graph_obj_remove(struct media_graph_obj *gobj);
 
 int media_entity_init(struct media_entity *entity, u16 num_pads,
-		struct media_pad *pads, u16 extra_links);
+		struct media_pad *pads);
 void media_entity_cleanup(struct media_entity *entity);
 
 int media_entity_create_link(struct media_entity *source, u16 source_pad,
-- 
2.4.3



From bjorn.andersson at sonymobile.com  Wed Aug 12 13:18:55 2015
From: bjorn.andersson at sonymobile.com (Bjorn Andersson)
Date: Wed, 12 Aug 2015 13:18:55 -0700
Subject: [PATCH 5/9] clk: qcom: gcc-msm8960: add child devices support.
In-Reply-To: <20150811224902.GO2839@codeaurora.org>
References: <1436348838-22671-1-git-send-email-rnayak@codeaurora.org>
 <1436348838-22671-6-git-send-email-rnayak@codeaurora.org>
 <20150811224902.GO2839@codeaurora.org>
Message-ID: <20150812201855.GF13472@usrtlx11787.corpusers.net>

On Tue 11 Aug 15:49 PDT 2015, Stephen Boyd wrote:

> On 07/08, Rajendra Nayak wrote:
> > diff --git a/drivers/clk/qcom/gcc-msm8960.c b/drivers/clk/qcom/gcc-msm8960.c
> > index eb6a4f9..2c80d03 100644
> > --- a/drivers/clk/qcom/gcc-msm8960.c
> > +++ b/drivers/clk/qcom/gcc-msm8960.c
> > @@ -15,6 +15,7 @@
> >  #include <linux/bitops.h>
> >  #include <linux/err.h>
> >  #include <linux/platform_device.h>
> > +#include <linux/of_platform.h>
> >  #include <linux/module.h>
> >  #include <linux/of.h>
> >  #include <linux/of_device.h>
> > @@ -3520,7 +3521,8 @@ static int gcc_msm8960_probe(struct platform_device *pdev)
> >  	if (IS_ERR(clk))
> >  		return PTR_ERR(clk);
> >  
> > -	return qcom_cc_probe(pdev, match->data);
> > +	qcom_cc_probe(pdev, match->data);
> > +	return of_platform_populate(pdev->dev.of_node, NULL, NULL, &pdev->dev);
> 
> We just lost the error code from qcom_cc_probe()...
> 
> Also, I don't like having a subnode in DT. Why can't we use the
> same node as the GCC node and create a virtual child device here
> for tsens? We can assign the same of_node that this platform
> device has so that DT keeps working correctly.
> 

Can't we make the gcc driver support being a child of a simple-mfd by
having it attempting to acquire the regmap of the parent and falling
back to creating its own mmio regmap?

That way we don't need to make tsense a child of the clock device and
we're still backwards compatible.

Regards,
Bjorn


From john.stultz at linaro.org  Wed Aug 12 13:00:53 2015
From: john.stultz at linaro.org (John Stultz)
Date: Wed, 12 Aug 2015 13:00:53 -0700
Subject: [PATCH 2/2] arm64: VDSO: fix coarse clock monotonicity regression
In-Reply-To: <1438999403-5770-3-git-send-email-nathan_lynch@mentor.com>
References: <1438999403-5770-1-git-send-email-nathan_lynch@mentor.com>
 <1438999403-5770-3-git-send-email-nathan_lynch@mentor.com>
Message-ID: <CALAqxLVt43ntH04FJCTXujhtNQ8KAOcTSfyZ5TnKs=R7m2grNA@mail.gmail.com>

On Fri, Aug 7, 2015 at 7:03 PM, Nathan Lynch <nathan_lynch at mentor.com> wrote:
> Since 906c55579a63 ("timekeeping: Copy the shadow-timekeeper over the
> real timekeeper last") it has become possible on arm64 to:
>
> - Obtain a CLOCK_MONOTONIC_COARSE or CLOCK_REALTIME_COARSE timestamp
>   via syscall.
> - Subsequently obtain a timestamp for the same clock ID via VDSO which
>   predates the first timestamp (by one jiffy).
>
> This is because arm64's update_vsyscall is deriving the coarse time
> using the __current_kernel_time interface, when it should really be
> using the timekeeper object provided to it by the timekeeping core.
> It happened to work before only because __current_kernel_time would
> access the same timekeeper object which had been passed to
> update_vsyscall.  This is no longer the case.
>
> Signed-off-by: Nathan Lynch <nathan_lynch at mentor.com>
> ---
>  arch/arm64/kernel/vdso.c | 7 +++----
>  1 file changed, 3 insertions(+), 4 deletions(-)
>
> diff --git a/arch/arm64/kernel/vdso.c b/arch/arm64/kernel/vdso.c
> index ec37ab3f524f..97bc68f4c689 100644
> --- a/arch/arm64/kernel/vdso.c
> +++ b/arch/arm64/kernel/vdso.c
> @@ -199,16 +199,15 @@ int arch_setup_additional_pages(struct linux_binprm *bprm,
>   */
>  void update_vsyscall(struct timekeeper *tk)
>  {
> -       struct timespec xtime_coarse;
>         u32 use_syscall = strcmp(tk->tkr_mono.clock->name, "arch_sys_counter");
>
>         ++vdso_data->tb_seq_count;
>         smp_wmb();
>
> -       xtime_coarse = __current_kernel_time();
>         vdso_data->use_syscall                  = use_syscall;
> -       vdso_data->xtime_coarse_sec             = xtime_coarse.tv_sec;
> -       vdso_data->xtime_coarse_nsec            = xtime_coarse.tv_nsec;
> +       vdso_data->xtime_coarse_sec             = tk->xtime_sec;
> +       vdso_data->xtime_coarse_nsec            = tk->tkr_mono.xtime_nsec >>
> +                                                       tk->tkr_mono.shift;
>         vdso_data->wtm_clock_sec                = tk->wall_to_monotonic.tv_sec;
>         vdso_data->wtm_clock_nsec               = tk->wall_to_monotonic.tv_nsec;
>

(Sorry for the slow response, I've been out on vacation).

If its worth anything now:
Acked-by: John Stultz <john.stultz at linaro.org>

thanks
-john


From khilman at kernel.org  Wed Aug 12 13:28:06 2015
From: khilman at kernel.org (Kevin Hilman)
Date: Wed, 12 Aug 2015 13:28:06 -0700
Subject: [PATCH 9/9] ARM: smp: Add runtime PM support for CPU hotplug
In-Reply-To: <1438731339-58317-10-git-send-email-lina.iyer@linaro.org> (Lina
 Iyer's message of "Tue, 4 Aug 2015 17:35:39 -0600")
References: <1438731339-58317-1-git-send-email-lina.iyer@linaro.org>
 <1438731339-58317-10-git-send-email-lina.iyer@linaro.org>
Message-ID: <7hoaicmeuh.fsf@deeprootsystems.com>

Lina Iyer <lina.iyer at linaro.org> writes:

> Enable runtime PM for CPU devices. Do a runtime get of the CPU device
> when the CPU is hotplugged in and a runtime put of the CPU device when
> the CPU is hotplugged off. When all the CPUs in a domain are hotplugged
> off, the domain may also be powered off and cluster_pm_enter/exit()
> notifications are be sent out.
>
> Cc: Catalin Marinas <catalin.marinas at arm.com>
> Cc: Mark Rutland <mark.rutland at arm.com>
> Cc: Lorenzo Pieralisi <lorenzo.pieralisi at arm.com>
> Signed-off-by: Lina Iyer <lina.iyer at linaro.org>

How does the runtiem PM usage with hotplug work with the runtime PM
usage in idle?

IIUC, when a CPU is hotplugged in, it will always have a usecount of at
least 1, right?  and if it's not idle, it will have done a _get() so it
will have a usecount of at least 2.   So I'm not quite seeing how the
usecount will ever go to zero in idle and allow the domain to power_off.

Kevin


From lina.iyer at linaro.org  Wed Aug 12 13:43:26 2015
From: lina.iyer at linaro.org (Lina Iyer)
Date: Wed, 12 Aug 2015 14:43:26 -0600
Subject: [PATCH 9/9] ARM: smp: Add runtime PM support for CPU hotplug
In-Reply-To: <7hoaicmeuh.fsf@deeprootsystems.com>
References: <1438731339-58317-1-git-send-email-lina.iyer@linaro.org>
 <1438731339-58317-10-git-send-email-lina.iyer@linaro.org>
 <7hoaicmeuh.fsf@deeprootsystems.com>
Message-ID: <20150812204326.GM52339@linaro.org>

On Wed, Aug 12 2015 at 14:28 -0600, Kevin Hilman wrote:
>Lina Iyer <lina.iyer at linaro.org> writes:
>
>> Enable runtime PM for CPU devices. Do a runtime get of the CPU device
>> when the CPU is hotplugged in and a runtime put of the CPU device when
>> the CPU is hotplugged off. When all the CPUs in a domain are hotplugged
>> off, the domain may also be powered off and cluster_pm_enter/exit()
>> notifications are be sent out.
>>
>> Cc: Catalin Marinas <catalin.marinas at arm.com>
>> Cc: Mark Rutland <mark.rutland at arm.com>
>> Cc: Lorenzo Pieralisi <lorenzo.pieralisi at arm.com>
>> Signed-off-by: Lina Iyer <lina.iyer at linaro.org>
>
>How does the runtiem PM usage with hotplug work with the runtime PM
>usage in idle?
>
>IIUC, when a CPU is hotplugged in, it will always have a usecount of at
>least 1, right?  and if it's not idle, it will have done a _get() so it
>will have a usecount of at least 2.   So I'm not quite seeing how the
>usecount will ever go to zero in idle and allow the domain to power_off.
>
When the CPU is online and running, it would have a ref count of 1. Then
cpuidle would do a _put and the ref count would go to 0 and when coming
out of idle, cpuidle would get a _get and the ref count will be back at
1. Ref count is not incremented when cpuidle is initialized on the CPU.
So whenever the CPU is running, it would have a ref count of 1.

As of today, atleast my understanding is hotplug does not go back into
cpuidle, so the ref count would go to 0 when the core is hotplugged off.
This may change, if the CPU hotplug is routed to cpuidle.

Am I wrong in my understanding?

Thanks,
Lina


From lina.iyer at linaro.org  Wed Aug 12 13:47:14 2015
From: lina.iyer at linaro.org (Lina Iyer)
Date: Wed, 12 Aug 2015 14:47:14 -0600
Subject: [PATCH 3/9] PM / Domains: Support IRQ safe PM domains
In-Reply-To: <7hy4hgmfkq.fsf@deeprootsystems.com>
References: <1438731339-58317-1-git-send-email-lina.iyer@linaro.org>
 <1438731339-58317-4-git-send-email-lina.iyer@linaro.org>
 <7hy4hgmfkq.fsf@deeprootsystems.com>
Message-ID: <20150812204714.GN52339@linaro.org>

On Wed, Aug 12 2015 at 14:12 -0600, Kevin Hilman wrote:
>Lina Iyer <lina.iyer at linaro.org> writes:
>
>> Generic Power Domains currently support turning on/off only in process
>> context. This prevents the usage of PM domains for domains that could be
>> powered on/off in a context where IRQs are disabled. Many such domains
>> exist today and do not get powered off, when the IRQ safe devices in
>> that domain are powered off, because of this limitation.
>>
>> However, not all domains can operate in IRQ safe contexts. Genpd
>> therefore, has to support both cases where the domain may or may not
>> operate in IRQ safe contexts. Configuring genpd to use an appropriate
>> lock for that domain, would allow domains that have IRQ safe devices to
>> runtime suspend and resume, in atomic context.
>>
>> To achieve domain specific locking, set the domain's ->flag to
>> GENPD_FLAG_IRQ_SAFE while defining the domain. This indicates that genpd
>> should use a spinlock instead of a mutex for locking the domain. Locking
>> is abstracted through genpd_lock() and genpd_unlock() functions that use
>> the flag to determine the appropriate lock to be used for that domain.
>> Domains that have lower latency to suspend and resume and can operate
>> with IRQs disabled may now be able to save power, when the component
>> devices and sub-domains are idle at runtime.
>>
>> The restriction this imposes on the domain hierarchy is that sub-domains
>> and all devices in the IRQ safe domain's hierarchy also have to be IRQ
>> safe, so that we dont try to lock a mutex, while holding a spinlock.
>> Non-IRQ safe domains may continue to have devices and sub-domains that
>> may or may not be IRQ safe.
>>
>> Cc: Ulf Hansson <ulf.hansson at linaro.org>
>> Cc: Kevin Hilman <khilman at linaro.org>
>> Cc: Rafael J. Wysocki <rjw at rjwysocki.net>
>> Cc: Geert Uytterhoeven <geert at linux-m68k.org>
>> Cc: Krzysztof Koz?owski <k.kozlowski at samsung.com>
>> Signed-off-by: Lina Iyer <lina.iyer at linaro.org>
>
>Approach seems good to me, some cosmetic issues below...
>
Thanks for your review.

>> ---
>>  Documentation/power/devices.txt |  11 ++-
>>  drivers/base/power/domain.c     | 201 +++++++++++++++++++++++++++++++---------
>>  include/linux/pm_domain.h       |  11 ++-
>>  3 files changed, 178 insertions(+), 45 deletions(-)
>>
>> diff --git a/Documentation/power/devices.txt b/Documentation/power/devices.txt
>> index 8ba6625..6d8318c 100644
>> --- a/Documentation/power/devices.txt
>> +++ b/Documentation/power/devices.txt
>> @@ -607,7 +607,16 @@ individually.  Instead, a set of devices sharing a power resource can be put
>>  into a low-power state together at the same time by turning off the shared
>>  power resource.  Of course, they also need to be put into the full-power state
>>  together, by turning the shared power resource on.  A set of devices with this
>> -property is often referred to as a power domain.
>> +property is often referred to as a power domain. A power domain may also be
>> +nested inside another power domain.
>> +
>> +Devices, by default, operate in process context and if a device can operate in
>> +IRQ safe context, has to be explicitly set as IRQ safe. Power domains by
>> +default, operate in process context but could have devices that are IRQ safe.
>> +Such power domains cannot be powered on/off during runtime PM. On the other
>> +hand, an IRQ safe PM domain that can be powered on/off and suspend or resumed
>> +in an atomic context, may contain IRQ safe devices. Such domains may only
>> +contain IRQ safe devices or IRQ safe sub-domains.
>>
>>  Support for power domains is provided through the pm_domain field of struct
>>  device.  This field is a pointer to an object of type struct dev_pm_domain,
>> diff --git a/drivers/base/power/domain.c b/drivers/base/power/domain.c
>> index ef8d19f..221feb0 100644
>> --- a/drivers/base/power/domain.c
>> +++ b/drivers/base/power/domain.c
>> @@ -53,6 +53,74 @@
>>  static LIST_HEAD(gpd_list);
>>  static DEFINE_MUTEX(gpd_list_lock);
>>
>> +static inline int genpd_lock_noirq(struct generic_pm_domain *genpd,
>> +					unsigned int subclass)
>
>I don't like the _noirq naming, as in the context of suspend/resume,
>that means no *device* IRQs, not no IRQs at all.  Maybe _atomic is
>better, or _nosleep? or ...
>
I like _nosleep, will change it.

>> +	__acquires(&genpd->slock)
>> +{
>> +	unsigned long flags;
>> +
>> +	if (subclass > 0)
>> +		spin_lock_irqsave_nested(&genpd->slock, flags, subclass);
>> +	else
>> +		spin_lock_irqsave(&genpd->slock, flags);
>> +
>> +	genpd->lock_flags = flags;
>> +	return 0;
>> +}
>> +
>> +static inline void genpd_unlock_noirq(struct generic_pm_domain *genpd)
>> +	__releases(&genpd->slock)
>> +{
>> +	spin_unlock_irqrestore(&genpd->slock, genpd->lock_flags);
>> +}
>> +
>> +static inline int genpd_lock_irq(struct generic_pm_domain *genpd,
>> +					unsigned int subclass)
>> +	__acquires(&genpd->mlock)
>> +{
>> +	if (subclass > 0)
>> +		mutex_lock_nested(&genpd->mlock, subclass);
>> +	else
>> +		mutex_lock(&genpd->mlock);
>> +	return 0;
>> +}
>> +
>> +static inline int genpd_lock_interruptible_irq(struct generic_pm_domain *genpd)
>> +	__acquires(&genpd->mlock)
>> +{
>> +	return mutex_lock_interruptible(&genpd->mlock);
>> +}
>> +
>> +static inline void genpd_unlock_irq(struct generic_pm_domain *genpd)
>> +	__releases(&genpd->mlock)
>> +{
>> +	mutex_unlock(&genpd->mlock);
>> +}
>> +
>> +static inline int genpd_lock(struct generic_pm_domain *genpd)
>> +{
>> +	return genpd->irq_safe ? genpd_lock_noirq(genpd, 0)
>> +			: genpd_lock_irq(genpd, 0);
>> +}
>> +
>> +static inline int genpd_lock_nested(struct generic_pm_domain *genpd)
>> +{
>> +	return genpd->irq_safe ? genpd_lock_noirq(genpd, SINGLE_DEPTH_NESTING)
>> +			: genpd_lock_irq(genpd, SINGLE_DEPTH_NESTING);
>> +}
>> +
>> +static inline int genpd_lock_interruptible(struct generic_pm_domain *genpd)
>> +{
>> +	return genpd->irq_safe ? genpd_lock_noirq(genpd, 0)
>> +			: genpd_lock_interruptible_irq(genpd);
>> +}
>> +
>> +static inline void genpd_unlock(struct generic_pm_domain *genpd)
>> +{
>> +	return genpd->irq_safe ? genpd_unlock_noirq(genpd)
>> +			: genpd_unlock_irq(genpd);
>> +}
>> +
>>  static struct generic_pm_domain *pm_genpd_lookup_name(const char *domain_name)
>>  {
>>  	struct generic_pm_domain *genpd = NULL, *gpd;
>> @@ -273,9 +341,9 @@ int pm_genpd_poweron(struct generic_pm_domain *genpd)
>>  {
>>  	int ret;
>>
>> -	mutex_lock(&genpd->lock);
>> +	genpd_lock(genpd);
>>  	ret = __pm_genpd_poweron(genpd);
>> -	mutex_unlock(&genpd->lock);
>> +	genpd_unlock(genpd);
>>  	return ret;
>>  }
>>
>> @@ -335,9 +403,9 @@ static int genpd_dev_pm_qos_notifier(struct notifier_block *nb,
>>  		spin_unlock_irq(&dev->power.lock);
>>
>>  		if (!IS_ERR(genpd)) {
>> -			mutex_lock(&genpd->lock);
>> +			genpd_lock(genpd);
>>  			genpd->max_off_time_changed = true;
>> -			mutex_unlock(&genpd->lock);
>> +			genpd_unlock(genpd);
>>  		}
>>
>>  		dev = dev->parent;
>> @@ -394,7 +462,13 @@ static int pm_genpd_poweroff(struct generic_pm_domain *genpd)
>>  		if (stat > PM_QOS_FLAGS_NONE)
>>  			return -EBUSY;
>>
>> -		if (!pm_runtime_suspended(pdd->dev) || pdd->dev->power.irq_safe)
>> +		/*
>> +		 * We do not want to power off the domain if the device is
>> +		 * not suspended or an IRQ safe device is part of this
>> +		 * non-IRQ safe domain.
>> +		 */
>> +		if (!pm_runtime_suspended(pdd->dev) ||
>> +			(pdd->dev->power.irq_safe && !genpd->irq_safe))
>>  			not_suspended++;
>
>The !irq_safe check should maybe spit a warning via WARN_ONCE(), as this
>would be useful in debugging domains that are not shutting down.
>
>>  	}
I thought about putting it before, but I figured it might print only
once for all the genpd/devices. So there might be many cases that may
not be reported. Is my assumption of the __section usage for this macro,
correct?

>>
>> @@ -460,9 +534,9 @@ static void genpd_power_off_work_fn(struct work_struct *work)
>>
>>  	genpd = container_of(work, struct generic_pm_domain, power_off_work);
>>
>> -	mutex_lock(&genpd->lock);
>> +	genpd_lock(genpd);
>>  	pm_genpd_poweroff(genpd);
>> -	mutex_unlock(&genpd->lock);
>> +	genpd_unlock(genpd);
>>  }
>>
>>  /**
>> @@ -500,17 +574,19 @@ static int pm_genpd_runtime_suspend(struct device *dev)
>>  	}
>>
>>  	/*
>> -	 * If power.irq_safe is set, this routine will be run with interrupts
>> -	 * off, so it can't use mutexes.
>> +	 * If power.irq_safe is set, this routine may be run with
>> +	 * IRQ disabled, so suspend only if the power domain is
>> +	 * irq_safe.
>>  	 */
>> -	if (dev->power.irq_safe)
>> +	if (dev->power.irq_safe && !genpd->irq_safe)
>>  		return 0;
>
>Similarily, a WARN_ONCE() will probably be helpful here.
>
>> -	mutex_lock(&genpd->lock);
>> +	genpd_lock(genpd);
>> +
>>  	genpd->in_progress++;
>>  	pm_genpd_poweroff(genpd);
>>  	genpd->in_progress--;
>> -	mutex_unlock(&genpd->lock);
>> +	genpd_unlock(genpd);
>>
>>  	return 0;
>>  }
>> @@ -535,15 +611,18 @@ static int pm_genpd_runtime_resume(struct device *dev)
>>  	if (IS_ERR(genpd))
>>  		return -EINVAL;
>>
>> -	/* If power.irq_safe, the PM domain is never powered off. */
>> -	if (dev->power.irq_safe) {
>> +	/*
>> +	 * As we dont power off a non IRQ safe domain, which holds
>> +	 * an IRQ safe device, we dont need to restore power to it.
>> +	 */
>> +	if (dev->power.irq_safe && !genpd->irq_safe) {
>>  		timed = false;
>>  		goto out;
>>  	}
>>
>> -	mutex_lock(&genpd->lock);
>> +	genpd_lock(genpd);
>>  	ret = __pm_genpd_poweron(genpd);
>> -	mutex_unlock(&genpd->lock);
>> +	genpd_unlock(genpd);
>>
>>  	if (ret)
>>  		return ret;
>> @@ -743,14 +822,14 @@ static int pm_genpd_prepare(struct device *dev)
>>  	if (resume_needed(dev, genpd))
>>  		pm_runtime_resume(dev);
>>
>> -	mutex_lock(&genpd->lock);
>> +	genpd_lock(genpd);
>>
>>  	if (genpd->prepared_count++ == 0) {
>>  		genpd->suspended_count = 0;
>>  		genpd->suspend_power_off = genpd->status == GPD_STATE_POWER_OFF;
>>  	}
>>
>> -	mutex_unlock(&genpd->lock);
>> +	genpd_unlock(genpd);
>>
>>  	if (genpd->suspend_power_off) {
>>  		pm_runtime_put_noidle(dev);
>> @@ -768,12 +847,12 @@ static int pm_genpd_prepare(struct device *dev)
>>
>>  	ret = pm_generic_prepare(dev);
>>  	if (ret) {
>> -		mutex_lock(&genpd->lock);
>> +		genpd_lock(genpd);
>>
>>  		if (--genpd->prepared_count == 0)
>>  			genpd->suspend_power_off = false;
>>
>> -		mutex_unlock(&genpd->lock);
>> +		genpd_unlock(genpd);
>>  		pm_runtime_enable(dev);
>>  	}
>>
>> @@ -1130,13 +1209,13 @@ static void pm_genpd_complete(struct device *dev)
>>  	if (IS_ERR(genpd))
>>  		return;
>>
>> -	mutex_lock(&genpd->lock);
>> +	genpd_lock(genpd);
>>
>>  	run_complete = !genpd->suspend_power_off;
>>  	if (--genpd->prepared_count == 0)
>>  		genpd->suspend_power_off = false;
>>
>> -	mutex_unlock(&genpd->lock);
>> +	genpd_unlock(genpd);
>>
>>  	if (run_complete) {
>>  		pm_generic_complete(dev);
>> @@ -1280,11 +1359,17 @@ int __pm_genpd_add_device(struct generic_pm_domain *genpd, struct device *dev,
>>  	if (IS_ERR_OR_NULL(genpd) || IS_ERR_OR_NULL(dev))
>>  		return -EINVAL;
>>
>> +	if (genpd->irq_safe && !dev->power.irq_safe) {
>> +		dev_err(dev,
>> +			"Devices in an IRQ safe domain have to be IRQ safe.\n");
>
>This should also dump the PM domain, something like:
>
>            dev_err(dev, "PM domain %s is IRQ safe; device has to be IRQ safe.\n")
>
Sure.

>> +		return -EINVAL;
>> +	}
>> +
>>  	gpd_data = genpd_alloc_dev_data(dev, genpd, td);
>>  	if (IS_ERR(gpd_data))
>>  		return PTR_ERR(gpd_data);
>>
>> -	mutex_lock(&genpd->lock);
>> +	genpd_lock(genpd);
>>
>>  	if (genpd->prepared_count > 0) {
>>  		ret = -EAGAIN;
>> @@ -1301,7 +1386,7 @@ int __pm_genpd_add_device(struct generic_pm_domain *genpd, struct device *dev,
>>  	list_add_tail(&gpd_data->base.list_node, &genpd->dev_list);
>>
>>   out:
>> -	mutex_unlock(&genpd->lock);
>> +	genpd_unlock(genpd);
>>
>>  	if (ret)
>>  		genpd_free_dev_data(dev, gpd_data);
>> @@ -1345,7 +1430,7 @@ int pm_genpd_remove_device(struct generic_pm_domain *genpd,
>>  	gpd_data = to_gpd_data(pdd);
>>  	dev_pm_qos_remove_notifier(dev, &gpd_data->nb);
>>
>> -	mutex_lock(&genpd->lock);
>> +	genpd_lock(genpd);
>>
>>  	if (genpd->prepared_count > 0) {
>>  		ret = -EAGAIN;
>> @@ -1360,14 +1445,14 @@ int pm_genpd_remove_device(struct generic_pm_domain *genpd,
>>
>>  	list_del_init(&pdd->list_node);
>>
>> -	mutex_unlock(&genpd->lock);
>> +	genpd_unlock(genpd);
>>
>>  	genpd_free_dev_data(dev, gpd_data);
>>
>>  	return 0;
>>
>>   out:
>> -	mutex_unlock(&genpd->lock);
>> +	genpd_unlock(genpd);
>>  	dev_pm_qos_add_notifier(dev, &gpd_data->nb);
>>
>>  	return ret;
>> @@ -1388,12 +1473,24 @@ int pm_genpd_add_subdomain(struct generic_pm_domain *genpd,
>>  	    || genpd == subdomain)
>>  		return -EINVAL;
>>
>> +	/*
>> +	 * If the domain can be powered on/off in an IRQ safe
>> +	 * context, ensure that the subdomain can also be
>> +	 * powered on/off in that context.
>> +	 */
>> +	if (genpd->irq_safe && !subdomain->irq_safe) {
>> +		WARN("Sub-domain (%s) in an IRQ-safe domain (%s)"
>> +				"have to be IRQ safe\n",
>
>s/have/has/
>
Argh. Fixed.

>> +				subdomain->name, genpd->name);
>> +		return -EINVAL;
>> +	}
>> +
>
>Kevin

Thank you again for looking through this big patch.
-- Lina


From linux at arm.linux.org.uk  Wed Aug 12 14:05:43 2015
From: linux at arm.linux.org.uk (Russell King - ARM Linux)
Date: Wed, 12 Aug 2015 22:05:43 +0100
Subject: My boot farm
In-Reply-To: <20150812073515.GE7557@n2100.arm.linux.org.uk>
References: <20150812073515.GE7557@n2100.arm.linux.org.uk>
Message-ID: <20150812210543.GL7557@n2100.arm.linux.org.uk>

On Wed, Aug 12, 2015 at 08:35:15AM +0100, Russell King - ARM Linux wrote:
> ... will be offline for a while as, on the face of it, the Digi TS16
> rack (terminal server) internal power supply seems to have died.  I'll
> investigate further on Friday, but in the mean time, I'm taking the
> boot tests completely offline until it's resolved.

It turns out that I had more time today than I expected to look at it.
What's died in it is the open-frame switch-mode PSU, ITS UO01511120,
which supplies 12V 1.3A to the main board - which looks to be due to
a manufacturing error in component placement.

In the mean time, I've jury-rigged an alternative 12V power source for
the main board in the terminal server, so the boot farm should be back
up and running tonight, provided all the RJ45's found their correct
holes. :)

-- 
FTTC broadband for 0.8mile line: currently at 10.5Mbps down 400kbps up
according to speedtest.net.


From stern at rowland.harvard.edu  Wed Aug 12 14:08:18 2015
From: stern at rowland.harvard.edu (Alan Stern)
Date: Wed, 12 Aug 2015 17:08:18 -0400 (EDT)
Subject: [PATCH 0/4] USB: host: ohci-at91: cleanups
In-Reply-To: <1439216592-11381-1-git-send-email-alexandre.belloni@free-electrons.com>
Message-ID: <Pine.LNX.4.44L0.1508121708030.1582-100000@iolanthe.rowland.org>

On Mon, 10 Aug 2015, Alexandre Belloni wrote:

> Hi,
> 
> Here are a few cleanups for ohci-at91. This is the fallout of AT91 now being DT
> only.
> 
> Alexandre Belloni (4):
>   USB: host: ohci-at91: move at91_usbh_data definition in c file
>   USB: host: ohci-at91: depend on OF
>   USB: host: ohci-at91: merge ohci_at91_of_init in
>     ohci_hcd_at91_drv_probe
>   USB: host: ohci-at91: merge loops in ohci_hcd_at91_drv_probe
> 
>  drivers/usb/host/Kconfig            |   8 +-
>  drivers/usb/host/ohci-at91.c        | 179 ++++++++++++++++--------------------
>  include/linux/platform_data/atmel.h |  12 ---
>  3 files changed, 85 insertions(+), 114 deletions(-)

Acked-by: Alan Stern <stern at rowland.harvard.edu>



From jeremy.linton at arm.com  Wed Aug 12 14:51:29 2015
From: jeremy.linton at arm.com (Jeremy Linton)
Date: Wed, 12 Aug 2015 16:51:29 -0500
Subject: [PATCH 2/3] Display a DMA error message
In-Reply-To: <1439416290-21228-1-git-send-email-jeremy.linton@arm.com>
References: <1439416290-21228-1-git-send-email-jeremy.linton@arm.com>
Message-ID: <1439416290-21228-3-git-send-email-jeremy.linton@arm.com>

If the ehci driver fails to configure the dma settings then display
a dev error instead of simply failing. This is triggered in an
ACPI world if the user fails to set the _CCA on the device.

Signed-off-by: Jeremy Linton <jeremy.linton at arm.com>
---
 drivers/usb/host/ehci-platform.c | 4 +++-
 1 file changed, 3 insertions(+), 1 deletion(-)

diff --git a/drivers/usb/host/ehci-platform.c b/drivers/usb/host/ehci-platform.c
index 2593def..82e396f 100644
--- a/drivers/usb/host/ehci-platform.c
+++ b/drivers/usb/host/ehci-platform.c
@@ -162,8 +162,10 @@ static int ehci_platform_probe(struct platform_device *dev)
 
 	err = dma_coerce_mask_and_coherent(&dev->dev,
 		pdata->dma_mask_64 ? DMA_BIT_MASK(64) : DMA_BIT_MASK(32));
-	if (err)
+	if (err) {
+		dev_err(&dev->dev, "Error: DMA setup failed\n");
 		return err;
+	}
 
 	irq = platform_get_irq(dev, 0);
 	if (irq < 0) {
-- 
2.4.3




From jeremy.linton at arm.com  Wed Aug 12 14:51:30 2015
From: jeremy.linton at arm.com (Jeremy Linton)
Date: Wed, 12 Aug 2015 16:51:30 -0500
Subject: [PATCH 3/3] Add ACPI bindings for the EHCI platform driver.
In-Reply-To: <1439416290-21228-1-git-send-email-jeremy.linton@arm.com>
References: <1439416290-21228-1-git-send-email-jeremy.linton@arm.com>
Message-ID: <1439416290-21228-4-git-send-email-jeremy.linton@arm.com>

This enables USB on the ARM juno board when booted with
an ACPI kernel. The PNP id comes from the PNP/ACPI registry
and describes a EHCI controller without debug.

Signed-off-by: Jeremy Linton <jeremy.linton at arm.com>
---
 drivers/usb/host/ehci-platform.c | 9 +++++++++
 1 file changed, 9 insertions(+)

diff --git a/drivers/usb/host/ehci-platform.c b/drivers/usb/host/ehci-platform.c
index 82e396f..1807baa 100644
--- a/drivers/usb/host/ehci-platform.c
+++ b/drivers/usb/host/ehci-platform.c
@@ -27,6 +27,7 @@
 #include <linux/io.h>
 #include <linux/module.h>
 #include <linux/of.h>
+#include <linux/acpi.h>
 #include <linux/phy/phy.h>
 #include <linux/platform_device.h>
 #include <linux/reset.h>
@@ -382,6 +383,13 @@ static const struct of_device_id vt8500_ehci_ids[] = {
 };
 MODULE_DEVICE_TABLE(of, vt8500_ehci_ids);
 
+static const struct acpi_device_id ehci_acpi_match[] = {
+	{ "PNP0D20", 0 },
+	{ }
+};
+MODULE_DEVICE_TABLE(acpi, ehci_acpi_match);
+
+
 static const struct platform_device_id ehci_platform_table[] = {
 	{ "ehci-platform", 0 },
 	{ }
@@ -400,6 +408,7 @@ static struct platform_driver ehci_platform_driver = {
 		.name	= "ehci-platform",
 		.pm	= &ehci_platform_pm_ops,
 		.of_match_table = vt8500_ehci_ids,
+		.acpi_match_table = ACPI_PTR(ehci_acpi_match),
 	}
 };
 
-- 
2.4.3




From jeremy.linton at arm.com  Wed Aug 12 14:51:28 2015
From: jeremy.linton at arm.com (Jeremy Linton)
Date: Wed, 12 Aug 2015 16:51:28 -0500
Subject: [PATCH 1/3] Honor ACPI _CCA attribute setting
In-Reply-To: <1439416290-21228-1-git-send-email-jeremy.linton@arm.com>
References: <1439416290-21228-1-git-send-email-jeremy.linton@arm.com>
Message-ID: <1439416290-21228-2-git-send-email-jeremy.linton@arm.com>

ACPI configurations can now mark devices as noncoherent,
support that choice.

Signed-off-by: Jeremy Linton <jeremy.linton at arm.com>
---
 include/acpi/acpi_bus.h | 5 +++--
 1 file changed, 3 insertions(+), 2 deletions(-)

diff --git a/include/acpi/acpi_bus.h b/include/acpi/acpi_bus.h
index 83061ca..7ecb8e4 100644
--- a/include/acpi/acpi_bus.h
+++ b/include/acpi/acpi_bus.h
@@ -399,7 +399,7 @@ static inline bool acpi_check_dma(struct acpi_device *adev, bool *coherent)
 	 * case 1. Do not support and disable DMA.
 	 * case 2. Support but rely on arch-specific cache maintenance for
 	 *         non-coherence DMA operations.
-	 * Currently, we implement case 1 above.
+	 * Currently, we implement case 2 above.
 	 *
 	 * For the case when _CCA is missing (i.e. cca_seen=0) and
 	 * platform specifies ACPI_CCA_REQUIRED, we do not support DMA,
@@ -407,7 +407,8 @@ static inline bool acpi_check_dma(struct acpi_device *adev, bool *coherent)
 	 *
 	 * See acpi_init_coherency() for more info.
 	 */
-	if (adev->flags.coherent_dma) {
+	if (adev->flags.coherent_dma ||
+	    (adev->flags.cca_seen && IS_ENABLED(CONFIG_ARM64))) {
 		ret = true;
 		if (coherent)
 			*coherent = adev->flags.coherent_dma;
-- 
2.4.3




From jeremy.linton at arm.com  Wed Aug 12 14:51:27 2015
From: jeremy.linton at arm.com (Jeremy Linton)
Date: Wed, 12 Aug 2015 16:51:27 -0500
Subject: [PATCH 0/3] Enable EHCI-platform driver for use with ACPI
Message-ID: <1439416290-21228-1-git-send-email-jeremy.linton@arm.com>

This patch set enables the USB on the ARM Juno development platform
when using an ACPI kernel. This patch is in two primary parts. First
It tweaks the code in acpi_check_dma() to support the recently added
CCA attribute which describes a device which is not cache coherent.

It then adds an error message if the device cannot be configured with
the current DMA settings, finally it adds the ACPI PNP id to the
acpi_match_table entry.

Jeremy Linton (3):
  Honor ACPI _CCA attribute setting
  Display a DMA error message
  Add ACPI bindings for the EHCI platform driver.

 drivers/usb/host/ehci-platform.c | 13 ++++++++++++-
 include/acpi/acpi_bus.h          |  5 +++--
 2 files changed, 15 insertions(+), 3 deletions(-)

-- 
2.4.3




From sboyd at codeaurora.org  Wed Aug 12 14:57:31 2015
From: sboyd at codeaurora.org (Stephen Boyd)
Date: Wed, 12 Aug 2015 14:57:31 -0700
Subject: [PATCH 5/9] clk: qcom: gcc-msm8960: add child devices support.
In-Reply-To: <20150812201855.GF13472@usrtlx11787.corpusers.net>
References: <1436348838-22671-1-git-send-email-rnayak@codeaurora.org>
 <1436348838-22671-6-git-send-email-rnayak@codeaurora.org>
 <20150811224902.GO2839@codeaurora.org>
 <20150812201855.GF13472@usrtlx11787.corpusers.net>
Message-ID: <55CBC14B.8000509@codeaurora.org>

On 08/12/2015 01:18 PM, Bjorn Andersson wrote:
> On Tue 11 Aug 15:49 PDT 2015, Stephen Boyd wrote:
>
>> On 07/08, Rajendra Nayak wrote:
>>> diff --git a/drivers/clk/qcom/gcc-msm8960.c b/drivers/clk/qcom/gcc-msm8960.c
>>> index eb6a4f9..2c80d03 100644
>>> --- a/drivers/clk/qcom/gcc-msm8960.c
>>> +++ b/drivers/clk/qcom/gcc-msm8960.c
>>> @@ -15,6 +15,7 @@
>>>   #include <linux/bitops.h>
>>>   #include <linux/err.h>
>>>   #include <linux/platform_device.h>
>>> +#include <linux/of_platform.h>
>>>   #include <linux/module.h>
>>>   #include <linux/of.h>
>>>   #include <linux/of_device.h>
>>> @@ -3520,7 +3521,8 @@ static int gcc_msm8960_probe(struct platform_device *pdev)
>>>   	if (IS_ERR(clk))
>>>   		return PTR_ERR(clk);
>>>   
>>> -	return qcom_cc_probe(pdev, match->data);
>>> +	qcom_cc_probe(pdev, match->data);
>>> +	return of_platform_populate(pdev->dev.of_node, NULL, NULL, &pdev->dev);
>> We just lost the error code from qcom_cc_probe()...
>>
>> Also, I don't like having a subnode in DT. Why can't we use the
>> same node as the GCC node and create a virtual child device here
>> for tsens? We can assign the same of_node that this platform
>> device has so that DT keeps working correctly.
>>
> Can't we make the gcc driver support being a child of a simple-mfd by
> having it attempting to acquire the regmap of the parent and falling
> back to creating its own mmio regmap?

So we would need to make a new device and driver for the simple-mfd 
parent? I'm confused about what you're suggesting and what benefit it 
has versus creating a child of the clock controller device.

Here's the patch I'm suggesting. The device name is probably wrong, but 
you get the idea.

Signed-off-by: Stephen Boyd <sboyd at codeaurora.org>
----8<----

diff --git a/drivers/clk/qcom/gcc-msm8960.c b/drivers/clk/qcom/gcc-msm8960.c
index aa294b1bad34..802e9794f76e 100644
--- a/drivers/clk/qcom/gcc-msm8960.c
+++ b/drivers/clk/qcom/gcc-msm8960.c
@@ -3505,7 +3505,9 @@ static int gcc_msm8960_probe(struct platform_device *pdev)
  {
  	struct clk *clk;
  	struct device *dev = &pdev->dev;
+	struct platform_device *tsens;
  	const struct of_device_id *match;
+	int ret;
  
  	match = of_match_device(gcc_msm8960_match_table, &pdev->dev);
  	if (!match)
@@ -3520,7 +3522,30 @@ static int gcc_msm8960_probe(struct platform_device *pdev)
  	if (IS_ERR(clk))
  		return PTR_ERR(clk);
  
-	return qcom_cc_probe(pdev, match->data);
+	ret = qcom_cc_probe(pdev, match->data);
+	if (ret)
+		return ret;
+
+	tsens = platform_device_alloc("tsens", -1);
+	if (!tsens) {
+		ret = -ENOMEM;
+		goto err_alloc;
+	}
+
+	tsens->dev.parent = &pdev->dev;
+	tsens->dev.of_node = pdev->dev.of_node;
+	ret = platform_device_add(tsens);
+	if (ret)
+		goto err_add;
+
+	return 0;
+
+err_add:
+	platform_device_put(tsens);
+err_alloc:
+	qcom_cc_remove(pdev);
+
+	return ret;
  }
  
  static int gcc_msm8960_remove(struct platform_device *pdev)

-- 
Qualcomm Innovation Center, Inc. is a member of Code Aurora Forum,
a Linux Foundation Collaborative Project



From ralf at linux-mips.org  Wed Aug 12 15:05:00 2015
From: ralf at linux-mips.org (Ralf Baechle)
Date: Thu, 13 Aug 2015 00:05:00 +0200
Subject: [RFC PATCH v4 3/9] mips: pistachio_defconfig: remove
 CONFIG_MMC_DW_IDMAC
In-Reply-To: <1438843515-23935-1-git-send-email-shawn.lin@rock-chips.com>
References: <1438843469-23807-1-git-send-email-shawn.lin@rock-chips.com>
 <1438843515-23935-1-git-send-email-shawn.lin@rock-chips.com>
Message-ID: <20150812220500.GD11636@linux-mips.org>

On Thu, Aug 06, 2015 at 02:45:15PM +0800, Shawn Lin wrote:

> DesignWare MMC Controller's transfer mode should be decided
> at runtime instead of compile-time. So we remove this config
> option and read dw_mmc's register to select DMA master.
> 
> Signed-off-by: Shawn Lin <shawn.lin at rock-chips.com>
> ---
> 
> Changes in v4: None
> Changes in v3: None
> Changes in v2: None
> 
>  arch/mips/configs/pistachio_defconfig | 1 -

Acked-by: Ralf Baechle <ralf at linux-mips.org>

Please feel free to merge this patch with the remainder
of the series.

  Ralf


From jeremy.linton at arm.com  Wed Aug 12 15:06:25 2015
From: jeremy.linton at arm.com (Jeremy Linton)
Date: Wed, 12 Aug 2015 17:06:25 -0500
Subject: [PATCH 0/2] Enable smsc911x for use with ACPI
Message-ID: <1439417187-21411-1-git-send-email-jeremy.linton@arm.com>

This set of patches enables the front Ethernet port on the
ARM Juno development platform when used with an ACPI enabled kernel.

These patches covert the of_property* calls in the driver to the
DT/ACPI agnostic device_property* calls, and add the arm hardware
id to the acpi_match_table.

To support the above changes I copied a couple routines from
of_net into the properties.c file, and modified them to
be ACPI/DT agnostic. I'm not 100% sure this is the correct location
for these functions. But I think they are required to avoid having
a dozen different implementations scattered across assorted Ethernet
adapters that are being enabled to use ACPI properties.

Jeremy Linton (2):
  Add a matching set of device_ functions for determining mac/phy
  Convert smsc911x to use ACPI as well as DT

 drivers/base/property.c              | 73 ++++++++++++++++++++++++++++++++++++
 drivers/net/ethernet/smsc/smsc911x.c | 48 +++++++++++-------------
 include/linux/property.h             |  4 ++
 3 files changed, 99 insertions(+), 26 deletions(-)

-- 
2.4.3




From jeremy.linton at arm.com  Wed Aug 12 15:06:27 2015
From: jeremy.linton at arm.com (Jeremy Linton)
Date: Wed, 12 Aug 2015 17:06:27 -0500
Subject: [PATCH 2/2] Convert smsc911x to use ACPI as well as DT
In-Reply-To: <1439417187-21411-1-git-send-email-jeremy.linton@arm.com>
References: <1439417187-21411-1-git-send-email-jeremy.linton@arm.com>
Message-ID: <1439417187-21411-3-git-send-email-jeremy.linton@arm.com>

Add ACPI bindings for the smsc911x driver. Convert the DT specific calls
to nonspecific device* calls, This allows the driver to work
with both ACPI and DT configurations. Ethernet should now work when using
ACPI on ARM Juno.

Signed-off-by: Jeremy Linton <jeremy.linton at arm.com>
---
 drivers/net/ethernet/smsc/smsc911x.c | 48 +++++++++++++++++-------------------
 1 file changed, 22 insertions(+), 26 deletions(-)

diff --git a/drivers/net/ethernet/smsc/smsc911x.c b/drivers/net/ethernet/smsc/smsc911x.c
index 959aeea..0f21aa3 100644
--- a/drivers/net/ethernet/smsc/smsc911x.c
+++ b/drivers/net/ethernet/smsc/smsc911x.c
@@ -59,7 +59,9 @@
 #include <linux/of_device.h>
 #include <linux/of_gpio.h>
 #include <linux/of_net.h>
+#include <linux/acpi.h>
 #include <linux/pm_runtime.h>
+#include <linux/property.h>
 
 #include "smsc911x.h"
 
@@ -2362,59 +2364,46 @@ static const struct smsc911x_ops shifted_smsc911x_ops = {
 	.tx_writefifo = smsc911x_tx_writefifo_shift,
 };
 
-#ifdef CONFIG_OF
-static int smsc911x_probe_config_dt(struct smsc911x_platform_config *config,
-				    struct device_node *np)
+static int smsc911x_probe_config(struct smsc911x_platform_config *config,
+				 struct device *dev)
 {
-	const char *mac;
 	u32 width = 0;
 
-	if (!np)
+	if (!dev)
 		return -ENODEV;
 
-	config->phy_interface = of_get_phy_mode(np);
+	config->phy_interface = device_get_phy_mode(dev);
 
-	mac = of_get_mac_address(np);
-	if (mac)
-		memcpy(config->mac, mac, ETH_ALEN);
+	device_get_mac_address(dev, config->mac, ETH_ALEN);
 
-	of_property_read_u32(np, "reg-shift", &config->shift);
+	device_property_read_u32(dev, "reg-shift", &config->shift);
 
-	of_property_read_u32(np, "reg-io-width", &width);
+	device_property_read_u32(dev, "reg-io-width", &width);
 	if (width == 4)
 		config->flags |= SMSC911X_USE_32BIT;
 	else
 		config->flags |= SMSC911X_USE_16BIT;
 
-	if (of_get_property(np, "smsc,irq-active-high", NULL))
+	if (device_property_present(dev, "smsc,irq-active-high"))
 		config->irq_polarity = SMSC911X_IRQ_POLARITY_ACTIVE_HIGH;
 
-	if (of_get_property(np, "smsc,irq-push-pull", NULL))
+	if (device_property_present(dev, "smsc,irq-push-pull"))
 		config->irq_type = SMSC911X_IRQ_TYPE_PUSH_PULL;
 
-	if (of_get_property(np, "smsc,force-internal-phy", NULL))
+	if (device_property_present(dev, "smsc,force-internal-phy"))
 		config->flags |= SMSC911X_FORCE_INTERNAL_PHY;
 
-	if (of_get_property(np, "smsc,force-external-phy", NULL))
+	if (device_property_present(dev, "smsc,force-external-phy"))
 		config->flags |= SMSC911X_FORCE_EXTERNAL_PHY;
 
-	if (of_get_property(np, "smsc,save-mac-address", NULL))
+	if (device_property_present(dev, "smsc,save-mac-address"))
 		config->flags |= SMSC911X_SAVE_MAC_ADDRESS;
 
 	return 0;
 }
-#else
-static inline int smsc911x_probe_config_dt(
-				struct smsc911x_platform_config *config,
-				struct device_node *np)
-{
-	return -ENODEV;
-}
-#endif /* CONFIG_OF */
 
 static int smsc911x_drv_probe(struct platform_device *pdev)
 {
-	struct device_node *np = pdev->dev.of_node;
 	struct net_device *dev;
 	struct smsc911x_data *pdata;
 	struct smsc911x_platform_config *config = dev_get_platdata(&pdev->dev);
@@ -2478,7 +2467,7 @@ static int smsc911x_drv_probe(struct platform_device *pdev)
 		goto out_disable_resources;
 	}
 
-	retval = smsc911x_probe_config_dt(&pdata->config, np);
+	retval = smsc911x_probe_config(&pdata->config, &pdev->dev);
 	if (retval && config) {
 		/* copy config parameters across to pdata */
 		memcpy(&pdata->config, config, sizeof(pdata->config));
@@ -2654,6 +2643,12 @@ static const struct of_device_id smsc911x_dt_ids[] = {
 MODULE_DEVICE_TABLE(of, smsc911x_dt_ids);
 #endif
 
+static const struct acpi_device_id smsc911x_acpi_match[] = {
+	{ "ARMH9118", 0 },
+	{ }
+};
+MODULE_DEVICE_TABLE(acpi, smsc911x_acpi_match);
+
 static struct platform_driver smsc911x_driver = {
 	.probe = smsc911x_drv_probe,
 	.remove = smsc911x_drv_remove,
@@ -2661,6 +2656,7 @@ static struct platform_driver smsc911x_driver = {
 		.name	= SMSC_CHIPNAME,
 		.pm	= SMSC911X_PM_OPS,
 		.of_match_table = of_match_ptr(smsc911x_dt_ids),
+		.acpi_match_table = ACPI_PTR(smsc911x_acpi_match),
 	},
 };
 
-- 
2.4.3




From jeremy.linton at arm.com  Wed Aug 12 15:06:26 2015
From: jeremy.linton at arm.com (Jeremy Linton)
Date: Wed, 12 Aug 2015 17:06:26 -0500
Subject: [PATCH 1/2] Add a matching set of device_ functions for determining
 mac/phy
In-Reply-To: <1439417187-21411-1-git-send-email-jeremy.linton@arm.com>
References: <1439417187-21411-1-git-send-email-jeremy.linton@arm.com>
Message-ID: <1439417187-21411-2-git-send-email-jeremy.linton@arm.com>

OF has some helper functions for parsing MAC and PHY settings.
In cases where the platform is providing this information rather
than the device itself, there needs to be similar functions for ACPI.

These functions are slightly modified versions of the ones in
of_net which can use information provided via DT or ACPI.

Signed-off-by: Jeremy Linton <jeremy.linton at arm.com>
---
 drivers/base/property.c  | 73 ++++++++++++++++++++++++++++++++++++++++++++++++
 include/linux/property.h |  4 +++
 2 files changed, 77 insertions(+)

diff --git a/drivers/base/property.c b/drivers/base/property.c
index f3f6d16..2e8cd14 100644
--- a/drivers/base/property.c
+++ b/drivers/base/property.c
@@ -16,6 +16,8 @@
 #include <linux/of.h>
 #include <linux/of_address.h>
 #include <linux/property.h>
+#include <linux/etherdevice.h>
+#include <linux/phy.h>
 
 /**
  * device_add_property_set - Add a collection of properties to a device object.
@@ -533,3 +535,74 @@ bool device_dma_is_coherent(struct device *dev)
 	return coherent;
 }
 EXPORT_SYMBOL_GPL(device_dma_is_coherent);
+
+/**
+ * device_get_phy_mode - Get phy mode for given device_node
+ * @dev:	Pointer to the given device
+ *
+ * The function gets phy interface string from property 'phy-mode' or
+ * 'phy-connection-type', and return its index in phy_modes table, or errno in
+ * error case.
+ */
+int device_get_phy_mode(struct device *dev)
+{
+	const char *pm;
+	int err, i;
+
+	err = device_property_read_string(dev, "phy-mode", &pm);
+	if (err < 0)
+		err = device_property_read_string(dev,
+						  "phy-connection-type", &pm);
+	if (err < 0)
+		return err;
+
+	for (i = 0; i < PHY_INTERFACE_MODE_MAX; i++)
+		if (!strcasecmp(pm, phy_modes(i)))
+			return i;
+
+	return -ENODEV;
+}
+EXPORT_SYMBOL_GPL(device_get_phy_mode);
+
+static void *device_get_mac_addr(struct device *dev,
+				 const char *name, char *addr,
+				 int alen)
+{
+	int ret = device_property_read_u8_array(dev, name, addr, alen);
+
+	if (ret == 0 && is_valid_ether_addr(addr))
+		return addr;
+	return NULL;
+}
+
+/**
+ * Search the device tree for the best MAC address to use.  'mac-address' is
+ * checked first, because that is supposed to contain to "most recent" MAC
+ * address. If that isn't set, then 'local-mac-address' is checked next,
+ * because that is the default address.  If that isn't set, then the obsolete
+ * 'address' is checked, just in case we're using an old device tree.
+ *
+ * Note that the 'address' property is supposed to contain a virtual address of
+ * the register set, but some DTS files have redefined that property to be the
+ * MAC address.
+ *
+ * All-zero MAC addresses are rejected, because those could be properties that
+ * exist in the device tree, but were not set by U-Boot.  For example, the
+ * DTS could define 'mac-address' and 'local-mac-address', with zero MAC
+ * addresses.  Some older U-Boots only initialized 'local-mac-address'.  In
+ * this case, the real MAC is in 'local-mac-address', and 'mac-address' exists
+ * but is all zeros.
+*/
+void *device_get_mac_address(struct device *dev, char *addr, int alen)
+{
+	addr = device_get_mac_addr(dev, "mac-address", addr, alen);
+	if (addr)
+		return addr;
+
+	addr = device_get_mac_addr(dev, "local-mac-address", addr, alen);
+	if (addr)
+		return addr;
+
+	return device_get_mac_addr(dev, "address", addr, alen);
+}
+EXPORT_SYMBOL(device_get_mac_address);
diff --git a/include/linux/property.h b/include/linux/property.h
index 76ebde9..a59c6ee 100644
--- a/include/linux/property.h
+++ b/include/linux/property.h
@@ -166,4 +166,8 @@ void device_add_property_set(struct device *dev, struct property_set *pset);
 
 bool device_dma_is_coherent(struct device *dev);
 
+int device_get_phy_mode(struct device *dev);
+
+void *device_get_mac_address(struct device *dev, char *addr, int alen);
+
 #endif /* _LINUX_PROPERTY_H_ */
-- 
2.4.3




From mc5686 at mclink.it  Wed Aug 12 15:12:58 2015
From: mc5686 at mclink.it (Mauro Condarelli)
Date: Thu, 13 Aug 2015 00:12:58 +0200
Subject: Debugging "of_get_named_gpiod_flags: can't parse gpios property of
 node" warnings in kinux-3.16.1
Message-ID: <55CBC4EA.8040309@mclink.it>

Hi, I am working with a custom board based on ACME ariag25 which is, in turn, based on Atmel AT91SAM9G25 SoC.
I have a quite simple .dts file, mostly based on defaults (see attachments), bu I nevertheless get a bunch of "of_get_named_gpiod_flags: can't parse gpios property of node" warnings.
I tried to debug inserting a few pr_debug() in gpiolib-of.c, but I do not really understand .dts intricacies (this is the first time I work with it).
Can someone suggest me what I should check (or plainly tell me where and how I'm making a fool of myself)?

Thanks in advance.
Mauro
-------------- next part --------------
/*
 * at91-ariag25.dts - Device Tree file for Acme Systems Aria G25
 *
 * Copyright (C) 2013 Douglas Gilbert <dgilbert at interlog.com>,
 *                    Robert Nelson <robertcnelson at gmail.com>
 * Copyright (C) 2014 Sergio Tanzilli <sergio at tanzilli.com>
 *
 * Licensed under GPLv2 or later. 
 */
/dts-v1/;
#include "at91-ariag25-base.dtsi"

/ {
	memory {
		/* 128 MB Aria G25 version */
		reg = <0x20000000 0x8000000>;
		/* 256 MB Aria G25 version */
		/* reg = <0x20000000 0x10000000>; */
	};
};

-------------- next part --------------
/*
 * at91-ariag25.dts - Device Tree file for Acme Systems Aria G25
 *
 * Copyright (C) 2013 Douglas Gilbert <dgilbert at interlog.com>,
 *                    Robert Nelson <robertcnelson at gmail.com>
 * Copyright (C) 2014 Sergio Tanzilli <sergio at tanzilli.com>
 *
 * Licensed under GPLv2 or later. 
 */
#include "at91sam9g25.dtsi"

/ {
	model = "Acme Systems Aria G25";
	compatible = "acme,ariag25", "atmel,at91sam9x5ek",
				"atmel,at91sam9x5", "atmel,at91sam9";

	aliases {
		serial0 = &dbgu;
		serial1 = &usart0;
		serial2 = &usart1;
		serial3 = &usart2;
		serial4 = &usart3;
		serial5 = &uart0;
		serial6 = &uart1;
	};

	chosen {
		bootargs = "console=ttyS0,115200 root=/dev/mmcblk0p2 rw rootwait";
	};

	memory {
		/* 128 MB Aria G25 version */
		reg = <0x20000000 0x8000000>;
		/* 256 MB Aria G25 version */
		/* reg = <0x20000000 0x10000000>; */
	};


	clocks {
		#address-cells = <1>;
		#size-cells = <1>;
		ranges;

		main_clock: clock at 0 {
			compatible = "atmel,osc", "fixed-clock";
				clock-frequency = <12000000>;
		};
	};

	ahb {
		apb {
			mmc0: mmc at f0008000 {
				status = "okay";
				pinctrl-0 = <
				&pinctrl_mmc0_slot0_clk_cmd_dat0
				&pinctrl_mmc0_slot0_dat1_3>;
				slot at 0 {
					reg = <0>;
					bus-width = <4>;
					cd-gpios = <&pioA 1 GPIO_ACTIVE_LOW>;
					wp-gpios = <>;
				};
			};

			mmc1: mmc at f000c000 {
				status = "okay";
				pinctrl-0 = <
				&pinctrl_mmc1_slot0_clk_cmd_dat0
				&pinctrl_mmc1_slot0_dat1_3>;
				slot at 0 {
					reg = <0>;
					bus-width = <4>;
					cd-gpios = <&pioA 0 GPIO_ACTIVE_LOW>;
					wp-gpios = <>;
				};
			};

			i2c0: i2c at f8010000 {
				status = "disabled";
			};

			i2c1: i2c at f8014000 {
				status = "disabled";
			};

			/* /dev/ttyS1 */
			usart0: serial at f801c000 {
				pinctrl-0 = <&pinctrl_usart0 &pinctrl_usart0_rts &pinctrl_usart0_cts>;
				status = "disabled";
			};

			/* /dev/ttyS2 */
			usart1: serial at f8020000 {
				pinctrl-0 = <&pinctrl_usart1>;
				status = "okay";
			};

			/* /dev/ttyS3 */
			usart2: serial at f8024000 {
				pinctrl-0 = <&pinctrl_usart2>;
				status = "disabled";
			};

			/* /dev/ttyS4 */
			usart3: serial at f8028000 {
				compatible = "atmel,at91sam9260-usart";
				reg = <0xf8028000 0x200>;
				interrupts = <8 IRQ_TYPE_LEVEL_HIGH 5>;
				pinctrl-names = "default";
				pinctrl-0 = <&pinctrl_usart3
						&pinctrl_usart3_rts
						&pinctrl_usart3_cts
						>;
				status = "okay";
			};

			/* /dev/ttyS5 */
			uart0: serial at f8040000 {
				status = "disabled";
			};

			/* /dev/ttyS6 */
			uart1: serial at f8044000 {
				status = "disabled";
			};

			spi1: spi at f0004000 {
				status = "okay";
				cs-gpios = <&pioA 8 0>;

				device at 0 {
					compatible = "spidev";
					// spi-max-frequency = <50000000>;  // 50 MHz
					spi-max-frequency = <5000000>;	    // 5 MHz
					reg = <0>;
				};
			};

			macb0: ethernet at f802c000 {
				status = "okay";
				phy-mode = "rmii";

			};

			adc0: adc at f804c000 {
				status = "okay";
				atmel,adc-channels-used = <0x1>;
				atmel,adc-num-channels = <1>;
				compatible = "atmel,at91sam9x5-adc";
				atmel,adc-startup-time = <40>;
				atmel,adc-status-register = <0x1c>;
				atmel,adc-trigger-register = <0x08>;
				atmel,adc-use-external;
				atmel,adc-vref = <3300>;
				atmel,adc-res = <8 10>;
				atmel,adc-res-names = "lowres", "highres";
				atmel,adc-use-res = "highres";

				trigger at 0 {
					trigger-name = "continuous";
					trigger-value = <0x6>;
				};
			};

			dbgu: serial at fffff200 {
				status = "okay";
			};

			pinctrl at fffff400 {
				w1_0 {
					pinctrl_w1_0: w1_0-0 {
						atmel,pins = <0 21 0x0 0x1>; /* PA21 PIO, pull-up */
					};
				};

				pwm0 {
					pinctrl_pwm0: pwm0-0 {
						atmel,pins =
						< AT91_PIOC 18 AT91_PERIPH_C AT91_PINCTRL_NONE
						AT91_PIOC 19 AT91_PERIPH_C AT91_PINCTRL_NONE
						AT91_PIOC 20 AT91_PERIPH_C AT91_PINCTRL_NONE
						AT91_PIOC 21 AT91_PERIPH_C AT91_PINCTRL_NONE >;
					};
				};
			};

			pwm0: pwm at f8034000 {
				pinctrl-names = "default";
				pinctrl-0 = <&pinctrl_pwm0>;
				status = "okay";
			};

			rtc at fffffeb0 {
				status = "okay";
			};

			usb2: gadget at f803c000 {
				atmel,vbus-gpio = <&pioC 27 GPIO_ACTIVE_HIGH>;
/*
				compatible = "atmel,at91rm9200-udc";
				clocks = <&usb>, <&udphs_clk>;
				clock-names = "hclk", "pclk";
*/
				status = "okay";
			};

		};

		usb0: ohci at 00600000 {
			status = "okay";
			num-ports = <3>;
			atmel,vbus-gpio = <&pioC 30 GPIO_ACTIVE_HIGH>;
			atmel,oc-gpio = <&pioC 28 GPIO_ACTIVE_LOW>;

		};

		usb1: ehci at 00700000 {
			status = "okay";
			num-ports = <3>;
			atmel,vbus-gpio = <&pioC 31 GPIO_ACTIVE_HIGH>;
			atmel,oc-gpio = <&pioC 29 GPIO_ACTIVE_LOW>;
		};

	};

	leds {
		compatible = "gpio-leds";

		aria_led {
			label = "aria_led";
			gpios = <&pioB 8 GPIO_ACTIVE_HIGH>; /* PB8 */
			linux,default-trigger = "heartbeat";
		};

/*
pioB  8 led si schedino
pioA 29 abilitazione misura batteria (set HIGH)
pioC 14 abilitazione stampante (attivo basso, nasce alto)
*/
	};

	gpio_keys {
		compatible = "gpio-keys";
		powfail {
			label = "PowerFail";
			gpios = <&pioA 31 GPIO_ACTIVE_LOW>;
			linux,code = <117>;
			gpio-key,wakeup;
		};
		shutdown {
			label = "Shutdown";
			gpios = <&pioC 15 GPIO_ACTIVE_LOW>;
			linux,code = <116>;
			gpio-key,wakeup;
		};
		paperfeed {
			label = "PaperFeed";
			gpios = <&pioC 17 GPIO_ACTIVE_LOW>;
			linux,code = <115>;
			gpio-key,wakeup;
		};
		batteryon {
			label = "BatteryConnected";
			gpios = <&pioC 16 GPIO_ACTIVE_HIGH>;
			linux,code = <114>;
			gpio-key,wakeup;
		};
		initservice {
			label = "InitService";
			gpios = <&pioC 26 GPIO_ACTIVE_LOW>;
			linux,code = <113>;
			gpio-key,wakeup;
		};
	};

};


From f.fainelli at gmail.com  Wed Aug 12 15:13:56 2015
From: f.fainelli at gmail.com (Florian Fainelli)
Date: Wed, 12 Aug 2015 15:13:56 -0700
Subject: [PATCH 1/2] Add a matching set of device_ functions for
 determining mac/phy
In-Reply-To: <1439417187-21411-2-git-send-email-jeremy.linton@arm.com>
References: <1439417187-21411-1-git-send-email-jeremy.linton@arm.com>
 <1439417187-21411-2-git-send-email-jeremy.linton@arm.com>
Message-ID: <55CBC524.4070101@gmail.com>

On 12/08/15 15:06, Jeremy Linton wrote:
> OF has some helper functions for parsing MAC and PHY settings.
> In cases where the platform is providing this information rather
> than the device itself, there needs to be similar functions for ACPI.
> 
> These functions are slightly modified versions of the ones in
> of_net which can use information provided via DT or ACPI.
> 
> Signed-off-by: Jeremy Linton <jeremy.linton at arm.com>
> ---

[snip]

> +
> +static void *device_get_mac_addr(struct device *dev,
> +				 const char *name, char *addr,
> +				 int alen)
> +{
> +	int ret = device_property_read_u8_array(dev, name, addr, alen);
> +
> +	if (ret == 0 && is_valid_ether_addr(addr))
> +		return addr;
> +	return NULL;

The DT counterpart has an additional check on the properly length to be
ETH_ALEN, you might want to have such check here for consistency and
correctness.

Other than that, this looks good to me.
-- 
Florian


From luto at kernel.org  Wed Aug 12 15:20:54 2015
From: luto at kernel.org (Andy Lutomirski)
Date: Wed, 12 Aug 2015 15:20:54 -0700
Subject: enabling libgcc for 64-bit divisions, was Re: PROBLEM: XFS on ARM
 corruption 'Structure needs cleaning'
In-Reply-To: <CA+55aFxcoXkaa1syBVxwb9-bn3rfyFam9fcNY438bkhHjHq+Vw@mail.gmail.com>
References: <5579B804.9050707@skylable.com>
 <20150612122108.GB60661@bfoster.bfoster> <557AD4D4.3010901@skylable.com>
 <20150612225209.GA20262@dastard>
 <C6D0D499B56584katsuki.uwatoko@toshiba.co.jp>
 <20150812062445.GA4520@infradead.org>
 <CA+55aFxcoXkaa1syBVxwb9-bn3rfyFam9fcNY438bkhHjHq+Vw@mail.gmail.com>
Message-ID: <55CBC6C6.3090306@kernel.org>

On 08/12/2015 08:49 AM, Linus Torvalds wrote:
> On Tue, Aug 11, 2015 at 11:24 PM, Christoph Hellwig <hch at infradead.org> wrote:
>>
>> Maybe it's time to rely on gcc to handle 64 bit divisions now?
>
> Ugh. gcc still does a pretty horrible job at it. While gcc knows that
> a widening 32x32->64 multiplication can be simplified, it doesn't do
> the same thing for a 64/32->64 division, and always calls __udivdi3
> for it.
>
> Now, __udivdi3 does avoid the general nasty case by then testing the
> upper 32 bits of the divisor against zero, so it's not entirely
> disastrous. It's just ugly.
>
> But perhaps more importantly, I'm not at all sure libgcc is
> kernel-safe. In particular, I'm not at all sure it *remains*
> kernel-safe. Just as an example: can you guarantee that libgcc doesn't
> implement integer division on some architecture by using the FP
> hardware?
>
> There's been a few cases where not having libgcc saved us headaches. I
> forget the exact details, but it was something like several years ago
> that we had gcc start to generate some insane crap exception handling
> for C code generation, and the fact that we didn't include libgcc was
> what made us catch it because of the resulting link error.
>
> libgcc just isn't reliable in kernel space. I'm not opposed to some
> random architecture using it (arch/tile does include "-lgcc" for
> example), but I _do_ object to the notion that we say "let's use
> libgcc in general".
>
> So no. I do not believe that the occasional pain of a few people who
> do 64-bit divides incorrectly is a good enough argument to start using
> libgcc.
>

Does your objection still apply if we supplied our own implementations 
of a handful of libgcc helpers?

--Andy

>                   Linus
>



From stefan.wahren at i2se.com  Wed Aug 12 15:21:56 2015
From: stefan.wahren at i2se.com (Stefan Wahren)
Date: Wed, 12 Aug 2015 22:21:56 +0000
Subject: [PATCH V6 3/3] ARM: mxs: enable ocotp for i.MX23 and i.MX28
In-Reply-To: <1439418116-1833-1-git-send-email-stefan.wahren@i2se.com>
References: <1439418116-1833-1-git-send-email-stefan.wahren@i2se.com>
Message-ID: <1439418116-1833-4-git-send-email-stefan.wahren@i2se.com>

This patch enables On Chip OTP support for i.MX23 and i.MX28 SoCs,
but keeps the old compatible string.

Signed-off-by: Stefan Wahren <stefan.wahren at i2se.com>
---
 arch/arm/boot/dts/imx23.dtsi |    7 +++++--
 arch/arm/boot/dts/imx28.dtsi |    7 +++++--
 2 files changed, 10 insertions(+), 4 deletions(-)

diff --git a/arch/arm/boot/dts/imx23.dtsi b/arch/arm/boot/dts/imx23.dtsi
index b995333..0541563 100644
--- a/arch/arm/boot/dts/imx23.dtsi
+++ b/arch/arm/boot/dts/imx23.dtsi
@@ -383,9 +383,12 @@
 			};
 
 			ocotp at 8002c000 {
-				compatible = "fsl,ocotp";
+				compatible = "fsl,imx23-ocotp", "fsl,ocotp";
+				#address-cells = <1>;
+				#size-cells = <1>;
 				reg = <0x8002c000 0x2000>;
-				status = "disabled";
+				clocks = <&clks 15>;
+				status = "okay";
 			};
 
 			axi-ahb at 8002e000 {
diff --git a/arch/arm/boot/dts/imx28.dtsi b/arch/arm/boot/dts/imx28.dtsi
index 4e073e8..648d790 100644
--- a/arch/arm/boot/dts/imx28.dtsi
+++ b/arch/arm/boot/dts/imx28.dtsi
@@ -936,9 +936,12 @@
 			};
 
 			ocotp: ocotp at 8002c000 {
-				compatible = "fsl,ocotp";
+				compatible = "fsl,imx28-ocotp", "fsl,ocotp";
+				#address-cells = <1>;
+				#size-cells = <1>;
 				reg = <0x8002c000 0x2000>;
-				status = "disabled";
+				clocks = <&clks 25>;
+				status = "okay";
 			};
 
 			axi-ahb at 8002e000 {
-- 
1.7.9.5



From stefan.wahren at i2se.com  Wed Aug 12 15:21:54 2015
From: stefan.wahren at i2se.com (Stefan Wahren)
Date: Wed, 12 Aug 2015 22:21:54 +0000
Subject: [PATCH V6 1/3] DT: nvmem: add binding for mxs-ocotp
In-Reply-To: <1439418116-1833-1-git-send-email-stefan.wahren@i2se.com>
References: <1439418116-1833-1-git-send-email-stefan.wahren@i2se.com>
Message-ID: <1439418116-1833-2-git-send-email-stefan.wahren@i2se.com>

This patch adds the devicetree bindings for the Freescale MXS On Chip
OTP driver.

Signed-off-by: Stefan Wahren <stefan.wahren at i2se.com>
---
 .../devicetree/bindings/nvmem/mxs-ocotp.txt        |   25 ++++++++++++++++++++
 1 file changed, 25 insertions(+)
 create mode 100644 Documentation/devicetree/bindings/nvmem/mxs-ocotp.txt

diff --git a/Documentation/devicetree/bindings/nvmem/mxs-ocotp.txt b/Documentation/devicetree/bindings/nvmem/mxs-ocotp.txt
new file mode 100644
index 0000000..daebce9
--- /dev/null
+++ b/Documentation/devicetree/bindings/nvmem/mxs-ocotp.txt
@@ -0,0 +1,25 @@
+On-Chip OTP Memory for Freescale i.MX23/i.MX28
+
+Required properties :
+- compatible :
+  - "fsl,imx23-ocotp" for i.MX23
+  - "fsl,imx28-ocotp" for i.MX28
+- #address-cells : Should be 1
+- #size-cells : Should be 1
+- reg : Address and length of OTP controller registers
+- clocks : Should contain a reference to the hbus clock
+
+= Data cells =
+Are child nodes of mxs-ocotp, bindings of which as described in
+bindings/nvmem/nvmem.txt
+
+Example for i.MX28:
+
+	ocotp: ocotp at 8002c000 {
+		compatible = "fsl,imx28-ocotp", "fsl,ocotp";
+		#address-cells = <1>;
+		#size-cells = <1>;
+		reg = <0x8002c000 0x2000>;
+		clocks = <&clks 25>;
+		status = "okay";
+	};
-- 
1.7.9.5



From stefan.wahren at i2se.com  Wed Aug 12 15:21:55 2015
From: stefan.wahren at i2se.com (Stefan Wahren)
Date: Wed, 12 Aug 2015 22:21:55 +0000
Subject: [PATCH V6 2/3] nvmem: add driver for ocotp in i.MX23 and i.MX28
In-Reply-To: <1439418116-1833-1-git-send-email-stefan.wahren@i2se.com>
References: <1439418116-1833-1-git-send-email-stefan.wahren@i2se.com>
Message-ID: <1439418116-1833-3-git-send-email-stefan.wahren@i2se.com>

This patch brings read-only support for the On-Chip OTP cells
in the i.MX23 and i.MX28 processor. The driver implements the
new NVMEM provider API.

Signed-off-by: Stefan Wahren <stefan.wahren at i2se.com>
Reviewed-by: Marek Vasut <marex at denx.de>
---
 drivers/nvmem/Kconfig     |   11 ++
 drivers/nvmem/Makefile    |    2 +
 drivers/nvmem/mxs-ocotp.c |  257 +++++++++++++++++++++++++++++++++++++++++++++
 3 files changed, 270 insertions(+)
 create mode 100644 drivers/nvmem/mxs-ocotp.c

diff --git a/drivers/nvmem/Kconfig b/drivers/nvmem/Kconfig
index 8db2978..a7b43b9 100644
--- a/drivers/nvmem/Kconfig
+++ b/drivers/nvmem/Kconfig
@@ -36,4 +36,15 @@ config NVMEM_SUNXI_SID
 	  This driver can also be built as a module. If so, the module
 	  will be called nvmem_sunxi_sid.
 
+config NVMEM_MXS_OCOTP
+	tristate "Freescale MXS On-Chip OTP Memory Support"
+	depends on ARCH_MXS || COMPILE_TEST
+	help
+	  If you say Y here, you will get readonly access to the
+	  One Time Programmable memory pages that are stored
+	  on the Freescale i.MX23/i.MX28 processor.
+
+	  This driver can also be built as a module. If so, the module
+	  will be called nvmem-mxs-ocotp.
+
 endif
diff --git a/drivers/nvmem/Makefile b/drivers/nvmem/Makefile
index 4328b93..e9b6f3c 100644
--- a/drivers/nvmem/Makefile
+++ b/drivers/nvmem/Makefile
@@ -10,3 +10,5 @@ obj-$(CONFIG_QCOM_QFPROM)	+= nvmem_qfprom.o
 nvmem_qfprom-y			:= qfprom.o
 obj-$(CONFIG_NVMEM_SUNXI_SID)	+= nvmem_sunxi_sid.o
 nvmem_sunxi_sid-y		:= sunxi_sid.o
+obj-$(CONFIG_NVMEM_MXS_OCOTP)	+= nvmem-mxs-ocotp.o
+nvmem-mxs-ocotp-y		:= mxs-ocotp.o
diff --git a/drivers/nvmem/mxs-ocotp.c b/drivers/nvmem/mxs-ocotp.c
new file mode 100644
index 0000000..8ba19bb
--- /dev/null
+++ b/drivers/nvmem/mxs-ocotp.c
@@ -0,0 +1,257 @@
+/*
+ * Freescale MXS On-Chip OTP driver
+ *
+ * Copyright (C) 2015 Stefan Wahren <stefan.wahren at i2se.com>
+ *
+ * Based on the driver from Huang Shijie and Christoph G. Baumann
+ *
+ * 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.h>
+#include <linux/delay.h>
+#include <linux/device.h>
+#include <linux/err.h>
+#include <linux/io.h>
+#include <linux/module.h>
+#include <linux/nvmem-provider.h>
+#include <linux/of_device.h>
+#include <linux/platform_device.h>
+#include <linux/regmap.h>
+#include <linux/slab.h>
+#include <linux/stmp_device.h>
+
+/* OCOTP registers and bits */
+
+#define BM_OCOTP_CTRL_RD_BANK_OPEN	BIT(12)
+#define BM_OCOTP_CTRL_ERROR		BIT(9)
+#define BM_OCOTP_CTRL_BUSY		BIT(8)
+
+#define OCOTP_TIMEOUT		10000
+#define OCOTP_DATA_OFFSET	0x20
+
+struct mxs_ocotp {
+	struct clk *clk;
+	void __iomem *base;
+	struct nvmem_device *nvmem;
+};
+
+static int mxs_ocotp_wait(struct mxs_ocotp *otp)
+{
+	int timeout = OCOTP_TIMEOUT;
+	unsigned int status = 0;
+
+	while (timeout--) {
+		status = readl(otp->base);
+
+		if (!(status & (BM_OCOTP_CTRL_BUSY | BM_OCOTP_CTRL_ERROR)))
+			break;
+
+		cpu_relax();
+	}
+
+	if (status & BM_OCOTP_CTRL_BUSY)
+		return -EBUSY;
+	else if (status & BM_OCOTP_CTRL_ERROR)
+		return -EIO;
+
+	return 0;
+}
+
+static int mxs_ocotp_read(void *context, const void *reg, size_t reg_size,
+			  void *val, size_t val_size)
+{
+	struct mxs_ocotp *otp = context;
+	unsigned int offset = *(u32 *)reg;
+	u32 *buf = val;
+	int ret;
+
+	ret = clk_enable(otp->clk);
+	if (ret)
+		return ret;
+
+	writel(BM_OCOTP_CTRL_ERROR, otp->base + STMP_OFFSET_REG_CLR);
+
+	ret = mxs_ocotp_wait(otp);
+	if (ret)
+		goto disable_clk;
+
+	/* open OCOTP banks for read */
+	writel(BM_OCOTP_CTRL_RD_BANK_OPEN, otp->base + STMP_OFFSET_REG_SET);
+
+	/* approximately wait 33 hclk cycles */
+	udelay(1);
+
+	ret = mxs_ocotp_wait(otp);
+	if (ret)
+		goto close_banks;
+
+	while (val_size) {
+		if ((offset < OCOTP_DATA_OFFSET) || (offset % 16)) {
+			/* fill up non-data register */
+			*buf = 0;
+		} else {
+			*buf = readl(otp->base + offset);
+		}
+
+		buf++;
+		val_size--;
+		offset += reg_size;
+	}
+
+close_banks:
+	/* close banks for power saving */
+	writel(BM_OCOTP_CTRL_RD_BANK_OPEN, otp->base + STMP_OFFSET_REG_CLR);
+
+disable_clk:
+	clk_disable(otp->clk);
+
+	return ret;
+}
+
+static int mxs_ocotp_write(void *context, const void *data, size_t count)
+{
+	/* We don't want to support writing */
+	return 0;
+}
+
+static bool mxs_ocotp_writeable_reg(struct device *dev, unsigned int reg)
+{
+	return false;
+}
+
+static struct nvmem_config ocotp_config = {
+	.name = "mxs-ocotp",
+	.owner = THIS_MODULE,
+};
+
+static const struct regmap_range imx23_ranges[] = {
+	regmap_reg_range(OCOTP_DATA_OFFSET, 0x210),
+};
+
+static const struct regmap_access_table imx23_access = {
+	.yes_ranges = imx23_ranges,
+	.n_yes_ranges = ARRAY_SIZE(imx23_ranges),
+};
+
+static const struct regmap_range imx28_ranges[] = {
+	regmap_reg_range(OCOTP_DATA_OFFSET, 0x290),
+};
+
+static const struct regmap_access_table imx28_access = {
+	.yes_ranges = imx28_ranges,
+	.n_yes_ranges = ARRAY_SIZE(imx28_ranges),
+};
+
+static struct regmap_bus mxs_ocotp_bus = {
+	.read = mxs_ocotp_read,
+	.write = mxs_ocotp_write, /* make regmap_init() happy */
+	.reg_format_endian_default = REGMAP_ENDIAN_NATIVE,
+	.val_format_endian_default = REGMAP_ENDIAN_NATIVE,
+};
+
+static struct regmap_config mxs_ocotp_config = {
+	.reg_bits = 32,
+	.val_bits = 32,
+	.reg_stride = 16,
+	.writeable_reg = mxs_ocotp_writeable_reg,
+};
+
+static const struct of_device_id mxs_ocotp_match[] = {
+	{ .compatible = "fsl,imx23-ocotp", .data = &imx23_access },
+	{ .compatible = "fsl,imx28-ocotp", .data = &imx28_access },
+	{ /* sentinel */},
+};
+MODULE_DEVICE_TABLE(of, mxs_ocotp_match);
+
+static int mxs_ocotp_probe(struct platform_device *pdev)
+{
+	struct device *dev = &pdev->dev;
+	struct mxs_ocotp *otp;
+	struct resource *res;
+	const struct of_device_id *match;
+	struct regmap *regmap;
+	const struct regmap_access_table *access;
+	int ret;
+
+	match = of_match_device(dev->driver->of_match_table, dev);
+	if (!match || !match->data)
+		return -EINVAL;
+
+	otp = devm_kzalloc(dev, sizeof(*otp), GFP_KERNEL);
+	if (!otp)
+		return -ENOMEM;
+
+	res = platform_get_resource(pdev, IORESOURCE_MEM, 0);
+	otp->base = devm_ioremap_resource(dev, res);
+	if (IS_ERR(otp->base))
+		return PTR_ERR(otp->base);
+
+	otp->clk = devm_clk_get(&pdev->dev, NULL);
+	if (IS_ERR(otp->clk))
+		return PTR_ERR(otp->clk);
+
+	ret = clk_prepare(otp->clk);
+	if (ret < 0) {
+		dev_err(dev, "failed to prepare clk: %d\n", ret);
+		return ret;
+	}
+
+	access = match->data;
+	mxs_ocotp_config.rd_table = access;
+	mxs_ocotp_config.max_register = access->yes_ranges[0].range_max;
+
+	regmap = devm_regmap_init(dev, &mxs_ocotp_bus, otp, &mxs_ocotp_config);
+	if (IS_ERR(regmap)) {
+		dev_err(dev, "regmap init failed\n");
+		ret = PTR_ERR(regmap);
+		goto err_clk;
+	}
+
+	ocotp_config.dev = dev;
+	otp->nvmem = nvmem_register(&ocotp_config);
+	if (IS_ERR(otp->nvmem)) {
+		ret = PTR_ERR(otp->nvmem);
+		goto err_clk;
+	}
+
+	platform_set_drvdata(pdev, otp);
+
+	return 0;
+
+err_clk:
+	clk_unprepare(otp->clk);
+
+	return ret;
+}
+
+static int mxs_ocotp_remove(struct platform_device *pdev)
+{
+	struct mxs_ocotp *otp = platform_get_drvdata(pdev);
+
+	clk_unprepare(otp->clk);
+
+	return nvmem_unregister(otp->nvmem);
+}
+
+static struct platform_driver mxs_ocotp_driver = {
+	.probe = mxs_ocotp_probe,
+	.remove = mxs_ocotp_remove,
+	.driver = {
+		.name = "mxs-ocotp",
+		.of_match_table = mxs_ocotp_match,
+	},
+};
+
+module_platform_driver(mxs_ocotp_driver);
+MODULE_AUTHOR("Stefan Wahren <stefan.wahren at i2se.com>");
+MODULE_DESCRIPTION("driver for OCOTP in i.MX23/i.MX28");
+MODULE_LICENSE("GPL v2");
-- 
1.7.9.5



From stefan.wahren at i2se.com  Wed Aug 12 15:21:53 2015
From: stefan.wahren at i2se.com (Stefan Wahren)
Date: Wed, 12 Aug 2015 22:21:53 +0000
Subject: [PATCH V6 0/3] nvmem: add ocotp support for i.MX23 and i.MX28
Message-ID: <1439418116-1833-1-git-send-email-stefan.wahren@i2se.com>

This patch series brings read-only support for the On-Chip OTP cells
in the i.MX23 and i.MX28 processor.

changes in V6:
- add COMPILE_TEST to dependancy
- remove unnecessary headers
- enable clock during read operation
- fix module license

changes in V5:
- rebase to char-misc-next
- add nvmem prefix to module name
- set status in dtsi files

changes in V4:
- rename fsl_ocotp.c to mxs-ocotp.c
- adapt driver to use NVMEM framework V7
- take care of hbus clock
- increase too small timeout
- implement a wait function
- use defines from stmp_device.h
- remove owner init
- more code cleanup

changes in V3:
- drop write support
- take care of i.MX23 which has less registers
- drop unnecessary header file
- move static variables into driver data
- add devicetree probing
- fix missing bank closing in error case
- use kobj from platform device for sysfs
- add SYSFS to Kconfig
- add binding file
- code cleanup

Stefan Wahren (3):
  DT: nvmem: add binding for mxs-ocotp
  nvmem: add driver for ocotp in i.MX23 and i.MX28
  ARM: mxs: enable ocotp for i.MX23 and i.MX28

 .../devicetree/bindings/nvmem/mxs-ocotp.txt        |   25 ++
 arch/arm/boot/dts/imx23.dtsi                       |    7 +-
 arch/arm/boot/dts/imx28.dtsi                       |    7 +-
 drivers/nvmem/Kconfig                              |   11 +
 drivers/nvmem/Makefile                             |    2 +
 drivers/nvmem/mxs-ocotp.c                          |  257 ++++++++++++++++++++
 6 files changed, 305 insertions(+), 4 deletions(-)
 create mode 100644 Documentation/devicetree/bindings/nvmem/mxs-ocotp.txt
 create mode 100644 drivers/nvmem/mxs-ocotp.c

-- 
1.7.9.5



From timur at codeaurora.org  Wed Aug 12 15:35:04 2015
From: timur at codeaurora.org (Timur Tabi)
Date: Wed, 12 Aug 2015 17:35:04 -0500
Subject: [Linaro-acpi] [PATCH 1/5] ACPI: add in a bad_madt_entry()
 function to eventually replace the macro
In-Reply-To: <1438894770-31163-2-git-send-email-al.stone@linaro.org>
References: <1438894770-31163-1-git-send-email-al.stone@linaro.org>
 <1438894770-31163-2-git-send-email-al.stone@linaro.org>
Message-ID: <CAOZdJXVZomskfpvEjmDUiptW3SndJWvfKyzd9SwJp3dh7h3pig@mail.gmail.com>

On Thu, Aug 6, 2015 at 3:59 PM, Al Stone <al.stone at linaro.org> wrote:
> +       while (ms->num_types != 0) {
> +               if (ms->major_version == major &&
> +                   ms->minor_version == minor &&
> +                   ms->madt_version == madt->header.revision)
> +                       break;
> +               ms++;
> +       }
> +       if (!ms) {

Shouldn't this be

  if (!ms->num_types) {

instead?

-- 
Qualcomm Innovation Center, Inc.
The Qualcomm Innovation Center, Inc. is a member of the Code Aurora Forum,
a Linux Foundation Collaborative Project.


From torvalds at linux-foundation.org  Wed Aug 12 15:36:14 2015
From: torvalds at linux-foundation.org (Linus Torvalds)
Date: Wed, 12 Aug 2015 15:36:14 -0700
Subject: enabling libgcc for 64-bit divisions, was Re: PROBLEM: XFS on ARM
 corruption 'Structure needs cleaning'
In-Reply-To: <55CBC6C6.3090306@kernel.org>
References: <5579B804.9050707@skylable.com>
 <20150612122108.GB60661@bfoster.bfoster>
 <557AD4D4.3010901@skylable.com> <20150612225209.GA20262@dastard>
 <C6D0D499B56584katsuki.uwatoko@toshiba.co.jp>
 <20150812062445.GA4520@infradead.org>
 <CA+55aFxcoXkaa1syBVxwb9-bn3rfyFam9fcNY438bkhHjHq+Vw@mail.gmail.com>
 <55CBC6C6.3090306@kernel.org>
Message-ID: <CA+55aFx3-8LRR9aFDM-CrunSEFrSs+z_=iAZ6n-+wgNRzJ4NQQ@mail.gmail.com>

On Wed, Aug 12, 2015 at 3:20 PM, Andy Lutomirski <luto at kernel.org> wrote:
>
> Does your objection still apply if we supplied our own implementations of a
> handful of libgcc helpers?

We already do that.

Several architectures actually implement _udivdi3.

However, do_div() is actually the much simpler/better interface.

I don't think we have a single case in the kernel where we really want
the full 64/64 division, and the 64/32->64 case really is
fundamentally simpler.

This whole "do_div is so complicated" thing is just BS.

The thing that triggered Christoph to ask was a bug in the
implementation of that *simpler*  interface. What makes you think that
making people implement _udivdi3 would magically avoid all such bugs?

                Linus


From luto at amacapital.net  Wed Aug 12 15:39:19 2015
From: luto at amacapital.net (Andy Lutomirski)
Date: Wed, 12 Aug 2015 15:39:19 -0700
Subject: enabling libgcc for 64-bit divisions, was Re: PROBLEM: XFS on ARM
 corruption 'Structure needs cleaning'
In-Reply-To: <CA+55aFx3-8LRR9aFDM-CrunSEFrSs+z_=iAZ6n-+wgNRzJ4NQQ@mail.gmail.com>
References: <5579B804.9050707@skylable.com>
 <20150612122108.GB60661@bfoster.bfoster>
 <557AD4D4.3010901@skylable.com> <20150612225209.GA20262@dastard>
 <C6D0D499B56584katsuki.uwatoko@toshiba.co.jp>
 <20150812062445.GA4520@infradead.org>
 <CA+55aFxcoXkaa1syBVxwb9-bn3rfyFam9fcNY438bkhHjHq+Vw@mail.gmail.com>
 <55CBC6C6.3090306@kernel.org>
 <CA+55aFx3-8LRR9aFDM-CrunSEFrSs+z_=iAZ6n-+wgNRzJ4NQQ@mail.gmail.com>
Message-ID: <CALCETrVP1a+NMC1tGLSGQef4eeWHGgFLLh=ayNLrpoMOCWctJg@mail.gmail.com>

On Wed, Aug 12, 2015 at 3:36 PM, Linus Torvalds
<torvalds at linux-foundation.org> wrote:
> On Wed, Aug 12, 2015 at 3:20 PM, Andy Lutomirski <luto at kernel.org> wrote:
>>
>> Does your objection still apply if we supplied our own implementations of a
>> handful of libgcc helpers?
>
> We already do that.
>
> Several architectures actually implement _udivdi3.
>
> However, do_div() is actually the much simpler/better interface.
>
> I don't think we have a single case in the kernel where we really want
> the full 64/64 division, and the 64/32->64 case really is
> fundamentally simpler.
>
> This whole "do_div is so complicated" thing is just BS.
>
> The thing that triggered Christoph to ask was a bug in the
> implementation of that *simpler*  interface. What makes you think that
> making people implement _udivdi3 would magically avoid all such bugs?
>

Nothing.

We could ask gcc to fix this, I suppose (add __udiv_64_over_32 or whatever).

--Andy


From festevam at gmail.com  Wed Aug 12 15:47:44 2015
From: festevam at gmail.com (Fabio Estevam)
Date: Wed, 12 Aug 2015 19:47:44 -0300
Subject: [PATCH V6 1/3] DT: nvmem: add binding for mxs-ocotp
In-Reply-To: <1439418116-1833-2-git-send-email-stefan.wahren@i2se.com>
References: <1439418116-1833-1-git-send-email-stefan.wahren@i2se.com>
 <1439418116-1833-2-git-send-email-stefan.wahren@i2se.com>
Message-ID: <CAOMZO5AK9DGNrX2caxLdEKa17qm9hhAERTkKK4aa6qeRYBT+uQ@mail.gmail.com>

On Wed, Aug 12, 2015 at 7:21 PM, Stefan Wahren <stefan.wahren at i2se.com> wrote:
> This patch adds the devicetree bindings for the Freescale MXS On Chip
> OTP driver.
>
> Signed-off-by: Stefan Wahren <stefan.wahren at i2se.com>

Reviewed-by: Fabio Estevam <fabio.estevam at freescale.com>


From festevam at gmail.com  Wed Aug 12 15:48:15 2015
From: festevam at gmail.com (Fabio Estevam)
Date: Wed, 12 Aug 2015 19:48:15 -0300
Subject: [PATCH V6 2/3] nvmem: add driver for ocotp in i.MX23 and i.MX28
In-Reply-To: <1439418116-1833-3-git-send-email-stefan.wahren@i2se.com>
References: <1439418116-1833-1-git-send-email-stefan.wahren@i2se.com>
 <1439418116-1833-3-git-send-email-stefan.wahren@i2se.com>
Message-ID: <CAOMZO5A=eqrqOA+Prt72GFqBGtHmwOM4VVV=hU0q+GN59Kizqw@mail.gmail.com>

On Wed, Aug 12, 2015 at 7:21 PM, Stefan Wahren <stefan.wahren at i2se.com> wrote:
> This patch brings read-only support for the On-Chip OTP cells
> in the i.MX23 and i.MX28 processor. The driver implements the
> new NVMEM provider API.
>
> Signed-off-by: Stefan Wahren <stefan.wahren at i2se.com>
> Reviewed-by: Marek Vasut <marex at denx.de>

Reviewed-by: Fabio Estevam <fabio.estevam at freescale.com>


From festevam at gmail.com  Wed Aug 12 15:48:39 2015
From: festevam at gmail.com (Fabio Estevam)
Date: Wed, 12 Aug 2015 19:48:39 -0300
Subject: [PATCH V6 3/3] ARM: mxs: enable ocotp for i.MX23 and i.MX28
In-Reply-To: <1439418116-1833-4-git-send-email-stefan.wahren@i2se.com>
References: <1439418116-1833-1-git-send-email-stefan.wahren@i2se.com>
 <1439418116-1833-4-git-send-email-stefan.wahren@i2se.com>
Message-ID: <CAOMZO5CF_OMOTYrM+Dsxp54Do9GkoPPrWEN4k-BcCvQyQ8V0UA@mail.gmail.com>

On Wed, Aug 12, 2015 at 7:21 PM, Stefan Wahren <stefan.wahren at i2se.com> wrote:
> This patch enables On Chip OTP support for i.MX23 and i.MX28 SoCs,
> but keeps the old compatible string.
>
> Signed-off-by: Stefan Wahren <stefan.wahren at i2se.com>

Reviewed-by: Fabio Estevam <fabio.estevam at freescale.com>


From petr.cvek at tul.cz  Wed Aug 12 15:51:25 2015
From: petr.cvek at tul.cz (Petr Cvek)
Date: Thu, 13 Aug 2015 00:51:25 +0200
Subject: [PATCH v1 RFC] This patch repairs HTC Magician machine (PXA27x)
 support
Message-ID: <55CBCDED.8010409@tul.cz>

Fixing original code: Problems to successful boot due to the bad LCD
power sequence (wrongly configured GPIO).

Add/fix platform data and helper function for various hardware
(touchscreen, audio, USB device, ...).

Add new discovered GPIOs and fix names by GPIO context.

Add new LEDs driver.

Signed-off-by: Petr Cvek <petr.cvek at tul.cz>
---
 arch/arm/mach-pxa/Kconfig                 |    1 +
 arch/arm/mach-pxa/include/mach/magician.h |   21 +-
 arch/arm/mach-pxa/magician.c              | 1148 +++++++++++++++++++++++------
 drivers/leds/Kconfig                      |    9 +
 drivers/leds/Makefile                     |    1 +
 drivers/leds/leds-pasic3.c                |  192 +++++
 drivers/mfd/htc-pasic3.c                  |  115 ++-
 include/linux/mfd/htc-pasic3.h            |   69 +-
 8 files changed, 1293 insertions(+), 263 deletions(-)
 create mode 100644 drivers/leds/leds-pasic3.c

diff --git a/arch/arm/mach-pxa/Kconfig b/arch/arm/mach-pxa/Kconfig
index f096836..5c7b6ee 100644
--- a/arch/arm/mach-pxa/Kconfig
+++ b/arch/arm/mach-pxa/Kconfig
@@ -294,6 +294,7 @@ config MACH_MAGICIAN
 	bool "Enable HTC Magician Support"
 	select IWMMXT
 	select PXA27x
+	select HTC_EGPIO
 
 config MACH_MIOA701
 	bool "Mitac Mio A701 Support"
diff --git a/arch/arm/mach-pxa/include/mach/magician.h b/arch/arm/mach-pxa/include/mach/magician.h
index ba6a6e1..8d3936d 100644
--- a/arch/arm/mach-pxa/include/mach/magician.h
+++ b/arch/arm/mach-pxa/include/mach/magician.h
@@ -32,6 +32,8 @@
 #define GPIO37_MAGICIAN_KEY_HANGUP		37
 #define GPIO38_MAGICIAN_KEY_CONTACTS		38
 #define GPIO40_MAGICIAN_GSM_OUT2		40
+#define GPIO46_MAGICIAN_IR_RX			46
+#define GPIO47_MAGICIAN_IR_TX			47
 #define GPIO48_MAGICIAN_UNKNOWN			48
 #define GPIO56_MAGICIAN_UNKNOWN			56
 #define GPIO57_MAGICIAN_CAM_RESET		57
@@ -52,14 +54,16 @@
 #define GPIO101_MAGICIAN_KEY_VOL_DOWN 		101
 #define GPIO102_MAGICIAN_KEY_PHONE		102
 #define GPIO103_MAGICIAN_LED_KP			103
-#define GPIO104_MAGICIAN_LCD_POWER_1 		104
-#define GPIO105_MAGICIAN_LCD_POWER_2		105
-#define GPIO106_MAGICIAN_LCD_POWER_3		106
+#define GPIO104_MAGICIAN_LCD_VOFF_EN           104
+#define GPIO105_MAGICIAN_LCD_VON_EN            105
+#define GPIO106_MAGICIAN_LCD_DCDC_NRESET       106
 #define GPIO107_MAGICIAN_DS1WM_IRQ		107
 #define GPIO108_MAGICIAN_GSM_READY		108
 #define GPIO114_MAGICIAN_UNKNOWN		114
 #define GPIO115_MAGICIAN_nPEN_IRQ		115
 #define GPIO116_MAGICIAN_nCAM_EN		116
+#define GPIO117_MAGICIAN_I2C_SCL		117
+#define GPIO118_MAGICIAN_I2C_SDA		118
 #define GPIO119_MAGICIAN_UNKNOWN		119
 #define GPIO120_MAGICIAN_UNKNOWN		120
 
@@ -98,16 +102,19 @@
 #define EGPIO_MAGICIAN_BL_POWER			MAGICIAN_EGPIO(1, 7)
 #define EGPIO_MAGICIAN_SD_POWER			MAGICIAN_EGPIO(2, 0)
 #define EGPIO_MAGICIAN_CARKIT_MIC		MAGICIAN_EGPIO(2, 1)
-#define EGPIO_MAGICIAN_UNKNOWN_WAVEDEV_DLL	MAGICIAN_EGPIO(2, 2)
+#define EGPIO_MAGICIAN_IR_RECEIVE_SHUTDOWN		MAGICIAN_EGPIO(2, 2)
 #define EGPIO_MAGICIAN_FLASH_VPP		MAGICIAN_EGPIO(2, 3)
 #define EGPIO_MAGICIAN_BL_POWER2		MAGICIAN_EGPIO(2, 4)
 #define EGPIO_MAGICIAN_BQ24022_ISET2		MAGICIAN_EGPIO(2, 5)
+#define EGPIO_MAGICIAN_NICD_CHARGE		MAGICIAN_EGPIO(2, 6)
 #define EGPIO_MAGICIAN_GSM_POWER		MAGICIAN_EGPIO(2, 7)
 
 /* input */
 
-#define EGPIO_MAGICIAN_CABLE_STATE_AC		MAGICIAN_EGPIO(4, 0)
-#define EGPIO_MAGICIAN_CABLE_STATE_USB		MAGICIAN_EGPIO(4, 1)
+/* AC=1, USB=0 */
+#define EGPIO_MAGICIAN_CABLE_TYPE		MAGICIAN_EGPIO(4, 0)
+/* =1 when AC or USB cable inserted */
+#define EGPIO_MAGICIAN_CABLE_INSERT1		MAGICIAN_EGPIO(4, 1)
 
 #define EGPIO_MAGICIAN_BOARD_ID0		MAGICIAN_EGPIO(5, 0)
 #define EGPIO_MAGICIAN_BOARD_ID1		MAGICIAN_EGPIO(5, 1)
@@ -116,5 +123,7 @@
 #define EGPIO_MAGICIAN_nSD_READONLY		MAGICIAN_EGPIO(5, 4)
 
 #define EGPIO_MAGICIAN_EP_INSERT		MAGICIAN_EGPIO(6, 1)
+/* FIXME same like 4,1, may differ for host/device */
+#define EGPIO_MAGICIAN_CABLE_INSERT2	MAGICIAN_EGPIO(6, 4)
 
 #endif /* _MAGICIAN_H_ */
diff --git a/arch/arm/mach-pxa/magician.c b/arch/arm/mach-pxa/magician.c
index a9761c2..6872d5b 100644
--- a/arch/arm/mach-pxa/magician.c
+++ b/arch/arm/mach-pxa/magician.c
@@ -4,13 +4,54 @@
  * and T-Mobile MDA Compact.
  *
  * Copyright (c) 2006-2007 Philipp Zabel
+ * Copyright (c) 2014-2015 Petr Cvek (massive rework)
  *
- * Based on hx4700.c, spitz.c and others.
+ * Based on hx4700.c, spitz.c, board-overo.c and others.
  *
  * 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.
  *
+ *
+ * NOTICE MDA Compact (T-mobile XDA) facts:
+ *   On "LCD type = 1, system_rev = 2" (0x3a in CPLD)
+ * Samsung LTP280QV - valid LCD init sequence sequence:
+ *   powerup: Vdigital->Vanalog->gate Voff->gate Von->data enable
+ *   powerdown: data disable->gate Von->gate Voff->Vanalog->Vdigital
+ * Measured on PCB:
+ *   GPIO106
+ *     Affects VOFF, VON and other voltages
+ *     Probably main reset pin for DC-DC converter
+ *   GPIO75
+ *     Must be AF0+OUT (WM leaves it to AF2+OUT), not LCD signal
+ *     GPIO106 works only when GPIO75 is high (DC-DC power enable?)
+ *     After LCD powerup, value is irrelevant
+ *   GPIO104
+ *     LCD VOFF (gate off voltage)
+ *   GPIO105
+ *     LCD VON (gate on voltage)
+ * FFUART (/dev/ttyS0) WM: 38400,8,n,1,crtscts (GSM data?)
+ * BTUART (/dev/ttyS1) WM: 115200,8,n,1,crtscts (GSM AT commands)
+ *   Use a HTC line discipline: 0x02 channel(==0x16) data 0x02
+ * EGPIO(CPLD) should be always present (controls "all" supply power)
+ *   For rootfs on MMC/SD: EGPIO module controls card power (in kernel)
+ * cpu-freq often freeze platform (errata?, use userspace gov)
+ * Do not use YUV420, (erratum E24) causes LCD hang (forever)
+ * Many GSM related pins are unknown
+ * gpio-rc-recv probably require lowpass filter (sw is OK)
+ * TODO EGPIO_MAGICIAN_IR_RECEIVE_SHUTDOWN
+ * FIXME AC charging blocks IrDA
+ * Unimplemented blocking of camera+power+reset, reset and door open reset
+ *   Registers: htc-pasic3.h (but blocks charging too)
+ * Other PXA machines have wait_for_sync for ADS7846 (during LCD refresh)
+ * pda-power has not optimal charging (accu can be bloated)
+ * TODO Current switching works? Is gpio-regulator/bq24022 required?
+ * pdata supports alternative drivers (mutually exclusive modules)
+ *   i2c-pxa vs i2c-gpio (SCCB)
+ *   pwm_bl vs gpio_backlight
+ *   pxa27x_udc vs phy-gpio-vbus-usb
+ *   physmap-flash vs pxa2xx-flash
+ *
  */
 
 #include <linux/kernel.h>
@@ -28,8 +69,14 @@
 #include <linux/regulator/driver.h>
 #include <linux/regulator/gpio-regulator.h>
 #include <linux/regulator/machine.h>
+#include <linux/regulator/fixed.h>
+#include <linux/regulator/max1586.h>
+
 #include <linux/usb/gpio_vbus.h>
 #include <linux/i2c/pxa-i2c.h>
+#include <linux/i2c-gpio.h>
+#include <linux/i2c.h>
+
 
 #include <mach/hardware.h>
 #include <asm/mach-types.h>
@@ -42,46 +89,74 @@
 #include <linux/platform_data/mmc-pxamci.h>
 #include <linux/platform_data/irda-pxaficp.h>
 #include <linux/platform_data/usb-ohci-pxa27x.h>
+#include <linux/platform_data/camera-pxa.h>
+
+#include <linux/platform_data/gpio_backlight.h>
+
+#include <linux/platform_data/pxa2xx_udc.h>
+#include <mach/udc.h>
+#include <mach/pxa27x-udc.h>
+#include <linux/usb/g_hid.h>
+
+#include <media/soc_camera.h>
+#include <sound/uda1380.h>
 
 #include "devices.h"
 #include "generic.h"
 
+#include <linux/spi/ads7846.h>
+#include <linux/spi/pxa2xx_spi.h>
+#include <linux/spi/spi.h>
+#include <linux/i2c/pxa-i2c.h>
+#include <media/gpio-ir-recv.h>
+
 static unsigned long magician_pin_config[] __initdata = {
 
 	/* SDRAM and Static Memory I/O Signals */
 	GPIO20_nSDCS_2,
 	GPIO21_nSDCS_3,
 	GPIO15_nCS_1,
-	GPIO78_nCS_2,   /* PASIC3 */
-	GPIO79_nCS_3,   /* EGPIO CPLD */
+	GPIO78_nCS_2,	/* PASIC3 */
+	GPIO79_nCS_3,	/* EGPIO CPLD */
 	GPIO80_nCS_4,
 	GPIO33_nCS_5,
+	GPIO49_nPWE,
+	GPIO18_RDY,
 
-	/* I2C */
+	/* I2C UDA1380 + OV9640 */
 	GPIO117_I2C_SCL,
 	GPIO118_I2C_SDA,
 
-	/* PWM 0 */
+	/* Omnivision camera power and reset GPIO*/
+	MFP_CFG_OUT(GPIO116, AF0, DRIVE_HIGH),	/* nEnable, active in low*/
+	MFP_CFG_OUT(GPIO57, AF0, DRIVE_HIGH),	/* Reset, active in high*/
+
+#if IS_ENABLED(CONFIG_PWM_PXA)
+	/* PWM 0 - LCD backlight */
 	GPIO16_PWM0_OUT,
+#else
+	/* Ensure static backlight without any driver */
+	MFP_CFG_OUT(GPIO16, AF0, DRIVE_HIGH),	/* Backlight enabled */
+#endif
 
-	/* I2S */
+	/* I2S UDA1380 capture */
 	GPIO28_I2S_BITCLK_OUT,
 	GPIO29_I2S_SDATA_IN,
 	GPIO31_I2S_SYNC,
 	GPIO113_I2S_SYSCLK,
 
-	/* SSP 1 */
+	/* SSP 1 UDA1380 playback */
 	GPIO23_SSP1_SCLK,
 	GPIO24_SSP1_SFRM,
 	GPIO25_SSP1_TXD,
 
-	/* SSP 2 */
+	/* SSP 2 TSC2046 touchscreen */
 	GPIO19_SSP2_SCLK,
 	GPIO14_SSP2_SFRM,
 	GPIO89_SSP2_TXD,
 	GPIO88_SSP2_RXD,
 
-	/* MMC */
+	/* MMC/SD/SDHC slot */
 	GPIO32_MMC_CLK,
 	GPIO92_MMC_DAT_0,
 	GPIO109_MMC_DAT_1,
@@ -89,10 +164,28 @@ static unsigned long magician_pin_config[] __initdata = {
 	GPIO111_MMC_DAT_3,
 	GPIO112_MMC_CMD,
 
-	/* LCD */
-	GPIOxx_LCD_TFT_16BPP,
-
-	/* QCI */
+	/*
+	 * LCD
+	 * NOTICE Samsung LTP280QV:
+	 *   cannot use GPIOxx_LCD_TFT_16BPP, GPIO75 is LCD power,
+	 * 74 unused (AF0 by bootloader?)
+	 */
+	GPIOxx_LCD_16BPP,
+	GPIO76_LCD_PCLK,
+	GPIO77_LCD_BIAS,	/* data_valid (v/hsync) (ADS7846 sync?) */
+
+	/* NOTICE valid LCD init sequence */
+
+	/* for GPIO75_MAGICIAN_SAMSUNG_POWER */
+	MFP_CFG_OUT(GPIO75, AF0, DRIVE_HIGH),
+	/* for GPIO106_MAGICIAN_LCD_DCDC_NRESET */
+	MFP_CFG_OUT(GPIO106, AF0, DRIVE_HIGH),
+	/* for GPIO104_MAGICIAN_LCD_VOFF_EN */
+	MFP_CFG_OUT(GPIO104, AF0, DRIVE_HIGH),
+	/* for GPIO105_MAGICIAN_LCD_VON_EN */
+	MFP_CFG_OUT(GPIO105, AF0, DRIVE_HIGH),
+
+	/* QCI camera interface */
 	GPIO12_CIF_DD_7,
 	GPIO17_CIF_DD_6,
 	GPIO50_CIF_DD_3,
@@ -107,25 +200,101 @@ static unsigned long magician_pin_config[] __initdata = {
 	GPIO85_CIF_LV,
 
 	/* Magician specific input GPIOs */
-	GPIO9_GPIO,	/* unknown */
 	GPIO10_GPIO,	/* GSM_IRQ */
 	GPIO13_GPIO,	/* CPLD_IRQ */
 	GPIO107_GPIO,	/* DS1WM_IRQ */
 	GPIO108_GPIO,	/* GSM_READY */
 	GPIO115_GPIO,	/* nPEN_IRQ */
 
-	/* I2C */
-	GPIO117_I2C_SCL,
-	GPIO118_I2C_SDA,
+	/* IrDA transmitter(?) disable */
+	MFP_CFG_OUT(GPIO83, AF0, DRIVE_HIGH),
+
+	/* Vibration motor */
+	MFP_CFG_OUT(GPIO22, AF0, DRIVE_LOW),
+
+	/* Keypad LEDs (red/green phone) */
+	MFP_CFG_OUT(GPIO103, AF0, DRIVE_LOW),
+
+	/* GSM pins */
+	MFP_CFG_OUT(GPIO11, AF0, DRIVE_LOW), /* CPU is unavailable(?) */
+	MFP_CFG_OUT(GPIO26, AF0, DRIVE_LOW), /* GSM power, active high */
+	MFP_CFG_OUT(GPIO86, AF0, DRIVE_HIGH), /* GSM reset, active high */
+
+	/* USB connector */
+	MFP_CFG_OUT(GPIO27, AF0, DRIVE_LOW), /* usbc pull-up enable */
+	MFP_CFG_OUT(GPIO30, AF0, DRIVE_LOW), /* charging enable, active low */
+
+	/* FFUART, FIXME never observed to do something, GSM data? */
+	GPIO34_FFUART_RXD,
+	GPIO35_FFUART_CTS,
+	GPIO36_FFUART_DCD,
+	GPIO39_FFUART_TXD,
+	GPIO41_FFUART_RTS,
+
+	/* BTUART, AT commands/data, HTC port line discipline */
+	GPIO42_BTUART_RXD,
+	GPIO43_BTUART_TXD,
+	GPIO44_BTUART_CTS,
+	GPIO45_BTUART_RTS,
+
+	/* Power I2C, enabled controller will overrule GPIO */
+	GPIO3_GPIO,	/* SCL */
+	GPIO4_GPIO,	/* SDA */
+
+	/* IrDA GPIOs, if pxaficp, it will change AF accordingly to mode */
+	MFP_CFG_IN(GPIO46, AF0),
+	MFP_CFG_OUT(GPIO47, AF0, DRIVE_LOW),
+	MFP_CFG_OUT(GPIO83, AF0, DRIVE_HIGH),
+
+	/* TODO unknown */
+	GPIO9_GPIO,		/* unknown */
+	MFP_CFG_OUT(GPIO40, AF0, DRIVE_LOW),	/* FIXME GSM? */
+	MFP_CFG_OUT(GPIO87, AF0, DRIVE_LOW),	/* FIXME GSM? */
+
+	/* Left GPIOs (undefined here):
+	 * 18, 49 : bootloader=VLIO?, WinM=TODO
+	 * 48 : AF0/out0
+	 * 56 : AF0/out0
+	 * 74 : bootloader=AF0/output
+	 * 86 : bootloader=AF0/input (but should be gsm reset???)
+	 * 114 : AF0/out0
+	 * 119 : AF0/out0
+	 * 120 : AF0/out
+	 * 1 : dedicated reset, AF0/output
+	 * 13 : cpld irq, output (??)
+	 */
 };
 
 /*
- * IRDA
+ * IrDA
  */
 
 static struct pxaficp_platform_data magician_ficp_info = {
 	.gpio_pwdown		= GPIO83_MAGICIAN_nIR_EN,
-	.transceiver_cap	= IR_SIRMODE | IR_OFF,
+	/* TODO test with FIR dongle */
+	.transceiver_cap	= IR_SIRMODE | IR_FIRMODE | IR_OFF,
+	.gpio_pwdown_inverted = 0,
+};
+
+/*
+ * LIRC
+ * IrDA module can receive CIR, but it does not filter the carrier
+ * frequency. Low pass filter in driver (or HW) may be required.
+ */
+
+struct gpio_ir_recv_platform_data lirc_gpio_pdata = {
+	.gpio_nr = GPIO46_MAGICIAN_IR_RX,
+	.map_name = NULL,
+	.allowed_protos = 0,
+	.active_low = 0,
+};
+
+static struct platform_device lirc_gpio = {
+	.name = "gpio-rc-recv",
+	.dev = {
+		.platform_data = &lirc_gpio_pdata,
+	},
+	.id = -1,
 };
 
 /*
@@ -134,60 +303,59 @@ static struct pxaficp_platform_data magician_ficp_info = {
 
 #define INIT_KEY(_code, _gpio, _desc)	\
 	{				\
-		.code   = KEY_##_code,	\
-		.gpio   = _gpio,	\
-		.desc   = _desc,	\
-		.type   = EV_KEY,	\
-		.wakeup = 1,		\
+		.code = KEY_##_code,	\
+		.gpio = _gpio,	\
+		.desc = _desc,	\
+		.type = EV_KEY,	\
+		.wakeup = 1,	\
 	}
 
 static struct gpio_keys_button magician_button_table[] = {
-	INIT_KEY(POWER,      GPIO0_MAGICIAN_KEY_POWER,      "Power button"),
-	INIT_KEY(ESC,        GPIO37_MAGICIAN_KEY_HANGUP,    "Hangup button"),
-	INIT_KEY(F10,        GPIO38_MAGICIAN_KEY_CONTACTS,  "Contacts button"),
-	INIT_KEY(CALENDAR,   GPIO90_MAGICIAN_KEY_CALENDAR,  "Calendar button"),
-	INIT_KEY(CAMERA,     GPIO91_MAGICIAN_KEY_CAMERA,    "Camera button"),
-	INIT_KEY(UP,         GPIO93_MAGICIAN_KEY_UP,        "Up button"),
-	INIT_KEY(DOWN,       GPIO94_MAGICIAN_KEY_DOWN,      "Down button"),
-	INIT_KEY(LEFT,       GPIO95_MAGICIAN_KEY_LEFT,      "Left button"),
-	INIT_KEY(RIGHT,      GPIO96_MAGICIAN_KEY_RIGHT,     "Right button"),
-	INIT_KEY(KPENTER,    GPIO97_MAGICIAN_KEY_ENTER,     "Action button"),
-	INIT_KEY(RECORD,     GPIO98_MAGICIAN_KEY_RECORD,    "Record button"),
-	INIT_KEY(VOLUMEUP,   GPIO100_MAGICIAN_KEY_VOL_UP,   "Volume up"),
+	INIT_KEY(POWER, GPIO0_MAGICIAN_KEY_POWER, "Power button"),
+	INIT_KEY(ESC, GPIO37_MAGICIAN_KEY_HANGUP, "Hangup button"),
+	INIT_KEY(F10, GPIO38_MAGICIAN_KEY_CONTACTS, "Contacts button"),
+	INIT_KEY(CALENDAR, GPIO90_MAGICIAN_KEY_CALENDAR, "Calendar button"),
+	INIT_KEY(CAMERA, GPIO91_MAGICIAN_KEY_CAMERA, "Camera button"),
+	INIT_KEY(UP, GPIO93_MAGICIAN_KEY_UP, "Up button"),
+	INIT_KEY(DOWN, GPIO94_MAGICIAN_KEY_DOWN, "Down button"),
+	INIT_KEY(LEFT, GPIO95_MAGICIAN_KEY_LEFT, "Left button"),
+	INIT_KEY(RIGHT, GPIO96_MAGICIAN_KEY_RIGHT, "Right button"),
+	INIT_KEY(KPENTER, GPIO97_MAGICIAN_KEY_ENTER, "Action button"),
+	INIT_KEY(RECORD, GPIO98_MAGICIAN_KEY_RECORD, "Record button"),
+	INIT_KEY(VOLUMEUP, GPIO100_MAGICIAN_KEY_VOL_UP, "Volume up"),
 	INIT_KEY(VOLUMEDOWN, GPIO101_MAGICIAN_KEY_VOL_DOWN, "Volume down"),
-	INIT_KEY(PHONE,      GPIO102_MAGICIAN_KEY_PHONE,    "Phone button"),
-	INIT_KEY(PLAY,       GPIO99_MAGICIAN_HEADPHONE_IN,  "Headset button"),
+	INIT_KEY(PHONE, GPIO102_MAGICIAN_KEY_PHONE, "Phone button"),
+	INIT_KEY(PLAY, GPIO99_MAGICIAN_HEADPHONE_IN, "Headset button"),
 };
 
 static struct gpio_keys_platform_data gpio_keys_data = {
-	.buttons  = magician_button_table,
+	.buttons = magician_button_table,
 	.nbuttons = ARRAY_SIZE(magician_button_table),
 };
 
 static struct platform_device gpio_keys = {
 	.name = "gpio-keys",
-	.dev  = {
+	.dev = {
 		.platform_data = &gpio_keys_data,
 	},
-	.id   = -1,
+	.id = -1,
 };
 
-
 /*
  * EGPIO (Xilinx CPLD)
- *
- * 7 32-bit aligned 8-bit registers: 3x output, 1x irq, 3x input
+ * 32-bit aligned
+ * 7x 8-bit registers: 3x output, 1x irq, 3x input
  */
 
 static struct resource egpio_resources[] = {
 	[0] = {
 		.start = PXA_CS3_PHYS,
-		.end   = PXA_CS3_PHYS + 0x20 - 1,
+		.end = PXA_CS3_PHYS + 0x20 - 1,
 		.flags = IORESOURCE_MEM,
 	},
 	[1] = {
 		.start = PXA_GPIO_TO_IRQ(GPIO13_MAGICIAN_CPLD_IRQ),
-		.end   = PXA_GPIO_TO_IRQ(GPIO13_MAGICIAN_CPLD_IRQ),
+		.end = PXA_GPIO_TO_IRQ(GPIO13_MAGICIAN_CPLD_IRQ),
 		.flags = IORESOURCE_IRQ,
 	},
 };
@@ -198,7 +366,12 @@ static struct htc_egpio_chip egpio_chips[] = {
 		.gpio_base = MAGICIAN_EGPIO(0, 0),
 		.num_gpios = 24,
 		.direction = HTC_EGPIO_OUTPUT,
-		.initial_values = 0x40, /* EGPIO_MAGICIAN_GSM_RESET */
+
+		/*
+		 * Depends on modules configuration
+		 * Things like MMC and LCD should be enabled
+		 */
+		.initial_values = 0x21a0c0,
 	},
 	[1] = {
 		.reg_start = 4,
@@ -209,19 +382,19 @@ static struct htc_egpio_chip egpio_chips[] = {
 };
 
 static struct htc_egpio_platform_data egpio_info = {
-	.reg_width    = 8,
-	.bus_width    = 32,
-	.irq_base     = IRQ_BOARD_START,
-	.num_irqs     = 4,
+	.reg_width = 8,
+	.bus_width = 32,
+	.irq_base = IRQ_BOARD_START,
+	.num_irqs = 4,
 	.ack_register = 3,
-	.chip         = egpio_chips,
-	.num_chips    = ARRAY_SIZE(egpio_chips),
+	.chip	= egpio_chips,
+	.num_chips = ARRAY_SIZE(egpio_chips),
 };
 
 static struct platform_device egpio = {
-	.name          = "htc-egpio",
-	.id            = -1,
-	.resource      = egpio_resources,
+	.name	= "htc-egpio",
+	.id	= -1,
+	.resource = egpio_resources,
 	.num_resources = ARRAY_SIZE(egpio_resources),
 	.dev = {
 		.platform_data = &egpio_info,
@@ -229,95 +402,89 @@ static struct platform_device egpio = {
 };
 
 /*
- * LCD - Toppoly TD028STEB1 or Samsung LTP280QV
+ * PXAFB LCD - Toppoly TD028STEB1 or Samsung LTP280QV
  */
 
 static struct pxafb_mode_info toppoly_modes[] = {
 	{
-		.pixclock     = 96153,
-		.bpp          = 16,
-		.xres         = 240,
-		.yres         = 320,
-		.hsync_len    = 11,
-		.vsync_len    = 3,
-		.left_margin  = 19,
+		.pixclock = 96153,
+		.bpp	= 16,
+		.xres	= 240,
+		.yres	= 320,
+		.hsync_len = 11,
+		.vsync_len = 3,
+		.left_margin = 19,
 		.upper_margin = 2,
 		.right_margin = 10,
 		.lower_margin = 2,
-		.sync         = 0,
+		.sync	= 0,
 	},
 };
 
 static struct pxafb_mode_info samsung_modes[] = {
 	{
-		.pixclock     = 96153,
-		.bpp          = 16,
-		.xres         = 240,
-		.yres         = 320,
-		.hsync_len    = 8,
-		.vsync_len    = 4,
-		.left_margin  = 9,
+		.pixclock = 96153,
+		.bpp	= 16,
+		.xres	= 240,
+		.yres	= 320,
+		.hsync_len = 8,
+		.vsync_len = 4,
+		.left_margin = 9,
 		.upper_margin = 4,
 		.right_margin = 9,
 		.lower_margin = 4,
-		.sync         = FB_SYNC_HOR_HIGH_ACT | FB_SYNC_VERT_HIGH_ACT,
+		.sync	= FB_SYNC_HOR_HIGH_ACT | FB_SYNC_VERT_HIGH_ACT,
 	},
 };
 
 static void toppoly_lcd_power(int on, struct fb_var_screeninfo *si)
 {
-	pr_debug("Toppoly LCD power\n");
+	pr_debug("Toppoly LCD power: %s\n", on ? "on" : "off");
 
 	if (on) {
-		pr_debug("on\n");
 		gpio_set_value(EGPIO_MAGICIAN_TOPPOLY_POWER, 1);
-		gpio_set_value(GPIO106_MAGICIAN_LCD_POWER_3, 1);
+		gpio_set_value(GPIO106_MAGICIAN_LCD_DCDC_NRESET, 1);
 		udelay(2000);
 		gpio_set_value(EGPIO_MAGICIAN_LCD_POWER, 1);
 		udelay(2000);
 		/* FIXME: enable LCDC here */
 		udelay(2000);
-		gpio_set_value(GPIO104_MAGICIAN_LCD_POWER_1, 1);
+		gpio_set_value(GPIO104_MAGICIAN_LCD_VOFF_EN, 1);
 		udelay(2000);
-		gpio_set_value(GPIO105_MAGICIAN_LCD_POWER_2, 1);
+		gpio_set_value(GPIO105_MAGICIAN_LCD_VON_EN, 1);
 	} else {
-		pr_debug("off\n");
-		msleep(15);
-		gpio_set_value(GPIO105_MAGICIAN_LCD_POWER_2, 0);
+		mdelay(15);
+		gpio_set_value(GPIO105_MAGICIAN_LCD_VON_EN, 0);
 		udelay(500);
-		gpio_set_value(GPIO104_MAGICIAN_LCD_POWER_1, 0);
+		gpio_set_value(GPIO104_MAGICIAN_LCD_VOFF_EN, 0);
 		udelay(1000);
-		gpio_set_value(GPIO106_MAGICIAN_LCD_POWER_3, 0);
+		gpio_set_value(GPIO106_MAGICIAN_LCD_DCDC_NRESET, 0);
 		gpio_set_value(EGPIO_MAGICIAN_LCD_POWER, 0);
 	}
 }
 
 static void samsung_lcd_power(int on, struct fb_var_screeninfo *si)
 {
-	pr_debug("Samsung LCD power\n");
+	pr_debug("Samsung LCD power: %s\n", on ? "on" : "off");
 
 	if (on) {
-		pr_debug("on\n");
 		if (system_rev < 3)
 			gpio_set_value(GPIO75_MAGICIAN_SAMSUNG_POWER, 1);
 		else
 			gpio_set_value(EGPIO_MAGICIAN_LCD_POWER, 1);
-		mdelay(10);
-		gpio_set_value(GPIO106_MAGICIAN_LCD_POWER_3, 1);
-		mdelay(10);
-		gpio_set_value(GPIO104_MAGICIAN_LCD_POWER_1, 1);
-		mdelay(30);
-		gpio_set_value(GPIO105_MAGICIAN_LCD_POWER_2, 1);
-		mdelay(10);
+		mdelay(6);
+		gpio_set_value(GPIO106_MAGICIAN_LCD_DCDC_NRESET, 1);
+		mdelay(6);	/* Avdd -> Voff >5ms */
+		gpio_set_value(GPIO104_MAGICIAN_LCD_VOFF_EN, 1);
+		mdelay(16);	/* Voff -> Von >(5+10)ms */
+		gpio_set_value(GPIO105_MAGICIAN_LCD_VON_EN, 1);
 	} else {
-		pr_debug("off\n");
-		mdelay(10);
-		gpio_set_value(GPIO105_MAGICIAN_LCD_POWER_2, 0);
-		mdelay(30);
-		gpio_set_value(GPIO104_MAGICIAN_LCD_POWER_1, 0);
-		mdelay(10);
-		gpio_set_value(GPIO106_MAGICIAN_LCD_POWER_3, 0);
-		mdelay(10);
+		gpio_set_value(GPIO105_MAGICIAN_LCD_VON_EN, 0);
+		mdelay(16);
+		gpio_set_value(GPIO104_MAGICIAN_LCD_VOFF_EN, 0);
+		mdelay(6);
+		gpio_set_value(GPIO106_MAGICIAN_LCD_DCDC_NRESET, 0);
+		mdelay(6);
 		if (system_rev < 3)
 			gpio_set_value(GPIO75_MAGICIAN_SAMSUNG_POWER, 0);
 		else
@@ -326,19 +493,19 @@ static void samsung_lcd_power(int on, struct fb_var_screeninfo *si)
 }
 
 static struct pxafb_mach_info toppoly_info = {
-	.modes           = toppoly_modes,
-	.num_modes       = 1,
-	.fixed_modes     = 1,
-	.lcd_conn	= LCD_COLOR_TFT_16BPP,
+	.modes = toppoly_modes,
+	.num_modes = 1,
+	.fixed_modes = 1,
+	.lcd_conn = LCD_COLOR_TFT_16BPP,
 	.pxafb_lcd_power = toppoly_lcd_power,
 };
 
 static struct pxafb_mach_info samsung_info = {
-	.modes           = samsung_modes,
-	.num_modes       = 1,
-	.fixed_modes     = 1,
-	.lcd_conn	 = LCD_COLOR_TFT_16BPP | LCD_PCLK_EDGE_FALL |\
-			   LCD_ALTERNATE_MAPPING,
+	.modes = samsung_modes,
+	.num_modes = 1,
+	.fixed_modes = 1,
+	.lcd_conn = LCD_COLOR_TFT_16BPP | LCD_PCLK_EDGE_FALL |
+		LCD_ALTERNATE_MAPPING,
 	.pxafb_lcd_power = samsung_lcd_power,
 };
 
@@ -347,17 +514,22 @@ static struct pxafb_mach_info samsung_info = {
  */
 
 static struct gpio magician_bl_gpios[] = {
-	{ EGPIO_MAGICIAN_BL_POWER,  GPIOF_DIR_OUT, "Backlight power" },
-	{ EGPIO_MAGICIAN_BL_POWER2, GPIOF_DIR_OUT, "Backlight power 2" },
+	{ EGPIO_MAGICIAN_BL_POWER, GPIOF_DIR_OUT, "Backlight power" },
+	{ EGPIO_MAGICIAN_BL_POWER2, GPIOF_DIR_OUT, "Extra backlight power" },
 };
 
 static int magician_backlight_init(struct device *dev)
 {
-	return gpio_request_array(ARRAY_AND_SIZE(magician_bl_gpios));
+	int ret;
+
+	pr_debug("Backlight init\n");
+	ret = gpio_request_array(ARRAY_AND_SIZE(magician_bl_gpios));
+	return ret;
 }
 
 static int magician_backlight_notify(struct device *dev, int brightness)
 {
+	pr_debug("Brightness = %i\n", brightness);
 	gpio_set_value(EGPIO_MAGICIAN_BL_POWER, brightness);
 	if (brightness >= 200) {
 		gpio_set_value(EGPIO_MAGICIAN_BL_POWER2, 1);
@@ -373,28 +545,57 @@ static void magician_backlight_exit(struct device *dev)
 	gpio_free_array(ARRAY_AND_SIZE(magician_bl_gpios));
 }
 
-static struct platform_pwm_backlight_data backlight_data = {
-	.pwm_id         = 0,
+/*
+ * LCD backlight by PWM (main)
+ * PWM frequency for MP1521 should be:
+ *   100-400 Hz = 2?.5*10^6 - 10?*10^6 ns
+ */
+
+static struct platform_pwm_backlight_data pwm_backlight_data = {
+	.pwm_id = 0,
 	.max_brightness = 272,
 	.dft_brightness = 100,
-	.pwm_period_ns  = 30923,
-	.enable_gpio    = -1,
-	.init           = magician_backlight_init,
-	.notify         = magician_backlight_notify,
-	.exit           = magician_backlight_exit,
+	.pwm_period_ns = 30923,
+	.enable_gpio = -1,
+	.init = magician_backlight_init,
+	.notify = magician_backlight_notify,
+	.exit = magician_backlight_exit,
 };
 
-static struct platform_device backlight = {
+static struct platform_device pwm_backlight = {
 	.name = "pwm-backlight",
-	.id   = -1,
-	.dev  = {
-		.parent        = &pxa27x_device_pwm0.dev,
-		.platform_data = &backlight_data,
+	.id = -1,
+	.dev = {
+		.parent	= &pxa27x_device_pwm0.dev,
+		.platform_data = &pwm_backlight_data,
 	},
 };
 
+/* Backlight controlled by single GPIO (alternative) */
+static struct gpio_backlight_platform_data gpio_backlight_data = {
+/* .fbdev = &pxa_device_fb.dev, */
+	.gpio = EGPIO_MAGICIAN_BL_POWER,
+	.def_value = 1,
+	.name = "backlight",
+};
+
+static struct platform_device gpio_backlight = {
+	.name = "gpio-backlight",
+	.dev = {
+		.platform_data = &gpio_backlight_data,
+	},
+};
+
+/*
+ * fixed regulator for pwm_backlight
+ */
+
+static struct regulator_consumer_supply pwm_backlight_supply[] = {
+	REGULATOR_SUPPLY("power", "pwm_backlight"),
+};
+
 /*
- * LEDs
+ * Phone keys backlight, vibra
  */
 
 static struct gpio_led gpio_leds[] = {
@@ -417,76 +618,135 @@ static struct gpio_led_platform_data gpio_led_info = {
 
 static struct platform_device leds_gpio = {
 	.name = "leds-gpio",
-	.id   = -1,
-	.dev  = {
+	.id = -1,
+	.dev = {
 		.platform_data = &gpio_led_info,
 	},
 };
 
+/*
+ * SoC Camera
+ */
+
+static struct pxacamera_platform_data magician_pxacamera_pdata = {
+	.flags = PXA_CAMERA_MASTER | PXA_CAMERA_DATAWIDTH_8 |
+		PXA_CAMERA_PCLK_EN | PXA_CAMERA_MCLK_EN,
+	.mclk_10khz = 4800,
+};
+
+static int magician_camera_power(struct device *dev, int power)
+{
+	pr_debug("Camera power = %i\n", power);
+
+	gpio_set_value(GPIO116_MAGICIAN_nCAM_EN, !power);
+	mdelay(3);
+
+	return 0;
+}
+
+static int magician_camera_reset(struct device *dev)
+{
+	pr_debug("Camera reset\n");
+
+	gpio_set_value(GPIO57_MAGICIAN_CAM_RESET, 1);
+	mdelay(3);
+	gpio_set_value(GPIO57_MAGICIAN_CAM_RESET, 0);
+	mdelay(3);
+
+	return 0;
+}
+
+static struct i2c_board_info magician_camera_i2c_board_info = {
+	I2C_BOARD_INFO("ov9640", 0x30),
+	.flags = I2C_CLIENT_SCCB,
+};
+
+static struct soc_camera_link magician_camera_iclink = {
+	.bus_id			= 0,
+	.flags			= SOCAM_DATAWIDTH_8,
+	.i2c_adapter_id	= 0,
+	.board_info		= &magician_camera_i2c_board_info,
+	.power		= magician_camera_power,
+	.reset		= magician_camera_reset,
+};
+
+static struct platform_device magician_camera = {
+	.name = "soc-camera-pdrv",
+	.id = 0,
+	.dev = {
+		.platform_data = &magician_camera_iclink,
+	},
+};
+
+/*
+ * PASIC3: DS1WM, LEDs, sysreset
+ */
+
 static struct pasic3_led pasic3_leds[] = {
 	{
-		.led = {
-			.name            = "magician:red",
+		.cdev = {
+			.name = "magician:red",
 			.default_trigger = "ds2760-battery.0-charging",
 		},
 		.hw_num = 0,
-		.bit2   = PASIC3_BIT2_LED0,
-		.mask   = PASIC3_MASK_LED0,
+		.bit_blink_en	= R06_CH0_EN,
+		.bit_force_on	= R06_CH0_FORCE_ON,
+		.bit_mask		= MASK_CH0,
+		.reg_delay_on	= PASIC3_CH0_DELAY_ON,
+		.reg_delay_off	= PASIC3_CH0_DELAY_OFF,
 	},
 	{
-		.led = {
-			.name            = "magician:green",
+		.cdev = {
+			.name = "magician:green",
 			.default_trigger = "ds2760-battery.0-charging-or-full",
 		},
 		.hw_num = 1,
-		.bit2   = PASIC3_BIT2_LED1,
-		.mask   = PASIC3_MASK_LED1,
+		.bit_blink_en	= R06_CH1_EN,
+		.bit_force_on	= R06_CH1_FORCE_ON,
+		.bit_mask		= MASK_CH1,
+		.reg_delay_on	= PASIC3_CH1_DELAY_ON,
+		.reg_delay_off	= PASIC3_CH1_DELAY_OFF,
 	},
 	{
-		.led = {
-			.name            = "magician:blue",
+		.cdev = {
+			.name = "magician:blue",
 			.default_trigger = "bluetooth",
 		},
 		.hw_num = 2,
-		.bit2   = PASIC3_BIT2_LED2,
-		.mask   = PASIC3_MASK_LED2,
+		.bit_blink_en	= R06_CH2_EN,
+		.bit_force_on	= R06_CH2_FORCE_ON,
+		.bit_mask		= MASK_CH2,
+		.reg_delay_on	= PASIC3_CH2_DELAY_ON,
+		.reg_delay_off	= PASIC3_CH2_DELAY_OFF,
 	},
 };
 
-static struct pasic3_leds_machinfo pasic3_leds_info = {
-	.num_leds   = ARRAY_SIZE(pasic3_leds),
-	.power_gpio = EGPIO_MAGICIAN_LED_POWER,
-	.leds       = pasic3_leds,
-};
-
-/*
- * PASIC3 with DS1WM
- */
-
 static struct resource pasic3_resources[] = {
 	[0] = {
-		.start  = PXA_CS2_PHYS,
-		.end	= PXA_CS2_PHYS + 0x1b,
-		.flags  = IORESOURCE_MEM,
+		.start = PXA_CS2_PHYS,
+		.end = PXA_CS2_PHYS + 0x1b,
+		.flags = IORESOURCE_MEM,
 	},
 	/* No IRQ handler in the PASIC3, DS1WM needs an external IRQ */
 	[1] = {
-		.start  = PXA_GPIO_TO_IRQ(GPIO107_MAGICIAN_DS1WM_IRQ),
-		.end    = PXA_GPIO_TO_IRQ(GPIO107_MAGICIAN_DS1WM_IRQ),
-		.flags  = IORESOURCE_IRQ | IORESOURCE_IRQ_HIGHEDGE,
+		.start = PXA_GPIO_TO_IRQ(GPIO107_MAGICIAN_DS1WM_IRQ),
+		.end = PXA_GPIO_TO_IRQ(GPIO107_MAGICIAN_DS1WM_IRQ),
+		.flags = IORESOURCE_IRQ | IORESOURCE_IRQ_HIGHEDGE,
 	}
 };
 
 static struct pasic3_platform_data pasic3_platform_data = {
-	.led_pdata  = &pasic3_leds_info,
+	.power_gpio = EGPIO_MAGICIAN_LED_POWER, /* Green LED doesn't use it */
+	.leds = pasic3_leds,
+	.num_leds = ARRAY_SIZE(pasic3_leds),
 	.clock_rate = 4000000,
 };
 
 static struct platform_device pasic3 = {
-	.name		= "pasic3",
+	.name	= "pasic3",
 	.id		= -1,
 	.num_resources	= ARRAY_SIZE(pasic3_resources),
-	.resource	= pasic3_resources,
+	.resource		= pasic3_resources,
 	.dev = {
 		.platform_data = &pasic3_platform_data,
 	},
@@ -496,87 +756,183 @@ static struct platform_device pasic3 = {
  * USB "Transceiver"
  */
 
+#if IS_ENABLED(CONFIG_USB_PXA27X)
+static void magician_udc_command(int cmd)
+{
+	if (cmd == PXA2XX_UDC_CMD_CONNECT)
+		UP2OCR |= UP2OCR_DPPUE | UP2OCR_DPPUBE;
+	else if (cmd == PXA2XX_UDC_CMD_DISCONNECT)
+		UP2OCR &= ~(UP2OCR_DPPUE | UP2OCR_DPPUBE);
+}
+
+/* HACK, shared USB connected state with pda-power */
+int my_usb_online = 1;
+
+static int magician_udc_is_connected(void)
+{
+	/* Shared with pda_power or gpio-vbus */
+	return my_usb_online;
+}
+
+static struct pxa2xx_udc_mach_info magician_udc_info __initdata = {
+	.udc_command	= magician_udc_command,
+	.udc_is_connected = magician_udc_is_connected,
+	.gpio_pullup	= GPIO27_MAGICIAN_USBC_PUEN,
+};
+
+#else
+
+/* GPIO USB client vbus sensing, when no PXA UDC installed */
+
 static struct resource gpio_vbus_resource = {
 	.flags = IORESOURCE_IRQ,
 	.start = IRQ_MAGICIAN_VBUS,
-	.end   = IRQ_MAGICIAN_VBUS,
+	.end = IRQ_MAGICIAN_VBUS,
 };
 
 static struct gpio_vbus_mach_info gpio_vbus_info = {
 	.gpio_pullup = GPIO27_MAGICIAN_USBC_PUEN,
-	.gpio_vbus   = EGPIO_MAGICIAN_CABLE_STATE_USB,
+	.gpio_vbus = EGPIO_MAGICIAN_CABLE_INSERT1,
 };
 
 static struct platform_device gpio_vbus = {
-	.name          = "gpio-vbus",
-	.id            = -1,
+	.name = "gpio-vbus",
+	.id = -1,
 	.num_resources = 1,
-	.resource      = &gpio_vbus_resource,
+	.resource = &gpio_vbus_resource,
 	.dev = {
 		.platform_data = &gpio_vbus_info,
 	},
 };
+#endif	/* IS_ENABLED(CONFIG_USB_PXA27X) */
 
 /*
- * External power
+ * Charging functions
  */
 
-static int power_supply_init(struct device *dev)
+static int magician_supply_init(struct device *dev)
 {
-	return gpio_request(EGPIO_MAGICIAN_CABLE_STATE_AC, "CABLE_STATE_AC");
+	int ret = -1;
+
+	ret = gpio_request(EGPIO_MAGICIAN_CABLE_TYPE, "AC charger in USB");
+	if (ret) {
+		pr_err("Cannot request AC/USB charger GPIO (%i)\n", ret);
+		goto err_ac;
+	}
+
+	ret = gpio_request(EGPIO_MAGICIAN_CABLE_INSERT1, "Cable inserted");
+	if (ret) {
+		pr_err("Cannot request cable detection GPIO (%i)\n", ret);
+		goto err_usb;
+	}
+
+	return 0;
+
+err_usb:
+	gpio_free(EGPIO_MAGICIAN_CABLE_TYPE);
+err_ac:
+	return ret;
+}
+
+static void magician_set_charge(int flags)
+{
+	/* EGPIO_MAGICIAN_BQ24022_ISET2: =1 500mA, =0 100mA
+	 *
+	 * RTC NiCd voltage can be read from ADS7846
+	 * in0_input=1930, when =0 (after =1 its going up)
+	 * in0_input=1367, when =1
+	 * in0_input=2499, always (without NiCd)
+	 *
+	 * FIXME Will disabled NiCd slow accu discharge?
+	 *
+	 * Charging from USB can be 500mA too
+	 * NOTICE: IrDA=on, Vcore=1V, Fcore=104MHz, everything other=off
+	 *   -> power consumption still over 100mA
+	 */
+
+	if (flags & PDA_POWER_CHARGE_AC) {
+		pr_debug("Charging from AC\n");
+		gpio_set_value(EGPIO_MAGICIAN_NICD_CHARGE, 1);
+	} else if (flags & PDA_POWER_CHARGE_USB) {
+		pr_debug("Charging from USB\n");
+		gpio_set_value(EGPIO_MAGICIAN_NICD_CHARGE, 1);
+	} else {
+		pr_debug("Charging disabled\n");
+		gpio_set_value(EGPIO_MAGICIAN_NICD_CHARGE, 0);
+	}
+
+	gpio_set_value(EGPIO_MAGICIAN_NICD_CHARGE, 1);
 }
 
 static int magician_is_ac_online(void)
 {
-	return gpio_get_value(EGPIO_MAGICIAN_CABLE_STATE_AC);
+	return gpio_get_value(EGPIO_MAGICIAN_CABLE_INSERT1) &&
+		gpio_get_value(EGPIO_MAGICIAN_CABLE_TYPE); /* AC=1 */
+}
+
+static int magician_is_usb_online(void)
+{
+	my_usb_online = gpio_get_value(EGPIO_MAGICIAN_CABLE_INSERT1) &&
+		(!gpio_get_value(EGPIO_MAGICIAN_CABLE_TYPE)); /* USB=0 */
+	return my_usb_online;
 }
 
-static void power_supply_exit(struct device *dev)
+static void magician_supply_exit(struct device *dev)
 {
-	gpio_free(EGPIO_MAGICIAN_CABLE_STATE_AC);
+	/* HACK FIXME EGPIO pin is used with two drivers */
+	my_usb_online = 1;
+
+	gpio_free(EGPIO_MAGICIAN_CABLE_INSERT1);
+	gpio_free(EGPIO_MAGICIAN_CABLE_TYPE);
 }
 
 static char *magician_supplicants[] = {
 	"ds2760-battery.0", "backup-battery"
 };
 
+/*
+ * pda_power Li-ion charger
+ */
+
 static struct pda_power_pdata power_supply_info = {
-	.init            = power_supply_init,
-	.is_ac_online    = magician_is_ac_online,
-	.exit            = power_supply_exit,
-	.supplied_to     = magician_supplicants,
+	.init = magician_supply_init,
+	.exit = magician_supply_exit,
+	.is_ac_online = magician_is_ac_online,
+	.is_usb_online = magician_is_usb_online,
+	.set_charge = magician_set_charge,
+	.supplied_to = magician_supplicants,
 	.num_supplicants = ARRAY_SIZE(magician_supplicants),
 };
 
 static struct resource power_supply_resources[] = {
 	[0] = {
-		.name  = "ac",
+		.name = "ac",
 		.flags = IORESOURCE_IRQ | IORESOURCE_IRQ_HIGHEDGE |
-		         IORESOURCE_IRQ_LOWEDGE,
+			IORESOURCE_IRQ_LOWEDGE,
 		.start = IRQ_MAGICIAN_VBUS,
-		.end   = IRQ_MAGICIAN_VBUS,
+		.end = IRQ_MAGICIAN_VBUS,
 	},
 	[1] = {
-		.name  = "usb",
+		.name = "usb",
 		.flags = IORESOURCE_IRQ | IORESOURCE_IRQ_HIGHEDGE |
-		         IORESOURCE_IRQ_LOWEDGE,
+			IORESOURCE_IRQ_LOWEDGE,
 		.start = IRQ_MAGICIAN_VBUS,
-		.end   = IRQ_MAGICIAN_VBUS,
+		.end = IRQ_MAGICIAN_VBUS,
 	},
 };
 
 static struct platform_device power_supply = {
 	.name = "pda-power",
-	.id   = -1,
-	.dev  = {
+	.id = -1,
+	.dev = {
 		.platform_data = &power_supply_info,
 	},
-	.resource      = power_supply_resources,
+	.resource = power_supply_resources,
 	.num_resources = ARRAY_SIZE(power_supply_resources),
 };
 
 /*
- * Battery charger
+ * Charging current switcher
  */
 
 static struct regulator_consumer_supply bq24022_consumers[] = {
@@ -586,11 +942,12 @@ static struct regulator_consumer_supply bq24022_consumers[] = {
 
 static struct regulator_init_data bq24022_init_data = {
 	.constraints = {
-		.max_uA         = 500000,
-		.valid_ops_mask = REGULATOR_CHANGE_CURRENT | REGULATOR_CHANGE_STATUS,
+		.max_uA = 500000,
+		.valid_ops_mask =
+			REGULATOR_CHANGE_CURRENT | REGULATOR_CHANGE_STATUS,
 	},
-	.num_consumer_supplies  = ARRAY_SIZE(bq24022_consumers),
-	.consumer_supplies      = bq24022_consumers,
+	.num_consumer_supplies = ARRAY_SIZE(bq24022_consumers),
+	.consumer_supplies = bq24022_consumers,
 };
 
 static struct gpio bq24022_gpios[] = {
@@ -607,7 +964,7 @@ static struct gpio_regulator_config bq24022_info = {
 
 	.enable_gpio = GPIO30_MAGICIAN_BQ24022_nCHARGE_EN,
 	.enable_high = 0,
-	.enabled_at_boot = 0,
+	.enabled_at_boot = 1,
 
 	.gpios = bq24022_gpios,
 	.nr_gpios = ARRAY_SIZE(bq24022_gpios),
@@ -621,21 +978,98 @@ static struct gpio_regulator_config bq24022_info = {
 
 static struct platform_device bq24022 = {
 	.name = "gpio-regulator",
-	.id   = -1,
-	.dev  = {
+	.id = 2,
+	.dev = {
 		.platform_data = &bq24022_info,
 	},
 };
 
 /*
+ * fixed regulator for ads7846
+ */
+
+static struct regulator_consumer_supply ads7846_supply =
+	REGULATOR_SUPPLY("vcc", "spi2.0");
+
+static struct regulator_init_data vads7846_regulator = {
+	.constraints = {
+		.valid_ops_mask	= REGULATOR_CHANGE_STATUS,
+	},
+	.num_consumer_supplies = 1,
+	.consumer_supplies = &ads7846_supply,
+};
+
+static struct fixed_voltage_config vads7846 = {
+	.supply_name = "vads7846",
+	.microvolts = 3300000, /* probably */
+	.gpio = -EINVAL,
+	.startup_delay = 0,
+	.init_data = &vads7846_regulator,
+};
+
+static struct platform_device vads7846_device = {
+	.name = "reg-fixed-voltage",
+	.id = 1,
+	.dev = {
+		.platform_data = &vads7846,
+	},
+};
+
+/*
+ * Vcore regulator MAX1587A
+ */
+
+static struct regulator_consumer_supply magician_max1587a_consumers[] = {
+	REGULATOR_SUPPLY("vcc_core", NULL),
+};
+
+static struct regulator_init_data magician_max1587a_v3_info = {
+	.constraints = {
+		.name		= "vcc_core range",
+		.min_uV		= 700000,
+		.max_uV		= 1500000,
+		.always_on	= 1,
+		.valid_ops_mask	= REGULATOR_CHANGE_VOLTAGE,
+	},
+	.consumer_supplies	= magician_max1587a_consumers,
+	.num_consumer_supplies	= ARRAY_SIZE(magician_max1587a_consumers),
+};
+
+static struct max1586_subdev_data magician_max1587a_subdevs[] = {
+	{
+		.name		= "vcc_core",
+		.id		= MAX1586_V3,
+		.platform_data	= &magician_max1587a_v3_info,
+	}
+};
+
+static struct max1586_platform_data magician_max1587a_info = {
+	.subdevs     = magician_max1587a_subdevs,
+	.num_subdevs = ARRAY_SIZE(magician_max1587a_subdevs),
+	/*
+	 * NOTICE measured directly on the PCB (board_id == 0x3a), but
+	 * if R24 is present, it will boost the voltage
+	 * (write 1.475V, get 1.645V and smoke)
+	 */
+	.v3_gain     = MAX1586_GAIN_NO_R24,
+};
+
+static struct i2c_board_info magician_pwr_i2c_board_info[] __initdata = {
+	{
+		I2C_BOARD_INFO("max1586", 0x14),
+		.platform_data	= &magician_max1587a_info,
+	},
+};
+
+/*
  * MMC/SD
  */
 
 static int magician_mci_init(struct device *dev,
-				irq_handler_t detect_irq, void *data)
+	irq_handler_t detect_irq, void *data)
 {
 	return request_irq(IRQ_MAGICIAN_SD, detect_irq, 0,
-			   "mmc card detect", data);
+		"mmc card detect", data);
 }
 
 static void magician_mci_exit(struct device *dev, void *data)
@@ -644,15 +1078,40 @@ static void magician_mci_exit(struct device *dev, void *data)
 }
 
 static struct pxamci_platform_data magician_mci_info = {
-	.ocr_mask 		= MMC_VDD_32_33|MMC_VDD_33_34,
-	.init     		= magician_mci_init,
-	.exit     		= magician_mci_exit,
+	.ocr_mask		= MMC_VDD_32_33|MMC_VDD_33_34,
+	.init			= magician_mci_init,
+	.exit			= magician_mci_exit,
 	.gpio_card_detect	= -1,
 	.gpio_card_ro		= EGPIO_MAGICIAN_nSD_READONLY,
 	.gpio_card_ro_invert	= 1,
 	.gpio_power		= EGPIO_MAGICIAN_SD_POWER,
 };
 
+/*
+ * AUDIO codec UDA1380
+ */
+
+static struct uda1380_platform_data uda1380_info = {
+	.gpio_power = EGPIO_MAGICIAN_CODEC_POWER,
+	.gpio_reset = EGPIO_MAGICIAN_CODEC_RESET,
+	.dac_clk = UDA1380_DAC_CLK_WSPLL,
+};
+
+static struct i2c_board_info magician_audio_i2c_devices[] = {
+	{
+		I2C_BOARD_INFO("uda1380", 0x18),
+		.platform_data = &uda1380_info,
+	},
+};
+
+/*
+ * Magician Audio controller
+ */
+
+static struct platform_device magician_audio_device = {
+	.name = "magician-audio",
+	.id = -1,
+};
 
 /*
  * USB OHCI
@@ -660,47 +1119,257 @@ static struct pxamci_platform_data magician_mci_info = {
 
 static struct pxaohci_platform_data magician_ohci_info = {
 	.port_mode	= PMM_PERPORT_MODE,
-	.flags		= ENABLE_PORT1 | ENABLE_PORT3 | POWER_CONTROL_LOW,
+	/* port1: CSR Bluetooth, port2: OTG with UDC */
+	.flags		= ENABLE_PORT1 | ENABLE_PORT2 | POWER_CONTROL_LOW,
 	.power_budget	= 0,
+	.power_on_delay = 100,
 };
 
-
 /*
  * StrataFlash
  */
 
+static int magician_flash_init(struct platform_device *pdev)
+{
+	int ret = gpio_request(EGPIO_MAGICIAN_FLASH_VPP, "flash Vpp enable");
+
+	if (ret) {
+		pr_err("Cannot request flash enable GPIO (%i)\n", ret);
+		return ret;
+	}
+
+	ret = gpio_direction_output(EGPIO_MAGICIAN_FLASH_VPP, 1);
+	if (ret) {
+		pr_err("Cannot set direction for flash enable (%i)\n", ret);
+		gpio_free(EGPIO_MAGICIAN_FLASH_VPP);
+	}
+
+	return ret;
+}
+
 static void magician_set_vpp(struct platform_device *pdev, int vpp)
 {
 	gpio_set_value(EGPIO_MAGICIAN_FLASH_VPP, vpp);
 }
 
+static void magician_flash_exit(struct platform_device *pdev)
+{
+	gpio_free(EGPIO_MAGICIAN_FLASH_VPP);
+}
+
 static struct resource strataflash_resource = {
 	.start = PXA_CS0_PHYS,
-	.end   = PXA_CS0_PHYS + SZ_64M - 1,
+	.end = PXA_CS0_PHYS + SZ_64M - 1,
 	.flags = IORESOURCE_MEM,
 };
 
+static struct mtd_partition magician_flash_parts[] = {
+	{
+		.name = "Bootloader",	/*htc or will uboot?*/
+		.offset = 0x0,
+		.size = 0x40000,
+		.mask_flags = MTD_WRITEABLE,	/* EXPERIMENTAL */
+	},
+	{
+		.name = "Linux Kernel",	/*wince or linux?*/
+		.offset = 0x40000,
+		.size = MTDPART_SIZ_FULL,
+	},
+};
+
+#if 1
+/*
+ * physmap-flash driver
+ */
+
 static struct physmap_flash_data strataflash_data = {
 	.width = 4,
+	.init = magician_flash_init,
 	.set_vpp = magician_set_vpp,
+	.exit = magician_flash_exit,
+	.parts = magician_flash_parts,
+	.nr_parts = ARRAY_SIZE(magician_flash_parts),
 };
 
 static struct platform_device strataflash = {
-	.name          = "physmap-flash",
-	.id            = -1,
-	.resource      = &strataflash_resource,
+	.name = "physmap-flash",
+	.id = -1,
+	.resource = &strataflash_resource,
 	.num_resources = 1,
 	.dev = {
 		.platform_data = &strataflash_data,
 	},
 };
 
+#else
+
 /*
- * I2C
+ * pxa2xx-flash driver
+ */
+
+static struct flash_platform_data magician_flash_data = {
+	.map_name = "cfi_probe",
+	.parts = magician_flash_parts,
+	.nr_parts = ARRAY_SIZE(magician_flash_parts),
+	.width = 2,
+};
+
+static struct platform_device strataflash = {
+	.name = "pxa2xx-flash",
+	.id = -1,
+	.dev = {
+		.platform_data = &magician_flash_data,
+	},
+	.resource = &strataflash_resource,
+	.num_resources = 1,
+};
+#endif
+
+/*
+ * PXA I2C normal controller (main)
  */
 
 static struct i2c_pxa_platform_data i2c_info = {
-	.fast_mode = 1,
+	.fast_mode = 0,	/* fast mode seems to be have bit errors */
+	.use_pio = 0, /* no polling */
+};
+
+/*
+ * PXA I2C power controller
+ */
+
+static struct i2c_pxa_platform_data magician_i2c_power_info = {
+	.fast_mode = 0,
+	.use_pio = 0,
+};
+
+/*
+ * GPIO I2C normal controller (alternative)
+ */
+
+static struct i2c_gpio_platform_data rtc_device_data = {
+	.sda_pin = GPIO118_MAGICIAN_I2C_SDA,
+	.scl_pin = GPIO117_MAGICIAN_I2C_SCL,
+	.udelay = 100
+};
+
+static struct platform_device i2c_gpio_bus_alt = {
+	.name = "i2c-gpio",
+	.id = 0,
+	.dev = {
+		.platform_data = &rtc_device_data,
+	}
+};
+
+/* HID should be configurable through configfs */
+#if 0
+/* hid descriptor for a keyboard */
+static struct hidg_func_descriptor my_hid_data = {
+	.subclass		= 0, /* No subclass */
+	.protocol		= 1, /* Keyboard */
+	.report_length		= 8,
+	.report_desc_length	= 63,
+	.report_desc		= {
+		0x05, 0x01,	/* USAGE_PAGE (Generic Desktop) */
+		0x09, 0x06,	/* USAGE (Keyboard) */
+		0xa1, 0x01,	/* COLLECTION (Application) */
+		0x05, 0x07,	/* USAGE_PAGE (Keyboard) */
+		0x19, 0xe0,	/* USAGE_MINIMUM (Keyboard LeftControl) */
+		0x29, 0xe7,	/* USAGE_MAXIMUM (Keyboard Right GUI) */
+		0x15, 0x00,	/* LOGICAL_MINIMUM (0) */
+		0x25, 0x01,	/* LOGICAL_MAXIMUM (1) */
+		0x75, 0x01,	/* REPORT_SIZE (1) */
+		0x95, 0x08,	/* REPORT_COUNT (8) */
+		0x81, 0x02,	/* INPUT (Data,Var,Abs) */
+		0x95, 0x01,	/* REPORT_COUNT (1) */
+		0x75, 0x08,	/* REPORT_SIZE (8) */
+		0x81, 0x03,	/* INPUT (Cnst,Var,Abs) */
+		0x95, 0x05,	/* REPORT_COUNT (5) */
+		0x75, 0x01,	/* REPORT_SIZE (1) */
+		0x05, 0x08,	/* USAGE_PAGE (LEDs) */
+		0x19, 0x01,	/* USAGE_MINIMUM (Num Lock) */
+		0x29, 0x05,	/* USAGE_MAXIMUM (Kana) */
+		0x91, 0x02,	/* OUTPUT (Data,Var,Abs) */
+		0x95, 0x01,	/* REPORT_COUNT (1) */
+		0x75, 0x03,	/* REPORT_SIZE (3) */
+		0x91, 0x03,	/* OUTPUT (Cnst,Var,Abs) */
+		0x95, 0x06,	/* REPORT_COUNT (6) */
+		0x75, 0x08,	/* REPORT_SIZE (8) */
+		0x15, 0x00,	/* LOGICAL_MINIMUM (0) */
+		0x25, 0x65,	/* LOGICAL_MAXIMUM (101) */
+		0x05, 0x07,	/* USAGE_PAGE (Keyboard) */
+		0x19, 0x00,	/* USAGE_MINIMUM (Reserved) */
+		0x29, 0x65,	/* USAGE_MAXIMUM (Keyboard Application) */
+		0x81, 0x00,	/* INPUT (Data,Ary,Abs) */
+		0xc0		/* END_COLLECTION */
+	}
+};
+
+static struct platform_device my_hid = {
+	.name	= "hidg",
+	.id		= 0,
+	.num_resources		= 0,
+	.resource			= 0,
+	.dev.platform_data	= &my_hid_data,
+};
+#endif
+
+static struct ads7846_platform_data ads7846_pdata = {
+	.model	= 7846,
+	.x_min		= 0,
+	.y_min		= 0,
+	.x_max		= 4096,
+	.y_max		= 4096,
+	.x_plate_ohms	= 320,	/* measured */
+	.y_plate_ohms	= 500,
+	.pressure_max	= 255,	/* up to 12bit sampling */
+	.debounce_max	= 10,
+	.debounce_tol	= 3,
+	.debounce_rep	= 1,
+	.gpio_pendown	= GPIO115_MAGICIAN_nPEN_IRQ,
+	.keep_vref_on	= 1,	/* FIXME, external Vref? */
+	.vref_delay_usecs = 100,
+	/* .wait_for_sync, GPIO77_LCD_BIAS low noise measure, latency! */
+};
+
+struct pxa2xx_spi_chip tsc2046_chip_info = {
+	.tx_threshold = 1,
+	.rx_threshold = 2,
+	.timeout = 64,
+	.gpio_cs = -1,
+};
+
+static struct pxa2xx_spi_master magician_spi_info = {
+	.num_chipselect = 1,
+/*	.enable_dma = 1, */ /* FIXME probably unnecessary */
+};
+
+static struct spi_board_info ads7846_spi_board_info[] __initdata = {
+	{
+		.modalias		= "ads7846",
+		.bus_num		= 2,
+		.max_speed_hz	= 1857143,
+		.platform_data	= &ads7846_pdata,
+		.controller_data	= &tsc2046_chip_info,
+		.irq	= PXA_GPIO_TO_IRQ(GPIO115_MAGICIAN_nPEN_IRQ),
+	},
+};
+
+/*
+ * Global GPIOs
+ */
+
+static struct gpio magician_global_gpios[] = {
+	{ GPIO13_MAGICIAN_CPLD_IRQ, GPIOF_IN, "CPLD_IRQ" },
+	{ GPIO107_MAGICIAN_DS1WM_IRQ, GPIOF_IN, "DS1WM_IRQ" },
+
+	/* NOTICE valid LCD init sequence */
+	{ GPIO106_MAGICIAN_LCD_DCDC_NRESET, GPIOF_OUT_INIT_HIGH,
+		"LCD DCDC nreset" },
+	{ GPIO104_MAGICIAN_LCD_VOFF_EN, GPIOF_OUT_INIT_HIGH,
+		"LCD VOFF enable" },
+	{ GPIO105_MAGICIAN_LCD_VON_EN, GPIOF_OUT_INIT_HIGH,
+		"LCD VON enable" },
 };
 
 /*
@@ -708,24 +1377,35 @@ static struct i2c_pxa_platform_data i2c_info = {
  */
 
 static struct platform_device *devices[] __initdata = {
-	&gpio_keys,
 	&egpio,
-	&backlight,
 	&pasic3,
-	&bq24022,
-	&gpio_vbus,
-	&power_supply,
+	&gpio_keys,
+	&magician_camera,
+	&vads7846_device,
 	&strataflash,
 	&leds_gpio,
-};
+	&magician_audio_device,
 
-static struct gpio magician_global_gpios[] = {
-	{ GPIO13_MAGICIAN_CPLD_IRQ,   GPIOF_IN, "CPLD_IRQ" },
-	{ GPIO107_MAGICIAN_DS1WM_IRQ, GPIOF_IN, "DS1WM_IRQ" },
-	{ GPIO104_MAGICIAN_LCD_POWER_1, GPIOF_OUT_INIT_LOW, "LCD power 1" },
-	{ GPIO105_MAGICIAN_LCD_POWER_2, GPIOF_OUT_INIT_LOW, "LCD power 2" },
-	{ GPIO106_MAGICIAN_LCD_POWER_3, GPIOF_OUT_INIT_LOW, "LCD power 3" },
-	{ GPIO83_MAGICIAN_nIR_EN, GPIOF_OUT_INIT_HIGH, "nIR_EN" },
+	/* NOTICE mutually exclusive */
+	&power_supply,
+	&bq24022,
+
+	/* NOTICE mutually exclusive with UDC*/
+#if !(IS_ENABLED(CONFIG_USB_PXA27X))
+	&gpio_vbus,
+#endif
+
+	/* NOTICE mutually exclusive with PXA I2C */
+	&i2c_gpio_bus_alt,
+
+	/* NOTICE mutually exclusive */
+	&pwm_backlight,
+	&gpio_backlight,
+
+	&lirc_gpio,
+#if 0
+	&my_hid,	/* HID should be configurable through configfs */
+#endif
 };
 
 static void __init magician_init(void)
@@ -735,21 +1415,27 @@ static void __init magician_init(void)
 	int err;
 
 	pxa2xx_mfp_config(ARRAY_AND_SIZE(magician_pin_config));
+
 	err = gpio_request_array(ARRAY_AND_SIZE(magician_global_gpios));
 	if (err)
-		pr_err("magician: Failed to request GPIOs: %d\n", err);
+		pr_err("magician: Failed to request global GPIOs: %d\n", err);
 
 	pxa_set_ffuart_info(NULL);
 	pxa_set_btuart_info(NULL);
 	pxa_set_stuart_info(NULL);
-
-	platform_add_devices(ARRAY_AND_SIZE(devices));
-
 	pxa_set_ficp_info(&magician_ficp_info);
-	pxa27x_set_i2c_power_info(NULL);
+
+	pxa27x_set_i2c_power_info(&magician_i2c_power_info);
 	pxa_set_i2c_info(&i2c_info);
+
+	i2c_register_board_info(0,
+		ARRAY_AND_SIZE(magician_audio_i2c_devices));
+	i2c_register_board_info(1,
+		ARRAY_AND_SIZE(magician_pwr_i2c_board_info));
+
 	pxa_set_mci_info(&magician_mci_info);
 	pxa_set_ohci_info(&magician_ohci_info);
+	pxa_set_udc_info(&magician_udc_info);
 
 	/* Check LCD type we have */
 	cpld = ioremap_nocache(PXA_CS3_PHYS, 0x1000);
@@ -758,15 +1444,29 @@ static void __init magician_init(void)
 		iounmap(cpld);
 		system_rev = board_id & 0x7;
 		lcd_select = board_id & 0x8;
-		pr_info("LCD type: %s\n", lcd_select ? "Samsung" : "Toppoly");
+		pr_info("LCD type: %s, board type: 0x%02x\n",
+			lcd_select ? "Samsung" : "Toppoly",
+			board_id);
+
 		if (lcd_select && (system_rev < 3))
+			/* NOTICE valid LCD init sequence */
 			gpio_request_one(GPIO75_MAGICIAN_SAMSUNG_POWER,
-			                 GPIOF_OUT_INIT_LOW, "SAMSUNG_POWER");
+				GPIOF_OUT_INIT_HIGH, "LCD Samsung Power");
+
 		pxa_set_fb_info(NULL, lcd_select ? &samsung_info : &toppoly_info);
 	} else
 		pr_err("LCD detection: CPLD mapping failed\n");
-}
 
+	pxa2xx_set_spi_info(2, &magician_spi_info);
+	spi_register_board_info(ARRAY_AND_SIZE(ads7846_spi_board_info));
+
+	pxa_set_camera_info(&magician_pxacamera_pdata);
+
+	regulator_register_always_on(0, "power", pwm_backlight_supply,
+		ARRAY_SIZE(pwm_backlight_supply), 5000000);
+
+	platform_add_devices(ARRAY_AND_SIZE(devices));
+}
 
 MACHINE_START(MAGICIAN, "HTC Magician")
 	.atag_offset = 0x100,
diff --git a/drivers/leds/Kconfig b/drivers/leds/Kconfig
index 9ad35f7..516ba65 100644
--- a/drivers/leds/Kconfig
+++ b/drivers/leds/Kconfig
@@ -586,6 +586,15 @@ config LEDS_PM8941_WLED
 	  This option enables support for the 'White' LED block
 	  on Qualcomm PM8941 PMICs.
 
+config LEDS_PASIC3
+	tristate "LED support for the HTC Magician/Alpine PASIC3"
+	depends on LEDS_CLASS
+	depends on HTC_PASIC3
+	select REGMAP
+	help
+	  This option enables support for the PASIC3 chip (different chip
+	  than Compaq ASIC3).
+
 comment "LED Triggers"
 source "drivers/leds/trigger/Kconfig"
 
diff --git a/drivers/leds/Makefile b/drivers/leds/Makefile
index 8d6a24a..b1c659c 100644
--- a/drivers/leds/Makefile
+++ b/drivers/leds/Makefile
@@ -65,6 +65,7 @@ obj-$(CONFIG_LEDS_VERSATILE)		+= leds-versatile.o
 obj-$(CONFIG_LEDS_MENF21BMC)		+= leds-menf21bmc.o
 obj-$(CONFIG_LEDS_PM8941_WLED)		+= leds-pm8941-wled.o
 obj-$(CONFIG_LEDS_KTD2692)		+= leds-ktd2692.o
+obj-$(CONFIG_LEDS_PASIC3)		+= leds-pasic3.o
 
 # LED SPI Drivers
 obj-$(CONFIG_LEDS_DAC124S085)		+= leds-dac124s085.o
diff --git a/drivers/leds/leds-pasic3.c b/drivers/leds/leds-pasic3.c
new file mode 100644
index 0000000..ecb0557
--- /dev/null
+++ b/drivers/leds/leds-pasic3.c
@@ -0,0 +1,192 @@
+/*
+ * AIC3 (or PASIC3) LED driver for HTC Magician/Alpine/.. (not Compaq ASIC3)
+ *
+ * Copyright (c) 2015 Petr Cvek <petr.cvek at tul.cz>
+ *
+ * Based on leds-asic3.c driver
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License version 2 as
+ * published by the Free Software Foundation.
+ *
+ */
+
+#include <linux/kernel.h>
+#include <linux/platform_device.h>
+#include <linux/leds.h>
+#include <linux/slab.h>
+
+#include <linux/mfd/htc-pasic3.h>
+#include <linux/mfd/core.h>
+#include <linux/module.h>
+
+/*
+ * 1 tick is around 62-63 ms, blinking settings (on+off):
+ *	Min: 1+1 ticks ~125ms
+ *	Max: 127+127 ticks ~15?875ms
+ * Sometimes takes time to change after write (counter overflow?)
+ */
+
+#define MS_TO_CLK(ms)	DIV_ROUND_CLOSEST(((ms)*1024), 64000)
+#define CLK_TO_MS(clk)	(((clk)*64000)/1024)
+#define MAX_CLK		254		/* 127 + 127 (2x 7 bit reg) */
+#define MAX_MS		CLK_TO_MS(MAX_CLK)
+
+static void brightness_set(struct led_classdev *cdev,
+	enum led_brightness value)
+{
+	struct platform_device *pdev = to_platform_device(cdev->dev->parent);
+	const struct mfd_cell *cell = mfd_get_cell(pdev);
+	struct pasic3_led *led;
+	struct device *dev;
+	u8 val;
+
+	if (!cell->platform_data) {
+		pr_err("No platform data\n");
+		return;
+	}
+
+	led = cell->platform_data;
+	dev = pdev->dev.parent;
+
+	if (value == LED_OFF) {
+		val = pasic3_read_register(dev, PASIC3_CH_CONTROL);
+		pasic3_write_register(dev, PASIC3_CH_CONTROL,
+			val & ~(led->bit_blink_en | led->bit_force_on));
+
+		val = pasic3_read_register(dev, PASIC3_MASK_A);
+		pasic3_write_register(dev, PASIC3_MASK_A, val & ~led->bit_mask);
+	} else {
+		val = pasic3_read_register(dev, PASIC3_CH_CONTROL);
+		pasic3_write_register(dev, PASIC3_CH_CONTROL,
+			val | led->bit_force_on);
+	}
+}
+
+static int blink_set(struct led_classdev *cdev,
+	unsigned long *delay_on,
+	unsigned long *delay_off)
+{
+	struct platform_device *pdev = to_platform_device(cdev->dev->parent);
+	const struct mfd_cell *cell = mfd_get_cell(pdev);
+	struct device *dev;
+	struct pasic3_led *led;
+	u32 on, off;
+	u8 val;
+
+	if (!cell->platform_data) {
+		pr_err("No platform data\n");
+		return -EINVAL;
+	}
+
+	if (*delay_on > MAX_MS || *delay_off > MAX_MS)
+		return -EINVAL;
+
+	if (*delay_on == 0 && *delay_off == 0) {
+		/* If both are zero then a sensible default should be chosen */
+		on = MS_TO_CLK(500);
+		off = MS_TO_CLK(500);
+	} else {
+		on = MS_TO_CLK(*delay_on);
+		off = MS_TO_CLK(*delay_off);
+		if ((on + off) > MAX_CLK)
+			return -EINVAL;
+		/* Minimal value must be 1 */
+		on = on ? on : 1;
+		off = off ? off : 1;
+	}
+
+	led = cell->platform_data;
+	dev = pdev->dev.parent;
+
+	pasic3_write_register(dev, led->reg_delay_on, on);
+	pasic3_write_register(dev, led->reg_delay_off, off);
+
+	val = pasic3_read_register(dev, PASIC3_CH_CONTROL);
+	pasic3_write_register(dev, PASIC3_CH_CONTROL, val | led->bit_blink_en);
+
+	*delay_on = CLK_TO_MS(on);
+	*delay_off = CLK_TO_MS(off);
+
+	return 0;
+}
+
+static int pasic3_led_probe(struct platform_device *pdev)
+{
+	struct pasic3_led *led = dev_get_platdata(&pdev->dev);
+	int ret;
+
+	ret = mfd_cell_enable(pdev);
+	if (ret < 0)
+		return ret;
+
+	led->cdev.flags = LED_CORE_SUSPENDRESUME;
+	led->cdev.brightness_set = brightness_set;
+	led->cdev.blink_set = blink_set;
+
+	ret = led_classdev_register(&pdev->dev, &led->cdev);
+	if (ret < 0)
+		goto out;
+
+	return 0;
+
+out:
+	(void) mfd_cell_disable(pdev);
+	return ret;
+}
+
+static int pasic3_led_remove(struct platform_device *pdev)
+{
+	struct pasic3_led *led = dev_get_platdata(&pdev->dev);
+
+	led_classdev_unregister(&led->cdev);
+
+	return mfd_cell_disable(pdev);
+}
+
+#ifdef CONFIG_PM_SLEEP
+static int pasic3_led_suspend(struct device *dev)
+{
+	struct platform_device *pdev = to_platform_device(dev);
+	const struct mfd_cell *cell = mfd_get_cell(pdev);
+	int ret;
+
+	ret = 0;
+	if (cell->suspend)
+		ret = (*cell->suspend)(pdev);
+
+	return ret;
+}
+
+static int pasic3_led_resume(struct device *dev)
+{
+	struct platform_device *pdev = to_platform_device(dev);
+	const struct mfd_cell *cell = mfd_get_cell(pdev);
+	int ret;
+
+	ret = 0;
+	if (cell->resume)
+		ret = (*cell->resume)(pdev);
+
+	return ret;
+}
+#endif
+
+static SIMPLE_DEV_PM_OPS(pasic3_led_pm_ops, pasic3_led_suspend,
+	pasic3_led_resume);
+
+static struct platform_driver pasic3_led_driver = {
+	.probe		= pasic3_led_probe,
+	.remove		= pasic3_led_remove,
+	.driver		= {
+		.name	= "leds-pasic3",
+		.pm	= &pasic3_led_pm_ops,
+	},
+};
+
+module_platform_driver(pasic3_led_driver);
+
+MODULE_AUTHOR("Petr Cvek <petr.cvek at tul.cz>");
+MODULE_DESCRIPTION("HTC Magician PASIC3 LED driver");
+MODULE_LICENSE("GPL");
+MODULE_ALIAS("platform:leds-pasic3");
diff --git a/drivers/mfd/htc-pasic3.c b/drivers/mfd/htc-pasic3.c
index e88d4f6..3df3f0a 100644
--- a/drivers/mfd/htc-pasic3.c
+++ b/drivers/mfd/htc-pasic3.c
@@ -3,6 +3,9 @@
  *
  * Copyright (C) 2006 Philipp Zabel <philipp.zabel at gmail.com>
  *
+ * LED support:
+ * Copyright (C) 2015 Petr Cvek <petr.cvek at tul.cz>
+ *
  * 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; version 2 of the License.
@@ -65,8 +68,76 @@ EXPORT_SYMBOL(pasic3_read_register); /* for leds-pasic3 */
  * LEDs
  */
 
-static struct mfd_cell led_cell __initdata = {
-	.name = "leds-pasic3",
+
+static int pasic3_leds_enable(struct platform_device *pdev)
+{
+	const struct mfd_cell *cell = mfd_get_cell(pdev);
+	struct pasic3_platform_data *pdata = dev_get_platdata(&pdev->dev);
+	struct pasic3_led *led;
+
+	led = cell->platform_data;
+	pdata = led->pdata;
+
+	gpio_set_value(pdata->power_gpio, 1);
+
+	return 0;
+}
+
+static int pasic3_leds_disable(struct platform_device *pdev)
+{
+	const struct mfd_cell *cell = mfd_get_cell(pdev);
+	struct pasic3_platform_data *pdata = dev_get_platdata(&pdev->dev);
+	struct pasic3_led *led;
+
+	led = cell->platform_data;
+	pdata = led->pdata;
+
+	gpio_set_value(pdata->power_gpio, 0);
+
+	return 0;
+}
+
+static int pasic3_leds_suspend(struct platform_device *pdev)
+{
+	const struct mfd_cell *cell = mfd_get_cell(pdev);
+	struct pasic3_platform_data *pdata = dev_get_platdata(&pdev->dev);
+	struct pasic3_led *led;
+
+	led = cell->platform_data;
+	pdata = led->pdata;
+
+	gpio_set_value(pdata->power_gpio, 0);
+
+	return 0;
+}
+
+#define PASIC3_NUM_LEDS 3
+
+static struct mfd_cell pasic3_cell_leds[PASIC3_NUM_LEDS] = {
+	[0] = {
+		.name		= "leds-pasic3",
+		.id			= 0,
+		.enable		= pasic3_leds_enable,
+		.disable	= pasic3_leds_disable,
+		.suspend	= pasic3_leds_suspend,
+		.resume		= pasic3_leds_enable,
+	},
+	[1] = {
+		.name		= "leds-pasic3",
+		.id			= 1,
+		.enable		= pasic3_leds_enable,
+		.disable	= pasic3_leds_disable,
+		.suspend	= pasic3_leds_suspend,
+		.resume		= pasic3_leds_enable,
+	},
+	[2] = {
+		.name		= "leds-pasic3",
+		.id			= 2,
+		.enable		= pasic3_leds_enable,
+		.disable	= pasic3_leds_disable,
+		.suspend	= pasic3_leds_suspend,
+		.resume		= pasic3_leds_enable,
+	},
 };
 
 /*
@@ -78,10 +149,10 @@ static int ds1wm_enable(struct platform_device *pdev)
 	struct device *dev = pdev->dev.parent;
 	int c;
 
-	c = pasic3_read_register(dev, 0x28);
-	pasic3_write_register(dev, 0x28, c & 0x7f);
+	c = pasic3_read_register(dev, PASIC3_GPIO);
+	pasic3_write_register(dev, PASIC3_GPIO, c & ~DS1WM_nEN);
 
-	dev_dbg(dev, "DS1WM OWM_EN low (active) %02x\n", c & 0x7f);
+	dev_dbg(dev, "DS1WM OWM_EN low (active) %02x\n", c & ~DS1WM_nEN);
 	return 0;
 }
 
@@ -90,10 +161,10 @@ static int ds1wm_disable(struct platform_device *pdev)
 	struct device *dev = pdev->dev.parent;
 	int c;
 
-	c = pasic3_read_register(dev, 0x28);
-	pasic3_write_register(dev, 0x28, c | 0x80);
+	c = pasic3_read_register(dev, PASIC3_GPIO);
+	pasic3_write_register(dev, PASIC3_GPIO, c | DS1WM_nEN);
 
-	dev_dbg(dev, "DS1WM OWM_EN high (inactive) %02x\n", c | 0x80);
+	dev_dbg(dev, "DS1WM OWM_EN high (inactive) %02x\n", c | DS1WM_nEN);
 	return 0;
 }
 
@@ -172,13 +243,27 @@ static int __init pasic3_probe(struct platform_device *pdev)
 			dev_warn(dev, "failed to register DS1WM\n");
 	}
 
-	if (pdata && pdata->led_pdata) {
-		led_cell.platform_data = pdata->led_pdata;
-		led_cell.pdata_size = sizeof(struct pasic3_leds_machinfo);
-		ret = mfd_add_devices(&pdev->dev, pdev->id, &led_cell, 1, r,
-				      0, NULL);
+	if (pdata && pdata->leds) {
+		int i;
+
+		for (i = 0; i < PASIC3_NUM_LEDS; ++i) {
+			pdata->leds[i].pdata = pdata;
+			pasic3_cell_leds[i].platform_data = &pdata->leds[i];
+			pasic3_cell_leds[i].pdata_size = sizeof(pdata->leds[i]);
+		}
+		ret = mfd_add_devices(&pdev->dev, 0,
+			pasic3_cell_leds, PASIC3_NUM_LEDS, NULL, 0, NULL);
+
 		if (ret < 0)
 			dev_warn(dev, "failed to register LED device\n");
+
+		if (pdata->power_gpio) {
+			ret = gpio_request(pdata->power_gpio,
+				"Red-Blue LED Power");
+			if (ret < 0)
+				dev_warn(dev, "failed to request power GPIO\n");
+		}
+
 	}
 
 	return 0;
@@ -187,10 +272,14 @@ static int __init pasic3_probe(struct platform_device *pdev)
 static int pasic3_remove(struct platform_device *pdev)
 {
 	struct pasic3_data *asic = platform_get_drvdata(pdev);
+	struct pasic3_platform_data *pdata = dev_get_platdata(&pdev->dev);
 	struct resource *r;
 
 	mfd_remove_devices(&pdev->dev);
 
+	if (pdata->power_gpio)
+		gpio_free(pdata->power_gpio);
+
 	iounmap(asic->mapping);
 	r = platform_get_resource(pdev, IORESOURCE_MEM, 0);
 	release_mem_region(r->start, resource_size(r));
diff --git a/include/linux/mfd/htc-pasic3.h b/include/linux/mfd/htc-pasic3.h
index 3d3ed67..e8e4cd2 100644
--- a/include/linux/mfd/htc-pasic3.h
+++ b/include/linux/mfd/htc-pasic3.h
@@ -18,36 +18,65 @@
 extern void pasic3_write_register(struct device *dev, u32 reg, u8 val);
 extern u8 pasic3_read_register(struct device *dev, u32 reg);
 
-/*
- * mask for registers 0x20,0x21,0x22
- */
-#define PASIC3_MASK_LED0 0x04
-#define PASIC3_MASK_LED1 0x08
-#define PASIC3_MASK_LED2 0x40
+#define PASIC3_CH0_DELAY_ON		0x00
+#define PASIC3_CH0_DELAY_OFF	0x01
+#define PASIC3_CH1_DELAY_ON		0x02
+#define PASIC3_CH1_DELAY_OFF	0x03
+#define PASIC3_CH2_DELAY_ON		0x04
+#define PASIC3_CH2_DELAY_OFF	0x05
+#define PASIC3_DELAY_MASK		0x7f
+
+#define PASIC3_CH_CONTROL		0x06
+#define		R06_CH0_EN			(1<<0)
+#define		R06_CH1_EN			(1<<1)
+#define		R06_CH2_EN			(1<<2)
+#define		R06_CH0_FORCE_ON	(1<<3)
+#define		R06_CH1_FORCE_ON	(1<<4)
+#define		R06_CH2_FORCE_ON	(1<<5)
 
 /*
- * bits in register 0x06
+ * pwm_ch0_out | force_on | (bit0 & bit1 & bit2)
+ * pwm_ch1_out | force_on | (bit0 & bit1 & bit2)
+ * pwm_ch2_out | force_on | (bit2?bit0:(bit0 & ! bit1))
  */
-#define PASIC3_BIT2_LED0 0x08
-#define PASIC3_BIT2_LED1 0x10
-#define PASIC3_BIT2_LED2 0x20
+
+#define PASIC3_MASK_A	0x20
+#define PASIC3_MASK_B	0x21
+#define PASIC3_MASK_C	0x22
+#define  MASK_CH0	(1<<2)
+#define  MASK_CH1	(1<<3)
+#define  MASK_CH2	(1<<6)
+#define  PASIC3_GPIO	0x28
+
+#define	DS1WM_nEN	(1<<7)
+#define  PASIC3_SYS	0x2a
+/* NORMAL_RST, CAM_PWR_RST and UNKNOWN will autoclear, set STATUS */
+#define  NORMAL_RST		(1<<0)
+#define  CAM_PWR_RST	(1<<1)
+#define  UNKNOWN		(1<<2)
+#define  STATUS_NORMAL_RST	(1<<4)
+#define  STATUS_CAM_PWR_RST	(1<<5)
+#define  STATUS_UNKNOWN		(1<<6)
+
+#define PASIC3_RST_EN		0x2c
+#define  EN_NORMAL_RST	0x40
+#define  EN_DOOR_RST	0x42
 
 struct pasic3_led {
-	struct led_classdev         led;
-	unsigned int                hw_num;
-	unsigned int                bit2;
-	unsigned int                mask;
-	struct pasic3_leds_machinfo *pdata;
+	struct led_classdev		cdev;
+	unsigned int	hw_num;
+	unsigned char	bit_blink_en;
+	unsigned char	bit_force_on;
+	unsigned char	bit_mask;
+	unsigned char	reg_delay_on;
+	unsigned char	reg_delay_off;
+	struct pasic3_platform_data *pdata;
 };
 
-struct pasic3_leds_machinfo {
+struct pasic3_platform_data {
 	unsigned int      num_leds;
 	unsigned int      power_gpio;
 	struct pasic3_led *leds;
-};
-
-struct pasic3_platform_data {
-	struct pasic3_leds_machinfo *led_pdata;
 	unsigned int                 clock_rate;
 };
 
-- 
1.7.12.1



From sboyd at codeaurora.org  Wed Aug 12 16:03:21 2015
From: sboyd at codeaurora.org (Stephen Boyd)
Date: Wed, 12 Aug 2015 16:03:21 -0700
Subject: [PATCH 3/9] PM / Domains: Support IRQ safe PM domains
In-Reply-To: <1438731339-58317-4-git-send-email-lina.iyer@linaro.org>
References: <1438731339-58317-1-git-send-email-lina.iyer@linaro.org>
 <1438731339-58317-4-git-send-email-lina.iyer@linaro.org>
Message-ID: <20150812230321.GN26614@codeaurora.org>

On 08/04, Lina Iyer wrote:
> diff --git a/Documentation/power/devices.txt b/Documentation/power/devices.txt
> index 8ba6625..6d8318c 100644
> --- a/Documentation/power/devices.txt
> +++ b/Documentation/power/devices.txt
> @@ -607,7 +607,16 @@ individually.  Instead, a set of devices sharing a power resource can be put
>  into a low-power state together at the same time by turning off the shared
>  power resource.  Of course, they also need to be put into the full-power state
>  together, by turning the shared power resource on.  A set of devices with this
> -property is often referred to as a power domain.
> +property is often referred to as a power domain. A power domain may also be
> +nested inside another power domain.
> +
> +Devices, by default, operate in process context and if a device can operate in
> +IRQ safe context, has to be explicitly set as IRQ safe. Power domains by
> +default, operate in process context but could have devices that are IRQ safe.
> +Such power domains cannot be powered on/off during runtime PM. On the other
> +hand, an IRQ safe PM domain that can be powered on/off and suspend or resumed

s/suspend/suspended/?

> +in an atomic context, may contain IRQ safe devices. Such domains may only
> +contain IRQ safe devices or IRQ safe sub-domains.
>  
>  Support for power domains is provided through the pm_domain field of struct
>  device.  This field is a pointer to an object of type struct dev_pm_domain,
> diff --git a/drivers/base/power/domain.c b/drivers/base/power/domain.c
> index ef8d19f..221feb0 100644
> --- a/drivers/base/power/domain.c
> +++ b/drivers/base/power/domain.c
> @@ -53,6 +53,74 @@
>  static LIST_HEAD(gpd_list);
>  static DEFINE_MUTEX(gpd_list_lock);
>  
> +static inline int genpd_lock_noirq(struct generic_pm_domain *genpd,
> +					unsigned int subclass)
> +	__acquires(&genpd->slock)
> +{
> +	unsigned long flags;
> +
> +	if (subclass > 0)
> +		spin_lock_irqsave_nested(&genpd->slock, flags, subclass);
> +	else
> +		spin_lock_irqsave(&genpd->slock, flags);
> +
> +	genpd->lock_flags = flags;
> +	return 0;

Why return anything at all?

> +}
> +
> +static inline void genpd_unlock_noirq(struct generic_pm_domain *genpd)
> +	__releases(&genpd->slock)
> +{
> +	spin_unlock_irqrestore(&genpd->slock, genpd->lock_flags);
> +}
> +
> +static inline int genpd_lock_irq(struct generic_pm_domain *genpd,
> +					unsigned int subclass)
> +	__acquires(&genpd->mlock)
> +{
> +	if (subclass > 0)
> +		mutex_lock_nested(&genpd->mlock, subclass);
> +	else
> +		mutex_lock(&genpd->mlock);
> +	return 0;

Same here.

> +}
> +
> +static inline int genpd_lock_interruptible_irq(struct generic_pm_domain *genpd)
> +	__acquires(&genpd->mlock)
> +{
> +	return mutex_lock_interruptible(&genpd->mlock);
> +}
> +
> +static inline void genpd_unlock_irq(struct generic_pm_domain *genpd)
> +	__releases(&genpd->mlock)
> +{
> +	mutex_unlock(&genpd->mlock);
> +}
> +
> +static inline int genpd_lock(struct generic_pm_domain *genpd)
> +{
> +	return genpd->irq_safe ? genpd_lock_noirq(genpd, 0)
> +			: genpd_lock_irq(genpd, 0);
> +}
> +
> +static inline int genpd_lock_nested(struct generic_pm_domain *genpd)
> +{
> +	return genpd->irq_safe ? genpd_lock_noirq(genpd, SINGLE_DEPTH_NESTING)
> +			: genpd_lock_irq(genpd, SINGLE_DEPTH_NESTING);
> +}

And for all these functions. The return is always 0.

> +
> +static inline int genpd_lock_interruptible(struct generic_pm_domain *genpd)
> +{
> +	return genpd->irq_safe ? genpd_lock_noirq(genpd, 0)
> +			: genpd_lock_interruptible_irq(genpd);
> +}

I guess this is the only one that matters.

> +
> +static inline void genpd_unlock(struct generic_pm_domain *genpd)
> +{
> +	return genpd->irq_safe ? genpd_unlock_noirq(genpd)
> +			: genpd_unlock_irq(genpd);
> +}

And this one again always returns 0?

> +
>  static struct generic_pm_domain *pm_genpd_lookup_name(const char *domain_name)
>  {
>  	struct generic_pm_domain *genpd = NULL, *gpd;
> @@ -535,15 +611,18 @@ static int pm_genpd_runtime_resume(struct device *dev)
>  	if (IS_ERR(genpd))
>  		return -EINVAL;
>  
> -	/* If power.irq_safe, the PM domain is never powered off. */
> -	if (dev->power.irq_safe) {
> +	/*
> +	 * As we dont power off a non IRQ safe domain, which holds
> +	 * an IRQ safe device, we dont need to restore power to it.
> +	 */
> +	if (dev->power.irq_safe && !genpd->irq_safe) {

This same statement where we check dev for irq_safe and genpd for
!irq_safe has happened three times now. Maybe it should be some
sort of helper function?

if (irq_safe_device_in_no_sleep_domain(dev, genpd))

or something?

-- 
Qualcomm Innovation Center, Inc. is a member of Code Aurora Forum,
a Linux Foundation Collaborative Project


From stefan at agner.ch  Wed Aug 12 16:03:51 2015
From: stefan at agner.ch (Stefan Agner)
Date: Thu, 13 Aug 2015 01:03:51 +0200
Subject: [PATCH v5] ARM: early fixmap support for earlycon
In-Reply-To: <1439309753-30864-1-git-send-email-stefan@agner.ch>
References: <1439309753-30864-1-git-send-email-stefan@agner.ch>
Message-ID: <be21734a76bbc844d3035b3bf3a1ad6c@agner.ch>

On 2015-08-11 18:15, Stefan Agner wrote:
<snip>
> Hi Russel,
> 
> All three compile issues were related to MMU/!MMU differences. The solution
> is rather simple: This patch now only configures FIX_EARLYCON_MEM if the
> MMU is available. This makes sense since on !MMU platform we can use ioremap
> very early...
> 
> --
> Stefan
> 
> Changes since v4:
> - Add MMU dependency for FIX_EARLYCON_MEM
> - Call early_fixmap_init conditionally, only if FIX_EARLYCON_MEM is set
<snip>

Submitted to the patch tracker as 8415/1.

--
Stefan


From petr.cvek at tul.cz  Wed Aug 12 16:10:29 2015
From: petr.cvek at tul.cz (Petr Cvek)
Date: Thu, 13 Aug 2015 01:10:29 +0200
Subject: [PATCH v1 RFC] This patch repairs HTC Magician machine (PXA27x)
 support
In-Reply-To: <55CBCDED.8010409@tul.cz>
References: <55CBCDED.8010409@tul.cz>
Message-ID: <55CBD265.7080705@tul.cz>

Dne 13.8.2015 v 00:51 Petr Cvek napsal(a):

> diff --git a/drivers/mfd/htc-pasic3.c b/drivers/mfd/htc-pasic3.c
> index e88d4f6..3df3f0a 100644
> --- a/drivers/mfd/htc-pasic3.c
> +++ b/drivers/mfd/htc-pasic3.c
> @@ -3,6 +3,9 @@
>   *
>   * Copyright (C) 2006 Philipp Zabel <philipp.zabel at gmail.com>
>   *
> + * LED support:
> + * Copyright (C) 2015 Petr Cvek <petr.cvek at tul.cz>
> + *
>   * 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; version 2 of the License.
> @@ -65,8 +68,76 @@ EXPORT_SYMBOL(pasic3_read_register); /* for leds-pasic3 */
>   * LEDs
>   */

Just some P.S.

Checkpatch warns me about spaces around * in this section. It seems it thinks it is some pointer. Is this behavior OK (I assume it cannot find begining of comment or am I doing something bad?).

Checkpatch also throws warning about new file and MAINTAINERS list updating (for leds-pasic3.c). I assume it falls into LEDs subsystem.

As the patch changes the definitions for many subsystems, are there another people who should be awared of this patch?

Cheers,
Petr Cvek



From sboyd at codeaurora.org  Wed Aug 12 16:12:40 2015
From: sboyd at codeaurora.org (Stephen Boyd)
Date: Wed, 12 Aug 2015 16:12:40 -0700
Subject: [PATCH 1/2] clk: Constify clk_hw argument to provider APIs
Message-ID: <1439421161-17868-1-git-send-email-sboyd@codeaurora.org>

We don't modify the clk_hw argument in these functions, so it's
safe to mark it as const.

Signed-off-by: Stephen Boyd <sboyd at codeaurora.org>
---
 drivers/clk/clk.c            | 15 ++++++++-------
 include/linux/clk-provider.h | 14 +++++++-------
 2 files changed, 15 insertions(+), 14 deletions(-)

diff --git a/drivers/clk/clk.c b/drivers/clk/clk.c
index 128ad748b682..8e6688d1ecbd 100644
--- a/drivers/clk/clk.c
+++ b/drivers/clk/clk.c
@@ -278,7 +278,7 @@ const char *__clk_get_name(struct clk *clk)
 }
 EXPORT_SYMBOL_GPL(__clk_get_name);
 
-const char *clk_hw_get_name(struct clk_hw *hw)
+const char *clk_hw_get_name(const struct clk_hw *hw)
 {
 	return hw->core->name;
 }
@@ -290,13 +290,13 @@ struct clk_hw *__clk_get_hw(struct clk *clk)
 }
 EXPORT_SYMBOL_GPL(__clk_get_hw);
 
-unsigned int clk_hw_get_num_parents(struct clk_hw *hw)
+unsigned int clk_hw_get_num_parents(const struct clk_hw *hw)
 {
 	return hw->core->num_parents;
 }
 EXPORT_SYMBOL_GPL(clk_hw_get_num_parents);
 
-struct clk_hw *clk_hw_get_parent(struct clk_hw *hw)
+struct clk_hw *clk_hw_get_parent(const struct clk_hw *hw)
 {
 	return hw->core->parent ? hw->core->parent->hw : NULL;
 }
@@ -359,7 +359,8 @@ static struct clk_core *clk_core_get_parent_by_index(struct clk_core *core,
 		return core->parents[index];
 }
 
-struct clk_hw *clk_hw_get_parent_by_index(struct clk_hw *hw, unsigned int index)
+struct clk_hw *
+clk_hw_get_parent_by_index(const struct clk_hw *hw, unsigned int index)
 {
 	struct clk_core *parent;
 
@@ -395,7 +396,7 @@ out:
 	return ret;
 }
 
-unsigned long clk_hw_get_rate(struct clk_hw *hw)
+unsigned long clk_hw_get_rate(const struct clk_hw *hw)
 {
 	return clk_core_get_rate_nolock(hw->core);
 }
@@ -415,13 +416,13 @@ unsigned long __clk_get_flags(struct clk *clk)
 }
 EXPORT_SYMBOL_GPL(__clk_get_flags);
 
-unsigned long clk_hw_get_flags(struct clk_hw *hw)
+unsigned long clk_hw_get_flags(const struct clk_hw *hw)
 {
 	return hw->core->flags;
 }
 EXPORT_SYMBOL_GPL(clk_hw_get_flags);
 
-bool clk_hw_is_prepared(struct clk_hw *hw)
+bool clk_hw_is_prepared(const struct clk_hw *hw)
 {
 	return clk_core_is_prepared(hw->core);
 }
diff --git a/include/linux/clk-provider.h b/include/linux/clk-provider.h
index 0d3128fbc14e..3ecc07d0da77 100644
--- a/include/linux/clk-provider.h
+++ b/include/linux/clk-provider.h
@@ -607,17 +607,17 @@ void devm_clk_unregister(struct device *dev, struct clk *clk);
 
 /* helper functions */
 const char *__clk_get_name(struct clk *clk);
-const char *clk_hw_get_name(struct clk_hw *hw);
+const char *clk_hw_get_name(const struct clk_hw *hw);
 struct clk_hw *__clk_get_hw(struct clk *clk);
-unsigned int clk_hw_get_num_parents(struct clk_hw *hw);
-struct clk_hw *clk_hw_get_parent(struct clk_hw *hw);
-struct clk_hw *clk_hw_get_parent_by_index(struct clk_hw *hw,
+unsigned int clk_hw_get_num_parents(const struct clk_hw *hw);
+struct clk_hw *clk_hw_get_parent(const struct clk_hw *hw);
+struct clk_hw *clk_hw_get_parent_by_index(const struct clk_hw *hw,
 					  unsigned int index);
 unsigned int __clk_get_enable_count(struct clk *clk);
-unsigned long clk_hw_get_rate(struct clk_hw *hw);
+unsigned long clk_hw_get_rate(const struct clk_hw *hw);
 unsigned long __clk_get_flags(struct clk *clk);
-unsigned long clk_hw_get_flags(struct clk_hw *hw);
-bool clk_hw_is_prepared(struct clk_hw *hw);
+unsigned long clk_hw_get_flags(const struct clk_hw *hw);
+bool clk_hw_is_prepared(const struct clk_hw *hw);
 bool __clk_is_enabled(struct clk *clk);
 struct clk *__clk_lookup(const char *name);
 int __clk_mux_determine_rate(struct clk_hw *hw,
-- 
The Qualcomm Innovation Center, Inc. is a member of the Code Aurora Forum,
a Linux Foundation Collaborative Project



From sboyd at codeaurora.org  Wed Aug 12 16:12:41 2015
From: sboyd at codeaurora.org (Stephen Boyd)
Date: Wed, 12 Aug 2015 16:12:41 -0700
Subject: [PATCH 2/2] clk: Convert __clk_get_name(hw->clk) to
 clk_hw_get_name(hw)
In-Reply-To: <1439421161-17868-1-git-send-email-sboyd@codeaurora.org>
References: <1439421161-17868-1-git-send-email-sboyd@codeaurora.org>
Message-ID: <1439421161-17868-2-git-send-email-sboyd@codeaurora.org>

Use the provider based method to get a clock's name so that we
can get rid of the clk member in struct clk_hw one day. Mostly
converted with the following coccinelle script.

@@
struct clk_hw *E;
@@

-__clk_get_name(E->clk)
+clk_hw_get_name(E)

Cc: Heiko Stuebner <heiko at sntech.de>
Cc: Sylwester Nawrocki <s.nawrocki at samsung.com>
Cc: Tomasz Figa <tomasz.figa at gmail.com>
Cc: Peter De Schrijver <pdeschrijver at nvidia.com>
Cc: Prashant Gaikwad <pgaikwad at nvidia.com>
Cc: Stephen Warren <swarren at wwwdotorg.org>
Cc: Thierry Reding <thierry.reding at gmail.com>
Cc: Alexandre Courbot <gnurou at gmail.com>
Cc: Tero Kristo <t-kristo at ti.com>
Cc: Ulf Hansson <ulf.hansson at linaro.org>
Cc: Sebastian Hesselbarth <sebastian.hesselbarth at gmail.com>
Cc: Andrew Bresticker <abrestic at chromium.org>
Cc: Ezequiel Garcia <ezequiel.garcia at imgtec.com>
Cc: Ralf Baechle <ralf at linux-mips.org>
Cc: Kevin Cernekee <cernekee at chromium.org>
Cc: Geert Uytterhoeven <geert+renesas at glider.be>
Cc: Ulrich Hecht <ulrich.hecht+renesas at gmail.com>
Cc: linux-arm-kernel at lists.infradead.org
Cc: linux-rockchip at lists.infradead.org
Cc: linux-samsung-soc at vger.kernel.org
Cc: linux-tegra at vger.kernel.org
Cc: linux-omap at vger.kernel.org
Signed-off-by: Stephen Boyd <sboyd at codeaurora.org>
---
 drivers/clk/berlin/berlin2-pll.c     |  4 ++--
 drivers/clk/clk-xgene.c              | 22 +++++++++++-----------
 drivers/clk/pistachio/clk-pll.c      |  4 ++--
 drivers/clk/qcom/clk-branch.c        |  2 +-
 drivers/clk/rockchip/clk-inverter.c  |  2 +-
 drivers/clk/rockchip/clk-mmc-phase.c |  2 +-
 drivers/clk/samsung/clk-pll.c        | 18 +++++++++---------
 drivers/clk/shmobile/clk-div6.c      |  2 +-
 drivers/clk/st/clk-flexgen.c         |  4 ++--
 drivers/clk/st/clkgen-fsyn.c         | 18 +++++++++---------
 drivers/clk/st/clkgen-mux.c          |  2 +-
 drivers/clk/st/clkgen-pll.c          |  8 ++++----
 drivers/clk/tegra/clk-pll.c          |  8 ++++----
 drivers/clk/ti/apll.c                |  4 ++--
 drivers/clk/ti/clkt_dflt.c           |  8 ++++----
 drivers/clk/ti/clockdomain.c         | 14 +++++++-------
 drivers/clk/ux500/clk-prcmu.c        | 16 ++++++++--------
 drivers/clk/ux500/clk-sysctrl.c      |  2 +-
 18 files changed, 70 insertions(+), 70 deletions(-)

diff --git a/drivers/clk/berlin/berlin2-pll.c b/drivers/clk/berlin/berlin2-pll.c
index f4b8d324b083..1c2294d3ba85 100644
--- a/drivers/clk/berlin/berlin2-pll.c
+++ b/drivers/clk/berlin/berlin2-pll.c
@@ -61,7 +61,7 @@ berlin2_pll_recalc_rate(struct clk_hw *hw, unsigned long parent_rate)
 	fbdiv = (val >> map->fbdiv_shift) & FBDIV_MASK;
 	rfdiv = (val >> map->rfdiv_shift) & RFDIV_MASK;
 	if (rfdiv == 0) {
-		pr_warn("%s has zero rfdiv\n", __clk_get_name(hw->clk));
+		pr_warn("%s has zero rfdiv\n", clk_hw_get_name(hw));
 		rfdiv = 1;
 	}
 
@@ -70,7 +70,7 @@ berlin2_pll_recalc_rate(struct clk_hw *hw, unsigned long parent_rate)
 	vcodiv = map->vcodiv[vcodivsel];
 	if (vcodiv == 0) {
 		pr_warn("%s has zero vcodiv (index %d)\n",
-			__clk_get_name(hw->clk), vcodivsel);
+			clk_hw_get_name(hw), vcodivsel);
 		vcodiv = 1;
 	}
 
diff --git a/drivers/clk/clk-xgene.c b/drivers/clk/clk-xgene.c
index 4caee9356407..96a6190acac2 100644
--- a/drivers/clk/clk-xgene.c
+++ b/drivers/clk/clk-xgene.c
@@ -74,7 +74,7 @@ static int xgene_clk_pll_is_enabled(struct clk_hw *hw)
 	u32 data;
 
 	data = xgene_clk_read(pllclk->reg + pllclk->pll_offset);
-	pr_debug("%s pll %s\n", __clk_get_name(hw->clk),
+	pr_debug("%s pll %s\n", clk_hw_get_name(hw),
 		data & REGSPEC_RESET_F1_MASK ? "disabled" : "enabled");
 
 	return data & REGSPEC_RESET_F1_MASK ? 0 : 1;
@@ -112,7 +112,7 @@ static unsigned long xgene_clk_pll_recalc_rate(struct clk_hw *hw,
 		fref = parent_rate / nref;
 		fvco = fref * nfb;
 	}
-	pr_debug("%s pll recalc rate %ld parent %ld\n", __clk_get_name(hw->clk),
+	pr_debug("%s pll recalc rate %ld parent %ld\n", clk_hw_get_name(hw),
 		fvco / nout, parent_rate);
 
 	return fvco / nout;
@@ -225,7 +225,7 @@ static int xgene_clk_enable(struct clk_hw *hw)
 		spin_lock_irqsave(pclk->lock, flags);
 
 	if (pclk->param.csr_reg != NULL) {
-		pr_debug("%s clock enabled\n", __clk_get_name(hw->clk));
+		pr_debug("%s clock enabled\n", clk_hw_get_name(hw));
 		reg = __pa(pclk->param.csr_reg);
 		/* First enable the clock */
 		data = xgene_clk_read(pclk->param.csr_reg +
@@ -234,7 +234,7 @@ static int xgene_clk_enable(struct clk_hw *hw)
 		xgene_clk_write(data, pclk->param.csr_reg +
 					pclk->param.reg_clk_offset);
 		pr_debug("%s clock PADDR base %pa clk offset 0x%08X mask 0x%08X value 0x%08X\n",
-			__clk_get_name(hw->clk), &reg,
+			clk_hw_get_name(hw), &reg,
 			pclk->param.reg_clk_offset, pclk->param.reg_clk_mask,
 			data);
 
@@ -245,7 +245,7 @@ static int xgene_clk_enable(struct clk_hw *hw)
 		xgene_clk_write(data, pclk->param.csr_reg +
 					pclk->param.reg_csr_offset);
 		pr_debug("%s CSR RESET PADDR base %pa csr offset 0x%08X mask 0x%08X value 0x%08X\n",
-			__clk_get_name(hw->clk), &reg,
+			clk_hw_get_name(hw), &reg,
 			pclk->param.reg_csr_offset, pclk->param.reg_csr_mask,
 			data);
 	}
@@ -266,7 +266,7 @@ static void xgene_clk_disable(struct clk_hw *hw)
 		spin_lock_irqsave(pclk->lock, flags);
 
 	if (pclk->param.csr_reg != NULL) {
-		pr_debug("%s clock disabled\n", __clk_get_name(hw->clk));
+		pr_debug("%s clock disabled\n", clk_hw_get_name(hw));
 		/* First put the CSR in reset */
 		data = xgene_clk_read(pclk->param.csr_reg +
 					pclk->param.reg_csr_offset);
@@ -292,10 +292,10 @@ static int xgene_clk_is_enabled(struct clk_hw *hw)
 	u32 data = 0;
 
 	if (pclk->param.csr_reg != NULL) {
-		pr_debug("%s clock checking\n", __clk_get_name(hw->clk));
+		pr_debug("%s clock checking\n", clk_hw_get_name(hw));
 		data = xgene_clk_read(pclk->param.csr_reg +
 					pclk->param.reg_clk_offset);
-		pr_debug("%s clock is %s\n", __clk_get_name(hw->clk),
+		pr_debug("%s clock is %s\n", clk_hw_get_name(hw),
 			data & pclk->param.reg_clk_mask ? "enabled" :
 							"disabled");
 	}
@@ -318,13 +318,13 @@ static unsigned long xgene_clk_recalc_rate(struct clk_hw *hw,
 		data &= (1 << pclk->param.reg_divider_width) - 1;
 
 		pr_debug("%s clock recalc rate %ld parent %ld\n",
-			__clk_get_name(hw->clk),
+			clk_hw_get_name(hw),
 			parent_rate / data, parent_rate);
 
 		return parent_rate / data;
 	} else {
 		pr_debug("%s clock recalc rate %ld parent %ld\n",
-			__clk_get_name(hw->clk), parent_rate, parent_rate);
+			clk_hw_get_name(hw), parent_rate, parent_rate);
 		return parent_rate;
 	}
 }
@@ -356,7 +356,7 @@ static int xgene_clk_set_rate(struct clk_hw *hw, unsigned long rate,
 		data |= divider;
 		xgene_clk_write(data, pclk->param.divider_reg +
 					pclk->param.reg_divider_offset);
-		pr_debug("%s clock set rate %ld\n", __clk_get_name(hw->clk),
+		pr_debug("%s clock set rate %ld\n", clk_hw_get_name(hw),
 			parent_rate / divider_save);
 	} else {
 		divider_save = 1;
diff --git a/drivers/clk/pistachio/clk-pll.c b/drivers/clk/pistachio/clk-pll.c
index e17dada0dd21..addfec731333 100644
--- a/drivers/clk/pistachio/clk-pll.c
+++ b/drivers/clk/pistachio/clk-pll.c
@@ -174,7 +174,7 @@ static int pll_gf40lp_frac_set_rate(struct clk_hw *hw, unsigned long rate,
 	struct pistachio_pll_rate_table *params;
 	int enabled = pll_gf40lp_frac_is_enabled(hw);
 	u32 val, vco, old_postdiv1, old_postdiv2;
-	const char *name = __clk_get_name(hw->clk);
+	const char *name = clk_hw_get_name(hw);
 
 	if (rate < MIN_OUTPUT_FRAC || rate > MAX_OUTPUT_FRAC)
 		return -EINVAL;
@@ -316,7 +316,7 @@ static int pll_gf40lp_laint_set_rate(struct clk_hw *hw, unsigned long rate,
 	struct pistachio_pll_rate_table *params;
 	int enabled = pll_gf40lp_laint_is_enabled(hw);
 	u32 val, vco, old_postdiv1, old_postdiv2;
-	const char *name = __clk_get_name(hw->clk);
+	const char *name = clk_hw_get_name(hw);
 
 	if (rate < MIN_OUTPUT_LA || rate > MAX_OUTPUT_LA)
 		return -EINVAL;
diff --git a/drivers/clk/qcom/clk-branch.c b/drivers/clk/qcom/clk-branch.c
index 6b4d2bcb1a53..26f7af315066 100644
--- a/drivers/clk/qcom/clk-branch.c
+++ b/drivers/clk/qcom/clk-branch.c
@@ -75,7 +75,7 @@ static int clk_branch_wait(const struct clk_branch *br, bool enabling,
 		bool (check_halt)(const struct clk_branch *, bool))
 {
 	bool voted = br->halt_check & BRANCH_VOTED;
-	const char *name = __clk_get_name(br->clkr.hw.clk);
+	const char *name = clk_hw_get_name(&br->clkr.hw);
 
 	/* Skip checking halt bit if the clock is in hardware gated mode */
 	if (clk_branch_in_hwcg_mode(br))
diff --git a/drivers/clk/rockchip/clk-inverter.c b/drivers/clk/rockchip/clk-inverter.c
index 8054fdb5effb..7cbf43beb3c6 100644
--- a/drivers/clk/rockchip/clk-inverter.c
+++ b/drivers/clk/rockchip/clk-inverter.c
@@ -50,7 +50,7 @@ static int rockchip_inv_set_phase(struct clk_hw *hw, int degrees)
 		val = !!degrees;
 	} else {
 		pr_err("%s: unsupported phase %d for %s\n",
-		       __func__, degrees, __clk_get_name(hw->clk));
+		       __func__, degrees, clk_hw_get_name(hw));
 		return -EINVAL;
 	}
 
diff --git a/drivers/clk/rockchip/clk-mmc-phase.c b/drivers/clk/rockchip/clk-mmc-phase.c
index 77e19097bdc7..9b613426e968 100644
--- a/drivers/clk/rockchip/clk-mmc-phase.c
+++ b/drivers/clk/rockchip/clk-mmc-phase.c
@@ -108,7 +108,7 @@ static int rockchip_mmc_set_phase(struct clk_hw *hw, int degrees)
 	writel(HIWORD_UPDATE(raw_value, 0x07ff, mmc_clock->shift), mmc_clock->reg);
 
 	pr_debug("%s->set_phase(%d) delay_nums=%u reg[0x%p]=0x%03x actual_degrees=%d\n",
-		__clk_get_name(hw->clk), degrees, delay_num,
+		clk_hw_get_name(hw), degrees, delay_num,
 		mmc_clock->reg, raw_value>>(mmc_clock->shift),
 		rockchip_mmc_get_phase(hw)
 	);
diff --git a/drivers/clk/samsung/clk-pll.c b/drivers/clk/samsung/clk-pll.c
index e9394261f80f..b7dd396100d8 100644
--- a/drivers/clk/samsung/clk-pll.c
+++ b/drivers/clk/samsung/clk-pll.c
@@ -182,7 +182,7 @@ static int samsung_pll35xx_set_rate(struct clk_hw *hw, unsigned long drate,
 	rate = samsung_get_pll_settings(pll, drate);
 	if (!rate) {
 		pr_err("%s: Invalid rate : %lu for pll clk %s\n", __func__,
-			drate, __clk_get_name(hw->clk));
+			drate, clk_hw_get_name(hw));
 		return -EINVAL;
 	}
 
@@ -290,7 +290,7 @@ static int samsung_pll36xx_set_rate(struct clk_hw *hw, unsigned long drate,
 	rate = samsung_get_pll_settings(pll, drate);
 	if (!rate) {
 		pr_err("%s: Invalid rate : %lu for pll clk %s\n", __func__,
-			drate, __clk_get_name(hw->clk));
+			drate, clk_hw_get_name(hw));
 		return -EINVAL;
 	}
 
@@ -405,7 +405,7 @@ static int samsung_pll45xx_set_rate(struct clk_hw *hw, unsigned long drate,
 	rate = samsung_get_pll_settings(pll, drate);
 	if (!rate) {
 		pr_err("%s: Invalid rate : %lu for pll clk %s\n", __func__,
-			drate, __clk_get_name(hw->clk));
+			drate, clk_hw_get_name(hw));
 		return -EINVAL;
 	}
 
@@ -457,7 +457,7 @@ static int samsung_pll45xx_set_rate(struct clk_hw *hw, unsigned long drate,
 
 		if (ktime_to_ms(delta) > PLL_TIMEOUT_MS) {
 			pr_err("%s: could not lock PLL %s\n",
-					__func__, __clk_get_name(hw->clk));
+					__func__, clk_hw_get_name(hw));
 			return -EFAULT;
 		}
 
@@ -556,7 +556,7 @@ static int samsung_pll46xx_set_rate(struct clk_hw *hw, unsigned long drate,
 	rate = samsung_get_pll_settings(pll, drate);
 	if (!rate) {
 		pr_err("%s: Invalid rate : %lu for pll clk %s\n", __func__,
-			drate, __clk_get_name(hw->clk));
+			drate, clk_hw_get_name(hw));
 		return -EINVAL;
 	}
 
@@ -616,7 +616,7 @@ static int samsung_pll46xx_set_rate(struct clk_hw *hw, unsigned long drate,
 
 		if (ktime_to_ms(delta) > PLL_TIMEOUT_MS) {
 			pr_err("%s: could not lock PLL %s\n",
-					__func__, __clk_get_name(hw->clk));
+					__func__, clk_hw_get_name(hw));
 			return -EFAULT;
 		}
 
@@ -774,7 +774,7 @@ static int samsung_s3c2410_pll_set_rate(struct clk_hw *hw, unsigned long drate,
 	rate = samsung_get_pll_settings(pll, drate);
 	if (!rate) {
 		pr_err("%s: Invalid rate : %lu for pll clk %s\n", __func__,
-			drate, __clk_get_name(hw->clk));
+			drate, clk_hw_get_name(hw));
 		return -EINVAL;
 	}
 
@@ -1015,7 +1015,7 @@ static int samsung_pll2550xx_set_rate(struct clk_hw *hw, unsigned long drate,
 	rate = samsung_get_pll_settings(pll, drate);
 	if (!rate) {
 		pr_err("%s: Invalid rate : %lu for pll clk %s\n", __func__,
-			drate, __clk_get_name(hw->clk));
+			drate, clk_hw_get_name(hw));
 		return -EINVAL;
 	}
 
@@ -1113,7 +1113,7 @@ static int samsung_pll2650xx_set_rate(struct clk_hw *hw, unsigned long drate,
 	rate = samsung_get_pll_settings(pll, drate);
 	if (!rate) {
 		pr_err("%s: Invalid rate : %lu for pll clk %s\n", __func__,
-			drate, __clk_get_name(hw->clk));
+			drate, clk_hw_get_name(hw));
 		return -EINVAL;
 	}
 
diff --git a/drivers/clk/shmobile/clk-div6.c b/drivers/clk/shmobile/clk-div6.c
index ee66f49812df..b4c8d6746f68 100644
--- a/drivers/clk/shmobile/clk-div6.c
+++ b/drivers/clk/shmobile/clk-div6.c
@@ -139,7 +139,7 @@ static u8 cpg_div6_clock_get_parent(struct clk_hw *hw)
 	}
 
 	pr_err("%s: %s DIV6 clock set to invalid parent %u\n",
-	       __func__, __clk_get_name(hw->clk), hw_index);
+	       __func__, clk_hw_get_name(hw), hw_index);
 	return 0;
 }
 
diff --git a/drivers/clk/st/clk-flexgen.c b/drivers/clk/st/clk-flexgen.c
index 965b13ba3515..bd355ee33766 100644
--- a/drivers/clk/st/clk-flexgen.c
+++ b/drivers/clk/st/clk-flexgen.c
@@ -45,7 +45,7 @@ static int flexgen_enable(struct clk_hw *hw)
 
 	clk_gate_ops.enable(fgate_hw);
 
-	pr_debug("%s: flexgen output enabled\n", __clk_get_name(hw->clk));
+	pr_debug("%s: flexgen output enabled\n", clk_hw_get_name(hw));
 	return 0;
 }
 
@@ -59,7 +59,7 @@ static void flexgen_disable(struct clk_hw *hw)
 
 	clk_gate_ops.disable(fgate_hw);
 
-	pr_debug("%s: flexgen output disabled\n", __clk_get_name(hw->clk));
+	pr_debug("%s: flexgen output disabled\n", clk_hw_get_name(hw));
 }
 
 static int flexgen_is_enabled(struct clk_hw *hw)
diff --git a/drivers/clk/st/clkgen-fsyn.c b/drivers/clk/st/clkgen-fsyn.c
index aa3117db4514..83ccf142ff2a 100644
--- a/drivers/clk/st/clkgen-fsyn.c
+++ b/drivers/clk/st/clkgen-fsyn.c
@@ -513,7 +513,7 @@ static unsigned long quadfs_pll_fs660c32_recalc_rate(struct clk_hw *hw,
 	params.ndiv = CLKGEN_READ(pll, ndiv);
 	if (clk_fs660c32_vco_get_rate(parent_rate, &params, &rate))
 		pr_err("%s:%s error calculating rate\n",
-		       __clk_get_name(hw->clk), __func__);
+		       clk_hw_get_name(hw), __func__);
 
 	pll->ndiv = params.ndiv;
 
@@ -558,7 +558,7 @@ static long quadfs_pll_fs660c32_round_rate(struct clk_hw *hw, unsigned long rate
 		clk_fs660c32_vco_get_rate(*prate, &params, &rate);
 
 	pr_debug("%s: %s new rate %ld [sdiv=0x%x,md=0x%x,pe=0x%x,nsdiv3=%u]\n",
-		 __func__, __clk_get_name(hw->clk),
+		 __func__, clk_hw_get_name(hw),
 		 rate, (unsigned int)params.sdiv,
 		 (unsigned int)params.mdiv,
 		 (unsigned int)params.pe, (unsigned int)params.nsdiv);
@@ -581,7 +581,7 @@ static int quadfs_pll_fs660c32_set_rate(struct clk_hw *hw, unsigned long rate,
 		clk_fs660c32_vco_get_rate(parent_rate, &params, &hwrate);
 
 	pr_debug("%s: %s new rate %ld [ndiv=0x%x]\n",
-		 __func__, __clk_get_name(hw->clk),
+		 __func__, clk_hw_get_name(hw),
 		 hwrate, (unsigned int)params.ndiv);
 
 	if (!hwrate)
@@ -745,7 +745,7 @@ static int quadfs_fsynth_enable(struct clk_hw *hw)
 	struct st_clk_quadfs_fsynth *fs = to_quadfs_fsynth(hw);
 	unsigned long flags = 0;
 
-	pr_debug("%s: %s\n", __func__, __clk_get_name(hw->clk));
+	pr_debug("%s: %s\n", __func__, clk_hw_get_name(hw));
 
 	quadfs_fsynth_program_rate(fs);
 
@@ -770,7 +770,7 @@ static void quadfs_fsynth_disable(struct clk_hw *hw)
 	struct st_clk_quadfs_fsynth *fs = to_quadfs_fsynth(hw);
 	unsigned long flags = 0;
 
-	pr_debug("%s: %s\n", __func__, __clk_get_name(hw->clk));
+	pr_debug("%s: %s\n", __func__, clk_hw_get_name(hw));
 
 	if (fs->lock)
 		spin_lock_irqsave(fs->lock, flags);
@@ -787,7 +787,7 @@ static int quadfs_fsynth_is_enabled(struct clk_hw *hw)
 	u32 nsb = CLKGEN_READ(fs, nsb[fs->chan]);
 
 	pr_debug("%s: %s enable bit = 0x%x\n",
-		 __func__, __clk_get_name(hw->clk), nsb);
+		 __func__, clk_hw_get_name(hw), nsb);
 
 	return fs->data->standby_polarity ? !nsb : !!nsb;
 }
@@ -946,10 +946,10 @@ static unsigned long quadfs_recalc_rate(struct clk_hw *hw,
 
 	if (clk_fs_get_rate(parent_rate, &params, &rate)) {
 		pr_err("%s:%s error calculating rate\n",
-		       __clk_get_name(hw->clk), __func__);
+		       clk_hw_get_name(hw), __func__);
 	}
 
-	pr_debug("%s:%s rate %lu\n", __clk_get_name(hw->clk), __func__, rate);
+	pr_debug("%s:%s rate %lu\n", clk_hw_get_name(hw), __func__, rate);
 
 	return rate;
 }
@@ -962,7 +962,7 @@ static long quadfs_round_rate(struct clk_hw *hw, unsigned long rate,
 	rate = quadfs_find_best_rate(hw, rate, *prate, &params);
 
 	pr_debug("%s: %s new rate %ld [sdiv=0x%x,md=0x%x,pe=0x%x,nsdiv3=%u]\n",
-		 __func__, __clk_get_name(hw->clk),
+		 __func__, clk_hw_get_name(hw),
 		 rate, (unsigned int)params.sdiv, (unsigned int)params.mdiv,
 			 (unsigned int)params.pe, (unsigned int)params.nsdiv);
 
diff --git a/drivers/clk/st/clkgen-mux.c b/drivers/clk/st/clkgen-mux.c
index 81f2372b97ff..4f7f6c00b219 100644
--- a/drivers/clk/st/clkgen-mux.c
+++ b/drivers/clk/st/clkgen-mux.c
@@ -139,7 +139,7 @@ static u8 clkgena_divmux_get_parent(struct clk_hw *hw)
 	genamux->muxsel = clk_mux_ops.get_parent(mux_hw);
 	if ((s8)genamux->muxsel < 0) {
 		pr_debug("%s: %s: Invalid parent, setting to default.\n",
-		      __func__, __clk_get_name(hw->clk));
+		      __func__, clk_hw_get_name(hw));
 		genamux->muxsel = 0;
 	}
 
diff --git a/drivers/clk/st/clkgen-pll.c b/drivers/clk/st/clkgen-pll.c
index cc2b52ec730a..47a38a994cac 100644
--- a/drivers/clk/st/clkgen-pll.c
+++ b/drivers/clk/st/clkgen-pll.c
@@ -292,7 +292,7 @@ static unsigned long recalc_stm_pll800c65(struct clk_hw *hw,
 	res = (uint64_t)2 * (uint64_t)parent_rate * (uint64_t)ndiv;
 	rate = (unsigned long)div64_u64(res, mdiv * (1 << pdiv));
 
-	pr_debug("%s:%s rate %lu\n", __clk_get_name(hw->clk), __func__, rate);
+	pr_debug("%s:%s rate %lu\n", clk_hw_get_name(hw), __func__, rate);
 
 	return rate;
 
@@ -317,7 +317,7 @@ static unsigned long recalc_stm_pll1600c65(struct clk_hw *hw,
 	/* Note: input is divided by 1000 to avoid overflow */
 	rate = ((2 * (parent_rate / 1000) * ndiv) / mdiv) * 1000;
 
-	pr_debug("%s:%s rate %lu\n", __clk_get_name(hw->clk), __func__, rate);
+	pr_debug("%s:%s rate %lu\n", clk_hw_get_name(hw), __func__, rate);
 
 	return rate;
 }
@@ -339,7 +339,7 @@ static unsigned long recalc_stm_pll3200c32(struct clk_hw *hw,
 		/* Note: input is divided to avoid overflow */
 		rate = ((2 * (parent_rate/1000) * ndiv) / idf) * 1000;
 
-	pr_debug("%s:%s rate %lu\n", __clk_get_name(hw->clk), __func__, rate);
+	pr_debug("%s:%s rate %lu\n", clk_hw_get_name(hw), __func__, rate);
 
 	return rate;
 }
@@ -366,7 +366,7 @@ static unsigned long recalc_stm_pll1200c32(struct clk_hw *hw,
 	/* Note: input is divided by 1000 to avoid overflow */
 	rate = (((parent_rate / 1000) * ldf) / (odf * idf)) * 1000;
 
-	pr_debug("%s:%s rate %lu\n", __clk_get_name(hw->clk), __func__, rate);
+	pr_debug("%s:%s rate %lu\n", clk_hw_get_name(hw), __func__, rate);
 
 	return rate;
 }
diff --git a/drivers/clk/tegra/clk-pll.c b/drivers/clk/tegra/clk-pll.c
index 69fea7d08681..d6d4ecb88e94 100644
--- a/drivers/clk/tegra/clk-pll.c
+++ b/drivers/clk/tegra/clk-pll.c
@@ -264,7 +264,7 @@ static int clk_pll_wait_for_lock(struct tegra_clk_pll *pll)
 	}
 
 	pr_err("%s: Timed out waiting for pll %s lock\n", __func__,
-	       __clk_get_name(pll->hw.clk));
+	       clk_hw_get_name(&pll->hw));
 
 	return -1;
 }
@@ -595,7 +595,7 @@ static int clk_pll_set_rate(struct clk_hw *hw, unsigned long rate,
 	if (pll->params->flags & TEGRA_PLL_FIXED) {
 		if (rate != pll->params->fixed_rate) {
 			pr_err("%s: Can not change %s fixed rate %lu to %lu\n",
-				__func__, __clk_get_name(hw->clk),
+				__func__, clk_hw_get_name(hw),
 				pll->params->fixed_rate, rate);
 			return -EINVAL;
 		}
@@ -605,7 +605,7 @@ static int clk_pll_set_rate(struct clk_hw *hw, unsigned long rate,
 	if (_get_table_rate(hw, &cfg, rate, parent_rate) &&
 	    _calc_rate(hw, &cfg, rate, parent_rate)) {
 		pr_err("%s: Failed to set %s rate %lu\n", __func__,
-		       __clk_get_name(hw->clk), rate);
+		       clk_hw_get_name(hw), rate);
 		WARN_ON(1);
 		return -EINVAL;
 	}
@@ -663,7 +663,7 @@ static unsigned long clk_pll_recalc_rate(struct clk_hw *hw,
 		if (_get_table_rate(hw, &sel, pll->params->fixed_rate,
 					parent_rate)) {
 			pr_err("Clock %s has unknown fixed frequency\n",
-			       __clk_get_name(hw->clk));
+			       clk_hw_get_name(hw));
 			BUG();
 		}
 		return pll->params->fixed_rate;
diff --git a/drivers/clk/ti/apll.c b/drivers/clk/ti/apll.c
index 24febd4fe324..f3eab6e79027 100644
--- a/drivers/clk/ti/apll.c
+++ b/drivers/clk/ti/apll.c
@@ -50,7 +50,7 @@ static int dra7_apll_enable(struct clk_hw *hw)
 	if (!ad)
 		return -EINVAL;
 
-	clk_name = __clk_get_name(clk->hw.clk);
+	clk_name = clk_hw_get_name(&clk->hw);
 
 	state <<= __ffs(ad->idlest_mask);
 
@@ -273,7 +273,7 @@ static int omap2_apll_enable(struct clk_hw *hw)
 
 	if (i == MAX_APLL_WAIT_TRIES) {
 		pr_warn("%s failed to transition to locked\n",
-			__clk_get_name(clk->hw.clk));
+			clk_hw_get_name(&clk->hw));
 		return -EBUSY;
 	}
 
diff --git a/drivers/clk/ti/clkt_dflt.c b/drivers/clk/ti/clkt_dflt.c
index a176b8ac8dd0..90d7d8a21c49 100644
--- a/drivers/clk/ti/clkt_dflt.c
+++ b/drivers/clk/ti/clkt_dflt.c
@@ -110,7 +110,7 @@ static void _omap2_module_wait_ready(struct clk_hw_omap *clk)
 	if (r) {
 		/* IDLEST register not in the CM module */
 		_wait_idlest_generic(clk, idlest_reg, (1 << idlest_bit),
-				     idlest_val, __clk_get_name(clk->hw.clk));
+				     idlest_val, clk_hw_get_name(&clk->hw));
 	} else {
 		ti_clk_ll_ops->cm_wait_module_ready(0, prcm_mod, idlest_reg_id,
 						    idlest_bit);
@@ -216,7 +216,7 @@ int omap2_dflt_clk_enable(struct clk_hw *hw)
 		if (ret) {
 			WARN(1,
 			     "%s: could not enable %s's clockdomain %s: %d\n",
-			     __func__, __clk_get_name(hw->clk),
+			     __func__, clk_hw_get_name(hw),
 			     clk->clkdm_name, ret);
 			return ret;
 		}
@@ -224,7 +224,7 @@ int omap2_dflt_clk_enable(struct clk_hw *hw)
 
 	if (unlikely(!clk->enable_reg)) {
 		pr_err("%s: %s missing enable_reg\n", __func__,
-		       __clk_get_name(hw->clk));
+		       clk_hw_get_name(hw));
 		ret = -EINVAL;
 		goto err;
 	}
@@ -270,7 +270,7 @@ void omap2_dflt_clk_disable(struct clk_hw *hw)
 		 * controlled by its parent.
 		 */
 		pr_err("%s: independent clock %s has no enable_reg\n",
-		       __func__, __clk_get_name(hw->clk));
+		       __func__, clk_hw_get_name(hw));
 		return;
 	}
 
diff --git a/drivers/clk/ti/clockdomain.c b/drivers/clk/ti/clockdomain.c
index 362a62c10311..b9bc3b8df659 100644
--- a/drivers/clk/ti/clockdomain.c
+++ b/drivers/clk/ti/clockdomain.c
@@ -48,23 +48,23 @@ int omap2_clkops_enable_clkdm(struct clk_hw *hw)
 
 	if (unlikely(!clk->clkdm)) {
 		pr_err("%s: %s: no clkdm set ?!\n", __func__,
-		       __clk_get_name(hw->clk));
+		       clk_hw_get_name(hw));
 		return -EINVAL;
 	}
 
 	if (unlikely(clk->enable_reg))
 		pr_err("%s: %s: should use dflt_clk_enable ?!\n", __func__,
-		       __clk_get_name(hw->clk));
+		       clk_hw_get_name(hw));
 
 	if (ti_clk_get_features()->flags & TI_CLK_DISABLE_CLKDM_CONTROL) {
 		pr_err("%s: %s: clkfw-based clockdomain control disabled ?!\n",
-		       __func__, __clk_get_name(hw->clk));
+		       __func__, clk_hw_get_name(hw));
 		return 0;
 	}
 
 	ret = ti_clk_ll_ops->clkdm_clk_enable(clk->clkdm, hw->clk);
 	WARN(ret, "%s: could not enable %s's clockdomain %s: %d\n",
-	     __func__, __clk_get_name(hw->clk), clk->clkdm_name, ret);
+	     __func__, clk_hw_get_name(hw), clk->clkdm_name, ret);
 
 	return ret;
 }
@@ -86,17 +86,17 @@ void omap2_clkops_disable_clkdm(struct clk_hw *hw)
 
 	if (unlikely(!clk->clkdm)) {
 		pr_err("%s: %s: no clkdm set ?!\n", __func__,
-		       __clk_get_name(hw->clk));
+		       clk_hw_get_name(hw));
 		return;
 	}
 
 	if (unlikely(clk->enable_reg))
 		pr_err("%s: %s: should use dflt_clk_disable ?!\n", __func__,
-		       __clk_get_name(hw->clk));
+		       clk_hw_get_name(hw));
 
 	if (ti_clk_get_features()->flags & TI_CLK_DISABLE_CLKDM_CONTROL) {
 		pr_err("%s: %s: clkfw-based clockdomain control disabled ?!\n",
-		       __func__, __clk_get_name(hw->clk));
+		       __func__, clk_hw_get_name(hw));
 		return;
 	}
 
diff --git a/drivers/clk/ux500/clk-prcmu.c b/drivers/clk/ux500/clk-prcmu.c
index bf63c96acb1a..7f343821f4e4 100644
--- a/drivers/clk/ux500/clk-prcmu.c
+++ b/drivers/clk/ux500/clk-prcmu.c
@@ -43,7 +43,7 @@ static void clk_prcmu_unprepare(struct clk_hw *hw)
 	struct clk_prcmu *clk = to_clk_prcmu(hw);
 	if (prcmu_request_clock(clk->cg_sel, false))
 		pr_err("clk_prcmu: %s failed to disable %s.\n", __func__,
-			__clk_get_name(hw->clk));
+			clk_hw_get_name(hw));
 	else
 		clk->is_prepared = 0;
 }
@@ -101,11 +101,11 @@ static int clk_prcmu_opp_prepare(struct clk_hw *hw)
 
 	if (!clk->opp_requested) {
 		err = prcmu_qos_add_requirement(PRCMU_QOS_APE_OPP,
-						(char *)__clk_get_name(hw->clk),
+						(char *)clk_hw_get_name(hw),
 						100);
 		if (err) {
 			pr_err("clk_prcmu: %s fail req APE OPP for %s.\n",
-				__func__, __clk_get_name(hw->clk));
+				__func__, clk_hw_get_name(hw));
 			return err;
 		}
 		clk->opp_requested = 1;
@@ -114,7 +114,7 @@ static int clk_prcmu_opp_prepare(struct clk_hw *hw)
 	err = prcmu_request_clock(clk->cg_sel, true);
 	if (err) {
 		prcmu_qos_remove_requirement(PRCMU_QOS_APE_OPP,
-					(char *)__clk_get_name(hw->clk));
+					(char *)clk_hw_get_name(hw));
 		clk->opp_requested = 0;
 		return err;
 	}
@@ -129,13 +129,13 @@ static void clk_prcmu_opp_unprepare(struct clk_hw *hw)
 
 	if (prcmu_request_clock(clk->cg_sel, false)) {
 		pr_err("clk_prcmu: %s failed to disable %s.\n", __func__,
-			__clk_get_name(hw->clk));
+			clk_hw_get_name(hw));
 		return;
 	}
 
 	if (clk->opp_requested) {
 		prcmu_qos_remove_requirement(PRCMU_QOS_APE_OPP,
-					(char *)__clk_get_name(hw->clk));
+					(char *)clk_hw_get_name(hw));
 		clk->opp_requested = 0;
 	}
 
@@ -151,7 +151,7 @@ static int clk_prcmu_opp_volt_prepare(struct clk_hw *hw)
 		err = prcmu_request_ape_opp_100_voltage(true);
 		if (err) {
 			pr_err("clk_prcmu: %s fail req APE OPP VOLT for %s.\n",
-				__func__, __clk_get_name(hw->clk));
+				__func__, clk_hw_get_name(hw));
 			return err;
 		}
 		clk->opp_requested = 1;
@@ -174,7 +174,7 @@ static void clk_prcmu_opp_volt_unprepare(struct clk_hw *hw)
 
 	if (prcmu_request_clock(clk->cg_sel, false)) {
 		pr_err("clk_prcmu: %s failed to disable %s.\n", __func__,
-			__clk_get_name(hw->clk));
+			clk_hw_get_name(hw));
 		return;
 	}
 
diff --git a/drivers/clk/ux500/clk-sysctrl.c b/drivers/clk/ux500/clk-sysctrl.c
index e364c9d4aa60..266ddea630d2 100644
--- a/drivers/clk/ux500/clk-sysctrl.c
+++ b/drivers/clk/ux500/clk-sysctrl.c
@@ -52,7 +52,7 @@ static void clk_sysctrl_unprepare(struct clk_hw *hw)
 	struct clk_sysctrl *clk = to_clk_sysctrl(hw);
 	if (ab8500_sysctrl_clear(clk->reg_sel[0], clk->reg_mask[0]))
 		dev_err(clk->dev, "clk_sysctrl: %s fail to clear %s.\n",
-			__func__, __clk_get_name(hw->clk));
+			__func__, clk_hw_get_name(hw));
 }
 
 static unsigned long clk_sysctrl_recalc_rate(struct clk_hw *hw,
-- 
The Qualcomm Innovation Center, Inc. is a member of the Code Aurora Forum,
a Linux Foundation Collaborative Project



From sboyd at codeaurora.org  Wed Aug 12 16:47:56 2015
From: sboyd at codeaurora.org (Stephen Boyd)
Date: Wed, 12 Aug 2015 16:47:56 -0700
Subject: [PATCH 9/9] ARM: smp: Add runtime PM support for CPU hotplug
In-Reply-To: <1438731339-58317-10-git-send-email-lina.iyer@linaro.org>
References: <1438731339-58317-1-git-send-email-lina.iyer@linaro.org>
 <1438731339-58317-10-git-send-email-lina.iyer@linaro.org>
Message-ID: <20150812234756.GO26614@codeaurora.org>

On 08/04, Lina Iyer wrote:
> @@ -137,7 +138,6 @@ int __cpu_up(unsigned int cpu, struct task_struct *idle)
>  		pr_err("CPU%u: failed to boot: %d\n", cpu, ret);
>  	}
>  
> -

Remove noise please.

>  	memset(&secondary_data, 0, sizeof(secondary_data));
>  	return ret;
>  }
> @@ -205,6 +205,9 @@ int __cpu_disable(void)
>  	unsigned int cpu = smp_processor_id();
>  	int ret;
>  
> +	/* We dont need the CPU device anymore. */
> +	pm_runtime_put_sync(get_cpu_device(cpu));

This is all very generic. Any reason it can't be done at a higher
level for all architectures? It certainly seems like
cpu_startup_entry() could be modifed to do the
pm_runtime_get_sync().

> +
>  	ret = platform_cpu_disable(cpu);
>  	if (ret)
>  		return ret;
> @@ -272,6 +275,13 @@ void __ref cpu_die(void)
>  {
>  	unsigned int cpu = smp_processor_id();
>  
> +	/*
> +	 * We dont need the CPU device anymore.
> +	 * Lets do this before IRQs are disabled to allow
> +	 * runtime PM to suspend the domain as well.
> +	 */
> +	pm_runtime_put_sync(get_cpu_device(cpu));

The two put calls is confusing. __cpu_disable() is called on the
CPU that's dying, and cpu_die() is called on the CPU that's doing
the takedown. That would be two decrements but only one increment
in secondary_start_kernel()? How is this properly balanced?

> +
>  	idle_task_exit();
>  
>  	local_irq_disable();
> @@ -401,6 +412,11 @@ asmlinkage void secondary_start_kernel(void)
>  	local_irq_enable();
>  	local_fiq_enable();
>  
> +	/* We are running, enable runtime PM for the CPU. */
> +	cpu_dev = get_cpu_device(cpu);
> +	if (cpu_dev)
> +		pm_runtime_get_sync(cpu_dev);

Also, where would the dev->power.irq_safe flag be set if we
aren't using the genpd DT stuff? It looks like we're going to
start causing warnings on devices that don't have the DT magic.
Please add a hotplug test with some device that isn't using this
genpd code to catch problems. Also please turn on lockdep and RCU
lockdep, touching the idle code like this

-- 
Qualcomm Innovation Center, Inc. is a member of Code Aurora Forum,
a Linux Foundation Collaborative Project


From horms at verge.net.au  Wed Aug 12 17:05:38 2015
From: horms at verge.net.au (Simon Horman)
Date: Thu, 13 Aug 2015 09:05:38 +0900
Subject: [PATCH v2] ARM: shmobile: kzm9g dts: Use adxl345-specific
 compatible property
In-Reply-To: <20150708005148.GA28100@verge.net.au>
References: <1436180132-26190-1-git-send-email-geert+renesas@glider.be>
 <15966074.zDS67FO48r@avalon> <20150707002621.GD13326@verge.net.au>
 <9389528.5qtaECVqX7@avalon> <20150708005148.GA28100@verge.net.au>
Message-ID: <20150813000537.GD5221@verge.net.au>

On Wed, Jul 08, 2015 at 09:51:49AM +0900, Simon Horman wrote:
> On Tue, Jul 07, 2015 at 09:56:29AM +0300, Laurent Pinchart wrote:
> > Hi Simon,
> > 
> > On Tuesday 07 July 2015 09:26:21 Simon Horman wrote:
> > > On Mon, Jul 06, 2015 at 04:29:33PM +0300, Laurent Pinchart wrote:
> > > > On Monday 06 July 2015 12:55:32 Geert Uytterhoeven wrote:
> > > > > Replace the deprecated generic "adi,adxl34x" compatible value by the
> > > > > adxl345-specific "adi,adxl345" value, cfr. commit e465bf6fc55d5ce2 ("DT:
> > > > > i2c: Deprecate adi,adxl34x compatible string").
> > > > > 
> > > > > Signed-off-by: Geert Uytterhoeven <geert+renesas at glider.be>
> > > > 
> > > > Acked-by: Laurent Pinchart <laurent.pinchart+renesas at ideasonboard.com>
> > > > 
> > > > > ---
> > > > > Depends on commit 3a38958d2477b718 ("Input: adxl34x - add OF match
> > > > > support"), which is in v4.2-rc1.
> > > > > 
> > > > > This is v2 of "ARM: shmobile: kzm9g dts: Add adxl345-specific compatible
> > > > > property".
> > > 
> > > It appears to me that this will cause a regression when booting old kernels
> > > with new dts blobs. For that reason think we should consider v1
> > > of this change coupled with a schedule to remove use of the deprecated
> > > compat string.
> > 
> > That's the forward compatibility that Geert mentioned, is that really an 
> > issue, especially on this board ?
> 
> I think it would be best to provide backwards compatibility unless there
> is a compelling reason not to.

I would like to revisit this discussion with a view to getting some version
of this patch queued up (yes I know I pushed back on it earlier in this thread).


From shawn.lin at rock-chips.com  Wed Aug 12 17:08:22 2015
From: shawn.lin at rock-chips.com (Shawn Lin)
Date: Thu, 13 Aug 2015 08:08:22 +0800
Subject: [RFC PATCH v4 3/9] mips: pistachio_defconfig: remove
 CONFIG_MMC_DW_IDMAC
In-Reply-To: <20150812220500.GD11636@linux-mips.org>
References: <1438843469-23807-1-git-send-email-shawn.lin@rock-chips.com>
 <1438843515-23935-1-git-send-email-shawn.lin@rock-chips.com>
 <20150812220500.GD11636@linux-mips.org>
Message-ID: <55CBDFF6.9090900@rock-chips.com>

? 2015/8/13 6:05, Ralf Baechle ??:
> On Thu, Aug 06, 2015 at 02:45:15PM +0800, Shawn Lin wrote:
>
>> DesignWare MMC Controller's transfer mode should be decided
>> at runtime instead of compile-time. So we remove this config
>> option and read dw_mmc's register to select DMA master.
>>
>> Signed-off-by: Shawn Lin <shawn.lin at rock-chips.com>
>> ---
>>
>> Changes in v4: None
>> Changes in v3: None
>> Changes in v2: None
>>
>>   arch/mips/configs/pistachio_defconfig | 1 -
>
> Acked-by: Ralf Baechle <ralf at linux-mips.org>
>
> Please feel free to merge this patch with the remainder
> of the series.
>

Thanks, Ralf. :)

v5 is coming which will be rebased on 
"https://github.com/jh80chung/dw-mmc.git tags/dw-mmc-for-ulf-v4.2" for 
the next merge window
that make Jeahoon do it easier. Also define new macro for reading
HCON register suggested by Joachim.


>    Ralf
>
>
>


-- 
Shawn Lin



From kgene at kernel.org  Wed Aug 12 17:11:55 2015
From: kgene at kernel.org (Kukjin Kim)
Date: Thu, 13 Aug 2015 09:11:55 +0900
Subject: [GIT PULL 2nd 1/4] Samsung defconfig updates for v4.3
Message-ID: <55CBE0CB.1060708@kernel.org>

The following changes since commit d770e558e21961ad6cfdf0ff7df0eb5d7d4f0754:

  Linux 4.2-rc1 (2015-07-05 11:01:52 -0700)

are available in the git repository at:

  git://git.kernel.org/pub/scm/linux/kernel/git/kgene/linux-samsung.git
tags/samsung-defconfig-1

for you to fetch changes up to c3e71f4b5f580b43e0eb3be18059c8844d8713e7:

  ARM: multi_v7_defconfig: Enable max77802 regulator (2015-08-12
08:15:02 +0900)

----------------------------------------------------------------
Samsung defconfig updates for v4.3

- for exynos_defconfig
  : enable SND_SOC_ODROIDX2 and SND_SIMPLE_CARD for
    Odroid-XU3 to use max98090 audio codec
  : enalbe SENSORS_NTC_THERMISTOR for Peach boards

- for multi_v7_defconfig:
  : remove SAMSUNG_USB2PHY and SAMSUNG_USB3PHY are not used now
  : enable SENSORS_NTC_THERMISTOR and EXYNOS_ADC for Peach boards
  : enable REGULATOR_MAX77802 for Peach boards

----------------------------------------------------------------
Anand Moon (1):
      ARM: exynos_defconfig: Enable CONFIG_SND_SOC_ODROIDX2 for Odroid-XU3

Javier Martinez Canillas (4):
      ARM: multi_v7_defconfig: Remove old Samsung USB PHY configs
      ARM: multi_v7_defconfig: Enable NTC Thermistors support
      ARM: exynos_defconfig: Enable NTC Thermistors support
      ARM: multi_v7_defconfig: Enable max77802 regulator

 arch/arm/configs/exynos_defconfig   | 3 +++
 arch/arm/configs/multi_v7_defconfig | 5 +++--
 2 files changed, 6 insertions(+), 2 deletions(-)


From kgene at kernel.org  Wed Aug 12 17:12:34 2015
From: kgene at kernel.org (Kukjin Kim)
Date: Thu, 13 Aug 2015 09:12:34 +0900
Subject: [GIT PULL 2nd 2/4] Samsung DT 3rd updates for v4.3
Message-ID: <55CBE0F2.4020104@kernel.org>

Hi Arnd, Olof, Kevin

This is based on tags/samsung-dt-2 and including exynos4 related clock
changes to support cpufreq-dt driver for exynos4 SoCs. Note that I've
created one more clk topic branch called v4.3-topic/clk-samsung-2 based
on previous one has been merged by Mike into clock tree before but I'm
not sure new one merged into clk tree that's why I've noted its merge in
this signed tag.

Please pull.

Thanks,
Kukjin


The following changes since commit 71ae9acc2e3b4b85a08c65e7f411d110b786ca1d:

  ARM: dts: Add SPI CS on exynos5250-snow (2015-07-30 23:12:43 +0900)

are available in the git repository at:

  git://git.kernel.org/pub/scm/linux/kernel/git/kgene/linux-samsung.git
tags/samsung-dt-3

for you to fetch changes up to 99f610d89b5bb1852742165b94ab99a8f63af6a9:

  ARM: dts: add CPU OPP and regulator supply property for exynos4x12
(2015-08-12 07:38:45 +0900)

----------------------------------------------------------------
Samsung 3rd DT updates for v4.3

- add CPU OPP and regulator for exynos4212 and 4412
  based on adding regarding cpu clock configuration

----------------------------------------------------------------
Bartlomiej Zolnierkiewicz (2):
      clk: exynos4x12: add cpu clock configuration data and instantiate
cpu clock
      ARM: dts: add CPU OPP and regulator supply property for exynos4x12

Kukjin Kim (1):
      Merge branch 'v4.3-topic/clk-samsung-2' into v4.3-next/dt-samsung-3

 arch/arm/boot/dts/exynos4212.dtsi               | 81
++++++++++++++++++++++++
 arch/arm/boot/dts/exynos4412-odroid-common.dtsi |  4 ++
 arch/arm/boot/dts/exynos4412-origen.dts         |  4 ++
 arch/arm/boot/dts/exynos4412-trats2.dts         |  4 ++
 arch/arm/boot/dts/exynos4412.dtsi               | 83
+++++++++++++++++++++++++
 drivers/clk/samsung/clk-exynos4.c               | 50 +++++++++++++++
 6 files changed, 226 insertions(+)


From kgene at kernel.org  Wed Aug 12 17:12:59 2015
From: kgene at kernel.org (Kukjin Kim)
Date: Thu, 13 Aug 2015 09:12:59 +0900
Subject: [GIT PULL 2nd 3/4] Samsung driver 2nd updates for v4.3
Message-ID: <55CBE10B.2030103@kernel.org>

Hi,

I've created the signed tag based on previous tags/samsung-driver so you
can see several merge in there. To support cpufreq-dt driver requires
clk/cpufreq/exynos changes together and clk/cpufreq maintainers are
aware of this changes. And we can remove exynos cpufreq driver at last.

Note this drivers update is including previous dependencies and if
you're OK, please pull.

Thanks,
Kukjin


The following changes since commit 6b1621c4a15b9110cda7cc2e2eb3e8e1a0c2bcfc:

  ARM: EXYNOS: Add exynos3250 compatible to use generic cpufreq driver
(2015-08-04 15:59:33 +0900)

are available in the git repository at:

  git://git.kernel.org/pub/scm/linux/kernel/git/kgene/linux-samsung.git
tags/samsung-driver-2

for you to fetch changes up to 50ef057c78ba7141b502f85ca1035e9c45612f4e:

  Merge branch 'v4.3-topic/cpufreq-samsung-2' into
v4.3-next/clk-cpufreq-samsung-2 (2015-08-12 07:44:59 +0900)

----------------------------------------------------------------

Samsung 2nd driver updates for v4.3

- add generic cpufreq driver for exynos4212 and 4412

- remove exynos4 SoCs specific cpufreq driver will not
  be used more and acked by cpufreq maintainer Viresh

Note this is based on tags/samsung-driver + tags/samsung-dt-3
to support cpufreq-dt driver for Exynos SoCs 3250, 4210, 4412
and 5250 finally

----------------------------------------------------------------
Bartlomiej Zolnierkiewicz (4):
      clk: exynos4x12: add cpu clock configuration data and instantiate
cpu clock
      ARM: dts: add CPU OPP and regulator supply property for exynos4x12
      ARM: EXYNOS: switch to using generic cpufreq driver for exynos4x12
      cpufreq: exynos: remove Exynos4x12 specific cpufreq driver support

Kukjin Kim (3):
      Merge branch 'v4.3-topic/clk-samsung-2' into v4.3-next/dt-samsung-3
      Merge branch 'v4.3-next/dt-samsung-3' into
v4.3-next/clk-cpufreq-samsung-2
      Merge branch 'v4.3-topic/cpufreq-samsung-2' into
v4.3-next/clk-cpufreq-samsung-2

 arch/arm/boot/dts/exynos4212.dtsi               |  81 ++++++++
 arch/arm/boot/dts/exynos4412-odroid-common.dtsi |   4 +
 arch/arm/boot/dts/exynos4412-origen.dts         |   4 +
 arch/arm/boot/dts/exynos4412-trats2.dts         |   4 +
 arch/arm/boot/dts/exynos4412.dtsi               |  83 +++++++++
 arch/arm/mach-exynos/Kconfig                    |   2 +
 arch/arm/mach-exynos/exynos.c                   |   2 +
 drivers/clk/samsung/clk-exynos4.c               |  50 +++++
 drivers/cpufreq/Kconfig.arm                     |  38 ----
 drivers/cpufreq/Makefile                        |   2 -
 drivers/cpufreq/exynos-cpufreq.c                | 234
-----------------------
 drivers/cpufreq/exynos-cpufreq.h                |  72 --------
 drivers/cpufreq/exynos4x12-cpufreq.c            | 236
------------------------
 13 files changed, 230 insertions(+), 582 deletions(-)
 delete mode 100644 drivers/cpufreq/exynos-cpufreq.c
 delete mode 100644 drivers/cpufreq/exynos-cpufreq.h
 delete mode 100644 drivers/cpufreq/exynos4x12-cpufreq.c


From kgene at kernel.org  Wed Aug 12 17:13:12 2015
From: kgene at kernel.org (Kukjin Kim)
Date: Thu, 13 Aug 2015 09:13:12 +0900
Subject: [GIT PULL 2nd 4/4] Samsung defconfig 2nd update for v4.3
Message-ID: <55CBE118.7060000@kernel.org>

Here is enable cpufreq-dt driver for exynos stuff.

Please pull and sorry for little bit confused branches in this time...

Thanks,
Kukjin


The following changes since commit c3e71f4b5f580b43e0eb3be18059c8844d8713e7:

  ARM: multi_v7_defconfig: Enable max77802 regulator (2015-08-12
08:15:02 +0900)

are available in the git repository at:

  git://git.kernel.org/pub/scm/linux/kernel/git/kgene/linux-samsung.git
tags/samsung-defconfig-2

for you to fetch changes up to 2b347c6494cbc6bfdc81b5201b8aa34afb2c3500:

  ARM: exynos_defconfig: Enable cpufreq-dt driver (2015-08-12 08:17:31
+0900)

----------------------------------------------------------------
Samsung 2nd defconfig updates for v4.3

- enable cpufreq-dt driver with ONDEMAND governor
  for Exynos SoCs 3250, 4210, 4212, 4412 and 5250

----------------------------------------------------------------
Krzysztof Kozlowski (1):
      ARM: exynos_defconfig: Enable cpufreq-dt driver

 arch/arm/configs/exynos_defconfig | 2 ++
 1 file changed, 2 insertions(+)


From k.kozlowski at samsung.com  Wed Aug 12 17:38:10 2015
From: k.kozlowski at samsung.com (Krzysztof Kozlowski)
Date: Thu, 13 Aug 2015 09:38:10 +0900
Subject: [PATCH] ARM: dts: exynos4412-odroidu3: Enable SPI1.
In-Reply-To: <1439378871-28117-1-git-send-email-aballier@gentoo.org>
References: <1439378871-28117-1-git-send-email-aballier@gentoo.org>
Message-ID: <55CBE6F2.9030405@samsung.com>

On 12.08.2015 20:27, Alexis Ballier wrote:
> SPI1 is available on IO Port #2 (as depicted on their website) in
> PCB Revision 0.5 of Hardkernel Odroid U3 board.
> The shield connects a 256KiB spi-nor flash on that bus.
> 
> Signed-off-by: Alexis Ballier <aballier at gentoo.org>
> ---
>  arch/arm/boot/dts/exynos4412-odroidu3.dts | 7 +++++++
>  1 file changed, 7 insertions(+)
> 
> diff --git a/arch/arm/boot/dts/exynos4412-odroidu3.dts b/arch/arm/boot/dts/exynos4412-odroidu3.dts
> index 44684e5..37698e4 100644
> --- a/arch/arm/boot/dts/exynos4412-odroidu3.dts
> +++ b/arch/arm/boot/dts/exynos4412-odroidu3.dts
> @@ -61,3 +61,10 @@
>  		"Speakers", "SPKL",
>  		"Speakers", "SPKR";
>  };
> +
> +&spi_1 {
> +	pinctrl-names = "default";
> +	pinctrl-0 = <&spi1_bus>;
> +	cs-gpios = <&gpb 5 0>;

Please use GPIO_ACTIVE_HIGH.

Best regards,
Krzysztof

> +	status = "okay";
> +};
> 



From rjw at rjwysocki.net  Wed Aug 12 18:20:35 2015
From: rjw at rjwysocki.net (Rafael J. Wysocki)
Date: Thu, 13 Aug 2015 03:20:35 +0200
Subject: 3.18: lockdep problems in cpufreq
In-Reply-To: <20150811170357.GA24529@n2100.arm.linux.org.uk>
References: <20141214213655.GA11285@n2100.arm.linux.org.uk>
 <2574268.XBqpdL2VLI@vostro.rjw.lan>
 <20150811170357.GA24529@n2100.arm.linux.org.uk>
Message-ID: <5160300.5D2Dvly8u9@vostro.rjw.lan>

On Tuesday, August 11, 2015 06:03:57 PM Russell King - ARM Linux wrote:
> On Tue, May 19, 2015 at 12:05:55AM +0200, Rafael J. Wysocki wrote:
> > On Monday, May 18, 2015 07:56:45 PM Russell King - ARM Linux wrote:
> > > On Tue, Dec 16, 2014 at 09:11:53AM +0530, Viresh Kumar wrote:
> > > > On 16 December 2014 at 04:39, Russell King - ARM Linux
> > > > <linux at arm.linux.org.uk> wrote:
> > > > > Well, here's a patch which I'm running on top of 3.18 at the moment,
> > > > > which is basically what I described in my email, and I'm running with it
> > > > > and it is without any lockdep complaint.
> > > > 
> > > > We need two separate patches now, one for 3.18 and other one for 3.19-rc.
> > > > 3.19 has see lots of changes in this particular file and so we need to
> > > > change few things here.
> > > 
> > > What happened with this?  I'm still carrying the patch.
> > 
> > This should go in through the thermal tree.  Eduardo?
> 
> Having waited a long time for any kind of response from Eduardo, I've
> given up.  My conclusion is that Eduardo isn't interested in this.
> 
> I've re-checked, and the AB-BA deadlock is still there in the latest
> code.  So, I've taken it upon myself to throw this into my for-next
> branch to force the issue - not something I _want_ to do, but I'm doing
> this out of frustration.  It's clear to me that "playing nice" by email
> does _not_ work with some people.
> 
> I'm rather hoping that Stephen reports a merge conflict with linux-next
> this evening to highlight this situation.  I've added additional commentry
> to the commit message on the patch giving the reason why I've done this,
> and the relevant message IDs showing the past history.
> 
> I've not decided whether I'm going to ask Linus to take this patch
> directly or not, that rather depends whether there's any co-operation
> from Eduardo on this.  I'd rather Eduardo took the patch.
> 
> The patch I have has had to be updated again for changes to the driver,
> but I really don't see the point of re-posting it just for it to be
> ignored yet again.
> 
> I'm really disappointed by this dysfunctional state of affairs, and
> that what should be an urgent fix for an observable problem is still
> not merged some nine months after it was first identified.

I guess it might help if you sent the updated patch in a new thread.


-- 
I speak only for myself.
Rafael J. Wysocki, Intel Open Source Technology Center.


From eric at anholt.net  Wed Aug 12 17:56:13 2015
From: eric at anholt.net (Eric Anholt)
Date: Wed, 12 Aug 2015 17:56:13 -0700
Subject: Raspberry Pi KMS-only driver
Message-ID: <1439427380-2436-1-git-send-email-eric@anholt.net>

Here's the first patch series for graphics on the Raspberry Pi.  It
brings up fbcon on KMS, and the xf86-video-modesetting driver runs so
you can do X with no further userspace drivers.

Right now this series doesn't support changing video modes away from
the firmware boot setup, because when I set the pixel clock using the
rpi-dt-clocks series I end up with a black display. even on no-op
modesets.

I've dropped all of the 3D bits from this series, to simplify this
review stage.  See vc4-kms-v3d-rpi2 for a series that works with the
current Mesa driver, based on downstream 2709.  I squashed all of my
messy KMS series down, but kept Derek's patches separate to make sure
he gets credit.

This code can also be found at:

https://github.com/anholt/linux/tree/vc4-kms-squash



From eric at anholt.net  Wed Aug 12 17:56:15 2015
From: eric at anholt.net (Eric Anholt)
Date: Wed, 12 Aug 2015 17:56:15 -0700
Subject: [PATCH 2/7] MAINTAINERS: Add myself for the new VC4 (RPi GPU)
 graphics driver.
In-Reply-To: <1439427380-2436-1-git-send-email-eric@anholt.net>
References: <1439427380-2436-1-git-send-email-eric@anholt.net>
Message-ID: <1439427380-2436-3-git-send-email-eric@anholt.net>

Signed-off-by: Eric Anholt <eric at anholt.net>
---
 MAINTAINERS | 6 ++++++
 1 file changed, 6 insertions(+)

diff --git a/MAINTAINERS b/MAINTAINERS
index 8133cef..d0dc42c 100644
--- a/MAINTAINERS
+++ b/MAINTAINERS
@@ -3573,6 +3573,12 @@ S:	Maintained
 F:	drivers/gpu/drm/rockchip/
 F:	Documentation/devicetree/bindings/video/rockchip*
 
+DRM DRIVERS FOR VC4
+M:	Eric Anholt <eric at anholt.net>
+T:	git git://github.com/anholt/linux
+S:	Maintained
+F:	drivers/gpu/drm/vc4/*
+
 DSBR100 USB FM RADIO DRIVER
 M:	Alexey Klimov <klimov.linux at gmail.com>
 L:	linux-media at vger.kernel.org
-- 
2.1.4



From eric at anholt.net  Wed Aug 12 17:56:14 2015
From: eric at anholt.net (Eric Anholt)
Date: Wed, 12 Aug 2015 17:56:14 -0700
Subject: [PATCH 1/7] drm/vc4: Add devicetree bindings for VC4.
In-Reply-To: <1439427380-2436-1-git-send-email-eric@anholt.net>
References: <1439427380-2436-1-git-send-email-eric@anholt.net>
Message-ID: <1439427380-2436-2-git-send-email-eric@anholt.net>

Signed-off-by: Eric Anholt <eric at anholt.net>
---
 .../devicetree/bindings/gpu/brcm,bcm-vc4.txt       | 83 ++++++++++++++++++++++
 1 file changed, 83 insertions(+)
 create mode 100644 Documentation/devicetree/bindings/gpu/brcm,bcm-vc4.txt

diff --git a/Documentation/devicetree/bindings/gpu/brcm,bcm-vc4.txt b/Documentation/devicetree/bindings/gpu/brcm,bcm-vc4.txt
new file mode 100644
index 0000000..2b13e61
--- /dev/null
+++ b/Documentation/devicetree/bindings/gpu/brcm,bcm-vc4.txt
@@ -0,0 +1,83 @@
+Broadcom VC4 GPU
+
+The VC4 device present on the Raspberry Pi includes a display system
+with HDMI output and the HVS scaler for compositing display planes.
+
+Required properties for VC4:
+- compatible:	Should be "brcm,vc4"
+- crtcs:	List of references to pixelvalve scanout engines
+- hvss:		List of references to HVS video scalers
+- encoders:	List of references to output encoders (HDMI, SDTV)
+
+Required properties for Pixel Valve:
+- compatible:	Should be "brcm,vc4-pixelvalve"
+- reg:		Physical base address and length of the PV's registers
+- interrupts:	The interrupt number
+		  See bindings/interrupt-controller/brcm,bcm2835-armctrl-ic.txt
+
+Required properties for HVS:
+- compatible:	Should be "brcm,vc4-hvs"
+- reg:		Physical base address and length of the HVS's registers
+- interrupts:	The interrupt number
+		  See bindings/interrupt-controller/brcm,bcm2835-armctrl-ic.txt
+
+Required properties for HDMI
+- compatible:	Should be "brcm,vc4-hdmi"
+- reg:		Physical base address and length of the two register ranges
+		  ("HDMI" and "HD")
+- interrupts:	The interrupt numbers
+		  See bindings/interrupt-controller/brcm,bcm2835-armctrl-ic.txt
+- ddc:		phandle of the I2C controller used for DDC EDID probing
+- crtc:		phandle to the pixelvalve CRTC the HDMI encoder is attached to
+
+Optional properties for HDMI:
+- hpd-gpio:	The GPIO pin for HDMI hotplug detect (if it doesn't appear
+		  as an interrupt/status bit in the HDMI controller
+		  itself).  See bindings/pinctrl/brcm,bcm2835-gpio.txt
+
+Example:
+/ {
+	soc {
+		pv0: brcm,vc4-pixelvalve at 7e206000 {
+			compatible = "brcm,vc4-pixelvalve";
+			reg = <0x7e206000 0x100>;
+			interrupts = <2 13>; /* pwa2 */
+		};
+
+		pv1: brcm,vc4-pixelvalve at 7e207000 {
+			compatible = "brcm,vc4-pixelvalve";
+			reg = <0x7e207000 0x100>;
+			interrupts = <2 14>; /* pwa1 */
+		};
+
+		pv2: brcm,vc4-pixelvalve at 7e807000 {
+			compatible = "brcm,vc4-pixelvalve";
+			reg = <0x7e807000 0x100>;
+			interrupts = <2 10>; /* pixelvalve */
+		};
+
+		hvs: brcm,hvs at 7e400000 {
+			compatible = "brcm,vc4-hvs";
+			reg = <0x7e400000 0x6000>;
+			interrupts = <2 1>;
+		};
+
+		hdmi: brcm,vc4-hdmi at 7e902000 {
+			compatible = "brcm,vc4-hdmi";
+			reg = <0x7e902000 0x600>,
+			      <0x7e808000 0x100>;
+			interrupts = <2 8>, <2 9>;
+			ddc = <&i2c2>;
+			hpd-gpio = <&gpio 46 GPIO_ACTIVE_HIGH>;
+			crtc = <&pv2>;
+		};
+
+		vc4: vc4 at 0x7e4c0000 {
+			compatible = "brcm,vc4";
+
+			crtcs = <&pv0>, <&pv1>, <&pv2>;
+			encoders = <&hdmi>;
+			hvss = <&hvs>;
+		};
+	};
+};
-- 
2.1.4



From eric at anholt.net  Wed Aug 12 17:56:17 2015
From: eric at anholt.net (Eric Anholt)
Date: Wed, 12 Aug 2015 17:56:17 -0700
Subject: [PATCH 4/7] drm/vc4: Use the fbdev_cma helpers
In-Reply-To: <1439427380-2436-1-git-send-email-eric@anholt.net>
References: <1439427380-2436-1-git-send-email-eric@anholt.net>
Message-ID: <1439427380-2436-5-git-send-email-eric@anholt.net>

From: Derek Foreman <derekf at osg.samsung.com>

Keep the fbdev_cma pointer around so we can use it on hotplog and close
to ensure the frame buffer console is in a useful state.

Signed-off-by: Derek Foreman <derekf at osg.samsung.com>
Signed-off-by: Eric Anholt <eric at anholt.net>
---
 drivers/gpu/drm/vc4/vc4_drv.c | 15 +++++++++++++++
 drivers/gpu/drm/vc4/vc4_drv.h |  2 ++
 drivers/gpu/drm/vc4/vc4_kms.c | 18 +++++++++++++++---
 3 files changed, 32 insertions(+), 3 deletions(-)

diff --git a/drivers/gpu/drm/vc4/vc4_drv.c b/drivers/gpu/drm/vc4/vc4_drv.c
index 9ecf4b8b..90414d1 100644
--- a/drivers/gpu/drm/vc4/vc4_drv.c
+++ b/drivers/gpu/drm/vc4/vc4_drv.c
@@ -14,6 +14,7 @@
 #include <linux/module.h>
 #include <linux/of_platform.h>
 #include <linux/platform_device.h>
+#include "drm_fb_cma_helper.h"
 
 #include "vc4_drv.h"
 #include "vc4_regs.h"
@@ -70,6 +71,11 @@ static int vc4_drm_load(struct drm_device *dev, unsigned long flags)
 
 static int vc4_drm_unload(struct drm_device *dev)
 {
+	struct vc4_dev *vc4 = to_vc4_dev(dev);
+
+	if (vc4->fbdev)
+		drm_fbdev_cma_fini(vc4->fbdev);
+
 	drm_mode_config_cleanup(dev);
 
 	component_unbind_all(dev->dev, dev);
@@ -85,6 +91,14 @@ static void vc4_drm_preclose(struct drm_device *dev, struct drm_file *file)
 		vc4_cancel_page_flip(crtc, file);
 }
 
+static void vc4_lastclose(struct drm_device *dev)
+{
+	struct vc4_dev *vc4 = to_vc4_dev(dev);
+
+	if (vc4->fbdev)
+		drm_fbdev_cma_restore_mode(vc4->fbdev);
+}
+
 static const struct file_operations vc4_drm_fops = {
 	.owner = THIS_MODULE,
 	.open = drm_open,
@@ -109,6 +123,7 @@ static struct drm_driver vc4_drm_driver = {
 			    DRIVER_PRIME),
 	.load = vc4_drm_load,
 	.unload = vc4_drm_unload,
+	.lastclose = vc4_lastclose,
 	.set_busid = drm_platform_set_busid,
 	.preclose = vc4_drm_preclose,
 
diff --git a/drivers/gpu/drm/vc4/vc4_drv.h b/drivers/gpu/drm/vc4/vc4_drv.h
index 1b0a0b0..6edc14b 100644
--- a/drivers/gpu/drm/vc4/vc4_drv.h
+++ b/drivers/gpu/drm/vc4/vc4_drv.h
@@ -15,6 +15,8 @@ struct vc4_dev {
 	struct vc4_hdmi *hdmi;
 	struct vc4_hvs *hvs;
 	struct vc4_crtc *crtc[3];
+
+	struct drm_fbdev_cma *fbdev;
 };
 
 static inline struct vc4_dev *
diff --git a/drivers/gpu/drm/vc4/vc4_kms.c b/drivers/gpu/drm/vc4/vc4_kms.c
index e5e96bc..a34439f 100644
--- a/drivers/gpu/drm/vc4/vc4_kms.c
+++ b/drivers/gpu/drm/vc4/vc4_kms.c
@@ -21,7 +21,16 @@
 #include "drm_fb_cma_helper.h"
 #include "vc4_drv.h"
 
+static void vc4_output_poll_changed(struct drm_device *dev)
+{
+	struct vc4_dev *vc4 = to_vc4_dev(dev);
+
+	if (vc4->fbdev)
+		drm_fbdev_cma_hotplug_event(vc4->fbdev);
+}
+
 static const struct drm_mode_config_funcs vc4_mode_funcs = {
+	.output_poll_changed = vc4_output_poll_changed,
 	.atomic_check = drm_atomic_helper_check,
 	.atomic_commit = drm_atomic_helper_commit,
 	.fb_create = drm_fb_cma_create,
@@ -54,6 +63,7 @@ fail:
 
 int vc4_kms_load(struct drm_device *dev)
 {
+	struct vc4_dev *vc4 = to_vc4_dev(dev);
 	int ret;
 
 	ret = drm_vblank_init(dev, dev->mode_config.num_crtc);
@@ -73,9 +83,11 @@ int vc4_kms_load(struct drm_device *dev)
 
 	drm_mode_config_reset(dev);
 
-	drm_fbdev_cma_init(dev, 32,
-			   dev->mode_config.num_crtc,
-			   dev->mode_config.num_connector);
+	vc4->fbdev = drm_fbdev_cma_init(dev, 32,
+					dev->mode_config.num_crtc,
+					dev->mode_config.num_connector);
+	if (IS_ERR(vc4->fbdev))
+		vc4->fbdev = NULL;
 
 	drm_kms_helper_poll_init(dev);
 
-- 
2.1.4



From eric at anholt.net  Wed Aug 12 17:56:18 2015
From: eric at anholt.net (Eric Anholt)
Date: Wed, 12 Aug 2015 17:56:18 -0700
Subject: [PATCH 5/7] drm/vc4: Allow vblank to be disabled
In-Reply-To: <1439427380-2436-1-git-send-email-eric@anholt.net>
References: <1439427380-2436-1-git-send-email-eric@anholt.net>
Message-ID: <1439427380-2436-6-git-send-email-eric@anholt.net>

From: Derek Foreman <derekf at osg.samsung.com>

Signed-off-by: Derek Foreman <derekf at osg.samsung.com>
Signed-off-by: Eric Anholt <eric at anholt.net>
---
 drivers/gpu/drm/vc4/vc4_kms.c | 2 ++
 1 file changed, 2 insertions(+)

diff --git a/drivers/gpu/drm/vc4/vc4_kms.c b/drivers/gpu/drm/vc4/vc4_kms.c
index a34439f..f881cd4 100644
--- a/drivers/gpu/drm/vc4/vc4_kms.c
+++ b/drivers/gpu/drm/vc4/vc4_kms.c
@@ -77,6 +77,8 @@ int vc4_kms_load(struct drm_device *dev)
 	dev->mode_config.funcs = &vc4_mode_funcs;
 	dev->mode_config.preferred_depth = 24;
 
+	dev->vblank_disable_allowed = true;
+
 	ret = vc4_init_modeset_objects(dev);
 	if (ret)
 		goto fail;
-- 
2.1.4



From eric at anholt.net  Wed Aug 12 17:56:20 2015
From: eric at anholt.net (Eric Anholt)
Date: Wed, 12 Aug 2015 17:56:20 -0700
Subject: [PATCH 7/7] ARM: bcm2835: Add VC4 to the device tree.
In-Reply-To: <1439427380-2436-1-git-send-email-eric@anholt.net>
References: <1439427380-2436-1-git-send-email-eric@anholt.net>
Message-ID: <1439427380-2436-8-git-send-email-eric@anholt.net>

Signed-off-by: Eric Anholt <eric at anholt.net>
---
 arch/arm/boot/dts/bcm2835.dtsi | 43 ++++++++++++++++++++++++++++++++++++++++++
 1 file changed, 43 insertions(+)

diff --git a/arch/arm/boot/dts/bcm2835.dtsi b/arch/arm/boot/dts/bcm2835.dtsi
index 8f3ba88..dda67aa 100644
--- a/arch/arm/boot/dts/bcm2835.dtsi
+++ b/arch/arm/boot/dts/bcm2835.dtsi
@@ -1,4 +1,5 @@
 #include <dt-bindings/pinctrl/bcm2835.h>
+#include <dt-bindings/gpio/gpio.h>
 #include "skeleton.dtsi"
 
 / {
@@ -167,6 +168,48 @@
 		arm-pmu {
 			compatible = "arm,arm1176-pmu";
 		};
+
+		hdmi: brcm,vc4-hdmi at 7e902000 {
+			compatible = "brcm,vc4-hdmi";
+			reg = <0x7e902000 0x600>,
+			      <0x7e808000 0x100>;
+			interrupts = <2 8>, <2 9>;
+			ddc = <&i2c2>;
+			hpd-gpio = <&gpio 46 GPIO_ACTIVE_HIGH>;
+			crtc = <&pv2>;
+		};
+
+		pv0: brcm,vc4-pixelvalve at 7e206000 {
+			compatible = "brcm,vc4-pixelvalve";
+			reg = <0x7e206000 0x100>;
+			interrupts = <2 13>; /* pwa2 */
+		};
+
+		pv1: brcm,vc4-pixelvalve at 7e207000 {
+			compatible = "brcm,vc4-pixelvalve";
+			reg = <0x7e207000 0x100>;
+			interrupts = <2 14>; /* pwa1 */
+		};
+
+		pv2: brcm,vc4-pixelvalve at 7e807000 {
+			compatible = "brcm,vc4-pixelvalve";
+			reg = <0x7e807000 0x100>;
+			interrupts = <2 10>; /* pixelvalve */
+		};
+
+		hvs: brcm,hvs at 7e400000 {
+			compatible = "brcm,vc4-hvs";
+			reg = <0x7e400000 0x6000>;
+			interrupts = <2 1>;
+		};
+
+		vc4: vc4 at 0x7e4c0000 {
+			compatible = "brcm,vc4";
+
+			crtcs = <&pv0>, <&pv1>, <&pv2>;
+			encoders = <&hdmi>;
+			hvss = <&hvs>;
+		};
 	};
 
 	clocks {
-- 
2.1.4



From eric at anholt.net  Wed Aug 12 17:56:19 2015
From: eric at anholt.net (Eric Anholt)
Date: Wed, 12 Aug 2015 17:56:19 -0700
Subject: [PATCH 6/7] ARM: bcm2835: Add the DDC I2C controller to the device
 tree.
In-Reply-To: <1439427380-2436-1-git-send-email-eric@anholt.net>
References: <1439427380-2436-1-git-send-email-eric@anholt.net>
Message-ID: <1439427380-2436-7-git-send-email-eric@anholt.net>

We need to use it for getting video modes over HDMI.

Signed-off-by: Eric Anholt <eric at anholt.net>
---
 arch/arm/boot/dts/bcm2835.dtsi | 9 +++++++++
 1 file changed, 9 insertions(+)

diff --git a/arch/arm/boot/dts/bcm2835.dtsi b/arch/arm/boot/dts/bcm2835.dtsi
index 301c73f..8f3ba88 100644
--- a/arch/arm/boot/dts/bcm2835.dtsi
+++ b/arch/arm/boot/dts/bcm2835.dtsi
@@ -149,6 +149,15 @@
 			status = "disabled";
 		};
 
+		i2c2: i2c at 7e805000 {
+			compatible = "brcm,bcm2835-i2c";
+			reg = <0x7e805000 0x1000>;
+			interrupts = <2 21>;
+			clocks = <&clk_i2c>;
+			#address-cells = <1>;
+			#size-cells = <0>;
+		};
+
 		usb at 7e980000 {
 			compatible = "brcm,bcm2835-usb";
 			reg = <0x7e980000 0x10000>;
-- 
2.1.4



From eric at anholt.net  Wed Aug 12 17:56:16 2015
From: eric at anholt.net (Eric Anholt)
Date: Wed, 12 Aug 2015 17:56:16 -0700
Subject: [PATCH 3/7] drm/vc4: Add KMS support for Raspberry Pi.
In-Reply-To: <1439427380-2436-1-git-send-email-eric@anholt.net>
References: <1439427380-2436-1-git-send-email-eric@anholt.net>
Message-ID: <1439427380-2436-4-git-send-email-eric@anholt.net>

This is the start of a full VC4 driver.  Right now this just supports
configuring the display using a pre-existing video mode (because
changing the pixel clock isn't available yet, and doesn't work when it
is).  However, this is enough for fbcon and bringing up X using
xf86-video-modesetting.

Signed-off-by: Eric Anholt <eric at anholt.net>
---
 drivers/gpu/drm/Kconfig           |   2 +
 drivers/gpu/drm/Makefile          |   1 +
 drivers/gpu/drm/vc4/Kconfig       |  14 +
 drivers/gpu/drm/vc4/Makefile      |  18 ++
 drivers/gpu/drm/vc4/vc4_bo.c      |  54 ++++
 drivers/gpu/drm/vc4/vc4_crtc.c    | 583 ++++++++++++++++++++++++++++++++++
 drivers/gpu/drm/vc4/vc4_debugfs.c |  38 +++
 drivers/gpu/drm/vc4/vc4_drv.c     | 249 +++++++++++++++
 drivers/gpu/drm/vc4/vc4_drv.h     | 123 +++++++
 drivers/gpu/drm/vc4/vc4_hdmi.c    | 651 ++++++++++++++++++++++++++++++++++++++
 drivers/gpu/drm/vc4/vc4_hvs.c     | 172 ++++++++++
 drivers/gpu/drm/vc4/vc4_kms.c     |  84 +++++
 drivers/gpu/drm/vc4/vc4_plane.c   | 320 +++++++++++++++++++
 drivers/gpu/drm/vc4/vc4_regs.h    | 562 ++++++++++++++++++++++++++++++++
 14 files changed, 2871 insertions(+)
 create mode 100644 drivers/gpu/drm/vc4/Kconfig
 create mode 100644 drivers/gpu/drm/vc4/Makefile
 create mode 100644 drivers/gpu/drm/vc4/vc4_bo.c
 create mode 100644 drivers/gpu/drm/vc4/vc4_crtc.c
 create mode 100644 drivers/gpu/drm/vc4/vc4_debugfs.c
 create mode 100644 drivers/gpu/drm/vc4/vc4_drv.c
 create mode 100644 drivers/gpu/drm/vc4/vc4_drv.h
 create mode 100644 drivers/gpu/drm/vc4/vc4_hdmi.c
 create mode 100644 drivers/gpu/drm/vc4/vc4_hvs.c
 create mode 100644 drivers/gpu/drm/vc4/vc4_kms.c
 create mode 100644 drivers/gpu/drm/vc4/vc4_plane.c
 create mode 100644 drivers/gpu/drm/vc4/vc4_regs.h

diff --git a/drivers/gpu/drm/Kconfig b/drivers/gpu/drm/Kconfig
index c46ca31..1730a76 100644
--- a/drivers/gpu/drm/Kconfig
+++ b/drivers/gpu/drm/Kconfig
@@ -240,3 +240,5 @@ source "drivers/gpu/drm/sti/Kconfig"
 source "drivers/gpu/drm/amd/amdkfd/Kconfig"
 
 source "drivers/gpu/drm/imx/Kconfig"
+
+source "drivers/gpu/drm/vc4/Kconfig"
diff --git a/drivers/gpu/drm/Makefile b/drivers/gpu/drm/Makefile
index 5713d05..b991ac5 100644
--- a/drivers/gpu/drm/Makefile
+++ b/drivers/gpu/drm/Makefile
@@ -42,6 +42,7 @@ obj-$(CONFIG_DRM_MGA)	+= mga/
 obj-$(CONFIG_DRM_I810)	+= i810/
 obj-$(CONFIG_DRM_I915)  += i915/
 obj-$(CONFIG_DRM_MGAG200) += mgag200/
+obj-$(CONFIG_DRM_VC4)  += vc4/
 obj-$(CONFIG_DRM_CIRRUS_QEMU) += cirrus/
 obj-$(CONFIG_DRM_SIS)   += sis/
 obj-$(CONFIG_DRM_SAVAGE)+= savage/
diff --git a/drivers/gpu/drm/vc4/Kconfig b/drivers/gpu/drm/vc4/Kconfig
new file mode 100644
index 0000000..130cc94
--- /dev/null
+++ b/drivers/gpu/drm/vc4/Kconfig
@@ -0,0 +1,14 @@
+config DRM_VC4
+	tristate "Broadcom VC4 Graphics"
+	depends on ARCH_BCM2835
+	depends on DRM
+	select DRM_KMS_HELPER
+	select DRM_KMS_FB_HELPER
+	select DRM_KMS_CMA_HELPER
+	help
+	  Choose this option if you have a system that has a Broadcom
+	  VC4 GPU, such as the Raspberry Pi or other BCM2708/BCM2835.
+
+	  This driver requires that "avoid_warnings=2" be present in
+	  the config.txt for the firmware, to keep it from smashing
+	  our display setup.
diff --git a/drivers/gpu/drm/vc4/Makefile b/drivers/gpu/drm/vc4/Makefile
new file mode 100644
index 0000000..4aa07ca
--- /dev/null
+++ b/drivers/gpu/drm/vc4/Makefile
@@ -0,0 +1,18 @@
+ccflags-y := -Iinclude/drm
+
+# Please keep these build lists sorted!
+
+# core driver code
+vc4-y := \
+	vc4_bo.o \
+	vc4_crtc.o \
+	vc4_drv.o \
+	vc4_kms.o \
+	vc4_hdmi.o \
+	vc4_hvs.o \
+	vc4_plane.o \
+	$()
+
+vc4-$(CONFIG_DEBUG_FS) += vc4_debugfs.o
+
+obj-$(CONFIG_DRM_VC4)  += vc4.o
diff --git a/drivers/gpu/drm/vc4/vc4_bo.c b/drivers/gpu/drm/vc4/vc4_bo.c
new file mode 100644
index 0000000..fee8cac
--- /dev/null
+++ b/drivers/gpu/drm/vc4/vc4_bo.c
@@ -0,0 +1,54 @@
+/*
+ *  Copyright ? 2015 Broadcom
+ *
+ * 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.
+ */
+
+/* DOC: VC4 GEM BO management support.
+ *
+ * The VC4 GPU architecture (both scanout and rendering) has direct
+ * access to system memory with no MMU in between.  To support it, we
+ * use the GEM CMA helper functions to allocate contiguous ranges of
+ * physical memory for our BOs.
+ */
+
+#include "vc4_drv.h"
+
+struct vc4_bo *vc4_bo_create(struct drm_device *dev, size_t size)
+{
+	struct drm_gem_cma_object *cma_obj;
+
+	cma_obj = drm_gem_cma_create(dev, size);
+	if (IS_ERR(cma_obj))
+		return NULL;
+	else
+		return to_vc4_bo(&cma_obj->base);
+}
+
+int vc4_dumb_create(struct drm_file *file_priv,
+		    struct drm_device *dev,
+		    struct drm_mode_create_dumb *args)
+{
+	int min_pitch = DIV_ROUND_UP(args->width * args->bpp, 8);
+	struct vc4_bo *bo = NULL;
+	int ret;
+
+	if (args->pitch < min_pitch)
+		args->pitch = min_pitch;
+
+	if (args->size < args->pitch * args->height)
+		args->size = args->pitch * args->height;
+
+	mutex_lock(&dev->struct_mutex);
+	bo = vc4_bo_create(dev, roundup(args->size, PAGE_SIZE));
+	mutex_unlock(&dev->struct_mutex);
+	if (!bo)
+		return -ENOMEM;
+
+	ret = drm_gem_handle_create(file_priv, &bo->base.base, &args->handle);
+	drm_gem_object_unreference_unlocked(&bo->base.base);
+
+	return ret;
+}
diff --git a/drivers/gpu/drm/vc4/vc4_crtc.c b/drivers/gpu/drm/vc4/vc4_crtc.c
new file mode 100644
index 0000000..6f127f0
--- /dev/null
+++ b/drivers/gpu/drm/vc4/vc4_crtc.c
@@ -0,0 +1,583 @@
+/*
+ * Copyright (C) 2015 Broadcom
+ *
+ * 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.
+ */
+
+/**
+ * DOC: VC4 CRTC module
+ *
+ * In VC4, the Pixel Valve is what most closely corresponds to the
+ * DRM's concept of a CRTC.  The PV generates video timings from the
+ * pixel clock and its configuration.
+ *
+ * However, the DRM CRTC also collects the configuration of all the
+ * DRM planes attached to it.  As a result, this file also manages
+ * setup of the VC4 HVS's display elements on the CRTC.
+ */
+
+#include "drm_atomic_helper.h"
+#include "drm_crtc_helper.h"
+#include "linux/clk.h"
+#include "linux/component.h"
+#include "vc4_drv.h"
+#include "vc4_regs.h"
+
+#define CRTC_WRITE(offset, val) writel(val, vc4_crtc->regs + (offset))
+#define CRTC_READ(offset) readl(vc4_crtc->regs + (offset))
+
+#define CRTC_REG(reg) { reg, #reg }
+static const struct {
+	u32 reg;
+	const char *name;
+} crtc_regs[] = {
+	CRTC_REG(PV_CONTROL),
+	CRTC_REG(PV_V_CONTROL),
+	CRTC_REG(PV_VSYNCD),
+	CRTC_REG(PV_HORZA),
+	CRTC_REG(PV_HORZB),
+	CRTC_REG(PV_VERTA),
+	CRTC_REG(PV_VERTB),
+	CRTC_REG(PV_VERTA_EVEN),
+	CRTC_REG(PV_VERTB_EVEN),
+	CRTC_REG(PV_INTEN),
+	CRTC_REG(PV_INTSTAT),
+	CRTC_REG(PV_STAT),
+	CRTC_REG(PV_HACT_ACT),
+};
+
+static void vc4_crtc_dump_regs(struct vc4_crtc *vc4_crtc)
+{
+	int i;
+
+	for (i = 0; i < ARRAY_SIZE(crtc_regs); i++) {
+		DRM_INFO("0x%04x (%s): 0x%08x\n",
+			 crtc_regs[i].reg, crtc_regs[i].name,
+			 CRTC_READ(crtc_regs[i].reg));
+	}
+}
+
+#ifdef CONFIG_DEBUG_FS
+int vc4_crtc_debugfs_regs(struct seq_file *m, void *unused)
+{
+	struct drm_info_node *node = (struct drm_info_node *) m->private;
+	struct drm_device *dev = node->minor->dev;
+	int crtc_index = (uintptr_t)node->info_ent->data;
+	struct drm_crtc *crtc;
+	struct vc4_crtc *vc4_crtc;
+	int i;
+
+	i = 0;
+	list_for_each_entry(crtc, &dev->mode_config.crtc_list, head) {
+		if (i == crtc_index)
+			break;
+		i++;
+	}
+	if (!crtc)
+		return 0;
+	vc4_crtc = to_vc4_crtc(crtc);
+
+	for (i = 0; i < ARRAY_SIZE(crtc_regs); i++) {
+		seq_printf(m, "%s (0x%04x): 0x%08x\n",
+			   crtc_regs[i].name, crtc_regs[i].reg,
+			   CRTC_READ(crtc_regs[i].reg));
+	}
+
+	return 0;
+}
+#endif
+
+static void vc4_crtc_destroy(struct drm_crtc *crtc)
+{
+	drm_crtc_cleanup(crtc);
+}
+
+static bool vc4_crtc_mode_fixup(struct drm_crtc *crtc,
+				const struct drm_display_mode *mode,
+				struct drm_display_mode *adjusted_mode)
+{
+	return true;
+}
+
+static u32 vc4_get_fifo_full_level(u32 format)
+{
+	static const u32 fifo_len_bytes = 64;
+	static const u32 hvs_latency_pix = 6;
+
+	switch (format) {
+	case PV_CONTROL_FORMAT_DSIV_16:
+	case PV_CONTROL_FORMAT_DSIC_16:
+		return fifo_len_bytes - 2 * hvs_latency_pix;
+	case PV_CONTROL_FORMAT_DSIV_18:
+		return fifo_len_bytes - 14;
+	case PV_CONTROL_FORMAT_24:
+	case PV_CONTROL_FORMAT_DSIV_24:
+	default:
+		return fifo_len_bytes - 3 * hvs_latency_pix;
+	}
+}
+
+static void vc4_crtc_mode_set_nofb(struct drm_crtc *crtc)
+{
+	struct vc4_crtc *vc4_crtc = to_vc4_crtc(crtc);
+	struct drm_crtc_state *state = crtc->state;
+	struct drm_display_mode *mode = &state->adjusted_mode;
+	u32 vactive = (mode->vdisplay >>
+		       ((mode->flags & DRM_MODE_FLAG_INTERLACE) ? 1 : 0));
+	u32 format = PV_CONTROL_FORMAT_24;
+	bool debug_dump_regs = false;
+
+	if (debug_dump_regs) {
+		DRM_INFO("CRTC %d regs before:\n", drm_crtc_index(crtc));
+		vc4_crtc_dump_regs(vc4_crtc);
+	}
+
+	/* This is where we would set the pixel clock. */
+
+	/* Reset the PV fifo. */
+	CRTC_WRITE(PV_CONTROL, 0);
+	CRTC_WRITE(PV_CONTROL, PV_CONTROL_FIFO_CLR | PV_CONTROL_EN);
+	CRTC_WRITE(PV_CONTROL, 0);
+
+	CRTC_WRITE(PV_HORZA,
+		   VC4_SET_FIELD(mode->htotal - mode->hsync_end,
+				 PV_HORZA_HBP) |
+		   VC4_SET_FIELD(mode->hsync_end - mode->hsync_start,
+				 PV_HORZA_HSYNC));
+	CRTC_WRITE(PV_HORZB,
+		   VC4_SET_FIELD(mode->hsync_start - mode->hdisplay,
+				 PV_HORZB_HFP) |
+		   VC4_SET_FIELD(mode->hdisplay, PV_HORZB_HACTIVE));
+
+	CRTC_WRITE(PV_VERTA,
+		   VC4_SET_FIELD(mode->vtotal - mode->vsync_end,
+				 PV_VERTA_VBP) |
+		   VC4_SET_FIELD(mode->vsync_end - mode->vsync_start,
+				 PV_VERTA_VSYNC));
+	CRTC_WRITE(PV_VERTB,
+		   VC4_SET_FIELD(mode->vsync_start - mode->vdisplay,
+				 PV_VERTB_VFP) |
+		   VC4_SET_FIELD(vactive, PV_VERTB_VACTIVE));
+	if (mode->flags & DRM_MODE_FLAG_INTERLACE) {
+		/* Write PV_VERTA_EVEN/VERTB_EVEN */
+	}
+
+	CRTC_WRITE(PV_HACT_ACT, mode->hdisplay);
+
+	CRTC_WRITE(PV_V_CONTROL,
+		   PV_VCONTROL_CONTINUOUS);
+
+	CRTC_WRITE(PV_CONTROL,
+		   VC4_SET_FIELD(format, PV_CONTROL_FORMAT) |
+		   VC4_SET_FIELD(vc4_get_fifo_full_level(format),
+				 PV_CONTROL_FIFO_LEVEL) |
+		   PV_CONTROL_CLR_AT_START |
+		   PV_CONTROL_TRIGGER_UNDERFLOW |
+		   PV_CONTROL_WAIT_HSTART |
+		   VC4_SET_FIELD(PV_CONTROL_CLK_SELECT_DPI_SMI_HDMI,
+				 PV_CONTROL_CLK_SELECT) |
+		   PV_CONTROL_FIFO_CLR |
+		   PV_CONTROL_EN);
+
+	if (debug_dump_regs) {
+		DRM_INFO("CRTC %d regs after:\n", drm_crtc_index(crtc));
+		vc4_crtc_dump_regs(vc4_crtc);
+	}
+}
+
+static void
+require_hvs_enabled(struct drm_device *dev)
+{
+	struct vc4_dev *vc4 = to_vc4_dev(dev);
+
+	WARN_ON_ONCE((HVS_READ(SCALER_DISPCTRL) & SCALER_DISPCTRL_ENABLE) !=
+		     SCALER_DISPCTRL_ENABLE);
+}
+
+static void vc4_crtc_disable(struct drm_crtc *crtc)
+{
+	struct drm_device *dev = crtc->dev;
+	struct vc4_dev *vc4 = to_vc4_dev(dev);
+	struct vc4_crtc *vc4_crtc = to_vc4_crtc(crtc);
+
+	require_hvs_enabled(dev);
+
+	CRTC_WRITE(PV_V_CONTROL,
+		   CRTC_READ(PV_V_CONTROL) & ~PV_VCONTROL_VIDEN);
+	while (CRTC_READ(PV_V_CONTROL) & PV_VCONTROL_VIDEN)
+		cpu_relax();
+
+	/* Without a wait here, we end up with a black screen. */
+	msleep(30);
+
+	if (HVS_READ(SCALER_DISPCTRLX(vc4_crtc->channel)) &
+	    SCALER_DISPCTRLX_ENABLE) {
+		HVS_WRITE(SCALER_DISPCTRLX(vc4_crtc->channel),
+			  SCALER_DISPCTRLX_RESET);
+
+		/* While the docs say that reset is self-clearing, it
+		 * seems it doesn't actually.
+		 */
+		HVS_WRITE(SCALER_DISPCTRLX(vc4_crtc->channel), 0);
+	}
+
+	/* Once we leave, the scaler should be disabled and its fifo empty. */
+
+	WARN_ON_ONCE(HVS_READ(SCALER_DISPCTRLX(vc4_crtc->channel)) &
+		     SCALER_DISPCTRLX_RESET);
+
+	WARN_ON_ONCE(VC4_GET_FIELD(HVS_READ(SCALER_DISPSTATX(vc4_crtc->channel)),
+				   SCALER_DISPSTATX_MODE) !=
+		     SCALER_DISPSTATX_MODE_DISABLED);
+
+	WARN_ON_ONCE((HVS_READ(SCALER_DISPSTATX(vc4_crtc->channel)) &
+		      (SCALER_DISPSTATX_FULL | SCALER_DISPSTATX_EMPTY)) !=
+		     SCALER_DISPSTATX_EMPTY);
+}
+
+static void vc4_crtc_enable(struct drm_crtc *crtc)
+{
+	struct drm_device *dev = crtc->dev;
+	struct vc4_dev *vc4 = to_vc4_dev(dev);
+	struct vc4_crtc *vc4_crtc = to_vc4_crtc(crtc);
+	struct drm_crtc_state *state = crtc->state;
+	struct drm_display_mode *mode = &state->adjusted_mode;
+
+	require_hvs_enabled(dev);
+
+	/* Turn on the scaler, which will wait for vstart to start
+	 * compositing.
+	 */
+	HVS_WRITE(SCALER_DISPCTRLX(vc4_crtc->channel),
+		  VC4_SET_FIELD(mode->hdisplay, SCALER_DISPCTRLX_WIDTH) |
+		  VC4_SET_FIELD(mode->vdisplay, SCALER_DISPCTRLX_HEIGHT) |
+		  SCALER_DISPCTRLX_ENABLE);
+
+	/* Turn on the pixel valve, which will emit the vstart signal. */
+	CRTC_WRITE(PV_V_CONTROL,
+		   CRTC_READ(PV_V_CONTROL) | PV_VCONTROL_VIDEN);
+}
+
+static int vc4_crtc_atomic_check(struct drm_crtc *crtc,
+				 struct drm_crtc_state *state)
+{
+	struct drm_device *dev = crtc->dev;
+	struct vc4_dev *vc4 = to_vc4_dev(dev);
+	struct drm_plane *plane;
+	struct vc4_crtc *vc4_crtc = to_vc4_crtc(crtc);
+	u32 dlist_count = 0;
+
+	drm_atomic_crtc_state_for_each_plane(plane, state) {
+		struct drm_plane_state *plane_state =
+			state->state->plane_states[drm_plane_index(plane)];
+
+		/* plane might not have changed, in which case take
+		 * current state:
+		 */
+		if (!plane_state)
+			plane_state = plane->state;
+
+		dlist_count += vc4_plane_dlist_size(plane_state);
+	}
+
+	dlist_count++; /* Account for SCALER_CTL0_END. */
+
+	if (!vc4_crtc->dlist || dlist_count > vc4_crtc->dlist_size) {
+		vc4_crtc->dlist = ((u32 __iomem *)vc4->hvs->dlist +
+				   HVS_BOOTLOADER_DLIST_END);
+		vc4_crtc->dlist_size = ((SCALER_DLIST_SIZE >> 2) -
+					HVS_BOOTLOADER_DLIST_END);
+
+		if (dlist_count > vc4_crtc->dlist_size) {
+			DRM_DEBUG_KMS("dlist too large for CRTC (%d > %d).\n",
+				      dlist_count, vc4_crtc->dlist_size);
+			return -EINVAL;
+		}
+	}
+
+	return 0;
+}
+
+static void vc4_crtc_atomic_begin(struct drm_crtc *crtc)
+{
+}
+
+static void vc4_crtc_atomic_flush(struct drm_crtc *crtc)
+{
+	struct drm_device *dev = crtc->dev;
+	struct vc4_dev *vc4 = to_vc4_dev(dev);
+	struct vc4_crtc *vc4_crtc = to_vc4_crtc(crtc);
+	struct drm_plane *plane;
+	bool debug_dump_regs = false;
+	u32 __iomem *dlist_next = vc4_crtc->dlist;
+
+	if (debug_dump_regs) {
+		DRM_INFO("CRTC %d HVS before:\n", drm_crtc_index(crtc));
+		vc4_hvs_dump_state(dev);
+	}
+
+	/* Copy all the active planes' dlist contents to the hardware dlist.
+	 *
+	 * XXX: If the new display list was large enough that it
+	 * overlapped a currently-read display list, we need to do
+	 * something like disable scanout before putting in the new
+	 * list.  For now, we're safe because we only have the two
+	 * planes.
+	 */
+	drm_atomic_crtc_for_each_plane(plane, crtc) {
+		dlist_next += vc4_plane_write_dlist(plane, dlist_next);
+	}
+
+	if (dlist_next == vc4_crtc->dlist) {
+		/* If no planes were enabled, use the SCALER_CTL0_END
+		 * at the start of the display list memory (in the
+		 * bootloader section).  We'll rewrite that
+		 * SCALER_CTL0_END, just in case, though.
+		 */
+		writel(SCALER_CTL0_END, vc4->hvs->dlist);
+		HVS_WRITE(SCALER_DISPLISTX(vc4_crtc->channel), 0);
+	} else {
+		writel(SCALER_CTL0_END, dlist_next);
+		dlist_next++;
+
+		HVS_WRITE(SCALER_DISPLISTX(vc4_crtc->channel),
+			  (u32 *)vc4_crtc->dlist - (u32 *)vc4->hvs->dlist);
+
+		/* Make the next display list start after ours. */
+		vc4_crtc->dlist_size -= (dlist_next - vc4_crtc->dlist);
+		vc4_crtc->dlist = dlist_next;
+	}
+
+	if (debug_dump_regs) {
+		DRM_INFO("CRTC %d HVS after:\n", drm_crtc_index(crtc));
+		vc4_hvs_dump_state(dev);
+	}
+
+	if (crtc->state->event) {
+		unsigned long flags;
+
+		crtc->state->event->pipe = drm_crtc_index(crtc);
+
+		WARN_ON(drm_crtc_vblank_get(crtc) != 0);
+
+		spin_lock_irqsave(&dev->event_lock, flags);
+		vc4_crtc->event = crtc->state->event;
+		spin_unlock_irqrestore(&dev->event_lock, flags);
+		crtc->state->event = NULL;
+	}
+}
+
+int vc4_enable_vblank(struct drm_device *dev, int crtc_id)
+{
+	struct vc4_dev *vc4 = to_vc4_dev(dev);
+	struct vc4_crtc *vc4_crtc = vc4->crtc[crtc_id];
+
+	CRTC_WRITE(PV_INTEN, PV_INT_VFP_START);
+
+	return 0;
+}
+
+void vc4_disable_vblank(struct drm_device *dev, int crtc_id)
+{
+	struct vc4_dev *vc4 = to_vc4_dev(dev);
+	struct vc4_crtc *vc4_crtc = vc4->crtc[crtc_id];
+
+	CRTC_WRITE(PV_INTEN, 0);
+}
+
+static void
+vc4_crtc_handle_page_flip(struct vc4_crtc *vc4_crtc)
+{
+	struct drm_crtc *crtc = &vc4_crtc->base;
+	struct drm_device *dev = crtc->dev;
+	unsigned long flags;
+
+	spin_lock_irqsave(&dev->event_lock, flags);
+	if (vc4_crtc->event) {
+		drm_crtc_send_vblank_event(crtc, vc4_crtc->event);
+		vc4_crtc->event = NULL;
+	}
+	spin_unlock_irqrestore(&dev->event_lock, flags);
+}
+
+static irqreturn_t vc4_crtc_irq_handler(int irq, void *data)
+{
+	struct vc4_crtc *vc4_crtc = data;
+	u32 stat = CRTC_READ(PV_INTSTAT);
+	irqreturn_t ret = IRQ_NONE;
+
+	if (stat & PV_INT_VFP_START) {
+		CRTC_WRITE(PV_INTSTAT, PV_INT_VFP_START);
+		drm_crtc_handle_vblank(&vc4_crtc->base);
+		vc4_crtc_handle_page_flip(vc4_crtc);
+		ret = IRQ_HANDLED;
+	}
+
+	return ret;
+}
+
+static const struct drm_crtc_funcs vc4_crtc_funcs = {
+	.set_config = drm_atomic_helper_set_config,
+	.destroy = vc4_crtc_destroy,
+	.page_flip = drm_atomic_helper_page_flip,
+	.set_property = NULL,
+	.cursor_set = NULL, /* handled by drm_mode_cursor_universal */
+	.cursor_move = NULL, /* handled by drm_mode_cursor_universal */
+	.reset = drm_atomic_helper_crtc_reset,
+	.atomic_duplicate_state = drm_atomic_helper_crtc_duplicate_state,
+	.atomic_destroy_state = drm_atomic_helper_crtc_destroy_state,
+};
+
+static const struct drm_crtc_helper_funcs vc4_crtc_helper_funcs = {
+	.mode_fixup = vc4_crtc_mode_fixup,
+	.mode_set_nofb = vc4_crtc_mode_set_nofb,
+	.disable = vc4_crtc_disable,
+	.enable = vc4_crtc_enable,
+	.atomic_check = vc4_crtc_atomic_check,
+	.atomic_begin = vc4_crtc_atomic_begin,
+	.atomic_flush = vc4_crtc_atomic_flush,
+};
+
+/* Frees the page flip event when the DRM device is closed with the
+ * event still outstanding.
+ */
+void vc4_cancel_page_flip(struct drm_crtc *crtc, struct drm_file *file)
+{
+	struct vc4_crtc *vc4_crtc = to_vc4_crtc(crtc);
+	struct drm_device *dev = crtc->dev;
+	unsigned long flags;
+
+	spin_lock_irqsave(&dev->event_lock, flags);
+
+	if (vc4_crtc->event && vc4_crtc->event->base.file_priv == file) {
+		vc4_crtc->event->base.destroy(&vc4_crtc->event->base);
+		drm_crtc_vblank_put(crtc);
+		vc4_crtc->event = NULL;
+	}
+
+	spin_unlock_irqrestore(&dev->event_lock, flags);
+}
+
+static int vc4_crtc_bind(struct device *dev, struct device *master, void *data)
+{
+	struct platform_device *pdev = to_platform_device(dev);
+	struct drm_device *drm = dev_get_drvdata(master);
+	struct vc4_dev *vc4 = to_vc4_dev(drm);
+	struct vc4_crtc *vc4_crtc;
+	struct drm_crtc *crtc;
+	struct drm_plane *primary_plane, *cursor_plane;
+	int ret;
+
+	primary_plane = vc4_plane_init(drm, DRM_PLANE_TYPE_PRIMARY);
+	if (!primary_plane) {
+		dev_err(dev, "failed to construct primary plane\n");
+		ret = PTR_ERR(primary_plane);
+		goto fail;
+	}
+
+	cursor_plane = vc4_plane_init(drm, DRM_PLANE_TYPE_CURSOR);
+	if (!cursor_plane) {
+		dev_err(dev, "failed to construct cursor plane\n");
+		ret = PTR_ERR(cursor_plane);
+		goto fail;
+	}
+
+	vc4_crtc = devm_kzalloc(dev, sizeof(*vc4_crtc), GFP_KERNEL);
+	if (!vc4_crtc)
+		return -ENOMEM;
+	crtc = &vc4_crtc->base;
+
+	vc4_crtc->regs = vc4_ioremap_regs(pdev, 0);
+	if (IS_ERR(vc4_crtc->regs))
+		return PTR_ERR(vc4_crtc->regs);
+
+	drm_crtc_init_with_planes(drm, crtc, primary_plane, cursor_plane,
+				  &vc4_crtc_funcs);
+	drm_crtc_helper_add(crtc, &vc4_crtc_helper_funcs);
+	primary_plane->crtc = crtc;
+	cursor_plane->crtc = crtc;
+	vc4->crtc[drm_crtc_index(crtc)] = vc4_crtc;
+
+	/* Until we have full scanout setup to route things through to
+	 * encoders, line things up like the firmware did.
+	 */
+	switch (drm_crtc_index(crtc)) {
+	case 0:
+		vc4_crtc->channel = 0;
+		break;
+	case 1:
+		vc4_crtc->channel = 2;
+		break;
+	default:
+	case 2:
+		vc4_crtc->channel = 1;
+		break;
+	}
+
+	CRTC_WRITE(PV_INTEN, 0);
+	CRTC_WRITE(PV_INTSTAT, PV_INT_VFP_START);
+	ret = devm_request_irq(dev, platform_get_irq(pdev, 0),
+			       vc4_crtc_irq_handler, 0, "vc4 crtc", vc4_crtc);
+
+	platform_set_drvdata(pdev, vc4_crtc);
+
+	return 0;
+
+fail:
+	return ret;
+}
+
+static void vc4_crtc_unbind(struct device *dev, struct device *master,
+			    void *data)
+{
+	struct platform_device *pdev = to_platform_device(dev);
+	struct vc4_crtc *vc4_crtc = dev_get_drvdata(dev);
+
+	vc4_crtc_destroy(&vc4_crtc->base);
+
+	CRTC_WRITE(PV_INTEN, 0);
+
+	platform_set_drvdata(pdev, NULL);
+}
+
+static const struct component_ops vc4_crtc_ops = {
+	.bind   = vc4_crtc_bind,
+	.unbind = vc4_crtc_unbind,
+};
+
+static int vc4_crtc_dev_probe(struct platform_device *pdev)
+{
+	return component_add(&pdev->dev, &vc4_crtc_ops);
+}
+
+static int vc4_crtc_dev_remove(struct platform_device *pdev)
+{
+	component_del(&pdev->dev, &vc4_crtc_ops);
+	return 0;
+}
+
+static const struct of_device_id vc4_crtc_dt_match[] = {
+	{ .compatible = "brcm,vc4-pixelvalve" },
+	{}
+};
+
+static struct platform_driver vc4_crtc_driver = {
+	.probe = vc4_crtc_dev_probe,
+	.remove = vc4_crtc_dev_remove,
+	.driver = {
+		.name = "vc4_crtc",
+		.of_match_table = vc4_crtc_dt_match,
+	},
+};
+
+void __init vc4_crtc_register(void)
+{
+	platform_driver_register(&vc4_crtc_driver);
+}
+
+void __exit vc4_crtc_unregister(void)
+{
+	platform_driver_unregister(&vc4_crtc_driver);
+}
diff --git a/drivers/gpu/drm/vc4/vc4_debugfs.c b/drivers/gpu/drm/vc4/vc4_debugfs.c
new file mode 100644
index 0000000..c557039
--- /dev/null
+++ b/drivers/gpu/drm/vc4/vc4_debugfs.c
@@ -0,0 +1,38 @@
+/*
+ *  Copyright ? 2014 Broadcom
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License version 2 as
+ * published by the Free Software Foundation.
+ */
+
+#include <linux/seq_file.h>
+#include <linux/circ_buf.h>
+#include <linux/ctype.h>
+#include <linux/debugfs.h>
+#include <drm/drmP.h>
+
+#include "vc4_drv.h"
+#include "vc4_regs.h"
+
+static const struct drm_info_list vc4_debugfs_list[] = {
+	{"hdmi_regs", vc4_hdmi_debugfs_regs, 0},
+	{"hvs_regs", vc4_hvs_debugfs_regs, 0},
+	{"crtc0_regs", vc4_crtc_debugfs_regs, 0, (void *)(uintptr_t)0},
+	{"crtc1_regs", vc4_crtc_debugfs_regs, 0, (void *)(uintptr_t)1},
+	{"crtc2_regs", vc4_crtc_debugfs_regs, 0, (void *)(uintptr_t)2},
+};
+#define VC4_DEBUGFS_ENTRIES ARRAY_SIZE(vc4_debugfs_list)
+
+int
+vc4_debugfs_init(struct drm_minor *minor)
+{
+	return drm_debugfs_create_files(vc4_debugfs_list, VC4_DEBUGFS_ENTRIES,
+					minor->debugfs_root, minor);
+}
+
+void
+vc4_debugfs_cleanup(struct drm_minor *minor)
+{
+	drm_debugfs_remove_files(vc4_debugfs_list, VC4_DEBUGFS_ENTRIES, minor);
+}
diff --git a/drivers/gpu/drm/vc4/vc4_drv.c b/drivers/gpu/drm/vc4/vc4_drv.c
new file mode 100644
index 0000000..9ecf4b8b
--- /dev/null
+++ b/drivers/gpu/drm/vc4/vc4_drv.c
@@ -0,0 +1,249 @@
+/*
+ * Copyright (C) 2014-2015 Broadcom
+ * Copyright (C) 2013 Red Hat
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License version 2 as
+ * published by the Free Software Foundation.
+ */
+
+#include <linux/clk.h>
+#include <linux/component.h>
+#include <linux/device.h>
+#include <linux/io.h>
+#include <linux/module.h>
+#include <linux/of_platform.h>
+#include <linux/platform_device.h>
+
+#include "vc4_drv.h"
+#include "vc4_regs.h"
+
+#define DRIVER_NAME "vc4"
+#define DRIVER_DESC "Broadcom VC4 graphics"
+#define DRIVER_DATE "20140616"
+#define DRIVER_MAJOR 0
+#define DRIVER_MINOR 0
+#define DRIVER_PATCHLEVEL 0
+
+/* Helper function for mapping the regs on a platform device.
+ *
+ * We assume only one register range per device, so we use index 0.
+ */
+void __iomem *vc4_ioremap_regs(struct platform_device *dev, int index)
+{
+	struct resource *res;
+	void __iomem *map;
+
+	res = platform_get_resource(dev, IORESOURCE_MEM, index);
+	map = devm_ioremap_resource(&dev->dev, res);
+	if (IS_ERR(map)) {
+		DRM_ERROR("Failed to map registers: %ld\n", PTR_ERR(map));
+		return map;
+	}
+
+	return map;
+}
+
+static int vc4_drm_load(struct drm_device *dev, unsigned long flags)
+{
+	struct vc4_dev *vc4;
+	int ret;
+
+	vc4 = devm_kzalloc(dev->dev, sizeof(*vc4), GFP_KERNEL);
+	if (!vc4)
+		return -ENOMEM;
+
+	dev_set_drvdata(dev->dev, dev);
+	vc4->dev = dev;
+	dev->dev_private = vc4;
+
+	drm_mode_config_init(dev);
+
+	ret = component_bind_all(dev->dev, dev);
+	if (ret)
+		return ret;
+
+	vc4_kms_load(dev);
+
+	return 0;
+}
+
+static int vc4_drm_unload(struct drm_device *dev)
+{
+	drm_mode_config_cleanup(dev);
+
+	component_unbind_all(dev->dev, dev);
+
+	return 0;
+}
+
+static void vc4_drm_preclose(struct drm_device *dev, struct drm_file *file)
+{
+	struct drm_crtc *crtc;
+
+	list_for_each_entry(crtc, &dev->mode_config.crtc_list, head)
+		vc4_cancel_page_flip(crtc, file);
+}
+
+static const struct file_operations vc4_drm_fops = {
+	.owner = THIS_MODULE,
+	.open = drm_open,
+	.release = drm_release,
+	.unlocked_ioctl = drm_ioctl,
+	.mmap = drm_gem_cma_mmap,
+	.poll = drm_poll,
+	.read = drm_read,
+#ifdef CONFIG_COMPAT
+	.compat_ioctl = drm_compat_ioctl,
+#endif
+	.llseek = noop_llseek,
+};
+
+static const struct drm_ioctl_desc vc4_drm_ioctls[] = {
+};
+
+static struct drm_driver vc4_drm_driver = {
+	.driver_features = (DRIVER_MODESET |
+			    DRIVER_ATOMIC |
+			    DRIVER_GEM |
+			    DRIVER_PRIME),
+	.load = vc4_drm_load,
+	.unload = vc4_drm_unload,
+	.set_busid = drm_platform_set_busid,
+	.preclose = vc4_drm_preclose,
+
+	.enable_vblank = vc4_enable_vblank,
+	.disable_vblank = vc4_disable_vblank,
+	.get_vblank_counter = drm_vblank_count,
+
+#if defined(CONFIG_DEBUG_FS)
+	.debugfs_init = vc4_debugfs_init,
+	.debugfs_cleanup = vc4_debugfs_cleanup,
+#endif
+
+	.gem_free_object = drm_gem_cma_free_object,
+	.gem_vm_ops = &drm_gem_cma_vm_ops,
+
+	.prime_handle_to_fd = drm_gem_prime_handle_to_fd,
+	.prime_fd_to_handle = drm_gem_prime_fd_to_handle,
+	.gem_prime_import = drm_gem_prime_import,
+	.gem_prime_export = drm_gem_prime_export,
+	.gem_prime_get_sg_table	= drm_gem_cma_prime_get_sg_table,
+	.gem_prime_import_sg_table = drm_gem_cma_prime_import_sg_table,
+	.gem_prime_vmap		= drm_gem_cma_prime_vmap,
+	.gem_prime_vunmap	= drm_gem_cma_prime_vunmap,
+	.gem_prime_mmap		= drm_gem_cma_prime_mmap,
+
+	.dumb_create = vc4_dumb_create,
+	.dumb_map_offset = drm_gem_cma_dumb_map_offset,
+	.dumb_destroy = drm_gem_dumb_destroy,
+
+	.ioctls = vc4_drm_ioctls,
+	.num_ioctls = ARRAY_SIZE(vc4_drm_ioctls),
+	.fops = &vc4_drm_fops,
+
+	.name = DRIVER_NAME,
+	.desc = DRIVER_DESC,
+	.date = DRIVER_DATE,
+	.major = DRIVER_MAJOR,
+	.minor = DRIVER_MINOR,
+	.patchlevel = DRIVER_PATCHLEVEL,
+};
+
+static int vc4_drm_bind(struct device *dev)
+{
+	return drm_platform_init(&vc4_drm_driver, to_platform_device(dev));
+}
+
+static void vc4_drm_unbind(struct device *dev)
+{
+	drm_put_dev(platform_get_drvdata(to_platform_device(dev)));
+}
+
+static const struct component_master_ops vc4_drm_ops = {
+	.bind = vc4_drm_bind,
+	.unbind = vc4_drm_unbind,
+};
+
+static int compare_of(struct device *dev, void *data)
+{
+	return dev->of_node == data;
+}
+
+static int add_components(struct device *dev, struct component_match **matchptr,
+			  const char *name)
+{
+	struct device_node *np = dev->of_node;
+	unsigned i;
+
+	for (i = 0; ; i++) {
+		struct device_node *node;
+
+		node = of_parse_phandle(np, name, i);
+		if (!node)
+			break;
+
+		component_match_add(dev, matchptr, compare_of, node);
+	}
+
+	return 0;
+}
+
+static int vc4_platform_drm_probe(struct platform_device *pdev)
+{
+	struct component_match *match = NULL;
+
+	add_components(&pdev->dev, &match, "crtcs");
+	add_components(&pdev->dev, &match, "encoders");
+	add_components(&pdev->dev, &match, "hvss");
+
+	pdev->dev.coherent_dma_mask = DMA_BIT_MASK(32);
+	return component_master_add_with_match(&pdev->dev, &vc4_drm_ops, match);
+}
+
+static int vc4_platform_drm_remove(struct platform_device *pdev)
+{
+	drm_put_dev(platform_get_drvdata(pdev));
+
+	return 0;
+}
+
+static const struct of_device_id vc4_of_match[] = {
+	{ .compatible = "brcm,vc4", },
+	{},
+};
+MODULE_DEVICE_TABLE(of, vc4_of_match);
+
+static struct platform_driver vc4_platform_driver = {
+	.probe		= vc4_platform_drm_probe,
+	.remove		= vc4_platform_drm_remove,
+	.driver		= {
+		.name	= "vc4-drm",
+		.owner	= THIS_MODULE,
+		.of_match_table = vc4_of_match,
+	},
+};
+
+static int __init vc4_drm_register(void)
+{
+	vc4_hdmi_register();
+	vc4_crtc_register();
+	vc4_hvs_register();
+	return platform_driver_register(&vc4_platform_driver);
+}
+
+static void __exit vc4_drm_unregister(void)
+{
+	platform_driver_unregister(&vc4_platform_driver);
+	vc4_hvs_unregister();
+	vc4_crtc_unregister();
+	vc4_hdmi_unregister();
+}
+
+module_init(vc4_drm_register);
+module_exit(vc4_drm_unregister);
+
+MODULE_ALIAS("platform:vc4-drm");
+MODULE_DESCRIPTION("Broadcom VC4 DRM Driver");
+MODULE_AUTHOR("Eric Anholt <eric at anholt.net>");
+MODULE_LICENSE("GPL v2");
diff --git a/drivers/gpu/drm/vc4/vc4_drv.h b/drivers/gpu/drm/vc4/vc4_drv.h
new file mode 100644
index 0000000..1b0a0b0
--- /dev/null
+++ b/drivers/gpu/drm/vc4/vc4_drv.h
@@ -0,0 +1,123 @@
+/*
+ * Copyright (C) 2015 Broadcom
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License version 2 as
+ * published by the Free Software Foundation.
+ */
+
+#include "drmP.h"
+#include "drm_gem_cma_helper.h"
+
+struct vc4_dev {
+	struct drm_device *dev;
+
+	struct vc4_hdmi *hdmi;
+	struct vc4_hvs *hvs;
+	struct vc4_crtc *crtc[3];
+};
+
+static inline struct vc4_dev *
+to_vc4_dev(struct drm_device *dev)
+{
+	return (struct vc4_dev *)dev->dev_private;
+}
+
+struct vc4_bo {
+	struct drm_gem_cma_object base;
+};
+
+static inline struct vc4_bo *
+to_vc4_bo(struct drm_gem_object *bo)
+{
+	return (struct vc4_bo *)bo;
+}
+
+struct vc4_hvs {
+	struct platform_device *pdev;
+	void __iomem *regs;
+	void __iomem *dlist;
+};
+
+struct vc4_crtc {
+	struct drm_crtc base;
+	void __iomem *regs;
+
+	/* Which HVS channel we're using for our CRTC. */
+	int channel;
+
+	/* Pointer to the actual hardware display list memory for the
+	 * crtc.
+	 */
+	u32 __iomem *dlist;
+
+	u32 dlist_size; /* in dwords */
+
+	struct drm_pending_vblank_event *event;
+};
+
+static inline struct vc4_crtc *
+to_vc4_crtc(struct drm_crtc *crtc)
+{
+	return (struct vc4_crtc *)crtc;
+}
+
+struct vc4_plane {
+	struct drm_plane base;
+};
+
+static inline struct vc4_plane *
+to_vc4_plane(struct drm_plane *plane)
+{
+	return (struct vc4_plane *)plane;
+}
+
+#define HVS_READ(offset) readl(vc4->hvs->regs + offset)
+#define HVS_WRITE(offset, val) writel(val, vc4->hvs->regs + offset)
+
+/* vc4_bo.c */
+void vc4_free_object(struct drm_gem_object *gem_obj);
+struct vc4_bo *vc4_bo_create(struct drm_device *dev, size_t size);
+int vc4_dumb_create(struct drm_file *file_priv,
+		    struct drm_device *dev,
+		    struct drm_mode_create_dumb *args);
+struct dma_buf *vc4_prime_export(struct drm_device *dev,
+				 struct drm_gem_object *obj, int flags);
+
+/* vc4_crtc.c */
+void vc4_crtc_register(void);
+void vc4_crtc_unregister(void);
+int vc4_enable_vblank(struct drm_device *dev, int crtc_id);
+void vc4_disable_vblank(struct drm_device *dev, int crtc_id);
+void vc4_cancel_page_flip(struct drm_crtc *crtc, struct drm_file *file);
+int vc4_crtc_debugfs_regs(struct seq_file *m, void *arg);
+
+/* vc4_debugfs.c */
+int vc4_debugfs_init(struct drm_minor *minor);
+void vc4_debugfs_cleanup(struct drm_minor *minor);
+
+/* vc4_drv.c */
+void __iomem *vc4_ioremap_regs(struct platform_device *dev, int index);
+
+/* vc4_hdmi.c */
+void vc4_hdmi_register(void);
+void vc4_hdmi_unregister(void);
+struct drm_encoder *vc4_hdmi_encoder_init(struct drm_device *dev);
+struct drm_connector *vc4_hdmi_connector_init(struct drm_device *dev,
+					      struct drm_encoder *encoder);
+int vc4_hdmi_debugfs_regs(struct seq_file *m, void *unused);
+
+/* vc4_hvs.c */
+void vc4_hvs_register(void);
+void vc4_hvs_unregister(void);
+void vc4_hvs_dump_state(struct drm_device *dev);
+int vc4_hvs_debugfs_regs(struct seq_file *m, void *unused);
+
+/* vc4_kms.c */
+int vc4_kms_load(struct drm_device *dev);
+
+/* vc4_plane.c */
+struct drm_plane *vc4_plane_init(struct drm_device *dev,
+				 enum drm_plane_type type);
+u32 vc4_plane_write_dlist(struct drm_plane *plane, u32 __iomem *dlist);
+u32 vc4_plane_dlist_size(struct drm_plane_state *state);
diff --git a/drivers/gpu/drm/vc4/vc4_hdmi.c b/drivers/gpu/drm/vc4/vc4_hdmi.c
new file mode 100644
index 0000000..c1ac96e
--- /dev/null
+++ b/drivers/gpu/drm/vc4/vc4_hdmi.c
@@ -0,0 +1,651 @@
+/*
+ * Copyright (c) 2014 The Linux Foundation. All rights reserved.
+ * Copyright (C) 2013 Red Hat
+ * Author: Rob Clark <robdclark at gmail.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.
+ *
+ * You should have received a copy of the GNU General Public License along with
+ * this program.  If not, see <http://www.gnu.org/licenses/>.
+ */
+
+#include "drm_atomic_helper.h"
+#include "drm_crtc_helper.h"
+#include "drm_edid.h"
+#include "linux/clk.h"
+#include "linux/component.h"
+#include "linux/of_gpio.h"
+#include "linux/of_platform.h"
+#include "vc4_drv.h"
+#include "vc4_regs.h"
+
+/* General HDMI hardware state. */
+struct vc4_hdmi {
+	struct platform_device *pdev;
+	struct i2c_adapter *ddc;
+	void __iomem *hdmicore_regs;
+	void __iomem *hd_regs;
+	int hpd_gpio;
+
+	/* Probed video mode at boot time, used to filter display
+	 * modes to only allow equivalent ones (since we can't set the
+	 * pixel clock yet).
+	 */
+	struct drm_display_mode boot_mode;
+};
+#define HDMI_READ(offset) readl(vc4->hdmi->hdmicore_regs + offset)
+#define HDMI_WRITE(offset, val) writel(val, vc4->hdmi->hdmicore_regs + offset)
+#define HD_READ(offset) readl(vc4->hdmi->hd_regs + offset)
+#define HD_WRITE(offset, val) writel(val, vc4->hdmi->hd_regs + offset)
+
+/* VC4 HDMI encoder KMS struct */
+struct vc4_hdmi_encoder {
+	struct drm_encoder base;
+	bool hdmi_monitor;
+};
+static inline struct vc4_hdmi_encoder *
+to_vc4_hdmi_encoder(struct drm_encoder *encoder)
+{
+	return container_of(encoder, struct vc4_hdmi_encoder, base);
+}
+
+/* VC4 HDMI connector KMS struct */
+struct vc4_hdmi_connector {
+	struct drm_connector base;
+
+	/* Since the connector is attached to just the one encoder,
+	 * this is the reference to it so we can do the best_encoder()
+	 * hook.
+	 */
+	struct drm_encoder *encoder;
+};
+static inline struct vc4_hdmi_connector *
+to_vc4_hdmi_connector(struct drm_connector *connector)
+{
+	return container_of(connector, struct vc4_hdmi_connector, base);
+}
+
+#define HDMI_REG(reg) { reg, #reg }
+static const struct {
+	u32 reg;
+	const char *name;
+} hdmi_regs[] = {
+	HDMI_REG(VC4_HDMI_CORE_REV),
+	HDMI_REG(VC4_HDMI_SW_RESET_CONTROL),
+	HDMI_REG(VC4_HDMI_HOTPLUG_INT),
+	HDMI_REG(VC4_HDMI_HOTPLUG),
+	HDMI_REG(VC4_HDMI_HORZA),
+	HDMI_REG(VC4_HDMI_HORZB),
+	HDMI_REG(VC4_HDMI_FIFO_CTL),
+	HDMI_REG(VC4_HDMI_SCHEDULER_CONTROL),
+	HDMI_REG(VC4_HDMI_VERTA0),
+	HDMI_REG(VC4_HDMI_VERTA1),
+	HDMI_REG(VC4_HDMI_VERTB0),
+	HDMI_REG(VC4_HDMI_VERTB1),
+	HDMI_REG(VC4_HDMI_TX_PHY_RESET_CTL),
+};
+static const struct {
+	u32 reg;
+	const char *name;
+} hd_regs[] = {
+	HDMI_REG(VC4_HD_M_CTL),
+	HDMI_REG(VC4_HD_MAI_CTL),
+	HDMI_REG(VC4_HD_VID_CTL),
+	HDMI_REG(VC4_HD_CSC_CTL),
+	HDMI_REG(VC4_HD_FRAME_COUNT),
+};
+
+#ifdef CONFIG_DEBUG_FS
+int vc4_hdmi_debugfs_regs(struct seq_file *m, void *unused)
+{
+	struct drm_info_node *node = (struct drm_info_node *) m->private;
+	struct drm_device *dev = node->minor->dev;
+	struct vc4_dev *vc4 = to_vc4_dev(dev);
+	int i;
+
+	for (i = 0; i < ARRAY_SIZE(hdmi_regs); i++) {
+		seq_printf(m, "%s (0x%04x): 0x%08x\n",
+			   hdmi_regs[i].name, hdmi_regs[i].reg,
+			   HDMI_READ(hdmi_regs[i].reg));
+	}
+
+	for (i = 0; i < ARRAY_SIZE(hd_regs); i++) {
+		seq_printf(m, "%s (0x%04x): 0x%08x\n",
+			   hd_regs[i].name, hd_regs[i].reg,
+			   HD_READ(hd_regs[i].reg));
+	}
+
+	return 0;
+}
+#endif /* CONFIG_DEBUG_FS */
+
+static void vc4_hdmi_dump_regs(struct drm_device *dev)
+{
+	struct vc4_dev *vc4 = to_vc4_dev(dev);
+	int i;
+
+	for (i = 0; i < ARRAY_SIZE(hdmi_regs); i++) {
+		DRM_INFO("0x%04x (%s): 0x%08x\n",
+			 hdmi_regs[i].reg, hdmi_regs[i].name,
+			 HDMI_READ(hdmi_regs[i].reg));
+	}
+	for (i = 0; i < ARRAY_SIZE(hd_regs); i++) {
+		DRM_INFO("0x%04x (%s): 0x%08x\n",
+			 hd_regs[i].reg, hd_regs[i].name,
+			 HD_READ(hd_regs[i].reg));
+	}
+}
+
+static enum drm_connector_status
+vc4_hdmi_connector_detect(struct drm_connector *connector, bool force)
+{
+	struct drm_device *dev = connector->dev;
+	struct vc4_dev *vc4 = to_vc4_dev(dev);
+
+	if (vc4->hdmi->hpd_gpio) {
+		if (gpio_get_value(vc4->hdmi->hpd_gpio))
+			return connector_status_connected;
+		else
+			return connector_status_disconnected;
+	}
+
+	if (HDMI_READ(VC4_HDMI_HOTPLUG) & VC4_HDMI_HOTPLUG_CONNECTED)
+		return connector_status_connected;
+	else
+		return connector_status_disconnected;
+}
+
+static void vc4_hdmi_connector_destroy(struct drm_connector *connector)
+{
+	drm_connector_unregister(connector);
+	drm_connector_cleanup(connector);
+}
+
+static int vc4_hdmi_connector_get_modes(struct drm_connector *connector)
+{
+	struct vc4_hdmi_connector *vc4_connector =
+		to_vc4_hdmi_connector(connector);
+	struct drm_encoder *encoder = vc4_connector->encoder;
+	struct vc4_hdmi_encoder *vc4_encoder = to_vc4_hdmi_encoder(encoder);
+	struct drm_device *dev = connector->dev;
+	struct vc4_dev *vc4 = to_vc4_dev(dev);
+	int ret = 0;
+	struct edid *edid;
+
+	edid = drm_get_edid(connector, vc4->hdmi->ddc);
+	if (!edid)
+		return -ENODEV;
+
+	vc4_encoder->hdmi_monitor = drm_detect_hdmi_monitor(edid);
+	drm_mode_connector_update_edid_property(connector, edid);
+	ret = drm_add_edid_modes(connector, edid);
+
+	return ret;
+}
+
+/* Since we can't set the pixel clock yet, filter out all the EDID
+ * modes that don't match what was set up by the firmware.
+ */
+int vc4_hdmi_mode_valid(struct drm_connector *connector,
+			struct drm_display_mode *mode)
+{
+	struct drm_device *dev = connector->dev;
+	struct vc4_dev *vc4 = to_vc4_dev(dev);
+	struct drm_display_mode *boot_mode = &vc4->hdmi->boot_mode;
+
+	if (mode->hdisplay != boot_mode->hdisplay ||
+	    mode->hsync_start != boot_mode->hsync_start ||
+	    mode->hsync_end != boot_mode->hsync_end ||
+	    mode->htotal != boot_mode->htotal) {
+		return MODE_ERROR;
+	}
+
+	return MODE_OK;
+}
+
+static struct drm_encoder *
+vc4_hdmi_connector_best_encoder(struct drm_connector *connector)
+{
+	struct vc4_hdmi_connector *hdmi_connector =
+		to_vc4_hdmi_connector(connector);
+	return hdmi_connector->encoder;
+}
+
+static const struct drm_connector_funcs vc4_hdmi_connector_funcs = {
+	.dpms = drm_atomic_helper_connector_dpms,
+	.detect = vc4_hdmi_connector_detect,
+	.fill_modes = drm_helper_probe_single_connector_modes,
+	.destroy = vc4_hdmi_connector_destroy,
+	.reset = drm_atomic_helper_connector_reset,
+	.atomic_duplicate_state = drm_atomic_helper_connector_duplicate_state,
+	.atomic_destroy_state = drm_atomic_helper_connector_destroy_state,
+};
+
+static const struct drm_connector_helper_funcs vc4_hdmi_connector_helper_funcs = {
+	.get_modes = vc4_hdmi_connector_get_modes,
+	.mode_valid = vc4_hdmi_mode_valid,
+	.best_encoder = vc4_hdmi_connector_best_encoder,
+};
+
+struct drm_connector *vc4_hdmi_connector_init(struct drm_device *dev,
+					      struct drm_encoder *encoder)
+{
+	struct drm_connector *connector = NULL;
+	struct vc4_hdmi_connector *hdmi_connector;
+	int ret = 0;
+
+	hdmi_connector = devm_kzalloc(dev->dev, sizeof(*hdmi_connector),
+				      GFP_KERNEL);
+	if (!hdmi_connector) {
+		ret = -ENOMEM;
+		goto fail;
+	}
+	connector = &hdmi_connector->base;
+
+	hdmi_connector->encoder = encoder;
+
+	drm_connector_init(dev, connector, &vc4_hdmi_connector_funcs,
+			   DRM_MODE_CONNECTOR_HDMIA);
+	drm_connector_helper_add(connector, &vc4_hdmi_connector_helper_funcs);
+
+	connector->polled = (DRM_CONNECTOR_POLL_CONNECT |
+			     DRM_CONNECTOR_POLL_DISCONNECT);
+
+	connector->interlace_allowed = 0;
+	connector->doublescan_allowed = 0;
+
+	drm_connector_register(connector);
+
+	drm_mode_connector_attach_encoder(connector, encoder);
+
+	return connector;
+
+ fail:
+	if (connector)
+		vc4_hdmi_connector_destroy(connector);
+
+	return ERR_PTR(ret);
+}
+
+static void vc4_encoder_destroy(struct drm_encoder *encoder)
+{
+	drm_encoder_cleanup(encoder);
+}
+
+static const struct drm_encoder_funcs vc4_hdmi_encoder_funcs = {
+	.destroy = vc4_encoder_destroy,
+};
+
+static bool vc4_hdmi_encoder_mode_fixup(struct drm_encoder *encoder,
+					const struct drm_display_mode *mode,
+					struct drm_display_mode *adjusted_mode)
+{
+	return true;
+}
+
+static void vc4_hdmi_encoder_mode_set(struct drm_encoder *encoder,
+				      struct drm_display_mode *unadjusted_mode,
+				      struct drm_display_mode *mode)
+{
+	struct drm_device *dev = encoder->dev;
+	struct vc4_dev *vc4 = to_vc4_dev(dev);
+	bool debug_dump_regs = false;
+	bool hsync_pos = !(mode->flags & DRM_MODE_FLAG_NHSYNC);
+	bool vsync_pos = !(mode->flags & DRM_MODE_FLAG_NVSYNC);
+	u32 vactive = (mode->vdisplay >>
+		       ((mode->flags & DRM_MODE_FLAG_INTERLACE) ? 1 : 0));
+	u32 verta = (VC4_SET_FIELD(mode->vsync_end - mode->vsync_start,
+				   VC4_HDMI_VERTA_VSP) |
+		     VC4_SET_FIELD(mode->vsync_start - mode->vdisplay,
+				   VC4_HDMI_VERTA_VFP) |
+		     VC4_SET_FIELD(vactive, VC4_HDMI_VERTA_VAL));
+	u32 vertb = (VC4_SET_FIELD(0, VC4_HDMI_VERTB_VSPO) |
+		     VC4_SET_FIELD(mode->vtotal - mode->vsync_end,
+				   VC4_HDMI_VERTB_VBP));
+
+	if (debug_dump_regs) {
+		DRM_INFO("HDMI regs before:\n");
+		vc4_hdmi_dump_regs(dev);
+	}
+
+	HD_WRITE(VC4_HD_VID_CTL, 0);
+
+	/* XXX: This is where we would set the HDMI state machine
+	 * clock, if we had an interface for it.
+	 */
+
+	HDMI_WRITE(VC4_HDMI_SCHEDULER_CONTROL,
+		   HDMI_READ(VC4_HDMI_SCHEDULER_CONTROL) |
+		   VC4_HDMI_SCHEDULER_CONTROL_MANUAL_FORMAT |
+		   VC4_HDMI_SCHEDULER_CONTROL_IGNORE_VSYNC_PREDICTS);
+
+	HDMI_WRITE(VC4_HDMI_HORZA,
+		   (vsync_pos ? VC4_HDMI_HORZA_VPOS : 0) |
+		   (hsync_pos ? VC4_HDMI_HORZA_HPOS : 0) |
+		   VC4_SET_FIELD(mode->hdisplay, VC4_HDMI_HORZA_HAP));
+
+	HDMI_WRITE(VC4_HDMI_HORZB,
+		   VC4_SET_FIELD(mode->htotal - mode->hsync_end,
+				 VC4_HDMI_HORZB_HBP) |
+		   VC4_SET_FIELD(mode->hsync_end - mode->hsync_start,
+				 VC4_HDMI_HORZB_HSP) |
+		   VC4_SET_FIELD(mode->hsync_start - mode->hdisplay,
+				 VC4_HDMI_HORZB_HFP));
+
+	HDMI_WRITE(VC4_HDMI_VERTA0, verta);
+	HDMI_WRITE(VC4_HDMI_VERTA1, verta);
+
+	HDMI_WRITE(VC4_HDMI_VERTB0, vertb);
+	HDMI_WRITE(VC4_HDMI_VERTB1, vertb);
+
+	HD_WRITE(VC4_HD_VID_CTL,
+		 (vsync_pos ? 0 : VC4_HD_VID_CTL_VSYNC_LOW) |
+		 (hsync_pos ? 0 : VC4_HD_VID_CTL_HSYNC_LOW));
+
+	/* The RGB order applies even when CSC is disabled. */
+	HD_WRITE(VC4_HD_CSC_CTL, VC4_SET_FIELD(VC4_HD_CSC_CTL_ORDER_BGR,
+					       VC4_HD_CSC_CTL_ORDER));
+
+	HDMI_WRITE(VC4_HDMI_FIFO_CTL, VC4_HDMI_FIFO_CTL_MASTER_SLAVE_N);
+
+	if (debug_dump_regs) {
+		DRM_INFO("HDMI regs after:\n");
+		vc4_hdmi_dump_regs(dev);
+	}
+}
+
+static void vc4_hdmi_encoder_disable(struct drm_encoder *encoder)
+{
+	struct drm_device *dev = encoder->dev;
+	struct vc4_dev *vc4 = to_vc4_dev(dev);
+
+	HDMI_WRITE(VC4_HDMI_TX_PHY_RESET_CTL, 0xf << 16);
+	HD_WRITE(VC4_HD_VID_CTL,
+		 HD_READ(VC4_HD_VID_CTL) & ~VC4_HD_VID_CTL_ENABLE);
+}
+
+static void vc4_hdmi_encoder_enable(struct drm_encoder *encoder)
+{
+	struct vc4_hdmi_encoder *vc4_encoder = to_vc4_hdmi_encoder(encoder);
+	struct drm_device *dev = encoder->dev;
+	struct vc4_dev *vc4 = to_vc4_dev(dev);
+
+	HDMI_WRITE(VC4_HDMI_TX_PHY_RESET_CTL, 0);
+
+	HD_WRITE(VC4_HD_VID_CTL,
+		 HD_READ(VC4_HD_VID_CTL) |
+		 VC4_HD_VID_CTL_ENABLE |
+		 VC4_HD_VID_CTL_UNDERFLOW_ENABLE |
+		 VC4_HD_VID_CTL_FRAME_COUNTER_RESET);
+
+	if (vc4_encoder->hdmi_monitor) {
+		HDMI_WRITE(VC4_HDMI_SCHEDULER_CONTROL,
+			   HDMI_READ(VC4_HDMI_SCHEDULER_CONTROL) |
+			   VC4_HDMI_SCHEDULER_CONTROL_MODE_HDMI);
+
+		while (!(HDMI_READ(VC4_HDMI_SCHEDULER_CONTROL) &
+			 VC4_HDMI_SCHEDULER_CONTROL_HDMI_ACTIVE)) {
+			cpu_relax();
+		}
+	} else {
+		HDMI_WRITE(VC4_HDMI_RAM_PACKET_CONFIG,
+			   HDMI_READ(VC4_HDMI_RAM_PACKET_CONFIG) &
+			   ~(VC4_HDMI_RAM_PACKET_ENABLE));
+		HDMI_WRITE(VC4_HDMI_SCHEDULER_CONTROL,
+			   HDMI_READ(VC4_HDMI_SCHEDULER_CONTROL) &
+			   ~VC4_HDMI_SCHEDULER_CONTROL_MODE_HDMI);
+
+		while (HDMI_READ(VC4_HDMI_SCHEDULER_CONTROL) &
+		       VC4_HDMI_SCHEDULER_CONTROL_HDMI_ACTIVE) {
+			cpu_relax();
+		}
+	}
+
+	if (vc4_encoder->hdmi_monitor) {
+		u32 drift;
+
+		WARN_ON(!(HDMI_READ(VC4_HDMI_SCHEDULER_CONTROL) &
+			  VC4_HDMI_SCHEDULER_CONTROL_HDMI_ACTIVE));
+		HDMI_WRITE(VC4_HDMI_SCHEDULER_CONTROL,
+			   HDMI_READ(VC4_HDMI_SCHEDULER_CONTROL) |
+			   VC4_HDMI_SCHEDULER_CONTROL_VERT_ALWAYS_KEEPOUT);
+
+		/* XXX: Set HDMI_RAM_PACKET_CONFIG (1 << 16) and set
+		 * up the infoframe.
+		 */
+
+		drift = HDMI_READ(VC4_HDMI_FIFO_CTL);
+		drift &= VC4_HDMI_FIFO_VALID_WRITE_MASK;
+
+		HDMI_WRITE(VC4_HDMI_FIFO_CTL,
+			   drift & ~VC4_HDMI_FIFO_CTL_RECENTER);
+		HDMI_WRITE(VC4_HDMI_FIFO_CTL,
+			   drift | VC4_HDMI_FIFO_CTL_RECENTER);
+		udelay(1000);
+		HDMI_WRITE(VC4_HDMI_FIFO_CTL,
+			   drift & ~VC4_HDMI_FIFO_CTL_RECENTER);
+		HDMI_WRITE(VC4_HDMI_FIFO_CTL,
+			   drift | VC4_HDMI_FIFO_CTL_RECENTER);
+
+		while ((HDMI_READ(VC4_HDMI_FIFO_CTL) &
+			VC4_HDMI_FIFO_CTL_RECENTER_DONE) == 0) {
+			cpu_relax();
+		}
+	}
+}
+
+static const struct drm_encoder_helper_funcs vc4_hdmi_encoder_helper_funcs = {
+	.mode_fixup = vc4_hdmi_encoder_mode_fixup,
+	.mode_set = vc4_hdmi_encoder_mode_set,
+	.disable = vc4_hdmi_encoder_disable,
+	.enable = vc4_hdmi_encoder_enable,
+};
+
+static struct drm_crtc *
+vc4_get_crtc_node(struct platform_device *pdev)
+{
+	struct device_node *crtc_node;
+	struct platform_device *crtc_pdev;
+
+	crtc_node = of_parse_phandle(pdev->dev.of_node, "crtc", 0);
+	if (!crtc_node) {
+		DRM_ERROR("No CRTC for hdmi in DT\n");
+		return ERR_PTR(-EINVAL);
+	}
+
+	crtc_pdev = of_find_device_by_node(crtc_node);
+	if (!crtc_pdev) {
+		DRM_ERROR("No CRTC device attached to OF node\n");
+		return ERR_PTR(-EINVAL);
+	}
+
+	return platform_get_drvdata(crtc_pdev);
+}
+
+struct drm_encoder *vc4_hdmi_encoder_init(struct drm_device *dev)
+{
+	struct vc4_dev *vc4 = to_vc4_dev(dev);
+	struct drm_encoder *encoder = NULL;
+	struct vc4_hdmi_encoder *vc4_hdmi_encoder;
+	struct drm_crtc *crtc;
+	int ret;
+
+	vc4_hdmi_encoder = devm_kzalloc(dev->dev, sizeof(*vc4_hdmi_encoder),
+					GFP_KERNEL);
+	if (!vc4_hdmi_encoder) {
+		ret = -ENOMEM;
+		goto fail;
+	}
+	encoder = &vc4_hdmi_encoder->base;
+
+	crtc = vc4_get_crtc_node(vc4->hdmi->pdev);
+	if (IS_ERR(crtc)) {
+		ret = PTR_ERR(crtc);
+		goto fail;
+	}
+
+	drm_encoder_init(dev, encoder, &vc4_hdmi_encoder_funcs,
+			 DRM_MODE_ENCODER_TMDS);
+	drm_encoder_helper_add(encoder, &vc4_hdmi_encoder_helper_funcs);
+
+	encoder->possible_crtcs = drm_crtc_mask(crtc);
+
+	return encoder;
+
+fail:
+	if (encoder)
+		vc4_encoder_destroy(encoder);
+
+	return ERR_PTR(ret);
+}
+
+/* Reads out the current HDMI mode progreamming at driver load time.
+ *
+ * This is currently used for later filtering out of the DDC-probed
+ * video modes, since we can't actually change modes due to not having
+ * control of the necessary clocks.  Later on, we may end up reusing
+ * this for skipping modesets at boot time.
+ */
+static void
+vc4_hdmi_get_boot_display_mode(struct vc4_dev *vc4)
+{
+	struct drm_display_mode *mode = &vc4->hdmi->boot_mode;
+	u32 horza = HDMI_READ(VC4_HDMI_HORZA);
+	u32 horzb = HDMI_READ(VC4_HDMI_HORZB);
+	u32 verta = HDMI_READ(VC4_HDMI_VERTA0);
+	u32 vertb = HDMI_READ(VC4_HDMI_VERTB0);
+
+	memset(mode, 0, sizeof(*mode));
+
+	if (!(horza & VC4_HDMI_HORZA_VPOS))
+		mode->flags |= DRM_MODE_FLAG_NVSYNC;
+	if (!(horza & VC4_HDMI_HORZA_HPOS))
+		mode->flags |= DRM_MODE_FLAG_NHSYNC;
+	mode->hdisplay = VC4_GET_FIELD(horza, VC4_HDMI_HORZA_HAP);
+	mode->hsync_start = (mode->hdisplay +
+			     VC4_GET_FIELD(horzb, VC4_HDMI_HORZB_HFP));
+	mode->hsync_end = (mode->hsync_start +
+			   VC4_GET_FIELD(horzb, VC4_HDMI_HORZB_HSP));
+	mode->htotal = (mode->hsync_end +
+			VC4_GET_FIELD(horzb, VC4_HDMI_HORZB_HBP));
+
+	mode->vdisplay = VC4_GET_FIELD(verta, VC4_HDMI_VERTA_VAL);
+	mode->vsync_start = (mode->vdisplay +
+			     VC4_GET_FIELD(verta, VC4_HDMI_VERTA_VFP));
+	mode->vsync_end = (mode->vsync_start +
+			   VC4_GET_FIELD(verta, VC4_HDMI_VERTA_VSP));
+	mode->vtotal = (mode->vsync_end +
+			VC4_GET_FIELD(vertb, VC4_HDMI_VERTB_VBP));
+}
+
+static int vc4_hdmi_bind(struct device *dev, struct device *master, void *data)
+{
+	struct platform_device *pdev = to_platform_device(dev);
+	struct drm_device *drm = dev_get_drvdata(master);
+	struct vc4_dev *vc4 = drm->dev_private;
+	struct vc4_hdmi *hdmi;
+	struct device_node *ddc_node;
+	u32 value;
+
+	hdmi = devm_kzalloc(dev, sizeof(*hdmi), GFP_KERNEL);
+	if (!hdmi)
+		return -ENOMEM;
+
+	hdmi->pdev = pdev;
+	hdmi->hdmicore_regs = vc4_ioremap_regs(pdev, 0);
+	if (IS_ERR(hdmi->hdmicore_regs))
+		return PTR_ERR(hdmi->hdmicore_regs);
+
+	hdmi->hd_regs = vc4_ioremap_regs(pdev, 1);
+	if (IS_ERR(hdmi->hd_regs))
+		return PTR_ERR(hdmi->hd_regs);
+
+	/* DDC i2c driver */
+	ddc_node = of_parse_phandle(dev->of_node, "ddc", 0);
+	if (!ddc_node) {
+		DRM_ERROR("Failed to find ddc node in device tree\n");
+		return -ENODEV;
+	}
+
+	hdmi->ddc = of_find_i2c_adapter_by_node(ddc_node);
+	if (!hdmi->ddc) {
+		DRM_ERROR("Failed to get ddc i2c adapter by node\n");
+		return -EPROBE_DEFER;
+	}
+
+	/* Only use the GPIO HPD pin if present in the DT, otherwise
+	 * we'll use the HDMI core's register.
+	 */
+	if (of_find_property(dev->of_node, "hpd-gpio", &value)) {
+		hdmi->hpd_gpio = of_get_named_gpio(dev->of_node, "hpd-gpio", 0);
+		if (hdmi->hpd_gpio < 0)
+			return hdmi->hpd_gpio;
+	}
+
+	vc4->hdmi = hdmi;
+
+	/* HDMI core must be enabled. */
+	WARN_ON_ONCE((HD_READ(VC4_HD_M_CTL) & VC4_HD_M_ENABLE) == 0);
+
+	vc4_hdmi_get_boot_display_mode(vc4);
+
+	return 0;
+}
+
+static void vc4_hdmi_unbind(struct device *dev, struct device *master,
+			    void *data)
+{
+	struct drm_device *drm = dev_get_drvdata(master);
+	struct vc4_dev *vc4 = drm->dev_private;
+
+	put_device(&vc4->hdmi->ddc->dev);
+
+	vc4->hdmi = NULL;
+}
+
+static const struct component_ops vc4_hdmi_ops = {
+	.bind   = vc4_hdmi_bind,
+	.unbind = vc4_hdmi_unbind,
+};
+
+static int vc4_hdmi_dev_probe(struct platform_device *pdev)
+{
+	return component_add(&pdev->dev, &vc4_hdmi_ops);
+}
+
+static int vc4_hdmi_dev_remove(struct platform_device *pdev)
+{
+	component_del(&pdev->dev, &vc4_hdmi_ops);
+	return 0;
+}
+
+static const struct of_device_id vc4_hdmi_dt_match[] = {
+	{ .compatible = "brcm,vc4-hdmi" },
+	{}
+};
+
+static struct platform_driver vc4_hdmi_driver = {
+	.probe = vc4_hdmi_dev_probe,
+	.remove = vc4_hdmi_dev_remove,
+	.driver = {
+		.name = "vc4_hdmi",
+		.of_match_table = vc4_hdmi_dt_match,
+	},
+};
+
+void __init vc4_hdmi_register(void)
+{
+	platform_driver_register(&vc4_hdmi_driver);
+}
+
+void __exit vc4_hdmi_unregister(void)
+{
+	platform_driver_unregister(&vc4_hdmi_driver);
+}
diff --git a/drivers/gpu/drm/vc4/vc4_hvs.c b/drivers/gpu/drm/vc4/vc4_hvs.c
new file mode 100644
index 0000000..dcf4f78
--- /dev/null
+++ b/drivers/gpu/drm/vc4/vc4_hvs.c
@@ -0,0 +1,172 @@
+/*
+ * Copyright (C) 2015 Broadcom
+ *
+ * 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.
+ */
+
+/**
+ * DOC: VC4 HVS module.
+ *
+ * The HVS is the piece of hardware that does translation, scaling,
+ * colorspace conversion, and compositing of pixels stored in
+ * framebuffers into a FIFO of pixels going out to the Pixel Valve
+ * (CRTC).
+ *
+ * There is a single global HVS, with multiple output FIFOs that can
+ * be consumed by the PVs.  This file just manages the resources for
+ * the HVS, while the vc4_crtc.c code actually drives HVS setup for
+ * each CRTC.
+ */
+
+#include "linux/component.h"
+#include "vc4_drv.h"
+#include "vc4_regs.h"
+
+#define HVS_REG(reg) { reg, #reg }
+static const struct {
+	u32 reg;
+	const char *name;
+} hvs_regs[] = {
+	HVS_REG(SCALER_DISPCTRL),
+	HVS_REG(SCALER_DISPSTAT),
+	HVS_REG(SCALER_DISPID),
+	HVS_REG(SCALER_DISPECTRL),
+	HVS_REG(SCALER_DISPPROF),
+	HVS_REG(SCALER_DISPDITHER),
+	HVS_REG(SCALER_DISPEOLN),
+	HVS_REG(SCALER_DISPLIST0),
+	HVS_REG(SCALER_DISPLIST1),
+	HVS_REG(SCALER_DISPLIST2),
+	HVS_REG(SCALER_DISPLSTAT),
+	HVS_REG(SCALER_DISPLACT0),
+	HVS_REG(SCALER_DISPLACT1),
+	HVS_REG(SCALER_DISPLACT2),
+	HVS_REG(SCALER_DISPCTRL0),
+	HVS_REG(SCALER_DISPBKGND0),
+	HVS_REG(SCALER_DISPSTAT0),
+	HVS_REG(SCALER_DISPBASE0),
+	HVS_REG(SCALER_DISPCTRL1),
+	HVS_REG(SCALER_DISPBKGND1),
+	HVS_REG(SCALER_DISPSTAT1),
+	HVS_REG(SCALER_DISPBASE1),
+	HVS_REG(SCALER_DISPCTRL2),
+	HVS_REG(SCALER_DISPBKGND2),
+	HVS_REG(SCALER_DISPSTAT2),
+	HVS_REG(SCALER_DISPBASE2),
+	HVS_REG(SCALER_DISPALPHA2),
+};
+
+void
+vc4_hvs_dump_state(struct drm_device *dev)
+{
+	struct vc4_dev *vc4 = to_vc4_dev(dev);
+	int i;
+
+	for (i = 0; i < ARRAY_SIZE(hvs_regs); i++) {
+		DRM_INFO("0x%04x (%s): 0x%08x\n",
+			 hvs_regs[i].reg, hvs_regs[i].name,
+			 HVS_READ(hvs_regs[i].reg));
+	}
+
+	DRM_INFO("HVS ctx:\n");
+	for (i = 0; i < 64; i += 4) {
+		DRM_INFO("0x%08x (%s): 0x%08x 0x%08x 0x%08x 0x%08x\n",
+			 i * 4, i < HVS_BOOTLOADER_DLIST_END ? "B" : "D",
+			 ((uint32_t *)vc4->hvs->dlist)[i + 0],
+			 ((uint32_t *)vc4->hvs->dlist)[i + 1],
+			 ((uint32_t *)vc4->hvs->dlist)[i + 2],
+			 ((uint32_t *)vc4->hvs->dlist)[i + 3]);
+	}
+}
+
+#ifdef CONFIG_DEBUG_FS
+int vc4_hvs_debugfs_regs(struct seq_file *m, void *unused)
+{
+	struct drm_info_node *node = (struct drm_info_node *) m->private;
+	struct drm_device *dev = node->minor->dev;
+	struct vc4_dev *vc4 = to_vc4_dev(dev);
+	int i;
+
+	for (i = 0; i < ARRAY_SIZE(hvs_regs); i++) {
+		seq_printf(m, "%s (0x%04x): 0x%08x\n",
+			   hvs_regs[i].name, hvs_regs[i].reg,
+			   HVS_READ(hvs_regs[i].reg));
+	}
+
+	return 0;
+}
+#endif
+
+static int vc4_hvs_bind(struct device *dev, struct device *master, void *data)
+{
+	struct platform_device *pdev = to_platform_device(dev);
+	struct drm_device *drm = dev_get_drvdata(master);
+	struct vc4_dev *vc4 = drm->dev_private;
+	struct vc4_hvs *hvs = NULL;
+
+	hvs = devm_kzalloc(&pdev->dev, sizeof(*hvs), GFP_KERNEL);
+	if (!hvs)
+		return -ENOMEM;
+
+	hvs->pdev = pdev;
+
+	hvs->regs = vc4_ioremap_regs(pdev, 0);
+	if (IS_ERR(hvs->regs))
+		return PTR_ERR(hvs->regs);
+
+	hvs->dlist = hvs->regs + SCALER_DLIST_START;
+
+	vc4->hvs = hvs;
+	return 0;
+}
+
+static void vc4_hvs_unbind(struct device *dev, struct device *master,
+			   void *data)
+{
+	struct drm_device *drm = dev_get_drvdata(master);
+	struct vc4_dev *vc4 = drm->dev_private;
+
+	vc4->hvs = NULL;
+}
+
+static const struct component_ops vc4_hvs_ops = {
+	.bind   = vc4_hvs_bind,
+	.unbind = vc4_hvs_unbind,
+};
+
+static int vc4_hvs_dev_probe(struct platform_device *pdev)
+{
+	return component_add(&pdev->dev, &vc4_hvs_ops);
+}
+
+static int vc4_hvs_dev_remove(struct platform_device *pdev)
+{
+	component_del(&pdev->dev, &vc4_hvs_ops);
+	return 0;
+}
+
+static const struct of_device_id vc4_hvs_dt_match[] = {
+	{ .compatible = "brcm,vc4-hvs" },
+	{}
+};
+
+static struct platform_driver vc4_hvs_driver = {
+	.probe = vc4_hvs_dev_probe,
+	.remove = vc4_hvs_dev_remove,
+	.driver = {
+		.name = "vc4_hvs",
+		.of_match_table = vc4_hvs_dt_match,
+	},
+};
+
+void __init vc4_hvs_register(void)
+{
+	platform_driver_register(&vc4_hvs_driver);
+}
+
+void __exit vc4_hvs_unregister(void)
+{
+	platform_driver_unregister(&vc4_hvs_driver);
+}
diff --git a/drivers/gpu/drm/vc4/vc4_kms.c b/drivers/gpu/drm/vc4/vc4_kms.c
new file mode 100644
index 0000000..e5e96bc
--- /dev/null
+++ b/drivers/gpu/drm/vc4/vc4_kms.c
@@ -0,0 +1,84 @@
+/*
+ * Copyright (C) 2015 Broadcom
+ *
+ * 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.
+ */
+
+/**
+ * DOC: VC4 KMS
+ *
+ * This is the general code for implementing KMS mode setting that
+ * doesn't clearly associate with any of the other objects (plane,
+ * crtc, HDMI encoder).
+ */
+
+#include "drm_crtc.h"
+#include "drm_atomic_helper.h"
+#include "drm_crtc_helper.h"
+#include "drm_plane_helper.h"
+#include "drm_fb_cma_helper.h"
+#include "vc4_drv.h"
+
+static const struct drm_mode_config_funcs vc4_mode_funcs = {
+	.atomic_check = drm_atomic_helper_check,
+	.atomic_commit = drm_atomic_helper_commit,
+	.fb_create = drm_fb_cma_create,
+};
+
+/* Calls out to initialize all of the VC4 KMS objects. */
+static int vc4_init_modeset_objects(struct drm_device *dev)
+{
+	struct drm_encoder *encoder;
+	struct drm_connector *connector;
+	int ret = 0;
+
+	encoder = vc4_hdmi_encoder_init(dev);
+	if (IS_ERR(encoder)) {
+		dev_err(dev->dev, "failed to construct HDMI encoder\n");
+		ret = PTR_ERR(encoder);
+		goto fail;
+	}
+
+	connector = vc4_hdmi_connector_init(dev, encoder);
+	if (IS_ERR(connector)) {
+		ret = PTR_ERR(connector);
+		dev_err(dev->dev, "failed to initialize HDMI connector\n");
+		goto fail;
+	}
+
+fail:
+	return ret;
+}
+
+int vc4_kms_load(struct drm_device *dev)
+{
+	int ret;
+
+	ret = drm_vblank_init(dev, dev->mode_config.num_crtc);
+	if (ret < 0) {
+		dev_err(dev->dev, "failed to initialize vblank\n");
+		return ret;
+	}
+
+	dev->mode_config.max_width = 2048;
+	dev->mode_config.max_height = 2048;
+	dev->mode_config.funcs = &vc4_mode_funcs;
+	dev->mode_config.preferred_depth = 24;
+
+	ret = vc4_init_modeset_objects(dev);
+	if (ret)
+		goto fail;
+
+	drm_mode_config_reset(dev);
+
+	drm_fbdev_cma_init(dev, 32,
+			   dev->mode_config.num_crtc,
+			   dev->mode_config.num_connector);
+
+	drm_kms_helper_poll_init(dev);
+
+fail:
+	return ret;
+}
diff --git a/drivers/gpu/drm/vc4/vc4_plane.c b/drivers/gpu/drm/vc4/vc4_plane.c
new file mode 100644
index 0000000..cdd8b10
--- /dev/null
+++ b/drivers/gpu/drm/vc4/vc4_plane.c
@@ -0,0 +1,320 @@
+/*
+ * Copyright (C) 2015 Broadcom
+ *
+ * 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.
+ */
+
+/**
+ * DOC: VC4 plane module
+ *
+ * Each DRM plane is a layer of pixels being scanned out by the HVS.
+ *
+ * At atomic modeset check time, we compute the HVS display element
+ * state that would be necessary for displaying the plane (giving us a
+ * chance to figure out if a plane configuration is invalid), then at
+ * atomic flush time the CRTC will ask us to write our element state
+ * into the region of the HVS that it has allocated for us.
+ */
+
+#include "vc4_drv.h"
+#include "vc4_regs.h"
+#include "drm_atomic_helper.h"
+#include "drm_fb_cma_helper.h"
+#include "drm_plane_helper.h"
+
+struct vc4_plane_state {
+	struct drm_plane_state base;
+	u32 *dlist;
+	u32 dlist_size; /* Number of dwords in allocated for the display list */
+	u32 dlist_count; /* Number of used dwords in the display list. */
+};
+
+static inline struct vc4_plane_state *
+to_vc4_plane_state(struct drm_plane_state *state)
+{
+	return (struct vc4_plane_state *)state;
+}
+
+static const struct hvs_format {
+	u32 drm; /* DRM_FORMAT_* */
+	u32 hvs; /* HVS_FORMAT_* */
+	u32 pixel_order;
+	bool has_alpha;
+} hvs_formats[] = {
+	{
+		.drm = DRM_FORMAT_XRGB8888, .hvs = HVS_PIXEL_FORMAT_RGBA8888,
+		.pixel_order = HVS_PIXEL_ORDER_ABGR, .has_alpha = false,
+	},
+	{
+		.drm = DRM_FORMAT_ARGB8888, .hvs = HVS_PIXEL_FORMAT_RGBA8888,
+		.pixel_order = HVS_PIXEL_ORDER_ABGR, .has_alpha = true,
+	},
+};
+
+static const struct hvs_format *vc4_get_hvs_format(u32 drm_format)
+{
+	unsigned i;
+
+	for (i = 0; i < ARRAY_SIZE(hvs_formats); i++) {
+		if (hvs_formats[i].drm == drm_format)
+			return &hvs_formats[i];
+	}
+
+	return NULL;
+}
+
+static bool plane_enabled(struct drm_plane_state *state)
+{
+	return state->fb && state->crtc;
+}
+
+struct drm_plane_state *vc4_plane_duplicate_state(struct drm_plane *plane)
+{
+	struct vc4_plane_state *vc4_state;
+
+	if (WARN_ON(!plane->state))
+		return NULL;
+
+	vc4_state = kmemdup(plane->state, sizeof(*vc4_state), GFP_KERNEL);
+	if (!vc4_state)
+		return NULL;
+
+	__drm_atomic_helper_plane_duplicate_state(plane, &vc4_state->base);
+
+	if (vc4_state->dlist) {
+		vc4_state->dlist = kmemdup(vc4_state->dlist,
+					   vc4_state->dlist_count * 4,
+					   GFP_KERNEL);
+		if (!vc4_state->dlist) {
+			kfree(vc4_state);
+			return NULL;
+		}
+		vc4_state->dlist_size = vc4_state->dlist_count;
+	}
+
+	return &vc4_state->base;
+}
+
+void vc4_plane_destroy_state(struct drm_plane *plane,
+			     struct drm_plane_state *state)
+{
+	struct vc4_plane_state *vc4_state = to_vc4_plane_state(state);
+
+	kfree(vc4_state->dlist);
+	__drm_atomic_helper_plane_destroy_state(plane, &vc4_state->base);
+	kfree(state);
+}
+
+/* Called during init to allocate the plane's atomic state. */
+void vc4_plane_reset(struct drm_plane *plane)
+{
+	struct vc4_plane_state *vc4_state;
+
+	WARN_ON(plane->state);
+
+	vc4_state = kzalloc(sizeof(*vc4_state), GFP_KERNEL);
+	if (!vc4_state)
+		return;
+
+	plane->state = &vc4_state->base;
+	vc4_state->base.plane = plane;
+}
+
+static void vc4_dlist_write(struct vc4_plane_state *vc4_state, u32 val)
+{
+	if (vc4_state->dlist_count == vc4_state->dlist_size) {
+		u32 new_size = max(4u, vc4_state->dlist_count * 2);
+		u32 *new_dlist = kmalloc(new_size * 4, GFP_KERNEL);
+
+		if (!new_dlist)
+			return;
+		memcpy(new_dlist, vc4_state->dlist, vc4_state->dlist_count * 4);
+
+		kfree(vc4_state->dlist);
+		vc4_state->dlist = new_dlist;
+		vc4_state->dlist_size = new_size;
+	}
+
+	vc4_state->dlist[vc4_state->dlist_count++] = val;
+}
+
+/* Writes out a full display list for an active plane to the plane's
+ * private dlist state.
+ */
+static int vc4_plane_mode_set(struct drm_plane *plane,
+			      struct drm_plane_state *state)
+{
+	struct vc4_plane_state *vc4_state = to_vc4_plane_state(state);
+	struct drm_framebuffer *fb = state->fb;
+	struct drm_gem_cma_object *bo = drm_fb_cma_get_gem_obj(fb, 0);
+	u32 ctl0_offset = vc4_state->dlist_count;
+	const struct hvs_format *format = vc4_get_hvs_format(fb->pixel_format);
+	uint32_t offset = fb->offsets[0];
+	int crtc_x = state->crtc_x;
+	int crtc_y = state->crtc_y;
+	int crtc_w = state->crtc_w;
+	int crtc_h = state->crtc_h;
+
+	if (crtc_x < 0) {
+		offset += drm_format_plane_cpp(fb->pixel_format, 0) * -crtc_x;
+		crtc_w += crtc_x;
+		crtc_x = 0;
+	}
+
+	if (crtc_y < 0) {
+		offset += fb->pitches[0] * -crtc_y;
+		crtc_h += crtc_y;
+		crtc_y = 0;
+	}
+
+	vc4_dlist_write(vc4_state,
+			SCALER_CTL0_VALID |
+			(format->pixel_order << SCALER_CTL0_ORDER_SHIFT) |
+			(format->hvs << SCALER_CTL0_PIXEL_FORMAT_SHIFT) |
+			SCALER_CTL0_UNITY);
+
+	/* Position Word 0: Image Positions and Alpha Value */
+	vc4_dlist_write(vc4_state,
+			VC4_SET_FIELD(0xff, SCALER_POS0_FIXED_ALPHA) |
+			VC4_SET_FIELD(crtc_x, SCALER_POS0_START_X) |
+			VC4_SET_FIELD(crtc_y, SCALER_POS0_START_Y));
+
+	/* Position Word 1: Scaled Image Dimensions.
+	 * Skipped due to SCALER_CTL0_UNITY scaling.
+	 */
+
+	/* Position Word 2: Source Image Size, Alpha Mode */
+	vc4_dlist_write(vc4_state,
+			VC4_SET_FIELD(format->has_alpha ?
+				      SCALER_POS2_ALPHA_MODE_PIPELINE :
+				      SCALER_POS2_ALPHA_MODE_FIXED,
+				      SCALER_POS2_ALPHA_MODE) |
+			VC4_SET_FIELD(crtc_w, SCALER_POS2_WIDTH) |
+			VC4_SET_FIELD(crtc_h, SCALER_POS2_HEIGHT));
+
+	/* Position Word 3: Context.  Written by the HVS. */
+	vc4_dlist_write(vc4_state, 0xc0c0c0c0);
+
+	/* Pointer Word 0: RGB / Y Pointer */
+	vc4_dlist_write(vc4_state, bo->paddr + offset);
+
+	/* Pointer Context Word 0: Written by the HVS */
+	vc4_dlist_write(vc4_state, 0xc0c0c0c0);
+
+	/* Pitch word 0: Pointer 0 Pitch */
+	vc4_dlist_write(vc4_state,
+			VC4_SET_FIELD(fb->pitches[0], SCALER_SRC_PITCH));
+
+	vc4_state->dlist[ctl0_offset] |=
+		VC4_SET_FIELD(vc4_state->dlist_count, SCALER_CTL0_SIZE);
+
+	return 0;
+}
+
+/* If a modeset involves changing the setup of a plane, the atomic
+ * infrastructure will call this to validate a proposed plane setup.
+ * However, if a plane isn't getting updated, this (and the
+ * corresponding vc4_plane_atomic_update) won't get called.  Thus, we
+ * compute the dlist here and have all active plane dlists get updated
+ * in the CRTC's flush.
+ */
+static int vc4_plane_atomic_check(struct drm_plane *plane,
+				  struct drm_plane_state *state)
+{
+	struct vc4_plane_state *vc4_state = to_vc4_plane_state(state);
+
+	vc4_state->dlist_count = 0;
+
+	if (plane_enabled(state))
+		return vc4_plane_mode_set(plane, state);
+	else
+		return 0;
+}
+
+static void vc4_plane_atomic_update(struct drm_plane *plane,
+				    struct drm_plane_state *old_state)
+{
+	/* No contents here.  Since we don't know where in the CRTC's
+	 * dlist we should be stored, our dlist is uploaded to the
+	 * hardware with vc4_plane_write_dlist() at CRTC atomic_flush
+	 * time.
+	 */
+}
+
+u32 vc4_plane_write_dlist(struct drm_plane *plane, u32 __iomem *dlist)
+{
+	struct vc4_plane_state *vc4_state = to_vc4_plane_state(plane->state);
+	int i;
+
+	/* Can't memcpy_toio() because it needs to be 32-bit writes. */
+	for (i = 0; i < vc4_state->dlist_count; i++)
+		writel(vc4_state->dlist[i], &dlist[i]);
+
+	return vc4_state->dlist_count;
+}
+
+u32 vc4_plane_dlist_size(struct drm_plane_state *state)
+{
+	struct vc4_plane_state *vc4_state = to_vc4_plane_state(state);
+
+	return vc4_state->dlist_count;
+}
+
+static const struct drm_plane_helper_funcs vc4_plane_helper_funcs = {
+	.prepare_fb = NULL,
+	.cleanup_fb = NULL,
+	.atomic_check = vc4_plane_atomic_check,
+	.atomic_update = vc4_plane_atomic_update,
+};
+
+static void vc4_plane_destroy(struct drm_plane *plane)
+{
+	drm_plane_helper_disable(plane);
+	drm_plane_cleanup(plane);
+}
+
+static const struct drm_plane_funcs vc4_plane_funcs = {
+	.update_plane = drm_atomic_helper_update_plane,
+	.disable_plane = drm_atomic_helper_disable_plane,
+	.destroy = vc4_plane_destroy,
+	.set_property = NULL,
+	.reset = vc4_plane_reset,
+	.atomic_duplicate_state = vc4_plane_duplicate_state,
+	.atomic_destroy_state = vc4_plane_destroy_state,
+};
+
+struct drm_plane *vc4_plane_init(struct drm_device *dev,
+				 enum drm_plane_type type)
+{
+	struct drm_plane *plane = NULL;
+	struct vc4_plane *vc4_plane;
+	u32 formats[ARRAY_SIZE(hvs_formats)];
+	int ret = 0;
+	unsigned i;
+
+	vc4_plane = devm_kzalloc(dev->dev, sizeof(*vc4_plane),
+				 GFP_KERNEL);
+	if (!vc4_plane) {
+		ret = -ENOMEM;
+		goto fail;
+	}
+
+	for (i = 0; i < ARRAY_SIZE(hvs_formats); i++)
+		formats[i] = hvs_formats[i].drm;
+	plane = &vc4_plane->base;
+	ret = drm_universal_plane_init(dev, plane, 0xff,
+				       &vc4_plane_funcs,
+				       formats, ARRAY_SIZE(formats),
+				       type);
+
+	drm_plane_helper_add(plane, &vc4_plane_helper_funcs);
+
+	return plane;
+fail:
+	if (plane)
+		vc4_plane_destroy(plane);
+
+	return ERR_PTR(ret);
+}
diff --git a/drivers/gpu/drm/vc4/vc4_regs.h b/drivers/gpu/drm/vc4/vc4_regs.h
new file mode 100644
index 0000000..0eff631
--- /dev/null
+++ b/drivers/gpu/drm/vc4/vc4_regs.h
@@ -0,0 +1,562 @@
+/*
+ *  Copyright ? 2014-2015 Broadcom
+ *
+ * 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.
+ */
+
+#define VC4_MASK(high, low) (((1 << ((high) - (low) + 1)) - 1) << (low))
+/* Using the GNU statement expression extension */
+#define VC4_SET_FIELD(value, field)					\
+	({								\
+		uint32_t fieldval = (value) << field##_SHIFT;		\
+		WARN_ON((fieldval & ~field##_MASK) != 0);		\
+		fieldval & field##_MASK;				\
+	 })
+
+#define VC4_GET_FIELD(word, field) (((word) & field##_MASK) >>		\
+				    field##_SHIFT)
+
+#define V3D_IDENT0   0x00000
+# define V3D_EXPECTED_IDENT0 \
+	((2 << 24) | \
+	('V' << 0) | \
+	('3' << 8) | \
+	 ('D' << 16))
+
+#define V3D_IDENT1   0x00004
+/* Multiples of 1kb */
+# define V3D_IDENT1_VPM_SIZE_MASK                      VC4_MASK(31, 28)
+# define V3D_IDENT1_VPM_SIZE_SHIFT                     28
+# define V3D_IDENT1_NSEM_MASK                          VC4_MASK(23, 16)
+# define V3D_IDENT1_NSEM_SHIFT                         16
+# define V3D_IDENT1_TUPS_MASK                          VC4_MASK(15, 12)
+# define V3D_IDENT1_TUPS_SHIFT                         12
+# define V3D_IDENT1_QUPS_MASK                          VC4_MASK(11, 8)
+# define V3D_IDENT1_QUPS_SHIFT                         8
+# define V3D_IDENT1_NSLC_MASK                          VC4_MASK(7, 4)
+# define V3D_IDENT1_NSLC_SHIFT                         4
+# define V3D_IDENT1_REV_MASK                           VC4_MASK(3, 0)
+# define V3D_IDENT1_REV_SHIFT                          0
+
+#define V3D_IDENT2   0x00008
+#define V3D_SCRATCH  0x00010
+#define V3D_L2CACTL  0x00020
+# define V3D_L2CACTL_L2CCLR                            (1 << 2)
+# define V3D_L2CACTL_L2CDIS                            (1 << 1)
+# define V3D_L2CACTL_L2CENA                            (1 << 0)
+
+#define V3D_SLCACTL  0x00024
+# define V3D_SLCACTL_T1CC_MASK                         VC4_MASK(27, 24)
+# define V3D_SLCACTL_T1CC_SHIFT                        24
+# define V3D_SLCACTL_T0CC_MASK                         VC4_MASK(19, 16)
+# define V3D_SLCACTL_T0CC_SHIFT                        16
+# define V3D_SLCACTL_UCC_MASK                          VC4_MASK(11, 8)
+# define V3D_SLCACTL_UCC_SHIFT                         8
+# define V3D_SLCACTL_ICC_MASK                          VC4_MASK(3, 0)
+# define V3D_SLCACTL_ICC_SHIFT                         0
+
+#define V3D_INTCTL   0x00030
+#define V3D_INTENA   0x00034
+#define V3D_INTDIS   0x00038
+# define V3D_INT_SPILLUSE                              (1 << 3)
+# define V3D_INT_OUTOMEM                               (1 << 2)
+# define V3D_INT_FLDONE                                (1 << 1)
+# define V3D_INT_FRDONE                                (1 << 0)
+
+#define V3D_CT0CS    0x00100
+#define V3D_CT1CS    0x00104
+#define V3D_CTNCS(n) (V3D_CT0CS + 4 * n)
+# define V3D_CTRSTA      (1 << 15)
+# define V3D_CTSEMA      (1 << 12)
+# define V3D_CTRTSD      (1 << 8)
+# define V3D_CTRUN       (1 << 5)
+# define V3D_CTSUBS      (1 << 4)
+# define V3D_CTERR       (1 << 3)
+# define V3D_CTMODE      (1 << 0)
+
+#define V3D_CT0EA    0x00108
+#define V3D_CT1EA    0x0010c
+#define V3D_CTNEA(n) (V3D_CT0EA + 4 * (n))
+#define V3D_CT0CA    0x00110
+#define V3D_CT1CA    0x00114
+#define V3D_CTNCA(n) (V3D_CT0CA + 4 * (n))
+#define V3D_CT00RA0  0x00118
+#define V3D_CT01RA0  0x0011c
+#define V3D_CTNRA0(n) (V3D_CT00RA0 + 4 * (n))
+#define V3D_CT0LC    0x00120
+#define V3D_CT1LC    0x00124
+#define V3D_CTNLC(n) (V3D_CT0LC + 4 * (n))
+#define V3D_CT0PC    0x00128
+#define V3D_CT1PC    0x0012c
+#define V3D_CTNPC(n) (V3D_CT0PC + 4 * (n))
+
+#define V3D_PCS      0x00130
+# define V3D_BMOOM       (1 << 8)
+# define V3D_RMBUSY      (1 << 3)
+# define V3D_RMACTIVE    (1 << 2)
+# define V3D_BMBUSY      (1 << 1)
+# define V3D_BMACTIVE    (1 << 0)
+
+#define V3D_BFC      0x00134
+#define V3D_RFC      0x00138
+#define V3D_BPCA     0x00300
+#define V3D_BPCS     0x00304
+#define V3D_BPOA     0x00308
+#define V3D_BPOS     0x0030c
+#define V3D_BXCF     0x00310
+#define V3D_SQRSV0   0x00410
+#define V3D_SQRSV1   0x00414
+#define V3D_SQCNTL   0x00418
+#define V3D_SRQPC    0x00430
+#define V3D_SRQUA    0x00434
+#define V3D_SRQUL    0x00438
+#define V3D_SRQCS    0x0043c
+#define V3D_VPACNTL  0x00500
+#define V3D_VPMBASE  0x00504
+#define V3D_PCTRC    0x00670
+#define V3D_PCTRE    0x00674
+#define V3D_PCTR0    0x00680
+#define V3D_PCTRS0   0x00684
+#define V3D_PCTR1    0x00688
+#define V3D_PCTRS1   0x0068c
+#define V3D_PCTR2    0x00690
+#define V3D_PCTRS2   0x00694
+#define V3D_PCTR3    0x00698
+#define V3D_PCTRS3   0x0069c
+#define V3D_PCTR4    0x006a0
+#define V3D_PCTRS4   0x006a4
+#define V3D_PCTR5    0x006a8
+#define V3D_PCTRS5   0x006ac
+#define V3D_PCTR6    0x006b0
+#define V3D_PCTRS6   0x006b4
+#define V3D_PCTR7    0x006b8
+#define V3D_PCTRS7   0x006bc
+#define V3D_PCTR8    0x006c0
+#define V3D_PCTRS8   0x006c4
+#define V3D_PCTR9    0x006c8
+#define V3D_PCTRS9   0x006cc
+#define V3D_PCTR10   0x006d0
+#define V3D_PCTRS10  0x006d4
+#define V3D_PCTR11   0x006d8
+#define V3D_PCTRS11  0x006dc
+#define V3D_PCTR12   0x006e0
+#define V3D_PCTRS12  0x006e4
+#define V3D_PCTR13   0x006e8
+#define V3D_PCTRS13  0x006ec
+#define V3D_PCTR14   0x006f0
+#define V3D_PCTRS14  0x006f4
+#define V3D_PCTR15   0x006f8
+#define V3D_PCTRS15  0x006fc
+#define V3D_BGE      0x00f00
+#define V3D_FDBGO    0x00f04
+#define V3D_FDBGB    0x00f08
+#define V3D_FDBGR    0x00f0c
+#define V3D_FDBGS    0x00f10
+#define V3D_ERRSTAT  0x00f20
+
+#define PV_CONTROL				0x00
+# define PV_CONTROL_FORMAT_MASK			VC4_MASK(23, 21)
+# define PV_CONTROL_FORMAT_SHIFT		21
+# define PV_CONTROL_FORMAT_24			0
+# define PV_CONTROL_FORMAT_DSIV_16		1
+# define PV_CONTROL_FORMAT_DSIC_16		2
+# define PV_CONTROL_FORMAT_DSIV_18		3
+# define PV_CONTROL_FORMAT_DSIV_24		4
+
+# define PV_CONTROL_FIFO_LEVEL_MASK		VC4_MASK(20, 15)
+# define PV_CONTROL_FIFO_LEVEL_SHIFT		15
+# define PV_CONTROL_CLR_AT_START		(1 << 14)
+# define PV_CONTROL_TRIGGER_UNDERFLOW		(1 << 13)
+# define PV_CONTROL_WAIT_HSTART			(1 << 12)
+# define PV_CONTROL_CLK_SELECT_DSI		0
+# define PV_CONTROL_CLK_SELECT_DPI_SMI_HDMI	1
+# define PV_CONTROL_CLK_SELECT_MASK		VC4_MASK(3, 2)
+# define PV_CONTROL_CLK_SELECT_SHIFT		2
+# define PV_CONTROL_FIFO_CLR			(1 << 1)
+# define PV_CONTROL_EN				(1 << 0)
+
+#define PV_V_CONTROL				0x04
+# define PV_VCONTROL_CONTINUOUS			(1 << 1)
+# define PV_VCONTROL_VIDEN			(1 << 0)
+
+#define PV_VSYNCD				0x08
+
+#define PV_HORZA				0x0c
+# define PV_HORZA_HBP_MASK			VC4_MASK(31, 16)
+# define PV_HORZA_HBP_SHIFT			16
+# define PV_HORZA_HSYNC_MASK			VC4_MASK(15, 0)
+# define PV_HORZA_HSYNC_SHIFT			0
+
+#define PV_HORZB				0x10
+# define PV_HORZB_HFP_MASK			VC4_MASK(31, 16)
+# define PV_HORZB_HFP_SHIFT			16
+# define PV_HORZB_HACTIVE_MASK			VC4_MASK(15, 0)
+# define PV_HORZB_HACTIVE_SHIFT			0
+
+#define PV_VERTA				0x14
+# define PV_VERTA_VBP_MASK			VC4_MASK(31, 16)
+# define PV_VERTA_VBP_SHIFT			16
+# define PV_VERTA_VSYNC_MASK			VC4_MASK(15, 0)
+# define PV_VERTA_VSYNC_SHIFT			0
+
+#define PV_VERTB				0x18
+# define PV_VERTB_VFP_MASK			VC4_MASK(31, 16)
+# define PV_VERTB_VFP_SHIFT			16
+# define PV_VERTB_VACTIVE_MASK			VC4_MASK(15, 0)
+# define PV_VERTB_VACTIVE_SHIFT			0
+
+#define PV_VERTA_EVEN				0x1c
+#define PV_VERTB_EVEN				0x20
+
+#define PV_INTEN				0x24
+#define PV_INTSTAT				0x28
+# define PV_INT_VID_IDLE			(1 << 9)
+# define PV_INT_VFP_END				(1 << 8)
+# define PV_INT_VFP_START			(1 << 7)
+# define PV_INT_VACT_START			(1 << 6)
+# define PV_INT_VBP_START			(1 << 5)
+# define PV_INT_VSYNC_START			(1 << 4)
+# define PV_INT_HFP_START			(1 << 3)
+# define PV_INT_HACT_START			(1 << 2)
+# define PV_INT_HBP_START			(1 << 1)
+# define PV_INT_HSYNC_START			(1 << 0)
+
+#define PV_STAT					0x2c
+
+#define PV_HACT_ACT				0x30
+
+#define SCALER_DISPCTRL                         0x00000000
+/* Global register for clock gating the HVS */
+# define SCALER_DISPCTRL_ENABLE			(1 << 31)
+# define SCALER_DISPCTRL_DSP2EISLUR		(1 << 15)
+# define SCALER_DISPCTRL_DSP1EISLUR		(1 << 14)
+/* Enables Display 0 short line and underrun contribution to
+ * SCALER_DISPSTAT_IRQDISP0.  Note that short frame contributions are
+ * always enabled.
+ */
+# define SCALER_DISPCTRL_DSP0EISLUR		(1 << 13)
+# define SCALER_DISPCTRL_DSP2EIEOLN		(1 << 12)
+# define SCALER_DISPCTRL_DSP2EIEOF		(1 << 11)
+# define SCALER_DISPCTRL_DSP1EIEOLN		(1 << 10)
+# define SCALER_DISPCTRL_DSP1EIEOF		(1 << 9)
+/* Enables Display 0 end-of-line-N contribution to
+ * SCALER_DISPSTAT_IRQDISP0
+ */
+# define SCALER_DISPCTRL_DSP0EIEOLN		(1 << 8)
+/* Enables Display 0 EOF contribution to SCALER_DISPSTAT_IRQDISP0 */
+# define SCALER_DISPCTRL_DSP0EIEOF		(1 << 7)
+
+# define SCALER_DISPCTRL_SLVRDEIRQ		(1 << 6)
+# define SCALER_DISPCTRL_SLVWREIRQ		(1 << 5)
+# define SCALER_DISPCTRL_DMAEIRQ		(1 << 4)
+# define SCALER_DISPCTRL_DISP2EIRQ		(1 << 3)
+# define SCALER_DISPCTRL_DISP1EIRQ		(1 << 2)
+/* Enables interrupt generation on the enabled EOF/EOLN/EISLUR
+ * bits and short frames..
+ */
+# define SCALER_DISPCTRL_DISP0EIRQ		(1 << 1)
+/* Enables interrupt generation on scaler profiler interrupt. */
+# define SCALER_DISPCTRL_SCLEIRQ		(1 << 0)
+
+#define SCALER_DISPSTAT                         0x00000004
+# define SCALER_DISPSTAT_COBLOW2		(1 << 29)
+# define SCALER_DISPSTAT_EOLN2			(1 << 28)
+# define SCALER_DISPSTAT_ESFRAME2		(1 << 27)
+# define SCALER_DISPSTAT_ESLINE2		(1 << 26)
+# define SCALER_DISPSTAT_EUFLOW2		(1 << 25)
+# define SCALER_DISPSTAT_EOF2			(1 << 24)
+
+# define SCALER_DISPSTAT_COBLOW1		(1 << 21)
+# define SCALER_DISPSTAT_EOLN1			(1 << 20)
+# define SCALER_DISPSTAT_ESFRAME1		(1 << 19)
+# define SCALER_DISPSTAT_ESLINE1		(1 << 18)
+# define SCALER_DISPSTAT_EUFLOW1		(1 << 17)
+# define SCALER_DISPSTAT_EOF1			(1 << 16)
+
+# define SCALER_DISPSTAT_RESP_MASK		VC4_MASK(15, 14)
+# define SCALER_DISPSTAT_RESP_SHIFT		14
+# define SCALER_DISPSTAT_RESP_OKAY		0
+# define SCALER_DISPSTAT_RESP_EXOKAY		1
+# define SCALER_DISPSTAT_RESP_SLVERR		2
+# define SCALER_DISPSTAT_RESP_DECERR		3
+
+# define SCALER_DISPSTAT_COBLOW0		(1 << 13)
+/* Set when the DISPEOLN line is done compositing. */
+# define SCALER_DISPSTAT_EOLN0			(1 << 12)
+/* Set when VSTART is seen but there are still pixels in the current
+ * output line.
+ */
+# define SCALER_DISPSTAT_ESFRAME0		(1 << 11)
+/* Set when HSTART is seen but there are still pixels in the current
+ * output line.
+ */
+# define SCALER_DISPSTAT_ESLINE0		(1 << 10)
+/* Set when the the downstream tries to read from the display FIFO
+ * while it's empty.
+ */
+# define SCALER_DISPSTAT_EUFLOW0		(1 << 9)
+/* Set when the display mode changes from RUN to EOF */
+# define SCALER_DISPSTAT_EOF0			(1 << 8)
+
+/* Set on AXI invalid DMA ID error. */
+# define SCALER_DISPSTAT_DMA_ERROR		(1 << 7)
+/* Set on AXI slave read decode error */
+# define SCALER_DISPSTAT_IRQSLVRD		(1 << 6)
+/* Set on AXI slave write decode error */
+# define SCALER_DISPSTAT_IRQSLVWR		(1 << 5)
+/* Set when SCALER_DISPSTAT_DMA_ERROR is set, or
+ * SCALER_DISPSTAT_RESP_ERROR is not SCALER_DISPSTAT_RESP_OKAY.
+ */
+# define SCALER_DISPSTAT_IRQDMA			(1 << 4)
+# define SCALER_DISPSTAT_IRQDISP2		(1 << 3)
+# define SCALER_DISPSTAT_IRQDISP1		(1 << 2)
+/* Set when any of the EOF/EOLN/ESFRAME/ESLINE bits are set and their
+ * corresponding interrupt bit is enabled in DISPCTRL.
+ */
+# define SCALER_DISPSTAT_IRQDISP0		(1 << 1)
+/* On read, the profiler interrupt.  On write, clear *all* interrupt bits. */
+# define SCALER_DISPSTAT_IRQSCL			(1 << 0)
+
+#define SCALER_DISPID                           0x00000008
+#define SCALER_DISPECTRL                        0x0000000c
+#define SCALER_DISPPROF                         0x00000010
+#define SCALER_DISPDITHER                       0x00000014
+#define SCALER_DISPEOLN                         0x00000018
+#define SCALER_DISPLIST0                        0x00000020
+#define SCALER_DISPLIST1                        0x00000024
+#define SCALER_DISPLIST2                        0x00000028
+#define SCALER_DISPLSTAT                        0x0000002c
+#define SCALER_DISPLISTX(x)			(SCALER_DISPLIST0 +	\
+						 (x) * (SCALER_DISPLIST1 - \
+							SCALER_DISPLIST0))
+
+#define SCALER_DISPLACT0                        0x00000030
+#define SCALER_DISPLACT1                        0x00000034
+#define SCALER_DISPLACT2                        0x00000038
+#define SCALER_DISPCTRL0                        0x00000040
+# define SCALER_DISPCTRLX_ENABLE		(1 << 31)
+# define SCALER_DISPCTRLX_RESET			(1 << 30)
+# define SCALER_DISPCTRLX_WIDTH_MASK		VC4_MASK(23, 12)
+# define SCALER_DISPCTRLX_WIDTH_SHIFT		12
+# define SCALER_DISPCTRLX_HEIGHT_MASK		VC4_MASK(11, 0)
+# define SCALER_DISPCTRLX_HEIGHT_SHIFT		0
+
+#define SCALER_DISPBKGND0                       0x00000044
+#define SCALER_DISPSTAT0                        0x00000048
+#define SCALER_DISPBASE0                        0x0000004c
+# define SCALER_DISPSTATX_MODE_MASK		VC4_MASK(31, 30)
+# define SCALER_DISPSTATX_MODE_SHIFT		30
+# define SCALER_DISPSTATX_MODE_DISABLED		0
+# define SCALER_DISPSTATX_MODE_INIT		1
+# define SCALER_DISPSTATX_MODE_RUN		2
+# define SCALER_DISPSTATX_MODE_EOF		3
+# define SCALER_DISPSTATX_FULL			(1 << 29)
+# define SCALER_DISPSTATX_EMPTY			(1 << 28)
+#define SCALER_DISPCTRL1                        0x00000050
+#define SCALER_DISPBKGND1                       0x00000054
+#define SCALER_DISPSTAT1                        0x00000058
+#define SCALER_DISPSTATX(x)			(SCALER_DISPSTAT0 +        \
+						 (x) * (SCALER_DISPSTAT1 - \
+							SCALER_DISPSTAT0))
+#define SCALER_DISPBASE1                        0x0000005c
+#define SCALER_DISPCTRL2                        0x00000060
+#define SCALER_DISPCTRLX(x)			(SCALER_DISPCTRL0 +        \
+						 (x) * (SCALER_DISPCTRL1 - \
+							SCALER_DISPCTRL0))
+#define SCALER_DISPBKGND2                       0x00000064
+#define SCALER_DISPSTAT2                        0x00000068
+#define SCALER_DISPBASE2                        0x0000006c
+#define SCALER_DISPALPHA2                       0x00000070
+#define SCALER_GAMADDR                          0x00000078
+#define SCALER_GAMDATA                          0x000000e0
+#define SCALER_DLIST_START                      0x00002000
+#define SCALER_DLIST_SIZE                       0x00004000
+
+#define VC4_HDMI_CORE_REV			0x000
+
+#define VC4_HDMI_SW_RESET_CONTROL		0x004
+# define VC4_HDMI_SW_RESET_FORMAT_DETECT	(1 << 1)
+# define VC4_HDMI_SW_RESET_HDMI			(1 << 0)
+
+#define VC4_HDMI_HOTPLUG_INT			0x008
+
+#define VC4_HDMI_HOTPLUG			0x00c
+# define VC4_HDMI_HOTPLUG_CONNECTED		(1 << 0)
+
+#define VC4_HDMI_RAM_PACKET_CONFIG		0x0a0
+# define VC4_HDMI_RAM_PACKET_ENABLE		(1 << 16)
+
+#define VC4_HDMI_HORZA				0x0c4
+# define VC4_HDMI_HORZA_VPOS			(1 << 14)
+# define VC4_HDMI_HORZA_HPOS			(1 << 13)
+/* Horizontal active pixels (hdisplay). */
+# define VC4_HDMI_HORZA_HAP_MASK		VC4_MASK(12, 0)
+# define VC4_HDMI_HORZA_HAP_SHIFT		0
+
+#define VC4_HDMI_HORZB				0x0c8
+/* Horizontal pack porch (htotal - hsync_end). */
+# define VC4_HDMI_HORZB_HBP_MASK		VC4_MASK(29, 20)
+# define VC4_HDMI_HORZB_HBP_SHIFT		20
+/* Horizontal sync pulse (hsync_end - hsync_start). */
+# define VC4_HDMI_HORZB_HSP_MASK		VC4_MASK(19, 10)
+# define VC4_HDMI_HORZB_HSP_SHIFT		10
+/* Horizontal front porch (hsync_start - hdisplay). */
+# define VC4_HDMI_HORZB_HFP_MASK		VC4_MASK(9, 0)
+# define VC4_HDMI_HORZB_HFP_SHIFT		0
+
+#define VC4_HDMI_FIFO_CTL			0x05c
+# define VC4_HDMI_FIFO_CTL_RECENTER_DONE	(1 << 14)
+# define VC4_HDMI_FIFO_CTL_USE_EMPTY		(1 << 13)
+# define VC4_HDMI_FIFO_CTL_ON_VB		(1 << 7)
+# define VC4_HDMI_FIFO_CTL_RECENTER		(1 << 6)
+# define VC4_HDMI_FIFO_CTL_FIFO_RESET		(1 << 5)
+# define VC4_HDMI_FIFO_CTL_USE_PLL_LOCK		(1 << 4)
+# define VC4_HDMI_FIFO_CTL_INV_CLK_XFR		(1 << 3)
+# define VC4_HDMI_FIFO_CTL_CAPTURE_PTR		(1 << 2)
+# define VC4_HDMI_FIFO_CTL_USE_FULL		(1 << 1)
+# define VC4_HDMI_FIFO_CTL_MASTER_SLAVE_N	(1 << 0)
+# define VC4_HDMI_FIFO_VALID_WRITE_MASK		0xefff
+
+#define VC4_HDMI_SCHEDULER_CONTROL		0x0c0
+# define VC4_HDMI_SCHEDULER_CONTROL_MANUAL_FORMAT (1 << 15)
+# define VC4_HDMI_SCHEDULER_CONTROL_IGNORE_VSYNC_PREDICTS (1 << 5)
+# define VC4_HDMI_SCHEDULER_CONTROL_VERT_ALWAYS_KEEPOUT	(1 << 3)
+# define VC4_HDMI_SCHEDULER_CONTROL_HDMI_ACTIVE	(1 << 1)
+# define VC4_HDMI_SCHEDULER_CONTROL_MODE_HDMI	(1 << 0)
+
+#define VC4_HDMI_VERTA0				0x0cc
+#define VC4_HDMI_VERTA1				0x0d4
+/* Vertical sync pulse (vsync_end - vsync_start). */
+# define VC4_HDMI_VERTA_VSP_MASK		VC4_MASK(24, 20)
+# define VC4_HDMI_VERTA_VSP_SHIFT		20
+/* Vertical front porch (vsync_start - vdisplay). */
+# define VC4_HDMI_VERTA_VFP_MASK		VC4_MASK(19, 13)
+# define VC4_HDMI_VERTA_VFP_SHIFT		13
+/* Vertical active lines (vdisplay). */
+# define VC4_HDMI_VERTA_VAL_MASK		VC4_MASK(12, 0)
+# define VC4_HDMI_VERTA_VAL_SHIFT		0
+
+#define VC4_HDMI_VERTB0				0x0d0
+#define VC4_HDMI_VERTB1				0x0d8
+/* Vertical sync pulse offset (for interlaced) */
+# define VC4_HDMI_VERTB_VSPO_MASK		VC4_MASK(21, 9)
+# define VC4_HDMI_VERTB_VSPO_SHIFT		9
+/* Vertical pack porch (vtotal - vsync_end). */
+# define VC4_HDMI_VERTB_VBP_MASK		VC4_MASK(8, 0)
+# define VC4_HDMI_VERTB_VBP_SHIFT		0
+
+#define VC4_HDMI_TX_PHY_RESET_CTL		0x2c0
+
+#define VC4_HD_M_CTL				0x00c
+# define VC4_HD_M_SW_RST			(1 << 2)
+# define VC4_HD_M_ENABLE			(1 << 0)
+
+#define VC4_HD_MAI_CTL				0x014
+
+#define VC4_HD_VID_CTL				0x038
+# define VC4_HD_VID_CTL_ENABLE			(1 << 31)
+# define VC4_HD_VID_CTL_UNDERFLOW_ENABLE	(1 << 30)
+# define VC4_HD_VID_CTL_FRAME_COUNTER_RESET	(1 << 29)
+# define VC4_HD_VID_CTL_VSYNC_LOW		(1 << 28)
+# define VC4_HD_VID_CTL_HSYNC_LOW		(1 << 27)
+
+#define VC4_HD_CSC_CTL				0x040
+# define VC4_HD_CSC_CTL_ORDER_MASK		VC4_MASK(7, 5)
+# define VC4_HD_CSC_CTL_ORDER_SHIFT		5
+# define VC4_HD_CSC_CTL_ORDER_RGB		0
+# define VC4_HD_CSC_CTL_ORDER_BGR		1
+# define VC4_HD_CSC_CTL_ORDER_BRG		2
+# define VC4_HD_CSC_CTL_ORDER_GRB		3
+# define VC4_HD_CSC_CTL_ORDER_GBR		4
+# define VC4_HD_CSC_CTL_ORDER_RBG		5
+# define VC4_HD_CSC_CTL_PADMSB			(1 << 4)
+# define VC4_HD_CSC_CTL_MODE_MASK		VC4_MASK(3, 2)
+# define VC4_HD_CSC_CTL_MODE_SHIFT		2
+# define VC4_HD_CSC_CTL_MODE_RGB_TO_SD_YPRPB	0
+# define VC4_HD_CSC_CTL_MODE_RGB_TO_HD_YPRPB	1
+# define VC4_HD_CSC_CTL_MODE_CUSTOM		2
+# define VC4_HD_CSC_CTL_RGB2YCC			(1 << 1)
+# define VC4_HD_CSC_CTL_ENABLE			(1 << 0)
+
+#define VC4_HD_FRAME_COUNT			0x068
+
+/* HVS display list information. */
+#define HVS_BOOTLOADER_DLIST_END                32
+
+enum hvs_pixel_format {
+	/* 8bpp */
+	HVS_PIXEL_FORMAT_RGB332 = 0,
+	/* 16bpp */
+	HVS_PIXEL_FORMAT_RGBA4444 = 1,
+	HVS_PIXEL_FORMAT_RGB555 = 2,
+	HVS_PIXEL_FORMAT_RGBA5551 = 3,
+	HVS_PIXEL_FORMAT_RGB565 = 4,
+	/* 24bpp */
+	HVS_PIXEL_FORMAT_RGB888 = 5,
+	HVS_PIXEL_FORMAT_RGBA6666 = 6,
+	/* 32bpp */
+	HVS_PIXEL_FORMAT_RGBA8888 = 7
+};
+
+/* Note: the LSB is the rightmost character shown.  Only valid for
+ * HVS_PIXEL_FORMAT_RGB8888, not RGB888.
+ */
+#define HVS_PIXEL_ORDER_RGBA			0
+#define HVS_PIXEL_ORDER_BGRA			1
+#define HVS_PIXEL_ORDER_ARGB			2
+#define HVS_PIXEL_ORDER_ABGR			3
+
+#define HVS_PIXEL_ORDER_XBRG			0
+#define HVS_PIXEL_ORDER_XRBG			1
+#define HVS_PIXEL_ORDER_XRGB			2
+#define HVS_PIXEL_ORDER_XBGR			3
+
+#define HVS_PIXEL_ORDER_XYCBCR			0
+#define HVS_PIXEL_ORDER_XYCRCB			1
+#define HVS_PIXEL_ORDER_YXCBCR			2
+#define HVS_PIXEL_ORDER_YXCRCB			3
+
+#define SCALER_CTL0_END				(1 << 31)
+#define SCALER_CTL0_VALID			(1 << 30)
+
+#define SCALER_CTL0_SIZE_MASK			VC4_MASK(29, 24)
+#define SCALER_CTL0_SIZE_SHIFT			24
+
+#define SCALER_CTL0_HFLIP                       (1 << 16)
+#define SCALER_CTL0_VFLIP                       (1 << 15)
+
+#define SCALER_CTL0_ORDER_MASK			VC4_MASK(14, 13)
+#define SCALER_CTL0_ORDER_SHIFT			13
+
+/* Set to indicate no scaling. */
+#define SCALER_CTL0_UNITY			(1 << 4)
+
+#define SCALER_CTL0_PIXEL_FORMAT_MASK		VC4_MASK(3, 0)
+#define SCALER_CTL0_PIXEL_FORMAT_SHIFT		0
+
+#define SCALER_POS0_FIXED_ALPHA_MASK		VC4_MASK(31, 24)
+#define SCALER_POS0_FIXED_ALPHA_SHIFT		24
+
+#define SCALER_POS0_START_Y_MASK		VC4_MASK(23, 12)
+#define SCALER_POS0_START_Y_SHIFT		12
+
+#define SCALER_POS0_START_X_MASK		VC4_MASK(11, 0)
+#define SCALER_POS0_START_X_SHIFT		0
+
+#define SCALER_POS2_ALPHA_MODE_MASK		VC4_MASK(31, 30)
+#define SCALER_POS2_ALPHA_MODE_SHIFT		30
+#define SCALER_POS2_ALPHA_MODE_PIPELINE		0
+#define SCALER_POS2_ALPHA_MODE_FIXED		1
+#define SCALER_POS2_ALPHA_MODE_FIXED_NONZERO	2
+#define SCALER_POS2_ALPHA_MODE_FIXED_OVER_0x07	3
+
+#define SCALER_POS2_HEIGHT_MASK			VC4_MASK(27, 16)
+#define SCALER_POS2_HEIGHT_SHIFT		16
+
+#define SCALER_POS2_WIDTH_MASK			VC4_MASK(11, 0)
+#define SCALER_POS2_WIDTH_SHIFT			0
+
+#define SCALER_SRC_PITCH_MASK			VC4_MASK(15, 0)
+#define SCALER_SRC_PITCH_SHIFT			0
-- 
2.1.4



From computersforpeace at gmail.com  Wed Aug 12 19:00:04 2015
From: computersforpeace at gmail.com (Brian Norris)
Date: Wed, 12 Aug 2015 19:00:04 -0700
Subject: [PATCH v2 1/2] mtd: spi-nor: add driver for NXP SPI Flash
 Interface (SPIFI)
In-Reply-To: <CAGhQ9VzU+J1ZT45e-yZ+BAmyZvLUm1cyXE2T__O_4gGjtHrX-w@mail.gmail.com>
References: <1433106362-6032-1-git-send-email-manabian@gmail.com>
 <1433106362-6032-2-git-send-email-manabian@gmail.com>
 <5570692E.2050603@vanguardiasur.com.ar>
 <CAGhQ9VzU+J1ZT45e-yZ+BAmyZvLUm1cyXE2T__O_4gGjtHrX-w@mail.gmail.com>
Message-ID: <20150813020004.GA108786@google.com>

On Thu, Jun 04, 2015 at 05:58:07PM +0200, Joachim Eastwood wrote:
> On 4 June 2015 at 17:05, Ezequiel Garcia <ezequiel at vanguardiasur.com.ar> wrote:
> > I think the "auto-detect" quirk is really needed, or you are will
> > otherwise fail to probe with the generic "jedec,spi-nor" compatible
> > string.
[...]
> Note that this code was copied from fsl-quadspi so I assume it has the
> same problem.

Yes, fsl-quadspi gets this a bit wrong, I think. But spi_nor_scan()
didn't have a notion of "NULL means autodetect" when it was first
written. The framework is still evolving a bit.

I have a simple patch for fsl-quadspi to fix this up now, but I don't
have the HW. Maybe I'll send with a RFT.

Brian


From k.kozlowski at samsung.com  Wed Aug 12 19:03:32 2015
From: k.kozlowski at samsung.com (Krzysztof Kozlowski)
Date: Thu, 13 Aug 2015 11:03:32 +0900
Subject: [PATCH] drm/exynos: Staticize local function in exynos_drm_gem.c
Message-ID: <1439431412-20023-1-git-send-email-k.kozlowski@samsung.com>

The exynos_drm_gem_mmap_buffer() is not used outside so make it static.

Signed-off-by: Krzysztof Kozlowski <k.kozlowski at samsung.com>
---
 drivers/gpu/drm/exynos/exynos_drm_gem.c | 2 +-
 1 file changed, 1 insertion(+), 1 deletion(-)

diff --git a/drivers/gpu/drm/exynos/exynos_drm_gem.c b/drivers/gpu/drm/exynos/exynos_drm_gem.c
index 0d5b9698d384..d9f6de012235 100644
--- a/drivers/gpu/drm/exynos/exynos_drm_gem.c
+++ b/drivers/gpu/drm/exynos/exynos_drm_gem.c
@@ -318,7 +318,7 @@ void exynos_drm_gem_put_dma_addr(struct drm_device *dev,
 	drm_gem_object_unreference_unlocked(obj);
 }
 
-int exynos_drm_gem_mmap_buffer(struct exynos_drm_gem_obj *exynos_gem_obj,
+static int exynos_drm_gem_mmap_buffer(struct exynos_drm_gem_obj *exynos_gem_obj,
 				      struct vm_area_struct *vma)
 {
 	struct drm_device *drm_dev = exynos_gem_obj->base.dev;
-- 
1.9.1



From leilk.liu at mediatek.com  Wed Aug 12 19:11:59 2015
From: leilk.liu at mediatek.com (lei liu)
Date: Thu, 13 Aug 2015 10:11:59 +0800
Subject: [PATCH] spi: Mediatek: fix endian warnings
In-Reply-To: <CAOiHx=mrDhxkMd5WVTpayyyxXHUDRTELubErynN3qd-v5qpCfw@mail.gmail.com>
References: <1439289789-29026-1-git-send-email-leilk.liu@mediatek.com>
 <CAOiHx=mrDhxkMd5WVTpayyyxXHUDRTELubErynN3qd-v5qpCfw@mail.gmail.com>
Message-ID: <1439431919.21454.13.camel@mhfsdcap03>

Hello Mark,

 This patch is applied, should I append a new patch or you rollback it?
Thanks.

On Wed, 2015-08-12 at 16:45 +0200, Jonas Gorski wrote:
> Hi,
> 
> On Tue, Aug 11, 2015 at 12:43 PM, Leilk Liu <leilk.liu at mediatek.com> wrote:
> > This patch fixes endian warnings detected by sparse:
> > - sparse: incorrect type in argument 1 (different base types)
> >           expected unsigned int [unsigned] val
> >           got restricted __le32 [usertype] <noident>
> > - sparse: incorrect type in argument 1 (different base types)
> >           expected unsigned int [unsigned] val
> >           got restricted __le32 [usertype] <noident>
> 
> This doesn't "fix" the warning, it only hides the warning and leaves
> the actual issue unfixed.
> 
> >
> > Signed-off-by: Leilk Liu <leilk.liu at mediatek.com>
> > ---
> >  drivers/spi/spi-mt65xx.c | 6 ++++--
> >  1 file changed, 4 insertions(+), 2 deletions(-)
> >
> > diff --git a/drivers/spi/spi-mt65xx.c b/drivers/spi/spi-mt65xx.c
> > index 4676b01..ae645fa 100644
> > --- a/drivers/spi/spi-mt65xx.c
> > +++ b/drivers/spi/spi-mt65xx.c
> > @@ -359,9 +359,11 @@ static void mtk_spi_setup_dma_addr(struct spi_master *master,
> >         struct mtk_spi *mdata = spi_master_get_devdata(master);
> >
> >         if (mdata->tx_sgl)
> > -               writel(cpu_to_le32(xfer->tx_dma), mdata->base + SPI_TX_SRC_REG);
> > +               writel((__force u32)cpu_to_le32(xfer->tx_dma),
> > +                      mdata->base + SPI_TX_SRC_REG);
> >         if (mdata->rx_sgl)
> > -               writel(cpu_to_le32(xfer->rx_dma), mdata->base + SPI_RX_DST_REG);
> > +               writel((__force u32)cpu_to_le32(xfer->rx_dma),
> > +                      mdata->base + SPI_RX_DST_REG);
> 
> The issue here is that writel already does a cpu_to_le32 conversion,
> so the extra cpu_to_le32 calls are actually bogus and need to be
> removed. Else it will do a double conversion on big endian systems,
> resulting in the data being written in big endian.
> 
> 
> Jonas




From computersforpeace at gmail.com  Wed Aug 12 19:30:25 2015
From: computersforpeace at gmail.com (Brian Norris)
Date: Wed, 12 Aug 2015 19:30:25 -0700
Subject: [PATCH v3 1/2] mtd: spi-nor: add driver for NXP SPI Flash
 Interface (SPIFI)
In-Reply-To: <1433436843-22296-2-git-send-email-manabian@gmail.com>
References: <1433436843-22296-1-git-send-email-manabian@gmail.com>
 <1433436843-22296-2-git-send-email-manabian@gmail.com>
Message-ID: <20150813023025.GB108786@google.com>

On Thu, Jun 04, 2015 at 06:54:02PM +0200, Joachim Eastwood wrote:
> Add SPI-NOR driver for the SPI Flash Interface (SPIFI)
> controller that is found newer NXP MCU devices.
> 
> The controller supports serial SPI Flash devices with 1-, 2-
> and 4-bit width in either SPI mode 0 or 3. The controller
> can operate in either command or memory mode. In memory mode
> the Flash is exposed as normal memory and can be directly
> accessed by the CPU.
> 
> Signed-off-by: Joachim Eastwood <manabian at gmail.com>
> Reviewed-by: Ezequiel Garcia <ezequiel at vanguardiasur.com.ar>

Thanks for the reviews, Ezequiel. This driver is mostly looking pretty
good.

> ---
>  drivers/mtd/spi-nor/Kconfig     |  11 +
>  drivers/mtd/spi-nor/Makefile    |   1 +
>  drivers/mtd/spi-nor/nxp-spifi.c | 496 ++++++++++++++++++++++++++++++++++++++++
>  3 files changed, 508 insertions(+)
>  create mode 100644 drivers/mtd/spi-nor/nxp-spifi.c
> 
> diff --git a/drivers/mtd/spi-nor/Kconfig b/drivers/mtd/spi-nor/Kconfig
> index 64a4f0edabc7..407142e411fa 100644
> --- a/drivers/mtd/spi-nor/Kconfig
> +++ b/drivers/mtd/spi-nor/Kconfig
> @@ -28,4 +28,15 @@ config SPI_FSL_QUADSPI
>  	  This enables support for the Quad SPI controller in master mode.
>  	  We only connect the NOR to this controller now.
>  
> +config SPI_NXP_SPIFI
> +	tristate "NXP SPI Flash Interface (SPIFI)"
> +	depends on OF && (ARCH_LPC18XX || COMPILE_TEST)
> +	depends on HAS_IOMEM
> +	help
> +	  Enable support for the NXP LPC SPI Flash Interface controller.
> +
> +	  SPIFI is a specialized controller for connecting serial SPI
> +	  Flash. Enable this option if you have a device with a SPIFI
> +	  controller and want to access the Flash as a mtd device.
> +
>  endif # MTD_SPI_NOR
> diff --git a/drivers/mtd/spi-nor/Makefile b/drivers/mtd/spi-nor/Makefile
> index 6a7ce1462247..e53333ef8582 100644
> --- a/drivers/mtd/spi-nor/Makefile
> +++ b/drivers/mtd/spi-nor/Makefile
> @@ -1,2 +1,3 @@
>  obj-$(CONFIG_MTD_SPI_NOR)	+= spi-nor.o
>  obj-$(CONFIG_SPI_FSL_QUADSPI)	+= fsl-quadspi.o
> +obj-$(CONFIG_SPI_NXP_SPIFI)	+= nxp-spifi.o
> diff --git a/drivers/mtd/spi-nor/nxp-spifi.c b/drivers/mtd/spi-nor/nxp-spifi.c
> new file mode 100644
> index 000000000000..8721f686ac9e
> --- /dev/null
> +++ b/drivers/mtd/spi-nor/nxp-spifi.c
> @@ -0,0 +1,496 @@
> +/*
> + * SPI-NOR driver for NXP SPI Flash Interface (SPIFI)
> + *
> + * Copyright (C) 2015 Joachim Eastwood <manabian at gmail.com>
> + *
> + * Based on Freescale QuadSPI driver:
> + * Copyright (C) 2013 Freescale Semiconductor, Inc.
> + *
> + * This program is free software; you can redistribute it and/or modify
> + * it under the terms of the GNU General Public License version 2 as
> + * published by the Free Software Foundation.
> + *
> + */
> +
> +#include <linux/clk.h>
> +#include <linux/err.h>
> +#include <linux/io.h>
> +#include <linux/iopoll.h>
> +#include <linux/module.h>
> +#include <linux/mtd/mtd.h>
> +#include <linux/mtd/partitions.h>
> +#include <linux/mtd/spi-nor.h>
> +#include <linux/of.h>
> +#include <linux/of_device.h>
> +#include <linux/platform_device.h>
> +#include <linux/spi/spi.h>
> +
> +/* NXP SPIFI registers, bits and macros */
> +#define SPIFI_CTRL				0x000
> +#define  SPIFI_CTRL_TIMEOUT(timeout)		(timeout)
> +#define  SPIFI_CTRL_CSHIGH(cshigh)		((cshigh) << 16)
> +#define  SPIFI_CTRL_MODE3			BIT(23)
> +#define  SPIFI_CTRL_DUAL			BIT(28)
> +#define  SPIFI_CTRL_FBCLK			BIT(30)
> +#define SPIFI_CMD				0x004
> +#define  SPIFI_CMD_DATALEN(dlen)		(dlen & 0x3fff)

Parentheses around 'dlen', to avoid macro troubles.

> +#define  SPIFI_CMD_DOUT				BIT(15)
> +#define  SPIFI_CMD_INTLEN(ilen)			((ilen) << 16)
> +#define  SPIFI_CMD_FIELDFORM(field)		((field) << 19)
> +#define  SPIFI_CMD_FIELDFORM_ALL_SERIAL		SPIFI_CMD_FIELDFORM(0x0)
> +#define  SPIFI_CMD_FIELDFORM_QUAD_DUAL_DATA	SPIFI_CMD_FIELDFORM(0x1)
> +#define  SPIFI_CMD_FRAMEFORM(frame)		((frame) << 21)
> +#define  SPIFI_CMD_FRAMEFORM_OPCODE_ONLY	SPIFI_CMD_FRAMEFORM(0x1)
> +#define  SPIFI_CMD_OPCODE(op)			((op) << 24)
> +#define SPIFI_ADDR				0x008
> +#define SPIFI_IDATA				0x00c
> +#define SPIFI_CLIMIT				0x010
> +#define SPIFI_DATA				0x014
> +#define SPIFI_MCMD				0x018
> +#define SPIFI_STAT				0x01c
> +#define  SPIFI_STAT_MCINIT			BIT(0)
> +#define  SPIFI_STAT_CMD				BIT(1)
> +#define  SPIFI_STAT_RESET			BIT(4)
> +
> +#define SPI_NOR_MAX_ID_LEN	6
> +
> +struct nxp_spifi {
> +	struct device *dev;
> +	struct clk *clk_spifi;
> +	struct clk *clk_reg;
> +	void __iomem *io_base;
> +	void __iomem *flash_base;
> +	struct mtd_info mtd;
> +	struct spi_nor nor;
> +	bool memory_mode;
> +	u32 mcmd;
> +};
> +
> +static int nxp_spifi_wait_for_cmd(struct nxp_spifi *spifi)
> +{
> +	u8 stat;
> +	int ret;
> +
> +	ret = readb_poll_timeout(spifi->io_base + SPIFI_STAT, stat,
> +				 !(stat & SPIFI_STAT_CMD), 10, 30);
> +	if (ret)
> +		dev_warn(spifi->dev, "command timed out\n");
> +
> +	return ret;
> +}
> +
> +static int nxp_spifi_reset(struct nxp_spifi *spifi)
> +{
> +	u8 stat;
> +	int ret;
> +
> +	writel(SPIFI_STAT_RESET, spifi->io_base + SPIFI_STAT);
> +	ret = readb_poll_timeout(spifi->io_base + SPIFI_STAT, stat,
> +				 !(stat & SPIFI_STAT_RESET), 10, 30);
> +	if (ret)
> +		dev_warn(spifi->dev, "state reset timed out\n");
> +
> +	return ret;
> +}
> +
> +static int nxp_spifi_set_memory_mode_off(struct nxp_spifi *spifi)
> +{
> +	int ret;
> +
> +	if (!spifi->memory_mode)
> +		return 0;
> +
> +	ret = nxp_spifi_reset(spifi);
> +	if (ret)
> +		dev_err(spifi->dev, "unable to enter command mode\n");
> +	else
> +		spifi->memory_mode = false;
> +
> +	return ret;
> +}
> +
> +static int nxp_spifi_set_memory_mode_on(struct nxp_spifi *spifi)
> +{
> +	u8 stat;
> +	int ret;
> +
> +	if (spifi->memory_mode)
> +		return 0;
> +
> +	writel(spifi->mcmd, spifi->io_base + SPIFI_MCMD);
> +	ret = readb_poll_timeout(spifi->io_base + SPIFI_STAT, stat,
> +				 stat & SPIFI_STAT_MCINIT, 10, 30);
> +	if (ret)
> +		dev_err(spifi->dev, "unable to enter memory mode\n");
> +	else
> +		spifi->memory_mode = true;
> +
> +	return ret;
> +}
> +
> +static int nxp_spifi_read_reg(struct spi_nor *nor, u8 opcode, u8 *buf, int len)
> +{
> +	struct nxp_spifi *spifi = nor->priv;
> +	u32 cmd;
> +	int ret;
> +
> +	ret = nxp_spifi_set_memory_mode_off(spifi);
> +	if (ret)
> +		return ret;
> +
> +	cmd = SPIFI_CMD_DATALEN(len) |
> +	      SPIFI_CMD_OPCODE(opcode) |
> +	      SPIFI_CMD_FIELDFORM_ALL_SERIAL |
> +	      SPIFI_CMD_FRAMEFORM_OPCODE_ONLY;
> +	writel(cmd, spifi->io_base + SPIFI_CMD);
> +
> +	while (len--)
> +		*buf++ = readb(spifi->io_base + SPIFI_DATA);
> +
> +	return nxp_spifi_wait_for_cmd(spifi);

Hmm, I don't know this HW, but judging by the naming and structure, I'd
guess you want to "wait_for_cmd()" *before* you begin reading out data,
no? Or I may be making the wrong assumptions.

> +}
> +
> +static int nxp_spifi_write_reg(struct spi_nor *nor, u8 opcode, u8 *buf,
> +			       int len, int write_enable)
> +{
> +	struct nxp_spifi *spifi = nor->priv;
> +	u32 cmd;
> +	int ret;
> +
> +	ret = nxp_spifi_set_memory_mode_off(spifi);
> +	if (ret)
> +		return ret;
> +
> +	cmd = SPIFI_CMD_DOUT |
> +	      SPIFI_CMD_DATALEN(len) |
> +	      SPIFI_CMD_OPCODE(opcode) |
> +	      SPIFI_CMD_FIELDFORM_ALL_SERIAL |
> +	      SPIFI_CMD_FRAMEFORM_OPCODE_ONLY;
> +	writel(cmd, spifi->io_base + SPIFI_CMD);
> +
> +	while (len--)
> +		writeb(*buf++, spifi->io_base + SPIFI_DATA);
> +
> +	return nxp_spifi_wait_for_cmd(spifi);
> +}
> +
> +static int nxp_spifi_read(struct spi_nor *nor, loff_t from, size_t len,
> +			  size_t *retlen, u_char *buf)
> +{
> +	struct nxp_spifi *spifi = nor->priv;
> +	int ret;
> +
> +	ret = nxp_spifi_set_memory_mode_on(spifi);
> +	if (ret)
> +		return ret;
> +
> +	memcpy_fromio(buf, spifi->flash_base + from, len);
> +	*retlen += len;
> +
> +	return 0;
> +}
> +
> +static void nxp_spifi_write(struct spi_nor *nor, loff_t to, size_t len,
> +			    size_t *retlen, const u_char *buf)
> +{
> +	struct nxp_spifi *spifi = nor->priv;
> +	u32 cmd;
> +	int ret;
> +
> +	ret = nxp_spifi_set_memory_mode_off(spifi);
> +	if (ret) {
> +		*retlen = 0;
> +		return;
> +	}
> +
> +	writel(to, spifi->io_base + SPIFI_ADDR);
> +	*retlen = len;
> +
> +	cmd = SPIFI_CMD_DOUT |
> +	      SPIFI_CMD_DATALEN(len) |
> +	      SPIFI_CMD_FIELDFORM_ALL_SERIAL |
> +	      SPIFI_CMD_OPCODE(nor->program_opcode) |
> +	      SPIFI_CMD_FRAMEFORM(spifi->nor.addr_width + 1);
> +	writel(cmd, spifi->io_base + SPIFI_CMD);
> +
> +	while (len--)
> +		writeb(*buf++, spifi->io_base + SPIFI_DATA);
> +
> +	nxp_spifi_wait_for_cmd(spifi);
> +}
> +
> +static int nxp_spifi_erase(struct spi_nor *nor, loff_t offs)
> +{
> +	struct nxp_spifi *spifi = nor->priv;
> +	u32 cmd;
> +	int ret;
> +
> +	ret = nxp_spifi_set_memory_mode_off(spifi);
> +	if (ret)
> +		return ret;
> +
> +	writel(offs, spifi->io_base + SPIFI_ADDR);
> +
> +	cmd = SPIFI_CMD_FIELDFORM_ALL_SERIAL |
> +	      SPIFI_CMD_OPCODE(nor->erase_opcode) |
> +	      SPIFI_CMD_FRAMEFORM(spifi->nor.addr_width + 1);
> +	writel(cmd, spifi->io_base + SPIFI_CMD);
> +
> +	return nxp_spifi_wait_for_cmd(spifi);
> +}
> +
> +static int nxp_spifi_setup_memory_cmd(struct nxp_spifi *spifi)
> +{
> +	switch (spifi->nor.flash_read) {
> +	case SPI_NOR_NORMAL:
> +	case SPI_NOR_FAST:
> +		spifi->mcmd = SPIFI_CMD_FIELDFORM_ALL_SERIAL;
> +		break;
> +	case SPI_NOR_DUAL:
> +	case SPI_NOR_QUAD:
> +		spifi->mcmd = SPIFI_CMD_FIELDFORM_QUAD_DUAL_DATA;
> +		break;
> +	default:
> +		dev_err(spifi->dev, "unsupported spi read mode\n");

s/spi/SPI/

> +		return -EINVAL;
> +	}
> +
> +	/* Memory mode supports address length between 1 and 4 */
> +	if (spifi->nor.addr_width < 1 || spifi->nor.addr_width > 4)
> +		return -EINVAL;
> +
> +	spifi->mcmd |= SPIFI_CMD_OPCODE(spifi->nor.read_opcode) |
> +		       SPIFI_CMD_INTLEN(spifi->nor.read_dummy / 8) |
> +		       SPIFI_CMD_FRAMEFORM(spifi->nor.addr_width + 1);
> +
> +	return 0;
> +}
> +
> +static void nxp_spifi_dummy_id_read(struct spi_nor *nor)
> +{
> +	u8 id[SPI_NOR_MAX_ID_LEN];
> +	nor->read_reg(nor, SPINOR_OP_RDID, id, SPI_NOR_MAX_ID_LEN);
> +}
> +
> +static int nxp_spifi_setup_flash(struct nxp_spifi *spifi,
> +				 struct device_node *np)
> +{
> +	struct mtd_part_parser_data ppdata;
> +	enum read_mode flash_read;
> +	char *flash_name = NULL;
> +	u32 ctrl, property;
> +	char modalias[40];
> +	u16 mode = 0;
> +	int ret;
> +
> +	if (!of_property_read_u32(np, "spi-rx-bus-width", &property)) {
> +		switch (property) {
> +		case 1:
> +			break;
> +		case 2:
> +			mode |= SPI_RX_DUAL;
> +			break;
> +		case 4:
> +			mode |= SPI_RX_QUAD;
> +			break;
> +		default:
> +			dev_err(spifi->dev, "unsupported rx-bus-width\n");
> +			return -EINVAL;
> +		}
> +	}
> +
> +	if (of_find_property(np, "spi-cpha", NULL))
> +		mode |= SPI_CPHA;
> +
> +	if (of_find_property(np, "spi-cpol", NULL))
> +		mode |= SPI_CPOL;
> +
> +	/* Setup control register defaults */
> +	ctrl = SPIFI_CTRL_TIMEOUT(1000) |
> +	       SPIFI_CTRL_CSHIGH(15) |
> +	       SPIFI_CTRL_FBCLK;
> +
> +	if (mode & SPI_RX_DUAL) {
> +		ctrl |= SPIFI_CTRL_DUAL;
> +		flash_read = SPI_NOR_DUAL;
> +	} else if (mode & SPI_RX_QUAD) {
> +		ctrl &= ~SPIFI_CTRL_DUAL;
> +		flash_read = SPI_NOR_QUAD;
> +	} else {
> +		ctrl |= SPIFI_CTRL_DUAL;
> +		flash_read = SPI_NOR_NORMAL;
> +	}
> +
> +	switch (mode & (SPI_CPHA | SPI_CPOL)) {
> +	case SPI_MODE_0:
> +		ctrl &= ~SPIFI_CTRL_MODE3;
> +		break;
> +	case SPI_MODE_3:
> +		ctrl |= SPIFI_CTRL_MODE3;
> +		break;
> +	default:
> +		dev_err(spifi->dev, "only mode 0 and 3 supported\n");
> +		return -EINVAL;
> +	}
> +
> +	writel(ctrl, spifi->io_base + SPIFI_CTRL);
> +
> +	spifi->mtd.priv  = &spifi->nor;

Please drop this line. You're violating the layering here, where
spi-nor.c gets the privilege of setting this field.

> +	spifi->nor.mtd   = &spifi->mtd;
> +	spifi->nor.dev   = spifi->dev;
> +	spifi->nor.priv  = spifi;
> +	spifi->nor.read  = nxp_spifi_read;
> +	spifi->nor.write = nxp_spifi_write;
> +	spifi->nor.erase = nxp_spifi_erase;
> +	spifi->nor.read_reg  = nxp_spifi_read_reg;
> +	spifi->nor.write_reg = nxp_spifi_write_reg;
> +
> +	ret = of_modalias_node(np, modalias, sizeof(modalias));
> +	if (ret < 0) {
> +		dev_err(spifi->dev, "unable to get device modalias\n");
> +		return ret;
> +	}
> +
> +	/* Use auto detect unless chip is specified */
> +	if (strcmp(modalias, "spi-nor"))
> +		flash_name = modalias;

Do you have a good reason to specify a non-NULL flash_name? Mostly
curious, since AFAIK, almost all new flash can be identified by their ID
string, and so we can just pass NULL to spi_nor_scan().

> +
> +	/*
> +	 * The first read on a hard reset isn't reliable so do a
> +	 * dummy read of the id before calling spi_nor_scan().
> +	 * The reason for this problem is unknown.
> +	 *
> +	 * The official NXP spifilib uses more or less the same
> +	 * workaround that is applied here by reading the device
> +	 * id multiple times.
> +	 */
> +	nxp_spifi_dummy_id_read(&spifi->nor);
> +
> +	ret = spi_nor_scan(&spifi->nor, flash_name, flash_read);
> +	if (ret) {
> +		dev_err(spifi->dev, "device scan failed\n");
> +		return ret;
> +	}
> +
> +	ret = nxp_spifi_setup_memory_cmd(spifi);
> +	if (ret) {
> +		dev_err(spifi->dev, "memory command setup failed\n");
> +		return ret;
> +	}
> +
> +	ppdata.of_node = np;
> +	ret = mtd_device_parse_register(&spifi->mtd, NULL, &ppdata, NULL, 0);
> +	if (ret) {
> +		dev_err(spifi->dev, "mtd device parse failed\n");
> +		return ret;
> +	}
> +
> +	return 0;
> +}
> +
> +static int nxp_spifi_probe(struct platform_device *pdev)
> +{
> +	struct device_node *flash_np;
> +	struct nxp_spifi *spifi;
> +	struct resource *res;
> +	int ret;
> +
> +	spifi = devm_kzalloc(&pdev->dev, sizeof(*spifi), GFP_KERNEL);
> +	if (!spifi)
> +		return -ENOMEM;
> +
> +	res = platform_get_resource_byname(pdev, IORESOURCE_MEM, "spifi");
> +	spifi->io_base = devm_ioremap_resource(&pdev->dev, res);
> +	if (IS_ERR(spifi->io_base))
> +		return PTR_ERR(spifi->io_base);
> +
> +	res = platform_get_resource_byname(pdev, IORESOURCE_MEM, "flash");
> +	spifi->flash_base = devm_ioremap_resource(&pdev->dev, res);
> +	if (IS_ERR(spifi->flash_base))
> +		return PTR_ERR(spifi->flash_base);
> +
> +	spifi->clk_spifi = devm_clk_get(&pdev->dev, "spifi");
> +	if (IS_ERR(spifi->clk_spifi)) {
> +		dev_err(&pdev->dev, "spifi clock not found\n");
> +		return PTR_ERR(spifi->clk_spifi);
> +	}
> +
> +	spifi->clk_reg = devm_clk_get(&pdev->dev, "reg");
> +	if (IS_ERR(spifi->clk_reg)) {
> +		dev_err(&pdev->dev, "reg clock not found\n");
> +		return PTR_ERR(spifi->clk_reg);
> +	}
> +
> +	ret = clk_prepare_enable(spifi->clk_reg);
> +	if (ret) {
> +		dev_err(&pdev->dev, "unable to enable reg clock\n");
> +		return ret;
> +	}
> +
> +	ret = clk_prepare_enable(spifi->clk_spifi);
> +	if (ret) {
> +		dev_err(&pdev->dev, "unable to enable spifi clock\n");
> +		goto dis_clk_reg;
> +	}
> +
> +	spifi->dev = &pdev->dev;
> +	platform_set_drvdata(pdev, spifi);
> +
> +	/* Initialize and reset device */
> +	nxp_spifi_reset(spifi);
> +	writel(0, spifi->io_base + SPIFI_IDATA);
> +	writel(0, spifi->io_base + SPIFI_MCMD);
> +	nxp_spifi_reset(spifi);
> +
> +	flash_np = of_get_next_available_child(pdev->dev.of_node, NULL);
> +	if (!flash_np) {
> +		dev_err(&pdev->dev, "no spi flash device to configure\n");

s/spi/SPI/

> +		ret = -ENODEV;
> +		goto dis_clks;
> +	}
> +
> +	ret = nxp_spifi_setup_flash(spifi, flash_np);
> +	if (ret) {
> +		dev_err(&pdev->dev, "unable to setup flash chip\n");
> +		goto dis_clks;
> +	}
> +
> +	return 0;
> +
> +dis_clks:
> +	clk_disable_unprepare(spifi->clk_spifi);
> +dis_clk_reg:
> +	clk_disable_unprepare(spifi->clk_reg);
> +	return ret;
> +}
> +
> +static int nxp_spifi_remove(struct platform_device *pdev)
> +{
> +	struct nxp_spifi *spifi = platform_get_drvdata(pdev);
> +
> +	mtd_device_unregister(&spifi->mtd);
> +	clk_disable_unprepare(spifi->clk_spifi);
> +	clk_disable_unprepare(spifi->clk_reg);
> +
> +	return 0;
> +}
> +
> +static const struct of_device_id nxp_spifi_match[] = {
> +	{.compatible = "nxp,lpc1773-spifi"},
> +	{ /* sentinel */ }
> +};
> +MODULE_DEVICE_TABLE(of, nxp_spifi_match);
> +
> +static struct platform_driver nxp_spifi_driver = {
> +	.probe	= nxp_spifi_probe,
> +	.remove	= nxp_spifi_remove,
> +	.driver	= {
> +		.name = "nxp-spifi",
> +		.of_match_table = nxp_spifi_match,
> +	},
> +};
> +module_platform_driver(nxp_spifi_driver);
> +
> +MODULE_DESCRIPTION("NXP SPI Flash Interface driver");
> +MODULE_AUTHOR("Joachim Eastwood <manabian at gmail.com>");
> +MODULE_LICENSE("GPL v2");

With that:

Reviewed-by: Brian Norris <computersforpeace at gmail.com>

and I hope to be able to merge your next revision.

Thanks,
Brian


From computersforpeace at gmail.com  Wed Aug 12 19:33:21 2015
From: computersforpeace at gmail.com (Brian Norris)
Date: Wed, 12 Aug 2015 19:33:21 -0700
Subject: [PATCH v3 2/2] doc: dt: add documentation for nxp,lpc1773-spifi
In-Reply-To: <1433436843-22296-3-git-send-email-manabian@gmail.com>
References: <1433436843-22296-1-git-send-email-manabian@gmail.com>
 <1433436843-22296-3-git-send-email-manabian@gmail.com>
Message-ID: <20150813023321.GC108786@google.com>

On Thu, Jun 04, 2015 at 06:54:03PM +0200, Joachim Eastwood wrote:
> Add device tree binding documentation for the SPI Flash Interface
> (SPIFI) found on NXP LPC18xx and LPC43xx devies.
> 
> Signed-off-by: Joachim Eastwood <manabian at gmail.com>

Applied the DT binding patch to l2-mtd.git, as it looks good.

Brian


From computersforpeace at gmail.com  Wed Aug 12 19:43:37 2015
From: computersforpeace at gmail.com (Brian Norris)
Date: Wed, 12 Aug 2015 19:43:37 -0700
Subject: [PATCH v4 2/2] doc: dt: add documentation for nxp,lpc1773-spifi
In-Reply-To: <1436473147-31063-3-git-send-email-manabian@gmail.com>
References: <1436473147-31063-1-git-send-email-manabian@gmail.com>
 <1436473147-31063-3-git-send-email-manabian@gmail.com>
Message-ID: <20150813024337.GD108786@google.com>

On Thu, Jul 09, 2015 at 10:19:07PM +0200, Joachim Eastwood wrote:
> Add device tree binding documentation for the SPI Flash Interface
> (SPIFI) found on NXP LPC18xx and LPC43xx devies.
> 
> Signed-off-by: Joachim Eastwood <manabian at gmail.com>

Whoops, I was reviewing v3... pushed this one instead now. I'll double
check that my comments on v3 are applicable to v4.

Thanks,
Brian


From computersforpeace at gmail.com  Wed Aug 12 19:48:40 2015
From: computersforpeace at gmail.com (Brian Norris)
Date: Wed, 12 Aug 2015 19:48:40 -0700
Subject: [PATCH v4 1/2] mtd: spi-nor: add driver for NXP SPI Flash
 Interface (SPIFI)
In-Reply-To: <1436473147-31063-2-git-send-email-manabian@gmail.com>
References: <1436473147-31063-1-git-send-email-manabian@gmail.com>
 <1436473147-31063-2-git-send-email-manabian@gmail.com>
Message-ID: <20150813024840.GE108786@google.com>

On Thu, Jul 09, 2015 at 10:19:06PM +0200, Joachim Eastwood wrote:
> Add SPI-NOR driver for the SPI Flash Interface (SPIFI)
> controller that is found newer NXP MCU devices.
> 
> The controller supports serial SPI Flash devices with 1-, 2-
> and 4-bit width in either SPI mode 0 or 3. The controller
> can operate in either command or memory mode. In memory mode
> the Flash is exposed as normal memory and can be directly
> accessed by the CPU.
> 
> Signed-off-by: Joachim Eastwood <manabian at gmail.com>
> Reviewed-by: Ezequiel Garcia <ezequiel at vanguardiasur.com.ar>

Yep, same comments apply from v3. Sorry for the mixup.

Brian


From jszhang at marvell.com  Wed Aug 12 20:19:25 2015
From: jszhang at marvell.com (Jisheng Zhang)
Date: Thu, 13 Aug 2015 11:19:25 +0800
Subject: [PATCH v3 1/5] pwm: add the Berlin pwm controller driver
In-Reply-To: <1439387497-6863-2-git-send-email-antoine.tenart@free-electrons.com>
References: <1439387497-6863-1-git-send-email-antoine.tenart@free-electrons.com>
 <1439387497-6863-2-git-send-email-antoine.tenart@free-electrons.com>
Message-ID: <20150813111925.217c0b14@xhacker>

Dear Antoine,

On Wed, 12 Aug 2015 15:51:33 +0200
Antoine Tenart <antoine.tenart at free-electrons.com> wrote:

> Add a PWM controller driver for the Marvell Berlin SoCs. This PWM
> controller has 4 channels.
> 
> Signed-off-by: Antoine Tenart <antoine.tenart at free-electrons.com>
> ---
>  drivers/pwm/Kconfig      |   9 ++
>  drivers/pwm/Makefile     |   1 +
>  drivers/pwm/pwm-berlin.c | 227 +++++++++++++++++++++++++++++++++++++++++++++++
>  3 files changed, 237 insertions(+)
>  create mode 100644 drivers/pwm/pwm-berlin.c
> 
> diff --git a/drivers/pwm/Kconfig b/drivers/pwm/Kconfig
> index b1541f40fd8d..1773da8145b8 100644
> --- a/drivers/pwm/Kconfig
> +++ b/drivers/pwm/Kconfig
> @@ -92,6 +92,15 @@ config PWM_BCM2835
>  	  To compile this driver as a module, choose M here: the module
>  	  will be called pwm-bcm2835.
>  
> +config PWM_BERLIN
> +	tristate "Berlin PWM support"
> +	depends on ARCH_BERLIN
> +	help
> +	  PWM framework driver for Berlin.
> +
> +	  To compile this driver as a module, choose M here: the module
> +	  will be called pwm-berlin.
> +
>  config PWM_BFIN
>  	tristate "Blackfin PWM support"
>  	depends on BFIN_GPTIMERS
> diff --git a/drivers/pwm/Makefile b/drivers/pwm/Makefile
> index ec50eb5b5a8f..670c5fce8bbb 100644
> --- a/drivers/pwm/Makefile
> +++ b/drivers/pwm/Makefile
> @@ -6,6 +6,7 @@ obj-$(CONFIG_PWM_ATMEL_HLCDC_PWM)	+= pwm-atmel-hlcdc.o
>  obj-$(CONFIG_PWM_ATMEL_TCB)	+= pwm-atmel-tcb.o
>  obj-$(CONFIG_PWM_BCM_KONA)	+= pwm-bcm-kona.o
>  obj-$(CONFIG_PWM_BCM2835)	+= pwm-bcm2835.o
> +obj-$(CONFIG_PWM_BERLIN)	+= pwm-berlin.o
>  obj-$(CONFIG_PWM_BFIN)		+= pwm-bfin.o
>  obj-$(CONFIG_PWM_CLPS711X)	+= pwm-clps711x.o
>  obj-$(CONFIG_PWM_EP93XX)	+= pwm-ep93xx.o
> diff --git a/drivers/pwm/pwm-berlin.c b/drivers/pwm/pwm-berlin.c
> new file mode 100644
> index 000000000000..f89e25ea5c6d
> --- /dev/null
> +++ b/drivers/pwm/pwm-berlin.c
> @@ -0,0 +1,227 @@
> +/*
> + * Marvell Berlin PWM driver
> + *
> + * Copyright (C) 2015 Marvell Technology Group Ltd.
> + *
> + * Antoine Tenart <antoine.tenart at free-electrons.com>
> + *
> + * This file is licensed under the terms of the GNU General Public
> + * License version 2. This program is licensed "as is" without any
> + * warranty of any kind, whether express or implied.
> + */
> +
> +#include <linux/clk.h>
> +#include <linux/io.h>
> +#include <linux/kernel.h>
> +#include <linux/module.h>
> +#include <linux/platform_device.h>
> +#include <linux/pwm.h>
> +#include <linux/spinlock.h>
> +
> +#define BERLIN_PWM_EN			0x0
> +#define BERLIN_PWM_CONTROL		0x4
> +#define BERLIN_PWM_DUTY			0x8
> +#define BERLIN_PWM_TCNT			0xc
> +
> +#define BERLIN_PWM_ENABLE		BIT(0)
> +#define BERLIN_PWM_DISABLE		0x0
> +#define BERLIN_PWM_INVERT_POLARITY	BIT(3)
> +#define BERLIN_PWM_PRESCALE_MASK	0x7
> +#define BERLIN_PWM_PRESCALE_MAX		4096
> +#define BERLIN_PWM_MAX_TCNT		65535
> +
> +struct berlin_pwm_chip {
> +	struct pwm_chip chip;
> +	struct clk *clk;
> +	void __iomem *base;
> +	spinlock_t lock;
> +};
> +
> +#define to_berlin_pwm_chip(chip)	\
> +	container_of((chip), struct berlin_pwm_chip, chip)
> +
> +#define berlin_pwm_readl(chip, channel, offset)		\
> +	readl((chip)->base + (channel) * 0x10 + offset)
> +#define berlin_pwm_writel(val, chip, channel, offset)	\
> +	writel(val, (chip)->base + (channel) * 0x10 + offset)

It's better to use relaxed version. In some platforms with PL310 such as
BG2Q, the writel/readl will cost much time on spinning the lock if there's
heavy L2 cache maintenance ongoing, this time cost is not necessary.

And IIRC, in patch V2 review, Sebastian doesn't object to relaxed version.

Thanks,
Jisheng

> +
> +/* prescaler table: {1, 4, 8, 16, 64, 256, 1024, 4096} */
> +static const u32 prescaler_diff_table[] = {
> +	1, 4, 2, 2, 4, 4, 4, 4,
> +};
> +
> +static int berlin_pwm_config(struct pwm_chip *chip, struct pwm_device *pwm,
> +			     int duty_ns, int period_ns)
> +{
> +	struct berlin_pwm_chip *berlin_chip = to_berlin_pwm_chip(chip);
> +	int ret, prescale = 0;
> +	u32 val, duty, period;
> +	u64 cycles;
> +
> +	cycles = clk_get_rate(berlin_chip->clk);
> +	cycles *= period_ns;
> +	do_div(cycles, NSEC_PER_SEC);
> +
> +	while (cycles > BERLIN_PWM_MAX_TCNT)
> +		do_div(cycles, prescaler_diff_table[++prescale]);
> +
> +	if (cycles > BERLIN_PWM_MAX_TCNT)
> +		return -EINVAL;
> +
> +	period = cycles;
> +	cycles *= duty_ns;
> +	do_div(cycles, period_ns);
> +	duty = cycles;
> +
> +	ret = clk_prepare_enable(berlin_chip->clk);
> +	if (ret)
> +		return ret;
> +
> +	spin_lock(&berlin_chip->lock);
> +
> +	val = berlin_pwm_readl(berlin_chip, pwm->hwpwm, BERLIN_PWM_CONTROL);
> +	val &= ~BERLIN_PWM_PRESCALE_MASK;
> +	val |= prescale;
> +	berlin_pwm_writel(val, berlin_chip, pwm->hwpwm, BERLIN_PWM_CONTROL);
> +
> +	berlin_pwm_writel(duty, berlin_chip, pwm->hwpwm, BERLIN_PWM_DUTY);
> +	berlin_pwm_writel(period, berlin_chip, pwm->hwpwm, BERLIN_PWM_TCNT);
> +
> +	spin_unlock(&berlin_chip->lock);
> +
> +	clk_disable_unprepare(berlin_chip->clk);
> +
> +	return 0;
> +}
> +
> +static int berlin_pwm_set_polarity(struct pwm_chip *chip,
> +				   struct pwm_device *pwm,
> +				   enum pwm_polarity polarity)
> +{
> +	struct berlin_pwm_chip *berlin_chip = to_berlin_pwm_chip(chip);
> +	int ret;
> +	u32 val;
> +
> +	ret = clk_prepare_enable(berlin_chip->clk);
> +	if (ret)
> +		return ret;
> +
> +	spin_lock(&berlin_chip->lock);
> +
> +	val = berlin_pwm_readl(berlin_chip, pwm->hwpwm, BERLIN_PWM_CONTROL);
> +
> +	if (polarity == PWM_POLARITY_NORMAL)
> +		val &= ~BERLIN_PWM_INVERT_POLARITY;
> +	else
> +		val |= BERLIN_PWM_INVERT_POLARITY;
> +
> +	berlin_pwm_writel(val, berlin_chip, pwm->hwpwm, BERLIN_PWM_CONTROL);
> +
> +	spin_unlock(&berlin_chip->lock);
> +
> +	clk_disable_unprepare(berlin_chip->clk);
> +
> +	return 0;
> +}
> +
> +static int berlin_pwm_enable(struct pwm_chip *chip, struct pwm_device *pwm)
> +{
> +	struct berlin_pwm_chip *berlin_chip = to_berlin_pwm_chip(chip);
> +	int ret;
> +
> +	ret = clk_prepare_enable(berlin_chip->clk);
> +	if (ret)
> +		return ret;
> +
> +	spin_lock(&berlin_chip->lock);
> +	berlin_pwm_writel(BERLIN_PWM_ENABLE, berlin_chip, pwm->hwpwm, BERLIN_PWM_EN);
> +	spin_unlock(&berlin_chip->lock);
> +
> +	return 0;
> +}
> +
> +static void berlin_pwm_disable(struct pwm_chip *chip, struct pwm_device *pwm)
> +{
> +	struct berlin_pwm_chip *berlin_chip = to_berlin_pwm_chip(chip);
> +
> +	spin_lock(&berlin_chip->lock);
> +	berlin_pwm_writel(BERLIN_PWM_DISABLE, berlin_chip, pwm->hwpwm, BERLIN_PWM_EN);
> +	spin_unlock(&berlin_chip->lock);
> +
> +	clk_disable_unprepare(berlin_chip->clk);
> +}
> +
> +static const struct pwm_ops berlin_pwm_ops = {
> +	.config = berlin_pwm_config,
> +	.set_polarity = berlin_pwm_set_polarity,
> +	.enable = berlin_pwm_enable,
> +	.disable = berlin_pwm_disable,
> +	.owner = THIS_MODULE,
> +};
> +
> +static const struct of_device_id berlin_pwm_match[] = {
> +	{ .compatible = "marvell,berlin-pwm" },
> +	{ },
> +};
> +MODULE_DEVICE_TABLE(of, berlin_pwm_match);
> +
> +static int berlin_pwm_probe(struct platform_device *pdev)
> +{
> +	struct berlin_pwm_chip *pwm;
> +	struct resource *res;
> +	int ret;
> +
> +	pwm = devm_kzalloc(&pdev->dev, sizeof(*pwm), GFP_KERNEL);
> +	if (!pwm)
> +		return -ENOMEM;
> +
> +	res = platform_get_resource(pdev, IORESOURCE_MEM, 0);
> +	pwm->base = devm_ioremap_resource(&pdev->dev, res);
> +	if (IS_ERR(pwm->base))
> +		return PTR_ERR(pwm->base);
> +
> +	pwm->clk = devm_clk_get(&pdev->dev, NULL);
> +	if (IS_ERR(pwm->clk))
> +		return PTR_ERR(pwm->clk);
> +
> +	pwm->chip.dev = &pdev->dev;
> +	pwm->chip.ops = &berlin_pwm_ops;
> +	pwm->chip.base = -1;
> +	pwm->chip.npwm = 4;
> +	pwm->chip.can_sleep = true;
> +	pwm->chip.of_xlate = of_pwm_xlate_with_flags;
> +	pwm->chip.of_pwm_n_cells = 3;
> +
> +	spin_lock_init(&pwm->lock);
> +
> +	ret = pwmchip_add(&pwm->chip);
> +	if (ret < 0) {
> +		dev_err(&pdev->dev, "Failed to add PWM chip: %d\n", ret);
> +		return ret;
> +	}
> +
> +	platform_set_drvdata(pdev, pwm);
> +
> +	return 0;
> +}
> +
> +static int berlin_pwm_remove(struct platform_device *pdev)
> +{
> +	struct berlin_pwm_chip *pwm = platform_get_drvdata(pdev);
> +
> +	return pwmchip_remove(&pwm->chip);
> +}
> +
> +static struct platform_driver berlin_pwm_driver = {
> +	.probe	= berlin_pwm_probe,
> +	.remove	= berlin_pwm_remove,
> +	.driver	= {
> +		.name	= "berlin-pwm",
> +		.of_match_table = berlin_pwm_match,
> +	},
> +};
> +module_platform_driver(berlin_pwm_driver);
> +
> +MODULE_AUTHOR("Antoine Tenart <antoine.tenart at free-electrons.com>");
> +MODULE_DESCRIPTION("Marvell Berlin PWM driver");
> +MODULE_LICENSE("GPL v2");



From akpm at linux-foundation.org  Wed Aug 12 20:28:08 2015
From: akpm at linux-foundation.org (Andrew Morton)
Date: Wed, 12 Aug 2015 20:28:08 -0700
Subject: enabling libgcc for 64-bit divisions, was Re: PROBLEM: XFS on
 ARM corruption 'Structure needs cleaning'
In-Reply-To: <55CBC6C6.3090306@kernel.org>
References: <5579B804.9050707@skylable.com>
 <20150612122108.GB60661@bfoster.bfoster>
 <557AD4D4.3010901@skylable.com> <20150612225209.GA20262@dastard>
 <C6D0D499B56584katsuki.uwatoko@toshiba.co.jp>
 <20150812062445.GA4520@infradead.org>
 <CA+55aFxcoXkaa1syBVxwb9-bn3rfyFam9fcNY438bkhHjHq+Vw@mail.gmail.com>
 <55CBC6C6.3090306@kernel.org>
Message-ID: <20150812202808.abe0c080.akpm@linux-foundation.org>

On Wed, 12 Aug 2015 15:20:54 -0700 Andy Lutomirski <luto at kernel.org> wrote:

> On 08/12/2015 08:49 AM, Linus Torvalds wrote:
> > On Tue, Aug 11, 2015 at 11:24 PM, Christoph Hellwig <hch at infradead.org> wrote:
> >>
> >> Maybe it's time to rely on gcc to handle 64 bit divisions now?
> >
> > Ugh. gcc still does a pretty horrible job at it. While gcc knows that
> > a widening 32x32->64 multiplication can be simplified, it doesn't do
> > the same thing for a 64/32->64 division, and always calls __udivdi3
> > for it.
> >
> > Now, __udivdi3 does avoid the general nasty case by then testing the
> > upper 32 bits of the divisor against zero, so it's not entirely
> > disastrous. It's just ugly.
> >
> > But perhaps more importantly, I'm not at all sure libgcc is
> > kernel-safe. In particular, I'm not at all sure it *remains*
> > kernel-safe. Just as an example: can you guarantee that libgcc doesn't
> > implement integer division on some architecture by using the FP
> > hardware?
> >
> > There's been a few cases where not having libgcc saved us headaches. I
> > forget the exact details, but it was something like several years ago
> > that we had gcc start to generate some insane crap exception handling
> > for C code generation, and the fact that we didn't include libgcc was
> > what made us catch it because of the resulting link error.
> >
> > libgcc just isn't reliable in kernel space. I'm not opposed to some
> > random architecture using it (arch/tile does include "-lgcc" for
> > example), but I _do_ object to the notion that we say "let's use
> > libgcc in general".
> >
> > So no. I do not believe that the occasional pain of a few people who
> > do 64-bit divides incorrectly is a good enough argument to start using
> > libgcc.
> >
> 
> Does your objection still apply if we supplied our own implementations 
> of a handful of libgcc helpers?

It's not just a matter of "how fast is the divide".  The 32-bit build
error is supposed to prompt people to ask "did I really need to use 64
bits".

That *used* to work.  A bit.  But nowadays the errors are detected so
late that the fix (often by someone other than the original developer)
is to just slap a do_div() in there.

And as the build error no longer appears to be having the desired
effect, I too have been wondering if it's time to just give up and
implement __udivdi and friends.

Or maybe there's a way of breaking 64-bit builds instead ;)


From leilk.liu at mediatek.com  Wed Aug 12 20:35:16 2015
From: leilk.liu at mediatek.com (lei liu)
Date: Thu, 13 Aug 2015 11:35:16 +0800
Subject: [PATCH v5 3/3] arm64: dts: Add spi bus dts
In-Reply-To: <CAGS+omA0dabyGkCB2JYORn1CjXvgMs_3x7nqSOOJKMg4HRhCSg@mail.gmail.com>
References: <1438931991-17044-1-git-send-email-leilk.liu@mediatek.com>
 <1438931991-17044-4-git-send-email-leilk.liu@mediatek.com>
 <CAGS+omA0dabyGkCB2JYORn1CjXvgMs_3x7nqSOOJKMg4HRhCSg@mail.gmail.com>
Message-ID: <1439436916.21454.15.camel@mhfsdcap03>

> > +               spi: spi at 1100a000 {
> > +                       compatible = "mediatek,mt8173-spi";
> > +                       #address-cells = <1>;
> > +                       #size-cells = <0>;
> > +                       reg = <0 0x1100a000 0 0x1000>;
> > +                       interrupts = <GIC_SPI 110 IRQ_TYPE_LEVEL_LOW>;
> > +                       clocks = <&topckgen CLK_TOP_SPI_SEL>, <&topckgen CLK_TOP_SYSPLL3_D2>;
> > +                       clock-names = "spi-clk", "parent-clk";
> > +                       pinctrl-names = "default";
> > +                       pinctrl-0 = <&spi_pins_a>;
> > +                       mediatek,pad-select = <0>;
> 
> The pinctl and pad-select fields are board specific.
> Please move to mt8173-evb.dtsi, along with status = "okay";
> 

OK, I will fix it.



From bp at alien8.de  Wed Aug 12 20:36:40 2015
From: bp at alien8.de (Borislav Petkov)
Date: Thu, 13 Aug 2015 05:36:40 +0200
Subject: [PATCH v3 3/4] edac: Add L3/SoC EDAC support to the APM X-Gene
 SoC EDAC driver
In-Reply-To: <CAPw-ZTkRytHUsUsDmTkfzzTYbcZnmTVRMkzNzg_9ZpdQH76rZw@mail.gmail.com>
References: <1439326077-25507-1-git-send-email-lho@apm.com>
 <1439326077-25507-2-git-send-email-lho@apm.com>
 <1439326077-25507-3-git-send-email-lho@apm.com>
 <1439326077-25507-4-git-send-email-lho@apm.com>
 <20150812105121.GE14011@nazgul.tnic>
 <CAPw-ZTkRytHUsUsDmTkfzzTYbcZnmTVRMkzNzg_9ZpdQH76rZw@mail.gmail.com>
Message-ID: <20150813033640.GB14432@nazgul.tnic>

On Wed, Aug 12, 2015 at 10:50:52AM -0700, Loc Ho wrote:
> I intentional left this code as is so that the driver will still works
> with older version of the EDAC code.

Huh, what? I don't think this is how upstream development works.

> I had already reversed the logic for the L3 and SoC. Are you asking
> for the MC/PMD (earlier posting)? The MC/PMD routine isn't that big.
> Functions in general fit in an screen of 80 column?

Only for the ones where it becomes clumsy and flipping it would make the
code more readable. I'm not a hard 80 cols follower anyway.

> So, is there something that I am missing?

I hope you're not. But seeing the custom debugfs stuff left in the new
submission without any comment as to *why* you've left it, made me think
you didn't incorporate all feedback.

-- 
Regards/Gruss,
    Boris.

ECO tip #101: Trim your mails when you reply.
--


From bp at alien8.de  Wed Aug 12 20:38:37 2015
From: bp at alien8.de (Borislav Petkov)
Date: Thu, 13 Aug 2015 05:38:37 +0200
Subject: [PATCH v3 1/4] edac: Add an function to retrieve the EDAC
 debugfs node
In-Reply-To: <CAPw-ZT=AFtyLt4CNGBzLZcdPr-ekJpQxKA4Y_AiDzqKfhF1-=w@mail.gmail.com>
References: <1439326077-25507-1-git-send-email-lho@apm.com>
 <1439326077-25507-2-git-send-email-lho@apm.com>
 <20150812101219.GC14011@nazgul.tnic>
 <20150812104954.GD14011@nazgul.tnic>
 <CAPw-ZT=AFtyLt4CNGBzLZcdPr-ekJpQxKA4Y_AiDzqKfhF1-=w@mail.gmail.com>
Message-ID: <20150813033837.GC14432@nazgul.tnic>

On Wed, Aug 12, 2015 at 10:23:11AM -0700, Loc Ho wrote:
> I can't move it completely to the header and make it static. It will
> generate a lot of compiler warning as it isn't used by other modules.

Come again?

I'm talking about static inline functions in headers. Grep the kernel
sources for examples.

-- 
Regards/Gruss,
    Boris.

ECO tip #101: Trim your mails when you reply.
--


From dave.long at linaro.org  Wed Aug 12 20:50:40 2015
From: dave.long at linaro.org (David Long)
Date: Wed, 12 Aug 2015 23:50:40 -0400
Subject: [PATCH v8 1/7] arm64: Add HAVE_REGS_AND_STACK_ACCESS_API feature
In-Reply-To: <20150811173121.GC29880@arm.com>
References: <1439254364-15362-1-git-send-email-dave.long@linaro.org>
 <1439254364-15362-2-git-send-email-dave.long@linaro.org>
 <20150811173121.GC29880@arm.com>
Message-ID: <55CC1410.1090900@linaro.org>

On 08/11/15 13:31, Will Deacon wrote:
> Hi David,
>
> On Tue, Aug 11, 2015 at 01:52:38AM +0100, David Long wrote:
>> From: "David A. Long" <dave.long at linaro.org>
>>
>> Add HAVE_REGS_AND_STACK_ACCESS_API feature for arm64.
>>
>> Signed-off-by: David A. Long <dave.long at linaro.org>
>> ---
>>   arch/arm64/Kconfig              |  1 +
>>   arch/arm64/include/asm/ptrace.h | 25 +++++++++++++
>>   arch/arm64/kernel/ptrace.c      | 77 +++++++++++++++++++++++++++++++++++++++++
>>   3 files changed, 103 insertions(+)
>>
>> diff --git a/arch/arm64/Kconfig b/arch/arm64/Kconfig
>> index 318175f..ef5d726 100644
>> --- a/arch/arm64/Kconfig
>> +++ b/arch/arm64/Kconfig
>> @@ -70,6 +70,7 @@ config ARM64
>>   	select HAVE_PERF_EVENTS
>>   	select HAVE_PERF_REGS
>>   	select HAVE_PERF_USER_STACK_DUMP
>> +	select HAVE_REGS_AND_STACK_ACCESS_API
>>   	select HAVE_RCU_TABLE_FREE
>>   	select HAVE_SYSCALL_TRACEPOINTS
>>   	select IRQ_DOMAIN
>> diff --git a/arch/arm64/include/asm/ptrace.h b/arch/arm64/include/asm/ptrace.h
>> index d6dd9fd..8f440e9 100644
>> --- a/arch/arm64/include/asm/ptrace.h
>> +++ b/arch/arm64/include/asm/ptrace.h
>> @@ -118,6 +118,8 @@ struct pt_regs {
>>   	u64 syscallno;
>>   };
>>
>> +#define MAX_REG_OFFSET (sizeof(struct user_pt_regs) - sizeof(u64))
>
> Can you not use offset_of(struct user_pt_regs, pstate) here?

Yes, "offsetof" actually though.  I've just made that change.

>> +
>>   #define arch_has_single_step()	(1)
>>
>>   #ifdef CONFIG_COMPAT
>> @@ -146,6 +148,29 @@ struct pt_regs {
>>   #define user_stack_pointer(regs) \
>>   	(!compat_user_mode(regs) ? (regs)->sp : (regs)->compat_sp)
>>
>> +/**
>> + * regs_get_register() - get register value from its offset
>> + * @regs:	   pt_regs from which register value is gotten
>> + * @offset:    offset number of the register.
>> + *
>> + * regs_get_register returns the value of a register whose offset from @regs.
>> + * The @offset is the offset of the register in struct pt_regs.
>> + * If @offset is bigger than MAX_REG_OFFSET, this returns 0.
>> + */
>> +static inline u64 regs_get_register(struct pt_regs *regs,
>> +					      unsigned int offset)
>> +{
>> +	if (unlikely(offset > MAX_REG_OFFSET))
>> +		return 0;
>> +	return *(u64 *)((u64)regs + offset);
>> +}
>
> Is this guaranteed only to be called on kernel-mode regs, or do we need
> to deal with compat tasks too?

If I understand the question I think it's fine that it only deals with 
kernel-mode registers.  The implemenation is functionally similar to the 
other five architectures that implement it.

>> +
>> +/* Valid only for Kernel mode traps. */
>> +static inline unsigned long kernel_stack_pointer(struct pt_regs *regs)
>> +{
>> +	return regs->sp;
>> +}
>> +
>>   static inline unsigned long regs_return_value(struct pt_regs *regs)
>>   {
>>   	return regs->regs[0];
>> diff --git a/arch/arm64/kernel/ptrace.c b/arch/arm64/kernel/ptrace.c
>> index d882b83..f6199a5 100644
>> --- a/arch/arm64/kernel/ptrace.c
>> +++ b/arch/arm64/kernel/ptrace.c
>> @@ -48,6 +48,83 @@
>>   #define CREATE_TRACE_POINTS
>>   #include <trace/events/syscalls.h>
>>
>> +#define ARM_pstate	pstate
>> +#define ARM_pc		pc
>> +#define ARM_sp		sp
>> +#define ARM_x30		regs[30]
>> +#define ARM_x29		regs[29]
>> +#define ARM_x28		regs[28]
>> +#define ARM_x27		regs[27]
>> +#define ARM_x26		regs[26]
>> +#define ARM_x25		regs[25]
>> +#define ARM_x24		regs[24]
>> +#define ARM_x23		regs[23]
>> +#define ARM_x22		regs[22]
>> +#define ARM_x21		regs[21]
>> +#define ARM_x20		regs[20]
>> +#define ARM_x19		regs[19]
>> +#define ARM_x18		regs[18]
>> +#define ARM_x17		regs[17]
>> +#define ARM_x16		regs[16]
>> +#define ARM_x15		regs[15]
>> +#define ARM_x14		regs[14]
>> +#define ARM_x13		regs[13]
>> +#define ARM_x12		regs[12]
>> +#define ARM_x11		regs[11]
>> +#define ARM_x10		regs[10]
>> +#define ARM_x9		regs[9]
>> +#define ARM_x8		regs[8]
>> +#define ARM_x7		regs[7]
>> +#define ARM_x6		regs[6]
>> +#define ARM_x5		regs[5]
>> +#define ARM_x4		regs[4]
>> +#define ARM_x3		regs[3]
>> +#define ARM_x2		regs[2]
>> +#define ARM_x1		regs[1]
>> +#define ARM_x0		regs[0]
>
> I've said it before, but I really don't like these macros. I'd rather
> rework the following REG_OFFSET_NAME to be GPR_OFFSET_NAME which could
> prefix the "x" in the name field.

OK, I've ripped that out and replaced REG_OFFSET_NAME with 
GPR_OFFSET_NAME, for the numbered registers.  I'm using REGS_OFFSET_NAME 
(defined for all architectures in my earlier cleanup patch) for the 
non-numbered registers.

>
>> +
>> +#define REG_OFFSET_NAME(r) \
>> +	{.name = #r, .offset = offsetof(struct pt_regs, ARM_##r)}
>> +#define REG_OFFSET_END {.name = NULL, .offset = 0}
>> +
>> +const struct pt_regs_offset regs_offset_table[] = {
>> +	REG_OFFSET_NAME(x0),
>> +	REG_OFFSET_NAME(x1),
>> +	REG_OFFSET_NAME(x2),
>> +	REG_OFFSET_NAME(x3),
>> +	REG_OFFSET_NAME(x4),
>> +	REG_OFFSET_NAME(x5),
>> +	REG_OFFSET_NAME(x6),
>> +	REG_OFFSET_NAME(x7),
>> +	REG_OFFSET_NAME(x8),
>> +	REG_OFFSET_NAME(x9),
>> +	REG_OFFSET_NAME(x10),
>> +	REG_OFFSET_NAME(x11),
>> +	REG_OFFSET_NAME(x12),
>> +	REG_OFFSET_NAME(x13),
>> +	REG_OFFSET_NAME(x14),
>> +	REG_OFFSET_NAME(x15),
>> +	REG_OFFSET_NAME(x16),
>> +	REG_OFFSET_NAME(x17),
>> +	REG_OFFSET_NAME(x18),
>> +	REG_OFFSET_NAME(x19),
>> +	REG_OFFSET_NAME(x20),
>> +	REG_OFFSET_NAME(x21),
>> +	REG_OFFSET_NAME(x22),
>> +	REG_OFFSET_NAME(x23),
>> +	REG_OFFSET_NAME(x24),
>> +	REG_OFFSET_NAME(x25),
>> +	REG_OFFSET_NAME(x26),
>> +	REG_OFFSET_NAME(x27),
>> +	REG_OFFSET_NAME(x28),
>> +	REG_OFFSET_NAME(x29),
>> +	REG_OFFSET_NAME(x30),
>
> Does this interact badly with perf tools, which expect to pass "lr" for
> x30? (see tools/perf/arch/arm64/include/perf_regs.h).
>

Possibly, I can test that when I'm back from my short vacation this 
week.  The lr/x30 thing seems to be a recurring issue.  Perhaps it is 
best simply to add a reundant entry for x30 as "lr".  It's simple enough 
to do, although just slightly ugly looking as it would have to be done 
without a macro.  Would one ever use "x31" in place of "sp"?

Conversions in the other direction would have to use one or the other of 
course.

> Will
>

-dl


From lho at apm.com  Wed Aug 12 21:13:56 2015
From: lho at apm.com (Loc Ho)
Date: Wed, 12 Aug 2015 21:13:56 -0700
Subject: [PATCH v3 3/4] edac: Add L3/SoC EDAC support to the APM X-Gene
 SoC EDAC driver
In-Reply-To: <20150813033640.GB14432@nazgul.tnic>
References: <1439326077-25507-1-git-send-email-lho@apm.com>
 <1439326077-25507-2-git-send-email-lho@apm.com>
 <1439326077-25507-3-git-send-email-lho@apm.com>
 <1439326077-25507-4-git-send-email-lho@apm.com>
 <20150812105121.GE14011@nazgul.tnic>
 <CAPw-ZTkRytHUsUsDmTkfzzTYbcZnmTVRMkzNzg_9ZpdQH76rZw@mail.gmail.com>
 <20150813033640.GB14432@nazgul.tnic>
Message-ID: <CAPw-ZTnaQGTKTPy_cqCEYvXo1o23DXQTE4xaXu4d66YB9gV8mg@mail.gmail.com>

Hi,

>> I intentional left this code as is so that the driver will still works
>> with older version of the EDAC code.
>
> Huh, what? I don't think this is how upstream development works.

I will fix this in next version.

>
>> I had already reversed the logic for the L3 and SoC. Are you asking
>> for the MC/PMD (earlier posting)? The MC/PMD routine isn't that big.
>> Functions in general fit in an screen of 80 column?
>
> Only for the ones where it becomes clumsy and flipping it would make the
> code more readable. I'm not a hard 80 cols follower anyway.

I will look at the code one more time and see if the code would be
better with logic flipped for L2/L1 and MC.

>
>> So, is there something that I am missing?
>
> I hope you're not. But seeing the custom debugfs stuff left in the new
> submission without any comment as to *why* you've left it, made me think
> you didn't incorporate all feedback.

-Loc


From bjorn.andersson at sonymobile.com  Wed Aug 12 21:14:02 2015
From: bjorn.andersson at sonymobile.com (Bjorn Andersson)
Date: Wed, 12 Aug 2015 21:14:02 -0700
Subject: [PATCH 5/9] clk: qcom: gcc-msm8960: add child devices support.
In-Reply-To: <55CBC14B.8000509@codeaurora.org>
References: <1436348838-22671-1-git-send-email-rnayak@codeaurora.org>
 <1436348838-22671-6-git-send-email-rnayak@codeaurora.org>
 <20150811224902.GO2839@codeaurora.org>
 <20150812201855.GF13472@usrtlx11787.corpusers.net>
 <55CBC14B.8000509@codeaurora.org>
Message-ID: <20150813041402.GI13472@usrtlx11787.corpusers.net>

On Wed 12 Aug 14:57 PDT 2015, Stephen Boyd wrote:

> On 08/12/2015 01:18 PM, Bjorn Andersson wrote:
> > On Tue 11 Aug 15:49 PDT 2015, Stephen Boyd wrote:
> >
> >> On 07/08, Rajendra Nayak wrote:
> >>> diff --git a/drivers/clk/qcom/gcc-msm8960.c b/drivers/clk/qcom/gcc-msm8960.c
> >>> index eb6a4f9..2c80d03 100644
> >>> --- a/drivers/clk/qcom/gcc-msm8960.c
> >>> +++ b/drivers/clk/qcom/gcc-msm8960.c
> >>> @@ -15,6 +15,7 @@
> >>>   #include <linux/bitops.h>
> >>>   #include <linux/err.h>
> >>>   #include <linux/platform_device.h>
> >>> +#include <linux/of_platform.h>
> >>>   #include <linux/module.h>
> >>>   #include <linux/of.h>
> >>>   #include <linux/of_device.h>
> >>> @@ -3520,7 +3521,8 @@ static int gcc_msm8960_probe(struct platform_device *pdev)
> >>>   	if (IS_ERR(clk))
> >>>   		return PTR_ERR(clk);
> >>>   
> >>> -	return qcom_cc_probe(pdev, match->data);
> >>> +	qcom_cc_probe(pdev, match->data);
> >>> +	return of_platform_populate(pdev->dev.of_node, NULL, NULL, &pdev->dev);
> >> We just lost the error code from qcom_cc_probe()...
> >>
> >> Also, I don't like having a subnode in DT. Why can't we use the
> >> same node as the GCC node and create a virtual child device here
> >> for tsens? We can assign the same of_node that this platform
> >> device has so that DT keeps working correctly.
> >>
> > Can't we make the gcc driver support being a child of a simple-mfd by
> > having it attempting to acquire the regmap of the parent and falling
> > back to creating its own mmio regmap?
> 
> So we would need to make a new device and driver for the simple-mfd 
> parent?

No that part is already in mainline, so my idea was that we add an early
return in qcom_cc_map() like:

	 struct device *dev = &pdev->dev;
+        struct regmap *map;
+
+        map = syscon_node_to_regmap(dev->parent->of_node);
+        if (!IS_ERR(map))
+                return map;

And then just update the dts to:

	gcc {
		compatible = "syscon", "simple-mfd";
		reg = <0x00900000 0x4000>;

		gcc: clock-controller {
			compatible = "qcom,gcc-apq8064";
			#clock-cells = <1>;
			#reset-cells = <1>;
		};
	};

But as I implemented this I realized that the syscon_node_to_regmap()
does not register the regmap as a devres of the parent, and as such it's
not caught by the regmap lookup in devm_clk_register_regmap().

So either one would need to make the syscon throw the regmap into devres
or make it possible to pass a regmap to devm_clk_register_regmap() for
this to work.

> I'm confused about what you're suggesting and what benefit it 
> has versus creating a child of the clock controller device.

The benefit would simply be that we're using the already existing
mechanism for handling multiple platform_drivers sharing a hw block.

> 
> Here's the patch I'm suggesting. The device name is probably wrong, but 
> you get the idea.

Looks very much like my take on it as well, I do however have concerns
that suddenly the node called "clock-controller" will have to come with
tsens related properties.

Are all the tsens-in-gcc blocks the same? Or do you intend to of_match
on the gcc compatible in the tsens driver?

Regards,
Bjorn


From dave.long at linaro.org  Wed Aug 12 21:23:03 2015
From: dave.long at linaro.org (David Long)
Date: Thu, 13 Aug 2015 00:23:03 -0400
Subject: [PATCH v8 2/7] arm64: Add more test functions to insn.c
In-Reply-To: <20150811180012.GE29880@arm.com>
References: <1439254364-15362-1-git-send-email-dave.long@linaro.org>
 <1439254364-15362-3-git-send-email-dave.long@linaro.org>
 <20150811180012.GE29880@arm.com>
Message-ID: <55CC1BA7.7040200@linaro.org>

On 08/11/15 14:00, Will Deacon wrote:
> On Tue, Aug 11, 2015 at 01:52:39AM +0100, David Long wrote:
>> From: "David A. Long" <dave.long at linaro.org>
>>
>> Certain instructions are hard to execute correctly out-of-line (as in
>> kprobes).  Test functions are added to insn.[hc] to identify these.  The
>> instructions include any that use PC-relative addressing, change the PC,
>> or change interrupt masking. For efficiency and simplicity test
>> functions are also added for small collections of related instructions.
>>
>> Signed-off-by: David A. Long <dave.long at linaro.org>
>> ---
>>   arch/arm64/include/asm/insn.h | 18 ++++++++++++++++++
>>   arch/arm64/kernel/insn.c      | 28 ++++++++++++++++++++++++++++
>>   2 files changed, 46 insertions(+)
>>
>> diff --git a/arch/arm64/include/asm/insn.h b/arch/arm64/include/asm/insn.h
>> index 30e50eb..66bfb21 100644
>> --- a/arch/arm64/include/asm/insn.h
>> +++ b/arch/arm64/include/asm/insn.h
>> @@ -223,8 +223,13 @@ static __always_inline bool aarch64_insn_is_##abbr(u32 code) \
>>   static __always_inline u32 aarch64_insn_get_##abbr##_value(void) \
>>   { return (val); }
>>
>> +__AARCH64_INSN_FUNCS(adr_adrp,	0x1F000000, 0x10000000)
>> +__AARCH64_INSN_FUNCS(prfm_lit,	0xFF000000, 0xD8000000)
>>   __AARCH64_INSN_FUNCS(str_reg,	0x3FE0EC00, 0x38206800)
>>   __AARCH64_INSN_FUNCS(ldr_reg,	0x3FE0EC00, 0x38606800)
>> +__AARCH64_INSN_FUNCS(ldr_lit,	0xBF000000, 0x18000000)
>> +__AARCH64_INSN_FUNCS(ldrsw_lit,	0xFF000000, 0x98000000)
>> +__AARCH64_INSN_FUNCS(exclusive,	0x3F000000, 0x08000000)
>
> Hmm, so this class also pulls in load-acquire and store-release, which
> we *should* be able to single-step, no? Maybe it's worth splitting this
> category up (or at least changing aarch64_insn_is_exclusive to be more
> permissive).

I was not confident that this was the case. After reading the relevant 
parts of the v8 ARM yet again I think I see your point.

>
>>   __AARCH64_INSN_FUNCS(stp_post,	0x7FC00000, 0x28800000)
>>   __AARCH64_INSN_FUNCS(ldp_post,	0x7FC00000, 0x28C00000)
>>   __AARCH64_INSN_FUNCS(stp_pre,	0x7FC00000, 0x29800000)
>> @@ -264,19 +269,29 @@ __AARCH64_INSN_FUNCS(ands,	0x7F200000, 0x6A000000)
>>   __AARCH64_INSN_FUNCS(bics,	0x7F200000, 0x6A200000)
>>   __AARCH64_INSN_FUNCS(b,		0xFC000000, 0x14000000)
>>   __AARCH64_INSN_FUNCS(bl,	0xFC000000, 0x94000000)
>> +__AARCH64_INSN_FUNCS(b_bl,	0x7C000000, 0x14000000)
>
> Why do we need this when we already have checks for b and bl?

I was trying to avoid doing multiple checks for different variants of 
similar instructions.

>
>> +__AARCH64_INSN_FUNCS(cb,	0x7E000000, 0x34000000)
>
> Likewise for cbz and cbnz...
>
>>   __AARCH64_INSN_FUNCS(cbz,	0x7F000000, 0x34000000)
>>   __AARCH64_INSN_FUNCS(cbnz,	0x7F000000, 0x35000000)
>> +__AARCH64_INSN_FUNCS(tb,	0x7E000000, 0x36000000)
>
> ... there's a pattern here!
>

^^

>>   __AARCH64_INSN_FUNCS(tbz,	0x7F000000, 0x36000000)
>>   __AARCH64_INSN_FUNCS(tbnz,	0x7F000000, 0x37000000)
>> +__AARCH64_INSN_FUNCS(b_bl_cb_tb, 0x5C000000, 0x14000000)
>
> I must be missing something :)

^^

>
>>   __AARCH64_INSN_FUNCS(bcond,	0xFF000010, 0x54000000)
>>   __AARCH64_INSN_FUNCS(svc,	0xFFE0001F, 0xD4000001)
>>   __AARCH64_INSN_FUNCS(hvc,	0xFFE0001F, 0xD4000002)
>>   __AARCH64_INSN_FUNCS(smc,	0xFFE0001F, 0xD4000003)
>>   __AARCH64_INSN_FUNCS(brk,	0xFFE0001F, 0xD4200000)
>> +__AARCH64_INSN_FUNCS(exception,	0xFF000000, 0xD4000000)
>>   __AARCH64_INSN_FUNCS(hint,	0xFFFFF01F, 0xD503201F)
>>   __AARCH64_INSN_FUNCS(br,	0xFFFFFC1F, 0xD61F0000)
>>   __AARCH64_INSN_FUNCS(blr,	0xFFFFFC1F, 0xD63F0000)
>> +__AARCH64_INSN_FUNCS(br_blr,	0xFFDFFC1F, 0xD61F0000)
>>   __AARCH64_INSN_FUNCS(ret,	0xFFFFFC1F, 0xD65F0000)
>> +__AARCH64_INSN_FUNCS(msr_imm,	0xFFF8F01F, 0xD500401F)
>> +__AARCH64_INSN_FUNCS(msr_reg,	0xFFF00000, 0xD5100000)
>> +__AARCH64_INSN_FUNCS(set_clr_daif, 0xFFFFF0DF, 0xD50340DF)
>> +__AARCH64_INSN_FUNCS(rd_wr_daif, 0xFFDFFFE0, 0xD51B4220)
>
> I think I'd rather have separate decoders to decode the register field
> of an mrs/msr instruction than overload each encoding here.
>
> Anyway, on the whole this looks pretty good, I'd just prefer not to build
> compound instruction checks at the encoding level (even though it looks
> like you did a good job on the values).
>

OK, easy enough to just add to the if statements where these are getting 
used.  May be getting a little bloated looking there though.

-dl



From rnayak at codeaurora.org  Wed Aug 12 21:23:23 2015
From: rnayak at codeaurora.org (Rajendra Nayak)
Date: Thu, 13 Aug 2015 09:53:23 +0530
Subject: [PATCH v8 11/13] clk: qcom: gdsc: Use PM clocks to control gdsc
 clocks
In-Reply-To: <20150811065224.GA2839@codeaurora.org>
References: <1438857474-20262-1-git-send-email-rnayak@codeaurora.org>
 <1438857474-20262-12-git-send-email-rnayak@codeaurora.org>
 <20150811065224.GA2839@codeaurora.org>
Message-ID: <55CC1BBB.5090804@codeaurora.org>

On 08/11/2015 12:22 PM, Stephen Boyd wrote:
> On 08/06, Rajendra Nayak wrote:
>> +
>> +static int gdsc_attach(struct generic_pm_domain *domain, struct device *dev)
>> +{
>> +	int ret, i = 0, j = 0;
>> +	struct gdsc *sc = domain_to_gdsc(domain);
>> +	struct of_phandle_args clkspec;
>> +	struct device_node *np = dev->of_node;
>> +
>> +	if (!sc->clock_count)
>> +		return 0;
>> +
>> +	ret = pm_clk_create(dev);
>> +	if (ret) {
>> +		dev_dbg(dev, "pm_clk_create failed %d\n", ret);
>> +		return ret;
>> +	}
>> +
>> +	sc->clks = devm_kcalloc(dev, sc->clock_count, sizeof(sc->clks),
>> +				       GFP_KERNEL);
>> +	if (!sc->clks)
>> +		return -ENOMEM;
>> +
>> +	while (!of_parse_phandle_with_args(np, "clocks", "#clock-cells", i,
>> +					   &clkspec)) {
>> +		if (match(clkspec.args[0], sc->clocks, sc->clock_count)) {
>
> I'm lost. I was hoping we could just make up a clkspec on the
> stack and pass it over to of_clk_get_from_provider() without
> having to go through the np of the client device.

Sorry, can you elaborate a little more on 'make up a clkspec on
the stack'? I don't seem to be able to figure out.

  The point being
> to avoid forcing this code from knowing about the consumer
> binding or connection name choice for each device. Instead, it

I am not associating connection names but internal clock ids with
the corresponding gdsc. I don;t see how this is forcing the code
to know consumer DT bindings. However, it is forcing the client
device to have all clocks that need to be controlled listed in DT,
which I assume should be the case.

> assumes that it's a #clock-cells=<1> binding and gets the clocks
> by passing the 1 cell data without calling
> of_parse_phandle_with_args().

Yes, the code did assume #clock-cells=<1>, which is what all of
the existing clock controllers used in QCOM SoCs use.

>
> Now, one downside of that approach is that it's DT centric (also
> of_clk_get_from_provider() is not an exported symbol yet). So I'm
> really starting to lean towards exposing __clk_create_clk() (or
> some better named "provider" function) that will allow clk
> providers to turn their clk_hw structure into a struct clk
> pointer. That avoids the DT centric design, and avoids binding
> the provider to the connection ids too.

Again, there are no connection ids used here. I can explore the approach
of associating clk_hw structs to gdscs and avoiding anything to do with
a DT lookup. I seem to however fail to understand why we need this to
have nothing to do with DT though. Do you think the clocks for a given
device which need to be controlled along with the power switch (gdsc)
should *not* be associated/listed within its DT node?




From rnayak at codeaurora.org  Wed Aug 12 21:24:23 2015
From: rnayak at codeaurora.org (Rajendra Nayak)
Date: Thu, 13 Aug 2015 09:54:23 +0530
Subject: [PATCH v8 10/13] arm: dts: qcom: Add #power-domain-cells property
In-Reply-To: <20150811065335.GB2839@codeaurora.org>
References: <1438857474-20262-1-git-send-email-rnayak@codeaurora.org>
 <1438857474-20262-11-git-send-email-rnayak@codeaurora.org>
 <20150811065335.GB2839@codeaurora.org>
Message-ID: <55CC1BF7.1040406@codeaurora.org>

On 08/11/2015 12:23 PM, Stephen Boyd wrote:
> On 08/06, Rajendra Nayak wrote:
>> msm8974 has gcc and mmcc nodes, and apq8084 has a gcc node which
>> implement gdsc powerdomains. Add the #power-domain-cells property
>> to them.
>>
>> Signed-off-by: Rajendra Nayak <rnayak at codeaurora.org>
>> ---
>
> This needs to go through  Andy's tree and arm-soc. Also, I don't
> see an update for the binding anywhere. Please update the binding
> too.

Will do, I hope you mean update the bindings in qcom,mmcc.txt and
qcom,gcc.txt?


From rnayak at codeaurora.org  Wed Aug 12 21:28:46 2015
From: rnayak at codeaurora.org (Rajendra Nayak)
Date: Thu, 13 Aug 2015 09:58:46 +0530
Subject: [PATCH 5/9] clk: qcom: gcc-msm8960: add child devices support.
In-Reply-To: <55CB0B26.2020105@linaro.org>
References: <1436348838-22671-1-git-send-email-rnayak@codeaurora.org>
 <1436348838-22671-6-git-send-email-rnayak@codeaurora.org>
 <20150811224902.GO2839@codeaurora.org> <55CB0B26.2020105@linaro.org>
Message-ID: <55CC1CFE.7000005@codeaurora.org>

> On 11/08/15 23:49, Stephen Boyd wrote:
>> On 07/08, Rajendra Nayak wrote:
>>> diff --git a/drivers/clk/qcom/gcc-msm8960.c
>>> b/drivers/clk/qcom/gcc-msm8960.c
>>> index eb6a4f9..2c80d03 100644
>>> --- a/drivers/clk/qcom/gcc-msm8960.c
>>> +++ b/drivers/clk/qcom/gcc-msm8960.c
>>> @@ -15,6 +15,7 @@
>>>   #include <linux/bitops.h>
>>>   #include <linux/err.h>
>>>   #include <linux/platform_device.h>
>>> +#include <linux/of_platform.h>
>>>   #include <linux/module.h>
>>>   #include <linux/of.h>
>>>   #include <linux/of_device.h>
>>> @@ -3520,7 +3521,8 @@ static int gcc_msm8960_probe(struct
>>> platform_device *pdev)
>>>       if (IS_ERR(clk))
>>>           return PTR_ERR(clk);
>>>
>>> -    return qcom_cc_probe(pdev, match->data);
>>> +    qcom_cc_probe(pdev, match->data);
>>> +    return of_platform_populate(pdev->dev.of_node, NULL, NULL,
>>> &pdev->dev);
>>
>> We just lost the error code from qcom_cc_probe()...
>>
> I think Rajendra picked up the wrong patch for this series, I did submit
> a v2 (https://patches.linaro.org/44033/) with the above fixed.

ah, sorry about that.

>> Also, I don't like having a subnode in DT. Why can't we use the
>> same node as the GCC node and create a virtual child device here
>> for tsens? We can assign the same of_node that this platform
>> device has so that DT keeps working correctly.

So the current driver looks up data based on compatible strings.
So you suggesting to create a virtual child device for gcc and
associate the gcc DT node to it? (And have the tsens compatible
mentioned as part of the gcc DT node?)
How is this any different from creating a subnode in DT anyway?


From bjorn.andersson at sonymobile.com  Wed Aug 12 21:30:36 2015
From: bjorn.andersson at sonymobile.com (Bjorn Andersson)
Date: Wed, 12 Aug 2015 21:30:36 -0700
Subject: [PATCH RFC 08/10] hwspinlock: qcom: Lock #7 is special lock,
 uses dynamic proc_id
In-Reply-To: <1438792366-2737-9-git-send-email-lina.iyer@linaro.org>
References: <438731339-58317-1-git-send-email-lina.iyer@linaro.org>
 <1438792366-2737-1-git-send-email-lina.iyer@linaro.org>
 <1438792366-2737-9-git-send-email-lina.iyer@linaro.org>
Message-ID: <20150813043036.GJ13472@usrtlx11787.corpusers.net>

On Wed 05 Aug 09:32 PDT 2015, Lina Iyer wrote:

> Hwspinlocks are widely used between processors in an SoC, and also
> between elevation levels within in the same processor.  QCOM SoC's use
> hwspinlock to serialize entry into a low power mode when the context
> switches from Linux to secure monitor.
> 
> Lock #7 has been assigned for this purpose. In order to differentiate
> between one cpu core holding a lock while another cpu is contending for
> the same lock, the proc id written into the lock is (128 + cpu id). This
> makes it unique value among the cpu cores and therefore when a core
> locks the hwspinlock, other cores would wait for the lock to be released
> since they would have a different proc id.  This value is specific for
> the lock #7 only.
> 

As I was thinking about this, I came to the conclusion that my argument
that it's system configuration and not a property of the block that lock
#7 is special is actually biting myself.

Just as #7 is system configuration, so is the fact that 1 is the lock
value for all other locks.

I've been meaning to answer you, but I haven't come to a good conclusion
in this matter. I think that both of these properties should be possible
to express in DT, but I don't know how.


Perhaps we should just list each lock that we expose as a subnode in DT
with a property to indicate the lock value - with the possibility of
indicating cpu_id.

Something like:

tcsr-mutex {
	compatible = "qcom,tcsr-mutex";
	syscon = <&tcsr_mutex_block 0 0x80>;

	#hwlock-cells = <1>;
	#address-cells = <1>;
	#size-cells = <0>;

	smem-lock at 3 {
		reg = <3>;
		qcom,lock-value = <1>;
	};

	scm-lock at 7 {
		reg = <7>;
		qcom,lock-value-from-cpu-id;
		qcom,lock-raw;
	};
};

As we don't reference most of these locks anyways I don't think this
would still be reasonable. And if reg is an array it's quite compact.

> Declare lock #7 as raw capable, so the hwspinlock framework would not
> enfore acquiring a s/w spinlock before acquiring the hwspinlock.
> 

I'm fine with this part!


Sorry for the extremely slow response, but this took some time to
process...

Regards,
Bjorn


From lho at apm.com  Wed Aug 12 21:30:58 2015
From: lho at apm.com (Loc Ho)
Date: Wed, 12 Aug 2015 21:30:58 -0700
Subject: [PATCH v3 1/4] edac: Add an function to retrieve the EDAC debugfs
 node
In-Reply-To: <CAPw-ZT=AFtyLt4CNGBzLZcdPr-ekJpQxKA4Y_AiDzqKfhF1-=w@mail.gmail.com>
References: <1439326077-25507-1-git-send-email-lho@apm.com>
 <1439326077-25507-2-git-send-email-lho@apm.com>
 <20150812101219.GC14011@nazgul.tnic>
 <20150812104954.GD14011@nazgul.tnic>
 <CAPw-ZT=AFtyLt4CNGBzLZcdPr-ekJpQxKA4Y_AiDzqKfhF1-=w@mail.gmail.com>
Message-ID: <CAPw-ZTkfAxqG6HQHU3WomrqRwXa+jyTWCg=ns1HKC323ds1yug@mail.gmail.com>

Hi,

>
>>> EXPORT_SYMBOL_GPL() if it is going to be used by modules.
>>
>> Better yet, move it to the header.
>
> I can't move it completely to the header and make it static. It will
> generate a lot of compiler warning as it isn't used by other modules.
> I will add EXPORT_SYMBOL_GPL() in the next version.

Okay... The 'inline' helps with the compiler warning. If I move all to
header file with 'static inline' and wrapper around CONFIG_EDAC_DEBUG,
don't I need to export and declare the variable 'edac_debugfs'? Are
you okay with export this variable? Or, it is static inline if not
defined CONFIG_EDAC_DEBUG. Otherwise, just  an extern header function
and export it as well?

-Loc


From djkurtz at chromium.org  Wed Aug 12 21:49:46 2015
From: djkurtz at chromium.org (Daniel Kurtz)
Date: Thu, 13 Aug 2015 12:49:46 +0800
Subject: [PATCH 0/5] add GPT timer support for mt8173
In-Reply-To: <55CB3CCB.6020607@linaro.org>
References: <1436779969-18610-1-git-send-email-yingjoe.chen@mediatek.com>
 <CAGS+omAeYhXDpBueG-F_gYBccqeaejN9k5bRKC78aDLfvHfnBA@mail.gmail.com>
 <55CB3CCB.6020607@linaro.org>
Message-ID: <CAGS+omA7+O+hKqcSjYabLL08T1Va-Ryw=dNB_ZA34++-04dHHg@mail.gmail.com>

On Wed, Aug 12, 2015 at 8:32 PM, Daniel Lezcano
<daniel.lezcano at linaro.org> wrote:
> On 08/11/2015 05:54 PM, Daniel Kurtz wrote:
>>
>> On Mon, Jul 13, 2015 at 5:32 PM, Yingjoe Chen <yingjoe.chen at mediatek.com>
>> wrote:
>>>
>>> This series add GPT timer support for mt8173. This is based on v4.2-rc1
>>> and Matthias' next branch (for dts parts).
>>>
>>> The first 2 patches comes from 'Add SMP bringup support for mt65xx socs'
>>> series [1]. I decide to move these 2 patches to this series, since it
>>> is more relevent here. They are changed based on Matthias' and Daniel's
>>> comments.
>>>
>>> [1]
>>> http://lists.infradead.org/pipermail/linux-mediatek/2015-May/000714.html
>>>
>>> Daniel Kurtz (1):
>>>    arm64: dts: mt8173: add timer node
>>>
>>> Yingjoe Chen (4):
>>>    clocksource: mediatek: do not enable GPT_CLK_EVT when setup
>>>    clocksource: mediatek: Use GPT as sched clock source
>>>    arm64: mediatek: enable MTK_TIMER
>>>    clk: mediatek: add 13mhz clock for MT8173
>>
>>
>> Was this mediatek clocksource patch set get forgotten again?
>
>
> Yep. Sounds like it felt at the wrong moment.
>
>> All 5 patches have have been reviewed, and I think the ones that need
>> it have been Ack'ed by Matthias and/or Stephen.
>> What is the plan for merging them?
>
>
> So if I am not wrong we have two patches I can take in my tree as a couple
> of fixes (1 and 2), right ?

Yes.
Patches 3 & 5 are for Matthias, and patch 4 is Ack'ed by Stephen Boyd,
so I assume Matthias can pick that one up too.

Matthias, is that correct?
Or does Patch 4 need to go in via a clock maintainer's tree?

-Dan


From ryabinin.a.a at gmail.com  Wed Aug 12 22:37:22 2015
From: ryabinin.a.a at gmail.com (Andrey Ryabinin)
Date: Thu, 13 Aug 2015 08:37:22 +0300
Subject: [PATCH 0/2] x86/KASAN updates for 4.3
Message-ID: <1439444244-26057-1-git-send-email-ryabinin.a.a@gmail.com>

These 2 patches taken from v5 'KASAN for arm64' series.
The only change is updated changelog in second patch.

I hope this is not too late to queue these for 4.3,
as this allow us to merge arm64/KASAN patches in v4.4
through arm64 tree.



Andrey Ryabinin (2):
  x86/kasan: define KASAN_SHADOW_OFFSET per architecture
  x86/kasan, mm: introduce generic kasan_populate_zero_shadow()

 arch/x86/include/asm/kasan.h |   3 +
 arch/x86/mm/kasan_init_64.c  | 123 ++--------------------------------
 include/linux/kasan.h        |  10 ++-
 mm/kasan/Makefile            |   2 +-
 mm/kasan/kasan_init.c        | 152 +++++++++++++++++++++++++++++++++++++++++++
 5 files changed, 170 insertions(+), 120 deletions(-)
 create mode 100644 mm/kasan/kasan_init.c

-- 
2.4.6



From ryabinin.a.a at gmail.com  Wed Aug 12 22:37:23 2015
From: ryabinin.a.a at gmail.com (Andrey Ryabinin)
Date: Thu, 13 Aug 2015 08:37:23 +0300
Subject: [PATCH v6 1/2] x86/kasan: define KASAN_SHADOW_OFFSET per architecture
In-Reply-To: <1439444244-26057-1-git-send-email-ryabinin.a.a@gmail.com>
References: <1439444244-26057-1-git-send-email-ryabinin.a.a@gmail.com>
Message-ID: <1439444244-26057-2-git-send-email-ryabinin.a.a@gmail.com>

Current definition of  KASAN_SHADOW_OFFSET in include/linux/kasan.h
will not work for upcomming arm64, so move it to the arch header.

Signed-off-by: Andrey Ryabinin <ryabinin.a.a at gmail.com>
---
 arch/x86/include/asm/kasan.h | 3 +++
 include/linux/kasan.h        | 1 -
 2 files changed, 3 insertions(+), 1 deletion(-)

diff --git a/arch/x86/include/asm/kasan.h b/arch/x86/include/asm/kasan.h
index 74a2a8d..1410b56 100644
--- a/arch/x86/include/asm/kasan.h
+++ b/arch/x86/include/asm/kasan.h
@@ -1,6 +1,9 @@
 #ifndef _ASM_X86_KASAN_H
 #define _ASM_X86_KASAN_H
 
+#include <linux/const.h>
+#define KASAN_SHADOW_OFFSET _AC(CONFIG_KASAN_SHADOW_OFFSET, UL)
+
 /*
  * Compiler uses shadow offset assuming that addresses start
  * from 0. Kernel addresses don't start from 0, so shadow
diff --git a/include/linux/kasan.h b/include/linux/kasan.h
index 5486d77..6fb1c7d 100644
--- a/include/linux/kasan.h
+++ b/include/linux/kasan.h
@@ -10,7 +10,6 @@ struct vm_struct;
 #ifdef CONFIG_KASAN
 
 #define KASAN_SHADOW_SCALE_SHIFT 3
-#define KASAN_SHADOW_OFFSET _AC(CONFIG_KASAN_SHADOW_OFFSET, UL)
 
 #include <asm/kasan.h>
 #include <linux/sched.h>
-- 
2.4.6



From ryabinin.a.a at gmail.com  Wed Aug 12 22:37:24 2015
From: ryabinin.a.a at gmail.com (Andrey Ryabinin)
Date: Thu, 13 Aug 2015 08:37:24 +0300
Subject: [PATCH v6 2/2] x86/kasan,
 mm: introduce generic kasan_populate_zero_shadow()
In-Reply-To: <1439444244-26057-1-git-send-email-ryabinin.a.a@gmail.com>
References: <1439444244-26057-1-git-send-email-ryabinin.a.a@gmail.com>
Message-ID: <1439444244-26057-3-git-send-email-ryabinin.a.a@gmail.com>

Introduce generic kasan_populate_zero_shadow(shadow_start, shadow_end).
This function maps kasan_zero_page to the [shadow_start, shadow_end]
addresses.

This replaces x86_64 specific populate_zero_shadow() and will
be used for ARM64 in follow on patches.

The main changes from original version are:
 * Use p?d_populate*() instead of set_p?d()
 * Use memblock allocator directly instead of vmemmap_alloc_block()
 * __pa() instead of __pa_nodebug(). __pa() causes troubles
   iff we use it before kasan_early_init(). kasan_populate_zero_shadow()
   will be used later, so we ok with __pa() here.

Signed-off-by: Andrey Ryabinin <ryabinin.a.a at gmail.com>
---
 arch/x86/mm/kasan_init_64.c | 123 ++---------------------------------
 include/linux/kasan.h       |   9 +++
 mm/kasan/Makefile           |   2 +-
 mm/kasan/kasan_init.c       | 152 ++++++++++++++++++++++++++++++++++++++++++++
 4 files changed, 167 insertions(+), 119 deletions(-)
 create mode 100644 mm/kasan/kasan_init.c

diff --git a/arch/x86/mm/kasan_init_64.c b/arch/x86/mm/kasan_init_64.c
index e1840f3..9ce5da2 100644
--- a/arch/x86/mm/kasan_init_64.c
+++ b/arch/x86/mm/kasan_init_64.c
@@ -12,20 +12,6 @@
 extern pgd_t early_level4_pgt[PTRS_PER_PGD];
 extern struct range pfn_mapped[E820_X_MAX];
 
-static pud_t kasan_zero_pud[PTRS_PER_PUD] __page_aligned_bss;
-static pmd_t kasan_zero_pmd[PTRS_PER_PMD] __page_aligned_bss;
-static pte_t kasan_zero_pte[PTRS_PER_PTE] __page_aligned_bss;
-
-/*
- * This page used as early shadow. We don't use empty_zero_page
- * at early stages, stack instrumentation could write some garbage
- * to this page.
- * Latter we reuse it as zero shadow for large ranges of memory
- * that allowed to access, but not instrumented by kasan
- * (vmalloc/vmemmap ...).
- */
-static unsigned char kasan_zero_page[PAGE_SIZE] __page_aligned_bss;
-
 static int __init map_range(struct range *range)
 {
 	unsigned long start;
@@ -62,106 +48,6 @@ static void __init kasan_map_early_shadow(pgd_t *pgd)
 	}
 }
 
-static int __init zero_pte_populate(pmd_t *pmd, unsigned long addr,
-				unsigned long end)
-{
-	pte_t *pte = pte_offset_kernel(pmd, addr);
-
-	while (addr + PAGE_SIZE <= end) {
-		WARN_ON(!pte_none(*pte));
-		set_pte(pte, __pte(__pa_nodebug(kasan_zero_page)
-					| __PAGE_KERNEL_RO));
-		addr += PAGE_SIZE;
-		pte = pte_offset_kernel(pmd, addr);
-	}
-	return 0;
-}
-
-static int __init zero_pmd_populate(pud_t *pud, unsigned long addr,
-				unsigned long end)
-{
-	int ret = 0;
-	pmd_t *pmd = pmd_offset(pud, addr);
-
-	while (IS_ALIGNED(addr, PMD_SIZE) && addr + PMD_SIZE <= end) {
-		WARN_ON(!pmd_none(*pmd));
-		set_pmd(pmd, __pmd(__pa_nodebug(kasan_zero_pte)
-					| _KERNPG_TABLE));
-		addr += PMD_SIZE;
-		pmd = pmd_offset(pud, addr);
-	}
-	if (addr < end) {
-		if (pmd_none(*pmd)) {
-			void *p = vmemmap_alloc_block(PAGE_SIZE, NUMA_NO_NODE);
-			if (!p)
-				return -ENOMEM;
-			set_pmd(pmd, __pmd(__pa_nodebug(p) | _KERNPG_TABLE));
-		}
-		ret = zero_pte_populate(pmd, addr, end);
-	}
-	return ret;
-}
-
-
-static int __init zero_pud_populate(pgd_t *pgd, unsigned long addr,
-				unsigned long end)
-{
-	int ret = 0;
-	pud_t *pud = pud_offset(pgd, addr);
-
-	while (IS_ALIGNED(addr, PUD_SIZE) && addr + PUD_SIZE <= end) {
-		WARN_ON(!pud_none(*pud));
-		set_pud(pud, __pud(__pa_nodebug(kasan_zero_pmd)
-					| _KERNPG_TABLE));
-		addr += PUD_SIZE;
-		pud = pud_offset(pgd, addr);
-	}
-
-	if (addr < end) {
-		if (pud_none(*pud)) {
-			void *p = vmemmap_alloc_block(PAGE_SIZE, NUMA_NO_NODE);
-			if (!p)
-				return -ENOMEM;
-			set_pud(pud, __pud(__pa_nodebug(p) | _KERNPG_TABLE));
-		}
-		ret = zero_pmd_populate(pud, addr, end);
-	}
-	return ret;
-}
-
-static int __init zero_pgd_populate(unsigned long addr, unsigned long end)
-{
-	int ret = 0;
-	pgd_t *pgd = pgd_offset_k(addr);
-
-	while (IS_ALIGNED(addr, PGDIR_SIZE) && addr + PGDIR_SIZE <= end) {
-		WARN_ON(!pgd_none(*pgd));
-		set_pgd(pgd, __pgd(__pa_nodebug(kasan_zero_pud)
-					| _KERNPG_TABLE));
-		addr += PGDIR_SIZE;
-		pgd = pgd_offset_k(addr);
-	}
-
-	if (addr < end) {
-		if (pgd_none(*pgd)) {
-			void *p = vmemmap_alloc_block(PAGE_SIZE, NUMA_NO_NODE);
-			if (!p)
-				return -ENOMEM;
-			set_pgd(pgd, __pgd(__pa_nodebug(p) | _KERNPG_TABLE));
-		}
-		ret = zero_pud_populate(pgd, addr, end);
-	}
-	return ret;
-}
-
-
-static void __init populate_zero_shadow(const void *start, const void *end)
-{
-	if (zero_pgd_populate((unsigned long)start, (unsigned long)end))
-		panic("kasan: unable to map zero shadow!");
-}
-
-
 #ifdef CONFIG_KASAN_INLINE
 static int kasan_die_handler(struct notifier_block *self,
 			     unsigned long val,
@@ -213,7 +99,7 @@ void __init kasan_init(void)
 
 	clear_pgds(KASAN_SHADOW_START, KASAN_SHADOW_END);
 
-	populate_zero_shadow((void *)KASAN_SHADOW_START,
+	kasan_populate_zero_shadow((void *)KASAN_SHADOW_START,
 			kasan_mem_to_shadow((void *)PAGE_OFFSET));
 
 	for (i = 0; i < E820_X_MAX; i++) {
@@ -223,14 +109,15 @@ void __init kasan_init(void)
 		if (map_range(&pfn_mapped[i]))
 			panic("kasan: unable to allocate shadow!");
 	}
-	populate_zero_shadow(kasan_mem_to_shadow((void *)PAGE_OFFSET + MAXMEM),
-			kasan_mem_to_shadow((void *)__START_KERNEL_map));
+	kasan_populate_zero_shadow(
+		kasan_mem_to_shadow((void *)PAGE_OFFSET + MAXMEM),
+		kasan_mem_to_shadow((void *)__START_KERNEL_map));
 
 	vmemmap_populate((unsigned long)kasan_mem_to_shadow(_stext),
 			(unsigned long)kasan_mem_to_shadow(_end),
 			NUMA_NO_NODE);
 
-	populate_zero_shadow(kasan_mem_to_shadow((void *)MODULES_END),
+	kasan_populate_zero_shadow(kasan_mem_to_shadow((void *)MODULES_END),
 			(void *)KASAN_SHADOW_END);
 
 	memset(kasan_zero_page, 0, PAGE_SIZE);
diff --git a/include/linux/kasan.h b/include/linux/kasan.h
index 6fb1c7d..4b9f85c 100644
--- a/include/linux/kasan.h
+++ b/include/linux/kasan.h
@@ -12,8 +12,17 @@ struct vm_struct;
 #define KASAN_SHADOW_SCALE_SHIFT 3
 
 #include <asm/kasan.h>
+#include <asm/pgtable.h>
 #include <linux/sched.h>
 
+extern unsigned char kasan_zero_page[PAGE_SIZE];
+extern pte_t kasan_zero_pte[PTRS_PER_PTE];
+extern pmd_t kasan_zero_pmd[PTRS_PER_PMD];
+extern pud_t kasan_zero_pud[PTRS_PER_PUD];
+
+void kasan_populate_zero_shadow(const void *shadow_start,
+				const void *shadow_end);
+
 static inline void *kasan_mem_to_shadow(const void *addr)
 {
 	return (void *)((unsigned long)addr >> KASAN_SHADOW_SCALE_SHIFT)
diff --git a/mm/kasan/Makefile b/mm/kasan/Makefile
index bd837b8..6471014 100644
--- a/mm/kasan/Makefile
+++ b/mm/kasan/Makefile
@@ -5,4 +5,4 @@ CFLAGS_REMOVE_kasan.o = -pg
 # see: https://gcc.gnu.org/bugzilla/show_bug.cgi?id=63533
 CFLAGS_kasan.o := $(call cc-option, -fno-conserve-stack -fno-stack-protector)
 
-obj-y := kasan.o report.o
+obj-y := kasan.o report.o kasan_init.o
diff --git a/mm/kasan/kasan_init.c b/mm/kasan/kasan_init.c
new file mode 100644
index 0000000..3f9a41c
--- /dev/null
+++ b/mm/kasan/kasan_init.c
@@ -0,0 +1,152 @@
+/*
+ * This file contains some kasan initialization code.
+ *
+ * Copyright (c) 2015 Samsung Electronics Co., Ltd.
+ * Author: Andrey Ryabinin <ryabinin.a.a at gmail.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.
+ *
+ */
+
+#include <linux/bootmem.h>
+#include <linux/init.h>
+#include <linux/kasan.h>
+#include <linux/kernel.h>
+#include <linux/memblock.h>
+#include <linux/pfn.h>
+
+#include <asm/page.h>
+#include <asm/pgalloc.h>
+
+/*
+ * This page serves two purposes:
+ *   - It used as early shadow memory. The entire shadow region populated
+ *     with this page, before we will be able to setup normal shadow memory.
+ *   - Latter it reused it as zero shadow to cover large ranges of memory
+ *     that allowed to access, but not handled by kasan (vmalloc/vmemmap ...).
+ */
+unsigned char kasan_zero_page[PAGE_SIZE] __page_aligned_bss;
+
+#if CONFIG_PGTABLE_LEVELS > 3
+pud_t kasan_zero_pud[PTRS_PER_PUD] __page_aligned_bss;
+#endif
+#if CONFIG_PGTABLE_LEVELS > 2
+pmd_t kasan_zero_pmd[PTRS_PER_PMD] __page_aligned_bss;
+#endif
+pte_t kasan_zero_pte[PTRS_PER_PTE] __page_aligned_bss;
+
+static __init void *early_alloc(size_t size, int node)
+{
+	return memblock_virt_alloc_try_nid(size, size, __pa(MAX_DMA_ADDRESS),
+					BOOTMEM_ALLOC_ACCESSIBLE, node);
+}
+
+static void __init zero_pte_populate(pmd_t *pmd, unsigned long addr,
+				unsigned long end)
+{
+	pte_t *pte = pte_offset_kernel(pmd, addr);
+	pte_t zero_pte;
+
+	zero_pte = pfn_pte(PFN_DOWN(__pa(kasan_zero_page)), PAGE_KERNEL);
+	zero_pte = pte_wrprotect(zero_pte);
+
+	while (addr + PAGE_SIZE <= end) {
+		set_pte_at(&init_mm, addr, pte, zero_pte);
+		addr += PAGE_SIZE;
+		pte = pte_offset_kernel(pmd, addr);
+	}
+}
+
+static void __init zero_pmd_populate(pud_t *pud, unsigned long addr,
+				unsigned long end)
+{
+	pmd_t *pmd = pmd_offset(pud, addr);
+	unsigned long next;
+
+	do {
+		next = pmd_addr_end(addr, end);
+
+		if (IS_ALIGNED(addr, PMD_SIZE) && end - addr >= PMD_SIZE) {
+			pmd_populate_kernel(&init_mm, pmd, kasan_zero_pte);
+			continue;
+		}
+
+		if (pmd_none(*pmd)) {
+			pmd_populate_kernel(&init_mm, pmd,
+					early_alloc(PAGE_SIZE, NUMA_NO_NODE));
+		}
+		zero_pte_populate(pmd, addr, next);
+	} while (pmd++, addr = next, addr != end);
+}
+
+static void __init zero_pud_populate(pgd_t *pgd, unsigned long addr,
+				unsigned long end)
+{
+	pud_t *pud = pud_offset(pgd, addr);
+	unsigned long next;
+
+	do {
+		next = pud_addr_end(addr, end);
+		if (IS_ALIGNED(addr, PUD_SIZE) && end - addr >= PUD_SIZE) {
+			pmd_t *pmd;
+
+			pud_populate(&init_mm, pud, kasan_zero_pmd);
+			pmd = pmd_offset(pud, addr);
+			pmd_populate_kernel(&init_mm, pmd, kasan_zero_pte);
+			continue;
+		}
+
+		if (pud_none(*pud)) {
+			pud_populate(&init_mm, pud,
+				early_alloc(PAGE_SIZE, NUMA_NO_NODE));
+		}
+		zero_pmd_populate(pud, addr, next);
+	} while (pud++, addr = next, addr != end);
+}
+
+/**
+ * kasan_populate_zero_shadow - populate shadow memory region with
+ *                               kasan_zero_page
+ * @shadow_start - start of the memory range to populate
+ * @shadow_end   - end of the memory range to populate
+ */
+void __init kasan_populate_zero_shadow(const void *shadow_start,
+				const void *shadow_end)
+{
+	unsigned long addr = (unsigned long)shadow_start;
+	unsigned long end = (unsigned long)shadow_end;
+	pgd_t *pgd = pgd_offset_k(addr);
+	unsigned long next;
+
+	do {
+		next = pgd_addr_end(addr, end);
+
+		if (IS_ALIGNED(addr, PGDIR_SIZE) && end - addr >= PGDIR_SIZE) {
+			pud_t *pud;
+			pmd_t *pmd;
+
+			/*
+			 * kasan_zero_pud should be populated with pmds
+			 * at this moment.
+			 * [pud,pmd]_populate*() below needed only for
+			 * 3,2 - level page tables where we don't have
+			 * puds,pmds, so pgd_populate(), pud_populate()
+			 * is noops.
+			 */
+			pgd_populate(&init_mm, pgd, kasan_zero_pud);
+			pud = pud_offset(pgd, addr);
+			pud_populate(&init_mm, pud, kasan_zero_pmd);
+			pmd = pmd_offset(pud, addr);
+			pmd_populate_kernel(&init_mm, pmd, kasan_zero_pte);
+			continue;
+		}
+
+		if (pgd_none(*pgd)) {
+			pgd_populate(&init_mm, pgd,
+				early_alloc(PAGE_SIZE, NUMA_NO_NODE));
+		}
+		zero_pud_populate(pgd, addr, next);
+	} while (pgd++, addr = next, addr != end);
+}
-- 
2.4.6



From leilk.liu at mediatek.com  Wed Aug 12 23:29:24 2015
From: leilk.liu at mediatek.com (lei liu)
Date: Thu, 13 Aug 2015 14:29:24 +0800
Subject: [v5,2/3] spi: mediatek: Add spi bus for Mediatek MT8173
In-Reply-To: <CANMq1KBNz7u0XHQBwmJjLbXyT0twxnfFJ7Hn1Cp8HmnKdOdduw@mail.gmail.com>
References: <1438931991-17044-3-git-send-email-leilk.liu@mediatek.com>
 <CANMq1KBNz7u0XHQBwmJjLbXyT0twxnfFJ7Hn1Cp8HmnKdOdduw@mail.gmail.com>
Message-ID: <1439447364.21454.44.camel@mhfsdcap03>

Hi,

> > +#include <linux/clk.h>
> > +#include <linux/device.h>
> > +#include <linux/err.h>
> > +#include <linux/interrupt.h>
> 
> Since you are using readl/writel, please import linux/io.h as well (it
> is implicitly imported by spi/spi.h, but better be safe...)
> 
OK, I'll fix it.

> > +#include <linux/ioport.h>
> > +#include <linux/module.h>
> > +#include <linux/of.h>

> > +
> > +#define SPI_CMD_ACT_OFFSET                0
> > +#define SPI_CMD_RESUME_OFFSET             1
> > +#define SPI_CMD_CPHA_OFFSET               8
> > +#define SPI_CMD_CPOL_OFFSET               9
> > +#define SPI_CMD_TXMSBF_OFFSET             12
> > +#define SPI_CMD_RXMSBF_OFFSET             13
> > +#define SPI_CMD_RX_ENDIAN_OFFSET          14
> > +#define SPI_CMD_TX_ENDIAN_OFFSET          15
> 
> It feels error-prone that you are defining these offsets here, then
> redefining the bits just below.
> 
> Looking at the code, I think it's better if you remove these
> SPI_CMD_*_OFFSET defines, and only use the BIT(x) defines below.
> 
OK, I will remove those defines.

> > +#define SPI_CMD_RST                  BIT(2)
> > +#define SPI_CMD_PAUSE_EN             BIT(4)
> > +#define SPI_CMD_DEASSERT             BIT(5)
> > +#define SPI_CMD_CPHA                 BIT(8)
> > +#define SPI_CMD_CPOL                 BIT(9)
> > +#define SPI_CMD_RX_DMA               BIT(10)
> > +#define SPI_CMD_TX_DMA               BIT(11)
> > +#define SPI_CMD_TXMSBF               BIT(12)
> > +#define SPI_CMD_RXMSBF               BIT(13)
> > +#define SPI_CMD_RX_ENDIAN            BIT(14)
> > +#define SPI_CMD_TX_ENDIAN            BIT(15)
> > +#define SPI_CMD_FINISH_IE            BIT(16)
> > +#define SPI_CMD_PAUSE_IE             BIT(17)
> > +

> > +
> > +struct mtk_spi_compatible {
> > +       u32 need_pad_sel;
> > +       u32 must_tx;
> 
> Since the quirks are true/false, define these as bool, and remove
> MTK_SPI_QUIRK_PAD_SELECT/MTK_SPI_QUIRK_MUST_TX. Move the comment here
> too.
> 
OK. I will fix it.

> > +};
> > +

> > +static const struct mtk_spi_compatible mt6589_compat = {
> > +       .need_pad_sel = 0,
> > +       .must_tx = 0,
> > +};
> > +
> > +static const struct mtk_spi_compatible mt8135_compat = {
> > +       .need_pad_sel = 0,
> > +       .must_tx = 0,
> > +};
> 
> You don't need to set these explicitly to 0/false.
> 
OK, I will fix it.

> > +
> > +static const struct mtk_spi_compatible mt8173_compat = {
> > +       .need_pad_sel = MTK_SPI_QUIRK_PAD_SELECT,
> > +       .must_tx = MTK_SPI_QUIRK_MUST_TX,
> 
> Then you can set those as "true".
> 
OK, I will fix it.

> > +};
> > +
> > +/*
> > + * A piece of default chip info unless the platform
> > + * supplies it.
> > + */
> > +static const struct mtk_chip_config mtk_default_chip_info = {
> > +       .rx_mlsb = 1,
> > +       .tx_mlsb = 1,
> > +       .tx_endian = 0,
> > +       .rx_endian = 0,
> > +};
> > +

> > +
> > +       trans = list_first_entry(&msg->transfers, struct spi_transfer,
> > +                                transfer_list);
> > +       if (trans->cs_change == 0) {
> 
> !trans->cs_change
> 
OK, I  will fix it.

> > +               mdata->state = MTK_SPI_IDLE;
> > +               mtk_spi_reset(mdata);
> > +       }
> > +
> > +       return ret;
> > +}
> > +
> > +static int mtk_spi_unprepare_hardware(struct spi_master *master)
> > +{
> > +       struct mtk_spi *mdata = spi_master_get_devdata(master);
> > +
> > +       clk_disable_unprepare(mdata->spi_clk);
> > +
> > +       return 0;
> > +}
> 
> In this case, prepare_hardware/unprepare_hardware is redundant with
> pm_runtime (apart from the cs_change check, possibly).
> 
> If PM_RUNTIME is disabled, leave the clock enabled all the time, if
> not enable/disable in pm_runtime functions (as you already do)
> 
> See https://git.kernel.org/cgit/linux/kernel/git/broonie/spi.git/commit/?id=db91841b58f9ad0ecbb81ed0fa496c3a1b67fd63
> "spi/omap100k: Convert to runtime PM" for an example (it's one of the
> last driver that used prepare/unprepare calls, and got converted to
> pm_runtime)
> 
OK, I'll fix it.

> > +static int mtk_spi_prepare_message(struct spi_master *master,
> > +                                  struct spi_message *msg)
> > +{
> > +       u32 reg_val;
> > +       u8 cpha, cpol;
> > +       struct mtk_chip_config *chip_config;
> > +       struct spi_device *spi = msg->spi;
> > +       struct mtk_spi *mdata = spi_master_get_devdata(master);
> > +
> > +       cpha = spi->mode & SPI_CPHA ? 1 : 0;
> > +       cpol = spi->mode & SPI_CPOL ? 1 : 0;
> > +
> > +       reg_val = readl(mdata->base + SPI_CMD_REG);
> > +       reg_val &= ~(SPI_CMD_CPHA | SPI_CMD_CPOL);
> > +       reg_val |= (cpha << SPI_CMD_CPHA_OFFSET);
> > +       reg_val |= (cpol << SPI_CMD_CPOL_OFFSET);
> 
> This can actually be simplified a bit by using
> SPI_CMD_CPHA/SPI_CMD_CPOL instead.
> 
OK, I will fix it.

> > +       writel(reg_val, mdata->base + SPI_CMD_REG);
> > +

> > +
> > +static void mtk_spi_prepare_transfer(struct spi_master *master,
> > +                                    struct spi_transfer *xfer)
> > +{
> > +       u32 spi_clk_hz, div, high_time, low_time, holdtime,
> > +           setuptime, cs_idletime, reg_val = 0;
> > +       struct mtk_spi *mdata = spi_master_get_devdata(master);
> > +
> > +       spi_clk_hz = clk_get_rate(mdata->spi_clk);
> > +       if (xfer->speed_hz < spi_clk_hz / 2)
> > +               div = DIV_ROUND_UP(spi_clk_hz, xfer->speed_hz);
> > +       else
> > +               div = 1;
> > +
> > +       high_time = (div + 1) / 2;
> > +       low_time = (div + 1) / 2;
> > +       holdtime = (div + 1) / 2 * 2;
> > +       setuptime = (div + 1) / 2 * 2;
> > +       cs_idletime = (div + 1) / 2 * 2;
> 
> Why setting variables with the exact same value? Can you do with just 2?
> 
OK, I'll fix it.

> > +       reg_val |= (((high_time - 1) & 0xff) << SPI_CFG0_SCK_HIGH_OFFSET);
> > +       reg_val |= (((low_time - 1) & 0xff) << SPI_CFG0_SCK_LOW_OFFSET);
> > +       reg_val |= (((holdtime - 1) & 0xff) << SPI_CFG0_CS_HOLD_OFFSET);
> > +       reg_val |= (((setuptime - 1) & 0xff) << SPI_CFG0_CS_SETUP_OFFSET);
> 
> Not sure of the details, but can you guarantee this will never
> overflow? I.e. can div be larger than 256?
> 
If xfer->speed_hz is too small, maybe div may be larger than 256, but
0xff will mask div here, so I think it doesn't matter.


> > +       writel(reg_val, mdata->base + SPI_CFG0_REG);
> > +
> > +       reg_val = readl(mdata->base + SPI_CFG1_REG);
> > +       reg_val &= ~SPI_CFG1_CS_IDLE_MASK;
> > +       reg_val |= (((cs_idletime - 1) & 0xff) << SPI_CFG1_CS_IDLE_OFFSET);
> > +       writel(reg_val, mdata->base + SPI_CFG1_REG);
> > +}
> > +
> > +static void mtk_spi_setup_packet(struct spi_master *master)
> > +{
> > +       u32 packet_size, packet_loop, reg_val;
> > +       struct mtk_spi *mdata = spi_master_get_devdata(master);
> > +
> > +       packet_size = min_t(unsigned, mdata->xfer_len, MTK_SPI_PACKET_SIZE);
> 
> u32 instead of unsigned.
OK, I will fix it.

> 
> > +       packet_loop = mdata->xfer_len / packet_size;
> > +
> > +       reg_val = readl(mdata->base + SPI_CFG1_REG);
> > +       reg_val &= ~(SPI_CFG1_PACKET_LENGTH_MASK + SPI_CFG1_PACKET_LOOP_MASK);
> 
> Use |, not +.
OK, I will fix it.

> 
> > +       reg_val |= (packet_size - 1) << SPI_CFG1_PACKET_LENGTH_OFFSET;
> > +       reg_val |= (packet_loop - 1) << SPI_CFG1_PACKET_LOOP_OFFSET;
> 
> Can packet_loop be >256?
> 
packet_loop can never be >256. If packet_loop=256, the xfer_len will be
256*1024 bytes. It's not possible because packet_loop is from
mdata->xfer_len / packet_size, mdata->xfer_len is from sg_dma_len(). 

> > +       writel(reg_val, mdata->base + SPI_CFG1_REG);
> > +}
> > +
> > +static void mtk_spi_enable_transfer(struct spi_master *master)
> > +{
> > +       int cmd;
> 
> u32
> 
OK. I will fix it.

> > +       struct mtk_spi *mdata = spi_master_get_devdata(master);
> > +
> > +       cmd = readl(mdata->base + SPI_CMD_REG);
> > +       if (mdata->state == MTK_SPI_IDLE)
> > +               cmd |= 1 << SPI_CMD_ACT_OFFSET;
> > +       else
> > +               cmd |= 1 << SPI_CMD_RESUME_OFFSET;
> > +       writel(cmd, mdata->base + SPI_CMD_REG);
> > +}
> > +
> > +static int mtk_spi_get_mult_delta(int xfer_len)
> 
> xfer_len is a u32, so should be mult_delta.
> 
OK, I'll fix it.

> > +{
> > +       int mult_delta;
> > +
> > +       if (xfer_len > MTK_SPI_PACKET_SIZE)
> > +               mult_delta = xfer_len % MTK_SPI_PACKET_SIZE;
> > +       else
> > +               mult_delta = 0;
> > +
> > +       return mult_delta;
> > +}
> > +
> > +static void mtk_spi_update_mdata_len(struct spi_master *master)
> > +{
> > +       int mult_delta;
> > +       struct mtk_spi *mdata = spi_master_get_devdata(master);
> > +
> > +       if (mdata->tx_sgl_len && mdata->rx_sgl_len) {
> > +               if (mdata->tx_sgl_len > mdata->rx_sgl_len) {
> > +                       mult_delta = mtk_spi_get_mult_delta(mdata->rx_sgl_len);
> > +                       mdata->xfer_len = mdata->rx_sgl_len - mult_delta;
> > +                       mdata->rx_sgl_len = mult_delta;
> > +                       mdata->tx_sgl_len -= mdata->xfer_len;
> > +               } else {
> > +                       mult_delta = mtk_spi_get_mult_delta(mdata->tx_sgl_len);
> > +                       mdata->xfer_len = mdata->tx_sgl_len - mult_delta;
> > +                       mdata->tx_sgl_len = mult_delta;
> > +                       mdata->rx_sgl_len -= mdata->xfer_len;
> > +               }
> > +       } else if (mdata->tx_sgl_len) {
> > +               mult_delta = mtk_spi_get_mult_delta(mdata->tx_sgl_len);
> > +               mdata->xfer_len = mdata->tx_sgl_len - mult_delta;
> > +               mdata->tx_sgl_len = mult_delta;
> > +       } else if (mdata->rx_sgl_len) {
> > +               mult_delta = mtk_spi_get_mult_delta(mdata->rx_sgl_len);
> > +               mdata->xfer_len = mdata->rx_sgl_len - mult_delta;
> > +               mdata->rx_sgl_len = mult_delta;
> > +       }
> > +}
> > +
> > +static void mtk_spi_setup_dma_addr(struct spi_master *master,
> > +                                  struct spi_transfer *xfer)
> > +{
> > +       struct mtk_spi *mdata = spi_master_get_devdata(master);
> > +
> > +       if (mdata->tx_sgl)
> > +               writel(cpu_to_le32(xfer->tx_dma), mdata->base + SPI_TX_SRC_REG);
> > +       if (mdata->rx_sgl)
> > +               writel(cpu_to_le32(xfer->rx_dma), mdata->base + SPI_RX_DST_REG);
> > +}
> > +
> > +static int mtk_spi_fifo_transfer(struct spi_master *master,
> > +                                struct spi_device *spi,
> > +                                struct spi_transfer *xfer)
> > +{
> > +       int cnt, i;
> > +       struct mtk_spi *mdata = spi_master_get_devdata(master);
> > +
> > +       mdata->cur_transfer = xfer;
> > +       mdata->xfer_len = xfer->len;
> > +       mtk_spi_prepare_transfer(master, xfer);
> > +       mtk_spi_setup_packet(master);
> > +
> > +       if (xfer->len % 4)
> > +               cnt = xfer->len / 4 + 1;
> > +       else
> > +               cnt = xfer->len / 4;
> > +
> > +       for (i = 0; i < cnt; i++)
> > +               writel(*((u32 *)xfer->tx_buf + i),
> 
> This will access past the end of tx_buf if len%4 > 0.

SPI_TX_DATA_REG requires write 4 bytes once. If len%4 > 0, this just
reads more data from dram(xfer->tx_buf) to register, and that spi hw
only tranfer length according to xfer->len, so I think it doesn't
matter.

> > +                      mdata->base + SPI_TX_DATA_REG);
> > +
> > +       mtk_spi_enable_transfer(master);
> > +
> > +       return 1;
> > +}
> > +
> > +static int mtk_spi_dma_transfer(struct spi_master *master,
> > +                               struct spi_device *spi,
> > +                               struct spi_transfer *xfer)
> > +{
> > +       int cmd;
> > +       struct mtk_spi *mdata = spi_master_get_devdata(master);
> > +
> > +       mdata->tx_sgl = NULL;
> > +       mdata->rx_sgl = NULL;
> > +       mdata->tx_sgl_len = 0;
> > +       mdata->rx_sgl_len = 0;
> > +       mdata->cur_transfer = xfer;
> > +
> > +       mtk_spi_prepare_transfer(master, xfer);
> > +
> > +       cmd = readl(mdata->base + SPI_CMD_REG);
> > +       if (xfer->tx_buf)
> > +               cmd |= SPI_CMD_TX_DMA;
> > +       if (xfer->rx_buf)
> > +               cmd |= SPI_CMD_RX_DMA;
> > +       writel(cmd, mdata->base + SPI_CMD_REG);
> > +
> > +       if (xfer->tx_buf)
> > +               mdata->tx_sgl = xfer->tx_sg.sgl;
> > +       if (xfer->rx_buf)
> > +               mdata->rx_sgl = xfer->rx_sg.sgl;
> > +
> > +       if (mdata->tx_sgl) {
> > +               xfer->tx_dma = sg_dma_address(mdata->tx_sgl);
> > +               mdata->tx_sgl_len = sg_dma_len(mdata->tx_sgl);
> > +       }
> > +       if (mdata->rx_sgl) {
> > +               xfer->rx_dma = sg_dma_address(mdata->rx_sgl);
> > +               mdata->rx_sgl_len = sg_dma_len(mdata->rx_sgl);
> > +       }
> > +
> > +       mtk_spi_update_mdata_len(master);
> > +       mtk_spi_setup_packet(master);
> > +       mtk_spi_setup_dma_addr(master, xfer);
> > +       mtk_spi_enable_transfer(master);
> > +
> > +       return 1;
> > +}
> > +
> > +static int mtk_spi_transfer_one(struct spi_master *master,
> > +                               struct spi_device *spi,
> > +                               struct spi_transfer *xfer)
> > +{
> > +       if (master->can_dma(master, spi, xfer))
> > +               return mtk_spi_dma_transfer(master, spi, xfer);
> > +       else
> > +               return mtk_spi_fifo_transfer(master, spi, xfer);
> > +}
> > +
> > +static bool mtk_spi_can_dma(struct spi_master *master,
> > +                           struct spi_device *spi,
> > +                           struct spi_transfer *xfer)
> > +{
> > +       return xfer->len > MTK_SPI_MAX_FIFO_SIZE;
> > +}
> > +
> > +static irqreturn_t mtk_spi_interrupt(int irq, void *dev_id)
> > +{
> > +       u32 cmd, reg_val, i;
> > +       struct spi_master *master = dev_id;
> > +       struct mtk_spi *mdata = spi_master_get_devdata(master);
> > +       struct spi_transfer *trans = mdata->cur_transfer;
> > +
> > +       reg_val = readl(mdata->base + SPI_STATUS0_REG);
> > +       if (reg_val & 0x2)
> 
> define 0x2?

OK. I will fix it.

> > +               mdata->state = MTK_SPI_PAUSED;
> > +       else
> > +               mdata->state = MTK_SPI_IDLE;
> > +
> > +       if (!master->can_dma(master, master->cur_msg->spi, trans)) {
> > +               /* xfer len is not N*4 bytes every time in a transfer,
> > +                * but SPI_RX_DATA_REG must reads 4 bytes once,
> > +                * so rx buffer byte by byte.
> > +                */
> > +               if (trans->rx_buf) {
> > +                       for (i = 0; i < mdata->xfer_len; i++) {
> > +                               if (i % 4 == 0)
> > +                                       reg_val =
> > +                                       readl(mdata->base + SPI_RX_DATA_REG);
> 
> Strange indentation. Might be better to put readl on the same line,
> and SPI_RX_DATA_REG on the next one.

OK. I will fix it.

> > +                               *((u8 *)(trans->rx_buf + i)) =
> > +                                       (reg_val >> ((i % 4) * 8)) & 0xff;
> 
> This feels a bit awkward... Also, & 0xff is not needed.
> 
OK, I will fix it.

> > +
> > +static int mtk_spi_probe(struct platform_device *pdev)
> > +{
> > +       struct spi_master *master;
> > +       struct mtk_spi *mdata;
> > +       const struct of_device_id *of_id;
> > +       struct resource *res;
> > +       int     irq, ret;
> 
> Space, not tab, between int and irq.
> 
OK. I will fix it.

> > +
> > +       master = spi_alloc_master(&pdev->dev, sizeof(*mdata));
> > +       if (!master) {
> > +               dev_err(&pdev->dev, "failed to alloc spi master\n");





From sricharan at codeaurora.org  Wed Aug 12 23:37:59 2015
From: sricharan at codeaurora.org (Sricharan)
Date: Thu, 13 Aug 2015 12:07:59 +0530
Subject: [PATCH 4/5] iommu/msm: Set cacheability attributes without tex
 remap
In-Reply-To: <20150812145346.GH23540@arm.com>
References: <1439390869-6347-1-git-send-email-sricharan@codeaurora.org>
 <1439390869-6347-5-git-send-email-sricharan@codeaurora.org>
 <20150812145346.GH23540@arm.com>
Message-ID: <000201d0d592$9ce1a740$d6a4f5c0$@codeaurora.org>

Hi Will,

> -----Original Message-----
> From: linux-arm-kernel [mailto:linux-arm-kernel-
> bounces at lists.infradead.org] On Behalf Of Will Deacon
> Sent: Wednesday, August 12, 2015 8:24 PM
> To: Sricharan R
> Cc: devicetree at vger.kernel.org; linux-arm-msm at vger.kernel.org;
> joro at 8bytes.org; robdclark at gmail.com; iommu at lists.linux-foundation.org;
> srinivas.kandagatla at linaro.org; laurent.pinchart at ideasonboard.com;
> treding at nvidia.com; Robin Murphy; linux-arm-kernel at lists.infradead.org;
> stepanm at codeaurora.org
> Subject: Re: [PATCH 4/5] iommu/msm: Set cacheability attributes without
tex
> remap
> 
> On Wed, Aug 12, 2015 at 03:47:48PM +0100, Sricharan R wrote:
> > The cacheablity attributes are set when IOMMU_CACHE property is true.
> > So cachebility is set as either noncached (normal) or cached (normal
> > WBWA) directly and avoid setting using tex remap.
> 
> Does this IOMMU support the ARMv7 short descriptor format? If so, would it
> work with Yong's patch here:
> 
>   http://lists.infradead.org/pipermail/linux-arm-kernel/2015-
> August/361615.html
> 
> I've not gotten around to reviewing the latest version yet, but having
other
> IOMMUs consolidate on one set of page table code would be a good thing.

     Yes, this is ARMv7 short descriptor complaint. I will rebase the next
one the
     above. That should reduce more code in this driver. Thanks.

Regards,
  Sricharan



From mingo at kernel.org  Wed Aug 12 23:50:41 2015
From: mingo at kernel.org (Ingo Molnar)
Date: Thu, 13 Aug 2015 08:50:41 +0200
Subject: [PATCH 0/2] x86/KASAN updates for 4.3
In-Reply-To: <1439444244-26057-1-git-send-email-ryabinin.a.a@gmail.com>
References: <1439444244-26057-1-git-send-email-ryabinin.a.a@gmail.com>
Message-ID: <20150813065040.GA17983@gmail.com>


* Andrey Ryabinin <ryabinin.a.a at gmail.com> wrote:

> These 2 patches taken from v5 'KASAN for arm64' series.
> The only change is updated changelog in second patch.
> 
> I hope this is not too late to queue these for 4.3,
> as this allow us to merge arm64/KASAN patches in v4.4
> through arm64 tree.
> 
> Andrey Ryabinin (2):
>   x86/kasan: define KASAN_SHADOW_OFFSET per architecture
>   x86/kasan, mm: introduce generic kasan_populate_zero_shadow()
> 
>  arch/x86/include/asm/kasan.h |   3 +
>  arch/x86/mm/kasan_init_64.c  | 123 ++--------------------------------
>  include/linux/kasan.h        |  10 ++-
>  mm/kasan/Makefile            |   2 +-
>  mm/kasan/kasan_init.c        | 152 +++++++++++++++++++++++++++++++++++++++++++
>  5 files changed, 170 insertions(+), 120 deletions(-)
>  create mode 100644 mm/kasan/kasan_init.c

It's absolutely too late in the -rc cycle for v4.3!

I can create a stable topic tree for it, tip:mm/kasan or so, which arm64 could 
pull and base its own ARM specific work on, if that's OK with everyone.

Thanks,

	Ingo


From herbert at gondor.apana.org.au  Thu Aug 13 00:16:26 2015
From: herbert at gondor.apana.org.au (Herbert Xu)
Date: Thu, 13 Aug 2015 15:16:26 +0800
Subject: [PATCH 0/3] ARM: sun6i: Support Security System crypto engine
In-Reply-To: <1439271177-26523-1-git-send-email-wens@csie.org>
References: <1439271177-26523-1-git-send-email-wens@csie.org>
Message-ID: <20150813071626.GA21239@gondor.apana.org.au>

On Tue, Aug 11, 2015 at 01:32:54PM +0800, Chen-Yu Tsai wrote:
> Hi everyone,
> 
> This series enables support for the crypto engine found in sun6i, or
> Allwinner A31/A31s SoCs. The crypto engine is the same hardware as on
> earlier sun4i/sun7i (A10/A20), with the only difference being the reset
> control is separated out of the clock gate control.
> 
> The same hardware is also available on the A33, but not the A23. Support
> for this requires additions to the clock driver, and will be submitted
> separately once things are clear on how to proceed. I already have a
> proof of concept working.
> 
> 
> Patch 1 adds an optional reset control property to the sunxi-ss binding.
> 
> Patch 2 adds optional reset control support to the sunxi-ss driver.
> 
> Patch 3 enables the crypto engine on sun6i, by adding the module clock and
> device node.

All applied.  Thanks.
-- 
Email: Herbert Xu <herbert at gondor.apana.org.au>
Home Page: http://gondor.apana.org.au/~herbert/
PGP Key: http://gondor.apana.org.au/~herbert/pubkey.txt


From rsahu at apm.com  Thu Aug 13 00:18:28 2015
From: rsahu at apm.com (Rameshwar Sahu)
Date: Thu, 13 Aug 2015 12:48:28 +0530
Subject: [PATCH] dmaengine: xgene-dma: Add ACPI support for X-Gene DMA
 engine driver
In-Reply-To: <1437484479-2822-1-git-send-email-rsahu@apm.com>
References: <1437484479-2822-1-git-send-email-rsahu@apm.com>
Message-ID: <CAFd313zR468nZN+CZZ+efr9eKoY4N72jQ8+cF=iH+vkZEZ=7Xg@mail.gmail.com>

Hi Vinod,

On Tue, Jul 21, 2015 at 6:44 PM, Rameshwar Prasad Sahu <rsahu at apm.com> wrote:
> This patch adds ACPI support for the APM X-Gene DMA engine driver.
>
> Signed-off-by: Rameshwar Prasad Sahu <rsahu at apm.com>
> ---
>  drivers/dma/xgene-dma.c | 28 +++++++++++++++++++++-------
>  1 file changed, 21 insertions(+), 7 deletions(-)
>
> diff --git a/drivers/dma/xgene-dma.c b/drivers/dma/xgene-dma.c
> index dff22ab..d0a148d 100644
> --- a/drivers/dma/xgene-dma.c
> +++ b/drivers/dma/xgene-dma.c
> @@ -21,6 +21,7 @@
>   * NOTE: PM support is currently not available.
>   */
>
> +#include <linux/acpi.h>
>  #include <linux/clk.h>
>  #include <linux/delay.h>
>  #include <linux/dma-mapping.h>
> @@ -1944,16 +1945,18 @@ static int xgene_dma_probe(struct platform_device *pdev)
>                 return ret;
>
>         pdma->clk = devm_clk_get(&pdev->dev, NULL);
> -       if (IS_ERR(pdma->clk)) {
> +       if (IS_ERR(pdma->clk) && !ACPI_COMPANION(&pdev->dev)) {
>                 dev_err(&pdev->dev, "Failed to get clk\n");
>                 return PTR_ERR(pdma->clk);
>         }
>
>         /* Enable clk before accessing registers */
> -       ret = clk_prepare_enable(pdma->clk);
> -       if (ret) {
> -               dev_err(&pdev->dev, "Failed to enable clk %d\n", ret);
> -               return ret;
> +       if (!IS_ERR(pdma->clk)) {
> +               ret = clk_prepare_enable(pdma->clk);
> +               if (ret) {
> +                       dev_err(&pdev->dev, "Failed to enable clk %d\n", ret);
> +                       return ret;
> +               }
>         }
>
>         /* Remove DMA RAM out of shutdown */
> @@ -1998,7 +2001,8 @@ err_request_irq:
>
>  err_dma_mask:
>  err_clk_enable:
> -       clk_disable_unprepare(pdma->clk);
> +       if (!IS_ERR(pdma->clk))
> +               clk_disable_unprepare(pdma->clk);
>
>         return ret;
>  }
> @@ -2022,11 +2026,20 @@ static int xgene_dma_remove(struct platform_device *pdev)
>                 xgene_dma_delete_chan_rings(chan);
>         }
>
> -       clk_disable_unprepare(pdma->clk);
> +       if (!IS_ERR(pdma->clk))
> +               clk_disable_unprepare(pdma->clk);
>
>         return 0;
>  }
>
> +#ifdef CONFIG_ACPI
> +static const struct acpi_device_id xgene_dma_acpi_match_ptr[] = {
> +       {"APMC0D43", 0},
> +       {},
> +};
> +MODULE_DEVICE_TABLE(acpi, xgene_dma_acpi_match_ptr);
> +#endif
> +
>  static const struct of_device_id xgene_dma_of_match_ptr[] = {
>         {.compatible = "apm,xgene-storm-dma",},
>         {},
> @@ -2039,6 +2052,7 @@ static struct platform_driver xgene_dma_driver = {
>         .driver = {
>                 .name = "X-Gene-DMA",
>                 .of_match_table = xgene_dma_of_match_ptr,
> +               .acpi_match_table = ACPI_PTR(xgene_dma_acpi_match_ptr),
>         },
>  };
>
> --
> 1.8.2.1


Any Comments on the above patch ??


From tony at atomide.com  Thu Aug 13 00:51:05 2015
From: tony at atomide.com (Tony Lindgren)
Date: Thu, 13 Aug 2015 00:51:05 -0700
Subject: [PATCH v2 07/13] memory: kill off set_irq_flags usage
In-Reply-To: <1436711211-18223-8-git-send-email-robh@kernel.org>
References: <1436711211-18223-1-git-send-email-robh@kernel.org>
 <1436711211-18223-8-git-send-email-robh@kernel.org>
Message-ID: <20150813075105.GX4215@atomide.com>

* Rob Herring <robh at kernel.org> [150712 07:29]:
> set_irq_flags is ARM specific with custom flags which have genirq
> equivalents. Convert drivers to use the genirq interfaces directly, so we
> can kill off set_irq_flags. The translation of flags is as follows:
> 
> IRQF_VALID -> !IRQ_NOREQUEST
> IRQF_PROBE -> !IRQ_NOPROBE
> IRQF_NOAUTOEN -> IRQ_NOAUTOEN
> 
> For IRQs managed by an irqdomain, the irqdomain core code handles clearing
> and setting IRQ_NOREQUEST already, so there is no need to do this in
> .map() functions and we can simply remove the set_irq_flags calls. Some
> users also set IRQ_NOPROBE and this has been maintained although it is not
> clear that is really needed. There appears to be a great deal of blind
> copy and paste of this code.

Applying this one into omap-for-v4.3/soc thanks.

Tony


From daniel at ffwll.ch  Thu Aug 13 00:51:41 2015
From: daniel at ffwll.ch (Daniel Vetter)
Date: Thu, 13 Aug 2015 09:51:41 +0200
Subject: [PATCH 3/7] drm/vc4: Add KMS support for Raspberry Pi.
In-Reply-To: <1439427380-2436-4-git-send-email-eric@anholt.net>
References: <1439427380-2436-1-git-send-email-eric@anholt.net>
 <1439427380-2436-4-git-send-email-eric@anholt.net>
Message-ID: <20150813075141.GX17734@phenom.ffwll.local>

On Wed, Aug 12, 2015 at 05:56:16PM -0700, Eric Anholt wrote:
> This is the start of a full VC4 driver.  Right now this just supports
> configuring the display using a pre-existing video mode (because
> changing the pixel clock isn't available yet, and doesn't work when it
> is).  However, this is enough for fbcon and bringing up X using
> xf86-video-modesetting.
> 
> Signed-off-by: Eric Anholt <eric at anholt.net>
> ---
>  drivers/gpu/drm/Kconfig           |   2 +
>  drivers/gpu/drm/Makefile          |   1 +
>  drivers/gpu/drm/vc4/Kconfig       |  14 +
>  drivers/gpu/drm/vc4/Makefile      |  18 ++
>  drivers/gpu/drm/vc4/vc4_bo.c      |  54 ++++
>  drivers/gpu/drm/vc4/vc4_crtc.c    | 583 ++++++++++++++++++++++++++++++++++
>  drivers/gpu/drm/vc4/vc4_debugfs.c |  38 +++
>  drivers/gpu/drm/vc4/vc4_drv.c     | 249 +++++++++++++++
>  drivers/gpu/drm/vc4/vc4_drv.h     | 123 +++++++
>  drivers/gpu/drm/vc4/vc4_hdmi.c    | 651 ++++++++++++++++++++++++++++++++++++++
>  drivers/gpu/drm/vc4/vc4_hvs.c     | 172 ++++++++++
>  drivers/gpu/drm/vc4/vc4_kms.c     |  84 +++++
>  drivers/gpu/drm/vc4/vc4_plane.c   | 320 +++++++++++++++++++
>  drivers/gpu/drm/vc4/vc4_regs.h    | 562 ++++++++++++++++++++++++++++++++
>  14 files changed, 2871 insertions(+)
>  create mode 100644 drivers/gpu/drm/vc4/Kconfig
>  create mode 100644 drivers/gpu/drm/vc4/Makefile
>  create mode 100644 drivers/gpu/drm/vc4/vc4_bo.c
>  create mode 100644 drivers/gpu/drm/vc4/vc4_crtc.c
>  create mode 100644 drivers/gpu/drm/vc4/vc4_debugfs.c
>  create mode 100644 drivers/gpu/drm/vc4/vc4_drv.c
>  create mode 100644 drivers/gpu/drm/vc4/vc4_drv.h
>  create mode 100644 drivers/gpu/drm/vc4/vc4_hdmi.c
>  create mode 100644 drivers/gpu/drm/vc4/vc4_hvs.c
>  create mode 100644 drivers/gpu/drm/vc4/vc4_kms.c
>  create mode 100644 drivers/gpu/drm/vc4/vc4_plane.c
>  create mode 100644 drivers/gpu/drm/vc4/vc4_regs.h

Made a quick pass and found a few things to update to latest drm
developments. Of course didn't look at the hardware details since no clue,
but looks really nice overall.
-Daniel

> 
> diff --git a/drivers/gpu/drm/Kconfig b/drivers/gpu/drm/Kconfig
> index c46ca31..1730a76 100644
> --- a/drivers/gpu/drm/Kconfig
> +++ b/drivers/gpu/drm/Kconfig
> @@ -240,3 +240,5 @@ source "drivers/gpu/drm/sti/Kconfig"
>  source "drivers/gpu/drm/amd/amdkfd/Kconfig"
>  
>  source "drivers/gpu/drm/imx/Kconfig"
> +
> +source "drivers/gpu/drm/vc4/Kconfig"
> diff --git a/drivers/gpu/drm/Makefile b/drivers/gpu/drm/Makefile
> index 5713d05..b991ac5 100644
> --- a/drivers/gpu/drm/Makefile
> +++ b/drivers/gpu/drm/Makefile
> @@ -42,6 +42,7 @@ obj-$(CONFIG_DRM_MGA)	+= mga/
>  obj-$(CONFIG_DRM_I810)	+= i810/
>  obj-$(CONFIG_DRM_I915)  += i915/
>  obj-$(CONFIG_DRM_MGAG200) += mgag200/
> +obj-$(CONFIG_DRM_VC4)  += vc4/
>  obj-$(CONFIG_DRM_CIRRUS_QEMU) += cirrus/
>  obj-$(CONFIG_DRM_SIS)   += sis/
>  obj-$(CONFIG_DRM_SAVAGE)+= savage/
> diff --git a/drivers/gpu/drm/vc4/Kconfig b/drivers/gpu/drm/vc4/Kconfig
> new file mode 100644
> index 0000000..130cc94
> --- /dev/null
> +++ b/drivers/gpu/drm/vc4/Kconfig
> @@ -0,0 +1,14 @@
> +config DRM_VC4
> +	tristate "Broadcom VC4 Graphics"
> +	depends on ARCH_BCM2835
> +	depends on DRM
> +	select DRM_KMS_HELPER
> +	select DRM_KMS_FB_HELPER
> +	select DRM_KMS_CMA_HELPER

drm-misc/linux-next already has Archit's patches to enable/disable fbdev
in the core code, so you don't need to bother about these selects here any
more, it'll no-op out if drm fbdev emulation isn't enabled. Since you're
reusing cma fbdev helpers I don't think there's any need for other changes
because of this.

> +	help
> +	  Choose this option if you have a system that has a Broadcom
> +	  VC4 GPU, such as the Raspberry Pi or other BCM2708/BCM2835.
> +
> +	  This driver requires that "avoid_warnings=2" be present in
> +	  the config.txt for the firmware, to keep it from smashing
> +	  our display setup.
> diff --git a/drivers/gpu/drm/vc4/Makefile b/drivers/gpu/drm/vc4/Makefile
> new file mode 100644
> index 0000000..4aa07ca
> --- /dev/null
> +++ b/drivers/gpu/drm/vc4/Makefile
> @@ -0,0 +1,18 @@
> +ccflags-y := -Iinclude/drm
> +
> +# Please keep these build lists sorted!
> +
> +# core driver code
> +vc4-y := \
> +	vc4_bo.o \
> +	vc4_crtc.o \
> +	vc4_drv.o \
> +	vc4_kms.o \
> +	vc4_hdmi.o \
> +	vc4_hvs.o \
> +	vc4_plane.o \
> +	$()
> +
> +vc4-$(CONFIG_DEBUG_FS) += vc4_debugfs.o
> +
> +obj-$(CONFIG_DRM_VC4)  += vc4.o
> diff --git a/drivers/gpu/drm/vc4/vc4_bo.c b/drivers/gpu/drm/vc4/vc4_bo.c
> new file mode 100644
> index 0000000..fee8cac
> --- /dev/null
> +++ b/drivers/gpu/drm/vc4/vc4_bo.c
> @@ -0,0 +1,54 @@
> +/*
> + *  Copyright ? 2015 Broadcom
> + *
> + * 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.
> + */
> +
> +/* DOC: VC4 GEM BO management support.
> + *
> + * The VC4 GPU architecture (both scanout and rendering) has direct
> + * access to system memory with no MMU in between.  To support it, we
> + * use the GEM CMA helper functions to allocate contiguous ranges of
> + * physical memory for our BOs.
> + */

Since you're doing kerneldoc considered pulling it all into a new vc4
section in the drm docbook template?

> +
> +#include "vc4_drv.h"
> +
> +struct vc4_bo *vc4_bo_create(struct drm_device *dev, size_t size)
> +{
> +	struct drm_gem_cma_object *cma_obj;
> +
> +	cma_obj = drm_gem_cma_create(dev, size);
> +	if (IS_ERR(cma_obj))
> +		return NULL;
> +	else
> +		return to_vc4_bo(&cma_obj->base);
> +}
> +
> +int vc4_dumb_create(struct drm_file *file_priv,
> +		    struct drm_device *dev,
> +		    struct drm_mode_create_dumb *args)
> +{
> +	int min_pitch = DIV_ROUND_UP(args->width * args->bpp, 8);
> +	struct vc4_bo *bo = NULL;
> +	int ret;
> +
> +	if (args->pitch < min_pitch)
> +		args->pitch = min_pitch;
> +
> +	if (args->size < args->pitch * args->height)
> +		args->size = args->pitch * args->height;
> +
> +	mutex_lock(&dev->struct_mutex);
> +	bo = vc4_bo_create(dev, roundup(args->size, PAGE_SIZE));
> +	mutex_unlock(&dev->struct_mutex);

I'm on a struct_mutex crusade (trying to get rid of it in core and allow
drivers to live without it). On a quick look there doesn't seem to be
anything that needs struct_mutex here, so please just remove it. If there
is indeed something vc4-internal you want to protect, please use your own
driver-internal mutex (e.g. for drm_mm or command submission or whatever).

btw the last bit in the drm core for modern drivers that needs
struct_mutex is mmap_offset gem object lookup. I plan to replace that with
kref_get_unless_zero trickery, which would make the core and a lot of
drivers struct_mutex free and so relegate it mostly to a legacy role (and
can be forgotten).

> +	if (!bo)
> +		return -ENOMEM;
> +
> +	ret = drm_gem_handle_create(file_priv, &bo->base.base, &args->handle);
> +	drm_gem_object_unreference_unlocked(&bo->base.base);
> +
> +	return ret;
> +}
> diff --git a/drivers/gpu/drm/vc4/vc4_crtc.c b/drivers/gpu/drm/vc4/vc4_crtc.c
> new file mode 100644
> index 0000000..6f127f0
> --- /dev/null
> +++ b/drivers/gpu/drm/vc4/vc4_crtc.c
> @@ -0,0 +1,583 @@
> +/*
> + * Copyright (C) 2015 Broadcom
> + *
> + * 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.
> + */
> +
> +/**
> + * DOC: VC4 CRTC module
> + *
> + * In VC4, the Pixel Valve is what most closely corresponds to the
> + * DRM's concept of a CRTC.  The PV generates video timings from the
> + * pixel clock and its configuration.
> + *
> + * However, the DRM CRTC also collects the configuration of all the
> + * DRM planes attached to it.  As a result, this file also manages
> + * setup of the VC4 HVS's display elements on the CRTC.
> + */
> +
> +#include "drm_atomic_helper.h"
> +#include "drm_crtc_helper.h"
> +#include "linux/clk.h"
> +#include "linux/component.h"
> +#include "vc4_drv.h"
> +#include "vc4_regs.h"
> +
> +#define CRTC_WRITE(offset, val) writel(val, vc4_crtc->regs + (offset))
> +#define CRTC_READ(offset) readl(vc4_crtc->regs + (offset))
> +
> +#define CRTC_REG(reg) { reg, #reg }
> +static const struct {
> +	u32 reg;
> +	const char *name;
> +} crtc_regs[] = {
> +	CRTC_REG(PV_CONTROL),
> +	CRTC_REG(PV_V_CONTROL),
> +	CRTC_REG(PV_VSYNCD),
> +	CRTC_REG(PV_HORZA),
> +	CRTC_REG(PV_HORZB),
> +	CRTC_REG(PV_VERTA),
> +	CRTC_REG(PV_VERTB),
> +	CRTC_REG(PV_VERTA_EVEN),
> +	CRTC_REG(PV_VERTB_EVEN),
> +	CRTC_REG(PV_INTEN),
> +	CRTC_REG(PV_INTSTAT),
> +	CRTC_REG(PV_STAT),
> +	CRTC_REG(PV_HACT_ACT),
> +};
> +
> +static void vc4_crtc_dump_regs(struct vc4_crtc *vc4_crtc)
> +{
> +	int i;
> +
> +	for (i = 0; i < ARRAY_SIZE(crtc_regs); i++) {
> +		DRM_INFO("0x%04x (%s): 0x%08x\n",
> +			 crtc_regs[i].reg, crtc_regs[i].name,
> +			 CRTC_READ(crtc_regs[i].reg));
> +	}
> +}
> +
> +#ifdef CONFIG_DEBUG_FS
> +int vc4_crtc_debugfs_regs(struct seq_file *m, void *unused)
> +{
> +	struct drm_info_node *node = (struct drm_info_node *) m->private;
> +	struct drm_device *dev = node->minor->dev;
> +	int crtc_index = (uintptr_t)node->info_ent->data;
> +	struct drm_crtc *crtc;
> +	struct vc4_crtc *vc4_crtc;
> +	int i;
> +
> +	i = 0;
> +	list_for_each_entry(crtc, &dev->mode_config.crtc_list, head) {
> +		if (i == crtc_index)
> +			break;
> +		i++;
> +	}
> +	if (!crtc)
> +		return 0;
> +	vc4_crtc = to_vc4_crtc(crtc);
> +
> +	for (i = 0; i < ARRAY_SIZE(crtc_regs); i++) {
> +		seq_printf(m, "%s (0x%04x): 0x%08x\n",
> +			   crtc_regs[i].name, crtc_regs[i].reg,
> +			   CRTC_READ(crtc_regs[i].reg));
> +	}
> +
> +	return 0;
> +}
> +#endif
> +
> +static void vc4_crtc_destroy(struct drm_crtc *crtc)
> +{
> +	drm_crtc_cleanup(crtc);
> +}
> +
> +static bool vc4_crtc_mode_fixup(struct drm_crtc *crtc,
> +				const struct drm_display_mode *mode,
> +				struct drm_display_mode *adjusted_mode)
> +{
> +	return true;
> +}

mode_fixup on crtcs is optional since 840bfe953384a and I just merged a
patch to make it optional for encoders too (when using atomic helpers
which you do). You can remove them both.

> +
> +static u32 vc4_get_fifo_full_level(u32 format)
> +{
> +	static const u32 fifo_len_bytes = 64;
> +	static const u32 hvs_latency_pix = 6;
> +
> +	switch (format) {
> +	case PV_CONTROL_FORMAT_DSIV_16:
> +	case PV_CONTROL_FORMAT_DSIC_16:
> +		return fifo_len_bytes - 2 * hvs_latency_pix;
> +	case PV_CONTROL_FORMAT_DSIV_18:
> +		return fifo_len_bytes - 14;
> +	case PV_CONTROL_FORMAT_24:
> +	case PV_CONTROL_FORMAT_DSIV_24:
> +	default:
> +		return fifo_len_bytes - 3 * hvs_latency_pix;
> +	}
> +}
> +
> +static void vc4_crtc_mode_set_nofb(struct drm_crtc *crtc)
> +{
> +	struct vc4_crtc *vc4_crtc = to_vc4_crtc(crtc);
> +	struct drm_crtc_state *state = crtc->state;
> +	struct drm_display_mode *mode = &state->adjusted_mode;
> +	u32 vactive = (mode->vdisplay >>
> +		       ((mode->flags & DRM_MODE_FLAG_INTERLACE) ? 1 : 0));
> +	u32 format = PV_CONTROL_FORMAT_24;
> +	bool debug_dump_regs = false;
> +
> +	if (debug_dump_regs) {
> +		DRM_INFO("CRTC %d regs before:\n", drm_crtc_index(crtc));
> +		vc4_crtc_dump_regs(vc4_crtc);
> +	}
> +
> +	/* This is where we would set the pixel clock. */
> +
> +	/* Reset the PV fifo. */
> +	CRTC_WRITE(PV_CONTROL, 0);
> +	CRTC_WRITE(PV_CONTROL, PV_CONTROL_FIFO_CLR | PV_CONTROL_EN);
> +	CRTC_WRITE(PV_CONTROL, 0);
> +
> +	CRTC_WRITE(PV_HORZA,
> +		   VC4_SET_FIELD(mode->htotal - mode->hsync_end,
> +				 PV_HORZA_HBP) |
> +		   VC4_SET_FIELD(mode->hsync_end - mode->hsync_start,
> +				 PV_HORZA_HSYNC));
> +	CRTC_WRITE(PV_HORZB,
> +		   VC4_SET_FIELD(mode->hsync_start - mode->hdisplay,
> +				 PV_HORZB_HFP) |
> +		   VC4_SET_FIELD(mode->hdisplay, PV_HORZB_HACTIVE));
> +
> +	CRTC_WRITE(PV_VERTA,
> +		   VC4_SET_FIELD(mode->vtotal - mode->vsync_end,
> +				 PV_VERTA_VBP) |
> +		   VC4_SET_FIELD(mode->vsync_end - mode->vsync_start,
> +				 PV_VERTA_VSYNC));
> +	CRTC_WRITE(PV_VERTB,
> +		   VC4_SET_FIELD(mode->vsync_start - mode->vdisplay,
> +				 PV_VERTB_VFP) |
> +		   VC4_SET_FIELD(vactive, PV_VERTB_VACTIVE));
> +	if (mode->flags & DRM_MODE_FLAG_INTERLACE) {
> +		/* Write PV_VERTA_EVEN/VERTB_EVEN */
> +	}
> +
> +	CRTC_WRITE(PV_HACT_ACT, mode->hdisplay);
> +
> +	CRTC_WRITE(PV_V_CONTROL,
> +		   PV_VCONTROL_CONTINUOUS);
> +
> +	CRTC_WRITE(PV_CONTROL,
> +		   VC4_SET_FIELD(format, PV_CONTROL_FORMAT) |
> +		   VC4_SET_FIELD(vc4_get_fifo_full_level(format),
> +				 PV_CONTROL_FIFO_LEVEL) |
> +		   PV_CONTROL_CLR_AT_START |
> +		   PV_CONTROL_TRIGGER_UNDERFLOW |
> +		   PV_CONTROL_WAIT_HSTART |
> +		   VC4_SET_FIELD(PV_CONTROL_CLK_SELECT_DPI_SMI_HDMI,
> +				 PV_CONTROL_CLK_SELECT) |
> +		   PV_CONTROL_FIFO_CLR |
> +		   PV_CONTROL_EN);
> +
> +	if (debug_dump_regs) {
> +		DRM_INFO("CRTC %d regs after:\n", drm_crtc_index(crtc));
> +		vc4_crtc_dump_regs(vc4_crtc);
> +	}
> +}
> +
> +static void
> +require_hvs_enabled(struct drm_device *dev)
> +{
> +	struct vc4_dev *vc4 = to_vc4_dev(dev);
> +
> +	WARN_ON_ONCE((HVS_READ(SCALER_DISPCTRL) & SCALER_DISPCTRL_ENABLE) !=
> +		     SCALER_DISPCTRL_ENABLE);
> +}
> +
> +static void vc4_crtc_disable(struct drm_crtc *crtc)
> +{
> +	struct drm_device *dev = crtc->dev;
> +	struct vc4_dev *vc4 = to_vc4_dev(dev);
> +	struct vc4_crtc *vc4_crtc = to_vc4_crtc(crtc);
> +
> +	require_hvs_enabled(dev);
> +
> +	CRTC_WRITE(PV_V_CONTROL,
> +		   CRTC_READ(PV_V_CONTROL) & ~PV_VCONTROL_VIDEN);
> +	while (CRTC_READ(PV_V_CONTROL) & PV_VCONTROL_VIDEN)
> +		cpu_relax();
> +
> +	/* Without a wait here, we end up with a black screen. */
> +	msleep(30);
> +
> +	if (HVS_READ(SCALER_DISPCTRLX(vc4_crtc->channel)) &
> +	    SCALER_DISPCTRLX_ENABLE) {
> +		HVS_WRITE(SCALER_DISPCTRLX(vc4_crtc->channel),
> +			  SCALER_DISPCTRLX_RESET);
> +
> +		/* While the docs say that reset is self-clearing, it
> +		 * seems it doesn't actually.
> +		 */
> +		HVS_WRITE(SCALER_DISPCTRLX(vc4_crtc->channel), 0);
> +	}
> +
> +	/* Once we leave, the scaler should be disabled and its fifo empty. */
> +
> +	WARN_ON_ONCE(HVS_READ(SCALER_DISPCTRLX(vc4_crtc->channel)) &
> +		     SCALER_DISPCTRLX_RESET);
> +
> +	WARN_ON_ONCE(VC4_GET_FIELD(HVS_READ(SCALER_DISPSTATX(vc4_crtc->channel)),
> +				   SCALER_DISPSTATX_MODE) !=
> +		     SCALER_DISPSTATX_MODE_DISABLED);
> +
> +	WARN_ON_ONCE((HVS_READ(SCALER_DISPSTATX(vc4_crtc->channel)) &
> +		      (SCALER_DISPSTATX_FULL | SCALER_DISPSTATX_EMPTY)) !=
> +		     SCALER_DISPSTATX_EMPTY);
> +}
> +
> +static void vc4_crtc_enable(struct drm_crtc *crtc)
> +{
> +	struct drm_device *dev = crtc->dev;
> +	struct vc4_dev *vc4 = to_vc4_dev(dev);
> +	struct vc4_crtc *vc4_crtc = to_vc4_crtc(crtc);
> +	struct drm_crtc_state *state = crtc->state;
> +	struct drm_display_mode *mode = &state->adjusted_mode;
> +
> +	require_hvs_enabled(dev);
> +
> +	/* Turn on the scaler, which will wait for vstart to start
> +	 * compositing.
> +	 */
> +	HVS_WRITE(SCALER_DISPCTRLX(vc4_crtc->channel),
> +		  VC4_SET_FIELD(mode->hdisplay, SCALER_DISPCTRLX_WIDTH) |
> +		  VC4_SET_FIELD(mode->vdisplay, SCALER_DISPCTRLX_HEIGHT) |
> +		  SCALER_DISPCTRLX_ENABLE);
> +
> +	/* Turn on the pixel valve, which will emit the vstart signal. */
> +	CRTC_WRITE(PV_V_CONTROL,
> +		   CRTC_READ(PV_V_CONTROL) | PV_VCONTROL_VIDEN);
> +}
> +
> +static int vc4_crtc_atomic_check(struct drm_crtc *crtc,
> +				 struct drm_crtc_state *state)
> +{
> +	struct drm_device *dev = crtc->dev;
> +	struct vc4_dev *vc4 = to_vc4_dev(dev);
> +	struct drm_plane *plane;
> +	struct vc4_crtc *vc4_crtc = to_vc4_crtc(crtc);
> +	u32 dlist_count = 0;
> +
> +	drm_atomic_crtc_state_for_each_plane(plane, state) {
> +		struct drm_plane_state *plane_state =
> +			state->state->plane_states[drm_plane_index(plane)];
> +
> +		/* plane might not have changed, in which case take
> +		 * current state:
> +		 */
> +		if (!plane_state)
> +			plane_state = plane->state;
> +
> +		dlist_count += vc4_plane_dlist_size(plane_state);
> +	}
> +
> +	dlist_count++; /* Account for SCALER_CTL0_END. */
> +
> +	if (!vc4_crtc->dlist || dlist_count > vc4_crtc->dlist_size) {
> +		vc4_crtc->dlist = ((u32 __iomem *)vc4->hvs->dlist +
> +				   HVS_BOOTLOADER_DLIST_END);
> +		vc4_crtc->dlist_size = ((SCALER_DLIST_SIZE >> 2) -
> +					HVS_BOOTLOADER_DLIST_END);
> +
> +		if (dlist_count > vc4_crtc->dlist_size) {
> +			DRM_DEBUG_KMS("dlist too large for CRTC (%d > %d).\n",
> +				      dlist_count, vc4_crtc->dlist_size);
> +			return -EINVAL;
> +		}
> +	}
> +
> +	return 0;
> +}
> +
> +static void vc4_crtc_atomic_begin(struct drm_crtc *crtc)
> +{
> +}
> +
> +static void vc4_crtc_atomic_flush(struct drm_crtc *crtc)
> +{
> +	struct drm_device *dev = crtc->dev;
> +	struct vc4_dev *vc4 = to_vc4_dev(dev);
> +	struct vc4_crtc *vc4_crtc = to_vc4_crtc(crtc);
> +	struct drm_plane *plane;
> +	bool debug_dump_regs = false;
> +	u32 __iomem *dlist_next = vc4_crtc->dlist;
> +
> +	if (debug_dump_regs) {
> +		DRM_INFO("CRTC %d HVS before:\n", drm_crtc_index(crtc));
> +		vc4_hvs_dump_state(dev);
> +	}
> +
> +	/* Copy all the active planes' dlist contents to the hardware dlist.
> +	 *
> +	 * XXX: If the new display list was large enough that it
> +	 * overlapped a currently-read display list, we need to do
> +	 * something like disable scanout before putting in the new
> +	 * list.  For now, we're safe because we only have the two
> +	 * planes.
> +	 */
> +	drm_atomic_crtc_for_each_plane(plane, crtc) {
> +		dlist_next += vc4_plane_write_dlist(plane, dlist_next);
> +	}
> +
> +	if (dlist_next == vc4_crtc->dlist) {
> +		/* If no planes were enabled, use the SCALER_CTL0_END
> +		 * at the start of the display list memory (in the
> +		 * bootloader section).  We'll rewrite that
> +		 * SCALER_CTL0_END, just in case, though.
> +		 */
> +		writel(SCALER_CTL0_END, vc4->hvs->dlist);
> +		HVS_WRITE(SCALER_DISPLISTX(vc4_crtc->channel), 0);
> +	} else {
> +		writel(SCALER_CTL0_END, dlist_next);
> +		dlist_next++;
> +
> +		HVS_WRITE(SCALER_DISPLISTX(vc4_crtc->channel),
> +			  (u32 *)vc4_crtc->dlist - (u32 *)vc4->hvs->dlist);
> +
> +		/* Make the next display list start after ours. */
> +		vc4_crtc->dlist_size -= (dlist_next - vc4_crtc->dlist);
> +		vc4_crtc->dlist = dlist_next;
> +	}
> +
> +	if (debug_dump_regs) {
> +		DRM_INFO("CRTC %d HVS after:\n", drm_crtc_index(crtc));
> +		vc4_hvs_dump_state(dev);
> +	}
> +
> +	if (crtc->state->event) {
> +		unsigned long flags;
> +
> +		crtc->state->event->pipe = drm_crtc_index(crtc);
> +
> +		WARN_ON(drm_crtc_vblank_get(crtc) != 0);
> +
> +		spin_lock_irqsave(&dev->event_lock, flags);
> +		vc4_crtc->event = crtc->state->event;
> +		spin_unlock_irqrestore(&dev->event_lock, flags);
> +		crtc->state->event = NULL;
> +	}
> +}
> +
> +int vc4_enable_vblank(struct drm_device *dev, int crtc_id)
> +{
> +	struct vc4_dev *vc4 = to_vc4_dev(dev);
> +	struct vc4_crtc *vc4_crtc = vc4->crtc[crtc_id];
> +
> +	CRTC_WRITE(PV_INTEN, PV_INT_VFP_START);
> +
> +	return 0;
> +}
> +
> +void vc4_disable_vblank(struct drm_device *dev, int crtc_id)
> +{
> +	struct vc4_dev *vc4 = to_vc4_dev(dev);
> +	struct vc4_crtc *vc4_crtc = vc4->crtc[crtc_id];
> +
> +	CRTC_WRITE(PV_INTEN, 0);
> +}
> +
> +static void
> +vc4_crtc_handle_page_flip(struct vc4_crtc *vc4_crtc)
> +{
> +	struct drm_crtc *crtc = &vc4_crtc->base;
> +	struct drm_device *dev = crtc->dev;
> +	unsigned long flags;
> +
> +	spin_lock_irqsave(&dev->event_lock, flags);
> +	if (vc4_crtc->event) {
> +		drm_crtc_send_vblank_event(crtc, vc4_crtc->event);
> +		vc4_crtc->event = NULL;
> +	}
> +	spin_unlock_irqrestore(&dev->event_lock, flags);
> +}
> +
> +static irqreturn_t vc4_crtc_irq_handler(int irq, void *data)
> +{
> +	struct vc4_crtc *vc4_crtc = data;
> +	u32 stat = CRTC_READ(PV_INTSTAT);
> +	irqreturn_t ret = IRQ_NONE;
> +
> +	if (stat & PV_INT_VFP_START) {
> +		CRTC_WRITE(PV_INTSTAT, PV_INT_VFP_START);
> +		drm_crtc_handle_vblank(&vc4_crtc->base);
> +		vc4_crtc_handle_page_flip(vc4_crtc);
> +		ret = IRQ_HANDLED;
> +	}
> +
> +	return ret;
> +}
> +
> +static const struct drm_crtc_funcs vc4_crtc_funcs = {
> +	.set_config = drm_atomic_helper_set_config,
> +	.destroy = vc4_crtc_destroy,
> +	.page_flip = drm_atomic_helper_page_flip,
> +	.set_property = NULL,
> +	.cursor_set = NULL, /* handled by drm_mode_cursor_universal */
> +	.cursor_move = NULL, /* handled by drm_mode_cursor_universal */
> +	.reset = drm_atomic_helper_crtc_reset,
> +	.atomic_duplicate_state = drm_atomic_helper_crtc_duplicate_state,
> +	.atomic_destroy_state = drm_atomic_helper_crtc_destroy_state,
> +};
> +
> +static const struct drm_crtc_helper_funcs vc4_crtc_helper_funcs = {
> +	.mode_fixup = vc4_crtc_mode_fixup,
> +	.mode_set_nofb = vc4_crtc_mode_set_nofb,
> +	.disable = vc4_crtc_disable,
> +	.enable = vc4_crtc_enable,
> +	.atomic_check = vc4_crtc_atomic_check,
> +	.atomic_begin = vc4_crtc_atomic_begin,
> +	.atomic_flush = vc4_crtc_atomic_flush,
> +};
> +
> +/* Frees the page flip event when the DRM device is closed with the
> + * event still outstanding.
> + */
> +void vc4_cancel_page_flip(struct drm_crtc *crtc, struct drm_file *file)
> +{
> +	struct vc4_crtc *vc4_crtc = to_vc4_crtc(crtc);
> +	struct drm_device *dev = crtc->dev;
> +	unsigned long flags;
> +
> +	spin_lock_irqsave(&dev->event_lock, flags);
> +
> +	if (vc4_crtc->event && vc4_crtc->event->base.file_priv == file) {
> +		vc4_crtc->event->base.destroy(&vc4_crtc->event->base);
> +		drm_crtc_vblank_put(crtc);
> +		vc4_crtc->event = NULL;
> +	}
> +
> +	spin_unlock_irqrestore(&dev->event_lock, flags);
> +}
> +
> +static int vc4_crtc_bind(struct device *dev, struct device *master, void *data)
> +{
> +	struct platform_device *pdev = to_platform_device(dev);
> +	struct drm_device *drm = dev_get_drvdata(master);
> +	struct vc4_dev *vc4 = to_vc4_dev(drm);
> +	struct vc4_crtc *vc4_crtc;
> +	struct drm_crtc *crtc;
> +	struct drm_plane *primary_plane, *cursor_plane;
> +	int ret;
> +
> +	primary_plane = vc4_plane_init(drm, DRM_PLANE_TYPE_PRIMARY);
> +	if (!primary_plane) {
> +		dev_err(dev, "failed to construct primary plane\n");
> +		ret = PTR_ERR(primary_plane);
> +		goto fail;
> +	}
> +
> +	cursor_plane = vc4_plane_init(drm, DRM_PLANE_TYPE_CURSOR);
> +	if (!cursor_plane) {
> +		dev_err(dev, "failed to construct cursor plane\n");
> +		ret = PTR_ERR(cursor_plane);
> +		goto fail;
> +	}
> +
> +	vc4_crtc = devm_kzalloc(dev, sizeof(*vc4_crtc), GFP_KERNEL);
> +	if (!vc4_crtc)
> +		return -ENOMEM;
> +	crtc = &vc4_crtc->base;
> +
> +	vc4_crtc->regs = vc4_ioremap_regs(pdev, 0);
> +	if (IS_ERR(vc4_crtc->regs))
> +		return PTR_ERR(vc4_crtc->regs);
> +
> +	drm_crtc_init_with_planes(drm, crtc, primary_plane, cursor_plane,
> +				  &vc4_crtc_funcs);
> +	drm_crtc_helper_add(crtc, &vc4_crtc_helper_funcs);
> +	primary_plane->crtc = crtc;
> +	cursor_plane->crtc = crtc;
> +	vc4->crtc[drm_crtc_index(crtc)] = vc4_crtc;
> +
> +	/* Until we have full scanout setup to route things through to
> +	 * encoders, line things up like the firmware did.
> +	 */
> +	switch (drm_crtc_index(crtc)) {
> +	case 0:
> +		vc4_crtc->channel = 0;
> +		break;
> +	case 1:
> +		vc4_crtc->channel = 2;
> +		break;
> +	default:
> +	case 2:
> +		vc4_crtc->channel = 1;
> +		break;
> +	}
> +
> +	CRTC_WRITE(PV_INTEN, 0);
> +	CRTC_WRITE(PV_INTSTAT, PV_INT_VFP_START);
> +	ret = devm_request_irq(dev, platform_get_irq(pdev, 0),
> +			       vc4_crtc_irq_handler, 0, "vc4 crtc", vc4_crtc);
> +
> +	platform_set_drvdata(pdev, vc4_crtc);
> +
> +	return 0;
> +
> +fail:
> +	return ret;
> +}
> +
> +static void vc4_crtc_unbind(struct device *dev, struct device *master,
> +			    void *data)
> +{
> +	struct platform_device *pdev = to_platform_device(dev);
> +	struct vc4_crtc *vc4_crtc = dev_get_drvdata(dev);
> +
> +	vc4_crtc_destroy(&vc4_crtc->base);
> +
> +	CRTC_WRITE(PV_INTEN, 0);
> +
> +	platform_set_drvdata(pdev, NULL);
> +}
> +
> +static const struct component_ops vc4_crtc_ops = {
> +	.bind   = vc4_crtc_bind,
> +	.unbind = vc4_crtc_unbind,
> +};
> +
> +static int vc4_crtc_dev_probe(struct platform_device *pdev)
> +{
> +	return component_add(&pdev->dev, &vc4_crtc_ops);
> +}
> +
> +static int vc4_crtc_dev_remove(struct platform_device *pdev)
> +{
> +	component_del(&pdev->dev, &vc4_crtc_ops);
> +	return 0;
> +}
> +
> +static const struct of_device_id vc4_crtc_dt_match[] = {
> +	{ .compatible = "brcm,vc4-pixelvalve" },
> +	{}
> +};
> +
> +static struct platform_driver vc4_crtc_driver = {
> +	.probe = vc4_crtc_dev_probe,
> +	.remove = vc4_crtc_dev_remove,
> +	.driver = {
> +		.name = "vc4_crtc",
> +		.of_match_table = vc4_crtc_dt_match,
> +	},
> +};
> +
> +void __init vc4_crtc_register(void)
> +{
> +	platform_driver_register(&vc4_crtc_driver);
> +}
> +
> +void __exit vc4_crtc_unregister(void)
> +{
> +	platform_driver_unregister(&vc4_crtc_driver);
> +}
> diff --git a/drivers/gpu/drm/vc4/vc4_debugfs.c b/drivers/gpu/drm/vc4/vc4_debugfs.c
> new file mode 100644
> index 0000000..c557039
> --- /dev/null
> +++ b/drivers/gpu/drm/vc4/vc4_debugfs.c
> @@ -0,0 +1,38 @@
> +/*
> + *  Copyright ? 2014 Broadcom
> + *
> + * This program is free software; you can redistribute it and/or modify
> + * it under the terms of the GNU General Public License version 2 as
> + * published by the Free Software Foundation.
> + */
> +
> +#include <linux/seq_file.h>
> +#include <linux/circ_buf.h>
> +#include <linux/ctype.h>
> +#include <linux/debugfs.h>
> +#include <drm/drmP.h>
> +
> +#include "vc4_drv.h"
> +#include "vc4_regs.h"
> +
> +static const struct drm_info_list vc4_debugfs_list[] = {
> +	{"hdmi_regs", vc4_hdmi_debugfs_regs, 0},
> +	{"hvs_regs", vc4_hvs_debugfs_regs, 0},
> +	{"crtc0_regs", vc4_crtc_debugfs_regs, 0, (void *)(uintptr_t)0},
> +	{"crtc1_regs", vc4_crtc_debugfs_regs, 0, (void *)(uintptr_t)1},
> +	{"crtc2_regs", vc4_crtc_debugfs_regs, 0, (void *)(uintptr_t)2},
> +};
> +#define VC4_DEBUGFS_ENTRIES ARRAY_SIZE(vc4_debugfs_list)
> +
> +int
> +vc4_debugfs_init(struct drm_minor *minor)
> +{
> +	return drm_debugfs_create_files(vc4_debugfs_list, VC4_DEBUGFS_ENTRIES,
> +					minor->debugfs_root, minor);
> +}
> +
> +void
> +vc4_debugfs_cleanup(struct drm_minor *minor)
> +{
> +	drm_debugfs_remove_files(vc4_debugfs_list, VC4_DEBUGFS_ENTRIES, minor);
> +}
> diff --git a/drivers/gpu/drm/vc4/vc4_drv.c b/drivers/gpu/drm/vc4/vc4_drv.c
> new file mode 100644
> index 0000000..9ecf4b8b
> --- /dev/null
> +++ b/drivers/gpu/drm/vc4/vc4_drv.c
> @@ -0,0 +1,249 @@
> +/*
> + * Copyright (C) 2014-2015 Broadcom
> + * Copyright (C) 2013 Red Hat
> + *
> + * This program is free software; you can redistribute it and/or modify
> + * it under the terms of the GNU General Public License version 2 as
> + * published by the Free Software Foundation.
> + */
> +
> +#include <linux/clk.h>
> +#include <linux/component.h>
> +#include <linux/device.h>
> +#include <linux/io.h>
> +#include <linux/module.h>
> +#include <linux/of_platform.h>
> +#include <linux/platform_device.h>
> +
> +#include "vc4_drv.h"
> +#include "vc4_regs.h"
> +
> +#define DRIVER_NAME "vc4"
> +#define DRIVER_DESC "Broadcom VC4 graphics"
> +#define DRIVER_DATE "20140616"
> +#define DRIVER_MAJOR 0
> +#define DRIVER_MINOR 0
> +#define DRIVER_PATCHLEVEL 0
> +
> +/* Helper function for mapping the regs on a platform device.
> + *
> + * We assume only one register range per device, so we use index 0.
> + */
> +void __iomem *vc4_ioremap_regs(struct platform_device *dev, int index)
> +{
> +	struct resource *res;
> +	void __iomem *map;
> +
> +	res = platform_get_resource(dev, IORESOURCE_MEM, index);
> +	map = devm_ioremap_resource(&dev->dev, res);
> +	if (IS_ERR(map)) {
> +		DRM_ERROR("Failed to map registers: %ld\n", PTR_ERR(map));
> +		return map;
> +	}
> +
> +	return map;
> +}
> +
> +static int vc4_drm_load(struct drm_device *dev, unsigned long flags)
> +{
> +	struct vc4_dev *vc4;
> +	int ret;
> +
> +	vc4 = devm_kzalloc(dev->dev, sizeof(*vc4), GFP_KERNEL);
> +	if (!vc4)
> +		return -ENOMEM;
> +
> +	dev_set_drvdata(dev->dev, dev);
> +	vc4->dev = dev;
> +	dev->dev_private = vc4;
> +
> +	drm_mode_config_init(dev);
> +
> +	ret = component_bind_all(dev->dev, dev);
> +	if (ret)
> +		return ret;
> +
> +	vc4_kms_load(dev);
> +
> +	return 0;
> +}

->load has backwards init ordering (we register public interfaces before
calling it, yay) because backwards compat. Hence deprecated, please use
drm_dev_alloc(); ... driver init including drm_dev_set_unique();
drm_dev_register(); instead and drop ->load.

> +
> +static int vc4_drm_unload(struct drm_device *dev)
> +{
> +	drm_mode_config_cleanup(dev);
> +
> +	component_unbind_all(dev->dev, dev);
> +
> +	return 0;
> +}
> +
> +static void vc4_drm_preclose(struct drm_device *dev, struct drm_file *file)
> +{
> +	struct drm_crtc *crtc;
> +
> +	list_for_each_entry(crtc, &dev->mode_config.crtc_list, head)
> +		vc4_cancel_page_flip(crtc, file);
> +}
> +
> +static const struct file_operations vc4_drm_fops = {
> +	.owner = THIS_MODULE,
> +	.open = drm_open,
> +	.release = drm_release,
> +	.unlocked_ioctl = drm_ioctl,
> +	.mmap = drm_gem_cma_mmap,
> +	.poll = drm_poll,
> +	.read = drm_read,
> +#ifdef CONFIG_COMPAT
> +	.compat_ioctl = drm_compat_ioctl,
> +#endif
> +	.llseek = noop_llseek,
> +};
> +
> +static const struct drm_ioctl_desc vc4_drm_ioctls[] = {
> +};
> +
> +static struct drm_driver vc4_drm_driver = {
> +	.driver_features = (DRIVER_MODESET |
> +			    DRIVER_ATOMIC |
> +			    DRIVER_GEM |
> +			    DRIVER_PRIME),
> +	.load = vc4_drm_load,
> +	.unload = vc4_drm_unload,
> +	.set_busid = drm_platform_set_busid,

with ->load dropp and set_unique called directly you can drop this one
too. tegra is a nice example for the new sequence.

> +	.preclose = vc4_drm_preclose,
> +
> +	.enable_vblank = vc4_enable_vblank,
> +	.disable_vblank = vc4_disable_vblank,
> +	.get_vblank_counter = drm_vblank_count,
> +
> +#if defined(CONFIG_DEBUG_FS)
> +	.debugfs_init = vc4_debugfs_init,
> +	.debugfs_cleanup = vc4_debugfs_cleanup,
> +#endif
> +
> +	.gem_free_object = drm_gem_cma_free_object,
> +	.gem_vm_ops = &drm_gem_cma_vm_ops,
> +
> +	.prime_handle_to_fd = drm_gem_prime_handle_to_fd,
> +	.prime_fd_to_handle = drm_gem_prime_fd_to_handle,
> +	.gem_prime_import = drm_gem_prime_import,
> +	.gem_prime_export = drm_gem_prime_export,
> +	.gem_prime_get_sg_table	= drm_gem_cma_prime_get_sg_table,
> +	.gem_prime_import_sg_table = drm_gem_cma_prime_import_sg_table,
> +	.gem_prime_vmap		= drm_gem_cma_prime_vmap,
> +	.gem_prime_vunmap	= drm_gem_cma_prime_vunmap,
> +	.gem_prime_mmap		= drm_gem_cma_prime_mmap,
> +
> +	.dumb_create = vc4_dumb_create,
> +	.dumb_map_offset = drm_gem_cma_dumb_map_offset,
> +	.dumb_destroy = drm_gem_dumb_destroy,
> +
> +	.ioctls = vc4_drm_ioctls,
> +	.num_ioctls = ARRAY_SIZE(vc4_drm_ioctls),
> +	.fops = &vc4_drm_fops,
> +
> +	.name = DRIVER_NAME,
> +	.desc = DRIVER_DESC,
> +	.date = DRIVER_DATE,
> +	.major = DRIVER_MAJOR,
> +	.minor = DRIVER_MINOR,
> +	.patchlevel = DRIVER_PATCHLEVEL,
> +};
> +
> +static int vc4_drm_bind(struct device *dev)
> +{
> +	return drm_platform_init(&vc4_drm_driver, to_platform_device(dev));
> +}
> +
> +static void vc4_drm_unbind(struct device *dev)
> +{
> +	drm_put_dev(platform_get_drvdata(to_platform_device(dev)));
> +}
> +
> +static const struct component_master_ops vc4_drm_ops = {
> +	.bind = vc4_drm_bind,
> +	.unbind = vc4_drm_unbind,
> +};
> +
> +static int compare_of(struct device *dev, void *data)
> +{
> +	return dev->of_node == data;
> +}
> +
> +static int add_components(struct device *dev, struct component_match **matchptr,
> +			  const char *name)
> +{
> +	struct device_node *np = dev->of_node;
> +	unsigned i;
> +
> +	for (i = 0; ; i++) {
> +		struct device_node *node;
> +
> +		node = of_parse_phandle(np, name, i);
> +		if (!node)
> +			break;
> +
> +		component_match_add(dev, matchptr, compare_of, node);
> +	}
> +
> +	return 0;
> +}
> +
> +static int vc4_platform_drm_probe(struct platform_device *pdev)
> +{
> +	struct component_match *match = NULL;
> +
> +	add_components(&pdev->dev, &match, "crtcs");
> +	add_components(&pdev->dev, &match, "encoders");
> +	add_components(&pdev->dev, &match, "hvss");
> +
> +	pdev->dev.coherent_dma_mask = DMA_BIT_MASK(32);
> +	return component_master_add_with_match(&pdev->dev, &vc4_drm_ops, match);
> +}
> +
> +static int vc4_platform_drm_remove(struct platform_device *pdev)
> +{
> +	drm_put_dev(platform_get_drvdata(pdev));
> +
> +	return 0;
> +}
> +
> +static const struct of_device_id vc4_of_match[] = {
> +	{ .compatible = "brcm,vc4", },
> +	{},
> +};
> +MODULE_DEVICE_TABLE(of, vc4_of_match);
> +
> +static struct platform_driver vc4_platform_driver = {
> +	.probe		= vc4_platform_drm_probe,
> +	.remove		= vc4_platform_drm_remove,
> +	.driver		= {
> +		.name	= "vc4-drm",
> +		.owner	= THIS_MODULE,
> +		.of_match_table = vc4_of_match,
> +	},
> +};
> +
> +static int __init vc4_drm_register(void)
> +{
> +	vc4_hdmi_register();
> +	vc4_crtc_register();
> +	vc4_hvs_register();
> +	return platform_driver_register(&vc4_platform_driver);
> +}
> +
> +static void __exit vc4_drm_unregister(void)
> +{
> +	platform_driver_unregister(&vc4_platform_driver);
> +	vc4_hvs_unregister();
> +	vc4_crtc_unregister();
> +	vc4_hdmi_unregister();
> +}
> +
> +module_init(vc4_drm_register);
> +module_exit(vc4_drm_unregister);
> +
> +MODULE_ALIAS("platform:vc4-drm");
> +MODULE_DESCRIPTION("Broadcom VC4 DRM Driver");
> +MODULE_AUTHOR("Eric Anholt <eric at anholt.net>");
> +MODULE_LICENSE("GPL v2");
> diff --git a/drivers/gpu/drm/vc4/vc4_drv.h b/drivers/gpu/drm/vc4/vc4_drv.h
> new file mode 100644
> index 0000000..1b0a0b0
> --- /dev/null
> +++ b/drivers/gpu/drm/vc4/vc4_drv.h
> @@ -0,0 +1,123 @@
> +/*
> + * Copyright (C) 2015 Broadcom
> + *
> + * This program is free software; you can redistribute it and/or modify
> + * it under the terms of the GNU General Public License version 2 as
> + * published by the Free Software Foundation.
> + */
> +
> +#include "drmP.h"
> +#include "drm_gem_cma_helper.h"
> +
> +struct vc4_dev {
> +	struct drm_device *dev;
> +
> +	struct vc4_hdmi *hdmi;
> +	struct vc4_hvs *hvs;
> +	struct vc4_crtc *crtc[3];
> +};
> +
> +static inline struct vc4_dev *
> +to_vc4_dev(struct drm_device *dev)
> +{
> +	return (struct vc4_dev *)dev->dev_private;
> +}
> +
> +struct vc4_bo {
> +	struct drm_gem_cma_object base;
> +};
> +
> +static inline struct vc4_bo *
> +to_vc4_bo(struct drm_gem_object *bo)
> +{
> +	return (struct vc4_bo *)bo;
> +}
> +
> +struct vc4_hvs {
> +	struct platform_device *pdev;
> +	void __iomem *regs;
> +	void __iomem *dlist;
> +};
> +
> +struct vc4_crtc {
> +	struct drm_crtc base;
> +	void __iomem *regs;
> +
> +	/* Which HVS channel we're using for our CRTC. */
> +	int channel;
> +
> +	/* Pointer to the actual hardware display list memory for the
> +	 * crtc.
> +	 */
> +	u32 __iomem *dlist;
> +
> +	u32 dlist_size; /* in dwords */
> +
> +	struct drm_pending_vblank_event *event;
> +};
> +
> +static inline struct vc4_crtc *
> +to_vc4_crtc(struct drm_crtc *crtc)
> +{
> +	return (struct vc4_crtc *)crtc;
> +}
> +
> +struct vc4_plane {
> +	struct drm_plane base;
> +};
> +
> +static inline struct vc4_plane *
> +to_vc4_plane(struct drm_plane *plane)
> +{
> +	return (struct vc4_plane *)plane;
> +}
> +
> +#define HVS_READ(offset) readl(vc4->hvs->regs + offset)
> +#define HVS_WRITE(offset, val) writel(val, vc4->hvs->regs + offset)
> +
> +/* vc4_bo.c */
> +void vc4_free_object(struct drm_gem_object *gem_obj);
> +struct vc4_bo *vc4_bo_create(struct drm_device *dev, size_t size);
> +int vc4_dumb_create(struct drm_file *file_priv,
> +		    struct drm_device *dev,
> +		    struct drm_mode_create_dumb *args);
> +struct dma_buf *vc4_prime_export(struct drm_device *dev,
> +				 struct drm_gem_object *obj, int flags);
> +
> +/* vc4_crtc.c */
> +void vc4_crtc_register(void);
> +void vc4_crtc_unregister(void);
> +int vc4_enable_vblank(struct drm_device *dev, int crtc_id);
> +void vc4_disable_vblank(struct drm_device *dev, int crtc_id);
> +void vc4_cancel_page_flip(struct drm_crtc *crtc, struct drm_file *file);
> +int vc4_crtc_debugfs_regs(struct seq_file *m, void *arg);
> +
> +/* vc4_debugfs.c */
> +int vc4_debugfs_init(struct drm_minor *minor);
> +void vc4_debugfs_cleanup(struct drm_minor *minor);
> +
> +/* vc4_drv.c */
> +void __iomem *vc4_ioremap_regs(struct platform_device *dev, int index);
> +
> +/* vc4_hdmi.c */
> +void vc4_hdmi_register(void);
> +void vc4_hdmi_unregister(void);
> +struct drm_encoder *vc4_hdmi_encoder_init(struct drm_device *dev);
> +struct drm_connector *vc4_hdmi_connector_init(struct drm_device *dev,
> +					      struct drm_encoder *encoder);
> +int vc4_hdmi_debugfs_regs(struct seq_file *m, void *unused);
> +
> +/* vc4_hvs.c */
> +void vc4_hvs_register(void);
> +void vc4_hvs_unregister(void);
> +void vc4_hvs_dump_state(struct drm_device *dev);
> +int vc4_hvs_debugfs_regs(struct seq_file *m, void *unused);
> +
> +/* vc4_kms.c */
> +int vc4_kms_load(struct drm_device *dev);
> +
> +/* vc4_plane.c */
> +struct drm_plane *vc4_plane_init(struct drm_device *dev,
> +				 enum drm_plane_type type);
> +u32 vc4_plane_write_dlist(struct drm_plane *plane, u32 __iomem *dlist);
> +u32 vc4_plane_dlist_size(struct drm_plane_state *state);
> diff --git a/drivers/gpu/drm/vc4/vc4_hdmi.c b/drivers/gpu/drm/vc4/vc4_hdmi.c
> new file mode 100644
> index 0000000..c1ac96e
> --- /dev/null
> +++ b/drivers/gpu/drm/vc4/vc4_hdmi.c
> @@ -0,0 +1,651 @@
> +/*
> + * Copyright (c) 2014 The Linux Foundation. All rights reserved.
> + * Copyright (C) 2013 Red Hat
> + * Author: Rob Clark <robdclark at gmail.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.
> + *
> + * You should have received a copy of the GNU General Public License along with
> + * this program.  If not, see <http://www.gnu.org/licenses/>.
> + */
> +
> +#include "drm_atomic_helper.h"
> +#include "drm_crtc_helper.h"
> +#include "drm_edid.h"
> +#include "linux/clk.h"
> +#include "linux/component.h"
> +#include "linux/of_gpio.h"
> +#include "linux/of_platform.h"
> +#include "vc4_drv.h"
> +#include "vc4_regs.h"
> +
> +/* General HDMI hardware state. */
> +struct vc4_hdmi {
> +	struct platform_device *pdev;
> +	struct i2c_adapter *ddc;
> +	void __iomem *hdmicore_regs;
> +	void __iomem *hd_regs;
> +	int hpd_gpio;
> +
> +	/* Probed video mode at boot time, used to filter display
> +	 * modes to only allow equivalent ones (since we can't set the
> +	 * pixel clock yet).
> +	 */
> +	struct drm_display_mode boot_mode;
> +};
> +#define HDMI_READ(offset) readl(vc4->hdmi->hdmicore_regs + offset)
> +#define HDMI_WRITE(offset, val) writel(val, vc4->hdmi->hdmicore_regs + offset)
> +#define HD_READ(offset) readl(vc4->hdmi->hd_regs + offset)
> +#define HD_WRITE(offset, val) writel(val, vc4->hdmi->hd_regs + offset)
> +
> +/* VC4 HDMI encoder KMS struct */
> +struct vc4_hdmi_encoder {
> +	struct drm_encoder base;
> +	bool hdmi_monitor;
> +};
> +static inline struct vc4_hdmi_encoder *
> +to_vc4_hdmi_encoder(struct drm_encoder *encoder)
> +{
> +	return container_of(encoder, struct vc4_hdmi_encoder, base);
> +}
> +
> +/* VC4 HDMI connector KMS struct */
> +struct vc4_hdmi_connector {
> +	struct drm_connector base;
> +
> +	/* Since the connector is attached to just the one encoder,
> +	 * this is the reference to it so we can do the best_encoder()
> +	 * hook.
> +	 */
> +	struct drm_encoder *encoder;
> +};
> +static inline struct vc4_hdmi_connector *
> +to_vc4_hdmi_connector(struct drm_connector *connector)
> +{
> +	return container_of(connector, struct vc4_hdmi_connector, base);
> +}
> +
> +#define HDMI_REG(reg) { reg, #reg }
> +static const struct {
> +	u32 reg;
> +	const char *name;
> +} hdmi_regs[] = {
> +	HDMI_REG(VC4_HDMI_CORE_REV),
> +	HDMI_REG(VC4_HDMI_SW_RESET_CONTROL),
> +	HDMI_REG(VC4_HDMI_HOTPLUG_INT),
> +	HDMI_REG(VC4_HDMI_HOTPLUG),
> +	HDMI_REG(VC4_HDMI_HORZA),
> +	HDMI_REG(VC4_HDMI_HORZB),
> +	HDMI_REG(VC4_HDMI_FIFO_CTL),
> +	HDMI_REG(VC4_HDMI_SCHEDULER_CONTROL),
> +	HDMI_REG(VC4_HDMI_VERTA0),
> +	HDMI_REG(VC4_HDMI_VERTA1),
> +	HDMI_REG(VC4_HDMI_VERTB0),
> +	HDMI_REG(VC4_HDMI_VERTB1),
> +	HDMI_REG(VC4_HDMI_TX_PHY_RESET_CTL),
> +};
> +static const struct {
> +	u32 reg;
> +	const char *name;
> +} hd_regs[] = {
> +	HDMI_REG(VC4_HD_M_CTL),
> +	HDMI_REG(VC4_HD_MAI_CTL),
> +	HDMI_REG(VC4_HD_VID_CTL),
> +	HDMI_REG(VC4_HD_CSC_CTL),
> +	HDMI_REG(VC4_HD_FRAME_COUNT),
> +};
> +
> +#ifdef CONFIG_DEBUG_FS
> +int vc4_hdmi_debugfs_regs(struct seq_file *m, void *unused)
> +{
> +	struct drm_info_node *node = (struct drm_info_node *) m->private;
> +	struct drm_device *dev = node->minor->dev;
> +	struct vc4_dev *vc4 = to_vc4_dev(dev);
> +	int i;
> +
> +	for (i = 0; i < ARRAY_SIZE(hdmi_regs); i++) {
> +		seq_printf(m, "%s (0x%04x): 0x%08x\n",
> +			   hdmi_regs[i].name, hdmi_regs[i].reg,
> +			   HDMI_READ(hdmi_regs[i].reg));
> +	}
> +
> +	for (i = 0; i < ARRAY_SIZE(hd_regs); i++) {
> +		seq_printf(m, "%s (0x%04x): 0x%08x\n",
> +			   hd_regs[i].name, hd_regs[i].reg,
> +			   HD_READ(hd_regs[i].reg));
> +	}
> +
> +	return 0;
> +}
> +#endif /* CONFIG_DEBUG_FS */
> +
> +static void vc4_hdmi_dump_regs(struct drm_device *dev)
> +{
> +	struct vc4_dev *vc4 = to_vc4_dev(dev);
> +	int i;
> +
> +	for (i = 0; i < ARRAY_SIZE(hdmi_regs); i++) {
> +		DRM_INFO("0x%04x (%s): 0x%08x\n",
> +			 hdmi_regs[i].reg, hdmi_regs[i].name,
> +			 HDMI_READ(hdmi_regs[i].reg));
> +	}
> +	for (i = 0; i < ARRAY_SIZE(hd_regs); i++) {
> +		DRM_INFO("0x%04x (%s): 0x%08x\n",
> +			 hd_regs[i].reg, hd_regs[i].name,
> +			 HD_READ(hd_regs[i].reg));
> +	}
> +}
> +
> +static enum drm_connector_status
> +vc4_hdmi_connector_detect(struct drm_connector *connector, bool force)
> +{
> +	struct drm_device *dev = connector->dev;
> +	struct vc4_dev *vc4 = to_vc4_dev(dev);
> +
> +	if (vc4->hdmi->hpd_gpio) {
> +		if (gpio_get_value(vc4->hdmi->hpd_gpio))
> +			return connector_status_connected;
> +		else
> +			return connector_status_disconnected;
> +	}
> +
> +	if (HDMI_READ(VC4_HDMI_HOTPLUG) & VC4_HDMI_HOTPLUG_CONNECTED)
> +		return connector_status_connected;
> +	else
> +		return connector_status_disconnected;
> +}
> +
> +static void vc4_hdmi_connector_destroy(struct drm_connector *connector)
> +{
> +	drm_connector_unregister(connector);
> +	drm_connector_cleanup(connector);
> +}
> +
> +static int vc4_hdmi_connector_get_modes(struct drm_connector *connector)
> +{
> +	struct vc4_hdmi_connector *vc4_connector =
> +		to_vc4_hdmi_connector(connector);
> +	struct drm_encoder *encoder = vc4_connector->encoder;
> +	struct vc4_hdmi_encoder *vc4_encoder = to_vc4_hdmi_encoder(encoder);
> +	struct drm_device *dev = connector->dev;
> +	struct vc4_dev *vc4 = to_vc4_dev(dev);
> +	int ret = 0;
> +	struct edid *edid;
> +
> +	edid = drm_get_edid(connector, vc4->hdmi->ddc);
> +	if (!edid)
> +		return -ENODEV;
> +
> +	vc4_encoder->hdmi_monitor = drm_detect_hdmi_monitor(edid);
> +	drm_mode_connector_update_edid_property(connector, edid);
> +	ret = drm_add_edid_modes(connector, edid);
> +
> +	return ret;
> +}
> +
> +/* Since we can't set the pixel clock yet, filter out all the EDID
> + * modes that don't match what was set up by the firmware.
> + */
> +int vc4_hdmi_mode_valid(struct drm_connector *connector,
> +			struct drm_display_mode *mode)
> +{
> +	struct drm_device *dev = connector->dev;
> +	struct vc4_dev *vc4 = to_vc4_dev(dev);
> +	struct drm_display_mode *boot_mode = &vc4->hdmi->boot_mode;
> +
> +	if (mode->hdisplay != boot_mode->hdisplay ||
> +	    mode->hsync_start != boot_mode->hsync_start ||
> +	    mode->hsync_end != boot_mode->hsync_end ||
> +	    mode->htotal != boot_mode->htotal) {
> +		return MODE_ERROR;
> +	}
> +
> +	return MODE_OK;
> +}
> +
> +static struct drm_encoder *
> +vc4_hdmi_connector_best_encoder(struct drm_connector *connector)
> +{
> +	struct vc4_hdmi_connector *hdmi_connector =
> +		to_vc4_hdmi_connector(connector);
> +	return hdmi_connector->encoder;
> +}
> +
> +static const struct drm_connector_funcs vc4_hdmi_connector_funcs = {
> +	.dpms = drm_atomic_helper_connector_dpms,
> +	.detect = vc4_hdmi_connector_detect,
> +	.fill_modes = drm_helper_probe_single_connector_modes,
> +	.destroy = vc4_hdmi_connector_destroy,
> +	.reset = drm_atomic_helper_connector_reset,
> +	.atomic_duplicate_state = drm_atomic_helper_connector_duplicate_state,
> +	.atomic_destroy_state = drm_atomic_helper_connector_destroy_state,
> +};
> +
> +static const struct drm_connector_helper_funcs vc4_hdmi_connector_helper_funcs = {
> +	.get_modes = vc4_hdmi_connector_get_modes,
> +	.mode_valid = vc4_hdmi_mode_valid,
> +	.best_encoder = vc4_hdmi_connector_best_encoder,
> +};
> +
> +struct drm_connector *vc4_hdmi_connector_init(struct drm_device *dev,
> +					      struct drm_encoder *encoder)
> +{
> +	struct drm_connector *connector = NULL;
> +	struct vc4_hdmi_connector *hdmi_connector;
> +	int ret = 0;
> +
> +	hdmi_connector = devm_kzalloc(dev->dev, sizeof(*hdmi_connector),
> +				      GFP_KERNEL);
> +	if (!hdmi_connector) {
> +		ret = -ENOMEM;
> +		goto fail;
> +	}
> +	connector = &hdmi_connector->base;
> +
> +	hdmi_connector->encoder = encoder;
> +
> +	drm_connector_init(dev, connector, &vc4_hdmi_connector_funcs,
> +			   DRM_MODE_CONNECTOR_HDMIA);
> +	drm_connector_helper_add(connector, &vc4_hdmi_connector_helper_funcs);
> +
> +	connector->polled = (DRM_CONNECTOR_POLL_CONNECT |
> +			     DRM_CONNECTOR_POLL_DISCONNECT);
> +
> +	connector->interlace_allowed = 0;
> +	connector->doublescan_allowed = 0;
> +
> +	drm_connector_register(connector);
> +
> +	drm_mode_connector_attach_encoder(connector, encoder);
> +
> +	return connector;
> +
> + fail:
> +	if (connector)
> +		vc4_hdmi_connector_destroy(connector);
> +
> +	return ERR_PTR(ret);
> +}
> +
> +static void vc4_encoder_destroy(struct drm_encoder *encoder)
> +{
> +	drm_encoder_cleanup(encoder);
> +}
> +
> +static const struct drm_encoder_funcs vc4_hdmi_encoder_funcs = {
> +	.destroy = vc4_encoder_destroy,
> +};
> +
> +static bool vc4_hdmi_encoder_mode_fixup(struct drm_encoder *encoder,
> +					const struct drm_display_mode *mode,
> +					struct drm_display_mode *adjusted_mode)
> +{
> +	return true;
> +}

As mentioned above, you can drop this one here.

> +
> +static void vc4_hdmi_encoder_mode_set(struct drm_encoder *encoder,
> +				      struct drm_display_mode *unadjusted_mode,
> +				      struct drm_display_mode *mode)
> +{
> +	struct drm_device *dev = encoder->dev;
> +	struct vc4_dev *vc4 = to_vc4_dev(dev);
> +	bool debug_dump_regs = false;
> +	bool hsync_pos = !(mode->flags & DRM_MODE_FLAG_NHSYNC);
> +	bool vsync_pos = !(mode->flags & DRM_MODE_FLAG_NVSYNC);
> +	u32 vactive = (mode->vdisplay >>
> +		       ((mode->flags & DRM_MODE_FLAG_INTERLACE) ? 1 : 0));
> +	u32 verta = (VC4_SET_FIELD(mode->vsync_end - mode->vsync_start,
> +				   VC4_HDMI_VERTA_VSP) |
> +		     VC4_SET_FIELD(mode->vsync_start - mode->vdisplay,
> +				   VC4_HDMI_VERTA_VFP) |
> +		     VC4_SET_FIELD(vactive, VC4_HDMI_VERTA_VAL));
> +	u32 vertb = (VC4_SET_FIELD(0, VC4_HDMI_VERTB_VSPO) |
> +		     VC4_SET_FIELD(mode->vtotal - mode->vsync_end,
> +				   VC4_HDMI_VERTB_VBP));
> +
> +	if (debug_dump_regs) {
> +		DRM_INFO("HDMI regs before:\n");
> +		vc4_hdmi_dump_regs(dev);
> +	}
> +
> +	HD_WRITE(VC4_HD_VID_CTL, 0);
> +
> +	/* XXX: This is where we would set the HDMI state machine
> +	 * clock, if we had an interface for it.
> +	 */
> +
> +	HDMI_WRITE(VC4_HDMI_SCHEDULER_CONTROL,
> +		   HDMI_READ(VC4_HDMI_SCHEDULER_CONTROL) |
> +		   VC4_HDMI_SCHEDULER_CONTROL_MANUAL_FORMAT |
> +		   VC4_HDMI_SCHEDULER_CONTROL_IGNORE_VSYNC_PREDICTS);
> +
> +	HDMI_WRITE(VC4_HDMI_HORZA,
> +		   (vsync_pos ? VC4_HDMI_HORZA_VPOS : 0) |
> +		   (hsync_pos ? VC4_HDMI_HORZA_HPOS : 0) |
> +		   VC4_SET_FIELD(mode->hdisplay, VC4_HDMI_HORZA_HAP));
> +
> +	HDMI_WRITE(VC4_HDMI_HORZB,
> +		   VC4_SET_FIELD(mode->htotal - mode->hsync_end,
> +				 VC4_HDMI_HORZB_HBP) |
> +		   VC4_SET_FIELD(mode->hsync_end - mode->hsync_start,
> +				 VC4_HDMI_HORZB_HSP) |
> +		   VC4_SET_FIELD(mode->hsync_start - mode->hdisplay,
> +				 VC4_HDMI_HORZB_HFP));
> +
> +	HDMI_WRITE(VC4_HDMI_VERTA0, verta);
> +	HDMI_WRITE(VC4_HDMI_VERTA1, verta);
> +
> +	HDMI_WRITE(VC4_HDMI_VERTB0, vertb);
> +	HDMI_WRITE(VC4_HDMI_VERTB1, vertb);
> +
> +	HD_WRITE(VC4_HD_VID_CTL,
> +		 (vsync_pos ? 0 : VC4_HD_VID_CTL_VSYNC_LOW) |
> +		 (hsync_pos ? 0 : VC4_HD_VID_CTL_HSYNC_LOW));
> +
> +	/* The RGB order applies even when CSC is disabled. */
> +	HD_WRITE(VC4_HD_CSC_CTL, VC4_SET_FIELD(VC4_HD_CSC_CTL_ORDER_BGR,
> +					       VC4_HD_CSC_CTL_ORDER));
> +
> +	HDMI_WRITE(VC4_HDMI_FIFO_CTL, VC4_HDMI_FIFO_CTL_MASTER_SLAVE_N);
> +
> +	if (debug_dump_regs) {
> +		DRM_INFO("HDMI regs after:\n");
> +		vc4_hdmi_dump_regs(dev);
> +	}
> +}
> +
> +static void vc4_hdmi_encoder_disable(struct drm_encoder *encoder)
> +{
> +	struct drm_device *dev = encoder->dev;
> +	struct vc4_dev *vc4 = to_vc4_dev(dev);
> +
> +	HDMI_WRITE(VC4_HDMI_TX_PHY_RESET_CTL, 0xf << 16);
> +	HD_WRITE(VC4_HD_VID_CTL,
> +		 HD_READ(VC4_HD_VID_CTL) & ~VC4_HD_VID_CTL_ENABLE);
> +}
> +
> +static void vc4_hdmi_encoder_enable(struct drm_encoder *encoder)
> +{
> +	struct vc4_hdmi_encoder *vc4_encoder = to_vc4_hdmi_encoder(encoder);
> +	struct drm_device *dev = encoder->dev;
> +	struct vc4_dev *vc4 = to_vc4_dev(dev);
> +
> +	HDMI_WRITE(VC4_HDMI_TX_PHY_RESET_CTL, 0);
> +
> +	HD_WRITE(VC4_HD_VID_CTL,
> +		 HD_READ(VC4_HD_VID_CTL) |
> +		 VC4_HD_VID_CTL_ENABLE |
> +		 VC4_HD_VID_CTL_UNDERFLOW_ENABLE |
> +		 VC4_HD_VID_CTL_FRAME_COUNTER_RESET);
> +
> +	if (vc4_encoder->hdmi_monitor) {
> +		HDMI_WRITE(VC4_HDMI_SCHEDULER_CONTROL,
> +			   HDMI_READ(VC4_HDMI_SCHEDULER_CONTROL) |
> +			   VC4_HDMI_SCHEDULER_CONTROL_MODE_HDMI);
> +
> +		while (!(HDMI_READ(VC4_HDMI_SCHEDULER_CONTROL) &
> +			 VC4_HDMI_SCHEDULER_CONTROL_HDMI_ACTIVE)) {
> +			cpu_relax();
> +		}
> +	} else {
> +		HDMI_WRITE(VC4_HDMI_RAM_PACKET_CONFIG,
> +			   HDMI_READ(VC4_HDMI_RAM_PACKET_CONFIG) &
> +			   ~(VC4_HDMI_RAM_PACKET_ENABLE));
> +		HDMI_WRITE(VC4_HDMI_SCHEDULER_CONTROL,
> +			   HDMI_READ(VC4_HDMI_SCHEDULER_CONTROL) &
> +			   ~VC4_HDMI_SCHEDULER_CONTROL_MODE_HDMI);
> +
> +		while (HDMI_READ(VC4_HDMI_SCHEDULER_CONTROL) &
> +		       VC4_HDMI_SCHEDULER_CONTROL_HDMI_ACTIVE) {
> +			cpu_relax();
> +		}
> +	}
> +
> +	if (vc4_encoder->hdmi_monitor) {
> +		u32 drift;
> +
> +		WARN_ON(!(HDMI_READ(VC4_HDMI_SCHEDULER_CONTROL) &
> +			  VC4_HDMI_SCHEDULER_CONTROL_HDMI_ACTIVE));
> +		HDMI_WRITE(VC4_HDMI_SCHEDULER_CONTROL,
> +			   HDMI_READ(VC4_HDMI_SCHEDULER_CONTROL) |
> +			   VC4_HDMI_SCHEDULER_CONTROL_VERT_ALWAYS_KEEPOUT);
> +
> +		/* XXX: Set HDMI_RAM_PACKET_CONFIG (1 << 16) and set
> +		 * up the infoframe.
> +		 */
> +
> +		drift = HDMI_READ(VC4_HDMI_FIFO_CTL);
> +		drift &= VC4_HDMI_FIFO_VALID_WRITE_MASK;
> +
> +		HDMI_WRITE(VC4_HDMI_FIFO_CTL,
> +			   drift & ~VC4_HDMI_FIFO_CTL_RECENTER);
> +		HDMI_WRITE(VC4_HDMI_FIFO_CTL,
> +			   drift | VC4_HDMI_FIFO_CTL_RECENTER);
> +		udelay(1000);
> +		HDMI_WRITE(VC4_HDMI_FIFO_CTL,
> +			   drift & ~VC4_HDMI_FIFO_CTL_RECENTER);
> +		HDMI_WRITE(VC4_HDMI_FIFO_CTL,
> +			   drift | VC4_HDMI_FIFO_CTL_RECENTER);
> +
> +		while ((HDMI_READ(VC4_HDMI_FIFO_CTL) &
> +			VC4_HDMI_FIFO_CTL_RECENTER_DONE) == 0) {
> +			cpu_relax();
> +		}
> +	}
> +}
> +
> +static const struct drm_encoder_helper_funcs vc4_hdmi_encoder_helper_funcs = {
> +	.mode_fixup = vc4_hdmi_encoder_mode_fixup,
> +	.mode_set = vc4_hdmi_encoder_mode_set,
> +	.disable = vc4_hdmi_encoder_disable,
> +	.enable = vc4_hdmi_encoder_enable,
> +};
> +
> +static struct drm_crtc *
> +vc4_get_crtc_node(struct platform_device *pdev)
> +{
> +	struct device_node *crtc_node;
> +	struct platform_device *crtc_pdev;
> +
> +	crtc_node = of_parse_phandle(pdev->dev.of_node, "crtc", 0);
> +	if (!crtc_node) {
> +		DRM_ERROR("No CRTC for hdmi in DT\n");
> +		return ERR_PTR(-EINVAL);
> +	}
> +
> +	crtc_pdev = of_find_device_by_node(crtc_node);
> +	if (!crtc_pdev) {
> +		DRM_ERROR("No CRTC device attached to OF node\n");
> +		return ERR_PTR(-EINVAL);
> +	}
> +
> +	return platform_get_drvdata(crtc_pdev);
> +}
> +
> +struct drm_encoder *vc4_hdmi_encoder_init(struct drm_device *dev)
> +{
> +	struct vc4_dev *vc4 = to_vc4_dev(dev);
> +	struct drm_encoder *encoder = NULL;
> +	struct vc4_hdmi_encoder *vc4_hdmi_encoder;
> +	struct drm_crtc *crtc;
> +	int ret;
> +
> +	vc4_hdmi_encoder = devm_kzalloc(dev->dev, sizeof(*vc4_hdmi_encoder),
> +					GFP_KERNEL);
> +	if (!vc4_hdmi_encoder) {
> +		ret = -ENOMEM;
> +		goto fail;
> +	}
> +	encoder = &vc4_hdmi_encoder->base;
> +
> +	crtc = vc4_get_crtc_node(vc4->hdmi->pdev);
> +	if (IS_ERR(crtc)) {
> +		ret = PTR_ERR(crtc);
> +		goto fail;
> +	}
> +
> +	drm_encoder_init(dev, encoder, &vc4_hdmi_encoder_funcs,
> +			 DRM_MODE_ENCODER_TMDS);
> +	drm_encoder_helper_add(encoder, &vc4_hdmi_encoder_helper_funcs);
> +
> +	encoder->possible_crtcs = drm_crtc_mask(crtc);
> +
> +	return encoder;
> +
> +fail:
> +	if (encoder)
> +		vc4_encoder_destroy(encoder);
> +
> +	return ERR_PTR(ret);
> +}
> +
> +/* Reads out the current HDMI mode progreamming at driver load time.
> + *
> + * This is currently used for later filtering out of the DDC-probed
> + * video modes, since we can't actually change modes due to not having
> + * control of the necessary clocks.  Later on, we may end up reusing
> + * this for skipping modesets at boot time.
> + */
> +static void
> +vc4_hdmi_get_boot_display_mode(struct vc4_dev *vc4)
> +{
> +	struct drm_display_mode *mode = &vc4->hdmi->boot_mode;
> +	u32 horza = HDMI_READ(VC4_HDMI_HORZA);
> +	u32 horzb = HDMI_READ(VC4_HDMI_HORZB);
> +	u32 verta = HDMI_READ(VC4_HDMI_VERTA0);
> +	u32 vertb = HDMI_READ(VC4_HDMI_VERTB0);
> +
> +	memset(mode, 0, sizeof(*mode));
> +
> +	if (!(horza & VC4_HDMI_HORZA_VPOS))
> +		mode->flags |= DRM_MODE_FLAG_NVSYNC;
> +	if (!(horza & VC4_HDMI_HORZA_HPOS))
> +		mode->flags |= DRM_MODE_FLAG_NHSYNC;
> +	mode->hdisplay = VC4_GET_FIELD(horza, VC4_HDMI_HORZA_HAP);
> +	mode->hsync_start = (mode->hdisplay +
> +			     VC4_GET_FIELD(horzb, VC4_HDMI_HORZB_HFP));
> +	mode->hsync_end = (mode->hsync_start +
> +			   VC4_GET_FIELD(horzb, VC4_HDMI_HORZB_HSP));
> +	mode->htotal = (mode->hsync_end +
> +			VC4_GET_FIELD(horzb, VC4_HDMI_HORZB_HBP));
> +
> +	mode->vdisplay = VC4_GET_FIELD(verta, VC4_HDMI_VERTA_VAL);
> +	mode->vsync_start = (mode->vdisplay +
> +			     VC4_GET_FIELD(verta, VC4_HDMI_VERTA_VFP));
> +	mode->vsync_end = (mode->vsync_start +
> +			   VC4_GET_FIELD(verta, VC4_HDMI_VERTA_VSP));
> +	mode->vtotal = (mode->vsync_end +
> +			VC4_GET_FIELD(vertb, VC4_HDMI_VERTB_VBP));
> +}
> +
> +static int vc4_hdmi_bind(struct device *dev, struct device *master, void *data)
> +{
> +	struct platform_device *pdev = to_platform_device(dev);
> +	struct drm_device *drm = dev_get_drvdata(master);
> +	struct vc4_dev *vc4 = drm->dev_private;
> +	struct vc4_hdmi *hdmi;
> +	struct device_node *ddc_node;
> +	u32 value;
> +
> +	hdmi = devm_kzalloc(dev, sizeof(*hdmi), GFP_KERNEL);
> +	if (!hdmi)
> +		return -ENOMEM;
> +
> +	hdmi->pdev = pdev;
> +	hdmi->hdmicore_regs = vc4_ioremap_regs(pdev, 0);
> +	if (IS_ERR(hdmi->hdmicore_regs))
> +		return PTR_ERR(hdmi->hdmicore_regs);
> +
> +	hdmi->hd_regs = vc4_ioremap_regs(pdev, 1);
> +	if (IS_ERR(hdmi->hd_regs))
> +		return PTR_ERR(hdmi->hd_regs);
> +
> +	/* DDC i2c driver */
> +	ddc_node = of_parse_phandle(dev->of_node, "ddc", 0);
> +	if (!ddc_node) {
> +		DRM_ERROR("Failed to find ddc node in device tree\n");
> +		return -ENODEV;
> +	}
> +
> +	hdmi->ddc = of_find_i2c_adapter_by_node(ddc_node);
> +	if (!hdmi->ddc) {
> +		DRM_ERROR("Failed to get ddc i2c adapter by node\n");
> +		return -EPROBE_DEFER;
> +	}
> +
> +	/* Only use the GPIO HPD pin if present in the DT, otherwise
> +	 * we'll use the HDMI core's register.
> +	 */
> +	if (of_find_property(dev->of_node, "hpd-gpio", &value)) {
> +		hdmi->hpd_gpio = of_get_named_gpio(dev->of_node, "hpd-gpio", 0);
> +		if (hdmi->hpd_gpio < 0)
> +			return hdmi->hpd_gpio;
> +	}
> +
> +	vc4->hdmi = hdmi;
> +
> +	/* HDMI core must be enabled. */
> +	WARN_ON_ONCE((HD_READ(VC4_HD_M_CTL) & VC4_HD_M_ENABLE) == 0);
> +
> +	vc4_hdmi_get_boot_display_mode(vc4);
> +
> +	return 0;
> +}
> +
> +static void vc4_hdmi_unbind(struct device *dev, struct device *master,
> +			    void *data)
> +{
> +	struct drm_device *drm = dev_get_drvdata(master);
> +	struct vc4_dev *vc4 = drm->dev_private;
> +
> +	put_device(&vc4->hdmi->ddc->dev);
> +
> +	vc4->hdmi = NULL;
> +}
> +
> +static const struct component_ops vc4_hdmi_ops = {
> +	.bind   = vc4_hdmi_bind,
> +	.unbind = vc4_hdmi_unbind,
> +};
> +
> +static int vc4_hdmi_dev_probe(struct platform_device *pdev)
> +{
> +	return component_add(&pdev->dev, &vc4_hdmi_ops);
> +}
> +
> +static int vc4_hdmi_dev_remove(struct platform_device *pdev)
> +{
> +	component_del(&pdev->dev, &vc4_hdmi_ops);
> +	return 0;
> +}
> +
> +static const struct of_device_id vc4_hdmi_dt_match[] = {
> +	{ .compatible = "brcm,vc4-hdmi" },
> +	{}
> +};
> +
> +static struct platform_driver vc4_hdmi_driver = {
> +	.probe = vc4_hdmi_dev_probe,
> +	.remove = vc4_hdmi_dev_remove,
> +	.driver = {
> +		.name = "vc4_hdmi",
> +		.of_match_table = vc4_hdmi_dt_match,
> +	},
> +};
> +
> +void __init vc4_hdmi_register(void)
> +{
> +	platform_driver_register(&vc4_hdmi_driver);
> +}
> +
> +void __exit vc4_hdmi_unregister(void)
> +{
> +	platform_driver_unregister(&vc4_hdmi_driver);
> +}
> diff --git a/drivers/gpu/drm/vc4/vc4_hvs.c b/drivers/gpu/drm/vc4/vc4_hvs.c
> new file mode 100644
> index 0000000..dcf4f78
> --- /dev/null
> +++ b/drivers/gpu/drm/vc4/vc4_hvs.c
> @@ -0,0 +1,172 @@
> +/*
> + * Copyright (C) 2015 Broadcom
> + *
> + * 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.
> + */
> +
> +/**
> + * DOC: VC4 HVS module.
> + *
> + * The HVS is the piece of hardware that does translation, scaling,
> + * colorspace conversion, and compositing of pixels stored in
> + * framebuffers into a FIFO of pixels going out to the Pixel Valve
> + * (CRTC).
> + *
> + * There is a single global HVS, with multiple output FIFOs that can
> + * be consumed by the PVs.  This file just manages the resources for
> + * the HVS, while the vc4_crtc.c code actually drives HVS setup for
> + * each CRTC.
> + */
> +
> +#include "linux/component.h"
> +#include "vc4_drv.h"
> +#include "vc4_regs.h"
> +
> +#define HVS_REG(reg) { reg, #reg }
> +static const struct {
> +	u32 reg;
> +	const char *name;
> +} hvs_regs[] = {
> +	HVS_REG(SCALER_DISPCTRL),
> +	HVS_REG(SCALER_DISPSTAT),
> +	HVS_REG(SCALER_DISPID),
> +	HVS_REG(SCALER_DISPECTRL),
> +	HVS_REG(SCALER_DISPPROF),
> +	HVS_REG(SCALER_DISPDITHER),
> +	HVS_REG(SCALER_DISPEOLN),
> +	HVS_REG(SCALER_DISPLIST0),
> +	HVS_REG(SCALER_DISPLIST1),
> +	HVS_REG(SCALER_DISPLIST2),
> +	HVS_REG(SCALER_DISPLSTAT),
> +	HVS_REG(SCALER_DISPLACT0),
> +	HVS_REG(SCALER_DISPLACT1),
> +	HVS_REG(SCALER_DISPLACT2),
> +	HVS_REG(SCALER_DISPCTRL0),
> +	HVS_REG(SCALER_DISPBKGND0),
> +	HVS_REG(SCALER_DISPSTAT0),
> +	HVS_REG(SCALER_DISPBASE0),
> +	HVS_REG(SCALER_DISPCTRL1),
> +	HVS_REG(SCALER_DISPBKGND1),
> +	HVS_REG(SCALER_DISPSTAT1),
> +	HVS_REG(SCALER_DISPBASE1),
> +	HVS_REG(SCALER_DISPCTRL2),
> +	HVS_REG(SCALER_DISPBKGND2),
> +	HVS_REG(SCALER_DISPSTAT2),
> +	HVS_REG(SCALER_DISPBASE2),
> +	HVS_REG(SCALER_DISPALPHA2),
> +};
> +
> +void
> +vc4_hvs_dump_state(struct drm_device *dev)
> +{
> +	struct vc4_dev *vc4 = to_vc4_dev(dev);
> +	int i;
> +
> +	for (i = 0; i < ARRAY_SIZE(hvs_regs); i++) {
> +		DRM_INFO("0x%04x (%s): 0x%08x\n",
> +			 hvs_regs[i].reg, hvs_regs[i].name,
> +			 HVS_READ(hvs_regs[i].reg));
> +	}
> +
> +	DRM_INFO("HVS ctx:\n");
> +	for (i = 0; i < 64; i += 4) {
> +		DRM_INFO("0x%08x (%s): 0x%08x 0x%08x 0x%08x 0x%08x\n",
> +			 i * 4, i < HVS_BOOTLOADER_DLIST_END ? "B" : "D",
> +			 ((uint32_t *)vc4->hvs->dlist)[i + 0],
> +			 ((uint32_t *)vc4->hvs->dlist)[i + 1],
> +			 ((uint32_t *)vc4->hvs->dlist)[i + 2],
> +			 ((uint32_t *)vc4->hvs->dlist)[i + 3]);
> +	}
> +}
> +
> +#ifdef CONFIG_DEBUG_FS
> +int vc4_hvs_debugfs_regs(struct seq_file *m, void *unused)
> +{
> +	struct drm_info_node *node = (struct drm_info_node *) m->private;
> +	struct drm_device *dev = node->minor->dev;
> +	struct vc4_dev *vc4 = to_vc4_dev(dev);
> +	int i;
> +
> +	for (i = 0; i < ARRAY_SIZE(hvs_regs); i++) {
> +		seq_printf(m, "%s (0x%04x): 0x%08x\n",
> +			   hvs_regs[i].name, hvs_regs[i].reg,
> +			   HVS_READ(hvs_regs[i].reg));
> +	}
> +
> +	return 0;
> +}
> +#endif
> +
> +static int vc4_hvs_bind(struct device *dev, struct device *master, void *data)
> +{
> +	struct platform_device *pdev = to_platform_device(dev);
> +	struct drm_device *drm = dev_get_drvdata(master);
> +	struct vc4_dev *vc4 = drm->dev_private;
> +	struct vc4_hvs *hvs = NULL;
> +
> +	hvs = devm_kzalloc(&pdev->dev, sizeof(*hvs), GFP_KERNEL);
> +	if (!hvs)
> +		return -ENOMEM;
> +
> +	hvs->pdev = pdev;
> +
> +	hvs->regs = vc4_ioremap_regs(pdev, 0);
> +	if (IS_ERR(hvs->regs))
> +		return PTR_ERR(hvs->regs);
> +
> +	hvs->dlist = hvs->regs + SCALER_DLIST_START;
> +
> +	vc4->hvs = hvs;
> +	return 0;
> +}
> +
> +static void vc4_hvs_unbind(struct device *dev, struct device *master,
> +			   void *data)
> +{
> +	struct drm_device *drm = dev_get_drvdata(master);
> +	struct vc4_dev *vc4 = drm->dev_private;
> +
> +	vc4->hvs = NULL;
> +}
> +
> +static const struct component_ops vc4_hvs_ops = {
> +	.bind   = vc4_hvs_bind,
> +	.unbind = vc4_hvs_unbind,
> +};
> +
> +static int vc4_hvs_dev_probe(struct platform_device *pdev)
> +{
> +	return component_add(&pdev->dev, &vc4_hvs_ops);
> +}
> +
> +static int vc4_hvs_dev_remove(struct platform_device *pdev)
> +{
> +	component_del(&pdev->dev, &vc4_hvs_ops);
> +	return 0;
> +}
> +
> +static const struct of_device_id vc4_hvs_dt_match[] = {
> +	{ .compatible = "brcm,vc4-hvs" },
> +	{}
> +};
> +
> +static struct platform_driver vc4_hvs_driver = {
> +	.probe = vc4_hvs_dev_probe,
> +	.remove = vc4_hvs_dev_remove,
> +	.driver = {
> +		.name = "vc4_hvs",
> +		.of_match_table = vc4_hvs_dt_match,
> +	},
> +};
> +
> +void __init vc4_hvs_register(void)
> +{
> +	platform_driver_register(&vc4_hvs_driver);
> +}
> +
> +void __exit vc4_hvs_unregister(void)
> +{
> +	platform_driver_unregister(&vc4_hvs_driver);
> +}
> diff --git a/drivers/gpu/drm/vc4/vc4_kms.c b/drivers/gpu/drm/vc4/vc4_kms.c
> new file mode 100644
> index 0000000..e5e96bc
> --- /dev/null
> +++ b/drivers/gpu/drm/vc4/vc4_kms.c
> @@ -0,0 +1,84 @@
> +/*
> + * Copyright (C) 2015 Broadcom
> + *
> + * 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.
> + */
> +
> +/**
> + * DOC: VC4 KMS
> + *
> + * This is the general code for implementing KMS mode setting that
> + * doesn't clearly associate with any of the other objects (plane,
> + * crtc, HDMI encoder).
> + */
> +
> +#include "drm_crtc.h"
> +#include "drm_atomic_helper.h"
> +#include "drm_crtc_helper.h"
> +#include "drm_plane_helper.h"
> +#include "drm_fb_cma_helper.h"
> +#include "vc4_drv.h"
> +
> +static const struct drm_mode_config_funcs vc4_mode_funcs = {
> +	.atomic_check = drm_atomic_helper_check,
> +	.atomic_commit = drm_atomic_helper_commit,
> +	.fb_create = drm_fb_cma_create,
> +};
> +
> +/* Calls out to initialize all of the VC4 KMS objects. */
> +static int vc4_init_modeset_objects(struct drm_device *dev)
> +{
> +	struct drm_encoder *encoder;
> +	struct drm_connector *connector;
> +	int ret = 0;
> +
> +	encoder = vc4_hdmi_encoder_init(dev);
> +	if (IS_ERR(encoder)) {
> +		dev_err(dev->dev, "failed to construct HDMI encoder\n");
> +		ret = PTR_ERR(encoder);
> +		goto fail;
> +	}
> +
> +	connector = vc4_hdmi_connector_init(dev, encoder);
> +	if (IS_ERR(connector)) {
> +		ret = PTR_ERR(connector);
> +		dev_err(dev->dev, "failed to initialize HDMI connector\n");
> +		goto fail;
> +	}
> +
> +fail:
> +	return ret;
> +}
> +
> +int vc4_kms_load(struct drm_device *dev)
> +{
> +	int ret;
> +
> +	ret = drm_vblank_init(dev, dev->mode_config.num_crtc);
> +	if (ret < 0) {
> +		dev_err(dev->dev, "failed to initialize vblank\n");
> +		return ret;
> +	}
> +
> +	dev->mode_config.max_width = 2048;
> +	dev->mode_config.max_height = 2048;
> +	dev->mode_config.funcs = &vc4_mode_funcs;
> +	dev->mode_config.preferred_depth = 24;
> +
> +	ret = vc4_init_modeset_objects(dev);
> +	if (ret)
> +		goto fail;
> +
> +	drm_mode_config_reset(dev);
> +
> +	drm_fbdev_cma_init(dev, 32,
> +			   dev->mode_config.num_crtc,
> +			   dev->mode_config.num_connector);
> +
> +	drm_kms_helper_poll_init(dev);
> +
> +fail:
> +	return ret;
> +}
> diff --git a/drivers/gpu/drm/vc4/vc4_plane.c b/drivers/gpu/drm/vc4/vc4_plane.c
> new file mode 100644
> index 0000000..cdd8b10
> --- /dev/null
> +++ b/drivers/gpu/drm/vc4/vc4_plane.c
> @@ -0,0 +1,320 @@
> +/*
> + * Copyright (C) 2015 Broadcom
> + *
> + * 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.
> + */
> +
> +/**
> + * DOC: VC4 plane module
> + *
> + * Each DRM plane is a layer of pixels being scanned out by the HVS.
> + *
> + * At atomic modeset check time, we compute the HVS display element
> + * state that would be necessary for displaying the plane (giving us a
> + * chance to figure out if a plane configuration is invalid), then at
> + * atomic flush time the CRTC will ask us to write our element state
> + * into the region of the HVS that it has allocated for us.
> + */
> +
> +#include "vc4_drv.h"
> +#include "vc4_regs.h"
> +#include "drm_atomic_helper.h"
> +#include "drm_fb_cma_helper.h"
> +#include "drm_plane_helper.h"
> +
> +struct vc4_plane_state {
> +	struct drm_plane_state base;
> +	u32 *dlist;
> +	u32 dlist_size; /* Number of dwords in allocated for the display list */
> +	u32 dlist_count; /* Number of used dwords in the display list. */
> +};
> +
> +static inline struct vc4_plane_state *
> +to_vc4_plane_state(struct drm_plane_state *state)
> +{
> +	return (struct vc4_plane_state *)state;
> +}
> +
> +static const struct hvs_format {
> +	u32 drm; /* DRM_FORMAT_* */
> +	u32 hvs; /* HVS_FORMAT_* */
> +	u32 pixel_order;
> +	bool has_alpha;
> +} hvs_formats[] = {
> +	{
> +		.drm = DRM_FORMAT_XRGB8888, .hvs = HVS_PIXEL_FORMAT_RGBA8888,
> +		.pixel_order = HVS_PIXEL_ORDER_ABGR, .has_alpha = false,
> +	},
> +	{
> +		.drm = DRM_FORMAT_ARGB8888, .hvs = HVS_PIXEL_FORMAT_RGBA8888,
> +		.pixel_order = HVS_PIXEL_ORDER_ABGR, .has_alpha = true,
> +	},
> +};
> +
> +static const struct hvs_format *vc4_get_hvs_format(u32 drm_format)
> +{
> +	unsigned i;
> +
> +	for (i = 0; i < ARRAY_SIZE(hvs_formats); i++) {
> +		if (hvs_formats[i].drm == drm_format)
> +			return &hvs_formats[i];
> +	}
> +
> +	return NULL;
> +}
> +
> +static bool plane_enabled(struct drm_plane_state *state)
> +{
> +	return state->fb && state->crtc;
> +}
> +
> +struct drm_plane_state *vc4_plane_duplicate_state(struct drm_plane *plane)
> +{
> +	struct vc4_plane_state *vc4_state;
> +
> +	if (WARN_ON(!plane->state))
> +		return NULL;
> +
> +	vc4_state = kmemdup(plane->state, sizeof(*vc4_state), GFP_KERNEL);
> +	if (!vc4_state)
> +		return NULL;
> +
> +	__drm_atomic_helper_plane_duplicate_state(plane, &vc4_state->base);
> +
> +	if (vc4_state->dlist) {
> +		vc4_state->dlist = kmemdup(vc4_state->dlist,
> +					   vc4_state->dlist_count * 4,
> +					   GFP_KERNEL);
> +		if (!vc4_state->dlist) {
> +			kfree(vc4_state);
> +			return NULL;
> +		}
> +		vc4_state->dlist_size = vc4_state->dlist_count;
> +	}
> +
> +	return &vc4_state->base;
> +}
> +
> +void vc4_plane_destroy_state(struct drm_plane *plane,
> +			     struct drm_plane_state *state)
> +{
> +	struct vc4_plane_state *vc4_state = to_vc4_plane_state(state);
> +
> +	kfree(vc4_state->dlist);
> +	__drm_atomic_helper_plane_destroy_state(plane, &vc4_state->base);
> +	kfree(state);
> +}
> +
> +/* Called during init to allocate the plane's atomic state. */
> +void vc4_plane_reset(struct drm_plane *plane)
> +{
> +	struct vc4_plane_state *vc4_state;
> +
> +	WARN_ON(plane->state);
> +
> +	vc4_state = kzalloc(sizeof(*vc4_state), GFP_KERNEL);
> +	if (!vc4_state)
> +		return;
> +
> +	plane->state = &vc4_state->base;
> +	vc4_state->base.plane = plane;
> +}
> +
> +static void vc4_dlist_write(struct vc4_plane_state *vc4_state, u32 val)
> +{
> +	if (vc4_state->dlist_count == vc4_state->dlist_size) {
> +		u32 new_size = max(4u, vc4_state->dlist_count * 2);
> +		u32 *new_dlist = kmalloc(new_size * 4, GFP_KERNEL);
> +
> +		if (!new_dlist)
> +			return;
> +		memcpy(new_dlist, vc4_state->dlist, vc4_state->dlist_count * 4);
> +
> +		kfree(vc4_state->dlist);
> +		vc4_state->dlist = new_dlist;
> +		vc4_state->dlist_size = new_size;
> +	}
> +
> +	vc4_state->dlist[vc4_state->dlist_count++] = val;
> +}
> +
> +/* Writes out a full display list for an active plane to the plane's
> + * private dlist state.
> + */
> +static int vc4_plane_mode_set(struct drm_plane *plane,
> +			      struct drm_plane_state *state)
> +{
> +	struct vc4_plane_state *vc4_state = to_vc4_plane_state(state);
> +	struct drm_framebuffer *fb = state->fb;
> +	struct drm_gem_cma_object *bo = drm_fb_cma_get_gem_obj(fb, 0);
> +	u32 ctl0_offset = vc4_state->dlist_count;
> +	const struct hvs_format *format = vc4_get_hvs_format(fb->pixel_format);
> +	uint32_t offset = fb->offsets[0];
> +	int crtc_x = state->crtc_x;
> +	int crtc_y = state->crtc_y;
> +	int crtc_w = state->crtc_w;
> +	int crtc_h = state->crtc_h;
> +
> +	if (crtc_x < 0) {
> +		offset += drm_format_plane_cpp(fb->pixel_format, 0) * -crtc_x;
> +		crtc_w += crtc_x;
> +		crtc_x = 0;
> +	}
> +
> +	if (crtc_y < 0) {
> +		offset += fb->pitches[0] * -crtc_y;
> +		crtc_h += crtc_y;
> +		crtc_y = 0;
> +	}
> +
> +	vc4_dlist_write(vc4_state,
> +			SCALER_CTL0_VALID |
> +			(format->pixel_order << SCALER_CTL0_ORDER_SHIFT) |
> +			(format->hvs << SCALER_CTL0_PIXEL_FORMAT_SHIFT) |
> +			SCALER_CTL0_UNITY);
> +
> +	/* Position Word 0: Image Positions and Alpha Value */
> +	vc4_dlist_write(vc4_state,
> +			VC4_SET_FIELD(0xff, SCALER_POS0_FIXED_ALPHA) |
> +			VC4_SET_FIELD(crtc_x, SCALER_POS0_START_X) |
> +			VC4_SET_FIELD(crtc_y, SCALER_POS0_START_Y));
> +
> +	/* Position Word 1: Scaled Image Dimensions.
> +	 * Skipped due to SCALER_CTL0_UNITY scaling.
> +	 */
> +
> +	/* Position Word 2: Source Image Size, Alpha Mode */
> +	vc4_dlist_write(vc4_state,
> +			VC4_SET_FIELD(format->has_alpha ?
> +				      SCALER_POS2_ALPHA_MODE_PIPELINE :
> +				      SCALER_POS2_ALPHA_MODE_FIXED,
> +				      SCALER_POS2_ALPHA_MODE) |
> +			VC4_SET_FIELD(crtc_w, SCALER_POS2_WIDTH) |
> +			VC4_SET_FIELD(crtc_h, SCALER_POS2_HEIGHT));
> +
> +	/* Position Word 3: Context.  Written by the HVS. */
> +	vc4_dlist_write(vc4_state, 0xc0c0c0c0);
> +
> +	/* Pointer Word 0: RGB / Y Pointer */
> +	vc4_dlist_write(vc4_state, bo->paddr + offset);
> +
> +	/* Pointer Context Word 0: Written by the HVS */
> +	vc4_dlist_write(vc4_state, 0xc0c0c0c0);
> +
> +	/* Pitch word 0: Pointer 0 Pitch */
> +	vc4_dlist_write(vc4_state,
> +			VC4_SET_FIELD(fb->pitches[0], SCALER_SRC_PITCH));
> +
> +	vc4_state->dlist[ctl0_offset] |=
> +		VC4_SET_FIELD(vc4_state->dlist_count, SCALER_CTL0_SIZE);
> +
> +	return 0;
> +}
> +
> +/* If a modeset involves changing the setup of a plane, the atomic
> + * infrastructure will call this to validate a proposed plane setup.
> + * However, if a plane isn't getting updated, this (and the
> + * corresponding vc4_plane_atomic_update) won't get called.  Thus, we
> + * compute the dlist here and have all active plane dlists get updated
> + * in the CRTC's flush.
> + */
> +static int vc4_plane_atomic_check(struct drm_plane *plane,
> +				  struct drm_plane_state *state)
> +{
> +	struct vc4_plane_state *vc4_state = to_vc4_plane_state(state);
> +
> +	vc4_state->dlist_count = 0;
> +
> +	if (plane_enabled(state))
> +		return vc4_plane_mode_set(plane, state);
> +	else
> +		return 0;
> +}
> +
> +static void vc4_plane_atomic_update(struct drm_plane *plane,
> +				    struct drm_plane_state *old_state)
> +{
> +	/* No contents here.  Since we don't know where in the CRTC's
> +	 * dlist we should be stored, our dlist is uploaded to the
> +	 * hardware with vc4_plane_write_dlist() at CRTC atomic_flush
> +	 * time.
> +	 */
> +}
> +
> +u32 vc4_plane_write_dlist(struct drm_plane *plane, u32 __iomem *dlist)
> +{
> +	struct vc4_plane_state *vc4_state = to_vc4_plane_state(plane->state);
> +	int i;
> +
> +	/* Can't memcpy_toio() because it needs to be 32-bit writes. */
> +	for (i = 0; i < vc4_state->dlist_count; i++)
> +		writel(vc4_state->dlist[i], &dlist[i]);
> +
> +	return vc4_state->dlist_count;
> +}
> +
> +u32 vc4_plane_dlist_size(struct drm_plane_state *state)
> +{
> +	struct vc4_plane_state *vc4_state = to_vc4_plane_state(state);
> +
> +	return vc4_state->dlist_count;
> +}
> +
> +static const struct drm_plane_helper_funcs vc4_plane_helper_funcs = {
> +	.prepare_fb = NULL,
> +	.cleanup_fb = NULL,
> +	.atomic_check = vc4_plane_atomic_check,
> +	.atomic_update = vc4_plane_atomic_update,
> +};
> +
> +static void vc4_plane_destroy(struct drm_plane *plane)
> +{
> +	drm_plane_helper_disable(plane);
> +	drm_plane_cleanup(plane);
> +}
> +
> +static const struct drm_plane_funcs vc4_plane_funcs = {
> +	.update_plane = drm_atomic_helper_update_plane,
> +	.disable_plane = drm_atomic_helper_disable_plane,
> +	.destroy = vc4_plane_destroy,
> +	.set_property = NULL,
> +	.reset = vc4_plane_reset,
> +	.atomic_duplicate_state = vc4_plane_duplicate_state,
> +	.atomic_destroy_state = vc4_plane_destroy_state,
> +};
> +
> +struct drm_plane *vc4_plane_init(struct drm_device *dev,
> +				 enum drm_plane_type type)
> +{
> +	struct drm_plane *plane = NULL;
> +	struct vc4_plane *vc4_plane;
> +	u32 formats[ARRAY_SIZE(hvs_formats)];
> +	int ret = 0;
> +	unsigned i;
> +
> +	vc4_plane = devm_kzalloc(dev->dev, sizeof(*vc4_plane),
> +				 GFP_KERNEL);
> +	if (!vc4_plane) {
> +		ret = -ENOMEM;
> +		goto fail;
> +	}
> +
> +	for (i = 0; i < ARRAY_SIZE(hvs_formats); i++)
> +		formats[i] = hvs_formats[i].drm;
> +	plane = &vc4_plane->base;
> +	ret = drm_universal_plane_init(dev, plane, 0xff,
> +				       &vc4_plane_funcs,
> +				       formats, ARRAY_SIZE(formats),
> +				       type);
> +
> +	drm_plane_helper_add(plane, &vc4_plane_helper_funcs);
> +
> +	return plane;
> +fail:
> +	if (plane)
> +		vc4_plane_destroy(plane);
> +
> +	return ERR_PTR(ret);
> +}
> diff --git a/drivers/gpu/drm/vc4/vc4_regs.h b/drivers/gpu/drm/vc4/vc4_regs.h
> new file mode 100644
> index 0000000..0eff631
> --- /dev/null
> +++ b/drivers/gpu/drm/vc4/vc4_regs.h
> @@ -0,0 +1,562 @@
> +/*
> + *  Copyright ? 2014-2015 Broadcom
> + *
> + * 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.
> + */
> +
> +#define VC4_MASK(high, low) (((1 << ((high) - (low) + 1)) - 1) << (low))
> +/* Using the GNU statement expression extension */
> +#define VC4_SET_FIELD(value, field)					\
> +	({								\
> +		uint32_t fieldval = (value) << field##_SHIFT;		\
> +		WARN_ON((fieldval & ~field##_MASK) != 0);		\
> +		fieldval & field##_MASK;				\
> +	 })
> +
> +#define VC4_GET_FIELD(word, field) (((word) & field##_MASK) >>		\
> +				    field##_SHIFT)
> +
> +#define V3D_IDENT0   0x00000
> +# define V3D_EXPECTED_IDENT0 \
> +	((2 << 24) | \
> +	('V' << 0) | \
> +	('3' << 8) | \
> +	 ('D' << 16))
> +
> +#define V3D_IDENT1   0x00004
> +/* Multiples of 1kb */
> +# define V3D_IDENT1_VPM_SIZE_MASK                      VC4_MASK(31, 28)
> +# define V3D_IDENT1_VPM_SIZE_SHIFT                     28
> +# define V3D_IDENT1_NSEM_MASK                          VC4_MASK(23, 16)
> +# define V3D_IDENT1_NSEM_SHIFT                         16
> +# define V3D_IDENT1_TUPS_MASK                          VC4_MASK(15, 12)
> +# define V3D_IDENT1_TUPS_SHIFT                         12
> +# define V3D_IDENT1_QUPS_MASK                          VC4_MASK(11, 8)
> +# define V3D_IDENT1_QUPS_SHIFT                         8
> +# define V3D_IDENT1_NSLC_MASK                          VC4_MASK(7, 4)
> +# define V3D_IDENT1_NSLC_SHIFT                         4
> +# define V3D_IDENT1_REV_MASK                           VC4_MASK(3, 0)
> +# define V3D_IDENT1_REV_SHIFT                          0
> +
> +#define V3D_IDENT2   0x00008
> +#define V3D_SCRATCH  0x00010
> +#define V3D_L2CACTL  0x00020
> +# define V3D_L2CACTL_L2CCLR                            (1 << 2)
> +# define V3D_L2CACTL_L2CDIS                            (1 << 1)
> +# define V3D_L2CACTL_L2CENA                            (1 << 0)
> +
> +#define V3D_SLCACTL  0x00024
> +# define V3D_SLCACTL_T1CC_MASK                         VC4_MASK(27, 24)
> +# define V3D_SLCACTL_T1CC_SHIFT                        24
> +# define V3D_SLCACTL_T0CC_MASK                         VC4_MASK(19, 16)
> +# define V3D_SLCACTL_T0CC_SHIFT                        16
> +# define V3D_SLCACTL_UCC_MASK                          VC4_MASK(11, 8)
> +# define V3D_SLCACTL_UCC_SHIFT                         8
> +# define V3D_SLCACTL_ICC_MASK                          VC4_MASK(3, 0)
> +# define V3D_SLCACTL_ICC_SHIFT                         0
> +
> +#define V3D_INTCTL   0x00030
> +#define V3D_INTENA   0x00034
> +#define V3D_INTDIS   0x00038
> +# define V3D_INT_SPILLUSE                              (1 << 3)
> +# define V3D_INT_OUTOMEM                               (1 << 2)
> +# define V3D_INT_FLDONE                                (1 << 1)
> +# define V3D_INT_FRDONE                                (1 << 0)
> +
> +#define V3D_CT0CS    0x00100
> +#define V3D_CT1CS    0x00104
> +#define V3D_CTNCS(n) (V3D_CT0CS + 4 * n)
> +# define V3D_CTRSTA      (1 << 15)
> +# define V3D_CTSEMA      (1 << 12)
> +# define V3D_CTRTSD      (1 << 8)
> +# define V3D_CTRUN       (1 << 5)
> +# define V3D_CTSUBS      (1 << 4)
> +# define V3D_CTERR       (1 << 3)
> +# define V3D_CTMODE      (1 << 0)
> +
> +#define V3D_CT0EA    0x00108
> +#define V3D_CT1EA    0x0010c
> +#define V3D_CTNEA(n) (V3D_CT0EA + 4 * (n))
> +#define V3D_CT0CA    0x00110
> +#define V3D_CT1CA    0x00114
> +#define V3D_CTNCA(n) (V3D_CT0CA + 4 * (n))
> +#define V3D_CT00RA0  0x00118
> +#define V3D_CT01RA0  0x0011c
> +#define V3D_CTNRA0(n) (V3D_CT00RA0 + 4 * (n))
> +#define V3D_CT0LC    0x00120
> +#define V3D_CT1LC    0x00124
> +#define V3D_CTNLC(n) (V3D_CT0LC + 4 * (n))
> +#define V3D_CT0PC    0x00128
> +#define V3D_CT1PC    0x0012c
> +#define V3D_CTNPC(n) (V3D_CT0PC + 4 * (n))
> +
> +#define V3D_PCS      0x00130
> +# define V3D_BMOOM       (1 << 8)
> +# define V3D_RMBUSY      (1 << 3)
> +# define V3D_RMACTIVE    (1 << 2)
> +# define V3D_BMBUSY      (1 << 1)
> +# define V3D_BMACTIVE    (1 << 0)
> +
> +#define V3D_BFC      0x00134
> +#define V3D_RFC      0x00138
> +#define V3D_BPCA     0x00300
> +#define V3D_BPCS     0x00304
> +#define V3D_BPOA     0x00308
> +#define V3D_BPOS     0x0030c
> +#define V3D_BXCF     0x00310
> +#define V3D_SQRSV0   0x00410
> +#define V3D_SQRSV1   0x00414
> +#define V3D_SQCNTL   0x00418
> +#define V3D_SRQPC    0x00430
> +#define V3D_SRQUA    0x00434
> +#define V3D_SRQUL    0x00438
> +#define V3D_SRQCS    0x0043c
> +#define V3D_VPACNTL  0x00500
> +#define V3D_VPMBASE  0x00504
> +#define V3D_PCTRC    0x00670
> +#define V3D_PCTRE    0x00674
> +#define V3D_PCTR0    0x00680
> +#define V3D_PCTRS0   0x00684
> +#define V3D_PCTR1    0x00688
> +#define V3D_PCTRS1   0x0068c
> +#define V3D_PCTR2    0x00690
> +#define V3D_PCTRS2   0x00694
> +#define V3D_PCTR3    0x00698
> +#define V3D_PCTRS3   0x0069c
> +#define V3D_PCTR4    0x006a0
> +#define V3D_PCTRS4   0x006a4
> +#define V3D_PCTR5    0x006a8
> +#define V3D_PCTRS5   0x006ac
> +#define V3D_PCTR6    0x006b0
> +#define V3D_PCTRS6   0x006b4
> +#define V3D_PCTR7    0x006b8
> +#define V3D_PCTRS7   0x006bc
> +#define V3D_PCTR8    0x006c0
> +#define V3D_PCTRS8   0x006c4
> +#define V3D_PCTR9    0x006c8
> +#define V3D_PCTRS9   0x006cc
> +#define V3D_PCTR10   0x006d0
> +#define V3D_PCTRS10  0x006d4
> +#define V3D_PCTR11   0x006d8
> +#define V3D_PCTRS11  0x006dc
> +#define V3D_PCTR12   0x006e0
> +#define V3D_PCTRS12  0x006e4
> +#define V3D_PCTR13   0x006e8
> +#define V3D_PCTRS13  0x006ec
> +#define V3D_PCTR14   0x006f0
> +#define V3D_PCTRS14  0x006f4
> +#define V3D_PCTR15   0x006f8
> +#define V3D_PCTRS15  0x006fc
> +#define V3D_BGE      0x00f00
> +#define V3D_FDBGO    0x00f04
> +#define V3D_FDBGB    0x00f08
> +#define V3D_FDBGR    0x00f0c
> +#define V3D_FDBGS    0x00f10
> +#define V3D_ERRSTAT  0x00f20
> +
> +#define PV_CONTROL				0x00
> +# define PV_CONTROL_FORMAT_MASK			VC4_MASK(23, 21)
> +# define PV_CONTROL_FORMAT_SHIFT		21
> +# define PV_CONTROL_FORMAT_24			0
> +# define PV_CONTROL_FORMAT_DSIV_16		1
> +# define PV_CONTROL_FORMAT_DSIC_16		2
> +# define PV_CONTROL_FORMAT_DSIV_18		3
> +# define PV_CONTROL_FORMAT_DSIV_24		4
> +
> +# define PV_CONTROL_FIFO_LEVEL_MASK		VC4_MASK(20, 15)
> +# define PV_CONTROL_FIFO_LEVEL_SHIFT		15
> +# define PV_CONTROL_CLR_AT_START		(1 << 14)
> +# define PV_CONTROL_TRIGGER_UNDERFLOW		(1 << 13)
> +# define PV_CONTROL_WAIT_HSTART			(1 << 12)
> +# define PV_CONTROL_CLK_SELECT_DSI		0
> +# define PV_CONTROL_CLK_SELECT_DPI_SMI_HDMI	1
> +# define PV_CONTROL_CLK_SELECT_MASK		VC4_MASK(3, 2)
> +# define PV_CONTROL_CLK_SELECT_SHIFT		2
> +# define PV_CONTROL_FIFO_CLR			(1 << 1)
> +# define PV_CONTROL_EN				(1 << 0)
> +
> +#define PV_V_CONTROL				0x04
> +# define PV_VCONTROL_CONTINUOUS			(1 << 1)
> +# define PV_VCONTROL_VIDEN			(1 << 0)
> +
> +#define PV_VSYNCD				0x08
> +
> +#define PV_HORZA				0x0c
> +# define PV_HORZA_HBP_MASK			VC4_MASK(31, 16)
> +# define PV_HORZA_HBP_SHIFT			16
> +# define PV_HORZA_HSYNC_MASK			VC4_MASK(15, 0)
> +# define PV_HORZA_HSYNC_SHIFT			0
> +
> +#define PV_HORZB				0x10
> +# define PV_HORZB_HFP_MASK			VC4_MASK(31, 16)
> +# define PV_HORZB_HFP_SHIFT			16
> +# define PV_HORZB_HACTIVE_MASK			VC4_MASK(15, 0)
> +# define PV_HORZB_HACTIVE_SHIFT			0
> +
> +#define PV_VERTA				0x14
> +# define PV_VERTA_VBP_MASK			VC4_MASK(31, 16)
> +# define PV_VERTA_VBP_SHIFT			16
> +# define PV_VERTA_VSYNC_MASK			VC4_MASK(15, 0)
> +# define PV_VERTA_VSYNC_SHIFT			0
> +
> +#define PV_VERTB				0x18
> +# define PV_VERTB_VFP_MASK			VC4_MASK(31, 16)
> +# define PV_VERTB_VFP_SHIFT			16
> +# define PV_VERTB_VACTIVE_MASK			VC4_MASK(15, 0)
> +# define PV_VERTB_VACTIVE_SHIFT			0
> +
> +#define PV_VERTA_EVEN				0x1c
> +#define PV_VERTB_EVEN				0x20
> +
> +#define PV_INTEN				0x24
> +#define PV_INTSTAT				0x28
> +# define PV_INT_VID_IDLE			(1 << 9)
> +# define PV_INT_VFP_END				(1 << 8)
> +# define PV_INT_VFP_START			(1 << 7)
> +# define PV_INT_VACT_START			(1 << 6)
> +# define PV_INT_VBP_START			(1 << 5)
> +# define PV_INT_VSYNC_START			(1 << 4)
> +# define PV_INT_HFP_START			(1 << 3)
> +# define PV_INT_HACT_START			(1 << 2)
> +# define PV_INT_HBP_START			(1 << 1)
> +# define PV_INT_HSYNC_START			(1 << 0)
> +
> +#define PV_STAT					0x2c
> +
> +#define PV_HACT_ACT				0x30
> +
> +#define SCALER_DISPCTRL                         0x00000000
> +/* Global register for clock gating the HVS */
> +# define SCALER_DISPCTRL_ENABLE			(1 << 31)
> +# define SCALER_DISPCTRL_DSP2EISLUR		(1 << 15)
> +# define SCALER_DISPCTRL_DSP1EISLUR		(1 << 14)
> +/* Enables Display 0 short line and underrun contribution to
> + * SCALER_DISPSTAT_IRQDISP0.  Note that short frame contributions are
> + * always enabled.
> + */
> +# define SCALER_DISPCTRL_DSP0EISLUR		(1 << 13)
> +# define SCALER_DISPCTRL_DSP2EIEOLN		(1 << 12)
> +# define SCALER_DISPCTRL_DSP2EIEOF		(1 << 11)
> +# define SCALER_DISPCTRL_DSP1EIEOLN		(1 << 10)
> +# define SCALER_DISPCTRL_DSP1EIEOF		(1 << 9)
> +/* Enables Display 0 end-of-line-N contribution to
> + * SCALER_DISPSTAT_IRQDISP0
> + */
> +# define SCALER_DISPCTRL_DSP0EIEOLN		(1 << 8)
> +/* Enables Display 0 EOF contribution to SCALER_DISPSTAT_IRQDISP0 */
> +# define SCALER_DISPCTRL_DSP0EIEOF		(1 << 7)
> +
> +# define SCALER_DISPCTRL_SLVRDEIRQ		(1 << 6)
> +# define SCALER_DISPCTRL_SLVWREIRQ		(1 << 5)
> +# define SCALER_DISPCTRL_DMAEIRQ		(1 << 4)
> +# define SCALER_DISPCTRL_DISP2EIRQ		(1 << 3)
> +# define SCALER_DISPCTRL_DISP1EIRQ		(1 << 2)
> +/* Enables interrupt generation on the enabled EOF/EOLN/EISLUR
> + * bits and short frames..
> + */
> +# define SCALER_DISPCTRL_DISP0EIRQ		(1 << 1)
> +/* Enables interrupt generation on scaler profiler interrupt. */
> +# define SCALER_DISPCTRL_SCLEIRQ		(1 << 0)
> +
> +#define SCALER_DISPSTAT                         0x00000004
> +# define SCALER_DISPSTAT_COBLOW2		(1 << 29)
> +# define SCALER_DISPSTAT_EOLN2			(1 << 28)
> +# define SCALER_DISPSTAT_ESFRAME2		(1 << 27)
> +# define SCALER_DISPSTAT_ESLINE2		(1 << 26)
> +# define SCALER_DISPSTAT_EUFLOW2		(1 << 25)
> +# define SCALER_DISPSTAT_EOF2			(1 << 24)
> +
> +# define SCALER_DISPSTAT_COBLOW1		(1 << 21)
> +# define SCALER_DISPSTAT_EOLN1			(1 << 20)
> +# define SCALER_DISPSTAT_ESFRAME1		(1 << 19)
> +# define SCALER_DISPSTAT_ESLINE1		(1 << 18)
> +# define SCALER_DISPSTAT_EUFLOW1		(1 << 17)
> +# define SCALER_DISPSTAT_EOF1			(1 << 16)
> +
> +# define SCALER_DISPSTAT_RESP_MASK		VC4_MASK(15, 14)
> +# define SCALER_DISPSTAT_RESP_SHIFT		14
> +# define SCALER_DISPSTAT_RESP_OKAY		0
> +# define SCALER_DISPSTAT_RESP_EXOKAY		1
> +# define SCALER_DISPSTAT_RESP_SLVERR		2
> +# define SCALER_DISPSTAT_RESP_DECERR		3
> +
> +# define SCALER_DISPSTAT_COBLOW0		(1 << 13)
> +/* Set when the DISPEOLN line is done compositing. */
> +# define SCALER_DISPSTAT_EOLN0			(1 << 12)
> +/* Set when VSTART is seen but there are still pixels in the current
> + * output line.
> + */
> +# define SCALER_DISPSTAT_ESFRAME0		(1 << 11)
> +/* Set when HSTART is seen but there are still pixels in the current
> + * output line.
> + */
> +# define SCALER_DISPSTAT_ESLINE0		(1 << 10)
> +/* Set when the the downstream tries to read from the display FIFO
> + * while it's empty.
> + */
> +# define SCALER_DISPSTAT_EUFLOW0		(1 << 9)
> +/* Set when the display mode changes from RUN to EOF */
> +# define SCALER_DISPSTAT_EOF0			(1 << 8)
> +
> +/* Set on AXI invalid DMA ID error. */
> +# define SCALER_DISPSTAT_DMA_ERROR		(1 << 7)
> +/* Set on AXI slave read decode error */
> +# define SCALER_DISPSTAT_IRQSLVRD		(1 << 6)
> +/* Set on AXI slave write decode error */
> +# define SCALER_DISPSTAT_IRQSLVWR		(1 << 5)
> +/* Set when SCALER_DISPSTAT_DMA_ERROR is set, or
> + * SCALER_DISPSTAT_RESP_ERROR is not SCALER_DISPSTAT_RESP_OKAY.
> + */
> +# define SCALER_DISPSTAT_IRQDMA			(1 << 4)
> +# define SCALER_DISPSTAT_IRQDISP2		(1 << 3)
> +# define SCALER_DISPSTAT_IRQDISP1		(1 << 2)
> +/* Set when any of the EOF/EOLN/ESFRAME/ESLINE bits are set and their
> + * corresponding interrupt bit is enabled in DISPCTRL.
> + */
> +# define SCALER_DISPSTAT_IRQDISP0		(1 << 1)
> +/* On read, the profiler interrupt.  On write, clear *all* interrupt bits. */
> +# define SCALER_DISPSTAT_IRQSCL			(1 << 0)
> +
> +#define SCALER_DISPID                           0x00000008
> +#define SCALER_DISPECTRL                        0x0000000c
> +#define SCALER_DISPPROF                         0x00000010
> +#define SCALER_DISPDITHER                       0x00000014
> +#define SCALER_DISPEOLN                         0x00000018
> +#define SCALER_DISPLIST0                        0x00000020
> +#define SCALER_DISPLIST1                        0x00000024
> +#define SCALER_DISPLIST2                        0x00000028
> +#define SCALER_DISPLSTAT                        0x0000002c
> +#define SCALER_DISPLISTX(x)			(SCALER_DISPLIST0 +	\
> +						 (x) * (SCALER_DISPLIST1 - \
> +							SCALER_DISPLIST0))
> +
> +#define SCALER_DISPLACT0                        0x00000030
> +#define SCALER_DISPLACT1                        0x00000034
> +#define SCALER_DISPLACT2                        0x00000038
> +#define SCALER_DISPCTRL0                        0x00000040
> +# define SCALER_DISPCTRLX_ENABLE		(1 << 31)
> +# define SCALER_DISPCTRLX_RESET			(1 << 30)
> +# define SCALER_DISPCTRLX_WIDTH_MASK		VC4_MASK(23, 12)
> +# define SCALER_DISPCTRLX_WIDTH_SHIFT		12
> +# define SCALER_DISPCTRLX_HEIGHT_MASK		VC4_MASK(11, 0)
> +# define SCALER_DISPCTRLX_HEIGHT_SHIFT		0
> +
> +#define SCALER_DISPBKGND0                       0x00000044
> +#define SCALER_DISPSTAT0                        0x00000048
> +#define SCALER_DISPBASE0                        0x0000004c
> +# define SCALER_DISPSTATX_MODE_MASK		VC4_MASK(31, 30)
> +# define SCALER_DISPSTATX_MODE_SHIFT		30
> +# define SCALER_DISPSTATX_MODE_DISABLED		0
> +# define SCALER_DISPSTATX_MODE_INIT		1
> +# define SCALER_DISPSTATX_MODE_RUN		2
> +# define SCALER_DISPSTATX_MODE_EOF		3
> +# define SCALER_DISPSTATX_FULL			(1 << 29)
> +# define SCALER_DISPSTATX_EMPTY			(1 << 28)
> +#define SCALER_DISPCTRL1                        0x00000050
> +#define SCALER_DISPBKGND1                       0x00000054
> +#define SCALER_DISPSTAT1                        0x00000058
> +#define SCALER_DISPSTATX(x)			(SCALER_DISPSTAT0 +        \
> +						 (x) * (SCALER_DISPSTAT1 - \
> +							SCALER_DISPSTAT0))
> +#define SCALER_DISPBASE1                        0x0000005c
> +#define SCALER_DISPCTRL2                        0x00000060
> +#define SCALER_DISPCTRLX(x)			(SCALER_DISPCTRL0 +        \
> +						 (x) * (SCALER_DISPCTRL1 - \
> +							SCALER_DISPCTRL0))
> +#define SCALER_DISPBKGND2                       0x00000064
> +#define SCALER_DISPSTAT2                        0x00000068
> +#define SCALER_DISPBASE2                        0x0000006c
> +#define SCALER_DISPALPHA2                       0x00000070
> +#define SCALER_GAMADDR                          0x00000078
> +#define SCALER_GAMDATA                          0x000000e0
> +#define SCALER_DLIST_START                      0x00002000
> +#define SCALER_DLIST_SIZE                       0x00004000
> +
> +#define VC4_HDMI_CORE_REV			0x000
> +
> +#define VC4_HDMI_SW_RESET_CONTROL		0x004
> +# define VC4_HDMI_SW_RESET_FORMAT_DETECT	(1 << 1)
> +# define VC4_HDMI_SW_RESET_HDMI			(1 << 0)
> +
> +#define VC4_HDMI_HOTPLUG_INT			0x008
> +
> +#define VC4_HDMI_HOTPLUG			0x00c
> +# define VC4_HDMI_HOTPLUG_CONNECTED		(1 << 0)
> +
> +#define VC4_HDMI_RAM_PACKET_CONFIG		0x0a0
> +# define VC4_HDMI_RAM_PACKET_ENABLE		(1 << 16)
> +
> +#define VC4_HDMI_HORZA				0x0c4
> +# define VC4_HDMI_HORZA_VPOS			(1 << 14)
> +# define VC4_HDMI_HORZA_HPOS			(1 << 13)
> +/* Horizontal active pixels (hdisplay). */
> +# define VC4_HDMI_HORZA_HAP_MASK		VC4_MASK(12, 0)
> +# define VC4_HDMI_HORZA_HAP_SHIFT		0
> +
> +#define VC4_HDMI_HORZB				0x0c8
> +/* Horizontal pack porch (htotal - hsync_end). */
> +# define VC4_HDMI_HORZB_HBP_MASK		VC4_MASK(29, 20)
> +# define VC4_HDMI_HORZB_HBP_SHIFT		20
> +/* Horizontal sync pulse (hsync_end - hsync_start). */
> +# define VC4_HDMI_HORZB_HSP_MASK		VC4_MASK(19, 10)
> +# define VC4_HDMI_HORZB_HSP_SHIFT		10
> +/* Horizontal front porch (hsync_start - hdisplay). */
> +# define VC4_HDMI_HORZB_HFP_MASK		VC4_MASK(9, 0)
> +# define VC4_HDMI_HORZB_HFP_SHIFT		0
> +
> +#define VC4_HDMI_FIFO_CTL			0x05c
> +# define VC4_HDMI_FIFO_CTL_RECENTER_DONE	(1 << 14)
> +# define VC4_HDMI_FIFO_CTL_USE_EMPTY		(1 << 13)
> +# define VC4_HDMI_FIFO_CTL_ON_VB		(1 << 7)
> +# define VC4_HDMI_FIFO_CTL_RECENTER		(1 << 6)
> +# define VC4_HDMI_FIFO_CTL_FIFO_RESET		(1 << 5)
> +# define VC4_HDMI_FIFO_CTL_USE_PLL_LOCK		(1 << 4)
> +# define VC4_HDMI_FIFO_CTL_INV_CLK_XFR		(1 << 3)
> +# define VC4_HDMI_FIFO_CTL_CAPTURE_PTR		(1 << 2)
> +# define VC4_HDMI_FIFO_CTL_USE_FULL		(1 << 1)
> +# define VC4_HDMI_FIFO_CTL_MASTER_SLAVE_N	(1 << 0)
> +# define VC4_HDMI_FIFO_VALID_WRITE_MASK		0xefff
> +
> +#define VC4_HDMI_SCHEDULER_CONTROL		0x0c0
> +# define VC4_HDMI_SCHEDULER_CONTROL_MANUAL_FORMAT (1 << 15)
> +# define VC4_HDMI_SCHEDULER_CONTROL_IGNORE_VSYNC_PREDICTS (1 << 5)
> +# define VC4_HDMI_SCHEDULER_CONTROL_VERT_ALWAYS_KEEPOUT	(1 << 3)
> +# define VC4_HDMI_SCHEDULER_CONTROL_HDMI_ACTIVE	(1 << 1)
> +# define VC4_HDMI_SCHEDULER_CONTROL_MODE_HDMI	(1 << 0)
> +
> +#define VC4_HDMI_VERTA0				0x0cc
> +#define VC4_HDMI_VERTA1				0x0d4
> +/* Vertical sync pulse (vsync_end - vsync_start). */
> +# define VC4_HDMI_VERTA_VSP_MASK		VC4_MASK(24, 20)
> +# define VC4_HDMI_VERTA_VSP_SHIFT		20
> +/* Vertical front porch (vsync_start - vdisplay). */
> +# define VC4_HDMI_VERTA_VFP_MASK		VC4_MASK(19, 13)
> +# define VC4_HDMI_VERTA_VFP_SHIFT		13
> +/* Vertical active lines (vdisplay). */
> +# define VC4_HDMI_VERTA_VAL_MASK		VC4_MASK(12, 0)
> +# define VC4_HDMI_VERTA_VAL_SHIFT		0
> +
> +#define VC4_HDMI_VERTB0				0x0d0
> +#define VC4_HDMI_VERTB1				0x0d8
> +/* Vertical sync pulse offset (for interlaced) */
> +# define VC4_HDMI_VERTB_VSPO_MASK		VC4_MASK(21, 9)
> +# define VC4_HDMI_VERTB_VSPO_SHIFT		9
> +/* Vertical pack porch (vtotal - vsync_end). */
> +# define VC4_HDMI_VERTB_VBP_MASK		VC4_MASK(8, 0)
> +# define VC4_HDMI_VERTB_VBP_SHIFT		0
> +
> +#define VC4_HDMI_TX_PHY_RESET_CTL		0x2c0
> +
> +#define VC4_HD_M_CTL				0x00c
> +# define VC4_HD_M_SW_RST			(1 << 2)
> +# define VC4_HD_M_ENABLE			(1 << 0)
> +
> +#define VC4_HD_MAI_CTL				0x014
> +
> +#define VC4_HD_VID_CTL				0x038
> +# define VC4_HD_VID_CTL_ENABLE			(1 << 31)
> +# define VC4_HD_VID_CTL_UNDERFLOW_ENABLE	(1 << 30)
> +# define VC4_HD_VID_CTL_FRAME_COUNTER_RESET	(1 << 29)
> +# define VC4_HD_VID_CTL_VSYNC_LOW		(1 << 28)
> +# define VC4_HD_VID_CTL_HSYNC_LOW		(1 << 27)
> +
> +#define VC4_HD_CSC_CTL				0x040
> +# define VC4_HD_CSC_CTL_ORDER_MASK		VC4_MASK(7, 5)
> +# define VC4_HD_CSC_CTL_ORDER_SHIFT		5
> +# define VC4_HD_CSC_CTL_ORDER_RGB		0
> +# define VC4_HD_CSC_CTL_ORDER_BGR		1
> +# define VC4_HD_CSC_CTL_ORDER_BRG		2
> +# define VC4_HD_CSC_CTL_ORDER_GRB		3
> +# define VC4_HD_CSC_CTL_ORDER_GBR		4
> +# define VC4_HD_CSC_CTL_ORDER_RBG		5
> +# define VC4_HD_CSC_CTL_PADMSB			(1 << 4)
> +# define VC4_HD_CSC_CTL_MODE_MASK		VC4_MASK(3, 2)
> +# define VC4_HD_CSC_CTL_MODE_SHIFT		2
> +# define VC4_HD_CSC_CTL_MODE_RGB_TO_SD_YPRPB	0
> +# define VC4_HD_CSC_CTL_MODE_RGB_TO_HD_YPRPB	1
> +# define VC4_HD_CSC_CTL_MODE_CUSTOM		2
> +# define VC4_HD_CSC_CTL_RGB2YCC			(1 << 1)
> +# define VC4_HD_CSC_CTL_ENABLE			(1 << 0)
> +
> +#define VC4_HD_FRAME_COUNT			0x068
> +
> +/* HVS display list information. */
> +#define HVS_BOOTLOADER_DLIST_END                32
> +
> +enum hvs_pixel_format {
> +	/* 8bpp */
> +	HVS_PIXEL_FORMAT_RGB332 = 0,
> +	/* 16bpp */
> +	HVS_PIXEL_FORMAT_RGBA4444 = 1,
> +	HVS_PIXEL_FORMAT_RGB555 = 2,
> +	HVS_PIXEL_FORMAT_RGBA5551 = 3,
> +	HVS_PIXEL_FORMAT_RGB565 = 4,
> +	/* 24bpp */
> +	HVS_PIXEL_FORMAT_RGB888 = 5,
> +	HVS_PIXEL_FORMAT_RGBA6666 = 6,
> +	/* 32bpp */
> +	HVS_PIXEL_FORMAT_RGBA8888 = 7
> +};
> +
> +/* Note: the LSB is the rightmost character shown.  Only valid for
> + * HVS_PIXEL_FORMAT_RGB8888, not RGB888.
> + */
> +#define HVS_PIXEL_ORDER_RGBA			0
> +#define HVS_PIXEL_ORDER_BGRA			1
> +#define HVS_PIXEL_ORDER_ARGB			2
> +#define HVS_PIXEL_ORDER_ABGR			3
> +
> +#define HVS_PIXEL_ORDER_XBRG			0
> +#define HVS_PIXEL_ORDER_XRBG			1
> +#define HVS_PIXEL_ORDER_XRGB			2
> +#define HVS_PIXEL_ORDER_XBGR			3
> +
> +#define HVS_PIXEL_ORDER_XYCBCR			0
> +#define HVS_PIXEL_ORDER_XYCRCB			1
> +#define HVS_PIXEL_ORDER_YXCBCR			2
> +#define HVS_PIXEL_ORDER_YXCRCB			3
> +
> +#define SCALER_CTL0_END				(1 << 31)
> +#define SCALER_CTL0_VALID			(1 << 30)
> +
> +#define SCALER_CTL0_SIZE_MASK			VC4_MASK(29, 24)
> +#define SCALER_CTL0_SIZE_SHIFT			24
> +
> +#define SCALER_CTL0_HFLIP                       (1 << 16)
> +#define SCALER_CTL0_VFLIP                       (1 << 15)
> +
> +#define SCALER_CTL0_ORDER_MASK			VC4_MASK(14, 13)
> +#define SCALER_CTL0_ORDER_SHIFT			13
> +
> +/* Set to indicate no scaling. */
> +#define SCALER_CTL0_UNITY			(1 << 4)
> +
> +#define SCALER_CTL0_PIXEL_FORMAT_MASK		VC4_MASK(3, 0)
> +#define SCALER_CTL0_PIXEL_FORMAT_SHIFT		0
> +
> +#define SCALER_POS0_FIXED_ALPHA_MASK		VC4_MASK(31, 24)
> +#define SCALER_POS0_FIXED_ALPHA_SHIFT		24
> +
> +#define SCALER_POS0_START_Y_MASK		VC4_MASK(23, 12)
> +#define SCALER_POS0_START_Y_SHIFT		12
> +
> +#define SCALER_POS0_START_X_MASK		VC4_MASK(11, 0)
> +#define SCALER_POS0_START_X_SHIFT		0
> +
> +#define SCALER_POS2_ALPHA_MODE_MASK		VC4_MASK(31, 30)
> +#define SCALER_POS2_ALPHA_MODE_SHIFT		30
> +#define SCALER_POS2_ALPHA_MODE_PIPELINE		0
> +#define SCALER_POS2_ALPHA_MODE_FIXED		1
> +#define SCALER_POS2_ALPHA_MODE_FIXED_NONZERO	2
> +#define SCALER_POS2_ALPHA_MODE_FIXED_OVER_0x07	3
> +
> +#define SCALER_POS2_HEIGHT_MASK			VC4_MASK(27, 16)
> +#define SCALER_POS2_HEIGHT_SHIFT		16
> +
> +#define SCALER_POS2_WIDTH_MASK			VC4_MASK(11, 0)
> +#define SCALER_POS2_WIDTH_SHIFT			0
> +
> +#define SCALER_SRC_PITCH_MASK			VC4_MASK(15, 0)
> +#define SCALER_SRC_PITCH_SHIFT			0
> -- 
> 2.1.4
> 
> _______________________________________________
> dri-devel mailing list
> dri-devel at lists.freedesktop.org
> http://lists.freedesktop.org/mailman/listinfo/dri-devel

-- 
Daniel Vetter
Software Engineer, Intel Corporation
http://blog.ffwll.ch


From heiko at sntech.de  Thu Aug 13 00:57:24 2015
From: heiko at sntech.de (Heiko =?ISO-8859-1?Q?St=FCbner?=)
Date: Thu, 13 Aug 2015 09:57:24 +0200
Subject: [PATCH 2/2] clk: Convert __clk_get_name(hw->clk) to
 clk_hw_get_name(hw)
In-Reply-To: <1439421161-17868-2-git-send-email-sboyd@codeaurora.org>
References: <1439421161-17868-1-git-send-email-sboyd@codeaurora.org>
 <1439421161-17868-2-git-send-email-sboyd@codeaurora.org>
Message-ID: <1489587.uKDjVe3x3J@diego>

Am Mittwoch, 12. August 2015, 16:12:41 schrieb Stephen Boyd:
> Use the provider based method to get a clock's name so that we
> can get rid of the clk member in struct clk_hw one day. Mostly
> converted with the following coccinelle script.
> 
> @@
> struct clk_hw *E;
> @@
> 
> -__clk_get_name(E->clk)
> +clk_hw_get_name(E)
> 

For the Rockchip part
Reviewed-by: Heiko Stuebner <heiko at sntech.de>


Heiko

> diff --git a/drivers/clk/rockchip/clk-inverter.c
> b/drivers/clk/rockchip/clk-inverter.c index 8054fdb5effb..7cbf43beb3c6
> 100644
> --- a/drivers/clk/rockchip/clk-inverter.c
> +++ b/drivers/clk/rockchip/clk-inverter.c
> @@ -50,7 +50,7 @@ static int rockchip_inv_set_phase(struct clk_hw *hw, int
> degrees) val = !!degrees;
>  	} else {
>  		pr_err("%s: unsupported phase %d for %s\n",
> -		       __func__, degrees, __clk_get_name(hw->clk));
> +		       __func__, degrees, clk_hw_get_name(hw));
>  		return -EINVAL;
>  	}
> 
> diff --git a/drivers/clk/rockchip/clk-mmc-phase.c
> b/drivers/clk/rockchip/clk-mmc-phase.c index 77e19097bdc7..9b613426e968
> 100644
> --- a/drivers/clk/rockchip/clk-mmc-phase.c
> +++ b/drivers/clk/rockchip/clk-mmc-phase.c
> @@ -108,7 +108,7 @@ static int rockchip_mmc_set_phase(struct clk_hw *hw, int
> degrees) writel(HIWORD_UPDATE(raw_value, 0x07ff, mmc_clock->shift),
> mmc_clock->reg);
> 
>  	pr_debug("%s->set_phase(%d) delay_nums=%u reg[0x%p]=0x%03x
> actual_degrees=%d\n", -		__clk_get_name(hw->clk), degrees, delay_num,
> +		clk_hw_get_name(hw), degrees, delay_num,
>  		mmc_clock->reg, raw_value>>(mmc_clock->shift),
>  		rockchip_mmc_get_phase(hw)
>  	);



From hverkuil at xs4all.nl  Thu Aug 13 00:58:16 2015
From: hverkuil at xs4all.nl (Hans Verkuil)
Date: Thu, 13 Aug 2015 09:58:16 +0200
Subject: [PATCH RFC v3 10/16] media: rename link source/sink to
 pad0_source/pad1_sink
In-Reply-To: <30472f0a7f52ee834978c70cbecc5c035ce20f71.1439410053.git.mchehab@osg.samsung.com>
References: <cover.1439410053.git.mchehab@osg.samsung.com>
 <30472f0a7f52ee834978c70cbecc5c035ce20f71.1439410053.git.mchehab@osg.samsung.com>
Message-ID: <55CC4E18.7080605@xs4all.nl>

On 08/12/15 22:14, Mauro Carvalho Chehab wrote:
> Change the internal namespace for links between two pads to
> have the "pad" there.
> 
> We're also numbering it, as a common constructor is to do
> things like:
> 
>  	if (link->port1.type != MEDIA_GRAPH_PAD)
>  		continue;
>  	if (link->pad1_sink->entity == entity)
> 		/* do something */
> 
> by preserving the number, we keep consistency between
> port1 and pad1_sink, and port0 and pad0_source.

I would really leave this patch out. As long as sink and source are consistently
used for pads (and they are), then I see no benefit at all to this change.

Another reason why I don't like this is that pad0_ and pad1_ are actually
confusing since they suggested to me when I first read it that pad0_ referred to
the pad with index 0 and pad1_ referred to the pad with index 1.

That's obviously not the case, but it does mean that the prefix doesn't really
make things clearer.

I would just stick with source and sink.

Regards,

	Hans


From sricharan at codeaurora.org  Thu Aug 13 01:09:15 2015
From: sricharan at codeaurora.org (Sricharan)
Date: Thu, 13 Aug 2015 13:39:15 +0530
Subject: [PATCH 3/5] iommu/msm: Add support for generic master bindings
In-Reply-To: <55CB9A7D.7080206@codeaurora.org>
References: <1439390869-6347-1-git-send-email-sricharan@codeaurora.org>
 <1439390869-6347-4-git-send-email-sricharan@codeaurora.org>
 <55CB9A7D.7080206@codeaurora.org>
Message-ID: <000801d0d59f$5d017f80$17047e80$@codeaurora.org>

Hi Stephen,

> -----Original Message-----
> From: Stephen Boyd [mailto:sboyd at codeaurora.org]
> Sent: Thursday, August 13, 2015 12:42 AM
> To: Sricharan R
> Cc: linux-arm-kernel at lists.infradead.org;
iommu at lists.linux-foundation.org;
> devicetree at vger.kernel.org; linux-arm-msm at vger.kernel.org;
> robin.murphy at arm.com; robdclark at gmail.com; joro at 8bytes.org;
> srinivas.kandagatla at linaro.org; laurent.pinchart at ideasonboard.com;
> Will.Deacon at arm.com; stepanm at codeaurora.org; treding at nvidia.com
> Subject: Re: [PATCH 3/5] iommu/msm: Add support for generic master
> bindings
> 
> On 08/12/2015 07:47 AM, Sricharan R wrote:
> > @@ -702,6 +703,44 @@ static void print_ctx_regs(void __iomem *base,
> int ctx)
> >   	       GET_PRRR(base, ctx), GET_NMRR(base, ctx));
> >   }
> >
> > +static void insert_iommu_master(struct device *dev,
> > +				struct msm_iommu_dev *iommu,
> > +				struct of_phandle_args *spec)
> > +{
> > +	struct msm_iommu_ctx_dev *master;
> > +	int sid;
> > +
> > +	master = kzalloc(sizeof(*master), GFP_KERNEL);
> 
> This is called with irqs disabled, but it's not GFP_ATOMIC. Please test
with
> DEBUG_ATOMIC_SLEEP=y.

    Ok. I will have to adjust the locking here. It should be granular only
for the list manipulation.
> 
> > +	master->of_node = dev->of_node;
> > +	list_add(&master->list, &iommu->ctx_list);
> > +
> > +	for (sid = 0; sid < spec->args_count; sid++)
> > +		master->mids[sid] = spec->args[sid];
> > +
> > +	master->num_mids = spec->args_count; }
> > +
> > +static int qcom_iommu_of_xlate(struct device *dev,
> > +			       struct of_phandle_args *spec) {
> > +	struct msm_iommu_dev *iommu;
> > +	unsigned long flags;
> > +
> > +	spin_lock_irqsave(&msm_iommu_lock, flags);
> > +	list_for_each_entry(iommu, &qcom_iommu_devices, dev_node) {
> > +		if (iommu->dev->of_node == spec->np)
> > +			break;
> > +	}
> 
> The braces are unnecessary here.
 Ok, will remove this.
> 
> > +
> > +	if (!iommu || (iommu->dev->of_node != spec->np))
> 
> Please remove extraneous parentheses.
> 
 Ok.

> > +		return -ENODEV;
> > +
> > +	insert_iommu_master(dev, iommu, spec);
> > +	spin_unlock_irqrestore(&msm_iommu_lock, flags);
> > +
> > +	return 0;
> > +}
> > +
> >   irqreturn_t msm_iommu_fault_handler(int irq, void *dev_id)
> >   {
> >   	struct msm_iommu_dev *iommu = dev_id; @@ -737,7 +776,7 @@
> fail:
> >   	return 0;
> >   }
> >
> > -static const struct iommu_ops msm_iommu_ops = {
> > +static struct iommu_ops msm_iommu_ops = {
> 
> Is there a reason why we can't make of_iommu_set_ops() take a const ops
> pointer?
> 
  Hmm right. of_iommu_set_ops is the one that needs change. I will add a
separate
  patch to correct that.

Regards,
 Sricharan



From j.anaszewski at samsung.com  Thu Aug 13 01:10:00 2015
From: j.anaszewski at samsung.com (Jacek Anaszewski)
Date: Thu, 13 Aug 2015 10:10:00 +0200
Subject: [PATCH v1 RFC] This patch repairs HTC Magician machine (PXA27x)
 support
In-Reply-To: <55CBCDED.8010409@tul.cz>
References: <55CBCDED.8010409@tul.cz>
Message-ID: <55CC50D8.5000706@samsung.com>

Hi Petr,

This is review only of the LED subsystem related part of this patch,.

On 08/13/2015 12:51 AM, Petr Cvek wrote:
> Fixing original code: Problems to successful boot due to the bad LCD
> power sequence (wrongly configured GPIO).
>
> Add/fix platform data and helper function for various hardware
> (touchscreen, audio, USB device, ...).
>
> Add new discovered GPIOs and fix names by GPIO context.
>
> Add new LEDs driver.
>
> Signed-off-by: Petr Cvek <petr.cvek at tul.cz>
> ---
>   arch/arm/mach-pxa/Kconfig                 |    1 +
>   arch/arm/mach-pxa/include/mach/magician.h |   21 +-
>   arch/arm/mach-pxa/magician.c              | 1148 +++++++++++++++++++++++------
>   drivers/leds/Kconfig                      |    9 +
>   drivers/leds/Makefile                     |    1 +
>   drivers/leds/leds-pasic3.c                |  192 +++++
>   drivers/mfd/htc-pasic3.c                  |  115 ++-
>   include/linux/mfd/htc-pasic3.h            |   69 +-
>   8 files changed, 1293 insertions(+), 263 deletions(-)
>   create mode 100644 drivers/leds/leds-pasic3.c
>

[...]

> diff --git a/drivers/leds/Kconfig b/drivers/leds/Kconfig
> index 9ad35f7..516ba65 100644
> --- a/drivers/leds/Kconfig
> +++ b/drivers/leds/Kconfig
> @@ -586,6 +586,15 @@ config LEDS_PM8941_WLED
>   	  This option enables support for the 'White' LED block
>   	  on Qualcomm PM8941 PMICs.
>
> +config LEDS_PASIC3
> +	tristate "LED support for the HTC Magician/Alpine PASIC3"
> +	depends on LEDS_CLASS
> +	depends on HTC_PASIC3
> +	select REGMAP
> +	help
> +	  This option enables support for the PASIC3 chip (different chip
> +	  than Compaq ASIC3).
> +
>   comment "LED Triggers"
>   source "drivers/leds/trigger/Kconfig"
>
> diff --git a/drivers/leds/Makefile b/drivers/leds/Makefile
> index 8d6a24a..b1c659c 100644
> --- a/drivers/leds/Makefile
> +++ b/drivers/leds/Makefile
> @@ -65,6 +65,7 @@ obj-$(CONFIG_LEDS_VERSATILE)		+= leds-versatile.o
>   obj-$(CONFIG_LEDS_MENF21BMC)		+= leds-menf21bmc.o
>   obj-$(CONFIG_LEDS_PM8941_WLED)		+= leds-pm8941-wled.o
>   obj-$(CONFIG_LEDS_KTD2692)		+= leds-ktd2692.o
> +obj-$(CONFIG_LEDS_PASIC3)		+= leds-pasic3.o
>
>   # LED SPI Drivers
>   obj-$(CONFIG_LEDS_DAC124S085)		+= leds-dac124s085.o
> diff --git a/drivers/leds/leds-pasic3.c b/drivers/leds/leds-pasic3.c
> new file mode 100644
> index 0000000..ecb0557
> --- /dev/null
> +++ b/drivers/leds/leds-pasic3.c
> @@ -0,0 +1,192 @@
> +/*
> + * AIC3 (or PASIC3) LED driver for HTC Magician/Alpine/.. (not Compaq ASIC3)
> + *
> + * Copyright (c) 2015 Petr Cvek <petr.cvek at tul.cz>
> + *
> + * Based on leds-asic3.c driver
> + *
> + * This program is free software; you can redistribute it and/or modify
> + * it under the terms of the GNU General Public License version 2 as
> + * published by the Free Software Foundation.
> + *
> + */
> +
> +#include <linux/kernel.h>
> +#include <linux/platform_device.h>
> +#include <linux/leds.h>
> +#include <linux/slab.h>
> +

This empty line is not required.

> +#include <linux/mfd/htc-pasic3.h>
> +#include <linux/mfd/core.h>
> +#include <linux/module.h>

Please keep alphabetical order across all includes.

> +/*
> + * 1 tick is around 62-63 ms, blinking settings (on+off):
> + *	Min: 1+1 ticks ~125ms
> + *	Max: 127+127 ticks ~15?875ms
> + * Sometimes takes time to change after write (counter overflow?)
> + */
> +
> +#define MS_TO_CLK(ms)	DIV_ROUND_CLOSEST(((ms)*1024), 64000)
> +#define CLK_TO_MS(clk)	(((clk)*64000)/1024)
> +#define MAX_CLK		254		/* 127 + 127 (2x 7 bit reg) */
> +#define MAX_MS		CLK_TO_MS(MAX_CLK)
> +
> +static void brightness_set(struct led_classdev *cdev,
> +	enum led_brightness value)
> +{
> +	struct platform_device *pdev = to_platform_device(cdev->dev->parent);
> +	const struct mfd_cell *cell = mfd_get_cell(pdev);
> +	struct pasic3_led *led;
> +	struct device *dev;
> +	u8 val;
> +
> +	if (!cell->platform_data) {
> +		pr_err("No platform data\n");
> +		return;
> +	}
> +
> +	led = cell->platform_data;
> +	dev = pdev->dev.parent;
> +
> +	if (value == LED_OFF) {
> +		val = pasic3_read_register(dev, PASIC3_CH_CONTROL);
> +		pasic3_write_register(dev, PASIC3_CH_CONTROL,
> +			val & ~(led->bit_blink_en | led->bit_force_on));
> +
> +		val = pasic3_read_register(dev, PASIC3_MASK_A);
> +		pasic3_write_register(dev, PASIC3_MASK_A, val & ~led->bit_mask);

I think that you need spin_lock protection as setting brightness
is not an atomic operation here. Moreover pasic3_write_register
calls __raw_writeb twice, without spin_lock protection. This function
is used also in drivers/mfd/htc-pasic3.c - shouldn't it be fixed?

> +	} else {
> +		val = pasic3_read_register(dev, PASIC3_CH_CONTROL);
> +		pasic3_write_register(dev, PASIC3_CH_CONTROL,
> +			val | led->bit_force_on);
> +	}
> +}
> +
> +static int blink_set(struct led_classdev *cdev,
> +	unsigned long *delay_on,
> +	unsigned long *delay_off)
> +{
> +	struct platform_device *pdev = to_platform_device(cdev->dev->parent);
> +	const struct mfd_cell *cell = mfd_get_cell(pdev);
> +	struct device *dev;
> +	struct pasic3_led *led;
> +	u32 on, off;
> +	u8 val;
> +
> +	if (!cell->platform_data) {
> +		pr_err("No platform data\n");
> +		return -EINVAL;
> +	}
> +
> +	if (*delay_on > MAX_MS || *delay_off > MAX_MS)
> +		return -EINVAL;
> +
> +	if (*delay_on == 0 && *delay_off == 0) {
> +		/* If both are zero then a sensible default should be chosen */
> +		on = MS_TO_CLK(500);
> +		off = MS_TO_CLK(500);
> +	} else {
> +		on = MS_TO_CLK(*delay_on);
> +		off = MS_TO_CLK(*delay_off);
> +		if ((on + off) > MAX_CLK)
> +			return -EINVAL;
> +		/* Minimal value must be 1 */
> +		on = on ? on : 1;
> +		off = off ? off : 1;
> +	}
> +
> +	led = cell->platform_data;
> +	dev = pdev->dev.parent;
> +
> +	pasic3_write_register(dev, led->reg_delay_on, on);
> +	pasic3_write_register(dev, led->reg_delay_off, off);
> +
> +	val = pasic3_read_register(dev, PASIC3_CH_CONTROL);
> +	pasic3_write_register(dev, PASIC3_CH_CONTROL, val | led->bit_blink_en);

Ditto.

> +	*delay_on = CLK_TO_MS(on);
> +	*delay_off = CLK_TO_MS(off);
> +
> +	return 0;
> +}
> +
> +static int pasic3_led_probe(struct platform_device *pdev)
> +{
> +	struct pasic3_led *led = dev_get_platdata(&pdev->dev);
> +	int ret;
> +
> +	ret = mfd_cell_enable(pdev);
> +	if (ret < 0)
> +		return ret;
> +
> +	led->cdev.flags = LED_CORE_SUSPENDRESUME;
> +	led->cdev.brightness_set = brightness_set;
> +	led->cdev.blink_set = blink_set;

You need to set also led->cdev.name. What is the name of your
LED in the sysfs now?

> +	ret = led_classdev_register(&pdev->dev, &led->cdev);
> +	if (ret < 0)
> +		goto out;

Please use devm_led_classdev_register.

> +	return 0;
> +
> +out:
> +	(void) mfd_cell_disable(pdev);
> +	return ret;
> +}
> +
> +static int pasic3_led_remove(struct platform_device *pdev)
> +{
> +	struct pasic3_led *led = dev_get_platdata(&pdev->dev);
> +
> +	led_classdev_unregister(&led->cdev);
> +
> +	return mfd_cell_disable(pdev);
> +}
> +
> +#ifdef CONFIG_PM_SLEEP
> +static int pasic3_led_suspend(struct device *dev)
> +{
> +	struct platform_device *pdev = to_platform_device(dev);
> +	const struct mfd_cell *cell = mfd_get_cell(pdev);
> +	int ret;
> +
> +	ret = 0;
> +	if (cell->suspend)
> +		ret = (*cell->suspend)(pdev);
> +
> +	return ret;
> +}
> +
> +static int pasic3_led_resume(struct device *dev)
> +{
> +	struct platform_device *pdev = to_platform_device(dev);
> +	const struct mfd_cell *cell = mfd_get_cell(pdev);
> +	int ret;
> +
> +	ret = 0;
> +	if (cell->resume)
> +		ret = (*cell->resume)(pdev);
> +
> +	return ret;
> +}
> +#endif
> +
> +static SIMPLE_DEV_PM_OPS(pasic3_led_pm_ops, pasic3_led_suspend,
> +	pasic3_led_resume);
> +
> +static struct platform_driver pasic3_led_driver = {
> +	.probe		= pasic3_led_probe,
> +	.remove		= pasic3_led_remove,
> +	.driver		= {
> +		.name	= "leds-pasic3",
> +		.pm	= &pasic3_led_pm_ops,
> +	},
> +};
> +
> +module_platform_driver(pasic3_led_driver);
> +
> +MODULE_AUTHOR("Petr Cvek <petr.cvek at tul.cz>");
> +MODULE_DESCRIPTION("HTC Magician PASIC3 LED driver");
> +MODULE_LICENSE("GPL");
> +MODULE_ALIAS("platform:leds-pasic3");

[...]

-- 
Best Regards,
Jacek Anaszewski


From bp at alien8.de  Thu Aug 13 01:15:37 2015
From: bp at alien8.de (Borislav Petkov)
Date: Thu, 13 Aug 2015 10:15:37 +0200
Subject: [PATCH v3 1/4] edac: Add an function to retrieve the EDAC
 debugfs node
In-Reply-To: <CAPw-ZTkfAxqG6HQHU3WomrqRwXa+jyTWCg=ns1HKC323ds1yug@mail.gmail.com>
References: <1439326077-25507-1-git-send-email-lho@apm.com>
 <1439326077-25507-2-git-send-email-lho@apm.com>
 <20150812101219.GC14011@nazgul.tnic>
 <20150812104954.GD14011@nazgul.tnic>
 <CAPw-ZT=AFtyLt4CNGBzLZcdPr-ekJpQxKA4Y_AiDzqKfhF1-=w@mail.gmail.com>
 <CAPw-ZTkfAxqG6HQHU3WomrqRwXa+jyTWCg=ns1HKC323ds1yug@mail.gmail.com>
Message-ID: <20150813081537.GB20004@nazgul.tnic>

On Wed, Aug 12, 2015 at 09:30:58PM -0700, Loc Ho wrote:
> Okay... The 'inline' helps with the compiler warning. If I move all to
> header file with 'static inline' and wrapper around CONFIG_EDAC_DEBUG,
> don't I need to export and declare the variable 'edac_debugfs'? Are
> you okay with export this variable?

You need to make edac_debugfs extern in the header and define it in
edac_mc_sysfs.c.

But that's ok because edac_core.h will be included only by EDAC drivers
and they're supposed to see edac_debugfs anyway...

Thanks.

-- 
Regards/Gruss,
    Boris.

ECO tip #101: Trim your mails when you reply.
--


From mingo at kernel.org  Thu Aug 13 01:16:41 2015
From: mingo at kernel.org (Ingo Molnar)
Date: Thu, 13 Aug 2015 10:16:41 +0200
Subject: [PATCH 0/2] x86/KASAN updates for 4.3
In-Reply-To: <20150813065040.GA17983@gmail.com>
References: <1439444244-26057-1-git-send-email-ryabinin.a.a@gmail.com>
 <20150813065040.GA17983@gmail.com>
Message-ID: <20150813081641.GA14402@gmail.com>


* Ingo Molnar <mingo at kernel.org> wrote:

> 
> * Andrey Ryabinin <ryabinin.a.a at gmail.com> wrote:
> 
> > These 2 patches taken from v5 'KASAN for arm64' series.
> > The only change is updated changelog in second patch.
> > 
> > I hope this is not too late to queue these for 4.3,
> > as this allow us to merge arm64/KASAN patches in v4.4
> > through arm64 tree.
> > 
> > Andrey Ryabinin (2):
> >   x86/kasan: define KASAN_SHADOW_OFFSET per architecture
> >   x86/kasan, mm: introduce generic kasan_populate_zero_shadow()
> > 
> >  arch/x86/include/asm/kasan.h |   3 +
> >  arch/x86/mm/kasan_init_64.c  | 123 ++--------------------------------
> >  include/linux/kasan.h        |  10 ++-
> >  mm/kasan/Makefile            |   2 +-
> >  mm/kasan/kasan_init.c        | 152 +++++++++++++++++++++++++++++++++++++++++++
> >  5 files changed, 170 insertions(+), 120 deletions(-)
> >  create mode 100644 mm/kasan/kasan_init.c
> 
> It's absolutely too late in the -rc cycle for v4.3!

Stupid me, I have read 'v4.2' ...

So yes, it's still good for v4.3, the development window is still open.

The rest still stands:

> I can create a stable topic tree for it, tip:mm/kasan or so, which arm64 could 
> pull and base its own ARM specific work on, if that's OK with everyone.

Thanks,

	Ingo


From linux at arm.linux.org.uk  Thu Aug 13 01:17:44 2015
From: linux at arm.linux.org.uk (Russell King - ARM Linux)
Date: Thu, 13 Aug 2015 09:17:44 +0100
Subject: 3.18: lockdep problems in cpufreq
In-Reply-To: <5160300.5D2Dvly8u9@vostro.rjw.lan>
References: <20141214213655.GA11285@n2100.arm.linux.org.uk>
 <2574268.XBqpdL2VLI@vostro.rjw.lan>
 <20150811170357.GA24529@n2100.arm.linux.org.uk>
 <5160300.5D2Dvly8u9@vostro.rjw.lan>
Message-ID: <20150813081744.GN7557@n2100.arm.linux.org.uk>

On Thu, Aug 13, 2015 at 03:20:35AM +0200, Rafael J. Wysocki wrote:
> On Tuesday, August 11, 2015 06:03:57 PM Russell King - ARM Linux wrote:
> > On Tue, May 19, 2015 at 12:05:55AM +0200, Rafael J. Wysocki wrote:
> > > On Monday, May 18, 2015 07:56:45 PM Russell King - ARM Linux wrote:
> > > > On Tue, Dec 16, 2014 at 09:11:53AM +0530, Viresh Kumar wrote:
> > > > > On 16 December 2014 at 04:39, Russell King - ARM Linux
> > > > > <linux at arm.linux.org.uk> wrote:
> > > > > > Well, here's a patch which I'm running on top of 3.18 at the moment,
> > > > > > which is basically what I described in my email, and I'm running with it
> > > > > > and it is without any lockdep complaint.
> > > > > 
> > > > > We need two separate patches now, one for 3.18 and other one for 3.19-rc.
> > > > > 3.19 has see lots of changes in this particular file and so we need to
> > > > > change few things here.
> > > > 
> > > > What happened with this?  I'm still carrying the patch.
> > > 
> > > This should go in through the thermal tree.  Eduardo?
> > 
> > Having waited a long time for any kind of response from Eduardo, I've
> > given up.  My conclusion is that Eduardo isn't interested in this.
> > 
> > I've re-checked, and the AB-BA deadlock is still there in the latest
> > code.  So, I've taken it upon myself to throw this into my for-next
> > branch to force the issue - not something I _want_ to do, but I'm doing
> > this out of frustration.  It's clear to me that "playing nice" by email
> > does _not_ work with some people.
> > 
> > I'm rather hoping that Stephen reports a merge conflict with linux-next
> > this evening to highlight this situation.  I've added additional commentry
> > to the commit message on the patch giving the reason why I've done this,
> > and the relevant message IDs showing the past history.
> > 
> > I've not decided whether I'm going to ask Linus to take this patch
> > directly or not, that rather depends whether there's any co-operation
> > from Eduardo on this.  I'd rather Eduardo took the patch.
> > 
> > The patch I have has had to be updated again for changes to the driver,
> > but I really don't see the point of re-posting it just for it to be
> > ignored yet again.
> > 
> > I'm really disappointed by this dysfunctional state of affairs, and
> > that what should be an urgent fix for an observable problem is still
> > not merged some nine months after it was first identified.
> 
> I guess it might help if you sent the updated patch in a new thread.

That I doubt.  Eduardo has not bothered to reply at _any_ time.  I
have to question whether there is anyone even reading that email
address, or whether it's a redirect to /dev/null.  All the evidence I
have right now is that this Eduardo is a ficticous character.

I would have at least expected some complaints when I said "I've put
it in linux-next" but... absolutely nothing.

So... my only conclusion is that you're all pulling my leg that there
_is_ this "Eduardo" maintainer who's supposed to be taking patches for
this stuff.

As I've said, I'm not bothering with this anymore, it's just far too
much effort to play these stupid games.  The deadlock can stay for all
I care.

Sorry.

-- 
FTTC broadband for 0.8mile line: currently at 10.5Mbps down 400kbps up
according to speedtest.net.


From lee.jones at linaro.org  Thu Aug 13 01:17:57 2015
From: lee.jones at linaro.org (Lee Jones)
Date: Thu, 13 Aug 2015 09:17:57 +0100
Subject: [PATCH v1 RFC] This patch repairs HTC Magician machine (PXA27x)
 support
In-Reply-To: <55CBCDED.8010409@tul.cz>
References: <55CBCDED.8010409@tul.cz>
Message-ID: <20150813081757.GA8782@x1>

On Thu, 13 Aug 2015, Petr Cvek wrote:

> Fixing original code: Problems to successful boot due to the bad LCD
> power sequence (wrongly configured GPIO).
> 
> Add/fix platform data and helper function for various hardware
> (touchscreen, audio, USB device, ...).
> 
> Add new discovered GPIOs and fix names by GPIO context.
> 
> Add new LEDs driver.
> 
> Signed-off-by: Petr Cvek <petr.cvek at tul.cz>
> ---
>  arch/arm/mach-pxa/Kconfig                 |    1 +
>  arch/arm/mach-pxa/include/mach/magician.h |   21 +-
>  arch/arm/mach-pxa/magician.c              | 1148 +++++++++++++++++++++++------
>  drivers/leds/Kconfig                      |    9 +
>  drivers/leds/Makefile                     |    1 +
>  drivers/leds/leds-pasic3.c                |  192 +++++
>  drivers/mfd/htc-pasic3.c                  |  115 ++-
>  include/linux/mfd/htc-pasic3.h            |   69 +-
>  8 files changed, 1293 insertions(+), 263 deletions(-)
>  create mode 100644 drivers/leds/leds-pasic3.c

I'm pretty sure there aren't strong enough dependence to warrant all
of this code being shoved into a single patch.  Please do what you can
to break it up into simple, manageable pieces which will make the
review and maintenance (patch acceptance) process easier.

[...]

> diff --git a/drivers/leds/leds-pasic3.c b/drivers/leds/leds-pasic3.c
> new file mode 100644
> index 0000000..ecb0557
> --- /dev/null
> +++ b/drivers/leds/leds-pasic3.c
> @@ -0,0 +1,192 @@
> +/*
> + * AIC3 (or PASIC3) LED driver for HTC Magician/Alpine/.. (not Compaq ASIC3)
> + *
> + * Copyright (c) 2015 Petr Cvek <petr.cvek at tul.cz>
> + *
> + * Based on leds-asic3.c driver
> + *
> + * This program is free software; you can redistribute it and/or modify
> + * it under the terms of the GNU General Public License version 2 as
> + * published by the Free Software Foundation.
> + *
> + */
> +
> +#include <linux/kernel.h>
> +#include <linux/platform_device.h>
> +#include <linux/leds.h>
> +#include <linux/slab.h>
> +
> +#include <linux/mfd/htc-pasic3.h>
> +#include <linux/mfd/core.h>
> +#include <linux/module.h>
> +
> +/*
> + * 1 tick is around 62-63 ms, blinking settings (on+off):
> + *	Min: 1+1 ticks ~125ms
> + *	Max: 127+127 ticks ~15?875ms
> + * Sometimes takes time to change after write (counter overflow?)
> + */
> +
> +#define MS_TO_CLK(ms)	DIV_ROUND_CLOSEST(((ms)*1024), 64000)
> +#define CLK_TO_MS(clk)	(((clk)*64000)/1024)
> +#define MAX_CLK		254		/* 127 + 127 (2x 7 bit reg) */
> +#define MAX_MS		CLK_TO_MS(MAX_CLK)
> +
> +static void brightness_set(struct led_classdev *cdev,
> +	enum led_brightness value)
> +{
> +	struct platform_device *pdev = to_platform_device(cdev->dev->parent);
> +	const struct mfd_cell *cell = mfd_get_cell(pdev);

This device should have no idea it's part of an MFD.

Just fetch platform data in the normal way.

> +	struct pasic3_led *led;
> +	struct device *dev;
> +	u8 val;
> +
> +	if (!cell->platform_data) {
> +		pr_err("No platform data\n");
> +		return;
> +	}
> +
> +	led = cell->platform_data;
> +	dev = pdev->dev.parent;
> +
> +	if (value == LED_OFF) {
> +		val = pasic3_read_register(dev, PASIC3_CH_CONTROL);
> +		pasic3_write_register(dev, PASIC3_CH_CONTROL,
> +			val & ~(led->bit_blink_en | led->bit_force_on));
> +
> +		val = pasic3_read_register(dev, PASIC3_MASK_A);
> +		pasic3_write_register(dev, PASIC3_MASK_A, val & ~led->bit_mask);
> +	} else {
> +		val = pasic3_read_register(dev, PASIC3_CH_CONTROL);
> +		pasic3_write_register(dev, PASIC3_CH_CONTROL,
> +			val | led->bit_force_on);
> +	}
> +}
> +
> +static int blink_set(struct led_classdev *cdev,
> +	unsigned long *delay_on,
> +	unsigned long *delay_off)
> +{
> +	struct platform_device *pdev = to_platform_device(cdev->dev->parent);
> +	const struct mfd_cell *cell = mfd_get_cell(pdev);

As above.

> +	struct device *dev;
> +	struct pasic3_led *led;
> +	u32 on, off;
> +	u8 val;
> +
> +	if (!cell->platform_data) {
> +		pr_err("No platform data\n");
> +		return -EINVAL;
> +	}
> +
> +	if (*delay_on > MAX_MS || *delay_off > MAX_MS)
> +		return -EINVAL;
> +
> +	if (*delay_on == 0 && *delay_off == 0) {
> +		/* If both are zero then a sensible default should be chosen */
> +		on = MS_TO_CLK(500);
> +		off = MS_TO_CLK(500);
> +	} else {
> +		on = MS_TO_CLK(*delay_on);
> +		off = MS_TO_CLK(*delay_off);
> +		if ((on + off) > MAX_CLK)
> +			return -EINVAL;
> +		/* Minimal value must be 1 */
> +		on = on ? on : 1;
> +		off = off ? off : 1;
> +	}
> +
> +	led = cell->platform_data;
> +	dev = pdev->dev.parent;
> +
> +	pasic3_write_register(dev, led->reg_delay_on, on);
> +	pasic3_write_register(dev, led->reg_delay_off, off);
> +
> +	val = pasic3_read_register(dev, PASIC3_CH_CONTROL);
> +	pasic3_write_register(dev, PASIC3_CH_CONTROL, val | led->bit_blink_en);
> +
> +	*delay_on = CLK_TO_MS(on);
> +	*delay_off = CLK_TO_MS(off);
> +
> +	return 0;
> +}
> +
> +static int pasic3_led_probe(struct platform_device *pdev)
> +{
> +	struct pasic3_led *led = dev_get_platdata(&pdev->dev);
> +	int ret;
> +
> +	ret = mfd_cell_enable(pdev);
> +	if (ret < 0)
> +		return ret;

That is not what .enable is for, please don't use it.

> +	led->cdev.flags = LED_CORE_SUSPENDRESUME;
> +	led->cdev.brightness_set = brightness_set;
> +	led->cdev.blink_set = blink_set;
> +
> +	ret = led_classdev_register(&pdev->dev, &led->cdev);
> +	if (ret < 0)
> +		goto out;
> +
> +	return 0;
> +
> +out:
> +	(void) mfd_cell_disable(pdev);
> +	return ret;
> +}
> +
> +static int pasic3_led_remove(struct platform_device *pdev)
> +{
> +	struct pasic3_led *led = dev_get_platdata(&pdev->dev);
> +
> +	led_classdev_unregister(&led->cdev);
> +
> +	return mfd_cell_disable(pdev);

Likewise.

> +}
> +
> +#ifdef CONFIG_PM_SLEEP
> +static int pasic3_led_suspend(struct device *dev)
> +{
> +	struct platform_device *pdev = to_platform_device(dev);
> +	const struct mfd_cell *cell = mfd_get_cell(pdev);
> +	int ret;
> +
> +	ret = 0;
> +	if (cell->suspend)
> +		ret = (*cell->suspend)(pdev);
> +
> +	return ret;
> +}
> +
> +static int pasic3_led_resume(struct device *dev)
> +{
> +	struct platform_device *pdev = to_platform_device(dev);
> +	const struct mfd_cell *cell = mfd_get_cell(pdev);
> +	int ret;
> +
> +	ret = 0;
> +	if (cell->resume)
> +		ret = (*cell->resume)(pdev);

Err, no.  Move the cell->resume() code into here.

> +	return ret;
> +}
> +#endif
> +
> +static SIMPLE_DEV_PM_OPS(pasic3_led_pm_ops, pasic3_led_suspend,
> +	pasic3_led_resume);
> +
> +static struct platform_driver pasic3_led_driver = {
> +	.probe		= pasic3_led_probe,
> +	.remove		= pasic3_led_remove,
> +	.driver		= {
> +		.name	= "leds-pasic3",
> +		.pm	= &pasic3_led_pm_ops,
> +	},
> +};
> +
> +module_platform_driver(pasic3_led_driver);
> +
> +MODULE_AUTHOR("Petr Cvek <petr.cvek at tul.cz>");
> +MODULE_DESCRIPTION("HTC Magician PASIC3 LED driver");
> +MODULE_LICENSE("GPL");

v2

> +MODULE_ALIAS("platform:leds-pasic3");
> diff --git a/drivers/mfd/htc-pasic3.c b/drivers/mfd/htc-pasic3.c
> index e88d4f6..3df3f0a 100644
> --- a/drivers/mfd/htc-pasic3.c
> +++ b/drivers/mfd/htc-pasic3.c
> @@ -3,6 +3,9 @@
>   *
>   * Copyright (C) 2006 Philipp Zabel <philipp.zabel at gmail.com>
>   *
> + * LED support:
> + * Copyright (C) 2015 Petr Cvek <petr.cvek at tul.cz>
> + *

You don't need to break up the copyright statements.  Remove the "LED
support" line and the blank line above it.

>   * 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; version 2 of the License.
> @@ -65,8 +68,76 @@ EXPORT_SYMBOL(pasic3_read_register); /* for leds-pasic3 */
>   * LEDs
>   */
>  
> -static struct mfd_cell led_cell __initdata = {
> -	.name = "leds-pasic3",
> +
> +static int pasic3_leds_enable(struct platform_device *pdev)
> +{
> +	const struct mfd_cell *cell = mfd_get_cell(pdev);
> +	struct pasic3_platform_data *pdata = dev_get_platdata(&pdev->dev);
> +	struct pasic3_led *led;
> +
> +	led = cell->platform_data;
> +	pdata = led->pdata;
> +
> +	gpio_set_value(pdata->power_gpio, 1);
> +
> +	return 0;
> +}

You need to re-think this function (you're doing some pretty wacky
stuff in there) and move it into the LED driver.

> +static int pasic3_leds_disable(struct platform_device *pdev)
> +{
> +	const struct mfd_cell *cell = mfd_get_cell(pdev);
> +	struct pasic3_platform_data *pdata = dev_get_platdata(&pdev->dev);
> +	struct pasic3_led *led;
> +
> +	led = cell->platform_data;
> +	pdata = led->pdata;
> +
> +	gpio_set_value(pdata->power_gpio, 0);
> +
> +	return 0;
> +}

And this one.

> +static int pasic3_leds_suspend(struct platform_device *pdev)
> +{
> +	const struct mfd_cell *cell = mfd_get_cell(pdev);
> +	struct pasic3_platform_data *pdata = dev_get_platdata(&pdev->dev);
> +	struct pasic3_led *led;
> +
> +	led = cell->platform_data;
> +	pdata = led->pdata;
> +
> +	gpio_set_value(pdata->power_gpio, 0);
> +
> +	return 0;
> +}

And this one.

> +#define PASIC3_NUM_LEDS 3
> +
> +static struct mfd_cell pasic3_cell_leds[PASIC3_NUM_LEDS] = {
> +	[0] = {
> +		.name		= "leds-pasic3",
> +		.id			= 0,
> +		.enable		= pasic3_leds_enable,
> +		.disable	= pasic3_leds_disable,
> +		.suspend	= pasic3_leds_suspend,
> +		.resume		= pasic3_leds_enable,
> +	},
> +	[1] = {
> +		.name		= "leds-pasic3",
> +		.id			= 1,
> +		.enable		= pasic3_leds_enable,
> +		.disable	= pasic3_leds_disable,
> +		.suspend	= pasic3_leds_suspend,
> +		.resume		= pasic3_leds_enable,
> +	},
> +	[2] = {
> +		.name		= "leds-pasic3",
> +		.id			= 2,
> +		.enable		= pasic3_leds_enable,
> +		.disable	= pasic3_leds_disable,
> +		.suspend	= pasic3_leds_suspend,
> +		.resume		= pasic3_leds_enable,
> +	},
>  };

Why do you need to explicitly set the .ids?

>  /*
> @@ -78,10 +149,10 @@ static int ds1wm_enable(struct platform_device *pdev)
>  	struct device *dev = pdev->dev.parent;
>  	int c;
>  
> -	c = pasic3_read_register(dev, 0x28);
> -	pasic3_write_register(dev, 0x28, c & 0x7f);
> +	c = pasic3_read_register(dev, PASIC3_GPIO);
> +	pasic3_write_register(dev, PASIC3_GPIO, c & ~DS1WM_nEN);

Not keen on camel case defines.

> -	dev_dbg(dev, "DS1WM OWM_EN low (active) %02x\n", c & 0x7f);
> +	dev_dbg(dev, "DS1WM OWM_EN low (active) %02x\n", c & ~DS1WM_nEN);
>  	return 0;
>  }
>  
> @@ -90,10 +161,10 @@ static int ds1wm_disable(struct platform_device *pdev)
>  	struct device *dev = pdev->dev.parent;
>  	int c;
>  
> -	c = pasic3_read_register(dev, 0x28);
> -	pasic3_write_register(dev, 0x28, c | 0x80);
> +	c = pasic3_read_register(dev, PASIC3_GPIO);
> +	pasic3_write_register(dev, PASIC3_GPIO, c | DS1WM_nEN);
>  
> -	dev_dbg(dev, "DS1WM OWM_EN high (inactive) %02x\n", c | 0x80);
> +	dev_dbg(dev, "DS1WM OWM_EN high (inactive) %02x\n", c | DS1WM_nEN);
>  	return 0;
>  }
>  
> @@ -172,13 +243,27 @@ static int __init pasic3_probe(struct platform_device *pdev)
>  			dev_warn(dev, "failed to register DS1WM\n");
>  	}
>  
> -	if (pdata && pdata->led_pdata) {
> -		led_cell.platform_data = pdata->led_pdata;
> -		led_cell.pdata_size = sizeof(struct pasic3_leds_machinfo);
> -		ret = mfd_add_devices(&pdev->dev, pdev->id, &led_cell, 1, r,
> -				      0, NULL);
> +	if (pdata && pdata->leds) {
> +		int i;
> +
> +		for (i = 0; i < PASIC3_NUM_LEDS; ++i) {
> +			pdata->leds[i].pdata = pdata;
> +			pasic3_cell_leds[i].platform_data = &pdata->leds[i];
> +			pasic3_cell_leds[i].pdata_size = sizeof(pdata->leds[i]);
> +		}

Where is the platform data passed in from?

> +		ret = mfd_add_devices(&pdev->dev, 0,

Are you sure you don't want the this to be automatically done for you?

See: include/linux/platform_device.h

> +			pasic3_cell_leds, PASIC3_NUM_LEDS, NULL, 0, NULL);
> +
>  		if (ret < 0)
>  			dev_warn(dev, "failed to register LED device\n");
> +
> +		if (pdata->power_gpio) {
> +			ret = gpio_request(pdata->power_gpio,
> +				"Red-Blue LED Power");
> +			if (ret < 0)
> +				dev_warn(dev, "failed to request power GPIO\n");

Why are you doing this in here?  Doesn't this belong in the LED driver?

> +		}
> +
>  	}
>  
>  	return 0;
> @@ -187,10 +272,14 @@ static int __init pasic3_probe(struct platform_device *pdev)
>  static int pasic3_remove(struct platform_device *pdev)
>  {
>  	struct pasic3_data *asic = platform_get_drvdata(pdev);
> +	struct pasic3_platform_data *pdata = dev_get_platdata(&pdev->dev);
>  	struct resource *r;
>  
>  	mfd_remove_devices(&pdev->dev);
>  
> +	if (pdata->power_gpio)
> +		gpio_free(pdata->power_gpio);
> +

Move somewhere else.

>  	iounmap(asic->mapping);
>  	r = platform_get_resource(pdev, IORESOURCE_MEM, 0);
>  	release_mem_region(r->start, resource_size(r));
> diff --git a/include/linux/mfd/htc-pasic3.h b/include/linux/mfd/htc-pasic3.h
> index 3d3ed67..e8e4cd2 100644
> --- a/include/linux/mfd/htc-pasic3.h
> +++ b/include/linux/mfd/htc-pasic3.h
> @@ -18,36 +18,65 @@
>  extern void pasic3_write_register(struct device *dev, u32 reg, u8 val);
>  extern u8 pasic3_read_register(struct device *dev, u32 reg);
>  
> -/*
> - * mask for registers 0x20,0x21,0x22
> - */
> -#define PASIC3_MASK_LED0 0x04
> -#define PASIC3_MASK_LED1 0x08
> -#define PASIC3_MASK_LED2 0x40
> +#define PASIC3_CH0_DELAY_ON		0x00
> +#define PASIC3_CH0_DELAY_OFF	0x01
> +#define PASIC3_CH1_DELAY_ON		0x02
> +#define PASIC3_CH1_DELAY_OFF	0x03
> +#define PASIC3_CH2_DELAY_ON		0x04
> +#define PASIC3_CH2_DELAY_OFF	0x05
> +#define PASIC3_DELAY_MASK		0x7f
> +
> +#define PASIC3_CH_CONTROL		0x06
> +#define		R06_CH0_EN			(1<<0)
> +#define		R06_CH1_EN			(1<<1)
> +#define		R06_CH2_EN			(1<<2)
> +#define		R06_CH0_FORCE_ON	(1<<3)
> +#define		R06_CH1_FORCE_ON	(1<<4)
> +#define		R06_CH2_FORCE_ON	(1<<5)

Use BIT().

>  /*
> - * bits in register 0x06
> + * pwm_ch0_out | force_on | (bit0 & bit1 & bit2)
> + * pwm_ch1_out | force_on | (bit0 & bit1 & bit2)
> + * pwm_ch2_out | force_on | (bit2?bit0:(bit0 & ! bit1))
>   */
> -#define PASIC3_BIT2_LED0 0x08
> -#define PASIC3_BIT2_LED1 0x10
> -#define PASIC3_BIT2_LED2 0x20
> +
> +#define PASIC3_MASK_A	0x20
> +#define PASIC3_MASK_B	0x21
> +#define PASIC3_MASK_C	0x22
> +#define  MASK_CH0	(1<<2)
> +#define  MASK_CH1	(1<<3)
> +#define  MASK_CH2	(1<<6)

As above and for all other "1 <<" logic.

> +#define  PASIC3_GPIO	0x28
> +
> +#define	DS1WM_nEN	(1<<7)
> +#define  PASIC3_SYS	0x2a
> +/* NORMAL_RST, CAM_PWR_RST and UNKNOWN will autoclear, set STATUS */
> +#define  NORMAL_RST		(1<<0)
> +#define  CAM_PWR_RST	(1<<1)
> +#define  UNKNOWN		(1<<2)
> +#define  STATUS_NORMAL_RST	(1<<4)
> +#define  STATUS_CAM_PWR_RST	(1<<5)
> +#define  STATUS_UNKNOWN		(1<<6)
> +
> +#define PASIC3_RST_EN		0x2c
> +#define  EN_NORMAL_RST	0x40
> +#define  EN_DOOR_RST	0x42
>  
>  struct pasic3_led {
> -	struct led_classdev         led;
> -	unsigned int                hw_num;
> -	unsigned int                bit2;
> -	unsigned int                mask;
> -	struct pasic3_leds_machinfo *pdata;
> +	struct led_classdev		cdev;
> +	unsigned int	hw_num;
> +	unsigned char	bit_blink_en;
> +	unsigned char	bit_force_on;
> +	unsigned char	bit_mask;
> +	unsigned char	reg_delay_on;
> +	unsigned char	reg_delay_off;

Are you sure these shouldn't be bools?

> +	struct pasic3_platform_data *pdata;
>  };
>  
> -struct pasic3_leds_machinfo {
> +struct pasic3_platform_data {
>  	unsigned int      num_leds;
>  	unsigned int      power_gpio;
>  	struct pasic3_led *leds;
> -};
> -
> -struct pasic3_platform_data {
> -	struct pasic3_leds_machinfo *led_pdata;
>  	unsigned int                 clock_rate;
>  };
>  

-- 
Lee Jones
Linaro STMicroelectronics Landing Team Lead
Linaro.org ? Open source software for ARM SoCs
Follow Linaro: Facebook | Twitter | Blog


From tony at atomide.com  Thu Aug 13 01:20:22 2015
From: tony at atomide.com (Tony Lindgren)
Date: Thu, 13 Aug 2015 01:20:22 -0700
Subject: [GIT PULL] omap gpmc null pointer fix against v4.2-rc6
Message-ID: <20150813082022.GL10928@atomide.com>

The following changes since commit cd4556733b30cc363adc7b1cea3bffa7e2dd0c7c:

  ARM: dts: dra7: Fix broken pbias device creation (2015-08-05 03:04:07 -0700)

are available in the git repository at:

  git://git.kernel.org/pub/scm/linux/kernel/git/tmlind/linux-omap tags/omap-for-v4.2/fixes-rc6

for you to fetch changes up to e984a1791ac6a7c944911207e8a9c344763f0003:

  memory: omap-gpmc: Don't try to save uninitialized GPMC context (2015-08-12 01:43:49 -0700)

----------------------------------------------------------------
Fix a NULL pointer exception for omap GPMC bus code if probe fails.

----------------------------------------------------------------
Tomeu Vizoso (1):
      memory: omap-gpmc: Don't try to save uninitialized GPMC context

 drivers/memory/omap-gpmc.c | 6 ++++++
 1 file changed, 6 insertions(+)


From maoguang.meng at mediatek.com  Thu Aug 13 01:18:56 2015
From: maoguang.meng at mediatek.com (maoguang.meng at mediatek.com)
Date: Thu, 13 Aug 2015 16:18:56 +0800
Subject: [PATCH] pinctrl: mediatek: Implement wake handler and suspend resume
Message-ID: <1439453936-8315-1-git-send-email-maoguang.meng@mediatek.com>

From: Maoguang Meng <maoguang.meng at mediatek.com>

This patch implement irq_set_wake to get who is wakeup source and
setup on suspend resume.

Signed-off-by: Maoguang Meng <maoguang.meng at mediatek.com>

---
changes since v2:
-modify irq_wake to handle irq wakeup source.
-allocate two buffers separately.
-fix some codestyle.

Changes since v1:
-implement irq_wake handler.
---
 drivers/pinctrl/mediatek/pinctrl-mt8173.c     |  1 +
 drivers/pinctrl/mediatek/pinctrl-mtk-common.c | 94 ++++++++++++++++++++++++++-
 drivers/pinctrl/mediatek/pinctrl-mtk-common.h |  4 ++
 3 files changed, 97 insertions(+), 2 deletions(-)

diff --git a/drivers/pinctrl/mediatek/pinctrl-mt8173.c b/drivers/pinctrl/mediatek/pinctrl-mt8173.c
index d0c811d..ad27184 100644
--- a/drivers/pinctrl/mediatek/pinctrl-mt8173.c
+++ b/drivers/pinctrl/mediatek/pinctrl-mt8173.c
@@ -385,6 +385,7 @@ static struct platform_driver mtk_pinctrl_driver = {
 	.driver = {
 		.name = "mediatek-mt8173-pinctrl",
 		.of_match_table = mt8173_pctrl_match,
+		.pm = &mtk_eint_pm_ops,
 	},
 };
 
diff --git a/drivers/pinctrl/mediatek/pinctrl-mtk-common.c b/drivers/pinctrl/mediatek/pinctrl-mtk-common.c
index ad1ea16..7d4ba926 100644
--- a/drivers/pinctrl/mediatek/pinctrl-mtk-common.c
+++ b/drivers/pinctrl/mediatek/pinctrl-mtk-common.c
@@ -33,6 +33,7 @@
 #include <linux/mfd/syscon.h>
 #include <linux/delay.h>
 #include <linux/interrupt.h>
+#include <linux/pm.h>
 #include <dt-bindings/pinctrl/mt65xx.h>
 
 #include "../core.h"
@@ -1062,11 +1063,82 @@ static int mtk_eint_set_type(struct irq_data *d,
 	return 0;
 }
 
+static int mtk_eint_irq_set_wake(struct irq_data *d, unsigned int on)
+{
+	struct mtk_pinctrl *pctl = irq_data_get_irq_chip_data(d);
+	int shift = d->hwirq & 0x1f;
+	int reg = d->hwirq >> 5;
+
+	if (on)
+		pctl->wake_mask[reg] |= BIT(shift);
+	else
+		pctl->wake_mask[reg] &= ~BIT(shift);
+
+	return 0;
+}
+
+static void mtk_eint_chip_write_mask(const struct mtk_eint_offsets *chip,
+		void __iomem *eint_reg_base, u32 *buf)
+{
+	int port;
+	void __iomem *reg;
+
+	for (port = 0; port < chip->ports; port++) {
+		reg = eint_reg_base + (port << 2);
+		writel_relaxed(~buf[port], reg + chip->mask_set);
+		writel_relaxed(buf[port], reg + chip->mask_clr);
+	}
+}
+
+static void mtk_eint_chip_read_mask(const struct mtk_eint_offsets *chip,
+		void __iomem *eint_reg_base, u32 *buf)
+{
+	int port;
+	void __iomem *reg;
+
+	for (port = 0; port < chip->ports; port++) {
+		reg = eint_reg_base + chip->mask + (port << 2);
+		buf[port] = ~readl_relaxed(reg);
+	}
+}
+
+static int mtk_eint_suspend(struct device *device)
+{
+	void __iomem *reg;
+	struct mtk_pinctrl *pctl = dev_get_drvdata(device);
+	const struct mtk_eint_offsets *eint_offsets =
+			&pctl->devdata->eint_offsets;
+
+	reg = pctl->eint_reg_base;
+	mtk_eint_chip_read_mask(eint_offsets, reg, pctl->cur_mask);
+	mtk_eint_chip_write_mask(eint_offsets, reg, pctl->wake_mask);
+
+	return 0;
+}
+
+static int mtk_eint_resume(struct device *device)
+{
+	struct platform_device *pdev = to_platform_device(device);
+	struct mtk_pinctrl *pctl = platform_get_drvdata(pdev);
+	const struct mtk_eint_offsets *eint_offsets =
+			&pctl->devdata->eint_offsets;
+
+	mtk_eint_chip_write_mask(eint_offsets,
+			pctl->eint_reg_base, pctl->cur_mask);
+
+	return 0;
+}
+
+const struct dev_pm_ops mtk_eint_pm_ops = {
+	.suspend = mtk_eint_suspend,
+	.resume = mtk_eint_resume,
+};
+
 static void mtk_eint_ack(struct irq_data *d)
 {
 	struct mtk_pinctrl *pctl = irq_data_get_irq_chip_data(d);
 	const struct mtk_eint_offsets *eint_offsets =
-		&pctl->devdata->eint_offsets;
+			&pctl->devdata->eint_offsets;
 	u32 mask = BIT(d->hwirq & 0x1f);
 	void __iomem *reg = mtk_eint_get_offset(pctl, d->hwirq,
 			eint_offsets->ack);
@@ -1076,10 +1148,12 @@ static void mtk_eint_ack(struct irq_data *d)
 
 static struct irq_chip mtk_pinctrl_irq_chip = {
 	.name = "mt-eint",
+	.irq_disable = mtk_eint_mask,
 	.irq_mask = mtk_eint_mask,
 	.irq_unmask = mtk_eint_unmask,
 	.irq_ack = mtk_eint_ack,
 	.irq_set_type = mtk_eint_set_type,
+	.irq_set_wake = mtk_eint_irq_set_wake,
 	.irq_request_resources = mtk_pinctrl_irq_request_resources,
 	.irq_release_resources = mtk_pinctrl_irq_release_resources,
 };
@@ -1217,7 +1291,7 @@ int mtk_pctrl_init(struct platform_device *pdev,
 	struct device_node *np = pdev->dev.of_node, *node;
 	struct property *prop;
 	struct resource *res;
-	int i, ret, irq;
+	int i, ret, irq, ports_buf;
 
 	pctl = devm_kzalloc(&pdev->dev, sizeof(*pctl), GFP_KERNEL);
 	if (!pctl)
@@ -1319,6 +1393,22 @@ int mtk_pctrl_init(struct platform_device *pdev,
 		goto chip_error;
 	}
 
+	ports_buf = ALIGN(pctl->devdata->eint_offsets.ports,
+			sizeof(long)/sizeof(u32));
+	pctl->wake_mask = devm_kcalloc(&pdev->dev, ports_buf,
+					sizeof(*pctl->wake_mask), GFP_KERNEL);
+	if (!pctl->wake_mask) {
+		ret = -ENOMEM;
+		goto chip_error;
+	}
+
+	pctl->cur_mask = devm_kcalloc(&pdev->dev, ports_buf,
+					sizeof(*pctl->cur_mask), GFP_KERNEL);
+	if (!pctl->cur_mask) {
+		ret = -ENOMEM;
+		goto chip_error;
+	}
+
 	pctl->eint_dual_edges = devm_kcalloc(&pdev->dev, pctl->devdata->ap_num,
 					     sizeof(int), GFP_KERNEL);
 	if (!pctl->eint_dual_edges) {
diff --git a/drivers/pinctrl/mediatek/pinctrl-mtk-common.h b/drivers/pinctrl/mediatek/pinctrl-mtk-common.h
index 30213e5..f1be8e8 100644
--- a/drivers/pinctrl/mediatek/pinctrl-mtk-common.h
+++ b/drivers/pinctrl/mediatek/pinctrl-mtk-common.h
@@ -266,6 +266,8 @@ struct mtk_pinctrl {
 	void __iomem		*eint_reg_base;
 	struct irq_domain	*domain;
 	int			*eint_dual_edges;
+	u32 *wake_mask;
+	u32 *cur_mask;
 };
 
 int mtk_pctrl_init(struct platform_device *pdev,
@@ -281,4 +283,6 @@ int mtk_pconf_spec_set_ies_smt_range(struct regmap *regmap,
 		const struct mtk_pin_ies_smt_set *ies_smt_infos, unsigned int info_num,
 		unsigned int pin, unsigned char align, int value);
 
+extern const struct dev_pm_ops mtk_eint_pm_ops;
+
 #endif /* __PINCTRL_MTK_COMMON_H */
-- 
1.8.1.1.dirty



From viresh.kumar at linaro.org  Thu Aug 13 01:22:59 2015
From: viresh.kumar at linaro.org (Viresh Kumar)
Date: Thu, 13 Aug 2015 13:52:59 +0530
Subject: 3.18: lockdep problems in cpufreq
In-Reply-To: <20150813081744.GN7557@n2100.arm.linux.org.uk>
References: <20141214213655.GA11285@n2100.arm.linux.org.uk>
 <2574268.XBqpdL2VLI@vostro.rjw.lan>
 <20150811170357.GA24529@n2100.arm.linux.org.uk>
 <5160300.5D2Dvly8u9@vostro.rjw.lan>
 <20150813081744.GN7557@n2100.arm.linux.org.uk>
Message-ID: <20150813082259.GR20238@linux>

On 13-08-15, 09:17, Russell King - ARM Linux wrote:
> That I doubt.  Eduardo has not bothered to reply at _any_ time.  I
> have to question whether there is anyone even reading that email
> address, or whether it's a redirect to /dev/null.  All the evidence I
> have right now is that this Eduardo is a ficticous character.
> 
> I would have at least expected some complaints when I said "I've put
> it in linux-next" but... absolutely nothing.
> 
> So... my only conclusion is that you're all pulling my leg that there
> _is_ this "Eduardo" maintainer who's supposed to be taking patches for
> this stuff.

Haha, If that's the case then we are all in the same boat.
Who is Eduardo ? A bot ? :)

Anyway, AFAIK, he wasn't around for sometime and came back last week
only. Even I have expected him to reply to yesterday's discussions.

> As I've said, I'm not bothering with this anymore, it's just far too
> much effort to play these stupid games.  The deadlock can stay for all
> I care.

And finally I took the charge to carry it now. :)

-- 
viresh


From gg at slimlogic.co.uk  Thu Aug 13 01:27:59 2015
From: gg at slimlogic.co.uk (Graeme Gregory)
Date: Thu, 13 Aug 2015 09:27:59 +0100
Subject: [PATCH 2/2] Convert smsc911x to use ACPI as well as DT
In-Reply-To: <1439417187-21411-3-git-send-email-jeremy.linton@arm.com>
References: <1439417187-21411-1-git-send-email-jeremy.linton@arm.com>
 <1439417187-21411-3-git-send-email-jeremy.linton@arm.com>
Message-ID: <20150813082759.GB5468@xora-haswell.xora.org.uk>

On Wed, Aug 12, 2015 at 05:06:27PM -0500, Jeremy Linton wrote:
> Add ACPI bindings for the smsc911x driver. Convert the DT specific calls
> to nonspecific device* calls, This allows the driver to work
> with both ACPI and DT configurations. Ethernet should now work when using
> ACPI on ARM Juno.
> 
> Signed-off-by: Jeremy Linton <jeremy.linton at arm.com>

The code looks fine to me.

Currently the compulsary DT properties seem to match the "approved" ACPI
NIC properties from here

http://www.uefi.org/sites/default/files/resources/nic-request-v2.pdf

Reviewed-by: Graeme Gregory <graeme.gregory at linaro.org>

Thanks

> ---
>  drivers/net/ethernet/smsc/smsc911x.c | 48 +++++++++++++++++-------------------
>  1 file changed, 22 insertions(+), 26 deletions(-)
> 
> diff --git a/drivers/net/ethernet/smsc/smsc911x.c b/drivers/net/ethernet/smsc/smsc911x.c
> index 959aeea..0f21aa3 100644
> --- a/drivers/net/ethernet/smsc/smsc911x.c
> +++ b/drivers/net/ethernet/smsc/smsc911x.c
> @@ -59,7 +59,9 @@
>  #include <linux/of_device.h>
>  #include <linux/of_gpio.h>
>  #include <linux/of_net.h>
> +#include <linux/acpi.h>
>  #include <linux/pm_runtime.h>
> +#include <linux/property.h>
>  
>  #include "smsc911x.h"
>  
> @@ -2362,59 +2364,46 @@ static const struct smsc911x_ops shifted_smsc911x_ops = {
>  	.tx_writefifo = smsc911x_tx_writefifo_shift,
>  };
>  
> -#ifdef CONFIG_OF
> -static int smsc911x_probe_config_dt(struct smsc911x_platform_config *config,
> -				    struct device_node *np)
> +static int smsc911x_probe_config(struct smsc911x_platform_config *config,
> +				 struct device *dev)
>  {
> -	const char *mac;
>  	u32 width = 0;
>  
> -	if (!np)
> +	if (!dev)
>  		return -ENODEV;
>  
> -	config->phy_interface = of_get_phy_mode(np);
> +	config->phy_interface = device_get_phy_mode(dev);
>  
> -	mac = of_get_mac_address(np);
> -	if (mac)
> -		memcpy(config->mac, mac, ETH_ALEN);
> +	device_get_mac_address(dev, config->mac, ETH_ALEN);
>  
> -	of_property_read_u32(np, "reg-shift", &config->shift);
> +	device_property_read_u32(dev, "reg-shift", &config->shift);
>  
> -	of_property_read_u32(np, "reg-io-width", &width);
> +	device_property_read_u32(dev, "reg-io-width", &width);
>  	if (width == 4)
>  		config->flags |= SMSC911X_USE_32BIT;
>  	else
>  		config->flags |= SMSC911X_USE_16BIT;
>  
> -	if (of_get_property(np, "smsc,irq-active-high", NULL))
> +	if (device_property_present(dev, "smsc,irq-active-high"))
>  		config->irq_polarity = SMSC911X_IRQ_POLARITY_ACTIVE_HIGH;
>  
> -	if (of_get_property(np, "smsc,irq-push-pull", NULL))
> +	if (device_property_present(dev, "smsc,irq-push-pull"))
>  		config->irq_type = SMSC911X_IRQ_TYPE_PUSH_PULL;
>  
> -	if (of_get_property(np, "smsc,force-internal-phy", NULL))
> +	if (device_property_present(dev, "smsc,force-internal-phy"))
>  		config->flags |= SMSC911X_FORCE_INTERNAL_PHY;
>  
> -	if (of_get_property(np, "smsc,force-external-phy", NULL))
> +	if (device_property_present(dev, "smsc,force-external-phy"))
>  		config->flags |= SMSC911X_FORCE_EXTERNAL_PHY;
>  
> -	if (of_get_property(np, "smsc,save-mac-address", NULL))
> +	if (device_property_present(dev, "smsc,save-mac-address"))
>  		config->flags |= SMSC911X_SAVE_MAC_ADDRESS;
>  
>  	return 0;
>  }
> -#else
> -static inline int smsc911x_probe_config_dt(
> -				struct smsc911x_platform_config *config,
> -				struct device_node *np)
> -{
> -	return -ENODEV;
> -}
> -#endif /* CONFIG_OF */
>  
>  static int smsc911x_drv_probe(struct platform_device *pdev)
>  {
> -	struct device_node *np = pdev->dev.of_node;
>  	struct net_device *dev;
>  	struct smsc911x_data *pdata;
>  	struct smsc911x_platform_config *config = dev_get_platdata(&pdev->dev);
> @@ -2478,7 +2467,7 @@ static int smsc911x_drv_probe(struct platform_device *pdev)
>  		goto out_disable_resources;
>  	}
>  
> -	retval = smsc911x_probe_config_dt(&pdata->config, np);
> +	retval = smsc911x_probe_config(&pdata->config, &pdev->dev);
>  	if (retval && config) {
>  		/* copy config parameters across to pdata */
>  		memcpy(&pdata->config, config, sizeof(pdata->config));
> @@ -2654,6 +2643,12 @@ static const struct of_device_id smsc911x_dt_ids[] = {
>  MODULE_DEVICE_TABLE(of, smsc911x_dt_ids);
>  #endif
>  
> +static const struct acpi_device_id smsc911x_acpi_match[] = {
> +	{ "ARMH9118", 0 },
> +	{ }
> +};
> +MODULE_DEVICE_TABLE(acpi, smsc911x_acpi_match);
> +
>  static struct platform_driver smsc911x_driver = {
>  	.probe = smsc911x_drv_probe,
>  	.remove = smsc911x_drv_remove,
> @@ -2661,6 +2656,7 @@ static struct platform_driver smsc911x_driver = {
>  		.name	= SMSC_CHIPNAME,
>  		.pm	= SMSC911X_PM_OPS,
>  		.of_match_table = of_match_ptr(smsc911x_dt_ids),
> +		.acpi_match_table = ACPI_PTR(smsc911x_acpi_match),
>  	},
>  };
>  
> -- 
> 2.4.3
> 
> 
> 
> _______________________________________________
> linux-arm-kernel mailing list
> linux-arm-kernel at lists.infradead.org
> http://lists.infradead.org/mailman/listinfo/linux-arm-kernel


From marc.zyngier at arm.com  Thu Aug 13 01:28:44 2015
From: marc.zyngier at arm.com (Marc Zyngier)
Date: Thu, 13 Aug 2015 09:28:44 +0100
Subject: [PATCH v2 2/4] irqchip: GICv3: Don't deactivate interrupts forwarded
 to a guest
In-Reply-To: <1439454526-1185-1-git-send-email-marc.zyngier@arm.com>
References: <1439454526-1185-1-git-send-email-marc.zyngier@arm.com>
Message-ID: <1439454526-1185-3-git-send-email-marc.zyngier@arm.com>

Commit 0a4377de3056 ("genirq: Introduce irq_set_vcpu_affinity() to
target an interrupt to a VCPU") added just what we needed at the
lowest level to allow an interrupt to be deactivated by a guest.

When such a request reaches the GIC, it knows it doesn't need to
perform the deactivation anymore, and can safely leave the guest
do its magic. This of course requires additional support in both
VFIO and KVM.

Signed-off-by: Marc Zyngier <marc.zyngier at arm.com>
---
 drivers/irqchip/irq-gic-v3.c | 35 +++++++++++++++++++++++++++++++++--
 1 file changed, 33 insertions(+), 2 deletions(-)

diff --git a/drivers/irqchip/irq-gic-v3.c b/drivers/irqchip/irq-gic-v3.c
index 61190fb..01c6329 100644
--- a/drivers/irqchip/irq-gic-v3.c
+++ b/drivers/irqchip/irq-gic-v3.c
@@ -70,6 +70,11 @@ static inline int gic_irq_in_rdist(struct irq_data *d)
 	return gic_irq(d) < 32;
 }
 
+static inline bool forwarded_irq(struct irq_data *d)
+{
+	return d->handler_data != NULL;
+}
+
 static inline void __iomem *gic_dist_base(struct irq_data *d)
 {
 	if (gic_irq_in_rdist(d))	/* SGI+PPI -> SGI_base for this CPU */
@@ -231,6 +236,18 @@ static void gic_poke_irq(struct irq_data *d, u32 offset)
 static void gic_mask_irq(struct irq_data *d)
 {
 	gic_poke_irq(d, GICD_ICENABLER);
+	/*
+	 * When masking a forwarded interrupt, make sure it is
+	 * deactivated as well.
+	 *
+	 * This ensures that an interrupt that is getting
+	 * disabled/masked will not get "stuck", because there is
+	 * noone to deactivate it (guest is being terminated).
+	 */
+	if (static_key_true(&supports_deactivate)) {
+		if (forwarded_irq(d))
+			gic_poke_irq(d, GICD_ICACTIVER);
+	}
 }
 
 static void gic_unmask_irq(struct irq_data *d)
@@ -296,8 +313,11 @@ static int gic_irq_get_irqchip_state(struct irq_data *d,
 static void gic_eoi_irq(struct irq_data *d)
 {
 	if (static_key_true(&supports_deactivate)) {
-		/* No need to deactivate an LPI */
-		if (gic_irq(d) >= 8192)
+		/*
+		 * No need to deactivate an LPI, or an interrupt that
+		 * is is getting forwarded to a vcpu.
+		 */
+		if (gic_irq(d) >= 8192 || forwarded_irq(d))
 			return;
 		gic_write_dir(gic_irq(d));
 	} else {
@@ -331,6 +351,16 @@ static int gic_set_type(struct irq_data *d, unsigned int type)
 	return gic_configure_irq(irq, type, base, rwp_wait);
 }
 
+static int gic_irq_set_vcpu_affinity(struct irq_data *d, void *vcpu)
+{
+	if (static_key_true(&supports_deactivate)) {
+		d->handler_data = vcpu;
+		return 0;
+	}
+
+	return -EINVAL;
+}
+
 static u64 gic_mpidr_to_affinity(u64 mpidr)
 {
 	u64 aff;
@@ -681,6 +711,7 @@ static struct irq_chip gic_chip = {
 	.irq_set_affinity	= gic_set_affinity,
 	.irq_get_irqchip_state	= gic_irq_get_irqchip_state,
 	.irq_set_irqchip_state	= gic_irq_set_irqchip_state,
+	.irq_set_vcpu_affinity	= gic_irq_set_vcpu_affinity,
 	.flags			= IRQCHIP_SET_TYPE_MASKED,
 };
 
-- 
2.1.4



From marc.zyngier at arm.com  Thu Aug 13 01:28:43 2015
From: marc.zyngier at arm.com (Marc Zyngier)
Date: Thu, 13 Aug 2015 09:28:43 +0100
Subject: [PATCH v2 1/4] irqchip: GICv3: Convert to EOImode == 1
In-Reply-To: <1439454526-1185-1-git-send-email-marc.zyngier@arm.com>
References: <1439454526-1185-1-git-send-email-marc.zyngier@arm.com>
Message-ID: <1439454526-1185-2-git-send-email-marc.zyngier@arm.com>

So far, GICv3 has been used in with EOImode == 0. The effect of this
mode is to perform the priority drop and the deactivation of the
interrupt at the same time.

While this works perfectly for Linux (we only have a single priority),
it causes issues when an interrupt is forwarded to a guest, and when
we want the guest to perform the EOI itself.

For this case, the GIC architecture provides EOImode == 1, where:
- A write to ICC_EOIR1_EL1 drops the priority of the interrupt and leaves
it active. Other interrupts at the same priority level can now be taken,
but the active interrupt cannot be taken again
- A write to ICC_DIR_EL1 marks the interrupt as inactive, meaning it can
now be taken again.

This patch converts the driver to be able to use this new mode, depending
on whether or not the kernel can behave as a hypervisor. No feature change.

Signed-off-by: Marc Zyngier <marc.zyngier at arm.com>
---
 drivers/irqchip/irq-gic-v3.c       | 37 +++++++++++++++++++++++++++++++++----
 include/linux/irqchip/arm-gic-v3.h |  9 +++++++++
 2 files changed, 42 insertions(+), 4 deletions(-)

diff --git a/drivers/irqchip/irq-gic-v3.c b/drivers/irqchip/irq-gic-v3.c
index c52f7ba..61190fb 100644
--- a/drivers/irqchip/irq-gic-v3.c
+++ b/drivers/irqchip/irq-gic-v3.c
@@ -30,6 +30,7 @@
 #include <asm/cputype.h>
 #include <asm/exception.h>
 #include <asm/smp_plat.h>
+#include <asm/virt.h>
 
 #include "irq-gic-common.h"
 #include "irqchip.h"
@@ -50,6 +51,7 @@ struct gic_chip_data {
 };
 
 static struct gic_chip_data gic_data __read_mostly;
+static struct static_key supports_deactivate = STATIC_KEY_INIT_TRUE;
 
 #define gic_data_rdist()		(this_cpu_ptr(gic_data.rdists.rdist))
 #define gic_data_rdist_rd_base()	(gic_data_rdist()->rd_base)
@@ -293,7 +295,14 @@ static int gic_irq_get_irqchip_state(struct irq_data *d,
 
 static void gic_eoi_irq(struct irq_data *d)
 {
-	gic_write_eoir(gic_irq(d));
+	if (static_key_true(&supports_deactivate)) {
+		/* No need to deactivate an LPI */
+		if (gic_irq(d) >= 8192)
+			return;
+		gic_write_dir(gic_irq(d));
+	} else {
+		gic_write_eoir(gic_irq(d));
+	}
 }
 
 static int gic_set_type(struct irq_data *d, unsigned int type)
@@ -343,15 +352,24 @@ static asmlinkage void __exception_irq_entry gic_handle_irq(struct pt_regs *regs
 
 		if (likely(irqnr > 15 && irqnr < 1020) || irqnr >= 8192) {
 			int err;
+
+			if (static_key_true(&supports_deactivate))
+				gic_write_eoir(irqnr);
+
 			err = handle_domain_irq(gic_data.domain, irqnr, regs);
 			if (err) {
 				WARN_ONCE(true, "Unexpected interrupt received!\n");
-				gic_write_eoir(irqnr);
+				if (static_key_true(&supports_deactivate))
+					gic_write_dir(irqnr);
+				else
+					gic_write_eoir(irqnr);
 			}
 			continue;
 		}
 		if (irqnr < 16) {
 			gic_write_eoir(irqnr);
+			if (static_key_true(&supports_deactivate))
+				gic_write_dir(irqnr);
 #ifdef CONFIG_SMP
 			handle_IPI(irqnr, regs);
 #else
@@ -451,8 +469,13 @@ static void gic_cpu_sys_reg_init(void)
 	/* Set priority mask register */
 	gic_write_pmr(DEFAULT_PMR_VALUE);
 
-	/* EOI deactivates interrupt too (mode 0) */
-	gic_write_ctlr(ICC_CTLR_EL1_EOImode_drop_dir);
+	if (static_key_true(&supports_deactivate)) {
+		/* EOI drops priority only (mode 1) */
+		gic_write_ctlr(ICC_CTLR_EL1_EOImode_drop);
+	} else {
+		/* EOI deactivates interrupt too (mode 0) */
+		gic_write_ctlr(ICC_CTLR_EL1_EOImode_drop_dir);
+	}
 
 	/* ... and let's hit the road... */
 	gic_write_grpen1(1);
@@ -820,6 +843,12 @@ static int __init gic_of_init(struct device_node *node, struct device_node *pare
 	if (of_property_read_u64(node, "redistributor-stride", &redist_stride))
 		redist_stride = 0;
 
+	if (!is_hyp_mode_available())
+		static_key_slow_dec(&supports_deactivate);
+
+	if (static_key_true(&supports_deactivate))
+		pr_info("GIC: Using split EOI/Deactivate mode\n");
+
 	gic_data.dist_base = dist_base;
 	gic_data.redist_regions = rdist_regs;
 	gic_data.nr_redist_regions = nr_redist_regions;
diff --git a/include/linux/irqchip/arm-gic-v3.h b/include/linux/irqchip/arm-gic-v3.h
index ffbc034..bc98832 100644
--- a/include/linux/irqchip/arm-gic-v3.h
+++ b/include/linux/irqchip/arm-gic-v3.h
@@ -104,6 +104,8 @@
 #define GICR_SYNCR			0x00C0
 #define GICR_MOVLPIR			0x0100
 #define GICR_MOVALLR			0x0110
+#define GICR_ISACTIVER			GICD_ISACTIVER
+#define GICR_ICACTIVER			GICD_ICACTIVER
 #define GICR_IDREGS			GICD_IDREGS
 #define GICR_PIDR2			GICD_PIDR2
 
@@ -288,6 +290,7 @@
 #define ICH_VMCR_PMR_MASK		(0xffUL << ICH_VMCR_PMR_SHIFT)
 
 #define ICC_EOIR1_EL1			sys_reg(3, 0, 12, 12, 1)
+#define ICC_DIR_EL1			sys_reg(3, 0, 12, 11, 1)
 #define ICC_IAR1_EL1			sys_reg(3, 0, 12, 12, 0)
 #define ICC_SGI1R_EL1			sys_reg(3, 0, 12, 11, 5)
 #define ICC_PMR_EL1			sys_reg(3, 0, 4, 6, 0)
@@ -384,6 +387,12 @@ static inline void gic_write_eoir(u64 irq)
 	isb();
 }
 
+static inline void gic_write_dir(u64 irq)
+{
+	asm volatile("msr_s " __stringify(ICC_DIR_EL1) ", %0" : : "r" (irq));
+	isb();
+}
+
 struct irq_domain;
 int its_cpu_init(void);
 int its_init(struct device_node *node, struct rdists *rdists,
-- 
2.1.4



From marc.zyngier at arm.com  Thu Aug 13 01:28:42 2015
From: marc.zyngier at arm.com (Marc Zyngier)
Date: Thu, 13 Aug 2015 09:28:42 +0100
Subject: [PATCH v2 0/4] irqchip: GICv2/v3: Add support for irq_vcpu_affinity
Message-ID: <1439454526-1185-1-git-send-email-marc.zyngier@arm.com>

The GICv2 and GICv3 architectures allow an active physical interrupt
to be forwarded to a guest, and the guest to indirectly perform the
deactivation of the interrupt by performing an EOI on the virtual
interrupt (see for example the GICv2 spec, 3.2.1).

This allows some substantial performance improvement for level
triggered interrupts that otherwise have to be masked/unmasked in
VFIO, not to mention the required trap back to KVM when the guest
performs an EOI.

To enable this, the GICs need to be switched to a different EOImode,
where a taken interrupt can be left "active" (which prevents the same
interrupt from being taken again), while other interrupts are still
being processed normally.

We also use the new irq_set_vcpu_affinity hook that was introduced for
Intel's "Posted Interrupts" to determine whether or not to perform the
deactivation at EOI-time.

As all of this only makes sense when the kernel can behave as a
hypervisor, we only enable this mode on detecting that the kernel was
actually booted in HYP mode, and that the GIC supports this feature.

This series is a complete rework of a RFC I sent over a year ago:

http://lists.infradead.org/pipermail/linux-arm-kernel/2014-June/266328.html

Since then, a lot has been either merged (the irqchip_state) or reworked
(my active-timer series: http://www.spinics.net/lists/kvm/msg118768.html),
and this implements the last few bits for Eric Auger's series to
finally make it into the kernel:

https://lkml.org/lkml/2015/7/2/268
https://lkml.org/lkml/2015/7/6/291

With all these patches combined, physical interrupt routing from the
kernel into a VM becomes possible.

This has been tested on Juno (GICv2) and FastModel (GICv3). A branch
is available at:

git://git.kernel.org/pub/scm/linux/kernel/git/maz/arm-platforms.git irq/gic-irq-vcpu-affinity-v2

* From v1:
  - Fixes after review from Eric
  - Got rid of the cascaded GICv2 hack (it was broken anyway)
  - Folded the LPI deactivation patch (it makes more sense as part of
    the main one.
  - Some clarifying comments about the "deactivate on mask"
  - I haven't retained Eric's Reviewed/Tested-by, as the code as
    significantly changed on GICv2

Marc Zyngier (4):
  irqchip: GICv3: Convert to EOImode == 1
  irqchip: GICv3: Don't deactivate interrupts forwarded to a guest
  irqchip: GIC: Convert to EOImode == 1
  irqchip: GIC: Don't deactivate interrupts forwarded to a guest

 drivers/irqchip/irq-gic-v3.c       |  68 +++++++++++++++++++++--
 drivers/irqchip/irq-gic.c          | 109 ++++++++++++++++++++++++++++++++++++-
 include/linux/irqchip/arm-gic-v3.h |   9 +++
 include/linux/irqchip/arm-gic.h    |   4 ++
 4 files changed, 184 insertions(+), 6 deletions(-)

-- 
2.1.4



From marc.zyngier at arm.com  Thu Aug 13 01:28:45 2015
From: marc.zyngier at arm.com (Marc Zyngier)
Date: Thu, 13 Aug 2015 09:28:45 +0100
Subject: [PATCH v2 3/4] irqchip: GIC: Convert to EOImode == 1
In-Reply-To: <1439454526-1185-1-git-send-email-marc.zyngier@arm.com>
References: <1439454526-1185-1-git-send-email-marc.zyngier@arm.com>
Message-ID: <1439454526-1185-4-git-send-email-marc.zyngier@arm.com>

So far, GICv2 has been used in with EOImode == 0. The effect of this
mode is to perform the priority drop and the deactivation of the
interrupt at the same time.

While this works perfectly for Linux (we only have a single priority),
it causes issues when an interrupt is forwarded to a guest, and when
we want the guest to perform the EOI itself.

For this case, the GIC architecture provides EOImode == 1, where:
- A write to the EOI register drops the priority of the interrupt and leaves
it active. Other interrupts at the same priority level can now be taken,
but the active interrupt cannot be taken again
- A write to the DIR marks the interrupt as inactive, meaning it can
now be taken again.

We only enable this feature when booted in HYP mode and that
the device-tree reporte a suitable CPU interface. Observable behaviour
should remain unchanged.

Signed-off-by: Marc Zyngier <marc.zyngier at arm.com>
---
 drivers/irqchip/irq-gic.c       | 51 +++++++++++++++++++++++++++++++++++++++--
 include/linux/irqchip/arm-gic.h |  4 ++++
 2 files changed, 53 insertions(+), 2 deletions(-)

diff --git a/drivers/irqchip/irq-gic.c b/drivers/irqchip/irq-gic.c
index 4dd8826..b020c3a 100644
--- a/drivers/irqchip/irq-gic.c
+++ b/drivers/irqchip/irq-gic.c
@@ -46,6 +46,7 @@
 #include <asm/irq.h>
 #include <asm/exception.h>
 #include <asm/smp_plat.h>
+#include <asm/virt.h>
 
 #include "irq-gic-common.h"
 #include "irqchip.h"
@@ -82,6 +83,8 @@ static DEFINE_RAW_SPINLOCK(irq_controller_lock);
 #define NR_GIC_CPU_IF 8
 static u8 gic_cpu_map[NR_GIC_CPU_IF] __read_mostly;
 
+static struct static_key supports_deactivate = STATIC_KEY_INIT_TRUE;
+
 #ifndef MAX_GIC_NR
 #define MAX_GIC_NR	1
 #endif
@@ -137,6 +140,14 @@ static inline unsigned int gic_irq(struct irq_data *d)
 	return d->hwirq;
 }
 
+static inline bool primary_gic_irq(struct irq_data *d)
+{
+	if (MAX_GIC_NR > 1)
+		return irq_data_get_irq_chip_data(d) == &gic_data[0];
+
+	return true;
+}
+
 /*
  * Routines to acknowledge, disable and enable interrupts
  */
@@ -164,7 +175,14 @@ static void gic_unmask_irq(struct irq_data *d)
 
 static void gic_eoi_irq(struct irq_data *d)
 {
-	writel_relaxed(gic_irq(d), gic_cpu_base(d) + GIC_CPU_EOI);
+	u32 deact_offset = GIC_CPU_EOI;
+
+	if (static_key_true(&supports_deactivate)) {
+		if (primary_gic_irq(d))
+			deact_offset = GIC_CPU_DEACTIVATE;
+	}
+
+	writel_relaxed(gic_irq(d), gic_cpu_base(d) + deact_offset);
 }
 
 static int gic_irq_set_irqchip_state(struct irq_data *d,
@@ -272,11 +290,15 @@ static void __exception_irq_entry gic_handle_irq(struct pt_regs *regs)
 		irqnr = irqstat & GICC_IAR_INT_ID_MASK;
 
 		if (likely(irqnr > 15 && irqnr < 1021)) {
+			if (static_key_true(&supports_deactivate))
+				writel_relaxed(irqstat, cpu_base + GIC_CPU_EOI);
 			handle_domain_irq(gic->domain, irqnr, regs);
 			continue;
 		}
 		if (irqnr < 16) {
 			writel_relaxed(irqstat, cpu_base + GIC_CPU_EOI);
+			if (static_key_true(&supports_deactivate))
+				writel_relaxed(irqstat, cpu_base + GIC_CPU_DEACTIVATE);
 #ifdef CONFIG_SMP
 			handle_IPI(irqnr, regs);
 #endif
@@ -359,6 +381,10 @@ static void gic_cpu_if_up(void)
 {
 	void __iomem *cpu_base = gic_data_cpu_base(&gic_data[0]);
 	u32 bypass = 0;
+	u32 mode = 0;
+
+	if (static_key_true(&supports_deactivate))
+		mode = GIC_CPU_CTRL_EOImodeNS;
 
 	/*
 	* Preserve bypass disable bits to be written back later
@@ -366,7 +392,7 @@ static void gic_cpu_if_up(void)
 	bypass = readl(cpu_base + GIC_CPU_CTRL);
 	bypass &= GICC_DIS_BYPASS_MASK;
 
-	writel_relaxed(bypass | GICC_ENABLE, cpu_base + GIC_CPU_CTRL);
+	writel_relaxed(bypass | mode | GICC_ENABLE, cpu_base + GIC_CPU_CTRL);
 }
 
 
@@ -986,6 +1012,8 @@ void __init gic_init_bases(unsigned int gic_nr, int irq_start,
 		register_cpu_notifier(&gic_cpu_notifier);
 #endif
 		set_handle_irq(gic_handle_irq);
+		if (static_key_true(&supports_deactivate))
+			pr_info ("GIC: Using split EOI/Deactivate mode\n");
 	}
 
 	gic_dist_init(gic);
@@ -1001,6 +1029,7 @@ gic_of_init(struct device_node *node, struct device_node *parent)
 {
 	void __iomem *cpu_base;
 	void __iomem *dist_base;
+	struct resource cpu_res;
 	u32 percpu_offset;
 	int irq;
 
@@ -1013,6 +1042,16 @@ gic_of_init(struct device_node *node, struct device_node *parent)
 	cpu_base = of_iomap(node, 1);
 	WARN(!cpu_base, "unable to map gic cpu registers\n");
 
+	of_address_to_resource(node, 1, &cpu_res);
+
+	/*
+	 * Disable split EOI/Deactivate if either HYP is not available
+	 * or the CPU interface is too small.
+	 */
+	if (gic_cnt == 0 && (!is_hyp_mode_available() ||
+			     resource_size(&cpu_res) < SZ_8K))
+		static_key_slow_dec(&supports_deactivate);
+
 	if (of_property_read_u32(node, "cpu-offset", &percpu_offset))
 		percpu_offset = 0;
 
@@ -1132,6 +1171,14 @@ gic_v2_acpi_init(struct acpi_table_header *table)
 	}
 
 	/*
+	 * Disable split EOI/Deactivate if HYP is not available. ACPI
+	 * guarantees that we'll always have a GICv2, so the CPU
+	 * interface will always be the right size.
+	 */
+	if (!is_hyp_mode_available())
+		static_key_slow_dec(&supports_deactivate);
+
+	/*
 	 * Initialize zero GIC instance (no multi-GIC support). Also, set GIC
 	 * as default IRQ domain to allow for GSI registration and GSI to IRQ
 	 * number translation (see acpi_register_gsi() and acpi_gsi_to_irq()).
diff --git a/include/linux/irqchip/arm-gic.h b/include/linux/irqchip/arm-gic.h
index 9de976b..b1533c0 100644
--- a/include/linux/irqchip/arm-gic.h
+++ b/include/linux/irqchip/arm-gic.h
@@ -20,9 +20,13 @@
 #define GIC_CPU_ALIAS_BINPOINT		0x1c
 #define GIC_CPU_ACTIVEPRIO		0xd0
 #define GIC_CPU_IDENT			0xfc
+#define GIC_CPU_DEACTIVATE		0x1000
 
 #define GICC_ENABLE			0x1
 #define GICC_INT_PRI_THRESHOLD		0xf0
+
+#define GIC_CPU_CTRL_EOImodeNS		(1 << 9)
+
 #define GICC_IAR_INT_ID_MASK		0x3ff
 #define GICC_INT_SPURIOUS		1023
 #define GICC_DIS_BYPASS_MASK		0x1e0
-- 
2.1.4



From marc.zyngier at arm.com  Thu Aug 13 01:28:46 2015
From: marc.zyngier at arm.com (Marc Zyngier)
Date: Thu, 13 Aug 2015 09:28:46 +0100
Subject: [PATCH v2 4/4] irqchip: GIC: Don't deactivate interrupts forwarded to
 a guest
In-Reply-To: <1439454526-1185-1-git-send-email-marc.zyngier@arm.com>
References: <1439454526-1185-1-git-send-email-marc.zyngier@arm.com>
Message-ID: <1439454526-1185-5-git-send-email-marc.zyngier@arm.com>

Commit 0a4377de3056 ("genirq: Introduce irq_set_vcpu_affinity() to
target an interrupt to a VCPU") added just what we needed at the
lowest level to allow an interrupt to be deactivated by a guest.

When such a request reaches the GIC, it knows it doesn't need to
perform the deactivation anymore, and can safely leave the guest
do its magic. This of course requires additional support in both
VFIO and KVM.

Signed-off-by: Marc Zyngier <marc.zyngier at arm.com>
---
 drivers/irqchip/irq-gic.c | 58 +++++++++++++++++++++++++++++++++++++++++++++++
 1 file changed, 58 insertions(+)

diff --git a/drivers/irqchip/irq-gic.c b/drivers/irqchip/irq-gic.c
index b020c3a..ea691be 100644
--- a/drivers/irqchip/irq-gic.c
+++ b/drivers/irqchip/irq-gic.c
@@ -148,6 +148,34 @@ static inline bool primary_gic_irq(struct irq_data *d)
 	return true;
 }
 
+static inline bool cascading_gic_irq(struct irq_data *d)
+{
+	/*
+	 * If handler_data pointing to one of the secondary GICs, then
+	 * this is the cascading interrupt, and it cannot possibly be
+	 * forwarded.
+	 */
+	if (d->handler_data >= (void *)(gic_data + 1) &&
+	    d->handler_data <  (void *)(gic_data + MAX_GIC_NR))
+		return true;
+
+	return false;
+}
+
+static inline bool forwarded_irq(struct irq_data *d)
+{
+	/*
+	 * A forwarded interrupt:
+	 * - is on the primary GIC
+	 * - has its handler_data set to a value
+	 * - that isn't a secondary GIC
+	 */
+	if (primary_gic_irq(d) && d->handler_data && !cascading_gic_irq(d))
+		return true;
+
+	return false;
+}
+
 /*
  * Routines to acknowledge, disable and enable interrupts
  */
@@ -166,6 +194,18 @@ static int gic_peek_irq(struct irq_data *d, u32 offset)
 static void gic_mask_irq(struct irq_data *d)
 {
 	gic_poke_irq(d, GIC_DIST_ENABLE_CLEAR);
+	/*
+	 * When masking a forwarded interrupt, make sure it is
+	 * deactivated as well.
+	 *
+	 * This ensures that an interrupt that is getting
+	 * disabled/masked will not get "stuck", because there is
+	 * noone to deactivate it (guest is being terminated).
+	 */
+	if (static_key_true(&supports_deactivate)) {
+		if (forwarded_irq(d))
+			gic_poke_irq(d, GIC_DIST_ACTIVE_CLEAR);
+	}
 }
 
 static void gic_unmask_irq(struct irq_data *d)
@@ -178,6 +218,10 @@ static void gic_eoi_irq(struct irq_data *d)
 	u32 deact_offset = GIC_CPU_EOI;
 
 	if (static_key_true(&supports_deactivate)) {
+		/* Do not deactivate an IRQ forwarded to a vcpu. */
+		if (forwarded_irq(d))
+			return;
+
 		if (primary_gic_irq(d))
 			deact_offset = GIC_CPU_DEACTIVATE;
 	}
@@ -251,6 +295,19 @@ static int gic_set_type(struct irq_data *d, unsigned int type)
 	return gic_configure_irq(gicirq, type, base, NULL);
 }
 
+static int gic_irq_set_vcpu_affinity(struct irq_data *d, void *vcpu)
+{
+	/* Only interrupts on the primary GIC can be forwarded to a vcpu. */
+	if (static_key_true(&supports_deactivate)) {
+		if (primary_gic_irq(d) && !cascading_gic_irq(d)) {
+			d->handler_data = vcpu;
+			return 0;
+		}
+	}
+
+	return -EINVAL;
+}
+
 #ifdef CONFIG_SMP
 static int gic_set_affinity(struct irq_data *d, const struct cpumask *mask_val,
 			    bool force)
@@ -346,6 +403,7 @@ static struct irq_chip gic_chip = {
 #endif
 	.irq_get_irqchip_state	= gic_irq_get_irqchip_state,
 	.irq_set_irqchip_state	= gic_irq_set_irqchip_state,
+	.irq_set_vcpu_affinity	= gic_irq_set_vcpu_affinity,
 	.flags			= IRQCHIP_SET_TYPE_MASKED,
 };
 
-- 
2.1.4



From tony at atomide.com  Thu Aug 13 01:32:15 2015
From: tony at atomide.com (Tony Lindgren)
Date: Thu, 13 Aug 2015 01:32:15 -0700
Subject: [PATCH-next 2/4] arm: boot: dts: am4372: add ARM timers and SCU
 nodes
In-Reply-To: <1439409416-32673-3-git-send-email-balbi@ti.com>
References: <1439409416-32673-1-git-send-email-balbi@ti.com>
 <1439409416-32673-3-git-send-email-balbi@ti.com>
Message-ID: <20150813083215.GY4215@atomide.com>

* Felipe Balbi <balbi at ti.com> [150812 13:00]:
> AM437x devices sport SCU, TWD and Global timers,
> let's add them to DTS so they have a chance to
> probe and be used by Linux.

Applying this one into omap-for-v4.3/dt-v2. Not sure
if it will get merged as we're getting close to the
merge window. The rest we can patch once Russell has
reverted the bogus SMP dependency.

Regards,

Tony


From hanjun.guo at linaro.org  Thu Aug 13 01:34:13 2015
From: hanjun.guo at linaro.org (Hanjun Guo)
Date: Thu, 13 Aug 2015 16:34:13 +0800
Subject: [PATCH v2 0/2] net: thunder: Add ACPI support.
In-Reply-To: <55CB67E4.8030001@caviumnetworks.com>
References: <1439254717-2875-1-git-send-email-ddaney.cavm@gmail.com>
 <20150811.114908.1384923604512568161.davem@davemloft.net>
 <55CA5567.9010002@caviumnetworks.com>
 <20150812152337.GB5393@e104818-lin.cambridge.arm.com>
 <55CB67E4.8030001@caviumnetworks.com>
Message-ID: <55CC5685.4000807@linaro.org>

On 08/12/2015 11:36 PM, David Daney wrote:
> On 08/12/2015 08:23 AM, Catalin Marinas wrote:
>> On Tue, Aug 11, 2015 at 01:04:55PM -0700, David Daney wrote:
>>> On 08/11/2015 11:49 AM, David Miller wrote:
>>>> From: David Daney <ddaney.cavm at gmail.com>
>>>> Date: Mon, 10 Aug 2015 17:58:35 -0700
>>>>
>>>>> Change from v1:  Drop PHY binding part, use fwnode_property* APIs.
>>>>>
>>>>> The first patch (1/2) rearranges the existing code a little with no
>>>>> functional change to get ready for the second.  The second (2/2) does
>>>>> the actual work of adding support to extract the needed information
>>>> >from the ACPI tables.
>>>>
>>>> Series applied.
>>>
>>> Thank you very much.
>>>
>>>> In the future it might be better structured to try and get the OF
>>>> node, and if that fails then try and use the ACPI method to obtain
>>>> these values.
>>>
>>> Our current approach, as you can see in the patch, is the opposite.
>>> If ACPI
>>> is being used, prefer that over the OF device tree.
>>>
>>> You seem to be recommending precedence for OF.  It should be consistent
>>> across all drivers/sub-systems, so do you really think that OF before
>>> ACPI
>>> is the way to go?
>>
>> On arm64 (unless you use a vendor kernel), DT takes precedence over ACPI
>> if both arm provided to the kernel (and it's a fair assumption given
>> that ACPI on ARM is still in the early days). You could also force ACPI
>> with acpi=force on the kernel cmd line and the arch code will not
>> unflatten the DT even if it is provided, therefore is_of_node(fwnode)
>> returning false.

Yes. on the other hand, if no DT is provided, will try ACPI even
if no acpi=force on the kernel cmd line.

>>
>> I haven't looked at your driver in detail but something like AMD's
>> xgbe_probe() uses a single function for both DT and ACPI with
>> device_property_read_*() functions getting the information from the
>> correct place in either case. The ACPI vs DT precedence is handled by
>> the arch boot code, we never mix the two and confuse the drivers.
>>
>
> My long term plan is to create something like
> firmware_get_mac_address(), that would encapsulate  of_get_mac_address()
> and the ACPI equivalent.
>
> Same for firmware_phy_find_device().

I'm very keen on seeing that happens :)

Thanks
Hanjun


From daniel.lezcano at linaro.org  Thu Aug 13 01:35:16 2015
From: daniel.lezcano at linaro.org (Daniel Lezcano)
Date: Thu, 13 Aug 2015 10:35:16 +0200
Subject: [PATCH v2 1/5] clocksource: mediatek: do not enable GPT_CLK_EVT
 when setup
In-Reply-To: <1437552878-3684-1-git-send-email-yingjoe.chen@mediatek.com>
References: <CAGS+omD8k_Cfxv3bYyjmjtLbiavo-WmJPn0Z-CBhN_nnv65Tag@mail.gmail.com>
 <1437552878-3684-1-git-send-email-yingjoe.chen@mediatek.com>
Message-ID: <55CC56C4.8080201@linaro.org>

On 07/22/2015 10:14 AM, Yingjoe Chen wrote:
> Spurious mtk timer interrupt is noticed at boot and cause kernel
> crash. It seems if GPT is enabled, it will latch irq status even
> when its IRQ is disabled. When irq is enabled afterward, we see
> spurious interrupt.
> Change init flow to only enable GPT_CLK_SRC at mtk_timer_init.
>
> Acked-by: Matthias Brugger <matthias.bgg at gmail.com>
> Reviewed-by: Daniel Kurtz <djkurtz at chromium.org>
> Signed-off-by: Yingjoe Chen <yingjoe.chen at mediatek.com>
> ---
>
> Update to my patch [1], added __init as Daniel suggest. This is the
> only patch that need to change in that series, so I only sent this one.
>
> http://lists.infradead.org/pipermail/linux-mediatek/2015-July/001545.html
>
>   drivers/clocksource/mtk_timer.c | 16 ++++++++++------
>   1 file changed, 10 insertions(+), 6 deletions(-)
>
> diff --git a/drivers/clocksource/mtk_timer.c b/drivers/clocksource/mtk_timer.c
> index 68ab423..2ba5b66 100644
> --- a/drivers/clocksource/mtk_timer.c
> +++ b/drivers/clocksource/mtk_timer.c
> @@ -156,9 +156,11 @@ static void mtk_timer_global_reset(struct mtk_clock_event_device *evt)
>   	writel(0x3f, evt->gpt_base + GPT_IRQ_ACK_REG);
>   }
>
> -static void
> -mtk_timer_setup(struct mtk_clock_event_device *evt, u8 timer, u8 option)
> +static void __init mtk_timer_setup(struct mtk_clock_event_device *evt,
> +				   u8 timer, u8 option, bool enable)
>   {
> +	u32 val;
> +
>   	writel(TIMER_CTRL_CLEAR | TIMER_CTRL_DISABLE,
>   		evt->gpt_base + TIMER_CTRL_REG(timer));
>
> @@ -167,8 +169,10 @@ mtk_timer_setup(struct mtk_clock_event_device *evt, u8 timer, u8 option)
>
>   	writel(0x0, evt->gpt_base + TIMER_CMP_REG(timer));
>
> -	writel(TIMER_CTRL_OP(option) | TIMER_CTRL_ENABLE,
> -			evt->gpt_base + TIMER_CTRL_REG(timer));
> +	val = TIMER_CTRL_OP(option);
> +	if (enable)
> +		val |= TIMER_CTRL_ENABLE;
> +	writel(val, evt->gpt_base + TIMER_CTRL_REG(timer));

Instead of the 'enable' new option, I prefer a test with 'timer' with a 
comment:

	/*
	 * the timer hw is broken in that way ... bla bla, so we only
	 * enable the clocksource ...
	 */
	if (timer == GPT_CLK_SRC)
		val |= TIMER_CTRL_ENABLE;

That said, can you have a look at commit 1096be08 ?
"clockevents: sun5i: Fix setup_irq init sequence"

first and check if moving the interrupt request after the 
clockevents_config_and_register could fix your issue.

>   }
>
>   static void mtk_timer_enable_irq(struct mtk_clock_event_device *evt, u8 timer)
> @@ -235,12 +239,12 @@ static void __init mtk_timer_init(struct device_node *node)
>   	evt->ticks_per_jiffy = DIV_ROUND_UP(rate, HZ);
>
>   	/* Configure clock source */
> -	mtk_timer_setup(evt, GPT_CLK_SRC, TIMER_CTRL_OP_FREERUN);
> +	mtk_timer_setup(evt, GPT_CLK_SRC, TIMER_CTRL_OP_FREERUN, true);
>   	clocksource_mmio_init(evt->gpt_base + TIMER_CNT_REG(GPT_CLK_SRC),
>   			node->name, rate, 300, 32, clocksource_mmio_readl_up);
>
>   	/* Configure clock event */
> -	mtk_timer_setup(evt, GPT_CLK_EVT, TIMER_CTRL_OP_REPEAT);
> +	mtk_timer_setup(evt, GPT_CLK_EVT, TIMER_CTRL_OP_REPEAT, false);
>   	clockevents_config_and_register(&evt->dev, rate, 0x3,
>   					0xffffffff);




-- 
  <http://www.linaro.org/> Linaro.org ? Open source software for ARM SoCs

Follow Linaro:  <http://www.facebook.com/pages/Linaro> Facebook |
<http://twitter.com/#!/linaroorg> Twitter |
<http://www.linaro.org/linaro-blog/> Blog



From geert at linux-m68k.org  Thu Aug 13 01:41:09 2015
From: geert at linux-m68k.org (Geert Uytterhoeven)
Date: Thu, 13 Aug 2015 10:41:09 +0200
Subject: [PATCH 2/2] clk: Convert __clk_get_name(hw->clk) to
 clk_hw_get_name(hw)
In-Reply-To: <1439421161-17868-2-git-send-email-sboyd@codeaurora.org>
References: <1439421161-17868-1-git-send-email-sboyd@codeaurora.org>
 <1439421161-17868-2-git-send-email-sboyd@codeaurora.org>
Message-ID: <CAMuHMdXo4ChAfbi5h0okyw18LNM5iv-rfx_AO9e_u7QAB8Vx9A@mail.gmail.com>

On Thu, Aug 13, 2015 at 1:12 AM, Stephen Boyd <sboyd at codeaurora.org> wrote:
> Use the provider based method to get a clock's name so that we
> can get rid of the clk member in struct clk_hw one day. Mostly
> converted with the following coccinelle script.
>
> @@
> struct clk_hw *E;
> @@
>
> -__clk_get_name(E->clk)
> +clk_hw_get_name(E)
>
> Cc: Heiko Stuebner <heiko at sntech.de>
> Cc: Sylwester Nawrocki <s.nawrocki at samsung.com>
> Cc: Tomasz Figa <tomasz.figa at gmail.com>
> Cc: Peter De Schrijver <pdeschrijver at nvidia.com>
> Cc: Prashant Gaikwad <pgaikwad at nvidia.com>
> Cc: Stephen Warren <swarren at wwwdotorg.org>
> Cc: Thierry Reding <thierry.reding at gmail.com>
> Cc: Alexandre Courbot <gnurou at gmail.com>
> Cc: Tero Kristo <t-kristo at ti.com>
> Cc: Ulf Hansson <ulf.hansson at linaro.org>
> Cc: Sebastian Hesselbarth <sebastian.hesselbarth at gmail.com>
> Cc: Andrew Bresticker <abrestic at chromium.org>
> Cc: Ezequiel Garcia <ezequiel.garcia at imgtec.com>
> Cc: Ralf Baechle <ralf at linux-mips.org>
> Cc: Kevin Cernekee <cernekee at chromium.org>
> Cc: Geert Uytterhoeven <geert+renesas at glider.be>
> Cc: Ulrich Hecht <ulrich.hecht+renesas at gmail.com>
> Cc: linux-arm-kernel at lists.infradead.org
> Cc: linux-rockchip at lists.infradead.org
> Cc: linux-samsung-soc at vger.kernel.org
> Cc: linux-tegra at vger.kernel.org
> Cc: linux-omap at vger.kernel.org
> Signed-off-by: Stephen Boyd <sboyd at codeaurora.org>

>  drivers/clk/shmobile/clk-div6.c      |  2 +-

For the shmobile part:

Acked-by: Geert Uytterhoeven <geert+renesas at glider.be>

Gr{oetje,eeting}s,

                        Geert

--
Geert Uytterhoeven -- There's lots of Linux beyond ia32 -- geert at linux-m68k.org

In personal conversations with technical people, I call myself a hacker. But
when I'm talking to journalists I just say "programmer" or something like that.
                                -- Linus Torvalds


From LW at KARO-electronics.de  Thu Aug 13 01:41:50 2015
From: LW at KARO-electronics.de (Lothar =?UTF-8?B?V2HDn21hbm4=?=)
Date: Thu, 13 Aug 2015 10:41:50 +0200
Subject: [PATCH v3 1/4] edac: Add an function to retrieve the EDAC
 debugfs node
In-Reply-To: <20150813081537.GB20004@nazgul.tnic>
References: <1439326077-25507-1-git-send-email-lho@apm.com>
 <1439326077-25507-2-git-send-email-lho@apm.com>
 <20150812101219.GC14011@nazgul.tnic>
 <20150812104954.GD14011@nazgul.tnic>
 <CAPw-ZT=AFtyLt4CNGBzLZcdPr-ekJpQxKA4Y_AiDzqKfhF1-=w@mail.gmail.com>
 <CAPw-ZTkfAxqG6HQHU3WomrqRwXa+jyTWCg=ns1HKC323ds1yug@mail.gmail.com>
 <20150813081537.GB20004@nazgul.tnic>
Message-ID: <20150813104150.2c084a8c@ipc1.ka-ro>

Hi,

> On Wed, Aug 12, 2015 at 09:30:58PM -0700, Loc Ho wrote:
> > Okay... The 'inline' helps with the compiler warning. If I move all to
> > header file with 'static inline' and wrapper around CONFIG_EDAC_DEBUG,
> > don't I need to export and declare the variable 'edac_debugfs'? Are
> > you okay with export this variable?
> 
> You need to make edac_debugfs extern in the header and define it in
> edac_mc_sysfs.c.
> 
> But that's ok because edac_core.h will be included only by EDAC drivers
> and they're supposed to see edac_debugfs anyway...
> 
What's the point in having an accessor function that returns a driver
internal variable when this variable is exported anyway?
This will only further inconsistencies because half of the users will
use the variable directly and the other half will use the accessor
function.


Lothar Wa?mann
-- 
___________________________________________________________

Ka-Ro electronics GmbH | Pascalstra?e 22 | D - 52076 Aachen
Phone: +49 2408 1402-0 | Fax: +49 2408 1402-10
Gesch?ftsf?hrer: Matthias Kaussen
Handelsregistereintrag: Amtsgericht Aachen, HRB 4996

www.karo-electronics.de | info at karo-electronics.de
___________________________________________________________


From jassisinghbrar at gmail.com  Thu Aug 13 01:51:07 2015
From: jassisinghbrar at gmail.com (Jassi Brar)
Date: Thu, 13 Aug 2015 14:21:07 +0530
Subject: [PATCH v2 5/6] mailbox: Add generic mechanism for testing Mailbox
 Controllers
In-Reply-To: <20150812102328.GD18282@x1>
References: <1437990272-23111-1-git-send-email-lee.jones@linaro.org>
 <1437990272-23111-6-git-send-email-lee.jones@linaro.org>
 <CABb+yY20nQbiEEZeRvWTMUsJ2qgwRn8CrWvnFDSB-b1dgVaAuw@mail.gmail.com>
 <20150812102328.GD18282@x1>
Message-ID: <CABb+yY0A74Vy3-KOvj0URU_4zb2FAC7Yp3gmEwnFaBrD0mzt0w@mail.gmail.com>

On Wed, Aug 12, 2015 at 3:53 PM, Lee Jones <lee.jones at linaro.org> wrote:
> On Mon, 10 Aug 2015, Jassi Brar wrote:
>
>> On Mon, Jul 27, 2015 at 3:14 PM, Lee Jones <lee.jones at linaro.org> wrote:
>> > This particular Client implementation uses shared memory in order
>> > to pass messages between Mailbox users; however, it can be easily
>> > hacked to support any type of Controller.
>> >
>> > Signed-off-by: Lee Jones <lee.jones at linaro.org>
>> > ---
>> >  drivers/mailbox/Kconfig        |   7 ++
>> >  drivers/mailbox/Makefile       |   2 +
>> >  drivers/mailbox/mailbox-test.c | 210 +++++++++++++++++++++++++++++++++++++++++
>> >  3 files changed, 219 insertions(+)
>> >  create mode 100644 drivers/mailbox/mailbox-test.c
>> >
>> > diff --git a/drivers/mailbox/Kconfig b/drivers/mailbox/Kconfig
>> > index 2cc4c39..7720bde 100644
>> > --- a/drivers/mailbox/Kconfig
>> > +++ b/drivers/mailbox/Kconfig
>> > @@ -77,4 +77,11 @@ config STI_MBOX
>> >           Mailbox implementation for STMicroelectonics family chips with
>> >           hardware for interprocessor communication.
>> >
>> > +config MAILBOX_TEST
>> > +       tristate "Mailbox Test Client"
>> > +       depends on OF
>> > +       help
>> > +         Test client to help with testing new Controller driver
>> > +         implementations.
>> > +
>> >  endif
>> > diff --git a/drivers/mailbox/Makefile b/drivers/mailbox/Makefile
>> > index 7cb4766..92435ef 100644
>> > --- a/drivers/mailbox/Makefile
>> > +++ b/drivers/mailbox/Makefile
>> > @@ -2,6 +2,8 @@
>> >
>> >  obj-$(CONFIG_MAILBOX)          += mailbox.o
>> >
>> > +obj-$(CONFIG_MAILBOX_TEST)     += mailbox-test.o
>> > +
>> >  obj-$(CONFIG_ARM_MHU)  += arm_mhu.o
>> >
>> >  obj-$(CONFIG_PL320_MBOX)       += pl320-ipc.o
>> > diff --git a/drivers/mailbox/mailbox-test.c b/drivers/mailbox/mailbox-test.c
>> > new file mode 100644
>> > index 0000000..10bfe3a
>> > --- /dev/null
>> > +++ b/drivers/mailbox/mailbox-test.c
>> > @@ -0,0 +1,210 @@
>> > +/*
>> > + * Copyright (C) 2015 ST Microelectronics
>> > + *
>> > + * Author: Lee Jones <lee.jones at linaro.org>
>> > + *
>> > + * This program is free software; you can redistribute it and/or modify
>> > + * it under the terms of the GNU General Public License as published by
>> > + * the Free Software Foundation; either version 2 of the License, or
>> > + * (at your option) any later version.
>> > + */
>> > +
>> > +#include <linux/debugfs.h>
>> > +#include <linux/err.h>
>> > +#include <linux/kernel.h>
>> > +#include <linux/mailbox_client.h>
>> > +#include <linux/module.h>
>> > +#include <linux/of.h>
>> > +#include <linux/platform_device.h>
>> > +#include <linux/slab.h>
>> > +#include <linux/uaccess.h>
>> > +
>> > +#define MBOX_MAX_MSG_LEN 128
>> > +
>> > +static struct dentry *root_debugfs_dir;
>> > +
>> > +struct mbox_test_device {
>> > +       struct device           *dev;
>> > +       struct mbox_chan        *tx_channel;
>> > +       struct mbox_chan        *rx_channel;
>> > +       void __iomem            *mmio;
>> > +
>> > +};
>> > +
>> > +static ssize_t mbox_test_write(struct file *filp,
>> > +                              const char __user *userbuf,
>> > +                              size_t count, loff_t *ppos)
>> > +{
>> > +       struct mbox_test_device *tdev = filp->private_data;
>> > +       char *message;
>> > +       int ret;
>> > +
>> > +       if (count > MBOX_MAX_MSG_LEN) {
>> > +               dev_err(tdev->dev,
>> > +                       "Message length %d greater than max allowed %d\n",
>> > +                       count, MBOX_MAX_MSG_LEN);
>> > +               return -EINVAL;
>> > +       }
>> > +
>> > +       message = kzalloc(count, GFP_KERNEL);
>> > +       if (!message)
>> > +               return -ENOMEM;
>> > +
>> > +       ret = copy_from_user(message, userbuf, count);
>> > +       if (ret)
>> > +               return -EFAULT;
>> > +
>> > +       print_hex_dump(KERN_ERR, "Client: Sending: ", DUMP_PREFIX_ADDRESS,
>> > +                      16, 1, message, 16, true);
>> > +
>> > +       ret = mbox_send_message(tdev->tx_channel, message);
>> > +       if (ret < 0)
>> > +               dev_err(tdev->dev, "Failed to send message via mailbox\n");
>> > +
>> > +       kfree(message);
>> > +
>> > +       return ret < 0 ? ret : count;
>> > +}
>> > +
>> > +static const struct file_operations mbox_test_ops = {
>> > +       .write  = mbox_test_write,
>> > +       .open   = simple_open,
>> > +       .llseek = generic_file_llseek,
>> > +};
>> > +
>> > +static int mbox_test_add_debugfs(struct platform_device *pdev,
>> > +                                struct mbox_test_device *tdev)
>> > +{
>> > +       if (!debugfs_initialized())
>> > +               return 0;
>> > +
>> > +       root_debugfs_dir = debugfs_create_dir("mailbox", NULL);
>> > +       if (!root_debugfs_dir) {
>> > +               dev_err(&pdev->dev, "Failed to create Mailbox debugfs\n");
>> > +               return -EINVAL;
>> > +       }
>> > +
>> > +       debugfs_create_file("send-message", 0200, root_debugfs_dir,
>> > +                           tdev, &mbox_test_ops);
>> > +
>> > +       return 0;
>> > +}
>> > +
>> > +static void mbox_test_receive_message(struct mbox_client *client, void *message)
>> > +{
>> > +       struct mbox_test_device *tdev = dev_get_drvdata(client->dev);
>> > +
>> > +       if (!tdev->mmio) {
>> > +               dev_info(tdev->dev, "Client: Recived something [read mmio]\n");
>> > +               return;
>> > +       }
>> > +
>> > +       print_hex_dump(KERN_ERR, "Client: from co-proc: ", DUMP_PREFIX_ADDRESS,
>> > +                      16, 1, tdev->mmio, MBOX_MAX_MSG_LEN, true);
>> > +}
>> > +
>> > +static void mbox_test_prepare_message(struct mbox_client *client, void *message)
>> > +{
>> > +       struct mbox_test_device *tdev = dev_get_drvdata(client->dev);
>> > +
>> > +       if (tdev->mmio)
>> > +               memcpy(tdev->mmio, message, MBOX_MAX_MSG_LEN);
>> >
>> This is unlikely to work. Those platforms that need to send a 2 part
>> message, they do :
>> (a) Signal/Command/Target code via some controller register (via
>> mbox_send_message).
>> (b) Setup the payload in Shared-Memory (via tx_prepare).
>>
>> This test driver assumes both are the same. I think you have to
>> declare something like
>
> This driver assumes that the framework will call client->tx_prepare()
> first, which satisfies (b).  It then assumes controller->send_data()
> will be invoked, which will send the platform specific
> signal/command/target code, which then satisfies (a).
>
Yeah, but what would be that code? Who provides that?

> In what way does it assume they are the same?
>
notice the 'message' pointer in
mbox_send_message(tdev->tx_channel, message);
    and
memcpy(tdev->mmio, message, MBOX_MAX_MSG_LEN);

>> struct mbox_test_message { /* same for TX and RX */
>>           unsigned sig_len;
>>           void *signal;               /* rx/tx via mailbox api */
>>           unsigned pl_len;
>>           void *payload;           /* rx/tx via shared-memory */
>> };
>
> How do you think this should be set and use these?
>
The userspace would want to specify the command code (32bits or not)
that would be passed via the fifo/register of the controller. So we
need signal[]

The data to be passed via share-memory could be provided by userspace
via the payload[] array.


>> > +static void mbox_test_message_sent(struct mbox_client *client,
>> > +                                  void *message, int r)
>> > +{
>> > +       if (r)
>> > +               dev_warn(client->dev,
>> > +                        "Client: Message could not be sent: %d\n", r);
>> > +       else
>> > +               dev_info(client->dev,
>> > +                        "Client: Message sent\n");
>> > +}
>> > +
>> > +static struct mbox_chan *
>> > +mbox_test_request_channel(struct platform_device *pdev, const char *name)
>> > +{
>> > +       struct mbox_client *client;
>> > +
>> > +       client = devm_kzalloc(&pdev->dev, sizeof(*client), GFP_KERNEL);
>> > +       if (!client)
>> > +               return ERR_PTR(-ENOMEM);
>> > +
>> > +       client->dev             = &pdev->dev;
>> > +       client->rx_callback     = mbox_test_receive_message;
>> > +       client->tx_prepare      = mbox_test_prepare_message;
>> > +       client->tx_done         = mbox_test_message_sent;
>> > +       client->tx_block        = true;
>> > +       client->knows_txdone    = false;
>> > +       client->tx_tout         = 500;
>> > +
>> > +       return mbox_request_channel_byname(client, name);
>> > +}
>> > +
>> > +static int mbox_test_probe(struct platform_device *pdev)
>> > +{
>> > +       struct mbox_test_device *tdev;
>> > +       struct resource *res;
>> > +       int ret;
>> > +
>> > +       tdev = devm_kzalloc(&pdev->dev, sizeof(*tdev), GFP_KERNEL);
>> > +       if (!tdev)
>> > +               return -ENOMEM;
>> > +
>> > +       /* It's okay for MMIO to be NULL */
>> > +       res = platform_get_resource(pdev, IORESOURCE_MEM, 0);
>> > +       tdev->mmio = devm_ioremap_resource(&pdev->dev, res);
>> > +       if (IS_ERR(tdev->mmio))
>> > +               tdev->mmio = NULL;
>> > +
>> > +       tdev->tx_channel = mbox_test_request_channel(pdev, "tx");
>> > +       if (IS_ERR(tdev->tx_channel))
>> > +               return PTR_ERR(tdev->tx_channel);
>> > +
>> > +       tdev->rx_channel = mbox_test_request_channel(pdev, "rx");
>> > +       if (IS_ERR(tdev->rx_channel))
>> > +               return PTR_ERR(tdev->rx_channel);
>> > +
>> Should it really fail on TX or RX only clients?
>
> Good question.  Probably not, but I guess we'd need a flag for that.
>
Just assume 1 channel. You can't make it receive if the controller
can't do rx, so the userspace will simply block on read requests. And
you can't make the controller send, if it can't. So any write attempt
will simply return with an error.
 And we are going to need very platform specific knowledge to execute
the tests. It's not like some loop enumerating all possible
combinations of parameters that the api must pass... so we are good.

>> It takes write from userspace but shouldn't it also provide data
>> received to the userspace?
>
> Currently we only print the returning message.  If you want me to put
> it in a userspace file too, that's not an issue.
>
Ideally we should support 'read' just like write.

thanks.


From bp at alien8.de  Thu Aug 13 01:52:01 2015
From: bp at alien8.de (Borislav Petkov)
Date: Thu, 13 Aug 2015 10:52:01 +0200
Subject: [PATCH v3 1/4] edac: Add an function to retrieve the EDAC
 debugfs node
In-Reply-To: <20150813104150.2c084a8c@ipc1.ka-ro>
References: <1439326077-25507-1-git-send-email-lho@apm.com>
 <1439326077-25507-2-git-send-email-lho@apm.com>
 <20150812101219.GC14011@nazgul.tnic>
 <20150812104954.GD14011@nazgul.tnic>
 <CAPw-ZT=AFtyLt4CNGBzLZcdPr-ekJpQxKA4Y_AiDzqKfhF1-=w@mail.gmail.com>
 <CAPw-ZTkfAxqG6HQHU3WomrqRwXa+jyTWCg=ns1HKC323ds1yug@mail.gmail.com>
 <20150813081537.GB20004@nazgul.tnic>
 <20150813104150.2c084a8c@ipc1.ka-ro>
Message-ID: <20150813085201.GC20004@nazgul.tnic>

On Thu, Aug 13, 2015 at 10:41:50AM +0200, Lothar Wa?mann wrote:
> What's the point in having an accessor function that returns a driver
> internal variable when this variable is exported anyway?

Not driver-internal but EDAC-core internal.

> This will only further inconsistencies because half of the users will
> use the variable directly and the other half will use the accessor
> function.

The idea is that it is not visible outside of EDAC. The EDAC drivers
themselves should see it. And yes, I admit that the accessors are maybe
redundant then since EDAC drivers can use edac_debugfs ptr directly.

Hmm, and that's ok too because my other concern about future refactoring
is taken care of too because as long as all users of edac_debugfs are
confined to drivers/edac/, changing stuff there is easy.

Ok, I'm convinced, Loc, feel free to drop the accessors in your next
version.

Thanks.

-- 
Regards/Gruss,
    Boris.

ECO tip #101: Trim your mails when you reply.
--


From sudeep.holla at arm.com  Thu Aug 13 01:54:07 2015
From: sudeep.holla at arm.com (Sudeep Holla)
Date: Thu, 13 Aug 2015 09:54:07 +0100
Subject: [PATCH v2 2/6] genirq: fix irqchip_set_wake_parent if
 IRQCHIP_SKIP_SET_WAKE
In-Reply-To: <1439401562-28874-3-git-send-email-grygorii.strashko@ti.com>
References: <1439401562-28874-1-git-send-email-grygorii.strashko@ti.com>
 <1439401562-28874-3-git-send-email-grygorii.strashko@ti.com>
Message-ID: <55CC5B2F.7060503@arm.com>



On 12/08/15 18:45, Grygorii Strashko wrote:
> The irqchip_set_wake_parent should not fail if IRQ chip
> specifies IRQCHIP_SKIP_SET_WAKE. Otherwise, IRQ wakeup
> configuration can't be propagated properly through IRQ
> domains hierarchy.
>
> In case of TI OMAP DRA7 the issue reproduced with following
> configuration:
> ARM GIC<-OMAP wakeupgen<-TI CBAR<-GPIO<-GPIO pcf857x<-gpio_key
>
> gpio_key is wakeup source
>
> Failure is reproduced during suspend/resume to RAM:
> suspend:
>   - gpio_keys_suspend
>     enable_irq_wake
>       + pcf857x_irq_set_wake
>         + omap_gpio_wake_enable
>           + TI CBAR irq_chip_set_wake_parent
>             + OMAP wakeupgen has no .irq_set_wake()
>             and -ENOSYS will be returned
>
> resume:
>   - gpio_keys_resume
>     + disable_irq_wake
>       + irq_set_irq_wake
>         + WARN(1, "Unbalanced IRQ %d wake disable\n", irq);
>
> Fixes: 08b55e2a9208 ('genirq: Add irqchip_set_wake_parent')
> Signed-off-by: Grygorii Strashko <grygorii.strashko at ti.com>
> ---
>   kernel/irq/chip.c | 4 ++++
>   1 file changed, 4 insertions(+)
>
> diff --git a/kernel/irq/chip.c b/kernel/irq/chip.c
> index 6de638b..bdb1b9d 100644
> --- a/kernel/irq/chip.c
> +++ b/kernel/irq/chip.c
> @@ -1024,6 +1024,10 @@ int irq_chip_set_vcpu_affinity_parent(struct irq_data *data, void *vcpu_info)
>   int irq_chip_set_wake_parent(struct irq_data *data, unsigned int on)
>   {
>   	data = data->parent_data;
> +
> +	if (irq_data_get_irq_chip(data)->flags & IRQCHIP_SKIP_SET_WAKE)
> +		return 0;
> +

[Nit] I think the irq core can access data->chip directly. Either way,
it's better to be consistent, the statement following doesn't use helper
function.

Otherwise looks good to me.

Regards,
Sudeep

>   	if (data->chip->irq_set_wake)
>   		return data->chip->irq_set_wake(data, on);
>
>


From sebastian.hesselbarth at gmail.com  Thu Aug 13 01:56:31 2015
From: sebastian.hesselbarth at gmail.com (Sebastian Hesselbarth)
Date: Thu, 13 Aug 2015 10:56:31 +0200
Subject: [PATCH 2/2] clk: Convert __clk_get_name(hw->clk) to
 clk_hw_get_name(hw)
In-Reply-To: <1439421161-17868-2-git-send-email-sboyd@codeaurora.org>
References: <1439421161-17868-1-git-send-email-sboyd@codeaurora.org>
 <1439421161-17868-2-git-send-email-sboyd@codeaurora.org>
Message-ID: <55CC5BBF.9060600@gmail.com>

On 08/13/2015 01:12 AM, Stephen Boyd wrote:
> Use the provider based method to get a clock's name so that we
> can get rid of the clk member in struct clk_hw one day. Mostly
> converted with the following coccinelle script.
>
> @@
> struct clk_hw *E;
> @@
>
> -__clk_get_name(E->clk)
> +clk_hw_get_name(E)
[...]
> Signed-off-by: Stephen Boyd <sboyd at codeaurora.org>
> ---
>   drivers/clk/berlin/berlin2-pll.c     |  4 ++--

For Berlin,

Acked-by: Sebastian Hesselbarth <sebastian.hesselbarth at gmail.com>

Thanks!

[...]
> diff --git a/drivers/clk/berlin/berlin2-pll.c b/drivers/clk/berlin/berlin2-pll.c
> index f4b8d324b083..1c2294d3ba85 100644
> --- a/drivers/clk/berlin/berlin2-pll.c
> +++ b/drivers/clk/berlin/berlin2-pll.c
> @@ -61,7 +61,7 @@ berlin2_pll_recalc_rate(struct clk_hw *hw, unsigned long parent_rate)
>   	fbdiv = (val >> map->fbdiv_shift) & FBDIV_MASK;
>   	rfdiv = (val >> map->rfdiv_shift) & RFDIV_MASK;
>   	if (rfdiv == 0) {
> -		pr_warn("%s has zero rfdiv\n", __clk_get_name(hw->clk));
> +		pr_warn("%s has zero rfdiv\n", clk_hw_get_name(hw));
>   		rfdiv = 1;
>   	}
>
> @@ -70,7 +70,7 @@ berlin2_pll_recalc_rate(struct clk_hw *hw, unsigned long parent_rate)
>   	vcodiv = map->vcodiv[vcodivsel];
>   	if (vcodiv == 0) {
>   		pr_warn("%s has zero vcodiv (index %d)\n",
> -			__clk_get_name(hw->clk), vcodivsel);
> +			clk_hw_get_name(hw), vcodivsel);
>   		vcodiv = 1;
>   	}



From geert at linux-m68k.org  Thu Aug 13 01:57:38 2015
From: geert at linux-m68k.org (Geert Uytterhoeven)
Date: Thu, 13 Aug 2015 10:57:38 +0200
Subject: [PATCH 2/9] PM / Domains: Remove dev->driver check for runtime PM
In-Reply-To: <7hfv3onv5c.fsf@deeprootsystems.com>
References: <1438731339-58317-1-git-send-email-lina.iyer@linaro.org>
 <1438731339-58317-3-git-send-email-lina.iyer@linaro.org>
 <7hfv3onv5c.fsf@deeprootsystems.com>
Message-ID: <CAMuHMdVeffa-jgXuSjDQBKTrhgW-d87OKzs1iXX+4y-9U_AJbg@mail.gmail.com>

Hi Kevin,

On Wed, Aug 12, 2015 at 9:50 PM, Kevin Hilman <khilman at kernel.org> wrote:
> Lina Iyer <lina.iyer at linaro.org> writes:
>
>> Remove check for driver of a device, for runtime PM. Device may be
>> suspended without an explicit driver. This check seems to be vestigial
>> and incorrect in the current context.
>
> This one should probably have been RFC.
>
> For a little more context here, this was uncovered when experimenting
> with using runtime PM for CPU devices which don't have a dev->driver.
>
> This check might have made sense before PM domains, but with PM domains,
> it's entirely possible to have a simple device without a driver and the
> PM domain handles all the necesary PM, so I think this check
> could/should be removed.
>
> Thoughts?

Simple devices without a driver aren't handled automatically.
At minimum, the driver should call pm_runtime_enable(), cfr.
drivers/bus/simple-pm-bus.c.

Gr{oetje,eeting}s,

                        Geert

--
Geert Uytterhoeven -- There's lots of Linux beyond ia32 -- geert at linux-m68k.org

In personal conversations with technical people, I call myself a hacker. But
when I'm talking to journalists I just say "programmer" or something like that.
                                -- Linus Torvalds


From sudeep.holla at arm.com  Thu Aug 13 01:58:20 2015
From: sudeep.holla at arm.com (Sudeep Holla)
Date: Thu, 13 Aug 2015 09:58:20 +0100
Subject: [PATCH v2 3/6] genirq: introduce irq_chip_set_type_parent() helper
In-Reply-To: <1439401562-28874-4-git-send-email-grygorii.strashko@ti.com>
References: <1439401562-28874-1-git-send-email-grygorii.strashko@ti.com>
 <1439401562-28874-4-git-send-email-grygorii.strashko@ti.com>
Message-ID: <55CC5C2C.4080301@arm.com>



On 12/08/15 18:45, Grygorii Strashko wrote:
> It's expected to use this helper when the current
> domain doesn't implement .irq_set_type(),  but expect
> the parent to do so.
>
> Signed-off-by: Grygorii Strashko <grygorii.strashko at ti.com>
> ---
>   include/linux/irq.h |  1 +
>   kernel/irq/chip.c   | 20 ++++++++++++++++++++
>   2 files changed, 21 insertions(+)
>
> diff --git a/include/linux/irq.h b/include/linux/irq.h
> index 92188b0..51744bc 100644
> --- a/include/linux/irq.h
> +++ b/include/linux/irq.h
> @@ -484,6 +484,7 @@ extern int irq_chip_set_affinity_parent(struct irq_data *data,
>   extern int irq_chip_set_wake_parent(struct irq_data *data, unsigned int on);
>   extern int irq_chip_set_vcpu_affinity_parent(struct irq_data *data,
>   					     void *vcpu_info);
> +extern int irq_chip_set_type_parent(struct irq_data *data, unsigned int type);
>   #endif
>
>   /* Handling of unhandled and spurious interrupts: */
> diff --git a/kernel/irq/chip.c b/kernel/irq/chip.c
> index bdb1b9d..b48938b 100644
> --- a/kernel/irq/chip.c
> +++ b/kernel/irq/chip.c
> @@ -985,6 +985,26 @@ int irq_chip_set_affinity_parent(struct irq_data *data,
>   }
>
>   /**
> + * irq_chip_set_type_parent - Set IRQ type on the parent interrupt
> + * @data:	Pointer to interrupt specific data
> + * @type:	IRQ_TYPE_{LEVEL,EDGE}_* value - see include/linux/irq.h
> + *
> + * Conditional, as the underlying parent chip might not implement it.
> + */
> +int irq_chip_set_type_parent(struct irq_data *data, unsigned int type)
> +{
> +	data = data->parent_data;
> +
> +	if (irq_data_get_irq_chip(data)->flags & IRQCHIP_SKIP_SET_WAKE)
> +		return 0;
> +

I think this is unrelated here(perhaps copy-paste error ?). I fail to
see how wakeup and trigger type are related.

Regards,
Sudeep


From hdegoede at redhat.com  Thu Aug 13 01:58:44 2015
From: hdegoede at redhat.com (Hans de Goede)
Date: Thu, 13 Aug 2015 10:58:44 +0200
Subject: [linux-sunxi] [PATCH v2] pinctrl: sun4i: add spdif to pin
 description.
In-Reply-To: <1439400468-1563-2-git-send-email-codekipper@gmail.com>
References: <1439400468-1563-1-git-send-email-codekipper@gmail.com>
 <1439400468-1563-2-git-send-email-codekipper@gmail.com>
Message-ID: <55CC5C44.5060507@redhat.com>

Hi,

On 12-08-15 19:27, codekipper at gmail.com wrote:
> From: Marcus Cooper <codekipper at gmail.com>
>
> Signed-off-by: Marcus Cooper <codekipper at gmail.com>

LGTM:

Reviewed-by: Hans de Goede <hdegoede at redhat.com>

Regards,

Hans

> ---
>   drivers/pinctrl/sunxi/pinctrl-sun4i-a10.c | 17 ++++++++++++++---
>   1 file changed, 14 insertions(+), 3 deletions(-)
>
> diff --git a/drivers/pinctrl/sunxi/pinctrl-sun4i-a10.c b/drivers/pinctrl/sunxi/pinctrl-sun4i-a10.c
> index 7376a97..862a096 100644
> --- a/drivers/pinctrl/sunxi/pinctrl-sun4i-a10.c
> +++ b/drivers/pinctrl/sunxi/pinctrl-sun4i-a10.c
> @@ -135,7 +135,14 @@ static const struct sunxi_desc_pin sun4i_a10_pins[] = {
>   	SUNXI_PIN(SUNXI_PINCTRL_PIN(B, 3),
>   		  SUNXI_FUNCTION(0x0, "gpio_in"),
>   		  SUNXI_FUNCTION(0x1, "gpio_out"),
> -		  SUNXI_FUNCTION(0x2, "ir0")),		/* TX */
> +		  SUNXI_FUNCTION(0x2, "ir0"),		/* TX */
> +		/*
> +		 * The SPDIF block is not referenced at all in the A10 user
> +		 * manual. However it is described in the code leaked and the
> +		 * pin descriptions are declared in the A20 user manual which
> +		 * is pin compatible with this device.
> +		 */
> +		  SUNXI_FUNCTION(0x4, "spdif")),        /* SPDIF MCLK */
>   	SUNXI_PIN(SUNXI_PINCTRL_PIN(B, 4),
>   		  SUNXI_FUNCTION(0x0, "gpio_in"),
>   		  SUNXI_FUNCTION(0x1, "gpio_out"),
> @@ -176,11 +183,15 @@ static const struct sunxi_desc_pin sun4i_a10_pins[] = {
>   		  SUNXI_FUNCTION(0x0, "gpio_in"),
>   		  SUNXI_FUNCTION(0x1, "gpio_out"),
>   		  SUNXI_FUNCTION(0x2, "i2s"),		/* DI */
> -		  SUNXI_FUNCTION(0x3, "ac97")),		/* DI */
> +		  SUNXI_FUNCTION(0x3, "ac97"),		/* DI */
> +		/* Undocumented mux function - See SPDIF MCLK above */
> +		  SUNXI_FUNCTION(0x4, "spdif")),        /* SPDIF IN */
>   	SUNXI_PIN(SUNXI_PINCTRL_PIN(B, 13),
>   		  SUNXI_FUNCTION(0x0, "gpio_in"),
>   		  SUNXI_FUNCTION(0x1, "gpio_out"),
> -		  SUNXI_FUNCTION(0x2, "spi2")),		/* CS1 */
> +		  SUNXI_FUNCTION(0x2, "spi2"),		/* CS1 */
> +		/* Undocumented mux function - See SPDIF MCLK above */
> +		  SUNXI_FUNCTION(0x4, "spdif")),        /* SPDIF OUT */
>   	SUNXI_PIN(SUNXI_PINCTRL_PIN(B, 14),
>   		  SUNXI_FUNCTION(0x0, "gpio_in"),
>   		  SUNXI_FUNCTION(0x1, "gpio_out"),
>


From lorenzo.pieralisi at arm.com  Thu Aug 13 02:01:17 2015
From: lorenzo.pieralisi at arm.com (Lorenzo Pieralisi)
Date: Thu, 13 Aug 2015 10:01:17 +0100
Subject: [PATCH 2/2] Convert smsc911x to use ACPI as well as DT
In-Reply-To: <20150813082759.GB5468@xora-haswell.xora.org.uk>
References: <1439417187-21411-1-git-send-email-jeremy.linton@arm.com>
 <1439417187-21411-3-git-send-email-jeremy.linton@arm.com>
 <20150813082759.GB5468@xora-haswell.xora.org.uk>
Message-ID: <20150813090117.GA13833@red-moon>

On Thu, Aug 13, 2015 at 09:27:59AM +0100, Graeme Gregory wrote:
> On Wed, Aug 12, 2015 at 05:06:27PM -0500, Jeremy Linton wrote:
> > Add ACPI bindings for the smsc911x driver. Convert the DT specific calls
> > to nonspecific device* calls, This allows the driver to work
> > with both ACPI and DT configurations. Ethernet should now work when using
> > ACPI on ARM Juno.

Last sentence does not belong in the commit log.

> > 
> > Signed-off-by: Jeremy Linton <jeremy.linton at arm.com>
> 
> The code looks fine to me.
> 
> Currently the compulsary DT properties seem to match the "approved" ACPI
> NIC properties from here
> 
> http://www.uefi.org/sites/default/files/resources/nic-request-v2.pdf

What about _DSD device specific properties (eg "smsc,save-mac-address") ?
Are we taking 1:1 translation between DT and ACPI for granted ?

I thought some process must be put in place to define the corresponding
bindings in ACPI before starting this mechanical translation or maybe
I missed something, I would like to understand.

How does the device specific _DSD definitions work in ACPI world ? Where
are they published ? How will we translate those to DT bindings if there
is need ?

Lorenzo

> Reviewed-by: Graeme Gregory <graeme.gregory at linaro.org>
> 
> Thanks
> 
> > ---
> >  drivers/net/ethernet/smsc/smsc911x.c | 48 +++++++++++++++++-------------------
> >  1 file changed, 22 insertions(+), 26 deletions(-)
> > 
> > diff --git a/drivers/net/ethernet/smsc/smsc911x.c b/drivers/net/ethernet/smsc/smsc911x.c
> > index 959aeea..0f21aa3 100644
> > --- a/drivers/net/ethernet/smsc/smsc911x.c
> > +++ b/drivers/net/ethernet/smsc/smsc911x.c
> > @@ -59,7 +59,9 @@
> >  #include <linux/of_device.h>
> >  #include <linux/of_gpio.h>
> >  #include <linux/of_net.h>
> > +#include <linux/acpi.h>
> >  #include <linux/pm_runtime.h>
> > +#include <linux/property.h>
> >  
> >  #include "smsc911x.h"
> >  
> > @@ -2362,59 +2364,46 @@ static const struct smsc911x_ops shifted_smsc911x_ops = {
> >  	.tx_writefifo = smsc911x_tx_writefifo_shift,
> >  };
> >  
> > -#ifdef CONFIG_OF
> > -static int smsc911x_probe_config_dt(struct smsc911x_platform_config *config,
> > -				    struct device_node *np)
> > +static int smsc911x_probe_config(struct smsc911x_platform_config *config,
> > +				 struct device *dev)
> >  {
> > -	const char *mac;
> >  	u32 width = 0;
> >  
> > -	if (!np)
> > +	if (!dev)
> >  		return -ENODEV;
> >  
> > -	config->phy_interface = of_get_phy_mode(np);
> > +	config->phy_interface = device_get_phy_mode(dev);
> >  
> > -	mac = of_get_mac_address(np);
> > -	if (mac)
> > -		memcpy(config->mac, mac, ETH_ALEN);
> > +	device_get_mac_address(dev, config->mac, ETH_ALEN);
> >  
> > -	of_property_read_u32(np, "reg-shift", &config->shift);
> > +	device_property_read_u32(dev, "reg-shift", &config->shift);
> >  
> > -	of_property_read_u32(np, "reg-io-width", &width);
> > +	device_property_read_u32(dev, "reg-io-width", &width);
> >  	if (width == 4)
> >  		config->flags |= SMSC911X_USE_32BIT;
> >  	else
> >  		config->flags |= SMSC911X_USE_16BIT;
> >  
> > -	if (of_get_property(np, "smsc,irq-active-high", NULL))
> > +	if (device_property_present(dev, "smsc,irq-active-high"))
> >  		config->irq_polarity = SMSC911X_IRQ_POLARITY_ACTIVE_HIGH;
> >  
> > -	if (of_get_property(np, "smsc,irq-push-pull", NULL))
> > +	if (device_property_present(dev, "smsc,irq-push-pull"))
> >  		config->irq_type = SMSC911X_IRQ_TYPE_PUSH_PULL;
> >  
> > -	if (of_get_property(np, "smsc,force-internal-phy", NULL))
> > +	if (device_property_present(dev, "smsc,force-internal-phy"))
> >  		config->flags |= SMSC911X_FORCE_INTERNAL_PHY;
> >  
> > -	if (of_get_property(np, "smsc,force-external-phy", NULL))
> > +	if (device_property_present(dev, "smsc,force-external-phy"))
> >  		config->flags |= SMSC911X_FORCE_EXTERNAL_PHY;
> >  
> > -	if (of_get_property(np, "smsc,save-mac-address", NULL))
> > +	if (device_property_present(dev, "smsc,save-mac-address"))
> >  		config->flags |= SMSC911X_SAVE_MAC_ADDRESS;
> >  
> >  	return 0;
> >  }
> > -#else
> > -static inline int smsc911x_probe_config_dt(
> > -				struct smsc911x_platform_config *config,
> > -				struct device_node *np)
> > -{
> > -	return -ENODEV;
> > -}
> > -#endif /* CONFIG_OF */
> >  
> >  static int smsc911x_drv_probe(struct platform_device *pdev)
> >  {
> > -	struct device_node *np = pdev->dev.of_node;
> >  	struct net_device *dev;
> >  	struct smsc911x_data *pdata;
> >  	struct smsc911x_platform_config *config = dev_get_platdata(&pdev->dev);
> > @@ -2478,7 +2467,7 @@ static int smsc911x_drv_probe(struct platform_device *pdev)
> >  		goto out_disable_resources;
> >  	}
> >  
> > -	retval = smsc911x_probe_config_dt(&pdata->config, np);
> > +	retval = smsc911x_probe_config(&pdata->config, &pdev->dev);
> >  	if (retval && config) {
> >  		/* copy config parameters across to pdata */
> >  		memcpy(&pdata->config, config, sizeof(pdata->config));
> > @@ -2654,6 +2643,12 @@ static const struct of_device_id smsc911x_dt_ids[] = {
> >  MODULE_DEVICE_TABLE(of, smsc911x_dt_ids);
> >  #endif
> >  
> > +static const struct acpi_device_id smsc911x_acpi_match[] = {
> > +	{ "ARMH9118", 0 },
> > +	{ }
> > +};
> > +MODULE_DEVICE_TABLE(acpi, smsc911x_acpi_match);
> > +
> >  static struct platform_driver smsc911x_driver = {
> >  	.probe = smsc911x_drv_probe,
> >  	.remove = smsc911x_drv_remove,
> > @@ -2661,6 +2656,7 @@ static struct platform_driver smsc911x_driver = {
> >  		.name	= SMSC_CHIPNAME,
> >  		.pm	= SMSC911X_PM_OPS,
> >  		.of_match_table = of_match_ptr(smsc911x_dt_ids),
> > +		.acpi_match_table = ACPI_PTR(smsc911x_acpi_match),
> >  	},
> >  };
> >  
> > -- 
> > 2.4.3
> > 
> > 
> > 
> > _______________________________________________
> > linux-arm-kernel mailing list
> > linux-arm-kernel at lists.infradead.org
> > http://lists.infradead.org/mailman/listinfo/linux-arm-kernel
> 
> _______________________________________________
> linux-arm-kernel mailing list
> linux-arm-kernel at lists.infradead.org
> http://lists.infradead.org/mailman/listinfo/linux-arm-kernel
> 


From will.deacon at arm.com  Thu Aug 13 02:01:19 2015
From: will.deacon at arm.com (Will Deacon)
Date: Thu, 13 Aug 2015 10:01:19 +0100
Subject: [PATCH 0/2] x86/KASAN updates for 4.3
In-Reply-To: <20150813081641.GA14402@gmail.com>
References: <1439444244-26057-1-git-send-email-ryabinin.a.a@gmail.com>
 <20150813065040.GA17983@gmail.com>
 <20150813081641.GA14402@gmail.com>
Message-ID: <20150813090119.GA10280@arm.com>

Hi Ingo,

On Thu, Aug 13, 2015 at 09:16:41AM +0100, Ingo Molnar wrote:
> * Ingo Molnar <mingo at kernel.org> wrote:
> > * Andrey Ryabinin <ryabinin.a.a at gmail.com> wrote:
> > 
> > > These 2 patches taken from v5 'KASAN for arm64' series.
> > > The only change is updated changelog in second patch.
> > > 
> > > I hope this is not too late to queue these for 4.3,
> > > as this allow us to merge arm64/KASAN patches in v4.4
> > > through arm64 tree.
> > > 
> > > Andrey Ryabinin (2):
> > >   x86/kasan: define KASAN_SHADOW_OFFSET per architecture
> > >   x86/kasan, mm: introduce generic kasan_populate_zero_shadow()
> > > 
> > >  arch/x86/include/asm/kasan.h |   3 +
> > >  arch/x86/mm/kasan_init_64.c  | 123 ++--------------------------------
> > >  include/linux/kasan.h        |  10 ++-
> > >  mm/kasan/Makefile            |   2 +-
> > >  mm/kasan/kasan_init.c        | 152 +++++++++++++++++++++++++++++++++++++++++++
> > >  5 files changed, 170 insertions(+), 120 deletions(-)
> > >  create mode 100644 mm/kasan/kasan_init.c
> > 
> > It's absolutely too late in the -rc cycle for v4.3!
> 
> Stupid me, I have read 'v4.2' ...
> 
> So yes, it's still good for v4.3, the development window is still open.
> 
> The rest still stands:
> 
> > I can create a stable topic tree for it, tip:mm/kasan or so, which arm64 could 
> > pull and base its own ARM specific work on, if that's OK with everyone.

Yes please, works for me! If we're targetting 4.3, then please can you base
on 4.2-rc4, as that's what our current arm64 queue is using?

Cheers,

Will


From linus.walleij at linaro.org  Thu Aug 13 02:04:13 2015
From: linus.walleij at linaro.org (Linus Walleij)
Date: Thu, 13 Aug 2015 11:04:13 +0200
Subject: [PATCH v4 1/4] dt-bindings: brcmstb-gpio: document properties for
 wakeup
In-Reply-To: <1438391865-7862-2-git-send-email-gregory.0xf0@gmail.com>
References: <1438391865-7862-1-git-send-email-gregory.0xf0@gmail.com>
 <1438391865-7862-2-git-send-email-gregory.0xf0@gmail.com>
Message-ID: <CACRpkdaZj=vt_nPOxh+PCH6n1i8MkzcoicYwUGAMFyP_MPg_yg@mail.gmail.com>

On Sat, Aug 1, 2015 at 3:17 AM, Gregory Fong <gregory.0xf0 at gmail.com> wrote:

> Some brcmstb GPIO controllers can be used to wake from suspend, so use
> the de facto standard property 'wakeup-source' to mark the nodes of
> controllers with that capability.
>
> Also document interrupts-extended, which will be used for wakeup
> handling because the interrupt parent for the wake IRQ is different
> from the regular IRQ.
>
> While we're at it, a few more fixes: We don't actually use the
> "interrupt-names" property, so remove it from the listed optional
> properties and from the examples.  And since we're modifying the
> examples, also follow Brian's suggestions to:
> - change #gpio-cells, #interrupt-cells, and brcm,gpio-bank-widths from
>   hex to dec
> - use phandles
>
> Reviewed-by: Brian Norris <computersforpeace at gmail.com>
> Acked-by: Florian Fainelli <f.fainelli at gmail.com>
> Signed-off-by: Gregory Fong <gregory.0xf0 at gmail.com>
> ---
> v4: no changes from v3

I've already applied this, no action.

Yours,
Linus Walleij


From aballier at gentoo.org  Thu Aug 13 02:06:53 2015
From: aballier at gentoo.org (Alexis Ballier)
Date: Thu, 13 Aug 2015 11:06:53 +0200
Subject: [PATCH v2] ARM: dts: exynos4412-odroidu3: Enable SPI1.
Message-ID: <1439456813-4918-1-git-send-email-aballier@gentoo.org>

SPI1 is available on IO Port #2 (as depicted on their website) in
PCB Revision 0.5 of Hardkernel Odroid U3 board.
The shield connects a 256KiB spi-nor flash on that bus.

Signed-off-by: Alexis Ballier <aballier at gentoo.org>

---

Changes in v2: Use GPIO_ACTIVE_HIGH (Krzysztof Kozlowski)

 arch/arm/boot/dts/exynos4412-odroidu3.dts | 8 ++++++++
 1 file changed, 8 insertions(+)

diff --git a/arch/arm/boot/dts/exynos4412-odroidu3.dts b/arch/arm/boot/dts/exynos4412-odroidu3.dts
index 44684e5..8632f35 100644
--- a/arch/arm/boot/dts/exynos4412-odroidu3.dts
+++ b/arch/arm/boot/dts/exynos4412-odroidu3.dts
@@ -13,6 +13,7 @@
 
 /dts-v1/;
 #include "exynos4412-odroid-common.dtsi"
+#include <dt-bindings/gpio/gpio.h>
 
 / {
 	model = "Hardkernel ODROID-U3 board based on Exynos4412";
@@ -61,3 +62,10 @@
 		"Speakers", "SPKL",
 		"Speakers", "SPKR";
 };
+
+&spi_1 {
+	pinctrl-names = "default";
+	pinctrl-0 = <&spi1_bus>;
+	cs-gpios = <&gpb 5 GPIO_ACTIVE_HIGH>;
+	status = "okay";
+};
-- 
2.5.0



From thierry.reding at gmail.com  Thu Aug 13 02:07:32 2015
From: thierry.reding at gmail.com (Thierry Reding)
Date: Thu, 13 Aug 2015 11:07:32 +0200
Subject: [PATCH 2/2] clk: Convert __clk_get_name(hw->clk) to
 clk_hw_get_name(hw)
In-Reply-To: <1439421161-17868-2-git-send-email-sboyd@codeaurora.org>
References: <1439421161-17868-1-git-send-email-sboyd@codeaurora.org>
 <1439421161-17868-2-git-send-email-sboyd@codeaurora.org>
Message-ID: <20150813090731.GC21716@ulmo>

On Wed, Aug 12, 2015 at 04:12:41PM -0700, Stephen Boyd wrote:
> Use the provider based method to get a clock's name so that we
> can get rid of the clk member in struct clk_hw one day. Mostly
> converted with the following coccinelle script.
> 
> @@
> struct clk_hw *E;
> @@
> 
> -__clk_get_name(E->clk)
> +clk_hw_get_name(E)
> 
[...]
>  drivers/clk/tegra/clk-pll.c          |  8 ++++----

Acked-by: Thierry Reding <treding at nvidia.com>
-------------- next part --------------
A non-text attachment was scrubbed...
Name: signature.asc
Type: application/pgp-signature
Size: 819 bytes
Desc: not available
URL: <http://lists.infradead.org/pipermail/linux-arm-kernel/attachments/20150813/acb6e08a/attachment.sig>

From aisheng.dong at freescale.com  Thu Aug 13 01:58:56 2015
From: aisheng.dong at freescale.com (Dong Aisheng)
Date: Thu, 13 Aug 2015 16:58:56 +0800
Subject: [PATCH v6 0/6] mmc: imx: a few fixes and new feature
In-Reply-To: <1439293111-21077-1-git-send-email-haibo.chen@freescale.com>
References: <1439293111-21077-1-git-send-email-haibo.chen@freescale.com>
Message-ID: <20150813085854.GA19166@shlinux1.ap.freescale.net>

On Tue, Aug 11, 2015 at 07:38:25PM +0800, Haibo Chen wrote:
> Changes for v6:
> -remove duplicate code in esdhc_set_uhs_signaling().
> -fix a typo for patch-2.
> -make commit log of patch-3 more specific.
> 
> Haibo Chen (6):
>   mmc: sdhci-esdhc-imx: add imx7d support and support HS400
>   mmc: sdhci-esdhc-imx: add tuning-step setting support
>   mmc: sdhci-esdhc-imx: add imx7d support in bingding doc
>   ARM: dts: imx7d-sdb: add eMMC5.0 support
>   mmc: sdhci-esdhc-imx: set back the burst_length_enable bit to 1
>   mmc: sdhci-esdhc-imx: change default watermark level and burst length
> 
>  .../devicetree/bindings/mmc/fsl-imx-esdhc.txt      |   6 ++
>  arch/arm/boot/dts/imx7d-sdb.dts                    |  13 +++
>  drivers/mmc/host/sdhci-esdhc-imx.c                 | 114 ++++++++++++++++++++-
>  include/linux/platform_data/mmc-esdhc-imx.h        |   1 +
>  4 files changed, 130 insertions(+), 4 deletions(-)
> 
> -- 
> 1.9.1
> 

The patch set looks good to me.

Acked-by: Dong Aisheng <aisheng.dong at freescale.com>

Regards
Dong Aisheng


From lee.jones at linaro.org  Thu Aug 13 02:19:14 2015
From: lee.jones at linaro.org (Lee Jones)
Date: Thu, 13 Aug 2015 10:19:14 +0100
Subject: [PATCH v2 5/6] mailbox: Add generic mechanism for testing
 Mailbox Controllers
In-Reply-To: <CABb+yY0A74Vy3-KOvj0URU_4zb2FAC7Yp3gmEwnFaBrD0mzt0w@mail.gmail.com>
References: <1437990272-23111-1-git-send-email-lee.jones@linaro.org>
 <1437990272-23111-6-git-send-email-lee.jones@linaro.org>
 <CABb+yY20nQbiEEZeRvWTMUsJ2qgwRn8CrWvnFDSB-b1dgVaAuw@mail.gmail.com>
 <20150812102328.GD18282@x1>
 <CABb+yY0A74Vy3-KOvj0URU_4zb2FAC7Yp3gmEwnFaBrD0mzt0w@mail.gmail.com>
Message-ID: <20150813091914.GB8782@x1>

On Thu, 13 Aug 2015, Jassi Brar wrote:

> On Wed, Aug 12, 2015 at 3:53 PM, Lee Jones <lee.jones at linaro.org> wrote:
> > On Mon, 10 Aug 2015, Jassi Brar wrote:
> >
> >> On Mon, Jul 27, 2015 at 3:14 PM, Lee Jones <lee.jones at linaro.org> wrote:
> >> > This particular Client implementation uses shared memory in order
> >> > to pass messages between Mailbox users; however, it can be easily
> >> > hacked to support any type of Controller.
> >> >
> >> > Signed-off-by: Lee Jones <lee.jones at linaro.org>
> >> > ---
> >> >  drivers/mailbox/Kconfig        |   7 ++
> >> >  drivers/mailbox/Makefile       |   2 +
> >> >  drivers/mailbox/mailbox-test.c | 210 +++++++++++++++++++++++++++++++++++++++++
> >> >  3 files changed, 219 insertions(+)
> >> >  create mode 100644 drivers/mailbox/mailbox-test.c
> >> >
> >> > diff --git a/drivers/mailbox/Kconfig b/drivers/mailbox/Kconfig
> >> > index 2cc4c39..7720bde 100644
> >> > --- a/drivers/mailbox/Kconfig
> >> > +++ b/drivers/mailbox/Kconfig
> >> > @@ -77,4 +77,11 @@ config STI_MBOX
> >> >           Mailbox implementation for STMicroelectonics family chips with
> >> >           hardware for interprocessor communication.
> >> >
> >> > +config MAILBOX_TEST
> >> > +       tristate "Mailbox Test Client"
> >> > +       depends on OF
> >> > +       help
> >> > +         Test client to help with testing new Controller driver
> >> > +         implementations.
> >> > +
> >> >  endif
> >> > diff --git a/drivers/mailbox/Makefile b/drivers/mailbox/Makefile
> >> > index 7cb4766..92435ef 100644
> >> > --- a/drivers/mailbox/Makefile
> >> > +++ b/drivers/mailbox/Makefile
> >> > @@ -2,6 +2,8 @@
> >> >
> >> >  obj-$(CONFIG_MAILBOX)          += mailbox.o
> >> >
> >> > +obj-$(CONFIG_MAILBOX_TEST)     += mailbox-test.o
> >> > +
> >> >  obj-$(CONFIG_ARM_MHU)  += arm_mhu.o
> >> >
> >> >  obj-$(CONFIG_PL320_MBOX)       += pl320-ipc.o
> >> > diff --git a/drivers/mailbox/mailbox-test.c b/drivers/mailbox/mailbox-test.c
> >> > new file mode 100644
> >> > index 0000000..10bfe3a
> >> > --- /dev/null
> >> > +++ b/drivers/mailbox/mailbox-test.c
> >> > @@ -0,0 +1,210 @@
> >> > +/*
> >> > + * Copyright (C) 2015 ST Microelectronics
> >> > + *
> >> > + * Author: Lee Jones <lee.jones at linaro.org>
> >> > + *
> >> > + * This program is free software; you can redistribute it and/or modify
> >> > + * it under the terms of the GNU General Public License as published by
> >> > + * the Free Software Foundation; either version 2 of the License, or
> >> > + * (at your option) any later version.
> >> > + */
> >> > +
> >> > +#include <linux/debugfs.h>
> >> > +#include <linux/err.h>
> >> > +#include <linux/kernel.h>
> >> > +#include <linux/mailbox_client.h>
> >> > +#include <linux/module.h>
> >> > +#include <linux/of.h>
> >> > +#include <linux/platform_device.h>
> >> > +#include <linux/slab.h>
> >> > +#include <linux/uaccess.h>
> >> > +
> >> > +#define MBOX_MAX_MSG_LEN 128
> >> > +
> >> > +static struct dentry *root_debugfs_dir;
> >> > +
> >> > +struct mbox_test_device {
> >> > +       struct device           *dev;
> >> > +       struct mbox_chan        *tx_channel;
> >> > +       struct mbox_chan        *rx_channel;
> >> > +       void __iomem            *mmio;
> >> > +
> >> > +};
> >> > +
> >> > +static ssize_t mbox_test_write(struct file *filp,
> >> > +                              const char __user *userbuf,
> >> > +                              size_t count, loff_t *ppos)
> >> > +{
> >> > +       struct mbox_test_device *tdev = filp->private_data;
> >> > +       char *message;
> >> > +       int ret;
> >> > +
> >> > +       if (count > MBOX_MAX_MSG_LEN) {
> >> > +               dev_err(tdev->dev,
> >> > +                       "Message length %d greater than max allowed %d\n",
> >> > +                       count, MBOX_MAX_MSG_LEN);
> >> > +               return -EINVAL;
> >> > +       }
> >> > +
> >> > +       message = kzalloc(count, GFP_KERNEL);
> >> > +       if (!message)
> >> > +               return -ENOMEM;
> >> > +
> >> > +       ret = copy_from_user(message, userbuf, count);
> >> > +       if (ret)
> >> > +               return -EFAULT;
> >> > +
> >> > +       print_hex_dump(KERN_ERR, "Client: Sending: ", DUMP_PREFIX_ADDRESS,
> >> > +                      16, 1, message, 16, true);
> >> > +
> >> > +       ret = mbox_send_message(tdev->tx_channel, message);
> >> > +       if (ret < 0)
> >> > +               dev_err(tdev->dev, "Failed to send message via mailbox\n");
> >> > +
> >> > +       kfree(message);
> >> > +
> >> > +       return ret < 0 ? ret : count;
> >> > +}
> >> > +
> >> > +static const struct file_operations mbox_test_ops = {
> >> > +       .write  = mbox_test_write,
> >> > +       .open   = simple_open,
> >> > +       .llseek = generic_file_llseek,
> >> > +};
> >> > +
> >> > +static int mbox_test_add_debugfs(struct platform_device *pdev,
> >> > +                                struct mbox_test_device *tdev)
> >> > +{
> >> > +       if (!debugfs_initialized())
> >> > +               return 0;
> >> > +
> >> > +       root_debugfs_dir = debugfs_create_dir("mailbox", NULL);
> >> > +       if (!root_debugfs_dir) {
> >> > +               dev_err(&pdev->dev, "Failed to create Mailbox debugfs\n");
> >> > +               return -EINVAL;
> >> > +       }
> >> > +
> >> > +       debugfs_create_file("send-message", 0200, root_debugfs_dir,
> >> > +                           tdev, &mbox_test_ops);
> >> > +
> >> > +       return 0;
> >> > +}
> >> > +
> >> > +static void mbox_test_receive_message(struct mbox_client *client, void *message)
> >> > +{
> >> > +       struct mbox_test_device *tdev = dev_get_drvdata(client->dev);
> >> > +
> >> > +       if (!tdev->mmio) {
> >> > +               dev_info(tdev->dev, "Client: Recived something [read mmio]\n");
> >> > +               return;
> >> > +       }
> >> > +
> >> > +       print_hex_dump(KERN_ERR, "Client: from co-proc: ", DUMP_PREFIX_ADDRESS,
> >> > +                      16, 1, tdev->mmio, MBOX_MAX_MSG_LEN, true);
> >> > +}
> >> > +
> >> > +static void mbox_test_prepare_message(struct mbox_client *client, void *message)
> >> > +{
> >> > +       struct mbox_test_device *tdev = dev_get_drvdata(client->dev);
> >> > +
> >> > +       if (tdev->mmio)
> >> > +               memcpy(tdev->mmio, message, MBOX_MAX_MSG_LEN);
> >> >
> >> This is unlikely to work. Those platforms that need to send a 2 part
> >> message, they do :
> >> (a) Signal/Command/Target code via some controller register (via
> >> mbox_send_message).
> >> (b) Setup the payload in Shared-Memory (via tx_prepare).
> >>
> >> This test driver assumes both are the same. I think you have to
> >> declare something like
> >
> > This driver assumes that the framework will call client->tx_prepare()
> > first, which satisfies (b).  It then assumes controller->send_data()
> > will be invoked, which will send the platform specific
> > signal/command/target code, which then satisfies (a).
> >
> Yeah, but what would be that code? Who provides that?
> 
> > In what way does it assume they are the same?
> >
> notice the 'message' pointer in
> mbox_send_message(tdev->tx_channel, message);
>     and
> memcpy(tdev->mmio, message, MBOX_MAX_MSG_LEN);
> 
> >> struct mbox_test_message { /* same for TX and RX */
> >>           unsigned sig_len;
> >>           void *signal;               /* rx/tx via mailbox api */
> >>           unsigned pl_len;
> >>           void *payload;           /* rx/tx via shared-memory */
> >> };
> >
> > How do you think this should be set and use these?
> >
> The userspace would want to specify the command code (32bits or not)
> that would be passed via the fifo/register of the controller. So we
> need signal[]
> 
> The data to be passed via share-memory could be provided by userspace
> via the payload[] array.

Okay, so would the solution be two userspace files 'signal' and
'message', so in the case of a client specified signal we can write it
into there first.

echo 255  > signal
echo test > message

... or in the case where no signal is required, or the controller
driver taking care of it, we just don't write anything to signal?

Just for clarification, in the case where a signal is required, do
clients usually pass that through mbox_send_message() too?

  mbox_send_message(tdev->tx_channel, signal);
  mbox_send_message(tdev->tx_channel, message);

... or vice versa.

> >> > +static void mbox_test_message_sent(struct mbox_client *client,
> >> > +                                  void *message, int r)
> >> > +{
> >> > +       if (r)
> >> > +               dev_warn(client->dev,
> >> > +                        "Client: Message could not be sent: %d\n", r);
> >> > +       else
> >> > +               dev_info(client->dev,
> >> > +                        "Client: Message sent\n");
> >> > +}
> >> > +
> >> > +static struct mbox_chan *
> >> > +mbox_test_request_channel(struct platform_device *pdev, const char *name)
> >> > +{
> >> > +       struct mbox_client *client;
> >> > +
> >> > +       client = devm_kzalloc(&pdev->dev, sizeof(*client), GFP_KERNEL);
> >> > +       if (!client)
> >> > +               return ERR_PTR(-ENOMEM);
> >> > +
> >> > +       client->dev             = &pdev->dev;
> >> > +       client->rx_callback     = mbox_test_receive_message;
> >> > +       client->tx_prepare      = mbox_test_prepare_message;
> >> > +       client->tx_done         = mbox_test_message_sent;
> >> > +       client->tx_block        = true;
> >> > +       client->knows_txdone    = false;
> >> > +       client->tx_tout         = 500;
> >> > +
> >> > +       return mbox_request_channel_byname(client, name);
> >> > +}
> >> > +
> >> > +static int mbox_test_probe(struct platform_device *pdev)
> >> > +{
> >> > +       struct mbox_test_device *tdev;
> >> > +       struct resource *res;
> >> > +       int ret;
> >> > +
> >> > +       tdev = devm_kzalloc(&pdev->dev, sizeof(*tdev), GFP_KERNEL);
> >> > +       if (!tdev)
> >> > +               return -ENOMEM;
> >> > +
> >> > +       /* It's okay for MMIO to be NULL */
> >> > +       res = platform_get_resource(pdev, IORESOURCE_MEM, 0);
> >> > +       tdev->mmio = devm_ioremap_resource(&pdev->dev, res);
> >> > +       if (IS_ERR(tdev->mmio))
> >> > +               tdev->mmio = NULL;
> >> > +
> >> > +       tdev->tx_channel = mbox_test_request_channel(pdev, "tx");
> >> > +       if (IS_ERR(tdev->tx_channel))
> >> > +               return PTR_ERR(tdev->tx_channel);
> >> > +
> >> > +       tdev->rx_channel = mbox_test_request_channel(pdev, "rx");
> >> > +       if (IS_ERR(tdev->rx_channel))
> >> > +               return PTR_ERR(tdev->rx_channel);
> >> > +
> >> Should it really fail on TX or RX only clients?
> >
> > Good question.  Probably not, but I guess we'd need a flag for that.
> >
> Just assume 1 channel. You can't make it receive if the controller
> can't do rx, so the userspace will simply block on read requests. And
> you can't make the controller send, if it can't. So any write attempt
> will simply return with an error.
>  And we are going to need very platform specific knowledge to execute
> the tests. It's not like some loop enumerating all possible
> combinations of parameters that the api must pass... so we are good.

I'm guessing most tests will be some kind of send-reply test, so we'd
need two channels for that.  I can make it so the driver does not fail
if 'tx' or 'rx' is missing, but will fail if both are.

Bare in mind that this test driver isn't designed to cover all of the
corner cases, but more designed as a helpful boiler plate where it
will tick some use-case boxes, but is clear enough to be hacked around
by other vendors who have different requirements.

With regards to you comments on userspace; I suggest that whoever is
testing the controller will know it and will not attempt to check for
a reply from a controller (or co-proc) which is write-only.

> >> It takes write from userspace but shouldn't it also provide data
> >> received to the userspace?
> >
> > Currently we only print the returning message.  If you want me to put
> > it in a userspace file too, that's not an issue.
> >
> Ideally we should support 'read' just like write.

Sure, I can do that.

-- 
Lee Jones
Linaro STMicroelectronics Landing Team Lead
Linaro.org ? Open source software for ARM SoCs
Follow Linaro: Facebook | Twitter | Blog


From eric.auger at linaro.org  Thu Aug 13 02:19:21 2015
From: eric.auger at linaro.org (Eric Auger)
Date: Thu, 13 Aug 2015 11:19:21 +0200
Subject: [PATCH v5 5/5] KVM: eventfd: add irq bypass consumer management
In-Reply-To: <1439406307.4023.532.camel@redhat.com>
References: <1439213467-13668-1-git-send-email-eric.auger@linaro.org>	
 <1439213467-13668-6-git-send-email-eric.auger@linaro.org>
 <1439406307.4023.532.camel@redhat.com>
Message-ID: <55CC6119.10001@linaro.org>

Hi Alex,
On 08/12/2015 09:05 PM, Alex Williamson wrote:
> On Mon, 2015-08-10 at 15:31 +0200, Eric Auger wrote:
>> This patch adds the registration/unregistration of an
>> irq_bypass_consumer on irqfd assignment/deassignment.
>>
>> Signed-off-by: Eric Auger <eric.auger at linaro.org>
>> Signed-off-by: Feng Wu <feng.wu at intel.com>
>>
>> ---
>>
>> v4 -> v5:
>> - due to removal of static inline stubs, add
>>   #ifdef CONFIG_HAVE_KVM_IRQ_BYPASS
>>   around consumer registration/unregistration
>> - add pr_info when registration fails
>>
>> v2 -> v3 (Feng Wu):
>> - Use kvm_arch_irq_bypass_start
>> - Remove kvm_arch_irq_bypass_update
>> - Add member 'struct irq_bypass_producer *producer' in
>>   'struct kvm_kernel_irqfd', it is needed by posted interrupt.
>> - Remove 'irq_bypass_unregister_consumer' in kvm_irqfd_deassign()
>>
>> v1 -> v2:
>> - populate of kvm and gsi removed
>> - unregister the consumer on irqfd_shutdown
>> ---
>>  include/linux/kvm_irqfd.h |  2 ++
>>  virt/kvm/eventfd.c        | 15 +++++++++++++++
>>  2 files changed, 17 insertions(+)
>>
>> diff --git a/include/linux/kvm_irqfd.h b/include/linux/kvm_irqfd.h
>> index f926b39..0c1de05 100644
>> --- a/include/linux/kvm_irqfd.h
>> +++ b/include/linux/kvm_irqfd.h
>> @@ -64,6 +64,8 @@ struct kvm_kernel_irqfd {
>>  	struct list_head list;
>>  	poll_table pt;
>>  	struct work_struct shutdown;
>> +	struct irq_bypass_consumer consumer;
>> +	struct irq_bypass_producer *producer;
>>  };
>>  
>>  #endif /* __LINUX_KVM_IRQFD_H */
>> diff --git a/virt/kvm/eventfd.c b/virt/kvm/eventfd.c
>> index 647ffb8..d7a230f 100644
>> --- a/virt/kvm/eventfd.c
>> +++ b/virt/kvm/eventfd.c
>> @@ -35,6 +35,7 @@
>>  #include <linux/srcu.h>
>>  #include <linux/slab.h>
>>  #include <linux/seqlock.h>
>> +#include <linux/irqbypass.h>
>>  #include <trace/events/kvm.h>
>>  
>>  #include <kvm/iodev.h>
>> @@ -140,6 +141,9 @@ irqfd_shutdown(struct work_struct *work)
>>  	/*
>>  	 * It is now safe to release the object's resources
>>  	 */
>> +#ifdef CONFIG_HAVE_KVM_IRQ_BYPASS
>> +	irq_bypass_unregister_consumer(&irqfd->consumer);
>> +#endif
>>  	eventfd_ctx_put(irqfd->eventfd);
>>  	kfree(irqfd);
>>  }
>> @@ -379,6 +383,17 @@ kvm_irqfd_assign(struct kvm *kvm, struct kvm_irqfd *args)
>>  	 * we might race against the POLLHUP
>>  	 */
>>  	fdput(f);
>> +#ifdef CONFIG_HAVE_KVM_IRQ_BYPASS
>> +	irqfd->consumer.token = (void *)irqfd->eventfd;
>> +	irqfd->consumer.add_producer = kvm_arch_irq_bypass_add_producer;
>> +	irqfd->consumer.del_producer = kvm_arch_irq_bypass_del_producer;
>> +	irqfd->consumer.stop = kvm_arch_irq_bypass_stop;
>> +	irqfd->consumer.start = kvm_arch_irq_bypass_start;
>> +	ret = irq_bypass_register_consumer(&irqfd->consumer);
>> +	if (ret)
>> +		pr_info("irq bypass consumer (token %p) registration fails: %d\n",
>> +				irqfd->consumer.token, ret);
>> +#endif
> 
> Does this series compile on its own?  Aren't all these arch function
> unresolved?
yes it does since by default CONFIG_HAVE_KVM_IRQ_BYPASS is not defined

Best Regards

Eric
> 
>>  
>>  	return 0;
>>  
> 
> 
> 



From broonie at kernel.org  Thu Aug 13 02:19:53 2015
From: broonie at kernel.org (Mark Brown)
Date: Thu, 13 Aug 2015 10:19:53 +0100
Subject: [PATCH] spi: Mediatek: fix endian warnings
In-Reply-To: <1439431919.21454.13.camel@mhfsdcap03>
References: <1439289789-29026-1-git-send-email-leilk.liu@mediatek.com>
 <CAOiHx=mrDhxkMd5WVTpayyyxXHUDRTELubErynN3qd-v5qpCfw@mail.gmail.com>
 <1439431919.21454.13.camel@mhfsdcap03>
Message-ID: <20150813091953.GM10748@sirena.org.uk>

On Thu, Aug 13, 2015 at 10:11:59AM +0800, lei liu wrote:

>  This patch is applied, should I append a new patch or you rollback it?
> Thanks.

Please send an incremental patch on top of what's applied and don't top
post.
-------------- next part --------------
A non-text attachment was scrubbed...
Name: signature.asc
Type: application/pgp-signature
Size: 473 bytes
Desc: Digital signature
URL: <http://lists.infradead.org/pipermail/linux-arm-kernel/attachments/20150813/834457b6/attachment.sig>

From geert at linux-m68k.org  Thu Aug 13 02:26:32 2015
From: geert at linux-m68k.org (Geert Uytterhoeven)
Date: Thu, 13 Aug 2015 11:26:32 +0200
Subject: [PATCH v2] ARM: shmobile: kzm9g dts: Use adxl345-specific
 compatible property
In-Reply-To: <20150813000537.GD5221@verge.net.au>
References: <1436180132-26190-1-git-send-email-geert+renesas@glider.be>
 <15966074.zDS67FO48r@avalon> <20150707002621.GD13326@verge.net.au>
 <9389528.5qtaECVqX7@avalon> <20150708005148.GA28100@verge.net.au>
 <20150813000537.GD5221@verge.net.au>
Message-ID: <CAMuHMdV0fqjJSjmYqP0uFa0x5ydc1iztu4za1Ufu7OMdhC29Ug@mail.gmail.com>

Hi Simon,

On Thu, Aug 13, 2015 at 2:05 AM, Simon Horman <horms at verge.net.au> wrote:
> On Wed, Jul 08, 2015 at 09:51:49AM +0900, Simon Horman wrote:
>> On Tue, Jul 07, 2015 at 09:56:29AM +0300, Laurent Pinchart wrote:
>> > On Tuesday 07 July 2015 09:26:21 Simon Horman wrote:
>> > > On Mon, Jul 06, 2015 at 04:29:33PM +0300, Laurent Pinchart wrote:
>> > > > On Monday 06 July 2015 12:55:32 Geert Uytterhoeven wrote:
>> > > > > Replace the deprecated generic "adi,adxl34x" compatible value by the
>> > > > > adxl345-specific "adi,adxl345" value, cfr. commit e465bf6fc55d5ce2 ("DT:
>> > > > > i2c: Deprecate adi,adxl34x compatible string").
>> > > > >
>> > > > > Signed-off-by: Geert Uytterhoeven <geert+renesas at glider.be>
>> > > >
>> > > > Acked-by: Laurent Pinchart <laurent.pinchart+renesas at ideasonboard.com>
>> > > >
>> > > > > ---
>> > > > > Depends on commit 3a38958d2477b718 ("Input: adxl34x - add OF match
>> > > > > support"), which is in v4.2-rc1.
>> > > > >
>> > > > > This is v2 of "ARM: shmobile: kzm9g dts: Add adxl345-specific compatible
>> > > > > property".
>> > >
>> > > It appears to me that this will cause a regression when booting old kernels
>> > > with new dts blobs. For that reason think we should consider v1
>> > > of this change coupled with a schedule to remove use of the deprecated
>> > > compat string.
>> >
>> > That's the forward compatibility that Geert mentioned, is that really an
>> > issue, especially on this board ?
>>
>> I think it would be best to provide backwards compatibility unless there
>> is a compelling reason not to.
>
> I would like to revisit this discussion with a view to getting some version
> of this patch queued up (yes I know I pushed back on it earlier in this thread).

I'm fine with applying v1.

Gr{oetje,eeting}s,

                        Geert

--
Geert Uytterhoeven -- There's lots of Linux beyond ia32 -- geert at linux-m68k.org

In personal conversations with technical people, I call myself a hacker. But
when I'm talking to journalists I just say "programmer" or something like that.
                                -- Linus Torvalds


From marc.zyngier at arm.com  Thu Aug 13 02:26:30 2015
From: marc.zyngier at arm.com (Marc Zyngier)
Date: Thu, 13 Aug 2015 10:26:30 +0100
Subject: [PATCH v2 1/6] genirq: fix irq_chip_retrigger_hierarchy
In-Reply-To: <1439401562-28874-2-git-send-email-grygorii.strashko@ti.com>
References: <1439401562-28874-1-git-send-email-grygorii.strashko@ti.com>
 <1439401562-28874-2-git-send-email-grygorii.strashko@ti.com>
Message-ID: <55CC62C6.20304@arm.com>

[adding Jiang to the cc list]

On 12/08/15 18:45, Grygorii Strashko wrote:
> Now irq_chip_retrigger_hierarchy() returns -ENOSYS if it
> was not able to find at least one .irq_retrigger() callback
> implemented in IRQ domain hierarchy. As result, IRQ
> re-triggering is not working now on ARM (TI OMAP) where
> ARM GIC is not implemented this callback.
> The .irq_retrigger() is optional (see check_irq_resend())
> and there are no reasons to fail if it was not found, hence
> lets return 0 in this case.
> 
> In case of TI OMAP DRA7 the following IRQ hierarchy is defined:
> ARM GIC <- OMAP wakeupgen <- TI CBAR
> 
> Failure is reproduced during resume from suspend to RAM:
> - wakeup by IRQx
> - suspend_enter
>   + arch_suspend_enable_irqs
>     + handle_fasteoi_irq
>       + irq_may_run
>         + irq_pm_check_wakeup
>           + irq_disable(IRQx)
>   + dpm_resume_noirq()
>     + resume_device_irqs
>       + resume_irqs
>         + resume_irq
>           + __enable_irq <== IRQx is not re-triggered
> 
> Fixes: 85f08c17de26 ('genirq: Introduce helper functions...')
> Signed-off-by: Grygorii Strashko <grygorii.strashko at ti.com>
> ---
>  kernel/irq/chip.c | 2 +-
>  1 file changed, 1 insertion(+), 1 deletion(-)
> 
> diff --git a/kernel/irq/chip.c b/kernel/irq/chip.c
> index 27f4332..6de638b 100644
> --- a/kernel/irq/chip.c
> +++ b/kernel/irq/chip.c
> @@ -997,7 +997,7 @@ int irq_chip_retrigger_hierarchy(struct irq_data *data)
>  		if (data->chip && data->chip->irq_retrigger)
>  			return data->chip->irq_retrigger(data);
>  
> -	return -ENOSYS;
> +	return 0;
>  }
>  
>  /**
> 

I think this makes sense. Not having an irq_retrigger or having an
irq_retrigger that returns zero are the same thing.

Actually, we don't even distinguish between a retrigger that
successfully poked the HW, and a retrigger that returned an error. Both
are considered to not to require a SW retrigger... maybe we should fix
that too. Jiang, Thomas?

Anyway, for this patch:

Reviewed-by: Marc Zyngier <marc.zyngier at arm.com>

	M.
-- 
Jazz is not dead. It just smells funny...


From hanjun.guo at linaro.org  Thu Aug 13 02:28:41 2015
From: hanjun.guo at linaro.org (Hanjun Guo)
Date: Thu, 13 Aug 2015 17:28:41 +0800
Subject: [PATCH 1/5] ACPI: add in a bad_madt_entry() function to eventually
 replace the macro
In-Reply-To: <1438894770-31163-2-git-send-email-al.stone@linaro.org>
References: <1438894770-31163-1-git-send-email-al.stone@linaro.org>
 <1438894770-31163-2-git-send-email-al.stone@linaro.org>
Message-ID: <55CC6349.3010809@linaro.org>

On 08/07/2015 04:59 AM, Al Stone wrote:
> The existing BAD_MADT_ENTRY macro only checks that the size of the data
> structure for an MADT subtable matches the length entry in the subtable.
> This is, unfortunately, not reliable.  Nor, as it turns out, does it have
> anything to do with what the length should be in any particular table.
>
> We introduce the bad_madt_entry() function that uses a data set to
> do some basic sanity checks on any given MADT subtable.  Over time, as
> the spec changes, we should just be able to add entries to the data set
> to reflect the changes.
>
> What the data set captures is the allowed MADT subtable length for each
> type of subtable, for each revision of the specification.  While there
> is a revision number in the MADT that we should be able to use to figure
> out the proper subtable length, it was not changed when subtables did.
> And, while there is a major and minor revision in the FADT that could
> also help, it was not always changed as the subtables changed either.
> So, the data set captures for each published version of the ACPI spec
> what the FADT revisions numbers should be, the corresponding MADT
> revision number, and the subtable types and lengths that were defined
> at that time.
>
> The sanity checks done are:
> 	-- is the length non-zero?
> 	-- is the subtable type defined/allowed for the revision of
> 	   the FADT we're using?
> 	-- is the subtable type defined/allowed for the revision of
> 	   the MADT we're using?
> 	-- is the length entry what it should be for this revision
> 	   of the MADT and FADT?
>
> These checks are more thorough than the previous macro provided, and
> are now insulated from data structure size changes by ACPICA, which
> have been the source of other patches in the past.
>
> Now that the bad_madt_entry() function is available, we add code to
> also invoke it before any subtable handlers are called to use the
> info in the subtable.  Subsequent patches will remove the use of the
> BAD_MADT_ENTRY macro which is now redundant as a result.  Any ACPI
> functions that use acpi_parse_madt_entries() will always have all of
> the MADT subtables checked from now on.
>
> Signed-off-by: Al Stone <al.stone at linaro.org>
> Cc: Rafael J. Wysocki <rjw at rjwysocki.net>
> Cc: Len Brown <lenb at kernel.org>
> ---
>   drivers/acpi/tables.c | 241 ++++++++++++++++++++++++++++++++++++++++++++++++++
>   1 file changed, 241 insertions(+)
>
> diff --git a/drivers/acpi/tables.c b/drivers/acpi/tables.c
> index 2e19189..abd7a72 100644
> --- a/drivers/acpi/tables.c
> +++ b/drivers/acpi/tables.c
> @@ -214,6 +214,245 @@ void acpi_table_print_madt_entry(struct acpi_subtable_header *header)
>   	}
>   }
>
> +/*
> + * The Long, Sad, True Story of the MADT
> + *    or
> + * What does bad_madt_entry() actually do?
> + *
> + * Once upon a time in ACPI 1.0, there was the MADT.  It was a nice table,
> + * and it had two subtables all of its own.  But, it was also a pretty
> + * busy table, too, so over time the MADT gathered up other nice little
> + * subtables.  By the time ACPI 6.0 came around, the MADT had 16 of the
> + * little guys.
> + *
> + * Now, the MADT kept a little counter around for the subtables.  In fact,
> + * it kept two counters: one was the revision level, which was supposed to
> + * change when new subtables came to be, or as the ones already around grew
> + * up. The second counter was a type number, because the MADT needed a unique
> + * type for each subtable so he could tell them apart.  But, sometimes the
> + * MADT got so busy, he forgot to increment the revision level when he needed
> + * to.  Fortunately, the type counter kept increasing since that's the only
> + * way the MADT could find each little subtable.  It just wouldn't do to have
> + * every subtable called Number 6.
> + *
> + * In the next valley over, a castle full of wizards was watching the MADT
> + * and made a pact to keep their own counter.  Every time the MADT found a
> + * new subtable, or a subtable grew up, the wizards promised they would
> + * increment their counter.  Well, wizards being the forgetful sort, they
> + * didn't alway do that.  And, since there quite a lot of them, they
> + * couldn't always remember who was supposed to keep track of the MADT,
> + * especially if dinner was coming up soon.  Their counter was called the
> + * spec version.
> + *
> + * Every now and then, the MADT would gather up all its little subtables
> + * and take them in to the cobbler to get new boots.  This was a very, very
> + * meticulous cobbler, so every time they came, he wrote down all the boot
> + * sizes for all of the little subtables.  The cobbler would ask each subtable
> + * for its length, check that against his careful notes, and then go get the
> + * right boots.  Sometimes, a little subtable would change a bit, and their
> + * length did not match what the cobbler had written down.  If the wizards
> + * or the MADT had incremented their counters, the cobbler would breath a
> + * sigh of relief and write down the new length as the right one.  But, if
> + * none of the counters had changed, this would make the cobbler very, very
> + * mad.  He couldn't tell if he had the right size boots or not for the
> + * little subtable.  He would have to *guess* and this really bugged him.
> + *
> + * Well, when the cobbler got mad like this, he would go into hiding.  He
> + * would not make or sell any boots.  He would not go out at all.  Pretty
> + * soon, the coffee shop would have to close because the cobbler wasn't
> + * coming by twice a day any more.  Then the grocery store would have to
> + * close because he wouldn't eat much.  After a while, everyone would panic
> + * and have to move from the village and go live with all their relatives
> + * (usually the ones they didn't like very much).
> + *
> + * Eventually, the cobbler would work his way out of his bad mood, and
> + * open up his boot business again.  Then, everyone else could move back
> + * to the village and restart their lives, too.
> + *
> + * Fortunately, we have been able to collect up all the cobbler's careful
> + * notes (and we wrote them down below).  We'll have to keep checking these
> + * notes over time, too, just as the cobbler does.  But, in the meantime,
> + * we can avoid the panic and the reboot since we can make sure that each
> + * subtable is doing okay.  And that's what bad_madt_entry() does.
> + *
> + *
> + * FADT Major Version ->       1    3    4     4     5     5     6
> + * FADT Minor Version ->       x    x    x     x     x     1     0
> + * MADT revision ->            1    1    2     3     3     3     3
> + * Spec Version ->            1.0  2.0  3.0b  4.0a  5.0b  5.1a  6.0
> + * Subtable Name	Type  Expected Length ->
> + * Processor Local APIC  0x0    8    8    8     8     8     8     8
> + * IO APIC               0x1   12   12   12    12    12    12    12
> + * Int Src Override      0x2        10   10    10    10    10    10
> + * NMI Src               0x3         8    8     8     8     8     8
> + * Local APIC NMI Struct 0x4         6    6     6     6     6     6
> + * Local APIC Addr Ovrrd 0x5        16   12    12    12    12    12
> + * IO SAPIC              0x6        20   16    16    16    16    16
> + * Local SAPIC           0x7         8  >16   >16   >16   >16   >16
> + * Platform Int Src      0x8        16   16    16    16    16    16
> + * Proc Local x2APIC     0x9                   16    16    16    16
> + * Local x2APIC NMI      0xa                   12    12    12    12
> + * GICC CPU I/F          0xb                         40    76    80
> + * GICD                  0xc                         24    24    24
> + * GICv2m MSI            0xd                               24    24
> + * GICR                  0xe                               16    16
> + * GIC ITS               0xf                                     16
> + *
> + * In the table, each length entry is what should be in the length
> + * field of the subtable, and -- in general -- it should match the
> + * size of the struct for the subtable.  Any value that is not set
> + * (i.e., is zero) indicates that the subtable is not defined for
> + * that version of the ACPI spec.
> + *
> + */
> +#define SUBTABLE_UNDEFINED	0x00
> +#define SUBTABLE_VARIABLE	0xff
> +#define NUM_SUBTABLE_TYPES	16
> +
> +struct acpi_madt_subtable_lengths {
> +	unsigned short major_version;	/* from revision in FADT header */
> +	unsigned short minor_version;	/* FADT field starting with 5.1 */
> +	unsigned short madt_version;	/* MADT revision */
> +	unsigned short num_types;	/* types possible for this version */
> +	unsigned short lengths[NUM_SUBTABLE_TYPES];
> +					/* subtable lengths, indexed by type */
> +};
> +
> +static struct acpi_madt_subtable_lengths spec_info[] = {
> +	{ /* for ACPI 1.0 */
> +		.major_version = 1,
> +		.minor_version = 0,
> +		.madt_version = 1,
> +		.num_types = 2,
> +		.lengths = { 8, 12 }
> +	},
> +	{ /* for ACPI 2.0 */
> +		.major_version = 3,
> +		.minor_version = 0,
> +		.madt_version = 1,
> +		.num_types = 9,
> +		.lengths = { 8, 12, 10, 8, 6, 16, 20, 8, 16 }
> +	},
> +	{ /* for ACPI 3.0b */
> +		.major_version = 4,
> +		.minor_version = 0,
> +		.madt_version = 2,
> +		.num_types = 9,
> +		.lengths = { 8, 12, 10, 8, 6, 12, 16, SUBTABLE_VARIABLE, 16 }
> +	},
> +	{ /* for ACPI 4.0a */
> +		.major_version = 4,
> +		.minor_version = 0,
> +		.madt_version = 3,
> +		.num_types = 11,
> +		.lengths = { 8, 12, 10, 8, 6, 12, 16, SUBTABLE_VARIABLE,
> +			     16, 16, 12 }
> +	},
> +	{ /* for ACPI 5.0b */
> +		.major_version = 5,
> +		.minor_version = 0,
> +		.madt_version = 3,
> +		.num_types = 13,
> +		.lengths = { 8, 12, 10, 8, 6, 12, 16, SUBTABLE_VARIABLE,
> +			     16, 16, 12, 40, 24 }
> +	},
> +	{ /* for ACPI 5.1a */
> +		.major_version = 5,
> +		.minor_version = 1,
> +		.madt_version = 3,
> +		.num_types = 15,
> +		.lengths = { 8, 12, 10, 8, 6, 12, 16, SUBTABLE_VARIABLE,
> +			     16, 16, 12, 76, 24, 24, 16 }
> +	},
> +	{ /* for ACPI 6.0 */
> +		.major_version = 6,
> +		.minor_version = 0,
> +		.madt_version = 3,
> +		.num_types = 16,
> +		.lengths = { 8, 12, 10, 8, 6, 12, 16, SUBTABLE_VARIABLE,
> +			     16, 16, 12, 80, 24, 24, 16, 16 }
> +	},
> +	{ /* terminator */
> +		.major_version = 0,
> +		.minor_version = 0,
> +		.madt_version = 0,
> +		.num_types = 0,
> +		.lengths = { 0 }
> +	}
> +};
> +
> +int __init bad_madt_entry(struct acpi_table_header *table,

static?

> +			  struct acpi_subtable_header *entry)
> +{
> +	struct acpi_madt_subtable_lengths *ms;
> +	struct acpi_table_madt *madt;
> +	unsigned short major;
> +	unsigned short minor;
> +	unsigned short len;
> +
> +	/* simple sanity checking on MADT subtable entries */
> +	if (!entry || !table)
> +		return 1;

This function is defined as int, so just return some
error numbers? or

bool __init bad_madt_entry()...

> +
> +	/* FADT minor numbers were not introduced until ACPI 5.1 */
> +	major = acpi_gbl_FADT.header.revision;
> +	if (major >= 5 && acpi_gbl_FADT.header.length >= 268)
> +		minor = acpi_gbl_FADT.minor_revision;
> +	else
> +		minor = 0;
> +
> +	madt = (struct acpi_table_madt *)table;
> +	ms = spec_info;
> +	while (ms->num_types != 0) {
> +		if (ms->major_version == major &&
> +		    ms->minor_version == minor &&
> +		    ms->madt_version == madt->header.revision)
> +			break;
> +		ms++;
> +	}
> +	if (!ms) {

seems ms will never be NULL, as it will point to one entry
in spec_info.

Thanks
Hanjun


From hanjun.guo at linaro.org  Thu Aug 13 02:30:36 2015
From: hanjun.guo at linaro.org (Hanjun Guo)
Date: Thu, 13 Aug 2015 17:30:36 +0800
Subject: [Linaro-acpi] [PATCH 1/5] ACPI: add in a bad_madt_entry() function
 to eventually replace the macro
In-Reply-To: <CAOZdJXVZomskfpvEjmDUiptW3SndJWvfKyzd9SwJp3dh7h3pig@mail.gmail.com>
References: <1438894770-31163-1-git-send-email-al.stone@linaro.org>	<1438894770-31163-2-git-send-email-al.stone@linaro.org>
 <CAOZdJXVZomskfpvEjmDUiptW3SndJWvfKyzd9SwJp3dh7h3pig@mail.gmail.com>
Message-ID: <55CC63BC.4080902@linaro.org>

On 08/13/2015 06:35 AM, Timur Tabi wrote:
> On Thu, Aug 6, 2015 at 3:59 PM, Al Stone <al.stone at linaro.org> wrote:
>> +       while (ms->num_types != 0) {
>> +               if (ms->major_version == major &&
>> +                   ms->minor_version == minor &&
>> +                   ms->madt_version == madt->header.revision)
>> +                       break;
>> +               ms++;
>> +       }
>> +       if (!ms) {
>
> Shouldn't this be
>
>    if (!ms->num_types) {
>
> instead?

I think so, but seems nothing to do with the FADT version,
Al may explain more about it :)

Thanks
Hanjun


From sudeep.holla at arm.com  Thu Aug 13 02:30:56 2015
From: sudeep.holla at arm.com (Sudeep Holla)
Date: Thu, 13 Aug 2015 10:30:56 +0100
Subject: [PATCH v2 6/6] irqchip: crossbar: fix irq masking at suspend
In-Reply-To: <1439401562-28874-7-git-send-email-grygorii.strashko@ti.com>
References: <1439401562-28874-1-git-send-email-grygorii.strashko@ti.com>
 <1439401562-28874-7-git-send-email-grygorii.strashko@ti.com>
Message-ID: <55CC63D0.8030707@arm.com>



On 12/08/15 18:46, Grygorii Strashko wrote:
> All ARM GIC IRQs have to masked during suspend if they are not
> wakeup source. Now this is not happen, since switching to
> use IRQ domain hierarchy, because suspend_device_irq() only checks flags
> in the last IRQ chip in hierarchy for IRQCHIP_MASK_ON_SUSPEND
> bit set. And in the case of TI OMAP DRA7 the last IRQ chip is TI Crossbar
> which do not have this flag set.
>
> In case of TI OMAP DRA7 the following IRQ hierarchy is defined:
>    ARM GIC <- OMAP wakeupgen <- TI CBAR
> ARM GIC - IRQCHIP_MASK_ON_SUSPEND=n

May be this won't affect your platform or this patch but even GIC marks
IRQCHIP_MASK_ON_SUSPEND=y now since GIC doesn't provide any facility to
configure the wakeup source and keeps all the interrupt source enabled.

We have this flag enabled now as it's always safer to mask all the non
wakeup interrupts are masked at the chip level when suspending.

Also the beginning of the commit message contradicts when you also say
in the following statement IRQCHIP_MASK_ON_SUSPEND=n. So you may need to
update the log.

Regards,
Sudeep


From olof at lixom.net  Thu Aug 13 02:18:48 2015
From: olof at lixom.net (Olof Johansson)
Date: Thu, 13 Aug 2015 11:18:48 +0200
Subject: [GIT PULL 5/5] Samsung driver updates for v4.3
In-Reply-To: <55C06A0A.6040407@kernel.org>
References: <55C06A0A.6040407@kernel.org>
Message-ID: <20150813091848.GB30160@localhost>

On Tue, Aug 04, 2015 at 04:30:18PM +0900, Kukjin Kim wrote:
> Hi,
> 
> This branch is including to support generic cpufreq driver in
> mach-exynos dir. for exynos3250 and exynos5250 even the tag name is
> driver. Because it is depending on clk and cpufreq changes which acked
> by regarding maintainers, Mike and Viresh.
> 
> Please pull and if any problems, please kindly let me know.

This now needs to be respun too, apparantly, since it includes dt2.


-Olof



From olof at lixom.net  Thu Aug 13 02:20:38 2015
From: olof at lixom.net (Olof Johansson)
Date: Thu, 13 Aug 2015 11:20:38 +0200
Subject: [GIT PULL 2nd 2/4] Samsung DT 3rd updates for v4.3
In-Reply-To: <55CBE0F2.4020104@kernel.org>
References: <55CBE0F2.4020104@kernel.org>
Message-ID: <20150813092038.GC30160@localhost>

On Thu, Aug 13, 2015 at 09:12:34AM +0900, Kukjin Kim wrote:
> Hi Arnd, Olof, Kevin
> 
> This is based on tags/samsung-dt-2 and including exynos4 related clock
> changes to support cpufreq-dt driver for exynos4 SoCs. Note that I've
> created one more clk topic branch called v4.3-topic/clk-samsung-2 based
> on previous one has been merged by Mike into clock tree before but I'm
> not sure new one merged into clk tree that's why I've noted its merge in
> this signed tag.

Since this depends on the previous DT branch that I asked for a respin, please
do it all over and send a fresh pull request that we hopefully can include.

We normally ask that you don't queue up merge requests like these for that
reason: If there's need to redo an earlier branch there's a lot of work that
needs to be done on your side. Instead, please wait until previous pull request
has been merged before you send the next one. Thanks!


-Olof



From olof at lixom.net  Thu Aug 13 02:18:14 2015
From: olof at lixom.net (Olof Johansson)
Date: Thu, 13 Aug 2015 11:18:14 +0200
Subject: [GIT PULL 4/5] Samsung 2nd DT updates for v4.3
In-Reply-To: <55C069D5.1050409@kernel.org>
References: <55C069D5.1050409@kernel.org>
Message-ID: <20150813091814.GA30160@localhost>

On Tue, Aug 04, 2015 at 04:29:25PM +0900, Kukjin Kim wrote:
> Hi Arnd, Olof, Kevin
> 
> This 2nd DT update branch is based tags/samsung-dt-1 +
> v4.3-topic/clk-samsung branch because of dependency to support generic
> cpufreq driver. Please pull.
> 
> Thanks,
> Kukjin
> 
> 
> The following changes since commit e4a39d904c3c3e4855287b7325306289ff044b06:
> 
>   Merge branch 'v4.3-topic/clk-samsung' into v4.3-next/dt-samsung-2
> (2015-07-24 12:54:00 +0900)
> 
> are available in the git repository at:
> 
> 
>   git://git.kernel.org/pub/scm/linux/kernel/git/kgene/linux-samsung.git
> tags/samsung-dt-2

"clk: exynos5250: add cpu clock configuration data and instantiate cpu
clock" is applied twice, once to your own branch, and once merged in
from Mike's branch. That doesn't look right.

Can you please respin? Thanks.


Thanks,

-Olof


From olof at lixom.net  Thu Aug 13 02:27:21 2015
From: olof at lixom.net (Olof Johansson)
Date: Thu, 13 Aug 2015 11:27:21 +0200
Subject: [PATCH v2 0/4] Device Tree updates of UniPhier SoCs for Linux 4.3
In-Reply-To: <CAK7LNAS_Tx=-it9LFg1K7i-URu1Dx_2xnHPkgM1KJkBFb9q4ig@mail.gmail.com>
References: <1438857468-9740-1-git-send-email-yamada.masahiro@socionext.com>
 <20150811132049.GK30181@localhost>
 <CAK7LNAS_Tx=-it9LFg1K7i-URu1Dx_2xnHPkgM1KJkBFb9q4ig@mail.gmail.com>
Message-ID: <20150813092721.GF30160@localhost>

On Wed, Aug 12, 2015 at 10:39:47PM +0900, Masahiro Yamada wrote:
> 2015-08-11 22:20 GMT+09:00 Olof Johansson <olof at lixom.net>:
> > On Thu, Aug 06, 2015 at 07:37:44PM +0900, Masahiro Yamada wrote:
> >> Hi Olof and Arnd,
> >>
> >> Here are a little more updates for device trees for UniPhier SoCs.
> >>
> >> Please consider applying this series to your ARM-SOC tree.
> >>
> >> Thanks!
> >
> > Hi,
> >
> > Please always comment on when the previous when you respin. I didn't
> > see this thread until after I had applied v1.
> >
> > I've taken 2/4 directly now, since it's the only difference.
> 
> 
> Instead, build fails between commit a5e921b4771 and 63ef577d9
> because 2/4 is a pre-requisite patch for 3/4 and /4/4.
> 
> 
> Maybe I should have sent a pull-request instead of patches.

The most important thing you should have done is followed up on the bad
patch series. Sending this as a pull request wouldn't have saved you if
you had just sent a second pull request without withdrawing the first one.

Sending patches and pull requests make little different for us for a new
platform with only a few patches per release. We still need to review
your code before we merge it. Actually, doing it as patches is sometimes
a bit easier since we can touch up trivial things instead of asking you
to redo the pull request.


-Olof


From olof at lixom.net  Thu Aug 13 02:21:44 2015
From: olof at lixom.net (Olof Johansson)
Date: Thu, 13 Aug 2015 11:21:44 +0200
Subject: [GIT PULL 2nd 3/4] Samsung driver 2nd updates for v4.3
In-Reply-To: <55CBE10B.2030103@kernel.org>
References: <55CBE10B.2030103@kernel.org>
Message-ID: <20150813092144.GD30160@localhost>

On Thu, Aug 13, 2015 at 09:12:59AM +0900, Kukjin Kim wrote:
> Hi,
> 
> I've created the signed tag based on previous tags/samsung-driver so you
> can see several merge in there. To support cpufreq-dt driver requires
> clk/cpufreq/exynos changes together and clk/cpufreq maintainers are
> aware of this changes. And we can remove exynos cpufreq driver at last.
> 
> Note this drivers update is including previous dependencies and if
> you're OK, please pull.

Again, this needs to be revisited.

Please try to keep the dependency only driver->dt if you can,
and we can merge drivers before DT this release cycle. If you do
driver->dt->driver->dt like here then things get messy.


-Olof



From olof at lixom.net  Thu Aug 13 02:24:15 2015
From: olof at lixom.net (Olof Johansson)
Date: Thu, 13 Aug 2015 11:24:15 +0200
Subject: [PATCH] ARM/EP93xx/timer: Migrate to new 'set-state' interface
In-Reply-To: <BN3PR0101MB10579524DEE61E49B8725469D07E0@BN3PR0101MB1057.prod.exchangelabs.com>
References: <744dca162a7626694770a9f51457566a33c3e08f.1438852023.git.viresh.kumar@linaro.org>
 <BN3PR0101MB10579524DEE61E49B8725469D07E0@BN3PR0101MB1057.prod.exchangelabs.com>
Message-ID: <20150813092415.GE30160@localhost>

On Wed, Aug 12, 2015 at 04:39:46PM +0000, Hartley Sweeten wrote:
> On Thursday, August 06, 2015 2:11 AM, Viresh Kumar wrote:
> > Migrate EP93xx driver to the new 'set-state' interface provided by
> > clockevents core, the earlier 'set-mode' interface is marked obsolete
> > now.
> >
> > This also enables us to implement callbacks for new states of clockevent
> > devices, for example: ONESHOT_STOPPED.
> >
> > Signed-off-by: Viresh Kumar <viresh.kumar at linaro.org>
> 
> Reviewed-by: H Hartley Sweeten <hsweeten at visionengravers.com>

Thanks, applied now.


-Olof


From olof at lixom.net  Thu Aug 13 02:30:21 2015
From: olof at lixom.net (Olof Johansson)
Date: Thu, 13 Aug 2015 11:30:21 +0200
Subject: [GIT PULL] Renesas ARM Based SoC CPG MSTP Clock Domain Updates
 for v4.3
In-Reply-To: <20150812084822.GB16058@verge.net.au>
References: <cover.1438911559.git.horms+renesas@verge.net.au>
 <20150811133843.GP30181@localhost>
 <20150812084822.GB16058@verge.net.au>
Message-ID: <20150813093021.GG30160@localhost>

On Wed, Aug 12, 2015 at 05:48:22PM +0900, Simon Horman wrote:
> On Tue, Aug 11, 2015 at 03:38:43PM +0200, Olof Johansson wrote:
> > On Fri, Aug 07, 2015 at 11:12:03AM +0900, Simon Horman wrote:
> > > Hi Olof, Hi Kevin, Hi Arnd,
> > > 
> > > Please consider these Renesas ARM based SoC CPG MSTP clock domain updates
> > > for v4.3.
> > > 
> > > This pull request is based on "Third Round of Renesas ARM Based SoC DT
> > > Updates for v4.3", tagged as renesas-dt3-for-v4.3, which I have also sent a
> > > pull-request for.
> > > 
> > > The reason for that base is that the DT changes in this series update nodes
> > > added in that tag.
> > > 
> > > This series begins with driver changes and follows up with DT changes.
> > > The latter depend on the former.
> > 
> > I see the acked-by tags on the clk patches, but it took some searching to find
> > the ack email from Stephen.
> > 
> > Can you please make our homework a bit easier when providing that in
> > the future?
> 
> Sure, I hadn't realised that you liked to track down Acks to that extent.
> 
> As practice for myself I've included some notes in the repost of the
> patches in question.  Please let me know if you need something different.

It's one of those things that we check in on every now and then, just to make
sure that there weren't comments from the other maintainer that were missed.

We're more likely to do it on pull requests that didn't have the other
maintainer on Cc, FWIW. :)


-Olof


From olof at lixom.net  Thu Aug 13 02:09:39 2015
From: olof at lixom.net (Olof Johansson)
Date: Thu, 13 Aug 2015 11:09:39 +0200
Subject: [PATCH 3/3] ARM: dts: UniPhier: add ProXstream2 and PH1-LD6b
 SoC/board support
In-Reply-To: <CAK7LNAQ+6tQ9Ci6LKsAB7kLj0o60Hizo2gOokDH9qW=FnO0gEA@mail.gmail.com>
References: <1438687264-26538-1-git-send-email-yamada.masahiro@socionext.com>
 <1438687264-26538-4-git-send-email-yamada.masahiro@socionext.com>
 <20150811130739.GD30181@localhost>
 <CAK7LNAQ+6tQ9Ci6LKsAB7kLj0o60Hizo2gOokDH9qW=FnO0gEA@mail.gmail.com>
Message-ID: <CAOesGMhhSKr6Nn7YEjoB9V_5-yhwzn_fKZ7FSU3U-2XYT5mJrQ@mail.gmail.com>

On Wed, Aug 12, 2015 at 3:14 PM, Masahiro Yamada
<yamada.masahiro at socionext.com> wrote:
> Hi Olof,
>
>
> 2015-08-11 22:07 GMT+09:00 Olof Johansson <olof at lixom.net>:
>> Hi,
>>
>> On Tue, Aug 04, 2015 at 08:21:04PM +0900, Masahiro Yamada wrote:
>>> Initial version of DTSI for ProXstream2 and PH1-LD6b and DTS for
>>> PH1-LD6b reference board.
>>>
>>> Signed-off-by: Masahiro Yamada <yamada.masahiro at socionext.com>
>>> ---
>>>
>>>  arch/arm/boot/dts/Makefile                  |   3 +-
>>>  arch/arm/boot/dts/uniphier-ph1-ld6b-ref.dts | 105 +++++++++++
>>>  arch/arm/boot/dts/uniphier-ph1-ld6b.dtsi    |  67 +++++++
>>>  arch/arm/boot/dts/uniphier-proxstream2.dtsi | 273 ++++++++++++++++++++++++++++
>>>  4 files changed, 447 insertions(+), 1 deletion(-)
>>>  create mode 100644 arch/arm/boot/dts/uniphier-ph1-ld6b-ref.dts
>>>  create mode 100644 arch/arm/boot/dts/uniphier-ph1-ld6b.dtsi
>>>  create mode 100644 arch/arm/boot/dts/uniphier-proxstream2.dtsi
>>>
>>> diff --git a/arch/arm/boot/dts/Makefile b/arch/arm/boot/dts/Makefile
>>> index 246473a..6eb3f2f 100644
>>> --- a/arch/arm/boot/dts/Makefile
>>> +++ b/arch/arm/boot/dts/Makefile
>>> @@ -645,7 +645,8 @@ dtb-$(CONFIG_ARCH_UNIPHIER) += \
>>>       uniphier-ph1-sld3-ref.dtb \
>>>       uniphier-ph1-ld4-ref.dtb \
>>>       uniphier-ph1-pro4-ref.dtb \
>>> -     uniphier-ph1-sld8-ref.dtb
>>> +     uniphier-ph1-sld8-ref.dtb \
>>> +     uniphier-ph1-ld6b-ref.dtb
>>
>> Please always add entries here sorted, don't just append. I've fixed it
>> up for you this time.
>>
>>
>
> Please do not do that (without my ack).

I'm not going to go get your ack for something as trivial as this. We
do make sure subplatform maintainers are in the loop and get to review
code that touches their platform, but in this case this was a shared
makefile and there were no functional changes.

> It was already sorted from old SoC to new SoC.
>
> Sorting chronologically (in other words, in the order of chip ID)
> makes more sense than sorting alphabetically.

No, it doesn't. All entries in these files should be sorted
alphabetically. Sometimes we miss out on it, but it's the goal.

If you sort chronologically it's impossible for anyone but people
intimately familiar with UniPhier's product history to add any new
entries in the right location. Also, since it's likely that newer
chips will be introduced over time, new entries are likely to just be
appends instead of inserted at more varied locations in the files.

Append-only additions are more likely to have add/add conflicts, which
is why we're preferring alphabetical sort order in the first place.


-Olof


From gg at slimlogic.co.uk  Thu Aug 13 02:38:38 2015
From: gg at slimlogic.co.uk (Graeme Gregory)
Date: Thu, 13 Aug 2015 10:38:38 +0100
Subject: [PATCH 2/2] Convert smsc911x to use ACPI as well as DT
In-Reply-To: <20150813090117.GA13833@red-moon>
References: <1439417187-21411-1-git-send-email-jeremy.linton@arm.com>
 <1439417187-21411-3-git-send-email-jeremy.linton@arm.com>
 <20150813082759.GB5468@xora-haswell.xora.org.uk>
 <20150813090117.GA13833@red-moon>
Message-ID: <20150813093838.GC5468@xora-haswell.xora.org.uk>

On Thu, Aug 13, 2015 at 10:01:17AM +0100, Lorenzo Pieralisi wrote:
> On Thu, Aug 13, 2015 at 09:27:59AM +0100, Graeme Gregory wrote:
> > On Wed, Aug 12, 2015 at 05:06:27PM -0500, Jeremy Linton wrote:
> > > Add ACPI bindings for the smsc911x driver. Convert the DT specific calls
> > > to nonspecific device* calls, This allows the driver to work
> > > with both ACPI and DT configurations. Ethernet should now work when using
> > > ACPI on ARM Juno.
> 
> Last sentence does not belong in the commit log.
> 
> > > 
> > > Signed-off-by: Jeremy Linton <jeremy.linton at arm.com>
> > 
> > The code looks fine to me.
> > 
> > Currently the compulsary DT properties seem to match the "approved" ACPI
> > NIC properties from here
> > 
> > http://www.uefi.org/sites/default/files/resources/nic-request-v2.pdf
> 
> What about _DSD device specific properties (eg "smsc,save-mac-address") ?
> Are we taking 1:1 translation between DT and ACPI for granted ?
> 
> I thought some process must be put in place to define the corresponding
> bindings in ACPI before starting this mechanical translation or maybe
> I missed something, I would like to understand.
> 
> How does the device specific _DSD definitions work in ACPI world ? Where
> are they published ? How will we translate those to DT bindings if there
> is need ?
> 

This I do not know as that discussion is still ongoing. But those
options are currently marked as optional so driver should not fail if
they are not present in ACPI.

Graeme

> Lorenzo
> 
> > Reviewed-by: Graeme Gregory <graeme.gregory at linaro.org>
> > 
> > Thanks
> > 
> > > ---
> > >  drivers/net/ethernet/smsc/smsc911x.c | 48 +++++++++++++++++-------------------
> > >  1 file changed, 22 insertions(+), 26 deletions(-)
> > > 
> > > diff --git a/drivers/net/ethernet/smsc/smsc911x.c b/drivers/net/ethernet/smsc/smsc911x.c
> > > index 959aeea..0f21aa3 100644
> > > --- a/drivers/net/ethernet/smsc/smsc911x.c
> > > +++ b/drivers/net/ethernet/smsc/smsc911x.c
> > > @@ -59,7 +59,9 @@
> > >  #include <linux/of_device.h>
> > >  #include <linux/of_gpio.h>
> > >  #include <linux/of_net.h>
> > > +#include <linux/acpi.h>
> > >  #include <linux/pm_runtime.h>
> > > +#include <linux/property.h>
> > >  
> > >  #include "smsc911x.h"
> > >  
> > > @@ -2362,59 +2364,46 @@ static const struct smsc911x_ops shifted_smsc911x_ops = {
> > >  	.tx_writefifo = smsc911x_tx_writefifo_shift,
> > >  };
> > >  
> > > -#ifdef CONFIG_OF
> > > -static int smsc911x_probe_config_dt(struct smsc911x_platform_config *config,
> > > -				    struct device_node *np)
> > > +static int smsc911x_probe_config(struct smsc911x_platform_config *config,
> > > +				 struct device *dev)
> > >  {
> > > -	const char *mac;
> > >  	u32 width = 0;
> > >  
> > > -	if (!np)
> > > +	if (!dev)
> > >  		return -ENODEV;
> > >  
> > > -	config->phy_interface = of_get_phy_mode(np);
> > > +	config->phy_interface = device_get_phy_mode(dev);
> > >  
> > > -	mac = of_get_mac_address(np);
> > > -	if (mac)
> > > -		memcpy(config->mac, mac, ETH_ALEN);
> > > +	device_get_mac_address(dev, config->mac, ETH_ALEN);
> > >  
> > > -	of_property_read_u32(np, "reg-shift", &config->shift);
> > > +	device_property_read_u32(dev, "reg-shift", &config->shift);
> > >  
> > > -	of_property_read_u32(np, "reg-io-width", &width);
> > > +	device_property_read_u32(dev, "reg-io-width", &width);
> > >  	if (width == 4)
> > >  		config->flags |= SMSC911X_USE_32BIT;
> > >  	else
> > >  		config->flags |= SMSC911X_USE_16BIT;
> > >  
> > > -	if (of_get_property(np, "smsc,irq-active-high", NULL))
> > > +	if (device_property_present(dev, "smsc,irq-active-high"))
> > >  		config->irq_polarity = SMSC911X_IRQ_POLARITY_ACTIVE_HIGH;
> > >  
> > > -	if (of_get_property(np, "smsc,irq-push-pull", NULL))
> > > +	if (device_property_present(dev, "smsc,irq-push-pull"))
> > >  		config->irq_type = SMSC911X_IRQ_TYPE_PUSH_PULL;
> > >  
> > > -	if (of_get_property(np, "smsc,force-internal-phy", NULL))
> > > +	if (device_property_present(dev, "smsc,force-internal-phy"))
> > >  		config->flags |= SMSC911X_FORCE_INTERNAL_PHY;
> > >  
> > > -	if (of_get_property(np, "smsc,force-external-phy", NULL))
> > > +	if (device_property_present(dev, "smsc,force-external-phy"))
> > >  		config->flags |= SMSC911X_FORCE_EXTERNAL_PHY;
> > >  
> > > -	if (of_get_property(np, "smsc,save-mac-address", NULL))
> > > +	if (device_property_present(dev, "smsc,save-mac-address"))
> > >  		config->flags |= SMSC911X_SAVE_MAC_ADDRESS;
> > >  
> > >  	return 0;
> > >  }
> > > -#else
> > > -static inline int smsc911x_probe_config_dt(
> > > -				struct smsc911x_platform_config *config,
> > > -				struct device_node *np)
> > > -{
> > > -	return -ENODEV;
> > > -}
> > > -#endif /* CONFIG_OF */
> > >  
> > >  static int smsc911x_drv_probe(struct platform_device *pdev)
> > >  {
> > > -	struct device_node *np = pdev->dev.of_node;
> > >  	struct net_device *dev;
> > >  	struct smsc911x_data *pdata;
> > >  	struct smsc911x_platform_config *config = dev_get_platdata(&pdev->dev);
> > > @@ -2478,7 +2467,7 @@ static int smsc911x_drv_probe(struct platform_device *pdev)
> > >  		goto out_disable_resources;
> > >  	}
> > >  
> > > -	retval = smsc911x_probe_config_dt(&pdata->config, np);
> > > +	retval = smsc911x_probe_config(&pdata->config, &pdev->dev);
> > >  	if (retval && config) {
> > >  		/* copy config parameters across to pdata */
> > >  		memcpy(&pdata->config, config, sizeof(pdata->config));
> > > @@ -2654,6 +2643,12 @@ static const struct of_device_id smsc911x_dt_ids[] = {
> > >  MODULE_DEVICE_TABLE(of, smsc911x_dt_ids);
> > >  #endif
> > >  
> > > +static const struct acpi_device_id smsc911x_acpi_match[] = {
> > > +	{ "ARMH9118", 0 },
> > > +	{ }
> > > +};
> > > +MODULE_DEVICE_TABLE(acpi, smsc911x_acpi_match);
> > > +
> > >  static struct platform_driver smsc911x_driver = {
> > >  	.probe = smsc911x_drv_probe,
> > >  	.remove = smsc911x_drv_remove,
> > > @@ -2661,6 +2656,7 @@ static struct platform_driver smsc911x_driver = {
> > >  		.name	= SMSC_CHIPNAME,
> > >  		.pm	= SMSC911X_PM_OPS,
> > >  		.of_match_table = of_match_ptr(smsc911x_dt_ids),
> > > +		.acpi_match_table = ACPI_PTR(smsc911x_acpi_match),
> > >  	},
> > >  };
> > >  
> > > -- 
> > > 2.4.3
> > > 
> > > 
> > > 
> > > _______________________________________________
> > > linux-arm-kernel mailing list
> > > linux-arm-kernel at lists.infradead.org
> > > http://lists.infradead.org/mailman/listinfo/linux-arm-kernel
> > 
> > _______________________________________________
> > linux-arm-kernel mailing list
> > linux-arm-kernel at lists.infradead.org
> > http://lists.infradead.org/mailman/listinfo/linux-arm-kernel
> > 
> 
> _______________________________________________
> linux-arm-kernel mailing list
> linux-arm-kernel at lists.infradead.org
> http://lists.infradead.org/mailman/listinfo/linux-arm-kernel


From gg at slimlogic.co.uk  Thu Aug 13 02:44:59 2015
From: gg at slimlogic.co.uk (Graeme Gregory)
Date: Thu, 13 Aug 2015 10:44:59 +0100
Subject: [PATCH 0/3] Enable EHCI-platform driver for use with ACPI
In-Reply-To: <1439416290-21228-1-git-send-email-jeremy.linton@arm.com>
References: <1439416290-21228-1-git-send-email-jeremy.linton@arm.com>
Message-ID: <20150813094459.GD5468@xora-haswell.xora.org.uk>

On Wed, Aug 12, 2015 at 04:51:27PM -0500, Jeremy Linton wrote:
> This patch set enables the USB on the ARM Juno development platform
> when using an ACPI kernel. This patch is in two primary parts. First
> It tweaks the code in acpi_check_dma() to support the recently added
> CCA attribute which describes a device which is not cache coherent.
> 
> It then adds an error message if the device cannot be configured with
> the current DMA settings, finally it adds the ACPI PNP id to the
> acpi_match_table entry.
> 

Patch 1 I am unsure of (I just don't know enough about DMA), but for the other
two it looks fine to me.

Reviewed-by: Graeme Gregory <graeme.gregory at linaro.org>

> Jeremy Linton (3):
>   Honor ACPI _CCA attribute setting
>   Display a DMA error message
>   Add ACPI bindings for the EHCI platform driver.
> 
>  drivers/usb/host/ehci-platform.c | 13 ++++++++++++-
>  include/acpi/acpi_bus.h          |  5 +++--
>  2 files changed, 15 insertions(+), 3 deletions(-)
> 
> -- 
> 2.4.3
> 
> 
> --
> To unsubscribe from this list: send the line "unsubscribe linux-acpi" in
> the body of a message to majordomo at vger.kernel.org
> More majordomo info at  http://vger.kernel.org/majordomo-info.html


From tony at atomide.com  Thu Aug 13 02:50:48 2015
From: tony at atomide.com (Tony Lindgren)
Date: Thu, 13 Aug 2015 02:50:48 -0700
Subject: [PATCH v2 5/6] ARM: OMAP: wakeupgen: fix arm gic irq type
 configuration
In-Reply-To: <1439401562-28874-6-git-send-email-grygorii.strashko@ti.com>
References: <1439401562-28874-1-git-send-email-grygorii.strashko@ti.com>
 <1439401562-28874-6-git-send-email-grygorii.strashko@ti.com>
Message-ID: <20150813095048.GA4215@atomide.com>

* Grygorii Strashko <grygorii.strashko at ti.com> [150812 10:49]:
> It's observed that ARM GIC IRQ triggering type is not configured
> properly when IRQ is routed through IRQ domain hierarchy and
> system started using DT. As result, system will start using default
> ARM GIC configuration, ignore DT IRQ triggering configuration,
> and value of desc->irq_data.state_use_accessors = 0.
> 
> In case of TI OMAP DRA7 the following IRQ hierarchy is defined:
> ARM GIC <- OMAP wakeupgen <- TI CBAR
> 
> Failed call chain:
>      irq_create_of_mapping
>      irq_set_irq_type
>      __irq_set_trigger
>      if (!chip || !chip->irq_set_type) {
>         return 0; <- return here
>      }
> OMAP wakeupgen has no .irq_set_type() defined and, so, IRQ triggering
> configuration will not be propagated to parent IRQ domain.
> 
> Hence, fix it by using irq_chip_set_type_parent() for
> propagation IRQ triggering type to parent IRQ domains.
> 
> Fixes: 7136d457f365 ('ARM: omap: convert wakeupgen to stacked domains')
> Signed-off-by: Grygorii Strashko <grygorii.strashko at ti.com>

Makse sense to merge this along with the irqchip changes once those
are ready, so feel free to add to this one:

Acked-by: Tony Lindgren <tony at atomide.com>

> ---
>  arch/arm/mach-omap2/omap-wakeupgen.c | 1 +
>  1 file changed, 1 insertion(+)
> 
> diff --git a/arch/arm/mach-omap2/omap-wakeupgen.c b/arch/arm/mach-omap2/omap-wakeupgen.c
> index 8e52621..e1d2e99 100644
> --- a/arch/arm/mach-omap2/omap-wakeupgen.c
> +++ b/arch/arm/mach-omap2/omap-wakeupgen.c
> @@ -392,6 +392,7 @@ static struct irq_chip wakeupgen_chip = {
>  	.irq_mask		= wakeupgen_mask,
>  	.irq_unmask		= wakeupgen_unmask,
>  	.irq_retrigger		= irq_chip_retrigger_hierarchy,
> +	.irq_set_type		= irq_chip_set_type_parent,
>  	.flags			= IRQCHIP_SKIP_SET_WAKE | IRQCHIP_MASK_ON_SUSPEND,
>  #ifdef CONFIG_SMP
>  	.irq_set_affinity	= irq_chip_set_affinity_parent,
> -- 
> 2.5.0
> 


From grygorii.strashko at ti.com  Thu Aug 13 02:51:28 2015
From: grygorii.strashko at ti.com (Grygorii Strashko)
Date: Thu, 13 Aug 2015 12:51:28 +0300
Subject: [PATCH v2 2/6] genirq: fix irqchip_set_wake_parent if
 IRQCHIP_SKIP_SET_WAKE
In-Reply-To: <55CC5B2F.7060503@arm.com>
References: <1439401562-28874-1-git-send-email-grygorii.strashko@ti.com>
 <1439401562-28874-3-git-send-email-grygorii.strashko@ti.com>
 <55CC5B2F.7060503@arm.com>
Message-ID: <55CC68A0.40101@ti.com>

On 08/13/2015 11:54 AM, Sudeep Holla wrote:
>
>
> On 12/08/15 18:45, Grygorii Strashko wrote:
>> The irqchip_set_wake_parent should not fail if IRQ chip
>> specifies IRQCHIP_SKIP_SET_WAKE. Otherwise, IRQ wakeup
>> configuration can't be propagated properly through IRQ
>> domains hierarchy.
>>
>> In case of TI OMAP DRA7 the issue reproduced with following
>> configuration:
>> ARM GIC<-OMAP wakeupgen<-TI CBAR<-GPIO<-GPIO pcf857x<-gpio_key
>>
>> gpio_key is wakeup source
>>
>> Failure is reproduced during suspend/resume to RAM:
>> suspend:
>>   - gpio_keys_suspend
>>     enable_irq_wake
>>       + pcf857x_irq_set_wake
>>         + omap_gpio_wake_enable
>>           + TI CBAR irq_chip_set_wake_parent
>>             + OMAP wakeupgen has no .irq_set_wake()
>>             and -ENOSYS will be returned
>>
>> resume:
>>   - gpio_keys_resume
>>     + disable_irq_wake
>>       + irq_set_irq_wake
>>         + WARN(1, "Unbalanced IRQ %d wake disable\n", irq);
>>
>> Fixes: 08b55e2a9208 ('genirq: Add irqchip_set_wake_parent')
>> Signed-off-by: Grygorii Strashko <grygorii.strashko at ti.com>
>> ---
>>   kernel/irq/chip.c | 4 ++++
>>   1 file changed, 4 insertions(+)
>>
>> diff --git a/kernel/irq/chip.c b/kernel/irq/chip.c
>> index 6de638b..bdb1b9d 100644
>> --- a/kernel/irq/chip.c
>> +++ b/kernel/irq/chip.c
>> @@ -1024,6 +1024,10 @@ int irq_chip_set_vcpu_affinity_parent(struct
>> irq_data *data, void *vcpu_info)
>>   int irq_chip_set_wake_parent(struct irq_data *data, unsigned int on)
>>   {
>>       data = data->parent_data;
>> +
>> +    if (irq_data_get_irq_chip(data)->flags & IRQCHIP_SKIP_SET_WAKE)
>> +        return 0;
>> +
>
> [Nit] I think the irq core can access data->chip directly. Either way,
> it's better to be consistent, the statement following doesn't use helper
> function.

thanks. I'll change it to:
	if (data->chip->flags & IRQCHIP_SKIP_SET_WAKE)
		return 0;

>
> Otherwise looks good to me.

Does it means that I can add your Reviewed-by: with above change?


>
>>       if (data->chip->irq_set_wake)
>>           return data->chip->irq_set_wake(data, on);
>>
>>


-- 
regards,
-grygorii


From grygorii.strashko at ti.com  Thu Aug 13 02:54:36 2015
From: grygorii.strashko at ti.com (Grygorii Strashko)
Date: Thu, 13 Aug 2015 12:54:36 +0300
Subject: [PATCH v2 3/6] genirq: introduce irq_chip_set_type_parent() helper
In-Reply-To: <55CC5C2C.4080301@arm.com>
References: <1439401562-28874-1-git-send-email-grygorii.strashko@ti.com>
 <1439401562-28874-4-git-send-email-grygorii.strashko@ti.com>
 <55CC5C2C.4080301@arm.com>
Message-ID: <55CC695C.1080601@ti.com>

On 08/13/2015 11:58 AM, Sudeep Holla wrote:
>
>
> On 12/08/15 18:45, Grygorii Strashko wrote:
>> It's expected to use this helper when the current
>> domain doesn't implement .irq_set_type(),  but expect
>> the parent to do so.
>>
>> Signed-off-by: Grygorii Strashko <grygorii.strashko at ti.com>
>> ---
>>   include/linux/irq.h |  1 +
>>   kernel/irq/chip.c   | 20 ++++++++++++++++++++
>>   2 files changed, 21 insertions(+)
>>
>> diff --git a/include/linux/irq.h b/include/linux/irq.h
>> index 92188b0..51744bc 100644
>> --- a/include/linux/irq.h
>> +++ b/include/linux/irq.h
>> @@ -484,6 +484,7 @@ extern int irq_chip_set_affinity_parent(struct
>> irq_data *data,
>>   extern int irq_chip_set_wake_parent(struct irq_data *data, unsigned
>> int on);
>>   extern int irq_chip_set_vcpu_affinity_parent(struct irq_data *data,
>>                            void *vcpu_info);
>> +extern int irq_chip_set_type_parent(struct irq_data *data, unsigned
>> int type);
>>   #endif
>>
>>   /* Handling of unhandled and spurious interrupts: */
>> diff --git a/kernel/irq/chip.c b/kernel/irq/chip.c
>> index bdb1b9d..b48938b 100644
>> --- a/kernel/irq/chip.c
>> +++ b/kernel/irq/chip.c
>> @@ -985,6 +985,26 @@ int irq_chip_set_affinity_parent(struct irq_data
>> *data,
>>   }
>>
>>   /**
>> + * irq_chip_set_type_parent - Set IRQ type on the parent interrupt
>> + * @data:    Pointer to interrupt specific data
>> + * @type:    IRQ_TYPE_{LEVEL,EDGE}_* value - see include/linux/irq.h
>> + *
>> + * Conditional, as the underlying parent chip might not implement it.
>> + */
>> +int irq_chip_set_type_parent(struct irq_data *data, unsigned int type)
>> +{
>> +    data = data->parent_data;
>> +
>> +    if (irq_data_get_irq_chip(data)->flags & IRQCHIP_SKIP_SET_WAKE)
>> +        return 0;
>> +
>
> I think this is unrelated here(perhaps copy-paste error ?). I fail to
> see how wakeup and trigger type are related.

Oh. Yes, it's copy-paste error. thanks, will fix.

-- 
regards,
-grygorii


From Suravee.Suthikulpanit at amd.com  Thu Aug 13 02:58:45 2015
From: Suravee.Suthikulpanit at amd.com (Suravee Suthikulpanit)
Date: Thu, 13 Aug 2015 16:58:45 +0700
Subject: [PATCH] pci: acpi: Generic function for setting up PCI device DMA
 coherency
Message-ID: <1439459925-2361-1-git-send-email-Suravee.Suthikulpanit@amd.com>

This patch refactors of_pci_dma_configure() into a more generic
pci_dma_configure(), which can be reused by non-OF code.
Then, it adds support for setting up PCI device DMA coherency from
ACPI _CCA object that should normally be specified in the DSDT node
of its PCI host bridge..

Signed-off-by: Suravee Suthikulpanit <Suravee.Suthikulpanit at amd.com>
CC: Bjorn Helgaas <bhelgaas at google.com>
CC: Catalin Marinas <catalin.marinas at arm.com>
CC: Will Deacon <will.deacon at arm.com>
CC: Rafael J. Wysocki <rjw at rjwysocki.net>
CC: Rob Herring <robh+dt at kernel.org>
CC: Murali Karicheri <m-karicheri2 at ti.com>
---
Note: According to the ACPI spec, the _CCA attribute is required
      for ARM64. Therefore, this patch is a pre-req for ACPI PCI
      support for ARM64 which is currently in development.

      Also, this should not affect other architectures since
      if CCA is not required, the default value is coherent.
      Please see include/acpi/acpi_bus.h: acpi_check_dma() and
      drivers/acpi/scan.c: acpi_init_coherency() for more information

 drivers/of/of_pci.c    | 20 --------------------
 drivers/pci/probe.c    | 35 +++++++++++++++++++++++++++++++++--
 include/linux/of_pci.h |  3 ---
 3 files changed, 33 insertions(+), 25 deletions(-)

diff --git a/drivers/of/of_pci.c b/drivers/of/of_pci.c
index 5751dc5..b66ee4e 100644
--- a/drivers/of/of_pci.c
+++ b/drivers/of/of_pci.c
@@ -117,26 +117,6 @@ int of_get_pci_domain_nr(struct device_node *node)
 }
 EXPORT_SYMBOL_GPL(of_get_pci_domain_nr);
 
-/**
- * of_pci_dma_configure - Setup DMA configuration
- * @dev: ptr to pci_dev struct of the PCI device
- *
- * Function to update PCI devices's DMA configuration using the same
- * info from the OF node of host bridge's parent (if any).
- */
-void of_pci_dma_configure(struct pci_dev *pci_dev)
-{
-	struct device *dev = &pci_dev->dev;
-	struct device *bridge = pci_get_host_bridge_device(pci_dev);
-
-	if (!bridge->parent)
-		return;
-
-	of_dma_configure(dev, bridge->parent->of_node);
-	pci_put_host_bridge_device(bridge);
-}
-EXPORT_SYMBOL_GPL(of_pci_dma_configure);
-
 #if defined(CONFIG_OF_ADDRESS)
 /**
  * of_pci_get_host_bridge_resources - Parse PCI host bridge resources from DT
diff --git a/drivers/pci/probe.c b/drivers/pci/probe.c
index cefd636..e2fcd3b 100644
--- a/drivers/pci/probe.c
+++ b/drivers/pci/probe.c
@@ -6,12 +6,14 @@
 #include <linux/delay.h>
 #include <linux/init.h>
 #include <linux/pci.h>
-#include <linux/of_pci.h>
+#include <linux/of_device.h>
 #include <linux/pci_hotplug.h>
 #include <linux/slab.h>
 #include <linux/module.h>
 #include <linux/cpumask.h>
 #include <linux/pci-aspm.h>
+#include <linux/acpi.h>
+#include <linux/property.h>
 #include <asm-generic/pci-bridge.h>
 #include "pci.h"
 
@@ -1544,6 +1546,35 @@ static void pci_init_capabilities(struct pci_dev *dev)
 	pci_enable_acs(dev);
 }
 
+/**
+ * pci_dma_configure - Setup DMA configuration
+ * @pci_dev: ptr to pci_dev struct of the PCI device
+ *
+ * Function to update PCI devices's DMA configuration using the same
+ * info from the OF node or ACPI node of host bridge's parent (if any).
+ */
+static void pci_dma_configure(struct pci_dev *pci_dev)
+{
+	struct device *dev = &pci_dev->dev;
+	struct device *bridge = pci_get_host_bridge_device(pci_dev);
+	struct acpi_device *adev;
+	bool coherent;
+
+	if (has_acpi_companion(bridge)) {
+		adev = to_acpi_node(bridge->fwnode);
+		if (acpi_check_dma(adev, &coherent))
+			arch_setup_dma_ops(dev, 0, 0, NULL, coherent);
+	} else {
+		struct device *host = bridge->parent;
+		if (!host)
+			return;
+
+		of_dma_configure(dev, host->of_node);
+	}
+
+	pci_put_host_bridge_device(bridge);
+}
+
 void pci_device_add(struct pci_dev *dev, struct pci_bus *bus)
 {
 	int ret;
@@ -1557,7 +1588,7 @@ void pci_device_add(struct pci_dev *dev, struct pci_bus *bus)
 	dev->dev.dma_mask = &dev->dma_mask;
 	dev->dev.dma_parms = &dev->dma_parms;
 	dev->dev.coherent_dma_mask = 0xffffffffull;
-	of_pci_dma_configure(dev);
+	pci_dma_configure(dev);
 
 	pci_set_dma_max_seg_size(dev, 65536);
 	pci_set_dma_seg_boundary(dev, 0xffffffff);
diff --git a/include/linux/of_pci.h b/include/linux/of_pci.h
index 29fd3fe..ce0e5ab 100644
--- a/include/linux/of_pci.h
+++ b/include/linux/of_pci.h
@@ -16,7 +16,6 @@ int of_pci_get_devfn(struct device_node *np);
 int of_irq_parse_and_map_pci(const struct pci_dev *dev, u8 slot, u8 pin);
 int of_pci_parse_bus_range(struct device_node *node, struct resource *res);
 int of_get_pci_domain_nr(struct device_node *node);
-void of_pci_dma_configure(struct pci_dev *pci_dev);
 #else
 static inline int of_irq_parse_pci(const struct pci_dev *pdev, struct of_phandle_args *out_irq)
 {
@@ -51,8 +50,6 @@ of_get_pci_domain_nr(struct device_node *node)
 {
 	return -1;
 }
-
-static inline void of_pci_dma_configure(struct pci_dev *pci_dev) { }
 #endif
 
 #if defined(CONFIG_OF_ADDRESS)
-- 
2.1.0



From jassisinghbrar at gmail.com  Thu Aug 13 03:01:36 2015
From: jassisinghbrar at gmail.com (Jassi Brar)
Date: Thu, 13 Aug 2015 15:31:36 +0530
Subject: [PATCH v2 5/6] mailbox: Add generic mechanism for testing Mailbox
 Controllers
In-Reply-To: <20150813091914.GB8782@x1>
References: <1437990272-23111-1-git-send-email-lee.jones@linaro.org>
 <1437990272-23111-6-git-send-email-lee.jones@linaro.org>
 <CABb+yY20nQbiEEZeRvWTMUsJ2qgwRn8CrWvnFDSB-b1dgVaAuw@mail.gmail.com>
 <20150812102328.GD18282@x1>
 <CABb+yY0A74Vy3-KOvj0URU_4zb2FAC7Yp3gmEwnFaBrD0mzt0w@mail.gmail.com>
 <20150813091914.GB8782@x1>
Message-ID: <CABb+yY0cgbtM68-E_Xqgh5O6GRLXESYTLa5WcAwUBoVL3ufrxA@mail.gmail.com>

On Thu, Aug 13, 2015 at 2:49 PM, Lee Jones <lee.jones at linaro.org> wrote:
> On Thu, 13 Aug 2015, Jassi Brar wrote:

>> >> > +
>> >> > +static void mbox_test_prepare_message(struct mbox_client *client, void *message)
>> >> > +{
>> >> > +       struct mbox_test_device *tdev = dev_get_drvdata(client->dev);
>> >> > +
>> >> > +       if (tdev->mmio)
>> >> > +               memcpy(tdev->mmio, message, MBOX_MAX_MSG_LEN);
>> >> >
>> >> This is unlikely to work. Those platforms that need to send a 2 part
>> >> message, they do :
>> >> (a) Signal/Command/Target code via some controller register (via
>> >> mbox_send_message).
>> >> (b) Setup the payload in Shared-Memory (via tx_prepare).
>> >>
>> >> This test driver assumes both are the same. I think you have to
>> >> declare something like
>> >
>> > This driver assumes that the framework will call client->tx_prepare()
>> > first, which satisfies (b).  It then assumes controller->send_data()
>> > will be invoked, which will send the platform specific
>> > signal/command/target code, which then satisfies (a).
>> >
>> Yeah, but what would be that code? Who provides that?
>>
>> > In what way does it assume they are the same?
>> >
>> notice the 'message' pointer in
>> mbox_send_message(tdev->tx_channel, message);
>>     and
>> memcpy(tdev->mmio, message, MBOX_MAX_MSG_LEN);
>>
>> >> struct mbox_test_message { /* same for TX and RX */
>> >>           unsigned sig_len;
>> >>           void *signal;               /* rx/tx via mailbox api */
>> >>           unsigned pl_len;
>> >>           void *payload;           /* rx/tx via shared-memory */
>> >> };
>> >
>> > How do you think this should be set and use these?
>> >
>> The userspace would want to specify the command code (32bits or not)
>> that would be passed via the fifo/register of the controller. So we
>> need signal[]
>>
>> The data to be passed via share-memory could be provided by userspace
>> via the payload[] array.
>
> Okay, so would the solution be two userspace files 'signal' and
> 'message', so in the case of a client specified signal we can write it
> into there first.
>
> echo 255  > signal
> echo test > message
>
> ... or in the case where no signal is required, or the controller
> driver taking care of it, we just don't write anything to signal?
>
file_operations.write() should parse signal and message, coming from
userspace, into a local structure before routing them via
mbox_send_message and tx_prepare respectively.

> Just for clarification, in the case where a signal is required, do
> clients usually pass that through mbox_send_message() too?
>
>   mbox_send_message(tdev->tx_channel, signal);
>   mbox_send_message(tdev->tx_channel, message);
>
No. Command/Signal code is passed via mbox_send_message(signal). The
payload is passed via Shared-Memory during tx_prepare(message)


>> >> > +static void mbox_test_message_sent(struct mbox_client *client,
>> >> > +                                  void *message, int r)
>> >> > +{
>> >> > +       if (r)
>> >> > +               dev_warn(client->dev,
>> >> > +                        "Client: Message could not be sent: %d\n", r);
>> >> > +       else
>> >> > +               dev_info(client->dev,
>> >> > +                        "Client: Message sent\n");
>> >> > +}
>> >> > +
>> >> > +static struct mbox_chan *
>> >> > +mbox_test_request_channel(struct platform_device *pdev, const char *name)
>> >> > +{
>> >> > +       struct mbox_client *client;
>> >> > +
>> >> > +       client = devm_kzalloc(&pdev->dev, sizeof(*client), GFP_KERNEL);
>> >> > +       if (!client)
>> >> > +               return ERR_PTR(-ENOMEM);
>> >> > +
>> >> > +       client->dev             = &pdev->dev;
>> >> > +       client->rx_callback     = mbox_test_receive_message;
>> >> > +       client->tx_prepare      = mbox_test_prepare_message;
>> >> > +       client->tx_done         = mbox_test_message_sent;
>> >> > +       client->tx_block        = true;
>> >> > +       client->knows_txdone    = false;
>> >> > +       client->tx_tout         = 500;
>> >> > +
>> >> > +       return mbox_request_channel_byname(client, name);
>> >> > +}
>> >> > +
>> >> > +static int mbox_test_probe(struct platform_device *pdev)
>> >> > +{
>> >> > +       struct mbox_test_device *tdev;
>> >> > +       struct resource *res;
>> >> > +       int ret;
>> >> > +
>> >> > +       tdev = devm_kzalloc(&pdev->dev, sizeof(*tdev), GFP_KERNEL);
>> >> > +       if (!tdev)
>> >> > +               return -ENOMEM;
>> >> > +
>> >> > +       /* It's okay for MMIO to be NULL */
>> >> > +       res = platform_get_resource(pdev, IORESOURCE_MEM, 0);
>> >> > +       tdev->mmio = devm_ioremap_resource(&pdev->dev, res);
>> >> > +       if (IS_ERR(tdev->mmio))
>> >> > +               tdev->mmio = NULL;
>> >> > +
>> >> > +       tdev->tx_channel = mbox_test_request_channel(pdev, "tx");
>> >> > +       if (IS_ERR(tdev->tx_channel))
>> >> > +               return PTR_ERR(tdev->tx_channel);
>> >> > +
>> >> > +       tdev->rx_channel = mbox_test_request_channel(pdev, "rx");
>> >> > +       if (IS_ERR(tdev->rx_channel))
>> >> > +               return PTR_ERR(tdev->rx_channel);
>> >> > +
>> >> Should it really fail on TX or RX only clients?
>> >
>> > Good question.  Probably not, but I guess we'd need a flag for that.
>> >
>> Just assume 1 channel. You can't make it receive if the controller
>> can't do rx, so the userspace will simply block on read requests. And
>> you can't make the controller send, if it can't. So any write attempt
>> will simply return with an error.
>>  And we are going to need very platform specific knowledge to execute
>> the tests. It's not like some loop enumerating all possible
>> combinations of parameters that the api must pass... so we are good.
>
> I'm guessing most tests will be some kind of send-reply test, so we'd
> need two channels for that.  I can make it so the driver does not fail
> if 'tx' or 'rx' is missing, but will fail if both are.
>
I have seen more channels to be rx+tx, than rx/tx only. And for latter
case the user should run 2 test threads, one each for RX and TX.

> Bare in mind that this test driver isn't designed to cover all of the
> corner cases, but more designed as a helpful boiler plate where it
> will tick some use-case boxes, but is clear enough to be hacked around
> by other vendors who have different requirements.
>
> With regards to you comments on userspace; I suggest that whoever is
> testing the controller will know it and will not attempt to check for
> a reply from a controller (or co-proc) which is write-only.
>
That's actually my point :)
When the userspace already has all that platform specific knowledge,
why check for 'valid' usage in controller driver? Simply reject any
request that the controller isn't capable of (which is practically
never supposed to happen).

Thanks.


From marc.zyngier at arm.com  Thu Aug 13 03:01:35 2015
From: marc.zyngier at arm.com (Marc Zyngier)
Date: Thu, 13 Aug 2015 11:01:35 +0100
Subject: [PATCH v2 2/6] genirq: fix irqchip_set_wake_parent if
 IRQCHIP_SKIP_SET_WAKE
In-Reply-To: <1439401562-28874-3-git-send-email-grygorii.strashko@ti.com>
References: <1439401562-28874-1-git-send-email-grygorii.strashko@ti.com>
 <1439401562-28874-3-git-send-email-grygorii.strashko@ti.com>
Message-ID: <55CC6AFF.8060400@arm.com>

On 12/08/15 18:45, Grygorii Strashko wrote:
> The irqchip_set_wake_parent should not fail if IRQ chip
> specifies IRQCHIP_SKIP_SET_WAKE. Otherwise, IRQ wakeup
> configuration can't be propagated properly through IRQ
> domains hierarchy.
> 
> In case of TI OMAP DRA7 the issue reproduced with following
> configuration:
> ARM GIC<-OMAP wakeupgen<-TI CBAR<-GPIO<-GPIO pcf857x<-gpio_key
> 
> gpio_key is wakeup source
> 
> Failure is reproduced during suspend/resume to RAM:
> suspend:
>  - gpio_keys_suspend
>    enable_irq_wake
>      + pcf857x_irq_set_wake
>        + omap_gpio_wake_enable
>          + TI CBAR irq_chip_set_wake_parent
>            + OMAP wakeupgen has no .irq_set_wake()

Most importantly, wakeupgen has IRQCHIP_SKIP_SET_WAKE set.

>            and -ENOSYS will be returned
> 
> resume:
>  - gpio_keys_resume
>    + disable_irq_wake
>      + irq_set_irq_wake
>        + WARN(1, "Unbalanced IRQ %d wake disable\n", irq);
> 
> Fixes: 08b55e2a9208 ('genirq: Add irqchip_set_wake_parent')
> Signed-off-by: Grygorii Strashko <grygorii.strashko at ti.com>
> ---
>  kernel/irq/chip.c | 4 ++++
>  1 file changed, 4 insertions(+)
> 
> diff --git a/kernel/irq/chip.c b/kernel/irq/chip.c
> index 6de638b..bdb1b9d 100644
> --- a/kernel/irq/chip.c
> +++ b/kernel/irq/chip.c
> @@ -1024,6 +1024,10 @@ int irq_chip_set_vcpu_affinity_parent(struct irq_data *data, void *vcpu_info)
>  int irq_chip_set_wake_parent(struct irq_data *data, unsigned int on)
>  {
>  	data = data->parent_data;
> +
> +	if (irq_data_get_irq_chip(data)->flags & IRQCHIP_SKIP_SET_WAKE)
> +		return 0;
> +
>  	if (data->chip->irq_set_wake)
>  		return data->chip->irq_set_wake(data, on);
>  
> 

We have a more general issue with chip flags, and how they combine
within a stack of irqchips.

What if you remove the irq_chip_set_wake_parent from the crossbar
driver, and instead set IRQCHIP_SKIP_SET_WAKE?

Thanks,

	M.
-- 
Jazz is not dead. It just smells funny...


From kgene at kernel.org  Thu Aug 13 03:02:57 2015
From: kgene at kernel.org (Kukjin Kim)
Date: Thu, 13 Aug 2015 19:02:57 +0900
Subject: [GIT PULL 4/5] Samsung 2nd DT updates for v4.3
In-Reply-To: <20150813091814.GA30160@localhost>
References: <55C069D5.1050409@kernel.org> <20150813091814.GA30160@localhost>
Message-ID: <004101d0d5af$3c688420$b5398c60$@kernel.org>

Olof Johansson wrote:
> 
> On Tue, Aug 04, 2015 at 04:29:25PM +0900, Kukjin Kim wrote:
> > Hi Arnd, Olof, Kevin
> >
> > This 2nd DT update branch is based tags/samsung-dt-1 +
> > v4.3-topic/clk-samsung branch because of dependency to support generic
> > cpufreq driver. Please pull.
> >
> > Thanks,
> > Kukjin
> >
> >
> > The following changes since commit e4a39d904c3c3e4855287b7325306289ff044b06:
> >
> >   Merge branch 'v4.3-topic/clk-samsung' into v4.3-next/dt-samsung-2
> > (2015-07-24 12:54:00 +0900)
> >
> > are available in the git repository at:
> >
> >
> >   git://git.kernel.org/pub/scm/linux/kernel/git/kgene/linux-samsung.git
> > tags/samsung-dt-2
> 
> "clk: exynos5250: add cpu clock configuration data and instantiate cpu
> clock" is applied twice, once to your own branch, and once merged in
> from Mike's branch. That doesn't look right.
> 
Oops, it's my fault. Sorry for that.

> Can you please respin? Thanks.
> 
Sure, I'll tonight in my time.

Thanks,
Kukjin



From tony at atomide.com  Thu Aug 13 03:08:46 2015
From: tony at atomide.com (Tony Lindgren)
Date: Thu, 13 Aug 2015 03:08:46 -0700
Subject: [GIT PULL 2/2] omap device tree changes for v4.3, part 4
In-Reply-To: <pull-1439455019-336197>
References: <pull-1439455019-336197>
Message-ID: <pull-1439455019-336197-2>

The following changes since commit ed05637c30e6d13e5793aab64d6a6e57e30228af:

  ARM: dts: omap3-devkit8000: Add ADS7846 Touchscreen support (2015-08-06 02:43:09 -0700)

are available in the git repository at:

  git://git.kernel.org/pub/scm/linux/kernel/git/tmlind/linux-omap tags/omap-for-v4.3/dt-pt4-v2

for you to fetch changes up to 8cbd4c2f6a996f6cf5dfdf8775d331606cff95bd:

  arm: boot: dts: am4372: add ARM timers and SCU nodes (2015-08-13 01:25:11 -0700)

----------------------------------------------------------------
Fix up bogus RTC compatible change for am4372 and add missing
DPLL for am4372 cpsw Ethernet driver. Also add ARM global and
local timers for am4372.

----------------------------------------------------------------
Felipe Balbi (1):
      arm: boot: dts: am4372: add ARM timers and SCU nodes

Keerthy (3):
      ARM: dts: AM437X: add dpll_clksel_mac_clk node
      ARM: dts: am4372: Set the default clock rate for dpll_clksel_mac_clk clock
      ARM: dts: AM4372: Add the am4372-rtc compatible string

Tony Lindgren (1):
      Merge branch 'for-4.3/ti-clk-dt' of https://github.com/t-kristo/linux-pm into omap-for-v4.3/dt-v2

 Documentation/devicetree/bindings/rtc/rtc-omap.txt |  1 +
 arch/arm/boot/dts/am4372.dtsi                      | 31 +++++++++++++++++++---
 arch/arm/boot/dts/am43xx-clocks.dtsi               |  9 +++++++
 drivers/clk/ti/clk-43xx.c                          |  1 +
 4 files changed, 39 insertions(+), 3 deletions(-)


From tony at atomide.com  Thu Aug 13 03:08:45 2015
From: tony at atomide.com (Tony Lindgren)
Date: Thu, 13 Aug 2015 03:08:45 -0700
Subject: [GIT PULL 1/2] omap soc fix for v4.3 merge window
Message-ID: <pull-1439455019-336197>

The following changes since commit 24da741c678f865de3182194604dbddcc7fc7f3c:

  Merge branch 'dm814x-soc' into omap-for-v4.3/soc (2015-07-23 21:59:18 -0700)

are available in the git repository at:

  git://git.kernel.org/pub/scm/linux/kernel/git/tmlind/linux-omap tags/omap-for-v4.3/soc-pt2

for you to fetch changes up to ed293d1ad2b0c28b6abc3bd728b07754bc00f1cd:

  memory: kill off set_irq_flags usage (2015-08-13 00:48:52 -0700)

----------------------------------------------------------------
Fix omap PM regression in Linux next and kill set_irq_flags usage
for GPMC.

----------------------------------------------------------------
Rob Herring (1):
      memory: kill off set_irq_flags usage

Tony Lindgren (1):
      ARM: OMAP2+: Fix power domain operations regression caused by 81xx

 arch/arm/mach-omap2/powerdomains3xxx_data.c | 6 +++++-
 drivers/memory/omap-gpmc.c                  | 5 ++---
 2 files changed, 7 insertions(+), 4 deletions(-)


From kgene at kernel.org  Thu Aug 13 03:11:04 2015
From: kgene at kernel.org (Kukjin Kim)
Date: Thu, 13 Aug 2015 19:11:04 +0900
Subject: [GIT PULL 2nd 2/4] Samsung DT 3rd updates for v4.3
In-Reply-To: <20150813092038.GC30160@localhost>
References: <55CBE0F2.4020104@kernel.org> <20150813092038.GC30160@localhost>
Message-ID: <005101d0d5b0$5d4333b0$17c99b10$@kernel.org>

Olof Johansson wrote:
> 
> On Thu, Aug 13, 2015 at 09:12:34AM +0900, Kukjin Kim wrote:
> > Hi Arnd, Olof, Kevin
> >
> > This is based on tags/samsung-dt-2 and including exynos4 related clock
> > changes to support cpufreq-dt driver for exynos4 SoCs. Note that I've
> > created one more clk topic branch called v4.3-topic/clk-samsung-2 based
> > on previous one has been merged by Mike into clock tree before but I'm
> > not sure new one merged into clk tree that's why I've noted its merge in
> > this signed tag.
> 
> Since this depends on the previous DT branch that I asked for a respin, please
> do it all over and send a fresh pull request that we hopefully can include.
> 
Yes, will make a fresh pull request for the exynos cpufreq-dt driver.

> We normally ask that you don't queue up merge requests like these for that
> reason: If there's need to redo an earlier branch there's a lot of work that
> needs to be done on your side. Instead, please wait until previous pull request
> has been merged before you send the next one. Thanks!
> 
Yeah, you're right. Actually, it was hard to handle it because of dependencies
of clk and cpufreq...Anyway I'll keep in mind what you suggested.

Thanks,
Kukjin



From mkl at pengutronix.de  Thu Aug 13 03:11:18 2015
From: mkl at pengutronix.de (Marc Kleine-Budde)
Date: Thu, 13 Aug 2015 12:11:18 +0200
Subject: [PATCH] can: at91: move at91_can_data to at91_can.c
In-Reply-To: <1439217894-15230-1-git-send-email-alexandre.belloni@free-electrons.com>
References: <1439217894-15230-1-git-send-email-alexandre.belloni@free-electrons.com>
Message-ID: <55CC6D46.8020202@pengutronix.de>

On 08/10/2015 04:44 PM, Alexandre Belloni wrote:
> struct at91_can_data is now only used inside the driver, move it to
> its c file.

It was supposed to be the interface between the board and the CAN
driver. In commit 4403ac46edcdb51e92d36ad9f00ea3bbb766342e the
at91sam9263 board was removed. As the driver has no support for DT
transceiver switch, this functionality was lost. We should either remove
the transceiver support or add a DT regulator for this.

Marc

-- 
Pengutronix e.K.                  | Marc Kleine-Budde           |
Industrial Linux Solutions        | Phone: +49-231-2826-924     |
Vertretung West/Dortmund          | Fax:   +49-5121-206917-5555 |
Amtsgericht Hildesheim, HRA 2686  | http://www.pengutronix.de   |

-------------- next part --------------
A non-text attachment was scrubbed...
Name: signature.asc
Type: application/pgp-signature
Size: 455 bytes
Desc: OpenPGP digital signature
URL: <http://lists.infradead.org/pipermail/linux-arm-kernel/attachments/20150813/726599ba/attachment.sig>

From kgene at kernel.org  Thu Aug 13 03:12:24 2015
From: kgene at kernel.org (Kukjin Kim)
Date: Thu, 13 Aug 2015 19:12:24 +0900
Subject: [GIT PULL 5/5] Samsung driver updates for v4.3
In-Reply-To: <20150813091848.GB30160@localhost>
References: <55C06A0A.6040407@kernel.org> <20150813091848.GB30160@localhost>
Message-ID: <007601d0d5b0$8c6eb3d0$a54c1b70$@kernel.org>

Olof Johansson wrote:
> 
> On Tue, Aug 04, 2015 at 04:30:18PM +0900, Kukjin Kim wrote:
> > Hi,
> >
> > This branch is including to support generic cpufreq driver in
> > mach-exynos dir. for exynos3250 and exynos5250 even the tag name is
> > driver. Because it is depending on clk and cpufreq changes which acked
> > by regarding maintainers, Mike and Viresh.
> >
> > Please pull and if any problems, please kindly let me know.
> 
> This now needs to be respun too, apparantly, since it includes dt2.
> 
Sure, I'll.

Thanks
Kukjin



From kgene at kernel.org  Thu Aug 13 03:13:59 2015
From: kgene at kernel.org (Kukjin Kim)
Date: Thu, 13 Aug 2015 19:13:59 +0900
Subject: [GIT PULL 2nd 3/4] Samsung driver 2nd updates for v4.3
In-Reply-To: <20150813092144.GD30160@localhost>
References: <55CBE10B.2030103@kernel.org> <20150813092144.GD30160@localhost>
Message-ID: <007a01d0d5b0$c53d6580$4fb83080$@kernel.org>

Olof Johansson wrote:
> 
> On Thu, Aug 13, 2015 at 09:12:59AM +0900, Kukjin Kim wrote:
> > Hi,
> >
> > I've created the signed tag based on previous tags/samsung-driver so you
> > can see several merge in there. To support cpufreq-dt driver requires
> > clk/cpufreq/exynos changes together and clk/cpufreq maintainers are
> > aware of this changes. And we can remove exynos cpufreq driver at last.
> >
> > Note this drivers update is including previous dependencies and if
> > you're OK, please pull.
> 
> Again, this needs to be revisited.
> 
YES.

> Please try to keep the dependency only driver->dt if you can,
> and we can merge drivers before DT this release cycle. If you do
> driver->dt->driver->dt like here then things get messy.
> 
It looks better. OK.

Thanks,
Kukjin



From k.kozlowski at samsung.com  Thu Aug 13 03:14:51 2015
From: k.kozlowski at samsung.com (Krzysztof Kozlowski)
Date: Thu, 13 Aug 2015 19:14:51 +0900
Subject: [PATCH v2] ARM: dts: exynos4412-odroidu3: Enable SPI1.
In-Reply-To: <1439456813-4918-1-git-send-email-aballier@gentoo.org>
References: <1439456813-4918-1-git-send-email-aballier@gentoo.org>
Message-ID: <55CC6E1B.2050707@samsung.com>

W dniu 13.08.2015 o 18:06, Alexis Ballier pisze:
> SPI1 is available on IO Port #2 (as depicted on their website) in
> PCB Revision 0.5 of Hardkernel Odroid U3 board.
> The shield connects a 256KiB spi-nor flash on that bus.
> 
> Signed-off-by: Alexis Ballier <aballier at gentoo.org>
> 
> ---
> 
> Changes in v2: Use GPIO_ACTIVE_HIGH (Krzysztof Kozlowski)
> 
>  arch/arm/boot/dts/exynos4412-odroidu3.dts | 8 ++++++++
>  1 file changed, 8 insertions(+)

Thanks for fixing, looks good:

Reviewed-by: Krzysztof Kozlowski <k.kozlowski at samsung.com>

Best regards,
Krzysztof



From kgene at kernel.org  Thu Aug 13 03:17:27 2015
From: kgene at kernel.org (Kukjin Kim)
Date: Thu, 13 Aug 2015 19:17:27 +0900
Subject: [PATCH v2] ARM: dts: exynos4412-odroidu3: Enable SPI1.
In-Reply-To: <55CC6E1B.2050707@samsung.com>
References: <1439456813-4918-1-git-send-email-aballier@gentoo.org>
 <55CC6E1B.2050707@samsung.com>
Message-ID: <009d01d0d5b1$417e5370$c47afa50$@kernel.org>

Krzysztof Kozlowski wrote:
> 
> W dniu 13.08.2015 o 18:06, Alexis Ballier pisze:
> > SPI1 is available on IO Port #2 (as depicted on their website) in
> > PCB Revision 0.5 of Hardkernel Odroid U3 board.
> > The shield connects a 256KiB spi-nor flash on that bus.
> >
> > Signed-off-by: Alexis Ballier <aballier at gentoo.org>
> >
> > ---
> >
> > Changes in v2: Use GPIO_ACTIVE_HIGH (Krzysztof Kozlowski)
> >
> >  arch/arm/boot/dts/exynos4412-odroidu3.dts | 8 ++++++++
> >  1 file changed, 8 insertions(+)
> 
> Thanks for fixing, looks good:
> 
> Reviewed-by: Krzysztof Kozlowski <k.kozlowski at samsung.com>
> 
Applied, thanks.

- Kukjin



From grygorii.strashko at ti.com  Thu Aug 13 03:17:28 2015
From: grygorii.strashko at ti.com (Grygorii Strashko)
Date: Thu, 13 Aug 2015 13:17:28 +0300
Subject: [PATCH v2 6/6] irqchip: crossbar: fix irq masking at suspend
In-Reply-To: <55CC63D0.8030707@arm.com>
References: <1439401562-28874-1-git-send-email-grygorii.strashko@ti.com>
 <1439401562-28874-7-git-send-email-grygorii.strashko@ti.com>
 <55CC63D0.8030707@arm.com>
Message-ID: <55CC6EB8.3050906@ti.com>

On 08/13/2015 12:30 PM, Sudeep Holla wrote:
> 
> 
> On 12/08/15 18:46, Grygorii Strashko wrote:
>> All ARM GIC IRQs have to masked during suspend if they are not
>> wakeup source. Now this is not happen, since switching to
>> use IRQ domain hierarchy, because suspend_device_irq() only checks flags
>> in the last IRQ chip in hierarchy for IRQCHIP_MASK_ON_SUSPEND
>> bit set. And in the case of TI OMAP DRA7 the last IRQ chip is TI Crossbar
>> which do not have this flag set.
>>
>> In case of TI OMAP DRA7 the following IRQ hierarchy is defined:
>>    ARM GIC <- OMAP wakeupgen <- TI CBAR
>> ARM GIC - IRQCHIP_MASK_ON_SUSPEND=n
> 
> May be this won't affect your platform or this patch but even GIC marks
> IRQCHIP_MASK_ON_SUSPEND=y now since GIC doesn't provide any facility to
> configure the wakeup source and keeps all the interrupt source enabled.

That's true for next, bur not true for 4.2-rc6 or 4.1 :(

> 
> We have this flag enabled now as it's always safer to mask all the non
> wakeup interrupts are masked at the chip level when suspending.

Indeed, but that's do not work in case of IRQ domain hierarchy and
it's do not clear how should it work?
I've tried to describe this problem in cover letter actually.

> 
> Also the beginning of the commit message contradicts when you also say
> in the following statement IRQCHIP_MASK_ON_SUSPEND=n. So you may need to
> update the log.

I'll try to reword. What I've tried to mention that IRQs masking on
suspend is default expected behavior and that how it was before
switching to IRQ domain hierarchy.

"All ARM GIC IRQs have to masked during suspend if they are not
 wakeup source - this is expected behavior and that's how it was before
 switching to IRQ domain hierarchy. ..."
ok?

-- 
regards,
-grygorii


From lee.jones at linaro.org  Thu Aug 13 03:23:35 2015
From: lee.jones at linaro.org (Lee Jones)
Date: Thu, 13 Aug 2015 11:23:35 +0100
Subject: [PATCH v2 5/6] mailbox: Add generic mechanism for testing
 Mailbox Controllers
In-Reply-To: <CABb+yY0cgbtM68-E_Xqgh5O6GRLXESYTLa5WcAwUBoVL3ufrxA@mail.gmail.com>
References: <1437990272-23111-1-git-send-email-lee.jones@linaro.org>
 <1437990272-23111-6-git-send-email-lee.jones@linaro.org>
 <CABb+yY20nQbiEEZeRvWTMUsJ2qgwRn8CrWvnFDSB-b1dgVaAuw@mail.gmail.com>
 <20150812102328.GD18282@x1>
 <CABb+yY0A74Vy3-KOvj0URU_4zb2FAC7Yp3gmEwnFaBrD0mzt0w@mail.gmail.com>
 <20150813091914.GB8782@x1>
 <CABb+yY0cgbtM68-E_Xqgh5O6GRLXESYTLa5WcAwUBoVL3ufrxA@mail.gmail.com>
Message-ID: <20150813102335.GC8782@x1>

On Thu, 13 Aug 2015, Jassi Brar wrote:

> On Thu, Aug 13, 2015 at 2:49 PM, Lee Jones <lee.jones at linaro.org> wrote:
> > On Thu, 13 Aug 2015, Jassi Brar wrote:
> 
> >> >> > +
> >> >> > +static void mbox_test_prepare_message(struct mbox_client *client, void *message)
> >> >> > +{
> >> >> > +       struct mbox_test_device *tdev = dev_get_drvdata(client->dev);
> >> >> > +
> >> >> > +       if (tdev->mmio)
> >> >> > +               memcpy(tdev->mmio, message, MBOX_MAX_MSG_LEN);
> >> >> >
> >> >> This is unlikely to work. Those platforms that need to send a 2 part
> >> >> message, they do :
> >> >> (a) Signal/Command/Target code via some controller register (via
> >> >> mbox_send_message).
> >> >> (b) Setup the payload in Shared-Memory (via tx_prepare).
> >> >>
> >> >> This test driver assumes both are the same. I think you have to
> >> >> declare something like
> >> >
> >> > This driver assumes that the framework will call client->tx_prepare()
> >> > first, which satisfies (b).  It then assumes controller->send_data()
> >> > will be invoked, which will send the platform specific
> >> > signal/command/target code, which then satisfies (a).
> >> >
> >> Yeah, but what would be that code? Who provides that?
> >>
> >> > In what way does it assume they are the same?
> >> >
> >> notice the 'message' pointer in
> >> mbox_send_message(tdev->tx_channel, message);
> >>     and
> >> memcpy(tdev->mmio, message, MBOX_MAX_MSG_LEN);
> >>
> >> >> struct mbox_test_message { /* same for TX and RX */
> >> >>           unsigned sig_len;
> >> >>           void *signal;               /* rx/tx via mailbox api */
> >> >>           unsigned pl_len;
> >> >>           void *payload;           /* rx/tx via shared-memory */
> >> >> };
> >> >
> >> > How do you think this should be set and use these?
> >> >
> >> The userspace would want to specify the command code (32bits or not)
> >> that would be passed via the fifo/register of the controller. So we
> >> need signal[]
> >>
> >> The data to be passed via share-memory could be provided by userspace
> >> via the payload[] array.
> >
> > Okay, so would the solution be two userspace files 'signal' and
> > 'message', so in the case of a client specified signal we can write it
> > into there first.
> >
> > echo 255  > signal
> > echo test > message
> >
> > ... or in the case where no signal is required, or the controller
> > driver taking care of it, we just don't write anything to signal?
> >
> file_operations.write() should parse signal and message, coming from
> userspace, into a local structure before routing them via
> mbox_send_message and tx_prepare respectively.

Okay.  So before I code this up we should agree on syntax.

How would you like to represent the break between signal and message?
Obviously ' ' would be a bad idea, as some clients may want to send
messages with white space contained.  How about '\t' or '\n'?

> > Just for clarification, in the case where a signal is required, do
> > clients usually pass that through mbox_send_message() too?
> >
> >   mbox_send_message(tdev->tx_channel, signal);
> >   mbox_send_message(tdev->tx_channel, message);
> >
> No. Command/Signal code is passed via mbox_send_message(signal). The
> payload is passed via Shared-Memory during tx_prepare(message)

Okay, I see.  Thanks for the clarification.

> >> >> > +static void mbox_test_message_sent(struct mbox_client *client,
> >> >> > +                                  void *message, int r)
> >> >> > +{
> >> >> > +       if (r)
> >> >> > +               dev_warn(client->dev,
> >> >> > +                        "Client: Message could not be sent: %d\n", r);
> >> >> > +       else
> >> >> > +               dev_info(client->dev,
> >> >> > +                        "Client: Message sent\n");
> >> >> > +}
> >> >> > +
> >> >> > +static struct mbox_chan *
> >> >> > +mbox_test_request_channel(struct platform_device *pdev, const char *name)
> >> >> > +{
> >> >> > +       struct mbox_client *client;
> >> >> > +
> >> >> > +       client = devm_kzalloc(&pdev->dev, sizeof(*client), GFP_KERNEL);
> >> >> > +       if (!client)
> >> >> > +               return ERR_PTR(-ENOMEM);
> >> >> > +
> >> >> > +       client->dev             = &pdev->dev;
> >> >> > +       client->rx_callback     = mbox_test_receive_message;
> >> >> > +       client->tx_prepare      = mbox_test_prepare_message;
> >> >> > +       client->tx_done         = mbox_test_message_sent;
> >> >> > +       client->tx_block        = true;
> >> >> > +       client->knows_txdone    = false;
> >> >> > +       client->tx_tout         = 500;
> >> >> > +
> >> >> > +       return mbox_request_channel_byname(client, name);
> >> >> > +}
> >> >> > +
> >> >> > +static int mbox_test_probe(struct platform_device *pdev)
> >> >> > +{
> >> >> > +       struct mbox_test_device *tdev;
> >> >> > +       struct resource *res;
> >> >> > +       int ret;
> >> >> > +
> >> >> > +       tdev = devm_kzalloc(&pdev->dev, sizeof(*tdev), GFP_KERNEL);
> >> >> > +       if (!tdev)
> >> >> > +               return -ENOMEM;
> >> >> > +
> >> >> > +       /* It's okay for MMIO to be NULL */
> >> >> > +       res = platform_get_resource(pdev, IORESOURCE_MEM, 0);
> >> >> > +       tdev->mmio = devm_ioremap_resource(&pdev->dev, res);
> >> >> > +       if (IS_ERR(tdev->mmio))
> >> >> > +               tdev->mmio = NULL;
> >> >> > +
> >> >> > +       tdev->tx_channel = mbox_test_request_channel(pdev, "tx");
> >> >> > +       if (IS_ERR(tdev->tx_channel))
> >> >> > +               return PTR_ERR(tdev->tx_channel);
> >> >> > +
> >> >> > +       tdev->rx_channel = mbox_test_request_channel(pdev, "rx");
> >> >> > +       if (IS_ERR(tdev->rx_channel))
> >> >> > +               return PTR_ERR(tdev->rx_channel);
> >> >> > +
> >> >> Should it really fail on TX or RX only clients?
> >> >
> >> > Good question.  Probably not, but I guess we'd need a flag for that.
> >> >
> >> Just assume 1 channel. You can't make it receive if the controller
> >> can't do rx, so the userspace will simply block on read requests. And
> >> you can't make the controller send, if it can't. So any write attempt
> >> will simply return with an error.
> >>  And we are going to need very platform specific knowledge to execute
> >> the tests. It's not like some loop enumerating all possible
> >> combinations of parameters that the api must pass... so we are good.
> >
> > I'm guessing most tests will be some kind of send-reply test, so we'd
> > need two channels for that.  I can make it so the driver does not fail
> > if 'tx' or 'rx' is missing, but will fail if both are.
> >
> I have seen more channels to be rx+tx, than rx/tx only. And for latter
> case the user should run 2 test threads, one each for RX and TX.

Okay, makes sense to me.

> > Bare in mind that this test driver isn't designed to cover all of the
> > corner cases, but more designed as a helpful boiler plate where it
> > will tick some use-case boxes, but is clear enough to be hacked around
> > by other vendors who have different requirements.
> >
> > With regards to you comments on userspace; I suggest that whoever is
> > testing the controller will know it and will not attempt to check for
> > a reply from a controller (or co-proc) which is write-only.
> >
> That's actually my point :)
> When the userspace already has all that platform specific knowledge,
> why check for 'valid' usage in controller driver? Simply reject any
> request that the controller isn't capable of (which is practically
> never supposed to happen).

This conversation doesn't really belong in this thread; but seeing as
you bought it up ...

I absolutely and fundamentally disagree that the controller shouldn't
do error checking during mbox_request_channel(). It is
mbox_request_channel() that should fail on a known bad configuration,
rather than pass back a known rotten apple and wait for that it to be
eaten (appreciate I've gone a little overboard with the analogies)
before flagging it up.  And for what purpose?  To make the controller
driver a little simpler?  I do hope that you do see sense on this one
and allow me to keep the error checking in the driver!

If you have a reply to this, please do so one the driver thread, so
it's easier to follow.

Secondly, a reply more akin to this thread.  The guys using _this_
driver are more likely to be Controller authors.  These are the chaps
I was speaking about that are going to know the platform specifics of
the controller.  The error checking in mbox_request_channel() is
designed for 'client' authors, who are more likely to be requesting
invalid configurations.

-- 
Lee Jones
Linaro STMicroelectronics Landing Team Lead
Linaro.org ? Open source software for ARM SoCs
Follow Linaro: Facebook | Twitter | Blog


From aisheng.dong at freescale.com  Thu Aug 13 03:17:03 2015
From: aisheng.dong at freescale.com (Dong Aisheng)
Date: Thu, 13 Aug 2015 18:17:03 +0800
Subject: [PATCH V3 0/5] clk: support clocks which requires parent clock
 on during operation
In-Reply-To: <20150804094556.GE24870@shlinux1.ap.freescale.net>
References: <1438089585-30103-1-git-send-email-aisheng.dong@freescale.com>
 <20150728143824.GB16916@shlinux1.ap.freescale.net>
 <20150804094556.GE24870@shlinux1.ap.freescale.net>
Message-ID: <20150813101702.GB19166@shlinux1.ap.freescale.net>

On Tue, Aug 04, 2015 at 05:45:57PM +0800, Dong Aisheng wrote:
> On Tue, Jul 28, 2015 at 10:38:25PM +0800, Dong Aisheng wrote:
> > On Tue, Jul 28, 2015 at 09:19:40PM +0800, Dong Aisheng wrote:
> > > This patch series adds support in clock framework for clocks which operations
> > > requires its parent clock is on.
> > > 
> > > Such clock type is initially met on Freescale i.MX7D platform that all clocks
> > > operations, including enable/disable, rate change and re-parent, requires its
> > > parent clock on. No sure if any other SoC has the similar clock type.
> > > 
> > > Current clock core can not support such type of clock well.
> > > 
> > > This patch introduce a new flag CLK_SET_PARENT_ON to handle this special case
> > > in clock core that enable its parent clock firstly for each operation and disable
> > > it later after operation complete.
> > > 
> > > The most special case is for set_parent() operation which requires both parent,
> > > old one and new one, to be enabled at the same time during the operation.
> > > 
> > > The patch series is based on for-next branch of Michael's git:
> > > git://git.kernel.org/pub/scm/linux/kernel/git/clk/linux.git
> > > 
> > > Change Log:
> > > v2->v3:
> > >  * rebased version, no other changes.
> > > 
> > > v1->v2:
> > >  Mainly addressed Stephen Boyd's comments
> > >  * remove dupliciated code with __clk_set_parent_after
> > >  * introduce more clk_core_x APIs for core easily use
> > >  * move clk_disable_unused code position
> > >  * use clk_core_x API to make code more clean and easily read
> > > 
> > > Dong Aisheng (5):
> > >   clk: remove duplicated code with __clk_set_parent_after
> > >   clk: introduce clk_core_enable_lock and clk_core_disable_lock
> > >     functions
> > >   clk: move clk_disable_unused after clk_core_disable_unprepare function
> > >   clk: core: add CLK_OPS_PARENT_ON flags to support clocks require
> > >     parent on
> > >   clk: core: add CLK_OPS_PARENT_ON flags to support clocks require
> > >     parent on
> > > 
> > >  drivers/clk/clk.c            | 338 +++++++++++++++++++++++++------------------
> > >  include/linux/clk-provider.h |   5 +
> > >  2 files changed, 200 insertions(+), 143 deletions(-)
> > > 
> > 
> > Sorry, forgot to update Mike's new email address.
> > Updated.
> > 
> 
> Ping...
> 

Hi Mike,

It's been quite a long time.
Can you help pick this?

Regards
Dong Aisheng

> Regards
> Dong Aisheng
> 
> > Regards
> > Dong Aisheng
> > 
> > > -- 
> > > 1.9.1
> > > 


From xuwei5 at hisilicon.com  Thu Aug 13 03:18:10 2015
From: xuwei5 at hisilicon.com (Wei Xu)
Date: Thu, 13 Aug 2015 11:18:10 +0100
Subject: [RFC PATCH v4 6/9] arm: hisi_defconfig: remove CONFIG_MMC_DW_IDMAC
In-Reply-To: <1438843553-24058-1-git-send-email-shawn.lin@rock-chips.com>
References: <1438843469-23807-1-git-send-email-shawn.lin@rock-chips.com>
 <1438843553-24058-1-git-send-email-shawn.lin@rock-chips.com>
Message-ID: <55CC6EE2.4070308@hisilicon.com>



On 8/6/2015 7:45 AM, Shawn Lin wrote:
> DesignWare MMC Controller's transfer mode should be decided
> at runtime instead of compile-time. So we remove this config
> option and read dw_mmc's register to select DMA master.
> 
> Signed-off-by: Shawn Lin <shawn.lin at rock-chips.com>

Acked-by: Wei Xu <xuwei5 at hisilicon.com>

> ---
> 
> Changes in v4: None
> Changes in v3: None
> Changes in v2: None
> 
>  arch/arm/configs/hisi_defconfig | 1 -
>  1 file changed, 1 deletion(-)
> 
> diff --git a/arch/arm/configs/hisi_defconfig b/arch/arm/configs/hisi_defconfig
> index 5997dbc..b2e340b 100644
> --- a/arch/arm/configs/hisi_defconfig
> +++ b/arch/arm/configs/hisi_defconfig
> @@ -69,7 +69,6 @@ CONFIG_NOP_USB_XCEIV=y
>  CONFIG_MMC=y
>  CONFIG_RTC_CLASS=y
>  CONFIG_MMC_DW=y
> -CONFIG_MMC_DW_IDMAC=y
>  CONFIG_MMC_DW_PLTFM=y
>  CONFIG_RTC_DRV_PL031=y
>  CONFIG_DMADEVICES=y
> 

Thanks!

Best Regards,
Wei



From lorenzo.pieralisi at arm.com  Thu Aug 13 03:30:08 2015
From: lorenzo.pieralisi at arm.com (Lorenzo Pieralisi)
Date: Thu, 13 Aug 2015 11:30:08 +0100
Subject: [PATCH 2/2] Convert smsc911x to use ACPI as well as DT
In-Reply-To: <20150813093838.GC5468@xora-haswell.xora.org.uk>
References: <1439417187-21411-1-git-send-email-jeremy.linton@arm.com>
 <1439417187-21411-3-git-send-email-jeremy.linton@arm.com>
 <20150813082759.GB5468@xora-haswell.xora.org.uk>
 <20150813090117.GA13833@red-moon>
 <20150813093838.GC5468@xora-haswell.xora.org.uk>
Message-ID: <20150813103008.GA13356@red-moon>

On Thu, Aug 13, 2015 at 10:38:38AM +0100, Graeme Gregory wrote:
> On Thu, Aug 13, 2015 at 10:01:17AM +0100, Lorenzo Pieralisi wrote:
> > On Thu, Aug 13, 2015 at 09:27:59AM +0100, Graeme Gregory wrote:
> > > On Wed, Aug 12, 2015 at 05:06:27PM -0500, Jeremy Linton wrote:
> > > > Add ACPI bindings for the smsc911x driver. Convert the DT specific calls
> > > > to nonspecific device* calls, This allows the driver to work
> > > > with both ACPI and DT configurations. Ethernet should now work when using
> > > > ACPI on ARM Juno.
> > 
> > Last sentence does not belong in the commit log.
> > 
> > > > 
> > > > Signed-off-by: Jeremy Linton <jeremy.linton at arm.com>
> > > 
> > > The code looks fine to me.
> > > 
> > > Currently the compulsary DT properties seem to match the "approved" ACPI
> > > NIC properties from here
> > > 
> > > http://www.uefi.org/sites/default/files/resources/nic-request-v2.pdf
> > 
> > What about _DSD device specific properties (eg "smsc,save-mac-address") ?
> > Are we taking 1:1 translation between DT and ACPI for granted ?
> > 
> > I thought some process must be put in place to define the corresponding
> > bindings in ACPI before starting this mechanical translation or maybe
> > I missed something, I would like to understand.
> > 
> > How does the device specific _DSD definitions work in ACPI world ? Where
> > are they published ? How will we translate those to DT bindings if there
> > is need ?
> > 
> 
> This I do not know as that discussion is still ongoing. But those
> options are currently marked as optional so driver should not fail if
> they are not present in ACPI.

Well yes, but if they are present this patch uses them when booting
with ACPI and that's what I am arguing about, because they are
undocumented.

This discussion should be brought to completion, the _DSD usage and
bindings sharing between DT and ACPI well defined before we can
enable drivers to rely on properties that in ACPI world have no
binding definition at all, if we go by this route we might end
up having drivers reusing DT properties that have no reason whatsoever
to exist in ACPI world.

So, to make this clear, the _DSD usage must be documented and there
has to be a way to define the related bindings in ACPI world so that
driver code can be reviewed accordingly.

Lorenzo

> Graeme
> 
> > Lorenzo
> > 
> > > Reviewed-by: Graeme Gregory <graeme.gregory at linaro.org>
> > > 
> > > Thanks
> > > 
> > > > ---
> > > >  drivers/net/ethernet/smsc/smsc911x.c | 48 +++++++++++++++++-------------------
> > > >  1 file changed, 22 insertions(+), 26 deletions(-)
> > > > 
> > > > diff --git a/drivers/net/ethernet/smsc/smsc911x.c b/drivers/net/ethernet/smsc/smsc911x.c
> > > > index 959aeea..0f21aa3 100644
> > > > --- a/drivers/net/ethernet/smsc/smsc911x.c
> > > > +++ b/drivers/net/ethernet/smsc/smsc911x.c
> > > > @@ -59,7 +59,9 @@
> > > >  #include <linux/of_device.h>
> > > >  #include <linux/of_gpio.h>
> > > >  #include <linux/of_net.h>
> > > > +#include <linux/acpi.h>
> > > >  #include <linux/pm_runtime.h>
> > > > +#include <linux/property.h>
> > > >  
> > > >  #include "smsc911x.h"
> > > >  
> > > > @@ -2362,59 +2364,46 @@ static const struct smsc911x_ops shifted_smsc911x_ops = {
> > > >  	.tx_writefifo = smsc911x_tx_writefifo_shift,
> > > >  };
> > > >  
> > > > -#ifdef CONFIG_OF
> > > > -static int smsc911x_probe_config_dt(struct smsc911x_platform_config *config,
> > > > -				    struct device_node *np)
> > > > +static int smsc911x_probe_config(struct smsc911x_platform_config *config,
> > > > +				 struct device *dev)
> > > >  {
> > > > -	const char *mac;
> > > >  	u32 width = 0;
> > > >  
> > > > -	if (!np)
> > > > +	if (!dev)
> > > >  		return -ENODEV;
> > > >  
> > > > -	config->phy_interface = of_get_phy_mode(np);
> > > > +	config->phy_interface = device_get_phy_mode(dev);
> > > >  
> > > > -	mac = of_get_mac_address(np);
> > > > -	if (mac)
> > > > -		memcpy(config->mac, mac, ETH_ALEN);
> > > > +	device_get_mac_address(dev, config->mac, ETH_ALEN);
> > > >  
> > > > -	of_property_read_u32(np, "reg-shift", &config->shift);
> > > > +	device_property_read_u32(dev, "reg-shift", &config->shift);
> > > >  
> > > > -	of_property_read_u32(np, "reg-io-width", &width);
> > > > +	device_property_read_u32(dev, "reg-io-width", &width);
> > > >  	if (width == 4)
> > > >  		config->flags |= SMSC911X_USE_32BIT;
> > > >  	else
> > > >  		config->flags |= SMSC911X_USE_16BIT;
> > > >  
> > > > -	if (of_get_property(np, "smsc,irq-active-high", NULL))
> > > > +	if (device_property_present(dev, "smsc,irq-active-high"))
> > > >  		config->irq_polarity = SMSC911X_IRQ_POLARITY_ACTIVE_HIGH;
> > > >  
> > > > -	if (of_get_property(np, "smsc,irq-push-pull", NULL))
> > > > +	if (device_property_present(dev, "smsc,irq-push-pull"))
> > > >  		config->irq_type = SMSC911X_IRQ_TYPE_PUSH_PULL;
> > > >  
> > > > -	if (of_get_property(np, "smsc,force-internal-phy", NULL))
> > > > +	if (device_property_present(dev, "smsc,force-internal-phy"))
> > > >  		config->flags |= SMSC911X_FORCE_INTERNAL_PHY;
> > > >  
> > > > -	if (of_get_property(np, "smsc,force-external-phy", NULL))
> > > > +	if (device_property_present(dev, "smsc,force-external-phy"))
> > > >  		config->flags |= SMSC911X_FORCE_EXTERNAL_PHY;
> > > >  
> > > > -	if (of_get_property(np, "smsc,save-mac-address", NULL))
> > > > +	if (device_property_present(dev, "smsc,save-mac-address"))
> > > >  		config->flags |= SMSC911X_SAVE_MAC_ADDRESS;
> > > >  
> > > >  	return 0;
> > > >  }
> > > > -#else
> > > > -static inline int smsc911x_probe_config_dt(
> > > > -				struct smsc911x_platform_config *config,
> > > > -				struct device_node *np)
> > > > -{
> > > > -	return -ENODEV;
> > > > -}
> > > > -#endif /* CONFIG_OF */
> > > >  
> > > >  static int smsc911x_drv_probe(struct platform_device *pdev)
> > > >  {
> > > > -	struct device_node *np = pdev->dev.of_node;
> > > >  	struct net_device *dev;
> > > >  	struct smsc911x_data *pdata;
> > > >  	struct smsc911x_platform_config *config = dev_get_platdata(&pdev->dev);
> > > > @@ -2478,7 +2467,7 @@ static int smsc911x_drv_probe(struct platform_device *pdev)
> > > >  		goto out_disable_resources;
> > > >  	}
> > > >  
> > > > -	retval = smsc911x_probe_config_dt(&pdata->config, np);
> > > > +	retval = smsc911x_probe_config(&pdata->config, &pdev->dev);
> > > >  	if (retval && config) {
> > > >  		/* copy config parameters across to pdata */
> > > >  		memcpy(&pdata->config, config, sizeof(pdata->config));
> > > > @@ -2654,6 +2643,12 @@ static const struct of_device_id smsc911x_dt_ids[] = {
> > > >  MODULE_DEVICE_TABLE(of, smsc911x_dt_ids);
> > > >  #endif
> > > >  
> > > > +static const struct acpi_device_id smsc911x_acpi_match[] = {
> > > > +	{ "ARMH9118", 0 },
> > > > +	{ }
> > > > +};
> > > > +MODULE_DEVICE_TABLE(acpi, smsc911x_acpi_match);
> > > > +
> > > >  static struct platform_driver smsc911x_driver = {
> > > >  	.probe = smsc911x_drv_probe,
> > > >  	.remove = smsc911x_drv_remove,
> > > > @@ -2661,6 +2656,7 @@ static struct platform_driver smsc911x_driver = {
> > > >  		.name	= SMSC_CHIPNAME,
> > > >  		.pm	= SMSC911X_PM_OPS,
> > > >  		.of_match_table = of_match_ptr(smsc911x_dt_ids),
> > > > +		.acpi_match_table = ACPI_PTR(smsc911x_acpi_match),
> > > >  	},
> > > >  };
> > > >  
> > > > -- 
> > > > 2.4.3
> > > > 
> > > > 
> > > > 
> > > > _______________________________________________
> > > > linux-arm-kernel mailing list
> > > > linux-arm-kernel at lists.infradead.org
> > > > http://lists.infradead.org/mailman/listinfo/linux-arm-kernel
> > > 
> > > _______________________________________________
> > > linux-arm-kernel mailing list
> > > linux-arm-kernel at lists.infradead.org
> > > http://lists.infradead.org/mailman/listinfo/linux-arm-kernel
> > > 
> > 
> > _______________________________________________
> > linux-arm-kernel mailing list
> > linux-arm-kernel at lists.infradead.org
> > http://lists.infradead.org/mailman/listinfo/linux-arm-kernel
> 


From grygorii.strashko at ti.com  Thu Aug 13 03:31:04 2015
From: grygorii.strashko at ti.com (Grygorii Strashko)
Date: Thu, 13 Aug 2015 13:31:04 +0300
Subject: [PATCH v2 2/6] genirq: fix irqchip_set_wake_parent if
 IRQCHIP_SKIP_SET_WAKE
In-Reply-To: <55CC6AFF.8060400@arm.com>
References: <1439401562-28874-1-git-send-email-grygorii.strashko@ti.com>
 <1439401562-28874-3-git-send-email-grygorii.strashko@ti.com>
 <55CC6AFF.8060400@arm.com>
Message-ID: <55CC71E8.80604@ti.com>

On 08/13/2015 01:01 PM, Marc Zyngier wrote:
> On 12/08/15 18:45, Grygorii Strashko wrote:
>> The irqchip_set_wake_parent should not fail if IRQ chip
>> specifies IRQCHIP_SKIP_SET_WAKE. Otherwise, IRQ wakeup
>> configuration can't be propagated properly through IRQ
>> domains hierarchy.
>>
>> In case of TI OMAP DRA7 the issue reproduced with following
>> configuration:
>> ARM GIC<-OMAP wakeupgen<-TI CBAR<-GPIO<-GPIO pcf857x<-gpio_key
>>
>> gpio_key is wakeup source
>>
>> Failure is reproduced during suspend/resume to RAM:
>> suspend:
>>   - gpio_keys_suspend
>>     enable_irq_wake
>>       + pcf857x_irq_set_wake
>>         + omap_gpio_wake_enable
>>           + TI CBAR irq_chip_set_wake_parent
>>             + OMAP wakeupgen has no .irq_set_wake()
>
> Most importantly, wakeupgen has IRQCHIP_SKIP_SET_WAKE set.
>
>>             and -ENOSYS will be returned
>>
>> resume:
>>   - gpio_keys_resume
>>     + disable_irq_wake
>>       + irq_set_irq_wake
>>         + WARN(1, "Unbalanced IRQ %d wake disable\n", irq);
>>
>> Fixes: 08b55e2a9208 ('genirq: Add irqchip_set_wake_parent')
>> Signed-off-by: Grygorii Strashko <grygorii.strashko at ti.com>
>> ---
>>   kernel/irq/chip.c | 4 ++++
>>   1 file changed, 4 insertions(+)
>>
>> diff --git a/kernel/irq/chip.c b/kernel/irq/chip.c
>> index 6de638b..bdb1b9d 100644
>> --- a/kernel/irq/chip.c
>> +++ b/kernel/irq/chip.c
>> @@ -1024,6 +1024,10 @@ int irq_chip_set_vcpu_affinity_parent(struct irq_data *data, void *vcpu_info)
>>   int irq_chip_set_wake_parent(struct irq_data *data, unsigned int on)
>>   {
>>   	data = data->parent_data;
>> +
>> +	if (irq_data_get_irq_chip(data)->flags & IRQCHIP_SKIP_SET_WAKE)
>> +		return 0;
>> +
>>   	if (data->chip->irq_set_wake)
>>   		return data->chip->irq_set_wake(data, on);
>>
>>
>
> We have a more general issue with chip flags, and how they combine
> within a stack of irqchips.

Indeed. Problem looks similar to IRQCHIP_MASK_ON_SUSPEND flag usage.

>
> What if you remove the irq_chip_set_wake_parent from the crossbar
> driver, and instead set IRQCHIP_SKIP_SET_WAKE?

I've thought about this and it should work for me.
One question - what if crossbar will be not the last one in
IRQ domains hierarchy?


-- 
regards,
-grygorii


From sudeep.holla at arm.com  Thu Aug 13 03:33:21 2015
From: sudeep.holla at arm.com (Sudeep Holla)
Date: Thu, 13 Aug 2015 11:33:21 +0100
Subject: [PATCH v2 2/6] genirq: fix irqchip_set_wake_parent if
 IRQCHIP_SKIP_SET_WAKE
In-Reply-To: <55CC68A0.40101@ti.com>
References: <1439401562-28874-1-git-send-email-grygorii.strashko@ti.com>
 <1439401562-28874-3-git-send-email-grygorii.strashko@ti.com>
 <55CC5B2F.7060503@arm.com> <55CC68A0.40101@ti.com>
Message-ID: <55CC7271.5040202@arm.com>



On 13/08/15 10:51, Grygorii Strashko wrote:
> On 08/13/2015 11:54 AM, Sudeep Holla wrote:
>>
>>
>> On 12/08/15 18:45, Grygorii Strashko wrote:

[...]

>>> diff --git a/kernel/irq/chip.c b/kernel/irq/chip.c
>>> index 6de638b..bdb1b9d 100644
>>> --- a/kernel/irq/chip.c
>>> +++ b/kernel/irq/chip.c
>>> @@ -1024,6 +1024,10 @@ int irq_chip_set_vcpu_affinity_parent(struct
>>> irq_data *data, void *vcpu_info)
>>>    int irq_chip_set_wake_parent(struct irq_data *data, unsigned int on)
>>>    {
>>>        data = data->parent_data;
>>> +
>>> +    if (irq_data_get_irq_chip(data)->flags & IRQCHIP_SKIP_SET_WAKE)
>>> +        return 0;
>>> +
>>
>> [Nit] I think the irq core can access data->chip directly. Either way,
>> it's better to be consistent, the statement following doesn't use helper
>> function.
>
> thanks. I'll change it to:
> 	if (data->chip->flags & IRQCHIP_SKIP_SET_WAKE)
> 		return 0;
>
>>
>> Otherwise looks good to me.
>
> Does it means that I can add your Reviewed-by: with above change?
>

Yes you can.

Regards,
Sudeep


From jassisinghbrar at gmail.com  Thu Aug 13 03:41:38 2015
From: jassisinghbrar at gmail.com (Jassi Brar)
Date: Thu, 13 Aug 2015 16:11:38 +0530
Subject: [PATCH v2 5/6] mailbox: Add generic mechanism for testing Mailbox
 Controllers
In-Reply-To: <20150813102335.GC8782@x1>
References: <1437990272-23111-1-git-send-email-lee.jones@linaro.org>
 <1437990272-23111-6-git-send-email-lee.jones@linaro.org>
 <CABb+yY20nQbiEEZeRvWTMUsJ2qgwRn8CrWvnFDSB-b1dgVaAuw@mail.gmail.com>
 <20150812102328.GD18282@x1>
 <CABb+yY0A74Vy3-KOvj0URU_4zb2FAC7Yp3gmEwnFaBrD0mzt0w@mail.gmail.com>
 <20150813091914.GB8782@x1>
 <CABb+yY0cgbtM68-E_Xqgh5O6GRLXESYTLa5WcAwUBoVL3ufrxA@mail.gmail.com>
 <20150813102335.GC8782@x1>
Message-ID: <CABb+yY3z7p97eOhncQ2i+g6yoYGfDgSN9BDPKmiDaVLa3oPocA@mail.gmail.com>

On Thu, Aug 13, 2015 at 3:53 PM, Lee Jones <lee.jones at linaro.org> wrote:
> On Thu, 13 Aug 2015, Jassi Brar wrote:
>
>> On Thu, Aug 13, 2015 at 2:49 PM, Lee Jones <lee.jones at linaro.org> wrote:
>> > On Thu, 13 Aug 2015, Jassi Brar wrote:
>>
>> >> >> > +
>> >> >> > +static void mbox_test_prepare_message(struct mbox_client *client, void *message)
>> >> >> > +{
>> >> >> > +       struct mbox_test_device *tdev = dev_get_drvdata(client->dev);
>> >> >> > +
>> >> >> > +       if (tdev->mmio)
>> >> >> > +               memcpy(tdev->mmio, message, MBOX_MAX_MSG_LEN);
>> >> >> >
>> >> >> This is unlikely to work. Those platforms that need to send a 2 part
>> >> >> message, they do :
>> >> >> (a) Signal/Command/Target code via some controller register (via
>> >> >> mbox_send_message).
>> >> >> (b) Setup the payload in Shared-Memory (via tx_prepare).
>> >> >>
>> >> >> This test driver assumes both are the same. I think you have to
>> >> >> declare something like
>> >> >
>> >> > This driver assumes that the framework will call client->tx_prepare()
>> >> > first, which satisfies (b).  It then assumes controller->send_data()
>> >> > will be invoked, which will send the platform specific
>> >> > signal/command/target code, which then satisfies (a).
>> >> >
>> >> Yeah, but what would be that code? Who provides that?
>> >>
>> >> > In what way does it assume they are the same?
>> >> >
>> >> notice the 'message' pointer in
>> >> mbox_send_message(tdev->tx_channel, message);
>> >>     and
>> >> memcpy(tdev->mmio, message, MBOX_MAX_MSG_LEN);
>> >>
>> >> >> struct mbox_test_message { /* same for TX and RX */
>> >> >>           unsigned sig_len;
>> >> >>           void *signal;               /* rx/tx via mailbox api */
>> >> >>           unsigned pl_len;
>> >> >>           void *payload;           /* rx/tx via shared-memory */
>> >> >> };
>> >> >
>> >> > How do you think this should be set and use these?
>> >> >
>> >> The userspace would want to specify the command code (32bits or not)
>> >> that would be passed via the fifo/register of the controller. So we
>> >> need signal[]
>> >>
>> >> The data to be passed via share-memory could be provided by userspace
>> >> via the payload[] array.
>> >
>> > Okay, so would the solution be two userspace files 'signal' and
>> > 'message', so in the case of a client specified signal we can write it
>> > into there first.
>> >
>> > echo 255  > signal
>> > echo test > message
>> >
>> > ... or in the case where no signal is required, or the controller
>> > driver taking care of it, we just don't write anything to signal?
>> >
>> file_operations.write() should parse signal and message, coming from
>> userspace, into a local structure before routing them via
>> mbox_send_message and tx_prepare respectively.
>
> Okay.  So before I code this up we should agree on syntax.
>
> How would you like to represent the break between signal and message?
> Obviously ' ' would be a bad idea, as some clients may want to send
> messages with white space contained.  How about '\t' or '\n'?
>
Yeah, I am not a fan of markers and flags either.

Maybe we should share with userspace
  struct mbox_test_message { /* same for TX and RX */
           unsigned sig_len;
           void __user *signal;        /* rx/tx via mailbox api */
           unsigned pl_len;
           void __user *payload;    /* rx/tx via shared-memory */
  };

First copy_from_user the structure of length sizof(struct
mbox_test_message) and then copy_from_user length sig_len and pl_len
from signal[] and payload[] respectively (usually ioctls would carry
such data).


From olof at lixom.net  Thu Aug 13 02:57:11 2015
From: olof at lixom.net (Olof Johansson)
Date: Thu, 13 Aug 2015 11:57:11 +0200
Subject: [PATCH] ARM: Feroceon: use of_iomap() to map register base
In-Reply-To: <1439035899-1783-1-git-send-email-yamada.masahiro@socionext.com>
References: <1439035899-1783-1-git-send-email-yamada.masahiro@socionext.com>
Message-ID: <20150813095711.GJ30160@localhost>

On Sat, Aug 08, 2015 at 09:11:39PM +0900, Masahiro Yamada wrote:
> The sequence of of_address_to_resource() and ioremap() can be
> replaced with of_iomap().
> 
> Signed-off-by: Masahiro Yamada <yamada.masahiro at socionext.com>

Acked-by: Olof Johansson <olof at lixom.net>

Please submit this to Russell's patch tracker, he's usually the one who merges
patches to arch/arm/mm/*.


-Olof


From olof at lixom.net  Thu Aug 13 02:58:41 2015
From: olof at lixom.net (Olof Johansson)
Date: Thu, 13 Aug 2015 11:58:41 +0200
Subject: [GIT PULL] at91: dt for 4.3 #2
In-Reply-To: <20150807154544.GA18934@piout.net>
References: <20150807154544.GA18934@piout.net>
Message-ID: <20150813095841.GK30160@localhost>

On Fri, Aug 07, 2015 at 05:45:44PM +0200, Alexandre Belloni wrote:
> 
> Arnd, Olof, Kevin,
> 
> This is the second batch of DT changes for 4.3.
> It is mainly some preparation to support properly getting the slow clock
> from each driver so that the dtsis are ready when the driver change
> lands in each subsystem.
> 
> It also adds support for the lcd controller on at91sam9x5 and
> at91sam9n12. The driver changes have been submitted but didn't yet land
> in the drm and mfd subsystem however, I don't expect any issue getting
> those in.
> 
> Thanks, best regards,
> 
> The following changes since commit 22b5a0f7bc07ac4b4e4aab9a7f8cf2521819c1c4:
> 
>   ARM: at91/dt: add minimal sama5d2 Xplained board (2015-07-30 18:44:44 +0200)
> 
> are available in the git repository at:
> 
>   git://git.kernel.org/pub/scm/linux/kernel/git/abelloni/linux.git tags/at91-ab-dt2
> 
> for you to fetch changes up to 761c5867ef031fae244d030bc17c93f5a3df106f:
> 
>   ARM: at91/dt: sama5d2: use slow clock where necessary (2015-08-07 17:33:54 +0200)

Merged, thanks!


-Olof



From olof at lixom.net  Thu Aug 13 03:02:51 2015
From: olof at lixom.net (Olof Johansson)
Date: Thu, 13 Aug 2015 12:02:51 +0200
Subject: [GIT PULL] ARM: mvebu: soc changes for v4.3 #2
In-Reply-To: <55C4D665.8060702@free-electrons.com>
References: <55C4D665.8060702@free-electrons.com>
Message-ID: <20150813100251.GM30160@localhost>

Hi,

On Fri, Aug 07, 2015 at 06:01:41PM +0200, Gregory CLEMENT wrote:
> Hi,
> 
> Here is the second pull request for soc for mvebu for v4.3
> 
> Gregory
> 
> The following changes since commit 482d638f98cc626bf01d4c9f6d6d35fc77d630c8:
> 
>   ARM: mvebu: Warn about the wake-up sources not taken into account in suspend (2015-07-28 11:40:47 +0200)
> 
> are available in the git repository at:
> 
>   git://git.infradead.org/linux-mvebu.git tags/mvebu-soc-4.3-2
> 
> for you to fetch changes up to 44e259ac909f3b41786cf732a44b5cf8444e098a:
> 
>   ARM: dove: create a proper PMU driver for power domains, PMU IRQs and resets (2015-08-05 18:36:49 +0200)

I've merged this into next/drivers (which now has a dependency on next/soc
since your branch was based on previous soc contents, but that's OK).

Thanks,

-Olof



From olof at lixom.net  Thu Aug 13 03:09:38 2015
From: olof at lixom.net (Olof Johansson)
Date: Thu, 13 Aug 2015 12:09:38 +0200
Subject: [GIT PULL] at91: defconfig for 4.3 #2
In-Reply-To: <20150807162754.GA20169@piout.net>
References: <20150807162754.GA20169@piout.net>
Message-ID: <20150813100938.GN30160@localhost>

On Fri, Aug 07, 2015 at 06:27:54PM +0200, Alexandre Belloni wrote:
> Arnd, Olof, Kevin,
> 
> A little defconfig update. That will probably be all for this cycle.
> 
> Thanks, bye,
> 
> 
> The following changes since commit eff7f41572a645bf14a96a6f844be4f1c88cd9dd:
> 
>   ARM: at91: at91_dt_defconfig: enable ISI and ov2640 support (2015-07-30 14:17:31 +0200)
> 
> are available in the git repository at:
> 
>   git://git.kernel.org/pub/scm/linux/kernel/git/abelloni/linux.git tags/at91-ab-defconfig2
> 
> for you to fetch changes up to ea7bf603fd494391acc1f42acbfc34260b965c44:
> 
>   ARM: at91/defconfig: at91_dt: remove ARM_AT91_ETHER (2015-08-07 12:07:50 +0200)

Nicolas had sent me one patch which you've also included here but it's not in
the pull request ("enable ISI and ov2640 support"). That caused a conflict
here, so to avoid having the patch in the tree twice I instead also directly
applied your patches from this branch instead of merging.

Sorry about that, it started due to Nicolas sending the discrete patch to us.
So it seems like we'll apply at91 defconfig updates directly this release, in
case there are any more. No big deal I hope. :)


-Olof



From olof at lixom.net  Thu Aug 13 03:12:29 2015
From: olof at lixom.net (Olof Johansson)
Date: Thu, 13 Aug 2015 12:12:29 +0200
Subject: [PATCH] ARM: UniPhier: drop v7_invalidate_l1 call at secondary
 entry
In-Reply-To: <1439036024-1933-1-git-send-email-yamada.masahiro@socionext.com>
References: <1439036024-1933-1-git-send-email-yamada.masahiro@socionext.com>
Message-ID: <20150813101229.GQ30160@localhost>

On Sat, Aug 08, 2015 at 09:13:44PM +0900, Masahiro Yamada wrote:
> This is unnecessary since commit 02b4e2756e01 ("ARM: v7 setup
> function should invalidate L1 cache").
> 
> Signed-off-by: Masahiro Yamada <yamada.masahiro at socionext.com>
> ---

Applied, thanks.


-Olof


From olof at lixom.net  Thu Aug 13 03:00:16 2015
From: olof at lixom.net (Olof Johansson)
Date: Thu, 13 Aug 2015 12:00:16 +0200
Subject: [GIT PULL] ARM: mvebu: dt changes for v4.3 #3
In-Reply-To: <55C4D663.4050508@free-electrons.com>
References: <55C4D663.4050508@free-electrons.com>
Message-ID: <20150813100016.GL30160@localhost>

On Fri, Aug 07, 2015 at 06:01:39PM +0200, Gregory CLEMENT wrote:
> Hi,
> 
> Here is the third  pull request for dt for mvebu for v4.3
> 
> Gregory
> 
> he following changes since commit dc57844a736f10bf3799d63d7c0d0efc29b1ad7d:
> 
>   ARM: dts: orion5x: add buffalo linkstation ls-wtgl (2015-07-25 16:19:20 +0200)
> 
> are available in the git repository at:
> 
>   git://git.infradead.org/linux-mvebu.git tags/mvebu-dt-4.3-3
> 
> for you to fetch changes up to 15979aeeb548e020b6107214f0405be894891a57:
> 
>   ARM: dts: Convert Linkstation Mini to Device Tree (2015-08-06 18:51:29 +0200)

Merged, thanks!


-Olof



From olof at lixom.net  Thu Aug 13 03:14:10 2015
From: olof at lixom.net (Olof Johansson)
Date: Thu, 13 Aug 2015 12:14:10 +0200
Subject: [GIT PULL 1/2] Rockchip soc changes for 4.3, part2
In-Reply-To: <3109032.sS4ICWceDv@diego>
References: <3109032.sS4ICWceDv@diego>
Message-ID: <20150813101410.GR30160@localhost>

On Sat, Aug 08, 2015 at 11:28:07PM +0200, Heiko St?bner wrote:
> Hi Olof, Kevin, Arnd,
> 
> here is round two of soc and devicetree changes for 4.3.
> 
> So if ok, please pull
> 
> Thanks
> Heiko
> 
> 
> The following changes since commit cb8cc37f4d38d96552f2c52deb15e511cdacf906:
> 
>   ARM: rockchip: fix broken build (2015-07-06 11:46:08 +0200)
> 
> are available in the git repository at:
> 
>   git://git.kernel.org/pub/scm/linux/kernel/git/mmind/linux-rockchip.git tags/v4.3-rockchip32-soc2
> 
> for you to fetch changes up to 9bb91ae970dd004393a3d7d09bdcc30dfe2f8693:
> 
>   ARM: rockchip: enable PMU_GPIOINT_WAKEUP_EN when entering shallow suspend (2015-08-06 13:05:14 +0200)

Merged, thanks.


-Olof



From olof at lixom.net  Thu Aug 13 03:15:09 2015
From: olof at lixom.net (Olof Johansson)
Date: Thu, 13 Aug 2015 12:15:09 +0200
Subject: [GIT PULL 2/2] Rockchip devicetree changes for 4.3, part2
In-Reply-To: <1647709.GpuDCKf86R@diego>
References: <3109032.sS4ICWceDv@diego>
 <1647709.GpuDCKf86R@diego>
Message-ID: <20150813101509.GS30160@localhost>

On Sat, Aug 08, 2015 at 11:28:54PM +0200, Heiko St?bner wrote:
> The following changes since commit 4863dcd394019b542ac968870cba734d27e992e0:
> 
>   ARM: dts: rockchip: add rk3288 arm-pmu irq affinity (2015-07-16 22:22:47 +0200)
> 
> are available in the git repository at:
> 
>   git://git.kernel.org/pub/scm/linux/kernel/git/mmind/linux-rockchip.git tags/v4.3-rockchip32-dts2
> 
> for you to fetch changes up to 378abcdf3297613f6712343ce3a79b7d6abdf955:
> 
>   ARM: dts: rockchip: add veyron-minnie board (2015-08-08 12:31:27 +0200)
> 
> ----------------------------------------------------------------
> Some more devicetree changes, including usbphy support for the
> Cortex-A9 SoCs and actually enabling usb on the rk3066-marsboard,
> Two more veyron-devices - namely Speedy and Minnie and a fix for
> the tsadc.
> One slightly more interesting fix is the blocking of the last
> 16MB of memory on 4GB rk3288 devices. The rk3288 cannot use this
> area for dma operations, so things like the mmc or usb controllers
> regularly fail when trying to read data. This solution mimicks the
> solution from the ChromeOS kernel, who also do not seem to have
> found a better solution yet. Here it only moves to the devicetree.
> As this issue is also present on the arm64 rk3368, any future
> better solution to this problem would need to describe this in
> the devicetree as well and could then remove this block.

Merged, thanks!


-Olof



From olof at lixom.net  Thu Aug 13 03:20:22 2015
From: olof at lixom.net (Olof Johansson)
Date: Thu, 13 Aug 2015 12:20:22 +0200
Subject: [GIT PULL] SoCFPGA DTS updates for v4.3, part 2
In-Reply-To: <1439176556-30367-1-git-send-email-dinh.linux@gmail.com>
References: <1439176556-30367-1-git-send-email-dinh.linux@gmail.com>
Message-ID: <20150813102022.GU30160@localhost>

On Sun, Aug 09, 2015 at 10:15:56PM -0500, dinh.linux at gmail.com wrote:
> Hi Arnd, Kevin, and Olof:
> 
> This is a 2nd pull-request for v4.3. Please consider pulling in this patches.
> 
> Thanks,
> Dinh
> 
> 
> The following changes since commit d770e558e21961ad6cfdf0ff7df0eb5d7d4f0754:
> 
>   Linux 4.2-rc1 (2015-07-05 11:01:52 -0700)
> 
> are available in the git repository at:
> 
>   git://git.kernel.org/pub/scm/linux/kernel/git/dinguyen/linux.git socfpga_dts_for_v4.3_part_2
> 
> for you to fetch changes up to 6855e5b7090330add9521d8947017875d5f4f88e:
> 
>   ARM: socfpga: dts: Add resets for EMACs on Arria10 (2015-08-09 21:58:58 -0500)

Merged, thanks.


-Olof



From olof at lixom.net  Thu Aug 13 03:19:04 2015
From: olof at lixom.net (Olof Johansson)
Date: Thu, 13 Aug 2015 12:19:04 +0200
Subject: [GIT PULL] Samsung mach fixes for 4.2
In-Reply-To: <040901d0d310$e233fde0$a69bf9a0$@kernel.org>
References: <1439171530-971-1-git-send-email-k.kozlowski@samsung.com>
 <040901d0d310$e233fde0$a69bf9a0$@kernel.org>
Message-ID: <20150813101904.GT30160@localhost>

On Mon, Aug 10, 2015 at 11:04:25AM +0900, Kukjin Kim wrote:
> Hi arm-soc guys,
> 
> Can you please pull this into arm-soc fixes for v4.2 directly?
> I don't have other samsung fixes in my tree at this moment.
> 
> Thanks,
> Kukjin
> 
> Krzysztof Kozlowski wrote:
> > 
> > Dear Kukjin,
> > 
> > Please find latest two fixes for v4.2 cycle. You can find more detailed
> > description with the tag.
> > 
> > Best regards,
> > Krzysztof
> > 
> > 
> > The following changes since commit d770e558e21961ad6cfdf0ff7df0eb5d7d4f0754:
> > 
> >   Linux 4.2-rc1 (2015-07-05 11:01:52 -0700)
> > 
> > are available in the git repository at:
> > 
> >   https://github.com/krzk/linux.git tags/samsung-mach-fixes-4.2
> > 
> > for you to fetch changes up to 3e9f798784b30293012682021d5a0352f78658b8:
> > 
> >   ARM: EXYNOS: fix double of_node_put() on error path (2015-07-31 10:12:17 +0900)

Merged, thanks.


-Olof



From olof at lixom.net  Thu Aug 13 03:24:34 2015
From: olof at lixom.net (Olof Johansson)
Date: Thu, 13 Aug 2015 12:24:34 +0200
Subject: [GIT PULL] ARM: Couple of Keystone MDIO DTS fixes for 4.2-rc6+
In-Reply-To: <1439177200-32434-1-git-send-email-ssantosh@kernel.org>
References: <1439177200-32434-1-git-send-email-ssantosh@kernel.org>
Message-ID: <20150813102434.GV30160@localhost>

On Sun, Aug 09, 2015 at 08:26:40PM -0700, Santosh Shilimkar wrote:
> ARM-SoC folks,
> 
> Please pull below couple of late fixes for 4.2-rc6+. I know its late
> with rc6 already out but if possible please consider. 
> 
> The following changes since commit f7644cbfcdf03528f0f450f3940c4985b2291f49:
> 
>   Linux 4.2-rc6 (2015-08-09 15:54:30 -0400)
> 
> are available in the git repository at:
> 
>   git://git.kernel.org/pub/scm/linux/kernel/git/ssantosh/linux-keystone.git tags/keystone-dts-late-fixes
> 
> for you to fetch changes up to 6a024079862443b3ec9455931e9219cd5912656d:
> 
>   ARM: dts: keystone: Fix the mdio bindings by moving it to soc specific file (2015-08-09 20:06:27 -0700)

Hi,

Our fixes branch is still at -rc2. Would you mind respinning with an older
base unless there are conflicts?


-Olof


From olof at lixom.net  Thu Aug 13 03:25:11 2015
From: olof at lixom.net (Olof Johansson)
Date: Thu, 13 Aug 2015 12:25:11 +0200
Subject: [GIT PULL] ARM: imx: fixes for 4.2, 3rd round
In-Reply-To: <20150810153542.GA10035@tiger>
References: <20150810153542.GA10035@tiger>
Message-ID: <20150813102511.GW30160@localhost>

On Mon, Aug 10, 2015 at 11:35:42PM +0800, Shawn Guo wrote:
> The following changes since commit e053f96b1a00022b4e2c7ceb7ac0229646626507:
> 
>   ARM: dts: i.MX35: Fix can support. (2015-07-25 11:35:08 +0800)
> 
> are available in the git repository at:
> 
>   git://git.kernel.org/pub/scm/linux/kernel/git/shawnguo/linux.git tags/imx-fixes-4.2-3
> 
> for you to fetch changes up to 1a9fa190956f45c1e58c4d8bfa5ac051691ea590:
> 
>   ARM: imx6: correct i.MX6 PCIe interrupt routing (2015-08-06 16:30:18 +0800)

Merged, thanks.


-Olof


From olof at lixom.net  Thu Aug 13 03:25:56 2015
From: olof at lixom.net (Olof Johansson)
Date: Thu, 13 Aug 2015 12:25:56 +0200
Subject: [PATCH] ARM/fb: ep93xx: switch framebuffer to use modedb only
In-Reply-To: <1439306238-30655-1-git-send-email-linus.walleij@linaro.org>
References: <1439306238-30655-1-git-send-email-linus.walleij@linaro.org>
Message-ID: <20150813102556.GX30160@localhost>

On Tue, Aug 11, 2015 at 05:17:18PM +0200, Linus Walleij wrote:
> All the EP93xx boards exclusively use modedb to look up video
> modes from the command line. Root out the parametrization of
> custom video modes from the platform data and board files
> and simplify the driver.
> 
> Cc: Jean-Christophe Plagniol-Villard <plagnioj at jcrosoft.com>
> Reviewed-by: H Hartley Sweeten <hsweeten at visionengravers.com>
> Acked-by: Tomi Valkeinen <tomi.valkeinen at ti.com>
> Signed-off-by: Linus Walleij <linus.walleij at linaro.org>
> ---
> Hi ARM SoC maintainers, please apply this directly to the
> EP93xx/cleanup branch now that I have Tomi's ACK.

Applied to next/cleanup, thanks.


-Olof



From olof at lixom.net  Thu Aug 13 03:30:56 2015
From: olof at lixom.net (Olof Johansson)
Date: Thu, 13 Aug 2015 12:30:56 +0200
Subject: [GIT PULL] RPi DT changes due for v4.3
In-Reply-To: <20150811160642.GQ18282@x1>
References: <20150811160642.GQ18282@x1>
Message-ID: <20150813103056.GY30160@localhost>

Hi,

On Tue, Aug 11, 2015 at 05:06:42PM +0100, Lee Jones wrote:
> ARM SoC Chaps,
> 
> Please find a couple of simple RPi changes pertaining to Firmware.
> 
> The following changes since commit bc0195aad0daa2ad5b0d76cce22b167bc3435590:
> 
>   Linux 4.2-rc2 (2015-07-12 15:10:30 -0700)
> 
> are available in the git repository at:
> 
>   git://git.kernel.org/pub/scm/linux/kernel/git/rpi/linux-rpi.git tags/rpi-dt-for-armsoc-4.3
> 
> for you to fetch changes up to fd26f8830979de48eb3f1c253eb9d2ee2e468eb6:
> 
>   dt/bindings: Add binding for the Raspberry Pi firmware driver (2015-08-11 16:56:41 +0100)

I've merged this but I'm a little confused about bcm2835 maintainership:
I got a MAINTAINERS update from Florian earlier grouped in a set of
other bcm changes (adding Eric), and now this directly from you.

In general the bcm platforms are quite diverse and we've asked Florian
to be the funnel for all of the new ones, but I don't think we talked
much about 2835 at that time. Should we expect to see merges directly
from you and the other maintainers there or will it go through Florian?

Either way is OK with me, just looking to clarify.


Thanks!

-Olof



From lee.jones at linaro.org  Thu Aug 13 04:00:08 2015
From: lee.jones at linaro.org (Lee Jones)
Date: Thu, 13 Aug 2015 12:00:08 +0100
Subject: [PATCH v2 5/6] mailbox: Add generic mechanism for testing
 Mailbox Controllers
In-Reply-To: <CABb+yY3z7p97eOhncQ2i+g6yoYGfDgSN9BDPKmiDaVLa3oPocA@mail.gmail.com>
References: <1437990272-23111-1-git-send-email-lee.jones@linaro.org>
 <1437990272-23111-6-git-send-email-lee.jones@linaro.org>
 <CABb+yY20nQbiEEZeRvWTMUsJ2qgwRn8CrWvnFDSB-b1dgVaAuw@mail.gmail.com>
 <20150812102328.GD18282@x1>
 <CABb+yY0A74Vy3-KOvj0URU_4zb2FAC7Yp3gmEwnFaBrD0mzt0w@mail.gmail.com>
 <20150813091914.GB8782@x1>
 <CABb+yY0cgbtM68-E_Xqgh5O6GRLXESYTLa5WcAwUBoVL3ufrxA@mail.gmail.com>
 <20150813102335.GC8782@x1>
 <CABb+yY3z7p97eOhncQ2i+g6yoYGfDgSN9BDPKmiDaVLa3oPocA@mail.gmail.com>
Message-ID: <20150813110008.GD8782@x1>

On Thu, 13 Aug 2015, Jassi Brar wrote:

> On Thu, Aug 13, 2015 at 3:53 PM, Lee Jones <lee.jones at linaro.org> wrote:
> > On Thu, 13 Aug 2015, Jassi Brar wrote:
> >
> >> On Thu, Aug 13, 2015 at 2:49 PM, Lee Jones <lee.jones at linaro.org> wrote:
> >> > On Thu, 13 Aug 2015, Jassi Brar wrote:
> >>
> >> >> >> > +
> >> >> >> > +static void mbox_test_prepare_message(struct mbox_client *client, void *message)
> >> >> >> > +{
> >> >> >> > +       struct mbox_test_device *tdev = dev_get_drvdata(client->dev);
> >> >> >> > +
> >> >> >> > +       if (tdev->mmio)
> >> >> >> > +               memcpy(tdev->mmio, message, MBOX_MAX_MSG_LEN);
> >> >> >> >
> >> >> >> This is unlikely to work. Those platforms that need to send a 2 part
> >> >> >> message, they do :
> >> >> >> (a) Signal/Command/Target code via some controller register (via
> >> >> >> mbox_send_message).
> >> >> >> (b) Setup the payload in Shared-Memory (via tx_prepare).
> >> >> >>
> >> >> >> This test driver assumes both are the same. I think you have to
> >> >> >> declare something like
> >> >> >
> >> >> > This driver assumes that the framework will call client->tx_prepare()
> >> >> > first, which satisfies (b).  It then assumes controller->send_data()
> >> >> > will be invoked, which will send the platform specific
> >> >> > signal/command/target code, which then satisfies (a).
> >> >> >
> >> >> Yeah, but what would be that code? Who provides that?
> >> >>
> >> >> > In what way does it assume they are the same?
> >> >> >
> >> >> notice the 'message' pointer in
> >> >> mbox_send_message(tdev->tx_channel, message);
> >> >>     and
> >> >> memcpy(tdev->mmio, message, MBOX_MAX_MSG_LEN);
> >> >>
> >> >> >> struct mbox_test_message { /* same for TX and RX */
> >> >> >>           unsigned sig_len;
> >> >> >>           void *signal;               /* rx/tx via mailbox api */
> >> >> >>           unsigned pl_len;
> >> >> >>           void *payload;           /* rx/tx via shared-memory */
> >> >> >> };
> >> >> >
> >> >> > How do you think this should be set and use these?
> >> >> >
> >> >> The userspace would want to specify the command code (32bits or not)
> >> >> that would be passed via the fifo/register of the controller. So we
> >> >> need signal[]
> >> >>
> >> >> The data to be passed via share-memory could be provided by userspace
> >> >> via the payload[] array.
> >> >
> >> > Okay, so would the solution be two userspace files 'signal' and
> >> > 'message', so in the case of a client specified signal we can write it
> >> > into there first.
> >> >
> >> > echo 255  > signal
> >> > echo test > message
> >> >
> >> > ... or in the case where no signal is required, or the controller
> >> > driver taking care of it, we just don't write anything to signal?
> >> >
> >> file_operations.write() should parse signal and message, coming from
> >> userspace, into a local structure before routing them via
> >> mbox_send_message and tx_prepare respectively.
> >
> > Okay.  So before I code this up we should agree on syntax.
> >
> > How would you like to represent the break between signal and message?
> > Obviously ' ' would be a bad idea, as some clients may want to send
> > messages with white space contained.  How about '\t' or '\n'?
> >
> Yeah, I am not a fan of markers and flags either.
> 
> Maybe we should share with userspace
>   struct mbox_test_message { /* same for TX and RX */
>            unsigned sig_len;
>            void __user *signal;        /* rx/tx via mailbox api */
>            unsigned pl_len;
>            void __user *payload;    /* rx/tx via shared-memory */
>   };
> 
> First copy_from_user the structure of length sizof(struct
> mbox_test_message) and then copy_from_user length sig_len and pl_len
> from signal[] and payload[] respectively (usually ioctls would carry
> such data).

Simplicity and ease of use should be the goals here.  Testers should
not have to write applications to use this driver.  Can we come up
with a simple/effective method that uses SYSFS/DEBUGFS please?

The easiest way I can think of which avoids markers/separators AND the
requirement for users to have to write applications is to have two
files, 'signal' and 'message' as mentioned before.  Once both are
populated I can get this driver to draft the message appropriately and
fire it off.

-- 
Lee Jones
Linaro STMicroelectronics Landing Team Lead
Linaro.org ? Open source software for ARM SoCs
Follow Linaro: Facebook | Twitter | Blog


From ryabinin.a.a at gmail.com  Thu Aug 13 04:02:26 2015
From: ryabinin.a.a at gmail.com (Andrey Ryabinin)
Date: Thu, 13 Aug 2015 14:02:26 +0300
Subject: [PATCH 0/2] x86/KASAN updates for 4.3
In-Reply-To: <20150813090119.GA10280@arm.com>
References: <1439444244-26057-1-git-send-email-ryabinin.a.a@gmail.com>
 <20150813065040.GA17983@gmail.com>
 <20150813081641.GA14402@gmail.com> <20150813090119.GA10280@arm.com>
Message-ID: <CAPAsAGxk2+v5VG77cOHAThsXyWx-_UJ1XVeJProaa0gQWH5jvA@mail.gmail.com>

2015-08-13 12:01 GMT+03:00 Will Deacon <will.deacon at arm.com>:
> Hi Ingo,
>
> On Thu, Aug 13, 2015 at 09:16:41AM +0100, Ingo Molnar wrote:
>> * Ingo Molnar <mingo at kernel.org> wrote:
>> > * Andrey Ryabinin <ryabinin.a.a at gmail.com> wrote:
>> >
>> > > These 2 patches taken from v5 'KASAN for arm64' series.
>> > > The only change is updated changelog in second patch.
>> > >
>> > > I hope this is not too late to queue these for 4.3,
>> > > as this allow us to merge arm64/KASAN patches in v4.4
>> > > through arm64 tree.
>> > >
>> > > Andrey Ryabinin (2):
>> > >   x86/kasan: define KASAN_SHADOW_OFFSET per architecture
>> > >   x86/kasan, mm: introduce generic kasan_populate_zero_shadow()
>> > >
>> > >  arch/x86/include/asm/kasan.h |   3 +
>> > >  arch/x86/mm/kasan_init_64.c  | 123 ++--------------------------------
>> > >  include/linux/kasan.h        |  10 ++-
>> > >  mm/kasan/Makefile            |   2 +-
>> > >  mm/kasan/kasan_init.c        | 152 +++++++++++++++++++++++++++++++++++++++++++
>> > >  5 files changed, 170 insertions(+), 120 deletions(-)
>> > >  create mode 100644 mm/kasan/kasan_init.c
>> >
>> > It's absolutely too late in the -rc cycle for v4.3!
>>
>> Stupid me, I have read 'v4.2' ...
>>
>> So yes, it's still good for v4.3, the development window is still open.
>>
>> The rest still stands:
>>
>> > I can create a stable topic tree for it, tip:mm/kasan or so, which arm64 could
>> > pull and base its own ARM specific work on, if that's OK with everyone.

OK with me.


> Yes please, works for me! If we're targetting 4.3, then please can you base
> on 4.2-rc4, as that's what our current arm64 queue is using?
>

Does this mean that we are targeting arm64 part for 4.3 too?


> Cheers,
>
> Will


From guohanjun at huawei.com  Thu Aug 13 04:02:17 2015
From: guohanjun at huawei.com (Hanjun Guo)
Date: Thu, 13 Aug 2015 19:02:17 +0800
Subject: [PATCH 2/3] Display a DMA error message
In-Reply-To: <1439416290-21228-3-git-send-email-jeremy.linton@arm.com>
References: <1439416290-21228-1-git-send-email-jeremy.linton@arm.com>
 <1439416290-21228-3-git-send-email-jeremy.linton@arm.com>
Message-ID: <55CC7939.7020800@huawei.com>

On 2015/8/13 5:51, Jeremy Linton wrote:
> If the ehci driver fails to configure the dma settings then display
> a dev error instead of simply failing. This is triggered in an
> ACPI world if the user fails to set the _CCA on the device.
>
> Signed-off-by: Jeremy Linton <jeremy.linton at arm.com>
> ---
>  drivers/usb/host/ehci-platform.c | 4 +++-
>  1 file changed, 3 insertions(+), 1 deletion(-)
>
> diff --git a/drivers/usb/host/ehci-platform.c b/drivers/usb/host/ehci-platform.c
> index 2593def..82e396f 100644
> --- a/drivers/usb/host/ehci-platform.c
> +++ b/drivers/usb/host/ehci-platform.c
> @@ -162,8 +162,10 @@ static int ehci_platform_probe(struct platform_device *dev)
>  
>  	err = dma_coerce_mask_and_coherent(&dev->dev,
>  		pdata->dma_mask_64 ? DMA_BIT_MASK(64) : DMA_BIT_MASK(32));
> -	if (err)
> +	if (err) {
> +		dev_err(&dev->dev, "Error: DMA setup failed\n");
>  		return err;
> +	}
>  
>  	irq = platform_get_irq(dev, 0);
>  	if (irq < 0) {

Reviewed-by: Hanjun Guo <hanjun.guo at linaro.org>

Thanks
Hanjun



From sudeep.holla at arm.com  Thu Aug 13 04:04:29 2015
From: sudeep.holla at arm.com (Sudeep Holla)
Date: Thu, 13 Aug 2015 12:04:29 +0100
Subject: [PATCH v2 6/6] irqchip: crossbar: fix irq masking at suspend
In-Reply-To: <55CC6EB8.3050906@ti.com>
References: <1439401562-28874-1-git-send-email-grygorii.strashko@ti.com>
 <1439401562-28874-7-git-send-email-grygorii.strashko@ti.com>
 <55CC63D0.8030707@arm.com> <55CC6EB8.3050906@ti.com>
Message-ID: <55CC79BD.4030001@arm.com>



On 13/08/15 11:17, Grygorii Strashko wrote:
> On 08/13/2015 12:30 PM, Sudeep Holla wrote:
>>
>>
>> On 12/08/15 18:46, Grygorii Strashko wrote:
>>> All ARM GIC IRQs have to masked during suspend if they are not
>>> wakeup source. Now this is not happen, since switching to
>>> use IRQ domain hierarchy, because suspend_device_irq() only checks flags
>>> in the last IRQ chip in hierarchy for IRQCHIP_MASK_ON_SUSPEND
>>> bit set. And in the case of TI OMAP DRA7 the last IRQ chip is TI Crossbar
>>> which do not have this flag set.
>>>
>>> In case of TI OMAP DRA7 the following IRQ hierarchy is defined:
>>>     ARM GIC <- OMAP wakeupgen <- TI CBAR
>>> ARM GIC - IRQCHIP_MASK_ON_SUSPEND=n
>>
>> May be this won't affect your platform or this patch but even GIC marks
>> IRQCHIP_MASK_ON_SUSPEND=y now since GIC doesn't provide any facility to
>> configure the wakeup source and keeps all the interrupt source enabled.
>
> That's true for next, bur not true for 4.2-rc6 or 4.1 :(
>

True, I just wanted to ensure there is no assumption.

[...]
>>
>> Also the beginning of the commit message contradicts when you also say
>> in the following statement IRQCHIP_MASK_ON_SUSPEND=n. So you may need to
>> update the log.
>
> I'll try to reword. What I've tried to mention that IRQs masking on
> suspend is default expected behavior and that how it was before
> switching to IRQ domain hierarchy.
>
> "All ARM GIC IRQs have to masked during suspend if they are not
>   wakeup source - this is expected behavior and that's how it was before
>   switching to IRQ domain hierarchy. ..."
> ok?
>

My mistake I referred the code after it was converted to use stack
domains. So I missed to understand that you were using gic_arch_extn
flags before to override GIC flags as gic_set_irqchip_flags was not
used when I removed it. Sorry for the noise, you can retain the commit
log as is.

Regards,
Sudeep


From geert at linux-m68k.org  Thu Aug 13 04:05:02 2015
From: geert at linux-m68k.org (Geert Uytterhoeven)
Date: Thu, 13 Aug 2015 13:05:02 +0200
Subject: [RFC] sh-sci: Add CONFIG_SERIAL_EARLYCON support
In-Reply-To: <1433669307-19478-1-git-send-email-ysato@users.sourceforge.jp>
References: <1433669307-19478-1-git-send-email-ysato@users.sourceforge.jp>
Message-ID: <CAMuHMdVRjsN5TixjMnnwp4JvRPHqv2iJOGpSvrk7p4-Dd1MHUA@mail.gmail.com>

Hi Sato-san, Arnd,

On Sun, Jun 7, 2015 at 11:28 AM, Yoshinori Sato
<ysato at users.sourceforge.jp> wrote:
> "earlyprintk" is architecture specific option.
> I think general "earlycon" option support more better.

Thanks for your patch!

I finally gave it a try on shmobile. Sorry for taking that long...

Despite claims from a few months ago:

On Sun, Mar 22, 2015 at 8:48 PM, Arnd Bergmann <arnd at arndb.de> wrote:
> I think a number of people have expressed that they'd rather get rid of the
> DEBUG_LL list in the long run, now that we have earlycon working. If we

earlycon doesn't seem to be ready on arm.

Without "[PATCH v5] ARM: early fixmap support for earlycon"
(https://lkml.org/lkml/2015/8/11/532), it hangs in ioremap(), as called from
earlycon_map().

> diff --git a/drivers/tty/serial/sh-sci.c b/drivers/tty/serial/sh-sci.c
> index 95772cf..6eb82e1 100644
> --- a/drivers/tty/serial/sh-sci.c
> +++ b/drivers/tty/serial/sh-sci.c

> -#ifdef CONFIG_SERIAL_SH_SCI_CONSOLE
> +#if defined(CONFIG_SERIAL_SH_SCI_CONSOLE) || defined(CONFIG_SERIAL_EARLYCON)
>  static void serial_console_putchar(struct uart_port *port, int ch)
>  {
>         sci_poll_put_char(port, ch);
> @@ -2359,9 +2360,12 @@ static void serial_console_write(struct console *co, const char *s,
>         int locked = 1;
>
>         local_irq_save(flags);
> +#if defined(SUPPORT_SYSRQ)
>         if (port->sysrq)
>                 locked = 0;
> -       else if (oops_in_progress)
> +       else
> +#endif
> +       if (oops_in_progress)
>                 locked = spin_trylock(&port->lock);
>         else
>                 spin_lock(&port->lock);
> @@ -2719,6 +2723,66 @@ static void __exit sci_exit(void)
>  early_platform_init_buffer("earlyprintk", &sci_driver,
>                            early_serial_buf, ARRAY_SIZE(early_serial_buf));
>  #endif
> +#ifdef CONFIG_SERIAL_EARLYCON
> +static struct __init plat_sci_port port_cfg;
> +
> +static int __init early_console_setup(struct earlycon_device *device,
> +                                     int type)
> +{
> +       if (!device->port.membase)
> +               return -ENODEV;
> +
> +       device->port.serial_in = sci_serial_in;
> +       device->port.serial_out = sci_serial_out;
> +       device->port.type = type;
> +       memcpy(&sci_ports[0].port, &device->port, sizeof(struct uart_port));
> +       sci_ports[0].cfg = &port_cfg;
> +       sci_ports[0].cfg->type = type;
> +       sci_probe_regmap(sci_ports[0].cfg);
> +       port_cfg.scscr = SCSCR_RE | SCSCR_TE;
> +       sci_serial_out(&sci_ports[0].port, SCSCR, port_cfg.scscr);
> +
> +       device->con->write = serial_console_write;
> +       return 0;
> +}

Earlycon cannot use serial_console_write(), as it takes an
uninitialized spinlock():

BUG: spinlock bad magic on CPU#0, swapper/0
 lock: sci_ports+0x0/0x35c0, .magic: 00000000, .owner: <none>/-1, .owner_cpu: 0
CPU: 0 PID: 0 Comm: swapper Not tainted
4.2.0-rc6-koelsch-04464-g15cd6b1126aee571 #1525
Hardware name: Generic R8A7791 (Flattened Device Tree)
Backtrace:
[<c00138b4>] (dump_backtrace) from [<c0013aac>] (show_stack+0x18/0x1c)
 r6:600001d3 r5:c0e6d268 r4:00000000 r3:00200000
[<c0013a94>] (show_stack) from [<c045fe3c>] (dump_stack+0x78/0x94)
[<c045fdc4>] (dump_stack) from [<c006f61c>] (spin_dump+0x80/0x94)
 r4:00000000 r3:00000000
[<c006f59c>] (spin_dump) from [<c006f65c>] (spin_bug+0x2c/0x30)
 r5:c0e6d268 r4:c057cfe7
[<c006f630>] (spin_bug) from [<c006f6e8>] (do_raw_spin_lock+0x28/0x198)
 r5:c0e6d268 r4:c0e6d268
[<c006f6c0>] (do_raw_spin_lock) from [<c0465654>] (_raw_spin_lock+0x3c/0x44)
 r9:00000000 r8:00000022 r7:00000000 r6:600001d3 r5:c0e6d268 r4:c0e6d268
[<c0465618>] (_raw_spin_lock) from [<c02636cc>]
(serial_console_write+0x58/0x134)
 r4:c0e6d268
[<c0263674>] (serial_console_write) from [<c0072aec>]
(call_console_drivers.constprop.25+0xd0/0xf4)
 r10:c0e4e2c8 r9:c0646010 r8:00000022 r7:00000000 r6:c0e4e2dc r5:c0e2d988
 r4:c066a2f0
[<c0072a1c>] (call_console_drivers.constprop.25) from [<c00747a4>]
(console_unlock+0x370/0x44c)
 r9:00000000 r8:00000022 r7:00000006 r6:200001d3 r5:c0e4d908 r4:c0e2e2a4
[<c0074434>] (console_unlock) from [<c00754a4>] (register_console+0x2ac/0x39c)
 r10:00000001 r9:00000000 r8:c06502d4 r7:c0e2d988 r6:00000000 r5:c0e2d9b8
 r4:c066a2f0
[<c00751f8>] (register_console) from [<c061f150>] (of_setup_earlycon+0x9c/0xb0)
 r9:00000080 r8:c0634039 r7:c061f240 r6:00000000 r5:c066a2f0 r4:ffeff000
[<c061f0b4>] (of_setup_earlycon) from [<c0623668>]
(setup_of_earlycon+0x100/0x124)
 r7:00004288 r6:c063f42c r5:00000000 r4:c0fec000

Fortunately it continues, so I saw the BUG()...

Most drivers seem to fix this by having an early_serial_console_write()
that only performs the core functionality of serial_console_write().

Alternatively, (sci-specific) early_console_setup() or (generic)
register_earlycon() could call

        spin_lock_init(&device->port.lock);

I tried both approaches, and then the kernel doesn't crash anymore.
Still, I don't think anything is printed by earlycon: I just see a long delay of
a few seconds, presumable until ttySC0 takes over.

Calling serial_console_write() explicitly with a test message makes the
kernel lock up. Oops...

Does FIX_EARLYCON_MEM work?

Thanks!

Gr{oetje,eeting}s,

                        Geert

--
Geert Uytterhoeven -- There's lots of Linux beyond ia32 -- geert at linux-m68k.org

In personal conversations with technical people, I call myself a hacker. But
when I'm talking to journalists I just say "programmer" or something like that.
                                -- Linus Torvalds


From jassisinghbrar at gmail.com  Thu Aug 13 04:10:42 2015
From: jassisinghbrar at gmail.com (Jassi Brar)
Date: Thu, 13 Aug 2015 16:40:42 +0530
Subject: [PATCH v2 5/6] mailbox: Add generic mechanism for testing Mailbox
 Controllers
In-Reply-To: <20150813110008.GD8782@x1>
References: <1437990272-23111-1-git-send-email-lee.jones@linaro.org>
 <1437990272-23111-6-git-send-email-lee.jones@linaro.org>
 <CABb+yY20nQbiEEZeRvWTMUsJ2qgwRn8CrWvnFDSB-b1dgVaAuw@mail.gmail.com>
 <20150812102328.GD18282@x1>
 <CABb+yY0A74Vy3-KOvj0URU_4zb2FAC7Yp3gmEwnFaBrD0mzt0w@mail.gmail.com>
 <20150813091914.GB8782@x1>
 <CABb+yY0cgbtM68-E_Xqgh5O6GRLXESYTLa5WcAwUBoVL3ufrxA@mail.gmail.com>
 <20150813102335.GC8782@x1>
 <CABb+yY3z7p97eOhncQ2i+g6yoYGfDgSN9BDPKmiDaVLa3oPocA@mail.gmail.com>
 <20150813110008.GD8782@x1>
Message-ID: <CABb+yY34i=VUnswUE21vgeQYAGOS=7uwvdnTAFFgYkTV0CFk=w@mail.gmail.com>

On Thu, Aug 13, 2015 at 4:30 PM, Lee Jones <lee.jones at linaro.org> wrote:
> On Thu, 13 Aug 2015, Jassi Brar wrote:
>
>> On Thu, Aug 13, 2015 at 3:53 PM, Lee Jones <lee.jones at linaro.org> wrote:
>> > On Thu, 13 Aug 2015, Jassi Brar wrote:
>> >
>> >> On Thu, Aug 13, 2015 at 2:49 PM, Lee Jones <lee.jones at linaro.org> wrote:
>> >> > On Thu, 13 Aug 2015, Jassi Brar wrote:
>> >>
>> >> >> >> > +
>> >> >> >> > +static void mbox_test_prepare_message(struct mbox_client *client, void *message)
>> >> >> >> > +{
>> >> >> >> > +       struct mbox_test_device *tdev = dev_get_drvdata(client->dev);
>> >> >> >> > +
>> >> >> >> > +       if (tdev->mmio)
>> >> >> >> > +               memcpy(tdev->mmio, message, MBOX_MAX_MSG_LEN);
>> >> >> >> >
>> >> >> >> This is unlikely to work. Those platforms that need to send a 2 part
>> >> >> >> message, they do :
>> >> >> >> (a) Signal/Command/Target code via some controller register (via
>> >> >> >> mbox_send_message).
>> >> >> >> (b) Setup the payload in Shared-Memory (via tx_prepare).
>> >> >> >>
>> >> >> >> This test driver assumes both are the same. I think you have to
>> >> >> >> declare something like
>> >> >> >
>> >> >> > This driver assumes that the framework will call client->tx_prepare()
>> >> >> > first, which satisfies (b).  It then assumes controller->send_data()
>> >> >> > will be invoked, which will send the platform specific
>> >> >> > signal/command/target code, which then satisfies (a).
>> >> >> >
>> >> >> Yeah, but what would be that code? Who provides that?
>> >> >>
>> >> >> > In what way does it assume they are the same?
>> >> >> >
>> >> >> notice the 'message' pointer in
>> >> >> mbox_send_message(tdev->tx_channel, message);
>> >> >>     and
>> >> >> memcpy(tdev->mmio, message, MBOX_MAX_MSG_LEN);
>> >> >>
>> >> >> >> struct mbox_test_message { /* same for TX and RX */
>> >> >> >>           unsigned sig_len;
>> >> >> >>           void *signal;               /* rx/tx via mailbox api */
>> >> >> >>           unsigned pl_len;
>> >> >> >>           void *payload;           /* rx/tx via shared-memory */
>> >> >> >> };
>> >> >> >
>> >> >> > How do you think this should be set and use these?
>> >> >> >
>> >> >> The userspace would want to specify the command code (32bits or not)
>> >> >> that would be passed via the fifo/register of the controller. So we
>> >> >> need signal[]
>> >> >>
>> >> >> The data to be passed via share-memory could be provided by userspace
>> >> >> via the payload[] array.
>> >> >
>> >> > Okay, so would the solution be two userspace files 'signal' and
>> >> > 'message', so in the case of a client specified signal we can write it
>> >> > into there first.
>> >> >
>> >> > echo 255  > signal
>> >> > echo test > message
>> >> >
>> >> > ... or in the case where no signal is required, or the controller
>> >> > driver taking care of it, we just don't write anything to signal?
>> >> >
>> >> file_operations.write() should parse signal and message, coming from
>> >> userspace, into a local structure before routing them via
>> >> mbox_send_message and tx_prepare respectively.
>> >
>> > Okay.  So before I code this up we should agree on syntax.
>> >
>> > How would you like to represent the break between signal and message?
>> > Obviously ' ' would be a bad idea, as some clients may want to send
>> > messages with white space contained.  How about '\t' or '\n'?
>> >
>> Yeah, I am not a fan of markers and flags either.
>>
>> Maybe we should share with userspace
>>   struct mbox_test_message { /* same for TX and RX */
>>            unsigned sig_len;
>>            void __user *signal;        /* rx/tx via mailbox api */
>>            unsigned pl_len;
>>            void __user *payload;    /* rx/tx via shared-memory */
>>   };
>>
>> First copy_from_user the structure of length sizof(struct
>> mbox_test_message) and then copy_from_user length sig_len and pl_len
>> from signal[] and payload[] respectively (usually ioctls would carry
>> such data).
>
> Simplicity and ease of use should be the goals here.  Testers should
> not have to write applications to use this driver.  Can we come up
> with a simple/effective method that uses SYSFS/DEBUGFS please?
>
> The easiest way I can think of which avoids markers/separators AND the
> requirement for users to have to write applications is to have two
> files, 'signal' and 'message' as mentioned before.  Once both are
> populated I can get this driver to draft the message appropriately and
> fire it off.
>
And then write to more files for RX data? ... which should also be in
the form of 'signal' and 'message'.

BTW like for spi there is a stock application in
Documentation/spi/spidev_test.c we could do the same?


From linus.walleij at linaro.org  Thu Aug 13 04:11:01 2015
From: linus.walleij at linaro.org (Linus Walleij)
Date: Thu, 13 Aug 2015 13:11:01 +0200
Subject: [PATCH v4 2/4] gpio: brcmstb: Add interrupt and wakeup source
 support
In-Reply-To: <1438391865-7862-3-git-send-email-gregory.0xf0@gmail.com>
References: <1438391865-7862-1-git-send-email-gregory.0xf0@gmail.com>
 <1438391865-7862-3-git-send-email-gregory.0xf0@gmail.com>
Message-ID: <CACRpkdaz3k_N1qS5M_jmprPz8fHXeLtTke_YT8i2gaehmme+OQ@mail.gmail.com>

On Sat, Aug 1, 2015 at 3:17 AM, Gregory Fong <gregory.0xf0 at gmail.com> wrote:

> Uses the gpiolib irqchip helpers.  For this to work, the irq setup
> function is called once per bank instead of once per device.  Note
> that all known uses of this block have a BCM7120 L2 interrupt
> controller as a parent.  Supports interrupts for all GPIOs.
>
> In the IRQ handler, we check for raised IRQs for invalid GPIOs and
> warn (ratelimited) if they're encountered.
>
> Also, several drivers (e.g. gpio-keys) allow for GPIOs to be
> configured as wakeup sources, and this GPIO controller supports that
> through a separate interrupt path.
>
> The de-facto standard DT property "wakeup-source" is checked, since
> that indicates whether the GPIO controller hardware can wake.  Uses
> the IRQCHIP_MASK_ON_SUSPEND irq_chip flag because UPG GIO doesn't have
> any of its own wakeup source configuration.
>
> Aside regarding gpiolib irqchip helpers: It wasn't obvious (to me)
> that you can have multiple chained irqchips and associated IRQ domains
> for a single parent IRQ, and as long as the xlate function is written
> correctly, a GPIO IRQ request end up checking the correct domain and
> will get associated with the correct IRQ.  What helps make this clear
> is to read
>   drivers/gpio/gpiolib-of.c:
>    - of_gpiochip_find_and_xlate()
>    - of_get_named_gpiod_flags()
>   drivers/gpio/gpiolib.c:
>    - gpiochip_find()
>
> Signed-off-by: Gregory Fong <gregory.0xf0 at gmail.com>
> ---
> v4:
> - when checking parent_irq, use <= 0 or > 0 since 0 is NO_IRQ.

Patch applied, but:


> +       if (of_property_read_bool(np, "interrupt-controller")) {
> +               priv->parent_irq = platform_get_irq(pdev, 0);
> +               if (priv->parent_irq <= 0) {
> +                       dev_err(dev, "Couldn't get IRQ");
> +                       return -ENOENT;
> +               }
> +       } else {
> +               priv->parent_irq = -ENOENT;
> +       }
> +
>         if (brcmstb_gpio_sanity_check_banks(dev, np, res))
>                 return -EINVAL;

This patch does not apply cleanly because the version in my
tree has INIT_LIST_HEAD(&priv->bank_list);
before the sanity check.

I applied it manually, but check that things are working right.

Yours,
Linus Walleij


From linus.walleij at linaro.org  Thu Aug 13 04:12:31 2015
From: linus.walleij at linaro.org (Linus Walleij)
Date: Thu, 13 Aug 2015 13:12:31 +0200
Subject: [PATCH v4 3/4] gpio: brcmstb: support wakeup from S5 cold boot
In-Reply-To: <1438391865-7862-4-git-send-email-gregory.0xf0@gmail.com>
References: <1438391865-7862-1-git-send-email-gregory.0xf0@gmail.com>
 <1438391865-7862-4-git-send-email-gregory.0xf0@gmail.com>
Message-ID: <CACRpkdaTwLHC528+p6ytPhR7POonECfU3_-EEz--nrs353UTXg@mail.gmail.com>

On Sat, Aug 1, 2015 at 3:17 AM, Gregory Fong <gregory.0xf0 at gmail.com> wrote:

> For wake from S5, we need to:
> - register a reboot handler
> - set wakeup capability before requesting IRQ so wakeup count is
>   incremented
> - mask all GPIO IRQs and clear any pending interrupts during driver
>   probe to since no driver will yet be registered to handle any IRQs
>   carried over from boot at that time, and it's possible that the
>   booted kernel does not request the same IRQ anyway.
>
> This means that /sys/.../power/wakeup_count is valid at boot time, and
> we can properly account for S5 wakeup stats. e.g.:
>
>   ### After waking from S5 from a GPIO key
>   # cat /sys/bus/platform/drivers/brcmstb-gpio/f04172c0.gpio/power/wakeup
>   enabled
>   # cat /sys/bus/platform/drivers/brcmstb-gpio/f04172c0.gpio/power/wakeup_count
>   1
>
> Signed-off-by: Gregory Fong <gregory.0xf0 at gmail.com>
> ---
> v4: rename __brcmstb_gpio_irq_set_wake() to brcmstb_gpio_priv_set_wake().

Patch applied.

Yours,
Linus Walleij


From linus.walleij at linaro.org  Thu Aug 13 04:15:35 2015
From: linus.walleij at linaro.org (Linus Walleij)
Date: Thu, 13 Aug 2015 13:15:35 +0200
Subject: [PATCH] pinctrl: UniPhier: PH1-Pro5: add I2C ch6 pin-mux setting
In-Reply-To: <1438400332-2933-1-git-send-email-yamada.masahiro@socionext.com>
References: <1438400332-2933-1-git-send-email-yamada.masahiro@socionext.com>
Message-ID: <CACRpkdYR-tzShzN=p7YnY-EAfOkJJbcK4ydpZMP9KXFA7+ZOvw@mail.gmail.com>

On Sat, Aug 1, 2015 at 5:38 AM, Masahiro Yamada
<yamada.masahiro at socionext.com> wrote:

> The initial version of this driver missed to add I2C ch6 pin-muxing.
>
> Signed-off-by: Masahiro Yamada <yamada.masahiro at socionext.com>

Patch applied.

Yours,
Linus Walleij


From alexandre.belloni at free-electrons.com  Thu Aug 13 04:21:18 2015
From: alexandre.belloni at free-electrons.com (Alexandre Belloni)
Date: Thu, 13 Aug 2015 13:21:18 +0200
Subject: [GIT PULL] at91: defconfig for 4.3 #2
In-Reply-To: <20150813100938.GN30160@localhost>
References: <20150807162754.GA20169@piout.net>
 <20150813100938.GN30160@localhost>
Message-ID: <20150813112118.GA22269@piout.net>

On 13/08/2015 at 12:09:38 +0200, Olof Johansson wrote :
> On Fri, Aug 07, 2015 at 06:27:54PM +0200, Alexandre Belloni wrote:
> > Arnd, Olof, Kevin,
> > 
> > A little defconfig update. That will probably be all for this cycle.
> > 
> > Thanks, bye,
> > 
> > 
> > The following changes since commit eff7f41572a645bf14a96a6f844be4f1c88cd9dd:
> > 
> >   ARM: at91: at91_dt_defconfig: enable ISI and ov2640 support (2015-07-30 14:17:31 +0200)
> > 
> > are available in the git repository at:
> > 
> >   git://git.kernel.org/pub/scm/linux/kernel/git/abelloni/linux.git tags/at91-ab-defconfig2
> > 
> > for you to fetch changes up to ea7bf603fd494391acc1f42acbfc34260b965c44:
> > 
> >   ARM: at91/defconfig: at91_dt: remove ARM_AT91_ETHER (2015-08-07 12:07:50 +0200)
> 
> Nicolas had sent me one patch which you've also included here but it's not in
> the pull request ("enable ISI and ov2640 support"). That caused a conflict
> here, so to avoid having the patch in the tree twice I instead also directly
> applied your patches from this branch instead of merging.
> 
> Sorry about that, it started due to Nicolas sending the discrete patch to us.
> So it seems like we'll apply at91 defconfig updates directly this release, in
> case there are any more. No big deal I hope. :)
> 

That's not a big deal and there will most probably be all for that cycle
anyway.

However, I'm wondering how I should have done. From the PR, if you get
eff7f41572a645bf14a96a6f844be4f1c88cd9dd..tags/at91-ab-defconfig2, it
correctly excludes "enable ISI and ov2640 support" so I was thinking it
was fine.
Be cause the first patch was taken as a patch, should I have prepared a
branch without it?

-- 
Alexandre Belloni, Free Electrons
Embedded Linux, Kernel and Android engineering
http://free-electrons.com


From will.deacon at arm.com  Thu Aug 13 04:24:28 2015
From: will.deacon at arm.com (Will Deacon)
Date: Thu, 13 Aug 2015 12:24:28 +0100
Subject: [PATCH 0/2] x86/KASAN updates for 4.3
In-Reply-To: <CAPAsAGxk2+v5VG77cOHAThsXyWx-_UJ1XVeJProaa0gQWH5jvA@mail.gmail.com>
References: <1439444244-26057-1-git-send-email-ryabinin.a.a@gmail.com>
 <20150813065040.GA17983@gmail.com>
 <20150813081641.GA14402@gmail.com> <20150813090119.GA10280@arm.com>
 <CAPAsAGxk2+v5VG77cOHAThsXyWx-_UJ1XVeJProaa0gQWH5jvA@mail.gmail.com>
Message-ID: <20150813112428.GG10280@arm.com>

On Thu, Aug 13, 2015 at 12:02:26PM +0100, Andrey Ryabinin wrote:
> 2015-08-13 12:01 GMT+03:00 Will Deacon <will.deacon at arm.com>:
> > Yes please, works for me! If we're targetting 4.3, then please can you base
> > on 4.2-rc4, as that's what our current arm64 queue is using?
> >
> 
> Does this mean that we are targeting arm64 part for 4.3 too?

It depends on how well it merges with our current queue and whether it
holds up to regression testing. The patches have been reviewed, so I'm
comfortable with the content, but we're not at a stage where we can debug
and fix any failures that might crop up from the merge.

Will


From suzuki.poulose at arm.com  Thu Aug 13 04:33:50 2015
From: suzuki.poulose at arm.com (Suzuki K. Poulose)
Date: Thu, 13 Aug 2015 12:33:50 +0100
Subject: [PATCH 00/14] arm64: 16K translation granule support
Message-ID: <1439465645-22584-1-git-send-email-suzuki.poulose@arm.com>

From: "Suzuki K. Poulose" <suzuki.poulose at arm.com>

This series enables the 16K page size support on Linux for arm64.
This series adds support for 48bit VA(4 level), 47bit VA(3 level) and
36bit VA(2 level) with 16K. 16K was a late addition to the architecture
and is not implemented by all CPUs. Added a check to ensure the
selected granule size is supported by the CPU, failing which the CPU
won't proceed with booting.

KVM bits have been tested on a fast model with GICv3 using Andre's kvmtool
with gicv3 support[1].

Patches 1-7 cleans up the kernel page size handling code.
Patches 8-11 Fixes some issues with the KVM bits, mainly the fake PGD
             handling code.
Patch 12    Adds a check to ensure the CPU supports the selected granule size.
Patch 13-14 Adds the 16k page size support bits.

This series applies on top of for-next/core branch of the aarch64 tree and is
also available here:

	git://linux-arm.org/linux-skp.git  16k/v1

[1] git://linux-arm.org/kvmtool.git gicv3/v4

TODO:
 1) Testing on a silicon
 2) Analyse the performance of HugePages with 16K (32MB) on a
    silicon.
 3) SMMU driver

Suzuki K. Poulose (14):
  arm64: Move swapper pagetable definitions
  arm64: Handle section maps for swapper/idmap
  arm64: Introduce helpers for page table levels
  arm64: Calculate size for idmap_pg_dir at compile time
  arm64: Handle 4 level page table for swapper
  arm64: Clean config usages for page size
  arm64: Kconfig: Fix help text about AArch32 support with 64K pages
  arm64: kvm: Fix {V}TCR_EL2_TG0 mask
  arm64: Cleanup VTCR_EL2 computation
  arm: kvm: Move fake PGD handling to arch specific files
  arm64: kvm: Rewrite fake pgd handling
  arm64: Check for selected granule support
  arm64: Add 16K page size support
  arm64: 36 bit VA

 arch/arm/include/asm/kvm_mmu.h          |    7 ++
 arch/arm/kvm/mmu.c                      |   44 ++--------
 arch/arm64/Kconfig                      |   37 +++++++--
 arch/arm64/Kconfig.debug                |    2 +-
 arch/arm64/include/asm/boot.h           |    1 +
 arch/arm64/include/asm/fixmap.h         |    4 +-
 arch/arm64/include/asm/kernel-pgtable.h |   77 ++++++++++++++++++
 arch/arm64/include/asm/kvm_arm.h        |   29 +++++--
 arch/arm64/include/asm/kvm_mmu.h        |  135 +++++++++++++++++++++----------
 arch/arm64/include/asm/page.h           |   20 +----
 arch/arm64/include/asm/pgtable-hwdef.h  |   15 +++-
 arch/arm64/include/asm/sysreg.h         |    8 ++
 arch/arm64/include/asm/thread_info.h    |    4 +-
 arch/arm64/kernel/head.S                |   71 +++++++++-------
 arch/arm64/kernel/vmlinux.lds.S         |    1 +
 arch/arm64/mm/mmu.c                     |   70 +++++++---------
 arch/arm64/mm/proc.S                    |    4 +-
 17 files changed, 337 insertions(+), 192 deletions(-)
 create mode 100644 arch/arm64/include/asm/kernel-pgtable.h

-- 
1.7.9.5



From suzuki.poulose at arm.com  Thu Aug 13 04:33:54 2015
From: suzuki.poulose at arm.com (Suzuki K. Poulose)
Date: Thu, 13 Aug 2015 12:33:54 +0100
Subject: [PATCH 04/14] arm64: Calculate size for idmap_pg_dir at compile time
In-Reply-To: <1439465645-22584-1-git-send-email-suzuki.poulose@arm.com>
References: <1439465645-22584-1-git-send-email-suzuki.poulose@arm.com>
Message-ID: <1439465645-22584-5-git-send-email-suzuki.poulose@arm.com>

From: "Suzuki K. Poulose" <suzuki.poulose at arm.com>

Now that we can calculate the number of levels required for
mapping a va width, reserve exact number of pages that would
be required to cover the idmap. The idmap should be able to handle
the maximum physical address size supported.

Cc: Ard Biesheuvel <ard.biesheuvel at linaro.org>
Cc: Mark Rutland <mark.rutland at arm.com>
Cc: Catalin Marinas <catalin.marinas at arm.com>
Cc: Will Deacon <will.deacon at arm.com>
Signed-off-by: Suzuki K. Poulose <suzuki.poulose at arm.com>
---
 arch/arm64/include/asm/boot.h           |    1 +
 arch/arm64/include/asm/kernel-pgtable.h |    7 +++++--
 2 files changed, 6 insertions(+), 2 deletions(-)

diff --git a/arch/arm64/include/asm/boot.h b/arch/arm64/include/asm/boot.h
index 81151b6..678b63e 100644
--- a/arch/arm64/include/asm/boot.h
+++ b/arch/arm64/include/asm/boot.h
@@ -2,6 +2,7 @@
 #ifndef __ASM_BOOT_H
 #define __ASM_BOOT_H
 
+#include <asm/page.h>
 #include <asm/sizes.h>
 
 /*
diff --git a/arch/arm64/include/asm/kernel-pgtable.h b/arch/arm64/include/asm/kernel-pgtable.h
index 5876a36..def7168 100644
--- a/arch/arm64/include/asm/kernel-pgtable.h
+++ b/arch/arm64/include/asm/kernel-pgtable.h
@@ -33,16 +33,19 @@
  * map to pte level. The swapper also maps the FDT (see __create_page_tables
  * for more information). Note that the number of ID map translation levels
  * could be increased on the fly if system RAM is out of reach for the default
- * VA range, so 3 pages are reserved in all cases.
+ * VA range, so pages required to map highest possible PA are reserved in all
+ * cases.
  */
 #if ARM64_SWAPPER_USES_SECTION_MAPS
 #define SWAPPER_PGTABLE_LEVELS	(CONFIG_PGTABLE_LEVELS - 1)
+#define IDMAP_PGTABLE_LEVELS	(ARM64_HW_PGTABLE_LEVELS(PHYS_MASK_SHIFT) - 1)
 #else
 #define SWAPPER_PGTABLE_LEVELS	(CONFIG_PGTABLE_LEVELS)
+#define IDMAP_PGTABLE_LEVELS	(ARM64_HW_PGTABLE_LEVELS(PHYS_MASK_SHIFT))
 #endif
 
 #define SWAPPER_DIR_SIZE	(SWAPPER_PGTABLE_LEVELS * PAGE_SIZE)
-#define IDMAP_DIR_SIZE		(3 * PAGE_SIZE)
+#define IDMAP_DIR_SIZE		(IDMAP_PGTABLE_LEVELS * PAGE_SIZE)
 
 /* Initial memory map size */
 #if ARM64_SWAPPER_USES_SECTION_MAPS
-- 
1.7.9.5



From suzuki.poulose at arm.com  Thu Aug 13 04:33:52 2015
From: suzuki.poulose at arm.com (Suzuki K. Poulose)
Date: Thu, 13 Aug 2015 12:33:52 +0100
Subject: [PATCH 02/14] arm64: Handle section maps for swapper/idmap
In-Reply-To: <1439465645-22584-1-git-send-email-suzuki.poulose@arm.com>
References: <1439465645-22584-1-git-send-email-suzuki.poulose@arm.com>
Message-ID: <1439465645-22584-3-git-send-email-suzuki.poulose@arm.com>

From: "Suzuki K. Poulose" <suzuki.poulose at arm.com>

We use section maps with 4K page size to create the
swapper/idmaps. So far we have used !64K or 4K checks
to handle the case where we use the section maps. This
patch adds a symbol to make it clear those cases.

Cc: Ard Biesheuvel <ard.biesheuvel at linaro.org>
Cc: Mark Rutland <mark.rutland at arm.com>
Cc: Catalin Marinas <catalin.marinas at arm.com>
Cc: Will Deacon <will.deacon at arm.com>
Signed-off-by: Suzuki K. Poulose <suzuki.poulose at arm.com>
---
 arch/arm64/include/asm/kernel-pgtable.h |   31 +++++++++-----
 arch/arm64/mm/mmu.c                     |   70 ++++++++++++++-----------------
 2 files changed, 51 insertions(+), 50 deletions(-)

diff --git a/arch/arm64/include/asm/kernel-pgtable.h b/arch/arm64/include/asm/kernel-pgtable.h
index 622929d..5876a36 100644
--- a/arch/arm64/include/asm/kernel-pgtable.h
+++ b/arch/arm64/include/asm/kernel-pgtable.h
@@ -19,6 +19,13 @@
 #ifndef __ASM_KERNEL_PGTABLE_H
 #define __ASM_KERNEL_PGTABLE_H
 
+/* With 4K pages, we use section maps. */
+#ifdef CONFIG_ARM64_4K_PAGES
+#define ARM64_SWAPPER_USES_SECTION_MAPS 1
+#else
+#define ARM64_SWAPPER_USES_SECTION_MAPS 0
+#endif
+
 /*
  * The idmap and swapper page tables need some space reserved in the kernel
  * image. Both require pgd, pud (4 levels only) and pmd tables to (section)
@@ -28,26 +35,28 @@
  * could be increased on the fly if system RAM is out of reach for the default
  * VA range, so 3 pages are reserved in all cases.
  */
-#ifdef CONFIG_ARM64_64K_PAGES
-#define SWAPPER_PGTABLE_LEVELS	(CONFIG_PGTABLE_LEVELS)
-#else
+#if ARM64_SWAPPER_USES_SECTION_MAPS
 #define SWAPPER_PGTABLE_LEVELS	(CONFIG_PGTABLE_LEVELS - 1)
+#else
+#define SWAPPER_PGTABLE_LEVELS	(CONFIG_PGTABLE_LEVELS)
 #endif
 
 #define SWAPPER_DIR_SIZE	(SWAPPER_PGTABLE_LEVELS * PAGE_SIZE)
 #define IDMAP_DIR_SIZE		(3 * PAGE_SIZE)
 
 /* Initial memory map size */
-#ifdef CONFIG_ARM64_64K_PAGES
-#define SWAPPER_BLOCK_SHIFT	PAGE_SHIFT
-#define SWAPPER_BLOCK_SIZE	PAGE_SIZE
-#define SWAPPER_TABLE_SHIFT	PMD_SHIFT
-#else
+#if ARM64_SWAPPER_USES_SECTION_MAPS
 #define SWAPPER_BLOCK_SHIFT	SECTION_SHIFT
 #define SWAPPER_BLOCK_SIZE	SECTION_SIZE
 #define SWAPPER_TABLE_SHIFT	PUD_SHIFT
+#else
+#define SWAPPER_BLOCK_SHIFT	PAGE_SHIFT
+#define SWAPPER_BLOCK_SIZE	PAGE_SIZE
+#define SWAPPER_TABLE_SHIFT	PMD_SHIFT
 #endif
 
+/* The size of the initial kernel direct mapping */
+#define SWAPPER_INIT_MAP_SIZE	(_AC(1, UL) << SWAPPER_TABLE_SHIFT)
 
 /*
  * Initial memory map attributes.
@@ -55,10 +64,10 @@
 #define SWAPPER_PTE_FLAGS	PTE_TYPE_PAGE | PTE_AF | PTE_SHARED
 #define SWAPPER_PMD_FLAGS	PMD_TYPE_SECT | PMD_SECT_AF | PMD_SECT_S
 
-#ifdef CONFIG_ARM64_64K_PAGES
-#define SWAPPER_MM_MMUFLAGS	PTE_ATTRINDX(MT_NORMAL) | SWAPPER_PTE_FLAGS
-#else
+#if ARM64_SWAPPER_USES_SECTION_MAPS
 #define SWAPPER_MM_MMUFLAGS	PMD_ATTRINDX(MT_NORMAL) | SWAPPER_PMD_FLAGS
+#else
+#define SWAPPER_MM_MMUFLAGS	PTE_ATTRINDX(MT_NORMAL) | SWAPPER_PTE_FLAGS
 #endif
 
 
diff --git a/arch/arm64/mm/mmu.c b/arch/arm64/mm/mmu.c
index 9211b85..71230488 100644
--- a/arch/arm64/mm/mmu.c
+++ b/arch/arm64/mm/mmu.c
@@ -32,6 +32,7 @@
 
 #include <asm/cputype.h>
 #include <asm/fixmap.h>
+#include <asm/kernel-pgtable.h>
 #include <asm/sections.h>
 #include <asm/setup.h>
 #include <asm/sizes.h>
@@ -353,14 +354,11 @@ static void __init map_mem(void)
 	 * memory addressable from the initial direct kernel mapping.
 	 *
 	 * The initial direct kernel mapping, located at swapper_pg_dir, gives
-	 * us PUD_SIZE (4K pages) or PMD_SIZE (64K pages) memory starting from
-	 * PHYS_OFFSET (which must be aligned to 2MB as per
-	 * Documentation/arm64/booting.txt).
+	 * us PUD_SIZE (with SECTION maps, i.e, 4K) or PMD_SIZE (without
+	 * SECTION maps, i.e, 64K pages) memory starting from PHYS_OFFSET
+	 * (which must be aligned to 2MB as per Documentation/arm64/booting.txt).
 	 */
-	if (IS_ENABLED(CONFIG_ARM64_64K_PAGES))
-		limit = PHYS_OFFSET + PMD_SIZE;
-	else
-		limit = PHYS_OFFSET + PUD_SIZE;
+	limit = PHYS_OFFSET + SWAPPER_INIT_MAP_SIZE;
 	memblock_set_current_limit(limit);
 
 	/* map all the memory banks */
@@ -371,21 +369,24 @@ static void __init map_mem(void)
 		if (start >= end)
 			break;
 
-#ifndef CONFIG_ARM64_64K_PAGES
-		/*
-		 * For the first memory bank align the start address and
-		 * current memblock limit to prevent create_mapping() from
-		 * allocating pte page tables from unmapped memory.
-		 * When 64K pages are enabled, the pte page table for the
-		 * first PGDIR_SIZE is already present in swapper_pg_dir.
-		 */
-		if (start < limit)
-			start = ALIGN(start, PMD_SIZE);
-		if (end < limit) {
-			limit = end & PMD_MASK;
-			memblock_set_current_limit(limit);
+		if (ARM64_SWAPPER_USES_SECTION_MAPS) {
+			/*
+			 * For the first memory bank align the start address and
+			 * current memblock limit to prevent create_mapping() from
+			 * allocating pte page tables from unmapped memory. With
+			 * the section maps, if the first block doesn't end on section
+			 * size boundary, create_mapping() will try to allocate a pte
+			 * page, which may be returned from an unmapped area.
+			 * When section maps are not used, the pte page table for the
+			 * current limit is already present in swapper_pg_dir.
+			 */
+			if (start < limit)
+				start = ALIGN(start, SECTION_SIZE);
+			if (end < limit) {
+				limit = end & SECTION_MASK;
+				memblock_set_current_limit(limit);
+			}
 		}
-#endif
 		__map_memblock(start, end);
 	}
 
@@ -638,7 +639,7 @@ void *__init fixmap_remap_fdt(phys_addr_t dt_phys)
 {
 	const u64 dt_virt_base = __fix_to_virt(FIX_FDT);
 	pgprot_t prot = PAGE_KERNEL | PTE_RDONLY;
-	int granularity, size, offset;
+	int size, offset;
 	void *dt_virt;
 
 	/*
@@ -664,24 +665,15 @@ void *__init fixmap_remap_fdt(phys_addr_t dt_phys)
 	 */
 	BUILD_BUG_ON(dt_virt_base % SZ_2M);
 
-	if (IS_ENABLED(CONFIG_ARM64_64K_PAGES)) {
-		BUILD_BUG_ON(__fix_to_virt(FIX_FDT_END) >> PMD_SHIFT !=
-			     __fix_to_virt(FIX_BTMAP_BEGIN) >> PMD_SHIFT);
-
-		granularity = PAGE_SIZE;
-	} else {
-		BUILD_BUG_ON(__fix_to_virt(FIX_FDT_END) >> PUD_SHIFT !=
-			     __fix_to_virt(FIX_BTMAP_BEGIN) >> PUD_SHIFT);
-
-		granularity = PMD_SIZE;
-	}
+	BUILD_BUG_ON(__fix_to_virt(FIX_FDT_END) >> SWAPPER_TABLE_SHIFT !=
+		     __fix_to_virt(FIX_BTMAP_BEGIN) >> SWAPPER_TABLE_SHIFT);
 
-	offset = dt_phys % granularity;
+	offset = dt_phys % SWAPPER_BLOCK_SIZE;
 	dt_virt = (void *)dt_virt_base + offset;
 
 	/* map the first chunk so we can read the size from the header */
-	create_mapping(round_down(dt_phys, granularity), dt_virt_base,
-		       granularity, prot);
+	create_mapping(round_down(dt_phys, SWAPPER_BLOCK_SIZE), dt_virt_base,
+		       SWAPPER_BLOCK_SIZE, prot);
 
 	if (fdt_check_header(dt_virt) != 0)
 		return NULL;
@@ -690,9 +682,9 @@ void *__init fixmap_remap_fdt(phys_addr_t dt_phys)
 	if (size > MAX_FDT_SIZE)
 		return NULL;
 
-	if (offset + size > granularity)
-		create_mapping(round_down(dt_phys, granularity), dt_virt_base,
-			       round_up(offset + size, granularity), prot);
+	if (offset + size > SWAPPER_BLOCK_SIZE)
+		create_mapping(round_down(dt_phys, SWAPPER_BLOCK_SIZE), dt_virt_base,
+			       round_up(offset + size, SWAPPER_BLOCK_SIZE), prot);
 
 	memblock_reserve(dt_phys, size);
 
-- 
1.7.9.5



From suzuki.poulose at arm.com  Thu Aug 13 04:33:51 2015
From: suzuki.poulose at arm.com (Suzuki K. Poulose)
Date: Thu, 13 Aug 2015 12:33:51 +0100
Subject: [PATCH 01/14] arm64: Move swapper pagetable definitions
In-Reply-To: <1439465645-22584-1-git-send-email-suzuki.poulose@arm.com>
References: <1439465645-22584-1-git-send-email-suzuki.poulose@arm.com>
Message-ID: <1439465645-22584-2-git-send-email-suzuki.poulose@arm.com>

From: "Suzuki K. Poulose" <suzuki.poulose at arm.com>

Move the kernel pagetable (both swapper and idmap) definitions
from the generic asm/page.h to a new file, asm/kernel-pgtable.h.

This is mostly a cosmetic change, to clean up the asm/page.h to
get rid of the arch specific details which are not needed by the
generic code.

Also renames the symbols to prevent conflicts. e.g,
 	BLOCK_SHIFT => SWAPPER_BLOCK_SHIFT

Cc: Ard Biesheuvel <ard.biesheuvel at linaro.org>
Cc: Mark Rutland <mark.rutland at arm.com>
Cc: Catalin Marinas <catalin.marinas at arm.com>
Cc: Will Deacon <will.deacon at arm.com>
Signed-off-by: Suzuki K. Poulose <suzuki.poulose at arm.com>
---
 arch/arm64/include/asm/kernel-pgtable.h |   65 +++++++++++++++++++++++++++++++
 arch/arm64/include/asm/page.h           |   18 ---------
 arch/arm64/kernel/head.S                |   37 ++++--------------
 arch/arm64/kernel/vmlinux.lds.S         |    1 +
 4 files changed, 74 insertions(+), 47 deletions(-)
 create mode 100644 arch/arm64/include/asm/kernel-pgtable.h

diff --git a/arch/arm64/include/asm/kernel-pgtable.h b/arch/arm64/include/asm/kernel-pgtable.h
new file mode 100644
index 0000000..622929d
--- /dev/null
+++ b/arch/arm64/include/asm/kernel-pgtable.h
@@ -0,0 +1,65 @@
+/*
+ * asm/kernel-pgtable.h : Kernel page table mapping
+ *
+ * Copyright (C) 2015 ARM Ltd.
+ *
+ * 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.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program.  If not, see <http://www.gnu.org/licenses/>.
+ */
+
+#ifndef __ASM_KERNEL_PGTABLE_H
+#define __ASM_KERNEL_PGTABLE_H
+
+/*
+ * The idmap and swapper page tables need some space reserved in the kernel
+ * image. Both require pgd, pud (4 levels only) and pmd tables to (section)
+ * map the kernel. With the 64K page configuration, swapper and idmap need to
+ * map to pte level. The swapper also maps the FDT (see __create_page_tables
+ * for more information). Note that the number of ID map translation levels
+ * could be increased on the fly if system RAM is out of reach for the default
+ * VA range, so 3 pages are reserved in all cases.
+ */
+#ifdef CONFIG_ARM64_64K_PAGES
+#define SWAPPER_PGTABLE_LEVELS	(CONFIG_PGTABLE_LEVELS)
+#else
+#define SWAPPER_PGTABLE_LEVELS	(CONFIG_PGTABLE_LEVELS - 1)
+#endif
+
+#define SWAPPER_DIR_SIZE	(SWAPPER_PGTABLE_LEVELS * PAGE_SIZE)
+#define IDMAP_DIR_SIZE		(3 * PAGE_SIZE)
+
+/* Initial memory map size */
+#ifdef CONFIG_ARM64_64K_PAGES
+#define SWAPPER_BLOCK_SHIFT	PAGE_SHIFT
+#define SWAPPER_BLOCK_SIZE	PAGE_SIZE
+#define SWAPPER_TABLE_SHIFT	PMD_SHIFT
+#else
+#define SWAPPER_BLOCK_SHIFT	SECTION_SHIFT
+#define SWAPPER_BLOCK_SIZE	SECTION_SIZE
+#define SWAPPER_TABLE_SHIFT	PUD_SHIFT
+#endif
+
+
+/*
+ * Initial memory map attributes.
+ */
+#define SWAPPER_PTE_FLAGS	PTE_TYPE_PAGE | PTE_AF | PTE_SHARED
+#define SWAPPER_PMD_FLAGS	PMD_TYPE_SECT | PMD_SECT_AF | PMD_SECT_S
+
+#ifdef CONFIG_ARM64_64K_PAGES
+#define SWAPPER_MM_MMUFLAGS	PTE_ATTRINDX(MT_NORMAL) | SWAPPER_PTE_FLAGS
+#else
+#define SWAPPER_MM_MMUFLAGS	PMD_ATTRINDX(MT_NORMAL) | SWAPPER_PMD_FLAGS
+#endif
+
+
+#endif
diff --git a/arch/arm64/include/asm/page.h b/arch/arm64/include/asm/page.h
index 7d9c7e4..3c9ce8c 100644
--- a/arch/arm64/include/asm/page.h
+++ b/arch/arm64/include/asm/page.h
@@ -28,24 +28,6 @@
 #define PAGE_SIZE		(_AC(1,UL) << PAGE_SHIFT)
 #define PAGE_MASK		(~(PAGE_SIZE-1))
 
-/*
- * The idmap and swapper page tables need some space reserved in the kernel
- * image. Both require pgd, pud (4 levels only) and pmd tables to (section)
- * map the kernel. With the 64K page configuration, swapper and idmap need to
- * map to pte level. The swapper also maps the FDT (see __create_page_tables
- * for more information). Note that the number of ID map translation levels
- * could be increased on the fly if system RAM is out of reach for the default
- * VA range, so 3 pages are reserved in all cases.
- */
-#ifdef CONFIG_ARM64_64K_PAGES
-#define SWAPPER_PGTABLE_LEVELS	(CONFIG_PGTABLE_LEVELS)
-#else
-#define SWAPPER_PGTABLE_LEVELS	(CONFIG_PGTABLE_LEVELS - 1)
-#endif
-
-#define SWAPPER_DIR_SIZE	(SWAPPER_PGTABLE_LEVELS * PAGE_SIZE)
-#define IDMAP_DIR_SIZE		(3 * PAGE_SIZE)
-
 #ifndef __ASSEMBLY__
 
 #include <asm/pgtable-types.h>
diff --git a/arch/arm64/kernel/head.S b/arch/arm64/kernel/head.S
index a055be6..46670bf 100644
--- a/arch/arm64/kernel/head.S
+++ b/arch/arm64/kernel/head.S
@@ -29,6 +29,7 @@
 #include <asm/asm-offsets.h>
 #include <asm/cache.h>
 #include <asm/cputype.h>
+#include <asm/kernel-pgtable.h>
 #include <asm/memory.h>
 #include <asm/thread_info.h>
 #include <asm/pgtable-hwdef.h>
@@ -46,32 +47,10 @@
 #error TEXT_OFFSET must be less than 2MB
 #endif
 
-#ifdef CONFIG_ARM64_64K_PAGES
-#define BLOCK_SHIFT	PAGE_SHIFT
-#define BLOCK_SIZE	PAGE_SIZE
-#define TABLE_SHIFT	PMD_SHIFT
-#else
-#define BLOCK_SHIFT	SECTION_SHIFT
-#define BLOCK_SIZE	SECTION_SIZE
-#define TABLE_SHIFT	PUD_SHIFT
-#endif
-
 #define KERNEL_START	_text
 #define KERNEL_END	_end
 
 /*
- * Initial memory map attributes.
- */
-#define PTE_FLAGS	PTE_TYPE_PAGE | PTE_AF | PTE_SHARED
-#define PMD_FLAGS	PMD_TYPE_SECT | PMD_SECT_AF | PMD_SECT_S
-
-#ifdef CONFIG_ARM64_64K_PAGES
-#define MM_MMUFLAGS	PTE_ATTRINDX(MT_NORMAL) | PTE_FLAGS
-#else
-#define MM_MMUFLAGS	PMD_ATTRINDX(MT_NORMAL) | PMD_FLAGS
-#endif
-
-/*
  * Kernel startup entry point.
  * ---------------------------
  *
@@ -293,7 +272,7 @@ ENDPROC(preserve_boot_args)
 	.macro	create_pgd_entry, tbl, virt, tmp1, tmp2
 	create_table_entry \tbl, \virt, PGDIR_SHIFT, PTRS_PER_PGD, \tmp1, \tmp2
 #if SWAPPER_PGTABLE_LEVELS == 3
-	create_table_entry \tbl, \virt, TABLE_SHIFT, PTRS_PER_PTE, \tmp1, \tmp2
+	create_table_entry \tbl, \virt, SWAPPER_TABLE_SHIFT, PTRS_PER_PTE, \tmp1, \tmp2
 #endif
 	.endm
 
@@ -305,15 +284,15 @@ ENDPROC(preserve_boot_args)
  * Corrupts:	phys, start, end, pstate
  */
 	.macro	create_block_map, tbl, flags, phys, start, end
-	lsr	\phys, \phys, #BLOCK_SHIFT
-	lsr	\start, \start, #BLOCK_SHIFT
+	lsr	\phys, \phys, #SWAPPER_BLOCK_SHIFT
+	lsr	\start, \start, #SWAPPER_BLOCK_SHIFT
 	and	\start, \start, #PTRS_PER_PTE - 1	// table index
-	orr	\phys, \flags, \phys, lsl #BLOCK_SHIFT	// table entry
-	lsr	\end, \end, #BLOCK_SHIFT
+	orr	\phys, \flags, \phys, lsl #SWAPPER_BLOCK_SHIFT	// table entry
+	lsr	\end, \end, #SWAPPER_BLOCK_SHIFT
 	and	\end, \end, #PTRS_PER_PTE - 1		// table end index
 9999:	str	\phys, [\tbl, \start, lsl #3]		// store the entry
 	add	\start, \start, #1			// next entry
-	add	\phys, \phys, #BLOCK_SIZE		// next block
+	add	\phys, \phys, #SWAPPER_BLOCK_SIZE		// next block
 	cmp	\start, \end
 	b.ls	9999b
 	.endm
@@ -350,7 +329,7 @@ __create_page_tables:
 	cmp	x0, x6
 	b.lo	1b
 
-	ldr	x7, =MM_MMUFLAGS
+	ldr	x7, =SWAPPER_MM_MMUFLAGS
 
 	/*
 	 * Create the identity mapping.
diff --git a/arch/arm64/kernel/vmlinux.lds.S b/arch/arm64/kernel/vmlinux.lds.S
index 9807333..8a5d97b 100644
--- a/arch/arm64/kernel/vmlinux.lds.S
+++ b/arch/arm64/kernel/vmlinux.lds.S
@@ -5,6 +5,7 @@
  */
 
 #include <asm-generic/vmlinux.lds.h>
+#include <asm/kernel-pgtable.h>
 #include <asm/thread_info.h>
 #include <asm/memory.h>
 #include <asm/page.h>
-- 
1.7.9.5



From suzuki.poulose at arm.com  Thu Aug 13 04:33:57 2015
From: suzuki.poulose at arm.com (Suzuki K. Poulose)
Date: Thu, 13 Aug 2015 12:33:57 +0100
Subject: [PATCH 07/14] arm64: Kconfig: Fix help text about AArch32 support
 with 64K pages
In-Reply-To: <1439465645-22584-1-git-send-email-suzuki.poulose@arm.com>
References: <1439465645-22584-1-git-send-email-suzuki.poulose@arm.com>
Message-ID: <1439465645-22584-8-git-send-email-suzuki.poulose@arm.com>

From: "Suzuki K. Poulose" <suzuki.poulose at arm.com>

Update the help text for ARM64_64K_PAGES to reflect the reality
about AArch32 support.

Cc: Mark Rutland <mark.rutland at arm.com>
Cc: Catalin Marinas <catalin.marinas at arm.com>
Cc: Will Deacon <will.deacon at arm.com>
Signed-off-by: Suzuki K. Poulose <suzuki.poulose at arm.com>
---
 arch/arm64/Kconfig |    4 ++--
 1 file changed, 2 insertions(+), 2 deletions(-)

diff --git a/arch/arm64/Kconfig b/arch/arm64/Kconfig
index d1fb2a3..b247897 100644
--- a/arch/arm64/Kconfig
+++ b/arch/arm64/Kconfig
@@ -449,8 +449,8 @@ config ARM64_64K_PAGES
 	help
 	  This feature enables 64KB pages support (4KB by default)
 	  allowing only two levels of page tables and faster TLB
-	  look-up. AArch32 emulation is not available when this feature
-	  is enabled.
+	  look-up. AArch32 emulation requires applications compiled
+	  with 64K aligned segments.
 
 endchoice
 
-- 
1.7.9.5



From suzuki.poulose at arm.com  Thu Aug 13 04:34:00 2015
From: suzuki.poulose at arm.com (Suzuki K. Poulose)
Date: Thu, 13 Aug 2015 12:34:00 +0100
Subject: [PATCH 10/14] arm: kvm: Move fake PGD handling to arch specific files
In-Reply-To: <1439465645-22584-1-git-send-email-suzuki.poulose@arm.com>
References: <1439465645-22584-1-git-send-email-suzuki.poulose@arm.com>
Message-ID: <1439465645-22584-11-git-send-email-suzuki.poulose@arm.com>

From: "Suzuki K. Poulose" <suzuki.poulose at arm.com>

Rearrange the code for fake pgd handling, which is applicable
to only ARM64. The intention is to keep the common code cleaner,
unaware of the underlying hacks.

Cc: kvmarm at lists.cs.columbia.edu
Cc: christoffer.dall at linaro.org
Cc: Marc.Zyngier at arm.com
Signed-off-by: Suzuki K. Poulose <suzuki.poulose at arm.com>
---
 arch/arm/include/asm/kvm_mmu.h   |    7 ++++++
 arch/arm/kvm/mmu.c               |   44 +++++---------------------------------
 arch/arm64/include/asm/kvm_mmu.h |   43 +++++++++++++++++++++++++++++++++++++
 3 files changed, 55 insertions(+), 39 deletions(-)

diff --git a/arch/arm/include/asm/kvm_mmu.h b/arch/arm/include/asm/kvm_mmu.h
index 405aa18..1c9aa8a 100644
--- a/arch/arm/include/asm/kvm_mmu.h
+++ b/arch/arm/include/asm/kvm_mmu.h
@@ -173,6 +173,13 @@ static inline unsigned int kvm_get_hwpgd_size(void)
 	return PTRS_PER_S2_PGD * sizeof(pgd_t);
 }
 
+static inline pgd_t *kvm_setup_fake_pgd(pgd_t *pgd)
+{
+	return pgd;
+}
+
+static inline void kvm_free_fake_pgd(pgd_t *pgd) {}
+
 struct kvm;
 
 #define kvm_flush_dcache_to_poc(a,l)	__cpuc_flush_dcache_area((a), (l))
diff --git a/arch/arm/kvm/mmu.c b/arch/arm/kvm/mmu.c
index 7b42012..b210622 100644
--- a/arch/arm/kvm/mmu.c
+++ b/arch/arm/kvm/mmu.c
@@ -677,43 +677,11 @@ int kvm_alloc_stage2_pgd(struct kvm *kvm)
 	 * guest, we allocate a fake PGD and pre-populate it to point
 	 * to the next-level page table, which will be the real
 	 * initial page table pointed to by the VTTBR.
-	 *
-	 * When KVM_PREALLOC_LEVEL==2, we allocate a single page for
-	 * the PMD and the kernel will use folded pud.
-	 * When KVM_PREALLOC_LEVEL==1, we allocate 2 consecutive PUD
-	 * pages.
 	 */
-	if (KVM_PREALLOC_LEVEL > 0) {
-		int i;
-
-		/*
-		 * Allocate fake pgd for the page table manipulation macros to
-		 * work.  This is not used by the hardware and we have no
-		 * alignment requirement for this allocation.
-		 */
-		pgd = kmalloc(PTRS_PER_S2_PGD * sizeof(pgd_t),
-				GFP_KERNEL | __GFP_ZERO);
-
-		if (!pgd) {
-			kvm_free_hwpgd(hwpgd);
-			return -ENOMEM;
-		}
-
-		/* Plug the HW PGD into the fake one. */
-		for (i = 0; i < PTRS_PER_S2_PGD; i++) {
-			if (KVM_PREALLOC_LEVEL == 1)
-				pgd_populate(NULL, pgd + i,
-					     (pud_t *)hwpgd + i * PTRS_PER_PUD);
-			else if (KVM_PREALLOC_LEVEL == 2)
-				pud_populate(NULL, pud_offset(pgd, 0) + i,
-					     (pmd_t *)hwpgd + i * PTRS_PER_PMD);
-		}
-	} else {
-		/*
-		 * Allocate actual first-level Stage-2 page table used by the
-		 * hardware for Stage-2 page table walks.
-		 */
-		pgd = (pgd_t *)hwpgd;
+	pgd = kvm_setup_fake_pgd(hwpgd);
+	if (IS_ERR(pgd)) {
+		kvm_free_hwpgd(hwpgd);
+		return PTR_ERR(pgd);
 	}
 
 	kvm_clean_pgd(pgd);
@@ -820,9 +788,7 @@ void kvm_free_stage2_pgd(struct kvm *kvm)
 
 	unmap_stage2_range(kvm, 0, KVM_PHYS_SIZE);
 	kvm_free_hwpgd(kvm_get_hwpgd(kvm));
-	if (KVM_PREALLOC_LEVEL > 0)
-		kfree(kvm->arch.pgd);
-
+	kvm_free_fake_pgd(kvm->arch.pgd);
 	kvm->arch.pgd = NULL;
 }
 
diff --git a/arch/arm64/include/asm/kvm_mmu.h b/arch/arm64/include/asm/kvm_mmu.h
index 6150567..2567fe8 100644
--- a/arch/arm64/include/asm/kvm_mmu.h
+++ b/arch/arm64/include/asm/kvm_mmu.h
@@ -198,6 +198,49 @@ static inline unsigned int kvm_get_hwpgd_size(void)
 	return PTRS_PER_S2_PGD * sizeof(pgd_t);
 }
 
+/*
+ * Allocate fake pgd for the page table manipulation macros to
+ * work.  This is not used by the hardware and we have no
+ * alignment requirement for this allocation.
+ */
+static inline pgd_t* kvm_setup_fake_pgd(pgd_t *hwpgd)
+{
+	int i;
+	pgd_t *pgd;
+
+	if (!KVM_PREALLOC_LEVEL)
+		return hwpgd;
+	/*
+	 * When KVM_PREALLOC_LEVEL==2, we allocate a single page for
+	 * the PMD and the kernel will use folded pud.
+	 * When KVM_PREALLOC_LEVEL==1, we allocate 2 consecutive PUD
+	 * pages.
+	 */
+	pgd = kmalloc(PTRS_PER_S2_PGD * sizeof(pgd_t),
+			GFP_KERNEL | __GFP_ZERO);
+
+	if (!pgd)
+		return ERR_PTR(-ENOMEM);
+
+	/* Plug the HW PGD into the fake one. */
+	for (i = 0; i < PTRS_PER_S2_PGD; i++) {
+		if (KVM_PREALLOC_LEVEL == 1)
+			pgd_populate(NULL, pgd + i,
+				     (pud_t *)hwpgd + i * PTRS_PER_PUD);
+		else if (KVM_PREALLOC_LEVEL == 2)
+			pud_populate(NULL, pud_offset(pgd, 0) + i,
+				     (pmd_t *)hwpgd + i * PTRS_PER_PMD);
+	}
+
+	return pgd;
+}
+
+static inline void kvm_free_fake_pgd(pgd_t *pgd)
+{
+	if (KVM_PREALLOC_LEVEL > 0)
+		kfree(pgd);
+}
+
 static inline bool kvm_page_empty(void *ptr)
 {
 	struct page *ptr_page = virt_to_page(ptr);
-- 
1.7.9.5



From suzuki.poulose at arm.com  Thu Aug 13 04:34:02 2015
From: suzuki.poulose at arm.com (Suzuki K. Poulose)
Date: Thu, 13 Aug 2015 12:34:02 +0100
Subject: [PATCH 12/14] arm64: Check for selected granule support
In-Reply-To: <1439465645-22584-1-git-send-email-suzuki.poulose@arm.com>
References: <1439465645-22584-1-git-send-email-suzuki.poulose@arm.com>
Message-ID: <1439465645-22584-13-git-send-email-suzuki.poulose@arm.com>

From: "Suzuki K. Poulose" <suzuki.poulose at arm.com>

Ensure that the selected page size is supported by the
CPU(s).

Cc: Mark Rutland <mark.rutland at arm.com>
Cc: Catalin Marinas <catalin.marinas at arm.com>
Cc: Will Deacon <will.deacon at arm.com>
Signed-off-by: Suzuki K. Poulose <suzuki.poulose at arm.com>
---
 arch/arm64/include/asm/sysreg.h |    6 ++++++
 arch/arm64/kernel/head.S        |   24 +++++++++++++++++++++++-
 2 files changed, 29 insertions(+), 1 deletion(-)

diff --git a/arch/arm64/include/asm/sysreg.h b/arch/arm64/include/asm/sysreg.h
index a7f3d4b..e01d323 100644
--- a/arch/arm64/include/asm/sysreg.h
+++ b/arch/arm64/include/asm/sysreg.h
@@ -87,4 +87,10 @@ static inline void config_sctlr_el1(u32 clear, u32 set)
 }
 #endif
 
+#define ID_AA64MMFR0_TGran4_SHIFT	28
+#define ID_AA64MMFR0_TGran64_SHIFT	24
+
+#define ID_AA64MMFR0_TGran4_ENABLED	0x0
+#define ID_AA64MMFR0_TGran64_ENABLED	0x0
+
 #endif	/* __ASM_SYSREG_H */
diff --git a/arch/arm64/kernel/head.S b/arch/arm64/kernel/head.S
index 01b8e58..0cb04db 100644
--- a/arch/arm64/kernel/head.S
+++ b/arch/arm64/kernel/head.S
@@ -31,10 +31,11 @@
 #include <asm/cputype.h>
 #include <asm/kernel-pgtable.h>
 #include <asm/memory.h>
-#include <asm/thread_info.h>
 #include <asm/pgtable-hwdef.h>
 #include <asm/pgtable.h>
 #include <asm/page.h>
+#include <asm/sysreg.h>
+#include <asm/thread_info.h>
 #include <asm/virt.h>
 
 #define __PHYS_OFFSET	(KERNEL_START - TEXT_OFFSET)
@@ -606,9 +607,25 @@ ENDPROC(__secondary_switched)
  *  x27 = *virtual* address to jump to upon completion
  *
  * other registers depend on the function called upon completion
+ * Checks if the selected granule size is supported by the CPU.
  */
+#if	defined(CONFIG_ARM64_64K_PAGES)
+
+#define ID_AA64MMFR0_TGran_SHIFT	ID_AA64MMFR0_TGran64_SHIFT
+#define ID_AA64MMFR0_TGran_ENABLED	ID_AA64MMFR0_TGran64_ENABLED
+
+#else
+
+#define ID_AA64MMFR0_TGran_SHIFT	ID_AA64MMFR0_TGran4_SHIFT
+#define ID_AA64MMFR0_TGran_ENABLED	ID_AA64MMFR0_TGran4_ENABLED
+
+#endif
 	.section	".idmap.text", "ax"
 __enable_mmu:
+	mrs	x1, ID_AA64MMFR0_EL1
+	ubfx	x2, x1, #ID_AA64MMFR0_TGran_SHIFT, 4
+	cmp	x2, #ID_AA64MMFR0_TGran_ENABLED
+	b.ne	__no_granule_support
 	ldr	x5, =vectors
 	msr	vbar_el1, x5
 	msr	ttbr0_el1, x25			// load TTBR0
@@ -626,3 +643,8 @@ __enable_mmu:
 	isb
 	br	x27
 ENDPROC(__enable_mmu)
+
+__no_granule_support:
+	wfe
+	b __no_granule_support
+ENDPROC(__no_granule_support)
-- 
1.7.9.5



From suzuki.poulose at arm.com  Thu Aug 13 04:34:04 2015
From: suzuki.poulose at arm.com (Suzuki K. Poulose)
Date: Thu, 13 Aug 2015 12:34:04 +0100
Subject: [PATCH 14/14] arm64: 36 bit VA
In-Reply-To: <1439465645-22584-1-git-send-email-suzuki.poulose@arm.com>
References: <1439465645-22584-1-git-send-email-suzuki.poulose@arm.com>
Message-ID: <1439465645-22584-15-git-send-email-suzuki.poulose@arm.com>

From: "Suzuki K. Poulose" <suzuki.poulose at arm.com>

36bit VA lets us use 2 level page tables while limiting the
available address space to 64GB.

Cc: Mark Rutland <mark.rutland at arm.com>
Cc: Catalin Marinas <catalin.marinas at arm.com>
Cc: Will Deacon <will.deacon at arm.com>
Signed-off-by: Suzuki K. Poulose <suzuki.poulose at arm.com>
---
 arch/arm64/Kconfig |    8 +++++++-
 1 file changed, 7 insertions(+), 1 deletion(-)

diff --git a/arch/arm64/Kconfig b/arch/arm64/Kconfig
index 8327edf..0407fd3 100644
--- a/arch/arm64/Kconfig
+++ b/arch/arm64/Kconfig
@@ -164,6 +164,7 @@ config FIX_EARLYCON_MEM
 
 config PGTABLE_LEVELS
 	int
+	default 2 if ARM64_16K_PAGES && ARM64_VA_BITS_36
 	default 2 if ARM64_64K_PAGES && ARM64_VA_BITS_42
 	default 3 if ARM64_64K_PAGES && ARM64_VA_BITS_48
 	default 3 if ARM64_4K_PAGES && ARM64_VA_BITS_39
@@ -472,6 +473,10 @@ choice
 	  space sizes. The level of translation table is determined by
 	  a combination of page size and virtual address space size.
 
+config ARM64_VA_BITS_36
+	bool "36-bit"
+	depends on ARM64_16K_PAGES
+
 config ARM64_VA_BITS_39
 	bool "39-bit"
 	depends on ARM64_4K_PAGES
@@ -491,6 +496,7 @@ endchoice
 
 config ARM64_VA_BITS
 	int
+	default 36 if ARM64_VA_BITS_36
 	default 39 if ARM64_VA_BITS_39
 	default 42 if ARM64_VA_BITS_42
 	default 47 if ARM64_VA_BITS_47
@@ -564,7 +570,7 @@ config ARCH_WANT_GENERAL_HUGETLB
 	def_bool y
 
 config ARCH_WANT_HUGE_PMD_SHARE
-	def_bool y if ARM64_4K_PAGES || ARM64_16K_PAGES
+	def_bool y if ARM64_4K_PAGES || (ARM64_16K_PAGES && !ARM64_VA_BITS_36)
 
 config HAVE_ARCH_TRANSPARENT_HUGEPAGE
 	def_bool y
-- 
1.7.9.5



From suzuki.poulose at arm.com  Thu Aug 13 04:33:56 2015
From: suzuki.poulose at arm.com (Suzuki K. Poulose)
Date: Thu, 13 Aug 2015 12:33:56 +0100
Subject: [PATCH 06/14] arm64: Clean config usages for page size
In-Reply-To: <1439465645-22584-1-git-send-email-suzuki.poulose@arm.com>
References: <1439465645-22584-1-git-send-email-suzuki.poulose@arm.com>
Message-ID: <1439465645-22584-7-git-send-email-suzuki.poulose@arm.com>

From: "Suzuki K. Poulose" <suzuki.poulose at arm.com>

We use !CONFIG_ARM64_64K_PAGES for CONFIG_ARM64_4K_PAGES
(and vice versa) in code. It all worked well, so far since
we only had two options. Now, with the introduction of 16K,
these cases will break. This patch cleans up the code to
use the required CONFIG symbol expression without the assumption
that !64K => 4K (and vice versa)

Cc: Ard Biesheuvel <ard.biesheuvel at linaro.org>
Cc: Catalin Marinas <catalin.marinas at arm.com>
Cc: Will Deacon <will.deacon at arm.com>
Cc: Steve Capper <steve.capper at linaro.org>
Acked-by: Mark Rutland <mark.rutland at arm.com>
Signed-off-by: Suzuki K. Poulose <suzuki.poulose at arm.com>
---
 arch/arm64/Kconfig                   |    4 ++--
 arch/arm64/Kconfig.debug             |    2 +-
 arch/arm64/include/asm/thread_info.h |    2 +-
 3 files changed, 4 insertions(+), 4 deletions(-)

diff --git a/arch/arm64/Kconfig b/arch/arm64/Kconfig
index 78b89fa..d1fb2a3 100644
--- a/arch/arm64/Kconfig
+++ b/arch/arm64/Kconfig
@@ -550,7 +550,7 @@ config ARCH_WANT_GENERAL_HUGETLB
 	def_bool y
 
 config ARCH_WANT_HUGE_PMD_SHARE
-	def_bool y if !ARM64_64K_PAGES
+	def_bool y if ARM64_4K_PAGES
 
 config HAVE_ARCH_TRANSPARENT_HUGEPAGE
 	def_bool y
@@ -762,7 +762,7 @@ source "fs/Kconfig.binfmt"
 
 config COMPAT
 	bool "Kernel support for 32-bit EL0"
-	depends on !ARM64_64K_PAGES || EXPERT
+	depends on ARM64_4K_PAGES || EXPERT
 	select COMPAT_BINFMT_ELF
 	select HAVE_UID16
 	select OLD_SIGSUSPEND3
diff --git a/arch/arm64/Kconfig.debug b/arch/arm64/Kconfig.debug
index d6285ef..c24d6ad 100644
--- a/arch/arm64/Kconfig.debug
+++ b/arch/arm64/Kconfig.debug
@@ -77,7 +77,7 @@ config DEBUG_RODATA
           If in doubt, say Y
 
 config DEBUG_ALIGN_RODATA
-	depends on DEBUG_RODATA && !ARM64_64K_PAGES
+	depends on DEBUG_RODATA && ARM64_4K_PAGES
 	bool "Align linker sections up to SECTION_SIZE"
 	help
 	  If this option is enabled, sections that may potentially be marked as
diff --git a/arch/arm64/include/asm/thread_info.h b/arch/arm64/include/asm/thread_info.h
index dcd06d1..d9c8c9f 100644
--- a/arch/arm64/include/asm/thread_info.h
+++ b/arch/arm64/include/asm/thread_info.h
@@ -23,7 +23,7 @@
 
 #include <linux/compiler.h>
 
-#ifndef CONFIG_ARM64_64K_PAGES
+#ifdef CONFIG_ARM64_4K_PAGES
 #define THREAD_SIZE_ORDER	2
 #endif
 
-- 
1.7.9.5



From suzuki.poulose at arm.com  Thu Aug 13 04:33:53 2015
From: suzuki.poulose at arm.com (Suzuki K. Poulose)
Date: Thu, 13 Aug 2015 12:33:53 +0100
Subject: [PATCH 03/14] arm64: Introduce helpers for page table levels
In-Reply-To: <1439465645-22584-1-git-send-email-suzuki.poulose@arm.com>
References: <1439465645-22584-1-git-send-email-suzuki.poulose@arm.com>
Message-ID: <1439465645-22584-4-git-send-email-suzuki.poulose@arm.com>

From: "Suzuki K. Poulose" <suzuki.poulose at arm.com>

Introduce helpers for finding the number of page table
levels required for a given VA width, shift for a particular
page table level.

Convert the existing users to the new helpers. More users
to follow.

Cc: Ard Biesheuvel <ard.biesheuvel at linaro.org>
Cc: Mark Rutland <mark.rutland at arm.com>
Cc: Catalin Marinas <catalin.marinas at arm.com>
Cc: Will Deacon <will.deacon at arm.com>
Signed-off-by: Suzuki K. Poulose <suzuki.poulose at arm.com>
---
 arch/arm64/include/asm/pgtable-hwdef.h |   15 ++++++++++++---
 1 file changed, 12 insertions(+), 3 deletions(-)

diff --git a/arch/arm64/include/asm/pgtable-hwdef.h b/arch/arm64/include/asm/pgtable-hwdef.h
index 24154b0..ce18389 100644
--- a/arch/arm64/include/asm/pgtable-hwdef.h
+++ b/arch/arm64/include/asm/pgtable-hwdef.h
@@ -16,13 +16,21 @@
 #ifndef __ASM_PGTABLE_HWDEF_H
 #define __ASM_PGTABLE_HWDEF_H
 
+/*
+ * Number of page-table levels required to address 'va_bits' wide
+ * address, without section mapping
+ */
+#define ARM64_HW_PGTABLE_LEVELS(va_bits) (((va_bits) - 4) / (PAGE_SHIFT - 3))
+#define ARM64_HW_PGTABLE_LEVEL_SHIFT(level) \
+		((PAGE_SHIFT - 3) * (level) + 3)
+
 #define PTRS_PER_PTE		(1 << (PAGE_SHIFT - 3))
 
 /*
  * PMD_SHIFT determines the size a level 2 page table entry can map.
  */
 #if CONFIG_PGTABLE_LEVELS > 2
-#define PMD_SHIFT		((PAGE_SHIFT - 3) * 2 + 3)
+#define PMD_SHIFT		ARM64_HW_PGTABLE_LEVEL_SHIFT(2)
 #define PMD_SIZE		(_AC(1, UL) << PMD_SHIFT)
 #define PMD_MASK		(~(PMD_SIZE-1))
 #define PTRS_PER_PMD		PTRS_PER_PTE
@@ -32,7 +40,7 @@
  * PUD_SHIFT determines the size a level 1 page table entry can map.
  */
 #if CONFIG_PGTABLE_LEVELS > 3
-#define PUD_SHIFT		((PAGE_SHIFT - 3) * 3 + 3)
+#define PUD_SHIFT		ARM64_HW_PGTABLE_LEVEL_SHIFT(3)
 #define PUD_SIZE		(_AC(1, UL) << PUD_SHIFT)
 #define PUD_MASK		(~(PUD_SIZE-1))
 #define PTRS_PER_PUD		PTRS_PER_PTE
@@ -42,7 +50,8 @@
  * PGDIR_SHIFT determines the size a top-level page table entry can map
  * (depending on the configuration, this level can be 0, 1 or 2).
  */
-#define PGDIR_SHIFT		((PAGE_SHIFT - 3) * CONFIG_PGTABLE_LEVELS + 3)
+#define PGDIR_SHIFT	\
+		ARM64_HW_PGTABLE_LEVEL_SHIFT(CONFIG_PGTABLE_LEVELS)
 #define PGDIR_SIZE		(_AC(1, UL) << PGDIR_SHIFT)
 #define PGDIR_MASK		(~(PGDIR_SIZE-1))
 #define PTRS_PER_PGD		(1 << (VA_BITS - PGDIR_SHIFT))
-- 
1.7.9.5



From suzuki.poulose at arm.com  Thu Aug 13 04:33:55 2015
From: suzuki.poulose at arm.com (Suzuki K. Poulose)
Date: Thu, 13 Aug 2015 12:33:55 +0100
Subject: [PATCH 05/14] arm64: Handle 4 level page table for swapper
In-Reply-To: <1439465645-22584-1-git-send-email-suzuki.poulose@arm.com>
References: <1439465645-22584-1-git-send-email-suzuki.poulose@arm.com>
Message-ID: <1439465645-22584-6-git-send-email-suzuki.poulose@arm.com>

From: "Suzuki K. Poulose" <suzuki.poulose at arm.com>

At the moment, we only support maximum of 3-level page table for
swapper. With 48bit VA, 64K has only 3 levels and 4K uses section
mapping. Add support for 4-level page table for swapper, needed
by 16K pages.

Cc: Ard Biesheuvel <ard.biesheuvel at linaro.org>
Cc: Mark Rutland <mark.rutland at arm.com>
Cc: Catalin Marinas <catalin.marinas at arm.com>
Cc: Will Deacon <will.deacon at arm.com>
Signed-off-by: Suzuki K. Poulose <suzuki.poulose at arm.com>
---
 arch/arm64/kernel/head.S |    5 ++++-
 1 file changed, 4 insertions(+), 1 deletion(-)

diff --git a/arch/arm64/kernel/head.S b/arch/arm64/kernel/head.S
index 46670bf..01b8e58 100644
--- a/arch/arm64/kernel/head.S
+++ b/arch/arm64/kernel/head.S
@@ -271,7 +271,10 @@ ENDPROC(preserve_boot_args)
  */
 	.macro	create_pgd_entry, tbl, virt, tmp1, tmp2
 	create_table_entry \tbl, \virt, PGDIR_SHIFT, PTRS_PER_PGD, \tmp1, \tmp2
-#if SWAPPER_PGTABLE_LEVELS == 3
+#if SWAPPER_PGTABLE_LEVELS > 3
+	create_table_entry \tbl, \virt, PUD_SHIFT, PTRS_PER_PUD, \tmp1, \tmp2
+#endif
+#if SWAPPER_PGTABLE_LEVELS > 2
 	create_table_entry \tbl, \virt, SWAPPER_TABLE_SHIFT, PTRS_PER_PTE, \tmp1, \tmp2
 #endif
 	.endm
-- 
1.7.9.5



From suzuki.poulose at arm.com  Thu Aug 13 04:33:59 2015
From: suzuki.poulose at arm.com (Suzuki K. Poulose)
Date: Thu, 13 Aug 2015 12:33:59 +0100
Subject: [PATCH 09/14] arm64: Cleanup VTCR_EL2 computation
In-Reply-To: <1439465645-22584-1-git-send-email-suzuki.poulose@arm.com>
References: <1439465645-22584-1-git-send-email-suzuki.poulose@arm.com>
Message-ID: <1439465645-22584-10-git-send-email-suzuki.poulose@arm.com>

From: "Suzuki K. Poulose" <suzuki.poulose at arm.com>

No functional changes. Group the common bits for VCTR_EL2
initialisation for better readability. The granule size
and the entry level are controlled by the page size.

Cc: Christoffer Dall <christoffer.dall at linaro.org>
Cc: Marc Zyngier <marc.zyngier at arm.com>
Cc: kvmarm at lists.cs.columbia.edu
Signed-off-by: Suzuki K. Poulose <suzuki.poulose at arm.com>
---
 arch/arm64/include/asm/kvm_arm.h |   13 +++++++------
 1 file changed, 7 insertions(+), 6 deletions(-)

diff --git a/arch/arm64/include/asm/kvm_arm.h b/arch/arm64/include/asm/kvm_arm.h
index 52dc9cc..dcaf799 100644
--- a/arch/arm64/include/asm/kvm_arm.h
+++ b/arch/arm64/include/asm/kvm_arm.h
@@ -138,6 +138,9 @@
  * The magic numbers used for VTTBR_X in this patch can be found in Tables
  * D4-23 and D4-25 in ARM DDI 0487A.b.
  */
+#define VTCR_EL2_COMMON_BITS	(VTCR_EL2_SH0_INNER | VTCR_EL2_ORGN0_WBWA | \
+				 VTCR_EL2_IRGN0_WBWA | VTCR_EL2_T0SZ_40B)
+
 #ifdef CONFIG_ARM64_64K_PAGES
 /*
  * Stage2 translation configuration:
@@ -145,9 +148,8 @@
  * 64kB pages (TG0 = 1)
  * 2 level page tables (SL = 1)
  */
-#define VTCR_EL2_FLAGS		(VTCR_EL2_TG0_64K | VTCR_EL2_SH0_INNER | \
-				 VTCR_EL2_ORGN0_WBWA | VTCR_EL2_IRGN0_WBWA | \
-				 VTCR_EL2_SL0_LVL1 | VTCR_EL2_T0SZ_40B)
+#define VTCR_EL2_FLAGS		(VTCR_EL2_TG0_64K | VTCR_EL2_SL0_LVL1 | \
+				 VTCR_EL2_COMMON_BITS)
 #define VTTBR_X		(38 - VTCR_EL2_T0SZ_40B)
 #else
 /*
@@ -156,9 +158,8 @@
  * 4kB pages (TG0 = 0)
  * 3 level page tables (SL = 1)
  */
-#define VTCR_EL2_FLAGS		(VTCR_EL2_TG0_4K | VTCR_EL2_SH0_INNER | \
-				 VTCR_EL2_ORGN0_WBWA | VTCR_EL2_IRGN0_WBWA | \
-				 VTCR_EL2_SL0_LVL1 | VTCR_EL2_T0SZ_40B)
+#define VTCR_EL2_FLAGS		(VTCR_EL2_TG0_4K | VTCR_EL2_SL0_LVL1 | \
+				 VTCR_EL2_COMMON_BITS)
 #define VTTBR_X		(37 - VTCR_EL2_T0SZ_40B)
 #endif
 
-- 
1.7.9.5



From suzuki.poulose at arm.com  Thu Aug 13 04:34:01 2015
From: suzuki.poulose at arm.com (Suzuki K. Poulose)
Date: Thu, 13 Aug 2015 12:34:01 +0100
Subject: [PATCH 11/14] arm64: kvm: Rewrite fake pgd handling
In-Reply-To: <1439465645-22584-1-git-send-email-suzuki.poulose@arm.com>
References: <1439465645-22584-1-git-send-email-suzuki.poulose@arm.com>
Message-ID: <1439465645-22584-12-git-send-email-suzuki.poulose@arm.com>

From: "Suzuki K. Poulose" <suzuki.poulose at arm.com>

The existing fake pgd handling code assumes that the stage-2 entry
level can only be one level down that of the host, which may not be
true always(e.g, with the introduction of 16k pagesize).

e.g.
With 16k page size and 48bit VA and 40bit IPA we have the following
split for page table levels:

level:  0       1         2         3
bits : [47] [46 - 36] [35 - 25] [24 - 14] [13 - 0]
         ^       ^     ^
         |       |     |
   host entry    |     x---- stage-2 entry
                 |
        IPA -----x

The stage-2 entry level is 2, due to the concatenation of 16tables
at level 2(mandated by the hardware). So, we need to fake two levels
to actually reach the hyp page table. This case cannot be handled
with the existing code, as, all we know about is KVM_PREALLOC_LEVEL
which kind of stands for two different pieces of information.

1) Whether we have fake page table entry levels.
2) The entry level of stage-2 translation.

We loose the information about the number of fake levels that
we may have to use. Also, KVM_PREALLOC_LEVEL computation itself
is wrong, as we assume the hw entry level is always 1 level down
from the host.

This patch introduces two seperate indicators :
1) Accurate entry level for stage-2 translation - HYP_PGTABLE_ENTRY_LEVEL -
   using the new helpers.
2) Number of levels of fake pagetable entries. (KVM_FAKE_PGTABLE_LEVELS)

The following conditions hold true for all cases(with 40bit IPA)
1) The stage-2 entry level <= 2
2) Number of fake page-table entries is in the inclusive range [0, 2].

Cc: kvmarm at lists.cs.columbia.edu
Cc: christoffer.dall at linaro.org
Cc: Marc.Zyngier at arm.com
Signed-off-by: Suzuki K. Poulose <suzuki.poulose at arm.com>
---
 arch/arm64/include/asm/kvm_mmu.h |  114 ++++++++++++++++++++------------------
 1 file changed, 61 insertions(+), 53 deletions(-)

diff --git a/arch/arm64/include/asm/kvm_mmu.h b/arch/arm64/include/asm/kvm_mmu.h
index 2567fe8..72cfd9e 100644
--- a/arch/arm64/include/asm/kvm_mmu.h
+++ b/arch/arm64/include/asm/kvm_mmu.h
@@ -41,18 +41,6 @@
  */
 #define TRAMPOLINE_VA		(HYP_PAGE_OFFSET_MASK & PAGE_MASK)
 
-/*
- * KVM_MMU_CACHE_MIN_PAGES is the number of stage2 page table translation
- * levels in addition to the PGD and potentially the PUD which are
- * pre-allocated (we pre-allocate the fake PGD and the PUD when the Stage-2
- * tables use one level of tables less than the kernel.
- */
-#ifdef CONFIG_ARM64_64K_PAGES
-#define KVM_MMU_CACHE_MIN_PAGES	1
-#else
-#define KVM_MMU_CACHE_MIN_PAGES	2
-#endif
-
 #ifdef __ASSEMBLY__
 
 /*
@@ -80,6 +68,26 @@
 #define KVM_PHYS_SIZE	(1UL << KVM_PHYS_SHIFT)
 #define KVM_PHYS_MASK	(KVM_PHYS_SIZE - 1UL)
 
+/*
+ * At stage-2 entry level, upto 16 tables can be concatenated and
+ * the hardware expects us to use concatenation, whenever possible.
+ * So, number of page table levels for KVM_PHYS_SHIFT is always
+ * the number of normal page table levels for (KVM_PHYS_SHIFT - 4).
+ */
+#define HYP_PGTABLE_LEVELS	ARM64_HW_PGTABLE_LEVELS(KVM_PHYS_SHIFT - 4)
+/* Number of bits normally addressed by HYP_PGTABLE_LEVELS */
+#define HYP_PGTABLE_SHIFT	ARM64_HW_PGTABLE_LEVEL_SHIFT(HYP_PGTABLE_LEVELS + 1)
+#define HYP_PGDIR_SHIFT		ARM64_HW_PGTABLE_LEVEL_SHIFT(HYP_PGTABLE_LEVELS)
+#define HYP_PGTABLE_ENTRY_LEVEL	(4 - HYP_PGTABLE_LEVELS)
+
+/*
+ * KVM_MMU_CACHE_MIN_PAGES is the number of stage2 page table translation
+ * levels in addition to the PGD and potentially the PUD which are
+ * pre-allocated (we pre-allocate the fake PGD and the PUD when the Stage-2
+ * tables use one level of tables less than the kernel.
+ */
+#define KVM_MMU_CACHE_MIN_PAGES	(HYP_PGTABLE_LEVELS - 1)
+
 int create_hyp_mappings(void *from, void *to);
 int create_hyp_io_mappings(void *from, void *to, phys_addr_t);
 void free_boot_hyp_pgd(void);
@@ -145,56 +153,41 @@ static inline bool kvm_s2pmd_readonly(pmd_t *pmd)
 #define kvm_pud_addr_end(addr, end)	pud_addr_end(addr, end)
 #define kvm_pmd_addr_end(addr, end)	pmd_addr_end(addr, end)
 
-/*
- * In the case where PGDIR_SHIFT is larger than KVM_PHYS_SHIFT, we can address
- * the entire IPA input range with a single pgd entry, and we would only need
- * one pgd entry.  Note that in this case, the pgd is actually not used by
- * the MMU for Stage-2 translations, but is merely a fake pgd used as a data
- * structure for the kernel pgtable macros to work.
- */
-#if PGDIR_SHIFT > KVM_PHYS_SHIFT
-#define PTRS_PER_S2_PGD_SHIFT	0
+/* Number of concatenated tables in stage-2 entry level */
+#if KVM_PHYS_SHIFT > HYP_PGTABLE_SHIFT
+#define S2_ENTRY_TABLES_SHIFT	(KVM_PHYS_SHIFT - HYP_PGTABLE_SHIFT)
 #else
-#define PTRS_PER_S2_PGD_SHIFT	(KVM_PHYS_SHIFT - PGDIR_SHIFT)
+#define S2_ENTRY_TABLES_SHIFT	0
 #endif
+#define S2_ENTRY_TABLES		(1 << (S2_ENTRY_TABLES_SHIFT))
+
+/* Number of page table levels we fake to reach the hw pgtable for hyp */
+#define KVM_FAKE_PGTABLE_LEVELS	(CONFIG_PGTABLE_LEVELS - HYP_PGTABLE_LEVELS)
+
+#define PTRS_PER_S2_PGD_SHIFT	(KVM_PHYS_SHIFT - HYP_PGDIR_SHIFT)
 #define PTRS_PER_S2_PGD		(1 << PTRS_PER_S2_PGD_SHIFT)
 #define S2_PGD_ORDER		get_order(PTRS_PER_S2_PGD * sizeof(pgd_t))
 
 #define kvm_pgd_index(addr)	(((addr) >> PGDIR_SHIFT) & (PTRS_PER_S2_PGD - 1))
 
-/*
- * If we are concatenating first level stage-2 page tables, we would have less
- * than or equal to 16 pointers in the fake PGD, because that's what the
- * architecture allows.  In this case, (4 - CONFIG_PGTABLE_LEVELS)
- * represents the first level for the host, and we add 1 to go to the next
- * level (which uses contatenation) for the stage-2 tables.
- */
-#if PTRS_PER_S2_PGD <= 16
-#define KVM_PREALLOC_LEVEL	(4 - CONFIG_PGTABLE_LEVELS + 1)
-#else
-#define KVM_PREALLOC_LEVEL	(0)
-#endif
-
 static inline void *kvm_get_hwpgd(struct kvm *kvm)
 {
 	pgd_t *pgd = kvm->arch.pgd;
 	pud_t *pud;
 
-	if (KVM_PREALLOC_LEVEL == 0)
+	if (KVM_FAKE_PGTABLE_LEVELS == 0)
 		return pgd;
 
 	pud = pud_offset(pgd, 0);
-	if (KVM_PREALLOC_LEVEL == 1)
+	if (HYP_PGTABLE_ENTRY_LEVEL == 1)
 		return pud;
 
-	BUG_ON(KVM_PREALLOC_LEVEL != 2);
+	BUG_ON(HYP_PGTABLE_ENTRY_LEVEL != 2);
 	return pmd_offset(pud, 0);
 }
 
 static inline unsigned int kvm_get_hwpgd_size(void)
 {
-	if (KVM_PREALLOC_LEVEL > 0)
-		return PTRS_PER_S2_PGD * PAGE_SIZE;
 	return PTRS_PER_S2_PGD * sizeof(pgd_t);
 }
 
@@ -207,27 +200,38 @@ static inline pgd_t* kvm_setup_fake_pgd(pgd_t *hwpgd)
 {
 	int i;
 	pgd_t *pgd;
+	pud_t *pud;
 
-	if (!KVM_PREALLOC_LEVEL)
+	if (KVM_FAKE_PGTABLE_LEVELS == 0)
 		return hwpgd;
-	/*
-	 * When KVM_PREALLOC_LEVEL==2, we allocate a single page for
-	 * the PMD and the kernel will use folded pud.
-	 * When KVM_PREALLOC_LEVEL==1, we allocate 2 consecutive PUD
-	 * pages.
-	 */
+
 	pgd = kmalloc(PTRS_PER_S2_PGD * sizeof(pgd_t),
 			GFP_KERNEL | __GFP_ZERO);
 
 	if (!pgd)
 		return ERR_PTR(-ENOMEM);
+	/*
+	 * If the stage-2 entry is two level down from that of the host,
+	 * we are using a 4-level table on host (since HYP_PGTABLE_ENTRY_LEVEL
+	 * cannot be < 2. So, this implies we need to allocat a PUD table
+	 * to map the concatenated PMD tables.
+	 */
+	if (KVM_FAKE_PGTABLE_LEVELS == 2) {
+		pud = (pud_t *)__get_free_pages(GFP_KERNEL | __GFP_ZERO, 0);
+		if (!pud) {
+			kfree(pgd);
+			return ERR_PTR(-ENOMEM);
+		}
+		/* plug the pud into the PGD */
+		pgd_populate(NULL, pgd, pud);
+	}
 
 	/* Plug the HW PGD into the fake one. */
-	for (i = 0; i < PTRS_PER_S2_PGD; i++) {
-		if (KVM_PREALLOC_LEVEL == 1)
+	for (i = 0; i < S2_ENTRY_TABLES; i++) {
+		if (HYP_PGTABLE_ENTRY_LEVEL == 1)
 			pgd_populate(NULL, pgd + i,
 				     (pud_t *)hwpgd + i * PTRS_PER_PUD);
-		else if (KVM_PREALLOC_LEVEL == 2)
+		else if (HYP_PGTABLE_ENTRY_LEVEL == 2)
 			pud_populate(NULL, pud_offset(pgd, 0) + i,
 				     (pmd_t *)hwpgd + i * PTRS_PER_PMD);
 	}
@@ -237,8 +241,12 @@ static inline pgd_t* kvm_setup_fake_pgd(pgd_t *hwpgd)
 
 static inline void kvm_free_fake_pgd(pgd_t *pgd)
 {
-	if (KVM_PREALLOC_LEVEL > 0)
+	if (KVM_FAKE_PGTABLE_LEVELS > 0) {
+		/* free the PUD table */
+		if (KVM_FAKE_PGTABLE_LEVELS == 2)
+			free_page((unsigned long)pud_offset(pgd, 0));
 		kfree(pgd);
+	}
 }
 
 static inline bool kvm_page_empty(void *ptr)
@@ -253,14 +261,14 @@ static inline bool kvm_page_empty(void *ptr)
 #define kvm_pmd_table_empty(kvm, pmdp) (0)
 #else
 #define kvm_pmd_table_empty(kvm, pmdp) \
-	(kvm_page_empty(pmdp) && (!(kvm) || KVM_PREALLOC_LEVEL < 2))
+	(kvm_page_empty(pmdp) && (!(kvm) || HYP_PGTABLE_ENTRY_LEVEL < 2))
 #endif
 
 #ifdef __PAGETABLE_PUD_FOLDED
 #define kvm_pud_table_empty(kvm, pudp) (0)
 #else
 #define kvm_pud_table_empty(kvm, pudp) \
-	(kvm_page_empty(pudp) && (!(kvm) || KVM_PREALLOC_LEVEL < 1))
+	(kvm_page_empty(pudp) && (!(kvm) || HYP_PGTABLE_ENTRY_LEVEL < 1))
 #endif
 
 
-- 
1.7.9.5



From suzuki.poulose at arm.com  Thu Aug 13 04:33:58 2015
From: suzuki.poulose at arm.com (Suzuki K. Poulose)
Date: Thu, 13 Aug 2015 12:33:58 +0100
Subject: [PATCH 08/14] arm64: kvm: Fix {V}TCR_EL2_TG0 mask
In-Reply-To: <1439465645-22584-1-git-send-email-suzuki.poulose@arm.com>
References: <1439465645-22584-1-git-send-email-suzuki.poulose@arm.com>
Message-ID: <1439465645-22584-9-git-send-email-suzuki.poulose@arm.com>

From: "Suzuki K. Poulose" <suzuki.poulose at arm.com>

{V}TCR_EL2_TG0 is a 2bit wide field, where:

 00 - 4K
 01 - 64K
 10 - 16K

But we use only 1 bit, which has worked well so far since
we never cared about 16K. Fix it for 16K support.

Cc: Catalin Marinas <catalin.marinas at arm.com>
Cc: Will Deacon <will.deacon at arm.com>
Cc: Marc Zyngier <marc.zyngier at arm.com>
Cc: Christoffer Dall <christoffer.dall at linaro.org>
Cc: kvmarm at lists.cs.columbia.edu
Acked-by: Mark Rutland <mark.rutland at arm.com>
Signed-off-by: Suzuki K. Poulose <suzuki.poulose at arm.com>
---
 arch/arm64/include/asm/kvm_arm.h |    4 ++--
 1 file changed, 2 insertions(+), 2 deletions(-)

diff --git a/arch/arm64/include/asm/kvm_arm.h b/arch/arm64/include/asm/kvm_arm.h
index ac6fafb..52dc9cc 100644
--- a/arch/arm64/include/asm/kvm_arm.h
+++ b/arch/arm64/include/asm/kvm_arm.h
@@ -98,7 +98,7 @@
 #define TCR_EL2_TBI	(1 << 20)
 #define TCR_EL2_PS	(7 << 16)
 #define TCR_EL2_PS_40B	(2 << 16)
-#define TCR_EL2_TG0	(1 << 14)
+#define TCR_EL2_TG0	(3 << 14)
 #define TCR_EL2_SH0	(3 << 12)
 #define TCR_EL2_ORGN0	(3 << 10)
 #define TCR_EL2_IRGN0	(3 << 8)
@@ -110,7 +110,7 @@
 
 /* VTCR_EL2 Registers bits */
 #define VTCR_EL2_PS_MASK	(7 << 16)
-#define VTCR_EL2_TG0_MASK	(1 << 14)
+#define VTCR_EL2_TG0_MASK	(3 << 14)
 #define VTCR_EL2_TG0_4K		(0 << 14)
 #define VTCR_EL2_TG0_64K	(1 << 14)
 #define VTCR_EL2_SH0_MASK	(3 << 12)
-- 
1.7.9.5



From lee.jones at linaro.org  Thu Aug 13 04:40:05 2015
From: lee.jones at linaro.org (Lee Jones)
Date: Thu, 13 Aug 2015 12:40:05 +0100
Subject: [PATCH v2 5/6] mailbox: Add generic mechanism for testing
 Mailbox Controllers
In-Reply-To: <CABb+yY34i=VUnswUE21vgeQYAGOS=7uwvdnTAFFgYkTV0CFk=w@mail.gmail.com>
References: <1437990272-23111-6-git-send-email-lee.jones@linaro.org>
 <CABb+yY20nQbiEEZeRvWTMUsJ2qgwRn8CrWvnFDSB-b1dgVaAuw@mail.gmail.com>
 <20150812102328.GD18282@x1>
 <CABb+yY0A74Vy3-KOvj0URU_4zb2FAC7Yp3gmEwnFaBrD0mzt0w@mail.gmail.com>
 <20150813091914.GB8782@x1>
 <CABb+yY0cgbtM68-E_Xqgh5O6GRLXESYTLa5WcAwUBoVL3ufrxA@mail.gmail.com>
 <20150813102335.GC8782@x1>
 <CABb+yY3z7p97eOhncQ2i+g6yoYGfDgSN9BDPKmiDaVLa3oPocA@mail.gmail.com>
 <20150813110008.GD8782@x1>
 <CABb+yY34i=VUnswUE21vgeQYAGOS=7uwvdnTAFFgYkTV0CFk=w@mail.gmail.com>
Message-ID: <20150813114005.GF8782@x1>

On Thu, 13 Aug 2015, Jassi Brar wrote:

> On Thu, Aug 13, 2015 at 4:30 PM, Lee Jones <lee.jones at linaro.org> wrote:
> > On Thu, 13 Aug 2015, Jassi Brar wrote:
> >
> >> On Thu, Aug 13, 2015 at 3:53 PM, Lee Jones <lee.jones at linaro.org> wrote:
> >> > On Thu, 13 Aug 2015, Jassi Brar wrote:
> >> >
> >> >> On Thu, Aug 13, 2015 at 2:49 PM, Lee Jones <lee.jones at linaro.org> wrote:
> >> >> > On Thu, 13 Aug 2015, Jassi Brar wrote:
> >> >>
> >> >> >> >> > +
> >> >> >> >> > +static void mbox_test_prepare_message(struct mbox_client *client, void *message)
> >> >> >> >> > +{
> >> >> >> >> > +       struct mbox_test_device *tdev = dev_get_drvdata(client->dev);
> >> >> >> >> > +
> >> >> >> >> > +       if (tdev->mmio)
> >> >> >> >> > +               memcpy(tdev->mmio, message, MBOX_MAX_MSG_LEN);
> >> >> >> >> >
> >> >> >> >> This is unlikely to work. Those platforms that need to send a 2 part
> >> >> >> >> message, they do :
> >> >> >> >> (a) Signal/Command/Target code via some controller register (via
> >> >> >> >> mbox_send_message).
> >> >> >> >> (b) Setup the payload in Shared-Memory (via tx_prepare).
> >> >> >> >>
> >> >> >> >> This test driver assumes both are the same. I think you have to
> >> >> >> >> declare something like
> >> >> >> >
> >> >> >> > This driver assumes that the framework will call client->tx_prepare()
> >> >> >> > first, which satisfies (b).  It then assumes controller->send_data()
> >> >> >> > will be invoked, which will send the platform specific
> >> >> >> > signal/command/target code, which then satisfies (a).
> >> >> >> >
> >> >> >> Yeah, but what would be that code? Who provides that?
> >> >> >>
> >> >> >> > In what way does it assume they are the same?
> >> >> >> >
> >> >> >> notice the 'message' pointer in
> >> >> >> mbox_send_message(tdev->tx_channel, message);
> >> >> >>     and
> >> >> >> memcpy(tdev->mmio, message, MBOX_MAX_MSG_LEN);
> >> >> >>
> >> >> >> >> struct mbox_test_message { /* same for TX and RX */
> >> >> >> >>           unsigned sig_len;
> >> >> >> >>           void *signal;               /* rx/tx via mailbox api */
> >> >> >> >>           unsigned pl_len;
> >> >> >> >>           void *payload;           /* rx/tx via shared-memory */
> >> >> >> >> };
> >> >> >> >
> >> >> >> > How do you think this should be set and use these?
> >> >> >> >
> >> >> >> The userspace would want to specify the command code (32bits or not)
> >> >> >> that would be passed via the fifo/register of the controller. So we
> >> >> >> need signal[]
> >> >> >>
> >> >> >> The data to be passed via share-memory could be provided by userspace
> >> >> >> via the payload[] array.
> >> >> >
> >> >> > Okay, so would the solution be two userspace files 'signal' and
> >> >> > 'message', so in the case of a client specified signal we can write it
> >> >> > into there first.
> >> >> >
> >> >> > echo 255  > signal
> >> >> > echo test > message
> >> >> >
> >> >> > ... or in the case where no signal is required, or the controller
> >> >> > driver taking care of it, we just don't write anything to signal?
> >> >> >
> >> >> file_operations.write() should parse signal and message, coming from
> >> >> userspace, into a local structure before routing them via
> >> >> mbox_send_message and tx_prepare respectively.
> >> >
> >> > Okay.  So before I code this up we should agree on syntax.
> >> >
> >> > How would you like to represent the break between signal and message?
> >> > Obviously ' ' would be a bad idea, as some clients may want to send
> >> > messages with white space contained.  How about '\t' or '\n'?
> >> >
> >> Yeah, I am not a fan of markers and flags either.
> >>
> >> Maybe we should share with userspace
> >>   struct mbox_test_message { /* same for TX and RX */
> >>            unsigned sig_len;
> >>            void __user *signal;        /* rx/tx via mailbox api */
> >>            unsigned pl_len;
> >>            void __user *payload;    /* rx/tx via shared-memory */
> >>   };
> >>
> >> First copy_from_user the structure of length sizof(struct
> >> mbox_test_message) and then copy_from_user length sig_len and pl_len
> >> from signal[] and payload[] respectively (usually ioctls would carry
> >> such data).
> >
> > Simplicity and ease of use should be the goals here.  Testers should
> > not have to write applications to use this driver.  Can we come up
> > with a simple/effective method that uses SYSFS/DEBUGFS please?
> >
> > The easiest way I can think of which avoids markers/separators AND the
> > requirement for users to have to write applications is to have two
> > files, 'signal' and 'message' as mentioned before.  Once both are
> > populated I can get this driver to draft the message appropriately and
> > fire it off.
> >
> And then write to more files for RX data? ... which should also be in
> the form of 'signal' and 'message'.
> 
> BTW like for spi there is a stock application in
> Documentation/spi/spidev_test.c we could do the same?

Coming from personal experience, testing drivers with (even stock)
applications is much more painful that simply writing/reading
(cat/echo) to a file in SYSFS/DEBUGFS.  Particularly if people are
using initramfs or thelike.  If it is possible to use SYSFS/DEBUGFS,
which it is in this case, then I believe that's the route we could go
down.

In answer to your question; we only need those two files.  The reply
can be placed back into 'message' and can be read from there.

Simple to use, simple to code (on both sides), elegant, no overhead.

Win, win, win, win.

-- 
Lee Jones
Linaro STMicroelectronics Landing Team Lead
Linaro.org ? Open source software for ARM SoCs
Follow Linaro: Facebook | Twitter | Blog


From suzuki.poulose at arm.com  Thu Aug 13 04:34:03 2015
From: suzuki.poulose at arm.com (Suzuki K. Poulose)
Date: Thu, 13 Aug 2015 12:34:03 +0100
Subject: [PATCH 13/14] arm64: Add 16K page size support
In-Reply-To: <1439465645-22584-1-git-send-email-suzuki.poulose@arm.com>
References: <1439465645-22584-1-git-send-email-suzuki.poulose@arm.com>
Message-ID: <1439465645-22584-14-git-send-email-suzuki.poulose@arm.com>

From: "Suzuki K. Poulose" <suzuki.poulose at arm.com>

This patch turns on the 16K page support in the kernel. We
support 48bit VA (4 level page tables) and 47bit VA (3 level
page tables).

Cc: Mark Rutland <mark.rutland at arm.com>
Cc: Catalin Marinas <catalin.marinas at arm.com>
Cc: Will Deacon <will.deacon at arm.com>
Cc: Steve Capper <steve.capper at linaro.org>
Signed-off-by: Suzuki K. Poulose <suzuki.poulose at arm.com>
---
 arch/arm64/Kconfig                   |   25 ++++++++++++++++++++-----
 arch/arm64/include/asm/fixmap.h      |    4 +++-
 arch/arm64/include/asm/kvm_arm.h     |   12 ++++++++++++
 arch/arm64/include/asm/page.h        |    2 ++
 arch/arm64/include/asm/sysreg.h      |    2 ++
 arch/arm64/include/asm/thread_info.h |    2 ++
 arch/arm64/kernel/head.S             |    7 ++++++-
 arch/arm64/mm/proc.S                 |    4 +++-
 8 files changed, 50 insertions(+), 8 deletions(-)

diff --git a/arch/arm64/Kconfig b/arch/arm64/Kconfig
index b247897..8327edf 100644
--- a/arch/arm64/Kconfig
+++ b/arch/arm64/Kconfig
@@ -167,7 +167,8 @@ config PGTABLE_LEVELS
 	default 2 if ARM64_64K_PAGES && ARM64_VA_BITS_42
 	default 3 if ARM64_64K_PAGES && ARM64_VA_BITS_48
 	default 3 if ARM64_4K_PAGES && ARM64_VA_BITS_39
-	default 4 if ARM64_4K_PAGES && ARM64_VA_BITS_48
+	default 3 if ARM64_16K_PAGES && ARM64_VA_BITS_47
+	default 4 if !ARM64_64K_PAGES && ARM64_VA_BITS_48
 
 source "init/Kconfig"
 
@@ -444,6 +445,13 @@ config ARM64_4K_PAGES
 	help
 	  This feature enables 4KB pages support.
 
+config ARM64_16K_PAGES
+	bool "16KB"
+	help
+	  The system will use 16KB pages support. AArch32 emulation
+	  requires applications compiled with 16K(or multiple of 16K)
+	  aligned segments.
+
 config ARM64_64K_PAGES
 	bool "64KB"
 	help
@@ -457,6 +465,7 @@ endchoice
 choice
 	prompt "Virtual address space size"
 	default ARM64_VA_BITS_39 if ARM64_4K_PAGES
+	default ARM64_VA_BITS_47 if ARM64_16K_PAGES
 	default ARM64_VA_BITS_42 if ARM64_64K_PAGES
 	help
 	  Allows choosing one of multiple possible virtual address
@@ -471,6 +480,10 @@ config ARM64_VA_BITS_42
 	bool "42-bit"
 	depends on ARM64_64K_PAGES
 
+config ARM64_VA_BITS_47
+	bool "47-bit"
+	depends on ARM64_16K_PAGES
+
 config ARM64_VA_BITS_48
 	bool "48-bit"
 
@@ -480,6 +493,7 @@ config ARM64_VA_BITS
 	int
 	default 39 if ARM64_VA_BITS_39
 	default 42 if ARM64_VA_BITS_42
+	default 47 if ARM64_VA_BITS_47
 	default 48 if ARM64_VA_BITS_48
 
 config CPU_BIG_ENDIAN
@@ -550,7 +564,7 @@ config ARCH_WANT_GENERAL_HUGETLB
 	def_bool y
 
 config ARCH_WANT_HUGE_PMD_SHARE
-	def_bool y if ARM64_4K_PAGES
+	def_bool y if ARM64_4K_PAGES || ARM64_16K_PAGES
 
 config HAVE_ARCH_TRANSPARENT_HUGEPAGE
 	def_bool y
@@ -587,6 +601,7 @@ config XEN
 config FORCE_MAX_ZONEORDER
 	int
 	default "14" if (ARM64_64K_PAGES && TRANSPARENT_HUGEPAGE)
+	default "12" if (ARM64_16K_PAGES && TRANSPARENT_HUGEPAGE)
 	default "11"
 
 menuconfig ARMV8_DEPRECATED
@@ -773,9 +788,9 @@ config COMPAT
 	  the user helper functions, VFP support and the ptrace interface are
 	  handled appropriately by the kernel.
 
-	  If you also enabled CONFIG_ARM64_64K_PAGES, please be aware that you
-	  will only be able to execute AArch32 binaries that were compiled with
-	  64k aligned segments.
+	  If you use a page size other than 4KB(i.e, 16KB or 64KB), please be aware
+	  that you will only be able to execute AArch32 binaries that were compiled
+	  with page size aligned segments.
 
 	  If you want to execute 32-bit userspace applications, say Y.
 
diff --git a/arch/arm64/include/asm/fixmap.h b/arch/arm64/include/asm/fixmap.h
index c0739187..f44a390 100644
--- a/arch/arm64/include/asm/fixmap.h
+++ b/arch/arm64/include/asm/fixmap.h
@@ -55,8 +55,10 @@ enum fixed_addresses {
 	 * Temporary boot-time mappings, used by early_ioremap(),
 	 * before ioremap() is functional.
 	 */
-#ifdef CONFIG_ARM64_64K_PAGES
+#if	defined(CONFIG_ARM64_64K_PAGES)
 #define NR_FIX_BTMAPS		4
+#elif	defined (CONFIG_ARM64_16K_PAGES)
+#define NR_FIX_BTMAPS		16
 #else
 #define NR_FIX_BTMAPS		64
 #endif
diff --git a/arch/arm64/include/asm/kvm_arm.h b/arch/arm64/include/asm/kvm_arm.h
index dcaf799..4d6a022 100644
--- a/arch/arm64/include/asm/kvm_arm.h
+++ b/arch/arm64/include/asm/kvm_arm.h
@@ -113,6 +113,7 @@
 #define VTCR_EL2_TG0_MASK	(3 << 14)
 #define VTCR_EL2_TG0_4K		(0 << 14)
 #define VTCR_EL2_TG0_64K	(1 << 14)
+#define VTCR_EL2_TG0_16K	(2 << 14)
 #define VTCR_EL2_SH0_MASK	(3 << 12)
 #define VTCR_EL2_SH0_INNER	(3 << 12)
 #define VTCR_EL2_ORGN0_MASK	(3 << 10)
@@ -134,6 +135,8 @@
  *
  * Note that when using 4K pages, we concatenate two first level page tables
  * together.
+ * With 16K pages, we concatenate 16 first level page tables and enter at
+ * level 2.
  *
  * The magic numbers used for VTTBR_X in this patch can be found in Tables
  * D4-23 and D4-25 in ARM DDI 0487A.b.
@@ -151,6 +154,15 @@
 #define VTCR_EL2_FLAGS		(VTCR_EL2_TG0_64K | VTCR_EL2_SL0_LVL1 | \
 				 VTCR_EL2_COMMON_BITS)
 #define VTTBR_X		(38 - VTCR_EL2_T0SZ_40B)
+#elif defined(CONFIG_ARM64_16K_PAGES)
+/*
+ * Stage2 translation configuration:
+ * 16kB pages (TG0 = 2)
+ * 2 level page tables (SL0 = 1)
+ */
+#define VTCR_EL2_FLAGS		(VTCR_EL2_TG0_16K | VTCR_EL2_SL0_LVL1 | \
+				 VTCR_EL2_COMMON_BITS)
+#define VTTBR_X			(42 - VTCR_EL2_T0SZ_40B)
 #else
 /*
  * Stage2 translation configuration:
diff --git a/arch/arm64/include/asm/page.h b/arch/arm64/include/asm/page.h
index 3c9ce8c..6aee732 100644
--- a/arch/arm64/include/asm/page.h
+++ b/arch/arm64/include/asm/page.h
@@ -22,6 +22,8 @@
 /* PAGE_SHIFT determines the page size */
 #ifdef CONFIG_ARM64_64K_PAGES
 #define PAGE_SHIFT		16
+#elif defined(CONFIG_ARM64_16K_PAGES)
+#define PAGE_SHIFT		14
 #else
 #define PAGE_SHIFT		12
 #endif
diff --git a/arch/arm64/include/asm/sysreg.h b/arch/arm64/include/asm/sysreg.h
index e01d323..310592c 100644
--- a/arch/arm64/include/asm/sysreg.h
+++ b/arch/arm64/include/asm/sysreg.h
@@ -89,8 +89,10 @@ static inline void config_sctlr_el1(u32 clear, u32 set)
 
 #define ID_AA64MMFR0_TGran4_SHIFT	28
 #define ID_AA64MMFR0_TGran64_SHIFT	24
+#define ID_AA64MMFR0_TGran16_SHIFT	20
 
 #define ID_AA64MMFR0_TGran4_ENABLED	0x0
 #define ID_AA64MMFR0_TGran64_ENABLED	0x0
+#define ID_AA64MMFR0_TGran16_ENABLED	0x1
 
 #endif	/* __ASM_SYSREG_H */
diff --git a/arch/arm64/include/asm/thread_info.h b/arch/arm64/include/asm/thread_info.h
index d9c8c9f..338a4ac 100644
--- a/arch/arm64/include/asm/thread_info.h
+++ b/arch/arm64/include/asm/thread_info.h
@@ -25,6 +25,8 @@
 
 #ifdef CONFIG_ARM64_4K_PAGES
 #define THREAD_SIZE_ORDER	2
+#elif defined(CONFIG_ARM64_16K_PAGES)
+#define THREAD_SIZE_ORDER	0
 #endif
 
 #define THREAD_SIZE		16384
diff --git a/arch/arm64/kernel/head.S b/arch/arm64/kernel/head.S
index 0cb04db..959100b 100644
--- a/arch/arm64/kernel/head.S
+++ b/arch/arm64/kernel/head.S
@@ -614,7 +614,12 @@ ENDPROC(__secondary_switched)
 #define ID_AA64MMFR0_TGran_SHIFT	ID_AA64MMFR0_TGran64_SHIFT
 #define ID_AA64MMFR0_TGran_ENABLED	ID_AA64MMFR0_TGran64_ENABLED
 
-#else
+#elif	defined(CONFIG_ARM64_16K_PAGES)
+
+#define ID_AA64MMFR0_TGran_SHIFT	ID_AA64MMFR0_TGran16_SHIFT
+#define ID_AA64MMFR0_TGran_ENABLED	ID_AA64MMFR0_TGran16_ENABLED
+
+#elif	defined(CONFIG_ARM64_4K_PAGES)
 
 #define ID_AA64MMFR0_TGran_SHIFT	ID_AA64MMFR0_TGran4_SHIFT
 #define ID_AA64MMFR0_TGran_ENABLED	ID_AA64MMFR0_TGran4_ENABLED
diff --git a/arch/arm64/mm/proc.S b/arch/arm64/mm/proc.S
index 6e8765a..182bced 100644
--- a/arch/arm64/mm/proc.S
+++ b/arch/arm64/mm/proc.S
@@ -30,7 +30,9 @@
 
 #ifdef CONFIG_ARM64_64K_PAGES
 #define TCR_TG_FLAGS	TCR_TG0_64K | TCR_TG1_64K
-#else
+#elif defined(CONFIG_ARM64_16K_PAGES)
+#define TCR_TG_FLAGS	TCR_TG0_16K | TCR_TG1_16K
+#else /* CONFIG_ARM64_4K_PAGES */
 #define TCR_TG_FLAGS	TCR_TG0_4K | TCR_TG1_4K
 #endif
 
-- 
1.7.9.5



From steve.capper at linaro.org  Thu Aug 13 04:42:50 2015
From: steve.capper at linaro.org (Steve Capper)
Date: Thu, 13 Aug 2015 12:42:50 +0100
Subject: [PATCH v8 3/7] arm64: Kprobes with single stepping support
In-Reply-To: <1439254364-15362-4-git-send-email-dave.long@linaro.org>
References: <1439254364-15362-1-git-send-email-dave.long@linaro.org>
 <1439254364-15362-4-git-send-email-dave.long@linaro.org>
Message-ID: <CAPvkgC2qXiVUYjvUCQvmb6FFoAqCi-aP1eGay8_uWpM2C9XfFA@mail.gmail.com>

Hi David,

On 11 August 2015 at 01:52, David Long <dave.long at linaro.org> wrote:
> From: Sandeepa Prabhu <sandeepa.s.prabhu at gmail.com>
>
> Add support for basic kernel probes(kprobes) and jump probes
> (jprobes) for ARM64.
>
> Kprobes utilizes software breakpoint and single step debug
> exceptions supported on ARM v8.
>
> A software breakpoint is placed at the probe address to trap the
> kernel execution into the kprobe handler.
>
> ARM v8 supports enabling single stepping before the break exception
> return (ERET), with next PC in exception return address (ELR_EL1). The
> kprobe handler prepares an executable memory slot for out-of-line
> execution with a copy of the original instruction being probed, and
> enables single stepping. The PC is set to the out-of-line slot address
> before the ERET. With this scheme, the instruction is executed with the
> exact same register context except for the PC (and DAIF) registers.
>
> Debug mask (PSTATE.D) is enabled only when single stepping a recursive
> kprobe, e.g.: during kprobes reenter so that probed instruction can be
> single stepped within the kprobe handler -exception- context.
> The recursion depth of kprobe is always 2, i.e. upon probe re-entry,
> any further re-entry is prevented by not calling handlers and the case
> counted as a missed kprobe).
>
> Single stepping from the x-o-l slot has a drawback for PC-relative accesses
> like branching and symbolic literals access as the offset from the new PC
> (slot address) may not be ensured to fit in the immediate value of
> the opcode. Such instructions need simulation, so reject
> probing them.
>
> Instructions generating exceptions or cpu mode change are rejected
> for probing.
>
> Instructions using Exclusive Monitor are rejected too.
>
> System instructions are mostly enabled for stepping, except MSR/MRS
> accesses to "DAIF" flags in PSTATE, which are not safe for
> probing.
>
> Thanks to Steve Capper and Pratyush Anand for several suggested
> Changes.
>
> Signed-off-by: Sandeepa Prabhu <sandeepa.s.prabhu at gmail.com>
> Signed-off-by: Steve Capper <steve.capper at linaro.org>

Please remove my SoB, we can replace it with a Reviewed-by hopefully soon :-).


> Signed-off-by: David A. Long <dave.long at linaro.org>
> ---
>  arch/arm64/Kconfig                      |   1 +
>  arch/arm64/include/asm/debug-monitors.h |   5 +
>  arch/arm64/include/asm/kprobes.h        |  62 ++++
>  arch/arm64/include/asm/probes.h         |  50 +++
>  arch/arm64/include/asm/ptrace.h         |   3 +-
>  arch/arm64/kernel/Makefile              |   1 +
>  arch/arm64/kernel/debug-monitors.c      |  35 ++-
>  arch/arm64/kernel/kprobes-arm64.c       |  68 ++++
>  arch/arm64/kernel/kprobes-arm64.h       |  28 ++
>  arch/arm64/kernel/kprobes.c             | 537 ++++++++++++++++++++++++++++++++
>  arch/arm64/kernel/kprobes.h             |  24 ++
>  arch/arm64/kernel/vmlinux.lds.S         |   1 +
>  arch/arm64/mm/fault.c                   |  25 ++
>  13 files changed, 829 insertions(+), 11 deletions(-)
>  create mode 100644 arch/arm64/include/asm/kprobes.h
>  create mode 100644 arch/arm64/include/asm/probes.h
>  create mode 100644 arch/arm64/kernel/kprobes-arm64.c
>  create mode 100644 arch/arm64/kernel/kprobes-arm64.h
>  create mode 100644 arch/arm64/kernel/kprobes.c
>  create mode 100644 arch/arm64/kernel/kprobes.h
>

[...]

> +
> +void __kprobes kprobe_handler(struct pt_regs *regs)
> +{
> +       struct kprobe *p, *cur;
> +       struct kprobe_ctlblk *kcb;
> +       unsigned long addr = instruction_pointer(regs);
> +
> +       kcb = get_kprobe_ctlblk();
> +       cur = kprobe_running();
> +
> +       p = get_kprobe((kprobe_opcode_t *) addr);
> +
> +       if (p) {
> +               if (cur) {
> +                       if (reenter_kprobe(p, regs, kcb))
> +                               return;
> +               } else if (!p->ainsn.check_condn ||
> +                          p->ainsn.check_condn(p, regs)) {
> +                       /* Probe hit and conditional execution check ok. */
> +                       set_current_kprobe(p);
> +                       kcb->kprobe_status = KPROBE_HIT_ACTIVE;
> +
> +                       /*
> +                        * If we have no pre-handler or it returned 0, we
> +                        * continue with normal processing.  If we have a
> +                        * pre-handler and it returned non-zero, it prepped
> +                        * for calling the break_handler below on re-entry,
> +                        * so get out doing nothing more here.
> +                        *
> +                        * pre_handler can hit a breakpoint and can step thru
> +                        * before return, keep PSTATE D-flag enabled until
> +                        * pre_handler return back.
> +                        */
> +                       if (!p->pre_handler || !p->pre_handler(p, regs)) {
> +                               kcb->kprobe_status = KPROBE_HIT_SS;
> +                               setup_singlestep(p, regs, kcb, 0);
> +                               return;
> +                       }
> +               } else {
> +                       /*
> +                        * Breakpoint hit but conditional check failed,
> +                        * so just skip the instruction (NOP behaviour)
> +                        */
> +                       skip_singlestep_missed(kcb, regs);
> +                       return;

Sorry, I'm still unconvinced by this. :-(

I had a play with kprobes on my x86 box and my arm64 devboard running
this series.

On x86, I had the following two consecutive instructions from do_fork:

ffffffff810a0972:       f7 c7 00 00 80 00       test   $0x800000,%edi
ffffffff810a0978:       75 42                   jne
ffffffff810a09bc <do_fork+0x7c>

I had the kprobes set up as follows:
# cat kprobe_events
p:kprobes/probe1 0xffffffff810a0972
p:kprobes/probe2 0xffffffff810a0978

Now on my arm64 devboard in do_fork, I was interested in the following
two consecutive instructions:
ffffffc0000bbf54:       f9402ba1        ldr     x1, [x29,#80]
ffffffc0000bbf58:       37b80215        tbnz    w21, #23,
ffffffc0000bbf98 <_do_fork+0x80>

Which had kprobes set up thusly:
# cat kprobe_events
p:kprobes/armprobe1 0xffffffc0000bbf54
p:kprobes/armprobe2 0xffffffc0000bbf58

The last instruction in each pair corresponds to the same line of C
code in _do_fork:
"        if (!(clone_flags & CLONE_UNTRACED)) {"
So I would expect them to behave very similarly on both systems.

Now on x86, if I take a look at kprobe_profile:
# cat kprobe_profile
  probe1                                                    72               0
  probe2                                                    72               0

And for arm64:
# cat kprobe_profile
  armprobe1                                                 40               0
  armprobe2                                                  0               0

For both systems I would expect the counts of the two probes to be
identical as both instructions are "hit".
On x86 this appears to be the case, but not for arm64.

I know arm and arm64 are the same; but I do think their behaviour
should match x86 in this regard.
(i.e. I believe arm should be changed too).

Cheers,
--
Steve


From emil.l.velikov at gmail.com  Thu Aug 13 04:45:09 2015
From: emil.l.velikov at gmail.com (Emil Velikov)
Date: Thu, 13 Aug 2015 12:45:09 +0100
Subject: [PATCH 3/7] drm/vc4: Add KMS support for Raspberry Pi.
In-Reply-To: <1439427380-2436-4-git-send-email-eric@anholt.net>
References: <1439427380-2436-1-git-send-email-eric@anholt.net>
 <1439427380-2436-4-git-send-email-eric@anholt.net>
Message-ID: <CACvgo527EEmC-iMf3waUHpBXVZzu2fNjk_UtHQENUGmd8fepYQ@mail.gmail.com>

On 13 August 2015 at 01:56, Eric Anholt <eric at anholt.net> wrote:
> This is the start of a full VC4 driver.  Right now this just supports
> configuring the display using a pre-existing video mode (because
> changing the pixel clock isn't available yet, and doesn't work when it
> is).  However, this is enough for fbcon and bringing up X using
> xf86-video-modesetting.
>
> Signed-off-by: Eric Anholt <eric at anholt.net>
...
> --- /dev/null
> +++ b/drivers/gpu/drm/vc4/Makefile
> @@ -0,0 +1,18 @@
> +ccflags-y := -Iinclude/drm
> +
> +# Please keep these build lists sorted!
> +
> +# core driver code
> +vc4-y := \
> +       vc4_bo.o \
> +       vc4_crtc.o \
> +       vc4_drv.o \
> +       vc4_kms.o \
> +       vc4_hdmi.o \
> +       vc4_hvs.o \
> +       vc4_plane.o \
> +       $()
> +
In case anyone is curious - this is the first sentinel in the whole
kernel (some 2000+ Makefiles) :-)

-Emil


From guohanjun at huawei.com  Thu Aug 13 04:50:08 2015
From: guohanjun at huawei.com (Hanjun Guo)
Date: Thu, 13 Aug 2015 19:50:08 +0800
Subject: [PATCH 3/3] Add ACPI bindings for the EHCI platform driver.
In-Reply-To: <1439416290-21228-4-git-send-email-jeremy.linton@arm.com>
References: <1439416290-21228-1-git-send-email-jeremy.linton@arm.com>
 <1439416290-21228-4-git-send-email-jeremy.linton@arm.com>
Message-ID: <55CC8470.5070007@huawei.com>

Hi Jeremy,

Just minor comments below. (resend as it's blocked by mailist)

On 2015/8/13 5:51, Jeremy Linton wrote:
> This enables USB on the ARM juno board when booted with
> an ACPI kernel. The PNP id comes from the PNP/ACPI registry
> and describes a EHCI controller without debug.
>
> Signed-off-by: Jeremy Linton <jeremy.linton at arm.com>
> ---
>  drivers/usb/host/ehci-platform.c | 9 +++++++++
>  1 file changed, 9 insertions(+)
>
> diff --git a/drivers/usb/host/ehci-platform.c b/drivers/usb/host/ehci-platform.c
> index 82e396f..1807baa 100644
> --- a/drivers/usb/host/ehci-platform.c
> +++ b/drivers/usb/host/ehci-platform.c
> @@ -27,6 +27,7 @@
>  #include <linux/io.h>
>  #include <linux/module.h>
>  #include <linux/of.h>
> +#include <linux/acpi.h>

this file list the head file in alphabetical order, I think it's
better to follow that rule.

>  #include <linux/phy/phy.h>
>  #include <linux/platform_device.h>
>  #include <linux/reset.h>
> @@ -382,6 +383,13 @@ static const struct of_device_id vt8500_ehci_ids[] = {
>  };
>  MODULE_DEVICE_TABLE(of, vt8500_ehci_ids);
>  
> +static const struct acpi_device_id ehci_acpi_match[] = {
> +	{ "PNP0D20", 0 },
> +	{ }
> +};
> +MODULE_DEVICE_TABLE(acpi, ehci_acpi_match);
> +
> +

Single empty line will be fine :)

>  static const struct platform_device_id ehci_platform_table[] = {
>  	{ "ehci-platform", 0 },
>  	{ }
> @@ -400,6 +408,7 @@ static struct platform_driver ehci_platform_driver = {
>  		.name	= "ehci-platform",
>  		.pm	= &ehci_platform_pm_ops,
>  		.of_match_table = vt8500_ehci_ids,
> +		.acpi_match_table = ACPI_PTR(ehci_acpi_match),
>  	}
>  };
>  

With that minor fixes,

Reviewed-by: Hanjun Guo <hanjun.guo at linaro.org>

Thanks
Hanjun




From robin.murphy at arm.com  Thu Aug 13 04:57:07 2015
From: robin.murphy at arm.com (Robin Murphy)
Date: Thu, 13 Aug 2015 12:57:07 +0100
Subject: [PATCH 1/2] Add a matching set of device_ functions for
 determining mac/phy
In-Reply-To: <1439417187-21411-2-git-send-email-jeremy.linton@arm.com>
References: <1439417187-21411-1-git-send-email-jeremy.linton@arm.com>
 <1439417187-21411-2-git-send-email-jeremy.linton@arm.com>
Message-ID: <55CC8613.1040709@arm.com>

Hi Jeremy,

On 12/08/15 23:06, Jeremy Linton wrote:
[...]
> +static void *device_get_mac_addr(struct device *dev,
> +				 const char *name, char *addr,
> +				 int alen)
> +{
> +	int ret = device_property_read_u8_array(dev, name, addr, alen);
> +
> +	if (ret == 0 && is_valid_ether_addr(addr))
> +		return addr;
> +	return NULL;
> +}

Not sure I understand the logic here - "return the same thing we were 
given if we updated it, or null if we didn't". It's only indicating 
success/failure (the caller can perfectly well cast its own buffer to a 
void * if it needs to), so why wouldn't you just return a normal int 
error code?

> +/**
> + * Search the device tree for the best MAC address to use.  'mac-address' is
> + * checked first, because that is supposed to contain to "most recent" MAC
> + * address. If that isn't set, then 'local-mac-address' is checked next,
> + * because that is the default address.  If that isn't set, then the obsolete
> + * 'address' is checked, just in case we're using an old device tree.
> + *
> + * Note that the 'address' property is supposed to contain a virtual address of
> + * the register set, but some DTS files have redefined that property to be the
> + * MAC address.
> + *
> + * All-zero MAC addresses are rejected, because those could be properties that
> + * exist in the device tree, but were not set by U-Boot.  For example, the
> + * DTS could define 'mac-address' and 'local-mac-address', with zero MAC
> + * addresses.  Some older U-Boots only initialized 'local-mac-address'.  In
> + * this case, the real MAC is in 'local-mac-address', and 'mac-address' exists
> + * but is all zeros.
> +*/
> +void *device_get_mac_address(struct device *dev, char *addr, int alen)
> +{
> +	addr = device_get_mac_addr(dev, "mac-address", addr, alen);
> +	if (addr)
> +		return addr;
> +
> +	addr = device_get_mac_addr(dev, "local-mac-address", addr, alen);
> +	if (addr)
> +		return addr;
> +
> +	return device_get_mac_addr(dev, "address", addr, alen);
> +}
> +EXPORT_SYMBOL(device_get_mac_address);

Same here, it's not at all apparent why this should return a void * 
instead of an int (or even possibly bool). of_get_mac_address is giving 
its caller back a _new_ pointer they didn't know about before; this isn't.

Robin.



From leilk.liu at mediatek.com  Thu Aug 13 05:06:41 2015
From: leilk.liu at mediatek.com (Leilk Liu)
Date: Thu, 13 Aug 2015 20:06:41 +0800
Subject: [PATCH] spi: Mediatek: fixup cpu_to_le32 incorrect usage
Message-ID: <1439467601-10209-1-git-send-email-leilk.liu@mediatek.com>

writel() already does a cpu_to_le32 conversion, so
remove cpu_to_le32().

Signed-off-by: Leilk Liu <leilk.liu at mediatek.com>
---
 drivers/spi/spi-mt65xx.c | 6 ++----
 1 file changed, 2 insertions(+), 4 deletions(-)

diff --git a/drivers/spi/spi-mt65xx.c b/drivers/spi/spi-mt65xx.c
index ae645fa..519f50c 100644
--- a/drivers/spi/spi-mt65xx.c
+++ b/drivers/spi/spi-mt65xx.c
@@ -359,11 +359,9 @@ static void mtk_spi_setup_dma_addr(struct spi_master *master,
 	struct mtk_spi *mdata = spi_master_get_devdata(master);
 
 	if (mdata->tx_sgl)
-		writel((__force u32)cpu_to_le32(xfer->tx_dma),
-		       mdata->base + SPI_TX_SRC_REG);
+		writel(xfer->tx_dma, mdata->base + SPI_TX_SRC_REG);
 	if (mdata->rx_sgl)
-		writel((__force u32)cpu_to_le32(xfer->rx_dma),
-		       mdata->base + SPI_RX_DST_REG);
+		writel(xfer->rx_dma, mdata->base + SPI_RX_DST_REG);
 }
 
 static int mtk_spi_fifo_transfer(struct spi_master *master,
-- 
1.8.1.1.dirty



From linus.walleij at linaro.org  Thu Aug 13 05:14:33 2015
From: linus.walleij at linaro.org (Linus Walleij)
Date: Thu, 13 Aug 2015 14:14:33 +0200
Subject: [PATCH 1/2] drivers: PL061: add support for platform driver
 probing
In-Reply-To: <1438614811.2338188.346456017.5D258EC5@webmail.messagingengine.com>
References: <1438585198-8764-1-git-send-email-zhaoshenglong@huawei.com>
 <1438585198-8764-2-git-send-email-zhaoshenglong@huawei.com>
 <CACRpkdY6ZfB-gnnr49He+BYELy4fhiV0g5jkEHhyVsJOc_SBFw@mail.gmail.com>
 <1438614811.2338188.346456017.5D258EC5@webmail.messagingengine.com>
Message-ID: <CACRpkdYmeXvXCrJPxCJCDfCG_=MmopmyAe5mgCPoB_S02ERTLg@mail.gmail.com>

On Mon, Aug 3, 2015 at 5:13 PM, Graeme Gregory <gg at slimlogic.co.uk> wrote:
> On Mon, 3 Aug 2015, at 01:40 PM, Linus Walleij wrote:
>> On Mon, Aug 3, 2015 at 8:59 AM, Shannon Zhao <zhaoshenglong at huawei.com>
>> wrote:
>>
>> > From: Shannon Zhao <shannon.zhao at linaro.org>
>> >
>> > Since PL061 currently only supports AMBA driver, to support using GPIO
>> > PL061 by DT or ACPI, it needs to add support for platform driver.
>> > A DT binding is provided with this patch, ACPI support is added in a
>> > separate one.
>> >
>> > Signed-off-by: Shannon Zhao <zhaoshenglong at huawei.com>
>> > Signed-off-by: Shannon Zhao <shannon.zhao at linaro.org>
>>
>> I already stated in 0/2 what the problem is with this, and it's obviously
>> adding
>> a huge codechunk, very similar to the AMBA probe path.
>>
>> We need to investigate if ACPI can just spawn AMBA/PrimeCell type devices
>> instead.
>
> AMBA DT support is a hideous hack, we had kind of hoped to avoid doing
> that in ACPI.

Define what you mean with "hideous hack".

I think it is elegant. It combines the DT aspect of telling where the
device is with the Plug-and-play aspect of reading the 0xB105F00D
magic in the PrimeCells very nicely. With an optional override
mechanism. It's nice.

The runtime PM stuff and pclk handling that Russell and also Ulf
has worked on is very helpful and takes out a lot of codelines
in a lot of drivers. Also very nice.

> If you notice ARM already updated pl011 driver to support platform
> device type probing this seems to be the way to go.

Just because there is a precedent does not mean it is good.

Continuing with this adds 100+ lines of hairy initialization to
every AMBA driver.

What needs to happen is stop this and make ACPI spawn
AMBA devices for PrimeCells, and move the serial port over
to that.

A compromise may be to have something that probes a list
of these platform devices in drivers/acpi/ and spawn a
corresponding AMBA device for it. It will still save codelines in
all other subsystems and lower maintenance for the
subsystem maintainers.

Yours,
Linus Walleij


From linus.walleij at linaro.org  Thu Aug 13 05:18:21 2015
From: linus.walleij at linaro.org (Linus Walleij)
Date: Thu, 13 Aug 2015 14:18:21 +0200
Subject: [PATCH] pinctrl/mediatek: fix spelling mistake in dev_err error
 message
In-Reply-To: <1438557045-3590-1-git-send-email-colin.king@canonical.com>
References: <1438557045-3590-1-git-send-email-colin.king@canonical.com>
Message-ID: <CACRpkdZWcsr0uWe5Zyo18YHvToPxM3W=ePA=SG35uBEg+EEx3w@mail.gmail.com>

On Mon, Aug 3, 2015 at 1:10 AM, Colin King <colin.king at canonical.com> wrote:

> From: Colin Ian King <colin.king at canonical.com>
>
> Trivial change, fix spelling mistake 'invaild' -> 'invalid' in
> dev_err message.
>
> Signed-off-by: Colin Ian King <colin.king at canonical.com>

Patch applied with Hongzhou's ACK.

Yours,
Linus Walleij


From eric.auger at linaro.org  Thu Aug 13 05:17:38 2015
From: eric.auger at linaro.org (Eric Auger)
Date: Thu, 13 Aug 2015 14:17:38 +0200
Subject: [PATCH v2 07/15] KVM: arm64: handle ITS related GICv3
 redistributor registers
In-Reply-To: <1436538111-4294-8-git-send-email-andre.przywara@arm.com>
References: <1436538111-4294-1-git-send-email-andre.przywara@arm.com>
 <1436538111-4294-8-git-send-email-andre.przywara@arm.com>
Message-ID: <55CC8AE2.2070807@linaro.org>

On 07/10/2015 04:21 PM, Andre Przywara wrote:
> In the GICv3 redistributor there are the PENDBASER and PROPBASER
> registers which we did not emulate so far, as they only make sense
> when having an ITS. In preparation for that emulate those MMIO
> accesses by storing the 64-bit data written into it into a variable
> which we later read in the ITS emulation.
> 
> Signed-off-by: Andre Przywara <andre.przywara at arm.com>
> ---
>  include/kvm/arm_vgic.h      |  8 ++++++++
>  virt/kvm/arm/vgic-v3-emul.c | 44 ++++++++++++++++++++++++++++++++++++++++++++
>  virt/kvm/arm/vgic.c         | 35 +++++++++++++++++++++++++++++++++++
>  virt/kvm/arm/vgic.h         |  4 ++++
>  4 files changed, 91 insertions(+)
> 
> diff --git a/include/kvm/arm_vgic.h b/include/kvm/arm_vgic.h
> index 3ee063b..8c6cb0e 100644
> --- a/include/kvm/arm_vgic.h
> +++ b/include/kvm/arm_vgic.h
> @@ -256,6 +256,14 @@ struct vgic_dist {
>  	struct vgic_vm_ops	vm_ops;
>  	struct vgic_io_device	dist_iodev;
>  	struct vgic_io_device	*redist_iodevs;
> +
> +	/* Address of LPI configuration table shared by all redistributors */
> +	u64			propbaser;
> +
> +	/* Addresses of LPI pending tables per redistributor */
> +	u64			*pendbaser;
> +
> +	bool			lpis_enabled;
>  };
>  
>  struct vgic_v2_cpu_if {
> diff --git a/virt/kvm/arm/vgic-v3-emul.c b/virt/kvm/arm/vgic-v3-emul.c
> index a8cf669..5269ad1 100644
> --- a/virt/kvm/arm/vgic-v3-emul.c
> +++ b/virt/kvm/arm/vgic-v3-emul.c
> @@ -651,6 +651,38 @@ static bool handle_mmio_cfg_reg_redist(struct kvm_vcpu *vcpu,
>  	return vgic_handle_cfg_reg(reg, mmio, offset);
>  }
>  
> +/* We don't trigger any actions here, just store the register value */
> +static bool handle_mmio_propbaser_redist(struct kvm_vcpu *vcpu,
> +					 struct kvm_exit_mmio *mmio,
> +					 phys_addr_t offset)
> +{
> +	struct vgic_dist *dist = &vcpu->kvm->arch.vgic;
> +	int mode = ACCESS_READ_VALUE;
> +
> +	/* Storing a value with LPIs already enabled is undefined */
> +	mode |= dist->lpis_enabled ? ACCESS_WRITE_IGNORED : ACCESS_WRITE_VALUE;
> +	vgic_handle_base_register(vcpu, mmio, offset, &dist->propbaser, mode);
> +
> +	return false;
> +}
> +
> +/* We don't trigger any actions here, just store the register value */
> +static bool handle_mmio_pendbaser_redist(struct kvm_vcpu *vcpu,
> +					 struct kvm_exit_mmio *mmio,
> +					 phys_addr_t offset)
> +{
> +	struct kvm_vcpu *rdvcpu = mmio->private;
> +	struct vgic_dist *dist = &vcpu->kvm->arch.vgic;
> +	int mode = ACCESS_READ_VALUE;
> +
> +	/* Storing a value with LPIs already enabled is undefined */
> +	mode |= dist->lpis_enabled ? ACCESS_WRITE_IGNORED : ACCESS_WRITE_VALUE;
> +	vgic_handle_base_register(vcpu, mmio, offset,
> +				  &dist->pendbaser[rdvcpu->vcpu_id], mode);
> +
> +	return false;
> +}
> +
>  #define SGI_base(x) ((x) + SZ_64K)
>  
>  static const struct vgic_io_range vgic_redist_ranges[] = {
> @@ -679,6 +711,18 @@ static const struct vgic_io_range vgic_redist_ranges[] = {
>  		.handle_mmio    = handle_mmio_raz_wi,
>  	},
>  	{
> +		.base		= GICR_PENDBASER,
> +		.len		= 0x08,
> +		.bits_per_irq	= 0,
> +		.handle_mmio	= handle_mmio_pendbaser_redist,
> +	},
> +	{
> +		.base		= GICR_PROPBASER,
> +		.len		= 0x08,
> +		.bits_per_irq	= 0,
> +		.handle_mmio	= handle_mmio_propbaser_redist,
> +	},
> +	{
>  		.base           = GICR_IDREGS,
>  		.len            = 0x30,
>  		.bits_per_irq   = 0,
> diff --git a/virt/kvm/arm/vgic.c b/virt/kvm/arm/vgic.c
> index 15e447f..49ee92b 100644
> --- a/virt/kvm/arm/vgic.c
> +++ b/virt/kvm/arm/vgic.c
> @@ -446,6 +446,41 @@ void vgic_reg_access(struct kvm_exit_mmio *mmio, u32 *reg,
>  	}
>  }
>  
> +/* handle a 64-bit register access */
> +void vgic_handle_base_register(struct kvm_vcpu *vcpu,
> +			       struct kvm_exit_mmio *mmio,
> +			       phys_addr_t offset, u64 *basereg,
> +			       int mode)
> +{
why do we have vcpu in the proto? I don't see it used. Also if it were
can't we fetch it from mmio->private?

why not renaming this into something like vgic_reg64_access as par
vgic_reg_access 32b flavor above. vgic_handle* usually is the name of
the region handler returning bool?


> +	u32 reg;
> +	u64 breg;
> +
> +	switch (offset & ~3) {
> +	case 0x00:
> +		breg = *basereg;
> +		reg = lower_32_bits(breg);
> +		vgic_reg_access(mmio, &reg, offset & 3, mode);
> +		if (mmio->is_write && (mode & ACCESS_WRITE_VALUE)) {
> +			breg &= GENMASK_ULL(63, 32);
> +			breg |= reg;
> +			*basereg = breg;
> +		}
> +		break;
> +	case 0x04:
> +		breg = *basereg;
> +		reg = upper_32_bits(breg);
> +		vgic_reg_access(mmio, &reg, offset & 3, mode);
> +		if (mmio->is_write && (mode & ACCESS_WRITE_VALUE)) {
> +			breg  = lower_32_bits(breg);
> +			breg |= (u64)reg << 32;
> +			*basereg = breg;
> +		}
> +		break;
> +	}
> +}
> +
> +
> +
some spare white lines

Best Regards

Eric
>  bool handle_mmio_raz_wi(struct kvm_vcpu *vcpu, struct kvm_exit_mmio *mmio,
>  			phys_addr_t offset)
>  {
> diff --git a/virt/kvm/arm/vgic.h b/virt/kvm/arm/vgic.h
> index a093f5c..b2d791c 100644
> --- a/virt/kvm/arm/vgic.h
> +++ b/virt/kvm/arm/vgic.h
> @@ -71,6 +71,10 @@ void vgic_reg_access(struct kvm_exit_mmio *mmio, u32 *reg,
>  		     phys_addr_t offset, int mode);
>  bool handle_mmio_raz_wi(struct kvm_vcpu *vcpu, struct kvm_exit_mmio *mmio,
>  			phys_addr_t offset);
> +void vgic_handle_base_register(struct kvm_vcpu *vcpu,
> +			       struct kvm_exit_mmio *mmio,
> +			       phys_addr_t offset, u64 *basereg,
> +			       int mode);
>  
>  static inline
>  u32 mmio_data_read(struct kvm_exit_mmio *mmio, u32 mask)
> 



From eric.auger at linaro.org  Thu Aug 13 05:17:47 2015
From: eric.auger at linaro.org (Eric Auger)
Date: Thu, 13 Aug 2015 14:17:47 +0200
Subject: [PATCH v2 06/15] KVM: arm64: Introduce new MMIO region for the
 ITS base address
In-Reply-To: <1436538111-4294-7-git-send-email-andre.przywara@arm.com>
References: <1436538111-4294-1-git-send-email-andre.przywara@arm.com>
 <1436538111-4294-7-git-send-email-andre.przywara@arm.com>
Message-ID: <55CC8AEB.6040001@linaro.org>

Reviewed-by: Eric Auger <eric.auger at linaro.org>

On 07/10/2015 04:21 PM, Andre Przywara wrote:
> The ARM GICv3 ITS controller requires a separate register frame to
> cover ITS specific registers. Add a new VGIC address type and store
> the address in a field in the vgic_dist structure.
> Provide a function to check whether userland has provided the address,
> so ITS functionality can be guarded by that check.
> 
> Signed-off-by: Andre Przywara <andre.przywara at arm.com>
> ---
>  Documentation/virtual/kvm/devices/arm-vgic.txt |  9 +++++++++
>  arch/arm64/include/uapi/asm/kvm.h              |  2 ++
>  include/kvm/arm_vgic.h                         |  3 +++
>  virt/kvm/arm/vgic-v3-emul.c                    |  2 ++
>  virt/kvm/arm/vgic.c                            | 16 ++++++++++++++++
>  virt/kvm/arm/vgic.h                            |  1 +
>  6 files changed, 33 insertions(+)
> 
> diff --git a/Documentation/virtual/kvm/devices/arm-vgic.txt b/Documentation/virtual/kvm/devices/arm-vgic.txt
> index 3fb9054..ec715f9e 100644
> --- a/Documentation/virtual/kvm/devices/arm-vgic.txt
> +++ b/Documentation/virtual/kvm/devices/arm-vgic.txt
> @@ -39,6 +39,15 @@ Groups:
>        Only valid for KVM_DEV_TYPE_ARM_VGIC_V3.
>        This address needs to be 64K aligned.
>  
> +    KVM_VGIC_V3_ADDR_TYPE_ITS (rw, 64-bit)
> +      Base address in the guest physical address space of the GICv3 ITS
> +      control register frame. The ITS allows MSI(-X) interrupts to be
> +      injected into guests. This extension is optional, if the kernel
> +      does not support the ITS, the call returns -ENODEV.
> +      This memory is solely for the guest to access the ITS control
> +      registers and does not cover the ITS translation register.
> +      Only valid for KVM_DEV_TYPE_ARM_VGIC_V3.
> +      This address needs to be 64K aligned and the region covers 64 KByte.
>  
>    KVM_DEV_ARM_VGIC_GRP_DIST_REGS
>    Attributes:
> diff --git a/arch/arm64/include/uapi/asm/kvm.h b/arch/arm64/include/uapi/asm/kvm.h
> index d268320..a89b407c 100644
> --- a/arch/arm64/include/uapi/asm/kvm.h
> +++ b/arch/arm64/include/uapi/asm/kvm.h
> @@ -81,9 +81,11 @@ struct kvm_regs {
>  /* Supported VGICv3 address types  */
>  #define KVM_VGIC_V3_ADDR_TYPE_DIST	2
>  #define KVM_VGIC_V3_ADDR_TYPE_REDIST	3
> +#define KVM_VGIC_V3_ADDR_TYPE_ITS	4
>  
>  #define KVM_VGIC_V3_DIST_SIZE		SZ_64K
>  #define KVM_VGIC_V3_REDIST_SIZE		(2 * SZ_64K)
> +#define KVM_VGIC_V3_ITS_SIZE		SZ_64K
>  
>  #define KVM_ARM_VCPU_POWER_OFF		0 /* CPU is started in OFF state */
>  #define KVM_ARM_VCPU_EL1_32BIT		1 /* CPU running a 32bit VM */
> diff --git a/include/kvm/arm_vgic.h b/include/kvm/arm_vgic.h
> index b18e2c5..3ee063b 100644
> --- a/include/kvm/arm_vgic.h
> +++ b/include/kvm/arm_vgic.h
> @@ -178,6 +178,9 @@ struct vgic_dist {
>  		phys_addr_t		vgic_redist_base;
>  	};
>  
> +	/* The base address of the ITS control register frame */
> +	phys_addr_t		vgic_its_base;
> +
>  	/* Distributor enabled */
>  	u32			enabled;
>  
> diff --git a/virt/kvm/arm/vgic-v3-emul.c b/virt/kvm/arm/vgic-v3-emul.c
> index 1f42348..a8cf669 100644
> --- a/virt/kvm/arm/vgic-v3-emul.c
> +++ b/virt/kvm/arm/vgic-v3-emul.c
> @@ -887,6 +887,7 @@ void vgic_v3_init_emulation(struct kvm *kvm)
>  
>  	dist->vgic_dist_base = VGIC_ADDR_UNDEF;
>  	dist->vgic_redist_base = VGIC_ADDR_UNDEF;
> +	dist->vgic_its_base = VGIC_ADDR_UNDEF;
>  
>  	kvm->arch.max_vcpus = KVM_MAX_VCPUS;
>  }
> @@ -1059,6 +1060,7 @@ static int vgic_v3_has_attr(struct kvm_device *dev,
>  			return -ENXIO;
>  		case KVM_VGIC_V3_ADDR_TYPE_DIST:
>  		case KVM_VGIC_V3_ADDR_TYPE_REDIST:
> +		case KVM_VGIC_V3_ADDR_TYPE_ITS:
>  			return 0;
>  		}
>  		break;
> diff --git a/virt/kvm/arm/vgic.c b/virt/kvm/arm/vgic.c
> index 59f1801..15e447f 100644
> --- a/virt/kvm/arm/vgic.c
> +++ b/virt/kvm/arm/vgic.c
> @@ -930,6 +930,16 @@ int vgic_register_kvm_io_dev(struct kvm *kvm, gpa_t base, int len,
>  	return ret;
>  }
>  
> +bool vgic_has_its(struct kvm *kvm)
> +{
> +	struct vgic_dist *dist = &kvm->arch.vgic;
> +
> +	if (dist->vgic_model != KVM_DEV_TYPE_ARM_VGIC_V3)
> +		return false;
> +
> +	return !IS_VGIC_ADDR_UNDEF(dist->vgic_its_base);
> +}
> +
>  static int vgic_nr_shared_irqs(struct vgic_dist *dist)
>  {
>  	return dist->nr_irqs - VGIC_NR_PRIVATE_IRQS;
> @@ -1927,6 +1937,12 @@ int kvm_vgic_addr(struct kvm *kvm, unsigned long type, u64 *addr, bool write)
>  		block_size = KVM_VGIC_V3_REDIST_SIZE;
>  		alignment = SZ_64K;
>  		break;
> +	case KVM_VGIC_V3_ADDR_TYPE_ITS:
> +		type_needed = KVM_DEV_TYPE_ARM_VGIC_V3;
> +		addr_ptr = &vgic->vgic_its_base;
> +		block_size = KVM_VGIC_V3_ITS_SIZE;
> +		alignment = SZ_64K;
> +		break;
>  #endif
>  	default:
>  		r = -ENODEV;
> diff --git a/virt/kvm/arm/vgic.h b/virt/kvm/arm/vgic.h
> index 0df74cb..a093f5c 100644
> --- a/virt/kvm/arm/vgic.h
> +++ b/virt/kvm/arm/vgic.h
> @@ -136,5 +136,6 @@ int vgic_get_common_attr(struct kvm_device *dev, struct kvm_device_attr *attr);
>  int vgic_init(struct kvm *kvm);
>  void vgic_v2_init_emulation(struct kvm *kvm);
>  void vgic_v3_init_emulation(struct kvm *kvm);
> +bool vgic_has_its(struct kvm *kvm);
>  
>  #endif
> 



From thierry.reding at gmail.com  Thu Aug 13 05:17:48 2015
From: thierry.reding at gmail.com (Thierry Reding)
Date: Thu, 13 Aug 2015 14:17:48 +0200
Subject: [PATCH v14 3/6] drm/panel: simple: Add support for NEC
 NL4827HC19-05B 480x272 panel
In-Reply-To: <1438158605-28248-4-git-send-email-jianwei.wang.chn@gmail.com>
References: <1438158605-28248-1-git-send-email-jianwei.wang.chn@gmail.com>
 <1438158605-28248-4-git-send-email-jianwei.wang.chn@gmail.com>
Message-ID: <20150813121748.GB11095@ulmo>

On Wed, Jul 29, 2015 at 04:30:02PM +0800, Jianwei Wang wrote:
> This adds support for the NEC NL4827HC19-05B 480x272 panel to the DRM
> simple panel driver.
> 
> Signed-off-by: Alison Wang <b18965 at freescale.com>
> Signed-off-by: Xiubo Li <lixiubo at cmss.chinamobile.com>
> Signed-off-by: Jianwei Wang <jianwei.wang.chn at gmail.com>
> Acked-by: Daniel Vetter <daniel.vetter at ffwll.ch>
> ---
>  .../bindings/panel/nec,nl4827hc19_05b.txt          |  7 ++++++
>  drivers/gpu/drm/panel/panel-simple.c               | 26 ++++++++++++++++++++++
>  2 files changed, 33 insertions(+)
>  create mode 100644 Documentation/devicetree/bindings/panel/nec,nl4827hc19_05b.txt

Applied, thanks.

Thierry
-------------- next part --------------
A non-text attachment was scrubbed...
Name: signature.asc
Type: application/pgp-signature
Size: 819 bytes
Desc: not available
URL: <http://lists.infradead.org/pipermail/linux-arm-kernel/attachments/20150813/533f3a7b/attachment.sig>

From thierry.reding at gmail.com  Thu Aug 13 05:23:13 2015
From: thierry.reding at gmail.com (Thierry Reding)
Date: Thu, 13 Aug 2015 14:23:13 +0200
Subject: [PATCH v14 3/6] drm/panel: simple: Add support for NEC
 NL4827HC19-05B 480x272 panel
In-Reply-To: <1438158605-28248-4-git-send-email-jianwei.wang.chn@gmail.com>
References: <1438158605-28248-1-git-send-email-jianwei.wang.chn@gmail.com>
 <1438158605-28248-4-git-send-email-jianwei.wang.chn@gmail.com>
Message-ID: <20150813122312.GC11095@ulmo>

On Wed, Jul 29, 2015 at 04:30:02PM +0800, Jianwei Wang wrote:
> This adds support for the NEC NL4827HC19-05B 480x272 panel to the DRM
> simple panel driver.
> 
> Signed-off-by: Alison Wang <b18965 at freescale.com>
> Signed-off-by: Xiubo Li <lixiubo at cmss.chinamobile.com>
> Signed-off-by: Jianwei Wang <jianwei.wang.chn at gmail.com>
> Acked-by: Daniel Vetter <daniel.vetter at ffwll.ch>
> ---
>  .../bindings/panel/nec,nl4827hc19_05b.txt          |  7 ++++++
>  drivers/gpu/drm/panel/panel-simple.c               | 26 ++++++++++++++++++++++
>  2 files changed, 33 insertions(+)
>  create mode 100644 Documentation/devicetree/bindings/panel/nec,nl4827hc19_05b.txt
> 
> diff --git a/Documentation/devicetree/bindings/panel/nec,nl4827hc19_05b.txt b/Documentation/devicetree/bindings/panel/nec,nl4827hc19_05b.txt
> new file mode 100644
> index 0000000..20e9473
> --- /dev/null
> +++ b/Documentation/devicetree/bindings/panel/nec,nl4827hc19_05b.txt
> @@ -0,0 +1,7 @@
> +NEC LCD Technologies,Ltd. WQVGA TFT LCD panel
> +
> +Required properties:
> +- compatible: should be "nec,nl4827hc19_05b"

Underscores are deprecated in compatible strings, so I've applied this
with "nec,nl4827hc19-05b".

Thierry
-------------- next part --------------
A non-text attachment was scrubbed...
Name: signature.asc
Type: application/pgp-signature
Size: 819 bytes
Desc: not available
URL: <http://lists.infradead.org/pipermail/linux-arm-kernel/attachments/20150813/db690ec4/attachment.sig>

From linus.walleij at linaro.org  Thu Aug 13 05:24:28 2015
From: linus.walleij at linaro.org (Linus Walleij)
Date: Thu, 13 Aug 2015 14:24:28 +0200
Subject: [PATCH v5 2/2] pinctrl: rockchip: only enable gpio clock when it
 setting
In-Reply-To: <1439287924-6988-2-git-send-email-hl@rock-chips.com>
References: <1439287924-6988-1-git-send-email-hl@rock-chips.com>
 <1439287924-6988-2-git-send-email-hl@rock-chips.com>
Message-ID: <CACRpkda0FXz1dpdS-wLRNmkt1KBESMyCWKMMa0ArH9Z-L=i_sw@mail.gmail.com>

On Tue, Aug 11, 2015 at 12:12 PM, Lin Huang <hl at rock-chips.com> wrote:

> gpio can keep state even the clock disable, for save power
> consumption, only enable gpio clock when it setting
>
> Signed-off-by: Lin Huang <hl at rock-chips.com>
> Reviewed-by: Heiko Stuebner <heiko at sntech.de>
> ---
> Changes in v5:
> -rebase patch

Patch applied with Doug's test tags etc.

Yours,
Linus Walleij


From gg at slimlogic.co.uk  Thu Aug 13 05:25:13 2015
From: gg at slimlogic.co.uk (Graeme Gregory)
Date: Thu, 13 Aug 2015 13:25:13 +0100
Subject: [PATCH 1/2] drivers: PL061: add support for platform driver
 probing
In-Reply-To: <CACRpkdYmeXvXCrJPxCJCDfCG_=MmopmyAe5mgCPoB_S02ERTLg@mail.gmail.com>
References: <1438585198-8764-1-git-send-email-zhaoshenglong@huawei.com>
 <1438585198-8764-2-git-send-email-zhaoshenglong@huawei.com>
 <CACRpkdY6ZfB-gnnr49He+BYELy4fhiV0g5jkEHhyVsJOc_SBFw@mail.gmail.com>
 <1438614811.2338188.346456017.5D258EC5@webmail.messagingengine.com>
 <CACRpkdYmeXvXCrJPxCJCDfCG_=MmopmyAe5mgCPoB_S02ERTLg@mail.gmail.com>
Message-ID: <1439468713.1661643.355247625.1CF96E47@webmail.messagingengine.com>



On Thu, 13 Aug 2015, at 01:14 PM, Linus Walleij wrote:
> On Mon, Aug 3, 2015 at 5:13 PM, Graeme Gregory <gg at slimlogic.co.uk>
> wrote:
> > On Mon, 3 Aug 2015, at 01:40 PM, Linus Walleij wrote:
> >> On Mon, Aug 3, 2015 at 8:59 AM, Shannon Zhao <zhaoshenglong at huawei.com>
> >> wrote:
> >>
> >> > From: Shannon Zhao <shannon.zhao at linaro.org>
> >> >
> >> > Since PL061 currently only supports AMBA driver, to support using GPIO
> >> > PL061 by DT or ACPI, it needs to add support for platform driver.
> >> > A DT binding is provided with this patch, ACPI support is added in a
> >> > separate one.
> >> >
> >> > Signed-off-by: Shannon Zhao <zhaoshenglong at huawei.com>
> >> > Signed-off-by: Shannon Zhao <shannon.zhao at linaro.org>
> >>
> >> I already stated in 0/2 what the problem is with this, and it's obviously
> >> adding
> >> a huge codechunk, very similar to the AMBA probe path.
> >>
> >> We need to investigate if ACPI can just spawn AMBA/PrimeCell type devices
> >> instead.
> >
> > AMBA DT support is a hideous hack, we had kind of hoped to avoid doing
> > that in ACPI.
> 
> Define what you mean with "hideous hack".
> 
drivers/of/platform.c search for #ifdef CONFIG_ARM_AMBA

> I think it is elegant. It combines the DT aspect of telling where the
> device is with the Plug-and-play aspect of reading the 0xB105F00D
> magic in the PrimeCells very nicely. With an optional override
> mechanism. It's nice.
> 
> The runtime PM stuff and pclk handling that Russell and also Ulf
> has worked on is very helpful and takes out a lot of codelines
> in a lot of drivers. Also very nice.
> 
I have no objection to AMBA devices that are children of an AMBA bus
object. Its the hack above that is nasty!  It is also un-scalable as it
sets the precedent that the platform.c in both DT and ACPI should learn
about all the different types of device probing.

> > If you notice ARM already updated pl011 driver to support platform
> > device type probing this seems to be the way to go.
> 
> Just because there is a precedent does not mean it is good.
> 
> Continuing with this adds 100+ lines of hairy initialization to
> every AMBA driver.
> 
> What needs to happen is stop this and make ACPI spawn
> AMBA devices for PrimeCells, and move the serial port over
> to that.
> 
> A compromise may be to have something that probes a list
> of these platform devices in drivers/acpi/ and spawn a
> corresponding AMBA device for it. It will still save codelines in
> all other subsystems and lower maintenance for the
> subsystem maintainers.
> 
I am currently working on exactly what you describe above.

Graeme



From steve.capper at linaro.org  Thu Aug 13 05:28:28 2015
From: steve.capper at linaro.org (Steve Capper)
Date: Thu, 13 Aug 2015 13:28:28 +0100
Subject: [PATCH 12/14] arm64: Check for selected granule support
In-Reply-To: <1439465645-22584-13-git-send-email-suzuki.poulose@arm.com>
References: <1439465645-22584-1-git-send-email-suzuki.poulose@arm.com>
 <1439465645-22584-13-git-send-email-suzuki.poulose@arm.com>
Message-ID: <CAPvkgC3=S1BxdzZM4uUOmyXLjii48SMpCof6i6HdNeTG_fydfg@mail.gmail.com>

On 13 August 2015 at 12:34, Suzuki K. Poulose <suzuki.poulose at arm.com> wrote:
> From: "Suzuki K. Poulose" <suzuki.poulose at arm.com>
>
> Ensure that the selected page size is supported by the
> CPU(s).
>
> Cc: Mark Rutland <mark.rutland at arm.com>
> Cc: Catalin Marinas <catalin.marinas at arm.com>
> Cc: Will Deacon <will.deacon at arm.com>
> Signed-off-by: Suzuki K. Poulose <suzuki.poulose at arm.com>
> ---
>  arch/arm64/include/asm/sysreg.h |    6 ++++++
>  arch/arm64/kernel/head.S        |   24 +++++++++++++++++++++++-
>  2 files changed, 29 insertions(+), 1 deletion(-)
>
> diff --git a/arch/arm64/include/asm/sysreg.h b/arch/arm64/include/asm/sysreg.h
> index a7f3d4b..e01d323 100644
> --- a/arch/arm64/include/asm/sysreg.h
> +++ b/arch/arm64/include/asm/sysreg.h
> @@ -87,4 +87,10 @@ static inline void config_sctlr_el1(u32 clear, u32 set)
>  }
>  #endif
>
> +#define ID_AA64MMFR0_TGran4_SHIFT      28
> +#define ID_AA64MMFR0_TGran64_SHIFT     24
> +
> +#define ID_AA64MMFR0_TGran4_ENABLED    0x0
> +#define ID_AA64MMFR0_TGran64_ENABLED   0x0
> +
>  #endif /* __ASM_SYSREG_H */
> diff --git a/arch/arm64/kernel/head.S b/arch/arm64/kernel/head.S
> index 01b8e58..0cb04db 100644
> --- a/arch/arm64/kernel/head.S
> +++ b/arch/arm64/kernel/head.S
> @@ -31,10 +31,11 @@
>  #include <asm/cputype.h>
>  #include <asm/kernel-pgtable.h>
>  #include <asm/memory.h>
> -#include <asm/thread_info.h>
>  #include <asm/pgtable-hwdef.h>
>  #include <asm/pgtable.h>
>  #include <asm/page.h>
> +#include <asm/sysreg.h>
> +#include <asm/thread_info.h>
>  #include <asm/virt.h>
>
>  #define __PHYS_OFFSET  (KERNEL_START - TEXT_OFFSET)
> @@ -606,9 +607,25 @@ ENDPROC(__secondary_switched)
>   *  x27 = *virtual* address to jump to upon completion
>   *
>   * other registers depend on the function called upon completion
> + * Checks if the selected granule size is supported by the CPU.
>   */
> +#if    defined(CONFIG_ARM64_64K_PAGES)
> +
> +#define ID_AA64MMFR0_TGran_SHIFT       ID_AA64MMFR0_TGran64_SHIFT
> +#define ID_AA64MMFR0_TGran_ENABLED     ID_AA64MMFR0_TGran64_ENABLED
> +
> +#else
> +
> +#define ID_AA64MMFR0_TGran_SHIFT       ID_AA64MMFR0_TGran4_SHIFT
> +#define ID_AA64MMFR0_TGran_ENABLED     ID_AA64MMFR0_TGran4_ENABLED
> +
> +#endif
>         .section        ".idmap.text", "ax"
>  __enable_mmu:
> +       mrs     x1, ID_AA64MMFR0_EL1
> +       ubfx    x2, x1, #ID_AA64MMFR0_TGran_SHIFT, 4
> +       cmp     x2, #ID_AA64MMFR0_TGran_ENABLED
> +       b.ne    __no_granule_support
>         ldr     x5, =vectors
>         msr     vbar_el1, x5
>         msr     ttbr0_el1, x25                  // load TTBR0
> @@ -626,3 +643,8 @@ __enable_mmu:
>         isb
>         br      x27
>  ENDPROC(__enable_mmu)
> +
> +__no_granule_support:
> +       wfe
> +       b __no_granule_support
> +ENDPROC(__no_granule_support)
> --
> 1.7.9.5
>

Hi Suzuki,
Is is possible to tell the user that the kernel has failed to boot due
to the kernel granule being unsupported?

Cheers,
--
Steve


From olof at lixom.net  Thu Aug 13 05:26:43 2015
From: olof at lixom.net (Olof Johansson)
Date: Thu, 13 Aug 2015 14:26:43 +0200
Subject: [GIT PULL] at91: defconfig for 4.3 #2
In-Reply-To: <20150813112118.GA22269@piout.net>
References: <20150807162754.GA20169@piout.net>
 <20150813100938.GN30160@localhost>
 <20150813112118.GA22269@piout.net>
Message-ID: <20150813122643.GA23581@localhost>

On Thu, Aug 13, 2015 at 01:21:18PM +0200, Alexandre Belloni wrote:
> On 13/08/2015 at 12:09:38 +0200, Olof Johansson wrote :
> > On Fri, Aug 07, 2015 at 06:27:54PM +0200, Alexandre Belloni wrote:
> > > Arnd, Olof, Kevin,
> > > 
> > > A little defconfig update. That will probably be all for this cycle.
> > > 
> > > Thanks, bye,
> > > 
> > > 
> > > The following changes since commit eff7f41572a645bf14a96a6f844be4f1c88cd9dd:
> > > 
> > >   ARM: at91: at91_dt_defconfig: enable ISI and ov2640 support (2015-07-30 14:17:31 +0200)
> > > 
> > > are available in the git repository at:
> > > 
> > >   git://git.kernel.org/pub/scm/linux/kernel/git/abelloni/linux.git tags/at91-ab-defconfig2
> > > 
> > > for you to fetch changes up to ea7bf603fd494391acc1f42acbfc34260b965c44:
> > > 
> > >   ARM: at91/defconfig: at91_dt: remove ARM_AT91_ETHER (2015-08-07 12:07:50 +0200)
> > 
> > Nicolas had sent me one patch which you've also included here but it's not in
> > the pull request ("enable ISI and ov2640 support"). That caused a conflict
> > here, so to avoid having the patch in the tree twice I instead also directly
> > applied your patches from this branch instead of merging.
> > 
> > Sorry about that, it started due to Nicolas sending the discrete patch to us.
> > So it seems like we'll apply at91 defconfig updates directly this release, in
> > case there are any more. No big deal I hope. :)
> > 
> 
> That's not a big deal and there will most probably be all for that cycle
> anyway.
> 
> However, I'm wondering how I should have done. From the PR, if you get
> eff7f41572a645bf14a96a6f844be4f1c88cd9dd..tags/at91-ab-defconfig2, it
> correctly excludes "enable ISI and ov2640 support" so I was thinking it
> was fine.
> Be cause the first patch was taken as a patch, should I have prepared a
> branch without it?

Yeah, you could have applied the other two if there were no conflicts. If there
were conflicts then it gets complicated, and the best answer would probably
have been to continue applying directly as patches.

This is the drawback of us sometimes applying patches directly -- when we do,
we no longer put them on a branch of their own that you can use as base. We
used to once upon a time but it is quite a bit of overhead for us and the
upside was pretty limited.


-Olof


From olof at lixom.net  Thu Aug 13 05:27:55 2015
From: olof at lixom.net (Olof Johansson)
Date: Thu, 13 Aug 2015 14:27:55 +0200
Subject: [GIT PULL] omap gpmc null pointer fix against v4.2-rc6
In-Reply-To: <20150813082022.GL10928@atomide.com>
References: <20150813082022.GL10928@atomide.com>
Message-ID: <20150813122755.GB23581@localhost>

On Thu, Aug 13, 2015 at 01:20:22AM -0700, Tony Lindgren wrote:
> The following changes since commit cd4556733b30cc363adc7b1cea3bffa7e2dd0c7c:
> 
>   ARM: dts: dra7: Fix broken pbias device creation (2015-08-05 03:04:07 -0700)
> 
> are available in the git repository at:
> 
>   git://git.kernel.org/pub/scm/linux/kernel/git/tmlind/linux-omap tags/omap-for-v4.2/fixes-rc6
> 
> for you to fetch changes up to e984a1791ac6a7c944911207e8a9c344763f0003:
> 
>   memory: omap-gpmc: Don't try to save uninitialized GPMC context (2015-08-12 01:43:49 -0700)

Thanks, merged.


-Olof


From linus.walleij at linaro.org  Thu Aug 13 05:29:47 2015
From: linus.walleij at linaro.org (Linus Walleij)
Date: Thu, 13 Aug 2015 14:29:47 +0200
Subject: [PATCH v2 0/6] ARM: shmobile: Move gpio ranges from C code to DT
In-Reply-To: <20150805005540.GB20726@verge.net.au>
References: <1438696519-13727-1-git-send-email-geert+renesas@glider.be>
 <20150805005540.GB20726@verge.net.au>
Message-ID: <CACRpkdY7P86+SxMr5-HnhrN5fC-N1U135jiGAJGTV=xx47VW5g@mail.gmail.com>

On Wed, Aug 5, 2015 at 2:55 AM, Simon Horman <horms at verge.net.au> wrote:

> Where possible I prefer not to apply non-DTS/DTSI patches on top of
> DTS/DTSI patches, I believe this is in keeping with how the ARM SoC
> maintainers like things handled.  With this in mind I have done the following:
>
> 1. Queued up the DTSI patches (patches 1 - 3) for v4.3 in my dt branch.
>    I intend for this to turn up in next soon.
> 2. Queued up for pinctrl patches (patches 4 - 6) for v4.4 in a pinctrl patch.
>    I intend for these to be present in the renesas devel branch but
>    not in next until after the release of v4.3-rc1. I would also be
>    happy to drop them and let Linus Walleij take these patches for v4.4,
>    assuming patches 1 - 3 are accepted for v4.3.

OK.

Will the world explode if I try to queue the pinctrl patches 4-6 in my
tree now for v4.3? Then I prefer to defer to v4.4. Else I can merge
it in parallel?

Yours,
Linus Walleij


From heiko at sntech.de  Thu Aug 13 05:37:36 2015
From: heiko at sntech.de (Heiko =?ISO-8859-1?Q?St=FCbner?=)
Date: Thu, 13 Aug 2015 14:37:36 +0200
Subject: [PATCH v5 2/2] pinctrl: rockchip: only enable gpio clock when it
 setting
In-Reply-To: <CACRpkda0FXz1dpdS-wLRNmkt1KBESMyCWKMMa0ArH9Z-L=i_sw@mail.gmail.com>
References: <1439287924-6988-1-git-send-email-hl@rock-chips.com>
 <1439287924-6988-2-git-send-email-hl@rock-chips.com>
 <CACRpkda0FXz1dpdS-wLRNmkt1KBESMyCWKMMa0ArH9Z-L=i_sw@mail.gmail.com>
Message-ID: <2167165.ooWgarx4Ov@diego>

Hi Linus,

Am Donnerstag, 13. August 2015, 14:24:28 schrieb Linus Walleij:
> On Tue, Aug 11, 2015 at 12:12 PM, Lin Huang <hl at rock-chips.com> wrote:
> > gpio can keep state even the clock disable, for save power
> > consumption, only enable gpio clock when it setting
> > 
> > Signed-off-by: Lin Huang <hl at rock-chips.com>
> > Reviewed-by: Heiko Stuebner <heiko at sntech.de>
> > ---
> > Changes in v5:
> > -rebase patch
> 
> Patch applied with Doug's test tags etc.

did you  also take the first patch?

Aka bot should probably stay together (hence Stephen's Ack for the clock 
change), as the dynamically controlling the gpio clocks exposes the 
pclk_pd_pmu.


Heiko


From linus.walleij at linaro.org  Thu Aug 13 05:37:54 2015
From: linus.walleij at linaro.org (Linus Walleij)
Date: Thu, 13 Aug 2015 14:37:54 +0200
Subject: [PATCH] pinctrl: atlas7: clear ugly branch statements for pull
 and drivestrength
In-Reply-To: <1438744934-15395-1-git-send-email-21cnbao@gmail.com>
References: <1438744934-15395-1-git-send-email-21cnbao@gmail.com>
Message-ID: <CACRpkdYtFSps1R-YgMFoekkW8osDVf+ujrnGLP47YBCcq2ZBzg@mail.gmail.com>

On Wed, Aug 5, 2015 at 5:22 AM, Barry Song <21cnbao at gmail.com> wrote:

> From: Wei Chen <Wei.Chen at csr.com>
>
> To set/get atlas7 pull & drive strength, we use lots of if/else
> to check pad type. But except mask value or immediate value, all
> actions in these conditional branches are the same.
> So we use predefined pull info table and drive strength table
> to reduce these redundancy code.
>
> Signed-off-by: Wei Chen <Wei.Chen at csr.com>
> Signed-off-by: Barry Song <Baohua.Song at csr.com>

Patch applied.

Yours,
Linus Walleij


From jszhang at marvell.com  Thu Aug 13 05:39:48 2015
From: jszhang at marvell.com (Jisheng Zhang)
Date: Thu, 13 Aug 2015 20:39:48 +0800
Subject: [GIT PULL] ARM: berlin: Initial Marvell Berlin ARM64 support
In-Reply-To: <1438629886-6390-1-git-send-email-sebastian.hesselbarth@gmail.com>
References: <1438629886-6390-1-git-send-email-sebastian.hesselbarth@gmail.com>
Message-ID: <20150813203948.31de7849@xhacker>

Dear Olof,

On Mon,  3 Aug 2015 21:24:44 +0200
Sebastian Hesselbarth <sebastian.hesselbarth at gmail.com> wrote:

> Hi Arnd, Kevin, Olof,
> 
> this is initial Marvell Berlin4CT ARM64 support for v4.3. It contains minimum SoC
> dtsi and basic dts for the development board. The patches have been posted by
> Marvell's Jisheng Zhang a while ago on the lists.
> 
> Please pull.
> 
> The following changes since commit d770e558e21961ad6cfdf0ff7df0eb5d7d4f0754:
> 
>   Linux 4.2-rc1 (2015-07-05 11:01:52 -0700)
> 
> are available in the git repository at:
> 
>   git://git.infradead.org/users/hesselba/linux-berlin.git tags/berlin64-for-v4.3-1
> 
> for you to fetch changes up to d93ac74ad150c89f2d0a3b90754cbccdc6ab102c:
> 
>   arm64: dts: Add dts files for Marvell Berlin4CT SoC (2015-08-03 20:45:54 +0200)
> 
> ----------------------------------------------------------------
> Initial support for Marvell Berlin4CT ARM64 SoC
> 
> ----------------------------------------------------------------
> Jisheng Zhang (1):
>       arm64: dts: Add dts files for Marvell Berlin4CT SoC
> 
>  arch/arm64/boot/dts/Makefile                  |   1 +
>  arch/arm64/boot/dts/marvell/Makefile          |   5 +
>  arch/arm64/boot/dts/marvell/berlin4ct-dmp.dts |  66 +++++++++++
>  arch/arm64/boot/dts/marvell/berlin4ct.dtsi    | 164 ++++++++++++++++++++++++++
>  4 files changed, 236 insertions(+)
>  create mode 100644 arch/arm64/boot/dts/marvell/Makefile
>  create mode 100644 arch/arm64/boot/dts/marvell/berlin4ct-dmp.dts
>  create mode 100644 arch/arm64/boot/dts/marvell/berlin4ct.dtsi

I just saw you were online ;)

Thank you very much for appling the patches for Kconfig and defconfig, I'm not
sure you missed this dts pull ;) could you please help?

Sorry for noise,
Jisheng


From geert at linux-m68k.org  Thu Aug 13 05:45:55 2015
From: geert at linux-m68k.org (Geert Uytterhoeven)
Date: Thu, 13 Aug 2015 14:45:55 +0200
Subject: [PATCH v2 0/6] ARM: shmobile: Move gpio ranges from C code to DT
In-Reply-To: <CACRpkdY7P86+SxMr5-HnhrN5fC-N1U135jiGAJGTV=xx47VW5g@mail.gmail.com>
References: <1438696519-13727-1-git-send-email-geert+renesas@glider.be>
 <20150805005540.GB20726@verge.net.au>
 <CACRpkdY7P86+SxMr5-HnhrN5fC-N1U135jiGAJGTV=xx47VW5g@mail.gmail.com>
Message-ID: <CAMuHMdW0T6MW6s4Gg_rqvtt+MRPtp_MpuiKtamfFrx-Tcm6WmQ@mail.gmail.com>

Hi Linus,

On Thu, Aug 13, 2015 at 2:29 PM, Linus Walleij <linus.walleij at linaro.org> wrote:
> On Wed, Aug 5, 2015 at 2:55 AM, Simon Horman <horms at verge.net.au> wrote:
>> Where possible I prefer not to apply non-DTS/DTSI patches on top of
>> DTS/DTSI patches, I believe this is in keeping with how the ARM SoC
>> maintainers like things handled.  With this in mind I have done the following:
>>
>> 1. Queued up the DTSI patches (patches 1 - 3) for v4.3 in my dt branch.
>>    I intend for this to turn up in next soon.
>> 2. Queued up for pinctrl patches (patches 4 - 6) for v4.4 in a pinctrl patch.
>>    I intend for these to be present in the renesas devel branch but
>>    not in next until after the release of v4.3-rc1. I would also be
>>    happy to drop them and let Linus Walleij take these patches for v4.4,
>>    assuming patches 1 - 3 are accepted for v4.3.
>
> OK.
>
> Will the world explode if I try to queue the pinctrl patches 4-6 in my
> tree now for v4.3? Then I prefer to defer to v4.4. Else I can merge
> it in parallel?

There won't be a mapping between gpio and pins in any branch having the
pinctrl changes but not the dtsi changes.

Gr{oetje,eeting}s,

                        Geert

--
Geert Uytterhoeven -- There's lots of Linux beyond ia32 -- geert at linux-m68k.org

In personal conversations with technical people, I call myself a hacker. But
when I'm talking to journalists I just say "programmer" or something like that.
                                -- Linus Torvalds


From jassisinghbrar at gmail.com  Thu Aug 13 05:47:18 2015
From: jassisinghbrar at gmail.com (Jassi Brar)
Date: Thu, 13 Aug 2015 18:17:18 +0530
Subject: [PATCH v2 5/6] mailbox: Add generic mechanism for testing Mailbox
 Controllers
In-Reply-To: <20150813114005.GF8782@x1>
References: <1437990272-23111-6-git-send-email-lee.jones@linaro.org>
 <CABb+yY20nQbiEEZeRvWTMUsJ2qgwRn8CrWvnFDSB-b1dgVaAuw@mail.gmail.com>
 <20150812102328.GD18282@x1>
 <CABb+yY0A74Vy3-KOvj0URU_4zb2FAC7Yp3gmEwnFaBrD0mzt0w@mail.gmail.com>
 <20150813091914.GB8782@x1>
 <CABb+yY0cgbtM68-E_Xqgh5O6GRLXESYTLa5WcAwUBoVL3ufrxA@mail.gmail.com>
 <20150813102335.GC8782@x1>
 <CABb+yY3z7p97eOhncQ2i+g6yoYGfDgSN9BDPKmiDaVLa3oPocA@mail.gmail.com>
 <20150813110008.GD8782@x1>
 <CABb+yY34i=VUnswUE21vgeQYAGOS=7uwvdnTAFFgYkTV0CFk=w@mail.gmail.com>
 <20150813114005.GF8782@x1>
Message-ID: <CABb+yY2OH16mgOwi=yH_eEHQN2Ck2x5xtVk-p-8Un9gGmcACdw@mail.gmail.com>

On Thu, Aug 13, 2015 at 5:10 PM, Lee Jones <lee.jones at linaro.org> wrote:
> On Thu, 13 Aug 2015, Jassi Brar wrote:
>
>> On Thu, Aug 13, 2015 at 4:30 PM, Lee Jones <lee.jones at linaro.org> wrote:
>> > On Thu, 13 Aug 2015, Jassi Brar wrote:
>> >
>> >> On Thu, Aug 13, 2015 at 3:53 PM, Lee Jones <lee.jones at linaro.org> wrote:
>> >> > On Thu, 13 Aug 2015, Jassi Brar wrote:
>> >> >
>> >> >> On Thu, Aug 13, 2015 at 2:49 PM, Lee Jones <lee.jones at linaro.org> wrote:
>> >> >> > On Thu, 13 Aug 2015, Jassi Brar wrote:
>> >> >>
>> >> >> >> >> > +
>> >> >> >> >> > +static void mbox_test_prepare_message(struct mbox_client *client, void *message)
>> >> >> >> >> > +{
>> >> >> >> >> > +       struct mbox_test_device *tdev = dev_get_drvdata(client->dev);
>> >> >> >> >> > +
>> >> >> >> >> > +       if (tdev->mmio)
>> >> >> >> >> > +               memcpy(tdev->mmio, message, MBOX_MAX_MSG_LEN);
>> >> >> >> >> >
>> >> >> >> >> This is unlikely to work. Those platforms that need to send a 2 part
>> >> >> >> >> message, they do :
>> >> >> >> >> (a) Signal/Command/Target code via some controller register (via
>> >> >> >> >> mbox_send_message).
>> >> >> >> >> (b) Setup the payload in Shared-Memory (via tx_prepare).
>> >> >> >> >>
>> >> >> >> >> This test driver assumes both are the same. I think you have to
>> >> >> >> >> declare something like
>> >> >> >> >
>> >> >> >> > This driver assumes that the framework will call client->tx_prepare()
>> >> >> >> > first, which satisfies (b).  It then assumes controller->send_data()
>> >> >> >> > will be invoked, which will send the platform specific
>> >> >> >> > signal/command/target code, which then satisfies (a).
>> >> >> >> >
>> >> >> >> Yeah, but what would be that code? Who provides that?
>> >> >> >>
>> >> >> >> > In what way does it assume they are the same?
>> >> >> >> >
>> >> >> >> notice the 'message' pointer in
>> >> >> >> mbox_send_message(tdev->tx_channel, message);
>> >> >> >>     and
>> >> >> >> memcpy(tdev->mmio, message, MBOX_MAX_MSG_LEN);
>> >> >> >>
>> >> >> >> >> struct mbox_test_message { /* same for TX and RX */
>> >> >> >> >>           unsigned sig_len;
>> >> >> >> >>           void *signal;               /* rx/tx via mailbox api */
>> >> >> >> >>           unsigned pl_len;
>> >> >> >> >>           void *payload;           /* rx/tx via shared-memory */
>> >> >> >> >> };
>> >> >> >> >
>> >> >> >> > How do you think this should be set and use these?
>> >> >> >> >
>> >> >> >> The userspace would want to specify the command code (32bits or not)
>> >> >> >> that would be passed via the fifo/register of the controller. So we
>> >> >> >> need signal[]
>> >> >> >>
>> >> >> >> The data to be passed via share-memory could be provided by userspace
>> >> >> >> via the payload[] array.
>> >> >> >
>> >> >> > Okay, so would the solution be two userspace files 'signal' and
>> >> >> > 'message', so in the case of a client specified signal we can write it
>> >> >> > into there first.
>> >> >> >
>> >> >> > echo 255  > signal
>> >> >> > echo test > message
>> >> >> >
>> >> >> > ... or in the case where no signal is required, or the controller
>> >> >> > driver taking care of it, we just don't write anything to signal?
>> >> >> >
>> >> >> file_operations.write() should parse signal and message, coming from
>> >> >> userspace, into a local structure before routing them via
>> >> >> mbox_send_message and tx_prepare respectively.
>> >> >
>> >> > Okay.  So before I code this up we should agree on syntax.
>> >> >
>> >> > How would you like to represent the break between signal and message?
>> >> > Obviously ' ' would be a bad idea, as some clients may want to send
>> >> > messages with white space contained.  How about '\t' or '\n'?
>> >> >
>> >> Yeah, I am not a fan of markers and flags either.
>> >>
>> >> Maybe we should share with userspace
>> >>   struct mbox_test_message { /* same for TX and RX */
>> >>            unsigned sig_len;
>> >>            void __user *signal;        /* rx/tx via mailbox api */
>> >>            unsigned pl_len;
>> >>            void __user *payload;    /* rx/tx via shared-memory */
>> >>   };
>> >>
>> >> First copy_from_user the structure of length sizof(struct
>> >> mbox_test_message) and then copy_from_user length sig_len and pl_len
>> >> from signal[] and payload[] respectively (usually ioctls would carry
>> >> such data).
>> >
>> > Simplicity and ease of use should be the goals here.  Testers should
>> > not have to write applications to use this driver.  Can we come up
>> > with a simple/effective method that uses SYSFS/DEBUGFS please?
>> >
>> > The easiest way I can think of which avoids markers/separators AND the
>> > requirement for users to have to write applications is to have two
>> > files, 'signal' and 'message' as mentioned before.  Once both are
>> > populated I can get this driver to draft the message appropriately and
>> > fire it off.
>> >
>> And then write to more files for RX data? ... which should also be in
>> the form of 'signal' and 'message'.
>>
>> BTW like for spi there is a stock application in
>> Documentation/spi/spidev_test.c we could do the same?
>
> Coming from personal experience, testing drivers with (even stock)
> applications is much more painful that simply writing/reading
> (cat/echo) to a file in SYSFS/DEBUGFS.  Particularly if people are
> using initramfs or thelike.  If it is possible to use SYSFS/DEBUGFS,
> which it is in this case, then I believe that's the route we could go
> down.
>
Well, where could sysfs/debugfs not be used? :)  Anyways I am ok if
prefer debugfs.

> In answer to your question; we only need those two files.  The reply
> can be placed back into 'message' and can be read from there.
>
Testing shouldn't be restricted to 'send command and receive reply'.
What if Linux only listens to broadcasts from the remote? Who knows
someone might want to (ab)use this test client to implement userspace
handler of remote commands?
So please see RX to be independent of TX.

Thanks.


From eric.auger at linaro.org  Thu Aug 13 05:48:27 2015
From: eric.auger at linaro.org (Eric Auger)
Date: Thu, 13 Aug 2015 14:48:27 +0200
Subject: [PATCH v2 08/15] KVM: arm64: introduce ITS emulation file with
 stub functions
In-Reply-To: <1436538111-4294-9-git-send-email-andre.przywara@arm.com>
References: <1436538111-4294-1-git-send-email-andre.przywara@arm.com>
 <1436538111-4294-9-git-send-email-andre.przywara@arm.com>
Message-ID: <55CC921B.503@linaro.org>

On 07/10/2015 04:21 PM, Andre Przywara wrote:
> The ARM GICv3 ITS emulation code goes into a separate file, but
> needs to be connected to the GICv3 emulation, of which it is an
> option.
> Introduce the skeleton with function stubs to be filled later.
> Introduce the basic ITS data structure and initialize it, but don't
> return any success yet, as we are not yet ready for the show.
> 
> Signed-off-by: Andre Przywara <andre.przywara at arm.com>
> ---
>  arch/arm64/kvm/Makefile            |   1 +
>  include/kvm/arm_vgic.h             |   6 ++
>  include/linux/irqchip/arm-gic-v3.h |   1 +
>  virt/kvm/arm/its-emul.c            | 125 +++++++++++++++++++++++++++++++++++++
>  virt/kvm/arm/its-emul.h            |  35 +++++++++++
>  virt/kvm/arm/vgic-v3-emul.c        |  24 ++++++-
>  6 files changed, 189 insertions(+), 3 deletions(-)
>  create mode 100644 virt/kvm/arm/its-emul.c
>  create mode 100644 virt/kvm/arm/its-emul.h
> 
> diff --git a/arch/arm64/kvm/Makefile b/arch/arm64/kvm/Makefile
> index f90f4aa..9803307 100644
> --- a/arch/arm64/kvm/Makefile
> +++ b/arch/arm64/kvm/Makefile
> @@ -25,5 +25,6 @@ kvm-$(CONFIG_KVM_ARM_HOST) += $(KVM)/arm/vgic-v2-emul.o
>  kvm-$(CONFIG_KVM_ARM_HOST) += vgic-v2-switch.o
>  kvm-$(CONFIG_KVM_ARM_HOST) += $(KVM)/arm/vgic-v3.o
>  kvm-$(CONFIG_KVM_ARM_HOST) += $(KVM)/arm/vgic-v3-emul.o
> +kvm-$(CONFIG_KVM_ARM_HOST) += $(KVM)/arm/its-emul.o
>  kvm-$(CONFIG_KVM_ARM_HOST) += vgic-v3-switch.o
>  kvm-$(CONFIG_KVM_ARM_HOST) += $(KVM)/arm/arch_timer.o
> diff --git a/include/kvm/arm_vgic.h b/include/kvm/arm_vgic.h
> index 8c6cb0e..9e9d4aa 100644
> --- a/include/kvm/arm_vgic.h
> +++ b/include/kvm/arm_vgic.h
> @@ -156,6 +156,11 @@ struct vgic_io_device {
>  	struct kvm_io_device dev;
>  };
>  
> +struct vgic_its {
> +	bool			enabled;
> +	spinlock_t		lock;
> +};
> +
>  struct vgic_dist {
>  	spinlock_t		lock;
>  	bool			in_kernel;
> @@ -264,6 +269,7 @@ struct vgic_dist {
>  	u64			*pendbaser;
>  
>  	bool			lpis_enabled;
> +	struct vgic_its		its;
>  };
>  
>  struct vgic_v2_cpu_if {
> diff --git a/include/linux/irqchip/arm-gic-v3.h b/include/linux/irqchip/arm-gic-v3.h
> index ffbc034..df4e527 100644
> --- a/include/linux/irqchip/arm-gic-v3.h
> +++ b/include/linux/irqchip/arm-gic-v3.h
> @@ -177,6 +177,7 @@
>  #define GITS_CWRITER			0x0088
>  #define GITS_CREADR			0x0090
>  #define GITS_BASER			0x0100
> +#define GITS_IDREGS_BASE		0xffd0
>  #define GITS_PIDR2			GICR_PIDR2
>  
>  #define GITS_TRANSLATER			0x10040
> diff --git a/virt/kvm/arm/its-emul.c b/virt/kvm/arm/its-emul.c
> new file mode 100644
> index 0000000..659dd39
> --- /dev/null
> +++ b/virt/kvm/arm/its-emul.c
> @@ -0,0 +1,125 @@
> +/*
> + * GICv3 ITS emulation
> + *
> + * Copyright (C) 2015 ARM Ltd.
> + * Author: Andre Przywara <andre.przywara at arm.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.
> + *
> + * You should have received a copy of the GNU General Public License
> + * along with this program.  If not, see <http://www.gnu.org/licenses/>.
> + */
> +
> +#include <linux/cpu.h>
> +#include <linux/kvm.h>
> +#include <linux/kvm_host.h>
> +#include <linux/interrupt.h>
> +
> +#include <linux/irqchip/arm-gic-v3.h>
> +#include <kvm/arm_vgic.h>
> +
> +#include <asm/kvm_emulate.h>
> +#include <asm/kvm_arm.h>
> +#include <asm/kvm_mmu.h>
> +
> +#include "vgic.h"
> +#include "its-emul.h"
> +
> +static bool handle_mmio_misc_gits(struct kvm_vcpu *vcpu,
> +				  struct kvm_exit_mmio *mmio,
> +				  phys_addr_t offset)
> +{
> +	return false;
> +}
> +
> +static bool handle_mmio_gits_idregs(struct kvm_vcpu *vcpu,
> +				    struct kvm_exit_mmio *mmio,
> +				    phys_addr_t offset)
> +{
> +	return false;
> +}
> +
> +static bool handle_mmio_gits_cbaser(struct kvm_vcpu *vcpu,
> +				    struct kvm_exit_mmio *mmio,
> +				    phys_addr_t offset)
> +{
> +	return false;
> +}
> +
> +static bool handle_mmio_gits_cwriter(struct kvm_vcpu *vcpu,
> +				     struct kvm_exit_mmio *mmio,
> +				     phys_addr_t offset)
> +{
> +	return false;
> +}
> +
> +static bool handle_mmio_gits_creadr(struct kvm_vcpu *vcpu,
> +				    struct kvm_exit_mmio *mmio,
> +				    phys_addr_t offset)
> +{
> +	return false;
> +}
> +
> +static const struct vgic_io_range vgicv3_its_ranges[] = {
> +	{
> +		.base		= GITS_CTLR,
> +		.len		= 0x10,
> +		.bits_per_irq	= 0,
> +		.handle_mmio	= handle_mmio_misc_gits,
> +	},
> +	{
> +		.base		= GITS_CBASER,
> +		.len		= 0x08,
> +		.bits_per_irq	= 0,
> +		.handle_mmio	= handle_mmio_gits_cbaser,
> +	},
> +	{
> +		.base		= GITS_CWRITER,
> +		.len		= 0x08,
> +		.bits_per_irq	= 0,
> +		.handle_mmio	= handle_mmio_gits_cwriter,
> +	},
> +	{
> +		.base		= GITS_CREADR,
> +		.len		= 0x08,
> +		.bits_per_irq	= 0,
> +		.handle_mmio	= handle_mmio_gits_creadr,
> +	},
> +	{
> +		/* We don't need any memory from the guest. */
> +		.base		= GITS_BASER,
> +		.len		= 0x40,
> +		.bits_per_irq	= 0,
> +		.handle_mmio	= handle_mmio_raz_wi,
> +	},
> +	{
> +		.base		= GITS_IDREGS_BASE,
> +		.len		= 0x30,
> +		.bits_per_irq	= 0,
> +		.handle_mmio	= handle_mmio_gits_idregs,
> +	},
> +};
> +
> +/* This is called on setting the LPI enable bit in the redistributor. */
> +void vgic_enable_lpis(struct kvm_vcpu *vcpu)
> +{
> +}
> +
> +int vits_init(struct kvm *kvm)
> +{
> +	struct vgic_dist *dist = &kvm->arch.vgic;
> +	struct vgic_its *its = &dist->its;
> +
> +	spin_lock_init(&its->lock);
> +
> +	its->enabled = false;
> +
> +	return -ENXIO;
> +}
> diff --git a/virt/kvm/arm/its-emul.h b/virt/kvm/arm/its-emul.h
> new file mode 100644
> index 0000000..5dc8e2f
> --- /dev/null
> +++ b/virt/kvm/arm/its-emul.h
> @@ -0,0 +1,35 @@
> +/*
> + * GICv3 ITS emulation definitions
> + *
> + * Copyright (C) 2015 ARM Ltd.
> + * Author: Andre Przywara <andre.przywara at arm.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.
> + *
> + * You should have received a copy of the GNU General Public License
> + * along with this program.  If not, see <http://www.gnu.org/licenses/>.
> + */
> +
> +#ifndef __KVM_ITS_EMUL_H__
> +#define __KVM_ITS_EMUL_H__
> +
> +#include <linux/kvm.h>
> +#include <linux/kvm_host.h>
> +
> +#include <asm/kvm_emulate.h>
> +#include <asm/kvm_arm.h>
> +#include <asm/kvm_mmu.h>
> +
> +#include "vgic.h"
> +
> +void vgic_enable_lpis(struct kvm_vcpu *vcpu);
> +int vits_init(struct kvm *kvm);
> +
> +#endif
> diff --git a/virt/kvm/arm/vgic-v3-emul.c b/virt/kvm/arm/vgic-v3-emul.c
> index 5269ad1..f5865e7 100644
> --- a/virt/kvm/arm/vgic-v3-emul.c
> +++ b/virt/kvm/arm/vgic-v3-emul.c
> @@ -48,6 +48,7 @@
>  #include <asm/kvm_mmu.h>
>  
>  #include "vgic.h"
> +#include "its-emul.h"
>  
>  static bool handle_mmio_rao_wi(struct kvm_vcpu *vcpu,
>  			       struct kvm_exit_mmio *mmio, phys_addr_t offset)
> @@ -530,9 +531,20 @@ static bool handle_mmio_ctlr_redist(struct kvm_vcpu *vcpu,
>  				    struct kvm_exit_mmio *mmio,
>  				    phys_addr_t offset)
>  {
> -	/* since we don't support LPIs, this register is zero for now */
> -	vgic_reg_access(mmio, NULL, offset,
> -			ACCESS_READ_RAZ | ACCESS_WRITE_IGNORED);
> +	struct vgic_dist *dist = &vcpu->kvm->arch.vgic;
> +	u32 reg;
> +
> +	if (!vgic_has_its(vcpu->kvm)) {
> +		vgic_reg_access(mmio, NULL, offset,
> +				ACCESS_READ_RAZ | ACCESS_WRITE_IGNORED);
> +		return false;
> +	}
can't we remove above block and ...
> +	reg = dist->lpis_enabled ? GICR_CTLR_ENABLE_LPIS : 0;
> +	vgic_reg_access(mmio, &reg, offset,
> +			ACCESS_READ_VALUE | ACCESS_WRITE_VALUE);
> +	if (!dist->lpis_enabled && (reg & GICR_CTLR_ENABLE_LPIS
add vgic_has_its(vcpu->kvm) && above?

Besides Reviewed-by: Eric Auger <eric.auger at linaro.org>

Eric
)) {
> +		/* Eventually do something */
> +	}
>  	return false;
>  }
>  
> @@ -861,6 +873,12 @@ static int vgic_v3_map_resources(struct kvm *kvm,
>  		rdbase += GIC_V3_REDIST_SIZE;
>  	}
>  
> +	if (vgic_has_its(kvm)) {
> +		ret = vits_init(kvm);
> +		if (ret)
> +			goto out_unregister;
> +	}
> +
>  	dist->redist_iodevs = iodevs;
>  	dist->ready = true;
>  	goto out;
> 



From olof at lixom.net  Thu Aug 13 05:49:22 2015
From: olof at lixom.net (Olof Johansson)
Date: Thu, 13 Aug 2015 14:49:22 +0200
Subject: [GIT PULL] ARM: berlin: Initial Marvell Berlin ARM64 support
In-Reply-To: <20150813203948.31de7849@xhacker>
References: <1438629886-6390-1-git-send-email-sebastian.hesselbarth@gmail.com>
 <20150813203948.31de7849@xhacker>
Message-ID: <CAOesGMhf2sjCUnX5thJZ=dmVbgH25dtwekF=YA96fCvsxpAZ3g@mail.gmail.com>

Hi,

On Thu, Aug 13, 2015 at 2:39 PM, Jisheng Zhang <jszhang at marvell.com> wrote:
> Dear Olof,
>
> On Mon,  3 Aug 2015 21:24:44 +0200
> Sebastian Hesselbarth <sebastian.hesselbarth at gmail.com> wrote:
>
>> Hi Arnd, Kevin, Olof,
>>
>> this is initial Marvell Berlin4CT ARM64 support for v4.3. It contains minimum SoC
>> dtsi and basic dts for the development board. The patches have been posted by
>> Marvell's Jisheng Zhang a while ago on the lists.
>>
>> Please pull.
>>
>> The following changes since commit d770e558e21961ad6cfdf0ff7df0eb5d7d4f0754:
>>
>>   Linux 4.2-rc1 (2015-07-05 11:01:52 -0700)
>>
>> are available in the git repository at:
>>
>>   git://git.infradead.org/users/hesselba/linux-berlin.git tags/berlin64-for-v4.3-1
>>
>> for you to fetch changes up to d93ac74ad150c89f2d0a3b90754cbccdc6ab102c:
>>
>>   arm64: dts: Add dts files for Marvell Berlin4CT SoC (2015-08-03 20:45:54 +0200)
>>
>> ----------------------------------------------------------------
>> Initial support for Marvell Berlin4CT ARM64 SoC
>>
>> ----------------------------------------------------------------
>> Jisheng Zhang (1):
>>       arm64: dts: Add dts files for Marvell Berlin4CT SoC
>>
>>  arch/arm64/boot/dts/Makefile                  |   1 +
>>  arch/arm64/boot/dts/marvell/Makefile          |   5 +
>>  arch/arm64/boot/dts/marvell/berlin4ct-dmp.dts |  66 +++++++++++
>>  arch/arm64/boot/dts/marvell/berlin4ct.dtsi    | 164 ++++++++++++++++++++++++++
>>  4 files changed, 236 insertions(+)
>>  create mode 100644 arch/arm64/boot/dts/marvell/Makefile
>>  create mode 100644 arch/arm64/boot/dts/marvell/berlin4ct-dmp.dts
>>  create mode 100644 arch/arm64/boot/dts/marvell/berlin4ct.dtsi
>
> I just saw you were online ;)
>
> Thank you very much for appling the patches for Kconfig and defconfig, I'm not
> sure you missed this dts pull ;) could you please help?

Yeah, sorry, not sure why I missed this twice. I must have
accidentally marked the email as read (twice) from my phone, that's
normally how it happens..

Anyway, merged now.


-Olof


From linus.walleij at linaro.org  Thu Aug 13 05:58:59 2015
From: linus.walleij at linaro.org (Linus Walleij)
Date: Thu, 13 Aug 2015 14:58:59 +0200
Subject: [PATCH] pinctrl: mediatek: Implement wake handler and suspend
 resume
In-Reply-To: <1439453936-8315-1-git-send-email-maoguang.meng@mediatek.com>
References: <1439453936-8315-1-git-send-email-maoguang.meng@mediatek.com>
Message-ID: <CACRpkdYKsUd4OSLJTPYZPmnLZfKQhj_UXmKtrBjKj5N4E8od2Q@mail.gmail.com>

On Thu, Aug 13, 2015 at 10:18 AM,  <maoguang.meng at mediatek.com> wrote:

> From: Maoguang Meng <maoguang.meng at mediatek.com>
>
> This patch implement irq_set_wake to get who is wakeup source and
> setup on suspend resume.
>
> Signed-off-by: Maoguang Meng <maoguang.meng at mediatek.com>
>
> ---
> changes since v2:
> -modify irq_wake to handle irq wakeup source.
> -allocate two buffers separately.
> -fix some codestyle.
>
> Changes since v1:
> -implement irq_wake handler.

Waiting for Hongzhu's ACK on this patch.

Yours,
Linus Walleij


From grygorii.strashko at ti.com  Thu Aug 13 05:58:59 2015
From: grygorii.strashko at ti.com (Grygorii Strashko)
Date: Thu, 13 Aug 2015 15:58:59 +0300
Subject: [PATCH v2 2/6] genirq: fix irqchip_set_wake_parent if
 IRQCHIP_SKIP_SET_WAKE
In-Reply-To: <55CC71E8.80604@ti.com>
References: <1439401562-28874-1-git-send-email-grygorii.strashko@ti.com>
 <1439401562-28874-3-git-send-email-grygorii.strashko@ti.com>
 <55CC6AFF.8060400@arm.com> <55CC71E8.80604@ti.com>
Message-ID: <55CC9493.9020101@ti.com>

On 08/13/2015 01:31 PM, Grygorii Strashko wrote:
> On 08/13/2015 01:01 PM, Marc Zyngier wrote:
>> On 12/08/15 18:45, Grygorii Strashko wrote:
>>> The irqchip_set_wake_parent should not fail if IRQ chip
>>> specifies IRQCHIP_SKIP_SET_WAKE. Otherwise, IRQ wakeup
>>> configuration can't be propagated properly through IRQ
>>> domains hierarchy.
>>>
>>> In case of TI OMAP DRA7 the issue reproduced with following
>>> configuration:
>>> ARM GIC<-OMAP wakeupgen<-TI CBAR<-GPIO<-GPIO pcf857x<-gpio_key
>>>
>>> gpio_key is wakeup source
>>>
>>> Failure is reproduced during suspend/resume to RAM:
>>> suspend:
>>>   - gpio_keys_suspend
>>>     enable_irq_wake
>>>       + pcf857x_irq_set_wake
>>>         + omap_gpio_wake_enable
>>>           + TI CBAR irq_chip_set_wake_parent
>>>             + OMAP wakeupgen has no .irq_set_wake()
>>
>> Most importantly, wakeupgen has IRQCHIP_SKIP_SET_WAKE set.
>>
>>>             and -ENOSYS will be returned
>>>
>>> resume:
>>>   - gpio_keys_resume
>>>     + disable_irq_wake
>>>       + irq_set_irq_wake
>>>         + WARN(1, "Unbalanced IRQ %d wake disable\n", irq);
>>>
>>> Fixes: 08b55e2a9208 ('genirq: Add irqchip_set_wake_parent')
>>> Signed-off-by: Grygorii Strashko <grygorii.strashko at ti.com>
>>> ---
>>>   kernel/irq/chip.c | 4 ++++
>>>   1 file changed, 4 insertions(+)
>>>
>>> diff --git a/kernel/irq/chip.c b/kernel/irq/chip.c
>>> index 6de638b..bdb1b9d 100644
>>> --- a/kernel/irq/chip.c
>>> +++ b/kernel/irq/chip.c
>>> @@ -1024,6 +1024,10 @@ int irq_chip_set_vcpu_affinity_parent(struct 
>>> irq_data *data, void *vcpu_info)
>>>   int irq_chip_set_wake_parent(struct irq_data *data, unsigned int on)
>>>   {
>>>       data = data->parent_data;
>>> +
>>> +    if (irq_data_get_irq_chip(data)->flags & IRQCHIP_SKIP_SET_WAKE)
>>> +        return 0;
>>> +
>>>       if (data->chip->irq_set_wake)
>>>           return data->chip->irq_set_wake(data, on);
>>>
>>>
>>
>> We have a more general issue with chip flags, and how they combine
>> within a stack of irqchips.
> 
> Indeed. Problem looks similar to IRQCHIP_MASK_ON_SUSPEND flag usage.
> 
>>
>> What if you remove the irq_chip_set_wake_parent from the crossbar
>> driver, and instead set IRQCHIP_SKIP_SET_WAKE?
> 
> I've thought about this and it should work for me.
> One question - what if crossbar will be not the last one in
> IRQ domains hierarchy?
> 

I can confirm, if I revert this patch, add IRQCHIP_SKIP_SET_WAKE to
the crossbar and remove irq_chip_set_wake_parent wakeups still works.
What do you prefer me to do: add additional patch for the crossbar,
drop/keep this patch?

-- 
regards,
-grygorii


From mpa at pengutronix.de  Thu Aug 13 06:07:20 2015
From: mpa at pengutronix.de (Markus Pargmann)
Date: Thu, 13 Aug 2015 15:07:20 +0200
Subject: [PATCH v2] gpio: Allow hogged gpios to be requested
In-Reply-To: <CACRpkdZAjWf3Echvz6Z2hTOF8Bqs=OqLKUTYc04r9vzFo727jg@mail.gmail.com>
References: <1438680424-698-1-git-send-email-mpa@pengutronix.de>
 <CACRpkdZAjWf3Echvz6Z2hTOF8Bqs=OqLKUTYc04r9vzFo727jg@mail.gmail.com>
Message-ID: <20150813130720.GV19600@pengutronix.de>

Hi,

On Mon, Aug 10, 2015 at 11:26:49AM +0200, Linus Walleij wrote:
> On Tue, Aug 4, 2015 at 11:27 AM, Markus Pargmann <mpa at pengutronix.de> wrote:
> 
> > It can be useful to claim hogged gpios later, for example from
> > userspace. This allows to set defaults for GPIOs using the hogging
> > mechanism and override the setup later from userspace or a kernel driver.
> >
> > This patch adds a check for hogged gpios to allow requesting them. If
> > the gpio is not hogged but marked as requested, it still fails with
> > -EBUSY.
> >
> > Signed-off-by: Markus Pargmann <mpa at pengutronix.de>
> 
> To me it feels like a new DT property "gpio-inital-value" or so
> need to be defined in addition to the hogging bindings, and that
> one just sets the GPIO up without setting the FLAG_IS_HOGGED.
> 
> The mechanism needs to be available to non-DT as well
> of course, but it could be a first usecase.
> 
> So instead of:
> 
> line_b {
>            gpio-initval;
>            gpios = <6 0>;
>            output-low;
> };
> 
> Note: no line-name. And it shouldn't be allowed: we don't
> know who will use this in the end.

Sounds good to me. If everyone is okay with this I could go ahead and
implement something like this.

Best Regards,

Markus

-- 
Pengutronix e.K.                           |                             |
Industrial Linux Solutions                 | http://www.pengutronix.de/  |
Peiner Str. 6-8, 31137 Hildesheim, Germany | Phone: +49-5121-206917-0    |
Amtsgericht Hildesheim, HRA 2686           | Fax:   +49-5121-206917-5555 |
-------------- next part --------------
A non-text attachment was scrubbed...
Name: signature.asc
Type: application/pgp-signature
Size: 819 bytes
Desc: Digital signature
URL: <http://lists.infradead.org/pipermail/linux-arm-kernel/attachments/20150813/73758fb7/attachment.sig>

From lee.jones at linaro.org  Thu Aug 13 06:07:36 2015
From: lee.jones at linaro.org (Lee Jones)
Date: Thu, 13 Aug 2015 14:07:36 +0100
Subject: [PATCH v2 5/6] mailbox: Add generic mechanism for testing
 Mailbox Controllers
In-Reply-To: <CABb+yY2OH16mgOwi=yH_eEHQN2Ck2x5xtVk-p-8Un9gGmcACdw@mail.gmail.com>
References: <20150812102328.GD18282@x1>
 <CABb+yY0A74Vy3-KOvj0URU_4zb2FAC7Yp3gmEwnFaBrD0mzt0w@mail.gmail.com>
 <20150813091914.GB8782@x1>
 <CABb+yY0cgbtM68-E_Xqgh5O6GRLXESYTLa5WcAwUBoVL3ufrxA@mail.gmail.com>
 <20150813102335.GC8782@x1>
 <CABb+yY3z7p97eOhncQ2i+g6yoYGfDgSN9BDPKmiDaVLa3oPocA@mail.gmail.com>
 <20150813110008.GD8782@x1>
 <CABb+yY34i=VUnswUE21vgeQYAGOS=7uwvdnTAFFgYkTV0CFk=w@mail.gmail.com>
 <20150813114005.GF8782@x1>
 <CABb+yY2OH16mgOwi=yH_eEHQN2Ck2x5xtVk-p-8Un9gGmcACdw@mail.gmail.com>
Message-ID: <20150813130736.GG8782@x1>

On Thu, 13 Aug 2015, Jassi Brar wrote:

> On Thu, Aug 13, 2015 at 5:10 PM, Lee Jones <lee.jones at linaro.org> wrote:
> > On Thu, 13 Aug 2015, Jassi Brar wrote:
> >
> >> On Thu, Aug 13, 2015 at 4:30 PM, Lee Jones <lee.jones at linaro.org> wrote:
> >> > On Thu, 13 Aug 2015, Jassi Brar wrote:
> >> >
> >> >> On Thu, Aug 13, 2015 at 3:53 PM, Lee Jones <lee.jones at linaro.org> wrote:
> >> >> > On Thu, 13 Aug 2015, Jassi Brar wrote:
> >> >> >
> >> >> >> On Thu, Aug 13, 2015 at 2:49 PM, Lee Jones <lee.jones at linaro.org> wrote:
> >> >> >> > On Thu, 13 Aug 2015, Jassi Brar wrote:
> >> >> >>
> >> >> >> >> >> > +
> >> >> >> >> >> > +static void mbox_test_prepare_message(struct mbox_client *client, void *message)
> >> >> >> >> >> > +{
> >> >> >> >> >> > +       struct mbox_test_device *tdev = dev_get_drvdata(client->dev);
> >> >> >> >> >> > +
> >> >> >> >> >> > +       if (tdev->mmio)
> >> >> >> >> >> > +               memcpy(tdev->mmio, message, MBOX_MAX_MSG_LEN);
> >> >> >> >> >> >
> >> >> >> >> >> This is unlikely to work. Those platforms that need to send a 2 part
> >> >> >> >> >> message, they do :
> >> >> >> >> >> (a) Signal/Command/Target code via some controller register (via
> >> >> >> >> >> mbox_send_message).
> >> >> >> >> >> (b) Setup the payload in Shared-Memory (via tx_prepare).
> >> >> >> >> >>
> >> >> >> >> >> This test driver assumes both are the same. I think you have to
> >> >> >> >> >> declare something like
> >> >> >> >> >
> >> >> >> >> > This driver assumes that the framework will call client->tx_prepare()
> >> >> >> >> > first, which satisfies (b).  It then assumes controller->send_data()
> >> >> >> >> > will be invoked, which will send the platform specific
> >> >> >> >> > signal/command/target code, which then satisfies (a).
> >> >> >> >> >
> >> >> >> >> Yeah, but what would be that code? Who provides that?
> >> >> >> >>
> >> >> >> >> > In what way does it assume they are the same?
> >> >> >> >> >
> >> >> >> >> notice the 'message' pointer in
> >> >> >> >> mbox_send_message(tdev->tx_channel, message);
> >> >> >> >>     and
> >> >> >> >> memcpy(tdev->mmio, message, MBOX_MAX_MSG_LEN);
> >> >> >> >>
> >> >> >> >> >> struct mbox_test_message { /* same for TX and RX */
> >> >> >> >> >>           unsigned sig_len;
> >> >> >> >> >>           void *signal;               /* rx/tx via mailbox api */
> >> >> >> >> >>           unsigned pl_len;
> >> >> >> >> >>           void *payload;           /* rx/tx via shared-memory */
> >> >> >> >> >> };
> >> >> >> >> >
> >> >> >> >> > How do you think this should be set and use these?
> >> >> >> >> >
> >> >> >> >> The userspace would want to specify the command code (32bits or not)
> >> >> >> >> that would be passed via the fifo/register of the controller. So we
> >> >> >> >> need signal[]
> >> >> >> >>
> >> >> >> >> The data to be passed via share-memory could be provided by userspace
> >> >> >> >> via the payload[] array.
> >> >> >> >
> >> >> >> > Okay, so would the solution be two userspace files 'signal' and
> >> >> >> > 'message', so in the case of a client specified signal we can write it
> >> >> >> > into there first.
> >> >> >> >
> >> >> >> > echo 255  > signal
> >> >> >> > echo test > message
> >> >> >> >
> >> >> >> > ... or in the case where no signal is required, or the controller
> >> >> >> > driver taking care of it, we just don't write anything to signal?
> >> >> >> >
> >> >> >> file_operations.write() should parse signal and message, coming from
> >> >> >> userspace, into a local structure before routing them via
> >> >> >> mbox_send_message and tx_prepare respectively.
> >> >> >
> >> >> > Okay.  So before I code this up we should agree on syntax.
> >> >> >
> >> >> > How would you like to represent the break between signal and message?
> >> >> > Obviously ' ' would be a bad idea, as some clients may want to send
> >> >> > messages with white space contained.  How about '\t' or '\n'?
> >> >> >
> >> >> Yeah, I am not a fan of markers and flags either.
> >> >>
> >> >> Maybe we should share with userspace
> >> >>   struct mbox_test_message { /* same for TX and RX */
> >> >>            unsigned sig_len;
> >> >>            void __user *signal;        /* rx/tx via mailbox api */
> >> >>            unsigned pl_len;
> >> >>            void __user *payload;    /* rx/tx via shared-memory */
> >> >>   };
> >> >>
> >> >> First copy_from_user the structure of length sizof(struct
> >> >> mbox_test_message) and then copy_from_user length sig_len and pl_len
> >> >> from signal[] and payload[] respectively (usually ioctls would carry
> >> >> such data).
> >> >
> >> > Simplicity and ease of use should be the goals here.  Testers should
> >> > not have to write applications to use this driver.  Can we come up
> >> > with a simple/effective method that uses SYSFS/DEBUGFS please?
> >> >
> >> > The easiest way I can think of which avoids markers/separators AND the
> >> > requirement for users to have to write applications is to have two
> >> > files, 'signal' and 'message' as mentioned before.  Once both are
> >> > populated I can get this driver to draft the message appropriately and
> >> > fire it off.
> >> >
> >> And then write to more files for RX data? ... which should also be in
> >> the form of 'signal' and 'message'.
> >>
> >> BTW like for spi there is a stock application in
> >> Documentation/spi/spidev_test.c we could do the same?
> >
> > Coming from personal experience, testing drivers with (even stock)
> > applications is much more painful that simply writing/reading
> > (cat/echo) to a file in SYSFS/DEBUGFS.  Particularly if people are
> > using initramfs or thelike.  If it is possible to use SYSFS/DEBUGFS,
> > which it is in this case, then I believe that's the route we could go
> > down.
> >
> Well, where could sysfs/debugfs not be used? :)  Anyways I am ok if
> prefer debugfs.

You know what I mean; CPIO et. al.

> > In answer to your question; we only need those two files.  The reply
> > can be placed back into 'message' and can be read from there.
> >
> Testing shouldn't be restricted to 'send command and receive reply'.
> What if Linux only listens to broadcasts from the remote? Who knows
> someone might want to (ab)use this test client to implement userspace
> handler of remote commands?
> So please see RX to be independent of TX.

Sure.

Now just agree with me that mbox_request_chan() should fail on request
of a known bad configuration request and I can code all this up and
re-submit. :D

-- 
Lee Jones
Linaro STMicroelectronics Landing Team Lead
Linaro.org ? Open source software for ARM SoCs
Follow Linaro: Facebook | Twitter | Blog


From olof at lixom.net  Thu Aug 13 05:40:26 2015
From: olof at lixom.net (Olof Johansson)
Date: Thu, 13 Aug 2015 14:40:26 +0200
Subject: [GIT PULL] ARM64: juno: SCPI and dependent drivers for v4.3
In-Reply-To: <55C1E3FB.5090309@arm.com>
References: <55C1E3FB.5090309@arm.com>
Message-ID: <20150813124026.GD23581@localhost>

On Wed, Aug 05, 2015 at 11:22:51AM +0100, Sudeep Holla wrote:
> Hi Olof,
> 
> 
> Here is the first pull request for SCPI, clock and cpufreq support on
> ARM64 Juno development platform for v4.3

Hi,

I'd like to hear from Catalin and Will on why ARM is doing this. Catalin
and Will are pushing back very hard at vendors who don't use PSCI for
CPU power management, and then they have coworkers that are looking to
merge this directly into the kernel.

Hmm?


-Olof



From olof at lixom.net  Thu Aug 13 06:08:18 2015
From: olof at lixom.net (Olof Johansson)
Date: Thu, 13 Aug 2015 15:08:18 +0200
Subject: [GIT PULL] qcom SoC changes for 4.3 *CORRECTED*
In-Reply-To: <1438379275-6314-1-git-send-email-agross@codeaurora.org>
References: <1438379275-6314-1-git-send-email-agross@codeaurora.org>
Message-ID: <20150813130818.GE23581@localhost>

On Fri, Jul 31, 2015 at 04:47:55PM -0500, Andy Gross wrote:
> The following changes since commit d770e558e21961ad6cfdf0ff7df0eb5d7d4f0754:
> 
>   Linux 4.2-rc1 (2015-07-05 11:01:52 -0700)
> 
> are available in the git repository at:
> 
>   git://codeaurora.org/quic/kernel/agross-msm.git tags/qcom-soc-for-4.3
> 
> for you to fetch changes up to ba68227e610cec8e0bef7da7e04af3f479d9797d:
> 
>   devicetree: soc: Add Qualcomm SMD based RPM DT binding (2015-07-29 14:13:48 -0500)
> 
> ----------------------------------------------------------------
> Qualcomm ARM Based SoC Updates for 4.3
> 
> * Add SMEM driver
> * Add SMD driver
> * Add RPM over SMD driver
> * Select QCOM_SCM by default
> 
> ----------------------------------------------------------------
> Bjorn Andersson (5):
>       soc: qcom: Add Shared Memory Manager driver
>       soc: qcom: Add device tree binding for Shared Memory Device
>       soc: qcom: Add Shared Memory Driver
>       soc: qcom: Driver for the Qualcomm RPM over SMD
>       devicetree: soc: Add Qualcomm SMD based RPM DT binding
> 
> Lina Iyer (1):
>       drivers: qcom: Select QCOM_SCM unconditionally for QCOM_PM

Ok, after looking through it, I've decided to merge this branch.

I'm still concerned that we are picking up similar functionality without
any shared implementation for a lot of platforms right now. At some
point we'll have to say that enough is enough and someone will have to
clean it up.

In the past, Linaro has done some of that work since several members have been
affected. I don't know if this is the right time to kick something off though,
or if we should let a few more implementations surface such that there is
a better set of needed use cases to base a common framework on.


-Olof



From mpa at pengutronix.de  Thu Aug 13 06:14:03 2015
From: mpa at pengutronix.de (Markus Pargmann)
Date: Thu, 13 Aug 2015 15:14:03 +0200
Subject: [PATCH 1/6] gpiolib-of: Rename gpio_hog functions to be generic
In-Reply-To: <CACRpkdYpeoo2scKzNuSYbWfWLTBodXJEX3KyRzoRQPuoaeqzKw@mail.gmail.com>
References: <1438680203-13432-1-git-send-email-mpa@pengutronix.de>
 <1438680203-13432-2-git-send-email-mpa@pengutronix.de>
 <CACRpkdYpeoo2scKzNuSYbWfWLTBodXJEX3KyRzoRQPuoaeqzKw@mail.gmail.com>
Message-ID: <20150813131403.GW19600@pengutronix.de>

On Mon, Aug 10, 2015 at 11:29:58AM +0200, Linus Walleij wrote:
> On Tue, Aug 4, 2015 at 11:23 AM, Markus Pargmann <mpa at pengutronix.de> wrote:
> 
> > The gpio hogging functions are currently only used for gpio-hogging. But
> > these functions are widely generic ones which parse gpio device nodes in
> > the DT.
> >
> > Signed-off-by: Markus Pargmann <mpa at pengutronix.de>
> (...)
> >  /**
> > - * of_get_gpio_hog() - Get a GPIO hog descriptor, names and flags for GPIO API
> > + * of_parse_gpio() - Get a GPIO hog descriptor, names and flags for GPIO API
> 
> It's not a good name, too generic. It could easily be assued this is
> for something
> wider.
> 
> of_parse_own_gpio() or something, indicating that this pertains to the
> chip itself and not to outside users, would be better.

Yes, changed to of_parse_own_gpio() for next version.

Best Regards,

Markus

-- 
Pengutronix e.K.                           |                             |
Industrial Linux Solutions                 | http://www.pengutronix.de/  |
Peiner Str. 6-8, 31137 Hildesheim, Germany | Phone: +49-5121-206917-0    |
Amtsgericht Hildesheim, HRA 2686           | Fax:   +49-5121-206917-5555 |
-------------- next part --------------
A non-text attachment was scrubbed...
Name: signature.asc
Type: application/pgp-signature
Size: 819 bytes
Desc: Digital signature
URL: <http://lists.infradead.org/pipermail/linux-arm-kernel/attachments/20150813/06c025d3/attachment.sig>

From Suravee.Suthikulpanit at amd.com  Thu Aug 13 06:16:30 2015
From: Suravee.Suthikulpanit at amd.com (Suravee Suthikulpanit)
Date: Thu, 13 Aug 2015 20:16:30 +0700
Subject: [PATCH v4 1/3] PCI: generic: remove dependency on hw_pci
In-Reply-To: <20150805092318.GB6092@arm.com>
References: <1438721620-15493-1-git-send-email-jchandra@broadcom.com>
 <20150804234956.GF17327@google.com> <20150805092318.GB6092@arm.com>
Message-ID: <55CC98AE.5010604@amd.com>

Hi Bjorn,

On 8/5/15 16:23, Will Deacon wrote:
> On Wed, Aug 05, 2015 at 12:49:56AM +0100, Bjorn Helgaas wrote:
>> >On Wed, Aug 05, 2015 at 02:23:38AM +0530, Jayachandran C wrote:
>>> > >The current code in pci-host-generic.c uses pci_common_init_dev()
>>> > >from arm architecture to do some part of the PCI setup, and this
>>> > >prevents it from being used with arm64 architecture.
>>> > >
>>> > >The part of pci_common_init_dev() that is really needed by
>>> > >pci-host-generic.c is very limited and can be done in the same
>>> > >file without using hw_pci API of ARM. The ARM platform requires
>>> > >a pci_sys_data as sysdata for the PCI bus, this can be handled by
>>> > >setting up gen_pci to have a pci_sys_data variable as the first
>>> > >element.
>>> > >
>>> > >Signed-off-by: Jayachandran C<jchandra at broadcom.com>
>>> > >Acked-by: Lorenzo Pieralisi<lorenzo.pieralisi at arm.com>
>>> > >Tested-by: Lorenzo Pieralisi<lorenzo.pieralisi at arm.com>
>>> > >Tested-by: Pavel Fedin<p.fedin at samsung.com>
>> >
>> >I applied all three of these to my pci/enumeration branch for v4.3.
>> >
>> >I made a few changes, the most important being to call
>> >pcie_bus_configure_settings() before pci_bus_add_devices(), because drivers
>> >may claim devices in pci_bus_add_devices(), and the PCI core shouldn't
>> >touch devices after drivers claim them.
>> >
>> >I dropped the acks and tested-by because of that change, but I'll happily
>> >add them back if Lorenzo and Pavel confirm.  The patches are here if you
>> >want to review/test them:
>> >
>> >https://git.kernel.org/cgit/linux/kernel/git/helgaas/pci.git/log/?h=pci/enumeration
>> >
>> >I'm sure the other patches on that branch will need some tweaks, too, so I
>> >don't have any problem with updating these.

I have also tested on AMD Seattle (w/ non-PROBE_ONLY mode).

Tested-by: Suravee Suthikulpanit <Suravee.Suthikulpanit at amd.com>


From maitysanchayan at gmail.com  Thu Aug 13 06:17:20 2015
From: maitysanchayan at gmail.com (maitysanchayan at gmail.com)
Date: Thu, 13 Aug 2015 18:47:20 +0530
Subject: [PATCH v3 0/3] Add support for touchscreen on Colibri VF50
In-Reply-To: <cover.1438763030.git.maitysanchayan@gmail.com>
References: <cover.1438763030.git.maitysanchayan@gmail.com>
Message-ID: <20150813131720.GA2925@Sanchayan-Arch.toradex.int>

Hello,

Ping?

- Sanchayan.

On 15-08-05 14:25:48, Sanchayan Maity wrote:
> Hello,
> 
> The patchset adds support for 4 wire touchscreen on Toradex Colibri
> VF50 modules. Patches are tested on top of shawn's for-next branch.
> 
> Changes since v2:
> 1. Fix pin multiplexing for pins in idle state. Configuration of the
> pen detect pull up viz. PTA19__GPIO_9 resulted in generation of pen
> irq's on a continuous basis.
> 2. Fix pinmux of the ADC pins as per the recommended pinmux in TRM.
> 3. Use a threaded irq handler instead of a irq handler plus workqueue
> approach.
> 4. Use a low level trigger with oneshot flag specifier instead of the
> previous falling edge triggered irq's. This coupled with the fix in
> point 1 fixes the previous continuous spurious irq generation bug.
> 5. Change/fix the TS measurement logic to account for the fact that
> iio_channel_read_raw might actually return an error. To be more
> specific use break instead of continue and take care to close the
> FET's in case of channel read error.
> 6. Drop the first patch "Add io-channel-cells property for ADC node"
> as it has already been applied.
> 7. Move the iio channel get call again at the start. Having it in
> the end resulted in crashes sometimes when iio was not probed and
> the ts device got probed and opened earlier.
> 
> Changes since v1:
> 1. Fix/drop comments
> 2. Use an inline function for multiple gpiod_get calls in probe
> 3. Remove the pull up in the pinmux specified in DT for touchctrl_gpios
> 4. Add the io-channel-cells property before status property.
> 5. Add GPIOLIB as dependency in the Kconfig file
> 
> Version 2 of the patchset can be found here
> https://www.mail-archive.com/linux-input at vger.kernel.org/msg18090.html
> 
> Version 1 of the patchset can be found here
> https://lkml.org/lkml/2015/6/30/103
> 
> Thank you very much for the feedback till now.
> 
> Regards,
> Sanchayan.
> 
> Sanchayan Maity (3):
>   ARM: dts: vf500-colibri: Add device tree node for touchscreen support
>   input: Add DT binding documentation for Colibri VF50 touchscreen
>   touchscreen: colibri-vf50-ts: Add touchscreen support for Colibri VF50
> 
>  .../bindings/input/touchscreen/colibri-vf50-ts.txt |  32 ++
>  arch/arm/boot/dts/vf500-colibri-eval-v3.dts        |   4 +
>  arch/arm/boot/dts/vf500-colibri.dtsi               |  45 +++
>  drivers/input/touchscreen/Kconfig                  |  12 +
>  drivers/input/touchscreen/Makefile                 |   1 +
>  drivers/input/touchscreen/colibri-vf50-ts.c        | 404 +++++++++++++++++++++
>  6 files changed, 498 insertions(+)
>  create mode 100644 Documentation/devicetree/bindings/input/touchscreen/colibri-vf50-ts.txt
>  create mode 100644 drivers/input/touchscreen/colibri-vf50-ts.c
> 
> -- 
> 2.5.0
> 


From mpa at pengutronix.de  Thu Aug 13 06:28:13 2015
From: mpa at pengutronix.de (Markus Pargmann)
Date: Thu, 13 Aug 2015 15:28:13 +0200
Subject: [PATCH 2/6] gpio: Introduce gpio descriptor 'name'
In-Reply-To: <CACRpkdYv=-fCj+ts9tTmFsovPN0RPYkOdYh9Dj6oFDJiRV=RUA@mail.gmail.com>
References: <1438680203-13432-1-git-send-email-mpa@pengutronix.de>
 <1438680203-13432-3-git-send-email-mpa@pengutronix.de>
 <CACRpkdYv=-fCj+ts9tTmFsovPN0RPYkOdYh9Dj6oFDJiRV=RUA@mail.gmail.com>
Message-ID: <20150813132813.GX19600@pengutronix.de>

On Mon, Aug 10, 2015 at 11:37:06AM +0200, Linus Walleij wrote:
> On Tue, Aug 4, 2015 at 11:23 AM, Markus Pargmann <mpa at pengutronix.de> wrote:
> 
> > The latest gpio hogging mechanism assigns each gpio a 'line-name' in the
> > devicetree. The 'name' field is different from the 'label' field.
> > 'label' is only used for requested GPIOs to describe its current use by
> > driver or userspace.
> >
> > The 'name' field describes the GPIO itself, not the use. This is most
> > likely identical to the label in the schematic on the GPIO line and
> > should help to find this particular GPIO.
> >
> > This patch adds a helper function to find gpio descriptors by name
> > instead of gpio number.
> >
> > Signed-off-by: Markus Pargmann <mpa at pengutronix.de>
> 
> Oh I realized there is a big problem with this.
> 
> struct gpio_chip already contains this:
> 
>         const char              *const *names;
> 
> Now it seems like names can be stored in two places:
> in an array in the gpio_chip and in a name tag in struct
> gpio_desc.
> 
> So how do we handle this?
> 
> I guess we need to keep just *one* of them, so maybe remove
> the names array from the struct gpio_chip and add a helper function
> that sets the names on the descs for the lines like:
> 
> int gpiochip_set_names(struct gpio_chip *gc, const char * const names);
> 
> And then refactor all code and chips that use the old names
> array to use this instead. I don't think they are too many, really.

That sounds good. There are just a few users of this names array, so it
should all be fine.

Just to clarify: The line names will then be the same as this name
array? So all GPIOs with name/line-names are then exported by their name
and not the number?

Best Regards,

Markus

-- 
Pengutronix e.K.                           |                             |
Industrial Linux Solutions                 | http://www.pengutronix.de/  |
Peiner Str. 6-8, 31137 Hildesheim, Germany | Phone: +49-5121-206917-0    |
Amtsgericht Hildesheim, HRA 2686           | Fax:   +49-5121-206917-5555 |
-------------- next part --------------
A non-text attachment was scrubbed...
Name: signature.asc
Type: application/pgp-signature
Size: 819 bytes
Desc: Digital signature
URL: <http://lists.infradead.org/pipermail/linux-arm-kernel/attachments/20150813/240de3a7/attachment-0001.sig>

From mpa at pengutronix.de  Thu Aug 13 06:43:33 2015
From: mpa at pengutronix.de (Markus Pargmann)
Date: Thu, 13 Aug 2015 15:43:33 +0200
Subject: [PATCH 5/6] gpiolib-sysfs: Show gpio-name in
 /sys/class/gpio/gpio*/name
In-Reply-To: <CACRpkdZCSwWUuhbe2+nrEPTRnqNGvJrrbZLDwy8fkHeEJDujUg@mail.gmail.com>
References: <1438680203-13432-1-git-send-email-mpa@pengutronix.de>
 <1438680203-13432-6-git-send-email-mpa@pengutronix.de>
 <CACRpkdZCSwWUuhbe2+nrEPTRnqNGvJrrbZLDwy8fkHeEJDujUg@mail.gmail.com>
Message-ID: <20150813134333.GY19600@pengutronix.de>

On Mon, Aug 10, 2015 at 11:50:16AM +0200, Linus Walleij wrote:
> On Tue, Aug 4, 2015 at 11:23 AM, Markus Pargmann <mpa at pengutronix.de> wrote:
> 
> > This patch adds a sysfs attribute 'name' to gpios that were exported. It
> > exposes the newly added name property of gpio descriptors.
> >
> > Signed-off-by: Markus Pargmann <mpa at pengutronix.de>
> 
> This needs to also patch Documentation/ABI/testing/sysfs-gpio
> if we should go with it. It says this:

Right, forgot about that documentation.

> 
>     /sys/class/gpio
>         /export ... asks the kernel to export a GPIO to userspace
>         /unexport ... to return a GPIO to the kernel
>         /gpioN ... for each exported GPIO #N
>             /value ... always readable, writes fail for input GPIOs
>             /direction ... r/w as: in, out (default low); write: high, low
>             /edge ... r/w as: none, falling, rising, both
> 
> Anyways I don't know if this is right, and that ABI doc is also lying.
> 
> Look at this in gpiolib-sysfs.c:
> 
>         if (chip->names && chip->names[offset])
>                 ioname = chip->names[offset];
> 
>         dev = device_create_with_groups(&gpio_class, chip->dev,
>                                         MKDEV(0, 0), data, gpio_groups,
>                                         ioname ? ioname : "gpio%u",
>                                         desc_to_gpio(desc));
> 
> I.e. what the ABI doc say about the dirs being named "gpioN" is
> a plain lie, it can have a descriptive name as its directory  name
> under /sys/class/gpio/foo-line or so.
> 
> Since this already exist and is a flat namespace ... we should
> use that.
> 
> However it has the implication like I said before that two names
> cannot be the same. I think Johan's comment that they could
> be non-unique did not take into account the fact that two chips
> could use the same .names array (and that would already fail,
> by the way) so the .names in the struct gpio_chip *MUST* be
> unique as compared to all other names.
> 
> We *could* deprecate the old line naming mechanism (that create
> dirs named after the pin), and from here on only use gpioN and
> "name" in a separate file like this patch does. However that is
> not really OK either: we want to move away from the GPIO numbers
> and to descriptors and descriptive names, so I currently feel
> we should name the directories after the line instead, and
> require them to be unique.

Ok, this also answers the question I just had in the other mail.

Best Regards,

Markus

> 
> I'll have to patch this document now anyways because it is
> lying about the ABI :(
> 
> Yours,
> Linus Walleij
> 

-- 
Pengutronix e.K.                           |                             |
Industrial Linux Solutions                 | http://www.pengutronix.de/  |
Peiner Str. 6-8, 31137 Hildesheim, Germany | Phone: +49-5121-206917-0    |
Amtsgericht Hildesheim, HRA 2686           | Fax:   +49-5121-206917-5555 |
-------------- next part --------------
A non-text attachment was scrubbed...
Name: signature.asc
Type: application/pgp-signature
Size: 819 bytes
Desc: Digital signature
URL: <http://lists.infradead.org/pipermail/linux-arm-kernel/attachments/20150813/6621e989/attachment.sig>

From jassisinghbrar at gmail.com  Thu Aug 13 06:46:20 2015
From: jassisinghbrar at gmail.com (Jassi Brar)
Date: Thu, 13 Aug 2015 19:16:20 +0530
Subject: [PATCH v2 5/6] mailbox: Add generic mechanism for testing Mailbox
 Controllers
In-Reply-To: <20150813130736.GG8782@x1>
References: <20150812102328.GD18282@x1>
 <CABb+yY0A74Vy3-KOvj0URU_4zb2FAC7Yp3gmEwnFaBrD0mzt0w@mail.gmail.com>
 <20150813091914.GB8782@x1>
 <CABb+yY0cgbtM68-E_Xqgh5O6GRLXESYTLa5WcAwUBoVL3ufrxA@mail.gmail.com>
 <20150813102335.GC8782@x1>
 <CABb+yY3z7p97eOhncQ2i+g6yoYGfDgSN9BDPKmiDaVLa3oPocA@mail.gmail.com>
 <20150813110008.GD8782@x1>
 <CABb+yY34i=VUnswUE21vgeQYAGOS=7uwvdnTAFFgYkTV0CFk=w@mail.gmail.com>
 <20150813114005.GF8782@x1>
 <CABb+yY2OH16mgOwi=yH_eEHQN2Ck2x5xtVk-p-8Un9gGmcACdw@mail.gmail.com>
 <20150813130736.GG8782@x1>
Message-ID: <CABb+yY2N6=oTrwni0tw1WffLv-udtBWh9LJR43EMVqYf+i2xUg@mail.gmail.com>

On Thu, Aug 13, 2015 at 6:37 PM, Lee Jones <lee.jones at linaro.org> wrote:
>
> Now just agree with me that mbox_request_chan() should fail on request
> of a known bad configuration request and I can code all this up and
> re-submit. :D
>
You make me look like a jerk :(   My problem is not with validation as
such. I see problem in the way you implement that makes validation
necessary. I'll explain step-by-step in the driver post.


From linus.walleij at linaro.org  Thu Aug 13 06:54:18 2015
From: linus.walleij at linaro.org (Linus Walleij)
Date: Thu, 13 Aug 2015 15:54:18 +0200
Subject: [PATCH 2/2] soc/fsl: add ftm alarm driver for ls1021a platform
In-Reply-To: <1439358807-9024-2-git-send-email-dongsheng.wang@freescale.com>
References: <1439358807-9024-1-git-send-email-dongsheng.wang@freescale.com>
 <1439358807-9024-2-git-send-email-dongsheng.wang@freescale.com>
Message-ID: <CACRpkdbninKuGzhEc5mN+85j-=w_wYQgra-Ark_Du6gWKN2=tg@mail.gmail.com>

On Wed, Aug 12, 2015 at 7:53 AM, Dongsheng Wang
<dongsheng.wang at freescale.com> wrote:

> From: Wang Dongsheng <dongsheng.wang at freescale.com>
>
> Only Ftm0 can be used when system going to deep sleep. So this driver
> to support ftm0 as a wakeup source.
>
> Signed-off-by: Wang Dongsheng <dongsheng.wang at freescale.com>
> ---
> *V2*
> Change Copyright 2014 to 2015.
(...)
> +config FTM_ALARM
> +       bool "FTM alarm driver"
> +       depends on SOC_LS1021A
> +       default n
> +       help
> +         Say y here to enable FTM alarm support.  The FTM alarm provides
> +         alarm functions for wakeup system from deep sleep.  There is only
> +         one FTM can be used in ALARM(FTM 0).
(...)
> +static u32 time_to_cycle(unsigned long time)
> +static u32 cycle_to_time(u32 cycle)
> +static int ftm_set_alarm(u64 cycle)
> +static irqreturn_t ftm_alarm_interrupt(int irq, void *dev_id)
> +static ssize_t ftm_alarm_show(struct device *dev,
> +                             struct device_attribute *attr,
> +                             char *buf)
> +static ssize_t ftm_alarm_store(struct device *dev,
> +                              struct device_attribute *attr,
> +                              const char *buf, size_t count)
(...)
> +static struct device_attribute ftm_alarm_attributes = __ATTR(ftm_alarm, 0644,
> +                       ftm_alarm_show, ftm_alarm_store);

If you're gonna invent ABIs, document then in Documentation/ABI/testing/*.

But I don't get it. Why is this driver not in drivers/rtc?

It does a subset of what an RTC does. The ioctl()'s of an RTC
can do what you want to do. And much much more.

If it can't do all an RTC can do, surely the RTC subsystem
can be augmented to host it anyway. It's way to close to
an RTC to have it's own random sysfs driver like this.

Unless I'm totally off, rewrite this to an RTC driver and post
it to the RTC maintainers.

Yours,
Linus Walleij


From gregory.clement at free-electrons.com  Thu Aug 13 06:59:25 2015
From: gregory.clement at free-electrons.com (Gregory CLEMENT)
Date: Thu, 13 Aug 2015 15:59:25 +0200
Subject: [PATCH] ARM: dma-mapping: Don't use outer_flush_range when the L2C is
 coherent
Message-ID: <1439474365-12058-1-git-send-email-gregory.clement@free-electrons.com>

When a L2 cache controller is used in a system that provides hardware
coherency, the entire outer cache operations are useless, and can be
skipped.  Moreover, on some systems, it is harmful as it causes
deadlocks between the Marvell coherency mechanism, the Marvell PCIe
controller and the Cortex-A9.

In the current kernel implementation, the outer cache flush range
operation is triggered by the dma_alloc function.
This operation can be take place during runtime and in some
circumstances may lead to the PCIe/PL310 deadlock on Armada 375/38x
SoCs.

This patch extends the __dma_clear_buffer() function to receive a
boolean argument related to the coherency of the system. The same
things is done for the calling functions. In order to be consistent
the iommu variant of dma_alloc are also updated.

Reported-by: Nadav Haklai <nadavh at marvell.com>
Signed-off-by: Gregory CLEMENT <gregory.clement at free-electrons.com>
Cc: <stable at vger.kernel.org> # v3.16+
---
 arch/arm/mm/dma-mapping.c | 58 ++++++++++++++++++++++++++++++++++-------------
 1 file changed, 42 insertions(+), 16 deletions(-)

diff --git a/arch/arm/mm/dma-mapping.c b/arch/arm/mm/dma-mapping.c
index 1ced8a0f7a52..ccd792af2c51 100644
--- a/arch/arm/mm/dma-mapping.c
+++ b/arch/arm/mm/dma-mapping.c
@@ -224,7 +224,7 @@ static u64 get_coherent_dma_mask(struct device *dev)
 	return mask;
 }
 
-static void __dma_clear_buffer(struct page *page, size_t size)
+static void __dma_clear_buffer(struct page *page, size_t size, bool is_coherent)
 {
 	/*
 	 * Ensure that the allocated pages are zeroed, and that any data
@@ -241,12 +241,15 @@ static void __dma_clear_buffer(struct page *page, size_t size)
 			page++;
 			size -= PAGE_SIZE;
 		}
-		outer_flush_range(base, end);
+		if (!is_coherent)
+			outer_flush_range(base, end);
 	} else {
 		void *ptr = page_address(page);
 		memset(ptr, 0, size);
-		dmac_flush_range(ptr, ptr + size);
-		outer_flush_range(__pa(ptr), __pa(ptr) + size);
+		if (!is_coherent) {
+			dmac_flush_range(ptr, ptr + size);
+			outer_flush_range(__pa(ptr), __pa(ptr) + size);
+		}
 	}
 }
 
@@ -254,7 +257,8 @@ static void __dma_clear_buffer(struct page *page, size_t size)
  * Allocate a DMA buffer for 'dev' of size 'size' using the
  * specified gfp mask.  Note that 'size' must be page aligned.
  */
-static struct page *__dma_alloc_buffer(struct device *dev, size_t size, gfp_t gfp)
+static struct page *__dma_alloc_buffer(struct device *dev, size_t size,
+				gfp_t gfp, bool is_coherent)
 {
 	unsigned long order = get_order(size);
 	struct page *page, *p, *e;
@@ -270,7 +274,7 @@ static struct page *__dma_alloc_buffer(struct device *dev, size_t size, gfp_t gf
 	for (p = page + (size >> PAGE_SHIFT), e = page + (1 << order); p < e; p++)
 		__free_page(p);
 
-	__dma_clear_buffer(page, size);
+	__dma_clear_buffer(page, size, is_coherent);
 
 	return page;
 }
@@ -474,7 +478,8 @@ static void *__alloc_remap_buffer(struct device *dev, size_t size, gfp_t gfp,
 {
 	struct page *page;
 	void *ptr = NULL;
-	page = __dma_alloc_buffer(dev, size, gfp);
+	/* This function is only called when the arch is non-coherent */
+	page = __dma_alloc_buffer(dev, size, gfp, false);
 	if (!page)
 		return NULL;
 	if (!want_vaddr)
@@ -540,7 +545,13 @@ static void *__alloc_from_contiguous(struct device *dev, size_t size,
 	if (!page)
 		return NULL;
 
-	__dma_clear_buffer(page, size);
+	/*
+	 * We are either called from __dma_alloc on the non-coherent
+	 * case or only once from atomic_pool_init. It is called
+	 * during boot time so it is harmless to use the non-coherent
+	 * case even if the L2C is coherent.
+	 */
+	__dma_clear_buffer(page, size, false);
 
 	if (!want_vaddr)
 		goto out;
@@ -601,7 +612,8 @@ static void *__alloc_simple_buffer(struct device *dev, size_t size, gfp_t gfp,
 				   struct page **ret_page)
 {
 	struct page *page;
-	page = __dma_alloc_buffer(dev, size, gfp);
+	/* This function is only called when the arch is coherent */
+	page = __dma_alloc_buffer(dev, size, gfp, true);
 	if (!page)
 		return NULL;
 
@@ -1131,7 +1143,8 @@ static inline void __free_iova(struct dma_iommu_mapping *mapping,
 }
 
 static struct page **__iommu_alloc_buffer(struct device *dev, size_t size,
-					  gfp_t gfp, struct dma_attrs *attrs)
+					gfp_t gfp, struct dma_attrs *attrs,
+					bool is_coherent)
 {
 	struct page **pages;
 	int count = size >> PAGE_SHIFT;
@@ -1154,7 +1167,7 @@ static struct page **__iommu_alloc_buffer(struct device *dev, size_t size,
 		if (!page)
 			goto error;
 
-		__dma_clear_buffer(page, size);
+		__dma_clear_buffer(page, size, is_coherent);
 
 		for (i = 0; i < count; i++)
 			pages[i] = page + i;
@@ -1198,7 +1211,7 @@ static struct page **__iommu_alloc_buffer(struct device *dev, size_t size,
 				pages[i + j] = pages[i] + j;
 		}
 
-		__dma_clear_buffer(pages[i], PAGE_SIZE << order);
+		__dma_clear_buffer(pages[i], PAGE_SIZE << order, is_coherent);
 		i += 1 << order;
 		count -= 1 << order;
 	}
@@ -1359,8 +1372,9 @@ static void __iommu_free_atomic(struct device *dev, void *cpu_addr,
 	__free_from_pool(cpu_addr, size);
 }
 
-static void *arm_iommu_alloc_attrs(struct device *dev, size_t size,
-	    dma_addr_t *handle, gfp_t gfp, struct dma_attrs *attrs)
+static void *__arm_iommu_alloc_attrs(struct device *dev, size_t size,
+	    dma_addr_t *handle, gfp_t gfp, struct dma_attrs *attrs,
+	    bool is_coherent)
 {
 	pgprot_t prot = __get_dma_pgprot(attrs, PAGE_KERNEL);
 	struct page **pages;
@@ -1381,7 +1395,7 @@ static void *arm_iommu_alloc_attrs(struct device *dev, size_t size,
 	 */
 	gfp &= ~(__GFP_COMP);
 
-	pages = __iommu_alloc_buffer(dev, size, gfp, attrs);
+	pages = __iommu_alloc_buffer(dev, size, gfp, attrs, is_coherent);
 	if (!pages)
 		return NULL;
 
@@ -1406,6 +1420,18 @@ err_buffer:
 	return NULL;
 }
 
+static void *arm_iommu_alloc_attrs(struct device *dev, size_t size,
+	    dma_addr_t *handle, gfp_t gfp, struct dma_attrs *attrs)
+{
+	__arm_iommu_alloc_attrs(dev, size, handle, gfp, attrs, false);
+}
+
+static void *arm_coherent_iommu_alloc_attrs(struct device *dev, size_t size,
+	    dma_addr_t *handle, gfp_t gfp, struct dma_attrs *attrs)
+{
+	__arm_iommu_alloc_attrs(dev, size, handle, gfp, attrs, true);
+}
+
 static int arm_iommu_mmap_attrs(struct device *dev, struct vm_area_struct *vma,
 		    void *cpu_addr, dma_addr_t dma_addr, size_t size,
 		    struct dma_attrs *attrs)
@@ -1868,7 +1894,7 @@ struct dma_map_ops iommu_ops = {
 };
 
 struct dma_map_ops iommu_coherent_ops = {
-	.alloc		= arm_iommu_alloc_attrs,
+	.alloc		= arm_coherent_iommu_alloc_attrs,
 	.free		= arm_iommu_free_attrs,
 	.mmap		= arm_iommu_mmap_attrs,
 	.get_sgtable	= arm_iommu_get_sgtable,
-- 
2.1.0



From linus.walleij at linaro.org  Thu Aug 13 07:06:26 2015
From: linus.walleij at linaro.org (Linus Walleij)
Date: Thu, 13 Aug 2015 16:06:26 +0200
Subject: [PATCH v2] pinctrl: sun4i: add spdif to pin description.
In-Reply-To: <1439400468-1563-2-git-send-email-codekipper@gmail.com>
References: <1439400468-1563-1-git-send-email-codekipper@gmail.com>
 <1439400468-1563-2-git-send-email-codekipper@gmail.com>
Message-ID: <CACRpkdby6DPxnQPxMfxqw1r06Cuq3ZEjmdJHebU9R=oM52GecA@mail.gmail.com>

On Wed, Aug 12, 2015 at 7:27 PM,  <codekipper at gmail.com> wrote:

> From: Marcus Cooper <codekipper at gmail.com>
>
> Signed-off-by: Marcus Cooper <codekipper at gmail.com>

Patch applied with Hans' ACK.

Yours,
Linus Walleij


From ricardo.ribalda at gmail.com  Thu Aug 13 07:09:28 2015
From: ricardo.ribalda at gmail.com (Ricardo Ribalda Delgado)
Date: Thu, 13 Aug 2015 16:09:28 +0200
Subject: [PATCH] spi/spi-xilinx: Fix spurious IRQ ACK on irq mode
Message-ID: <1439474968-10260-1-git-send-email-ricardo.ribalda@gmail.com>

The ACK of an inexistent IRQ can trigger an spurious IRQ that breaks the
txrx logic. This has been observed on axi_quad_spi:3.2 core.

This patch only ACKs IRQs that have not been Acknowledge jet.

Reported-by: Edward Kigwana <ekigwana at scires.com>
Tested-by: Edward Kigwana <ekigwana at scires.com>
Signed-off-by: Ricardo Ribalda Delgado <ricardo.ribalda at gmail.com>
---
 drivers/spi/spi-xilinx.c | 16 ++++++++++------
 1 file changed, 10 insertions(+), 6 deletions(-)

diff --git a/drivers/spi/spi-xilinx.c b/drivers/spi/spi-xilinx.c
index 7abf6792cc11..a339c1e9997a 100644
--- a/drivers/spi/spi-xilinx.c
+++ b/drivers/spi/spi-xilinx.c
@@ -249,19 +249,23 @@ static int xilinx_spi_txrx_bufs(struct spi_device *spi, struct spi_transfer *t)
 	xspi->tx_ptr = t->tx_buf;
 	xspi->rx_ptr = t->rx_buf;
 	remaining_words = t->len / xspi->bytes_per_word;
-	reinit_completion(&xspi->done);
 
 	if (xspi->irq >= 0 &&  remaining_words > xspi->buffer_size) {
+		u32 isr;
 		use_irq = true;
-		xspi->write_fn(XSPI_INTR_TX_EMPTY,
-				xspi->regs + XIPIF_V123B_IISR_OFFSET);
-		/* Enable the global IPIF interrupt */
-		xspi->write_fn(XIPIF_V123B_GINTR_ENABLE,
-				xspi->regs + XIPIF_V123B_DGIER_OFFSET);
 		/* Inhibit irq to avoid spurious irqs on tx_empty*/
 		cr = xspi->read_fn(xspi->regs + XSPI_CR_OFFSET);
 		xspi->write_fn(cr | XSPI_CR_TRANS_INHIBIT,
 			       xspi->regs + XSPI_CR_OFFSET);
+		/* ACK old irqs (if any) */
+		isr = xspi->read_fn(xspi->regs + XIPIF_V123B_IISR_OFFSET);
+		if (isr)
+			xspi->write_fn(isr,
+				       xspi->regs + XIPIF_V123B_IISR_OFFSET);
+		/* Enable the global IPIF interrupt */
+		xspi->write_fn(XIPIF_V123B_GINTR_ENABLE,
+				xspi->regs + XIPIF_V123B_DGIER_OFFSET);
+		reinit_completion(&xspi->done);
 	}
 
 	while (remaining_words) {
-- 
2.5.0



From linus.walleij at linaro.org  Thu Aug 13 07:10:52 2015
From: linus.walleij at linaro.org (Linus Walleij)
Date: Thu, 13 Aug 2015 16:10:52 +0200
Subject: [PATCH v5 1/2] clk: rockchip: add pclk_pd_pmu to the list of
 rk3288 critical clocks
In-Reply-To: <1439287924-6988-1-git-send-email-hl@rock-chips.com>
References: <1439287924-6988-1-git-send-email-hl@rock-chips.com>
Message-ID: <CACRpkdZpk+djjb08Ls0CQdCD=wmNYQSDTMWwgJs_CMGYWXpoQw@mail.gmail.com>

On Tue, Aug 11, 2015 at 12:12 PM, Lin Huang <hl at rock-chips.com> wrote:

> From: Heiko Stuebner <heiko at sntech.de>
>
> pclk_pd_pmu needs to keep running and with the upcoming gpio clock
> handling this is not always the case anymore. So add it to the list
> of critical clocks for now.
>
> Signed-off-by: Heiko Stuebner <heiko at sntech.de>
> Signed-off-by: Lin Huang <hl at rock-chips.com>
> ---
> Changes in v5:
> - Add From: Heiko Stuebner <heiko at sntech.de>
> - Add Signed-off-by: Heiko Stuebner <heiko at sntech.de>

Patch applied to the pinctrl tree with Doug's reviwe tag and
Stephen B's ACK.

Yours,
Linus Walleij


From linus.walleij at linaro.org  Thu Aug 13 07:11:38 2015
From: linus.walleij at linaro.org (Linus Walleij)
Date: Thu, 13 Aug 2015 16:11:38 +0200
Subject: [PATCH v5 2/2] pinctrl: rockchip: only enable gpio clock when it
 setting
In-Reply-To: <2167165.ooWgarx4Ov@diego>
References: <1439287924-6988-1-git-send-email-hl@rock-chips.com>
 <1439287924-6988-2-git-send-email-hl@rock-chips.com>
 <CACRpkda0FXz1dpdS-wLRNmkt1KBESMyCWKMMa0ArH9Z-L=i_sw@mail.gmail.com>
 <2167165.ooWgarx4Ov@diego>
Message-ID: <CACRpkdYYdqm+CfejMA6yrDheNA=3H13zsW2XuKqqYDRNMS=07w@mail.gmail.com>

On Thu, Aug 13, 2015 at 2:37 PM, Heiko St?bner <heiko at sntech.de> wrote:

>> Patch applied with Doug's test tags etc.
>
> did you  also take the first patch?
>
> Aka bot should probably stay together (hence Stephen's Ack for the clock
> change), as the dynamically controlling the gpio clocks exposes the
> pclk_pd_pmu.

OK wasn't obvious to me, patch 1/2 applied to the pinctrl tree now.

Yours,
Linus Walleij


From thierry.reding at gmail.com  Thu Aug 13 07:16:40 2015
From: thierry.reding at gmail.com (Thierry Reding)
Date: Thu, 13 Aug 2015 16:16:40 +0200
Subject: [PATCH] [ARM][TEGRA] Fix AHB base address on tegra20, tegra30
 and tegra114
In-Reply-To: <1439042292-19912-1-git-send-email-kwizart@gmail.com>
References: <1439042292-19912-1-git-send-email-kwizart@gmail.com>
Message-ID: <20150813141639.GA26559@ulmo>

On Sat, Aug 08, 2015 at 03:58:12PM +0200, Nicolas Chauvet wrote:
> Current base address is wrong by 0x04 bytes for AHB bus device as shown in dmesg:
>  tegra-ahb 6000c004.ahb: incorrect AHB base address in DT data - enabling workaround
> 
> To correct old dtbs,  the commit ce7a10b0ff3db63 checks for the low bit
> of the base address and removes theses 0x04 bytes at runtime.
> 
> This patch fix the original dts, so upstream version doesn't need
> the workaround of the base address.
> 
> As both addresses are valid, this patch doesn't break compatibility
> 
> Tested on tegra20-paz00 (aka ac100)
> 
> Signed-off-by: Nicolas Chauvet <kwizart at gmail.com>
> ---
>  arch/arm/boot/dts/tegra114.dtsi | 4 ++--
>  arch/arm/boot/dts/tegra20.dtsi  | 4 ++--
>  arch/arm/boot/dts/tegra30.dtsi  | 4 ++--
>  3 files changed, 6 insertions(+), 6 deletions(-)

Applied, thanks.

Thierry
-------------- next part --------------
A non-text attachment was scrubbed...
Name: signature.asc
Type: application/pgp-signature
Size: 819 bytes
Desc: not available
URL: <http://lists.infradead.org/pipermail/linux-arm-kernel/attachments/20150813/f2090462/attachment.sig>

From thierry.reding at gmail.com  Thu Aug 13 07:18:41 2015
From: thierry.reding at gmail.com (Thierry Reding)
Date: Thu, 13 Aug 2015 16:18:41 +0200
Subject: [PATCH] soc: tegra: remove redundant $(CONFIG_ARCH_TEGRA) in
 Makefile
In-Reply-To: <1438322301-24584-1-git-send-email-yamada.masahiro@socionext.com>
References: <1438322301-24584-1-git-send-email-yamada.masahiro@socionext.com>
Message-ID: <20150813141840.GB26559@ulmo>

On Fri, Jul 31, 2015 at 02:58:21PM +0900, Masahiro Yamada wrote:
> Kbuild descends into drivers/soc/tegra/ only when CONFIG_ARCH_TEGRA
> is enabled. (see drivers/soc/Makefile)
> 
> $(CONFIG_ARCH_TEGRA) in drivers/soc/tegra/Makefile always evaluates
> to 'y'.
> 
> Signed-off-by: Masahiro Yamada <yamada.masahiro at socionext.com>
> ---
> 
>  drivers/soc/tegra/Makefile | 6 +++---
>  1 file changed, 3 insertions(+), 3 deletions(-)

Applied, thanks.

Thierry
-------------- next part --------------
A non-text attachment was scrubbed...
Name: signature.asc
Type: application/pgp-signature
Size: 819 bytes
Desc: not available
URL: <http://lists.infradead.org/pipermail/linux-arm-kernel/attachments/20150813/7536bad6/attachment.sig>

From jeremy.linton at arm.com  Thu Aug 13 07:24:23 2015
From: jeremy.linton at arm.com (Jeremy Linton)
Date: Thu, 13 Aug 2015 09:24:23 -0500
Subject: [PATCH 1/2] Add a matching set of device_ functions for
 determining mac/phy
In-Reply-To: <55CC8613.1040709@arm.com>
References: <1439417187-21411-1-git-send-email-jeremy.linton@arm.com>
 <1439417187-21411-2-git-send-email-jeremy.linton@arm.com>
 <55CC8613.1040709@arm.com>
Message-ID: <55CCA897.5080108@arm.com>

Hello Robin,

On 08/13/2015 06:57 AM, Robin Murphy wrote:
>> +static void *device_get_mac_addr(struct device *dev,
>> +				 const char *name, char *addr,
>> +				 int alen)
>> +{
>> +	int ret = device_property_read_u8_array(dev, name, addr, alen);
>> +
>> +	if (ret == 0 && is_valid_ether_addr(addr))
>> +		return addr;
>> +	return NULL;
>> +}
>
> Not sure I understand the logic here - "return the same thing we were
> given if we updated it, or null if we didn't". It's only indicating
> success/failure (the caller can perfectly well cast its own buffer to a
> void * if it needs to), so why wouldn't you just return a normal int
> error code?


	No particular reason, other than initially I was trying to keep the 
function as similar as possible to the one in of_net. AKA copy paste 
job. I can convert the return types, but I was trying for a simple 
function rename. That way the users of the of version could be converted 
with relative ease, and the drivers which invented their own version of 
these functions could be changed to use this instead. Of course, that 
plan took a blow, when I added the addr/alen parameters.

	Same thing applies for the other function.


	



From catalin.marinas at arm.com  Thu Aug 13 07:24:44 2015
From: catalin.marinas at arm.com (Catalin Marinas)
Date: Thu, 13 Aug 2015 15:24:44 +0100
Subject: [GIT PULL] ARM64: juno: SCPI and dependent drivers for v4.3
In-Reply-To: <20150813124026.GD23581@localhost>
References: <55C1E3FB.5090309@arm.com>
 <20150813124026.GD23581@localhost>
Message-ID: <20150813142444.GA4602@e104818-lin.cambridge.arm.com>

On Thu, Aug 13, 2015 at 02:40:26PM +0200, Olof Johansson wrote:
> On Wed, Aug 05, 2015 at 11:22:51AM +0100, Sudeep Holla wrote:
> > Here is the first pull request for SCPI, clock and cpufreq support on
> > ARM64 Juno development platform for v4.3
> 
> I'd like to hear from Catalin and Will on why ARM is doing this. Catalin
> and Will are pushing back very hard at vendors who don't use PSCI for
> CPU power management, and then they have coworkers that are looking to
> merge this directly into the kernel.

Actually, the arm64 CPU power management story is pretty much handled by
Lorenzo and Sudeep in my team, so I trust their judgement ;). But I
agree with you that a better explanation on the reasons behind this is
needed, otherwise we risk confusing messages. I'll try to summarise it
below but Sudeep can reply with more details.

PSCI only covers CPU boot/cpuidle and platform suspend. It does not have
any provisions for DVFS and I'm not sure this could be easily
standardised (or whether we could find enough supporters to get it
adopted).

SCPI is a (standard) interface to a coprocessor handling clocks etc. to
be used with cpufreq. This patchset adds support for cpufreq/dvs which
is not handled by PSCI. So, just to clarify the acronyms:

SCPI - System Control and Power Interface - it's a protocol for
communicating with a System Control Processor (e.g. Cortex-M3) via
mailboxes. It is used in Linux for DVFS but this is *not* a secure/EL3
firmware interface (a.k.a. SMC calls). It indeed a firmware interface
but the firmware runs on a separate coprocessor and not on the CPU itself.

PSCI - Power State Coordination Interface - it is a secure firmware
interface for coordinating the CPU power states (idle, not DVFS). The
firmware may use an SCPI communication channel (e.g. deeper sleep states
where clock changes are needed).

-- 
Catalin


From lee.jones at linaro.org  Thu Aug 13 07:26:14 2015
From: lee.jones at linaro.org (Lee Jones)
Date: Thu, 13 Aug 2015 15:26:14 +0100
Subject: [PATCH v2 5/6] mailbox: Add generic mechanism for testing
 Mailbox Controllers
In-Reply-To: <CABb+yY2N6=oTrwni0tw1WffLv-udtBWh9LJR43EMVqYf+i2xUg@mail.gmail.com>
References: <20150813091914.GB8782@x1>
 <CABb+yY0cgbtM68-E_Xqgh5O6GRLXESYTLa5WcAwUBoVL3ufrxA@mail.gmail.com>
 <20150813102335.GC8782@x1>
 <CABb+yY3z7p97eOhncQ2i+g6yoYGfDgSN9BDPKmiDaVLa3oPocA@mail.gmail.com>
 <20150813110008.GD8782@x1>
 <CABb+yY34i=VUnswUE21vgeQYAGOS=7uwvdnTAFFgYkTV0CFk=w@mail.gmail.com>
 <20150813114005.GF8782@x1>
 <CABb+yY2OH16mgOwi=yH_eEHQN2Ck2x5xtVk-p-8Un9gGmcACdw@mail.gmail.com>
 <20150813130736.GG8782@x1>
 <CABb+yY2N6=oTrwni0tw1WffLv-udtBWh9LJR43EMVqYf+i2xUg@mail.gmail.com>
Message-ID: <20150813142614.GH8782@x1>

On Thu, 13 Aug 2015, Jassi Brar wrote:

> On Thu, Aug 13, 2015 at 6:37 PM, Lee Jones <lee.jones at linaro.org> wrote:
> >
> > Now just agree with me that mbox_request_chan() should fail on request
> > of a known bad configuration request and I can code all this up and
> > re-submit. :D
> >
> You make me look like a jerk :(   My problem is not with validation as
> such. I see problem in the way you implement that makes validation
> necessary. I'll explain step-by-step in the driver post.

That wasn't the intention, don't be so sensitive. ;)

-- 
Lee Jones
Linaro STMicroelectronics Landing Team Lead
Linaro.org ? Open source software for ARM SoCs
Follow Linaro: Facebook | Twitter | Blog


From nm at ti.com  Thu Aug 13 07:32:20 2015
From: nm at ti.com (Nishanth Menon)
Date: Thu, 13 Aug 2015 09:32:20 -0500
Subject: [PATCH] ARM: DRA752: Add ID detect for ES2.0
Message-ID: <1439476340-20141-1-git-send-email-nm@ti.com>

From: Vishal Mahaveer <vishalm at ti.com>

ES2.0 is a minor variant of ES1.1. ES2.0 is an incremental revision
with various fixes including the following:
	- reset logic fixes
	- few assymetric aging logic fixes
	- MMC clock rate fixes
	- Ethernet speed fixes
	- edma fixes for mcasp

NOTE: even though we use a compatible of dra742 and dra752, the usage in
the Linux kernel is more or less interchangable - we use dra752 more
often in the linux kernel compared to dra742 and 4.2-rc6

Signed-off-by: Vishal Mahaveer <vishalm at ti.com>
Signed-off-by: Nishanth Menon <nm at ti.com>
---
based on linux-next next-20150812, applies to v4.2-rc6 as well.
Definetly not a 4.2 material, for 4.3, this probably missed the first merge
window for 4.3, will be great if it could be considered for the second merge
window.

 arch/arm/mach-omap2/id.c  | 8 ++++++--
 arch/arm/mach-omap2/soc.h | 2 ++
 2 files changed, 8 insertions(+), 2 deletions(-)

diff --git a/arch/arm/mach-omap2/id.c b/arch/arm/mach-omap2/id.c
index e3f713ffb06b..54a5ba54d2ff 100644
--- a/arch/arm/mach-omap2/id.c
+++ b/arch/arm/mach-omap2/id.c
@@ -653,8 +653,12 @@ void __init dra7xxx_check_revision(void)
 			omap_revision = DRA752_REV_ES1_0;
 			break;
 		case 1:
-		default:
 			omap_revision = DRA752_REV_ES1_1;
+			break;
+		case 2:
+		default:
+			omap_revision = DRA752_REV_ES2_0;
+			break;
 		}
 		break;
 
@@ -674,7 +678,7 @@ void __init dra7xxx_check_revision(void)
 		/* Unknown default to latest silicon rev as default*/
 		pr_warn("%s: unknown idcode=0x%08x (hawkeye=0x%08x,rev=0x%x)\n",
 			__func__, idcode, hawkeye, rev);
-		omap_revision = DRA752_REV_ES1_1;
+		omap_revision = DRA752_REV_ES2_0;
 	}
 
 	sprintf(soc_name, "DRA%03x", omap_rev() >> 16);
diff --git a/arch/arm/mach-omap2/soc.h b/arch/arm/mach-omap2/soc.h
index f97654d11ea5..2d1d3845253c 100644
--- a/arch/arm/mach-omap2/soc.h
+++ b/arch/arm/mach-omap2/soc.h
@@ -469,6 +469,8 @@ IS_OMAP_TYPE(3430, 0x3430)
 #define DRA7XX_CLASS		0x07000000
 #define DRA752_REV_ES1_0	(DRA7XX_CLASS | (0x52 << 16) | (0x10 << 8))
 #define DRA752_REV_ES1_1	(DRA7XX_CLASS | (0x52 << 16) | (0x11 << 8))
+#define DRA752_REV_ES2_0	(DRA7XX_CLASS | (0x52 << 16) | (0x20 << 8))
+#define DRA722_REV_ES1_0	(DRA7XX_CLASS | (0x22 << 16) | (0x10 << 8))
 #define DRA722_REV_ES1_0	(DRA7XX_CLASS | (0x22 << 16) | (0x10 << 8))
 
 void omap2xxx_check_revision(void);
-- 
2.1.4



From thierry.reding at gmail.com  Thu Aug 13 07:33:33 2015
From: thierry.reding at gmail.com (Thierry Reding)
Date: Thu, 13 Aug 2015 16:33:33 +0200
Subject: [PATCH v2 0/3] Have Tegra's GPIO chip depend explicitly on the
 pinctrl device
In-Reply-To: <1436862596-27730-1-git-send-email-tomeu.vizoso@collabora.com>
References: <1436862596-27730-1-git-send-email-tomeu.vizoso@collabora.com>
Message-ID: <20150813143332.GC26559@ulmo>

On Tue, Jul 14, 2015 at 10:29:53AM +0200, Tomeu Vizoso wrote:
> Hello,
> 
> these three patches make sure that there's an explicit dependency from
> the GPIO chip in Tegra SoCs to the corresponding pinctrl device, without
> having duplicated gpio ranges.
> 
> By having an explicit dependency, we can do things such as probing the
> pinctrl device before the GPIO chip device to avoid deferred probes.
> 
> Thanks,
> 
> Tomeu
> 
> Changes in v2:
> - Don't defer probe if the pinctrl node is disabled
> - Remove outdated comment from the commit changelog
> 
> Tomeu Vizoso (3):
>   gpio: defer probe if pinctrl cannot be found
>   pinctrl: tegra: Only set the gpio range if needed
>   ARM: tegra: Add gpio-ranges property

Patches 2 and 3 applied to the Tegra tree. Linus, I've applied the
pinctrl patch to a separate branch, so we could use that to resolve
conflicts, should there be any.

Thierry
-------------- next part --------------
A non-text attachment was scrubbed...
Name: signature.asc
Type: application/pgp-signature
Size: 819 bytes
Desc: not available
URL: <http://lists.infradead.org/pipermail/linux-arm-kernel/attachments/20150813/d6be596e/attachment.sig>

From balbi at ti.com  Thu Aug 13 07:36:51 2015
From: balbi at ti.com (Felipe Balbi)
Date: Thu, 13 Aug 2015 09:36:51 -0500
Subject: [PATCH v3] i2c: omap: improve duty cycle on SCL
In-Reply-To: <20150710172714.GC20408@saruman.tx.rr.com>
References: <1434569475-17378-1-git-send-email-balbi@ti.com>
 <55827CD7.7030207@nokia.com>
 <20150618172558.GC27790@saruman.tx.rr.com>
 <20150709194241.GF4744@katana>
 <20150710172714.GC20408@saruman.tx.rr.com>
Message-ID: <20150813143651.GG27560@saruman.tx.rr.com>

On Fri, Jul 10, 2015 at 12:27:15PM -0500, Felipe Balbi wrote:
> On Thu, Jul 09, 2015 at 09:42:41PM +0200, Wolfram Sang wrote:
> > On Thu, Jun 18, 2015 at 12:25:58PM -0500, Felipe Balbi wrote:
> > > On Thu, Jun 18, 2015 at 10:09:59AM +0200, Alexander Sverdlin wrote:
> > > > Hello Felipe,
> > > > 
> > > > On 17/06/15 21:31, ext Felipe Balbi wrote:
> > > > > With this patch we try to be as close to 50%
> > > > > duty cycle as possible. The reason for this
> > > > > is that some devices present an erratic behavior
> > > > > with certain duty cycles.
> > > > > 
> > > > > One such example is TPS65218 PMIC which fails
> > > > > to change voltages when running @ 400kHz and
> > > > > duty cycle is lower than 34%.
> > > > > 
> > > > > The idea of the patch is simple:
> > > > > 
> > > > > calculate desired scl_period from requested scl
> > > > > and use 50% for tLow and 50% for tHigh.
> > > > > 
> > > > > tLow is calculated with a DIV_ROUND_UP() to make
> > > > > sure it's slightly higher than tHigh and to make
> > > > > sure that we end up within I2C specifications.
> > > > 
> > > > if you refuse to change the calculations to achieve maximum possible
> > > > bus rate (as I've shown you with SCLL=9 and SCLH=9), maybe you want to
> > > > change the description? Because you are doing something else than is
> > > > written here. You are only in spec because you are not doing 50% duty
> > > > cycle. And you didn't mention here that you lower the bus speed below
> > > > 400kHz to achieve this.
> > > 
> > > and there's a comment where the calculation goes which states "as close
> > > to 50% as possible but we make sure tLow is higher than tHigh so we're
> > > still within spec".
> > 
> > So, is that ready to go in for-next?
> 
> should be.

ping ?

-- 
balbi
-------------- next part --------------
A non-text attachment was scrubbed...
Name: signature.asc
Type: application/pgp-signature
Size: 819 bytes
Desc: Digital signature
URL: <http://lists.infradead.org/pipermail/linux-arm-kernel/attachments/20150813/595fa791/attachment.sig>

From linux at arm.linux.org.uk  Thu Aug 13 07:37:30 2015
From: linux at arm.linux.org.uk (Russell King - ARM Linux)
Date: Thu, 13 Aug 2015 15:37:30 +0100
Subject: [PATCH 1/2] drivers: PL061: add support for platform driver
 probing
In-Reply-To: <1439468713.1661643.355247625.1CF96E47@webmail.messagingengine.com>
References: <1438585198-8764-1-git-send-email-zhaoshenglong@huawei.com>
 <1438585198-8764-2-git-send-email-zhaoshenglong@huawei.com>
 <CACRpkdY6ZfB-gnnr49He+BYELy4fhiV0g5jkEHhyVsJOc_SBFw@mail.gmail.com>
 <1438614811.2338188.346456017.5D258EC5@webmail.messagingengine.com>
 <CACRpkdYmeXvXCrJPxCJCDfCG_=MmopmyAe5mgCPoB_S02ERTLg@mail.gmail.com>
 <1439468713.1661643.355247625.1CF96E47@webmail.messagingengine.com>
Message-ID: <20150813143730.GP7557@n2100.arm.linux.org.uk>

On Thu, Aug 13, 2015 at 01:25:13PM +0100, Graeme Gregory wrote:
> 
> 
> On Thu, 13 Aug 2015, at 01:14 PM, Linus Walleij wrote:
> > On Mon, Aug 3, 2015 at 5:13 PM, Graeme Gregory <gg at slimlogic.co.uk>
> > wrote:
> > > On Mon, 3 Aug 2015, at 01:40 PM, Linus Walleij wrote:
> > >> On Mon, Aug 3, 2015 at 8:59 AM, Shannon Zhao <zhaoshenglong at huawei.com>
> > >> wrote:
> > >>
> > >> > From: Shannon Zhao <shannon.zhao at linaro.org>
> > >> >
> > >> > Since PL061 currently only supports AMBA driver, to support using GPIO
> > >> > PL061 by DT or ACPI, it needs to add support for platform driver.
> > >> > A DT binding is provided with this patch, ACPI support is added in a
> > >> > separate one.
> > >> >
> > >> > Signed-off-by: Shannon Zhao <zhaoshenglong at huawei.com>
> > >> > Signed-off-by: Shannon Zhao <shannon.zhao at linaro.org>
> > >>
> > >> I already stated in 0/2 what the problem is with this, and it's obviously
> > >> adding
> > >> a huge codechunk, very similar to the AMBA probe path.
> > >>
> > >> We need to investigate if ACPI can just spawn AMBA/PrimeCell type devices
> > >> instead.
> > >
> > > AMBA DT support is a hideous hack, we had kind of hoped to avoid doing
> > > that in ACPI.
> > 
> > Define what you mean with "hideous hack".
> > 
> drivers/of/platform.c search for #ifdef CONFIG_ARM_AMBA

The way that AMBA support was added to OF was not something I was involved
in.  Don't make the mistake of saying "we're only supporting platform
devices in ACPI because the OF implementation is messed up".

> > I think it is elegant. It combines the DT aspect of telling where the
> > device is with the Plug-and-play aspect of reading the 0xB105F00D
> > magic in the PrimeCells very nicely. With an optional override
> > mechanism. It's nice.

It's also the _right_ way to deal with buses with different properties
from platform devices, especially where some can be probed and identified
via hardware-encoded IDs.

> I have no objection to AMBA devices that are children of an AMBA bus
> object. Its the hack above that is nasty!  It is also un-scalable as it
> sets the precedent that the platform.c in both DT and ACPI should learn
> about all the different types of device probing.

What's actually the nasty thing is that DT and ACPI are wedded to platform
devices, which pushes people down the path of more platform device usage,
when in fact they should be creating their own bus classes.

> > > If you notice ARM already updated pl011 driver to support platform
> > > device type probing this seems to be the way to go.
> > 
> > Just because there is a precedent does not mean it is good.

Exactly.

> > Continuing with this adds 100+ lines of hairy initialization to
> > every AMBA driver.

And that's utterly insane.

> > What needs to happen is stop this and make ACPI spawn
> > AMBA devices for PrimeCells, and move the serial port over
> > to that.
> > 
> > A compromise may be to have something that probes a list
> > of these platform devices in drivers/acpi/ and spawn a
> > corresponding AMBA device for it. It will still save codelines in
> > all other subsystems and lower maintenance for the
> > subsystem maintainers.

Even that isn't nice... but I guess as the madness will be contained
within ACPI, it'll be ACPI's problem to maintain, so up to them how to
deal with it provided the code is contained within ACPI. :)

-- 
FTTC broadband for 0.8mile line: currently at 10.5Mbps down 400kbps up
according to speedtest.net.


From Suzuki.Poulose at arm.com  Thu Aug 13 07:45:07 2015
From: Suzuki.Poulose at arm.com (Suzuki K. Poulose)
Date: Thu, 13 Aug 2015 15:45:07 +0100
Subject: [PATCH 12/14] arm64: Check for selected granule support
In-Reply-To: <CAPvkgC3=S1BxdzZM4uUOmyXLjii48SMpCof6i6HdNeTG_fydfg@mail.gmail.com>
References: <1439465645-22584-1-git-send-email-suzuki.poulose@arm.com>	<1439465645-22584-13-git-send-email-suzuki.poulose@arm.com>
 <CAPvkgC3=S1BxdzZM4uUOmyXLjii48SMpCof6i6HdNeTG_fydfg@mail.gmail.com>
Message-ID: <55CCAD73.7080702@arm.com>

On 13/08/15 13:28, Steve Capper wrote:
> On 13 August 2015 at 12:34, Suzuki K. Poulose <suzuki.poulose at arm.com> wrote:
>> From: "Suzuki K. Poulose" <suzuki.poulose at arm.com>
>>
>> Ensure that the selected page size is supported by the
>> CPU(s).
>>
>> Cc: Mark Rutland <mark.rutland at arm.com>
>> Cc: Catalin Marinas <catalin.marinas at arm.com>
>> Cc: Will Deacon <will.deacon at arm.com>
>> Signed-off-by: Suzuki K. Poulose <suzuki.poulose at arm.com>
>> ---
>>   arch/arm64/include/asm/sysreg.h |    6 ++++++
>>   arch/arm64/kernel/head.S        |   24 +++++++++++++++++++++++-
>>   2 files changed, 29 insertions(+), 1 deletion(-)
>>
>> diff --git a/arch/arm64/include/asm/sysreg.h b/arch/arm64/include/asm/sysreg.h
>> index a7f3d4b..e01d323 100644
>> --- a/arch/arm64/include/asm/sysreg.h
>> +++ b/arch/arm64/include/asm/sysreg.h
>> @@ -87,4 +87,10 @@ static inline void config_sctlr_el1(u32 clear, u32 set)
>>   }
>>   #endif
>>
>> +#define ID_AA64MMFR0_TGran4_SHIFT      28
>> +#define ID_AA64MMFR0_TGran64_SHIFT     24
>> +
>> +#define ID_AA64MMFR0_TGran4_ENABLED    0x0
>> +#define ID_AA64MMFR0_TGran64_ENABLED   0x0
>> +
>>   #endif /* __ASM_SYSREG_H */
>> diff --git a/arch/arm64/kernel/head.S b/arch/arm64/kernel/head.S
>> index 01b8e58..0cb04db 100644
>> --- a/arch/arm64/kernel/head.S
>> +++ b/arch/arm64/kernel/head.S
>> @@ -31,10 +31,11 @@
>>   #include <asm/cputype.h>
>>   #include <asm/kernel-pgtable.h>
>>   #include <asm/memory.h>
>> -#include <asm/thread_info.h>
>>   #include <asm/pgtable-hwdef.h>
>>   #include <asm/pgtable.h>
>>   #include <asm/page.h>
>> +#include <asm/sysreg.h>
>> +#include <asm/thread_info.h>
>>   #include <asm/virt.h>
>>
>>   #define __PHYS_OFFSET  (KERNEL_START - TEXT_OFFSET)
>> @@ -606,9 +607,25 @@ ENDPROC(__secondary_switched)
>>    *  x27 = *virtual* address to jump to upon completion
>>    *
>>    * other registers depend on the function called upon completion
>> + * Checks if the selected granule size is supported by the CPU.
>>    */
>> +#if    defined(CONFIG_ARM64_64K_PAGES)
>> +
>> +#define ID_AA64MMFR0_TGran_SHIFT       ID_AA64MMFR0_TGran64_SHIFT
>> +#define ID_AA64MMFR0_TGran_ENABLED     ID_AA64MMFR0_TGran64_ENABLED
>> +
>> +#else
>> +
>> +#define ID_AA64MMFR0_TGran_SHIFT       ID_AA64MMFR0_TGran4_SHIFT
>> +#define ID_AA64MMFR0_TGran_ENABLED     ID_AA64MMFR0_TGran4_ENABLED
>> +
>> +#endif
>>          .section        ".idmap.text", "ax"
>>   __enable_mmu:
>> +       mrs     x1, ID_AA64MMFR0_EL1
>> +       ubfx    x2, x1, #ID_AA64MMFR0_TGran_SHIFT, 4
>> +       cmp     x2, #ID_AA64MMFR0_TGran_ENABLED
>> +       b.ne    __no_granule_support
>>          ldr     x5, =vectors
>>          msr     vbar_el1, x5
>>          msr     ttbr0_el1, x25                  // load TTBR0
>> @@ -626,3 +643,8 @@ __enable_mmu:
>>          isb
>>          br      x27
>>   ENDPROC(__enable_mmu)
>> +
>> +__no_granule_support:
>> +       wfe
>> +       b __no_granule_support
>> +ENDPROC(__no_granule_support)
>> --
>> 1.7.9.5
>>
>
> Hi Suzuki,
> Is is possible to tell the user that the kernel has failed to boot due
> to the kernel granule being unsupported?

We don't have anything up at this time. The "looping address" is actually a clue
to the (expert) user. Not sure we can do something, until we get something like DEBUG_LL(?)
Or we should let it continue and end in a panic(?). The current situation can boot a
multi-cluster system with boot cluster having the Tgran support(which doesn't make a
strong use case though). I will try out some options and get back to you.


Thanks
Suzuki

>
> Cheers,
> --
> Steve
>



From jeremy.linton at arm.com  Thu Aug 13 07:45:52 2015
From: jeremy.linton at arm.com (Jeremy Linton)
Date: Thu, 13 Aug 2015 09:45:52 -0500
Subject: [PATCH 3/3] Add ACPI bindings for the EHCI platform driver.
In-Reply-To: <55CC8470.5070007@huawei.com>
References: <1439416290-21228-1-git-send-email-jeremy.linton@arm.com>
 <1439416290-21228-4-git-send-email-jeremy.linton@arm.com>
 <55CC8470.5070007@huawei.com>
Message-ID: <55CCADA0.2090409@arm.com>

Hello Hanjun,


On 08/13/2015 06:50 AM, Hanjun Guo wrote:
> With that minor fixes,
>
> Reviewed-by: Hanjun Guo <hanjun.guo at linaro.org>


Fixes applied, thanks.



	

	




From rric at kernel.org  Thu Aug 13 07:47:55 2015
From: rric at kernel.org (Robert Richter)
Date: Thu, 13 Aug 2015 16:47:55 +0200
Subject: [PATCH v2 3/5] irqchip,
 gicv3: Workaround for Cavium ThunderX erratum 23154
In-Reply-To: <1439477277-6157-1-git-send-email-rric@kernel.org>
References: <1439477277-6157-1-git-send-email-rric@kernel.org>
Message-ID: <1439477277-6157-4-git-send-email-rric@kernel.org>

From: Robert Richter <rrichter at cavium.com>

This patch implements Cavium ThunderX erratum 23154.

The gicv3 of ThunderX requires a modified version for reading the IAR
status to ensure data synchronization. Since this is in the fast-path
and called with each interrupt, runtime patching is used using jump
label patching for smallest overhead (no-op). This is the same
technique as used for tracepoints.

v2:
 * implement code in a single asm() to keep instruction sequence
 * added comment to the code that explains the erratum
 * apply workaround also if running as guest, thus check MIDR

Signed-off-by: Robert Richter <rrichter at cavium.com>
---
 drivers/irqchip/irq-gic-v3.c | 45 +++++++++++++++++++++++++++++++++++++++++++-
 1 file changed, 44 insertions(+), 1 deletion(-)

diff --git a/drivers/irqchip/irq-gic-v3.c b/drivers/irqchip/irq-gic-v3.c
index 1a91902be0b1..2f80a11621a0 100644
--- a/drivers/irqchip/irq-gic-v3.c
+++ b/drivers/irqchip/irq-gic-v3.c
@@ -107,7 +107,7 @@ static void gic_redist_wait_for_rwp(void)
 }
 
 /* Low level accessors */
-static u64 __maybe_unused gic_read_iar(void)
+static u64 gic_read_iar_common(void)
 {
 	u64 irqstat;
 
@@ -115,6 +115,38 @@ static u64 __maybe_unused gic_read_iar(void)
 	return irqstat;
 }
 
+/*
+ * Cavium ThunderX erratum 23154
+ *
+ * The gicv3 of ThunderX requires a modified version for reading the
+ * IAR status to ensure data synchronization (access to icc_iar1_el1
+ * is not sync'ed before and after).
+ */
+static u64 gic_read_iar_cavium_thunderx(void)
+{
+	u64 irqstat;
+
+	asm volatile(
+		"nop;nop;nop;nop\n\t"
+		"nop;nop;nop;nop\n\t"
+		"mrs_s %0, " __stringify(ICC_IAR1_EL1) "\n\t"
+		"nop;nop;nop;nop"
+		: "=r" (irqstat));
+	mb();
+
+	return irqstat;
+}
+
+struct static_key is_cavium_thunderx = STATIC_KEY_INIT_FALSE;
+
+static u64 __maybe_unused gic_read_iar(void)
+{
+	if (static_key_false(&is_cavium_thunderx))
+		return gic_read_iar_common();
+	else
+		return gic_read_iar_cavium_thunderx();
+}
+
 static void __maybe_unused gic_write_pmr(u64 val)
 {
 	asm volatile("msr_s " __stringify(ICC_PMR_EL1) ", %0" : : "r" (val));
@@ -766,8 +798,19 @@ static const struct irq_domain_ops gic_irq_domain_ops = {
 	.free = gic_irq_domain_free,
 };
 
+static void gicv3_enable_cavium_thunderx(void *data)
+{
+	static_key_slow_inc(&is_cavium_thunderx);
+}
+
 static const struct gic_capabilities gicv3_errata[] = {
 	{
+		.desc		= "GIC: Cavium erratum 23154",
+		.iidr		= 0xa100034c,	/* ThunderX pass 1.x */
+		.iidr_mask	= 0xffff0fff,
+		.init		= gicv3_enable_cavium_thunderx,
+	},
+	{
 	}
 };
 
-- 
2.1.1



From rric at kernel.org  Thu Aug 13 07:47:52 2015
From: rric at kernel.org (Robert Richter)
Date: Thu, 13 Aug 2015 16:47:52 +0200
Subject: [PATCH v2 0/5] irqchip,
 gicv3: Updates and Cavium ThunderX errata workarounds
Message-ID: <1439477277-6157-1-git-send-email-rric@kernel.org>

From: Robert Richter <rrichter at cavium.com>

This patch series adds gicv3 updates and workarounds for HW errata in
Cavium's ThunderX GICV3.

The first one is an unchanged resubmission of a gicv3 series I sent a
while ago.

The next patches implement the workarounds for ThunderX's gicv3. Patch
#2 adds generic code to parse the hw revision provided by an IIDR or
MIDR register value and runs specific code if hw matches. This is used
to implement the actual errata fixes in patch #3 (gicv3) and #5
(gicv3-its). Patch #4 prerequisit for patch #5.

All current review comments addressed so far with V2.

V2:
 * Workaround for 23154:
   * implement code in a single asm() to keep instruction sequence
   * added comment to the code that explains the erratum
   * apply workaround also if running as guest, thus check MIDR
 * adding MIDR check

Robert Richter (5):
  arm64: gicv3: its: Add range check for number of allocated pages
  irqchip, gicv3: Add HW revision detection and configuration
  irqchip, gicv3: Workaround for Cavium ThunderX erratum 23154
  irqchip, gicv3-its: Read typer register outside the loop
  irqchip, gicv3-its: Workaround for Cavium ThunderX errata 22375, 24313

 drivers/irqchip/irq-gic-common.c   | 13 ++++++++
 drivers/irqchip/irq-gic-common.h   | 11 +++++++
 drivers/irqchip/irq-gic-v3-its.c   | 66 ++++++++++++++++++++++++++++++++++----
 drivers/irqchip/irq-gic-v3.c       | 59 +++++++++++++++++++++++++++++++++-
 include/linux/irqchip/arm-gic-v3.h |  1 +
 5 files changed, 143 insertions(+), 7 deletions(-)

-- 
2.1.1



From rric at kernel.org  Thu Aug 13 07:47:53 2015
From: rric at kernel.org (Robert Richter)
Date: Thu, 13 Aug 2015 16:47:53 +0200
Subject: [PATCH v2 1/5] arm64: gicv3: its: Add range check for number of
 allocated pages
In-Reply-To: <1439477277-6157-1-git-send-email-rric@kernel.org>
References: <1439477277-6157-1-git-send-email-rric@kernel.org>
Message-ID: <1439477277-6157-2-git-send-email-rric@kernel.org>

From: Robert Richter <rrichter at cavium.com>

The number of pages for the its table may exceed the maximum of 256.
Adding a range check and limitting the number to its maximum.

Based on a patch from Tirumalesh Chalamarla <tchalamarla at cavium.com>.

Signed-off-by: Tirumalesh Chalamarla <tchalamarla at cavium.com>
Reviewed-by: Marc Zyngier <marc.zyngier at arm.com>
Signed-off-by: Robert Richter <rrichter at cavium.com>
---
 drivers/irqchip/irq-gic-v3-its.c   | 11 ++++++++++-
 include/linux/irqchip/arm-gic-v3.h |  1 +
 2 files changed, 11 insertions(+), 1 deletion(-)

diff --git a/drivers/irqchip/irq-gic-v3-its.c b/drivers/irqchip/irq-gic-v3-its.c
index 1b7e155869f6..466edf8a7477 100644
--- a/drivers/irqchip/irq-gic-v3-its.c
+++ b/drivers/irqchip/irq-gic-v3-its.c
@@ -810,6 +810,7 @@ static int its_alloc_tables(struct its_node *its)
 		u64 entry_size = GITS_BASER_ENTRY_SIZE(val);
 		int order = get_order(psz);
 		int alloc_size;
+		int alloc_pages;
 		u64 tmp;
 		void *base;
 
@@ -844,6 +845,14 @@ static int its_alloc_tables(struct its_node *its)
 		}
 
 		alloc_size = (1 << order) * PAGE_SIZE;
+		alloc_pages = (alloc_size / psz);
+		if (alloc_pages > GITS_BASER_PAGES_MAX) {
+			alloc_pages = GITS_BASER_PAGES_MAX;
+			order = get_order(GITS_BASER_PAGES_MAX * psz);
+			pr_warn("%s: Device Table too large, reduce its page order to %u (%u pages)\n",
+				its->msi_chip.of_node->full_name, order, alloc_pages);
+		}
+
 		base = (void *)__get_free_pages(GFP_KERNEL | __GFP_ZERO, order);
 		if (!base) {
 			err = -ENOMEM;
@@ -872,7 +881,7 @@ static int its_alloc_tables(struct its_node *its)
 			break;
 		}
 
-		val |= (alloc_size / psz) - 1;
+		val |= alloc_pages - 1;
 
 		writeq_relaxed(val, its->base + GITS_BASER + i * 8);
 		tmp = readq_relaxed(its->base + GITS_BASER + i * 8);
diff --git a/include/linux/irqchip/arm-gic-v3.h b/include/linux/irqchip/arm-gic-v3.h
index ffbc034c8810..f28da189c4aa 100644
--- a/include/linux/irqchip/arm-gic-v3.h
+++ b/include/linux/irqchip/arm-gic-v3.h
@@ -229,6 +229,7 @@
 #define GITS_BASER_PAGE_SIZE_16K	(1UL << GITS_BASER_PAGE_SIZE_SHIFT)
 #define GITS_BASER_PAGE_SIZE_64K	(2UL << GITS_BASER_PAGE_SIZE_SHIFT)
 #define GITS_BASER_PAGE_SIZE_MASK	(3UL << GITS_BASER_PAGE_SIZE_SHIFT)
+#define GITS_BASER_PAGES_MAX		256
 
 #define GITS_BASER_TYPE_NONE		0
 #define GITS_BASER_TYPE_DEVICE		1
-- 
2.1.1



From rric at kernel.org  Thu Aug 13 07:47:56 2015
From: rric at kernel.org (Robert Richter)
Date: Thu, 13 Aug 2015 16:47:56 +0200
Subject: [PATCH v2 4/5] irqchip,
 gicv3-its: Read typer register outside the loop
In-Reply-To: <1439477277-6157-1-git-send-email-rric@kernel.org>
References: <1439477277-6157-1-git-send-email-rric@kernel.org>
Message-ID: <1439477277-6157-5-git-send-email-rric@kernel.org>

From: Robert Richter <rrichter at cavium.com>

No need to read the typer register in the loop. Values do not change.

This patch is basically a prerequisite for a follow-on patch that adds
errata code for Cavium ThunderX. It moves the calculation of the
number of id entries to the beginning of the function close to other
setup values that are needed to allocate the its table. Now we have a
central location to modify the setup parameters and the errata code
can be implemented in a single block.

Acked-by: Marc Zyngier <marc.zyngier at arm.com>
Signed-off-by: Robert Richter <rrichter at cavium.com>
---
 drivers/irqchip/irq-gic-v3-its.c | 5 ++---
 1 file changed, 2 insertions(+), 3 deletions(-)

diff --git a/drivers/irqchip/irq-gic-v3-its.c b/drivers/irqchip/irq-gic-v3-its.c
index 105674037618..bf0659821683 100644
--- a/drivers/irqchip/irq-gic-v3-its.c
+++ b/drivers/irqchip/irq-gic-v3-its.c
@@ -804,6 +804,8 @@ static int its_alloc_tables(struct its_node *its)
 	int psz = SZ_64K;
 	u64 shr = GITS_BASER_InnerShareable;
 	u64 cache = GITS_BASER_WaWb;
+	u64 typer = readq_relaxed(its->base + GITS_TYPER);
+	u32 ids = GITS_TYPER_DEVBITS(typer);
 
 	for (i = 0; i < GITS_BASER_NR_REGS; i++) {
 		u64 val = readq_relaxed(its->base + GITS_BASER + i * 8);
@@ -827,9 +829,6 @@ static int its_alloc_tables(struct its_node *its)
 		 * For other tables, only allocate a single page.
 		 */
 		if (type == GITS_BASER_TYPE_DEVICE) {
-			u64 typer = readq_relaxed(its->base + GITS_TYPER);
-			u32 ids = GITS_TYPER_DEVBITS(typer);
-
 			/*
 			 * 'order' was initialized earlier to the default page
 			 * granule of the the ITS.  We can't have an allocation
-- 
2.1.1



From rric at kernel.org  Thu Aug 13 07:47:54 2015
From: rric at kernel.org (Robert Richter)
Date: Thu, 13 Aug 2015 16:47:54 +0200
Subject: [PATCH v2 2/5] irqchip,
 gicv3: Add HW revision detection and configuration
In-Reply-To: <1439477277-6157-1-git-send-email-rric@kernel.org>
References: <1439477277-6157-1-git-send-email-rric@kernel.org>
Message-ID: <1439477277-6157-3-git-send-email-rric@kernel.org>

From: Robert Richter <rrichter at cavium.com>

Some GIC revisions require an individual configuration to esp. add
workarounds for HW bugs. This patch implements generic code to parse
the hw revision provided by an IIDR register value and runs specific
code if hw matches. There are functions that read the IIDR registers
for GICV3 and ITS (GICD_IIDR/GITS_IIDR) and then go through a list of
init functions to be called for specific versions.

A MIDR register value may also be used, this is especially useful for
hw detection from a guest.

The patch is needed to implement workarounds for HW errata in Cavium's
ThunderX GICV3.

V2:
 * adding MIDR check

Signed-off-by: Robert Richter <rrichter at cavium.com>
---
 drivers/irqchip/irq-gic-common.c | 13 +++++++++++++
 drivers/irqchip/irq-gic-common.h | 11 +++++++++++
 drivers/irqchip/irq-gic-v3-its.c | 15 +++++++++++++++
 drivers/irqchip/irq-gic-v3.c     | 14 ++++++++++++++
 4 files changed, 53 insertions(+)

diff --git a/drivers/irqchip/irq-gic-common.c b/drivers/irqchip/irq-gic-common.c
index 9448e391cb71..886c09e645bf 100644
--- a/drivers/irqchip/irq-gic-common.c
+++ b/drivers/irqchip/irq-gic-common.c
@@ -21,6 +21,19 @@
 
 #include "irq-gic-common.h"
 
+void gic_check_capabilities(u32 iidr, const struct gic_capabilities *cap,
+			void *data)
+{
+	for (; cap->desc; cap++) {
+		if (cap->midr != (cap->midr_mask & read_cpuid_id()))
+			continue;
+		if (cap->iidr != (cap->iidr_mask & iidr))
+			continue;
+		cap->init(data);
+		pr_info("%s\n", cap->desc);
+	}
+}
+
 int gic_configure_irq(unsigned int irq, unsigned int type,
 		       void __iomem *base, void (*sync_access)(void))
 {
diff --git a/drivers/irqchip/irq-gic-common.h b/drivers/irqchip/irq-gic-common.h
index 35a9884778bd..e9a3e2800005 100644
--- a/drivers/irqchip/irq-gic-common.h
+++ b/drivers/irqchip/irq-gic-common.h
@@ -20,10 +20,21 @@
 #include <linux/of.h>
 #include <linux/irqdomain.h>
 
+struct gic_capabilities {
+	const char *desc;
+	void (*init)(void *data);
+	u32 iidr;
+	u32 iidr_mask;
+	u32 midr;
+	u32 midr_mask;
+};
+
 int gic_configure_irq(unsigned int irq, unsigned int type,
                        void __iomem *base, void (*sync_access)(void));
 void gic_dist_config(void __iomem *base, int gic_irqs,
 		     void (*sync_access)(void));
 void gic_cpu_config(void __iomem *base, void (*sync_access)(void));
+void gic_check_capabilities(u32 iidr, const struct gic_capabilities *cap,
+			void *data);
 
 #endif /* _IRQ_GIC_COMMON_H */
diff --git a/drivers/irqchip/irq-gic-v3-its.c b/drivers/irqchip/irq-gic-v3-its.c
index 466edf8a7477..105674037618 100644
--- a/drivers/irqchip/irq-gic-v3-its.c
+++ b/drivers/irqchip/irq-gic-v3-its.c
@@ -36,6 +36,7 @@
 #include <asm/cputype.h>
 #include <asm/exception.h>
 
+#include "irq-gic-common.h"
 #include "irqchip.h"
 
 #define ITS_FLAGS_CMDQ_NEEDS_FLUSHING		(1 << 0)
@@ -1391,6 +1392,18 @@ static int its_force_quiescent(void __iomem *base)
 	}
 }
 
+static const struct gic_capabilities its_errata[] = {
+	{
+	}
+};
+
+static void its_check_capabilities(struct its_node *its)
+{
+	u32 iidr = readl_relaxed(its->base + GITS_IIDR);
+
+	gic_check_capabilities(iidr, its_errata, its);
+}
+
 static int its_probe(struct device_node *node, struct irq_domain *parent)
 {
 	struct resource res;
@@ -1449,6 +1462,8 @@ static int its_probe(struct device_node *node, struct irq_domain *parent)
 	}
 	its->cmd_write = its->cmd_base;
 
+	its_check_capabilities(its);
+
 	err = its_alloc_tables(its);
 	if (err)
 		goto out_free_cmd;
diff --git a/drivers/irqchip/irq-gic-v3.c b/drivers/irqchip/irq-gic-v3.c
index c52f7ba205b4..1a91902be0b1 100644
--- a/drivers/irqchip/irq-gic-v3.c
+++ b/drivers/irqchip/irq-gic-v3.c
@@ -766,6 +766,18 @@ static const struct irq_domain_ops gic_irq_domain_ops = {
 	.free = gic_irq_domain_free,
 };
 
+static const struct gic_capabilities gicv3_errata[] = {
+	{
+	}
+};
+
+static void gicv3_check_capabilities(void)
+{
+	u32 iidr = readl_relaxed(gic_data.dist_base + GICD_IIDR);
+
+	gic_check_capabilities(iidr, gicv3_errata, NULL);
+}
+
 static int __init gic_of_init(struct device_node *node, struct device_node *parent)
 {
 	void __iomem *dist_base;
@@ -825,6 +837,8 @@ static int __init gic_of_init(struct device_node *node, struct device_node *pare
 	gic_data.nr_redist_regions = nr_redist_regions;
 	gic_data.redist_stride = redist_stride;
 
+	gicv3_check_capabilities();
+
 	/*
 	 * Find out how many interrupts are supported.
 	 * The GIC only supports up to 1020 interrupt sources (SGI+PPI+SPI)
-- 
2.1.1



From rric at kernel.org  Thu Aug 13 07:47:57 2015
From: rric at kernel.org (Robert Richter)
Date: Thu, 13 Aug 2015 16:47:57 +0200
Subject: [PATCH v2 5/5] irqchip,
 gicv3-its: Workaround for Cavium ThunderX errata 22375, 24313
In-Reply-To: <1439477277-6157-1-git-send-email-rric@kernel.org>
References: <1439477277-6157-1-git-send-email-rric@kernel.org>
Message-ID: <1439477277-6157-6-git-send-email-rric@kernel.org>

From: Robert Richter <rrichter at cavium.com>

This implements two gicv3-its errata workarounds for ThunderX. Both
with small impact affecting only ITS table allocation.

 erratum 22375: only alloc 8MB table size
 erratum 24313: ignore memory access type

The fixes are in ITS initialization and basically ignore memory access
type and table size provided by the TYPER and BASER registers.

Signed-off-by: Robert Richter <rrichter at cavium.com>
---
 drivers/irqchip/irq-gic-v3-its.c | 39 +++++++++++++++++++++++++++++++++++----
 1 file changed, 35 insertions(+), 4 deletions(-)

diff --git a/drivers/irqchip/irq-gic-v3-its.c b/drivers/irqchip/irq-gic-v3-its.c
index bf0659821683..d629e0e03322 100644
--- a/drivers/irqchip/irq-gic-v3-its.c
+++ b/drivers/irqchip/irq-gic-v3-its.c
@@ -39,7 +39,8 @@
 #include "irq-gic-common.h"
 #include "irqchip.h"
 
-#define ITS_FLAGS_CMDQ_NEEDS_FLUSHING		(1 << 0)
+#define ITS_FLAGS_CMDQ_NEEDS_FLUSHING		(1ULL << 0)
+#define ITS_FLAGS_CAVIUM_THUNDERX		(1ULL << 1)
 
 #define RDIST_FLAGS_PROPBASE_NEEDS_FLUSHING	(1 << 0)
 
@@ -803,9 +804,22 @@ static int its_alloc_tables(struct its_node *its)
 	int i;
 	int psz = SZ_64K;
 	u64 shr = GITS_BASER_InnerShareable;
-	u64 cache = GITS_BASER_WaWb;
-	u64 typer = readq_relaxed(its->base + GITS_TYPER);
-	u32 ids = GITS_TYPER_DEVBITS(typer);
+	u64 cache;
+	u64 typer;
+	u32 ids;
+
+	if (its->flags & ITS_FLAGS_CAVIUM_THUNDERX) {
+		/*
+		 * erratum 22375: only alloc 8MB table size
+		 * erratum 24313: ignore memory access type
+		 */
+		cache	= 0;
+		ids	= 0x13;			/* 20 bits, 8MB */
+	} else {
+		cache	= GITS_BASER_WaWb;
+		typer	= readq_relaxed(its->base + GITS_TYPER);
+		ids	= GITS_TYPER_DEVBITS(typer);
+	}
 
 	for (i = 0; i < GITS_BASER_NR_REGS; i++) {
 		u64 val = readq_relaxed(its->base + GITS_BASER + i * 8);
@@ -1391,8 +1405,25 @@ static int its_force_quiescent(void __iomem *base)
 	}
 }
 
+static void its_enable_cavium_thunderx(void *data)
+{
+	struct its_node *its = data;
+
+	its->flags |= ITS_FLAGS_CAVIUM_THUNDERX;
+}
+
 static const struct gic_capabilities its_errata[] = {
 	{
+		/*
+		 * Need to be applied in guests too, thus use midr as
+		 * iidr is emulated with different vendor id.
+		 */
+		.desc		= "ITS: Cavium errata 22375, 24313",
+		.midr		= 0x43000a10,	/* ThunderX pass 1.x */
+		.midr_mask	= 0xfff0fff0,
+		.init		= its_enable_cavium_thunderx,
+	},
+	{
 	}
 };
 
-- 
2.1.1



From heiko at sntech.de  Thu Aug 13 07:50:06 2015
From: heiko at sntech.de (Heiko =?ISO-8859-1?Q?St=FCbner?=)
Date: Thu, 13 Aug 2015 16:50:06 +0200
Subject: [PATCH v5 2/2] pinctrl: rockchip: only enable gpio clock when it
 setting
In-Reply-To: <CACRpkdYYdqm+CfejMA6yrDheNA=3H13zsW2XuKqqYDRNMS=07w@mail.gmail.com>
References: <1439287924-6988-1-git-send-email-hl@rock-chips.com>
 <2167165.ooWgarx4Ov@diego>
 <CACRpkdYYdqm+CfejMA6yrDheNA=3H13zsW2XuKqqYDRNMS=07w@mail.gmail.com>
Message-ID: <1632762.z1JEYVnjv5@diego>

Am Donnerstag, 13. August 2015, 16:11:38 schrieb Linus Walleij:
> On Thu, Aug 13, 2015 at 2:37 PM, Heiko St?bner <heiko at sntech.de> wrote:
> >> Patch applied with Doug's test tags etc.
> > 
> > did you  also take the first patch?
> > 
> > Aka bot should probably stay together (hence Stephen's Ack for the clock
> > change), as the dynamically controlling the gpio clocks exposes the
> > pclk_pd_pmu.
> 
> OK wasn't obvious to me, patch 1/2 applied to the pinctrl tree now.

Thanks for picking patch 1/2 too.

Both me and Lin seem to have forgotten to mention this in this new revision 
(sorry about that), as it was discussed in a previous revision only.


From stern at rowland.harvard.edu  Thu Aug 13 07:52:56 2015
From: stern at rowland.harvard.edu (Alan Stern)
Date: Thu, 13 Aug 2015 10:52:56 -0400 (EDT)
Subject: [PATCH 2/3] Display a DMA error message
In-Reply-To: <1439416290-21228-3-git-send-email-jeremy.linton@arm.com>
Message-ID: <Pine.LNX.4.44L0.1508131051500.1277-100000@iolanthe.rowland.org>

On Wed, 12 Aug 2015, Jeremy Linton wrote:

> If the ehci driver fails to configure the dma settings then display
> a dev error instead of simply failing. This is triggered in an
> ACPI world if the user fails to set the _CCA on the device.
> 
> Signed-off-by: Jeremy Linton <jeremy.linton at arm.com>
> ---
>  drivers/usb/host/ehci-platform.c | 4 +++-
>  1 file changed, 3 insertions(+), 1 deletion(-)
> 
> diff --git a/drivers/usb/host/ehci-platform.c b/drivers/usb/host/ehci-platform.c
> index 2593def..82e396f 100644
> --- a/drivers/usb/host/ehci-platform.c
> +++ b/drivers/usb/host/ehci-platform.c
> @@ -162,8 +162,10 @@ static int ehci_platform_probe(struct platform_device *dev)
>  
>  	err = dma_coerce_mask_and_coherent(&dev->dev,
>  		pdata->dma_mask_64 ? DMA_BIT_MASK(64) : DMA_BIT_MASK(32));
> -	if (err)
> +	if (err) {
> +		dev_err(&dev->dev, "Error: DMA setup failed\n");
>  		return err;
> +	}
>  
>  	irq = platform_get_irq(dev, 0);
>  	if (irq < 0) {
> 

Too bad the ohci-platform driver doesn't get the same update, but 
it clearly wouldn't belong in this patch set.  Anyway,

Acked-by: Alan Stern <stern at rowland.harvard.edu>

Alan Stern



From sudeep.holla at arm.com  Thu Aug 13 07:53:04 2015
From: sudeep.holla at arm.com (Sudeep Holla)
Date: Thu, 13 Aug 2015 15:53:04 +0100
Subject: [GIT PULL] ARM64: juno: SCPI and dependent drivers for v4.3
In-Reply-To: <20150813142444.GA4602@e104818-lin.cambridge.arm.com>
References: <55C1E3FB.5090309@arm.com> <20150813124026.GD23581@localhost>
 <20150813142444.GA4602@e104818-lin.cambridge.arm.com>
Message-ID: <55CCAF50.4040503@arm.com>



On 13/08/15 15:24, Catalin Marinas wrote:
> On Thu, Aug 13, 2015 at 02:40:26PM +0200, Olof Johansson wrote:
>> On Wed, Aug 05, 2015 at 11:22:51AM +0100, Sudeep Holla wrote:
>>> Here is the first pull request for SCPI, clock and cpufreq support on
>>> ARM64 Juno development platform for v4.3
>>
>> I'd like to hear from Catalin and Will on why ARM is doing this. Catalin
>> and Will are pushing back very hard at vendors who don't use PSCI for
>> CPU power management, and then they have coworkers that are looking to
>> merge this directly into the kernel.
>
> Actually, the arm64 CPU power management story is pretty much handled by
> Lorenzo and Sudeep in my team, so I trust their judgement ;). But I
> agree with you that a better explanation on the reasons behind this is
> needed, otherwise we risk confusing messages. I'll try to summarise it
> below but Sudeep can reply with more details.
>

(I will use the acronomys directly as Catalin has already explained the
difference)

Thanks Catalin for the detailed explanation. I agree that this pull
request has not much details, but the patch series makes reference only
to the clocks and features provided by the SCP(System Control Processor)
to be used by Linux(non-secure) and nothing about CPU power states that
are handled by PSCI. This SCPI is completely independent and orthogonal
to PSCI.

> PSCI only covers CPU boot/cpuidle and platform suspend. It does not have
> any provisions for DVFS and I'm not sure this could be easily
> standardised (or whether we could find enough supporters to get it
> adopted).
>

Though we are not campaigning it as aggressively as PSCI.

> SCPI is a (standard) interface to a coprocessor handling clocks etc. to
> be used with cpufreq. This patchset adds support for cpufreq/dvs which
> is not handled by PSCI. So, just to clarify the acronyms:
>
> SCPI - System Control and Power Interface - it's a protocol for
> communicating with a System Control Processor (e.g. Cortex-M3) via
> mailboxes. It is used in Linux for DVFS but this is *not* a secure/EL3
> firmware interface (a.k.a. SMC calls). It indeed a firmware interface
> but the firmware runs on a separate coprocessor and not on the CPU itself.
>
> PSCI - Power State Coordination Interface - it is a secure firmware
> interface for coordinating the CPU power states (idle, not DVFS). The
> firmware may use an SCPI communication channel (e.g. deeper sleep states
> where clock changes are needed).
>

I will add some more information to (hopefully) clarify the doubts.

SCP(System Control Processor) offers control and management of the
core/cluster power states, various power domain DVFS including the
core/cluster, certain system clocks configuration, thermal sensors and
many others.

Though the core/cluster power states are also handled this SCP,
they are accessible only through secure channels and PSCI firmware
implementations on the platform rely on that internally. Non-secure
access/requests are not possible.

Just to summarize, this SCP helps to offload all the power management
work to a dedicated low power processor which can be always running.
On Juno, its Cortex-M while on AMD Seattle it's Cortex-A5.

Regards,
Sudeep


From stern at rowland.harvard.edu  Thu Aug 13 07:53:15 2015
From: stern at rowland.harvard.edu (Alan Stern)
Date: Thu, 13 Aug 2015 10:53:15 -0400 (EDT)
Subject: [PATCH 3/3] Add ACPI bindings for the EHCI platform driver.
In-Reply-To: <1439416290-21228-4-git-send-email-jeremy.linton@arm.com>
Message-ID: <Pine.LNX.4.44L0.1508131049001.1277-100000@iolanthe.rowland.org>

On Wed, 12 Aug 2015, Jeremy Linton wrote:

> This enables USB on the ARM juno board when booted with
> an ACPI kernel. The PNP id comes from the PNP/ACPI registry
> and describes a EHCI controller without debug.
> 
> Signed-off-by: Jeremy Linton <jeremy.linton at arm.com>

Looks okay, but...

> ---
>  drivers/usb/host/ehci-platform.c | 9 +++++++++
>  1 file changed, 9 insertions(+)
> 
> diff --git a/drivers/usb/host/ehci-platform.c b/drivers/usb/host/ehci-platform.c
> index 82e396f..1807baa 100644
> --- a/drivers/usb/host/ehci-platform.c
> +++ b/drivers/usb/host/ehci-platform.c
> @@ -27,6 +27,7 @@
>  #include <linux/io.h>
>  #include <linux/module.h>
>  #include <linux/of.h>
> +#include <linux/acpi.h>
>  #include <linux/phy/phy.h>
>  #include <linux/platform_device.h>
>  #include <linux/reset.h>
> @@ -382,6 +383,13 @@ static const struct of_device_id vt8500_ehci_ids[] = {
>  };
>  MODULE_DEVICE_TABLE(of, vt8500_ehci_ids);
>  
> +static const struct acpi_device_id ehci_acpi_match[] = {
> +	{ "PNP0D20", 0 },

How about a comment on this line?  Something like:

+	{ "PNP0D20", 0 },	/* EHCI controller without debug */

I realize the of_device_id table doesn't include similar comments, but 
there the entries are more or less self-documenting.  The same cannot 
be said for "PNP0D20".

> +	{ }
> +};
> +MODULE_DEVICE_TABLE(acpi, ehci_acpi_match);
> +
> +

Undesired extra blank line.

>  static const struct platform_device_id ehci_platform_table[] = {
>  	{ "ehci-platform", 0 },
>  	{ }
> @@ -400,6 +408,7 @@ static struct platform_driver ehci_platform_driver = {
>  		.name	= "ehci-platform",
>  		.pm	= &ehci_platform_pm_ops,
>  		.of_match_table = vt8500_ehci_ids,
> +		.acpi_match_table = ACPI_PTR(ehci_acpi_match),
>  	}
>  };

With these changes:

Acked-by: Alan Stern <stern at rowland.harvard.edu>

Alan Stern



From thierry.reding at gmail.com  Thu Aug 13 07:54:47 2015
From: thierry.reding at gmail.com (Thierry Reding)
Date: Thu, 13 Aug 2015 16:54:47 +0200
Subject: [PATCH v3] ARM: tegra: cpuidle: implement
 cpuidle_state.enter_freeze()
In-Reply-To: <1432046953-12945-1-git-send-email-tomeu.vizoso@collabora.com>
References: <1432046953-12945-1-git-send-email-tomeu.vizoso@collabora.com>
Message-ID: <20150813145446.GD26559@ulmo>

On Tue, May 19, 2015 at 04:49:12PM +0200, Tomeu Vizoso wrote:
> This callback is expected to do the same as enter() but it has to
> guarantee that interrupts aren't enabled at any point in its execution,
> as the tick is frozen.
> 
> It will be called when the system goes to suspend-to-idle and will
> reduce power usage because CPUs won't be awaken for unnecessary IRQs.
> 
> By setting the CPUIDLE_FLAG_TIMER_STOP flag, we can reuse the same code
> for both the enter() and enter_freeze() callbacks.
> 
> Signed-off-by: Tomeu Vizoso <tomeu.vizoso at collabora.com>
> Cc: Rafael J. Wysocki <rafael.j.wysocki at intel.com>
> 
> ---
> 
> v3:	* Set CPUIDLE_FLAG_TIMER_STOP to simplify things as suggested by
> 	Lorenzo Pieralisi
> v2:	* Disable FIQs also when suspending-to-idle
> ---
>  arch/arm/mach-tegra/cpuidle-tegra114.c | 13 +++++++++----
>  1 file changed, 9 insertions(+), 4 deletions(-)

Applied, thanks.

Thierry
-------------- next part --------------
A non-text attachment was scrubbed...
Name: signature.asc
Type: application/pgp-signature
Size: 819 bytes
Desc: not available
URL: <http://lists.infradead.org/pipermail/linux-arm-kernel/attachments/20150813/06f41e28/attachment.sig>

From balbi at ti.com  Thu Aug 13 08:01:14 2015
From: balbi at ti.com (Felipe Balbi)
Date: Thu, 13 Aug 2015 10:01:14 -0500
Subject: [PATCH-next 2/4] arm: boot: dts: am4372: add ARM timers and SCU
 nodes
In-Reply-To: <20150813083215.GY4215@atomide.com>
References: <1439409416-32673-1-git-send-email-balbi@ti.com>
 <1439409416-32673-3-git-send-email-balbi@ti.com>
 <20150813083215.GY4215@atomide.com>
Message-ID: <20150813150114.GH27560@saruman.tx.rr.com>

On Thu, Aug 13, 2015 at 01:32:15AM -0700, Tony Lindgren wrote:
> * Felipe Balbi <balbi at ti.com> [150812 13:00]:
> > AM437x devices sport SCU, TWD and Global timers,
> > let's add them to DTS so they have a chance to
> > probe and be used by Linux.
> 
> Applying this one into omap-for-v4.3/dt-v2. Not sure
> if it will get merged as we're getting close to the
> merge window. The rest we can patch once Russell has
> reverted the bogus SMP dependency.

I'm just waiting for Russell's "it's okay to post on patch system".

-- 
balbi
-------------- next part --------------
A non-text attachment was scrubbed...
Name: signature.asc
Type: application/pgp-signature
Size: 819 bytes
Desc: Digital signature
URL: <http://lists.infradead.org/pipermail/linux-arm-kernel/attachments/20150813/a9e68a66/attachment-0001.sig>

From lorenzo.pieralisi at arm.com  Thu Aug 13 08:01:54 2015
From: lorenzo.pieralisi at arm.com (Lorenzo Pieralisi)
Date: Thu, 13 Aug 2015 16:01:54 +0100
Subject: [PATCH 5/9] ARM: common: Introduce PM domains for CPUs/clusters
In-Reply-To: <CAL_JsqK67=DTtjZwwnonObLDjLbahkREfm0RvyXVV95bhR-d4Q@mail.gmail.com>
References: <1438731339-58317-1-git-send-email-lina.iyer@linaro.org>
 <1438731339-58317-6-git-send-email-lina.iyer@linaro.org>
 <CAL_JsqK67=DTtjZwwnonObLDjLbahkREfm0RvyXVV95bhR-d4Q@mail.gmail.com>
Message-ID: <20150813150154.GB13356@red-moon>

On Thu, Aug 06, 2015 at 04:14:51AM +0100, Rob Herring wrote:
> On Tue, Aug 4, 2015 at 6:35 PM, Lina Iyer <lina.iyer at linaro.org> wrote:
> > Define and add Generic PM domains (genpd) for ARM CPU clusters. Many new
> > SoCs group CPUs as clusters. Clusters share common resources like GIC,
> > power rail, caches, VFP, Coresight etc. When all CPUs in the cluster are
> > idle, these shared resources may also be put in their idle state.
> >
> > The idle time between the last CPU entering idle and a CPU resuming
> > execution is an opportunity for these shared resources to be powered
> > down. Generic PM domain provides a framework for defining such power
> > domains and attach devices to the domain. When the devices in the domain
> > are idle at runtime, the domain would also be suspended and resumed
> > before the first of the devices resume execution.
> >
> > We define a generic PM domain for each cluster and attach CPU devices in
> > the cluster to that PM domain. The DT definitions for the SoC describe
> > this relationship. Genpd callbacks for power_on and power_off can then
> > be used to power up/down the shared resources for the domain.
> 
> [...]
> 
> > +ARM CPU Power domains
> > +
> > +The device tree allows describing of CPU power domains in a SoC. In ARM SoC,
> > +CPUs may be grouped as clusters. A cluster may have CPUs, GIC, Coresight,
> > +caches, VFP and power controller and other peripheral hardware. Generally,
> > +when the CPUs in the cluster are idle/suspended, the shared resources may also
> > +be suspended and resumed before any of the CPUs resume execution.
> > +
> > +CPUs are the defined as the PM domain consumers and there is a PM domain
> > +provider for the CPUs. Bindings for generic PM domains (genpd) is described in
> > +[1].
> > +
> > +The ARM CPU PM domain follows the same binding convention as any generic PM
> > +domain. Additional binding properties are -
> > +
> > +- compatible:
> > +       Usage: required
> > +       Value type: <string>
> > +       Definition: Must also have
> > +                       "arm,pd"
> > +               inorder to initialize the genpd provider as ARM CPU PM domain.
> 
> A compatible string should represent a particular h/w block. If it is
> generic, it should represent some sort of standard programming
> interface (e.g, AHCI, EHCI, etc.). This doesn't seem to be either and
> is rather just a mapping of what "driver" you want to use.
> 
> I would expect that identifying a cpu's or cluster's power domain
> would be done by a phandle between the cpu/cluster node and power
> domain node. But I've not really looked at the power domain bindings
> so who knows.

I would expect the same, meaning that a cpu node, like any other device
node would have a phandle pointing at the respective HW power domain.

I do not really understand why we want a "generic" CPU power domain, what
purpose does it serve ? Creating a collection of cpu devices that we
can call "cluster" ?

Thanks,
Lorenzo


From marc.zyngier at arm.com  Thu Aug 13 08:06:42 2015
From: marc.zyngier at arm.com (Marc Zyngier)
Date: Thu, 13 Aug 2015 16:06:42 +0100
Subject: [PATCH v2 2/5] irqchip, gicv3: Add HW revision detection and
 configuration
In-Reply-To: <1439477277-6157-3-git-send-email-rric@kernel.org>
References: <1439477277-6157-1-git-send-email-rric@kernel.org>
 <1439477277-6157-3-git-send-email-rric@kernel.org>
Message-ID: <55CCB282.8070405@arm.com>

On 13/08/15 15:47, Robert Richter wrote:
> From: Robert Richter <rrichter at cavium.com>
> 
> Some GIC revisions require an individual configuration to esp. add
> workarounds for HW bugs. This patch implements generic code to parse
> the hw revision provided by an IIDR register value and runs specific
> code if hw matches. There are functions that read the IIDR registers
> for GICV3 and ITS (GICD_IIDR/GITS_IIDR) and then go through a list of
> init functions to be called for specific versions.
> 
> A MIDR register value may also be used, this is especially useful for
> hw detection from a guest.
> 
> The patch is needed to implement workarounds for HW errata in Cavium's
> ThunderX GICV3.
> 
> V2:
>  * adding MIDR check
> 
> Signed-off-by: Robert Richter <rrichter at cavium.com>
> ---
>  drivers/irqchip/irq-gic-common.c | 13 +++++++++++++
>  drivers/irqchip/irq-gic-common.h | 11 +++++++++++
>  drivers/irqchip/irq-gic-v3-its.c | 15 +++++++++++++++
>  drivers/irqchip/irq-gic-v3.c     | 14 ++++++++++++++
>  4 files changed, 53 insertions(+)
> 
> diff --git a/drivers/irqchip/irq-gic-common.c b/drivers/irqchip/irq-gic-common.c
> index 9448e391cb71..886c09e645bf 100644
> --- a/drivers/irqchip/irq-gic-common.c
> +++ b/drivers/irqchip/irq-gic-common.c
> @@ -21,6 +21,19 @@
>  
>  #include "irq-gic-common.h"
>  
> +void gic_check_capabilities(u32 iidr, const struct gic_capabilities *cap,
> +			void *data)
> +{
> +	for (; cap->desc; cap++) {
> +		if (cap->midr != (cap->midr_mask & read_cpuid_id()))
> +			continue;
> +		if (cap->iidr != (cap->iidr_mask & iidr))
> +			continue;
> +		cap->init(data);
> +		pr_info("%s\n", cap->desc);
> +	}
> +}
> +
>  int gic_configure_irq(unsigned int irq, unsigned int type,
>  		       void __iomem *base, void (*sync_access)(void))
>  {
> diff --git a/drivers/irqchip/irq-gic-common.h b/drivers/irqchip/irq-gic-common.h
> index 35a9884778bd..e9a3e2800005 100644
> --- a/drivers/irqchip/irq-gic-common.h
> +++ b/drivers/irqchip/irq-gic-common.h
> @@ -20,10 +20,21 @@
>  #include <linux/of.h>
>  #include <linux/irqdomain.h>
>  
> +struct gic_capabilities {
> +	const char *desc;
> +	void (*init)(void *data);
> +	u32 iidr;
> +	u32 iidr_mask;
> +	u32 midr;
> +	u32 midr_mask;
> +};

Sorry to ask the obvious, but why should we implement another MIDR check
that is private to the GIC driver, while we already have an
infrastructure that deals with that kind of things?

Also, the GIC CPU interface is very much part of the CPU, not part the
GIC itself. I'd rather see a CPU erratum being handler at the same
location as all the other errata.

Thanks,

	M.
-- 
Jazz is not dead. It just smells funny...


From nm at ti.com  Thu Aug 13 08:09:41 2015
From: nm at ti.com (Nishanth Menon)
Date: Thu, 13 Aug 2015 10:09:41 -0500
Subject: [PATCH 0/3] ARM: multi_v7_defconfig: Enable more OMAP family
 platforms
In-Reply-To: <20150811103751.GK4215@atomide.com>
References: <1428614121-3374-1-git-send-email-nm@ti.com>
 <20150805102234.GZ16878@atomide.com>
 <7hfv3uwvdw.fsf@deeprootsystems.com>
 <20150811103751.GK4215@atomide.com>
Message-ID: <CAGo_u6q+U_Yi7Oq2pAFr4hs28_-G6dFbiHJQg3s3aEj0vG1asg@mail.gmail.com>

On Tue, Aug 11, 2015 at 5:37 AM, Tony Lindgren <tony at atomide.com> wrote:
>
> * Kevin Hilman <khilman at kernel.org> [150807 16:10]:
> > Tony Lindgren <tony at atomide.com> writes:
> >
> > > Ping, looks like these are still pending. Probably should be
> > > applied directly by the arm-soc maintainers.
> >
> > If these should go through arm-soc, please resend to:arm at kernel.org so
> > they make it into our queue of stuff to be reviewed/applied.
>
> OK thanks, up to Nihshant to resend.
>

Sorry about the slow response - i will have to do this at a later
point(probably based off 4.3-rc1). tied up with a few other internal
stuff atm :(

-- 
---
Regards,
Nishanth Menon


From marc.zyngier at arm.com  Thu Aug 13 08:11:15 2015
From: marc.zyngier at arm.com (Marc Zyngier)
Date: Thu, 13 Aug 2015 16:11:15 +0100
Subject: [PATCH v2 3/5] irqchip, gicv3: Workaround for Cavium ThunderX
 erratum 23154
In-Reply-To: <1439477277-6157-4-git-send-email-rric@kernel.org>
References: <1439477277-6157-1-git-send-email-rric@kernel.org>
 <1439477277-6157-4-git-send-email-rric@kernel.org>
Message-ID: <55CCB393.1040909@arm.com>

On 13/08/15 15:47, Robert Richter wrote:
> From: Robert Richter <rrichter at cavium.com>
> 
> This patch implements Cavium ThunderX erratum 23154.
> 
> The gicv3 of ThunderX requires a modified version for reading the IAR
> status to ensure data synchronization. Since this is in the fast-path
> and called with each interrupt, runtime patching is used using jump
> label patching for smallest overhead (no-op). This is the same
> technique as used for tracepoints.
> 
> v2:
>  * implement code in a single asm() to keep instruction sequence
>  * added comment to the code that explains the erratum
>  * apply workaround also if running as guest, thus check MIDR
> 
> Signed-off-by: Robert Richter <rrichter at cavium.com>
> ---
>  drivers/irqchip/irq-gic-v3.c | 45 +++++++++++++++++++++++++++++++++++++++++++-
>  1 file changed, 44 insertions(+), 1 deletion(-)
> 
> diff --git a/drivers/irqchip/irq-gic-v3.c b/drivers/irqchip/irq-gic-v3.c
> index 1a91902be0b1..2f80a11621a0 100644
> --- a/drivers/irqchip/irq-gic-v3.c
> +++ b/drivers/irqchip/irq-gic-v3.c
> @@ -107,7 +107,7 @@ static void gic_redist_wait_for_rwp(void)
>  }
>  
>  /* Low level accessors */
> -static u64 __maybe_unused gic_read_iar(void)
> +static u64 gic_read_iar_common(void)
>  {
>  	u64 irqstat;
>  
> @@ -115,6 +115,38 @@ static u64 __maybe_unused gic_read_iar(void)
>  	return irqstat;
>  }
>  
> +/*
> + * Cavium ThunderX erratum 23154
> + *
> + * The gicv3 of ThunderX requires a modified version for reading the
> + * IAR status to ensure data synchronization (access to icc_iar1_el1
> + * is not sync'ed before and after).
> + */
> +static u64 gic_read_iar_cavium_thunderx(void)
> +{
> +	u64 irqstat;
> +
> +	asm volatile(
> +		"nop;nop;nop;nop\n\t"
> +		"nop;nop;nop;nop\n\t"
> +		"mrs_s %0, " __stringify(ICC_IAR1_EL1) "\n\t"
> +		"nop;nop;nop;nop"
> +		: "=r" (irqstat));
> +	mb();
> +
> +	return irqstat;
> +}
> +
> +struct static_key is_cavium_thunderx = STATIC_KEY_INIT_FALSE;
> +
> +static u64 __maybe_unused gic_read_iar(void)
> +{
> +	if (static_key_false(&is_cavium_thunderx))
> +		return gic_read_iar_common();
> +	else
> +		return gic_read_iar_cavium_thunderx();
> +}
> +
>  static void __maybe_unused gic_write_pmr(u64 val)
>  {
>  	asm volatile("msr_s " __stringify(ICC_PMR_EL1) ", %0" : : "r" (val));
> @@ -766,8 +798,19 @@ static const struct irq_domain_ops gic_irq_domain_ops = {
>  	.free = gic_irq_domain_free,
>  };
>  
> +static void gicv3_enable_cavium_thunderx(void *data)
> +{
> +	static_key_slow_inc(&is_cavium_thunderx);
> +}
> +
>  static const struct gic_capabilities gicv3_errata[] = {
>  	{
> +		.desc		= "GIC: Cavium erratum 23154",
> +		.iidr		= 0xa100034c,	/* ThunderX pass 1.x */
> +		.iidr_mask	= 0xffff0fff,
> +		.init		= gicv3_enable_cavium_thunderx,
> +	},

I'm even more puzzled. You're working around a CPU bug based on the ITS
ID registers? Or have you swapped the detection methods for the two errata?

	M.
-- 
Jazz is not dead. It just smells funny...


From jeremy.linton at arm.com  Thu Aug 13 08:13:44 2015
From: jeremy.linton at arm.com (Jeremy Linton)
Date: Thu, 13 Aug 2015 10:13:44 -0500
Subject: [PATCH 3/3] Add ACPI bindings for the EHCI platform driver.
In-Reply-To: <Pine.LNX.4.44L0.1508131049001.1277-100000@iolanthe.rowland.org>
References: <Pine.LNX.4.44L0.1508131049001.1277-100000@iolanthe.rowland.org>
Message-ID: <55CCB428.1000404@arm.com>

Alan,

On 08/13/2015 09:53 AM, Alan Stern wrote:
> With these changes:

	Applied..

> Acked-by: Alan Stern <stern at rowland.harvard.edu>

	Thanks,







From catalin.marinas at arm.com  Thu Aug 13 08:16:04 2015
From: catalin.marinas at arm.com (Catalin Marinas)
Date: Thu, 13 Aug 2015 16:16:04 +0100
Subject: [PATCH] ARM: dma-mapping: Don't use outer_flush_range when the
 L2C is coherent
In-Reply-To: <1439474365-12058-1-git-send-email-gregory.clement@free-electrons.com>
References: <1439474365-12058-1-git-send-email-gregory.clement@free-electrons.com>
Message-ID: <20150813151603.GB4602@e104818-lin.cambridge.arm.com>

On Thu, Aug 13, 2015 at 03:59:25PM +0200, Gregory CLEMENT wrote:
> @@ -241,12 +241,15 @@ static void __dma_clear_buffer(struct page *page, size_t size)
>  			page++;
>  			size -= PAGE_SIZE;
>  		}
> -		outer_flush_range(base, end);
> +		if (!is_coherent)
> +			outer_flush_range(base, end);

There is a dmac_flush_range() call above this (in the "while" block),
please add a check for is_coherent in there as well.

> @@ -540,7 +545,13 @@ static void *__alloc_from_contiguous(struct device *dev, size_t size,
>  	if (!page)
>  		return NULL;
>  
> -	__dma_clear_buffer(page, size);
> +	/*
> +	 * We are either called from __dma_alloc on the non-coherent
> +	 * case or only once from atomic_pool_init. It is called
> +	 * during boot time so it is harmless to use the non-coherent
> +	 * case even if the L2C is coherent.
> +	 */
> +	__dma_clear_buffer(page, size, false);

This is no longer the case with commit 21caf3a765b0 ("ARM: 8398/1: arm
DMA: Fix allocation from CMA for coherent DMA") in -next. So you need
another argument for __alloc_from_contiguous() that can be passed down
to __dma_clear_buffer().

> @@ -1131,7 +1143,8 @@ static inline void __free_iova(struct dma_iommu_mapping *mapping,
>  }
>  
>  static struct page **__iommu_alloc_buffer(struct device *dev, size_t size,
> -					  gfp_t gfp, struct dma_attrs *attrs)
> +					gfp_t gfp, struct dma_attrs *attrs,
> +					bool is_coherent)
>  {
>  	struct page **pages;
>  	int count = size >> PAGE_SHIFT;
> @@ -1154,7 +1167,7 @@ static struct page **__iommu_alloc_buffer(struct device *dev, size_t size,
>  		if (!page)
>  			goto error;
>  
> -		__dma_clear_buffer(page, size);
> +		__dma_clear_buffer(page, size, is_coherent);
>  
>  		for (i = 0; i < count; i++)
>  			pages[i] = page + i;
> @@ -1198,7 +1211,7 @@ static struct page **__iommu_alloc_buffer(struct device *dev, size_t size,
>  				pages[i + j] = pages[i] + j;
>  		}
>  
> -		__dma_clear_buffer(pages[i], PAGE_SIZE << order);
> +		__dma_clear_buffer(pages[i], PAGE_SIZE << order, is_coherent);
>  		i += 1 << order;
>  		count -= 1 << order;
>  	}
> @@ -1359,8 +1372,9 @@ static void __iommu_free_atomic(struct device *dev, void *cpu_addr,
>  	__free_from_pool(cpu_addr, size);
>  }
>  
> -static void *arm_iommu_alloc_attrs(struct device *dev, size_t size,
> -	    dma_addr_t *handle, gfp_t gfp, struct dma_attrs *attrs)
> +static void *__arm_iommu_alloc_attrs(struct device *dev, size_t size,
> +	    dma_addr_t *handle, gfp_t gfp, struct dma_attrs *attrs,
> +	    bool is_coherent)
>  {
>  	pgprot_t prot = __get_dma_pgprot(attrs, PAGE_KERNEL);
>  	struct page **pages;
> @@ -1381,7 +1395,7 @@ static void *arm_iommu_alloc_attrs(struct device *dev, size_t size,
>  	 */
>  	gfp &= ~(__GFP_COMP);
>  
> -	pages = __iommu_alloc_buffer(dev, size, gfp, attrs);
> +	pages = __iommu_alloc_buffer(dev, size, gfp, attrs, is_coherent);
>  	if (!pages)
>  		return NULL;
>  

I can see you are trying to fix the iommu_alloc code to cope with
coherent devices. I think it's currently broken and if you want to fix
it, you'd better add a separate patch. Otherwise, if no-one needs it,
just pass false to __dma_clear_buffer() in __iommu_alloc_buffer()
(though it's better if we fixed it).

In arm_iommu_alloc_attrs(), there is an __iommu_alloc_atomic() call
which goes to the non-cacheable pool, it should use
__alloc_simple_buffer() instead if is_coherent.

-- 
Catalin


From ludovic.desroches at atmel.com  Thu Aug 13 08:23:03 2015
From: ludovic.desroches at atmel.com (Ludovic Desroches)
Date: Thu, 13 Aug 2015 17:23:03 +0200
Subject: [PATCH] mmc: atmel-mci: remove useless include
In-Reply-To: <1439216808-11826-1-git-send-email-alexandre.belloni@free-electrons.com>
References: <1439216808-11826-1-git-send-email-alexandre.belloni@free-electrons.com>
Message-ID: <20150813152303.GA7268@odux.rfo.atmel.com>

On Mon, Aug 10, 2015 at 04:26:48PM +0200, Alexandre Belloni wrote:
> Definitions from linux/platform_data/atmel.h are not used, remove the
> include.
> 
> Signed-off-by: Alexandre Belloni <alexandre.belloni at free-electrons.com>
Acked-by: Ludovic Desroches <ludovic.desroches at atmel.com>

> ---
>  drivers/mmc/host/atmel-mci.c | 1 -
>  1 file changed, 1 deletion(-)
> 
> diff --git a/drivers/mmc/host/atmel-mci.c b/drivers/mmc/host/atmel-mci.c
> index 9a39e0b7e583..bf62e429f7fc 100644
> --- a/drivers/mmc/host/atmel-mci.c
> +++ b/drivers/mmc/host/atmel-mci.c
> @@ -29,7 +29,6 @@
>  #include <linux/slab.h>
>  #include <linux/stat.h>
>  #include <linux/types.h>
> -#include <linux/platform_data/atmel.h>
>  #include <linux/platform_data/mmc-atmel-mci.h>
>  
>  #include <linux/mmc/host.h>
> -- 
> 2.1.4
> 


From HenryC.Chen at mediatek.com  Thu Aug 13 08:25:05 2015
From: HenryC.Chen at mediatek.com (Henry Chen)
Date: Thu, 13 Aug 2015 23:25:05 +0800
Subject: [PATCH] regmap: Add function check before called format_val
In-Reply-To: <CAGS+omDa+FhKD2u_VwBG3cWvN+ZiHneqFVz=mtdYuPsiQu4JEQ@mail.gmail.com>
References: <1437396110-5192-1-git-send-email-henryc.chen@mediatek.com>
 <20150720150254.GC11162@sirena.org.uk>
 <1437458845.30329.51.camel@mtksdaap41>
 <CAGS+omDa+FhKD2u_VwBG3cWvN+ZiHneqFVz=mtdYuPsiQu4JEQ@mail.gmail.com>
Message-ID: <1439479505.32674.43.camel@mtksdaap41>

On Wed, 2015-08-12 at 22:20 +0800, Daniel Kurtz wrote:

> 
> Since I didn't see it elsewhere in this discussion, I'll point out
> that the "regression" here was introduced by commit [0], which added
> the call to map->format.format_val from regmap_bulk_read() when
> map->bus == NULL.
> 
> [0] commit 15b8d2c41fe5839582029f65c5f7004db451cc2b
>   Author: Arun Chandran <achandran at mvista.com>
>   regmap: Fix regmap_bulk_read in BE mode
> 
> Perhaps the easiest work around to unbreak v4.2 is, as Henry mentions,
> for mtk_pmic_wrap to define its own regmap_bus, with .read() &
> .write() handlers.  This way they will inherit the default built-in
> format_val() from the regmap core.
> 
> Making mtk_pmic-wrap into a regmap_bus makes a bit of sense
> architecturally, too, since it is essentially just a bus for accessing
> the registers of an off-chip PMIC.  The CPU sees a platform bus, but
> the registers of the remote PMIC are accessed over a dedicated SPI
> bus.
> 
> WDYT?
> 
> Henry, can you try to implement this?

Hi Daniel,
I can try to create a regmap_bus for pmic wrap. But I'm not sure if it
was the good solution for this problem.

Hi Mark,
Sorry, I'm afraid that I cannot do this right on init as you said last
time. What do you think about regmap_bus, can you accept that way?

Thanks,
Henry
> 
> Thanks,
> -Dan




From eric.auger at linaro.org  Thu Aug 13 08:25:32 2015
From: eric.auger at linaro.org (Eric Auger)
Date: Thu, 13 Aug 2015 17:25:32 +0200
Subject: [PATCH v2 09/15] KVM: arm64: implement basic ITS register handlers
In-Reply-To: <1436538111-4294-10-git-send-email-andre.przywara@arm.com>
References: <1436538111-4294-1-git-send-email-andre.przywara@arm.com>
 <1436538111-4294-10-git-send-email-andre.przywara@arm.com>
Message-ID: <55CCB6EC.50609@linaro.org>

On 07/10/2015 04:21 PM, Andre Przywara wrote:
> Add emulation for some basic MMIO registers used in the ITS emulation.
> This includes:
> - GITS_{CTLR,TYPER,IIDR}
> - ID registers
> - GITS_{CBASER,CREADR,CWRITER}
>   those implement the ITS command buffer handling
> 
> Most of the handlers are pretty straight forward
straightforward?
, but CWRITER goes
> some extra miles to allow fine grained locking. The idea here
> is to let only the first instance iterate through the command ring
> buffer, CWRITER accesses on other VCPUs meanwhile will be picked up
> by that first instance and handled as well. The ITS lock is thus only
> hold for very small periods of time and is dropped before the actual
> command handler is called.
> 
> Signed-off-by: Andre Przywara <andre.przywara at arm.com>
> ---
>  include/kvm/arm_vgic.h             |   3 +
>  include/linux/irqchip/arm-gic-v3.h |   8 ++
>  virt/kvm/arm/its-emul.c            | 205 +++++++++++++++++++++++++++++++++++++
>  virt/kvm/arm/its-emul.h            |   1 +
>  virt/kvm/arm/vgic-v3-emul.c        |   2 +
>  5 files changed, 219 insertions(+)
> 
> diff --git a/include/kvm/arm_vgic.h b/include/kvm/arm_vgic.h
> index 9e9d4aa..b432055 100644
> --- a/include/kvm/arm_vgic.h
> +++ b/include/kvm/arm_vgic.h
> @@ -159,6 +159,9 @@ struct vgic_io_device {
>  struct vgic_its {
>  	bool			enabled;
>  	spinlock_t		lock;
> +	u64			cbaser;
> +	int			creadr;
> +	int			cwriter;
>  };
>  
>  struct vgic_dist {
> diff --git a/include/linux/irqchip/arm-gic-v3.h b/include/linux/irqchip/arm-gic-v3.h
> index df4e527..0b450c7 100644
> --- a/include/linux/irqchip/arm-gic-v3.h
> +++ b/include/linux/irqchip/arm-gic-v3.h
> @@ -179,15 +179,23 @@
>  #define GITS_BASER			0x0100
>  #define GITS_IDREGS_BASE		0xffd0
>  #define GITS_PIDR2			GICR_PIDR2
> +#define GITS_PIDR4			0xffd0
> +#define GITS_CIDR0			0xfff0
> +#define GITS_CIDR1			0xfff4
> +#define GITS_CIDR2			0xfff8
> +#define GITS_CIDR3			0xfffc
>  
>  #define GITS_TRANSLATER			0x10040
>  
>  #define GITS_CTLR_ENABLE		(1U << 0)
>  #define GITS_CTLR_QUIESCENT		(1U << 31)
>  
> +#define GITS_TYPER_PLPIS		(1UL << 0)
> +#define GITS_TYPER_IDBITS_SHIFT		8
>  #define GITS_TYPER_DEVBITS_SHIFT	13
>  #define GITS_TYPER_DEVBITS(r)		((((r) >> GITS_TYPER_DEVBITS_SHIFT) & 0x1f) + 1)
>  #define GITS_TYPER_PTA			(1UL << 19)
> +#define GITS_TYPER_HWCOLLCNT_SHIFT	24
>  
>  #define GITS_CBASER_VALID		(1UL << 63)
>  #define GITS_CBASER_nCnB		(0UL << 59)
> diff --git a/virt/kvm/arm/its-emul.c b/virt/kvm/arm/its-emul.c
> index 659dd39..b498f06 100644
> --- a/virt/kvm/arm/its-emul.c
> +++ b/virt/kvm/arm/its-emul.c
> @@ -32,10 +32,62 @@
>  #include "vgic.h"
>  #include "its-emul.h"
>  
> +#define BASER_BASE_ADDRESS(x) ((x) & 0xfffffffff000ULL)
> +
> +/* The distributor lock is held by the VGIC MMIO handler. */
>  static bool handle_mmio_misc_gits(struct kvm_vcpu *vcpu,
>  				  struct kvm_exit_mmio *mmio,
>  				  phys_addr_t offset)
>  {
> +	struct vgic_its *its = &vcpu->kvm->arch.vgic.its;
> +	u32 reg;
> +	bool was_enabled;
> +
> +	switch (offset & ~3) {
> +	case 0x00:		/* GITS_CTLR */
> +		/* We never defer any command execution. */
> +		reg = GITS_CTLR_QUIESCENT;
> +		if (its->enabled)
> +			reg |= GITS_CTLR_ENABLE;
> +		was_enabled = its->enabled;
> +		vgic_reg_access(mmio, &reg, offset & 3,
> +				ACCESS_READ_VALUE | ACCESS_WRITE_VALUE);
> +		its->enabled = !!(reg & GITS_CTLR_ENABLE);
> +		return !was_enabled && its->enabled;
> +	case 0x04:		/* GITS_IIDR */
> +		reg = (PRODUCT_ID_KVM << 24) | (IMPLEMENTER_ARM << 0);
> +		vgic_reg_access(mmio, &reg, offset & 3,
> +				ACCESS_READ_VALUE | ACCESS_WRITE_IGNORED);
> +		break;
> +	case 0x08:		/* GITS_TYPER */
> +		/*
> +		 * We use linear CPU numbers for redistributor addressing,
> +		 * so GITS_TYPER.PTA is 0.
> +		 * To avoid memory waste on the guest side, we keep the
> +		 * number of IDBits and DevBits low for the time being.
> +		 * This could later be made configurable by userland.
> +		 * Since we have all collections in linked list, we claim
> +		 * that we can hold all of the collection tables in our
> +		 * own memory and that the ITT entry size is 1 byte (the
> +		 * smallest possible one).
> +		 */
> +		reg = GITS_TYPER_PLPIS;
> +		reg |= 0xff << GITS_TYPER_HWCOLLCNT_SHIFT;
> +		reg |= 0x0f << GITS_TYPER_DEVBITS_SHIFT;
> +		reg |= 0x0f << GITS_TYPER_IDBITS_SHIFT;
> +		vgic_reg_access(mmio, &reg, offset & 3,
> +				ACCESS_READ_VALUE | ACCESS_WRITE_IGNORED);
> +		break;
> +	case 0x0c:
> +		/* The upper 32bits of TYPER are all 0 for the time being.
> +		 * Should we need more than 256 collections, we can enable
> +		 * some bits in here.
> +		 */
> +		vgic_reg_access(mmio, NULL, offset & 3,
> +				ACCESS_READ_RAZ | ACCESS_WRITE_IGNORED);
> +		break;
> +	}
> +
>  	return false;
>  }
>  
> @@ -43,20 +95,142 @@ static bool handle_mmio_gits_idregs(struct kvm_vcpu *vcpu,
>  				    struct kvm_exit_mmio *mmio,
>  				    phys_addr_t offset)
>  {
> +	u32 reg = 0;
> +	int idreg = (offset & ~3) + GITS_IDREGS_BASE;
> +
> +	switch (idreg) {
> +	case GITS_PIDR2:
> +		reg = GIC_PIDR2_ARCH_GICv3;
> +		break;
> +	case GITS_PIDR4:
> +		/* This is a 64K software visible page */
> +		reg = 0x40;
> +		break;
> +	/* Those are the ID registers for (any) GIC. */
> +	case GITS_CIDR0:
> +		reg = 0x0d;
> +		break;
> +	case GITS_CIDR1:
> +		reg = 0xf0;
> +		break;
> +	case GITS_CIDR2:
> +		reg = 0x05;
> +		break;
> +	case GITS_CIDR3:
> +		reg = 0xb1;
> +		break;
> +	}
> +	vgic_reg_access(mmio, &reg, offset & 3,
> +			ACCESS_READ_VALUE | ACCESS_WRITE_IGNORED);
>  	return false;
>  }
>  
> +static int vits_handle_command(struct kvm_vcpu *vcpu, u64 *its_cmd)
> +{
> +	return -ENODEV;
> +}
> +
>  static bool handle_mmio_gits_cbaser(struct kvm_vcpu *vcpu,
>  				    struct kvm_exit_mmio *mmio,
>  				    phys_addr_t offset)
>  {
> +	struct vgic_its *its = &vcpu->kvm->arch.vgic.its;
> +	int mode = ACCESS_READ_VALUE;
> +
> +	mode |= its->enabled ? ACCESS_WRITE_IGNORED : ACCESS_WRITE_VALUE;
> +
> +	vgic_handle_base_register(vcpu, mmio, offset, &its->cbaser, mode);
> +
> +	/* Writing CBASER resets the read pointer. */
> +	if (mmio->is_write)
> +		its->creadr = 0;
> +
>  	return false;
>  }
>  
> +static int its_cmd_buffer_size(struct kvm *kvm)
> +{
> +	struct vgic_its *its = &kvm->arch.vgic.its;
> +
> +	return ((its->cbaser & 0xff) + 1) << 12;
> +}
> +
> +static gpa_t its_cmd_buffer_base(struct kvm *kvm)
> +{
> +	struct vgic_its *its = &kvm->arch.vgic.its;
> +
> +	return BASER_BASE_ADDRESS(its->cbaser);
> +}
> +
> +/*
> + * By writing to CWRITER the guest announces new commands to be processed.
> + * Since we cannot read from guest memory inside the ITS spinlock, we
> + * iterate over the command buffer (with the lock dropped) until the read
> + * pointer matches the write pointer. Other VCPUs writing this register in the
> + * meantime will just update the write pointer, leaving the command
> + * processing to the first instance of the function.
> + */
I am lost, isn't the dist lock hold by vgic_handle_mmio_access before
calling call_range_handler/range->handle_mmio ?

if confirmed we need to move the command enumeration + execution
somewhere else. Besides that piece of code may deserve to be
encaspulated in a function. what do you think?


>  static bool handle_mmio_gits_cwriter(struct kvm_vcpu *vcpu,
>  				     struct kvm_exit_mmio *mmio,
>  				     phys_addr_t offset)
>  {
> +	struct vgic_its *its = &vcpu->kvm->arch.vgic.its;
> +	gpa_t cbaser = its_cmd_buffer_base(vcpu->kvm);
> +	u64 cmd_buf[4];
> +	u32 reg;
> +	bool finished;
> +
> +	/* The upper 32 bits are RES0 */
> +	if ((offset & ~3) == 0x04) {
> +		vgic_reg_access(mmio, &reg, offset & 3,
> +				ACCESS_READ_RAZ | ACCESS_WRITE_IGNORED);
> +		return false;
> +	}
> +
> +	reg = its->cwriter & 0xfffe0;
> +	vgic_reg_access(mmio, &reg, offset & 3,
> +			ACCESS_READ_VALUE | ACCESS_WRITE_VALUE);
> +	if (!mmio->is_write)
> +		return false;
> +
> +	reg &= 0xfffe0;
> +	if (reg > its_cmd_buffer_size(vcpu->kvm))
> +		return false;
> +
> +	spin_lock(&its->lock);
> +
> +	/*
> +	 * If there is still another VCPU handling commands, let this
> +	 * one pick up the new CWRITER and process our new commands as well.
> +	 */
> +	finished = (its->cwriter != its->creadr);
> +	its->cwriter = reg;
> +
> +	spin_unlock(&its->lock);
> +
> +	while (!finished) {
> +		int ret = kvm_read_guest(vcpu->kvm, cbaser + its->creadr,
> +					 cmd_buf, 32);
> +		if (ret) {
> +			/*
> +			 * Gah, we are screwed. Reset CWRITER to that command
> +			 * that we have finished processing and return.
> +			 */
> +			spin_lock(&its->lock);
> +			its->cwriter = its->creadr;
> +			spin_unlock(&its->lock);
> +			break;
> +		}
> +		vits_handle_command(vcpu, cmd_buf);
> +
> +		spin_lock(&its->lock);
> +		its->creadr += 32;
> +		if (its->creadr == its_cmd_buffer_size(vcpu->kvm))
> +			its->creadr = 0;
> +		finished = (its->creadr == its->cwriter);
> +		spin_unlock(&its->lock);
> +	}
> +
>  	return false;
>  }
>  
> @@ -64,6 +238,20 @@ static bool handle_mmio_gits_creadr(struct kvm_vcpu *vcpu,
>  				    struct kvm_exit_mmio *mmio,
>  				    phys_addr_t offset)
>  {
> +	struct vgic_its *its = &vcpu->kvm->arch.vgic.its;
> +	u32 reg;
> +
> +	switch (offset & ~3) {
> +	case 0x00:
> +		reg = its->creadr & 0xfffe0;
> +		vgic_reg_access(mmio, &reg, offset & 3,
> +				ACCESS_READ_VALUE | ACCESS_WRITE_IGNORED);
> +		break;
> +	case 0x04:
> +		vgic_reg_access(mmio, &reg, offset & 3,
> +				ACCESS_READ_RAZ | ACCESS_WRITE_IGNORED);
> +		break;
> +	}
>  	return false;
>  }
>  
> @@ -117,9 +305,26 @@ int vits_init(struct kvm *kvm)
>  	struct vgic_dist *dist = &kvm->arch.vgic;
>  	struct vgic_its *its = &dist->its;
>  
> +	dist->pendbaser = kmalloc(sizeof(u64) * dist->nr_cpus, GFP_KERNEL);
check_patch advises to use kmalloc_array here (warning). or kcalloc?

Eric

> +	if (!dist->pendbaser)
> +		return -ENOMEM;
> +
>  	spin_lock_init(&its->lock);
>  
>  	its->enabled = false;
>  
>  	return -ENXIO;
>  }
> +
> +void vits_destroy(struct kvm *kvm)
> +{
> +	struct vgic_dist *dist = &kvm->arch.vgic;
> +	struct vgic_its *its = &dist->its;
> +
> +	if (!vgic_has_its(kvm))
> +		return;
> +
> +	kfree(dist->pendbaser);
> +
> +	its->enabled = false;
> +}
> diff --git a/virt/kvm/arm/its-emul.h b/virt/kvm/arm/its-emul.h
> index 5dc8e2f..472a6d0 100644
> --- a/virt/kvm/arm/its-emul.h
> +++ b/virt/kvm/arm/its-emul.h
> @@ -31,5 +31,6 @@
>  
>  void vgic_enable_lpis(struct kvm_vcpu *vcpu);
>  int vits_init(struct kvm *kvm);
> +void vits_destroy(struct kvm *kvm);
>  
>  #endif
> diff --git a/virt/kvm/arm/vgic-v3-emul.c b/virt/kvm/arm/vgic-v3-emul.c
> index f5865e7..49be3c3 100644
> --- a/virt/kvm/arm/vgic-v3-emul.c
> +++ b/virt/kvm/arm/vgic-v3-emul.c
> @@ -928,6 +928,8 @@ static void vgic_v3_destroy_model(struct kvm *kvm)
>  {
>  	struct vgic_dist *dist = &kvm->arch.vgic;
>  
> +	vits_destroy(kvm);
> +
>  	kfree(dist->irq_spi_mpidr);
>  	dist->irq_spi_mpidr = NULL;
>  }
> 



From agross at codeaurora.org  Thu Aug 13 08:31:05 2015
From: agross at codeaurora.org (Andy Gross)
Date: Thu, 13 Aug 2015 10:31:05 -0500
Subject: [GIT PULL] qcom SoC changes for 4.3 *CORRECTED*
In-Reply-To: <20150813130818.GE23581@localhost>
References: <1438379275-6314-1-git-send-email-agross@codeaurora.org>
 <20150813130818.GE23581@localhost>
Message-ID: <20150813153105.GB4627@qualcomm.com>

On Thu, Aug 13, 2015 at 03:08:18PM +0200, Olof Johansson wrote:
> On Fri, Jul 31, 2015 at 04:47:55PM -0500, Andy Gross wrote:
> > The following changes since commit d770e558e21961ad6cfdf0ff7df0eb5d7d4f0754:
> > 
> >   Linux 4.2-rc1 (2015-07-05 11:01:52 -0700)
> > 
> > are available in the git repository at:
> > 
> >   git://codeaurora.org/quic/kernel/agross-msm.git tags/qcom-soc-for-4.3
> > 
> > for you to fetch changes up to ba68227e610cec8e0bef7da7e04af3f479d9797d:
> > 
> >   devicetree: soc: Add Qualcomm SMD based RPM DT binding (2015-07-29 14:13:48 -0500)
> > 
> > ----------------------------------------------------------------
> > Qualcomm ARM Based SoC Updates for 4.3
> > 
> > * Add SMEM driver
> > * Add SMD driver
> > * Add RPM over SMD driver
> > * Select QCOM_SCM by default
> > 
> > ----------------------------------------------------------------
> > Bjorn Andersson (5):
> >       soc: qcom: Add Shared Memory Manager driver
> >       soc: qcom: Add device tree binding for Shared Memory Device
> >       soc: qcom: Add Shared Memory Driver
> >       soc: qcom: Driver for the Qualcomm RPM over SMD
> >       devicetree: soc: Add Qualcomm SMD based RPM DT binding
> > 
> > Lina Iyer (1):
> >       drivers: qcom: Select QCOM_SCM unconditionally for QCOM_PM
> 
> Ok, after looking through it, I've decided to merge this branch.
> 
> I'm still concerned that we are picking up similar functionality without
> any shared implementation for a lot of platforms right now. At some
> point we'll have to say that enough is enough and someone will have to
> clean it up.
> 
> In the past, Linaro has done some of that work since several members have been
> affected. I don't know if this is the right time to kick something off though,
> or if we should let a few more implementations surface such that there is
> a better set of needed use cases to base a common framework on.

We can certainly discuss this at the coming Connect.  I'll bring this up then.

Thanks for pulling this in.

-- 
Qualcomm Innovation Center, Inc.
The Qualcomm Innovation Center, Inc. is a member of the Code Aurora Forum,
a Linux Foundation Collaborative Project



From linux at arm.linux.org.uk  Thu Aug 13 08:37:07 2015
From: linux at arm.linux.org.uk (Russell King - ARM Linux)
Date: Thu, 13 Aug 2015 16:37:07 +0100
Subject: [PATCH-next 1/4] Revert "ARM: 7655/1: smp_twd: make
 twd_local_timer_of_register() no-op for nosmp"
In-Reply-To: <1439409416-32673-2-git-send-email-balbi@ti.com>
References: <1439409416-32673-1-git-send-email-balbi@ti.com>
 <1439409416-32673-2-git-send-email-balbi@ti.com>
Message-ID: <20150813153707.GF7576@n2100.arm.linux.org.uk>

On Wed, Aug 12, 2015 at 02:56:53PM -0500, Felipe Balbi wrote:
> This reverts commit 904464b91eca8c665acea033489225af02eeb75a.
> 
> The problem pointed out by commit 904464b91eca ("ARM: 7655/1:
> smp_twd: make twd_local_timer_of_register() no-op for nosmp")
> doesn't exist anymore.
> 
> We can safely boot with nosmp and the warning won't show up.
> 
> The other side benefit of this patch is that TWD has a chance
> to probe on single-core A9 systems such as AM437x which sport
> TWD.

I don't remember all the details from Feb 2013 on why we made that
change.  If this is proven safe, then I guess it's okay.

-- 
FTTC broadband for 0.8mile line: currently at 10.5Mbps down 400kbps up
according to speedtest.net.


From jassisinghbrar at gmail.com  Thu Aug 13 08:40:59 2015
From: jassisinghbrar at gmail.com (Jassi Brar)
Date: Thu, 13 Aug 2015 21:10:59 +0530
Subject: [PATCH v2 3/6] mailbox: Add support for ST's Mailbox IP
In-Reply-To: <1437990272-23111-4-git-send-email-lee.jones@linaro.org>
References: <1437990272-23111-1-git-send-email-lee.jones@linaro.org>
 <1437990272-23111-4-git-send-email-lee.jones@linaro.org>
Message-ID: <CABb+yY3NTHLx2N-sUABjxQW=MUCntdUg1d8kjvjH0dkb4n9EgA@mail.gmail.com>

On Mon, Jul 27, 2015 at 3:14 PM, Lee Jones <lee.jones at linaro.org> wrote:

> +
> +static bool sti_mbox_tx_is_ready(struct mbox_chan *chan)
> +{
> +       struct sti_channel *chan_info = chan->con_priv;
> +       struct sti_mbox_device *mdev = chan_info->mdev;
> +       unsigned int instance = chan_info->instance;
> +       unsigned int channel = chan_info->channel;
> +       void __iomem *base = MBOX_BASE(mdev, instance);
> +
> +       if (!(chan_info->direction & MBOX_TX))
> +               return false;
>
Here the 'direction' is gotten via DT node of the client i.e, you
expect consumer drivers to tell the provider what its limitations are?

IMO if some physical channel can't do TX then that should be either
hardcoded inside the controller driver or learnt via DT node of the
_controller_.


> +static struct mbox_chan *sti_mbox_xlate(struct mbox_controller *mbox,
> +                                       const struct of_phandle_args *spec)
> +{
> +       struct sti_mbox_device *mdev = dev_get_drvdata(mbox->dev);
> +       struct sti_mbox_pdata *pdata = dev_get_platdata(mdev->dev);
> +       struct sti_channel *chan_info;
> +       struct mbox_chan *chan = NULL;
> +       unsigned int instance  = spec->args[0];
> +       unsigned int channel   = spec->args[1];
> +       unsigned int direction = spec->args[2];
> +       int i;
> +
> +       /* Bounds checking */
> +       if (instance >= pdata->num_inst || channel  >= pdata->num_chan) {
> +               dev_err(mbox->dev,
> +                       "Invalid channel requested instance: %d channel: %d\n",
> +                       instance, channel);
> +               return NULL;
return ERR_PTR(-EINVAL)

> +       }
> +
> +       for (i = 0; i < mbox->num_chans; i++) {
> +               chan_info = mbox->chans[i].con_priv;
> +
> +               /* Is requested channel free? */
> +               if (direction != MBOX_LOOPBACK &&
>
Consider this example when 2 clients ask for same physical channel but
in different modes.
           mboxes = <&mboxA 0 1 MBOX_TX>;
           mboxes = <&mboxA 0 1 MBOX_LOOPBACK>;

You happily assign 2 virtual channels backed by one physical channel
{mboxA, 0, 1}. The 2 clients think they can freely do startup(),
shutdown() and send_data() on the channels. But obviously we are
screwed with races like
   client1.startup()
    -> client2.startup()
        -> client2.send_data()
            -> client2.shutdown()
                -> client1.send_data()  XXXX

 Now you can shove in some more checks to 'fix' the race OR you can
simply expose only physical channels. Practically no client would ever
ask it to do what it can't, and for the hypothetical possibility that
some does, just return error.

> +                   chan_info &&
> +                   mbox->dev == chan_info->mdev->dev &&
> +                   instance == chan_info->instance &&
> +                   channel == chan_info->channel) {
> +                       dev_err(mbox->dev, "Channel in use\n");
> +                       return NULL;
return ERR_PTR(-EBUSY)

> +               }
> +
> +               /*
> +                * Find the first free slot, then continue checking
> +                * to see if requested channel is in use
> +                */
> +               if (!chan && !chan_info)
> +                       chan = &mbox->chans[i];
> +       }
> +
> +       if (!chan) {
> +               dev_err(mbox->dev, "No free channels left\n");
> +               return NULL;
return ERR_PTR(-EBUSY)

> +       }
> +
> +       chan_info = devm_kzalloc(mbox->dev, sizeof(*chan_info), GFP_KERNEL);
> +       if (!chan_info)
> +               return NULL;
return ERR_PTR(-ENOMEM)

Thanks.


From al.stone at linaro.org  Thu Aug 13 08:43:46 2015
From: al.stone at linaro.org (Al Stone)
Date: Thu, 13 Aug 2015 09:43:46 -0600
Subject: [Linaro-acpi] [PATCH 1/5] ACPI: add in a bad_madt_entry()
 function to eventually replace the macro
In-Reply-To: <CAOZdJXVZomskfpvEjmDUiptW3SndJWvfKyzd9SwJp3dh7h3pig@mail.gmail.com>
References: <1438894770-31163-1-git-send-email-al.stone@linaro.org>
 <1438894770-31163-2-git-send-email-al.stone@linaro.org>
 <CAOZdJXVZomskfpvEjmDUiptW3SndJWvfKyzd9SwJp3dh7h3pig@mail.gmail.com>
Message-ID: <55CCBB32.6000103@linaro.org>

On 08/12/2015 04:35 PM, Timur Tabi wrote:
> On Thu, Aug 6, 2015 at 3:59 PM, Al Stone <al.stone at linaro.org> wrote:
>> +       while (ms->num_types != 0) {
>> +               if (ms->major_version == major &&
>> +                   ms->minor_version == minor &&
>> +                   ms->madt_version == madt->header.revision)
>> +                       break;
>> +               ms++;
>> +       }
>> +       if (!ms) {
> 
> Shouldn't this be
> 
>   if (!ms->num_types) {
> 
> instead?
> 

Argh.  Yes, it should.  It will always be false, otherwise.
Will fix for next version.  Thanks for catching that.

-- 
ciao,
al
-----------------------------------
Al Stone
Software Engineer
Linaro Enterprise Group
al.stone at linaro.org
-----------------------------------


From lina.iyer at linaro.org  Thu Aug 13 08:45:03 2015
From: lina.iyer at linaro.org (Lina Iyer)
Date: Thu, 13 Aug 2015 09:45:03 -0600
Subject: [PATCH 5/9] ARM: common: Introduce PM domains for CPUs/clusters
In-Reply-To: <20150813150154.GB13356@red-moon>
References: <1438731339-58317-1-git-send-email-lina.iyer@linaro.org>
 <1438731339-58317-6-git-send-email-lina.iyer@linaro.org>
 <CAL_JsqK67=DTtjZwwnonObLDjLbahkREfm0RvyXVV95bhR-d4Q@mail.gmail.com>
 <20150813150154.GB13356@red-moon>
Message-ID: <20150813154503.GO52339@linaro.org>

On Thu, Aug 13 2015 at 09:01 -0600, Lorenzo Pieralisi wrote:
>On Thu, Aug 06, 2015 at 04:14:51AM +0100, Rob Herring wrote:
>> On Tue, Aug 4, 2015 at 6:35 PM, Lina Iyer <lina.iyer at linaro.org> wrote:
>> > Define and add Generic PM domains (genpd) for ARM CPU clusters. Many new
>> > SoCs group CPUs as clusters. Clusters share common resources like GIC,
>> > power rail, caches, VFP, Coresight etc. When all CPUs in the cluster are
>> > idle, these shared resources may also be put in their idle state.
>> >
>> > The idle time between the last CPU entering idle and a CPU resuming
>> > execution is an opportunity for these shared resources to be powered
>> > down. Generic PM domain provides a framework for defining such power
>> > domains and attach devices to the domain. When the devices in the domain
>> > are idle at runtime, the domain would also be suspended and resumed
>> > before the first of the devices resume execution.
>> >
>> > We define a generic PM domain for each cluster and attach CPU devices in
>> > the cluster to that PM domain. The DT definitions for the SoC describe
>> > this relationship. Genpd callbacks for power_on and power_off can then
>> > be used to power up/down the shared resources for the domain.
>>
>> [...]
>>
>> > +ARM CPU Power domains
>> > +
>> > +The device tree allows describing of CPU power domains in a SoC. In ARM SoC,
>> > +CPUs may be grouped as clusters. A cluster may have CPUs, GIC, Coresight,
>> > +caches, VFP and power controller and other peripheral hardware. Generally,
>> > +when the CPUs in the cluster are idle/suspended, the shared resources may also
>> > +be suspended and resumed before any of the CPUs resume execution.
>> > +
>> > +CPUs are the defined as the PM domain consumers and there is a PM domain
>> > +provider for the CPUs. Bindings for generic PM domains (genpd) is described in
>> > +[1].
>> > +
>> > +The ARM CPU PM domain follows the same binding convention as any generic PM
>> > +domain. Additional binding properties are -
>> > +
>> > +- compatible:
>> > +       Usage: required
>> > +       Value type: <string>
>> > +       Definition: Must also have
>> > +                       "arm,pd"
>> > +               inorder to initialize the genpd provider as ARM CPU PM domain.
>>
>> A compatible string should represent a particular h/w block. If it is
>> generic, it should represent some sort of standard programming
>> interface (e.g, AHCI, EHCI, etc.). This doesn't seem to be either and
>> is rather just a mapping of what "driver" you want to use.
>>
>> I would expect that identifying a cpu's or cluster's power domain
>> would be done by a phandle between the cpu/cluster node and power
>> domain node. But I've not really looked at the power domain bindings
>> so who knows.
>
>I would expect the same, meaning that a cpu node, like any other device
>node would have a phandle pointing at the respective HW power domain.
>
CPUs have phandles to their domains. That is how the relationship
between the domain provider (power-controller) and the consumer (CPU) is
established.

>I do not really understand why we want a "generic" CPU power domain, what
>purpose does it serve ? Creating a collection of cpu devices that we
>can call "cluster" ?
>
Nope, not for calling a cluster, a cluster :)

This compatible is used to define a generic behavior of the CPU domain
controller (in addition to the platform specific behavior of the domain
power controller). The kernel activities for such power controller are
generally the same which otherwise would be repeated across platforms.
An analogy to this would be the "arm,idle-state" that defines the DT
node as something that also depicts a generic cpuidle C state.

Thanks,
Lina


From eric.auger at linaro.org  Thu Aug 13 08:46:07 2015
From: eric.auger at linaro.org (Eric Auger)
Date: Thu, 13 Aug 2015 17:46:07 +0200
Subject: [PATCH v2 10/15] KVM: arm64: add data structures to model ITS
 interrupt translation
In-Reply-To: <1436538111-4294-11-git-send-email-andre.przywara@arm.com>
References: <1436538111-4294-1-git-send-email-andre.przywara@arm.com>
 <1436538111-4294-11-git-send-email-andre.przywara@arm.com>
Message-ID: <55CCBBBF.1080407@linaro.org>


On 07/10/2015 04:21 PM, Andre Przywara wrote:
> The GICv3 Interrupt Translation Service (ITS) uses tables in memory
> to allow a sophisticated interrupt routing. It features device tables,
> an interrupt table per device and a table connecting "collections" to
> actual CPUs (aka. redistributors in the GICv3 lingo).
> Since the interrupt numbers for the LPIs are allocated quite sparsely
> and the range can be quite huge (8192 LPIs being the minimum), using
> bitmaps or arrays for storing information is a waste of memory.
> We use linked lists instead, which we iterate linearily. This works
> very well with the actual number of LPIs/MSIs in the guest being
> quite low. Should the number of LPIs exceed the number where iterating
> through lists seems acceptable, we can later revisit this and use more
> efficient data structures.
> 
> Signed-off-by: Andre Przywara <andre.przywara at arm.com>
> ---
>  include/kvm/arm_vgic.h  |  3 +++
>  virt/kvm/arm/its-emul.c | 48 ++++++++++++++++++++++++++++++++++++++++++++++++
>  2 files changed, 51 insertions(+)
> 
> diff --git a/include/kvm/arm_vgic.h b/include/kvm/arm_vgic.h
> index b432055..1648668 100644
> --- a/include/kvm/arm_vgic.h
> +++ b/include/kvm/arm_vgic.h
> @@ -25,6 +25,7 @@
>  #include <linux/spinlock.h>
>  #include <linux/types.h>
>  #include <kvm/iodev.h>
> +#include <linux/list.h>
>  
>  #define VGIC_NR_IRQS_LEGACY	256
>  #define VGIC_NR_SGIS		16
> @@ -162,6 +163,8 @@ struct vgic_its {
>  	u64			cbaser;
>  	int			creadr;
>  	int			cwriter;
> +	struct list_head	device_list;
> +	struct list_head	collection_list;
>  };
>  
>  struct vgic_dist {
> diff --git a/virt/kvm/arm/its-emul.c b/virt/kvm/arm/its-emul.c
> index b498f06..7f217fa 100644
> --- a/virt/kvm/arm/its-emul.c
> +++ b/virt/kvm/arm/its-emul.c
> @@ -21,6 +21,7 @@
>  #include <linux/kvm.h>
>  #include <linux/kvm_host.h>
>  #include <linux/interrupt.h>
> +#include <linux/list.h>
>  
>  #include <linux/irqchip/arm-gic-v3.h>
>  #include <kvm/arm_vgic.h>
> @@ -32,6 +33,25 @@
>  #include "vgic.h"
>  #include "its-emul.h"
>  
> +struct its_device {
> +	struct list_head dev_list;
> +	struct list_head itt;
> +	u32 device_id;
> +};
> +
> +struct its_collection {
> +	struct list_head coll_list;
> +	u32 collection_id;
> +	u32 target_addr;
> +};
> +
> +struct its_itte {
> +	struct list_head itte_list;
> +	struct its_collection *collection;
> +	u32 lpi;
> +	u32 event_id;
> +};
> +
>  #define BASER_BASE_ADDRESS(x) ((x) & 0xfffffffff000ULL)
>  
>  /* The distributor lock is held by the VGIC MMIO handler. */
> @@ -311,6 +331,9 @@ int vits_init(struct kvm *kvm)
>  
>  	spin_lock_init(&its->lock);
>  
> +	INIT_LIST_HEAD(&its->device_list);
> +	INIT_LIST_HEAD(&its->collection_list);
> +
>  	its->enabled = false;
>  
>  	return -ENXIO;
> @@ -320,11 +343,36 @@ void vits_destroy(struct kvm *kvm)
>  {
>  	struct vgic_dist *dist = &kvm->arch.vgic;
>  	struct vgic_its *its = &dist->its;
> +	struct its_device *dev;
> +	struct its_itte *itte;
> +	struct list_head *dev_cur, *dev_temp;
> +	struct list_head *cur, *temp;
>  
>  	if (!vgic_has_its(kvm))
>  		return;
>  
> +	if (!its->device_list.next)
Why not using list_empty? But I think I would simply remove this since
the empty case if handle below...
> +		return;
> +
> +	spin_lock(&its->lock);
> +	list_for_each_safe(dev_cur, dev_temp, &its->device_list) {
> +		dev = container_of(dev_cur, struct its_device, dev_list);
isn't the usage of list_for_each_entry_safe more synthetic here?
> +		list_for_each_safe(cur, temp, &dev->itt) {
> +			itte = (container_of(cur, struct its_itte, itte_list));
same

Eric
> +			list_del(cur);
> +			kfree(itte);
> +		}
> +		list_del(dev_cur);
> +		kfree(dev);
> +	}
> +
> +	list_for_each_safe(cur, temp, &its->collection_list) {
> +		list_del(cur);
> +		kfree(container_of(cur, struct its_collection, coll_list));
> +	}
> +
>  	kfree(dist->pendbaser);
>  
>  	its->enabled = false;
> +	spin_unlock(&its->lock);
>  }
> 



From balbi at ti.com  Thu Aug 13 08:47:36 2015
From: balbi at ti.com (Felipe Balbi)
Date: Thu, 13 Aug 2015 10:47:36 -0500
Subject: [PATCH-next 1/4] Revert "ARM: 7655/1: smp_twd: make
 twd_local_timer_of_register() no-op for nosmp"
In-Reply-To: <20150813153707.GF7576@n2100.arm.linux.org.uk>
References: <1439409416-32673-1-git-send-email-balbi@ti.com>
 <1439409416-32673-2-git-send-email-balbi@ti.com>
 <20150813153707.GF7576@n2100.arm.linux.org.uk>
Message-ID: <20150813154736.GI27560@saruman.tx.rr.com>

On Thu, Aug 13, 2015 at 04:37:07PM +0100, Russell King - ARM Linux wrote:
> On Wed, Aug 12, 2015 at 02:56:53PM -0500, Felipe Balbi wrote:
> > This reverts commit 904464b91eca8c665acea033489225af02eeb75a.
> > 
> > The problem pointed out by commit 904464b91eca ("ARM: 7655/1:
> > smp_twd: make twd_local_timer_of_register() no-op for nosmp")
> > doesn't exist anymore.
> > 
> > We can safely boot with nosmp and the warning won't show up.
> > 
> > The other side benefit of this patch is that TWD has a chance
> > to probe on single-core A9 systems such as AM437x which sport
> > TWD.
> 
> I don't remember all the details from Feb 2013 on why we made that
> change.  If this is proven safe, then I guess it's okay.

Do you want me to upload to your patch system and, perhaps, keep in
linux-next for v4.4 merge window ? (too late for v4.3 I guess).

-- 
balbi
-------------- next part --------------
A non-text attachment was scrubbed...
Name: signature.asc
Type: application/pgp-signature
Size: 819 bytes
Desc: Digital signature
URL: <http://lists.infradead.org/pipermail/linux-arm-kernel/attachments/20150813/67ef08f1/attachment-0001.sig>

From lorenzo.pieralisi at arm.com  Thu Aug 13 08:52:45 2015
From: lorenzo.pieralisi at arm.com (Lorenzo Pieralisi)
Date: Thu, 13 Aug 2015 16:52:45 +0100
Subject: [PATCH 5/9] ARM: common: Introduce PM domains for CPUs/clusters
In-Reply-To: <20150813154503.GO52339@linaro.org>
References: <1438731339-58317-1-git-send-email-lina.iyer@linaro.org>
 <1438731339-58317-6-git-send-email-lina.iyer@linaro.org>
 <CAL_JsqK67=DTtjZwwnonObLDjLbahkREfm0RvyXVV95bhR-d4Q@mail.gmail.com>
 <20150813150154.GB13356@red-moon>
 <20150813154503.GO52339@linaro.org>
Message-ID: <20150813155245.GD13833@red-moon>

On Thu, Aug 13, 2015 at 04:45:03PM +0100, Lina Iyer wrote:
> On Thu, Aug 13 2015 at 09:01 -0600, Lorenzo Pieralisi wrote:
> >On Thu, Aug 06, 2015 at 04:14:51AM +0100, Rob Herring wrote:
> >> On Tue, Aug 4, 2015 at 6:35 PM, Lina Iyer <lina.iyer at linaro.org> wrote:
> >> > Define and add Generic PM domains (genpd) for ARM CPU clusters. Many new
> >> > SoCs group CPUs as clusters. Clusters share common resources like GIC,
> >> > power rail, caches, VFP, Coresight etc. When all CPUs in the cluster are
> >> > idle, these shared resources may also be put in their idle state.
> >> >
> >> > The idle time between the last CPU entering idle and a CPU resuming
> >> > execution is an opportunity for these shared resources to be powered
> >> > down. Generic PM domain provides a framework for defining such power
> >> > domains and attach devices to the domain. When the devices in the domain
> >> > are idle at runtime, the domain would also be suspended and resumed
> >> > before the first of the devices resume execution.
> >> >
> >> > We define a generic PM domain for each cluster and attach CPU devices in
> >> > the cluster to that PM domain. The DT definitions for the SoC describe
> >> > this relationship. Genpd callbacks for power_on and power_off can then
> >> > be used to power up/down the shared resources for the domain.
> >>
> >> [...]
> >>
> >> > +ARM CPU Power domains
> >> > +
> >> > +The device tree allows describing of CPU power domains in a SoC. In ARM SoC,
> >> > +CPUs may be grouped as clusters. A cluster may have CPUs, GIC, Coresight,
> >> > +caches, VFP and power controller and other peripheral hardware. Generally,
> >> > +when the CPUs in the cluster are idle/suspended, the shared resources may also
> >> > +be suspended and resumed before any of the CPUs resume execution.
> >> > +
> >> > +CPUs are the defined as the PM domain consumers and there is a PM domain
> >> > +provider for the CPUs. Bindings for generic PM domains (genpd) is described in
> >> > +[1].
> >> > +
> >> > +The ARM CPU PM domain follows the same binding convention as any generic PM
> >> > +domain. Additional binding properties are -
> >> > +
> >> > +- compatible:
> >> > +       Usage: required
> >> > +       Value type: <string>
> >> > +       Definition: Must also have
> >> > +                       "arm,pd"
> >> > +               inorder to initialize the genpd provider as ARM CPU PM domain.
> >>
> >> A compatible string should represent a particular h/w block. If it is
> >> generic, it should represent some sort of standard programming
> >> interface (e.g, AHCI, EHCI, etc.). This doesn't seem to be either and
> >> is rather just a mapping of what "driver" you want to use.
> >>
> >> I would expect that identifying a cpu's or cluster's power domain
> >> would be done by a phandle between the cpu/cluster node and power
> >> domain node. But I've not really looked at the power domain bindings
> >> so who knows.
> >
> >I would expect the same, meaning that a cpu node, like any other device
> >node would have a phandle pointing at the respective HW power domain.
> >
> CPUs have phandles to their domains. That is how the relationship
> between the domain provider (power-controller) and the consumer (CPU) is
> established.
> 
> >I do not really understand why we want a "generic" CPU power domain, what
> >purpose does it serve ? Creating a collection of cpu devices that we
> >can call "cluster" ?
> >
> Nope, not for calling a cluster, a cluster :)
> 
> This compatible is used to define a generic behavior of the CPU domain
> controller (in addition to the platform specific behavior of the domain
> power controller). The kernel activities for such power controller are
> generally the same which otherwise would be repeated across platforms.

What activities ? CPU PM notifiers ?

Thanks,
Lorenzo


From lina.iyer at linaro.org  Thu Aug 13 09:00:38 2015
From: lina.iyer at linaro.org (Lina Iyer)
Date: Thu, 13 Aug 2015 10:00:38 -0600
Subject: [PATCH 9/9] ARM: smp: Add runtime PM support for CPU hotplug
In-Reply-To: <20150812234756.GO26614@codeaurora.org>
References: <1438731339-58317-1-git-send-email-lina.iyer@linaro.org>
 <1438731339-58317-10-git-send-email-lina.iyer@linaro.org>
 <20150812234756.GO26614@codeaurora.org>
Message-ID: <20150813160038.GP52339@linaro.org>

On Wed, Aug 12 2015 at 17:47 -0600, Stephen Boyd wrote:
>On 08/04, Lina Iyer wrote:
>> @@ -137,7 +138,6 @@ int __cpu_up(unsigned int cpu, struct task_struct *idle)
>>  		pr_err("CPU%u: failed to boot: %d\n", cpu, ret);
>>  	}
>>
>> -
>
>Remove noise please.
>
OK

>>  	memset(&secondary_data, 0, sizeof(secondary_data));
>>  	return ret;
>>  }
>> @@ -205,6 +205,9 @@ int __cpu_disable(void)
>>  	unsigned int cpu = smp_processor_id();
>>  	int ret;
>>
>> +	/* We dont need the CPU device anymore. */
>> +	pm_runtime_put_sync(get_cpu_device(cpu));
>
>This is all very generic. Any reason it can't be done at a higher
>level for all architectures? It certainly seems like
>cpu_startup_entry() could be modifed to do the
>pm_runtime_get_sync().
>
I am suspecting, when the concept of CPU PM domains are finalized, they
would probably move out of the ARM domain and into generic.  Will keep
that in mind.

>> +
>>  	ret = platform_cpu_disable(cpu);
>>  	if (ret)
>>  		return ret;
>> @@ -272,6 +275,13 @@ void __ref cpu_die(void)
>>  {
>>  	unsigned int cpu = smp_processor_id();
>>
>> +	/*
>> +	 * We dont need the CPU device anymore.
>> +	 * Lets do this before IRQs are disabled to allow
>> +	 * runtime PM to suspend the domain as well.
>> +	 */
>> +	pm_runtime_put_sync(get_cpu_device(cpu));
>
>The two put calls is confusing. __cpu_disable() is called on the
>CPU that's dying, and cpu_die() is called on the CPU that's doing
>the takedown.
>
Is that right? Looking at the code and the comments, I can only imagine
that they must be called on the CPU going down. If thats not the case,
then I need to fix this.

>That would be two decrements but only one increment
>in secondary_start_kernel()? How is this properly balanced?
>
I dont see __cpu_disable() ending up at cpu_die(). These seem two
different exit points. I will check again.

>> +
>>  	idle_task_exit();
>>
>>  	local_irq_disable();
>> @@ -401,6 +412,11 @@ asmlinkage void secondary_start_kernel(void)
>>  	local_irq_enable();
>>  	local_fiq_enable();
>>
>> +	/* We are running, enable runtime PM for the CPU. */
>> +	cpu_dev = get_cpu_device(cpu);
>> +	if (cpu_dev)
>> +		pm_runtime_get_sync(cpu_dev);
>
>Also, where would the dev->power.irq_safe flag be set if we
>aren't using the genpd DT stuff? It looks like we're going to
>start causing warnings on devices that don't have the DT magic.
>
Not necessarily. I have added _get and _put at points, when the
interrupts are still enabled. So there should not be a need for the CPU
devices to be IRQ safe. They will operate as regular devices. If they
are attached to a non-IRQ safe domain, they would effect power savings
on the domain.

>Please add a hotplug test with some device that isn't using this
>genpd code to catch problems. Also please turn on lockdep and RCU
>lockdep, touching the idle code like this
>
Good idea. Will add and test.

Thanks Stephen for the review.

Thanks,
Lina


From djkurtz at chromium.org  Thu Aug 13 09:16:16 2015
From: djkurtz at chromium.org (Daniel Kurtz)
Date: Fri, 14 Aug 2015 00:16:16 +0800
Subject: [PATCH] pinctrl: mediatek: Implement wake handler and suspend
 resume
In-Reply-To: <1439453936-8315-1-git-send-email-maoguang.meng@mediatek.com>
References: <1439453936-8315-1-git-send-email-maoguang.meng@mediatek.com>
Message-ID: <CAGS+omAVFUXg3WRyDrPsaWGmpTVwY5r5PZW8azT442+FLqMM8A@mail.gmail.com>

Hi Maoguang,

This patch looks pretty good now.  Just some small nitpicks below...

On Thu, Aug 13, 2015 at 4:18 PM,  <maoguang.meng at mediatek.com> wrote:
> From: Maoguang Meng <maoguang.meng at mediatek.com>
>
> This patch implement irq_set_wake to get who is wakeup source and
> setup on suspend resume.
>
> Signed-off-by: Maoguang Meng <maoguang.meng at mediatek.com>
>
> ---
> changes since v2:
> -modify irq_wake to handle irq wakeup source.
> -allocate two buffers separately.
> -fix some codestyle.
>
> Changes since v1:
> -implement irq_wake handler.
> ---
>  drivers/pinctrl/mediatek/pinctrl-mt8173.c     |  1 +
>  drivers/pinctrl/mediatek/pinctrl-mtk-common.c | 94 ++++++++++++++++++++++++++-
>  drivers/pinctrl/mediatek/pinctrl-mtk-common.h |  4 ++
>  3 files changed, 97 insertions(+), 2 deletions(-)
>
> diff --git a/drivers/pinctrl/mediatek/pinctrl-mt8173.c b/drivers/pinctrl/mediatek/pinctrl-mt8173.c
> index d0c811d..ad27184 100644
> --- a/drivers/pinctrl/mediatek/pinctrl-mt8173.c
> +++ b/drivers/pinctrl/mediatek/pinctrl-mt8173.c
> @@ -385,6 +385,7 @@ static struct platform_driver mtk_pinctrl_driver = {
>         .driver = {
>                 .name = "mediatek-mt8173-pinctrl",
>                 .of_match_table = mt8173_pctrl_match,
> +               .pm = &mtk_eint_pm_ops,
>         },
>  };
>
> diff --git a/drivers/pinctrl/mediatek/pinctrl-mtk-common.c b/drivers/pinctrl/mediatek/pinctrl-mtk-common.c
> index ad1ea16..7d4ba926 100644
> --- a/drivers/pinctrl/mediatek/pinctrl-mtk-common.c
> +++ b/drivers/pinctrl/mediatek/pinctrl-mtk-common.c
> @@ -33,6 +33,7 @@
>  #include <linux/mfd/syscon.h>
>  #include <linux/delay.h>
>  #include <linux/interrupt.h>
> +#include <linux/pm.h>
>  #include <dt-bindings/pinctrl/mt65xx.h>
>
>  #include "../core.h"
> @@ -1062,11 +1063,82 @@ static int mtk_eint_set_type(struct irq_data *d,
>         return 0;
>  }
>
> +static int mtk_eint_irq_set_wake(struct irq_data *d, unsigned int on)
> +{
> +       struct mtk_pinctrl *pctl = irq_data_get_irq_chip_data(d);
> +       int shift = d->hwirq & 0x1f;
> +       int reg = d->hwirq >> 5;
> +
> +       if (on)
> +               pctl->wake_mask[reg] |= BIT(shift);
> +       else
> +               pctl->wake_mask[reg] &= ~BIT(shift);
> +
> +       return 0;
> +}
> +
> +static void mtk_eint_chip_write_mask(const struct mtk_eint_offsets *chip,
> +               void __iomem *eint_reg_base, u32 *buf)
> +{
> +       int port;
> +       void __iomem *reg;
> +
> +       for (port = 0; port < chip->ports; port++) {
> +               reg = eint_reg_base + (port << 2);
> +               writel_relaxed(~buf[port], reg + chip->mask_set);
> +               writel_relaxed(buf[port], reg + chip->mask_clr);
> +       }
> +}
> +
> +static void mtk_eint_chip_read_mask(const struct mtk_eint_offsets *chip,
> +               void __iomem *eint_reg_base, u32 *buf)
> +{
> +       int port;
> +       void __iomem *reg;
> +
> +       for (port = 0; port < chip->ports; port++) {
> +               reg = eint_reg_base + chip->mask + (port << 2);
> +               buf[port] = ~readl_relaxed(reg);

You are storing the registers inverted.
This is a bit counter-intuititve, so please add a comment....

Better yet, perhaps just do the inversion when modifying wake_mask[]
in mtk_eint_irq_set_wake() (and add the comment there):

  /* Mask is 0 when irq is enabled, and 1 when disabled. */

> +       }
> +}
> +
> +static int mtk_eint_suspend(struct device *device)
> +{
> +       void __iomem *reg;
> +       struct mtk_pinctrl *pctl = dev_get_drvdata(device);
> +       const struct mtk_eint_offsets *eint_offsets =
> +                       &pctl->devdata->eint_offsets;
> +
> +       reg = pctl->eint_reg_base;
> +       mtk_eint_chip_read_mask(eint_offsets, reg, pctl->cur_mask);
> +       mtk_eint_chip_write_mask(eint_offsets, reg, pctl->wake_mask);
> +
> +       return 0;
> +}
> +
> +static int mtk_eint_resume(struct device *device)
> +{
> +       struct platform_device *pdev = to_platform_device(device);
> +       struct mtk_pinctrl *pctl = platform_get_drvdata(pdev);

Aren't these two lines just:
  struct mtk_pinctrl *pctl = dev_get_drvdata(device);

> +       const struct mtk_eint_offsets *eint_offsets =
> +                       &pctl->devdata->eint_offsets;
> +
> +       mtk_eint_chip_write_mask(eint_offsets,
> +                       pctl->eint_reg_base, pctl->cur_mask);
> +
> +       return 0;
> +}
> +
> +const struct dev_pm_ops mtk_eint_pm_ops = {
> +       .suspend = mtk_eint_suspend,
> +       .resume = mtk_eint_resume,
> +};
> +
>  static void mtk_eint_ack(struct irq_data *d)
>  {
>         struct mtk_pinctrl *pctl = irq_data_get_irq_chip_data(d);
>         const struct mtk_eint_offsets *eint_offsets =
> -               &pctl->devdata->eint_offsets;
> +                       &pctl->devdata->eint_offsets;

Unrelated change; it is often preferred to fix something like this in
a separate patch.

>         u32 mask = BIT(d->hwirq & 0x1f);
>         void __iomem *reg = mtk_eint_get_offset(pctl, d->hwirq,
>                         eint_offsets->ack);
> @@ -1076,10 +1148,12 @@ static void mtk_eint_ack(struct irq_data *d)
>
>  static struct irq_chip mtk_pinctrl_irq_chip = {
>         .name = "mt-eint",
> +       .irq_disable = mtk_eint_mask,
>         .irq_mask = mtk_eint_mask,
>         .irq_unmask = mtk_eint_unmask,
>         .irq_ack = mtk_eint_ack,
>         .irq_set_type = mtk_eint_set_type,
> +       .irq_set_wake = mtk_eint_irq_set_wake,
>         .irq_request_resources = mtk_pinctrl_irq_request_resources,
>         .irq_release_resources = mtk_pinctrl_irq_release_resources,
>  };
> @@ -1217,7 +1291,7 @@ int mtk_pctrl_init(struct platform_device *pdev,
>         struct device_node *np = pdev->dev.of_node, *node;
>         struct property *prop;
>         struct resource *res;
> -       int i, ret, irq;
> +       int i, ret, irq, ports_buf;
>
>         pctl = devm_kzalloc(&pdev->dev, sizeof(*pctl), GFP_KERNEL);
>         if (!pctl)
> @@ -1319,6 +1393,22 @@ int mtk_pctrl_init(struct platform_device *pdev,
>                 goto chip_error;
>         }
>
> +       ports_buf = ALIGN(pctl->devdata->eint_offsets.ports,
> +                       sizeof(long)/sizeof(u32));

Why this ALIGN?
Shouldn't we allocate eint_offsets.ports * sizeof(u32), like this:

  pctl->wake_mask = devm_kcalloc(&pdev->dev, pctl->devdata->eint_offsets.ports,
                  sizeof(*pctl->wake_mask), GFP_KERNEL);

Thanks,
-Dan

> +       pctl->wake_mask = devm_kcalloc(&pdev->dev, ports_buf,
> +                                       sizeof(*pctl->wake_mask), GFP_KERNEL);
> +       if (!pctl->wake_mask) {
> +               ret = -ENOMEM;
> +               goto chip_error;
> +       }
> +
> +       pctl->cur_mask = devm_kcalloc(&pdev->dev, ports_buf,
> +                                       sizeof(*pctl->cur_mask), GFP_KERNEL);
> +       if (!pctl->cur_mask) {
> +               ret = -ENOMEM;
> +               goto chip_error;
> +       }
> +
>         pctl->eint_dual_edges = devm_kcalloc(&pdev->dev, pctl->devdata->ap_num,
>                                              sizeof(int), GFP_KERNEL);
>         if (!pctl->eint_dual_edges) {
> diff --git a/drivers/pinctrl/mediatek/pinctrl-mtk-common.h b/drivers/pinctrl/mediatek/pinctrl-mtk-common.h
> index 30213e5..f1be8e8 100644
> --- a/drivers/pinctrl/mediatek/pinctrl-mtk-common.h
> +++ b/drivers/pinctrl/mediatek/pinctrl-mtk-common.h
> @@ -266,6 +266,8 @@ struct mtk_pinctrl {
>         void __iomem            *eint_reg_base;
>         struct irq_domain       *domain;
>         int                     *eint_dual_edges;
> +       u32 *wake_mask;
> +       u32 *cur_mask;
>  };
>
>  int mtk_pctrl_init(struct platform_device *pdev,
> @@ -281,4 +283,6 @@ int mtk_pconf_spec_set_ies_smt_range(struct regmap *regmap,
>                 const struct mtk_pin_ies_smt_set *ies_smt_infos, unsigned int info_num,
>                 unsigned int pin, unsigned char align, int value);
>
> +extern const struct dev_pm_ops mtk_eint_pm_ops;
> +
>  #endif /* __PINCTRL_MTK_COMMON_H */
> --
> 1.8.1.1.dirty
>
> --
> To unsubscribe from this list: send the line "unsubscribe linux-kernel" in
> the body of a message to majordomo at vger.kernel.org
> More majordomo info at  http://vger.kernel.org/majordomo-info.html
> Please read the FAQ at  http://www.tux.org/lkml/


From robert.richter at caviumnetworks.com  Thu Aug 13 09:17:41 2015
From: robert.richter at caviumnetworks.com (Robert Richter)
Date: Thu, 13 Aug 2015 18:17:41 +0200
Subject: [PATCH v2 3/5] irqchip, gicv3: Workaround for Cavium ThunderX
 erratum 23154
In-Reply-To: <55CCB393.1040909@arm.com>
References: <1439477277-6157-1-git-send-email-rric@kernel.org>
 <1439477277-6157-4-git-send-email-rric@kernel.org>
 <55CCB393.1040909@arm.com>
Message-ID: <20150813161741.GO1820@rric.localhost>

Marc,

thanks for your quick review.

On 13.08.15 16:11:15, Marc Zyngier wrote:
> On 13/08/15 15:47, Robert Richter wrote:
> > From: Robert Richter <rrichter at cavium.com>

> >  static const struct gic_capabilities gicv3_errata[] = {
> >  	{
> > +		.desc		= "GIC: Cavium erratum 23154",
> > +		.iidr		= 0xa100034c,	/* ThunderX pass 1.x */
> > +		.iidr_mask	= 0xffff0fff,
> > +		.init		= gicv3_enable_cavium_thunderx,
> > +	},
> 
> I'm even more puzzled. You're working around a CPU bug based on the ITS
> ID registers? Or have you swapped the detection methods for the two errata?

:/ Right, I mixed this up... Must have starred on this for too long.
Will fix that.

Wrt midr: Originally this was written to support iidr. I wanted to
keep the version check in the driver of the hw, an implementation
outside of drivers/irqchip looked not appropriate here as it would
rely then on arch arm64 only. This is the main reason. Apart from
that, I think an implmentation based on struct arm64_cpu_capabilities,
etc. would require much rework compared to my current easy
implementation, e.g:

 * binding flags to callbacks and actually run them,

 * handing over private driver data (base addr for iidr detection) to
   a capabilty's match function.

Overall this looked bloated. Now, that the MIDR also needs to be
checked, it looked better to me to keep the gic hw detection at a
single location in the driver. This also allows us to check a
combination of midr and iidr values.

I hope this sounds reasonable?

-Robert


From lina.iyer at linaro.org  Thu Aug 13 09:22:05 2015
From: lina.iyer at linaro.org (Lina Iyer)
Date: Thu, 13 Aug 2015 10:22:05 -0600
Subject: [PATCH 5/9] ARM: common: Introduce PM domains for CPUs/clusters
In-Reply-To: <20150813155245.GD13833@red-moon>
References: <1438731339-58317-1-git-send-email-lina.iyer@linaro.org>
 <1438731339-58317-6-git-send-email-lina.iyer@linaro.org>
 <CAL_JsqK67=DTtjZwwnonObLDjLbahkREfm0RvyXVV95bhR-d4Q@mail.gmail.com>
 <20150813150154.GB13356@red-moon>
 <20150813154503.GO52339@linaro.org>
 <20150813155245.GD13833@red-moon>
Message-ID: <20150813162205.GQ52339@linaro.org>

On Thu, Aug 13 2015 at 09:52 -0600, Lorenzo Pieralisi wrote:
>On Thu, Aug 13, 2015 at 04:45:03PM +0100, Lina Iyer wrote:
>> On Thu, Aug 13 2015 at 09:01 -0600, Lorenzo Pieralisi wrote:
>> >On Thu, Aug 06, 2015 at 04:14:51AM +0100, Rob Herring wrote:
>> >> On Tue, Aug 4, 2015 at 6:35 PM, Lina Iyer <lina.iyer at linaro.org> wrote:
>> >> > Define and add Generic PM domains (genpd) for ARM CPU clusters. Many new
>> >> > SoCs group CPUs as clusters. Clusters share common resources like GIC,
>> >> > power rail, caches, VFP, Coresight etc. When all CPUs in the cluster are
>> >> > idle, these shared resources may also be put in their idle state.
>> >> >
>> >> > The idle time between the last CPU entering idle and a CPU resuming
>> >> > execution is an opportunity for these shared resources to be powered
>> >> > down. Generic PM domain provides a framework for defining such power
>> >> > domains and attach devices to the domain. When the devices in the domain
>> >> > are idle at runtime, the domain would also be suspended and resumed
>> >> > before the first of the devices resume execution.
>> >> >
>> >> > We define a generic PM domain for each cluster and attach CPU devices in
>> >> > the cluster to that PM domain. The DT definitions for the SoC describe
>> >> > this relationship. Genpd callbacks for power_on and power_off can then
>> >> > be used to power up/down the shared resources for the domain.
>> >>
>> >> [...]
>> >>
>> >> > +ARM CPU Power domains
>> >> > +
>> >> > +The device tree allows describing of CPU power domains in a SoC. In ARM SoC,
>> >> > +CPUs may be grouped as clusters. A cluster may have CPUs, GIC, Coresight,
>> >> > +caches, VFP and power controller and other peripheral hardware. Generally,
>> >> > +when the CPUs in the cluster are idle/suspended, the shared resources may also
>> >> > +be suspended and resumed before any of the CPUs resume execution.
>> >> > +
>> >> > +CPUs are the defined as the PM domain consumers and there is a PM domain
>> >> > +provider for the CPUs. Bindings for generic PM domains (genpd) is described in
>> >> > +[1].
>> >> > +
>> >> > +The ARM CPU PM domain follows the same binding convention as any generic PM
>> >> > +domain. Additional binding properties are -
>> >> > +
>> >> > +- compatible:
>> >> > +       Usage: required
>> >> > +       Value type: <string>
>> >> > +       Definition: Must also have
>> >> > +                       "arm,pd"
>> >> > +               inorder to initialize the genpd provider as ARM CPU PM domain.
>> >>
>> >> A compatible string should represent a particular h/w block. If it is
>> >> generic, it should represent some sort of standard programming
>> >> interface (e.g, AHCI, EHCI, etc.). This doesn't seem to be either and
>> >> is rather just a mapping of what "driver" you want to use.
>> >>
>> >> I would expect that identifying a cpu's or cluster's power domain
>> >> would be done by a phandle between the cpu/cluster node and power
>> >> domain node. But I've not really looked at the power domain bindings
>> >> so who knows.
>> >
>> >I would expect the same, meaning that a cpu node, like any other device
>> >node would have a phandle pointing at the respective HW power domain.
>> >
>> CPUs have phandles to their domains. That is how the relationship
>> between the domain provider (power-controller) and the consumer (CPU) is
>> established.
>>
>> >I do not really understand why we want a "generic" CPU power domain, what
>> >purpose does it serve ? Creating a collection of cpu devices that we
>> >can call "cluster" ?
>> >
>> Nope, not for calling a cluster, a cluster :)
>>
>> This compatible is used to define a generic behavior of the CPU domain
>> controller (in addition to the platform specific behavior of the domain
>> power controller). The kernel activities for such power controller are
>> generally the same which otherwise would be repeated across platforms.
>
>What activities ? CPU PM notifiers ?
>
Yes, for now. May be someday we can get rid of these notifiers and
directly invoke subsystems from these callbacks directly. Kevin proposed
this idea. With little exploration that I have done, I dont have a good
way to do that yet.

I am imagining here (only imagining at this time) that I could tie this
with last man down for cluster idle state determination and call into
cpuidle-PSCI to help compose the composite state id.

Thanks,
Lina


From b08248 at gmail.com  Thu Aug 13 09:23:11 2015
From: b08248 at gmail.com (Stuart Yoder)
Date: Thu, 13 Aug 2015 11:23:11 -0500
Subject: [PATCH v3 1/2] Documentation: DT: FTM: add FTM0 be used as alarm
 timer
In-Reply-To: <1439352061-14656-1-git-send-email-dongsheng.wang@freescale.com>
References: <1439352061-14656-1-git-send-email-dongsheng.wang@freescale.com>
Message-ID: <CALRxmdDGgYh+_cOPB43gyuZwu_zo+wE0qHh8nWJTjiQN__hZ3w@mail.gmail.com>

On Tue, Aug 11, 2015 at 11:01 PM, Dongsheng Wang
<dongsheng.wang at freescale.com> wrote:
> From: Wang Dongsheng <dongsheng.wang at freescale.com>
>
> In freescale layerscape platform there is only FTM0 can be used as
> alarm timer to wake up system. So add FTM0 description for devicetree
> document.

Suggestion:

In the Freescale Layerscape platform a flextimer module can be used
as an alarm timer to wake up the system.  Define a binding for this
alarm.

> Signed-off-by: Wang Dongsheng <dongsheng.wang at freescale.com>
> ---
> V3:
> Include this patch in V3.
>
> diff --git a/Documentation/devicetree/bindings/timer/fsl,ftm-timer.txt b/Documentation/devicetree/bindings/timer/fsl,ftm-timer.txt
> index aa8c402..380a0b3d 100644
> --- a/Documentation/devicetree/bindings/timer/fsl,ftm-timer.txt
> +++ b/Documentation/devicetree/bindings/timer/fsl,ftm-timer.txt
> @@ -1,5 +1,7 @@
>  Freescale FlexTimer Module (FTM) Timer
>
> +* Default FTM Timer
> +
>  Required properties:
>
>  - compatible : should be "fsl,ftm-timer"
> @@ -29,3 +31,26 @@ ftm: ftm at 400b8000 {
>                 <&clks VF610_CLK_FTM3_EXT_FIX_EN>;
>         big-endian;
>  };
> +
> +* FTM Alarm Timer
> +  The default FTM device contains eight FlexTimer modules. FlexTimer1 is in
> +  on-domain(power is not switched off in deep sleep mode). Other seven FlexTimer
> +  modules(flextimer2/3/4/5/6/7/8) are in off-domain (power is switched off in
> +  deep sleep mode).

Suggestion:

  This binding describes a Flextimer (FTM) instance that can be used as an alarm
  to wake up a system in deep sleep.  The flextimer module with alarm
  support is in a power domain that remains awake when the SoC is in
  deep sleep mode.

(don't use flextimer1 in the binding...for all you know in the next SoC it
will be flextimer7 that has this capability)

> +Required properties:
> +
> +- compatible : should be "fsl,ftm-alarm".
> +- reg : should contain base address and length of FTM timer 0 register.

  "should contain the address and size of the FTM alarm module registers"

(don't use the number 0)

> +- interrupts : Should contain FTM 0 interrupt.

   "describes the FTM alarm interrupt"

> +- big-endian: One boolean property, the big endian mode will be in use if it is
> +  present, or the little endian mode will be in use for all the device registers.
> +
> +Example:
> +ftm0: ftm0 at 29d0000 {
> +       compatible = "fsl,ftm-alarm";
> +       reg = <0x0 0x29d0000 0x0 0x10000>;
> +       interrupts = <GIC_SPI 118 IRQ_TYPE_LEVEL_HIGH>;
> +       big-endian;
> +       status = "disabled";
> +};

Drop the number 0 from the names in your example.

Thanks,
Stuart


From torvalds at linux-foundation.org  Thu Aug 13 09:28:35 2015
From: torvalds at linux-foundation.org (Linus Torvalds)
Date: Thu, 13 Aug 2015 09:28:35 -0700
Subject: enabling libgcc for 64-bit divisions, was Re: PROBLEM: XFS on ARM
 corruption 'Structure needs cl
In-Reply-To: <20150813061109.29409.qmail@ns.horizon.com>
References: <20150813061109.29409.qmail@ns.horizon.com>
Message-ID: <CA+55aFwgaq3KkeXGQWxmVHsNVwJUWK3WssJ5_ADpQG4zTXjWPQ@mail.gmail.com>

On Wed, Aug 12, 2015 at 11:11 PM, George Spelvin <linux at horizon.com> wrote:
>
> Agreed.  But some x86 code I'm working on now, I have a *lot* of
> asm("divl") calls because even do_div isn't great for 64/32->32 division.

Yeah.

I'm not convinced that "64/32->32" is all that generic, though.  If
the dividend in 64-bit, there's no fundamental type-based guarantee
that things will fit.

So your case is rather special, and depends (intimately) on knowing
the actual ranges and how they interact.

That's not a generic situation like "do_div()".

                  Linus


From abrestic at chromium.org  Thu Aug 13 09:40:07 2015
From: abrestic at chromium.org (Andrew Bresticker)
Date: Thu, 13 Aug 2015 09:40:07 -0700
Subject: [PATCH 2/2] clk: Convert __clk_get_name(hw->clk) to
 clk_hw_get_name(hw)
In-Reply-To: <1439421161-17868-2-git-send-email-sboyd@codeaurora.org>
References: <1439421161-17868-1-git-send-email-sboyd@codeaurora.org>
 <1439421161-17868-2-git-send-email-sboyd@codeaurora.org>
Message-ID: <CAL1qeaE-UJD3CBx=6feF=Hu4=gu5AtQiWwQAZmbg+6qYLhOy2Q@mail.gmail.com>

On Wed, Aug 12, 2015 at 4:12 PM, Stephen Boyd <sboyd at codeaurora.org> wrote:
> Use the provider based method to get a clock's name so that we
> can get rid of the clk member in struct clk_hw one day. Mostly
> converted with the following coccinelle script.
>
> @@
> struct clk_hw *E;
> @@
>
> -__clk_get_name(E->clk)
> +clk_hw_get_name(E)
>
> Cc: Heiko Stuebner <heiko at sntech.de>
> Cc: Sylwester Nawrocki <s.nawrocki at samsung.com>
> Cc: Tomasz Figa <tomasz.figa at gmail.com>
> Cc: Peter De Schrijver <pdeschrijver at nvidia.com>
> Cc: Prashant Gaikwad <pgaikwad at nvidia.com>
> Cc: Stephen Warren <swarren at wwwdotorg.org>
> Cc: Thierry Reding <thierry.reding at gmail.com>
> Cc: Alexandre Courbot <gnurou at gmail.com>
> Cc: Tero Kristo <t-kristo at ti.com>
> Cc: Ulf Hansson <ulf.hansson at linaro.org>
> Cc: Sebastian Hesselbarth <sebastian.hesselbarth at gmail.com>
> Cc: Andrew Bresticker <abrestic at chromium.org>
> Cc: Ezequiel Garcia <ezequiel.garcia at imgtec.com>
> Cc: Ralf Baechle <ralf at linux-mips.org>
> Cc: Kevin Cernekee <cernekee at chromium.org>
> Cc: Geert Uytterhoeven <geert+renesas at glider.be>
> Cc: Ulrich Hecht <ulrich.hecht+renesas at gmail.com>
> Cc: linux-arm-kernel at lists.infradead.org
> Cc: linux-rockchip at lists.infradead.org
> Cc: linux-samsung-soc at vger.kernel.org
> Cc: linux-tegra at vger.kernel.org
> Cc: linux-omap at vger.kernel.org
> Signed-off-by: Stephen Boyd <sboyd at codeaurora.org>

>  drivers/clk/pistachio/clk-pll.c      |  4 ++--

For Pistachio,

Acked-by: Andrew Bresticker <abrestic at chromium.org>


From marc.zyngier at arm.com  Thu Aug 13 09:54:41 2015
From: marc.zyngier at arm.com (Marc Zyngier)
Date: Thu, 13 Aug 2015 17:54:41 +0100
Subject: [PATCH v2 3/5] irqchip, gicv3: Workaround for Cavium ThunderX
 erratum 23154
In-Reply-To: <20150813161741.GO1820@rric.localhost>
References: <1439477277-6157-1-git-send-email-rric@kernel.org>
 <1439477277-6157-4-git-send-email-rric@kernel.org> <55CCB393.1040909@arm.com>
 <20150813161741.GO1820@rric.localhost>
Message-ID: <55CCCBD1.2090304@arm.com>

On 13/08/15 17:17, Robert Richter wrote:
> Marc,
> 
> thanks for your quick review.
> 
> On 13.08.15 16:11:15, Marc Zyngier wrote:
>> On 13/08/15 15:47, Robert Richter wrote:
>>> From: Robert Richter <rrichter at cavium.com>
> 
>>>  static const struct gic_capabilities gicv3_errata[] = {
>>>  	{
>>> +		.desc		= "GIC: Cavium erratum 23154",
>>> +		.iidr		= 0xa100034c,	/* ThunderX pass 1.x */
>>> +		.iidr_mask	= 0xffff0fff,
>>> +		.init		= gicv3_enable_cavium_thunderx,
>>> +	},
>>
>> I'm even more puzzled. You're working around a CPU bug based on the ITS
>> ID registers? Or have you swapped the detection methods for the two errata?
> 
> :/ Right, I mixed this up... Must have starred on this for too long.
> Will fix that.
> 
> Wrt midr: Originally this was written to support iidr. I wanted to
> keep the version check in the driver of the hw, an implementation
> outside of drivers/irqchip looked not appropriate here as it would
> rely then on arch arm64 only. This is the main reason. Apart from
> that, I think an implmentation based on struct arm64_cpu_capabilities,
> etc. would require much rework compared to my current easy
> implementation, e.g:
> 
>  * binding flags to callbacks and actually run them,
> 
>  * handing over private driver data (base addr for iidr detection) to
>    a capabilty's match function.
> 
> Overall this looked bloated. Now, that the MIDR also needs to be
> checked, it looked better to me to keep the gic hw detection at a
> single location in the driver. This also allows us to check a
> combination of midr and iidr values.
> 
> I hope this sounds reasonable?

+Will.

The point I was trying to make is that a CPU interface bug is a CPU bug,
and that it feels quite weird weird to have the detection in the GIC.
Will, what do you think?

Also, I don't really buy the combined MIDR/GITS_IIDR detection. These
are two *very* distinct pieces of HW that are not even directly
connected (the redistributors are in between).

I wouldn't mind having something like:

struct gic_capabilities {
	const char *desc;
	void (*init)(void *data);
	u32 iidr;
	u32 iidr_mask;
	int feature;
};

where "feature" is a one of things declared in cpufeature.h, and that
would condition the capability (I love the name!) if that really
happens. I don't think we're there yet.

As for the complexity of implementation, testing a flag in the probe
function and tingling a static key is not really a big deal.

Thanks,

	M.
-- 
Jazz is not dead. It just smells funny...


From robert.richter at caviumnetworks.com  Thu Aug 13 10:11:50 2015
From: robert.richter at caviumnetworks.com (Robert Richter)
Date: Thu, 13 Aug 2015 19:11:50 +0200
Subject: [PATCH v2 3/5] irqchip, gicv3: Workaround for Cavium ThunderX
 erratum 23154
In-Reply-To: <55CCCBD1.2090304@arm.com>
References: <1439477277-6157-1-git-send-email-rric@kernel.org>
 <1439477277-6157-4-git-send-email-rric@kernel.org>
 <55CCB393.1040909@arm.com> <20150813161741.GO1820@rric.localhost>
 <55CCCBD1.2090304@arm.com>
Message-ID: <20150813171150.GB4914@rric.localhost>

On 13.08.15 17:54:41, Marc Zyngier wrote:
> On 13/08/15 17:17, Robert Richter wrote:
> > Marc,
> > 
> > thanks for your quick review.
> > 
> > On 13.08.15 16:11:15, Marc Zyngier wrote:
> >> On 13/08/15 15:47, Robert Richter wrote:
> >>> From: Robert Richter <rrichter at cavium.com>
> > 
> >>>  static const struct gic_capabilities gicv3_errata[] = {
> >>>  	{
> >>> +		.desc		= "GIC: Cavium erratum 23154",
> >>> +		.iidr		= 0xa100034c,	/* ThunderX pass 1.x */
> >>> +		.iidr_mask	= 0xffff0fff,
> >>> +		.init		= gicv3_enable_cavium_thunderx,
> >>> +	},
> >>
> >> I'm even more puzzled. You're working around a CPU bug based on the ITS
> >> ID registers? Or have you swapped the detection methods for the two errata?
> > 
> > :/ Right, I mixed this up... Must have starred on this for too long.
> > Will fix that.
> > 
> > Wrt midr: Originally this was written to support iidr. I wanted to
> > keep the version check in the driver of the hw, an implementation
> > outside of drivers/irqchip looked not appropriate here as it would
> > rely then on arch arm64 only. This is the main reason. Apart from
> > that, I think an implmentation based on struct arm64_cpu_capabilities,
> > etc. would require much rework compared to my current easy
> > implementation, e.g:
> > 
> >  * binding flags to callbacks and actually run them,
> > 
> >  * handing over private driver data (base addr for iidr detection) to
> >    a capabilty's match function.
> > 
> > Overall this looked bloated. Now, that the MIDR also needs to be
> > checked, it looked better to me to keep the gic hw detection at a
> > single location in the driver. This also allows us to check a
> > combination of midr and iidr values.
> > 
> > I hope this sounds reasonable?
> 
> +Will.
> 
> The point I was trying to make is that a CPU interface bug is a CPU bug,
> and that it feels quite weird weird to have the detection in the GIC.
> Will, what do you think?
> 
> Also, I don't really buy the combined MIDR/GITS_IIDR detection. These
> are two *very* distinct pieces of HW that are not even directly
> connected (the redistributors are in between).
> 
> I wouldn't mind having something like:
> 
> struct gic_capabilities {
> 	const char *desc;
> 	void (*init)(void *data);
> 	u32 iidr;
> 	u32 iidr_mask;
> 	int feature;
> };

Yes, once we leave this in the driver it is much easier. But why do
the read_cpuid_id() in cpu_errata.c and not in his file? The
value/mask pairs will be then on complete different locations for the
same kind of hw depending on midr/iidr. And the only reason for using
midr is not, that it's a cpu, but just that it needs to be applied to
guests too and this is the only way to find out the real hw, otherwise
we would use iidr.  Apart from the fact that this looks inconsistent
having one errata^Mfeature flag for one errata, but not for the
other. And only because one is useing midr for hw detection and the
other iidr.

> where "feature" is a one of things declared in cpufeature.h, and that
> would condition the capability (I love the name!) if that really
> happens. I don't think we're there yet.

Yeah, some "Newspeak". :)

-Robert

> 
> As for the complexity of implementation, testing a flag in the probe
> function and tingling a static key is not really a big deal.
> 
> Thanks,
> 
> 	M.
> -- 
> Jazz is not dead. It just smells funny...


From manabian at gmail.com  Thu Aug 13 10:19:40 2015
From: manabian at gmail.com (Joachim Eastwood)
Date: Thu, 13 Aug 2015 19:19:40 +0200
Subject: [PATCH v5] mtd: spi-nor: add driver for NXP SPI Flash Interface
 (SPIFI)
Message-ID: <1439486380-17720-1-git-send-email-manabian@gmail.com>

Add SPI-NOR driver for the SPI Flash Interface (SPIFI)
controller that is found on newer NXP MCU devices.

The controller supports serial SPI Flash devices with 1-, 2-
and 4-bit width in either SPI mode 0 or 3. The controller
can operate in either command or memory mode. In memory mode
the Flash is exposed as normal memory and can be directly
accessed by the CPU.

Signed-off-by: Joachim Eastwood <manabian at gmail.com>
Reviewed-by: Ezequiel Garcia <ezequiel at vanguardiasur.com.ar>
---
Hi Brian,

I skipped the cover letter since you already applied the 2nd
of patch of the original set and using a cover letter for
just one patch seemed a bit useless. Cover letter for v4 can
be found here: http://marc.info/?l=devicetree&m=143647330431908&w=2

This version address all comments from Brian Norris except
for two things noted below.

If the line below is removed the kernel opses on jffs2 mount.
spifi->mtd.priv  = &spifi->nor;
It seems like spi-nor.c doesn't setup this field. fsl-quadspi
also assigns this field, btw.

The read/wait ordering in nxp_spifi_read_reg is correct. I
don't really have a good explaination for the ordering. The
user manual doesn't document the SPIFI in detail, but the
offcial NXP spifilib has the same ordering.

Changes since v4:
 - spifi: always autodetect SPI Flash
 - s/spi/SPI on dev_* output
 - add parentheses to SPIFI_CMD_DATALEN macro
 - rebase on mtd-master

Changes since v3:
 - fix bug in write function
 - rebase on 4.2-rc1

Changes since v2:
 - default to auto detection unless chip is specified
 - update doc with reference to jedec,spi-nor.txt

Test on the following boards.
Hitex board boots on SPIFI Flash with JFFS2.

Hitex LPC4350 Eval board:
[    2.093956] nxp-spifi 40003000.spifi: s25sl064p (8192 Kbytes)

Embedded Artists' LPC4357 Developer's Kit:
[    3.051627] nxp-spifi 40003000.spifi: s25fl016k (2048 Kbytes)

Both s25fl016k and s25sl064p support dual/quad mode, but this
is not flagged in spi-nor.c. I have sent a patch for s25fl016k
and will send a patch s25sl064p please apply when you get them.

 drivers/mtd/spi-nor/Kconfig     |  11 +
 drivers/mtd/spi-nor/Makefile    |   1 +
 drivers/mtd/spi-nor/nxp-spifi.c | 482 ++++++++++++++++++++++++++++++++++++++++
 3 files changed, 494 insertions(+)
 create mode 100644 drivers/mtd/spi-nor/nxp-spifi.c

diff --git a/drivers/mtd/spi-nor/Kconfig b/drivers/mtd/spi-nor/Kconfig
index 64a4f0edabc7..407142e411fa 100644
--- a/drivers/mtd/spi-nor/Kconfig
+++ b/drivers/mtd/spi-nor/Kconfig
@@ -28,4 +28,15 @@ config SPI_FSL_QUADSPI
 	  This enables support for the Quad SPI controller in master mode.
 	  We only connect the NOR to this controller now.
 
+config SPI_NXP_SPIFI
+	tristate "NXP SPI Flash Interface (SPIFI)"
+	depends on OF && (ARCH_LPC18XX || COMPILE_TEST)
+	depends on HAS_IOMEM
+	help
+	  Enable support for the NXP LPC SPI Flash Interface controller.
+
+	  SPIFI is a specialized controller for connecting serial SPI
+	  Flash. Enable this option if you have a device with a SPIFI
+	  controller and want to access the Flash as a mtd device.
+
 endif # MTD_SPI_NOR
diff --git a/drivers/mtd/spi-nor/Makefile b/drivers/mtd/spi-nor/Makefile
index 6a7ce1462247..e53333ef8582 100644
--- a/drivers/mtd/spi-nor/Makefile
+++ b/drivers/mtd/spi-nor/Makefile
@@ -1,2 +1,3 @@
 obj-$(CONFIG_MTD_SPI_NOR)	+= spi-nor.o
 obj-$(CONFIG_SPI_FSL_QUADSPI)	+= fsl-quadspi.o
+obj-$(CONFIG_SPI_NXP_SPIFI)	+= nxp-spifi.o
diff --git a/drivers/mtd/spi-nor/nxp-spifi.c b/drivers/mtd/spi-nor/nxp-spifi.c
new file mode 100644
index 000000000000..9ad1dd0896c0
--- /dev/null
+++ b/drivers/mtd/spi-nor/nxp-spifi.c
@@ -0,0 +1,482 @@
+/*
+ * SPI-NOR driver for NXP SPI Flash Interface (SPIFI)
+ *
+ * Copyright (C) 2015 Joachim Eastwood <manabian at gmail.com>
+ *
+ * Based on Freescale QuadSPI driver:
+ * Copyright (C) 2013 Freescale Semiconductor, Inc.
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License version 2 as
+ * published by the Free Software Foundation.
+ *
+ */
+
+#include <linux/clk.h>
+#include <linux/err.h>
+#include <linux/io.h>
+#include <linux/iopoll.h>
+#include <linux/module.h>
+#include <linux/mtd/mtd.h>
+#include <linux/mtd/partitions.h>
+#include <linux/mtd/spi-nor.h>
+#include <linux/of.h>
+#include <linux/of_device.h>
+#include <linux/platform_device.h>
+#include <linux/spi/spi.h>
+
+/* NXP SPIFI registers, bits and macros */
+#define SPIFI_CTRL				0x000
+#define  SPIFI_CTRL_TIMEOUT(timeout)		(timeout)
+#define  SPIFI_CTRL_CSHIGH(cshigh)		((cshigh) << 16)
+#define  SPIFI_CTRL_MODE3			BIT(23)
+#define  SPIFI_CTRL_DUAL			BIT(28)
+#define  SPIFI_CTRL_FBCLK			BIT(30)
+#define SPIFI_CMD				0x004
+#define  SPIFI_CMD_DATALEN(dlen)		((dlen) & 0x3fff)
+#define  SPIFI_CMD_DOUT				BIT(15)
+#define  SPIFI_CMD_INTLEN(ilen)			((ilen) << 16)
+#define  SPIFI_CMD_FIELDFORM(field)		((field) << 19)
+#define  SPIFI_CMD_FIELDFORM_ALL_SERIAL		SPIFI_CMD_FIELDFORM(0x0)
+#define  SPIFI_CMD_FIELDFORM_QUAD_DUAL_DATA	SPIFI_CMD_FIELDFORM(0x1)
+#define  SPIFI_CMD_FRAMEFORM(frame)		((frame) << 21)
+#define  SPIFI_CMD_FRAMEFORM_OPCODE_ONLY	SPIFI_CMD_FRAMEFORM(0x1)
+#define  SPIFI_CMD_OPCODE(op)			((op) << 24)
+#define SPIFI_ADDR				0x008
+#define SPIFI_IDATA				0x00c
+#define SPIFI_CLIMIT				0x010
+#define SPIFI_DATA				0x014
+#define SPIFI_MCMD				0x018
+#define SPIFI_STAT				0x01c
+#define  SPIFI_STAT_MCINIT			BIT(0)
+#define  SPIFI_STAT_CMD				BIT(1)
+#define  SPIFI_STAT_RESET			BIT(4)
+
+#define SPI_NOR_MAX_ID_LEN	6
+
+struct nxp_spifi {
+	struct device *dev;
+	struct clk *clk_spifi;
+	struct clk *clk_reg;
+	void __iomem *io_base;
+	void __iomem *flash_base;
+	struct mtd_info mtd;
+	struct spi_nor nor;
+	bool memory_mode;
+	u32 mcmd;
+};
+
+static int nxp_spifi_wait_for_cmd(struct nxp_spifi *spifi)
+{
+	u8 stat;
+	int ret;
+
+	ret = readb_poll_timeout(spifi->io_base + SPIFI_STAT, stat,
+				 !(stat & SPIFI_STAT_CMD), 10, 30);
+	if (ret)
+		dev_warn(spifi->dev, "command timed out\n");
+
+	return ret;
+}
+
+static int nxp_spifi_reset(struct nxp_spifi *spifi)
+{
+	u8 stat;
+	int ret;
+
+	writel(SPIFI_STAT_RESET, spifi->io_base + SPIFI_STAT);
+	ret = readb_poll_timeout(spifi->io_base + SPIFI_STAT, stat,
+				 !(stat & SPIFI_STAT_RESET), 10, 30);
+	if (ret)
+		dev_warn(spifi->dev, "state reset timed out\n");
+
+	return ret;
+}
+
+static int nxp_spifi_set_memory_mode_off(struct nxp_spifi *spifi)
+{
+	int ret;
+
+	if (!spifi->memory_mode)
+		return 0;
+
+	ret = nxp_spifi_reset(spifi);
+	if (ret)
+		dev_err(spifi->dev, "unable to enter command mode\n");
+	else
+		spifi->memory_mode = false;
+
+	return ret;
+}
+
+static int nxp_spifi_set_memory_mode_on(struct nxp_spifi *spifi)
+{
+	u8 stat;
+	int ret;
+
+	if (spifi->memory_mode)
+		return 0;
+
+	writel(spifi->mcmd, spifi->io_base + SPIFI_MCMD);
+	ret = readb_poll_timeout(spifi->io_base + SPIFI_STAT, stat,
+				 stat & SPIFI_STAT_MCINIT, 10, 30);
+	if (ret)
+		dev_err(spifi->dev, "unable to enter memory mode\n");
+	else
+		spifi->memory_mode = true;
+
+	return ret;
+}
+
+static int nxp_spifi_read_reg(struct spi_nor *nor, u8 opcode, u8 *buf, int len)
+{
+	struct nxp_spifi *spifi = nor->priv;
+	u32 cmd;
+	int ret;
+
+	ret = nxp_spifi_set_memory_mode_off(spifi);
+	if (ret)
+		return ret;
+
+	cmd = SPIFI_CMD_DATALEN(len) |
+	      SPIFI_CMD_OPCODE(opcode) |
+	      SPIFI_CMD_FIELDFORM_ALL_SERIAL |
+	      SPIFI_CMD_FRAMEFORM_OPCODE_ONLY;
+	writel(cmd, spifi->io_base + SPIFI_CMD);
+
+	while (len--)
+		*buf++ = readb(spifi->io_base + SPIFI_DATA);
+
+	return nxp_spifi_wait_for_cmd(spifi);
+}
+
+static int nxp_spifi_write_reg(struct spi_nor *nor, u8 opcode, u8 *buf,
+			       int len, int write_enable)
+{
+	struct nxp_spifi *spifi = nor->priv;
+	u32 cmd;
+	int ret;
+
+	ret = nxp_spifi_set_memory_mode_off(spifi);
+	if (ret)
+		return ret;
+
+	cmd = SPIFI_CMD_DOUT |
+	      SPIFI_CMD_DATALEN(len) |
+	      SPIFI_CMD_OPCODE(opcode) |
+	      SPIFI_CMD_FIELDFORM_ALL_SERIAL |
+	      SPIFI_CMD_FRAMEFORM_OPCODE_ONLY;
+	writel(cmd, spifi->io_base + SPIFI_CMD);
+
+	while (len--)
+		writeb(*buf++, spifi->io_base + SPIFI_DATA);
+
+	return nxp_spifi_wait_for_cmd(spifi);
+}
+
+static int nxp_spifi_read(struct spi_nor *nor, loff_t from, size_t len,
+			  size_t *retlen, u_char *buf)
+{
+	struct nxp_spifi *spifi = nor->priv;
+	int ret;
+
+	ret = nxp_spifi_set_memory_mode_on(spifi);
+	if (ret)
+		return ret;
+
+	memcpy_fromio(buf, spifi->flash_base + from, len);
+	*retlen += len;
+
+	return 0;
+}
+
+static void nxp_spifi_write(struct spi_nor *nor, loff_t to, size_t len,
+			    size_t *retlen, const u_char *buf)
+{
+	struct nxp_spifi *spifi = nor->priv;
+	u32 cmd;
+	int ret;
+
+	ret = nxp_spifi_set_memory_mode_off(spifi);
+	if (ret)
+		return;
+
+	writel(to, spifi->io_base + SPIFI_ADDR);
+	*retlen += len;
+
+	cmd = SPIFI_CMD_DOUT |
+	      SPIFI_CMD_DATALEN(len) |
+	      SPIFI_CMD_FIELDFORM_ALL_SERIAL |
+	      SPIFI_CMD_OPCODE(nor->program_opcode) |
+	      SPIFI_CMD_FRAMEFORM(spifi->nor.addr_width + 1);
+	writel(cmd, spifi->io_base + SPIFI_CMD);
+
+	while (len--)
+		writeb(*buf++, spifi->io_base + SPIFI_DATA);
+
+	nxp_spifi_wait_for_cmd(spifi);
+}
+
+static int nxp_spifi_erase(struct spi_nor *nor, loff_t offs)
+{
+	struct nxp_spifi *spifi = nor->priv;
+	u32 cmd;
+	int ret;
+
+	ret = nxp_spifi_set_memory_mode_off(spifi);
+	if (ret)
+		return ret;
+
+	writel(offs, spifi->io_base + SPIFI_ADDR);
+
+	cmd = SPIFI_CMD_FIELDFORM_ALL_SERIAL |
+	      SPIFI_CMD_OPCODE(nor->erase_opcode) |
+	      SPIFI_CMD_FRAMEFORM(spifi->nor.addr_width + 1);
+	writel(cmd, spifi->io_base + SPIFI_CMD);
+
+	return nxp_spifi_wait_for_cmd(spifi);
+}
+
+static int nxp_spifi_setup_memory_cmd(struct nxp_spifi *spifi)
+{
+	switch (spifi->nor.flash_read) {
+	case SPI_NOR_NORMAL:
+	case SPI_NOR_FAST:
+		spifi->mcmd = SPIFI_CMD_FIELDFORM_ALL_SERIAL;
+		break;
+	case SPI_NOR_DUAL:
+	case SPI_NOR_QUAD:
+		spifi->mcmd = SPIFI_CMD_FIELDFORM_QUAD_DUAL_DATA;
+		break;
+	default:
+		dev_err(spifi->dev, "unsupported SPI read mode\n");
+		return -EINVAL;
+	}
+
+	/* Memory mode supports address length between 1 and 4 */
+	if (spifi->nor.addr_width < 1 || spifi->nor.addr_width > 4)
+		return -EINVAL;
+
+	spifi->mcmd |= SPIFI_CMD_OPCODE(spifi->nor.read_opcode) |
+		       SPIFI_CMD_INTLEN(spifi->nor.read_dummy / 8) |
+		       SPIFI_CMD_FRAMEFORM(spifi->nor.addr_width + 1);
+
+	return 0;
+}
+
+static void nxp_spifi_dummy_id_read(struct spi_nor *nor)
+{
+	u8 id[SPI_NOR_MAX_ID_LEN];
+	nor->read_reg(nor, SPINOR_OP_RDID, id, SPI_NOR_MAX_ID_LEN);
+}
+
+static int nxp_spifi_setup_flash(struct nxp_spifi *spifi,
+				 struct device_node *np)
+{
+	struct mtd_part_parser_data ppdata;
+	enum read_mode flash_read;
+	u32 ctrl, property;
+	u16 mode = 0;
+	int ret;
+
+	if (!of_property_read_u32(np, "spi-rx-bus-width", &property)) {
+		switch (property) {
+		case 1:
+			break;
+		case 2:
+			mode |= SPI_RX_DUAL;
+			break;
+		case 4:
+			mode |= SPI_RX_QUAD;
+			break;
+		default:
+			dev_err(spifi->dev, "unsupported rx-bus-width\n");
+			return -EINVAL;
+		}
+	}
+
+	if (of_find_property(np, "spi-cpha", NULL))
+		mode |= SPI_CPHA;
+
+	if (of_find_property(np, "spi-cpol", NULL))
+		mode |= SPI_CPOL;
+
+	/* Setup control register defaults */
+	ctrl = SPIFI_CTRL_TIMEOUT(1000) |
+	       SPIFI_CTRL_CSHIGH(15) |
+	       SPIFI_CTRL_FBCLK;
+
+	if (mode & SPI_RX_DUAL) {
+		ctrl |= SPIFI_CTRL_DUAL;
+		flash_read = SPI_NOR_DUAL;
+	} else if (mode & SPI_RX_QUAD) {
+		ctrl &= ~SPIFI_CTRL_DUAL;
+		flash_read = SPI_NOR_QUAD;
+	} else {
+		ctrl |= SPIFI_CTRL_DUAL;
+		flash_read = SPI_NOR_NORMAL;
+	}
+
+	switch (mode & (SPI_CPHA | SPI_CPOL)) {
+	case SPI_MODE_0:
+		ctrl &= ~SPIFI_CTRL_MODE3;
+		break;
+	case SPI_MODE_3:
+		ctrl |= SPIFI_CTRL_MODE3;
+		break;
+	default:
+		dev_err(spifi->dev, "only mode 0 and 3 supported\n");
+		return -EINVAL;
+	}
+
+	writel(ctrl, spifi->io_base + SPIFI_CTRL);
+
+	spifi->mtd.priv  = &spifi->nor;
+	spifi->nor.mtd   = &spifi->mtd;
+	spifi->nor.dev   = spifi->dev;
+	spifi->nor.priv  = spifi;
+	spifi->nor.read  = nxp_spifi_read;
+	spifi->nor.write = nxp_spifi_write;
+	spifi->nor.erase = nxp_spifi_erase;
+	spifi->nor.read_reg  = nxp_spifi_read_reg;
+	spifi->nor.write_reg = nxp_spifi_write_reg;
+
+	/*
+	 * The first read on a hard reset isn't reliable so do a
+	 * dummy read of the id before calling spi_nor_scan().
+	 * The reason for this problem is unknown.
+	 *
+	 * The official NXP spifilib uses more or less the same
+	 * workaround that is applied here by reading the device
+	 * id multiple times.
+	 */
+	nxp_spifi_dummy_id_read(&spifi->nor);
+
+	ret = spi_nor_scan(&spifi->nor, NULL, flash_read);
+	if (ret) {
+		dev_err(spifi->dev, "device scan failed\n");
+		return ret;
+	}
+
+	ret = nxp_spifi_setup_memory_cmd(spifi);
+	if (ret) {
+		dev_err(spifi->dev, "memory command setup failed\n");
+		return ret;
+	}
+
+	ppdata.of_node = np;
+	ret = mtd_device_parse_register(&spifi->mtd, NULL, &ppdata, NULL, 0);
+	if (ret) {
+		dev_err(spifi->dev, "mtd device parse failed\n");
+		return ret;
+	}
+
+	return 0;
+}
+
+static int nxp_spifi_probe(struct platform_device *pdev)
+{
+	struct device_node *flash_np;
+	struct nxp_spifi *spifi;
+	struct resource *res;
+	int ret;
+
+	spifi = devm_kzalloc(&pdev->dev, sizeof(*spifi), GFP_KERNEL);
+	if (!spifi)
+		return -ENOMEM;
+
+	res = platform_get_resource_byname(pdev, IORESOURCE_MEM, "spifi");
+	spifi->io_base = devm_ioremap_resource(&pdev->dev, res);
+	if (IS_ERR(spifi->io_base))
+		return PTR_ERR(spifi->io_base);
+
+	res = platform_get_resource_byname(pdev, IORESOURCE_MEM, "flash");
+	spifi->flash_base = devm_ioremap_resource(&pdev->dev, res);
+	if (IS_ERR(spifi->flash_base))
+		return PTR_ERR(spifi->flash_base);
+
+	spifi->clk_spifi = devm_clk_get(&pdev->dev, "spifi");
+	if (IS_ERR(spifi->clk_spifi)) {
+		dev_err(&pdev->dev, "spifi clock not found\n");
+		return PTR_ERR(spifi->clk_spifi);
+	}
+
+	spifi->clk_reg = devm_clk_get(&pdev->dev, "reg");
+	if (IS_ERR(spifi->clk_reg)) {
+		dev_err(&pdev->dev, "reg clock not found\n");
+		return PTR_ERR(spifi->clk_reg);
+	}
+
+	ret = clk_prepare_enable(spifi->clk_reg);
+	if (ret) {
+		dev_err(&pdev->dev, "unable to enable reg clock\n");
+		return ret;
+	}
+
+	ret = clk_prepare_enable(spifi->clk_spifi);
+	if (ret) {
+		dev_err(&pdev->dev, "unable to enable spifi clock\n");
+		goto dis_clk_reg;
+	}
+
+	spifi->dev = &pdev->dev;
+	platform_set_drvdata(pdev, spifi);
+
+	/* Initialize and reset device */
+	nxp_spifi_reset(spifi);
+	writel(0, spifi->io_base + SPIFI_IDATA);
+	writel(0, spifi->io_base + SPIFI_MCMD);
+	nxp_spifi_reset(spifi);
+
+	flash_np = of_get_next_available_child(pdev->dev.of_node, NULL);
+	if (!flash_np) {
+		dev_err(&pdev->dev, "no SPI flash device to configure\n");
+		ret = -ENODEV;
+		goto dis_clks;
+	}
+
+	ret = nxp_spifi_setup_flash(spifi, flash_np);
+	if (ret) {
+		dev_err(&pdev->dev, "unable to setup flash chip\n");
+		goto dis_clks;
+	}
+
+	return 0;
+
+dis_clks:
+	clk_disable_unprepare(spifi->clk_spifi);
+dis_clk_reg:
+	clk_disable_unprepare(spifi->clk_reg);
+	return ret;
+}
+
+static int nxp_spifi_remove(struct platform_device *pdev)
+{
+	struct nxp_spifi *spifi = platform_get_drvdata(pdev);
+
+	mtd_device_unregister(&spifi->mtd);
+	clk_disable_unprepare(spifi->clk_spifi);
+	clk_disable_unprepare(spifi->clk_reg);
+
+	return 0;
+}
+
+static const struct of_device_id nxp_spifi_match[] = {
+	{.compatible = "nxp,lpc1773-spifi"},
+	{ /* sentinel */ }
+};
+MODULE_DEVICE_TABLE(of, nxp_spifi_match);
+
+static struct platform_driver nxp_spifi_driver = {
+	.probe	= nxp_spifi_probe,
+	.remove	= nxp_spifi_remove,
+	.driver	= {
+		.name = "nxp-spifi",
+		.of_match_table = nxp_spifi_match,
+	},
+};
+module_platform_driver(nxp_spifi_driver);
+
+MODULE_DESCRIPTION("NXP SPI Flash Interface driver");
+MODULE_AUTHOR("Joachim Eastwood <manabian at gmail.com>");
+MODULE_LICENSE("GPL v2");
-- 
1.8.0



From santosh.shilimkar at oracle.com  Thu Aug 13 10:21:31 2015
From: santosh.shilimkar at oracle.com (santosh.shilimkar at oracle.com)
Date: Thu, 13 Aug 2015 10:21:31 -0700
Subject: [GIT PULL] ARM: Couple of Keystone MDIO DTS fixes for 4.2-rc6+
In-Reply-To: <20150813102434.GV30160@localhost>
References: <1439177200-32434-1-git-send-email-ssantosh@kernel.org>
 <20150813102434.GV30160@localhost>
Message-ID: <55CCD21B.5030309@oracle.com>

On 8/13/15 3:24 AM, Olof Johansson wrote:
> On Sun, Aug 09, 2015 at 08:26:40PM -0700, Santosh Shilimkar wrote:
>> ARM-SoC folks,
>>
>> Please pull below couple of late fixes for 4.2-rc6+. I know its late
>> with rc6 already out but if possible please consider.
>>
>> The following changes since commit f7644cbfcdf03528f0f450f3940c4985b2291f49:
>>
>>    Linux 4.2-rc6 (2015-08-09 15:54:30 -0400)
>>
>> are available in the git repository at:
>>
>>    git://git.kernel.org/pub/scm/linux/kernel/git/ssantosh/linux-keystone.git tags/keystone-dts-late-fixes
>>
>> for you to fetch changes up to 6a024079862443b3ec9455931e9219cd5912656d:
>>
>>    ARM: dts: keystone: Fix the mdio bindings by moving it to soc specific file (2015-08-09 20:06:27 -0700)
>
> Hi,
>
> Our fixes branch is still at -rc2. Would you mind respinning with an older
> base unless there are conflicts?
>
Just created v2. I tried merging with arm-soc/fixes and it merge
cleanly. Please pull below.

 
git://git.kernel.org/pub/scm/linux/kernel/git/ssantosh/linux-keystone.git tags/keystone-dts-late-fixes-v2

Thanks and regards,
Santosh




From will.deacon at arm.com  Thu Aug 13 10:23:10 2015
From: will.deacon at arm.com (Will Deacon)
Date: Thu, 13 Aug 2015 18:23:10 +0100
Subject: [PATCH 0/2] x86/KASAN updates for 4.3
In-Reply-To: <20150813112428.GG10280@arm.com>
References: <1439444244-26057-1-git-send-email-ryabinin.a.a@gmail.com>
 <20150813065040.GA17983@gmail.com>
 <20150813081641.GA14402@gmail.com> <20150813090119.GA10280@arm.com>
 <CAPAsAGxk2+v5VG77cOHAThsXyWx-_UJ1XVeJProaa0gQWH5jvA@mail.gmail.com>
 <20150813112428.GG10280@arm.com>
Message-ID: <20150813172310.GK10280@arm.com>

On Thu, Aug 13, 2015 at 12:24:28PM +0100, Will Deacon wrote:
> On Thu, Aug 13, 2015 at 12:02:26PM +0100, Andrey Ryabinin wrote:
> > 2015-08-13 12:01 GMT+03:00 Will Deacon <will.deacon at arm.com>:
> > > Yes please, works for me! If we're targetting 4.3, then please can you base
> > > on 4.2-rc4, as that's what our current arm64 queue is using?
> > >
> > 
> > Does this mean that we are targeting arm64 part for 4.3 too?
> 
> It depends on how well it merges with our current queue and whether it
> holds up to regression testing. The patches have been reviewed, so I'm
> comfortable with the content, but we're not at a stage where we can debug
> and fix any failures that might crop up from the merge.

Scratch that :(

I tried this out under EFI and it dies horribly in the stub code because
we're missing at least one KASAN_SANITIZE_ Makefile entry.

So I think this needs longer to stew before hitting mainline. By all means
get the x86 dependencies in for 4.3, but the arm64 port can probably use
another cycle to iron out the bugs.

Cheers,

Will


From sudeep.holla at arm.com  Thu Aug 13 10:26:52 2015
From: sudeep.holla at arm.com (Sudeep Holla)
Date: Thu, 13 Aug 2015 18:26:52 +0100
Subject: [PATCH 5/9] ARM: common: Introduce PM domains for CPUs/clusters
In-Reply-To: <20150813154503.GO52339@linaro.org>
References: <1438731339-58317-1-git-send-email-lina.iyer@linaro.org>
 <1438731339-58317-6-git-send-email-lina.iyer@linaro.org>
 <CAL_JsqK67=DTtjZwwnonObLDjLbahkREfm0RvyXVV95bhR-d4Q@mail.gmail.com>
 <20150813150154.GB13356@red-moon> <20150813154503.GO52339@linaro.org>
Message-ID: <55CCD35C.4000901@arm.com>



On 13/08/15 16:45, Lina Iyer wrote:
> On Thu, Aug 13 2015 at 09:01 -0600, Lorenzo Pieralisi wrote:
>> On Thu, Aug 06, 2015 at 04:14:51AM +0100, Rob Herring wrote:
>>> On Tue, Aug 4, 2015 at 6:35 PM, Lina Iyer <lina.iyer at linaro.org> wrote:

[..]

>>>
>>>> +ARM CPU Power domains
>>>> +
>>>> +The device tree allows describing of CPU power domains in a SoC. In ARM SoC,
>>>> +CPUs may be grouped as clusters. A cluster may have CPUs, GIC, Coresight,
>>>> +caches, VFP and power controller and other peripheral hardware. Generally,
>>>> +when the CPUs in the cluster are idle/suspended, the shared resources may also
>>>> +be suspended and resumed before any of the CPUs resume execution.
>>>> +
>>>> +CPUs are the defined as the PM domain consumers and there is a PM domain
>>>> +provider for the CPUs. Bindings for generic PM domains (genpd) is described in
>>>> +[1].
>>>> +
>>>> +The ARM CPU PM domain follows the same binding convention as any generic PM
>>>> +domain. Additional binding properties are -
>>>> +
>>>> +- compatible:
>>>> +       Usage: required
>>>> +       Value type: <string>
>>>> +       Definition: Must also have
>>>> +                       "arm,pd"
>>>> +               inorder to initialize the genpd provider as ARM CPU PM domain.
>>>
>>> A compatible string should represent a particular h/w block. If it is
>>> generic, it should represent some sort of standard programming
>>> interface (e.g, AHCI, EHCI, etc.). This doesn't seem to be either and
>>> is rather just a mapping of what "driver" you want to use.
>>>
>>> I would expect that identifying a cpu's or cluster's power domain
>>> would be done by a phandle between the cpu/cluster node and power
>>> domain node. But I've not really looked at the power domain bindings
>>> so who knows.
>>
>> I would expect the same, meaning that a cpu node, like any other device
>> node would have a phandle pointing at the respective HW power domain.
>>
> CPUs have phandles to their domains. That is how the relationship
> between the domain provider (power-controller) and the consumer (CPU) is
> established.
>
>> I do not really understand why we want a "generic" CPU power domain, what
>> purpose does it serve ? Creating a collection of cpu devices that we
>> can call "cluster" ?
>>
> Nope, not for calling a cluster, a cluster :)
>
> This compatible is used to define a generic behavior of the CPU domain
> controller (in addition to the platform specific behavior of the domain
> power controller). The kernel activities for such power controller are
> generally the same which otherwise would be repeated across platforms.

Having gone through this series and the one using it[1], the only common
activity is just cluster pm notifiers. Other than that it's just
creating indirection for now. The scenario might change in future, but
for now it seems unnecessary.

Also if you look at the shmobile power controller driver, it covers all
the devices including CPUs unlike QCOM power controller which handles
only CPU. Yes we can skip CPU genpd creation there only for CPU, IMO
creating the power domains should be part of power controller driver.

You can add helper functions for all the ARM specific code that can be
reused by multiple power controller drivers handling CPU/Cluster power
domain.

> An analogy to this would be the "arm,idle-state" that defines the DT
> node as something that also depicts a generic cpuidle C state.
>

I tend to disagree. In idle-states, the nodes define that generic
properties and they can be parsed in a generic way. That's not the case
here. Each power controller binding differs.

Yes the generic compatible might be useful to identify that this power
domain handles CPU/Cluster, but there will be more power controller
specific things compared to generic code.

Regards,
Sudeep

[1] http://www.spinics.net/lists/arm-kernel/msg437304.html


From catalin.marinas at arm.com  Thu Aug 13 10:29:47 2015
From: catalin.marinas at arm.com (Catalin Marinas)
Date: Thu, 13 Aug 2015 18:29:47 +0100
Subject: [PATCH 12/14] arm64: Check for selected granule support
In-Reply-To: <55CCAD73.7080702@arm.com>
References: <1439465645-22584-1-git-send-email-suzuki.poulose@arm.com>
 <1439465645-22584-13-git-send-email-suzuki.poulose@arm.com>
 <CAPvkgC3=S1BxdzZM4uUOmyXLjii48SMpCof6i6HdNeTG_fydfg@mail.gmail.com>
 <55CCAD73.7080702@arm.com>
Message-ID: <20150813172946.GD4602@e104818-lin.cambridge.arm.com>

On Thu, Aug 13, 2015 at 03:45:07PM +0100, Suzuki K. Poulose wrote:
> On 13/08/15 13:28, Steve Capper wrote:
> >On 13 August 2015 at 12:34, Suzuki K. Poulose <suzuki.poulose at arm.com> wrote:
> >>  __enable_mmu:
> >>+       mrs     x1, ID_AA64MMFR0_EL1
> >>+       ubfx    x2, x1, #ID_AA64MMFR0_TGran_SHIFT, 4
> >>+       cmp     x2, #ID_AA64MMFR0_TGran_ENABLED
> >>+       b.ne    __no_granule_support
> >>         ldr     x5, =vectors
> >>         msr     vbar_el1, x5
> >>         msr     ttbr0_el1, x25                  // load TTBR0
> >>@@ -626,3 +643,8 @@ __enable_mmu:
> >>         isb
> >>         br      x27
> >>  ENDPROC(__enable_mmu)
> >>+
> >>+__no_granule_support:
> >>+       wfe
> >>+       b __no_granule_support
> >>+ENDPROC(__no_granule_support)
> >>--
> >>1.7.9.5
> >>
> >
> >Is is possible to tell the user that the kernel has failed to boot due
> >to the kernel granule being unsupported?
> 
> We don't have anything up at this time. The "looping address" is actually a clue
> to the (expert) user. Not sure we can do something, until we get something like DEBUG_LL(?)

No.

> Or we should let it continue and end in a panic(?). The current situation can boot a
> multi-cluster system with boot cluster having the Tgran support(which doesn't make a
> strong use case though). I will try out some options and get back to you.

If the boot CPU does not support 16KB pages, in general there isn't much
we can do since the console printing is done after we enabled the MMU.
Even mapping the UART address requires fixmap support and the PAGE_SIZE
is hard-coded in the kernel image. The DT is also mapped at run-time.

While in theory it's possible to fall back to a 4KB page size just
enough to load the DT and figure out the early console, I suggest we
just live with the "looping address" clue.

-- 
Catalin


From robherring2 at gmail.com  Thu Aug 13 10:29:35 2015
From: robherring2 at gmail.com (Rob Herring)
Date: Thu, 13 Aug 2015 12:29:35 -0500
Subject: [PATCH v2 1/2] ARM: common: Introduce PM domains for CPUs/clusters
In-Reply-To: <1439406024-41893-1-git-send-email-lina.iyer@linaro.org>
References: <CAL_JsqLhHy5gO=usm1HLf8h6iz_5FguCDo-Qz2Km+XEwaCODUA@mail.gmail.com>
 <1439406024-41893-1-git-send-email-lina.iyer@linaro.org>
Message-ID: <CAL_JsqLcSs79bnj4ELN0uiwJ6gxt46PghxvuGQ7prkq-4gLKhg@mail.gmail.com>

On Wed, Aug 12, 2015 at 2:00 PM, Lina Iyer <lina.iyer at linaro.org> wrote:
> Define and add Generic PM domains (genpd) for CPU clusters. Many new
> SoCs group CPUs as clusters. Clusters share common resources like GIC,
> power rail, caches, VFP, Coresight etc. When all CPUs in the cluster are
> idle, these shared resources may also be put in their idle state.
>
> The idle time between the last CPU entering idle and a CPU resuming
> execution is an opportunity for these shared resources to be powered
> down. Generic PM domain provides a framework for defining such power
> domains and attach devices to the domain. When the devices in the domain
> are idle at runtime, the domain would also be suspended and resumed
> before the first of the devices resume execution.
>
> We define a generic PM domain for each cluster and attach CPU devices in
> the cluster to that PM domain. The DT definitions for the SoC describe
> this relationship. Genpd callbacks for power_on and power_off can then
> be used to power up/down the shared resources for the domain.
>
> Cc: Stephen Boyd <sboyd at codeaurora.org>
> Cc: Kevin Hilman <khilman at linaro.org>
> Cc: Ulf Hansson <ulf.hansson at linaro.org>
> Cc: Catalin Marinas <catalin.marinas at arm.com>
> Cc: Daniel Lezcano <daniel.lezcano at linaro.org>
> Cc: Mark Rutland <mark.rutland at arm.com>
> Cc: Lorenzo Pieralisi <lorenzo.pieralisi at arm.com>
> Signed-off-by: Kevin Hilman <khilman at linaro.org>
> Signed-off-by: Lina Iyer <lina.iyer at linaro.org>
> ---
> Changes since v1:
>
> - Function name changes and split out common code
> - Use cpu,pd for now. Removed references to ARM. Open to recommendations.
> - Still located in arch/arm/common/. May move to a more appropriate location.
> - Platform drivers can directly call of_init_cpu_domain() without using
>   compatibles.
> - Now maintains a list of CPU PM domains.

[...]

> +static int __init of_pm_domain_attach_cpus(void)
> +{
> +       int cpuid, ret;
> +
> +       /* Find any CPU nodes with a phandle to this power domain */
> +       for_each_possible_cpu(cpuid) {
> +               struct device *cpu_dev;
> +               struct of_phandle_args pd_args;
> +
> +               cpu_dev = get_cpu_device(cpuid);
> +               if (!cpu_dev) {
> +                       pr_warn("%s: Unable to get device for CPU%d\n",
> +                                       __func__, cpuid);
> +                       return -ENODEV;
> +               }
> +
> +               /*
> +                * We are only interested in CPUs that can be attached to
> +                * PM domains that are cpu,pd compatible.
> +                */

Under what conditions would the power domain for a cpu not be cpu,pd compatible?

Why can't the driver handling the power domain register with gen_pd
and the cpu_pd as the driver is going to be aware of which domains are
for cpus. While there could be h/w such that all power domains within
a chip have a nice uniform programming model, I'd guess that is the
exception, not the rule. First, chips I have worked on were not that
way. CPU related and peripheral related domains are handled quite
differently. Second, often the actions on the CPU power domains don't
take effect until a WFI, so you end up with a different programming
sequence.

Rob


From robert.jarzmik at free.fr  Thu Aug 13 11:01:08 2015
From: robert.jarzmik at free.fr (Robert Jarzmik)
Date: Thu, 13 Aug 2015 20:01:08 +0200
Subject: [PATCH v1 RFC] This patch repairs HTC Magician machine (PXA27x)
 support
In-Reply-To: <55CBCDED.8010409@tul.cz> (Petr Cvek's message of "Thu, 13 Aug
 2015 00:51:25 +0200")
References: <55CBCDED.8010409@tul.cz>
Message-ID: <87y4hfhxuj.fsf@belgarion.home>

Petr Cvek <petr.cvek at tul.cz> writes:

> Fixing original code: Problems to successful boot due to the bad LCD
> power sequence (wrongly configured GPIO).
>
> Add/fix platform data and helper function for various hardware
> (touchscreen, audio, USB device, ...).
>
> Add new discovered GPIOs and fix names by GPIO context.
>
> Add new LEDs driver.
>
> Signed-off-by: Petr Cvek <petr.cvek at tul.cz>
Hi Petr,

Just as Lee, I want the serie to be split per-subsystem.

For the mach-pxa part, I need you to split the patch into several chunks to
review.
At least please split :
 - a first patch for cleanup (identation and whitespaces)
 - a second patch for cleanup (comments changes, debug messages)
 - a serie of fix patches
   - one for the power sequence
   - one for GPIO fixes
 - a serie of evolution patches
   - new gpio_keys
   - new backlight stuff
   - one per new device declared
   - new flash stuff
   - etc ...

Please keep in mind that in order to pick the patches, I need to split them in 3
groups :
 - cleanups
 - fixes
 - evolutions / new stuff
Moreover I want to be able to revert one functionality (for example new power
sequence) without reverting the whole serie.

You probably know that the pxa patches need the subject prefix to be "ARM: pxa:
magician: " in your case. Other subsystem maintainers have similar requirements
I believe.

When that's done, I'll begin the review, and Philipp will probably too as he is
the maintainer.

Cheers.

--
Robert


From linux at horizon.com  Thu Aug 13 11:18:41 2015
From: linux at horizon.com (George Spelvin)
Date: 13 Aug 2015 14:18:41 -0400
Subject: enabling libgcc for 64-bit divisions,
 was Re: PROBLEM: XFS on ARM corruption 'Structure needs cl
In-Reply-To: <CA+55aFwgaq3KkeXGQWxmVHsNVwJUWK3WssJ5_ADpQG4zTXjWPQ@mail.gmail.com>
Message-ID: <20150813181841.10342.qmail@ns.horizon.com>

> I'm not convinced that "64/32->32" is all that generic, though.  If
> the dividend in 64-bit, there's no fundamental type-based guarantee
> that things will fit.

I agree that it's impossible to decide based on the types, but having
that knowledge is extremely common.  Which is why it would be nice
to have a way for the programmer to communicate that knowledge.

> So your case is rather special, and depends (intimately) on knowing
> the actual ranges and how they interact.

Actually, it's the most common case.  Going through "git grep -w do_div",
by far the *majority* of all calls to do_div immediately convert the
result to 32 bits (or unsigned long), with no overflow checking.

Partially that's because I'm cointing static code frequency and there
are a ridiculous number of different PLL drivers, but still.

On x86, the case that msword >= divsor causes a divide exception
(divide ba generalization of divide by zero), so it's tempting
to do the same sort of "assume no trap and fix up in the handler"
trick as <asm/uaccess.h>.


There are only 854 references to do_div in the kernel, so
doing a sweep over all of them is quite practical.

One function that would cover a significant number of use cases
(but not all, damn it) would be

rem = do_mul_div(x, mul,_div)

Which returns x * mul / div, with a 64-bit intermediate.


From sboyd at codeaurora.org  Thu Aug 13 11:25:10 2015
From: sboyd at codeaurora.org (Stephen Boyd)
Date: Thu, 13 Aug 2015 11:25:10 -0700
Subject: [PATCH V3 1/5] clk: remove duplicated code with
 __clk_set_parent_after
In-Reply-To: <1438089585-30103-2-git-send-email-aisheng.dong@freescale.com>
References: <1438089585-30103-1-git-send-email-aisheng.dong@freescale.com>
 <1438089585-30103-2-git-send-email-aisheng.dong@freescale.com>
Message-ID: <20150813182510.GQ26614@codeaurora.org>

On 07/28, Dong Aisheng wrote:
> __clk_set_parent_after() actually used the second argument then we
> could put this duplicate logic in there and call it with a different
> order of arguments in the success vs. error paths in this function.
> 
> Cc: Mike Turquette <mturquette at linaro.org>
> Cc: Stephen Boyd <sboyd at codeaurora.org>
> Suggested-by: Stephen Boyd <sboyd at codeaurora.org>
> Signed-off-by: Dong Aisheng <aisheng.dong at freescale.com>
> ---

Applied to clk-next

-- 
Qualcomm Innovation Center, Inc. is a member of Code Aurora Forum,
a Linux Foundation Collaborative Project


From torvalds at linux-foundation.org  Thu Aug 13 11:26:30 2015
From: torvalds at linux-foundation.org (Linus Torvalds)
Date: Thu, 13 Aug 2015 11:26:30 -0700
Subject: enabling libgcc for 64-bit divisions, was Re: PROBLEM: XFS on ARM
 corruption 'Structure needs cl
In-Reply-To: <20150813181841.10342.qmail@ns.horizon.com>
References: <CA+55aFwgaq3KkeXGQWxmVHsNVwJUWK3WssJ5_ADpQG4zTXjWPQ@mail.gmail.com>
 <20150813181841.10342.qmail@ns.horizon.com>
Message-ID: <CA+55aFw9-sN0nHn-ohdhSEt9i-mUjXN3fBj+dXLg56jgsOwgDw@mail.gmail.com>

On Thu, Aug 13, 2015 at 11:18 AM, George Spelvin <linux at horizon.com> wrote:
>
> On x86, the case that msword >= divsor causes a divide exception
> (divide ba generalization of divide by zero), so it's tempting
> to do the same sort of "assume no trap and fix up in the handler"
> trick as <asm/uaccess.h>.

That would be horrible. One of the reasonably common cases of do_div()
is for printing out numbers. And they are often in the 4G+ range..

> One function that would cover a significant number of use cases
> (but not all, damn it) would be
>
> rem = do_mul_div(x, mul,_div)

Yes. That might be worth introducing. Not to replace do_div(), but as
a "32-bit only" interface to a somewhat common situation.

                Linus


From kgene at kernel.org  Thu Aug 13 11:42:31 2015
From: kgene at kernel.org (Kukjin Kim)
Date: Fri, 14 Aug 2015 03:42:31 +0900
Subject: [GIT PULL v2 0/5] Samsung updates for v4.3
Message-ID: <55CCE517.2070003@kernel.org>

Hello Arnd, Olof, Kevin

Here is re-spin of pull request for Samsung stuff for v4.3 as per Olof's
suggestion.

Most of this pull-requests are to switch to support generic cpufreq
driver for exynos3250, 4210, 4412 and 5250 and several exynos dt updates.

Note as I commented in each tag, each pull-request(signed tag) has a
dependency with each other, so please keep the ordering in this time.

1) tags/samsung-clk-driver
2) tags/samsung-late-dt
3) tags/samsung-soc
4) tags/samsung-late-cpufreq-driver
5) tags/samsung-defconfig-new

If any problems, please kindly let me know.

Thanks,
Kukjin

Alexis Ballier (1):
      ARM: dts: enable SPI1 for exynos4412-odroidu3

Anand Moon (1):
      ARM: exynos_defconfig: Enable CONFIG_SND_SOC_ODROIDX2 for Odroid-XU3

Bartlomiej Zolnierkiewicz (5):
      cpufreq: exynos: remove exynos5250 specific cpufreq driver support
      clk: exynos4x12: add cpu clock configuration data and instantiate
cpu clock
      cpufreq: exynos: remove Exynos4x12 specific cpufreq driver support
      ARM: dts: add CPU OPP and regulator supply property for exynos4x12
      ARM: EXYNOS: switch to using generic cpufreq driver for exynos4x12

Chanho Park (1):
      ARM: dts: add exynos5422-cpus.dtsi to correct cpu order

Chanwoo Choi (4):
      clk: exynos3250: Add cpu clock configuration data and instaniate
cpu clock
      ARM: EXYNOS: Add exynos3250 compatible to use generic cpufreq driver
      ARM: dts: Add CPU OPP and regulator supply property for exynos3250
      ARM: dts: Add CPU cooling binding for exynos3250 boards

Javier Martinez Canillas (4):
      ARM: multi_v7_defconfig: Remove old Samsung USB PHY configs
      ARM: multi_v7_defconfig: Enable NTC Thermistors support
      ARM: exynos_defconfig: Enable NTC Thermistors support
      ARM: multi_v7_defconfig: Enable max77802 regulator

Jonas Rabenstein (1):
      cpufreq: exynos: Remove unselectable rule for arm-exynos-cpufreq.o

Krzysztof Kozlowski (1):
      ARM: exynos_defconfig: Enable cpufreq-dt driver

Marek Szyprowski (1):
      ARM: dts: add iommu property to JPEG device for exynos4

Michal Suchanek (1):
      ARM: dts: Add SPI CS on exynos5250-snow

Thomas Abraham (3):
      clk: exynos5250: add cpu clock configuration data and instantiate
cpu clock
      ARM: EXYNOS: switch to using generic cpufreq driver for exynos5250
      ARM: dts: add CPU OPP and regulator supply property for exynos5250

 arch/arm/boot/dts/exynos3250-monk.dts              |  19 ++
 arch/arm/boot/dts/exynos3250-rinato.dts            |  19 ++
 arch/arm/boot/dts/exynos3250.dtsi                  |  16 ++
 arch/arm/boot/dts/exynos4.dtsi                     |   1 +
 arch/arm/boot/dts/exynos4212.dtsi                  |  81 +++++++
 arch/arm/boot/dts/exynos4412-odroid-common.dtsi    |   4 +
 arch/arm/boot/dts/exynos4412-odroidu3.dts          |   8 +
 arch/arm/boot/dts/exynos4412-origen.dts            |   4 +
 arch/arm/boot/dts/exynos4412-trats2.dts            |   4 +
 arch/arm/boot/dts/exynos4412.dtsi                  |  83 ++++++++
 arch/arm/boot/dts/exynos5250-arndale.dts           |   4 +
 arch/arm/boot/dts/exynos5250-smdk5250.dts          |   4 +
 arch/arm/boot/dts/exynos5250-snow.dts              |   5 +
 arch/arm/boot/dts/exynos5250-spring.dts            |   4 +
 arch/arm/boot/dts/exynos5250.dtsi                  |  22 ++
 arch/arm/boot/dts/exynos5422-cpus.dtsi             |  81 +++++++
 arch/arm/boot/dts/exynos5422-odroidxu3-common.dtsi |   1 +
 arch/arm/configs/exynos_defconfig                  |   5 +
 arch/arm/configs/multi_v7_defconfig                |   5 +-
 arch/arm/mach-exynos/Kconfig                       |   2 +
 arch/arm/mach-exynos/exynos.c                      |   4 +
 drivers/clk/samsung/clk-exynos3250.c               |  32 ++-
 drivers/clk/samsung/clk-exynos4.c                  |  50 +++++
 drivers/clk/samsung/clk-exynos5250.c               |  31 +++
 drivers/cpufreq/Kconfig.arm                        |  49 -----
 drivers/cpufreq/Makefile                           |   4 -
 drivers/cpufreq/exynos-cpufreq.c                   | 237
---------------------
 drivers/cpufreq/exynos-cpufreq.h                   |  89 --------
 drivers/cpufreq/exynos4x12-cpufreq.c               | 236
--------------------
 drivers/cpufreq/exynos5250-cpufreq.c               | 210 ------------------
 include/dt-bindings/clock/exynos3250.h             |   1 +
 include/dt-bindings/clock/exynos5250.h             |   1 +
 32 files changed, 487 insertions(+), 829 deletions(-)


From kgene at kernel.org  Thu Aug 13 11:48:37 2015
From: kgene at kernel.org (Kukjin Kim)
Date: Fri, 14 Aug 2015 03:48:37 +0900
Subject: [GIT PULL v2 1/5] Samsung clk driver updates for v4.3
In-Reply-To: <55CCE517.2070003@kernel.org>
References: <55CCE517.2070003@kernel.org>
Message-ID: <55CCE685.40501@kernel.org>

The following changes since commit d770e558e21961ad6cfdf0ff7df0eb5d7d4f0754:

  Linux 4.2-rc1 (2015-07-05 11:01:52 -0700)

are available in the git repository at:

  git://git.kernel.org/pub/scm/linux/kernel/git/kgene/linux-samsung.git
tags/samsung-clk-driver

for you to fetch changes up to cd6aceef028afc3fa216e3e7bc94cc31632cad43:

  clk: exynos4x12: add cpu clock configuration data and instantiate cpu
clock (2015-08-14 02:00:43 +0900)

----------------------------------------------------------------
Samsung clk driver updates for v4.3

- add cpu clock configuration data and instantiate cpu clock
  for exynos3250, 4210, 4412 and 5250 SoCs to support Samsung
  specific cpu-clock type

* Note this branch has been provided to clk tree as a topic branch

----------------------------------------------------------------
Bartlomiej Zolnierkiewicz (1):
      clk: exynos4x12: add cpu clock configuration data and instantiate
cpu clock

Chanwoo Choi (1):
      clk: exynos3250: Add cpu clock configuration data and instaniate
cpu clock

Thomas Abraham (1):
      clk: exynos5250: add cpu clock configuration data and instantiate
cpu clock

 drivers/clk/samsung/clk-exynos3250.c   | 32 ++++++++++++++++++++--
 drivers/clk/samsung/clk-exynos4.c      | 50
++++++++++++++++++++++++++++++++++
 drivers/clk/samsung/clk-exynos5250.c   | 31 +++++++++++++++++++++
 include/dt-bindings/clock/exynos3250.h |  1 +
 include/dt-bindings/clock/exynos5250.h |  1 +
 5 files changed, 113 insertions(+), 2 deletions(-)


From kgene at kernel.org  Thu Aug 13 11:50:30 2015
From: kgene at kernel.org (Kukjin Kim)
Date: Fri, 14 Aug 2015 03:50:30 +0900
Subject: [GIT PULL v2 2/5] Samsung 2nd DT updates for v4.3
In-Reply-To: <55CCE517.2070003@kernel.org>
References: <55CCE517.2070003@kernel.org>
Message-ID: <55CCE6F6.1090001@kernel.org>

The following changes since commit 5e080b078fa1f929d9aa5586985d5e7c0739d207:

  ARM: dts: Extend exynos5420-pinctrl nodes using labels instead of
paths (2015-07-21 13:01:23 +0900)

are available in the git repository at:

  git://git.kernel.org/pub/scm/linux/kernel/git/kgene/linux-samsung.git
tags/samsung-late-dt

for you to fetch changes up to ba032795463bfc461937dbde7a345103a47f969b:

  ARM: dts: add iommu property to JPEG device for exynos4 (2015-08-14
02:30:58 +0900)

----------------------------------------------------------------
Samsung 2nd DT updates for v4.3

- for exynos3250, 4212, 4412 and 5250
  : add CPU OPP and regulator supply property

- for exynos3250
  : add CPU cooling binding for exynos3250 boards

- for exynos4 SoCs
  : add iommu property to JPEG device

- for exynos4412-odroidu3
  : enable SPI1

- for exynos5250-snow
  : add SPI CS

- for exynos5422
  : add exynos5422-cpus.dtsi to correct cpu order

* Note this branch is depending on tags/samsung-clk-driver

----------------------------------------------------------------
Alexis Ballier (1):
      ARM: dts: enable SPI1 for exynos4412-odroidu3

Bartlomiej Zolnierkiewicz (1):
      ARM: dts: add CPU OPP and regulator supply property for exynos4x12

Chanho Park (1):
      ARM: dts: add exynos5422-cpus.dtsi to correct cpu order

Chanwoo Choi (2):
      ARM: dts: Add CPU OPP and regulator supply property for exynos3250
      ARM: dts: Add CPU cooling binding for exynos3250 boards

Marek Szyprowski (1):
      ARM: dts: add iommu property to JPEG device for exynos4

Michal Suchanek (1):
      ARM: dts: Add SPI CS on exynos5250-snow

Thomas Abraham (1):
      ARM: dts: add CPU OPP and regulator supply property for exynos5250

 arch/arm/boot/dts/exynos3250-monk.dts              | 19 +++++
 arch/arm/boot/dts/exynos3250-rinato.dts            | 19 +++++
 arch/arm/boot/dts/exynos3250.dtsi                  | 16 +++++
 arch/arm/boot/dts/exynos4.dtsi                     |  1 +
 arch/arm/boot/dts/exynos4212.dtsi                  | 81
+++++++++++++++++++++
 arch/arm/boot/dts/exynos4412-odroid-common.dtsi    |  4 ++
 arch/arm/boot/dts/exynos4412-odroidu3.dts          |  8 +++
 arch/arm/boot/dts/exynos4412-origen.dts            |  4 ++
 arch/arm/boot/dts/exynos4412-trats2.dts            |  4 ++
 arch/arm/boot/dts/exynos4412.dtsi                  | 83
++++++++++++++++++++++
 arch/arm/boot/dts/exynos5250-arndale.dts           |  4 ++
 arch/arm/boot/dts/exynos5250-smdk5250.dts          |  4 ++
 arch/arm/boot/dts/exynos5250-snow.dts              |  5 ++
 arch/arm/boot/dts/exynos5250-spring.dts            |  4 ++
 arch/arm/boot/dts/exynos5250.dtsi                  | 22 ++++++
 arch/arm/boot/dts/exynos5422-cpus.dtsi             | 81
+++++++++++++++++++++
 arch/arm/boot/dts/exynos5422-odroidxu3-common.dtsi |  1 +
 17 files changed, 360 insertions(+)
 create mode 100644 arch/arm/boot/dts/exynos5422-cpus.dtsi


From kgene at kernel.org  Thu Aug 13 11:51:40 2015
From: kgene at kernel.org (Kukjin Kim)
Date: Fri, 14 Aug 2015 03:51:40 +0900
Subject: [GIT PULL v2 3/5] Samsung SoC updates for v4.3
In-Reply-To: <55CCE517.2070003@kernel.org>
References: <55CCE517.2070003@kernel.org>
Message-ID: <55CCE73C.3080404@kernel.org>

The following changes since commit d770e558e21961ad6cfdf0ff7df0eb5d7d4f0754:

  Linux 4.2-rc1 (2015-07-05 11:01:52 -0700)

are available in the git repository at:

  git://git.kernel.org/pub/scm/linux/kernel/git/kgene/linux-samsung.git
tags/samsung-soc

for you to fetch changes up to bdd2648e50508cbb2eb6d1c303e4d2d6d7505400:

  ARM: EXYNOS: switch to using generic cpufreq driver for exynos4x12
(2015-08-14 03:07:10 +0900)

----------------------------------------------------------------
Samsung SoC updates for v4.3

- add compatible string to exynos_cpufreq_matchs to switch for
  supporting generic cpufreq driver for exynos3250, 4210, 4212
  and 5250 SoCs in mach-exynos/

----------------------------------------------------------------
Bartlomiej Zolnierkiewicz (1):
      ARM: EXYNOS: switch to using generic cpufreq driver for exynos4x12

Chanwoo Choi (1):
      ARM: EXYNOS: Add exynos3250 compatible to use generic cpufreq driver

Thomas Abraham (1):
      ARM: EXYNOS: switch to using generic cpufreq driver for exynos5250

 arch/arm/mach-exynos/Kconfig  | 2 ++
 arch/arm/mach-exynos/exynos.c | 4 ++++
 2 files changed, 6 insertions(+)


From kgene at kernel.org  Thu Aug 13 11:52:49 2015
From: kgene at kernel.org (Kukjin Kim)
Date: Fri, 14 Aug 2015 03:52:49 +0900
Subject: [GIT PULL v2 4/5] Samsung cpufreq driver updates for v4.3
In-Reply-To: <55CCE517.2070003@kernel.org>
References: <55CCE517.2070003@kernel.org>
Message-ID: <55CCE781.1090007@kernel.org>

The following changes since commit d770e558e21961ad6cfdf0ff7df0eb5d7d4f0754:

  Linux 4.2-rc1 (2015-07-05 11:01:52 -0700)

are available in the git repository at:

  git://git.kernel.org/pub/scm/linux/kernel/git/kgene/linux-samsung.git
tags/samsung-late-cpufreq-driver

for you to fetch changes up to 5e3863a74fb70d6a432504ba2fa16a998cd3736b:

  cpufreq: exynos: Remove unselectable rule for arm-exynos-cpufreq.o
(2015-08-14 02:36:33 +0900)

----------------------------------------------------------------
Samsung cpufreq driver updates for v4.3

- remove exynos4 SoCs and exynos5250 specific cpufreq driver support
  and unselectable rule for arm-exynos-cpufreq.o because of supporting
  generic cpufreq driver for the exynos SoCs

* Note this is depending on tags/samsung-clk-driver, tags/samsung-soc
  and tags/samsung-late-dt

----------------------------------------------------------------
Bartlomiej Zolnierkiewicz (2):
      cpufreq: exynos: remove exynos5250 specific cpufreq driver support
      cpufreq: exynos: remove Exynos4x12 specific cpufreq driver support

Jonas Rabenstein (1):
      cpufreq: exynos: Remove unselectable rule for arm-exynos-cpufreq.o

 drivers/cpufreq/Kconfig.arm          |  49 --------
 drivers/cpufreq/Makefile             |   4 -
 drivers/cpufreq/exynos-cpufreq.c     | 237
-----------------------------------
 drivers/cpufreq/exynos-cpufreq.h     |  89 -------------
 drivers/cpufreq/exynos4x12-cpufreq.c | 236
----------------------------------
 drivers/cpufreq/exynos5250-cpufreq.c | 210 -------------------------------
 6 files changed, 825 deletions(-)
 delete mode 100644 drivers/cpufreq/exynos-cpufreq.c
 delete mode 100644 drivers/cpufreq/exynos-cpufreq.h
 delete mode 100644 drivers/cpufreq/exynos4x12-cpufreq.c
 delete mode 100644 drivers/cpufreq/exynos5250-cpufreq.c


From kgene at kernel.org  Thu Aug 13 11:53:51 2015
From: kgene at kernel.org (Kukjin Kim)
Date: Fri, 14 Aug 2015 03:53:51 +0900
Subject: [GIT PULL v2 5/5] Samsung defconfig updates for v4.3
In-Reply-To: <55CCE517.2070003@kernel.org>
References: <55CCE517.2070003@kernel.org>
Message-ID: <55CCE7BF.2070407@kernel.org>

The following changes since commit d770e558e21961ad6cfdf0ff7df0eb5d7d4f0754:

  Linux 4.2-rc1 (2015-07-05 11:01:52 -0700)

are available in the git repository at:

  git://git.kernel.org/pub/scm/linux/kernel/git/kgene/linux-samsung.git
tags/samsung-defconfig-new

for you to fetch changes up to 2b347c6494cbc6bfdc81b5201b8aa34afb2c3500:

  ARM: exynos_defconfig: Enable cpufreq-dt driver (2015-08-12 08:17:31
+0900)

----------------------------------------------------------------
Samsung defconfig updates for v4.3

- for exynos_defconfig
  : enable SND_SOC_ODROIDX2 and SND_SIMPLE_CARD for
    Odroid-XU3 to use max98090 audio codec
  : enalbe SENSORS_NTC_THERMISTOR for Peach boards
  : enable cpufreq-dt driver with ONDEMAND governor
    for Exynos SoCs 3250, 4210, 4212, 4412 and 5250

- for multi_v7_defconfig:
  : remove SAMSUNG_USB2PHY and SAMSUNG_USB3PHY are not used now
  : enable SENSORS_NTC_THERMISTOR and EXYNOS_ADC for Peach boards
  : enable REGULATOR_MAX77802 for Peach boards

----------------------------------------------------------------
Anand Moon (1):
      ARM: exynos_defconfig: Enable CONFIG_SND_SOC_ODROIDX2 for Odroid-XU3

Javier Martinez Canillas (4):
      ARM: multi_v7_defconfig: Remove old Samsung USB PHY configs
      ARM: multi_v7_defconfig: Enable NTC Thermistors support
      ARM: exynos_defconfig: Enable NTC Thermistors support
      ARM: multi_v7_defconfig: Enable max77802 regulator

Krzysztof Kozlowski (1):
      ARM: exynos_defconfig: Enable cpufreq-dt driver

 arch/arm/configs/exynos_defconfig   | 5 +++++
 arch/arm/configs/multi_v7_defconfig | 5 +++--
 2 files changed, 8 insertions(+), 2 deletions(-)


From linux at horizon.com  Thu Aug 13 12:09:25 2015
From: linux at horizon.com (George Spelvin)
Date: 13 Aug 2015 15:09:25 -0400
Subject: enabling libgcc for 64-bit divisions,
 was Re: PROBLEM: XFS on ARM corruption 'Structure needs cl
In-Reply-To: <CA+55aFw9-sN0nHn-ohdhSEt9i-mUjXN3fBj+dXLg56jgsOwgDw@mail.gmail.com>
Message-ID: <20150813190925.16478.qmail@ns.horizon.com>

>> On x86, the case that msword >= divsor causes a divide exception
>> (divide ba generalization of divide by zero), so it's tempting
>> to do the same sort of "assume no trap and fix up in the handler"
>> trick as <asm/uaccess.h>.

> That would be horrible. One of the reasonably common cases of do_div()
> is for printing out numbers. And they are often in the 4G+ range..

Actually, printing numbers is *not* such an instance; I've had my fingers
in lib/vsprintf.c, and since the divisor is constant, it uses reciprocal
multiplies.

The only instance of do_div in lib/vsprintf.c is in a version of put_dec()
which is used only if BITS_PER_LONG == 64.  If bits_per_long == 32,
it uses a neat hack due to Douglas Jones which avoids using divide
instructions entirely!

(Commit 133fd9f5cd if you are curious.)


The hot paths with 64-bit results are in the block layer and RAID
code, and that's why I wasn't seriously suggesting replacing *all*
instances; it was more of a static code size diet hack.

(It's also not likely worth the maintenance burden of the additional
code subtlety.  "Tempting" is not necessarily a good idea.)


From sboyd at codeaurora.org  Thu Aug 13 12:18:18 2015
From: sboyd at codeaurora.org (Stephen Boyd)
Date: Thu, 13 Aug 2015 12:18:18 -0700
Subject: [PATCH 9/9] ARM: smp: Add runtime PM support for CPU hotplug
In-Reply-To: <20150813160038.GP52339@linaro.org>
References: <1438731339-58317-1-git-send-email-lina.iyer@linaro.org>
 <1438731339-58317-10-git-send-email-lina.iyer@linaro.org>
 <20150812234756.GO26614@codeaurora.org>
 <20150813160038.GP52339@linaro.org>
Message-ID: <20150813191818.GT26614@codeaurora.org>

On 08/13, Lina Iyer wrote:
> On Wed, Aug 12 2015 at 17:47 -0600, Stephen Boyd wrote:
> >On 08/04, Lina Iyer wrote:
> 
> >>+
> >> 	ret = platform_cpu_disable(cpu);
> >> 	if (ret)
> >> 		return ret;
> >>@@ -272,6 +275,13 @@ void __ref cpu_die(void)
> >> {
> >> 	unsigned int cpu = smp_processor_id();
> >>
> >>+	/*
> >>+	 * We dont need the CPU device anymore.
> >>+	 * Lets do this before IRQs are disabled to allow
> >>+	 * runtime PM to suspend the domain as well.
> >>+	 */
> >>+	pm_runtime_put_sync(get_cpu_device(cpu));
> >
> >The two put calls is confusing. __cpu_disable() is called on the
> >CPU that's dying, and cpu_die() is called on the CPU that's doing
> >the takedown.
> >
> Is that right? Looking at the code and the comments, I can only imagine
> that they must be called on the CPU going down. If thats not the case,
> then I need to fix this.
> 
> >That would be two decrements but only one increment
> >in secondary_start_kernel()? How is this properly balanced?
> >
> I dont see __cpu_disable() ending up at cpu_die(). These seem two
> different exit points. I will check again.

Yeah I suspect we want a single call in __cpu_disable() so that
it runs on the CPU that's being hotplugged out.

> 
> >>+
> >> 	idle_task_exit();
> >>
> >> 	local_irq_disable();
> >>@@ -401,6 +412,11 @@ asmlinkage void secondary_start_kernel(void)
> >> 	local_irq_enable();
> >> 	local_fiq_enable();
> >>
> >>+	/* We are running, enable runtime PM for the CPU. */
> >>+	cpu_dev = get_cpu_device(cpu);
> >>+	if (cpu_dev)
> >>+		pm_runtime_get_sync(cpu_dev);
> >
> >Also, where would the dev->power.irq_safe flag be set if we
> >aren't using the genpd DT stuff? It looks like we're going to
> >start causing warnings on devices that don't have the DT magic.
> >
> Not necessarily. I have added _get and _put at points, when the
> interrupts are still enabled. So there should not be a need for the CPU
> devices to be IRQ safe. They will operate as regular devices. If they
> are attached to a non-IRQ safe domain, they would effect power savings
> on the domain.

What about preemption? Preemption is disabled in __cpu_disable()
and secondary_start_kernel() where this patch is calling
pm_runtime_{get,put}_sync(). That should still trigger a warning
with the might_sleep() inside the runtime PM functions if we
haven't set the irq_safe flag.

-- 
Qualcomm Innovation Center, Inc. is a member of Code Aurora Forum,
a Linux Foundation Collaborative Project


From stuart.yoder at freescale.com  Thu Aug 13 12:24:00 2015
From: stuart.yoder at freescale.com (Stuart Yoder)
Date: Thu, 13 Aug 2015 19:24:00 +0000
Subject: [RFC] arm64: defconfig: enable 48-bit VA by default
In-Reply-To: <CAKv+Gu-SH7MjkrgevfcUurPc7iQm+11cntfEo84opkqQoN2YPQ@mail.gmail.com>
References: <CY1PR0301MB07488D6DC5F0B171D6B290E187830@CY1PR0301MB0748.namprd03.prod.outlook.com>
 <55B0E1AD.60409@arm.com>
 <BY2PR0301MB0743CBCFC5476E39A5D1EC0B878C0@BY2PR0301MB0743.namprd03.prod.outlook.com>
 <CAKv+Gu9LHBd7wM6P4H0X5WigzDETtpr2++_Ebo=adg5QtTOW2w@mail.gmail.com>
 <BY2PR0301MB074300C5F31701D9211827F0878C0@BY2PR0301MB0743.namprd03.prod.outlook.com>
 <20150730101358.GA30796@e104818-lin.cambridge.arm.com>
 <CY1PR0301MB074850E27D5D298D1B8495D2878B0@CY1PR0301MB0748.namprd03.prod.outlook.com>
 <20150730161210.GE407@e104818-lin.cambridge.arm.com>
 <CY1PR0301MB0748FA3A10AFA9BFC1AB0A39878B0@CY1PR0301MB0748.namprd03.prod.outlook.com>
 <CAKv+Gu-Wbv3J9-2KbXrz_3W_=VXChrD+REo1-q1Ns_=RUM1BFw@mail.gmail.com>
 <BY2PR0301MB07436AC9C8D023DC7C67DE3D87730@BY2PR0301MB0743.namprd03.prod.outlook.com>
 <CAKv+Gu-SH7MjkrgevfcUurPc7iQm+11cntfEo84opkqQoN2YPQ@mail.gmail.com>
Message-ID: <CY1PR0301MB07488764C02CCA3F653ED6A5877D0@CY1PR0301MB0748.namprd03.prod.outlook.com>


> -----Original Message-----
> From: Ard Biesheuvel [mailto:ard.biesheuvel at linaro.org]
> Sent: Saturday, August 08, 2015 3:21 AM
> To: Yoder Stuart-B08248
> Cc: Catalin Marinas; Mark Rutland; Marc Zyngier; Will Deacon; Newton Peter-RA3823; linux-arm-
> kernel at lists.infradead.org; Sun York-R58495
> Subject: Re: [RFC] arm64: defconfig: enable 48-bit VA by default
> 
> On 7 aug. 2015, at 21:01, Stuart Yoder <stuart.yoder at freescale.com> wrote:
> 
> >> Whether defconfig supports your platform optimally has nothing to do
> >> with that. Of course, we should deal with the unexpected memory layout
> >> gracefully, which is why Mark Rutland and myself proposed patches to
> >> fix the panic you reported. But in a development context, I think it
> >> is perfectly acceptable to simply load the kernel at 0x80_8000_0000,
> >> and be able to run defconfig fine while losing just 2 GB of your 16 GB
> >> at the low end.
> >
> > I've done this experiment-- loading/running the kernel at 0x80_8000_0000
> > and losing the lower 2GB of memory.  And in fact I can see the kernel
> > ignoring the low memory:
> >
> >   [    0.000000] Ignoring memory block 0x80000000 - 0x100000000
> >
> 
> Yes that looks correct
> 
> > However, this only works with 48-bit VA enabled.  With 39-bit VA
> > enabled the kernel crashes before the early console is working
> > and I see nothing.
> >
> 
> That may well be a kernel bug: the changes to allow 39-bit VA kernels
> to execute on systems whose memory is outside the 39-bit VA range was
> developed and tested on AMD Seattle only, which has its RAM at
> 0x80_0000_0000. But it is hard to be sure, of course, with no output
> at all ...
> 
> > Does the linear mapping we've been talking about just need to cover
> > all of _RAM_, or does it need to cover all of I/O as well in
> > the same mapping.
> >
> > In our case we have various SoC I/O devices, like the UART
> > in the space below 4 GB... at 0x0100_0000.
> >
> 
> The linear mapping only covers system RAM, so that should not matter at all.
> 
> > Before debugging further I want to check whether this should
> > work in theory.  I had the impression that the issue was
> > discontiguous RAM regions, and I/O was a separate issue.
> 
> Yes, it should work in theory. The linear region starts at the base of
> the kernel Image, and extends all the way up to the end of DRAM (14 GB
> in your case, IIRC)

An update on this... in my original test where the kernel did not run from
high memory I was using a 4.0.x kernel.  I re-tried with a 4.2-rc4 kernel
and it booted fine.  So, there is no kernel bug it in the latest kernel,
it appears.

Thanks,
Stuart

From lina.iyer at linaro.org  Thu Aug 13 12:27:13 2015
From: lina.iyer at linaro.org (Lina Iyer)
Date: Thu, 13 Aug 2015 13:27:13 -0600
Subject: [PATCH 5/9] ARM: common: Introduce PM domains for CPUs/clusters
In-Reply-To: <55CCD35C.4000901@arm.com>
References: <1438731339-58317-1-git-send-email-lina.iyer@linaro.org>
 <1438731339-58317-6-git-send-email-lina.iyer@linaro.org>
 <CAL_JsqK67=DTtjZwwnonObLDjLbahkREfm0RvyXVV95bhR-d4Q@mail.gmail.com>
 <20150813150154.GB13356@red-moon>
 <20150813154503.GO52339@linaro.org> <55CCD35C.4000901@arm.com>
Message-ID: <20150813192713.GA84868@linaro.org>

On Thu, Aug 13 2015 at 11:26 -0600, Sudeep Holla wrote:
>
>
>On 13/08/15 16:45, Lina Iyer wrote:
>>On Thu, Aug 13 2015 at 09:01 -0600, Lorenzo Pieralisi wrote:
>>>On Thu, Aug 06, 2015 at 04:14:51AM +0100, Rob Herring wrote:
>>>>On Tue, Aug 4, 2015 at 6:35 PM, Lina Iyer <lina.iyer at linaro.org> wrote:
>
>[..]
>
>>>>
>>>>>+ARM CPU Power domains
>>>>>+
>>>>>+The device tree allows describing of CPU power domains in a SoC. In ARM SoC,
>>>>>+CPUs may be grouped as clusters. A cluster may have CPUs, GIC, Coresight,
>>>>>+caches, VFP and power controller and other peripheral hardware. Generally,
>>>>>+when the CPUs in the cluster are idle/suspended, the shared resources may also
>>>>>+be suspended and resumed before any of the CPUs resume execution.
>>>>>+
>>>>>+CPUs are the defined as the PM domain consumers and there is a PM domain
>>>>>+provider for the CPUs. Bindings for generic PM domains (genpd) is described in
>>>>>+[1].
>>>>>+
>>>>>+The ARM CPU PM domain follows the same binding convention as any generic PM
>>>>>+domain. Additional binding properties are -
>>>>>+
>>>>>+- compatible:
>>>>>+       Usage: required
>>>>>+       Value type: <string>
>>>>>+       Definition: Must also have
>>>>>+                       "arm,pd"
>>>>>+               inorder to initialize the genpd provider as ARM CPU PM domain.
>>>>
>>>>A compatible string should represent a particular h/w block. If it is
>>>>generic, it should represent some sort of standard programming
>>>>interface (e.g, AHCI, EHCI, etc.). This doesn't seem to be either and
>>>>is rather just a mapping of what "driver" you want to use.
>>>>
>>>>I would expect that identifying a cpu's or cluster's power domain
>>>>would be done by a phandle between the cpu/cluster node and power
>>>>domain node. But I've not really looked at the power domain bindings
>>>>so who knows.
>>>
>>>I would expect the same, meaning that a cpu node, like any other device
>>>node would have a phandle pointing at the respective HW power domain.
>>>
>>CPUs have phandles to their domains. That is how the relationship
>>between the domain provider (power-controller) and the consumer (CPU) is
>>established.
>>
>>>I do not really understand why we want a "generic" CPU power domain, what
>>>purpose does it serve ? Creating a collection of cpu devices that we
>>>can call "cluster" ?
>>>
>>Nope, not for calling a cluster, a cluster :)
>>
>>This compatible is used to define a generic behavior of the CPU domain
>>controller (in addition to the platform specific behavior of the domain
>>power controller). The kernel activities for such power controller are
>>generally the same which otherwise would be repeated across platforms.
>
>Having gone through this series and the one using it[1], the only common
>activity is just cluster pm notifiers. Other than that it's just
>creating indirection for now. The scenario might change in future, but
>for now it seems unnecessary.
>
Not sure, what seems unnecessary to you. Platforms do have to send
cluster PM notifications, and they have to duplicate reference counting.
Also PM domain framework allows hierarchy which is quite desirable to
power down parts of the SoC that are powered on or have to clocked high,
until the CPU is running.

Cluster PM notifications are just one aspect of this that we currently
handle in the first submission. The patchset as a whole provides a way
to determine in Linux the last man down and the first man up and carry
out activities. There are a bunch of things that are done to power save
when the last man goes down - Turn off debuggers, switch off PLLs,
reduce bus clocks, flush caches amongst a few that I know of. Some of it
are platform specific and some of it arent. This patches provide the way
for both of them to be done easily. The CPU runtime PM and PM domains as
a framework, closely track what the hardware does.

Mentioned in an other mail in this thread, is also an option to
determine the cluster flush state and use it in conjunction with PSCI to
do OS-Initiated cluster power down.

>Also if you look at the shmobile power controller driver, it covers all
>the devices including CPUs unlike QCOM power controller which handles
>only CPU. Yes we can skip CPU genpd creation there only for CPU, IMO
>creating the power domains should be part of power controller driver.
>
>You can add helper functions for all the ARM specific code that can be
>reused by multiple power controller drivers handling CPU/Cluster power
>domain.
>
Sure, some architectures may desire that. I have them addressed in [2].

>>An analogy to this would be the "arm,idle-state" that defines the DT
>>node as something that also depicts a generic cpuidle C state.
>>
>
>I tend to disagree. In idle-states, the nodes define that generic
>properties and they can be parsed in a generic way. That's not the case
>here. Each power controller binding differs.
>
Yes, may be we will have common elements like latency, residency of
powering on/off a domain that a genpd governor can utilize in
determining if its worth powering off the domain or not.

>Yes the generic compatible might be useful to identify that this power
>domain handles CPU/Cluster, but there will be more power controller
>specific things compared to generic code.
>
Agreed, not debating that. Power controller is very SoC specific, but
not debuggers, GIC, caches, buses etc. Many SoCs have almost similiar
needs for many of these supplemental hardware to the CPUs and trend
seems to be generalizing on many of these components.

Thanks,
Lina

>[1] http://www.spinics.net/lists/arm-kernel/msg437304.html
[2] http://www.spinics.net/lists/arm-kernel/msg438971.html


From lina.iyer at linaro.org  Thu Aug 13 13:12:48 2015
From: lina.iyer at linaro.org (Lina Iyer)
Date: Thu, 13 Aug 2015 14:12:48 -0600
Subject: [PATCH v2 1/2] ARM: common: Introduce PM domains for CPUs/clusters
In-Reply-To: <CAL_JsqLcSs79bnj4ELN0uiwJ6gxt46PghxvuGQ7prkq-4gLKhg@mail.gmail.com>
References: <CAL_JsqLhHy5gO=usm1HLf8h6iz_5FguCDo-Qz2Km+XEwaCODUA@mail.gmail.com>
 <1439406024-41893-1-git-send-email-lina.iyer@linaro.org>
 <CAL_JsqLcSs79bnj4ELN0uiwJ6gxt46PghxvuGQ7prkq-4gLKhg@mail.gmail.com>
Message-ID: <20150813201248.GB84868@linaro.org>

On Thu, Aug 13 2015 at 11:29 -0600, Rob Herring wrote:
>On Wed, Aug 12, 2015 at 2:00 PM, Lina Iyer <lina.iyer at linaro.org> wrote:
>> Define and add Generic PM domains (genpd) for CPU clusters. Many new
>> SoCs group CPUs as clusters. Clusters share common resources like GIC,
>> power rail, caches, VFP, Coresight etc. When all CPUs in the cluster are
>> idle, these shared resources may also be put in their idle state.
>>
>> The idle time between the last CPU entering idle and a CPU resuming
>> execution is an opportunity for these shared resources to be powered
>> down. Generic PM domain provides a framework for defining such power
>> domains and attach devices to the domain. When the devices in the domain
>> are idle at runtime, the domain would also be suspended and resumed
>> before the first of the devices resume execution.
>>
>> We define a generic PM domain for each cluster and attach CPU devices in
>> the cluster to that PM domain. The DT definitions for the SoC describe
>> this relationship. Genpd callbacks for power_on and power_off can then
>> be used to power up/down the shared resources for the domain.
>>
>> Cc: Stephen Boyd <sboyd at codeaurora.org>
>> Cc: Kevin Hilman <khilman at linaro.org>
>> Cc: Ulf Hansson <ulf.hansson at linaro.org>
>> Cc: Catalin Marinas <catalin.marinas at arm.com>
>> Cc: Daniel Lezcano <daniel.lezcano at linaro.org>
>> Cc: Mark Rutland <mark.rutland at arm.com>
>> Cc: Lorenzo Pieralisi <lorenzo.pieralisi at arm.com>
>> Signed-off-by: Kevin Hilman <khilman at linaro.org>
>> Signed-off-by: Lina Iyer <lina.iyer at linaro.org>
>> ---
>> Changes since v1:
>>
>> - Function name changes and split out common code
>> - Use cpu,pd for now. Removed references to ARM. Open to recommendations.
>> - Still located in arch/arm/common/. May move to a more appropriate location.
>> - Platform drivers can directly call of_init_cpu_domain() without using
>>   compatibles.
>> - Now maintains a list of CPU PM domains.
>
>[...]
>
>> +static int __init of_pm_domain_attach_cpus(void)
>> +{
>> +       int cpuid, ret;
>> +
>> +       /* Find any CPU nodes with a phandle to this power domain */
>> +       for_each_possible_cpu(cpuid) {
>> +               struct device *cpu_dev;
>> +               struct of_phandle_args pd_args;
>> +
>> +               cpu_dev = get_cpu_device(cpuid);
>> +               if (!cpu_dev) {
>> +                       pr_warn("%s: Unable to get device for CPU%d\n",
>> +                                       __func__, cpuid);
>> +                       return -ENODEV;
>> +               }
>> +
>> +               /*
>> +                * We are only interested in CPUs that can be attached to
>> +                * PM domains that are cpu,pd compatible.
>> +                */
>
>Under what conditions would the power domain for a cpu not be cpu,pd compatible?
>
Mostly never. But I dont want to assume and attach a CPU to its domain
that I am not concerned with.

>Why can't the driver handling the power domain register with gen_pd
>and the cpu_pd as the driver is going to be aware of which domains are
>for cpus.
They could and like Renesas they would. They could have an intricate
hierarchy of domains that they may want to deal with in their platform
drivers. Platforms could define the CPU devices as IRQ-safe and attach
it to their domains. Ensure the reference count of the online and
running CPUs are correct and they are good to go. They also would attach
the CPU devices to the domain and everything would work as they would
here. Its just repeated code across platforms that we are trying to
avoid.

>While there could be h/w such that all power domains within
>a chip have a nice uniform programming model, I'd guess that is the
>exception, not the rule. First, chips I have worked on were not that
>way. CPU related and peripheral related domains are handled quite
>differently. 
>
Agreed. These are very SoC specific components and would require
platform specific programming. But most SoCs, would need to do many
other things like suspending debuggers, reducing clocks, GIC save and
restore, cluster state determination etc that are only getting more
generalized. We have generalized ARM CPU idle, I see this as the
platform for the next set of power saving in an SoC.

>Second, often the actions on the CPU power domains don't
>take effect until a WFI, so you end up with a different programming
>sequence.
>
How so? The last core going down (in this case, when the domain is
suspended the last core is the last device that does a _put() on the
domain) would determine and perform the power domain's programming
sequence, in the context of the last CPU. A sequence that would only be
effected in hardware when the the CPU executes WFI. I dont see why it
would be any different than how it is today.

Thanks,
Lina


From manabian at gmail.com  Thu Aug 13 13:43:11 2015
From: manabian at gmail.com (Joachim Eastwood)
Date: Thu, 13 Aug 2015 22:43:11 +0200
Subject: [PATCH 1/2] clk: add lpc18xx creg clk driver
In-Reply-To: <20150811204127.31346.16729@quantum>
References: <1436651307-24098-1-git-send-email-manabian@gmail.com>
 <1436651307-24098-2-git-send-email-manabian@gmail.com>
 <20150811204127.31346.16729@quantum>
Message-ID: <CAGhQ9VwZaM_iWTkQYVTuTiyb6gCG2y6s8WFVySCHt7YHE1qbcA@mail.gmail.com>

On 11 August 2015 at 22:41, Michael Turquette <mturquette at baylibre.com> wrote:
> Hi Joachim,
>
> Quoting Joachim Eastwood (2015-07-11 14:48:26)
>> +static void __init lpc18xx_creg_clk_init(struct device_node *np)
>> +{
>> +       const char *clk_32khz_parent;
>> +       struct regmap *syscon;
>> +
>> +       syscon = syscon_node_to_regmap(np->parent);
>> +       if (IS_ERR(syscon)) {
>> +               pr_err("%s: syscon lookup failed\n", __func__);
>> +               return;
>> +       }
>> +
>> +       clk_32khz_parent = of_clk_get_parent_name(np, 0);
>> +
>> +       clk_creg[CREG_CLK_32KHZ] =
>> +               clk_register_creg_clk(&clk_creg_clocks[CREG_CLK_32KHZ],
>> +                                     &clk_32khz_parent, syscon);
>> +
>> +       clk_creg[CREG_CLK_1KHZ] =
>> +               clk_register_creg_clk(&clk_creg_clocks[CREG_CLK_1KHZ],
>> +                                     &clk_creg_clocks[CREG_CLK_32KHZ].name,
>> +                                     syscon);
>> +
>> +       of_clk_add_provider(np, of_clk_src_onecell_get, &clk_base_data);
>> +}
>> +CLK_OF_DECLARE(lpc18xx_creg_clk, "nxp,lpc1850-creg-clk", lpc18xx_creg_clk_init);
>
> I'll ask the same question that Stephen asked in your CCU/CGU driver
> series: is it necessary to use CLK_OF_DECLARE here or can you use the
> platform device model?

The 32 kHz clock from the CREG block is a clock parent to the CGU
block so it's possible that it will required early. This is all
depends on how the boot loader initially configures the CGU.

Currently in the DTS for lpc18xx cgu it has:
clocks = <&xtal>, <&xtal32>, <...>;
xtal32 is just a temporary placeholder until the CREG clock is in place.


Note that while it's possible to use the 32k clock together with PLL0
to generate the main CPU bus clock I doubt it will be common
configuration. It is however fully possible to do.


regards,
Joachim Eastwood


From eric at anholt.net  Thu Aug 13 13:44:03 2015
From: eric at anholt.net (Eric Anholt)
Date: Thu, 13 Aug 2015 13:44:03 -0700
Subject: [PATCH 3/7] drm/vc4: Add KMS support for Raspberry Pi.
In-Reply-To: <20150813075141.GX17734@phenom.ffwll.local>
References: <1439427380-2436-1-git-send-email-eric@anholt.net>
 <1439427380-2436-4-git-send-email-eric@anholt.net>
 <20150813075141.GX17734@phenom.ffwll.local>
Message-ID: <87d1yqq5po.fsf@eliezer.anholt.net>

Daniel Vetter <daniel at ffwll.ch> writes:

> On Wed, Aug 12, 2015 at 05:56:16PM -0700, Eric Anholt wrote:
>> This is the start of a full VC4 driver.  Right now this just supports
>> configuring the display using a pre-existing video mode (because
>> changing the pixel clock isn't available yet, and doesn't work when it
>> is).  However, this is enough for fbcon and bringing up X using
>> xf86-video-modesetting.
>> 
>> Signed-off-by: Eric Anholt <eric at anholt.net>
>> ---
>>  drivers/gpu/drm/Kconfig           |   2 +
>>  drivers/gpu/drm/Makefile          |   1 +
>>  drivers/gpu/drm/vc4/Kconfig       |  14 +
>>  drivers/gpu/drm/vc4/Makefile      |  18 ++
>>  drivers/gpu/drm/vc4/vc4_bo.c      |  54 ++++
>>  drivers/gpu/drm/vc4/vc4_crtc.c    | 583 ++++++++++++++++++++++++++++++++++
>>  drivers/gpu/drm/vc4/vc4_debugfs.c |  38 +++
>>  drivers/gpu/drm/vc4/vc4_drv.c     | 249 +++++++++++++++
>>  drivers/gpu/drm/vc4/vc4_drv.h     | 123 +++++++
>>  drivers/gpu/drm/vc4/vc4_hdmi.c    | 651 ++++++++++++++++++++++++++++++++++++++
>>  drivers/gpu/drm/vc4/vc4_hvs.c     | 172 ++++++++++
>>  drivers/gpu/drm/vc4/vc4_kms.c     |  84 +++++
>>  drivers/gpu/drm/vc4/vc4_plane.c   | 320 +++++++++++++++++++
>>  drivers/gpu/drm/vc4/vc4_regs.h    | 562 ++++++++++++++++++++++++++++++++
>>  14 files changed, 2871 insertions(+)
>>  create mode 100644 drivers/gpu/drm/vc4/Kconfig
>>  create mode 100644 drivers/gpu/drm/vc4/Makefile
>>  create mode 100644 drivers/gpu/drm/vc4/vc4_bo.c
>>  create mode 100644 drivers/gpu/drm/vc4/vc4_crtc.c
>>  create mode 100644 drivers/gpu/drm/vc4/vc4_debugfs.c
>>  create mode 100644 drivers/gpu/drm/vc4/vc4_drv.c
>>  create mode 100644 drivers/gpu/drm/vc4/vc4_drv.h
>>  create mode 100644 drivers/gpu/drm/vc4/vc4_hdmi.c
>>  create mode 100644 drivers/gpu/drm/vc4/vc4_hvs.c
>>  create mode 100644 drivers/gpu/drm/vc4/vc4_kms.c
>>  create mode 100644 drivers/gpu/drm/vc4/vc4_plane.c
>>  create mode 100644 drivers/gpu/drm/vc4/vc4_regs.h
>
> Made a quick pass and found a few things to update to latest drm
> developments. Of course didn't look at the hardware details since no clue,
> but looks really nice overall.
> -Daniel

If you have anything about the hardware that you were curious about, I'd
be interested in trying to explain them in the comments to the extent
that I can.  It's unfortunate that we haven't shipped docs for the
display side of things, but had to do a lot of reading of the verilog
just to get this far, anyway.

>> diff --git a/drivers/gpu/drm/Kconfig b/drivers/gpu/drm/Kconfig
>> index c46ca31..1730a76 100644
>> --- a/drivers/gpu/drm/Kconfig
>> +++ b/drivers/gpu/drm/Kconfig
>> @@ -240,3 +240,5 @@ source "drivers/gpu/drm/sti/Kconfig"
>>  source "drivers/gpu/drm/amd/amdkfd/Kconfig"
>>  
>>  source "drivers/gpu/drm/imx/Kconfig"
>> +
>> +source "drivers/gpu/drm/vc4/Kconfig"
>> diff --git a/drivers/gpu/drm/Makefile b/drivers/gpu/drm/Makefile
>> index 5713d05..b991ac5 100644
>> --- a/drivers/gpu/drm/Makefile
>> +++ b/drivers/gpu/drm/Makefile
>> @@ -42,6 +42,7 @@ obj-$(CONFIG_DRM_MGA)	+= mga/
>>  obj-$(CONFIG_DRM_I810)	+= i810/
>>  obj-$(CONFIG_DRM_I915)  += i915/
>>  obj-$(CONFIG_DRM_MGAG200) += mgag200/
>> +obj-$(CONFIG_DRM_VC4)  += vc4/
>>  obj-$(CONFIG_DRM_CIRRUS_QEMU) += cirrus/
>>  obj-$(CONFIG_DRM_SIS)   += sis/
>>  obj-$(CONFIG_DRM_SAVAGE)+= savage/
>> diff --git a/drivers/gpu/drm/vc4/Kconfig b/drivers/gpu/drm/vc4/Kconfig
>> new file mode 100644
>> index 0000000..130cc94
>> --- /dev/null
>> +++ b/drivers/gpu/drm/vc4/Kconfig
>> @@ -0,0 +1,14 @@
>> +config DRM_VC4
>> +	tristate "Broadcom VC4 Graphics"
>> +	depends on ARCH_BCM2835
>> +	depends on DRM
>> +	select DRM_KMS_HELPER
>> +	select DRM_KMS_FB_HELPER
>> +	select DRM_KMS_CMA_HELPER
>
> drm-misc/linux-next already has Archit's patches to enable/disable fbdev
> in the core code, so you don't need to bother about these selects here any
> more, it'll no-op out if drm fbdev emulation isn't enabled. Since you're
> reusing cma fbdev helpers I don't think there's any need for other changes
> because of this.

It sounds like I should rebase on that, then?

>> +	help
>> +	  Choose this option if you have a system that has a Broadcom
>> +	  VC4 GPU, such as the Raspberry Pi or other BCM2708/BCM2835.
>> +
>> +	  This driver requires that "avoid_warnings=2" be present in
>> +	  the config.txt for the firmware, to keep it from smashing
>> +	  our display setup.
>> diff --git a/drivers/gpu/drm/vc4/Makefile b/drivers/gpu/drm/vc4/Makefile
>> new file mode 100644
>> index 0000000..4aa07ca
>> --- /dev/null
>> +++ b/drivers/gpu/drm/vc4/Makefile
>> @@ -0,0 +1,18 @@
>> +ccflags-y := -Iinclude/drm
>> +
>> +# Please keep these build lists sorted!
>> +
>> +# core driver code
>> +vc4-y := \
>> +	vc4_bo.o \
>> +	vc4_crtc.o \
>> +	vc4_drv.o \
>> +	vc4_kms.o \
>> +	vc4_hdmi.o \
>> +	vc4_hvs.o \
>> +	vc4_plane.o \
>> +	$()
>> +
>> +vc4-$(CONFIG_DEBUG_FS) += vc4_debugfs.o
>> +
>> +obj-$(CONFIG_DRM_VC4)  += vc4.o
>> diff --git a/drivers/gpu/drm/vc4/vc4_bo.c b/drivers/gpu/drm/vc4/vc4_bo.c
>> new file mode 100644
>> index 0000000..fee8cac
>> --- /dev/null
>> +++ b/drivers/gpu/drm/vc4/vc4_bo.c
>> @@ -0,0 +1,54 @@
>> +/*
>> + *  Copyright ? 2015 Broadcom
>> + *
>> + * 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.
>> + */
>> +
>> +/* DOC: VC4 GEM BO management support.
>> + *
>> + * The VC4 GPU architecture (both scanout and rendering) has direct
>> + * access to system memory with no MMU in between.  To support it, we
>> + * use the GEM CMA helper functions to allocate contiguous ranges of
>> + * physical memory for our BOs.
>> + */
>
> Since you're doing kerneldoc considered pulling it all into a new vc4
> section in the drm docbook template?

I hadn't found the docbook template.  Interesting.  I'll try to cook up
some general vc4 docs for that.  I think that could be a separate
commit, though?

>> +
>> +#include "vc4_drv.h"
>> +
>> +struct vc4_bo *vc4_bo_create(struct drm_device *dev, size_t size)
>> +{
>> +	struct drm_gem_cma_object *cma_obj;
>> +
>> +	cma_obj = drm_gem_cma_create(dev, size);
>> +	if (IS_ERR(cma_obj))
>> +		return NULL;
>> +	else
>> +		return to_vc4_bo(&cma_obj->base);
>> +}
>> +
>> +int vc4_dumb_create(struct drm_file *file_priv,
>> +		    struct drm_device *dev,
>> +		    struct drm_mode_create_dumb *args)
>> +{
>> +	int min_pitch = DIV_ROUND_UP(args->width * args->bpp, 8);
>> +	struct vc4_bo *bo = NULL;
>> +	int ret;
>> +
>> +	if (args->pitch < min_pitch)
>> +		args->pitch = min_pitch;
>> +
>> +	if (args->size < args->pitch * args->height)
>> +		args->size = args->pitch * args->height;
>> +
>> +	mutex_lock(&dev->struct_mutex);
>> +	bo = vc4_bo_create(dev, roundup(args->size, PAGE_SIZE));
>> +	mutex_unlock(&dev->struct_mutex);
>
> I'm on a struct_mutex crusade (trying to get rid of it in core and allow
> drivers to live without it). On a quick look there doesn't seem to be
> anything that needs struct_mutex here, so please just remove it. If there
> is indeed something vc4-internal you want to protect, please use your own
> driver-internal mutex (e.g. for drm_mm or command submission or whatever).
>
> btw the last bit in the drm core for modern drivers that needs
> struct_mutex is mmap_offset gem object lookup. I plan to replace that with
> kref_get_unless_zero trickery, which would make the core and a lot of
> drivers struct_mutex free and so relegate it mostly to a legacy role (and
> can be forgotten).

Struct mutex is here because this code is from the V3D series, with the
in-kernel BO cache ripped out (it turns out that the CMA allocator is
slow, and you can't just userspace cache since we have to do allocations
within the kernel to the tune of a couple per draw and that's too much).

I'll pull the mutex calls out for now until the cache stuff is
submitted.

>> +static bool vc4_crtc_mode_fixup(struct drm_crtc *crtc,
>> +				const struct drm_display_mode *mode,
>> +				struct drm_display_mode *adjusted_mode)
>> +{
>> +	return true;
>> +}
>
> mode_fixup on crtcs is optional since 840bfe953384a and I just merged a
> patch to make it optional for encoders too (when using atomic helpers
> which you do). You can remove them both.

Great!  It felt like there was a *lot* of boilerplate when I was first
writing this stuff, and things are way better than they used to be.

>> +static int vc4_drm_load(struct drm_device *dev, unsigned long flags)
>> +{
>> +	struct vc4_dev *vc4;
>> +	int ret;
>> +
>> +	vc4 = devm_kzalloc(dev->dev, sizeof(*vc4), GFP_KERNEL);
>> +	if (!vc4)
>> +		return -ENOMEM;
>> +
>> +	dev_set_drvdata(dev->dev, dev);
>> +	vc4->dev = dev;
>> +	dev->dev_private = vc4;
>> +
>> +	drm_mode_config_init(dev);
>> +
>> +	ret = component_bind_all(dev->dev, dev);
>> +	if (ret)
>> +		return ret;
>> +
>> +	vc4_kms_load(dev);
>> +
>> +	return 0;
>> +}
>
> ->load has backwards init ordering (we register public interfaces before
> calling it, yay) because backwards compat. Hence deprecated, please use
> drm_dev_alloc(); ... driver init including drm_dev_set_unique();
> drm_dev_register(); instead and drop ->load.

Will do.
-------------- next part --------------
A non-text attachment was scrubbed...
Name: signature.asc
Type: application/pgp-signature
Size: 818 bytes
Desc: not available
URL: <http://lists.infradead.org/pipermail/linux-arm-kernel/attachments/20150813/dca1b430/attachment.sig>

From manabian at gmail.com  Thu Aug 13 13:55:48 2015
From: manabian at gmail.com (Joachim Eastwood)
Date: Thu, 13 Aug 2015 22:55:48 +0200
Subject: [PATCH V3 0/5] clk: support clocks which requires parent clock on
 during operation
In-Reply-To: <1438089585-30103-1-git-send-email-aisheng.dong@freescale.com>
References: <1438089585-30103-1-git-send-email-aisheng.dong@freescale.com>
Message-ID: <CAGhQ9VyoepPsoLhuqFz397UnrM+n4SH0rp5Y3xfTQYvDXr=APw@mail.gmail.com>

Hi Dong,

On 28 July 2015 at 15:19, Dong Aisheng <aisheng.dong at freescale.com> wrote:
> This patch series adds support in clock framework for clocks which operations
> requires its parent clock is on.
>
> Such clock type is initially met on Freescale i.MX7D platform that all clocks
> operations, including enable/disable, rate change and re-parent, requires its
> parent clock on. No sure if any other SoC has the similar clock type.

Just noticed this patch set.

One of clock-controller blocks (CCU) on lpc18xx has a similar
requirement. The CCU is clock fanout block with gates and the gate
registers can not be accessed if the base (parent) clock for the gate
is not running. Doing so causes the cpu to wedge.

The workaround I have locally is to check in the is_enabled gate op if
the parent is running or not. This works fine, but I am all for a more
generic solution in the clk framework.

I'll see if I can find the time to test your patch set. Thanks for
working on this.


regards,
Joachim Eastwood


From leoli at freescale.com  Thu Aug 13 13:58:01 2015
From: leoli at freescale.com (Li Yang)
Date: Thu, 13 Aug 2015 15:58:01 -0500
Subject: [PATCH v2] dmaengine: fsl-edma: add PM suspend/resume support
In-Reply-To: <1437469005-3162-1-git-send-email-yao.yuan@freescale.com>
References: <1437469005-3162-1-git-send-email-yao.yuan@freescale.com>
Message-ID: <CADRPPNQJi_x+mdQV=DEVuhCL_p6VOWcPiV3jzioeRdWgSW2w3g@mail.gmail.com>

On Tue, Jul 21, 2015 at 3:56 AM, Yuan Yao <yao.yuan at freescale.com> wrote:
> This add power management suspend/resume support for the fsl-edma
> driver.
>
> eDMA acted as a basic function used by others. What it needs to do is
> the two steps below to support power management.
>
> In fsl_edma_suspend_late:
> Check whether the DMA chan is idle and if it is not idle, stop PM
> operation.

You should try to quiesce the device on suspend instead of depending
on itself to be happen in idle and failing if it is not.

Regards,
Leo


From daniel at ffwll.ch  Thu Aug 13 14:17:55 2015
From: daniel at ffwll.ch (Daniel Vetter)
Date: Thu, 13 Aug 2015 23:17:55 +0200
Subject: [PATCH 3/7] drm/vc4: Add KMS support for Raspberry Pi.
In-Reply-To: <87d1yqq5po.fsf@eliezer.anholt.net>
References: <1439427380-2436-1-git-send-email-eric@anholt.net>
 <1439427380-2436-4-git-send-email-eric@anholt.net>
 <20150813075141.GX17734@phenom.ffwll.local>
 <87d1yqq5po.fsf@eliezer.anholt.net>
Message-ID: <20150813211755.GE17734@phenom.ffwll.local>

On Thu, Aug 13, 2015 at 01:44:03PM -0700, Eric Anholt wrote:
> Daniel Vetter <daniel at ffwll.ch> writes:
> 
> > On Wed, Aug 12, 2015 at 05:56:16PM -0700, Eric Anholt wrote:
> >> This is the start of a full VC4 driver.  Right now this just supports
> >> configuring the display using a pre-existing video mode (because
> >> changing the pixel clock isn't available yet, and doesn't work when it
> >> is).  However, this is enough for fbcon and bringing up X using
> >> xf86-video-modesetting.
> >> 
> >> Signed-off-by: Eric Anholt <eric at anholt.net>
> >> ---
> >>  drivers/gpu/drm/Kconfig           |   2 +
> >>  drivers/gpu/drm/Makefile          |   1 +
> >>  drivers/gpu/drm/vc4/Kconfig       |  14 +
> >>  drivers/gpu/drm/vc4/Makefile      |  18 ++
> >>  drivers/gpu/drm/vc4/vc4_bo.c      |  54 ++++
> >>  drivers/gpu/drm/vc4/vc4_crtc.c    | 583 ++++++++++++++++++++++++++++++++++
> >>  drivers/gpu/drm/vc4/vc4_debugfs.c |  38 +++
> >>  drivers/gpu/drm/vc4/vc4_drv.c     | 249 +++++++++++++++
> >>  drivers/gpu/drm/vc4/vc4_drv.h     | 123 +++++++
> >>  drivers/gpu/drm/vc4/vc4_hdmi.c    | 651 ++++++++++++++++++++++++++++++++++++++
> >>  drivers/gpu/drm/vc4/vc4_hvs.c     | 172 ++++++++++
> >>  drivers/gpu/drm/vc4/vc4_kms.c     |  84 +++++
> >>  drivers/gpu/drm/vc4/vc4_plane.c   | 320 +++++++++++++++++++
> >>  drivers/gpu/drm/vc4/vc4_regs.h    | 562 ++++++++++++++++++++++++++++++++
> >>  14 files changed, 2871 insertions(+)
> >>  create mode 100644 drivers/gpu/drm/vc4/Kconfig
> >>  create mode 100644 drivers/gpu/drm/vc4/Makefile
> >>  create mode 100644 drivers/gpu/drm/vc4/vc4_bo.c
> >>  create mode 100644 drivers/gpu/drm/vc4/vc4_crtc.c
> >>  create mode 100644 drivers/gpu/drm/vc4/vc4_debugfs.c
> >>  create mode 100644 drivers/gpu/drm/vc4/vc4_drv.c
> >>  create mode 100644 drivers/gpu/drm/vc4/vc4_drv.h
> >>  create mode 100644 drivers/gpu/drm/vc4/vc4_hdmi.c
> >>  create mode 100644 drivers/gpu/drm/vc4/vc4_hvs.c
> >>  create mode 100644 drivers/gpu/drm/vc4/vc4_kms.c
> >>  create mode 100644 drivers/gpu/drm/vc4/vc4_plane.c
> >>  create mode 100644 drivers/gpu/drm/vc4/vc4_regs.h
> >
> > Made a quick pass and found a few things to update to latest drm
> > developments. Of course didn't look at the hardware details since no clue,
> > but looks really nice overall.
> 
> If you have anything about the hardware that you were curious about, I'd
> be interested in trying to explain them in the comments to the extent
> that I can.  It's unfortunate that we haven't shipped docs for the
> display side of things, but had to do a lot of reading of the verilog
> just to get this far, anyway.

The only thing I spotted is that you right now only register a primary and
cursor plane. I guess the plan we once discussed about exposing piles of
planes for -modesetting accel isn't there yet?

But otherwise I really didn't go into the hardware details.

> >> diff --git a/drivers/gpu/drm/Kconfig b/drivers/gpu/drm/Kconfig
> >> index c46ca31..1730a76 100644
> >> --- a/drivers/gpu/drm/Kconfig
> >> +++ b/drivers/gpu/drm/Kconfig
> >> @@ -240,3 +240,5 @@ source "drivers/gpu/drm/sti/Kconfig"
> >>  source "drivers/gpu/drm/amd/amdkfd/Kconfig"
> >>  
> >>  source "drivers/gpu/drm/imx/Kconfig"
> >> +
> >> +source "drivers/gpu/drm/vc4/Kconfig"
> >> diff --git a/drivers/gpu/drm/Makefile b/drivers/gpu/drm/Makefile
> >> index 5713d05..b991ac5 100644
> >> --- a/drivers/gpu/drm/Makefile
> >> +++ b/drivers/gpu/drm/Makefile
> >> @@ -42,6 +42,7 @@ obj-$(CONFIG_DRM_MGA)	+= mga/
> >>  obj-$(CONFIG_DRM_I810)	+= i810/
> >>  obj-$(CONFIG_DRM_I915)  += i915/
> >>  obj-$(CONFIG_DRM_MGAG200) += mgag200/
> >> +obj-$(CONFIG_DRM_VC4)  += vc4/
> >>  obj-$(CONFIG_DRM_CIRRUS_QEMU) += cirrus/
> >>  obj-$(CONFIG_DRM_SIS)   += sis/
> >>  obj-$(CONFIG_DRM_SAVAGE)+= savage/
> >> diff --git a/drivers/gpu/drm/vc4/Kconfig b/drivers/gpu/drm/vc4/Kconfig
> >> new file mode 100644
> >> index 0000000..130cc94
> >> --- /dev/null
> >> +++ b/drivers/gpu/drm/vc4/Kconfig
> >> @@ -0,0 +1,14 @@
> >> +config DRM_VC4
> >> +	tristate "Broadcom VC4 Graphics"
> >> +	depends on ARCH_BCM2835
> >> +	depends on DRM
> >> +	select DRM_KMS_HELPER
> >> +	select DRM_KMS_FB_HELPER
> >> +	select DRM_KMS_CMA_HELPER
> >
> > drm-misc/linux-next already has Archit's patches to enable/disable fbdev
> > in the core code, so you don't need to bother about these selects here any
> > more, it'll no-op out if drm fbdev emulation isn't enabled. Since you're
> > reusing cma fbdev helpers I don't think there's any need for other changes
> > because of this.
> 
> It sounds like I should rebase on that, then?

Yeah probably simplest. I made a pull request for drm-misc and a tag and
cc'ed you on it so you have a baseline.

> >> +	help
> >> +	  Choose this option if you have a system that has a Broadcom
> >> +	  VC4 GPU, such as the Raspberry Pi or other BCM2708/BCM2835.
> >> +
> >> +	  This driver requires that "avoid_warnings=2" be present in
> >> +	  the config.txt for the firmware, to keep it from smashing
> >> +	  our display setup.
> >> diff --git a/drivers/gpu/drm/vc4/Makefile b/drivers/gpu/drm/vc4/Makefile
> >> new file mode 100644
> >> index 0000000..4aa07ca
> >> --- /dev/null
> >> +++ b/drivers/gpu/drm/vc4/Makefile
> >> @@ -0,0 +1,18 @@
> >> +ccflags-y := -Iinclude/drm
> >> +
> >> +# Please keep these build lists sorted!
> >> +
> >> +# core driver code
> >> +vc4-y := \
> >> +	vc4_bo.o \
> >> +	vc4_crtc.o \
> >> +	vc4_drv.o \
> >> +	vc4_kms.o \
> >> +	vc4_hdmi.o \
> >> +	vc4_hvs.o \
> >> +	vc4_plane.o \
> >> +	$()
> >> +
> >> +vc4-$(CONFIG_DEBUG_FS) += vc4_debugfs.o
> >> +
> >> +obj-$(CONFIG_DRM_VC4)  += vc4.o
> >> diff --git a/drivers/gpu/drm/vc4/vc4_bo.c b/drivers/gpu/drm/vc4/vc4_bo.c
> >> new file mode 100644
> >> index 0000000..fee8cac
> >> --- /dev/null
> >> +++ b/drivers/gpu/drm/vc4/vc4_bo.c
> >> @@ -0,0 +1,54 @@
> >> +/*
> >> + *  Copyright ? 2015 Broadcom
> >> + *
> >> + * 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.
> >> + */
> >> +
> >> +/* DOC: VC4 GEM BO management support.
> >> + *
> >> + * The VC4 GPU architecture (both scanout and rendering) has direct
> >> + * access to system memory with no MMU in between.  To support it, we
> >> + * use the GEM CMA helper functions to allocate contiguous ranges of
> >> + * physical memory for our BOs.
> >> + */
> >
> > Since you're doing kerneldoc considered pulling it all into a new vc4
> > section in the drm docbook template?
> 
> I hadn't found the docbook template.  Interesting.  I'll try to cook up
> some general vc4 docs for that.  I think that could be a separate
> commit, though?

Sure. Really just for yourself and other people hacking on this. btw
there's some work intel sponsors from collabora to improve kerneldoc
comments with automated hyperlinking, markdown and a few other things. But
unfortunately not yet merged.

> >> +
> >> +#include "vc4_drv.h"
> >> +
> >> +struct vc4_bo *vc4_bo_create(struct drm_device *dev, size_t size)
> >> +{
> >> +	struct drm_gem_cma_object *cma_obj;
> >> +
> >> +	cma_obj = drm_gem_cma_create(dev, size);
> >> +	if (IS_ERR(cma_obj))
> >> +		return NULL;
> >> +	else
> >> +		return to_vc4_bo(&cma_obj->base);
> >> +}
> >> +
> >> +int vc4_dumb_create(struct drm_file *file_priv,
> >> +		    struct drm_device *dev,
> >> +		    struct drm_mode_create_dumb *args)
> >> +{
> >> +	int min_pitch = DIV_ROUND_UP(args->width * args->bpp, 8);
> >> +	struct vc4_bo *bo = NULL;
> >> +	int ret;
> >> +
> >> +	if (args->pitch < min_pitch)
> >> +		args->pitch = min_pitch;
> >> +
> >> +	if (args->size < args->pitch * args->height)
> >> +		args->size = args->pitch * args->height;
> >> +
> >> +	mutex_lock(&dev->struct_mutex);
> >> +	bo = vc4_bo_create(dev, roundup(args->size, PAGE_SIZE));
> >> +	mutex_unlock(&dev->struct_mutex);
> >
> > I'm on a struct_mutex crusade (trying to get rid of it in core and allow
> > drivers to live without it). On a quick look there doesn't seem to be
> > anything that needs struct_mutex here, so please just remove it. If there
> > is indeed something vc4-internal you want to protect, please use your own
> > driver-internal mutex (e.g. for drm_mm or command submission or whatever).
> >
> > btw the last bit in the drm core for modern drivers that needs
> > struct_mutex is mmap_offset gem object lookup. I plan to replace that with
> > kref_get_unless_zero trickery, which would make the core and a lot of
> > drivers struct_mutex free and so relegate it mostly to a legacy role (and
> > can be forgotten).
> 
> Struct mutex is here because this code is from the V3D series, with the
> in-kernel BO cache ripped out (it turns out that the CMA allocator is
> slow, and you can't just userspace cache since we have to do allocations
> within the kernel to the tune of a couple per draw and that's too much).
> 
> I'll pull the mutex calls out for now until the cache stuff is
> submitted.

Yeah I suspected that's for later. If feasible it'd be great if you could
rearchtect it to use a driver-private lock, just to not grow another place
using it.

> >> +static bool vc4_crtc_mode_fixup(struct drm_crtc *crtc,
> >> +				const struct drm_display_mode *mode,
> >> +				struct drm_display_mode *adjusted_mode)
> >> +{
> >> +	return true;
> >> +}
> >
> > mode_fixup on crtcs is optional since 840bfe953384a and I just merged a
> > patch to make it optional for encoders too (when using atomic helpers
> > which you do). You can remove them both.
> 
> Great!  It felt like there was a *lot* of boilerplate when I was first
> writing this stuff, and things are way better than they used to be.

Just noticed that crtc->atomic_begin is optional too. btw if you spot
boilerplate somewhere else please raise it on irc, there's still a lot of
room for improvement for atomic helpers.
-Daniel
-- 
Daniel Vetter
Software Engineer, Intel Corporation
http://blog.ffwll.ch


From linux at arm.linux.org.uk  Thu Aug 13 14:29:36 2015
From: linux at arm.linux.org.uk (Russell King - ARM Linux)
Date: Thu, 13 Aug 2015 22:29:36 +0100
Subject: [PATCH 3/7] drm/vc4: Add KMS support for Raspberry Pi.
In-Reply-To: <87d1yqq5po.fsf@eliezer.anholt.net>
References: <1439427380-2436-1-git-send-email-eric@anholt.net>
 <1439427380-2436-4-git-send-email-eric@anholt.net>
 <20150813075141.GX17734@phenom.ffwll.local>
 <87d1yqq5po.fsf@eliezer.anholt.net>
Message-ID: <20150813212936.GT7557@n2100.arm.linux.org.uk>

On Thu, Aug 13, 2015 at 01:44:03PM -0700, Eric Anholt wrote:
> Struct mutex is here because this code is from the V3D series, with the
> in-kernel BO cache ripped out (it turns out that the CMA allocator is
> slow, and you can't just userspace cache since we have to do allocations
> within the kernel to the tune of a couple per draw and that's too much).

The CMA allocator is fast until you have pinned pages in its region,
where it becomes _very_ slow to do allocations, sometimes getting up
to the order of seconds.

The main culpret of this are GFP_HIGHUSER_MOVABLE allocations which
then pin the page.  It doesn't take many of those to make CMA really
inefficient.

The problem is that CMA doesn't get any information back from the
internal page migration about which pages couldn't be moved, so it
dumbly just tries incrementing the allocation by one page (subject
to alignment constraints) and retrying again - repeating over the
entire CMA region.  The bigger the region, the more time this takes.

-- 
FTTC broadband for 0.8mile line: currently at 10.5Mbps down 400kbps up
according to speedtest.net.


From laurent.pinchart at ideasonboard.com  Thu Aug 13 14:31:09 2015
From: laurent.pinchart at ideasonboard.com (Laurent Pinchart)
Date: Fri, 14 Aug 2015 00:31:09 +0300
Subject: [PATCH v2] ARM: shmobile: kzm9g dts: Use adxl345-specific
 compatible property
In-Reply-To: <CAMuHMdV0fqjJSjmYqP0uFa0x5ydc1iztu4za1Ufu7OMdhC29Ug@mail.gmail.com>
References: <1436180132-26190-1-git-send-email-geert+renesas@glider.be>
 <20150813000537.GD5221@verge.net.au>
 <CAMuHMdV0fqjJSjmYqP0uFa0x5ydc1iztu4za1Ufu7OMdhC29Ug@mail.gmail.com>
Message-ID: <10744920.2768uXkYtL@avalon>

On Thursday 13 August 2015 11:26:32 Geert Uytterhoeven wrote:
> On Thu, Aug 13, 2015 at 2:05 AM, Simon Horman <horms at verge.net.au> wrote:
> > On Wed, Jul 08, 2015 at 09:51:49AM +0900, Simon Horman wrote:
> >> On Tue, Jul 07, 2015 at 09:56:29AM +0300, Laurent Pinchart wrote:
> >>> On Tuesday 07 July 2015 09:26:21 Simon Horman wrote:
> >>>> On Mon, Jul 06, 2015 at 04:29:33PM +0300, Laurent Pinchart wrote:
> >>>>> On Monday 06 July 2015 12:55:32 Geert Uytterhoeven wrote:
> >>>>>> Replace the deprecated generic "adi,adxl34x" compatible value by
> >>>>>> the adxl345-specific "adi,adxl345" value, cfr. commit
> >>>>>> e465bf6fc55d5ce2 ("DT:
> >>>>>> i2c: Deprecate adi,adxl34x compatible string").
> >>>>>> 
> >>>>>> Signed-off-by: Geert Uytterhoeven <geert+renesas at glider.be>
> >>>>> 
> >>>>> Acked-by: Laurent Pinchart
> >>>>> <laurent.pinchart+renesas at ideasonboard.com>
> >>>>> 
> >>>>>> ---
> >>>>>> Depends on commit 3a38958d2477b718 ("Input: adxl34x - add OF
> >>>>>> match support"), which is in v4.2-rc1.
> >>>>>> 
> >>>>>> This is v2 of "ARM: shmobile: kzm9g dts: Add adxl345-specific
> >>>>>> compatible property".
> >>>> 
> >>>> It appears to me that this will cause a regression when booting old
> >>>> kernels with new dts blobs. For that reason think we should consider
> >>>> v1 of this change coupled with a schedule to remove use of the
> >>>> deprecated compat string.
> >>> 
> >>> That's the forward compatibility that Geert mentioned, is that really
> >>> an issue, especially on this board ?
> >> 
> >> I think it would be best to provide backwards compatibility unless there
> >> is a compelling reason not to.
> > 
> > I would like to revisit this discussion with a view to getting some
> > version of this patch queued up (yes I know I pushed back on it earlier in
> > this thread).
>
> I'm fine with applying v1.

And I'm quite unsurprisingly not, as I've asked for a v2.

The "adi,adxl34x" compatible string is deprecated. That means we still support 
it in the driver for device trees that haven't been updated, but it shouldn't 
be used forward by new device trees. That's why the device tree sources 
contained in the kernel shouldn't use it, especially given that they often 
serve as references for device trees shipped out of tree.

-- 
Regards,

Laurent Pinchart



From mathieu at codeaurora.org  Thu Aug 13 14:33:38 2015
From: mathieu at codeaurora.org (Mathieu Olivari)
Date: Thu, 13 Aug 2015 14:33:38 -0700
Subject: [PATCH 1/3] ARM: qcom: add SFPB nodes to IPQ806x dts
In-Reply-To: <1439501620-24073-1-git-send-email-mathieu@codeaurora.org>
References: <1439501620-24073-1-git-send-email-mathieu@codeaurora.org>
Message-ID: <1439501620-24073-2-git-send-email-mathieu@codeaurora.org>

Add one new node to the ipq806x.dtsi file to declare & register the
hardware spinlock devices. This mechanism is required to be used by
other drivers such as SMEM.

Signed-off-by: Mathieu Olivari <mathieu at codeaurora.org>
---
 arch/arm/boot/dts/qcom-ipq8064.dtsi | 12 ++++++++++++
 1 file changed, 12 insertions(+)

diff --git a/arch/arm/boot/dts/qcom-ipq8064.dtsi b/arch/arm/boot/dts/qcom-ipq8064.dtsi
index 9f727d8..ea7b959 100644
--- a/arch/arm/boot/dts/qcom-ipq8064.dtsi
+++ b/arch/arm/boot/dts/qcom-ipq8064.dtsi
@@ -67,6 +67,18 @@
 			clock-frequency = <32768>;
 			#clock-cells = <0>;
 		};
+
+		sfpb_mutex_block: syscon at 01200600 {
+			compatible = "syscon";
+			reg = <0x01200600 0x100>;
+		};
+
+		sfpb_mutex: sfpb-mutex {
+			compatible = "qcom,sfpb-mutex";
+			syscon = <&sfpb_mutex_block 4 4>;
+
+			#hwlock-cells = <1>;
+		};
 	};
 
 	soc: soc {
-- 
2.1.4



From mathieu at codeaurora.org  Thu Aug 13 14:33:37 2015
From: mathieu at codeaurora.org (Mathieu Olivari)
Date: Thu, 13 Aug 2015 14:33:37 -0700
Subject: [PATCH 0/3] qcom: Add SMEM MTD parser
Message-ID: <1439501620-24073-1-git-send-email-mathieu@codeaurora.org>

QCOM platforms such as IPQ806x are using SMEM to store their flash
layout. This patch set adds the DT nodes required to instanciate SMEM
on IPQ806x and add an MTD parser using it.

This change is based on the SMEM driver posted here:
*https://lkml.org/lkml/2015/7/27/1125

Mathieu Olivari (3):
  ARM: qcom: add SFPB nodes to IPQ806x dts
  ARM: qcom: add SMEM device node to IPQ806x dts
  mtd: add SMEM parser for QCOM platforms

 arch/arm/boot/dts/qcom-ipq8064.dtsi |  23 +++-
 drivers/mtd/Kconfig                 |   7 ++
 drivers/mtd/Makefile                |   1 +
 drivers/mtd/qcom_smem_part.c        | 224 ++++++++++++++++++++++++++++++++++++
 4 files changed, 254 insertions(+), 1 deletion(-)
 create mode 100644 drivers/mtd/qcom_smem_part.c

-- 
2.1.4



From mathieu at codeaurora.org  Thu Aug 13 14:33:39 2015
From: mathieu at codeaurora.org (Mathieu Olivari)
Date: Thu, 13 Aug 2015 14:33:39 -0700
Subject: [PATCH 2/3] ARM: qcom: add SMEM device node to IPQ806x dts
In-Reply-To: <1439501620-24073-1-git-send-email-mathieu@codeaurora.org>
References: <1439501620-24073-1-git-send-email-mathieu@codeaurora.org>
Message-ID: <1439501620-24073-3-git-send-email-mathieu@codeaurora.org>

SMEM is used on IPQ806x to store various board related information such
as boot device and flash partition layout. We'll declare it as a device
so we can make use of it thanks to the new SMEM soc driver.

Signed-off-by: Mathieu Olivari <mathieu at codeaurora.org>
---
 arch/arm/boot/dts/qcom-ipq8064.dtsi | 11 ++++++++++-
 1 file changed, 10 insertions(+), 1 deletion(-)

diff --git a/arch/arm/boot/dts/qcom-ipq8064.dtsi b/arch/arm/boot/dts/qcom-ipq8064.dtsi
index ea7b959..9ee9780 100644
--- a/arch/arm/boot/dts/qcom-ipq8064.dtsi
+++ b/arch/arm/boot/dts/qcom-ipq8064.dtsi
@@ -55,7 +55,7 @@
 			no-map;
 		};
 
-		smem at 41000000 {
+		smem: smem at 41000000 {
 			reg = <0x41000000 0x200000>;
 			no-map;
 		};
@@ -79,6 +79,15 @@
 
 			#hwlock-cells = <1>;
 		};
+
+		smem {
+			compatible = "qcom,smem";
+
+			memory-region = <&smem>;
+			reg = <0x41000000 0x4000>;
+
+			hwlocks = <&sfpb_mutex 3>;
+		};
 	};
 
 	soc: soc {
-- 
2.1.4



From mathieu at codeaurora.org  Thu Aug 13 14:33:40 2015
From: mathieu at codeaurora.org (Mathieu Olivari)
Date: Thu, 13 Aug 2015 14:33:40 -0700
Subject: [PATCH 3/3] mtd: add SMEM parser for QCOM platforms
In-Reply-To: <1439501620-24073-1-git-send-email-mathieu@codeaurora.org>
References: <1439501620-24073-1-git-send-email-mathieu@codeaurora.org>
Message-ID: <1439501620-24073-4-git-send-email-mathieu@codeaurora.org>

On QCOM platforms using MTD devices storage (such as IPQ806x), SMEM is
used to store partition layout. This new parser can now be used to read
SMEM and use it to register an MTD layout according to its content.

Signed-off-by: Mathieu Olivari <mathieu at codeaurora.org>
---
 drivers/mtd/Kconfig          |   7 ++
 drivers/mtd/Makefile         |   1 +
 drivers/mtd/qcom_smem_part.c | 224 +++++++++++++++++++++++++++++++++++++++++++
 3 files changed, 232 insertions(+)
 create mode 100644 drivers/mtd/qcom_smem_part.c

diff --git a/drivers/mtd/Kconfig b/drivers/mtd/Kconfig
index a03ad29..debc887 100644
--- a/drivers/mtd/Kconfig
+++ b/drivers/mtd/Kconfig
@@ -155,6 +155,13 @@ config MTD_BCM47XX_PARTS
 	  This provides partitions parser for devices based on BCM47xx
 	  boards.
 
+config MTD_QCOM_SMEM_PARTS
+	tristate "QCOM SMEM partitioning support"
+	depends on QCOM_SMEM
+	help
+	  This provides partitions parser for QCOM devices using SMEM
+	  such as IPQ806x.
+
 comment "User Modules And Translation Layers"
 
 #
diff --git a/drivers/mtd/Makefile b/drivers/mtd/Makefile
index 99bb9a1..b3c7de4 100644
--- a/drivers/mtd/Makefile
+++ b/drivers/mtd/Makefile
@@ -13,6 +13,7 @@ obj-$(CONFIG_MTD_AFS_PARTS)	+= afs.o
 obj-$(CONFIG_MTD_AR7_PARTS)	+= ar7part.o
 obj-$(CONFIG_MTD_BCM63XX_PARTS)	+= bcm63xxpart.o
 obj-$(CONFIG_MTD_BCM47XX_PARTS)	+= bcm47xxpart.o
+obj-$(CONFIG_MTD_QCOM_SMEM_PARTS) += qcom_smem_part.o
 
 # 'Users' - code which presents functionality to userspace.
 obj-$(CONFIG_MTD_BLKDEVS)	+= mtd_blkdevs.o
diff --git a/drivers/mtd/qcom_smem_part.c b/drivers/mtd/qcom_smem_part.c
new file mode 100644
index 0000000..6cbf610
--- /dev/null
+++ b/drivers/mtd/qcom_smem_part.c
@@ -0,0 +1,224 @@
+/*
+ * Copyright (c) 2015, The Linux Foundation. All rights reserved.
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License version 2 and
+ * only 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/kernel.h>
+#include <linux/device.h>
+#include <linux/slab.h>
+
+#include <linux/mtd/mtd.h>
+#include <linux/mtd/partitions.h>
+#include <linux/spi/spi.h>
+#include <linux/module.h>
+
+#include <linux/soc/qcom/smem.h>
+
+/* Processor/host identifier for the application processor */
+#define SMEM_HOST_APPS			0
+
+/* SMEM items index */
+#define SMEM_AARM_PARTITION_TABLE	9
+#define SMEM_BOOT_FLASH_TYPE		421
+#define SMEM_BOOT_FLASH_BLOCK_SIZE	424
+
+/* SMEM Magic values in partition table */
+#define SMEM_PTABLE_MAGIC_1		0x55ee73aa
+#define SMEM_PTABLE_MAGIC_2		0xe35ebddb
+
+/* SMEM Flash types */
+#define SMEM_FLASH_NAND			2
+#define SMEM_FLASH_SPI			6
+
+#define SMEM_PART_NAME_SZ		16
+#define SMEM_PARTS_MAX			32
+
+struct smem_partition {
+	char name[SMEM_PART_NAME_SZ];
+	uint32_t start;
+	uint32_t size;
+	uint32_t attr;
+};
+
+struct smem_partition_table {
+	uint32_t magic[2];
+	uint32_t version;
+	uint32_t len;
+	struct smem_partition parts[SMEM_PARTS_MAX];
+};
+
+static int qcom_smem_get_flash_blksz(uint64_t **smem_blksz)
+{
+	int ret;
+	size_t size;
+
+	ret = qcom_smem_get(SMEM_HOST_APPS, SMEM_BOOT_FLASH_BLOCK_SIZE,
+			    (void **) smem_blksz, &size);
+
+	if (ret < 0) {
+		pr_err("Unable to read flash blksz from SMEM\n");
+		return -ENOENT;
+	}
+
+	if (size != sizeof(**smem_blksz)) {
+		pr_err("Invalid flash blksz size in SMEM\n");
+		return -EINVAL;
+	}
+
+	return 0;
+}
+
+static int qcom_smem_get_flash_type(uint64_t **smem_flash_type)
+{
+	int ret;
+	size_t size;
+
+	ret = qcom_smem_get(SMEM_HOST_APPS, SMEM_BOOT_FLASH_TYPE,
+			    (void **) smem_flash_type, &size);
+
+	if (ret < 0) {
+		pr_err("Unable to read flash type from SMEM\n");
+		return -ENOENT;
+	}
+
+	if (size != sizeof(**smem_flash_type)) {
+		pr_err("Invalid flash type size in SMEM\n");
+		return -EINVAL;
+	}
+
+	return 0;
+}
+
+static int qcom_smem_get_flash_partitions(struct smem_partition_table **pparts)
+{
+	int ret;
+	size_t size;
+
+	ret = qcom_smem_get(SMEM_HOST_APPS, SMEM_AARM_PARTITION_TABLE,
+			    (void **) pparts, &size);
+
+	if (ret < 0) {
+		pr_err("Unable to read partition table from SMEM\n");
+		return -ENOENT;
+	}
+
+	return 0;
+}
+
+static int of_dev_node_match(struct device *dev, void *data)
+{
+	return dev->of_node == data;
+}
+
+static bool is_spi_device(struct device_node *np)
+{
+	struct device *dev;
+
+	dev = bus_find_device(&spi_bus_type, NULL, np, of_dev_node_match);
+	return dev ? true : false;
+}
+
+static int parse_qcom_smem_partitions(struct mtd_info *master,
+				      struct mtd_partition **pparts,
+				      struct mtd_part_parser_data *data)
+{
+	struct smem_partition_table *smem_parts;
+	uint64_t *smem_flash_type, *smem_blksz;
+	struct mtd_partition *mtd_parts;
+	struct device_node *of_node = data->of_node;
+	int i, ret;
+
+	/*
+	 * SMEM will only store the partition table of the boot device.
+	 * If this is not the boot device, do not return any partition.
+	 */
+	ret = qcom_smem_get_flash_type(&smem_flash_type);
+	if (ret < 0)
+		return ret;
+
+	if ((*smem_flash_type == SMEM_FLASH_NAND && !mtd_type_is_nand(master))
+	    || (*smem_flash_type == SMEM_FLASH_SPI && !is_spi_device(of_node)))
+		return 0;
+
+	/*
+	 * Just for sanity purpose, make sure the block size in SMEM matches the
+	 * block size of the MTD device
+	 */
+	ret = qcom_smem_get_flash_blksz(&smem_blksz);
+	if (ret < 0)
+		return ret;
+
+	if (*smem_blksz != master->erasesize) {
+		pr_err("SMEM block size differs from MTD block size\n");
+		return -EINVAL;
+	}
+
+	/* Get partition pointer from SMEM */
+	ret = qcom_smem_get_flash_partitions(&smem_parts);
+	if (ret < 0)
+		return ret;
+
+	if (smem_parts->magic[0] != SMEM_PTABLE_MAGIC_1 ||
+	    smem_parts->magic[1] != SMEM_PTABLE_MAGIC_2) {
+		pr_err("SMEM partition magic invalid\n");
+		return -EINVAL;
+	}
+
+	/* Allocate and populate the mtd structures */
+	mtd_parts = kcalloc(smem_parts->len, sizeof(struct mtd_partition),
+			    GFP_KERNEL);
+	if (mtd_parts == NULL)
+		return -ENOMEM;
+
+	for (i = 0; i < smem_parts->len; i++) {
+		struct smem_partition *part = &smem_parts->parts[i];
+
+		mtd_parts[i].name = part->name;
+		mtd_parts[i].size = part->size * (*smem_blksz);
+		mtd_parts[i].offset = part->start * (*smem_blksz);
+
+		/*
+		 * The last SMEM partition may have its size marked as
+		 * something like 0xffffffff, which means "until the end of the
+		 * flash device". In this case, truncate it.
+		 */
+		if (mtd_parts[i].offset + mtd_parts[i].size > master->size)
+			mtd_parts[i].size = master->size - mtd_parts[i].offset;
+	}
+
+	*pparts = mtd_parts;
+
+	return smem_parts->len;
+}
+
+static struct mtd_part_parser qcom_smem_parser = {
+	.owner = THIS_MODULE,
+	.parse_fn = parse_qcom_smem_partitions,
+	.name = "qcom-smem",
+};
+
+static int __init qcom_smem_parser_init(void)
+{
+	register_mtd_parser(&qcom_smem_parser);
+	return 0;
+}
+
+static void __exit qcom_smem_parser_exit(void)
+{
+	deregister_mtd_parser(&qcom_smem_parser);
+}
+
+module_init(qcom_smem_parser_init);
+module_exit(qcom_smem_parser_exit);
+
+MODULE_LICENSE("GPL");
+MODULE_AUTHOR("Mathieu Olivari <mathieu at codeaurora.org>");
+MODULE_DESCRIPTION("Parsing code for SMEM based partition tables");
-- 
2.1.4



From computersforpeace at gmail.com  Thu Aug 13 14:47:39 2015
From: computersforpeace at gmail.com (Brian Norris)
Date: Thu, 13 Aug 2015 14:47:39 -0700
Subject: [PATCH v5] mtd: spi-nor: add driver for NXP SPI Flash Interface
 (SPIFI)
In-Reply-To: <1439486380-17720-1-git-send-email-manabian@gmail.com>
References: <1439486380-17720-1-git-send-email-manabian@gmail.com>
Message-ID: <20150813214739.GH60523@google.com>

On Thu, Aug 13, 2015 at 07:19:40PM +0200, Joachim Eastwood wrote:
> Add SPI-NOR driver for the SPI Flash Interface (SPIFI)
> controller that is found on newer NXP MCU devices.
> 
> The controller supports serial SPI Flash devices with 1-, 2-
> and 4-bit width in either SPI mode 0 or 3. The controller
> can operate in either command or memory mode. In memory mode
> the Flash is exposed as normal memory and can be directly
> accessed by the CPU.
> 
> Signed-off-by: Joachim Eastwood <manabian at gmail.com>
> Reviewed-by: Ezequiel Garcia <ezequiel at vanguardiasur.com.ar>
> ---
> Hi Brian,
> 
> I skipped the cover letter since you already applied the 2nd
> of patch of the original set and using a cover letter for
> just one patch seemed a bit useless. Cover letter for v4 can
> be found here: http://marc.info/?l=devicetree&m=143647330431908&w=2
> 
> This version address all comments from Brian Norris except
> for two things noted below.
> 
> If the line below is removed the kernel opses on jffs2 mount.
> spifi->mtd.priv  = &spifi->nor;
> It seems like spi-nor.c doesn't setup this field. fsl-quadspi
> also assigns this field, btw.

Sorry, I overlooked that. But that code's pretty dumb. I'll take yours
as-is, but I'll send a patch to fix both.

> The read/wait ordering in nxp_spifi_read_reg is correct. I
> don't really have a good explaination for the ordering. The
> user manual doesn't document the SPIFI in detail, but the
> offcial NXP spifilib has the same ordering.

OK, no problem.

> Changes since v4:
>  - spifi: always autodetect SPI Flash
>  - s/spi/SPI on dev_* output
>  - add parentheses to SPIFI_CMD_DATALEN macro
>  - rebase on mtd-master
> 
> Changes since v3:
>  - fix bug in write function
>  - rebase on 4.2-rc1
> 
> Changes since v2:
>  - default to auto detection unless chip is specified
>  - update doc with reference to jedec,spi-nor.txt
> 
> Test on the following boards.
> Hitex board boots on SPIFI Flash with JFFS2.
> 
> Hitex LPC4350 Eval board:
> [    2.093956] nxp-spifi 40003000.spifi: s25sl064p (8192 Kbytes)
> 
> Embedded Artists' LPC4357 Developer's Kit:
> [    3.051627] nxp-spifi 40003000.spifi: s25fl016k (2048 Kbytes)

Applied to l2-mtd.git, thanks!

BTW, is this driver worth a MAINTAINERS entry? It's nice to always have
someone on CC that has the hardware. The git history should probably
pick you up anyway when running get_maintainers.pl, so it may not be
absolutely necessary.

> Both s25fl016k and s25sl064p support dual/quad mode, but this
> is not flagged in spi-nor.c. I have sent a patch for s25fl016k
> and will send a patch s25sl064p please apply when you get them.

I'll see if I can dig these out of the mailing list eventually. I have a
sizable backlog.

Brian


From robherring2 at gmail.com  Thu Aug 13 15:01:47 2015
From: robherring2 at gmail.com (Rob Herring)
Date: Thu, 13 Aug 2015 17:01:47 -0500
Subject: [PATCH v2 1/2] ARM: common: Introduce PM domains for CPUs/clusters
In-Reply-To: <20150813201248.GB84868@linaro.org>
References: <CAL_JsqLhHy5gO=usm1HLf8h6iz_5FguCDo-Qz2Km+XEwaCODUA@mail.gmail.com>
 <1439406024-41893-1-git-send-email-lina.iyer@linaro.org>
 <CAL_JsqLcSs79bnj4ELN0uiwJ6gxt46PghxvuGQ7prkq-4gLKhg@mail.gmail.com>
 <20150813201248.GB84868@linaro.org>
Message-ID: <CAL_Jsq+-9vS4_KRQKAsQnHXBMfubkRtnWwuBHSrD166trmTVSw@mail.gmail.com>

On Thu, Aug 13, 2015 at 3:12 PM, Lina Iyer <lina.iyer at linaro.org> wrote:
> On Thu, Aug 13 2015 at 11:29 -0600, Rob Herring wrote:
>>
>> On Wed, Aug 12, 2015 at 2:00 PM, Lina Iyer <lina.iyer at linaro.org> wrote:
>>>
>>> Define and add Generic PM domains (genpd) for CPU clusters. Many new
>>> SoCs group CPUs as clusters. Clusters share common resources like GIC,
>>> power rail, caches, VFP, Coresight etc. When all CPUs in the cluster are
>>> idle, these shared resources may also be put in their idle state.
>>>
>>> The idle time between the last CPU entering idle and a CPU resuming
>>> execution is an opportunity for these shared resources to be powered
>>> down. Generic PM domain provides a framework for defining such power
>>> domains and attach devices to the domain. When the devices in the domain
>>> are idle at runtime, the domain would also be suspended and resumed
>>> before the first of the devices resume execution.
>>>
>>> We define a generic PM domain for each cluster and attach CPU devices in
>>> the cluster to that PM domain. The DT definitions for the SoC describe
>>> this relationship. Genpd callbacks for power_on and power_off can then
>>> be used to power up/down the shared resources for the domain.
>>>
>>> Cc: Stephen Boyd <sboyd at codeaurora.org>
>>> Cc: Kevin Hilman <khilman at linaro.org>
>>> Cc: Ulf Hansson <ulf.hansson at linaro.org>
>>> Cc: Catalin Marinas <catalin.marinas at arm.com>
>>> Cc: Daniel Lezcano <daniel.lezcano at linaro.org>
>>> Cc: Mark Rutland <mark.rutland at arm.com>
>>> Cc: Lorenzo Pieralisi <lorenzo.pieralisi at arm.com>
>>> Signed-off-by: Kevin Hilman <khilman at linaro.org>
>>> Signed-off-by: Lina Iyer <lina.iyer at linaro.org>
>>> ---
>>> Changes since v1:
>>>
>>> - Function name changes and split out common code
>>> - Use cpu,pd for now. Removed references to ARM. Open to recommendations.
>>> - Still located in arch/arm/common/. May move to a more appropriate
>>> location.
>>> - Platform drivers can directly call of_init_cpu_domain() without using
>>>   compatibles.
>>> - Now maintains a list of CPU PM domains.
>>
>>
>> [...]
>>
>>> +static int __init of_pm_domain_attach_cpus(void)
>>> +{
>>> +       int cpuid, ret;
>>> +
>>> +       /* Find any CPU nodes with a phandle to this power domain */
>>> +       for_each_possible_cpu(cpuid) {
>>> +               struct device *cpu_dev;
>>> +               struct of_phandle_args pd_args;
>>> +
>>> +               cpu_dev = get_cpu_device(cpuid);
>>> +               if (!cpu_dev) {
>>> +                       pr_warn("%s: Unable to get device for CPU%d\n",
>>> +                                       __func__, cpuid);
>>> +                       return -ENODEV;
>>> +               }
>>> +
>>> +               /*
>>> +                * We are only interested in CPUs that can be attached to
>>> +                * PM domains that are cpu,pd compatible.
>>> +                */
>>
>>
>> Under what conditions would the power domain for a cpu not be cpu,pd
>> compatible?
>>
> Mostly never. But I dont want to assume and attach a CPU to its domain
> that I am not concerned with.

Which is why the power controller driver should tell you.

>> Why can't the driver handling the power domain register with gen_pd
>> and the cpu_pd as the driver is going to be aware of which domains are
>> for cpus.
>
> They could and like Renesas they would. They could have an intricate
> hierarchy of domains that they may want to deal with in their platform
> drivers. Platforms could define the CPU devices as IRQ-safe and attach
> it to their domains. Ensure the reference count of the online and
> running CPUs are correct and they are good to go. They also would attach
> the CPU devices to the domain and everything would work as they would
> here. Its just repeated code across platforms that we are trying to
> avoid.

I agree that we want to have core code doing all that setup, But that
has nothing to do with needing to have a DT property. The driver just
needs to tell you the list of cpu power domains and the associated
cpus they want the core to manage. Then it is up to you to do the rest
of the setup.

So I really don't think we need a DT binding here.

>> While there could be h/w such that all power domains within
>> a chip have a nice uniform programming model, I'd guess that is the
>> exception, not the rule. First, chips I have worked on were not that
>> way. CPU related and peripheral related domains are handled quite
>> differently.
>
> Agreed. These are very SoC specific components and would require
> platform specific programming. But most SoCs, would need to do many
> other things like suspending debuggers, reducing clocks, GIC save and
> restore, cluster state determination etc that are only getting more
> generalized. We have generalized ARM CPU idle, I see this as the
> platform for the next set of power saving in an SoC.
>
>> Second, often the actions on the CPU power domains don't
>> take effect until a WFI, so you end up with a different programming
>> sequence.
>>
> How so? The last core going down (in this case, when the domain is
> suspended the last core is the last device that does a _put() on the
> domain) would determine and perform the power domain's programming
> sequence, in the context of the last CPU. A sequence that would only be
> effected in hardware when the the CPU executes WFI. I dont see why it
> would be any different than how it is today.

I just mean that for a peripheral (e.g a SATA controller), you simply
quiesce the device and driver and shut off power. With a cpu or cpu
related component, you can't really shut it off until you stop
running. So cpu domains are special.

Rob


From manabian at gmail.com  Thu Aug 13 15:10:59 2015
From: manabian at gmail.com (Joachim Eastwood)
Date: Fri, 14 Aug 2015 00:10:59 +0200
Subject: [PATCH v5] mtd: spi-nor: add driver for NXP SPI Flash Interface
 (SPIFI)
In-Reply-To: <20150813214739.GH60523@google.com>
References: <1439486380-17720-1-git-send-email-manabian@gmail.com>
 <20150813214739.GH60523@google.com>
Message-ID: <CAGhQ9Vzs2h3mw2qnYvy83RAvrX8uPZGGzNASr1csk_LhLnHB8g@mail.gmail.com>

Hi Brian,

On 13 August 2015 at 23:47, Brian Norris <computersforpeace at gmail.com> wrote:
> On Thu, Aug 13, 2015 at 07:19:40PM +0200, Joachim Eastwood wrote:
>> Add SPI-NOR driver for the SPI Flash Interface (SPIFI)
>> controller that is found on newer NXP MCU devices.
>>
>> The controller supports serial SPI Flash devices with 1-, 2-
>> and 4-bit width in either SPI mode 0 or 3. The controller
>> can operate in either command or memory mode. In memory mode
>> the Flash is exposed as normal memory and can be directly
>> accessed by the CPU.
>>
>> Signed-off-by: Joachim Eastwood <manabian at gmail.com>
>> Reviewed-by: Ezequiel Garcia <ezequiel at vanguardiasur.com.ar>
>> ---
>> Hi Brian,
>>
>> I skipped the cover letter since you already applied the 2nd
>> of patch of the original set and using a cover letter for
>> just one patch seemed a bit useless. Cover letter for v4 can
>> be found here: http://marc.info/?l=devicetree&m=143647330431908&w=2
>>
>> This version address all comments from Brian Norris except
>> for two things noted below.
>>
>> If the line below is removed the kernel opses on jffs2 mount.
>> spifi->mtd.priv  = &spifi->nor;
>> It seems like spi-nor.c doesn't setup this field. fsl-quadspi
>> also assigns this field, btw.
>
> Sorry, I overlooked that. But that code's pretty dumb. I'll take yours
> as-is, but I'll send a patch to fix both.

OK.

>> The read/wait ordering in nxp_spifi_read_reg is correct. I
>> don't really have a good explaination for the ordering. The
>> user manual doesn't document the SPIFI in detail, but the
>> offcial NXP spifilib has the same ordering.
>
> OK, no problem.
>
>> Changes since v4:
>>  - spifi: always autodetect SPI Flash
>>  - s/spi/SPI on dev_* output
>>  - add parentheses to SPIFI_CMD_DATALEN macro
>>  - rebase on mtd-master
>>
>> Changes since v3:
>>  - fix bug in write function
>>  - rebase on 4.2-rc1
>>
>> Changes since v2:
>>  - default to auto detection unless chip is specified
>>  - update doc with reference to jedec,spi-nor.txt
>>
>> Test on the following boards.
>> Hitex board boots on SPIFI Flash with JFFS2.
>>
>> Hitex LPC4350 Eval board:
>> [    2.093956] nxp-spifi 40003000.spifi: s25sl064p (8192 Kbytes)
>>
>> Embedded Artists' LPC4357 Developer's Kit:
>> [    3.051627] nxp-spifi 40003000.spifi: s25fl016k (2048 Kbytes)
>
> Applied to l2-mtd.git, thanks!

Excellent. Thanks Brian.

> BTW, is this driver worth a MAINTAINERS entry? It's nice to always have
> someone on CC that has the hardware. The git history should probably
> pick you up anyway when running get_maintainers.pl, so it may not be
> absolutely necessary.

Sure. I can add it under the main lpc18xx platform entry in
MAINTAINERS. I'll queue up a patch for arm-soc.

>> Both s25fl016k and s25sl064p support dual/quad mode, but this
>> is not flagged in spi-nor.c. I have sent a patch for s25fl016k
>> and will send a patch s25sl064p please apply when you get them.
>
> I'll see if I can dig these out of the mailing list eventually. I have a
> sizable backlog.

Ok, thanks.


regards,
Joachim Eastwood


From computersforpeace at gmail.com  Thu Aug 13 15:13:16 2015
From: computersforpeace at gmail.com (Brian Norris)
Date: Thu, 13 Aug 2015 15:13:16 -0700
Subject: [PATCH v5] mtd: spi-nor: add driver for NXP SPI Flash Interface
 (SPIFI)
In-Reply-To: <CAGhQ9Vzs2h3mw2qnYvy83RAvrX8uPZGGzNASr1csk_LhLnHB8g@mail.gmail.com>
References: <1439486380-17720-1-git-send-email-manabian@gmail.com>
 <20150813214739.GH60523@google.com>
 <CAGhQ9Vzs2h3mw2qnYvy83RAvrX8uPZGGzNASr1csk_LhLnHB8g@mail.gmail.com>
Message-ID: <20150813221316.GI60523@google.com>

On Fri, Aug 14, 2015 at 12:10:59AM +0200, Joachim Eastwood wrote:
> On 13 August 2015 at 23:47, Brian Norris <computersforpeace at gmail.com> wrote:
> > BTW, is this driver worth a MAINTAINERS entry? It's nice to always have
> > someone on CC that has the hardware. The git history should probably
> > pick you up anyway when running get_maintainers.pl, so it may not be
> > absolutely necessary.
> 
> Sure. I can add it under the main lpc18xx platform entry in
> MAINTAINERS. I'll queue up a patch for arm-soc.

Sounds good.


From sergei.shtylyov at cogentembedded.com  Thu Aug 13 15:47:12 2015
From: sergei.shtylyov at cogentembedded.com (Sergei Shtylyov)
Date: Fri, 14 Aug 2015 01:47:12 +0300
Subject: [PATCH v2] ARM: shmobile: silk: add SDHI1 DT support
In-Reply-To: <2757472.iuyUyRzJ3z@wasted.cogentembedded.com>
References: <10037494.4LD4T2QGPX@wasted.cogentembedded.com>
 <2757472.iuyUyRzJ3z@wasted.cogentembedded.com>
Message-ID: <55CD1E70.6050103@cogentembedded.com>

Hello.

On 08/11/2015 01:44 AM, Sergei Shtylyov wrote:

> Define the SILK board dependent part of the SDHI1 (connected to micro-SD slot)
> device nodes along with the necessary voltage regulators.
>
> Based on the original patch by Vladimir Barinov
> <vladimir.barinov at cogentembedded.com>.
>
> Signed-off-by: Sergei Shtylyov <sergei.shtylyov at cogentembedded.com>
>
> ---
> This patch is against 'renesas-devel-20150810-v4.2-rc6' tag of Simon Horman's
> 'renesas.git' repo plus the R8A7794/SILK QSPI patches just re-posted. It needs
> the R8A7794 GPIO patches in order to compile.
>
> Changes in version 2:
> - removed not working SDHI0 stuff, renamed the patch;
> - replaced SDHI1's "wp-gpios" property with "disable-wp".
>
>   arch/arm/boot/dts/r8a7794-silk.dts |   40 +++++++++++++++++++++++++++++++++++++
>   1 file changed, 40 insertions(+)
>
> Index: renesas/arch/arm/boot/dts/r8a7794-silk.dts
> ===================================================================
> --- renesas.orig/arch/arm/boot/dts/r8a7794-silk.dts
> +++ renesas/arch/arm/boot/dts/r8a7794-silk.dts
[...]
> @@ -39,6 +40,29 @@
>   		regulator-boot-on;
>   		regulator-always-on;
>   	};

    Oops, need a newline here. I'll repost.

> +	vcc_sdhi1: regulator at 3 {
> +		compatible = "regulator-fixed";
> +
> +		regulator-name = "SDHI1 Vcc";
> +		regulator-min-microvolt = <3300000>;
> +		regulator-max-microvolt = <3300000>;
> +
> +		gpio = <&gpio4 26 GPIO_ACTIVE_HIGH>;
> +		enable-active-high;
> +	};
> +
> +	vccq_sdhi1: regulator at 4 {
> +		compatible = "regulator-gpio";
> +
> +		regulator-name = "SDHI1 VccQ";
> +		regulator-min-microvolt = <1800000>;
> +		regulator-max-microvolt = <3300000>;
> +
> +		gpios = <&gpio4 29 GPIO_ACTIVE_HIGH>;
> +		gpios-states = <1>;
> +		states = <3300000 1
> +			  1800000 0>;
> +	};
>   };
>
>   &extal_clk {
[...]

MBR, Sergei



From eric at anholt.net  Thu Aug 13 16:03:00 2015
From: eric at anholt.net (Eric Anholt)
Date: Thu, 13 Aug 2015 16:03:00 -0700
Subject: [PATCH 3/7] drm/vc4: Add KMS support for Raspberry Pi.
In-Reply-To: <20150813212936.GT7557@n2100.arm.linux.org.uk>
References: <1439427380-2436-1-git-send-email-eric@anholt.net>
 <1439427380-2436-4-git-send-email-eric@anholt.net>
 <20150813075141.GX17734@phenom.ffwll.local>
 <87d1yqq5po.fsf@eliezer.anholt.net>
 <20150813212936.GT7557@n2100.arm.linux.org.uk>
Message-ID: <87zj1uiyfv.fsf@eliezer.anholt.net>

Russell King - ARM Linux <linux at arm.linux.org.uk> writes:

> On Thu, Aug 13, 2015 at 01:44:03PM -0700, Eric Anholt wrote:
>> Struct mutex is here because this code is from the V3D series, with the
>> in-kernel BO cache ripped out (it turns out that the CMA allocator is
>> slow, and you can't just userspace cache since we have to do allocations
>> within the kernel to the tune of a couple per draw and that's too much).
>
> The CMA allocator is fast until you have pinned pages in its region,
> where it becomes _very_ slow to do allocations, sometimes getting up
> to the order of seconds.
>
> The main culpret of this are GFP_HIGHUSER_MOVABLE allocations which
> then pin the page.  It doesn't take many of those to make CMA really
> inefficient.
>
> The problem is that CMA doesn't get any information back from the
> internal page migration about which pages couldn't be moved, so it
> dumbly just tries incrementing the allocation by one page (subject
> to alignment constraints) and retrying again - repeating over the
> entire CMA region.  The bigger the region, the more time this takes.

Ouch.

Since I can workaround the allocation cost, the main problem I have
right now is that I've got a set of small allocations for 3D that all
need to have the same high 4 bits of paddr, because someone cleverly
packed some address bits in a GPU-managed structure.  Any
recommendations for ways to handle this with CMA?
-------------- next part --------------
A non-text attachment was scrubbed...
Name: signature.asc
Type: application/pgp-signature
Size: 818 bytes
Desc: not available
URL: <http://lists.infradead.org/pipermail/linux-arm-kernel/attachments/20150813/771987cb/attachment.sig>

From eric at anholt.net  Thu Aug 13 16:05:39 2015
From: eric at anholt.net (Eric Anholt)
Date: Thu, 13 Aug 2015 16:05:39 -0700
Subject: Rasperry Pi clock support
Message-ID: <1439507142-2965-1-git-send-email-eric@anholt.net>

I'm also avoiding requests to set rate/state when they're a no-op, as
apparently no-op changes to pixel clock break the firmware-configured
display setup.  It *shouldn't* change anything, but I've confirmed
that setting the CPU clock works fine, and after a couple of weeks of
prodding pixel clock now, I'm at a loss for what's going on with it.



From eric at anholt.net  Thu Aug 13 16:05:40 2015
From: eric at anholt.net (Eric Anholt)
Date: Thu, 13 Aug 2015 16:05:40 -0700
Subject: [PATCH v5 1/3] clk: bcm2835: Add binding docs for the Raspberry Pi
 clock provider
In-Reply-To: <1439507142-2965-1-git-send-email-eric@anholt.net>
References: <1439507142-2965-1-git-send-email-eric@anholt.net>
Message-ID: <1439507142-2965-2-git-send-email-eric@anholt.net>

The hardware clocks are not controllable by the ARM, so we have to
make requests to the firmware to do so from the VPU side.  This will
let us replace fixed clocks in our DT with actual clock control (and
correct frequency information).

Signed-off-by: Eric Anholt <eric at anholt.net>
Acked-by: Stephen Warren <swarren at wwwdotorg.org>
Acked-by: Michael Turquette <mturquette at baylibre.com>
---

v2: Include the dt-bindings header in this commit instead of the next
    one.  Make the clock indices match the firmware clock IDs.  Rename
    the binding's compat string.  Move the firmware phandle to be
    under a vendor-specific namespace.
v3: Mention 'clk' in the subject instead of the more generic
    dt/bindings.

 .../clock/raspberrypi,bcm2835-firmware-clocks.txt  | 25 ++++++++++++++++++++++
 include/dt-bindings/clk/raspberrypi.h              | 23 ++++++++++++++++++++
 2 files changed, 48 insertions(+)
 create mode 100644 Documentation/devicetree/bindings/clock/raspberrypi,bcm2835-firmware-clocks.txt
 create mode 100644 include/dt-bindings/clk/raspberrypi.h

diff --git a/Documentation/devicetree/bindings/clock/raspberrypi,bcm2835-firmware-clocks.txt b/Documentation/devicetree/bindings/clock/raspberrypi,bcm2835-firmware-clocks.txt
new file mode 100644
index 0000000..0972602
--- /dev/null
+++ b/Documentation/devicetree/bindings/clock/raspberrypi,bcm2835-firmware-clocks.txt
@@ -0,0 +1,25 @@
+Raspberry Pi firmware clock provider.
+
+The Raspberry Pi architecture doesn't provide direct access to the
+CLOCKMAN peripheral from the ARM side, so Linux has to make requests
+to the VPU firmware to program them.
+
+This binding uses the common clock binding:
+Documentation/devicetree/bindings/clock/clock-bindings.txt
+
+Required properties:
+- compatible:		Should be "raspberrypi,bcm2835-firmware-clocks"
+
+- #clock-cells:		Shall have value <1>.  The permitted clock-specifier
+			  values can be found in
+			  include/dt-bindings/clk/raspberrypi.h.
+
+- raspberrypi,firmware:	Phandle to the firmware driver node.
+
+Example:
+
+firmware_clocks: firmware-clocks {
+	compatible = "raspberrypi,bcm2835-firmware-clocks";
+	#clock-cells = <1>;
+	raspberrypi,firmware = <&firmware>;
+};
diff --git a/include/dt-bindings/clk/raspberrypi.h b/include/dt-bindings/clk/raspberrypi.h
new file mode 100644
index 0000000..ceec90f
--- /dev/null
+++ b/include/dt-bindings/clk/raspberrypi.h
@@ -0,0 +1,23 @@
+#/*
+ *  Copyright ? 2015 Broadcom
+ *
+ * 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.
+ */
+
+#ifndef _DT_BINDINGS_CLK_RASPBERRYPI_H
+#define _DT_BINDINGS_CLK_RASPBERRYPI_H
+
+#define RPI_CLOCK_EMMC	1
+#define RPI_CLOCK_UART0	2
+#define RPI_CLOCK_ARM	3
+#define RPI_CLOCK_CORE	4
+#define RPI_CLOCK_V3D	5
+#define RPI_CLOCK_H264	6
+#define RPI_CLOCK_ISP	7
+#define RPI_CLOCK_SDRAM	8
+#define RPI_CLOCK_PIXEL	9
+#define RPI_CLOCK_PWM	10
+
+#endif
-- 
2.1.4



From eric at anholt.net  Thu Aug 13 16:05:42 2015
From: eric at anholt.net (Eric Anholt)
Date: Thu, 13 Aug 2015 16:05:42 -0700
Subject: [PATCH v5 3/3] ARM: bcm2835: Add DT for the firmware clocks driver.
In-Reply-To: <1439507142-2965-1-git-send-email-eric@anholt.net>
References: <1439507142-2965-1-git-send-email-eric@anholt.net>
Message-ID: <1439507142-2965-4-git-send-email-eric@anholt.net>

Signed-off-by: Eric Anholt <eric at anholt.net>
Acked-by: Lee Jones <lee at kernel.org>
---

v2: Rename our compat string to mention bcm2835, and make our firmware
    phandle be under a vendor-namespaced property.

v3: Squashed in the patches to reference the other clocks, to avoid
    regressions now that we register all clocks at boot.  Dropped
    Stephen's ack, since he hadn't acked the new EMMC change yet.

 arch/arm/boot/dts/bcm2835-rpi.dtsi | 18 ++++++++++++++++++
 arch/arm/boot/dts/bcm2835.dtsi     |  3 +--
 2 files changed, 19 insertions(+), 2 deletions(-)

diff --git a/arch/arm/boot/dts/bcm2835-rpi.dtsi b/arch/arm/boot/dts/bcm2835-rpi.dtsi
index ab5474e..5d370cb 100644
--- a/arch/arm/boot/dts/bcm2835-rpi.dtsi
+++ b/arch/arm/boot/dts/bcm2835-rpi.dtsi
@@ -1,3 +1,4 @@
+#include <dt-bindings/clk/raspberrypi.h>
 #include "bcm2835.dtsi"
 
 / {
@@ -20,6 +21,12 @@
 			compatible = "raspberrypi,bcm2835-firmware";
 			mboxes = <&mailbox>;
 		};
+
+		firmware_clocks: firmware-clocks {
+			compatible = "raspberrypi,bcm2835-firmware-clocks";
+			#clock-cells = <1>;
+			raspberrypi,firmware = <&firmware>;
+		};
 	};
 };
 
@@ -55,4 +62,15 @@
 &sdhci {
 	status = "okay";
 	bus-width = <4>;
+	clocks = <&firmware_clocks RPI_CLOCK_EMMC>;
+};
+
+&uart0 {
+	clocks = <&firmware_clocks RPI_CLOCK_UART0>,
+		 <&firmware_clocks RPI_CLOCK_CORE>;
+	clock-names = "uartclk", "apb_pclk";
+};
+
+&spi {
+	clocks = <&firmware_clocks RPI_CLOCK_CORE>;
 };
diff --git a/arch/arm/boot/dts/bcm2835.dtsi b/arch/arm/boot/dts/bcm2835.dtsi
index 301c73f..5be2862 100644
--- a/arch/arm/boot/dts/bcm2835.dtsi
+++ b/arch/arm/boot/dts/bcm2835.dtsi
@@ -92,11 +92,10 @@
 			#interrupt-cells = <2>;
 		};
 
-		uart at 7e201000 {
+		uart0: uart at 7e201000 {
 			compatible = "brcm,bcm2835-pl011", "arm,pl011", "arm,primecell";
 			reg = <0x7e201000 0x1000>;
 			interrupts = <2 25>;
-			clock-frequency = <3000000>;
 			arm,primecell-periphid = <0x00241011>;
 		};
 
-- 
2.1.4



From eric at anholt.net  Thu Aug 13 16:05:41 2015
From: eric at anholt.net (Eric Anholt)
Date: Thu, 13 Aug 2015 16:05:41 -0700
Subject: [PATCH v5 2/3] clk: Add a Raspberry Pi-specific clock driver.
In-Reply-To: <1439507142-2965-1-git-send-email-eric@anholt.net>
References: <1439507142-2965-1-git-send-email-eric@anholt.net>
Message-ID: <1439507142-2965-3-git-send-email-eric@anholt.net>

Unfortunately, the clock manager's registers are not accessible by the
ARM, so we have to request that the firmware modify our clocks for us.

This driver only registers the clocks at the point they are requested
by a client driver.  This is partially to support returning
-EPROBE_DEFER when the firmware driver isn't supported yet, but it
also avoids issues with disabling "unused" clocks due to them not yet
being connected to their consumers in the DT.

Signed-off-by: Eric Anholt <eric at anholt.net>
---

v2: Declare the mutex static (from review by Baruch Siach), merge
    description and copyright comments.

v3: Update for new rpi firmware API.  Update the compatible string.
    Make the firmware handle be under a vendor-namespaced property.
    Make the DT indices match the firmware clock IDs.  Move the driver
    under the firmware driver's Kconfig, since it requires it.  Move a
    container_of() from 2 callers into the callee.

v4: Update commit message to mention subsystem.  Add #defines for a
    couple of bitfield checks, and use the bitfield check for
    rpi_clk_is_on().  Return an error when appropriate in
    rpi_clk_is_on(), and don't return specific rpi_firmware_property()
    errors in other places when we were only returning -EINVAL.  Add
    some comment text describing how return values work from
    the firmware.

v5: Restructure as a platform_driver on suggestion from Michael
    Turquette.  This works around the -EPROBE_DEFER problem, so now we
    can register all of our clocks at probe time.  Store the current
    clock rate in the struct, and avoid asking for no-op changes.  It
    appears that a no-op change of the pixel clock while the clock is
    being used (at boot time when the KMS driver calls
    clk_prepare_enable()) actually breaks the display.  Dropped
    Stephen's ack since this is a pretty significant rewrite.

 drivers/clk/Makefile          |   1 +
 drivers/clk/clk-raspberrypi.c | 286 ++++++++++++++++++++++++++++++++++++++++++
 2 files changed, 287 insertions(+)
 create mode 100644 drivers/clk/clk-raspberrypi.c

diff --git a/drivers/clk/Makefile b/drivers/clk/Makefile
index c4cf075..ad0a4a5 100644
--- a/drivers/clk/Makefile
+++ b/drivers/clk/Makefile
@@ -20,6 +20,7 @@ obj-$(CONFIG_MACH_ASM9260)		+= clk-asm9260.o
 obj-$(CONFIG_COMMON_CLK_AXI_CLKGEN)	+= clk-axi-clkgen.o
 obj-$(CONFIG_ARCH_AXXIA)		+= clk-axm5516.o
 obj-$(CONFIG_ARCH_BCM2835)		+= clk-bcm2835.o
+obj-$(CONFIG_RASPBERRYPI_FIRMWARE)	+= clk-raspberrypi.o
 obj-$(CONFIG_COMMON_CLK_CDCE706)	+= clk-cdce706.o
 obj-$(CONFIG_ARCH_CLPS711X)		+= clk-clps711x.o
 obj-$(CONFIG_ARCH_EFM32)		+= clk-efm32gg.o
diff --git a/drivers/clk/clk-raspberrypi.c b/drivers/clk/clk-raspberrypi.c
new file mode 100644
index 0000000..a65a028
--- /dev/null
+++ b/drivers/clk/clk-raspberrypi.c
@@ -0,0 +1,286 @@
+/*
+ * Implements a clock provider for the clocks controlled by the
+ * firmware on Raspberry Pi.
+ *
+ * These clocks are controlled by the CLOCKMAN peripheral in the
+ * hardware, but the ARM doesn't have access to the registers for
+ * them.  As a result, we have to call into the firmware to get it to
+ * enable, disable, and set their frequencies.
+ *
+ * We don't have an interface for getting the set of frequencies
+ * available from the hardware.  We can request a min/max, but other
+ * than that we have to request a frequency and take what it gives us.
+ *
+ * Copyright ? 2015 Broadcom
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License version 2 as
+ * published by the Free Software Foundation.
+ */
+
+#include <linux/clk-provider.h>
+#include <linux/module.h>
+#include <dt-bindings/clk/raspberrypi.h>
+#include <soc/bcm2835/raspberrypi-firmware.h>
+
+#define RPI_FIRMWARE_CLOCK_STATE_ENABLED		(1 << 0)
+#define RPI_FIRMWARE_CLOCK_STATE_ERROR			(1 << 1)
+#define RPI_FIRMWARE_SET_CLOCK_RATE_ERROR		0
+
+static const struct {
+	const char *name;
+	int flags;
+} rpi_clocks[] = {
+	[RPI_CLOCK_EMMC] = { "emmc", CLK_IS_ROOT },
+	[RPI_CLOCK_UART0] = { "uart0", CLK_IS_ROOT },
+	[RPI_CLOCK_ARM] = { "arm", CLK_IS_ROOT | CLK_IGNORE_UNUSED },
+	[RPI_CLOCK_CORE] = { "core", CLK_IS_ROOT | CLK_IGNORE_UNUSED },
+	[RPI_CLOCK_V3D] = { "v3d", CLK_IS_ROOT },
+	[RPI_CLOCK_H264] = { "h264", CLK_IS_ROOT },
+	[RPI_CLOCK_ISP] = { "isp", CLK_IS_ROOT },
+	[RPI_CLOCK_SDRAM] = { "sdram", CLK_IS_ROOT | CLK_IGNORE_UNUSED },
+	[RPI_CLOCK_PIXEL] = { "pixel", CLK_IS_ROOT | CLK_IGNORE_UNUSED },
+	[RPI_CLOCK_PWM] = { "pwm", CLK_IS_ROOT },
+};
+
+struct rpi_firmware_clock {
+	/* Clock definitions in our static struct. */
+	const char *name;
+	int flags;
+
+	/* The rest are filled in at init time. */
+	struct clk_hw hw;
+	struct device *dev;
+	struct rpi_firmware *firmware;
+	uint32_t last_rate;
+	int id;
+};
+
+static int rpi_clk_is_on(struct clk_hw *hw)
+{
+	struct rpi_firmware_clock *rpi_clk =
+		container_of(hw, struct rpi_firmware_clock, hw);
+	u32 packet[2];
+	int ret;
+
+	packet[0] = rpi_clk->id;
+	packet[1] = 0;
+	ret = rpi_firmware_property(rpi_clk->firmware,
+				    RPI_FIRMWARE_GET_CLOCK_STATE,
+				    &packet, sizeof(packet));
+	/*
+	 * The second packet field has the new clock state returned in
+	 * the low bit, or an error flag in the second bit.
+	 */
+	if (ret || (packet[1] & RPI_FIRMWARE_CLOCK_STATE_ERROR)) {
+		dev_err(rpi_clk->dev, "Failed to get clock state\n");
+		return ret ? ret : -EINVAL;
+	}
+
+	return packet[1] & RPI_FIRMWARE_CLOCK_STATE_ENABLED;
+}
+
+static int rpi_clk_set_state(struct clk_hw *hw, bool on)
+{
+	struct rpi_firmware_clock *rpi_clk =
+		container_of(hw, struct rpi_firmware_clock, hw);
+	u32 packet[2];
+	int ret;
+
+	if (on == (rpi_clk->last_rate != 0))
+		return 0;
+
+	packet[0] = rpi_clk->id;
+	packet[1] = on;
+	ret = rpi_firmware_property(rpi_clk->firmware,
+				    RPI_FIRMWARE_SET_CLOCK_STATE,
+				    &packet, sizeof(packet));
+	/*
+	 * The second packet field has the new clock state returned in
+	 * the low bit, or an error flag in the second bit.
+	 */
+	if (ret || (packet[1] & RPI_FIRMWARE_CLOCK_STATE_ERROR)) {
+		dev_err(rpi_clk->dev, "Failed to set clock state\n");
+		return ret ? ret : -EINVAL;
+	}
+
+	return 0;
+}
+
+static int rpi_clk_on(struct clk_hw *hw)
+{
+	return rpi_clk_set_state(hw, true);
+}
+
+static void rpi_clk_off(struct clk_hw *hw)
+{
+	rpi_clk_set_state(hw, false);
+}
+
+static unsigned long rpi_clk_get_rate(struct clk_hw *hw,
+				      unsigned long parent_rate)
+{
+	struct rpi_firmware_clock *rpi_clk =
+		container_of(hw, struct rpi_firmware_clock, hw);
+	u32 packet[2];
+	int ret;
+
+	packet[0] = rpi_clk->id;
+	packet[1] = 0;
+	ret = rpi_firmware_property(rpi_clk->firmware,
+				    RPI_FIRMWARE_GET_CLOCK_RATE,
+				    &packet, sizeof(packet));
+	/*
+	 * Note that the second packet field returns 0 on an unknown
+	 * clock error, which would also be a reasonable value for a
+	 * clock that's off.
+	 */
+	if (ret) {
+		dev_err(rpi_clk->dev, "Failed to get clock rate\n");
+		return 0;
+	}
+
+	rpi_clk->last_rate = packet[1];
+
+	return packet[1];
+}
+
+static int rpi_clk_set_rate(struct clk_hw *hw,
+			    unsigned long rate, unsigned long parent_rate)
+{
+	struct rpi_firmware_clock *rpi_clk =
+		container_of(hw, struct rpi_firmware_clock, hw);
+	u32 packet[2];
+	int ret;
+
+	if (rate == rpi_clk->last_rate)
+		return 0;
+
+	packet[0] = rpi_clk->id;
+	packet[1] = rate;
+	ret = rpi_firmware_property(rpi_clk->firmware,
+				    RPI_FIRMWARE_SET_CLOCK_RATE,
+				    &packet, sizeof(packet));
+	/*
+	 * The second packet field has the new clock rate returned, or
+	 * 0 on error.
+	 */
+	if (ret || packet[1] == RPI_FIRMWARE_SET_CLOCK_RATE_ERROR) {
+		dev_err(rpi_clk->dev, "Failed to set clock rate\n");
+		return ret;
+	}
+
+	rpi_clk->last_rate = packet[1];
+
+	return 0;
+}
+
+static long rpi_clk_round_rate(struct clk_hw *hw, unsigned long rate,
+			       unsigned long *parent_rate)
+{
+	/*
+	 * The firmware will end up rounding our rate to something,
+	 * but we don't have an interface for it.  Just return the
+	 * requested value, and it'll get updated after the clock gets
+	 * set.
+	 */
+	return rate;
+}
+
+static struct clk_ops rpi_clk_ops = {
+	.is_prepared = rpi_clk_is_on,
+	.prepare = rpi_clk_on,
+	.unprepare = rpi_clk_off,
+	.recalc_rate = rpi_clk_get_rate,
+	.set_rate = rpi_clk_set_rate,
+	.round_rate = rpi_clk_round_rate,
+};
+
+static int rpi_clk_probe(struct platform_device *pdev)
+{
+	struct device *dev = &pdev->dev;
+	struct device_node *firmware_node;
+	struct rpi_firmware *firmware;
+	struct clk_init_data init;
+	int i;
+	struct clk_onecell_data *onecell;
+
+	firmware_node = of_parse_phandle(dev->of_node,
+					 "raspberrypi,firmware", 0);
+	if (!firmware_node) {
+		dev_err(dev, "Missing firmware node\n");
+		return -ENODEV;
+	}
+	firmware = rpi_firmware_get(firmware_node);
+	if (!firmware)
+		return -EPROBE_DEFER;
+
+	onecell = devm_kmalloc(dev, sizeof(*onecell), GFP_KERNEL);
+	if (!onecell)
+		return -ENOMEM;
+	onecell->clk_num = ARRAY_SIZE(rpi_clocks);
+	onecell->clks = devm_kzalloc(dev, sizeof(*onecell->clks), GFP_KERNEL);
+	if (!onecell->clks)
+		return -ENOMEM;
+
+	memset(&init, 0, sizeof(init));
+	init.ops = &rpi_clk_ops;
+
+	for (i = 0; i < ARRAY_SIZE(rpi_clocks); i++) {
+		struct rpi_firmware_clock *rpi_clk;
+
+		if (!rpi_clocks[i].name)
+			continue;
+
+		rpi_clk = devm_kzalloc(dev, sizeof(*rpi_clk), GFP_KERNEL);
+		if (!rpi_clk)
+			return -ENOMEM;
+
+		rpi_clk->name = rpi_clocks[i].name;
+		rpi_clk->firmware = firmware;
+		rpi_clk->dev = dev;
+		rpi_clk->hw.init = &init;
+		rpi_clk->id = i;
+		init.name = rpi_clocks[i].name;
+		init.flags = rpi_clocks[i].flags;
+
+		onecell->clks[i] = devm_clk_register(&pdev->dev, &rpi_clk->hw);
+		if (IS_ERR(onecell->clks[i]))
+			return PTR_ERR(onecell->clks[i]);
+
+		/* Get the current clock rate/state, to avoid extra on
+		 * to on transitions at boot.
+		 */
+		rpi_clk_get_rate(&rpi_clk->hw, 0);
+	}
+
+	return of_clk_add_provider(pdev->dev.of_node, of_clk_src_onecell_get,
+				   onecell);
+}
+
+static int rpi_clk_remove(struct platform_device *pdev)
+{
+	of_clk_del_provider(pdev->dev.of_node);
+
+	return 0;
+}
+
+static const struct of_device_id rpi_clk_of_match[] = {
+	{ .compatible = "raspberrypi,bcm2835-firmware-clocks", },
+	{},
+};
+MODULE_DEVICE_TABLE(of, rpi_clk_of_match);
+
+static struct platform_driver rpi_clk_driver = {
+	.driver = {
+		.name = "raspberrypi-clk",
+		.of_match_table = rpi_clk_of_match,
+	},
+	.probe		= rpi_clk_probe,
+	.remove		= rpi_clk_remove,
+};
+module_platform_driver(rpi_clk_driver);
+
+MODULE_AUTHOR("Eric Anholt <eric at anholt.net>");
+MODULE_DESCRIPTION("Raspberry Pi clock driver");
+MODULE_LICENSE("GPL v2");
-- 
2.1.4



From sboyd at codeaurora.org  Thu Aug 13 16:18:14 2015
From: sboyd at codeaurora.org (Stephen Boyd)
Date: Thu, 13 Aug 2015 16:18:14 -0700
Subject: [PATCH 1/3] ARM: qcom: add SFPB nodes to IPQ806x dts
In-Reply-To: <1439501620-24073-2-git-send-email-mathieu@codeaurora.org>
References: <1439501620-24073-1-git-send-email-mathieu@codeaurora.org>
 <1439501620-24073-2-git-send-email-mathieu@codeaurora.org>
Message-ID: <55CD25B6.6050901@codeaurora.org>

On 08/13/2015 02:33 PM, Mathieu Olivari wrote:
> Add one new node to the ipq806x.dtsi file to declare & register the
> hardware spinlock devices. This mechanism is required to be used by
> other drivers such as SMEM.
>
> Signed-off-by: Mathieu Olivari <mathieu at codeaurora.org>
> ---
>   arch/arm/boot/dts/qcom-ipq8064.dtsi | 12 ++++++++++++
>   1 file changed, 12 insertions(+)
>
> diff --git a/arch/arm/boot/dts/qcom-ipq8064.dtsi b/arch/arm/boot/dts/qcom-ipq8064.dtsi
> index 9f727d8..ea7b959 100644
> --- a/arch/arm/boot/dts/qcom-ipq8064.dtsi
> +++ b/arch/arm/boot/dts/qcom-ipq8064.dtsi
> @@ -67,6 +67,18 @@
>   			clock-frequency = <32768>;
>   			#clock-cells = <0>;
>   		};
> +
> +		sfpb_mutex_block: syscon at 01200600 {

I think you can drop the leading 0 here. Also this should be moved into 
the soc node.

> +			compatible = "syscon";
> +			reg = <0x01200600 0x100>;
> +		};
> +
> +		sfpb_mutex: sfpb-mutex {
> +			compatible = "qcom,sfpb-mutex";
> +			syscon = <&sfpb_mutex_block 4 4>;
> +
> +			#hwlock-cells = <1>;
> +		};

And this node should be moved to the root /.
>   	};
>   
>   	soc: soc {


-- 
Qualcomm Innovation Center, Inc. is a member of Code Aurora Forum,
a Linux Foundation Collaborative Project



From sfr at canb.auug.org.au  Thu Aug 13 16:22:37 2015
From: sfr at canb.auug.org.au (Stephen Rothwell)
Date: Fri, 14 Aug 2015 09:22:37 +1000
Subject: [GIT PULL] at91: defconfig for 4.3 #2
In-Reply-To: <20150813122643.GA23581@localhost>
References: <20150807162754.GA20169@piout.net>
 <20150813100938.GN30160@localhost>
 <20150813112118.GA22269@piout.net>
 <20150813122643.GA23581@localhost>
Message-ID: <20150814092237.3551c03e@canb.auug.org.au>

Hi Olof,

On Thu, 13 Aug 2015 14:26:43 +0200 Olof Johansson <olof at lixom.net> wrote:
>
> On Thu, Aug 13, 2015 at 01:21:18PM +0200, Alexandre Belloni wrote:
> > On 13/08/2015 at 12:09:38 +0200, Olof Johansson wrote :
> > > On Fri, Aug 07, 2015 at 06:27:54PM +0200, Alexandre Belloni wrote:
> > > > 
> > > > A little defconfig update. That will probably be all for this cycle.
> > > > 
> > > > Thanks, bye,
> > > > 
> > > > 
> > > > The following changes since commit eff7f41572a645bf14a96a6f844be4f1c88cd9dd:
> > > > 
> > > >   ARM: at91: at91_dt_defconfig: enable ISI and ov2640 support (2015-07-30 14:17:31 +0200)
> > > > 
> > > > are available in the git repository at:
> > > > 
> > > >   git://git.kernel.org/pub/scm/linux/kernel/git/abelloni/linux.git tags/at91-ab-defconfig2
> > > > 
> > > > for you to fetch changes up to ea7bf603fd494391acc1f42acbfc34260b965c44:
> > > > 
> > > >   ARM: at91/defconfig: at91_dt: remove ARM_AT91_ETHER (2015-08-07 12:07:50 +0200)
> > > 
> > > Nicolas had sent me one patch which you've also included here but it's not in
> > > the pull request ("enable ISI and ov2640 support"). That caused a conflict
> > > here, so to avoid having the patch in the tree twice I instead also directly
> > > applied your patches from this branch instead of merging.
> > > 
> > > Sorry about that, it started due to Nicolas sending the discrete patch to us.
> > > So it seems like we'll apply at91 defconfig updates directly this release, in
> > > case there are any more. No big deal I hope. :)
> > 
> > That's not a big deal and there will most probably be all for that cycle
> > anyway.
> > 
> > However, I'm wondering how I should have done. From the PR, if you get
> > eff7f41572a645bf14a96a6f844be4f1c88cd9dd..tags/at91-ab-defconfig2, it
> > correctly excludes "enable ISI and ov2640 support" so I was thinking it
> > was fine.
> > Be cause the first patch was taken as a patch, should I have prepared a
> > branch without it?
> 
> Yeah, you could have applied the other two if there were no conflicts. If there
> were conflicts then it gets complicated, and the best answer would probably
> have been to continue applying directly as patches.
> 
> This is the drawback of us sometimes applying patches directly -- when we do,
> we no longer put them on a branch of their own that you can use as base. We
> used to once upon a time but it is quite a bit of overhead for us and the
> upside was pretty limited.

The only thing now is that since the at91 tree is in linux-next as well
as the arm-soc tree, those patches appear twice there and there is a
conflict (easy to fix, but a pain).  The solution here is to update the
at91 tree to be somewhere in the arm-soc tree (probably just reset to
the point where the two trees match in patches but not commits).  This
has the downside that the at91 tree will be rebased which will affect
any development work that is based on that.

If there was just one patch in common, it maybe have been better to
just merge the at91 tree and fix the conflict in the merge.
-- 
Cheers,
Stephen Rothwell                    sfr at canb.auug.org.au


From gregory.0xf0 at gmail.com  Thu Aug 13 16:49:57 2015
From: gregory.0xf0 at gmail.com (Gregory Fong)
Date: Thu, 13 Aug 2015 16:49:57 -0700
Subject: [PATCH v4 2/4] gpio: brcmstb: Add interrupt and wakeup source
 support
In-Reply-To: <CACRpkdaz3k_N1qS5M_jmprPz8fHXeLtTke_YT8i2gaehmme+OQ@mail.gmail.com>
References: <1438391865-7862-1-git-send-email-gregory.0xf0@gmail.com>
 <1438391865-7862-3-git-send-email-gregory.0xf0@gmail.com>
 <CACRpkdaz3k_N1qS5M_jmprPz8fHXeLtTke_YT8i2gaehmme+OQ@mail.gmail.com>
Message-ID: <CADtm3G7NQqDKwGujZUA9CUJ15+e8fLg0Kupbn2CMc0MeK9DbMw@mail.gmail.com>

On Thu, Aug 13, 2015 at 4:11 AM, Linus Walleij <linus.walleij at linaro.org> wrote:
> On Sat, Aug 1, 2015 at 3:17 AM, Gregory Fong <gregory.0xf0 at gmail.com> wrote:
>
>> Uses the gpiolib irqchip helpers.  For this to work, the irq setup
>> function is called once per bank instead of once per device.  Note
>> that all known uses of this block have a BCM7120 L2 interrupt
>> controller as a parent.  Supports interrupts for all GPIOs.
>>
>> In the IRQ handler, we check for raised IRQs for invalid GPIOs and
>> warn (ratelimited) if they're encountered.
>>
>> Also, several drivers (e.g. gpio-keys) allow for GPIOs to be
>> configured as wakeup sources, and this GPIO controller supports that
>> through a separate interrupt path.
>>
>> The de-facto standard DT property "wakeup-source" is checked, since
>> that indicates whether the GPIO controller hardware can wake.  Uses
>> the IRQCHIP_MASK_ON_SUSPEND irq_chip flag because UPG GIO doesn't have
>> any of its own wakeup source configuration.
>>
>> Aside regarding gpiolib irqchip helpers: It wasn't obvious (to me)
>> that you can have multiple chained irqchips and associated IRQ domains
>> for a single parent IRQ, and as long as the xlate function is written
>> correctly, a GPIO IRQ request end up checking the correct domain and
>> will get associated with the correct IRQ.  What helps make this clear
>> is to read
>>   drivers/gpio/gpiolib-of.c:
>>    - of_gpiochip_find_and_xlate()
>>    - of_get_named_gpiod_flags()
>>   drivers/gpio/gpiolib.c:
>>    - gpiochip_find()
>>
>> Signed-off-by: Gregory Fong <gregory.0xf0 at gmail.com>
>> ---
>> v4:
>> - when checking parent_irq, use <= 0 or > 0 since 0 is NO_IRQ.
>
> Patch applied, but:
>
>
>> +       if (of_property_read_bool(np, "interrupt-controller")) {
>> +               priv->parent_irq = platform_get_irq(pdev, 0);
>> +               if (priv->parent_irq <= 0) {
>> +                       dev_err(dev, "Couldn't get IRQ");
>> +                       return -ENOENT;
>> +               }
>> +       } else {
>> +               priv->parent_irq = -ENOENT;
>> +       }
>> +
>>         if (brcmstb_gpio_sanity_check_banks(dev, np, res))
>>                 return -EINVAL;
>
> This patch does not apply cleanly because the version in my
> tree has INIT_LIST_HEAD(&priv->bank_list);
> before the sanity check.
>
> I applied it manually, but check that things are working right.

Your tree seems to be missing

commit 2252607d327d5219a6331b50e6ec266d56402be0
Author: Gregory Fong <gregory.0xf0 at gmail.com>
Date:   Wed Jun 17 18:00:40 2015 -0700

    gpio: brcmstb: fix null ptr dereference in driver remove

which you had pulled in and sent for 4.2-rc1.  It should apply cleanly
on top of that.


From sboyd at codeaurora.org  Thu Aug 13 16:57:50 2015
From: sboyd at codeaurora.org (Stephen Boyd)
Date: Thu, 13 Aug 2015 16:57:50 -0700
Subject: [PATCH 2/3] ARM: qcom: add SMEM device node to IPQ806x dts
In-Reply-To: <1439501620-24073-3-git-send-email-mathieu@codeaurora.org>
References: <1439501620-24073-1-git-send-email-mathieu@codeaurora.org>
 <1439501620-24073-3-git-send-email-mathieu@codeaurora.org>
Message-ID: <55CD2EFE.8040606@codeaurora.org>

On 08/13/2015 02:33 PM, Mathieu Olivari wrote:
> @@ -79,6 +79,15 @@
>   
>   			#hwlock-cells = <1>;
>   		};
> +
> +		smem {
> +			compatible = "qcom,smem";
> +
> +			memory-region = <&smem>;
> +			reg = <0x41000000 0x4000>;

Does this reg property do something? I thought we were supposed to leave 
this out when not using the rpm msg ram. Also, if there's no reg, it 
should be at the root /.

-- 
Qualcomm Innovation Center, Inc. is a member of Code Aurora Forum,
a Linux Foundation Collaborative Project



From davem at davemloft.net  Thu Aug 13 17:00:15 2015
From: davem at davemloft.net (David Miller)
Date: Thu, 13 Aug 2015 17:00:15 -0700 (PDT)
Subject: [PATCH 0/2] Enable smsc911x for use with ACPI
In-Reply-To: <1439417187-21411-1-git-send-email-jeremy.linton@arm.com>
References: <1439417187-21411-1-git-send-email-jeremy.linton@arm.com>
Message-ID: <20150813.170015.1983400219932580352.davem@davemloft.net>

From: Jeremy Linton <jeremy.linton at arm.com>
Date: Wed, 12 Aug 2015 17:06:25 -0500

> This set of patches enables the front Ethernet port on the
> ARM Juno development platform when used with an ACPI enabled kernel.
> 
> These patches covert the of_property* calls in the driver to the
> DT/ACPI agnostic device_property* calls, and add the arm hardware
> id to the acpi_match_table.
> 
> To support the above changes I copied a couple routines from
> of_net into the properties.c file, and modified them to
> be ACPI/DT agnostic. I'm not 100% sure this is the correct location
> for these functions. But I think they are required to avoid having
> a dozen different implementations scattered across assorted Ethernet
> adapters that are being enabled to use ACPI properties.

I realize that there are still some rinkles to work out, but I applied
this patch series as-is to net-next, and any fixups should be
submitted as followups.

Thanks.



From horms at verge.net.au  Thu Aug 13 17:30:23 2015
From: horms at verge.net.au (Simon Horman)
Date: Fri, 14 Aug 2015 09:30:23 +0900
Subject: [PATCH v2 0/6] ARM: shmobile: Move gpio ranges from C code to DT
In-Reply-To: <CAMuHMdW0T6MW6s4Gg_rqvtt+MRPtp_MpuiKtamfFrx-Tcm6WmQ@mail.gmail.com>
References: <1438696519-13727-1-git-send-email-geert+renesas@glider.be>
 <20150805005540.GB20726@verge.net.au>
 <CACRpkdY7P86+SxMr5-HnhrN5fC-N1U135jiGAJGTV=xx47VW5g@mail.gmail.com>
 <CAMuHMdW0T6MW6s4Gg_rqvtt+MRPtp_MpuiKtamfFrx-Tcm6WmQ@mail.gmail.com>
Message-ID: <20150814003023.GC12589@verge.net.au>

On Thu, Aug 13, 2015 at 02:45:55PM +0200, Geert Uytterhoeven wrote:
> Hi Linus,
> 
> On Thu, Aug 13, 2015 at 2:29 PM, Linus Walleij <linus.walleij at linaro.org> wrote:
> > On Wed, Aug 5, 2015 at 2:55 AM, Simon Horman <horms at verge.net.au> wrote:
> >> Where possible I prefer not to apply non-DTS/DTSI patches on top of
> >> DTS/DTSI patches, I believe this is in keeping with how the ARM SoC
> >> maintainers like things handled.  With this in mind I have done the following:
> >>
> >> 1. Queued up the DTSI patches (patches 1 - 3) for v4.3 in my dt branch.
> >>    I intend for this to turn up in next soon.
> >> 2. Queued up for pinctrl patches (patches 4 - 6) for v4.4 in a pinctrl patch.
> >>    I intend for these to be present in the renesas devel branch but
> >>    not in next until after the release of v4.3-rc1. I would also be
> >>    happy to drop them and let Linus Walleij take these patches for v4.4,
> >>    assuming patches 1 - 3 are accepted for v4.3.
> >
> > OK.
> >
> > Will the world explode if I try to queue the pinctrl patches 4-6 in my
> > tree now for v4.3? Then I prefer to defer to v4.4. Else I can merge
> > it in parallel?
> 
> There won't be a mapping between gpio and pins in any branch having the
> pinctrl changes but not the dtsi changes.

It sounds to me that Linus should take his option 2; defer to v4.4.
In which case I should drop the changes from my tree (they are not in next
anyway). Please let me know if thats the way we will move this forwards.



From sboyd at codeaurora.org  Thu Aug 13 17:38:02 2015
From: sboyd at codeaurora.org (Stephen Boyd)
Date: Thu, 13 Aug 2015 17:38:02 -0700
Subject: [PATCH 3/3] mtd: add SMEM parser for QCOM platforms
In-Reply-To: <1439501620-24073-4-git-send-email-mathieu@codeaurora.org>
References: <1439501620-24073-1-git-send-email-mathieu@codeaurora.org>
 <1439501620-24073-4-git-send-email-mathieu@codeaurora.org>
Message-ID: <55CD386A.5070801@codeaurora.org>

On 08/13/2015 02:33 PM, Mathieu Olivari wrote:
> diff --git a/drivers/mtd/qcom_smem_part.c b/drivers/mtd/qcom_smem_part.c
> new file mode 100644
> index 0000000..6cbf610
> --- /dev/null
> +++ b/drivers/mtd/qcom_smem_part.c
>
> +#define SMEM_PARTS_MAX			32
> +
> +struct smem_partition {
> +	char name[SMEM_PART_NAME_SZ];
> +	uint32_t start;
> +	uint32_t size;
> +	uint32_t attr;

Is this little endian? __le32? I think so.

> +};
> +
> +struct smem_partition_table {
> +	uint32_t magic[2];
> +	uint32_t version;
> +	uint32_t len;

Same for these being little endian. And if so, please make magic into a 
byte array of size 8 and then do a memcmp with another static byte array.

> +	struct smem_partition parts[SMEM_PARTS_MAX];
> +};
> +
> +static int qcom_smem_get_flash_blksz(uint64_t **smem_blksz)

I don't know, but I prefer u64 because it's short and sweet. But I'm not 
the maintainer here.

> +{
> +	int ret;
> +	size_t size;
> +
> +	ret = qcom_smem_get(SMEM_HOST_APPS, SMEM_BOOT_FLASH_BLOCK_SIZE,
> +			    (void **) smem_blksz, &size);

Is the cast necessary?

> +
> +	if (ret < 0) {
> +		pr_err("Unable to read flash blksz from SMEM\n");
> +		return -ENOENT;
> +	}
> +
> +	if (size != sizeof(**smem_blksz)) {
> +		pr_err("Invalid flash blksz size in SMEM\n");
> +		return -EINVAL;
> +	}
> +
> +	return 0;
> +}
> +
> +static int qcom_smem_get_flash_type(uint64_t **smem_flash_type)
> +{
> +	int ret;
> +	size_t size;
> +
> +	ret = qcom_smem_get(SMEM_HOST_APPS, SMEM_BOOT_FLASH_TYPE,
> +			    (void **) smem_flash_type, &size);
> +
> +	if (ret < 0) {
> +		pr_err("Unable to read flash type from SMEM\n");
> +		return -ENOENT;
> +	}
> +
> +	if (size != sizeof(**smem_flash_type)) {
> +		pr_err("Invalid flash type size in SMEM\n");
> +		return -EINVAL;
> +	}
> +
> +	return 0;
> +}
> +
> +static int qcom_smem_get_flash_partitions(struct smem_partition_table **pparts)
> +{
> +	int ret;
> +	size_t size;
> +
> +	ret = qcom_smem_get(SMEM_HOST_APPS, SMEM_AARM_PARTITION_TABLE,
> +			    (void **) pparts, &size);
> +
> +	if (ret < 0) {
> +		pr_err("Unable to read partition table from SMEM\n");
> +		return -ENOENT;
> +	}
> +
> +	return 0;
> +}
> +
> +static int of_dev_node_match(struct device *dev, void *data)
> +{
> +	return dev->of_node == data;
> +}
> +
> +static bool is_spi_device(struct device_node *np)
> +{
> +	struct device *dev;
> +
> +	dev = bus_find_device(&spi_bus_type, NULL, np, of_dev_node_match);

I'm pretty sure this holds a reference to the device that needs to be 
released with put_device().

> +	return dev ? true : false;
> +}
> +
> +static int parse_qcom_smem_partitions(struct mtd_info *master,
> +				      struct mtd_partition **pparts,
> +				      struct mtd_part_parser_data *data)
> +{
> +	struct smem_partition_table *smem_parts;
> +	uint64_t *smem_flash_type, *smem_blksz;
> +	struct mtd_partition *mtd_parts;
> +	struct device_node *of_node = data->of_node;
> +	int i, ret;
> +
> +	/*
> +	 * SMEM will only store the partition table of the boot device.
> +	 * If this is not the boot device, do not return any partition.
> +	 */
> +	ret = qcom_smem_get_flash_type(&smem_flash_type);
> +	if (ret < 0)
> +		return ret;
> +
> +	if ((*smem_flash_type == SMEM_FLASH_NAND && !mtd_type_is_nand(master))
> +	    || (*smem_flash_type == SMEM_FLASH_SPI && !is_spi_device(of_node)))
> +		return 0;
> +
> +	/*
> +	 * Just for sanity purpose, make sure the block size in SMEM matches the
> +	 * block size of the MTD device
> +	 */
> +	ret = qcom_smem_get_flash_blksz(&smem_blksz);
> +	if (ret < 0)
> +		return ret;
> +
> +	if (*smem_blksz != master->erasesize) {
> +		pr_err("SMEM block size differs from MTD block size\n");
> +		return -EINVAL;
> +	}
> +
> +	/* Get partition pointer from SMEM */
> +	ret = qcom_smem_get_flash_partitions(&smem_parts);
> +	if (ret < 0)
> +		return ret;
> +
> +	if (smem_parts->magic[0] != SMEM_PTABLE_MAGIC_1 ||
> +	    smem_parts->magic[1] != SMEM_PTABLE_MAGIC_2) {
> +		pr_err("SMEM partition magic invalid\n");
> +		return -EINVAL;
> +	}
> +
> +	/* Allocate and populate the mtd structures */
> +	mtd_parts = kcalloc(smem_parts->len, sizeof(struct mtd_partition),

sizeof(*mtd_parts)?

> +			    GFP_KERNEL);
> +	if (mtd_parts == NULL)

if (!mtd_parts) is more kernel style.

> +		return -ENOMEM;
> +
> +	for (i = 0; i < smem_parts->len; i++) {
> +		struct smem_partition *part = &smem_parts->parts[i];
> +
> +		mtd_parts[i].name = part->name;
> +		mtd_parts[i].size = part->size * (*smem_blksz);
> +		mtd_parts[i].offset = part->start * (*smem_blksz);
> +
> +		/*
> +		 * The last SMEM partition may have its size marked as
> +		 * something like 0xffffffff, which means "until the end of the
> +		 * flash device". In this case, truncate it.
> +		 */
> +		if (mtd_parts[i].offset + mtd_parts[i].size > master->size)
> +			mtd_parts[i].size = master->size - mtd_parts[i].offset;

That is 7 mtd_parts[i]. instances. Consider making a local variable 
pointer instead. Actually we could make two pointers for 
smem_parts->part and mtd_parts and increment both in the loop to make 
tighter code.

> +	}
> +
> +	*pparts = mtd_parts;

Oh we already have the pointer, so just do this assignment before iterating.

-- 
Qualcomm Innovation Center, Inc. is a member of Code Aurora Forum,
a Linux Foundation Collaborative Project



From sboyd at codeaurora.org  Thu Aug 13 17:42:06 2015
From: sboyd at codeaurora.org (Stephen Boyd)
Date: Thu, 13 Aug 2015 17:42:06 -0700
Subject: [PATCH 5/9] clk: qcom: gcc-msm8960: add child devices support.
In-Reply-To: <55CC1CFE.7000005@codeaurora.org>
References: <1436348838-22671-1-git-send-email-rnayak@codeaurora.org>
 <1436348838-22671-6-git-send-email-rnayak@codeaurora.org>
 <20150811224902.GO2839@codeaurora.org>
 <55CB0B26.2020105@linaro.org> <55CC1CFE.7000005@codeaurora.org>
Message-ID: <20150814004206.GU26614@codeaurora.org>

On 08/13, Rajendra Nayak wrote:
> >On 11/08/15 23:49, Stephen Boyd wrote:
> >>On 07/08, Rajendra Nayak wrote:
> >>>diff --git a/drivers/clk/qcom/gcc-msm8960.c
> >>>b/drivers/clk/qcom/gcc-msm8960.c
> >>>index eb6a4f9..2c80d03 100644
> >>>--- a/drivers/clk/qcom/gcc-msm8960.c
> >>>+++ b/drivers/clk/qcom/gcc-msm8960.c
> >>>@@ -15,6 +15,7 @@
> >>>  #include <linux/bitops.h>
> >>>  #include <linux/err.h>
> >>>  #include <linux/platform_device.h>
> >>>+#include <linux/of_platform.h>
> >>>  #include <linux/module.h>
> >>>  #include <linux/of.h>
> >>>  #include <linux/of_device.h>
> >>>@@ -3520,7 +3521,8 @@ static int gcc_msm8960_probe(struct
> >>>platform_device *pdev)
> >>>      if (IS_ERR(clk))
> >>>          return PTR_ERR(clk);
> >>>
> >>>-    return qcom_cc_probe(pdev, match->data);
> >>>+    qcom_cc_probe(pdev, match->data);
> >>>+    return of_platform_populate(pdev->dev.of_node, NULL, NULL,
> >>>&pdev->dev);
> >>
> >>We just lost the error code from qcom_cc_probe()...
> >>
> >I think Rajendra picked up the wrong patch for this series, I did submit
> >a v2 (https://patches.linaro.org/44033/) with the above fixed.
> 
> ah, sorry about that.
> 
> >>Also, I don't like having a subnode in DT. Why can't we use the
> >>same node as the GCC node and create a virtual child device here
> >>for tsens? We can assign the same of_node that this platform
> >>device has so that DT keeps working correctly.
> 
> So the current driver looks up data based on compatible strings.

The tsens device is always the same piece of hardware. The only
thing that's changing is the qfprom data and the number of
sensors. So we should be looking at the qfprom compatible string
to figure out how to interpret the qfprom data which would
include the number of sensors and how the data is encoded.

> So you suggesting to create a virtual child device for gcc and
> associate the gcc DT node to it? (And have the tsens compatible
> mentioned as part of the gcc DT node?)

No. The driver should work just fine without having to
interrogate the device's compatible string. If we still need the
compatible check for some reason, then we can always match based
on qcom,gcc-msm8960, qcom,gcc-apq8064, etc. But I don't see why
we need to do that when we should be looking at what type of
qfprom is connected so we can correctly parse the data.

> How is this any different from creating a subnode in DT anyway?

The difference is we don't make up nodes to satisfy linux device
driver design. I suspect the hardware engineers put tsens inside
gcc because both blocks were written by the same person/team and
they just needed some place to jam some registers and call it a
day. That doesn't constitute an MFD or bus, which is what we
would be expressing in DT if we made a child node, it constitutes
a horrible software interface design that we have to live with.

-- 
Qualcomm Innovation Center, Inc. is a member of Code Aurora Forum,
a Linux Foundation Collaborative Project


From sboyd at codeaurora.org  Thu Aug 13 17:46:02 2015
From: sboyd at codeaurora.org (Stephen Boyd)
Date: Thu, 13 Aug 2015 17:46:02 -0700
Subject: [PATCH 5/9] clk: qcom: gcc-msm8960: add child devices support.
In-Reply-To: <20150813041402.GI13472@usrtlx11787.corpusers.net>
References: <1436348838-22671-1-git-send-email-rnayak@codeaurora.org>
 <1436348838-22671-6-git-send-email-rnayak@codeaurora.org>
 <20150811224902.GO2839@codeaurora.org>
 <20150812201855.GF13472@usrtlx11787.corpusers.net>
 <55CBC14B.8000509@codeaurora.org>
 <20150813041402.GI13472@usrtlx11787.corpusers.net>
Message-ID: <20150814004602.GV26614@codeaurora.org>

On 08/12, Bjorn Andersson wrote:
> On Wed 12 Aug 14:57 PDT 2015, Stephen Boyd wrote:
> 
> > Here's the patch I'm suggesting. The device name is probably wrong, but 
> > you get the idea.
> 
> Looks very much like my take on it as well, I do however have concerns
> that suddenly the node called "clock-controller" will have to come with
> tsens related properties.
> 
> Are all the tsens-in-gcc blocks the same?

Yes they're all the same, except some of them have more sensors
than others. It depends on what SoC the hardware is instantiated
in. They also messed up the software interface and had to add
discontinuous registers for the sensors because it was never
designed to have more than 4 sensors or something like that. But
even that sort of change can be handled by figuring out the
format of the sensor data in the qfprom.

> Or do you intend to of_match
> on the gcc compatible in the tsens driver?
> 

I hope we don't have to of_match in the tsens driver on gcc
compatible strings.

-- 
Qualcomm Innovation Center, Inc. is a member of Code Aurora Forum,
a Linux Foundation Collaborative Project


From sboyd at codeaurora.org  Thu Aug 13 18:01:09 2015
From: sboyd at codeaurora.org (Stephen Boyd)
Date: Thu, 13 Aug 2015 18:01:09 -0700
Subject: [PATCH V3 4/5] clk: core: add CLK_OPS_PARENT_ON flags to support
 clocks require parent on
In-Reply-To: <1438089585-30103-5-git-send-email-aisheng.dong@freescale.com>
References: <1438089585-30103-1-git-send-email-aisheng.dong@freescale.com>
 <1438089585-30103-5-git-send-email-aisheng.dong@freescale.com>
Message-ID: <20150814010109.GW26614@codeaurora.org>

On 07/28, Dong Aisheng wrote:
> On Freescale i.MX7D platform, all clocks operations, including
> enable/disable, rate change and re-parent, requires its parent
> clock on. Current clock core can not support it well.
> This patch introduce a new flag CLK_OPS_PARENT_ON to handle this
> special case in clock core that enable its parent clock firstly for
> each operation and disable it later after operation complete.
> 
> This patch fixes disaling clocks while its parent is off.
> This is a special case that is caused by a state mis-align between
> HW and SW in clock tree during booting.
> Usually in uboot, we may enable all clocks in HW by default.
> And during kernel booting time, the parent clock could be disabled in its
> driver probe due to calling clk_prepare_enable and clk_disable_unprepare.
> Because it's child clock is only enabled in HW while its SW usecount
> in clock tree is still 0, so clk_disable of parent clock will gate
> the parent clock in both HW and SW usecount ultimately.
> Then there will be a clock is on in HW while its parent is disabled.
> 
> Later when clock core does clk_disable_unused, this clock disable
> will cause system hang due to the limitation of operation requiring
> its parent clock on.
> 
> Cc: Mike Turquette <mturquette at linaro.org>
> Cc: Stephen Boyd <sboyd at codeaurora.org>
> Signed-off-by: Dong Aisheng <aisheng.dong at freescale.com>
> ---

Sorry, I still don't agree with this patch. There's no reason we
should be turning on clocks during late init so that we can turn
off clocks. If there's some sort of problem in doing that we
should figure it out and make it so that during late init we turn
off clocks from the leaves of the tree to the root.

I agree that there's a problem here where we don't properly
handle keeping children clocks on if a driver comes in and turns
off a clock in the middle of the tree before late init. That's a
real bug, and we should fix it. Mike Turquette has been doing
some work to have a way to indicate that certain clocks should be
kept on until client drivers grab them. I think it will also make
sure to up refcounts on parent clocks in the middle of the tree
when it figures out that a child clock is enabled. Would that be
all that we need to do to fix this problem?

Also, the subject of this patch and patch 5 are the same. Why?

-- 
Qualcomm Innovation Center, Inc. is a member of Code Aurora Forum,
a Linux Foundation Collaborative Project


From 21cnbao at gmail.com  Thu Aug 13 18:11:02 2015
From: 21cnbao at gmail.com (Barry Song)
Date: Fri, 14 Aug 2015 01:11:02 +0000
Subject: [PATCH 1/2] clk: atlas7: move variable-definition together
Message-ID: <1439514663-23979-1-git-send-email-21cnbao@gmail.com>

From: Guo Zeng <Guo.Zeng at csr.com>

re-order the codes more reasonable by moving variable-definition
together.

Signed-off-by: Guo Zeng <Guo.Zeng at csr.com>
Signed-off-by: Barry Song <Baohua.Song at csr.com>
---
 drivers/clk/sirf/clk-atlas7.c | 24 ++++++++++++------------
 1 file changed, 12 insertions(+), 12 deletions(-)

diff --git a/drivers/clk/sirf/clk-atlas7.c b/drivers/clk/sirf/clk-atlas7.c
index a98e21f..d34d1b3 100644
--- a/drivers/clk/sirf/clk-atlas7.c
+++ b/drivers/clk/sirf/clk-atlas7.c
@@ -206,18 +206,6 @@
 #define SIRFSOC_CLKC_LEAF_CLK_EN8_SET        0x0548
 
 
-static void __iomem *sirfsoc_clk_vbase;
-static struct clk_onecell_data clk_data;
-
-static const struct clk_div_table pll_div_table[] = {
-	{ .val = 0, .div = 1 },
-	{ .val = 1, .div = 2 },
-	{ .val = 2, .div = 4 },
-	{ .val = 3, .div = 8 },
-	{ .val = 4, .div = 16 },
-	{ .val = 5, .div = 32 },
-};
-
 struct clk_pll {
 	struct clk_hw hw;
 	u16 regofs;  /* register offset */
@@ -284,6 +272,18 @@ struct atlas7_reset_desc {
 	spinlock_t *lock;
 };
 
+static void __iomem *sirfsoc_clk_vbase;
+static struct clk_onecell_data clk_data;
+
+static const struct clk_div_table pll_div_table[] = {
+	{ .val = 0, .div = 1 },
+	{ .val = 1, .div = 2 },
+	{ .val = 2, .div = 4 },
+	{ .val = 3, .div = 8 },
+	{ .val = 4, .div = 16 },
+	{ .val = 5, .div = 32 },
+};
+
 static DEFINE_SPINLOCK(cpupll_ctrl1_lock);
 static DEFINE_SPINLOCK(mempll_ctrl1_lock);
 static DEFINE_SPINLOCK(sys0pll_ctrl1_lock);
-- 
1.9.1



From 21cnbao at gmail.com  Thu Aug 13 18:11:03 2015
From: 21cnbao at gmail.com (Barry Song)
Date: Fri, 14 Aug 2015 01:11:03 +0000
Subject: [PATCH 2/2] clk: atlas7: fix noc/socket disconnect/reconnect for unit
 clks
In-Reply-To: <1439514663-23979-1-git-send-email-21cnbao@gmail.com>
References: <1439514663-23979-1-git-send-email-21cnbao@gmail.com>
Message-ID: <1439514663-23979-2-git-send-email-21cnbao@gmail.com>

From: Guo Zeng <Guo.Zeng at csr.com>

Power management on of NoC(Notwork On Chip) requires that disconnect
and reconnect routine should been done during clk disable/enable.

also there are different types of clocks,
For NoC Macro clocks, write idle_bit and wait for hardward ACK;
For Socket clocks, write idle_bit;
For others, do nothing.

Signed-off-by: Guo Zeng <Guo.Zeng at csr.com>
Signed-off-by: Barry Song <Baohua.Song at csr.com>
---
 drivers/clk/sirf/clk-atlas7.c | 334 ++++++++++++++++++++++++------------------
 1 file changed, 188 insertions(+), 146 deletions(-)

diff --git a/drivers/clk/sirf/clk-atlas7.c b/drivers/clk/sirf/clk-atlas7.c
index d34d1b3..957aae6 100644
--- a/drivers/clk/sirf/clk-atlas7.c
+++ b/drivers/clk/sirf/clk-atlas7.c
@@ -205,6 +205,11 @@
 #define SIRFSOC_CLKC_LEAF_CLK_EN7_SET        0x0530
 #define SIRFSOC_CLKC_LEAF_CLK_EN8_SET        0x0548
 
+#define SIRFSOC_NOC_CLK_IDLEREQ_SET		0x02D0
+#define SIRFSOC_NOC_CLK_IDLEREQ_CLR		0x02D4
+#define SIRFSOC_NOC_CLK_SLVRDY_SET		0x02E8
+#define SIRFSOC_NOC_CLK_SLVRDY_CLR		0x02EC
+#define SIRFSOC_NOC_CLK_IDLE_STATUS		0x02F4
 
 struct clk_pll {
 	struct clk_hw hw;
@@ -219,10 +224,18 @@ struct clk_dto {
 };
 #define to_dtoclk(_hw) container_of(_hw, struct clk_dto, hw)
 
+enum clk_unit_type {
+	CLK_UNIT_NOC_OTHER,
+	CLK_UNIT_NOC_CLOCK,
+	CLK_UNIT_NOC_SOCKET,
+};
+
 struct clk_unit {
 	struct clk_hw hw;
 	u16 regofs;
 	u16 bit;
+	u32 type;
+	u8 idle_bit;
 	spinlock_t *lock;
 };
 #define to_unitclk(_hw) container_of(_hw, struct clk_unit, hw)
@@ -260,6 +273,8 @@ struct atlas7_unit_init_data {
 	unsigned long flags;
 	u32 regofs;
 	u8 bit;
+	u32 type;
+	u8 idle_bit;
 	spinlock_t *lock;
 };
 
@@ -1040,148 +1055,148 @@ static struct atlas7_mux_init_data mux_list[] __initdata = {
 	/* new unit should add start from the tail of list */
 static struct atlas7_unit_init_data unit_list[] __initdata = {
 	/* unit_name, parent_name, flags, regofs, bit, lock */
-	{ 0, "audmscm_kas", "kas_mux", 0, SIRFSOC_CLKC_ROOT_CLK_EN0_SET, 0, &root0_gate_lock },
-	{ 1, "gnssm_gnss", "gnss_mux", 0, SIRFSOC_CLKC_ROOT_CLK_EN0_SET, 1, &root0_gate_lock },
-	{ 2, "gpum_gpu", "gpu_mux", 0, SIRFSOC_CLKC_ROOT_CLK_EN0_SET, 2, &root0_gate_lock },
-	{ 3, "mediam_g2d", "g2d_mux", 0, SIRFSOC_CLKC_ROOT_CLK_EN0_SET, 3, &root0_gate_lock },
-	{ 4, "mediam_jpenc", "jpenc_mux", 0, SIRFSOC_CLKC_ROOT_CLK_EN0_SET, 4, &root0_gate_lock },
-	{ 5, "vdifm_disp0", "disp0_mux", 0, SIRFSOC_CLKC_ROOT_CLK_EN0_SET, 5, &root0_gate_lock },
-	{ 6, "vdifm_disp1", "disp1_mux", 0, SIRFSOC_CLKC_ROOT_CLK_EN0_SET, 6, &root0_gate_lock },
-	{ 7, "audmscm_i2s", "i2s_mux", 0, SIRFSOC_CLKC_ROOT_CLK_EN0_SET, 8, &root0_gate_lock },
-	{ 8, "audmscm_io", "io_mux", 0, SIRFSOC_CLKC_ROOT_CLK_EN0_SET, 11, &root0_gate_lock },
-	{ 9, "vdifm_io", "io_mux", 0, SIRFSOC_CLKC_ROOT_CLK_EN0_SET, 12, &root0_gate_lock },
-	{ 10, "gnssm_io", "io_mux", 0, SIRFSOC_CLKC_ROOT_CLK_EN0_SET, 13, &root0_gate_lock },
-	{ 11, "mediam_io", "io_mux", 0, SIRFSOC_CLKC_ROOT_CLK_EN0_SET, 14, &root0_gate_lock },
-	{ 12, "btm_io", "io_mux", 0, SIRFSOC_CLKC_ROOT_CLK_EN0_SET, 17, &root0_gate_lock },
-	{ 13, "mediam_sdphy01", "sdphy01_mux", 0, SIRFSOC_CLKC_ROOT_CLK_EN0_SET, 18, &root0_gate_lock },
-	{ 14, "vdifm_sdphy23", "sdphy23_mux", 0, SIRFSOC_CLKC_ROOT_CLK_EN0_SET, 19, &root0_gate_lock },
-	{ 15, "vdifm_sdphy45", "sdphy45_mux", 0, SIRFSOC_CLKC_ROOT_CLK_EN0_SET, 20, &root0_gate_lock },
-	{ 16, "vdifm_sdphy67", "sdphy67_mux", 0, SIRFSOC_CLKC_ROOT_CLK_EN0_SET, 21, &root0_gate_lock },
-	{ 17, "audmscm_xin", "xin", 0, SIRFSOC_CLKC_ROOT_CLK_EN0_SET, 22, &root0_gate_lock },
-	{ 18, "mediam_nand", "nand_mux", 0, SIRFSOC_CLKC_ROOT_CLK_EN0_SET, 27, &root0_gate_lock },
-	{ 19, "gnssm_sec", "sec_mux", 0, SIRFSOC_CLKC_ROOT_CLK_EN0_SET, 28, &root0_gate_lock },
-	{ 20, "cpum_cpu", "cpu_mux", 0, SIRFSOC_CLKC_ROOT_CLK_EN0_SET, 29, &root0_gate_lock },
-	{ 21, "gnssm_xin", "xin", 0, SIRFSOC_CLKC_ROOT_CLK_EN0_SET, 30, &root0_gate_lock },
-	{ 22, "vdifm_vip", "vip_mux", 0, SIRFSOC_CLKC_ROOT_CLK_EN0_SET, 31, &root0_gate_lock },
-	{ 23, "btm_btss", "btss_mux", 0, SIRFSOC_CLKC_ROOT_CLK_EN1_SET, 0, &root1_gate_lock },
-	{ 24, "mediam_usbphy", "usbphy_mux", 0, SIRFSOC_CLKC_ROOT_CLK_EN1_SET, 1, &root1_gate_lock },
-	{ 25, "rtcm_kas", "kas_mux", 0, SIRFSOC_CLKC_ROOT_CLK_EN1_SET, 2, &root1_gate_lock },
-	{ 26, "audmscm_nocd", "nocd_mux", 0, SIRFSOC_CLKC_ROOT_CLK_EN1_SET, 3, &root1_gate_lock },
-	{ 27, "vdifm_nocd", "nocd_mux", 0, SIRFSOC_CLKC_ROOT_CLK_EN1_SET, 4, &root1_gate_lock },
-	{ 28, "gnssm_nocd", "nocd_mux", 0, SIRFSOC_CLKC_ROOT_CLK_EN1_SET, 5, &root1_gate_lock },
-	{ 29, "mediam_nocd", "nocd_mux", 0, SIRFSOC_CLKC_ROOT_CLK_EN1_SET, 6, &root1_gate_lock },
-	{ 30, "cpum_nocd", "nocd_mux", 0, SIRFSOC_CLKC_ROOT_CLK_EN1_SET, 8, &root1_gate_lock },
-	{ 31, "gpum_nocd", "nocd_mux", 0, SIRFSOC_CLKC_ROOT_CLK_EN1_SET, 9, &root1_gate_lock },
-	{ 32, "audmscm_nocr", "nocr_mux", 0, SIRFSOC_CLKC_ROOT_CLK_EN1_SET, 11, &root1_gate_lock },
-	{ 33, "vdifm_nocr", "nocr_mux", 0, SIRFSOC_CLKC_ROOT_CLK_EN1_SET, 12, &root1_gate_lock },
-	{ 34, "gnssm_nocr", "nocr_mux", CLK_IGNORE_UNUSED, SIRFSOC_CLKC_ROOT_CLK_EN1_SET, 13, &root1_gate_lock },
-	{ 35, "mediam_nocr", "nocr_mux", CLK_IGNORE_UNUSED, SIRFSOC_CLKC_ROOT_CLK_EN1_SET, 14, &root1_gate_lock },
-	{ 36, "ddrm_nocr", "nocr_mux", CLK_IGNORE_UNUSED, SIRFSOC_CLKC_ROOT_CLK_EN1_SET, 15, &root1_gate_lock },
-	{ 37, "cpum_tpiu", "tpiu_mux", 0, SIRFSOC_CLKC_ROOT_CLK_EN1_SET, 16, &root1_gate_lock },
-	{ 38, "gpum_nocr", "nocr_mux", 0, SIRFSOC_CLKC_ROOT_CLK_EN1_SET, 17, &root1_gate_lock },
-	{ 39, "gnssm_rgmii", "rgmii_mux", 0, SIRFSOC_CLKC_ROOT_CLK_EN1_SET, 20, &root1_gate_lock },
-	{ 40, "mediam_vdec", "vdec_mux", 0, SIRFSOC_CLKC_ROOT_CLK_EN1_SET, 21, &root1_gate_lock },
-	{ 41, "gpum_sdr", "sdr_mux", 0, SIRFSOC_CLKC_ROOT_CLK_EN1_SET, 22, &root1_gate_lock },
-	{ 42, "vdifm_deint", "deint_mux", 0, SIRFSOC_CLKC_ROOT_CLK_EN1_SET, 23, &root1_gate_lock },
-	{ 43, "gnssm_can", "can_mux", 0, SIRFSOC_CLKC_ROOT_CLK_EN1_SET, 26, &root1_gate_lock },
-	{ 44, "mediam_usb", "usb_mux", 0, SIRFSOC_CLKC_ROOT_CLK_EN1_SET, 28, &root1_gate_lock },
-	{ 45, "gnssm_gmac", "gmac_mux", 0, SIRFSOC_CLKC_ROOT_CLK_EN1_SET, 29, &root1_gate_lock },
-	{ 46, "cvd_io", "audmscm_io", 0, SIRFSOC_CLKC_LEAF_CLK_EN1_SET, 0, &leaf1_gate_lock },
-	{ 47, "timer_io", "audmscm_io", 0, SIRFSOC_CLKC_LEAF_CLK_EN1_SET, 1, &leaf1_gate_lock },
-	{ 48, "pulse_io", "audmscm_io", 0, SIRFSOC_CLKC_LEAF_CLK_EN1_SET, 2, &leaf1_gate_lock },
-	{ 49, "tsc_io", "audmscm_io", 0, SIRFSOC_CLKC_LEAF_CLK_EN1_SET, 3, &leaf1_gate_lock },
-	{ 50, "tsc_xin", "audmscm_xin", 0, SIRFSOC_CLKC_LEAF_CLK_EN1_SET, 21, &leaf1_gate_lock },
-	{ 51, "ioctop_io", "audmscm_io", 0, SIRFSOC_CLKC_LEAF_CLK_EN1_SET, 4, &leaf1_gate_lock },
-	{ 52, "rsc_io", "audmscm_io", 0, SIRFSOC_CLKC_LEAF_CLK_EN1_SET, 5, &leaf1_gate_lock },
-	{ 53, "dvm_io", "audmscm_io", 0, SIRFSOC_CLKC_LEAF_CLK_EN1_SET, 6, &leaf1_gate_lock },
-	{ 54, "lvds_xin", "audmscm_xin", 0, SIRFSOC_CLKC_LEAF_CLK_EN1_SET, 7, &leaf1_gate_lock },
-	{ 55, "kas_kas", "audmscm_kas", 0, SIRFSOC_CLKC_LEAF_CLK_EN1_SET, 8, &leaf1_gate_lock },
-	{ 56, "ac97_kas", "audmscm_kas", 0, SIRFSOC_CLKC_LEAF_CLK_EN1_SET, 9, &leaf1_gate_lock },
-	{ 57, "usp0_kas", "audmscm_kas", 0, SIRFSOC_CLKC_LEAF_CLK_EN1_SET, 10, &leaf1_gate_lock },
-	{ 58, "usp1_kas", "audmscm_kas", 0, SIRFSOC_CLKC_LEAF_CLK_EN1_SET, 11, &leaf1_gate_lock },
-	{ 59, "usp2_kas", "audmscm_kas", 0, SIRFSOC_CLKC_LEAF_CLK_EN1_SET, 12, &leaf1_gate_lock },
-	{ 60, "dmac2_kas", "audmscm_kas", 0, SIRFSOC_CLKC_LEAF_CLK_EN1_SET, 13, &leaf1_gate_lock },
-	{ 61, "dmac3_kas", "audmscm_kas", 0, SIRFSOC_CLKC_LEAF_CLK_EN1_SET, 14, &leaf1_gate_lock },
-	{ 62, "audioif_kas", "audmscm_kas", 0, SIRFSOC_CLKC_LEAF_CLK_EN1_SET, 15, &leaf1_gate_lock },
-	{ 63, "i2s1_kas", "audmscm_kas", 0, SIRFSOC_CLKC_LEAF_CLK_EN1_SET, 17, &leaf1_gate_lock },
-	{ 64, "thaudmscm_io", "audmscm_io", 0, SIRFSOC_CLKC_LEAF_CLK_EN1_SET, 22, &leaf1_gate_lock },
-	{ 65, "analogtest_xin", "audmscm_xin", 0, SIRFSOC_CLKC_LEAF_CLK_EN1_SET, 23, &leaf1_gate_lock },
-	{ 66, "sys2pci_io", "vdifm_io", 0, SIRFSOC_CLKC_LEAF_CLK_EN2_SET, 0, &leaf2_gate_lock },
-	{ 67, "pciarb_io", "vdifm_io", 0, SIRFSOC_CLKC_LEAF_CLK_EN2_SET, 1, &leaf2_gate_lock },
-	{ 68, "pcicopy_io", "vdifm_io", 0, SIRFSOC_CLKC_LEAF_CLK_EN2_SET, 2, &leaf2_gate_lock },
-	{ 69, "rom_io", "vdifm_io", 0, SIRFSOC_CLKC_LEAF_CLK_EN2_SET, 3, &leaf2_gate_lock },
-	{ 70, "sdio23_io", "vdifm_io", 0, SIRFSOC_CLKC_LEAF_CLK_EN2_SET, 4, &leaf2_gate_lock },
-	{ 71, "sdio45_io", "vdifm_io", 0, SIRFSOC_CLKC_LEAF_CLK_EN2_SET, 5, &leaf2_gate_lock },
-	{ 72, "sdio67_io", "vdifm_io", 0, SIRFSOC_CLKC_LEAF_CLK_EN2_SET, 6, &leaf2_gate_lock },
-	{ 73, "vip1_io", "vdifm_io", 0, SIRFSOC_CLKC_LEAF_CLK_EN2_SET, 7, &leaf2_gate_lock },
-	{ 74, "vip1_vip", "vdifm_vip", 0, SIRFSOC_CLKC_LEAF_CLK_EN2_SET, 16, &leaf2_gate_lock },
-	{ 75, "sdio23_sdphy23", "vdifm_sdphy23", 0, SIRFSOC_CLKC_LEAF_CLK_EN2_SET, 8, &leaf2_gate_lock },
-	{ 76, "sdio45_sdphy45", "vdifm_sdphy45", 0, SIRFSOC_CLKC_LEAF_CLK_EN2_SET, 9, &leaf2_gate_lock },
-	{ 77, "sdio67_sdphy67", "vdifm_sdphy67", 0, SIRFSOC_CLKC_LEAF_CLK_EN2_SET, 10, &leaf2_gate_lock },
-	{ 78, "vpp0_disp0", "vdifm_disp0", 0, SIRFSOC_CLKC_LEAF_CLK_EN2_SET, 11, &leaf2_gate_lock },
-	{ 79, "lcd0_disp0", "vdifm_disp0", 0, SIRFSOC_CLKC_LEAF_CLK_EN2_SET, 12, &leaf2_gate_lock },
-	{ 80, "vpp1_disp1", "vdifm_disp1", 0, SIRFSOC_CLKC_LEAF_CLK_EN2_SET, 13, &leaf2_gate_lock },
-	{ 81, "lcd1_disp1", "vdifm_disp1", 0, SIRFSOC_CLKC_LEAF_CLK_EN2_SET, 14, &leaf2_gate_lock },
-	{ 82, "dcu_deint", "vdifm_deint", 0, SIRFSOC_CLKC_LEAF_CLK_EN2_SET, 15, &leaf2_gate_lock },
-	{ 83, "vdifm_dapa_r_nocr", "vdifm_nocr", 0, SIRFSOC_CLKC_LEAF_CLK_EN2_SET, 17, &leaf2_gate_lock },
-	{ 84, "gpio1_io", "vdifm_io", 0, SIRFSOC_CLKC_LEAF_CLK_EN2_SET, 18, &leaf2_gate_lock },
-	{ 85, "thvdifm_io", "vdifm_io", 0, SIRFSOC_CLKC_LEAF_CLK_EN2_SET, 19, &leaf2_gate_lock },
-	{ 86, "gmac_rgmii", "gnssm_rgmii", 0, SIRFSOC_CLKC_LEAF_CLK_EN3_SET, 0, &leaf3_gate_lock },
-	{ 87, "gmac_gmac", "gnssm_gmac", 0, SIRFSOC_CLKC_LEAF_CLK_EN3_SET, 1, &leaf3_gate_lock },
-	{ 88, "uart1_io", "gnssm_io", 0, SIRFSOC_CLKC_LEAF_CLK_EN3_SET, 2, &leaf3_gate_lock },
-	{ 89, "dmac0_io", "gnssm_io", 0, SIRFSOC_CLKC_LEAF_CLK_EN3_SET, 3, &leaf3_gate_lock },
-	{ 90, "uart0_io", "gnssm_io", 0, SIRFSOC_CLKC_LEAF_CLK_EN3_SET, 4, &leaf3_gate_lock },
-	{ 91, "uart2_io", "gnssm_io", 0, SIRFSOC_CLKC_LEAF_CLK_EN3_SET, 5, &leaf3_gate_lock },
-	{ 92, "uart3_io", "gnssm_io", 0, SIRFSOC_CLKC_LEAF_CLK_EN3_SET, 6, &leaf3_gate_lock },
-	{ 93, "uart4_io", "gnssm_io", 0, SIRFSOC_CLKC_LEAF_CLK_EN3_SET, 7, &leaf3_gate_lock },
-	{ 94, "uart5_io", "gnssm_io", 0, SIRFSOC_CLKC_LEAF_CLK_EN3_SET, 8, &leaf3_gate_lock },
-	{ 95, "spi1_io", "gnssm_io", 0, SIRFSOC_CLKC_LEAF_CLK_EN3_SET, 9, &leaf3_gate_lock },
-	{ 96, "gnss_gnss", "gnssm_gnss", 0, SIRFSOC_CLKC_LEAF_CLK_EN3_SET, 10, &leaf3_gate_lock },
-	{ 97, "canbus1_can", "gnssm_can", 0, SIRFSOC_CLKC_LEAF_CLK_EN3_SET, 12, &leaf3_gate_lock },
-	{ 98, "ccsec_sec", "gnssm_sec", 0, SIRFSOC_CLKC_LEAF_CLK_EN3_SET, 15, &leaf3_gate_lock },
-	{ 99,  "ccpub_sec", "gnssm_sec", 0, SIRFSOC_CLKC_LEAF_CLK_EN3_SET, 16, &leaf3_gate_lock },
-	{ 100, "gnssm_dapa_r_nocr", "gnssm_nocr", 0, SIRFSOC_CLKC_LEAF_CLK_EN3_SET, 13, &leaf3_gate_lock },
-	{ 101, "thgnssm_io", "gnssm_io", 0, SIRFSOC_CLKC_LEAF_CLK_EN3_SET, 14, &leaf3_gate_lock },
-	{ 102, "media_vdec", "mediam_vdec", 0, SIRFSOC_CLKC_LEAF_CLK_EN4_SET, 0, &leaf4_gate_lock },
-	{ 103, "media_jpenc", "mediam_jpenc", 0, SIRFSOC_CLKC_LEAF_CLK_EN4_SET, 1, &leaf4_gate_lock },
-	{ 104, "g2d_g2d", "mediam_g2d", 0, SIRFSOC_CLKC_LEAF_CLK_EN4_SET, 2, &leaf4_gate_lock },
-	{ 105, "i2c0_io", "mediam_io", 0, SIRFSOC_CLKC_LEAF_CLK_EN4_SET, 3, &leaf4_gate_lock },
-	{ 106, "i2c1_io", "mediam_io", 0, SIRFSOC_CLKC_LEAF_CLK_EN4_SET, 4, &leaf4_gate_lock },
-	{ 107, "gpio0_io", "mediam_io", 0, SIRFSOC_CLKC_LEAF_CLK_EN4_SET, 5, &leaf4_gate_lock },
-	{ 108, "nand_io", "mediam_io", 0, SIRFSOC_CLKC_LEAF_CLK_EN4_SET, 6, &leaf4_gate_lock },
-	{ 109, "sdio01_io", "mediam_io", 0, SIRFSOC_CLKC_LEAF_CLK_EN4_SET, 7, &leaf4_gate_lock },
-	{ 110, "sys2pci2_io", "mediam_io", 0, SIRFSOC_CLKC_LEAF_CLK_EN4_SET, 8, &leaf4_gate_lock },
-	{ 111, "sdio01_sdphy01", "mediam_sdphy01", 0, SIRFSOC_CLKC_LEAF_CLK_EN4_SET, 9, &leaf4_gate_lock },
-	{ 112, "nand_nand", "mediam_nand", 0, SIRFSOC_CLKC_LEAF_CLK_EN4_SET, 10, &leaf4_gate_lock },
-	{ 113, "usb0_usb", "mediam_usb", 0, SIRFSOC_CLKC_LEAF_CLK_EN4_SET, 11, &leaf4_gate_lock },
-	{ 114, "usb1_usb", "mediam_usb", 0, SIRFSOC_CLKC_LEAF_CLK_EN4_SET, 12, &leaf4_gate_lock },
-	{ 115, "usbphy0_usbphy", "mediam_usbphy", 0, SIRFSOC_CLKC_LEAF_CLK_EN4_SET, 13, &leaf4_gate_lock },
-	{ 116, "usbphy1_usbphy", "mediam_usbphy", 0, SIRFSOC_CLKC_LEAF_CLK_EN4_SET, 14, &leaf4_gate_lock },
-	{ 117, "thmediam_io", "mediam_io", 0, SIRFSOC_CLKC_LEAF_CLK_EN4_SET, 15, &leaf4_gate_lock },
-	{ 118, "memc_mem", "mempll_clk1", CLK_IGNORE_UNUSED, SIRFSOC_CLKC_LEAF_CLK_EN5_SET, 0, &leaf5_gate_lock },
-	{ 119, "dapa_mem", "mempll_clk1", 0, SIRFSOC_CLKC_LEAF_CLK_EN5_SET, 1, &leaf5_gate_lock },
-	{ 120, "nocddrm_nocr", "ddrm_nocr", 0, SIRFSOC_CLKC_LEAF_CLK_EN5_SET, 2, &leaf5_gate_lock },
-	{ 121, "thddrm_nocr", "ddrm_nocr", 0, SIRFSOC_CLKC_LEAF_CLK_EN5_SET, 3, &leaf5_gate_lock },
-	{ 122, "spram1_cpudiv2", "cpum_cpu", 0, SIRFSOC_CLKC_LEAF_CLK_EN6_SET, 0, &leaf6_gate_lock },
-	{ 123, "spram2_cpudiv2", "cpum_cpu", 0, SIRFSOC_CLKC_LEAF_CLK_EN6_SET, 1, &leaf6_gate_lock },
-	{ 124, "coresight_cpudiv2", "cpum_cpu", 0, SIRFSOC_CLKC_LEAF_CLK_EN6_SET, 2, &leaf6_gate_lock },
-	{ 125, "coresight_tpiu", "cpum_tpiu", 0, SIRFSOC_CLKC_LEAF_CLK_EN6_SET, 3, &leaf6_gate_lock },
-	{ 126, "graphic_gpu", "gpum_gpu", 0, SIRFSOC_CLKC_LEAF_CLK_EN7_SET, 0, &leaf7_gate_lock },
-	{ 127, "vss_sdr", "gpum_sdr", 0, SIRFSOC_CLKC_LEAF_CLK_EN7_SET, 1, &leaf7_gate_lock },
-	{ 128, "thgpum_nocr", "gpum_nocr", 0, SIRFSOC_CLKC_LEAF_CLK_EN7_SET, 2, &leaf7_gate_lock },
-	{ 129, "a7ca_btss", "btm_btss", 0, SIRFSOC_CLKC_LEAF_CLK_EN8_SET, 1, &leaf8_gate_lock },
-	{ 130, "dmac4_io", "btm_io", 0, SIRFSOC_CLKC_LEAF_CLK_EN8_SET, 2, &leaf8_gate_lock },
-	{ 131, "uart6_io", "btm_io", 0, SIRFSOC_CLKC_LEAF_CLK_EN8_SET, 3, &leaf8_gate_lock },
-	{ 132, "usp3_io", "btm_io", 0, SIRFSOC_CLKC_LEAF_CLK_EN8_SET, 4, &leaf8_gate_lock },
-	{ 133, "a7ca_io", "btm_io", 0, SIRFSOC_CLKC_LEAF_CLK_EN8_SET, 5, &leaf8_gate_lock },
-	{ 134, "noc_btm_io", "btm_io", 0, SIRFSOC_CLKC_LEAF_CLK_EN8_SET, 6, &leaf8_gate_lock },
-	{ 135, "thbtm_io", "btm_io", 0, SIRFSOC_CLKC_LEAF_CLK_EN8_SET, 7, &leaf8_gate_lock },
-	{ 136, "btslow", "xinw_fixdiv_btslow", 0, SIRFSOC_CLKC_ROOT_CLK_EN1_SET, 25, &root1_gate_lock },
-	{ 137, "a7ca_btslow", "btslow", 0, SIRFSOC_CLKC_LEAF_CLK_EN8_SET, 0, &leaf8_gate_lock },
-	{ 138, "pwm_io", "io_mux", 0, SIRFSOC_CLKC_LEAF_CLK_EN0_SET, 0, &leaf0_gate_lock },
-	{ 139, "pwm_xin", "xin", 0, SIRFSOC_CLKC_LEAF_CLK_EN0_SET, 1, &leaf0_gate_lock },
-	{ 140, "pwm_xinw", "xinw", 0, SIRFSOC_CLKC_LEAF_CLK_EN0_SET, 2, &leaf0_gate_lock },
-	{ 141, "thcgum_sys", "sys_mux", 0, SIRFSOC_CLKC_LEAF_CLK_EN0_SET, 3, &leaf0_gate_lock },
+	{ 0, "audmscm_kas", "kas_mux", 0, SIRFSOC_CLKC_ROOT_CLK_EN0_SET, 0, 0, 0, &root0_gate_lock },
+	{ 1, "gnssm_gnss", "gnss_mux", 0, SIRFSOC_CLKC_ROOT_CLK_EN0_SET, 1, 0, 0, &root0_gate_lock },
+	{ 2, "gpum_gpu", "gpu_mux", 0, SIRFSOC_CLKC_ROOT_CLK_EN0_SET, 2, 0, 0, &root0_gate_lock },
+	{ 3, "mediam_g2d", "g2d_mux", 0, SIRFSOC_CLKC_ROOT_CLK_EN0_SET, 3, 0, 0, &root0_gate_lock },
+	{ 4, "mediam_jpenc", "jpenc_mux", 0, SIRFSOC_CLKC_ROOT_CLK_EN0_SET, 4, 0, 0, &root0_gate_lock },
+	{ 5, "vdifm_disp0", "disp0_mux", 0, SIRFSOC_CLKC_ROOT_CLK_EN0_SET, 5, 0, 0, &root0_gate_lock },
+	{ 6, "vdifm_disp1", "disp1_mux", 0, SIRFSOC_CLKC_ROOT_CLK_EN0_SET, 6, 0, 0, &root0_gate_lock },
+	{ 7, "audmscm_i2s", "i2s_mux", 0, SIRFSOC_CLKC_ROOT_CLK_EN0_SET, 8, 0, 0, &root0_gate_lock },
+	{ 8, "audmscm_io", "io_mux", 0, SIRFSOC_CLKC_ROOT_CLK_EN0_SET, 11, 0, 0, &root0_gate_lock },
+	{ 9, "vdifm_io", "io_mux", 0, SIRFSOC_CLKC_ROOT_CLK_EN0_SET, 12, 0, 0, &root0_gate_lock },
+	{ 10, "gnssm_io", "io_mux", 0, SIRFSOC_CLKC_ROOT_CLK_EN0_SET, 13, 0, 0, &root0_gate_lock },
+	{ 11, "mediam_io", "io_mux", 0, SIRFSOC_CLKC_ROOT_CLK_EN0_SET, 14, 0, 0, &root0_gate_lock },
+	{ 12, "btm_io", "io_mux", 0, SIRFSOC_CLKC_ROOT_CLK_EN0_SET, 17, 0, 0, &root0_gate_lock },
+	{ 13, "mediam_sdphy01", "sdphy01_mux", 0, SIRFSOC_CLKC_ROOT_CLK_EN0_SET, 18, 0, 0, &root0_gate_lock },
+	{ 14, "vdifm_sdphy23", "sdphy23_mux", 0, SIRFSOC_CLKC_ROOT_CLK_EN0_SET, 19, 0, 0, &root0_gate_lock },
+	{ 15, "vdifm_sdphy45", "sdphy45_mux", 0, SIRFSOC_CLKC_ROOT_CLK_EN0_SET, 20, 0, 0, &root0_gate_lock },
+	{ 16, "vdifm_sdphy67", "sdphy67_mux", 0, SIRFSOC_CLKC_ROOT_CLK_EN0_SET, 21, 0, 0, &root0_gate_lock },
+	{ 17, "audmscm_xin", "xin", 0, SIRFSOC_CLKC_ROOT_CLK_EN0_SET, 22, 0, 0, &root0_gate_lock },
+	{ 18, "mediam_nand", "nand_mux", 0, SIRFSOC_CLKC_ROOT_CLK_EN0_SET, 27, 0, 0, &root0_gate_lock },
+	{ 19, "gnssm_sec", "sec_mux", 0, SIRFSOC_CLKC_ROOT_CLK_EN0_SET, 28, 0, 0, &root0_gate_lock },
+	{ 20, "cpum_cpu", "cpu_mux", 0, SIRFSOC_CLKC_ROOT_CLK_EN0_SET, 29, 0, 0, &root0_gate_lock },
+	{ 21, "gnssm_xin", "xin", 0, SIRFSOC_CLKC_ROOT_CLK_EN0_SET, 30, 0, 0, &root0_gate_lock },
+	{ 22, "vdifm_vip", "vip_mux", 0, SIRFSOC_CLKC_ROOT_CLK_EN0_SET, 31, 0, 0, &root0_gate_lock },
+	{ 23, "btm_btss", "btss_mux", 0, SIRFSOC_CLKC_ROOT_CLK_EN1_SET, 0, 0, 0, &root1_gate_lock },
+	{ 24, "mediam_usbphy", "usbphy_mux", 0, SIRFSOC_CLKC_ROOT_CLK_EN1_SET, 1, 0, 0, &root1_gate_lock },
+	{ 25, "rtcm_kas", "kas_mux", 0, SIRFSOC_CLKC_ROOT_CLK_EN1_SET, 2, 0, 0, &root1_gate_lock },
+	{ 26, "audmscm_nocd", "nocd_mux", 0, SIRFSOC_CLKC_ROOT_CLK_EN1_SET, 3, 0, 0, &root1_gate_lock },
+	{ 27, "vdifm_nocd", "nocd_mux", 0, SIRFSOC_CLKC_ROOT_CLK_EN1_SET, 4, 0, 0, &root1_gate_lock },
+	{ 28, "gnssm_nocd", "nocd_mux", 0, SIRFSOC_CLKC_ROOT_CLK_EN1_SET, 5, 0, 0, &root1_gate_lock },
+	{ 29, "mediam_nocd", "nocd_mux", 0, SIRFSOC_CLKC_ROOT_CLK_EN1_SET, 6, 0, 0, &root1_gate_lock },
+	{ 30, "cpum_nocd", "nocd_mux", 0, SIRFSOC_CLKC_ROOT_CLK_EN1_SET, 8, 0, 0, &root1_gate_lock },
+	{ 31, "gpum_nocd", "nocd_mux", 0, SIRFSOC_CLKC_ROOT_CLK_EN1_SET, 9, 0, 0, &root1_gate_lock },
+	{ 32, "audmscm_nocr", "nocr_mux", 0, SIRFSOC_CLKC_ROOT_CLK_EN1_SET, 11, 0, 0, &root1_gate_lock },
+	{ 33, "vdifm_nocr", "nocr_mux", 0, SIRFSOC_CLKC_ROOT_CLK_EN1_SET, 12, 0, 0, &root1_gate_lock },
+	{ 34, "gnssm_nocr", "nocr_mux", CLK_IGNORE_UNUSED, SIRFSOC_CLKC_ROOT_CLK_EN1_SET, 13, 0, 0, &root1_gate_lock },
+	{ 35, "mediam_nocr", "nocr_mux", CLK_IGNORE_UNUSED, SIRFSOC_CLKC_ROOT_CLK_EN1_SET, 14, 0, 0, &root1_gate_lock },
+	{ 36, "ddrm_nocr", "nocr_mux", CLK_IGNORE_UNUSED, SIRFSOC_CLKC_ROOT_CLK_EN1_SET, 15, 0, 0, &root1_gate_lock },
+	{ 37, "cpum_tpiu", "tpiu_mux", 0, SIRFSOC_CLKC_ROOT_CLK_EN1_SET, 16, 0, 0, &root1_gate_lock },
+	{ 38, "gpum_nocr", "nocr_mux", 0, SIRFSOC_CLKC_ROOT_CLK_EN1_SET, 17, 0, 0, &root1_gate_lock },
+	{ 39, "gnssm_rgmii", "rgmii_mux", 0, SIRFSOC_CLKC_ROOT_CLK_EN1_SET, 20, 0, 0, &root1_gate_lock },
+	{ 40, "mediam_vdec", "vdec_mux", 0, SIRFSOC_CLKC_ROOT_CLK_EN1_SET, 21, 0, 0, &root1_gate_lock },
+	{ 41, "gpum_sdr", "sdr_mux", 0, SIRFSOC_CLKC_ROOT_CLK_EN1_SET, 22, 0, 0, &root1_gate_lock },
+	{ 42, "vdifm_deint", "deint_mux", 0, SIRFSOC_CLKC_ROOT_CLK_EN1_SET, 23, 0, 0, &root1_gate_lock },
+	{ 43, "gnssm_can", "can_mux", 0, SIRFSOC_CLKC_ROOT_CLK_EN1_SET, 26, 0, 0, &root1_gate_lock },
+	{ 44, "mediam_usb", "usb_mux", 0, SIRFSOC_CLKC_ROOT_CLK_EN1_SET, 28, 0, 0, &root1_gate_lock },
+	{ 45, "gnssm_gmac", "gmac_mux", 0, SIRFSOC_CLKC_ROOT_CLK_EN1_SET, 29, 0, 0, &root1_gate_lock },
+	{ 46, "cvd_io", "audmscm_io", 0, SIRFSOC_CLKC_LEAF_CLK_EN1_SET, 0, CLK_UNIT_NOC_CLOCK, 4, &leaf1_gate_lock },
+	{ 47, "timer_io", "audmscm_io", 0, SIRFSOC_CLKC_LEAF_CLK_EN1_SET, 1, 0, 0, &leaf1_gate_lock },
+	{ 48, "pulse_io", "audmscm_io", 0, SIRFSOC_CLKC_LEAF_CLK_EN1_SET, 2, 0, 0, &leaf1_gate_lock },
+	{ 49, "tsc_io", "audmscm_io", 0, SIRFSOC_CLKC_LEAF_CLK_EN1_SET, 3, 0, 0, &leaf1_gate_lock },
+	{ 50, "tsc_xin", "audmscm_xin", 0, SIRFSOC_CLKC_LEAF_CLK_EN1_SET, 21, 0, 0, &leaf1_gate_lock },
+	{ 51, "ioctop_io", "audmscm_io", 0, SIRFSOC_CLKC_LEAF_CLK_EN1_SET, 4, 0, 0, &leaf1_gate_lock },
+	{ 52, "rsc_io", "audmscm_io", 0, SIRFSOC_CLKC_LEAF_CLK_EN1_SET, 5, 0, 0, &leaf1_gate_lock },
+	{ 53, "dvm_io", "audmscm_io", 0, SIRFSOC_CLKC_LEAF_CLK_EN1_SET, 6, CLK_UNIT_NOC_SOCKET, 7, &leaf1_gate_lock },
+	{ 54, "lvds_xin", "audmscm_xin", 0, SIRFSOC_CLKC_LEAF_CLK_EN1_SET, 7, CLK_UNIT_NOC_SOCKET, 8, &leaf1_gate_lock },
+	{ 55, "kas_kas", "audmscm_kas", 0, SIRFSOC_CLKC_LEAF_CLK_EN1_SET, 8, CLK_UNIT_NOC_CLOCK, 2, &leaf1_gate_lock },
+	{ 56, "ac97_kas", "audmscm_kas", 0, SIRFSOC_CLKC_LEAF_CLK_EN1_SET, 9, 0, 0, &leaf1_gate_lock },
+	{ 57, "usp0_kas", "audmscm_kas", 0, SIRFSOC_CLKC_LEAF_CLK_EN1_SET, 10, CLK_UNIT_NOC_SOCKET, 4, &leaf1_gate_lock },
+	{ 58, "usp1_kas", "audmscm_kas", 0, SIRFSOC_CLKC_LEAF_CLK_EN1_SET, 11, CLK_UNIT_NOC_SOCKET, 5, &leaf1_gate_lock },
+	{ 59, "usp2_kas", "audmscm_kas", 0, SIRFSOC_CLKC_LEAF_CLK_EN1_SET, 12, CLK_UNIT_NOC_SOCKET, 6, &leaf1_gate_lock },
+	{ 60, "dmac2_kas", "audmscm_kas", 0, SIRFSOC_CLKC_LEAF_CLK_EN1_SET, 13, CLK_UNIT_NOC_SOCKET, 1, &leaf1_gate_lock },
+	{ 61, "dmac3_kas", "audmscm_kas", 0, SIRFSOC_CLKC_LEAF_CLK_EN1_SET, 14, CLK_UNIT_NOC_SOCKET, 2, &leaf1_gate_lock },
+	{ 62, "audioif_kas", "audmscm_kas", 0, SIRFSOC_CLKC_LEAF_CLK_EN1_SET, 15, CLK_UNIT_NOC_SOCKET, 0, &leaf1_gate_lock },
+	{ 63, "i2s1_kas", "audmscm_kas", 0, SIRFSOC_CLKC_LEAF_CLK_EN1_SET, 17, CLK_UNIT_NOC_CLOCK, 2, &leaf1_gate_lock },
+	{ 64, "thaudmscm_io", "audmscm_io", 0, SIRFSOC_CLKC_LEAF_CLK_EN1_SET, 22, 0, 0, &leaf1_gate_lock },
+	{ 65, "analogtest_xin", "audmscm_xin", 0, SIRFSOC_CLKC_LEAF_CLK_EN1_SET, 23, 0, 0, &leaf1_gate_lock },
+	{ 66, "sys2pci_io", "vdifm_io", 0, SIRFSOC_CLKC_LEAF_CLK_EN2_SET, 0, CLK_UNIT_NOC_CLOCK, 20, &leaf2_gate_lock },
+	{ 67, "pciarb_io", "vdifm_io", 0, SIRFSOC_CLKC_LEAF_CLK_EN2_SET, 1, 0, 0, &leaf2_gate_lock },
+	{ 68, "pcicopy_io", "vdifm_io", 0, SIRFSOC_CLKC_LEAF_CLK_EN2_SET, 2, 0, 0, &leaf2_gate_lock },
+	{ 69, "rom_io", "vdifm_io", 0, SIRFSOC_CLKC_LEAF_CLK_EN2_SET, 3, 0, 0, &leaf2_gate_lock },
+	{ 70, "sdio23_io", "vdifm_io", 0, SIRFSOC_CLKC_LEAF_CLK_EN2_SET, 4, 0, 0, &leaf2_gate_lock },
+	{ 71, "sdio45_io", "vdifm_io", 0, SIRFSOC_CLKC_LEAF_CLK_EN2_SET, 5, 0, 0, &leaf2_gate_lock },
+	{ 72, "sdio67_io", "vdifm_io", 0, SIRFSOC_CLKC_LEAF_CLK_EN2_SET, 6, 0, 0, &leaf2_gate_lock },
+	{ 73, "vip1_io", "vdifm_io", 0, SIRFSOC_CLKC_LEAF_CLK_EN2_SET, 7, 0, 0, &leaf2_gate_lock },
+	{ 74, "vip1_vip", "vdifm_vip", 0, SIRFSOC_CLKC_LEAF_CLK_EN2_SET, 16, CLK_UNIT_NOC_CLOCK, 21, &leaf2_gate_lock },
+	{ 75, "sdio23_sdphy23", "vdifm_sdphy23", 0, SIRFSOC_CLKC_LEAF_CLK_EN2_SET, 8, 0, 0, &leaf2_gate_lock },
+	{ 76, "sdio45_sdphy45", "vdifm_sdphy45", 0, SIRFSOC_CLKC_LEAF_CLK_EN2_SET, 9, 0, 0, &leaf2_gate_lock },
+	{ 77, "sdio67_sdphy67", "vdifm_sdphy67", 0, SIRFSOC_CLKC_LEAF_CLK_EN2_SET, 10, 0, 0, &leaf2_gate_lock },
+	{ 78, "vpp0_disp0", "vdifm_disp0", 0, SIRFSOC_CLKC_LEAF_CLK_EN2_SET, 11, CLK_UNIT_NOC_CLOCK, 22, &leaf2_gate_lock },
+	{ 79, "lcd0_disp0", "vdifm_disp0", 0, SIRFSOC_CLKC_LEAF_CLK_EN2_SET, 12, CLK_UNIT_NOC_CLOCK, 18, &leaf2_gate_lock },
+	{ 80, "vpp1_disp1", "vdifm_disp1", 0, SIRFSOC_CLKC_LEAF_CLK_EN2_SET, 13, CLK_UNIT_NOC_CLOCK, 23, &leaf2_gate_lock },
+	{ 81, "lcd1_disp1", "vdifm_disp1", 0, SIRFSOC_CLKC_LEAF_CLK_EN2_SET, 14, CLK_UNIT_NOC_CLOCK, 19, &leaf2_gate_lock },
+	{ 82, "dcu_deint", "vdifm_deint", 0, SIRFSOC_CLKC_LEAF_CLK_EN2_SET, 15,  CLK_UNIT_NOC_CLOCK, 17, &leaf2_gate_lock },
+	{ 83, "vdifm_dapa_r_nocr", "vdifm_nocr", 0, SIRFSOC_CLKC_LEAF_CLK_EN2_SET, 17, 0, 0, &leaf2_gate_lock },
+	{ 84, "gpio1_io", "vdifm_io", 0, SIRFSOC_CLKC_LEAF_CLK_EN2_SET, 18, 0, 0, &leaf2_gate_lock },
+	{ 85, "thvdifm_io", "vdifm_io", 0, SIRFSOC_CLKC_LEAF_CLK_EN2_SET, 19, 0, 0, &leaf2_gate_lock },
+	{ 86, "gmac_rgmii", "gnssm_rgmii", 0, SIRFSOC_CLKC_LEAF_CLK_EN3_SET, 0, 0, 0, &leaf3_gate_lock },
+	{ 87, "gmac_gmac", "gnssm_gmac", 0, SIRFSOC_CLKC_LEAF_CLK_EN3_SET, 1, CLK_UNIT_NOC_CLOCK, 10, &leaf3_gate_lock },
+	{ 88, "uart1_io", "gnssm_io", 0, SIRFSOC_CLKC_LEAF_CLK_EN3_SET, 2, CLK_UNIT_NOC_SOCKET, 14, &leaf3_gate_lock },
+	{ 89, "dmac0_io", "gnssm_io", 0, SIRFSOC_CLKC_LEAF_CLK_EN3_SET, 3, CLK_UNIT_NOC_SOCKET, 11, &leaf3_gate_lock },
+	{ 90, "uart0_io", "gnssm_io", 0, SIRFSOC_CLKC_LEAF_CLK_EN3_SET, 4, CLK_UNIT_NOC_SOCKET, 13, &leaf3_gate_lock },
+	{ 91, "uart2_io", "gnssm_io", 0, SIRFSOC_CLKC_LEAF_CLK_EN3_SET, 5, CLK_UNIT_NOC_SOCKET, 15, &leaf3_gate_lock },
+	{ 92, "uart3_io", "gnssm_io", 0, SIRFSOC_CLKC_LEAF_CLK_EN3_SET, 6, CLK_UNIT_NOC_SOCKET, 16, &leaf3_gate_lock },
+	{ 93, "uart4_io", "gnssm_io", 0, SIRFSOC_CLKC_LEAF_CLK_EN3_SET, 7, CLK_UNIT_NOC_SOCKET, 17, &leaf3_gate_lock },
+	{ 94, "uart5_io", "gnssm_io", 0, SIRFSOC_CLKC_LEAF_CLK_EN3_SET, 8, CLK_UNIT_NOC_SOCKET, 18, &leaf3_gate_lock },
+	{ 95, "spi1_io", "gnssm_io", 0, SIRFSOC_CLKC_LEAF_CLK_EN3_SET, 9, CLK_UNIT_NOC_SOCKET, 12, &leaf3_gate_lock },
+	{ 96, "gnss_gnss", "gnssm_gnss", 0, SIRFSOC_CLKC_LEAF_CLK_EN3_SET, 10, 0, 0, &leaf3_gate_lock },
+	{ 97, "canbus1_can", "gnssm_can", 0, SIRFSOC_CLKC_LEAF_CLK_EN3_SET, 12, CLK_UNIT_NOC_CLOCK, 7, &leaf3_gate_lock },
+	{ 98, "ccsec_sec", "gnssm_sec", 0, SIRFSOC_CLKC_LEAF_CLK_EN3_SET, 15, CLK_UNIT_NOC_CLOCK, 9, &leaf3_gate_lock },
+	{ 99,  "ccpub_sec", "gnssm_sec", 0, SIRFSOC_CLKC_LEAF_CLK_EN3_SET, 16, CLK_UNIT_NOC_CLOCK, 8, &leaf3_gate_lock },
+	{ 100, "gnssm_dapa_r_nocr", "gnssm_nocr", 0, SIRFSOC_CLKC_LEAF_CLK_EN3_SET, 13, 0, 0, &leaf3_gate_lock },
+	{ 101, "thgnssm_io", "gnssm_io", 0, SIRFSOC_CLKC_LEAF_CLK_EN3_SET, 14, 0, 0, &leaf3_gate_lock },
+	{ 102, "media_vdec", "mediam_vdec", 0, SIRFSOC_CLKC_LEAF_CLK_EN4_SET, 0, CLK_UNIT_NOC_CLOCK, 3, &leaf4_gate_lock },
+	{ 103, "media_jpenc", "mediam_jpenc", 0, SIRFSOC_CLKC_LEAF_CLK_EN4_SET, 1, CLK_UNIT_NOC_CLOCK, 1, &leaf4_gate_lock },
+	{ 104, "g2d_g2d", "mediam_g2d", 0, SIRFSOC_CLKC_LEAF_CLK_EN4_SET, 2, CLK_UNIT_NOC_CLOCK, 12, &leaf4_gate_lock },
+	{ 105, "i2c0_io", "mediam_io", 0, SIRFSOC_CLKC_LEAF_CLK_EN4_SET, 3, CLK_UNIT_NOC_SOCKET, 21, &leaf4_gate_lock },
+	{ 106, "i2c1_io", "mediam_io", 0, SIRFSOC_CLKC_LEAF_CLK_EN4_SET, 4, CLK_UNIT_NOC_SOCKET, 20, &leaf4_gate_lock },
+	{ 107, "gpio0_io", "mediam_io", 0, SIRFSOC_CLKC_LEAF_CLK_EN4_SET, 5, CLK_UNIT_NOC_SOCKET, 19,  &leaf4_gate_lock },
+	{ 108, "nand_io", "mediam_io", 0, SIRFSOC_CLKC_LEAF_CLK_EN4_SET, 6, 0, 0, &leaf4_gate_lock },
+	{ 109, "sdio01_io", "mediam_io", 0, SIRFSOC_CLKC_LEAF_CLK_EN4_SET, 7, 0, 0, &leaf4_gate_lock },
+	{ 110, "sys2pci2_io", "mediam_io", 0, SIRFSOC_CLKC_LEAF_CLK_EN4_SET, 8, CLK_UNIT_NOC_CLOCK, 13, &leaf4_gate_lock },
+	{ 111, "sdio01_sdphy01", "mediam_sdphy01", 0, SIRFSOC_CLKC_LEAF_CLK_EN4_SET, 9, 0, 0, &leaf4_gate_lock },
+	{ 112, "nand_nand", "mediam_nand", 0, SIRFSOC_CLKC_LEAF_CLK_EN4_SET, 10, CLK_UNIT_NOC_CLOCK, 14, &leaf4_gate_lock },
+	{ 113, "usb0_usb", "mediam_usb", 0, SIRFSOC_CLKC_LEAF_CLK_EN4_SET, 11, CLK_UNIT_NOC_CLOCK, 15, &leaf4_gate_lock },
+	{ 114, "usb1_usb", "mediam_usb", 0, SIRFSOC_CLKC_LEAF_CLK_EN4_SET, 12,  CLK_UNIT_NOC_CLOCK, 16, &leaf4_gate_lock },
+	{ 115, "usbphy0_usbphy", "mediam_usbphy", 0, SIRFSOC_CLKC_LEAF_CLK_EN4_SET, 13, 0, 0, &leaf4_gate_lock },
+	{ 116, "usbphy1_usbphy", "mediam_usbphy", 0, SIRFSOC_CLKC_LEAF_CLK_EN4_SET, 14, 0, 0, &leaf4_gate_lock },
+	{ 117, "thmediam_io", "mediam_io", 0, SIRFSOC_CLKC_LEAF_CLK_EN4_SET, 15, 0, 0, &leaf4_gate_lock },
+	{ 118, "memc_mem", "mempll_clk1", CLK_IGNORE_UNUSED, SIRFSOC_CLKC_LEAF_CLK_EN5_SET, 0, 0, 0, &leaf5_gate_lock },
+	{ 119, "dapa_mem", "mempll_clk1", 0, SIRFSOC_CLKC_LEAF_CLK_EN5_SET, 1, 0, 0, &leaf5_gate_lock },
+	{ 120, "nocddrm_nocr", "ddrm_nocr", 0, SIRFSOC_CLKC_LEAF_CLK_EN5_SET, 2, 0, 0, &leaf5_gate_lock },
+	{ 121, "thddrm_nocr", "ddrm_nocr", 0, SIRFSOC_CLKC_LEAF_CLK_EN5_SET, 3, 0, 0, &leaf5_gate_lock },
+	{ 122, "spram1_cpudiv2", "cpum_cpu", 0, SIRFSOC_CLKC_LEAF_CLK_EN6_SET, 0, CLK_UNIT_NOC_SOCKET, 9, &leaf6_gate_lock },
+	{ 123, "spram2_cpudiv2", "cpum_cpu", 0, SIRFSOC_CLKC_LEAF_CLK_EN6_SET, 1, CLK_UNIT_NOC_SOCKET, 10, &leaf6_gate_lock },
+	{ 124, "coresight_cpudiv2", "cpum_cpu", 0, SIRFSOC_CLKC_LEAF_CLK_EN6_SET, 2, 0, 0, &leaf6_gate_lock },
+	{ 125, "coresight_tpiu", "cpum_tpiu", 0, SIRFSOC_CLKC_LEAF_CLK_EN6_SET, 3, 0, 0, &leaf6_gate_lock },
+	{ 126, "graphic_gpu", "gpum_gpu", 0, SIRFSOC_CLKC_LEAF_CLK_EN7_SET, 0, CLK_UNIT_NOC_CLOCK, 0, &leaf7_gate_lock },
+	{ 127, "vss_sdr", "gpum_sdr", 0, SIRFSOC_CLKC_LEAF_CLK_EN7_SET, 1, CLK_UNIT_NOC_CLOCK, 11, &leaf7_gate_lock },
+	{ 128, "thgpum_nocr", "gpum_nocr", 0, SIRFSOC_CLKC_LEAF_CLK_EN7_SET, 2, 0, 0, &leaf7_gate_lock },
+	{ 129, "a7ca_btss", "btm_btss", 0, SIRFSOC_CLKC_LEAF_CLK_EN8_SET, 1, 0, 0, &leaf8_gate_lock },
+	{ 130, "dmac4_io", "a7ca_io", 0, SIRFSOC_CLKC_LEAF_CLK_EN8_SET, 2, 0, 0, &leaf8_gate_lock },
+	{ 131, "uart6_io", "dmac4_io", 0, SIRFSOC_CLKC_LEAF_CLK_EN8_SET, 3, 0, 0, &leaf8_gate_lock },
+	{ 132, "usp3_io", "dmac4_io", 0, SIRFSOC_CLKC_LEAF_CLK_EN8_SET, 4, 0, 0, &leaf8_gate_lock },
+	{ 133, "a7ca_io", "noc_btm_io", 0, SIRFSOC_CLKC_LEAF_CLK_EN8_SET, 5, 0, 0, &leaf8_gate_lock },
+	{ 134, "noc_btm_io", "btm_io", 0, SIRFSOC_CLKC_LEAF_CLK_EN8_SET, 6, 0, 0, &leaf8_gate_lock },
+	{ 135, "thbtm_io", "btm_io", 0, SIRFSOC_CLKC_LEAF_CLK_EN8_SET, 7, 0, 0, &leaf8_gate_lock },
+	{ 136, "btslow", "xinw_fixdiv_btslow", 0, SIRFSOC_CLKC_ROOT_CLK_EN1_SET, 25, 0, 0, &root1_gate_lock },
+	{ 137, "a7ca_btslow", "btslow", 0, SIRFSOC_CLKC_LEAF_CLK_EN8_SET, 0, 0, 0, &leaf8_gate_lock },
+	{ 138, "pwm_io", "io_mux", 0, SIRFSOC_CLKC_LEAF_CLK_EN0_SET, 0, 0, 0, &leaf0_gate_lock },
+	{ 139, "pwm_xin", "xin", 0, SIRFSOC_CLKC_LEAF_CLK_EN0_SET, 1, 0, 0, &leaf0_gate_lock },
+	{ 140, "pwm_xinw", "xinw", 0, SIRFSOC_CLKC_LEAF_CLK_EN0_SET, 2, 0, 0, &leaf0_gate_lock },
+	{ 141, "thcgum_sys", "sys_mux", 0, SIRFSOC_CLKC_LEAF_CLK_EN0_SET, 3, 0, 0, &leaf0_gate_lock },
 };
 
 static struct clk *atlas7_clks[ARRAY_SIZE(unit_list) + ARRAY_SIZE(mux_list)];
@@ -1206,20 +1221,44 @@ static int unit_clk_enable(struct clk_hw *hw)
 
 	spin_lock_irqsave(clk->lock, flags);
 	clkc_writel(BIT(clk->bit), reg);
+	if (clk->type == CLK_UNIT_NOC_CLOCK)
+		clkc_writel(BIT(clk->idle_bit), SIRFSOC_NOC_CLK_IDLEREQ_CLR);
+	else if (clk->type == CLK_UNIT_NOC_SOCKET)
+		clkc_writel(BIT(clk->idle_bit), SIRFSOC_NOC_CLK_SLVRDY_SET);
+
 	spin_unlock_irqrestore(clk->lock, flags);
 	return 0;
 }
 
 static void unit_clk_disable(struct clk_hw *hw)
 {
-	u32  reg;
+	u32 reg;
+	u32 i = 0;
 	struct clk_unit *clk = to_unitclk(hw);
 	unsigned long flags;
 
 	reg = clk->regofs + SIRFSOC_CLKC_ROOT_CLK_EN0_CLR - SIRFSOC_CLKC_ROOT_CLK_EN0_SET;
-
 	spin_lock_irqsave(clk->lock, flags);
+	if (clk->type == CLK_UNIT_NOC_CLOCK) {
+		clkc_writel(BIT(clk->idle_bit), SIRFSOC_NOC_CLK_IDLEREQ_SET);
+		while (!(clkc_readl(SIRFSOC_NOC_CLK_IDLE_STATUS) &
+				BIT(clk->idle_bit)) && (i++ < 100)) {
+			cpu_relax();
+			udelay(10);
+		}
+
+		if (i == 100) {
+			pr_err("unit NoC Clock disconnect Error:timeout\n");
+			/*once timeout, undo idlereq by CLR*/
+			clkc_writel(BIT(clk->idle_bit), SIRFSOC_NOC_CLK_IDLEREQ_CLR);
+			goto err;
+		}
+
+	} else if (clk->type == CLK_UNIT_NOC_SOCKET)
+		clkc_writel(BIT(clk->idle_bit), SIRFSOC_NOC_CLK_SLVRDY_CLR);
+
 	clkc_writel(BIT(clk->bit), reg);
+err:
 	spin_unlock_irqrestore(clk->lock, flags);
 }
 
@@ -1232,7 +1271,7 @@ static const struct clk_ops unit_clk_ops = {
 static struct clk * __init
 atlas7_unit_clk_register(struct device *dev, const char *name,
 		 const char * const parent_name, unsigned long flags,
-		 u32 regofs, u8 bit, spinlock_t *lock)
+		 u32 regofs, u8 bit, u32 type, u8 idle_bit, spinlock_t *lock)
 {
 	struct clk *clk;
 	struct clk_unit *unit;
@@ -1251,6 +1290,9 @@ atlas7_unit_clk_register(struct device *dev, const char *name,
 	unit->hw.init = &init;
 	unit->regofs = regofs;
 	unit->bit = bit;
+
+	unit->type = type;
+	unit->idle_bit = idle_bit;
 	unit->lock = lock;
 
 	clk = clk_register(dev, &unit->hw);
@@ -1624,7 +1666,7 @@ static void __init atlas7_clk_init(struct device_node *np)
 	for (i = 0; i < ARRAY_SIZE(unit_list); i++) {
 		unit = &unit_list[i];
 		atlas7_clks[i] = atlas7_unit_clk_register(NULL, unit->unit_name, unit->parent_name,
-				unit->flags, unit->regofs, unit->bit, unit->lock);
+				unit->flags, unit->regofs, unit->bit, unit->type, unit->idle_bit, unit->lock);
 		BUG_ON(!atlas7_clks[i]);
 	}
 
-- 
1.9.1



From sboyd at codeaurora.org  Thu Aug 13 18:44:47 2015
From: sboyd at codeaurora.org (Stephen Boyd)
Date: Thu, 13 Aug 2015 18:44:47 -0700
Subject: [PATCH v8 10/13] arm: dts: qcom: Add #power-domain-cells property
In-Reply-To: <55CC1BF7.1040406@codeaurora.org>
References: <1438857474-20262-1-git-send-email-rnayak@codeaurora.org>
 <1438857474-20262-11-git-send-email-rnayak@codeaurora.org>
 <20150811065335.GB2839@codeaurora.org> <55CC1BF7.1040406@codeaurora.org>
Message-ID: <55CD480F.8060502@codeaurora.org>

On 08/12/2015 09:24 PM, Rajendra Nayak wrote:
> On 08/11/2015 12:23 PM, Stephen Boyd wrote:
>> On 08/06, Rajendra Nayak wrote:
>>> msm8974 has gcc and mmcc nodes, and apq8084 has a gcc node which
>>> implement gdsc powerdomains. Add the #power-domain-cells property
>>> to them.
>>>
>>> Signed-off-by: Rajendra Nayak <rnayak at codeaurora.org>
>>> ---
>>
>> This needs to go through  Andy's tree and arm-soc. Also, I don't
>> see an update for the binding anywhere. Please update the binding
>> too.
>
> Will do, I hope you mean update the bindings in qcom,mmcc.txt and
> qcom,gcc.txt?

Yes.

-- 
Qualcomm Innovation Center, Inc. is a member of Code Aurora Forum,
a Linux Foundation Collaborative Project



From Suravee.Suthikulpanit at amd.com  Thu Aug 13 18:45:22 2015
From: Suravee.Suthikulpanit at amd.com (Suravee Suthikulpanit)
Date: Fri, 14 Aug 2015 08:45:22 +0700
Subject: [PATCH 1/3] Honor ACPI _CCA attribute setting
In-Reply-To: <1439416290-21228-2-git-send-email-jeremy.linton@arm.com>
References: <1439416290-21228-1-git-send-email-jeremy.linton@arm.com>
 <1439416290-21228-2-git-send-email-jeremy.linton@arm.com>
Message-ID: <55CD4832.7070301@amd.com>

Hi Jeremy,

On 8/13/15 04:51, Jeremy Linton wrote:
> ACPI configurations can now mark devices as noncoherent,
> support that choice.
>
> Signed-off-by: Jeremy Linton <jeremy.linton at arm.com>
> ---
>   include/acpi/acpi_bus.h | 5 +++--
>   1 file changed, 3 insertions(+), 2 deletions(-)
>
> diff --git a/include/acpi/acpi_bus.h b/include/acpi/acpi_bus.h
> index 83061ca..7ecb8e4 100644
> --- a/include/acpi/acpi_bus.h
> +++ b/include/acpi/acpi_bus.h
> @@ -399,7 +399,7 @@ static inline bool acpi_check_dma(struct acpi_device *adev, bool *coherent)
>   	 * case 1. Do not support and disable DMA.
>   	 * case 2. Support but rely on arch-specific cache maintenance for
>   	 *         non-coherence DMA operations.
> -	 * Currently, we implement case 1 above.
> +	 * Currently, we implement case 2 above.
>   	 *
>   	 * For the case when _CCA is missing (i.e. cca_seen=0) and
>   	 * platform specifies ACPI_CCA_REQUIRED, we do not support DMA,
> @@ -407,7 +407,8 @@ static inline bool acpi_check_dma(struct acpi_device *adev, bool *coherent)
>   	 *
>   	 * See acpi_init_coherency() for more info.
>   	 */
> -	if (adev->flags.coherent_dma) {
> +	if (adev->flags.coherent_dma ||
> +	    (adev->flags.cca_seen && IS_ENABLED(CONFIG_ARM64))) {
>   		ret = true;
>   		if (coherent)
>   			*coherent = adev->flags.coherent_dma;
>

This change was in my earlier revisions for the original patch series to 
add ACPI CCA support. At the time, this was pushed back since we were 
not sure whether this would be a useful case, and whether such hardware 
exists.

Would it be useful to document somewhere (may be in the GIT commit 
message) about which hardware might need this?

Arnd/Catalin, any feedback on this?

Thanks,

Suravee


From bhelgaas at google.com  Thu Aug 13 18:50:04 2015
From: bhelgaas at google.com (Bjorn Helgaas)
Date: Thu, 13 Aug 2015 20:50:04 -0500
Subject: [PATCH] pci: acpi: Generic function for setting up PCI device
 DMA coherency
In-Reply-To: <1439459925-2361-1-git-send-email-Suravee.Suthikulpanit@amd.com>
References: <1439459925-2361-1-git-send-email-Suravee.Suthikulpanit@amd.com>
Message-ID: <20150814015004.GA26431@google.com>

Hi Suravee,

On Thu, Aug 13, 2015 at 04:58:45PM +0700, Suravee Suthikulpanit wrote:
> This patch refactors of_pci_dma_configure() into a more generic
> pci_dma_configure(), which can be reused by non-OF code.
> Then, it adds support for setting up PCI device DMA coherency from
> ACPI _CCA object that should normally be specified in the DSDT node
> of its PCI host bridge..

Since this does two things:
  1) Rename of_pci_dma_configure() and move it to PCI
  2) Add _CCA support,
maybe it should be split into two patches?

There are a couple more comments below.

While looking at this, I thought some of the existing code could be
made simpler and easier to follow.  I appended a couple possible patches;
you can incorporate them or ignore them, whatever seems best to you.

Bjorn

> Signed-off-by: Suravee Suthikulpanit <Suravee.Suthikulpanit at amd.com>
> CC: Bjorn Helgaas <bhelgaas at google.com>
> CC: Catalin Marinas <catalin.marinas at arm.com>
> CC: Will Deacon <will.deacon at arm.com>
> CC: Rafael J. Wysocki <rjw at rjwysocki.net>
> CC: Rob Herring <robh+dt at kernel.org>
> CC: Murali Karicheri <m-karicheri2 at ti.com>
> ---
> Note: According to the ACPI spec, the _CCA attribute is required
>       for ARM64. Therefore, this patch is a pre-req for ACPI PCI
>       support for ARM64 which is currently in development.
> 
>       Also, this should not affect other architectures since
>       if CCA is not required, the default value is coherent.
>       Please see include/acpi/acpi_bus.h: acpi_check_dma() and
>       drivers/acpi/scan.c: acpi_init_coherency() for more information
> 
>  drivers/of/of_pci.c    | 20 --------------------
>  drivers/pci/probe.c    | 35 +++++++++++++++++++++++++++++++++--
>  include/linux/of_pci.h |  3 ---
>  3 files changed, 33 insertions(+), 25 deletions(-)
> 
> diff --git a/drivers/of/of_pci.c b/drivers/of/of_pci.c
> index 5751dc5..b66ee4e 100644
> --- a/drivers/of/of_pci.c
> +++ b/drivers/of/of_pci.c
> @@ -117,26 +117,6 @@ int of_get_pci_domain_nr(struct device_node *node)
>  }
>  EXPORT_SYMBOL_GPL(of_get_pci_domain_nr);
>  
> -/**
> - * of_pci_dma_configure - Setup DMA configuration
> - * @dev: ptr to pci_dev struct of the PCI device
> - *
> - * Function to update PCI devices's DMA configuration using the same
> - * info from the OF node of host bridge's parent (if any).
> - */
> -void of_pci_dma_configure(struct pci_dev *pci_dev)
> -{
> -	struct device *dev = &pci_dev->dev;
> -	struct device *bridge = pci_get_host_bridge_device(pci_dev);
> -
> -	if (!bridge->parent)
> -		return;
> -
> -	of_dma_configure(dev, bridge->parent->of_node);
> -	pci_put_host_bridge_device(bridge);
> -}
> -EXPORT_SYMBOL_GPL(of_pci_dma_configure);
> -
>  #if defined(CONFIG_OF_ADDRESS)
>  /**
>   * of_pci_get_host_bridge_resources - Parse PCI host bridge resources from DT
> diff --git a/drivers/pci/probe.c b/drivers/pci/probe.c
> index cefd636..e2fcd3b 100644
> --- a/drivers/pci/probe.c
> +++ b/drivers/pci/probe.c
> @@ -6,12 +6,14 @@
>  #include <linux/delay.h>
>  #include <linux/init.h>
>  #include <linux/pci.h>
> -#include <linux/of_pci.h>
> +#include <linux/of_device.h>
>  #include <linux/pci_hotplug.h>
>  #include <linux/slab.h>
>  #include <linux/module.h>
>  #include <linux/cpumask.h>
>  #include <linux/pci-aspm.h>
> +#include <linux/acpi.h>
> +#include <linux/property.h>
>  #include <asm-generic/pci-bridge.h>
>  #include "pci.h"
>  
> @@ -1544,6 +1546,35 @@ static void pci_init_capabilities(struct pci_dev *dev)
>  	pci_enable_acs(dev);
>  }
>  
> +/**
> + * pci_dma_configure - Setup DMA configuration
> + * @pci_dev: ptr to pci_dev struct of the PCI device
> + *
> + * Function to update PCI devices's DMA configuration using the same
> + * info from the OF node or ACPI node of host bridge's parent (if any).
> + */
> +static void pci_dma_configure(struct pci_dev *pci_dev)

Almost all pci_dev pointers in probe.c are named "dev", so I would use
that for this one, too.  I probably would just drop the "struct device
*dev" below and use "&dev->dev" the two places you need it.  That's a
common idiom in PCI.

> +{
> +	struct device *dev = &pci_dev->dev;
> +	struct device *bridge = pci_get_host_bridge_device(pci_dev);
> +	struct acpi_device *adev;
> +	bool coherent;
> +
> +	if (has_acpi_companion(bridge)) {
> +		adev = to_acpi_node(bridge->fwnode);
> +		if (acpi_check_dma(adev, &coherent))
> +			arch_setup_dma_ops(dev, 0, 0, NULL, coherent);
> +	} else {
> +		struct device *host = bridge->parent;
> +		if (!host)
> +			return;
> +
> +		of_dma_configure(dev, host->of_node);
> +	}

Why is this check reversed with respect to device_dma_is_coherent()?
In device_dma_is_coherent(), we first look for an OF property, then look
for ACPI _CCA.  But here we check for _CCA, then for OF.

> +
> +	pci_put_host_bridge_device(bridge);
> +}
> +
>  void pci_device_add(struct pci_dev *dev, struct pci_bus *bus)
>  {
>  	int ret;
> @@ -1557,7 +1588,7 @@ void pci_device_add(struct pci_dev *dev, struct pci_bus *bus)
>  	dev->dev.dma_mask = &dev->dma_mask;
>  	dev->dev.dma_parms = &dev->dma_parms;
>  	dev->dev.coherent_dma_mask = 0xffffffffull;
> -	of_pci_dma_configure(dev);
> +	pci_dma_configure(dev);
>  
>  	pci_set_dma_max_seg_size(dev, 65536);
>  	pci_set_dma_seg_boundary(dev, 0xffffffff);
> diff --git a/include/linux/of_pci.h b/include/linux/of_pci.h
> index 29fd3fe..ce0e5ab 100644
> --- a/include/linux/of_pci.h
> +++ b/include/linux/of_pci.h
> @@ -16,7 +16,6 @@ int of_pci_get_devfn(struct device_node *np);
>  int of_irq_parse_and_map_pci(const struct pci_dev *dev, u8 slot, u8 pin);
>  int of_pci_parse_bus_range(struct device_node *node, struct resource *res);
>  int of_get_pci_domain_nr(struct device_node *node);
> -void of_pci_dma_configure(struct pci_dev *pci_dev);
>  #else
>  static inline int of_irq_parse_pci(const struct pci_dev *pdev, struct of_phandle_args *out_irq)
>  {
> @@ -51,8 +50,6 @@ of_get_pci_domain_nr(struct device_node *node)
>  {
>  	return -1;
>  }
> -
> -static inline void of_pci_dma_configure(struct pci_dev *pci_dev) { }
>  #endif
>  
>  #if defined(CONFIG_OF_ADDRESS)
> -- 
> 2.1.0
> 
commit 18183957888f601807ca0e166516ae60f682eb62
Author: Bjorn Helgaas <bhelgaas at google.com>
Date:   Thu Aug 13 20:01:21 2015 -0500

    ACPI / scan: Move _CCA comments to acpi_init_coherency()
    
    Move the comments about how we handle _CCA to the code that looks at _CCA,
    and fix a couple typos.
    
    No functional change.
    
    Signed-off-by: Bjorn Helgaas <bhelgaas at google.com>

diff --git a/drivers/acpi/scan.c b/drivers/acpi/scan.c
index ec25635..a12e522 100644
--- a/drivers/acpi/scan.c
+++ b/drivers/acpi/scan.c
@@ -2188,6 +2188,22 @@ static void acpi_init_coherency(struct acpi_device *adev)
 	acpi_status status;
 	struct acpi_device *parent = adev->parent;
 
+	/**
+	 * Currently, we only support _CCA=1 (i.e. coherent_dma=1)
+	 * This should be equivalent to specifying dma-coherent for
+	 * a device in OF.
+	 *
+	 * For the case when _CCA=0 (i.e. coherent_dma=0 && cca_seen=1),
+	 * we have two choices:
+	 * case 1. Do not support and disable DMA.
+	 * case 2. Support but rely on arch-specific cache maintenance for
+	 *         non-coherent DMA operations.
+	 * Currently, we implement case 1 above.
+	 *
+	 * For the case when _CCA is missing (i.e. cca_seen=0) and
+	 * platform specifies ACPI_CCA_REQUIRED, we do not support DMA,
+	 * and fallback to arch-specific default handling.
+	 */
 	if (parent && parent->flags.cca_seen) {
 		/*
 		 * From ACPI spec, OSPM will ignore _CCA if an ancestor
diff --git a/include/acpi/acpi_bus.h b/include/acpi/acpi_bus.h
index 83061ca..718942b 100644
--- a/include/acpi/acpi_bus.h
+++ b/include/acpi/acpi_bus.h
@@ -389,24 +389,6 @@ static inline bool acpi_check_dma(struct acpi_device *adev, bool *coherent)
 	if (!adev)
 		return ret;
 
-	/**
-	 * Currently, we only support _CCA=1 (i.e. coherent_dma=1)
-	 * This should be equivalent to specifyig dma-coherent for
-	 * a device in OF.
-	 *
-	 * For the case when _CCA=0 (i.e. coherent_dma=0 && cca_seen=1),
-	 * There are two cases:
-	 * case 1. Do not support and disable DMA.
-	 * case 2. Support but rely on arch-specific cache maintenance for
-	 *         non-coherence DMA operations.
-	 * Currently, we implement case 1 above.
-	 *
-	 * For the case when _CCA is missing (i.e. cca_seen=0) and
-	 * platform specifies ACPI_CCA_REQUIRED, we do not support DMA,
-	 * and fallback to arch-specific default handling.
-	 *
-	 * See acpi_init_coherency() for more info.
-	 */
 	if (adev->flags.coherent_dma) {
 		ret = true;
 		if (coherent)

commit 84cfb2213cd400fef227ec0d7829ec4e12895da9
Author: Bjorn Helgaas <bhelgaas at google.com>
Date:   Thu Aug 13 19:49:52 2015 -0500

    ACPI / scan: Rename acpi_check_dma() to acpi_dma_is_coherent()
    
    The name "acpi_check_dma()" doesn't give any much indication about what
    exactly it checks.  The function also returns information both as a normal
    return value and as the "bool *coherent" return parameter.  But "*coherent"
    doesn't actually give any extra information: it is unchanged when returning
    false and set to true when returning true.
    
    Rename acpi_check_dma() to acpi_dma_is_coherent() so the callers read more
    naturally.  Drop the return parameter and just use the function return
    value.
    
    Signed-off-by: Bjorn Helgaas <bhelgaas at google.com>

diff --git a/drivers/acpi/acpi_platform.c b/drivers/acpi/acpi_platform.c
index 06a67d5..fc6138d 100644
--- a/drivers/acpi/acpi_platform.c
+++ b/drivers/acpi/acpi_platform.c
@@ -103,7 +103,7 @@ struct platform_device *acpi_create_platform_device(struct acpi_device *adev)
 	pdevinfo.res = resources;
 	pdevinfo.num_res = count;
 	pdevinfo.fwnode = acpi_fwnode_handle(adev);
-	pdevinfo.dma_mask = acpi_check_dma(adev, NULL) ? DMA_BIT_MASK(32) : 0;
+	pdevinfo.dma_mask = acpi_dma_is_coherent(adev) ? DMA_BIT_MASK(32) : 0;
 	pdev = platform_device_register_full(&pdevinfo);
 	if (IS_ERR(pdev))
 		dev_err(&adev->dev, "platform device creation failed: %ld\n",
diff --git a/drivers/acpi/glue.c b/drivers/acpi/glue.c
index b9657af..89b1cf8 100644
--- a/drivers/acpi/glue.c
+++ b/drivers/acpi/glue.c
@@ -168,7 +168,6 @@ int acpi_bind_one(struct device *dev, struct acpi_device *acpi_dev)
 	struct list_head *physnode_list;
 	unsigned int node_id;
 	int retval = -EINVAL;
-	bool coherent;
 
 	if (has_acpi_companion(dev)) {
 		if (acpi_dev) {
@@ -225,8 +224,8 @@ int acpi_bind_one(struct device *dev, struct acpi_device *acpi_dev)
 	if (!has_acpi_companion(dev))
 		ACPI_COMPANION_SET(dev, acpi_dev);
 
-	if (acpi_check_dma(acpi_dev, &coherent))
-		arch_setup_dma_ops(dev, 0, 0, NULL, coherent);
+	if (acpi_dma_is_coherent(acpi_dev))
+		arch_setup_dma_ops(dev, 0, 0, NULL, true);
 
 	acpi_physnode_link_name(physical_node_name, node_id);
 	retval = sysfs_create_link(&acpi_dev->dev.kobj, &dev->kobj,
diff --git a/drivers/base/property.c b/drivers/base/property.c
index f3f6d16..1124130 100644
--- a/drivers/base/property.c
+++ b/drivers/base/property.c
@@ -523,13 +523,9 @@ EXPORT_SYMBOL_GPL(device_get_child_node_count);
 
 bool device_dma_is_coherent(struct device *dev)
 {
-	bool coherent = false;
-
 	if (IS_ENABLED(CONFIG_OF) && dev->of_node)
-		coherent = of_dma_is_coherent(dev->of_node);
-	else
-		acpi_check_dma(ACPI_COMPANION(dev), &coherent);
+		return of_dma_is_coherent(dev->of_node);
 
-	return coherent;
+	return acpi_dma_is_coherent(ACPI_COMPANION(dev));
 }
 EXPORT_SYMBOL_GPL(device_dma_is_coherent);
diff --git a/include/acpi/acpi_bus.h b/include/acpi/acpi_bus.h
index 718942b..39f1be6 100644
--- a/include/acpi/acpi_bus.h
+++ b/include/acpi/acpi_bus.h
@@ -382,19 +382,12 @@ struct acpi_device {
 	void (*remove)(struct acpi_device *);
 };
 
-static inline bool acpi_check_dma(struct acpi_device *adev, bool *coherent)
+static inline bool acpi_dma_is_coherent(struct acpi_device *adev)
 {
-	bool ret = false;
+	if (adev && adev->flags.coherent_dma)
+		return true;
 
-	if (!adev)
-		return ret;
-
-	if (adev->flags.coherent_dma) {
-		ret = true;
-		if (coherent)
-			*coherent = adev->flags.coherent_dma;
-	}
-	return ret;
+	return false;
 }
 
 static inline bool is_acpi_node(struct fwnode_handle *fwnode)
diff --git a/include/linux/acpi.h b/include/linux/acpi.h
index d2445fa..f29b8b5 100644
--- a/include/linux/acpi.h
+++ b/include/linux/acpi.h
@@ -562,7 +562,7 @@ static inline int acpi_device_modalias(struct device *dev,
 	return -ENODEV;
 }
 
-static inline bool acpi_check_dma(struct acpi_device *adev, bool *coherent)
+static inline bool acpi_dma_is_coherent(struct acpi_device *adev)
 {
 	return false;
 }


From festevam at gmail.com  Thu Aug 13 19:43:19 2015
From: festevam at gmail.com (Fabio Estevam)
Date: Thu, 13 Aug 2015 23:43:19 -0300
Subject: [PATCH] ARM: rockchip: pm: Fix PTR_ERR() argument
Message-ID: <1439520199-16076-1-git-send-email-festevam@gmail.com>

From: Fabio Estevam <fabio.estevam at freescale.com>

PTR_ERR should access the value just tested by IS_ERR.

The semantic patch that makes this change is available
in scripts/coccinelle/tests/odd_ptr_err.cocci.

Signed-off-by: Fabio Estevam <fabio.estevam at freescale.com>
---
 arch/arm/mach-rockchip/pm.c | 4 ++--
 1 file changed, 2 insertions(+), 2 deletions(-)

diff --git a/arch/arm/mach-rockchip/pm.c b/arch/arm/mach-rockchip/pm.c
index 892bace..01123dd 100644
--- a/arch/arm/mach-rockchip/pm.c
+++ b/arch/arm/mach-rockchip/pm.c
@@ -224,14 +224,14 @@ static int rk3288_suspend_init(struct device_node *np)
 				"rockchip,rk3288-sgrf");
 	if (IS_ERR(sgrf_regmap)) {
 		pr_err("%s: could not find sgrf regmap\n", __func__);
-		return PTR_ERR(pmu_regmap);
+		return PTR_ERR(sgrf_regmap);
 	}
 
 	grf_regmap = syscon_regmap_lookup_by_compatible(
 				"rockchip,rk3288-grf");
 	if (IS_ERR(grf_regmap)) {
 		pr_err("%s: could not find grf regmap\n", __func__);
-		return PTR_ERR(pmu_regmap);
+		return PTR_ERR(grf_regmap);
 	}
 
 	sram_np = of_find_compatible_node(NULL, NULL,
-- 
1.9.1



From rnayak at codeaurora.org  Thu Aug 13 20:09:06 2015
From: rnayak at codeaurora.org (Rajendra Nayak)
Date: Fri, 14 Aug 2015 08:39:06 +0530
Subject: [PATCH 5/9] clk: qcom: gcc-msm8960: add child devices support.
In-Reply-To: <20150814004206.GU26614@codeaurora.org>
References: <1436348838-22671-1-git-send-email-rnayak@codeaurora.org>
 <1436348838-22671-6-git-send-email-rnayak@codeaurora.org>
 <20150811224902.GO2839@codeaurora.org> <55CB0B26.2020105@linaro.org>
 <55CC1CFE.7000005@codeaurora.org> <20150814004206.GU26614@codeaurora.org>
Message-ID: <55CD5BD2.3070907@codeaurora.org>

[]..
>>>> Also, I don't like having a subnode in DT. Why can't we use the
>>>> same node as the GCC node and create a virtual child device here
>>>> for tsens? We can assign the same of_node that this platform
>>>> device has so that DT keeps working correctly.
>>
>> So the current driver looks up data based on compatible strings.
>
> The tsens device is always the same piece of hardware. The only

Well, not always. The one in 8960 does need additional initializations,
requires you to save/restore context as it can be powered off
not being in an always powered on domain etc.

> thing that's changing is the qfprom data and the number of
> sensors. So we should be looking at the qfprom compatible string

How? Tsens uses nvmem framework apis to read the qfprom atleast
in this series.

> to figure out how to interpret the qfprom data which would
> include the number of sensors and how the data is encoded.
>
>> So you suggesting to create a virtual child device for gcc and
>> associate the gcc DT node to it? (And have the tsens compatible
>> mentioned as part of the gcc DT node?)
>
> No. The driver should work just fine without having to
> interrogate the device's compatible string. If we still need the
> compatible check for some reason, then we can always match based
> on qcom,gcc-msm8960, qcom,gcc-apq8064, etc. But I don't see why

Thats not quite possible I guess. 2 drivers (gcc and tsens) matching
the same compatibles? Will it not just depend on which ends up being
the first match?

> we need to do that when we should be looking at what type of
> qfprom is connected so we can correctly parse the data.


From Dongsheng.Wang at freescale.com  Thu Aug 13 20:12:13 2015
From: Dongsheng.Wang at freescale.com (Wang Dongsheng)
Date: Fri, 14 Aug 2015 03:12:13 +0000
Subject: [PATCH 2/2] soc/fsl: add ftm alarm driver for ls1021a platform
In-Reply-To: <CACRpkdbninKuGzhEc5mN+85j-=w_wYQgra-Ark_Du6gWKN2=tg@mail.gmail.com>
References: <1439358807-9024-1-git-send-email-dongsheng.wang@freescale.com>
 <1439358807-9024-2-git-send-email-dongsheng.wang@freescale.com>
 <CACRpkdbninKuGzhEc5mN+85j-=w_wYQgra-Ark_Du6gWKN2=tg@mail.gmail.com>
Message-ID: <SN1PR0301MB161682A7FC5200580BED09119D7C0@SN1PR0301MB1616.namprd03.prod.outlook.com>



> -----Original Message-----
> From: Linus Walleij [mailto:linus.walleij at linaro.org]
> Sent: Thursday, August 13, 2015 9:54 PM
> To: Wang Dongsheng-B40534; John Stultz; Alessandro Zummo; Alexandre Belloni
> Cc: Shawn Guo; Nair, Sandeep; Hans de Goede; Wang Huan-B18965; linux-arm-
> kernel at lists.infradead.org; linux-kernel at vger.kernel.org; rtc-
> linux at googlegroups.com
> Subject: Re: [PATCH 2/2] soc/fsl: add ftm alarm driver for ls1021a platform
> 
> On Wed, Aug 12, 2015 at 7:53 AM, Dongsheng Wang
> <dongsheng.wang at freescale.com> wrote:
> 
> > From: Wang Dongsheng <dongsheng.wang at freescale.com>
> >
> > Only Ftm0 can be used when system going to deep sleep. So this driver
> > to support ftm0 as a wakeup source.
> >
> > Signed-off-by: Wang Dongsheng <dongsheng.wang at freescale.com>
> > ---
> > *V2*
> > Change Copyright 2014 to 2015.
> (...)
> > +config FTM_ALARM
> > +       bool "FTM alarm driver"
> > +       depends on SOC_LS1021A
> > +       default n
> > +       help
> > +         Say y here to enable FTM alarm support.  The FTM alarm provides
> > +         alarm functions for wakeup system from deep sleep.  There is only
> > +         one FTM can be used in ALARM(FTM 0).
> (...)
> > +static u32 time_to_cycle(unsigned long time)
> > +static u32 cycle_to_time(u32 cycle)
> > +static int ftm_set_alarm(u64 cycle)
> > +static irqreturn_t ftm_alarm_interrupt(int irq, void *dev_id)
> > +static ssize_t ftm_alarm_show(struct device *dev,
> > +                             struct device_attribute *attr,
> > +                             char *buf)
> > +static ssize_t ftm_alarm_store(struct device *dev,
> > +                              struct device_attribute *attr,
> > +                              const char *buf, size_t count)
> (...)
> > +static struct device_attribute ftm_alarm_attributes = __ATTR(ftm_alarm, 0644,
> > +                       ftm_alarm_show, ftm_alarm_store);
> 
> If you're gonna invent ABIs, document then in Documentation/ABI/testing/*.
> 
> But I don't get it. Why is this driver not in drivers/rtc?
> 
> It does a subset of what an RTC does. The ioctl()'s of an RTC
> can do what you want to do. And much much more.
> 
> If it can't do all an RTC can do, surely the RTC subsystem
> can be augmented to host it anyway. It's way to close to
> an RTC to have it's own random sysfs driver like this.
> 
> Unless I'm totally off, rewrite this to an RTC driver and post
> it to the RTC maintainers.
> 

FlexTimer is not a RTC device and not have any rtc deivce function. They belong to
different devices, why we need to register this to RTC framework? I am confused about this.

Now in freescale layerscape platform this driver is only for FlexTimer0, and not
fit for each flextimer. Because only FlexTimer0 still turn-on when system in the Deep Sleep.

If the "alarm" make you feel confused or mislead you think this is a RTC devices. I think
I need to change the "alarm" to "timer".

Regards,
-Dongsheng

From Peter.Chen at freescale.com  Thu Aug 13 20:13:26 2015
From: Peter.Chen at freescale.com (Peter Chen)
Date: Fri, 14 Aug 2015 03:13:26 +0000
Subject: [PATCH v3 00/10] USB: chipidea misc patches
In-Reply-To: <1438931747-25209-1-git-send-email-peter.chen@freescale.com>
References: <1438931747-25209-1-git-send-email-peter.chen@freescale.com>
Message-ID: <BN3PR0301MB0849D5DDFF2A5EBAE79CF673817C0@BN3PR0301MB0849.namprd03.prod.outlook.com>


 
> 
> In this series, I add several new interfaces for chipidea driver, they are mainly
> for system configuration adjustment. The USB performance may be improved
> with these configuration changing, but each vendor driver owner needs to
> consult with your IC owner which configuration parameters are suitable for
> your system before changing it, and only change it if necessary.
> 
> The other changes are for imx, it shows how imx uses these interfaces.
> Shawn, the patch [5/10] and [9/10] are dts changes, help to review it please.
> 

Shawn, there are no comments for week, I will queue chipidea changes for
v4.3-rc1, would you help to queue dts changes (5/10 and 9/10), thanks.

Peter

> Changes for v3:
> - Improve the binding doc according to Rob's comment [Patch 4/10, 8/10]
> 
> Changes for v2:
> - Use the bit fields which are not used. [Patch 2/10, 6/10, 10/10]
> - According to Greg and Sascha comments, format patch 2/10's
>   commit log.
> - using non-burst instead of unburst for patch 7/10
> 
> Peter Chen (10):
>   usb: chipidea: udc: zero-length packet is only needed for TX
>   usb: chipidea: define stream mode disable for both roles
>   usb: chipidea: imx: add stream mode enable for device mode at
>     imx6sl/imx6sx
>   Doc: usb: ci-hdrc-usb2: add ahb-burst-config for binding doc
>   ARM: imx6: set ahb-burst-config as 0 for USB
>   usb: chipidea: add ahb burst configuration interface
>   usb: chipidea: usbmisc_imx: add non-burst setting for imx6
>   Doc: usb: ci-hdrc-usb2: add tx(rx)-burst-config-dword for binding doc
>   ARM: imx6: change default burst size for USB
>   usb: chipidea: add tx/rx burst size configuration interface
> 
>  .../devicetree/bindings/usb/ci-hdrc-usb2.txt       | 17 ++++++
>  arch/arm/boot/dts/imx6qdl.dtsi                     | 12 +++++
>  arch/arm/boot/dts/imx6sl.dtsi                      |  9 ++++
>  arch/arm/boot/dts/imx6sx.dtsi                      |  9 ++++
>  drivers/usb/chipidea/bits.h                        |  7 +++
>  drivers/usb/chipidea/ci.h                          |  1 +
>  drivers/usb/chipidea/ci_hdrc_imx.c                 | 16 +++---
>  drivers/usb/chipidea/core.c                        | 62 +++++++++++++++++++++-
>  drivers/usb/chipidea/udc.c                         |  2 +-
>  drivers/usb/chipidea/usbmisc_imx.c                 | 12 ++++-
>  include/linux/usb/chipidea.h                       | 11 +++-
>  11 files changed, 147 insertions(+), 11 deletions(-)
> 
> --
> 1.9.1


From Dongsheng.Wang at freescale.com  Thu Aug 13 20:24:35 2015
From: Dongsheng.Wang at freescale.com (Wang Dongsheng)
Date: Fri, 14 Aug 2015 03:24:35 +0000
Subject: [PATCH v3 1/2] Documentation: DT: FTM: add FTM0 be used as alarm
 timer
In-Reply-To: <CALRxmdDGgYh+_cOPB43gyuZwu_zo+wE0qHh8nWJTjiQN__hZ3w@mail.gmail.com>
References: <1439352061-14656-1-git-send-email-dongsheng.wang@freescale.com>
 <CALRxmdDGgYh+_cOPB43gyuZwu_zo+wE0qHh8nWJTjiQN__hZ3w@mail.gmail.com>
Message-ID: <SN1PR0301MB16165DCFD09CEB424A91F79F9D7C0@SN1PR0301MB1616.namprd03.prod.outlook.com>

Thank Yoder,

Fix them in next version.

Regards,
-Dongsheng

> -----Original Message-----
> From: Stuart Yoder [mailto:b08248 at gmail.com]
> Sent: Friday, August 14, 2015 12:23 AM
> To: Wang Dongsheng-B40534
> Cc: shawn.guo at linaro.org; devicetree at vger.kernel.org; linux-
> kernel at vger.kernel.org; linux-arm-kernel at lists.infradead.org; Wang Huan-B18965
> Subject: Re: [PATCH v3 1/2] Documentation: DT: FTM: add FTM0 be used as alarm
> timer
> 
> On Tue, Aug 11, 2015 at 11:01 PM, Dongsheng Wang
> <dongsheng.wang at freescale.com> wrote:
> > From: Wang Dongsheng <dongsheng.wang at freescale.com>
> >
> > In freescale layerscape platform there is only FTM0 can be used as
> > alarm timer to wake up system. So add FTM0 description for devicetree
> > document.
> 
> Suggestion:
> 
> In the Freescale Layerscape platform a flextimer module can be used
> as an alarm timer to wake up the system.  Define a binding for this
> alarm.
> 
> > Signed-off-by: Wang Dongsheng <dongsheng.wang at freescale.com>
> > ---
> > V3:
> > Include this patch in V3.
> >
> > diff --git a/Documentation/devicetree/bindings/timer/fsl,ftm-timer.txt
> b/Documentation/devicetree/bindings/timer/fsl,ftm-timer.txt
> > index aa8c402..380a0b3d 100644
> > --- a/Documentation/devicetree/bindings/timer/fsl,ftm-timer.txt
> > +++ b/Documentation/devicetree/bindings/timer/fsl,ftm-timer.txt
> > @@ -1,5 +1,7 @@
> >  Freescale FlexTimer Module (FTM) Timer
> >
> > +* Default FTM Timer
> > +
> >  Required properties:
> >
> >  - compatible : should be "fsl,ftm-timer"
> > @@ -29,3 +31,26 @@ ftm: ftm at 400b8000 {
> >                 <&clks VF610_CLK_FTM3_EXT_FIX_EN>;
> >         big-endian;
> >  };
> > +
> > +* FTM Alarm Timer
> > +  The default FTM device contains eight FlexTimer modules. FlexTimer1 is in
> > +  on-domain(power is not switched off in deep sleep mode). Other seven
> FlexTimer
> > +  modules(flextimer2/3/4/5/6/7/8) are in off-domain (power is switched off in
> > +  deep sleep mode).
> 
> Suggestion:
> 
>   This binding describes a Flextimer (FTM) instance that can be used as an alarm
>   to wake up a system in deep sleep.  The flextimer module with alarm
>   support is in a power domain that remains awake when the SoC is in
>   deep sleep mode.
> 
> (don't use flextimer1 in the binding...for all you know in the next SoC it
> will be flextimer7 that has this capability)
> 
> > +Required properties:
> > +
> > +- compatible : should be "fsl,ftm-alarm".
> > +- reg : should contain base address and length of FTM timer 0 register.
> 
>   "should contain the address and size of the FTM alarm module registers"
> 
> (don't use the number 0)
> 
> > +- interrupts : Should contain FTM 0 interrupt.
> 
>    "describes the FTM alarm interrupt"
> 
> > +- big-endian: One boolean property, the big endian mode will be in use if it
> is
> > +  present, or the little endian mode will be in use for all the device
> registers.
> > +
> > +Example:
> > +ftm0: ftm0 at 29d0000 {
> > +       compatible = "fsl,ftm-alarm";
> > +       reg = <0x0 0x29d0000 0x0 0x10000>;
> > +       interrupts = <GIC_SPI 118 IRQ_TYPE_LEVEL_HIGH>;
> > +       big-endian;
> > +       status = "disabled";
> > +};
> 
> Drop the number 0 from the names in your example.
> 
> Thanks,
> Stuart

From khilman at kernel.org  Thu Aug 13 20:40:42 2015
From: khilman at kernel.org (Kevin Hilman)
Date: Thu, 13 Aug 2015 20:40:42 -0700
Subject: [PATCH 2/9] PM / Domains: Remove dev->driver check for runtime PM
In-Reply-To: <CAMuHMdVeffa-jgXuSjDQBKTrhgW-d87OKzs1iXX+4y-9U_AJbg@mail.gmail.com>
 (Geert Uytterhoeven's message of "Thu, 13 Aug 2015 10:57:38 +0200")
References: <1438731339-58317-1-git-send-email-lina.iyer@linaro.org>
 <1438731339-58317-3-git-send-email-lina.iyer@linaro.org>
 <7hfv3onv5c.fsf@deeprootsystems.com>
 <CAMuHMdVeffa-jgXuSjDQBKTrhgW-d87OKzs1iXX+4y-9U_AJbg@mail.gmail.com>
Message-ID: <7hwpwylepx.fsf@deeprootsystems.com>

Geert Uytterhoeven <geert at linux-m68k.org> writes:

> Hi Kevin,
>
> On Wed, Aug 12, 2015 at 9:50 PM, Kevin Hilman <khilman at kernel.org> wrote:
>> Lina Iyer <lina.iyer at linaro.org> writes:
>>
>>> Remove check for driver of a device, for runtime PM. Device may be
>>> suspended without an explicit driver. This check seems to be vestigial
>>> and incorrect in the current context.
>>
>> This one should probably have been RFC.
>>
>> For a little more context here, this was uncovered when experimenting
>> with using runtime PM for CPU devices which don't have a dev->driver.
>>
>> This check might have made sense before PM domains, but with PM domains,
>> it's entirely possible to have a simple device without a driver and the
>> PM domain handles all the necesary PM, so I think this check
>> could/should be removed.
>>
>> Thoughts?
>
> Simple devices without a driver aren't handled automatically.
> At minimum, the driver should call pm_runtime_enable(), cfr.
> drivers/bus/simple-pm-bus.c.

That's correct, and in the proof-of-concept stuff I hacked up and in
Lina's series, the CPU "devices" do indeed to this.  Without that, they
wouldn't end up ever taking this codepath through genpd's
runtime_suspend and power_off hooks.

Also, I'm not sure if your comment was meant to be an objection to the
patch?  or if you're OK with it.

Thanks for the feedback,

Kevin


From khilman at kernel.org  Thu Aug 13 20:51:15 2015
From: khilman at kernel.org (Kevin Hilman)
Date: Thu, 13 Aug 2015 20:51:15 -0700
Subject: [PATCH 5/9] ARM: common: Introduce PM domains for CPUs/clusters
In-Reply-To: <20150813155245.GD13833@red-moon> (Lorenzo Pieralisi's message of
 "Thu, 13 Aug 2015 16:52:45 +0100")
References: <1438731339-58317-1-git-send-email-lina.iyer@linaro.org>
 <1438731339-58317-6-git-send-email-lina.iyer@linaro.org>
 <CAL_JsqK67=DTtjZwwnonObLDjLbahkREfm0RvyXVV95bhR-d4Q@mail.gmail.com>
 <20150813150154.GB13356@red-moon> <20150813154503.GO52339@linaro.org>
 <20150813155245.GD13833@red-moon>
Message-ID: <7hegj6le8c.fsf@deeprootsystems.com>

Lorenzo Pieralisi <lorenzo.pieralisi at arm.com> writes:

> On Thu, Aug 13, 2015 at 04:45:03PM +0100, Lina Iyer wrote:
>> On Thu, Aug 13 2015 at 09:01 -0600, Lorenzo Pieralisi wrote:
>> >On Thu, Aug 06, 2015 at 04:14:51AM +0100, Rob Herring wrote:
>> >> On Tue, Aug 4, 2015 at 6:35 PM, Lina Iyer <lina.iyer at linaro.org> wrote:
>> >> > Define and add Generic PM domains (genpd) for ARM CPU clusters. Many new
>> >> > SoCs group CPUs as clusters. Clusters share common resources like GIC,
>> >> > power rail, caches, VFP, Coresight etc. When all CPUs in the cluster are
>> >> > idle, these shared resources may also be put in their idle state.
>> >> >
>> >> > The idle time between the last CPU entering idle and a CPU resuming
>> >> > execution is an opportunity for these shared resources to be powered
>> >> > down. Generic PM domain provides a framework for defining such power
>> >> > domains and attach devices to the domain. When the devices in the domain
>> >> > are idle at runtime, the domain would also be suspended and resumed
>> >> > before the first of the devices resume execution.
>> >> >
>> >> > We define a generic PM domain for each cluster and attach CPU devices in
>> >> > the cluster to that PM domain. The DT definitions for the SoC describe
>> >> > this relationship. Genpd callbacks for power_on and power_off can then
>> >> > be used to power up/down the shared resources for the domain.
>> >>
>> >> [...]
>> >>
>> >> > +ARM CPU Power domains
>> >> > +
>> >> > +The device tree allows describing of CPU power domains in a SoC. In ARM SoC,
>> >> > +CPUs may be grouped as clusters. A cluster may have CPUs, GIC, Coresight,
>> >> > +caches, VFP and power controller and other peripheral hardware. Generally,
>> >> > +when the CPUs in the cluster are idle/suspended, the shared resources may also
>> >> > +be suspended and resumed before any of the CPUs resume execution.
>> >> > +
>> >> > +CPUs are the defined as the PM domain consumers and there is a PM domain
>> >> > +provider for the CPUs. Bindings for generic PM domains (genpd) is described in
>> >> > +[1].
>> >> > +
>> >> > +The ARM CPU PM domain follows the same binding convention as any generic PM
>> >> > +domain. Additional binding properties are -
>> >> > +
>> >> > +- compatible:
>> >> > +       Usage: required
>> >> > +       Value type: <string>
>> >> > +       Definition: Must also have
>> >> > +                       "arm,pd"
>> >> > +               inorder to initialize the genpd provider as ARM CPU PM domain.
>> >>
>> >> A compatible string should represent a particular h/w block. If it is
>> >> generic, it should represent some sort of standard programming
>> >> interface (e.g, AHCI, EHCI, etc.). This doesn't seem to be either and
>> >> is rather just a mapping of what "driver" you want to use.
>> >>
>> >> I would expect that identifying a cpu's or cluster's power domain
>> >> would be done by a phandle between the cpu/cluster node and power
>> >> domain node. But I've not really looked at the power domain bindings
>> >> so who knows.
>> >
>> >I would expect the same, meaning that a cpu node, like any other device
>> >node would have a phandle pointing at the respective HW power domain.
>> >
>> CPUs have phandles to their domains. That is how the relationship
>> between the domain provider (power-controller) and the consumer (CPU) is
>> established.
>> 
>> >I do not really understand why we want a "generic" CPU power domain, what
>> >purpose does it serve ? Creating a collection of cpu devices that we
>> >can call "cluster" ?
>> >
>> Nope, not for calling a cluster, a cluster :)
>> 
>> This compatible is used to define a generic behavior of the CPU domain
>> controller (in addition to the platform specific behavior of the domain
>> power controller). The kernel activities for such power controller are
>> generally the same which otherwise would be repeated across platforms.
>
> What activities ? CPU PM notifiers ?

For today, yes.

However, you can think of CPU PM notifiers as the equivalent of runtime
PM hooks.  They're called when the "devices" are about to be powered off
(runtime suspended) or powered on (runtime resumed.)

However the CPU PM framework and notifiers are rather dumb compared to
runtime PM.  For example, runtime PM gives you usecounting, autosuspend,
control from userspace, statistics, etc. etc.  Also, IMO, CPU PM will 
not scale well for multiple clusters.

What if instead, we used runtime PM for the things that the CPU PM
notifiers manager (GIC, VFP, Coresight, etc.), and those drivers used
runtime PM callbacks to replace their CPU PM notifiers?  We'd then be in
a beautiful land where CPU "devices" (and the other connected logic) can
be modeled as devices using runtime PM just like every other device in
the system.

Then take it up a level... what if we then could use genpd to model the
"cluster", made of of the CPUs and "connected" devices (GIC, VFP, etc.)
but also modeled the shared L2$ as a device which was using runtime PM.

Now we're in a place where we can use all the benefits of runtime PM,
plus the governor features of genpd to start doing a real, multi-CPU,
multi-cluster CPUidle that's flexible enough to model the various
dependencies in an SoC independent way, but generic enough to be able to
use common governors for last-man standing, cache flushing, etc. etc.

Kevin


From djkurtz at chromium.org  Thu Aug 13 21:01:06 2015
From: djkurtz at chromium.org (Daniel Kurtz)
Date: Fri, 14 Aug 2015 12:01:06 +0800
Subject: [PATCH v7 0/9] Fixes and new clocks support for Mediatek MT8173
In-Reply-To: <CAGS+omCya_0djzoVGhJchmaTtzo2z+JdnJHDjLipNMsZKV=MLQ@mail.gmail.com>
References: <1439200228-318-1-git-send-email-jamesjj.liao@mediatek.com>
 <CAGS+omCya_0djzoVGhJchmaTtzo2z+JdnJHDjLipNMsZKV=MLQ@mail.gmail.com>
Message-ID: <CAGS+omAj=BZXYXChJwC2Heq+2KVEV2EoRrhiQhtXZRHGaZ9tEw@mail.gmail.com>

On Tue, Aug 11, 2015 at 12:43 PM, Daniel Kurtz <djkurtz at chromium.org> wrote:
> Hi James,
>
> On Mon, Aug 10, 2015 at 5:50 PM, James Liao <jamesjj.liao at mediatek.com> wrote:
>> This patchset is based on 4.2-rc2 and [1], and contains minor fixes and
>> subsystem clocks support for Mediatek MT8173.
>>
>> The previous reviews can be found in [2].
>>
>> changes since v6:
>> - Use DUMMY_RATE (0) instead of typical rate for clocks that we don't care
>>   and not controlled in CCF.
>
> For the whole series:
> Reviewed-by: Daniel Kurtz <djkurtz at chromium.org>

Hi Sascha,

Are you happy with these patches now?

Thanks,
-Dan


From lina.iyer at linaro.org  Thu Aug 13 21:02:05 2015
From: lina.iyer at linaro.org (Lina Iyer)
Date: Thu, 13 Aug 2015 22:02:05 -0600
Subject: [PATCH 5/9] ARM: common: Introduce PM domains for CPUs/clusters
In-Reply-To: <7hegj6le8c.fsf@deeprootsystems.com>
References: <1438731339-58317-1-git-send-email-lina.iyer@linaro.org>
 <1438731339-58317-6-git-send-email-lina.iyer@linaro.org>
 <CAL_JsqK67=DTtjZwwnonObLDjLbahkREfm0RvyXVV95bhR-d4Q@mail.gmail.com>
 <20150813150154.GB13356@red-moon>
 <20150813154503.GO52339@linaro.org>
 <20150813155245.GD13833@red-moon>
 <7hegj6le8c.fsf@deeprootsystems.com>
Message-ID: <20150814040205.GA86880@linaro.org>

On Thu, Aug 13 2015 at 21:51 -0600, Kevin Hilman wrote:
>Lorenzo Pieralisi <lorenzo.pieralisi at arm.com> writes:
>
>> On Thu, Aug 13, 2015 at 04:45:03PM +0100, Lina Iyer wrote:
>>> On Thu, Aug 13 2015 at 09:01 -0600, Lorenzo Pieralisi wrote:
>>> >On Thu, Aug 06, 2015 at 04:14:51AM +0100, Rob Herring wrote:
>>> >> On Tue, Aug 4, 2015 at 6:35 PM, Lina Iyer <lina.iyer at linaro.org> wrote:
>>> >> > Define and add Generic PM domains (genpd) for ARM CPU clusters. Many new
>>> >> > SoCs group CPUs as clusters. Clusters share common resources like GIC,
>>> >> > power rail, caches, VFP, Coresight etc. When all CPUs in the cluster are
>>> >> > idle, these shared resources may also be put in their idle state.
>>> >> >
>>> >> > The idle time between the last CPU entering idle and a CPU resuming
>>> >> > execution is an opportunity for these shared resources to be powered
>>> >> > down. Generic PM domain provides a framework for defining such power
>>> >> > domains and attach devices to the domain. When the devices in the domain
>>> >> > are idle at runtime, the domain would also be suspended and resumed
>>> >> > before the first of the devices resume execution.
>>> >> >
>>> >> > We define a generic PM domain for each cluster and attach CPU devices in
>>> >> > the cluster to that PM domain. The DT definitions for the SoC describe
>>> >> > this relationship. Genpd callbacks for power_on and power_off can then
>>> >> > be used to power up/down the shared resources for the domain.
>>> >>
>>> >> [...]
>>> >>
>>> >> > +ARM CPU Power domains
>>> >> > +
>>> >> > +The device tree allows describing of CPU power domains in a SoC. In ARM SoC,
>>> >> > +CPUs may be grouped as clusters. A cluster may have CPUs, GIC, Coresight,
>>> >> > +caches, VFP and power controller and other peripheral hardware. Generally,
>>> >> > +when the CPUs in the cluster are idle/suspended, the shared resources may also
>>> >> > +be suspended and resumed before any of the CPUs resume execution.
>>> >> > +
>>> >> > +CPUs are the defined as the PM domain consumers and there is a PM domain
>>> >> > +provider for the CPUs. Bindings for generic PM domains (genpd) is described in
>>> >> > +[1].
>>> >> > +
>>> >> > +The ARM CPU PM domain follows the same binding convention as any generic PM
>>> >> > +domain. Additional binding properties are -
>>> >> > +
>>> >> > +- compatible:
>>> >> > +       Usage: required
>>> >> > +       Value type: <string>
>>> >> > +       Definition: Must also have
>>> >> > +                       "arm,pd"
>>> >> > +               inorder to initialize the genpd provider as ARM CPU PM domain.
>>> >>
>>> >> A compatible string should represent a particular h/w block. If it is
>>> >> generic, it should represent some sort of standard programming
>>> >> interface (e.g, AHCI, EHCI, etc.). This doesn't seem to be either and
>>> >> is rather just a mapping of what "driver" you want to use.
>>> >>
>>> >> I would expect that identifying a cpu's or cluster's power domain
>>> >> would be done by a phandle between the cpu/cluster node and power
>>> >> domain node. But I've not really looked at the power domain bindings
>>> >> so who knows.
>>> >
>>> >I would expect the same, meaning that a cpu node, like any other device
>>> >node would have a phandle pointing at the respective HW power domain.
>>> >
>>> CPUs have phandles to their domains. That is how the relationship
>>> between the domain provider (power-controller) and the consumer (CPU) is
>>> established.
>>>
>>> >I do not really understand why we want a "generic" CPU power domain, what
>>> >purpose does it serve ? Creating a collection of cpu devices that we
>>> >can call "cluster" ?
>>> >
>>> Nope, not for calling a cluster, a cluster :)
>>>
>>> This compatible is used to define a generic behavior of the CPU domain
>>> controller (in addition to the platform specific behavior of the domain
>>> power controller). The kernel activities for such power controller are
>>> generally the same which otherwise would be repeated across platforms.
>>
>> What activities ? CPU PM notifiers ?
>
>For today, yes.
>
>However, you can think of CPU PM notifiers as the equivalent of runtime
>PM hooks.  They're called when the "devices" are about to be powered off
>(runtime suspended) or powered on (runtime resumed.)
>
>However the CPU PM framework and notifiers are rather dumb compared to
>runtime PM.  For example, runtime PM gives you usecounting, autosuspend,
>control from userspace, statistics, etc. etc.  Also, IMO, CPU PM will
>not scale well for multiple clusters.
>
>What if instead, we used runtime PM for the things that the CPU PM
>notifiers manager (GIC, VFP, Coresight, etc.), and those drivers used
>runtime PM callbacks to replace their CPU PM notifiers?  We'd then be in
>a beautiful land where CPU "devices" (and the other connected logic) can
>be modeled as devices using runtime PM just like every other device in
>the system.
>
>Then take it up a level... what if we then could use genpd to model the
>"cluster", made of of the CPUs and "connected" devices (GIC, VFP, etc.)
>but also modeled the shared L2$ as a device which was using runtime PM.
>
>Now we're in a place where we can use all the benefits of runtime PM,
>plus the governor features of genpd to start doing a real, multi-CPU,
>multi-cluster CPUidle that's flexible enough to model the various
>dependencies in an SoC independent way, but generic enough to be able to
>use common governors for last-man standing, cache flushing, etc. etc.
>

- Off list

Nicely written response Kevin.
Thank you.

--Lina


From yinghai at kernel.org  Thu Aug 13 21:22:24 2015
From: yinghai at kernel.org (Yinghai Lu)
Date: Thu, 13 Aug 2015 21:22:24 -0700
Subject: [PATCH v2] lib/decompressors: Use real out buf size for gunzip with
 kernel
Message-ID: <1439526144-3243-1-git-send-email-yinghai@kernel.org>

When loading x86 64bit kernel above 4GiB with patched grub2, got kernel
gunzip error.

| early console in decompress_kernel
| decompress_kernel:
|       input: [0x807f2143b4-0x807ff61aee]
|      output: [0x807cc00000-0x807f3ea29b] 0x027ea29c: output_len
| boot via startup_64
| KASLR using RDTSC...
|  new output: [0x46fe000000-0x470138cfff] 0x0338d000: output_run_size
|  decompress: [0x46fe000000-0x47007ea29b] <=== [0x807f2143b4-0x807ff61aee]
|
| Decompressing Linux... gz...
|
| uncompression error
|
| -- System halted

the new buffer is at 0x46fe000000ULL, decompressor_gzip is using
0xffffffb901ffffff as out_len. gunzip in lib/zlib_inflate/inflate.c
cap that len to 0x01ffffff and decompress fails later.

We could hit this problem with crashkernel booting that uses kexec
loading kernel above 4GiB.

We have decompress_* support:
    1. inbuf[]/outbuf[] for kernel preboot.
    2. inbuf[]/flush() for initramfs
    3. fill()/flush() for initrd.
This bug only affect kernel preboot path that use outbuf[].

Add __decompress and take real out_buf_len for gunzip instead of guessing
wrong buf size.

-v2: fix unused warning on sh/arm/m32r from Fengguang.

Signed-off-by: Yinghai Lu <yinghai at kernel.org>
Fixes: 1431574a1c4 (lib/decompressors: fix "no limit" output buffer length)
Cc: Alexandre Courbot <acourbot at nvidia.com>
Cc: Jon Medhurst <tixy at linaro.org>
Cc: Stephen Warren <swarren at wwwdotorg.org>
Cc: "H. Peter Anvin" <hpa at zytor.com>
Cc: Thomas Gleixner <tglx at linutronix.de>
Cc: Ingo Molnar <mingo at redhat.com>
Cc: Russell King <linux at arm.linux.org.uk>
Cc: Yoshinori Sato <ysato at users.sourceforge.jp>
Cc: Ralf Baechle <ralf at linux-mips.org>
Cc: Martin Schwidefsky <schwidefsky at de.ibm.com>
Cc: Heiko Carstens <heiko.carstens at de.ibm.com>
Cc: Guan Xuetao <gxt at mprc.pku.edu.cn>
Cc: linux-arm-kernel at lists.infradead.org
Cc: uclinux-h8-devel at lists.sourceforge.jp
Cc: linux-mips at linux-mips.org
Cc: linux-s390 at vger.kernel.org
Cc: linux-sh at vger.kernel.org
Cc: Fengguang Wu <fengguang.wu at intel.com>
Cc: stable <stable at vger.kernel.org>

---
 arch/arm/boot/compressed/decompress.c  |    2 +-
 arch/h8300/boot/compressed/misc.c      |    2 +-
 arch/m32r/boot/compressed/misc.c       |    3 ++-
 arch/mips/boot/compressed/decompress.c |    4 ++--
 arch/s390/boot/compressed/misc.c       |    2 +-
 arch/sh/boot/compressed/misc.c         |    2 +-
 arch/unicore32/boot/compressed/misc.c  |    4 ++--
 arch/x86/boot/compressed/misc.c        |    3 ++-
 lib/decompress_bunzip2.c               |    6 +++---
 lib/decompress_inflate.c               |   31 ++++++++++++++++++++++++++-----
 lib/decompress_unlz4.c                 |    6 +++---
 lib/decompress_unlzma.c                |    7 +++----
 lib/decompress_unlzo.c                 |   13 ++++++++++++-
 lib/decompress_unxz.c                  |   12 +++++++++++-
 14 files changed, 70 insertions(+), 27 deletions(-)

Index: linux-2.6/arch/arm/boot/compressed/decompress.c
===================================================================
--- linux-2.6.orig/arch/arm/boot/compressed/decompress.c
+++ linux-2.6/arch/arm/boot/compressed/decompress.c
@@ -57,5 +57,5 @@ extern char * strstr(const char * s1, co
 
 int do_decompress(u8 *input, int len, u8 *output, void (*error)(char *x))
 {
-	return decompress(input, len, NULL, NULL, output, NULL, error);
+	return __decompress(input, len, NULL, NULL, output, 0, NULL, error);
 }
Index: linux-2.6/arch/h8300/boot/compressed/misc.c
===================================================================
--- linux-2.6.orig/arch/h8300/boot/compressed/misc.c
+++ linux-2.6/arch/h8300/boot/compressed/misc.c
@@ -70,5 +70,5 @@ void decompress_kernel(void)
 	free_mem_ptr = (unsigned long)&_end;
 	free_mem_end_ptr = free_mem_ptr + HEAP_SIZE;
 
-	decompress(input_data, input_len, NULL, NULL, output, NULL, error);
+	__decompress(input_data, input_len, NULL, NULL, output, 0, NULL, error);
 }
Index: linux-2.6/arch/m32r/boot/compressed/misc.c
===================================================================
--- linux-2.6.orig/arch/m32r/boot/compressed/misc.c
+++ linux-2.6/arch/m32r/boot/compressed/misc.c
@@ -86,6 +86,7 @@ decompress_kernel(int mmu_on, unsigned c
 	free_mem_end_ptr = free_mem_ptr + BOOT_HEAP_SIZE;
 
 	puts("\nDecompressing Linux... ");
-	decompress(input_data, input_len, NULL, NULL, output_data, NULL, error);
+	__decompress(input_data, input_len, NULL, NULL, output_data, 0,
+			NULL, error);
 	puts("done.\nBooting the kernel.\n");
 }
Index: linux-2.6/arch/mips/boot/compressed/decompress.c
===================================================================
--- linux-2.6.orig/arch/mips/boot/compressed/decompress.c
+++ linux-2.6/arch/mips/boot/compressed/decompress.c
@@ -111,8 +111,8 @@ void decompress_kernel(unsigned long boo
 	puts("\n");
 
 	/* Decompress the kernel with according algorithm */
-	decompress((char *)zimage_start, zimage_size, 0, 0,
-		   (void *)VMLINUX_LOAD_ADDRESS_ULL, 0, error);
+	__decompress((char *)zimage_start, zimage_size, 0, 0,
+		   (void *)VMLINUX_LOAD_ADDRESS_ULL, 0, 0, error);
 
 	/* FIXME: should we flush cache here? */
 	puts("Now, booting the kernel...\n");
Index: linux-2.6/arch/s390/boot/compressed/misc.c
===================================================================
--- linux-2.6.orig/arch/s390/boot/compressed/misc.c
+++ linux-2.6/arch/s390/boot/compressed/misc.c
@@ -167,7 +167,7 @@ unsigned long decompress_kernel(void)
 #endif
 
 	puts("Uncompressing Linux... ");
-	decompress(input_data, input_len, NULL, NULL, output, NULL, error);
+	__decompress(input_data, input_len, NULL, NULL, output, 0, NULL, error);
 	puts("Ok, booting the kernel.\n");
 	return (unsigned long) output;
 }
Index: linux-2.6/arch/sh/boot/compressed/misc.c
===================================================================
--- linux-2.6.orig/arch/sh/boot/compressed/misc.c
+++ linux-2.6/arch/sh/boot/compressed/misc.c
@@ -132,7 +132,7 @@ void decompress_kernel(void)
 
 	puts("Uncompressing Linux... ");
 	cache_control(CACHE_ENABLE);
-	decompress(input_data, input_len, NULL, NULL, output, NULL, error);
+	__decompress(input_data, input_len, NULL, NULL, output, 0, NULL, error);
 	cache_control(CACHE_DISABLE);
 	puts("Ok, booting the kernel.\n");
 }
Index: linux-2.6/arch/unicore32/boot/compressed/misc.c
===================================================================
--- linux-2.6.orig/arch/unicore32/boot/compressed/misc.c
+++ linux-2.6/arch/unicore32/boot/compressed/misc.c
@@ -119,8 +119,8 @@ unsigned long decompress_kernel(unsigned
 	output_ptr = get_unaligned_le32(tmp);
 
 	arch_decomp_puts("Uncompressing Linux...");
-	decompress(input_data, input_data_end - input_data, NULL, NULL,
-			output_data, NULL, error);
+	__decompress(input_data, input_data_end - input_data, NULL, NULL,
+			output_data, 0, NULL, error);
 	arch_decomp_puts(" done, booting the kernel.\n");
 	return output_ptr;
 }
Index: linux-2.6/arch/x86/boot/compressed/misc.c
===================================================================
--- linux-2.6.orig/arch/x86/boot/compressed/misc.c
+++ linux-2.6/arch/x86/boot/compressed/misc.c
@@ -448,7 +448,8 @@ asmlinkage __visible void *decompress_ke
 #endif
 
 	debug_putstr("\nDecompressing Linux... ");
-	decompress(input_data, input_len, NULL, NULL, output, NULL, error);
+	__decompress(input_data, input_len, NULL, NULL, output, output_len,
+			NULL, error);
 	parse_elf(output);
 	/*
 	 * 32-bit always performs relocations. 64-bit relocations are only
Index: linux-2.6/lib/decompress_bunzip2.c
===================================================================
--- linux-2.6.orig/lib/decompress_bunzip2.c
+++ linux-2.6/lib/decompress_bunzip2.c
@@ -743,12 +743,12 @@ exit_0:
 }
 
 #ifdef PREBOOT
-STATIC int INIT decompress(unsigned char *buf, long len,
+STATIC int INIT __decompress(unsigned char *buf, long len,
 			long (*fill)(void*, unsigned long),
 			long (*flush)(void*, unsigned long),
-			unsigned char *outbuf,
+			unsigned char *outbuf, long olen,
 			long *pos,
-			void(*error)(char *x))
+			void (*error)(char *x))
 {
 	return bunzip2(buf, len - 4, fill, flush, outbuf, pos, error);
 }
Index: linux-2.6/lib/decompress_inflate.c
===================================================================
--- linux-2.6.orig/lib/decompress_inflate.c
+++ linux-2.6/lib/decompress_inflate.c
@@ -1,4 +1,5 @@
 #ifdef STATIC
+#define PREBOOT
 /* Pre-boot environment: included */
 
 /* prevent inclusion of _LINUX_KERNEL_H in pre-boot environment: lots
@@ -33,23 +34,23 @@ static long INIT nofill(void *buffer, un
 }
 
 /* Included from initramfs et al code */
-STATIC int INIT gunzip(unsigned char *buf, long len,
+STATIC int INIT __gunzip(unsigned char *buf, long len,
 		       long (*fill)(void*, unsigned long),
 		       long (*flush)(void*, unsigned long),
-		       unsigned char *out_buf,
+		       unsigned char *out_buf, long out_len,
 		       long *pos,
 		       void(*error)(char *x)) {
 	u8 *zbuf;
 	struct z_stream_s *strm;
 	int rc;
-	size_t out_len;
 
 	rc = -1;
 	if (flush) {
 		out_len = 0x8000; /* 32 K */
 		out_buf = malloc(out_len);
 	} else {
-		out_len = ((size_t)~0) - (size_t)out_buf; /* no limit */
+		if (!out_len)
+			out_len = ((size_t)~0) - (size_t)out_buf; /* no limit */
 	}
 	if (!out_buf) {
 		error("Out of memory while allocating output buffer");
@@ -181,4 +182,24 @@ gunzip_nomem1:
 	return rc; /* returns Z_OK (0) if successful */
 }
 
-#define decompress gunzip
+#ifndef PREBOOT
+STATIC int INIT gunzip(unsigned char *buf, long len,
+		       long (*fill)(void*, unsigned long),
+		       long (*flush)(void*, unsigned long),
+		       unsigned char *out_buf,
+		       long *pos,
+		       void (*error)(char *x))
+{
+	return __gunzip(buf, len, fill, flush, out_buf, 0, pos, error);
+}
+#else
+STATIC int INIT __decompress(unsigned char *buf, long len,
+			   long (*fill)(void*, unsigned long),
+			   long (*flush)(void*, unsigned long),
+			   unsigned char *out_buf, long out_len,
+			   long *pos,
+			   void (*error)(char *x))
+{
+	return __gunzip(buf, len, fill, flush, out_buf, out_len, pos, error);
+}
+#endif
Index: linux-2.6/lib/decompress_unlz4.c
===================================================================
--- linux-2.6.orig/lib/decompress_unlz4.c
+++ linux-2.6/lib/decompress_unlz4.c
@@ -196,12 +196,12 @@ exit_0:
 }
 
 #ifdef PREBOOT
-STATIC int INIT decompress(unsigned char *buf, long in_len,
+STATIC int INIT __decompress(unsigned char *buf, long in_len,
 			      long (*fill)(void*, unsigned long),
 			      long (*flush)(void*, unsigned long),
-			      unsigned char *output,
+			      unsigned char *output, long out_len,
 			      long *posp,
-			      void(*error)(char *x)
+			      void (*error)(char *x)
 	)
 {
 	return unlz4(buf, in_len - 4, fill, flush, output, posp, error);
Index: linux-2.6/lib/decompress_unlzma.c
===================================================================
--- linux-2.6.orig/lib/decompress_unlzma.c
+++ linux-2.6/lib/decompress_unlzma.c
@@ -667,13 +667,12 @@ exit_0:
 }
 
 #ifdef PREBOOT
-STATIC int INIT decompress(unsigned char *buf, long in_len,
+STATIC int INIT __decompress(unsigned char *buf, long in_len,
 			      long (*fill)(void*, unsigned long),
 			      long (*flush)(void*, unsigned long),
-			      unsigned char *output,
+			      unsigned char *output, long out_len,
 			      long *posp,
-			      void(*error)(char *x)
-	)
+			      void (*error)(char *x))
 {
 	return unlzma(buf, in_len - 4, fill, flush, output, posp, error);
 }
Index: linux-2.6/lib/decompress_unlzo.c
===================================================================
--- linux-2.6.orig/lib/decompress_unlzo.c
+++ linux-2.6/lib/decompress_unlzo.c
@@ -31,6 +31,7 @@
  */
 
 #ifdef STATIC
+#define PREBOOT
 #include "lzo/lzo1x_decompress_safe.c"
 #else
 #include <linux/decompress/unlzo.h>
@@ -287,4 +288,14 @@ exit:
 	return ret;
 }
 
-#define decompress unlzo
+#ifdef PREBOOT
+STATIC int INIT __decompress(unsigned char *buf, long len,
+			   long (*fill)(void*, unsigned long),
+			   long (*flush)(void*, unsigned long),
+			   unsigned char *out_buf, long olen,
+			   long *pos,
+			   void (*error)(char *x))
+{
+	return unlzo(buf, len, fill, flush, out_buf, pos, error);
+}
+#endif
Index: linux-2.6/lib/decompress_unxz.c
===================================================================
--- linux-2.6.orig/lib/decompress_unxz.c
+++ linux-2.6/lib/decompress_unxz.c
@@ -394,4 +394,14 @@ error_alloc_state:
  * This macro is used by architecture-specific files to decompress
  * the kernel image.
  */
-#define decompress unxz
+#ifdef XZ_PREBOOT
+STATIC int INIT __decompress(unsigned char *buf, long len,
+			   long (*fill)(void*, unsigned long),
+			   long (*flush)(void*, unsigned long),
+			   unsigned char *out_buf, long olen,
+			   long *pos,
+			   void (*error)(char *x))
+{
+	return unxz(buf, len, fill, flush, out_buf, pos, error);
+}
+#endif


From edubezval at gmail.com  Thu Aug 13 21:50:11 2015
From: edubezval at gmail.com (Eduardo Valentin)
Date: Thu, 13 Aug 2015 21:50:11 -0700
Subject: [PATCH] thermal: cpu_cooling: fix lockdep problems in cpu_cooling
In-Reply-To: <E1ZPQfV-0005nb-DN@rmk-PC.arm.linux.org.uk>
References: <20150812073530.GA16445@linux>
 <E1ZPQfV-0005nb-DN@rmk-PC.arm.linux.org.uk>
Message-ID: <20150814045009.GB10354@localhost.localdomain>

Hi Russell,

On Wed, Aug 12, 2015 at 08:41:49AM +0100, Russell King wrote:

<cut>

> 
> For some reason, despite Rafael saying that this should go in, despite it
> having been reviewed, Eduardo appears to be ignoring basic fixes to code
> under his control.  Having waited more than a reasonable amount of time,
> it is now time to take some action against this blockage.  Hence, I'm
> putting this into linux-next in the hope that it'll conflict and elicit
> a response for this important bug fix.

Sorry if I let this one to fall into the cracks for this long.

I am looking at this now and queuing as soon as possible.

Thanks for pushing this fix.

BR,

Eduardo

> 
> Relevant message IDs:
> 20141214213655.GA11285 at n2100.arm.linux.org.uk
> 7573578.UE8ufgjWuX at vostro.rjw.lan
> 20141215230922.GL11285 at n2100.arm.linux.org.uk
> CAKohponhkk9BK6-7ScHeZa4R43iooWQFV8YoPLv6LjO40GNq=A at mail.gmail.com
> 20150518185645.GA28053 at n2100.arm.linux.org.uk
> 2574268.XBqpdL2VLI at vostro.rjw.lan
> ---
>  drivers/thermal/cpu_cooling.c | 22 ++++++++++++++++------
>  1 file changed, 16 insertions(+), 6 deletions(-)
> 
> diff --git a/drivers/thermal/cpu_cooling.c b/drivers/thermal/cpu_cooling.c
> index 6509c61b9648..d1fd02eec58d 100644
> --- a/drivers/thermal/cpu_cooling.c
> +++ b/drivers/thermal/cpu_cooling.c
> @@ -107,6 +107,9 @@ struct cpufreq_cooling_device {
>  static DEFINE_IDR(cpufreq_idr);
>  static DEFINE_MUTEX(cooling_cpufreq_lock);
>  
> +static unsigned int cpufreq_dev_count;
> +
> +static DEFINE_MUTEX(cooling_list_lock);
>  static LIST_HEAD(cpufreq_dev_list);
>  
>  /**
> @@ -221,7 +224,7 @@ static int cpufreq_thermal_notifier(struct notifier_block *nb,
>  	switch (event) {
>  
>  	case CPUFREQ_ADJUST:
> -		mutex_lock(&cooling_cpufreq_lock);
> +		mutex_lock(&cooling_list_lock);
>  		list_for_each_entry(cpufreq_dev, &cpufreq_dev_list, node) {
>  			if (!cpumask_test_cpu(policy->cpu,
>  					      &cpufreq_dev->allowed_cpus))
> @@ -233,7 +236,7 @@ static int cpufreq_thermal_notifier(struct notifier_block *nb,
>  				cpufreq_verify_within_limits(policy, 0,
>  							     max_freq);
>  		}
> -		mutex_unlock(&cooling_cpufreq_lock);
> +		mutex_unlock(&cooling_list_lock);
>  		break;
>  	default:
>  		return NOTIFY_DONE;
> @@ -865,12 +868,15 @@ __cpufreq_cooling_register(struct device_node *np,
>  	cpufreq_dev->cool_dev = cool_dev;
>  
>  	mutex_lock(&cooling_cpufreq_lock);
> +	mutex_lock(&cooling_list_lock);
> +	list_add(&cpufreq_dev->node, &cpufreq_dev_list);
> +	mutex_unlock(&cooling_list_lock);
>  
>  	/* Register the notifier for first cpufreq cooling device */
> -	if (list_empty(&cpufreq_dev_list))
> +	if (cpufreq_dev_count == 0)
>  		cpufreq_register_notifier(&thermal_cpufreq_notifier_block,
>  					  CPUFREQ_POLICY_NOTIFIER);
> -	list_add(&cpufreq_dev->node, &cpufreq_dev_list);
> +	cpufreq_dev_count++;
>  
>  	mutex_unlock(&cooling_cpufreq_lock);
>  
> @@ -1014,14 +1020,18 @@ void cpufreq_cooling_unregister(struct thermal_cooling_device *cdev)
>  
>  	cpufreq_dev = cdev->devdata;
>  	mutex_lock(&cooling_cpufreq_lock);
> -	list_del(&cpufreq_dev->node);
> +	cpufreq_dev_count--;
>  
>  	/* Unregister the notifier for the last cpufreq cooling device */
> -	if (list_empty(&cpufreq_dev_list))
> +	if (cpufreq_dev_count == 0)
>  		cpufreq_unregister_notifier(&thermal_cpufreq_notifier_block,
>  					    CPUFREQ_POLICY_NOTIFIER);
>  	mutex_unlock(&cooling_cpufreq_lock);
>  
> +	mutex_lock(&cooling_list_lock);
> +	list_del(&cpufreq_dev->node);
> +	mutex_unlock(&cooling_list_lock);
> +
>  	thermal_cooling_device_unregister(cpufreq_dev->cool_dev);
>  	release_idr(&cpufreq_idr, cpufreq_dev->id);
>  	kfree(cpufreq_dev->time_in_idle_timestamp);
> -- 
> 2.1.0
> 


From horms at verge.net.au  Thu Aug 13 21:54:16 2015
From: horms at verge.net.au (Simon Horman)
Date: Fri, 14 Aug 2015 13:54:16 +0900
Subject: [PATCH v2] ARM: shmobile: kzm9g dts: Use adxl345-specific
 compatible property
In-Reply-To: <10744920.2768uXkYtL@avalon>
References: <1436180132-26190-1-git-send-email-geert+renesas@glider.be>
 <20150813000537.GD5221@verge.net.au>
 <CAMuHMdV0fqjJSjmYqP0uFa0x5ydc1iztu4za1Ufu7OMdhC29Ug@mail.gmail.com>
 <10744920.2768uXkYtL@avalon>
Message-ID: <20150814045414.GA7739@verge.net.au>

On Fri, Aug 14, 2015 at 12:31:09AM +0300, Laurent Pinchart wrote:
> On Thursday 13 August 2015 11:26:32 Geert Uytterhoeven wrote:
> > On Thu, Aug 13, 2015 at 2:05 AM, Simon Horman <horms at verge.net.au> wrote:
> > > On Wed, Jul 08, 2015 at 09:51:49AM +0900, Simon Horman wrote:
> > >> On Tue, Jul 07, 2015 at 09:56:29AM +0300, Laurent Pinchart wrote:
> > >>> On Tuesday 07 July 2015 09:26:21 Simon Horman wrote:
> > >>>> On Mon, Jul 06, 2015 at 04:29:33PM +0300, Laurent Pinchart wrote:
> > >>>>> On Monday 06 July 2015 12:55:32 Geert Uytterhoeven wrote:
> > >>>>>> Replace the deprecated generic "adi,adxl34x" compatible value by
> > >>>>>> the adxl345-specific "adi,adxl345" value, cfr. commit
> > >>>>>> e465bf6fc55d5ce2 ("DT:
> > >>>>>> i2c: Deprecate adi,adxl34x compatible string").
> > >>>>>> 
> > >>>>>> Signed-off-by: Geert Uytterhoeven <geert+renesas at glider.be>
> > >>>>> 
> > >>>>> Acked-by: Laurent Pinchart
> > >>>>> <laurent.pinchart+renesas at ideasonboard.com>
> > >>>>> 
> > >>>>>> ---
> > >>>>>> Depends on commit 3a38958d2477b718 ("Input: adxl34x - add OF
> > >>>>>> match support"), which is in v4.2-rc1.
> > >>>>>> 
> > >>>>>> This is v2 of "ARM: shmobile: kzm9g dts: Add adxl345-specific
> > >>>>>> compatible property".
> > >>>> 
> > >>>> It appears to me that this will cause a regression when booting old
> > >>>> kernels with new dts blobs. For that reason think we should consider
> > >>>> v1 of this change coupled with a schedule to remove use of the
> > >>>> deprecated compat string.
> > >>> 
> > >>> That's the forward compatibility that Geert mentioned, is that really
> > >>> an issue, especially on this board ?
> > >> 
> > >> I think it would be best to provide backwards compatibility unless there
> > >> is a compelling reason not to.
> > > 
> > > I would like to revisit this discussion with a view to getting some
> > > version of this patch queued up (yes I know I pushed back on it earlier in
> > > this thread).
> >
> > I'm fine with applying v1.
> 
> And I'm quite unsurprisingly not, as I've asked for a v2.
> 
> The "adi,adxl34x" compatible string is deprecated. That means we still support 
> it in the driver for device trees that haven't been updated, but it shouldn't 
> be used forward by new device trees. That's why the device tree sources 
> contained in the kernel shouldn't use it, especially given that they often 
> serve as references for device trees shipped out of tree.

Thanks, I see your point now. I have queued up v2.


From laurent.pinchart at ideasonboard.com  Thu Aug 13 22:17:28 2015
From: laurent.pinchart at ideasonboard.com (Laurent Pinchart)
Date: Fri, 14 Aug 2015 08:17:28 +0300
Subject: [PATCH v2] ARM: shmobile: kzm9g dts: Use adxl345-specific
 compatible property
In-Reply-To: <20150814045414.GA7739@verge.net.au>
References: <1436180132-26190-1-git-send-email-geert+renesas@glider.be>
 <10744920.2768uXkYtL@avalon> <20150814045414.GA7739@verge.net.au>
Message-ID: <1710972.6MUFEBJ6zn@avalon>

Hi Simon,

On Friday 14 August 2015 13:54:16 Simon Horman wrote:
> On Fri, Aug 14, 2015 at 12:31:09AM +0300, Laurent Pinchart wrote:
> > On Thursday 13 August 2015 11:26:32 Geert Uytterhoeven wrote:
> >> On Thu, Aug 13, 2015 at 2:05 AM, Simon Horman <horms at verge.net.au> wrote:
> >>> On Wed, Jul 08, 2015 at 09:51:49AM +0900, Simon Horman wrote:
> >>>> On Tue, Jul 07, 2015 at 09:56:29AM +0300, Laurent Pinchart wrote:
> >>>>> On Tuesday 07 July 2015 09:26:21 Simon Horman wrote:
> >>>>>> On Mon, Jul 06, 2015 at 04:29:33PM +0300, Laurent Pinchart wrote:
> >>>>>>> On Monday 06 July 2015 12:55:32 Geert Uytterhoeven wrote:
> >>>>>>>> Replace the deprecated generic "adi,adxl34x" compatible value by
> >>>>>>>> the adxl345-specific "adi,adxl345" value, cfr. commit
> >>>>>>>> e465bf6fc55d5ce2 ("DT:
> >>>>>>>> i2c: Deprecate adi,adxl34x compatible string").
> >>>>>>>> 
> >>>>>>>> Signed-off-by: Geert Uytterhoeven <geert+renesas at glider.be>
> >>>>>>> 
> >>>>>>> Acked-by: Laurent Pinchart
> >>>>>>> <laurent.pinchart+renesas at ideasonboard.com>
> >>>>>>> 
> >>>>>>>> ---
> >>>>>>>> Depends on commit 3a38958d2477b718 ("Input: adxl34x - add OF
> >>>>>>>> match support"), which is in v4.2-rc1.
> >>>>>>>> 
> >>>>>>>> This is v2 of "ARM: shmobile: kzm9g dts: Add adxl345-specific
> >>>>>>>> compatible property".
> >>>>>> 
> >>>>>> It appears to me that this will cause a regression when booting old
> >>>>>> kernels with new dts blobs. For that reason think we should
> >>>>>> consider v1 of this change coupled with a schedule to remove use of
> >>>>>> the deprecated compat string.
> >>>>> 
> >>>>> That's the forward compatibility that Geert mentioned, is that
> >>>>> really an issue, especially on this board ?
> >>>> 
> >>>> I think it would be best to provide backwards compatibility unless
> >>>> there is a compelling reason not to.
> >>> 
> >>> I would like to revisit this discussion with a view to getting some
> >>> version of this patch queued up (yes I know I pushed back on it
> >>> earlier in this thread).
> >> 
> >> I'm fine with applying v1.
> > 
> > And I'm quite unsurprisingly not, as I've asked for a v2.
> > 
> > The "adi,adxl34x" compatible string is deprecated. That means we still
> > support it in the driver for device trees that haven't been updated, but
> > it shouldn't be used forward by new device trees. That's why the device
> > tree sources contained in the kernel shouldn't use it, especially given
> > that they often serve as references for device trees shipped out of tree.
> 
> Thanks, I see your point now. I have queued up v2.

Thank you :-)

-- 
Regards,

Laurent Pinchart



From viresh.kumar at linaro.org  Thu Aug 13 22:53:59 2015
From: viresh.kumar at linaro.org (Viresh Kumar)
Date: Fri, 14 Aug 2015 11:23:59 +0530
Subject: [PATCH] thermal: cpu_cooling: fix lockdep problems in cpu_cooling
In-Reply-To: <20150814045009.GB10354@localhost.localdomain>
References: <20150812073530.GA16445@linux>
 <E1ZPQfV-0005nb-DN@rmk-PC.arm.linux.org.uk>
 <20150814045009.GB10354@localhost.localdomain>
Message-ID: <20150814055359.GY20238@linux>

On 13-08-15, 21:50, Eduardo Valentin wrote:
> Sorry if I let this one to fall into the cracks for this long.
> 
> I am looking at this now and queuing as soon as possible.

You applied the wrong one, please drop it. And apply the one I have
sent as a separate thread, with my sob on it.

-- 
viresh


From viresh.kumar at linaro.org  Thu Aug 13 22:55:56 2015
From: viresh.kumar at linaro.org (Viresh Kumar)
Date: Fri, 14 Aug 2015 11:25:56 +0530
Subject: [PATCH V2] thermal: cpu_cooling: fix lockdep problems in
 cpu_cooling
In-Reply-To: <16e7d7d811fa2b0f8dcf6cade345a5f2f3e3c36a.1439372926.git.viresh.kumar@linaro.org>
References: <16e7d7d811fa2b0f8dcf6cade345a5f2f3e3c36a.1439372926.git.viresh.kumar@linaro.org>
Message-ID: <20150814055556.GZ20238@linux>

On 12-08-15, 15:22, Viresh Kumar wrote:
> From: Russell King <rmk+kernel at arm.linux.org.uk>
> Fixes: 2dcd851fe4b4 ("thermal: cpu_cooling: Update always cpufreq policy with
> Reviewed-by: Viresh Kumar <viresh.kumar at linaro.org>
> Signed-off-by: Russell King <rmk+kernel at arm.linux.org.uk>
> Signed-off-by: Viresh Kumar <viresh.kumar at linaro.org>
> ---
> 
> Hi Eduardo/Zhang,
> 
> This is 4.2-rc material, please apply soon.

Hey,

Please apply this one and drop

8ad61f934e9e ("thermal: cpu_cooling: fix lockdep problems in
cpu_cooling")

-- 
viresh


From yao.yuan at freescale.com  Thu Aug 13 23:24:48 2015
From: yao.yuan at freescale.com (Yao Yuan)
Date: Fri, 14 Aug 2015 06:24:48 +0000
Subject: [PATCH v2] dmaengine: fsl-edma: add PM suspend/resume support
In-Reply-To: <CADRPPNQJi_x+mdQV=DEVuhCL_p6VOWcPiV3jzioeRdWgSW2w3g@mail.gmail.com>
References: <1437469005-3162-1-git-send-email-yao.yuan@freescale.com>
 <CADRPPNQJi_x+mdQV=DEVuhCL_p6VOWcPiV3jzioeRdWgSW2w3g@mail.gmail.com>
Message-ID: <CY1PR0301MB15628DD5CFCE2B65BF4FECB2837C0@CY1PR0301MB1562.namprd03.prod.outlook.com>

Hi Leo,

Thanks for your review.
About those two methods for DMA suspend that you have mentioned. We have a lot of the discussions in other DMA driver like DMA for Freescale PowerPC.

Finally, we think the device which used the DMA transmission service should cancel the transmission service in its suspend. 
So DMA in suspend should be idle.

Once the DMA in late_suspend is not be idle, we think some driver haven't canceled the DMA transmission. So maybe something is error when other driver in suspend.

In the case, we should return failed to stop PM. DMA should not make a choice for other drivers(which used DMA) to force stop DMA transmission.

Thanks.

Best Regards,
Yuan Yao

> -----Original Message-----
> From: pku.leo at gmail.com [mailto:pku.leo at gmail.com] On Behalf Of Li Yang
> Sent: Friday, August 14, 2015 4:58 AM
> To: Yuan Yao-B46683
> Cc: Vinod Koul; stefan at agner.ch; Arnd Bergmann; Dan Williams;
> dmaengine at vger.kernel.org; lkml; linux-arm-kernel at lists.infradead.org; linux-
> pm at vger.kernel.org
> Subject: Re: [PATCH v2] dmaengine: fsl-edma: add PM suspend/resume
> support
> 
> On Tue, Jul 21, 2015 at 3:56 AM, Yuan Yao <yao.yuan at freescale.com> wrote:
> > This add power management suspend/resume support for the fsl-edma
> > driver.
> >
> > eDMA acted as a basic function used by others. What it needs to do is
> > the two steps below to support power management.
> >
> > In fsl_edma_suspend_late:
> > Check whether the DMA chan is idle and if it is not idle, stop PM
> > operation.
> 
> You should try to quiesce the device on suspend instead of depending on itself
> to be happen in idle and failing if it is not.
> 
> Regards,
> Leo

From lee.jones at linaro.org  Thu Aug 13 23:33:43 2015
From: lee.jones at linaro.org (Lee Jones)
Date: Fri, 14 Aug 2015 07:33:43 +0100
Subject: [PATCH v2 3/6] mailbox: Add support for ST's Mailbox IP
In-Reply-To: <CABb+yY3NTHLx2N-sUABjxQW=MUCntdUg1d8kjvjH0dkb4n9EgA@mail.gmail.com>
References: <1437990272-23111-1-git-send-email-lee.jones@linaro.org>
 <1437990272-23111-4-git-send-email-lee.jones@linaro.org>
 <CABb+yY3NTHLx2N-sUABjxQW=MUCntdUg1d8kjvjH0dkb4n9EgA@mail.gmail.com>
Message-ID: <20150814063343.GI8782@x1>

On Thu, 13 Aug 2015, Jassi Brar wrote:
> On Mon, Jul 27, 2015 at 3:14 PM, Lee Jones <lee.jones at linaro.org> wrote:
> 
> > +
> > +static bool sti_mbox_tx_is_ready(struct mbox_chan *chan)
> > +{
> > +       struct sti_channel *chan_info = chan->con_priv;
> > +       struct sti_mbox_device *mdev = chan_info->mdev;
> > +       unsigned int instance = chan_info->instance;
> > +       unsigned int channel = chan_info->channel;
> > +       void __iomem *base = MBOX_BASE(mdev, instance);
> > +
> > +       if (!(chan_info->direction & MBOX_TX))
> > +               return false;
> >
> Here the 'direction' is gotten via DT node of the client i.e, you
> expect consumer drivers to tell the provider what its limitations are?
> 
> IMO if some physical channel can't do TX then that should be either
> hardcoded inside the controller driver or learnt via DT node of the
> _controller_.

That's a fair point.  I need to create a new property similar to the
already existing 'read-only'.  I guess 'tx-only' is equivalent.

> > +static struct mbox_chan *sti_mbox_xlate(struct mbox_controller *mbox,
> > +                                       const struct of_phandle_args *spec)
> > +{
> > +       struct sti_mbox_device *mdev = dev_get_drvdata(mbox->dev);
> > +       struct sti_mbox_pdata *pdata = dev_get_platdata(mdev->dev);
> > +       struct sti_channel *chan_info;
> > +       struct mbox_chan *chan = NULL;
> > +       unsigned int instance  = spec->args[0];
> > +       unsigned int channel   = spec->args[1];
> > +       unsigned int direction = spec->args[2];
> > +       int i;
> > +
> > +       /* Bounds checking */
> > +       if (instance >= pdata->num_inst || channel  >= pdata->num_chan) {
> > +               dev_err(mbox->dev,
> > +                       "Invalid channel requested instance: %d channel: %d\n",
> > +                       instance, channel);
> > +               return NULL;
> return ERR_PTR(-EINVAL)

I can handle all these, no problem.

> > +       }
> > +
> > +       for (i = 0; i < mbox->num_chans; i++) {
> > +               chan_info = mbox->chans[i].con_priv;
> > +
> > +               /* Is requested channel free? */
> > +               if (direction != MBOX_LOOPBACK &&
> >
> Consider this example when 2 clients ask for same physical channel but
> in different modes.
>            mboxes = <&mboxA 0 1 MBOX_TX>;
>            mboxes = <&mboxA 0 1 MBOX_LOOPBACK>;
> 
> You happily assign 2 virtual channels backed by one physical channel
> {mboxA, 0, 1}. The 2 clients think they can freely do startup(),
> shutdown() and send_data() on the channels. But obviously we are
> screwed with races like
>    client1.startup()
>     -> client2.startup()
>         -> client2.send_data()
>             -> client2.shutdown()
>                 -> client1.send_data()  XXXX

Good catch and a fair point.  As you say, it's unlikely to happen, but
I would like to prevent it in any case.

>  Now you can shove in some more checks to 'fix' the race OR you can
> simply expose only physical channels.

We can't expose all of the channels.  There are too many and would
take up too much *unused* memory.

I don't want to have an endless stream of checks either, but we should
try to cover the bases.  I think smarter (rather than more) checks is
the answer.  I'll have a think about it.

> Practically no client would ever
> ask it to do what it can't, and for the hypothetical possibility that
> some does, just return error.

Right.  Smarter error checking here and returning an error on a bad
config is what I plan to do.

[...]

-- 
Lee Jones
Linaro STMicroelectronics Landing Team Lead
Linaro.org ? Open source software for ARM SoCs
Follow Linaro: Facebook | Twitter | Blog


From lho at apm.com  Thu Aug 13 23:46:05 2015
From: lho at apm.com (Loc Ho)
Date: Fri, 14 Aug 2015 00:46:05 -0600
Subject: [PATCH v4 0/4] edac: Add L3/SoC support to the APM X-Gene SoC EDAC
 driver
Message-ID: <1439534769-22811-1-git-send-email-lho@apm.com>

v4:
* Remove function for EDAC debugfs node and replace with export variable
* Switch the driver to use the exported edac_debugfs variable
* Revert the if statement logic for function as necessary
* Remove un-necessary code in debugfs creation functions

v3:
* Add an function to retrieve the EDAC debugfs node
* Move all debugfs node under EDAC code debugfs node
* Update L3 to check for v1 errata
* Rename error label for L3/SoC add routines
* Re-structure SoC EDAC functions for code readability
* Inline the function xgene_edac_soc_mem_data
* Remove un-necessary { }

v2:
* Update binding documentation accordingly
* Change all single bit defines to BIT(x)
* Add support for L3 version 1 and 2 HW's
* Change to use debug file system for error injection
* In L3/SoC instance add function, allocate EDAC context after all
  initalization successed
* Support raw or detail info for SoC EDAC error reporting

v1:
* Add L3/SoC support to the APM X-Gene SoC EDAC driver
---
Loc Ho (4):
  edac: Export edac_debugfs
  Documentation: Update the APM X-Gene SoC EDAC DTS binding for L3/SoC
    subnodes
  edac: Add L3/SoC EDAC support to the APM X-Gene SoC EDAC driver
  arm64: Add L3/SoC DT subnodes to the APM X-Gene SoC EDAC node

 .../devicetree/bindings/edac/apm-xgene-edac.txt    |   23 +
 arch/arm64/boot/dts/apm/apm-storm.dtsi             |   10 +
 drivers/edac/edac_core.h                           |    1 +
 drivers/edac/edac_mc_sysfs.c                       |    5 +-
 drivers/edac/xgene_edac.c                          | 1169 ++++++++++++++++----
 5 files changed, 1012 insertions(+), 196 deletions(-)



From lho at apm.com  Thu Aug 13 23:46:06 2015
From: lho at apm.com (Loc Ho)
Date: Fri, 14 Aug 2015 00:46:06 -0600
Subject: [PATCH v4 1/4] edac: Export edac_debugfs
In-Reply-To: <1439534769-22811-1-git-send-email-lho@apm.com>
References: <1439534769-22811-1-git-send-email-lho@apm.com>
Message-ID: <1439534769-22811-2-git-send-email-lho@apm.com>

This patch exports and expose the edac_debugfs file node. This allows
EDAC driver to create debugfs node under the EDAC debugfs node.

Signed-off-by: Loc Ho <lho at apm.com>
---
 drivers/edac/edac_core.h     |    1 +
 drivers/edac/edac_mc_sysfs.c |    5 +++--
 2 files changed, 4 insertions(+), 2 deletions(-)

diff --git a/drivers/edac/edac_core.h b/drivers/edac/edac_core.h
index ad42587..a978a4f 100644
--- a/drivers/edac/edac_core.h
+++ b/drivers/edac/edac_core.h
@@ -511,5 +511,6 @@ extern void edac_pci_remove_sysfs(struct edac_pci_ctl_info *pci);
  * edac misc APIs
  */
 extern char *edac_op_state_to_string(int op_state);
+extern struct dentry *edac_debugfs;
 
 #endif				/* _EDAC_CORE_H_ */
diff --git a/drivers/edac/edac_mc_sysfs.c b/drivers/edac/edac_mc_sysfs.c
index 33df7d9..236e76c 100644
--- a/drivers/edac/edac_mc_sysfs.c
+++ b/drivers/edac/edac_mc_sysfs.c
@@ -896,9 +896,10 @@ static struct device_type mci_attr_type = {
 	.release	= mci_attr_release,
 };
 
-#ifdef CONFIG_EDAC_DEBUG
-static struct dentry *edac_debugfs;
+struct dentry *edac_debugfs;
+EXPORT_SYMBOL_GPL(edac_debugfs);
 
+#ifdef CONFIG_EDAC_DEBUG
 int __init edac_debugfs_init(void)
 {
 	edac_debugfs = debugfs_create_dir("edac", NULL);
-- 
1.7.1



From lho at apm.com  Thu Aug 13 23:46:07 2015
From: lho at apm.com (Loc Ho)
Date: Fri, 14 Aug 2015 00:46:07 -0600
Subject: [PATCH v4 2/4] Documentation: Update the APM X-Gene SoC EDAC DTS
 binding for L3/SoC subnodes
In-Reply-To: <1439534769-22811-2-git-send-email-lho@apm.com>
References: <1439534769-22811-1-git-send-email-lho@apm.com>
 <1439534769-22811-2-git-send-email-lho@apm.com>
Message-ID: <1439534769-22811-3-git-send-email-lho@apm.com>

This patch updates documentation for the APM X-Gene SoC EDAC DTS binding
for L3/SoC subnodes.

Signed-off-by: Loc Ho <lho at apm.com>
---
 .../devicetree/bindings/edac/apm-xgene-edac.txt    |   23 ++++++++++++++++++++
 1 files changed, 23 insertions(+), 0 deletions(-)

diff --git a/Documentation/devicetree/bindings/edac/apm-xgene-edac.txt b/Documentation/devicetree/bindings/edac/apm-xgene-edac.txt
index 78edb80..78e2a31 100644
--- a/Documentation/devicetree/bindings/edac/apm-xgene-edac.txt
+++ b/Documentation/devicetree/bindings/edac/apm-xgene-edac.txt
@@ -5,6 +5,8 @@ The follow error types are supported:
 
   memory controller	- Memory controller
   PMD (L1/L2)		- Processor module unit (PMD) L1/L2 cache
+  L3			- L3 cache controller
+  SoC			- SoC IP's such as Ethernet, SATA, and etc
 
 The following section describes the EDAC DT node binding.
 
@@ -30,6 +32,17 @@ Required properties for PMD subnode:
 - reg			: First resource shall be the PMD resource.
 - pmd-controller	: Instance number of the PMD controller.
 
+Required properties for L3 subnode:
+- compatible		: Shall be "apm,xgene-edac-l3" or
+                          "apm,xgene-edac-l3-v2".
+- reg			: First resource shall be the L3 EDAC resource.
+
+Required properties for SoC subnode:
+- compatible		: Shall be "apm,xgene-edac-soc-v1" for revision 1 or
+                          "apm,xgene-edac-l3-soc" for general value reporting
+                          only.
+- reg			: First resource shall be the SoC EDAC resource.
+
 Example:
 	csw: csw at 7e200000 {
 		compatible = "apm,xgene-csw", "syscon";
@@ -76,4 +89,14 @@ Example:
 			reg = <0x0 0x7c000000 0x0 0x200000>;
 			pmd-controller = <0>;
 		};
+
+		edacl3 at 7e600000 {
+			compatible = "apm,xgene-edac-l3";
+			reg = <0x0 0x7e600000 0x0 0x1000>;
+		};
+
+		edacsoc at 7e930000 {
+			compatible = "apm,xgene-edac-soc-v1";
+			reg = <0x0 0x7e930000 0x0 0x1000>;
+		};
 	};
-- 
1.7.1



From lho at apm.com  Thu Aug 13 23:46:08 2015
From: lho at apm.com (Loc Ho)
Date: Fri, 14 Aug 2015 00:46:08 -0600
Subject: [PATCH v4 3/4] edac: Add L3/SoC EDAC support to the APM X-Gene SoC
 EDAC driver
In-Reply-To: <1439534769-22811-3-git-send-email-lho@apm.com>
References: <1439534769-22811-1-git-send-email-lho@apm.com>
 <1439534769-22811-2-git-send-email-lho@apm.com>
 <1439534769-22811-3-git-send-email-lho@apm.com>
Message-ID: <1439534769-22811-4-git-send-email-lho@apm.com>

This patch adds EDAC support for the L3 and SoC components.

Signed-off-by: Loc Ho <lho at apm.com>
---
 drivers/edac/xgene_edac.c | 1169 +++++++++++++++++++++++++++++++++++++--------
 1 files changed, 975 insertions(+), 194 deletions(-)

diff --git a/drivers/edac/xgene_edac.c b/drivers/edac/xgene_edac.c
index ba06904..c7a5ea6 100644
--- a/drivers/edac/xgene_edac.c
+++ b/drivers/edac/xgene_edac.c
@@ -66,6 +66,8 @@ struct xgene_edac {
 
 	struct list_head	mcus;
 	struct list_head	pmds;
+	struct list_head	l3s;
+	struct list_head	socs;
 
 	struct mutex		mc_lock;
 	int			mc_active_mask;
@@ -536,140 +538,134 @@ static void xgene_edac_pmd_l1_check(struct edac_device_ctl_info *edac_dev,
 	pg_f = ctx->pmd_csr + cpu_idx * CPU_CSR_STRIDE + CPU_MEMERR_CPU_PAGE;
 
 	val = readl(pg_f + MEMERR_CPU_ICFESR_PAGE_OFFSET);
-	if (val) {
-		dev_err(edac_dev->dev,
-			"CPU%d L1 memory error ICF 0x%08X Way 0x%02X Index 0x%02X Info 0x%02X\n",
-			ctx->pmd * MAX_CPU_PER_PMD + cpu_idx, val,
-			MEMERR_CPU_ICFESR_ERRWAY_RD(val),
-			MEMERR_CPU_ICFESR_ERRINDEX_RD(val),
-			MEMERR_CPU_ICFESR_ERRINFO_RD(val));
-		if (val & MEMERR_CPU_ICFESR_CERR_MASK)
-			dev_err(edac_dev->dev,
-				"One or more correctable error\n");
-		if (val & MEMERR_CPU_ICFESR_MULTCERR_MASK)
-			dev_err(edac_dev->dev, "Multiple correctable error\n");
-		switch (MEMERR_CPU_ICFESR_ERRTYPE_RD(val)) {
-		case 1:
-			dev_err(edac_dev->dev, "L1 TLB multiple hit\n");
-			break;
-		case 2:
-			dev_err(edac_dev->dev, "Way select multiple hit\n");
-			break;
-		case 3:
-			dev_err(edac_dev->dev, "Physical tag parity error\n");
-			break;
-		case 4:
-		case 5:
-			dev_err(edac_dev->dev, "L1 data parity error\n");
-			break;
-		case 6:
-			dev_err(edac_dev->dev, "L1 pre-decode parity error\n");
-			break;
-		}
+	if (!val)
+		goto chk_lsu;
+	dev_err(edac_dev->dev,
+		"CPU%d L1 memory error ICF 0x%08X Way 0x%02X Index 0x%02X Info 0x%02X\n",
+		ctx->pmd * MAX_CPU_PER_PMD + cpu_idx, val,
+		MEMERR_CPU_ICFESR_ERRWAY_RD(val),
+		MEMERR_CPU_ICFESR_ERRINDEX_RD(val),
+		MEMERR_CPU_ICFESR_ERRINFO_RD(val));
+	if (val & MEMERR_CPU_ICFESR_CERR_MASK)
+		dev_err(edac_dev->dev, "One or more correctable error\n");
+	if (val & MEMERR_CPU_ICFESR_MULTCERR_MASK)
+		dev_err(edac_dev->dev, "Multiple correctable error\n");
+	switch (MEMERR_CPU_ICFESR_ERRTYPE_RD(val)) {
+	case 1:
+		dev_err(edac_dev->dev, "L1 TLB multiple hit\n");
+		break;
+	case 2:
+		dev_err(edac_dev->dev, "Way select multiple hit\n");
+		break;
+	case 3:
+		dev_err(edac_dev->dev, "Physical tag parity error\n");
+		break;
+	case 4:
+	case 5:
+		dev_err(edac_dev->dev, "L1 data parity error\n");
+		break;
+	case 6:
+		dev_err(edac_dev->dev, "L1 pre-decode parity error\n");
+		break;
+	}
 
-		/* Clear any HW errors */
-		writel(val, pg_f + MEMERR_CPU_ICFESR_PAGE_OFFSET);
+	/* Clear any HW errors */
+	writel(val, pg_f + MEMERR_CPU_ICFESR_PAGE_OFFSET);
 
-		if (val & (MEMERR_CPU_ICFESR_CERR_MASK |
-			   MEMERR_CPU_ICFESR_MULTCERR_MASK))
-			edac_device_handle_ce(edac_dev, 0, 0,
-					      edac_dev->ctl_name);
-	}
+	if (val & (MEMERR_CPU_ICFESR_CERR_MASK |
+		   MEMERR_CPU_ICFESR_MULTCERR_MASK))
+		edac_device_handle_ce(edac_dev, 0, 0, edac_dev->ctl_name);
 
+chk_lsu:
 	val = readl(pg_f + MEMERR_CPU_LSUESR_PAGE_OFFSET);
-	if (val) {
+	if (!val)
+		goto chk_mmu;
+	dev_err(edac_dev->dev,
+		"CPU%d memory error LSU 0x%08X Way 0x%02X Index 0x%02X Info 0x%02X\n",
+		ctx->pmd * MAX_CPU_PER_PMD + cpu_idx, val,
+		MEMERR_CPU_LSUESR_ERRWAY_RD(val),
+		MEMERR_CPU_LSUESR_ERRINDEX_RD(val),
+		MEMERR_CPU_LSUESR_ERRINFO_RD(val));
+	if (val & MEMERR_CPU_LSUESR_CERR_MASK)
+		dev_err(edac_dev->dev, "One or more correctable error\n");
+	if (val & MEMERR_CPU_LSUESR_MULTCERR_MASK)
+		dev_err(edac_dev->dev, "Multiple correctable error\n");
+	switch (MEMERR_CPU_LSUESR_ERRTYPE_RD(val)) {
+	case 0:
+		dev_err(edac_dev->dev, "Load tag error\n");
+		break;
+	case 1:
+		dev_err(edac_dev->dev, "Load data error\n");
+		break;
+	case 2:
+		dev_err(edac_dev->dev, "WSL multihit error\n");
+		break;
+	case 3:
+		dev_err(edac_dev->dev, "Store tag error\n");
+		break;
+	case 4:
 		dev_err(edac_dev->dev,
-			"CPU%d memory error LSU 0x%08X Way 0x%02X Index 0x%02X Info 0x%02X\n",
-			ctx->pmd * MAX_CPU_PER_PMD + cpu_idx, val,
-			MEMERR_CPU_LSUESR_ERRWAY_RD(val),
-			MEMERR_CPU_LSUESR_ERRINDEX_RD(val),
-			MEMERR_CPU_LSUESR_ERRINFO_RD(val));
-		if (val & MEMERR_CPU_LSUESR_CERR_MASK)
-			dev_err(edac_dev->dev,
-				"One or more correctable error\n");
-		if (val & MEMERR_CPU_LSUESR_MULTCERR_MASK)
-			dev_err(edac_dev->dev, "Multiple correctable error\n");
-		switch (MEMERR_CPU_LSUESR_ERRTYPE_RD(val)) {
-		case 0:
-			dev_err(edac_dev->dev, "Load tag error\n");
-			break;
-		case 1:
-			dev_err(edac_dev->dev, "Load data error\n");
-			break;
-		case 2:
-			dev_err(edac_dev->dev, "WSL multihit error\n");
-			break;
-		case 3:
-			dev_err(edac_dev->dev, "Store tag error\n");
-			break;
-		case 4:
-			dev_err(edac_dev->dev,
-				"DTB multihit from load pipeline error\n");
-			break;
-		case 5:
-			dev_err(edac_dev->dev,
-				"DTB multihit from store pipeline error\n");
-			break;
-		}
+			"DTB multihit from load pipeline error\n");
+		break;
+	case 5:
+		dev_err(edac_dev->dev,
+			"DTB multihit from store pipeline error\n");
+		break;
+	}
 
-		/* Clear any HW errors */
-		writel(val, pg_f + MEMERR_CPU_LSUESR_PAGE_OFFSET);
+	/* Clear any HW errors */
+	writel(val, pg_f + MEMERR_CPU_LSUESR_PAGE_OFFSET);
 
-		if (val & (MEMERR_CPU_LSUESR_CERR_MASK |
-			   MEMERR_CPU_LSUESR_MULTCERR_MASK))
-			edac_device_handle_ce(edac_dev, 0, 0,
-					      edac_dev->ctl_name);
-	}
+	if (val & (MEMERR_CPU_LSUESR_CERR_MASK |
+		   MEMERR_CPU_LSUESR_MULTCERR_MASK))
+		edac_device_handle_ce(edac_dev, 0, 0, edac_dev->ctl_name);
 
+chk_mmu:
 	val = readl(pg_f + MEMERR_CPU_MMUESR_PAGE_OFFSET);
-	if (val) {
-		dev_err(edac_dev->dev,
-			"CPU%d memory error MMU 0x%08X Way 0x%02X Index 0x%02X Info 0x%02X %s\n",
-			ctx->pmd * MAX_CPU_PER_PMD + cpu_idx, val,
-			MEMERR_CPU_MMUESR_ERRWAY_RD(val),
-			MEMERR_CPU_MMUESR_ERRINDEX_RD(val),
-			MEMERR_CPU_MMUESR_ERRINFO_RD(val),
-			val & MEMERR_CPU_MMUESR_ERRREQSTR_LSU_MASK ? "LSU" :
-								     "ICF");
-		if (val & MEMERR_CPU_MMUESR_CERR_MASK)
-			dev_err(edac_dev->dev,
-				"One or more correctable error\n");
-		if (val & MEMERR_CPU_MMUESR_MULTCERR_MASK)
-			dev_err(edac_dev->dev, "Multiple correctable error\n");
-		switch (MEMERR_CPU_MMUESR_ERRTYPE_RD(val)) {
-		case 0:
-			dev_err(edac_dev->dev, "Stage 1 UTB hit error\n");
-			break;
-		case 1:
-			dev_err(edac_dev->dev, "Stage 1 UTB miss error\n");
-			break;
-		case 2:
-			dev_err(edac_dev->dev, "Stage 1 UTB allocate error\n");
-			break;
-		case 3:
-			dev_err(edac_dev->dev,
-				"TMO operation single bank error\n");
-			break;
-		case 4:
-			dev_err(edac_dev->dev, "Stage 2 UTB error\n");
-			break;
-		case 5:
-			dev_err(edac_dev->dev, "Stage 2 UTB miss error\n");
-			break;
-		case 6:
-			dev_err(edac_dev->dev, "Stage 2 UTB allocate error\n");
-			break;
-		case 7:
-			dev_err(edac_dev->dev,
-				"TMO operation multiple bank error\n");
-			break;
-		}
+	if (!val)
+		return;
+	dev_err(edac_dev->dev,
+		"CPU%d memory error MMU 0x%08X Way 0x%02X Index 0x%02X Info 0x%02X %s\n",
+		ctx->pmd * MAX_CPU_PER_PMD + cpu_idx, val,
+		MEMERR_CPU_MMUESR_ERRWAY_RD(val),
+		MEMERR_CPU_MMUESR_ERRINDEX_RD(val),
+		MEMERR_CPU_MMUESR_ERRINFO_RD(val),
+		val & MEMERR_CPU_MMUESR_ERRREQSTR_LSU_MASK ? "LSU" : "ICF");
+	if (val & MEMERR_CPU_MMUESR_CERR_MASK)
+		dev_err(edac_dev->dev, "One or more correctable error\n");
+	if (val & MEMERR_CPU_MMUESR_MULTCERR_MASK)
+		dev_err(edac_dev->dev, "Multiple correctable error\n");
+	switch (MEMERR_CPU_MMUESR_ERRTYPE_RD(val)) {
+	case 0:
+		dev_err(edac_dev->dev, "Stage 1 UTB hit error\n");
+		break;
+	case 1:
+		dev_err(edac_dev->dev, "Stage 1 UTB miss error\n");
+		break;
+	case 2:
+		dev_err(edac_dev->dev, "Stage 1 UTB allocate error\n");
+		break;
+	case 3:
+		dev_err(edac_dev->dev, "TMO operation single bank error\n");
+		break;
+	case 4:
+		dev_err(edac_dev->dev, "Stage 2 UTB error\n");
+		break;
+	case 5:
+		dev_err(edac_dev->dev, "Stage 2 UTB miss error\n");
+		break;
+	case 6:
+		dev_err(edac_dev->dev, "Stage 2 UTB allocate error\n");
+		break;
+	case 7:
+		dev_err(edac_dev->dev, "TMO operation multiple bank error\n");
+		break;
+	}
 
-		/* Clear any HW errors */
-		writel(val, pg_f + MEMERR_CPU_MMUESR_PAGE_OFFSET);
+	/* Clear any HW errors */
+	writel(val, pg_f + MEMERR_CPU_MMUESR_PAGE_OFFSET);
 
-		edac_device_handle_ce(edac_dev, 0, 0, edac_dev->ctl_name);
-	}
+	edac_device_handle_ce(edac_dev, 0, 0, edac_dev->ctl_name);
 }
 
 static void xgene_edac_pmd_l2_check(struct edac_device_ctl_info *edac_dev)
@@ -684,60 +680,56 @@ static void xgene_edac_pmd_l2_check(struct edac_device_ctl_info *edac_dev)
 	/* Check L2 */
 	pg_e = ctx->pmd_csr + CPU_MEMERR_L2C_PAGE;
 	val = readl(pg_e + MEMERR_L2C_L2ESR_PAGE_OFFSET);
-	if (val) {
-		val_lo = readl(pg_e + MEMERR_L2C_L2EALR_PAGE_OFFSET);
-		val_hi = readl(pg_e + MEMERR_L2C_L2EAHR_PAGE_OFFSET);
-		dev_err(edac_dev->dev,
-			"PMD%d memory error L2C L2ESR 0x%08X @ 0x%08X.%08X\n",
-			ctx->pmd, val, val_hi, val_lo);
-		dev_err(edac_dev->dev,
-			"ErrSyndrome 0x%02X ErrWay 0x%02X ErrCpu %d ErrGroup 0x%02X ErrAction 0x%02X\n",
-			MEMERR_L2C_L2ESR_ERRSYN_RD(val),
-			MEMERR_L2C_L2ESR_ERRWAY_RD(val),
-			MEMERR_L2C_L2ESR_ERRCPU_RD(val),
-			MEMERR_L2C_L2ESR_ERRGROUP_RD(val),
-			MEMERR_L2C_L2ESR_ERRACTION_RD(val));
-
-		if (val & MEMERR_L2C_L2ESR_ERR_MASK)
-			dev_err(edac_dev->dev,
-				"One or more correctable error\n");
-		if (val & MEMERR_L2C_L2ESR_MULTICERR_MASK)
-			dev_err(edac_dev->dev, "Multiple correctable error\n");
-		if (val & MEMERR_L2C_L2ESR_UCERR_MASK)
-			dev_err(edac_dev->dev,
-				"One or more uncorrectable error\n");
-		if (val & MEMERR_L2C_L2ESR_MULTUCERR_MASK)
-			dev_err(edac_dev->dev,
-				"Multiple uncorrectable error\n");
-
-		switch (MEMERR_L2C_L2ESR_ERRTYPE_RD(val)) {
-		case 0:
-			dev_err(edac_dev->dev, "Outbound SDB parity error\n");
-			break;
-		case 1:
-			dev_err(edac_dev->dev, "Inbound SDB parity error\n");
-			break;
-		case 2:
-			dev_err(edac_dev->dev, "Tag ECC error\n");
-			break;
-		case 3:
-			dev_err(edac_dev->dev, "Data ECC error\n");
-			break;
-		}
+	if (!val)
+		goto chk_l2c;
+	val_lo = readl(pg_e + MEMERR_L2C_L2EALR_PAGE_OFFSET);
+	val_hi = readl(pg_e + MEMERR_L2C_L2EAHR_PAGE_OFFSET);
+	dev_err(edac_dev->dev,
+		"PMD%d memory error L2C L2ESR 0x%08X @ 0x%08X.%08X\n",
+		ctx->pmd, val, val_hi, val_lo);
+	dev_err(edac_dev->dev,
+		"ErrSyndrome 0x%02X ErrWay 0x%02X ErrCpu %d ErrGroup 0x%02X ErrAction 0x%02X\n",
+		MEMERR_L2C_L2ESR_ERRSYN_RD(val),
+		MEMERR_L2C_L2ESR_ERRWAY_RD(val),
+		MEMERR_L2C_L2ESR_ERRCPU_RD(val),
+		MEMERR_L2C_L2ESR_ERRGROUP_RD(val),
+		MEMERR_L2C_L2ESR_ERRACTION_RD(val));
+
+	if (val & MEMERR_L2C_L2ESR_ERR_MASK)
+		dev_err(edac_dev->dev, "One or more correctable error\n");
+	if (val & MEMERR_L2C_L2ESR_MULTICERR_MASK)
+		dev_err(edac_dev->dev, "Multiple correctable error\n");
+	if (val & MEMERR_L2C_L2ESR_UCERR_MASK)
+		dev_err(edac_dev->dev, "One or more uncorrectable error\n");
+	if (val & MEMERR_L2C_L2ESR_MULTUCERR_MASK)
+		dev_err(edac_dev->dev, "Multiple uncorrectable error\n");
+
+	switch (MEMERR_L2C_L2ESR_ERRTYPE_RD(val)) {
+	case 0:
+		dev_err(edac_dev->dev, "Outbound SDB parity error\n");
+		break;
+	case 1:
+		dev_err(edac_dev->dev, "Inbound SDB parity error\n");
+		break;
+	case 2:
+		dev_err(edac_dev->dev, "Tag ECC error\n");
+		break;
+	case 3:
+		dev_err(edac_dev->dev, "Data ECC error\n");
+		break;
+	}
 
-		/* Clear any HW errors */
-		writel(val, pg_e + MEMERR_L2C_L2ESR_PAGE_OFFSET);
+	/* Clear any HW errors */
+	writel(val, pg_e + MEMERR_L2C_L2ESR_PAGE_OFFSET);
 
-		if (val & (MEMERR_L2C_L2ESR_ERR_MASK |
-			   MEMERR_L2C_L2ESR_MULTICERR_MASK))
-			edac_device_handle_ce(edac_dev, 0, 0,
-					      edac_dev->ctl_name);
-		if (val & (MEMERR_L2C_L2ESR_UCERR_MASK |
-			   MEMERR_L2C_L2ESR_MULTUCERR_MASK))
-			edac_device_handle_ue(edac_dev, 0, 0,
-					      edac_dev->ctl_name);
-	}
+	if (val & (MEMERR_L2C_L2ESR_ERR_MASK |
+		   MEMERR_L2C_L2ESR_MULTICERR_MASK))
+		edac_device_handle_ce(edac_dev, 0, 0, edac_dev->ctl_name);
+	if (val & (MEMERR_L2C_L2ESR_UCERR_MASK |
+		   MEMERR_L2C_L2ESR_MULTUCERR_MASK))
+		edac_device_handle_ue(edac_dev, 0, 0, edac_dev->ctl_name);
 
+chk_l2c:
 	/* Check if any memory request timed out on L2 cache */
 	pg_d = ctx->pmd_csr + CPU_L2C_PAGE;
 	val = readl(pg_d + CPUX_L2C_L2RTOSR_PAGE_OFFSET);
@@ -877,26 +869,15 @@ static const struct file_operations xgene_edac_pmd_debug_inject_fops[] = {
 	{ }
 };
 
-static void xgene_edac_pmd_create_debugfs_nodes(
-	struct edac_device_ctl_info *edac_dev)
+static void
+xgene_edac_pmd_create_debugfs_nodes(struct edac_device_ctl_info *edac_dev)
 {
 	struct xgene_edac_pmd_ctx *ctx = edac_dev->pvt_info;
 	struct dentry *edac_debugfs;
 	char name[30];
 
-	if (!IS_ENABLED(CONFIG_EDAC_DEBUG))
+	if (!ctx->edac->dfs)
 		return;
-
-	/*
-	 * Todo: Switch to common EDAC debug file system for edac device
-	 *       when available.
-	 */
-	if (!ctx->edac->dfs) {
-		ctx->edac->dfs = debugfs_create_dir(edac_dev->dev->kobj.name,
-						    NULL);
-		if (!ctx->edac->dfs)
-			return;
-	}
 	sprintf(name, "PMD%d", ctx->pmd);
 	edac_debugfs = debugfs_create_dir(name, ctx->edac->dfs);
 	if (!edac_debugfs)
@@ -1016,10 +997,786 @@ static int xgene_edac_pmd_remove(struct xgene_edac_pmd_ctx *pmd)
 	return 0;
 }
 
+/* L3 Error device */
+#define L3C_ESR				(0x0A * 4)
+#define  L3C_ESR_DATATAG_MASK		BIT(9)
+#define  L3C_ESR_MULTIHIT_MASK		BIT(8)
+#define  L3C_ESR_UCEVICT_MASK		BIT(6)
+#define  L3C_ESR_MULTIUCERR_MASK	BIT(5)
+#define  L3C_ESR_MULTICERR_MASK		BIT(4)
+#define  L3C_ESR_UCERR_MASK		BIT(3)
+#define  L3C_ESR_CERR_MASK		BIT(2)
+#define  L3C_ESR_UCERRINTR_MASK		BIT(1)
+#define  L3C_ESR_CERRINTR_MASK		BIT(0)
+#define L3C_ECR				(0x0B * 4)
+#define  L3C_ECR_UCINTREN		BIT(3)
+#define  L3C_ECR_CINTREN		BIT(2)
+#define  L3C_UCERREN			BIT(1)
+#define  L3C_CERREN			BIT(0)
+#define L3C_ELR				(0x0C * 4)
+#define  L3C_ELR_ERRSYN(src)		((src & 0xFF800000) >> 23)
+#define  L3C_ELR_ERRWAY(src)		((src & 0x007E0000) >> 17)
+#define  L3C_ELR_AGENTID(src)		((src & 0x0001E000) >> 13)
+#define  L3C_ELR_ERRGRP(src)		((src & 0x00000F00) >> 8)
+#define  L3C_ELR_OPTYPE(src)		((src & 0x000000F0) >> 4)
+#define  L3C_ELR_PADDRHIGH(src)		(src & 0x0000000F)
+#define L3C_AELR			(0x0D * 4)
+#define L3C_BELR			(0x0E * 4)
+#define  L3C_BELR_BANK(src)		(src & 0x0000000F)
+
+struct xgene_edac_dev_ctx {
+	struct list_head	next;
+	struct device		ddev;
+	char			*name;
+	struct xgene_edac	*edac;
+	struct edac_device_ctl_info *edac_dev;
+	int			edac_idx;
+	void __iomem		*dev_csr;
+	int			version;
+};
+
+static bool xgene_edac_l3_v1_errata_chk(u32 l3cesr, u32 l3celr)
+{
+	/*
+	 * L3 version 1 has certain conditions in which correctable error
+	 * needs to be flagged as un-correctable error. This function
+	 * check for such conditions.
+	 */
+	if (l3cesr & L3C_ESR_DATATAG_MASK) {
+		switch (L3C_ELR_ERRSYN(l3celr)) {
+		case 0x13C:
+		case 0x0B4:
+		case 0x007:
+		case 0x00D:
+		case 0x00E:
+		case 0x019:
+		case 0x01A:
+		case 0x01C:
+		case 0x04E:
+		case 0x041:
+			return true;
+		}
+	} else if (L3C_ELR_ERRSYN(l3celr) == 9) {
+		return true;
+	}
+
+	return false;
+}
+
+static void xgene_edac_l3_check(struct edac_device_ctl_info *edac_dev)
+{
+	struct xgene_edac_dev_ctx *ctx = edac_dev->pvt_info;
+	u32 l3cesr;
+	u32 l3celr;
+	u32 l3caelr;
+	u32 l3cbelr;
+
+	l3cesr = readl(ctx->dev_csr + L3C_ESR);
+	if (!(l3cesr & (L3C_ESR_UCERR_MASK | L3C_ESR_CERR_MASK)))
+		return;
+
+	if (l3cesr & L3C_ESR_UCERR_MASK)
+		dev_err(edac_dev->dev, "L3C uncorrectable error\n");
+	if (l3cesr & L3C_ESR_CERR_MASK)
+		dev_warn(edac_dev->dev, "L3C correctable error\n");
+
+	l3celr = readl(ctx->dev_csr + L3C_ELR);
+	l3caelr = readl(ctx->dev_csr + L3C_AELR);
+	l3cbelr = readl(ctx->dev_csr + L3C_BELR);
+	if (l3cesr & L3C_ESR_MULTIHIT_MASK)
+		dev_err(edac_dev->dev, "L3C multiple hit error\n");
+	if (l3cesr & L3C_ESR_UCEVICT_MASK)
+		dev_err(edac_dev->dev,
+			"L3C dropped eviction of line with error\n");
+	if (l3cesr & L3C_ESR_MULTIUCERR_MASK)
+		dev_err(edac_dev->dev, "L3C multiple uncorrectable error\n");
+	if (l3cesr & L3C_ESR_DATATAG_MASK)
+		dev_err(edac_dev->dev,
+			"L3C data error syndrome 0x%X group 0x%X\n",
+			L3C_ELR_ERRSYN(l3celr), L3C_ELR_ERRGRP(l3celr));
+	else
+		dev_err(edac_dev->dev,
+			"L3C tag error syndrome 0x%X Way of Tag 0x%X Agent ID 0x%X Operation type 0x%X\n",
+			L3C_ELR_ERRSYN(l3celr), L3C_ELR_ERRWAY(l3celr),
+			L3C_ELR_AGENTID(l3celr), L3C_ELR_OPTYPE(l3celr));
+	/*
+	 * NOTE: Address [41:38] in L3C_ELR_PADDRHIGH(l3celr).
+	 *       Address [37:6] in l3caelr. Lower 6 bits are zero.
+	 */
+	dev_err(edac_dev->dev, "L3C error address 0x%08X.%08X bank %d\n",
+		L3C_ELR_PADDRHIGH(l3celr) << 6 | (l3caelr >> 26),
+		(l3caelr & 0x3FFFFFFF) << 6, L3C_BELR_BANK(l3cbelr));
+	dev_err(edac_dev->dev,
+		"L3C error status register value 0x%X\n", l3cesr);
+
+	/* Clear L3C error interrupt */
+	writel(0, ctx->dev_csr + L3C_ESR);
+
+	if (ctx->version <= 1 &&
+	    xgene_edac_l3_v1_errata_chk(l3cesr, l3celr)) {
+		/*
+		 * Version 1 of the L3C has broken single bit correctable
+		 * logic for certain condition. When such condition is
+		 * detected, map them as uncorrectable.
+		 */
+		edac_device_handle_ue(edac_dev, 0, 0, edac_dev->ctl_name);
+		return;
+	}
+	if (l3cesr & L3C_ESR_CERR_MASK)
+		edac_device_handle_ce(edac_dev, 0, 0, edac_dev->ctl_name);
+	if (l3cesr & L3C_ESR_UCERR_MASK)
+		edac_device_handle_ue(edac_dev, 0, 0, edac_dev->ctl_name);
+}
+
+static void xgene_edac_l3_hw_init(struct edac_device_ctl_info *edac_dev,
+				  bool enable)
+{
+	struct xgene_edac_dev_ctx *ctx = edac_dev->pvt_info;
+	u32 val;
+
+	val = readl(ctx->dev_csr + L3C_ECR);
+	val |= L3C_UCERREN | L3C_CERREN;
+	/* On disable, we just disable interrupt but keep error enabled */
+	if (edac_dev->op_state == OP_RUNNING_INTERRUPT) {
+		if (enable)
+			val |= L3C_ECR_UCINTREN | L3C_ECR_CINTREN;
+		else
+			val &= ~(L3C_ECR_UCINTREN | L3C_ECR_CINTREN);
+	}
+	writel(val, ctx->dev_csr + L3C_ECR);
+
+	if (edac_dev->op_state == OP_RUNNING_INTERRUPT) {
+		/* Enable/disable L3 error top level interrupt */
+		if (enable) {
+			xgene_edac_pcp_clrbits(ctx->edac, PCPHPERRINTMSK,
+					       L3C_UNCORR_ERR_MASK);
+			xgene_edac_pcp_clrbits(ctx->edac, PCPLPERRINTMSK,
+					       L3C_CORR_ERR_MASK);
+		} else {
+			xgene_edac_pcp_setbits(ctx->edac, PCPHPERRINTMSK,
+					       L3C_UNCORR_ERR_MASK);
+			xgene_edac_pcp_setbits(ctx->edac, PCPLPERRINTMSK,
+					       L3C_CORR_ERR_MASK);
+		}
+	}
+}
+
+static ssize_t xgene_edac_l3_inject_ctrl_write(struct file *file,
+					       const char __user *data,
+					       size_t count, loff_t *ppos)
+{
+	struct edac_device_ctl_info *edac_dev = file->private_data;
+	struct xgene_edac_dev_ctx *ctx = edac_dev->pvt_info;
+
+	/* Generate all errors */
+	writel(0xFFFFFFFF, ctx->dev_csr + L3C_ESR);
+	return count;
+}
+
+static const struct file_operations xgene_edac_l3_debug_inject_fops = {
+	.open = simple_open,
+	.write = xgene_edac_l3_inject_ctrl_write,
+	.llseek = generic_file_llseek
+};
+
+static void xgene_edac_l3_create_debugfs_nodes(
+	struct edac_device_ctl_info *edac_dev)
+{
+	struct xgene_edac_dev_ctx *ctx = edac_dev->pvt_info;
+	struct dentry *edac_debugfs;
+	char name[30];
+
+	if (!ctx->edac->dfs)
+		return;
+	sprintf(name, "l3c%d", ctx->edac_idx);
+	edac_debugfs = debugfs_create_dir(name, ctx->edac->dfs);
+	if (!edac_debugfs)
+		return;
+
+	debugfs_create_file("l3_inject_ctrl", S_IWUSR, edac_debugfs, edac_dev,
+			    &xgene_edac_l3_debug_inject_fops);
+}
+
+static int xgene_edac_l3_add(struct xgene_edac *edac, struct device_node *np,
+			     int version)
+{
+	struct edac_device_ctl_info *edac_dev;
+	struct xgene_edac_dev_ctx *ctx;
+	struct resource res;
+	void __iomem *dev_csr;
+	int edac_idx;
+	int rc = 0;
+
+	if (!devres_open_group(edac->dev, xgene_edac_l3_add, GFP_KERNEL))
+		return -ENOMEM;
+
+	rc = of_address_to_resource(np, 0, &res);
+	if (rc < 0) {
+		dev_err(edac->dev, "no L3 resource address\n");
+		goto err_release_group;
+	}
+	dev_csr = devm_ioremap_resource(edac->dev, &res);
+	if (IS_ERR(dev_csr)) {
+		dev_err(edac->dev,
+			"devm_ioremap_resource failed for L3 resource address\n");
+		rc = PTR_ERR(dev_csr);
+		goto err_release_group;
+	}
+
+	edac_idx = edac_device_alloc_index();
+	edac_dev = edac_device_alloc_ctl_info(sizeof(*ctx),
+					      "l3c", 1, "l3c", 1, 0, NULL, 0,
+					      edac_idx);
+	if (!edac_dev) {
+		rc = -ENOMEM;
+		goto err_release_group;
+	}
+
+	ctx = edac_dev->pvt_info;
+	ctx->dev_csr = dev_csr;
+	ctx->name = "xgene_l3_err";
+	ctx->edac_idx = edac_idx;
+	ctx->edac = edac;
+	ctx->edac_dev = edac_dev;
+	ctx->ddev = *edac->dev;
+	ctx->version = version;
+	edac_dev->dev = &ctx->ddev;
+	edac_dev->ctl_name = ctx->name;
+	edac_dev->dev_name = ctx->name;
+	edac_dev->mod_name = EDAC_MOD_STR;
+
+	if (edac_op_state == EDAC_OPSTATE_POLL)
+		edac_dev->edac_check = xgene_edac_l3_check;
+
+	xgene_edac_l3_create_debugfs_nodes(edac_dev);
+
+	rc = edac_device_add_device(edac_dev);
+	if (rc > 0) {
+		dev_err(edac->dev, "failed edac_device_add_device()\n");
+		rc = -ENOMEM;
+		goto err_ctl_free;
+	}
+
+	if (edac_op_state == EDAC_OPSTATE_INT)
+		edac_dev->op_state = OP_RUNNING_INTERRUPT;
+
+	list_add(&ctx->next, &edac->l3s);
+
+	xgene_edac_l3_hw_init(edac_dev, 1);
+
+	devres_remove_group(edac->dev, xgene_edac_l3_add);
+
+	dev_info(edac->dev, "X-Gene EDAC L3 registered\n");
+	return 0;
+
+err_ctl_free:
+	edac_device_free_ctl_info(edac_dev);
+err_release_group:
+	devres_release_group(edac->dev, xgene_edac_l3_add);
+	return rc;
+}
+
+static int xgene_edac_l3_remove(struct xgene_edac_dev_ctx *l3)
+{
+	struct edac_device_ctl_info *edac_dev = l3->edac_dev;
+
+	xgene_edac_l3_hw_init(edac_dev, 0);
+	edac_device_del_device(l3->edac->dev);
+	edac_device_free_ctl_info(edac_dev);
+	return 0;
+}
+
+/* SoC Error device */
+#define IOBAXIS0TRANSERRINTSTS		0x0000
+#define  IOBAXIS0_M_ILLEGAL_ACCESS_MASK	BIT(1)
+#define  IOBAXIS0_ILLEGAL_ACCESS_MASK	BIT(0)
+#define IOBAXIS0TRANSERRINTMSK		0x0004
+#define IOBAXIS0TRANSERRREQINFOL	0x0008
+#define IOBAXIS0TRANSERRREQINFOH	0x000c
+#define  REQTYPE_RD(src)		(((src) & BIT(0)))
+#define  ERRADDRH_RD(src)		(((src) & 0xffc00000) >> 22)
+#define IOBAXIS1TRANSERRINTSTS		0x0010
+#define IOBAXIS1TRANSERRINTMSK		0x0014
+#define IOBAXIS1TRANSERRREQINFOL	0x0018
+#define IOBAXIS1TRANSERRREQINFOH	0x001c
+#define IOBPATRANSERRINTSTS		0x0020
+#define  IOBPA_M_REQIDRAM_CORRUPT_MASK	BIT(7)
+#define  IOBPA_REQIDRAM_CORRUPT_MASK	BIT(6)
+#define  IOBPA_M_TRANS_CORRUPT_MASK	BIT(5)
+#define  IOBPA_TRANS_CORRUPT_MASK	BIT(4)
+#define  IOBPA_M_WDATA_CORRUPT_MASK	BIT(3)
+#define  IOBPA_WDATA_CORRUPT_MASK	BIT(2)
+#define  IOBPA_M_RDATA_CORRUPT_MASK	BIT(1)
+#define  IOBPA_RDATA_CORRUPT_MASK	BIT(0)
+#define IOBBATRANSERRINTSTS		0x0030
+#define  M_ILLEGAL_ACCESS_MASK		BIT(15)
+#define  ILLEGAL_ACCESS_MASK		BIT(14)
+#define  M_WIDRAM_CORRUPT_MASK		BIT(13)
+#define  WIDRAM_CORRUPT_MASK		BIT(12)
+#define  M_RIDRAM_CORRUPT_MASK		BIT(11)
+#define  RIDRAM_CORRUPT_MASK		BIT(10)
+#define  M_TRANS_CORRUPT_MASK		BIT(9)
+#define  TRANS_CORRUPT_MASK		BIT(8)
+#define  M_WDATA_CORRUPT_MASK		BIT(7)
+#define  WDATA_CORRUPT_MASK		BIT(6)
+#define  M_RBM_POISONED_REQ_MASK	BIT(5)
+#define  RBM_POISONED_REQ_MASK		BIT(4)
+#define  M_XGIC_POISONED_REQ_MASK	BIT(3)
+#define  XGIC_POISONED_REQ_MASK		BIT(2)
+#define  M_WRERR_RESP_MASK		BIT(1)
+#define  WRERR_RESP_MASK		BIT(0)
+#define IOBBATRANSERRREQINFOL		0x0038
+#define IOBBATRANSERRREQINFOH		0x003c
+#define  REQTYPE_F2_RD(src)		((src) & BIT(0))
+#define  ERRADDRH_F2_RD(src)		(((src) & 0xffc00000) >> 22)
+#define IOBBATRANSERRCSWREQID		0x0040
+#define XGICTRANSERRINTSTS		0x0050
+#define  M_WR_ACCESS_ERR_MASK		BIT(3)
+#define  WR_ACCESS_ERR_MASK		BIT(2)
+#define  M_RD_ACCESS_ERR_MASK		BIT(1)
+#define  RD_ACCESS_ERR_MASK		BIT(0)
+#define XGICTRANSERRINTMSK		0x0054
+#define XGICTRANSERRREQINFO		0x0058
+#define  REQTYPE_MASK			BIT(26)
+#define  ERRADDR_RD(src)		((src) & 0x03ffffff)
+#define GLBL_ERR_STS			0x0800
+#define  MDED_ERR_MASK			BIT(3)
+#define  DED_ERR_MASK			BIT(2)
+#define  MSEC_ERR_MASK			BIT(1)
+#define  SEC_ERR_MASK			BIT(0)
+#define GLBL_SEC_ERRL			0x0810
+#define GLBL_SEC_ERRH			0x0818
+#define GLBL_MSEC_ERRL			0x0820
+#define GLBL_MSEC_ERRH			0x0828
+#define GLBL_DED_ERRL			0x0830
+#define GLBL_DED_ERRLMASK		0x0834
+#define GLBL_DED_ERRH			0x0838
+#define GLBL_DED_ERRHMASK		0x083c
+#define GLBL_MDED_ERRL			0x0840
+#define GLBL_MDED_ERRLMASK		0x0844
+#define GLBL_MDED_ERRH			0x0848
+#define GLBL_MDED_ERRHMASK		0x084c
+
+static const char * const soc_mem_err_v1[] = {
+	"10GbE0",
+	"10GbE1",
+	"Security",
+	"SATA45",
+	"SATA23/ETH23",
+	"SATA01/ETH01",
+	"USB1",
+	"USB0",
+	"QML",
+	"QM0",
+	"QM1 (XGbE01)",
+	"PCIE4",
+	"PCIE3",
+	"PCIE2",
+	"PCIE1",
+	"PCIE0",
+	"CTX Manager",
+	"OCM",
+	"1GbE",
+	"CLE",
+	"AHBC",
+	"PktDMA",
+	"GFC",
+	"MSLIM",
+	"10GbE2",
+	"10GbE3",
+	"QM2 (XGbE23)",
+	"IOB",
+	"unknown",
+	"unknown",
+	"unknown",
+	"unknown",
+};
+
+static void xgene_edac_iob_gic_report(struct edac_device_ctl_info *edac_dev)
+{
+	struct xgene_edac_dev_ctx *ctx = edac_dev->pvt_info;
+	u32 err_addr_lo;
+	u32 err_addr_hi;
+	u32 reg;
+	u32 info;
+
+	/* GIC transaction error interrupt */
+	reg = readl(ctx->dev_csr + XGICTRANSERRINTSTS);
+	if (!reg)
+		goto chk_iob_err;
+	dev_err(edac_dev->dev, "XGIC transaction error\n");
+	if (reg & RD_ACCESS_ERR_MASK)
+		dev_err(edac_dev->dev, "XGIC read size error\n");
+	if (reg & M_RD_ACCESS_ERR_MASK)
+		dev_err(edac_dev->dev, "Multiple XGIC read size error\n");
+	if (reg & WR_ACCESS_ERR_MASK)
+		dev_err(edac_dev->dev, "XGIC write size error\n");
+	if (reg & M_WR_ACCESS_ERR_MASK)
+		dev_err(edac_dev->dev, "Multiple XGIC write size error\n");
+	info = readl(ctx->dev_csr + XGICTRANSERRREQINFO);
+	dev_err(edac_dev->dev, "XGIC %s access @ 0x%08X (0x%08X)\n",
+		info & REQTYPE_MASK ? "read" : "write", ERRADDR_RD(info),
+		info);
+	writel(reg, ctx->dev_csr + XGICTRANSERRINTSTS);
+
+chk_iob_err:
+	/* IOB memory error */
+	reg = readl(ctx->dev_csr + GLBL_ERR_STS);
+	if (!reg)
+		return;
+	if (reg & SEC_ERR_MASK) {
+		err_addr_lo = readl(ctx->dev_csr + GLBL_SEC_ERRL);
+		err_addr_hi = readl(ctx->dev_csr + GLBL_SEC_ERRH);
+		dev_err(edac_dev->dev,
+			"IOB single-bit correctable memory at 0x%08X.%08X error\n",
+			err_addr_lo, err_addr_hi);
+		writel(err_addr_lo, ctx->dev_csr + GLBL_SEC_ERRL);
+		writel(err_addr_hi, ctx->dev_csr + GLBL_SEC_ERRH);
+	}
+	if (reg & MSEC_ERR_MASK) {
+		err_addr_lo = readl(ctx->dev_csr + GLBL_MSEC_ERRL);
+		err_addr_hi = readl(ctx->dev_csr + GLBL_MSEC_ERRH);
+		dev_err(edac_dev->dev,
+			"IOB multiple single-bit correctable memory at 0x%08X.%08X error\n",
+			err_addr_lo, err_addr_hi);
+		writel(err_addr_lo, ctx->dev_csr + GLBL_MSEC_ERRL);
+		writel(err_addr_hi, ctx->dev_csr + GLBL_MSEC_ERRH);
+	}
+	if (reg & (SEC_ERR_MASK | MSEC_ERR_MASK))
+		edac_device_handle_ce(edac_dev, 0, 0, edac_dev->ctl_name);
+
+	if (reg & DED_ERR_MASK) {
+		err_addr_lo = readl(ctx->dev_csr + GLBL_DED_ERRL);
+		err_addr_hi = readl(ctx->dev_csr + GLBL_DED_ERRH);
+		dev_err(edac_dev->dev,
+			"IOB double-bit uncorrectable memory at 0x%08X.%08X error\n",
+			err_addr_lo, err_addr_hi);
+		writel(err_addr_lo, ctx->dev_csr + GLBL_DED_ERRL);
+		writel(err_addr_hi, ctx->dev_csr + GLBL_DED_ERRH);
+	}
+	if (reg & MDED_ERR_MASK) {
+		err_addr_lo = readl(ctx->dev_csr + GLBL_MDED_ERRL);
+		err_addr_hi = readl(ctx->dev_csr + GLBL_MDED_ERRH);
+		dev_err(edac_dev->dev,
+			"Multiple IOB double-bit uncorrectable memory at 0x%08X.%08X error\n",
+			err_addr_lo, err_addr_hi);
+		writel(err_addr_lo, ctx->dev_csr + GLBL_MDED_ERRL);
+		writel(err_addr_hi, ctx->dev_csr + GLBL_MDED_ERRH);
+	}
+	if (reg & (DED_ERR_MASK | MDED_ERR_MASK))
+		edac_device_handle_ue(edac_dev, 0, 0, edac_dev->ctl_name);
+}
+
+static void xgene_edac_rb_report(struct edac_device_ctl_info *edac_dev)
+{
+	struct xgene_edac_dev_ctx *ctx = edac_dev->pvt_info;
+	u32 err_addr_lo;
+	u32 err_addr_hi;
+	u32 reg;
+
+	/* IOB Bridge agent transaction error interrupt */
+	reg = readl(ctx->dev_csr + IOBBATRANSERRINTSTS);
+	if (!reg)
+		return;
+
+	dev_err(edac_dev->dev, "IOB bridge agent (BA) transaction error\n");
+	if (reg & WRERR_RESP_MASK)
+		dev_err(edac_dev->dev, "IOB BA write response error\n");
+	if (reg & M_WRERR_RESP_MASK)
+		dev_err(edac_dev->dev,
+			"Multiple IOB BA write response error\n");
+	if (reg & XGIC_POISONED_REQ_MASK)
+		dev_err(edac_dev->dev, "IOB BA XGIC poisoned write error\n");
+	if (reg & M_XGIC_POISONED_REQ_MASK)
+		dev_err(edac_dev->dev,
+			"Multiple IOB BA XGIC poisoned write error\n");
+	if (reg & RBM_POISONED_REQ_MASK)
+		dev_err(edac_dev->dev, "IOB BA RBM poisoned write error\n");
+	if (reg & M_RBM_POISONED_REQ_MASK)
+		dev_err(edac_dev->dev,
+			"Multiple IOB BA RBM poisoned write error\n");
+	if (reg & WDATA_CORRUPT_MASK)
+		dev_err(edac_dev->dev, "IOB BA write error\n");
+	if (reg & M_WDATA_CORRUPT_MASK)
+		dev_err(edac_dev->dev, "Multiple IOB BA write error\n");
+	if (reg & TRANS_CORRUPT_MASK)
+		dev_err(edac_dev->dev, "IOB BA transaction error\n");
+	if (reg & M_TRANS_CORRUPT_MASK)
+		dev_err(edac_dev->dev, "Multiple IOB BA transaction error\n");
+	if (reg & RIDRAM_CORRUPT_MASK)
+		dev_err(edac_dev->dev,
+			"IOB BA RDIDRAM read transaction ID error\n");
+	if (reg & M_RIDRAM_CORRUPT_MASK)
+		dev_err(edac_dev->dev,
+			"Multiple IOB BA RDIDRAM read transaction ID error\n");
+	if (reg & WIDRAM_CORRUPT_MASK)
+		dev_err(edac_dev->dev,
+			"IOB BA RDIDRAM write transaction ID error\n");
+	if (reg & M_WIDRAM_CORRUPT_MASK)
+		dev_err(edac_dev->dev,
+			"Multiple IOB BA RDIDRAM write transaction ID error\n");
+	if (reg & ILLEGAL_ACCESS_MASK)
+		dev_err(edac_dev->dev,
+			"IOB BA XGIC/RB illegal access error\n");
+	if (reg & M_ILLEGAL_ACCESS_MASK)
+		dev_err(edac_dev->dev,
+			"Multiple IOB BA XGIC/RB illegal access error\n");
+
+	err_addr_lo = readl(ctx->dev_csr + IOBBATRANSERRREQINFOL);
+	err_addr_hi = readl(ctx->dev_csr + IOBBATRANSERRREQINFOH);
+	dev_err(edac_dev->dev, "IOB BA %s access at 0x%02X.%08X (0x%08X)\n",
+		REQTYPE_F2_RD(err_addr_hi) ? "read" : "write",
+		ERRADDRH_F2_RD(err_addr_hi), err_addr_lo, err_addr_hi);
+	if (reg & WRERR_RESP_MASK)
+		dev_err(edac_dev->dev, "IOB BA requestor ID 0x%08X\n",
+			readl(ctx->dev_csr + IOBBATRANSERRCSWREQID));
+	writel(reg, ctx->dev_csr + IOBBATRANSERRINTSTS);
+}
+
+static void xgene_edac_pa_report(struct edac_device_ctl_info *edac_dev)
+{
+	struct xgene_edac_dev_ctx *ctx = edac_dev->pvt_info;
+	u32 err_addr_lo;
+	u32 err_addr_hi;
+	u32 reg;
+
+	/* IOB Processing agent transaction error interrupt */
+	reg = readl(ctx->dev_csr + IOBPATRANSERRINTSTS);
+	if (!reg)
+		goto chk_iob_axi0;
+	dev_err(edac_dev->dev, "IOB procesing agent (PA) transaction error\n");
+	if (reg & IOBPA_RDATA_CORRUPT_MASK)
+		dev_err(edac_dev->dev, "IOB PA read data RAM error\n");
+	if (reg & IOBPA_M_RDATA_CORRUPT_MASK)
+		dev_err(edac_dev->dev,
+			"Mutilple IOB PA read data RAM error\n");
+	if (reg & IOBPA_WDATA_CORRUPT_MASK)
+		dev_err(edac_dev->dev, "IOB PA write data RAM error\n");
+	if (reg & IOBPA_M_WDATA_CORRUPT_MASK)
+		dev_err(edac_dev->dev,
+			"Mutilple IOB PA write data RAM error\n");
+	if (reg & IOBPA_TRANS_CORRUPT_MASK)
+		dev_err(edac_dev->dev, "IOB PA transaction error\n");
+	if (reg & IOBPA_M_TRANS_CORRUPT_MASK)
+		dev_err(edac_dev->dev, "Mutilple IOB PA transaction error\n");
+	if (reg & IOBPA_REQIDRAM_CORRUPT_MASK)
+		dev_err(edac_dev->dev, "IOB PA transaction ID RAM error\n");
+	if (reg & IOBPA_M_REQIDRAM_CORRUPT_MASK)
+		dev_err(edac_dev->dev,
+			"Multiple IOB PA transaction ID RAM error\n");
+	writel(reg, ctx->dev_csr + IOBPATRANSERRINTSTS);
+
+chk_iob_axi0:
+	/* IOB AXI0 Error */
+	reg = readl(ctx->dev_csr + IOBAXIS0TRANSERRINTSTS);
+	if (!reg)
+		goto chk_iob_axi1;
+	err_addr_lo = readl(ctx->dev_csr + IOBAXIS0TRANSERRREQINFOL);
+	err_addr_hi = readl(ctx->dev_csr + IOBAXIS0TRANSERRREQINFOH);
+	dev_err(edac_dev->dev,
+		"%sAXI slave 0 illegal %s access @ 0x%02X.%08X (0x%08X)\n",
+		reg & IOBAXIS0_M_ILLEGAL_ACCESS_MASK ? "Multiple " : "",
+		REQTYPE_RD(err_addr_hi) ? "read" : "write",
+		ERRADDRH_RD(err_addr_hi), err_addr_lo, err_addr_hi);
+	writel(reg, ctx->dev_csr + IOBAXIS0TRANSERRINTSTS);
+
+chk_iob_axi1:
+	/* IOB AXI1 Error */
+	reg = readl(ctx->dev_csr + IOBAXIS1TRANSERRINTSTS);
+	if (!reg)
+		return;
+	err_addr_lo = readl(ctx->dev_csr + IOBAXIS1TRANSERRREQINFOL);
+	err_addr_hi = readl(ctx->dev_csr + IOBAXIS1TRANSERRREQINFOH);
+	dev_err(edac_dev->dev,
+		"%sAXI slave 1 illegal %s access @ 0x%02X.%08X (0x%08X)\n",
+		reg & IOBAXIS0_M_ILLEGAL_ACCESS_MASK ? "Multiple " : "",
+		REQTYPE_RD(err_addr_hi) ? "read" : "write",
+		ERRADDRH_RD(err_addr_hi), err_addr_lo, err_addr_hi);
+	writel(reg, ctx->dev_csr + IOBAXIS1TRANSERRINTSTS);
+}
+
+static void xgene_edac_soc_check(struct edac_device_ctl_info *edac_dev)
+{
+	struct xgene_edac_dev_ctx *ctx = edac_dev->pvt_info;
+	const char * const *soc_mem_err = NULL;
+	u32 pcp_hp_stat;
+	u32 pcp_lp_stat;
+	u32 reg;
+	int i;
+
+	xgene_edac_pcp_rd(ctx->edac, PCPHPERRINTSTS, &pcp_hp_stat);
+	xgene_edac_pcp_rd(ctx->edac, PCPLPERRINTSTS, &pcp_lp_stat);
+	xgene_edac_pcp_rd(ctx->edac, MEMERRINTSTS, &reg);
+	if (!((pcp_hp_stat & (IOB_PA_ERR_MASK | IOB_BA_ERR_MASK |
+			     IOB_XGIC_ERR_MASK | IOB_RB_ERR_MASK)) ||
+	      (pcp_lp_stat & CSW_SWITCH_TRACE_ERR_MASK) || reg))
+		return;
+
+	if (pcp_hp_stat & IOB_XGIC_ERR_MASK)
+		xgene_edac_iob_gic_report(edac_dev);
+
+	if (pcp_hp_stat & (IOB_RB_ERR_MASK | IOB_BA_ERR_MASK))
+		xgene_edac_rb_report(edac_dev);
+
+	if (pcp_hp_stat & IOB_PA_ERR_MASK)
+		xgene_edac_pa_report(edac_dev);
+
+	if (pcp_lp_stat & CSW_SWITCH_TRACE_ERR_MASK) {
+		dev_info(edac_dev->dev,
+			 "CSW switch trace correctable memory parity error\n");
+		edac_device_handle_ce(edac_dev, 0, 0, edac_dev->ctl_name);
+	}
+
+	if (!reg)
+		return;
+	if (ctx->version == 1)
+		soc_mem_err = soc_mem_err_v1;
+	if (!soc_mem_err) {
+		dev_err(edac_dev->dev, "SoC memory parity error 0x%08X\n",
+			reg);
+		edac_device_handle_ue(edac_dev, 0, 0, edac_dev->ctl_name);
+		return;
+	}
+	for (i = 0; i < 31; i++) {
+		if (reg & (1 << i)) {
+			dev_err(edac_dev->dev, "%s memory parity error\n",
+				soc_mem_err[i]);
+			edac_device_handle_ue(edac_dev, 0, 0,
+					      edac_dev->ctl_name);
+		}
+	}
+}
+
+static void xgene_edac_soc_hw_init(struct edac_device_ctl_info *edac_dev,
+				   bool enable)
+{
+	struct xgene_edac_dev_ctx *ctx = edac_dev->pvt_info;
+
+	/* Enable SoC IP error interrupt */
+	if (edac_dev->op_state == OP_RUNNING_INTERRUPT) {
+		if (enable) {
+			xgene_edac_pcp_clrbits(ctx->edac, PCPHPERRINTMSK,
+					       IOB_PA_ERR_MASK |
+					       IOB_BA_ERR_MASK |
+					       IOB_XGIC_ERR_MASK |
+					       IOB_RB_ERR_MASK);
+			xgene_edac_pcp_clrbits(ctx->edac, PCPLPERRINTMSK,
+					       CSW_SWITCH_TRACE_ERR_MASK);
+		} else {
+			xgene_edac_pcp_setbits(ctx->edac, PCPHPERRINTMSK,
+					       IOB_PA_ERR_MASK |
+					       IOB_BA_ERR_MASK |
+					       IOB_XGIC_ERR_MASK |
+					       IOB_RB_ERR_MASK);
+			xgene_edac_pcp_setbits(ctx->edac, PCPLPERRINTMSK,
+					       CSW_SWITCH_TRACE_ERR_MASK);
+		}
+
+		writel(enable ? 0x0 : 0xFFFFFFFF,
+		       ctx->dev_csr + IOBAXIS0TRANSERRINTMSK);
+		writel(enable ? 0x0 : 0xFFFFFFFF,
+		       ctx->dev_csr + IOBAXIS1TRANSERRINTMSK);
+		writel(enable ? 0x0 : 0xFFFFFFFF,
+		       ctx->dev_csr + XGICTRANSERRINTMSK);
+
+		xgene_edac_pcp_setbits(ctx->edac, MEMERRINTMSK,
+				       enable ? 0x0 : 0xFFFFFFFF);
+	}
+}
+
+static int xgene_edac_soc_add(struct xgene_edac *edac, struct device_node *np,
+			      int version)
+{
+	struct edac_device_ctl_info *edac_dev;
+	struct xgene_edac_dev_ctx *ctx;
+	void __iomem *dev_csr;
+	struct resource res;
+	int edac_idx;
+	int rc = 0;
+
+	if (!devres_open_group(edac->dev, xgene_edac_soc_add, GFP_KERNEL))
+		return -ENOMEM;
+
+	rc = of_address_to_resource(np, 0, &res);
+	if (rc < 0) {
+		dev_err(edac->dev, "no SoC resource address\n");
+		goto err_release_group;
+	}
+	dev_csr = devm_ioremap_resource(edac->dev, &res);
+	if (IS_ERR(dev_csr)) {
+		dev_err(edac->dev,
+			"devm_ioremap_resource failed for soc resource address\n");
+		rc = PTR_ERR(dev_csr);
+		goto err_release_group;
+	}
+
+	edac_idx = edac_device_alloc_index();
+	edac_dev = edac_device_alloc_ctl_info(sizeof(*ctx),
+					      "SOC", 1, "SOC", 1, 2, NULL, 0,
+					      edac_idx);
+	if (!edac_dev) {
+		rc = -ENOMEM;
+		goto err_release_group;
+	}
+
+	ctx = edac_dev->pvt_info;
+	ctx->dev_csr = dev_csr;
+	ctx->name = "xgene_soc_err";
+	ctx->edac_idx = edac_idx;
+	ctx->edac = edac;
+	ctx->edac_dev = edac_dev;
+	ctx->ddev = *edac->dev;
+	ctx->version = version;
+	edac_dev->dev = &ctx->ddev;
+	edac_dev->ctl_name = ctx->name;
+	edac_dev->dev_name = ctx->name;
+	edac_dev->mod_name = EDAC_MOD_STR;
+
+	if (edac_op_state == EDAC_OPSTATE_POLL)
+		edac_dev->edac_check = xgene_edac_soc_check;
+
+	rc = edac_device_add_device(edac_dev);
+	if (rc > 0) {
+		dev_err(edac->dev, "failed edac_device_add_device()\n");
+		rc = -ENOMEM;
+		goto err_ctl_free;
+	}
+
+	if (edac_op_state == EDAC_OPSTATE_INT)
+		edac_dev->op_state = OP_RUNNING_INTERRUPT;
+
+	list_add(&ctx->next, &edac->socs);
+
+	xgene_edac_soc_hw_init(edac_dev, 1);
+
+	devres_remove_group(edac->dev, xgene_edac_soc_add);
+
+	dev_info(edac->dev, "X-Gene EDAC SoC registered\n");
+
+	return 0;
+
+err_ctl_free:
+	edac_device_free_ctl_info(edac_dev);
+err_release_group:
+	devres_release_group(edac->dev, xgene_edac_soc_add);
+	return rc;
+}
+
+static int xgene_edac_soc_remove(struct xgene_edac_dev_ctx *soc)
+{
+	struct edac_device_ctl_info *edac_dev = soc->edac_dev;
+
+	xgene_edac_soc_hw_init(edac_dev, 0);
+	edac_device_del_device(soc->edac->dev);
+	edac_device_free_ctl_info(edac_dev);
+	return 0;
+}
+
 static irqreturn_t xgene_edac_isr(int irq, void *dev_id)
 {
 	struct xgene_edac *ctx = dev_id;
 	struct xgene_edac_pmd_ctx *pmd;
+	struct xgene_edac_dev_ctx *node;
 	unsigned int pcp_hp_stat;
 	unsigned int pcp_lp_stat;
 
@@ -1030,9 +1787,8 @@ static irqreturn_t xgene_edac_isr(int irq, void *dev_id)
 	    (MCU_CORR_ERR_MASK & pcp_lp_stat)) {
 		struct xgene_edac_mc_ctx *mcu;
 
-		list_for_each_entry(mcu, &ctx->mcus, next) {
+		list_for_each_entry(mcu, &ctx->mcus, next)
 			xgene_edac_mc_check(mcu->mci);
-		}
 	}
 
 	list_for_each_entry(pmd, &ctx->pmds, next) {
@@ -1040,6 +1796,12 @@ static irqreturn_t xgene_edac_isr(int irq, void *dev_id)
 			xgene_edac_pmd_check(pmd->edac_dev);
 	}
 
+	list_for_each_entry(node, &ctx->l3s, next)
+		xgene_edac_l3_check(node->edac_dev);
+
+	list_for_each_entry(node, &ctx->socs, next)
+		xgene_edac_soc_check(node->edac_dev);
+
 	return IRQ_HANDLED;
 }
 
@@ -1058,6 +1820,8 @@ static int xgene_edac_probe(struct platform_device *pdev)
 	platform_set_drvdata(pdev, edac);
 	INIT_LIST_HEAD(&edac->mcus);
 	INIT_LIST_HEAD(&edac->pmds);
+	INIT_LIST_HEAD(&edac->l3s);
+	INIT_LIST_HEAD(&edac->socs);
 	spin_lock_init(&edac->lock);
 	mutex_init(&edac->mc_lock);
 
@@ -1122,6 +1886,8 @@ static int xgene_edac_probe(struct platform_device *pdev)
 		}
 	}
 
+	edac->dfs = edac_debugfs;
+
 	for_each_child_of_node(pdev->dev.of_node, child) {
 		if (!of_device_is_available(child))
 			continue;
@@ -1131,6 +1897,14 @@ static int xgene_edac_probe(struct platform_device *pdev)
 			xgene_edac_pmd_add(edac, child, 1);
 		if (of_device_is_compatible(child, "apm,xgene-edac-pmd-v2"))
 			xgene_edac_pmd_add(edac, child, 2);
+		if (of_device_is_compatible(child, "apm,xgene-edac-l3"))
+			xgene_edac_l3_add(edac, child, 1);
+		if (of_device_is_compatible(child, "apm,xgene-edac-l3-v2"))
+			xgene_edac_l3_add(edac, child, 2);
+		if (of_device_is_compatible(child, "apm,xgene-edac-soc"))
+			xgene_edac_soc_add(edac, child, 0);
+		if (of_device_is_compatible(child, "apm,xgene-edac-soc-v1"))
+			xgene_edac_soc_add(edac, child, 1);
 	}
 
 	return 0;
@@ -1146,14 +1920,21 @@ static int xgene_edac_remove(struct platform_device *pdev)
 	struct xgene_edac_mc_ctx *temp_mcu;
 	struct xgene_edac_pmd_ctx *pmd;
 	struct xgene_edac_pmd_ctx *temp_pmd;
+	struct xgene_edac_dev_ctx *node;
+	struct xgene_edac_dev_ctx *temp_node;
 
-	list_for_each_entry_safe(mcu, temp_mcu, &edac->mcus, next) {
+	list_for_each_entry_safe(mcu, temp_mcu, &edac->mcus, next)
 		xgene_edac_mc_remove(mcu);
-	}
 
-	list_for_each_entry_safe(pmd, temp_pmd, &edac->pmds, next) {
+	list_for_each_entry_safe(pmd, temp_pmd, &edac->pmds, next)
 		xgene_edac_pmd_remove(pmd);
-	}
+
+	list_for_each_entry_safe(node, temp_node, &edac->l3s, next)
+		xgene_edac_l3_remove(node);
+
+	list_for_each_entry_safe(node, temp_node, &edac->socs, next)
+		xgene_edac_soc_remove(node);
+
 	return 0;
 }
 
-- 
1.7.1



From lho at apm.com  Thu Aug 13 23:46:09 2015
From: lho at apm.com (Loc Ho)
Date: Fri, 14 Aug 2015 00:46:09 -0600
Subject: [PATCH v4 4/4] arm64: Add L3/SoC DT subnodes to the APM X-Gene SoC
 EDAC node
In-Reply-To: <1439534769-22811-4-git-send-email-lho@apm.com>
References: <1439534769-22811-1-git-send-email-lho@apm.com>
 <1439534769-22811-2-git-send-email-lho@apm.com>
 <1439534769-22811-3-git-send-email-lho@apm.com>
 <1439534769-22811-4-git-send-email-lho@apm.com>
Message-ID: <1439534769-22811-5-git-send-email-lho@apm.com>

This patch adds L3/SoC DT subnodes to the APM X-Gene SoC EDAC node.

Signed-off-by: Loc Ho <lho at apm.com>
---
 arch/arm64/boot/dts/apm/apm-storm.dtsi |   10 ++++++++++
 1 files changed, 10 insertions(+), 0 deletions(-)

diff --git a/arch/arm64/boot/dts/apm/apm-storm.dtsi b/arch/arm64/boot/dts/apm/apm-storm.dtsi
index 58093ed..8ab6b0e 100644
--- a/arch/arm64/boot/dts/apm/apm-storm.dtsi
+++ b/arch/arm64/boot/dts/apm/apm-storm.dtsi
@@ -477,6 +477,16 @@
 				reg = <0x0 0x7c600000 0x0 0x200000>;
 				pmd-controller = <3>;
 			};
+
+			edacl3 at 7e600000 {
+				compatible = "apm,xgene-edac-l3";
+				reg = <0x0 0x7e600000 0x0 0x1000>;
+			};
+
+			edacsoc at 7e930000 {
+				compatible = "apm,xgene-edac-soc-v1";
+				reg = <0x0 0x7e930000 0x0 0x1000>;
+			};
 		};
 
 		pcie0: pcie at 1f2b0000 {
-- 
1.7.1



From geert at linux-m68k.org  Fri Aug 14 00:24:49 2015
From: geert at linux-m68k.org (Geert Uytterhoeven)
Date: Fri, 14 Aug 2015 09:24:49 +0200
Subject: [PATCH 2/9] PM / Domains: Remove dev->driver check for runtime PM
In-Reply-To: <7hwpwylepx.fsf@deeprootsystems.com>
References: <1438731339-58317-1-git-send-email-lina.iyer@linaro.org>
 <1438731339-58317-3-git-send-email-lina.iyer@linaro.org>
 <7hfv3onv5c.fsf@deeprootsystems.com>
 <CAMuHMdVeffa-jgXuSjDQBKTrhgW-d87OKzs1iXX+4y-9U_AJbg@mail.gmail.com>
 <7hwpwylepx.fsf@deeprootsystems.com>
Message-ID: <CAMuHMdW-T9rUWXsQeffwtXspHbjfGqo_0G4QMB1o0TwTLJAQAg@mail.gmail.com>

Hi Kevin,

On Fri, Aug 14, 2015 at 5:40 AM, Kevin Hilman <khilman at kernel.org> wrote:
> Geert Uytterhoeven <geert at linux-m68k.org> writes:
>> On Wed, Aug 12, 2015 at 9:50 PM, Kevin Hilman <khilman at kernel.org> wrote:
>>> This check might have made sense before PM domains, but with PM domains,
>>> it's entirely possible to have a simple device without a driver and the
>>> PM domain handles all the necesary PM, so I think this check
>>> could/should be removed.
>>>
>>> Thoughts?
>>
>> Simple devices without a driver aren't handled automatically.
>> At minimum, the driver should call pm_runtime_enable(), cfr.
>> drivers/bus/simple-pm-bus.c.
>
> That's correct, and in the proof-of-concept stuff I hacked up and in
> Lina's series, the CPU "devices" do indeed to this.  Without that, they
> wouldn't end up ever taking this codepath through genpd's
> runtime_suspend and power_off hooks.
>
> Also, I'm not sure if your comment was meant to be an objection to the
> patch?  or if you're OK with it.

My comment was purely meant as a response to "it's entirely possible to have a
simple device without a driver and the PM domain handles all the necesary PM".

I have no objections to the patch (read: I'm not sufficiently familiar with
the code to make educated guesses about the side effects of this change ;-).

Gr{oetje,eeting}s,

                        Geert

--
Geert Uytterhoeven -- There's lots of Linux beyond ia32 -- geert at linux-m68k.org

In personal conversations with technical people, I call myself a hacker. But
when I'm talking to journalists I just say "programmer" or something like that.
                                -- Linus Torvalds


From jassisinghbrar at gmail.com  Fri Aug 14 00:39:13 2015
From: jassisinghbrar at gmail.com (Jassi Brar)
Date: Fri, 14 Aug 2015 13:09:13 +0530
Subject: [PATCH v2 3/6] mailbox: Add support for ST's Mailbox IP
In-Reply-To: <20150814063343.GI8782@x1>
References: <1437990272-23111-1-git-send-email-lee.jones@linaro.org>
 <1437990272-23111-4-git-send-email-lee.jones@linaro.org>
 <CABb+yY3NTHLx2N-sUABjxQW=MUCntdUg1d8kjvjH0dkb4n9EgA@mail.gmail.com>
 <20150814063343.GI8782@x1>
Message-ID: <CABb+yY07A=jWvDgbPMpDdT=WPhwSzLumMGiJSB4NddTA4z7Hww@mail.gmail.com>

On Fri, Aug 14, 2015 at 12:03 PM, Lee Jones <lee.jones at linaro.org> wrote:
> On Thu, 13 Aug 2015, Jassi Brar wrote:
>> On Mon, Jul 27, 2015 at 3:14 PM, Lee Jones <lee.jones at linaro.org> wrote:
>>
>> > +
>> > +static bool sti_mbox_tx_is_ready(struct mbox_chan *chan)
>> > +{
>> > +       struct sti_channel *chan_info = chan->con_priv;
>> > +       struct sti_mbox_device *mdev = chan_info->mdev;
>> > +       unsigned int instance = chan_info->instance;
>> > +       unsigned int channel = chan_info->channel;
>> > +       void __iomem *base = MBOX_BASE(mdev, instance);
>> > +
>> > +       if (!(chan_info->direction & MBOX_TX))
>> > +               return false;
>> >
>> Here the 'direction' is gotten via DT node of the client i.e, you
>> expect consumer drivers to tell the provider what its limitations are?
>>
>> IMO if some physical channel can't do TX then that should be either
>> hardcoded inside the controller driver or learnt via DT node of the
>> _controller_.
>
> That's a fair point.
.

>  I need to create a new property similar to the
> already existing 'read-only'.  I guess 'tx-only' is equivalent.
>
Just to be clear, if you must have such a property it should come from
the _controller_ node.

However at one point you said,  "Only the A9 (Mbox 0) can Rx."
  Which sounds like the 'simplex' constraint is not coming from the
mailbox controller but from the remote endpoints that don't RX+TX
except for one of them. That makes more sense than a controller with
differently capable physical channels. If that is indeed the
situation, then the controller is actually 'duplex' and there should
be no tx-only/rx-only property anywhere. Everything automatically
falls into place because client drivers are written for specific
targets and, unless you write some code, there can be no TX call to a
remote that doesn't listen.

>> > +
>> > +       for (i = 0; i < mbox->num_chans; i++) {
>> > +               chan_info = mbox->chans[i].con_priv;
>> > +
>> > +               /* Is requested channel free? */
>> > +               if (direction != MBOX_LOOPBACK &&
>> >
>> Consider this example when 2 clients ask for same physical channel but
>> in different modes.
>>            mboxes = <&mboxA 0 1 MBOX_TX>;
>>            mboxes = <&mboxA 0 1 MBOX_LOOPBACK>;
>>
>> You happily assign 2 virtual channels backed by one physical channel
>> {mboxA, 0, 1}. The 2 clients think they can freely do startup(),
>> shutdown() and send_data() on the channels. But obviously we are
>> screwed with races like
>>    client1.startup()
>>     -> client2.startup()
>>         -> client2.send_data()
>>             -> client2.shutdown()
>>                 -> client1.send_data()  XXXX
>
> Good catch and a fair point.  As you say, it's unlikely to happen, but
> I would like to prevent it in any case.
>
No, such races are a practical problem. We must own them.

I was talking about problems that arise because someone wrote bad
DT... those are not 'practical' problems because there are too many
ways to screw up with bad DT properties that if we try to check for
them we'll go insane.

>>  Now you can shove in some more checks to 'fix' the race OR you can
>> simply expose only physical channels.
>
> We can't expose all of the channels.  There are too many and would
> take up too much *unused* memory.
>
I am aware of that. I said expose _only_ physical channels, not _all_ :)

Cheers!


From geert at linux-m68k.org  Fri Aug 14 00:46:41 2015
From: geert at linux-m68k.org (Geert Uytterhoeven)
Date: Fri, 14 Aug 2015 09:46:41 +0200
Subject: [PATCH v2 0/6] ARM: shmobile: Move gpio ranges from C code to DT
In-Reply-To: <20150814003023.GC12589@verge.net.au>
References: <1438696519-13727-1-git-send-email-geert+renesas@glider.be>
 <20150805005540.GB20726@verge.net.au>
 <CACRpkdY7P86+SxMr5-HnhrN5fC-N1U135jiGAJGTV=xx47VW5g@mail.gmail.com>
 <CAMuHMdW0T6MW6s4Gg_rqvtt+MRPtp_MpuiKtamfFrx-Tcm6WmQ@mail.gmail.com>
 <20150814003023.GC12589@verge.net.au>
Message-ID: <CAMuHMdU0XoZ-comYSAau6e3kAY9VUbNgyeRcS_LzmV1gm31ZKA@mail.gmail.com>

On Fri, Aug 14, 2015 at 2:30 AM, Simon Horman <horms at verge.net.au> wrote:
> On Thu, Aug 13, 2015 at 02:45:55PM +0200, Geert Uytterhoeven wrote:
>> On Thu, Aug 13, 2015 at 2:29 PM, Linus Walleij <linus.walleij at linaro.org> wrote:
>> > On Wed, Aug 5, 2015 at 2:55 AM, Simon Horman <horms at verge.net.au> wrote:
>> >> Where possible I prefer not to apply non-DTS/DTSI patches on top of
>> >> DTS/DTSI patches, I believe this is in keeping with how the ARM SoC
>> >> maintainers like things handled.  With this in mind I have done the following:
>> >>
>> >> 1. Queued up the DTSI patches (patches 1 - 3) for v4.3 in my dt branch.
>> >>    I intend for this to turn up in next soon.
>> >> 2. Queued up for pinctrl patches (patches 4 - 6) for v4.4 in a pinctrl patch.
>> >>    I intend for these to be present in the renesas devel branch but
>> >>    not in next until after the release of v4.3-rc1. I would also be
>> >>    happy to drop them and let Linus Walleij take these patches for v4.4,
>> >>    assuming patches 1 - 3 are accepted for v4.3.
>> >
>> > OK.
>> >
>> > Will the world explode if I try to queue the pinctrl patches 4-6 in my
>> > tree now for v4.3? Then I prefer to defer to v4.4. Else I can merge
>> > it in parallel?
>>
>> There won't be a mapping between gpio and pins in any branch having the
>> pinctrl changes but not the dtsi changes.
>
> It sounds to me that Linus should take his option 2; defer to v4.4.
> In which case I should drop the changes from my tree (they are not in next
> anyway). Please let me know if thats the way we will move this forwards.

Sounds fine to me.

And in the unlikely event we discover regressions in v4.3-rc1 due to having
the dtsi changes without the pinctrl changes, we can still fast-track them
into v4.3-rc2.

Gr{oetje,eeting}s,

                        Geert

--
Geert Uytterhoeven -- There's lots of Linux beyond ia32 -- geert at linux-m68k.org

In personal conversations with technical people, I call myself a hacker. But
when I'm talking to journalists I just say "programmer" or something like that.
                                -- Linus Torvalds


From sboyd at codeaurora.org  Fri Aug 14 00:58:59 2015
From: sboyd at codeaurora.org (Stephen Boyd)
Date: Fri, 14 Aug 2015 00:58:59 -0700
Subject: [PATCH] ARM: smp: Collapse arch_cpu_idle_dead() into cpu_die()
Message-ID: <1439539139-8783-1-git-send-email-sboyd@codeaurora.org>

The only caller of cpu_die() on ARM is arch_cpu_idle_dead(), so
let's simplify the code by renaming cpu_die() to
arch_cpu_idle_dead(). While were here, drop the __ref annotation
because __cpuinit is gone nowadays.

Signed-off-by: Stephen Boyd <sboyd at codeaurora.org>
---
 arch/arm/include/asm/smp.h | 1 -
 arch/arm/kernel/process.c  | 7 -------
 arch/arm/kernel/smp.c      | 2 +-
 3 files changed, 1 insertion(+), 9 deletions(-)

diff --git a/arch/arm/include/asm/smp.h b/arch/arm/include/asm/smp.h
index 318ce89eeff7..ef356659b4f4 100644
--- a/arch/arm/include/asm/smp.h
+++ b/arch/arm/include/asm/smp.h
@@ -74,7 +74,6 @@ extern void secondary_startup_arm(void);
 extern int __cpu_disable(void);
 
 extern void __cpu_die(unsigned int cpu);
-extern void cpu_die(void);
 
 extern void arch_send_call_function_single_ipi(int cpu);
 extern void arch_send_call_function_ipi_mask(const struct cpumask *mask);
diff --git a/arch/arm/kernel/process.c b/arch/arm/kernel/process.c
index f192a2a41719..358984b7f249 100644
--- a/arch/arm/kernel/process.c
+++ b/arch/arm/kernel/process.c
@@ -91,13 +91,6 @@ void arch_cpu_idle_exit(void)
 	ledtrig_cpu(CPU_LED_IDLE_END);
 }
 
-#ifdef CONFIG_HOTPLUG_CPU
-void arch_cpu_idle_dead(void)
-{
-	cpu_die();
-}
-#endif
-
 void __show_regs(struct pt_regs *regs)
 {
 	unsigned long flags;
diff --git a/arch/arm/kernel/smp.c b/arch/arm/kernel/smp.c
index 0496b481ad88..48185a773852 100644
--- a/arch/arm/kernel/smp.c
+++ b/arch/arm/kernel/smp.c
@@ -268,7 +268,7 @@ void __cpu_die(unsigned int cpu)
  * of the other hotplug-cpu capable cores, so presumably coming
  * out of idle fixes this.
  */
-void __ref cpu_die(void)
+void arch_cpu_idle_dead(void)
 {
 	unsigned int cpu = smp_processor_id();
 
-- 
The Qualcomm Innovation Center, Inc. is a member of the Code Aurora Forum,
a Linux Foundation Collaborative Project



From marc.zyngier at arm.com  Fri Aug 14 01:28:12 2015
From: marc.zyngier at arm.com (Marc Zyngier)
Date: Fri, 14 Aug 2015 09:28:12 +0100
Subject: [PATCH v2 3/5] irqchip, gicv3: Workaround for Cavium ThunderX
 erratum 23154
In-Reply-To: <20150813171150.GB4914@rric.localhost>
References: <1439477277-6157-1-git-send-email-rric@kernel.org>
 <1439477277-6157-4-git-send-email-rric@kernel.org> <55CCB393.1040909@arm.com>
 <20150813161741.GO1820@rric.localhost> <55CCCBD1.2090304@arm.com>
 <20150813171150.GB4914@rric.localhost>
Message-ID: <55CDA69C.50600@arm.com>

On 13/08/15 18:11, Robert Richter wrote:
> On 13.08.15 17:54:41, Marc Zyngier wrote:
>> On 13/08/15 17:17, Robert Richter wrote:
>>> Marc,
>>>
>>> thanks for your quick review.
>>>
>>> On 13.08.15 16:11:15, Marc Zyngier wrote:
>>>> On 13/08/15 15:47, Robert Richter wrote:
>>>>> From: Robert Richter <rrichter at cavium.com>
>>>
>>>>>  static const struct gic_capabilities gicv3_errata[] = {
>>>>>  	{
>>>>> +		.desc		= "GIC: Cavium erratum 23154",
>>>>> +		.iidr		= 0xa100034c,	/* ThunderX pass 1.x */
>>>>> +		.iidr_mask	= 0xffff0fff,
>>>>> +		.init		= gicv3_enable_cavium_thunderx,
>>>>> +	},
>>>>
>>>> I'm even more puzzled. You're working around a CPU bug based on the ITS
>>>> ID registers? Or have you swapped the detection methods for the two errata?
>>>
>>> :/ Right, I mixed this up... Must have starred on this for too long.
>>> Will fix that.
>>>
>>> Wrt midr: Originally this was written to support iidr. I wanted to
>>> keep the version check in the driver of the hw, an implementation
>>> outside of drivers/irqchip looked not appropriate here as it would
>>> rely then on arch arm64 only. This is the main reason. Apart from
>>> that, I think an implmentation based on struct arm64_cpu_capabilities,
>>> etc. would require much rework compared to my current easy
>>> implementation, e.g:
>>>
>>>  * binding flags to callbacks and actually run them,
>>>
>>>  * handing over private driver data (base addr for iidr detection) to
>>>    a capabilty's match function.
>>>
>>> Overall this looked bloated. Now, that the MIDR also needs to be
>>> checked, it looked better to me to keep the gic hw detection at a
>>> single location in the driver. This also allows us to check a
>>> combination of midr and iidr values.
>>>
>>> I hope this sounds reasonable?
>>
>> +Will.
>>
>> The point I was trying to make is that a CPU interface bug is a CPU bug,
>> and that it feels quite weird weird to have the detection in the GIC.
>> Will, what do you think?
>>
>> Also, I don't really buy the combined MIDR/GITS_IIDR detection. These
>> are two *very* distinct pieces of HW that are not even directly
>> connected (the redistributors are in between).
>>
>> I wouldn't mind having something like:
>>
>> struct gic_capabilities {
>> 	const char *desc;
>> 	void (*init)(void *data);
>> 	u32 iidr;
>> 	u32 iidr_mask;
>> 	int feature;
>> };
> 
> Yes, once we leave this in the driver it is much easier. But why do
> the read_cpuid_id() in cpu_errata.c and not in his file? The
> value/mask pairs will be then on complete different locations for the
> same kind of hw depending on midr/iidr. And the only reason for using
> midr is not, that it's a cpu, but just that it needs to be applied to
> guests too and this is the only way to find out the real hw, otherwise
> we would use iidr. 

But that's the thing! Using GITS_IIDR would be the complete wrong thing
to check for a CPU interface, which is what your ICC_IAR1_EL1 workaround
is about.

> Apart from the fact that this looks inconsistent
> having one errata^Mfeature flag for one errata, but not for the
> other. And only because one is useing midr for hw detection and the
> other iidr.

Because they are architecturally two different things. I strongly
suspect that you could take the ThunderX core, remove Cavium's own
implementation of the GIC and slap another GIC implementation in front
of it, and you would have the exact same CPU interface bug, because
that's where the issue is.

Thanks,

	M.
-- 
Jazz is not dead. It just smells funny...


From maxime.coquelin at st.com  Fri Aug 14 01:34:36 2015
From: maxime.coquelin at st.com (Maxime Coquelin)
Date: Fri, 14 Aug 2015 10:34:36 +0200
Subject: [PATCH] enable HQVDP for stih410 platform
In-Reply-To: <1439305964-15641-1-git-send-email-benjamin.gaignard@linaro.org>
References: <1439305964-15641-1-git-send-email-benjamin.gaignard@linaro.org>
Message-ID: <55CDA81C.6040307@st.com>

Hi Benjamin,

     The title needs to be appended with "ARM: dts:".

     If you agree, I can fix this when applying it.


On 08/11/2015 05:12 PM, Benjamin Gaignard wrote:
> From: Vincent Abriou <vincent.abriou at st.com>
>
> Add HQVDP in stih410 devicetree to enable it.
> HQVDP bindings have been describe in
> Documentation/devicetree/bindings/gpu/st,stih4xx.txt file.
>
> Signed-off-by: Vincent Abriou <vincent.abriou at st.com>
You need also your sign-off here. I will add it too.
> ---
>   arch/arm/boot/dts/stih410.dtsi | 10 ++++++++++
>   1 file changed, 10 insertions(+)
>
>

Regards,
Maxime


From l.stach at pengutronix.de  Fri Aug 14 01:37:30 2015
From: l.stach at pengutronix.de (Lucas Stach)
Date: Fri, 14 Aug 2015 10:37:30 +0200
Subject: [PATCH v3 08/10] Doc: usb: ci-hdrc-usb2: add
 tx(rx)-burst-config-dword for binding doc
In-Reply-To: <1438931747-25209-9-git-send-email-peter.chen@freescale.com>
References: <1438931747-25209-1-git-send-email-peter.chen@freescale.com>
 <1438931747-25209-9-git-send-email-peter.chen@freescale.com>
Message-ID: <1439541450.13210.31.camel@pengutronix.de>

Am Freitag, den 07.08.2015, 15:15 +0800 schrieb Peter Chen:
> It is used to override the default setting for burst size, changing
> burst size takes effect only when the SBUSCFG.AHBBRST = 0.
> 
> Signed-off-by: Peter Chen <peter.chen at freescale.com>
> ---
>  Documentation/devicetree/bindings/usb/ci-hdrc-usb2.txt | 10 ++++++++++
>  1 file changed, 10 insertions(+)
> 
> diff --git a/Documentation/devicetree/bindings/usb/ci-hdrc-usb2.txt b/Documentation/devicetree/bindings/usb/ci-hdrc-usb2.txt
> index d52a747..d71ef07 100644
> --- a/Documentation/devicetree/bindings/usb/ci-hdrc-usb2.txt
> +++ b/Documentation/devicetree/bindings/usb/ci-hdrc-usb2.txt
> @@ -37,6 +37,14 @@ Optional properties:
>    property is used to change AHB burst configuration, check the chipidea
>    spec for meaning of each value. If this property is not existed, it
>    will use the reset value.
> +- tx-burst-size-dword: it is vendor dependent, the tx burst size in dword
> +  (4 bytes), This register represents the maximum length of a the burst
> +  in 32-bit words while moving data from system memory to the USB
> +  bus, changing this value takes effect only the SBUSCFG.AHBBRST is 0.

The last bits about SBUSCFG.AHBBRST don't make any sense in the DT
binding. The DT writer doesn't know about the SBUSCFG.AHBBRST value and
should not care either. If someone sets the burst size to something
non-standard in the DT, the driver should make sure to enable to
necessary bits to make this setting take effect.

Also both those descriptions are missing a description to what value the
burst sizes will be set if the DT properties are not found. If it's
implementation defined spell this out in the doc.

Are there really cases where it makes sense to set RX and TX burst sizes
to different values?

Regards,
Lucas

> +- rx-burst-size-dword: it is vendor dependent, the rx burst size in dword
> +  (4 bytes), This register represents the maximum length of a the burst
> +  in 32-bit words while moving data from the USB bus to system memory,
> +  changing this value takes effect only the SBUSCFG.AHBBRST is 0.
>  
>  Example:
>  
> @@ -51,4 +59,6 @@ Example:
>  		gadget-itc-setting = <0x4>; /* 4 micro-frames */
>  		 /* Incremental burst of unspecified length */
>  		ahb-burst-config = <0x0>;
> +		tx-burst-size-dword = <0x10>; /* 64 bytes */
> +		rx-burst-size-dword = <0x10>;
>  	};

-- 
Pengutronix e.K.             | Lucas Stach                 |
Industrial Linux Solutions   | http://www.pengutronix.de/  |



From shawn.lin at rock-chips.com  Fri Aug 14 01:33:52 2015
From: shawn.lin at rock-chips.com (Shawn Lin)
Date: Fri, 14 Aug 2015 16:33:52 +0800
Subject: [RFC PATCH v5 0/9] Add external dma support for Synopsys MSHC
Message-ID: <1439541232-30100-1-git-send-email-shawn.lin@rock-chips.com>


Synopsys DesignWare mobile storage host controller supports three
types of transfer mode: pio, internal dma and external dma. However,
dw_mmc can only supports pio and internal dma now. Thus some platforms
using dw-mshc integrated with generic dma can't work in dma mode. So we
submit this patch to achieve it.

And the config option, CONFIG_MMC_DW_IDMAC, was added by Will Newton
(commit:f95f3850) for the first version of dw_mmc and never be touched since
then. At that time dt-bindings hadn't been introduced into dw_mmc yet means
we should select CONFIG_MMC_DW_IDMAC to enable internal dma mode at compile
time. Nowadays, device-tree helps us to support a variety of boards with one
kernel. That's why we need to remove it and decide the transfer mode by reading
dw_mmc's HCON reg at runtime.

This RFC patch needs lots of ACKs. I know it's hard, but it does need someone
to make the running.

Patch does the following things:
- remove CONFIG_MMC_DW_IDMAC config option
- add bindings for edmac used by synopsys-dw-mshc
  at runtime
- add edmac support for synopsys-dw-mshc

Patch v1~v4 is based on next of git://git.linaro.org/people/ulf.hansson/mmc
Patch v5 is rebased on dw-mmc-for-ulf-v4.2 of https://github.com/jh80chung/dw-mmc.git


Changes in v5:
- add the title of cover letter
- fix typo of comment
- add macro for reading HCON register
- add "Acked-by: Krzysztof Kozlowski <k.kozlowski at samsung.com>" for exynos_defconfig patch
- add "Acked-by: Vineet Gupta <vgupta at synopsys.com>" for axs10x_defconfig patch
- add "Acked-by: Govindraj Raja <govindraj.raja at imgtec.com>" and
  "Acked-by: Ralf Baechle <ralf at linux-mips.org>" for pistachio_defconfig patch
- add "Acked-by: Joachim Eastwood <manabian at gmail.com>" for lpc18xx_defconfig patch
- add "Acked-by: Wei Xu <xuwei5 at hisilicon.com>" for hisi_defconfig patch
- rebase on "https://github.com/jh80chung/dw-mmc.git tags/dw-mmc-for-ulf-v4.2" for merging easily

Changes in v4:
- remove "host->trans_mode" and use "host->use_dma" to indicate
  transfer mode.
- remove all bt-bindings' changes since we don't need new properities.
- check transfer mode at runtime by reading HCON reg
- spilt defconfig changes for each sub-architecture
- fix the title of cover letter
- reuse some code for reducing code size

Changes in v3:
- choose transfer mode at runtime
- remove all CONFIG_MMC_DW_IDMAC config option
- add supports-idmac property for some platforms

Changes in v2:
- Fix typo of dev_info msg
- remove unused dmach from declaration of dw_mci_dma_slave

Shawn Lin (9):
  mmc: dw_mmc: Add external dma interface support
  Documentation: synopsys-dw-mshc: add bindings for idmac and edmac
  mips: pistachio_defconfig: remove CONFIG_MMC_DW_IDMAC
  arc: axs10x_defconfig: remove CONFIG_MMC_DW_IDMAC
  arm: exynos_defconfig: remove CONFIG_MMC_DW_IDMAC
  arm: hisi_defconfig: remove CONFIG_MMC_DW_IDMAC
  arm: lpc18xx_defconfig: remove CONFIG_MMC_DW_IDMAC
  arm: multi_v7_defconfig: remove CONFIG_MMC_DW_IDMAC
  arm: zx_defconfig: remove CONFIG_MMC_DW_IDMAC

 .../devicetree/bindings/mmc/synopsys-dw-mshc.txt   |  25 +++
 arch/arc/configs/axs101_defconfig                  |   1 -
 arch/arc/configs/axs103_defconfig                  |   1 -
 arch/arc/configs/axs103_smp_defconfig              |   1 -
 arch/arm/configs/exynos_defconfig                  |   1 -
 arch/arm/configs/hisi_defconfig                    |   1 -
 arch/arm/configs/lpc18xx_defconfig                 |   1 -
 arch/arm/configs/multi_v7_defconfig                |   1 -
 arch/arm/configs/zx_defconfig                      |   1 -
 arch/mips/configs/pistachio_defconfig              |   1 -
 drivers/mmc/host/Kconfig                           |  11 +-
 drivers/mmc/host/dw_mmc-pltfm.c                    |   2 +
 drivers/mmc/host/dw_mmc.c                          | 209 ++++++++++++++++++---
 drivers/mmc/host/dw_mmc.h                          |   5 +
 include/linux/mmc/dw_mmc.h                         |  27 ++-
 15 files changed, 235 insertions(+), 53 deletions(-)

-- 
2.3.7




From maoguang.meng at mediatek.com  Fri Aug 14 01:38:06 2015
From: maoguang.meng at mediatek.com (maoguang.meng at mediatek.com)
Date: Fri, 14 Aug 2015 16:38:06 +0800
Subject: [PATCH v4] pinctrl: mediatek: Implement wake handler and suspend
 resume
Message-ID: <1439541486-22203-1-git-send-email-maoguang.meng@mediatek.com>

From: Maoguang Meng <maoguang.meng at mediatek.com>

This patch implement irq_set_wake to get who is wakeup source and
setup on suspend resume.

Signed-off-by: Maoguang Meng <maoguang.meng at mediatek.com>

---
changes since v3:
-add a comment in mtk_eint_chip_read_mask.
-delete ALIGN when allocate eint_offsets.ports.
-fix unrelated change.

changes since v2:
-modify irq_wake to handle irq wakeup source.
-allocate two buffers separately.
-fix some codestyle.

Changes since v1:
-implement irq_wake handler.
---

 drivers/pinctrl/mediatek/pinctrl-mt8173.c     |  1 +
 drivers/pinctrl/mediatek/pinctrl-mtk-common.c | 91 ++++++++++++++++++++++++++-
 drivers/pinctrl/mediatek/pinctrl-mtk-common.h |  4 ++
 3 files changed, 95 insertions(+), 1 deletion(-)

diff --git a/drivers/pinctrl/mediatek/pinctrl-mt8173.c b/drivers/pinctrl/mediatek/pinctrl-mt8173.c
index d0c811d..ad27184 100644
--- a/drivers/pinctrl/mediatek/pinctrl-mt8173.c
+++ b/drivers/pinctrl/mediatek/pinctrl-mt8173.c
@@ -385,6 +385,7 @@ static struct platform_driver mtk_pinctrl_driver = {
 	.driver = {
 		.name = "mediatek-mt8173-pinctrl",
 		.of_match_table = mt8173_pctrl_match,
+		.pm = &mtk_eint_pm_ops,
 	},
 };
 
diff --git a/drivers/pinctrl/mediatek/pinctrl-mtk-common.c b/drivers/pinctrl/mediatek/pinctrl-mtk-common.c
index ad1ea16..fe34ce9 100644
--- a/drivers/pinctrl/mediatek/pinctrl-mtk-common.c
+++ b/drivers/pinctrl/mediatek/pinctrl-mtk-common.c
@@ -33,6 +33,7 @@
 #include <linux/mfd/syscon.h>
 #include <linux/delay.h>
 #include <linux/interrupt.h>
+#include <linux/pm.h>
 #include <dt-bindings/pinctrl/mt65xx.h>
 
 #include "../core.h"
@@ -1062,6 +1063,77 @@ static int mtk_eint_set_type(struct irq_data *d,
 	return 0;
 }
 
+static int mtk_eint_irq_set_wake(struct irq_data *d, unsigned int on)
+{
+	struct mtk_pinctrl *pctl = irq_data_get_irq_chip_data(d);
+	int shift = d->hwirq & 0x1f;
+	int reg = d->hwirq >> 5;
+
+	if (on)
+		pctl->wake_mask[reg] |= BIT(shift);
+	else
+		pctl->wake_mask[reg] &= ~BIT(shift);
+
+	return 0;
+}
+
+static void mtk_eint_chip_write_mask(const struct mtk_eint_offsets *chip,
+		void __iomem *eint_reg_base, u32 *buf)
+{
+	int port;
+	void __iomem *reg;
+
+	for (port = 0; port < chip->ports; port++) {
+		reg = eint_reg_base + (port << 2);
+		writel_relaxed(~buf[port], reg + chip->mask_set);
+		writel_relaxed(buf[port], reg + chip->mask_clr);
+	}
+}
+
+static void mtk_eint_chip_read_mask(const struct mtk_eint_offsets *chip,
+		void __iomem *eint_reg_base, u32 *buf)
+{
+	int port;
+	void __iomem *reg;
+
+	for (port = 0; port < chip->ports; port++) {
+		reg = eint_reg_base + chip->mask + (port << 2);
+		buf[port] = ~readl_relaxed(reg);
+		/* Mask is 0 when irq is enabled, and 1 when disabled. */
+	}
+}
+
+static int mtk_eint_suspend(struct device *device)
+{
+	void __iomem *reg;
+	struct mtk_pinctrl *pctl = dev_get_drvdata(device);
+	const struct mtk_eint_offsets *eint_offsets =
+			&pctl->devdata->eint_offsets;
+
+	reg = pctl->eint_reg_base;
+	mtk_eint_chip_read_mask(eint_offsets, reg, pctl->cur_mask);
+	mtk_eint_chip_write_mask(eint_offsets, reg, pctl->wake_mask);
+
+	return 0;
+}
+
+static int mtk_eint_resume(struct device *device)
+{
+	struct mtk_pinctrl *pctl = dev_get_drvdata(device);
+	const struct mtk_eint_offsets *eint_offsets =
+			&pctl->devdata->eint_offsets;
+
+	mtk_eint_chip_write_mask(eint_offsets,
+			pctl->eint_reg_base, pctl->cur_mask);
+
+	return 0;
+}
+
+const struct dev_pm_ops mtk_eint_pm_ops = {
+	.suspend = mtk_eint_suspend,
+	.resume = mtk_eint_resume,
+};
+
 static void mtk_eint_ack(struct irq_data *d)
 {
 	struct mtk_pinctrl *pctl = irq_data_get_irq_chip_data(d);
@@ -1076,10 +1148,12 @@ static void mtk_eint_ack(struct irq_data *d)
 
 static struct irq_chip mtk_pinctrl_irq_chip = {
 	.name = "mt-eint",
+	.irq_disable = mtk_eint_mask,
 	.irq_mask = mtk_eint_mask,
 	.irq_unmask = mtk_eint_unmask,
 	.irq_ack = mtk_eint_ack,
 	.irq_set_type = mtk_eint_set_type,
+	.irq_set_wake = mtk_eint_irq_set_wake,
 	.irq_request_resources = mtk_pinctrl_irq_request_resources,
 	.irq_release_resources = mtk_pinctrl_irq_release_resources,
 };
@@ -1217,7 +1291,7 @@ int mtk_pctrl_init(struct platform_device *pdev,
 	struct device_node *np = pdev->dev.of_node, *node;
 	struct property *prop;
 	struct resource *res;
-	int i, ret, irq;
+	int i, ret, irq, ports_buf;
 
 	pctl = devm_kzalloc(&pdev->dev, sizeof(*pctl), GFP_KERNEL);
 	if (!pctl)
@@ -1319,6 +1393,21 @@ int mtk_pctrl_init(struct platform_device *pdev,
 		goto chip_error;
 	}
 
+	ports_buf = pctl->devdata->eint_offsets.ports;
+	pctl->wake_mask = devm_kcalloc(&pdev->dev, ports_buf,
+					sizeof(*pctl->wake_mask), GFP_KERNEL);
+	if (!pctl->wake_mask) {
+		ret = -ENOMEM;
+		goto chip_error;
+	}
+
+	pctl->cur_mask = devm_kcalloc(&pdev->dev, ports_buf,
+					sizeof(*pctl->cur_mask), GFP_KERNEL);
+	if (!pctl->cur_mask) {
+		ret = -ENOMEM;
+		goto chip_error;
+	}
+
 	pctl->eint_dual_edges = devm_kcalloc(&pdev->dev, pctl->devdata->ap_num,
 					     sizeof(int), GFP_KERNEL);
 	if (!pctl->eint_dual_edges) {
diff --git a/drivers/pinctrl/mediatek/pinctrl-mtk-common.h b/drivers/pinctrl/mediatek/pinctrl-mtk-common.h
index 30213e5..f1be8e8 100644
--- a/drivers/pinctrl/mediatek/pinctrl-mtk-common.h
+++ b/drivers/pinctrl/mediatek/pinctrl-mtk-common.h
@@ -266,6 +266,8 @@ struct mtk_pinctrl {
 	void __iomem		*eint_reg_base;
 	struct irq_domain	*domain;
 	int			*eint_dual_edges;
+	u32 *wake_mask;
+	u32 *cur_mask;
 };
 
 int mtk_pctrl_init(struct platform_device *pdev,
@@ -281,4 +283,6 @@ int mtk_pconf_spec_set_ies_smt_range(struct regmap *regmap,
 		const struct mtk_pin_ies_smt_set *ies_smt_infos, unsigned int info_num,
 		unsigned int pin, unsigned char align, int value);
 
+extern const struct dev_pm_ops mtk_eint_pm_ops;
+
 #endif /* __PINCTRL_MTK_COMMON_H */
-- 
1.8.1.1.dirty



From shawn.lin at rock-chips.com  Fri Aug 14 01:34:35 2015
From: shawn.lin at rock-chips.com (Shawn Lin)
Date: Fri, 14 Aug 2015 16:34:35 +0800
Subject: [RFC PATCH v5 1/9] mmc: dw_mmc: Add external dma interface support
In-Reply-To: <1439541232-30100-1-git-send-email-shawn.lin@rock-chips.com>
References: <1439541232-30100-1-git-send-email-shawn.lin@rock-chips.com>
Message-ID: <1439541275-30146-1-git-send-email-shawn.lin@rock-chips.com>

DesignWare MMC Controller can supports two types of DMA
mode: external dma and internal dma. We get a RK312x platform
integrated dw_mmc and ARM pl330 dma controller. This patch add
edmac ops to support these platforms. I've tested it on RK312x
platform with edmac mode and RK3288 platform with idmac mode.

Signed-off-by: Shawn Lin <shawn.lin at rock-chips.com>

---

Changes in v5:
- add the title of cover letter
- fix typo of comment
- add macro for reading HCON register
- add "Acked-by: Krzysztof Kozlowski <k.kozlowski at samsung.com>" for exynos_defconfig patch
- add "Acked-by: Vineet Gupta <vgupta at synopsys.com>" for axs10x_defconfig patch
- add "Acked-by: Govindraj Raja <govindraj.raja at imgtec.com>" and
  "Acked-by: Ralf Baechle <ralf at linux-mips.org>" for pistachio_defconfig patch
- add "Acked-by: Joachim Eastwood <manabian at gmail.com>" for lpc18xx_defconfig patch
- add "Acked-by: Wei Xu <xuwei5 at hisilicon.com>" for hisi_defconfig patch
- rebase on "https://github.com/jh80chung/dw-mmc.git tags/dw-mmc-for-ulf-v4.2" for merging easily

Changes in v4:
- remove "host->trans_mode" and use "host->use_dma" to indicate
  transfer mode.
- remove all bt-bindings' changes since we don't need new properities.
- check transfer mode at runtime by reading HCON reg
- spilt defconfig changes for each sub-architecture
- fix the title of cover letter
- reuse some code for reducing code size

Changes in v3:
- choose transfer mode at runtime
- remove all CONFIG_MMC_DW_IDMAC config option
- add supports-idmac property for some platforms

Changes in v2:
- Fix typo of dev_info msg
- remove unused dmach from declaration of dw_mci_dma_slave

 drivers/mmc/host/Kconfig        |  11 +--
 drivers/mmc/host/dw_mmc-pltfm.c |   2 +
 drivers/mmc/host/dw_mmc.c       | 209 ++++++++++++++++++++++++++++++++++------
 drivers/mmc/host/dw_mmc.h       |   5 +
 include/linux/mmc/dw_mmc.h      |  27 +++++-
 5 files changed, 210 insertions(+), 44 deletions(-)

diff --git a/drivers/mmc/host/Kconfig b/drivers/mmc/host/Kconfig
index 6a0f9c7..a86c0eb 100644
--- a/drivers/mmc/host/Kconfig
+++ b/drivers/mmc/host/Kconfig
@@ -607,15 +607,7 @@ config MMC_DW
 	help
 	  This selects support for the Synopsys DesignWare Mobile Storage IP
 	  block, this provides host support for SD and MMC interfaces, in both
-	  PIO and external DMA modes.
-
-config MMC_DW_IDMAC
-	bool "Internal DMAC interface"
-	depends on MMC_DW
-	help
-	  This selects support for the internal DMAC block within the Synopsys
-	  Designware Mobile Storage IP block. This disables the external DMA
-	  interface.
+	  PIO, internal DMA mode and external DMA modes.
 
 config MMC_DW_PLTFM
 	tristate "Synopsys Designware MCI Support as platform device"
@@ -644,7 +636,6 @@ config MMC_DW_K3
 	tristate "K3 specific extensions for Synopsys DW Memory Card Interface"
 	depends on MMC_DW
 	select MMC_DW_PLTFM
-	select MMC_DW_IDMAC
 	help
 	  This selects support for Hisilicon K3 SoC specific extensions to the
 	  Synopsys DesignWare Memory Card Interface driver. Select this option
diff --git a/drivers/mmc/host/dw_mmc-pltfm.c b/drivers/mmc/host/dw_mmc-pltfm.c
index ec6dbcd..7e1d13b 100644
--- a/drivers/mmc/host/dw_mmc-pltfm.c
+++ b/drivers/mmc/host/dw_mmc-pltfm.c
@@ -59,6 +59,8 @@ int dw_mci_pltfm_register(struct platform_device *pdev,
 	host->pdata = pdev->dev.platform_data;
 
 	regs = platform_get_resource(pdev, IORESOURCE_MEM, 0);
+	/* Get registers' physical base address */
+	host->phy_regs = (void *)(regs->start);
 	host->regs = devm_ioremap_resource(&pdev->dev, regs);
 	if (IS_ERR(host->regs))
 		return PTR_ERR(host->regs);
diff --git a/drivers/mmc/host/dw_mmc.c b/drivers/mmc/host/dw_mmc.c
index fcbf552..e01ead3 100644
--- a/drivers/mmc/host/dw_mmc.c
+++ b/drivers/mmc/host/dw_mmc.c
@@ -56,7 +56,6 @@
 #define DW_MCI_FREQ_MAX	200000000	/* unit: HZ */
 #define DW_MCI_FREQ_MIN	400000		/* unit: HZ */
 
-#ifdef CONFIG_MMC_DW_IDMAC
 #define IDMAC_INT_CLR		(SDMMC_IDMAC_INT_AI | SDMMC_IDMAC_INT_NI | \
 				 SDMMC_IDMAC_INT_CES | SDMMC_IDMAC_INT_DU | \
 				 SDMMC_IDMAC_INT_FBE | SDMMC_IDMAC_INT_RI | \
@@ -102,7 +101,6 @@ struct idmac_desc {
 
 /* Each descriptor can transfer up to 4KB of data in chained mode */
 #define DW_MCI_DESC_DATA_LENGTH	0x1000
-#endif /* CONFIG_MMC_DW_IDMAC */
 
 static bool dw_mci_reset(struct dw_mci *host);
 static bool dw_mci_ctrl_reset(struct dw_mci *host, u32 reset);
@@ -407,7 +405,6 @@ static int dw_mci_get_dma_dir(struct mmc_data *data)
 		return DMA_FROM_DEVICE;
 }
 
-#ifdef CONFIG_MMC_DW_IDMAC
 static void dw_mci_dma_cleanup(struct dw_mci *host)
 {
 	struct mmc_data *data = host->data;
@@ -445,12 +442,21 @@ static void dw_mci_idmac_stop_dma(struct dw_mci *host)
 	mci_writel(host, BMOD, temp);
 }
 
-static void dw_mci_idmac_complete_dma(struct dw_mci *host)
+static void dw_mci_dmac_complete_dma(void *arg)
 {
+	struct dw_mci *host = arg;
 	struct mmc_data *data = host->data;
 
 	dev_vdbg(host->dev, "DMA complete\n");
 
+	if (host->use_dma == TRANS_MODE_EDMAC)
+		if (data && (data->flags & MMC_DATA_READ))
+			/* Invalidate cache after read */
+			dma_sync_sg_for_cpu(mmc_dev(host->cur_slot->mmc),
+					    data->sg,
+					    data->sg_len,
+					    DMA_FROM_DEVICE);
+
 	host->dma_ops->cleanup(host);
 
 	/*
@@ -564,7 +570,7 @@ static void dw_mci_translate_sglist(struct dw_mci *host, struct mmc_data *data,
 	wmb(); /* drain writebuffer */
 }
 
-static void dw_mci_idmac_start_dma(struct dw_mci *host, unsigned int sg_len)
+static int dw_mci_idmac_start_dma(struct dw_mci *host, unsigned int sg_len)
 {
 	u32 temp;
 
@@ -589,6 +595,8 @@ static void dw_mci_idmac_start_dma(struct dw_mci *host, unsigned int sg_len)
 
 	/* Start it running */
 	mci_writel(host, PLDMND, 1);
+
+	return 0;
 }
 
 static int dw_mci_idmac_init(struct dw_mci *host)
@@ -669,10 +677,112 @@ static const struct dw_mci_dma_ops dw_mci_idmac_ops = {
 	.init = dw_mci_idmac_init,
 	.start = dw_mci_idmac_start_dma,
 	.stop = dw_mci_idmac_stop_dma,
-	.complete = dw_mci_idmac_complete_dma,
+	.complete = dw_mci_dmac_complete_dma,
+	.cleanup = dw_mci_dma_cleanup,
+};
+
+static void dw_mci_edmac_stop_dma(struct dw_mci *host)
+{
+	dmaengine_terminate_all(host->dms->ch);
+}
+
+static int dw_mci_edmac_start_dma(struct dw_mci *host,
+					    unsigned int sg_len)
+{
+	struct dma_slave_config cfg;
+	struct dma_async_tx_descriptor *desc = NULL;
+	struct scatterlist *sgl = host->data->sg;
+	const u32 mszs[] = {1, 4, 8, 16, 32, 64, 128, 256};
+	u32 sg_elems = host->data->sg_len;
+	u32 fifoth_val;
+	u32 fifo_offset = host->fifo_reg - host->regs;
+	int ret = 0;
+
+	/* Set external dma config: burst size, burst width */
+	cfg.dst_addr = (dma_addr_t)(host->phy_regs + fifo_offset);
+	cfg.src_addr = cfg.dst_addr;
+	cfg.dst_addr_width = DMA_SLAVE_BUSWIDTH_4_BYTES;
+	cfg.src_addr_width = DMA_SLAVE_BUSWIDTH_4_BYTES;
+
+	/* Match burst msize with external dma config */
+	fifoth_val = mci_readl(host, FIFOTH);
+	cfg.dst_maxburst = mszs[(fifoth_val >> 28) & 0x7];
+	cfg.src_maxburst = cfg.dst_maxburst;
+
+	if (host->data->flags & MMC_DATA_WRITE)
+		cfg.direction = DMA_MEM_TO_DEV;
+	else /* MMC_DATA_READ */
+		cfg.direction = DMA_DEV_TO_MEM;
+
+	ret = dmaengine_slave_config(host->dms->ch, &cfg);
+	if (ret) {
+		dev_err(host->dev, "Failed to config edmac.\n");
+		return -EBUSY;
+	}
+
+	desc = dmaengine_prep_slave_sg(host->dms->ch, sgl,
+				       sg_len, cfg.direction,
+				       DMA_PREP_INTERRUPT | DMA_CTRL_ACK);
+	if (!desc) {
+		dev_err(host->dev, "Can't prepare slave sg.\n");
+		return -EBUSY;
+	}
+
+	/* Set dw_mci_dmac_complete_dma as callback */
+	desc->callback = dw_mci_dmac_complete_dma;
+	desc->callback_param = (void *)host;
+	dmaengine_submit(desc);
+
+	/* Flush cache before write */
+	if (host->data->flags & MMC_DATA_WRITE)
+		dma_sync_sg_for_device(mmc_dev(host->cur_slot->mmc), sgl,
+				       sg_elems, DMA_TO_DEVICE);
+
+	dma_async_issue_pending(host->dms->ch);
+
+	return 0;
+}
+
+static int dw_mci_edmac_init(struct dw_mci *host)
+{
+	/* Request external dma channel */
+	host->dms = kzalloc(sizeof(struct dw_mci_dma_slave), GFP_KERNEL);
+	if (!host->dms)
+		return -ENOMEM;
+
+	host->dms->ch = dma_request_slave_channel(host->dev, "rx-tx");
+	if (!host->dms->ch) {
+		dev_err(host->dev,
+			"Failed to get external DMA channel %d\n",
+			host->dms->ch->chan_id);
+		kfree(host->dms);
+		host->dms = NULL;
+		return -ENXIO;
+	}
+
+	return 0;
+}
+
+static void dw_mci_edmac_exit(struct dw_mci *host)
+{
+	if (host->dms) {
+		if (host->dms->ch) {
+			dma_release_channel(host->dms->ch);
+			host->dms->ch = NULL;
+		}
+		kfree(host->dms);
+		host->dms = NULL;
+	}
+}
+
+static const struct dw_mci_dma_ops dw_mci_edmac_ops = {
+	.init = dw_mci_edmac_init,
+	.exit = dw_mci_edmac_exit,
+	.start = dw_mci_edmac_start_dma,
+	.stop = dw_mci_edmac_stop_dma,
+	.complete = dw_mci_dmac_complete_dma,
 	.cleanup = dw_mci_dma_cleanup,
 };
-#endif /* CONFIG_MMC_DW_IDMAC */
 
 static int dw_mci_pre_dma_transfer(struct dw_mci *host,
 				   struct mmc_data *data,
@@ -752,7 +862,6 @@ static void dw_mci_post_req(struct mmc_host *mmc,
 
 static void dw_mci_adjust_fifoth(struct dw_mci *host, struct mmc_data *data)
 {
-#ifdef CONFIG_MMC_DW_IDMAC
 	unsigned int blksz = data->blksz;
 	const u32 mszs[] = {1, 4, 8, 16, 32, 64, 128, 256};
 	u32 fifo_width = 1 << host->data_shift;
@@ -760,6 +869,10 @@ static void dw_mci_adjust_fifoth(struct dw_mci *host, struct mmc_data *data)
 	u32 msize = 0, rx_wmark = 1, tx_wmark, tx_wmark_invers;
 	int idx = ARRAY_SIZE(mszs) - 1;
 
+	/* pio should ship this scenario */
+	if (!host->use_dma)
+		return;
+
 	tx_wmark = (host->fifo_depth) / 2;
 	tx_wmark_invers = host->fifo_depth - tx_wmark;
 
@@ -788,7 +901,6 @@ static void dw_mci_adjust_fifoth(struct dw_mci *host, struct mmc_data *data)
 done:
 	fifoth_val = SDMMC_SET_FIFOTH(msize, rx_wmark, tx_wmark);
 	mci_writel(host, FIFOTH, fifoth_val);
-#endif
 }
 
 static void dw_mci_ctrl_rd_thld(struct dw_mci *host, struct mmc_data *data)
@@ -875,7 +987,11 @@ static int dw_mci_submit_data_dma(struct dw_mci *host, struct mmc_data *data)
 	mci_writel(host, INTMASK, temp);
 	spin_unlock_irqrestore(&host->irq_lock, irqflags);
 
-	host->dma_ops->start(host, sg_len);
+	if (host->dma_ops->start(host, sg_len)) {
+		/* We can't do DMA */
+		dev_err(host->dev, "%s: failed to start DMA.\n", __func__);
+		return -ENODEV;
+	}
 
 	return 0;
 }
@@ -2343,15 +2459,17 @@ static irqreturn_t dw_mci_interrupt(int irq, void *dev_id)
 
 	}
 
-#ifdef CONFIG_MMC_DW_IDMAC
-	/* Handle DMA interrupts */
+	if (host->use_dma != TRANS_MODE_IDMAC)
+		return IRQ_HANDLED;
+
+	/* Handle IDMA interrupts */
 	if (host->dma_64bit_address == 1) {
 		pending = mci_readl(host, IDSTS64);
 		if (pending & (SDMMC_IDMAC_INT_TI | SDMMC_IDMAC_INT_RI)) {
 			mci_writel(host, IDSTS64, SDMMC_IDMAC_INT_TI |
 							SDMMC_IDMAC_INT_RI);
 			mci_writel(host, IDSTS64, SDMMC_IDMAC_INT_NI);
-			host->dma_ops->complete(host);
+			host->dma_ops->complete((void *)host);
 		}
 	} else {
 		pending = mci_readl(host, IDSTS);
@@ -2359,10 +2477,9 @@ static irqreturn_t dw_mci_interrupt(int irq, void *dev_id)
 			mci_writel(host, IDSTS, SDMMC_IDMAC_INT_TI |
 							SDMMC_IDMAC_INT_RI);
 			mci_writel(host, IDSTS, SDMMC_IDMAC_INT_NI);
-			host->dma_ops->complete(host);
+			host->dma_ops->complete((void *)host);
 		}
 	}
-#endif
 
 	return IRQ_HANDLED;
 }
@@ -2471,13 +2588,21 @@ static int dw_mci_init_slot(struct dw_mci *host, unsigned int id)
 		goto err_host_allocated;
 
 	/* Useful defaults if platform data is unset. */
-	if (host->use_dma) {
+	if (host->use_dma == TRANS_MODE_IDMAC) {
 		mmc->max_segs = host->ring_size;
 		mmc->max_blk_size = 65536;
 		mmc->max_seg_size = 0x1000;
 		mmc->max_req_size = mmc->max_seg_size * host->ring_size;
 		mmc->max_blk_count = mmc->max_req_size / 512;
+	} else if (host->use_dma == TRANS_MODE_EDMAC) {
+			mmc->max_segs = 64;
+			mmc->max_blk_size = 65536;
+			mmc->max_blk_count = 65535;
+			mmc->max_req_size =
+					mmc->max_blk_size * mmc->max_blk_count;
+			mmc->max_seg_size = mmc->max_req_size;
 	} else {
+		/* TRANS_MODE_PIO */
 		mmc->max_segs = 64;
 		mmc->max_blk_size = 65536; /* BLKSIZ is 16 bits */
 		mmc->max_blk_count = 512;
@@ -2517,8 +2642,23 @@ static void dw_mci_cleanup_slot(struct dw_mci_slot *slot, unsigned int id)
 static void dw_mci_init_dma(struct dw_mci *host)
 {
 	int addr_config;
+	int trans_mode;
+	struct device *dev = host->dev;
+	struct device_node *np = dev->of_node;
+
+	/* Check tansfer mode */
+	trans_mode = SDMMC_GET_TRANS_MODE(mci_readl(host, HCON));
+	if (trans_mode == 0) {
+		trans_mode = TRANS_MODE_IDMAC;
+	} else if (trans_mode == 1 || trans_mode == 2) {
+		trans_mode = TRANS_MODE_EDMAC;
+	} else {
+		trans_mode = TRANS_MODE_PIO;
+		goto no_dma;
+	}
+
 	/* Check ADDR_CONFIG bit in HCON to find IDMAC address bus width */
-	addr_config = (mci_readl(host, HCON) >> 27) & 0x01;
+	addr_config = SDMMC_GET_ADDR_CONFIG(mci_readl(host, HCON));
 
 	if (addr_config == 1) {
 		/* host supports IDMAC in 64-bit address mode */
@@ -2542,10 +2682,19 @@ static void dw_mci_init_dma(struct dw_mci *host)
 	}
 
 	/* Determine which DMA interface to use */
-#ifdef CONFIG_MMC_DW_IDMAC
-	host->dma_ops = &dw_mci_idmac_ops;
-	dev_info(host->dev, "Using internal DMA controller.\n");
-#endif
+	if (trans_mode == TRANS_MODE_IDMAC) {
+		host->dma_ops = &dw_mci_idmac_ops;
+		dev_info(host->dev, "Using internal DMA controller.\n");
+	} else {
+		/* TRANS_MODE_EDMAC: check dma bindings again */
+		if ((of_property_count_strings(np, "dma-names") < 0) ||
+		    (!of_find_property(np, "dmas", NULL))) {
+			trans_mode = TRANS_MODE_PIO;
+			goto no_dma;
+		}
+		host->dma_ops = &dw_mci_edmac_ops;
+		dev_info(host->dev, "Using external DMA controller.\n");
+	}
 
 	if (!host->dma_ops)
 		goto no_dma;
@@ -2562,12 +2711,12 @@ static void dw_mci_init_dma(struct dw_mci *host)
 		goto no_dma;
 	}
 
-	host->use_dma = 1;
+	host->use_dma = trans_mode;
 	return;
 
 no_dma:
 	dev_info(host->dev, "Using PIO mode.\n");
-	host->use_dma = 0;
+	host->use_dma = trans_mode;
 }
 
 static bool dw_mci_ctrl_reset(struct dw_mci *host, u32 reset)
@@ -2650,10 +2799,9 @@ static bool dw_mci_reset(struct dw_mci *host)
 		}
 	}
 
-#if IS_ENABLED(CONFIG_MMC_DW_IDMAC)
-	/* It is also recommended that we reset and reprogram idmac */
-	dw_mci_idmac_reset(host);
-#endif
+	if (host->use_dma == TRANS_MODE_IDMAC)
+		/* It is also recommended that we reset and reprogram idmac */
+		dw_mci_idmac_reset(host);
 
 	ret = true;
 
@@ -2890,7 +3038,7 @@ int dw_mci_probe(struct dw_mci *host)
 	 * Get the host data width - this assumes that HCON has been set with
 	 * the correct values.
 	 */
-	i = (mci_readl(host, HCON) >> 7) & 0x7;
+	i = SDMMC_GET_HDATA_WIDTH(mci_readl(host, HCON));
 	if (!i) {
 		host->push_data = dw_mci_push_data16;
 		host->pull_data = dw_mci_pull_data16;
@@ -2972,7 +3120,7 @@ int dw_mci_probe(struct dw_mci *host)
 	if (host->pdata->num_slots)
 		host->num_slots = host->pdata->num_slots;
 	else
-		host->num_slots = ((mci_readl(host, HCON) >> 1) & 0x1F) + 1;
+		host->num_slots = SDMMC_GET_SLOT_NUM(mci_readl(host, HCON));
 
 	/*
 	 * Enable interrupts for command done, data over, data empty,
@@ -3067,6 +3215,9 @@ EXPORT_SYMBOL(dw_mci_remove);
  */
 int dw_mci_suspend(struct dw_mci *host)
 {
+	if (host->use_dma && host->dma_ops->exit)
+		host->dma_ops->exit(host);
+
 	return 0;
 }
 EXPORT_SYMBOL(dw_mci_suspend);
diff --git a/drivers/mmc/host/dw_mmc.h b/drivers/mmc/host/dw_mmc.h
index 8ce4674..c453e94 100644
--- a/drivers/mmc/host/dw_mmc.h
+++ b/drivers/mmc/host/dw_mmc.h
@@ -148,6 +148,11 @@
 #define SDMMC_SET_FIFOTH(m, r, t)	(((m) & 0x7) << 28 | \
 					 ((r) & 0xFFF) << 16 | \
 					 ((t) & 0xFFF))
+/* HCON register defines */
+#define SDMMC_GET_SLOT_NUM(x)		((((x)>>1) & 0x1F) + 1)
+#define SDMMC_GET_HDATA_WIDTH(x)	(((x)>>7) & 0x7)
+#define SDMMC_GET_TRANS_MODE(x)		(((x)>>16) & 0x3)
+#define SDMMC_GET_ADDR_CONFIG(x)	(((x)>>27) & 0x1)
 /* Internal DMAC interrupt defines */
 #define SDMMC_IDMAC_INT_AI		BIT(9)
 #define SDMMC_IDMAC_INT_NI		BIT(8)
diff --git a/include/linux/mmc/dw_mmc.h b/include/linux/mmc/dw_mmc.h
index c846f42..6a2b83c 100644
--- a/include/linux/mmc/dw_mmc.h
+++ b/include/linux/mmc/dw_mmc.h
@@ -16,6 +16,7 @@
 
 #include <linux/scatterlist.h>
 #include <linux/mmc/core.h>
+#include <linux/dmaengine.h>
 
 #define MAX_MCI_SLOTS	2
 
@@ -40,6 +41,17 @@ enum {
 
 struct mmc_data;
 
+enum {
+	TRANS_MODE_PIO = 0,
+	TRANS_MODE_IDMAC,
+	TRANS_MODE_EDMAC
+};
+
+struct dw_mci_dma_slave {
+	struct dma_chan *ch;
+	enum dma_transfer_direction direction;
+};
+
 /**
  * struct dw_mci - MMC controller state shared between all slots
  * @lock: Spinlock protecting the queue and associated data.
@@ -154,11 +166,16 @@ struct dw_mci {
 	dma_addr_t		sg_dma;
 	void			*sg_cpu;
 	const struct dw_mci_dma_ops	*dma_ops;
-#ifdef CONFIG_MMC_DW_IDMAC
+	/* For idmac */
 	unsigned int		ring_size;
-#else
+
+	/* For edmac */
+	struct dw_mci_dma_slave *dms;
+	/* Registers's physical base address */
+	void                    *phy_regs;
+
 	struct dw_mci_dma_data	*dma_data;
-#endif
+
 	u32			cmd_status;
 	u32			data_status;
 	u32			stop_cmdr;
@@ -212,8 +229,8 @@ struct dw_mci {
 struct dw_mci_dma_ops {
 	/* DMA Ops */
 	int (*init)(struct dw_mci *host);
-	void (*start)(struct dw_mci *host, unsigned int sg_len);
-	void (*complete)(struct dw_mci *host);
+	int (*start)(struct dw_mci *host, unsigned int sg_len);
+	void (*complete)(void *host);
 	void (*stop)(struct dw_mci *host);
 	void (*cleanup)(struct dw_mci *host);
 	void (*exit)(struct dw_mci *host);
-- 
2.3.7




From shawn.lin at rock-chips.com  Fri Aug 14 01:34:55 2015
From: shawn.lin at rock-chips.com (Shawn Lin)
Date: Fri, 14 Aug 2015 16:34:55 +0800
Subject: [RFC PATCH v5 2/9] Documentation: synopsys-dw-mshc: add bindings for
 idmac and edmac
In-Reply-To: <1439541232-30100-1-git-send-email-shawn.lin@rock-chips.com>
References: <1439541232-30100-1-git-send-email-shawn.lin@rock-chips.com>
Message-ID: <1439541295-30189-1-git-send-email-shawn.lin@rock-chips.com>

synopsys-dw-mshc supports three types of transfer mode. We add
bindings and description for how to use them at runtime.

Signed-off-by: Shawn Lin <shawn.lin at rock-chips.com>
---

Changes in v5: None
Changes in v4: None
Changes in v3: None
Changes in v2: None

 .../devicetree/bindings/mmc/synopsys-dw-mshc.txt   | 25 ++++++++++++++++++++++
 1 file changed, 25 insertions(+)

diff --git a/Documentation/devicetree/bindings/mmc/synopsys-dw-mshc.txt b/Documentation/devicetree/bindings/mmc/synopsys-dw-mshc.txt
index 346c609..8636f5a 100644
--- a/Documentation/devicetree/bindings/mmc/synopsys-dw-mshc.txt
+++ b/Documentation/devicetree/bindings/mmc/synopsys-dw-mshc.txt
@@ -75,6 +75,12 @@ Optional properties:
 * vmmc-supply: The phandle to the regulator to use for vmmc.  If this is
   specified we'll defer probe until we can find this regulator.
 
+* dmas: List of DMA specifiers with the controller specific format as described
+  in the generic DMA client binding. Refer to dma.txt for details.
+
+* dma-names: request names for generic DMA client binding. Must be "rx-tx".
+  Refer to dma.txt for details.
+
 Aliases:
 
 - All the MSHC controller nodes should be represented in the aliases node using
@@ -95,6 +101,23 @@ board specific portions as listed below.
 		#size-cells = <0>;
 	};
 
+[board specific internal DMA resources]
+
+	dwmmc0 at 12200000 {
+		clock-frequency = <400000000>;
+		clock-freq-min-max = <400000 200000000>;
+		num-slots = <1>;
+		broken-cd;
+		fifo-depth = <0x80>;
+		card-detect-delay = <200>;
+		vmmc-supply = <&buck8>;
+		bus-width = <8>;
+		cap-mmc-highspeed;
+		cap-sd-highspeed;
+	};
+
+[board specific generic DMA request binding]
+
 	dwmmc0 at 12200000 {
 		clock-frequency = <400000000>;
 		clock-freq-min-max = <400000 200000000>;
@@ -106,4 +129,6 @@ board specific portions as listed below.
 		bus-width = <8>;
 		cap-mmc-highspeed;
 		cap-sd-highspeed;
+		dmas = <&pdma 12>;
+		dma-names = "rx-tx";
 	};
-- 
2.3.7




From shawn.lin at rock-chips.com  Fri Aug 14 01:35:12 2015
From: shawn.lin at rock-chips.com (Shawn Lin)
Date: Fri, 14 Aug 2015 16:35:12 +0800
Subject: [RFC PATCH v5 3/9] mips: pistachio_defconfig: remove
 CONFIG_MMC_DW_IDMAC
In-Reply-To: <1439541232-30100-1-git-send-email-shawn.lin@rock-chips.com>
References: <1439541232-30100-1-git-send-email-shawn.lin@rock-chips.com>
Message-ID: <1439541312-30230-1-git-send-email-shawn.lin@rock-chips.com>

DesignWare MMC Controller's transfer mode should be decided
at runtime instead of compile-time. So we remove this config
option and read dw_mmc's register to select DMA master.

Signed-off-by: Shawn Lin <shawn.lin at rock-chips.com>
Acked-by: Govindraj Raja <govindraj.raja at imgtec.com>
Acked-by: Ralf Baechle <ralf at linux-mips.org>
---

Changes in v5: None
Changes in v4: None
Changes in v3: None
Changes in v2: None

 arch/mips/configs/pistachio_defconfig | 1 -
 1 file changed, 1 deletion(-)

diff --git a/arch/mips/configs/pistachio_defconfig b/arch/mips/configs/pistachio_defconfig
index 1646cce..013c62c 100644
--- a/arch/mips/configs/pistachio_defconfig
+++ b/arch/mips/configs/pistachio_defconfig
@@ -257,7 +257,6 @@ CONFIG_MMC=y
 CONFIG_MMC_BLOCK_MINORS=16
 CONFIG_MMC_TEST=m
 CONFIG_MMC_DW=y
-CONFIG_MMC_DW_IDMAC=y
 CONFIG_NEW_LEDS=y
 CONFIG_LEDS_CLASS=y
 CONFIG_RTC_CLASS=y
-- 
2.3.7




From shawn.lin at rock-chips.com  Fri Aug 14 01:35:28 2015
From: shawn.lin at rock-chips.com (Shawn Lin)
Date: Fri, 14 Aug 2015 16:35:28 +0800
Subject: [RFC PATCH v5 4/9] arc: axs10x_defconfig: remove CONFIG_MMC_DW_IDMAC
In-Reply-To: <1439541232-30100-1-git-send-email-shawn.lin@rock-chips.com>
References: <1439541232-30100-1-git-send-email-shawn.lin@rock-chips.com>
Message-ID: <1439541328-30271-1-git-send-email-shawn.lin@rock-chips.com>

DesignWare MMC Controller's transfer mode should be decided
at runtime instead of compile-time. So we remove this config
option and read dw_mmc's register to select DMA master.

Signed-off-by: Shawn Lin <shawn.lin at rock-chips.com>
Acked-by: Vineet Gupta <vgupta at synopsys.com>
---

Changes in v5: None
Changes in v4: None
Changes in v3: None
Changes in v2: None

 arch/arc/configs/axs101_defconfig     | 1 -
 arch/arc/configs/axs103_defconfig     | 1 -
 arch/arc/configs/axs103_smp_defconfig | 1 -
 3 files changed, 3 deletions(-)

diff --git a/arch/arc/configs/axs101_defconfig b/arch/arc/configs/axs101_defconfig
index 562dac6..c92c0ef 100644
--- a/arch/arc/configs/axs101_defconfig
+++ b/arch/arc/configs/axs101_defconfig
@@ -89,7 +89,6 @@ CONFIG_MMC=y
 CONFIG_MMC_SDHCI=y
 CONFIG_MMC_SDHCI_PLTFM=y
 CONFIG_MMC_DW=y
-CONFIG_MMC_DW_IDMAC=y
 # CONFIG_IOMMU_SUPPORT is not set
 CONFIG_EXT3_FS=y
 CONFIG_EXT4_FS=y
diff --git a/arch/arc/configs/axs103_defconfig b/arch/arc/configs/axs103_defconfig
index 83a6d8d..cfac24e 100644
--- a/arch/arc/configs/axs103_defconfig
+++ b/arch/arc/configs/axs103_defconfig
@@ -95,7 +95,6 @@ CONFIG_MMC=y
 CONFIG_MMC_SDHCI=y
 CONFIG_MMC_SDHCI_PLTFM=y
 CONFIG_MMC_DW=y
-CONFIG_MMC_DW_IDMAC=y
 # CONFIG_IOMMU_SUPPORT is not set
 CONFIG_EXT3_FS=y
 CONFIG_EXT4_FS=y
diff --git a/arch/arc/configs/axs103_smp_defconfig b/arch/arc/configs/axs103_smp_defconfig
index f1e1c84..9922a11 100644
--- a/arch/arc/configs/axs103_smp_defconfig
+++ b/arch/arc/configs/axs103_smp_defconfig
@@ -96,7 +96,6 @@ CONFIG_MMC=y
 CONFIG_MMC_SDHCI=y
 CONFIG_MMC_SDHCI_PLTFM=y
 CONFIG_MMC_DW=y
-CONFIG_MMC_DW_IDMAC=y
 # CONFIG_IOMMU_SUPPORT is not set
 CONFIG_EXT3_FS=y
 CONFIG_EXT4_FS=y
-- 
2.3.7




From shawn.lin at rock-chips.com  Fri Aug 14 01:35:44 2015
From: shawn.lin at rock-chips.com (Shawn Lin)
Date: Fri, 14 Aug 2015 16:35:44 +0800
Subject: [RFC PATCH v5 5/9] arm: exynos_defconfig: remove CONFIG_MMC_DW_IDMAC
In-Reply-To: <1439541232-30100-1-git-send-email-shawn.lin@rock-chips.com>
References: <1439541232-30100-1-git-send-email-shawn.lin@rock-chips.com>
Message-ID: <1439541344-30312-1-git-send-email-shawn.lin@rock-chips.com>

DesignWare MMC Controller's transfer mode should be decided
at runtime instead of compile-time. So we remove this config
option and read dw_mmc's register to select DMA master.

Signed-off-by: Shawn Lin <shawn.lin at rock-chips.com>
Acked-by: Krzysztof Kozlowski <k.kozlowski at samsung.com>
---

Changes in v5: None
Changes in v4: None
Changes in v3: None
Changes in v2: None

 arch/arm/configs/exynos_defconfig | 1 -
 1 file changed, 1 deletion(-)

diff --git a/arch/arm/configs/exynos_defconfig b/arch/arm/configs/exynos_defconfig
index 9504e77..7e4af6e 100644
--- a/arch/arm/configs/exynos_defconfig
+++ b/arch/arm/configs/exynos_defconfig
@@ -161,7 +161,6 @@ CONFIG_MMC_SDHCI=y
 CONFIG_MMC_SDHCI_S3C=y
 CONFIG_MMC_SDHCI_S3C_DMA=y
 CONFIG_MMC_DW=y
-CONFIG_MMC_DW_IDMAC=y
 CONFIG_MMC_DW_EXYNOS=y
 CONFIG_RTC_CLASS=y
 CONFIG_RTC_DRV_MAX77686=y
-- 
2.3.7




From shawn.lin at rock-chips.com  Fri Aug 14 01:35:59 2015
From: shawn.lin at rock-chips.com (Shawn Lin)
Date: Fri, 14 Aug 2015 16:35:59 +0800
Subject: [RFC PATCH v5 6/9] arm: hisi_defconfig: remove CONFIG_MMC_DW_IDMAC
In-Reply-To: <1439541232-30100-1-git-send-email-shawn.lin@rock-chips.com>
References: <1439541232-30100-1-git-send-email-shawn.lin@rock-chips.com>
Message-ID: <1439541359-30353-1-git-send-email-shawn.lin@rock-chips.com>

DesignWare MMC Controller's transfer mode should be decided
at runtime instead of compile-time. So we remove this config
option and read dw_mmc's register to select DMA master.

Signed-off-by: Shawn Lin <shawn.lin at rock-chips.com>
Acked-by: Wei Xu <xuwei5 at hisilicon.com>
---

Changes in v5: None
Changes in v4: None
Changes in v3: None
Changes in v2: None

 arch/arm/configs/hisi_defconfig | 1 -
 1 file changed, 1 deletion(-)

diff --git a/arch/arm/configs/hisi_defconfig b/arch/arm/configs/hisi_defconfig
index 5997dbc..b2e340b 100644
--- a/arch/arm/configs/hisi_defconfig
+++ b/arch/arm/configs/hisi_defconfig
@@ -69,7 +69,6 @@ CONFIG_NOP_USB_XCEIV=y
 CONFIG_MMC=y
 CONFIG_RTC_CLASS=y
 CONFIG_MMC_DW=y
-CONFIG_MMC_DW_IDMAC=y
 CONFIG_MMC_DW_PLTFM=y
 CONFIG_RTC_DRV_PL031=y
 CONFIG_DMADEVICES=y
-- 
2.3.7




From shawn.lin at rock-chips.com  Fri Aug 14 01:36:11 2015
From: shawn.lin at rock-chips.com (Shawn Lin)
Date: Fri, 14 Aug 2015 16:36:11 +0800
Subject: [RFC PATCH v5 7/9] arm: lpc18xx_defconfig: remove CONFIG_MMC_DW_IDMAC
In-Reply-To: <1439541232-30100-1-git-send-email-shawn.lin@rock-chips.com>
References: <1439541232-30100-1-git-send-email-shawn.lin@rock-chips.com>
Message-ID: <1439541371-30394-1-git-send-email-shawn.lin@rock-chips.com>

DesignWare MMC Controller's transfer mode should be decided
at runtime instead of compile-time. So we remove this config
option and read dw_mmc's register to select DMA master.

Signed-off-by: Shawn Lin <shawn.lin at rock-chips.com>
Acked-by: Joachim Eastwood <manabian at gmail.com>
---

Changes in v5: None
Changes in v4: None
Changes in v3: None
Changes in v2: None

 arch/arm/configs/lpc18xx_defconfig | 1 -
 1 file changed, 1 deletion(-)

diff --git a/arch/arm/configs/lpc18xx_defconfig b/arch/arm/configs/lpc18xx_defconfig
index 1c47f86..b7e8cda 100644
--- a/arch/arm/configs/lpc18xx_defconfig
+++ b/arch/arm/configs/lpc18xx_defconfig
@@ -119,7 +119,6 @@ CONFIG_USB_EHCI_HCD=y
 CONFIG_USB_EHCI_ROOT_HUB_TT=y
 CONFIG_MMC=y
 CONFIG_MMC_DW=y
-CONFIG_MMC_DW_IDMAC=y
 CONFIG_NEW_LEDS=y
 CONFIG_LEDS_CLASS=y
 CONFIG_LEDS_PCA9532=y
-- 
2.3.7




From 21cnbao at gmail.com  Fri Aug 14 01:43:52 2015
From: 21cnbao at gmail.com (Barry Song)
Date: Fri, 14 Aug 2015 16:43:52 +0800
Subject: CLK_IGNORE_UNUSE looks buggy
Message-ID: <CAGsJ_4wxVL9sFWkc9dnZsAA++MfFJ1KXoq481wPLoQ-HaDRFEA@mail.gmail.com>

hi Stephen, Michael,

currently we can set a CLK_IGNORE_UNUSE flag to  a clock to stop
clk_disable_unused()  from disabling it at the boot stage:

static void clk_disable_unused_subtree(struct clk_core *core)
{
...
if (core->flags & CLK_IGNORE_UNUSED)
goto unlock_out;

...
}

static int clk_disable_unused(void)
{
...
clk_unprepare_unused_subtree(core);
...

return 0;
}
late_initcall_sync(clk_disable_unused);

so if there are two clocks A and B, A is the parent of B, and A is
marked as CLK_IGNORE_UNUSED.

in boot stage if there is nobody using A and B, Linux will disable B
due to clk_disable_unused() , but keep A being enabled since A has
CLK_IGNORE_UNUSED.

but in Linux runtime, we might frequently disable /enable B in runtime
power management, this will cause A disabled since Linux will not
check CLK_IGNORE_UNUSED for runtime disabling clk .

so this makes CLK_IGNORE_UNUSE only work if we don't disable its
sub-clock at runtime. this looks making no sense.

i am thinking whether we should do some changes to make it have side
affect for runtime clk disable. otherwise, why do we want to stop it
from being disabled during boot stage?

I am not sure whether i missed something in clk core level support.

-barry


From benjamin.gaignard at linaro.org  Fri Aug 14 01:50:21 2015
From: benjamin.gaignard at linaro.org (Benjamin Gaignard)
Date: Fri, 14 Aug 2015 10:50:21 +0200
Subject: [PATCH] enable HQVDP for stih410 platform
In-Reply-To: <55CDA81C.6040307@st.com>
References: <1439305964-15641-1-git-send-email-benjamin.gaignard@linaro.org>
 <55CDA81C.6040307@st.com>
Message-ID: <CA+M3ks4PGmyS6ZdrYy708VhvC6f4wNye-i1fMm1oxRDD5mEckw@mail.gmail.com>

It is fine for me,

Thanks,
Benjamin

2015-08-14 10:34 GMT+02:00 Maxime Coquelin <maxime.coquelin at st.com>:
> Hi Benjamin,
>
>     The title needs to be appended with "ARM: dts:".
>
>     If you agree, I can fix this when applying it.
>
>
> On 08/11/2015 05:12 PM, Benjamin Gaignard wrote:
>>
>> From: Vincent Abriou <vincent.abriou at st.com>
>>
>> Add HQVDP in stih410 devicetree to enable it.
>> HQVDP bindings have been describe in
>> Documentation/devicetree/bindings/gpu/st,stih4xx.txt file.
>>
>> Signed-off-by: Vincent Abriou <vincent.abriou at st.com>
>
> You need also your sign-off here. I will add it too.
>>
>> ---
>>   arch/arm/boot/dts/stih410.dtsi | 10 ++++++++++
>>   1 file changed, 10 insertions(+)
>>
>>
>
> Regards,
> Maxime



-- 
Benjamin Gaignard

Graphic Working Group

Linaro.org ? Open source software for ARM SoCs

Follow Linaro: Facebook | Twitter | Blog


From shawn.lin at rock-chips.com  Fri Aug 14 01:36:27 2015
From: shawn.lin at rock-chips.com (Shawn Lin)
Date: Fri, 14 Aug 2015 16:36:27 +0800
Subject: [RFC PATCH v5 8/9] arm: multi_v7_defconfig: remove CONFIG_MMC_DW_IDMAC
In-Reply-To: <1439541232-30100-1-git-send-email-shawn.lin@rock-chips.com>
References: <1439541232-30100-1-git-send-email-shawn.lin@rock-chips.com>
Message-ID: <1439541387-30435-1-git-send-email-shawn.lin@rock-chips.com>

DesignWare MMC Controller's transfer mode should be decided
at runtime instead of compile-time. So we remove this config
option and read dw_mmc's register to select DMA master.

Signed-off-by: Shawn Lin <shawn.lin at rock-chips.com>
---

Changes in v5: None
Changes in v4: None
Changes in v3: None
Changes in v2: None

 arch/arm/configs/multi_v7_defconfig | 1 -
 1 file changed, 1 deletion(-)

diff --git a/arch/arm/configs/multi_v7_defconfig b/arch/arm/configs/multi_v7_defconfig
index 5fd8df6..a3734b5 100644
--- a/arch/arm/configs/multi_v7_defconfig
+++ b/arch/arm/configs/multi_v7_defconfig
@@ -520,7 +520,6 @@ CONFIG_MMC_ATMELMCI=y
 CONFIG_MMC_MVSDIO=y
 CONFIG_MMC_SDHI=y
 CONFIG_MMC_DW=y
-CONFIG_MMC_DW_IDMAC=y
 CONFIG_MMC_DW_PLTFM=y
 CONFIG_MMC_DW_EXYNOS=y
 CONFIG_MMC_DW_ROCKCHIP=y
-- 
2.3.7




From srinivas.kandagatla at linaro.org  Fri Aug 14 02:30:35 2015
From: srinivas.kandagatla at linaro.org (Srinivas Kandagatla)
Date: Fri, 14 Aug 2015 10:30:35 +0100
Subject: [PATCH 0/5] iommu/msm: Add DT adaptation and generic bindings
 support
In-Reply-To: <1439390869-6347-1-git-send-email-sricharan@codeaurora.org>
References: <1439390869-6347-1-git-send-email-sricharan@codeaurora.org>
Message-ID: <55CDB53B.9000605@linaro.org>

Hi Sricharan,

thanks for the patches,

On 12/08/15 15:47, Sricharan R wrote:
> The msm_iommu.c driver currently works based on platform data. A single master
> device can be connected to more than one iommu and multiple contexts in each
> of the iommu. This association between master and iommus was represented
> from platform data using parent/child devices. The master drivers were
> responsible for attaching all of the iommus/context to a domain. Now the
> platform data support is removed and DT support is added. The master/iommus
> are added through generic iommu bindings.
>
> This is essentially rework of the patch posted earlier by
> Rob Clark <robdclark at gmail.com>. This series folds the changes
> in to the existing driver with the addition of generic bindings.
>
>          http://www.spinics.net/lists/linux-arm-msm/msg10077.html
>
> This series is based on the IOMMU probe deferral series from
> Laurent Pinchart <laurent.pinchart at ideasonboard.com>
>
>          https://lkml.org/lkml/2015/5/14/786
>
> Tested this series on ifc6410 board.
>
I tested this series on IFC6410 with both HDMI and LVDS Panel with 
openbox desktop. It works.. :-)

Tested-by: Srinivas Kandagatla <srinivas.kandagatla at linaro.org>

--srini
> Sricharan R (5):
>    iommu/msm: Add DT adaptation
>    iommu/msm: Move the contents from msm_iommu_dev.c to msm_iommu.c
>    iommu/msm: Add support for generic master bindings
>    iommu/msm: Set cacheability attributes without tex remap
>    iommu/msm: Remove driver BROKEN
>
>   .../devicetree/bindings/iommu/msm,iommu-v0.txt     |  59 +++
>   drivers/iommu/Kconfig                              |   1 -
>   drivers/iommu/Makefile                             |   2 +-
>   drivers/iommu/msm_iommu.c                          | 508 ++++++++++++++-------
>   drivers/iommu/msm_iommu.h                          |  73 ++-
>   drivers/iommu/msm_iommu_dev.c                      | 392 ----------------
>   drivers/iommu/msm_iommu_hw-8xxx.h                  |  10 +-
>   7 files changed, 432 insertions(+), 613 deletions(-)
>   create mode 100644 Documentation/devicetree/bindings/iommu/msm,iommu-v0.txt
>   delete mode 100644 drivers/iommu/msm_iommu_dev.c
>


From kgene at kernel.org  Fri Aug 14 02:47:08 2015
From: kgene at kernel.org (Kukjin Kim)
Date: Fri, 14 Aug 2015 18:47:08 +0900
Subject: [PATCH v2 1/3] mfd: documentation: dt: Document grounded ACOKB pin
 on S2MPS11
In-Reply-To: <1439287746-14034-2-git-send-email-k.kozlowski.k@gmail.com>
References: <1439287746-14034-1-git-send-email-k.kozlowski.k@gmail.com>
 <1439287746-14034-2-git-send-email-k.kozlowski.k@gmail.com>
Message-ID: <02a201d0d676$2fbe73c0$8f3b5b40$@kernel.org>

Krzysztof Kozlowski wrote:
> 
> Document a new Device Tree property 'samsung,s2mps11-acokb-ground'
> indicating that ACOKB pin of S2MPS11 PMIC is connected to the ground so
> the PMIC must manually set PWRHOLD bit in CTRL1 register to turn off the
> power.
> 
> Signed-off-by: Krzysztof Kozlowski <k.kozlowski.k at gmail.com>
> Reviewed-by: Javier Martinez Canillas <javier at osg.samsung.com>
> Acked-by: Lee Jones <lee.jones at linaro.org>
> 
> ---
> 
> Changes since v1:
> 1. Split bindings documentation to separate patch (suggested by Lee).
> 2. Add Javier's reviewed-by and Lee's acked-by.
> ---
>  Documentation/devicetree/bindings/mfd/s2mps11.txt | 4 ++++
>  1 file changed, 4 insertions(+)
> 
> diff --git a/Documentation/devicetree/bindings/mfd/s2mps11.txt
> b/Documentation/devicetree/bindings/mfd/s2mps11.txt
> index 57a045016fca..90eaef393325 100644
> --- a/Documentation/devicetree/bindings/mfd/s2mps11.txt
> +++ b/Documentation/devicetree/bindings/mfd/s2mps11.txt
> @@ -15,6 +15,10 @@ Optional properties:
>  - interrupt-parent: Specifies the phandle of the interrupt controller to which
>    the interrupts from s2mps11 are delivered to.
>  - interrupts: Interrupt specifiers for interrupt sources.
> +- samsung,s2mps11-acokb-ground: Indicates that ACOKB pin of S2MPS11 PMIC is
> +  connected to the ground so the PMIC must manually set PWRHOLD bit in CTRL1
> +  register to turn off the power. Usually the ACOKB is pulled up to VBATT so
> +  when PWRHOLD pin goes low, the rising ACOKB will trigger power off.
> 
>  Optional nodes:
>  - clocks: s2mps11, s2mps13 and s5m8767 provide three(AP/CP/BT) buffered 32.768
> --
> 2.1.4

Applied 1/3 and 3/3.

Thanks,
Kukjin



From peter.chen at freescale.com  Fri Aug 14 01:40:51 2015
From: peter.chen at freescale.com (Peter Chen)
Date: Fri, 14 Aug 2015 16:40:51 +0800
Subject: [PATCH v3 08/10] Doc: usb: ci-hdrc-usb2: add
 tx(rx)-burst-config-dword for binding doc
In-Reply-To: <1439541450.13210.31.camel@pengutronix.de>
References: <1438931747-25209-1-git-send-email-peter.chen@freescale.com>
 <1438931747-25209-9-git-send-email-peter.chen@freescale.com>
 <1439541450.13210.31.camel@pengutronix.de>
Message-ID: <20150814084050.GE11072@shlinux2>

On Fri, Aug 14, 2015 at 10:37:30AM +0200, Lucas Stach wrote:
> Am Freitag, den 07.08.2015, 15:15 +0800 schrieb Peter Chen:
> > It is used to override the default setting for burst size, changing
> > burst size takes effect only when the SBUSCFG.AHBBRST = 0.
> > 
> > Signed-off-by: Peter Chen <peter.chen at freescale.com>
> > ---
> >  Documentation/devicetree/bindings/usb/ci-hdrc-usb2.txt | 10 ++++++++++
> >  1 file changed, 10 insertions(+)
> > 
> > diff --git a/Documentation/devicetree/bindings/usb/ci-hdrc-usb2.txt b/Documentation/devicetree/bindings/usb/ci-hdrc-usb2.txt
> > index d52a747..d71ef07 100644
> > --- a/Documentation/devicetree/bindings/usb/ci-hdrc-usb2.txt
> > +++ b/Documentation/devicetree/bindings/usb/ci-hdrc-usb2.txt
> > @@ -37,6 +37,14 @@ Optional properties:
> >    property is used to change AHB burst configuration, check the chipidea
> >    spec for meaning of each value. If this property is not existed, it
> >    will use the reset value.
> > +- tx-burst-size-dword: it is vendor dependent, the tx burst size in dword
> > +  (4 bytes), This register represents the maximum length of a the burst
> > +  in 32-bit words while moving data from system memory to the USB
> > +  bus, changing this value takes effect only the SBUSCFG.AHBBRST is 0.
> 
> The last bits about SBUSCFG.AHBBRST don't make any sense in the DT
> binding. The DT writer doesn't know about the SBUSCFG.AHBBRST value and
> should not care either.
> If someone sets the burst size to something
> non-standard in the DT, the driver should make sure to enable to
> necessary bits to make this setting take effect.

The SBUSCFG.AHBBRST property description is just above this one,
and the user should read the spec for changing these system
configuration parameters.

This requirement is from the spec, and the code logic makes sure
the burst size changes only when SBUSCFG.AHBBRST is 0, since the
hardware will only change burst size if SBUSCFG.AHBBRST is 0.

> 
> Also both those descriptions are missing a description to what value the
> burst sizes will be set if the DT properties are not found. If it's
> implementation defined spell this out in the doc.

It is optional property, if without this property, it will use the
default value.

> 
> Are there really cases where it makes sense to set RX and TX burst sizes
> to different values?

Yes, the default burst size is the same for all SoCs, but the bus
burst size may be larger for some SoCs.

-- 

Best Regards,
Peter Chen


From sudeep.holla at arm.com  Fri Aug 14 02:52:01 2015
From: sudeep.holla at arm.com (Sudeep Holla)
Date: Fri, 14 Aug 2015 10:52:01 +0100
Subject: [PATCH 5/9] ARM: common: Introduce PM domains for CPUs/clusters
In-Reply-To: <20150813192713.GA84868@linaro.org>
References: <1438731339-58317-1-git-send-email-lina.iyer@linaro.org>
 <1438731339-58317-6-git-send-email-lina.iyer@linaro.org>
 <CAL_JsqK67=DTtjZwwnonObLDjLbahkREfm0RvyXVV95bhR-d4Q@mail.gmail.com>
 <20150813150154.GB13356@red-moon> <20150813154503.GO52339@linaro.org>
 <55CCD35C.4000901@arm.com> <20150813192713.GA84868@linaro.org>
Message-ID: <55CDBA41.2080703@arm.com>



On 13/08/15 20:27, Lina Iyer wrote:
> On Thu, Aug 13 2015 at 11:26 -0600, Sudeep Holla wrote:
>>

[...]

>>
>> Having gone through this series and the one using it[1], the only common
>> activity is just cluster pm notifiers. Other than that it's just
>> creating indirection for now. The scenario might change in future, but
>> for now it seems unnecessary.
>>
> Not sure, what seems unnecessary to you. Platforms do have to send
> cluster PM notifications, and they have to duplicate reference counting.
> Also PM domain framework allows hierarchy which is quite desirable to
> power down parts of the SoC that are powered on or have to clocked high,
> until the CPU is running.
>

Agreed, no argument on using genpd for CPU PM for all the goodies genpd
provides, but the way this patch was creating the genpd domains. It
needs to be part of your power controller.

> Cluster PM notifications are just one aspect of this that we currently
> handle in the first submission. The patchset as a whole provides a way
> to determine in Linux the last man down and the first man up and carry
> out activities. There are a bunch of things that are done to power save
> when the last man goes down - Turn off debuggers, switch off PLLs,
> reduce bus clocks, flush caches amongst a few that I know of. Some of it
> are platform specific and some of it arent. This patches provide the way
> for both of them to be done easily. The CPU runtime PM and PM domains as
> a framework, closely track what the hardware does.
>

Again no argument, I just favour common interface functions. Since each
power controller/platform will have specific sequence, it might be hard
to generalize that, but I may be wrong. OTH common interface functions
to handle those components might give some flexibility to the power
controllers.

> Mentioned in an other mail in this thread, is also an option to
> determine the cluster flush state and use it in conjunction with PSCI to
> do OS-Initiated cluster power down.
>

I haven't yet explored down that route yet, with platform co-ordination
we don't need much complexity in kernel :). OS co-ordination is a
different story as we need to consider the secure/non-secure world
dimensions there. We will have to consider the privileges/restrictions
Linux has.

>> Also if you look at the shmobile power controller driver, it covers all
>> the devices including CPUs unlike QCOM power controller which handles
>> only CPU. Yes we can skip CPU genpd creation there only for CPU, IMO
>> creating the power domains should be part of power controller driver.
>>
>> You can add helper functions for all the ARM specific code that can be
>> reused by multiple power controller drivers handling CPU/Cluster power
>> domain.
>>
> Sure, some architectures may desire that. I have them addressed in [2].
>

I haven't looked at that yet, but will do soon.

>>> An analogy to this would be the "arm,idle-state" that defines the DT
>>> node as something that also depicts a generic cpuidle C state.
>>>
>>
>> I tend to disagree. In idle-states, the nodes define that generic
>> properties and they can be parsed in a generic way. That's not the case
>> here. Each power controller binding differs.
>>
> Yes, may be we will have common elements like latency, residency of
> powering on/off a domain that a genpd governor can utilize in
> determining if its worth powering off the domain or not.
>

Make sense, but as Rob pointed how generic are those on various
platforms is something we need to check considering few platforms before
we build the generic infrastructure.

>> Yes the generic compatible might be useful to identify that this power
>> domain handles CPU/Cluster, but there will be more power controller
>> specific things compared to generic code.
>>
> Agreed, not debating that. Power controller is very SoC specific, but
> not debuggers, GIC, caches, buses etc. Many SoCs have almost similiar
> needs for many of these supplemental hardware to the CPUs and trend
> seems to be generalizing on many of these components.
>

Generalizing those components and using genpd is absolutely fine, just
the mechanics is what I am debating on.

Regards,
Sudeep


From djkurtz at chromium.org  Fri Aug 14 02:57:17 2015
From: djkurtz at chromium.org (Daniel Kurtz)
Date: Fri, 14 Aug 2015 17:57:17 +0800
Subject: [PATCH v4] pinctrl: mediatek: Implement wake handler and suspend
 resume
In-Reply-To: <1439541486-22203-1-git-send-email-maoguang.meng@mediatek.com>
References: <1439541486-22203-1-git-send-email-maoguang.meng@mediatek.com>
Message-ID: <CAGS+omAtW0O2FgGkDsw7BgZA1Vhdkp2UhCvsgjf5rP1Q+jybuA@mail.gmail.com>

On Fri, Aug 14, 2015 at 4:38 PM, <maoguang.meng at mediatek.com> wrote:
>
> From: Maoguang Meng <maoguang.meng at mediatek.com>
>
> This patch implement irq_set_wake to get who is wakeup source and
> setup on suspend resume.
>
> Signed-off-by: Maoguang Meng <maoguang.meng at mediatek.com>

Reviewed-by: Daniel Kurtz <djkurtz at chromium.org>

Thanks!
-Dan

>
> ---
> changes since v3:
> -add a comment in mtk_eint_chip_read_mask.
> -delete ALIGN when allocate eint_offsets.ports.
> -fix unrelated change.
>
> changes since v2:
> -modify irq_wake to handle irq wakeup source.
> -allocate two buffers separately.
> -fix some codestyle.
>
> Changes since v1:
> -implement irq_wake handler.
> ---
>
>  drivers/pinctrl/mediatek/pinctrl-mt8173.c     |  1 +
>  drivers/pinctrl/mediatek/pinctrl-mtk-common.c | 91 ++++++++++++++++++++++++++-
>  drivers/pinctrl/mediatek/pinctrl-mtk-common.h |  4 ++
>  3 files changed, 95 insertions(+), 1 deletion(-)
>
> diff --git a/drivers/pinctrl/mediatek/pinctrl-mt8173.c b/drivers/pinctrl/mediatek/pinctrl-mt8173.c
> index d0c811d..ad27184 100644
> --- a/drivers/pinctrl/mediatek/pinctrl-mt8173.c
> +++ b/drivers/pinctrl/mediatek/pinctrl-mt8173.c
> @@ -385,6 +385,7 @@ static struct platform_driver mtk_pinctrl_driver = {
>         .driver = {
>                 .name = "mediatek-mt8173-pinctrl",
>                 .of_match_table = mt8173_pctrl_match,
> +               .pm = &mtk_eint_pm_ops,
>         },
>  };
>
> diff --git a/drivers/pinctrl/mediatek/pinctrl-mtk-common.c b/drivers/pinctrl/mediatek/pinctrl-mtk-common.c
> index ad1ea16..fe34ce9 100644
> --- a/drivers/pinctrl/mediatek/pinctrl-mtk-common.c
> +++ b/drivers/pinctrl/mediatek/pinctrl-mtk-common.c
> @@ -33,6 +33,7 @@
>  #include <linux/mfd/syscon.h>
>  #include <linux/delay.h>
>  #include <linux/interrupt.h>
> +#include <linux/pm.h>
>  #include <dt-bindings/pinctrl/mt65xx.h>
>
>  #include "../core.h"
> @@ -1062,6 +1063,77 @@ static int mtk_eint_set_type(struct irq_data *d,
>         return 0;
>  }
>
> +static int mtk_eint_irq_set_wake(struct irq_data *d, unsigned int on)
> +{
> +       struct mtk_pinctrl *pctl = irq_data_get_irq_chip_data(d);
> +       int shift = d->hwirq & 0x1f;
> +       int reg = d->hwirq >> 5;
> +
> +       if (on)
> +               pctl->wake_mask[reg] |= BIT(shift);
> +       else
> +               pctl->wake_mask[reg] &= ~BIT(shift);
> +
> +       return 0;
> +}
> +
> +static void mtk_eint_chip_write_mask(const struct mtk_eint_offsets *chip,
> +               void __iomem *eint_reg_base, u32 *buf)
> +{
> +       int port;
> +       void __iomem *reg;
> +
> +       for (port = 0; port < chip->ports; port++) {
> +               reg = eint_reg_base + (port << 2);
> +               writel_relaxed(~buf[port], reg + chip->mask_set);
> +               writel_relaxed(buf[port], reg + chip->mask_clr);
> +       }
> +}
> +
> +static void mtk_eint_chip_read_mask(const struct mtk_eint_offsets *chip,
> +               void __iomem *eint_reg_base, u32 *buf)
> +{
> +       int port;
> +       void __iomem *reg;
> +
> +       for (port = 0; port < chip->ports; port++) {
> +               reg = eint_reg_base + chip->mask + (port << 2);
> +               buf[port] = ~readl_relaxed(reg);
> +               /* Mask is 0 when irq is enabled, and 1 when disabled. */
> +       }
> +}
> +
> +static int mtk_eint_suspend(struct device *device)
> +{
> +       void __iomem *reg;
> +       struct mtk_pinctrl *pctl = dev_get_drvdata(device);
> +       const struct mtk_eint_offsets *eint_offsets =
> +                       &pctl->devdata->eint_offsets;
> +
> +       reg = pctl->eint_reg_base;
> +       mtk_eint_chip_read_mask(eint_offsets, reg, pctl->cur_mask);
> +       mtk_eint_chip_write_mask(eint_offsets, reg, pctl->wake_mask);
> +
> +       return 0;
> +}
> +
> +static int mtk_eint_resume(struct device *device)
> +{
> +       struct mtk_pinctrl *pctl = dev_get_drvdata(device);
> +       const struct mtk_eint_offsets *eint_offsets =
> +                       &pctl->devdata->eint_offsets;
> +
> +       mtk_eint_chip_write_mask(eint_offsets,
> +                       pctl->eint_reg_base, pctl->cur_mask);
> +
> +       return 0;
> +}
> +
> +const struct dev_pm_ops mtk_eint_pm_ops = {
> +       .suspend = mtk_eint_suspend,
> +       .resume = mtk_eint_resume,
> +};
> +
>  static void mtk_eint_ack(struct irq_data *d)
>  {
>         struct mtk_pinctrl *pctl = irq_data_get_irq_chip_data(d);
> @@ -1076,10 +1148,12 @@ static void mtk_eint_ack(struct irq_data *d)
>
>  static struct irq_chip mtk_pinctrl_irq_chip = {
>         .name = "mt-eint",
> +       .irq_disable = mtk_eint_mask,
>         .irq_mask = mtk_eint_mask,
>         .irq_unmask = mtk_eint_unmask,
>         .irq_ack = mtk_eint_ack,
>         .irq_set_type = mtk_eint_set_type,
> +       .irq_set_wake = mtk_eint_irq_set_wake,
>         .irq_request_resources = mtk_pinctrl_irq_request_resources,
>         .irq_release_resources = mtk_pinctrl_irq_release_resources,
>  };
> @@ -1217,7 +1291,7 @@ int mtk_pctrl_init(struct platform_device *pdev,
>         struct device_node *np = pdev->dev.of_node, *node;
>         struct property *prop;
>         struct resource *res;
> -       int i, ret, irq;
> +       int i, ret, irq, ports_buf;
>
>         pctl = devm_kzalloc(&pdev->dev, sizeof(*pctl), GFP_KERNEL);
>         if (!pctl)
> @@ -1319,6 +1393,21 @@ int mtk_pctrl_init(struct platform_device *pdev,
>                 goto chip_error;
>         }
>
> +       ports_buf = pctl->devdata->eint_offsets.ports;
> +       pctl->wake_mask = devm_kcalloc(&pdev->dev, ports_buf,
> +                                       sizeof(*pctl->wake_mask), GFP_KERNEL);
> +       if (!pctl->wake_mask) {
> +               ret = -ENOMEM;
> +               goto chip_error;
> +       }
> +
> +       pctl->cur_mask = devm_kcalloc(&pdev->dev, ports_buf,
> +                                       sizeof(*pctl->cur_mask), GFP_KERNEL);
> +       if (!pctl->cur_mask) {
> +               ret = -ENOMEM;
> +               goto chip_error;
> +       }
> +
>         pctl->eint_dual_edges = devm_kcalloc(&pdev->dev, pctl->devdata->ap_num,
>                                              sizeof(int), GFP_KERNEL);
>         if (!pctl->eint_dual_edges) {
> diff --git a/drivers/pinctrl/mediatek/pinctrl-mtk-common.h b/drivers/pinctrl/mediatek/pinctrl-mtk-common.h
> index 30213e5..f1be8e8 100644
> --- a/drivers/pinctrl/mediatek/pinctrl-mtk-common.h
> +++ b/drivers/pinctrl/mediatek/pinctrl-mtk-common.h
> @@ -266,6 +266,8 @@ struct mtk_pinctrl {
>         void __iomem            *eint_reg_base;
>         struct irq_domain       *domain;
>         int                     *eint_dual_edges;
> +       u32 *wake_mask;
> +       u32 *cur_mask;
>  };
>
>  int mtk_pctrl_init(struct platform_device *pdev,
> @@ -281,4 +283,6 @@ int mtk_pconf_spec_set_ies_smt_range(struct regmap *regmap,
>                 const struct mtk_pin_ies_smt_set *ies_smt_infos, unsigned int info_num,
>                 unsigned int pin, unsigned char align, int value);
>
> +extern const struct dev_pm_ops mtk_eint_pm_ops;
> +
>  #endif /* __PINCTRL_MTK_COMMON_H */
> --
> 1.8.1.1.dirty
>
> --
> To unsubscribe from this list: send the line "unsubscribe linux-kernel" in
> the body of a message to majordomo at vger.kernel.org
> More majordomo info at  http://vger.kernel.org/majordomo-info.html
> Please read the FAQ at  http://www.tux.org/lkml/


From mikko.perttunen at kapsi.fi  Fri Aug 14 02:59:15 2015
From: mikko.perttunen at kapsi.fi (Mikko Perttunen)
Date: Fri, 14 Aug 2015 12:59:15 +0300
Subject: [PATCH 0/5] Host1x/TegraDRM fixes/improvements
In-Reply-To: <1436354868-24309-1-git-send-email-mperttunen@nvidia.com>
References: <1436354868-24309-1-git-send-email-mperttunen@nvidia.com>
Message-ID: <55CDBBF3.3010405@kapsi.fi>

Bump.

On 07/08/2015 02:27 PM, Mikko Perttunen wrote:
> Hi, this series has a few small improvements for Host1x and TegraDRM
> that the VIC series will build upon.
> 
> 1/5 is a bug fix to host1x.
> 2/5 is required by VIC code to implement ->is_addr_reg().
> 3/5 deduplicates handling of HOST1X class address registers
>     and fixes the checked registers.
> 4/5 is required for the host1x firewall to work when bo's are
>     mapped using IOMMU.
> 5/5 adds a TegraDRM allocator that allows drivers to allocate
>     non-GEM memory that is still mapped to the TegraDRM domain.
> 
> Arto Merilainen (3):
>   host1x: Store device address to all bufs
>   host1x: Pass register value in firewall
>   drm/tegra: Support kernel mappings with IOMMU
> 
> Mikko Perttunen (2):
>   host1x: Handle HOST1X class address registers directly
>   drm/tegra: Add Tegra DRM allocation API
> 
>  drivers/gpu/drm/tegra/drm.c  | 99 +++++++++++++++++++++++++++++++++++++++++---
>  drivers/gpu/drm/tegra/drm.h  | 13 +++++-
>  drivers/gpu/drm/tegra/gem.c  | 34 +++++++++++++--
>  drivers/gpu/drm/tegra/gr2d.c | 25 ++++-------
>  drivers/gpu/drm/tegra/gr3d.c | 24 ++++-------
>  drivers/gpu/host1x/job.c     | 54 +++++++++++++++++-------
>  include/linux/host1x.h       |  4 +-
>  7 files changed, 193 insertions(+), 60 deletions(-)
> 


From l.stach at pengutronix.de  Fri Aug 14 03:02:37 2015
From: l.stach at pengutronix.de (Lucas Stach)
Date: Fri, 14 Aug 2015 12:02:37 +0200
Subject: [PATCH v3 08/10] Doc: usb: ci-hdrc-usb2: add
 tx(rx)-burst-config-dword for binding doc
In-Reply-To: <20150814084050.GE11072@shlinux2>
References: <1438931747-25209-1-git-send-email-peter.chen@freescale.com>
 <1438931747-25209-9-git-send-email-peter.chen@freescale.com>
 <1439541450.13210.31.camel@pengutronix.de>
 <20150814084050.GE11072@shlinux2>
Message-ID: <1439546557.13210.52.camel@pengutronix.de>

Am Freitag, den 14.08.2015, 16:40 +0800 schrieb Peter Chen:
> On Fri, Aug 14, 2015 at 10:37:30AM +0200, Lucas Stach wrote:
> > Am Freitag, den 07.08.2015, 15:15 +0800 schrieb Peter Chen:
> > > It is used to override the default setting for burst size, changing
> > > burst size takes effect only when the SBUSCFG.AHBBRST = 0.
> > > 
> > > Signed-off-by: Peter Chen <peter.chen at freescale.com>
> > > ---
> > >  Documentation/devicetree/bindings/usb/ci-hdrc-usb2.txt | 10 ++++++++++
> > >  1 file changed, 10 insertions(+)
> > > 
> > > diff --git a/Documentation/devicetree/bindings/usb/ci-hdrc-usb2.txt b/Documentation/devicetree/bindings/usb/ci-hdrc-usb2.txt
> > > index d52a747..d71ef07 100644
> > > --- a/Documentation/devicetree/bindings/usb/ci-hdrc-usb2.txt
> > > +++ b/Documentation/devicetree/bindings/usb/ci-hdrc-usb2.txt
> > > @@ -37,6 +37,14 @@ Optional properties:
> > >    property is used to change AHB burst configuration, check the chipidea
> > >    spec for meaning of each value. If this property is not existed, it
> > >    will use the reset value.
> > > +- tx-burst-size-dword: it is vendor dependent, the tx burst size in dword
> > > +  (4 bytes), This register represents the maximum length of a the burst
> > > +  in 32-bit words while moving data from system memory to the USB
> > > +  bus, changing this value takes effect only the SBUSCFG.AHBBRST is 0.
> > 
> > The last bits about SBUSCFG.AHBBRST don't make any sense in the DT
> > binding. The DT writer doesn't know about the SBUSCFG.AHBBRST value and
> > should not care either.
> > If someone sets the burst size to something
> > non-standard in the DT, the driver should make sure to enable to
> > necessary bits to make this setting take effect.
> 
> The SBUSCFG.AHBBRST property description is just above this one,
> and the user should read the spec for changing these system
> configuration parameters.
> 
This is not clear from the description. This should read something like
"The value of this property will only take effect if property
ahb-burst-config is set to 0."

The DT binding should be coherent and understandable without reading the
DW USB spec and/or the code. Please take some care about this.

> This requirement is from the spec, and the code logic makes sure
> the burst size changes only when SBUSCFG.AHBBRST is 0, since the
> hardware will only change burst size if SBUSCFG.AHBBRST is 0.
> 
> > 
> > Also both those descriptions are missing a description to what value the
> > burst sizes will be set if the DT properties are not found. If it's
> > implementation defined spell this out in the doc.
> 
> It is optional property, if without this property, it will use the
> default value.
> 
Then specify this in the binding. Again, the binding is a spec that one
should be able to understand without reading the code.

"If this property is missing the reset defaults of the hardware
implementation will be used."

> > 
> > Are there really cases where it makes sense to set RX and TX burst sizes
> > to different values?
> 
> Yes, the default burst size is the same for all SoCs, but the bus
> burst size may be larger for some SoCs.
> 
This question wasn't meant to dispute the RX/TX burst size
configuration, but I'm questioning if it really makes sense to set them
to different values. Do we really need 2 properties for this, or is 1
enough?

Do you see any use case where someone would like to do something like:
tx-burst-size-dword = <0x8>;
rx-burst-size-dword = <0x10>;

Regards,
Lucas
-- 
Pengutronix e.K.             | Lucas Stach                 |
Industrial Linux Solutions   | http://www.pengutronix.de/  |



From linus.walleij at linaro.org  Fri Aug 14 03:06:32 2015
From: linus.walleij at linaro.org (Linus Walleij)
Date: Fri, 14 Aug 2015 12:06:32 +0200
Subject: [PATCH 2/2] soc/fsl: add ftm alarm driver for ls1021a platform
In-Reply-To: <SN1PR0301MB161682A7FC5200580BED09119D7C0@SN1PR0301MB1616.namprd03.prod.outlook.com>
References: <1439358807-9024-1-git-send-email-dongsheng.wang@freescale.com>
 <1439358807-9024-2-git-send-email-dongsheng.wang@freescale.com>
 <CACRpkdbninKuGzhEc5mN+85j-=w_wYQgra-Ark_Du6gWKN2=tg@mail.gmail.com>
 <SN1PR0301MB161682A7FC5200580BED09119D7C0@SN1PR0301MB1616.namprd03.prod.outlook.com>
Message-ID: <CACRpkdYB23PbECUb2FP=_ck8PJe42wdifEcMSdKWrKnJLNp=pg@mail.gmail.com>

On Fri, Aug 14, 2015 at 5:12 AM, Wang Dongsheng
<Dongsheng.Wang at freescale.com> wrote:
>> On Wed, Aug 12, 2015 at 7:53 AM, Dongsheng Wang
>> <dongsheng.wang at freescale.com> wrote:
>>
>> > From: Wang Dongsheng <dongsheng.wang at freescale.com>
>> >
>> > Only Ftm0 can be used when system going to deep sleep. So this driver
>> > to support ftm0 as a wakeup source.
>> >
>> > Signed-off-by: Wang Dongsheng <dongsheng.wang at freescale.com>
>> > ---
>> > *V2*
>> > Change Copyright 2014 to 2015.
>> (...)
>> > +config FTM_ALARM
>> > +       bool "FTM alarm driver"
>> > +       depends on SOC_LS1021A
>> > +       default n
>> > +       help
>> > +         Say y here to enable FTM alarm support.  The FTM alarm provides
>> > +         alarm functions for wakeup system from deep sleep.  There is only
>> > +         one FTM can be used in ALARM(FTM 0).
>> (...)
>> > +static u32 time_to_cycle(unsigned long time)
>> > +static u32 cycle_to_time(u32 cycle)
>> > +static int ftm_set_alarm(u64 cycle)
>> > +static irqreturn_t ftm_alarm_interrupt(int irq, void *dev_id)
>> > +static ssize_t ftm_alarm_show(struct device *dev,
>> > +                             struct device_attribute *attr,
>> > +                             char *buf)
>> > +static ssize_t ftm_alarm_store(struct device *dev,
>> > +                              struct device_attribute *attr,
>> > +                              const char *buf, size_t count)
>> (...)
>> > +static struct device_attribute ftm_alarm_attributes = __ATTR(ftm_alarm, 0644,
>> > +                       ftm_alarm_show, ftm_alarm_store);
>>
>> If you're gonna invent ABIs, document then in Documentation/ABI/testing/*.
>>
>> But I don't get it. Why is this driver not in drivers/rtc?
>>
>> It does a subset of what an RTC does. The ioctl()'s of an RTC
>> can do what you want to do. And much much more.
>>
>> If it can't do all an RTC can do, surely the RTC subsystem
>> can be augmented to host it anyway. It's way to close to
>> an RTC to have it's own random sysfs driver like this.
>>
>> Unless I'm totally off, rewrite this to an RTC driver and post
>> it to the RTC maintainers.
>
> FlexTimer is not a RTC device and not have any rtc deivce function. They belong to
> different devices, why we need to register this to RTC framework? I am confused about this.
>
> Now in freescale layerscape platform this driver is only for FlexTimer0, and not
> fit for each flextimer. Because only FlexTimer0 still turn-on when system in the Deep Sleep.
>
> If the "alarm" make you feel confused or mislead you think this is a RTC devices. I think
> I need to change the "alarm" to "timer".

I think it is an RTC, it is just that the hardware engineer
designed it with a wakeup usecase in mind and did not call
it an RTC. Wakeup is one of the things RTCs do.

If you inspect a few drivers in drivers/rtc such as drivers/rtc/rtc-pl030.c
you will find that they are just as crude as this "alarm" thing.

It has a counter that counts cycles, it has a comparator
and an alarm function. It is an on-chip RTC, just like PL030
no matter what the datasheet or hardware engineer thinks it
should be called, the Linux kernel calls this an RTC, and it
has a subsystem for handling it, so we should use it and
not invent random new stuff.

If the hardware is really so strange that the counter can only
be started if you also put an alarm at the same time (I doubt
it, but OK if you say so) it is a subset of an RTC that can
only be used for alarms but not timekeeping, but it should
*still* live in drivers/rtc.

Think for a moment on the huge effort that John Stultz put into
integrating Android alarm timers with POSIX and the RTC
subsystem and fixing it all from the smallest handset to
the largest S360 supercomputer. The approach of a custom
device just throws all of that out the window and reinvents the
mechanism in userspace, forcing all standardized userspace to
have special code to handle this special alarm with its
special sysfs ABI.

Check
commit ff3ead96d17f47ee70c294a5cc2cce9b61e82f0f
"timers: Introduce in-kernel alarm-timer interface"
for example.

Even if you persist on keeping it in its own magic driver
like this, it should implement the alarm timer interface
from <linux/alarmtimer.h> and I bet after that you don't
need the sysfs files anymore, as the system will sleep
and wake up from the regular syscalls instead of using
magic poking in sysfs from userspace. AFAICT this hardware
is designed for exactly this usecase.

tools/testing/selftests/timers/alarmtimer-suspend.c
is there for you to test your driver with alarmtimer
support.

Needless to say: if you implement it as an RTC you get the
alarmtimer interaction for free. That is why we have the
subsystem after all: to be helpful.

Yours,
Linus Walleij


From srinivas.kandagatla at linaro.org  Fri Aug 14 03:17:18 2015
From: srinivas.kandagatla at linaro.org (Srinivas Kandagatla)
Date: Fri, 14 Aug 2015 11:17:18 +0100
Subject: [PATCH] nvmem: core: fix a copy paste error
Message-ID: <1439547438-4512-1-git-send-email-srinivas.kandagatla@linaro.org>

This patch fixes a copy paste error in a check which is performed to
determine if the cell is specified in bits or not.

This warning was picked-up by a static checker.

Reported-by: Dan Carpenter <dan.carpenter at oracle.com>
Signed-off-by: Srinivas Kandagatla <srinivas.kandagatla at linaro.org>
---
 drivers/nvmem/core.c | 2 +-
 1 file changed, 1 insertion(+), 1 deletion(-)

diff --git a/drivers/nvmem/core.c b/drivers/nvmem/core.c
index 35a42bb..ea0d6fd 100644
--- a/drivers/nvmem/core.c
+++ b/drivers/nvmem/core.c
@@ -825,7 +825,7 @@ static int __nvmem_cell_read(struct nvmem_device *nvmem,
 		return rc;
 
 	/* shift bits in-place */
-	if (cell->bit_offset || cell->bit_offset)
+	if (cell->bit_offset || cell->nbits)
 		nvmem_shift_read_buffer_in_place(cell, buf);
 
 	*len = cell->bytes;
-- 
1.9.1



From grygorii.strashko at ti.com  Fri Aug 14 03:18:49 2015
From: grygorii.strashko at ti.com (Grygorii Strashko)
Date: Fri, 14 Aug 2015 13:18:49 +0300
Subject: [PATCH v2 2/6] genirq: fix irqchip_set_wake_parent if
 IRQCHIP_SKIP_SET_WAKE
In-Reply-To: <55CC9493.9020101@ti.com>
References: <1439401562-28874-1-git-send-email-grygorii.strashko@ti.com>
 <1439401562-28874-3-git-send-email-grygorii.strashko@ti.com>
 <55CC6AFF.8060400@arm.com> <55CC71E8.80604@ti.com> <55CC9493.9020101@ti.com>
Message-ID: <55CDC089.1060309@ti.com>

On 08/13/2015 03:58 PM, Grygorii Strashko wrote:
> On 08/13/2015 01:31 PM, Grygorii Strashko wrote:
>> On 08/13/2015 01:01 PM, Marc Zyngier wrote:
>>> On 12/08/15 18:45, Grygorii Strashko wrote:
>>>> The irqchip_set_wake_parent should not fail if IRQ chip
>>>> specifies IRQCHIP_SKIP_SET_WAKE. Otherwise, IRQ wakeup
>>>> configuration can't be propagated properly through IRQ
>>>> domains hierarchy.
>>>>
>>>> In case of TI OMAP DRA7 the issue reproduced with following
>>>> configuration:
>>>> ARM GIC<-OMAP wakeupgen<-TI CBAR<-GPIO<-GPIO pcf857x<-gpio_key
>>>>
>>>> gpio_key is wakeup source
>>>>
>>>> Failure is reproduced during suspend/resume to RAM:
>>>> suspend:
>>>>    - gpio_keys_suspend
>>>>      enable_irq_wake
>>>>        + pcf857x_irq_set_wake
>>>>          + omap_gpio_wake_enable
>>>>            + TI CBAR irq_chip_set_wake_parent
>>>>              + OMAP wakeupgen has no .irq_set_wake()
>>>
>>> Most importantly, wakeupgen has IRQCHIP_SKIP_SET_WAKE set.
>>>
>>>>              and -ENOSYS will be returned
>>>>
>>>> resume:
>>>>    - gpio_keys_resume
>>>>      + disable_irq_wake
>>>>        + irq_set_irq_wake
>>>>          + WARN(1, "Unbalanced IRQ %d wake disable\n", irq);
>>>>
>>>> Fixes: 08b55e2a9208 ('genirq: Add irqchip_set_wake_parent')
>>>> Signed-off-by: Grygorii Strashko <grygorii.strashko at ti.com>
>>>> ---
>>>>    kernel/irq/chip.c | 4 ++++
>>>>    1 file changed, 4 insertions(+)
>>>>
>>>> diff --git a/kernel/irq/chip.c b/kernel/irq/chip.c
>>>> index 6de638b..bdb1b9d 100644
>>>> --- a/kernel/irq/chip.c
>>>> +++ b/kernel/irq/chip.c
>>>> @@ -1024,6 +1024,10 @@ int irq_chip_set_vcpu_affinity_parent(struct
>>>> irq_data *data, void *vcpu_info)
>>>>    int irq_chip_set_wake_parent(struct irq_data *data, unsigned int on)
>>>>    {
>>>>        data = data->parent_data;
>>>> +
>>>> +    if (irq_data_get_irq_chip(data)->flags & IRQCHIP_SKIP_SET_WAKE)
>>>> +        return 0;
>>>> +
>>>>        if (data->chip->irq_set_wake)
>>>>            return data->chip->irq_set_wake(data, on);
>>>>
>>>>
>>>
>>> We have a more general issue with chip flags, and how they combine
>>> within a stack of irqchips.
>>
>> Indeed. Problem looks similar to IRQCHIP_MASK_ON_SUSPEND flag usage.
>>
>>>
>>> What if you remove the irq_chip_set_wake_parent from the crossbar
>>> driver, and instead set IRQCHIP_SKIP_SET_WAKE?
>>
>> I've thought about this and it should work for me.
>> One question - what if crossbar will be not the last one in
>> IRQ domains hierarchy?
>>
> 
> I can confirm, if I revert this patch, add IRQCHIP_SKIP_SET_WAKE to
> the crossbar and remove irq_chip_set_wake_parent wakeups still works.
> What do you prefer me to do: add additional patch for the crossbar,
> drop/keep this patch?
> 

OK. There are two possibilities to fix set_wake functionality for TI OMAPs
where below HW configurations are used:
  OMAP4/5: GIC <- OMAP wakeupgen
  DRA7: GIC <- OMAP wakeupgen <- TI CBAR


1) ensure that IRQCHIP_SKIP_SET_WAKE flag is set only for GIC and
use irq_chip_set_wake_parent() in both wakeupgen and crossbar 
 [this patch is required]

2) ensure that IRQCHIP_SKIP_SET_WAKE flag is set and drop 
.irq_set_wake()/irq_chip_set_wake_parent() for all IRQ chips
in IRQ domains hierarchy.
 [this patch can be dropped]

I'm going to select approach 2 and re-send.


-- 
regards,
-grygorii


From liguozhu at hisilicon.com  Fri Aug 14 03:30:17 2015
From: liguozhu at hisilicon.com (Kenneth Lee)
Date: Fri, 14 Aug 2015 18:30:17 +0800
Subject: [PATCH 0/5] net: Hisilicon Network Subsystem support
Message-ID: <1439548222-231611-1-git-send-email-liguozhu@hisilicon.com>

This patchset add Hisilicon Network Subsystem support. The subsystem
provides a long term developing network accelerate engine with ring buffer
interface. The network interface can be used as standard ethernet network
interface card or be made use by a network application with decoded L2 to
L4 data.

The patchset is porting from some internal-use drivers, it is tested and
working fine with the hardware. But some detail design is not that good.
But we want to know if the community can accept the structure/arch before
refining it. Thank you.

Kenneth Lee (5):
  net: add Hisilicon Network Subsystem support (config and documents)
  net: add Hisilicon Network Subsystem hnae framework support
  net: add Hisilicon Network Subsystem MDIO support
  net: add Hisilicon Network Subsystem DSAF support
  net: add Hisilicon Network Subsystem basic ethernet support

 .../devicetree/bindings/net/hisilicon-hns-dsaf.txt |   40 +
 .../devicetree/bindings/net/hisilicon-hns-mdio.txt |   22 +
 .../devicetree/bindings/net/hisilicon-hns-nic.txt  |   14 +
 arch/arm64/boot/dts/hisilicon/hip05_hns.dtsi       |  197 ++
 drivers/net/ethernet/hisilicon/Kconfig             |   33 +-
 drivers/net/ethernet/hisilicon/Makefile            |    1 +
 drivers/net/ethernet/hisilicon/hns/Makefile        |   15 +
 drivers/net/ethernet/hisilicon/hns/hnae.c          |  494 ++++
 drivers/net/ethernet/hisilicon/hns/hnae.h          |  582 +++++
 drivers/net/ethernet/hisilicon/hns/hns_ae_adapt.c  |  766 ++++++
 drivers/net/ethernet/hisilicon/hns/hns_dsaf_gmac.c |  705 +++++
 drivers/net/ethernet/hisilicon/hns/hns_dsaf_gmac.h |   45 +
 drivers/net/ethernet/hisilicon/hns/hns_dsaf_mac.c  |  942 +++++++
 drivers/net/ethernet/hisilicon/hns/hns_dsaf_mac.h  |  462 ++++
 drivers/net/ethernet/hisilicon/hns/hns_dsaf_main.c | 2681 ++++++++++++++++++++
 drivers/net/ethernet/hisilicon/hns/hns_dsaf_main.h |  438 ++++
 drivers/net/ethernet/hisilicon/hns/hns_dsaf_misc.c |  311 +++
 drivers/net/ethernet/hisilicon/hns/hns_dsaf_misc.h |   45 +
 drivers/net/ethernet/hisilicon/hns/hns_dsaf_ppe.c  |  582 +++++
 drivers/net/ethernet/hisilicon/hns/hns_dsaf_ppe.h  |  105 +
 drivers/net/ethernet/hisilicon/hns/hns_dsaf_rcb.c  |  972 +++++++
 drivers/net/ethernet/hisilicon/hns/hns_dsaf_rcb.h  |  136 +
 drivers/net/ethernet/hisilicon/hns/hns_dsaf_reg.h  |  958 +++++++
 .../net/ethernet/hisilicon/hns/hns_dsaf_xgmac.c    |  826 ++++++
 .../net/ethernet/hisilicon/hns/hns_dsaf_xgmac.h    |   15 +
 drivers/net/ethernet/hisilicon/hns/hns_enet.c      | 1552 +++++++++++
 drivers/net/ethernet/hisilicon/hns/hns_enet.h      |   81 +
 drivers/net/ethernet/hisilicon/hns/hns_ethtool.c   | 1174 +++++++++
 drivers/net/ethernet/hisilicon/hns/hns_mdio_main.c |  597 +++++
 29 files changed, 14790 insertions(+), 1 deletion(-)
 create mode 100644 Documentation/devicetree/bindings/net/hisilicon-hns-dsaf.txt
 create mode 100644 Documentation/devicetree/bindings/net/hisilicon-hns-mdio.txt
 create mode 100644 Documentation/devicetree/bindings/net/hisilicon-hns-nic.txt
 create mode 100644 arch/arm64/boot/dts/hisilicon/hip05_hns.dtsi
 create mode 100644 drivers/net/ethernet/hisilicon/hns/Makefile
 create mode 100644 drivers/net/ethernet/hisilicon/hns/hnae.c
 create mode 100644 drivers/net/ethernet/hisilicon/hns/hnae.h
 create mode 100644 drivers/net/ethernet/hisilicon/hns/hns_ae_adapt.c
 create mode 100644 drivers/net/ethernet/hisilicon/hns/hns_dsaf_gmac.c
 create mode 100644 drivers/net/ethernet/hisilicon/hns/hns_dsaf_gmac.h
 create mode 100644 drivers/net/ethernet/hisilicon/hns/hns_dsaf_mac.c
 create mode 100644 drivers/net/ethernet/hisilicon/hns/hns_dsaf_mac.h
 create mode 100644 drivers/net/ethernet/hisilicon/hns/hns_dsaf_main.c
 create mode 100644 drivers/net/ethernet/hisilicon/hns/hns_dsaf_main.h
 create mode 100644 drivers/net/ethernet/hisilicon/hns/hns_dsaf_misc.c
 create mode 100644 drivers/net/ethernet/hisilicon/hns/hns_dsaf_misc.h
 create mode 100644 drivers/net/ethernet/hisilicon/hns/hns_dsaf_ppe.c
 create mode 100644 drivers/net/ethernet/hisilicon/hns/hns_dsaf_ppe.h
 create mode 100644 drivers/net/ethernet/hisilicon/hns/hns_dsaf_rcb.c
 create mode 100644 drivers/net/ethernet/hisilicon/hns/hns_dsaf_rcb.h
 create mode 100644 drivers/net/ethernet/hisilicon/hns/hns_dsaf_reg.h
 create mode 100644 drivers/net/ethernet/hisilicon/hns/hns_dsaf_xgmac.c
 create mode 100644 drivers/net/ethernet/hisilicon/hns/hns_dsaf_xgmac.h
 create mode 100644 drivers/net/ethernet/hisilicon/hns/hns_enet.c
 create mode 100644 drivers/net/ethernet/hisilicon/hns/hns_enet.h
 create mode 100644 drivers/net/ethernet/hisilicon/hns/hns_ethtool.c
 create mode 100644 drivers/net/ethernet/hisilicon/hns/hns_mdio_main.c

-- 
1.9.1



From liguozhu at hisilicon.com  Fri Aug 14 03:30:20 2015
From: liguozhu at hisilicon.com (Kenneth Lee)
Date: Fri, 14 Aug 2015 18:30:20 +0800
Subject: [PATCH 3/5] net: add Hisilicon Network Subsystem MDIO support
In-Reply-To: <1439548222-231611-1-git-send-email-liguozhu@hisilicon.com>
References: <1439548222-231611-1-git-send-email-liguozhu@hisilicon.com>
Message-ID: <1439548222-231611-4-git-send-email-liguozhu@hisilicon.com>

The MDIO support for Hisilicon Network Subsystem. It is used in Hislicon
P660 and Hi1610 SoC to control the external PHY

Signed-off-by: Yisen Zhuang <Yisen.Zhuang at huawei.com>
Signed-off-by: Kenneth Lee <liguozhu at huawei.com>
---
 drivers/net/ethernet/hisilicon/hns/hns_mdio_main.c | 597 +++++++++++++++++++++
 1 file changed, 597 insertions(+)
 create mode 100644 drivers/net/ethernet/hisilicon/hns/hns_mdio_main.c

diff --git a/drivers/net/ethernet/hisilicon/hns/hns_mdio_main.c b/drivers/net/ethernet/hisilicon/hns/hns_mdio_main.c
new file mode 100644
index 0000000..7113fa8
--- /dev/null
+++ b/drivers/net/ethernet/hisilicon/hns/hns_mdio_main.c
@@ -0,0 +1,597 @@
+/*
+ * Copyright (c) 2014-2015 Hisilicon Limited.
+ *
+ * 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.
+ */
+
+#include <linux/errno.h>
+#include <linux/etherdevice.h>
+#include <linux/init.h>
+#include <linux/kernel.h>
+#include <linux/module.h>
+#include <linux/mutex.h>
+#include <linux/netdevice.h>
+#include <linux/of_address.h>
+#include <linux/of.h>
+#include <linux/of_mdio.h>
+#include <linux/of_platform.h>
+#include <linux/phy.h>
+#include <linux/platform_device.h>
+#include <linux/spinlock_types.h>
+
+#define MDIO_DRV_NAME "hi-mdio"
+#define MDIO_BUS_NAME "Hisilicon MII Bus"
+#define MDIO_DRV_VERSION "1.1.0"
+#define MDIO_COPYRIGHT "Copyright(c) 2015 Huawei Corporation."
+#define MDIO_DRV_STRING MDIO_BUS_NAME
+#define MDIO_DEFAULT_DEVICE_DESCR MDIO_BUS_NAME
+
+#define MDIO_CTL_DEV_ADDR(x)	(x & 0x1f)
+#define MDIO_CTL_PORT_ADDR(x)	((x & 0x1f) << 5)
+
+#define MDIO_BASE_ADDR			0x403C0000
+#define MDIO_REG_ADDR_LEN		0x1000
+#define MDIO_PHY_GRP_LEN		0x100
+#define MDIO_REG_LEN			0x10
+#define MDIO_PHY_ADDR_NUM		5
+#define MDIO_MAX_PHY_ADDR		0x1F
+#define MDIO_MAX_PHY_REG_ADDR		0xFFFF
+
+#define MDIO_TIMEOUT			1000000
+
+struct hns_mdio_device {
+	struct device *dev;
+	void *vbase;		/* mdio reg base address */
+	u8 phy_class[PHY_MAX_ADDR];
+	u8 index;
+	u8 chip_id;
+	u8 gidx;		/* global index */
+};
+
+#define MDIO_COMMAND_REG		0x0
+#define MDIO_ADDR_REG			0x4
+#define MDIO_WDATA_REG			0x8
+#define MDIO_RDATA_REG			0xc
+#define MDIO_STA_REG			0x10
+
+#define MDIO_CMD_DEVAD_M	0x1f
+#define MDIO_CMD_DEVAD_S	0
+#define MDIO_CMD_PRTAD_M	0x1f
+#define MDIO_CMD_PRTAD_S	5
+#define MDIO_CMD_OP_M		0x3
+#define MDIO_CMD_OP_S		10
+#define MDIO_CMD_ST_M		0x3
+#define MDIO_CMD_ST_S		12
+#define MDIO_CMD_START_B	14
+
+#define MDIO_ADDR_DATA_M	0xffff
+#define MDIO_ADDR_DATA_S	0
+
+#define MDIO_WDATA_DATA_M	0xffff
+#define MDIO_WDATA_DATA_S	0
+
+#define MDIO_RDATA_DATA_M	0xffff
+#define MDIO_RDATA_DATA_S	0
+
+#define MDIO_STATE_STA_B	0
+
+enum mdio_st_clause {
+	MDIO_ST_CLAUSE_45 = 0,
+	MDIO_ST_CLAUSE_22
+};
+
+enum mdio_c22_op_seq {
+	MDIO_C22_WRITE = 1,
+	MDIO_C22_READ = 2
+};
+
+enum mdio_c45_op_seq {
+	MDIO_C45_WRITE_ADDR = 0,
+	MDIO_C45_WRITE_DATA,
+	MDIO_C45_READ_INCREMENT,
+	MDIO_C45_READ
+};
+
+static inline void mdio_write_reg(void *base, u32 reg, u32 value)
+{
+	u8 __iomem *reg_addr = ACCESS_ONCE(base);
+
+	writel(value, reg_addr + reg);
+}
+
+#define MDIO_WRITE_REG(a, reg, value) \
+	mdio_write_reg((a)->vbase, (reg), (value))
+
+static inline u32 mdio_read_reg(void *base, u32 reg)
+{
+	u8 __iomem *reg_addr = ACCESS_ONCE(base);
+
+	return readl(reg_addr + reg);
+}
+
+#define MDIO_READ_REG(a, reg) \
+	mdio_read_reg((a)->vbase, (reg))
+
+#define mdio_set_field(origin, mask, shift, val) \
+	do { \
+		(origin) &= (~((mask) << (shift))); \
+		(origin) |= (((val) & (mask)) << (shift)); \
+	} while (0)
+
+#define mdio_get_field(origin, mask, shift) (((origin) >> (shift)) & (mask))
+
+static void mdio_set_reg_field(void *base, u32 reg, u32 mask, u32 shift,
+			       u32 val)
+{
+	u32 origin = mdio_read_reg(base, reg);
+
+	mdio_set_field(origin, mask, shift, val);
+	mdio_write_reg(base, reg, origin);
+}
+
+#define MDIO_SET_REG_FIELD(dev, reg, mask, shift, val) \
+	mdio_set_reg_field((dev)->vbase, (reg), (mask), (shift), (val))
+
+static u32 mdio_get_reg_field(void *base, u32 reg, u32 mask, u32 shift)
+{
+	u32 origin;
+
+	origin = mdio_read_reg(base, reg);
+	return mdio_get_field(origin, mask, shift);
+}
+
+#define MDIO_GET_REG_FIELD(dev, reg, mask, shift) \
+		mdio_get_reg_field((dev)->vbase, (reg), (mask), (shift))
+
+#define MDIO_SET_REG_BIT(dev, reg, bit, val) \
+		mdio_set_reg_field((dev)->vbase, (reg), 0x1ull, (bit), (val))
+
+#define MDIO_GET_REG_BIT(dev, reg, bit) \
+		mdio_get_reg_field((dev)->vbase, (reg), 0x1ull, (bit))
+
+/**
+ *hns_mdio_read_hw - read phy regs
+ *@mdio_dev: mdio device
+ *@phy_addr:phy addr
+ *@is_c45:
+ *@page:
+ *@reg: reg
+ *@data:regs data
+ *return status
+ */
+static int hns_mdio_read_hw(struct hns_mdio_device *mdio_dev, u8 phy_addr,
+			    u8 is_c45, u8 page, u16 reg, u16 *data)
+{
+	u32 cmd_reg_value;
+	u32 sta_reg_value;
+	u32 time_cnt;
+
+	if (phy_addr > MDIO_MAX_PHY_ADDR) {
+		dev_err(mdio_dev->dev, "Wrong phy address: phy_addr(%x)\n",
+			phy_addr);
+		return -EINVAL;
+	}
+
+	dev_dbg(mdio_dev->dev, "mdio(%d) base is %p\n",
+		mdio_dev->gidx, mdio_dev->vbase);
+	dev_dbg(mdio_dev->dev,
+		"phy_addr=%d, is_c45=%d, devad=%d, regnum=%#x!\n",
+		phy_addr, is_c45, page, reg);
+
+	/* Step 1; waiting for MDIO_COMMAND_REG 's mdio_start==0,	*/
+	/*	after that can do read or write*/
+	for (time_cnt = MDIO_TIMEOUT; time_cnt; time_cnt--) {
+		cmd_reg_value = MDIO_GET_REG_BIT(mdio_dev,
+						 MDIO_COMMAND_REG,
+						 MDIO_CMD_START_B);
+		if (!cmd_reg_value)
+			break;
+	}
+	if (cmd_reg_value) {
+		dev_err(mdio_dev->dev, "MDIO is busy!\n");
+		return -EBUSY;
+	}
+
+	if (!is_c45) {
+		cmd_reg_value = MDIO_ST_CLAUSE_22 << MDIO_CMD_ST_S;
+		cmd_reg_value |= MDIO_C22_READ << MDIO_CMD_OP_S;
+		cmd_reg_value |=
+			(phy_addr & MDIO_CMD_PRTAD_M) << MDIO_CMD_PRTAD_S;
+		cmd_reg_value |= (reg & MDIO_CMD_DEVAD_M) << MDIO_CMD_DEVAD_S;
+		cmd_reg_value |= 1 << MDIO_CMD_START_B;
+
+		MDIO_WRITE_REG(mdio_dev, MDIO_COMMAND_REG, cmd_reg_value);
+	} else {
+		MDIO_SET_REG_FIELD(mdio_dev, MDIO_ADDR_REG, MDIO_ADDR_DATA_M,
+				   MDIO_ADDR_DATA_S, reg);
+
+		/* Step 2; config the cmd-reg to write addr*/
+		cmd_reg_value = MDIO_ST_CLAUSE_45 << MDIO_CMD_ST_S;
+		cmd_reg_value |= MDIO_C45_WRITE_ADDR << MDIO_CMD_OP_S;
+
+		/* mdio_st==2'b00: is configing port addr*/
+		cmd_reg_value |=
+			(phy_addr & MDIO_CMD_PRTAD_M) << MDIO_CMD_PRTAD_S;
+
+		/* mdio_st == 2'b00: is configing dev_addr*/
+		cmd_reg_value |= (page & MDIO_CMD_DEVAD_M) << MDIO_CMD_DEVAD_S;
+		cmd_reg_value |= 1 << MDIO_CMD_START_B;
+		MDIO_WRITE_REG(mdio_dev, MDIO_COMMAND_REG, cmd_reg_value);
+
+		/* Step 3; waiting for MDIO_COMMAND_REG 's mdio_start==0,*/
+		/*check for read or write opt is finished */
+		for (time_cnt = MDIO_TIMEOUT; time_cnt; time_cnt--) {
+			cmd_reg_value = MDIO_GET_REG_BIT(mdio_dev,
+							 MDIO_COMMAND_REG,
+							 MDIO_CMD_START_B);
+			if (!cmd_reg_value)
+				break;
+		}
+		if (cmd_reg_value) {
+			dev_err(mdio_dev->dev, "MDIO is busy\n");
+			return -EBUSY;
+		}
+
+		/* Step 4; config cmd-reg, send read opt */
+		cmd_reg_value = MDIO_ST_CLAUSE_45 << MDIO_CMD_ST_S;
+		cmd_reg_value |= MDIO_C45_READ << MDIO_CMD_OP_S;
+
+		/* mdio_st==2'b00: is configing port addr*/
+		cmd_reg_value |=
+			(phy_addr & MDIO_CMD_PRTAD_M) << MDIO_CMD_PRTAD_S;
+
+		/* mdio_st == 2'b00: is configing dev_addr*/
+		cmd_reg_value |= (page & MDIO_CMD_DEVAD_M) << MDIO_CMD_DEVAD_S;
+		cmd_reg_value |= 1 << MDIO_CMD_START_B;
+		MDIO_WRITE_REG(mdio_dev, MDIO_COMMAND_REG, cmd_reg_value);
+	}
+
+	/* Step 5; waiting for MDIO_COMMAND_REG 's mdio_start==0,*/
+	/* check for read or write opt is finished */
+	for (time_cnt = MDIO_TIMEOUT; time_cnt; time_cnt--) {
+		cmd_reg_value = MDIO_GET_REG_BIT(mdio_dev,
+						 MDIO_COMMAND_REG,
+						 MDIO_CMD_START_B);
+		if (!cmd_reg_value)
+			break;
+	}
+	if (cmd_reg_value) {
+		dev_err(mdio_dev->dev, "MDIO is busy\n");
+		return -EBUSY;
+	}
+
+	sta_reg_value = MDIO_GET_REG_BIT(mdio_dev,
+					 MDIO_STA_REG, MDIO_STATE_STA_B);
+	if (sta_reg_value) {
+		dev_err(mdio_dev->dev, "MDIO Read failed!\n");
+		return -EBUSY;
+	}
+
+	/* Step 6; get out data*/
+	*data = (u16)MDIO_GET_REG_FIELD(mdio_dev, MDIO_RDATA_REG,
+					MDIO_RDATA_DATA_M, MDIO_RDATA_DATA_S);
+
+	return 0;
+}
+
+/**
+ *hns_mdio_write_hw - write phy regs
+ *@mdio_dev: mdio device
+ *@phy_addr: phy addr
+ *@is_c45: 0 means the clause 22, none 0 means clause 45
+ *@page: phy page addr
+ *@reg:  phy reg
+ *@data: regs data
+ *return status
+ */
+static int hns_mdio_write_hw(struct hns_mdio_device *mdio_dev, u8 phy_addr,
+			     u8 is_c45, u8 page, u16 reg, u16 data)
+{
+	u32 cmd_reg_value;
+	u32 time_cnt;
+
+	if (phy_addr > MDIO_MAX_PHY_ADDR) {
+		dev_err(mdio_dev->dev, "Wrong phy address: phy_addr(%x)\n",
+			phy_addr);
+		return -EINVAL;
+	}
+
+	dev_dbg(mdio_dev->dev, "mdio(%d) base is %p,write data=%d\n",
+		mdio_dev->gidx, mdio_dev->vbase, data);
+	dev_dbg(mdio_dev->dev, "phy_addr=%d, is_c45=%d, devad=%d, regnum=%#x\n",
+		phy_addr, is_c45, page, reg);
+
+	/* Step 1; waiting for MDIO_COMMAND_REG 's mdio_start==0,*/
+	/*	after that can do read or wtrite*/
+	for (time_cnt = MDIO_TIMEOUT; time_cnt; time_cnt--) {
+		cmd_reg_value = MDIO_GET_REG_BIT(mdio_dev,
+						 MDIO_COMMAND_REG,
+						 MDIO_CMD_START_B);
+		if (!cmd_reg_value)
+			break;
+	}
+	if (cmd_reg_value) {
+		dev_err(mdio_dev->dev, "MDIO is busy\n");
+		return -EBUSY;
+	}
+
+	if (!is_c45) {
+		MDIO_SET_REG_FIELD(mdio_dev, MDIO_WDATA_REG, MDIO_WDATA_DATA_M,
+				   MDIO_WDATA_DATA_S, data);
+
+		cmd_reg_value = MDIO_ST_CLAUSE_22 << MDIO_CMD_ST_S;
+		cmd_reg_value |= MDIO_C22_WRITE << MDIO_CMD_OP_S;
+		cmd_reg_value |=
+			(phy_addr & MDIO_CMD_PRTAD_M) << MDIO_CMD_PRTAD_S;
+		cmd_reg_value |= (reg & MDIO_CMD_DEVAD_M) << MDIO_CMD_DEVAD_S;
+		cmd_reg_value |= 1 << MDIO_CMD_START_B;
+
+		MDIO_WRITE_REG(mdio_dev, MDIO_COMMAND_REG, cmd_reg_value);
+	} else {
+		/* Step 2; config the cmd-reg to write addr*/
+		MDIO_SET_REG_FIELD(mdio_dev, MDIO_ADDR_REG, MDIO_ADDR_DATA_M,
+				   MDIO_ADDR_DATA_S, reg);
+
+		cmd_reg_value = MDIO_ST_CLAUSE_45 << MDIO_CMD_ST_S;
+		cmd_reg_value |= MDIO_C45_WRITE_ADDR << MDIO_CMD_OP_S;
+
+		/* mdio_st==2'b00: is configing port addr*/
+		cmd_reg_value |=
+			(phy_addr & MDIO_CMD_PRTAD_M) << MDIO_CMD_PRTAD_S;
+
+		/* mdio_st == 2'b00: is configing dev_addr*/
+		cmd_reg_value |= (page & MDIO_CMD_DEVAD_M) << MDIO_CMD_DEVAD_S;
+		cmd_reg_value |= 1 << MDIO_CMD_START_B;
+		MDIO_WRITE_REG(mdio_dev, MDIO_COMMAND_REG, cmd_reg_value);
+
+		/* Step 3; waiting for MDIO_COMMAND_REG's mdio_start==0,*/
+		/* check for read or write opt is finished */
+		for (time_cnt = MDIO_TIMEOUT; time_cnt; time_cnt--) {
+			cmd_reg_value = MDIO_GET_REG_BIT(mdio_dev,
+							 MDIO_COMMAND_REG,
+							 MDIO_CMD_START_B);
+			if (!cmd_reg_value)
+				break;
+		}
+		if (cmd_reg_value) {
+			dev_err(mdio_dev->dev, "MDIO is busy\n");
+			return -EBUSY;
+		}
+
+		/* Step 4; config the data needed writing */
+		MDIO_SET_REG_FIELD(mdio_dev, MDIO_WDATA_REG, MDIO_WDATA_DATA_M,
+				   MDIO_WDATA_DATA_S, data);
+
+		/* Step 5; config the cmd-reg for the write opt*/
+		cmd_reg_value = MDIO_ST_CLAUSE_45 << MDIO_CMD_ST_S;
+		cmd_reg_value |= MDIO_C45_WRITE_DATA << MDIO_CMD_OP_S;
+
+		/* mdio_st==2'b00: is configing port addr*/
+		cmd_reg_value |=
+			(phy_addr & MDIO_CMD_PRTAD_M) << MDIO_CMD_PRTAD_S;
+
+		/* mdio_st == 2'b00: is configing dev_addr*/
+		cmd_reg_value |= (page & MDIO_CMD_DEVAD_M) << MDIO_CMD_DEVAD_S;
+		cmd_reg_value |= 1 << MDIO_CMD_START_B;
+		MDIO_WRITE_REG(mdio_dev, MDIO_COMMAND_REG, cmd_reg_value);
+	}
+
+	return 0;
+}
+
+/**
+ * hns_mdio_get_chip_id - get parent node's chip-id attribute
+ * @dpev: mdio platform device
+ * return chip id if found the chip-id, or return 0
+ */
+static u32 hns_mdio_get_chip_id(struct platform_device *pdev)
+{
+	struct device_node *np;
+	u32 chip_id;
+	int ret;
+
+	np = of_get_parent(pdev->dev.of_node);
+	if (!np)
+		return 0;
+
+	ret = of_property_read_u32(np, "chip-id", &chip_id);
+	if (ret)
+		return 0;
+
+	return chip_id;
+}
+
+/**
+ * hns_mdio_write - access phy register
+ * @bus: mdio bus
+ * @phy_id: phy id
+ * @regnum: register num
+ * @value: register value
+ *
+ * Return 0 on success, negative on failure
+ */
+static int hns_mdio_write(struct mii_bus *bus,
+			  int phy_id, int regnum, u16 value)
+{
+	int ret;
+	struct hns_mdio_device *mdio_dev = (struct hns_mdio_device *)bus->priv;
+	u8 devad = ((regnum >> 16) & 0x1f);
+	u8 is_c45 = !!(regnum & MII_ADDR_C45);
+
+	ret = hns_mdio_write_hw(mdio_dev, phy_id, is_c45, devad,
+				(u16)(regnum & 0xffff), value);
+	if (ret) {
+		dev_err(&bus->dev, "write_phy_reg fail, phy_id=%d, devad=%d,regnum=%#x, value=%#x!\n",
+			phy_id, devad, regnum, value);
+
+		return ret;
+	}
+
+	return 0;
+}
+
+/**
+ * hns_mdio_read - access phy register
+ * @bus: mdio bus
+ * @phy_id: phy id
+ * @regnum: register num
+ * @value: register value
+ *
+ * Return phy register value
+ */
+static int hns_mdio_read(struct mii_bus *bus, int phy_id, int regnum)
+{
+	int ret;
+	u16 reg_val = 0;
+	u8 devad = ((regnum >> 16) & 0x1f);
+	u8 is_c45 = !!(regnum & MII_ADDR_C45);
+	struct hns_mdio_device *mdio_dev = (struct hns_mdio_device *)bus->priv;
+
+	ret = hns_mdio_read_hw(mdio_dev, phy_id, is_c45, devad,
+			       (u16)(regnum & 0xffff), &reg_val);
+	if (ret) {
+		dev_err(&bus->dev, "read_phy_reg fail, mdio_idx=%d, phy_id=%d, devad=%d,regnum=%#x!\n",
+			mdio_dev->gidx,	phy_id, devad, regnum);
+
+		return ret;
+	}
+
+	return reg_val;
+}
+
+/**
+ * hns_mdio_reset - reset mdio bus
+ * @bus: mdio bus
+ *
+ * Return 0 on success, negative on failure
+ */
+static int hns_mdio_reset(struct mii_bus *bus)
+{
+	return 0;
+}
+
+/**
+ * hns_mdio_bus_name - get mdio bus name
+ * @name: mdio bus name
+ * @np: mdio device node pointer
+ */
+static void hns_mdio_bus_name(char *name, struct device_node *np)
+{
+	const u32 *addr;
+	u64 taddr = OF_BAD_ADDR;
+
+	addr = of_get_address(np, 0, NULL, NULL);
+	if (addr)
+		taddr = of_translate_address(np, addr);
+
+	snprintf(name, MII_BUS_ID_SIZE, "%s@%llx", np->name,
+		 (unsigned long long)taddr);
+}
+
+/**
+ * hns_mdio_probe - probe mdio device
+ * @pdev: mdio platform device
+ *
+ * Return 0 on success, negative on failure
+ */
+static int hns_mdio_probe(struct platform_device *pdev)
+{
+	struct device_node *np;
+	struct hns_mdio_device *mdio_dev;
+	struct mii_bus *new_bus;
+	struct resource *res;
+	int ret;
+
+	if (!pdev) {
+		dev_err(NULL, "pdev is NULL!\r\n");
+		return -ENODEV;
+	}
+	np = pdev->dev.of_node;
+	mdio_dev = devm_kzalloc(&pdev->dev, sizeof(*mdio_dev), GFP_KERNEL);
+	if (!mdio_dev)
+		return -ENOMEM;
+
+	new_bus = devm_mdiobus_alloc(&pdev->dev);
+	if (!new_bus) {
+		dev_err(&pdev->dev, "mdiobus_alloc fail!\n");
+		return -ENOMEM;
+	}
+
+	new_bus->name = MDIO_BUS_NAME;
+	new_bus->read = hns_mdio_read;
+	new_bus->write = hns_mdio_write;
+	new_bus->reset = hns_mdio_reset;
+	new_bus->priv = mdio_dev;
+	hns_mdio_bus_name(new_bus->id, np);
+
+	res = platform_get_resource(pdev, IORESOURCE_MEM, 0);
+	mdio_dev->vbase = devm_ioremap_resource(&pdev->dev, res);
+	if (IS_ERR(mdio_dev->vbase)) {
+		ret = PTR_ERR(mdio_dev->vbase);
+		return -EFAULT;
+	}
+	mdio_dev->index = 0;
+	mdio_dev->chip_id = hns_mdio_get_chip_id(pdev);
+	mdio_dev->gidx = mdio_dev->chip_id;
+	mdio_dev->dev = &pdev->dev;
+
+	new_bus->irq = devm_kcalloc(&pdev->dev, PHY_MAX_ADDR,
+				    sizeof(int), GFP_KERNEL);
+	if (!new_bus->irq)
+		return -ENOMEM;
+
+	new_bus->parent = &pdev->dev;
+	platform_set_drvdata(pdev, new_bus);
+
+	ret = of_mdiobus_register(new_bus, np);
+	if (ret) {
+		dev_err(&pdev->dev, "Cannot register as MDIO bus!\n");
+		platform_set_drvdata(pdev, NULL);
+		return ret;
+	}
+
+	return 0;
+}
+
+/**
+ * hns_mdio_remove - remove mdio device
+ * @pdev: mdio platform device
+ *
+ * Return 0 on success, negative on failure
+ */
+static int hns_mdio_remove(struct platform_device *pdev)
+{
+	struct hns_mdio_device *mdio_dev;
+	struct mii_bus *bus;
+
+	bus = platform_get_drvdata(pdev);
+	mdio_dev = (struct hns_mdio_device *)bus->priv;
+
+	mdiobus_unregister(bus);
+	platform_set_drvdata(pdev, NULL);
+	return 0;
+}
+
+static const struct of_device_id hns_mdio_match[] = {
+	{.compatible = "hisilicon,mdio"},
+	{}
+};
+
+static struct platform_driver hns_mdio_driver = {
+	.probe = hns_mdio_probe,
+	.remove = hns_mdio_remove,
+	.driver = {
+		   .name = MDIO_DRV_NAME,
+		   .of_match_table = hns_mdio_match,
+		   },
+};
+
+module_platform_driver(hns_mdio_driver);
+
+MODULE_LICENSE("GPL");
+MODULE_AUTHOR("Huawei Tech. Co., Ltd.");
+MODULE_DESCRIPTION("Hisilicon HNS MDIO driver");
+MODULE_ALIAS("platform:" MDIO_DRV_NAME);
-- 
1.9.1



From liguozhu at hisilicon.com  Fri Aug 14 03:30:18 2015
From: liguozhu at hisilicon.com (Kenneth Lee)
Date: Fri, 14 Aug 2015 18:30:18 +0800
Subject: [PATCH 1/5] net: add Hisilicon Network Subsystem support (config and
 documents)
In-Reply-To: <1439548222-231611-1-git-send-email-liguozhu@hisilicon.com>
References: <1439548222-231611-1-git-send-email-liguozhu@hisilicon.com>
Message-ID: <1439548222-231611-2-git-send-email-liguozhu@hisilicon.com>

The Hisilicon Network Subsystem is a long term evolution IP which is
supposed to be used in Hisilicon ICT SoC. The IP, which is called hns for
short, is a TCP/IP acceleration engine, which can directly decode TCP/IP
stream and distribute them to different ring buffers.

HNS can be configured to work on different mode for different scenario.
This patch make use only some of the mode to make it as standard ethernet
NIC.  The other mode will be added soon.

The whole function has 4 kernel sub-modules:

hnae: the HNS acceleration engine framework. It provides a abstract
interface between the engine and the upper layers which make use of the
engine by ring buffer.

hns_enet_drv: a standard ethernet driver that base on the ring buffer.

hns_dsaf: one of the implementation of HNS acceleration engine, which is
applied on Hililicon P660, Hi1610 and other later-on SoCs

hns_mdio: the mdio control to the PHY, used by acceleration engine

This submit add basic config and documents

Signed-off-by: Kenneth Lee <liguozhu at huawei.com>
Signed-off-by: Yisen Zhuang <Yisen.Zhuang at huawei.com>
---
 .../devicetree/bindings/net/hisilicon-hns-dsaf.txt |  40 +++++
 .../devicetree/bindings/net/hisilicon-hns-mdio.txt |  22 +++
 .../devicetree/bindings/net/hisilicon-hns-nic.txt  |  14 ++
 arch/arm64/boot/dts/hisilicon/hip05_hns.dtsi       | 197 +++++++++++++++++++++
 4 files changed, 273 insertions(+)
 create mode 100644 Documentation/devicetree/bindings/net/hisilicon-hns-dsaf.txt
 create mode 100644 Documentation/devicetree/bindings/net/hisilicon-hns-mdio.txt
 create mode 100644 Documentation/devicetree/bindings/net/hisilicon-hns-nic.txt
 create mode 100644 arch/arm64/boot/dts/hisilicon/hip05_hns.dtsi

diff --git a/Documentation/devicetree/bindings/net/hisilicon-hns-dsaf.txt b/Documentation/devicetree/bindings/net/hisilicon-hns-dsaf.txt
new file mode 100644
index 0000000..038c03d
--- /dev/null
+++ b/Documentation/devicetree/bindings/net/hisilicon-hns-dsaf.txt
@@ -0,0 +1,40 @@
+Hisilicon DSA Fabric device controller
+
+Required properties:
+- compatible: should be "hisilicon,dsaf".
+- dsa-name: dsa fabric name who provide this interface
+- interrupt-parent: the interrupt parent of this device.
+- interrupts: should contain the DSA Fabric and rcb interrupt.
+- reg: specifies base physical address(es) and size of the device registers.
+  The first region is external interface control register base and size.
+  The second region is SerDes base register and size.
+  The third region is the PPE register base and size.
+  The fourth region is dsa fabric base register and size.
+- phy-handle: phy handle of physicl port, 0 if not any phy device. see ethernet.txt [1].
+- buf-size: rx buffer size, should be 16-1024.
+- desc-num: number of description in TX and RX queue, should be 512, 1024, 2048 or 4096.
+
+[1] Documentation/devicetree/bindings/net/phy.txt
+
+Example:
+
+dsa: dsa at c7000000 {
+	compatible = "hisilicon,dsaf";
+	dsa_name = "soc0-n4";
+	interrupt-parent = <&mbigen_dsa>;
+	reg = <0x0 0xC0000000 0x0 0x420000
+	       0x0 0xC2000000 0x0 0x300000
+	       0x0 0xc5000000 0x0 0x890000
+	       0x0 0xc7000000 0x0 0x60000>;
+	phy-handle = <0 0 0 0 &soc0_phy4 &soc0_phy5 0 0>;
+	interrupts = <131 4>,<132 4>, <133 4>,<134 4>,
+		     <135 4>,<136 4>, <137 4>,<138 4>,
+		     <139 4>,<140 4>, <141 4>,<142 4>,
+		     <143 4>,<144 4>, <145 4>,<146 4>,
+		     <147 4>,<148 4>, <384 1>,<385 1>,
+		     <386 1>,<387 1>, <388 1>,<389 1>,
+		     <390 1>,<391 1>,
+	buf-size = <4096>;
+	desc-num = <1024>;
+	dma-coherent;
+};
diff --git a/Documentation/devicetree/bindings/net/hisilicon-hns-mdio.txt b/Documentation/devicetree/bindings/net/hisilicon-hns-mdio.txt
new file mode 100644
index 0000000..205e803
--- /dev/null
+++ b/Documentation/devicetree/bindings/net/hisilicon-hns-mdio.txt
@@ -0,0 +1,22 @@
+Hisilicon MDIO bus controller
+
+Properties:
+- compatible: "hisilicon,mdio"
+- reg: The base address of the MDIO bus controller register bank.
+- #address-cells: Must be <1>.
+- #size-cells: Must be <0>.  MDIO addresses have no size component.
+
+Typically an MDIO bus might have several children.
+
+Example:
+         mdio at 803c0000 {
+                   #address-cells = <1>;
+                   #size-cells = <0>;
+                   compatible = "hisilicon,mdio";
+                   reg = <0x0 0x803c0000 0x0 0x10000>;
+
+                   ethernet-phy at 0 {
+                            ...
+                            reg = <0>;
+                   };
+         };
diff --git a/Documentation/devicetree/bindings/net/hisilicon-hns-nic.txt b/Documentation/devicetree/bindings/net/hisilicon-hns-nic.txt
new file mode 100644
index 0000000..5ab6969
--- /dev/null
+++ b/Documentation/devicetree/bindings/net/hisilicon-hns-nic.txt
@@ -0,0 +1,14 @@
+Hisilicon Network Subsystem NIC controller
+
+Required properties:
+- compatible: hisilicon,hns-nic
+- ae-name: accelerator name who provide this interface
+- ae-opts: options (string) to the accelerator. e.g. the index interface
+
+Example:
+
+	ethernet at 0{
+		compatible = "hisilicon,hns-nic";
+		ae-name = "soc0-n4";
+		ae-opts = "0";
+	};
diff --git a/arch/arm64/boot/dts/hisilicon/hip05_hns.dtsi b/arch/arm64/boot/dts/hisilicon/hip05_hns.dtsi
new file mode 100644
index 0000000..80fd017
--- /dev/null
+++ b/arch/arm64/boot/dts/hisilicon/hip05_hns.dtsi
@@ -0,0 +1,197 @@
+soc0: soc at 000000000 {
+	#address-cells = <2>;
+	#size-cells = <2>;
+	device_type = "soc";
+	compatible = "simple-bus";
+	ranges = <0x0 0x0 0x0 0x0 0x1 0x0>;
+	chip-id = <0>;
+
+	soc0_mdio0: mdio at 803c0000 {
+		#address-cells = <1>;
+		#size-cells = <0>;
+		compatible = "hisilicon,mdio";
+		reg = <0x0 0x803c0000 0x0 0x10000>;
+		irq-num = <9383>;
+
+		soc0_phy4: ethernet-phy at 4 {
+			reg = <0x0>;
+			device_type = "ethernet-phy";
+			compatible = "ethernet-phy-ieee802.3-c22";
+		};
+		soc0_phy5: ethernet-phy at 5 {
+			reg = <0x1>;
+			device_type = "ethernet-phy";
+			compatible = "ethernet-phy-ieee802.3-c22";
+		};
+	};
+
+	dsa: dsa at c7000000 {
+		compatible = "hisilicon,dsaf";
+		dsa_name = "soc0-n4";
+		interrupt-parent = <&mbigen_dsa>;
+
+		reg = <0x0 0xC0000000 0x0 0x420000
+		       0x0 0xC2000000 0x0 0x300000
+		       0x0 0xc5000000 0x0 0x890000
+		       0x0 0xc7000000 0x0 0x60000
+		       >;
+
+		phy-handle = <0 0 0 0 &soc0_phy4 &soc0_phy5 0 0>;
+
+		interrupts =	<131 4>,<132 4>, /* 0 : dsa 0 -17  */
+				<133 4>,<134 4>,
+				<135 4>,<136 4>,
+				<137 4>,<138 4>,
+				<139 4>,<140 4>,
+				<141 4>,<142 4>,
+				<143 4>,<144 4>,
+				<145 4>,<146 4>,
+				<147 4>,<148 4>, /* 17 :dsa end   */
+				<384 1>,<385 1>, /* 18: rcb 0  16*2*6  */
+				<386 1>,<387 1>,
+				<388 1>,<389 1>,
+				<390 1>,<391 1>,
+				<392 1>,<393 1>,
+				<394 1>,<395 1>,
+				<396 1>,<397 1>,
+				<398 1>,<399 1>,
+				<400 1>,<401 1>,
+				<402 1>,<403 1>,
+				<404 1>,<405 1>,
+				<406 1>,<407 1>,
+				<408 1>,<409 1>,
+				<410 1>,<411 1>,
+				<412 1>,<413 1>,
+				<414 1>,<415 1>, /*    */
+				<416 1>,<417 1>,
+				<418 1>,<419 1>,
+				<420 1>,<421 1>,
+				<422 1>,<423 1>,
+				<424 1>,<425 1>,
+				<426 1>,<427 1>,
+				<428 1>,<429 1>,
+				<430 1>,<431 1>,
+				<432 1>,<433 1>,
+				<434 1>,<435 1>,
+				<436 1>,<437 1>,
+				<438 1>,<439 1>,
+				<440 1>,<441 1>,
+				<442 1>,<443 1>,
+				<444 1>,<445 1>,
+				<446 1>,<447 1>,
+				<448 1>,<449 1>,
+				<450 1>,<451 1>,
+				<452 1>,<453 1>,
+				<454 1>,<455 1>,
+				<456 1>,<457 1>,
+				<458 1>,<459 1>,
+				<460 1>,<461 1>,
+				<462 1>,<463 1>,
+				<464 1>,<465 1>,
+				<466 1>,<467 1>,
+				<468 1>,<469 1>,
+				<470 1>,<471 1>,
+				<472 1>,<473 1>,
+				<474 1>,<475 1>,
+				<476 1>,<477 1>,
+				<478 1>,<479 1>,
+				<480 1>,<481 1>,
+				<482 1>,<483 1>,
+				<484 1>,<485 1>,
+				<486 1>,<487 1>,
+				<488 1>,<489 1>,
+				<490 1>,<491 1>,
+				<492 1>,<493 1>,
+				<494 1>,<495 1>,
+				<496 1>,<497 1>,
+				<498 1>,<499 1>,
+				<500 1>,<501 1>,
+				<502 1>,<503 1>,
+				<504 1>,<505 1>,
+				<506 1>,<507 1>,
+				<508 1>,<509 1>,
+				<510 1>,<511 1>,
+				<512 1>,<513 1>,
+				<514 1>,<515 1>,
+				<516 1>,<517 1>,
+				<518 1>,<519 1>,
+				<520 1>,<521 1>,
+				<522 1>,<523 1>,
+				<524 1>,<525 1>,
+				<526 1>,<527 1>,
+				<528 1>,<529 1>,
+				<530 1>,<531 1>,
+				<532 1>,<533 1>,
+				<534 1>,<535 1>,
+				<536 1>,<537 1>,
+				<538 1>,<539 1>,
+				<540 1>,<541 1>,
+				<542 1>,<543 1>,
+				<544 1>,<545 1>,
+				<546 1>,<547 1>,
+				<548 1>,<549 1>,
+				<550 1>,<551 1>,
+				<552 1>,<553 1>,
+				<554 1>,<555 1>,
+				<556 1>,<557 1>,
+				<558 1>,<559 1>,
+				<560 1>,<561 1>,
+				<562 1>,<563 1>,
+				<564 1>,<565 1>,
+				<566 1>,<567 1>,
+				<568 1>,<569 1>,
+				<570 1>,<571 1>,
+				<572 1>,<573 1>,
+				<574 1>,<575 1>, /* rcb 96*2end  */
+				<14  1>,<15  1>,
+				<20  1>,<21  1>;
+		buf-size = <4096>;
+		desc-num = <1024>;
+		dma-coherent;
+	};
+
+	ethernet at 0{
+		compatible = "hisilicon,hns-nic";
+		ae-name = "soc0-n4";
+		ae-opts = "0";
+	};
+	ethernet at 1{
+		compatible = "hisilicon,hns-nic";
+		ae-name = "soc0-n4";
+		ae-opts = "1";
+	};
+	ethernet at 2{
+		compatible = "hisilicon,hns-nic";
+		ae-name = "soc0-n4";
+		ae-opts = "2";
+	};
+	ethernet at 3{
+		compatible = "hisilicon,hns-nic";
+		ae-name = "soc0-n4";
+		ae-opts = "3";
+	};
+	ethernet at 4{
+		compatible = "hisilicon,hns-nic";
+		ae-name = "soc0-n4";
+		ae-opts = "4";
+	};
+	ethernet at 5{
+		compatible = "hisilicon,hns-nic";
+		ae-name = "soc0-n4";
+		ae-opts = "5";
+	};
+	ethernet at 6{
+		compatible = "hisilicon,hns-nic";
+		ae-name = "soc0-n4";
+		ae-opts = "6";
+	};
+	ethernet at 7{
+		compatible = "hisilicon,hns-nic";
+		ae-name = "soc0-n4";
+		ae-opts = "7";
+	};
+
+
+
+
+};
-- 
1.9.1



From liguozhu at hisilicon.com  Fri Aug 14 03:30:19 2015
From: liguozhu at hisilicon.com (Kenneth Lee)
Date: Fri, 14 Aug 2015 18:30:19 +0800
Subject: [PATCH 2/5] net: add Hisilicon Network Subsystem hnae framework
 support
In-Reply-To: <1439548222-231611-1-git-send-email-liguozhu@hisilicon.com>
References: <1439548222-231611-1-git-send-email-liguozhu@hisilicon.com>
Message-ID: <1439548222-231611-3-git-send-email-liguozhu@hisilicon.com>

HNAE (Hisilicon Network Acceleration Engine) is a framework to provide a
unified ring buffer interface for Hisilicon Network Acceleration Engines.

With the interface, upper layer can work as ethernet driver, ODP driver or
other service driver on purpose.

Signed-off-by: Kenneth Lee <liguozhu at huawei.com>
Signed-off-by: Yisen Zhuang <Yisen.Zhuang at huawei.com>
---
 drivers/net/ethernet/hisilicon/Kconfig      |  33 +-
 drivers/net/ethernet/hisilicon/Makefile     |   1 +
 drivers/net/ethernet/hisilicon/hns/Makefile |  15 +
 drivers/net/ethernet/hisilicon/hns/hnae.c   | 494 +++++++++++++++++++++++
 drivers/net/ethernet/hisilicon/hns/hnae.h   | 582 ++++++++++++++++++++++++++++
 5 files changed, 1124 insertions(+), 1 deletion(-)
 create mode 100644 drivers/net/ethernet/hisilicon/hns/Makefile
 create mode 100644 drivers/net/ethernet/hisilicon/hns/hnae.c
 create mode 100644 drivers/net/ethernet/hisilicon/hns/hnae.h

diff --git a/drivers/net/ethernet/hisilicon/Kconfig b/drivers/net/ethernet/hisilicon/Kconfig
index dead17b..1e4f5a7 100644
--- a/drivers/net/ethernet/hisilicon/Kconfig
+++ b/drivers/net/ethernet/hisilicon/Kconfig
@@ -5,7 +5,7 @@
 config NET_VENDOR_HISILICON
 	bool "Hisilicon devices"
 	default y
-	depends on ARM
+	depends on ARM || ARM64
 	---help---
 	  If you have a network (Ethernet) card belonging to this class, say Y.
 
@@ -31,4 +31,35 @@ config HIP04_ETH
 	  If you wish to compile a kernel for a hardware with hisilicon p04 SoC and
 	  want to use the internal ethernet then you should answer Y to this.
 
+config HNS
+	tristate "Hisilicon Network Subsystem Support (Framework)"
+	---help---
+	  This selects the framework support for Hisilicon Network Subsystem. It
+	  is needed by any driver which provides HNS acceleration engine or make
+	  use of the engine
+
+config HNS_DSAF
+	tristate "Hisilicon HNS DSAF device Support"
+	select HNS
+	select HNS_MDIO
+	---help---
+	  This selects the DSAF (Distributed System Area Frabric) network
+	  acceleration engine support. The engine is used in Hisilicon P660,
+	  Hi1610 and further ICT SoC
+
+config HNS_MDIO
+	tristate "Hisilicon HNS MDIO device Support"
+	select MDIO
+	---help---
+	  This selects the HNS MDIO support. It is needed by HNS_DSAF to access
+	  the PHY
+
+config HNS_ENET
+	tristate "Hisilicon HNS Ethernet Device Support"
+	select PHYLIB
+	select HNS
+	---help---
+	  This selects the general ethernet driver for HNS.  This module make
+	  use of any HNS AE driver, such as HNS_DSAF
+
 endif # NET_VENDOR_HISILICON
diff --git a/drivers/net/ethernet/hisilicon/Makefile b/drivers/net/ethernet/hisilicon/Makefile
index 6c14540..2503a9b 100644
--- a/drivers/net/ethernet/hisilicon/Makefile
+++ b/drivers/net/ethernet/hisilicon/Makefile
@@ -4,3 +4,4 @@
 
 obj-$(CONFIG_HIX5HD2_GMAC) += hix5hd2_gmac.o
 obj-$(CONFIG_HIP04_ETH) += hip04_mdio.o hip04_eth.o
+obj-$(CONFIG_HNS) += hns/
diff --git a/drivers/net/ethernet/hisilicon/hns/Makefile b/drivers/net/ethernet/hisilicon/hns/Makefile
new file mode 100644
index 0000000..6680602
--- /dev/null
+++ b/drivers/net/ethernet/hisilicon/hns/Makefile
@@ -0,0 +1,15 @@
+#
+# Makefile for the HISILICON network device drivers.
+#
+
+obj-$(CONFIG_HNS) += hnae.o
+
+obj-$(CONFIG_HNS_DSAF) += hns_dsaf.o
+hns_dsaf-objs = hns_ae_adapt.o hns_dsaf_gmac.o hns_dsaf_mac.o hns_dsaf_misc.o \
+	hns_dsaf_main.o hns_dsaf_ppe.o hns_dsaf_rcb.o hns_dsaf_xgmac.o
+
+obj-$(CONFIG_HNS_MDIO) += hns_mdio.o
+hns_mdio-objs = hns_mdio_main.o
+
+obj-$(CONFIG_HNS_ENET) += hns_enet_drv.o
+hns_enet_drv-objs = hns_enet.o hns_ethtool.o
diff --git a/drivers/net/ethernet/hisilicon/hns/hnae.c b/drivers/net/ethernet/hisilicon/hns/hnae.c
new file mode 100644
index 0000000..fd09768
--- /dev/null
+++ b/drivers/net/ethernet/hisilicon/hns/hnae.c
@@ -0,0 +1,494 @@
+/*
+ * Copyright (c) 2014-2015 Hisilicon Limited.
+ *
+ * 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.
+ */
+
+#include <linux/dma-mapping.h>
+#include <linux/interrupt.h>
+#include <linux/skbuff.h>
+#include <linux/slab.h>
+
+#include "hnae.h"
+
+#define cls_to_ae_dev(dev) container_of(dev, struct hnae_ae_dev, cls_dev)
+
+static struct class *hnae_class;
+
+static inline void hnae_list_add(spinlock_t *lock, struct list_head *node,
+				 struct list_head *head)
+{
+	unsigned long flags;
+
+	spin_lock_irqsave(lock, flags);
+	list_add_tail_rcu(node, head);
+	spin_unlock_irqrestore(lock, flags);
+}
+
+static inline void hnae_list_del(spinlock_t *lock, struct list_head *node)
+{
+	unsigned long flags;
+
+	spin_lock_irqsave(lock, flags);
+	list_del_rcu(node);
+	spin_unlock_irqrestore(lock, flags);
+}
+
+static int hnae_alloc_buffer(struct hnae_ring *ring, struct hnae_desc_cb *cb)
+{
+	unsigned int order = hnae_page_order(ring);
+	struct page *p = dev_alloc_pages(order);
+
+	if (!p)
+		return -ENOMEM;
+
+	cb->priv = p;
+	cb->page_offset = 0;
+	cb->reuse_flag = 0;
+	cb->buf  = page_address(p);
+	cb->length = hnae_page_size(ring);
+	cb->type = DESC_TYPE_PAGE;
+
+	return 0;
+}
+
+static void hnae_free_buffer(struct hnae_ring *ring, struct hnae_desc_cb *cb)
+{
+	if (cb->type == DESC_TYPE_SKB)
+		dev_kfree_skb_any((struct sk_buff *)cb->priv);
+	else if (unlikely(is_rx_ring(ring)))
+		put_page((struct page *)cb->priv);
+	memset(cb, 0, sizeof(*cb));
+}
+
+static int hnae_map_buffer(struct hnae_ring *ring, struct hnae_desc_cb *cb)
+{
+	cb->dma = dma_map_page(ring_to_dev(ring), cb->priv, 0,
+			       cb->length, ring_to_dma_dir(ring));
+
+	if (dma_mapping_error(ring_to_dev(ring), cb->dma))
+		return -EIO;
+
+	return 0;
+}
+
+static void hnae_unmap_buffer(struct hnae_ring *ring, struct hnae_desc_cb *cb)
+{
+	if (cb->type == DESC_TYPE_SKB)
+		dma_unmap_single(ring_to_dev(ring), cb->dma, cb->length,
+				 ring_to_dma_dir(ring));
+	else
+		dma_unmap_page(ring_to_dev(ring), cb->dma, cb->length,
+			       ring_to_dma_dir(ring));
+}
+
+static struct hnae_buf_ops hnae_bops = {
+	.alloc_buffer = hnae_alloc_buffer,
+	.free_buffer = hnae_free_buffer,
+	.map_buffer = hnae_map_buffer,
+	.unmap_buffer = hnae_unmap_buffer,
+};
+
+static int __ae_match(struct device *dev, const void *data)
+{
+	struct hnae_ae_dev *hdev = cls_to_ae_dev(dev);
+	const char *ae_id = data;
+
+	if (!strncmp(ae_id, hdev->name, AE_NAME_SIZE))
+		return 1;
+
+	return 0;
+}
+
+static struct hnae_ae_dev *find_ae(const char *ae_id)
+{
+	struct device *dev;
+
+	BUG_ON(!ae_id);
+
+	dev = class_find_device(hnae_class, NULL, ae_id, __ae_match);
+
+	return cls_to_ae_dev(dev);
+}
+
+static void hnae_free_buffers(struct hnae_ring *ring)
+{
+	int i;
+
+	for (i = 0; i < ring->desc_num; i++)
+		hnae_free_buffer_detach(ring, i);
+}
+
+/* Allocate memory for raw pkg, and map with dma */
+static int hnae_alloc_buffers(struct hnae_ring *ring)
+{
+	int i, j, ret;
+
+	for (i = 0; i < ring->desc_num; i++) {
+		ret = hnae_alloc_buffer_attach(ring, i);
+		if (ret)
+			goto out_buffer_fail;
+	}
+
+	return 0;
+
+out_buffer_fail:
+	for (j = i - 1; j >= 0; j--)
+		hnae_free_buffer_detach(ring, j);
+	return ret;
+}
+
+/* free desc along with its attached buffer */
+static inline void hnae_free_desc(struct hnae_ring *ring)
+{
+	hnae_free_buffers(ring);
+	dma_unmap_single(ring_to_dev(ring), ring->desc_dma_addr,
+			 ring->desc_num * sizeof(ring->desc[0]),
+			 ring_to_dma_dir(ring));
+	ring->desc_dma_addr = 0;
+	kfree(ring->desc);
+	ring->desc = NULL;
+}
+
+/* alloc desc, without buffer attached */
+static inline int hnae_alloc_desc(struct hnae_ring *ring)
+{
+	int size = ring->desc_num * sizeof(ring->desc[0]);
+
+	ring->desc = kzalloc(size, GFP_KERNEL);
+	if (!ring->desc)
+		return -ENOMEM;
+
+	ring->desc_dma_addr = dma_map_single(ring_to_dev(ring),
+		ring->desc, size, ring_to_dma_dir(ring));
+	if (dma_mapping_error(ring_to_dev(ring), ring->desc_dma_addr)) {
+		ring->desc_dma_addr = 0;
+		kfree(ring->desc);
+		ring->desc = NULL;
+		return -ENOMEM;
+	}
+
+	return 0;
+}
+
+/* fini ring, also free the buffer for the ring */
+static inline void hnae_fini_ring(struct hnae_ring *ring)
+{
+	hnae_free_desc(ring);
+	kfree(ring->desc_cb);
+	ring->desc_cb = NULL;
+	ring->next_to_clean = 0;
+	ring->next_to_use = 0;
+}
+
+/* init ring, and with buffer for rx ring */
+static inline int hnae_init_ring(struct hnae_queue *q, struct hnae_ring *ring,
+				 int flags)
+{
+	int ret;
+
+	if (ring->desc_num <= 0 || ring->buf_size <= 0)
+		return -EINVAL;
+
+	ring->q = q;
+	ring->flags = flags;
+	assert(!ring->desc && !ring->desc_cb && !ring->desc_dma_addr);
+
+	/* not matter for tx or rx ring, the ntc and ntc start from 0 */
+	assert(ring->next_to_use == 0);
+	assert(ring->next_to_clean == 0);
+
+	ring->desc_cb = kcalloc(ring->desc_num, sizeof(ring->desc_cb[0]),
+			GFP_KERNEL);
+	if (!ring->desc_cb) {
+		ret = -ENOMEM;
+		goto out;
+	}
+
+	ret = hnae_alloc_desc(ring);
+	if (ret)
+		goto out_with_desc_cb;
+
+	if (is_rx_ring(ring)) {
+		ret = hnae_alloc_buffers(ring);
+		if (ret)
+			goto out_with_desc;
+	}
+
+	return 0;
+
+out_with_desc:
+	hnae_free_desc(ring);
+out_with_desc_cb:
+	kfree(ring->desc_cb);
+	ring->desc_cb = NULL;
+out:
+	return ret;
+}
+
+static inline int hnae_init_queue(struct hnae_handle *h, struct hnae_queue *q,
+				  struct hnae_ae_dev *dev)
+{
+	int ret;
+
+	q->dev = dev;
+	q->handle = h;
+
+	ret = hnae_init_ring(q, &q->tx_ring, q->tx_ring.flags | RINGF_DIR);
+	if (ret)
+		goto out;
+
+	ret = hnae_init_ring(q, &q->rx_ring, q->rx_ring.flags & ~RINGF_DIR);
+	if (ret)
+		goto out_with_tx_ring;
+
+	if (dev->ops->init_queue)
+		dev->ops->init_queue(q);
+
+	return 0;
+
+out_with_tx_ring:
+	hnae_fini_ring(&q->tx_ring);
+out:
+	return ret;
+}
+
+static inline void hnae_fini_queue(struct hnae_queue *q)
+{
+	if (q->dev->ops->fini_queue)
+		q->dev->ops->fini_queue(q);
+
+	hnae_fini_ring(&q->tx_ring);
+	hnae_fini_ring(&q->rx_ring);
+}
+
+/**
+ * ae_chain - define ae chain head
+ */
+static RAW_NOTIFIER_HEAD(ae_chain);
+
+int hnae_register_notifier(struct notifier_block *nb)
+{
+	return raw_notifier_chain_register(&ae_chain, nb);
+}
+EXPORT_SYMBOL(hnae_register_notifier);
+
+void hnae_unregister_notifier(struct notifier_block *nb)
+{
+	if (raw_notifier_chain_unregister(&ae_chain, nb))
+		dev_err(NULL, "notifier chain unregister fail\n");
+}
+EXPORT_SYMBOL(hnae_unregister_notifier);
+
+int hnae_reinit_handle(struct hnae_handle *handle)
+{
+	int i, j;
+	int ret;
+
+	for (i = 0; i < handle->q_num; i++) /* free ring*/
+		hnae_fini_queue(handle->qs[i]);
+
+	for (i = 0; i < handle->q_num; i++) {/* reinit ring*/
+		ret = hnae_init_queue(handle, handle->qs[i], handle->dev);
+		if (ret)
+			goto out_when_init_queue;
+	}
+	return 0;
+out_when_init_queue:
+	for (j = i - 1; j >= 0; j--)
+		hnae_fini_queue(handle->qs[j]);
+	return ret;
+}
+EXPORT_SYMBOL(hnae_reinit_handle);
+
+/* hnae_get_handle - get a handle from the AE
+ * @owner_dev: the dev use this handle
+ * @ae_id: the id of the ae to be used
+ * @ae_opts: the options set for the handle
+ * @bops: the callbacks for buffer management
+ *
+ * return handle ptr or ERR_PTR
+ */
+struct hnae_handle *hnae_get_handle(struct device *owner_dev,
+				    const char *ae_id, const char *ae_opts,
+				    struct hnae_buf_ops *bops)
+{
+	struct hnae_ae_dev *dev;
+	struct hnae_handle *handle;
+	int i, j;
+	int ret;
+
+	dev = find_ae(ae_id);
+	if (!dev)
+		return ERR_PTR(-ENODEV);
+
+	handle = dev->ops->get_handle(dev, ae_opts);
+	if (IS_ERR(handle))
+		return handle;
+
+	handle->dev = dev;
+	handle->owner_dev = owner_dev;
+	handle->bops = bops ? bops : &hnae_bops;
+	handle->ae_opts = ae_opts;
+
+	for (i = 0; i < handle->q_num; i++) {
+		ret = hnae_init_queue(handle, handle->qs[i], dev);
+		if (ret)
+			goto out_when_init_queue;
+	}
+
+	__module_get(dev->owner);
+
+	hnae_list_add(&dev->lock, &handle->node, &dev->handle_list);
+
+	return handle;
+
+out_when_init_queue:
+	for (j = i - 1; j >= 0; j--)
+		hnae_fini_queue(handle->qs[j]);
+
+	return ERR_PTR(-ENOMEM);
+}
+EXPORT_SYMBOL(hnae_get_handle);
+
+void hnae_put_handle(struct hnae_handle *h)
+{
+	struct hnae_ae_dev *dev = h->dev;
+	int i;
+
+	for (i = 0; i < h->q_num; i++)
+		hnae_fini_queue(h->qs[i]);
+
+	hnae_list_del(&dev->lock, &h->node);
+
+	if (dev->ops->put_handle)
+		dev->ops->put_handle(h);
+
+	module_put(dev->owner);
+}
+EXPORT_SYMBOL(hnae_put_handle);
+
+static void __hnae_release(struct device *dev)
+{
+}
+
+/**
+ * hnae_ae_register - register a AE engine to hnae framework
+ * @hdev: the hnae ae engine device
+ * @owner:  the module who provides this dev
+ * NOTE: the duplicated name will not be checked
+ */
+int hnae_ae_register(struct hnae_ae_dev *hdev, struct module *owner)
+{
+	static atomic_t id = ATOMIC_INIT(-1);
+	int ret;
+
+	if (!hdev->dev)
+		return -ENODEV;
+
+	if (!hdev->ops || !hdev->ops->get_handle ||
+	    !hdev->ops->toggle_ring_irq ||
+	    !hdev->ops->toggle_queue_status ||
+	    !hdev->ops->get_status || !hdev->ops->adjust_link)
+		return -EINVAL;
+
+	hdev->owner = owner;
+	hdev->id = (int)atomic_inc_return(&id);
+	hdev->cls_dev.parent = hdev->dev;
+	hdev->cls_dev.class = hnae_class;
+	hdev->cls_dev.release = __hnae_release;
+	dev_set_name(&hdev->cls_dev, "hnae%d", hdev->id);
+	ret = device_register(&hdev->cls_dev);
+	if (ret)
+		return ret;
+
+	__module_get(THIS_MODULE);
+
+	INIT_LIST_HEAD(&hdev->handle_list);
+	spin_lock_init(&hdev->lock);
+
+	ret = raw_notifier_call_chain(&ae_chain, HNAE_AE_REGISTER, NULL);
+	if (ret)
+		dev_dbg(hdev->dev,
+			"has not notifier for AE: %s\n", hdev->name);
+
+	return 0;
+}
+EXPORT_SYMBOL(hnae_ae_register);
+
+/**
+ * hnae_ae_unregister - unregisters a HNAE AE engine
+ * @cdev: the device to unregister
+ */
+void hnae_ae_unregister(struct hnae_ae_dev *hdev)
+{
+	device_unregister(&hdev->cls_dev);
+	module_put(THIS_MODULE);
+}
+EXPORT_SYMBOL(hnae_ae_unregister);
+
+static ssize_t handles_show(struct device *dev,
+			    struct device_attribute *attr, char *buf)
+{
+	ssize_t s = 0;
+	struct hnae_ae_dev *hdev = cls_to_ae_dev(dev);
+	struct hnae_handle *h;
+	int i = 0, j;
+
+	list_for_each_entry_rcu(h, &hdev->handle_list, node) {
+		s += sprintf(buf + s, "%s(%s): ", dev_name(h->owner_dev),
+			     h->ae_opts);
+		for (j = 0; j < h->q_num; j++) {
+			if (h->qs[i]) {
+				s += sprintf(buf + s,
+					"(%llu,%llu; ",
+					h->qs[i]->tx_ring.stats.sw_err_cnt,
+					h->qs[i]->tx_ring.stats.io_err_cnt);
+				s += sprintf(buf + s,
+					"%llu,%llu,%llu), ",
+					h->qs[i]->rx_ring.stats.sw_err_cnt,
+					h->qs[i]->rx_ring.stats.io_err_cnt,
+					h->qs[i]->rx_ring.stats.seg_pkt_cnt);
+			} else {
+				s += sprintf(buf + s, "(null)\n");
+			}
+		}
+		s += sprintf(buf + s, "\n");
+	}
+
+	return s;
+}
+
+static DEVICE_ATTR_RO(handles);
+static struct attribute *hnae_class_attrs[] = {
+	&dev_attr_handles.attr,
+	NULL,
+};
+ATTRIBUTE_GROUPS(hnae_class);
+
+static int __init hnae_init(void)
+{
+	hnae_class = class_create(THIS_MODULE, "hnae");
+	if (IS_ERR(hnae_class))
+		return PTR_ERR(hnae_class);
+
+	hnae_class->dev_groups = hnae_class_groups;
+	return 0;
+}
+
+static void __exit hnae_exit(void)
+{
+	class_destroy(hnae_class);
+}
+
+subsys_initcall(hnae_init);
+module_exit(hnae_exit);
+
+MODULE_AUTHOR("Hisilicon, Inc.");
+MODULE_LICENSE("GPL");
+MODULE_DESCRIPTION("Hisilicon Network Acceleration Engine Framework");
+
+/* vi: set tw=78 noet: */
diff --git a/drivers/net/ethernet/hisilicon/hns/hnae.h b/drivers/net/ethernet/hisilicon/hns/hnae.h
new file mode 100644
index 0000000..e7856cf
--- /dev/null
+++ b/drivers/net/ethernet/hisilicon/hns/hnae.h
@@ -0,0 +1,582 @@
+/*
+ * Copyright (c) 2014-2015 Hisilicon Limited.
+ *
+ * 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.
+ */
+
+#ifndef __HNAE_H
+#define __HNAE_H
+
+/* Names used in this framework:
+ *      ae handle (handle):
+ *        a set of queues provided by AE
+ *      ring buffer queue (rbq):
+ *        the channel between upper layer and the AE, can do tx and rx
+ *      ring:
+ *        a tx or rx channel within a rbq
+ *      ring description (desc):
+ *        an element in the ring with packet information
+ *      buffer:
+ *        a memory region referred by desc with the full packet payload
+ *
+ * "num" means a static number set as a parameter, "count" mean a dynamic
+ *   number set while running
+ * "cb" means control block
+ */
+
+#include <linux/delay.h>
+#include <linux/device.h>
+#include <linux/module.h>
+#include <linux/netdevice.h>
+#include <linux/notifier.h>
+#include <linux/types.h>
+
+#define HNAE_DRIVER_VERSION "1.1.0"
+#define HNAE_DRIVER_NAME "hns"
+#define HNAE_COPYRIGHT "Copyright(c) 2015 Huawei Corporation."
+#define HNAE_DRIVER_STRING "Hisilicon Network Subsystem Driver"
+#define HNAE_DEFAULT_DEVICE_DESCR "Hisilicon Network Subsystem"
+
+#ifdef DEBUG
+
+#ifndef assert
+#define assert(expr) \
+do { \
+	if (!(expr)) { \
+		pr_err("Assertion failed! %s, %s, %s, line %d\n", \
+			   #expr, __FILE__, __func__, __LINE__); \
+	} \
+} while (0)
+#endif
+
+#else
+
+#ifndef assert
+#define assert(expr)
+#endif
+
+#endif
+
+#define AE_NAME_SIZE 16
+#define AE_OPTS_SIZE 64
+
+/* some said the RX and TX RCB format should not be the same in the future. But
+ * it is the same now...
+ */
+#define RCB_REG_BASEADDR_L         0x00 /* P660 support only 32bit accessing */
+#define RCB_REG_BASEADDR_H         0x04
+#define RCB_REG_BD_NUM             0x08
+#define RCB_REG_BD_LEN             0x0C
+#define RCB_REG_PKTLINE            0x10
+#define RCB_REG_TAIL               0x18
+#define RCB_REG_HEAD               0x1C
+#define RCB_REG_FBDNUM             0x20
+#define RCB_REG_OFFSET             0x24 /* pkt num to be handled */
+#define RCB_REG_PKTNUM_RECORD      0x2C /* total pkt received */
+
+#define HNS_RX_HEAD_SIZE 256
+
+#define HNAE_AE_REGISTER 0x1
+
+#define RCB_RING_NAME_LEN 16
+
+enum hnae_led_state {
+	HNAE_LED_INACTIVE,
+	HNAE_LED_ACTIVE,
+	HNAE_LED_ON,
+	HNAE_LED_OFF
+};
+
+#define HNS_RX_FLAG_VLAN_PRESENT 0x1
+#define HNS_RX_FLAG_L3ID_IPV4 0x0
+#define HNS_RX_FLAG_L3ID_IPV6 0x1
+#define HNS_RX_FLAG_L4ID_UDP 0x0
+#define HNS_RX_FLAG_L4ID_TCP 0x1
+
+#define HNS_TXD_ASID_S 0
+#define HNS_TXD_ASID_M (0xff << HNS_TXD_ASID_S)
+#define HNS_TXD_BUFNUM_S 8
+#define HNS_TXD_BUFNUM_M (0x3 << HNS_TXD_BUFNUM_S)
+#define HNS_TXD_PORTID_S 10
+#define HNS_TXD_PORTID_M (0x7 << HNS_TXD_PORTID_S)
+
+#define HNS_TXD_RA_B 8
+#define HNS_TXD_RI_B 9
+#define HNS_TXD_L4CS_B 10
+#define HNS_TXD_L3CS_B 11
+#define HNS_TXD_FE_B 12
+#define HNS_TXD_VLD_B 13
+#define HNS_TXD_IPOFFSET_S 14
+#define HNS_TXD_IPOFFSET_M (0xff << HNS_TXD_IPOFFSET_S)
+
+#define HNS_RXD_IPOFFSET_S 0
+#define HNS_RXD_IPOFFSET_M (0xff << HNS_TXD_IPOFFSET_S)
+#define HNS_RXD_BUFNUM_S 8
+#define HNS_RXD_BUFNUM_M (0x3 << HNS_RXD_BUFNUM_S)
+#define HNS_RXD_PORTID_S 10
+#define HNS_RXD_PORTID_M (0x7 << HNS_RXD_PORTID_S)
+#define HNS_RXD_DMAC_S 13
+#define HNS_RXD_DMAC_M (0x3 << HNS_RXD_DMAC_S)
+#define HNS_RXD_VLAN_S 15
+#define HNS_RXD_VLAN_M (0x3 << HNS_RXD_VLAN_S)
+#define HNS_RXD_L3ID_S 17
+#define HNS_RXD_L3ID_M (0xf << HNS_RXD_L3ID_S)
+#define HNS_RXD_L4ID_S 21
+#define HNS_RXD_L4ID_M (0xf << HNS_RXD_L4ID_S)
+#define HNS_RXD_FE_B 25
+#define HNS_RXD_FRAG_B 26
+#define HNS_RXD_VLD_B 27
+#define HNS_RXD_L2E_B 28
+#define HNS_RXD_L3E_B 29
+#define HNS_RXD_L4E_B 30
+#define HNS_RXD_DROP_B 31
+
+#define HNS_RXD_VLANID_S 8
+#define HNS_RXD_VLANID_M (0xfff << HNS_RXD_VLANID_S)
+#define HNS_RXD_CFI_B 20
+#define HNS_RXD_PRI_S 21
+#define HNS_RXD_PRI_M (0x7 << HNS_RXD_PRI_S)
+#define HNS_RXD_ASID_S 24
+#define HNS_RXD_ASID_M (0xff << HNS_RXD_ASID_S)
+
+/* hardware spec ring buffer format */
+struct __packed hnae_desc {
+	__le64 addr;
+	union {
+		struct {
+			__le16 asid_bufnum_pid;
+			__le16 send_size;
+			__le32 flag_ipoffset;
+			__le32 reserved_3[4];
+		} tx;
+
+		struct {
+			__le32 ipoff_bnum_pid_flag;
+			__le16 pkt_len;
+			__le16 size;
+			__le32 vlan_pri_asid;
+			__le32 reserved_2[3];
+		} rx;
+	};
+};
+
+struct hnae_desc_cb {
+	dma_addr_t dma; /* dma address of this desc */
+	void *buf;      /* cpu addr for a desc */
+
+	/* priv data for the desc, e.g. skb when use with ip stack*/
+	void *priv;
+	u16 page_offset;
+	u16 reuse_flag;
+
+	u16 length;     /* length of the buffer */
+
+       /* desc type, used by the ring user to mark the type of the priv data */
+	u16 type;
+};
+
+#define setflags(flags, bits) ((flags) |= (bits))
+#define unsetflags(flags, bits) ((flags) &= ~(bits))
+
+/* hnae_ring->flags fields */
+#define RINGF_DIR 0x1	    /* TX or RX ring, set if TX */
+#define is_tx_ring(ring) ((ring)->flags & RINGF_DIR)
+#define is_rx_ring(ring) (!is_tx_ring(ring))
+#define ring_to_dma_dir(ring) (is_tx_ring(ring) ? \
+	DMA_TO_DEVICE : DMA_FROM_DEVICE)
+
+struct ring_stats {
+	u64 io_err_cnt;
+	u64 sw_err_cnt;
+	u64 seg_pkt_cnt;
+	u64 reuse_pg_cnt;
+	u64 err_pkt_len;
+	u64 non_vld_descs;
+	u64 err_bd_num;
+	u64 csum_err;
+	union {
+		u64 tx_pkts;
+		u64 rx_pkts;
+	} pkts;
+	union {
+		u64 tx_bytes;
+		u64 rx_bytes;
+	} bytes;
+	union {
+		u64 tx_err_cnt;
+		u64 rx_err_cnt;
+	} err_cnt;
+};
+
+struct hnae_queue;
+
+struct hnae_ring {
+	u8 __iomem *io_base; /* base io address for the ring */
+	struct hnae_desc *desc; /* dma map address space */
+	struct hnae_desc_cb *desc_cb;
+	struct hnae_queue *q;
+	int irq;
+	char ring_name[RCB_RING_NAME_LEN];
+
+	/* statistic */
+	struct ring_stats stats;
+
+	dma_addr_t desc_dma_addr;
+	u32 buf_size;       /* size for hnae_desc->addr, preset by AE */
+	u16 desc_num;       /* total number of desc */
+	u16 max_desc_num_per_pkt;
+	u16 max_raw_data_sz_per_desc;
+	u16 max_pkt_size;
+	int next_to_use;    /* idx of next spare desc */
+
+	/* idx of lastest sent desc, the ring is empty when equal to
+	 * next_to_use
+	 */
+	int next_to_clean;
+
+	int flags;          /* ring attribute */
+};
+
+#define ring_ptr_move_fw(ring, p) \
+	((ring)->p = ((ring)->p + 1) % (ring)->desc_num)
+#define ring_ptr_move_bw(ring, p) \
+	((ring)->p = ((ring)->p - 1 + (ring)->desc_num) % (ring)->desc_num)
+
+enum hns_desc_type {
+	DESC_TYPE_SKB,
+	DESC_TYPE_PAGE,
+};
+
+#define assert_is_ring_idx(ring, idx) \
+	assert((idx) >= 0 && (idx) < (ring)->desc_num)
+
+/* the distance between [begin, end) in a ring buffer
+ * note: there is a unuse slot between the begin and the end
+ */
+static inline int ring_dist(struct hnae_ring *ring, int begin, int end)
+{
+	assert_is_ring_idx(ring, begin);
+	assert_is_ring_idx(ring, end);
+
+	return (end - begin + ring->desc_num) % ring->desc_num;
+}
+
+static inline int ring_space(struct hnae_ring *ring)
+{
+	return ring->desc_num -
+		ring_dist(ring, ring->next_to_clean, ring->next_to_use) - 1;
+}
+
+static inline int is_ring_empty(struct hnae_ring *ring)
+{
+	assert_is_ring_idx(ring, ring->next_to_use);
+	assert_is_ring_idx(ring, ring->next_to_clean);
+
+	return ring->next_to_use == ring->next_to_clean;
+}
+
+#define hnae_buf_size(_ring) ((_ring)->buf_size)
+#define hnae_page_order(_ring) (get_order(hnae_buf_size(_ring)))
+#define hnae_page_size(_ring) (PAGE_SIZE << hnae_page_order(_ring))
+
+struct hnae_handle;
+
+/* allocate and dma map space for hnae desc */
+struct hnae_buf_ops {
+	int (*alloc_buffer)(struct hnae_ring *ring, struct hnae_desc_cb *cb);
+	void (*free_buffer)(struct hnae_ring *ring, struct hnae_desc_cb *cb);
+	int (*map_buffer)(struct hnae_ring *ring, struct hnae_desc_cb *cb);
+	void (*unmap_buffer)(struct hnae_ring *ring, struct hnae_desc_cb *cb);
+};
+
+struct hnae_queue {
+	void __iomem *io_base;
+	struct hnae_ae_dev *dev;	/* the device who use this queue */
+	struct hnae_ring rx_ring, tx_ring;
+	struct hnae_handle *handle;
+};
+
+/*hnae loop mode*/
+enum hnae_loop {
+	MAC_LOOP_NONE = 0,
+	MAC_INTERNALLOOP_MAC,
+	MAC_INTERNALLOOP_SERDES,
+	MAC_INTERNALLOOP_PHY,
+};
+
+/*hnae port type*/
+enum hnae_port_type {
+	HNAE_PORT_SERVICE = 0,
+	HNAE_PORT_DEBUG
+};
+
+/* This struct defines the operation on the handle.
+ *
+ * get_handle(): (mandatory)
+ *   Get a handle from AE according to its name and options.
+ *   the AE driver should manage the space used by handle and its queues while
+ *   the HNAE framework will allocate desc and desc_cb for all rings in the
+ *   queues.
+ * put_handle():
+ *   Release the handle.
+ * start():
+ *   Enable the hardware, include all queues
+ * stop():
+ *   Disable the hardware
+ * set_opts(): (mandatory)
+ *   Set options to the AE
+ * get_opts(): (mandatory)
+ *   Get options from the AE
+ * get_status():
+ *   Get the carrier state of the back channel of the handle, 1 for ok, 0 for
+ *   non-ok
+ * toggle_ring_irq(): (mandatory)
+ *   Set the ring irq to be enabled(0) or disable(1)
+ * toggle_queue_status(): (mandatory)
+ *   Set the queue to be enabled(1) or disable(0), this will not change the
+ *   ring irq state
+ * adjust_link()
+ *   adjust link status
+ * set_loopback()
+ *   set loopback
+ * get_ring_bdnum_limit()
+ *   get ring bd number limit
+ * get_pauseparam()
+ *   get tx and rx of pause frame use
+ * set_autoneg()
+ *   set auto autonegotiation of pause frame use
+ * get_autoneg()
+ *   get auto autonegotiation of pause frame use
+ * set_pauseparam()
+ *   set tx and rx of pause frame use
+ * get_coalesce_usecs()
+ *   get usecs to delay a TX interrupt after a packet is sent
+ * get_rx_max_coalesced_frames()
+ *   get Maximum number of packets to be sent before a TX interrupt.
+ * set_coalesce_usecs()
+ *   set usecs to delay a TX interrupt after a packet is sent
+ * set_coalesce_frames()
+ *   set Maximum number of packets to be sent before a TX interrupt.
+ * get_ringnum()
+ *   get RX/TX ring number
+ * get_max_ringnum()
+ *   get RX/TX ring maximum number
+ * get_mac_addr()
+ *   get mac address
+ * set_mac_addr()
+ *   set mac address
+ * set_mc_addr()
+ *   set multicast mode
+ * set_mtu()
+ *   set mtu
+ * update_stats()
+ *   update Old network device statistics
+ * get_ethtool_stats()
+ *   get ethtool network device statistics
+ * get_strings()
+ *   get a set of strings that describe the requested objects
+ * get_sset_count()
+ *   get number of strings that @get_strings will write
+ * update_led_status()
+ *   update the led status
+ * set_led_id()
+ *   set led id
+ * get_regs()
+ *   get regs dump
+ * get_regs_len()
+ *   get the len of the regs dump
+ */
+struct hnae_ae_ops {
+	struct hnae_handle *(*get_handle)(struct hnae_ae_dev *dev,
+					  const char *opts);
+	void (*put_handle)(struct hnae_handle *handle);
+	void (*init_queue)(struct hnae_queue *q);
+	void (*fini_queue)(struct hnae_queue *q);
+	int (*start)(struct hnae_handle *handle);
+	void (*stop)(struct hnae_handle *handle);
+	void (*reset)(struct hnae_handle *handle);
+	int (*set_opts)(struct hnae_handle *handle, int type, void *opts);
+	int (*get_opts)(struct hnae_handle *handle, int type, void **opts);
+	int (*get_status)(struct hnae_handle *handle);
+	int (*get_info)(struct hnae_handle *handle,
+			u8 *auto_neg, u16 *speed, u8 *duplex);
+	int (*set_info)(struct hnae_handle *handle,
+			u8 auto_neg, u16 speed, u8 duplex);
+	void (*toggle_ring_irq)(struct hnae_ring *ring, u32 val);
+	void (*toggle_queue_status)(struct hnae_queue *queue, u32 val);
+	void (*adjust_link)(struct hnae_handle *handle, int speed, int duplex);
+	int (*set_loopback)(struct hnae_handle *handle,
+			    enum hnae_loop loop_mode, int en);
+	void (*get_ring_bdnum_limit)(struct hnae_queue *queue,
+				     u32 *uplimit, u32 *lowlimit);
+	void (*get_pauseparam)(struct hnae_handle *handle,
+			       u32 *auto_neg, u32 *rx_en, u32 *tx_en);
+	int (*set_autoneg)(struct hnae_handle *handle, u8 enable);
+	int (*get_autoneg)(struct hnae_handle *handle);
+	void (*set_pauseparam)(struct hnae_handle *handle,
+			       u32 rx_en, u32 tx_en);
+	void (*get_coalesce_usecs)(struct hnae_handle *handle,
+				   u32 *tx_usecs, u32 *rx_usecs);
+	void (*get_rx_max_coalesced_frames)(struct hnae_handle *handle,
+					    u32 *tx_frames, u32 *rx_frames);
+	void (*set_coalesce_usecs)(struct hnae_handle *handle, u32 timeout);
+	int (*set_coalesce_frames)(struct hnae_handle *handle,
+				   u32 coalesce_frames);
+	void (*get_ringnum)(struct hnae_handle *handle, u32 *ringnum);
+	void (*get_max_ringnum)(struct hnae_handle *handle, u32 *max_ringnum);
+	int (*get_mac_addr)(struct hnae_handle *handle, void **p);
+	int (*set_mac_addr)(struct hnae_handle *handle, void *p);
+	int (*set_mc_addr)(struct hnae_handle *handle, void *addr);
+	int (*set_mtu)(struct hnae_handle *handle, int new_mtu);
+	void (*update_stats)(struct hnae_handle *handle,
+			     struct net_device_stats *net_stats);
+	void (*get_stats)(struct hnae_handle *handle, u64 *data);
+	void (*get_strings)(struct hnae_handle *handle,
+			    u32 stringset, u8 *data);
+	int (*get_sset_count)(struct hnae_handle *handle, int stringset);
+	void (*update_led_status)(struct hnae_handle *handle);
+	int (*set_led_id)(struct hnae_handle *handle,
+			  enum hnae_led_state status);
+	void (*get_regs)(struct hnae_handle *handle, void *data);
+	int (*get_regs_len)(struct hnae_handle *handle);
+};
+
+struct hnae_ae_dev {
+	struct device cls_dev; /* the class dev */
+	struct device *dev; /* the presented dev */
+	struct hnae_ae_ops *ops;
+	struct list_head node;
+	struct module *owner; /* the module who provides this dev */
+	int id;
+	char name[AE_NAME_SIZE];
+	struct list_head handle_list;
+	spinlock_t lock; /* lock to protect the handle_list */
+};
+
+struct hnae_handle {
+	struct device *owner_dev; /* the device which make use of this handle */
+	struct hnae_ae_dev *dev;  /* the device who provides this handle */
+	struct device_node *phy_node;
+	phy_interface_t phy_if;
+	u32 if_support;
+	int q_num;
+	const char *ae_opts;
+	enum hnae_port_type port_type;
+	struct list_head node;    /* list to hnae_ae_dev->handle_list */
+	struct hnae_buf_ops *bops; /* operation for the buffer */
+	struct net_device_stats net_stats;
+	struct hnae_queue **qs;  /* array base of all queues */
+};
+
+#define ring_to_dev(ring) ((ring)->q->dev->dev)
+
+struct hnae_handle *hnae_get_handle(struct device *owner_dev, const char *ae_id,
+				    const char *ae_opts,
+				    struct hnae_buf_ops *bops);
+void hnae_put_handle(struct hnae_handle *handle);
+int hnae_ae_register(struct hnae_ae_dev *dev, struct module *owner);
+void hnae_ae_unregister(struct hnae_ae_dev *dev);
+
+int hnae_register_notifier(struct notifier_block *nb);
+void hnae_unregister_notifier(struct notifier_block *nb);
+int hnae_reinit_handle(struct hnae_handle *handle);
+
+#define hnae_queue_xmit(q, buf_num) writel_relaxed(buf_num, \
+	(q)->tx_ring.io_base + RCB_REG_TAIL)
+
+#ifndef assert
+#define assert(cond)
+#endif
+
+static inline int hnae_reserve_buffer_map(struct hnae_ring *ring,
+					  struct hnae_desc_cb *cb)
+{
+	struct hnae_buf_ops *bops = ring->q->handle->bops;
+	int ret;
+
+	ret = bops->alloc_buffer(ring, cb);
+	if (ret)
+		goto out;
+
+	ret = bops->map_buffer(ring, cb);
+	if (ret)
+		goto out_with_buf;
+
+	return 0;
+
+out_with_buf:
+	bops->free_buffer(ring, cb);
+out:
+	return ret;
+}
+
+static inline int hnae_alloc_buffer_attach(struct hnae_ring *ring, int i)
+{
+	int ret = hnae_reserve_buffer_map(ring, &ring->desc_cb[i]);
+
+	if (ret)
+		return ret;
+
+	ring->desc[i].addr = (__le64)ring->desc_cb[i].dma;
+
+	return 0;
+}
+
+static inline void hnae_buffer_detach(struct hnae_ring *ring, int i)
+{
+	ring->q->handle->bops->unmap_buffer(ring, &ring->desc_cb[i]);
+	ring->desc[i].addr = 0;
+}
+
+static inline void hnae_free_buffer_detach(struct hnae_ring *ring, int i)
+{
+	struct hnae_buf_ops *bops = ring->q->handle->bops;
+	struct hnae_desc_cb *cb = &ring->desc_cb[i];
+
+	if (!ring->desc_cb[i].dma)
+		return;
+
+	hnae_buffer_detach(ring, i);
+	bops->free_buffer(ring, cb);
+}
+
+/* detach a in-used buffer and replace with a reserved one  */
+static inline void hnae_replace_buffer(struct hnae_ring *ring, int i,
+				       struct hnae_desc_cb *res_cb)
+{
+	struct hnae_buf_ops *bops = ring->q->handle->bops;
+	struct hnae_desc_cb tmp_cb = ring->desc_cb[i];
+
+	bops->unmap_buffer(ring, &ring->desc_cb[i]);
+	ring->desc_cb[i] = *res_cb;
+	*res_cb = tmp_cb;
+	ring->desc[i].addr = (__le64)ring->desc_cb[i].dma;
+	ring->desc[i].rx.ipoff_bnum_pid_flag = 0;
+}
+
+static inline void hnae_reuse_buffer(struct hnae_ring *ring, int i)
+{
+	ring->desc_cb[i].reuse_flag = 0;
+	ring->desc[i].addr = (__le64)(ring->desc_cb[i].dma
+		+ ring->desc_cb[i].page_offset);
+	ring->desc[i].rx.ipoff_bnum_pid_flag = 0;
+}
+
+#define hnae_set_field(origin, mask, shift, val) \
+	do { \
+		(origin) &= (~(mask)); \
+		(origin) |= ((val) << (shift)) & (mask); \
+	} while (0)
+
+#define hnae_set_bit(origin, shift, val) \
+	hnae_set_field((origin), (0x1 << (shift)), (shift), (val))
+
+#define hnae_get_field(origin, mask, shift) (((origin) & (mask)) >> (shift))
+
+#define hnae_get_bit(origin, shift) \
+	hnae_get_field((origin), (0x1 << (shift)), (shift))
+
+#endif
-- 
1.9.1



From sakari.ailus at iki.fi  Fri Aug 14 03:33:48 2015
From: sakari.ailus at iki.fi (Sakari Ailus)
Date: Fri, 14 Aug 2015 13:33:48 +0300
Subject: [PATCH RFC v3 07/16] media: get rid of unused "extra_links"
 param on media_entity_init()
In-Reply-To: <7b9f2654888f0fd54c290c50f50248a367768da7.1439410053.git.mchehab@osg.samsung.com>
References: <cover.1439410053.git.mchehab@osg.samsung.com>
 <7b9f2654888f0fd54c290c50f50248a367768da7.1439410053.git.mchehab@osg.samsung.com>
Message-ID: <20150814103348.GC19840@valkosipuli.retiisi.org.uk>

Hi Mauro,

On Wed, Aug 12, 2015 at 05:14:51PM -0300, Mauro Carvalho Chehab wrote:
> Currently, media_entity_init() creates an array with the links,
> allocated at init time. It provides a parameter (extra_links)
> that would allocate more links than the current needs, but this
> is not used by any driver.
> 
> As we want to be able to do dynamic link allocation/removal,
> we'll need to change the implementation of the links. So,
> before doing that, let's first remove that extra unused
> parameter, in order to cleanup the interface first.
> 
> Signed-off-by: Mauro Carvalho Chehab <mchehab at osg.samsung.com>
> 
...


> diff --git a/include/media/media-entity.h b/include/media/media-entity.h
> index 738e1d5d25dc..be6885e7c8ed 100644
> --- a/include/media/media-entity.h
> +++ b/include/media/media-entity.h
> @@ -177,7 +177,7 @@ void graph_obj_init(struct media_device *mdev,
>  void graph_obj_remove(struct media_graph_obj *gobj);
>  
>  int media_entity_init(struct media_entity *entity, u16 num_pads,
> -		struct media_pad *pads, u16 extra_links);
> +		struct media_pad *pads);
>  void media_entity_cleanup(struct media_entity *entity);
>  
>  int media_entity_create_link(struct media_entity *source, u16 source_pad,

How about putting this in front of the set? It has no dependencies to the
other patches, does it?

Acked-by: Sakari Ailus <sakari.ailus at linux.intel.com>

-- 
Regards,

Sakari Ailus
e-mail: sakari.ailus at iki.fi	XMPP: sailus at retiisi.org.uk


From linus.walleij at linaro.org  Fri Aug 14 03:34:33 2015
From: linus.walleij at linaro.org (Linus Walleij)
Date: Fri, 14 Aug 2015 12:34:33 +0200
Subject: [PATCH v2 0/6] ARM: shmobile: Move gpio ranges from C code to DT
In-Reply-To: <CAMuHMdU0XoZ-comYSAau6e3kAY9VUbNgyeRcS_LzmV1gm31ZKA@mail.gmail.com>
References: <1438696519-13727-1-git-send-email-geert+renesas@glider.be>
 <20150805005540.GB20726@verge.net.au>
 <CACRpkdY7P86+SxMr5-HnhrN5fC-N1U135jiGAJGTV=xx47VW5g@mail.gmail.com>
 <CAMuHMdW0T6MW6s4Gg_rqvtt+MRPtp_MpuiKtamfFrx-Tcm6WmQ@mail.gmail.com>
 <20150814003023.GC12589@verge.net.au>
 <CAMuHMdU0XoZ-comYSAau6e3kAY9VUbNgyeRcS_LzmV1gm31ZKA@mail.gmail.com>
Message-ID: <CACRpkdYe5z9vG+Aekdq1wcKdhUUN5bpxQ52RgNt17+bhJbjVEQ@mail.gmail.com>

On Fri, Aug 14, 2015 at 9:46 AM, Geert Uytterhoeven
<geert at linux-m68k.org> wrote:
> On Fri, Aug 14, 2015 at 2:30 AM, Simon Horman <horms at verge.net.au> wrote:
>> On Thu, Aug 13, 2015 at 02:45:55PM +0200, Geert Uytterhoeven wrote:
>>> On Thu, Aug 13, 2015 at 2:29 PM, Linus Walleij <linus.walleij at linaro.org> wrote:
>>> > On Wed, Aug 5, 2015 at 2:55 AM, Simon Horman <horms at verge.net.au> wrote:
>>> >> Where possible I prefer not to apply non-DTS/DTSI patches on top of
>>> >> DTS/DTSI patches, I believe this is in keeping with how the ARM SoC
>>> >> maintainers like things handled.  With this in mind I have done the following:
>>> >>
>>> >> 1. Queued up the DTSI patches (patches 1 - 3) for v4.3 in my dt branch.
>>> >>    I intend for this to turn up in next soon.
>>> >> 2. Queued up for pinctrl patches (patches 4 - 6) for v4.4 in a pinctrl patch.
>>> >>    I intend for these to be present in the renesas devel branch but
>>> >>    not in next until after the release of v4.3-rc1. I would also be
>>> >>    happy to drop them and let Linus Walleij take these patches for v4.4,
>>> >>    assuming patches 1 - 3 are accepted for v4.3.
>>> >
>>> > OK.
>>> >
>>> > Will the world explode if I try to queue the pinctrl patches 4-6 in my
>>> > tree now for v4.3? Then I prefer to defer to v4.4. Else I can merge
>>> > it in parallel?
>>>
>>> There won't be a mapping between gpio and pins in any branch having the
>>> pinctrl changes but not the dtsi changes.
>>
>> It sounds to me that Linus should take his option 2; defer to v4.4.
>> In which case I should drop the changes from my tree (they are not in next
>> anyway). Please let me know if thats the way we will move this forwards.
>
> Sounds fine to me.
>
> And in the unlikely event we discover regressions in v4.3-rc1 due to having
> the dtsi changes without the pinctrl changes, we can still fast-track them
> into v4.3-rc2.

Sounds like a plan.

Hit me on the head about this once v4.3-rc1 is out!

Yours,
Linus Walleij


From liguozhu at hisilicon.com  Fri Aug 14 03:30:22 2015
From: liguozhu at hisilicon.com (Kenneth Lee)
Date: Fri, 14 Aug 2015 18:30:22 +0800
Subject: [PATCH 5/5] net: add Hisilicon Network Subsystem basic ethernet
 support
In-Reply-To: <1439548222-231611-1-git-send-email-liguozhu@hisilicon.com>
References: <1439548222-231611-1-git-send-email-liguozhu@hisilicon.com>
Message-ID: <1439548222-231611-6-git-send-email-liguozhu@hisilicon.com>

This is to add basic ethernet support for HNS. It is one of the way to use
the HNS acceleration engine. But most of the decoding/encoding capability
of the AE cannot be used in this way.

This submit contains the basic feature as a ethernet driver. More will be
added later.

Signed-off-by: Kenneth Lee <liguozhu at huawei.com>
Signed-off-by: Yisen Zhuang <Yisen.Zhuang at huawei.com>
---
 drivers/net/ethernet/hisilicon/hns/hns_enet.c    | 1552 ++++++++++++++++++++++
 drivers/net/ethernet/hisilicon/hns/hns_enet.h    |   81 ++
 drivers/net/ethernet/hisilicon/hns/hns_ethtool.c | 1174 ++++++++++++++++
 3 files changed, 2807 insertions(+)
 create mode 100644 drivers/net/ethernet/hisilicon/hns/hns_enet.c
 create mode 100644 drivers/net/ethernet/hisilicon/hns/hns_enet.h
 create mode 100644 drivers/net/ethernet/hisilicon/hns/hns_ethtool.c

diff --git a/drivers/net/ethernet/hisilicon/hns/hns_enet.c b/drivers/net/ethernet/hisilicon/hns/hns_enet.c
new file mode 100644
index 0000000..b58d5ab
--- /dev/null
+++ b/drivers/net/ethernet/hisilicon/hns/hns_enet.c
@@ -0,0 +1,1552 @@
+/*
+ * Copyright (c) 2014-2015 Hisilicon Limited.
+ *
+ * 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.
+ */
+
+#include <linux/module.h>
+#include <linux/interrupt.h>
+#include <linux/etherdevice.h>
+#include <linux/platform_device.h>
+#include <linux/clk.h>
+#include <linux/skbuff.h>
+#include <linux/phy.h>
+#include <linux/io.h>
+#include <linux/ip.h>
+#include <linux/ipv6.h>
+#include <linux/if_vlan.h>
+#include "hnae.h"
+#include "hns_enet.h"
+
+#define NIC_MAX_Q_PER_VF 16
+#define HNS_NIC_TX_TIMEOUT (5 * HZ)
+
+#define SERVICE_TIMER_HZ (1 * HZ)
+
+#define NIC_TX_CLEAN_MAX_NUM 256
+#define NIC_RX_CLEAN_MAX_NUM 64
+
+#define RCB_ERR_PRINT_CYCLE 1000
+
+static inline void fill_desc(struct hnae_ring *ring, void *priv,
+			     int size, dma_addr_t dma, int frag_end,
+			     int buf_num, enum hns_desc_type type)
+{
+	struct hnae_desc *desc = &ring->desc[ring->next_to_use];
+	struct hnae_desc_cb *desc_cb = &ring->desc_cb[ring->next_to_use];
+	struct sk_buff *skb;
+	__be16 protocol;
+	u32 ip_offset;
+	u32 asid_bufnum_pid = 0;
+	u32 flag_ipoffset = 0;
+
+	desc_cb->priv = priv;
+	desc_cb->length = size;
+	desc_cb->dma = dma;
+	desc_cb->type = type;
+
+	desc->addr = cpu_to_le64(dma);
+	desc->tx.send_size = cpu_to_le16((u16)size);
+
+	/*config bd buffer end */
+	flag_ipoffset |= 1 << HNS_TXD_VLD_B;
+
+	asid_bufnum_pid |= buf_num << HNS_TXD_BUFNUM_S;
+
+	if (type == DESC_TYPE_SKB) {
+		skb = (struct sk_buff *)priv;
+
+		if (skb->ip_summed == CHECKSUM_PARTIAL) {
+			protocol = skb->protocol;
+			ip_offset = ETH_HLEN;
+
+			/*if it is a SW VLAN check the next protocol*/
+			if (protocol == htons(ETH_P_8021Q)) {
+				ip_offset += VLAN_HLEN;
+				protocol = vlan_get_protocol(skb);
+				skb->protocol = protocol;
+			}
+
+			if (skb->protocol == ntohs(ETH_P_IP)) {
+				flag_ipoffset |= 1 << HNS_TXD_L3CS_B;
+				/* check for tcp/udp header */
+				flag_ipoffset |= 1 << HNS_TXD_L4CS_B;
+
+			} else if (skb->protocol == ntohs(ETH_P_IPV6)) {
+				/* ipv6 has not l3 cs, check for L4 header */
+				flag_ipoffset |= 1 << HNS_TXD_L4CS_B;
+			}
+
+			flag_ipoffset |= ip_offset << HNS_TXD_IPOFFSET_S;
+		}
+	}
+
+	flag_ipoffset |= frag_end << HNS_TXD_FE_B;
+
+	desc->tx.asid_bufnum_pid = cpu_to_le16(asid_bufnum_pid);
+	desc->tx.flag_ipoffset = cpu_to_le32(flag_ipoffset);
+
+	ring_ptr_move_fw(ring, next_to_use);
+}
+
+static inline void unfill_desc(struct hnae_ring *ring)
+{
+	ring_ptr_move_bw(ring, next_to_use);
+}
+
+int hns_nic_net_xmit_hw(struct net_device *ndev,
+			struct sk_buff *skb,
+			struct hns_nic_ring_data *ring_data)
+{
+	struct hns_nic_priv *priv = netdev_priv(ndev);
+	struct device *dev = priv->dev;
+	struct hnae_ring *ring = ring_data->ring;
+	struct netdev_queue *dev_queue;
+	struct skb_frag_struct *frag;
+	int buf_num;
+	dma_addr_t dma;
+	int size, next_to_use;
+	int i, j;
+	struct sk_buff *new_skb;
+
+	assert(ring->max_desc_num_per_pkt <= ring->desc_num);
+
+	/* no. of segments (plus a header) */
+	buf_num = skb_shinfo(skb)->nr_frags + 1;
+
+	if (unlikely(buf_num > ring->max_desc_num_per_pkt)) {
+		if (ring_space(ring) < 1)
+			return NETDEV_TX_BUSY;
+
+		new_skb = skb_copy(skb, GFP_ATOMIC);
+		if (!new_skb) {
+			ring->stats.sw_err_cnt++;
+			netdev_err(ndev, "no memory to xmit!\n");
+			dev_kfree_skb_any(skb);
+			return NETDEV_TX_OK;
+		}
+
+		dev_kfree_skb_any(skb);
+		skb = new_skb;
+		buf_num = 1;
+		assert(skb_shinfo(skb)->nr_frags == 1);
+	}
+
+	if (buf_num > ring_space(ring))
+		return NETDEV_TX_BUSY;
+
+	next_to_use = ring->next_to_use;
+
+	/* fill the first part */
+	size = skb_headlen(skb);
+	dma = dma_map_single(dev, skb->data, size, DMA_TO_DEVICE);
+	if (dma_mapping_error(dev, dma)) {
+		netdev_err(ndev, "TX head DMA map failed\n");
+		ring->stats.sw_err_cnt++;
+		goto out_map_head_fail;
+	}
+	fill_desc(ring, skb, size, dma, buf_num == 1 ? 1 : 0, buf_num,
+		  DESC_TYPE_SKB);
+
+	/* fill the fragments */
+	for (i = 1; i < buf_num; i++) {
+		frag = &skb_shinfo(skb)->frags[i - 1];
+		size = skb_frag_size(frag);
+		dma = skb_frag_dma_map(dev, frag, 0, size, DMA_TO_DEVICE);
+		if (dma_mapping_error(dev, dma)) {
+			netdev_err(ndev, "TX frag(%d) DMA map failed\n", i);
+			ring->stats.sw_err_cnt++;
+			goto out_map_frag_fail;
+		}
+		fill_desc(ring, skb_frag_page(frag), size, dma,
+			  buf_num - 1 == i ? 1 : 0, buf_num, DESC_TYPE_PAGE);
+	}
+
+	/*complete translate all packets*/
+	dev_queue = netdev_get_tx_queue(ndev, skb->queue_mapping);
+	netdev_tx_sent_queue(dev_queue, skb->len);
+
+	wmb(); /* commit all data before submit */
+	assert(skb->queue_mapping < priv->ae_handle->q_num);
+	hnae_queue_xmit(priv->ae_handle->qs[skb->queue_mapping], buf_num);
+	ring->stats.pkts.tx_pkts++;
+	ring->stats.bytes.tx_bytes += skb->len;
+
+	return NETDEV_TX_OK;
+
+out_map_frag_fail:
+
+	for (j = i - 1; j > 0; j--) {
+		unfill_desc(ring);
+		next_to_use = ring->next_to_use;
+		dma_unmap_page(dev, ring->desc_cb[next_to_use].dma,
+			       ring->desc_cb[next_to_use].length,
+			       DMA_TO_DEVICE);
+	}
+
+	unfill_desc(ring);
+	next_to_use = ring->next_to_use;
+	dma_unmap_single(dev, ring->desc_cb[next_to_use].dma,
+			 ring->desc_cb[next_to_use].length, DMA_TO_DEVICE);
+
+out_map_head_fail:
+	return NETDEV_TX_BUSY;
+}
+
+/**
+ * hns_nic_get_headlen - determine size of header for RSC/LRO/GRO/FCOE
+ * @data: pointer to the start of the headers
+ * @max: total length of section to find headers in
+ *
+ * This function is meant to determine the length of headers that will
+ * be recognized by hardware for LRO, GRO, and RSC offloads.  The main
+ * motivation of doing this is to only perform one pull for IPv4 TCP
+ * packets so that we can do basic things like calculating the gso_size
+ * based on the average data per packet.
+ **/
+static unsigned int hns_nic_get_headlen(unsigned char *data, u32 flag,
+					unsigned int max)
+{
+	unsigned char *network;
+	u8 hlen;
+
+	/* this should never happen, but better safe than sorry */
+	if (max < ETH_HLEN)
+		return max;
+
+	/* initialize network frame pointer */
+	network = data;
+
+	/* set first protocol and move network header forward */
+	network += ETH_HLEN;
+
+	/* handle any vlan tag if present */
+	if (hnae_get_field(flag, HNS_RXD_VLAN_M, HNS_RXD_VLAN_S)
+		== HNS_RX_FLAG_VLAN_PRESENT) {
+		if ((typeof(max))(network - data) > (max - VLAN_HLEN))
+			return max;
+
+		network += VLAN_HLEN;
+	}
+
+	/* handle L3 protocols */
+	if (hnae_get_field(flag, HNS_RXD_L3ID_M, HNS_RXD_L3ID_S)
+		== HNS_RX_FLAG_L3ID_IPV4) {
+		if ((typeof(max))(network - data) >
+					(max - sizeof(struct iphdr)))
+			return max;
+
+		/* access ihl as a u8 to avoid unaligned access on ia64 */
+		hlen = (network[0] & 0x0F) << 2;
+
+		/* verify hlen meets minimum size requirements */
+		if (hlen < sizeof(struct iphdr))
+			return network - data;
+
+		/* record next protocol if header is present */
+	} else if (hnae_get_field(flag, HNS_RXD_L3ID_M, HNS_RXD_L3ID_S)
+		== HNS_RX_FLAG_L3ID_IPV6) {
+		if ((typeof(max))(network - data) >
+						(max - sizeof(struct ipv6hdr)))
+			return max;
+
+		/* record next protocol */
+		hlen = sizeof(struct ipv6hdr);
+	} else {
+		return network - data;
+	}
+
+	/* relocate pointer to start of L4 header */
+	network += hlen;
+
+	/* finally sort out TCP/UDP */
+	if (hnae_get_field(flag, HNS_RXD_L4ID_M, HNS_RXD_L4ID_S)
+		== HNS_RX_FLAG_L4ID_TCP) {
+		if ((typeof(max))(network - data) >
+						(max - sizeof(struct tcphdr)))
+			return max;
+
+		/* access doff as a u8 to avoid unaligned access on ia64 */
+		hlen = (network[12] & 0xF0) >> 2;
+
+		/* verify hlen meets minimum size requirements */
+		if (hlen < sizeof(struct tcphdr))
+			return network - data;
+
+		network += hlen;
+	} else if (hnae_get_field(flag, HNS_RXD_L4ID_M, HNS_RXD_L4ID_S)
+		== HNS_RX_FLAG_L4ID_UDP) {
+		if ((typeof(max))(network - data) >
+						(max - sizeof(struct udphdr)))
+			return max;
+
+		network += sizeof(struct udphdr);
+	}
+
+	/* If everything has gone correctly network should be the
+	 * data section of the packet and will be the end of the header.
+	 * If not then it probably represents the end of the last recognized
+	 * header.
+	 */
+	if ((typeof(max))(network - data) < max)
+		return network - data;
+	else
+		return max;
+}
+
+static inline void hns_nic_reuse_page(struct hnae_desc_cb *desc_cb, int tsize,
+				      int last_offset)
+{
+	 /* avoid re-using remote pages,flag default unreuse */
+	if (likely(page_to_nid(desc_cb->priv) == numa_node_id())) {
+		/* move offset up to the next cache line */
+		desc_cb->page_offset += tsize;
+
+		if (desc_cb->page_offset <= last_offset) {
+			desc_cb->reuse_flag = 1;
+			/* bump ref count on page before it is given*/
+			get_page(desc_cb->priv);
+		}
+	}
+}
+
+static inline int hns_nic_poll_rx_skb(struct hns_nic_ring_data *ring_data,
+				      struct sk_buff **out_skb, int *out_bnum)
+{
+	struct hnae_ring *ring = ring_data->ring;
+	struct net_device *ndev = ring_data->napi.dev;
+	struct sk_buff *skb;
+	struct hnae_desc *desc;
+	struct hnae_desc_cb *desc_cb;
+	unsigned char *va;
+	int bnum, length, size, i, truesize, last_offset;
+	int pull_len;
+	u32 bnum_flag;
+
+	last_offset = hnae_page_size(ring) - hnae_buf_size(ring);
+	desc = &ring->desc[ring->next_to_clean];
+	desc_cb = &ring->desc_cb[ring->next_to_clean];
+	length = le16_to_cpu(desc->rx.pkt_len);
+	bnum_flag = le32_to_cpu(desc->rx.ipoff_bnum_pid_flag);
+	bnum = hnae_get_field(bnum_flag, HNS_RXD_BUFNUM_M, HNS_RXD_BUFNUM_S);
+	*out_bnum = bnum;
+	va = (unsigned char *)desc_cb->buf + desc_cb->page_offset;
+
+	skb = *out_skb = napi_alloc_skb(&ring_data->napi, HNS_RX_HEAD_SIZE);
+	if (unlikely(!skb)) {
+		netdev_err(ndev, "alloc rx skb fail\n");
+		ring->stats.sw_err_cnt++;
+		return -ENOMEM;
+	}
+
+	if (length <= HNS_RX_HEAD_SIZE) {
+		memcpy(__skb_put(skb, length), va, ALIGN(length, sizeof(long)));
+
+		/* we can reuse buffer as-is, just make sure it is local */
+		if (likely(page_to_nid(desc_cb->priv) == numa_node_id()))
+			desc_cb->reuse_flag = 1;
+		else /* this page cannot be reused so discard it */
+			put_page(desc_cb->priv);
+
+		ring_ptr_move_fw(ring, next_to_clean);
+
+		if (unlikely(bnum != 1)) { /* check err*/
+			*out_bnum = 1;
+			goto out_bnum_err;
+		}
+	} else {
+		ring->stats.seg_pkt_cnt++;
+
+		pull_len = hns_nic_get_headlen(va, bnum_flag, HNS_RX_HEAD_SIZE);
+		memcpy(__skb_put(skb, pull_len), va,
+		       ALIGN(pull_len, sizeof(long)));
+
+		size = le16_to_cpu(desc->rx.size);
+		truesize = ALIGN(size, L1_CACHE_BYTES);
+		skb_add_rx_frag(skb, 0, desc_cb->priv,
+				desc_cb->page_offset + pull_len,
+				size - pull_len, truesize - pull_len);
+
+		hns_nic_reuse_page(desc_cb, truesize, last_offset);
+		ring_ptr_move_fw(ring, next_to_clean);
+
+		if (unlikely(bnum >= (int)MAX_SKB_FRAGS)) { /* check err*/
+			*out_bnum = 1;
+			goto out_bnum_err;
+		}
+		for (i = 1; i < bnum; i++) {
+			desc = &ring->desc[ring->next_to_clean];
+			desc_cb = &ring->desc_cb[ring->next_to_clean];
+			size = le16_to_cpu(desc->rx.size);
+			truesize = ALIGN(size, L1_CACHE_BYTES);
+			skb_add_rx_frag(skb, i, desc_cb->priv,
+					desc_cb->page_offset,
+					size, truesize);
+
+			hns_nic_reuse_page(desc_cb, truesize, last_offset);
+			ring_ptr_move_fw(ring, next_to_clean);
+		}
+	}
+
+	/* check except process, free skb and jump the desc */
+	if (unlikely((!bnum) || (bnum > ring->max_desc_num_per_pkt))) {
+out_bnum_err:
+		*out_bnum = *out_bnum ? *out_bnum : 1; /* ntc moved,cannot 0*/
+		netdev_err(ndev, "invalid bnum(%d,%d,%d,%d),%016llx,%016llx\n",
+			   bnum, ring->max_desc_num_per_pkt,
+			   length, (int)MAX_SKB_FRAGS,
+			   ((u64 *)desc)[0], ((u64 *)desc)[1]);
+		ring->stats.err_bd_num++;
+		dev_kfree_skb_any(skb);
+		return -EDOM;
+	}
+
+	bnum_flag = le32_to_cpu(desc->rx.ipoff_bnum_pid_flag);
+
+	if (unlikely(!hnae_get_bit(bnum_flag, HNS_RXD_VLD_B))) {
+		netdev_err(ndev, "no valid bd,%016llx,%016llx\n",
+			   ((u64 *)desc)[0], ((u64 *)desc)[1]);
+		ring->stats.non_vld_descs++;
+		dev_kfree_skb_any(skb);
+		return -EINVAL;
+	}
+
+	if (unlikely((!desc->rx.pkt_len) ||
+		     hnae_get_bit(bnum_flag, HNS_RXD_DROP_B))) {
+		if (!(ring->stats.err_pkt_len % RCB_ERR_PRINT_CYCLE))
+			netdev_dbg(ndev,
+				   "pkt_len(%u),drop(%u),%#llx,%#llx\n",
+				   le16_to_cpu(desc->rx.pkt_len),
+				   hnae_get_bit(bnum_flag, HNS_RXD_DROP_B),
+				   ((u64 *)desc)[0], ((u64 *)desc)[1]);
+		ring->stats.err_pkt_len++;
+		dev_kfree_skb_any(skb);
+		return -EFAULT;
+	}
+
+	if (unlikely(hnae_get_bit(bnum_flag, HNS_RXD_L2E_B) ||
+		     hnae_get_bit(bnum_flag, HNS_RXD_L3E_B) ||
+		     hnae_get_bit(bnum_flag, HNS_RXD_L4E_B))) {
+		if (!(ring->stats.csum_err % RCB_ERR_PRINT_CYCLE))
+			netdev_dbg(ndev,
+				   "check err(%#x),%#llx,%#llx\n",
+				   hnae_get_bit(bnum_flag, HNS_RXD_L2E_B) |
+				   hnae_get_bit(bnum_flag, HNS_RXD_L3E_B) |
+				   hnae_get_bit(bnum_flag, HNS_RXD_L4E_B),
+				   ((u64 *)desc)[0], ((u64 *)desc)[1]);
+		ring->stats.csum_err++;
+		dev_kfree_skb_any(skb);
+		return -EFAULT;
+	}
+
+	ring->stats.pkts.rx_pkts++;
+	ring->stats.bytes.rx_bytes += skb->len;
+
+	return 0;
+}
+
+static inline void hns_nic_alloc_rx_buffers(struct hns_nic_ring_data *ring_data,
+					    int cleand_count)
+{
+	int i, ret;
+	struct hnae_desc_cb res_cbs;
+	struct hnae_desc *desc;
+	struct hnae_desc_cb *desc_cb;
+	struct hnae_ring *ring = ring_data->ring;
+	struct net_device *ndev = ring_data->napi.dev;
+
+	for (i = 0; i < cleand_count; i++) {
+		desc = &ring->desc[ring->next_to_use];
+		desc_cb = &ring->desc_cb[ring->next_to_use];
+		if (desc_cb->reuse_flag) {
+			ring->stats.reuse_pg_cnt++;
+			hnae_reuse_buffer(ring, ring->next_to_use);
+		} else {
+			ret = hnae_reserve_buffer_map(ring, &res_cbs);
+			if (ret) {
+				ring->stats.sw_err_cnt++;
+				netdev_err(ndev, "hnae reserve buffer map failed.\n");
+				break;
+			}
+			hnae_replace_buffer(ring, ring->next_to_use, &res_cbs);
+		}
+
+		ring_ptr_move_fw(ring, next_to_use);
+	}
+
+	wmb(); /* make all data has been write before submit */
+	writel_relaxed(i, ring->io_base + RCB_REG_HEAD);
+}
+
+/* return error number for error or number of desc left to take
+ */
+static void hns_nic_rx_up_pro(struct hns_nic_ring_data *ring_data,
+			      struct sk_buff *skb)
+{
+	struct net_device *ndev = ring_data->napi.dev;
+
+	skb->ip_summed = CHECKSUM_UNNECESSARY;
+	skb->protocol = eth_type_trans(skb, ndev);
+	(void)napi_gro_receive(&ring_data->napi, skb);
+	ndev->last_rx = jiffies;
+}
+
+static int hns_nic_rx_poll_one(struct hns_nic_ring_data *ring_data,
+			       int budget, void *v)
+{
+	struct hnae_ring *ring = ring_data->ring;
+	struct sk_buff *skb;
+	int num, bnum, ex_num;
+#define RCB_NOF_ALLOC_RX_BUFF_ONCE 16
+	int recv_pkts, recv_bds, clean_count, err;
+
+	num = readl_relaxed(ring->io_base + RCB_REG_FBDNUM);
+	rmb(); /* make sure num taken effect before the other data is touched */
+
+	recv_pkts = 0, recv_bds = 0, clean_count = 0;
+recv:
+	while (recv_pkts < budget && recv_bds < num) {
+		/* reuse or realloc buffers*/
+		if (clean_count >= RCB_NOF_ALLOC_RX_BUFF_ONCE) {
+			hns_nic_alloc_rx_buffers(ring_data, clean_count);
+			clean_count = 0;
+		}
+
+		/* poll one pkg*/
+		err = hns_nic_poll_rx_skb(ring_data, &skb, &bnum);
+		if (unlikely(!skb)) /* this fault cannot be repaired */
+			break;
+
+		recv_bds += bnum;
+		clean_count += bnum;
+		if (unlikely(err))  /* do jump the err */
+			continue;
+
+		/* do update ip stack process*/
+		((void (*)(struct hns_nic_ring_data *, struct sk_buff *))v)(
+							ring_data, skb);
+		recv_pkts++;
+	}
+
+	/* make all data has been write before submit */
+	if (clean_count > 0) {
+		hns_nic_alloc_rx_buffers(ring_data, clean_count);
+		clean_count = 0;
+	}
+
+	if (recv_pkts < budget) {
+		ex_num = readl_relaxed(ring->io_base + RCB_REG_FBDNUM);
+		rmb(); /*complete read rx ring bd number*/
+		if (ex_num > 0) {
+			num += ex_num;
+			goto recv;
+		}
+	}
+
+	return recv_pkts;
+}
+
+static inline void hns_nic_reclaim_one_desc(struct hnae_ring *ring,
+					    int *bytes, int *pkts)
+{
+	struct hnae_desc_cb *desc_cb = &ring->desc_cb[ring->next_to_clean];
+
+	(*pkts) += (desc_cb->type == DESC_TYPE_SKB);
+	(*bytes) += desc_cb->length;
+	/* desc_cb will be cleaned, after hnae_free_buffer_detach*/
+	hnae_free_buffer_detach(ring, ring->next_to_clean);
+
+	ring_ptr_move_fw(ring, next_to_clean);
+}
+
+static int is_valid_clean_head(struct hnae_ring *ring, int h)
+{
+	int u = ring->next_to_use;
+	int c = ring->next_to_clean;
+
+	if (unlikely(h > ring->desc_num))
+		return 0;
+
+	assert(u > 0 && u < ring->desc_num);
+	assert(c > 0 && c < ring->desc_num);
+	assert(u != c && h != c); /* must be checked before call this func */
+
+	return u > c ? (h > c && h <= u) : (h > c || h <= u);
+}
+
+/* netif_tx_lock will turn down the performance, set only when necessary */
+#ifdef CONFIG_NET_POLL_CONTROLLER
+#define NETIF_TX_LOCK(ndev) netif_tx_lock(ndev)
+#define NETIF_TX_UNLOCK(ndev) netif_tx_unlock(ndev)
+#else
+#define NETIF_TX_LOCK(ndev)
+#define NETIF_TX_UNLOCK(ndev)
+#endif
+/* reclaim all desc in one budget
+ * return error or number of desc left
+ */
+static int hns_nic_tx_poll_one(struct hns_nic_ring_data *ring_data,
+			       int budget, void *v)
+{
+	struct hnae_ring *ring = ring_data->ring;
+	struct net_device *ndev = ring_data->napi.dev;
+	struct netdev_queue *dev_queue;
+	int head;
+	int bytes, pkts;
+
+	NETIF_TX_LOCK(ndev);
+
+	head = readl_relaxed(ring->io_base + RCB_REG_HEAD);
+	rmb(); /* make sure head is ready before touch any data */
+
+	if (is_ring_empty(ring) || head == ring->next_to_clean) {
+		NETIF_TX_UNLOCK(ndev);
+		return 0; /* no data to poll */
+	}
+
+	if (!is_valid_clean_head(ring, head)) {
+		netdev_err(ndev, "wrong head (%d, %d-%d)\n", head,
+			   ring->next_to_use, ring->next_to_clean);
+		ring->stats.io_err_cnt++;
+		NETIF_TX_UNLOCK(ndev);
+		return -EIO;
+	}
+
+	bytes = 0;
+	pkts = 0;
+	while (head != ring->next_to_clean)
+		hns_nic_reclaim_one_desc(ring, &bytes, &pkts);
+
+	NETIF_TX_UNLOCK(ndev);
+
+	dev_queue = netdev_get_tx_queue(ndev, ring_data->queue_index);
+	netdev_tx_completed_queue(dev_queue, pkts, bytes);
+
+	if (unlikely(netif_tx_queue_stopped(dev_queue)))
+		netif_tx_wake_queue(dev_queue);
+
+	return 0;
+}
+
+static void hns_nic_tx_clr_all_bufs(struct hns_nic_ring_data *ring_data)
+{
+	struct hnae_ring *ring = ring_data->ring;
+	struct net_device *ndev = ring_data->napi.dev;
+	struct netdev_queue *dev_queue;
+	int head;
+	int bytes, pkts;
+
+	NETIF_TX_LOCK(ndev);
+
+	head = ring->next_to_use; /* ntu :soft setted ring position*/
+	bytes = 0;
+	pkts = 0;
+	while (head != ring->next_to_clean)
+		hns_nic_reclaim_one_desc(ring, &bytes, &pkts);
+
+	NETIF_TX_UNLOCK(ndev);
+
+	dev_queue = netdev_get_tx_queue(ndev, ring_data->queue_index);
+	netdev_tx_reset_queue(dev_queue);
+}
+
+static int hns_nic_common_poll(struct napi_struct *napi, int budget)
+{
+	struct hns_nic_ring_data *ring_data =
+		container_of(napi, struct hns_nic_ring_data, napi);
+	int clean_complete = ring_data->poll_one(
+				ring_data, budget, ring_data->ex_process);
+
+	if (clean_complete >= 0 && clean_complete < budget) {
+		napi_complete(napi);
+		ring_data->ring->q->handle->dev->ops->toggle_ring_irq(
+			ring_data->ring, 0);
+	}
+
+	return clean_complete;
+}
+
+static irqreturn_t hns_irq_handle(int irq, void *dev)
+{
+	struct hns_nic_ring_data *ring_data = (struct hns_nic_ring_data *)dev;
+
+	ring_data->ring->q->handle->dev->ops->toggle_ring_irq(
+		ring_data->ring, 1);
+	napi_schedule(&ring_data->napi);
+
+	return IRQ_HANDLED;
+}
+
+/**
+ *hns_nic_adjust_link - adjust net work mode by the phy stat or new param
+ *@ndev: net device
+ */
+static void hns_nic_adjust_link(struct net_device *ndev)
+{
+	struct hns_nic_priv *priv = netdev_priv(ndev);
+	struct hnae_handle *h = priv->ae_handle;
+
+	h->dev->ops->adjust_link(h, ndev->phydev->speed, ndev->phydev->duplex);
+}
+
+/**
+ *hns_nic_init_phy - init phy
+ *@ndev: net device
+ *@h: ae handle
+ * Return 0 on success, negative on failure
+ */
+int hns_nic_init_phy(struct net_device *ndev, struct hnae_handle *h)
+{
+	struct hns_nic_priv *priv = netdev_priv(ndev);
+	struct phy_device *phy_dev = NULL;
+
+	if (!h->phy_node)
+		return 0;
+
+	if (h->phy_if != PHY_INTERFACE_MODE_XGMII)
+		phy_dev = of_phy_connect(ndev, h->phy_node,
+					 hns_nic_adjust_link, 0, h->phy_if);
+	else
+		phy_dev = of_phy_attach(ndev, h->phy_node, 0, h->phy_if);
+
+	if (unlikely(!phy_dev) || IS_ERR(phy_dev))
+		return !phy_dev ? -ENODEV : PTR_ERR(phy_dev);
+
+	phy_dev->supported &= h->if_support;
+	phy_dev->advertising = phy_dev->supported;
+
+	if (h->phy_if == PHY_INTERFACE_MODE_XGMII)
+		phy_dev->autoneg = false;
+
+	priv->phy = phy_dev;
+
+	return 0;
+}
+
+static int hns_nic_ring_open(struct net_device *netdev, int idx)
+{
+	struct hns_nic_priv *priv = netdev_priv(netdev);
+	struct hnae_handle *h = priv->ae_handle;
+
+	napi_enable(&priv->ring_data[idx].napi);
+
+	enable_irq(priv->ring_data[idx].ring->irq);
+	h->dev->ops->toggle_ring_irq(priv->ring_data[idx].ring, 0);
+
+	return 0;
+}
+
+static int hns_nic_net_set_mac_address(struct net_device *ndev, void *p)
+{
+	struct hns_nic_priv *priv = netdev_priv(ndev);
+	struct hnae_handle *h = priv->ae_handle;
+	struct sockaddr *mac_addr = p;
+	int ret;
+
+	if (!mac_addr || !is_valid_ether_addr((const u8 *)mac_addr->sa_data))
+		return -EADDRNOTAVAIL;
+
+	ret = h->dev->ops->set_mac_addr(h, mac_addr->sa_data);
+	if (ret) {
+		netdev_err(ndev, "set_mac_address fail, ret=%d!\n", ret);
+		return ret;
+	}
+
+	memcpy(ndev->dev_addr, mac_addr->sa_data, ndev->addr_len);
+
+	return 0;
+}
+
+void hns_nic_update_stats(struct net_device *netdev)
+{
+	struct hns_nic_priv *priv = netdev_priv(netdev);
+	struct hnae_handle *h = priv->ae_handle;
+
+	h->dev->ops->update_stats(h, &h->net_stats);
+
+	netdev->stats.rx_bytes = h->net_stats.rx_bytes;
+	netdev->stats.rx_packets = h->net_stats.rx_packets;
+	netdev->stats.tx_bytes = h->net_stats.tx_bytes;
+	netdev->stats.tx_packets = h->net_stats.tx_packets;
+	netdev->stats.rx_crc_errors = h->net_stats.rx_crc_errors;
+	netdev->stats.rx_frame_errors = h->net_stats.rx_frame_errors;
+	netdev->stats.rx_fifo_errors = h->net_stats.rx_fifo_errors;
+	netdev->stats.rx_length_errors = h->net_stats.rx_length_errors;
+	netdev->stats.multicast = h->net_stats.multicast;
+	netdev->stats.rx_errors = h->net_stats.rx_errors;
+	netdev->stats.rx_dropped = h->net_stats.rx_dropped;
+	netdev->stats.tx_errors = h->net_stats.tx_errors;
+	netdev->stats.tx_dropped = h->net_stats.tx_dropped;
+}
+
+/* set mac addr if it is configed. or leave it to the AE driver */
+static inline void hns_init_mac_addr(struct net_device *ndev)
+{
+	struct hns_nic_priv *priv = netdev_priv(ndev);
+	struct device_node *node = priv->dev->of_node;
+	const void *mac_addr_temp;
+
+	mac_addr_temp = of_get_mac_address(node);
+	if (mac_addr_temp && is_valid_ether_addr(mac_addr_temp)) {
+		memcpy(ndev->dev_addr, mac_addr_temp, ndev->addr_len);
+	} else {
+		eth_hw_addr_random(ndev);
+		dev_warn(priv->dev, "No valid mac, use random mac %pM",
+			 ndev->dev_addr);
+	}
+}
+
+static void hns_nic_ring_close(struct net_device *netdev, int idx)
+{
+	struct hns_nic_priv *priv = netdev_priv(netdev);
+	struct hnae_handle *h = priv->ae_handle;
+
+	h->dev->ops->toggle_ring_irq(priv->ring_data[idx].ring, 1);
+	disable_irq(priv->ring_data[idx].ring->irq);
+
+	napi_disable(&priv->ring_data[idx].napi);
+}
+
+static int hns_nic_net_up(struct net_device *ndev)
+{
+	struct hns_nic_priv *priv = netdev_priv(ndev);
+	struct hnae_handle *h = priv->ae_handle;
+	int i, j, k;
+	int ret;
+
+	if (h->phy_node) {
+		ret = hns_nic_init_phy(ndev, h);
+		if (ret)
+			goto out;
+	}
+
+	for (i = 0; i < h->q_num * 2; i++) {
+		ret = hns_nic_ring_open(ndev, i);
+		if (ret)
+			goto out_has_some_queues;
+	}
+
+	for (k = 0; k < h->q_num; k++)
+		h->dev->ops->toggle_queue_status(h->qs[k], 1);
+
+	ret = h->dev->ops->set_mac_addr(h, ndev->dev_addr);
+	if (ret)
+		goto out_set_mac_addr_err;
+
+	ret = h->dev->ops->start ? h->dev->ops->start(h) : 0;
+	if (ret)
+		goto out_start_err;
+
+	if (priv->phy)
+		phy_start(priv->phy);
+
+	netif_tx_wake_all_queues(ndev);
+
+	clear_bit(NIC_STATE_DOWN, &priv->state);
+	(void)mod_timer(&priv->service_timer, jiffies + SERVICE_TIMER_HZ);
+
+	return 0;
+
+out_start_err:
+	netif_stop_queue(ndev);
+out_set_mac_addr_err:
+	for (k = 0; k < h->q_num; k++)
+		h->dev->ops->toggle_queue_status(h->qs[k], 0);
+out_has_some_queues:
+	for (j = i - 1; j >= 0; j--)
+		hns_nic_ring_close(ndev, j);
+out:
+	set_bit(NIC_STATE_DOWN, &priv->state);
+	return ret;
+}
+
+static void hns_nic_net_down(struct net_device *ndev)
+{
+	int i;
+	struct hnae_ae_ops *ops;
+	struct hns_nic_priv *priv = netdev_priv(ndev);
+
+	if (test_and_set_bit(NIC_STATE_DOWN, &priv->state))
+		return;
+
+	(void)del_timer_sync(&priv->service_timer);
+	priv->link = 0;
+	netif_carrier_off(ndev);
+
+	if (priv->phy) {
+		phy_stop(priv->phy);
+		phy_disconnect(priv->phy);
+		priv->phy = NULL;
+	}
+	ops = priv->ae_handle->dev->ops;
+
+	if (ops->stop)
+		ops->stop(priv->ae_handle);
+
+	netif_tx_stop_all_queues(ndev);
+
+	for (i = priv->ae_handle->q_num - 1; i >= 0; i--) {
+		hns_nic_ring_close(ndev, i);
+		hns_nic_ring_close(ndev, i + priv->ae_handle->q_num);
+
+		/* clean tx buffers*/
+		hns_nic_tx_clr_all_bufs(priv->ring_data + i);
+	}
+}
+
+void hns_nic_net_reset(struct net_device *ndev)
+{
+	struct hns_nic_priv *priv = netdev_priv(ndev);
+	struct hnae_handle *handle = priv->ae_handle;
+
+	while (test_and_set_bit(NIC_STATE_RESETTING, &priv->state))
+		usleep_range(1000, 2000);
+
+	if (handle->dev->ops->stop)
+		handle->dev->ops->stop(handle);
+	msleep(100);
+
+	if (handle->dev->ops->reset)
+		handle->dev->ops->reset(handle);
+	(void)hnae_reinit_handle(handle);
+
+	clear_bit(NIC_STATE_RESETTING, &priv->state);
+}
+
+void hns_nic_net_reinit(struct net_device *netdev)
+{
+	struct hns_nic_priv *priv = netdev_priv(netdev);
+
+	priv->netdev->trans_start = jiffies;
+	while (test_and_set_bit(NIC_STATE_REINITING, &priv->state))
+		usleep_range(1000, 2000);
+
+	hns_nic_net_down(netdev);
+	hns_nic_net_reset(netdev);
+	(void)hns_nic_net_up(netdev);
+	clear_bit(NIC_STATE_REINITING, &priv->state);
+}
+
+static int hns_nic_net_open(struct net_device *ndev)
+{
+	struct hns_nic_priv *priv = netdev_priv(ndev);
+	struct hnae_handle *h = priv->ae_handle;
+	int ret;
+
+	if (test_bit(NIC_STATE_TESTING, &priv->state))
+		return -EBUSY;
+
+	priv->link = 0;
+	netif_carrier_off(ndev);
+
+	ret = netif_set_real_num_tx_queues(ndev, h->q_num);
+	if (ret < 0) {
+		netdev_err(ndev, "netif_set_real_num_tx_queues fail, ret=%d!\n",
+			   ret);
+		return ret;
+	}
+
+	ret = netif_set_real_num_rx_queues(ndev, h->q_num);
+	if (ret < 0) {
+		netdev_err(ndev,
+			   "netif_set_real_num_rx_queues fail, ret=%d!\n", ret);
+		return ret;
+	}
+
+	ret = hns_nic_net_up(ndev);
+	if (ret) {
+		netdev_err(ndev,
+			   "hns net up fail, ret=%d!\n", ret);
+		return ret;
+	}
+
+	return 0;
+}
+
+static int hns_nic_net_stop(struct net_device *ndev)
+{
+	hns_nic_net_down(ndev);
+
+	return 0;
+}
+
+static void hns_tx_timeout_reset(struct hns_nic_priv *priv);
+static void hns_nic_net_timeout(struct net_device *ndev)
+{
+	struct hns_nic_priv *priv = netdev_priv(ndev);
+
+	hns_tx_timeout_reset(priv);
+}
+
+static int hns_nic_do_ioctl(struct net_device *netdev, struct ifreq *ifr,
+			    int cmd)
+{
+	switch (cmd) {
+	default:
+		return -ENOTSUPP;
+	}
+}
+
+/* use only for netconsole to poll with the device without interrupt */
+#ifdef CONFIG_NET_POLL_CONTROLLER
+void hns_nic_poll_controller(struct net_device *ndev)
+{
+	struct hns_nic_priv *priv = netdev_priv(ndev);
+	unsigned long flags;
+	int i;
+
+	local_irq_save(flags);
+	for (i = 0; i < priv->ae_handle->q_num * 2; i++)
+		napi_schedule(&priv->ring_data[i].napi);
+	local_irq_restore(flags);
+}
+#endif
+
+static netdev_tx_t hns_nic_net_xmit(struct sk_buff *skb,
+				    struct net_device *ndev)
+{
+	struct hns_nic_priv *priv = netdev_priv(ndev);
+	int ret;
+
+	assert(skb->queue_mapping < ndev->ae_handle->q_num);
+	ret = hns_nic_net_xmit_hw(ndev, skb,
+				  &tx_ring_data(priv, skb->queue_mapping));
+	if (ret == NETDEV_TX_OK) {
+		ndev->trans_start = jiffies;
+		ndev->stats.tx_bytes += skb->len;
+		ndev->stats.tx_packets++;
+	}
+	return (netdev_tx_t)ret;
+}
+
+static int hns_nic_change_mtu(struct net_device *ndev, int new_mtu)
+{
+	struct hns_nic_priv *priv = netdev_priv(ndev);
+	struct hnae_handle *h = priv->ae_handle;
+	int ret;
+
+	/* MTU < 68 is an error and causes problems on some kernels */
+	if (new_mtu < 68)
+		return -EINVAL;
+
+	if (!h->dev->ops->set_mtu)
+		return -ENOTSUPP;
+
+	if (netif_running(ndev)) {
+		hns_nic_net_stop(ndev);
+		msleep(100);
+
+		ret = h->dev->ops->set_mtu(h, new_mtu);
+		if (ret)
+			netdev_err(ndev, "set mtu fail, return value %d\n",
+				   ret);
+
+		if (hns_nic_net_open(ndev))
+			netdev_err(ndev, "hns net open fail\n");
+	} else {
+		ret = h->dev->ops->set_mtu(h, new_mtu);
+	}
+
+	if (!ret)
+		ndev->mtu = new_mtu;
+
+	return ret;
+}
+
+/**
+ * nic_set_multicast_list - set mutl mac address
+ * @netdev: net device
+ * @p: mac address
+ *
+ * return void
+ */
+void hns_set_multicast_list(struct net_device *ndev)
+{
+	struct hns_nic_priv *priv = netdev_priv(ndev);
+	struct hnae_handle *h = priv->ae_handle;
+	struct netdev_hw_addr *ha = NULL;
+
+	assert(priv);
+
+	if (netif_running(ndev))
+		return;
+
+	if (!h)	{
+		netdev_err(ndev, "hnae handle is null\n");
+		return;
+	}
+
+	if (h->dev->ops->set_mc_addr) {
+		netdev_for_each_mc_addr(ha, ndev)
+			if (h->dev->ops->set_mc_addr(h, ha->addr))
+				netdev_err(ndev, "set multicast fail\n");
+	}
+}
+
+struct rtnl_link_stats64 *hns_nic_get_stats64(struct net_device *ndev,
+					      struct rtnl_link_stats64 *stats)
+{
+	int idx = 0;
+	u64 tx_bytes = 0;
+	u64 rx_bytes = 0;
+	u64 tx_pkts = 0;
+	u64 rx_pkts = 0;
+	struct hns_nic_priv *priv = netdev_priv(ndev);
+	struct hnae_handle *h = priv->ae_handle;
+
+	for (idx = 0; idx < h->q_num; idx++) {
+		tx_bytes += h->qs[idx]->tx_ring.stats.bytes.tx_bytes;
+		tx_pkts += h->qs[idx]->tx_ring.stats.pkts.tx_pkts;
+		rx_bytes += h->qs[idx]->rx_ring.stats.bytes.rx_bytes;
+		rx_pkts += h->qs[idx]->rx_ring.stats.pkts.rx_pkts;
+	}
+
+	stats->tx_bytes = tx_bytes;
+	stats->tx_packets = tx_pkts;
+	stats->rx_bytes = rx_bytes;
+	stats->rx_packets = rx_pkts;
+
+	stats->rx_errors = ndev->stats.rx_errors;
+	stats->multicast = ndev->stats.multicast;
+	stats->rx_length_errors = ndev->stats.rx_length_errors;
+	stats->rx_crc_errors = ndev->stats.rx_crc_errors;
+	stats->rx_missed_errors = ndev->stats.rx_missed_errors;
+
+	stats->tx_errors = ndev->stats.tx_errors;
+	stats->rx_dropped = ndev->stats.rx_dropped;
+	stats->tx_dropped = ndev->stats.tx_dropped;
+	stats->collisions = ndev->stats.collisions;
+	stats->rx_over_errors = ndev->stats.rx_over_errors;
+	stats->rx_frame_errors = ndev->stats.rx_frame_errors;
+	stats->rx_fifo_errors = ndev->stats.rx_fifo_errors;
+	stats->tx_aborted_errors = ndev->stats.tx_aborted_errors;
+	stats->tx_carrier_errors = ndev->stats.tx_carrier_errors;
+	stats->tx_fifo_errors = ndev->stats.tx_fifo_errors;
+	stats->tx_heartbeat_errors = ndev->stats.tx_heartbeat_errors;
+	stats->tx_window_errors = ndev->stats.tx_window_errors;
+	stats->rx_compressed = ndev->stats.rx_compressed;
+	stats->tx_compressed = ndev->stats.tx_compressed;
+
+	return stats;
+}
+
+static const struct net_device_ops hns_nic_netdev_ops = {
+	.ndo_open = hns_nic_net_open,
+	.ndo_stop = hns_nic_net_stop,
+	.ndo_start_xmit = hns_nic_net_xmit,
+	.ndo_tx_timeout = hns_nic_net_timeout,
+	.ndo_set_mac_address = hns_nic_net_set_mac_address,
+	.ndo_change_mtu = hns_nic_change_mtu,
+	.ndo_do_ioctl = hns_nic_do_ioctl,
+	.ndo_get_stats64 = hns_nic_get_stats64,
+#ifdef CONFIG_NET_POLL_CONTROLLER
+	.ndo_poll_controller = hns_nic_poll_controller,
+#endif
+	.ndo_set_rx_mode = hns_set_multicast_list,
+};
+
+static void hns_nic_update_link_status(struct net_device *netdev)
+{
+	struct hns_nic_priv *priv = netdev_priv(netdev);
+
+	struct hnae_handle *h = priv->ae_handle;
+	int state = 1;
+
+	if (priv->phy) {
+		if (!genphy_update_link(priv->phy))
+			state = priv->phy->link;
+		else
+			state = 0;
+	}
+	state = state && h->dev->ops->get_status(h);
+
+	if (state != priv->link) {
+		if (state) {
+			netif_carrier_on(netdev);
+			netdev_info(netdev, "link up\n");
+		} else {
+			netif_carrier_off(netdev);
+			netdev_info(netdev, "link down\n");
+		}
+		priv->link = state;
+	}
+}
+
+/* for dumping key regs*/
+static void hns_nic_dump(struct hns_nic_priv *priv)
+{
+	struct hnae_ae_ops *ops = priv->ae_handle->dev->ops;
+	u32 *data, reg_num, i;
+
+	if (ops->get_regs_len && ops->get_regs) {
+		reg_num = ops->get_regs_len(priv->ae_handle);
+		reg_num = (reg_num + 3ul) & ~3ul;
+		data = kcalloc(reg_num, sizeof(u32), GFP_KERNEL);
+		if (data) {
+			ops->get_regs(priv->ae_handle, data);
+			for (i = 0; i < reg_num; i++)
+				pr_info("0x%08x: 0x%08x 0x%08x 0x%08x 0x%08x\n",
+					i, data[i], data[i + 1],
+					data[i + 2], data[i + 3]);
+			kfree(data);
+		}
+	}
+}
+
+/* for resetting suntask*/
+static void hns_nic_reset_subtask(struct hns_nic_priv *priv)
+{
+	enum hnae_port_type type = priv->ae_handle->port_type;
+
+	if (!test_bit(NIC_STATE2_RESET_REQUESTED, &priv->state))
+		return;
+	clear_bit(NIC_STATE2_RESET_REQUESTED, &priv->state);
+
+	/* If we're already down, removing or resetting, just bail */
+	if (test_bit(NIC_STATE_DOWN, &priv->state) ||
+	    test_bit(NIC_STATE_REMOVING, &priv->state) ||
+	    test_bit(NIC_STATE_RESETTING, &priv->state))
+		return;
+
+	hns_nic_dump(priv);
+	netdev_err(priv->netdev, "Reset %s port\n",
+		   (type == HNAE_PORT_DEBUG ? "debug" : "business"));
+
+	rtnl_lock();
+	if (type == HNAE_PORT_DEBUG) {
+		hns_nic_net_reinit(priv->netdev);
+	} else {
+		hns_nic_net_down(priv->netdev);
+		hns_nic_net_reset(priv->netdev);
+	}
+	rtnl_unlock();
+}
+
+/* for doing service complete*/
+static void hns_nic_service_event_complete(struct hns_nic_priv *priv)
+{
+	BUG_ON(!test_bit(NIC_STATE_SERVICE_SCHED, &priv->state));
+
+	smp_mb__before_atomic();
+	clear_bit(NIC_STATE_SERVICE_SCHED, &priv->state);
+}
+
+static void hns_nic_service_task(struct work_struct *work)
+{
+	struct hns_nic_priv *priv
+		= container_of(work, struct hns_nic_priv, service_task);
+	struct hnae_handle *h = priv->ae_handle;
+
+	hns_nic_update_link_status(priv->netdev);
+	h->dev->ops->update_led_status(h);
+	hns_nic_update_stats(priv->netdev);
+
+	hns_nic_reset_subtask(priv);
+	hns_nic_service_event_complete(priv);
+}
+
+static void hns_nic_task_schedule(struct hns_nic_priv *priv)
+{
+	if (!test_bit(NIC_STATE_DOWN, &priv->state) &&
+	    !test_bit(NIC_STATE_REMOVING, &priv->state) &&
+	    !test_and_set_bit(NIC_STATE_SERVICE_SCHED, &priv->state))
+		(void)schedule_work(&priv->service_task);
+}
+
+static void hns_nic_service_timer(unsigned long data)
+{
+	struct hns_nic_priv *priv = (struct hns_nic_priv *)data;
+
+	(void)mod_timer(&priv->service_timer, jiffies + SERVICE_TIMER_HZ);
+
+	hns_nic_task_schedule(priv);
+}
+
+/**
+ * hns_tx_timeout_reset - initiate reset due to Tx timeout
+ * @priv: driver private struct
+ **/
+static void hns_tx_timeout_reset(struct hns_nic_priv *priv)
+{
+	/* Do the reset outside of interrupt context */
+	if (!test_bit(NIC_STATE_DOWN, &priv->state)) {
+		set_bit(NIC_STATE2_RESET_REQUESTED, &priv->state);
+		netdev_warn(priv->netdev,
+			    "initiating reset due to tx timeout(%llu,0x%lx)\n",
+			    priv->tx_timeout_count, priv->state);
+		priv->tx_timeout_count++;
+		hns_nic_task_schedule(priv);
+	}
+}
+
+static int hns_nic_init_ring_data(struct hns_nic_priv *priv)
+{
+	struct hnae_handle *h = priv->ae_handle;
+	struct hns_nic_ring_data *rd;
+	int i, j;
+	int ret;
+
+	if (h->q_num > NIC_MAX_Q_PER_VF) {
+		ret = -EINVAL;
+		netdev_err(priv->netdev, "too much queue (%d)\n", h->q_num);
+		goto out;
+	}
+
+	priv->ring_data = kzalloc(h->q_num * sizeof(*priv->ring_data) * 2,
+				  GFP_KERNEL);
+	if (!priv->ring_data) {
+		ret = -ENOMEM;
+		netdev_err(priv->netdev, "malloc ring data fail\n");
+		goto out;
+	}
+
+	for (i = 0; i < h->q_num; i++) {
+		rd = &priv->ring_data[i];
+		rd->queue_index = i;
+		rd->ring = &h->qs[i]->tx_ring;
+		rd->poll_one = hns_nic_tx_poll_one;
+
+		snprintf(rd->ring->ring_name, RCB_RING_NAME_LEN, "eth%s-tx%d",
+			 h->ae_opts, rd->queue_index);
+		rd->ring->ring_name[RCB_RING_NAME_LEN - 1] = '\0';
+
+		ret = request_irq(rd->ring->irq,
+				  hns_irq_handle, 0, rd->ring->ring_name, rd);
+		if (ret) {
+			netdev_err(priv->netdev, "request irq(%d) fail\n",
+				   rd->ring->irq);
+			goto out_has_some_queues;
+		}
+		disable_irq(rd->ring->irq);
+		netif_napi_add(priv->netdev, &rd->napi,
+			       hns_nic_common_poll, NIC_TX_CLEAN_MAX_NUM);
+	}
+	for (i = h->q_num; i < h->q_num * 2; i++) {
+		rd = &priv->ring_data[i];
+		rd->queue_index = i - h->q_num;
+		rd->ring = &h->qs[i - h->q_num]->rx_ring;
+		rd->poll_one = hns_nic_rx_poll_one;
+		rd->ex_process = hns_nic_rx_up_pro;
+
+		snprintf(rd->ring->ring_name, RCB_RING_NAME_LEN, "eth%s-rx%d",
+			 h->ae_opts, rd->queue_index);
+		rd->ring->ring_name[RCB_RING_NAME_LEN - 1] = '\0';
+
+		ret = request_irq(rd->ring->irq,
+				  hns_irq_handle, 0, rd->ring->ring_name, rd);
+		if (ret) {
+			netdev_err(priv->netdev, "request irq(%d) fail\n",
+				   rd->ring->irq);
+			goto out_has_some_queues;
+		}
+		disable_irq(rd->ring->irq);
+		netif_napi_add(priv->netdev, &rd->napi,
+			       hns_nic_common_poll, NIC_RX_CLEAN_MAX_NUM);
+	}
+
+	return 0;
+
+out_has_some_queues:
+	for (j = i - 1; j >= 0; j--) {
+		netif_napi_del(&priv->ring_data[j].napi);
+		free_irq(priv->ring_data[j].ring->irq, &priv->ring_data[j]);
+	}
+	kfree(priv->ring_data);
+	priv->ring_data = NULL;
+out:
+	return ret;
+}
+
+static void hns_nic_uninit_ring_data(struct hns_nic_priv *priv)
+{
+	struct hnae_handle *h = priv->ae_handle;
+	int i;
+
+	for (i = 0; i < h->q_num * 2; i++) {
+		netif_napi_del(&priv->ring_data[i].napi);
+		free_irq(priv->ring_data[i].ring->irq, &priv->ring_data[i]);
+	}
+	kfree(priv->ring_data);
+}
+
+static int hns_nic_try_get_ae(struct net_device *ndev)
+{
+	struct hns_nic_priv *priv = netdev_priv(ndev);
+	struct hnae_handle *h;
+	int ret;
+
+	h = hnae_get_handle(&priv->netdev->dev,
+			    priv->ae_name, priv->ae_opts, NULL);
+	if (IS_ERR_OR_NULL(h)) {
+		ret = PTR_ERR(h);
+		dev_dbg(priv->dev, "has not handle, register notifier!\n");
+		goto out;
+	}
+	priv->ae_handle = h;
+
+	ret = hns_nic_init_ring_data(priv);
+	if (ret) {
+		ret = -ENOMEM;
+		goto out_init_ring_data;
+	}
+
+	ret = register_netdev(ndev);
+	if (ret) {
+		dev_err(priv->dev, "probe register netdev fail!\n");
+		goto out_reg_ndev_fail;
+	}
+	return 0;
+
+out_reg_ndev_fail:
+	hns_nic_uninit_ring_data(priv);
+	priv->ring_data = NULL;
+out_init_ring_data:
+	hnae_put_handle(priv->ae_handle);
+	priv->ae_handle = NULL;
+out:
+	return ret;
+}
+
+static int hns_nic_notifier_action(struct notifier_block *nb,
+				   unsigned long action, void *data)
+{
+	struct hns_nic_priv *priv =
+		container_of(nb, struct hns_nic_priv, notifier_block);
+
+	assert(action == HNAE_AE_REGISTER);
+
+	if (!hns_nic_try_get_ae(priv->netdev)) {
+		hnae_unregister_notifier(&priv->notifier_block);
+		priv->notifier_block.notifier_call = NULL;
+	}
+	return 0;
+}
+
+static int hns_nic_dev_probe(struct platform_device *pdev)
+{
+	struct device *dev = &pdev->dev;
+	struct net_device *ndev;
+	struct hns_nic_priv *priv;
+	struct device_node *node = dev->of_node;
+	int ret;
+
+	ndev = alloc_etherdev_mq(sizeof(struct hns_nic_priv), NIC_MAX_Q_PER_VF);
+	if (!ndev)
+		return -ENOMEM;
+
+	platform_set_drvdata(pdev, ndev);
+
+	priv = netdev_priv(ndev);
+	priv->dev = dev;
+	priv->netdev = ndev;
+
+	ret = of_property_read_string(node, "ae-name", &priv->ae_name);
+	if (ret)
+		goto out_read_string_fail;
+
+	ret = of_property_read_string(node, "ae-opts", &priv->ae_opts);
+	if (ret)
+		goto out_read_string_fail;
+
+	hns_init_mac_addr(ndev);
+
+	ndev->watchdog_timeo = HNS_NIC_TX_TIMEOUT;
+	ndev->priv_flags |= IFF_UNICAST_FLT;
+	ndev->netdev_ops = &hns_nic_netdev_ops;
+	hns_ethtool_set_ops(ndev);
+	ndev->features |= NETIF_F_IP_CSUM | NETIF_F_IPV6_CSUM |
+		NETIF_F_RXCSUM | NETIF_F_SG | NETIF_F_GSO |
+		NETIF_F_GRO;
+	ndev->vlan_features |=
+		NETIF_F_IP_CSUM | NETIF_F_IPV6_CSUM | NETIF_F_RXCSUM;
+	ndev->vlan_features |= NETIF_F_SG | NETIF_F_GSO | NETIF_F_GRO;
+
+	SET_NETDEV_DEV(ndev, dev);
+
+	if (!dma_set_mask_and_coherent(dev, DMA_BIT_MASK(64)))
+		dev_dbg(dev, "set mask to 64bit\n");
+	else
+		dev_err(dev, "set mask to 32bit fail!\n");
+
+	/* carrier off reporting is important to ethtool even BEFORE open */
+	netif_carrier_off(ndev);
+
+	setup_timer(&priv->service_timer, hns_nic_service_timer,
+		    (unsigned long)priv);
+	INIT_WORK(&priv->service_task, hns_nic_service_task);
+
+	set_bit(NIC_STATE_SERVICE_INITED, &priv->state);
+	clear_bit(NIC_STATE_SERVICE_SCHED, &priv->state);
+	set_bit(NIC_STATE_DOWN, &priv->state);
+
+	if (hns_nic_try_get_ae(priv->netdev)) {
+		priv->notifier_block.notifier_call = hns_nic_notifier_action;
+		ret = hnae_register_notifier(&priv->notifier_block);
+		if (ret) {
+			dev_err(dev, "register notifier fail!\n");
+			goto out_notify_fail;
+		}
+		dev_dbg(dev, "has not handle, register notifier!\n");
+	}
+
+	return 0;
+
+out_notify_fail:
+	(void)cancel_work_sync(&priv->service_task);
+out_read_string_fail:
+	free_netdev(ndev);
+	return ret;
+}
+
+static int hns_nic_dev_remove(struct platform_device *pdev)
+{
+	struct net_device *ndev = platform_get_drvdata(pdev);
+	struct hns_nic_priv *priv = netdev_priv(ndev);
+
+	if (ndev->reg_state != NETREG_UNINITIALIZED)
+		unregister_netdev(ndev);
+
+	if (priv->ring_data)
+		hns_nic_uninit_ring_data(priv);
+	priv->ring_data = NULL;
+
+	if (!IS_ERR_OR_NULL(priv->ae_handle))
+		hnae_put_handle(priv->ae_handle);
+	priv->ae_handle = NULL;
+	if (priv->notifier_block.notifier_call)
+		hnae_unregister_notifier(&priv->notifier_block);
+	priv->notifier_block.notifier_call = NULL;
+
+	set_bit(NIC_STATE_REMOVING, &priv->state);
+	(void)cancel_work_sync(&priv->service_task);
+
+	free_netdev(ndev);
+	return 0;
+}
+
+static const struct of_device_id hns_enet_of_match[] = {
+	{.compatible = "hisilicon,hns-nic",},
+	{},
+};
+
+MODULE_DEVICE_TABLE(of, hns_enet_of_match);
+
+static struct platform_driver hns_nic_dev_driver = {
+	.driver = {
+		.name = "hns-nic",
+		.owner = THIS_MODULE,
+		.of_match_table = hns_enet_of_match,
+	},
+	.probe = hns_nic_dev_probe,
+	.remove = hns_nic_dev_remove,
+};
+
+module_platform_driver(hns_nic_dev_driver);
+
+MODULE_DESCRIPTION("HISILICON HNS Ethernet driver");
+MODULE_AUTHOR("Hisilicon, Inc.");
+MODULE_LICENSE("GPL v2");
+MODULE_ALIAS("platform:hns-nic");
diff --git a/drivers/net/ethernet/hisilicon/hns/hns_enet.h b/drivers/net/ethernet/hisilicon/hns/hns_enet.h
new file mode 100644
index 0000000..f632da4
--- /dev/null
+++ b/drivers/net/ethernet/hisilicon/hns/hns_enet.h
@@ -0,0 +1,81 @@
+/*
+ * Copyright (c) 2014-2015 Hisilicon Limited.
+ *
+ * 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.
+ */
+
+#ifndef __HNS_ENET_H
+#define __HNS_ENET_H
+
+#include <linux/timer.h>
+#include <linux/workqueue.h>
+#include <linux/of_net.h>
+#include <linux/of_mdio.h>
+#include <linux/netdevice.h>
+#include "hnae.h"
+
+enum hns_nic_state {
+	NIC_STATE_TESTING = 0,
+	NIC_STATE_RESETTING,
+	NIC_STATE_REINITING,
+	NIC_STATE_DOWN,
+	NIC_STATE_DISABLED,
+	NIC_STATE_REMOVING,
+	NIC_STATE_SERVICE_INITED,
+	NIC_STATE_SERVICE_SCHED,
+	NIC_STATE2_RESET_REQUESTED,
+	NIC_STATE_MAX
+};
+
+struct hns_nic_ring_data {
+	struct hnae_ring *ring;
+	struct napi_struct napi;
+	int queue_index;
+	int (*poll_one)(struct hns_nic_ring_data *, int, void *);
+	void (*ex_process)(struct hns_nic_ring_data *, struct sk_buff *);
+};
+
+struct hns_nic_priv {
+	const char *ae_name;
+	const char *ae_opts;
+	int phy_mode;
+	int phy_led_val;
+	struct phy_device *phy;
+	struct net_device *netdev;
+	struct device *dev;
+	struct hnae_handle *ae_handle;
+
+	/* the cb for nic to manage the ring buffer, the first half of the
+	 * array is for tx_ring and vice versa for the second half
+	 */
+	struct hns_nic_ring_data *ring_data;
+
+	/* The most recently read link state */
+	int link;
+	u64 tx_timeout_count;
+
+	unsigned long state;
+
+	struct timer_list service_timer;
+
+	struct work_struct service_task;
+
+	struct notifier_block notifier_block;
+};
+
+#define tx_ring_data(priv, idx) ((priv)->ring_data[idx])
+#define rx_ring_data(priv, idx) \
+	((priv)->ring_data[(priv)->ae_handle->q_num + (idx)])
+
+void hns_ethtool_set_ops(struct net_device *ndev);
+void hns_nic_net_reset(struct net_device *ndev);
+void hns_nic_net_reinit(struct net_device *netdev);
+int hns_nic_init_phy(struct net_device *ndev, struct hnae_handle *h);
+int hns_nic_net_xmit_hw(struct net_device *ndev,
+			struct sk_buff *skb,
+			struct hns_nic_ring_data *ring_data);
+
+#endif	/**__HNS_ENET_H */
diff --git a/drivers/net/ethernet/hisilicon/hns/hns_ethtool.c b/drivers/net/ethernet/hisilicon/hns/hns_ethtool.c
new file mode 100644
index 0000000..18f3fc5
--- /dev/null
+++ b/drivers/net/ethernet/hisilicon/hns/hns_ethtool.c
@@ -0,0 +1,1174 @@
+/*
+ * Copyright (c) 2014-2015 Hisilicon Limited.
+ *
+ * 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.
+ */
+
+#include <linux/module.h>
+#include <linux/interrupt.h>
+#include <linux/etherdevice.h>
+#include <linux/platform_device.h>
+#include "hns_enet.h"
+
+#define HNS_PHY_PAGE_REG	22
+#define HNS_PHY_PAGE_LED	3
+#define HNS_LED_FORCE_ON	9
+#define HNS_LED_FORCE_OFF	8
+#define HNS_PHY_PAGE_COPPER	0
+#define HNS_LED_FCR		16
+#define HNS_LED_PCR		17
+#define HNS_CHIP_VERSION 660
+
+#define HNS_NET_STATS_CNT 25
+
+/**
+ *hns_nic_get_link - get current link status
+ *@net_dev: net_device
+ *retuen 0 - success , negative --fail
+ */
+static u32 hns_nic_get_link(struct net_device *net_dev)
+{
+	struct hns_nic_priv *priv = netdev_priv(net_dev);
+	u32 link_stat = priv->link;
+	struct hnae_handle *h;
+
+	assert(priv && priv->ae_handle);
+	h = priv->ae_handle;
+
+	if (priv->phy) {
+		if (!genphy_update_link(priv->phy))
+			link_stat = priv->phy->link;
+		else
+			link_stat = 0;
+	}
+
+	if (h->dev && h->dev->ops && h->dev->ops->get_status)
+		link_stat = link_stat && h->dev->ops->get_status(h);
+	else
+		link_stat = 0;
+
+	return link_stat;
+}
+
+/**
+ *hns_nic_get_settings - implement ethtool get settings
+ *@net_dev: net_device
+ *@cmd: ethtool_cmd
+ *retuen 0 - success , negative --fail
+ */
+static int hns_nic_get_settings(struct net_device *net_dev,
+				struct ethtool_cmd *cmd)
+{
+	struct hns_nic_priv *priv = netdev_priv(net_dev);
+	struct hnae_handle *h;
+	u32 link_stat;
+	int ret;
+	u8 auto_neg, duplex;
+	u16 speed;
+
+	assert(priv && priv->ae_handle)
+	h = priv->ae_handle;
+
+	link_stat = hns_nic_get_link(net_dev);
+
+	if (h->dev->ops->get_info) {
+		ret = h->dev->ops->get_info(h, &auto_neg, &speed, &duplex);
+		if (ret < 0) {
+			netdev_err(net_dev,
+				   "%s get_info error!\n", __func__);
+			return -EINVAL;
+		}
+
+		cmd->autoneg = auto_neg;
+
+		if (link_stat) {
+			ethtool_cmd_speed_set(cmd, speed);
+			cmd->duplex = duplex;
+		} else {
+			ethtool_cmd_speed_set(cmd, (u32)SPEED_UNKNOWN);
+			cmd->duplex = DUPLEX_UNKNOWN;
+		}
+
+		if (auto_neg) {
+			cmd->supported |= SUPPORTED_Autoneg;
+			cmd->advertising |= ADVERTISED_Autoneg;
+			cmd->autoneg = AUTONEG_ENABLE;
+		} else {
+			cmd->autoneg = AUTONEG_DISABLE;
+		}
+	} else {
+		ethtool_cmd_speed_set(cmd, (u32)SPEED_UNKNOWN);
+		cmd->duplex = DUPLEX_UNKNOWN;
+	}
+
+	/* Phy exists, then update data from phy standard drv. */
+	if (priv->phy)
+		(void)phy_ethtool_gset(priv->phy, cmd);
+
+	if (PHY_INTERFACE_MODE_SGMII == h->phy_if) {
+		cmd->supported |= SUPPORTED_Autoneg;
+		cmd->supported |= SUPPORTED_10baseT_Half;
+		cmd->supported |= SUPPORTED_10baseT_Full;
+		cmd->supported |= SUPPORTED_100baseT_Half;
+		cmd->supported |= SUPPORTED_100baseT_Full;
+		cmd->supported |= SUPPORTED_1000baseT_Full;
+		cmd->supported |= SUPPORTED_1000baseT_Half;
+		cmd->supported |= SUPPORTED_2500baseX_Full;
+		cmd->supported |= SUPPORTED_FIBRE;
+		cmd->supported |= SUPPORTED_TP;
+
+		cmd->advertising |= ADVERTISED_1000baseT_Full;
+		cmd->advertising |= ADVERTISED_1000baseT_Half;
+
+		/* Update port type. */
+		cmd->port = PORT_TP;
+	} else if (PHY_INTERFACE_MODE_XGMII == h->phy_if) {
+		cmd->supported |= SUPPORTED_10000baseR_FEC;
+		cmd->supported |= SUPPORTED_10000baseKR_Full;
+		cmd->supported |= SUPPORTED_FIBRE;
+
+		cmd->advertising |= ADVERTISED_10000baseKR_Full;
+
+		/* Update port type. */
+		cmd->port = PORT_FIBRE;
+
+		if (link_stat) {
+			ethtool_cmd_speed_set(cmd, SPEED_10000);
+			cmd->duplex = DUPLEX_FULL;
+		}
+	}
+
+	cmd->transceiver = XCVR_EXTERNAL;
+	cmd->mdio_support = (ETH_MDIO_SUPPORTS_C45 | ETH_MDIO_SUPPORTS_C22);
+
+	return 0;
+}
+
+/**
+ *hns_nic_set_settings - implement ethtool set settings
+ *@net_dev: net_device
+ *@cmd: ethtool_cmd
+ *retuen 0 - success , negative --fail
+ */
+static int hns_nic_set_settings(struct net_device *net_dev,
+				struct ethtool_cmd *cmd)
+{
+	struct hns_nic_priv *priv       = netdev_priv(net_dev);
+	struct hnae_handle  *h;
+	int                 ret;
+
+	if (!priv || !priv->ae_handle)
+		return -ENODEV;
+
+	h = priv->ae_handle;
+
+	if (!h->dev->ops->set_info)
+		return -ENODEV;
+
+	if (!netif_running(net_dev))
+		return -ESRCH;
+
+	ret = h->dev->ops->set_info(h, cmd->autoneg, cmd->speed, cmd->duplex);
+	if (ret) {
+		netdev_err(net_dev,
+			   "set settings error!\n");
+		return ret;
+	}
+
+	if (priv->phy) {
+		(void)phy_ethtool_sset(priv->phy, cmd);
+		return 0;
+	}
+
+	/* Adjust the current link if link up. */
+	if (h->dev->ops->adjust_link && hns_nic_get_link(net_dev))
+		h->dev->ops->adjust_link(h, cmd->speed, cmd->duplex);
+	else
+		netdev_err(net_dev, "%s: not support setting!\n", __func__);
+
+	return 0;
+}
+
+static const char hns_nic_test_strs[][ETH_GSTRING_LEN] = {
+	"Mac    Loopback test",
+	"Serdes Loopback test",
+	"Phy    Loopback test"
+};
+
+static int hns_nic_config_phy_loopback(struct phy_device *phy_dev, u8 en)
+{
+#define COPPER_CONTROL_REG 0
+#define PHY_LOOP_BACK BIT(14)
+	u16 val = 0;
+
+	if (phy_dev->is_c45) /* c45 branch adding for XGE PHY */
+		return -ENOTSUPP;
+
+	if (en) {
+		/* speed : 1000M */
+		(void)mdiobus_write(phy_dev->bus, phy_dev->addr,
+				    HNS_PHY_PAGE_REG, 2);
+		(void)mdiobus_write(phy_dev->bus, phy_dev->addr,
+				    21, 0x1046);
+		/* Force Master */
+		(void)mdiobus_write(phy_dev->bus, phy_dev->addr,
+				    9, 0x1F00);
+		/* Soft-reset */
+		(void)mdiobus_write(phy_dev->bus, phy_dev->addr,
+				    0, 0x9140);
+		/* If autoneg disabled,two soft-reset operations */
+		(void)mdiobus_write(phy_dev->bus, phy_dev->addr,
+				    0, 0x9140);
+		(void)mdiobus_write(phy_dev->bus, phy_dev->addr,
+				    22, 0xFA);
+
+		/* Default is 0x0400 */
+		(void)mdiobus_write(phy_dev->bus, phy_dev->addr,
+				    1, 0x418);
+
+		/* Force 1000M Link, Default is 0x0200 */
+		(void)mdiobus_write(phy_dev->bus, phy_dev->addr,
+				    7, 0x20C);
+		(void)mdiobus_write(phy_dev->bus, phy_dev->addr,
+				    22, 0);
+
+		/* Enable MAC loop-back */
+		val = (u16)mdiobus_read(phy_dev->bus, phy_dev->addr,
+					COPPER_CONTROL_REG);
+		val |= PHY_LOOP_BACK;
+		(void)mdiobus_write(phy_dev->bus, phy_dev->addr,
+				    COPPER_CONTROL_REG, val);
+	} else {
+		(void)mdiobus_write(phy_dev->bus, phy_dev->addr,
+				    22, 0xFA);
+		(void)mdiobus_write(phy_dev->bus, phy_dev->addr,
+				    1, 0x400);
+		(void)mdiobus_write(phy_dev->bus, phy_dev->addr,
+				    7, 0x200);
+		(void)mdiobus_write(phy_dev->bus, phy_dev->addr,
+				    22, 0);
+
+		val = (u16)mdiobus_read(phy_dev->bus, phy_dev->addr,
+					COPPER_CONTROL_REG);
+		val &= ~PHY_LOOP_BACK;
+		(void)mdiobus_write(phy_dev->bus, phy_dev->addr,
+				    COPPER_CONTROL_REG, val);
+	}
+	return 0;
+}
+
+static int __lb_setup(struct net_device *ndev,
+		      enum hnae_loop loop)
+{
+	int ret = -ENOTSUPP;
+	struct hns_nic_priv *priv = netdev_priv(ndev);
+	struct phy_device *phy_dev = priv->phy;
+	struct hnae_handle *h = priv->ae_handle;
+
+	switch (loop) {
+	case MAC_INTERNALLOOP_PHY:
+		if (phy_dev)
+			ret = hns_nic_config_phy_loopback(phy_dev, 0x1);
+		break;
+	case MAC_INTERNALLOOP_MAC:
+	case MAC_INTERNALLOOP_SERDES:
+		if (h->dev->ops->set_loopback)
+			ret = h->dev->ops->set_loopback(h, loop, 0x1);
+		break;
+	case MAC_LOOP_NONE:
+		if (phy_dev)
+			ret = hns_nic_config_phy_loopback(phy_dev, 0x0);
+
+		if (h->dev->ops->set_loopback) {
+			ret |= h->dev->ops->set_loopback(h,
+				MAC_INTERNALLOOP_MAC, 0x0);
+			ret |= h->dev->ops->set_loopback(h,
+				MAC_INTERNALLOOP_SERDES, 0x0);
+		}
+		break;
+	default:
+		break;
+	}
+
+	return ret;
+}
+
+static int __lb_up(struct net_device *ndev,
+		   enum hnae_loop loop_mode)
+{
+	struct hns_nic_priv *priv = netdev_priv(ndev);
+	struct hnae_handle *h = priv->ae_handle;
+	int speed, duplex;
+	int ret;
+
+	hns_nic_net_reset(ndev);
+
+	if (h->phy_node) {
+		ret = hns_nic_init_phy(ndev, h);
+		if (ret)
+			return ret;
+	}
+
+	ret = __lb_setup(ndev, loop_mode);
+	if (ret)
+		return ret;
+	msleep(100);
+
+	ret = h->dev->ops->start ? h->dev->ops->start(h) : 0;
+	if (ret)
+		return ret;
+
+	if (priv->phy)
+		phy_start(priv->phy);
+
+	/* link adjust duplex*/
+	if (priv->ae_handle->phy_if != PHY_INTERFACE_MODE_XGMII)
+		speed = 1000;
+	else
+		speed = 10000;
+	duplex = 1;
+
+	h->dev->ops->adjust_link(h, speed, duplex);
+
+	return 0;
+}
+
+static void __lb_other_process(struct hns_nic_ring_data *ring_data,
+			       struct sk_buff *skb)
+{
+	struct net_device *ndev;
+	struct hnae_ring *ring;
+	struct netdev_queue *dev_queue;
+	struct sk_buff *new_skb;
+	unsigned int frame_size;
+	int check_ok;
+	u32 i;
+	char buff[33]; /* 32B data and the last character '\0' */
+
+	if (!ring_data) { /* Just for doing create frame*/
+		frame_size = skb->len;
+		memset(skb->data, 0xFF, frame_size);
+		frame_size &= ~1ul;
+		memset(&skb->data[frame_size / 2], 0xAA, frame_size / 2 - 1);
+		memset(&skb->data[frame_size / 2 + 10], 0xBE,
+		       frame_size / 2 - 11);
+		memset(&skb->data[frame_size / 2 + 12], 0xAF,
+		       frame_size / 2 - 13);
+		return;
+	}
+
+	ring = ring_data->ring;
+	ndev = ring_data->napi.dev;
+	if (is_tx_ring(ring)) { /* for tx queue reset*/
+		dev_queue = netdev_get_tx_queue(ndev, ring_data->queue_index);
+		netdev_tx_reset_queue(dev_queue);
+		return;
+	}
+
+	frame_size = skb->len;
+	frame_size &= ~1ul;
+	/* for mutl buffer*/
+	new_skb = skb_copy(skb, GFP_ATOMIC);
+	dev_kfree_skb_any(skb);
+	skb = new_skb;
+
+	check_ok = 0;
+	if (*(skb->data + 10) == 0xFF) { /* for rx check frame*/
+		if ((*(skb->data + frame_size / 2 + 10) == 0xBE) &&
+		    (*(skb->data + frame_size / 2 + 12) == 0xAF))
+			check_ok = 1;
+	}
+
+	if (check_ok) {
+		ndev->stats.rx_packets++;
+		ndev->stats.rx_bytes += skb->len;
+	} else {
+		ndev->stats.rx_frame_errors++;
+		for (i = 0; i < skb->len; i++) {
+			snprintf(buff + i % 16 * 2, 3, /* tailing \0*/
+				 "%02x", *(skb->data + i));
+			if ((i % 16 == 15) || (i == skb->len - 1))
+				pr_info("%s\n", buff);
+		}
+	}
+	dev_kfree_skb_any(skb);
+}
+
+static int __lb_clean_rings(struct hns_nic_priv *priv,
+			    int ringid0, int ringid1, int budget)
+{
+	int i, ret;
+	struct hns_nic_ring_data *ring_data;
+	struct net_device *ndev = priv->netdev;
+	unsigned long rx_packets = ndev->stats.rx_packets;
+	unsigned long rx_bytes = ndev->stats.rx_bytes;
+	unsigned long rx_frame_errors = ndev->stats.rx_frame_errors;
+
+	for (i = ringid0; i <= ringid1; i++) {
+		ring_data = &priv->ring_data[i];
+		(void)ring_data->poll_one(ring_data,
+					  budget, __lb_other_process);
+	}
+	ret = (int)(ndev->stats.rx_packets - rx_packets);
+	ndev->stats.rx_packets = rx_packets;
+	ndev->stats.rx_bytes = rx_bytes;
+	ndev->stats.rx_frame_errors = rx_frame_errors;
+	return ret;
+}
+
+static const char * const pr_test[] = {
+	"none",
+	"mac",
+	"serdes",
+	"phy",
+	NULL};
+
+/**
+ * nic_run_loopback_test -  run loopback test
+ * @nic_dev: net device
+ * @loopback_type: loopback type
+ */
+static int __lb_run_test(struct net_device *ndev,
+			 enum hnae_loop loop_mode)
+{
+#define NIC_LB_TEST_PKT_NUM_PER_CYCLE 1
+#define NIC_LB_TEST_RING_ID 0
+#define NIC_LB_TEST_FRAME_SIZE 128
+/* nic loopback test err  */
+#define NIC_LB_TEST_NO_MEM_ERR 1
+#define NIC_LB_TEST_TX_CNT_ERR 2
+#define NIC_LB_TEST_RX_CNT_ERR 3
+#define NIC_LB_TEST_RX_PKG_ERR 4
+	struct hns_nic_priv *priv = netdev_priv(ndev);
+	struct hnae_handle *h = priv->ae_handle;
+	int i, j, lc, good_cnt, ret_val = 0;
+	unsigned int size;
+	netdev_tx_t tx_ret_val;
+	struct sk_buff *skb;
+
+	size = NIC_LB_TEST_FRAME_SIZE;
+	/* allocate test skb */
+	skb = alloc_skb(size, GFP_KERNEL);
+	if (!skb)
+		return NIC_LB_TEST_NO_MEM_ERR;
+
+	/* place data into test skb */
+	(void)skb_put(skb, size);
+	__lb_other_process(NULL, skb);
+	skb->queue_mapping = NIC_LB_TEST_RING_ID;
+
+	lc = 1;
+	for (j = 0; j < lc; j++) {
+		/* reset count of good packets */
+		good_cnt = 0;
+		/* place 64 packets on the transmit queue*/
+		for (i = 0; i < NIC_LB_TEST_PKT_NUM_PER_CYCLE; i++) {
+			(void)skb_get(skb);
+
+			tx_ret_val = (netdev_tx_t)hns_nic_net_xmit_hw(
+				ndev, skb,
+				&tx_ring_data(priv, skb->queue_mapping));
+			if (tx_ret_val == NETDEV_TX_OK)
+				good_cnt++;
+			else
+				break;
+		}
+		if (good_cnt != NIC_LB_TEST_PKT_NUM_PER_CYCLE) {
+			ret_val = NIC_LB_TEST_TX_CNT_ERR;
+			dev_err(priv->dev, "%s lb test sent fail, cnt=0x%x, budget=0x%x\n",
+				pr_test[loop_mode], good_cnt,
+				NIC_LB_TEST_PKT_NUM_PER_CYCLE);
+			break;
+		}
+
+		/* allow 100 milliseconds for packets to go from Tx to Rx */
+		msleep(100);
+
+		good_cnt = __lb_clean_rings(priv,
+					    h->q_num, h->q_num * 2 - 1,
+					    NIC_LB_TEST_PKT_NUM_PER_CYCLE);
+		if (good_cnt != NIC_LB_TEST_PKT_NUM_PER_CYCLE) {
+			ret_val = NIC_LB_TEST_RX_CNT_ERR;
+			dev_err(priv->dev, "%s lb test recv fail, cnt=0x%x, budget=0x%x\n",
+				pr_test[loop_mode], good_cnt,
+				NIC_LB_TEST_PKT_NUM_PER_CYCLE);
+			break;
+		}
+		(void)__lb_clean_rings(priv,
+				       NIC_LB_TEST_RING_ID, NIC_LB_TEST_RING_ID,
+				       NIC_LB_TEST_PKT_NUM_PER_CYCLE);
+	}
+
+	/* free the original skb */
+	kfree_skb(skb);
+
+	return ret_val;
+}
+
+static int __lb_down(struct net_device *ndev)
+{
+	struct hns_nic_priv *priv = netdev_priv(ndev);
+	struct hnae_handle *h = priv->ae_handle;
+	int ret;
+
+	ret = __lb_setup(ndev, MAC_LOOP_NONE);
+	if ((ret) && (ret != -ENOTSUPP))
+		netdev_err(ndev, "%s: __lb_setup return error(%d)!\n",
+			   __func__,
+			   ret);
+
+	if (priv->phy) {
+		phy_stop(priv->phy);
+		phy_disconnect(priv->phy);
+	}
+
+	if (h->dev->ops->stop)
+		h->dev->ops->stop(h);
+
+	usleep_range(10000, 20000);
+	(void)__lb_clean_rings(priv, 0, h->q_num - 1, 256);
+
+	hns_nic_net_reset(ndev);
+
+	return 0;
+}
+
+/**
+ * hns_nic_self_test - self test
+ * @dev: net device
+ * @eth_test: test cmd
+ * @data: test result
+ */
+static void hns_nic_self_test(struct net_device *ndev,
+			      struct ethtool_test *eth_test, u64 *data)
+{
+	struct hns_nic_priv *priv = netdev_priv(ndev);
+	bool if_running = netif_running(ndev);
+#define SELF_TEST_TPYE_NUM 3
+	int st_param[SELF_TEST_TPYE_NUM][2];
+	int i;
+
+	set_bit(NIC_STATE_TESTING, &priv->state);
+
+	data[0] = ENOTSUPP;
+	data[1] = ENOTSUPP;
+	data[2] = ENOTSUPP;
+
+	st_param[0][0] = MAC_INTERNALLOOP_MAC; /* XGE not supported lb */
+	st_param[0][1] = (priv->ae_handle->phy_if != PHY_INTERFACE_MODE_XGMII);
+	st_param[1][0] = MAC_INTERNALLOOP_SERDES;
+	st_param[1][1] = 1; /*serdes must exist*/
+	st_param[2][0] = MAC_INTERNALLOOP_PHY; /* only supporte phy node*/
+	st_param[2][1] = !!(priv->ae_handle->phy_node);
+
+	if (eth_test->flags == ETH_TEST_FL_OFFLINE) {
+		if (if_running)
+			(void)dev_close(ndev);
+
+		for (i = 0; i < SELF_TEST_TPYE_NUM; i++) {
+			if (!st_param[i][1])
+				continue;	/* NEXT testing */
+
+			data[i] = __lb_up(ndev, (enum hnae_loop)st_param[i][0]);
+			if (!data[i]) {
+				data[i] = __lb_run_test(
+					ndev, (enum hnae_loop)st_param[i][0]);
+				(void)__lb_down(ndev);
+			}
+			if (data[i])
+				eth_test->flags |= ETH_TEST_FL_FAILED;
+		}
+
+		hns_nic_net_reset(priv->netdev);
+
+		if (if_running)
+			(void)dev_open(ndev);
+	}
+	/* Online tests aren't run; pass by default */
+
+	clear_bit(NIC_STATE_TESTING, &priv->state);
+
+	(void)msleep_interruptible(4 * 1000);
+}
+
+/**
+ * hns_nic_get_drvinfo - get net driver info
+ * @dev: net device
+ * @drvinfo: driver info
+ */
+static void hns_nic_get_drvinfo(struct net_device *net_dev,
+				struct ethtool_drvinfo *drvinfo)
+{
+	struct hns_nic_priv *priv = netdev_priv(net_dev);
+
+	assert(priv);
+
+	strncpy(drvinfo->version, HNAE_DRIVER_VERSION,
+		sizeof(drvinfo->version));
+	drvinfo->version[sizeof(drvinfo->version) - 1] = '\0';
+
+	strncpy(drvinfo->driver, HNAE_DRIVER_NAME, sizeof(drvinfo->driver));
+	drvinfo->driver[sizeof(drvinfo->driver) - 1] = '\0';
+
+	strncpy(drvinfo->bus_info, priv->dev->bus->name,
+		sizeof(drvinfo->bus_info));
+	drvinfo->bus_info[ETHTOOL_BUSINFO_LEN - 1] = '\0';
+
+	strncpy(drvinfo->fw_version, "N/A", ETHTOOL_FWVERS_LEN);
+	drvinfo->eedump_len = 0;
+}
+
+/**
+ * hns_get_ringparam - get ring parameter
+ * @dev: net device
+ * @param: ethtool parameter
+ */
+void hns_get_ringparam(struct net_device *net_dev,
+		       struct ethtool_ringparam *param)
+{
+	struct hns_nic_priv *priv = netdev_priv(net_dev);
+	struct hnae_ae_ops *ops;
+	struct hnae_queue *queue;
+	u32 uplimit = 0, lowlimit = 0;
+
+	queue = priv->ae_handle->qs[0];
+	ops = priv->ae_handle->dev->ops;
+
+	param->rx_max_pending = priv->ae_handle->q_num;
+	param->tx_max_pending = priv->ae_handle->q_num;
+
+	param->rx_mini_pending = priv->ae_handle->q_num;
+	param->rx_jumbo_pending = priv->ae_handle->q_num;
+	param->rx_pending = queue->rx_ring.desc_num;
+	param->tx_pending = queue->tx_ring.desc_num;
+
+	if (ops->get_ring_bdnum_limit)
+		ops->get_ring_bdnum_limit(queue, &uplimit, &lowlimit);
+
+	param->rx_mini_max_pending = lowlimit;
+	param->rx_jumbo_max_pending = uplimit;
+}
+
+/**
+ * hns_get_pauseparam - get pause parameter
+ * @dev: net device
+ * @param: pause parameter
+ */
+static void hns_get_pauseparam(struct net_device *net_dev,
+			       struct ethtool_pauseparam *param)
+{
+	struct hns_nic_priv *priv = netdev_priv(net_dev);
+	struct hnae_ae_ops *ops;
+
+	ops = priv->ae_handle->dev->ops;
+
+	if (ops->get_pauseparam)
+		ops->get_pauseparam(priv->ae_handle, &param->autoneg,
+					    &param->rx_pause, &param->tx_pause);
+}
+
+/**
+ * hns_set_pauseparam - set pause parameter
+ * @dev: net device
+ * @param: pause parameter
+ *
+ * Return 0 on success, negative on failure
+ */
+static int hns_set_pauseparam(struct net_device *net_dev,
+			      struct ethtool_pauseparam *param)
+{
+	struct hns_nic_priv *priv = netdev_priv(net_dev);
+	struct hnae_ae_ops *ops;
+
+	assert(priv || priv->ae_handle);
+
+	ops = priv->ae_handle->dev->ops;
+
+	if ((priv->ae_handle->phy_node) && (ops->set_autoneg))
+		(void)ops->set_autoneg(priv->ae_handle, param->autoneg);
+
+	if (!ops->set_pauseparam)
+		return -ESRCH;
+
+	ops->set_pauseparam(priv->ae_handle,
+				    param->rx_pause,
+				    param->tx_pause);
+
+	return 0;
+}
+
+/**
+ * hns_get_coalesce - get coalesce info.
+ * @dev: net device
+ * @ec: coalesce info.
+ *
+ * Return 0 on success, negative on failure.
+ */
+static int hns_get_coalesce(struct net_device *net_dev,
+			    struct ethtool_coalesce *ec)
+{
+	struct hns_nic_priv *priv = netdev_priv(net_dev);
+	struct hnae_ae_ops *ops;
+
+	ops = priv->ae_handle->dev->ops;
+
+	ec->use_adaptive_rx_coalesce = 1;
+	ec->use_adaptive_tx_coalesce = 1;
+
+	if ((!ops->get_coalesce_usecs) ||
+	    (!ops->get_rx_max_coalesced_frames))
+		return -ESRCH;
+
+	ops->get_coalesce_usecs(priv->ae_handle,
+					&ec->tx_coalesce_usecs,
+					&ec->rx_coalesce_usecs);
+
+	ops->get_rx_max_coalesced_frames(
+		priv->ae_handle,
+		&ec->tx_max_coalesced_frames,
+		&ec->rx_max_coalesced_frames);
+
+	return 0;
+}
+
+/**
+ * hns_set_coalesce - set coalesce info.
+ * @dev: net device
+ * @ec: coalesce info.
+ *
+ * Return 0 on success, negative on failure.
+ */
+static int hns_set_coalesce(struct net_device *net_dev,
+			    struct ethtool_coalesce *ec)
+{
+	struct hns_nic_priv *priv = netdev_priv(net_dev);
+	struct hnae_ae_ops *ops;
+	int ret;
+
+	assert(priv || priv->ae_handle);
+
+	ops = priv->ae_handle->dev->ops;
+
+	if (ec->tx_coalesce_usecs != ec->rx_coalesce_usecs)
+		return -EINVAL;
+
+	if (ec->rx_max_coalesced_frames != ec->tx_max_coalesced_frames)
+		return -EINVAL;
+
+	if ((!ops->set_coalesce_usecs) ||
+	    (!ops->set_coalesce_frames))
+		return -ESRCH;
+
+	ops->set_coalesce_usecs(priv->ae_handle,
+					ec->rx_coalesce_usecs);
+
+	ret = ops->set_coalesce_frames(
+		priv->ae_handle,
+		ec->rx_max_coalesced_frames);
+
+	return ret;
+}
+
+/**
+ * hns_get_channels - get channel info.
+ * @dev: net device
+ * @ch: channel info.
+ */
+void hns_get_channels(struct net_device *net_dev, struct ethtool_channels *ch)
+{
+	struct hns_nic_priv *priv = netdev_priv(net_dev);
+	struct hnae_ae_ops *ops;
+	u32 max_ring_pair_num, ring_pair_num;
+
+	assert(priv || priv->ae_handle);
+
+	ops = priv->ae_handle->dev->ops;
+
+	if (!ops->get_max_ringnum) {
+		netdev_err(net_dev, "don't support get max ringnum\n");
+		return;
+	}
+
+	ops->get_max_ringnum(priv->ae_handle, &max_ring_pair_num);
+
+	ch->max_rx = max_ring_pair_num;
+	ch->max_tx = max_ring_pair_num;
+	ch->max_combined = max_ring_pair_num;
+	ch->max_other = max_ring_pair_num;
+
+	if (!ops->get_ringnum) {
+		netdev_err(net_dev, "don't support get current ringnum\n");
+		return;
+	}
+
+	ops->get_ringnum(priv->ae_handle, &ring_pair_num);
+
+	ch->rx_count = ring_pair_num;
+	ch->tx_count = ring_pair_num;
+	ch->combined_count = ring_pair_num;
+	ch->other_count = ring_pair_num;
+}
+
+/**
+ * get_ethtool_stats - get detail statistics.
+ * @dev: net device
+ * @stats: statistics info.
+ * @data: statistics data.
+ */
+void hns_get_ethtool_stats(struct net_device *netdev,
+			   struct ethtool_stats *stats, u64 *data)
+{
+	u64 *p = data;
+	struct hns_nic_priv *priv = netdev_priv(netdev);
+	struct hnae_handle *h = priv->ae_handle;
+	const struct rtnl_link_stats64 *net_stats;
+	struct rtnl_link_stats64 temp;
+
+	if (!h->dev->ops->get_stats || !h->dev->ops->update_stats) {
+		netdev_err(netdev, "get_stats or update_stats is null!\n");
+		return;
+	}
+
+	h->dev->ops->update_stats(h, &netdev->stats);
+
+	net_stats = dev_get_stats(netdev, &temp);
+
+	/* get netdev statistics */
+	p[0] = net_stats->rx_packets;
+	p[1] = net_stats->tx_packets;
+	p[2] = net_stats->rx_bytes;
+	p[3] = net_stats->tx_bytes;
+	p[4] = net_stats->rx_errors;
+	p[5] = net_stats->tx_errors;
+	p[6] = net_stats->rx_dropped;
+	p[7] = net_stats->tx_dropped;
+	p[8] = net_stats->multicast;
+	p[9] = net_stats->collisions;
+	p[10] = net_stats->rx_over_errors;
+	p[11] = net_stats->rx_crc_errors;
+	p[12] = net_stats->rx_frame_errors;
+	p[13] = net_stats->rx_fifo_errors;
+	p[14] = net_stats->rx_missed_errors;
+	p[15] = net_stats->tx_aborted_errors;
+	p[16] = net_stats->tx_carrier_errors;
+	p[17] = net_stats->tx_fifo_errors;
+	p[18] = net_stats->tx_heartbeat_errors;
+	p[19] = net_stats->rx_length_errors;
+	p[20] = net_stats->tx_window_errors;
+	p[21] = net_stats->rx_compressed;
+	p[22] = net_stats->tx_compressed;
+
+	p[23] = (u64)netdev->rx_dropped.counter;
+	p[24] = (u64)netdev->tx_dropped.counter;
+
+	/* get driver statistics */
+	h->dev->ops->get_stats(h, &p[25]);
+}
+
+/**
+ * get_strings: Return a set of strings that describe the requested objects
+ * @dev: net device
+ * @stats: string set ID.
+ * @data: objects data.
+ */
+void hns_get_strings(struct net_device *netdev, u32 stringset, u8 *data)
+{
+	struct hns_nic_priv *priv = netdev_priv(netdev);
+	struct hnae_handle *h = priv->ae_handle;
+	char *buff = (char *)data;
+
+	if (!h->dev->ops->get_strings) {
+		netdev_err(netdev, "h->dev->ops->get_strings is null!\n");
+		return;
+	}
+	if (stringset == ETH_SS_TEST) {
+		memcpy(data, *hns_nic_test_strs, sizeof(hns_nic_test_strs));
+		}
+	else {
+		snprintf(buff, ETH_GSTRING_LEN, "rx_packets");
+		buff = buff + ETH_GSTRING_LEN;
+		snprintf(buff, ETH_GSTRING_LEN, "tx_packets");
+		buff = buff + ETH_GSTRING_LEN;
+		snprintf(buff, ETH_GSTRING_LEN, "rx_bytes");
+		buff = buff + ETH_GSTRING_LEN;
+		snprintf(buff, ETH_GSTRING_LEN, "tx_bytes");
+		buff = buff + ETH_GSTRING_LEN;
+		snprintf(buff, ETH_GSTRING_LEN, "rx_errors");
+		buff = buff + ETH_GSTRING_LEN;
+		snprintf(buff, ETH_GSTRING_LEN, "tx_errors");
+		buff = buff + ETH_GSTRING_LEN;
+		snprintf(buff, ETH_GSTRING_LEN, "rx_dropped");
+		buff = buff + ETH_GSTRING_LEN;
+		snprintf(buff, ETH_GSTRING_LEN, "tx_dropped");
+		buff = buff + ETH_GSTRING_LEN;
+		snprintf(buff, ETH_GSTRING_LEN, "multicast");
+		buff = buff + ETH_GSTRING_LEN;
+		snprintf(buff, ETH_GSTRING_LEN, "collisions");
+		buff = buff + ETH_GSTRING_LEN;
+		snprintf(buff, ETH_GSTRING_LEN, "rx_over_errors");
+		buff = buff + ETH_GSTRING_LEN;
+		snprintf(buff, ETH_GSTRING_LEN, "rx_crc_errors");
+		buff = buff + ETH_GSTRING_LEN;
+		snprintf(buff, ETH_GSTRING_LEN, "rx_frame_errors");
+		buff = buff + ETH_GSTRING_LEN;
+		snprintf(buff, ETH_GSTRING_LEN, "tx_carrier_errors");
+		buff = buff + ETH_GSTRING_LEN;
+		snprintf(buff, ETH_GSTRING_LEN, "rx_fifo_errors");
+		buff = buff + ETH_GSTRING_LEN;
+		snprintf(buff, ETH_GSTRING_LEN, "rx_missed_errors");
+		buff = buff + ETH_GSTRING_LEN;
+		snprintf(buff, ETH_GSTRING_LEN, "tx_aborted_errors");
+		buff = buff + ETH_GSTRING_LEN;
+		snprintf(buff, ETH_GSTRING_LEN, "tx_carrier_errors");
+		buff = buff + ETH_GSTRING_LEN;
+		snprintf(buff, ETH_GSTRING_LEN, "tx_fifo_errors");
+		buff = buff + ETH_GSTRING_LEN;
+		snprintf(buff, ETH_GSTRING_LEN, "tx_heartbeat_errors");
+		buff = buff + ETH_GSTRING_LEN;
+		snprintf(buff, ETH_GSTRING_LEN, "tx_window_errors");
+		buff = buff + ETH_GSTRING_LEN;
+		snprintf(buff, ETH_GSTRING_LEN, "rx_compressed");
+		buff = buff + ETH_GSTRING_LEN;
+		snprintf(buff, ETH_GSTRING_LEN, "tx_compressed");
+		buff = buff + ETH_GSTRING_LEN;
+		snprintf(buff, ETH_GSTRING_LEN, "netdev_rx_dropped");
+		buff = buff + ETH_GSTRING_LEN;
+		snprintf(buff, ETH_GSTRING_LEN, "netdev_tx_dropped");
+		buff = buff + ETH_GSTRING_LEN;
+
+		h->dev->ops->get_strings(h, stringset, buff);
+	}
+}
+
+/**
+ * nic_get_sset_count - get string set count witch returned by nic_get_strings.
+ * @dev: net device
+ * @stringset: string set index, 0: self test string; 1: statistics string.
+ *
+ * Return string set count.
+ */
+int hns_get_sset_count(struct net_device *netdev, int stringset)
+{
+	struct hns_nic_priv *priv = netdev_priv(netdev);
+	struct hnae_handle *h = priv->ae_handle;
+	struct hnae_ae_ops *ops = h->dev->ops;
+
+	if (!ops->get_sset_count) {
+		netdev_err(netdev, "get_sset_count is null!\n");
+		return -EOPNOTSUPP;
+	}
+	if (stringset == ETH_SS_TEST)
+		return (sizeof(hns_nic_test_strs) / ETH_GSTRING_LEN);
+	else
+		return (HNS_NET_STATS_CNT + ops->get_sset_count(h, stringset));
+}
+
+/**
+ * hns_phy_led_set - set phy LED status.
+ * @dev: net device
+ * @value: LED state.
+ *
+ * Return 0 on success, negative on failure.
+ */
+int hns_phy_led_set(struct net_device *netdev, int value)
+{
+	int retval;
+	struct hns_nic_priv *priv = netdev_priv(netdev);
+	struct phy_device *phy_dev = priv->phy;
+
+	if (!phy_dev->bus) {
+		netdev_err(netdev, "phy_dev->bus is null!\n");
+		return -EINVAL;
+	}
+	retval = mdiobus_write(phy_dev->bus, phy_dev->addr,
+			       HNS_PHY_PAGE_REG, HNS_PHY_PAGE_LED);
+	retval = mdiobus_write(phy_dev->bus, phy_dev->addr, HNS_LED_FCR, value);
+	retval = mdiobus_write(phy_dev->bus, phy_dev->addr,
+			       HNS_PHY_PAGE_REG, HNS_PHY_PAGE_COPPER);
+	if (retval) {
+		netdev_err(netdev, "mdiobus_write fail !\n");
+		return retval;
+	}
+	return 0;
+}
+
+/**
+ * nic_set_phys_id - set phy identify LED.
+ * @dev: net device
+ * @state: LED state.
+ *
+ * Return 0 on success, negative on failure.
+ */
+int hns_set_phys_id(struct net_device *netdev, enum ethtool_phys_id_state state)
+{
+	struct hns_nic_priv *priv = netdev_priv(netdev);
+	struct hnae_handle *h = priv->ae_handle;
+	struct phy_device *phy_dev = priv->phy;
+	int ret;
+
+	if (phy_dev)
+		switch (state) {
+		case ETHTOOL_ID_ACTIVE:
+			ret = mdiobus_write(phy_dev->bus, phy_dev->addr,
+					    HNS_PHY_PAGE_REG,
+					    HNS_PHY_PAGE_LED);
+			if (ret)
+				return ret;
+
+			priv->phy_led_val = (u16)mdiobus_read(phy_dev->bus,
+							      phy_dev->addr,
+							      HNS_LED_FCR);
+
+			ret = mdiobus_write(phy_dev->bus, phy_dev->addr,
+					    HNS_PHY_PAGE_REG,
+					    HNS_PHY_PAGE_COPPER);
+			if (ret)
+				return ret;
+			return 2;
+		case ETHTOOL_ID_ON:
+			ret = hns_phy_led_set(netdev, HNS_LED_FORCE_ON);
+			if (ret)
+				return ret;
+			break;
+		case ETHTOOL_ID_OFF:
+			ret = hns_phy_led_set(netdev, HNS_LED_FORCE_OFF);
+			if (ret)
+				return ret;
+			break;
+		case ETHTOOL_ID_INACTIVE:
+			ret = mdiobus_write(phy_dev->bus, phy_dev->addr,
+					    HNS_PHY_PAGE_REG,
+					    HNS_PHY_PAGE_LED);
+			if (ret)
+				return ret;
+
+			ret = mdiobus_write(phy_dev->bus, phy_dev->addr,
+					    HNS_LED_FCR, priv->phy_led_val);
+			if (ret)
+				return ret;
+
+			ret = mdiobus_write(phy_dev->bus, phy_dev->addr,
+					    HNS_PHY_PAGE_REG,
+					    HNS_PHY_PAGE_COPPER);
+			if (ret)
+				return ret;
+			break;
+		default:
+			return -EINVAL;
+		}
+	else
+		switch (state) {
+		case ETHTOOL_ID_ACTIVE:
+			return h->dev->ops->set_led_id(h, HNAE_LED_ACTIVE);
+		case ETHTOOL_ID_ON:
+			return h->dev->ops->set_led_id(h, HNAE_LED_ON);
+		case ETHTOOL_ID_OFF:
+			return h->dev->ops->set_led_id(h, HNAE_LED_OFF);
+		case ETHTOOL_ID_INACTIVE:
+			return h->dev->ops->set_led_id(h, HNAE_LED_INACTIVE);
+		default:
+			return -EINVAL;
+		}
+
+	return 0;
+}
+
+/**
+ * hns_get_regs - get net device register
+ * @dev: net device
+ * @cmd: ethtool cmd
+ * @date: register data
+ */
+void hns_get_regs(struct net_device *net_dev, struct ethtool_regs *cmd,
+		  void *data)
+{
+	struct hns_nic_priv *priv = netdev_priv(net_dev);
+	struct hnae_ae_ops *ops;
+
+	assert(priv || priv->ae_handle);
+
+	ops = priv->ae_handle->dev->ops;
+
+	cmd->version = HNS_CHIP_VERSION;
+	if (!ops->get_regs) {
+		netdev_err(net_dev, "ops->get_regs is null!\n");
+		return;
+	}
+	ops->get_regs(priv->ae_handle, data);
+}
+
+/**
+ * nic_get_regs_len - get total register len.
+ * @dev: net device
+ *
+ * Return total register len.
+ */
+static int hns_get_regs_len(struct net_device *net_dev)
+{
+	u32 reg_num;
+	struct hns_nic_priv *priv = netdev_priv(net_dev);
+	struct hnae_ae_ops *ops;
+
+	assert(priv || priv->ae_handle);
+
+	ops = priv->ae_handle->dev->ops;
+	if (!ops->get_regs_len) {
+		netdev_err(net_dev, "ops->get_regs_len is null!\n");
+		return -EOPNOTSUPP;
+	}
+
+	reg_num = ops->get_regs_len(priv->ae_handle);
+	if (reg_num > 0)
+		return reg_num * sizeof(u32);
+	else
+		return reg_num;	/* error code */
+}
+
+/**
+ * hns_nic_nway_reset - nway reset
+ * @dev: net device
+ *
+ * Return 0 on success, negative on failure
+ */
+static int hns_nic_nway_reset(struct net_device *netdev)
+{
+	int ret = 0;
+	struct hns_nic_priv *priv = netdev_priv(netdev);
+	struct phy_device *phy_dev = priv->phy;
+
+	if (netif_running(netdev)) {
+		hns_nic_net_reinit(netdev);
+		if (phy_dev)
+			ret = phy_start_aneg(phy_dev);
+	}
+	return ret;
+}
+
+static struct ethtool_ops hns_ethtool_ops = {
+	.get_drvinfo = hns_nic_get_drvinfo,
+	.get_link  = hns_nic_get_link,
+	.get_settings  = hns_nic_get_settings,
+	.set_settings  = hns_nic_set_settings,
+	.get_ringparam = hns_get_ringparam,
+	.get_pauseparam = hns_get_pauseparam,
+	.set_pauseparam = hns_set_pauseparam,
+	.get_coalesce = hns_get_coalesce,
+	.set_coalesce = hns_set_coalesce,
+	.get_channels = hns_get_channels,
+	.self_test = hns_nic_self_test,
+	.get_strings = hns_get_strings,
+	.get_sset_count = hns_get_sset_count,
+	.get_ethtool_stats = hns_get_ethtool_stats,
+	.set_phys_id = hns_set_phys_id,
+	.get_regs_len = hns_get_regs_len,
+	.get_regs = hns_get_regs,
+	.nway_reset = hns_nic_nway_reset,
+};
+
+void hns_ethtool_set_ops(struct net_device *ndev)
+{
+	ndev->ethtool_ops = &hns_ethtool_ops;
+}
-- 
1.9.1



From marc.zyngier at arm.com  Fri Aug 14 03:39:56 2015
From: marc.zyngier at arm.com (Marc Zyngier)
Date: Fri, 14 Aug 2015 11:39:56 +0100
Subject: [PATCH v2 2/6] genirq: fix irqchip_set_wake_parent if
 IRQCHIP_SKIP_SET_WAKE
In-Reply-To: <55CDC089.1060309@ti.com>
References: <1439401562-28874-1-git-send-email-grygorii.strashko@ti.com>
 <1439401562-28874-3-git-send-email-grygorii.strashko@ti.com>
 <55CC6AFF.8060400@arm.com> <55CC71E8.80604@ti.com> <55CC9493.9020101@ti.com>
 <55CDC089.1060309@ti.com>
Message-ID: <55CDC57C.2030006@arm.com>

On 14/08/15 11:18, Grygorii Strashko wrote:
> On 08/13/2015 03:58 PM, Grygorii Strashko wrote:
>> On 08/13/2015 01:31 PM, Grygorii Strashko wrote:
>>> On 08/13/2015 01:01 PM, Marc Zyngier wrote:
>>>> On 12/08/15 18:45, Grygorii Strashko wrote:
>>>>> The irqchip_set_wake_parent should not fail if IRQ chip
>>>>> specifies IRQCHIP_SKIP_SET_WAKE. Otherwise, IRQ wakeup
>>>>> configuration can't be propagated properly through IRQ
>>>>> domains hierarchy.
>>>>>
>>>>> In case of TI OMAP DRA7 the issue reproduced with following
>>>>> configuration:
>>>>> ARM GIC<-OMAP wakeupgen<-TI CBAR<-GPIO<-GPIO pcf857x<-gpio_key
>>>>>
>>>>> gpio_key is wakeup source
>>>>>
>>>>> Failure is reproduced during suspend/resume to RAM:
>>>>> suspend:
>>>>>    - gpio_keys_suspend
>>>>>      enable_irq_wake
>>>>>        + pcf857x_irq_set_wake
>>>>>          + omap_gpio_wake_enable
>>>>>            + TI CBAR irq_chip_set_wake_parent
>>>>>              + OMAP wakeupgen has no .irq_set_wake()
>>>>
>>>> Most importantly, wakeupgen has IRQCHIP_SKIP_SET_WAKE set.
>>>>
>>>>>              and -ENOSYS will be returned
>>>>>
>>>>> resume:
>>>>>    - gpio_keys_resume
>>>>>      + disable_irq_wake
>>>>>        + irq_set_irq_wake
>>>>>          + WARN(1, "Unbalanced IRQ %d wake disable\n", irq);
>>>>>
>>>>> Fixes: 08b55e2a9208 ('genirq: Add irqchip_set_wake_parent')
>>>>> Signed-off-by: Grygorii Strashko <grygorii.strashko at ti.com>
>>>>> ---
>>>>>    kernel/irq/chip.c | 4 ++++
>>>>>    1 file changed, 4 insertions(+)
>>>>>
>>>>> diff --git a/kernel/irq/chip.c b/kernel/irq/chip.c
>>>>> index 6de638b..bdb1b9d 100644
>>>>> --- a/kernel/irq/chip.c
>>>>> +++ b/kernel/irq/chip.c
>>>>> @@ -1024,6 +1024,10 @@ int irq_chip_set_vcpu_affinity_parent(struct
>>>>> irq_data *data, void *vcpu_info)
>>>>>    int irq_chip_set_wake_parent(struct irq_data *data, unsigned int on)
>>>>>    {
>>>>>        data = data->parent_data;
>>>>> +
>>>>> +    if (irq_data_get_irq_chip(data)->flags & IRQCHIP_SKIP_SET_WAKE)
>>>>> +        return 0;
>>>>> +
>>>>>        if (data->chip->irq_set_wake)
>>>>>            return data->chip->irq_set_wake(data, on);
>>>>>
>>>>>
>>>>
>>>> We have a more general issue with chip flags, and how they combine
>>>> within a stack of irqchips.
>>>
>>> Indeed. Problem looks similar to IRQCHIP_MASK_ON_SUSPEND flag usage.
>>>
>>>>
>>>> What if you remove the irq_chip_set_wake_parent from the crossbar
>>>> driver, and instead set IRQCHIP_SKIP_SET_WAKE?
>>>
>>> I've thought about this and it should work for me.
>>> One question - what if crossbar will be not the last one in
>>> IRQ domains hierarchy?
>>>
>>
>> I can confirm, if I revert this patch, add IRQCHIP_SKIP_SET_WAKE to
>> the crossbar and remove irq_chip_set_wake_parent wakeups still works.
>> What do you prefer me to do: add additional patch for the crossbar,
>> drop/keep this patch?
>>
> 
> OK. There are two possibilities to fix set_wake functionality for TI OMAPs
> where below HW configurations are used:
>   OMAP4/5: GIC <- OMAP wakeupgen
>   DRA7: GIC <- OMAP wakeupgen <- TI CBAR
> 
> 
> 1) ensure that IRQCHIP_SKIP_SET_WAKE flag is set only for GIC and
> use irq_chip_set_wake_parent() in both wakeupgen and crossbar 
>  [this patch is required]
> 
> 2) ensure that IRQCHIP_SKIP_SET_WAKE flag is set and drop 
> .irq_set_wake()/irq_chip_set_wake_parent() for all IRQ chips
> in IRQ domains hierarchy.
>  [this patch can be dropped]
> 
> I'm going to select approach 2 and re-send.

Yeah, I'd like to go for the minimal approach for now, and work out what
exactly are the propagation semantics (I had something at some point,
need to find what I did with those patches...).

Thanks,

	M.
-- 
Jazz is not dead. It just smells funny...


From lee.jones at linaro.org  Fri Aug 14 03:41:23 2015
From: lee.jones at linaro.org (Lee Jones)
Date: Fri, 14 Aug 2015 11:41:23 +0100
Subject: [PATCH v2 3/6] mailbox: Add support for ST's Mailbox IP
In-Reply-To: <CABb+yY07A=jWvDgbPMpDdT=WPhwSzLumMGiJSB4NddTA4z7Hww@mail.gmail.com>
References: <1437990272-23111-1-git-send-email-lee.jones@linaro.org>
 <1437990272-23111-4-git-send-email-lee.jones@linaro.org>
 <CABb+yY3NTHLx2N-sUABjxQW=MUCntdUg1d8kjvjH0dkb4n9EgA@mail.gmail.com>
 <20150814063343.GI8782@x1>
 <CABb+yY07A=jWvDgbPMpDdT=WPhwSzLumMGiJSB4NddTA4z7Hww@mail.gmail.com>
Message-ID: <20150814104123.GL8782@x1>

On Fri, 14 Aug 2015, Jassi Brar wrote:

> On Fri, Aug 14, 2015 at 12:03 PM, Lee Jones <lee.jones at linaro.org> wrote:
> > On Thu, 13 Aug 2015, Jassi Brar wrote:
> >> On Mon, Jul 27, 2015 at 3:14 PM, Lee Jones <lee.jones at linaro.org> wrote:
> >>
> >> > +
> >> > +static bool sti_mbox_tx_is_ready(struct mbox_chan *chan)
> >> > +{
> >> > +       struct sti_channel *chan_info = chan->con_priv;
> >> > +       struct sti_mbox_device *mdev = chan_info->mdev;
> >> > +       unsigned int instance = chan_info->instance;
> >> > +       unsigned int channel = chan_info->channel;
> >> > +       void __iomem *base = MBOX_BASE(mdev, instance);
> >> > +
> >> > +       if (!(chan_info->direction & MBOX_TX))
> >> > +               return false;
> >> >
> >> Here the 'direction' is gotten via DT node of the client i.e, you
> >> expect consumer drivers to tell the provider what its limitations are?
> >>
> >> IMO if some physical channel can't do TX then that should be either
> >> hardcoded inside the controller driver or learnt via DT node of the
> >> _controller_.
> >
> > That's a fair point.
> .
> 
> >  I need to create a new property similar to the
> > already existing 'read-only'.  I guess 'tx-only' is equivalent.
> >
> Just to be clear, if you must have such a property it should come from
> the _controller_ node.

Correct.  That's the plan.

> However at one point you said,  "Only the A9 (Mbox 0) can Rx."
>   Which sounds like the 'simplex' constraint is not coming from the
> mailbox controller but from the remote endpoints that don't RX+TX
> except for one of them. That makes more sense than a controller with
> differently capable physical channels. If that is indeed the
> situation, then the controller is actually 'duplex' and there should
> be no tx-only/rx-only property anywhere. Everything automatically
> falls into place because client drivers are written for specific
> targets and, unless you write some code, there can be no TX call to a
> remote that doesn't listen.

Unfortunately it's a restriction of the hardware (or the controller as
you call it, although it's not really a controller).  There is only
one IRQ for Rx'ing and that's wired up to the A9's mailbox (Mailbox
0).  If one of the remote processors attempted to send a message
through any of the other mailboxes (other than the Mailbox 0), then no
one would hear the doorbell ring and the message would go unserviced.

> >> > +
> >> > +       for (i = 0; i < mbox->num_chans; i++) {
> >> > +               chan_info = mbox->chans[i].con_priv;
> >> > +
> >> > +               /* Is requested channel free? */
> >> > +               if (direction != MBOX_LOOPBACK &&
> >> >
> >> Consider this example when 2 clients ask for same physical channel but
> >> in different modes.
> >>            mboxes = <&mboxA 0 1 MBOX_TX>;
> >>            mboxes = <&mboxA 0 1 MBOX_LOOPBACK>;
> >>
> >> You happily assign 2 virtual channels backed by one physical channel
> >> {mboxA, 0, 1}. The 2 clients think they can freely do startup(),
> >> shutdown() and send_data() on the channels. But obviously we are
> >> screwed with races like
> >>    client1.startup()
> >>     -> client2.startup()
> >>         -> client2.send_data()
> >>             -> client2.shutdown()
> >>                 -> client1.send_data()  XXXX
> >
> > Good catch and a fair point.  As you say, it's unlikely to happen, but
> > I would like to prevent it in any case.
> >
> No, such races are a practical problem. We must own them.
> 
> I was talking about problems that arise because someone wrote bad
> DT... those are not 'practical' problems because there are too many
> ways to screw up with bad DT properties that if we try to check for
> them we'll go insane.

The only thing I'm having trouble with protecting at the moment is
other clients _also_ requesting a LOOPBACK channel.  I would like to
check which clients have already requested one/them, however that
information is not available until _after_ xlate() has been called,
which is pretty frustrating.  Perhaps I'll put a comment in instead.

> >>  Now you can shove in some more checks to 'fix' the race OR you can
> >> simply expose only physical channels.
> >
> > We can't expose all of the channels.  There are too many and would
> > take up too much *unused* memory.
> >
> I am aware of that. I said expose _only_ physical channels, not _all_ :)

It's impossible to know which physical channels will be used by
clients and subsequently which physical channels to expose.

-- 
Lee Jones
Linaro STMicroelectronics Landing Team Lead
Linaro.org ? Open source software for ARM SoCs
Follow Linaro: Facebook | Twitter | Blog


From mchehab at osg.samsung.com  Fri Aug 14 04:07:52 2015
From: mchehab at osg.samsung.com (Mauro Carvalho Chehab)
Date: Fri, 14 Aug 2015 08:07:52 -0300
Subject: [PATCH RFC v3 07/16] media: get rid of unused "extra_links"
 param on media_entity_init()
In-Reply-To: <20150814103348.GC19840@valkosipuli.retiisi.org.uk>
References: <cover.1439410053.git.mchehab@osg.samsung.com>
 <7b9f2654888f0fd54c290c50f50248a367768da7.1439410053.git.mchehab@osg.samsung.com>
 <20150814103348.GC19840@valkosipuli.retiisi.org.uk>
Message-ID: <20150814080752.1e2d1311@recife.lan>

Em Fri, 14 Aug 2015 13:33:48 +0300
Sakari Ailus <sakari.ailus at iki.fi> escreveu:

> Hi Mauro,
> 
> On Wed, Aug 12, 2015 at 05:14:51PM -0300, Mauro Carvalho Chehab wrote:
> > Currently, media_entity_init() creates an array with the links,
> > allocated at init time. It provides a parameter (extra_links)
> > that would allocate more links than the current needs, but this
> > is not used by any driver.
> > 
> > As we want to be able to do dynamic link allocation/removal,
> > we'll need to change the implementation of the links. So,
> > before doing that, let's first remove that extra unused
> > parameter, in order to cleanup the interface first.
> > 
> > Signed-off-by: Mauro Carvalho Chehab <mchehab at osg.samsung.com>
> > 
> ...
> 
> 
> > diff --git a/include/media/media-entity.h b/include/media/media-entity.h
> > index 738e1d5d25dc..be6885e7c8ed 100644
> > --- a/include/media/media-entity.h
> > +++ b/include/media/media-entity.h
> > @@ -177,7 +177,7 @@ void graph_obj_init(struct media_device *mdev,
> >  void graph_obj_remove(struct media_graph_obj *gobj);
> >  
> >  int media_entity_init(struct media_entity *entity, u16 num_pads,
> > -		struct media_pad *pads, u16 extra_links);
> > +		struct media_pad *pads);
> >  void media_entity_cleanup(struct media_entity *entity);
> >  
> >  int media_entity_create_link(struct media_entity *source, u16 source_pad,
> 
> How about putting this in front of the set? It has no dependencies to the
> other patches, does it?

Yeah this patch can be the first one ;) It just cleans up something
that we never used. It just needs to be before patch 8.

> 
> Acked-by: Sakari Ailus <sakari.ailus at linux.intel.com>
> 


From robert.richter at caviumnetworks.com  Fri Aug 14 04:47:54 2015
From: robert.richter at caviumnetworks.com (Robert Richter)
Date: Fri, 14 Aug 2015 13:47:54 +0200
Subject: [PATCH v2 3/5] irqchip, gicv3: Workaround for Cavium ThunderX
 erratum 23154
In-Reply-To: <55CDA69C.50600@arm.com>
References: <1439477277-6157-1-git-send-email-rric@kernel.org>
 <1439477277-6157-4-git-send-email-rric@kernel.org>
 <55CCB393.1040909@arm.com> <20150813161741.GO1820@rric.localhost>
 <55CCCBD1.2090304@arm.com> <20150813171150.GB4914@rric.localhost>
 <55CDA69C.50600@arm.com>
Message-ID: <20150814114754.GR1820@rric.localhost>

On 14.08.15 09:28:12, Marc Zyngier wrote:
> On 13/08/15 18:11, Robert Richter wrote:
> > On 13.08.15 17:54:41, Marc Zyngier wrote:
> >> On 13/08/15 17:17, Robert Richter wrote:
> >>> Marc,
> >>>
> >>> thanks for your quick review.
> >>>
> >>> On 13.08.15 16:11:15, Marc Zyngier wrote:
> >>>> On 13/08/15 15:47, Robert Richter wrote:
> >>>>> From: Robert Richter <rrichter at cavium.com>
> >>>
> >>>>>  static const struct gic_capabilities gicv3_errata[] = {
> >>>>>  	{
> >>>>> +		.desc		= "GIC: Cavium erratum 23154",
> >>>>> +		.iidr		= 0xa100034c,	/* ThunderX pass 1.x */
> >>>>> +		.iidr_mask	= 0xffff0fff,
> >>>>> +		.init		= gicv3_enable_cavium_thunderx,
> >>>>> +	},
> >>>>
> >>>> I'm even more puzzled. You're working around a CPU bug based on the ITS
> >>>> ID registers? Or have you swapped the detection methods for the two errata?
> >>>
> >>> :/ Right, I mixed this up... Must have starred on this for too long.
> >>> Will fix that.
> >>>
> >>> Wrt midr: Originally this was written to support iidr. I wanted to
> >>> keep the version check in the driver of the hw, an implementation
> >>> outside of drivers/irqchip looked not appropriate here as it would
> >>> rely then on arch arm64 only. This is the main reason. Apart from
> >>> that, I think an implmentation based on struct arm64_cpu_capabilities,
> >>> etc. would require much rework compared to my current easy
> >>> implementation, e.g:
> >>>
> >>>  * binding flags to callbacks and actually run them,
> >>>
> >>>  * handing over private driver data (base addr for iidr detection) to
> >>>    a capabilty's match function.
> >>>
> >>> Overall this looked bloated. Now, that the MIDR also needs to be
> >>> checked, it looked better to me to keep the gic hw detection at a
> >>> single location in the driver. This also allows us to check a
> >>> combination of midr and iidr values.
> >>>
> >>> I hope this sounds reasonable?
> >>
> >> +Will.
> >>
> >> The point I was trying to make is that a CPU interface bug is a CPU bug,
> >> and that it feels quite weird weird to have the detection in the GIC.
> >> Will, what do you think?
> >>
> >> Also, I don't really buy the combined MIDR/GITS_IIDR detection. These
> >> are two *very* distinct pieces of HW that are not even directly
> >> connected (the redistributors are in between).
> >>
> >> I wouldn't mind having something like:
> >>
> >> struct gic_capabilities {
> >> 	const char *desc;
> >> 	void (*init)(void *data);
> >> 	u32 iidr;
> >> 	u32 iidr_mask;
> >> 	int feature;
> >> };
> > 
> > Yes, once we leave this in the driver it is much easier. But why do
> > the read_cpuid_id() in cpu_errata.c and not in his file? The
> > value/mask pairs will be then on complete different locations for the
> > same kind of hw depending on midr/iidr. And the only reason for using
> > midr is not, that it's a cpu, but just that it needs to be applied to
> > guests too and this is the only way to find out the real hw, otherwise
> > we would use iidr. 
> 
> But that's the thing! Using GITS_IIDR would be the complete wrong thing
> to check for a CPU interface, which is what your ICC_IAR1_EL1 workaround
> is about.
> 
> > Apart from the fact that this looks inconsistent
> > having one errata^Mfeature flag for one errata, but not for the
> > other. And only because one is useing midr for hw detection and the
> > other iidr.
> 
> Because they are architecturally two different things. I strongly
> suspect that you could take the ThunderX core, remove Cavium's own
> implementation of the GIC and slap another GIC implementation in front
> of it, and you would have the exact same CPU interface bug, because
> that's where the issue is.

Ok, I am going to send an update based on your suggestions.

Thanks,

-Robert


From eric.auger at linaro.org  Fri Aug 14 04:58:03 2015
From: eric.auger at linaro.org (Eric Auger)
Date: Fri, 14 Aug 2015 13:58:03 +0200
Subject: [PATCH v2 12/15] KVM: arm64: sync LPI configuration and pending
 tables
In-Reply-To: <1436538111-4294-13-git-send-email-andre.przywara@arm.com>
References: <1436538111-4294-1-git-send-email-andre.przywara@arm.com>
 <1436538111-4294-13-git-send-email-andre.przywara@arm.com>
Message-ID: <55CDD7CB.9020103@linaro.org>

On 07/10/2015 04:21 PM, Andre Przywara wrote:
> The LPI configuration and pending tables of the GICv3 LPIs are held
> in tables in (guest) memory. To achieve reasonable performance, we
> cache this data in our own data structures, so we need to sync those
> two views from time to time. This behaviour is well described in the
> GICv3 spec and is also exercised by hardware, so the sync points are
> well known.
> 
> Provide functions that read the guest memory and store the
> information from the configuration and pending tables in the kernel.
> 
> Signed-off-by: Andre Przywara <andre.przywara at arm.com>
> ---
would help to have change log between v1 -> v2 (valid for the whole series)
>  include/kvm/arm_vgic.h  |   2 +
>  virt/kvm/arm/its-emul.c | 124 ++++++++++++++++++++++++++++++++++++++++++++++++
>  virt/kvm/arm/its-emul.h |   3 ++
>  3 files changed, 129 insertions(+)
> 
> diff --git a/include/kvm/arm_vgic.h b/include/kvm/arm_vgic.h
> index 2a67a10..323c33a 100644
> --- a/include/kvm/arm_vgic.h
> +++ b/include/kvm/arm_vgic.h
> @@ -167,6 +167,8 @@ struct vgic_its {
>  	int			cwriter;
>  	struct list_head	device_list;
>  	struct list_head	collection_list;
> +	/* memory used for buffering guest's memory */
> +	void			*buffer_page;
>  };
>  
>  struct vgic_dist {
> diff --git a/virt/kvm/arm/its-emul.c b/virt/kvm/arm/its-emul.c
> index b9c40d7..05245cb 100644
> --- a/virt/kvm/arm/its-emul.c
> +++ b/virt/kvm/arm/its-emul.c
> @@ -50,6 +50,7 @@ struct its_itte {
>  	struct its_collection *collection;
>  	u32 lpi;
>  	u32 event_id;
> +	u8 priority;
>  	bool enabled;
>  	unsigned long *pending;
>  };
> @@ -70,8 +71,124 @@ static struct its_itte *find_itte_by_lpi(struct kvm *kvm, int lpi)
>  	return NULL;
>  }
>  
> +#define LPI_PROP_ENABLE_BIT(p)	((p) & LPI_PROP_ENABLED)
> +#define LPI_PROP_PRIORITY(p)	((p) & 0xfc)
> +
> +/* stores the priority and enable bit for a given LPI */
> +static void update_lpi_config(struct kvm *kvm, struct its_itte *itte, u8 prop)
> +{
> +	itte->priority = LPI_PROP_PRIORITY(prop);
> +	itte->enabled  = LPI_PROP_ENABLE_BIT(prop);
> +}
> +
> +#define GIC_LPI_OFFSET 8192
> +
> +/* We scan the table in chunks the size of the smallest page size */
4kB chunks?
> +#define CHUNK_SIZE 4096U
> +
>  #define BASER_BASE_ADDRESS(x) ((x) & 0xfffffffff000ULL)
>  
> +static int nr_idbits_propbase(u64 propbaser)
> +{
> +	int nr_idbits = (1U << (propbaser & 0x1f)) + 1;
> +
> +	return max(nr_idbits, INTERRUPT_ID_BITS_ITS);
> +}
> +
> +/*
> + * Scan the whole LPI configuration table and put the LPI configuration
> + * data in our own data structures. This relies on the LPI being
> + * mapped before.
> + */
> +static bool its_update_lpis_configuration(struct kvm *kvm)
> +{
> +	struct vgic_dist *dist = &kvm->arch.vgic;
> +	u8 *prop = dist->its.buffer_page;
> +	u32 tsize;
> +	gpa_t propbase;
> +	int lpi = GIC_LPI_OFFSET;
> +	struct its_itte *itte;
> +	struct its_device *device;
> +	int ret;
> +
> +	propbase = BASER_BASE_ADDRESS(dist->propbaser);
> +	tsize = nr_idbits_propbase(dist->propbaser);
> +
> +	while (tsize > 0) {
> +		int chunksize = min(tsize, CHUNK_SIZE);
> +
> +		ret = kvm_read_guest(kvm, propbase, prop, chunksize);
I think you still have the spin_lock issue  since if my understanding is
correct this is called from
vgic_handle_mmio_access/vcall_range_handler/gic_enable_lpis
where vgic_handle_mmio_access. Or does it take another path?

Shouldn't we create a new kvm_io_device to avoid holding the dist lock?

Eric
> +		if (ret)
> +			return false;
> +
> +		spin_lock(&dist->its.lock);
> +		/*
> +		 * Updating the status for all allocated LPIs. We catch
> +		 * those LPIs that get disabled. We really don't care
> +		 * about unmapped LPIs, as they need to be updated
> +		 * later manually anyway once they get mapped.
> +		 */
> +		for_each_lpi(device, itte, kvm) {
> +			if (itte->lpi < lpi || itte->lpi >= lpi + chunksize)
> +				continue;
> +
> +			update_lpi_config(kvm, itte, prop[itte->lpi - lpi]);
> +		}
> +		spin_unlock(&dist->its.lock);
> +		tsize -= chunksize;
> +		lpi += chunksize;
> +		propbase += chunksize;
> +	}
> +
> +	return true;
> +}
> +
> +/*
> + * Scan the whole LPI pending table and sync the pending bit in there
> + * with our own data structures. This relies on the LPI being
> + * mapped before.
> + */
> +static bool its_sync_lpi_pending_table(struct kvm_vcpu *vcpu)
> +{
> +	struct vgic_dist *dist = &vcpu->kvm->arch.vgic;
> +	unsigned long *pendmask = dist->its.buffer_page;
> +	u32 nr_lpis = VITS_NR_LPIS;
> +	gpa_t pendbase;
> +	int lpi = 0;
> +	struct its_itte *itte;
> +	struct its_device *device;
> +	int ret;
> +	int lpi_bit, nr_bits;
> +
> +	pendbase = BASER_BASE_ADDRESS(dist->pendbaser[vcpu->vcpu_id]);
> +
> +	while (nr_lpis > 0) {
> +		nr_bits = min(nr_lpis, CHUNK_SIZE * 8);
> +
> +		ret = kvm_read_guest(vcpu->kvm, pendbase, pendmask,
> +				     nr_bits / 8);
> +		if (ret)
> +			return false;
> +
> +		spin_lock(&dist->its.lock);
> +		for_each_lpi(device, itte, vcpu->kvm) {
> +			lpi_bit = itte->lpi - lpi;
> +			if (lpi_bit < 0 || lpi_bit >= nr_bits)
> +				continue;
> +			if (test_bit(lpi_bit, pendmask))
> +				__set_bit(vcpu->vcpu_id, itte->pending);
> +			else
> +				__clear_bit(vcpu->vcpu_id, itte->pending);
> +		}
> +		spin_unlock(&dist->its.lock);
> +		nr_lpis -= nr_bits;
> +		lpi += nr_bits;
> +		pendbase += nr_bits / 8;
> +	}
> +
> +	return true;
> +}
> +
>  /* The distributor lock is held by the VGIC MMIO handler. */
>  static bool handle_mmio_misc_gits(struct kvm_vcpu *vcpu,
>  				  struct kvm_exit_mmio *mmio,
> @@ -389,6 +506,8 @@ static const struct vgic_io_range vgicv3_its_ranges[] = {
>  /* This is called on setting the LPI enable bit in the redistributor. */
>  void vgic_enable_lpis(struct kvm_vcpu *vcpu)
>  {
> +	its_update_lpis_configuration(vcpu->kvm);
> +	its_sync_lpi_pending_table(vcpu);
>  }
>  
>  int vits_init(struct kvm *kvm)
> @@ -400,6 +519,10 @@ int vits_init(struct kvm *kvm)
>  	if (!dist->pendbaser)
>  		return -ENOMEM;
>  
> +	its->buffer_page = kmalloc(CHUNK_SIZE, GFP_KERNEL);
> +	if (!its->buffer_page)
> +		return -ENOMEM;
> +
>  	spin_lock_init(&its->lock);
>  
>  	INIT_LIST_HEAD(&its->device_list);
> @@ -442,6 +565,7 @@ void vits_destroy(struct kvm *kvm)
>  		kfree(container_of(cur, struct its_collection, coll_list));
>  	}
>  
> +	kfree(its->buffer_page);
>  	kfree(dist->pendbaser);
>  
>  	its->enabled = false;
> diff --git a/virt/kvm/arm/its-emul.h b/virt/kvm/arm/its-emul.h
> index cc5d5ff..cbc3877 100644
> --- a/virt/kvm/arm/its-emul.h
> +++ b/virt/kvm/arm/its-emul.h
> @@ -29,6 +29,9 @@
>  
>  #include "vgic.h"
>  
> +#define INTERRUPT_ID_BITS_ITS 16
> +#define VITS_NR_LPIS (1U << INTERRUPT_ID_BITS_ITS)
> +
>  void vgic_enable_lpis(struct kvm_vcpu *vcpu);
>  int vits_init(struct kvm *kvm);
>  void vits_destroy(struct kvm *kvm);
> 



From eric.auger at linaro.org  Fri Aug 14 04:58:37 2015
From: eric.auger at linaro.org (Eric Auger)
Date: Fri, 14 Aug 2015 13:58:37 +0200
Subject: [PATCH v2 11/15] KVM: arm64: handle pending bit for LPIs in ITS
 emulation
In-Reply-To: <1436538111-4294-12-git-send-email-andre.przywara@arm.com>
References: <1436538111-4294-1-git-send-email-andre.przywara@arm.com>
 <1436538111-4294-12-git-send-email-andre.przywara@arm.com>
Message-ID: <55CDD7ED.90008@linaro.org>

On 07/10/2015 04:21 PM, Andre Przywara wrote:
> As the actual LPI number in a guest can be quite high, but is mostly
> assigned using a very sparse allocation scheme, bitmaps and arrays
> for storing the virtual interrupt status are a waste of memory.
> We use our equivalent of the "Interrupt Translation Table Entry"
> (ITTE) to hold this extra status information for a virtual LPI.
> As the normal VGIC code cannot use it's fancy bitmaps to manage
> pending interrupts, we provide a hook in the VGIC code to let the
> ITS emulation handle the list register queueing itself.
> LPIs are located in a separate number range (>=8192), so
> distinguishing them is easy. With LPIs being only edge-triggered, we
> get away with a less complex IRQ handling.
> 
> Signed-off-by: Andre Przywara <andre.przywara at arm.com>
> ---
>  include/kvm/arm_vgic.h      |  2 ++
>  virt/kvm/arm/its-emul.c     | 71 ++++++++++++++++++++++++++++++++++++++++++++
>  virt/kvm/arm/its-emul.h     |  3 ++
>  virt/kvm/arm/vgic-v3-emul.c |  2 ++
>  virt/kvm/arm/vgic.c         | 72 ++++++++++++++++++++++++++++++++++-----------
>  5 files changed, 133 insertions(+), 17 deletions(-)
> 
> diff --git a/include/kvm/arm_vgic.h b/include/kvm/arm_vgic.h
> index 1648668..2a67a10 100644
> --- a/include/kvm/arm_vgic.h
> +++ b/include/kvm/arm_vgic.h
> @@ -147,6 +147,8 @@ struct vgic_vm_ops {
>  	int	(*init_model)(struct kvm *);
>  	void	(*destroy_model)(struct kvm *);
>  	int	(*map_resources)(struct kvm *, const struct vgic_params *);
> +	bool	(*queue_lpis)(struct kvm_vcpu *);
> +	void	(*unqueue_lpi)(struct kvm_vcpu *, int irq);
>  };
>  
>  struct vgic_io_device {
> diff --git a/virt/kvm/arm/its-emul.c b/virt/kvm/arm/its-emul.c
> index 7f217fa..b9c40d7 100644
> --- a/virt/kvm/arm/its-emul.c
> +++ b/virt/kvm/arm/its-emul.c
> @@ -50,8 +50,26 @@ struct its_itte {
>  	struct its_collection *collection;
>  	u32 lpi;
>  	u32 event_id;
> +	bool enabled;
> +	unsigned long *pending;
>  };
>  
> +#define for_each_lpi(dev, itte, kvm) \
> +	list_for_each_entry(dev, &(kvm)->arch.vgic.its.device_list, dev_list) \
> +		list_for_each_entry(itte, &(dev)->itt, itte_list)
> +
You have a checkpatch error here:

ERROR: Macros with complex values should be enclosed in parentheses
#52: FILE: virt/kvm/arm/its-emul.c:57:
+#define for_each_lpi(dev, itte, kvm) \
+	list_for_each_entry(dev, &(kvm)->arch.vgic.its.device_list, dev_list) \
+		list_for_each_entry(itte, &(dev)->itt, itte_list)

> +static struct its_itte *find_itte_by_lpi(struct kvm *kvm, int lpi)
> +{
can't we have the same LPI present in different interrupt translation
tables? I don't know it is a sensible setting but I did not succeed in
finding it was not possible.
> +	struct its_device *device;
> +	struct its_itte *itte;
> +
> +	for_each_lpi(device, itte, kvm) {
> +		if (itte->lpi == lpi)
> +			return itte;
> +	}
> +	return NULL;
> +}
> +
>  #define BASER_BASE_ADDRESS(x) ((x) & 0xfffffffff000ULL)
>  
>  /* The distributor lock is held by the VGIC MMIO handler. */
> @@ -145,6 +163,59 @@ static bool handle_mmio_gits_idregs(struct kvm_vcpu *vcpu,
>  	return false;
>  }
>  
> +/*
> + * Find all enabled and pending LPIs and queue them into the list
> + * registers.
> + * The dist lock is held by the caller.
> + */
> +bool vits_queue_lpis(struct kvm_vcpu *vcpu)
> +{
> +	struct vgic_its *its = &vcpu->kvm->arch.vgic.its;
> +	struct its_device *device;
> +	struct its_itte *itte;
> +	bool ret = true;
> +
> +	if (!vgic_has_its(vcpu->kvm))
> +		return true;
> +	if (!its->enabled || !vcpu->kvm->arch.vgic.lpis_enabled)
> +		return true;
> +
> +	spin_lock(&its->lock);
> +	for_each_lpi(device, itte, vcpu->kvm) {
> +		if (!itte->enabled || !test_bit(vcpu->vcpu_id, itte->pending))
> +			continue;
> +
> +		if (!itte->collection)
> +			continue;
> +
> +		if (itte->collection->target_addr != vcpu->vcpu_id)
> +			continue;
> +
> +		__clear_bit(vcpu->vcpu_id, itte->pending);
> +
> +		ret &= vgic_queue_irq(vcpu, 0, itte->lpi);
what if the vgic_queue_irq fails since no LR can be found, the
itte->pending was cleared so we forget that LPI? shouldn't we restore
the pending state in ITT? in vgic_queue_hwirq the state change only is
performed if the vgic_queue_irq succeeds
> +	}
> +
> +	spin_unlock(&its->lock);
> +	return ret;
> +}
> +
> +/* Called with the distributor lock held by the caller. */
> +void vits_unqueue_lpi(struct kvm_vcpu *vcpu, int lpi)
I was a bit confused by the name of the function, with regard to
existing vgic_unqueue_irqs which restores the states in accordance to
what we have in LR. Wouldn't it make sense to call it
vits_lpi_set_pending(vcpu, lpi) or something that looks more similar to
vgic_dist_irq_set_pending setter which I think it mirrors.

> +{
> +	struct vgic_its *its = &vcpu->kvm->arch.vgic.its;
> +	struct its_itte *itte;
> +
> +	spin_lock(&its->lock);
> +
> +	/* Find the right ITTE and put the pending state back in there */
> +	itte = find_itte_by_lpi(vcpu->kvm, lpi);
> +	if (itte)
> +		__set_bit(vcpu->vcpu_id, itte->pending);
> +
> +	spin_unlock(&its->lock);
> +}
> +
>  static int vits_handle_command(struct kvm_vcpu *vcpu, u64 *its_cmd)
>  {
>  	return -ENODEV;
> diff --git a/virt/kvm/arm/its-emul.h b/virt/kvm/arm/its-emul.h
> index 472a6d0..cc5d5ff 100644
> --- a/virt/kvm/arm/its-emul.h
> +++ b/virt/kvm/arm/its-emul.h
> @@ -33,4 +33,7 @@ void vgic_enable_lpis(struct kvm_vcpu *vcpu);
>  int vits_init(struct kvm *kvm);
>  void vits_destroy(struct kvm *kvm);
>  
> +bool vits_queue_lpis(struct kvm_vcpu *vcpu);
> +void vits_unqueue_lpi(struct kvm_vcpu *vcpu, int irq);
> +
>  #endif
> diff --git a/virt/kvm/arm/vgic-v3-emul.c b/virt/kvm/arm/vgic-v3-emul.c
> index 49be3c3..4132c26 100644
> --- a/virt/kvm/arm/vgic-v3-emul.c
> +++ b/virt/kvm/arm/vgic-v3-emul.c
> @@ -948,6 +948,8 @@ void vgic_v3_init_emulation(struct kvm *kvm)
>  	dist->vm_ops.init_model = vgic_v3_init_model;
>  	dist->vm_ops.destroy_model = vgic_v3_destroy_model;
>  	dist->vm_ops.map_resources = vgic_v3_map_resources;
> +	dist->vm_ops.queue_lpis = vits_queue_lpis;
> +	dist->vm_ops.unqueue_lpi = vits_unqueue_lpi;
>  
>  	dist->vgic_dist_base = VGIC_ADDR_UNDEF;
>  	dist->vgic_redist_base = VGIC_ADDR_UNDEF;
> diff --git a/virt/kvm/arm/vgic.c b/virt/kvm/arm/vgic.c
> index 49ee92b..9dfd094 100644
> --- a/virt/kvm/arm/vgic.c
> +++ b/virt/kvm/arm/vgic.c
> @@ -95,6 +95,20 @@ static bool queue_sgi(struct kvm_vcpu *vcpu, int irq)
>  	return vcpu->kvm->arch.vgic.vm_ops.queue_sgi(vcpu, irq);
>  }
>  
> +static bool vgic_queue_lpis(struct kvm_vcpu *vcpu)
> +{
> +	if (vcpu->kvm->arch.vgic.vm_ops.queue_lpis)
> +		return vcpu->kvm->arch.vgic.vm_ops.queue_lpis(vcpu);
> +	else
> +		return true;
> +}
> +
> +static void vgic_unqueue_lpi(struct kvm_vcpu *vcpu, int irq)
> +{
> +	if (vcpu->kvm->arch.vgic.vm_ops.unqueue_lpi)
> +		vcpu->kvm->arch.vgic.vm_ops.unqueue_lpi(vcpu, irq);
> +}
> +
>  int kvm_vgic_map_resources(struct kvm *kvm)
>  {
>  	return kvm->arch.vgic.vm_ops.map_resources(kvm, vgic);
> @@ -1135,6 +1149,10 @@ static void vgic_retire_disabled_irqs(struct kvm_vcpu *vcpu)
>  	for_each_clear_bit(lr, elrsr_ptr, vgic->nr_lr) {
>  		vlr = vgic_get_lr(vcpu, lr);
>  
> +		/* We don't care about LPIs here */
> +		if (vlr.irq >= 8192)
> +			continue;
> +
>  		if (!vgic_irq_is_enabled(vcpu, vlr.irq)) {
>  			vlr.state = 0;
>  			vgic_set_lr(vcpu, lr, vlr);
> @@ -1147,25 +1165,33 @@ static void vgic_retire_disabled_irqs(struct kvm_vcpu *vcpu)
>  static void vgic_queue_irq_to_lr(struct kvm_vcpu *vcpu, int irq,
>  				 int lr_nr, int sgi_source_id)
>  {
> +	struct vgic_dist *dist = &vcpu->kvm->arch.vgic;
>  	struct vgic_lr vlr;
>  
>  	vlr.state = 0;
>  	vlr.irq = irq;
>  	vlr.source = sgi_source_id;
>  
> -	if (vgic_irq_is_active(vcpu, irq)) {
> -		vlr.state |= LR_STATE_ACTIVE;
> -		kvm_debug("Set active, clear distributor: 0x%x\n", vlr.state);
> -		vgic_irq_clear_active(vcpu, irq);
> -		vgic_update_state(vcpu->kvm);
> -	} else if (vgic_dist_irq_is_pending(vcpu, irq)) {
> -		vlr.state |= LR_STATE_PENDING;
> -		kvm_debug("Set pending: 0x%x\n", vlr.state);
> -	}
> -
> -	if (!vgic_irq_is_edge(vcpu, irq))
> -		vlr.state |= LR_EOI_INT;
> +	/* We care only about state for SGIs/PPIs/SPIs, not for LPIs */
> +	if (irq < dist->nr_irqs) {
> +		if (vgic_irq_is_active(vcpu, irq)) {
> +			vlr.state |= LR_STATE_ACTIVE;
> +			kvm_debug("Set active, clear distributor: 0x%x\n",
> +				  vlr.state);
> +			vgic_irq_clear_active(vcpu, irq);
> +			vgic_update_state(vcpu->kvm);
> +		} else if (vgic_dist_irq_is_pending(vcpu, irq)) {
> +			vlr.state |= LR_STATE_PENDING;
> +			kvm_debug("Set pending: 0x%x\n", vlr.state);
> +		}
>  
> +		if (!vgic_irq_is_edge(vcpu, irq))
> +			vlr.state |= LR_EOI_INT;
> +	} else {
> +		/* If this is an LPI, it can only be pending */
> +		if (irq >= 8192)
> +			vlr.state |= LR_STATE_PENDING;
> +	}
>  	vgic_set_lr(vcpu, lr_nr, vlr);
>  	vgic_sync_lr_elrsr(vcpu, lr_nr, vlr);
>  }
> @@ -1177,7 +1203,6 @@ static void vgic_queue_irq_to_lr(struct kvm_vcpu *vcpu, int irq,
>   */
>  bool vgic_queue_irq(struct kvm_vcpu *vcpu, u8 sgi_source_id, int irq)
>  {
> -	struct vgic_dist *dist = &vcpu->kvm->arch.vgic;
>  	u64 elrsr = vgic_get_elrsr(vcpu);
>  	unsigned long *elrsr_ptr = u64_to_bitmask(&elrsr);
>  	int lr;
> @@ -1185,7 +1210,6 @@ bool vgic_queue_irq(struct kvm_vcpu *vcpu, u8 sgi_source_id, int irq)
>  	/* Sanitize the input... */
>  	BUG_ON(sgi_source_id & ~7);
>  	BUG_ON(sgi_source_id && irq >= VGIC_NR_SGIS);
> -	BUG_ON(irq >= dist->nr_irqs);
Is it safe to remove that check. What if it is attempted to inject an
SPI larger than supported. I think you should refine the check but not
remove it.
>  
>  	kvm_debug("Queue IRQ%d\n", irq);
>  
> @@ -1265,8 +1289,12 @@ static void __kvm_vgic_flush_hwstate(struct kvm_vcpu *vcpu)
>  			overflow = 1;
>  	}
>  
> -
> -
> +	/*
> +	 * LPIs are not mapped in our bitmaps, so we leave the iteration
> +	 * to the ITS emulation code.
> +	 */
> +	if (!vgic_queue_lpis(vcpu))
> +		overflow = 1;
>  
>  epilog:
>  	if (overflow) {
> @@ -1387,6 +1415,16 @@ static void __kvm_vgic_sync_hwstate(struct kvm_vcpu *vcpu)
>  	for_each_clear_bit(lr_nr, elrsr_ptr, vgic_cpu->nr_lr) {
>  		vlr = vgic_get_lr(vcpu, lr_nr);
>  
> +		/* LPIs are handled separately */
> +		if (vlr.irq >= 8192) {
> +			/* We just need to take care about still pending LPIs */
> +			if (vlr.state & LR_STATE_PENDING) {
> +				vgic_unqueue_lpi(vcpu, vlr.irq);
> +				pending = true;
> +			}
> +			continue;
don't we need to reset the LR & update elrsr?
> +		}
> +
>  		BUG_ON(!(vlr.state & LR_STATE_MASK));
>  		pending = true;
>  
> @@ -1411,7 +1449,7 @@ static void __kvm_vgic_sync_hwstate(struct kvm_vcpu *vcpu)
>  	}
>  	vgic_update_state(vcpu->kvm);
>  
> -	/* vgic_update_state would not cover only-active IRQs */
> +	/* vgic_update_state would not cover only-active IRQs or LPIs */
>  	if (pending)
>  		set_bit(vcpu->vcpu_id, dist->irq_pending_on_cpu);
>  }
> 



From ard.biesheuvel at linaro.org  Fri Aug 14 05:15:23 2015
From: ard.biesheuvel at linaro.org (Ard Biesheuvel)
Date: Fri, 14 Aug 2015 14:15:23 +0200
Subject: [RFC] arm64: defconfig: enable 48-bit VA by default
In-Reply-To: <CY1PR0301MB07488764C02CCA3F653ED6A5877D0@CY1PR0301MB0748.namprd03.prod.outlook.com>
References: <CY1PR0301MB07488D6DC5F0B171D6B290E187830@CY1PR0301MB0748.namprd03.prod.outlook.com>
 <55B0E1AD.60409@arm.com>
 <BY2PR0301MB0743CBCFC5476E39A5D1EC0B878C0@BY2PR0301MB0743.namprd03.prod.outlook.com>
 <CAKv+Gu9LHBd7wM6P4H0X5WigzDETtpr2++_Ebo=adg5QtTOW2w@mail.gmail.com>
 <BY2PR0301MB074300C5F31701D9211827F0878C0@BY2PR0301MB0743.namprd03.prod.outlook.com>
 <20150730101358.GA30796@e104818-lin.cambridge.arm.com>
 <CY1PR0301MB074850E27D5D298D1B8495D2878B0@CY1PR0301MB0748.namprd03.prod.outlook.com>
 <20150730161210.GE407@e104818-lin.cambridge.arm.com>
 <CY1PR0301MB0748FA3A10AFA9BFC1AB0A39878B0@CY1PR0301MB0748.namprd03.prod.outlook.com>
 <CAKv+Gu-Wbv3J9-2KbXrz_3W_=VXChrD+REo1-q1Ns_=RUM1BFw@mail.gmail.com>
 <BY2PR0301MB07436AC9C8D023DC7C67DE3D87730@BY2PR0301MB0743.namprd03.prod.outlook.com>
 <CAKv+Gu-SH7MjkrgevfcUurPc7iQm+11cntfEo84opkqQoN2YPQ@mail.gmail.com>
 <CY1PR0301MB07488764C02CCA3F653ED6A5877D0@CY1PR0301MB0748.namprd03.prod.outlook.com>
Message-ID: <CAKv+Gu9gvrBwZry+pwXqsso9qg2vZcrYA8wgogRaRPhd6rsJuw@mail.gmail.com>

On 13 August 2015 at 21:24, Stuart Yoder <stuart.yoder at freescale.com> wrote:
>
>> -----Original Message-----
>> From: Ard Biesheuvel [mailto:ard.biesheuvel at linaro.org]
>> Sent: Saturday, August 08, 2015 3:21 AM
>> To: Yoder Stuart-B08248
>> Cc: Catalin Marinas; Mark Rutland; Marc Zyngier; Will Deacon; Newton Peter-RA3823; linux-arm-
>> kernel at lists.infradead.org; Sun York-R58495
>> Subject: Re: [RFC] arm64: defconfig: enable 48-bit VA by default
>>
>> On 7 aug. 2015, at 21:01, Stuart Yoder <stuart.yoder at freescale.com> wrote:
>>
>> >> Whether defconfig supports your platform optimally has nothing to do
>> >> with that. Of course, we should deal with the unexpected memory layout
>> >> gracefully, which is why Mark Rutland and myself proposed patches to
>> >> fix the panic you reported. But in a development context, I think it
>> >> is perfectly acceptable to simply load the kernel at 0x80_8000_0000,
>> >> and be able to run defconfig fine while losing just 2 GB of your 16 GB
>> >> at the low end.
>> >
>> > I've done this experiment-- loading/running the kernel at 0x80_8000_0000
>> > and losing the lower 2GB of memory.  And in fact I can see the kernel
>> > ignoring the low memory:
>> >
>> >   [    0.000000] Ignoring memory block 0x80000000 - 0x100000000
>> >
>>
>> Yes that looks correct
>>
>> > However, this only works with 48-bit VA enabled.  With 39-bit VA
>> > enabled the kernel crashes before the early console is working
>> > and I see nothing.
>> >
>>
>> That may well be a kernel bug: the changes to allow 39-bit VA kernels
>> to execute on systems whose memory is outside the 39-bit VA range was
>> developed and tested on AMD Seattle only, which has its RAM at
>> 0x80_0000_0000. But it is hard to be sure, of course, with no output
>> at all ...
>>
>> > Does the linear mapping we've been talking about just need to cover
>> > all of _RAM_, or does it need to cover all of I/O as well in
>> > the same mapping.
>> >
>> > In our case we have various SoC I/O devices, like the UART
>> > in the space below 4 GB... at 0x0100_0000.
>> >
>>
>> The linear mapping only covers system RAM, so that should not matter at all.
>>
>> > Before debugging further I want to check whether this should
>> > work in theory.  I had the impression that the issue was
>> > discontiguous RAM regions, and I/O was a separate issue.
>>
>> Yes, it should work in theory. The linear region starts at the base of
>> the kernel Image, and extends all the way up to the end of DRAM (14 GB
>> in your case, IIRC)
>
> An update on this... in my original test where the kernel did not run from
> high memory I was using a 4.0.x kernel.  I re-tried with a 4.2-rc4 kernel
> and it booted fine.  So, there is no kernel bug it in the latest kernel,
> it appears.
>

OK, thanks for reporting back.

So we still need to decide how to fix the case where the linear region
is not of sufficient size to cover all of memory, considering that is
what got this discussion started in the first place.

RobH was not too happy about how I proposed to split off
early_init_dt_add_memory_arch () but there has been no movement on
this since.

-- 
Ard.


From grygorii.strashko at ti.com  Fri Aug 14 05:20:26 2015
From: grygorii.strashko at ti.com (Grygorii Strashko)
Date: Fri, 14 Aug 2015 15:20:26 +0300
Subject: [PATCH v3 2/6] genirq: introduce irq_chip_set_type_parent() helper
In-Reply-To: <1439554830-19502-1-git-send-email-grygorii.strashko@ti.com>
References: <1439554830-19502-1-git-send-email-grygorii.strashko@ti.com>
Message-ID: <1439554830-19502-3-git-send-email-grygorii.strashko@ti.com>

It's expected to use this helper when the current
domain doesn't implement .irq_set_type(),  but expect
the parent to do so.

Cc: Sudeep Holla <sudeep.holla at arm.com>
Signed-off-by: Grygorii Strashko <grygorii.strashko at ti.com>
---
 include/linux/irq.h |  1 +
 kernel/irq/chip.c   | 17 +++++++++++++++++
 2 files changed, 18 insertions(+)

diff --git a/include/linux/irq.h b/include/linux/irq.h
index 92188b0..51744bc 100644
--- a/include/linux/irq.h
+++ b/include/linux/irq.h
@@ -484,6 +484,7 @@ extern int irq_chip_set_affinity_parent(struct irq_data *data,
 extern int irq_chip_set_wake_parent(struct irq_data *data, unsigned int on);
 extern int irq_chip_set_vcpu_affinity_parent(struct irq_data *data,
 					     void *vcpu_info);
+extern int irq_chip_set_type_parent(struct irq_data *data, unsigned int type);
 #endif
 
 /* Handling of unhandled and spurious interrupts: */
diff --git a/kernel/irq/chip.c b/kernel/irq/chip.c
index 6de638b..ae21682 100644
--- a/kernel/irq/chip.c
+++ b/kernel/irq/chip.c
@@ -985,6 +985,23 @@ int irq_chip_set_affinity_parent(struct irq_data *data,
 }
 
 /**
+ * irq_chip_set_type_parent - Set IRQ type on the parent interrupt
+ * @data:	Pointer to interrupt specific data
+ * @type:	IRQ_TYPE_{LEVEL,EDGE}_* value - see include/linux/irq.h
+ *
+ * Conditional, as the underlying parent chip might not implement it.
+ */
+int irq_chip_set_type_parent(struct irq_data *data, unsigned int type)
+{
+	data = data->parent_data;
+
+	if (data->chip->irq_set_type)
+		return data->chip->irq_set_type(data, type);
+
+	return -ENOSYS;
+}
+
+/**
  * irq_chip_retrigger_hierarchy - Retrigger an interrupt in hardware
  * @data:	Pointer to interrupt specific data
  *
-- 
2.5.0



From grygorii.strashko at ti.com  Fri Aug 14 05:20:27 2015
From: grygorii.strashko at ti.com (Grygorii Strashko)
Date: Fri, 14 Aug 2015 15:20:27 +0300
Subject: [PATCH v3 3/6] irqchip: crossbar: fix arm gic irq type configuration
In-Reply-To: <1439554830-19502-1-git-send-email-grygorii.strashko@ti.com>
References: <1439554830-19502-1-git-send-email-grygorii.strashko@ti.com>
Message-ID: <1439554830-19502-4-git-send-email-grygorii.strashko@ti.com>

It's observed that ARM GIC IRQ triggering type is not configured
properly when IRQ is routed through IRQ domain hierarchy and
system started using DT. As result, system will start using default
ARM GIC configuration, ignore DT IRQ triggering configuration,
and value of desc->irq_data.state_use_accessors = 0.

In case of TI OMAP DRA7 the following IRQ hierarchy is defined:
ARM GIC <- OMAP wakeupgen <- TI CBAR

Failed call chain:
     irq_create_of_mapping
     irq_set_irq_type
     __irq_set_trigger
     if (!chip || !chip->irq_set_type) {
        return 0; <- return here
     }
Crossbar has no .irq_set_type() defined and, so, IRQ triggering
configuration will not be propagated to parent IRQ domain.

Hence, fix it by using irq_chip_set_type_parent() for
propagation IRQ triggering type to parent IRQ domains.

Cc: Sudeep Holla <sudeep.holla at arm.com>
Fixes: 783d31863fb8 ('irqchip: crossbar: Convert dra7 crossbar...')
Signed-off-by: Grygorii Strashko <grygorii.strashko at ti.com>
---
 drivers/irqchip/irq-crossbar.c | 1 +
 1 file changed, 1 insertion(+)

diff --git a/drivers/irqchip/irq-crossbar.c b/drivers/irqchip/irq-crossbar.c
index 692fe2b..3ba58e7 100644
--- a/drivers/irqchip/irq-crossbar.c
+++ b/drivers/irqchip/irq-crossbar.c
@@ -69,6 +69,7 @@ static struct irq_chip crossbar_chip = {
 	.irq_unmask		= irq_chip_unmask_parent,
 	.irq_retrigger		= irq_chip_retrigger_hierarchy,
 	.irq_set_wake		= irq_chip_set_wake_parent,
+	.irq_set_type		= irq_chip_set_type_parent,
 #ifdef CONFIG_SMP
 	.irq_set_affinity	= irq_chip_set_affinity_parent,
 #endif
-- 
2.5.0



From grygorii.strashko at ti.com  Fri Aug 14 05:20:25 2015
From: grygorii.strashko at ti.com (Grygorii Strashko)
Date: Fri, 14 Aug 2015 15:20:25 +0300
Subject: [PATCH v3 1/6] genirq: fix irq_chip_retrigger_hierarchy
In-Reply-To: <1439554830-19502-1-git-send-email-grygorii.strashko@ti.com>
References: <1439554830-19502-1-git-send-email-grygorii.strashko@ti.com>
Message-ID: <1439554830-19502-2-git-send-email-grygorii.strashko@ti.com>

Now irq_chip_retrigger_hierarchy() returns -ENOSYS if it
was not able to find at least one .irq_retrigger() callback
implemented in IRQ domain hierarchy. As result, IRQ
re-triggering is not working now on ARM (TI OMAP) where
ARM GIC is not implemented this callback.
The .irq_retrigger() is optional (see check_irq_resend())
and there are no reasons to fail if it was not found, hence
lets return 0 in this case.

In case of TI OMAP DRA7 the following IRQ hierarchy is defined:
ARM GIC <- OMAP wakeupgen <- TI CBAR

Failure is reproduced during resume from suspend to RAM:
- wakeup by IRQx
- suspend_enter
  + arch_suspend_enable_irqs
    + handle_fasteoi_irq
      + irq_may_run
        + irq_pm_check_wakeup
          + irq_disable(IRQx)
  + dpm_resume_noirq()
    + resume_device_irqs
      + resume_irqs
        + resume_irq
          + __enable_irq <== IRQx is not re-triggered

Cc: Sudeep Holla <sudeep.holla at arm.com>
Cc: Jiang Liu <jiang.liu at linux.intel.com>
Fixes: 85f08c17de26 ('genirq: Introduce helper functions...')
Reviewed-by: Marc Zyngier <marc.zyngier at arm.com>
Signed-off-by: Grygorii Strashko <grygorii.strashko at ti.com>
---
 kernel/irq/chip.c | 2 +-
 1 file changed, 1 insertion(+), 1 deletion(-)

diff --git a/kernel/irq/chip.c b/kernel/irq/chip.c
index 27f4332..6de638b 100644
--- a/kernel/irq/chip.c
+++ b/kernel/irq/chip.c
@@ -997,7 +997,7 @@ int irq_chip_retrigger_hierarchy(struct irq_data *data)
 		if (data->chip && data->chip->irq_retrigger)
 			return data->chip->irq_retrigger(data);
 
-	return -ENOSYS;
+	return 0;
 }
 
 /**
-- 
2.5.0



From grygorii.strashko at ti.com  Fri Aug 14 05:20:29 2015
From: grygorii.strashko at ti.com (Grygorii Strashko)
Date: Fri, 14 Aug 2015 15:20:29 +0300
Subject: [PATCH v3 5/6] irqchip: crossbar: fix irq masking at suspend
In-Reply-To: <1439554830-19502-1-git-send-email-grygorii.strashko@ti.com>
References: <1439554830-19502-1-git-send-email-grygorii.strashko@ti.com>
Message-ID: <1439554830-19502-6-git-send-email-grygorii.strashko@ti.com>

All ARM GIC IRQs have to masked during suspend if they are not
wakeup source - this is expected behavior.Now this is not happen, since
switching to use IRQ domain hierarchy, because suspend_device_irq()
only checks flags in the last IRQ chip in hierarchy for
IRQCHIP_MASK_ON_SUSPEND bit set. And in the case of TI OMAP DRA7 the
last IRQ chip is TI Crossbar which do not have this flag set.

In case of TI OMAP DRA7 the following IRQ hierarchy is defined:
  ARM GIC <- OMAP wakeupgen <- TI CBAR
ARM GIC - IRQCHIP_MASK_ON_SUSPEND=n
OMAP wakeupgen - IRQCHIP_MASK_ON_SUSPEND=y
TI CBAR - IRQCHIP_MASK_ON_SUSPEND=n

Hence, fix by adding IRQCHIP_MASK_ON_SUSPEND for TI Crossbar IRQ chip.

Cc: Sudeep Holla <sudeep.holla at arm.com>
Signed-off-by: Grygorii Strashko <grygorii.strashko at ti.com>
---
 drivers/irqchip/irq-crossbar.c | 1 +
 1 file changed, 1 insertion(+)

diff --git a/drivers/irqchip/irq-crossbar.c b/drivers/irqchip/irq-crossbar.c
index 3ba58e7..f5a72cc 100644
--- a/drivers/irqchip/irq-crossbar.c
+++ b/drivers/irqchip/irq-crossbar.c
@@ -70,6 +70,7 @@ static struct irq_chip crossbar_chip = {
 	.irq_retrigger		= irq_chip_retrigger_hierarchy,
 	.irq_set_wake		= irq_chip_set_wake_parent,
 	.irq_set_type		= irq_chip_set_type_parent,
+	.flags			= IRQCHIP_MASK_ON_SUSPEND,
 #ifdef CONFIG_SMP
 	.irq_set_affinity	= irq_chip_set_affinity_parent,
 #endif
-- 
2.5.0



From grygorii.strashko at ti.com  Fri Aug 14 05:20:24 2015
From: grygorii.strashko at ti.com (Grygorii Strashko)
Date: Fri, 14 Aug 2015 15:20:24 +0300
Subject: [PATCH v3 0/6] genirq: irqdomain_hierarchy: fixes
Message-ID: <1439554830-19502-1-git-send-email-grygorii.strashko@ti.com>

Hi All,

I've had able to identify and reproduce four issues related to switching on
using IRQ domain hierarchy on TI OMAP DRA7 (dra7-evm). Most of them were
discovered during testing of Suspend to RAM and IRQ wakeup functionality.
In my opinion, most of these issue could also affect on other ARM SoC if
they are using IRQ domain hierarchy.

In case of TI OMAP DRA7 the following IRQ hierarchy is defined:
 ARM GIC <- OMAP wakeupgen <- TI CBAR

Issue 1 - patch 1: IRQ re-triggering is not working if IRQ domain
hierarchy used in combination with ARM GIC and irq_chip_retrigger_hierarchy()
is used by child IRQ domain.

Issue 2 - patches 2-4: ARM GIC IRQ triggering type is not configured
properly when IRQ is routed through IRQ domain hierarchy and
system started using DT. As result, system will start using default
ARM GIC configuration, ignore DT IRQ triggering configuration,
and value of desc->irq_data.state_use_accessors = 0.

/ # cat /proc/interrupts -- before
230:          0          0      CBAR  30 Edge    -00000000  48051000.gpio
263:          0          0      CBAR 116 Edge    -00000000  48053000.gpio
296:        246          0      CBAR  67 Edge    -00000000  OMAP UART0
311:        341          0      CBAR  51 Edge    -00000000  48070000.i2c
312:          3          0      CBAR  52 Edge    -00000000  48072000.i2c
313:          0          0      CBAR  56 Edge    -00000000  48060000.i2c
314:        255          0      CBAR  78 Edge    -00000000  mmc0
315:         40          0      CBAR  81 Edge    -00000000  mmc1
316:         13          0      CBAR  91 Edge    -00000000  mmc2
320:          0          0      CBAR  49 Edge    -00000000  4a140000.sata
324:          0          0      CBAR   1 Edge    -00000000  48078000.elm
325:          0          0      CBAR  15 Edge    -00000000  gpmc
333:          0          0      CBAR 335 Edge    -00000000  48484000.ethernet
334:          0          0      CBAR 336 Edge    -00000000  48484000.ethernet
415:          0          0   pcf857x   2 Edge    -00000000  btnUser1
416:          0          0   pcf857x   3 Edge    -00000000  btnUser2
445:          0          0   pinctrl 992 Edge    -00010000  4806a000.seria

/ # cat /proc/interrupts -- after
230:          0          0      CBAR  30 Level   -00002004  48051000.gpio
263:          0          0      CBAR 116 Level   -00002004  48053000.gpio
296:        567          0      CBAR  67 Level   -00002004  OMAP UART0
311:        363          0      CBAR  51 Level   -00002004  48070000.i2c
312:          3          0      CBAR  52 Level   -00002004  48072000.i2c
313:          0          0      CBAR  56 Level   -00002004  48060000.i2c
314:        197          0      CBAR  78 Level   -00002004  mmc0
315:         40          0      CBAR  81 Level   -00002004  mmc1
316:         13          0      CBAR  91 Level   -00002004  mmc2
320:          0          0      CBAR  49 Level   -00002004  4a140000.sata
324:          0          0      CBAR   1 Level   -00002004  48078000.elm
325:          0          0      CBAR  15 Level   -00002004  gpmc
333:          0          0      CBAR 335 Level   -00002004  48484000.ethernet
334:          0          0      CBAR 336 Level   -00002004  48484000.ethernet
415:          0          0   pcf857x   2 Edge    -00000000  btnUser1
416:          4          2   pcf857x   3 Edge    -00000000  btnUser2
445:          0          0   pinctrl 992 Edge    -00010000  4806a000.serial

-xxxxxxxx are current values of desc->irq_data.state_use_accessors

Issue 3 - patch 5: ARM GIC IRQs are not masked during suspend even
if they are not wakeup source. 
	This issue related to IRQCHIP MASK ON SUSPEND flag usage and,
honestly, it's not clear how this flag has to be processed in
case of IRQ domain hierarchy - previously there was one IRQ chip per IRQ
desc and if it has IRQCHIP MASK ON SUSPEND flag set we had to mask IRQ.
But now there are up to three (DRA7) IRQ chip per IRQ desc, and all of them
could have different IRQCHIP MASK ON SUSPEND flag's configuration.
	Here, to fix an issue, I've just added IRQCHIP MASK ON SUSPEND flag
to TI Crossbar which is the last IRQ domain in hierarchy.

Issue 4 - patch 6: On TI dra7-evm, when irq_set_irq_type() is called for
IRQ which belongs to IRQ domain hierarchy the .irq_set_wake() callback
will be executed for TI Crossbar IRQ chip. The TI Crossbar doesn't provides
any facility to configure the wakeup sources, but it implements
.irq_set_wake() callback as:
	.irq_set_wake		= irq_chip_set_wake_parent
As result, the irq_chip_set_wake_parent() will try to execute
.irq_set_wake() callback for parent IRQ domain, which is TI OMAP wakeupgen,
but TI OMAP wakeupgen has IRQCHIP_SKIP_SET_WAKE flag set and do not
implement .irq_set_wake() callback. Thus, irq_chip_set_wake_parent() will
fail with -ENOSYS, but it shouldn't.

IRQ domain hierarchy code was merged in 4.1, so it seems these patches
are material for stable 4.1+.

Tested on:
 TI OMAP DRA7, dra7-evm

Series based on:
 Linux 4.2-rc6

Changes in v3:
 - copy-past issue fixed in patch 'genirq: introduce
   irq_chip_set_type_parent() helper'
 - dropped patch 'genirq: fix irqchip_set_wake_parent if
   IRQCHIP_SKIP_SET_WAKE'
 - added patch 'irqchip: crossbar: fix set_wake functionality'

Changes in v2:
- initial patch has been split on three;
- added three more patches.

Links:
 v2: https://lkml.org/lkml/2015/8/12/759
 v1: https://lkml.org/lkml/2015/8/11/179

Cc: Sudeep Holla <sudeep.holla at arm.com>
Cc: Jiang Liu <jiang.liu at linux.intel.com>
Grygorii Strashko (6):
  genirq: fix irq_chip_retrigger_hierarchy
  genirq: introduce irq_chip_set_type_parent() helper
  irqchip: crossbar: fix arm gic irq type configuration
  ARM: OMAP: wakeupgen: fix arm gic irq type configuration
  irqchip: crossbar: fix irq masking at suspend
  irqchip: crossbar: fix set_wake functionality

 arch/arm/mach-omap2/omap-wakeupgen.c |  1 +
 drivers/irqchip/irq-crossbar.c       |  4 +++-
 include/linux/irq.h                  |  1 +
 kernel/irq/chip.c                    | 19 ++++++++++++++++++-
 4 files changed, 23 insertions(+), 2 deletions(-)

-- 
2.5.0



From eric.auger at linaro.org  Fri Aug 14 05:35:50 2015
From: eric.auger at linaro.org (Eric Auger)
Date: Fri, 14 Aug 2015 14:35:50 +0200
Subject: [PATCH v2 12/15] KVM: arm64: sync LPI configuration and pending
 tables
In-Reply-To: <55CDD7CB.9020103@linaro.org>
References: <1436538111-4294-1-git-send-email-andre.przywara@arm.com>
 <1436538111-4294-13-git-send-email-andre.przywara@arm.com>
 <55CDD7CB.9020103@linaro.org>
Message-ID: <55CDE0A6.5010906@linaro.org>

On 08/14/2015 01:58 PM, Eric Auger wrote:
> On 07/10/2015 04:21 PM, Andre Przywara wrote:
>> The LPI configuration and pending tables of the GICv3 LPIs are held
>> in tables in (guest) memory. To achieve reasonable performance, we
>> cache this data in our own data structures, so we need to sync those
>> two views from time to time. This behaviour is well described in the
>> GICv3 spec and is also exercised by hardware, so the sync points are
>> well known.
>>
>> Provide functions that read the guest memory and store the
>> information from the configuration and pending tables in the kernel.
>>
>> Signed-off-by: Andre Przywara <andre.przywara at arm.com>
>> ---
> would help to have change log between v1 -> v2 (valid for the whole series)
>>  include/kvm/arm_vgic.h  |   2 +
>>  virt/kvm/arm/its-emul.c | 124 ++++++++++++++++++++++++++++++++++++++++++++++++
>>  virt/kvm/arm/its-emul.h |   3 ++
>>  3 files changed, 129 insertions(+)
>>
>> diff --git a/include/kvm/arm_vgic.h b/include/kvm/arm_vgic.h
>> index 2a67a10..323c33a 100644
>> --- a/include/kvm/arm_vgic.h
>> +++ b/include/kvm/arm_vgic.h
>> @@ -167,6 +167,8 @@ struct vgic_its {
>>  	int			cwriter;
>>  	struct list_head	device_list;
>>  	struct list_head	collection_list;
>> +	/* memory used for buffering guest's memory */
>> +	void			*buffer_page;
>>  };
>>  
>>  struct vgic_dist {
>> diff --git a/virt/kvm/arm/its-emul.c b/virt/kvm/arm/its-emul.c
>> index b9c40d7..05245cb 100644
>> --- a/virt/kvm/arm/its-emul.c
>> +++ b/virt/kvm/arm/its-emul.c
>> @@ -50,6 +50,7 @@ struct its_itte {
>>  	struct its_collection *collection;
>>  	u32 lpi;
>>  	u32 event_id;
>> +	u8 priority;
>>  	bool enabled;
>>  	unsigned long *pending;
>>  };
>> @@ -70,8 +71,124 @@ static struct its_itte *find_itte_by_lpi(struct kvm *kvm, int lpi)
>>  	return NULL;
>>  }
>>  
>> +#define LPI_PROP_ENABLE_BIT(p)	((p) & LPI_PROP_ENABLED)
>> +#define LPI_PROP_PRIORITY(p)	((p) & 0xfc)
>> +
>> +/* stores the priority and enable bit for a given LPI */
>> +static void update_lpi_config(struct kvm *kvm, struct its_itte *itte, u8 prop)
>> +{
>> +	itte->priority = LPI_PROP_PRIORITY(prop);
>> +	itte->enabled  = LPI_PROP_ENABLE_BIT(prop);
>> +}
>> +
>> +#define GIC_LPI_OFFSET 8192
>> +
>> +/* We scan the table in chunks the size of the smallest page size */
> 4kB chunks?
>> +#define CHUNK_SIZE 4096U
>> +
>>  #define BASER_BASE_ADDRESS(x) ((x) & 0xfffffffff000ULL)
>>  
>> +static int nr_idbits_propbase(u64 propbaser)
>> +{
>> +	int nr_idbits = (1U << (propbaser & 0x1f)) + 1;
>> +
>> +	return max(nr_idbits, INTERRUPT_ID_BITS_ITS);
>> +}
>> +
>> +/*
>> + * Scan the whole LPI configuration table and put the LPI configuration
>> + * data in our own data structures. This relies on the LPI being
>> + * mapped before.
>> + */
>> +static bool its_update_lpis_configuration(struct kvm *kvm)
>> +{
>> +	struct vgic_dist *dist = &kvm->arch.vgic;
>> +	u8 *prop = dist->its.buffer_page;
>> +	u32 tsize;
>> +	gpa_t propbase;
>> +	int lpi = GIC_LPI_OFFSET;
>> +	struct its_itte *itte;
>> +	struct its_device *device;
>> +	int ret;
>> +
>> +	propbase = BASER_BASE_ADDRESS(dist->propbaser);
>> +	tsize = nr_idbits_propbase(dist->propbaser);
>> +
>> +	while (tsize > 0) {
>> +		int chunksize = min(tsize, CHUNK_SIZE);
>> +
>> +		ret = kvm_read_guest(kvm, propbase, prop, chunksize);
> I think you still have the spin_lock issue  since if my understanding is
> correct this is called from
> vgic_handle_mmio_access/vcall_range_handler/gic_enable_lpis
> where vgic_handle_mmio_access. Or does it take another path?
> 
> Shouldn't we create a new kvm_io_device to avoid holding the dist lock?

Sorry I forgot it was the case already. But currently we always register
the same io ops (registration entry point being
vgic_register_kvm_io_dev) and maybe we should have separate dispatcher
function for dist, redit and its?

Eric
> 
> Eric
>> +		if (ret)
>> +			return false;
>> +
>> +		spin_lock(&dist->its.lock);
>> +		/*
>> +		 * Updating the status for all allocated LPIs. We catch
>> +		 * those LPIs that get disabled. We really don't care
>> +		 * about unmapped LPIs, as they need to be updated
>> +		 * later manually anyway once they get mapped.
>> +		 */
>> +		for_each_lpi(device, itte, kvm) {
>> +			if (itte->lpi < lpi || itte->lpi >= lpi + chunksize)
>> +				continue;
>> +
>> +			update_lpi_config(kvm, itte, prop[itte->lpi - lpi]);
>> +		}
>> +		spin_unlock(&dist->its.lock);
>> +		tsize -= chunksize;
>> +		lpi += chunksize;
>> +		propbase += chunksize;
>> +	}
>> +
>> +	return true;
>> +}
>> +
>> +/*
>> + * Scan the whole LPI pending table and sync the pending bit in there
>> + * with our own data structures. This relies on the LPI being
>> + * mapped before.
>> + */
>> +static bool its_sync_lpi_pending_table(struct kvm_vcpu *vcpu)
>> +{
>> +	struct vgic_dist *dist = &vcpu->kvm->arch.vgic;
>> +	unsigned long *pendmask = dist->its.buffer_page;
>> +	u32 nr_lpis = VITS_NR_LPIS;
>> +	gpa_t pendbase;
>> +	int lpi = 0;
>> +	struct its_itte *itte;
>> +	struct its_device *device;
>> +	int ret;
>> +	int lpi_bit, nr_bits;
>> +
>> +	pendbase = BASER_BASE_ADDRESS(dist->pendbaser[vcpu->vcpu_id]);
>> +
>> +	while (nr_lpis > 0) {
>> +		nr_bits = min(nr_lpis, CHUNK_SIZE * 8);
>> +
>> +		ret = kvm_read_guest(vcpu->kvm, pendbase, pendmask,
>> +				     nr_bits / 8);
>> +		if (ret)
>> +			return false;
>> +
>> +		spin_lock(&dist->its.lock);
>> +		for_each_lpi(device, itte, vcpu->kvm) {
>> +			lpi_bit = itte->lpi - lpi;
>> +			if (lpi_bit < 0 || lpi_bit >= nr_bits)
>> +				continue;
>> +			if (test_bit(lpi_bit, pendmask))
>> +				__set_bit(vcpu->vcpu_id, itte->pending);
>> +			else
>> +				__clear_bit(vcpu->vcpu_id, itte->pending);
>> +		}
>> +		spin_unlock(&dist->its.lock);
>> +		nr_lpis -= nr_bits;
>> +		lpi += nr_bits;
>> +		pendbase += nr_bits / 8;
>> +	}
>> +
>> +	return true;
>> +}
>> +
>>  /* The distributor lock is held by the VGIC MMIO handler. */
>>  static bool handle_mmio_misc_gits(struct kvm_vcpu *vcpu,
>>  				  struct kvm_exit_mmio *mmio,
>> @@ -389,6 +506,8 @@ static const struct vgic_io_range vgicv3_its_ranges[] = {
>>  /* This is called on setting the LPI enable bit in the redistributor. */
>>  void vgic_enable_lpis(struct kvm_vcpu *vcpu)
>>  {
>> +	its_update_lpis_configuration(vcpu->kvm);
>> +	its_sync_lpi_pending_table(vcpu);
>>  }
>>  
>>  int vits_init(struct kvm *kvm)
>> @@ -400,6 +519,10 @@ int vits_init(struct kvm *kvm)
>>  	if (!dist->pendbaser)
>>  		return -ENOMEM;
>>  
>> +	its->buffer_page = kmalloc(CHUNK_SIZE, GFP_KERNEL);
>> +	if (!its->buffer_page)
>> +		return -ENOMEM;
>> +
>>  	spin_lock_init(&its->lock);
>>  
>>  	INIT_LIST_HEAD(&its->device_list);
>> @@ -442,6 +565,7 @@ void vits_destroy(struct kvm *kvm)
>>  		kfree(container_of(cur, struct its_collection, coll_list));
>>  	}
>>  
>> +	kfree(its->buffer_page);
>>  	kfree(dist->pendbaser);
>>  
>>  	its->enabled = false;
>> diff --git a/virt/kvm/arm/its-emul.h b/virt/kvm/arm/its-emul.h
>> index cc5d5ff..cbc3877 100644
>> --- a/virt/kvm/arm/its-emul.h
>> +++ b/virt/kvm/arm/its-emul.h
>> @@ -29,6 +29,9 @@
>>  
>>  #include "vgic.h"
>>  
>> +#define INTERRUPT_ID_BITS_ITS 16
>> +#define VITS_NR_LPIS (1U << INTERRUPT_ID_BITS_ITS)
>> +
>>  void vgic_enable_lpis(struct kvm_vcpu *vcpu);
>>  int vits_init(struct kvm *kvm);
>>  void vits_destroy(struct kvm *kvm);
>>
> 



From linus.walleij at linaro.org  Fri Aug 14 05:36:53 2015
From: linus.walleij at linaro.org (Linus Walleij)
Date: Fri, 14 Aug 2015 14:36:53 +0200
Subject: [PATCH v4 2/4] gpio: brcmstb: Add interrupt and wakeup source
 support
In-Reply-To: <CADtm3G7NQqDKwGujZUA9CUJ15+e8fLg0Kupbn2CMc0MeK9DbMw@mail.gmail.com>
References: <1438391865-7862-1-git-send-email-gregory.0xf0@gmail.com>
 <1438391865-7862-3-git-send-email-gregory.0xf0@gmail.com>
 <CACRpkdaz3k_N1qS5M_jmprPz8fHXeLtTke_YT8i2gaehmme+OQ@mail.gmail.com>
 <CADtm3G7NQqDKwGujZUA9CUJ15+e8fLg0Kupbn2CMc0MeK9DbMw@mail.gmail.com>
Message-ID: <CACRpkdaTES0EtbTBUGJLfFC4-fg91Fef1CBLh5tor9SpMCo1og@mail.gmail.com>

On Fri, Aug 14, 2015 at 1:49 AM, Gregory Fong <gregory.0xf0 at gmail.com> wrote:
> On Thu, Aug 13, 2015 at 4:11 AM, Linus Walleij <linus.walleij at linaro.org> wrote:
>> On Sat, Aug 1, 2015 at 3:17 AM, Gregory Fong <gregory.0xf0 at gmail.com> wrote:

>> This patch does not apply cleanly because the version in my
>> tree has INIT_LIST_HEAD(&priv->bank_list);
>> before the sanity check.
>>
>> I applied it manually, but check that things are working right.
>
> Your tree seems to be missing
>
> commit 2252607d327d5219a6331b50e6ec266d56402be0
> Author: Gregory Fong <gregory.0xf0 at gmail.com>
> Date:   Wed Jun 17 18:00:40 2015 -0700
>
>     gpio: brcmstb: fix null ptr dereference in driver remove
>
> which you had pulled in and sent for 4.2-rc1.  It should apply cleanly
> on top of that.

Yes sorry, my bad.

I merged in v4.2-rc4 and now it looks better.

Yours,
Linus Walleij


From grygorii.strashko at ti.com  Fri Aug 14 05:20:30 2015
From: grygorii.strashko at ti.com (Grygorii Strashko)
Date: Fri, 14 Aug 2015 15:20:30 +0300
Subject: [PATCH v3 6/6] irqchip: crossbar: fix set_wake functionality
In-Reply-To: <1439554830-19502-1-git-send-email-grygorii.strashko@ti.com>
References: <1439554830-19502-1-git-send-email-grygorii.strashko@ti.com>
Message-ID: <1439554830-19502-7-git-send-email-grygorii.strashko@ti.com>

The TI crossbar doesn't provides any facility to configure the wakeup
sources, but it implements .irq_set_wake() callback:
	.irq_set_wake		= irq_chip_set_wake_parent

As result, the irq_chip_set_wake_parent() will try to execute
.irq_set_wake() callback for parent IRQ domain, which is TI OMAP wakeupgen,
but TI OMAP wakeupgen has IRQCHIP_SKIP_SET_WAKE flag set and do not
implement .irq_set_wake() callback. Thus, irq_chip_set_wake_parent() will
fail with -ENOSYS.

In case of TI OMAP DRA7 the issue reproduced with following
configuration:
   ARM GIC<-OMAP wakeupgen<-TI CBAR<-GPIO<-GPIO pcf857x<-gpio_key

gpio_key is wakeup source

Failure is reproduced during suspend/resume to RAM:
 suspend:
  - gpio_keys_suspend
    + enable_irq_wake
      + pcf857x_irq_set_wake
        + omap_gpio_wake_enable
          + TI CBAR irq_chip_set_wake_parent
            + OMAP wakeupgen has no .irq_set_wake() and
              -ENOSYS will be returned

 resume:
  - gpio_keys_resume
    + disable_irq_wake
      + irq_set_irq_wake
         + WARN(1, "Unbalanced IRQ %d wake disable\n", irq);

Hence, fix it by adding IRQCHIP_SKIP_SET_WAKE flag to TI Crossbar and
drop .irq_set_wake() at the same time.

Cc: Sudeep Holla <sudeep.holla at arm.com>
Signed-off-by: Grygorii Strashko <grygorii.strashko at ti.com>
---
 drivers/irqchip/irq-crossbar.c | 4 ++--
 1 file changed, 2 insertions(+), 2 deletions(-)

diff --git a/drivers/irqchip/irq-crossbar.c b/drivers/irqchip/irq-crossbar.c
index f5a72cc..c12bb93 100644
--- a/drivers/irqchip/irq-crossbar.c
+++ b/drivers/irqchip/irq-crossbar.c
@@ -68,9 +68,9 @@ static struct irq_chip crossbar_chip = {
 	.irq_mask		= irq_chip_mask_parent,
 	.irq_unmask		= irq_chip_unmask_parent,
 	.irq_retrigger		= irq_chip_retrigger_hierarchy,
-	.irq_set_wake		= irq_chip_set_wake_parent,
 	.irq_set_type		= irq_chip_set_type_parent,
-	.flags			= IRQCHIP_MASK_ON_SUSPEND,
+	.flags			= IRQCHIP_MASK_ON_SUSPEND |
+				  IRQCHIP_SKIP_SET_WAKE,
 #ifdef CONFIG_SMP
 	.irq_set_affinity	= irq_chip_set_affinity_parent,
 #endif
-- 
2.5.0



From grygorii.strashko at ti.com  Fri Aug 14 05:20:28 2015
From: grygorii.strashko at ti.com (Grygorii Strashko)
Date: Fri, 14 Aug 2015 15:20:28 +0300
Subject: [PATCH v3 4/6] ARM: OMAP: wakeupgen: fix arm gic irq type
 configuration
In-Reply-To: <1439554830-19502-1-git-send-email-grygorii.strashko@ti.com>
References: <1439554830-19502-1-git-send-email-grygorii.strashko@ti.com>
Message-ID: <1439554830-19502-5-git-send-email-grygorii.strashko@ti.com>

It's observed that ARM GIC IRQ triggering type is not configured
properly when IRQ is routed through IRQ domain hierarchy and
system started using DT. As result, system will start using default
ARM GIC configuration, ignore DT IRQ triggering configuration,
and value of desc->irq_data.state_use_accessors = 0.

In case of TI OMAP DRA7 the following IRQ hierarchy is defined:
ARM GIC <- OMAP wakeupgen <- TI CBAR

Failed call chain:
     irq_create_of_mapping
     irq_set_irq_type
     __irq_set_trigger
     if (!chip || !chip->irq_set_type) {
        return 0; <- return here
     }
OMAP wakeupgen has no .irq_set_type() defined and, so, IRQ triggering
configuration will not be propagated to parent IRQ domain.

Hence, fix it by using irq_chip_set_type_parent() for
propagation IRQ triggering type to parent IRQ domains.

Cc: Sudeep Holla <sudeep.holla at arm.com>
Fixes: 7136d457f365 ('ARM: omap: convert wakeupgen to stacked domains')
Acked-by: Tony Lindgren <tony at atomide.com>
Signed-off-by: Grygorii Strashko <grygorii.strashko at ti.com>
---
 arch/arm/mach-omap2/omap-wakeupgen.c | 1 +
 1 file changed, 1 insertion(+)

diff --git a/arch/arm/mach-omap2/omap-wakeupgen.c b/arch/arm/mach-omap2/omap-wakeupgen.c
index 8e52621..e1d2e99 100644
--- a/arch/arm/mach-omap2/omap-wakeupgen.c
+++ b/arch/arm/mach-omap2/omap-wakeupgen.c
@@ -392,6 +392,7 @@ static struct irq_chip wakeupgen_chip = {
 	.irq_mask		= wakeupgen_mask,
 	.irq_unmask		= wakeupgen_unmask,
 	.irq_retrigger		= irq_chip_retrigger_hierarchy,
+	.irq_set_type		= irq_chip_set_type_parent,
 	.flags			= IRQCHIP_SKIP_SET_WAKE | IRQCHIP_MASK_ON_SUSPEND,
 #ifdef CONFIG_SMP
 	.irq_set_affinity	= irq_chip_set_affinity_parent,
-- 
2.5.0



From linux at arm.linux.org.uk  Fri Aug 14 05:48:03 2015
From: linux at arm.linux.org.uk (Russell King - ARM Linux)
Date: Fri, 14 Aug 2015 13:48:03 +0100
Subject: [PATCH] ARM: smp: Collapse arch_cpu_idle_dead() into cpu_die()
In-Reply-To: <1439539139-8783-1-git-send-email-sboyd@codeaurora.org>
References: <1439539139-8783-1-git-send-email-sboyd@codeaurora.org>
Message-ID: <20150814124803.GV7557@n2100.arm.linux.org.uk>

On Fri, Aug 14, 2015 at 12:58:59AM -0700, Stephen Boyd wrote:
> The only caller of cpu_die() on ARM is arch_cpu_idle_dead(), so
> let's simplify the code by renaming cpu_die() to
> arch_cpu_idle_dead(). While were here, drop the __ref annotation
> because __cpuinit is gone nowadays.
> 
> Signed-off-by: Stephen Boyd <sboyd at codeaurora.org>

Ok.  Please put it in the patch system, thanks.

-- 
FTTC broadband for 0.8mile line: currently at 10.5Mbps down 400kbps up
according to speedtest.net.


From gregory.clement at free-electrons.com  Fri Aug 14 05:49:58 2015
From: gregory.clement at free-electrons.com (Gregory CLEMENT)
Date: Fri, 14 Aug 2015 14:49:58 +0200
Subject: [PATCH] ARM: dma-mapping: Don't use outer_flush_range when the
 L2C is coherent
In-Reply-To: <20150813151603.GB4602@e104818-lin.cambridge.arm.com>
References: <1439474365-12058-1-git-send-email-gregory.clement@free-electrons.com>
 <20150813151603.GB4602@e104818-lin.cambridge.arm.com>
Message-ID: <55CDE3F6.7050401@free-electrons.com>

Hi Catalin,

On 13/08/2015 17:16, Catalin Marinas wrote:
> On Thu, Aug 13, 2015 at 03:59:25PM +0200, Gregory CLEMENT wrote:
>> @@ -241,12 +241,15 @@ static void __dma_clear_buffer(struct page *page, size_t size)
>>  			page++;
>>  			size -= PAGE_SIZE;
>>  		}
>> -		outer_flush_range(base, end);
>> +		if (!is_coherent)
>> +			outer_flush_range(base, end);
> 
> There is a dmac_flush_range() call above this (in the "while" block),
> please add a check for is_coherent in there as well.

OK

> 
>> @@ -540,7 +545,13 @@ static void *__alloc_from_contiguous(struct device *dev, size_t size,
>>  	if (!page)
>>  		return NULL;
>>  
>> -	__dma_clear_buffer(page, size);
>> +	/*
>> +	 * We are either called from __dma_alloc on the non-coherent
>> +	 * case or only once from atomic_pool_init. It is called
>> +	 * during boot time so it is harmless to use the non-coherent
>> +	 * case even if the L2C is coherent.
>> +	 */
>> +	__dma_clear_buffer(page, size, false);
> 
> This is no longer the case with commit 21caf3a765b0 ("ARM: 8398/1: arm
> DMA: Fix allocation from CMA for coherent DMA") in -next. So you need
> another argument for __alloc_from_contiguous() that can be passed down
> to __dma_clear_buffer().

OK

> 
>> @@ -1131,7 +1143,8 @@ static inline void __free_iova(struct dma_iommu_mapping *mapping,
>>  }
>>  
>>  static struct page **__iommu_alloc_buffer(struct device *dev, size_t size,
>> -					  gfp_t gfp, struct dma_attrs *attrs)
>> +					gfp_t gfp, struct dma_attrs *attrs,
>> +					bool is_coherent)
>>  {
>>  	struct page **pages;
>>  	int count = size >> PAGE_SHIFT;
>> @@ -1154,7 +1167,7 @@ static struct page **__iommu_alloc_buffer(struct device *dev, size_t size,
>>  		if (!page)
>>  			goto error;
>>  
>> -		__dma_clear_buffer(page, size);
>> +		__dma_clear_buffer(page, size, is_coherent);
>>  
>>  		for (i = 0; i < count; i++)
>>  			pages[i] = page + i;
>> @@ -1198,7 +1211,7 @@ static struct page **__iommu_alloc_buffer(struct device *dev, size_t size,
>>  				pages[i + j] = pages[i] + j;
>>  		}
>>  
>> -		__dma_clear_buffer(pages[i], PAGE_SIZE << order);
>> +		__dma_clear_buffer(pages[i], PAGE_SIZE << order, is_coherent);
>>  		i += 1 << order;
>>  		count -= 1 << order;
>>  	}
>> @@ -1359,8 +1372,9 @@ static void __iommu_free_atomic(struct device *dev, void *cpu_addr,
>>  	__free_from_pool(cpu_addr, size);
>>  }
>>  
>> -static void *arm_iommu_alloc_attrs(struct device *dev, size_t size,
>> -	    dma_addr_t *handle, gfp_t gfp, struct dma_attrs *attrs)
>> +static void *__arm_iommu_alloc_attrs(struct device *dev, size_t size,
>> +	    dma_addr_t *handle, gfp_t gfp, struct dma_attrs *attrs,
>> +	    bool is_coherent)
>>  {
>>  	pgprot_t prot = __get_dma_pgprot(attrs, PAGE_KERNEL);
>>  	struct page **pages;
>> @@ -1381,7 +1395,7 @@ static void *arm_iommu_alloc_attrs(struct device *dev, size_t size,
>>  	 */
>>  	gfp &= ~(__GFP_COMP);
>>  
>> -	pages = __iommu_alloc_buffer(dev, size, gfp, attrs);
>> +	pages = __iommu_alloc_buffer(dev, size, gfp, attrs, is_coherent);
>>  	if (!pages)
>>  		return NULL;
>>  
> 
> I can see you are trying to fix the iommu_alloc code to cope with
> coherent devices. I think it's currently broken and if you want to fix

Could you explain what is broken exactly?
The way I tried to deal with coherency or something more low level?

> it, you'd better add a separate patch. Otherwise, if no-one needs it,
> just pass false to __dma_clear_buffer() in __iommu_alloc_buffer()
> (though it's better if we fixed it).

I will keep it apart for now. I agree trying to do a separate patch for
this but I am not sure that I familiar enough with this part of the kernel
to achieve it.

> 
> In arm_iommu_alloc_attrs(), there is an __iommu_alloc_atomic() call
> which goes to the non-cacheable pool, it should use
> __alloc_simple_buffer() instead if is_coherent.

__iommu_alloc_atomic is called when GFP_WAIT is not set meaning that
we can't sleep, but _alloc_simple_buffer can sleep. I follow the calls
inside this function and at a point we found a call to the might_sleep_if
macro:
http://lxr.free-electrons.com/source/mm/page_alloc.c#L2859

The _alloc_simple_buffer function ended by calling gen_pool_alloc
which won't sleep so from my point of view it is still the right
function to call. Did I miss something?


Thanks,

Gregory


-- 
Gregory Clement, Free Electrons
Kernel, drivers, real-time and embedded Linux
development, consulting, training and support.
http://free-electrons.com


From gary.bisson at boundarydevices.com  Fri Aug 14 05:51:05 2015
From: gary.bisson at boundarydevices.com (Gary Bisson)
Date: Fri, 14 Aug 2015 14:51:05 +0200
Subject: [PATCH v3 0/2] ARM: dts: add Okaya LCD display for Nitrogen and
 Sabrelite
In-Reply-To: <1432314867-30888-1-git-send-email-gary.bisson@boundarydevices.com>
References: <1432314867-30888-1-git-send-email-gary.bisson@boundarydevices.com>
Message-ID: <1439556667-3424-1-git-send-email-gary.bisson@boundarydevices.com>

This series adds the Okaya 7" LCD support as a simple panel for both Nitrogen
and Sabrelite.

This v3 updates the series as the compatible name has been changed from
"okaya,rs800480t_7x0gp" to "okaya,rs800480t-7x0gp" when the drm patch has been
merged into linux-next branch.
http://git.kernel.org/cgit/linux/kernel/git/next/linux-next.git/commit/?id=ec9000c

Also note that Philipp Zabel's patch that enables the parallel-display driver
to work with a simple panel has been merged.
http://git.kernel.org/cgit/linux/kernel/git/stable/linux-stable.git/commit/?id=553a59f

A U-Boot script to configure the displays based on detection of the
touch controller is available for reference here:
https://github.com/boundarydevices/u-boot-imx6/blob/staging/board/boundary/nitrogen6x/6x_bootscript-mainline.txt

Gary Bisson (2):
  ARM: dts: imx6qdl-nitrogen6x: add Okaya LCD panel
  ARM: dts: imx6qdl-sabrelite: add Okaya LCD panel

 arch/arm/boot/dts/imx6qdl-nitrogen6x.dtsi | 76 ++++++++++++++++++++++++++++++-
 arch/arm/boot/dts/imx6qdl-sabrelite.dtsi  | 76 ++++++++++++++++++++++++++++++-
 2 files changed, 150 insertions(+), 2 deletions(-)

-- 
2.4.6



From gary.bisson at boundarydevices.com  Fri Aug 14 05:51:06 2015
From: gary.bisson at boundarydevices.com (Gary Bisson)
Date: Fri, 14 Aug 2015 14:51:06 +0200
Subject: [PATCH v3 1/2] ARM: dts: imx6qdl-nitrogen6x: add Okaya LCD panel
In-Reply-To: <1439556667-3424-1-git-send-email-gary.bisson@boundarydevices.com>
References: <1432314867-30888-1-git-send-email-gary.bisson@boundarydevices.com>
 <1439556667-3424-1-git-send-email-gary.bisson@boundarydevices.com>
Message-ID: <1439556667-3424-2-git-send-email-gary.bisson@boundarydevices.com>

This patch adds support for the 7" LCD display available for Nitrogen6x:
http://boundarydevices.com/product/7-800x480-display/

Also add label to backlight_lcd and connect it to the panel.

Signed-off-by: Gary Bisson <gary.bisson at boundarydevices.com>
---
 arch/arm/boot/dts/imx6qdl-nitrogen6x.dtsi | 76 ++++++++++++++++++++++++++++++-
 1 file changed, 75 insertions(+), 1 deletion(-)

diff --git a/arch/arm/boot/dts/imx6qdl-nitrogen6x.dtsi b/arch/arm/boot/dts/imx6qdl-nitrogen6x.dtsi
index 340bc8e..ad16dce 100644
--- a/arch/arm/boot/dts/imx6qdl-nitrogen6x.dtsi
+++ b/arch/arm/boot/dts/imx6qdl-nitrogen6x.dtsi
@@ -124,7 +124,7 @@
 		mux-ext-port = <3>;
 	};
 
-	backlight_lcd {
+	backlight_lcd: backlight_lcd {
 		compatible = "pwm-backlight";
 		pwms = <&pwm1 0 5000000>;
 		brightness-levels = <0 4 8 16 32 64 128 255>;
@@ -142,6 +142,43 @@
 		status = "okay";
 	};
 
+	lcd_display: display at di0 {
+		compatible = "fsl,imx-parallel-display";
+		#address-cells = <1>;
+		#size-cells = <0>;
+		interface-pix-fmt = "bgr666";
+		pinctrl-names = "default";
+		pinctrl-0 = <&pinctrl_j15>;
+		status = "okay";
+
+		port at 0 {
+			reg = <0>;
+
+			lcd_display_in: endpoint {
+				remote-endpoint = <&ipu1_di0_disp0>;
+			};
+		};
+
+		port at 1 {
+			reg = <1>;
+
+			lcd_display_out: endpoint {
+				remote-endpoint = <&lcd_panel_in>;
+			};
+		};
+	};
+
+	lcd_panel {
+		compatible = "okaya,rs800480t-7x0gp";
+		backlight = <&backlight_lcd>;
+
+		port {
+			lcd_panel_in: endpoint {
+				remote-endpoint = <&lcd_display_out>;
+			};
+		};
+	};
+
 	panel {
 		compatible = "hannstar,hsd100pxn1";
 		backlight = <&backlight_lvds>;
@@ -354,6 +391,39 @@
 			>;
 		};
 
+		pinctrl_j15: j15grp {
+			fsl,pins = <
+				MX6QDL_PAD_DI0_DISP_CLK__IPU1_DI0_DISP_CLK 0x10
+				MX6QDL_PAD_DI0_PIN15__IPU1_DI0_PIN15       0x10
+				MX6QDL_PAD_DI0_PIN2__IPU1_DI0_PIN02        0x10
+				MX6QDL_PAD_DI0_PIN3__IPU1_DI0_PIN03        0x10
+				MX6QDL_PAD_DISP0_DAT0__IPU1_DISP0_DATA00   0x10
+				MX6QDL_PAD_DISP0_DAT1__IPU1_DISP0_DATA01   0x10
+				MX6QDL_PAD_DISP0_DAT2__IPU1_DISP0_DATA02   0x10
+				MX6QDL_PAD_DISP0_DAT3__IPU1_DISP0_DATA03   0x10
+				MX6QDL_PAD_DISP0_DAT4__IPU1_DISP0_DATA04   0x10
+				MX6QDL_PAD_DISP0_DAT5__IPU1_DISP0_DATA05   0x10
+				MX6QDL_PAD_DISP0_DAT6__IPU1_DISP0_DATA06   0x10
+				MX6QDL_PAD_DISP0_DAT7__IPU1_DISP0_DATA07   0x10
+				MX6QDL_PAD_DISP0_DAT8__IPU1_DISP0_DATA08   0x10
+				MX6QDL_PAD_DISP0_DAT9__IPU1_DISP0_DATA09   0x10
+				MX6QDL_PAD_DISP0_DAT10__IPU1_DISP0_DATA10  0x10
+				MX6QDL_PAD_DISP0_DAT11__IPU1_DISP0_DATA11  0x10
+				MX6QDL_PAD_DISP0_DAT12__IPU1_DISP0_DATA12  0x10
+				MX6QDL_PAD_DISP0_DAT13__IPU1_DISP0_DATA13  0x10
+				MX6QDL_PAD_DISP0_DAT14__IPU1_DISP0_DATA14  0x10
+				MX6QDL_PAD_DISP0_DAT15__IPU1_DISP0_DATA15  0x10
+				MX6QDL_PAD_DISP0_DAT16__IPU1_DISP0_DATA16  0x10
+				MX6QDL_PAD_DISP0_DAT17__IPU1_DISP0_DATA17  0x10
+				MX6QDL_PAD_DISP0_DAT18__IPU1_DISP0_DATA18  0x10
+				MX6QDL_PAD_DISP0_DAT19__IPU1_DISP0_DATA19  0x10
+				MX6QDL_PAD_DISP0_DAT20__IPU1_DISP0_DATA20  0x10
+				MX6QDL_PAD_DISP0_DAT21__IPU1_DISP0_DATA21  0x10
+				MX6QDL_PAD_DISP0_DAT22__IPU1_DISP0_DATA22  0x10
+				MX6QDL_PAD_DISP0_DAT23__IPU1_DISP0_DATA23  0x10
+			>;
+		};
+
 		pinctrl_pwm1: pwm1grp {
 			fsl,pins = <
 				MX6QDL_PAD_SD1_DAT3__PWM1_OUT 0x1b0b1
@@ -421,6 +491,10 @@
 	};
 };
 
+&ipu1_di0_disp0 {
+	remote-endpoint = <&lcd_display_in>;
+};
+
 &ldb {
 	status = "okay";
 
-- 
2.4.6



From gary.bisson at boundarydevices.com  Fri Aug 14 05:51:07 2015
From: gary.bisson at boundarydevices.com (Gary Bisson)
Date: Fri, 14 Aug 2015 14:51:07 +0200
Subject: [PATCH v3 2/2] ARM: dts: imx6qdl-sabrelite: add Okaya LCD panel
In-Reply-To: <1439556667-3424-1-git-send-email-gary.bisson@boundarydevices.com>
References: <1432314867-30888-1-git-send-email-gary.bisson@boundarydevices.com>
 <1439556667-3424-1-git-send-email-gary.bisson@boundarydevices.com>
Message-ID: <1439556667-3424-3-git-send-email-gary.bisson@boundarydevices.com>

This patch adds support for the 7" LCD display available for Sabrelite:
http://boundarydevices.com/product/7-800x480-display/

Also add label to backlight_lcd and connect it to the panel.

Signed-off-by: Gary Bisson <gary.bisson at boundarydevices.com>
---
 arch/arm/boot/dts/imx6qdl-sabrelite.dtsi | 76 +++++++++++++++++++++++++++++++-
 1 file changed, 75 insertions(+), 1 deletion(-)

diff --git a/arch/arm/boot/dts/imx6qdl-sabrelite.dtsi b/arch/arm/boot/dts/imx6qdl-sabrelite.dtsi
index ce4c731..6adbcdd 100644
--- a/arch/arm/boot/dts/imx6qdl-sabrelite.dtsi
+++ b/arch/arm/boot/dts/imx6qdl-sabrelite.dtsi
@@ -123,7 +123,7 @@
 		mux-ext-port = <4>;
 	};
 
-	backlight_lcd {
+	backlight_lcd: backlight_lcd {
 		compatible = "pwm-backlight";
 		pwms = <&pwm1 0 5000000>;
 		brightness-levels = <0 4 8 16 32 64 128 255>;
@@ -141,6 +141,43 @@
 		status = "okay";
 	};
 
+	lcd_display: display at di0 {
+		compatible = "fsl,imx-parallel-display";
+		#address-cells = <1>;
+		#size-cells = <0>;
+		interface-pix-fmt = "bgr666";
+		pinctrl-names = "default";
+		pinctrl-0 = <&pinctrl_j15>;
+		status = "okay";
+
+		port at 0 {
+			reg = <0>;
+
+			lcd_display_in: endpoint {
+				remote-endpoint = <&ipu1_di0_disp0>;
+			};
+		};
+
+		port at 1 {
+			reg = <1>;
+
+			lcd_display_out: endpoint {
+				remote-endpoint = <&lcd_panel_in>;
+			};
+		};
+	};
+
+	lcd_panel {
+		compatible = "okaya,rs800480t-7x0gp";
+		backlight = <&backlight_lcd>;
+
+		port {
+			lcd_panel_in: endpoint {
+				remote-endpoint = <&lcd_display_out>;
+			};
+		};
+	};
+
 	panel {
 		compatible = "hannstar,hsd100pxn1";
 		backlight = <&backlight_lvds>;
@@ -348,6 +385,39 @@
 			>;
 		};
 
+		pinctrl_j15: j15grp {
+			fsl,pins = <
+				MX6QDL_PAD_DI0_DISP_CLK__IPU1_DI0_DISP_CLK 0x10
+				MX6QDL_PAD_DI0_PIN15__IPU1_DI0_PIN15       0x10
+				MX6QDL_PAD_DI0_PIN2__IPU1_DI0_PIN02        0x10
+				MX6QDL_PAD_DI0_PIN3__IPU1_DI0_PIN03        0x10
+				MX6QDL_PAD_DISP0_DAT0__IPU1_DISP0_DATA00   0x10
+				MX6QDL_PAD_DISP0_DAT1__IPU1_DISP0_DATA01   0x10
+				MX6QDL_PAD_DISP0_DAT2__IPU1_DISP0_DATA02   0x10
+				MX6QDL_PAD_DISP0_DAT3__IPU1_DISP0_DATA03   0x10
+				MX6QDL_PAD_DISP0_DAT4__IPU1_DISP0_DATA04   0x10
+				MX6QDL_PAD_DISP0_DAT5__IPU1_DISP0_DATA05   0x10
+				MX6QDL_PAD_DISP0_DAT6__IPU1_DISP0_DATA06   0x10
+				MX6QDL_PAD_DISP0_DAT7__IPU1_DISP0_DATA07   0x10
+				MX6QDL_PAD_DISP0_DAT8__IPU1_DISP0_DATA08   0x10
+				MX6QDL_PAD_DISP0_DAT9__IPU1_DISP0_DATA09   0x10
+				MX6QDL_PAD_DISP0_DAT10__IPU1_DISP0_DATA10  0x10
+				MX6QDL_PAD_DISP0_DAT11__IPU1_DISP0_DATA11  0x10
+				MX6QDL_PAD_DISP0_DAT12__IPU1_DISP0_DATA12  0x10
+				MX6QDL_PAD_DISP0_DAT13__IPU1_DISP0_DATA13  0x10
+				MX6QDL_PAD_DISP0_DAT14__IPU1_DISP0_DATA14  0x10
+				MX6QDL_PAD_DISP0_DAT15__IPU1_DISP0_DATA15  0x10
+				MX6QDL_PAD_DISP0_DAT16__IPU1_DISP0_DATA16  0x10
+				MX6QDL_PAD_DISP0_DAT17__IPU1_DISP0_DATA17  0x10
+				MX6QDL_PAD_DISP0_DAT18__IPU1_DISP0_DATA18  0x10
+				MX6QDL_PAD_DISP0_DAT19__IPU1_DISP0_DATA19  0x10
+				MX6QDL_PAD_DISP0_DAT20__IPU1_DISP0_DATA20  0x10
+				MX6QDL_PAD_DISP0_DAT21__IPU1_DISP0_DATA21  0x10
+				MX6QDL_PAD_DISP0_DAT22__IPU1_DISP0_DATA22  0x10
+				MX6QDL_PAD_DISP0_DAT23__IPU1_DISP0_DATA23  0x10
+			>;
+		};
+
 		pinctrl_pwm1: pwm1grp {
 			fsl,pins = <
 				MX6QDL_PAD_SD1_DAT3__PWM1_OUT 0x1b0b1
@@ -416,6 +486,10 @@
 	};
 };
 
+&ipu1_di0_disp0 {
+	remote-endpoint = <&lcd_display_in>;
+};
+
 &ldb {
 	status = "okay";
 
-- 
2.4.6



From hdegoede at redhat.com  Fri Aug 14 06:05:21 2015
From: hdegoede at redhat.com (Hans de Goede)
Date: Fri, 14 Aug 2015 15:05:21 +0200
Subject: [linux-sunxi] [RFC PATCH 0/6] mtd: nand: per-partition ECC config
In-Reply-To: <1438264225-23796-1-git-send-email-boris.brezillon@free-electrons.com>
References: <1438264225-23796-1-git-send-email-boris.brezillon@free-electrons.com>
Message-ID: <55CDE791.8030306@redhat.com>

Hi all,

On 30-07-15 15:50, Boris Brezillon wrote:
> Hello,
>
> It's been a year and a half since I posted my first series proposing
> an approach to support per-partition ECC config [1].
>
> First of all, before describing what's done in this patch series, I'd
> like to sum-up why this is needed, and why a generic approach is
> preferred over a NAND controller specific one.
> On one side we have a lot of NAND chips out there and they all have
> their own requirements in term of ECC strength and step size. On the
> other side, most SoCs support booting from NAND (they embed a simple
> logic in the ROM code to access a NAND chip through their NAND
> controller).
> In a ideal world all NAND chips would use the ONFI or JEDEC standard
> exposing their requirements in a standard way, and the SoC vendors
> would put the ONFI and JEDEC detection code in their ROM code and use
> it to properly configure their NAND controller.
> But we're not leaving in an ideal world, and some SoC vendors have
> decided to hardcode (or use a simplified logic) to select the ECC
> controller config. And in the case where the NAND requirement does
> not match the ROM code config, you only have two solutions:
>
> 1/ leave with the unsuitable ECC config for the whole chip
> 2/ isolate the portion of NAND read by the ROM code into a sperate
>     partition and use a suitable ECC config for the rest of the
>     NAND
>
> IMHO the second solution is far better than the first one, but it
> requires some adjustments in the mtdpart and NAND code layer to be
> applicable.
>
> Now, why should we prefer a generic approach over a NAND controller/SoC
> specific one ?
> Because, this seems to be a problem faced by other people on other
> platform than the sunxi one. Moreover, the ECC config is not the only
> thing we'd have to tweak per partition: I'm currently working on the
> NAND randomizer/scrambler aspect (required to support some MLC chips),
> and this is also something the ROM code configure differently to
> boot the first stage bootloader.
> For all these reasons, I think providing a generic infrastructure allowing
> specific implementation to tweak their behavior is better than hardcoding
> it somewhere in the NAND controller driver.
>
> This series proposes a solution to allow such per-partition config by
> first letting MTD implementations (or subframework) overload the MTD
> partition functions (patches 1 and 2), and then providing the appropriate
> modifications in the NAND layer to support per-partition ECC config
> (patches 3 to 5).
> The last patch is showing how a NAND controller can add support for
> per-partition ECC config.
>
> Note that I tried to keep the changes as less invasive as impossible, but
> I might have missed some aspects.
> Any suggestions are welcome.
>
> Best Regards,
>
> Boris

Thanks for doing this, this series looks good to me.

MTD maintainers, what do we need to do to get this upstream, submit
a non RFC version ? Or ... ?

Regards,

Hans


From catalin.marinas at arm.com  Fri Aug 14 06:14:28 2015
From: catalin.marinas at arm.com (Catalin Marinas)
Date: Fri, 14 Aug 2015 14:14:28 +0100
Subject: [PATCH 1/3] Honor ACPI _CCA attribute setting
In-Reply-To: <55CD4832.7070301@amd.com>
References: <1439416290-21228-1-git-send-email-jeremy.linton@arm.com>
 <1439416290-21228-2-git-send-email-jeremy.linton@arm.com>
 <55CD4832.7070301@amd.com>
Message-ID: <20150814131427.GD16368@e104818-lin.cambridge.arm.com>

On Fri, Aug 14, 2015 at 08:45:22AM +0700, Suravee Suthikulpanit wrote:
> On 8/13/15 04:51, Jeremy Linton wrote:
> >ACPI configurations can now mark devices as noncoherent,
> >support that choice.
> >
> >Signed-off-by: Jeremy Linton <jeremy.linton at arm.com>
> >---
> >  include/acpi/acpi_bus.h | 5 +++--
> >  1 file changed, 3 insertions(+), 2 deletions(-)
> >
> >diff --git a/include/acpi/acpi_bus.h b/include/acpi/acpi_bus.h
> >index 83061ca..7ecb8e4 100644
> >--- a/include/acpi/acpi_bus.h
> >+++ b/include/acpi/acpi_bus.h
> >@@ -399,7 +399,7 @@ static inline bool acpi_check_dma(struct acpi_device *adev, bool *coherent)
> >  	 * case 1. Do not support and disable DMA.
> >  	 * case 2. Support but rely on arch-specific cache maintenance for
> >  	 *         non-coherence DMA operations.
> >-	 * Currently, we implement case 1 above.
> >+	 * Currently, we implement case 2 above.
> >  	 *
> >  	 * For the case when _CCA is missing (i.e. cca_seen=0) and
> >  	 * platform specifies ACPI_CCA_REQUIRED, we do not support DMA,
> >@@ -407,7 +407,8 @@ static inline bool acpi_check_dma(struct acpi_device *adev, bool *coherent)
> >  	 *
> >  	 * See acpi_init_coherency() for more info.
> >  	 */
> >-	if (adev->flags.coherent_dma) {
> >+	if (adev->flags.coherent_dma ||
> >+	    (adev->flags.cca_seen && IS_ENABLED(CONFIG_ARM64))) {
> >  		ret = true;
> >  		if (coherent)
> >  			*coherent = adev->flags.coherent_dma;
> >
> 
> This change was in my earlier revisions for the original patch series to add
> ACPI CCA support. At the time, this was pushed back since we were not sure
> whether this would be a useful case, and whether such hardware exists.
> 
> Would it be useful to document somewhere (may be in the GIT commit message)
> about which hardware might need this?

So far, it's the ARM Juno development board (the emphasis here is on
being able to use it for development, not a production system).

I think the commit log should also give you credit for the original
implementation.

> Arnd/Catalin, any feedback on this?

That's where it was left in the previous thread:

https://lkml.org/lkml/2015/5/21/376

(and I'll refrain from further comments ;))

-- 
Catalin


From rric at kernel.org  Fri Aug 14 06:18:34 2015
From: rric at kernel.org (Robert Richter)
Date: Fri, 14 Aug 2015 15:18:34 +0200
Subject: [PATCH v3 0/6] irqchip,
 gicv3: Updates and Cavium ThunderX errata workarounds
Message-ID: <1439558320-5777-1-git-send-email-rric@kernel.org>

From: Robert Richter <rrichter at cavium.com>

This patch series adds gicv3 updates and workarounds for HW errata in
Cavium's ThunderX GICV3.

The first one is an unchanged resubmission of a patch from a gicv3
series I sent a while ago.

The next patches implement the workarounds for ThunderX's gicv3. Patch
#2 adds generic code to parse the hw revision provided by an IIDR or
MIDR register value and runs specific code if hw matches. For MIDR
detection it uses the arm64 errata framework. This patch is used for
the implementation of the actual errata fixes in patch #3 (gicv3) and
#5 (gicv3-its). Patch #4 is a prerequisit for patch #5. Patch #6 is a
change to the errata framework to only check for cpu features if the
capability value is non-zero.

All current review comments addressed so far with v3.

v3:
 * use arm64 errata framework for midr check
 * fix mixup of errata to be dependend from midr/iidr

v2:
 * Workaround for 23154:
   * implement code in a single asm() to keep instruction sequence
   * added comment to the code that explains the erratum
   * apply workaround also if running as guest, thus check MIDR
 * adding MIDR check

Robert Richter (6):
  irqchip, gicv3-its: Add range check for number of allocated pages
  irqchip, gicv3: Add HW revision detection and configuration
  irqchip, gicv3: Workaround for Cavium ThunderX erratum 23154
  irqchip, gicv3-its: Read typer register outside the loop
  irqchip, gicv3-its: Workaround for Cavium ThunderX errata 22375, 24313
  arm64: errata: Match all cpus if capability value is zero

 arch/arm64/Kconfig                  | 11 +++++++
 arch/arm64/include/asm/cpufeature.h | 16 +++++++---
 arch/arm64/include/asm/cputype.h    | 18 ++++++-----
 arch/arm64/kernel/cpu_errata.c      |  9 ++++++
 drivers/irqchip/irq-gic-common.c    | 13 ++++++++
 drivers/irqchip/irq-gic-common.h    | 10 ++++++
 drivers/irqchip/irq-gic-v3-its.c    | 62 ++++++++++++++++++++++++++++++++----
 drivers/irqchip/irq-gic-v3.c        | 63 ++++++++++++++++++++++++++++++++++++-
 include/linux/irqchip/arm-gic-v3.h  |  1 +
 9 files changed, 184 insertions(+), 19 deletions(-)

-- 
2.1.1



From rric at kernel.org  Fri Aug 14 06:18:36 2015
From: rric at kernel.org (Robert Richter)
Date: Fri, 14 Aug 2015 15:18:36 +0200
Subject: [PATCH v3 2/6] irqchip,
 gicv3: Add HW revision detection and configuration
In-Reply-To: <1439558320-5777-1-git-send-email-rric@kernel.org>
References: <1439558320-5777-1-git-send-email-rric@kernel.org>
Message-ID: <1439558320-5777-3-git-send-email-rric@kernel.org>

From: Robert Richter <rrichter at cavium.com>

Some GIC revisions require an individual configuration to esp. add
workarounds for HW bugs. This patch implements generic code to parse
the hw revision provided by an IIDR register value and runs specific
code if hw matches. There are functions that read the IIDR registers
for GICV3 and ITS (GICD_IIDR/GITS_IIDR) and then go through a list of
init functions to be called for specific versions.

A MIDR register value may also be used, this is especially useful for
hw detection from a guest.

The patch is needed to implement workarounds for HW errata in Cavium's
ThunderX GICV3.

v3:
 * use arm64 errata framework for midr check

v2:
 * adding MIDR check

Signed-off-by: Robert Richter <rrichter at cavium.com>
---
 drivers/irqchip/irq-gic-common.c | 13 +++++++++++++
 drivers/irqchip/irq-gic-common.h | 10 ++++++++++
 drivers/irqchip/irq-gic-v3-its.c | 15 +++++++++++++++
 drivers/irqchip/irq-gic-v3.c     | 14 ++++++++++++++
 4 files changed, 52 insertions(+)

diff --git a/drivers/irqchip/irq-gic-common.c b/drivers/irqchip/irq-gic-common.c
index 9448e391cb71..f5e901a62ea5 100644
--- a/drivers/irqchip/irq-gic-common.c
+++ b/drivers/irqchip/irq-gic-common.c
@@ -21,6 +21,19 @@
 
 #include "irq-gic-common.h"
 
+void gic_check_capabilities(u32 iidr, const struct gic_capabilities *cap,
+			void *data)
+{
+	for (; cap->desc; cap++) {
+		if (cap->cpu_cap && !cpus_have_cap(cap->cpu_cap))
+			continue;
+		if (cap->iidr != (cap->mask & iidr))
+			continue;
+		cap->init(data);
+		pr_info("%s\n", cap->desc);
+	}
+}
+
 int gic_configure_irq(unsigned int irq, unsigned int type,
 		       void __iomem *base, void (*sync_access)(void))
 {
diff --git a/drivers/irqchip/irq-gic-common.h b/drivers/irqchip/irq-gic-common.h
index 35a9884778bd..6d019a238f3b 100644
--- a/drivers/irqchip/irq-gic-common.h
+++ b/drivers/irqchip/irq-gic-common.h
@@ -20,10 +20,20 @@
 #include <linux/of.h>
 #include <linux/irqdomain.h>
 
+struct gic_capabilities {
+	const char *desc;
+	void (*init)(void *data);
+	u32 iidr;
+	u32 mask;
+	u16 cpu_cap;
+};
+
 int gic_configure_irq(unsigned int irq, unsigned int type,
                        void __iomem *base, void (*sync_access)(void));
 void gic_dist_config(void __iomem *base, int gic_irqs,
 		     void (*sync_access)(void));
 void gic_cpu_config(void __iomem *base, void (*sync_access)(void));
+void gic_check_capabilities(u32 iidr, const struct gic_capabilities *cap,
+			void *data);
 
 #endif /* _IRQ_GIC_COMMON_H */
diff --git a/drivers/irqchip/irq-gic-v3-its.c b/drivers/irqchip/irq-gic-v3-its.c
index 466edf8a7477..105674037618 100644
--- a/drivers/irqchip/irq-gic-v3-its.c
+++ b/drivers/irqchip/irq-gic-v3-its.c
@@ -36,6 +36,7 @@
 #include <asm/cputype.h>
 #include <asm/exception.h>
 
+#include "irq-gic-common.h"
 #include "irqchip.h"
 
 #define ITS_FLAGS_CMDQ_NEEDS_FLUSHING		(1 << 0)
@@ -1391,6 +1392,18 @@ static int its_force_quiescent(void __iomem *base)
 	}
 }
 
+static const struct gic_capabilities its_errata[] = {
+	{
+	}
+};
+
+static void its_check_capabilities(struct its_node *its)
+{
+	u32 iidr = readl_relaxed(its->base + GITS_IIDR);
+
+	gic_check_capabilities(iidr, its_errata, its);
+}
+
 static int its_probe(struct device_node *node, struct irq_domain *parent)
 {
 	struct resource res;
@@ -1449,6 +1462,8 @@ static int its_probe(struct device_node *node, struct irq_domain *parent)
 	}
 	its->cmd_write = its->cmd_base;
 
+	its_check_capabilities(its);
+
 	err = its_alloc_tables(its);
 	if (err)
 		goto out_free_cmd;
diff --git a/drivers/irqchip/irq-gic-v3.c b/drivers/irqchip/irq-gic-v3.c
index c52f7ba205b4..1a91902be0b1 100644
--- a/drivers/irqchip/irq-gic-v3.c
+++ b/drivers/irqchip/irq-gic-v3.c
@@ -766,6 +766,18 @@ static const struct irq_domain_ops gic_irq_domain_ops = {
 	.free = gic_irq_domain_free,
 };
 
+static const struct gic_capabilities gicv3_errata[] = {
+	{
+	}
+};
+
+static void gicv3_check_capabilities(void)
+{
+	u32 iidr = readl_relaxed(gic_data.dist_base + GICD_IIDR);
+
+	gic_check_capabilities(iidr, gicv3_errata, NULL);
+}
+
 static int __init gic_of_init(struct device_node *node, struct device_node *parent)
 {
 	void __iomem *dist_base;
@@ -825,6 +837,8 @@ static int __init gic_of_init(struct device_node *node, struct device_node *pare
 	gic_data.nr_redist_regions = nr_redist_regions;
 	gic_data.redist_stride = redist_stride;
 
+	gicv3_check_capabilities();
+
 	/*
 	 * Find out how many interrupts are supported.
 	 * The GIC only supports up to 1020 interrupt sources (SGI+PPI+SPI)
-- 
2.1.1



From rric at kernel.org  Fri Aug 14 06:18:35 2015
From: rric at kernel.org (Robert Richter)
Date: Fri, 14 Aug 2015 15:18:35 +0200
Subject: [PATCH v3 1/6] irqchip,
 gicv3-its: Add range check for number of allocated pages
In-Reply-To: <1439558320-5777-1-git-send-email-rric@kernel.org>
References: <1439558320-5777-1-git-send-email-rric@kernel.org>
Message-ID: <1439558320-5777-2-git-send-email-rric@kernel.org>

From: Robert Richter <rrichter at cavium.com>

The number of pages for the its table may exceed the maximum of 256.
Adding a range check and limitting the number to its maximum.

Based on a patch from Tirumalesh Chalamarla <tchalamarla at cavium.com>.

Signed-off-by: Tirumalesh Chalamarla <tchalamarla at cavium.com>
Reviewed-by: Marc Zyngier <marc.zyngier at arm.com>
Signed-off-by: Robert Richter <rrichter at cavium.com>
---
 drivers/irqchip/irq-gic-v3-its.c   | 11 ++++++++++-
 include/linux/irqchip/arm-gic-v3.h |  1 +
 2 files changed, 11 insertions(+), 1 deletion(-)

diff --git a/drivers/irqchip/irq-gic-v3-its.c b/drivers/irqchip/irq-gic-v3-its.c
index 1b7e155869f6..466edf8a7477 100644
--- a/drivers/irqchip/irq-gic-v3-its.c
+++ b/drivers/irqchip/irq-gic-v3-its.c
@@ -810,6 +810,7 @@ static int its_alloc_tables(struct its_node *its)
 		u64 entry_size = GITS_BASER_ENTRY_SIZE(val);
 		int order = get_order(psz);
 		int alloc_size;
+		int alloc_pages;
 		u64 tmp;
 		void *base;
 
@@ -844,6 +845,14 @@ static int its_alloc_tables(struct its_node *its)
 		}
 
 		alloc_size = (1 << order) * PAGE_SIZE;
+		alloc_pages = (alloc_size / psz);
+		if (alloc_pages > GITS_BASER_PAGES_MAX) {
+			alloc_pages = GITS_BASER_PAGES_MAX;
+			order = get_order(GITS_BASER_PAGES_MAX * psz);
+			pr_warn("%s: Device Table too large, reduce its page order to %u (%u pages)\n",
+				its->msi_chip.of_node->full_name, order, alloc_pages);
+		}
+
 		base = (void *)__get_free_pages(GFP_KERNEL | __GFP_ZERO, order);
 		if (!base) {
 			err = -ENOMEM;
@@ -872,7 +881,7 @@ static int its_alloc_tables(struct its_node *its)
 			break;
 		}
 
-		val |= (alloc_size / psz) - 1;
+		val |= alloc_pages - 1;
 
 		writeq_relaxed(val, its->base + GITS_BASER + i * 8);
 		tmp = readq_relaxed(its->base + GITS_BASER + i * 8);
diff --git a/include/linux/irqchip/arm-gic-v3.h b/include/linux/irqchip/arm-gic-v3.h
index ffbc034c8810..f28da189c4aa 100644
--- a/include/linux/irqchip/arm-gic-v3.h
+++ b/include/linux/irqchip/arm-gic-v3.h
@@ -229,6 +229,7 @@
 #define GITS_BASER_PAGE_SIZE_16K	(1UL << GITS_BASER_PAGE_SIZE_SHIFT)
 #define GITS_BASER_PAGE_SIZE_64K	(2UL << GITS_BASER_PAGE_SIZE_SHIFT)
 #define GITS_BASER_PAGE_SIZE_MASK	(3UL << GITS_BASER_PAGE_SIZE_SHIFT)
+#define GITS_BASER_PAGES_MAX		256
 
 #define GITS_BASER_TYPE_NONE		0
 #define GITS_BASER_TYPE_DEVICE		1
-- 
2.1.1



From rric at kernel.org  Fri Aug 14 06:18:37 2015
From: rric at kernel.org (Robert Richter)
Date: Fri, 14 Aug 2015 15:18:37 +0200
Subject: [PATCH v3 3/6] irqchip,
 gicv3: Workaround for Cavium ThunderX erratum 23154
In-Reply-To: <1439558320-5777-1-git-send-email-rric@kernel.org>
References: <1439558320-5777-1-git-send-email-rric@kernel.org>
Message-ID: <1439558320-5777-4-git-send-email-rric@kernel.org>

From: Robert Richter <rrichter at cavium.com>

This patch implements Cavium ThunderX erratum 23154.

The gicv3 of ThunderX requires a modified version for reading the IAR
status to ensure data synchronization. Since this is in the fast-path
and called with each interrupt, runtime patching is used using jump
label patching for smallest overhead (no-op). This is the same
technique as used for tracepoints.

v3:
 * fix erratum to be dependend from midr
 * use arm64 errata framework

v2:
 * implement code in a single asm() to keep instruction sequence
 * added comment to the code that explains the erratum
 * apply workaround also if running as guest, thus check MIDR

Signed-off-by: Robert Richter <rrichter at cavium.com>
---
 arch/arm64/Kconfig                  | 11 +++++++++
 arch/arm64/include/asm/cpufeature.h |  3 ++-
 arch/arm64/include/asm/cputype.h    | 18 ++++++++------
 arch/arm64/kernel/cpu_errata.c      |  9 +++++++
 drivers/irqchip/irq-gic-v3.c        | 49 ++++++++++++++++++++++++++++++++++++-
 5 files changed, 81 insertions(+), 9 deletions(-)

diff --git a/arch/arm64/Kconfig b/arch/arm64/Kconfig
index 0f6edb14b7e4..4f866a4c6536 100644
--- a/arch/arm64/Kconfig
+++ b/arch/arm64/Kconfig
@@ -417,6 +417,17 @@ config ARM64_ERRATUM_845719
 
 	  If unsure, say Y.
 
+config CAVIUM_ERRATUM_23154
+	bool "Cavium erratum 23154: Access to ICC_IAR1_EL1 is not sync'ed"
+	depends on ARCH_THUNDER
+	default y
+	help
+	  The gicv3 of ThunderX requires a modified version for
+	  reading the IAR status to ensure data synchronization
+	  (access to icc_iar1_el1 is not sync'ed before and after).
+
+	  If unsure, say Y.
+
 endmenu
 
 
diff --git a/arch/arm64/include/asm/cpufeature.h b/arch/arm64/include/asm/cpufeature.h
index c1044218a63a..2a5e4c163ee5 100644
--- a/arch/arm64/include/asm/cpufeature.h
+++ b/arch/arm64/include/asm/cpufeature.h
@@ -25,8 +25,9 @@
 #define ARM64_WORKAROUND_DEVICE_LOAD_ACQUIRE	1
 #define ARM64_WORKAROUND_845719			2
 #define ARM64_HAS_SYSREG_GIC_CPUIF		3
+#define ARM64_WORKAROUND_CAVIUM_23154		4
 
-#define ARM64_NCAPS				4
+#define ARM64_NCAPS				5
 
 #ifndef __ASSEMBLY__
 
diff --git a/arch/arm64/include/asm/cputype.h b/arch/arm64/include/asm/cputype.h
index a84ec605bed8..3f0c7683f252 100644
--- a/arch/arm64/include/asm/cputype.h
+++ b/arch/arm64/include/asm/cputype.h
@@ -62,15 +62,19 @@
 	(0xf			<< MIDR_ARCHITECTURE_SHIFT) | \
 	((partnum)		<< MIDR_PARTNUM_SHIFT))
 
-#define ARM_CPU_IMP_ARM		0x41
-#define ARM_CPU_IMP_APM		0x50
+#define ARM_CPU_IMP_ARM			0x41
+#define ARM_CPU_IMP_APM			0x50
+#define ARM_CPU_IMP_CAVIUM		0x43
 
-#define ARM_CPU_PART_AEM_V8	0xD0F
-#define ARM_CPU_PART_FOUNDATION	0xD00
-#define ARM_CPU_PART_CORTEX_A57	0xD07
-#define ARM_CPU_PART_CORTEX_A53	0xD03
+#define ARM_CPU_PART_AEM_V8		0xD0F
+#define ARM_CPU_PART_FOUNDATION		0xD00
+#define ARM_CPU_PART_CORTEX_A57		0xD07
+#define ARM_CPU_PART_CORTEX_A53		0xD03
+
+#define APM_CPU_PART_POTENZA		0x000
+
+#define CAVIUM_CPU_PART_THUNDERX	0x0A1
 
-#define APM_CPU_PART_POTENZA	0x000
 
 #define ID_AA64MMFR0_BIGENDEL0_SHIFT	16
 #define ID_AA64MMFR0_BIGENDEL0_MASK	(0xf << ID_AA64MMFR0_BIGENDEL0_SHIFT)
diff --git a/arch/arm64/kernel/cpu_errata.c b/arch/arm64/kernel/cpu_errata.c
index 6ffd91438560..574450c257a4 100644
--- a/arch/arm64/kernel/cpu_errata.c
+++ b/arch/arm64/kernel/cpu_errata.c
@@ -23,6 +23,7 @@
 
 #define MIDR_CORTEX_A53 MIDR_CPU_PART(ARM_CPU_IMP_ARM, ARM_CPU_PART_CORTEX_A53)
 #define MIDR_CORTEX_A57 MIDR_CPU_PART(ARM_CPU_IMP_ARM, ARM_CPU_PART_CORTEX_A57)
+#define MIDR_THUNDERX	MIDR_CPU_PART(ARM_CPU_IMP_CAVIUM, CAVIUM_CPU_PART_THUNDERX)
 
 #define CPU_MODEL_MASK (MIDR_IMPLEMENTOR_MASK | MIDR_PARTNUM_MASK | \
 			MIDR_ARCHITECTURE_MASK)
@@ -82,6 +83,14 @@ const struct arm64_cpu_capabilities arm64_errata[] = {
 		MIDR_RANGE(MIDR_CORTEX_A53, 0x00, 0x04),
 	},
 #endif
+#ifdef CONFIG_CAVIUM_ERRATUM_23154
+	{
+	/* Cavium ThunderX, pass 1.x */
+		.desc = "Cavium erratum 23154",
+		.capability = ARM64_WORKAROUND_CAVIUM_23154,
+		MIDR_RANGE(MIDR_THUNDERX, 0x00, 0x01),
+	},
+#endif
 	{
 	}
 };
diff --git a/drivers/irqchip/irq-gic-v3.c b/drivers/irqchip/irq-gic-v3.c
index 1a91902be0b1..59a5f13f3c10 100644
--- a/drivers/irqchip/irq-gic-v3.c
+++ b/drivers/irqchip/irq-gic-v3.c
@@ -107,7 +107,7 @@ static void gic_redist_wait_for_rwp(void)
 }
 
 /* Low level accessors */
-static u64 __maybe_unused gic_read_iar(void)
+static u64 gic_read_iar_common(void)
 {
 	u64 irqstat;
 
@@ -115,6 +115,38 @@ static u64 __maybe_unused gic_read_iar(void)
 	return irqstat;
 }
 
+/*
+ * Cavium ThunderX erratum 23154
+ *
+ * The gicv3 of ThunderX requires a modified version for reading the
+ * IAR status to ensure data synchronization (access to icc_iar1_el1
+ * is not sync'ed before and after).
+ */
+static u64 gic_read_iar_cavium_thunderx(void)
+{
+	u64 irqstat;
+
+	asm volatile(
+		"nop;nop;nop;nop\n\t"
+		"nop;nop;nop;nop\n\t"
+		"mrs_s %0, " __stringify(ICC_IAR1_EL1) "\n\t"
+		"nop;nop;nop;nop"
+		: "=r" (irqstat));
+	mb();
+
+	return irqstat;
+}
+
+struct static_key is_cavium_thunderx = STATIC_KEY_INIT_FALSE;
+
+static u64 __maybe_unused gic_read_iar(void)
+{
+	if (static_key_false(&is_cavium_thunderx))
+		return gic_read_iar_common();
+	else
+		return gic_read_iar_cavium_thunderx();
+}
+
 static void __maybe_unused gic_write_pmr(u64 val)
 {
 	asm volatile("msr_s " __stringify(ICC_PMR_EL1) ", %0" : : "r" (val));
@@ -766,8 +798,23 @@ static const struct irq_domain_ops gic_irq_domain_ops = {
 	.free = gic_irq_domain_free,
 };
 
+static void gicv3_enable_cavium_thunderx(void *data)
+{
+	static_key_slow_inc(&is_cavium_thunderx);
+}
+
 static const struct gic_capabilities gicv3_errata[] = {
 	{
+		/*
+		 * Need to be applied in guests too, thus use cpu
+		 * detection as iidr is emulated with different vendor
+		 * id.
+		 */
+		.desc		= "GIC: Cavium erratum 23154",
+		.cpu_cap	= ARM64_WORKAROUND_CAVIUM_23154,
+		.init		= gicv3_enable_cavium_thunderx,
+	},
+	{
 	}
 };
 
-- 
2.1.1



From rric at kernel.org  Fri Aug 14 06:18:38 2015
From: rric at kernel.org (Robert Richter)
Date: Fri, 14 Aug 2015 15:18:38 +0200
Subject: [PATCH v3 4/6] irqchip,
 gicv3-its: Read typer register outside the loop
In-Reply-To: <1439558320-5777-1-git-send-email-rric@kernel.org>
References: <1439558320-5777-1-git-send-email-rric@kernel.org>
Message-ID: <1439558320-5777-5-git-send-email-rric@kernel.org>

From: Robert Richter <rrichter at cavium.com>

No need to read the typer register in the loop. Values do not change.

This patch is basically a prerequisite for a follow-on patch that adds
errata code for Cavium ThunderX. It moves the calculation of the
number of id entries to the beginning of the function close to other
setup values that are needed to allocate the its table. Now we have a
central location to modify the setup parameters and the errata code
can be implemented in a single block.

Acked-by: Marc Zyngier <marc.zyngier at arm.com>
Signed-off-by: Robert Richter <rrichter at cavium.com>
---
 drivers/irqchip/irq-gic-v3-its.c | 5 ++---
 1 file changed, 2 insertions(+), 3 deletions(-)

diff --git a/drivers/irqchip/irq-gic-v3-its.c b/drivers/irqchip/irq-gic-v3-its.c
index 105674037618..bf0659821683 100644
--- a/drivers/irqchip/irq-gic-v3-its.c
+++ b/drivers/irqchip/irq-gic-v3-its.c
@@ -804,6 +804,8 @@ static int its_alloc_tables(struct its_node *its)
 	int psz = SZ_64K;
 	u64 shr = GITS_BASER_InnerShareable;
 	u64 cache = GITS_BASER_WaWb;
+	u64 typer = readq_relaxed(its->base + GITS_TYPER);
+	u32 ids = GITS_TYPER_DEVBITS(typer);
 
 	for (i = 0; i < GITS_BASER_NR_REGS; i++) {
 		u64 val = readq_relaxed(its->base + GITS_BASER + i * 8);
@@ -827,9 +829,6 @@ static int its_alloc_tables(struct its_node *its)
 		 * For other tables, only allocate a single page.
 		 */
 		if (type == GITS_BASER_TYPE_DEVICE) {
-			u64 typer = readq_relaxed(its->base + GITS_TYPER);
-			u32 ids = GITS_TYPER_DEVBITS(typer);
-
 			/*
 			 * 'order' was initialized earlier to the default page
 			 * granule of the the ITS.  We can't have an allocation
-- 
2.1.1



From rric at kernel.org  Fri Aug 14 06:18:40 2015
From: rric at kernel.org (Robert Richter)
Date: Fri, 14 Aug 2015 15:18:40 +0200
Subject: [PATCH v3 6/6] arm64: errata: Match all cpus if capability value is
 zero
In-Reply-To: <1439558320-5777-1-git-send-email-rric@kernel.org>
References: <1439558320-5777-1-git-send-email-rric@kernel.org>
Message-ID: <1439558320-5777-7-git-send-email-rric@kernel.org>

From: Robert Richter <rrichter at cavium.com>

This patch make caps usable optionally. If its value is zero, then all
cpus are matched. E.g. if caps resides in a stuct for marking it
dependend on a certain cpu feature/errata, then an empty value will
indicate not to use caps detection. An empty value will match all cpus
and thus just skip the cpu feature test.

Signed-off-by: Robert Richter <rrichter at cavium.com>
---
 arch/arm64/include/asm/cpufeature.h | 17 +++++++++++------
 drivers/irqchip/irq-gic-common.c    |  2 +-
 2 files changed, 12 insertions(+), 7 deletions(-)

diff --git a/arch/arm64/include/asm/cpufeature.h b/arch/arm64/include/asm/cpufeature.h
index 2a5e4c163ee5..a5f8a007d982 100644
--- a/arch/arm64/include/asm/cpufeature.h
+++ b/arch/arm64/include/asm/cpufeature.h
@@ -21,13 +21,15 @@
 #define MAX_CPU_FEATURES	(8 * sizeof(elf_hwcap))
 #define cpu_feature(x)		ilog2(HWCAP_ ## x)
 
-#define ARM64_WORKAROUND_CLEAN_CACHE		0
-#define ARM64_WORKAROUND_DEVICE_LOAD_ACQUIRE	1
-#define ARM64_WORKAROUND_845719			2
-#define ARM64_HAS_SYSREG_GIC_CPUIF		3
-#define ARM64_WORKAROUND_CAVIUM_23154		4
+/* reserve zero to match all cpus for use of caps in empty structs */
+#define ARM64_ALL_CPUS				0
+#define ARM64_WORKAROUND_CLEAN_CACHE		1
+#define ARM64_WORKAROUND_DEVICE_LOAD_ACQUIRE	2
+#define ARM64_WORKAROUND_845719			3
+#define ARM64_HAS_SYSREG_GIC_CPUIF		4
+#define ARM64_WORKAROUND_CAVIUM_23154		5
 
-#define ARM64_NCAPS				5
+#define ARM64_NCAPS				6
 
 #ifndef __ASSEMBLY__
 
@@ -57,6 +59,9 @@ static inline bool cpu_have_feature(unsigned int num)
 
 static inline bool cpus_have_cap(unsigned int num)
 {
+	/* zero matches for all cpus */
+	if (!num)
+		return true;
 	if (num >= ARM64_NCAPS)
 		return false;
 	return test_bit(num, cpu_hwcaps);
diff --git a/drivers/irqchip/irq-gic-common.c b/drivers/irqchip/irq-gic-common.c
index f5e901a62ea5..cb55aaf960bb 100644
--- a/drivers/irqchip/irq-gic-common.c
+++ b/drivers/irqchip/irq-gic-common.c
@@ -25,7 +25,7 @@ void gic_check_capabilities(u32 iidr, const struct gic_capabilities *cap,
 			void *data)
 {
 	for (; cap->desc; cap++) {
-		if (cap->cpu_cap && !cpus_have_cap(cap->cpu_cap))
+		if (!cpus_have_cap(cap->cpu_cap))
 			continue;
 		if (cap->iidr != (cap->mask & iidr))
 			continue;
-- 
2.1.1



From rric at kernel.org  Fri Aug 14 06:18:39 2015
From: rric at kernel.org (Robert Richter)
Date: Fri, 14 Aug 2015 15:18:39 +0200
Subject: [PATCH v3 5/6] irqchip,
 gicv3-its: Workaround for Cavium ThunderX errata 22375, 24313
In-Reply-To: <1439558320-5777-1-git-send-email-rric@kernel.org>
References: <1439558320-5777-1-git-send-email-rric@kernel.org>
Message-ID: <1439558320-5777-6-git-send-email-rric@kernel.org>

From: Robert Richter <rrichter at cavium.com>

This implements two gicv3-its errata workarounds for ThunderX. Both
with small impact affecting only ITS table allocation.

 erratum 22375: only alloc 8MB table size
 erratum 24313: ignore memory access type

The fixes are in ITS initialization and basically ignore memory access
type and table size provided by the TYPER and BASER registers.

v3:
 * fix erratum to be dependend from iidr

Signed-off-by: Robert Richter <rrichter at cavium.com>
---
 drivers/irqchip/irq-gic-v3-its.c | 35 +++++++++++++++++++++++++++++++----
 1 file changed, 31 insertions(+), 4 deletions(-)

diff --git a/drivers/irqchip/irq-gic-v3-its.c b/drivers/irqchip/irq-gic-v3-its.c
index bf0659821683..ab888eeef4b1 100644
--- a/drivers/irqchip/irq-gic-v3-its.c
+++ b/drivers/irqchip/irq-gic-v3-its.c
@@ -39,7 +39,8 @@
 #include "irq-gic-common.h"
 #include "irqchip.h"
 
-#define ITS_FLAGS_CMDQ_NEEDS_FLUSHING		(1 << 0)
+#define ITS_FLAGS_CMDQ_NEEDS_FLUSHING		(1ULL << 0)
+#define ITS_FLAGS_CAVIUM_THUNDERX		(1ULL << 1)
 
 #define RDIST_FLAGS_PROPBASE_NEEDS_FLUSHING	(1 << 0)
 
@@ -803,9 +804,22 @@ static int its_alloc_tables(struct its_node *its)
 	int i;
 	int psz = SZ_64K;
 	u64 shr = GITS_BASER_InnerShareable;
-	u64 cache = GITS_BASER_WaWb;
-	u64 typer = readq_relaxed(its->base + GITS_TYPER);
-	u32 ids = GITS_TYPER_DEVBITS(typer);
+	u64 cache;
+	u64 typer;
+	u32 ids;
+
+	if (its->flags & ITS_FLAGS_CAVIUM_THUNDERX) {
+		/*
+		 * erratum 22375: only alloc 8MB table size
+		 * erratum 24313: ignore memory access type
+		 */
+		cache	= 0;
+		ids	= 0x13;			/* 20 bits, 8MB */
+	} else {
+		cache	= GITS_BASER_WaWb;
+		typer	= readq_relaxed(its->base + GITS_TYPER);
+		ids	= GITS_TYPER_DEVBITS(typer);
+	}
 
 	for (i = 0; i < GITS_BASER_NR_REGS; i++) {
 		u64 val = readq_relaxed(its->base + GITS_BASER + i * 8);
@@ -1391,8 +1405,21 @@ static int its_force_quiescent(void __iomem *base)
 	}
 }
 
+static void its_enable_cavium_thunderx(void *data)
+{
+	struct its_node *its = data;
+
+	its->flags |= ITS_FLAGS_CAVIUM_THUNDERX;
+}
+
 static const struct gic_capabilities its_errata[] = {
 	{
+		.desc	= "ITS: Cavium errata 22375, 24313",
+		.iidr	= 0xa100034c,	/* ThunderX pass 1.x */
+		.mask	= 0xffff0fff,
+		.init	= its_enable_cavium_thunderx,
+	},
+	{
 	}
 };
 
-- 
2.1.1



From catalin.marinas at arm.com  Fri Aug 14 06:24:29 2015
From: catalin.marinas at arm.com (Catalin Marinas)
Date: Fri, 14 Aug 2015 14:24:29 +0100
Subject: [RFC] arm64: defconfig: enable 48-bit VA by default
In-Reply-To: <CAKv+Gu9gvrBwZry+pwXqsso9qg2vZcrYA8wgogRaRPhd6rsJuw@mail.gmail.com>
References: <BY2PR0301MB074300C5F31701D9211827F0878C0@BY2PR0301MB0743.namprd03.prod.outlook.com>
 <20150730101358.GA30796@e104818-lin.cambridge.arm.com>
 <CY1PR0301MB074850E27D5D298D1B8495D2878B0@CY1PR0301MB0748.namprd03.prod.outlook.com>
 <20150730161210.GE407@e104818-lin.cambridge.arm.com>
 <CY1PR0301MB0748FA3A10AFA9BFC1AB0A39878B0@CY1PR0301MB0748.namprd03.prod.outlook.com>
 <CAKv+Gu-Wbv3J9-2KbXrz_3W_=VXChrD+REo1-q1Ns_=RUM1BFw@mail.gmail.com>
 <BY2PR0301MB07436AC9C8D023DC7C67DE3D87730@BY2PR0301MB0743.namprd03.prod.outlook.com>
 <CAKv+Gu-SH7MjkrgevfcUurPc7iQm+11cntfEo84opkqQoN2YPQ@mail.gmail.com>
 <CY1PR0301MB07488764C02CCA3F653ED6A5877D0@CY1PR0301MB0748.namprd03.prod.outlook.com>
 <CAKv+Gu9gvrBwZry+pwXqsso9qg2vZcrYA8wgogRaRPhd6rsJuw@mail.gmail.com>
Message-ID: <20150814132428.GE16368@e104818-lin.cambridge.arm.com>

On Fri, Aug 14, 2015 at 02:15:23PM +0200, Ard Biesheuvel wrote:
> >> On 7 aug. 2015, at 21:01, Stuart Yoder <stuart.yoder at freescale.com> wrote:
> >>
> >> >> Whether defconfig supports your platform optimally has nothing to do
> >> >> with that. Of course, we should deal with the unexpected memory layout
> >> >> gracefully, which is why Mark Rutland and myself proposed patches to
> >> >> fix the panic you reported. But in a development context, I think it
> >> >> is perfectly acceptable to simply load the kernel at 0x80_8000_0000,
> >> >> and be able to run defconfig fine while losing just 2 GB of your 16 GB
> >> >> at the low end.
[...]
> So we still need to decide how to fix the case where the linear region
> is not of sufficient size to cover all of memory, considering that is
> what got this discussion started in the first place.

We already have a solution, just enable 4-levels of page tables (only
that I don't think we should change defconfig as well).

If we want to do any tricks like compacting the memory range, it needs
to be backed by benchmarks to prove that it's worth compared to a full
48-bit VA.

-- 
Catalin


From wens at csie.org  Fri Aug 14 06:33:11 2015
From: wens at csie.org (Chen-Yu Tsai)
Date: Fri, 14 Aug 2015 21:33:11 +0800
Subject: CLK_IGNORE_UNUSE looks buggy
In-Reply-To: <CAGsJ_4wxVL9sFWkc9dnZsAA++MfFJ1KXoq481wPLoQ-HaDRFEA@mail.gmail.com>
References: <CAGsJ_4wxVL9sFWkc9dnZsAA++MfFJ1KXoq481wPLoQ-HaDRFEA@mail.gmail.com>
Message-ID: <CAGb2v661-dzXHpa4Vt7fPXONRgPvWuOmBixUKg=wRj6Se5--VQ@mail.gmail.com>

On Fri, Aug 14, 2015 at 4:43 PM, Barry Song <21cnbao at gmail.com> wrote:
> hi Stephen, Michael,
>
> currently we can set a CLK_IGNORE_UNUSE flag to  a clock to stop
> clk_disable_unused()  from disabling it at the boot stage:
>
> static void clk_disable_unused_subtree(struct clk_core *core)
> {
> ...
> if (core->flags & CLK_IGNORE_UNUSED)
> goto unlock_out;
>
> ...
> }
>
> static int clk_disable_unused(void)
> {
> ...
> clk_unprepare_unused_subtree(core);
> ...
>
> return 0;
> }
> late_initcall_sync(clk_disable_unused);
>
> so if there are two clocks A and B, A is the parent of B, and A is
> marked as CLK_IGNORE_UNUSED.
>
> in boot stage if there is nobody using A and B, Linux will disable B
> due to clk_disable_unused() , but keep A being enabled since A has
> CLK_IGNORE_UNUSED.
>
> but in Linux runtime, we might frequently disable /enable B in runtime
> power management, this will cause A disabled since Linux will not
> check CLK_IGNORE_UNUSED for runtime disabling clk .
>
> so this makes CLK_IGNORE_UNUSE only work if we don't disable its
> sub-clock at runtime. this looks making no sense.
>
> i am thinking whether we should do some changes to make it have side
> affect for runtime clk disable. otherwise, why do we want to stop it
> from being disabled during boot stage?
>
> I am not sure whether i missed something in clk core level support.

CLK_IGNORE_UNUSED is not really a safe or proper mechanism to
protect critical clocks from being disabled. Quite a few people
have noticed this.

People are using their own "critical clocks" implementations.
Sunxi uses a list of clocks the clock driver is supposed to get
and enable. Newer clock providers directly enable the clock
after registering it.

Both Lee Jones [1] and Mike [2] have posted patches to move the
critical clock preservation mechanism into the clock core.

[1] https://lkml.org/lkml/2015/7/22/311
[2] http://www.spinics.net/lists/kernel/msg2052297.html


ChenYu


From p.fedin at samsung.com  Fri Aug 14 06:44:24 2015
From: p.fedin at samsung.com (Pavel Fedin)
Date: Fri, 14 Aug 2015 16:44:24 +0300
Subject: [PATCH v4 1/3] PCI: generic: remove dependency on hw_pci
In-Reply-To: <20150812090449.GA22485@arm.com>
References: <1438721620-15493-1-git-send-email-jchandra@broadcom.com>
 <20150804234956.GF17327@google.com>
 <007501d0d4ce$1d2dd9c0$57898d40$@samsung.com> <20150812090449.GA22485@arm.com>
Message-ID: <019001d0d697$55a5cf40$00f16dc0$@samsung.com>

 Hello!

> >  I also added MSI support. Can i post it as patch on top of your branch?
> 
> There shouldn't be any need with the changes queued in tip/irq/core. Can
> you give the following branch a go, please (it doesn't look like Bjorn's
> stuff is in linux-next, unfortunately)?
> 
>   git://git.kernel.org/pub/scm/linux/kernel/git/arm64/linux.git devel

 I have checked, they already implemented generic handling for "msi-parent" property in the device
tree, and MSI works out of the box.

Kind regards,
Pavel Fedin
Expert Engineer
Samsung Electronics Research center Russia




From ard.biesheuvel at linaro.org  Fri Aug 14 06:55:19 2015
From: ard.biesheuvel at linaro.org (Ard Biesheuvel)
Date: Fri, 14 Aug 2015 15:55:19 +0200
Subject: [RFC] arm64: defconfig: enable 48-bit VA by default
In-Reply-To: <20150814132428.GE16368@e104818-lin.cambridge.arm.com>
References: <BY2PR0301MB074300C5F31701D9211827F0878C0@BY2PR0301MB0743.namprd03.prod.outlook.com>
 <20150730101358.GA30796@e104818-lin.cambridge.arm.com>
 <CY1PR0301MB074850E27D5D298D1B8495D2878B0@CY1PR0301MB0748.namprd03.prod.outlook.com>
 <20150730161210.GE407@e104818-lin.cambridge.arm.com>
 <CY1PR0301MB0748FA3A10AFA9BFC1AB0A39878B0@CY1PR0301MB0748.namprd03.prod.outlook.com>
 <CAKv+Gu-Wbv3J9-2KbXrz_3W_=VXChrD+REo1-q1Ns_=RUM1BFw@mail.gmail.com>
 <BY2PR0301MB07436AC9C8D023DC7C67DE3D87730@BY2PR0301MB0743.namprd03.prod.outlook.com>
 <CAKv+Gu-SH7MjkrgevfcUurPc7iQm+11cntfEo84opkqQoN2YPQ@mail.gmail.com>
 <CY1PR0301MB07488764C02CCA3F653ED6A5877D0@CY1PR0301MB0748.namprd03.prod.outlook.com>
 <CAKv+Gu9gvrBwZry+pwXqsso9qg2vZcrYA8wgogRaRPhd6rsJuw@mail.gmail.com>
 <20150814132428.GE16368@e104818-lin.cambridge.arm.com>
Message-ID: <CAKv+Gu_4d+cSE_ynsBmk4KmdiEKCT9hv_HWgU0+6e+1ra8OT7Q@mail.gmail.com>

On 14 August 2015 at 15:24, Catalin Marinas <catalin.marinas at arm.com> wrote:
> On Fri, Aug 14, 2015 at 02:15:23PM +0200, Ard Biesheuvel wrote:
>> >> On 7 aug. 2015, at 21:01, Stuart Yoder <stuart.yoder at freescale.com> wrote:
>> >>
>> >> >> Whether defconfig supports your platform optimally has nothing to do
>> >> >> with that. Of course, we should deal with the unexpected memory layout
>> >> >> gracefully, which is why Mark Rutland and myself proposed patches to
>> >> >> fix the panic you reported. But in a development context, I think it
>> >> >> is perfectly acceptable to simply load the kernel at 0x80_8000_0000,
>> >> >> and be able to run defconfig fine while losing just 2 GB of your 16 GB
>> >> >> at the low end.
> [...]
>> So we still need to decide how to fix the case where the linear region
>> is not of sufficient size to cover all of memory, considering that is
>> what got this discussion started in the first place.
>
> We already have a solution, just enable 4-levels of page tables (only
> that I don't think we should change defconfig as well).
>
> If we want to do any tricks like compacting the memory range, it needs
> to be backed by benchmarks to prove that it's worth compared to a full
> 48-bit VA.
>

If you run a 39-bit VA kernel on a system whose DRAM configuration
covers a larger area than what the linear mapping can support, you
currently get a panic since phys_to_virt() overflows into the user
range. So at the very least, we need to clip the range to a size the
kernel can manage.


From rmk+kernel at arm.linux.org.uk  Fri Aug 14 06:54:13 2015
From: rmk+kernel at arm.linux.org.uk (Russell King)
Date: Fri, 14 Aug 2015 14:54:13 +0100
Subject: [PATCH v2 1/9] drm: bridge/dw_hdmi-ahb-audio: add audio driver
 David Airlie <airlied@linux.ie>, Sascha Hauer <s.hauer@pengutronix.de>,
 linux-kernel@vger.kernel.org, dri-devel@lists.freedesktop.org, Jaroslav
 Kysela <perex@perex.cz>, linux-rockchip@lists.infradead.org, Mark Brown
 <broonie@kernel.org>, Philipp Zabel <p.zabel@pengutronix.de>, Yakir
 Yang <ykk@rock-chips.com>, Andy Yan <andy.yan@rock-chips.com>, Jon
 Nettleton <jon.nettleton@gmail.com>,
 linux-arm-kernel@lists.infradead.org
In-Reply-To: <s5hk2t35ui4.wl-tiwai@suse.de>
References: <s5hk2t35ui4.wl-tiwai@suse.de>
Message-ID: <E1ZQFQz-0002yp-Dx@rmk-PC.arm.linux.org.uk>

Add ALSA based HDMI AHB audio driver for dw_hdmi.  The only buffer
format supported by the hardware is its own special IEC958 based format,
which is not compatible with any ALSA format.  To avoid doing too much
data manipulation within the driver, we support only ALSAs IEC958 LE and
24-bit PCM formats for 2 to 6 channels, which we convert to its hardware
format.

A more desirable solution would be to have this conversion in userspace,
but ALSA does not appear to allow such transformations outside of
libasound itself.

Signed-off-by: Russell King <rmk+kernel at arm.linux.org.uk>
---
v2: updated with Takashi Iwai's comments.

 drivers/gpu/drm/bridge/Kconfig             |  10 +
 drivers/gpu/drm/bridge/Makefile            |   1 +
 drivers/gpu/drm/bridge/dw_hdmi-ahb-audio.c | 579 +++++++++++++++++++++++++++++
 drivers/gpu/drm/bridge/dw_hdmi-audio.h     |  13 +
 drivers/gpu/drm/bridge/dw_hdmi.c           |  24 ++
 drivers/gpu/drm/bridge/dw_hdmi.h           |   3 +
 6 files changed, 630 insertions(+)
 create mode 100644 drivers/gpu/drm/bridge/dw_hdmi-ahb-audio.c
 create mode 100644 drivers/gpu/drm/bridge/dw_hdmi-audio.h

diff --git a/drivers/gpu/drm/bridge/Kconfig b/drivers/gpu/drm/bridge/Kconfig
index acef3223772c..56ed35fe0734 100644
--- a/drivers/gpu/drm/bridge/Kconfig
+++ b/drivers/gpu/drm/bridge/Kconfig
@@ -3,6 +3,16 @@ config DRM_DW_HDMI
 	depends on DRM
 	select DRM_KMS_HELPER
 
+config DRM_DW_HDMI_AHB_AUDIO
+	tristate "Synopsis Designware AHB Audio interface"
+	depends on DRM_DW_HDMI && SND
+	select SND_PCM
+	select SND_PCM_IEC958
+	help
+	  Support the AHB Audio interface which is part of the Synopsis
+	  Designware HDMI block.  This is used in conjunction with
+	  the i.MX6 HDMI driver.
+
 config DRM_PTN3460
 	tristate "PTN3460 DP/LVDS bridge"
 	depends on DRM
diff --git a/drivers/gpu/drm/bridge/Makefile b/drivers/gpu/drm/bridge/Makefile
index 8dfebd984370..eb80dbbb8365 100644
--- a/drivers/gpu/drm/bridge/Makefile
+++ b/drivers/gpu/drm/bridge/Makefile
@@ -3,3 +3,4 @@ ccflags-y := -Iinclude/drm
 obj-$(CONFIG_DRM_PS8622) += ps8622.o
 obj-$(CONFIG_DRM_PTN3460) += ptn3460.o
 obj-$(CONFIG_DRM_DW_HDMI) += dw_hdmi.o
+obj-$(CONFIG_DRM_DW_HDMI_AHB_AUDIO) += dw_hdmi-ahb-audio.o
diff --git a/drivers/gpu/drm/bridge/dw_hdmi-ahb-audio.c b/drivers/gpu/drm/bridge/dw_hdmi-ahb-audio.c
new file mode 100644
index 000000000000..bf379310008a
--- /dev/null
+++ b/drivers/gpu/drm/bridge/dw_hdmi-ahb-audio.c
@@ -0,0 +1,579 @@
+/*
+ * DesignWare HDMI audio driver
+ *
+ * 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.
+ *
+ * Written and tested against the Designware HDMI Tx found in iMX6.
+ */
+#include <linux/io.h>
+#include <linux/interrupt.h>
+#include <linux/module.h>
+#include <linux/platform_device.h>
+#include <drm/bridge/dw_hdmi.h>
+
+#include <sound/asoundef.h>
+#include <sound/core.h>
+#include <sound/initval.h>
+#include <sound/pcm.h>
+#include <sound/pcm_iec958.h>
+
+#include "dw_hdmi-audio.h"
+
+#define DRIVER_NAME "dw-hdmi-ahb-audio"
+
+/* Provide some bits rather than bit offsets */
+enum {
+	HDMI_AHB_DMA_CONF0_SW_FIFO_RST = BIT(7),
+	HDMI_AHB_DMA_CONF0_EN_HLOCK = BIT(3),
+	HDMI_AHB_DMA_START_START = BIT(0),
+	HDMI_AHB_DMA_STOP_STOP = BIT(0),
+	HDMI_IH_MUTE_AHBDMAAUD_STAT0_ERROR = BIT(5),
+	HDMI_IH_MUTE_AHBDMAAUD_STAT0_LOST = BIT(4),
+	HDMI_IH_MUTE_AHBDMAAUD_STAT0_RETRY = BIT(3),
+	HDMI_IH_MUTE_AHBDMAAUD_STAT0_DONE = BIT(2),
+	HDMI_IH_MUTE_AHBDMAAUD_STAT0_BUFFFULL = BIT(1),
+	HDMI_IH_MUTE_AHBDMAAUD_STAT0_BUFFEMPTY = BIT(0),
+	HDMI_IH_MUTE_AHBDMAAUD_STAT0_ALL =
+		HDMI_IH_MUTE_AHBDMAAUD_STAT0_ERROR |
+		HDMI_IH_MUTE_AHBDMAAUD_STAT0_LOST |
+		HDMI_IH_MUTE_AHBDMAAUD_STAT0_RETRY |
+		HDMI_IH_MUTE_AHBDMAAUD_STAT0_DONE |
+		HDMI_IH_MUTE_AHBDMAAUD_STAT0_BUFFFULL |
+		HDMI_IH_MUTE_AHBDMAAUD_STAT0_BUFFEMPTY,
+	HDMI_IH_AHBDMAAUD_STAT0_ERROR = BIT(5),
+	HDMI_IH_AHBDMAAUD_STAT0_LOST = BIT(4),
+	HDMI_IH_AHBDMAAUD_STAT0_RETRY = BIT(3),
+	HDMI_IH_AHBDMAAUD_STAT0_DONE = BIT(2),
+	HDMI_IH_AHBDMAAUD_STAT0_BUFFFULL = BIT(1),
+	HDMI_IH_AHBDMAAUD_STAT0_BUFFEMPTY = BIT(0),
+	HDMI_IH_AHBDMAAUD_STAT0_ALL =
+		HDMI_IH_AHBDMAAUD_STAT0_ERROR |
+		HDMI_IH_AHBDMAAUD_STAT0_LOST |
+		HDMI_IH_AHBDMAAUD_STAT0_RETRY |
+		HDMI_IH_AHBDMAAUD_STAT0_DONE |
+		HDMI_IH_AHBDMAAUD_STAT0_BUFFFULL |
+		HDMI_IH_AHBDMAAUD_STAT0_BUFFEMPTY,
+	HDMI_AHB_DMA_CONF0_INCR16 = 2 << 1,
+	HDMI_AHB_DMA_CONF0_INCR8 = 1 << 1,
+	HDMI_AHB_DMA_CONF0_INCR4 = 0,
+	HDMI_AHB_DMA_CONF0_BURST_MODE = BIT(0),
+	HDMI_AHB_DMA_MASK_DONE = BIT(7),
+	HDMI_REVISION_ID = 0x0001,
+	HDMI_IH_AHBDMAAUD_STAT0 = 0x0109,
+	HDMI_IH_MUTE_AHBDMAAUD_STAT0 = 0x0189,
+	HDMI_AHB_DMA_CONF0 = 0x3600,
+	HDMI_AHB_DMA_START = 0x3601,
+	HDMI_AHB_DMA_STOP = 0x3602,
+	HDMI_AHB_DMA_THRSLD = 0x3603,
+	HDMI_AHB_DMA_STRADDR0 = 0x3604,
+	HDMI_AHB_DMA_STPADDR0 = 0x3608,
+	HDMI_AHB_DMA_MASK = 0x3614,
+	HDMI_AHB_DMA_POL = 0x3615,
+	HDMI_AHB_DMA_CONF1 = 0x3616,
+	HDMI_AHB_DMA_BUFFPOL = 0x361a,
+};
+
+struct snd_dw_hdmi {
+	struct snd_card *card;
+	struct snd_pcm *pcm;
+	spinlock_t lock;
+	struct dw_hdmi_audio_data data;
+	struct snd_pcm_substream *substream;
+	void (*reformat)(struct snd_dw_hdmi *, size_t, size_t);
+	void *buf_src;
+	void *buf_dst;
+	dma_addr_t buf_addr;
+	unsigned buf_offset;
+	unsigned buf_period;
+	unsigned buf_size;
+	unsigned channels;
+	u8 revision;
+	u8 iec_offset;
+	u8 cs[192][8];
+};
+
+static void dw_hdmi_writel(u32 val, void __iomem *ptr)
+{
+	writeb_relaxed(val, ptr);
+	writeb_relaxed(val >> 8, ptr + 1);
+	writeb_relaxed(val >> 16, ptr + 2);
+	writeb_relaxed(val >> 24, ptr + 3);
+}
+
+/*
+ * Convert to hardware format: The userspace buffer contains IEC958 samples,
+ * with the PCUV bits in bits 31..28 and audio samples in bits 27..4.  We
+ * need these to be in bits 27..24, with the IEC B bit in bit 28, and audio
+ * samples in 23..0.
+ *
+ * Default preamble in bits 3..0: 8 = block start, 4 = even 2 = odd
+ *
+ * Ideally, we could do with having the data properly formatted in userspace.
+ */
+static void dw_hdmi_reformat_iec958(struct snd_dw_hdmi *dw,
+	size_t offset, size_t bytes)
+{
+	u32 *src = dw->buf_src + offset;
+	u32 *dst = dw->buf_dst + offset;
+	u32 *end = dw->buf_src + offset + bytes;
+
+	do {
+		u32 b, sample = *src++;
+
+		b = (sample & 8) << (28 - 3);
+
+		sample >>= 4;
+
+		*dst++ = sample | b;
+	} while (src < end);
+}
+
+static u32 parity(u32 sample)
+{
+	sample ^= sample >> 16;
+	sample ^= sample >> 8;
+	sample ^= sample >> 4;
+	sample ^= sample >> 2;
+	sample ^= sample >> 1;
+	return (sample & 1) << 27;
+}
+
+static void dw_hdmi_reformat_s24(struct snd_dw_hdmi *dw,
+	size_t offset, size_t bytes)
+{
+	u32 *src = dw->buf_src + offset;
+	u32 *dst = dw->buf_dst + offset;
+	u32 *end = dw->buf_src + offset + bytes;
+
+	do {
+		unsigned i;
+		u8 *cs;
+
+		cs = dw->cs[dw->iec_offset++];
+		if (dw->iec_offset >= 192)
+			dw->iec_offset = 0;
+
+		i = dw->channels;
+		do {
+			u32 sample = *src++;
+
+			sample &= ~0xff000000;
+			sample |= *cs++ << 24;
+			sample |= parity(sample & ~0xf8000000);
+
+			*dst++ = sample;
+		} while (--i);
+	} while (src < end);
+}
+
+static void dw_hdmi_create_cs(struct snd_dw_hdmi *dw,
+	struct snd_pcm_runtime *runtime)
+{
+	u8 cs[4];
+	unsigned ch, i, j;
+
+	snd_pcm_create_iec958_consumer(runtime, cs, sizeof(cs));
+
+	memset(dw->cs, 0, sizeof(dw->cs));
+
+	for (ch = 0; ch < 8; ch++) {
+		cs[2] &= ~IEC958_AES2_CON_CHANNEL;
+		cs[2] |= (ch + 1) << 4;
+
+		for (i = 0; i < ARRAY_SIZE(cs); i++) {
+			unsigned c = cs[i];
+
+			for (j = 0; j < 8; j++, c >>= 1)
+				dw->cs[i * 8 + j][ch] = (c & 1) << 2;
+		}
+	}
+	dw->cs[0][0] |= BIT(4);
+}
+
+static void dw_hdmi_start_dma(struct snd_dw_hdmi *dw)
+{
+	void __iomem *base = dw->data.base;
+	unsigned offset = dw->buf_offset;
+	unsigned period = dw->buf_period;
+	u32 start, stop;
+
+	dw->reformat(dw, offset, period);
+
+	/* Clear all irqs before enabling irqs and starting DMA */
+	writeb_relaxed(HDMI_IH_AHBDMAAUD_STAT0_ALL,
+		       base + HDMI_IH_AHBDMAAUD_STAT0);
+
+	start = dw->buf_addr + offset;
+	stop = start + period - 1;
+
+	/* Setup the hardware start/stop addresses */
+	dw_hdmi_writel(start, base + HDMI_AHB_DMA_STRADDR0);
+	dw_hdmi_writel(stop, base + HDMI_AHB_DMA_STPADDR0);
+
+	writeb_relaxed((u8)~HDMI_AHB_DMA_MASK_DONE, base + HDMI_AHB_DMA_MASK);
+	writeb(HDMI_AHB_DMA_START_START, base + HDMI_AHB_DMA_START);
+
+	offset += period;
+	if (offset >= dw->buf_size)
+		offset = 0;
+	dw->buf_offset = offset;
+}
+
+static void dw_hdmi_stop_dma(struct snd_dw_hdmi *dw)
+{
+	/* Disable interrupts before disabling DMA */
+	writeb_relaxed(~0, dw->data.base + HDMI_AHB_DMA_MASK);
+	writeb_relaxed(HDMI_AHB_DMA_STOP_STOP, dw->data.base + HDMI_AHB_DMA_STOP);
+}
+
+static irqreturn_t snd_dw_hdmi_irq(int irq, void *data)
+{
+	struct snd_dw_hdmi *dw = data;
+	struct snd_pcm_substream *substream;
+	unsigned stat;
+
+	stat = readb_relaxed(dw->data.base + HDMI_IH_AHBDMAAUD_STAT0);
+	if (!stat)
+		return IRQ_NONE;
+
+	writeb_relaxed(stat, dw->data.base + HDMI_IH_AHBDMAAUD_STAT0);
+
+	substream = dw->substream;
+	if (stat & HDMI_IH_AHBDMAAUD_STAT0_DONE && substream) {
+		snd_pcm_period_elapsed(substream);
+
+		spin_lock(&dw->lock);
+		if (dw->substream)
+			dw_hdmi_start_dma(dw);
+		spin_unlock(&dw->lock);
+	}
+
+	return IRQ_HANDLED;
+}
+
+static struct snd_pcm_hardware dw_hdmi_hw = {
+	.info = SNDRV_PCM_INFO_INTERLEAVED |
+		SNDRV_PCM_INFO_BLOCK_TRANSFER |
+		SNDRV_PCM_INFO_MMAP |
+		SNDRV_PCM_INFO_MMAP_VALID,
+	.formats = SNDRV_PCM_FMTBIT_IEC958_SUBFRAME_LE |
+		   SNDRV_PCM_FMTBIT_S24_LE,
+	.rates = SNDRV_PCM_RATE_32000 |
+		 SNDRV_PCM_RATE_44100 |
+		 SNDRV_PCM_RATE_48000 |
+		 SNDRV_PCM_RATE_88200 |
+		 SNDRV_PCM_RATE_96000 |
+		 SNDRV_PCM_RATE_176400 |
+		 SNDRV_PCM_RATE_192000,
+	.channels_min = 2,
+	.channels_max = 8,
+	.buffer_bytes_max = 64 * 1024,
+	.period_bytes_min = 256,
+	.period_bytes_max = 8192,	/* ERR004323: must limit to 8k */
+	.periods_min = 2,
+	.periods_max = 16,
+	.fifo_size = 0,
+};
+
+static int dw_hdmi_open(struct snd_pcm_substream *substream)
+{
+	struct snd_pcm_runtime *runtime = substream->runtime;
+	struct snd_dw_hdmi *dw = substream->private_data;
+	void __iomem *base = dw->data.base;
+	int ret;
+
+	runtime->hw = dw_hdmi_hw;
+
+	ret = snd_pcm_limit_hw_rates(runtime);
+	if (ret < 0)
+		return ret;
+
+	ret = snd_pcm_hw_constraint_integer(runtime, SNDRV_PCM_HW_PARAM_PERIODS);
+	if (ret < 0)
+		return ret;
+
+	/* Clear FIFO */
+	writeb_relaxed(HDMI_AHB_DMA_CONF0_SW_FIFO_RST,
+		       base + HDMI_AHB_DMA_CONF0);
+
+	/* Configure interrupt polarities */
+	writeb_relaxed(~0, base + HDMI_AHB_DMA_POL);
+	writeb_relaxed(~0, base + HDMI_AHB_DMA_BUFFPOL);
+
+	/* Keep interrupts masked, and clear any pending */
+	writeb_relaxed(~0, base + HDMI_AHB_DMA_MASK);
+	writeb_relaxed(~0, base + HDMI_IH_AHBDMAAUD_STAT0);
+
+	ret = request_irq(dw->data.irq, snd_dw_hdmi_irq, IRQF_SHARED,
+			  "dw-hdmi-audio", dw);
+	if (ret)
+		return ret;
+
+	/* Un-mute done interrupt */
+	writeb_relaxed(HDMI_IH_MUTE_AHBDMAAUD_STAT0_ALL &
+		       ~HDMI_IH_MUTE_AHBDMAAUD_STAT0_DONE,
+		       base + HDMI_IH_MUTE_AHBDMAAUD_STAT0);
+
+	return 0;
+}
+
+static int dw_hdmi_close(struct snd_pcm_substream *substream)
+{
+	struct snd_dw_hdmi *dw = substream->private_data;
+
+	/* Mute all interrupts */
+	writeb_relaxed(HDMI_IH_MUTE_AHBDMAAUD_STAT0_ALL,
+		       dw->data.base + HDMI_IH_MUTE_AHBDMAAUD_STAT0);
+
+	free_irq(dw->data.irq, dw);
+
+	return 0;
+}
+
+static int dw_hdmi_hw_free(struct snd_pcm_substream *substream)
+{
+	return snd_pcm_lib_free_vmalloc_buffer(substream);
+}
+
+static int dw_hdmi_hw_params(struct snd_pcm_substream *substream,
+	struct snd_pcm_hw_params *params)
+{
+	return snd_pcm_lib_alloc_vmalloc_buffer(substream,
+						params_buffer_bytes(params));
+}
+
+static int dw_hdmi_prepare(struct snd_pcm_substream *substream)
+{
+	struct snd_pcm_runtime *runtime = substream->runtime;
+	struct snd_dw_hdmi *dw = substream->private_data;
+	u8 threshold, conf0, conf1;
+
+	/* Setup as per 3.0.5 FSL 4.1.0 BSP */
+	switch (dw->revision) {
+	case 0x0a:
+		conf0 = HDMI_AHB_DMA_CONF0_BURST_MODE |
+			HDMI_AHB_DMA_CONF0_INCR4;
+		if (runtime->channels == 2)
+			threshold = 126;
+		else
+			threshold = 124;
+		break;
+	case 0x1a:
+		conf0 = HDMI_AHB_DMA_CONF0_BURST_MODE |
+			HDMI_AHB_DMA_CONF0_INCR8;
+		threshold = 128;
+		break;
+	default:
+		/* NOTREACHED */
+		return -EINVAL;
+	}
+
+	dw_hdmi_set_sample_rate(dw->data.hdmi, runtime->rate);
+
+	/* Minimum number of bytes in the fifo. */
+	runtime->hw.fifo_size = threshold * 32;
+
+	conf0 |= HDMI_AHB_DMA_CONF0_EN_HLOCK;
+	conf1 = (1 << runtime->channels) - 1;
+
+	writeb_relaxed(threshold, dw->data.base + HDMI_AHB_DMA_THRSLD);
+	writeb_relaxed(conf0, dw->data.base + HDMI_AHB_DMA_CONF0);
+	writeb_relaxed(conf1, dw->data.base + HDMI_AHB_DMA_CONF1);
+
+	switch (runtime->format) {
+	case SNDRV_PCM_FORMAT_IEC958_SUBFRAME_LE:
+		dw->reformat = dw_hdmi_reformat_iec958;
+		break;
+	case SNDRV_PCM_FORMAT_S24_LE:
+		dw_hdmi_create_cs(dw, runtime);
+		dw->reformat = dw_hdmi_reformat_s24;
+		break;
+	}
+	dw->iec_offset = 0;
+	dw->channels = runtime->channels;
+	dw->buf_src  = runtime->dma_area;
+	dw->buf_dst  = substream->dma_buffer.area;
+	dw->buf_addr = substream->dma_buffer.addr;
+	dw->buf_period = snd_pcm_lib_period_bytes(substream);
+	dw->buf_size = snd_pcm_lib_buffer_bytes(substream);
+
+	return 0;
+}
+
+static int dw_hdmi_trigger(struct snd_pcm_substream *substream, int cmd)
+{
+	struct snd_dw_hdmi *dw = substream->private_data;
+	unsigned long flags;
+	int ret = 0;
+
+	switch (cmd) {
+	case SNDRV_PCM_TRIGGER_START:
+		spin_lock_irqsave(&dw->lock, flags);
+		dw->buf_offset = 0;
+		dw->substream = substream;
+		dw_hdmi_start_dma(dw);
+		dw_hdmi_audio_enable(dw->data.hdmi);
+		spin_unlock_irqrestore(&dw->lock, flags);
+		substream->runtime->delay = substream->runtime->period_size;
+		break;
+
+	case SNDRV_PCM_TRIGGER_STOP:
+		spin_lock_irqsave(&dw->lock, flags);
+		dw->substream = NULL;
+		dw_hdmi_stop_dma(dw);
+		dw_hdmi_audio_disable(dw->data.hdmi);
+		spin_unlock_irqrestore(&dw->lock, flags);
+		break;
+
+	default:
+		ret = -EINVAL;
+		break;
+	}
+
+	return ret;
+}
+
+static snd_pcm_uframes_t dw_hdmi_pointer(struct snd_pcm_substream *substream)
+{
+	struct snd_pcm_runtime *runtime = substream->runtime;
+	struct snd_dw_hdmi *dw = substream->private_data;
+
+	/*
+	 * We are unable to report the exact hardware position as
+	 * reading the 32-bit DMA position using 8-bit reads is racy.
+	 */
+	return bytes_to_frames(runtime, dw->buf_offset);
+}
+
+static struct snd_pcm_ops snd_dw_hdmi_ops = {
+	.open = dw_hdmi_open,
+	.close = dw_hdmi_close,
+	.ioctl = snd_pcm_lib_ioctl,
+	.hw_params = dw_hdmi_hw_params,
+	.hw_free = dw_hdmi_hw_free,
+	.prepare = dw_hdmi_prepare,
+	.trigger = dw_hdmi_trigger,
+	.pointer = dw_hdmi_pointer,
+	.page = snd_pcm_lib_get_vmalloc_page,
+};
+
+static int snd_dw_hdmi_probe(struct platform_device *pdev)
+{
+	const struct dw_hdmi_audio_data *data = pdev->dev.platform_data;
+	struct device *dev = pdev->dev.parent;
+	struct snd_dw_hdmi *dw;
+	struct snd_card *card;
+	struct snd_pcm *pcm;
+	unsigned revision;
+	int ret;
+
+	writeb_relaxed(HDMI_IH_MUTE_AHBDMAAUD_STAT0_ALL,
+		       data->base + HDMI_IH_MUTE_AHBDMAAUD_STAT0);
+	revision = readb_relaxed(data->base + HDMI_REVISION_ID);
+	if (revision != 0x0a && revision != 0x1a) {
+		dev_err(dev, "dw-hdmi-audio: unknown revision 0x%02x\n",
+			revision);
+		return -ENXIO;
+	}
+
+	ret = snd_card_new(dev, SNDRV_DEFAULT_IDX1, SNDRV_DEFAULT_STR1,
+			      THIS_MODULE, sizeof(struct snd_dw_hdmi), &card);
+	if (ret < 0)
+		return ret;
+
+	strlcpy(card->driver, DRIVER_NAME, sizeof(card->driver));
+	strlcpy(card->shortname, "DW-HDMI", sizeof(card->shortname));
+	snprintf(card->longname, sizeof(card->longname),
+		 "%s rev 0x%02x, irq %d", card->shortname, revision,
+		 data->irq);
+
+	dw = card->private_data;
+	dw->card = card;
+	dw->data = *data;
+	dw->revision = revision;
+
+	spin_lock_init(&dw->lock);
+
+	ret = snd_pcm_new(card, "DW HDMI", 0, 1, 0, &pcm);
+	if (ret < 0)
+		goto err;
+
+	dw->pcm = pcm;
+	pcm->private_data = dw;
+	strlcpy(pcm->name, DRIVER_NAME, sizeof(pcm->name));
+	snd_pcm_set_ops(pcm, SNDRV_PCM_STREAM_PLAYBACK, &snd_dw_hdmi_ops);
+
+	snd_pcm_lib_preallocate_pages_for_all(pcm, SNDRV_DMA_TYPE_DEV,
+			dev, 64 * 1024, 64 * 1024);
+
+	ret = snd_card_register(card);
+	if (ret < 0)
+		goto err;
+
+	platform_set_drvdata(pdev, dw);
+
+	return 0;
+
+err:
+	snd_card_free(card);
+	return ret;
+}
+
+static int snd_dw_hdmi_remove(struct platform_device *pdev)
+{
+	struct snd_dw_hdmi *dw = platform_get_drvdata(pdev);
+
+	snd_card_free(dw->card);
+
+	return 0;
+}
+
+#if defined(CONFIG_PM_SLEEP) && defined(IS_NOT_BROKEN)
+/*
+ * This code is fine, but requires implementation in the dw_hdmi_trigger()
+ * method which is currently missing as I have no way to test this.
+ */
+static int snd_dw_hdmi_suspend(struct device *dev)
+{
+	struct snd_dw_hdmi *dw = dev_get_drvdata(dev);
+
+	snd_power_change_state(dw->card, SNDRV_CTL_POWER_D3cold);
+	snd_pcm_suspend_all(dw->pcm);
+
+	return 0;
+}
+
+static int snd_dw_hdmi_resume(struct device *dev)
+{
+	struct snd_dw_hdmi *dw = dev_get_drvdata(dev);
+
+	snd_power_change_state(dw->card, SNDRV_CTL_POWER_D0);
+
+	return 0;
+}
+
+static SIMPLE_DEV_PM_OPS(snd_dw_hdmi_pm, snd_dw_hdmi_suspend,
+			 snd_dw_hdmi_resume);
+#define PM_OPS &snd_dw_hdmi_pm
+#else
+#define PM_OPS NULL
+#endif
+
+static struct platform_driver snd_dw_hdmi_driver = {
+	.probe	= snd_dw_hdmi_probe,
+	.remove	= snd_dw_hdmi_remove,
+	.driver	= {
+		.name = DRIVER_NAME,
+		.owner = THIS_MODULE,
+		.pm = PM_OPS,
+	},
+};
+
+module_platform_driver(snd_dw_hdmi_driver);
+
+MODULE_AUTHOR("Russell King <rmk+kernel at arm.linux.org.uk>");
+MODULE_DESCRIPTION("Synopsis Designware HDMI AHB ALSA interface");
+MODULE_LICENSE("GPL v2");
+MODULE_ALIAS("platform:" DRIVER_NAME);
diff --git a/drivers/gpu/drm/bridge/dw_hdmi-audio.h b/drivers/gpu/drm/bridge/dw_hdmi-audio.h
new file mode 100644
index 000000000000..1e840118d90a
--- /dev/null
+++ b/drivers/gpu/drm/bridge/dw_hdmi-audio.h
@@ -0,0 +1,13 @@
+#ifndef DW_HDMI_AUDIO_H
+#define DW_HDMI_AUDIO_H
+
+struct dw_hdmi;
+
+struct dw_hdmi_audio_data {
+	phys_addr_t phys;
+	void __iomem *base;
+	int irq;
+	struct dw_hdmi *hdmi;
+};
+
+#endif
diff --git a/drivers/gpu/drm/bridge/dw_hdmi.c b/drivers/gpu/drm/bridge/dw_hdmi.c
index fba25607ef88..b65464789fbd 100644
--- a/drivers/gpu/drm/bridge/dw_hdmi.c
+++ b/drivers/gpu/drm/bridge/dw_hdmi.c
@@ -28,6 +28,7 @@
 #include <drm/bridge/dw_hdmi.h>
 
 #include "dw_hdmi.h"
+#include "dw_hdmi-audio.h"
 
 #define HDMI_EDID_LEN		512
 
@@ -104,6 +105,7 @@ struct dw_hdmi {
 	struct drm_encoder *encoder;
 	struct drm_bridge *bridge;
 
+	struct platform_device *audio;
 	enum dw_hdmi_devtype dev_type;
 	struct device *dev;
 	struct clk *isfr_clk;
@@ -1732,7 +1734,9 @@ int dw_hdmi_bind(struct device *dev, struct device *master,
 {
 	struct drm_device *drm = data;
 	struct device_node *np = dev->of_node;
+	struct platform_device_info pdevinfo;
 	struct device_node *ddc_node;
+	struct dw_hdmi_audio_data audio;
 	struct dw_hdmi *hdmi;
 	int ret;
 	u32 val = 1;
@@ -1860,6 +1864,23 @@ int dw_hdmi_bind(struct device *dev, struct device *master,
 	hdmi_writeb(hdmi, ~(HDMI_IH_PHY_STAT0_HPD | HDMI_IH_PHY_STAT0_RX_SENSE),
 		    HDMI_IH_MUTE_PHY_STAT0);
 
+	memset(&pdevinfo, 0, sizeof(pdevinfo));
+	pdevinfo.parent = dev;
+	pdevinfo.id = PLATFORM_DEVID_AUTO;
+
+	if (hdmi_readb(hdmi, HDMI_CONFIG1_ID) & HDMI_CONFIG1_AHB) {
+		audio.phys = iores->start;
+		audio.base = hdmi->regs;
+		audio.irq = irq;
+		audio.hdmi = hdmi;
+
+		pdevinfo.name = "dw-hdmi-ahb-audio";
+		pdevinfo.data = &audio;
+		pdevinfo.size_data = sizeof(audio);
+		pdevinfo.dma_mask = DMA_BIT_MASK(32);
+		hdmi->audio = platform_device_register_full(&pdevinfo);
+	}
+
 	dev_set_drvdata(dev, hdmi);
 
 	return 0;
@@ -1877,6 +1898,9 @@ void dw_hdmi_unbind(struct device *dev, struct device *master, void *data)
 {
 	struct dw_hdmi *hdmi = dev_get_drvdata(dev);
 
+	if (hdmi->audio && !IS_ERR(hdmi->audio))
+		platform_device_unregister(hdmi->audio);
+
 	/* Disable all interrupts */
 	hdmi_writeb(hdmi, ~0, HDMI_IH_MUTE_PHY_STAT0);
 
diff --git a/drivers/gpu/drm/bridge/dw_hdmi.h b/drivers/gpu/drm/bridge/dw_hdmi.h
index 175dbc89a824..78e54e813212 100644
--- a/drivers/gpu/drm/bridge/dw_hdmi.h
+++ b/drivers/gpu/drm/bridge/dw_hdmi.h
@@ -545,6 +545,9 @@
 #define HDMI_I2CM_FS_SCL_LCNT_0_ADDR            0x7E12
 
 enum {
+/* CONFIG1_ID field values */
+	HDMI_CONFIG1_AHB = 0x01,
+
 /* IH_FC_INT2 field values */
 	HDMI_IH_FC_INT2_OVERFLOW_MASK = 0x03,
 	HDMI_IH_FC_INT2_LOW_PRIORITY_OVERFLOW = 0x02,
-- 
2.1.0



From m-karicheri2 at ti.com  Fri Aug 14 07:04:41 2015
From: m-karicheri2 at ti.com (Murali Karicheri)
Date: Fri, 14 Aug 2015 10:04:41 -0400
Subject: [PATCH] ARM: keystone: add a work around to handle asynchronous
 external abort
In-Reply-To: <1439320409-20084-1-git-send-email-m-karicheri2@ti.com>
References: <1439320409-20084-1-git-send-email-m-karicheri2@ti.com>
Message-ID: <55CDF579.4050408@ti.com>

On 08/11/2015 03:13 PM, Murali Karicheri wrote:
> Currently on some devices, an asynchronous external abort exception
> happens during boot up when exception handlers are enabled in kernel
> before switching to user space. This patch adds a workaround to handle
> this once during boot. Many customers are already using this
> with out any issues and is required to workaround the above issue.
>
> Signed-off-by: Murali Karicheri <m-karicheri2 at ti.com>
> ---
>   arch/arm/mach-keystone/keystone.c | 26 ++++++++++++++++++++++++++
>   1 file changed, 26 insertions(+)
>
> diff --git a/arch/arm/mach-keystone/keystone.c b/arch/arm/mach-keystone/keystone.c
> index e2880105..c1d0fe5 100644
> --- a/arch/arm/mach-keystone/keystone.c
> +++ b/arch/arm/mach-keystone/keystone.c
> @@ -15,6 +15,7 @@
>   #include <linux/of_platform.h>
>   #include <linux/of_address.h>
>   #include <linux/memblock.h>
> +#include <linux/signal.h>
>
>   #include <asm/setup.h>
>   #include <asm/mach/map.h>
> @@ -52,6 +53,24 @@ static struct notifier_block platform_nb = {
>   	.notifier_call = keystone_platform_notifier,
>   };
>
> +static bool ignore_first = true;
> +static int keystone_async_ext_abort_fault(unsigned long addr, unsigned int fsr,
> +					  struct pt_regs *regs)
> +{
> +	/*
> +	 * if first time, ignore this as this is a asynchronous external abort
> +	 * happening only some devices that couldn't be root caused and we add
> +	 * this work around to handle this first time.
> +	 */
> +	if (ignore_first) {
> +		ignore_first = false;
> +		return 0;
> +	}
> +
> +	/* Subsequent ones should be handled as fault */
> +	return 1;
> +}
> +
>   static void __init keystone_init(void)
>   {
>   	if (PHYS_OFFSET >= KEYSTONE_HIGH_PHYS_START) {
> @@ -61,6 +80,13 @@ static void __init keystone_init(void)
>   	}
>   	keystone_pm_runtime_init();
>   	of_platform_populate(NULL, of_default_bus_match_table, NULL, NULL);
> +
> +	/*
> +	 * Add a one time exception handler to catch asynchronous external
> +	 * abort
> +	 */
> +	hook_fault_code(17, keystone_async_ext_abort_fault, SIGBUS, 0,
> +			"async external abort handler");
>   }
>
>   static phys_addr_t keystone_virt_to_idmap(unsigned long x)
>
Can this be applied if it looks good?

Murali

-- 
Murali Karicheri
Linux Kernel, Keystone


From rmk+kernel at arm.linux.org.uk  Fri Aug 14 07:04:25 2015
From: rmk+kernel at arm.linux.org.uk (Russell King)
Date: Fri, 14 Aug 2015 15:04:25 +0100
Subject: [PATCH v2 1/9] drm: bridge/dw_hdmi-ahb-audio: add audio driver
In-Reply-To: <s5hk2t35ui4.wl-tiwai@suse.de>
References: <s5hk2t35ui4.wl-tiwai@suse.de>
Message-ID: <E1ZQFar-0003cx-RU@rmk-PC.arm.linux.org.uk>

Add ALSA based HDMI AHB audio driver for dw_hdmi.  The only buffer
format supported by the hardware is its own special IEC958 based format,
which is not compatible with any ALSA format.  To avoid doing too much
data manipulation within the driver, we support only ALSAs IEC958 LE and
24-bit PCM formats for 2 to 6 channels, which we convert to its hardware
format.

A more desirable solution would be to have this conversion in userspace,
but ALSA does not appear to allow such transformations outside of
libasound itself.

Signed-off-by: Russell King <rmk+kernel at arm.linux.org.uk>
---
v2: updated with Takashi Iwai's comments... and with a fixed Cc: line.

 drivers/gpu/drm/bridge/Kconfig             |  10 +
 drivers/gpu/drm/bridge/Makefile            |   1 +
 drivers/gpu/drm/bridge/dw_hdmi-ahb-audio.c | 579 +++++++++++++++++++++++++++++
 drivers/gpu/drm/bridge/dw_hdmi-audio.h     |  13 +
 drivers/gpu/drm/bridge/dw_hdmi.c           |  24 ++
 drivers/gpu/drm/bridge/dw_hdmi.h           |   3 +
 6 files changed, 630 insertions(+)
 create mode 100644 drivers/gpu/drm/bridge/dw_hdmi-ahb-audio.c
 create mode 100644 drivers/gpu/drm/bridge/dw_hdmi-audio.h

diff --git a/drivers/gpu/drm/bridge/Kconfig b/drivers/gpu/drm/bridge/Kconfig
index acef3223772c..56ed35fe0734 100644
--- a/drivers/gpu/drm/bridge/Kconfig
+++ b/drivers/gpu/drm/bridge/Kconfig
@@ -3,6 +3,16 @@ config DRM_DW_HDMI
 	depends on DRM
 	select DRM_KMS_HELPER
 
+config DRM_DW_HDMI_AHB_AUDIO
+	tristate "Synopsis Designware AHB Audio interface"
+	depends on DRM_DW_HDMI && SND
+	select SND_PCM
+	select SND_PCM_IEC958
+	help
+	  Support the AHB Audio interface which is part of the Synopsis
+	  Designware HDMI block.  This is used in conjunction with
+	  the i.MX6 HDMI driver.
+
 config DRM_PTN3460
 	tristate "PTN3460 DP/LVDS bridge"
 	depends on DRM
diff --git a/drivers/gpu/drm/bridge/Makefile b/drivers/gpu/drm/bridge/Makefile
index 8dfebd984370..eb80dbbb8365 100644
--- a/drivers/gpu/drm/bridge/Makefile
+++ b/drivers/gpu/drm/bridge/Makefile
@@ -3,3 +3,4 @@ ccflags-y := -Iinclude/drm
 obj-$(CONFIG_DRM_PS8622) += ps8622.o
 obj-$(CONFIG_DRM_PTN3460) += ptn3460.o
 obj-$(CONFIG_DRM_DW_HDMI) += dw_hdmi.o
+obj-$(CONFIG_DRM_DW_HDMI_AHB_AUDIO) += dw_hdmi-ahb-audio.o
diff --git a/drivers/gpu/drm/bridge/dw_hdmi-ahb-audio.c b/drivers/gpu/drm/bridge/dw_hdmi-ahb-audio.c
new file mode 100644
index 000000000000..bf379310008a
--- /dev/null
+++ b/drivers/gpu/drm/bridge/dw_hdmi-ahb-audio.c
@@ -0,0 +1,579 @@
+/*
+ * DesignWare HDMI audio driver
+ *
+ * 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.
+ *
+ * Written and tested against the Designware HDMI Tx found in iMX6.
+ */
+#include <linux/io.h>
+#include <linux/interrupt.h>
+#include <linux/module.h>
+#include <linux/platform_device.h>
+#include <drm/bridge/dw_hdmi.h>
+
+#include <sound/asoundef.h>
+#include <sound/core.h>
+#include <sound/initval.h>
+#include <sound/pcm.h>
+#include <sound/pcm_iec958.h>
+
+#include "dw_hdmi-audio.h"
+
+#define DRIVER_NAME "dw-hdmi-ahb-audio"
+
+/* Provide some bits rather than bit offsets */
+enum {
+	HDMI_AHB_DMA_CONF0_SW_FIFO_RST = BIT(7),
+	HDMI_AHB_DMA_CONF0_EN_HLOCK = BIT(3),
+	HDMI_AHB_DMA_START_START = BIT(0),
+	HDMI_AHB_DMA_STOP_STOP = BIT(0),
+	HDMI_IH_MUTE_AHBDMAAUD_STAT0_ERROR = BIT(5),
+	HDMI_IH_MUTE_AHBDMAAUD_STAT0_LOST = BIT(4),
+	HDMI_IH_MUTE_AHBDMAAUD_STAT0_RETRY = BIT(3),
+	HDMI_IH_MUTE_AHBDMAAUD_STAT0_DONE = BIT(2),
+	HDMI_IH_MUTE_AHBDMAAUD_STAT0_BUFFFULL = BIT(1),
+	HDMI_IH_MUTE_AHBDMAAUD_STAT0_BUFFEMPTY = BIT(0),
+	HDMI_IH_MUTE_AHBDMAAUD_STAT0_ALL =
+		HDMI_IH_MUTE_AHBDMAAUD_STAT0_ERROR |
+		HDMI_IH_MUTE_AHBDMAAUD_STAT0_LOST |
+		HDMI_IH_MUTE_AHBDMAAUD_STAT0_RETRY |
+		HDMI_IH_MUTE_AHBDMAAUD_STAT0_DONE |
+		HDMI_IH_MUTE_AHBDMAAUD_STAT0_BUFFFULL |
+		HDMI_IH_MUTE_AHBDMAAUD_STAT0_BUFFEMPTY,
+	HDMI_IH_AHBDMAAUD_STAT0_ERROR = BIT(5),
+	HDMI_IH_AHBDMAAUD_STAT0_LOST = BIT(4),
+	HDMI_IH_AHBDMAAUD_STAT0_RETRY = BIT(3),
+	HDMI_IH_AHBDMAAUD_STAT0_DONE = BIT(2),
+	HDMI_IH_AHBDMAAUD_STAT0_BUFFFULL = BIT(1),
+	HDMI_IH_AHBDMAAUD_STAT0_BUFFEMPTY = BIT(0),
+	HDMI_IH_AHBDMAAUD_STAT0_ALL =
+		HDMI_IH_AHBDMAAUD_STAT0_ERROR |
+		HDMI_IH_AHBDMAAUD_STAT0_LOST |
+		HDMI_IH_AHBDMAAUD_STAT0_RETRY |
+		HDMI_IH_AHBDMAAUD_STAT0_DONE |
+		HDMI_IH_AHBDMAAUD_STAT0_BUFFFULL |
+		HDMI_IH_AHBDMAAUD_STAT0_BUFFEMPTY,
+	HDMI_AHB_DMA_CONF0_INCR16 = 2 << 1,
+	HDMI_AHB_DMA_CONF0_INCR8 = 1 << 1,
+	HDMI_AHB_DMA_CONF0_INCR4 = 0,
+	HDMI_AHB_DMA_CONF0_BURST_MODE = BIT(0),
+	HDMI_AHB_DMA_MASK_DONE = BIT(7),
+	HDMI_REVISION_ID = 0x0001,
+	HDMI_IH_AHBDMAAUD_STAT0 = 0x0109,
+	HDMI_IH_MUTE_AHBDMAAUD_STAT0 = 0x0189,
+	HDMI_AHB_DMA_CONF0 = 0x3600,
+	HDMI_AHB_DMA_START = 0x3601,
+	HDMI_AHB_DMA_STOP = 0x3602,
+	HDMI_AHB_DMA_THRSLD = 0x3603,
+	HDMI_AHB_DMA_STRADDR0 = 0x3604,
+	HDMI_AHB_DMA_STPADDR0 = 0x3608,
+	HDMI_AHB_DMA_MASK = 0x3614,
+	HDMI_AHB_DMA_POL = 0x3615,
+	HDMI_AHB_DMA_CONF1 = 0x3616,
+	HDMI_AHB_DMA_BUFFPOL = 0x361a,
+};
+
+struct snd_dw_hdmi {
+	struct snd_card *card;
+	struct snd_pcm *pcm;
+	spinlock_t lock;
+	struct dw_hdmi_audio_data data;
+	struct snd_pcm_substream *substream;
+	void (*reformat)(struct snd_dw_hdmi *, size_t, size_t);
+	void *buf_src;
+	void *buf_dst;
+	dma_addr_t buf_addr;
+	unsigned buf_offset;
+	unsigned buf_period;
+	unsigned buf_size;
+	unsigned channels;
+	u8 revision;
+	u8 iec_offset;
+	u8 cs[192][8];
+};
+
+static void dw_hdmi_writel(u32 val, void __iomem *ptr)
+{
+	writeb_relaxed(val, ptr);
+	writeb_relaxed(val >> 8, ptr + 1);
+	writeb_relaxed(val >> 16, ptr + 2);
+	writeb_relaxed(val >> 24, ptr + 3);
+}
+
+/*
+ * Convert to hardware format: The userspace buffer contains IEC958 samples,
+ * with the PCUV bits in bits 31..28 and audio samples in bits 27..4.  We
+ * need these to be in bits 27..24, with the IEC B bit in bit 28, and audio
+ * samples in 23..0.
+ *
+ * Default preamble in bits 3..0: 8 = block start, 4 = even 2 = odd
+ *
+ * Ideally, we could do with having the data properly formatted in userspace.
+ */
+static void dw_hdmi_reformat_iec958(struct snd_dw_hdmi *dw,
+	size_t offset, size_t bytes)
+{
+	u32 *src = dw->buf_src + offset;
+	u32 *dst = dw->buf_dst + offset;
+	u32 *end = dw->buf_src + offset + bytes;
+
+	do {
+		u32 b, sample = *src++;
+
+		b = (sample & 8) << (28 - 3);
+
+		sample >>= 4;
+
+		*dst++ = sample | b;
+	} while (src < end);
+}
+
+static u32 parity(u32 sample)
+{
+	sample ^= sample >> 16;
+	sample ^= sample >> 8;
+	sample ^= sample >> 4;
+	sample ^= sample >> 2;
+	sample ^= sample >> 1;
+	return (sample & 1) << 27;
+}
+
+static void dw_hdmi_reformat_s24(struct snd_dw_hdmi *dw,
+	size_t offset, size_t bytes)
+{
+	u32 *src = dw->buf_src + offset;
+	u32 *dst = dw->buf_dst + offset;
+	u32 *end = dw->buf_src + offset + bytes;
+
+	do {
+		unsigned i;
+		u8 *cs;
+
+		cs = dw->cs[dw->iec_offset++];
+		if (dw->iec_offset >= 192)
+			dw->iec_offset = 0;
+
+		i = dw->channels;
+		do {
+			u32 sample = *src++;
+
+			sample &= ~0xff000000;
+			sample |= *cs++ << 24;
+			sample |= parity(sample & ~0xf8000000);
+
+			*dst++ = sample;
+		} while (--i);
+	} while (src < end);
+}
+
+static void dw_hdmi_create_cs(struct snd_dw_hdmi *dw,
+	struct snd_pcm_runtime *runtime)
+{
+	u8 cs[4];
+	unsigned ch, i, j;
+
+	snd_pcm_create_iec958_consumer(runtime, cs, sizeof(cs));
+
+	memset(dw->cs, 0, sizeof(dw->cs));
+
+	for (ch = 0; ch < 8; ch++) {
+		cs[2] &= ~IEC958_AES2_CON_CHANNEL;
+		cs[2] |= (ch + 1) << 4;
+
+		for (i = 0; i < ARRAY_SIZE(cs); i++) {
+			unsigned c = cs[i];
+
+			for (j = 0; j < 8; j++, c >>= 1)
+				dw->cs[i * 8 + j][ch] = (c & 1) << 2;
+		}
+	}
+	dw->cs[0][0] |= BIT(4);
+}
+
+static void dw_hdmi_start_dma(struct snd_dw_hdmi *dw)
+{
+	void __iomem *base = dw->data.base;
+	unsigned offset = dw->buf_offset;
+	unsigned period = dw->buf_period;
+	u32 start, stop;
+
+	dw->reformat(dw, offset, period);
+
+	/* Clear all irqs before enabling irqs and starting DMA */
+	writeb_relaxed(HDMI_IH_AHBDMAAUD_STAT0_ALL,
+		       base + HDMI_IH_AHBDMAAUD_STAT0);
+
+	start = dw->buf_addr + offset;
+	stop = start + period - 1;
+
+	/* Setup the hardware start/stop addresses */
+	dw_hdmi_writel(start, base + HDMI_AHB_DMA_STRADDR0);
+	dw_hdmi_writel(stop, base + HDMI_AHB_DMA_STPADDR0);
+
+	writeb_relaxed((u8)~HDMI_AHB_DMA_MASK_DONE, base + HDMI_AHB_DMA_MASK);
+	writeb(HDMI_AHB_DMA_START_START, base + HDMI_AHB_DMA_START);
+
+	offset += period;
+	if (offset >= dw->buf_size)
+		offset = 0;
+	dw->buf_offset = offset;
+}
+
+static void dw_hdmi_stop_dma(struct snd_dw_hdmi *dw)
+{
+	/* Disable interrupts before disabling DMA */
+	writeb_relaxed(~0, dw->data.base + HDMI_AHB_DMA_MASK);
+	writeb_relaxed(HDMI_AHB_DMA_STOP_STOP, dw->data.base + HDMI_AHB_DMA_STOP);
+}
+
+static irqreturn_t snd_dw_hdmi_irq(int irq, void *data)
+{
+	struct snd_dw_hdmi *dw = data;
+	struct snd_pcm_substream *substream;
+	unsigned stat;
+
+	stat = readb_relaxed(dw->data.base + HDMI_IH_AHBDMAAUD_STAT0);
+	if (!stat)
+		return IRQ_NONE;
+
+	writeb_relaxed(stat, dw->data.base + HDMI_IH_AHBDMAAUD_STAT0);
+
+	substream = dw->substream;
+	if (stat & HDMI_IH_AHBDMAAUD_STAT0_DONE && substream) {
+		snd_pcm_period_elapsed(substream);
+
+		spin_lock(&dw->lock);
+		if (dw->substream)
+			dw_hdmi_start_dma(dw);
+		spin_unlock(&dw->lock);
+	}
+
+	return IRQ_HANDLED;
+}
+
+static struct snd_pcm_hardware dw_hdmi_hw = {
+	.info = SNDRV_PCM_INFO_INTERLEAVED |
+		SNDRV_PCM_INFO_BLOCK_TRANSFER |
+		SNDRV_PCM_INFO_MMAP |
+		SNDRV_PCM_INFO_MMAP_VALID,
+	.formats = SNDRV_PCM_FMTBIT_IEC958_SUBFRAME_LE |
+		   SNDRV_PCM_FMTBIT_S24_LE,
+	.rates = SNDRV_PCM_RATE_32000 |
+		 SNDRV_PCM_RATE_44100 |
+		 SNDRV_PCM_RATE_48000 |
+		 SNDRV_PCM_RATE_88200 |
+		 SNDRV_PCM_RATE_96000 |
+		 SNDRV_PCM_RATE_176400 |
+		 SNDRV_PCM_RATE_192000,
+	.channels_min = 2,
+	.channels_max = 8,
+	.buffer_bytes_max = 64 * 1024,
+	.period_bytes_min = 256,
+	.period_bytes_max = 8192,	/* ERR004323: must limit to 8k */
+	.periods_min = 2,
+	.periods_max = 16,
+	.fifo_size = 0,
+};
+
+static int dw_hdmi_open(struct snd_pcm_substream *substream)
+{
+	struct snd_pcm_runtime *runtime = substream->runtime;
+	struct snd_dw_hdmi *dw = substream->private_data;
+	void __iomem *base = dw->data.base;
+	int ret;
+
+	runtime->hw = dw_hdmi_hw;
+
+	ret = snd_pcm_limit_hw_rates(runtime);
+	if (ret < 0)
+		return ret;
+
+	ret = snd_pcm_hw_constraint_integer(runtime, SNDRV_PCM_HW_PARAM_PERIODS);
+	if (ret < 0)
+		return ret;
+
+	/* Clear FIFO */
+	writeb_relaxed(HDMI_AHB_DMA_CONF0_SW_FIFO_RST,
+		       base + HDMI_AHB_DMA_CONF0);
+
+	/* Configure interrupt polarities */
+	writeb_relaxed(~0, base + HDMI_AHB_DMA_POL);
+	writeb_relaxed(~0, base + HDMI_AHB_DMA_BUFFPOL);
+
+	/* Keep interrupts masked, and clear any pending */
+	writeb_relaxed(~0, base + HDMI_AHB_DMA_MASK);
+	writeb_relaxed(~0, base + HDMI_IH_AHBDMAAUD_STAT0);
+
+	ret = request_irq(dw->data.irq, snd_dw_hdmi_irq, IRQF_SHARED,
+			  "dw-hdmi-audio", dw);
+	if (ret)
+		return ret;
+
+	/* Un-mute done interrupt */
+	writeb_relaxed(HDMI_IH_MUTE_AHBDMAAUD_STAT0_ALL &
+		       ~HDMI_IH_MUTE_AHBDMAAUD_STAT0_DONE,
+		       base + HDMI_IH_MUTE_AHBDMAAUD_STAT0);
+
+	return 0;
+}
+
+static int dw_hdmi_close(struct snd_pcm_substream *substream)
+{
+	struct snd_dw_hdmi *dw = substream->private_data;
+
+	/* Mute all interrupts */
+	writeb_relaxed(HDMI_IH_MUTE_AHBDMAAUD_STAT0_ALL,
+		       dw->data.base + HDMI_IH_MUTE_AHBDMAAUD_STAT0);
+
+	free_irq(dw->data.irq, dw);
+
+	return 0;
+}
+
+static int dw_hdmi_hw_free(struct snd_pcm_substream *substream)
+{
+	return snd_pcm_lib_free_vmalloc_buffer(substream);
+}
+
+static int dw_hdmi_hw_params(struct snd_pcm_substream *substream,
+	struct snd_pcm_hw_params *params)
+{
+	return snd_pcm_lib_alloc_vmalloc_buffer(substream,
+						params_buffer_bytes(params));
+}
+
+static int dw_hdmi_prepare(struct snd_pcm_substream *substream)
+{
+	struct snd_pcm_runtime *runtime = substream->runtime;
+	struct snd_dw_hdmi *dw = substream->private_data;
+	u8 threshold, conf0, conf1;
+
+	/* Setup as per 3.0.5 FSL 4.1.0 BSP */
+	switch (dw->revision) {
+	case 0x0a:
+		conf0 = HDMI_AHB_DMA_CONF0_BURST_MODE |
+			HDMI_AHB_DMA_CONF0_INCR4;
+		if (runtime->channels == 2)
+			threshold = 126;
+		else
+			threshold = 124;
+		break;
+	case 0x1a:
+		conf0 = HDMI_AHB_DMA_CONF0_BURST_MODE |
+			HDMI_AHB_DMA_CONF0_INCR8;
+		threshold = 128;
+		break;
+	default:
+		/* NOTREACHED */
+		return -EINVAL;
+	}
+
+	dw_hdmi_set_sample_rate(dw->data.hdmi, runtime->rate);
+
+	/* Minimum number of bytes in the fifo. */
+	runtime->hw.fifo_size = threshold * 32;
+
+	conf0 |= HDMI_AHB_DMA_CONF0_EN_HLOCK;
+	conf1 = (1 << runtime->channels) - 1;
+
+	writeb_relaxed(threshold, dw->data.base + HDMI_AHB_DMA_THRSLD);
+	writeb_relaxed(conf0, dw->data.base + HDMI_AHB_DMA_CONF0);
+	writeb_relaxed(conf1, dw->data.base + HDMI_AHB_DMA_CONF1);
+
+	switch (runtime->format) {
+	case SNDRV_PCM_FORMAT_IEC958_SUBFRAME_LE:
+		dw->reformat = dw_hdmi_reformat_iec958;
+		break;
+	case SNDRV_PCM_FORMAT_S24_LE:
+		dw_hdmi_create_cs(dw, runtime);
+		dw->reformat = dw_hdmi_reformat_s24;
+		break;
+	}
+	dw->iec_offset = 0;
+	dw->channels = runtime->channels;
+	dw->buf_src  = runtime->dma_area;
+	dw->buf_dst  = substream->dma_buffer.area;
+	dw->buf_addr = substream->dma_buffer.addr;
+	dw->buf_period = snd_pcm_lib_period_bytes(substream);
+	dw->buf_size = snd_pcm_lib_buffer_bytes(substream);
+
+	return 0;
+}
+
+static int dw_hdmi_trigger(struct snd_pcm_substream *substream, int cmd)
+{
+	struct snd_dw_hdmi *dw = substream->private_data;
+	unsigned long flags;
+	int ret = 0;
+
+	switch (cmd) {
+	case SNDRV_PCM_TRIGGER_START:
+		spin_lock_irqsave(&dw->lock, flags);
+		dw->buf_offset = 0;
+		dw->substream = substream;
+		dw_hdmi_start_dma(dw);
+		dw_hdmi_audio_enable(dw->data.hdmi);
+		spin_unlock_irqrestore(&dw->lock, flags);
+		substream->runtime->delay = substream->runtime->period_size;
+		break;
+
+	case SNDRV_PCM_TRIGGER_STOP:
+		spin_lock_irqsave(&dw->lock, flags);
+		dw->substream = NULL;
+		dw_hdmi_stop_dma(dw);
+		dw_hdmi_audio_disable(dw->data.hdmi);
+		spin_unlock_irqrestore(&dw->lock, flags);
+		break;
+
+	default:
+		ret = -EINVAL;
+		break;
+	}
+
+	return ret;
+}
+
+static snd_pcm_uframes_t dw_hdmi_pointer(struct snd_pcm_substream *substream)
+{
+	struct snd_pcm_runtime *runtime = substream->runtime;
+	struct snd_dw_hdmi *dw = substream->private_data;
+
+	/*
+	 * We are unable to report the exact hardware position as
+	 * reading the 32-bit DMA position using 8-bit reads is racy.
+	 */
+	return bytes_to_frames(runtime, dw->buf_offset);
+}
+
+static struct snd_pcm_ops snd_dw_hdmi_ops = {
+	.open = dw_hdmi_open,
+	.close = dw_hdmi_close,
+	.ioctl = snd_pcm_lib_ioctl,
+	.hw_params = dw_hdmi_hw_params,
+	.hw_free = dw_hdmi_hw_free,
+	.prepare = dw_hdmi_prepare,
+	.trigger = dw_hdmi_trigger,
+	.pointer = dw_hdmi_pointer,
+	.page = snd_pcm_lib_get_vmalloc_page,
+};
+
+static int snd_dw_hdmi_probe(struct platform_device *pdev)
+{
+	const struct dw_hdmi_audio_data *data = pdev->dev.platform_data;
+	struct device *dev = pdev->dev.parent;
+	struct snd_dw_hdmi *dw;
+	struct snd_card *card;
+	struct snd_pcm *pcm;
+	unsigned revision;
+	int ret;
+
+	writeb_relaxed(HDMI_IH_MUTE_AHBDMAAUD_STAT0_ALL,
+		       data->base + HDMI_IH_MUTE_AHBDMAAUD_STAT0);
+	revision = readb_relaxed(data->base + HDMI_REVISION_ID);
+	if (revision != 0x0a && revision != 0x1a) {
+		dev_err(dev, "dw-hdmi-audio: unknown revision 0x%02x\n",
+			revision);
+		return -ENXIO;
+	}
+
+	ret = snd_card_new(dev, SNDRV_DEFAULT_IDX1, SNDRV_DEFAULT_STR1,
+			      THIS_MODULE, sizeof(struct snd_dw_hdmi), &card);
+	if (ret < 0)
+		return ret;
+
+	strlcpy(card->driver, DRIVER_NAME, sizeof(card->driver));
+	strlcpy(card->shortname, "DW-HDMI", sizeof(card->shortname));
+	snprintf(card->longname, sizeof(card->longname),
+		 "%s rev 0x%02x, irq %d", card->shortname, revision,
+		 data->irq);
+
+	dw = card->private_data;
+	dw->card = card;
+	dw->data = *data;
+	dw->revision = revision;
+
+	spin_lock_init(&dw->lock);
+
+	ret = snd_pcm_new(card, "DW HDMI", 0, 1, 0, &pcm);
+	if (ret < 0)
+		goto err;
+
+	dw->pcm = pcm;
+	pcm->private_data = dw;
+	strlcpy(pcm->name, DRIVER_NAME, sizeof(pcm->name));
+	snd_pcm_set_ops(pcm, SNDRV_PCM_STREAM_PLAYBACK, &snd_dw_hdmi_ops);
+
+	snd_pcm_lib_preallocate_pages_for_all(pcm, SNDRV_DMA_TYPE_DEV,
+			dev, 64 * 1024, 64 * 1024);
+
+	ret = snd_card_register(card);
+	if (ret < 0)
+		goto err;
+
+	platform_set_drvdata(pdev, dw);
+
+	return 0;
+
+err:
+	snd_card_free(card);
+	return ret;
+}
+
+static int snd_dw_hdmi_remove(struct platform_device *pdev)
+{
+	struct snd_dw_hdmi *dw = platform_get_drvdata(pdev);
+
+	snd_card_free(dw->card);
+
+	return 0;
+}
+
+#if defined(CONFIG_PM_SLEEP) && defined(IS_NOT_BROKEN)
+/*
+ * This code is fine, but requires implementation in the dw_hdmi_trigger()
+ * method which is currently missing as I have no way to test this.
+ */
+static int snd_dw_hdmi_suspend(struct device *dev)
+{
+	struct snd_dw_hdmi *dw = dev_get_drvdata(dev);
+
+	snd_power_change_state(dw->card, SNDRV_CTL_POWER_D3cold);
+	snd_pcm_suspend_all(dw->pcm);
+
+	return 0;
+}
+
+static int snd_dw_hdmi_resume(struct device *dev)
+{
+	struct snd_dw_hdmi *dw = dev_get_drvdata(dev);
+
+	snd_power_change_state(dw->card, SNDRV_CTL_POWER_D0);
+
+	return 0;
+}
+
+static SIMPLE_DEV_PM_OPS(snd_dw_hdmi_pm, snd_dw_hdmi_suspend,
+			 snd_dw_hdmi_resume);
+#define PM_OPS &snd_dw_hdmi_pm
+#else
+#define PM_OPS NULL
+#endif
+
+static struct platform_driver snd_dw_hdmi_driver = {
+	.probe	= snd_dw_hdmi_probe,
+	.remove	= snd_dw_hdmi_remove,
+	.driver	= {
+		.name = DRIVER_NAME,
+		.owner = THIS_MODULE,
+		.pm = PM_OPS,
+	},
+};
+
+module_platform_driver(snd_dw_hdmi_driver);
+
+MODULE_AUTHOR("Russell King <rmk+kernel at arm.linux.org.uk>");
+MODULE_DESCRIPTION("Synopsis Designware HDMI AHB ALSA interface");
+MODULE_LICENSE("GPL v2");
+MODULE_ALIAS("platform:" DRIVER_NAME);
diff --git a/drivers/gpu/drm/bridge/dw_hdmi-audio.h b/drivers/gpu/drm/bridge/dw_hdmi-audio.h
new file mode 100644
index 000000000000..1e840118d90a
--- /dev/null
+++ b/drivers/gpu/drm/bridge/dw_hdmi-audio.h
@@ -0,0 +1,13 @@
+#ifndef DW_HDMI_AUDIO_H
+#define DW_HDMI_AUDIO_H
+
+struct dw_hdmi;
+
+struct dw_hdmi_audio_data {
+	phys_addr_t phys;
+	void __iomem *base;
+	int irq;
+	struct dw_hdmi *hdmi;
+};
+
+#endif
diff --git a/drivers/gpu/drm/bridge/dw_hdmi.c b/drivers/gpu/drm/bridge/dw_hdmi.c
index fba25607ef88..b65464789fbd 100644
--- a/drivers/gpu/drm/bridge/dw_hdmi.c
+++ b/drivers/gpu/drm/bridge/dw_hdmi.c
@@ -28,6 +28,7 @@
 #include <drm/bridge/dw_hdmi.h>
 
 #include "dw_hdmi.h"
+#include "dw_hdmi-audio.h"
 
 #define HDMI_EDID_LEN		512
 
@@ -104,6 +105,7 @@ struct dw_hdmi {
 	struct drm_encoder *encoder;
 	struct drm_bridge *bridge;
 
+	struct platform_device *audio;
 	enum dw_hdmi_devtype dev_type;
 	struct device *dev;
 	struct clk *isfr_clk;
@@ -1732,7 +1734,9 @@ int dw_hdmi_bind(struct device *dev, struct device *master,
 {
 	struct drm_device *drm = data;
 	struct device_node *np = dev->of_node;
+	struct platform_device_info pdevinfo;
 	struct device_node *ddc_node;
+	struct dw_hdmi_audio_data audio;
 	struct dw_hdmi *hdmi;
 	int ret;
 	u32 val = 1;
@@ -1860,6 +1864,23 @@ int dw_hdmi_bind(struct device *dev, struct device *master,
 	hdmi_writeb(hdmi, ~(HDMI_IH_PHY_STAT0_HPD | HDMI_IH_PHY_STAT0_RX_SENSE),
 		    HDMI_IH_MUTE_PHY_STAT0);
 
+	memset(&pdevinfo, 0, sizeof(pdevinfo));
+	pdevinfo.parent = dev;
+	pdevinfo.id = PLATFORM_DEVID_AUTO;
+
+	if (hdmi_readb(hdmi, HDMI_CONFIG1_ID) & HDMI_CONFIG1_AHB) {
+		audio.phys = iores->start;
+		audio.base = hdmi->regs;
+		audio.irq = irq;
+		audio.hdmi = hdmi;
+
+		pdevinfo.name = "dw-hdmi-ahb-audio";
+		pdevinfo.data = &audio;
+		pdevinfo.size_data = sizeof(audio);
+		pdevinfo.dma_mask = DMA_BIT_MASK(32);
+		hdmi->audio = platform_device_register_full(&pdevinfo);
+	}
+
 	dev_set_drvdata(dev, hdmi);
 
 	return 0;
@@ -1877,6 +1898,9 @@ void dw_hdmi_unbind(struct device *dev, struct device *master, void *data)
 {
 	struct dw_hdmi *hdmi = dev_get_drvdata(dev);
 
+	if (hdmi->audio && !IS_ERR(hdmi->audio))
+		platform_device_unregister(hdmi->audio);
+
 	/* Disable all interrupts */
 	hdmi_writeb(hdmi, ~0, HDMI_IH_MUTE_PHY_STAT0);
 
diff --git a/drivers/gpu/drm/bridge/dw_hdmi.h b/drivers/gpu/drm/bridge/dw_hdmi.h
index 175dbc89a824..78e54e813212 100644
--- a/drivers/gpu/drm/bridge/dw_hdmi.h
+++ b/drivers/gpu/drm/bridge/dw_hdmi.h
@@ -545,6 +545,9 @@
 #define HDMI_I2CM_FS_SCL_LCNT_0_ADDR            0x7E12
 
 enum {
+/* CONFIG1_ID field values */
+	HDMI_CONFIG1_AHB = 0x01,
+
 /* IH_FC_INT2 field values */
 	HDMI_IH_FC_INT2_OVERFLOW_MASK = 0x03,
 	HDMI_IH_FC_INT2_LOW_PRIORITY_OVERFLOW = 0x02,
-- 
2.1.0



From dv at vollmann.ch  Fri Aug 14 07:05:55 2015
From: dv at vollmann.ch (Detlef Vollmann)
Date: Fri, 14 Aug 2015 16:05:55 +0200
Subject: commit a71b092 "ARM: Convert handle_IRQ to use __handle_domain_irq"
 breaks DNS-323
Message-ID: <55CDF5C3.7080204@vollmann.ch>

Hello,

this commit:
 > commit a71b092a9c68685a270ebdde7b5986ba8787e575
 > Author: Marc Zyngier <marc.zyngier at arm.com>
 > Date:   Tue Aug 26 11:03:18 2014 +0100
 >
 >     ARM: Convert handle_IRQ to use __handle_domain_irq
[...]
causes the kernel not to boot anymore on my DNS-323.
Soc: MV88F5182 Rev 2
CPU: ARM926 (Rev 0) running @ 500Mhz
CPU: Feroceon [41069260] revision 0 (ARMv5TEJ), cr=a005317f
Orion ID: MV88F5182-A2. TCLK=166666667.
DNS-323: Identified HW revision B1

Boot stops after "Uncompressing Linux... done, booting the kernel."
Reverting the commit works fine for me.
Tested 4.1.2 and 4.2.0-rc6 with orion5x_defconfig.

   Detlef


From marc.zyngier at arm.com  Fri Aug 14 07:08:19 2015
From: marc.zyngier at arm.com (Marc Zyngier)
Date: Fri, 14 Aug 2015 15:08:19 +0100
Subject: [PATCH v3 3/6] irqchip, gicv3: Workaround for Cavium ThunderX
 erratum 23154
In-Reply-To: <1439558320-5777-4-git-send-email-rric@kernel.org>
References: <1439558320-5777-1-git-send-email-rric@kernel.org>
 <1439558320-5777-4-git-send-email-rric@kernel.org>
Message-ID: <55CDF653.6090601@arm.com>

On 14/08/15 14:18, Robert Richter wrote:
> From: Robert Richter <rrichter at cavium.com>
> 
> This patch implements Cavium ThunderX erratum 23154.
> 
> The gicv3 of ThunderX requires a modified version for reading the IAR
> status to ensure data synchronization. Since this is in the fast-path
> and called with each interrupt, runtime patching is used using jump
> label patching for smallest overhead (no-op). This is the same
> technique as used for tracepoints.
> 
> v3:
>  * fix erratum to be dependend from midr
>  * use arm64 errata framework
> 
> v2:
>  * implement code in a single asm() to keep instruction sequence
>  * added comment to the code that explains the erratum
>  * apply workaround also if running as guest, thus check MIDR
> 
> Signed-off-by: Robert Richter <rrichter at cavium.com>
> ---
>  arch/arm64/Kconfig                  | 11 +++++++++
>  arch/arm64/include/asm/cpufeature.h |  3 ++-
>  arch/arm64/include/asm/cputype.h    | 18 ++++++++------
>  arch/arm64/kernel/cpu_errata.c      |  9 +++++++
>  drivers/irqchip/irq-gic-v3.c        | 49 ++++++++++++++++++++++++++++++++++++-
>  5 files changed, 81 insertions(+), 9 deletions(-)
> 
> diff --git a/arch/arm64/Kconfig b/arch/arm64/Kconfig
> index 0f6edb14b7e4..4f866a4c6536 100644
> --- a/arch/arm64/Kconfig
> +++ b/arch/arm64/Kconfig
> @@ -417,6 +417,17 @@ config ARM64_ERRATUM_845719
>  
>  	  If unsure, say Y.
>  
> +config CAVIUM_ERRATUM_23154
> +	bool "Cavium erratum 23154: Access to ICC_IAR1_EL1 is not sync'ed"
> +	depends on ARCH_THUNDER
> +	default y
> +	help
> +	  The gicv3 of ThunderX requires a modified version for
> +	  reading the IAR status to ensure data synchronization
> +	  (access to icc_iar1_el1 is not sync'ed before and after).
> +
> +	  If unsure, say Y.
> +
>  endmenu
>  
>  
> diff --git a/arch/arm64/include/asm/cpufeature.h b/arch/arm64/include/asm/cpufeature.h
> index c1044218a63a..2a5e4c163ee5 100644
> --- a/arch/arm64/include/asm/cpufeature.h
> +++ b/arch/arm64/include/asm/cpufeature.h
> @@ -25,8 +25,9 @@
>  #define ARM64_WORKAROUND_DEVICE_LOAD_ACQUIRE	1
>  #define ARM64_WORKAROUND_845719			2
>  #define ARM64_HAS_SYSREG_GIC_CPUIF		3
> +#define ARM64_WORKAROUND_CAVIUM_23154		4
>  
> -#define ARM64_NCAPS				4
> +#define ARM64_NCAPS				5
>  
>  #ifndef __ASSEMBLY__
>  
> diff --git a/arch/arm64/include/asm/cputype.h b/arch/arm64/include/asm/cputype.h
> index a84ec605bed8..3f0c7683f252 100644
> --- a/arch/arm64/include/asm/cputype.h
> +++ b/arch/arm64/include/asm/cputype.h
> @@ -62,15 +62,19 @@
>  	(0xf			<< MIDR_ARCHITECTURE_SHIFT) | \
>  	((partnum)		<< MIDR_PARTNUM_SHIFT))
>  
> -#define ARM_CPU_IMP_ARM		0x41
> -#define ARM_CPU_IMP_APM		0x50
> +#define ARM_CPU_IMP_ARM			0x41
> +#define ARM_CPU_IMP_APM			0x50
> +#define ARM_CPU_IMP_CAVIUM		0x43
>  
> -#define ARM_CPU_PART_AEM_V8	0xD0F
> -#define ARM_CPU_PART_FOUNDATION	0xD00
> -#define ARM_CPU_PART_CORTEX_A57	0xD07
> -#define ARM_CPU_PART_CORTEX_A53	0xD03
> +#define ARM_CPU_PART_AEM_V8		0xD0F
> +#define ARM_CPU_PART_FOUNDATION		0xD00
> +#define ARM_CPU_PART_CORTEX_A57		0xD07
> +#define ARM_CPU_PART_CORTEX_A53		0xD03
> +
> +#define APM_CPU_PART_POTENZA		0x000
> +
> +#define CAVIUM_CPU_PART_THUNDERX	0x0A1
>  
> -#define APM_CPU_PART_POTENZA	0x000
>  
>  #define ID_AA64MMFR0_BIGENDEL0_SHIFT	16
>  #define ID_AA64MMFR0_BIGENDEL0_MASK	(0xf << ID_AA64MMFR0_BIGENDEL0_SHIFT)
> diff --git a/arch/arm64/kernel/cpu_errata.c b/arch/arm64/kernel/cpu_errata.c
> index 6ffd91438560..574450c257a4 100644
> --- a/arch/arm64/kernel/cpu_errata.c
> +++ b/arch/arm64/kernel/cpu_errata.c
> @@ -23,6 +23,7 @@
>  
>  #define MIDR_CORTEX_A53 MIDR_CPU_PART(ARM_CPU_IMP_ARM, ARM_CPU_PART_CORTEX_A53)
>  #define MIDR_CORTEX_A57 MIDR_CPU_PART(ARM_CPU_IMP_ARM, ARM_CPU_PART_CORTEX_A57)
> +#define MIDR_THUNDERX	MIDR_CPU_PART(ARM_CPU_IMP_CAVIUM, CAVIUM_CPU_PART_THUNDERX)
>  
>  #define CPU_MODEL_MASK (MIDR_IMPLEMENTOR_MASK | MIDR_PARTNUM_MASK | \
>  			MIDR_ARCHITECTURE_MASK)
> @@ -82,6 +83,14 @@ const struct arm64_cpu_capabilities arm64_errata[] = {
>  		MIDR_RANGE(MIDR_CORTEX_A53, 0x00, 0x04),
>  	},
>  #endif
> +#ifdef CONFIG_CAVIUM_ERRATUM_23154
> +	{
> +	/* Cavium ThunderX, pass 1.x */
> +		.desc = "Cavium erratum 23154",
> +		.capability = ARM64_WORKAROUND_CAVIUM_23154,
> +		MIDR_RANGE(MIDR_THUNDERX, 0x00, 0x01),
> +	},
> +#endif
>  	{
>  	}
>  };
> diff --git a/drivers/irqchip/irq-gic-v3.c b/drivers/irqchip/irq-gic-v3.c
> index 1a91902be0b1..59a5f13f3c10 100644
> --- a/drivers/irqchip/irq-gic-v3.c
> +++ b/drivers/irqchip/irq-gic-v3.c
> @@ -107,7 +107,7 @@ static void gic_redist_wait_for_rwp(void)
>  }
>  
>  /* Low level accessors */
> -static u64 __maybe_unused gic_read_iar(void)
> +static u64 gic_read_iar_common(void)
>  {
>  	u64 irqstat;
>  
> @@ -115,6 +115,38 @@ static u64 __maybe_unused gic_read_iar(void)
>  	return irqstat;
>  }
>  
> +/*
> + * Cavium ThunderX erratum 23154
> + *
> + * The gicv3 of ThunderX requires a modified version for reading the
> + * IAR status to ensure data synchronization (access to icc_iar1_el1
> + * is not sync'ed before and after).
> + */
> +static u64 gic_read_iar_cavium_thunderx(void)
> +{
> +	u64 irqstat;
> +
> +	asm volatile(
> +		"nop;nop;nop;nop\n\t"
> +		"nop;nop;nop;nop\n\t"
> +		"mrs_s %0, " __stringify(ICC_IAR1_EL1) "\n\t"
> +		"nop;nop;nop;nop"
> +		: "=r" (irqstat));
> +	mb();
> +
> +	return irqstat;
> +}
> +
> +struct static_key is_cavium_thunderx = STATIC_KEY_INIT_FALSE;
> +
> +static u64 __maybe_unused gic_read_iar(void)
> +{
> +	if (static_key_false(&is_cavium_thunderx))
> +		return gic_read_iar_common();
> +	else
> +		return gic_read_iar_cavium_thunderx();
> +}
> +
>  static void __maybe_unused gic_write_pmr(u64 val)
>  {
>  	asm volatile("msr_s " __stringify(ICC_PMR_EL1) ", %0" : : "r" (val));
> @@ -766,8 +798,23 @@ static const struct irq_domain_ops gic_irq_domain_ops = {
>  	.free = gic_irq_domain_free,
>  };
>  
> +static void gicv3_enable_cavium_thunderx(void *data)
> +{
> +	static_key_slow_inc(&is_cavium_thunderx);
> +}
> +
>  static const struct gic_capabilities gicv3_errata[] = {
>  	{
> +		/*
> +		 * Need to be applied in guests too, thus use cpu
> +		 * detection as iidr is emulated with different vendor
> +		 * id.
> +		 */
> +		.desc		= "GIC: Cavium erratum 23154",
> +		.cpu_cap	= ARM64_WORKAROUND_CAVIUM_23154,
> +		.init		= gicv3_enable_cavium_thunderx,
> +	},
> +	{
>  	}
>  };
>  
> 

Robert,

I probably didn't express myself very well, because this not what I had
in mind, sorry...

I think this is very much overdesigned for something that should be very
simple. Why can't you have a simple:

	if (cpu_have_feature(ARM64_WORKAROUND_CAVIUM_23154))
		static_key_slow_inc(&is_cavium_thunderx);

No need for a cpu_cap field, no need to special-case feature 0, and it
keeps the code fairly readable. You can even hide it in a
gic_enable_cpu_quirks() function.

Thanks,

	M.
-- 
Jazz is not dead. It just smells funny...


From linux at arm.linux.org.uk  Fri Aug 14 07:09:34 2015
From: linux at arm.linux.org.uk (Russell King - ARM Linux)
Date: Fri, 14 Aug 2015 15:09:34 +0100
Subject: [PATCH] ARM: keystone: add a work around to handle asynchronous
 external abort
In-Reply-To: <55CDF579.4050408@ti.com>
References: <1439320409-20084-1-git-send-email-m-karicheri2@ti.com>
 <55CDF579.4050408@ti.com>
Message-ID: <20150814140934.GX7557@n2100.arm.linux.org.uk>

On Fri, Aug 14, 2015 at 10:04:41AM -0400, Murali Karicheri wrote:
> On 08/11/2015 03:13 PM, Murali Karicheri wrote:
> >Currently on some devices, an asynchronous external abort exception
> >happens during boot up when exception handlers are enabled in kernel
> >before switching to user space. This patch adds a workaround to handle
> >this once during boot. Many customers are already using this
> >with out any issues and is required to workaround the above issue.
> >
> >Signed-off-by: Murali Karicheri <m-karicheri2 at ti.com>
> >---
> >  arch/arm/mach-keystone/keystone.c | 26 ++++++++++++++++++++++++++
> >  1 file changed, 26 insertions(+)
> >
> >diff --git a/arch/arm/mach-keystone/keystone.c b/arch/arm/mach-keystone/keystone.c
> >index e2880105..c1d0fe5 100644
> >--- a/arch/arm/mach-keystone/keystone.c
> >+++ b/arch/arm/mach-keystone/keystone.c
> >@@ -15,6 +15,7 @@
> >  #include <linux/of_platform.h>
> >  #include <linux/of_address.h>
> >  #include <linux/memblock.h>
> >+#include <linux/signal.h>
> >
> >  #include <asm/setup.h>
> >  #include <asm/mach/map.h>
> >@@ -52,6 +53,24 @@ static struct notifier_block platform_nb = {
> >  	.notifier_call = keystone_platform_notifier,
> >  };
> >
> >+static bool ignore_first = true;
> >+static int keystone_async_ext_abort_fault(unsigned long addr, unsigned int fsr,
> >+					  struct pt_regs *regs)
> >+{
> >+	/*
> >+	 * if first time, ignore this as this is a asynchronous external abort
> >+	 * happening only some devices that couldn't be root caused and we add
> >+	 * this work around to handle this first time.
> >+	 */
> >+	if (ignore_first) {
> >+		ignore_first = false;
> >+		return 0;
> >+	}
> >+
> >+	/* Subsequent ones should be handled as fault */
> >+	return 1;
> >+}
> >+
> >  static void __init keystone_init(void)
> >  {
> >  	if (PHYS_OFFSET >= KEYSTONE_HIGH_PHYS_START) {
> >@@ -61,6 +80,13 @@ static void __init keystone_init(void)
> >  	}
> >  	keystone_pm_runtime_init();
> >  	of_platform_populate(NULL, of_default_bus_match_table, NULL, NULL);
> >+
> >+	/*
> >+	 * Add a one time exception handler to catch asynchronous external
> >+	 * abort
> >+	 */
> >+	hook_fault_code(17, keystone_async_ext_abort_fault, SIGBUS, 0,
> >+			"async external abort handler");
> >  }
> >
> >  static phys_addr_t keystone_virt_to_idmap(unsigned long x)
> >
> Can this be applied if it looks good?

What causes the abort?  We shouldn't be adding hacks like this to the
kernel without having the full picture...

-- 
FTTC broadband for 0.8mile line: currently at 10.5Mbps down 400kbps up
according to speedtest.net.


From mpa at pengutronix.de  Fri Aug 14 07:11:06 2015
From: mpa at pengutronix.de (Markus Pargmann)
Date: Fri, 14 Aug 2015 16:11:06 +0200
Subject: [PATCH v3 9/9] gpiolib-of: Use dev_warn instead of pr_warn
In-Reply-To: <1439561466-14350-1-git-send-email-mpa@pengutronix.de>
References: <1439561466-14350-1-git-send-email-mpa@pengutronix.de>
Message-ID: <1439561466-14350-10-git-send-email-mpa@pengutronix.de>

chip->dev should be initialized at this point so we can use dev_* here
instead of pr_warn.

Signed-off-by: Markus Pargmann <mpa at pengutronix.de>
---
 drivers/gpio/gpiolib-of.c | 4 ++--
 1 file changed, 2 insertions(+), 2 deletions(-)

diff --git a/drivers/gpio/gpiolib-of.c b/drivers/gpio/gpiolib-of.c
index 1911b692f735..48a7579dd62d 100644
--- a/drivers/gpio/gpiolib-of.c
+++ b/drivers/gpio/gpiolib-of.c
@@ -227,8 +227,8 @@ static void of_gpiochip_scan_gpios(struct gpio_chip *chip)
 
 		if (of_property_read_bool(np, "gpio-hog")) {
 			if (!dflags) {
-				pr_warn("GPIO line %d (%s): no hogging state specified, bailing out\n",
-					desc_to_gpio(desc), np->name);
+				dev_warn(chip->dev, "GPIO line %d (%s): no hogging state specified, bailing out\n",
+					 desc_to_gpio(desc), np->name);
 				continue;
 			}
 
-- 
2.4.6



From mpa at pengutronix.de  Fri Aug 14 07:11:01 2015
From: mpa at pengutronix.de (Markus Pargmann)
Date: Fri, 14 Aug 2015 16:11:01 +0200
Subject: [PATCH v3 4/9] gpio-sysfs: Use gpio descriptor name instead of
 gpiochip names array
In-Reply-To: <1439561466-14350-1-git-send-email-mpa@pengutronix.de>
References: <1439561466-14350-1-git-send-email-mpa@pengutronix.de>
Message-ID: <1439561466-14350-5-git-send-email-mpa@pengutronix.de>

The name is now stored in the gpio descriptor as well, for example to
allow to store names from DT. This patch changes the sysfs gpio files
to use the gpio descriptor name.

Signed-off-by: Markus Pargmann <mpa at pengutronix.de>
---
 drivers/gpio/gpiolib-sysfs.c | 8 +-------
 1 file changed, 1 insertion(+), 7 deletions(-)

diff --git a/drivers/gpio/gpiolib-sysfs.c b/drivers/gpio/gpiolib-sysfs.c
index b57ed8e55ab5..3e81f28e3aee 100644
--- a/drivers/gpio/gpiolib-sysfs.c
+++ b/drivers/gpio/gpiolib-sysfs.c
@@ -550,9 +550,7 @@ int gpiod_export(struct gpio_desc *desc, bool direction_may_change)
 	struct gpiod_data	*data;
 	unsigned long		flags;
 	int			status;
-	const char		*ioname = NULL;
 	struct device		*dev;
-	int			offset;
 
 	/* can't export until sysfs is available ... */
 	if (!gpio_class.p) {
@@ -601,13 +599,9 @@ int gpiod_export(struct gpio_desc *desc, bool direction_may_change)
 	else
 		data->direction_can_change = false;
 
-	offset = gpio_chip_hwgpio(desc);
-	if (chip->names && chip->names[offset])
-		ioname = chip->names[offset];
-
 	dev = device_create_with_groups(&gpio_class, chip->dev,
 					MKDEV(0, 0), data, gpio_groups,
-					ioname ? ioname : "gpio%u",
+					desc->name ? desc->name : "gpio%u",
 					desc_to_gpio(desc));
 	if (IS_ERR(dev)) {
 		status = PTR_ERR(dev);
-- 
2.4.6



From mpa at pengutronix.de  Fri Aug 14 07:11:04 2015
From: mpa at pengutronix.de (Markus Pargmann)
Date: Fri, 14 Aug 2015 16:11:04 +0200
Subject: [PATCH v3 7/9] gpiolib-sysfs: Add gpio name parsing for sysfs export
In-Reply-To: <1439561466-14350-1-git-send-email-mpa@pengutronix.de>
References: <1439561466-14350-1-git-send-email-mpa@pengutronix.de>
Message-ID: <1439561466-14350-8-git-send-email-mpa@pengutronix.de>

Signed-off-by: Markus Pargmann <mpa at pengutronix.de>
---
 drivers/gpio/gpiolib-sysfs.c | 47 ++++++++++++++++++++++++++++++++------------
 1 file changed, 34 insertions(+), 13 deletions(-)

diff --git a/drivers/gpio/gpiolib-sysfs.c b/drivers/gpio/gpiolib-sysfs.c
index 2022cfb00aeb..e401878d05ce 100644
--- a/drivers/gpio/gpiolib-sysfs.c
+++ b/drivers/gpio/gpiolib-sysfs.c
@@ -455,18 +455,28 @@ static ssize_t export_store(struct class *class,
 				const char *buf, size_t len)
 {
 	long			gpio;
-	struct gpio_desc	*desc;
+	struct gpio_desc	*desc = NULL;
 	int			status;
 
 	status = kstrtol(buf, 0, &gpio);
-	if (status < 0)
-		goto done;
+	if (!status)
+		desc = gpio_to_desc(gpio);
 
-	desc = gpio_to_desc(gpio);
-	/* reject invalid GPIOs */
+	/* Fall back on detection by name */
 	if (!desc) {
-		pr_warn("%s: invalid GPIO %ld\n", __func__, gpio);
-		return -EINVAL;
+		char *gpio_name = kstrdup(buf, GFP_KERNEL);
+
+		if (!gpio_name)
+			return -ENOMEM;
+
+		desc = gpio_name_to_desc(strim(gpio_name));
+		kfree(gpio_name);
+
+		/* reject invalid GPIOs */
+		if (!desc) {
+			pr_warn("%s: invalid GPIO %s\n", __func__, buf);
+			return -EINVAL;
+		}
 	}
 
 	/* No extra locking here; FLAG_SYSFS just signifies that the
@@ -497,17 +507,28 @@ static ssize_t unexport_store(struct class *class,
 				const char *buf, size_t len)
 {
 	long			gpio;
-	struct gpio_desc	*desc;
+	struct gpio_desc	*desc = NULL;
 	int			status;
 
 	status = kstrtol(buf, 0, &gpio);
-	if (status < 0)
-		goto done;
+	if (!status)
+		desc = gpio_to_desc(gpio);
+
+	/* Fall back on detection by name */
+	if (!desc) {
+		char *gpio_name = kstrdup(buf, GFP_KERNEL);
+
+		if (!gpio_name)
+			return -ENOMEM;
+
+		desc = gpio_name_to_desc(strim(gpio_name));
+		kfree(gpio_name);
+	}
+
 
-	desc = gpio_to_desc(gpio);
 	/* reject bogus commands (gpio_unexport ignores them) */
 	if (!desc) {
-		pr_warn("%s: invalid GPIO %ld\n", __func__, gpio);
+		pr_warn("%s: invalid GPIO %s\n", __func__, buf);
 		return -EINVAL;
 	}
 
@@ -521,7 +542,7 @@ static ssize_t unexport_store(struct class *class,
 		status = 0;
 		gpiod_free(desc);
 	}
-done:
+
 	if (status)
 		pr_debug("%s: status %d\n", __func__, status);
 	return status ? : len;
-- 
2.4.6



From mpa at pengutronix.de  Fri Aug 14 07:10:58 2015
From: mpa at pengutronix.de (Markus Pargmann)
Date: Fri, 14 Aug 2015 16:10:58 +0200
Subject: [PATCH v3 1/9] gpiolib-of: Rename gpio_hog functions to be generic
In-Reply-To: <1439561466-14350-1-git-send-email-mpa@pengutronix.de>
References: <1439561466-14350-1-git-send-email-mpa@pengutronix.de>
Message-ID: <1439561466-14350-2-git-send-email-mpa@pengutronix.de>

The gpio hogging functions are currently only used for gpio-hogging. But
these functions are widely generic ones which parse gpio device nodes in
the DT.

Signed-off-by: Markus Pargmann <mpa at pengutronix.de>
---
 drivers/gpio/gpiolib-of.c | 20 ++++++++++----------
 1 file changed, 10 insertions(+), 10 deletions(-)

diff --git a/drivers/gpio/gpiolib-of.c b/drivers/gpio/gpiolib-of.c
index 9a0ec48a4737..fea80bbccf12 100644
--- a/drivers/gpio/gpiolib-of.c
+++ b/drivers/gpio/gpiolib-of.c
@@ -119,20 +119,20 @@ int of_get_named_gpio_flags(struct device_node *np, const char *list_name,
 EXPORT_SYMBOL(of_get_named_gpio_flags);
 
 /**
- * of_get_gpio_hog() - Get a GPIO hog descriptor, names and flags for GPIO API
+ * of_parse_own_gpio() - Get a GPIO hog descriptor, names and flags for GPIO API
  * @np:		device node to get GPIO from
  * @name:	GPIO line name
  * @lflags:	gpio_lookup_flags - returned from of_find_gpio() or
- *		of_get_gpio_hog()
+ *		of_parse_own_gpio()
  * @dflags:	gpiod_flags - optional GPIO initialization flags
  *
  * Returns GPIO descriptor to use with Linux GPIO API, or one of the errno
  * value on the error condition.
  */
-static struct gpio_desc *of_get_gpio_hog(struct device_node *np,
-				  const char **name,
-				  enum gpio_lookup_flags *lflags,
-				  enum gpiod_flags *dflags)
+static struct gpio_desc *of_parse_own_gpio(struct device_node *np,
+					   const char **name,
+					   enum gpio_lookup_flags *lflags,
+					   enum gpiod_flags *dflags)
 {
 	struct device_node *chip_np;
 	enum of_gpio_flags xlate_flags;
@@ -199,13 +199,13 @@ static struct gpio_desc *of_get_gpio_hog(struct device_node *np,
 }
 
 /**
- * of_gpiochip_scan_hogs - Scan gpio-controller and apply GPIO hog as requested
+ * of_gpiochip_scan_gpios - Scan gpio-controller for gpio definitions
  * @chip:	gpio chip to act on
  *
  * This is only used by of_gpiochip_add to request/set GPIO initial
  * configuration.
  */
-static void of_gpiochip_scan_hogs(struct gpio_chip *chip)
+static void of_gpiochip_scan_gpios(struct gpio_chip *chip)
 {
 	struct gpio_desc *desc = NULL;
 	struct device_node *np;
@@ -217,7 +217,7 @@ static void of_gpiochip_scan_hogs(struct gpio_chip *chip)
 		if (!of_property_read_bool(np, "gpio-hog"))
 			continue;
 
-		desc = of_get_gpio_hog(np, &name, &lflags, &dflags);
+		desc = of_parse_own_gpio(np, &name, &lflags, &dflags);
 		if (IS_ERR(desc))
 			continue;
 
@@ -436,7 +436,7 @@ void of_gpiochip_add(struct gpio_chip *chip)
 	of_gpiochip_add_pin_range(chip);
 	of_node_get(chip->of_node);
 
-	of_gpiochip_scan_hogs(chip);
+	of_gpiochip_scan_gpios(chip);
 }
 
 void of_gpiochip_remove(struct gpio_chip *chip)
-- 
2.4.6



From mpa at pengutronix.de  Fri Aug 14 07:11:02 2015
From: mpa at pengutronix.de (Markus Pargmann)
Date: Fri, 14 Aug 2015 16:11:02 +0200
Subject: [PATCH v3 5/9] gpiolib: Add gpio name information to
 /sys/kernel/debug/gpio
In-Reply-To: <1439561466-14350-1-git-send-email-mpa@pengutronix.de>
References: <1439561466-14350-1-git-send-email-mpa@pengutronix.de>
Message-ID: <1439561466-14350-6-git-send-email-mpa@pengutronix.de>

Add some information about gpio names to the debugfs gpio file. name and
label of a GPIO are then displayed next to each other. This way it is
easy to see what the real name of GPIO is and what the driver requested
it for.

Signed-off-by: Markus Pargmann <mpa at pengutronix.de>
---
 Documentation/ABI/testing/sysfs-gpio |  1 +
 drivers/gpio/gpiolib.c               | 11 ++++++++---
 2 files changed, 9 insertions(+), 3 deletions(-)

diff --git a/Documentation/ABI/testing/sysfs-gpio b/Documentation/ABI/testing/sysfs-gpio
index 55ffa2df1c10..2c1e199fd4e1 100644
--- a/Documentation/ABI/testing/sysfs-gpio
+++ b/Documentation/ABI/testing/sysfs-gpio
@@ -21,6 +21,7 @@ Description:
 	    /value ... always readable, writes fail for input GPIOs
 	    /direction ... r/w as: in, out (default low); write: high, low
 	    /edge ... r/w as: none, falling, rising, both
+	    /name ... r/o, unique name of the GPIO
 	/gpiochipN ... for each gpiochip; #N is its first GPIO
 	    /base ... (r/o) same as N
 	    /label ... (r/o) descriptive, not necessarily unique
diff --git a/drivers/gpio/gpiolib.c b/drivers/gpio/gpiolib.c
index 3908503bebfe..79a0b41ce57b 100644
--- a/drivers/gpio/gpiolib.c
+++ b/drivers/gpio/gpiolib.c
@@ -2344,14 +2344,19 @@ static void gpiolib_dbg_show(struct seq_file *s, struct gpio_chip *chip)
 	int			is_irq;
 
 	for (i = 0; i < chip->ngpio; i++, gpio++, gdesc++) {
-		if (!test_bit(FLAG_REQUESTED, &gdesc->flags))
+		if (!test_bit(FLAG_REQUESTED, &gdesc->flags)) {
+			if (gdesc->name) {
+				seq_printf(s, " gpio-%-3d (%-20.20s)\n",
+					   gpio, gdesc->name);
+			}
 			continue;
+		}
 
 		gpiod_get_direction(gdesc);
 		is_out = test_bit(FLAG_IS_OUT, &gdesc->flags);
 		is_irq = test_bit(FLAG_USED_AS_IRQ, &gdesc->flags);
-		seq_printf(s, " gpio-%-3d (%-20.20s) %s %s %s",
-			gpio, gdesc->label,
+		seq_printf(s, " gpio-%-3d (%-20.20s|%-20.20s) %s %s %s",
+			gpio, gdesc->name ? gdesc->name : "", gdesc->label,
 			is_out ? "out" : "in ",
 			chip->get
 				? (chip->get(chip, i) ? "hi" : "lo")
-- 
2.4.6



From lina.iyer at linaro.org  Fri Aug 14 07:12:22 2015
From: lina.iyer at linaro.org (Lina Iyer)
Date: Fri, 14 Aug 2015 08:12:22 -0600
Subject: [PATCH RFC 08/10] hwspinlock: qcom: Lock #7 is special lock,
 uses dynamic proc_id
In-Reply-To: <20150813043036.GJ13472@usrtlx11787.corpusers.net>
References: <438731339-58317-1-git-send-email-lina.iyer@linaro.org>
 <1438792366-2737-1-git-send-email-lina.iyer@linaro.org>
 <1438792366-2737-9-git-send-email-lina.iyer@linaro.org>
 <20150813043036.GJ13472@usrtlx11787.corpusers.net>
Message-ID: <20150814141222.GC86880@linaro.org>

On Wed, Aug 12 2015 at 22:30 -0600, Bjorn Andersson wrote:
>On Wed 05 Aug 09:32 PDT 2015, Lina Iyer wrote:
>
>> Hwspinlocks are widely used between processors in an SoC, and also
>> between elevation levels within in the same processor.  QCOM SoC's use
>> hwspinlock to serialize entry into a low power mode when the context
>> switches from Linux to secure monitor.
>>
>> Lock #7 has been assigned for this purpose. In order to differentiate
>> between one cpu core holding a lock while another cpu is contending for
>> the same lock, the proc id written into the lock is (128 + cpu id). This
>> makes it unique value among the cpu cores and therefore when a core
>> locks the hwspinlock, other cores would wait for the lock to be released
>> since they would have a different proc id.  This value is specific for
>> the lock #7 only.
>>
>
>As I was thinking about this, I came to the conclusion that my argument
>that it's system configuration and not a property of the block that lock
>#7 is special is actually biting myself.
>
>Just as #7 is system configuration, so is the fact that 1 is the lock
>value for all other locks.
>
>I've been meaning to answer you, but I haven't come to a good conclusion
>in this matter. I think that both of these properties should be possible
>to express in DT, but I don't know how.
>
I thought about that. These are s/w imposed behavior. As a far as the
h/w is concerned, you could just write a non-zero value and the lock is
considered acquired. So placing that in DT may not be appropriate.

>
>Perhaps we should just list each lock that we expose as a subnode in DT
>with a property to indicate the lock value - with the possibility of
>indicating cpu_id.
>
>Something like:
>
>tcsr-mutex {
>	compatible = "qcom,tcsr-mutex";
>	syscon = <&tcsr_mutex_block 0 0x80>;
>
>	#hwlock-cells = <1>;
>	#address-cells = <1>;
>	#size-cells = <0>;
>
>	smem-lock at 3 {
>		reg = <3>;
>		qcom,lock-value = <1>;
>	};
>
>	scm-lock at 7 {
>		reg = <7>;
>		qcom,lock-value-from-cpu-id;
>		qcom,lock-raw;
>	};
>};
>
>As we don't reference most of these locks anyways I don't think this
>would still be reasonable. And if reg is an array it's quite compact.
>
But, looking at the DT, its not evident what lock-value-from-cpu-id,
would mean.  It is an implementation detail of Linux (as a result of
firmware). May be better to just hide it in the hwspinlock driver.

I am not sure about lock-raw, but I would think its not QCOM specific.
Imagine the case, when hwspinlock framework does not s/w spinlock around
the hwspinlock, we wouldnt have this property. The reason why we
spinlock around the hwspinlock is because we dont have a good way to
generate a unique value for the hwspinlock, so multiple threads
acquiring the same locks could safely be assured that they have acquired
the lock. While convenient and probably more effecient to just have s/w
spinlocks around the hwspinlock, the problem here is it is mandated
across all locks.

To me it seems OK to explicity call out lock #7 as unique entity in the
bank that is compatible with a raw hwspinlock in the DT. But the value
that lock #7 uses is an implementation detail and should rest wth the
drivers.

Thanks,
Lina


From mpa at pengutronix.de  Fri Aug 14 07:11:00 2015
From: mpa at pengutronix.de (Markus Pargmann)
Date: Fri, 14 Aug 2015 16:11:00 +0200
Subject: [PATCH v3 3/9] gpiolib: Use GPIO name from names array for gpio
 descriptor
In-Reply-To: <1439561466-14350-1-git-send-email-mpa@pengutronix.de>
References: <1439561466-14350-1-git-send-email-mpa@pengutronix.de>
Message-ID: <1439561466-14350-4-git-send-email-mpa@pengutronix.de>

This patch adds GPIO names to the GPIO descriptors when initializing the
gpiochip. It also introduces a check whether any of the new names will
conflict with an existing GPIO name.

Signed-off-by: Markus Pargmann <mpa at pengutronix.de>
---
 drivers/gpio/gpiolib.c | 37 +++++++++++++++++++++++++++++++++++++
 1 file changed, 37 insertions(+)

diff --git a/drivers/gpio/gpiolib.c b/drivers/gpio/gpiolib.c
index eed3751fe14f..3908503bebfe 100644
--- a/drivers/gpio/gpiolib.c
+++ b/drivers/gpio/gpiolib.c
@@ -250,6 +250,38 @@ static int gpiochip_add_to_list(struct gpio_chip *chip)
 	return err;
 }
 
+/*
+ * Takes the names from gc->names and checks if they are all unique. If they
+ * are, they are assigned to their gpio descriptors.
+ *
+ * Returns -EEXIST if one of the names is already used for a different GPIO.
+ */
+static int gpiochip_set_desc_names(struct gpio_chip *gc)
+{
+	int i;
+
+	if (!gc->names)
+		return 0;
+
+	/* First check all names if they are unique */
+	for (i = 0; i != gc->ngpio; ++i) {
+		struct gpio_desc *gpio;
+
+		gpio = gpio_name_to_desc(gc->names[i]);
+		if (gpio) {
+			dev_err(gc->dev, "Detected name collision for GPIO name '%s'\n",
+				gc->names[i]);
+			return -EEXIST;
+		}
+	}
+
+	/* Then add all names to the GPIO descriptors */
+	for (i = 0; i != gc->ngpio; ++i)
+		gc->desc[i].name = gc->names[i];
+
+	return 0;
+}
+
 /**
  * gpiochip_add() - register a gpio_chip
  * @chip: the chip to register, with chip->base initialized
@@ -319,6 +351,10 @@ int gpiochip_add(struct gpio_chip *chip)
 	INIT_LIST_HEAD(&chip->pin_ranges);
 #endif
 
+	status = gpiochip_set_desc_names(chip);
+	if (status)
+		goto err_remove_from_list;
+
 	of_gpiochip_add(chip);
 	acpi_gpiochip_add(chip);
 
@@ -336,6 +372,7 @@ err_remove_chip:
 	acpi_gpiochip_remove(chip);
 	gpiochip_free_hogs(chip);
 	of_gpiochip_remove(chip);
+err_remove_from_list:
 	spin_lock_irqsave(&gpio_lock, flags);
 	list_del(&chip->list);
 	spin_unlock_irqrestore(&gpio_lock, flags);
-- 
2.4.6



From mpa at pengutronix.de  Fri Aug 14 07:10:57 2015
From: mpa at pengutronix.de (Markus Pargmann)
Date: Fri, 14 Aug 2015 16:10:57 +0200
Subject: [PATCH v3 0/9] gpiolib: Add GPIO name support
Message-ID: <1439561466-14350-1-git-send-email-mpa@pengutronix.de>

Changes in v3:
As discussed in the v2 thread, we are using the already existing gpiochip names
now. To avoid races between kernel and userspace, the setup of gpio names in
the gpio descriptors has to happen right before the gpiochip is added for use
and after the gpio descriptors are available. Unfortunately this is exactly in
the function gpiochip_add().

So we can't use a a function as proposed in the discussion like
gpiochip_set_names(), as this function would only be possible after we executed
gpiochip_add(). Before that point the gpio descriptors are not available. But
this can potentially lead to races between userspace and the gpio chip.

That is the reason why I left the names array in the gpioscript. But this array
is now only used to initialize the GPIO descriptors. The named sysfs
directories are now created using the name stored in the gpio descriptor.

As the name is now directly represented through the sysfs directory name, I am
not sure if it makes sense to keep the patch which adds a 'name' property to
the sysfs GPIO directories. For the moment it is still in this series.

Other changes in v3:
 - Renamed generic of_parse_gpio() to of_parse_own_gpio()
 - Replaced pr_warn with dev_warn as the device is available in the parsing code
   in gpiolib-of
 - Introduced name collision checks when adding the names from gpiochip->names
   to the gpio descriptors
 - Added documentation about /sys/class/gpio/<GPIO>/name
 - Added check for DT in case the GPIO already has a name. This may happen as
   there are different ways to set a name, through 'line-name' property and
   node name

Best Regards,

Markus


Changes in v2:
 - Removed patch 'gpiolib: Fix possible use of wrong name'
 - Removed discussed patch 'gpio: Allow hogged gpios to be requested' from this
   series
 - Fixed show gpio name patch (locks, (null) printing, and getting the descriptor)
 - Merged gpio name patch into gpio_name_to_desc() patch

Description from v1:

This is a proposal to add GPIO names to the kernel based on devicetree
descriptions.

This series adds GPIO name support. Until now it is only possible to use names
for already requested GPIOs (for example what they are used for). It is not
possible to identify GPIOs by a name although most of them have a name for
example in the schematics of the board. This makes it difficult to identify
a specific GPIO from userspace.

As the GPIO name information is a hardware description this series uses the
devicetree bindings introduced by the GPIO hogging mechanism, specifically
'line-name', to identify GPIOs. The sysfs 'export' file is changed to accept
names as fallback. The gpio numbers still have a higher priority to ensure
backwards compatibility.

Exported GPIOs are still using their number as directory name (gpio<ID>). But the
directories now contain a 'name' file which is '' for non-existent names and
the name otherwise.

This series can be used to have an easy name mapping for udev with a quite
simple rule similar to this:
	SUBSYSTEM=="gpio", KERNEL=="gpio*", ATTR{name}!="(null)", ACTION=="add", \
	PROGRAM+="/bin/sh -c 'mkdir -p /dev/gpios; rm -f /dev/gpios/$attr{name}; ln -s /sys%p/ /dev/gpios/$attr{name}"
With this rule udev adds a link for each exported GPIO with a name into
/dev/gpios/. This way it is not necessary to know the number of a GPIO to use
it.


Markus Pargmann (9):
  gpiolib-of: Rename gpio_hog functions to be generic
  gpio: Introduce gpio descriptor 'name'
  gpiolib: Use GPIO name from names array for gpio descriptor
  gpio-sysfs: Use gpio descriptor name instead of gpiochip names array
  gpiolib: Add gpio name information to /sys/kernel/debug/gpio
  gpiolib-sysfs: Show gpio-name in /sys/class/gpio/gpio*/name
  gpiolib-sysfs: Add gpio name parsing for sysfs export
  gpiolib-of: Reuse 'line-name' from DT as gpio descriptor name
  gpiolib-of: Use dev_warn instead of pr_warn

 Documentation/ABI/testing/sysfs-gpio |  1 +
 drivers/gpio/gpiolib-of.c            | 50 +++++++++++++---------
 drivers/gpio/gpiolib-sysfs.c         | 67 +++++++++++++++++++++---------
 drivers/gpio/gpiolib.c               | 80 ++++++++++++++++++++++++++++++++++--
 drivers/gpio/gpiolib.h               |  3 ++
 include/linux/gpio/consumer.h        |  7 ++++
 6 files changed, 166 insertions(+), 42 deletions(-)

-- 
2.4.6



From l.stach at pengutronix.de  Fri Aug 14 07:11:59 2015
From: l.stach at pengutronix.de (Lucas Stach)
Date: Fri, 14 Aug 2015 16:11:59 +0200
Subject: [PATCH] ARM: keystone: add a work around to handle asynchronous
 external abort
In-Reply-To: <55CDF579.4050408@ti.com>
References: <1439320409-20084-1-git-send-email-m-karicheri2@ti.com>
 <55CDF579.4050408@ti.com>
Message-ID: <1439561519.13210.55.camel@pengutronix.de>

Am Freitag, den 14.08.2015, 10:04 -0400 schrieb Murali Karicheri:
> On 08/11/2015 03:13 PM, Murali Karicheri wrote:
> > Currently on some devices, an asynchronous external abort exception
> > happens during boot up when exception handlers are enabled in kernel
> > before switching to user space. This patch adds a workaround to handle
> > this once during boot. Many customers are already using this
> > with out any issues and is required to workaround the above issue.
> >
> > Signed-off-by: Murali Karicheri <m-karicheri2 at ti.com>
> > ---
> >   arch/arm/mach-keystone/keystone.c | 26 ++++++++++++++++++++++++++
> >   1 file changed, 26 insertions(+)
> >
> > diff --git a/arch/arm/mach-keystone/keystone.c b/arch/arm/mach-keystone/keystone.c
> > index e2880105..c1d0fe5 100644
> > --- a/arch/arm/mach-keystone/keystone.c
> > +++ b/arch/arm/mach-keystone/keystone.c
> > @@ -15,6 +15,7 @@
> >   #include <linux/of_platform.h>
> >   #include <linux/of_address.h>
> >   #include <linux/memblock.h>
> > +#include <linux/signal.h>
> >
> >   #include <asm/setup.h>
> >   #include <asm/mach/map.h>
> > @@ -52,6 +53,24 @@ static struct notifier_block platform_nb = {
> >   	.notifier_call = keystone_platform_notifier,
> >   };
> >
> > +static bool ignore_first = true;
> > +static int keystone_async_ext_abort_fault(unsigned long addr, unsigned int fsr,
> > +					  struct pt_regs *regs)
> > +{
> > +	/*
> > +	 * if first time, ignore this as this is a asynchronous external abort
> > +	 * happening only some devices that couldn't be root caused and we add
> > +	 * this work around to handle this first time.
> > +	 */
> > +	if (ignore_first) {
> > +		ignore_first = false;
> > +		return 0;
> > +	}
> > +
> > +	/* Subsequent ones should be handled as fault */
> > +	return 1;
> > +}
> > +
> >   static void __init keystone_init(void)
> >   {
> >   	if (PHYS_OFFSET >= KEYSTONE_HIGH_PHYS_START) {
> > @@ -61,6 +80,13 @@ static void __init keystone_init(void)
> >   	}
> >   	keystone_pm_runtime_init();
> >   	of_platform_populate(NULL, of_default_bus_match_table, NULL, NULL);
> > +
> > +	/*
> > +	 * Add a one time exception handler to catch asynchronous external
> > +	 * abort
> > +	 */
> > +	hook_fault_code(17, keystone_async_ext_abort_fault, SIGBUS, 0,
> > +			"async external abort handler");
> >   }
> >
> >   static phys_addr_t keystone_virt_to_idmap(unsigned long x)
> >
> Can this be applied if it looks good?
> 
The keystone PCIe host driver already hooks the same fault code. Those
hooks are no chain, but a simple pointer, so one of those handlers is
going to loose out.

This likely isn't what you intended.

Regards,
Lucas
-- 
Pengutronix e.K.             | Lucas Stach                 |
Industrial Linux Solutions   | http://www.pengutronix.de/  |



From mpa at pengutronix.de  Fri Aug 14 07:11:05 2015
From: mpa at pengutronix.de (Markus Pargmann)
Date: Fri, 14 Aug 2015 16:11:05 +0200
Subject: [PATCH v3 8/9] gpiolib-of: Reuse 'line-name' from DT as gpio
 descriptor name
In-Reply-To: <1439561466-14350-1-git-send-email-mpa@pengutronix.de>
References: <1439561466-14350-1-git-send-email-mpa@pengutronix.de>
Message-ID: <1439561466-14350-9-git-send-email-mpa@pengutronix.de>

The DT describes gpios with subnodes. These subnodes can contain a
property 'line-name'. This information can be useful in other areas
where we want to identify a GPIO by its name.

This patch stores the line-name in the gpio descriptor.

Signed-off-by: Markus Pargmann <mpa at pengutronix.de>
---
 drivers/gpio/gpiolib-of.c | 30 +++++++++++++++++++++---------
 1 file changed, 21 insertions(+), 9 deletions(-)

diff --git a/drivers/gpio/gpiolib-of.c b/drivers/gpio/gpiolib-of.c
index fea80bbccf12..1911b692f735 100644
--- a/drivers/gpio/gpiolib-of.c
+++ b/drivers/gpio/gpiolib-of.c
@@ -184,11 +184,6 @@ static struct gpio_desc *of_parse_own_gpio(struct device_node *np,
 		*dflags |= GPIOD_OUT_LOW;
 	else if (of_property_read_bool(np, "output-high"))
 		*dflags |= GPIOD_OUT_HIGH;
-	else {
-		pr_warn("GPIO line %d (%s): no hogging state specified, bailing out\n",
-			desc_to_gpio(gg_data.out_gpio), np->name);
-		return ERR_PTR(-EINVAL);
-	}
 
 	if (name && of_property_read_string(np, "line-name", name))
 		*name = np->name;
@@ -214,15 +209,32 @@ static void of_gpiochip_scan_gpios(struct gpio_chip *chip)
 	enum gpiod_flags dflags;
 
 	for_each_child_of_node(chip->of_node, np) {
-		if (!of_property_read_bool(np, "gpio-hog"))
-			continue;
+		struct gpio_desc *name_desc;
 
 		desc = of_parse_own_gpio(np, &name, &lflags, &dflags);
 		if (IS_ERR(desc))
 			continue;
 
-		if (gpiod_hog(desc, name, lflags, dflags))
-			continue;
+		name_desc = gpio_name_to_desc(name);
+		if (name_desc)
+			dev_warn(chip->dev, "GPIO name collision for '%s' detected at GPIO line %d (%s)\n",
+				 name, desc_to_gpio(desc), np->name);
+		else if (desc->name)
+			dev_warn(chip->dev, "GPIO has already a name '%s' new name would be '%s' at GPIO %d\n",
+				 desc->name, name, desc_to_gpio(desc));
+		else
+			desc->name = name;
+
+		if (of_property_read_bool(np, "gpio-hog")) {
+			if (!dflags) {
+				pr_warn("GPIO line %d (%s): no hogging state specified, bailing out\n",
+					desc_to_gpio(desc), np->name);
+				continue;
+			}
+
+			if (gpiod_hog(desc, name, lflags, dflags))
+				continue;
+		}
 	}
 }
 
-- 
2.4.6



From mpa at pengutronix.de  Fri Aug 14 07:10:59 2015
From: mpa at pengutronix.de (Markus Pargmann)
Date: Fri, 14 Aug 2015 16:10:59 +0200
Subject: [PATCH v3 2/9] gpio: Introduce gpio descriptor 'name'
In-Reply-To: <1439561466-14350-1-git-send-email-mpa@pengutronix.de>
References: <1439561466-14350-1-git-send-email-mpa@pengutronix.de>
Message-ID: <1439561466-14350-3-git-send-email-mpa@pengutronix.de>

The latest gpio hogging mechanism assigns each gpio a 'line-name' in the
devicetree. The 'name' field is different from the 'label' field.
'label' is only used for requested GPIOs to describe its current use by
driver or userspace.

The 'name' field describes the GPIO itself, not the use. This is most
likely identical to the label in the schematic on the GPIO line and
should help to find this particular GPIO.

This is equivalent to the gpiochip->names array. However names should be
stored in the GPIO descriptor. We will use gpiochip->names in the future
only as initializer for the GPIO descriptors for drivers that assign
GPIO names hardcoded. All other GPIO names will be parsed from DT and
directly assigned to the GPIO descriptor.

This patch adds a helper function to find gpio descriptors by name
instead of gpio number.

Signed-off-by: Markus Pargmann <mpa at pengutronix.de>
---
 drivers/gpio/gpiolib.c        | 32 ++++++++++++++++++++++++++++++++
 drivers/gpio/gpiolib.h        |  3 +++
 include/linux/gpio/consumer.h |  7 +++++++
 3 files changed, 42 insertions(+)

diff --git a/drivers/gpio/gpiolib.c b/drivers/gpio/gpiolib.c
index bf4bd1d120c3..eed3751fe14f 100644
--- a/drivers/gpio/gpiolib.c
+++ b/drivers/gpio/gpiolib.c
@@ -90,6 +90,38 @@ struct gpio_desc *gpio_to_desc(unsigned gpio)
 EXPORT_SYMBOL_GPL(gpio_to_desc);
 
 /**
+ * Convert a GPIO name to its descriptor
+ */
+struct gpio_desc *gpio_name_to_desc(const char * const name)
+{
+	struct gpio_chip *chip;
+	unsigned long flags;
+
+	spin_lock_irqsave(&gpio_lock, flags);
+
+	list_for_each_entry(chip, &gpio_chips, list) {
+		int i;
+
+		for (i = 0; i != chip->ngpio; ++i) {
+			struct gpio_desc *gpio = &chip->desc[i];
+
+			if (!gpio->name)
+				continue;
+
+			if (!strcmp(gpio->name, name)) {
+				spin_unlock_irqrestore(&gpio_lock, flags);
+				return gpio;
+			}
+		}
+	}
+
+	spin_unlock_irqrestore(&gpio_lock, flags);
+
+	return NULL;
+}
+EXPORT_SYMBOL_GPL(gpio_name_to_desc);
+
+/**
  * Get the GPIO descriptor corresponding to the given hw number for this chip.
  */
 struct gpio_desc *gpiochip_get_desc(struct gpio_chip *chip,
diff --git a/drivers/gpio/gpiolib.h b/drivers/gpio/gpiolib.h
index bf343004b008..78e634d1c719 100644
--- a/drivers/gpio/gpiolib.h
+++ b/drivers/gpio/gpiolib.h
@@ -89,7 +89,10 @@ struct gpio_desc {
 #define FLAG_USED_AS_IRQ 9	/* GPIO is connected to an IRQ */
 #define FLAG_IS_HOGGED	11	/* GPIO is hogged */
 
+	/* Connection label */
 	const char		*label;
+	/* Name of the GPIO */
+	const char		*name;
 };
 
 int gpiod_request(struct gpio_desc *desc, const char *label);
diff --git a/include/linux/gpio/consumer.h b/include/linux/gpio/consumer.h
index adac255aee86..a873b8b47ab3 100644
--- a/include/linux/gpio/consumer.h
+++ b/include/linux/gpio/consumer.h
@@ -130,6 +130,7 @@ int gpiod_to_irq(const struct gpio_desc *desc);
 /* Convert between the old gpio_ and new gpiod_ interfaces */
 struct gpio_desc *gpio_to_desc(unsigned gpio);
 int desc_to_gpio(const struct gpio_desc *desc);
+struct gpio_desc *gpio_name_to_desc(const char *name);
 
 /* Child properties interface */
 struct fwnode_handle;
@@ -400,6 +401,12 @@ static inline struct gpio_desc *gpio_to_desc(unsigned gpio)
 {
 	return ERR_PTR(-EINVAL);
 }
+
+static inline struct gpio_desc *gpio_name_to_desc(const char *name)
+{
+	return ERR_PTR(-EINVAL);
+}
+
 static inline int desc_to_gpio(const struct gpio_desc *desc)
 {
 	/* GPIO can never have been requested */
-- 
2.4.6



From jeremy.linton at arm.com  Fri Aug 14 07:12:28 2015
From: jeremy.linton at arm.com (Jeremy Linton)
Date: Fri, 14 Aug 2015 09:12:28 -0500
Subject: [PATCH 1/3] Honor ACPI _CCA attribute setting
In-Reply-To: <55CD4832.7070301@amd.com>
References: <1439416290-21228-1-git-send-email-jeremy.linton@arm.com>
 <1439416290-21228-2-git-send-email-jeremy.linton@arm.com>
 <55CD4832.7070301@amd.com>
Message-ID: <55CDF74C.3050703@arm.com>

Hello Suravee,

On 08/13/2015 08:45 PM, Suravee Suthikulpanit wrote:
> On 8/13/15 04:51, Jeremy Linton wrote:
>> ACPI configurations can now mark devices as noncoherent,
>> support that choice.
>
> This change was in my earlier revisions for the original patch series to
> add ACPI CCA support. At the time, this was pushed back since we were
> not sure whether this would be a useful case, and whether such hardware
> exists.

Yes, I was made aware of that conversation during the review here.

Basically, the ARM Juno development platform has a mix of coherent and 
noncoherent devices. The EHCI being one of the primary noncoherent 
peripherals. Without which, the usefulness of the platform for 
developing with an ACPI kernel is limited.


Thanks,





From gregory.clement at free-electrons.com  Fri Aug 14 07:13:35 2015
From: gregory.clement at free-electrons.com (Gregory CLEMENT)
Date: Fri, 14 Aug 2015 16:13:35 +0200
Subject: commit a71b092 "ARM: Convert handle_IRQ to use
 __handle_domain_irq" breaks DNS-323
In-Reply-To: <55CDF5C3.7080204@vollmann.ch>
References: <55CDF5C3.7080204@vollmann.ch>
Message-ID: <55CDF78F.6070001@free-electrons.com>

Hi Detlef,

On 14/08/2015 16:05, Detlef Vollmann wrote:
> Hello,
> 
> this commit:
>  > commit a71b092a9c68685a270ebdde7b5986ba8787e575
>  > Author: Marc Zyngier <marc.zyngier at arm.com>
>  > Date:   Tue Aug 26 11:03:18 2014 +0100
>  >
>  >     ARM: Convert handle_IRQ to use __handle_domain_irq
> [...]
> causes the kernel not to boot anymore on my DNS-323.
> Soc: MV88F5182 Rev 2
> CPU: ARM926 (Rev 0) running @ 500Mhz
> CPU: Feroceon [41069260] revision 0 (ARMv5TEJ), cr=a005317f
> Orion ID: MV88F5182-A2. TCLK=166666667.
> DNS-323: Identified HW revision B1
> 
> Boot stops after "Uncompressing Linux... done, booting the kernel."
> Reverting the commit works fine for me.
> Tested 4.1.2 and 4.2.0-rc6 with orion5x_defconfig.

Could you try the following patch ?

http://lists.infradead.org/pipermail/linux-arm-kernel/2015-July/356501.html

Thanks,

Gregory

> 
>    Detlef
> 
> _______________________________________________
> linux-arm-kernel mailing list
> linux-arm-kernel at lists.infradead.org
> http://lists.infradead.org/mailman/listinfo/linux-arm-kernel
> 


-- 
Gregory Clement, Free Electrons
Kernel, drivers, real-time and embedded Linux
development, consulting, training and support.
http://free-electrons.com


From catalin.marinas at arm.com  Fri Aug 14 07:30:01 2015
From: catalin.marinas at arm.com (Catalin Marinas)
Date: Fri, 14 Aug 2015 15:30:01 +0100
Subject: [PATCH] ARM: dma-mapping: Don't use outer_flush_range when the
 L2C is coherent
In-Reply-To: <55CDE3F6.7050401@free-electrons.com>
References: <1439474365-12058-1-git-send-email-gregory.clement@free-electrons.com>
 <20150813151603.GB4602@e104818-lin.cambridge.arm.com>
 <55CDE3F6.7050401@free-electrons.com>
Message-ID: <20150814143000.GF16368@e104818-lin.cambridge.arm.com>

On Fri, Aug 14, 2015 at 02:49:58PM +0200, Gregory CLEMENT wrote:
> On 13/08/2015 17:16, Catalin Marinas wrote:
> > On Thu, Aug 13, 2015 at 03:59:25PM +0200, Gregory CLEMENT wrote:
> >> @@ -1131,7 +1143,8 @@ static inline void __free_iova(struct dma_iommu_mapping *mapping,
> >>  }
> >>  
> >>  static struct page **__iommu_alloc_buffer(struct device *dev, size_t size,
> >> -					  gfp_t gfp, struct dma_attrs *attrs)
> >> +					gfp_t gfp, struct dma_attrs *attrs,
> >> +					bool is_coherent)
> >>  {
> >>  	struct page **pages;
> >>  	int count = size >> PAGE_SHIFT;
> >> @@ -1154,7 +1167,7 @@ static struct page **__iommu_alloc_buffer(struct device *dev, size_t size,
> >>  		if (!page)
> >>  			goto error;
> >>  
> >> -		__dma_clear_buffer(page, size);
> >> +		__dma_clear_buffer(page, size, is_coherent);
> >>  
> >>  		for (i = 0; i < count; i++)
> >>  			pages[i] = page + i;
> >> @@ -1198,7 +1211,7 @@ static struct page **__iommu_alloc_buffer(struct device *dev, size_t size,
> >>  				pages[i + j] = pages[i] + j;
> >>  		}
> >>  
> >> -		__dma_clear_buffer(pages[i], PAGE_SIZE << order);
> >> +		__dma_clear_buffer(pages[i], PAGE_SIZE << order, is_coherent);
> >>  		i += 1 << order;
> >>  		count -= 1 << order;
> >>  	}
> >> @@ -1359,8 +1372,9 @@ static void __iommu_free_atomic(struct device *dev, void *cpu_addr,
> >>  	__free_from_pool(cpu_addr, size);
> >>  }
> >>  
> >> -static void *arm_iommu_alloc_attrs(struct device *dev, size_t size,
> >> -	    dma_addr_t *handle, gfp_t gfp, struct dma_attrs *attrs)
> >> +static void *__arm_iommu_alloc_attrs(struct device *dev, size_t size,
> >> +	    dma_addr_t *handle, gfp_t gfp, struct dma_attrs *attrs,
> >> +	    bool is_coherent)
> >>  {
> >>  	pgprot_t prot = __get_dma_pgprot(attrs, PAGE_KERNEL);
> >>  	struct page **pages;
> >> @@ -1381,7 +1395,7 @@ static void *arm_iommu_alloc_attrs(struct device *dev, size_t size,
> >>  	 */
> >>  	gfp &= ~(__GFP_COMP);
> >>  
> >> -	pages = __iommu_alloc_buffer(dev, size, gfp, attrs);
> >> +	pages = __iommu_alloc_buffer(dev, size, gfp, attrs, is_coherent);
> >>  	if (!pages)
> >>  		return NULL;
> >>  
> > 
> > I can see you are trying to fix the iommu_alloc code to cope with
> > coherent devices. I think it's currently broken and if you want to fix
> 
> Could you explain what is broken exactly?
> The way I tried to deal with coherency or something more low level?

The problem is that __iommu_alloc_atomic() allocates from a
non-cacheable pool, which is fine when the device is not cache coherent
but won't work as expected in the is_coherent case (the CPU and device
must access the memory using the same cacheability attributes).

> > In arm_iommu_alloc_attrs(), there is an __iommu_alloc_atomic() call
> > which goes to the non-cacheable pool, it should use
> > __alloc_simple_buffer() instead if is_coherent.
> 
> __iommu_alloc_atomic is called when GFP_WAIT is not set meaning that
> we can't sleep, but _alloc_simple_buffer can sleep. I follow the calls
> inside this function and at a point we found a call to the might_sleep_if
> macro:
> http://lxr.free-electrons.com/source/mm/page_alloc.c#L2859

This might sleep thing is:

	might_sleep_if(gfp_mask & __GFP_WAIT);

So it only sleeps if the __GFP_WAIT is set, but we would only call
__alloc_simple_buffer() in the !__GFP_WAIT case, so there is no
sleeping.

The reason to call __alloc_simple_buffer() (in the atomic alloc case) is
to get cacheable memory, unlike __alloc_from_pool() which only returns
memory from the non-cacheable pool.

> The _alloc_simple_buffer function ended by calling gen_pool_alloc
> which won't sleep so from my point of view it is still the right
> function to call. Did I miss something?

It's not just about sleep vs atomic but about cacheable vs non-cacheable
as well.

As a quick fix, below is what I meant. It needs extra snippets from your
patch to add arm_iommu_alloc_attrs_(coherent|noncoherent) and it's not
tested, but just to give you an idea:

diff --git a/arch/arm/mm/dma-mapping.c b/arch/arm/mm/dma-mapping.c
index 9f509b264346..e20a31d45ff3 100644
--- a/arch/arm/mm/dma-mapping.c
+++ b/arch/arm/mm/dma-mapping.c
@@ -1335,13 +1335,16 @@ static struct page **__iommu_get_pages(void *cpu_addr, struct dma_attrs *attrs)
 	return NULL;
 }
 
-static void *__iommu_alloc_atomic(struct device *dev, size_t size,
-				  dma_addr_t *handle)
+static void *__iommu_alloc_simple(struct device *dev, size_t size, gfp_t gfp,
+				  dma_addr_t *handle, bool is_coherent)
 {
 	struct page *page;
 	void *addr;
 
-	addr = __alloc_from_pool(size, &page);
+	if (is_coherent)
+		addr = __alloc_simple_buffer(dev, size, gfp, &page);
+	else
+		addr = __alloc_from_pool(size, &page);
 	if (!addr)
 		return NULL;
 
@@ -1356,15 +1359,18 @@ err_mapping:
 	return NULL;
 }
 
-static void __iommu_free_atomic(struct device *dev, void *cpu_addr,
-				dma_addr_t handle, size_t size)
+static void __iommu_free_simple(struct device *dev, void *cpu_addr,
+				dma_addr_t handle, size_t size, bool is_coherent)
 {
 	__iommu_remove_mapping(dev, handle, size);
-	__free_from_pool(cpu_addr, size);
+	if (is_coherent)
+		__dma_free_buffer(virt_to_page(cpu_addr), size);
+	else
+		__free_from_pool(cpu_addr, size);
 }
 
-static void *arm_iommu_alloc_attrs(struct device *dev, size_t size,
-	    dma_addr_t *handle, gfp_t gfp, struct dma_attrs *attrs)
+static void *__arm_iommu_alloc_attrs(struct device *dev, size_t size,
+	    dma_addr_t *handle, gfp_t gfp, struct dma_attrs *attrs, bool is_coherent)
 {
 	pgprot_t prot = __get_dma_pgprot(attrs, PAGE_KERNEL);
 	struct page **pages;
@@ -1373,8 +1379,8 @@ static void *arm_iommu_alloc_attrs(struct device *dev, size_t size,
 	*handle = DMA_ERROR_CODE;
 	size = PAGE_ALIGN(size);
 
-	if (!(gfp & __GFP_WAIT))
-		return __iommu_alloc_atomic(dev, size, handle);
+	if (is_coherent || !(gfp & __GFP_WAIT))
+		return __iommu_alloc_simple(dev, size, gfp, handle, is_coherent);
 
 	/*
 	 * Following is a work-around (a.k.a. hack) to prevent pages
@@ -1440,14 +1446,14 @@ static int arm_iommu_mmap_attrs(struct device *dev, struct vm_area_struct *vma,
  * free a page as defined by the above mapping.
  * Must not be called with IRQs disabled.
  */
-void arm_iommu_free_attrs(struct device *dev, size_t size, void *cpu_addr,
-			  dma_addr_t handle, struct dma_attrs *attrs)
+void __arm_iommu_free_attrs(struct device *dev, size_t size, void *cpu_addr,
+			  dma_addr_t handle, struct dma_attrs *attrs, bool is_coherent)
 {
 	struct page **pages;
 	size = PAGE_ALIGN(size);
 
-	if (__in_atomic_pool(cpu_addr, size)) {
-		__iommu_free_atomic(dev, cpu_addr, handle, size);
+	if (is_coherent || __in_atomic_pool(cpu_addr, size)) {
+		__iommu_free_simple(dev, cpu_addr, handle, size, is_coherent);
 		return;
 	}
 

-- 
Catalin


From l.stach at pengutronix.de  Fri Aug 14 07:20:59 2015
From: l.stach at pengutronix.de (Lucas Stach)
Date: Fri, 14 Aug 2015 16:20:59 +0200
Subject: [PATCH] ARM: keystone: add a work around to handle asynchronous
 external abort
In-Reply-To: <20150814140934.GX7557@n2100.arm.linux.org.uk>
References: <1439320409-20084-1-git-send-email-m-karicheri2@ti.com>
 <55CDF579.4050408@ti.com> <20150814140934.GX7557@n2100.arm.linux.org.uk>
Message-ID: <1439562059.13210.61.camel@pengutronix.de>

Hi Russell,

Am Freitag, den 14.08.2015, 15:09 +0100 schrieb Russell King - ARM
Linux:

[...]

> 
> What causes the abort?  We shouldn't be adding hacks like this to the
> kernel without having the full picture...
> 

some of the issues with tracking down such imprecise external aborts are
due to the fact that we only enable the signaling of those aborts on
entering the user-space. So the first schedule() crashes on the previous
dangling abort.

I'm carrying this patch locally to enable imprecise aborts much earlier
in the boot process. I think it has already been on the list some times,
but apparently it has fallen through the cracks. If you agree that this
is the right thing to do I can do a proper repost.

Regards,
Lucas

---------------------->8---------------------------------------------
>From bb9117d94cc2f1061dc364f42c446ccd9191e869 Mon Sep 17 00:00:00 2001
From: Lucas Stach <l.stach at pengutronix.de>
Date: Thu, 19 Feb 2015 18:12:50 +0100
Subject: [PATCH] ARM: Add imprecise abort enable/disable macro

This patch adds imprecise abort enable/disable macros.
It also enables imprecise aborts when starting kernel.

Changes in v2:
Only ARMv6 and later have CPSR.A bit. On earlier CPUs,
and ARMv7M this should be a no-op.

Signed-off-by: Fabrice Gasnier <fabrice.gasnier at st.com>
Signed-off-by: Lucas Stach <l.stach at pengutronix.de>
---
lst: rebased on v3.19
---
 arch/arm/include/asm/irqflags.h | 10 ++++++++++
 arch/arm/kernel/smp.c           |  1 +
 arch/arm/kernel/traps.c         |  4 ++++
 3 files changed, 15 insertions(+)

diff --git a/arch/arm/include/asm/irqflags.h
b/arch/arm/include/asm/irqflags.h
index 3b763d6652a0..8301f875564e 100644
--- a/arch/arm/include/asm/irqflags.h
+++ b/arch/arm/include/asm/irqflags.h
@@ -51,6 +51,14 @@ static inline void arch_local_irq_disable(void)
 
 #define local_fiq_enable()  __asm__("cpsie f   @ __stf" : : : "memory",
"cc")
 #define local_fiq_disable() __asm__("cpsid f   @ __clf" : : : "memory",
"cc")
+
+#ifndef CONFIG_CPU_V7M
+#define local_abt_enable()  __asm__("cpsie a   @ __sta" : : : "memory",
"cc")
+#define local_abt_disable() __asm__("cpsid a   @ __cla" : : : "memory",
"cc")
+#else
+#define local_abt_enable()     do { } while (0)
+#define local_abt_disable()    do { } while (0)
+#endif
 #else
 
 /*
@@ -130,6 +138,8 @@ static inline void arch_local_irq_disable(void)
        : "memory", "cc");                                      \
        })
 
+#define local_abt_enable()     do { } while (0)
+#define local_abt_disable()    do { } while (0)
 #endif
 
 /*
diff --git a/arch/arm/kernel/smp.c b/arch/arm/kernel/smp.c
index 86ef244c5a24..7b6b93cabef4 100644
--- a/arch/arm/kernel/smp.c
+++ b/arch/arm/kernel/smp.c
@@ -378,6 +378,7 @@ asmlinkage void secondary_start_kernel(void)
 
        local_irq_enable();
        local_fiq_enable();
+       local_abt_enable();
 
        /*
         * OK, it's off to the idle thread for us
diff --git a/arch/arm/kernel/traps.c b/arch/arm/kernel/traps.c
index 788e23fe64d8..466726ba9bdb 100644
--- a/arch/arm/kernel/traps.c
+++ b/arch/arm/kernel/traps.c
@@ -881,6 +881,10 @@ void __init early_trap_init(void *vectors_base)
 
        flush_icache_range(vectors, vectors + PAGE_SIZE * 2);
        modify_domain(DOMAIN_USER, DOMAIN_CLIENT);
+
+       /* Enable imprecise aborts */
+       local_abt_enable();
+
 #else /* ifndef CONFIG_CPU_V7M */
        /*
         * on V7-M there is no need to copy the vector table to a
dedicated
-- 
2.1.4

-- 
Pengutronix e.K.             | Lucas Stach                 |
Industrial Linux Solutions   | http://www.pengutronix.de/  |



From mpa at pengutronix.de  Fri Aug 14 07:11:03 2015
From: mpa at pengutronix.de (Markus Pargmann)
Date: Fri, 14 Aug 2015 16:11:03 +0200
Subject: [PATCH v3 6/9] gpiolib-sysfs: Show gpio-name in
 /sys/class/gpio/gpio*/name
In-Reply-To: <1439561466-14350-1-git-send-email-mpa@pengutronix.de>
References: <1439561466-14350-1-git-send-email-mpa@pengutronix.de>
Message-ID: <1439561466-14350-7-git-send-email-mpa@pengutronix.de>

This patch adds a sysfs attribute 'name' to gpios that were exported. It
exposes the newly added name property of gpio descriptors.

Signed-off-by: Markus Pargmann <mpa at pengutronix.de>
---
 drivers/gpio/gpiolib-sysfs.c | 12 ++++++++++++
 1 file changed, 12 insertions(+)

diff --git a/drivers/gpio/gpiolib-sysfs.c b/drivers/gpio/gpiolib-sysfs.c
index 3e81f28e3aee..2022cfb00aeb 100644
--- a/drivers/gpio/gpiolib-sysfs.c
+++ b/drivers/gpio/gpiolib-sysfs.c
@@ -139,6 +139,17 @@ static ssize_t value_store(struct device *dev,
 }
 static DEVICE_ATTR_RW(value);
 
+static ssize_t name_show(struct device *dev, struct device_attribute *attr,
+			 char *buf)
+{
+	struct gpiod_data *data = dev_get_drvdata(dev);
+	struct gpio_desc *desc = data->desc;
+
+	return sprintf(buf, "%s\n", desc->name ? : "");
+}
+
+static DEVICE_ATTR_RO(name);
+
 static irqreturn_t gpio_sysfs_irq(int irq, void *priv)
 {
 	struct gpiod_data *data = priv;
@@ -377,6 +388,7 @@ static struct attribute *gpio_attrs[] = {
 	&dev_attr_edge.attr,
 	&dev_attr_value.attr,
 	&dev_attr_active_low.attr,
+	&dev_attr_name.attr,
 	NULL,
 };
 
-- 
2.4.6



From tiwai at suse.de  Fri Aug 14 07:34:07 2015
From: tiwai at suse.de (Takashi Iwai)
Date: Fri, 14 Aug 2015 16:34:07 +0200
Subject: [alsa-devel] [PATCH v2 1/9] drm: bridge/dw_hdmi-ahb-audio:
 add	audio driver
In-Reply-To: <E1ZQFar-0003cx-RU@rmk-PC.arm.linux.org.uk>
References: <s5hk2t35ui4.wl-tiwai@suse.de>
 <E1ZQFar-0003cx-RU@rmk-PC.arm.linux.org.uk>
Message-ID: <s5h614iszvk.wl-tiwai@suse.de>

On Fri, 14 Aug 2015 16:04:25 +0200,
Russell King wrote:
> 
> Add ALSA based HDMI AHB audio driver for dw_hdmi.  The only buffer
> format supported by the hardware is its own special IEC958 based format,
> which is not compatible with any ALSA format.  To avoid doing too much
> data manipulation within the driver, we support only ALSAs IEC958 LE and
> 24-bit PCM formats for 2 to 6 channels, which we convert to its hardware
> format.
> 
> A more desirable solution would be to have this conversion in userspace,
> but ALSA does not appear to allow such transformations outside of
> libasound itself.
> 
> Signed-off-by: Russell King <rmk+kernel at arm.linux.org.uk>
> ---
> v2: updated with Takashi Iwai's comments... and with a fixed Cc: line.

Reviewed-by: Takashi Iwai <tiwai at suse.de>


thanks,

Takashi


>  drivers/gpu/drm/bridge/Kconfig             |  10 +
>  drivers/gpu/drm/bridge/Makefile            |   1 +
>  drivers/gpu/drm/bridge/dw_hdmi-ahb-audio.c | 579 +++++++++++++++++++++++++++++
>  drivers/gpu/drm/bridge/dw_hdmi-audio.h     |  13 +
>  drivers/gpu/drm/bridge/dw_hdmi.c           |  24 ++
>  drivers/gpu/drm/bridge/dw_hdmi.h           |   3 +
>  6 files changed, 630 insertions(+)
>  create mode 100644 drivers/gpu/drm/bridge/dw_hdmi-ahb-audio.c
>  create mode 100644 drivers/gpu/drm/bridge/dw_hdmi-audio.h
> 
> diff --git a/drivers/gpu/drm/bridge/Kconfig b/drivers/gpu/drm/bridge/Kconfig
> index acef3223772c..56ed35fe0734 100644
> --- a/drivers/gpu/drm/bridge/Kconfig
> +++ b/drivers/gpu/drm/bridge/Kconfig
> @@ -3,6 +3,16 @@ config DRM_DW_HDMI
>  	depends on DRM
>  	select DRM_KMS_HELPER
>  
> +config DRM_DW_HDMI_AHB_AUDIO
> +	tristate "Synopsis Designware AHB Audio interface"
> +	depends on DRM_DW_HDMI && SND
> +	select SND_PCM
> +	select SND_PCM_IEC958
> +	help
> +	  Support the AHB Audio interface which is part of the Synopsis
> +	  Designware HDMI block.  This is used in conjunction with
> +	  the i.MX6 HDMI driver.
> +
>  config DRM_PTN3460
>  	tristate "PTN3460 DP/LVDS bridge"
>  	depends on DRM
> diff --git a/drivers/gpu/drm/bridge/Makefile b/drivers/gpu/drm/bridge/Makefile
> index 8dfebd984370..eb80dbbb8365 100644
> --- a/drivers/gpu/drm/bridge/Makefile
> +++ b/drivers/gpu/drm/bridge/Makefile
> @@ -3,3 +3,4 @@ ccflags-y := -Iinclude/drm
>  obj-$(CONFIG_DRM_PS8622) += ps8622.o
>  obj-$(CONFIG_DRM_PTN3460) += ptn3460.o
>  obj-$(CONFIG_DRM_DW_HDMI) += dw_hdmi.o
> +obj-$(CONFIG_DRM_DW_HDMI_AHB_AUDIO) += dw_hdmi-ahb-audio.o
> diff --git a/drivers/gpu/drm/bridge/dw_hdmi-ahb-audio.c b/drivers/gpu/drm/bridge/dw_hdmi-ahb-audio.c
> new file mode 100644
> index 000000000000..bf379310008a
> --- /dev/null
> +++ b/drivers/gpu/drm/bridge/dw_hdmi-ahb-audio.c
> @@ -0,0 +1,579 @@
> +/*
> + * DesignWare HDMI audio driver
> + *
> + * 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.
> + *
> + * Written and tested against the Designware HDMI Tx found in iMX6.
> + */
> +#include <linux/io.h>
> +#include <linux/interrupt.h>
> +#include <linux/module.h>
> +#include <linux/platform_device.h>
> +#include <drm/bridge/dw_hdmi.h>
> +
> +#include <sound/asoundef.h>
> +#include <sound/core.h>
> +#include <sound/initval.h>
> +#include <sound/pcm.h>
> +#include <sound/pcm_iec958.h>
> +
> +#include "dw_hdmi-audio.h"
> +
> +#define DRIVER_NAME "dw-hdmi-ahb-audio"
> +
> +/* Provide some bits rather than bit offsets */
> +enum {
> +	HDMI_AHB_DMA_CONF0_SW_FIFO_RST = BIT(7),
> +	HDMI_AHB_DMA_CONF0_EN_HLOCK = BIT(3),
> +	HDMI_AHB_DMA_START_START = BIT(0),
> +	HDMI_AHB_DMA_STOP_STOP = BIT(0),
> +	HDMI_IH_MUTE_AHBDMAAUD_STAT0_ERROR = BIT(5),
> +	HDMI_IH_MUTE_AHBDMAAUD_STAT0_LOST = BIT(4),
> +	HDMI_IH_MUTE_AHBDMAAUD_STAT0_RETRY = BIT(3),
> +	HDMI_IH_MUTE_AHBDMAAUD_STAT0_DONE = BIT(2),
> +	HDMI_IH_MUTE_AHBDMAAUD_STAT0_BUFFFULL = BIT(1),
> +	HDMI_IH_MUTE_AHBDMAAUD_STAT0_BUFFEMPTY = BIT(0),
> +	HDMI_IH_MUTE_AHBDMAAUD_STAT0_ALL =
> +		HDMI_IH_MUTE_AHBDMAAUD_STAT0_ERROR |
> +		HDMI_IH_MUTE_AHBDMAAUD_STAT0_LOST |
> +		HDMI_IH_MUTE_AHBDMAAUD_STAT0_RETRY |
> +		HDMI_IH_MUTE_AHBDMAAUD_STAT0_DONE |
> +		HDMI_IH_MUTE_AHBDMAAUD_STAT0_BUFFFULL |
> +		HDMI_IH_MUTE_AHBDMAAUD_STAT0_BUFFEMPTY,
> +	HDMI_IH_AHBDMAAUD_STAT0_ERROR = BIT(5),
> +	HDMI_IH_AHBDMAAUD_STAT0_LOST = BIT(4),
> +	HDMI_IH_AHBDMAAUD_STAT0_RETRY = BIT(3),
> +	HDMI_IH_AHBDMAAUD_STAT0_DONE = BIT(2),
> +	HDMI_IH_AHBDMAAUD_STAT0_BUFFFULL = BIT(1),
> +	HDMI_IH_AHBDMAAUD_STAT0_BUFFEMPTY = BIT(0),
> +	HDMI_IH_AHBDMAAUD_STAT0_ALL =
> +		HDMI_IH_AHBDMAAUD_STAT0_ERROR |
> +		HDMI_IH_AHBDMAAUD_STAT0_LOST |
> +		HDMI_IH_AHBDMAAUD_STAT0_RETRY |
> +		HDMI_IH_AHBDMAAUD_STAT0_DONE |
> +		HDMI_IH_AHBDMAAUD_STAT0_BUFFFULL |
> +		HDMI_IH_AHBDMAAUD_STAT0_BUFFEMPTY,
> +	HDMI_AHB_DMA_CONF0_INCR16 = 2 << 1,
> +	HDMI_AHB_DMA_CONF0_INCR8 = 1 << 1,
> +	HDMI_AHB_DMA_CONF0_INCR4 = 0,
> +	HDMI_AHB_DMA_CONF0_BURST_MODE = BIT(0),
> +	HDMI_AHB_DMA_MASK_DONE = BIT(7),
> +	HDMI_REVISION_ID = 0x0001,
> +	HDMI_IH_AHBDMAAUD_STAT0 = 0x0109,
> +	HDMI_IH_MUTE_AHBDMAAUD_STAT0 = 0x0189,
> +	HDMI_AHB_DMA_CONF0 = 0x3600,
> +	HDMI_AHB_DMA_START = 0x3601,
> +	HDMI_AHB_DMA_STOP = 0x3602,
> +	HDMI_AHB_DMA_THRSLD = 0x3603,
> +	HDMI_AHB_DMA_STRADDR0 = 0x3604,
> +	HDMI_AHB_DMA_STPADDR0 = 0x3608,
> +	HDMI_AHB_DMA_MASK = 0x3614,
> +	HDMI_AHB_DMA_POL = 0x3615,
> +	HDMI_AHB_DMA_CONF1 = 0x3616,
> +	HDMI_AHB_DMA_BUFFPOL = 0x361a,
> +};
> +
> +struct snd_dw_hdmi {
> +	struct snd_card *card;
> +	struct snd_pcm *pcm;
> +	spinlock_t lock;
> +	struct dw_hdmi_audio_data data;
> +	struct snd_pcm_substream *substream;
> +	void (*reformat)(struct snd_dw_hdmi *, size_t, size_t);
> +	void *buf_src;
> +	void *buf_dst;
> +	dma_addr_t buf_addr;
> +	unsigned buf_offset;
> +	unsigned buf_period;
> +	unsigned buf_size;
> +	unsigned channels;
> +	u8 revision;
> +	u8 iec_offset;
> +	u8 cs[192][8];
> +};
> +
> +static void dw_hdmi_writel(u32 val, void __iomem *ptr)
> +{
> +	writeb_relaxed(val, ptr);
> +	writeb_relaxed(val >> 8, ptr + 1);
> +	writeb_relaxed(val >> 16, ptr + 2);
> +	writeb_relaxed(val >> 24, ptr + 3);
> +}
> +
> +/*
> + * Convert to hardware format: The userspace buffer contains IEC958 samples,
> + * with the PCUV bits in bits 31..28 and audio samples in bits 27..4.  We
> + * need these to be in bits 27..24, with the IEC B bit in bit 28, and audio
> + * samples in 23..0.
> + *
> + * Default preamble in bits 3..0: 8 = block start, 4 = even 2 = odd
> + *
> + * Ideally, we could do with having the data properly formatted in userspace.
> + */
> +static void dw_hdmi_reformat_iec958(struct snd_dw_hdmi *dw,
> +	size_t offset, size_t bytes)
> +{
> +	u32 *src = dw->buf_src + offset;
> +	u32 *dst = dw->buf_dst + offset;
> +	u32 *end = dw->buf_src + offset + bytes;
> +
> +	do {
> +		u32 b, sample = *src++;
> +
> +		b = (sample & 8) << (28 - 3);
> +
> +		sample >>= 4;
> +
> +		*dst++ = sample | b;
> +	} while (src < end);
> +}
> +
> +static u32 parity(u32 sample)
> +{
> +	sample ^= sample >> 16;
> +	sample ^= sample >> 8;
> +	sample ^= sample >> 4;
> +	sample ^= sample >> 2;
> +	sample ^= sample >> 1;
> +	return (sample & 1) << 27;
> +}
> +
> +static void dw_hdmi_reformat_s24(struct snd_dw_hdmi *dw,
> +	size_t offset, size_t bytes)
> +{
> +	u32 *src = dw->buf_src + offset;
> +	u32 *dst = dw->buf_dst + offset;
> +	u32 *end = dw->buf_src + offset + bytes;
> +
> +	do {
> +		unsigned i;
> +		u8 *cs;
> +
> +		cs = dw->cs[dw->iec_offset++];
> +		if (dw->iec_offset >= 192)
> +			dw->iec_offset = 0;
> +
> +		i = dw->channels;
> +		do {
> +			u32 sample = *src++;
> +
> +			sample &= ~0xff000000;
> +			sample |= *cs++ << 24;
> +			sample |= parity(sample & ~0xf8000000);
> +
> +			*dst++ = sample;
> +		} while (--i);
> +	} while (src < end);
> +}
> +
> +static void dw_hdmi_create_cs(struct snd_dw_hdmi *dw,
> +	struct snd_pcm_runtime *runtime)
> +{
> +	u8 cs[4];
> +	unsigned ch, i, j;
> +
> +	snd_pcm_create_iec958_consumer(runtime, cs, sizeof(cs));
> +
> +	memset(dw->cs, 0, sizeof(dw->cs));
> +
> +	for (ch = 0; ch < 8; ch++) {
> +		cs[2] &= ~IEC958_AES2_CON_CHANNEL;
> +		cs[2] |= (ch + 1) << 4;
> +
> +		for (i = 0; i < ARRAY_SIZE(cs); i++) {
> +			unsigned c = cs[i];
> +
> +			for (j = 0; j < 8; j++, c >>= 1)
> +				dw->cs[i * 8 + j][ch] = (c & 1) << 2;
> +		}
> +	}
> +	dw->cs[0][0] |= BIT(4);
> +}
> +
> +static void dw_hdmi_start_dma(struct snd_dw_hdmi *dw)
> +{
> +	void __iomem *base = dw->data.base;
> +	unsigned offset = dw->buf_offset;
> +	unsigned period = dw->buf_period;
> +	u32 start, stop;
> +
> +	dw->reformat(dw, offset, period);
> +
> +	/* Clear all irqs before enabling irqs and starting DMA */
> +	writeb_relaxed(HDMI_IH_AHBDMAAUD_STAT0_ALL,
> +		       base + HDMI_IH_AHBDMAAUD_STAT0);
> +
> +	start = dw->buf_addr + offset;
> +	stop = start + period - 1;
> +
> +	/* Setup the hardware start/stop addresses */
> +	dw_hdmi_writel(start, base + HDMI_AHB_DMA_STRADDR0);
> +	dw_hdmi_writel(stop, base + HDMI_AHB_DMA_STPADDR0);
> +
> +	writeb_relaxed((u8)~HDMI_AHB_DMA_MASK_DONE, base + HDMI_AHB_DMA_MASK);
> +	writeb(HDMI_AHB_DMA_START_START, base + HDMI_AHB_DMA_START);
> +
> +	offset += period;
> +	if (offset >= dw->buf_size)
> +		offset = 0;
> +	dw->buf_offset = offset;
> +}
> +
> +static void dw_hdmi_stop_dma(struct snd_dw_hdmi *dw)
> +{
> +	/* Disable interrupts before disabling DMA */
> +	writeb_relaxed(~0, dw->data.base + HDMI_AHB_DMA_MASK);
> +	writeb_relaxed(HDMI_AHB_DMA_STOP_STOP, dw->data.base + HDMI_AHB_DMA_STOP);
> +}
> +
> +static irqreturn_t snd_dw_hdmi_irq(int irq, void *data)
> +{
> +	struct snd_dw_hdmi *dw = data;
> +	struct snd_pcm_substream *substream;
> +	unsigned stat;
> +
> +	stat = readb_relaxed(dw->data.base + HDMI_IH_AHBDMAAUD_STAT0);
> +	if (!stat)
> +		return IRQ_NONE;
> +
> +	writeb_relaxed(stat, dw->data.base + HDMI_IH_AHBDMAAUD_STAT0);
> +
> +	substream = dw->substream;
> +	if (stat & HDMI_IH_AHBDMAAUD_STAT0_DONE && substream) {
> +		snd_pcm_period_elapsed(substream);
> +
> +		spin_lock(&dw->lock);
> +		if (dw->substream)
> +			dw_hdmi_start_dma(dw);
> +		spin_unlock(&dw->lock);
> +	}
> +
> +	return IRQ_HANDLED;
> +}
> +
> +static struct snd_pcm_hardware dw_hdmi_hw = {
> +	.info = SNDRV_PCM_INFO_INTERLEAVED |
> +		SNDRV_PCM_INFO_BLOCK_TRANSFER |
> +		SNDRV_PCM_INFO_MMAP |
> +		SNDRV_PCM_INFO_MMAP_VALID,
> +	.formats = SNDRV_PCM_FMTBIT_IEC958_SUBFRAME_LE |
> +		   SNDRV_PCM_FMTBIT_S24_LE,
> +	.rates = SNDRV_PCM_RATE_32000 |
> +		 SNDRV_PCM_RATE_44100 |
> +		 SNDRV_PCM_RATE_48000 |
> +		 SNDRV_PCM_RATE_88200 |
> +		 SNDRV_PCM_RATE_96000 |
> +		 SNDRV_PCM_RATE_176400 |
> +		 SNDRV_PCM_RATE_192000,
> +	.channels_min = 2,
> +	.channels_max = 8,
> +	.buffer_bytes_max = 64 * 1024,
> +	.period_bytes_min = 256,
> +	.period_bytes_max = 8192,	/* ERR004323: must limit to 8k */
> +	.periods_min = 2,
> +	.periods_max = 16,
> +	.fifo_size = 0,
> +};
> +
> +static int dw_hdmi_open(struct snd_pcm_substream *substream)
> +{
> +	struct snd_pcm_runtime *runtime = substream->runtime;
> +	struct snd_dw_hdmi *dw = substream->private_data;
> +	void __iomem *base = dw->data.base;
> +	int ret;
> +
> +	runtime->hw = dw_hdmi_hw;
> +
> +	ret = snd_pcm_limit_hw_rates(runtime);
> +	if (ret < 0)
> +		return ret;
> +
> +	ret = snd_pcm_hw_constraint_integer(runtime, SNDRV_PCM_HW_PARAM_PERIODS);
> +	if (ret < 0)
> +		return ret;
> +
> +	/* Clear FIFO */
> +	writeb_relaxed(HDMI_AHB_DMA_CONF0_SW_FIFO_RST,
> +		       base + HDMI_AHB_DMA_CONF0);
> +
> +	/* Configure interrupt polarities */
> +	writeb_relaxed(~0, base + HDMI_AHB_DMA_POL);
> +	writeb_relaxed(~0, base + HDMI_AHB_DMA_BUFFPOL);
> +
> +	/* Keep interrupts masked, and clear any pending */
> +	writeb_relaxed(~0, base + HDMI_AHB_DMA_MASK);
> +	writeb_relaxed(~0, base + HDMI_IH_AHBDMAAUD_STAT0);
> +
> +	ret = request_irq(dw->data.irq, snd_dw_hdmi_irq, IRQF_SHARED,
> +			  "dw-hdmi-audio", dw);
> +	if (ret)
> +		return ret;
> +
> +	/* Un-mute done interrupt */
> +	writeb_relaxed(HDMI_IH_MUTE_AHBDMAAUD_STAT0_ALL &
> +		       ~HDMI_IH_MUTE_AHBDMAAUD_STAT0_DONE,
> +		       base + HDMI_IH_MUTE_AHBDMAAUD_STAT0);
> +
> +	return 0;
> +}
> +
> +static int dw_hdmi_close(struct snd_pcm_substream *substream)
> +{
> +	struct snd_dw_hdmi *dw = substream->private_data;
> +
> +	/* Mute all interrupts */
> +	writeb_relaxed(HDMI_IH_MUTE_AHBDMAAUD_STAT0_ALL,
> +		       dw->data.base + HDMI_IH_MUTE_AHBDMAAUD_STAT0);
> +
> +	free_irq(dw->data.irq, dw);
> +
> +	return 0;
> +}
> +
> +static int dw_hdmi_hw_free(struct snd_pcm_substream *substream)
> +{
> +	return snd_pcm_lib_free_vmalloc_buffer(substream);
> +}
> +
> +static int dw_hdmi_hw_params(struct snd_pcm_substream *substream,
> +	struct snd_pcm_hw_params *params)
> +{
> +	return snd_pcm_lib_alloc_vmalloc_buffer(substream,
> +						params_buffer_bytes(params));
> +}
> +
> +static int dw_hdmi_prepare(struct snd_pcm_substream *substream)
> +{
> +	struct snd_pcm_runtime *runtime = substream->runtime;
> +	struct snd_dw_hdmi *dw = substream->private_data;
> +	u8 threshold, conf0, conf1;
> +
> +	/* Setup as per 3.0.5 FSL 4.1.0 BSP */
> +	switch (dw->revision) {
> +	case 0x0a:
> +		conf0 = HDMI_AHB_DMA_CONF0_BURST_MODE |
> +			HDMI_AHB_DMA_CONF0_INCR4;
> +		if (runtime->channels == 2)
> +			threshold = 126;
> +		else
> +			threshold = 124;
> +		break;
> +	case 0x1a:
> +		conf0 = HDMI_AHB_DMA_CONF0_BURST_MODE |
> +			HDMI_AHB_DMA_CONF0_INCR8;
> +		threshold = 128;
> +		break;
> +	default:
> +		/* NOTREACHED */
> +		return -EINVAL;
> +	}
> +
> +	dw_hdmi_set_sample_rate(dw->data.hdmi, runtime->rate);
> +
> +	/* Minimum number of bytes in the fifo. */
> +	runtime->hw.fifo_size = threshold * 32;
> +
> +	conf0 |= HDMI_AHB_DMA_CONF0_EN_HLOCK;
> +	conf1 = (1 << runtime->channels) - 1;
> +
> +	writeb_relaxed(threshold, dw->data.base + HDMI_AHB_DMA_THRSLD);
> +	writeb_relaxed(conf0, dw->data.base + HDMI_AHB_DMA_CONF0);
> +	writeb_relaxed(conf1, dw->data.base + HDMI_AHB_DMA_CONF1);
> +
> +	switch (runtime->format) {
> +	case SNDRV_PCM_FORMAT_IEC958_SUBFRAME_LE:
> +		dw->reformat = dw_hdmi_reformat_iec958;
> +		break;
> +	case SNDRV_PCM_FORMAT_S24_LE:
> +		dw_hdmi_create_cs(dw, runtime);
> +		dw->reformat = dw_hdmi_reformat_s24;
> +		break;
> +	}
> +	dw->iec_offset = 0;
> +	dw->channels = runtime->channels;
> +	dw->buf_src  = runtime->dma_area;
> +	dw->buf_dst  = substream->dma_buffer.area;
> +	dw->buf_addr = substream->dma_buffer.addr;
> +	dw->buf_period = snd_pcm_lib_period_bytes(substream);
> +	dw->buf_size = snd_pcm_lib_buffer_bytes(substream);
> +
> +	return 0;
> +}
> +
> +static int dw_hdmi_trigger(struct snd_pcm_substream *substream, int cmd)
> +{
> +	struct snd_dw_hdmi *dw = substream->private_data;
> +	unsigned long flags;
> +	int ret = 0;
> +
> +	switch (cmd) {
> +	case SNDRV_PCM_TRIGGER_START:
> +		spin_lock_irqsave(&dw->lock, flags);
> +		dw->buf_offset = 0;
> +		dw->substream = substream;
> +		dw_hdmi_start_dma(dw);
> +		dw_hdmi_audio_enable(dw->data.hdmi);
> +		spin_unlock_irqrestore(&dw->lock, flags);
> +		substream->runtime->delay = substream->runtime->period_size;
> +		break;
> +
> +	case SNDRV_PCM_TRIGGER_STOP:
> +		spin_lock_irqsave(&dw->lock, flags);
> +		dw->substream = NULL;
> +		dw_hdmi_stop_dma(dw);
> +		dw_hdmi_audio_disable(dw->data.hdmi);
> +		spin_unlock_irqrestore(&dw->lock, flags);
> +		break;
> +
> +	default:
> +		ret = -EINVAL;
> +		break;
> +	}
> +
> +	return ret;
> +}
> +
> +static snd_pcm_uframes_t dw_hdmi_pointer(struct snd_pcm_substream *substream)
> +{
> +	struct snd_pcm_runtime *runtime = substream->runtime;
> +	struct snd_dw_hdmi *dw = substream->private_data;
> +
> +	/*
> +	 * We are unable to report the exact hardware position as
> +	 * reading the 32-bit DMA position using 8-bit reads is racy.
> +	 */
> +	return bytes_to_frames(runtime, dw->buf_offset);
> +}
> +
> +static struct snd_pcm_ops snd_dw_hdmi_ops = {
> +	.open = dw_hdmi_open,
> +	.close = dw_hdmi_close,
> +	.ioctl = snd_pcm_lib_ioctl,
> +	.hw_params = dw_hdmi_hw_params,
> +	.hw_free = dw_hdmi_hw_free,
> +	.prepare = dw_hdmi_prepare,
> +	.trigger = dw_hdmi_trigger,
> +	.pointer = dw_hdmi_pointer,
> +	.page = snd_pcm_lib_get_vmalloc_page,
> +};
> +
> +static int snd_dw_hdmi_probe(struct platform_device *pdev)
> +{
> +	const struct dw_hdmi_audio_data *data = pdev->dev.platform_data;
> +	struct device *dev = pdev->dev.parent;
> +	struct snd_dw_hdmi *dw;
> +	struct snd_card *card;
> +	struct snd_pcm *pcm;
> +	unsigned revision;
> +	int ret;
> +
> +	writeb_relaxed(HDMI_IH_MUTE_AHBDMAAUD_STAT0_ALL,
> +		       data->base + HDMI_IH_MUTE_AHBDMAAUD_STAT0);
> +	revision = readb_relaxed(data->base + HDMI_REVISION_ID);
> +	if (revision != 0x0a && revision != 0x1a) {
> +		dev_err(dev, "dw-hdmi-audio: unknown revision 0x%02x\n",
> +			revision);
> +		return -ENXIO;
> +	}
> +
> +	ret = snd_card_new(dev, SNDRV_DEFAULT_IDX1, SNDRV_DEFAULT_STR1,
> +			      THIS_MODULE, sizeof(struct snd_dw_hdmi), &card);
> +	if (ret < 0)
> +		return ret;
> +
> +	strlcpy(card->driver, DRIVER_NAME, sizeof(card->driver));
> +	strlcpy(card->shortname, "DW-HDMI", sizeof(card->shortname));
> +	snprintf(card->longname, sizeof(card->longname),
> +		 "%s rev 0x%02x, irq %d", card->shortname, revision,
> +		 data->irq);
> +
> +	dw = card->private_data;
> +	dw->card = card;
> +	dw->data = *data;
> +	dw->revision = revision;
> +
> +	spin_lock_init(&dw->lock);
> +
> +	ret = snd_pcm_new(card, "DW HDMI", 0, 1, 0, &pcm);
> +	if (ret < 0)
> +		goto err;
> +
> +	dw->pcm = pcm;
> +	pcm->private_data = dw;
> +	strlcpy(pcm->name, DRIVER_NAME, sizeof(pcm->name));
> +	snd_pcm_set_ops(pcm, SNDRV_PCM_STREAM_PLAYBACK, &snd_dw_hdmi_ops);
> +
> +	snd_pcm_lib_preallocate_pages_for_all(pcm, SNDRV_DMA_TYPE_DEV,
> +			dev, 64 * 1024, 64 * 1024);
> +
> +	ret = snd_card_register(card);
> +	if (ret < 0)
> +		goto err;
> +
> +	platform_set_drvdata(pdev, dw);
> +
> +	return 0;
> +
> +err:
> +	snd_card_free(card);
> +	return ret;
> +}
> +
> +static int snd_dw_hdmi_remove(struct platform_device *pdev)
> +{
> +	struct snd_dw_hdmi *dw = platform_get_drvdata(pdev);
> +
> +	snd_card_free(dw->card);
> +
> +	return 0;
> +}
> +
> +#if defined(CONFIG_PM_SLEEP) && defined(IS_NOT_BROKEN)
> +/*
> + * This code is fine, but requires implementation in the dw_hdmi_trigger()
> + * method which is currently missing as I have no way to test this.
> + */
> +static int snd_dw_hdmi_suspend(struct device *dev)
> +{
> +	struct snd_dw_hdmi *dw = dev_get_drvdata(dev);
> +
> +	snd_power_change_state(dw->card, SNDRV_CTL_POWER_D3cold);
> +	snd_pcm_suspend_all(dw->pcm);
> +
> +	return 0;
> +}
> +
> +static int snd_dw_hdmi_resume(struct device *dev)
> +{
> +	struct snd_dw_hdmi *dw = dev_get_drvdata(dev);
> +
> +	snd_power_change_state(dw->card, SNDRV_CTL_POWER_D0);
> +
> +	return 0;
> +}
> +
> +static SIMPLE_DEV_PM_OPS(snd_dw_hdmi_pm, snd_dw_hdmi_suspend,
> +			 snd_dw_hdmi_resume);
> +#define PM_OPS &snd_dw_hdmi_pm
> +#else
> +#define PM_OPS NULL
> +#endif
> +
> +static struct platform_driver snd_dw_hdmi_driver = {
> +	.probe	= snd_dw_hdmi_probe,
> +	.remove	= snd_dw_hdmi_remove,
> +	.driver	= {
> +		.name = DRIVER_NAME,
> +		.owner = THIS_MODULE,
> +		.pm = PM_OPS,
> +	},
> +};
> +
> +module_platform_driver(snd_dw_hdmi_driver);
> +
> +MODULE_AUTHOR("Russell King <rmk+kernel at arm.linux.org.uk>");
> +MODULE_DESCRIPTION("Synopsis Designware HDMI AHB ALSA interface");
> +MODULE_LICENSE("GPL v2");
> +MODULE_ALIAS("platform:" DRIVER_NAME);
> diff --git a/drivers/gpu/drm/bridge/dw_hdmi-audio.h b/drivers/gpu/drm/bridge/dw_hdmi-audio.h
> new file mode 100644
> index 000000000000..1e840118d90a
> --- /dev/null
> +++ b/drivers/gpu/drm/bridge/dw_hdmi-audio.h
> @@ -0,0 +1,13 @@
> +#ifndef DW_HDMI_AUDIO_H
> +#define DW_HDMI_AUDIO_H
> +
> +struct dw_hdmi;
> +
> +struct dw_hdmi_audio_data {
> +	phys_addr_t phys;
> +	void __iomem *base;
> +	int irq;
> +	struct dw_hdmi *hdmi;
> +};
> +
> +#endif
> diff --git a/drivers/gpu/drm/bridge/dw_hdmi.c b/drivers/gpu/drm/bridge/dw_hdmi.c
> index fba25607ef88..b65464789fbd 100644
> --- a/drivers/gpu/drm/bridge/dw_hdmi.c
> +++ b/drivers/gpu/drm/bridge/dw_hdmi.c
> @@ -28,6 +28,7 @@
>  #include <drm/bridge/dw_hdmi.h>
>  
>  #include "dw_hdmi.h"
> +#include "dw_hdmi-audio.h"
>  
>  #define HDMI_EDID_LEN		512
>  
> @@ -104,6 +105,7 @@ struct dw_hdmi {
>  	struct drm_encoder *encoder;
>  	struct drm_bridge *bridge;
>  
> +	struct platform_device *audio;
>  	enum dw_hdmi_devtype dev_type;
>  	struct device *dev;
>  	struct clk *isfr_clk;
> @@ -1732,7 +1734,9 @@ int dw_hdmi_bind(struct device *dev, struct device *master,
>  {
>  	struct drm_device *drm = data;
>  	struct device_node *np = dev->of_node;
> +	struct platform_device_info pdevinfo;
>  	struct device_node *ddc_node;
> +	struct dw_hdmi_audio_data audio;
>  	struct dw_hdmi *hdmi;
>  	int ret;
>  	u32 val = 1;
> @@ -1860,6 +1864,23 @@ int dw_hdmi_bind(struct device *dev, struct device *master,
>  	hdmi_writeb(hdmi, ~(HDMI_IH_PHY_STAT0_HPD | HDMI_IH_PHY_STAT0_RX_SENSE),
>  		    HDMI_IH_MUTE_PHY_STAT0);
>  
> +	memset(&pdevinfo, 0, sizeof(pdevinfo));
> +	pdevinfo.parent = dev;
> +	pdevinfo.id = PLATFORM_DEVID_AUTO;
> +
> +	if (hdmi_readb(hdmi, HDMI_CONFIG1_ID) & HDMI_CONFIG1_AHB) {
> +		audio.phys = iores->start;
> +		audio.base = hdmi->regs;
> +		audio.irq = irq;
> +		audio.hdmi = hdmi;
> +
> +		pdevinfo.name = "dw-hdmi-ahb-audio";
> +		pdevinfo.data = &audio;
> +		pdevinfo.size_data = sizeof(audio);
> +		pdevinfo.dma_mask = DMA_BIT_MASK(32);
> +		hdmi->audio = platform_device_register_full(&pdevinfo);
> +	}
> +
>  	dev_set_drvdata(dev, hdmi);
>  
>  	return 0;
> @@ -1877,6 +1898,9 @@ void dw_hdmi_unbind(struct device *dev, struct device *master, void *data)
>  {
>  	struct dw_hdmi *hdmi = dev_get_drvdata(dev);
>  
> +	if (hdmi->audio && !IS_ERR(hdmi->audio))
> +		platform_device_unregister(hdmi->audio);
> +
>  	/* Disable all interrupts */
>  	hdmi_writeb(hdmi, ~0, HDMI_IH_MUTE_PHY_STAT0);
>  
> diff --git a/drivers/gpu/drm/bridge/dw_hdmi.h b/drivers/gpu/drm/bridge/dw_hdmi.h
> index 175dbc89a824..78e54e813212 100644
> --- a/drivers/gpu/drm/bridge/dw_hdmi.h
> +++ b/drivers/gpu/drm/bridge/dw_hdmi.h
> @@ -545,6 +545,9 @@
>  #define HDMI_I2CM_FS_SCL_LCNT_0_ADDR            0x7E12
>  
>  enum {
> +/* CONFIG1_ID field values */
> +	HDMI_CONFIG1_AHB = 0x01,
> +
>  /* IH_FC_INT2 field values */
>  	HDMI_IH_FC_INT2_OVERFLOW_MASK = 0x03,
>  	HDMI_IH_FC_INT2_LOW_PRIORITY_OVERFLOW = 0x02,
> -- 
> 2.1.0
> 
> _______________________________________________
> Alsa-devel mailing list
> Alsa-devel at alsa-project.org
> http://mailman.alsa-project.org/mailman/listinfo/alsa-devel
> 


From lina.iyer at linaro.org  Fri Aug 14 07:38:56 2015
From: lina.iyer at linaro.org (Lina Iyer)
Date: Fri, 14 Aug 2015 08:38:56 -0600
Subject: [PATCH v2 1/2] ARM: common: Introduce PM domains for CPUs/clusters
In-Reply-To: <CAL_Jsq+-9vS4_KRQKAsQnHXBMfubkRtnWwuBHSrD166trmTVSw@mail.gmail.com>
References: <CAL_JsqLhHy5gO=usm1HLf8h6iz_5FguCDo-Qz2Km+XEwaCODUA@mail.gmail.com>
 <1439406024-41893-1-git-send-email-lina.iyer@linaro.org>
 <CAL_JsqLcSs79bnj4ELN0uiwJ6gxt46PghxvuGQ7prkq-4gLKhg@mail.gmail.com>
 <20150813201248.GB84868@linaro.org>
 <CAL_Jsq+-9vS4_KRQKAsQnHXBMfubkRtnWwuBHSrD166trmTVSw@mail.gmail.com>
Message-ID: <20150814143856.GD86880@linaro.org>

On Thu, Aug 13 2015 at 16:02 -0600, Rob Herring wrote:
>On Thu, Aug 13, 2015 at 3:12 PM, Lina Iyer <lina.iyer at linaro.org> wrote:
>> On Thu, Aug 13 2015 at 11:29 -0600, Rob Herring wrote:
>>>
>>> On Wed, Aug 12, 2015 at 2:00 PM, Lina Iyer <lina.iyer at linaro.org> wrote:
>>>>
>>>> Define and add Generic PM domains (genpd) for CPU clusters. Many new
>>>> SoCs group CPUs as clusters. Clusters share common resources like GIC,
>>>> power rail, caches, VFP, Coresight etc. When all CPUs in the cluster are
>>>> idle, these shared resources may also be put in their idle state.
>>>>
>>>> The idle time between the last CPU entering idle and a CPU resuming
>>>> execution is an opportunity for these shared resources to be powered
>>>> down. Generic PM domain provides a framework for defining such power
>>>> domains and attach devices to the domain. When the devices in the domain
>>>> are idle at runtime, the domain would also be suspended and resumed
>>>> before the first of the devices resume execution.
>>>>
>>>> We define a generic PM domain for each cluster and attach CPU devices in
>>>> the cluster to that PM domain. The DT definitions for the SoC describe
>>>> this relationship. Genpd callbacks for power_on and power_off can then
>>>> be used to power up/down the shared resources for the domain.
>>>>
>>>> Cc: Stephen Boyd <sboyd at codeaurora.org>
>>>> Cc: Kevin Hilman <khilman at linaro.org>
>>>> Cc: Ulf Hansson <ulf.hansson at linaro.org>
>>>> Cc: Catalin Marinas <catalin.marinas at arm.com>
>>>> Cc: Daniel Lezcano <daniel.lezcano at linaro.org>
>>>> Cc: Mark Rutland <mark.rutland at arm.com>
>>>> Cc: Lorenzo Pieralisi <lorenzo.pieralisi at arm.com>
>>>> Signed-off-by: Kevin Hilman <khilman at linaro.org>
>>>> Signed-off-by: Lina Iyer <lina.iyer at linaro.org>
>>>> ---
>>>> Changes since v1:
>>>>
>>>> - Function name changes and split out common code
>>>> - Use cpu,pd for now. Removed references to ARM. Open to recommendations.
>>>> - Still located in arch/arm/common/. May move to a more appropriate
>>>> location.
>>>> - Platform drivers can directly call of_init_cpu_domain() without using
>>>>   compatibles.
>>>> - Now maintains a list of CPU PM domains.
>>>
>>>
>>> [...]
>>>
>>>> +static int __init of_pm_domain_attach_cpus(void)
>>>> +{
>>>> +       int cpuid, ret;
>>>> +
>>>> +       /* Find any CPU nodes with a phandle to this power domain */
>>>> +       for_each_possible_cpu(cpuid) {
>>>> +               struct device *cpu_dev;
>>>> +               struct of_phandle_args pd_args;
>>>> +
>>>> +               cpu_dev = get_cpu_device(cpuid);
>>>> +               if (!cpu_dev) {
>>>> +                       pr_warn("%s: Unable to get device for CPU%d\n",
>>>> +                                       __func__, cpuid);
>>>> +                       return -ENODEV;
>>>> +               }
>>>> +
>>>> +               /*
>>>> +                * We are only interested in CPUs that can be attached to
>>>> +                * PM domains that are cpu,pd compatible.
>>>> +                */
>>>
>>>
>>> Under what conditions would the power domain for a cpu not be cpu,pd
>>> compatible?
>>>
>> Mostly never. But I dont want to assume and attach a CPU to its domain
>> that I am not concerned with.
>
>Which is why the power controller driver should tell you.
>
>>> Why can't the driver handling the power domain register with gen_pd
>>> and the cpu_pd as the driver is going to be aware of which domains are
>>> for cpus.
>
I probably dont need that detail, the CPUs have phandle the domain, so
we know which CPUs are in the domain. I just need to know which domains
we should concern ourself with.

That would mean -
Platform drivers would explictly need to register the domains their CPU
domains. I was hoping to reduce that effort to register domains and
attach CPUs to their respective domains. The platform drivers need not
do anything unless they have SoC specific configuration to power down
the domain, in which case they would use the CPU_PD_METHOD_OF_DECLARE()
macro to register their platform callbacks. I thought it would be nice,
the platform specify the hardware relation in DT and drivers dont have
to explictly call out the domains.

>>
>> They could and like Renesas they would. They could have an intricate
>> hierarchy of domains that they may want to deal with in their platform
>> drivers. Platforms could define the CPU devices as IRQ-safe and attach
>> it to their domains. Ensure the reference count of the online and
>> running CPUs are correct and they are good to go. They also would attach
>> the CPU devices to the domain and everything would work as they would
>> here. Its just repeated code across platforms that we are trying to
>> avoid.
>
>I agree that we want to have core code doing all that setup, But that
>has nothing to do with needing to have a DT property. The driver just
>needs to tell you the list of cpu power domains and the associated
>cpus they want the core to manage. Then it is up to you to do the rest
>of the setup.
>
>So I really don't think we need a DT binding here.
>
Okay. I agree, that it is a far fetched idea. I will remove it for now.
May be when there are more common functionality, we can think about it.

>>> While there could be h/w such that all power domains within
>>> a chip have a nice uniform programming model, I'd guess that is the
>>> exception, not the rule. First, chips I have worked on were not that
>>> way. CPU related and peripheral related domains are handled quite
>>> differently.
>>

>>> Second, often the actions on the CPU power domains don't
>>> take effect until a WFI, so you end up with a different programming
>>> sequence.
>>>
>> How so? The last core going down (in this case, when the domain is
>> suspended the last core is the last device that does a _put() on the
>> domain) would determine and perform the power domain's programming
>> sequence, in the context of the last CPU. A sequence that would only be
>> effected in hardware when the the CPU executes WFI. I dont see why it
>> would be any different than how it is today.
>
>I just mean that for a peripheral (e.g a SATA controller), you simply
>quiesce the device and driver and shut off power. With a cpu or cpu
>related component, you can't really shut it off until you stop
>running. So cpu domains are special.
>
Makes sense.

Thanks Rob.

-- Lina


From marc.zyngier at arm.com  Fri Aug 14 07:41:05 2015
From: marc.zyngier at arm.com (Marc Zyngier)
Date: Fri, 14 Aug 2015 15:41:05 +0100
Subject: [PATCH 0/3] PCI: arm64/powerpc: Fix parsing of linux,pci-probe-only
Message-ID: <1439563268-13418-1-git-send-email-marc.zyngier@arm.com>

The pci-host-generic driver parses the linux,pci-probe-only property,
and assumes that it will have a boolean parameter.

Turns out that the Seattle DTS file has a naked "linux,pci-probe-only"
property, which leads to the driver dereferencing some unsuspecting
memory location. Nothing really bad happens (we end up reading some
other bit of DT, fortunately), but that not a reason to keep it this
way.

The first patch fixes the driver not to do silly things, and simply
give a warning when this happens. The powerpc code from where this
code was lifted is also fixed in a second patch.

Finally, the bad property is removed from the Seatle DTS, because it
is simply not necessary (it actually prevents me from using SR-IOV,
which otherwise runs fine without the probe-only thing).

Marc Zyngier (3):
  PCI: pci-host-generic: Fix lookup of linux,pci-probe-only property
  powerpc: PCI: Fix lookup of linux,pci-probe-only property
  arm64: dts: Drop linux,pci-probe-only from the Seattle DTS

 arch/arm64/boot/dts/amd/amd-overdrive.dts |  1 -
 arch/powerpc/platforms/pseries/setup.c    | 15 ++++++++++-----
 drivers/pci/host/pci-host-generic.c       | 15 ++++++++++-----
 3 files changed, 20 insertions(+), 11 deletions(-)

-- 
2.1.4



From marc.zyngier at arm.com  Fri Aug 14 07:41:06 2015
From: marc.zyngier at arm.com (Marc Zyngier)
Date: Fri, 14 Aug 2015 15:41:06 +0100
Subject: [PATCH 1/3] PCI: pci-host-generic: Fix lookup of linux,
 pci-probe-only property
In-Reply-To: <1439563268-13418-1-git-send-email-marc.zyngier@arm.com>
References: <1439563268-13418-1-git-send-email-marc.zyngier@arm.com>
Message-ID: <1439563268-13418-2-git-send-email-marc.zyngier@arm.com>

When pci-host-generic looks for the probe-only property, it seems
to trust the DT to be correctly written, and assumes that there
is a parameter to the property.

Unfortunately, this is not always the case, and some firmware expose
this property naked. The driver ends up making a decision based on
whatever the property pointer points to, which is likely to be junk.

Instead, let's check for the validity of the property, and ignore
it if the firmware couldn't make up its mind.

Signed-off-by: Marc Zyngier <marc.zyngier at arm.com>
---
 drivers/pci/host/pci-host-generic.c | 15 ++++++++++-----
 1 file changed, 10 insertions(+), 5 deletions(-)

diff --git a/drivers/pci/host/pci-host-generic.c b/drivers/pci/host/pci-host-generic.c
index 265dd25..2b2e2ff 100644
--- a/drivers/pci/host/pci-host-generic.c
+++ b/drivers/pci/host/pci-host-generic.c
@@ -211,6 +211,7 @@ static int gen_pci_probe(struct platform_device *pdev)
 	const char *type;
 	const struct of_device_id *of_id;
 	const int *prop;
+	int len;
 	struct device *dev = &pdev->dev;
 	struct device_node *np = dev->of_node;
 	struct gen_pci *pci = devm_kzalloc(dev, sizeof(*pci), GFP_KERNEL);
@@ -225,12 +226,16 @@ static int gen_pci_probe(struct platform_device *pdev)
 		return -EINVAL;
 	}
 
-	prop = of_get_property(of_chosen, "linux,pci-probe-only", NULL);
+	prop = of_get_property(of_chosen, "linux,pci-probe-only", &len);
 	if (prop) {
-		if (*prop)
-			pci_add_flags(PCI_PROBE_ONLY);
-		else
-			pci_clear_flags(PCI_PROBE_ONLY);
+		if (len) {
+			if (be32_to_cpup(prop))
+				pci_add_flags(PCI_PROBE_ONLY);
+			else
+				pci_clear_flags(PCI_PROBE_ONLY);
+		} else {
+			dev_warn(&pdev->dev, "linux,pci-probe-only set without value, ignoring\n");
+		}
 	}
 
 	of_id = of_match_node(gen_pci_of_match, np);
-- 
2.1.4



From marc.zyngier at arm.com  Fri Aug 14 07:41:08 2015
From: marc.zyngier at arm.com (Marc Zyngier)
Date: Fri, 14 Aug 2015 15:41:08 +0100
Subject: [PATCH 3/3] arm64: dts: Drop linux,
 pci-probe-only from the Seattle DTS
In-Reply-To: <1439563268-13418-1-git-send-email-marc.zyngier@arm.com>
References: <1439563268-13418-1-git-send-email-marc.zyngier@arm.com>
Message-ID: <1439563268-13418-4-git-send-email-marc.zyngier@arm.com>

The linux,pci-probe-only property mandates an argument to indicate
whether or not to engage the "probe-only" mode, but the Seattle
DTS just provides a naked property, which is illegal.

Also, it turns out that the board is perfectly happy without
probe-only, so let's drop this altogether.

Signed-off-by: Marc Zyngier <marc.zyngier at arm.com>
---
 arch/arm64/boot/dts/amd/amd-overdrive.dts | 1 -
 1 file changed, 1 deletion(-)

diff --git a/arch/arm64/boot/dts/amd/amd-overdrive.dts b/arch/arm64/boot/dts/amd/amd-overdrive.dts
index 564a3f7..128fa94 100644
--- a/arch/arm64/boot/dts/amd/amd-overdrive.dts
+++ b/arch/arm64/boot/dts/amd/amd-overdrive.dts
@@ -14,7 +14,6 @@
 
 	chosen {
 		stdout-path = &serial0;
-		linux,pci-probe-only;
 	};
 };
 
-- 
2.1.4



From marc.zyngier at arm.com  Fri Aug 14 07:41:07 2015
From: marc.zyngier at arm.com (Marc Zyngier)
Date: Fri, 14 Aug 2015 15:41:07 +0100
Subject: [PATCH 2/3] powerpc: PCI: Fix lookup of linux, pci-probe-only property
In-Reply-To: <1439563268-13418-1-git-send-email-marc.zyngier@arm.com>
References: <1439563268-13418-1-git-send-email-marc.zyngier@arm.com>
Message-ID: <1439563268-13418-3-git-send-email-marc.zyngier@arm.com>

When find_and_init_phbs() looks for the probe-only property, it seems
to trust the firmware to be correctly written, and assumes that there
is a parameter to the property.

It is conceivable that the firmware could not be that perfect, and it
could expose this property naked (at least one arm64 platform seems to
exhibit this exact behaviour). The setup code the ends up making
a decision based on whatever the property pointer points to, which
is likely to be junk.

Instead, let's check for the validity of the property, and ignore
it if the firmware couldn't make up its mind.

Signed-off-by: Marc Zyngier <marc.zyngier at arm.com>
---
 arch/powerpc/platforms/pseries/setup.c | 15 ++++++++++-----
 1 file changed, 10 insertions(+), 5 deletions(-)

diff --git a/arch/powerpc/platforms/pseries/setup.c b/arch/powerpc/platforms/pseries/setup.c
index df6a704..6bdc1f9 100644
--- a/arch/powerpc/platforms/pseries/setup.c
+++ b/arch/powerpc/platforms/pseries/setup.c
@@ -490,14 +490,19 @@ static void __init find_and_init_phbs(void)
 	 */
 	if (of_chosen) {
 		const int *prop;
+		int len;
 
 		prop = of_get_property(of_chosen,
-				"linux,pci-probe-only", NULL);
+				"linux,pci-probe-only", &len);
 		if (prop) {
-			if (*prop)
-				pci_add_flags(PCI_PROBE_ONLY);
-			else
-				pci_clear_flags(PCI_PROBE_ONLY);
+			if (len) {
+				if (be32_to_cpup(prop))
+					pci_add_flags(PCI_PROBE_ONLY);
+				else
+					pci_clear_flags(PCI_PROBE_ONLY);
+			} else {
+				pr_warn("linux,pci-probe-only set without value, ignoring\n");
+			}
 		}
 	}
 }
-- 
2.1.4



From hdegoede at redhat.com  Fri Aug 14 07:44:32 2015
From: hdegoede at redhat.com (Hans de Goede)
Date: Fri, 14 Aug 2015 16:44:32 +0200
Subject: [PATCH 1/6] ARM: dts: sun5i: Add simplefb node for tvencoder output
In-Reply-To: <1439563477-12295-1-git-send-email-hdegoede@redhat.com>
References: <1439563477-12295-1-git-send-email-hdegoede@redhat.com>
Message-ID: <1439563477-12295-2-git-send-email-hdegoede@redhat.com>

Add a simplefb node for tvencoder / composite-video output, such as found
on the Auxtek-T003 and the CHIP.

Signed-off-by: Hans de Goede <hdegoede at redhat.com>
---
 arch/arm/boot/dts/sun5i-a10s.dtsi | 9 +++++++++
 1 file changed, 9 insertions(+)

diff --git a/arch/arm/boot/dts/sun5i-a10s.dtsi b/arch/arm/boot/dts/sun5i-a10s.dtsi
index a6d55f0..3e47b3d 100644
--- a/arch/arm/boot/dts/sun5i-a10s.dtsi
+++ b/arch/arm/boot/dts/sun5i-a10s.dtsi
@@ -77,6 +77,15 @@
 			clocks = <&pll5 1>, <&ahb_gates 36>, <&ahb_gates 44>;
 			status = "disabled";
 		};
+
+		framebuffer at 2 {
+			compatible = "allwinner,simple-framebuffer",
+				     "simple-framebuffer";
+			allwinner,pipeline = "de_be0-lcd0-tve0";
+			clocks = <&pll5 1>, <&ahb_gates 34>, <&ahb_gates 36>,
+				 <&ahb_gates 44>;
+			status = "disabled";
+		};
 	};
 
 	clocks {
-- 
2.4.3



From hdegoede at redhat.com  Fri Aug 14 07:44:31 2015
From: hdegoede at redhat.com (Hans de Goede)
Date: Fri, 14 Aug 2015 16:44:31 +0200
Subject: [PATCH 0/6] ARM: dts: sunxi: Various sunxi devicetree patches
Message-ID: <1439563477-12295-1-git-send-email-hdegoede@redhat.com>

Hi Maxime,

Here is a bunch of sunxi dts patches which are ready for merging, some
are the result of the course I'm teaching during the weekends, some are
my own :)

I'm also sitting on another batch, which can go in as soon as the
axp209 usb-power-supply driver gets merged, so that we can support
otg on boards which use the pmic for vbus-det.

Regards,

Hans


From hdegoede at redhat.com  Fri Aug 14 07:44:33 2015
From: hdegoede at redhat.com (Hans de Goede)
Date: Fri, 14 Aug 2015 16:44:33 +0200
Subject: [PATCH 2/6] ARM: dts: sun7i: Enable i2c bus 1 and 2 on the Wits A20
 Pro DKT
In-Reply-To: <1439563477-12295-1-git-send-email-hdegoede@redhat.com>
References: <1439563477-12295-1-git-send-email-hdegoede@redhat.com>
Message-ID: <1439563477-12295-3-git-send-email-hdegoede@redhat.com>

Enable i2c bus 1 and 2 on the Wits A20 Pro DKT, these are used for
the touchscreen resp. the accelerometer.

Signed-off-by: Hans de Goede <hdegoede at redhat.com>
---
 arch/arm/boot/dts/sun7i-a20-wits-pro-a20-dkt.dts | 12 ++++++++++++
 1 file changed, 12 insertions(+)

diff --git a/arch/arm/boot/dts/sun7i-a20-wits-pro-a20-dkt.dts b/arch/arm/boot/dts/sun7i-a20-wits-pro-a20-dkt.dts
index da47608..85b500d 100644
--- a/arch/arm/boot/dts/sun7i-a20-wits-pro-a20-dkt.dts
+++ b/arch/arm/boot/dts/sun7i-a20-wits-pro-a20-dkt.dts
@@ -92,6 +92,18 @@
 	};
 };
 
+&i2c1 {
+	pinctrl-names = "default";
+	pinctrl-0 = <&i2c1_pins_a>;
+	status = "okay";
+};
+
+&i2c2 {
+	pinctrl-names = "default";
+	pinctrl-0 = <&i2c2_pins_a>;
+	status = "okay";
+};
+
 #include "axp209.dtsi"
 
 &mmc0 {
-- 
2.4.3



From hdegoede at redhat.com  Fri Aug 14 07:44:34 2015
From: hdegoede at redhat.com (Hans de Goede)
Date: Fri, 14 Aug 2015 16:44:34 +0200
Subject: [PATCH 3/6] ARM: dts: sun7i: Add regulator configuration to the
 pcduino3 dts file
In-Reply-To: <1439563477-12295-1-git-send-email-hdegoede@redhat.com>
References: <1439563477-12295-1-git-send-email-hdegoede@redhat.com>
Message-ID: <1439563477-12295-4-git-send-email-hdegoede@redhat.com>

From: Jelle van der Waa <jelle at vdwaa.nl>

Add regulator configuration to the pcduino3 dts file.

Signed-off-by: Jelle van der Waa <jelle at vdwaa.nl>
Signed-off-by: Hans de Goede <hdegoede at redhat.com>
---
 arch/arm/boot/dts/sun7i-a20-pcduino3.dts | 39 ++++++++++++++++++++++++++++----
 1 file changed, 35 insertions(+), 4 deletions(-)

diff --git a/arch/arm/boot/dts/sun7i-a20-pcduino3.dts b/arch/arm/boot/dts/sun7i-a20-pcduino3.dts
index afc9ece..99e238b 100644
--- a/arch/arm/boot/dts/sun7i-a20-pcduino3.dts
+++ b/arch/arm/boot/dts/sun7i-a20-pcduino3.dts
@@ -111,6 +111,10 @@
 	allwinner,pins = "PH2";
 };
 
+&cpu0 {
+	cpu-supply = <&reg_dcdc2>;
+};
+
 &ehci0 {
 	status = "okay";
 };
@@ -137,16 +141,14 @@
 	status = "okay";
 
 	axp209: pmic at 34 {
-		compatible = "x-powers,axp209";
 		reg = <0x34>;
 		interrupt-parent = <&nmi_intc>;
 		interrupts = <0 IRQ_TYPE_LEVEL_LOW>;
-
-		interrupt-controller;
-		#interrupt-cells = <1>;
 	};
 };
 
+#include "axp209.dtsi"
+
 &ir0 {
 	pinctrl-names = "default";
 	pinctrl-0 = <&ir0_rx_pins_a>;
@@ -192,6 +194,31 @@
 	status = "okay";
 };
 
+&reg_dcdc2 {
+	regulator-always-on;
+	regulator-min-microvolt = <1000000>;
+	regulator-max-microvolt = <1400000>;
+	regulator-name = "vdd-cpu";
+};
+
+&reg_dcdc3 {
+	regulator-always-on;
+	regulator-min-microvolt = <1000000>;
+	regulator-max-microvolt = <1400000>;
+	regulator-name = "vdd-int-pll";
+};
+
+&reg_ldo1 {
+	regulator-name = "vdd-rtc";
+};
+
+&reg_ldo2 {
+	regulator-always-on;
+	regulator-min-microvolt = <3000000>;
+	regulator-max-microvolt = <3000000>;
+	regulator-name = "avcc";
+};
+
 &reg_usb1_vbus {
 	status = "okay";
 };
@@ -206,6 +233,10 @@
 	status = "okay";
 };
 
+&usb_power_supply {
+	status = "okay";
+};
+
 &usbphy {
 	usb1_vbus-supply = <&reg_usb1_vbus>;
 	usb2_vbus-supply = <&reg_usb2_vbus>;
-- 
2.4.3



From hdegoede at redhat.com  Fri Aug 14 07:44:37 2015
From: hdegoede at redhat.com (Hans de Goede)
Date: Fri, 14 Aug 2015 16:44:37 +0200
Subject: [PATCH 6/6] ARM: dts: sun8i: Add support for qt90h-v4 tablets
In-Reply-To: <1439563477-12295-1-git-send-email-hdegoede@redhat.com>
References: <1439563477-12295-1-git-send-email-hdegoede@redhat.com>
Message-ID: <1439563477-12295-7-git-send-email-hdegoede@redhat.com>

The gt90h is a pcb found in generic 9" tablets with an A23 soc, 1G RAM
and 8G nand, rtl8723as usb wifi, 1 micro usb port and 1 micro sd slot.

This commit adds a dts for v4 of the gt90h pcb.

Signed-off-by: Hans de Goede <hdegoede at redhat.com>
---
 arch/arm/boot/dts/Makefile               |   1 +
 arch/arm/boot/dts/sun8i-a23-gt90h-v4.dts | 145 +++++++++++++++++++++++++++++++
 2 files changed, 146 insertions(+)
 create mode 100644 arch/arm/boot/dts/sun8i-a23-gt90h-v4.dts

diff --git a/arch/arm/boot/dts/Makefile b/arch/arm/boot/dts/Makefile
index d639774..6aa657f 100644
--- a/arch/arm/boot/dts/Makefile
+++ b/arch/arm/boot/dts/Makefile
@@ -600,6 +600,7 @@ dtb-$(CONFIG_MACH_SUN7I) += \
 	sun7i-a20-wits-pro-a20-dkt.dtb
 dtb-$(CONFIG_MACH_SUN8I) += \
 	sun8i-a23-evb.dtb \
+	sun8i-a23-gt90h-v4.dtb \
 	sun8i-a23-ippo-q8h-v5.dtb \
 	sun8i-a23-ippo-q8h-v1.2.dtb \
 	sun8i-a33-et-q8-v1.6.dtb \
diff --git a/arch/arm/boot/dts/sun8i-a23-gt90h-v4.dts b/arch/arm/boot/dts/sun8i-a23-gt90h-v4.dts
new file mode 100644
index 0000000..1aeb06c
--- /dev/null
+++ b/arch/arm/boot/dts/sun8i-a23-gt90h-v4.dts
@@ -0,0 +1,145 @@
+/*
+ * Copyright 2015 Hans de Goede <hdegoede at redhat.com>
+ *
+ * This file is dual-licensed: you can use it either under the terms
+ * of the GPL or the X11 license, at your option. Note that this dual
+ * licensing only applies to this file, and not this project as a
+ * whole.
+ *
+ *  a) This file is free software; you can redistribute it and/or
+ *     modify it under the terms of the GNU General Public License as
+ *     published by the Free Software Foundation; either version 2 of the
+ *     License, or (at your option) any later version.
+ *
+ *     This file is distributed in the hope that it will be useful,
+ *     but WITHOUT ANY WARRANTY; without even the implied warranty of
+ *     MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ *     GNU General Public License for more details.
+ *
+ * Or, alternatively,
+ *
+ *  b) Permission is hereby granted, free of charge, to any person
+ *     obtaining a copy of this software and associated documentation
+ *     files (the "Software"), to deal in the Software without
+ *     restriction, including without limitation the rights to use,
+ *     copy, modify, merge, publish, distribute, sublicense, and/or
+ *     sell copies of the Software, and to permit persons to whom the
+ *     Software is furnished to do so, subject to the following
+ *     conditions:
+ *
+ *     The above copyright notice and this permission notice shall be
+ *     included in all copies or substantial portions of the Software.
+ *
+ *     THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
+ *     EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES
+ *     OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
+ *     NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT
+ *     HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY,
+ *     WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
+ *     FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR
+ *     OTHER DEALINGS IN THE SOFTWARE.
+ */
+
+/dts-v1/;
+#include "sun8i-a23.dtsi"
+#include "sunxi-common-regulators.dtsi"
+
+#include <dt-bindings/gpio/gpio.h>
+#include <dt-bindings/input/input.h>
+#include <dt-bindings/pinctrl/sun4i-a10.h>
+
+/ {
+	model = "Allwinner GT90H Quad Core Tablet (v4)";
+	compatible = "allwinner,gt90h-v4", "allwinner,sun8i-a33";
+
+	aliases {
+		serial0 = &r_uart;
+	};
+
+	chosen {
+		stdout-path = "serial0:115200n8";
+	};
+};
+
+&ehci0 {
+	status = "okay";
+};
+
+&i2c0 {
+	pinctrl-names = "default";
+	pinctrl-0 = <&i2c0_pins_a>;
+	status = "okay";
+};
+
+&i2c1 {
+	pinctrl-names = "default";
+	pinctrl-0 = <&i2c1_pins_a>;
+	status = "okay";
+};
+
+&lradc {
+	vref-supply = <&reg_vcc3v0>;
+	status = "okay";
+
+	button at 200 {
+		label = "Volume Up";
+		linux,code = <KEY_VOLUMEUP>;
+		channel = <0>;
+		voltage = <200000>;
+	};
+
+	button at 400 {
+		label = "Volume Down";
+		linux,code = <KEY_VOLUMEDOWN>;
+		channel = <0>;
+		voltage = <400000>;
+	};
+
+	button at 600 {
+		label = "Back";
+		linux,code = <KEY_BACK>;
+		channel = <0>;
+		voltage = <600000>;
+	};
+};
+
+&mmc0 {
+	pinctrl-names = "default";
+	pinctrl-0 = <&mmc0_pins_a>, <&mmc0_cd_pin_gt90h>;
+	/* FIXME this really is aldo1, correct once we've pmic support */
+	vmmc-supply = <&reg_vcc3v0>;
+	bus-width = <4>;
+	cd-gpios = <&pio 1 4 GPIO_ACTIVE_HIGH>; /* PB4 */
+	cd-inverted;
+	status = "okay";
+};
+
+&pio {
+	mmc0_cd_pin_gt90h: mmc0_cd_pin at 0 {
+		allwinner,pins = "PB4";
+		allwinner,function = "gpio_in";
+		allwinner,drive = <SUN4I_PINCTRL_10_MA>;
+		allwinner,pull = <SUN4I_PINCTRL_PULL_UP>;
+	};
+};
+
+&r_uart {
+	pinctrl-names = "default";
+	pinctrl-0 = <&r_uart_pins_a>;
+	status = "okay";
+};
+
+/*
+ * FIXME for now we only support host mode and rely on u-boot to have
+ * turned on Vbus which is controlled by the axp223 pmic on the board.
+ *
+ * Once we have axp223 support we should switch to fully supporting otg.
+ */
+&usb_otg {
+	dr_mode = "host";
+	status = "okay";
+};
+
+&usbphy {
+	status = "okay";
+};
-- 
2.4.3



From hdegoede at redhat.com  Fri Aug 14 07:44:35 2015
From: hdegoede at redhat.com (Hans de Goede)
Date: Fri, 14 Aug 2015 16:44:35 +0200
Subject: [PATCH 4/6] ARM: dts: sun7i: Enable USB DRC on pcDuino 3
In-Reply-To: <1439563477-12295-1-git-send-email-hdegoede@redhat.com>
References: <1439563477-12295-1-git-send-email-hdegoede@redhat.com>
Message-ID: <1439563477-12295-5-git-send-email-hdegoede@redhat.com>

From: Jelle van der Waa <jelle at vdwaa.nl>

Enable the otg/drc usb controller on the pcDuino 3.

Note this board has the otg-vbus connected directly to the 5v-dcc of
the board, so there is no vbus0 regulator, nor vbus0-det.

Signed-off-by: Jelle van der Waa <jelle at vdwaa.nl>
Signed-off-by: Hans de Goede <hdegoede at redhat.com>
---
 arch/arm/boot/dts/sun7i-a20-pcduino3.dts | 19 +++++++++++++++++++
 1 file changed, 19 insertions(+)

diff --git a/arch/arm/boot/dts/sun7i-a20-pcduino3.dts b/arch/arm/boot/dts/sun7i-a20-pcduino3.dts
index 99e238b..08cf715 100644
--- a/arch/arm/boot/dts/sun7i-a20-pcduino3.dts
+++ b/arch/arm/boot/dts/sun7i-a20-pcduino3.dts
@@ -173,6 +173,10 @@
 	status = "okay";
 };
 
+&otg_sram {
+	status = "okay";
+};
+
 &pio {
 	led_pins_pcduino3: led_pins at 0 {
 		allwinner,pins = "PH15", "PH16";
@@ -187,6 +191,13 @@
 		allwinner,drive = <SUN4I_PINCTRL_10_MA>;
 		allwinner,pull = <SUN4I_PINCTRL_NO_PULL>;
 	};
+
+	usb0_id_detect_pin: usb0_id_detect_pin at 0 {
+		allwinner,pins = "PH4";
+		allwinner,function = "gpio_in";
+		allwinner,drive = <SUN4I_PINCTRL_10_MA>;
+		allwinner,pull = <SUN4I_PINCTRL_PULL_UP>;
+	};
 };
 
 &reg_ahci_5v {
@@ -237,7 +248,15 @@
 	status = "okay";
 };
 
+&usb_otg {
+	dr_mode = "otg";
+	status = "okay";
+};
+
 &usbphy {
+	pinctrl-names = "default";
+	pinctrl-0 = <&usb0_id_detect_pin>;
+	usb0_id_det-gpio = <&pio 7 4 GPIO_ACTIVE_HIGH>; /* PH4 */
 	usb1_vbus-supply = <&reg_usb1_vbus>;
 	usb2_vbus-supply = <&reg_usb2_vbus>;
 	status = "okay";
-- 
2.4.3



From hdegoede at redhat.com  Fri Aug 14 07:44:36 2015
From: hdegoede at redhat.com (Hans de Goede)
Date: Fri, 14 Aug 2015 16:44:36 +0200
Subject: [PATCH 5/6] ARM: dts: sun7i: Enable USB DRC on cubieboard2
In-Reply-To: <1439563477-12295-1-git-send-email-hdegoede@redhat.com>
References: <1439563477-12295-1-git-send-email-hdegoede@redhat.com>
Message-ID: <1439563477-12295-6-git-send-email-hdegoede@redhat.com>

From: Ralph Benadski <benadski at gmail.com>

Enable the otg/drc usb controller on the cubieboard2.

Note this board has the otg-vbus connected directly to the 5v-dcc of
the board, so there is no vbus0 regulator, nor vbus0-det.

Signed-off-by: Ralph Benadski <benadski at gmail.com>
Signed-off-by: Hans de Goede <hdegoede at redhat.com>
---
 arch/arm/boot/dts/sun7i-a20-cubieboard2.dts | 19 +++++++++++++++++++
 1 file changed, 19 insertions(+)

diff --git a/arch/arm/boot/dts/sun7i-a20-cubieboard2.dts b/arch/arm/boot/dts/sun7i-a20-cubieboard2.dts
index f35957d..7cbb22b 100644
--- a/arch/arm/boot/dts/sun7i-a20-cubieboard2.dts
+++ b/arch/arm/boot/dts/sun7i-a20-cubieboard2.dts
@@ -207,6 +207,10 @@
 	status = "okay";
 };
 
+&otg_sram {
+	status = "okay";
+};
+
 &pio {
 	led_pins_cubieboard2: led_pins at 0 {
 		allwinner,pins = "PH20", "PH21";
@@ -214,12 +218,24 @@
 		allwinner,drive = <SUN4I_PINCTRL_10_MA>;
 		allwinner,pull = <SUN4I_PINCTRL_NO_PULL>;
 	};
+
+	usb0_id_detect_pin: usb0_id_detect_pin at 0 {
+		allwinner,pins = "PH4";
+		allwinner,function = "gpio_in";
+		allwinner,drive = <SUN4I_PINCTRL_10_MA>;
+		allwinner,pull = <SUN4I_PINCTRL_PULL_UP>;
+	};
 };
 
 &reg_ahci_5v {
 	status = "okay";
 };
 
+&usb_otg {
+	dr_mode = "otg";
+	status = "okay";
+};
+
 #include "axp209.dtsi"
 
 &reg_dcdc2 {
@@ -262,6 +278,9 @@
 };
 
 &usbphy {
+	pinctrl-names = "default";
+	pinctrl-0 = <&usb0_id_detect_pin>;
+	usb0_id_det-gpio = <&pio 7 4 GPIO_ACTIVE_HIGH>; /* PH4 */
 	usb1_vbus-supply = <&reg_usb1_vbus>;
 	usb2_vbus-supply = <&reg_usb2_vbus>;
 	status = "okay";
-- 
2.4.3



From bhelgaas at google.com  Fri Aug 14 07:46:44 2015
From: bhelgaas at google.com (Bjorn Helgaas)
Date: Fri, 14 Aug 2015 09:46:44 -0500
Subject: [PATCH v4 1/3] PCI: generic: remove dependency on hw_pci
In-Reply-To: <20150812090449.GA22485@arm.com>
References: <1438721620-15493-1-git-send-email-jchandra@broadcom.com>
 <20150804234956.GF17327@google.com>
 <007501d0d4ce$1d2dd9c0$57898d40$@samsung.com>
 <20150812090449.GA22485@arm.com>
Message-ID: <20150814144644.GC26431@google.com>

On Wed, Aug 12, 2015 at 10:04:50AM +0100, Will Deacon wrote:
> On Wed, Aug 12, 2015 at 08:11:29AM +0100, Pavel Fedin wrote:
> > > I dropped the acks and tested-by because of that change, but I'll happily
> > > add them back if Lorenzo and Pavel confirm.  
> > 
> >  Confirm.
> >  Tested-by: Pavel Fedin <p.fedin at samsung.com>
> > 
> >  I also added MSI support. Can i post it as patch on top of your branch?
> 
> There shouldn't be any need with the changes queued in tip/irq/core. Can
> you give the following branch a go, please (it doesn't look like Bjorn's
> stuff is in linux-next, unfortunately)?

We still have a build issue (undefined reference to pci_write_msi_msg
in imx_v6_v7_defconfig) to resolve before putting it in linux-next.
Hopefully we can resolve that today.


From james.morse at arm.com  Fri Aug 14 07:48:32 2015
From: james.morse at arm.com (James Morse)
Date: Fri, 14 Aug 2015 15:48:32 +0100
Subject: [PATCH v6 3/6] PCI: designware: Add ARM64 support
In-Reply-To: <55C44B18.4010103@hisilicon.com>
References: <1438848559-232109-1-git-send-email-wangzhou1@hisilicon.com>
 <1438848559-232109-4-git-send-email-wangzhou1@hisilicon.com>
 <55C44B18.4010103@hisilicon.com>
Message-ID: <55CDFFC0.40604@arm.com>

On 07/08/15 07:07, Zhou Wang wrote:
> On 2015/8/6 16:09, Zhou Wang wrote:
>> This patch tries to unify ARM32 and ARM64 PCIe in designware driver. Delete
>> function dw_pcie_setup, dw_pcie_scan_bus, dw_pcie_map_irq and struct hw_pci,
>> move related operations to dw_pcie_host_init.
>>
>> In past, we use:
>> pci_common_init_dev
>>       -> pcibios_init_hw
>>               -> hw->scan (dw_pcie_scan_bus)
>> to pass 0 to root_bus_nr in struct pcie_port. This patch set pp->root_bus_nr = 0
>> in each PCIe host driver which is based on pcie-designware.
>>
>> This patch also try to use of_pci_get_host_bridge_resources for ARM32 and ARM64
>> according to the suggestion for Gabriele[1]
>>
>> Finally this patch reverts commit f4c55c5a3f7f "PCI: designware: Program ATU
>> with untranslated address" based on 1/6 in this series. we delete *_mod_base in
>> pcie-designware. This was discussed in [2]
>>
>> I have compiled the driver with multi_v7_defconfig. However, I don't have
>> ARM32 PCIe related board to do test. It will be appreciated if someone could
>> help to test it.

I've tested this whole series on an ARM32 PCIe board:'Freescale i.MX6 Quad
SABRE Lite Board' with an Intel wireless card on v4.2-rc6.

I can rescan the bus, load firmware, list nearby APs, and even get MSIs
coming from the card.

Tested-By: James Morse <james.morse at arm.com>


Thanks,

James


From thierry.reding at gmail.com  Fri Aug 14 07:48:31 2015
From: thierry.reding at gmail.com (Thierry Reding)
Date: Fri, 14 Aug 2015 16:48:31 +0200
Subject: [GIT PULL 0/9] ARM: tegra: Changes for v4.3-rc1
Message-ID: <1439563720-13189-1-git-send-email-thierry.reding@gmail.com>

Hi ARM SoC maintainers, Mike, Stephen, Linus, Joerg,

Here's a set of pull requests with changes for v4.3-rc1. This is coming
in rather late, but most of this is pretty trivial, so I hope it can
still be merged for the v4.3 window.

Thanks,
Thierry


From thierry.reding at gmail.com  Fri Aug 14 07:48:32 2015
From: thierry.reding at gmail.com (Thierry Reding)
Date: Fri, 14 Aug 2015 16:48:32 +0200
Subject: [GIT PULL 1/9] clk: tegra: Changes for v4.3-rc1
In-Reply-To: <1439563720-13189-1-git-send-email-thierry.reding@gmail.com>
References: <1439563720-13189-1-git-send-email-thierry.reding@gmail.com>
Message-ID: <1439563720-13189-2-git-send-email-thierry.reding@gmail.com>

Hi Mike, Stephen,

The following changes since commit d770e558e21961ad6cfdf0ff7df0eb5d7d4f0754:

  Linux 4.2-rc1 (2015-07-05 11:01:52 -0700)

are available in the git repository at:

  git://git.kernel.org/pub/scm/linux/kernel/git/tegra/linux.git tags/tegra-for-4.3-clk

for you to fetch changes up to 79cf95c763a11d4b365cd5a627fd1ab4dca67890:

  clk: tegra: Add the DFLL as a possible parent of the cclk_g clock (2015-07-16 10:40:20 +0200)

Thanks,
Thierry

----------------------------------------------------------------
clk: tegra: Changes for v4.3-rc1

This contains the DFLL driver needed to implement CPU frequency scaling
on Tegra.

----------------------------------------------------------------
Mikko Perttunen (1):
      clk: tegra: Introduce ability for SoC-specific reset control callbacks

Paul Walmsley (1):
      clk: tegra: Add DFLL DVCO reset control for Tegra124

Tuomas Tynkkynen (7):
      clk: tegra: Add binding for the Tegra124 DFLL clocksource
      clk: tegra: Add library for the DFLL clock source (open-loop mode)
      clk: tegra: Add closed loop support for the DFLL
      clk: tegra: Add functions for parsing CVB tables
      clk: tegra: Add Tegra124 DFLL clocksource platform driver
      clk: tegra: Save/restore CCLKG_BURST_POLICY on suspend
      clk: tegra: Add the DFLL as a possible parent of the cclk_g clock

 .../bindings/clock/nvidia,tegra124-dfll.txt        |   79 +
 arch/arm/mach-tegra/Kconfig                        |    1 +
 drivers/clk/tegra/Makefile                         |    3 +
 drivers/clk/tegra/clk-dfll.c                       | 1755 ++++++++++++++++++++
 drivers/clk/tegra/clk-dfll.h                       |   54 +
 drivers/clk/tegra/clk-tegra-super-gen4.c           |    4 +-
 drivers/clk/tegra/clk-tegra124-dfll-fcpu.c         |  166 ++
 drivers/clk/tegra/clk-tegra124.c                   |   82 +
 drivers/clk/tegra/clk.c                            |   39 +-
 drivers/clk/tegra/clk.h                            |    3 +
 drivers/clk/tegra/cvb.c                            |  140 ++
 drivers/clk/tegra/cvb.h                            |   67 +
 include/dt-bindings/reset/tegra124-car.h           |   12 +
 13 files changed, 2396 insertions(+), 9 deletions(-)
 create mode 100644 Documentation/devicetree/bindings/clock/nvidia,tegra124-dfll.txt
 create mode 100644 drivers/clk/tegra/clk-dfll.c
 create mode 100644 drivers/clk/tegra/clk-dfll.h
 create mode 100644 drivers/clk/tegra/clk-tegra124-dfll-fcpu.c
 create mode 100644 drivers/clk/tegra/cvb.c
 create mode 100644 drivers/clk/tegra/cvb.h
 create mode 100644 include/dt-bindings/reset/tegra124-car.h


From thierry.reding at gmail.com  Fri Aug 14 07:48:33 2015
From: thierry.reding at gmail.com (Thierry Reding)
Date: Fri, 14 Aug 2015 16:48:33 +0200
Subject: [GIT PULL 2/9] pinctrl: tegra: Changes for v4.3-rc1
In-Reply-To: <1439563720-13189-1-git-send-email-thierry.reding@gmail.com>
References: <1439563720-13189-1-git-send-email-thierry.reding@gmail.com>
Message-ID: <1439563720-13189-3-git-send-email-thierry.reding@gmail.com>

Hi Linus,

The following changes since commit d770e558e21961ad6cfdf0ff7df0eb5d7d4f0754:

  Linux 4.2-rc1 (2015-07-05 11:01:52 -0700)

are available in the git repository at:

  git://git.kernel.org/pub/scm/linux/kernel/git/tegra/linux.git tags/tegra-for-4.3-pinctrl

for you to fetch changes up to 9462510ce31e2b91156bdcc33e4c737e6768e5f8:

  pinctrl: tegra: Only set the gpio range if needed (2015-08-13 16:24:33 +0200)

As mentioned before I've created this branch with Tomeu's change and
based the for-4.3/dt branch onto that. Feel free to pull this into your
tree if necessary. It will also go in through the ARM SoC tree via the
device tree updates that depend upon it.

Thierry

----------------------------------------------------------------
pinctrl: tegra: Changes for v4.3-rc1

Contains a single patch from Tomeu to avoid setting up a duplicate GPIO
range.

----------------------------------------------------------------
Tomeu Vizoso (1):
      pinctrl: tegra: Only set the gpio range if needed

 drivers/pinctrl/pinctrl-tegra.c | 19 ++++++++++++++++++-
 1 file changed, 18 insertions(+), 1 deletion(-)


From thierry.reding at gmail.com  Fri Aug 14 07:48:34 2015
From: thierry.reding at gmail.com (Thierry Reding)
Date: Fri, 14 Aug 2015 16:48:34 +0200
Subject: [GIT PULL 3/9] ARM: tegra: Cleanup patches for v4.3-rc1
In-Reply-To: <1439563720-13189-1-git-send-email-thierry.reding@gmail.com>
References: <1439563720-13189-1-git-send-email-thierry.reding@gmail.com>
Message-ID: <1439563720-13189-4-git-send-email-thierry.reding@gmail.com>

Hi ARM SoC maintainers,

The following changes since commit d770e558e21961ad6cfdf0ff7df0eb5d7d4f0754:

  Linux 4.2-rc1 (2015-07-05 11:01:52 -0700)

are available in the git repository at:

  git://git.kernel.org/pub/scm/linux/kernel/git/tegra/linux.git tags/tegra-for-4.3-cleanup

for you to fetch changes up to 5cf4af3bebb718b72a23b7e80fddfe8b4e8b0620:

  ALSA: hda/tegra: Order clock and reset names consistently (2015-07-16 09:42:05 +0200)

Thanks,
Thierry

----------------------------------------------------------------
ARM: tegra: Cleanup patches for v4.3-rc1

Just a couple of trivial cleanups to make the HDA controller driver code
match the device tree binding.

----------------------------------------------------------------
Marcel Ziswiler (1):
      ALSA: hda/tegra - Fix hda2codec_2x clock and reset names

Thierry Reding (1):
      ALSA: hda/tegra: Order clock and reset names consistently

 Documentation/devicetree/bindings/sound/nvidia,tegra30-hda.txt | 8 ++++----
 1 file changed, 4 insertions(+), 4 deletions(-)


From thierry.reding at gmail.com  Fri Aug 14 07:48:35 2015
From: thierry.reding at gmail.com (Thierry Reding)
Date: Fri, 14 Aug 2015 16:48:35 +0200
Subject: [GIT PULL 4/9] ARM: tegra: Core SoC changes for v4.3-rc1
In-Reply-To: <1439563720-13189-1-git-send-email-thierry.reding@gmail.com>
References: <1439563720-13189-1-git-send-email-thierry.reding@gmail.com>
Message-ID: <1439563720-13189-5-git-send-email-thierry.reding@gmail.com>

Hi ARM SoC maintainers,

The following changes since commit d770e558e21961ad6cfdf0ff7df0eb5d7d4f0754:

  Linux 4.2-rc1 (2015-07-05 11:01:52 -0700)

are available in the git repository at:

  git://git.kernel.org/pub/scm/linux/kernel/git/tegra/linux.git tags/tegra-for-4.3-soc

for you to fetch changes up to 1ec0e115f8604940491861d207cc1e1478db97b3:

  ARM: tegra: cpuidle: implement cpuidle_state.enter_freeze() (2015-08-13 16:53:38 +0200)

Thanks,
Thierry

----------------------------------------------------------------
ARM: tegra: Core SoC changes for v4.3-rc1

This contains a bit more of Tegra210 support, which is shaping up pretty
nicely. Other than that there are a couple of cleanup patches here, too.

----------------------------------------------------------------
Masahiro Yamada (1):
      soc: tegra: Remove redundant $(CONFIG_ARCH_TEGRA) in Makefile

Thierry Reding (15):
      soc/tegra: Add Tegra132 support
      soc/tegra: Add Tegra210 support
      soc/tegra: pmc: Avoid usage of uninitialized variable
      soc/tegra: pmc: Restrict legacy code to 32-bit ARM
      soc/tegra: pmc: Add Tegra210 support
      soc/tegra: fuse: Restrict legacy code to 32-bit ARM
      soc/tegra: fuse: Unify Tegra20 and Tegra30 drivers
      soc/tegra: fuse: Add Tegra210 support
      soc/tegra: fuse: Rename core_* to soc_*
      soc/tegra: fuse: Add spare bit offset for Tegra114
      soc/tegra: fuse: Add spare bit offset for Tegra124
      soc/tegra: fuse: Add spare bit offset for Tegra210
      soc/tegra: pmc: Remove unnecessary return statement
      soc/tegra: pmc: Use existing pclk reference
      ARM: tegra: Disable cpuidle if PSCI is available

Tomeu Vizoso (1):
      ARM: tegra: cpuidle: implement cpuidle_state.enter_freeze()

 arch/arm/mach-tegra/cpuidle-tegra114.c   |  19 ++-
 arch/arm/mach-tegra/iomap.h              |   3 -
 drivers/soc/tegra/Makefile               |   6 +-
 drivers/soc/tegra/common.c               |   2 +
 drivers/soc/tegra/fuse/Makefile          |   2 +
 drivers/soc/tegra/fuse/fuse-tegra.c      | 257 ++++++++++++++++++++++++-------
 drivers/soc/tegra/fuse/fuse-tegra20.c    | 175 ++++++++-------------
 drivers/soc/tegra/fuse/fuse-tegra30.c    | 232 ++++++++++------------------
 drivers/soc/tegra/fuse/fuse.h            |  95 ++++++++----
 drivers/soc/tegra/fuse/speedo-tegra114.c |  22 +--
 drivers/soc/tegra/fuse/speedo-tegra124.c |  26 ++--
 drivers/soc/tegra/fuse/speedo-tegra20.c  |  28 ++--
 drivers/soc/tegra/fuse/speedo-tegra210.c | 184 ++++++++++++++++++++++
 drivers/soc/tegra/fuse/speedo-tegra30.c  |  48 +++---
 drivers/soc/tegra/fuse/tegra-apbmisc.c   |  76 +++++++--
 drivers/soc/tegra/pmc.c                  | 125 +++++++++++----
 include/soc/tegra/fuse.h                 |   6 +-
 include/soc/tegra/pmc.h                  |   5 +
 18 files changed, 853 insertions(+), 458 deletions(-)
 create mode 100644 drivers/soc/tegra/fuse/speedo-tegra210.c


From thierry.reding at gmail.com  Fri Aug 14 07:48:36 2015
From: thierry.reding at gmail.com (Thierry Reding)
Date: Fri, 14 Aug 2015 16:48:36 +0200
Subject: [GIT PULL 5/9] ARM: tegra: CPU frequency scaling for v4.3-rc1
In-Reply-To: <1439563720-13189-1-git-send-email-thierry.reding@gmail.com>
References: <1439563720-13189-1-git-send-email-thierry.reding@gmail.com>
Message-ID: <1439563720-13189-6-git-send-email-thierry.reding@gmail.com>

Hi ARM SoC maintainers,

The following changes since commit d770e558e21961ad6cfdf0ff7df0eb5d7d4f0754:

  Linux 4.2-rc1 (2015-07-05 11:01:52 -0700)

are available in the git repository at:

  git://git.kernel.org/pub/scm/linux/kernel/git/tegra/linux.git tags/tegra-for-4.3-cpufreq

for you to fetch changes up to 9eb15dbbfa1a23b5e65efaf1d5d6c47798e7264b:

  cpufreq: Add cpufreq driver for Tegra124 (2015-07-16 09:34:09 +0200)

Thanks,
Thierry

----------------------------------------------------------------
ARM: tegra: CPU frequency scaling for v4.3-rc1

This adds CPU frequency scaling support for Tegra124.

----------------------------------------------------------------
Tuomas Tynkkynen (3):
      cpufreq: tegra124: Add device tree bindings
      cpufreq: tegra: Rename tegra-cpufreq to tegra20-cpufreq
      cpufreq: Add cpufreq driver for Tegra124

 .../bindings/cpufreq/tegra124-cpufreq.txt          |  44 +++++
 drivers/cpufreq/Kconfig.arm                        |  13 +-
 drivers/cpufreq/Makefile                           |   3 +-
 drivers/cpufreq/tegra124-cpufreq.c                 | 214 +++++++++++++++++++++
 .../cpufreq/{tegra-cpufreq.c => tegra20-cpufreq.c} |   0
 5 files changed, 270 insertions(+), 4 deletions(-)
 create mode 100644 Documentation/devicetree/bindings/cpufreq/tegra124-cpufreq.txt
 create mode 100644 drivers/cpufreq/tegra124-cpufreq.c
 rename drivers/cpufreq/{tegra-cpufreq.c => tegra20-cpufreq.c} (100%)


From thierry.reding at gmail.com  Fri Aug 14 07:48:37 2015
From: thierry.reding at gmail.com (Thierry Reding)
Date: Fri, 14 Aug 2015 16:48:37 +0200
Subject: [GIT PULL 6/9] iommu/tegra-smmu: Changes for v4.3-rc1
In-Reply-To: <1439563720-13189-1-git-send-email-thierry.reding@gmail.com>
References: <1439563720-13189-1-git-send-email-thierry.reding@gmail.com>
Message-ID: <1439563720-13189-7-git-send-email-thierry.reding@gmail.com>

Hi Joerg,

The following changes since commit d770e558e21961ad6cfdf0ff7df0eb5d7d4f0754:

  Linux 4.2-rc1 (2015-07-05 11:01:52 -0700)

are available in the git repository at:

  git://git.kernel.org/pub/scm/linux/kernel/git/tegra/linux.git tags/tegra-for-4.3-iommu

for you to fetch changes up to 11cec15bf3fb498206ef63b1fa26c27689e02d0e:

  iommu/tegra-smmu: Parameterize number of TLB lines (2015-08-13 17:05:28 +0200)

This is the pull request with Russell's updates. I've added a patch
on top to unbreak Tegra30, which had been broken since the original
rewrite of the SMMU driver.

Thanks,
Thierry

----------------------------------------------------------------
iommu/tegra-smmu: Changes for v4.3-rc1

A bunch of improvements by Russell King, along with a fix to restore
display support when using the SMMU. This was due to the SMMU driver
writing the wrong value of active TLB lines, effectively disabling the
TLB and causing massive underflows on the display controller because
of the latency introduced by the SMMU.

----------------------------------------------------------------
Russell King (15):
      iommu/tegra-smmu: Fix iova_to_phys() method
      iommu/tegra-smmu: Fix unmap() method
      iommu/tegra-smmu: Factor out common PTE setting
      iommu/tegra-smmu: Add iova_pd_index() and iova_pt_index() helpers
      iommu/tegra-smmu: Fix page table lookup in unmap/iova_to_phys methods
      iommu/tegra-smmu: Store struct page pointer for page tables
      iommu/tegra-smmu: Use kcalloc() to allocate counter array
      iommu/tegra-smmu: Move flush_dcache to tegra-smmu.c
      iommu/tegra-smmu: Split smmu_flush_ptc()
      iommu/tegra-smmu: smmu_flush_ptc() wants device addresses
      iommu/tegra-smmu: Convert to use DMA API
      iommu/tegra-smmu: Remove PageReserved manipulation
      iommu/tegra-smmu: Use __GFP_ZERO to allocate zeroed pages
      iommu/tegra-smmu: Extract tegra_smmu_pte_get_use()
      iommu/tegra-smmu: Factor out tegra_smmu_set_pde()

Thierry Reding (1):
      iommu/tegra-smmu: Parameterize number of TLB lines

 drivers/iommu/tegra-smmu.c      | 306 ++++++++++++++++++++++++++--------------
 drivers/memory/tegra/tegra114.c |  18 +--
 drivers/memory/tegra/tegra124.c |  31 +---
 drivers/memory/tegra/tegra30.c  |  18 +--
 include/soc/tegra/mc.h          |   8 +-
 5 files changed, 202 insertions(+), 179 deletions(-)


From thierry.reding at gmail.com  Fri Aug 14 07:48:38 2015
From: thierry.reding at gmail.com (Thierry Reding)
Date: Fri, 14 Aug 2015 16:48:38 +0200
Subject: [GIT PULL 7/9] ARM: tegra: Memory controller updates for v4.3-rc1
In-Reply-To: <1439563720-13189-1-git-send-email-thierry.reding@gmail.com>
References: <1439563720-13189-1-git-send-email-thierry.reding@gmail.com>
Message-ID: <1439563720-13189-8-git-send-email-thierry.reding@gmail.com>

Hi ARM SoC maintainers,

The following changes since commit d770e558e21961ad6cfdf0ff7df0eb5d7d4f0754:

  Linux 4.2-rc1 (2015-07-05 11:01:52 -0700)

are available in the git repository at:

  git://git.kernel.org/pub/scm/linux/kernel/git/tegra/linux.git tags/tegra-for-4.3-memory

for you to fetch changes up to 588c43a7bd5a53ae523b318e1db16bdd59963a3c:

  memory: tegra: Add Tegra210 support (2015-08-13 16:07:52 +0200)

Thanks,
Thierry

----------------------------------------------------------------
ARM: tegra: Memory controller updates for v4.3-rc1

Adds support for Tegra210, which allows the SMMU to be used on this new
SoC generation.

----------------------------------------------------------------
Paul Walmsley (1):
      memory: tegra: Add support for a variable-size client ID bitfield

Thierry Reding (2):
      memory: tegra: Expose supported rates via debugfs
      memory: tegra: Add Tegra210 support

 drivers/iommu/Kconfig                    |    2 +-
 drivers/memory/tegra/Makefile            |    1 +
 drivers/memory/tegra/mc.c                |    8 +-
 drivers/memory/tegra/mc.h                |    4 +
 drivers/memory/tegra/tegra114.c          |    1 +
 drivers/memory/tegra/tegra124-emc.c      |   42 +-
 drivers/memory/tegra/tegra124.c          |    2 +
 drivers/memory/tegra/tegra210.c          | 1080 ++++++++++++++++++++++++++++++
 drivers/memory/tegra/tegra30.c           |    1 +
 include/dt-bindings/memory/tegra210-mc.h |   36 +
 include/soc/tegra/mc.h                   |    2 +
 11 files changed, 1174 insertions(+), 5 deletions(-)
 create mode 100644 drivers/memory/tegra/tegra210.c
 create mode 100644 include/dt-bindings/memory/tegra210-mc.h


From thierry.reding at gmail.com  Fri Aug 14 07:48:39 2015
From: thierry.reding at gmail.com (Thierry Reding)
Date: Fri, 14 Aug 2015 16:48:39 +0200
Subject: [GIT PULL 8/9] ARM: tegra: Devicetree changes for v4.3-rc1
In-Reply-To: <1439563720-13189-1-git-send-email-thierry.reding@gmail.com>
References: <1439563720-13189-1-git-send-email-thierry.reding@gmail.com>
Message-ID: <1439563720-13189-9-git-send-email-thierry.reding@gmail.com>

Hi ARM SoC maintainers,

The following changes since commit d770e558e21961ad6cfdf0ff7df0eb5d7d4f0754:

  Linux 4.2-rc1 (2015-07-05 11:01:52 -0700)

are available in the git repository at:

  git://git.kernel.org/pub/scm/linux/kernel/git/tegra/linux.git tags/tegra-for-4.3-dt

for you to fetch changes up to 6909c6632fdbea441b5077b4f882c0bf4b71997e:

  ARM: tegra: Add gpio-ranges property (2015-08-13 16:31:53 +0200)

Thanks,
Thierry

----------------------------------------------------------------
ARM: tegra: Devicetree changes for v4.3-rc1

Enables CPU frequency scaling on Jetson TK1 and enables the GK20A GPU on
Venice2 and Jetson TK1. This also enables support for the PMU hardware
found on Tegra124, which among other things, can be used for performance
measurements.

----------------------------------------------------------------
Alexandre Courbot (2):
      ARM: tegra: Add IOMMU node to GK20A
      ARM: tegra: jetson-tk1: Add GK20A GPU DT node

Kyle Huey (1):
      ARM: tegra: Add Tegra124 PMU support

Mikko Perttunen (1):
      ARM: tegra: Add CPU regulator to the Jetson TK1 device tree

Nicolas Chauvet (1):
      ARM: tegra: Fix AHB base address on Tegra20, Tegra30 and Tegra114

Thierry Reding (2):
      Merge branch 'for-4.3/pinctrl' into for-4.3/dt
      ARM: tegra: venice2: Add GK20A GPU DT node

Tomeu Vizoso (2):
      pinctrl: tegra: Only set the gpio range if needed
      ARM: tegra: Add gpio-ranges property

Tuomas Tynkkynen (3):
      ARM: tegra: Add the DFLL to Tegra124 device tree
      ARM: tegra: Enable the DFLL on the Jetson TK1
      ARM: tegra: Add entries for cpufreq on Tegra124

 arch/arm/boot/dts/tegra114.dtsi           |  5 ++--
 arch/arm/boot/dts/tegra124-jetson-tk1.dts | 25 ++++++++++++++--
 arch/arm/boot/dts/tegra124-venice2.dts    | 10 ++++++-
 arch/arm/boot/dts/tegra124.dtsi           | 50 +++++++++++++++++++++++++++++++
 arch/arm/boot/dts/tegra20.dtsi            |  5 ++--
 arch/arm/boot/dts/tegra30.dtsi            |  5 ++--
 drivers/pinctrl/pinctrl-tegra.c           | 19 +++++++++++-
 7 files changed, 109 insertions(+), 10 deletions(-)


From thierry.reding at gmail.com  Fri Aug 14 07:48:40 2015
From: thierry.reding at gmail.com (Thierry Reding)
Date: Fri, 14 Aug 2015 16:48:40 +0200
Subject: [GIT PULL 9/9] ARM: tegra: Default configuration updates for v4.3-rc1
In-Reply-To: <1439563720-13189-1-git-send-email-thierry.reding@gmail.com>
References: <1439563720-13189-1-git-send-email-thierry.reding@gmail.com>
Message-ID: <1439563720-13189-10-git-send-email-thierry.reding@gmail.com>

Hi ARM SoC maintainers,

The following changes since commit d770e558e21961ad6cfdf0ff7df0eb5d7d4f0754:

  Linux 4.2-rc1 (2015-07-05 11:01:52 -0700)

are available in the git repository at:

  git://git.kernel.org/pub/scm/linux/kernel/git/tegra/linux.git tags/tegra-for-4.3-defconfig

for you to fetch changes up to 258d9bc5e77fa40e290a0bd480d5349224374480:

  ARM: tegra: Update multi_v7_defconfig (2015-08-14 16:26:00 +0200)

Thanks,
Thierry

----------------------------------------------------------------
ARM: tegra: Default configuration updates for v4.3-rc1

Enable the GK20A GPU (via the Nouveau driver) and CPU frequency scaling
on Tegra124.

----------------------------------------------------------------
Thierry Reding (1):
      ARM: tegra: Update multi_v7_defconfig

Tuomas Tynkkynen (1):
      ARM: tegra: Update default configuration

 arch/arm/configs/multi_v7_defconfig | 9 +++++++++
 arch/arm/configs/tegra_defconfig    | 9 ++-------
 2 files changed, 11 insertions(+), 7 deletions(-)


From hdegoede at redhat.com  Fri Aug 14 07:50:57 2015
From: hdegoede at redhat.com (Hans de Goede)
Date: Fri, 14 Aug 2015 16:50:57 +0200
Subject: [PATCH 2/6] ARM: dts: sun7i: Enable i2c bus 1 and 2 on the Wits
 A20 Pro DKT
In-Reply-To: <1439563477-12295-3-git-send-email-hdegoede@redhat.com>
References: <1439563477-12295-1-git-send-email-hdegoede@redhat.com>
 <1439563477-12295-3-git-send-email-hdegoede@redhat.com>
Message-ID: <55CE0051.4010403@redhat.com>

Hi Maxime,

On 14-08-15 16:44, Hans de Goede wrote:
> Enable i2c bus 1 and 2 on the Wits A20 Pro DKT, these are used for
> the touchscreen resp. the accelerometer.
>
> Signed-off-by: Hans de Goede <hdegoede at redhat.com>

Erm, please skip this one it depends on another patch
(which adds the sun7i-a20-wits-pro-a20-dkt.dts), which
I've not submitted yet as it depends on the axp
usb-power-supply driver.

So as said please skip this one, I've squashed it into
the patch adding the dts file, which I will submit
later.

Regards,

Hans



> ---
>   arch/arm/boot/dts/sun7i-a20-wits-pro-a20-dkt.dts | 12 ++++++++++++
>   1 file changed, 12 insertions(+)
>
> diff --git a/arch/arm/boot/dts/sun7i-a20-wits-pro-a20-dkt.dts b/arch/arm/boot/dts/sun7i-a20-wits-pro-a20-dkt.dts
> index da47608..85b500d 100644
> --- a/arch/arm/boot/dts/sun7i-a20-wits-pro-a20-dkt.dts
> +++ b/arch/arm/boot/dts/sun7i-a20-wits-pro-a20-dkt.dts
> @@ -92,6 +92,18 @@
>   	};
>   };
>
> +&i2c1 {
> +	pinctrl-names = "default";
> +	pinctrl-0 = <&i2c1_pins_a>;
> +	status = "okay";
> +};
> +
> +&i2c2 {
> +	pinctrl-names = "default";
> +	pinctrl-0 = <&i2c2_pins_a>;
> +	status = "okay";
> +};
> +
>   #include "axp209.dtsi"
>
>   &mmc0 {
>


From bhelgaas at google.com  Fri Aug 14 07:53:10 2015
From: bhelgaas at google.com (Bjorn Helgaas)
Date: Fri, 14 Aug 2015 09:53:10 -0500
Subject: [PATCH v3 0/5] PCI: st: provide support for dw pcie
In-Reply-To: <1428657168-12495-1-git-send-email-gabriel.fernandez@linaro.org>
References: <1428657168-12495-1-git-send-email-gabriel.fernandez@linaro.org>
Message-ID: <20150814145310.GD26431@google.com>

On Fri, Apr 10, 2015 at 11:12:43AM +0200, Gabriel FERNANDEZ wrote:
> Changes in v3:
>  - Remove power management functions (was not fully tested)
>  - Remove configuration space range from dt binding
>  - Remove pci_common_init_dev() call in pcie-designware.c to avoid 
>    default IO space declaration. 
> 
> Changes in v2:
>  - comestic corrections in device tree binding
>  - add pci-st.c into MAINTAINERS
>  - remove st_pcie_ops structure to avoid another level of indirection
>  - remove nasty busy-loop
>  - remove useless test using virt_to_phys()
>  - move disable io support into dw-pcie driver
> 
> I don't change the st_pcie_abort_handler() function because abort handling
> is masked during boot.
> 
> 
> This patch-set introduces a STMicroelectronics PCIe controller.
> It's based on designware PCIe driver.
> 
> Gabriel Fernandez (5):
>   ARM: STi: Kconfig update for PCIe support
>   PCI: st: Add Device Tree bindings for sti pcie
>   PCI: st: Provide support for the sti PCIe controller
>   pci: designware: remove pci_common_init_dev()
>   MAINTAINERS: Add pci-st.c to ARCH/STI architecture

Hi Gabriel,

I lost track of where we are with this.  I *think* I'm waiting for a v4
posting, but I haven't seen it yet.  Let me know if I've missed something.

Bjorn


From gabriele.paoloni at huawei.com  Fri Aug 14 07:55:07 2015
From: gabriele.paoloni at huawei.com (Gabriele Paoloni)
Date: Fri, 14 Aug 2015 14:55:07 +0000
Subject: [PATCH v6 3/6] PCI: designware: Add ARM64 support
In-Reply-To: <55CDFFC0.40604@arm.com>
References: <1438848559-232109-1-git-send-email-wangzhou1@hisilicon.com>
 <1438848559-232109-4-git-send-email-wangzhou1@hisilicon.com>
 <55C44B18.4010103@hisilicon.com> <55CDFFC0.40604@arm.com>
Message-ID: <EE11001F9E5DDD47B7634E2F8A612F2E01D7BC19@lhreml503-mbs>

> 
> I've tested this whole series on an ARM32 PCIe board:'Freescale i.MX6
> Quad
> SABRE Lite Board' with an Intel wireless card on v4.2-rc6.
> 
> I can rescan the bus, load firmware, list nearby APs, and even get MSIs
> coming from the card.
> 
> Tested-By: James Morse <james.morse at arm.com>
> 
> 
> Thanks,
> 
> James

Many Thanks for this James!

Gab


From bhelgaas at google.com  Fri Aug 14 07:57:55 2015
From: bhelgaas at google.com (Bjorn Helgaas)
Date: Fri, 14 Aug 2015 09:57:55 -0500
Subject: [PATCH 2/3] powerpc: PCI: Fix lookup of linux,pci-probe-only
 property
In-Reply-To: <1439563268-13418-3-git-send-email-marc.zyngier@arm.com>
References: <1439563268-13418-1-git-send-email-marc.zyngier@arm.com>
 <1439563268-13418-3-git-send-email-marc.zyngier@arm.com>
Message-ID: <20150814145755.GE26431@google.com>

Hi Marc,

On Fri, Aug 14, 2015 at 03:41:07PM +0100, Marc Zyngier wrote:
> When find_and_init_phbs() looks for the probe-only property, it seems
> to trust the firmware to be correctly written, and assumes that there
> is a parameter to the property.
> 
> It is conceivable that the firmware could not be that perfect, and it
> could expose this property naked (at least one arm64 platform seems to
> exhibit this exact behaviour). The setup code the ends up making
> a decision based on whatever the property pointer points to, which
> is likely to be junk.
> 
> Instead, let's check for the validity of the property, and ignore
> it if the firmware couldn't make up its mind.
> 
> Signed-off-by: Marc Zyngier <marc.zyngier at arm.com>
> ---
>  arch/powerpc/platforms/pseries/setup.c | 15 ++++++++++-----
>  1 file changed, 10 insertions(+), 5 deletions(-)
> 
> diff --git a/arch/powerpc/platforms/pseries/setup.c b/arch/powerpc/platforms/pseries/setup.c
> index df6a704..6bdc1f9 100644
> --- a/arch/powerpc/platforms/pseries/setup.c
> +++ b/arch/powerpc/platforms/pseries/setup.c
> @@ -490,14 +490,19 @@ static void __init find_and_init_phbs(void)
>  	 */
>  	if (of_chosen) {
>  		const int *prop;
> +		int len;
>  
>  		prop = of_get_property(of_chosen,
> -				"linux,pci-probe-only", NULL);
> +				"linux,pci-probe-only", &len);
>  		if (prop) {
> -			if (*prop)
> -				pci_add_flags(PCI_PROBE_ONLY);
> -			else
> -				pci_clear_flags(PCI_PROBE_ONLY);
> +			if (len) {
> +				if (be32_to_cpup(prop))
> +					pci_add_flags(PCI_PROBE_ONLY);
> +				else
> +					pci_clear_flags(PCI_PROBE_ONLY);
> +			} else {
> +				pr_warn("linux,pci-probe-only set without value, ignoring\n");
> +			}

This seems essentially identical to the pci-host-generic version.
Is there a way we can factor it out so there's only one copy?

>  		}
>  	}
>  }
> -- 
> 2.1.4
> 


From mchehab at osg.samsung.com  Fri Aug 14 07:56:38 2015
From: mchehab at osg.samsung.com (Mauro Carvalho Chehab)
Date: Fri, 14 Aug 2015 11:56:38 -0300
Subject: [PATCH v4 1/6] media: get rid of unused "extra_links" param on
 media_entity_init()
In-Reply-To: <cover.1439563682.git.mchehab@osg.samsung.com>
References: <cover.1439563682.git.mchehab@osg.samsung.com>
Message-ID: <b0b576e0bfcc043b4fdab3a57665b525fc054add.1439563682.git.mchehab@osg.samsung.com>

Currently, media_entity_init() creates an array with the links,
allocated at init time. It provides a parameter (extra_links)
that would allocate more links than the current needs, but this
is not used by any driver.

As we want to be able to do dynamic link allocation/removal,
we'll need to change the implementation of the links. So,
before doing that, let's first remove that extra unused
parameter, in order to cleanup the interface first.

Signed-off-by: Mauro Carvalho Chehab <mchehab at osg.samsung.com>
Acked-by: Sakari Ailus <sakari.ailus at linux.intel.com>

diff --git a/Documentation/media-framework.txt b/Documentation/media-framework.txt
index f552a75c0e70..2cc6019f7147 100644
--- a/Documentation/media-framework.txt
+++ b/Documentation/media-framework.txt
@@ -104,7 +104,7 @@ although drivers can allocate entities directly.
 Drivers initialize entities by calling
 
 	media_entity_init(struct media_entity *entity, u16 num_pads,
-			  struct media_pad *pads, u16 extra_links);
+			  struct media_pad *pads);
 
 The media_entity name, type, flags, revision and group_id fields can be
 initialized before or after calling media_entity_init. Entities embedded in
diff --git a/Documentation/video4linux/v4l2-framework.txt b/Documentation/video4linux/v4l2-framework.txt
index 75d5c18d689a..109cc3792534 100644
--- a/Documentation/video4linux/v4l2-framework.txt
+++ b/Documentation/video4linux/v4l2-framework.txt
@@ -300,7 +300,7 @@ calling media_entity_init():
 	struct media_pad *pads = &my_sd->pads;
 	int err;
 
-	err = media_entity_init(&sd->entity, npads, pads, 0);
+	err = media_entity_init(&sd->entity, npads, pads);
 
 The pads array must have been previously initialized. There is no need to
 manually set the struct media_entity type and name fields, but the revision
@@ -700,7 +700,7 @@ calling media_entity_init():
 	struct media_pad *pad = &my_vdev->pad;
 	int err;
 
-	err = media_entity_init(&vdev->entity, 1, pad, 0);
+	err = media_entity_init(&vdev->entity, 1, pad);
 
 The pads array must have been previously initialized. There is no need to
 manually set the struct media_entity type and name fields.
diff --git a/Documentation/zh_CN/video4linux/v4l2-framework.txt b/Documentation/zh_CN/video4linux/v4l2-framework.txt
index 2b828e631e31..ff815cb92031 100644
--- a/Documentation/zh_CN/video4linux/v4l2-framework.txt
+++ b/Documentation/zh_CN/video4linux/v4l2-framework.txt
@@ -295,7 +295,7 @@ owner ??????????????? i2c ?????????????????????????????????????????????
 	struct media_pad *pads = &my_sd->pads;
 	int err;
 
-	err = media_entity_init(&sd->entity, npads, pads, 0);
+	err = media_entity_init(&sd->entity, npads, pads);
 
 pads ???????????????????????????????????????????????? media_entity ??? type ???
 name ????????????????????????revision ?????????????????????
@@ -602,7 +602,7 @@ v4l2_file_operations ???????????? file_operations ???????????????????????????
 	struct media_pad *pad = &my_vdev->pad;
 	int err;
 
-	err = media_entity_init(&vdev->entity, 1, pad, 0);
+	err = media_entity_init(&vdev->entity, 1, pad);
 
 pads ?????????????????????????????????????????????????????? media_entity ??? type ???
 name ??????
diff --git a/drivers/media/dvb-core/dvbdev.c b/drivers/media/dvb-core/dvbdev.c
index 13bb57f0457f..2fdcbb5f000a 100644
--- a/drivers/media/dvb-core/dvbdev.c
+++ b/drivers/media/dvb-core/dvbdev.c
@@ -249,7 +249,7 @@ static void dvb_register_media_device(struct dvb_device *dvbdev,
 	}
 
 	if (npads)
-		ret = media_entity_init(dvbdev->entity, npads, dvbdev->pads, 0);
+		ret = media_entity_init(dvbdev->entity, npads, dvbdev->pads);
 	if (!ret)
 		ret = media_device_register_entity(dvbdev->adapter->mdev,
 						   dvbdev->entity);
diff --git a/drivers/media/i2c/ad9389b.c b/drivers/media/i2c/ad9389b.c
index 69094ab047b1..39d6ee681aeb 100644
--- a/drivers/media/i2c/ad9389b.c
+++ b/drivers/media/i2c/ad9389b.c
@@ -1158,7 +1158,7 @@ static int ad9389b_probe(struct i2c_client *client, const struct i2c_device_id *
 	state->rgb_quantization_range_ctrl->is_private = true;
 
 	state->pad.flags = MEDIA_PAD_FL_SINK;
-	err = media_entity_init(&sd->entity, 1, &state->pad, 0);
+	err = media_entity_init(&sd->entity, 1, &state->pad);
 	if (err)
 		goto err_hdl;
 
diff --git a/drivers/media/i2c/adp1653.c b/drivers/media/i2c/adp1653.c
index c70ababce954..5f76997f6e07 100644
--- a/drivers/media/i2c/adp1653.c
+++ b/drivers/media/i2c/adp1653.c
@@ -512,7 +512,7 @@ static int adp1653_probe(struct i2c_client *client,
 	if (ret)
 		goto free_and_quit;
 
-	ret = media_entity_init(&flash->subdev.entity, 0, NULL, 0);
+	ret = media_entity_init(&flash->subdev.entity, 0, NULL);
 	if (ret < 0)
 		goto free_and_quit;
 
diff --git a/drivers/media/i2c/adv7180.c b/drivers/media/i2c/adv7180.c
index f82c8aa164fa..bab91a1e1525 100644
--- a/drivers/media/i2c/adv7180.c
+++ b/drivers/media/i2c/adv7180.c
@@ -1214,7 +1214,7 @@ static int adv7180_probe(struct i2c_client *client,
 
 	state->pad.flags = MEDIA_PAD_FL_SOURCE;
 	sd->entity.flags |= MEDIA_ENT_T_V4L2_SUBDEV_DECODER;
-	ret = media_entity_init(&sd->entity, 1, &state->pad, 0);
+	ret = media_entity_init(&sd->entity, 1, &state->pad);
 	if (ret)
 		goto err_free_ctrl;
 
diff --git a/drivers/media/i2c/adv7511.c b/drivers/media/i2c/adv7511.c
index ef198cee8969..992ac143a40b 100644
--- a/drivers/media/i2c/adv7511.c
+++ b/drivers/media/i2c/adv7511.c
@@ -1482,7 +1482,7 @@ static int adv7511_probe(struct i2c_client *client, const struct i2c_device_id *
 	state->rgb_quantization_range_ctrl->is_private = true;
 
 	state->pad.flags = MEDIA_PAD_FL_SINK;
-	err = media_entity_init(&sd->entity, 1, &state->pad, 0);
+	err = media_entity_init(&sd->entity, 1, &state->pad);
 	if (err)
 		goto err_hdl;
 
diff --git a/drivers/media/i2c/adv7604.c b/drivers/media/i2c/adv7604.c
index 5631ec004eed..35fccf450870 100644
--- a/drivers/media/i2c/adv7604.c
+++ b/drivers/media/i2c/adv7604.c
@@ -3209,7 +3209,7 @@ static int adv76xx_probe(struct i2c_client *client,
 	state->pads[state->source_pad].flags = MEDIA_PAD_FL_SOURCE;
 
 	err = media_entity_init(&sd->entity, state->source_pad + 1,
-				state->pads, 0);
+				state->pads);
 	if (err)
 		goto err_work_queues;
 
diff --git a/drivers/media/i2c/adv7842.c b/drivers/media/i2c/adv7842.c
index b7269b8f040d..3968d018135c 100644
--- a/drivers/media/i2c/adv7842.c
+++ b/drivers/media/i2c/adv7842.c
@@ -3309,7 +3309,7 @@ static int adv7842_probe(struct i2c_client *client,
 			adv7842_delayed_work_enable_hotplug);
 
 	state->pad.flags = MEDIA_PAD_FL_SOURCE;
-	err = media_entity_init(&sd->entity, 1, &state->pad, 0);
+	err = media_entity_init(&sd->entity, 1, &state->pad);
 	if (err)
 		goto err_work_queues;
 
diff --git a/drivers/media/i2c/as3645a.c b/drivers/media/i2c/as3645a.c
index 301084b07887..9d579a836f79 100644
--- a/drivers/media/i2c/as3645a.c
+++ b/drivers/media/i2c/as3645a.c
@@ -827,7 +827,7 @@ static int as3645a_probe(struct i2c_client *client,
 	if (ret < 0)
 		goto done;
 
-	ret = media_entity_init(&flash->subdev.entity, 0, NULL, 0);
+	ret = media_entity_init(&flash->subdev.entity, 0, NULL);
 	if (ret < 0)
 		goto done;
 
diff --git a/drivers/media/i2c/cx25840/cx25840-core.c b/drivers/media/i2c/cx25840/cx25840-core.c
index fe6eb78b6914..270135d06b32 100644
--- a/drivers/media/i2c/cx25840/cx25840-core.c
+++ b/drivers/media/i2c/cx25840/cx25840-core.c
@@ -5211,7 +5211,7 @@ static int cx25840_probe(struct i2c_client *client,
 	sd->entity.type = MEDIA_ENT_T_V4L2_SUBDEV_DECODER;
 
 	ret = media_entity_init(&sd->entity, ARRAY_SIZE(state->pads),
-				state->pads, 0);
+				state->pads);
 	if (ret < 0) {
 		v4l_info(client, "failed to initialize media entity!\n");
 		return ret;
diff --git a/drivers/media/i2c/lm3560.c b/drivers/media/i2c/lm3560.c
index d9ece4b2d047..9bd9def0852c 100644
--- a/drivers/media/i2c/lm3560.c
+++ b/drivers/media/i2c/lm3560.c
@@ -365,7 +365,7 @@ static int lm3560_subdev_init(struct lm3560_flash *flash,
 	rval = lm3560_init_controls(flash, led_no);
 	if (rval)
 		goto err_out;
-	rval = media_entity_init(&flash->subdev_led[led_no].entity, 0, NULL, 0);
+	rval = media_entity_init(&flash->subdev_led[led_no].entity, 0, NULL);
 	if (rval < 0)
 		goto err_out;
 	flash->subdev_led[led_no].entity.type = MEDIA_ENT_T_V4L2_SUBDEV_FLASH;
diff --git a/drivers/media/i2c/lm3646.c b/drivers/media/i2c/lm3646.c
index 626fb4679c02..4160e18af607 100644
--- a/drivers/media/i2c/lm3646.c
+++ b/drivers/media/i2c/lm3646.c
@@ -282,7 +282,7 @@ static int lm3646_subdev_init(struct lm3646_flash *flash)
 	rval = lm3646_init_controls(flash);
 	if (rval)
 		goto err_out;
-	rval = media_entity_init(&flash->subdev_led.entity, 0, NULL, 0);
+	rval = media_entity_init(&flash->subdev_led.entity, 0, NULL);
 	if (rval < 0)
 		goto err_out;
 	flash->subdev_led.entity.type = MEDIA_ENT_T_V4L2_SUBDEV_FLASH;
diff --git a/drivers/media/i2c/m5mols/m5mols_core.c b/drivers/media/i2c/m5mols/m5mols_core.c
index 6404c0d93e7a..f718a1009e4c 100644
--- a/drivers/media/i2c/m5mols/m5mols_core.c
+++ b/drivers/media/i2c/m5mols/m5mols_core.c
@@ -975,7 +975,7 @@ static int m5mols_probe(struct i2c_client *client,
 
 	sd->internal_ops = &m5mols_subdev_internal_ops;
 	info->pad.flags = MEDIA_PAD_FL_SOURCE;
-	ret = media_entity_init(&sd->entity, 1, &info->pad, 0);
+	ret = media_entity_init(&sd->entity, 1, &info->pad);
 	if (ret < 0)
 		return ret;
 	sd->entity.type = MEDIA_ENT_T_V4L2_SUBDEV_SENSOR;
diff --git a/drivers/media/i2c/mt9m032.c b/drivers/media/i2c/mt9m032.c
index c7747bd0cabb..1493ab6e7fb3 100644
--- a/drivers/media/i2c/mt9m032.c
+++ b/drivers/media/i2c/mt9m032.c
@@ -799,7 +799,7 @@ static int mt9m032_probe(struct i2c_client *client,
 
 	sensor->subdev.ctrl_handler = &sensor->ctrls;
 	sensor->pad.flags = MEDIA_PAD_FL_SOURCE;
-	ret = media_entity_init(&sensor->subdev.entity, 1, &sensor->pad, 0);
+	ret = media_entity_init(&sensor->subdev.entity, 1, &sensor->pad);
 	if (ret < 0)
 		goto error_ctrl;
 
diff --git a/drivers/media/i2c/mt9p031.c b/drivers/media/i2c/mt9p031.c
index 0db15f528ac1..e3c5af82b7c1 100644
--- a/drivers/media/i2c/mt9p031.c
+++ b/drivers/media/i2c/mt9p031.c
@@ -1112,7 +1112,7 @@ static int mt9p031_probe(struct i2c_client *client,
 	mt9p031->subdev.internal_ops = &mt9p031_subdev_internal_ops;
 
 	mt9p031->pad.flags = MEDIA_PAD_FL_SOURCE;
-	ret = media_entity_init(&mt9p031->subdev.entity, 1, &mt9p031->pad, 0);
+	ret = media_entity_init(&mt9p031->subdev.entity, 1, &mt9p031->pad);
 	if (ret < 0)
 		goto done;
 
diff --git a/drivers/media/i2c/mt9t001.c b/drivers/media/i2c/mt9t001.c
index 8ae99f7f254c..1dae1a98bc85 100644
--- a/drivers/media/i2c/mt9t001.c
+++ b/drivers/media/i2c/mt9t001.c
@@ -933,7 +933,7 @@ static int mt9t001_probe(struct i2c_client *client,
 	mt9t001->subdev.flags |= V4L2_SUBDEV_FL_HAS_DEVNODE;
 
 	mt9t001->pad.flags = MEDIA_PAD_FL_SOURCE;
-	ret = media_entity_init(&mt9t001->subdev.entity, 1, &mt9t001->pad, 0);
+	ret = media_entity_init(&mt9t001->subdev.entity, 1, &mt9t001->pad);
 
 done:
 	if (ret < 0) {
diff --git a/drivers/media/i2c/mt9v032.c b/drivers/media/i2c/mt9v032.c
index a68ce94ee097..065659e98719 100644
--- a/drivers/media/i2c/mt9v032.c
+++ b/drivers/media/i2c/mt9v032.c
@@ -1046,7 +1046,7 @@ static int mt9v032_probe(struct i2c_client *client,
 	mt9v032->subdev.flags |= V4L2_SUBDEV_FL_HAS_DEVNODE;
 
 	mt9v032->pad.flags = MEDIA_PAD_FL_SOURCE;
-	ret = media_entity_init(&mt9v032->subdev.entity, 1, &mt9v032->pad, 0);
+	ret = media_entity_init(&mt9v032->subdev.entity, 1, &mt9v032->pad);
 	if (ret < 0)
 		goto err;
 
diff --git a/drivers/media/i2c/noon010pc30.c b/drivers/media/i2c/noon010pc30.c
index f197b6cbd407..a9761251b970 100644
--- a/drivers/media/i2c/noon010pc30.c
+++ b/drivers/media/i2c/noon010pc30.c
@@ -780,7 +780,7 @@ static int noon010_probe(struct i2c_client *client,
 
 	info->pad.flags = MEDIA_PAD_FL_SOURCE;
 	sd->entity.type = MEDIA_ENT_T_V4L2_SUBDEV_SENSOR;
-	ret = media_entity_init(&sd->entity, 1, &info->pad, 0);
+	ret = media_entity_init(&sd->entity, 1, &info->pad);
 	if (ret < 0)
 		goto np_err;
 
diff --git a/drivers/media/i2c/ov2659.c b/drivers/media/i2c/ov2659.c
index 6edffc7b74e3..39f2d2cfdc9c 100644
--- a/drivers/media/i2c/ov2659.c
+++ b/drivers/media/i2c/ov2659.c
@@ -1450,7 +1450,7 @@ static int ov2659_probe(struct i2c_client *client,
 #if defined(CONFIG_MEDIA_CONTROLLER)
 	ov2659->pad.flags = MEDIA_PAD_FL_SOURCE;
 	sd->entity.type = MEDIA_ENT_T_V4L2_SUBDEV_SENSOR;
-	ret = media_entity_init(&sd->entity, 1, &ov2659->pad, 0);
+	ret = media_entity_init(&sd->entity, 1, &ov2659->pad);
 	if (ret < 0) {
 		v4l2_ctrl_handler_free(&ov2659->ctrls);
 		return ret;
diff --git a/drivers/media/i2c/ov9650.c b/drivers/media/i2c/ov9650.c
index 2bc473385c91..6a6747343512 100644
--- a/drivers/media/i2c/ov9650.c
+++ b/drivers/media/i2c/ov9650.c
@@ -1501,7 +1501,7 @@ static int ov965x_probe(struct i2c_client *client,
 
 	ov965x->pad.flags = MEDIA_PAD_FL_SOURCE;
 	sd->entity.type = MEDIA_ENT_T_V4L2_SUBDEV_SENSOR;
-	ret = media_entity_init(&sd->entity, 1, &ov965x->pad, 0);
+	ret = media_entity_init(&sd->entity, 1, &ov965x->pad);
 	if (ret < 0)
 		return ret;
 
diff --git a/drivers/media/i2c/s5c73m3/s5c73m3-core.c b/drivers/media/i2c/s5c73m3/s5c73m3-core.c
index 53c5ea89f0b9..6d167428727d 100644
--- a/drivers/media/i2c/s5c73m3/s5c73m3-core.c
+++ b/drivers/media/i2c/s5c73m3/s5c73m3-core.c
@@ -1691,7 +1691,7 @@ static int s5c73m3_probe(struct i2c_client *client,
 	sd->entity.type = MEDIA_ENT_T_V4L2_SUBDEV;
 
 	ret = media_entity_init(&sd->entity, S5C73M3_NUM_PADS,
-							state->sensor_pads, 0);
+							state->sensor_pads);
 	if (ret < 0)
 		return ret;
 
@@ -1707,7 +1707,7 @@ static int s5c73m3_probe(struct i2c_client *client,
 	oif_sd->entity.type = MEDIA_ENT_T_V4L2_SUBDEV;
 
 	ret = media_entity_init(&oif_sd->entity, OIF_NUM_PADS,
-							state->oif_pads, 0);
+							state->oif_pads);
 	if (ret < 0)
 		return ret;
 
diff --git a/drivers/media/i2c/s5k4ecgx.c b/drivers/media/i2c/s5k4ecgx.c
index 97084237275d..d207ddce31b6 100644
--- a/drivers/media/i2c/s5k4ecgx.c
+++ b/drivers/media/i2c/s5k4ecgx.c
@@ -962,7 +962,7 @@ static int s5k4ecgx_probe(struct i2c_client *client,
 
 	priv->pad.flags = MEDIA_PAD_FL_SOURCE;
 	sd->entity.type = MEDIA_ENT_T_V4L2_SUBDEV_SENSOR;
-	ret = media_entity_init(&sd->entity, 1, &priv->pad, 0);
+	ret = media_entity_init(&sd->entity, 1, &priv->pad);
 	if (ret)
 		return ret;
 
diff --git a/drivers/media/i2c/s5k5baf.c b/drivers/media/i2c/s5k5baf.c
index 774e0d0c94cb..30a9ca62e034 100644
--- a/drivers/media/i2c/s5k5baf.c
+++ b/drivers/media/i2c/s5k5baf.c
@@ -1905,7 +1905,7 @@ static int s5k5baf_configure_subdevs(struct s5k5baf *state,
 
 	state->cis_pad.flags = MEDIA_PAD_FL_SOURCE;
 	sd->entity.type = MEDIA_ENT_T_V4L2_SUBDEV_SENSOR;
-	ret = media_entity_init(&sd->entity, NUM_CIS_PADS, &state->cis_pad, 0);
+	ret = media_entity_init(&sd->entity, NUM_CIS_PADS, &state->cis_pad);
 	if (ret < 0)
 		goto err;
 
@@ -1920,7 +1920,7 @@ static int s5k5baf_configure_subdevs(struct s5k5baf *state,
 	state->pads[PAD_CIS].flags = MEDIA_PAD_FL_SINK;
 	state->pads[PAD_OUT].flags = MEDIA_PAD_FL_SOURCE;
 	sd->entity.type = MEDIA_ENT_T_V4L2_SUBDEV;
-	ret = media_entity_init(&sd->entity, NUM_ISP_PADS, state->pads, 0);
+	ret = media_entity_init(&sd->entity, NUM_ISP_PADS, state->pads);
 
 	if (!ret)
 		return 0;
diff --git a/drivers/media/i2c/s5k6a3.c b/drivers/media/i2c/s5k6a3.c
index b1b1574dfb95..2434a7944781 100644
--- a/drivers/media/i2c/s5k6a3.c
+++ b/drivers/media/i2c/s5k6a3.c
@@ -333,7 +333,7 @@ static int s5k6a3_probe(struct i2c_client *client,
 	sensor->format.height = S5K6A3_DEFAULT_HEIGHT;
 
 	sensor->pad.flags = MEDIA_PAD_FL_SOURCE;
-	ret = media_entity_init(&sd->entity, 1, &sensor->pad, 0);
+	ret = media_entity_init(&sd->entity, 1, &sensor->pad);
 	if (ret < 0)
 		return ret;
 
diff --git a/drivers/media/i2c/s5k6aa.c b/drivers/media/i2c/s5k6aa.c
index d0ad6a25bdab..39a461f9d9bb 100644
--- a/drivers/media/i2c/s5k6aa.c
+++ b/drivers/media/i2c/s5k6aa.c
@@ -1578,7 +1578,7 @@ static int s5k6aa_probe(struct i2c_client *client,
 
 	s5k6aa->pad.flags = MEDIA_PAD_FL_SOURCE;
 	sd->entity.type = MEDIA_ENT_T_V4L2_SUBDEV_SENSOR;
-	ret = media_entity_init(&sd->entity, 1, &s5k6aa->pad, 0);
+	ret = media_entity_init(&sd->entity, 1, &s5k6aa->pad);
 	if (ret)
 		return ret;
 
diff --git a/drivers/media/i2c/smiapp/smiapp-core.c b/drivers/media/i2c/smiapp/smiapp-core.c
index 636ebd6fe5dc..308613ea0aed 100644
--- a/drivers/media/i2c/smiapp/smiapp-core.c
+++ b/drivers/media/i2c/smiapp/smiapp-core.c
@@ -2488,7 +2488,7 @@ static int smiapp_register_subdevs(struct smiapp_sensor *sensor)
 			continue;
 
 		rval = media_entity_init(&this->sd.entity,
-					 this->npads, this->pads, 0);
+					 this->npads, this->pads);
 		if (rval) {
 			dev_err(&client->dev,
 				"media_entity_init failed\n");
@@ -3078,7 +3078,7 @@ static int smiapp_probe(struct i2c_client *client,
 
 	sensor->src->pads[0].flags = MEDIA_PAD_FL_SOURCE;
 	rval = media_entity_init(&sensor->src->sd.entity, 2,
-				 sensor->src->pads, 0);
+				 sensor->src->pads);
 	if (rval < 0)
 		return rval;
 
diff --git a/drivers/media/i2c/tc358743.c b/drivers/media/i2c/tc358743.c
index 2e926317d7e9..6dc6c49a3622 100644
--- a/drivers/media/i2c/tc358743.c
+++ b/drivers/media/i2c/tc358743.c
@@ -1877,7 +1877,7 @@ static int tc358743_probe(struct i2c_client *client,
 	}
 
 	state->pad.flags = MEDIA_PAD_FL_SOURCE;
-	err = media_entity_init(&sd->entity, 1, &state->pad, 0);
+	err = media_entity_init(&sd->entity, 1, &state->pad);
 	if (err < 0)
 		goto err_hdl;
 
diff --git a/drivers/media/i2c/tvp514x.c b/drivers/media/i2c/tvp514x.c
index a93985a9b070..11801636d901 100644
--- a/drivers/media/i2c/tvp514x.c
+++ b/drivers/media/i2c/tvp514x.c
@@ -1097,7 +1097,7 @@ tvp514x_probe(struct i2c_client *client, const struct i2c_device_id *id)
 	decoder->sd.flags |= V4L2_SUBDEV_FL_HAS_DEVNODE;
 	decoder->sd.entity.flags |= MEDIA_ENT_T_V4L2_SUBDEV_DECODER;
 
-	ret = media_entity_init(&decoder->sd.entity, 1, &decoder->pad, 0);
+	ret = media_entity_init(&decoder->sd.entity, 1, &decoder->pad);
 	if (ret < 0) {
 		v4l2_err(sd, "%s decoder driver failed to register !!\n",
 			 sd->name);
diff --git a/drivers/media/i2c/tvp7002.c b/drivers/media/i2c/tvp7002.c
index f617d8b745ee..3630f3e2a4c7 100644
--- a/drivers/media/i2c/tvp7002.c
+++ b/drivers/media/i2c/tvp7002.c
@@ -1014,7 +1014,7 @@ static int tvp7002_probe(struct i2c_client *c, const struct i2c_device_id *id)
 	device->sd.flags |= V4L2_SUBDEV_FL_HAS_DEVNODE;
 	device->sd.entity.flags |= MEDIA_ENT_T_V4L2_SUBDEV_DECODER;
 
-	error = media_entity_init(&device->sd.entity, 1, &device->pad, 0);
+	error = media_entity_init(&device->sd.entity, 1, &device->pad);
 	if (error < 0)
 		return error;
 #endif
diff --git a/drivers/media/media-entity.c b/drivers/media/media-entity.c
index 4d8e01c7b1b2..78440c7aad94 100644
--- a/drivers/media/media-entity.c
+++ b/drivers/media/media-entity.c
@@ -30,7 +30,6 @@
  * media_entity_init - Initialize a media entity
  *
  * @num_pads: Total number of sink and source pads.
- * @extra_links: Initial estimate of the number of extra links.
  * @pads: Array of 'num_pads' pads.
  *
  * The total number of pads is an intrinsic property of entities known by the
@@ -52,10 +51,10 @@
  */
 int
 media_entity_init(struct media_entity *entity, u16 num_pads,
-		  struct media_pad *pads, u16 extra_links)
+		  struct media_pad *pads)
 {
 	struct media_link *links;
-	unsigned int max_links = num_pads + extra_links;
+	unsigned int max_links = num_pads;
 	unsigned int i;
 
 	links = kzalloc(max_links * sizeof(links[0]), GFP_KERNEL);
diff --git a/drivers/media/platform/exynos4-is/fimc-capture.c b/drivers/media/platform/exynos4-is/fimc-capture.c
index cfebf292e15a..0627a93b2f3b 100644
--- a/drivers/media/platform/exynos4-is/fimc-capture.c
+++ b/drivers/media/platform/exynos4-is/fimc-capture.c
@@ -1804,7 +1804,7 @@ static int fimc_register_capture_device(struct fimc_dev *fimc,
 	vid_cap->wb_fmt.code = fmt->mbus_code;
 
 	vid_cap->vd_pad.flags = MEDIA_PAD_FL_SINK;
-	ret = media_entity_init(&vfd->entity, 1, &vid_cap->vd_pad, 0);
+	ret = media_entity_init(&vfd->entity, 1, &vid_cap->vd_pad);
 	if (ret)
 		goto err_free_ctx;
 
@@ -1897,7 +1897,7 @@ int fimc_initialize_capture_subdev(struct fimc_dev *fimc)
 	fimc->vid_cap.sd_pads[FIMC_SD_PAD_SINK_FIFO].flags = MEDIA_PAD_FL_SINK;
 	fimc->vid_cap.sd_pads[FIMC_SD_PAD_SOURCE].flags = MEDIA_PAD_FL_SOURCE;
 	ret = media_entity_init(&sd->entity, FIMC_SD_PADS_NUM,
-				fimc->vid_cap.sd_pads, 0);
+				fimc->vid_cap.sd_pads);
 	if (ret)
 		return ret;
 
diff --git a/drivers/media/platform/exynos4-is/fimc-isp-video.c b/drivers/media/platform/exynos4-is/fimc-isp-video.c
index 76b6b4d14616..b7dc5ac66e36 100644
--- a/drivers/media/platform/exynos4-is/fimc-isp-video.c
+++ b/drivers/media/platform/exynos4-is/fimc-isp-video.c
@@ -618,7 +618,7 @@ int fimc_isp_video_device_register(struct fimc_isp *isp,
 	vdev->lock = &isp->video_lock;
 
 	iv->pad.flags = MEDIA_PAD_FL_SINK;
-	ret = media_entity_init(&vdev->entity, 1, &iv->pad, 0);
+	ret = media_entity_init(&vdev->entity, 1, &iv->pad);
 	if (ret < 0)
 		return ret;
 
diff --git a/drivers/media/platform/exynos4-is/fimc-isp.c b/drivers/media/platform/exynos4-is/fimc-isp.c
index 5d78f5716f3b..f52eebf765c1 100644
--- a/drivers/media/platform/exynos4-is/fimc-isp.c
+++ b/drivers/media/platform/exynos4-is/fimc-isp.c
@@ -709,7 +709,7 @@ int fimc_isp_subdev_create(struct fimc_isp *isp)
 	isp->subdev_pads[FIMC_ISP_SD_PAD_SRC_FIFO].flags = MEDIA_PAD_FL_SOURCE;
 	isp->subdev_pads[FIMC_ISP_SD_PAD_SRC_DMA].flags = MEDIA_PAD_FL_SOURCE;
 	ret = media_entity_init(&sd->entity, FIMC_ISP_SD_PADS_NUM,
-				isp->subdev_pads, 0);
+				isp->subdev_pads);
 	if (ret)
 		return ret;
 
diff --git a/drivers/media/platform/exynos4-is/fimc-lite.c b/drivers/media/platform/exynos4-is/fimc-lite.c
index ca6261a86a5f..e8f707d1729b 100644
--- a/drivers/media/platform/exynos4-is/fimc-lite.c
+++ b/drivers/media/platform/exynos4-is/fimc-lite.c
@@ -1322,7 +1322,7 @@ static int fimc_lite_subdev_registered(struct v4l2_subdev *sd)
 		return ret;
 
 	fimc->vd_pad.flags = MEDIA_PAD_FL_SINK;
-	ret = media_entity_init(&vfd->entity, 1, &fimc->vd_pad, 0);
+	ret = media_entity_init(&vfd->entity, 1, &fimc->vd_pad);
 	if (ret < 0)
 		return ret;
 
@@ -1437,7 +1437,7 @@ static int fimc_lite_create_capture_subdev(struct fimc_lite *fimc)
 	fimc->subdev_pads[FLITE_SD_PAD_SOURCE_DMA].flags = MEDIA_PAD_FL_SOURCE;
 	fimc->subdev_pads[FLITE_SD_PAD_SOURCE_ISP].flags = MEDIA_PAD_FL_SOURCE;
 	ret = media_entity_init(&sd->entity, FLITE_SD_PADS_NUM,
-				fimc->subdev_pads, 0);
+				fimc->subdev_pads);
 	if (ret)
 		return ret;
 
diff --git a/drivers/media/platform/exynos4-is/fimc-m2m.c b/drivers/media/platform/exynos4-is/fimc-m2m.c
index 0ad1b6f84a27..b57daec48b21 100644
--- a/drivers/media/platform/exynos4-is/fimc-m2m.c
+++ b/drivers/media/platform/exynos4-is/fimc-m2m.c
@@ -738,7 +738,7 @@ int fimc_register_m2m_device(struct fimc_dev *fimc,
 		return PTR_ERR(fimc->m2m.m2m_dev);
 	}
 
-	ret = media_entity_init(&vfd->entity, 0, NULL, 0);
+	ret = media_entity_init(&vfd->entity, 0, NULL);
 	if (ret)
 		goto err_me;
 
diff --git a/drivers/media/platform/exynos4-is/mipi-csis.c b/drivers/media/platform/exynos4-is/mipi-csis.c
index d74e1bec3d86..cf10cd783a86 100644
--- a/drivers/media/platform/exynos4-is/mipi-csis.c
+++ b/drivers/media/platform/exynos4-is/mipi-csis.c
@@ -866,7 +866,7 @@ static int s5pcsis_probe(struct platform_device *pdev)
 	state->pads[CSIS_PAD_SINK].flags = MEDIA_PAD_FL_SINK;
 	state->pads[CSIS_PAD_SOURCE].flags = MEDIA_PAD_FL_SOURCE;
 	ret = media_entity_init(&state->sd.entity,
-				CSIS_PADS_NUM, state->pads, 0);
+				CSIS_PADS_NUM, state->pads);
 	if (ret < 0)
 		goto e_clkdis;
 
diff --git a/drivers/media/platform/omap3isp/ispccdc.c b/drivers/media/platform/omap3isp/ispccdc.c
index a6a61cce43dd..3b10304b580b 100644
--- a/drivers/media/platform/omap3isp/ispccdc.c
+++ b/drivers/media/platform/omap3isp/ispccdc.c
@@ -2650,7 +2650,7 @@ static int ccdc_init_entities(struct isp_ccdc_device *ccdc)
 	pads[CCDC_PAD_SOURCE_OF].flags = MEDIA_PAD_FL_SOURCE;
 
 	me->ops = &ccdc_media_ops;
-	ret = media_entity_init(me, CCDC_PADS_NUM, pads, 0);
+	ret = media_entity_init(me, CCDC_PADS_NUM, pads);
 	if (ret < 0)
 		return ret;
 
diff --git a/drivers/media/platform/omap3isp/ispccp2.c b/drivers/media/platform/omap3isp/ispccp2.c
index 38e6a974c5b1..e1b5f5bea541 100644
--- a/drivers/media/platform/omap3isp/ispccp2.c
+++ b/drivers/media/platform/omap3isp/ispccp2.c
@@ -1071,7 +1071,7 @@ static int ccp2_init_entities(struct isp_ccp2_device *ccp2)
 	pads[CCP2_PAD_SOURCE].flags = MEDIA_PAD_FL_SOURCE;
 
 	me->ops = &ccp2_media_ops;
-	ret = media_entity_init(me, CCP2_PADS_NUM, pads, 0);
+	ret = media_entity_init(me, CCP2_PADS_NUM, pads);
 	if (ret < 0)
 		return ret;
 
diff --git a/drivers/media/platform/omap3isp/ispcsi2.c b/drivers/media/platform/omap3isp/ispcsi2.c
index a78338d012b4..6fff92f0813a 100644
--- a/drivers/media/platform/omap3isp/ispcsi2.c
+++ b/drivers/media/platform/omap3isp/ispcsi2.c
@@ -1245,7 +1245,7 @@ static int csi2_init_entities(struct isp_csi2_device *csi2)
 				    | MEDIA_PAD_FL_MUST_CONNECT;
 
 	me->ops = &csi2_media_ops;
-	ret = media_entity_init(me, CSI2_PADS_NUM, pads, 0);
+	ret = media_entity_init(me, CSI2_PADS_NUM, pads);
 	if (ret < 0)
 		return ret;
 
diff --git a/drivers/media/platform/omap3isp/isppreview.c b/drivers/media/platform/omap3isp/isppreview.c
index 13803270d104..b440c6342ca4 100644
--- a/drivers/media/platform/omap3isp/isppreview.c
+++ b/drivers/media/platform/omap3isp/isppreview.c
@@ -2282,7 +2282,7 @@ static int preview_init_entities(struct isp_prev_device *prev)
 	pads[PREV_PAD_SOURCE].flags = MEDIA_PAD_FL_SOURCE;
 
 	me->ops = &preview_media_ops;
-	ret = media_entity_init(me, PREV_PADS_NUM, pads, 0);
+	ret = media_entity_init(me, PREV_PADS_NUM, pads);
 	if (ret < 0)
 		return ret;
 
diff --git a/drivers/media/platform/omap3isp/ispresizer.c b/drivers/media/platform/omap3isp/ispresizer.c
index 7cfb43dc0ffd..3deb1ec4a973 100644
--- a/drivers/media/platform/omap3isp/ispresizer.c
+++ b/drivers/media/platform/omap3isp/ispresizer.c
@@ -1728,7 +1728,7 @@ static int resizer_init_entities(struct isp_res_device *res)
 	pads[RESZ_PAD_SOURCE].flags = MEDIA_PAD_FL_SOURCE;
 
 	me->ops = &resizer_media_ops;
-	ret = media_entity_init(me, RESZ_PADS_NUM, pads, 0);
+	ret = media_entity_init(me, RESZ_PADS_NUM, pads);
 	if (ret < 0)
 		return ret;
 
diff --git a/drivers/media/platform/omap3isp/ispstat.c b/drivers/media/platform/omap3isp/ispstat.c
index 20434e83e801..92a31dd28ace 100644
--- a/drivers/media/platform/omap3isp/ispstat.c
+++ b/drivers/media/platform/omap3isp/ispstat.c
@@ -1029,7 +1029,7 @@ static int isp_stat_init_entities(struct ispstat *stat, const char *name,
 	stat->pad.flags = MEDIA_PAD_FL_SINK | MEDIA_PAD_FL_MUST_CONNECT;
 	me->ops = NULL;
 
-	return media_entity_init(me, 1, &stat->pad, 0);
+	return media_entity_init(me, 1, &stat->pad);
 }
 
 int omap3isp_stat_init(struct ispstat *stat, const char *name,
diff --git a/drivers/media/platform/omap3isp/ispvideo.c b/drivers/media/platform/omap3isp/ispvideo.c
index d285af18df7f..1809e52d2df9 100644
--- a/drivers/media/platform/omap3isp/ispvideo.c
+++ b/drivers/media/platform/omap3isp/ispvideo.c
@@ -1368,7 +1368,7 @@ int omap3isp_video_init(struct isp_video *video, const char *name)
 	if (IS_ERR(video->alloc_ctx))
 		return PTR_ERR(video->alloc_ctx);
 
-	ret = media_entity_init(&video->video.entity, 1, &video->pad, 0);
+	ret = media_entity_init(&video->video.entity, 1, &video->pad);
 	if (ret < 0) {
 		vb2_dma_contig_cleanup_ctx(video->alloc_ctx);
 		return ret;
diff --git a/drivers/media/platform/s3c-camif/camif-capture.c b/drivers/media/platform/s3c-camif/camif-capture.c
index 76e6289a5612..eae667eab1b9 100644
--- a/drivers/media/platform/s3c-camif/camif-capture.c
+++ b/drivers/media/platform/s3c-camif/camif-capture.c
@@ -1159,7 +1159,7 @@ int s3c_camif_register_video_node(struct camif_dev *camif, int idx)
 		goto err_vd_rel;
 
 	vp->pad.flags = MEDIA_PAD_FL_SINK;
-	ret = media_entity_init(&vfd->entity, 1, &vp->pad, 0);
+	ret = media_entity_init(&vfd->entity, 1, &vp->pad);
 	if (ret)
 		goto err_vd_rel;
 
@@ -1575,7 +1575,7 @@ int s3c_camif_create_subdev(struct camif_dev *camif)
 	camif->pads[CAMIF_SD_PAD_SOURCE_P].flags = MEDIA_PAD_FL_SOURCE;
 
 	ret = media_entity_init(&sd->entity, CAMIF_SD_PADS_NUM,
-				camif->pads, 0);
+				camif->pads);
 	if (ret)
 		return ret;
 
diff --git a/drivers/media/platform/vsp1/vsp1_entity.c b/drivers/media/platform/vsp1/vsp1_entity.c
index fd95a75b04f4..619942ff2058 100644
--- a/drivers/media/platform/vsp1/vsp1_entity.c
+++ b/drivers/media/platform/vsp1/vsp1_entity.c
@@ -220,7 +220,7 @@ int vsp1_entity_init(struct vsp1_device *vsp1, struct vsp1_entity *entity,
 
 	/* Initialize the media entity. */
 	return media_entity_init(&entity->subdev.entity, num_pads,
-				 entity->pads, 0);
+				 entity->pads);
 }
 
 void vsp1_entity_destroy(struct vsp1_entity *entity)
diff --git a/drivers/media/platform/vsp1/vsp1_video.c b/drivers/media/platform/vsp1/vsp1_video.c
index 3c124c14ce14..17f08973f835 100644
--- a/drivers/media/platform/vsp1/vsp1_video.c
+++ b/drivers/media/platform/vsp1/vsp1_video.c
@@ -1221,7 +1221,7 @@ int vsp1_video_init(struct vsp1_video *video, struct vsp1_entity *rwpf)
 	video->pipe.state = VSP1_PIPELINE_STOPPED;
 
 	/* Initialize the media entity... */
-	ret = media_entity_init(&video->video.entity, 1, &video->pad, 0);
+	ret = media_entity_init(&video->video.entity, 1, &video->pad);
 	if (ret < 0)
 		return ret;
 
diff --git a/drivers/media/platform/xilinx/xilinx-dma.c b/drivers/media/platform/xilinx/xilinx-dma.c
index e779c93cb015..f7f9aa353a55 100644
--- a/drivers/media/platform/xilinx/xilinx-dma.c
+++ b/drivers/media/platform/xilinx/xilinx-dma.c
@@ -676,7 +676,7 @@ int xvip_dma_init(struct xvip_composite_device *xdev, struct xvip_dma *dma,
 	dma->pad.flags = type == V4L2_BUF_TYPE_VIDEO_CAPTURE
 		       ? MEDIA_PAD_FL_SINK : MEDIA_PAD_FL_SOURCE;
 
-	ret = media_entity_init(&dma->video.entity, 1, &dma->pad, 0);
+	ret = media_entity_init(&dma->video.entity, 1, &dma->pad);
 	if (ret < 0)
 		goto error;
 
diff --git a/drivers/media/platform/xilinx/xilinx-tpg.c b/drivers/media/platform/xilinx/xilinx-tpg.c
index b5f7d5ecb7f6..285976aa0f4d 100644
--- a/drivers/media/platform/xilinx/xilinx-tpg.c
+++ b/drivers/media/platform/xilinx/xilinx-tpg.c
@@ -836,7 +836,7 @@ static int xtpg_probe(struct platform_device *pdev)
 	subdev->flags |= V4L2_SUBDEV_FL_HAS_DEVNODE;
 	subdev->entity.ops = &xtpg_media_ops;
 
-	ret = media_entity_init(&subdev->entity, xtpg->npads, xtpg->pads, 0);
+	ret = media_entity_init(&subdev->entity, xtpg->npads, xtpg->pads);
 	if (ret < 0)
 		goto error;
 
diff --git a/drivers/media/usb/cx231xx/cx231xx-video.c b/drivers/media/usb/cx231xx/cx231xx-video.c
index c6ff8968286a..8f04b125486f 100644
--- a/drivers/media/usb/cx231xx/cx231xx-video.c
+++ b/drivers/media/usb/cx231xx/cx231xx-video.c
@@ -2175,7 +2175,7 @@ int cx231xx_register_analog_devices(struct cx231xx *dev)
 	cx231xx_vdev_init(dev, &dev->vdev, &cx231xx_video_template, "video");
 #if defined(CONFIG_MEDIA_CONTROLLER)
 	dev->video_pad.flags = MEDIA_PAD_FL_SINK;
-	ret = media_entity_init(&dev->vdev.entity, 1, &dev->video_pad, 0);
+	ret = media_entity_init(&dev->vdev.entity, 1, &dev->video_pad);
 	if (ret < 0)
 		dev_err(dev->dev, "failed to initialize video media entity!\n");
 #endif
@@ -2202,7 +2202,7 @@ int cx231xx_register_analog_devices(struct cx231xx *dev)
 
 #if defined(CONFIG_MEDIA_CONTROLLER)
 	dev->vbi_pad.flags = MEDIA_PAD_FL_SINK;
-	ret = media_entity_init(&dev->vbi_dev.entity, 1, &dev->vbi_pad, 0);
+	ret = media_entity_init(&dev->vbi_dev.entity, 1, &dev->vbi_pad);
 	if (ret < 0)
 		dev_err(dev->dev, "failed to initialize vbi media entity!\n");
 #endif
diff --git a/drivers/media/usb/uvc/uvc_entity.c b/drivers/media/usb/uvc/uvc_entity.c
index dc56a59ecadc..245445491516 100644
--- a/drivers/media/usb/uvc/uvc_entity.c
+++ b/drivers/media/usb/uvc/uvc_entity.c
@@ -89,10 +89,10 @@ static int uvc_mc_init_entity(struct uvc_entity *entity)
 			sizeof(entity->subdev.name));
 
 		ret = media_entity_init(&entity->subdev.entity,
-					entity->num_pads, entity->pads, 0);
+					entity->num_pads, entity->pads);
 	} else if (entity->vdev != NULL) {
 		ret = media_entity_init(&entity->vdev->entity,
-					entity->num_pads, entity->pads, 0);
+					entity->num_pads, entity->pads);
 		if (entity->flags & UVC_ENTITY_FLAG_DEFAULT)
 			entity->vdev->entity.flags |= MEDIA_ENT_FL_DEFAULT;
 	} else
diff --git a/drivers/media/v4l2-core/tuner-core.c b/drivers/media/v4l2-core/tuner-core.c
index 581e21ad6801..100b8f069640 100644
--- a/drivers/media/v4l2-core/tuner-core.c
+++ b/drivers/media/v4l2-core/tuner-core.c
@@ -699,7 +699,7 @@ register_client:
 	t->sd.entity.type = MEDIA_ENT_T_V4L2_SUBDEV_TUNER;
 	t->sd.entity.name = t->name;
 
-	ret = media_entity_init(&t->sd.entity, 1, &t->pad, 0);
+	ret = media_entity_init(&t->sd.entity, 1, &t->pad);
 	if (ret < 0) {
 		tuner_err("failed to initialize media entity!\n");
 		kfree(t);
diff --git a/drivers/media/v4l2-core/v4l2-flash-led-class.c b/drivers/media/v4l2-core/v4l2-flash-led-class.c
index 5bdfb8d5263a..34c489fed55e 100644
--- a/drivers/media/v4l2-core/v4l2-flash-led-class.c
+++ b/drivers/media/v4l2-core/v4l2-flash-led-class.c
@@ -651,7 +651,7 @@ struct v4l2_flash *v4l2_flash_init(
 	sd->flags |= V4L2_SUBDEV_FL_HAS_DEVNODE;
 	strlcpy(sd->name, config->dev_name, sizeof(sd->name));
 
-	ret = media_entity_init(&sd->entity, 0, NULL, 0);
+	ret = media_entity_init(&sd->entity, 0, NULL);
 	if (ret < 0)
 		return ERR_PTR(ret);
 
diff --git a/drivers/staging/media/davinci_vpfe/dm365_ipipe.c b/drivers/staging/media/davinci_vpfe/dm365_ipipe.c
index 1bbb90ce0086..b89a057b8b7e 100644
--- a/drivers/staging/media/davinci_vpfe/dm365_ipipe.c
+++ b/drivers/staging/media/davinci_vpfe/dm365_ipipe.c
@@ -1839,7 +1839,7 @@ vpfe_ipipe_init(struct vpfe_ipipe_device *ipipe, struct platform_device *pdev)
 	v4l2_ctrl_handler_setup(&ipipe->ctrls);
 	sd->ctrl_handler = &ipipe->ctrls;
 
-	return media_entity_init(me, IPIPE_PADS_NUM, pads, 0);
+	return media_entity_init(me, IPIPE_PADS_NUM, pads);
 }
 
 /*
diff --git a/drivers/staging/media/davinci_vpfe/dm365_ipipeif.c b/drivers/staging/media/davinci_vpfe/dm365_ipipeif.c
index 8b230541b1d1..8fb676186898 100644
--- a/drivers/staging/media/davinci_vpfe/dm365_ipipeif.c
+++ b/drivers/staging/media/davinci_vpfe/dm365_ipipeif.c
@@ -1026,7 +1026,7 @@ int vpfe_ipipeif_init(struct vpfe_ipipeif_device *ipipeif,
 	ipipeif->output = IPIPEIF_OUTPUT_NONE;
 	me->ops = &ipipeif_media_ops;
 
-	ret = media_entity_init(me, IPIPEIF_NUM_PADS, pads, 0);
+	ret = media_entity_init(me, IPIPEIF_NUM_PADS, pads);
 	if (ret)
 		goto fail;
 
diff --git a/drivers/staging/media/davinci_vpfe/dm365_isif.c b/drivers/staging/media/davinci_vpfe/dm365_isif.c
index 80907b464412..b1f01adfa7c8 100644
--- a/drivers/staging/media/davinci_vpfe/dm365_isif.c
+++ b/drivers/staging/media/davinci_vpfe/dm365_isif.c
@@ -2052,7 +2052,7 @@ int vpfe_isif_init(struct vpfe_isif_device *isif, struct platform_device *pdev)
 	isif->input = ISIF_INPUT_NONE;
 	isif->output = ISIF_OUTPUT_NONE;
 	me->ops = &isif_media_ops;
-	status = media_entity_init(me, ISIF_PADS_NUM, pads, 0);
+	status = media_entity_init(me, ISIF_PADS_NUM, pads);
 	if (status)
 		goto isif_fail;
 	isif->video_out.type = V4L2_BUF_TYPE_VIDEO_CAPTURE;
diff --git a/drivers/staging/media/davinci_vpfe/dm365_resizer.c b/drivers/staging/media/davinci_vpfe/dm365_resizer.c
index acb293ed9c91..692789aa22f4 100644
--- a/drivers/staging/media/davinci_vpfe/dm365_resizer.c
+++ b/drivers/staging/media/davinci_vpfe/dm365_resizer.c
@@ -1915,7 +1915,7 @@ int vpfe_resizer_init(struct vpfe_resizer_device *vpfe_rsz,
 	vpfe_rsz->crop_resizer.output2 = RESIZER_CROP_OUTPUT_NONE;
 	vpfe_rsz->crop_resizer.rsz_device = vpfe_rsz;
 	me->ops = &resizer_media_ops;
-	ret = media_entity_init(me, RESIZER_CROP_PADS_NUM, pads, 0);
+	ret = media_entity_init(me, RESIZER_CROP_PADS_NUM, pads);
 	if (ret)
 		return ret;
 
@@ -1937,7 +1937,7 @@ int vpfe_resizer_init(struct vpfe_resizer_device *vpfe_rsz,
 	vpfe_rsz->resizer_a.output = RESIZER_OUTPUT_NONE;
 	vpfe_rsz->resizer_a.rsz_device = vpfe_rsz;
 	me->ops = &resizer_media_ops;
-	ret = media_entity_init(me, RESIZER_PADS_NUM, pads, 0);
+	ret = media_entity_init(me, RESIZER_PADS_NUM, pads);
 	if (ret)
 		return ret;
 
@@ -1959,7 +1959,7 @@ int vpfe_resizer_init(struct vpfe_resizer_device *vpfe_rsz,
 	vpfe_rsz->resizer_b.output = RESIZER_OUTPUT_NONE;
 	vpfe_rsz->resizer_b.rsz_device = vpfe_rsz;
 	me->ops = &resizer_media_ops;
-	ret = media_entity_init(me, RESIZER_PADS_NUM, pads, 0);
+	ret = media_entity_init(me, RESIZER_PADS_NUM, pads);
 	if (ret)
 		return ret;
 
diff --git a/drivers/staging/media/davinci_vpfe/vpfe_video.c b/drivers/staging/media/davinci_vpfe/vpfe_video.c
index 87048a14c34d..61a8d5beff58 100644
--- a/drivers/staging/media/davinci_vpfe/vpfe_video.c
+++ b/drivers/staging/media/davinci_vpfe/vpfe_video.c
@@ -1594,7 +1594,7 @@ int vpfe_video_init(struct vpfe_video_device *video, const char *name)
 	spin_lock_init(&video->dma_queue_lock);
 	mutex_init(&video->lock);
 	ret = media_entity_init(&video->video_dev.entity,
-				1, &video->pad, 0);
+				1, &video->pad);
 	if (ret < 0)
 		return ret;
 
diff --git a/drivers/staging/media/omap4iss/iss_csi2.c b/drivers/staging/media/omap4iss/iss_csi2.c
index bc83f8246101..e936cfc218cb 100644
--- a/drivers/staging/media/omap4iss/iss_csi2.c
+++ b/drivers/staging/media/omap4iss/iss_csi2.c
@@ -1271,7 +1271,7 @@ static int csi2_init_entities(struct iss_csi2_device *csi2, const char *subname)
 	pads[CSI2_PAD_SINK].flags = MEDIA_PAD_FL_SINK;
 
 	me->ops = &csi2_media_ops;
-	ret = media_entity_init(me, CSI2_PADS_NUM, pads, 0);
+	ret = media_entity_init(me, CSI2_PADS_NUM, pads);
 	if (ret < 0)
 		return ret;
 
diff --git a/drivers/staging/media/omap4iss/iss_ipipe.c b/drivers/staging/media/omap4iss/iss_ipipe.c
index f94a59299a83..e1a7b7ba7362 100644
--- a/drivers/staging/media/omap4iss/iss_ipipe.c
+++ b/drivers/staging/media/omap4iss/iss_ipipe.c
@@ -513,7 +513,7 @@ static int ipipe_init_entities(struct iss_ipipe_device *ipipe)
 	pads[IPIPE_PAD_SOURCE_VP].flags = MEDIA_PAD_FL_SOURCE;
 
 	me->ops = &ipipe_media_ops;
-	ret = media_entity_init(me, IPIPE_PADS_NUM, pads, 0);
+	ret = media_entity_init(me, IPIPE_PADS_NUM, pads);
 	if (ret < 0)
 		return ret;
 
diff --git a/drivers/staging/media/omap4iss/iss_ipipeif.c b/drivers/staging/media/omap4iss/iss_ipipeif.c
index c0da13d55865..be5f80d7b5dc 100644
--- a/drivers/staging/media/omap4iss/iss_ipipeif.c
+++ b/drivers/staging/media/omap4iss/iss_ipipeif.c
@@ -743,7 +743,7 @@ static int ipipeif_init_entities(struct iss_ipipeif_device *ipipeif)
 	pads[IPIPEIF_PAD_SOURCE_VP].flags = MEDIA_PAD_FL_SOURCE;
 
 	me->ops = &ipipeif_media_ops;
-	ret = media_entity_init(me, IPIPEIF_PADS_NUM, pads, 0);
+	ret = media_entity_init(me, IPIPEIF_PADS_NUM, pads);
 	if (ret < 0)
 		return ret;
 
diff --git a/drivers/staging/media/omap4iss/iss_resizer.c b/drivers/staging/media/omap4iss/iss_resizer.c
index 5030cf3cd34c..91e724085dba 100644
--- a/drivers/staging/media/omap4iss/iss_resizer.c
+++ b/drivers/staging/media/omap4iss/iss_resizer.c
@@ -787,7 +787,7 @@ static int resizer_init_entities(struct iss_resizer_device *resizer)
 	pads[RESIZER_PAD_SOURCE_MEM].flags = MEDIA_PAD_FL_SOURCE;
 
 	me->ops = &resizer_media_ops;
-	ret = media_entity_init(me, RESIZER_PADS_NUM, pads, 0);
+	ret = media_entity_init(me, RESIZER_PADS_NUM, pads);
 	if (ret < 0)
 		return ret;
 
diff --git a/drivers/staging/media/omap4iss/iss_video.c b/drivers/staging/media/omap4iss/iss_video.c
index 40405d8710a6..bae67742706f 100644
--- a/drivers/staging/media/omap4iss/iss_video.c
+++ b/drivers/staging/media/omap4iss/iss_video.c
@@ -1104,7 +1104,7 @@ int omap4iss_video_init(struct iss_video *video, const char *name)
 		return -EINVAL;
 	}
 
-	ret = media_entity_init(&video->video.entity, 1, &video->pad, 0);
+	ret = media_entity_init(&video->video.entity, 1, &video->pad);
 	if (ret < 0)
 		return ret;
 
diff --git a/include/media/media-entity.h b/include/media/media-entity.h
index 0c003d817493..8b21a4d920d9 100644
--- a/include/media/media-entity.h
+++ b/include/media/media-entity.h
@@ -127,7 +127,7 @@ struct media_entity_graph {
 };
 
 int media_entity_init(struct media_entity *entity, u16 num_pads,
-		struct media_pad *pads, u16 extra_links);
+		struct media_pad *pads);
 void media_entity_cleanup(struct media_entity *entity);
 
 int media_entity_create_link(struct media_entity *source, u16 source_pad,
-- 
2.4.3



From hverkuil at xs4all.nl  Fri Aug 14 07:59:52 2015
From: hverkuil at xs4all.nl (Hans Verkuil)
Date: Fri, 14 Aug 2015 16:59:52 +0200
Subject: [PATCH v4 1/6] media: get rid of unused "extra_links" param on
 media_entity_init()
In-Reply-To: <b0b576e0bfcc043b4fdab3a57665b525fc054add.1439563682.git.mchehab@osg.samsung.com>
References: <cover.1439563682.git.mchehab@osg.samsung.com>
 <b0b576e0bfcc043b4fdab3a57665b525fc054add.1439563682.git.mchehab@osg.samsung.com>
Message-ID: <55CE0268.9050400@xs4all.nl>

On 08/14/2015 04:56 PM, Mauro Carvalho Chehab wrote:
> Currently, media_entity_init() creates an array with the links,
> allocated at init time. It provides a parameter (extra_links)
> that would allocate more links than the current needs, but this
> is not used by any driver.
> 
> As we want to be able to do dynamic link allocation/removal,
> we'll need to change the implementation of the links. So,
> before doing that, let's first remove that extra unused
> parameter, in order to cleanup the interface first.
> 
> Signed-off-by: Mauro Carvalho Chehab <mchehab at osg.samsung.com>
> Acked-by: Sakari Ailus <sakari.ailus at linux.intel.com>

Acked-by: Hans Verkuil <hans.verkuil at cisco.com>

Thanks!

	Hans


From suneel.garapati at xilinx.com  Fri Aug 14 08:01:02 2015
From: suneel.garapati at xilinx.com (Suneel Garapati)
Date: Fri, 14 Aug 2015 20:31:02 +0530
Subject: [PATCH v3 2/3] drivers: rtc: add xilinx zynqmp rtc driver
In-Reply-To: <1439564462-21252-1-git-send-email-suneel.garapati@xilinx.com>
References: <1439564462-21252-1-git-send-email-suneel.garapati@xilinx.com>
Message-ID: <1439564462-21252-2-git-send-email-suneel.garapati@xilinx.com>

adds support for RTC controller found on
Xilinx Zynq Ultrascale+ MPSoC platform.

Signed-off-by: Suneel Garapati <suneel.garapati at xilinx.com>
---
Changes v3
- fix checkpatch errors
- check time in secs arg against max sec val
- order header files
- use ptr_err_or_zero macro
- use time64 variants
Changes v2 
- change alm to alarm
---
 drivers/rtc/Kconfig      |   7 ++
 drivers/rtc/Makefile     |   1 +
 drivers/rtc/rtc-zynqmp.c | 279 +++++++++++++++++++++++++++++++++++++++++++++++
 3 files changed, 287 insertions(+)
 create mode 100644 drivers/rtc/rtc-zynqmp.c

diff --git a/drivers/rtc/Kconfig b/drivers/rtc/Kconfig
index 35ea04c..bc96277 100644
--- a/drivers/rtc/Kconfig
+++ b/drivers/rtc/Kconfig
@@ -1116,6 +1116,13 @@ config RTC_DRV_OPAL
 	  This driver can also be built as a module. If so, the module
 	  will be called rtc-opal.
 
+config RTC_DRV_ZYNQMP
+	tristate "Xilinx Zynq Ultrascale+ MPSoC RTC"
+	depends on OF
+	help
+	  If you say yes here you get support for the RTC controller found on
+	  Xilinx Zynq Ultrascale+ MPSoC.
+
 comment "on-CPU RTC drivers"
 
 config RTC_DRV_DAVINCI
diff --git a/drivers/rtc/Makefile b/drivers/rtc/Makefile
index 2797384..e491eb5 100644
--- a/drivers/rtc/Makefile
+++ b/drivers/rtc/Makefile
@@ -159,3 +159,4 @@ obj-$(CONFIG_RTC_DRV_WM831X)	+= rtc-wm831x.o
 obj-$(CONFIG_RTC_DRV_WM8350)	+= rtc-wm8350.o
 obj-$(CONFIG_RTC_DRV_X1205)	+= rtc-x1205.o
 obj-$(CONFIG_RTC_DRV_XGENE)	+= rtc-xgene.o
+obj-$(CONFIG_RTC_DRV_ZYNQMP)	+= rtc-zynqmp.o
diff --git a/drivers/rtc/rtc-zynqmp.c b/drivers/rtc/rtc-zynqmp.c
new file mode 100644
index 0000000..8b28762
--- /dev/null
+++ b/drivers/rtc/rtc-zynqmp.c
@@ -0,0 +1,279 @@
+/*
+ * Xilinx Zynq Ultrascale+ MPSoC Real Time Clock Driver
+ *
+ * Copyright (C) 2015 Xilinx, Inc.
+ *
+ * This program is free software; you can redistribute it and/or modify it
+ * under the terms and conditions of the GNU General Public License,
+ * version 2, as published by the Free Software Foundation.
+ *
+ * This program is distributed in the hope 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.
+ *
+ * You should have received a copy of the GNU General Public License along with
+ * this program. If not, see <http://www.gnu.org/licenses/>.
+ *
+ */
+
+#include <linux/delay.h>
+#include <linux/init.h>
+#include <linux/io.h>
+#include <linux/module.h>
+#include <linux/of.h>
+#include <linux/platform_device.h>
+#include <linux/rtc.h>
+
+/* RTC Registers */
+#define RTC_SET_TM_WR		0x00
+#define RTC_SET_TM_RD		0x04
+#define RTC_CALIB_WR		0x08
+#define RTC_CALIB_RD		0x0C
+#define RTC_CUR_TM		0x10
+#define RTC_CUR_TICK		0x14
+#define RTC_ALRM		0x18
+#define RTC_INT_STS		0x20
+#define RTC_INT_MASK		0x24
+#define RTC_INT_EN		0x28
+#define RTC_INT_DIS		0x2C
+#define RTC_CTRL		0x40
+
+#define RTC_FR_EN		BIT(20)
+#define RTC_FR_DATSHIFT		16
+#define RTC_TICK_MASK		0xFFFF
+#define RTC_INT_SEC		BIT(0)
+#define RTC_INT_ALRM		BIT(1)
+#define RTC_OSC_EN		BIT(24)
+
+#define RTC_CALIB_DEF		0x198233
+#define RTC_CALIB_MASK		0x1FFFFF
+#define RTC_SEC_MAX_VAL		0xFFFFFFFF
+
+struct xlnx_rtc_dev {
+	struct rtc_device	*rtc;
+	void __iomem		*reg_base;
+	int			alarm_irq;
+	int			sec_irq;
+};
+
+static int xlnx_rtc_set_time(struct device *dev, struct rtc_time *tm)
+{
+	struct xlnx_rtc_dev *xrtcdev = dev_get_drvdata(dev);
+	unsigned long new_time;
+
+	new_time = rtc_tm_to_time64(tm);
+
+	if (new_time > RTC_SEC_MAX_VAL)
+		return -EINVAL;
+
+	writel(new_time, xrtcdev->reg_base + RTC_SET_TM_WR);
+
+	return 0;
+}
+
+static int xlnx_rtc_read_time(struct device *dev, struct rtc_time *tm)
+{
+	struct xlnx_rtc_dev *xrtcdev = dev_get_drvdata(dev);
+
+	rtc_time64_to_tm(readl(xrtcdev->reg_base + RTC_CUR_TM), tm);
+
+	return rtc_valid_tm(tm);
+}
+
+static int xlnx_rtc_read_alarm(struct device *dev, struct rtc_wkalrm *alrm)
+{
+	struct xlnx_rtc_dev *xrtcdev = dev_get_drvdata(dev);
+
+	rtc_time64_to_tm(readl(xrtcdev->reg_base + RTC_ALRM), &alrm->time);
+	alrm->enabled = readl(xrtcdev->reg_base + RTC_INT_MASK) & RTC_INT_ALRM;
+
+	return 0;
+}
+
+static int xlnx_rtc_alarm_irq_enable(struct device *dev, u32 enabled)
+{
+	struct xlnx_rtc_dev *xrtcdev = dev_get_drvdata(dev);
+
+	if (enabled)
+		writel(RTC_INT_ALRM, xrtcdev->reg_base + RTC_INT_EN);
+	else
+		writel(RTC_INT_ALRM, xrtcdev->reg_base + RTC_INT_DIS);
+
+	return 0;
+}
+
+static int xlnx_rtc_set_alarm(struct device *dev, struct rtc_wkalrm *alrm)
+{
+	struct xlnx_rtc_dev *xrtcdev = dev_get_drvdata(dev);
+	unsigned long alarm_time;
+
+	alarm_time = rtc_tm_to_time64(&alrm->time);
+
+	if (alarm_time > RTC_SEC_MAX_VAL)
+		return -EINVAL;
+
+	writel((u32)alarm_time, (xrtcdev->reg_base + RTC_ALRM));
+
+	xlnx_rtc_alarm_irq_enable(dev, alrm->enabled);
+
+	return 0;
+}
+
+static void xlnx_init_rtc(struct xlnx_rtc_dev *xrtcdev, u32 calibval)
+{
+	/*
+	 * Based on crystal freq of 33.330 KHz
+	 * set the seconds counter and enable, set fractions counter
+	 * to default value suggested as per design spec
+	 * to correct RTC delay in frequency over period of time.
+	 */
+	calibval &= RTC_CALIB_MASK;
+	writel(calibval, (xrtcdev->reg_base + RTC_CALIB_WR));
+}
+
+static const struct rtc_class_ops xlnx_rtc_ops = {
+	.set_time	  = xlnx_rtc_set_time,
+	.read_time	  = xlnx_rtc_read_time,
+	.read_alarm	  = xlnx_rtc_read_alarm,
+	.set_alarm	  = xlnx_rtc_set_alarm,
+	.alarm_irq_enable = xlnx_rtc_alarm_irq_enable,
+};
+
+static irqreturn_t xlnx_rtc_interrupt(int irq, void *id)
+{
+	struct xlnx_rtc_dev *xrtcdev = (struct xlnx_rtc_dev *)id;
+	unsigned int status;
+
+	status = readl(xrtcdev->reg_base + RTC_INT_STS);
+	/* Check if interrupt asserted */
+	if (!(status & (RTC_INT_SEC | RTC_INT_ALRM)))
+		return IRQ_NONE;
+
+	/* Clear interrupt */
+	writel(status, xrtcdev->reg_base + RTC_INT_STS);
+
+	if (status & RTC_INT_SEC)
+		rtc_update_irq(xrtcdev->rtc, 1, RTC_IRQF | RTC_UF);
+	if (status & RTC_INT_ALRM)
+		rtc_update_irq(xrtcdev->rtc, 1, RTC_IRQF | RTC_AF);
+
+	return IRQ_HANDLED;
+}
+
+static int xlnx_rtc_probe(struct platform_device *pdev)
+{
+	struct xlnx_rtc_dev *xrtcdev;
+	struct resource *res;
+	int ret;
+	unsigned int calibvalue;
+
+	xrtcdev = devm_kzalloc(&pdev->dev, sizeof(*xrtcdev), GFP_KERNEL);
+	if (!xrtcdev)
+		return -ENOMEM;
+
+	platform_set_drvdata(pdev, xrtcdev);
+
+	res = platform_get_resource(pdev, IORESOURCE_MEM, 0);
+
+	xrtcdev->reg_base = devm_ioremap_resource(&pdev->dev, res);
+	if (IS_ERR(xrtcdev->reg_base))
+		return PTR_ERR(xrtcdev->reg_base);
+
+	xrtcdev->alarm_irq = platform_get_irq_byname(pdev, "alarm");
+	if (xrtcdev->alarm_irq < 0) {
+		dev_err(&pdev->dev, "no irq resource\n");
+		return xrtcdev->alarm_irq;
+	}
+	ret = devm_request_irq(&pdev->dev, xrtcdev->alarm_irq,
+			       xlnx_rtc_interrupt, 0,
+			       dev_name(&pdev->dev), xrtcdev);
+	if (ret) {
+		dev_err(&pdev->dev, "request irq failed\n");
+		return ret;
+	}
+
+	xrtcdev->sec_irq = platform_get_irq_byname(pdev, "sec");
+	if (xrtcdev->sec_irq < 0) {
+		dev_err(&pdev->dev, "no irq resource\n");
+		return xrtcdev->sec_irq;
+	}
+	ret = devm_request_irq(&pdev->dev, xrtcdev->sec_irq,
+			       xlnx_rtc_interrupt, 0,
+			       dev_name(&pdev->dev), xrtcdev);
+	if (ret) {
+		dev_err(&pdev->dev, "request irq failed\n");
+		return ret;
+	}
+
+	ret = of_property_read_u32(pdev->dev.of_node, "calibration",
+				   &calibvalue);
+	if (ret)
+		calibvalue = RTC_CALIB_DEF;
+
+	xlnx_init_rtc(xrtcdev, calibvalue);
+
+	device_init_wakeup(&pdev->dev, 1);
+
+	xrtcdev->rtc = devm_rtc_device_register(&pdev->dev, pdev->name,
+					 &xlnx_rtc_ops, THIS_MODULE);
+	return PTR_ERR_OR_ZERO(xrtcdev->rtc);
+}
+
+static int xlnx_rtc_remove(struct platform_device *pdev)
+{
+	xlnx_rtc_alarm_irq_enable(&pdev->dev, 0);
+	device_init_wakeup(&pdev->dev, 0);
+
+	return 0;
+}
+
+static int __maybe_unused xlnx_rtc_suspend(struct device *dev)
+{
+	struct platform_device *pdev = to_platform_device(dev);
+	struct xlnx_rtc_dev *xrtcdev = platform_get_drvdata(pdev);
+
+	if (device_may_wakeup(&pdev->dev))
+		enable_irq_wake(xrtcdev->alarm_irq);
+	else
+		xlnx_rtc_alarm_irq_enable(dev, 0);
+
+	return 0;
+}
+
+static int __maybe_unused xlnx_rtc_resume(struct device *dev)
+{
+	struct platform_device *pdev = to_platform_device(dev);
+	struct xlnx_rtc_dev *xrtcdev = platform_get_drvdata(pdev);
+
+	if (device_may_wakeup(&pdev->dev))
+		disable_irq_wake(xrtcdev->alarm_irq);
+	else
+		xlnx_rtc_alarm_irq_enable(dev, 1);
+
+	return 0;
+}
+
+static SIMPLE_DEV_PM_OPS(xlnx_rtc_pm_ops, xlnx_rtc_suspend, xlnx_rtc_resume);
+
+static const struct of_device_id xlnx_rtc_of_match[] = {
+	{.compatible = "xlnx,zynqmp-rtc" },
+	{ }
+};
+MODULE_DEVICE_TABLE(of, xlnx_rtc_of_match);
+
+static struct platform_driver xlnx_rtc_driver = {
+	.probe		= xlnx_rtc_probe,
+	.remove		= xlnx_rtc_remove,
+	.driver		= {
+		.name	= KBUILD_MODNAME,
+		.pm	= &xlnx_rtc_pm_ops,
+		.of_match_table	= xlnx_rtc_of_match,
+	},
+};
+
+module_platform_driver(xlnx_rtc_driver);
+
+MODULE_DESCRIPTION("Xilinx Zynq MPSoC RTC driver");
+MODULE_AUTHOR("Xilinx Inc.");
+MODULE_LICENSE("GPL v2");
-- 
2.1.2



From suneel.garapati at xilinx.com  Fri Aug 14 08:01:01 2015
From: suneel.garapati at xilinx.com (Suneel Garapati)
Date: Fri, 14 Aug 2015 20:31:01 +0530
Subject: [PATCH v3 1/3] devicetree: bindings: rtc: add bindings for xilinx
 zynqmp rtc
Message-ID: <1439564462-21252-1-git-send-email-suneel.garapati@xilinx.com>

adds file for description on device node bindings for RTC
found on Xilinx Zynq Ultrascale+ MPSoC.

Signed-off-by: Suneel Garapati <suneel.garapati at xilinx.com>
---
Changes v3
- none
Changes v2 
- add examples for interrupt-names 
- change alm to alarm 
---
 Documentation/devicetree/bindings/rtc/xlnx-rtc.txt | 25 ++++++++++++++++++++++
 1 file changed, 25 insertions(+)
 create mode 100644 Documentation/devicetree/bindings/rtc/xlnx-rtc.txt

diff --git a/Documentation/devicetree/bindings/rtc/xlnx-rtc.txt b/Documentation/devicetree/bindings/rtc/xlnx-rtc.txt
new file mode 100644
index 0000000..0df6f01
--- /dev/null
+++ b/Documentation/devicetree/bindings/rtc/xlnx-rtc.txt
@@ -0,0 +1,25 @@
+* Xilinx Zynq Ultrascale+ MPSoC Real Time Clock
+
+RTC controller for the Xilinx Zynq MPSoC Real Time Clock
+Separate IRQ lines for seconds and alarm
+
+Required properties:
+- compatible: Should be "xlnx,zynqmp-rtc"
+- reg: Physical base address of the controller and length
+       of memory mapped region.
+- interrupts: IRQ lines for the RTC.
+- interrupt-names: interrupt line names eg. "sec" "alarm"
+
+Optional:
+- calibration: calibration value for 1 sec period which will
+		be programmed directly to calibration register
+
+Example:
+rtc: rtc at ffa60000 {
+	compatible = "xlnx,zynqmp-rtc";
+	reg = <0x0 0xffa60000 0x100>;
+	interrupt-parent = <&gic>;
+	interrupts = <0 26 4>, <0 27 4>;
+	interrupt-names = "alarm", "sec";
+	calibration = <0x198233>;
+};
-- 
2.1.2



From gregory.clement at free-electrons.com  Fri Aug 14 08:06:09 2015
From: gregory.clement at free-electrons.com (Gregory CLEMENT)
Date: Fri, 14 Aug 2015 17:06:09 +0200
Subject: [PATCH] ARM: dma-mapping: Don't use outer_flush_range when the
 L2C is coherent
In-Reply-To: <20150814143000.GF16368@e104818-lin.cambridge.arm.com>
References: <1439474365-12058-1-git-send-email-gregory.clement@free-electrons.com>
 <20150813151603.GB4602@e104818-lin.cambridge.arm.com>
 <55CDE3F6.7050401@free-electrons.com>
 <20150814143000.GF16368@e104818-lin.cambridge.arm.com>
Message-ID: <55CE03E1.5020001@free-electrons.com>

Hi Catalin,

On 14/08/2015 16:30, Catalin Marinas wrote:
>>>> -static void *arm_iommu_alloc_attrs(struct device *dev, size_t size,
>>>> -	    dma_addr_t *handle, gfp_t gfp, struct dma_attrs *attrs)
>>>> +static void *__arm_iommu_alloc_attrs(struct device *dev, size_t size,
>>>> +	    dma_addr_t *handle, gfp_t gfp, struct dma_attrs *attrs,
>>>> +	    bool is_coherent)
>>>>  {
>>>>  	pgprot_t prot = __get_dma_pgprot(attrs, PAGE_KERNEL);
>>>>  	struct page **pages;
>>>> @@ -1381,7 +1395,7 @@ static void *arm_iommu_alloc_attrs(struct device *dev, size_t size,
>>>>  	 */
>>>>  	gfp &= ~(__GFP_COMP);
>>>>  
>>>> -	pages = __iommu_alloc_buffer(dev, size, gfp, attrs);
>>>> +	pages = __iommu_alloc_buffer(dev, size, gfp, attrs, is_coherent);
>>>>  	if (!pages)
>>>>  		return NULL;
>>>>  
>>>
>>> I can see you are trying to fix the iommu_alloc code to cope with
>>> coherent devices. I think it's currently broken and if you want to fix
>>
>> Could you explain what is broken exactly?
>> The way I tried to deal with coherency or something more low level?
> 
> The problem is that __iommu_alloc_atomic() allocates from a
> non-cacheable pool, which is fine when the device is not cache coherent
> but won't work as expected in the is_coherent case (the CPU and device
> must access the memory using the same cacheability attributes).

Thanks for the explanation.

> 
>>> In arm_iommu_alloc_attrs(), there is an __iommu_alloc_atomic() call
>>> which goes to the non-cacheable pool, it should use
>>> __alloc_simple_buffer() instead if is_coherent.
>>
>> __iommu_alloc_atomic is called when GFP_WAIT is not set meaning that
>> we can't sleep, but _alloc_simple_buffer can sleep. I follow the calls
>> inside this function and at a point we found a call to the might_sleep_if
>> macro:
>> http://lxr.free-electrons.com/source/mm/page_alloc.c#L2859
> 
> This might sleep thing is:
> 
> 	might_sleep_if(gfp_mask & __GFP_WAIT);
> 
> So it only sleeps if the __GFP_WAIT is set, but we would only call
> __alloc_simple_buffer() in the !__GFP_WAIT case, so there is no
> sleeping.

Yes my bad I inverted the logic at a point!

> 
> The reason to call __alloc_simple_buffer() (in the atomic alloc case) is
> to get cacheable memory, unlike __alloc_from_pool() which only returns
> memory from the non-cacheable pool.
> 
>> The _alloc_simple_buffer function ended by calling gen_pool_alloc
>> which won't sleep so from my point of view it is still the right
>> function to call. Did I miss something?
> 
> It's not just about sleep vs atomic but about cacheable vs non-cacheable
> as well.
> 
> As a quick fix, below is what I meant. It needs extra snippets from your
> patch to add arm_iommu_alloc_attrs_(coherent|noncoherent) and it's not
> tested, but just to give you an idea:

I am fine to make it a proper patch following my 1st patch. However I don't have
a platform with IOMMU so the test would have to be done by people ahving such
platforms.

Gregory
> 
> diff --git a/arch/arm/mm/dma-mapping.c b/arch/arm/mm/dma-mapping.c
> index 9f509b264346..e20a31d45ff3 100644
> --- a/arch/arm/mm/dma-mapping.c
> +++ b/arch/arm/mm/dma-mapping.c
> @@ -1335,13 +1335,16 @@ static struct page **__iommu_get_pages(void *cpu_addr, struct dma_attrs *attrs)
>  	return NULL;
>  }
>  
> -static void *__iommu_alloc_atomic(struct device *dev, size_t size,
> -				  dma_addr_t *handle)
> +static void *__iommu_alloc_simple(struct device *dev, size_t size, gfp_t gfp,
> +				  dma_addr_t *handle, bool is_coherent)
>  {
>  	struct page *page;
>  	void *addr;
>  
> -	addr = __alloc_from_pool(size, &page);
> +	if (is_coherent)
> +		addr = __alloc_simple_buffer(dev, size, gfp, &page);
> +	else
> +		addr = __alloc_from_pool(size, &page);
>  	if (!addr)
>  		return NULL;
>  
> @@ -1356,15 +1359,18 @@ err_mapping:
>  	return NULL;
>  }
>  
> -static void __iommu_free_atomic(struct device *dev, void *cpu_addr,
> -				dma_addr_t handle, size_t size)
> +static void __iommu_free_simple(struct device *dev, void *cpu_addr,
> +				dma_addr_t handle, size_t size, bool is_coherent)
>  {
>  	__iommu_remove_mapping(dev, handle, size);
> -	__free_from_pool(cpu_addr, size);
> +	if (is_coherent)
> +		__dma_free_buffer(virt_to_page(cpu_addr), size);
> +	else
> +		__free_from_pool(cpu_addr, size);
>  }
>  
> -static void *arm_iommu_alloc_attrs(struct device *dev, size_t size,
> -	    dma_addr_t *handle, gfp_t gfp, struct dma_attrs *attrs)
> +static void *__arm_iommu_alloc_attrs(struct device *dev, size_t size,
> +	    dma_addr_t *handle, gfp_t gfp, struct dma_attrs *attrs, bool is_coherent)
>  {
>  	pgprot_t prot = __get_dma_pgprot(attrs, PAGE_KERNEL);
>  	struct page **pages;
> @@ -1373,8 +1379,8 @@ static void *arm_iommu_alloc_attrs(struct device *dev, size_t size,
>  	*handle = DMA_ERROR_CODE;
>  	size = PAGE_ALIGN(size);
>  
> -	if (!(gfp & __GFP_WAIT))
> -		return __iommu_alloc_atomic(dev, size, handle);
> +	if (is_coherent || !(gfp & __GFP_WAIT))
> +		return __iommu_alloc_simple(dev, size, gfp, handle, is_coherent);
>  
>  	/*
>  	 * Following is a work-around (a.k.a. hack) to prevent pages
> @@ -1440,14 +1446,14 @@ static int arm_iommu_mmap_attrs(struct device *dev, struct vm_area_struct *vma,
>   * free a page as defined by the above mapping.
>   * Must not be called with IRQs disabled.
>   */
> -void arm_iommu_free_attrs(struct device *dev, size_t size, void *cpu_addr,
> -			  dma_addr_t handle, struct dma_attrs *attrs)
> +void __arm_iommu_free_attrs(struct device *dev, size_t size, void *cpu_addr,
> +			  dma_addr_t handle, struct dma_attrs *attrs, bool is_coherent)
>  {
>  	struct page **pages;
>  	size = PAGE_ALIGN(size);
>  
> -	if (__in_atomic_pool(cpu_addr, size)) {
> -		__iommu_free_atomic(dev, cpu_addr, handle, size);
> +	if (is_coherent || __in_atomic_pool(cpu_addr, size)) {
> +		__iommu_free_simple(dev, cpu_addr, handle, size, is_coherent);
>  		return;
>  	}
>  
> 


-- 
Gregory Clement, Free Electrons
Kernel, drivers, real-time and embedded Linux
development, consulting, training and support.
http://free-electrons.com


From suneel.garapati at xilinx.com  Fri Aug 14 08:09:02 2015
From: suneel.garapati at xilinx.com (Suneel Garapati)
Date: Fri, 14 Aug 2015 20:39:02 +0530
Subject: [PATCH v3 1/2] devicetree: bindings: rtc: add bindings for xilinx
 zynqmp rtc
Message-ID: <1439564943-21590-1-git-send-email-suneel.garapati@xilinx.com>

adds file for description on device node bindings for RTC
found on Xilinx Zynq Ultrascale+ MPSoC.

Signed-off-by: Suneel Garapati <suneel.garapati at xilinx.com>
---
Changes v3 
- none 
Changes v2 
- add examples for interrupt-names 
- change alm to alarm 
---
 Documentation/devicetree/bindings/rtc/xlnx-rtc.txt | 25 ++++++++++++++++++++++
 1 file changed, 25 insertions(+)
 create mode 100644 Documentation/devicetree/bindings/rtc/xlnx-rtc.txt

diff --git a/Documentation/devicetree/bindings/rtc/xlnx-rtc.txt b/Documentation/devicetree/bindings/rtc/xlnx-rtc.txt
new file mode 100644
index 0000000..0df6f01
--- /dev/null
+++ b/Documentation/devicetree/bindings/rtc/xlnx-rtc.txt
@@ -0,0 +1,25 @@
+* Xilinx Zynq Ultrascale+ MPSoC Real Time Clock
+
+RTC controller for the Xilinx Zynq MPSoC Real Time Clock
+Separate IRQ lines for seconds and alarm
+
+Required properties:
+- compatible: Should be "xlnx,zynqmp-rtc"
+- reg: Physical base address of the controller and length
+       of memory mapped region.
+- interrupts: IRQ lines for the RTC.
+- interrupt-names: interrupt line names eg. "sec" "alarm"
+
+Optional:
+- calibration: calibration value for 1 sec period which will
+		be programmed directly to calibration register
+
+Example:
+rtc: rtc at ffa60000 {
+	compatible = "xlnx,zynqmp-rtc";
+	reg = <0x0 0xffa60000 0x100>;
+	interrupt-parent = <&gic>;
+	interrupts = <0 26 4>, <0 27 4>;
+	interrupt-names = "alarm", "sec";
+	calibration = <0x198233>;
+};
-- 
2.1.2



From suneel.garapati at xilinx.com  Fri Aug 14 08:09:03 2015
From: suneel.garapati at xilinx.com (Suneel Garapati)
Date: Fri, 14 Aug 2015 20:39:03 +0530
Subject: [PATCH v3 2/2] drivers: rtc: add xilinx zynqmp rtc driver
In-Reply-To: <1439564943-21590-1-git-send-email-suneel.garapati@xilinx.com>
References: <1439564943-21590-1-git-send-email-suneel.garapati@xilinx.com>
Message-ID: <1439564943-21590-2-git-send-email-suneel.garapati@xilinx.com>

adds support for RTC controller found on
Xilinx Zynq Ultrascale+ MPSoC platform.

Signed-off-by: Suneel Garapati <suneel.garapati at xilinx.com>
---
Changes v3 
- fix checkpatch errors 
- check time in secs arg against max sec val 
- order header files 
- use ptr_err_or_zero macro 
- use time64 variants 
Changes v2 
- change alm to alarm 
---
 drivers/rtc/Kconfig      |   7 ++
 drivers/rtc/Makefile     |   1 +
 drivers/rtc/rtc-zynqmp.c | 279 +++++++++++++++++++++++++++++++++++++++++++++++
 3 files changed, 287 insertions(+)
 create mode 100644 drivers/rtc/rtc-zynqmp.c

diff --git a/drivers/rtc/Kconfig b/drivers/rtc/Kconfig
index 35ea04c..bc96277 100644
--- a/drivers/rtc/Kconfig
+++ b/drivers/rtc/Kconfig
@@ -1116,6 +1116,13 @@ config RTC_DRV_OPAL
 	  This driver can also be built as a module. If so, the module
 	  will be called rtc-opal.
 
+config RTC_DRV_ZYNQMP
+	tristate "Xilinx Zynq Ultrascale+ MPSoC RTC"
+	depends on OF
+	help
+	  If you say yes here you get support for the RTC controller found on
+	  Xilinx Zynq Ultrascale+ MPSoC.
+
 comment "on-CPU RTC drivers"
 
 config RTC_DRV_DAVINCI
diff --git a/drivers/rtc/Makefile b/drivers/rtc/Makefile
index 2797384..e491eb5 100644
--- a/drivers/rtc/Makefile
+++ b/drivers/rtc/Makefile
@@ -159,3 +159,4 @@ obj-$(CONFIG_RTC_DRV_WM831X)	+= rtc-wm831x.o
 obj-$(CONFIG_RTC_DRV_WM8350)	+= rtc-wm8350.o
 obj-$(CONFIG_RTC_DRV_X1205)	+= rtc-x1205.o
 obj-$(CONFIG_RTC_DRV_XGENE)	+= rtc-xgene.o
+obj-$(CONFIG_RTC_DRV_ZYNQMP)	+= rtc-zynqmp.o
diff --git a/drivers/rtc/rtc-zynqmp.c b/drivers/rtc/rtc-zynqmp.c
new file mode 100644
index 0000000..8b28762
--- /dev/null
+++ b/drivers/rtc/rtc-zynqmp.c
@@ -0,0 +1,279 @@
+/*
+ * Xilinx Zynq Ultrascale+ MPSoC Real Time Clock Driver
+ *
+ * Copyright (C) 2015 Xilinx, Inc.
+ *
+ * This program is free software; you can redistribute it and/or modify it
+ * under the terms and conditions of the GNU General Public License,
+ * version 2, as published by the Free Software Foundation.
+ *
+ * This program is distributed in the hope 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.
+ *
+ * You should have received a copy of the GNU General Public License along with
+ * this program. If not, see <http://www.gnu.org/licenses/>.
+ *
+ */
+
+#include <linux/delay.h>
+#include <linux/init.h>
+#include <linux/io.h>
+#include <linux/module.h>
+#include <linux/of.h>
+#include <linux/platform_device.h>
+#include <linux/rtc.h>
+
+/* RTC Registers */
+#define RTC_SET_TM_WR		0x00
+#define RTC_SET_TM_RD		0x04
+#define RTC_CALIB_WR		0x08
+#define RTC_CALIB_RD		0x0C
+#define RTC_CUR_TM		0x10
+#define RTC_CUR_TICK		0x14
+#define RTC_ALRM		0x18
+#define RTC_INT_STS		0x20
+#define RTC_INT_MASK		0x24
+#define RTC_INT_EN		0x28
+#define RTC_INT_DIS		0x2C
+#define RTC_CTRL		0x40
+
+#define RTC_FR_EN		BIT(20)
+#define RTC_FR_DATSHIFT		16
+#define RTC_TICK_MASK		0xFFFF
+#define RTC_INT_SEC		BIT(0)
+#define RTC_INT_ALRM		BIT(1)
+#define RTC_OSC_EN		BIT(24)
+
+#define RTC_CALIB_DEF		0x198233
+#define RTC_CALIB_MASK		0x1FFFFF
+#define RTC_SEC_MAX_VAL		0xFFFFFFFF
+
+struct xlnx_rtc_dev {
+	struct rtc_device	*rtc;
+	void __iomem		*reg_base;
+	int			alarm_irq;
+	int			sec_irq;
+};
+
+static int xlnx_rtc_set_time(struct device *dev, struct rtc_time *tm)
+{
+	struct xlnx_rtc_dev *xrtcdev = dev_get_drvdata(dev);
+	unsigned long new_time;
+
+	new_time = rtc_tm_to_time64(tm);
+
+	if (new_time > RTC_SEC_MAX_VAL)
+		return -EINVAL;
+
+	writel(new_time, xrtcdev->reg_base + RTC_SET_TM_WR);
+
+	return 0;
+}
+
+static int xlnx_rtc_read_time(struct device *dev, struct rtc_time *tm)
+{
+	struct xlnx_rtc_dev *xrtcdev = dev_get_drvdata(dev);
+
+	rtc_time64_to_tm(readl(xrtcdev->reg_base + RTC_CUR_TM), tm);
+
+	return rtc_valid_tm(tm);
+}
+
+static int xlnx_rtc_read_alarm(struct device *dev, struct rtc_wkalrm *alrm)
+{
+	struct xlnx_rtc_dev *xrtcdev = dev_get_drvdata(dev);
+
+	rtc_time64_to_tm(readl(xrtcdev->reg_base + RTC_ALRM), &alrm->time);
+	alrm->enabled = readl(xrtcdev->reg_base + RTC_INT_MASK) & RTC_INT_ALRM;
+
+	return 0;
+}
+
+static int xlnx_rtc_alarm_irq_enable(struct device *dev, u32 enabled)
+{
+	struct xlnx_rtc_dev *xrtcdev = dev_get_drvdata(dev);
+
+	if (enabled)
+		writel(RTC_INT_ALRM, xrtcdev->reg_base + RTC_INT_EN);
+	else
+		writel(RTC_INT_ALRM, xrtcdev->reg_base + RTC_INT_DIS);
+
+	return 0;
+}
+
+static int xlnx_rtc_set_alarm(struct device *dev, struct rtc_wkalrm *alrm)
+{
+	struct xlnx_rtc_dev *xrtcdev = dev_get_drvdata(dev);
+	unsigned long alarm_time;
+
+	alarm_time = rtc_tm_to_time64(&alrm->time);
+
+	if (alarm_time > RTC_SEC_MAX_VAL)
+		return -EINVAL;
+
+	writel((u32)alarm_time, (xrtcdev->reg_base + RTC_ALRM));
+
+	xlnx_rtc_alarm_irq_enable(dev, alrm->enabled);
+
+	return 0;
+}
+
+static void xlnx_init_rtc(struct xlnx_rtc_dev *xrtcdev, u32 calibval)
+{
+	/*
+	 * Based on crystal freq of 33.330 KHz
+	 * set the seconds counter and enable, set fractions counter
+	 * to default value suggested as per design spec
+	 * to correct RTC delay in frequency over period of time.
+	 */
+	calibval &= RTC_CALIB_MASK;
+	writel(calibval, (xrtcdev->reg_base + RTC_CALIB_WR));
+}
+
+static const struct rtc_class_ops xlnx_rtc_ops = {
+	.set_time	  = xlnx_rtc_set_time,
+	.read_time	  = xlnx_rtc_read_time,
+	.read_alarm	  = xlnx_rtc_read_alarm,
+	.set_alarm	  = xlnx_rtc_set_alarm,
+	.alarm_irq_enable = xlnx_rtc_alarm_irq_enable,
+};
+
+static irqreturn_t xlnx_rtc_interrupt(int irq, void *id)
+{
+	struct xlnx_rtc_dev *xrtcdev = (struct xlnx_rtc_dev *)id;
+	unsigned int status;
+
+	status = readl(xrtcdev->reg_base + RTC_INT_STS);
+	/* Check if interrupt asserted */
+	if (!(status & (RTC_INT_SEC | RTC_INT_ALRM)))
+		return IRQ_NONE;
+
+	/* Clear interrupt */
+	writel(status, xrtcdev->reg_base + RTC_INT_STS);
+
+	if (status & RTC_INT_SEC)
+		rtc_update_irq(xrtcdev->rtc, 1, RTC_IRQF | RTC_UF);
+	if (status & RTC_INT_ALRM)
+		rtc_update_irq(xrtcdev->rtc, 1, RTC_IRQF | RTC_AF);
+
+	return IRQ_HANDLED;
+}
+
+static int xlnx_rtc_probe(struct platform_device *pdev)
+{
+	struct xlnx_rtc_dev *xrtcdev;
+	struct resource *res;
+	int ret;
+	unsigned int calibvalue;
+
+	xrtcdev = devm_kzalloc(&pdev->dev, sizeof(*xrtcdev), GFP_KERNEL);
+	if (!xrtcdev)
+		return -ENOMEM;
+
+	platform_set_drvdata(pdev, xrtcdev);
+
+	res = platform_get_resource(pdev, IORESOURCE_MEM, 0);
+
+	xrtcdev->reg_base = devm_ioremap_resource(&pdev->dev, res);
+	if (IS_ERR(xrtcdev->reg_base))
+		return PTR_ERR(xrtcdev->reg_base);
+
+	xrtcdev->alarm_irq = platform_get_irq_byname(pdev, "alarm");
+	if (xrtcdev->alarm_irq < 0) {
+		dev_err(&pdev->dev, "no irq resource\n");
+		return xrtcdev->alarm_irq;
+	}
+	ret = devm_request_irq(&pdev->dev, xrtcdev->alarm_irq,
+			       xlnx_rtc_interrupt, 0,
+			       dev_name(&pdev->dev), xrtcdev);
+	if (ret) {
+		dev_err(&pdev->dev, "request irq failed\n");
+		return ret;
+	}
+
+	xrtcdev->sec_irq = platform_get_irq_byname(pdev, "sec");
+	if (xrtcdev->sec_irq < 0) {
+		dev_err(&pdev->dev, "no irq resource\n");
+		return xrtcdev->sec_irq;
+	}
+	ret = devm_request_irq(&pdev->dev, xrtcdev->sec_irq,
+			       xlnx_rtc_interrupt, 0,
+			       dev_name(&pdev->dev), xrtcdev);
+	if (ret) {
+		dev_err(&pdev->dev, "request irq failed\n");
+		return ret;
+	}
+
+	ret = of_property_read_u32(pdev->dev.of_node, "calibration",
+				   &calibvalue);
+	if (ret)
+		calibvalue = RTC_CALIB_DEF;
+
+	xlnx_init_rtc(xrtcdev, calibvalue);
+
+	device_init_wakeup(&pdev->dev, 1);
+
+	xrtcdev->rtc = devm_rtc_device_register(&pdev->dev, pdev->name,
+					 &xlnx_rtc_ops, THIS_MODULE);
+	return PTR_ERR_OR_ZERO(xrtcdev->rtc);
+}
+
+static int xlnx_rtc_remove(struct platform_device *pdev)
+{
+	xlnx_rtc_alarm_irq_enable(&pdev->dev, 0);
+	device_init_wakeup(&pdev->dev, 0);
+
+	return 0;
+}
+
+static int __maybe_unused xlnx_rtc_suspend(struct device *dev)
+{
+	struct platform_device *pdev = to_platform_device(dev);
+	struct xlnx_rtc_dev *xrtcdev = platform_get_drvdata(pdev);
+
+	if (device_may_wakeup(&pdev->dev))
+		enable_irq_wake(xrtcdev->alarm_irq);
+	else
+		xlnx_rtc_alarm_irq_enable(dev, 0);
+
+	return 0;
+}
+
+static int __maybe_unused xlnx_rtc_resume(struct device *dev)
+{
+	struct platform_device *pdev = to_platform_device(dev);
+	struct xlnx_rtc_dev *xrtcdev = platform_get_drvdata(pdev);
+
+	if (device_may_wakeup(&pdev->dev))
+		disable_irq_wake(xrtcdev->alarm_irq);
+	else
+		xlnx_rtc_alarm_irq_enable(dev, 1);
+
+	return 0;
+}
+
+static SIMPLE_DEV_PM_OPS(xlnx_rtc_pm_ops, xlnx_rtc_suspend, xlnx_rtc_resume);
+
+static const struct of_device_id xlnx_rtc_of_match[] = {
+	{.compatible = "xlnx,zynqmp-rtc" },
+	{ }
+};
+MODULE_DEVICE_TABLE(of, xlnx_rtc_of_match);
+
+static struct platform_driver xlnx_rtc_driver = {
+	.probe		= xlnx_rtc_probe,
+	.remove		= xlnx_rtc_remove,
+	.driver		= {
+		.name	= KBUILD_MODNAME,
+		.pm	= &xlnx_rtc_pm_ops,
+		.of_match_table	= xlnx_rtc_of_match,
+	},
+};
+
+module_platform_driver(xlnx_rtc_driver);
+
+MODULE_DESCRIPTION("Xilinx Zynq MPSoC RTC driver");
+MODULE_AUTHOR("Xilinx Inc.");
+MODULE_LICENSE("GPL v2");
-- 
2.1.2



From santosh.shilimkar at oracle.com  Fri Aug 14 08:14:52 2015
From: santosh.shilimkar at oracle.com (santosh shilimkar)
Date: Fri, 14 Aug 2015 08:14:52 -0700
Subject: [PATCH] ARM: keystone: add a work around to handle asynchronous
 external abort
In-Reply-To: <20150814140934.GX7557@n2100.arm.linux.org.uk>
References: <1439320409-20084-1-git-send-email-m-karicheri2@ti.com>
 <55CDF579.4050408@ti.com> <20150814140934.GX7557@n2100.arm.linux.org.uk>
Message-ID: <55CE05EC.4040909@oracle.com>

On 8/14/2015 7:09 AM, Russell King - ARM Linux wrote:
> On Fri, Aug 14, 2015 at 10:04:41AM -0400, Murali Karicheri wrote:
>> On 08/11/2015 03:13 PM, Murali Karicheri wrote:
>>> Currently on some devices, an asynchronous external abort exception
>>> happens during boot up when exception handlers are enabled in kernel
>>> before switching to user space. This patch adds a workaround to handle
>>> this once during boot. Many customers are already using this
>>> with out any issues and is required to workaround the above issue.
>>>
>>> Signed-off-by: Murali Karicheri <m-karicheri2 at ti.com>
>>> ---
>>>   arch/arm/mach-keystone/keystone.c | 26 ++++++++++++++++++++++++++
>>>   1 file changed, 26 insertions(+)
>>>
>>> diff --git a/arch/arm/mach-keystone/keystone.c b/arch/arm/mach-keystone/keystone.c
>>> index e2880105..c1d0fe5 100644
>>> --- a/arch/arm/mach-keystone/keystone.c
>>> +++ b/arch/arm/mach-keystone/keystone.c
>>> @@ -15,6 +15,7 @@
>>>   #include <linux/of_platform.h>
>>>   #include <linux/of_address.h>
>>>   #include <linux/memblock.h>
>>> +#include <linux/signal.h>
>>>
>>>   #include <asm/setup.h>
>>>   #include <asm/mach/map.h>
>>> @@ -52,6 +53,24 @@ static struct notifier_block platform_nb = {
>>>   	.notifier_call = keystone_platform_notifier,
>>>   };
>>>
>>> +static bool ignore_first = true;
>>> +static int keystone_async_ext_abort_fault(unsigned long addr, unsigned int fsr,
>>> +					  struct pt_regs *regs)
>>> +{
>>> +	/*
>>> +	 * if first time, ignore this as this is a asynchronous external abort
>>> +	 * happening only some devices that couldn't be root caused and we add
>>> +	 * this work around to handle this first time.
>>> +	 */
>>> +	if (ignore_first) {
>>> +		ignore_first = false;
>>> +		return 0;
>>> +	}
>>> +
>>> +	/* Subsequent ones should be handled as fault */
>>> +	return 1;
>>> +}
>>> +
>>>   static void __init keystone_init(void)
>>>   {
>>>   	if (PHYS_OFFSET >= KEYSTONE_HIGH_PHYS_START) {
>>> @@ -61,6 +80,13 @@ static void __init keystone_init(void)
>>>   	}
>>>   	keystone_pm_runtime_init();
>>>   	of_platform_populate(NULL, of_default_bus_match_table, NULL, NULL);
>>> +
>>> +	/*
>>> +	 * Add a one time exception handler to catch asynchronous external
>>> +	 * abort
>>> +	 */
>>> +	hook_fault_code(17, keystone_async_ext_abort_fault, SIGBUS, 0,
>>> +			"async external abort handler");
>>>   }
>>>
>>>   static phys_addr_t keystone_virt_to_idmap(unsigned long x)
>>>
>> Can this be applied if it looks good?
>
> What causes the abort?  We shouldn't be adding hacks like this to the
> kernel without having the full picture...
>
Indeed. These external aborts are notorious and often hides dangerous
bugs. On OMAP as well many folks burn their had with it till the
interconnect handlers were added to detect those and hunt those
bugs.

In my experience such aborts happen outside ARM subsystem, either in
the interconnect or at the salve targets which are reported over
the ARM bus as async external aborts. And often these errors are
due to bad accesses/wrong accesses/un-clocked accesses at slaves.

Regards,
Santosh



From laurent.pinchart at ideasonboard.com  Fri Aug 14 08:16:49 2015
From: laurent.pinchart at ideasonboard.com (Laurent Pinchart)
Date: Fri, 14 Aug 2015 18:16:49 +0300
Subject: [PATCH v4 1/6] media: get rid of unused "extra_links" param on
 media_entity_init()
In-Reply-To: <b0b576e0bfcc043b4fdab3a57665b525fc054add.1439563682.git.mchehab@osg.samsung.com>
References: <cover.1439563682.git.mchehab@osg.samsung.com>
 <b0b576e0bfcc043b4fdab3a57665b525fc054add.1439563682.git.mchehab@osg.samsung.com>
Message-ID: <3975256.nCAQDV8Exf@avalon>

Hi Mauro,

Thank you for the patch.

On Friday 14 August 2015 11:56:38 Mauro Carvalho Chehab wrote:
> Currently, media_entity_init() creates an array with the links,
> allocated at init time. It provides a parameter (extra_links)
> that would allocate more links than the current needs, but this
> is not used by any driver.
> 
> As we want to be able to do dynamic link allocation/removal,
> we'll need to change the implementation of the links. So,
> before doing that, let's first remove that extra unused
> parameter, in order to cleanup the interface first.
> 
> Signed-off-by: Mauro Carvalho Chehab <mchehab at osg.samsung.com>
> Acked-by: Sakari Ailus <sakari.ailus at linux.intel.com>
> 
> diff --git a/Documentation/media-framework.txt
> b/Documentation/media-framework.txt index f552a75c0e70..2cc6019f7147 100644
> --- a/Documentation/media-framework.txt
> +++ b/Documentation/media-framework.txt
> @@ -104,7 +104,7 @@ although drivers can allocate entities directly.
>  Drivers initialize entities by calling
> 
>  	media_entity_init(struct media_entity *entity, u16 num_pads,
> -			  struct media_pad *pads, u16 extra_links);
> +			  struct media_pad *pads);
> 
>  The media_entity name, type, flags, revision and group_id fields can be
>  initialized before or after calling media_entity_init. Entities embedded in

The extra_links parameter is documented later on in this file. Could you 
replace the paragraph

"Unlike the number of pads, the total number of links isn't always known in
advance by the entity driver. As an initial estimate, media_entity_init
pre-allocates a number of links equal to the number of pads plus an optional
number of extra links. The links array will be reallocated if it grows beyond
the initial estimate."

with

"Unlike the number of pads, the total number of links isn't always known in
advance by the entity driver. As an initial estimate, media_entity_init
pre-allocates a number of links equal to the number of pads. The links array 
will be reallocated if it grows beyond the initial estimate."

?

[snip]

> diff --git a/drivers/media/media-entity.c b/drivers/media/media-entity.c
> index 4d8e01c7b1b2..78440c7aad94 100644
> --- a/drivers/media/media-entity.c
> +++ b/drivers/media/media-entity.c
> @@ -30,7 +30,6 @@
>   * media_entity_init - Initialize a media entity
>   *
>   * @num_pads: Total number of sink and source pads.
> - * @extra_links: Initial estimate of the number of extra links.
>   * @pads: Array of 'num_pads' pads.
>   *
>   * The total number of pads is an intrinsic property of entities known by
> the

Similarly here, I would rewrite the documentation as

 * The total number of pads is an intrinsic property of entities known by the
 * entity driver, while the total number of links depends on hardware design
 * and is an extrinsic property unknown to the entity driver. However, in most
 * use cases the number of links can safely be assumed to be equal to or
 * larger than the number of pads.
 *
 * For those reasons the links array can be preallocated based on the number
 * of pads and will be reallocated later if extra links need to be created.
 *
 * This function allocates a links array with enough space to hold at least
 * 'num_pads' elements. The media_entity::max_links field will be set to the
 * number of allocated elements.

With that fixed,

Acked-by: Laurent Pinchart <laurent.pinchart at ideasonboard.com>

And feel free to merge this patch for v4.3 independently of the rest.

> @@ -52,10 +51,10 @@
>   */
>  int
>  media_entity_init(struct media_entity *entity, u16 num_pads,
> -		  struct media_pad *pads, u16 extra_links)
> +		  struct media_pad *pads)
>  {
>  	struct media_link *links;
> -	unsigned int max_links = num_pads + extra_links;
> +	unsigned int max_links = num_pads;
>  	unsigned int i;
> 
>  	links = kzalloc(max_links * sizeof(links[0]), GFP_KERNEL);

-- 
Regards,

Laurent Pinchart



From marc.zyngier at arm.com  Fri Aug 14 08:16:06 2015
From: marc.zyngier at arm.com (Marc Zyngier)
Date: Fri, 14 Aug 2015 16:16:06 +0100
Subject: commit a71b092 "ARM: Convert handle_IRQ to use
 __handle_domain_irq" breaks DNS-323
In-Reply-To: <55CDF78F.6070001@free-electrons.com>
References: <55CDF5C3.7080204@vollmann.ch>
 <55CDF78F.6070001@free-electrons.com>
Message-ID: <55CE0636.3050205@arm.com>

On 14/08/15 15:13, Gregory CLEMENT wrote:
> Hi Detlef,
> 
> On 14/08/2015 16:05, Detlef Vollmann wrote:
>> Hello,
>>
>> this commit:
>>  > commit a71b092a9c68685a270ebdde7b5986ba8787e575
>>  > Author: Marc Zyngier <marc.zyngier at arm.com>
>>  > Date:   Tue Aug 26 11:03:18 2014 +0100
>>  >
>>  >     ARM: Convert handle_IRQ to use __handle_domain_irq
>> [...]
>> causes the kernel not to boot anymore on my DNS-323.
>> Soc: MV88F5182 Rev 2
>> CPU: ARM926 (Rev 0) running @ 500Mhz
>> CPU: Feroceon [41069260] revision 0 (ARMv5TEJ), cr=a005317f
>> Orion ID: MV88F5182-A2. TCLK=166666667.
>> DNS-323: Identified HW revision B1
>>
>> Boot stops after "Uncompressing Linux... done, booting the kernel."
>> Reverting the commit works fine for me.
>> Tested 4.1.2 and 4.2.0-rc6 with orion5x_defconfig.
> 
> Could you try the following patch ?
> 
> http://lists.infradead.org/pipermail/linux-arm-kernel/2015-July/356501.html

As a side note, having to revert that patch to get your system up and
running is a reliable indication that something is wrong with your
interrupt mapping, and that you are using 0 as a valid interrupt number
(which has been declared invalid a long time ago by the chief penguin).

Hopefully Gregory has put you in the right direction.

Thanks,

	M.
-- 
Jazz is not dead. It just smells funny...


From lorenzo.pieralisi at arm.com  Fri Aug 14 08:24:38 2015
From: lorenzo.pieralisi at arm.com (Lorenzo Pieralisi)
Date: Fri, 14 Aug 2015 16:24:38 +0100
Subject: [PATCH v4 1/3] PCI: generic: remove dependency on hw_pci
In-Reply-To: <20150814144644.GC26431@google.com>
References: <1438721620-15493-1-git-send-email-jchandra@broadcom.com>
 <20150804234956.GF17327@google.com>
 <007501d0d4ce$1d2dd9c0$57898d40$@samsung.com>
 <20150812090449.GA22485@arm.com>
 <20150814144644.GC26431@google.com>
Message-ID: <20150814152438.GA24806@red-moon>

Hi Bjorn,

On Fri, Aug 14, 2015 at 03:46:44PM +0100, Bjorn Helgaas wrote:
> On Wed, Aug 12, 2015 at 10:04:50AM +0100, Will Deacon wrote:
> > On Wed, Aug 12, 2015 at 08:11:29AM +0100, Pavel Fedin wrote:
> > > > I dropped the acks and tested-by because of that change, but I'll happily
> > > > add them back if Lorenzo and Pavel confirm.  
> > > 
> > >  Confirm.
> > >  Tested-by: Pavel Fedin <p.fedin at samsung.com>
> > > 
> > >  I also added MSI support. Can i post it as patch on top of your branch?
> > 
> > There shouldn't be any need with the changes queued in tip/irq/core. Can
> > you give the following branch a go, please (it doesn't look like Bjorn's
> > stuff is in linux-next, unfortunately)?
> 
> We still have a build issue (undefined reference to pci_write_msi_msg
> in imx_v6_v7_defconfig) to resolve before putting it in linux-next.
> Hopefully we can resolve that today.

I have sent you a fix for that, please let me know if that's ok with
you or you want me to rework it.

Thanks,
Lorenzo


From dv at vollmann.ch  Fri Aug 14 08:35:52 2015
From: dv at vollmann.ch (Detlef Vollmann)
Date: Fri, 14 Aug 2015 17:35:52 +0200
Subject: commit a71b092 "ARM: Convert handle_IRQ to use
 __handle_domain_irq" breaks DNS-323
In-Reply-To: <55CDF78F.6070001@free-electrons.com>
References: <55CDF5C3.7080204@vollmann.ch>
 <55CDF78F.6070001@free-electrons.com>
Message-ID: <55CE0AD8.3030800@vollmann.ch>

Hi Gregory,

On 08/14/15 16:13, Gregory CLEMENT wrote:
> On 14/08/2015 16:05, Detlef Vollmann wrote:
>> Hello,
>>
>> this commit:
>>   > commit a71b092a9c68685a270ebdde7b5986ba8787e575
>>   > Author: Marc Zyngier <marc.zyngier at arm.com>
>>   > Date:   Tue Aug 26 11:03:18 2014 +0100
>>   >
>>   >     ARM: Convert handle_IRQ to use __handle_domain_irq
>> [...]
>> causes the kernel not to boot anymore on my DNS-323.
>> Soc: MV88F5182 Rev 2
>> CPU: ARM926 (Rev 0) running @ 500Mhz
>> CPU: Feroceon [41069260] revision 0 (ARMv5TEJ), cr=a005317f
>> Orion ID: MV88F5182-A2. TCLK=166666667.
>> DNS-323: Identified HW revision B1
>>
>> Boot stops after "Uncompressing Linux... done, booting the kernel."
>> Reverting the commit works fine for me.
>> Tested 4.1.2 and 4.2.0-rc6 with orion5x_defconfig.
>
> Could you try the following patch ?
>
> http://lists.infradead.org/pipermail/linux-arm-kernel/2015-July/356501.html
Thanks for the pointer.
Yes, this patch fixes it :-)

I've also tested Arnd's patch at

http://git.kernel.org/cgit/linux/kernel/git/arnd/playground.git/commit/?h=multiplatform-4.2-next&id=44b55cab3bd74739e4c39205d41e1b2ed8953155

But at least in isolation this doesn't fix the problem.

Thanks again,
   Detlef



From catalin.marinas at arm.com  Fri Aug 14 08:37:22 2015
From: catalin.marinas at arm.com (Catalin Marinas)
Date: Fri, 14 Aug 2015 16:37:22 +0100
Subject: [RFC] arm64: defconfig: enable 48-bit VA by default
In-Reply-To: <CAKv+Gu_4d+cSE_ynsBmk4KmdiEKCT9hv_HWgU0+6e+1ra8OT7Q@mail.gmail.com>
References: <CY1PR0301MB074850E27D5D298D1B8495D2878B0@CY1PR0301MB0748.namprd03.prod.outlook.com>
 <20150730161210.GE407@e104818-lin.cambridge.arm.com>
 <CY1PR0301MB0748FA3A10AFA9BFC1AB0A39878B0@CY1PR0301MB0748.namprd03.prod.outlook.com>
 <CAKv+Gu-Wbv3J9-2KbXrz_3W_=VXChrD+REo1-q1Ns_=RUM1BFw@mail.gmail.com>
 <BY2PR0301MB07436AC9C8D023DC7C67DE3D87730@BY2PR0301MB0743.namprd03.prod.outlook.com>
 <CAKv+Gu-SH7MjkrgevfcUurPc7iQm+11cntfEo84opkqQoN2YPQ@mail.gmail.com>
 <CY1PR0301MB07488764C02CCA3F653ED6A5877D0@CY1PR0301MB0748.namprd03.prod.outlook.com>
 <CAKv+Gu9gvrBwZry+pwXqsso9qg2vZcrYA8wgogRaRPhd6rsJuw@mail.gmail.com>
 <20150814132428.GE16368@e104818-lin.cambridge.arm.com>
 <CAKv+Gu_4d+cSE_ynsBmk4KmdiEKCT9hv_HWgU0+6e+1ra8OT7Q@mail.gmail.com>
Message-ID: <20150814153722.GG16368@e104818-lin.cambridge.arm.com>

On Fri, Aug 14, 2015 at 03:55:19PM +0200, Ard Biesheuvel wrote:
> On 14 August 2015 at 15:24, Catalin Marinas <catalin.marinas at arm.com> wrote:
> > On Fri, Aug 14, 2015 at 02:15:23PM +0200, Ard Biesheuvel wrote:
> >> >> On 7 aug. 2015, at 21:01, Stuart Yoder <stuart.yoder at freescale.com> wrote:
> >> >>
> >> >> >> Whether defconfig supports your platform optimally has nothing to do
> >> >> >> with that. Of course, we should deal with the unexpected memory layout
> >> >> >> gracefully, which is why Mark Rutland and myself proposed patches to
> >> >> >> fix the panic you reported. But in a development context, I think it
> >> >> >> is perfectly acceptable to simply load the kernel at 0x80_8000_0000,
> >> >> >> and be able to run defconfig fine while losing just 2 GB of your 16 GB
> >> >> >> at the low end.
> > [...]
> >> So we still need to decide how to fix the case where the linear region
> >> is not of sufficient size to cover all of memory, considering that is
> >> what got this discussion started in the first place.
> >
> > We already have a solution, just enable 4-levels of page tables (only
> > that I don't think we should change defconfig as well).
> >
> > If we want to do any tricks like compacting the memory range, it needs
> > to be backed by benchmarks to prove that it's worth compared to a full
> > 48-bit VA.
> 
> If you run a 39-bit VA kernel on a system whose DRAM configuration
> covers a larger area than what the linear mapping can support, you
> currently get a panic since phys_to_virt() overflows into the user
> range. So at the very least, we need to clip the range to a size the
> kernel can manage.

Yes, this needs fixing (clipping looks like the best option).

-- 
Catalin


From gregory.clement at free-electrons.com  Fri Aug 14 08:38:20 2015
From: gregory.clement at free-electrons.com (Gregory CLEMENT)
Date: Fri, 14 Aug 2015 17:38:20 +0200
Subject: commit a71b092 "ARM: Convert handle_IRQ to use
 __handle_domain_irq" breaks DNS-323
In-Reply-To: <55CE0AD8.3030800@vollmann.ch>
References: <55CDF5C3.7080204@vollmann.ch>
 <55CDF78F.6070001@free-electrons.com> <55CE0AD8.3030800@vollmann.ch>
Message-ID: <55CE0B6C.509@free-electrons.com>

Hi Detlef,

On 14/08/2015 17:35, Detlef Vollmann wrote:
> Hi Gregory,
> 
> On 08/14/15 16:13, Gregory CLEMENT wrote:
>> On 14/08/2015 16:05, Detlef Vollmann wrote:
>>> Hello,
>>>
>>> this commit:
>>>   > commit a71b092a9c68685a270ebdde7b5986ba8787e575
>>>   > Author: Marc Zyngier <marc.zyngier at arm.com>
>>>   > Date:   Tue Aug 26 11:03:18 2014 +0100
>>>   >
>>>   >     ARM: Convert handle_IRQ to use __handle_domain_irq
>>> [...]
>>> causes the kernel not to boot anymore on my DNS-323.
>>> Soc: MV88F5182 Rev 2
>>> CPU: ARM926 (Rev 0) running @ 500Mhz
>>> CPU: Feroceon [41069260] revision 0 (ARMv5TEJ), cr=a005317f
>>> Orion ID: MV88F5182-A2. TCLK=166666667.
>>> DNS-323: Identified HW revision B1
>>>
>>> Boot stops after "Uncompressing Linux... done, booting the kernel."
>>> Reverting the commit works fine for me.
>>> Tested 4.1.2 and 4.2.0-rc6 with orion5x_defconfig.
>>
>> Could you try the following patch ?
>>
>> http://lists.infradead.org/pipermail/linux-arm-kernel/2015-July/356501.html
> Thanks for the pointer.
> Yes, this patch fixes it :-)
> 
> I've also tested Arnd's patch at
> 
> http://git.kernel.org/cgit/linux/kernel/git/arnd/playground.git/commit/?h=multiplatform-4.2-next&id=44b55cab3bd74739e4c39205d41e1b2ed8953155
> 
> But at least in isolation this doesn't fix the problem.

Thanks for doing these two tests, so I will take Benjamin and also add your
Tested-by if you agree.

Gregory



-- 
Gregory Clement, Free Electrons
Kernel, drivers, real-time and embedded Linux
development, consulting, training and support.
http://free-electrons.com


From dv at vollmann.ch  Fri Aug 14 08:43:28 2015
From: dv at vollmann.ch (Detlef Vollmann)
Date: Fri, 14 Aug 2015 17:43:28 +0200
Subject: commit a71b092 "ARM: Convert handle_IRQ to use
 __handle_domain_irq" breaks DNS-323
In-Reply-To: <55CE0636.3050205@arm.com>
References: <55CDF5C3.7080204@vollmann.ch>
 <55CDF78F.6070001@free-electrons.com> <55CE0636.3050205@arm.com>
Message-ID: <55CE0CA0.5010806@vollmann.ch>

On 08/14/15 17:16, Marc Zyngier wrote:
> On 14/08/15 15:13, Gregory CLEMENT wrote:
>> Hi Detlef,
>>
>> On 14/08/2015 16:05, Detlef Vollmann wrote:
>>> Hello,
>>>
>>> this commit:
>>>   > commit a71b092a9c68685a270ebdde7b5986ba8787e575
>>>   > Author: Marc Zyngier <marc.zyngier at arm.com>
>>>   > Date:   Tue Aug 26 11:03:18 2014 +0100
>>>   >
>>>   >     ARM: Convert handle_IRQ to use __handle_domain_irq
>>> [...]
>>> causes the kernel not to boot anymore on my DNS-323.
>>> Soc: MV88F5182 Rev 2
>>> CPU: ARM926 (Rev 0) running @ 500Mhz
>>> CPU: Feroceon [41069260] revision 0 (ARMv5TEJ), cr=a005317f
>>> Orion ID: MV88F5182-A2. TCLK=166666667.
>>> DNS-323: Identified HW revision B1
>>>
>>> Boot stops after "Uncompressing Linux... done, booting the kernel."
>>> Reverting the commit works fine for me.
>>> Tested 4.1.2 and 4.2.0-rc6 with orion5x_defconfig.
>>
>> Could you try the following patch ?
>>
>> http://lists.infradead.org/pipermail/linux-arm-kernel/2015-July/356501.html
>
> As a side note, having to revert that patch to get your system up and
> running is a reliable indication that something is wrong with your
> interrupt mapping, and that you are using 0 as a valid interrupt number
> (which has been declared invalid a long time ago by the chief penguin).
Well, in this case it wasn't me ;-)
I wanted to avoid looking at the sources myself as the DNS-323 is still
a widely used hardware.

> Hopefully Gregory has put you in the right direction.
Yes.  Now I'll use that patch until some fix is accepted in mainline.

   Detlef



From marc.zyngier at arm.com  Fri Aug 14 08:44:02 2015
From: marc.zyngier at arm.com (Marc Zyngier)
Date: Fri, 14 Aug 2015 16:44:02 +0100
Subject: [PATCH 2/3] powerpc: PCI: Fix lookup of linux,pci-probe-only
 property
In-Reply-To: <20150814145755.GE26431@google.com>
References: <1439563268-13418-1-git-send-email-marc.zyngier@arm.com>
 <1439563268-13418-3-git-send-email-marc.zyngier@arm.com>
 <20150814145755.GE26431@google.com>
Message-ID: <55CE0CC2.7010705@arm.com>

Hi Bjorn,

On 14/08/15 15:57, Bjorn Helgaas wrote:
> Hi Marc,
> 
> On Fri, Aug 14, 2015 at 03:41:07PM +0100, Marc Zyngier wrote:
>> When find_and_init_phbs() looks for the probe-only property, it seems
>> to trust the firmware to be correctly written, and assumes that there
>> is a parameter to the property.
>>
>> It is conceivable that the firmware could not be that perfect, and it
>> could expose this property naked (at least one arm64 platform seems to
>> exhibit this exact behaviour). The setup code the ends up making
>> a decision based on whatever the property pointer points to, which
>> is likely to be junk.
>>
>> Instead, let's check for the validity of the property, and ignore
>> it if the firmware couldn't make up its mind.
>>
>> Signed-off-by: Marc Zyngier <marc.zyngier at arm.com>
>> ---
>>  arch/powerpc/platforms/pseries/setup.c | 15 ++++++++++-----
>>  1 file changed, 10 insertions(+), 5 deletions(-)
>>
>> diff --git a/arch/powerpc/platforms/pseries/setup.c b/arch/powerpc/platforms/pseries/setup.c
>> index df6a704..6bdc1f9 100644
>> --- a/arch/powerpc/platforms/pseries/setup.c
>> +++ b/arch/powerpc/platforms/pseries/setup.c
>> @@ -490,14 +490,19 @@ static void __init find_and_init_phbs(void)
>>  	 */
>>  	if (of_chosen) {
>>  		const int *prop;
>> +		int len;
>>  
>>  		prop = of_get_property(of_chosen,
>> -				"linux,pci-probe-only", NULL);
>> +				"linux,pci-probe-only", &len);
>>  		if (prop) {
>> -			if (*prop)
>> -				pci_add_flags(PCI_PROBE_ONLY);
>> -			else
>> -				pci_clear_flags(PCI_PROBE_ONLY);
>> +			if (len) {
>> +				if (be32_to_cpup(prop))
>> +					pci_add_flags(PCI_PROBE_ONLY);
>> +				else
>> +					pci_clear_flags(PCI_PROBE_ONLY);
>> +			} else {
>> +				pr_warn("linux,pci-probe-only set without value, ignoring\n");
>> +			}
> 
> This seems essentially identical to the pci-host-generic version.
> Is there a way we can factor it out so there's only one copy?

Probably. drivers/of/of_pci.c seems like a good landing place for it.
I'll hack something and repost it.

Thanks,

	M.
-- 
Jazz is not dead. It just smells funny...


From dv at vollmann.ch  Fri Aug 14 08:45:02 2015
From: dv at vollmann.ch (Detlef Vollmann)
Date: Fri, 14 Aug 2015 17:45:02 +0200
Subject: commit a71b092 "ARM: Convert handle_IRQ to use
 __handle_domain_irq" breaks DNS-323
In-Reply-To: <55CE0B6C.509@free-electrons.com>
References: <55CDF5C3.7080204@vollmann.ch>
 <55CDF78F.6070001@free-electrons.com> <55CE0AD8.3030800@vollmann.ch>
 <55CE0B6C.509@free-electrons.com>
Message-ID: <55CE0CFE.4040206@vollmann.ch>

On 08/14/15 17:38, Gregory CLEMENT wrote:
> Hi Detlef,
>
> On 14/08/2015 17:35, Detlef Vollmann wrote:
>> Hi Gregory,
>>
>> On 08/14/15 16:13, Gregory CLEMENT wrote:
>>> On 14/08/2015 16:05, Detlef Vollmann wrote:
>>>> Hello,
>>>>
>>>> this commit:
>>>>    > commit a71b092a9c68685a270ebdde7b5986ba8787e575
>>>>    > Author: Marc Zyngier <marc.zyngier at arm.com>
>>>>    > Date:   Tue Aug 26 11:03:18 2014 +0100
>>>>    >
>>>>    >     ARM: Convert handle_IRQ to use __handle_domain_irq
>>>> [...]
>>>> causes the kernel not to boot anymore on my DNS-323.
>>>> Soc: MV88F5182 Rev 2
>>>> CPU: ARM926 (Rev 0) running @ 500Mhz
>>>> CPU: Feroceon [41069260] revision 0 (ARMv5TEJ), cr=a005317f
>>>> Orion ID: MV88F5182-A2. TCLK=166666667.
>>>> DNS-323: Identified HW revision B1
>>>>
>>>> Boot stops after "Uncompressing Linux... done, booting the kernel."
>>>> Reverting the commit works fine for me.
>>>> Tested 4.1.2 and 4.2.0-rc6 with orion5x_defconfig.
>>>
>>> Could you try the following patch ?
>>>
>>> http://lists.infradead.org/pipermail/linux-arm-kernel/2015-July/356501.html
>> Thanks for the pointer.
>> Yes, this patch fixes it :-)
>>
>> I've also tested Arnd's patch at
>>
>> http://git.kernel.org/cgit/linux/kernel/git/arnd/playground.git/commit/?h=multiplatform-4.2-next&id=44b55cab3bd74739e4c39205d41e1b2ed8953155
>>
>> But at least in isolation this doesn't fix the problem.
>
> Thanks for doing these two tests,
Well, thanks for the pointer!

> so I will take Benjamin and also add your
> Tested-by if you agree.
Fine by me.

Thanks,
   Detlef



From gregory.clement at free-electrons.com  Fri Aug 14 08:46:55 2015
From: gregory.clement at free-electrons.com (Gregory CLEMENT)
Date: Fri, 14 Aug 2015 17:46:55 +0200
Subject: [PATCH] ARM: orion5x: fix legacy orion5x IRQ numbers
In-Reply-To: <4168769.RaQL1yKSFF@wuerfel>
References: <5583DD23.90505@arm.com> <1436710916.5657.169.camel@dolka.fr>
 <1436883958.13048.5.camel@dolka.fr> <4168769.RaQL1yKSFF@wuerfel>
Message-ID: <55CE0D6F.9040203@free-electrons.com>

Hi Arnd, Benjamin,

On 14/07/2015 22:50, Arnd Bergmann wrote:
> On Tuesday 14 July 2015 16:25:58 Benjamin Cama wrote:
>> Hi everyone,
>>
>> I finally nailed it: my attempt at copying Russell's patch for dove did
>> not work because MULTI_IRQ_HANDLER was not set. It is not in the
>> defconfig; maybe it should be now? I hesitated to put it as a
>> dependency for PLAT_ORION_LEGACY, but as the platform is globally
>> broken without it, I added it.
>>
>> What do you think?
>>
> 
> I think it makes sense the way you did here.
> 
> See also my patch at
> 
> http://git.kernel.org/cgit/linux/kernel/git/arnd/playground.git/commit/?h=multiplatform-4.2-next&id=44b55cab3bd74739e4c39205d41e1b2ed8953155
> 
> I'd be happy if we could just merge that one, along with the other
> plat-orion multiplatform patches at
> http://git.kernel.org/cgit/linux/kernel/git/arnd/playground.git/log/?h=b1f5b2f1a738d7f78b94856bfe7a1a7d4da1fbd1
> 
> I did not manage to get them merged before my parental leave and
> certainly won't be able to do it before I get back to work, but maybe
> someone else can have a look. I think the five patches should all
> be fine there, they mainly need testing on real hardware.

Benjamin's patch definitely needs to be applied, as another orion user got
an issue too:
http://lists.infradead.org/pipermail/linux-arm-kernel/2015-August/364503.html


The remaining question in this thread was about only taking Benjamin patch
or the full series from Arnd. But now it is too late to take the full series
and currently there is a bug in 4.2-rc. So first I will apply this patch with
the hope that it could be merged before the 4.2 release.

Later we definitely will need to take care of Arnd series.

Thanks,

Gregory

> 
> 	Arnd
> 


-- 
Gregory Clement, Free Electrons
Kernel, drivers, real-time and embedded Linux
development, consulting, training and support.
http://free-electrons.com


From lorenzo.pieralisi at arm.com  Fri Aug 14 08:49:47 2015
From: lorenzo.pieralisi at arm.com (Lorenzo Pieralisi)
Date: Fri, 14 Aug 2015 16:49:47 +0100
Subject: [PATCH 5/9] ARM: common: Introduce PM domains for CPUs/clusters
In-Reply-To: <7hegj6le8c.fsf@deeprootsystems.com>
References: <1438731339-58317-1-git-send-email-lina.iyer@linaro.org>
 <1438731339-58317-6-git-send-email-lina.iyer@linaro.org>
 <CAL_JsqK67=DTtjZwwnonObLDjLbahkREfm0RvyXVV95bhR-d4Q@mail.gmail.com>
 <20150813150154.GB13356@red-moon>
 <20150813154503.GO52339@linaro.org>
 <20150813155245.GD13833@red-moon>
 <7hegj6le8c.fsf@deeprootsystems.com>
Message-ID: <20150814154947.GC24806@red-moon>

On Fri, Aug 14, 2015 at 04:51:15AM +0100, Kevin Hilman wrote:
> Lorenzo Pieralisi <lorenzo.pieralisi at arm.com> writes:
> 
> > On Thu, Aug 13, 2015 at 04:45:03PM +0100, Lina Iyer wrote:
> >> On Thu, Aug 13 2015 at 09:01 -0600, Lorenzo Pieralisi wrote:
> >> >On Thu, Aug 06, 2015 at 04:14:51AM +0100, Rob Herring wrote:
> >> >> On Tue, Aug 4, 2015 at 6:35 PM, Lina Iyer <lina.iyer at linaro.org> wrote:
> >> >> > Define and add Generic PM domains (genpd) for ARM CPU clusters. Many new
> >> >> > SoCs group CPUs as clusters. Clusters share common resources like GIC,
> >> >> > power rail, caches, VFP, Coresight etc. When all CPUs in the cluster are
> >> >> > idle, these shared resources may also be put in their idle state.
> >> >> >
> >> >> > The idle time between the last CPU entering idle and a CPU resuming
> >> >> > execution is an opportunity for these shared resources to be powered
> >> >> > down. Generic PM domain provides a framework for defining such power
> >> >> > domains and attach devices to the domain. When the devices in the domain
> >> >> > are idle at runtime, the domain would also be suspended and resumed
> >> >> > before the first of the devices resume execution.
> >> >> >
> >> >> > We define a generic PM domain for each cluster and attach CPU devices in
> >> >> > the cluster to that PM domain. The DT definitions for the SoC describe
> >> >> > this relationship. Genpd callbacks for power_on and power_off can then
> >> >> > be used to power up/down the shared resources for the domain.
> >> >>
> >> >> [...]
> >> >>
> >> >> > +ARM CPU Power domains
> >> >> > +
> >> >> > +The device tree allows describing of CPU power domains in a SoC. In ARM SoC,
> >> >> > +CPUs may be grouped as clusters. A cluster may have CPUs, GIC, Coresight,
> >> >> > +caches, VFP and power controller and other peripheral hardware. Generally,
> >> >> > +when the CPUs in the cluster are idle/suspended, the shared resources may also
> >> >> > +be suspended and resumed before any of the CPUs resume execution.
> >> >> > +
> >> >> > +CPUs are the defined as the PM domain consumers and there is a PM domain
> >> >> > +provider for the CPUs. Bindings for generic PM domains (genpd) is described in
> >> >> > +[1].
> >> >> > +
> >> >> > +The ARM CPU PM domain follows the same binding convention as any generic PM
> >> >> > +domain. Additional binding properties are -
> >> >> > +
> >> >> > +- compatible:
> >> >> > +       Usage: required
> >> >> > +       Value type: <string>
> >> >> > +       Definition: Must also have
> >> >> > +                       "arm,pd"
> >> >> > +               inorder to initialize the genpd provider as ARM CPU PM domain.
> >> >>
> >> >> A compatible string should represent a particular h/w block. If it is
> >> >> generic, it should represent some sort of standard programming
> >> >> interface (e.g, AHCI, EHCI, etc.). This doesn't seem to be either and
> >> >> is rather just a mapping of what "driver" you want to use.
> >> >>
> >> >> I would expect that identifying a cpu's or cluster's power domain
> >> >> would be done by a phandle between the cpu/cluster node and power
> >> >> domain node. But I've not really looked at the power domain bindings
> >> >> so who knows.
> >> >
> >> >I would expect the same, meaning that a cpu node, like any other device
> >> >node would have a phandle pointing at the respective HW power domain.
> >> >
> >> CPUs have phandles to their domains. That is how the relationship
> >> between the domain provider (power-controller) and the consumer (CPU) is
> >> established.
> >> 
> >> >I do not really understand why we want a "generic" CPU power domain, what
> >> >purpose does it serve ? Creating a collection of cpu devices that we
> >> >can call "cluster" ?
> >> >
> >> Nope, not for calling a cluster, a cluster :)
> >> 
> >> This compatible is used to define a generic behavior of the CPU domain
> >> controller (in addition to the platform specific behavior of the domain
> >> power controller). The kernel activities for such power controller are
> >> generally the same which otherwise would be repeated across platforms.
> >
> > What activities ? CPU PM notifiers ?
> 
> For today, yes.
> 
> However, you can think of CPU PM notifiers as the equivalent of runtime
> PM hooks.  They're called when the "devices" are about to be powered off
> (runtime suspended) or powered on (runtime resumed.)
> 
> However the CPU PM framework and notifiers are rather dumb compared to
> runtime PM.  For example, runtime PM gives you usecounting, autosuspend,
> control from userspace, statistics, etc. etc.  Also, IMO, CPU PM will 
> not scale well for multiple clusters.
> 
> What if instead, we used runtime PM for the things that the CPU PM
> notifiers manager (GIC, VFP, Coresight, etc.), and those drivers used
> runtime PM callbacks to replace their CPU PM notifiers?  We'd then be in
> a beautiful land where CPU "devices" (and the other connected logic) can
> be modeled as devices using runtime PM just like every other device in
> the system.

I would agree with that (even though I do not see how we can make
eg GIC, VFP and arch timers behave like devices from a runtime PM
standpoint), still I do not see why we need a virtual power domain for
that, the CPU "devices" should be attached to the HW CPU power domain.

More below for systems relying on FW interfaces to handle CPU power
management.

> Then take it up a level... what if we then could use genpd to model the
> "cluster", made of of the CPUs and "connected" devices (GIC, VFP, etc.)
> but also modeled the shared L2$ as a device which was using runtime PM.

I have to understand what "modeled" means (do we create a struct device
on purpose for that ? Same goes for GIC and VFP).

But overall I get the gist of what you are saying, we just have to see
how this can be implemented within the genPD framework.

I suspect the "virtual" power domain you are introducing is there for
systems where the power controller is hidden from the kernel (ie PSCI),
where basically the CPU "devices" can't be attached to a power domain
simply because that power domain is not managed in the kernel but
by firmware.

> Now we're in a place where we can use all the benefits of runtime PM,
> plus the governor features of genpd to start doing a real, multi-CPU,
> multi-cluster CPUidle that's flexible enough to model the various
> dependencies in an SoC independent way, but generic enough to be able to
> use common governors for last-man standing, cache flushing, etc. etc.

I do not disagree (even though I think that last man standing is pushing
this concept a bit over the top), I am just concerned about the points
raised above, most of them should be reasonably simple to solve.

Thanks,
Lorenzo


From jeremy.linton at arm.com  Fri Aug 14 08:55:53 2015
From: jeremy.linton at arm.com (Jeremy Linton)
Date: Fri, 14 Aug 2015 10:55:53 -0500
Subject: [PATCH 1/2] Add a matching set of device_ functions for
 determining mac/phy
In-Reply-To: <55CBC524.4070101@gmail.com>
References: <1439417187-21411-1-git-send-email-jeremy.linton@arm.com>
 <1439417187-21411-2-git-send-email-jeremy.linton@arm.com>
 <55CBC524.4070101@gmail.com>
Message-ID: <55CE0F89.2040200@arm.com>

On 08/12/2015 05:13 PM, Florian Fainelli wrote:
> On 12/08/15 15:06, Jeremy Linton wrote:
>> +
>> +static void *device_get_mac_addr(struct device *dev,
>> +				 const char *name, char *addr,
>> +				 int alen)
>> +{
>> +	int ret = device_property_read_u8_array(dev, name, addr, alen);
>> +
>> +	if (ret == 0 && is_valid_ether_addr(addr))
>> +		return addr;
>> +	return NULL;
>
> The DT counterpart has an additional check on the properly length to be
> ETH_ALEN, you might want to have such check here for consistency and
> correctness.

I will add it back,

Thanks,





From marc.zyngier at arm.com  Fri Aug 14 08:59:11 2015
From: marc.zyngier at arm.com (Marc Zyngier)
Date: Fri, 14 Aug 2015 16:59:11 +0100
Subject: commit a71b092 "ARM: Convert handle_IRQ to use
 __handle_domain_irq" breaks DNS-323
In-Reply-To: <55CE0CA0.5010806@vollmann.ch>
References: <55CDF5C3.7080204@vollmann.ch>
 <55CDF78F.6070001@free-electrons.com> <55CE0636.3050205@arm.com>
 <55CE0CA0.5010806@vollmann.ch>
Message-ID: <55CE104F.1080901@arm.com>

On 14/08/15 16:43, Detlef Vollmann wrote:
> On 08/14/15 17:16, Marc Zyngier wrote:
>> On 14/08/15 15:13, Gregory CLEMENT wrote:
>>> Hi Detlef,
>>>
>>> On 14/08/2015 16:05, Detlef Vollmann wrote:
>>>> Hello,
>>>>
>>>> this commit:
>>>>   > commit a71b092a9c68685a270ebdde7b5986ba8787e575
>>>>   > Author: Marc Zyngier <marc.zyngier at arm.com>
>>>>   > Date:   Tue Aug 26 11:03:18 2014 +0100
>>>>   >
>>>>   >     ARM: Convert handle_IRQ to use __handle_domain_irq
>>>> [...]
>>>> causes the kernel not to boot anymore on my DNS-323.
>>>> Soc: MV88F5182 Rev 2
>>>> CPU: ARM926 (Rev 0) running @ 500Mhz
>>>> CPU: Feroceon [41069260] revision 0 (ARMv5TEJ), cr=a005317f
>>>> Orion ID: MV88F5182-A2. TCLK=166666667.
>>>> DNS-323: Identified HW revision B1
>>>>
>>>> Boot stops after "Uncompressing Linux... done, booting the kernel."
>>>> Reverting the commit works fine for me.
>>>> Tested 4.1.2 and 4.2.0-rc6 with orion5x_defconfig.
>>>
>>> Could you try the following patch ?
>>>
>>> http://lists.infradead.org/pipermail/linux-arm-kernel/2015-July/356501.html
>>
>> As a side note, having to revert that patch to get your system up and
>> running is a reliable indication that something is wrong with your
>> interrupt mapping, and that you are using 0 as a valid interrupt number
>> (which has been declared invalid a long time ago by the chief penguin).
> Well, in this case it wasn't me ;-)

Guilty by association! ;-)

> I wanted to avoid looking at the sources myself as the DNS-323 is still
> a widely used hardware.

You're missing out! Think of all these sleepless nights you could spend
staring at all kind of weird and fascinating code! :D

>> Hopefully Gregory has put you in the right direction.
> Yes.  Now I'll use that patch until some fix is accepted in mainline.

Hopefully soon.

Thanks,

	M.
-- 
Jazz is not dead. It just smells funny...


From robherring2 at gmail.com  Fri Aug 14 09:09:21 2015
From: robherring2 at gmail.com (Rob Herring)
Date: Fri, 14 Aug 2015 11:09:21 -0500
Subject: [GIT PULL] SA1100/PXA RTC for 4.3
Message-ID: <CAL_JsqKMN1SEQoJRSPixih4ckDh1pGb4x3T_t+2oWVvW8fqzmg@mail.gmail.com>

Alexandre,

Please pull SA1100/PXA changes for 4.3. This series has had several
rounds of review over several months without comment from PXA
maintainers other than Robert.

Rob

The following changes since commit 52721d9d3334c1cb1f76219a161084094ec634dc:

  Linux 4.2-rc3 (2015-07-19 14:45:02 -0700)

are available in the git repository at:

  git://git.kernel.org/pub/scm/linux/kernel/git/robh/linux.git
tags/pxa-rtc-for-4.3

for you to fetch changes up to e473ff0fe8548941ef67bf956a6b7943f4663ab1:

  ARM: config: Switch PXA27x platforms to use PXA RTC driver
(2015-08-14 10:53:44 -0500)

----------------------------------------------------------------
SA1100 and PXA RTC clean-ups

This series enables building the SA1100 RTC driver for ARM64 in
preparation for enabling CONFIG_ARCH_MMP on ARM64. This is needed for
supporting the PXA1928 SOC. Clean-up of SA1100 RTC is complicated by the
fact that some PXA chips use both sa1100-rtc and pxa-rtc drivers and
share the same registers. This does not work well with the Linux driver
model. So the first step is removing this sharing by the 2 drivers and
making sa1100-rtc and pxa-rtc mutually exclusive.

----------------------------------------------------------------
Rob Herring (7):
      rtc: sa1100: prepare to share sa1100_rtc_ops
      rtc: pxa: convert to use shared sa1100 functions
      ARM: pxa: add memory resource to SA1100 RTC device
      rtc: sa1100/pxa: convert to run-time register mapping
      ARM: sa1100: remove unused RTC register definitions
      ARM: mmp: remove unused RTC register definitions
      ARM: config: Switch PXA27x platforms to use PXA RTC driver

 arch/arm/configs/cm_x2xx_defconfig          |   2 +-
 arch/arm/configs/em_x270_defconfig          |   2 +-
 arch/arm/configs/magician_defconfig         |   2 +-
 arch/arm/configs/palmz72_defconfig          |   2 +-
 arch/arm/configs/pcm027_defconfig           |   2 +-
 arch/arm/configs/trizeps4_defconfig         |   2 +-
 arch/arm/mach-mmp/include/mach/regs-rtc.h   |  23 -----
 arch/arm/mach-pxa/devices.c                 |  18 +---
 arch/arm/mach-pxa/pxa27x.c                  |   1 -
 arch/arm/mach-pxa/pxa3xx.c                  |   1 -
 arch/arm/mach-sa1100/include/mach/SA-1100.h |  34 -------
 drivers/rtc/Kconfig                         |  12 ++-
 drivers/rtc/rtc-pxa.c                       |  55 +++++------
 drivers/rtc/rtc-sa1100.c                    | 139 +++++++++++++++++-----------
 drivers/rtc/rtc-sa1100.h                    |  23 +++++
 15 files changed, 150 insertions(+), 168 deletions(-)
 delete mode 100644 arch/arm/mach-mmp/include/mach/regs-rtc.h
 create mode 100644 drivers/rtc/rtc-sa1100.h


From gregory.clement at free-electrons.com  Fri Aug 14 09:12:54 2015
From: gregory.clement at free-electrons.com (Gregory CLEMENT)
Date: Fri, 14 Aug 2015 18:12:54 +0200
Subject: [PATCH v2 0/2] Fix dma mapping when the cache is coherent
Message-ID: <1439568776-17864-1-git-send-email-gregory.clement@free-electrons.com>

Hi,

These two patches fixes the dma mapping functions when the system is
cache coherent. The first one allows to fix an issue we have on Armada
375/38x with the PL310 that's why it is tagged for stable too.

The second one was suggested by Catalin. I put it in form and check
that it can be built, but I don't have the platform to test it, so it
definitely need someone to test it. I guess this one should also go to
the stable kernel but I don't know from which point.

Gregory

Gregory CLEMENT (2):
  ARM: dma-mapping: Don't use outer_flush_range when the L2C is coherent
  ARM: dma-mapping: Fix the coherent case when iommu is used

 arch/arm/mm/dma-mapping.c | 103 +++++++++++++++++++++++++++++++---------------
 1 file changed, 69 insertions(+), 34 deletions(-)

-- 
2.1.0



From gregory.clement at free-electrons.com  Fri Aug 14 09:12:55 2015
From: gregory.clement at free-electrons.com (Gregory CLEMENT)
Date: Fri, 14 Aug 2015 18:12:55 +0200
Subject: [PATCH v2 1/2] ARM: dma-mapping: Don't use outer_flush_range when the
 L2C is coherent
In-Reply-To: <1439568776-17864-1-git-send-email-gregory.clement@free-electrons.com>
References: <1439568776-17864-1-git-send-email-gregory.clement@free-electrons.com>
Message-ID: <1439568776-17864-2-git-send-email-gregory.clement@free-electrons.com>

When a L2 cache controller is used in a system that provides hardware
coherency, the entire outer cache operations are useless, and can be
skipped.  Moreover, on some systems, it is harmful as it causes
deadlocks between the Marvell coherency mechanism, the Marvell PCIe
controller and the Cortex-A9.

In the current kernel implementation, the outer cache flush range
operation is triggered by the dma_alloc function.
This operation can be take place during runtime and in some
circumstances may lead to the PCIe/PL310 deadlock on Armada 375/38x
SoCs.

This patch extends the __dma_clear_buffer() function to receive a
boolean argument related to the coherency of the system. The same
things is done for the calling functions.

Reported-by: Nadav Haklai <nadavh at marvell.com>
Signed-off-by: Gregory CLEMENT <gregory.clement at free-electrons.com>
Cc: <stable at vger.kernel.org> # v3.16+
---
 arch/arm/mm/dma-mapping.c | 55 +++++++++++++++++++++++++++++++----------------
 1 file changed, 36 insertions(+), 19 deletions(-)

diff --git a/arch/arm/mm/dma-mapping.c b/arch/arm/mm/dma-mapping.c
index 1ced8a0f7a52..96d1b0572602 100644
--- a/arch/arm/mm/dma-mapping.c
+++ b/arch/arm/mm/dma-mapping.c
@@ -224,7 +224,7 @@ static u64 get_coherent_dma_mask(struct device *dev)
 	return mask;
 }
 
-static void __dma_clear_buffer(struct page *page, size_t size)
+static void __dma_clear_buffer(struct page *page, size_t size, bool is_coherent)
 {
 	/*
 	 * Ensure that the allocated pages are zeroed, and that any data
@@ -236,17 +236,21 @@ static void __dma_clear_buffer(struct page *page, size_t size)
 		while (size > 0) {
 			void *ptr = kmap_atomic(page);
 			memset(ptr, 0, PAGE_SIZE);
-			dmac_flush_range(ptr, ptr + PAGE_SIZE);
+			if (!is_coherent)
+				dmac_flush_range(ptr, ptr + PAGE_SIZE);
 			kunmap_atomic(ptr);
 			page++;
 			size -= PAGE_SIZE;
 		}
-		outer_flush_range(base, end);
+		if (!is_coherent)
+			outer_flush_range(base, end);
 	} else {
 		void *ptr = page_address(page);
 		memset(ptr, 0, size);
-		dmac_flush_range(ptr, ptr + size);
-		outer_flush_range(__pa(ptr), __pa(ptr) + size);
+		if (!is_coherent) {
+			dmac_flush_range(ptr, ptr + size);
+			outer_flush_range(__pa(ptr), __pa(ptr) + size);
+		}
 	}
 }
 
@@ -254,7 +258,8 @@ static void __dma_clear_buffer(struct page *page, size_t size)
  * Allocate a DMA buffer for 'dev' of size 'size' using the
  * specified gfp mask.  Note that 'size' must be page aligned.
  */
-static struct page *__dma_alloc_buffer(struct device *dev, size_t size, gfp_t gfp)
+static struct page *__dma_alloc_buffer(struct device *dev, size_t size,
+				gfp_t gfp, bool is_coherent)
 {
 	unsigned long order = get_order(size);
 	struct page *page, *p, *e;
@@ -270,7 +275,7 @@ static struct page *__dma_alloc_buffer(struct device *dev, size_t size, gfp_t gf
 	for (p = page + (size >> PAGE_SHIFT), e = page + (1 << order); p < e; p++)
 		__free_page(p);
 
-	__dma_clear_buffer(page, size);
+	__dma_clear_buffer(page, size, is_coherent);
 
 	return page;
 }
@@ -292,7 +297,8 @@ static void __dma_free_buffer(struct page *page, size_t size)
 
 static void *__alloc_from_contiguous(struct device *dev, size_t size,
 				     pgprot_t prot, struct page **ret_page,
-				     const void *caller, bool want_vaddr);
+				     const void *caller, bool want_vaddr,
+				     bool is_coherent);
 
 static void *__alloc_remap_buffer(struct device *dev, size_t size, gfp_t gfp,
 				 pgprot_t prot, struct page **ret_page,
@@ -358,9 +364,14 @@ static int __init atomic_pool_init(void)
 	if (!atomic_pool)
 		goto out;
 
+	/*
+	 * Here we don't know if the system is coherent, but it is
+	 * harmless to use the non-coherent case in the
+	 * __alloc_from_contiguous() call.
+	 */
 	if (dev_get_cma_area(NULL))
 		ptr = __alloc_from_contiguous(NULL, atomic_pool_size, prot,
-					      &page, atomic_pool_init, true);
+					&page, atomic_pool_init, true, false);
 	else
 		ptr = __alloc_remap_buffer(NULL, atomic_pool_size, gfp, prot,
 					   &page, atomic_pool_init, true);
@@ -474,7 +485,8 @@ static void *__alloc_remap_buffer(struct device *dev, size_t size, gfp_t gfp,
 {
 	struct page *page;
 	void *ptr = NULL;
-	page = __dma_alloc_buffer(dev, size, gfp);
+	/* This function is only called when the arch is non-coherent */
+	page = __dma_alloc_buffer(dev, size, gfp, false);
 	if (!page)
 		return NULL;
 	if (!want_vaddr)
@@ -529,7 +541,8 @@ static int __free_from_pool(void *start, size_t size)
 
 static void *__alloc_from_contiguous(struct device *dev, size_t size,
 				     pgprot_t prot, struct page **ret_page,
-				     const void *caller, bool want_vaddr)
+				     const void *caller, bool want_vaddr,
+				     bool is_coherent)
 {
 	unsigned long order = get_order(size);
 	size_t count = size >> PAGE_SHIFT;
@@ -540,7 +553,7 @@ static void *__alloc_from_contiguous(struct device *dev, size_t size,
 	if (!page)
 		return NULL;
 
-	__dma_clear_buffer(page, size);
+	__dma_clear_buffer(page, size, is_coherent);
 
 	if (!want_vaddr)
 		goto out;
@@ -590,7 +603,7 @@ static inline pgprot_t __get_dma_pgprot(struct dma_attrs *attrs, pgprot_t prot)
 #define __get_dma_pgprot(attrs, prot)				__pgprot(0)
 #define __alloc_remap_buffer(dev, size, gfp, prot, ret, c, wv)	NULL
 #define __alloc_from_pool(size, ret_page)			NULL
-#define __alloc_from_contiguous(dev, size, prot, ret, c, wv)	NULL
+#define __alloc_from_contiguous(dev, size, prot, ret, c, wv, is_coherent)   NULL
 #define __free_from_pool(cpu_addr, size)			0
 #define __free_from_contiguous(dev, page, cpu_addr, size, wv)	do { } while (0)
 #define __dma_free_remap(cpu_addr, size)			do { } while (0)
@@ -601,7 +614,8 @@ static void *__alloc_simple_buffer(struct device *dev, size_t size, gfp_t gfp,
 				   struct page **ret_page)
 {
 	struct page *page;
-	page = __dma_alloc_buffer(dev, size, gfp);
+	/* This function is only called when the arch is coherent */
+	page = __dma_alloc_buffer(dev, size, gfp, true);
 	if (!page)
 		return NULL;
 
@@ -655,7 +669,8 @@ static void *__dma_alloc(struct device *dev, size_t size, dma_addr_t *handle,
 	else if (!dev_get_cma_area(dev))
 		addr = __alloc_remap_buffer(dev, size, gfp, prot, &page, caller, want_vaddr);
 	else
-		addr = __alloc_from_contiguous(dev, size, prot, &page, caller, want_vaddr);
+		addr = __alloc_from_contiguous(dev, size, prot, &page, caller,
+					want_vaddr, is_coherent);
 
 	if (page)
 		*handle = pfn_to_dma(dev, page_to_pfn(page));
@@ -1131,7 +1146,8 @@ static inline void __free_iova(struct dma_iommu_mapping *mapping,
 }
 
 static struct page **__iommu_alloc_buffer(struct device *dev, size_t size,
-					  gfp_t gfp, struct dma_attrs *attrs)
+					gfp_t gfp, struct dma_attrs *attrs,
+					bool is_coherent)
 {
 	struct page **pages;
 	int count = size >> PAGE_SHIFT;
@@ -1154,7 +1170,7 @@ static struct page **__iommu_alloc_buffer(struct device *dev, size_t size,
 		if (!page)
 			goto error;
 
-		__dma_clear_buffer(page, size);
+		__dma_clear_buffer(page, size, is_coherent);
 
 		for (i = 0; i < count; i++)
 			pages[i] = page + i;
@@ -1198,7 +1214,7 @@ static struct page **__iommu_alloc_buffer(struct device *dev, size_t size,
 				pages[i + j] = pages[i] + j;
 		}
 
-		__dma_clear_buffer(pages[i], PAGE_SIZE << order);
+		__dma_clear_buffer(pages[i], PAGE_SIZE << order, is_coherent);
 		i += 1 << order;
 		count -= 1 << order;
 	}
@@ -1381,7 +1397,8 @@ static void *arm_iommu_alloc_attrs(struct device *dev, size_t size,
 	 */
 	gfp &= ~(__GFP_COMP);
 
-	pages = __iommu_alloc_buffer(dev, size, gfp, attrs);
+	/* For now always consider we are in a non-coherent case */
+	pages = __iommu_alloc_buffer(dev, size, gfp, attrs, false);
 	if (!pages)
 		return NULL;
 
-- 
2.1.0



From gregory.clement at free-electrons.com  Fri Aug 14 09:12:56 2015
From: gregory.clement at free-electrons.com (Gregory CLEMENT)
Date: Fri, 14 Aug 2015 18:12:56 +0200
Subject: [PATCH v2 2/2] ARM: dma-mapping: Fix the coherent case when iommu is
 used
In-Reply-To: <1439568776-17864-1-git-send-email-gregory.clement@free-electrons.com>
References: <1439568776-17864-1-git-send-email-gregory.clement@free-electrons.com>
Message-ID: <1439568776-17864-3-git-send-email-gregory.clement@free-electrons.com>

When doing dma allocation with IOMMU the __iommu_alloc_atomic() was
used even when the system was coherent. However, this function
allocates from a non-cacheable pool, which is fine when the device is
not cache coherent but won't work as expected in the device is cache
coherent. Indeed, the CPU and device must access the memory using the
same cacheability attributes.

Tested-by: We need someone here

Suggested-by: Catalin Marinas <catalin.marinas at arm.com>
Signed-off-by: Gregory CLEMENT <gregory.clement at free-electrons.com>
---
 arch/arm/mm/dma-mapping.c | 52 +++++++++++++++++++++++++++++++----------------
 1 file changed, 35 insertions(+), 17 deletions(-)

diff --git a/arch/arm/mm/dma-mapping.c b/arch/arm/mm/dma-mapping.c
index 96d1b0572602..9dcb290e9c8c 100644
--- a/arch/arm/mm/dma-mapping.c
+++ b/arch/arm/mm/dma-mapping.c
@@ -1347,13 +1347,16 @@ static struct page **__iommu_get_pages(void *cpu_addr, struct dma_attrs *attrs)
 	return NULL;
 }
 
-static void *__iommu_alloc_atomic(struct device *dev, size_t size,
-				  dma_addr_t *handle)
+static void *__iommu_alloc_simple(struct device *dev, size_t size, gfp_t gfp,
+				  dma_addr_t *handle, bool is_coherent)
 {
 	struct page *page;
 	void *addr;
 
-	addr = __alloc_from_pool(size, &page);
+	if (is_coherent)
+		addr = __alloc_simple_buffer(dev, size, gfp, &page);
+	else
+		addr = __alloc_from_pool(size, &page);
 	if (!addr)
 		return NULL;
 
@@ -1368,15 +1371,19 @@ err_mapping:
 	return NULL;
 }
 
-static void __iommu_free_atomic(struct device *dev, void *cpu_addr,
-				dma_addr_t handle, size_t size)
+static void __iommu_free_simple(struct device *dev, void *cpu_addr,
+	    dma_addr_t handle, size_t size, bool is_coherent)
 {
 	__iommu_remove_mapping(dev, handle, size);
-	__free_from_pool(cpu_addr, size);
+	if (is_coherent)
+		__dma_free_buffer(virt_to_page(cpu_addr), size);
+	else
+		__free_from_pool(cpu_addr, size);
 }
 
-static void *arm_iommu_alloc_attrs(struct device *dev, size_t size,
-	    dma_addr_t *handle, gfp_t gfp, struct dma_attrs *attrs)
+static void *__arm_iommu_alloc_attrs(struct device *dev, size_t size,
+	    dma_addr_t *handle, gfp_t gfp, struct dma_attrs *attrs,
+	    bool is_coherent)
 {
 	pgprot_t prot = __get_dma_pgprot(attrs, PAGE_KERNEL);
 	struct page **pages;
@@ -1385,8 +1392,8 @@ static void *arm_iommu_alloc_attrs(struct device *dev, size_t size,
 	*handle = DMA_ERROR_CODE;
 	size = PAGE_ALIGN(size);
 
-	if (!(gfp & __GFP_WAIT))
-		return __iommu_alloc_atomic(dev, size, handle);
+	if (is_coherent || !(gfp & __GFP_WAIT))
+		return __iommu_alloc_simple(dev, size, gfp, handle, is_coherent);
 
 	/*
 	 * Following is a work-around (a.k.a. hack) to prevent pages
@@ -1397,8 +1404,7 @@ static void *arm_iommu_alloc_attrs(struct device *dev, size_t size,
 	 */
 	gfp &= ~(__GFP_COMP);
 
-	/* For now always consider we are in a non-coherent case */
-	pages = __iommu_alloc_buffer(dev, size, gfp, attrs, false);
+	pages = __iommu_alloc_buffer(dev, size, gfp, attrs, is_coherent);
 	if (!pages)
 		return NULL;
 
@@ -1423,6 +1429,18 @@ err_buffer:
 	return NULL;
 }
 
+static void *arm_iommu_alloc_attrs(struct device *dev, size_t size,
+	    dma_addr_t *handle, gfp_t gfp, struct dma_attrs *attrs)
+{
+	__arm_iommu_alloc_attrs(dev, size, handle, gfp, attrs, false);
+}
+
+static void *arm_coherent_iommu_alloc_attrs(struct device *dev, size_t size,
+	    dma_addr_t *handle, gfp_t gfp, struct dma_attrs *attrs)
+{
+	__arm_iommu_alloc_attrs(dev, size, handle, gfp, attrs, true);
+}
+
 static int arm_iommu_mmap_attrs(struct device *dev, struct vm_area_struct *vma,
 		    void *cpu_addr, dma_addr_t dma_addr, size_t size,
 		    struct dma_attrs *attrs)
@@ -1453,14 +1471,14 @@ static int arm_iommu_mmap_attrs(struct device *dev, struct vm_area_struct *vma,
  * free a page as defined by the above mapping.
  * Must not be called with IRQs disabled.
  */
-void arm_iommu_free_attrs(struct device *dev, size_t size, void *cpu_addr,
-			  dma_addr_t handle, struct dma_attrs *attrs)
+void __arm_iommu_free_attrs(struct device *dev, size_t size, void *cpu_addr,
+	dma_addr_t handle, struct dma_attrs *attrs, bool is_coherent)
 {
 	struct page **pages;
 	size = PAGE_ALIGN(size);
 
-	if (__in_atomic_pool(cpu_addr, size)) {
-		__iommu_free_atomic(dev, cpu_addr, handle, size);
+	if (is_coherent || __in_atomic_pool(cpu_addr, size)) {
+		__iommu_free_simple(dev, cpu_addr, handle, size, is_coherent);
 		return;
 	}
 
@@ -1885,7 +1903,7 @@ struct dma_map_ops iommu_ops = {
 };
 
 struct dma_map_ops iommu_coherent_ops = {
-	.alloc		= arm_iommu_alloc_attrs,
+	.alloc		= arm_coherent_iommu_alloc_attrs,
 	.free		= arm_iommu_free_attrs,
 	.mmap		= arm_iommu_mmap_attrs,
 	.get_sgtable	= arm_iommu_get_sgtable,
-- 
2.1.0



From marc.zyngier at arm.com  Fri Aug 14 09:19:15 2015
From: marc.zyngier at arm.com (Marc Zyngier)
Date: Fri, 14 Aug 2015 17:19:15 +0100
Subject: [PATCH v2 0/4] PCI: arm64/powerpc: Fix parsing of linux,
 pci-probe-only
Message-ID: <1439569159-10051-1-git-send-email-marc.zyngier@arm.com>

The pci-host-generic driver parses the linux,pci-probe-only property,
and assumes that it will have a boolean parameter.

Turns out that the Seattle DTS file has a naked "linux,pci-probe-only"
property, which leads to the driver dereferencing some unsuspecting
memory location. Nothing really bad happens (we end up reading some
other bit of DT, fortunately), but that not a reason to keep it this
way. Turns out that the Pseries code (where this code was lifted from)
may suffer from the same issue.

The first patch introduces a common (and fixed) version of that check
that can be used by drivers and architectures that require it. The two
following patches change the pci-host-generic driver and the powerpc
code to use it.

Finally, the bad property is removed from the Seatle DTS, because it
is simply not necessary (it actually prevents me from using SR-IOV,
which otherwise runs fine without the probe-only thing).

This has been tested on the offending Seattle board.

* From v1:
  - Consolidate the parsing in of_pci.c (Bjorn)

Marc Zyngier (4):
  of/pci: Add of_pci_check_probe_only to parse "linux,pci-probe-only"
  PCI: pci-host-generic: Fix lookup of linux,pci-probe-only property
  powerpc: PCI: Fix lookup of linux,pci-probe-only property
  arm64: dts: Drop linux,pci-probe-only from the Seattle DTS

 arch/arm64/boot/dts/amd/amd-overdrive.dts |  1 -
 arch/powerpc/platforms/pseries/setup.c    | 14 ++------------
 drivers/of/of_pci.c                       | 30 ++++++++++++++++++++++++++++++
 drivers/pci/host/pci-host-generic.c       |  9 +--------
 include/linux/of_pci.h                    |  3 +++
 5 files changed, 36 insertions(+), 21 deletions(-)

-- 
2.1.4



From marc.zyngier at arm.com  Fri Aug 14 09:19:16 2015
From: marc.zyngier at arm.com (Marc Zyngier)
Date: Fri, 14 Aug 2015 17:19:16 +0100
Subject: [PATCH v2 1/4] of/pci: Add of_pci_check_probe_only to parse "linux,
 pci-probe-only"
In-Reply-To: <1439569159-10051-1-git-send-email-marc.zyngier@arm.com>
References: <1439569159-10051-1-git-send-email-marc.zyngier@arm.com>
Message-ID: <1439569159-10051-2-git-send-email-marc.zyngier@arm.com>

Both pci-host-generic and Pseries parse the "linux,pci-probe-only"
to engage the PCI_PROBE_ONLY mode, and both have a subtle bug that
can be triggered if the property has no parameter.

Provide a generic implementation that can be used by both.

Signed-off-by: Marc Zyngier <marc.zyngier at arm.com>
---
 drivers/of/of_pci.c    | 30 ++++++++++++++++++++++++++++++
 include/linux/of_pci.h |  3 +++
 2 files changed, 33 insertions(+)

diff --git a/drivers/of/of_pci.c b/drivers/of/of_pci.c
index 5751dc5..a4e29ff 100644
--- a/drivers/of/of_pci.c
+++ b/drivers/of/of_pci.c
@@ -118,6 +118,36 @@ int of_get_pci_domain_nr(struct device_node *node)
 EXPORT_SYMBOL_GPL(of_get_pci_domain_nr);
 
 /**
+ * of_pci_check_probe_only - Setup probe only mode if linux,pci-probe-only
+ *                           is present and valid
+ *
+ * @node: device tree node that may contain the property (usually "chosen")
+ *
+ */
+void of_pci_check_probe_only(struct device_node *node)
+{
+	const int *prop;
+	int len;
+
+	if (!node)
+		return;
+
+	prop = of_get_property(node, "linux,pci-probe-only", &len);
+	if (prop) {
+		if (!len) {
+			pr_warn("linux,pci-probe-only set without value, ignoring\n");
+			return;
+		}
+
+		if (be32_to_cpup(prop))
+			pci_add_flags(PCI_PROBE_ONLY);
+		else
+			pci_clear_flags(PCI_PROBE_ONLY);
+	}
+}
+EXPORT_SYMBOL_GPL(of_pci_check_probe_only);
+
+/**
  * of_pci_dma_configure - Setup DMA configuration
  * @dev: ptr to pci_dev struct of the PCI device
  *
diff --git a/include/linux/of_pci.h b/include/linux/of_pci.h
index 29fd3fe..4c0a617 100644
--- a/include/linux/of_pci.h
+++ b/include/linux/of_pci.h
@@ -17,6 +17,7 @@ int of_irq_parse_and_map_pci(const struct pci_dev *dev, u8 slot, u8 pin);
 int of_pci_parse_bus_range(struct device_node *node, struct resource *res);
 int of_get_pci_domain_nr(struct device_node *node);
 void of_pci_dma_configure(struct pci_dev *pci_dev);
+void of_pci_check_probe_only(struct device_node *node);
 #else
 static inline int of_irq_parse_pci(const struct pci_dev *pdev, struct of_phandle_args *out_irq)
 {
@@ -53,6 +54,8 @@ of_get_pci_domain_nr(struct device_node *node)
 }
 
 static inline void of_pci_dma_configure(struct pci_dev *pci_dev) { }
+
+static inline void of_pci_check_probe_only(struct device_node *node) { }
 #endif
 
 #if defined(CONFIG_OF_ADDRESS)
-- 
2.1.4



From marc.zyngier at arm.com  Fri Aug 14 09:19:17 2015
From: marc.zyngier at arm.com (Marc Zyngier)
Date: Fri, 14 Aug 2015 17:19:17 +0100
Subject: [PATCH v2 2/4] PCI: pci-host-generic: Fix lookup of linux,
 pci-probe-only property
In-Reply-To: <1439569159-10051-1-git-send-email-marc.zyngier@arm.com>
References: <1439569159-10051-1-git-send-email-marc.zyngier@arm.com>
Message-ID: <1439569159-10051-3-git-send-email-marc.zyngier@arm.com>

When pci-host-generic looks for the probe-only property, it seems
to trust the DT to be correctly written, and assumes that there
is a parameter to the property.

Unfortunately, this is not always the case, and some firmware expose
this property naked. The driver ends up making a decision based on
whatever the property pointer points to, which is likely to be junk.

Switch to the common of_pci.c implementation that doesn't suffer
from this problem.

Signed-off-by: Marc Zyngier <marc.zyngier at arm.com>
---
 drivers/pci/host/pci-host-generic.c | 9 +--------
 1 file changed, 1 insertion(+), 8 deletions(-)

diff --git a/drivers/pci/host/pci-host-generic.c b/drivers/pci/host/pci-host-generic.c
index 265dd25..545ff4e 100644
--- a/drivers/pci/host/pci-host-generic.c
+++ b/drivers/pci/host/pci-host-generic.c
@@ -210,7 +210,6 @@ static int gen_pci_probe(struct platform_device *pdev)
 	int err;
 	const char *type;
 	const struct of_device_id *of_id;
-	const int *prop;
 	struct device *dev = &pdev->dev;
 	struct device_node *np = dev->of_node;
 	struct gen_pci *pci = devm_kzalloc(dev, sizeof(*pci), GFP_KERNEL);
@@ -225,13 +224,7 @@ static int gen_pci_probe(struct platform_device *pdev)
 		return -EINVAL;
 	}
 
-	prop = of_get_property(of_chosen, "linux,pci-probe-only", NULL);
-	if (prop) {
-		if (*prop)
-			pci_add_flags(PCI_PROBE_ONLY);
-		else
-			pci_clear_flags(PCI_PROBE_ONLY);
-	}
+	of_pci_check_probe_only(of_chosen);
 
 	of_id = of_match_node(gen_pci_of_match, np);
 	pci->cfg.ops = of_id->data;
-- 
2.1.4



From marc.zyngier at arm.com  Fri Aug 14 09:19:18 2015
From: marc.zyngier at arm.com (Marc Zyngier)
Date: Fri, 14 Aug 2015 17:19:18 +0100
Subject: [PATCH v2 3/4] powerpc: PCI: Fix lookup of linux,
 pci-probe-only property
In-Reply-To: <1439569159-10051-1-git-send-email-marc.zyngier@arm.com>
References: <1439569159-10051-1-git-send-email-marc.zyngier@arm.com>
Message-ID: <1439569159-10051-4-git-send-email-marc.zyngier@arm.com>

When find_and_init_phbs() looks for the probe-only property, it seems
to trust the firmware to be correctly written, and assumes that there
is a parameter to the property.

It is conceivable that the firmware could not be that perfect, and it
could expose this property naked (at least one arm64 platform seems to
exhibit this exact behaviour). The setup code the ends up making
a decision based on whatever the property pointer points to, which
is likely to be junk.

Instead, switch to the common of_pci.c implementation that doesn't
suffer from this problem and ignore the property if the firmware
couldn't make up its mind.

Signed-off-by: Marc Zyngier <marc.zyngier at arm.com>
---
 arch/powerpc/platforms/pseries/setup.c | 14 ++------------
 1 file changed, 2 insertions(+), 12 deletions(-)

diff --git a/arch/powerpc/platforms/pseries/setup.c b/arch/powerpc/platforms/pseries/setup.c
index df6a704..8434953 100644
--- a/arch/powerpc/platforms/pseries/setup.c
+++ b/arch/powerpc/platforms/pseries/setup.c
@@ -40,6 +40,7 @@
 #include <linux/seq_file.h>
 #include <linux/root_dev.h>
 #include <linux/of.h>
+#include <linux/of_pci.h>
 #include <linux/kexec.h>
 
 #include <asm/mmu.h>
@@ -488,18 +489,7 @@ static void __init find_and_init_phbs(void)
 	 * PCI_PROBE_ONLY and PCI_REASSIGN_ALL_BUS can be set via properties
 	 * in chosen.
 	 */
-	if (of_chosen) {
-		const int *prop;
-
-		prop = of_get_property(of_chosen,
-				"linux,pci-probe-only", NULL);
-		if (prop) {
-			if (*prop)
-				pci_add_flags(PCI_PROBE_ONLY);
-			else
-				pci_clear_flags(PCI_PROBE_ONLY);
-		}
-	}
+	of_pci_check_probe_only(of_chosen);
 }
 
 static void __init pSeries_setup_arch(void)
-- 
2.1.4



From marc.zyngier at arm.com  Fri Aug 14 09:19:19 2015
From: marc.zyngier at arm.com (Marc Zyngier)
Date: Fri, 14 Aug 2015 17:19:19 +0100
Subject: [PATCH v2 4/4] arm64: dts: Drop linux,
 pci-probe-only from the Seattle DTS
In-Reply-To: <1439569159-10051-1-git-send-email-marc.zyngier@arm.com>
References: <1439569159-10051-1-git-send-email-marc.zyngier@arm.com>
Message-ID: <1439569159-10051-5-git-send-email-marc.zyngier@arm.com>

The linux,pci-probe-only property mandates an argument to indicate
whether or not to engage the "probe-only" mode, but the Seattle
DTS just provides a naked property, which is illegal.

Also, it turns out that the board is perfectly happy without
probe-only, so let's drop this altogether.

Signed-off-by: Marc Zyngier <marc.zyngier at arm.com>
---
 arch/arm64/boot/dts/amd/amd-overdrive.dts | 1 -
 1 file changed, 1 deletion(-)

diff --git a/arch/arm64/boot/dts/amd/amd-overdrive.dts b/arch/arm64/boot/dts/amd/amd-overdrive.dts
index 564a3f7..128fa94 100644
--- a/arch/arm64/boot/dts/amd/amd-overdrive.dts
+++ b/arch/arm64/boot/dts/amd/amd-overdrive.dts
@@ -14,7 +14,6 @@
 
 	chosen {
 		stdout-path = &serial0;
-		linux,pci-probe-only;
 	};
 };
 
-- 
2.1.4



From gkulkarni at caviumnetworks.com  Fri Aug 14 09:39:30 2015
From: gkulkarni at caviumnetworks.com (Ganapatrao Kulkarni)
Date: Fri, 14 Aug 2015 22:09:30 +0530
Subject: [PATCH v5 0/8] arm64, numa: Add numa support for arm64 platforms.
Message-ID: <1439570374-4079-1-git-send-email-gkulkarni@caviumnetworks.com>

v5:
	- created base verion of numa.c which creates dummy numa without using dt
	  on single socket platforms. Then added patches for dt support.
	- Incorporated review comments from Hanjun Guo.

v4:
done changes as per Arnd review comments.

v3:
Added changes to support numa on arm64 based platforms.
Tested these patches on cavium's multinode(2 node topology) platform.
In this patchset, defined and implemented dt bindings for numa mapping
for core and memory using device node property arm,associativity.

v2:
Defined and implemented numa map for memory, cores to node and
proximity distance matrix of nodes.

v1:
Initial patchset to support numa on arm64 platforms.

Note:
	1. This patchset is tested for numa with dt on
	   thunderx single socket and dual socket boards.
	2. Numa DT booting needs the dt memory nodes, which are deleted in current efi-stub,
	hence to try numa with dt, you need to rebase with ard's patchset.
	http://git.linaro.org/people/ard.biesheuvel/linux-arm.git/shortlog/refs/heads/arm64-uefi-early-fdt-handling


Ganapatrao Kulkarni (4):
  arm64, numa: adding numa support for arm64 platforms.
  Documentation: arm64/arm: dt bindings for numa.
  arm64, numa: adding numa support for arm64 platforms.
  arm64, dt, thunderx: Add initial dts for Cavium Thunder SoC in 2 Node
    topology.

 Documentation/devicetree/bindings/arm/numa.txt  | 212 +++++++
 arch/arm64/Kconfig                              |  32 +
 arch/arm64/boot/dts/cavium/Makefile             |   2 +-
 arch/arm64/boot/dts/cavium/thunder-88xx-2n.dts  |  78 +++
 arch/arm64/boot/dts/cavium/thunder-88xx-2n.dtsi | 790 ++++++++++++++++++++++++
 arch/arm64/include/asm/mmzone.h                 |  32 +
 arch/arm64/include/asm/numa.h                   |  49 ++
 arch/arm64/kernel/Makefile                      |   1 +
 arch/arm64/kernel/dt_numa.c                     | 316 ++++++++++
 arch/arm64/kernel/setup.c                       |   9 +
 arch/arm64/kernel/smp.c                         |   3 +
 arch/arm64/mm/Makefile                          |   1 +
 arch/arm64/mm/init.c                            |  34 +-
 arch/arm64/mm/numa.c                            | 563 +++++++++++++++++
 14 files changed, 2115 insertions(+), 7 deletions(-)
 create mode 100644 Documentation/devicetree/bindings/arm/numa.txt
 create mode 100644 arch/arm64/boot/dts/cavium/thunder-88xx-2n.dts
 create mode 100644 arch/arm64/boot/dts/cavium/thunder-88xx-2n.dtsi
 create mode 100644 arch/arm64/include/asm/mmzone.h
 create mode 100644 arch/arm64/include/asm/numa.h
 create mode 100644 arch/arm64/kernel/dt_numa.c
 create mode 100644 arch/arm64/mm/numa.c

-- 
1.8.1.4



From gkulkarni at caviumnetworks.com  Fri Aug 14 09:39:34 2015
From: gkulkarni at caviumnetworks.com (Ganapatrao Kulkarni)
Date: Fri, 14 Aug 2015 22:09:34 +0530
Subject: [PATCH v5 4/4] arm64, dt,
 thunderx: Add initial dts for Cavium Thunder SoC in 2 Node topology.
In-Reply-To: <1439570374-4079-1-git-send-email-gkulkarni@caviumnetworks.com>
References: <1439570374-4079-1-git-send-email-gkulkarni@caviumnetworks.com>
Message-ID: <1439570374-4079-5-git-send-email-gkulkarni@caviumnetworks.com>

adding dt file for Cavium's Thunder SoC in 2 Node topology
using arm,associativity device node property.

Signed-off-by: Ganapatrao Kulkarni <gkulkarni at caviumnetworks.com>
---
 arch/arm64/boot/dts/cavium/Makefile             |   2 +-
 arch/arm64/boot/dts/cavium/thunder-88xx-2n.dts  |  78 +++
 arch/arm64/boot/dts/cavium/thunder-88xx-2n.dtsi | 790 ++++++++++++++++++++++++
 3 files changed, 869 insertions(+), 1 deletion(-)
 create mode 100644 arch/arm64/boot/dts/cavium/thunder-88xx-2n.dts
 create mode 100644 arch/arm64/boot/dts/cavium/thunder-88xx-2n.dtsi

diff --git a/arch/arm64/boot/dts/cavium/Makefile b/arch/arm64/boot/dts/cavium/Makefile
index e34f89d..7fe7067 100644
--- a/arch/arm64/boot/dts/cavium/Makefile
+++ b/arch/arm64/boot/dts/cavium/Makefile
@@ -1,4 +1,4 @@
-dtb-$(CONFIG_ARCH_THUNDER) += thunder-88xx.dtb
+dtb-$(CONFIG_ARCH_THUNDER) += thunder-88xx.dtb thunder-88xx-2n.dtb
 
 always		:= $(dtb-y)
 subdir-y	:= $(dts-dirs)
diff --git a/arch/arm64/boot/dts/cavium/thunder-88xx-2n.dts b/arch/arm64/boot/dts/cavium/thunder-88xx-2n.dts
new file mode 100644
index 0000000..adbd3a9
--- /dev/null
+++ b/arch/arm64/boot/dts/cavium/thunder-88xx-2n.dts
@@ -0,0 +1,78 @@
+/*
+ * Cavium Thunder DTS file - Thunder board description
+ *
+ * Copyright (C) 2014, Cavium Inc.
+ *
+ * This file is dual-licensed: you can use it either under the terms
+ * of the GPL or the X11 license, at your option. Note that this dual
+ * licensing only applies to this file, and not this project as a
+ * whole.
+ *
+ *  a) This library 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 library 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.
+ *
+ *     You should have received a copy of the GNU General Public
+ *     License along with this library; if not, write to the Free
+ *     Software Foundation, Inc., 51 Franklin St, Fifth Floor, Boston,
+ *     MA 02110-1301 USA
+ *
+ * Or, alternatively,
+ *
+ *  b) Permission is hereby granted, free of charge, to any person
+ *     obtaining a copy of this software and associated documentation
+ *     files (the "Software"), to deal in the Software without
+ *     restriction, including without limitation the rights to use,
+ *     copy, modify, merge, publish, distribute, sublicense, and/or
+ *     sell copies of the Software, and to permit persons to whom the
+ *     Software is furnished to do so, subject to the following
+ *     conditions:
+ *
+ *     The above copyright notice and this permission notice shall be
+ *     included in all copies or substantial portions of the Software.
+ *
+ *     THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
+ *     EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES
+ *     OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
+ *     NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT
+ *     HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY,
+ *     WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
+ *     FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR
+ *     OTHER DEALINGS IN THE SOFTWARE.
+ */
+
+/dts-v1/;
+
+/include/ "thunder-88xx-2n.dtsi"
+
+/ {
+	model = "Cavium ThunderX CN88XX board";
+	compatible = "cavium,thunder-88xx";
+	arm,associativity-reference-points = <0>;
+
+	aliases {
+		serial0 = &uaa0;
+		serial1 = &uaa1;
+	};
+
+	memory at 00000000 {
+		device_type = "memory";
+		reg = <0x0 0x00000000 0x0 0x80000000>;
+		/* socket 0, no specific cluster, core */
+		arm,associativity = <0 0xffff 0xffff>;
+	};
+
+	memory at 10000000000 {
+		device_type = "memory";
+		reg = <0x100 0x00000000 0x0 0x80000000>;
+		/* socket 1, no specific cluster, core */
+		arm,associativity = <1 0xffff 0xffff>;
+	};
+
+};
diff --git a/arch/arm64/boot/dts/cavium/thunder-88xx-2n.dtsi b/arch/arm64/boot/dts/cavium/thunder-88xx-2n.dtsi
new file mode 100644
index 0000000..dc6f8ea
--- /dev/null
+++ b/arch/arm64/boot/dts/cavium/thunder-88xx-2n.dtsi
@@ -0,0 +1,790 @@
+/*
+ * Cavium Thunder DTS file - Thunder SoC description
+ *
+ * Copyright (C) 2014, Cavium Inc.
+ *
+ * This file is dual-licensed: you can use it either under the terms
+ * of the GPL or the X11 license, at your option. Note that this dual
+ * licensing only applies to this file, and not this project as a
+ * whole.
+ *
+ *  a) This library 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 library 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.
+ *
+ *     You should have received a copy of the GNU General Public
+ *     License along with this library; if not, write to the Free
+ *     Software Foundation, Inc., 51 Franklin St, Fifth Floor, Boston,
+ *     MA 02110-1301 USA
+ *
+ * Or, alternatively,
+ *
+ *  b) Permission is hereby granted, free of charge, to any person
+ *     obtaining a copy of this software and associated documentation
+ *     files (the "Software"), to deal in the Software without
+ *     restriction, including without limitation the rights to use,
+ *     copy, modify, merge, publish, distribute, sublicense, and/or
+ *     sell copies of the Software, and to permit persons to whom the
+ *     Software is furnished to do so, subject to the following
+ *     conditions:
+ *
+ *     The above copyright notice and this permission notice shall be
+ *     included in all copies or substantial portions of the Software.
+ *
+ *     THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
+ *     EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES
+ *     OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
+ *     NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT
+ *     HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY,
+ *     WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
+ *     FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR
+ *     OTHER DEALINGS IN THE SOFTWARE.
+ */
+
+/ {
+	compatible = "cavium,thunder-88xx";
+	interrupt-parent = <&gic0>;
+	#address-cells = <2>;
+	#size-cells = <2>;
+
+	psci {
+		compatible = "arm,psci-0.2";
+		method = "smc";
+	};
+
+	cpus {
+		#address-cells = <2>;
+		#size-cells = <0>;
+
+		cpu at 000 {
+			device_type = "cpu";
+			compatible = "cavium,thunder", "arm,armv8";
+			reg = <0x0 0x000>;
+			enable-method = "psci";
+			/* socket 0, cluster 0, core 0*/
+			arm,associativity = <0 0 0>;
+		};
+		cpu at 001 {
+			device_type = "cpu";
+			compatible = "cavium,thunder", "arm,armv8";
+			reg = <0x0 0x001>;
+			enable-method = "psci";
+			arm,associativity = <0 0 1>;
+		};
+		cpu at 002 {
+			device_type = "cpu";
+			compatible = "cavium,thunder", "arm,armv8";
+			reg = <0x0 0x002>;
+			enable-method = "psci";
+			arm,associativity = <0 0 2>;
+		};
+		cpu at 003 {
+			device_type = "cpu";
+			compatible = "cavium,thunder", "arm,armv8";
+			reg = <0x0 0x003>;
+			enable-method = "psci";
+			arm,associativity = <0 0 3>;
+		};
+		cpu at 004 {
+			device_type = "cpu";
+			compatible = "cavium,thunder", "arm,armv8";
+			reg = <0x0 0x004>;
+			enable-method = "psci";
+			arm,associativity = <0 0 4>;
+		};
+		cpu at 005 {
+			device_type = "cpu";
+			compatible = "cavium,thunder", "arm,armv8";
+			reg = <0x0 0x005>;
+			enable-method = "psci";
+			arm,associativity = <0 0 5>;
+		};
+		cpu at 006 {
+			device_type = "cpu";
+			compatible = "cavium,thunder", "arm,armv8";
+			reg = <0x0 0x006>;
+			enable-method = "psci";
+			arm,associativity = <0 0 6>;
+		};
+		cpu at 007 {
+			device_type = "cpu";
+			compatible = "cavium,thunder", "arm,armv8";
+			reg = <0x0 0x007>;
+			enable-method = "psci";
+			arm,associativity = <0 0 7>;
+		};
+		cpu at 008 {
+			device_type = "cpu";
+			compatible = "cavium,thunder", "arm,armv8";
+			reg = <0x0 0x008>;
+			enable-method = "psci";
+			arm,associativity = <0 0 8>;
+		};
+		cpu at 009 {
+			device_type = "cpu";
+			compatible = "cavium,thunder", "arm,armv8";
+			reg = <0x0 0x009>;
+			enable-method = "psci";
+			arm,associativity = <0 0 9>;
+		};
+		cpu at 00a {
+			device_type = "cpu";
+			compatible = "cavium,thunder", "arm,armv8";
+			reg = <0x0 0x00a>;
+			enable-method = "psci";
+			arm,associativity = <0 0 10>;
+		};
+		cpu at 00b {
+			device_type = "cpu";
+			compatible = "cavium,thunder", "arm,armv8";
+			reg = <0x0 0x00b>;
+			enable-method = "psci";
+			arm,associativity = <0 0 11>;
+		};
+		cpu at 00c {
+			device_type = "cpu";
+			compatible = "cavium,thunder", "arm,armv8";
+			reg = <0x0 0x00c>;
+			enable-method = "psci";
+			arm,associativity = <0 0 12>;
+		};
+		cpu at 00d {
+			device_type = "cpu";
+			compatible = "cavium,thunder", "arm,armv8";
+			reg = <0x0 0x00d>;
+			enable-method = "psci";
+			arm,associativity = <0 0 13>;
+		};
+		cpu at 00e {
+			device_type = "cpu";
+			compatible = "cavium,thunder", "arm,armv8";
+			reg = <0x0 0x00e>;
+			enable-method = "psci";
+			arm,associativity = <0 0 14>;
+		};
+		cpu at 00f {
+			device_type = "cpu";
+			compatible = "cavium,thunder", "arm,armv8";
+			reg = <0x0 0x00f>;
+			enable-method = "psci";
+			arm,associativity = <0 0 15>;
+		};
+		cpu at 100 {
+			device_type = "cpu";
+			compatible = "cavium,thunder", "arm,armv8";
+			reg = <0x0 0x100>;
+			enable-method = "psci";
+			arm,associativity = <0 1 0>;
+		};
+		cpu at 101 {
+			device_type = "cpu";
+			compatible = "cavium,thunder", "arm,armv8";
+			reg = <0x0 0x101>;
+			enable-method = "psci";
+			arm,associativity = <0 1 1>;
+		};
+		cpu at 102 {
+			device_type = "cpu";
+			compatible = "cavium,thunder", "arm,armv8";
+			reg = <0x0 0x102>;
+			enable-method = "psci";
+			arm,associativity = <0 1 2>;
+		};
+		cpu at 103 {
+			device_type = "cpu";
+			compatible = "cavium,thunder", "arm,armv8";
+			reg = <0x0 0x103>;
+			enable-method = "psci";
+			arm,associativity = <0 1 3>;
+		};
+		cpu at 104 {
+			device_type = "cpu";
+			compatible = "cavium,thunder", "arm,armv8";
+			reg = <0x0 0x104>;
+			enable-method = "psci";
+			arm,associativity = <0 1 4>;
+		};
+		cpu at 105 {
+			device_type = "cpu";
+			compatible = "cavium,thunder", "arm,armv8";
+			reg = <0x0 0x105>;
+			enable-method = "psci";
+			arm,associativity = <0 1 5>;
+		};
+		cpu at 106 {
+			device_type = "cpu";
+			compatible = "cavium,thunder", "arm,armv8";
+			reg = <0x0 0x106>;
+			enable-method = "psci";
+			arm,associativity = <0 1 6>;
+		};
+		cpu at 107 {
+			device_type = "cpu";
+			compatible = "cavium,thunder", "arm,armv8";
+			reg = <0x0 0x107>;
+			enable-method = "psci";
+			arm,associativity = <0 1 7>;
+		};
+		cpu at 108 {
+			device_type = "cpu";
+			compatible = "cavium,thunder", "arm,armv8";
+			reg = <0x0 0x108>;
+			enable-method = "psci";
+			arm,associativity = <0 1 8>;
+		};
+		cpu at 109 {
+			device_type = "cpu";
+			compatible = "cavium,thunder", "arm,armv8";
+			reg = <0x0 0x109>;
+			enable-method = "psci";
+			arm,associativity = <0 1 9>;
+		};
+		cpu at 10a {
+			device_type = "cpu";
+			compatible = "cavium,thunder", "arm,armv8";
+			reg = <0x0 0x10a>;
+			enable-method = "psci";
+			arm,associativity = <0 1 10>;
+		};
+		cpu at 10b {
+			device_type = "cpu";
+			compatible = "cavium,thunder", "arm,armv8";
+			reg = <0x0 0x10b>;
+			enable-method = "psci";
+			arm,associativity = <0 1 11>;
+		};
+		cpu at 10c {
+			device_type = "cpu";
+			compatible = "cavium,thunder", "arm,armv8";
+			reg = <0x0 0x10c>;
+			enable-method = "psci";
+			arm,associativity = <0 1 12>;
+		};
+		cpu at 10d {
+			device_type = "cpu";
+			compatible = "cavium,thunder", "arm,armv8";
+			reg = <0x0 0x10d>;
+			enable-method = "psci";
+			arm,associativity = <0 1 13>;
+		};
+		cpu at 10e {
+			device_type = "cpu";
+			compatible = "cavium,thunder", "arm,armv8";
+			reg = <0x0 0x10e>;
+			enable-method = "psci";
+			arm,associativity = <0 1 14>;
+		};
+		cpu at 10f {
+			device_type = "cpu";
+			compatible = "cavium,thunder", "arm,armv8";
+			reg = <0x0 0x10f>;
+			enable-method = "psci";
+			arm,associativity = <0 1 15>;
+		};
+		cpu at 200 {
+			device_type = "cpu";
+			compatible = "cavium,thunder", "arm,armv8";
+			reg = <0x0 0x200>;
+			enable-method = "psci";
+			arm,associativity = <0 2 0>;
+		};
+		cpu at 201 {
+			device_type = "cpu";
+			compatible = "cavium,thunder", "arm,armv8";
+			reg = <0x0 0x201>;
+			enable-method = "psci";
+			arm,associativity = <0 2 1>;
+		};
+		cpu at 202 {
+			device_type = "cpu";
+			compatible = "cavium,thunder", "arm,armv8";
+			reg = <0x0 0x202>;
+			enable-method = "psci";
+			arm,associativity = <0 2 2>;
+		};
+		cpu at 203 {
+			device_type = "cpu";
+			compatible = "cavium,thunder", "arm,armv8";
+			reg = <0x0 0x203>;
+			enable-method = "psci";
+			arm,associativity = <0 2 3>;
+		};
+		cpu at 204 {
+			device_type = "cpu";
+			compatible = "cavium,thunder", "arm,armv8";
+			reg = <0x0 0x204>;
+			enable-method = "psci";
+			arm,associativity = <0 2 4>;
+		};
+		cpu at 205 {
+			device_type = "cpu";
+			compatible = "cavium,thunder", "arm,armv8";
+			reg = <0x0 0x205>;
+			enable-method = "psci";
+			arm,associativity = <0 2 5>;
+		};
+		cpu at 206 {
+			device_type = "cpu";
+			compatible = "cavium,thunder", "arm,armv8";
+			reg = <0x0 0x206>;
+			enable-method = "psci";
+			arm,associativity = <0 2 6>;
+		};
+		cpu at 207 {
+			device_type = "cpu";
+			compatible = "cavium,thunder", "arm,armv8";
+			reg = <0x0 0x207>;
+			enable-method = "psci";
+			arm,associativity = <0 2 7>;
+		};
+		cpu at 208 {
+			device_type = "cpu";
+			compatible = "cavium,thunder", "arm,armv8";
+			reg = <0x0 0x208>;
+			enable-method = "psci";
+			arm,associativity = <0 2 8>;
+		};
+		cpu at 209 {
+			device_type = "cpu";
+			compatible = "cavium,thunder", "arm,armv8";
+			reg = <0x0 0x209>;
+			enable-method = "psci";
+			arm,associativity = <0 2 9>;
+		};
+		cpu at 20a {
+			device_type = "cpu";
+			compatible = "cavium,thunder", "arm,armv8";
+			reg = <0x0 0x20a>;
+			enable-method = "psci";
+			arm,associativity = <0 2 10>;
+		};
+		cpu at 20b {
+			device_type = "cpu";
+			compatible = "cavium,thunder", "arm,armv8";
+			reg = <0x0 0x20b>;
+			enable-method = "psci";
+			arm,associativity = <0 2 11>;
+		};
+		cpu at 20c {
+			device_type = "cpu";
+			compatible = "cavium,thunder", "arm,armv8";
+			reg = <0x0 0x20c>;
+			enable-method = "psci";
+			arm,associativity = <0 2 12>;
+		};
+		cpu at 20d {
+			device_type = "cpu";
+			compatible = "cavium,thunder", "arm,armv8";
+			reg = <0x0 0x20d>;
+			enable-method = "psci";
+			arm,associativity = <0 2 13>;
+		};
+		cpu at 20e {
+			device_type = "cpu";
+			compatible = "cavium,thunder", "arm,armv8";
+			reg = <0x0 0x20e>;
+			enable-method = "psci";
+			arm,associativity = <0 2 14>;
+		};
+		cpu at 20f {
+			device_type = "cpu";
+			compatible = "cavium,thunder", "arm,armv8";
+			reg = <0x0 0x20f>;
+			enable-method = "psci";
+			arm,associativity = <0 2 15>;
+		};
+		cpu at 10000 {
+			device_type = "cpu";
+			compatible = "cavium,thunder", "arm,armv8";
+			reg = <0x0 0x10000>;
+			enable-method = "psci";
+			/* socket 1, cluster 0, core 0*/
+			arm,associativity = <1 0 0>;
+		};
+		cpu at 10001 {
+			device_type = "cpu";
+			compatible = "cavium,thunder", "arm,armv8";
+			reg = <0x0 0x10001>;
+			enable-method = "psci";
+			arm,associativity = <1 0 1>;
+		};
+		cpu at 10002 {
+			device_type = "cpu";
+			compatible = "cavium,thunder", "arm,armv8";
+			reg = <0x0 0x10002>;
+			enable-method = "psci";
+			arm,associativity = <1 0 2>;
+		};
+		cpu at 10003 {
+			device_type = "cpu";
+			compatible = "cavium,thunder", "arm,armv8";
+			reg = <0x0 0x10003>;
+			enable-method = "psci";
+			arm,associativity = <1 0 3>;
+		};
+		cpu at 10004 {
+			device_type = "cpu";
+			compatible = "cavium,thunder", "arm,armv8";
+			reg = <0x0 0x10004>;
+			enable-method = "psci";
+			arm,associativity = <1 0 4>;
+		};
+		cpu at 10005 {
+			device_type = "cpu";
+			compatible = "cavium,thunder", "arm,armv8";
+			reg = <0x0 0x10005>;
+			enable-method = "psci";
+			arm,associativity = <1 0 5>;
+		};
+		cpu at 10006 {
+			device_type = "cpu";
+			compatible = "cavium,thunder", "arm,armv8";
+			reg = <0x0 0x10006>;
+			enable-method = "psci";
+			arm,associativity = <1 0 6>;
+		};
+		cpu at 10007 {
+			device_type = "cpu";
+			compatible = "cavium,thunder", "arm,armv8";
+			reg = <0x0 0x10007>;
+			enable-method = "psci";
+			arm,associativity = <1 0 7>;
+		};
+		cpu at 10008 {
+			device_type = "cpu";
+			compatible = "cavium,thunder", "arm,armv8";
+			reg = <0x0 0x10008>;
+			enable-method = "psci";
+			arm,associativity = <1 0 8>;
+		};
+		cpu at 10009 {
+			device_type = "cpu";
+			compatible = "cavium,thunder", "arm,armv8";
+			reg = <0x0 0x10009>;
+			enable-method = "psci";
+			arm,associativity = <1 0 9>;
+		};
+		cpu at 1000a {
+			device_type = "cpu";
+			compatible = "cavium,thunder", "arm,armv8";
+			reg = <0x0 0x1000a>;
+			enable-method = "psci";
+			arm,associativity = <1 0 10>;
+		};
+		cpu at 1000b {
+			device_type = "cpu";
+			compatible = "cavium,thunder", "arm,armv8";
+			reg = <0x0 0x1000b>;
+			enable-method = "psci";
+			arm,associativity = <1 0 11>;
+		};
+		cpu at 1000c {
+			device_type = "cpu";
+			compatible = "cavium,thunder", "arm,armv8";
+			reg = <0x0 0x1000c>;
+			enable-method = "psci";
+			arm,associativity = <1 0 12>;
+		};
+		cpu at 1000d {
+			device_type = "cpu";
+			compatible = "cavium,thunder", "arm,armv8";
+			reg = <0x0 0x1000d>;
+			enable-method = "psci";
+			arm,associativity = <1 0 13>;
+		};
+		cpu at 1000e {
+			device_type = "cpu";
+			compatible = "cavium,thunder", "arm,armv8";
+			reg = <0x0 0x1000e>;
+			enable-method = "psci";
+			arm,associativity = <1 0 14>;
+		};
+		cpu at 1000f {
+			device_type = "cpu";
+			compatible = "cavium,thunder", "arm,armv8";
+			reg = <0x0 0x1000f>;
+			enable-method = "psci";
+			arm,associativity = <1 0 15>;
+		};
+		cpu at 10100 {
+			device_type = "cpu";
+			compatible = "cavium,thunder", "arm,armv8";
+			reg = <0x0 0x10100>;
+			enable-method = "psci";
+			arm,associativity = <1 1 0>;
+		};
+		cpu at 10101 {
+			device_type = "cpu";
+			compatible = "cavium,thunder", "arm,armv8";
+			reg = <0x0 0x10101>;
+			enable-method = "psci";
+			arm,associativity = <1 1 1>;
+		};
+		cpu at 10102 {
+			device_type = "cpu";
+			compatible = "cavium,thunder", "arm,armv8";
+			reg = <0x0 0x10102>;
+			enable-method = "psci";
+			arm,associativity = <1 1 2>;
+		};
+		cpu at 10103 {
+			device_type = "cpu";
+			compatible = "cavium,thunder", "arm,armv8";
+			reg = <0x0 0x10103>;
+			enable-method = "psci";
+			arm,associativity = <1 1 3>;
+		};
+		cpu at 10104 {
+			device_type = "cpu";
+			compatible = "cavium,thunder", "arm,armv8";
+			reg = <0x0 0x10104>;
+			enable-method = "psci";
+			arm,associativity = <1 1 4>;
+		};
+		cpu at 10105 {
+			device_type = "cpu";
+			compatible = "cavium,thunder", "arm,armv8";
+			reg = <0x0 0x10105>;
+			enable-method = "psci";
+			arm,associativity = <1 1 5>;
+		};
+		cpu at 10106 {
+			device_type = "cpu";
+			compatible = "cavium,thunder", "arm,armv8";
+			reg = <0x0 0x10106>;
+			enable-method = "psci";
+			arm,associativity = <1 1 6>;
+		};
+		cpu at 10107 {
+			device_type = "cpu";
+			compatible = "cavium,thunder", "arm,armv8";
+			reg = <0x0 0x10107>;
+			enable-method = "psci";
+			arm,associativity = <1 1 7>;
+		};
+		cpu at 10108 {
+			device_type = "cpu";
+			compatible = "cavium,thunder", "arm,armv8";
+			reg = <0x0 0x10108>;
+			enable-method = "psci";
+			arm,associativity = <1 1 8>;
+		};
+		cpu at 10109 {
+			device_type = "cpu";
+			compatible = "cavium,thunder", "arm,armv8";
+			reg = <0x0 0x10109>;
+			enable-method = "psci";
+			arm,associativity = <1 1 9>;
+		};
+		cpu at 1010a {
+			device_type = "cpu";
+			compatible = "cavium,thunder", "arm,armv8";
+			reg = <0x0 0x1010a>;
+			enable-method = "psci";
+			arm,associativity = <1 1 10>;
+		};
+		cpu at 1010b {
+			device_type = "cpu";
+			compatible = "cavium,thunder", "arm,armv8";
+			reg = <0x0 0x1010b>;
+			enable-method = "psci";
+			arm,associativity = <1 1 11>;
+		};
+		cpu at 1010c {
+			device_type = "cpu";
+			compatible = "cavium,thunder", "arm,armv8";
+			reg = <0x0 0x1010c>;
+			enable-method = "psci";
+			arm,associativity = <1 1 12>;
+		};
+		cpu at 1010d {
+			device_type = "cpu";
+			compatible = "cavium,thunder", "arm,armv8";
+			reg = <0x0 0x1010d>;
+			enable-method = "psci";
+			arm,associativity = <1 1 13>;
+		};
+		cpu at 1010e {
+			device_type = "cpu";
+			compatible = "cavium,thunder", "arm,armv8";
+			reg = <0x0 0x1010e>;
+			enable-method = "psci";
+			arm,associativity = <1 1 14>;
+		};
+		cpu at 1010f {
+			device_type = "cpu";
+			compatible = "cavium,thunder", "arm,armv8";
+			reg = <0x0 0x1010f>;
+			enable-method = "psci";
+			arm,associativity = <1 1 15>;
+		};
+		cpu at 10200 {
+			device_type = "cpu";
+			compatible = "cavium,thunder", "arm,armv8";
+			reg = <0x0 0x10200>;
+			enable-method = "psci";
+			arm,associativity = <1 2 0>;
+		};
+		cpu at 10201 {
+			device_type = "cpu";
+			compatible = "cavium,thunder", "arm,armv8";
+			reg = <0x0 0x10201>;
+			enable-method = "psci";
+			arm,associativity = <1 2 1>;
+		};
+		cpu at 10202 {
+			device_type = "cpu";
+			compatible = "cavium,thunder", "arm,armv8";
+			reg = <0x0 0x10202>;
+			enable-method = "psci";
+			arm,associativity = <1 2 2>;
+		};
+		cpu at 10203 {
+			device_type = "cpu";
+			compatible = "cavium,thunder", "arm,armv8";
+			reg = <0x0 0x10203>;
+			enable-method = "psci";
+			arm,associativity = <1 2 3>;
+		};
+		cpu at 10204 {
+			device_type = "cpu";
+			compatible = "cavium,thunder", "arm,armv8";
+			reg = <0x0 0x10204>;
+			enable-method = "psci";
+			arm,associativity = <1 2 4>;
+		};
+		cpu at 10205 {
+			device_type = "cpu";
+			compatible = "cavium,thunder", "arm,armv8";
+			reg = <0x0 0x10205>;
+			enable-method = "psci";
+			arm,associativity = <1 2 5>;
+		};
+		cpu at 10206 {
+			device_type = "cpu";
+			compatible = "cavium,thunder", "arm,armv8";
+			reg = <0x0 0x10206>;
+			enable-method = "psci";
+			arm,associativity = <1 2 6>;
+		};
+		cpu at 10207 {
+			device_type = "cpu";
+			compatible = "cavium,thunder", "arm,armv8";
+			reg = <0x0 0x10207>;
+			enable-method = "psci";
+			arm,associativity = <1 2 7>;
+		};
+		cpu at 10208 {
+			device_type = "cpu";
+			compatible = "cavium,thunder", "arm,armv8";
+			reg = <0x0 0x10208>;
+			enable-method = "psci";
+			arm,associativity = <1 2 8>;
+		};
+		cpu at 10209 {
+			device_type = "cpu";
+			compatible = "cavium,thunder", "arm,armv8";
+			reg = <0x0 0x10209>;
+			enable-method = "psci";
+			arm,associativity = <1 2 9>;
+		};
+		cpu at 1020a {
+			device_type = "cpu";
+			compatible = "cavium,thunder", "arm,armv8";
+			reg = <0x0 0x1020a>;
+			enable-method = "psci";
+			arm,associativity = <1 2 10>;
+		};
+		cpu at 1020b {
+			device_type = "cpu";
+			compatible = "cavium,thunder", "arm,armv8";
+			reg = <0x0 0x1020b>;
+			enable-method = "psci";
+			arm,associativity = <1 2 11>;
+		};
+		cpu at 1020c {
+			device_type = "cpu";
+			compatible = "cavium,thunder", "arm,armv8";
+			reg = <0x0 0x1020c>;
+			enable-method = "psci";
+			arm,associativity = <1 2 12>;
+		};
+		cpu at 1020d {
+			device_type = "cpu";
+			compatible = "cavium,thunder", "arm,armv8";
+			reg = <0x0 0x1020d>;
+			enable-method = "psci";
+			arm,associativity = <1 2 13>;
+		};
+		cpu at 1020e {
+			device_type = "cpu";
+			compatible = "cavium,thunder", "arm,armv8";
+			reg = <0x0 0x1020e>;
+			enable-method = "psci";
+			arm,associativity = <1 2 14>;
+		};
+		cpu at 1020f {
+			device_type = "cpu";
+			compatible = "cavium,thunder", "arm,armv8";
+			reg = <0x0 0x1020f>;
+			enable-method = "psci";
+			arm,associativity = <1 2 15>;
+		};
+	};
+
+	timer {
+		compatible = "arm,armv8-timer";
+		interrupts = <1 13 0xff01>,
+		             <1 14 0xff01>,
+		             <1 11 0xff01>,
+		             <1 10 0xff01>;
+	};
+
+	soc {
+		compatible = "simple-bus";
+		#address-cells = <2>;
+		#size-cells = <2>;
+		ranges;
+		arm,associativity = <0 0xffff 0xffff>;
+
+		refclk50mhz: refclk50mhz {
+			compatible = "fixed-clock";
+			#clock-cells = <0>;
+			clock-frequency = <50000000>;
+			clock-output-names = "refclk50mhz";
+		};
+
+		gic0: interrupt-controller at 8010,00000000 {
+			compatible = "arm,gic-v3";
+			#interrupt-cells = <3>;
+			#redistributor-regions = <2>;
+			interrupt-controller;
+			reg = <0x8010 0x00000000 0x0 0x010000>, /* GICD */
+			      <0x8010 0x80000000 0x0 0x600000>, /* GICR Node 0 */
+			      <0x9010 0x80000000 0x0 0x600000>; /* GICR Node 1 */
+			interrupts = <1 9 0xf04>;
+		};
+
+		uaa0: serial at 87e0,24000000 {
+			compatible = "arm,pl011", "arm,primecell";
+			reg = <0x87e0 0x24000000 0x0 0x1000>;
+			interrupts = <1 21 4>;
+			clocks = <&refclk50mhz>;
+			clock-names = "apb_pclk";
+		};
+
+		uaa1: serial at 87e0,25000000 {
+			compatible = "arm,pl011", "arm,primecell";
+			reg = <0x87e0 0x25000000 0x0 0x1000>;
+			interrupts = <1 22 4>;
+			clocks = <&refclk50mhz>;
+			clock-names = "apb_pclk";
+		};
+	};
+};
-- 
1.8.1.4



From gkulkarni at caviumnetworks.com  Fri Aug 14 09:39:31 2015
From: gkulkarni at caviumnetworks.com (Ganapatrao Kulkarni)
Date: Fri, 14 Aug 2015 22:09:31 +0530
Subject: [PATCH v5 1/4] arm64, numa: adding numa support for arm64 platforms.
In-Reply-To: <1439570374-4079-1-git-send-email-gkulkarni@caviumnetworks.com>
References: <1439570374-4079-1-git-send-email-gkulkarni@caviumnetworks.com>
Message-ID: <1439570374-4079-2-git-send-email-gkulkarni@caviumnetworks.com>

Adding numa support for arm64 based platforms.
This patch adds by default the dummy numa node and
maps all memory and cpus to node 0.
using this patch, numa can be simulated on single node arm64 platforms.

Signed-off-by: Ganapatrao Kulkarni <gkulkarni at caviumnetworks.com>
---
 arch/arm64/Kconfig              |  26 ++
 arch/arm64/include/asm/mmzone.h |  32 +++
 arch/arm64/include/asm/numa.h   |  42 +++
 arch/arm64/kernel/setup.c       |   9 +
 arch/arm64/kernel/smp.c         |   2 +
 arch/arm64/mm/Makefile          |   1 +
 arch/arm64/mm/init.c            |  34 ++-
 arch/arm64/mm/numa.c            | 550 ++++++++++++++++++++++++++++++++++++++++
 8 files changed, 690 insertions(+), 6 deletions(-)
 create mode 100644 arch/arm64/include/asm/mmzone.h
 create mode 100644 arch/arm64/include/asm/numa.h
 create mode 100644 arch/arm64/mm/numa.c

diff --git a/arch/arm64/Kconfig b/arch/arm64/Kconfig
index 43a0c26..fa37a5d 100644
--- a/arch/arm64/Kconfig
+++ b/arch/arm64/Kconfig
@@ -72,6 +72,7 @@ config ARM64
 	select HAVE_PERF_USER_STACK_DUMP
 	select HAVE_RCU_TABLE_FREE
 	select HAVE_SYSCALL_TRACEPOINTS
+	select HAVE_MEMBLOCK_NODE_MAP if NUMA
 	select IRQ_DOMAIN
 	select IRQ_FORCED_THREADING
 	select MODULES_USE_ELF_RELA
@@ -559,6 +560,31 @@ config HOTPLUG_CPU
 	  Say Y here to experiment with turning CPUs off and on.  CPUs
 	  can be controlled through /sys/devices/system/cpu.
 
+# Common NUMA Features
+config NUMA
+	bool "Numa Memory Allocation and Scheduler Support"
+	depends on SMP
+	help
+	  Enable NUMA (Non Uniform Memory Access) support.
+
+	  The kernel will try to allocate memory used by a CPU on the
+	  local memory controller of the CPU and add some more
+	  NUMA awareness to the kernel.
+
+config NODES_SHIFT
+	int "Maximum NUMA Nodes (as a power of 2)"
+	range 1 10
+	default "2"
+	depends on NEED_MULTIPLE_NODES
+	help
+	  Specify the maximum number of NUMA Nodes available on the target
+	  system.  Increases memory reserved to accommodate various tables.
+
+config USE_PERCPU_NUMA_NODE_ID
+	def_bool y
+	depends on NUMA
+
+
 source kernel/Kconfig.preempt
 
 config UP_LATE_INIT
diff --git a/arch/arm64/include/asm/mmzone.h b/arch/arm64/include/asm/mmzone.h
new file mode 100644
index 0000000..d27ee66
--- /dev/null
+++ b/arch/arm64/include/asm/mmzone.h
@@ -0,0 +1,32 @@
+#ifndef __ASM_ARM64_MMZONE_H_
+#define __ASM_ARM64_MMZONE_H_
+
+#ifdef CONFIG_NUMA
+
+#include <linux/mmdebug.h>
+#include <asm/smp.h>
+#include <linux/types.h>
+#include <asm/numa.h>
+
+extern struct pglist_data *node_data[];
+
+#define NODE_DATA(nid)		(node_data[nid])
+
+
+struct numa_memblk {
+	u64			start;
+	u64			end;
+	int			nid;
+};
+
+struct numa_meminfo {
+	int			nr_blks;
+	struct numa_memblk	blk[NR_NODE_MEMBLKS];
+};
+
+void __init numa_remove_memblk_from(int idx, struct numa_meminfo *mi);
+int __init numa_cleanup_meminfo(struct numa_meminfo *mi);
+void __init numa_reset_distance(void);
+
+#endif /* CONFIG_NUMA */
+#endif /* __ASM_ARM64_MMZONE_H_ */
diff --git a/arch/arm64/include/asm/numa.h b/arch/arm64/include/asm/numa.h
new file mode 100644
index 0000000..59b834e
--- /dev/null
+++ b/arch/arm64/include/asm/numa.h
@@ -0,0 +1,42 @@
+#ifndef _ASM_NUMA_H
+#define _ASM_NUMA_H
+
+#include <linux/nodemask.h>
+#include <asm/topology.h>
+
+#ifdef CONFIG_NUMA
+
+#define NR_NODE_MEMBLKS		(MAX_NUMNODES * 2)
+#define ZONE_ALIGN (1UL << (MAX_ORDER + PAGE_SHIFT))
+
+/* currently, arm64 implements flat NUMA topology */
+#define parent_node(node)	(node)
+
+/* dummy definitions for pci functions */
+#define pcibus_to_node(node)	0
+#define cpumask_of_pcibus(bus)	0
+
+struct __node_cpu_hwid {
+	u32 node_id;    /* logical node containing this CPU */
+	u64 cpu_hwid;   /* MPIDR for this CPU */
+};
+
+extern struct __node_cpu_hwid node_cpu_hwid[NR_CPUS];
+extern nodemask_t numa_nodes_parsed __initdata;
+
+const struct cpumask *cpumask_of_node(int node);
+/* Mappings between node number and cpus on that node. */
+extern cpumask_var_t node_to_cpumask_map[MAX_NUMNODES];
+
+void __init arm64_numa_init(void);
+int __init numa_add_memblk(u32 nodeid, u64 start, u64 end);
+void numa_store_cpu_info(int cpu);
+void __init build_cpu_to_node_map(void);
+void __init numa_set_distance(int from, int to, int distance);
+#else	/* CONFIG_NUMA */
+static inline void numa_store_cpu_info(int cpu)		{ }
+static inline void arm64_numa_init(void)		{ }
+static inline void build_cpu_to_node_map(void) { }
+static inline void numa_set_distance(int from, int to, int distance) { }
+#endif	/* CONFIG_NUMA */
+#endif	/* _ASM_NUMA_H */
diff --git a/arch/arm64/kernel/setup.c b/arch/arm64/kernel/setup.c
index 4d4d7ce..6e101eb 100644
--- a/arch/arm64/kernel/setup.c
+++ b/arch/arm64/kernel/setup.c
@@ -65,6 +65,7 @@
 #include <asm/efi.h>
 #include <asm/virt.h>
 #include <asm/xen/hypervisor.h>
+#include <asm/numa.h>
 
 unsigned long elf_hwcap __read_mostly;
 EXPORT_SYMBOL_GPL(elf_hwcap);
@@ -439,6 +440,9 @@ static int __init topology_init(void)
 {
 	int i;
 
+	for_each_online_node(i)
+		register_one_node(i);
+
 	for_each_possible_cpu(i) {
 		struct cpu *cpu = &per_cpu(cpu_data.cpu, i);
 		cpu->hotpluggable = 1;
@@ -511,7 +515,12 @@ static int c_show(struct seq_file *m, void *v)
 		 * "processor".  Give glibc what it expects.
 		 */
 #ifdef CONFIG_SMP
+	if (IS_ENABLED(CONFIG_NUMA)) {
+		seq_printf(m, "processor\t: %d", i);
+		seq_printf(m, " [nid: %d]\n", cpu_to_node(i));
+	} else {
 		seq_printf(m, "processor\t: %d\n", i);
+	}
 #endif
 
 		/*
diff --git a/arch/arm64/kernel/smp.c b/arch/arm64/kernel/smp.c
index 50fb469..ae3e02c 100644
--- a/arch/arm64/kernel/smp.c
+++ b/arch/arm64/kernel/smp.c
@@ -52,6 +52,7 @@
 #include <asm/sections.h>
 #include <asm/tlbflush.h>
 #include <asm/ptrace.h>
+#include <asm/numa.h>
 
 #define CREATE_TRACE_POINTS
 #include <trace/events/ipi.h>
@@ -124,6 +125,7 @@ int __cpu_up(unsigned int cpu, struct task_struct *idle)
 static void smp_store_cpu_info(unsigned int cpuid)
 {
 	store_cpu_topology(cpuid);
+	numa_store_cpu_info(cpuid);
 }
 
 /*
diff --git a/arch/arm64/mm/Makefile b/arch/arm64/mm/Makefile
index 773d37a..bb92d41 100644
--- a/arch/arm64/mm/Makefile
+++ b/arch/arm64/mm/Makefile
@@ -4,3 +4,4 @@ obj-y				:= dma-mapping.o extable.o fault.o init.o \
 				   context.o proc.o pageattr.o
 obj-$(CONFIG_HUGETLB_PAGE)	+= hugetlbpage.o
 obj-$(CONFIG_ARM64_PTDUMP)	+= dump.o
+obj-$(CONFIG_NUMA)		+= numa.o
diff --git a/arch/arm64/mm/init.c b/arch/arm64/mm/init.c
index 54da32e..cab384b 100644
--- a/arch/arm64/mm/init.c
+++ b/arch/arm64/mm/init.c
@@ -42,6 +42,7 @@
 #include <asm/sizes.h>
 #include <asm/tlb.h>
 #include <asm/alternative.h>
+#include <asm/numa.h>
 
 #include "mm.h"
 
@@ -77,6 +78,20 @@ static phys_addr_t max_zone_dma_phys(void)
 	return min(offset + (1ULL << 32), memblock_end_of_DRAM());
 }
 
+#ifdef CONFIG_NUMA
+static void __init zone_sizes_init(unsigned long min, unsigned long max)
+{
+	unsigned long max_zone_pfns[MAX_NR_ZONES];
+
+	memset(max_zone_pfns, 0, sizeof(max_zone_pfns));
+	if (IS_ENABLED(CONFIG_ZONE_DMA))
+		max_zone_pfns[ZONE_DMA] = PFN_DOWN(max_zone_dma_phys());
+	max_zone_pfns[ZONE_NORMAL] = max;
+
+	free_area_init_nodes(max_zone_pfns);
+}
+
+#else
 static void __init zone_sizes_init(unsigned long min, unsigned long max)
 {
 	struct memblock_region *reg;
@@ -115,6 +130,7 @@ static void __init zone_sizes_init(unsigned long min, unsigned long max)
 
 	free_area_init_node(0, zone_size, min, zhole_size);
 }
+#endif /* CONFIG_NUMA */
 
 #ifdef CONFIG_HAVE_ARCH_PFN_VALID
 int pfn_valid(unsigned long pfn)
@@ -132,10 +148,15 @@ static void arm64_memory_present(void)
 static void arm64_memory_present(void)
 {
 	struct memblock_region *reg;
+	int nid = 0;
 
-	for_each_memblock(memory, reg)
-		memory_present(0, memblock_region_memory_base_pfn(reg),
-			       memblock_region_memory_end_pfn(reg));
+	for_each_memblock(memory, reg) {
+#ifdef CONFIG_NUMA
+		nid = reg->nid;
+#endif
+		memory_present(nid, memblock_region_memory_base_pfn(reg),
+				memblock_region_memory_end_pfn(reg));
+	}
 }
 #endif
 
@@ -200,6 +221,10 @@ void __init bootmem_init(void)
 	min = PFN_UP(memblock_start_of_DRAM());
 	max = PFN_DOWN(memblock_end_of_DRAM());
 
+	high_memory = __va((max << PAGE_SHIFT) - 1) + 1;
+	max_pfn = max_low_pfn = max;
+
+	arm64_numa_init();
 	/*
 	 * Sparsemem tries to allocate bootmem in memory_present(), so must be
 	 * done after the fixed reservations.
@@ -208,9 +233,6 @@ void __init bootmem_init(void)
 
 	sparse_init();
 	zone_sizes_init(min, max);
-
-	high_memory = __va((max << PAGE_SHIFT) - 1) + 1;
-	max_pfn = max_low_pfn = max;
 }
 
 #ifndef CONFIG_SPARSEMEM_VMEMMAP
diff --git a/arch/arm64/mm/numa.c b/arch/arm64/mm/numa.c
new file mode 100644
index 0000000..2be83de
--- /dev/null
+++ b/arch/arm64/mm/numa.c
@@ -0,0 +1,550 @@
+/*
+ * NUMA support, based on the x86 implementation.
+ *
+ * Copyright (C) 2015 Cavium Inc.
+ * Author: Ganapatrao Kulkarni <gkulkarni at cavium.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.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program.  If not, see <http://www.gnu.org/licenses/>.
+ */
+
+#include <linux/kernel.h>
+#include <linux/mm.h>
+#include <linux/string.h>
+#include <linux/init.h>
+#include <linux/bootmem.h>
+#include <linux/memblock.h>
+#include <linux/ctype.h>
+#include <linux/module.h>
+#include <linux/nodemask.h>
+#include <linux/sched.h>
+#include <linux/topology.h>
+#include <linux/mmzone.h>
+
+#include <asm/smp_plat.h>
+
+int __initdata numa_off;
+nodemask_t numa_nodes_parsed __initdata;
+static int numa_distance_cnt;
+static u8 *numa_distance;
+static u8 dummy_numa_enabled;
+
+struct pglist_data *node_data[MAX_NUMNODES] __read_mostly;
+EXPORT_SYMBOL(node_data);
+
+struct __node_cpu_hwid node_cpu_hwid[NR_CPUS];
+static struct numa_meminfo numa_meminfo;
+
+static __init int numa_setup(char *opt)
+{
+	if (!opt)
+		return -EINVAL;
+	if (!strncmp(opt, "off", 3)) {
+		pr_info("%s\n", "NUMA turned off");
+		numa_off = 1;
+	}
+	return 0;
+}
+early_param("numa", numa_setup);
+
+cpumask_var_t node_to_cpumask_map[MAX_NUMNODES];
+EXPORT_SYMBOL(node_to_cpumask_map);
+
+int cpu_to_node_map[NR_CPUS];
+EXPORT_SYMBOL(cpu_to_node_map);
+
+/*
+ * Returns a pointer to the bitmask of CPUs on Node 'node'.
+ */
+const struct cpumask *cpumask_of_node(int node)
+{
+	if (node >= nr_node_ids) {
+		pr_warn("cpumask_of_node(%d): node > nr_node_ids(%d)\n",
+			node, nr_node_ids);
+		dump_stack();
+		return cpu_none_mask;
+	}
+	if (node_to_cpumask_map[node] == NULL) {
+		pr_warn("cpumask_of_node(%d): no node_to_cpumask_map!\n",
+			node);
+		dump_stack();
+		return cpu_online_mask;
+	}
+	return node_to_cpumask_map[node];
+}
+EXPORT_SYMBOL(cpumask_of_node);
+
+void numa_clear_node(int cpu)
+{
+	set_cpu_numa_node(cpu, NUMA_NO_NODE);
+}
+
+void map_cpu_to_node(int cpu, int nid)
+{
+	if (nid < 0) { /* just initialize by zero */
+		cpu_to_node_map[cpu] = 0;
+		return;
+	}
+
+	cpu_to_node_map[cpu] = nid;
+	cpumask_set_cpu(cpu, node_to_cpumask_map[nid]);
+	set_numa_node(nid);
+}
+
+/**
+ * build_cpu_to_node_map - setup cpu to node and node to cpumask arrays
+ *
+ * Build cpu to node mapping and initialize the per node cpu masks using
+ * info from the node_cpuid array handed to us by ACPI or DT.
+ */
+void __init build_cpu_to_node_map(void)
+{
+	int cpu, i, node;
+
+	for (node = 0; node < MAX_NUMNODES; node++)
+		cpumask_clear(node_to_cpumask_map[node]);
+
+	for_each_possible_cpu(cpu) {
+		node = NUMA_NO_NODE;
+		for_each_possible_cpu(i) {
+			if (cpu_logical_map(cpu) == node_cpu_hwid[i].cpu_hwid) {
+				node = node_cpu_hwid[i].node_id;
+				break;
+			}
+		}
+		map_cpu_to_node(cpu, node);
+	}
+}
+/*
+ * Allocate node_to_cpumask_map based on number of available nodes
+ * Requires node_possible_map to be valid.
+ *
+ * Note: cpumask_of_node() is not valid until after this is done.
+ * (Use CONFIG_DEBUG_PER_CPU_MAPS to check this.)
+ */
+void __init setup_node_to_cpumask_map(void)
+{
+	unsigned int node;
+
+	/* setup nr_node_ids if not done yet */
+	if (nr_node_ids == MAX_NUMNODES)
+		setup_nr_node_ids();
+
+	/* allocate the map */
+	for (node = 0; node < nr_node_ids; node++)
+		alloc_bootmem_cpumask_var(&node_to_cpumask_map[node]);
+
+	/* cpumask_of_node() will now work */
+	pr_debug("Node to cpumask map for %d nodes\n", nr_node_ids);
+}
+
+/*
+ *  Set the cpu to node and mem mapping
+ */
+void numa_store_cpu_info(int cpu)
+{
+	if (dummy_numa_enabled) {
+		/* set to default */
+		node_cpu_hwid[cpu].node_id  =  0;
+		node_cpu_hwid[cpu].cpu_hwid = cpu_logical_map(cpu);
+	}
+	map_cpu_to_node(cpu, node_cpu_hwid[cpu].node_id);
+}
+
+/**
+ * numa_add_memblk_to - Add one numa_memblk to a numa_meminfo
+ */
+
+static int __init numa_add_memblk_to(int nid, u64 start, u64 end,
+				     struct numa_meminfo *mi)
+{
+	/* ignore zero length blks */
+	if (start == end)
+		return 0;
+
+	/* whine about and ignore invalid blks */
+	if (start > end || nid < 0 || nid >= MAX_NUMNODES) {
+		pr_warn("NUMA: Warning: invalid memblk node %d [mem %#010Lx-%#010Lx]\n",
+				nid, start, end - 1);
+		return 0;
+	}
+
+	if (mi->nr_blks >= NR_NODE_MEMBLKS) {
+		pr_err("NUMA: too many memblk ranges\n");
+		return -EINVAL;
+	}
+
+	pr_info("NUMA: Adding memblock %d [0x%llx - 0x%llx] on node %d\n",
+			mi->nr_blks, start, end, nid);
+	mi->blk[mi->nr_blks].start = start;
+	mi->blk[mi->nr_blks].end = end;
+	mi->blk[mi->nr_blks].nid = nid;
+	mi->nr_blks++;
+	return 0;
+}
+
+/**
+ * numa_add_memblk - Add one numa_memblk to numa_meminfo
+ * @nid: NUMA node ID of the new memblk
+ * @start: Start address of the new memblk
+ * @end: End address of the new memblk
+ *
+ * Add a new memblk to the default numa_meminfo.
+ *
+ * RETURNS:
+ * 0 on success, -errno on failure.
+ */
+#define MAX_PHYS_ADDR	((phys_addr_t)~0)
+
+int __init numa_add_memblk(u32 nid, u64 base, u64 end)
+{
+	const u64 phys_offset = __pa(PAGE_OFFSET);
+
+	base &= PAGE_MASK;
+	end &= PAGE_MASK;
+
+	if (base > MAX_PHYS_ADDR) {
+		pr_warn("NUMA: Ignoring memory block 0x%llx - 0x%llx\n",
+				base, base + end);
+		return -ENOMEM;
+	}
+
+	if (base + end > MAX_PHYS_ADDR) {
+		pr_info("NUMA: Ignoring memory range 0x%lx - 0x%llx\n",
+				ULONG_MAX, base + end);
+		end = MAX_PHYS_ADDR - base;
+	}
+
+	if (base + end < phys_offset) {
+		pr_warn("NUMA: Ignoring memory block 0x%llx - 0x%llx\n",
+			   base, base + end);
+		return -ENOMEM;
+	}
+	if (base < phys_offset) {
+		pr_info("NUMA: Ignoring memory range 0x%llx - 0x%llx\n",
+			   base, phys_offset);
+		end -= phys_offset - base;
+		base = phys_offset;
+	}
+
+	return numa_add_memblk_to(nid, base, base + end, &numa_meminfo);
+}
+EXPORT_SYMBOL(numa_add_memblk);
+
+/* Initialize NODE_DATA for a node on the local memory */
+static void __init setup_node_data(int nid, u64 start, u64 end)
+{
+	const size_t nd_size = roundup(sizeof(pg_data_t), PAGE_SIZE);
+	u64 nd_pa;
+	void *nd;
+	int tnid;
+
+	start = roundup(start, ZONE_ALIGN);
+
+	pr_info("Initmem setup node %d [mem %#010Lx-%#010Lx]\n",
+	       nid, start, end - 1);
+
+	/*
+	 * Allocate node data.  Try node-local memory and then any node.
+	 */
+	nd_pa = memblock_alloc_nid(nd_size, SMP_CACHE_BYTES, nid);
+	if (!nd_pa) {
+		nd_pa = __memblock_alloc_base(nd_size, SMP_CACHE_BYTES,
+					      MEMBLOCK_ALLOC_ACCESSIBLE);
+		if (!nd_pa) {
+			pr_err("Cannot find %zu bytes in node %d\n",
+			       nd_size, nid);
+			return;
+		}
+	}
+	nd = __va(nd_pa);
+
+	/* report and initialize */
+	pr_info("  NODE_DATA [mem %#010Lx-%#010Lx]\n",
+	       nd_pa, nd_pa + nd_size - 1);
+	tnid = early_pfn_to_nid(nd_pa >> PAGE_SHIFT);
+	if (tnid != nid)
+		pr_info("    NODE_DATA(%d) on node %d\n", nid, tnid);
+
+	node_data[nid] = nd;
+	memset(NODE_DATA(nid), 0, sizeof(pg_data_t));
+	NODE_DATA(nid)->node_id = nid;
+	NODE_DATA(nid)->node_start_pfn = start >> PAGE_SHIFT;
+	NODE_DATA(nid)->node_spanned_pages = (end - start) >> PAGE_SHIFT;
+
+	node_set_online(nid);
+}
+
+/*
+ * Set nodes, which have memory in @mi, in *@nodemask.
+ */
+static void __init numa_nodemask_from_meminfo(nodemask_t *nodemask,
+					      const struct numa_meminfo *mi)
+{
+	int i;
+
+	for (i = 0; i < ARRAY_SIZE(mi->blk); i++)
+		if (mi->blk[i].start != mi->blk[i].end &&
+		    mi->blk[i].nid != NUMA_NO_NODE)
+			node_set(mi->blk[i].nid, *nodemask);
+}
+
+/*
+ * Sanity check to catch more bad NUMA configurations (they are amazingly
+ * common).  Make sure the nodes cover all memory.
+ */
+static bool __init numa_meminfo_cover_memory(const struct numa_meminfo *mi)
+{
+	u64 numaram, totalram;
+	int i;
+
+	numaram = 0;
+	for (i = 0; i < mi->nr_blks; i++) {
+		u64 s = mi->blk[i].start >> PAGE_SHIFT;
+		u64 e = mi->blk[i].end >> PAGE_SHIFT;
+
+		numaram += e - s;
+		numaram -= __absent_pages_in_range(mi->blk[i].nid, s, e);
+		if ((s64)numaram < 0)
+			numaram = 0;
+	}
+
+	totalram = max_pfn - absent_pages_in_range(0, max_pfn);
+
+	/* We seem to lose 3 pages somewhere. Allow 1M of slack. */
+	if ((s64)(totalram - numaram) >= (1 << (20 - PAGE_SHIFT))) {
+		pr_err("NUMA: nodes only cover %lluMB of your %lluMB Total RAM. Not used.\n",
+		       (numaram << PAGE_SHIFT) >> 20,
+		       (totalram << PAGE_SHIFT) >> 20);
+		return false;
+	}
+	return true;
+}
+
+/**
+ * numa_reset_distance - Reset NUMA distance table
+ *
+ * The current table is freed.  The next numa_set_distance() call will
+ * create a new one.
+ */
+void __init numa_reset_distance(void)
+{
+	size_t size = numa_distance_cnt * numa_distance_cnt *
+		sizeof(numa_distance[0]);
+
+	/* numa_distance could be 1LU marking allocation failure, test cnt */
+	if (numa_distance_cnt)
+		memblock_free(__pa(numa_distance), size);
+	numa_distance_cnt = 0;
+	numa_distance = NULL;	/* enable table creation */
+}
+
+static int __init numa_alloc_distance(void)
+{
+	nodemask_t nodes_parsed;
+	size_t size;
+	int i, j, cnt = 0;
+	u64 phys;
+
+	/* size the new table and allocate it */
+	nodes_parsed = numa_nodes_parsed;
+	numa_nodemask_from_meminfo(&nodes_parsed, &numa_meminfo);
+
+	for_each_node_mask(i, nodes_parsed)
+		cnt = i;
+	cnt++;
+	size = cnt * cnt * sizeof(numa_distance[0]);
+
+	phys = memblock_find_in_range(0, PFN_PHYS(max_pfn),
+				      size, PAGE_SIZE);
+	if (!phys) {
+		pr_warn("NUMA: Warning: can't allocate distance table!\n");
+		/* don't retry until explicitly reset */
+		numa_distance = (void *)1LU;
+		return -ENOMEM;
+	}
+	memblock_reserve(phys, size);
+
+	numa_distance = __va(phys);
+	numa_distance_cnt = cnt;
+
+	/* fill with the default distances */
+	for (i = 0; i < cnt; i++)
+		for (j = 0; j < cnt; j++)
+			numa_distance[i * cnt + j] = i == j ?
+				LOCAL_DISTANCE : REMOTE_DISTANCE;
+	pr_debug("NUMA: Initialized distance table, cnt=%d\n", cnt);
+
+	return 0;
+}
+
+/**
+ * numa_set_distance - Set NUMA distance from one NUMA to another
+ * @from: the 'from' node to set distance
+ * @to: the 'to'  node to set distance
+ * @distance: NUMA distance
+ *
+ * Set the distance from node @from to @to to @distance.  If distance table
+ * doesn't exist, one which is large enough to accommodate all the currently
+ * known nodes will be created.
+ *
+ * If such table cannot be allocated, a warning is printed and further
+ * calls are ignored until the distance table is reset with
+ * numa_reset_distance().
+ *
+ * If @from or @to is higher than the highest known node or lower than zero
+ * at the time of table creation or @distance doesn't make sense, the call
+ * is ignored.
+ * This is to allow simplification of specific NUMA config implementations.
+ */
+void __init numa_set_distance(int from, int to, int distance)
+{
+	if (!numa_distance && numa_alloc_distance() < 0)
+		return;
+
+	if (from >= numa_distance_cnt || to >= numa_distance_cnt ||
+			from < 0 || to < 0) {
+		pr_warn_once("NUMA: Warning: node ids are out of bound, from=%d to=%d distance=%d\n",
+			    from, to, distance);
+		return;
+	}
+
+	if ((u8)distance != distance ||
+	    (from == to && distance != LOCAL_DISTANCE)) {
+		pr_warn_once("NUMA: Warning: invalid distance parameter, from=%d to=%d distance=%d\n",
+			     from, to, distance);
+		return;
+	}
+
+	numa_distance[from * numa_distance_cnt + to] = distance;
+}
+EXPORT_SYMBOL(numa_set_distance);
+
+int __node_distance(int from, int to)
+{
+	if (from >= numa_distance_cnt || to >= numa_distance_cnt)
+		return from == to ? LOCAL_DISTANCE : REMOTE_DISTANCE;
+	return numa_distance[from * numa_distance_cnt + to];
+}
+EXPORT_SYMBOL(__node_distance);
+
+static int __init numa_register_memblks(struct numa_meminfo *mi)
+{
+	unsigned long uninitialized_var(pfn_align);
+	int i, nid;
+
+	/* Account for nodes with cpus and no memory */
+	node_possible_map = numa_nodes_parsed;
+	numa_nodemask_from_meminfo(&node_possible_map, mi);
+	if (WARN_ON(nodes_empty(node_possible_map)))
+		return -EINVAL;
+
+	for (i = 0; i < mi->nr_blks; i++) {
+		struct numa_memblk *mb = &mi->blk[i];
+
+		memblock_set_node(mb->start, mb->end - mb->start,
+				  &memblock.memory, mb->nid);
+	}
+
+	/*
+	 * If sections array is gonna be used for pfn -> nid mapping, check
+	 * whether its granularity is fine enough.
+	 */
+#ifdef NODE_NOT_IN_PAGE_FLAGS
+	pfn_align = node_map_pfn_alignment();
+	if (pfn_align && pfn_align < PAGES_PER_SECTION) {
+		pr_warn("Node alignment %lluMB < min %lluMB, rejecting NUMA config\n",
+		       PFN_PHYS(pfn_align) >> 20,
+		       PFN_PHYS(PAGES_PER_SECTION) >> 20);
+		return -EINVAL;
+	}
+#endif
+	if (!numa_meminfo_cover_memory(mi))
+		return -EINVAL;
+
+	/* Finally register nodes. */
+	for_each_node_mask(nid, node_possible_map) {
+		u64 start = PFN_PHYS(max_pfn);
+		u64 end = 0;
+
+		for (i = 0; i < mi->nr_blks; i++) {
+			if (nid != mi->blk[i].nid)
+				continue;
+			start = min(mi->blk[i].start, start);
+			end = max(mi->blk[i].end, end);
+		}
+
+		if (start < end)
+			setup_node_data(nid, start, end);
+	}
+
+	/* Dump memblock with node info and return. */
+	memblock_dump_all();
+	return 0;
+}
+
+static int __init numa_init(int (*init_func)(void))
+{
+	int ret, i;
+
+	nodes_clear(numa_nodes_parsed);
+	nodes_clear(node_possible_map);
+	nodes_clear(node_online_map);
+
+	ret = init_func();
+	if (ret < 0)
+		return ret;
+
+	ret = numa_register_memblks(&numa_meminfo);
+	if (ret < 0)
+		return ret;
+
+	for (i = 0; i < nr_cpu_ids; i++)
+		numa_clear_node(i);
+
+	setup_node_to_cpumask_map();
+	build_cpu_to_node_map();
+	return 0;
+}
+
+/**
+ * dummy_numa_init - Fallback dummy NUMA init
+ *
+ * Used if there's no underlying NUMA architecture, NUMA initialization
+ * fails, or NUMA is disabled on the command line.
+ *
+ * Must online at least one node and add memory blocks that cover all
+ * allowed memory.  This function must not fail.
+ */
+static int __init dummy_numa_init(void)
+{
+	pr_info("%s\n", "No NUMA configuration found");
+	pr_info("Faking a node at [mem %#018Lx-%#018Lx]\n",
+	       0LLU, PFN_PHYS(max_pfn) - 1);
+	node_set(0, numa_nodes_parsed);
+	numa_add_memblk(0, 0, PFN_PHYS(max_pfn));
+	dummy_numa_enabled = 1;
+
+	return 0;
+}
+
+/**
+ * arm64_numa_init - Initialize NUMA
+ *
+ * Try each configured NUMA initialization method until one succeeds.  The
+ * last fallback is dummy single node config encomapssing whole memory and
+ * never fails.
+ */
+void __init arm64_numa_init(void)
+{
+	numa_init(dummy_numa_init);
+}
-- 
1.8.1.4



From gkulkarni at caviumnetworks.com  Fri Aug 14 09:39:33 2015
From: gkulkarni at caviumnetworks.com (Ganapatrao Kulkarni)
Date: Fri, 14 Aug 2015 22:09:33 +0530
Subject: [PATCH v5 3/4] arm64, numa,
 dt: adding dt based numa support using dt node property arm, associativity
In-Reply-To: <1439570374-4079-1-git-send-email-gkulkarni@caviumnetworks.com>
References: <1439570374-4079-1-git-send-email-gkulkarni@caviumnetworks.com>
Message-ID: <1439570374-4079-4-git-send-email-gkulkarni@caviumnetworks.com>

Adding dt node pasring for numa topology using property arm,associativity.
arm,associativity property can be used to map memory, cpu and
io devices to numa node.

Signed-off-by: Ganapatrao Kulkarni <gkulkarni at caviumnetworks.com>
---
 arch/arm64/Kconfig            |   6 +
 arch/arm64/include/asm/numa.h |   7 +
 arch/arm64/kernel/Makefile    |   1 +
 arch/arm64/kernel/dt_numa.c   | 316 ++++++++++++++++++++++++++++++++++++++++++
 arch/arm64/kernel/smp.c       |   1 +
 arch/arm64/mm/numa.c          |  13 ++
 6 files changed, 344 insertions(+)
 create mode 100644 arch/arm64/kernel/dt_numa.c

diff --git a/arch/arm64/Kconfig b/arch/arm64/Kconfig
index fa37a5d..ca0f701 100644
--- a/arch/arm64/Kconfig
+++ b/arch/arm64/Kconfig
@@ -571,6 +571,12 @@ config NUMA
 	  local memory controller of the CPU and add some more
 	  NUMA awareness to the kernel.
 
+config ARM64_DT_NUMA
+	bool "Device Tree NUMA support"
+	depends on NUMA
+	help
+	  Enable Device Tree NUMA support.
+
 config NODES_SHIFT
 	int "Maximum NUMA Nodes (as a power of 2)"
 	range 1 10
diff --git a/arch/arm64/include/asm/numa.h b/arch/arm64/include/asm/numa.h
index 59b834e..40c0997 100644
--- a/arch/arm64/include/asm/numa.h
+++ b/arch/arm64/include/asm/numa.h
@@ -33,10 +33,17 @@ int __init numa_add_memblk(u32 nodeid, u64 start, u64 end);
 void numa_store_cpu_info(int cpu);
 void __init build_cpu_to_node_map(void);
 void __init numa_set_distance(int from, int to, int distance);
+#if defined(CONFIG_ARM64_DT_NUMA)
+void __init dt_numa_set_node_info(u32 cpu, u64 hwid, void *dn);
+#else
+static inline void dt_numa_set_node_info(u32 cpu, u64 hwid, void *dn) { }
+#endif
+int __init arm64_dt_numa_init(void);
 #else	/* CONFIG_NUMA */
 static inline void numa_store_cpu_info(int cpu)		{ }
 static inline void arm64_numa_init(void)		{ }
 static inline void build_cpu_to_node_map(void) { }
 static inline void numa_set_distance(int from, int to, int distance) { }
+static inline void dt_numa_set_node_info(u32 cpu, u64 hwid, void *dn) { }
 #endif	/* CONFIG_NUMA */
 #endif	/* _ASM_NUMA_H */
diff --git a/arch/arm64/kernel/Makefile b/arch/arm64/kernel/Makefile
index 9add37b..bc7954b 100644
--- a/arch/arm64/kernel/Makefile
+++ b/arch/arm64/kernel/Makefile
@@ -37,6 +37,7 @@ arm64-obj-$(CONFIG_PCI)			+= pci.o
 arm64-obj-$(CONFIG_ARMV8_DEPRECATED)	+= armv8_deprecated.o
 arm64-obj-$(CONFIG_ACPI)		+= pci-acpi.o
 arm64-obj-$(CONFIG_ACPI)		+= acpi.o
+arm64-obj-$(CONFIG_ARM64_DT_NUMA)	+= dt_numa.o
 
 obj-y					+= $(arm64-obj-y) vdso/
 obj-m					+= $(arm64-obj-m)
diff --git a/arch/arm64/kernel/dt_numa.c b/arch/arm64/kernel/dt_numa.c
new file mode 100644
index 0000000..02b0a57
--- /dev/null
+++ b/arch/arm64/kernel/dt_numa.c
@@ -0,0 +1,316 @@
+/*
+ * DT NUMA Parsing support, based on the powerpc implementation.
+ *
+ * Copyright (C) 2015 Cavium Inc.
+ * Author: Ganapatrao Kulkarni <gkulkarni at cavium.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.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program.  If not, see <http://www.gnu.org/licenses/>.
+ */
+
+#include <linux/kernel.h>
+#include <linux/mm.h>
+#include <linux/string.h>
+#include <linux/init.h>
+#include <linux/bootmem.h>
+#include <linux/memblock.h>
+#include <linux/ctype.h>
+#include <linux/module.h>
+#include <linux/nodemask.h>
+#include <linux/sched.h>
+#include <linux/of.h>
+#include <linux/of_fdt.h>
+#include <asm/smp_plat.h>
+
+#define MAX_DISTANCE_REF_POINTS 8
+static int min_common_depth;
+static int distance_ref_points_depth;
+static const __be32 *distance_ref_points;
+static int distance_lookup_table[MAX_NUMNODES][MAX_DISTANCE_REF_POINTS];
+static int default_nid;
+static int of_node_to_nid_single(struct device_node *device);
+static struct device_node *of_cpu_to_node(int cpu);
+
+static void initialize_distance_lookup_table(int nid,
+		const __be32 *associativity)
+{
+	int i;
+
+	for (i = 0; i < distance_ref_points_depth; i++) {
+		const __be32 *entry;
+
+		entry = &associativity[be32_to_cpu(distance_ref_points[i])];
+		distance_lookup_table[nid][i] = of_read_number(entry, 1);
+	}
+}
+
+/* must hold reference to node during call */
+static const __be32 *of_get_associativity(struct device_node *dev)
+{
+	return of_get_property(dev, "arm,associativity", NULL);
+}
+
+/* Returns nid in the range [0..MAX_NUMNODES-1], or -1 if no useful numa
+ * info is found.
+ */
+static int associativity_to_nid(const __be32 *associativity)
+{
+	int nid = NUMA_NO_NODE;
+
+	if (min_common_depth == -1)
+		goto out;
+
+	if (of_read_number(associativity, 1) >= min_common_depth)
+		nid = of_read_number(&associativity[min_common_depth], 1);
+
+	/* set 0xffff as invalid node */
+	if (nid == 0xffff || nid >= MAX_NUMNODES)
+		nid = NUMA_NO_NODE;
+
+	if (nid != NUMA_NO_NODE)
+		initialize_distance_lookup_table(nid, associativity);
+out:
+	return nid;
+}
+
+/* Returns the nid associated with the given device tree node,
+ * or -1 if not found.
+ */
+static int of_node_to_nid_single(struct device_node *device)
+{
+	int nid = default_nid;
+	const __be32 *tmp;
+
+	tmp = of_get_associativity(device);
+	if (tmp)
+		nid = associativity_to_nid(tmp);
+	return nid;
+}
+
+/* Walk the device tree upwards, looking for an associativity id */
+int of_node_to_nid(struct device_node *device)
+{
+	struct device_node *tmp;
+	int nid = NUMA_NO_NODE;
+
+	of_node_get(device);
+	while (device) {
+		nid = of_node_to_nid_single(device);
+		if (nid != NUMA_NO_NODE)
+			break;
+
+		tmp = device;
+		device = of_get_parent(tmp);
+		of_node_put(tmp);
+	}
+	of_node_put(device);
+
+	return nid;
+}
+
+static int __init find_min_common_depth(unsigned long node)
+{
+	int depth;
+	const __be32 *numa_prop;
+	int nr_address_cells;
+
+	/*
+	 * This property is a set of 32-bit integers, each representing
+	 * an index into the arm,associativity nodes.
+	 *
+	 * With form 1 affinity the first integer is the most significant
+	 * NUMA boundary and the following are progressively less significant
+	 * boundaries. There can be more than one level of NUMA.
+	 */
+
+	distance_ref_points = of_get_flat_dt_prop(node,
+			"arm,associativity-reference-points",
+			&distance_ref_points_depth);
+	numa_prop = distance_ref_points;
+
+	if (numa_prop) {
+		nr_address_cells = dt_mem_next_cell(
+				OF_ROOT_NODE_ADDR_CELLS_DEFAULT, &numa_prop);
+		nr_address_cells = dt_mem_next_cell(
+				OF_ROOT_NODE_ADDR_CELLS_DEFAULT, &numa_prop);
+	}
+	if (!distance_ref_points) {
+		pr_debug("NUMA: arm,associativity-reference-points not found.\n");
+		goto err;
+	}
+
+	distance_ref_points_depth /= sizeof(__be32);
+
+	if (!distance_ref_points_depth) {
+		pr_err("NUMA: missing arm,associativity-reference-points\n");
+		goto err;
+	}
+	depth = of_read_number(distance_ref_points, 1);
+
+	/*
+	 * Warn and cap if the hardware supports more than
+	 * MAX_DISTANCE_REF_POINTS domains.
+	 */
+	if (distance_ref_points_depth > MAX_DISTANCE_REF_POINTS) {
+		pr_debug("NUMA: distance array capped at %d entries\n",
+				MAX_DISTANCE_REF_POINTS);
+		distance_ref_points_depth = MAX_DISTANCE_REF_POINTS;
+	}
+
+	return depth;
+err:
+	return -1;
+}
+
+void __init dt_numa_set_node_info(u32 cpu, u64 hwid,  void *dn_ptr)
+{
+	struct device_node *dn = (struct device_node *) dn_ptr;
+	int nid = default_nid;
+
+	if (dn)
+		nid = of_node_to_nid_single(dn);
+
+	node_cpu_hwid[cpu].node_id = nid;
+	node_cpu_hwid[cpu].cpu_hwid = hwid;
+	node_set(nid, numa_nodes_parsed);
+}
+
+int dt_get_cpu_node_id(int cpu)
+{
+	struct device_node *dn = NULL;
+	int nid = default_nid;
+
+	dn =  of_cpu_to_node(cpu);
+	if (dn)
+		nid = of_node_to_nid_single(dn);
+	return nid;
+}
+
+static struct device_node *of_cpu_to_node(int cpu)
+{
+	struct device_node *dn = NULL;
+
+	while ((dn = of_find_node_by_type(dn, "cpu"))) {
+		const u32 *cell;
+		u64 hwid;
+
+		/*
+		 * A cpu node with missing "reg" property is
+		 * considered invalid to build a cpu_logical_map
+		 * entry.
+		 */
+		cell = of_get_property(dn, "reg", NULL);
+		if (!cell) {
+			pr_err("%s: missing reg property\n", dn->full_name);
+			return NULL;
+		}
+		hwid = of_read_number(cell, of_n_addr_cells(dn));
+
+		if (cpu_logical_map(cpu) == hwid)
+			return dn;
+	}
+	return NULL;
+}
+
+static int __init parse_memory_node(unsigned long node)
+{
+	const __be32 *reg, *endp, *associativity;
+	int length;
+	int nid = default_nid;
+
+	associativity = of_get_flat_dt_prop(node, "arm,associativity", &length);
+
+	if (associativity)
+		nid = associativity_to_nid(associativity);
+
+	reg = of_get_flat_dt_prop(node, "reg", &length);
+	endp = reg + (length / sizeof(__be32));
+
+	while ((endp - reg) >= (dt_root_addr_cells + dt_root_size_cells)) {
+		u64 base, size;
+		struct memblock_region *mblk;
+
+		base = dt_mem_next_cell(dt_root_addr_cells, &reg);
+		size = dt_mem_next_cell(dt_root_size_cells, &reg);
+		pr_debug("NUMA-DT:  base = %llx , node = %u\n",
+				base, nid);
+		for_each_memblock(memory, mblk) {
+			if (mblk->base == base) {
+				node_set(nid, numa_nodes_parsed);
+				numa_add_memblk(nid, mblk->base, mblk->size);
+				break;
+			}
+		}
+	}
+
+	return 0;
+}
+
+/**
+ * early_init_dt_scan_numa_map - parse memory node and map nid to memory range.
+ */
+int __init early_init_dt_scan_numa_map(unsigned long node, const char *uname,
+				     int depth, void *data)
+{
+	const char *type = of_get_flat_dt_prop(node, "device_type", NULL);
+
+	if (depth == 0) {
+		min_common_depth = find_min_common_depth(node);
+		if (min_common_depth < 0)
+			return min_common_depth;
+		pr_debug("NUMA associativity depth for CPU/Memory: %d\n",
+				min_common_depth);
+		return 0;
+	}
+
+	if (type) {
+		if (strcmp(type, "memory") == 0)
+			parse_memory_node(node);
+	}
+	return 0;
+}
+
+int dt_get_node_distance(int a, int b)
+{
+	int i;
+	int distance = LOCAL_DISTANCE;
+
+	for (i = 0; i < distance_ref_points_depth; i++) {
+		if (distance_lookup_table[a][i] == distance_lookup_table[b][i])
+			break;
+
+		/* Double the distance for each NUMA level */
+		distance *= 2;
+	}
+	return distance;
+}
+
+/* DT node mapping is done already early_init_dt_scan_memory */
+int __init arm64_dt_numa_init(void)
+{
+	int i;
+	u32 nodea, nodeb, distance, node_count = 0;
+
+	of_scan_flat_dt(early_init_dt_scan_numa_map, NULL);
+
+	for_each_node_mask(i, numa_nodes_parsed)
+		node_count = i;
+	node_count++;
+
+	for (nodea =  0; nodea < node_count; nodea++) {
+		for (nodeb = 0; nodeb < node_count; nodeb++) {
+			distance = dt_get_node_distance(nodea, nodeb);
+			numa_set_distance(nodea, nodeb, distance);
+		}
+	}
+	return 0;
+}
diff --git a/arch/arm64/kernel/smp.c b/arch/arm64/kernel/smp.c
index ae3e02c..bdf0358 100644
--- a/arch/arm64/kernel/smp.c
+++ b/arch/arm64/kernel/smp.c
@@ -503,6 +503,7 @@ void __init of_parse_and_init_cpus(void)
 
 		pr_debug("cpu logical map 0x%llx\n", hwid);
 		cpu_logical_map(cpu_count) = hwid;
+		dt_numa_set_node_info(cpu_count, hwid, (void *)dn);
 next:
 		cpu_count++;
 	}
diff --git a/arch/arm64/mm/numa.c b/arch/arm64/mm/numa.c
index 2be83de..0c879eb 100644
--- a/arch/arm64/mm/numa.c
+++ b/arch/arm64/mm/numa.c
@@ -28,6 +28,7 @@
 #include <linux/nodemask.h>
 #include <linux/sched.h>
 #include <linux/topology.h>
+#include <linux/of.h>
 #include <linux/mmzone.h>
 
 #include <asm/smp_plat.h>
@@ -546,5 +547,17 @@ static int __init dummy_numa_init(void)
  */
 void __init arm64_numa_init(void)
 {
+	int (*init_func)(void);
+
+	if (IS_ENABLED(CONFIG_ARM64_DT_NUMA))
+		init_func = arm64_dt_numa_init;
+	else
+		init_func = NULL;
+
+	if (!numa_off && init_func) {
+		if (!numa_init(init_func))
+			return;
+	}
+
 	numa_init(dummy_numa_init);
 }
-- 
1.8.1.4



From will.deacon at arm.com  Fri Aug 14 09:43:25 2015
From: will.deacon at arm.com (Will Deacon)
Date: Fri, 14 Aug 2015 17:43:25 +0100
Subject: [PATCH v2 2/4] PCI: pci-host-generic: Fix lookup of
 linux,pci-probe-only property
In-Reply-To: <20150814164051.GF26431@google.com>
References: <1439569159-10051-1-git-send-email-marc.zyngier@arm.com>
 <1439569159-10051-3-git-send-email-marc.zyngier@arm.com>
 <20150814164051.GF26431@google.com>
Message-ID: <20150814164324.GC22809@arm.com>

On Fri, Aug 14, 2015 at 05:40:51PM +0100, Bjorn Helgaas wrote:
> On Fri, Aug 14, 2015 at 05:19:17PM +0100, Marc Zyngier wrote:
> > When pci-host-generic looks for the probe-only property, it seems
> > to trust the DT to be correctly written, and assumes that there
> > is a parameter to the property.
> > 
> > Unfortunately, this is not always the case, and some firmware expose
> > this property naked. The driver ends up making a decision based on
> > whatever the property pointer points to, which is likely to be junk.
> > 
> > Switch to the common of_pci.c implementation that doesn't suffer
> > from this problem.
> > 
> > Signed-off-by: Marc Zyngier <marc.zyngier at arm.com>
> > ---
> >  drivers/pci/host/pci-host-generic.c | 9 +--------
> >  1 file changed, 1 insertion(+), 8 deletions(-)
> > 
> > diff --git a/drivers/pci/host/pci-host-generic.c b/drivers/pci/host/pci-host-generic.c
> > index 265dd25..545ff4e 100644
> > --- a/drivers/pci/host/pci-host-generic.c
> > +++ b/drivers/pci/host/pci-host-generic.c
> > @@ -210,7 +210,6 @@ static int gen_pci_probe(struct platform_device *pdev)
> >  	int err;
> >  	const char *type;
> >  	const struct of_device_id *of_id;
> > -	const int *prop;
> >  	struct device *dev = &pdev->dev;
> >  	struct device_node *np = dev->of_node;
> >  	struct gen_pci *pci = devm_kzalloc(dev, sizeof(*pci), GFP_KERNEL);
> > @@ -225,13 +224,7 @@ static int gen_pci_probe(struct platform_device *pdev)
> >  		return -EINVAL;
> >  	}
> >  
> > -	prop = of_get_property(of_chosen, "linux,pci-probe-only", NULL);
> > -	if (prop) {
> > -		if (*prop)
> > -			pci_add_flags(PCI_PROBE_ONLY);
> > -		else
> > -			pci_clear_flags(PCI_PROBE_ONLY);
> > -	}
> > +	of_pci_check_probe_only(of_chosen);
> 
> Do we need support for pci-probe-only in pci-host-generic at all?
> You're removing the use in amd-overdrive.dts, and there are no other
> DTs in the kernel tree that mention it.
> 
> If we can live without it, that would be nice.  It seems like a relic from
> days when we couldn't reliably assign resources.  (I'm not saying we can do
> that reliably even today, but I'd rather make it reliable than turn it
> off.)

Kvmtool certainly uses it (and generates its own DT, hence why you don't
see it in mainline). Not sure about qemu, though.

Will


From gpkulkarni at gmail.com  Fri Aug 14 09:44:27 2015
From: gpkulkarni at gmail.com (Ganapatrao Kulkarni)
Date: Fri, 14 Aug 2015 22:14:27 +0530
Subject: [PATCH v5 0/8] arm64, numa: Add numa support for arm64 platforms.
In-Reply-To: <1439570374-4079-1-git-send-email-gkulkarni@caviumnetworks.com>
References: <1439570374-4079-1-git-send-email-gkulkarni@caviumnetworks.com>
Message-ID: <CAFpQJXXXFmWE5rk9=KW_Vg0B9aA+Cd_6YQOeiCZ21Q61cSQ+ew@mail.gmail.com>

On Fri, Aug 14, 2015 at 10:09 PM, Ganapatrao Kulkarni
<gkulkarni at caviumnetworks.com> wrote:
> v5:
>         - created base verion of numa.c which creates dummy numa without using dt
>           on single socket platforms. Then added patches for dt support.
>         - Incorporated review comments from Hanjun Guo.
>
> v4:
> done changes as per Arnd review comments.
>
> v3:
> Added changes to support numa on arm64 based platforms.
> Tested these patches on cavium's multinode(2 node topology) platform.
> In this patchset, defined and implemented dt bindings for numa mapping
> for core and memory using device node property arm,associativity.
>
> v2:
> Defined and implemented numa map for memory, cores to node and
> proximity distance matrix of nodes.
>
> v1:
> Initial patchset to support numa on arm64 platforms.
>
> Note:
>         1. This patchset is tested for numa with dt on
>            thunderx single socket and dual socket boards.
>         2. Numa DT booting needs the dt memory nodes, which are deleted in current efi-stub,
>         hence to try numa with dt, you need to rebase with ard's patchset.
>         http://git.linaro.org/people/ard.biesheuvel/linux-arm.git/shortlog/refs/heads/arm64-uefi-early-fdt-handling
>
>
> Ganapatrao Kulkarni (4):
>   arm64, numa: adding numa support for arm64 platforms.
>   Documentation: arm64/arm: dt bindings for numa.
>   arm64, numa: adding numa support for arm64 platforms.
>   arm64, dt, thunderx: Add initial dts for Cavium Thunder SoC in 2 Node
>     topology.
>
>  Documentation/devicetree/bindings/arm/numa.txt  | 212 +++++++
>  arch/arm64/Kconfig                              |  32 +
>  arch/arm64/boot/dts/cavium/Makefile             |   2 +-
>  arch/arm64/boot/dts/cavium/thunder-88xx-2n.dts  |  78 +++
>  arch/arm64/boot/dts/cavium/thunder-88xx-2n.dtsi | 790 ++++++++++++++++++++++++
>  arch/arm64/include/asm/mmzone.h                 |  32 +
>  arch/arm64/include/asm/numa.h                   |  49 ++
>  arch/arm64/kernel/Makefile                      |   1 +
>  arch/arm64/kernel/dt_numa.c                     | 316 ++++++++++
>  arch/arm64/kernel/setup.c                       |   9 +
>  arch/arm64/kernel/smp.c                         |   3 +
>  arch/arm64/mm/Makefile                          |   1 +
>  arch/arm64/mm/init.c                            |  34 +-
>  arch/arm64/mm/numa.c                            | 563 +++++++++++++++++
>  14 files changed, 2115 insertions(+), 7 deletions(-)
>  create mode 100644 Documentation/devicetree/bindings/arm/numa.txt
>  create mode 100644 arch/arm64/boot/dts/cavium/thunder-88xx-2n.dts
>  create mode 100644 arch/arm64/boot/dts/cavium/thunder-88xx-2n.dtsi
>  create mode 100644 arch/arm64/include/asm/mmzone.h
>  create mode 100644 arch/arm64/include/asm/numa.h
>  create mode 100644 arch/arm64/kernel/dt_numa.c
>  create mode 100644 arch/arm64/mm/numa.c
>
> --
> 1.8.1.4
>
sorry, minor correction, this patchset has 4 patches.

PATCH v5 0/8 => PATCH v5 0/4


From will.deacon at arm.com  Fri Aug 14 09:45:12 2015
From: will.deacon at arm.com (Will Deacon)
Date: Fri, 14 Aug 2015 17:45:12 +0100
Subject: [PATCH v2 2/4] PCI: pci-host-generic: Fix lookup of
 linux,pci-probe-only property
In-Reply-To: <1439569159-10051-3-git-send-email-marc.zyngier@arm.com>
References: <1439569159-10051-1-git-send-email-marc.zyngier@arm.com>
 <1439569159-10051-3-git-send-email-marc.zyngier@arm.com>
Message-ID: <20150814164512.GD22809@arm.com>

On Fri, Aug 14, 2015 at 05:19:17PM +0100, Marc Zyngier wrote:
> When pci-host-generic looks for the probe-only property, it seems
> to trust the DT to be correctly written, and assumes that there
> is a parameter to the property.
> 
> Unfortunately, this is not always the case, and some firmware expose
> this property naked. The driver ends up making a decision based on
> whatever the property pointer points to, which is likely to be junk.
> 
> Switch to the common of_pci.c implementation that doesn't suffer
> from this problem.
> 
> Signed-off-by: Marc Zyngier <marc.zyngier at arm.com>
> ---
>  drivers/pci/host/pci-host-generic.c | 9 +--------
>  1 file changed, 1 insertion(+), 8 deletions(-)
> 
> diff --git a/drivers/pci/host/pci-host-generic.c b/drivers/pci/host/pci-host-generic.c
> index 265dd25..545ff4e 100644
> --- a/drivers/pci/host/pci-host-generic.c
> +++ b/drivers/pci/host/pci-host-generic.c
> @@ -210,7 +210,6 @@ static int gen_pci_probe(struct platform_device *pdev)
>  	int err;
>  	const char *type;
>  	const struct of_device_id *of_id;
> -	const int *prop;
>  	struct device *dev = &pdev->dev;
>  	struct device_node *np = dev->of_node;
>  	struct gen_pci *pci = devm_kzalloc(dev, sizeof(*pci), GFP_KERNEL);
> @@ -225,13 +224,7 @@ static int gen_pci_probe(struct platform_device *pdev)
>  		return -EINVAL;
>  	}
>  
> -	prop = of_get_property(of_chosen, "linux,pci-probe-only", NULL);
> -	if (prop) {
> -		if (*prop)
> -			pci_add_flags(PCI_PROBE_ONLY);
> -		else
> -			pci_clear_flags(PCI_PROBE_ONLY);
> -	}
> +	of_pci_check_probe_only(of_chosen);

You could probably just make this take void, as the probe-only property
is always in the /chosen node.

Either way:

  Acked-by: Will Deacon <will.deacon at arm.com>

Will


From agraf at suse.de  Fri Aug 14 09:50:54 2015
From: agraf at suse.de (Alexander Graf)
Date: Fri, 14 Aug 2015 09:50:54 -0700
Subject: [PATCH v2 2/4] PCI: pci-host-generic: Fix lookup of linux,
 pci-probe-only property
In-Reply-To: <20150814164324.GC22809@arm.com>
References: <1439569159-10051-1-git-send-email-marc.zyngier@arm.com>
 <1439569159-10051-3-git-send-email-marc.zyngier@arm.com>
 <20150814164051.GF26431@google.com> <20150814164324.GC22809@arm.com>
Message-ID: <EA13B7D9-D612-4957-AF64-6B0BA0DFE06F@suse.de>


> On 14.08.2015, at 09:43, Will Deacon <will.deacon at arm.com> wrote:
> 
> On Fri, Aug 14, 2015 at 05:40:51PM +0100, Bjorn Helgaas wrote:
>> On Fri, Aug 14, 2015 at 05:19:17PM +0100, Marc Zyngier wrote:
>>> When pci-host-generic looks for the probe-only property, it seems
>>> to trust the DT to be correctly written, and assumes that there
>>> is a parameter to the property.
>>> 
>>> Unfortunately, this is not always the case, and some firmware expose
>>> this property naked. The driver ends up making a decision based on
>>> whatever the property pointer points to, which is likely to be junk.
>>> 
>>> Switch to the common of_pci.c implementation that doesn't suffer
>>> from this problem.
>>> 
>>> Signed-off-by: Marc Zyngier <marc.zyngier at arm.com>
>>> ---
>>> drivers/pci/host/pci-host-generic.c | 9 +--------
>>> 1 file changed, 1 insertion(+), 8 deletions(-)
>>> 
>>> diff --git a/drivers/pci/host/pci-host-generic.c b/drivers/pci/host/pci-host-generic.c
>>> index 265dd25..545ff4e 100644
>>> --- a/drivers/pci/host/pci-host-generic.c
>>> +++ b/drivers/pci/host/pci-host-generic.c
>>> @@ -210,7 +210,6 @@ static int gen_pci_probe(struct platform_device *pdev)
>>> 	int err;
>>> 	const char *type;
>>> 	const struct of_device_id *of_id;
>>> -	const int *prop;
>>> 	struct device *dev = &pdev->dev;
>>> 	struct device_node *np = dev->of_node;
>>> 	struct gen_pci *pci = devm_kzalloc(dev, sizeof(*pci), GFP_KERNEL);
>>> @@ -225,13 +224,7 @@ static int gen_pci_probe(struct platform_device *pdev)
>>> 		return -EINVAL;
>>> 	}
>>> 
>>> -	prop = of_get_property(of_chosen, "linux,pci-probe-only", NULL);
>>> -	if (prop) {
>>> -		if (*prop)
>>> -			pci_add_flags(PCI_PROBE_ONLY);
>>> -		else
>>> -			pci_clear_flags(PCI_PROBE_ONLY);
>>> -	}
>>> +	of_pci_check_probe_only(of_chosen);
>> 
>> Do we need support for pci-probe-only in pci-host-generic at all?
>> You're removing the use in amd-overdrive.dts, and there are no other
>> DTs in the kernel tree that mention it.
>> 
>> If we can live without it, that would be nice.  It seems like a relic from
>> days when we couldn't reliably assign resources.  (I'm not saying we can do
>> that reliably even today, but I'd rather make it reliable than turn it
>> off.)
> 
> Kvmtool certainly uses it (and generates its own DT, hence why you don't
> see it in mainline). Not sure about qemu, though.

QEMU definitely doesn't do proble-only. Is this driver used on real PPC machines too? In that case you also won't see the dt, because it comes with the hardware ;).


Alex



From gkulkarni at caviumnetworks.com  Fri Aug 14 09:39:32 2015
From: gkulkarni at caviumnetworks.com (Ganapatrao Kulkarni)
Date: Fri, 14 Aug 2015 22:09:32 +0530
Subject: [PATCH v5 2/4] Documentation: arm64/arm: dt bindings for numa.
In-Reply-To: <1439570374-4079-1-git-send-email-gkulkarni@caviumnetworks.com>
References: <1439570374-4079-1-git-send-email-gkulkarni@caviumnetworks.com>
Message-ID: <1439570374-4079-3-git-send-email-gkulkarni@caviumnetworks.com>

DT bindings for numa map for memory, cores and IOs using
arm,associativity device node property.

Signed-off-by: Ganapatrao Kulkarni <gkulkarni at caviumnetworks.com>
---
 Documentation/devicetree/bindings/arm/numa.txt | 212 +++++++++++++++++++++++++
 1 file changed, 212 insertions(+)
 create mode 100644 Documentation/devicetree/bindings/arm/numa.txt

diff --git a/Documentation/devicetree/bindings/arm/numa.txt b/Documentation/devicetree/bindings/arm/numa.txt
new file mode 100644
index 0000000..dc3ef86
--- /dev/null
+++ b/Documentation/devicetree/bindings/arm/numa.txt
@@ -0,0 +1,212 @@
+==============================================================================
+NUMA binding description.
+==============================================================================
+
+==============================================================================
+1 - Introduction
+==============================================================================
+
+Systems employing a Non Uniform Memory Access (NUMA) architecture contain
+collections of hardware resources including processors, memory, and I/O buses,
+that comprise what is commonly known as a NUMA node.
+Processor accesses to memory within the local NUMA node is generally faster
+than processor accesses to memory outside of the local NUMA node.
+DT defines interfaces that allow the platform to convey NUMA node
+topology information to OS.
+
+==============================================================================
+2 - arm,associativity
+==============================================================================
+The mapping is done using arm,associativity device property.
+this property needs to be present in every device node which needs to to be
+mapped to numa nodes.
+
+arm,associativity property is set of 32-bit integers which defines level of
+topology and boundary in the system at which a significant difference in
+performance can be measured between cross-device accesses within
+a single location and those spanning multiple locations.
+The first cell always contains the broadest subdivision within the system,
+while the last cell enumerates the individual devices, such as an SMT thread
+of a CPU, or a bus bridge within an SoC".
+
+ex:
+	/* board 0, socket 0, cluster 0, core 0  thread 0 */
+	arm,associativity = <0 0 0 0 0>;
+
+==============================================================================
+3 - arm,associativity-reference-points
+==============================================================================
+This property is a set of 32-bit integers, each representing an index into
+the arm,associativity nodes. The first integer is the most significant
+NUMA boundary and the following are progressively less significant boundaries.
+There can be more than one level of NUMA.
+
+Ex:
+	arm,associativity-reference-points = <0 1>;
+	The board Id(index 0) used first to calculate the associativity (node
+	distance), then follows the  socket id(index 1).
+
+	arm,associativity-reference-points = <1 0>;
+	The socket Id(index 1) used first to calculate the associativity,
+	then follows the board id(index 0).
+
+	arm,associativity-reference-points = <0>;
+	Only the board Id(index 0) used to calculate the associativity.
+
+	arm,associativity-reference-points = <1>;
+	Only socket Id(index 1) used to calculate the associativity.
+
+==============================================================================
+4 - Example dts
+==============================================================================
+
+Example: 2 Node system consists of 2 boards and each board having one socket
+and 8 core in each socket.
+
+	arm,associativity-reference-points = <0>;
+
+	memory at 00c00000 {
+		device_type = "memory";
+		reg = <0x0 0x00c00000 0x0 0x80000000>;
+		/* board 0, socket 0, no specific core */
+		arm,associativity = <0 0 0xffff>;
+	};
+
+	memory at 10000000000 {
+		device_type = "memory";
+		reg = <0x100 0x00000000 0x0 0x80000000>;
+		/* board 1, socket 0, no specific core */
+		arm,associativity = <1 0 0xffff>;
+	};
+
+	cpus {
+		#address-cells = <2>;
+		#size-cells = <0>;
+
+		cpu at 000 {
+			device_type = "cpu";
+			compatible =  "arm,armv8";
+			reg = <0x0 0x000>;
+			enable-method = "psci";
+			/* board 0, socket 0, core 0*/
+			arm,associativity = <0 0 0>;
+		};
+		cpu at 001 {
+			device_type = "cpu";
+			compatible =  "arm,armv8";
+			reg = <0x0 0x001>;
+			enable-method = "psci";
+			arm,associativity = <0 0 1>;
+		};
+		cpu at 002 {
+			device_type = "cpu";
+			compatible =  "arm,armv8";
+			reg = <0x0 0x002>;
+			enable-method = "psci";
+			arm,associativity = <0 0 2>;
+		};
+		cpu at 003 {
+			device_type = "cpu";
+			compatible =  "arm,armv8";
+			reg = <0x0 0x003>;
+			enable-method = "psci";
+			arm,associativity = <0 0 3>;
+		};
+		cpu at 004 {
+			device_type = "cpu";
+			compatible =  "arm,armv8";
+			reg = <0x0 0x004>;
+			enable-method = "psci";
+			arm,associativity = <0 0 4>;
+		};
+		cpu at 005 {
+			device_type = "cpu";
+			compatible =  "arm,armv8";
+			reg = <0x0 0x005>;
+			enable-method = "psci";
+			arm,associativity = <0 0 5>;
+		};
+		cpu at 006 {
+			device_type = "cpu";
+			compatible =  "arm,armv8";
+			reg = <0x0 0x006>;
+			enable-method = "psci";
+			arm,associativity = <0 0 6>;
+		};
+		cpu at 007 {
+			device_type = "cpu";
+			compatible =  "arm,armv8";
+			reg = <0x0 0x007>;
+			enable-method = "psci";
+			arm,associativity = <0 0 7>;
+		};
+		cpu at 008 {
+			device_type = "cpu";
+			compatible =  "arm,armv8";
+			reg = <0x0 0x008>;
+			enable-method = "psci";
+			/* board 1, socket 0, core 0*/
+			arm,associativity = <1 0 0>;
+		};
+		cpu at 009 {
+			device_type = "cpu";
+			compatible =  "arm,armv8";
+			reg = <0x0 0x009>;
+			enable-method = "psci";
+			arm,associativity = <1 0 1>;
+		};
+		cpu at 00a {
+			device_type = "cpu";
+			compatible =  "arm,armv8";
+			reg = <0x0 0x00a>;
+			enable-method = "psci";
+			arm,associativity = <0 0 2>;
+		};
+		cpu at 00b {
+			device_type = "cpu";
+			compatible =  "arm,armv8";
+			reg = <0x0 0x00b>;
+			enable-method = "psci";
+			arm,associativity = <1 0 3>;
+		};
+		cpu at 00c {
+			device_type = "cpu";
+			compatible =  "arm,armv8";
+			reg = <0x0 0x00c>;
+			enable-method = "psci";
+			arm,associativity = <1 0 4>;
+		};
+		cpu at 00d {
+			device_type = "cpu";
+			compatible =  "arm,armv8";
+			reg = <0x0 0x00d>;
+			enable-method = "psci";
+			arm,associativity = <1 0 5>;
+		};
+		cpu at 00e {
+			device_type = "cpu";
+			compatible =  "arm,armv8";
+			reg = <0x0 0x00e>;
+			enable-method = "psci";
+			arm,associativity = <1 0 6>;
+		};
+		cpu at 00f {
+			device_type = "cpu";
+			compatible =  "arm,armv8";
+			reg = <0x0 0x00f>;
+			enable-method = "psci";
+			arm,associativity = <1 0 7>;
+		};
+	};
+
+	pcie0: pcie0 at 0x8480,00000000 {
+		compatible = "arm,armv8";
+		device_type = "pci";
+		bus-range = <0 255>;
+		#size-cells = <2>;
+		#address-cells = <3>;
+		reg = <0x8480 0x00000000 0 0x10000000>;  /* Configuration space */
+		ranges = <0x03000000 0x8010 0x00000000 0x8010 0x00000000 0x70 0x00000000>; /* mem ranges */
+		/* board 0, socket 0, pci bus 0*/
+		arm,associativity = <0 0 0>;
+        };
-- 
1.8.1.4



From bhelgaas at google.com  Fri Aug 14 09:40:51 2015
From: bhelgaas at google.com (Bjorn Helgaas)
Date: Fri, 14 Aug 2015 11:40:51 -0500
Subject: [PATCH v2 2/4] PCI: pci-host-generic: Fix lookup of
 linux,pci-probe-only property
In-Reply-To: <1439569159-10051-3-git-send-email-marc.zyngier@arm.com>
References: <1439569159-10051-1-git-send-email-marc.zyngier@arm.com>
 <1439569159-10051-3-git-send-email-marc.zyngier@arm.com>
Message-ID: <20150814164051.GF26431@google.com>

On Fri, Aug 14, 2015 at 05:19:17PM +0100, Marc Zyngier wrote:
> When pci-host-generic looks for the probe-only property, it seems
> to trust the DT to be correctly written, and assumes that there
> is a parameter to the property.
> 
> Unfortunately, this is not always the case, and some firmware expose
> this property naked. The driver ends up making a decision based on
> whatever the property pointer points to, which is likely to be junk.
> 
> Switch to the common of_pci.c implementation that doesn't suffer
> from this problem.
> 
> Signed-off-by: Marc Zyngier <marc.zyngier at arm.com>
> ---
>  drivers/pci/host/pci-host-generic.c | 9 +--------
>  1 file changed, 1 insertion(+), 8 deletions(-)
> 
> diff --git a/drivers/pci/host/pci-host-generic.c b/drivers/pci/host/pci-host-generic.c
> index 265dd25..545ff4e 100644
> --- a/drivers/pci/host/pci-host-generic.c
> +++ b/drivers/pci/host/pci-host-generic.c
> @@ -210,7 +210,6 @@ static int gen_pci_probe(struct platform_device *pdev)
>  	int err;
>  	const char *type;
>  	const struct of_device_id *of_id;
> -	const int *prop;
>  	struct device *dev = &pdev->dev;
>  	struct device_node *np = dev->of_node;
>  	struct gen_pci *pci = devm_kzalloc(dev, sizeof(*pci), GFP_KERNEL);
> @@ -225,13 +224,7 @@ static int gen_pci_probe(struct platform_device *pdev)
>  		return -EINVAL;
>  	}
>  
> -	prop = of_get_property(of_chosen, "linux,pci-probe-only", NULL);
> -	if (prop) {
> -		if (*prop)
> -			pci_add_flags(PCI_PROBE_ONLY);
> -		else
> -			pci_clear_flags(PCI_PROBE_ONLY);
> -	}
> +	of_pci_check_probe_only(of_chosen);

Do we need support for pci-probe-only in pci-host-generic at all?
You're removing the use in amd-overdrive.dts, and there are no other
DTs in the kernel tree that mention it.

If we can live without it, that would be nice.  It seems like a relic from
days when we couldn't reliably assign resources.  (I'm not saying we can do
that reliably even today, but I'd rather make it reliable than turn it
off.)

>  	of_id = of_match_node(gen_pci_of_match, np);
>  	pci->cfg.ops = of_id->data;
> -- 
> 2.1.4
> 


From horia.geanta at freescale.com  Fri Aug 14 10:06:06 2015
From: horia.geanta at freescale.com (=?UTF-8?Q?Horia_Geant=c4=83?=)
Date: Fri, 14 Aug 2015 20:06:06 +0300
Subject: [PATCH v3] ARM: configs: Add Freescale LS1021A defconfig
In-Reply-To: <55CB4829.40204@freescale.com>
References: <1438941784-38403-1-git-send-email-b18965@freescale.com>
 <55CB4829.40204@freescale.com>
Message-ID: <55CE1FFE.2080200@freescale.com>

On 8/12/2015 4:20 PM, Horia Geant? wrote:
> On 8/7/2015 1:03 PM, Alison Wang wrote:
>> Add Freescale LS1021A initial defconfig file.
>> The LS1021A SoC is a dual-core Cortex-A7 based processor.
>>
>> LS1021A has some special configure options against common V7 SOCs,
>> such as CONFIG_THUMB2_KERNEL, CONFIG_VMSPLIT_2G, CONFIG_VFP...
>>
>> Enable I2C, LPUART, eDMA, WDT, GIANFAR, Sound, DSPI at default.
>>
>> Signed-off-by: Haikun Wang <haikun.wang at freescale.com>
>> Signed-off-by: Alison Wang <alison.wang at freescale.com>
>> ---
>> Changes since v2:
>> - Enable PSCI, as PSCI is enabled in u-boot.
>> Changes since v1:
>> - Enable GIANFAR, Sound and DSPI.
> 
> Looks like CONFIG_ARCH_DMA_ADDR_T_64BIT=y is missing.
> For e.g. CAAM (crypto engine) is a DMA device able to use 40-bit bus
> addresses.
> Note that ARCH_DMA_ADDR_T_64BIT does not depend / is not selected by
> ARM_LPAE.

Another thing:
Commit 385c0fb0e2c4 ("ARM: imx_v6_v7_defconfig: Select LS1021A") added
CONFIG_SOC_LS1021A in imx_v6_v7_defconfig.

Besides this, booting a LS1021 AQDS board (Rev2) using
imx_v6_v7_defconfig did not work (stuck at "Starting kernel").

Horia



From b.zolnierkie at samsung.com  Fri Aug 14 10:04:16 2015
From: b.zolnierkie at samsung.com (Bartlomiej Zolnierkiewicz)
Date: Fri, 14 Aug 2015 19:04:16 +0200
Subject: [RFT PATCH] arm: am200epdkit_defconfig: convert to use libata PATA
 drivers
Message-ID: <1439571876-13758-1-git-send-email-b.zolnierkie@samsung.com>

IDE subsystem has been deprecated since 2009 and the majority
(if not all) of Linux distributions have switched to use
libata for ATA support exclusively.  However there are still
some users (mostly old or/and embedded non-x86 systems) that
have not converted from using IDE subsystem to libata PATA
drivers.  This doesn't seem to be good thing in the long-term
for Linux as while there is less and less PATA systems left
in use:

* testing efforts are divided between two subsystems

* having duplicate drivers for same hardware confuses users

This patch converts am200epdkit_defconfig to use libata PATA
drivers.

Cc: Daniel Mack <daniel at zonque.org>
Cc: Haojian Zhuang <haojian.zhuang at gmail.com>
Cc: Robert Jarzmik <robert.jarzmik at free.fr>
Signed-off-by: Bartlomiej Zolnierkiewicz <b.zolnierkie at samsung.com>
---
Build tested only.
If you have affected hardware please test.  Thank you.

 arch/arm/configs/am200epdkit_defconfig | 5 +++--
 1 file changed, 3 insertions(+), 2 deletions(-)

diff --git a/arch/arm/configs/am200epdkit_defconfig b/arch/arm/configs/am200epdkit_defconfig
index f0dea52..113a5d8 100644
--- a/arch/arm/configs/am200epdkit_defconfig
+++ b/arch/arm/configs/am200epdkit_defconfig
@@ -55,8 +55,9 @@ CONFIG_MTD_CFI_INTELEXT=y
 CONFIG_MTD_COMPLEX_MAPPINGS=y
 CONFIG_MTD_PXA2XX=y
 CONFIG_BLK_DEV_LOOP=m
-CONFIG_IDE=m
-CONFIG_BLK_DEV_IDECS=m
+CONFIG_BLK_DEV_SD=m
+CONFIG_ATA=m
+CONFIG_PATA_PCMCIA=m
 CONFIG_NETDEVICES=y
 CONFIG_NET_ETHERNET=y
 CONFIG_SMC91X=m
-- 
1.9.1



From b.zolnierkie at samsung.com  Fri Aug 14 10:04:17 2015
From: b.zolnierkie at samsung.com (Bartlomiej Zolnierkiewicz)
Date: Fri, 14 Aug 2015 19:04:17 +0200
Subject: [PATCH] arm: assabet_defconfig: disable IDE subsystem
In-Reply-To: <1439571876-13758-1-git-send-email-b.zolnierkie@samsung.com>
References: <1439571876-13758-1-git-send-email-b.zolnierkie@samsung.com>
Message-ID: <1439571876-13758-2-git-send-email-b.zolnierkie@samsung.com>

This patch disables deprecated IDE subsystem in assabet_defconfig
(no IDE host drivers are selected in this config so there is no
valid reason to enable IDE subsystem itself).

Cc: Dmitry Eremin-Solenikov <dbaryshkov at gmail.com>
Signed-off-by: Bartlomiej Zolnierkiewicz <b.zolnierkie at samsung.com>
---
 arch/arm/configs/assabet_defconfig | 1 -
 1 file changed, 1 deletion(-)

diff --git a/arch/arm/configs/assabet_defconfig b/arch/arm/configs/assabet_defconfig
index 558ecd8..ab19ff1 100644
--- a/arch/arm/configs/assabet_defconfig
+++ b/arch/arm/configs/assabet_defconfig
@@ -34,7 +34,6 @@ CONFIG_MTD_CFI_INTELEXT=y
 CONFIG_MTD_SA1100=y
 CONFIG_BLK_DEV_LOOP=m
 CONFIG_BLK_DEV_RAM=y
-CONFIG_IDE=y
 CONFIG_NETDEVICES=y
 CONFIG_NET_ETHERNET=y
 CONFIG_NET_PCMCIA=y
-- 
1.9.1



From b.zolnierkie at samsung.com  Fri Aug 14 10:04:18 2015
From: b.zolnierkie at samsung.com (Bartlomiej Zolnierkiewicz)
Date: Fri, 14 Aug 2015 19:04:18 +0200
Subject: [PATCH] arm: badge4_defconfig: disable IDE subsystem
In-Reply-To: <1439571876-13758-1-git-send-email-b.zolnierkie@samsung.com>
References: <1439571876-13758-1-git-send-email-b.zolnierkie@samsung.com>
Message-ID: <1439571876-13758-3-git-send-email-b.zolnierkie@samsung.com>

This patch disables deprecated IDE subsystem in badge4_defconfig
(no IDE host drivers are selected in this config so there is no
valid reason to enable IDE subsystem itself).

Cc: Dmitry Eremin-Solenikov <dbaryshkov at gmail.com>
Signed-off-by: Bartlomiej Zolnierkiewicz <b.zolnierkie at samsung.com>
---
 arch/arm/configs/badge4_defconfig | 2 --
 1 file changed, 2 deletions(-)

diff --git a/arch/arm/configs/badge4_defconfig b/arch/arm/configs/badge4_defconfig
index d590098..2a604aa 100644
--- a/arch/arm/configs/badge4_defconfig
+++ b/arch/arm/configs/badge4_defconfig
@@ -42,8 +42,6 @@ CONFIG_MTD_SA1100=y
 CONFIG_PARPORT=m
 CONFIG_BLK_DEV_LOOP=y
 CONFIG_BLK_DEV_NBD=m
-CONFIG_IDE=m
-CONFIG_BLK_DEV_IDECD=m
 CONFIG_SCSI=y
 CONFIG_BLK_DEV_SD=y
 CONFIG_CHR_DEV_ST=m
-- 
1.9.1



From b.zolnierkie at samsung.com  Fri Aug 14 10:04:20 2015
From: b.zolnierkie at samsung.com (Bartlomiej Zolnierkiewicz)
Date: Fri, 14 Aug 2015 19:04:20 +0200
Subject: [PATCH] arm: colibri_pxa270_defconfig: disable IDE subsystem
In-Reply-To: <1439571876-13758-1-git-send-email-b.zolnierkie@samsung.com>
References: <1439571876-13758-1-git-send-email-b.zolnierkie@samsung.com>
Message-ID: <1439571876-13758-5-git-send-email-b.zolnierkie@samsung.com>

This patch disables deprecated IDE subsystem in colibri_pxa270_defconfig
(no IDE host drivers are selected in this config so there is no valid
reason to enable IDE subsystem itself).

Cc: Daniel Mack <daniel at zonque.org>
Cc: Haojian Zhuang <haojian.zhuang at gmail.com>
Cc: Robert Jarzmik <robert.jarzmik at free.fr>
Signed-off-by: Bartlomiej Zolnierkiewicz <b.zolnierkie at samsung.com>
---
 arch/arm/configs/colibri_pxa270_defconfig | 1 -
 1 file changed, 1 deletion(-)

diff --git a/arch/arm/configs/colibri_pxa270_defconfig b/arch/arm/configs/colibri_pxa270_defconfig
index 18c311a..7154e55 100644
--- a/arch/arm/configs/colibri_pxa270_defconfig
+++ b/arch/arm/configs/colibri_pxa270_defconfig
@@ -83,7 +83,6 @@ CONFIG_BLK_DEV_CRYPTOLOOP=m
 CONFIG_BLK_DEV_NBD=y
 CONFIG_BLK_DEV_RAM=y
 CONFIG_BLK_DEV_RAM_COUNT=8
-CONFIG_IDE=y
 CONFIG_NETDEVICES=y
 CONFIG_PHYLIB=y
 CONFIG_NET_ETHERNET=y
-- 
1.9.1



From b.zolnierkie at samsung.com  Fri Aug 14 10:04:19 2015
From: b.zolnierkie at samsung.com (Bartlomiej Zolnierkiewicz)
Date: Fri, 14 Aug 2015 19:04:19 +0200
Subject: [PATCH] arm: cerfcube_defconfig: disable IDE subsystem
In-Reply-To: <1439571876-13758-1-git-send-email-b.zolnierkie@samsung.com>
References: <1439571876-13758-1-git-send-email-b.zolnierkie@samsung.com>
Message-ID: <1439571876-13758-4-git-send-email-b.zolnierkie@samsung.com>

This patch disables deprecated IDE subsystem in cerfcube_defconfig
(no IDE host drivers are selected in this config so there is no
valid reason to enable IDE subsystem itself).

Cc: Dmitry Eremin-Solenikov <dbaryshkov at gmail.com>
Signed-off-by: Bartlomiej Zolnierkiewicz <b.zolnierkie at samsung.com>
---
 arch/arm/configs/cerfcube_defconfig | 1 -
 1 file changed, 1 deletion(-)

diff --git a/arch/arm/configs/cerfcube_defconfig b/arch/arm/configs/cerfcube_defconfig
index dce912d..57a2a18 100644
--- a/arch/arm/configs/cerfcube_defconfig
+++ b/arch/arm/configs/cerfcube_defconfig
@@ -39,7 +39,6 @@ CONFIG_MTD_CFI_INTELEXT=y
 CONFIG_MTD_SA1100=y
 CONFIG_BLK_DEV_LOOP=m
 CONFIG_BLK_DEV_RAM=m
-CONFIG_IDE=y
 CONFIG_NETDEVICES=y
 CONFIG_NET_ETHERNET=y
 CONFIG_NET_PCI=y
-- 
1.9.1



From b.zolnierkie at samsung.com  Fri Aug 14 10:04:24 2015
From: b.zolnierkie at samsung.com (Bartlomiej Zolnierkiewicz)
Date: Fri, 14 Aug 2015 19:04:24 +0200
Subject: [RFT PATCH] arm: h3600_defconfig: convert to use libata PATA drivers
In-Reply-To: <1439571876-13758-1-git-send-email-b.zolnierkie@samsung.com>
References: <1439571876-13758-1-git-send-email-b.zolnierkie@samsung.com>
Message-ID: <1439571876-13758-9-git-send-email-b.zolnierkie@samsung.com>

IDE subsystem has been deprecated since 2009 and the majority
(if not all) of Linux distributions have switched to use
libata for ATA support exclusively.  However there are still
some users (mostly old or/and embedded non-x86 systems) that
have not converted from using IDE subsystem to libata PATA
drivers.  This doesn't seem to be good thing in the long-term
for Linux as while there is less and less PATA systems left
in use:

* testing efforts are divided between two subsystems

* having duplicate drivers for same hardware confuses users

This patch converts h3600_defconfig to use libata PATA
drivers.

Cc: Dmitry Eremin-Solenikov <dbaryshkov at gmail.com>
Signed-off-by: Bartlomiej Zolnierkiewicz <b.zolnierkie at samsung.com>
---
Build tested only.
If you have affected hardware please test.  Thank you.

 arch/arm/configs/h3600_defconfig | 5 +++--
 1 file changed, 3 insertions(+), 2 deletions(-)

diff --git a/arch/arm/configs/h3600_defconfig b/arch/arm/configs/h3600_defconfig
index 0142ec3..ebeca11 100644
--- a/arch/arm/configs/h3600_defconfig
+++ b/arch/arm/configs/h3600_defconfig
@@ -39,8 +39,9 @@ CONFIG_MTD_SA1100=y
 CONFIG_BLK_DEV_LOOP=m
 CONFIG_BLK_DEV_RAM=y
 CONFIG_BLK_DEV_RAM_SIZE=8192
-CONFIG_IDE=y
-CONFIG_BLK_DEV_IDECS=y
+CONFIG_BLK_DEV_SD=y
+CONFIG_ATA=y
+CONFIG_PATA_PCMCIA=y
 CONFIG_NETDEVICES=y
 CONFIG_PCMCIA_PCNET=y
 CONFIG_PPP=m
-- 
1.9.1



From b.zolnierkie at samsung.com  Fri Aug 14 10:04:25 2015
From: b.zolnierkie at samsung.com (Bartlomiej Zolnierkiewicz)
Date: Fri, 14 Aug 2015 19:04:25 +0200
Subject: [RFT PATCH] arm: ixp4xx_defconfig: convert to use libata PATA drivers
In-Reply-To: <1439571876-13758-1-git-send-email-b.zolnierkie@samsung.com>
References: <1439571876-13758-1-git-send-email-b.zolnierkie@samsung.com>
Message-ID: <1439571876-13758-10-git-send-email-b.zolnierkie@samsung.com>

IDE subsystem has been deprecated since 2009 and the majority
(if not all) of Linux distributions have switched to use
libata for ATA support exclusively.  However there are still
some users (mostly old or/and embedded non-x86 systems) that
have not converted from using IDE subsystem to libata PATA
drivers.  This doesn't seem to be good thing in the long-term
for Linux as while there is less and less PATA systems left
in use:

* testing efforts are divided between two subsystems

* having duplicate drivers for same hardware confuses users

This patch converts ixp4xx_defconfig to use libata PATA
drivers.

Cc: Imre Kaloz <kaloz at openwrt.org>
Cc: Krzysztof Halasa <khalasa at piap.pl>
Signed-off-by: Bartlomiej Zolnierkiewicz <b.zolnierkie at samsung.com>
---
Build tested only.
If you have affected hardware please test.  Thank you.

 arch/arm/configs/ixp4xx_defconfig | 9 +++++----
 1 file changed, 5 insertions(+), 4 deletions(-)

diff --git a/arch/arm/configs/ixp4xx_defconfig b/arch/arm/configs/ixp4xx_defconfig
index 24636cf..6414f24 100644
--- a/arch/arm/configs/ixp4xx_defconfig
+++ b/arch/arm/configs/ixp4xx_defconfig
@@ -127,16 +127,17 @@ CONFIG_BLK_DEV_LOOP=y
 CONFIG_BLK_DEV_RAM=y
 CONFIG_BLK_DEV_RAM_SIZE=8192
 CONFIG_EEPROM_LEGACY=y
-CONFIG_IDE=y
-CONFIG_BLK_DEV_CMD64X=y
-CONFIG_BLK_DEV_HPT366=y
-CONFIG_BLK_DEV_PDC202XX_NEW=y
 # CONFIG_SCSI_PROC_FS is not set
 CONFIG_BLK_DEV_SD=y
 # CONFIG_SCSI_LOWLEVEL is not set
 CONFIG_ATA=y
 CONFIG_SATA_VIA=y
 CONFIG_PATA_ARTOP=y
+CONFIG_PATA_CMD64X=y
+CONFIG_PATA_HPT366=y
+CONFIG_PATA_HPT37X=y
+CONFIG_PATA_HPT3X2N=y
+CONFIG_PATA_PDC2027X=y
 CONFIG_PATA_IXP4XX_CF=y
 CONFIG_NETDEVICES=y
 CONFIG_DUMMY=y
-- 
1.9.1



From b.zolnierkie at samsung.com  Fri Aug 14 10:04:26 2015
From: b.zolnierkie at samsung.com (Bartlomiej Zolnierkiewicz)
Date: Fri, 14 Aug 2015 19:04:26 +0200
Subject: [RFT PATCH] arm: jornada720_defconfig: convert to use libata PATA
 drivers
In-Reply-To: <1439571876-13758-1-git-send-email-b.zolnierkie@samsung.com>
References: <1439571876-13758-1-git-send-email-b.zolnierkie@samsung.com>
Message-ID: <1439571876-13758-11-git-send-email-b.zolnierkie@samsung.com>

IDE subsystem has been deprecated since 2009 and the majority
(if not all) of Linux distributions have switched to use
libata for ATA support exclusively.  However there are still
some users (mostly old or/and embedded non-x86 systems) that
have not converted from using IDE subsystem to libata PATA
drivers.  This doesn't seem to be good thing in the long-term
for Linux as while there is less and less PATA systems left
in use:

* testing efforts are divided between two subsystems

* having duplicate drivers for same hardware confuses users

This patch converts jornada720_defconfig to use libata PATA
drivers.

Cc: Kristoffer Ericson <kristoffer.ericson at gmail.com>
Cc: Dmitry Eremin-Solenikov <dbaryshkov at gmail.com>
Signed-off-by: Bartlomiej Zolnierkiewicz <b.zolnierkie at samsung.com>
---
Build tested only.
If you have affected hardware please test.  Thank you.

 arch/arm/configs/jornada720_defconfig | 5 +++--
 1 file changed, 3 insertions(+), 2 deletions(-)

diff --git a/arch/arm/configs/jornada720_defconfig b/arch/arm/configs/jornada720_defconfig
index ea80e7e..9056284 100644
--- a/arch/arm/configs/jornada720_defconfig
+++ b/arch/arm/configs/jornada720_defconfig
@@ -29,8 +29,9 @@ CONFIG_SA1100_FIR=m
 CONFIG_UEVENT_HELPER_PATH="/sbin/hotplug"
 CONFIG_BLK_DEV_LOOP=y
 CONFIG_BLK_DEV_NBD=y
-CONFIG_IDE=y
-CONFIG_BLK_DEV_IDECS=y
+CONFIG_BLK_DEV_SD=y
+CONFIG_ATA=y
+CONFIG_PATA_PCMCIA=y
 CONFIG_NETDEVICES=y
 CONFIG_DUMMY=y
 CONFIG_NET_ETHERNET=y
-- 
1.9.1



From b.zolnierkie at samsung.com  Fri Aug 14 10:04:27 2015
From: b.zolnierkie at samsung.com (Bartlomiej Zolnierkiewicz)
Date: Fri, 14 Aug 2015 19:04:27 +0200
Subject: [PATCH] arm: lart_defconfig: disable IDE subsystem
In-Reply-To: <1439571876-13758-1-git-send-email-b.zolnierkie@samsung.com>
References: <1439571876-13758-1-git-send-email-b.zolnierkie@samsung.com>
Message-ID: <1439571876-13758-12-git-send-email-b.zolnierkie@samsung.com>

This patch disables deprecated IDE subsystem in lart_defconfig
(no IDE host drivers are selected in this config so there is no
valid reason to enable IDE subsystem itself).

Cc: Dmitry Eremin-Solenikov <dbaryshkov at gmail.com>
Signed-off-by: Bartlomiej Zolnierkiewicz <b.zolnierkie at samsung.com>
---
 arch/arm/configs/lart_defconfig | 2 --
 1 file changed, 2 deletions(-)

diff --git a/arch/arm/configs/lart_defconfig b/arch/arm/configs/lart_defconfig
index faa2865..8fc6fd0 100644
--- a/arch/arm/configs/lart_defconfig
+++ b/arch/arm/configs/lart_defconfig
@@ -36,8 +36,6 @@ CONFIG_MTD_CHAR=y
 CONFIG_MTD_BLOCK=y
 CONFIG_MTD_LART=y
 CONFIG_BLK_DEV_RAM=y
-CONFIG_IDE=m
-CONFIG_BLK_DEV_IDECD=m
 CONFIG_NETDEVICES=y
 CONFIG_DUMMY=m
 CONFIG_NET_ETHERNET=y
-- 
1.9.1



From b.zolnierkie at samsung.com  Fri Aug 14 10:04:21 2015
From: b.zolnierkie at samsung.com (Bartlomiej Zolnierkiewicz)
Date: Fri, 14 Aug 2015 19:04:21 +0200
Subject: [RFT PATCH] arm: collie_defconfig: convert to use libata PATA drivers
In-Reply-To: <1439571876-13758-1-git-send-email-b.zolnierkie@samsung.com>
References: <1439571876-13758-1-git-send-email-b.zolnierkie@samsung.com>
Message-ID: <1439571876-13758-6-git-send-email-b.zolnierkie@samsung.com>

IDE subsystem has been deprecated since 2009 and the majority
(if not all) of Linux distributions have switched to use
libata for ATA support exclusively.  However there are still
some users (mostly old or/and embedded non-x86 systems) that
have not converted from using IDE subsystem to libata PATA
drivers.  This doesn't seem to be good thing in the long-term
for Linux as while there is less and less PATA systems left
in use:

* testing efforts are divided between two subsystems

* having duplicate drivers for same hardware confuses users

This patch converts collie_defconfig to use libata PATA
drivers.

Cc: Dmitry Eremin-Solenikov <dbaryshkov at gmail.com>
Signed-off-by: Bartlomiej Zolnierkiewicz <b.zolnierkie at samsung.com>
---
Build tested only.
If you have affected hardware please test.  Thank you.

 arch/arm/configs/collie_defconfig | 5 +++--
 1 file changed, 3 insertions(+), 2 deletions(-)

diff --git a/arch/arm/configs/collie_defconfig b/arch/arm/configs/collie_defconfig
index 6c56ad0..4e6b68f 100644
--- a/arch/arm/configs/collie_defconfig
+++ b/arch/arm/configs/collie_defconfig
@@ -43,8 +43,9 @@ CONFIG_MTD_SA1100=y
 CONFIG_BLK_DEV_LOOP=y
 CONFIG_BLK_DEV_RAM=y
 CONFIG_BLK_DEV_RAM_SIZE=1024
-CONFIG_IDE=y
-CONFIG_BLK_DEV_IDECS=y
+CONFIG_BLK_DEV_SD=y
+CONFIG_ATA=y
+CONFIG_PATA_PCMCIA=y
 # CONFIG_INPUT_MOUSEDEV is not set
 CONFIG_INPUT_EVDEV=y
 # CONFIG_KEYBOARD_ATKBD is not set
-- 
1.9.1



From b.zolnierkie at samsung.com  Fri Aug 14 10:04:22 2015
From: b.zolnierkie at samsung.com (Bartlomiej Zolnierkiewicz)
Date: Fri, 14 Aug 2015 19:04:22 +0200
Subject: [RFT PATCH] arm: corgi_defconfig: convert to use libata PATA drivers
In-Reply-To: <1439571876-13758-1-git-send-email-b.zolnierkie@samsung.com>
References: <1439571876-13758-1-git-send-email-b.zolnierkie@samsung.com>
Message-ID: <1439571876-13758-7-git-send-email-b.zolnierkie@samsung.com>

IDE subsystem has been deprecated since 2009 and the majority
(if not all) of Linux distributions have switched to use
libata for ATA support exclusively.  However there are still
some users (mostly old or/and embedded non-x86 systems) that
have not converted from using IDE subsystem to libata PATA
drivers.  This doesn't seem to be good thing in the long-term
for Linux as while there is less and less PATA systems left
in use:

* testing efforts are divided between two subsystems

* having duplicate drivers for same hardware confuses users

This patch converts corgi_defconfig to use libata PATA
drivers.

Cc: Daniel Mack <daniel at zonque.org>
Cc: Haojian Zhuang <haojian.zhuang at gmail.com>
Cc: Robert Jarzmik <robert.jarzmik at free.fr>
Signed-off-by: Bartlomiej Zolnierkiewicz <b.zolnierkie at samsung.com>
---
Build tested only.
If you have affected hardware please test.  Thank you.

 arch/arm/configs/corgi_defconfig | 7 +++----
 1 file changed, 3 insertions(+), 4 deletions(-)

diff --git a/arch/arm/configs/corgi_defconfig b/arch/arm/configs/corgi_defconfig
index c1470a0..462533b 100644
--- a/arch/arm/configs/corgi_defconfig
+++ b/arch/arm/configs/corgi_defconfig
@@ -99,15 +99,14 @@ CONFIG_MTD_COMPLEX_MAPPINGS=y
 CONFIG_MTD_NAND=y
 CONFIG_MTD_NAND_SHARPSL=y
 CONFIG_BLK_DEV_LOOP=y
-CONFIG_IDE=y
-CONFIG_BLK_DEV_IDECS=y
-CONFIG_SCSI=m
-CONFIG_BLK_DEV_SD=m
+CONFIG_BLK_DEV_SD=y
 CONFIG_CHR_DEV_ST=m
 CONFIG_CHR_DEV_OSST=m
 CONFIG_BLK_DEV_SR=m
 CONFIG_CHR_DEV_SG=m
 CONFIG_SCSI_MULTI_LUN=y
+CONFIG_ATA=y
+CONFIG_PATA_PCMCIA=y
 CONFIG_NETDEVICES=y
 CONFIG_NET_ETHERNET=y
 CONFIG_USB_CATC=m
-- 
1.9.1



From b.zolnierkie at samsung.com  Fri Aug 14 10:04:23 2015
From: b.zolnierkie at samsung.com (Bartlomiej Zolnierkiewicz)
Date: Fri, 14 Aug 2015 19:04:23 +0200
Subject: [PATCH] arm: footbridge_defconfig: disable IDE subsystem
In-Reply-To: <1439571876-13758-1-git-send-email-b.zolnierkie@samsung.com>
References: <1439571876-13758-1-git-send-email-b.zolnierkie@samsung.com>
Message-ID: <1439571876-13758-8-git-send-email-b.zolnierkie@samsung.com>

This patch disables deprecated IDE subsystem in footbridge_defconfig
(no IDE host drivers are selected in this config so there is no valid
reason to enable IDE subsystem itself).

Cc: Russell King <linux at arm.linux.org.uk>
Signed-off-by: Bartlomiej Zolnierkiewicz <b.zolnierkie at samsung.com>
---
 arch/arm/configs/footbridge_defconfig | 1 -
 1 file changed, 1 deletion(-)

diff --git a/arch/arm/configs/footbridge_defconfig b/arch/arm/configs/footbridge_defconfig
index 87e020f..cd7a001 100644
--- a/arch/arm/configs/footbridge_defconfig
+++ b/arch/arm/configs/footbridge_defconfig
@@ -66,7 +66,6 @@ CONFIG_PARIDE_ON26=m
 CONFIG_BLK_DEV_LOOP=m
 CONFIG_BLK_DEV_NBD=m
 CONFIG_BLK_DEV_RAM=y
-CONFIG_IDE=y
 CONFIG_NETDEVICES=y
 CONFIG_NET_ETHERNET=y
 CONFIG_NET_VENDOR_3COM=y
-- 
1.9.1



From b.zolnierkie at samsung.com  Fri Aug 14 10:04:28 2015
From: b.zolnierkie at samsung.com (Bartlomiej Zolnierkiewicz)
Date: Fri, 14 Aug 2015 19:04:28 +0200
Subject: [PATCH] arm: lpda270_defconfig: disable IDE subsystem
In-Reply-To: <1439571876-13758-1-git-send-email-b.zolnierkie@samsung.com>
References: <1439571876-13758-1-git-send-email-b.zolnierkie@samsung.com>
Message-ID: <1439571876-13758-13-git-send-email-b.zolnierkie@samsung.com>

This patch disables deprecated IDE subsystem in lpd270_defconfig
(no IDE host drivers are selected in this config so there is no
valid reason to enable IDE subsystem itself).

Cc: Daniel Mack <daniel at zonque.org>
Cc: Haojian Zhuang <haojian.zhuang at gmail.com>
Cc: Robert Jarzmik <robert.jarzmik at free.fr>
Signed-off-by: Bartlomiej Zolnierkiewicz <b.zolnierkie at samsung.com>
---
 arch/arm/configs/lpd270_defconfig | 1 -
 1 file changed, 1 deletion(-)

diff --git a/arch/arm/configs/lpd270_defconfig b/arch/arm/configs/lpd270_defconfig
index 1c8c9ee..a9dd1e9 100644
--- a/arch/arm/configs/lpd270_defconfig
+++ b/arch/arm/configs/lpd270_defconfig
@@ -31,7 +31,6 @@ CONFIG_MTD_CFI_GEOMETRY=y
 # CONFIG_MTD_CFI_I1 is not set
 CONFIG_MTD_CFI_INTELEXT=y
 CONFIG_BLK_DEV_NBD=y
-CONFIG_IDE=y
 CONFIG_NETDEVICES=y
 CONFIG_NET_ETHERNET=y
 CONFIG_SMC91X=y
-- 
1.9.1



From b.zolnierkie at samsung.com  Fri Aug 14 10:04:29 2015
From: b.zolnierkie at samsung.com (Bartlomiej Zolnierkiewicz)
Date: Fri, 14 Aug 2015 19:04:29 +0200
Subject: [PATCH] arm: mainstone_defconfig: disable IDE subsystem
In-Reply-To: <1439571876-13758-1-git-send-email-b.zolnierkie@samsung.com>
References: <1439571876-13758-1-git-send-email-b.zolnierkie@samsung.com>
Message-ID: <1439571876-13758-14-git-send-email-b.zolnierkie@samsung.com>

This patch disables deprecated IDE subsystem in mainstone_defconfig
(no IDE host drivers are selected in this config so there is no valid
reason to enable IDE subsystem itself).

Cc: Daniel Mack <daniel at zonque.org>
Cc: Haojian Zhuang <haojian.zhuang at gmail.com>
Cc: Robert Jarzmik <robert.jarzmik at free.fr>
Signed-off-by: Bartlomiej Zolnierkiewicz <b.zolnierkie at samsung.com>
---
 arch/arm/configs/mainstone_defconfig | 1 -
 1 file changed, 1 deletion(-)

diff --git a/arch/arm/configs/mainstone_defconfig b/arch/arm/configs/mainstone_defconfig
index 04efa1b..e8d26b8 100644
--- a/arch/arm/configs/mainstone_defconfig
+++ b/arch/arm/configs/mainstone_defconfig
@@ -27,7 +27,6 @@ CONFIG_MTD_CFI_ADV_OPTIONS=y
 CONFIG_MTD_CFI_GEOMETRY=y
 # CONFIG_MTD_CFI_I1 is not set
 CONFIG_MTD_CFI_INTELEXT=y
-CONFIG_IDE=y
 CONFIG_NETDEVICES=y
 CONFIG_NET_ETHERNET=y
 CONFIG_SMC91X=y
-- 
1.9.1



From b.zolnierkie at samsung.com  Fri Aug 14 10:04:30 2015
From: b.zolnierkie at samsung.com (Bartlomiej Zolnierkiewicz)
Date: Fri, 14 Aug 2015 19:04:30 +0200
Subject: [RFT PATCH] arm: netwinder_defconfig: convert to use libata PATA
 drivers
In-Reply-To: <1439571876-13758-1-git-send-email-b.zolnierkie@samsung.com>
References: <1439571876-13758-1-git-send-email-b.zolnierkie@samsung.com>
Message-ID: <1439571876-13758-15-git-send-email-b.zolnierkie@samsung.com>

IDE subsystem has been deprecated since 2009 and the majority
(if not all) of Linux distributions have switched to use
libata for ATA support exclusively.  However there are still
some users (mostly old or/and embedded non-x86 systems) that
have not converted from using IDE subsystem to libata PATA
drivers.  This doesn't seem to be good thing in the long-term
for Linux as while there is less and less PATA systems left
in use:

* testing efforts are divided between two subsystems

* having duplicate drivers for same hardware confuses users

This patch converts netwinder_defconfig to use libata PATA
drivers.

Cc: Russell King <linux at arm.linux.org.uk>
Signed-off-by: Bartlomiej Zolnierkiewicz <b.zolnierkie at samsung.com>
---
Build tested only.
If you have affected hardware please test.  Thank you.

 arch/arm/configs/netwinder_defconfig | 7 ++++---
 1 file changed, 4 insertions(+), 3 deletions(-)

diff --git a/arch/arm/configs/netwinder_defconfig b/arch/arm/configs/netwinder_defconfig
index 25ed772..a890a93 100644
--- a/arch/arm/configs/netwinder_defconfig
+++ b/arch/arm/configs/netwinder_defconfig
@@ -7,7 +7,7 @@ CONFIG_LEDS=y
 CONFIG_LEDS_CPU=y
 CONFIG_ZBOOT_ROM_TEXT=0x0
 CONFIG_ZBOOT_ROM_BSS=0x0
-CONFIG_CMDLINE="root=0x301"
+CONFIG_CMDLINE="root=0x801"
 CONFIG_FPE_NWFPE=y
 CONFIG_BINFMT_AOUT=y
 CONFIG_NET=y
@@ -26,8 +26,9 @@ CONFIG_PARPORT=y
 CONFIG_PARPORT_PC=y
 CONFIG_PARPORT_PC_SUPERIO=y
 CONFIG_BLK_DEV_LOOP=y
-CONFIG_IDE=y
-CONFIG_BLK_DEV_SL82C105=y
+CONFIG_BLK_DEV_SD=y
+CONFIG_ATA=y
+CONFIG_PATA_WINBOND=y
 CONFIG_NETDEVICES=y
 CONFIG_NET_ETHERNET=y
 CONFIG_MII=y
-- 
1.9.1



From b.zolnierkie at samsung.com  Fri Aug 14 10:04:34 2015
From: b.zolnierkie at samsung.com (Bartlomiej Zolnierkiewicz)
Date: Fri, 14 Aug 2015 19:04:34 +0200
Subject: [PATCH] arm: shannon_defconfig: disable IDE subsystem
In-Reply-To: <1439571876-13758-1-git-send-email-b.zolnierkie@samsung.com>
References: <1439571876-13758-1-git-send-email-b.zolnierkie@samsung.com>
Message-ID: <1439571876-13758-19-git-send-email-b.zolnierkie@samsung.com>

This patch disables deprecated IDE subsystem in shannon_defconfig
(no IDE host drivers are selected in this config so there is no
valid reason to enable IDE subsystem itself).

Cc: Dmitry Eremin-Solenikov <dbaryshkov at gmail.com>
Signed-off-by: Bartlomiej Zolnierkiewicz <b.zolnierkie at samsung.com>
---
 arch/arm/configs/shannon_defconfig | 1 -
 1 file changed, 1 deletion(-)

diff --git a/arch/arm/configs/shannon_defconfig b/arch/arm/configs/shannon_defconfig
index b0b9694..e523956 100644
--- a/arch/arm/configs/shannon_defconfig
+++ b/arch/arm/configs/shannon_defconfig
@@ -25,7 +25,6 @@ CONFIG_MTD_CFI_AMDSTD=y
 CONFIG_MTD_SA1100=y
 CONFIG_BLK_DEV_RAM=y
 CONFIG_BLK_DEV_RAM_SIZE=8192
-CONFIG_IDE=m
 CONFIG_NETDEVICES=y
 CONFIG_NET_ETHERNET=y
 CONFIG_NET_PCMCIA=y
-- 
1.9.1



From b.zolnierkie at samsung.com  Fri Aug 14 10:04:31 2015
From: b.zolnierkie at samsung.com (Bartlomiej Zolnierkiewicz)
Date: Fri, 14 Aug 2015 19:04:31 +0200
Subject: [RFT PATCH] arm: omap1_defconfig: convert to use libata PATA drivers
In-Reply-To: <1439571876-13758-1-git-send-email-b.zolnierkie@samsung.com>
References: <1439571876-13758-1-git-send-email-b.zolnierkie@samsung.com>
Message-ID: <1439571876-13758-16-git-send-email-b.zolnierkie@samsung.com>

IDE subsystem has been deprecated since 2009 and the majority
(if not all) of Linux distributions have switched to use
libata for ATA support exclusively.  However there are still
some users (mostly old or/and embedded non-x86 systems) that
have not converted from using IDE subsystem to libata PATA
drivers.  This doesn't seem to be good thing in the long-term
for Linux as while there is less and less PATA systems left
in use:

* testing efforts are divided between two subsystems

* having duplicate drivers for same hardware confuses users

This patch converts omap1_defconfig to use libata PATA
drivers.

Cc: Tony Lindgren <tony at atomide.com>
Cc: linux-omap at vger.kernel.org
Signed-off-by: Bartlomiej Zolnierkiewicz <b.zolnierkie at samsung.com>
---
Build tested only.
If you have affected hardware please test.  Thank you.

 arch/arm/configs/omap1_defconfig | 4 ++--
 1 file changed, 2 insertions(+), 2 deletions(-)

diff --git a/arch/arm/configs/omap1_defconfig b/arch/arm/configs/omap1_defconfig
index 0c8a787..6ffc984 100644
--- a/arch/arm/configs/omap1_defconfig
+++ b/arch/arm/configs/omap1_defconfig
@@ -96,14 +96,14 @@ CONFIG_BLK_DEV_LOOP=y
 CONFIG_BLK_DEV_RAM=y
 CONFIG_BLK_DEV_RAM_COUNT=2
 CONFIG_BLK_DEV_RAM_SIZE=8192
-CONFIG_IDE=m
-CONFIG_BLK_DEV_IDECS=m
 CONFIG_SCSI=y
 # CONFIG_SCSI_PROC_FS is not set
 CONFIG_BLK_DEV_SD=y
 CONFIG_CHR_DEV_ST=y
 CONFIG_BLK_DEV_SR=y
 CONFIG_CHR_DEV_SG=y
+CONFIG_ATA=m
+CONFIG_PATA_PCMCIA=m
 CONFIG_NETDEVICES=y
 CONFIG_TUN=y
 CONFIG_PHYLIB=y
-- 
1.9.1



From b.zolnierkie at samsung.com  Fri Aug 14 10:04:32 2015
From: b.zolnierkie at samsung.com (Bartlomiej Zolnierkiewicz)
Date: Fri, 14 Aug 2015 19:04:32 +0200
Subject: [PATCH] arm: pxa255-idp_defconfig: disable IDE subsystem
In-Reply-To: <1439571876-13758-1-git-send-email-b.zolnierkie@samsung.com>
References: <1439571876-13758-1-git-send-email-b.zolnierkie@samsung.com>
Message-ID: <1439571876-13758-17-git-send-email-b.zolnierkie@samsung.com>

This patch disables deprecated IDE subsystem in pxa255-idp_defconfig
(no IDE host drivers are selected in this config so there is no valid
reason to enable IDE subsystem itself).

Cc: Daniel Mack <daniel at zonque.org>
Cc: Haojian Zhuang <haojian.zhuang at gmail.com>
Cc: Robert Jarzmik <robert.jarzmik at free.fr>
Signed-off-by: Bartlomiej Zolnierkiewicz <b.zolnierkie at samsung.com>
---
 arch/arm/configs/pxa255-idp_defconfig | 1 -
 1 file changed, 1 deletion(-)

diff --git a/arch/arm/configs/pxa255-idp_defconfig b/arch/arm/configs/pxa255-idp_defconfig
index 917a070b..088627a 100644
--- a/arch/arm/configs/pxa255-idp_defconfig
+++ b/arch/arm/configs/pxa255-idp_defconfig
@@ -28,7 +28,6 @@ CONFIG_MTD_CFI_GEOMETRY=y
 # CONFIG_MTD_MAP_BANK_WIDTH_2 is not set
 # CONFIG_MTD_CFI_I1 is not set
 CONFIG_MTD_CFI_INTELEXT=y
-CONFIG_IDE=y
 CONFIG_NETDEVICES=y
 CONFIG_NET_ETHERNET=y
 CONFIG_SMC91X=y
-- 
1.9.1



From b.zolnierkie at samsung.com  Fri Aug 14 10:04:33 2015
From: b.zolnierkie at samsung.com (Bartlomiej Zolnierkiewicz)
Date: Fri, 14 Aug 2015 19:04:33 +0200
Subject: [RFT PATCH] arm: s3c2410_defconfig: convert to use libata PATA drivers
In-Reply-To: <1439571876-13758-1-git-send-email-b.zolnierkie@samsung.com>
References: <1439571876-13758-1-git-send-email-b.zolnierkie@samsung.com>
Message-ID: <1439571876-13758-18-git-send-email-b.zolnierkie@samsung.com>

IDE subsystem has been deprecated since 2009 and the majority
(if not all) of Linux distributions have switched to use
libata for ATA support exclusively.  However there are still
some users (mostly old or/and embedded non-x86 systems) that
have not converted from using IDE subsystem to libata PATA
drivers.  This doesn't seem to be good thing in the long-term
for Linux as while there is less and less PATA systems left
in use:

* testing efforts are divided between two subsystems

* having duplicate drivers for same hardware confuses users

This patch converts s3c2410_defconfig to use libata PATA
drivers.

Cc: Kukjin Kim <kgene at kernel.org>
Cc: Krzysztof Kozlowski <k.kozlowski at samsung.com>
Cc: linux-samsung-soc at vger.kernel.org
Cc: Ben Dooks <ben.dooks at codethink.co.uk>
Cc: Vincent Sanders <vince at simtec.co.uk>
Cc: Simtec Linux Team <linux at simtec.co.uk>
Signed-off-by: Bartlomiej Zolnierkiewicz <b.zolnierkie at samsung.com>
---
Build tested only.
If you have affected hardware please test.  Thank you.

 arch/arm/configs/s3c2410_defconfig | 10 +++-------
 1 file changed, 3 insertions(+), 7 deletions(-)

diff --git a/arch/arm/configs/s3c2410_defconfig b/arch/arm/configs/s3c2410_defconfig
index f314236..f44fa09 100644
--- a/arch/arm/configs/s3c2410_defconfig
+++ b/arch/arm/configs/s3c2410_defconfig
@@ -220,20 +220,16 @@ CONFIG_BLK_DEV_NBD=m
 CONFIG_BLK_DEV_UB=m
 CONFIG_BLK_DEV_RAM=y
 CONFIG_ATA_OVER_ETH=m
-CONFIG_IDE=y
-CONFIG_BLK_DEV_IDECD=y
-CONFIG_BLK_DEV_IDETAPE=m
-CONFIG_BLK_DEV_PLATFORM=y
-CONFIG_SCSI=y
 CONFIG_BLK_DEV_SD=y
 CONFIG_CHR_DEV_ST=m
-CONFIG_BLK_DEV_SR=m
+CONFIG_BLK_DEV_SR=y
 CONFIG_BLK_DEV_SR_VENDOR=y
 CONFIG_CHR_DEV_SG=y
 CONFIG_CHR_DEV_SCH=m
-CONFIG_SCSI_MULTI_LUN=y
 CONFIG_SCSI_CONSTANTS=y
 CONFIG_SCSI_SCAN_ASYNC=y
+CONFIG_ATA=y
+CONFIG_PATA_PLATFORM=y
 CONFIG_NETDEVICES=y
 CONFIG_DM9000=y
 CONFIG_INPUT_EVDEV=y
-- 
1.9.1



From b.zolnierkie at samsung.com  Fri Aug 14 10:04:35 2015
From: b.zolnierkie at samsung.com (Bartlomiej Zolnierkiewicz)
Date: Fri, 14 Aug 2015 19:04:35 +0200
Subject: [RFT PATCH] arm: spitz_defconfig: convert to use libata PATA drivers
In-Reply-To: <1439571876-13758-1-git-send-email-b.zolnierkie@samsung.com>
References: <1439571876-13758-1-git-send-email-b.zolnierkie@samsung.com>
Message-ID: <1439571876-13758-20-git-send-email-b.zolnierkie@samsung.com>

IDE subsystem has been deprecated since 2009 and the majority
(if not all) of Linux distributions have switched to use
libata for ATA support exclusively.  However there are still
some users (mostly old or/and embedded non-x86 systems) that
have not converted from using IDE subsystem to libata PATA
drivers.  This doesn't seem to be good thing in the long-term
for Linux as while there is less and less PATA systems left
in use:

* testing efforts are divided between two subsystems

* having duplicate drivers for same hardware confuses users

This patch converts spitz_defconfig to use libata PATA
drivers.

Cc: Daniel Mack <daniel at zonque.org>
Cc: Haojian Zhuang <haojian.zhuang at gmail.com>
Cc: Robert Jarzmik <robert.jarzmik at free.fr>
Signed-off-by: Bartlomiej Zolnierkiewicz <b.zolnierkie at samsung.com>
---
Build tested only.
If you have affected hardware please test.  Thank you.

 arch/arm/configs/spitz_defconfig | 8 +++-----
 1 file changed, 3 insertions(+), 5 deletions(-)

diff --git a/arch/arm/configs/spitz_defconfig b/arch/arm/configs/spitz_defconfig
index a1ede19..d8c5293 100644
--- a/arch/arm/configs/spitz_defconfig
+++ b/arch/arm/configs/spitz_defconfig
@@ -96,15 +96,13 @@ CONFIG_MTD_COMPLEX_MAPPINGS=y
 CONFIG_MTD_NAND=y
 CONFIG_MTD_NAND_SHARPSL=y
 CONFIG_BLK_DEV_LOOP=y
-CONFIG_IDE=y
-CONFIG_BLK_DEV_IDECS=y
-CONFIG_SCSI=m
-CONFIG_BLK_DEV_SD=m
+CONFIG_BLK_DEV_SD=y
 CONFIG_CHR_DEV_ST=m
 CONFIG_CHR_DEV_OSST=m
 CONFIG_BLK_DEV_SR=m
 CONFIG_CHR_DEV_SG=m
-CONFIG_SCSI_MULTI_LUN=y
+CONFIG_ATA=y
+CONFIG_PATA_PCMCIA=y
 CONFIG_NETDEVICES=y
 CONFIG_NET_ETHERNET=y
 CONFIG_USB_CATC=m
-- 
1.9.1



From b.zolnierkie at samsung.com  Fri Aug 14 10:04:36 2015
From: b.zolnierkie at samsung.com (Bartlomiej Zolnierkiewicz)
Date: Fri, 14 Aug 2015 19:04:36 +0200
Subject: [PATCH] arm: trizeps4_defconfig: disable IDE subsystem
In-Reply-To: <1439571876-13758-1-git-send-email-b.zolnierkie@samsung.com>
References: <1439571876-13758-1-git-send-email-b.zolnierkie@samsung.com>
Message-ID: <1439571876-13758-21-git-send-email-b.zolnierkie@samsung.com>

This patch disables deprecated IDE subsystem in trizeps4_defconfig
(ide-cs host driver is selected in this config but pata_pcmcia
libata PATA host driver is also selected so ide-cs is redundant
and can be disabled together with the whole IDE subsystem).

Cc: Daniel Mack <daniel at zonque.org>
Cc: Haojian Zhuang <haojian.zhuang at gmail.com>
Cc: Robert Jarzmik <robert.jarzmik at free.fr>
Signed-off-by: Bartlomiej Zolnierkiewicz <b.zolnierkie at samsung.com>
---
 arch/arm/configs/trizeps4_defconfig | 2 --
 1 file changed, 2 deletions(-)

diff --git a/arch/arm/configs/trizeps4_defconfig b/arch/arm/configs/trizeps4_defconfig
index 932ee4e..cb3226a 100644
--- a/arch/arm/configs/trizeps4_defconfig
+++ b/arch/arm/configs/trizeps4_defconfig
@@ -94,8 +94,6 @@ CONFIG_BLK_DEV_CRYPTOLOOP=m
 CONFIG_BLK_DEV_NBD=y
 CONFIG_BLK_DEV_RAM=y
 CONFIG_BLK_DEV_RAM_COUNT=8
-CONFIG_IDE=y
-CONFIG_BLK_DEV_IDECS=m
 CONFIG_SCSI=y
 CONFIG_BLK_DEV_SD=y
 CONFIG_CHR_DEV_SG=y
-- 
1.9.1



From khilman at kernel.org  Fri Aug 14 10:19:04 2015
From: khilman at kernel.org (Kevin Hilman)
Date: Fri, 14 Aug 2015 10:19:04 -0700
Subject: [PATCH 2/9] PM / Domains: Remove dev->driver check for runtime PM
In-Reply-To: <CAMuHMdW-T9rUWXsQeffwtXspHbjfGqo_0G4QMB1o0TwTLJAQAg@mail.gmail.com>
References: <1438731339-58317-1-git-send-email-lina.iyer@linaro.org>
 <1438731339-58317-3-git-send-email-lina.iyer@linaro.org>
 <7hfv3onv5c.fsf@deeprootsystems.com>
 <CAMuHMdVeffa-jgXuSjDQBKTrhgW-d87OKzs1iXX+4y-9U_AJbg@mail.gmail.com>
 <7hwpwylepx.fsf@deeprootsystems.com>
 <CAMuHMdW-T9rUWXsQeffwtXspHbjfGqo_0G4QMB1o0TwTLJAQAg@mail.gmail.com>
Message-ID: <CAMAWPa-0R42thqBo0omn0KK7y0wyxoyaP+wsfoRvXBmWhBytKg@mail.gmail.com>

On Fri, Aug 14, 2015 at 12:24 AM, Geert Uytterhoeven
<geert at linux-m68k.org> wrote:
> Hi Kevin,
>
> On Fri, Aug 14, 2015 at 5:40 AM, Kevin Hilman <khilman at kernel.org> wrote:
>> Geert Uytterhoeven <geert at linux-m68k.org> writes:
>>> On Wed, Aug 12, 2015 at 9:50 PM, Kevin Hilman <khilman at kernel.org> wrote:
>>>> This check might have made sense before PM domains, but with PM domains,
>>>> it's entirely possible to have a simple device without a driver and the
>>>> PM domain handles all the necesary PM, so I think this check
>>>> could/should be removed.
>>>>
>>>> Thoughts?
>>>
>>> Simple devices without a driver aren't handled automatically.
>>> At minimum, the driver should call pm_runtime_enable(), cfr.
>>> drivers/bus/simple-pm-bus.c.
>>
>> That's correct, and in the proof-of-concept stuff I hacked up and in
>> Lina's series, the CPU "devices" do indeed to this.  Without that, they
>> wouldn't end up ever taking this codepath through genpd's
>> runtime_suspend and power_off hooks.
>>
>> Also, I'm not sure if your comment was meant to be an objection to the
>> patch?  or if you're OK with it.
>
> My comment was purely meant as a response to "it's entirely possible to have a
> simple device without a driver and the PM domain handles all the necesary PM".

Right, so if the PM domain does the pm_runtime_enable() for these
"simple" devices without drivers, they can still exist without a
driver, and the PM domain doing all the magic.

> I have no objections to the patch (read: I'm not sufficiently familiar with
> the code to make educated guesses about the side effects of this change ;-).

OK, thanks for clarifiying.

Kevin


From mathieu at codeaurora.org  Fri Aug 14 10:25:37 2015
From: mathieu at codeaurora.org (Mathieu Olivari)
Date: Fri, 14 Aug 2015 10:25:37 -0700
Subject: [PATCH 1/3] ARM: qcom: add SFPB nodes to IPQ806x dts
In-Reply-To: <55CD25B6.6050901@codeaurora.org>
References: <1439501620-24073-1-git-send-email-mathieu@codeaurora.org>
 <1439501620-24073-2-git-send-email-mathieu@codeaurora.org>
 <55CD25B6.6050901@codeaurora.org>
Message-ID: <20150814172536.GA7516@codeaurora.org>

On Thu, Aug 13, 2015 at 04:18:14PM -0700, Stephen Boyd wrote:
> On 08/13/2015 02:33 PM, Mathieu Olivari wrote:
> >Add one new node to the ipq806x.dtsi file to declare & register the
> >hardware spinlock devices. This mechanism is required to be used by
> >other drivers such as SMEM.
> >
> >Signed-off-by: Mathieu Olivari <mathieu at codeaurora.org>
> >---
> >  arch/arm/boot/dts/qcom-ipq8064.dtsi | 12 ++++++++++++
> >  1 file changed, 12 insertions(+)
> >
> >diff --git a/arch/arm/boot/dts/qcom-ipq8064.dtsi b/arch/arm/boot/dts/qcom-ipq8064.dtsi
> >index 9f727d8..ea7b959 100644
> >--- a/arch/arm/boot/dts/qcom-ipq8064.dtsi
> >+++ b/arch/arm/boot/dts/qcom-ipq8064.dtsi
> >@@ -67,6 +67,18 @@
> >  			clock-frequency = <32768>;
> >  			#clock-cells = <0>;
> >  		};
> >+
> >+		sfpb_mutex_block: syscon at 01200600 {
> 
> I think you can drop the leading 0 here. Also this should be moved into the
> soc node.
> 
> >+			compatible = "syscon";
> >+			reg = <0x01200600 0x100>;
> >+		};
> >+
> >+		sfpb_mutex: sfpb-mutex {
> >+			compatible = "qcom,sfpb-mutex";
> >+			syscon = <&sfpb_mutex_block 4 4>;
> >+
> >+			#hwlock-cells = <1>;
> >+		};
> 
> And this node should be moved to the root /.
> >  	};
> >  	soc: soc {
Right; I'll repost a patch to address both of these.
> 
> 
> -- 
> Qualcomm Innovation Center, Inc. is a member of Code Aurora Forum,
> a Linux Foundation Collaborative Project
> 


From dbaryshkov at gmail.com  Fri Aug 14 10:25:45 2015
From: dbaryshkov at gmail.com (Dmitry Eremin-Solenikov)
Date: Fri, 14 Aug 2015 20:25:45 +0300
Subject: [RFT PATCH] arm: collie_defconfig: convert to use libata PATA
 drivers
In-Reply-To: <1439571876-13758-6-git-send-email-b.zolnierkie@samsung.com>
References: <1439571876-13758-1-git-send-email-b.zolnierkie@samsung.com>
 <1439571876-13758-6-git-send-email-b.zolnierkie@samsung.com>
Message-ID: <CALT56yO0Z3hs4CGAmT_Qtpc8482cUzK_GMROjQ=_4+rOJs0TBw@mail.gmail.com>

2015-08-14 20:04 GMT+03:00 Bartlomiej Zolnierkiewicz <b.zolnierkie at samsung.com>:
> IDE subsystem has been deprecated since 2009 and the majority
> (if not all) of Linux distributions have switched to use
> libata for ATA support exclusively.  However there are still
> some users (mostly old or/and embedded non-x86 systems) that
> have not converted from using IDE subsystem to libata PATA
> drivers.  This doesn't seem to be good thing in the long-term
> for Linux as while there is less and less PATA systems left
> in use:
>
> * testing efforts are divided between two subsystems
>
> * having duplicate drivers for same hardware confuses users
>
> This patch converts collie_defconfig to use libata PATA
> drivers.
>
> Cc: Dmitry Eremin-Solenikov <dbaryshkov at gmail.com>
> Signed-off-by: Bartlomiej Zolnierkiewicz <b.zolnierkie at samsung.com>

Acked-by: Dmitry Eremin-Solenikov <dbaryshkov at gmail.com>


-- 
With best wishes
Dmitry


From festevam at gmail.com  Fri Aug 14 10:28:30 2015
From: festevam at gmail.com (Fabio Estevam)
Date: Fri, 14 Aug 2015 14:28:30 -0300
Subject: [PATCH v3] ARM: configs: Add Freescale LS1021A defconfig
In-Reply-To: <55CE1FFE.2080200@freescale.com>
References: <1438941784-38403-1-git-send-email-b18965@freescale.com>
 <55CB4829.40204@freescale.com> <55CE1FFE.2080200@freescale.com>
Message-ID: <CAOMZO5By_15OCsb7z2pbywPi3n9vKGj=393hWYHVEQ32=jDNaA@mail.gmail.com>

On Fri, Aug 14, 2015 at 2:06 PM, Horia Geant?
<horia.geanta at freescale.com> wrote:

> Another thing:
> Commit 385c0fb0e2c4 ("ARM: imx_v6_v7_defconfig: Select LS1021A") added
> CONFIG_SOC_LS1021A in imx_v6_v7_defconfig.
>
> Besides this, booting a LS1021 AQDS board (Rev2) using
> imx_v6_v7_defconfig did not work (stuck at "Starting kernel").

What would be the recommended approach?

- Fix imx_v6_v7_defconfig so that it can make LS1021A to boot

or

- Use this proposed ls1021a_defconfig and remove LS1021A from
imx_v6_v7_defconfig?

Regards,

Fabio Estevam


From matthias.bgg at gmail.com  Fri Aug 14 10:37:13 2015
From: matthias.bgg at gmail.com (Matthias Brugger)
Date: Fri, 14 Aug 2015 19:37:13 +0200
Subject: [PATCH] ARM: rockchip: pm: Fix PTR_ERR() argument
In-Reply-To: <1439520199-16076-1-git-send-email-festevam@gmail.com>
References: <1439520199-16076-1-git-send-email-festevam@gmail.com>
Message-ID: <1447521.3N0AVjqGBX@ubix>

On Thursday, August 13, 2015 11:43:19 PM Fabio Estevam wrote:
> From: Fabio Estevam <fabio.estevam at freescale.com>
> 
> PTR_ERR should access the value just tested by IS_ERR.
> 
> The semantic patch that makes this change is available
> in scripts/coccinelle/tests/odd_ptr_err.cocci.
> 
> Signed-off-by: Fabio Estevam <fabio.estevam at freescale.com>
> ---

Reviewed-by: Matthias Brugger <matthias.bgg at gmail.com>

>  arch/arm/mach-rockchip/pm.c | 4 ++--
>  1 file changed, 2 insertions(+), 2 deletions(-)
> 
> diff --git a/arch/arm/mach-rockchip/pm.c b/arch/arm/mach-rockchip/pm.c
> index 892bace..01123dd 100644
> --- a/arch/arm/mach-rockchip/pm.c
> +++ b/arch/arm/mach-rockchip/pm.c
> @@ -224,14 +224,14 @@ static int rk3288_suspend_init(struct device_node *np)
> "rockchip,rk3288-sgrf");
>  	if (IS_ERR(sgrf_regmap)) {
>  		pr_err("%s: could not find sgrf regmap\n", __func__);
> -		return PTR_ERR(pmu_regmap);
> +		return PTR_ERR(sgrf_regmap);
>  	}
> 
>  	grf_regmap = syscon_regmap_lookup_by_compatible(
>  				"rockchip,rk3288-grf");
>  	if (IS_ERR(grf_regmap)) {
>  		pr_err("%s: could not find grf regmap\n", __func__);
> -		return PTR_ERR(pmu_regmap);
> +		return PTR_ERR(grf_regmap);
>  	}
> 
>  	sram_np = of_find_compatible_node(NULL, NULL,



From linux at arm.linux.org.uk  Fri Aug 14 10:43:30 2015
From: linux at arm.linux.org.uk (Russell King - ARM Linux)
Date: Fri, 14 Aug 2015 18:43:30 +0100
Subject: [PATCH] arm: footbridge_defconfig: disable IDE subsystem
In-Reply-To: <1439571876-13758-8-git-send-email-b.zolnierkie@samsung.com>
References: <1439571876-13758-1-git-send-email-b.zolnierkie@samsung.com>
 <1439571876-13758-8-git-send-email-b.zolnierkie@samsung.com>
Message-ID: <20150814174330.GY7557@n2100.arm.linux.org.uk>

On Fri, Aug 14, 2015 at 07:04:23PM +0200, Bartlomiej Zolnierkiewicz wrote:
> This patch disables deprecated IDE subsystem in footbridge_defconfig
> (no IDE host drivers are selected in this config so there is no valid
> reason to enable IDE subsystem itself).

That's actually incorrect.  I use IDE on Footbridge because it works
loads with my CY82C693 board.  I never submitted the patches which make
CY82C693 work on ARM though...

However, the CY82C693 must not be allowed to use DMA (which is why the
ATA driver can't be used) - if it does, it locks the PCI bus.  It's
a hardware incompatibility between some PCI devices and the Footbridge.

-- 
FTTC broadband for 0.8mile line: currently at 10.5Mbps down 400kbps up
according to speedtest.net.


From catalin.marinas at arm.com  Fri Aug 14 10:43:41 2015
From: catalin.marinas at arm.com (Catalin Marinas)
Date: Fri, 14 Aug 2015 18:43:41 +0100
Subject: [PATCH v2 1/2] ARM: dma-mapping: Don't use outer_flush_range
 when the L2C is coherent
In-Reply-To: <1439568776-17864-2-git-send-email-gregory.clement@free-electrons.com>
References: <1439568776-17864-1-git-send-email-gregory.clement@free-electrons.com>
 <1439568776-17864-2-git-send-email-gregory.clement@free-electrons.com>
Message-ID: <20150814174340.GA21966@e104818-lin.cambridge.arm.com>

On Fri, Aug 14, 2015 at 06:12:55PM +0200, Gregory CLEMENT wrote:
> When a L2 cache controller is used in a system that provides hardware
> coherency, the entire outer cache operations are useless, and can be
> skipped.  Moreover, on some systems, it is harmful as it causes
> deadlocks between the Marvell coherency mechanism, the Marvell PCIe
> controller and the Cortex-A9.
> 
> In the current kernel implementation, the outer cache flush range
> operation is triggered by the dma_alloc function.
> This operation can be take place during runtime and in some
> circumstances may lead to the PCIe/PL310 deadlock on Armada 375/38x
> SoCs.
> 
> This patch extends the __dma_clear_buffer() function to receive a
> boolean argument related to the coherency of the system. The same
> things is done for the calling functions.
> 
> Reported-by: Nadav Haklai <nadavh at marvell.com>
> Signed-off-by: Gregory CLEMENT <gregory.clement at free-electrons.com>
> Cc: <stable at vger.kernel.org> # v3.16+

Most likely the patch won't apply on kernels before 4.3. But that's
fine, you can send separate patches to stable that work on those kernels
and reference the mainline commit.

> @@ -358,9 +364,14 @@ static int __init atomic_pool_init(void)
>  	if (!atomic_pool)
>  		goto out;
>  
> +	/*
> +	 * Here we don't know if the system is coherent, but it is
> +	 * harmless to use the non-coherent case in the
> +	 * __alloc_from_contiguous() call.
> +	 */
>  	if (dev_get_cma_area(NULL))
>  		ptr = __alloc_from_contiguous(NULL, atomic_pool_size, prot,
> -					      &page, atomic_pool_init, true);
> +					&page, atomic_pool_init, true, false);

This comment is not entirely correct. The atomic pool is only used for
non-coherent allocations (the prot is pgprot_dmacoherent which means
Normal Non-cacheable memory). So we must pass false for is_coherent.

> @@ -474,7 +485,8 @@ static void *__alloc_remap_buffer(struct device *dev, size_t size, gfp_t gfp,
>  {
>  	struct page *page;
>  	void *ptr = NULL;
> -	page = __dma_alloc_buffer(dev, size, gfp);
> +	/* This function is only called when the arch is non-coherent */
> +	page = __dma_alloc_buffer(dev, size, gfp, false);

Nitpick: "__alloc_remap_buffer() is only called when the arch is
non-coherent". That's to avoid misreading as __dma_alloc_buffer() being
called only for non-coherent cases.

BTW, for other comments as well, instead of "arch" being coherent or not
I would say "device". We check this property on a per-device basis.

> @@ -601,7 +614,8 @@ static void *__alloc_simple_buffer(struct device *dev, size_t size, gfp_t gfp,
>  				   struct page **ret_page)
>  {
>  	struct page *page;
> -	page = __dma_alloc_buffer(dev, size, gfp);
> +	/* This function is only called when the arch is coherent */
> +	page = __dma_alloc_buffer(dev, size, gfp, true);

Same nitpick as above, "__alloc_simple_buffer() is only called...".

Few minor things above on comments, otherwise:

Reviewed-by: Catalin Marinas <catalin.marinas at arm.com>


From catalin.marinas at arm.com  Fri Aug 14 10:55:06 2015
From: catalin.marinas at arm.com (Catalin Marinas)
Date: Fri, 14 Aug 2015 18:55:06 +0100
Subject: [PATCH v2 2/2] ARM: dma-mapping: Fix the coherent case when
 iommu is used
In-Reply-To: <1439568776-17864-3-git-send-email-gregory.clement@free-electrons.com>
References: <1439568776-17864-1-git-send-email-gregory.clement@free-electrons.com>
 <1439568776-17864-3-git-send-email-gregory.clement@free-electrons.com>
Message-ID: <20150814175505.GB21966@e104818-lin.cambridge.arm.com>

On Fri, Aug 14, 2015 at 06:12:56PM +0200, Gregory CLEMENT wrote:
> When doing dma allocation with IOMMU the __iommu_alloc_atomic() was
> used even when the system was coherent. However, this function
> allocates from a non-cacheable pool, which is fine when the device is
> not cache coherent but won't work as expected in the device is cache
> coherent. Indeed, the CPU and device must access the memory using the
> same cacheability attributes.
> 
> Tested-by: We need someone here

And at least a build on your side ;).

Rob Herring added the coherent IOMMU ops in commit 0fa478df444f ("ARM:
add coherent iommu dma ops"). But it doesn't look like he needed the
coherent DMA API, only the streaming one.

> @@ -1885,7 +1903,7 @@ struct dma_map_ops iommu_ops = {
>  };
>  
>  struct dma_map_ops iommu_coherent_ops = {
> -	.alloc		= arm_iommu_alloc_attrs,
> +	.alloc		= arm_coherent_iommu_alloc_attrs,
>  	.free		= arm_iommu_free_attrs,

Does this compile? You renamed arm_iommu_free_attrs to
__arm_iommu_alloc_attrs but I don't see arm_iommu_free_attrs
and arm_coherent_iommu_free_attrs functions.

>  	.mmap		= arm_iommu_mmap_attrs,

And we need an arm_coherent_iommu_mmap_attrs (similar to
arm_iommu_mmap_attrs but without __get_dma_pgprot. Use
arm_(coherent_)dma_mmap as an example.

-- 
Catalin


From b.zolnierkie at samsung.com  Fri Aug 14 11:08:13 2015
From: b.zolnierkie at samsung.com (Bartlomiej Zolnierkiewicz)
Date: Fri, 14 Aug 2015 20:08:13 +0200
Subject: [PATCH] arm: footbridge_defconfig: disable IDE subsystem
In-Reply-To: <20150814174330.GY7557@n2100.arm.linux.org.uk>
References: <1439571876-13758-1-git-send-email-b.zolnierkie@samsung.com>
 <1439571876-13758-8-git-send-email-b.zolnierkie@samsung.com>
 <20150814174330.GY7557@n2100.arm.linux.org.uk>
Message-ID: <4667234.QqV6GaKOSx@amdc1976>


Hi,

On Friday, August 14, 2015 06:43:30 PM Russell King - ARM Linux wrote:
> On Fri, Aug 14, 2015 at 07:04:23PM +0200, Bartlomiej Zolnierkiewicz wrote:
> > This patch disables deprecated IDE subsystem in footbridge_defconfig
> > (no IDE host drivers are selected in this config so there is no valid
> > reason to enable IDE subsystem itself).
> 
> That's actually incorrect.  I use IDE on Footbridge because it works
> loads with my CY82C693 board.  I never submitted the patches which make
> CY82C693 work on ARM though...
> 
> However, the CY82C693 must not be allowed to use DMA (which is why the
> ATA driver can't be used) - if it does, it locks the PCI bus.  It's
> a hardware incompatibility between some PCI devices and the Footbridge.

PATA driver is the same in this regard as IDE one.  They both try to
use DMA if supported by a device.  Would be great if you could fix
them (or at least PATA one) to limit your setup to PIO automatically
(please also note that you can limit libata to PIO manually these
days).

When it comes to CY82C693 there is also a leftover issue with PATA
driver that it only supports primary interface currently (BTW this is
why I left Alpha's defconfig alone for now - it uses CY82C693).  I can
look into fixing this (or assist in this work) if you are interested
in it.

Best regards,
--
Bartlomiej Zolnierkiewicz
Samsung R&D Institute Poland
Samsung Electronics



From rric at kernel.org  Fri Aug 14 11:28:00 2015
From: rric at kernel.org (Robert Richter)
Date: Fri, 14 Aug 2015 20:28:00 +0200
Subject: [PATCH v4 0/5] irqchip,
 gicv3: Updates and Cavium ThunderX errata workarounds
Message-ID: <1439576885-15621-1-git-send-email-rric@kernel.org>

From: Robert Richter <rrichter at cavium.com>

This patch series adds gicv3 updates and workarounds for HW errata in
Cavium's ThunderX GICV3.

The first one is an unchanged resubmission of a patch from a gicv3
series I sent a while ago.

The next patches implement the workarounds for ThunderX's gicv3. Patch
#2 implements the cpu workaround for gicv3 on ThunderX. Patch #3 is a
prerequisit for patch #5. Patch #4 adds generic code to parse the hw
revision provided by an IIDR. This patch is used for the implementa-
tion of the actual gicv3-its workaround in #5.

All current review comments addressed so far with v4.

v4:
 * simplify code to only use cpus_have_cap() in gicv3_enable_quirks()
 * only enable hw detection for its in its_enable_quirks()
 * removed gicv3_check_capabilities()
 * drop special cpu capability for zero

v3:
 * use arm64 errata framework for midr check
 * fix mixup of errata to be dependend from midr/iidr

v2:
 * Workaround for 23154:
   * implement code in a single asm() to keep instruction sequence
   * added comment to the code that explains the erratum
   * apply workaround also if running as guest, thus check MIDR
 * adding MIDR check

Robert Richter (5):
  irqchip, gicv3-its: Add range check for number of allocated pages
  irqchip, gicv3: Workaround for Cavium ThunderX erratum 23154
  irqchip, gicv3-its: Read typer register outside the loop
  irqchip, gicv3-its: Add HW revision detection and configuration
  irqchip, gicv3-its: Workaround for Cavium ThunderX errata 22375, 24313

 arch/arm64/Kconfig                  | 11 +++++++
 arch/arm64/include/asm/cpufeature.h |  3 +-
 arch/arm64/include/asm/cputype.h    | 18 ++++++-----
 arch/arm64/kernel/cpu_errata.c      |  9 ++++++
 drivers/irqchip/irq-gic-common.c    | 11 +++++++
 drivers/irqchip/irq-gic-common.h    |  9 ++++++
 drivers/irqchip/irq-gic-v3-its.c    | 62 +++++++++++++++++++++++++++++++++----
 drivers/irqchip/irq-gic-v3.c        | 42 ++++++++++++++++++++++++-
 include/linux/irqchip/arm-gic-v3.h  |  1 +
 9 files changed, 151 insertions(+), 15 deletions(-)

-- 
2.1.1



From rric at kernel.org  Fri Aug 14 11:28:01 2015
From: rric at kernel.org (Robert Richter)
Date: Fri, 14 Aug 2015 20:28:01 +0200
Subject: [PATCH v4 1/5] irqchip,
 gicv3-its: Add range check for number of allocated pages
In-Reply-To: <1439576885-15621-1-git-send-email-rric@kernel.org>
References: <1439576885-15621-1-git-send-email-rric@kernel.org>
Message-ID: <1439576885-15621-2-git-send-email-rric@kernel.org>

From: Robert Richter <rrichter at cavium.com>

The number of pages for the its table may exceed the maximum of 256.
Adding a range check and limitting the number to its maximum.

Based on a patch from Tirumalesh Chalamarla <tchalamarla at cavium.com>.

Signed-off-by: Tirumalesh Chalamarla <tchalamarla at cavium.com>
Reviewed-by: Marc Zyngier <marc.zyngier at arm.com>
Signed-off-by: Robert Richter <rrichter at cavium.com>
---
 drivers/irqchip/irq-gic-v3-its.c   | 11 ++++++++++-
 include/linux/irqchip/arm-gic-v3.h |  1 +
 2 files changed, 11 insertions(+), 1 deletion(-)

diff --git a/drivers/irqchip/irq-gic-v3-its.c b/drivers/irqchip/irq-gic-v3-its.c
index 1b7e155869f6..466edf8a7477 100644
--- a/drivers/irqchip/irq-gic-v3-its.c
+++ b/drivers/irqchip/irq-gic-v3-its.c
@@ -810,6 +810,7 @@ static int its_alloc_tables(struct its_node *its)
 		u64 entry_size = GITS_BASER_ENTRY_SIZE(val);
 		int order = get_order(psz);
 		int alloc_size;
+		int alloc_pages;
 		u64 tmp;
 		void *base;
 
@@ -844,6 +845,14 @@ static int its_alloc_tables(struct its_node *its)
 		}
 
 		alloc_size = (1 << order) * PAGE_SIZE;
+		alloc_pages = (alloc_size / psz);
+		if (alloc_pages > GITS_BASER_PAGES_MAX) {
+			alloc_pages = GITS_BASER_PAGES_MAX;
+			order = get_order(GITS_BASER_PAGES_MAX * psz);
+			pr_warn("%s: Device Table too large, reduce its page order to %u (%u pages)\n",
+				its->msi_chip.of_node->full_name, order, alloc_pages);
+		}
+
 		base = (void *)__get_free_pages(GFP_KERNEL | __GFP_ZERO, order);
 		if (!base) {
 			err = -ENOMEM;
@@ -872,7 +881,7 @@ static int its_alloc_tables(struct its_node *its)
 			break;
 		}
 
-		val |= (alloc_size / psz) - 1;
+		val |= alloc_pages - 1;
 
 		writeq_relaxed(val, its->base + GITS_BASER + i * 8);
 		tmp = readq_relaxed(its->base + GITS_BASER + i * 8);
diff --git a/include/linux/irqchip/arm-gic-v3.h b/include/linux/irqchip/arm-gic-v3.h
index ffbc034c8810..f28da189c4aa 100644
--- a/include/linux/irqchip/arm-gic-v3.h
+++ b/include/linux/irqchip/arm-gic-v3.h
@@ -229,6 +229,7 @@
 #define GITS_BASER_PAGE_SIZE_16K	(1UL << GITS_BASER_PAGE_SIZE_SHIFT)
 #define GITS_BASER_PAGE_SIZE_64K	(2UL << GITS_BASER_PAGE_SIZE_SHIFT)
 #define GITS_BASER_PAGE_SIZE_MASK	(3UL << GITS_BASER_PAGE_SIZE_SHIFT)
+#define GITS_BASER_PAGES_MAX		256
 
 #define GITS_BASER_TYPE_NONE		0
 #define GITS_BASER_TYPE_DEVICE		1
-- 
2.1.1



From rric at kernel.org  Fri Aug 14 11:28:02 2015
From: rric at kernel.org (Robert Richter)
Date: Fri, 14 Aug 2015 20:28:02 +0200
Subject: [PATCH v4 2/5] irqchip,
 gicv3: Workaround for Cavium ThunderX erratum 23154
In-Reply-To: <1439576885-15621-1-git-send-email-rric@kernel.org>
References: <1439576885-15621-1-git-send-email-rric@kernel.org>
Message-ID: <1439576885-15621-3-git-send-email-rric@kernel.org>

From: Robert Richter <rrichter at cavium.com>

This patch implements Cavium ThunderX erratum 23154.

The gicv3 of ThunderX requires a modified version for reading the IAR
status to ensure data synchronization. Since this is in the fast-path
and called with each interrupt, runtime patching is used using jump
label patching for smallest overhead (no-op). This is the same
technique as used for tracepoints.

v4:
 * simplify code to only use cpus_have_cap() in gicv3_enable_quirks()

v3:
 * fix erratum to be dependend from midr
 * use arm64 errata framework

v2:
 * implement code in a single asm() to keep instruction sequence
 * added comment to the code that explains the erratum
 * apply workaround also if running as guest, thus check MIDR

Signed-off-by: Robert Richter <rrichter at cavium.com>
---
 arch/arm64/Kconfig                  | 11 ++++++++++
 arch/arm64/include/asm/cpufeature.h |  3 ++-
 arch/arm64/include/asm/cputype.h    | 18 +++++++++-------
 arch/arm64/kernel/cpu_errata.c      |  9 ++++++++
 drivers/irqchip/irq-gic-v3.c        | 42 ++++++++++++++++++++++++++++++++++++-
 5 files changed, 74 insertions(+), 9 deletions(-)

diff --git a/arch/arm64/Kconfig b/arch/arm64/Kconfig
index 0f6edb14b7e4..4f866a4c6536 100644
--- a/arch/arm64/Kconfig
+++ b/arch/arm64/Kconfig
@@ -417,6 +417,17 @@ config ARM64_ERRATUM_845719
 
 	  If unsure, say Y.
 
+config CAVIUM_ERRATUM_23154
+	bool "Cavium erratum 23154: Access to ICC_IAR1_EL1 is not sync'ed"
+	depends on ARCH_THUNDER
+	default y
+	help
+	  The gicv3 of ThunderX requires a modified version for
+	  reading the IAR status to ensure data synchronization
+	  (access to icc_iar1_el1 is not sync'ed before and after).
+
+	  If unsure, say Y.
+
 endmenu
 
 
diff --git a/arch/arm64/include/asm/cpufeature.h b/arch/arm64/include/asm/cpufeature.h
index c1044218a63a..2a5e4c163ee5 100644
--- a/arch/arm64/include/asm/cpufeature.h
+++ b/arch/arm64/include/asm/cpufeature.h
@@ -25,8 +25,9 @@
 #define ARM64_WORKAROUND_DEVICE_LOAD_ACQUIRE	1
 #define ARM64_WORKAROUND_845719			2
 #define ARM64_HAS_SYSREG_GIC_CPUIF		3
+#define ARM64_WORKAROUND_CAVIUM_23154		4
 
-#define ARM64_NCAPS				4
+#define ARM64_NCAPS				5
 
 #ifndef __ASSEMBLY__
 
diff --git a/arch/arm64/include/asm/cputype.h b/arch/arm64/include/asm/cputype.h
index a84ec605bed8..3f0c7683f252 100644
--- a/arch/arm64/include/asm/cputype.h
+++ b/arch/arm64/include/asm/cputype.h
@@ -62,15 +62,19 @@
 	(0xf			<< MIDR_ARCHITECTURE_SHIFT) | \
 	((partnum)		<< MIDR_PARTNUM_SHIFT))
 
-#define ARM_CPU_IMP_ARM		0x41
-#define ARM_CPU_IMP_APM		0x50
+#define ARM_CPU_IMP_ARM			0x41
+#define ARM_CPU_IMP_APM			0x50
+#define ARM_CPU_IMP_CAVIUM		0x43
 
-#define ARM_CPU_PART_AEM_V8	0xD0F
-#define ARM_CPU_PART_FOUNDATION	0xD00
-#define ARM_CPU_PART_CORTEX_A57	0xD07
-#define ARM_CPU_PART_CORTEX_A53	0xD03
+#define ARM_CPU_PART_AEM_V8		0xD0F
+#define ARM_CPU_PART_FOUNDATION		0xD00
+#define ARM_CPU_PART_CORTEX_A57		0xD07
+#define ARM_CPU_PART_CORTEX_A53		0xD03
+
+#define APM_CPU_PART_POTENZA		0x000
+
+#define CAVIUM_CPU_PART_THUNDERX	0x0A1
 
-#define APM_CPU_PART_POTENZA	0x000
 
 #define ID_AA64MMFR0_BIGENDEL0_SHIFT	16
 #define ID_AA64MMFR0_BIGENDEL0_MASK	(0xf << ID_AA64MMFR0_BIGENDEL0_SHIFT)
diff --git a/arch/arm64/kernel/cpu_errata.c b/arch/arm64/kernel/cpu_errata.c
index 6ffd91438560..574450c257a4 100644
--- a/arch/arm64/kernel/cpu_errata.c
+++ b/arch/arm64/kernel/cpu_errata.c
@@ -23,6 +23,7 @@
 
 #define MIDR_CORTEX_A53 MIDR_CPU_PART(ARM_CPU_IMP_ARM, ARM_CPU_PART_CORTEX_A53)
 #define MIDR_CORTEX_A57 MIDR_CPU_PART(ARM_CPU_IMP_ARM, ARM_CPU_PART_CORTEX_A57)
+#define MIDR_THUNDERX	MIDR_CPU_PART(ARM_CPU_IMP_CAVIUM, CAVIUM_CPU_PART_THUNDERX)
 
 #define CPU_MODEL_MASK (MIDR_IMPLEMENTOR_MASK | MIDR_PARTNUM_MASK | \
 			MIDR_ARCHITECTURE_MASK)
@@ -82,6 +83,14 @@ const struct arm64_cpu_capabilities arm64_errata[] = {
 		MIDR_RANGE(MIDR_CORTEX_A53, 0x00, 0x04),
 	},
 #endif
+#ifdef CONFIG_CAVIUM_ERRATUM_23154
+	{
+	/* Cavium ThunderX, pass 1.x */
+		.desc = "Cavium erratum 23154",
+		.capability = ARM64_WORKAROUND_CAVIUM_23154,
+		MIDR_RANGE(MIDR_THUNDERX, 0x00, 0x01),
+	},
+#endif
 	{
 	}
 };
diff --git a/drivers/irqchip/irq-gic-v3.c b/drivers/irqchip/irq-gic-v3.c
index c52f7ba205b4..4211c39b8744 100644
--- a/drivers/irqchip/irq-gic-v3.c
+++ b/drivers/irqchip/irq-gic-v3.c
@@ -107,7 +107,7 @@ static void gic_redist_wait_for_rwp(void)
 }
 
 /* Low level accessors */
-static u64 __maybe_unused gic_read_iar(void)
+static u64 gic_read_iar_common(void)
 {
 	u64 irqstat;
 
@@ -115,6 +115,38 @@ static u64 __maybe_unused gic_read_iar(void)
 	return irqstat;
 }
 
+/*
+ * Cavium ThunderX erratum 23154
+ *
+ * The gicv3 of ThunderX requires a modified version for reading the
+ * IAR status to ensure data synchronization (access to icc_iar1_el1
+ * is not sync'ed before and after).
+ */
+static u64 gic_read_iar_cavium_thunderx(void)
+{
+	u64 irqstat;
+
+	asm volatile(
+		"nop;nop;nop;nop\n\t"
+		"nop;nop;nop;nop\n\t"
+		"mrs_s %0, " __stringify(ICC_IAR1_EL1) "\n\t"
+		"nop;nop;nop;nop"
+		: "=r" (irqstat));
+	mb();
+
+	return irqstat;
+}
+
+struct static_key is_cavium_thunderx = STATIC_KEY_INIT_FALSE;
+
+static u64 __maybe_unused gic_read_iar(void)
+{
+	if (static_key_false(&is_cavium_thunderx))
+		return gic_read_iar_common();
+	else
+		return gic_read_iar_cavium_thunderx();
+}
+
 static void __maybe_unused gic_write_pmr(u64 val)
 {
 	asm volatile("msr_s " __stringify(ICC_PMR_EL1) ", %0" : : "r" (val));
@@ -766,6 +798,12 @@ static const struct irq_domain_ops gic_irq_domain_ops = {
 	.free = gic_irq_domain_free,
 };
 
+static void gicv3_enable_quirks(void)
+{
+	if (cpus_have_cap(ARM64_WORKAROUND_CAVIUM_23154))
+		static_key_slow_inc(&is_cavium_thunderx);
+}
+
 static int __init gic_of_init(struct device_node *node, struct device_node *parent)
 {
 	void __iomem *dist_base;
@@ -825,6 +863,8 @@ static int __init gic_of_init(struct device_node *node, struct device_node *pare
 	gic_data.nr_redist_regions = nr_redist_regions;
 	gic_data.redist_stride = redist_stride;
 
+	gicv3_enable_quirks();
+
 	/*
 	 * Find out how many interrupts are supported.
 	 * The GIC only supports up to 1020 interrupt sources (SGI+PPI+SPI)
-- 
2.1.1



From rric at kernel.org  Fri Aug 14 11:28:03 2015
From: rric at kernel.org (Robert Richter)
Date: Fri, 14 Aug 2015 20:28:03 +0200
Subject: [PATCH v4 3/5] irqchip,
 gicv3-its: Read typer register outside the loop
In-Reply-To: <1439576885-15621-1-git-send-email-rric@kernel.org>
References: <1439576885-15621-1-git-send-email-rric@kernel.org>
Message-ID: <1439576885-15621-4-git-send-email-rric@kernel.org>

From: Robert Richter <rrichter at cavium.com>

No need to read the typer register in the loop. Values do not change.

This patch is basically a prerequisite for a follow-on patch that adds
errata code for Cavium ThunderX. It moves the calculation of the
number of id entries to the beginning of the function close to other
setup values that are needed to allocate the its table. Now we have a
central location to modify the setup parameters and the errata code
can be implemented in a single block.

Acked-by: Marc Zyngier <marc.zyngier at arm.com>
Signed-off-by: Robert Richter <rrichter at cavium.com>
---
 drivers/irqchip/irq-gic-v3-its.c | 5 ++---
 1 file changed, 2 insertions(+), 3 deletions(-)

diff --git a/drivers/irqchip/irq-gic-v3-its.c b/drivers/irqchip/irq-gic-v3-its.c
index 466edf8a7477..06131db7a198 100644
--- a/drivers/irqchip/irq-gic-v3-its.c
+++ b/drivers/irqchip/irq-gic-v3-its.c
@@ -803,6 +803,8 @@ static int its_alloc_tables(struct its_node *its)
 	int psz = SZ_64K;
 	u64 shr = GITS_BASER_InnerShareable;
 	u64 cache = GITS_BASER_WaWb;
+	u64 typer = readq_relaxed(its->base + GITS_TYPER);
+	u32 ids = GITS_TYPER_DEVBITS(typer);
 
 	for (i = 0; i < GITS_BASER_NR_REGS; i++) {
 		u64 val = readq_relaxed(its->base + GITS_BASER + i * 8);
@@ -826,9 +828,6 @@ static int its_alloc_tables(struct its_node *its)
 		 * For other tables, only allocate a single page.
 		 */
 		if (type == GITS_BASER_TYPE_DEVICE) {
-			u64 typer = readq_relaxed(its->base + GITS_TYPER);
-			u32 ids = GITS_TYPER_DEVBITS(typer);
-
 			/*
 			 * 'order' was initialized earlier to the default page
 			 * granule of the the ITS.  We can't have an allocation
-- 
2.1.1



From rric at kernel.org  Fri Aug 14 11:28:04 2015
From: rric at kernel.org (Robert Richter)
Date: Fri, 14 Aug 2015 20:28:04 +0200
Subject: [PATCH v4 4/5] irqchip,
 gicv3-its: Add HW revision detection and configuration
In-Reply-To: <1439576885-15621-1-git-send-email-rric@kernel.org>
References: <1439576885-15621-1-git-send-email-rric@kernel.org>
Message-ID: <1439576885-15621-5-git-send-email-rric@kernel.org>

From: Robert Richter <rrichter at cavium.com>

Some GIC revisions require an individual configuration to esp. add
workarounds for HW bugs. This patch implements generic code to parse
the hw revision provided by an IIDR register value and runs specific
code if hw matches. There are functions that read the IIDR registers
for GICV3 and ITS (GICD_IIDR/GITS_IIDR) and then go through a list of
init functions to be called for specific versions.

A MIDR register value may also be used, this is especially useful for
hw detection from a guest.

The patch is needed to implement workarounds for HW errata in Cavium's
ThunderX GICV3.

v4:
 * only enable hw detection for its in its_enable_quirks()
 * removed gicv3_check_capabilities()

v3:
 * use arm64 errata framework for midr check

v2:
 * adding MIDR check

Signed-off-by: Robert Richter <rrichter at cavium.com>
---
 drivers/irqchip/irq-gic-common.c | 11 +++++++++++
 drivers/irqchip/irq-gic-common.h |  9 +++++++++
 drivers/irqchip/irq-gic-v3-its.c | 15 +++++++++++++++
 3 files changed, 35 insertions(+)

diff --git a/drivers/irqchip/irq-gic-common.c b/drivers/irqchip/irq-gic-common.c
index 9448e391cb71..ee789b07f2d1 100644
--- a/drivers/irqchip/irq-gic-common.c
+++ b/drivers/irqchip/irq-gic-common.c
@@ -21,6 +21,17 @@
 
 #include "irq-gic-common.h"
 
+void gic_check_capabilities(u32 iidr, const struct gic_capabilities *cap,
+			void *data)
+{
+	for (; cap->desc; cap++) {
+		if (cap->iidr != (cap->mask & iidr))
+			continue;
+		cap->init(data);
+		pr_info("%s\n", cap->desc);
+	}
+}
+
 int gic_configure_irq(unsigned int irq, unsigned int type,
 		       void __iomem *base, void (*sync_access)(void))
 {
diff --git a/drivers/irqchip/irq-gic-common.h b/drivers/irqchip/irq-gic-common.h
index 35a9884778bd..ca12635bbe3c 100644
--- a/drivers/irqchip/irq-gic-common.h
+++ b/drivers/irqchip/irq-gic-common.h
@@ -20,10 +20,19 @@
 #include <linux/of.h>
 #include <linux/irqdomain.h>
 
+struct gic_capabilities {
+	const char *desc;
+	void (*init)(void *data);
+	u32 iidr;
+	u32 mask;
+};
+
 int gic_configure_irq(unsigned int irq, unsigned int type,
                        void __iomem *base, void (*sync_access)(void));
 void gic_dist_config(void __iomem *base, int gic_irqs,
 		     void (*sync_access)(void));
 void gic_cpu_config(void __iomem *base, void (*sync_access)(void));
+void gic_check_capabilities(u32 iidr, const struct gic_capabilities *cap,
+			void *data);
 
 #endif /* _IRQ_GIC_COMMON_H */
diff --git a/drivers/irqchip/irq-gic-v3-its.c b/drivers/irqchip/irq-gic-v3-its.c
index 06131db7a198..697421e834ee 100644
--- a/drivers/irqchip/irq-gic-v3-its.c
+++ b/drivers/irqchip/irq-gic-v3-its.c
@@ -36,6 +36,7 @@
 #include <asm/cputype.h>
 #include <asm/exception.h>
 
+#include "irq-gic-common.h"
 #include "irqchip.h"
 
 #define ITS_FLAGS_CMDQ_NEEDS_FLUSHING		(1 << 0)
@@ -1390,6 +1391,18 @@ static int its_force_quiescent(void __iomem *base)
 	}
 }
 
+static const struct gic_capabilities its_errata[] = {
+	{
+	}
+};
+
+static void its_enable_quirks(struct its_node *its)
+{
+	u32 iidr = readl_relaxed(its->base + GITS_IIDR);
+
+	gic_check_capabilities(iidr, its_errata, its);
+}
+
 static int its_probe(struct device_node *node, struct irq_domain *parent)
 {
 	struct resource res;
@@ -1448,6 +1461,8 @@ static int its_probe(struct device_node *node, struct irq_domain *parent)
 	}
 	its->cmd_write = its->cmd_base;
 
+	its_enable_quirks(its);
+
 	err = its_alloc_tables(its);
 	if (err)
 		goto out_free_cmd;
-- 
2.1.1



From rric at kernel.org  Fri Aug 14 11:28:05 2015
From: rric at kernel.org (Robert Richter)
Date: Fri, 14 Aug 2015 20:28:05 +0200
Subject: [PATCH v4 5/5] irqchip,
 gicv3-its: Workaround for Cavium ThunderX errata 22375, 24313
In-Reply-To: <1439576885-15621-1-git-send-email-rric@kernel.org>
References: <1439576885-15621-1-git-send-email-rric@kernel.org>
Message-ID: <1439576885-15621-6-git-send-email-rric@kernel.org>

From: Robert Richter <rrichter at cavium.com>

This implements two gicv3-its errata workarounds for ThunderX. Both
with small impact affecting only ITS table allocation.

 erratum 22375: only alloc 8MB table size
 erratum 24313: ignore memory access type

The fixes are in ITS initialization and basically ignore memory access
type and table size provided by the TYPER and BASER registers.

v3:
 * fix erratum to be dependend from iidr

Signed-off-by: Robert Richter <rrichter at cavium.com>
---
 drivers/irqchip/irq-gic-v3-its.c | 35 +++++++++++++++++++++++++++++++----
 1 file changed, 31 insertions(+), 4 deletions(-)

diff --git a/drivers/irqchip/irq-gic-v3-its.c b/drivers/irqchip/irq-gic-v3-its.c
index 697421e834ee..30459df2ee2c 100644
--- a/drivers/irqchip/irq-gic-v3-its.c
+++ b/drivers/irqchip/irq-gic-v3-its.c
@@ -39,7 +39,8 @@
 #include "irq-gic-common.h"
 #include "irqchip.h"
 
-#define ITS_FLAGS_CMDQ_NEEDS_FLUSHING		(1 << 0)
+#define ITS_FLAGS_CMDQ_NEEDS_FLUSHING		(1ULL << 0)
+#define ITS_FLAGS_CAVIUM_THUNDERX		(1ULL << 1)
 
 #define RDIST_FLAGS_PROPBASE_NEEDS_FLUSHING	(1 << 0)
 
@@ -803,9 +804,22 @@ static int its_alloc_tables(struct its_node *its)
 	int i;
 	int psz = SZ_64K;
 	u64 shr = GITS_BASER_InnerShareable;
-	u64 cache = GITS_BASER_WaWb;
-	u64 typer = readq_relaxed(its->base + GITS_TYPER);
-	u32 ids = GITS_TYPER_DEVBITS(typer);
+	u64 cache;
+	u64 typer;
+	u32 ids;
+
+	if (its->flags & ITS_FLAGS_CAVIUM_THUNDERX) {
+		/*
+		 * erratum 22375: only alloc 8MB table size
+		 * erratum 24313: ignore memory access type
+		 */
+		cache	= 0;
+		ids	= 0x13;			/* 20 bits, 8MB */
+	} else {
+		cache	= GITS_BASER_WaWb;
+		typer	= readq_relaxed(its->base + GITS_TYPER);
+		ids	= GITS_TYPER_DEVBITS(typer);
+	}
 
 	for (i = 0; i < GITS_BASER_NR_REGS; i++) {
 		u64 val = readq_relaxed(its->base + GITS_BASER + i * 8);
@@ -1391,8 +1405,21 @@ static int its_force_quiescent(void __iomem *base)
 	}
 }
 
+static void its_enable_cavium_thunderx(void *data)
+{
+	struct its_node *its = data;
+
+	its->flags |= ITS_FLAGS_CAVIUM_THUNDERX;
+}
+
 static const struct gic_capabilities its_errata[] = {
 	{
+		.desc	= "ITS: Cavium errata 22375, 24313",
+		.iidr	= 0xa100034c,	/* ThunderX pass 1.x */
+		.mask	= 0xffff0fff,
+		.init	= its_enable_cavium_thunderx,
+	},
+	{
 	}
 };
 
-- 
2.1.1



From eric at anholt.net  Fri Aug 14 11:29:02 2015
From: eric at anholt.net (Eric Anholt)
Date: Fri, 14 Aug 2015 11:29:02 -0700
Subject: [GIT PULL] RPi DT changes due for v4.3
In-Reply-To: <20150813103056.GY30160@localhost>
References: <20150811160642.GQ18282@x1> <20150813103056.GY30160@localhost>
Message-ID: <878u9dhggh.fsf@eliezer.anholt.net>

Olof Johansson <olof at lixom.net> writes:

> Hi,
>
> On Tue, Aug 11, 2015 at 05:06:42PM +0100, Lee Jones wrote:
>> ARM SoC Chaps,
>> 
>> Please find a couple of simple RPi changes pertaining to Firmware.
>> 
>> The following changes since commit bc0195aad0daa2ad5b0d76cce22b167bc3435590:
>> 
>>   Linux 4.2-rc2 (2015-07-12 15:10:30 -0700)
>> 
>> are available in the git repository at:
>> 
>>   git://git.kernel.org/pub/scm/linux/kernel/git/rpi/linux-rpi.git tags/rpi-dt-for-armsoc-4.3
>> 
>> for you to fetch changes up to fd26f8830979de48eb3f1c253eb9d2ee2e468eb6:
>> 
>>   dt/bindings: Add binding for the Raspberry Pi firmware driver (2015-08-11 16:56:41 +0100)
>
> I've merged this but I'm a little confused about bcm2835 maintainership:
> I got a MAINTAINERS update from Florian earlier grouped in a set of
> other bcm changes (adding Eric), and now this directly from you.
>
> In general the bcm platforms are quite diverse and we've asked Florian
> to be the funnel for all of the new ones, but I don't think we talked
> much about 2835 at that time. Should we expect to see merges directly
> from you and the other maintainers there or will it go through Florian?

I'd been talking with Arnd and Florian about the delays in RPi patch
acceptance (Stephen and Lee have limited time to dedicate to 2835), and
Florian suggested me becoming a maintainer and routing patches through
him.  He's been great to work with and has had useful feedback on my
patches.

I was kind of surprised to see Lee send this pull request -- these
patches had been sitting un-merged for 2 months and pings on irc didn't
get replies, so I thought I was stepping in where the others definitely
didn't have time.  It was also odd to see just these two patches, but
not the actual driver.

I'm willing to do the merging process for 2835, and if I'm doing so, I
like the idea of feeding it through a more experienced maintainer who's
ready to look at my pull requests whenever, without bothering the main
arm-soc folks.  My goal here, besides my actual job of getting open
source graphics working for Broadcom, is to hopefully push the rpi
foundation toward getting their code merged, so that this hardware fully
works on stock upstream.
-------------- next part --------------
A non-text attachment was scrubbed...
Name: signature.asc
Type: application/pgp-signature
Size: 818 bytes
Desc: not available
URL: <http://lists.infradead.org/pipermail/linux-arm-kernel/attachments/20150814/a6508819/attachment.sig>

From sjg at chromium.org  Fri Aug 14 11:34:41 2015
From: sjg at chromium.org (Simon Glass)
Date: Fri, 14 Aug 2015 12:34:41 -0600
Subject: [PATCH] arm: rpi: Device tree modifications for U-Boot
In-Reply-To: <CAPnjgZ3ztXnkxZJvitiXiKMzq5+x46hbv0PW4HcF7yGgsXUV+Q@mail.gmail.com>
References: <1439303153-12171-1-git-send-email-sjg@chromium.org>
 <1439312701.2451.3.camel@lynxeye.de>
 <CAPnjgZ3ztXnkxZJvitiXiKMzq5+x46hbv0PW4HcF7yGgsXUV+Q@mail.gmail.com>
Message-ID: <CAPnjgZ0hzyjy=8o8ocaGCoOC7Js4CirhystidbvtabzbhRi4RQ@mail.gmail.com>

-linux-tegra

Hi,

On 12 August 2015 at 07:21, Simon Glass <sjg at chromium.org> wrote:
> Hi Lucas,
>
> On 11 August 2015 at 11:05, Lucas Stach <dev at lynxeye.de> wrote:
>> Hi Simon,
>>
>> why did you send this to the Tegra ML?
>>
>> Am Dienstag, den 11.08.2015, 08:25 -0600 schrieb Simon Glass:
>>> This updates the device tree from the kernel version to something suitable
>>> for U-Boot:
>>>
>>> - Add stdout-path alias for console
>>> - Mark the /soc node to be available pre-relocation so that the early
>>> serial console works (we need the 'ranges' property to be available)
>>>
>>> Signed-off-by: Simon Glass <sjg at chromium.org>
>>> ---
>>>
>>>  arch/arm/boot/dts/bcm2835.dtsi | 4 +++-
>>>  1 file changed, 3 insertions(+), 1 deletion(-)
>>>
>>> diff --git a/arch/arm/boot/dts/bcm2835.dtsi b/arch/arm/boot/dts/bcm2835.dtsi
>>> index 301c73f..bd6bff6 100644
>>> --- a/arch/arm/boot/dts/bcm2835.dtsi
>>> +++ b/arch/arm/boot/dts/bcm2835.dtsi
>>> @@ -8,6 +8,7 @@
>>>
>>>       chosen {
>>>               bootargs = "earlyprintk console=ttyAMA0";
>>> +             stdout-path = &uart;
>>>       };
>>>
>>>       soc {
>>> @@ -16,6 +17,7 @@
>>>               #size-cells = <1>;
>>>               ranges = <0x7e000000 0x20000000 0x02000000>;
>>>               dma-ranges = <0x40000000 0x00000000 0x20000000>;
>>> +             u-boot,dm-pre-reloc;
>>
>> Why do you need this and why should upstream carry your favourite
>> bootloaders configuration? This is in no way hardware description.
>
> I'm not sure how much you know about U-Boot, so let me know if you
> need more info.
>
> U-Boot normally starts up by setting up its serial UART and displaying
> a banner message. At this stage typically only a few devices are
> initialised (e.g. maybe just the UART). It then relocates itself to
> the top of memory and starts up all the devices. It throws away any
> previous devices that it set up before relocation and starts again.
>
> U-Boot uses a thing called driver model (dm) which handles driver
> binding and probing. Driver model has the device tree and would
> normally scan through it and create devices for everything it finds.
>
> Before relocation we don't need every device. Also the CPU is often
> running slowly, perhaps without the cache enabled. SDRAM may not be
> available yet so space is short. We want to avoid starting up things
> that will not be used.
>
> So this property indicates that the device is needed before relocation
> and should be set up by driver model. We need it to avoid a very slow
> and memory-hungry startup.
>
> As to why upstream should accept it, my understanding of upstream is
> that people can send patches to it and in fact are encouraged to do
> so, to avoid misunderstandings and duplication. The device tree files
> are stored in Linux so any binding or source file changes should end
> up there. Otherwise the files tend to diverge and we end up with
> multiple bindings and multiple versions of the same source file.

Is the above explanation sufficient? Will this patch be applied?

Regards,
Simon


From linux at arm.linux.org.uk  Fri Aug 14 11:46:50 2015
From: linux at arm.linux.org.uk (Russell King - ARM Linux)
Date: Fri, 14 Aug 2015 19:46:50 +0100
Subject: [PATCH] arm: footbridge_defconfig: disable IDE subsystem
In-Reply-To: <4667234.QqV6GaKOSx@amdc1976>
References: <1439571876-13758-1-git-send-email-b.zolnierkie@samsung.com>
 <1439571876-13758-8-git-send-email-b.zolnierkie@samsung.com>
 <20150814174330.GY7557@n2100.arm.linux.org.uk>
 <4667234.QqV6GaKOSx@amdc1976>
Message-ID: <20150814184649.GZ7557@n2100.arm.linux.org.uk>

On Fri, Aug 14, 2015 at 08:08:13PM +0200, Bartlomiej Zolnierkiewicz wrote:
> On Friday, August 14, 2015 06:43:30 PM Russell King - ARM Linux wrote:
> > On Fri, Aug 14, 2015 at 07:04:23PM +0200, Bartlomiej Zolnierkiewicz wrote:
> > > This patch disables deprecated IDE subsystem in footbridge_defconfig
> > > (no IDE host drivers are selected in this config so there is no valid
> > > reason to enable IDE subsystem itself).
> > 
> > That's actually incorrect.  I use IDE on Footbridge because it works
> > loads with my CY82C693 board.  I never submitted the patches which make
> > CY82C693 work on ARM though...
> > 
> > However, the CY82C693 must not be allowed to use DMA (which is why the
> > ATA driver can't be used) - if it does, it locks the PCI bus.  It's
> > a hardware incompatibility between some PCI devices and the Footbridge.
> 
> PATA driver is the same in this regard as IDE one.  They both try to
> use DMA if supported by a device.  Would be great if you could fix
> them (or at least PATA one) to limit your setup to PIO automatically
> (please also note that you can limit libata to PIO manually these
> days).
> 
> When it comes to CY82C693 there is also a leftover issue with PATA
> driver that it only supports primary interface currently (BTW this is
> why I left Alpha's defconfig alone for now - it uses CY82C693).  I can
> look into fixing this (or assist in this work) if you are interested
> in it.

Well, it looks like the PCI layer has been screwed for this for some time:

cy82c693 0000:00:06.1: IDE controller (0x1080:0xc693 rev 0x00)
Cypress_IDE 0000:00:06.1: device not available (can't reserve [io  0x0170-0x0177])
Cypress_IDE 0000:00:06.1: device not available (can't reserve [io  0x0170-0x0177])
cy82c693 0000:00:06.1: couldn't enable device
Cypress_IDE: probe of 0000:00:06.1 failed with error -22

The PCI layer forces the standard legacy ports onto the Cypress device,
and then the "primary" resources get null'd out by the long-standing
CY82C693 quirk in the ARM bios32.c.

However - the ARM quick is not what causes the above - the above looks
to be caused by the generic PCI code going wrong - it adds those
legacy resources, and nothing ever connects them to the resource tree:

000000a0-000000bf : pic2
000000c0-000000df : dma2
00000213-00000213 : ISAPnP
000002f8-000002ff : serial8250.0

which then causes pci_enable_device() to fail.

I doubt CY82C693 even works on Alpha... or any IDE interface using the
legacy IO ports...  So it may take quite a bit of work to get going
again - not something I'm going to attempt prior to the 4.3 merge
window.

-- 
FTTC broadband for 0.8mile line: currently at 10.5Mbps down 400kbps up
according to speedtest.net.


From mathieu at codeaurora.org  Fri Aug 14 11:54:48 2015
From: mathieu at codeaurora.org (Mathieu Olivari)
Date: Fri, 14 Aug 2015 11:54:48 -0700
Subject: [PATCH 2/3] ARM: qcom: add SMEM device node to IPQ806x dts
In-Reply-To: <55CD2EFE.8040606@codeaurora.org>
References: <1439501620-24073-1-git-send-email-mathieu@codeaurora.org>
 <1439501620-24073-3-git-send-email-mathieu@codeaurora.org>
 <55CD2EFE.8040606@codeaurora.org>
Message-ID: <20150814185446.GB7516@codeaurora.org>

On Thu, Aug 13, 2015 at 04:57:50PM -0700, Stephen Boyd wrote:
> On 08/13/2015 02:33 PM, Mathieu Olivari wrote:
> >@@ -79,6 +79,15 @@
> >  			#hwlock-cells = <1>;
> >  		};
> >+
> >+		smem {
> >+			compatible = "qcom,smem";
> >+
> >+			memory-region = <&smem>;
> >+			reg = <0x41000000 0x4000>;
> 
> Does this reg property do something? I thought we were supposed to leave
> this out when not using the rpm msg ram. Also, if there's no reg, it should
> be at the root /.
Actually; no it doesn't do much. I'll remove it.
> 
> -- 
> Qualcomm Innovation Center, Inc. is a member of Code Aurora Forum,
> a Linux Foundation Collaborative Project
> 


From khilman at kernel.org  Fri Aug 14 11:59:31 2015
From: khilman at kernel.org (Kevin Hilman)
Date: Fri, 14 Aug 2015 11:59:31 -0700
Subject: [PATCH 9/9] ARM: smp: Add runtime PM support for CPU hotplug
In-Reply-To: <20150812204326.GM52339@linaro.org> (Lina Iyer's message of "Wed, 
 12 Aug 2015 14:43:26 -0600")
References: <1438731339-58317-1-git-send-email-lina.iyer@linaro.org>
 <1438731339-58317-10-git-send-email-lina.iyer@linaro.org>
 <7hoaicmeuh.fsf@deeprootsystems.com>
 <20150812204326.GM52339@linaro.org>
Message-ID: <7hlhdditm4.fsf@deeprootsystems.com>

Lina Iyer <lina.iyer at linaro.org> writes:

> On Wed, Aug 12 2015 at 14:28 -0600, Kevin Hilman wrote:
>>Lina Iyer <lina.iyer at linaro.org> writes:
>>
>>> Enable runtime PM for CPU devices. Do a runtime get of the CPU device
>>> when the CPU is hotplugged in and a runtime put of the CPU device when
>>> the CPU is hotplugged off. When all the CPUs in a domain are hotplugged
>>> off, the domain may also be powered off and cluster_pm_enter/exit()
>>> notifications are be sent out.
>>>
>>> Cc: Catalin Marinas <catalin.marinas at arm.com>
>>> Cc: Mark Rutland <mark.rutland at arm.com>
>>> Cc: Lorenzo Pieralisi <lorenzo.pieralisi at arm.com>
>>> Signed-off-by: Lina Iyer <lina.iyer at linaro.org>
>>
>>How does the runtiem PM usage with hotplug work with the runtime PM
>>usage in idle?
>>
>>IIUC, when a CPU is hotplugged in, it will always have a usecount of at
>>least 1, right?  and if it's not idle, it will have done a _get() so it
>>will have a usecount of at least 2.   So I'm not quite seeing how the
>>usecount will ever go to zero in idle and allow the domain to power_off.
>>
> When the CPU is online and running, it would have a ref count of 1. Then
> cpuidle would do a _put and the ref count would go to 0 and when coming
> out of idle, cpuidle would get a _get and the ref count will be back at
> 1. Ref count is not incremented when cpuidle is initialized on the CPU.
> So whenever the CPU is running, it would have a ref count of 1.

Ah, OK, that was the part I was missing.

Thanks,

Kevin


From mathieu at codeaurora.org  Fri Aug 14 12:08:44 2015
From: mathieu at codeaurora.org (Mathieu Olivari)
Date: Fri, 14 Aug 2015 12:08:44 -0700
Subject: [PATCH 3/3] mtd: add SMEM parser for QCOM platforms
In-Reply-To: <55CD386A.5070801@codeaurora.org>
References: <1439501620-24073-1-git-send-email-mathieu@codeaurora.org>
 <1439501620-24073-4-git-send-email-mathieu@codeaurora.org>
 <55CD386A.5070801@codeaurora.org>
Message-ID: <20150814190835.GA16804@codeaurora.org>

On Thu, Aug 13, 2015 at 05:38:02PM -0700, Stephen Boyd wrote:
> On 08/13/2015 02:33 PM, Mathieu Olivari wrote:
> >diff --git a/drivers/mtd/qcom_smem_part.c b/drivers/mtd/qcom_smem_part.c
> >new file mode 100644
> >index 0000000..6cbf610
> >--- /dev/null
> >+++ b/drivers/mtd/qcom_smem_part.c
> >
> >+#define SMEM_PARTS_MAX			32
> >+
> >+struct smem_partition {
> >+	char name[SMEM_PART_NAME_SZ];
> >+	uint32_t start;
> >+	uint32_t size;
> >+	uint32_t attr;
> 
> Is this little endian? __le32? I think so.
Yes. I'll make the change.
> 
> >+};
> >+
> >+struct smem_partition_table {
> >+	uint32_t magic[2];
> >+	uint32_t version;
> >+	uint32_t len;
> 
> Same for these being little endian. And if so, please make magic into a byte
> array of size 8 and then do a memcmp with another static byte array.
Done.
> 
> >+	struct smem_partition parts[SMEM_PARTS_MAX];
> >+};
> >+
> >+static int qcom_smem_get_flash_blksz(uint64_t **smem_blksz)
> 
> I don't know, but I prefer u64 because it's short and sweet. But I'm not the
> maintainer here.
Agreed.
> 
> >+{
> >+	int ret;
> >+	size_t size;
> >+
> >+	ret = qcom_smem_get(SMEM_HOST_APPS, SMEM_BOOT_FLASH_BLOCK_SIZE,
> >+			    (void **) smem_blksz, &size);
> 
> Is the cast necessary?
Compiler will issue a warning if it's not there.
> 
> >+
> >+	if (ret < 0) {
> >+		pr_err("Unable to read flash blksz from SMEM\n");
> >+		return -ENOENT;
> >+	}
> >+
> >+	if (size != sizeof(**smem_blksz)) {
> >+		pr_err("Invalid flash blksz size in SMEM\n");
> >+		return -EINVAL;
> >+	}
> >+
> >+	return 0;
> >+}
> >+
> >+static int qcom_smem_get_flash_type(uint64_t **smem_flash_type)
> >+{
> >+	int ret;
> >+	size_t size;
> >+
> >+	ret = qcom_smem_get(SMEM_HOST_APPS, SMEM_BOOT_FLASH_TYPE,
> >+			    (void **) smem_flash_type, &size);
> >+
> >+	if (ret < 0) {
> >+		pr_err("Unable to read flash type from SMEM\n");
> >+		return -ENOENT;
> >+	}
> >+
> >+	if (size != sizeof(**smem_flash_type)) {
> >+		pr_err("Invalid flash type size in SMEM\n");
> >+		return -EINVAL;
> >+	}
> >+
> >+	return 0;
> >+}
> >+
> >+static int qcom_smem_get_flash_partitions(struct smem_partition_table **pparts)
> >+{
> >+	int ret;
> >+	size_t size;
> >+
> >+	ret = qcom_smem_get(SMEM_HOST_APPS, SMEM_AARM_PARTITION_TABLE,
> >+			    (void **) pparts, &size);
> >+
> >+	if (ret < 0) {
> >+		pr_err("Unable to read partition table from SMEM\n");
> >+		return -ENOENT;
> >+	}
> >+
> >+	return 0;
> >+}
> >+
> >+static int of_dev_node_match(struct device *dev, void *data)
> >+{
> >+	return dev->of_node == data;
> >+}
> >+
> >+static bool is_spi_device(struct device_node *np)
> >+{
> >+	struct device *dev;
> >+
> >+	dev = bus_find_device(&spi_bus_type, NULL, np, of_dev_node_match);
> 
> I'm pretty sure this holds a reference to the device that needs to be
> released with put_device().
You're right. I'll add the corresponding put_device().
> 
> >+	return dev ? true : false;
> >+}
> >+
> >+static int parse_qcom_smem_partitions(struct mtd_info *master,
> >+				      struct mtd_partition **pparts,
> >+				      struct mtd_part_parser_data *data)
> >+{
> >+	struct smem_partition_table *smem_parts;
> >+	uint64_t *smem_flash_type, *smem_blksz;
> >+	struct mtd_partition *mtd_parts;
> >+	struct device_node *of_node = data->of_node;
> >+	int i, ret;
> >+
> >+	/*
> >+	 * SMEM will only store the partition table of the boot device.
> >+	 * If this is not the boot device, do not return any partition.
> >+	 */
> >+	ret = qcom_smem_get_flash_type(&smem_flash_type);
> >+	if (ret < 0)
> >+		return ret;
> >+
> >+	if ((*smem_flash_type == SMEM_FLASH_NAND && !mtd_type_is_nand(master))
> >+	    || (*smem_flash_type == SMEM_FLASH_SPI && !is_spi_device(of_node)))
> >+		return 0;
> >+
> >+	/*
> >+	 * Just for sanity purpose, make sure the block size in SMEM matches the
> >+	 * block size of the MTD device
> >+	 */
> >+	ret = qcom_smem_get_flash_blksz(&smem_blksz);
> >+	if (ret < 0)
> >+		return ret;
> >+
> >+	if (*smem_blksz != master->erasesize) {
> >+		pr_err("SMEM block size differs from MTD block size\n");
> >+		return -EINVAL;
> >+	}
> >+
> >+	/* Get partition pointer from SMEM */
> >+	ret = qcom_smem_get_flash_partitions(&smem_parts);
> >+	if (ret < 0)
> >+		return ret;
> >+
> >+	if (smem_parts->magic[0] != SMEM_PTABLE_MAGIC_1 ||
> >+	    smem_parts->magic[1] != SMEM_PTABLE_MAGIC_2) {
> >+		pr_err("SMEM partition magic invalid\n");
> >+		return -EINVAL;
> >+	}
> >+
> >+	/* Allocate and populate the mtd structures */
> >+	mtd_parts = kcalloc(smem_parts->len, sizeof(struct mtd_partition),
> 
> sizeof(*mtd_parts)?
OK.
> 
> >+			    GFP_KERNEL);
> >+	if (mtd_parts == NULL)
> 
> if (!mtd_parts) is more kernel style.
OK.
> 
> >+		return -ENOMEM;
> >+
> >+	for (i = 0; i < smem_parts->len; i++) {
> >+		struct smem_partition *part = &smem_parts->parts[i];
> >+
> >+		mtd_parts[i].name = part->name;
> >+		mtd_parts[i].size = part->size * (*smem_blksz);
> >+		mtd_parts[i].offset = part->start * (*smem_blksz);
> >+
> >+		/*
> >+		 * The last SMEM partition may have its size marked as
> >+		 * something like 0xffffffff, which means "until the end of the
> >+		 * flash device". In this case, truncate it.
> >+		 */
> >+		if (mtd_parts[i].offset + mtd_parts[i].size > master->size)
> >+			mtd_parts[i].size = master->size - mtd_parts[i].offset;
> 
> That is 7 mtd_parts[i]. instances. Consider making a local variable pointer
> instead. Actually we could make two pointers for smem_parts->part and
> mtd_parts and increment both in the loop to make tighter code.
OK; I'll simplify it by making a new pointer.
> 
> >+	}
> >+
> >+	*pparts = mtd_parts;
> 
> Oh we already have the pointer, so just do this assignment before iterating.
pparts is an argument; I'd rather not make double use of it for clarity
purpose. I'll create a new one similar to the SMEM one instead.
> 
> -- 
> Qualcomm Innovation Center, Inc. is a member of Code Aurora Forum,
> a Linux Foundation Collaborative Project
> 


From grygorii.strashko at ti.com  Fri Aug 14 12:09:56 2015
From: grygorii.strashko at ti.com (Grygorii Strashko)
Date: Fri, 14 Aug 2015 22:09:56 +0300
Subject: [PATCH v3 01/18] platform: delay OF device-driver matches until
 late_initcall
In-Reply-To: <CAAObsKDJsuhuQfLbxq27Mtm1T_Auz7Gohp8PDyK7rNNDyaGhcg@mail.gmail.com>
References: <1438870315-18689-1-git-send-email-tomeu.vizoso@collabora.com>
 <1438870315-18689-2-git-send-email-tomeu.vizoso@collabora.com>
 <CAL_Jsq+GLMZe-f6qEi=7i1YrrWc6k99RpGkOyCd5KkYDiyt0QA@mail.gmail.com>
 <CAAObsKBapFqzr+4YEXJfcJWMd+tkaBqYbGiFTntHStAP=+P-_Q@mail.gmail.com>
 <55C4E597.1010701@ti.com>
 <CAAObsKDJsuhuQfLbxq27Mtm1T_Auz7Gohp8PDyK7rNNDyaGhcg@mail.gmail.com>
Message-ID: <55CE3D04.8000607@ti.com>

Hi Tomeu,

On 08/09/2015 04:03 PM, Tomeu Vizoso wrote:
> On 7 August 2015 at 19:06, Grygorii Strashko <grygorii.strashko at ti.com> wrote:
>> On 08/07/2015 10:11 AM, Tomeu Vizoso wrote:
>>> On 6 August 2015 at 22:19, Rob Herring <robherring2 at gmail.com> wrote:
>>>> On Thu, Aug 6, 2015 at 9:11 AM, Tomeu Vizoso <tomeu.vizoso at collabora.com> wrote:
>>>>> Delay matches of platform devices with OF nodes until late_initcall,
>>>>> when we are sure that all built-in drivers have been registered already.
>>>>> This is needed to prevent deferred probes because of some drivers not
>>>>> having registered yet.
>>>>>
>>>>> The reason why only platform devices are delayed is that some other
>>>>> devices are expected to be probed earlier than late_initcall, for
>>>>> example, the system PNP driver needs to probe its devices in
>>>>> fs_initcall.
>>>>>
>>>>> Additionally, only platform devices with OF nodes are delayed because
>>>>> some machines may depend on oter platform devices being registered at
>>>>> specific times.
>>>>
>>>> How do we know that these probes occur before the unused clocks and
>>>> regulators are turned off? Just getting lucky (as is deferred probe)?
>>>> Can we do this one level earlier so we have a level left to do things
>>>> after probe.
>>>
>>> Those are already late_initcall_sync so I guess we're fine.
>>
>> I wouldn't be so sure :(
>> FYI:
>> http://git.ti.com/ti-linux-kernel/ti-linux-kernel/commit/763d643bbfc0f445c6685c541fcae3c370e4314a

I'm very sorry for delayed reply.

First of all, I'd like to say that proposition to move drivers probing/matching 
one layer early (device_initcall_sync) is reasonable 
(and I've already mentioned the same here https://lkml.org/lkml/2015/6/3/979).

> 
> If I understand the situation correctly, this is one more instance of
> starting to do some work at some point and hoping that something else
> that started before has already finished happening. If that's the
> case, how does this series make that worst?

You going to increase pressure on the late boot stages without taking
into account that there could be platforms which perfectly works
just using init_calls. And the fact that drivers will be not probed at
expected time could be very surprising for them.

Or, there should be an option to disable this functionality.

> 
> During this development I have found many hacks intended to put some
> order, even if not enough care was taken to make sure that the order
> was guaranteed. In general I would recommend for moving code into
> proper drivers and have them to defer the probe of their devices if
> some dependency isn't fulfilled at that moment.

Unfortunately, not everything can be moved to drivers or it could be
just unreasonable. 

> 
> Once that's done and we have a safe and reliable boot, we can avoid
> those deferred probes by fulfilling the dependency on-demand as this
> series shows.
> 
> There was some recent thread about how the disabling of unused clocks
> and regulators isn't really safe because after late_initcall_sync more
> drivers can be registered from modules. Furthermore, there's async
> device probes.

Clocks and regulators are safe, problems may happen first of all with 
platform's specific initcalls.


Just take a look how many late_initcalls defined now in Kernel
(grep -w -RI  "late_initcall" ./*) and everything which belongs
to  /arch/* will be called before your probe_delayed_matches_initcall().
The sequence of late_initcalls in /drivers/* is defined by
/drivers/Makefile. 

#
./arch/um/kernel/process.c:late_initcall(make_proc_sysemu);
./arch/um/drivers/umcast_kern.c:late_initcall(register_umcast);
./arch/um/drivers/stdio_console.c:late_initcall(stdio_init);
./arch/um/drivers/pcap_kern.c:late_initcall(register_pcap);
./arch/um/drivers/ssl.c:late_initcall(ssl_init);
./arch/um/drivers/slip_kern.c:late_initcall(register_slip);
./arch/um/drivers/vde_kern.c:late_initcall(register_vde);
./arch/um/drivers/mconsole_kern.c:late_initcall(mc_add_console);
./arch/um/drivers/ubd_kern.c:late_initcall(ubd_init);
./arch/um/drivers/slirp_kern.c:late_initcall(register_slirp);
./arch/um/drivers/daemon_kern.c:late_initcall(register_daemon);
./arch/um/os-Linux/drivers/tuntap_kern.c:late_initcall(register_tuntap);
./arch/um/os-Linux/drivers/ethertap_kern.c:late_initcall(register_ethertap);
./arch/arm/kernel/pj4-cp0.c:late_initcall(pj4_cp0_init);
./arch/arm/kernel/setup.c:late_initcall(init_machine_late);
./arch/arm/kernel/xscale-cp0.c:late_initcall(xscale_cp0_init);
./arch/arm/kernel/swp_emulate.c:late_initcall(swp_emulation_init);
./arch/arm/kernel/thumbee.c:late_initcall(thumbee_init);
./arch/arm/kernel/traps.c:late_initcall(arm_mrc_hook_init);
./arch/arm/mach-mmp/pm-pxa910.c:late_initcall(pxa910_pm_init);
./arch/arm/mach-mmp/pm-mmp2.c:late_initcall(mmp2_pm_init);
./arch/arm/common/bL_switcher.c:late_initcall(bL_switcher_init);
./arch/arm/mach-pxa/sharpsl_pm.c:late_initcall(sharpsl_pm_init);
./arch/arm/kvm/coproc_a15.c:late_initcall(coproc_a15_init);
./arch/arm/kvm/coproc_a7.c:late_initcall(coproc_a7_init);
./arch/arm/mach-omap1/clock.c:late_initcall(clk_disable_unused);
./arch/arm/mach-omap1/clock.c:late_initcall(omap_clk_enable_autoidle_all);
./arch/arm/mach-omap1/clock.c:late_initcall(clk_debugfs_init);
./arch/arm/xen/enlighten.c:late_initcall(xen_pm_init);
./arch/arm/probes/kprobes/test-core.c:late_initcall(run_all_tests);
./arch/arm/mach-mvebu/pm-board.c:late_initcall(mvebu_armada_xp_gp_pm_init);
./arch/unicore32/kernel/fpu-ucf64.c:late_initcall(ucf64_init);
./arch/avr32/mm/tlb.c:late_initcall(proctlb_init);
./arch/sh/kernel/cpu/sh4a/smp-shx3.c:late_initcall(register_shx3_cpu_notifier);
./arch/sh/kernel/cpu/shmobile/pm.c:late_initcall(sh_pm_init);
./arch/sh/boards/mach-hp6xx/pm.c:late_initcall(hp6x0_pm_init);
./arch/xtensa/platforms/iss/console.c:late_initcall(rs_init);
./arch/frv/kernel/setup.c:late_initcall(setup_arch_serial);
./arch/powerpc/kernel/machine_kexec.c:late_initcall(kexec_setup);
./arch/powerpc/kernel/machine_kexec_64.c:late_initcall(export_htab_values);
./arch/powerpc/kernel/setup-common.c:late_initcall(check_cache_coherency);
./arch/powerpc/kernel/iommu.c:late_initcall(fail_iommu_debugfs);
./arch/powerpc/lib/code-patching.c:late_initcall(test_code_patching);
./arch/powerpc/lib/feature-fixups.c:late_initcall(test_feature_fixups);
./arch/powerpc/sysdev/ppc4xx_cpm.c:late_initcall(cpm_init);
./arch/powerpc/sysdev/dart_iommu.c:late_initcall(iommu_init_late_dart);
./arch/powerpc/sysdev/msi_bitmap.c:late_initcall(msi_bitmap_selftest);
./arch/tile/kernel/hardwall.c:late_initcall(dev_hardwall_init);
./arch/tile/kernel/smpboot.c:late_initcall(reset_init_affinity);
./arch/arm64/kernel/fpsimd.c:late_initcall(fpsimd_init);
./arch/arm64/kernel/armv8_deprecated.c:late_initcall(armv8_deprecated_init);
./arch/arm64/kvm/sys_regs_generic_v8.c:late_initcall(sys_reg_genericv8_init);
./arch/m68k/kernel/early_printk.c:late_initcall(unregister_early_console);
./arch/sparc/kernel/leon_pmc.c:late_initcall(leon_pmc_install);
./arch/sparc/kernel/sstate.c:late_initcall(sstate_running);
./arch/metag/kernel/setup.c:late_initcall(init_machine_late);
./arch/x86/kernel/tboot.c:late_initcall(tboot_late_init);
./arch/x86/kernel/cpu/mcheck/mce-severity.c:late_initcall(severities_debugfs_init);
./arch/x86/kernel/cpu/mcheck/mce_amd.c:late_initcall(threshold_init_device);
./arch/x86/kernel/cpu/mcheck/mce.c:late_initcall(mcheck_debugfs_init);
./arch/x86/kernel/mpparse.c:late_initcall(update_mp_table);
./arch/x86/kernel/apic/x2apic_uv_x.c:late_initcall(uv_init_heartbeat);
./arch/x86/kernel/apic/apic.c:late_initcall(lapic_insert_resource);
./arch/x86/kernel/apic/vector.c:late_initcall(print_ICs);
./arch/x86/kernel/apic/probe_32.c:late_initcall(print_ipi_mode);
./arch/x86/kernel/acpi/boot.c:late_initcall(hpet_insert_resource);
./arch/x86/crypto/aesni-intel_glue.c:late_initcall(aesni_init);
./arch/x86/mm/tlb.c:late_initcall(create_tlb_single_page_flush_ceiling);
./arch/x86/mm/pat.c:late_initcall(pat_memtype_list_init);
./arch/x86/platform/intel-mid/device_libs/platform_gpio_keys.c:late_initcall(pb_keys_init);
./arch/x86/pci/mmconfig-shared.c:late_initcall(pci_mmcfg_late_insert_resources);
./arch/arc/kernel/setup.c:late_initcall(init_late_machine);
./arch/mips/alchemy/devboards/pm.c:late_initcall(pm_init);
./arch/mips/loongson64/common/mem.c:late_initcall(find_vga_mem_init);
./arch/mips/txx9/generic/setup_tx4927.c:late_initcall(tx4927_late_init);
./arch/mips/txx9/generic/setup_tx4939.c:late_initcall(tx4939_late_init);
./arch/mips/txx9/generic/setup_tx4938.c:late_initcall(tx4938_late_init);
./arch/mips/cavium-octeon/setup.c:late_initcall(octeon_no_pci_release);
./arch/mips/cavium-octeon/flash_setup.c:late_initcall(octeon_flash_init);
./arch/mips/cavium-octeon/smp.c:late_initcall(register_cavium_notifier);
./arch/mips/mti-malta/malta-pm.c:late_initcall(malta_pm_setup);
./arch/mips/jz4740/pm.c:late_initcall(jz4740_pm_init);
./arch/mips/sgi-ip27/ip27-timer.c:late_initcall(sgi_ip27_rtc_devinit);
./arch/blackfin/kernel/cplbinfo.c:late_initcall(cplbinfo_init);
./arch/blackfin/kernel/bfin_dma.c:late_initcall(proc_dma_init);
./arch/blackfin/kernel/nmi.c:late_initcall(init_nmi_wdt_syscore);
./arch/blackfin/mach-bf609/pm.c:late_initcall(bf609_init_pm);
./arch/blackfin/mm/sram-alloc.c:late_initcall(sram_proc_init);
./arch/blackfin/mm/isram-driver.c:late_initcall(isram_test_init);
./block/blk-core.c:late_initcall(fail_make_request_debugfs);
./block/blk-timeout.c:late_initcall(fail_io_timeout_debugfs);
./crypto/async_tx/raid6test.c:late_initcall(raid6_test);
./drivers/clk/clk.c:late_initcall(clk_debug_init);
./drivers/mtd/ubi/build.c:late_initcall(ubi_init);
./drivers/mtd/devices/block2mtd.c:late_initcall(block2mtd_init);
./drivers/devfreq/exynos/exynos5_bus.c:late_initcall(exynos5_busfreq_int_init);
./drivers/devfreq/exynos/exynos4_bus.c:late_initcall(exynos4_busfreq_init);
./drivers/gpu/drm/omapdrm/omap_drv.c:late_initcall(omap_drm_init);
./drivers/gpu/drm/gma500/psb_drv.c:late_initcall(psb_init);
./drivers/video/logo/logo.c:late_initcall(fb_logo_late_init);
./drivers/of/fdt.c:late_initcall(of_fdt_raw_init);
./drivers/base/dd.c:late_initcall(deferred_probe_initcall);
./drivers/base/power/trace.c:late_initcall(late_resume_init);
./drivers/base/power/domain.c:late_initcall(genpd_poweroff_unused);
./drivers/base/power/domain.c:late_initcall(pm_genpd_debug_init);
./drivers/mfd/wl1273-core.c:late_initcall(wl1273_core_init);
./drivers/cpufreq/speedstep-centrino.c:late_initcall(centrino_init);
./drivers/cpufreq/amd_freq_sensitivity.c:late_initcall(amd_freq_sensitivity_init);
./drivers/cpufreq/sfi-cpufreq.c:late_initcall(sfi_cpufreq_init);
./drivers/cpufreq/powernow-k8.c:late_initcall(powernowk8_init);
./drivers/cpufreq/acpi-cpufreq.c:late_initcall(acpi_cpufreq_init);
./drivers/cpufreq/ia64-acpi-cpufreq.c:late_initcall(acpi_cpufreq_init);
./drivers/cpufreq/p4-clockmod.c:late_initcall(cpufreq_p4_init);
./drivers/cpufreq/pcc-cpufreq.c:late_initcall(pcc_cpufreq_init);
./drivers/cpufreq/powernow-k7.c:late_initcall(powernow_init);
./drivers/cpufreq/longhaul.c:late_initcall(longhaul_init);
./drivers/cpufreq/s3c24xx-cpufreq-debugfs.c:late_initcall(s3c_freq_debugfs_init);
./drivers/cpufreq/at32ap-cpufreq.c:late_initcall(at32_cpufreq_init);
./drivers/cpufreq/s3c24xx-cpufreq.c:late_initcall(s3c_cpufreq_initcall);
./drivers/sh/clk/core.c:late_initcall(clk_late_init);
./drivers/sh/intc/userimask.c:late_initcall(userimask_sysdev_init);
./drivers/net/netconsole.c:late_initcall(init_netconsole);
./drivers/net/vxlan.c:late_initcall(vxlan_init_module);
./drivers/net/geneve.c:late_initcall(geneve_init_module);
./drivers/net/ethernet/ti/davinci_emac.c:late_initcall(davinci_emac_init);
./drivers/net/ethernet/ti/cpsw.c:late_initcall(cpsw_init);
./drivers/net/rionet.c:late_initcall(rionet_init);
./drivers/gpio/gpio-tegra.c:late_initcall(tegra_gpio_debuginit);
./drivers/block/hd.c:late_initcall(hd_init);
./drivers/thermal/db8500_cpufreq_cooling.c:late_initcall(db8500_cpufreq_cooling_init);
./drivers/staging/android/sync_debug.c:late_initcall(sync_debugfs_init);
./drivers/staging/wilc1000/linux_wlan.c:late_initcall(init_wilc_driver);
./drivers/iommu/dmar.c:late_initcall(dmar_free_unused_resources);
./drivers/watchdog/ie6xx_wdt.c:late_initcall(ie6xx_wdt_init);
./drivers/watchdog/intel_scu_watchdog.c:late_initcall(intel_scu_watchdog_init);
./drivers/tty/serial/mpsc.c:late_initcall(mpsc_late_console_init);
./drivers/media/platform/omap/omap_vout.c:late_initcall(omap_vout_init);
./drivers/media/pci/cx25821/cx25821-alsa.c:late_initcall(cx25821_alsa_init);
./drivers/media/pci/saa7134/saa7134-alsa.c:late_initcall(saa7134_alsa_init);
./drivers/dma/dmatest.c:late_initcall(dmatest_init);
./drivers/rapidio/rio-scan.c:late_initcall(rio_basic_attach);
./drivers/xen/xenbus/xenbus_probe_frontend.c:late_initcall(boot_wait_for_devices);
./drivers/platform/x86/dell-laptop.c:late_initcall(dell_init);
./drivers/firmware/memmap.c:late_initcall(firmware_memmap_init);
./drivers/firmware/edd.c:late_initcall(edd_init);
./drivers/firmware/efi/reboot.c:late_initcall(efi_shutdown_init);
./drivers/input/keyboard/gpio_keys.c:late_initcall(gpio_keys_init);
./drivers/pci/pci.c:late_initcall(pci_resource_alignment_sysfs_init);
./drivers/pci/pci-sysfs.c:late_initcall(pci_sysfs_init);
./drivers/macintosh/via-pmu-led.c:late_initcall(via_pmu_led_init);
./drivers/macintosh/via-pmu-event.c:late_initcall(via_pmu_event_init);
./drivers/ide/sgiioc4.c:late_initcall(ioc4_ide_init); /* Call only after IDE init is done */
./drivers/ide/ide-cs.c:late_initcall(init_ide_cs);
./drivers/rtc/Kconfig:	  The driver for this RTC device must be loaded before late_initcall
./drivers/rtc/hctosys.c:late_initcall(rtc_hctosys);
./drivers/irqchip/irq-vic.c:late_initcall(vic_pm_init);
./drivers/power/avs/smartreflex.c:late_initcall(sr_init);
./drivers/power/charger-manager.c:late_initcall(charger_manager_init);
./fs/btrfs/super.c:late_initcall(init_btrfs_fs);
./fs/afs/main.c:late_initcall(afs_init);	/* must be called after net/ to create socket */
./fs/ubifs/super.c:late_initcall(ubifs_init);
./kernel/sched/core.c:late_initcall(sched_init_debug);
./kernel/time/timekeeping_debug.c:late_initcall(tk_debug_sleep_time_init);
./kernel/taskstats.c:late_initcall(taskstats_init);
./kernel/printk/printk.c:late_initcall(printk_late_init);
./kernel/bpf/arraymap.c:late_initcall(register_array_map);
./kernel/bpf/arraymap.c:late_initcall(register_prog_array_map);
./kernel/bpf/hashtab.c:late_initcall(register_htab_map);
./kernel/trace/trace_events.c:late_initcall(event_trace_self_tests_init);
./kernel/trace/bpf_trace.c:late_initcall(register_kprobe_prog_ops);
./kernel/trace/trace.c:late_initcall(clear_boot_tracer);
./kernel/trace/trace_kprobe.c:late_initcall(kprobe_trace_self_tests_init);
./kernel/trace/trace_events_filter.c:late_initcall(ftrace_test_event_filter);
./kernel/trace/trace_kdb.c:late_initcall(kdb_ftrace_register);
./kernel/trace/ring_buffer.c:late_initcall(test_ringbuffer);
./kernel/kprobes.c:late_initcall(debugfs_kprobe_init);
./kernel/rcu/update.c:late_initcall(rcu_verify_early_boot_tests);
./kernel/panic.c:late_initcall(init_oops_id);
./kernel/system_keyring.c:late_initcall(load_system_certificate_list);
./kernel/power/qos.c:late_initcall(pm_qos_power_init);
./kernel/power/Kconfig:	  late_initcall.
./kernel/power/main.c:late_initcall(pm_debugfs_init);
./kernel/power/suspend_test.c:late_initcall(test_suspend);
./lib/list_sort.c:late_initcall(list_sort_test);
./lib/random32.c:late_initcall(prandom_reseed);
./mm/kmemleak.c:late_initcall(kmemleak_late_init);
./mm/failslab.c:late_initcall(failslab_debugfs_init);
./mm/memory.c:late_initcall(fault_around_debugfs);
./mm/early_ioremap.c:late_initcall(check_early_ioremap_leak);
./mm/cma_debug.c:late_initcall(cma_debugfs_init);
./mm/page_owner.c:late_initcall(pageowner_init)
./mm/page_alloc.c:late_initcall(fail_page_alloc_debugfs);
./mm/swapfile.c:late_initcall(max_swapfiles_check);
./mm/zswap.c:late_initcall(init_zswap);
./net/ipv4/ipconfig.c:late_initcall(ip_auto_config);
./net/ipv4/tcp_cong.c:late_initcall(tcp_congestion_default);
./net/core/filter.c:late_initcall(register_sk_filter_ops);
./net/bluetooth/selftest.c:late_initcall(bt_selftest_init);
./security/integrity/evm/evm_main.c:late_initcall(init_evm);
./security/integrity/ima/ima_main.c:late_initcall(init_ima);	/* Start IMA after the TPM is available */
./security/apparmor/crypto.c:late_initcall(init_profile_hash);
./security/keys/trusted.c:late_initcall(init_trusted);
./security/keys/encrypted-keys/encrypted.c:late_initcall(init_encrypted);
./security/keys/process_keys.c:late_initcall(init_root_keyring);
./sound/soc/fsl/p1022_rdk.c:late_initcall(p1022_rdk_init);
./sound/soc/fsl/phycore-ac97.c:late_initcall(imx_phycore_init);

-- 
regards,
-grygorii


From khilman at kernel.org  Fri Aug 14 12:11:30 2015
From: khilman at kernel.org (Kevin Hilman)
Date: Fri, 14 Aug 2015 12:11:30 -0700
Subject: [PATCH 5/9] ARM: common: Introduce PM domains for CPUs/clusters
In-Reply-To: <20150814154947.GC24806@red-moon> (Lorenzo Pieralisi's message of
 "Fri, 14 Aug 2015 16:49:47 +0100")
References: <1438731339-58317-1-git-send-email-lina.iyer@linaro.org>
 <1438731339-58317-6-git-send-email-lina.iyer@linaro.org>
 <CAL_JsqK67=DTtjZwwnonObLDjLbahkREfm0RvyXVV95bhR-d4Q@mail.gmail.com>
 <20150813150154.GB13356@red-moon> <20150813154503.GO52339@linaro.org>
 <20150813155245.GD13833@red-moon> <7hegj6le8c.fsf@deeprootsystems.com>
 <20150814154947.GC24806@red-moon>
Message-ID: <7h1tf5it25.fsf@deeprootsystems.com>

Lorenzo Pieralisi <lorenzo.pieralisi at arm.com> writes:

> On Fri, Aug 14, 2015 at 04:51:15AM +0100, Kevin Hilman wrote:

[...]

>> However, you can think of CPU PM notifiers as the equivalent of runtime
>> PM hooks.  They're called when the "devices" are about to be powered off
>> (runtime suspended) or powered on (runtime resumed.)
>> 
>> However the CPU PM framework and notifiers are rather dumb compared to
>> runtime PM.  For example, runtime PM gives you usecounting, autosuspend,
>> control from userspace, statistics, etc. etc.  Also, IMO, CPU PM will 
>> not scale well for multiple clusters.
>> 
>> What if instead, we used runtime PM for the things that the CPU PM
>> notifiers manager (GIC, VFP, Coresight, etc.), and those drivers used
>> runtime PM callbacks to replace their CPU PM notifiers?  We'd then be in
>> a beautiful land where CPU "devices" (and the other connected logic) can
>> be modeled as devices using runtime PM just like every other device in
>> the system.
>
> I would agree with that (even though I do not see how we can make
> eg GIC, VFP and arch timers behave like devices from a runtime PM
> standpoint), 

Sure, that might be a stretch due the implementation details, but
conceptully it models the hardware well and I'd like to explore runtime
PM for all of these "devices", though it's not the highest priority.

> still I do not see why we need a virtual power domain for
> that, the CPU "devices" should be attached to the HW CPU power domain.
>
> More below for systems relying on FW interfaces to handle CPU power
> management.
>
>> Then take it up a level... what if we then could use genpd to model the
>> "cluster", made of of the CPUs and "connected" devices (GIC, VFP, etc.)
>> but also modeled the shared L2$ as a device which was using runtime PM.
>
> I have to understand what "modeled" means (do we create a struct device
> on purpose for that ? Same goes for GIC and VFP).

Not necessarily a struct device for the cluster, but for the CPUs (which
already have one) and and possibly GIC, VFP, timers. etc.  With that in
place, cluster would just be modleled by a genpd (which is what Lina's
series is doing.)

> But overall I get the gist of what you are saying, we just have to see
> how this can be implemented within the genPD framework.
>
> I suspect the "virtual" power domain you are introducing is there for
> systems where the power controller is hidden from the kernel (ie PSCI),
> where basically the CPU "devices" can't be attached to a power domain
> simply because that power domain is not managed in the kernel but
> by firmware.

The main idea behind a "virtual" power domain was to collect the common
parts of cluster management, possibly governors etc.  However, maybe
it's better just have a set of functions that the "real" hw power domain
drivers could use for the common parts.  That might get rid of the need
to describe this in DT, which I think is what Rob is suggesting also.

>> Now we're in a place where we can use all the benefits of runtime PM,
>> plus the governor features of genpd to start doing a real, multi-CPU,
>> multi-cluster CPUidle that's flexible enough to model the various
>> dependencies in an SoC independent way, but generic enough to be able to
>> use common governors for last-man standing, cache flushing, etc. etc.
>
> I do not disagree (even though I think that last man standing is pushing
> this concept a bit over the top), I am just concerned about the points
> raised above, most of them should be reasonably simple to solve.

Good, hopefully we can have a good discussion about this at Plumbers
next week as the issues above and proposed in Lina's series are the main
issues I want to raise in my part of the EAS/PM track[1].

See you there!

Kevin

[1] https://linuxplumbersconf.org/2015/ocw/events/LPC2015/tracks/501


From robert.jarzmik at free.fr  Fri Aug 14 12:09:07 2015
From: robert.jarzmik at free.fr (Robert Jarzmik)
Date: Fri, 14 Aug 2015 21:09:07 +0200
Subject: [PATCH] arm: mainstone_defconfig: disable IDE subsystem
In-Reply-To: <1439571876-13758-14-git-send-email-b.zolnierkie@samsung.com>
 (Bartlomiej Zolnierkiewicz's message of "Fri, 14 Aug 2015 19:04:29
 +0200")
References: <1439571876-13758-1-git-send-email-b.zolnierkie@samsung.com>
 <1439571876-13758-14-git-send-email-b.zolnierkie@samsung.com>
Message-ID: <87wpwxadrg.fsf@belgarion.home>

Bartlomiej Zolnierkiewicz <b.zolnierkie at samsung.com> writes:

> This patch disables deprecated IDE subsystem in mainstone_defconfig
> (no IDE host drivers are selected in this config so there is no valid
> reason to enable IDE subsystem itself).
>
> Cc: Daniel Mack <daniel at zonque.org>
> Cc: Haojian Zhuang <haojian.zhuang at gmail.com>
> Cc: Robert Jarzmik <robert.jarzmik at free.fr>
> Signed-off-by: Bartlomiej Zolnierkiewicz <b.zolnierkie at samsung.com>
Acked-by: Robert Jarzmik <robert.jarzmik at free.fr>

--
Robert


From bhelgaas at google.com  Fri Aug 14 13:26:21 2015
From: bhelgaas at google.com (Bjorn Helgaas)
Date: Fri, 14 Aug 2015 15:26:21 -0500
Subject: [PATCH v2 2/4] PCI: pci-host-generic: Fix lookup of
 linux,pci-probe-only property
In-Reply-To: <20150814164324.GC22809@arm.com>
References: <1439569159-10051-1-git-send-email-marc.zyngier@arm.com>
 <1439569159-10051-3-git-send-email-marc.zyngier@arm.com>
 <20150814164051.GF26431@google.com>
 <20150814164324.GC22809@arm.com>
Message-ID: <CAErSpo5abs2Qj25Bs+JVg87ve346f_RVz7jhNwqdv856+WvXQA@mail.gmail.com>

On Fri, Aug 14, 2015 at 11:43 AM, Will Deacon <will.deacon at arm.com> wrote:
> On Fri, Aug 14, 2015 at 05:40:51PM +0100, Bjorn Helgaas wrote:
>> On Fri, Aug 14, 2015 at 05:19:17PM +0100, Marc Zyngier wrote:
>> > When pci-host-generic looks for the probe-only property, it seems
>> > to trust the DT to be correctly written, and assumes that there
>> > is a parameter to the property.
>> >
>> > Unfortunately, this is not always the case, and some firmware expose
>> > this property naked. The driver ends up making a decision based on
>> > whatever the property pointer points to, which is likely to be junk.
>> >
>> > Switch to the common of_pci.c implementation that doesn't suffer
>> > from this problem.
>> >
>> > Signed-off-by: Marc Zyngier <marc.zyngier at arm.com>
>> > ---
>> >  drivers/pci/host/pci-host-generic.c | 9 +--------
>> >  1 file changed, 1 insertion(+), 8 deletions(-)
>> >
>> > diff --git a/drivers/pci/host/pci-host-generic.c b/drivers/pci/host/pci-host-generic.c
>> > index 265dd25..545ff4e 100644
>> > --- a/drivers/pci/host/pci-host-generic.c
>> > +++ b/drivers/pci/host/pci-host-generic.c
>> > @@ -210,7 +210,6 @@ static int gen_pci_probe(struct platform_device *pdev)
>> >     int err;
>> >     const char *type;
>> >     const struct of_device_id *of_id;
>> > -   const int *prop;
>> >     struct device *dev = &pdev->dev;
>> >     struct device_node *np = dev->of_node;
>> >     struct gen_pci *pci = devm_kzalloc(dev, sizeof(*pci), GFP_KERNEL);
>> > @@ -225,13 +224,7 @@ static int gen_pci_probe(struct platform_device *pdev)
>> >             return -EINVAL;
>> >     }
>> >
>> > -   prop = of_get_property(of_chosen, "linux,pci-probe-only", NULL);
>> > -   if (prop) {
>> > -           if (*prop)
>> > -                   pci_add_flags(PCI_PROBE_ONLY);
>> > -           else
>> > -                   pci_clear_flags(PCI_PROBE_ONLY);
>> > -   }
>> > +   of_pci_check_probe_only(of_chosen);
>>
>> Do we need support for pci-probe-only in pci-host-generic at all?
>> You're removing the use in amd-overdrive.dts, and there are no other
>> DTs in the kernel tree that mention it.
>>
>> If we can live without it, that would be nice.  It seems like a relic from
>> days when we couldn't reliably assign resources.  (I'm not saying we can do
>> that reliably even today, but I'd rather make it reliable than turn it
>> off.)
>
> Kvmtool certainly uses it (and generates its own DT, hence why you don't
> see it in mainline). Not sure about qemu, though.

Do you know why kvmtool wants probe-only?  Would something break if we
didn't support probe-only?  I guess we'd be looking for a case where
Linux assigns resources and that assignment doesn't work with kvmtool?

"pci-probe-only" doesn't appear in qemu
(git://git.qemu-project.org/qemu.git).  (I guess Alexander confirmed
that later.)

Alexander wrote:
> QEMU definitely doesn't do proble-only.
> Is this driver used on real PPC machines too?

I think you're asking about pci-host-generic.c, and the answer is
"no," because pci-host-generic.c currently depends on CONFIG_ARM.

Bjorn


From robherring2 at gmail.com  Fri Aug 14 13:29:03 2015
From: robherring2 at gmail.com (Rob Herring)
Date: Fri, 14 Aug 2015 15:29:03 -0500
Subject: [PATCH] arm: rpi: Device tree modifications for U-Boot
In-Reply-To: <CAPnjgZ0hzyjy=8o8ocaGCoOC7Js4CirhystidbvtabzbhRi4RQ@mail.gmail.com>
References: <1439303153-12171-1-git-send-email-sjg@chromium.org>
 <1439312701.2451.3.camel@lynxeye.de>
 <CAPnjgZ3ztXnkxZJvitiXiKMzq5+x46hbv0PW4HcF7yGgsXUV+Q@mail.gmail.com>
 <CAPnjgZ0hzyjy=8o8ocaGCoOC7Js4CirhystidbvtabzbhRi4RQ@mail.gmail.com>
Message-ID: <CAL_Jsq++ihz6svJAKWwT7-=KyJvyWXjdf=tZb4aDGgV_Dc=-Nw@mail.gmail.com>

On Fri, Aug 14, 2015 at 1:34 PM, Simon Glass <sjg at chromium.org> wrote:
> -linux-tegra
>
> Hi,
>
> On 12 August 2015 at 07:21, Simon Glass <sjg at chromium.org> wrote:
>> Hi Lucas,
>>
>> On 11 August 2015 at 11:05, Lucas Stach <dev at lynxeye.de> wrote:
>>> Hi Simon,
>>>
>>> why did you send this to the Tegra ML?
>>>
>>> Am Dienstag, den 11.08.2015, 08:25 -0600 schrieb Simon Glass:
>>>> This updates the device tree from the kernel version to something suitable
>>>> for U-Boot:
>>>>
>>>> - Add stdout-path alias for console
>>>> - Mark the /soc node to be available pre-relocation so that the early
>>>> serial console works (we need the 'ranges' property to be available)

I find it quite strange that you must explicitly enable the parent
node, but not the uart node.

>>>>
>>>> Signed-off-by: Simon Glass <sjg at chromium.org>
>>>> ---
>>>>
>>>>  arch/arm/boot/dts/bcm2835.dtsi | 4 +++-
>>>>  1 file changed, 3 insertions(+), 1 deletion(-)
>>>>
>>>> diff --git a/arch/arm/boot/dts/bcm2835.dtsi b/arch/arm/boot/dts/bcm2835.dtsi
>>>> index 301c73f..bd6bff6 100644
>>>> --- a/arch/arm/boot/dts/bcm2835.dtsi
>>>> +++ b/arch/arm/boot/dts/bcm2835.dtsi
>>>> @@ -8,6 +8,7 @@
>>>>
>>>>       chosen {
>>>>               bootargs = "earlyprintk console=ttyAMA0";
>>>> +             stdout-path = &uart;
>>>>       };
>>>>
>>>>       soc {
>>>> @@ -16,6 +17,7 @@
>>>>               #size-cells = <1>;
>>>>               ranges = <0x7e000000 0x20000000 0x02000000>;
>>>>               dma-ranges = <0x40000000 0x00000000 0x20000000>;
>>>> +             u-boot,dm-pre-reloc;
>>>
>>> Why do you need this and why should upstream carry your favourite
>>> bootloaders configuration? This is in no way hardware description.
>>
>> I'm not sure how much you know about U-Boot, so let me know if you
>> need more info.
>>
>> U-Boot normally starts up by setting up its serial UART and displaying
>> a banner message. At this stage typically only a few devices are
>> initialised (e.g. maybe just the UART). It then relocates itself to
>> the top of memory and starts up all the devices. It throws away any
>> previous devices that it set up before relocation and starts again.
>>
>> U-Boot uses a thing called driver model (dm) which handles driver
>> binding and probing. Driver model has the device tree and would
>> normally scan through it and create devices for everything it finds.

How do you debug the DM itself? It seems like you still would need
something earlier for debug like earlycon in the kernel. u-boot DM is
probably simple enough you can get away with using it early, but you
often can't as the complexity increases. Ultimately you need something
simple that just hits all the registers needed to get characters out.
What happens when you add pinmux, clocks, PMIC, power domains, etc. to
the DM and they all become dependencies for the UART?

>> Before relocation we don't need every device. Also the CPU is often
>> running slowly, perhaps without the cache enabled. SDRAM may not be
>> available yet so space is short. We want to avoid starting up things
>> that will not be used.
>>
>> So this property indicates that the device is needed before relocation
>> and should be set up by driver model. We need it to avoid a very slow
>> and memory-hungry startup.

Can't the need for that property change over time? Either as more
drivers are converted to DM you need to add this or you add some
feature that depends on a driver (e.g. get a board rev or boot mode
from GPIO). You would have backwards compatibility issues with this.
I'm somewhat less worried about that for u-boot as we should be
bundling the dtb and bootloader rather than kernel and dtb. For the
UART, you can just get which UART to initialize early from
stdout-path. But for other cases, couldn't you just have the platform
provide the list of needed drivers. Then when u-boot needs change, you
just change u-boot.

>> As to why upstream should accept it, my understanding of upstream is
>> that people can send patches to it and in fact are encouraged to do
>> so, to avoid misunderstandings and duplication. The device tree files
>> are stored in Linux so any binding or source file changes should end
>> up there. Otherwise the files tend to diverge and we end up with
>> multiple bindings and multiple versions of the same source file.
>
> Is the above explanation sufficient? Will this patch be applied?

Well, for starters bindings need to be documented, so you need to send
this as a binding doc with this detail.

Rob


From arnd at arndb.de  Fri Aug 14 13:49:50 2015
From: arnd at arndb.de (Arnd Bergmann)
Date: Fri, 14 Aug 2015 22:49:50 +0200
Subject: [PATCH 1/5] net: add Hisilicon Network Subsystem support (config
 and documents)
In-Reply-To: <1439548222-231611-2-git-send-email-liguozhu@hisilicon.com>
References: <1439548222-231611-1-git-send-email-liguozhu@hisilicon.com>
 <1439548222-231611-2-git-send-email-liguozhu@hisilicon.com>
Message-ID: <1536926.jEJjsM70Lj@wuerfel>

On Friday 14 August 2015 18:30:18 Kenneth Lee wrote:
> diff --git a/Documentation/devicetree/bindings/net/hisilicon-hns-nic.txt b/Documentation/devicetree/bindings/net/hisilicon-hns-nic.txt
> new file mode 100644
> index 0000000..5ab6969
> --- /dev/null
> +++ b/Documentation/devicetree/bindings/net/hisilicon-hns-nic.txt
> @@ -0,0 +1,14 @@
> +Hisilicon Network Subsystem NIC controller
> +
> +Required properties:
> +- compatible: hisilicon,hns-nic
> +- ae-name: accelerator name who provide this interface
> +- ae-opts: options (string) to the accelerator. e.g. the index interface
> +
> +Example:
> +
> +       ethernet at 0{
> +               compatible = "hisilicon,hns-nic";
> +               ae-name = "soc0-n4";
> +               ae-opts = "0";
> +       };
> 

These properties look very unconventional. What are the valid strings
for ae-name and ae-opts? It looks like the latter is just a number,
so why not use an integer property?

	Arnd


From arnd at arndb.de  Fri Aug 14 13:57:28 2015
From: arnd at arndb.de (Arnd Bergmann)
Date: Fri, 14 Aug 2015 22:57:28 +0200
Subject: [PATCH 3/5] net: add Hisilicon Network Subsystem MDIO support
In-Reply-To: <1439548222-231611-4-git-send-email-liguozhu@hisilicon.com>
References: <1439548222-231611-1-git-send-email-liguozhu@hisilicon.com>
 <1439548222-231611-4-git-send-email-liguozhu@hisilicon.com>
Message-ID: <2142879.tTtWetb0nc@wuerfel>

On Friday 14 August 2015 18:30:20 Kenneth Lee wrote:

> +#define MDIO_BASE_ADDR                 0x403C0000

Does not belong in here (and is not used)

> +#define MDIO_COMMAND_REG               0x0
> +#define MDIO_ADDR_REG                  0x4
> +#define MDIO_WDATA_REG                 0x8
> +#define MDIO_RDATA_REG                 0xc
> +#define MDIO_STA_REG                   0x10

These look suspiciously similar to definitions from
drivers/net/ethernet/hisilicon/hip04_mdio.c.

Could the hardware be related? If so, please try to share
the common parts.

> +static inline void mdio_write_reg(void *base, u32 reg, u32 value)
> +{
> +       u8 __iomem *reg_addr = ACCESS_ONCE(base);
> +
> +       writel(value, reg_addr + reg);
> +}
> +
> +#define MDIO_WRITE_REG(a, reg, value) \
> +       mdio_write_reg((a)->vbase, (reg), (value))
> 

Something seems wrong here: why do you have an ACCESS_ONCE() on a
local variable? Doesn't this just make the code less efficient
without providing lockless access to shared variables?

The types are inconsistent here, you should get a warning from
running this through 'make C=1' because of the missing __iomem
annotation of the pointer.

Also, why both a macro and an inline function? Just use an inline
function.

	Arnd


From robherring2 at gmail.com  Fri Aug 14 14:08:10 2015
From: robherring2 at gmail.com (Rob Herring)
Date: Fri, 14 Aug 2015 16:08:10 -0500
Subject: [PATCH v2 1/4] of/pci: Add of_pci_check_probe_only to parse
 "linux, pci-probe-only"
In-Reply-To: <1439569159-10051-2-git-send-email-marc.zyngier@arm.com>
References: <1439569159-10051-1-git-send-email-marc.zyngier@arm.com>
 <1439569159-10051-2-git-send-email-marc.zyngier@arm.com>
Message-ID: <CAL_JsqL7VPB6nc-zRYm_73ZSgYVq_+a6sW_XZZ_LRaUXf4jTng@mail.gmail.com>

On Fri, Aug 14, 2015 at 11:19 AM, Marc Zyngier <marc.zyngier at arm.com> wrote:
> Both pci-host-generic and Pseries parse the "linux,pci-probe-only"
> to engage the PCI_PROBE_ONLY mode, and both have a subtle bug that
> can be triggered if the property has no parameter.

Humm, I bet we could break a lot of machines if we fixed the core code
to properly make pp->value NULL when there is no value.

> Provide a generic implementation that can be used by both.
>
> Signed-off-by: Marc Zyngier <marc.zyngier at arm.com>
> ---
>  drivers/of/of_pci.c    | 30 ++++++++++++++++++++++++++++++
>  include/linux/of_pci.h |  3 +++
>  2 files changed, 33 insertions(+)
>
> diff --git a/drivers/of/of_pci.c b/drivers/of/of_pci.c
> index 5751dc5..a4e29ff 100644
> --- a/drivers/of/of_pci.c
> +++ b/drivers/of/of_pci.c
> @@ -118,6 +118,36 @@ int of_get_pci_domain_nr(struct device_node *node)
>  EXPORT_SYMBOL_GPL(of_get_pci_domain_nr);
>
>  /**
> + * of_pci_check_probe_only - Setup probe only mode if linux,pci-probe-only
> + *                           is present and valid
> + *
> + * @node: device tree node that may contain the property (usually "chosen")
> + *
> + */
> +void of_pci_check_probe_only(struct device_node *node)
> +{
> +       const int *prop;
> +       int len;
> +
> +       if (!node)
> +               return;
> +
> +       prop = of_get_property(node, "linux,pci-probe-only", &len);

It is preferred to use of_property_read_u32 to avoid just these types
of problems.

Rob


From arnd at arndb.de  Fri Aug 14 14:19:46 2015
From: arnd at arndb.de (Arnd Bergmann)
Date: Fri, 14 Aug 2015 23:19:46 +0200
Subject: [PATCH 2/3] Display a DMA error message
In-Reply-To: <1439416290-21228-3-git-send-email-jeremy.linton@arm.com>
References: <1439416290-21228-1-git-send-email-jeremy.linton@arm.com>
 <1439416290-21228-3-git-send-email-jeremy.linton@arm.com>
Message-ID: <2099290.n6l88bWDgg@wuerfel>

On Wednesday 12 August 2015 16:51:29 Jeremy Linton wrote:
> diff --git a/drivers/usb/host/ehci-platform.c b/drivers/usb/host/ehci-platform.c
> index 2593def..82e396f 100644
> --- a/drivers/usb/host/ehci-platform.c
> +++ b/drivers/usb/host/ehci-platform.c
> @@ -162,8 +162,10 @@ static int ehci_platform_probe(struct platform_device *dev)
>  
>         err = dma_coerce_mask_and_coherent(&dev->dev,
>                 pdata->dma_mask_64 ? DMA_BIT_MASK(64) : DMA_BIT_MASK(32));
> -       if (err)
> +       if (err) {
> +               dev_err(&dev->dev, "Error: DMA setup failed\n");
>                 return err;
> +       }

We should really stop doing this: the platform should provide the
correct dma mask when creating the device, instead of setting a
bogus pdata field. Do not duplicate this bug for ACPI.

	Arnd


From robherring2 at gmail.com  Fri Aug 14 14:21:51 2015
From: robherring2 at gmail.com (Rob Herring)
Date: Fri, 14 Aug 2015 16:21:51 -0500
Subject: [PATCH v5] dtb: Create a common home for cross-architecture dtsi
 files.
In-Reply-To: <1439287646.9747.212.camel@citrix.com>
References: <1438618000-1091-1-git-send-email-ian.campbell@citrix.com>
 <1439287646.9747.212.camel@citrix.com>
Message-ID: <CAL_JsqKv2aOEM-U7JNZnaHomA6HFBSFhSLZ-zhp7c20s6gQBaQ@mail.gmail.com>

+arm-soc

On Tue, Aug 11, 2015 at 5:07 AM, Ian Campbell <ian.campbell at citrix.com> wrote:
> On Mon, 2015-08-03 at 17:06 +0100, Ian Campbell wrote:
>> Commit 9ccd608070b6 ("arm64: dts: add device tree for ARM SMM-A53x2 on
>> LogicTile Express 20MG") added a new dts file to arch/arm64 which
>> included "../../../../arm/boot/dts/vexpress-v2m-rs1.dtsi", i.e. a
>> .dtsi supplied by arch/arm.
>>
>> Unfortunately this causes some issues for the split device tree
>> repository[0], since things get moved around there. In that context
>> the new .dts ends up at src/arm64/arm/vexpress-v2f-1xv7-ca53x2.dts
>> while the include is at src/arm/vexpress-v2m-rs1.dtsi.
>
> Hi Grant,
>
> Do you think there is any chance of getting this into 4.2-rc$NEXT or shall
> we wait until 4.3? I'm assuming this should go via the DT tree, but maybe
> it should go via an ARM tree?

I was assuming this would go thru the arm-soc tree which is why I
acked it. It is getting a bit late for 4.2 at this point, but I guess
the standalone tree remains broken for these platforms until this is
done. Probably not such a big deal in grand scheme of things.

Rob


From jeremy.linton at arm.com  Fri Aug 14 14:44:12 2015
From: jeremy.linton at arm.com (Jeremy Linton)
Date: Fri, 14 Aug 2015 16:44:12 -0500
Subject: [PATCH 2/3] Display a DMA error message
In-Reply-To: <2099290.n6l88bWDgg@wuerfel>
References: <1439416290-21228-1-git-send-email-jeremy.linton@arm.com>
 <1439416290-21228-3-git-send-email-jeremy.linton@arm.com>
 <2099290.n6l88bWDgg@wuerfel>
Message-ID: <55CE612C.4010405@arm.com>

Arnd,

On 08/14/2015 04:19 PM, Arnd Bergmann wrote:
> On Wednesday 12 August 2015 16:51:29 Jeremy Linton wrote:
>> diff --git a/drivers/usb/host/ehci-platform.c b/drivers/usb/host/ehci-platform.c
>> index 2593def..82e396f 100644
>> --- a/drivers/usb/host/ehci-platform.c
>> +++ b/drivers/usb/host/ehci-platform.c
>> @@ -162,8 +162,10 @@ static int ehci_platform_probe(struct platform_device *dev)
>>
>>          err = dma_coerce_mask_and_coherent(&dev->dev,
>>                  pdata->dma_mask_64 ? DMA_BIT_MASK(64) : DMA_BIT_MASK(32));
>> -       if (err)
>> +       if (err) {
>> +               dev_err(&dev->dev, "Error: DMA setup failed\n");
>>                  return err;
>> +       }
>
> We should really stop doing this: the platform should provide the
> correct dma mask when creating the device, instead of setting a
> bogus pdata field. Do not duplicate this bug for ACPI.


I'm not sure I understand, I'm not changing the mask anywhere, all I'm 
doing is printing a message if the mask cannot be set.

AKA if CCA is missing or set to 0 then, this line is triggered because 
the dma_coerce_mask_and_coherent() routine returns with a failure 
indicating there aren't any DMA ops to set a mask on. Right now what 
happens is the device detection displays that there is an EHCI 
controller then silently disappears with telling the user why it didn't 
configure.


Thanks,



	





From m-karicheri2 at ti.com  Fri Aug 14 14:53:00 2015
From: m-karicheri2 at ti.com (Murali Karicheri)
Date: Fri, 14 Aug 2015 17:53:00 -0400
Subject: [PATCH] ARM: keystone: add a work around to handle asynchronous
 external abort
In-Reply-To: <55CE05EC.4040909@oracle.com>
References: <1439320409-20084-1-git-send-email-m-karicheri2@ti.com>
 <55CDF579.4050408@ti.com> <20150814140934.GX7557@n2100.arm.linux.org.uk>
 <55CE05EC.4040909@oracle.com>
Message-ID: <55CE633C.10402@ti.com>

On 08/14/2015 11:14 AM, santosh shilimkar wrote:
> On 8/14/2015 7:09 AM, Russell King - ARM Linux wrote:
>> On Fri, Aug 14, 2015 at 10:04:41AM -0400, Murali Karicheri wrote:
>>> On 08/11/2015 03:13 PM, Murali Karicheri wrote:
>>>> Currently on some devices, an asynchronous external abort exception
>>>> happens during boot up when exception handlers are enabled in kernel
>>>> before switching to user space. This patch adds a workaround to handle
>>>> this once during boot. Many customers are already using this
>>>> with out any issues and is required to workaround the above issue.
>>>>
>>>> Signed-off-by: Murali Karicheri <m-karicheri2 at ti.com>
>>>> ---
>>>>   arch/arm/mach-keystone/keystone.c | 26 ++++++++++++++++++++++++++
>>>>   1 file changed, 26 insertions(+)
>>>>
>>>> diff --git a/arch/arm/mach-keystone/keystone.c
>>>> b/arch/arm/mach-keystone/keystone.c
>>>> index e2880105..c1d0fe5 100644
>>>> --- a/arch/arm/mach-keystone/keystone.c
>>>> +++ b/arch/arm/mach-keystone/keystone.c
>>>> @@ -15,6 +15,7 @@
>>>>   #include <linux/of_platform.h>
>>>>   #include <linux/of_address.h>
>>>>   #include <linux/memblock.h>
>>>> +#include <linux/signal.h>
>>>>
>>>>   #include <asm/setup.h>
>>>>   #include <asm/mach/map.h>
>>>> @@ -52,6 +53,24 @@ static struct notifier_block platform_nb = {
>>>>       .notifier_call = keystone_platform_notifier,
>>>>   };
>>>>
>>>> +static bool ignore_first = true;
>>>> +static int keystone_async_ext_abort_fault(unsigned long addr,
>>>> unsigned int fsr,
>>>> +                      struct pt_regs *regs)
>>>> +{
>>>> +    /*
>>>> +     * if first time, ignore this as this is a asynchronous
>>>> external abort
>>>> +     * happening only some devices that couldn't be root caused and
>>>> we add
>>>> +     * this work around to handle this first time.
>>>> +     */
>>>> +    if (ignore_first) {
>>>> +        ignore_first = false;
>>>> +        return 0;
>>>> +    }
>>>> +
>>>> +    /* Subsequent ones should be handled as fault */
>>>> +    return 1;
>>>> +}
>>>> +
>>>>   static void __init keystone_init(void)
>>>>   {
>>>>       if (PHYS_OFFSET >= KEYSTONE_HIGH_PHYS_START) {
>>>> @@ -61,6 +80,13 @@ static void __init keystone_init(void)
>>>>       }
>>>>       keystone_pm_runtime_init();
>>>>       of_platform_populate(NULL, of_default_bus_match_table, NULL,
>>>> NULL);
>>>> +
>>>> +    /*
>>>> +     * Add a one time exception handler to catch asynchronous external
>>>> +     * abort
>>>> +     */
>>>> +    hook_fault_code(17, keystone_async_ext_abort_fault, SIGBUS, 0,
>>>> +            "async external abort handler");
>>>>   }
>>>>
>>>>   static phys_addr_t keystone_virt_to_idmap(unsigned long x)
>>>>
>>> Can this be applied if it looks good?
>>
>> What causes the abort?  We shouldn't be adding hacks like this to the
>> kernel without having the full picture...
>>
> Indeed. These external aborts are notorious and often hides dangerous
> bugs. On OMAP as well many folks burn their had with it till the
> interconnect handlers were added to detect those and hunt those
> bugs.
>
> In my experience such aborts happen outside ARM subsystem, either in
> the interconnect or at the salve targets which are reported over
> the ARM bus as async external aborts. And often these errors are
> due to bad accesses/wrong accesses/un-clocked accesses at slaves.
>
We have spend some time already to debug the root cause. Do you have 
idea on how this was hunted down on OMAP that we can learn from? The bad 
address is NULL and it seems to happen very rarely and is not easily 
reproducible. Don't want to put this workaround, but we couldn't track 
it down either. So any help to debug this will be appreciated.

Murali

> Regards,
> Santosh
>
>
>


-- 
Murali Karicheri
Linux Kernel, Keystone


From m-karicheri2 at ti.com  Fri Aug 14 14:55:09 2015
From: m-karicheri2 at ti.com (Murali Karicheri)
Date: Fri, 14 Aug 2015 17:55:09 -0400
Subject: [PATCH] ARM: keystone: add a work around to handle asynchronous
 external abort
In-Reply-To: <1439562059.13210.61.camel@pengutronix.de>
References: <1439320409-20084-1-git-send-email-m-karicheri2@ti.com>	
 <55CDF579.4050408@ti.com> <20150814140934.GX7557@n2100.arm.linux.org.uk>
 <1439562059.13210.61.camel@pengutronix.de>
Message-ID: <55CE63BD.2060107@ti.com>

On 08/14/2015 10:20 AM, Lucas Stach wrote:
> Hi Russell,
>
> Am Freitag, den 14.08.2015, 15:09 +0100 schrieb Russell King - ARM
> Linux:
>
> [...]
>
>>
>> What causes the abort?  We shouldn't be adding hacks like this to the
>> kernel without having the full picture...
>>
>
> some of the issues with tracking down such imprecise external aborts are
> due to the fact that we only enable the signaling of those aborts on
> entering the user-space. So the first schedule() crashes on the previous
> dangling abort.
>
> I'm carrying this patch locally to enable imprecise aborts much earlier
> in the boot process. I think it has already been on the list some times,
> but apparently it has fallen through the cracks. If you agree that this
> is the right thing to do I can do a proper repost.
Lucas,

Would you mind sharing the code? Does that help in root causing where it 
actually happens? I have spend considerable time debugging this, but so 
far not successful.

Murali
>
> Regards,
> Lucas
>
> ---------------------->8---------------------------------------------
>>From bb9117d94cc2f1061dc364f42c446ccd9191e869 Mon Sep 17 00:00:00 2001
> From: Lucas Stach <l.stach at pengutronix.de>
> Date: Thu, 19 Feb 2015 18:12:50 +0100
> Subject: [PATCH] ARM: Add imprecise abort enable/disable macro
>
> This patch adds imprecise abort enable/disable macros.
> It also enables imprecise aborts when starting kernel.
>
> Changes in v2:
> Only ARMv6 and later have CPSR.A bit. On earlier CPUs,
> and ARMv7M this should be a no-op.
>
> Signed-off-by: Fabrice Gasnier <fabrice.gasnier at st.com>
> Signed-off-by: Lucas Stach <l.stach at pengutronix.de>
> ---
> lst: rebased on v3.19
> ---
>   arch/arm/include/asm/irqflags.h | 10 ++++++++++
>   arch/arm/kernel/smp.c           |  1 +
>   arch/arm/kernel/traps.c         |  4 ++++
>   3 files changed, 15 insertions(+)
>
> diff --git a/arch/arm/include/asm/irqflags.h
> b/arch/arm/include/asm/irqflags.h
> index 3b763d6652a0..8301f875564e 100644
> --- a/arch/arm/include/asm/irqflags.h
> +++ b/arch/arm/include/asm/irqflags.h
> @@ -51,6 +51,14 @@ static inline void arch_local_irq_disable(void)
>
>   #define local_fiq_enable()  __asm__("cpsie f   @ __stf" : : : "memory",
> "cc")
>   #define local_fiq_disable() __asm__("cpsid f   @ __clf" : : : "memory",
> "cc")
> +
> +#ifndef CONFIG_CPU_V7M
> +#define local_abt_enable()  __asm__("cpsie a   @ __sta" : : : "memory",
> "cc")
> +#define local_abt_disable() __asm__("cpsid a   @ __cla" : : : "memory",
> "cc")
> +#else
> +#define local_abt_enable()     do { } while (0)
> +#define local_abt_disable()    do { } while (0)
> +#endif
>   #else
>
>   /*
> @@ -130,6 +138,8 @@ static inline void arch_local_irq_disable(void)
>          : "memory", "cc");                                      \
>          })
>
> +#define local_abt_enable()     do { } while (0)
> +#define local_abt_disable()    do { } while (0)
>   #endif
>
>   /*
> diff --git a/arch/arm/kernel/smp.c b/arch/arm/kernel/smp.c
> index 86ef244c5a24..7b6b93cabef4 100644
> --- a/arch/arm/kernel/smp.c
> +++ b/arch/arm/kernel/smp.c
> @@ -378,6 +378,7 @@ asmlinkage void secondary_start_kernel(void)
>
>          local_irq_enable();
>          local_fiq_enable();
> +       local_abt_enable();
>
>          /*
>           * OK, it's off to the idle thread for us
> diff --git a/arch/arm/kernel/traps.c b/arch/arm/kernel/traps.c
> index 788e23fe64d8..466726ba9bdb 100644
> --- a/arch/arm/kernel/traps.c
> +++ b/arch/arm/kernel/traps.c
> @@ -881,6 +881,10 @@ void __init early_trap_init(void *vectors_base)
>
>          flush_icache_range(vectors, vectors + PAGE_SIZE * 2);
>          modify_domain(DOMAIN_USER, DOMAIN_CLIENT);
> +
> +       /* Enable imprecise aborts */
> +       local_abt_enable();
> +
>   #else /* ifndef CONFIG_CPU_V7M */
>          /*
>           * on V7-M there is no need to copy the vector table to a
> dedicated
>


-- 
Murali Karicheri
Linux Kernel, Keystone


From arnd at arndb.de  Fri Aug 14 14:56:46 2015
From: arnd at arndb.de (Arnd Bergmann)
Date: Fri, 14 Aug 2015 23:56:46 +0200
Subject: [PATCH 2/3] Display a DMA error message
In-Reply-To: <55CE612C.4010405@arm.com>
References: <1439416290-21228-1-git-send-email-jeremy.linton@arm.com>
 <2099290.n6l88bWDgg@wuerfel> <55CE612C.4010405@arm.com>
Message-ID: <3034536.ALogCXmi9A@wuerfel>

On Friday 14 August 2015 16:44:12 Jeremy Linton wrote:
> On 08/14/2015 04:19 PM, Arnd Bergmann wrote:
> > On Wednesday 12 August 2015 16:51:29 Jeremy Linton wrote:
> >> diff --git a/drivers/usb/host/ehci-platform.c b/drivers/usb/host/ehci-platform.c
> >> index 2593def..82e396f 100644
> >> --- a/drivers/usb/host/ehci-platform.c
> >> +++ b/drivers/usb/host/ehci-platform.c
> >> @@ -162,8 +162,10 @@ static int ehci_platform_probe(struct platform_device *dev)
> >>
> >>          err = dma_coerce_mask_and_coherent(&dev->dev,
> >>                  pdata->dma_mask_64 ? DMA_BIT_MASK(64) : DMA_BIT_MASK(32));
> >> -       if (err)
> >> +       if (err) {
> >> +               dev_err(&dev->dev, "Error: DMA setup failed\n");
> >>                  return err;
> >> +       }
> >
> > We should really stop doing this: the platform should provide the
> > correct dma mask when creating the device, instead of setting a
> > bogus pdata field. Do not duplicate this bug for ACPI.
> 
> 
> I'm not sure I understand, I'm not changing the mask anywhere, all I'm 
> doing is printing a message if the mask cannot be set.

The problem is that dma_coerce_mask_and_coherent() is not a proper
interface for a driver to use, it's an annotation that tells us
that the driver is trying to do something horrible by overriding
the dma mask that was set by the platform.

> AKA if CCA is missing or set to 0 then, this line is triggered because 
> the dma_coerce_mask_and_coherent() routine returns with a failure 
> indicating there aren't any DMA ops to set a mask on. Right now what 
> happens is the device detection displays that there is an EHCI 
> controller then silently disappears with telling the user why it didn't 
> configure.

Adding a warning is fine, but the text is not right here (the driver is
not setting up the dma mask, but trying to override the one that has been
set up by the platform), and the solution should really be to not
call dma_coerce_mask_and_coherent() at all for ACPI. The main reason
that we have not removed this call here yet is that there is still a
MIPS platform that relies on it. We should probably remove it for DT
already and only do it if platform data was provided, but that requires
careful testing.

	Arnd


From linux at arm.linux.org.uk  Fri Aug 14 14:56:17 2015
From: linux at arm.linux.org.uk (Russell King - ARM Linux)
Date: Fri, 14 Aug 2015 22:56:17 +0100
Subject: [PATCH] ARM: keystone: add a work around to handle asynchronous
 external abort
In-Reply-To: <55CE633C.10402@ti.com>
References: <1439320409-20084-1-git-send-email-m-karicheri2@ti.com>
 <55CDF579.4050408@ti.com>
 <20150814140934.GX7557@n2100.arm.linux.org.uk>
 <55CE05EC.4040909@oracle.com> <55CE633C.10402@ti.com>
Message-ID: <20150814215617.GA7557@n2100.arm.linux.org.uk>

On Fri, Aug 14, 2015 at 05:53:00PM -0400, Murali Karicheri wrote:
> We have spend some time already to debug the root cause. Do you have idea on
> how this was hunted down on OMAP that we can learn from? The bad address is
> NULL and it seems to happen very rarely and is not easily reproducible.
> Don't want to put this workaround, but we couldn't track it down either. So
> any help to debug this will be appreciated.

If you try applying Lucas' patch, you should receive the abort earlier
in the kernel boot up, which may help narrow down what is provoking it.

-- 
FTTC broadband for 0.8mile line: currently at 10.5Mbps down 400kbps up
according to speedtest.net.


From linux at arm.linux.org.uk  Fri Aug 14 14:56:58 2015
From: linux at arm.linux.org.uk (Russell King - ARM Linux)
Date: Fri, 14 Aug 2015 22:56:58 +0100
Subject: [PATCH] ARM: keystone: add a work around to handle asynchronous
 external abort
In-Reply-To: <55CE63BD.2060107@ti.com>
References: <1439320409-20084-1-git-send-email-m-karicheri2@ti.com>
 <55CDF579.4050408@ti.com>
 <20150814140934.GX7557@n2100.arm.linux.org.uk>
 <1439562059.13210.61.camel@pengutronix.de>
 <55CE63BD.2060107@ti.com>
Message-ID: <20150814215658.GB7557@n2100.arm.linux.org.uk>

On Fri, Aug 14, 2015 at 05:55:09PM -0400, Murali Karicheri wrote:
> On 08/14/2015 10:20 AM, Lucas Stach wrote:
> >Hi Russell,
> >
> >Am Freitag, den 14.08.2015, 15:09 +0100 schrieb Russell King - ARM
> >Linux:
> >
> >[...]
> >
> >>
> >>What causes the abort?  We shouldn't be adding hacks like this to the
> >>kernel without having the full picture...
> >>
> >
> >some of the issues with tracking down such imprecise external aborts are
> >due to the fact that we only enable the signaling of those aborts on
> >entering the user-space. So the first schedule() crashes on the previous
> >dangling abort.
> >
> >I'm carrying this patch locally to enable imprecise aborts much earlier
> >in the boot process. I think it has already been on the list some times,
> >but apparently it has fallen through the cracks. If you agree that this
> >is the right thing to do I can do a proper repost.
> Lucas,
> 
> Would you mind sharing the code? Does that help in root causing where it
> actually happens? I have spend considerable time debugging this, but so far
> not successful.

If you look below, Lucas provided the patch.

> 
> Murali
> >
> >Regards,
> >Lucas
> >
> >---------------------->8---------------------------------------------
> >>From bb9117d94cc2f1061dc364f42c446ccd9191e869 Mon Sep 17 00:00:00 2001
> >From: Lucas Stach <l.stach at pengutronix.de>
> >Date: Thu, 19 Feb 2015 18:12:50 +0100
> >Subject: [PATCH] ARM: Add imprecise abort enable/disable macro
> >
> >This patch adds imprecise abort enable/disable macros.
> >It also enables imprecise aborts when starting kernel.
> >
> >Changes in v2:
> >Only ARMv6 and later have CPSR.A bit. On earlier CPUs,
> >and ARMv7M this should be a no-op.
> >
> >Signed-off-by: Fabrice Gasnier <fabrice.gasnier at st.com>
> >Signed-off-by: Lucas Stach <l.stach at pengutronix.de>
> >---
> >lst: rebased on v3.19
> >---
> >  arch/arm/include/asm/irqflags.h | 10 ++++++++++
> >  arch/arm/kernel/smp.c           |  1 +
> >  arch/arm/kernel/traps.c         |  4 ++++
> >  3 files changed, 15 insertions(+)
> >
> >diff --git a/arch/arm/include/asm/irqflags.h
> >b/arch/arm/include/asm/irqflags.h
> >index 3b763d6652a0..8301f875564e 100644
> >--- a/arch/arm/include/asm/irqflags.h
> >+++ b/arch/arm/include/asm/irqflags.h
> >@@ -51,6 +51,14 @@ static inline void arch_local_irq_disable(void)
> >
> >  #define local_fiq_enable()  __asm__("cpsie f   @ __stf" : : : "memory",
> >"cc")
> >  #define local_fiq_disable() __asm__("cpsid f   @ __clf" : : : "memory",
> >"cc")
> >+
> >+#ifndef CONFIG_CPU_V7M
> >+#define local_abt_enable()  __asm__("cpsie a   @ __sta" : : : "memory",
> >"cc")
> >+#define local_abt_disable() __asm__("cpsid a   @ __cla" : : : "memory",
> >"cc")
> >+#else
> >+#define local_abt_enable()     do { } while (0)
> >+#define local_abt_disable()    do { } while (0)
> >+#endif
> >  #else
> >
> >  /*
> >@@ -130,6 +138,8 @@ static inline void arch_local_irq_disable(void)
> >         : "memory", "cc");                                      \
> >         })
> >
> >+#define local_abt_enable()     do { } while (0)
> >+#define local_abt_disable()    do { } while (0)
> >  #endif
> >
> >  /*
> >diff --git a/arch/arm/kernel/smp.c b/arch/arm/kernel/smp.c
> >index 86ef244c5a24..7b6b93cabef4 100644
> >--- a/arch/arm/kernel/smp.c
> >+++ b/arch/arm/kernel/smp.c
> >@@ -378,6 +378,7 @@ asmlinkage void secondary_start_kernel(void)
> >
> >         local_irq_enable();
> >         local_fiq_enable();
> >+       local_abt_enable();
> >
> >         /*
> >          * OK, it's off to the idle thread for us
> >diff --git a/arch/arm/kernel/traps.c b/arch/arm/kernel/traps.c
> >index 788e23fe64d8..466726ba9bdb 100644
> >--- a/arch/arm/kernel/traps.c
> >+++ b/arch/arm/kernel/traps.c
> >@@ -881,6 +881,10 @@ void __init early_trap_init(void *vectors_base)
> >
> >         flush_icache_range(vectors, vectors + PAGE_SIZE * 2);
> >         modify_domain(DOMAIN_USER, DOMAIN_CLIENT);
> >+
> >+       /* Enable imprecise aborts */
> >+       local_abt_enable();
> >+
> >  #else /* ifndef CONFIG_CPU_V7M */
> >         /*
> >          * on V7-M there is no need to copy the vector table to a
> >dedicated
> >
> 
> 
> -- 
> Murali Karicheri
> Linux Kernel, Keystone

-- 
FTTC broadband for 0.8mile line: currently at 10.5Mbps down 400kbps up
according to speedtest.net.


From heiko at sntech.de  Fri Aug 14 15:13:49 2015
From: heiko at sntech.de (Heiko =?ISO-8859-1?Q?St=FCbner?=)
Date: Sat, 15 Aug 2015 00:13:49 +0200
Subject: [RFC PATCH v5 1/9] mmc: dw_mmc: Add external dma interface support
In-Reply-To: <1439541275-30146-1-git-send-email-shawn.lin@rock-chips.com>
References: <1439541232-30100-1-git-send-email-shawn.lin@rock-chips.com>
 <1439541275-30146-1-git-send-email-shawn.lin@rock-chips.com>
Message-ID: <1522710.BT6Gc0L6oH@diego>

Hi Shawn,

Am Freitag, 14. August 2015, 16:34:35 schrieb Shawn Lin:
> DesignWare MMC Controller can supports two types of DMA
> mode: external dma and internal dma. We get a RK312x platform
> integrated dw_mmc and ARM pl330 dma controller. This patch add
> edmac ops to support these platforms. I've tested it on RK312x
> platform with edmac mode and RK3288 platform with idmac mode.
> 
> Signed-off-by: Shawn Lin <shawn.lin at rock-chips.com>

judging by your "from", I guess you're running this on some older Rockchip soc 
without the idma? Because I tried testing this on a Radxa Rock, but only got 
failures, from the start (failed to read card status register). In PIO mode 
everything works again.


I guess I overlooked just some tiny detail, but to me the dma channel ids seem 
correct after all. Maybe you have any hints what I'm doing wrong?

diff --git a/arch/arm/boot/dts/rk3xxx.dtsi b/arch/arm/boot/dts/rk3xxx.dtsi
index 4497d28..92d7156 100644
--- a/arch/arm/boot/dts/rk3xxx.dtsi
+++ b/arch/arm/boot/dts/rk3xxx.dtsi
@@ -217,6 +217,8 @@
                interrupts = <GIC_SPI 23 IRQ_TYPE_LEVEL_HIGH>;
                clocks = <&cru HCLK_SDMMC>, <&cru SCLK_SDMMC>;
                clock-names = "biu", "ciu";
+             dmas = <&dmac2 1>;
+             dma-names = "rx-tx";
                fifo-depth = <256>;
                status = "disabled";
        };
@@ -227,6 +229,8 @@
                interrupts = <GIC_SPI 24 IRQ_TYPE_LEVEL_HIGH>;
                clocks = <&cru HCLK_SDIO>, <&cru SCLK_SDIO>;
                clock-names = "biu", "ciu";
+             dmas = <&dmac2 3>;
+             dma-names = "rx-tx";
                fifo-depth = <256>;
                status = "disabled";
        };
@@ -237,6 +241,8 @@
                interrupts = <GIC_SPI 25 IRQ_TYPE_LEVEL_HIGH>;
                clocks = <&cru HCLK_EMMC>, <&cru SCLK_EMMC>;
                clock-names = "biu", "ciu";
+             dmas = <&dmac2 4>;
+             dma-names = "rx-tx";
                fifo-depth = <256>;
                status = "disabled";
        };


[...]

> diff --git a/drivers/mmc/host/dw_mmc.c b/drivers/mmc/host/dw_mmc.c
> index fcbf552..e01ead3 100644
> --- a/drivers/mmc/host/dw_mmc.c
> +++ b/drivers/mmc/host/dw_mmc.c
> @@ -2517,8 +2642,23 @@ static void dw_mci_cleanup_slot(struct dw_mci_slot
> *slot, unsigned int id) static void dw_mci_init_dma(struct dw_mci *host)
>  {
>  	int addr_config;
> +	int trans_mode;
> +	struct device *dev = host->dev;
> +	struct device_node *np = dev->of_node;
> +
> +	/* Check tansfer mode */
> +	trans_mode = SDMMC_GET_TRANS_MODE(mci_readl(host, HCON));
> +	if (trans_mode == 0) {
> +		trans_mode = TRANS_MODE_IDMAC;
> +	} else if (trans_mode == 1 || trans_mode == 2) {
> +		trans_mode = TRANS_MODE_EDMAC;
> +	} else {
> +		trans_mode = TRANS_MODE_PIO;
> +		goto no_dma;
> +	}
> +
>  	/* Check ADDR_CONFIG bit in HCON to find IDMAC address bus width */
> -	addr_config = (mci_readl(host, HCON) >> 27) & 0x01;
> +	addr_config = SDMMC_GET_ADDR_CONFIG(mci_readl(host, HCON));
> 
>  	if (addr_config == 1) {
>  		/* host supports IDMAC in 64-bit address mode */

I guess the idmac address size checking block

        /* Check ADDR_CONFIG bit in HCON to find IDMAC address bus width */
        addr_config = SDMMC_GET_ADDR_CONFIG(mci_readl(host, HCON));

        if (addr_config == 1) {
                /* host supports IDMAC in 64-bit address mode */
                host->dma_64bit_address = 1;
                dev_info(host->dev, "IDMAC supports 64-bit address mode.\n");
                if (!dma_set_mask(host->dev, DMA_BIT_MASK(64)))
                        dma_set_coherent_mask(host->dev, DMA_BIT_MASK(64));
        } else {
                /* host supports IDMAC in 32-bit address mode */
                host->dma_64bit_address = 0;
                dev_info(host->dev, "IDMAC supports 32-bit address mode.\n");
        }

could either live inside the trans_mode == 0 conditional above or get its own
if (trans_mode == 0) conditional. Either way I guess it should not talk about 
idmac when either pio or extdmac are used.


Thanks
Heiko


From dmitry.torokhov at gmail.com  Fri Aug 14 15:53:46 2015
From: dmitry.torokhov at gmail.com (Dmitry Torokhov)
Date: Fri, 14 Aug 2015 15:53:46 -0700
Subject: [PATCH v3 3/3] touchscreen: colibri-vf50-ts: Add touchscreen
 support for Colibri VF50
In-Reply-To: <bb234514d6921c3d184930d78e7822381c481b79.1438763030.git.maitysanchayan@gmail.com>
References: <cover.1438763030.git.maitysanchayan@gmail.com>
 <bb234514d6921c3d184930d78e7822381c481b79.1438763030.git.maitysanchayan@gmail.com>
Message-ID: <20150814225346.GA9160@dtor-ws>

Hi Sanchayan,

On Wed, Aug 05, 2015 at 02:25:51PM +0530, Sanchayan Maity wrote:
> The Colibri Vybrid VF50 module supports 4-wire touchscreens using
> FETs and ADC inputs. This driver uses the IIO consumer interface
> and relies on the vf610_adc driver based on the IIO framework.
> 
> Signed-off-by: Sanchayan Maity <maitysanchayan at gmail.com>
> ---
>  drivers/input/touchscreen/Kconfig           |  12 +
>  drivers/input/touchscreen/Makefile          |   1 +
>  drivers/input/touchscreen/colibri-vf50-ts.c | 404 ++++++++++++++++++++++++++++
>  3 files changed, 417 insertions(+)
>  create mode 100644 drivers/input/touchscreen/colibri-vf50-ts.c
> 
> diff --git a/drivers/input/touchscreen/Kconfig b/drivers/input/touchscreen/Kconfig
> index 80f6386..28948ca 100644
> --- a/drivers/input/touchscreen/Kconfig
> +++ b/drivers/input/touchscreen/Kconfig
> @@ -1027,4 +1027,16 @@ config TOUCHSCREEN_ZFORCE
>  	  To compile this driver as a module, choose M here: the
>  	  module will be called zforce_ts.
>  
> +config TOUCHSCREEN_COLIBRI_VF50
> +	tristate "Toradex Colibri on board touchscreen driver"
> +	depends on GPIOLIB && IIO && VF610_ADC
> +	help
> +	  Say Y here if you have a Colibri VF50 and plan to use
> +	  the on-board provided 4-wire touchscreen driver.
> +
> +	  If unsure, say N.
> +
> +	  To compile this driver as a module, choose M here: the
> +	  module will be called colibri_vf50_ts.
> +
>  endif
> diff --git a/drivers/input/touchscreen/Makefile b/drivers/input/touchscreen/Makefile
> index 44deea7..93746a0 100644
> --- a/drivers/input/touchscreen/Makefile
> +++ b/drivers/input/touchscreen/Makefile
> @@ -84,3 +84,4 @@ obj-$(CONFIG_TOUCHSCREEN_W90X900)	+= w90p910_ts.o
>  obj-$(CONFIG_TOUCHSCREEN_SX8654)	+= sx8654.o
>  obj-$(CONFIG_TOUCHSCREEN_TPS6507X)	+= tps6507x-ts.o
>  obj-$(CONFIG_TOUCHSCREEN_ZFORCE)	+= zforce_ts.o
> +obj-$(CONFIG_TOUCHSCREEN_COLIBRI_VF50)	+= colibri-vf50-ts.o
> diff --git a/drivers/input/touchscreen/colibri-vf50-ts.c b/drivers/input/touchscreen/colibri-vf50-ts.c
> new file mode 100644
> index 0000000..d7bc91a
> --- /dev/null
> +++ b/drivers/input/touchscreen/colibri-vf50-ts.c
> @@ -0,0 +1,404 @@
> +/* Copyright 2015 Toradex AG
> + *
> + * Toradex Colibri VF50 Touchscreen driver
> + *
> + * Originally authored by Stefan Agner for 3.0 kernel
> + *
> + * 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.
> + */
> +
> +#include <linux/delay.h>
> +#include <linux/err.h>
> +#include <linux/gpio.h>
> +#include <linux/iio/consumer.h>
> +#include <linux/iio/types.h>
> +#include <linux/input.h>
> +#include <linux/interrupt.h>
> +#include <linux/kernel.h>
> +#include <linux/module.h>
> +#include <linux/pinctrl/consumer.h>
> +#include <linux/platform_device.h>
> +#include <linux/slab.h>
> +#include <linux/types.h>
> +
> +#define DRIVER_NAME "colibri-vf50-ts"
> +#define DRV_VERSION "1.0"
> +
> +#define VF_ADC_MAX ((1 << 12) - 1)
> +
> +#define COLI_TOUCH_MIN_DELAY_US 1000
> +#define COLI_TOUCH_MAX_DELAY_US 2000
> +
> +static int min_pressure = 200;
> +
> +struct vf50_touch_device {
> +	struct platform_device	*pdev;
> +	struct input_dev	*ts_input;
> +	struct iio_channel	*channels;
> +	struct gpio_desc *gpio_xp;
> +	struct gpio_desc *gpio_xm;
> +	struct gpio_desc *gpio_yp;
> +	struct gpio_desc *gpio_ym;
> +	struct gpio_desc *gpio_pen_detect;
> +	int pen_irq;
> +	bool stop_touchscreen;
> +};
> +
> +/*
> + * Enables given plates and measures touch parameters using ADC
> + */
> +static int adc_ts_measure(struct iio_channel *channel,
> +		  struct gpio_desc *plate_p, struct gpio_desc *plate_m)
> +{
> +	int i, value = 0, val = 0;
> +	int ret;
> +
> +	gpiod_set_value(plate_p, 1);
> +	gpiod_set_value(plate_m, 1);
> +
> +	usleep_range(COLI_TOUCH_MIN_DELAY_US, COLI_TOUCH_MAX_DELAY_US);
> +
> +	for (i = 0; i < 5; i++) {

Can we have a #define for 5?

> +		ret = iio_read_channel_raw(channel, &val);
> +		if (ret < 0) {
> +			value = ret;
> +			goto error_iio_read;
> +		}
> +
> +		value += val;
> +	}
> +
> +	value /= 5;
> +
> +error_iio_read:
> +	gpiod_set_value(plate_p, 0);
> +	gpiod_set_value(plate_m, 0);
> +
> +	return value;
> +}
> +
> +/*
> + * Enable touch detection using falling edge detection on XM
> + */
> +static void vf50_ts_enable_touch_detection(struct vf50_touch_device *vf50_ts)
> +{
> +	/* Enable plate YM (needs to be strong GND, high active) */
> +	gpiod_set_value(vf50_ts->gpio_ym, 1);
> +
> +	/*
> +	 * Let the platform mux to idle state in order to enable
> +	 * Pull-Up on GPIO
> +	 */
> +	pinctrl_pm_select_idle_state(&vf50_ts->pdev->dev);
> +}
> +
> +/*
> + * ADC touch screen sampling bottom half irq handler
> + */
> +static irqreturn_t vf50_ts_irq_bh(int irq, void *private)
> +{
> +	struct vf50_touch_device *vf50_ts = (struct vf50_touch_device *)private;
> +	struct device *dev = &vf50_ts->pdev->dev;
> +	int val_x, val_y, val_z1, val_z2, val_p = 0;
> +	bool discard_val_on_start = true;
> +
> +	/* Disable the touch detection plates */
> +	gpiod_set_value(vf50_ts->gpio_ym, 0);
> +
> +	/* Let the platform mux to default state in order to mux as ADC */
> +	pinctrl_pm_select_default_state(dev);
> +
> +	while (!vf50_ts->stop_touchscreen) {
> +		/* X-Direction */
> +		val_x = adc_ts_measure(&vf50_ts->channels[0],
> +				vf50_ts->gpio_xp, vf50_ts->gpio_xm);
> +		if (val_x < 0)
> +			break;
> +
> +		/* Y-Direction */
> +		val_y = adc_ts_measure(&vf50_ts->channels[1],
> +				vf50_ts->gpio_yp, vf50_ts->gpio_ym);
> +		if (val_y < 0)
> +			break;
> +
> +		/*
> +		 * Touch pressure
> +		 * Measure on XP/YM
> +		 */
> +		val_z1 = adc_ts_measure(&vf50_ts->channels[2],
> +				vf50_ts->gpio_yp, vf50_ts->gpio_xm);
> +		if (val_z1 < 0)
> +			break;
> +		val_z2 = adc_ts_measure(&vf50_ts->channels[3],
> +				vf50_ts->gpio_yp, vf50_ts->gpio_xm);
> +		if (val_z2 < 0)
> +			break;
> +
> +		/* Validate signal (avoid calculation using noise) */
> +		if (val_z1 > 64 && val_x > 64) {
> +			/*
> +			 * Calculate resistance between the plates
> +			 * lower resistance means higher pressure
> +			 */
> +			int r_x = (1000 * val_x) / VF_ADC_MAX;
> +
> +			val_p = (r_x * val_z2) / val_z1 - r_x;
> +
> +		} else {
> +			val_p = 2000;
> +		}
> +
> +		val_p = 2000 - val_p;
> +		dev_dbg(dev, "Measured values: x: %d, y: %d, z1: %d, z2: %d, "
> +			"p: %d\n", val_x, val_y, val_z1, val_z2, val_p);
> +
> +		/*
> +		 * If touch pressure is too low, stop measuring and reenable
> +		 * touch detection
> +		 */
> +		if (val_p < min_pressure || val_p > 2000)
> +			break;
> +
> +		/*
> +		 * The pressure may not be enough for the first x and the
> +		 * second y measurement, but, the pressure is ok when the
> +		 * driver is doing the third and fourth measurement. To
> +		 * take care of this, we drop the first measurement always.
> +		 */
> +		if (discard_val_on_start) {
> +			discard_val_on_start = false;
> +		} else {
> +			/*
> +			 * Report touch position and sleep for
> +			 * next measurement
> +			 */
> +			input_report_abs(vf50_ts->ts_input,
> +					ABS_X, VF_ADC_MAX - val_x);
> +			input_report_abs(vf50_ts->ts_input,
> +					ABS_Y, VF_ADC_MAX - val_y);
> +			input_report_abs(vf50_ts->ts_input,
> +					ABS_PRESSURE, val_p);
> +			input_report_key(vf50_ts->ts_input, BTN_TOUCH, 1);
> +			input_sync(vf50_ts->ts_input);
> +		}
> +
> +		msleep(10);
> +	}
> +
> +	/* Report no more touch, reenable touch detection */
> +	input_report_abs(vf50_ts->ts_input, ABS_PRESSURE, 0);
> +	input_report_key(vf50_ts->ts_input, BTN_TOUCH, 0);
> +	input_sync(vf50_ts->ts_input);
> +
> +	vf50_ts_enable_touch_detection(vf50_ts);
> +
> +	/* Wait for the pull-up to be stable on high */
> +	msleep(10);
> +
> +	return IRQ_HANDLED;
> +}
> +
> +static int vf50_ts_open(struct input_dev *dev_input)
> +{
> +	int ret;
> +	struct vf50_touch_device *touchdev = input_get_drvdata(dev_input);
> +	struct device *dev = &touchdev->pdev->dev;
> +
> +	dev_dbg(dev, "Input device %s opened, starting touch detection\n",
> +			dev_input->name);
> +
> +	touchdev->stop_touchscreen = false;
> +
> +	ret = gpiod_direction_output(touchdev->gpio_xp, 0);
> +	if (ret) {
> +		dev_err(dev, "Could not set gpio xp as output %d\n", ret);
> +		return ret;
> +	}
> +
> +	ret = gpiod_direction_output(touchdev->gpio_xm, 0);
> +	if (ret) {
> +		dev_err(dev, "Could not set gpio xm as output %d\n", ret);
> +		return ret;
> +	}
> +
> +	ret = gpiod_direction_output(touchdev->gpio_yp, 0);
> +	if (ret) {
> +		dev_err(dev, "Could not set gpio yp as output %d\n", ret);
> +		return ret;
> +	}
> +
> +	ret = gpiod_direction_output(touchdev->gpio_ym, 0);
> +	if (ret) {
> +		dev_err(dev, "Could not set gpio ym as output %d\n", ret);
> +		return ret;
> +	}
> +
> +	ret = gpiod_direction_input(touchdev->gpio_pen_detect);
> +	if (ret) {
> +		dev_err(dev,
> +			"Could not set gpio pen detect as input %d\n", ret);
> +		return ret;
> +	}

Why do we do this on every open? You can configure gpios as you request
them.

> +
> +	/* Mux detection before request IRQ, wait for pull-up to settle */
> +	vf50_ts_enable_touch_detection(touchdev);
> +	msleep(10);
> +
> +	return 0;
> +}
> +
> +static void vf50_ts_close(struct input_dev *dev_input)
> +{
> +	struct vf50_touch_device *touchdev = input_get_drvdata(dev_input);
> +	struct device *dev = &touchdev->pdev->dev;
> +
> +	touchdev->stop_touchscreen = true;

I think you also need:

	mb();
	synchronize_irq(touchdev->irq);

to make sure interrupt routine is not running past close.

> +
> +	dev_dbg(dev, "Input device %s closed, disable touch detection\n",
> +		dev_input->name);
> +}
> +
> +static inline int vf50_ts_get_gpiod(struct device *dev,

Drop inline, let compiler decide whether it should be inlined or not.

> +			struct gpio_desc **gpio_d, const char *con_id)
> +{
> +	int ret;

Personal preference: call this variable "error".

> +
> +	*gpio_d = devm_gpiod_get(dev, con_id);

I think you need use GPIOD_OUT_LOW (assuming you do not use the function
for pen detect gpio, see below).

> +	if (IS_ERR(*gpio_d)) {
> +		ret = PTR_ERR(*gpio_d);
> +		dev_err(dev, "Could not get gpio_%s %d\n", con_id, ret);
> +		return ret;
> +	}
> +
> +	return 0;
> +}
> +
> +static int vf50_ts_probe(struct platform_device *pdev)
> +{
> +	struct input_dev *input;
> +	struct iio_channel *channels;
> +	struct device *dev = &pdev->dev;
> +	struct vf50_touch_device *touchdev;
> +	int ret;

Personal preference: call this variable "error".


> +
> +	channels = iio_channel_get_all(dev);
> +	if (IS_ERR(channels))
> +		return PTR_ERR(channels);


Please either introduce devm_iio_channel_get_all() or install
iio_channel_release_all as a custom devm action (devm_add_action).

> +
> +	touchdev = devm_kzalloc(dev, sizeof(*touchdev), GFP_KERNEL);
> +	if (touchdev == NULL) {

	if (!touchdev)

please.

> +		ret = -ENOMEM;
> +		goto error_release_channels;
> +	}
> +
> +	input = devm_input_allocate_device(dev);
> +	if (!input) {
> +		dev_err(dev, "Failed to allocate TS input device\n");
> +		ret = -ENOMEM;
> +		goto error_release_channels;
> +	}
> +
> +	platform_set_drvdata(pdev, touchdev);
> +
> +	touchdev->pdev = pdev;
> +	touchdev->channels = channels;
> +
> +	input->name = DRIVER_NAME;
> +	input->id.bustype = BUS_HOST;
> +	input->dev.parent = dev;
> +	input->open = vf50_ts_open;
> +	input->close = vf50_ts_close;
> +
> +	_set_bit(EV_ABS, input->evbit);
> +	_set_bit(EV_KEY, input->evbit);
> +	_set_bit(BTN_TOUCH, input->keybit);

input_set_capability(dev, EV_KEY, BTN_TOUCH);

and kill _set_bit()s above.

> +	input_set_abs_params(input, ABS_X, 0, VF_ADC_MAX, 0, 0);
> +	input_set_abs_params(input, ABS_Y, 0, VF_ADC_MAX, 0, 0);
> +	input_set_abs_params(input, ABS_PRESSURE, 0, VF_ADC_MAX, 0, 0);
> +
> +	touchdev->ts_input = input;
> +	input_set_drvdata(input, touchdev);
> +	ret = input_register_device(input);
> +	if (ret) {
> +		dev_err(dev, "Failed to register input device\n");
> +		goto error_release_channels;
> +	}
> +
> +	ret = vf50_ts_get_gpiod(dev, &touchdev->gpio_xp, "xp");
> +	if (ret)
> +		goto error_release_channels;
> +
> +	ret = vf50_ts_get_gpiod(dev, &touchdev->gpio_xm, "xm");
> +	if (ret)
> +		goto error_release_channels;
> +
> +	ret = vf50_ts_get_gpiod(dev, &touchdev->gpio_yp, "yp");
> +	if (ret)
> +		goto error_release_channels;
> +
> +	ret = vf50_ts_get_gpiod(dev, &touchdev->gpio_ym, "ym");
> +	if (ret)
> +		goto error_release_channels;
> +
> +	ret = vf50_ts_get_gpiod(dev, &touchdev->gpio_pen_detect,
> +				"pen-detect");
> +	if (ret)
> +		goto error_release_channels;
> +
> +	touchdev->pen_irq = gpiod_to_irq(touchdev->gpio_pen_detect);
> +	if (touchdev->pen_irq < 0) {
> +		ret = touchdev->pen_irq;
> +		dev_err(dev, "Unable to get IRQ for GPIO\n");
> +		goto error_release_channels;
> +	}

I do not think you need to specify this as gpio, since you are not
reading it's state. Map it using "interrupts" property instead and do

	touchdev->pen_irq = platform_get_irq(pdev, 0);

> +
> +	ret = devm_request_threaded_irq(dev, touchdev->pen_irq, NULL,
> +			vf50_ts_irq_bh, IRQF_TRIGGER_LOW | IRQF_ONESHOT,

Just use IRQF_ONESHOT here, rely on the platform/OF to read and set up
the trigger properly (via "interrupts" property).

> +			"vf50 touch", touchdev);
> +	if (ret < 0) {
> +		dev_err(dev, "Unable to request IRQ %d\n", touchdev->pen_irq);
> +		goto error_release_channels;
> +	}
> +
> +	return 0;
> +
> +error_release_channels:
> +	iio_channel_release_all(channels);
> +	return ret;
> +}
> +
> +static int vf50_ts_remove(struct platform_device *pdev)
> +{
> +	struct vf50_touch_device *touchdev = platform_get_drvdata(pdev);
> +
> +	iio_channel_release_all(touchdev->channels);

This is wrong order, I do not think you want to release channels while
your interrupt routine still running. With custom devm action you can
avoid this and also remove whole vf50_ts_remove.

> +
> +	return 0;
> +}
> +
> +static const struct of_device_id vf50_touch_of_match[] = {
> +	{ .compatible = "toradex,vf50-touchscreen", },
> +	{ }
> +};
> +MODULE_DEVICE_TABLE(of, vf50_touch_of_match);
> +
> +static struct platform_driver vf50_touch_driver = {
> +	.driver = {
> +		.name = "toradex,vf50_touchctrl",
> +		.of_match_table = vf50_touch_of_match,
> +	},
> +	.probe = vf50_ts_probe,
> +	.remove = vf50_ts_remove,
> +};
> +
> +module_platform_driver(vf50_touch_driver);
> +
> +module_param(min_pressure, int, 0600);
> +MODULE_PARM_DESC(min_pressure, "Minimum pressure for touch detection");

Since it is my understanding this is not user preference but rather
property of device, I'd rather this been part of DT binding.

> +MODULE_AUTHOR("Sanchayan Maity");
> +MODULE_DESCRIPTION("Colibri VF50 Touchscreen driver");
> +MODULE_LICENSE("GPL v2");
> +MODULE_VERSION(DRV_VERSION);
> -- 
> 2.5.0
> 

Thanks.

-- 
Dmitry


From leoli at freescale.com  Fri Aug 14 16:48:18 2015
From: leoli at freescale.com (Li Yang)
Date: Fri, 14 Aug 2015 18:48:18 -0500
Subject: [PATCH v2] dmaengine: fsl-edma: add PM suspend/resume support
In-Reply-To: <CY1PR0301MB15628DD5CFCE2B65BF4FECB2837C0@CY1PR0301MB1562.namprd03.prod.outlook.com>
References: <1437469005-3162-1-git-send-email-yao.yuan@freescale.com>
 <CADRPPNQJi_x+mdQV=DEVuhCL_p6VOWcPiV3jzioeRdWgSW2w3g@mail.gmail.com>
 <CY1PR0301MB15628DD5CFCE2B65BF4FECB2837C0@CY1PR0301MB1562.namprd03.prod.outlook.com>
Message-ID: <CADRPPNS_wzX+mwT0L-H=ZP9w8gH9W4O9KUqnGYiAc39S5v4qLA@mail.gmail.com>

On Fri, Aug 14, 2015 at 1:24 AM, Yao Yuan <yao.yuan at freescale.com> wrote:
> Hi Leo,
>
> Thanks for your review.
> About those two methods for DMA suspend that you have mentioned. We have a lot of the discussions in other DMA driver like DMA for Freescale PowerPC.
>
> Finally, we think the device which used the DMA transmission service should cancel the transmission service in its suspend.
> So DMA in suspend should be idle.

If that's the case you should clearly state this in the commit message
and in code, although I don't know if it is safe to make such
assumption.  There could be user of the DMA that doesn't track the
completion of transfers.

>
> Once the DMA in late_suspend is not be idle, we think some driver haven't canceled the DMA transmission. So maybe something is error when other driver in suspend.
>
> In the case, we should return failed to stop PM. DMA should not make a choice for other drivers(which used DMA) to force stop DMA transmission.

The suspend entrance should be terminated by wakeup events and only
critical issues.  I don't think we should just terminate the suspend
entrance just because having on-going I/O without even try to stop it.

>
> Thanks.
>
> Best Regards,
> Yuan Yao
>
>> -----Original Message-----
>> From: pku.leo at gmail.com [mailto:pku.leo at gmail.com] On Behalf Of Li Yang
>> Sent: Friday, August 14, 2015 4:58 AM
>> To: Yuan Yao-B46683
>> Cc: Vinod Koul; stefan at agner.ch; Arnd Bergmann; Dan Williams;
>> dmaengine at vger.kernel.org; lkml; linux-arm-kernel at lists.infradead.org; linux-
>> pm at vger.kernel.org
>> Subject: Re: [PATCH v2] dmaengine: fsl-edma: add PM suspend/resume
>> support
>>
>> On Tue, Jul 21, 2015 at 3:56 AM, Yuan Yao <yao.yuan at freescale.com> wrote:
>> > This add power management suspend/resume support for the fsl-edma
>> > driver.
>> >
>> > eDMA acted as a basic function used by others. What it needs to do is
>> > the two steps below to support power management.
>> >
>> > In fsl_edma_suspend_late:
>> > Check whether the DMA chan is idle and if it is not idle, stop PM
>> > operation.
>>
>> You should try to quiesce the device on suspend instead of depending on itself
>> to be happen in idle and failing if it is not.
>>
>> Regards,
>> Leo



-- 
- Leo


From santosh.shilimkar at oracle.com  Fri Aug 14 17:01:49 2015
From: santosh.shilimkar at oracle.com (santosh.shilimkar at oracle.com)
Date: Fri, 14 Aug 2015 17:01:49 -0700
Subject: [PATCH] ARM: keystone: add a work around to handle asynchronous
 external abort
In-Reply-To: <55CE633C.10402@ti.com>
References: <1439320409-20084-1-git-send-email-m-karicheri2@ti.com>
 <55CDF579.4050408@ti.com> <20150814140934.GX7557@n2100.arm.linux.org.uk>
 <55CE05EC.4040909@oracle.com> <55CE633C.10402@ti.com>
Message-ID: <55CE816D.1020809@oracle.com>

On 8/14/15 2:53 PM, Murali Karicheri wrote:
> On 08/14/2015 11:14 AM, santosh shilimkar wrote:
>> On 8/14/2015 7:09 AM, Russell King - ARM Linux wrote:
>>> On Fri, Aug 14, 2015 at 10:04:41AM -0400, Murali Karicheri wrote:
>>>> On 08/11/2015 03:13 PM, Murali Karicheri wrote:
>>>>> Currently on some devices, an asynchronous external abort exception
>>>>> happens during boot up when exception handlers are enabled in kernel
>>>>> before switching to user space. This patch adds a workaround to handle
>>>>> this once during boot. Many customers are already using this
>>>>> with out any issues and is required to workaround the above issue.
>>>>>
>>>>> Signed-off-by: Murali Karicheri <m-karicheri2 at ti.com>
>>>>> ---
>>>>>   arch/arm/mach-keystone/keystone.c | 26 ++++++++++++++++++++++++++
>>>>>   1 file changed, 26 insertions(+)

[...]

>>>>> +
>>>>> +    /*
>>>>> +     * Add a one time exception handler to catch asynchronous
>>>>> external
>>>>> +     * abort
>>>>> +     */
>>>>> +    hook_fault_code(17, keystone_async_ext_abort_fault, SIGBUS, 0,
>>>>> +            "async external abort handler");
>>>>>   }
>>>>>
>>>>>   static phys_addr_t keystone_virt_to_idmap(unsigned long x)
>>>>>
>>>> Can this be applied if it looks good?
>>>
>>> What causes the abort?  We shouldn't be adding hacks like this to the
>>> kernel without having the full picture...
>>>
>> Indeed. These external aborts are notorious and often hides dangerous
>> bugs. On OMAP as well many folks burn their had with it till the
>> interconnect handlers were added to detect those and hunt those
>> bugs.
>>
>> In my experience such aborts happen outside ARM subsystem, either in
>> the interconnect or at the salve targets which are reported over
>> the ARM bus as async external aborts. And often these errors are
>> due to bad accesses/wrong accesses/un-clocked accesses at slaves.
>>
> We have spend some time already to debug the root cause. Do you have
> idea on how this was hunted down on OMAP that we can learn from? The bad
> address is NULL and it seems to happen very rarely and is not easily
> reproducible. Don't want to put this workaround, but we couldn't track
> it down either. So any help to debug this will be appreciated.
>
As RMK pointed out, try Lucas patch and see if it gives any useful
information to narrow it down.

On OMAP, fortunately interconnect has IRQ(s) which are hooked with
ARM subsystem. So the bus driver(drivers/bus/omap-l3*) was able to
handle those events and report the offenders.

Regards,
Santosh



From jianwei.wang.chn at gmail.com  Fri Aug 14 17:13:36 2015
From: jianwei.wang.chn at gmail.com (Jianwei Wang)
Date: Fri, 14 Aug 2015 20:13:36 -0400
Subject: [PATCH v14 3/6] drm/panel: simple: Add support for NEC
 NL4827HC19-05B 480x272 panel
In-Reply-To: <20150813122312.GC11095@ulmo>
References: <1438158605-28248-1-git-send-email-jianwei.wang.chn@gmail.com>
 <1438158605-28248-4-git-send-email-jianwei.wang.chn@gmail.com>
 <20150813122312.GC11095@ulmo>
Message-ID: <CANk3uyBZuBOZNHqNmiRTcFAEH6BOXhD2sS=EKsY_EHfzjY406Q@mail.gmail.com>

On Thu, Aug 13, 2015 at 8:23 AM, Thierry Reding
<thierry.reding at gmail.com> wrote:
> On Wed, Jul 29, 2015 at 04:30:02PM +0800, Jianwei Wang wrote:
>> This adds support for the NEC NL4827HC19-05B 480x272 panel to the DRM
>> simple panel driver.
>>
>> Signed-off-by: Alison Wang <b18965 at freescale.com>
>> Signed-off-by: Xiubo Li <lixiubo at cmss.chinamobile.com>
>> Signed-off-by: Jianwei Wang <jianwei.wang.chn at gmail.com>
>> Acked-by: Daniel Vetter <daniel.vetter at ffwll.ch>
>> ---
>>  .../bindings/panel/nec,nl4827hc19_05b.txt          |  7 ++++++
>>  drivers/gpu/drm/panel/panel-simple.c               | 26 ++++++++++++++++++++++
>>  2 files changed, 33 insertions(+)
>>  create mode 100644 Documentation/devicetree/bindings/panel/nec,nl4827hc19_05b.txt
>>
>> diff --git a/Documentation/devicetree/bindings/panel/nec,nl4827hc19_05b.txt b/Documentation/devicetree/bindings/panel/nec,nl4827hc19_05b.txt
>> new file mode 100644
>> index 0000000..20e9473
>> --- /dev/null
>> +++ b/Documentation/devicetree/bindings/panel/nec,nl4827hc19_05b.txt
>> @@ -0,0 +1,7 @@
>> +NEC LCD Technologies,Ltd. WQVGA TFT LCD panel
>> +
>> +Required properties:
>> +- compatible: should be "nec,nl4827hc19_05b"
>
> Underscores are deprecated in compatible strings, so I've applied this
> with "nec,nl4827hc19-05b".
>
> Thierry

Okay, thanks.

Jianwei


From gregkh at linuxfoundation.org  Fri Aug 14 17:16:32 2015
From: gregkh at linuxfoundation.org (Greg Kroah-Hartman)
Date: Fri, 14 Aug 2015 17:16:32 -0700
Subject: [PATCH 5/5] drivers/tty: make serial 8250_lpc18xx.c explicitly
 non-modular
In-Reply-To: <20150811060544.GJ9751@windriver.com>
References: <1439081497-14986-1-git-send-email-paul.gortmaker@windriver.com>
 <1439081497-14986-6-git-send-email-paul.gortmaker@windriver.com>
 <CAGhQ9Vxjymt4z32s3x2B8b6ypgn3Bzh1ncbqxqidfPyM2k87jw@mail.gmail.com>
 <20150811060544.GJ9751@windriver.com>
Message-ID: <20150815001632.GA20581@kroah.com>

On Tue, Aug 11, 2015 at 02:05:44AM -0400, Paul Gortmaker wrote:
> [Re: [PATCH 5/5] drivers/tty: make serial 8250_lpc18xx.c explicitly non-modular] On 10/08/2015 (Mon 20:42) Joachim Eastwood wrote:
> 
> > Hi Paul,
> > 
> > On 9 August 2015 at 02:51, Paul Gortmaker <paul.gortmaker at windriver.com> wrote:
> > > The Kconfig currently controlling compilation of this code is:
> > >
> > > 8250/Kconfig:config SERIAL_8250_LPC18XX
> > > 8250/Kconfig:        bool "NXP LPC18xx/43xx serial port support"
> > >
> > > ...meaning that it currently is not being built as a module by anyone.
> > >
> > > Lets remove the modular code that is essentially orphaned, so that
> > > when reading the driver there is no doubt it is builtin-only.
> > 
> > The bool in KConfig is more or less a copy-paste mistake on my side. I
> > really meant for this driver to be buildable as module and it builds
> > just fine with 'm'.
> > 
> > Want me send a patch changing it to tristate or will you handle it?
> 
> I will do a v2 in the next day or so with collected ACKs and this patch
> replaced, unless Greg jumps in and indicates he'd like something
> different.

Nope, that would be fine with me, thanks.

greg k-h


From mathieu at codeaurora.org  Fri Aug 14 17:46:11 2015
From: mathieu at codeaurora.org (Mathieu Olivari)
Date: Fri, 14 Aug 2015 17:46:11 -0700
Subject: [PATCH 1/3] ARM: qcom: add SFPB nodes to IPQ806x dts
In-Reply-To: <1439599573-3932-1-git-send-email-mathieu@codeaurora.org>
References: <1439599573-3932-1-git-send-email-mathieu@codeaurora.org>
Message-ID: <1439599573-3932-2-git-send-email-mathieu@codeaurora.org>

Add one new node to the ipq806x.dtsi file to declare & register the
hardware spinlock devices. This mechanism is required to be used by
other drivers such as SMEM.

Signed-off-by: Mathieu Olivari <mathieu at codeaurora.org>
---
 arch/arm/boot/dts/qcom-ipq8064.dtsi | 11 +++++++++++
 1 file changed, 11 insertions(+)

diff --git a/arch/arm/boot/dts/qcom-ipq8064.dtsi b/arch/arm/boot/dts/qcom-ipq8064.dtsi
index 9f727d8..8d366ae 100644
--- a/arch/arm/boot/dts/qcom-ipq8064.dtsi
+++ b/arch/arm/boot/dts/qcom-ipq8064.dtsi
@@ -329,5 +329,16 @@
 			#reset-cells = <1>;
 		};
 
+		sfpb_mutex_block: syscon at 1200600 {
+			compatible = "syscon";
+			reg = <0x01200600 0x100>;
+		};
+	};
+
+	sfpb_mutex: sfpb-mutex {
+		compatible = "qcom,sfpb-mutex";
+		syscon = <&sfpb_mutex_block 4 4>;
+
+		#hwlock-cells = <1>;
 	};
 };
-- 
2.1.4



From mathieu at codeaurora.org  Fri Aug 14 17:46:10 2015
From: mathieu at codeaurora.org (Mathieu Olivari)
Date: Fri, 14 Aug 2015 17:46:10 -0700
Subject: [PATCH 0/3] qcom: Add SMEM MTD parser
Message-ID: <1439599573-3932-1-git-send-email-mathieu@codeaurora.org>

QCOM platforms such as IPQ806x are using SMEM to store their flash
layout. This patch set adds the DT nodes required to instanciate SMEM
on IPQ806x and add an MTD parser using it.

This change is based on the SMEM driver posted here:
*https://lkml.org/lkml/2015/7/27/1125

v2:
*Release the SPI device reference after looking it up (put_device())
*Represent SMEM data as __le32 rather than u32
*Move new DT nodes in their proper respective location
*Address readability concerns in MTD parser

Mathieu Olivari (3):
  ARM: qcom: add SFPB nodes to IPQ806x dts
  ARM: qcom: add SMEM device node to IPQ806x dts
  mtd: add SMEM parser for QCOM platforms

 arch/arm/boot/dts/qcom-ipq8064.dtsi |  23 +++-
 drivers/mtd/Kconfig                 |   7 ++
 drivers/mtd/Makefile                |   1 +
 drivers/mtd/qcom_smem_part.c        | 224 ++++++++++++++++++++++++++++++++++++
 4 files changed, 254 insertions(+), 1 deletion(-)
 create mode 100644 drivers/mtd/qcom_smem_part.c

-- 
2.1.4



From mathieu at codeaurora.org  Fri Aug 14 17:46:12 2015
From: mathieu at codeaurora.org (Mathieu Olivari)
Date: Fri, 14 Aug 2015 17:46:12 -0700
Subject: [PATCH 2/3] ARM: qcom: add SMEM device node to IPQ806x dts
In-Reply-To: <1439599573-3932-1-git-send-email-mathieu@codeaurora.org>
References: <1439599573-3932-1-git-send-email-mathieu@codeaurora.org>
Message-ID: <1439599573-3932-3-git-send-email-mathieu@codeaurora.org>

SMEM is used on IPQ806x to store various board related information such
as boot device and flash partition layout. We'll declare it as a device
so we can make use of it thanks to the new SMEM soc driver.

Signed-off-by: Mathieu Olivari <mathieu at codeaurora.org>
---
 arch/arm/boot/dts/qcom-ipq8064.dtsi | 8 +++++++-
 1 file changed, 7 insertions(+), 1 deletion(-)

diff --git a/arch/arm/boot/dts/qcom-ipq8064.dtsi b/arch/arm/boot/dts/qcom-ipq8064.dtsi
index 8d366ae..85dbccf 100644
--- a/arch/arm/boot/dts/qcom-ipq8064.dtsi
+++ b/arch/arm/boot/dts/qcom-ipq8064.dtsi
@@ -55,7 +55,7 @@
 			no-map;
 		};
 
-		smem at 41000000 {
+		smem: smem at 41000000 {
 			reg = <0x41000000 0x200000>;
 			no-map;
 		};
@@ -341,4 +341,10 @@
 
 		#hwlock-cells = <1>;
 	};
+
+	smem {
+		compatible = "qcom,smem";
+		memory-region = <&smem>;
+		hwlocks = <&sfpb_mutex 3>;
+	};
 };
-- 
2.1.4



From mathieu at codeaurora.org  Fri Aug 14 17:46:13 2015
From: mathieu at codeaurora.org (Mathieu Olivari)
Date: Fri, 14 Aug 2015 17:46:13 -0700
Subject: [PATCH 3/3] mtd: add SMEM parser for QCOM platforms
In-Reply-To: <1439599573-3932-1-git-send-email-mathieu@codeaurora.org>
References: <1439599573-3932-1-git-send-email-mathieu@codeaurora.org>
Message-ID: <1439599573-3932-4-git-send-email-mathieu@codeaurora.org>

On QCOM platforms using MTD devices storage (such as IPQ806x), SMEM is
used to store partition layout. This new parser can now be used to read
SMEM and use it to register an MTD layout according to its content.

Signed-off-by: Mathieu Olivari <mathieu at codeaurora.org>
---
 drivers/mtd/Kconfig          |   7 ++
 drivers/mtd/Makefile         |   1 +
 drivers/mtd/qcom_smem_part.c | 231 +++++++++++++++++++++++++++++++++++++++++++
 3 files changed, 239 insertions(+)
 create mode 100644 drivers/mtd/qcom_smem_part.c

diff --git a/drivers/mtd/Kconfig b/drivers/mtd/Kconfig
index a03ad29..debc887 100644
--- a/drivers/mtd/Kconfig
+++ b/drivers/mtd/Kconfig
@@ -155,6 +155,13 @@ config MTD_BCM47XX_PARTS
 	  This provides partitions parser for devices based on BCM47xx
 	  boards.
 
+config MTD_QCOM_SMEM_PARTS
+	tristate "QCOM SMEM partitioning support"
+	depends on QCOM_SMEM
+	help
+	  This provides partitions parser for QCOM devices using SMEM
+	  such as IPQ806x.
+
 comment "User Modules And Translation Layers"
 
 #
diff --git a/drivers/mtd/Makefile b/drivers/mtd/Makefile
index 99bb9a1..b3c7de4 100644
--- a/drivers/mtd/Makefile
+++ b/drivers/mtd/Makefile
@@ -13,6 +13,7 @@ obj-$(CONFIG_MTD_AFS_PARTS)	+= afs.o
 obj-$(CONFIG_MTD_AR7_PARTS)	+= ar7part.o
 obj-$(CONFIG_MTD_BCM63XX_PARTS)	+= bcm63xxpart.o
 obj-$(CONFIG_MTD_BCM47XX_PARTS)	+= bcm47xxpart.o
+obj-$(CONFIG_MTD_QCOM_SMEM_PARTS) += qcom_smem_part.o
 
 # 'Users' - code which presents functionality to userspace.
 obj-$(CONFIG_MTD_BLKDEVS)	+= mtd_blkdevs.o
diff --git a/drivers/mtd/qcom_smem_part.c b/drivers/mtd/qcom_smem_part.c
new file mode 100644
index 0000000..20fef5c
--- /dev/null
+++ b/drivers/mtd/qcom_smem_part.c
@@ -0,0 +1,231 @@
+/*
+ * Copyright (c) 2015, The Linux Foundation. All rights reserved.
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License version 2 and
+ * only 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/kernel.h>
+#include <linux/device.h>
+#include <linux/slab.h>
+
+#include <linux/mtd/mtd.h>
+#include <linux/mtd/partitions.h>
+#include <linux/spi/spi.h>
+#include <linux/module.h>
+
+#include <linux/soc/qcom/smem.h>
+
+/* Processor/host identifier for the application processor */
+#define SMEM_HOST_APPS			0
+
+/* SMEM items index */
+#define SMEM_AARM_PARTITION_TABLE	9
+#define SMEM_BOOT_FLASH_TYPE		421
+#define SMEM_BOOT_FLASH_BLOCK_SIZE	424
+
+/* SMEM Flash types */
+#define SMEM_FLASH_NAND			2
+#define SMEM_FLASH_SPI			6
+
+#define SMEM_PART_NAME_SZ		16
+#define SMEM_PARTS_MAX			32
+
+struct smem_partition {
+	char name[SMEM_PART_NAME_SZ];
+	__le32 start;
+	__le32 size;
+	__le32 attr;
+};
+
+struct smem_partition_table {
+	u8 magic[8];
+	__le32 version;
+	__le32 len;
+	struct smem_partition parts[SMEM_PARTS_MAX];
+};
+
+/* SMEM Magic values in partition table */
+static const u8 SMEM_PTABLE_MAGIC[] = {
+	0xaa, 0x73, 0xee, 0x55,
+	0xdb, 0xbd, 0x5e, 0xe3,
+};
+
+static int qcom_smem_get_flash_blksz(u64 **smem_blksz)
+{
+	int ret;
+	size_t size;
+
+	ret = qcom_smem_get(SMEM_HOST_APPS, SMEM_BOOT_FLASH_BLOCK_SIZE,
+			    (void **) smem_blksz, &size);
+
+	if (ret < 0) {
+		pr_err("Unable to read flash blksz from SMEM\n");
+		return -ENOENT;
+	}
+
+	if (size != sizeof(**smem_blksz)) {
+		pr_err("Invalid flash blksz size in SMEM\n");
+		return -EINVAL;
+	}
+
+	return 0;
+}
+
+static int qcom_smem_get_flash_type(u64 **smem_flash_type)
+{
+	int ret;
+	size_t size;
+
+	ret = qcom_smem_get(SMEM_HOST_APPS, SMEM_BOOT_FLASH_TYPE,
+			    (void **) smem_flash_type, &size);
+
+	if (ret < 0) {
+		pr_err("Unable to read flash type from SMEM\n");
+		return -ENOENT;
+	}
+
+	if (size != sizeof(**smem_flash_type)) {
+		pr_err("Invalid flash type size in SMEM\n");
+		return -EINVAL;
+	}
+
+	return 0;
+}
+
+static int qcom_smem_get_flash_partitions(struct smem_partition_table **pparts)
+{
+	int ret;
+	size_t size;
+
+	ret = qcom_smem_get(SMEM_HOST_APPS, SMEM_AARM_PARTITION_TABLE,
+			    (void **) pparts, &size);
+
+	if (ret < 0) {
+		pr_err("Unable to read partition table from SMEM\n");
+		return -ENOENT;
+	}
+
+	return 0;
+}
+
+static int of_dev_node_match(struct device *dev, void *data)
+{
+	return dev->of_node == data;
+}
+
+static bool is_spi_device(struct device_node *np)
+{
+	struct device *dev;
+
+	dev = bus_find_device(&spi_bus_type, NULL, np, of_dev_node_match);
+	if (!dev)
+		return false;
+
+	put_device(dev);
+	return true;
+}
+
+static int parse_qcom_smem_partitions(struct mtd_info *master,
+				      struct mtd_partition **pparts,
+				      struct mtd_part_parser_data *data)
+{
+	struct smem_partition_table *smem_parts;
+	u64 *smem_flash_type, *smem_blksz;
+	struct mtd_partition *mtd_parts;
+	struct device_node *of_node = data->of_node;
+	int i, ret;
+
+	/*
+	 * SMEM will only store the partition table of the boot device.
+	 * If this is not the boot device, do not return any partition.
+	 */
+	ret = qcom_smem_get_flash_type(&smem_flash_type);
+	if (ret < 0)
+		return ret;
+
+	if ((*smem_flash_type == SMEM_FLASH_NAND && !mtd_type_is_nand(master))
+	    || (*smem_flash_type == SMEM_FLASH_SPI && !is_spi_device(of_node)))
+		return 0;
+
+	/*
+	 * Just for sanity purpose, make sure the block size in SMEM matches the
+	 * block size of the MTD device
+	 */
+	ret = qcom_smem_get_flash_blksz(&smem_blksz);
+	if (ret < 0)
+		return ret;
+
+	if (*smem_blksz != master->erasesize) {
+		pr_err("SMEM block size differs from MTD block size\n");
+		return -EINVAL;
+	}
+
+	/* Get partition pointer from SMEM */
+	ret = qcom_smem_get_flash_partitions(&smem_parts);
+	if (ret < 0)
+		return ret;
+
+	if (memcmp(SMEM_PTABLE_MAGIC, smem_parts->magic,
+		   sizeof(SMEM_PTABLE_MAGIC))) {
+		pr_err("SMEM partition magic invalid\n");
+		return -EINVAL;
+	}
+
+	/* Allocate and populate the mtd structures */
+	mtd_parts = kcalloc(le32_to_cpu(smem_parts->len), sizeof(*mtd_parts),
+			    GFP_KERNEL);
+	if (!mtd_parts)
+		return -ENOMEM;
+
+	for (i = 0; i < smem_parts->len; i++) {
+		struct smem_partition *s_part = &smem_parts->parts[i];
+		struct mtd_partition *m_part = &mtd_parts[i];
+
+		m_part->name = s_part->name;
+		m_part->size = le32_to_cpu(s_part->size) * (*smem_blksz);
+		m_part->offset = le32_to_cpu(s_part->start) * (*smem_blksz);
+
+		/*
+		 * The last SMEM partition may have its size marked as
+		 * something like 0xffffffff, which means "until the end of the
+		 * flash device". In this case, truncate it.
+		 */
+		if (m_part->offset + m_part->size > master->size)
+			m_part->size = master->size - m_part->offset;
+	}
+
+	*pparts = mtd_parts;
+
+	return smem_parts->len;
+}
+
+static struct mtd_part_parser qcom_smem_parser = {
+	.owner = THIS_MODULE,
+	.parse_fn = parse_qcom_smem_partitions,
+	.name = "qcom-smem",
+};
+
+static int __init qcom_smem_parser_init(void)
+{
+	register_mtd_parser(&qcom_smem_parser);
+	return 0;
+}
+
+static void __exit qcom_smem_parser_exit(void)
+{
+	deregister_mtd_parser(&qcom_smem_parser);
+}
+
+module_init(qcom_smem_parser_init);
+module_exit(qcom_smem_parser_exit);
+
+MODULE_LICENSE("GPL");
+MODULE_AUTHOR("Mathieu Olivari <mathieu at codeaurora.org>");
+MODULE_DESCRIPTION("Parsing code for SMEM based partition tables");
-- 
2.1.4



From edubezval at gmail.com  Fri Aug 14 18:10:16 2015
From: edubezval at gmail.com (Eduardo Valentin)
Date: Fri, 14 Aug 2015 18:10:16 -0700
Subject: [PATCH V2] thermal: cpu_cooling: fix lockdep problems in
 cpu_cooling
In-Reply-To: <20150814055556.GZ20238@linux>
References: <16e7d7d811fa2b0f8dcf6cade345a5f2f3e3c36a.1439372926.git.viresh.kumar@linaro.org>
 <20150814055556.GZ20238@linux>
Message-ID: <20150815011015.GA4125@localhost.localdomain>

On Fri, Aug 14, 2015 at 11:25:56AM +0530, Viresh Kumar wrote:
> On 12-08-15, 15:22, Viresh Kumar wrote:
> > From: Russell King <rmk+kernel at arm.linux.org.uk>
> > Fixes: 2dcd851fe4b4 ("thermal: cpu_cooling: Update always cpufreq policy with
> > Reviewed-by: Viresh Kumar <viresh.kumar at linaro.org>
> > Signed-off-by: Russell King <rmk+kernel at arm.linux.org.uk>
> > Signed-off-by: Viresh Kumar <viresh.kumar at linaro.org>
> > ---
> > 
> > Hi Eduardo/Zhang,
> > 
> > This is 4.2-rc material, please apply soon.
> 
> Hey,
> 
> Please apply this one and drop
> 
> 8ad61f934e9e ("thermal: cpu_cooling: fix lockdep problems in
> cpu_cooling")

OK, I am having a looking at this.

> 
> -- 
> viresh
-------------- next part --------------
A non-text attachment was scrubbed...
Name: signature.asc
Type: application/pgp-signature
Size: 490 bytes
Desc: Digital signature
URL: <http://lists.infradead.org/pipermail/linux-arm-kernel/attachments/20150814/7b2c8ec3/attachment.sig>

From edubezval at gmail.com  Fri Aug 14 18:19:19 2015
From: edubezval at gmail.com (Eduardo Valentin)
Date: Fri, 14 Aug 2015 18:19:19 -0700
Subject: [PATCH] thermal: cpu_cooling: fix lockdep problems in cpu_cooling
In-Reply-To: <20150814055359.GY20238@linux>
References: <20150812073530.GA16445@linux>
 <E1ZPQfV-0005nb-DN@rmk-PC.arm.linux.org.uk>
 <20150814045009.GB10354@localhost.localdomain>
 <20150814055359.GY20238@linux>
Message-ID: <20150815011918.GB4125@localhost.localdomain>

On Fri, Aug 14, 2015 at 11:23:59AM +0530, Viresh Kumar wrote:
> On 13-08-15, 21:50, Eduardo Valentin wrote:
> > Sorry if I let this one to fall into the cracks for this long.
> > 
> > I am looking at this now and queuing as soon as possible.
> 
> You applied the wrong one, please drop it. And apply the one I have
> sent as a separate thread, with my sob on it.

OK. I am updating it to your V2.


> 
> -- 
> viresh
-------------- next part --------------
A non-text attachment was scrubbed...
Name: signature.asc
Type: application/pgp-signature
Size: 490 bytes
Desc: Digital signature
URL: <http://lists.infradead.org/pipermail/linux-arm-kernel/attachments/20150814/825916ac/attachment.sig>

From vthakkar1994 at gmail.com  Fri Aug 14 18:51:00 2015
From: vthakkar1994 at gmail.com (Vaishali Thakkar)
Date: Sat, 15 Aug 2015 07:21:00 +0530
Subject: [PATCH] ASoC: rockchip: i2s: Adjust devm usage
Message-ID: <20150815015059.GA31009@localhost>

Remove use of snd_soc_unregister_component in remove function
as devm_snd_soc_register_component in probe function automatically
handles it.

Also, convert call of snd_dmaengine_pcm_register to managed resource
function devm_snd_dmaengine_pcm_register and remove usage of
snd_dmaengine_pcm_unregister in probe and remove functions.

Signed-off-by: Vaishali Thakkar <vthakkar1994 at gmail.com>
---
 sound/soc/rockchip/rockchip_i2s.c | 8 ++------
 1 file changed, 2 insertions(+), 6 deletions(-)

diff --git a/sound/soc/rockchip/rockchip_i2s.c b/sound/soc/rockchip/rockchip_i2s.c
index acb5be5..b936102 100644
--- a/sound/soc/rockchip/rockchip_i2s.c
+++ b/sound/soc/rockchip/rockchip_i2s.c
@@ -483,16 +483,14 @@ static int rockchip_i2s_probe(struct platform_device *pdev)
 		goto err_suspend;
 	}
 
-	ret = snd_dmaengine_pcm_register(&pdev->dev, NULL, 0);
+	ret = devm_snd_dmaengine_pcm_register(&pdev->dev, NULL, 0);
 	if (ret) {
 		dev_err(&pdev->dev, "Could not register PCM\n");
-		goto err_pcm_register;
+		return ret;
 	}
 
 	return 0;
 
-err_pcm_register:
-	snd_dmaengine_pcm_unregister(&pdev->dev);
 err_suspend:
 	if (!pm_runtime_status_suspended(&pdev->dev))
 		i2s_runtime_suspend(&pdev->dev);
@@ -512,8 +510,6 @@ static int rockchip_i2s_remove(struct platform_device *pdev)
 
 	clk_disable_unprepare(i2s->mclk);
 	clk_disable_unprepare(i2s->hclk);
-	snd_dmaengine_pcm_unregister(&pdev->dev);
-	snd_soc_unregister_component(&pdev->dev);
 
 	return 0;
 }
-- 
1.9.1



From broonie at kernel.org  Fri Aug 14 10:56:16 2015
From: broonie at kernel.org (Mark Brown)
Date: Fri, 14 Aug 2015 18:56:16 +0100
Subject: [PATCH] regmap: Add function check before called format_val
In-Reply-To: <1439479505.32674.43.camel@mtksdaap41>
References: <1437396110-5192-1-git-send-email-henryc.chen@mediatek.com>
 <20150720150254.GC11162@sirena.org.uk>
 <1437458845.30329.51.camel@mtksdaap41>
 <CAGS+omDa+FhKD2u_VwBG3cWvN+ZiHneqFVz=mtdYuPsiQu4JEQ@mail.gmail.com>
 <1439479505.32674.43.camel@mtksdaap41>
Message-ID: <20150814175616.GA10748@sirena.org.uk>

On Thu, Aug 13, 2015 at 11:25:05PM +0800, Henry Chen wrote:
> On Wed, 2015-08-12 at 22:20 +0800, Daniel Kurtz wrote:

> > Making mtk_pmic-wrap into a regmap_bus makes a bit of sense
> > architecturally, too, since it is essentially just a bus for accessing
> > the registers of an off-chip PMIC.  The CPU sees a platform bus, but
> > the registers of the remote PMIC are accessed over a dedicated SPI
> > bus.

> Sorry, I'm afraid that I cannot do this right on init as you said last
> time. What do you think about regmap_bus, can you accept that way?

I don't have enough context from the above to understand what's going
on, sorry.  Implementing a bus for something that isn't actually a Linux
bus doesn't seem like the best idea though and in general what I'm
seeing of the discussion sounds like you're hacking around in driver
code to bodge around problems that are being seen rather than really
addressing things, the code I can see certainly looks like it just wants
to be implementing read and write operations for a single MFD.
-------------- next part --------------
A non-text attachment was scrubbed...
Name: signature.asc
Type: application/pgp-signature
Size: 473 bytes
Desc: Digital signature
URL: <http://lists.infradead.org/pipermail/linux-arm-kernel/attachments/20150814/b7f823b8/attachment-0001.sig>

From broonie at kernel.org  Fri Aug 14 09:36:25 2015
From: broonie at kernel.org (Mark Brown)
Date: Fri, 14 Aug 2015 17:36:25 +0100
Subject: [PATCH 14/20] regmap: Add raw_write/read checks for
 max_raw_write/read sizes
In-Reply-To: <20150812124706.GI19600@pengutronix.de>
References: <1439374365-20623-1-git-send-email-mpa@pengutronix.de>
 <1439374365-20623-15-git-send-email-mpa@pengutronix.de>
 <20150812115759.GB10748@sirena.org.uk>
 <20150812124706.GI19600@pengutronix.de>
Message-ID: <20150814163625.GY10748@sirena.org.uk>

On Wed, Aug 12, 2015 at 02:47:06PM +0200, Markus Pargmann wrote:
> On Wed, Aug 12, 2015 at 12:57:59PM +0100, Mark Brown wrote:
> > On Wed, Aug 12, 2015 at 12:12:39PM +0200, Markus Pargmann wrote:

> > > Check in regmap_raw_read() and regmap_raw_write() for correct maximum
> > > sizes of the operations. Return -E2BIG if this size is not supported
> > > because it is too big.

> > Why not just split the transaction up like your other changes did?

> My intention was to keep these raw functions as close to the actual
> hardware as possible also reporting proper error values. For
> transactions that are split up you could still use the bulk functions.

That's not what we do otherwise, and not what you yourself have done for
some of the other changes in the series like those around multi write.
-------------- next part --------------
A non-text attachment was scrubbed...
Name: signature.asc
Type: application/pgp-signature
Size: 473 bytes
Desc: Digital signature
URL: <http://lists.infradead.org/pipermail/linux-arm-kernel/attachments/20150814/d9f822a2/attachment.sig>

From broonie at kernel.org  Fri Aug 14 09:34:19 2015
From: broonie at kernel.org (Mark Brown)
Date: Fri, 14 Aug 2015 17:34:19 +0100
Subject: [PATCH 00/20] Regmap max_raw_io and bmc150 SPI support
In-Reply-To: <20150812104739.GC19600@pengutronix.de>
References: <1439374365-20623-1-git-send-email-mpa@pengutronix.de>
 <20150812103736.GR10748@sirena.org.uk>
 <20150812104739.GC19600@pengutronix.de>
Message-ID: <20150814163419.GW10748@sirena.org.uk>

On Wed, Aug 12, 2015 at 12:47:39PM +0200, Markus Pargmann wrote:

> Ok. I can try to separate them but there are lots of dependencies
> between the patches and most of them touch regmap.c so I thought it may
> be better to put it in one series.

No, just the opposite - it means there's much less structure to the
series as it just becomes a sequence of unrelated changes without
overall aim or common theme.
-------------- next part --------------
A non-text attachment was scrubbed...
Name: signature.asc
Type: application/pgp-signature
Size: 473 bytes
Desc: Digital signature
URL: <http://lists.infradead.org/pipermail/linux-arm-kernel/attachments/20150814/b7edce91/attachment.sig>

From broonie at kernel.org  Fri Aug 14 09:34:51 2015
From: broonie at kernel.org (Mark Brown)
Date: Fri, 14 Aug 2015 17:34:51 +0100
Subject: [PATCH 11/20] regmap: _regmap_raw_read: Add handling of busses
 without bus->read()
In-Reply-To: <20150812123412.GG19600@pengutronix.de>
References: <1439374365-20623-1-git-send-email-mpa@pengutronix.de>
 <1439374365-20623-12-git-send-email-mpa@pengutronix.de>
 <20150812112707.GY10748@sirena.org.uk>
 <20150812123412.GG19600@pengutronix.de>
Message-ID: <20150814163451.GX10748@sirena.org.uk>

On Wed, Aug 12, 2015 at 02:34:12PM +0200, Markus Pargmann wrote:

> Is -EINVAL the right thing to return or would you prefer -ENOTSUPP?

-ENOTSUPP is going to be better.
-------------- next part --------------
A non-text attachment was scrubbed...
Name: signature.asc
Type: application/pgp-signature
Size: 473 bytes
Desc: Digital signature
URL: <http://lists.infradead.org/pipermail/linux-arm-kernel/attachments/20150814/4556f380/attachment.sig>

From broonie at kernel.org  Fri Aug 14 12:19:20 2015
From: broonie at kernel.org (Mark Brown)
Date: Fri, 14 Aug 2015 20:19:20 +0100
Subject: [PATCH 1/3] spi: bitbang: Replace spinlock by mutex when calling
 chipselect
In-Reply-To: <CANMq1KB2zxPPCbxh4K-REUgp-83s=MPcGRjz-p1fK1PQMzyLdw@mail.gmail.com>
References: <CANMq1KB2zxPPCbxh4K-REUgp-83s=MPcGRjz-p1fK1PQMzyLdw@mail.gmail.com>
Message-ID: <20150814191920.GK10748@sirena.org.uk>

On Wed, Aug 05, 2015 at 06:24:05PM +0800, Nicolas Boichat wrote:

> Anyway, the "safer" way to fix this would be to keep the
> prepare/unprepare functions, busy variable, and just protect it with a
> mutex instead of a spinlock...

OK, that seems reasonable.
-------------- next part --------------
A non-text attachment was scrubbed...
Name: signature.asc
Type: application/pgp-signature
Size: 473 bytes
Desc: Digital signature
URL: <http://lists.infradead.org/pipermail/linux-arm-kernel/attachments/20150814/a3aba122/attachment.sig>

From broonie at kernel.org  Fri Aug 14 12:30:15 2015
From: broonie at kernel.org (Mark Brown)
Date: Fri, 14 Aug 2015 20:30:15 +0100
Subject: [PATCH] spi: imx: fix ecspi mode setup
In-Reply-To: <CAN8RqkDrc9sqsbv360yuu7cN3dg527vEomu+FakqnkbTgGZtzQ@mail.gmail.com>
References: <1436880205-25023-1-git-send-email-qxovxp@gmail.com>
 <20150714134934.GV11162@sirena.org.uk>
 <CAN8RqkDrc9sqsbv360yuu7cN3dg527vEomu+FakqnkbTgGZtzQ@mail.gmail.com>
Message-ID: <20150814193015.GN10748@sirena.org.uk>

On Tue, Jul 14, 2015 at 07:06:36PM +0300, Andrew Kuksov wrote:
> >> Fixed problem with setting spi mode 0 or 1 after setting mode 2 or 3

> > What is the problem and how does this change fix it (this information
> > should be in the changelog)?

> SPI_MODE_0 and SPI_MODE_1 requires clock low when inactive. SPI_MODE_2
> and SPI_MODE_3 requires clk high when inactive.
> Currently driver can just set bits in fields SCLK_PHA (SPI Clock/Data
> Phase Control), SCLK_POL (SPI Clock Polarity Control),
> SCLK_CTL (controls the inactive state of SCLK) ans SS_POL (SPI SS
> Polarity Select) of ECSPIx_CONFIGREG register.
> This patch allows driver to clear corresponding bits in these fields.

Please provide a patch with a changelog more like this...
-------------- next part --------------
A non-text attachment was scrubbed...
Name: signature.asc
Type: application/pgp-signature
Size: 473 bytes
Desc: Digital signature
URL: <http://lists.infradead.org/pipermail/linux-arm-kernel/attachments/20150814/950f0023/attachment.sig>

From broonie at kernel.org  Fri Aug 14 09:40:00 2015
From: broonie at kernel.org (Mark Brown)
Date: Fri, 14 Aug 2015 17:40:00 +0100
Subject: [PATCH 09/20] regmap: _regmap_raw_write fix for busses without
 write()
In-Reply-To: <20150812130518.GM19600@pengutronix.de>
References: <1439374365-20623-1-git-send-email-mpa@pengutronix.de>
 <1439374365-20623-10-git-send-email-mpa@pengutronix.de>
 <20150812112035.GX10748@sirena.org.uk>
 <20150812122011.GE19600@pengutronix.de>
 <20150812123406.GG10748@sirena.org.uk>
 <20150812130518.GM19600@pengutronix.de>
Message-ID: <20150814164000.GZ10748@sirena.org.uk>

On Wed, Aug 12, 2015 at 03:05:18PM +0200, Markus Pargmann wrote:
> On Wed, Aug 12, 2015 at 01:34:06PM +0100, Mark Brown wrote:

> > > Yes right. On the other hand if bus->read() and bus->write() was not set
> > > in the init method (before this patch series) no formatting functions at
> > > all were assigned. So it was always ignored for bus->reg_read() and
> > > bus->reg_write()?!

> > I'm not sure what the "it" you're talking about here is, sorry.  There
> > are unsupported features in the API especially for cases that don't make
> > a huge amount of sense, the error handling isn't always complete.  It
> > sounds like you might be trying to support one of these nonsensical
> > cases - it's not obvious what raw I/O on a device where we don't know
> > the raw format of the device should mean or how anything could sensibly
> > use that.

> The bus and the regmap user are separate. So as a regmap user, I am not
> able to know if the bus the device is connected to actually supports raw
> reads/writes. At least it should not fail with a null pointer when using

You should generally have a pretty good idea simply by knowing which
device you're working with - unless you're writing generic code you know
which device you're working with and what it's capabilities are.  A
driver that doesn't know these things should never be trying to do raw
I/O, and a driver that is doing raw I/O clearly depends on having the
ability to get a bytestream to and from the device since that's what raw
I/O does.
-------------- next part --------------
A non-text attachment was scrubbed...
Name: signature.asc
Type: application/pgp-signature
Size: 473 bytes
Desc: Digital signature
URL: <http://lists.infradead.org/pipermail/linux-arm-kernel/attachments/20150814/deb79824/attachment.sig>

From nicolas.pitre at linaro.org  Fri Aug 14 19:46:25 2015
From: nicolas.pitre at linaro.org (Nicolas Pitre)
Date: Fri, 14 Aug 2015 22:46:25 -0400 (EDT)
Subject: [PATCH] ARM: add TC2 PM support to multi_v7_defconfig
Message-ID: <alpine.LFD.2.20.1508142239070.1515@knanqh.ubzr>

Without this, the multi_v7_defconfig kernel cannot boot all CPUs
nor do deep cpuidle power saving on a TC2 board.

Signed-off-by: Nicolas Pitre <nico at linaro.org>

diff --git a/arch/arm/configs/multi_v7_defconfig b/arch/arm/configs/multi_v7_defconfig
index 5fd8df6f50..d91b8783f2 100644
--- a/arch/arm/configs/multi_v7_defconfig
+++ b/arch/arm/configs/multi_v7_defconfig
@@ -98,6 +98,7 @@ CONFIG_MACH_SNOWBALL=y
 CONFIG_MACH_UX500_DT=y
 CONFIG_ARCH_VEXPRESS=y
 CONFIG_ARCH_VEXPRESS_CA9X4=y
+CONFIG_ARCH_VEXPRESS_TC2_PM=y
 CONFIG_ARCH_WM8850=y
 CONFIG_ARCH_ZYNQ=y
 CONFIG_TRUSTED_FOUNDATIONS=y


From viresh.kumar at linaro.org  Fri Aug 14 20:06:59 2015
From: viresh.kumar at linaro.org (Viresh Kumar)
Date: Sat, 15 Aug 2015 08:36:59 +0530
Subject: [PATCH] thermal: cpu_cooling: fix lockdep problems in cpu_cooling
In-Reply-To: <20150815011918.GB4125@localhost.localdomain>
References: <20150812073530.GA16445@linux>
 <E1ZPQfV-0005nb-DN@rmk-PC.arm.linux.org.uk>
 <20150814045009.GB10354@localhost.localdomain>
 <20150814055359.GY20238@linux>
 <20150815011918.GB4125@localhost.localdomain>
Message-ID: <20150815030659.GC1162@linux>

On 14-08-15, 18:19, Eduardo Valentin wrote:
> On Fri, Aug 14, 2015 at 11:23:59AM +0530, Viresh Kumar wrote:
> > On 13-08-15, 21:50, Eduardo Valentin wrote:
> > > Sorry if I let this one to fall into the cracks for this long.
> > > 
> > > I am looking at this now and queuing as soon as possible.
> > 
> > You applied the wrong one, please drop it. And apply the one I have
> > sent as a separate thread, with my sob on it.
> 
> OK. I am updating it to your V2.

Looks fine now.

-- 
viresh


From swarren at wwwdotorg.org  Fri Aug 14 20:46:15 2015
From: swarren at wwwdotorg.org (Stephen Warren)
Date: Fri, 14 Aug 2015 21:46:15 -0600
Subject: [PATCH] arm: rpi: Device tree modifications for U-Boot
In-Reply-To: <CAPnjgZ3ztXnkxZJvitiXiKMzq5+x46hbv0PW4HcF7yGgsXUV+Q@mail.gmail.com>
References: <1439303153-12171-1-git-send-email-sjg@chromium.org>
 <1439312701.2451.3.camel@lynxeye.de>
 <CAPnjgZ3ztXnkxZJvitiXiKMzq5+x46hbv0PW4HcF7yGgsXUV+Q@mail.gmail.com>
Message-ID: <55CEB607.7060908@wwwdotorg.org>

On 08/12/2015 07:21 AM, Simon Glass wrote:
> Hi Lucas,
> 
> On 11 August 2015 at 11:05, Lucas Stach <dev at lynxeye.de> wrote:
>> Hi Simon,
>>
>> why did you send this to the Tegra ML?
>>
>> Am Dienstag, den 11.08.2015, 08:25 -0600 schrieb Simon Glass:
>>> This updates the device tree from the kernel version to something suitable
>>> for U-Boot:
>>>
>>> - Add stdout-path alias for console
>>> - Mark the /soc node to be available pre-relocation so that the early
>>> serial console works (we need the 'ranges' property to be available)
>>>
>>> Signed-off-by: Simon Glass <sjg at chromium.org>
>>> ---
>>>
>>>  arch/arm/boot/dts/bcm2835.dtsi | 4 +++-
>>>  1 file changed, 3 insertions(+), 1 deletion(-)
>>>
>>> diff --git a/arch/arm/boot/dts/bcm2835.dtsi b/arch/arm/boot/dts/bcm2835.dtsi
>>> index 301c73f..bd6bff6 100644
>>> --- a/arch/arm/boot/dts/bcm2835.dtsi
>>> +++ b/arch/arm/boot/dts/bcm2835.dtsi
>>> @@ -8,6 +8,7 @@
>>>
>>>       chosen {
>>>               bootargs = "earlyprintk console=ttyAMA0";
>>> +             stdout-path = &uart;
>>>       };
>>>
>>>       soc {
>>> @@ -16,6 +17,7 @@
>>>               #size-cells = <1>;
>>>               ranges = <0x7e000000 0x20000000 0x02000000>;
>>>               dma-ranges = <0x40000000 0x00000000 0x20000000>;
>>> +             u-boot,dm-pre-reloc;
>>
>> Why do you need this and why should upstream carry your favourite
>> bootloaders configuration? This is in no way hardware description.
> 
> I'm not sure how much you know about U-Boot, so let me know if you
> need more info.
> 
> U-Boot normally starts up by setting up its serial UART and displaying
> a banner message. At this stage typically only a few devices are
> initialised (e.g. maybe just the UART). It then relocates itself to
> the top of memory and starts up all the devices. It throws away any
> previous devices that it set up before relocation and starts again.
> 
> U-Boot uses a thing called driver model (dm) which handles driver
> binding and probing. Driver model has the device tree and would
> normally scan through it and create devices for everything it finds.
> 
> Before relocation we don't need every device. Also the CPU is often
> running slowly, perhaps without the cache enabled. SDRAM may not be
> available yet so space is short. We want to avoid starting up things
> that will not be used.
> 
> So this property indicates that the device is needed before relocation
> and should be set up by driver model. We need it to avoid a very slow
> and memory-hungry startup.
> 
> As to why upstream should accept it, my understanding of upstream is
> that people can send patches to it and in fact are encouraged to do
> so, to avoid misunderstandings and duplication. The device tree files
> are stored in Linux so any binding or source file changes should end
> up there. Otherwise the files tend to diverge and we end up with
> multiple bindings and multiple versions of the same source file.

On many platforms, we have U-Boot SPL running first, then the main
U-Boot. The main U-Boot binary contains both the code to do the
relocation and the binary that runs after relocation. It seems like it'd
be simpler to split these up into 3 binaries that each do a single job:

1) SPL, roughly as-is today (varying jobs depending on platform)

2) Relocator, which does nothing but work out where to copy U-Boot,
memcpy()s it there, relocates the image (if not PIE), and jumps to it.

3) The main U-Boot.

Item (2) above should be simple enough that it can use a very simple
debug mechanism rather like DEBUG_LL in the Linux kernel. Similar to
what Rob mentioned in his email.

Item (3) could use DM and DT/ACPI/... to get device information in a
complete non-hard-coded manner.


From agross at codeaurora.org  Fri Aug 14 20:56:30 2015
From: agross at codeaurora.org (Andy Gross)
Date: Fri, 14 Aug 2015 22:56:30 -0500
Subject: [PATCH] soc: qcom: smem: Fix errant private access
Message-ID: <1439610990-8427-1-git-send-email-agross@codeaurora.org>

This patch corrects private partition item access.  Instead of falling back to
global for instances where we have an actual host and remote partition existing,
return the results of the private lookup.

Signed-off-by: Andy Gross <agross at codeaurora.org>
---
 drivers/soc/qcom/smem.c |    5 +++--
 1 file changed, 3 insertions(+), 2 deletions(-)

diff --git a/drivers/soc/qcom/smem.c b/drivers/soc/qcom/smem.c
index 7c2c324c..6603201d 100644
--- a/drivers/soc/qcom/smem.c
+++ b/drivers/soc/qcom/smem.c
@@ -484,8 +484,9 @@ int qcom_smem_get(unsigned host, unsigned item, void **ptr, size_t *size)
 	if (ret)
 		return ret;
 
-	ret = qcom_smem_get_private(__smem, host, item, ptr, size);
-	if (ret == -ENOENT)
+	if (host < SMEM_HOST_COUNT && __smem->partitions[host])
+		ret = qcom_smem_get_private(__smem, host, item, ptr, size);
+	else
 		ret = qcom_smem_get_global(__smem, item, ptr, size);
 
 	hwspin_unlock_irqrestore(__smem->hwlock, &flags);
-- 
The Qualcomm Innovation Center, Inc. is a member of the Code Aurora Forum,
hosted by The Linux Foundation



From swarren at wwwdotorg.org  Fri Aug 14 21:13:31 2015
From: swarren at wwwdotorg.org (Stephen Warren)
Date: Fri, 14 Aug 2015 22:13:31 -0600
Subject: [PATCH v5 3/3] ARM: bcm2835: Add DT for the firmware clocks
 driver.
In-Reply-To: <1439507142-2965-4-git-send-email-eric@anholt.net>
References: <1439507142-2965-1-git-send-email-eric@anholt.net>
 <1439507142-2965-4-git-send-email-eric@anholt.net>
Message-ID: <55CEBC6B.9070001@wwwdotorg.org>

On 08/13/2015 05:05 PM, Eric Anholt wrote:
> Signed-off-by: Eric Anholt <eric at anholt.net>
> Acked-by: Lee Jones <lee at kernel.org>

A patch description might be nice, although admittedly the subject seems
clear enough.

> diff --git a/arch/arm/boot/dts/bcm2835-rpi.dtsi b/arch/arm/boot/dts/bcm2835-rpi.dtsi

> +		firmware_clocks: firmware-clocks {
> +			compatible = "raspberrypi,bcm2835-firmware-clocks";
> +			#clock-cells = <1>;
> +			raspberrypi,firmware = <&firmware>;
> +		};

No need to resend for this, but just a background note: DT node names
usually contain a device type not a device identity, so "clocks" not
"firmware-clocks" would be typical.

This patch,
Acked-by: Stephen Warren <swarren at wwwdotorg.org>


From swarren at wwwdotorg.org  Fri Aug 14 21:28:26 2015
From: swarren at wwwdotorg.org (Stephen Warren)
Date: Fri, 14 Aug 2015 22:28:26 -0600
Subject: [PATCH v5 2/3] clk: Add a Raspberry Pi-specific clock driver.
In-Reply-To: <1439507142-2965-3-git-send-email-eric@anholt.net>
References: <1439507142-2965-1-git-send-email-eric@anholt.net>
 <1439507142-2965-3-git-send-email-eric@anholt.net>
Message-ID: <55CEBFEA.7080505@wwwdotorg.org>

On 08/13/2015 05:05 PM, Eric Anholt wrote:
> Unfortunately, the clock manager's registers are not accessible by the
> ARM, so we have to request that the firmware modify our clocks for us.
> 
> This driver only registers the clocks at the point they are requested
> by a client driver.  This is partially to support returning
> -EPROBE_DEFER when the firmware driver isn't supported yet, but it
> also avoids issues with disabling "unused" clocks due to them not yet
> being connected to their consumers in the DT.

> diff --git a/drivers/clk/clk-raspberrypi.c b/drivers/clk/clk-raspberrypi.c

> +static const struct {
> +	const char *name;
> +	int flags;
> +} rpi_clocks[] = {
> +	[RPI_CLOCK_EMMC] = { "emmc", CLK_IS_ROOT },
> +	[RPI_CLOCK_UART0] = { "uart0", CLK_IS_ROOT },
> +	[RPI_CLOCK_ARM] = { "arm", CLK_IS_ROOT | CLK_IGNORE_UNUSED },
> +	[RPI_CLOCK_CORE] = { "core", CLK_IS_ROOT | CLK_IGNORE_UNUSED },
> +	[RPI_CLOCK_V3D] = { "v3d", CLK_IS_ROOT },
> +	[RPI_CLOCK_H264] = { "h264", CLK_IS_ROOT },
> +	[RPI_CLOCK_ISP] = { "isp", CLK_IS_ROOT },
> +	[RPI_CLOCK_SDRAM] = { "sdram", CLK_IS_ROOT | CLK_IGNORE_UNUSED },
> +	[RPI_CLOCK_PIXEL] = { "pixel", CLK_IS_ROOT | CLK_IGNORE_UNUSED },
> +	[RPI_CLOCK_PWM] = { "pwm", CLK_IS_ROOT },
> +};
> +
> +struct rpi_firmware_clock {
> +	/* Clock definitions in our static struct. */
> +	const char *name;
> +	int flags;

Are these duplicates of the values in rpi_clocks[]? Why not just store a
pointer to or index of the entry in that array?

> +static int rpi_clk_set_state(struct clk_hw *hw, bool on)
> +{
> +	struct rpi_firmware_clock *rpi_clk =
> +		container_of(hw, struct rpi_firmware_clock, hw);
> +	u32 packet[2];
> +	int ret;
> +
> +	if (on == (rpi_clk->last_rate != 0))
> +		return 0;

The overloading of last_rate to represent both rate information and
on/off status is slightly confusing. I would have expected this function
to clear last_rate to 0 when switching the clock off, and some specific
rate when turning a clock on. Is there some guarantee that the clock
core will always call recalc_rate() at certain times, thus ensuring that
last_rate is always accurate?

Wouldn't it be simpler to let last_rate always represent that actual
rate, and have a separate last_on or is_on field to represent the
enable/disable state?

> +static unsigned long rpi_clk_get_rate(struct clk_hw *hw,
> +				      unsigned long parent_rate)
...
> +	rpi_clk->last_rate = packet[1];

Since this is a query API, I wouldn't have expected it to have
side-effects like this. Don't we know what rate the clock runs at based
on the firmware's response in set_rate()?

> +static int rpi_clk_probe(struct platform_device *pdev)

> +	onecell = devm_kmalloc(dev, sizeof(*onecell), GFP_KERNEL);
> +	if (!onecell)
> +		return -ENOMEM;
> +	onecell->clk_num = ARRAY_SIZE(rpi_clocks);
> +	onecell->clks = devm_kzalloc(dev, sizeof(*onecell->clks), GFP_KERNEL);

Don't you need to multiply the size by ARRAY_SIZE(rpi_clocks)? I assume
onecell->clks is an array with one entry per each of onecell->clk_num?
Yes, the for loop right after that allocation confirms this.


From swarren at wwwdotorg.org  Fri Aug 14 21:38:54 2015
From: swarren at wwwdotorg.org (Stephen Warren)
Date: Fri, 14 Aug 2015 22:38:54 -0600
Subject: [PATCH 1/7] drm/vc4: Add devicetree bindings for VC4.
In-Reply-To: <1439427380-2436-2-git-send-email-eric@anholt.net>
References: <1439427380-2436-1-git-send-email-eric@anholt.net>
 <1439427380-2436-2-git-send-email-eric@anholt.net>
Message-ID: <55CEC25E.7070303@wwwdotorg.org>

On 08/12/2015 06:56 PM, Eric Anholt wrote:
> Signed-off-by: Eric Anholt <eric at anholt.net>

This one definitely needs a patch description, since someone might not
know what a VC4 is, and "git log" won't show the text from the binding
doc itself. I'd suggest adding the initial paragraph of the binding doc
as the patch description, or more.

> diff --git a/Documentation/devicetree/bindings/gpu/brcm,bcm-vc4.txt b/Documentation/devicetree/bindings/gpu/brcm,bcm-vc4.txt

> +Required properties for VC4:
> +- compatible:	Should be "brcm,vc4"
> +- crtcs:	List of references to pixelvalve scanout engines

s/references to/phandles of/ would be more typical DT language.

> +- hvss:		List of references to HVS video scalers
> +- encoders:	List of references to output encoders (HDMI, SDTV)

Would it make sense to make all those nodes child node of the vc4
object. That way, there's no need to have these lists of objects; they
can be automatically built up as the DT is enumerated. I know that e.g.
the NVIDIA Tegra host1x binding works this way, and I think it may have
been inspired by other similar cases.

Of course, this is only appropriate if the HW modules really are
logically children of the VC4 HW module. Perhaps they aren't. If they
aren't though, I wonder what this "vc4" module actually represents in HW?

> +Required properties for HDMI
> +- compatible:	Should be "brcm,vc4-hdmi"
> +- reg:		Physical base address and length of the two register ranges
> +		  ("HDMI" and "HD")

I'd add "in that order" right before ")".

> +Example:
> +/ {
> +	soc {

Minor nit: Examples often don't include any nodes "above" the nodes
whose bindings are being documented.


From swarren at wwwdotorg.org  Fri Aug 14 21:39:56 2015
From: swarren at wwwdotorg.org (Stephen Warren)
Date: Fri, 14 Aug 2015 22:39:56 -0600
Subject: [PATCH 2/7] MAINTAINERS: Add myself for the new VC4 (RPi GPU)
 graphics driver.
In-Reply-To: <1439427380-2436-3-git-send-email-eric@anholt.net>
References: <1439427380-2436-1-git-send-email-eric@anholt.net>
 <1439427380-2436-3-git-send-email-eric@anholt.net>
Message-ID: <55CEC29C.806@wwwdotorg.org>

On 08/12/2015 06:56 PM, Eric Anholt wrote:

> diff --git a/MAINTAINERS b/MAINTAINERS

> +DRM DRIVERS FOR VC4
> +M:	Eric Anholt <eric at anholt.net>
> +T:	git git://github.com/anholt/linux
> +S:	Maintained
> +F:	drivers/gpu/drm/vc4/*

S: Supported

?


From swarren at wwwdotorg.org  Fri Aug 14 21:45:12 2015
From: swarren at wwwdotorg.org (Stephen Warren)
Date: Fri, 14 Aug 2015 22:45:12 -0600
Subject: [PATCH 3/7] drm/vc4: Add KMS support for Raspberry Pi.
In-Reply-To: <1439427380-2436-4-git-send-email-eric@anholt.net>
References: <1439427380-2436-1-git-send-email-eric@anholt.net>
 <1439427380-2436-4-git-send-email-eric@anholt.net>
Message-ID: <55CEC3D8.7060103@wwwdotorg.org>

On 08/12/2015 06:56 PM, Eric Anholt wrote:
> This is the start of a full VC4 driver.  Right now this just supports
> configuring the display using a pre-existing video mode (because
> changing the pixel clock isn't available yet, and doesn't work when it
> is).  However, this is enough for fbcon and bringing up X using
> xf86-video-modesetting.

> diff --git a/drivers/gpu/drm/vc4/Kconfig b/drivers/gpu/drm/vc4/Kconfig

> +config DRM_VC4
> +	tristate "Broadcom VC4 Graphics"

> +	help
> +	  Choose this option if you have a system that has a Broadcom
> +	  VC4 GPU, such as the Raspberry Pi or other BCM2708/BCM2835.
> +
> +	  This driver requires that "avoid_warnings=2" be present in
> +	  the config.txt for the firmware, to keep it from smashing
> +	  our display setup.

The need for "avoid_warnings=2" seems like it will trip people up. I
don't think it's in any config.txt I've seen. Can you expand more on that?


From bjorn.andersson at sonymobile.com  Fri Aug 14 21:50:17 2015
From: bjorn.andersson at sonymobile.com (Bjorn Andersson)
Date: Fri, 14 Aug 2015 21:50:17 -0700
Subject: [PATCH] soc: qcom: smem: Fix errant private access
In-Reply-To: <1439610990-8427-1-git-send-email-agross@codeaurora.org>
References: <1439610990-8427-1-git-send-email-agross@codeaurora.org>
Message-ID: <20150815045017.GK13472@usrtlx11787.corpusers.net>

On Fri 14 Aug 20:56 PDT 2015, Andy Gross wrote:

> This patch corrects private partition item access.  Instead of falling back to
> global for instances where we have an actual host and remote partition existing,
> return the results of the private lookup.
> 
> Signed-off-by: Andy Gross <agross at codeaurora.org>
> ---
>  drivers/soc/qcom/smem.c |    5 +++--
>  1 file changed, 3 insertions(+), 2 deletions(-)
> 
> diff --git a/drivers/soc/qcom/smem.c b/drivers/soc/qcom/smem.c
> index 7c2c324c..6603201d 100644
> --- a/drivers/soc/qcom/smem.c
> +++ b/drivers/soc/qcom/smem.c
> @@ -484,8 +484,9 @@ int qcom_smem_get(unsigned host, unsigned item, void **ptr, size_t *size)
>  	if (ret)
>  		return ret;
>  
> -	ret = qcom_smem_get_private(__smem, host, item, ptr, size);
> -	if (ret == -ENOENT)
> +	if (host < SMEM_HOST_COUNT && __smem->partitions[host])
> +		ret = qcom_smem_get_private(__smem, host, item, ptr, size);
> +	else
>  		ret = qcom_smem_get_global(__smem, item, ptr, size);

Looks good, but you can drop the if statement in the beginning of the
qcom_smem_get_private() now.

Can you please also do the same change in the alloc path, to keep them
consistent?

Regards,
Bjorn


From swarren at wwwdotorg.org  Fri Aug 14 21:51:51 2015
From: swarren at wwwdotorg.org (Stephen Warren)
Date: Fri, 14 Aug 2015 22:51:51 -0600
Subject: [PATCH 6/7] ARM: bcm2835: Add the DDC I2C controller to the device
 tree.
In-Reply-To: <1439427380-2436-7-git-send-email-eric@anholt.net>
References: <1439427380-2436-1-git-send-email-eric@anholt.net>
 <1439427380-2436-7-git-send-email-eric@anholt.net>
Message-ID: <55CEC567.109@wwwdotorg.org>

On 08/12/2015 06:56 PM, Eric Anholt wrote:
> We need to use it for getting video modes over HDMI.

> diff --git a/arch/arm/boot/dts/bcm2835.dtsi b/arch/arm/boot/dts/bcm2835.dtsi

> +		i2c2: i2c at 7e805000 {
> +			compatible = "brcm,bcm2835-i2c";
> +			reg = <0x7e805000 0x1000>;
> +			interrupts = <2 21>;
> +			clocks = <&clk_i2c>;
> +			#address-cells = <1>;
> +			#size-cells = <0>;
> +		};

In an SoC .dtsi file, you'd typically write:

	status = "disabled";

... in all nodes that represent IO controllers that interface to
external HW, so that board DT files can/must explicitly choose to enable
the device if it's actually in use on the board. Some systems might not
have HDMI and hence might not hook up the HDMI_SCL/SDA pads.

BCM2835-ARM-Peripherals.pdf states "Note that the BSC2 master is used
dedicated with the HDMI interface and should not be accessed by user
programs.". Does this imply the Linux kernel shouldn't be touching this
I2C controller; that the VC4 firmware might also be attempting to use
it? I wonder how any such sharing of the HW would work.


From swarren at wwwdotorg.org  Fri Aug 14 21:54:00 2015
From: swarren at wwwdotorg.org (Stephen Warren)
Date: Fri, 14 Aug 2015 22:54:00 -0600
Subject: [PATCH 7/7] ARM: bcm2835: Add VC4 to the device tree.
In-Reply-To: <1439427380-2436-8-git-send-email-eric@anholt.net>
References: <1439427380-2436-1-git-send-email-eric@anholt.net>
 <1439427380-2436-8-git-send-email-eric@anholt.net>
Message-ID: <55CEC5E8.6090203@wwwdotorg.org>

On 08/12/2015 06:56 PM, Eric Anholt wrote:
> Signed-off-by: Eric Anholt <eric at anholt.net>

Patch description?


> diff --git a/arch/arm/boot/dts/bcm2835.dtsi b/arch/arm/boot/dts/bcm2835.dtsi

>  		arm-pmu {
>  			compatible = "arm,arm1176-pmu";
>  		};
> +
> +		hdmi: brcm,vc4-hdmi at 7e902000 {

It'd be nice to keep all the DT nodes with a reg property together, and
sorted in reg order.

As before, I think any DT node for a HW block that may-or-may-not-be
used based on board connectivity/features should be disabled in the SoC
.dtsi file, and enabled in the board's DT file if the feature is useful
for that board.


From agross at codeaurora.org  Fri Aug 14 21:56:59 2015
From: agross at codeaurora.org (Andy Gross)
Date: Fri, 14 Aug 2015 23:56:59 -0500
Subject: [Patch v2] soc: qcom: smem: Fix errant private access
Message-ID: <1439614619-29808-1-git-send-email-agross@codeaurora.org>

This patch corrects private partition item access.  Instead of falling back to
global for instances where we have an actual host and remote partition existing,
return the results of the private lookup.

Signed-off-by: Andy Gross <agross at codeaurora.org>
---
 drivers/soc/qcom/smem.c |   18 ++++++------------
 1 file changed, 6 insertions(+), 12 deletions(-)

diff --git a/drivers/soc/qcom/smem.c b/drivers/soc/qcom/smem.c
index c809127..7fddf3b 100644
--- a/drivers/soc/qcom/smem.c
+++ b/drivers/soc/qcom/smem.c
@@ -264,10 +264,6 @@ static int qcom_smem_alloc_private(struct qcom_smem *smem,
 	size_t alloc_size;
 	void *p;
 
-	/* We're not going to find it if there's no matching partition */
-	if (host >= SMEM_HOST_COUNT || !smem->partitions[host])
-		return -ENOENT;
-
 	phdr = smem->partitions[host];
 
 	p = (void *)phdr + sizeof(*phdr);
@@ -377,8 +373,9 @@ int qcom_smem_alloc(unsigned host, unsigned item, size_t size)
 	if (ret)
 		return ret;
 
-	ret = qcom_smem_alloc_private(__smem, host, item, size);
-	if (ret == -ENOENT)
+	if (host < SMEM_HOST_COUNT && __smem->partitions[host])
+		ret = qcom_smem_alloc_private(__smem, host, item, size);
+	else
 		ret = qcom_smem_alloc_global(__smem, item, size);
 
 	hwspin_unlock_irqrestore(__smem->hwlock, &flags);
@@ -434,10 +431,6 @@ static int qcom_smem_get_private(struct qcom_smem *smem,
 	struct smem_private_entry *hdr;
 	void *p;
 
-	/* We're not going to find it if there's no matching partition */
-	if (host >= SMEM_HOST_COUNT || !smem->partitions[host])
-		return -ENOENT;
-
 	phdr = smem->partitions[host];
 
 	p = (void *)phdr + sizeof(*phdr);
@@ -490,8 +483,9 @@ int qcom_smem_get(unsigned host, unsigned item, void **ptr, size_t *size)
 	if (ret)
 		return ret;
 
-	ret = qcom_smem_get_private(__smem, host, item, ptr, size);
-	if (ret == -ENOENT)
+	if (host < SMEM_HOST_COUNT && __smem->partitions[host])
+		ret = qcom_smem_get_private(__smem, host, item, ptr, size);
+	else
 		ret = qcom_smem_get_global(__smem, item, ptr, size);
 
 	hwspin_unlock_irqrestore(__smem->hwlock, &flags);
-- 
The Qualcomm Innovation Center, Inc. is a member of the Code Aurora Forum,
hosted by The Linux Foundation



From bjorn.andersson at sonymobile.com  Fri Aug 14 22:48:17 2015
From: bjorn.andersson at sonymobile.com (Bjorn Andersson)
Date: Fri, 14 Aug 2015 22:48:17 -0700
Subject: [PATCH 3/3] mtd: add SMEM parser for QCOM platforms
In-Reply-To: <1439599573-3932-4-git-send-email-mathieu@codeaurora.org>
References: <1439599573-3932-1-git-send-email-mathieu@codeaurora.org>
 <1439599573-3932-4-git-send-email-mathieu@codeaurora.org>
Message-ID: <20150815054817.GM13472@usrtlx11787.corpusers.net>

On Fri 14 Aug 17:46 PDT 2015, Mathieu Olivari wrote:

> On QCOM platforms using MTD devices storage (such as IPQ806x), SMEM is
> used to store partition layout. This new parser can now be used to read
> SMEM and use it to register an MTD layout according to its content.
> 

Nice to see another user of the smem code :)

> diff --git a/drivers/mtd/qcom_smem_part.c b/drivers/mtd/qcom_smem_part.c
[..]
> +
> +/* Processor/host identifier for the application processor */
> +#define SMEM_HOST_APPS			0

This makes me wonder if there will ever be an apps partition. I would
have picked QCOM_SMEM_HOST_ANY, but I don't know what future platforms
might hold for us.


And as a side note, I think I will propose that we rename that define
QCOM_SMEM_GLOBAL.

> +
> +/* SMEM items index */
> +#define SMEM_AARM_PARTITION_TABLE	9
> +#define SMEM_BOOT_FLASH_TYPE		421
> +#define SMEM_BOOT_FLASH_BLOCK_SIZE	424
> +
> +/* SMEM Flash types */
> +#define SMEM_FLASH_NAND			2
> +#define SMEM_FLASH_SPI			6
> +
> +#define SMEM_PART_NAME_SZ		16
> +#define SMEM_PARTS_MAX			32
> +
> +struct smem_partition {
> +	char name[SMEM_PART_NAME_SZ];
> +	__le32 start;
> +	__le32 size;
> +	__le32 attr;
> +};
> +
> +struct smem_partition_table {
> +	u8 magic[8];
> +	__le32 version;
> +	__le32 len;
> +	struct smem_partition parts[SMEM_PARTS_MAX];
> +};
> +
> +/* SMEM Magic values in partition table */
> +static const u8 SMEM_PTABLE_MAGIC[] = {
> +	0xaa, 0x73, 0xee, 0x55,
> +	0xdb, 0xbd, 0x5e, 0xe3,
> +};
> +
> +static int qcom_smem_get_flash_blksz(u64 **smem_blksz)

Instead of passing pointers around I think you should just make this
function return < 0 for errors and >= 0 for the requested data. You can
probably still have it as an int, as the current values are well below
the size of the int.

> +{
> +	int ret;
> +	size_t size;
> +
> +	ret = qcom_smem_get(SMEM_HOST_APPS, SMEM_BOOT_FLASH_BLOCK_SIZE,
> +			    (void **) smem_blksz, &size);
> +
> +	if (ret < 0) {
> +		pr_err("Unable to read flash blksz from SMEM\n");
> +		return -ENOENT;
> +	}
> +
> +	if (size != sizeof(**smem_blksz)) {
> +		pr_err("Invalid flash blksz size in SMEM\n");
> +		return -EINVAL;
> +	}
> +
> +	return 0;
> +}
> +
> +static int qcom_smem_get_flash_type(u64 **smem_flash_type)

Same as above.

> +{
> +	int ret;
> +	size_t size;
> +
> +	ret = qcom_smem_get(SMEM_HOST_APPS, SMEM_BOOT_FLASH_TYPE,
> +			    (void **) smem_flash_type, &size);
> +
> +	if (ret < 0) {
> +		pr_err("Unable to read flash type from SMEM\n");
> +		return -ENOENT;
> +	}
> +
> +	if (size != sizeof(**smem_flash_type)) {
> +		pr_err("Invalid flash type size in SMEM\n");
> +		return -EINVAL;
> +	}
> +
> +	return 0;
> +}
> +
> +static int qcom_smem_get_flash_partitions(struct smem_partition_table **pparts)
> +{
> +	int ret;
> +	size_t size;
> +
> +	ret = qcom_smem_get(SMEM_HOST_APPS, SMEM_AARM_PARTITION_TABLE,
> +			    (void **) pparts, &size);
> +

If you don't care about the size just pass NULL as the last argument.

> +	if (ret < 0) {
> +		pr_err("Unable to read partition table from SMEM\n");
> +		return -ENOENT;
> +	}

I think it would be cleaner if you had this function check the magic and
version and then return the partition pointer. That is:

static smem_partition *qcom_smem_get_flash_partitions(size_t *count)


And make *count = le32_to_cpu(table->len); so you don't have to care
about that below.

(And use NULL or ERR_PTR for the error paths)

> +
> +	return 0;
> +}
> +
> +static int of_dev_node_match(struct device *dev, void *data)
> +{
> +	return dev->of_node == data;
> +}
> +
> +static bool is_spi_device(struct device_node *np)
> +{
> +	struct device *dev;
> +
> +	dev = bus_find_device(&spi_bus_type, NULL, np, of_dev_node_match);
> +	if (!dev)
> +		return false;
> +
> +	put_device(dev);
> +	return true;
> +}
> +
> +static int parse_qcom_smem_partitions(struct mtd_info *master,
> +				      struct mtd_partition **pparts,
> +				      struct mtd_part_parser_data *data)
> +{
> +	struct smem_partition_table *smem_parts;
> +	u64 *smem_flash_type, *smem_blksz;
> +	struct mtd_partition *mtd_parts;
> +	struct device_node *of_node = data->of_node;
> +	int i, ret;
> +
> +	/*
> +	 * SMEM will only store the partition table of the boot device.
> +	 * If this is not the boot device, do not return any partition.
> +	 */

I guess this is the result of below checks, but it's not describing
what's actually done here. I think it should say "only parse
partitions on the specified memory type" or something like that.

> +	ret = qcom_smem_get_flash_type(&smem_flash_type);
> +	if (ret < 0)
> +		return ret;
> +
> +	if ((*smem_flash_type == SMEM_FLASH_NAND && !mtd_type_is_nand(master))
> +	    || (*smem_flash_type == SMEM_FLASH_SPI && !is_spi_device(of_node)))
> +		return 0;
> +
> +	/*
> +	 * Just for sanity purpose, make sure the block size in SMEM matches the
> +	 * block size of the MTD device
> +	 */

Well, this is not only for sanity purpose, as you multiply all sizes
with this number below...

> +	ret = qcom_smem_get_flash_blksz(&smem_blksz);
> +	if (ret < 0)
> +		return ret;
> +
> +	if (*smem_blksz != master->erasesize) {
> +		pr_err("SMEM block size differs from MTD block size\n");
> +		return -EINVAL;
> +	}
> +
> +	/* Get partition pointer from SMEM */
> +	ret = qcom_smem_get_flash_partitions(&smem_parts);
> +	if (ret < 0)
> +		return ret;
> +
> +	if (memcmp(SMEM_PTABLE_MAGIC, smem_parts->magic,
> +		   sizeof(SMEM_PTABLE_MAGIC))) {
> +		pr_err("SMEM partition magic invalid\n");
> +		return -EINVAL;
> +	}
> +
> +	/* Allocate and populate the mtd structures */
> +	mtd_parts = kcalloc(le32_to_cpu(smem_parts->len), sizeof(*mtd_parts),
> +			    GFP_KERNEL);
> +	if (!mtd_parts)
> +		return -ENOMEM;
> +
> +	for (i = 0; i < smem_parts->len; i++) {

This might have the wrong endian...

> +		struct smem_partition *s_part = &smem_parts->parts[i];
> +		struct mtd_partition *m_part = &mtd_parts[i];

I think Stephens suggestion was that you assign *pparts before looping
and then you simply do:

*pparts = mtd_parts;

while (len--) {
	..

	s_part++;
	mtd_parts++;
}

> +
> +		m_part->name = s_part->name;

I tried to follow the mtd code, and I believe that this pointer might
be freed in free_partition(). If so you must kstrdup it here.

> +		m_part->size = le32_to_cpu(s_part->size) * (*smem_blksz);
> +		m_part->offset = le32_to_cpu(s_part->start) * (*smem_blksz);
> +
> +		/*
> +		 * The last SMEM partition may have its size marked as
> +		 * something like 0xffffffff, which means "until the end of the
> +		 * flash device". In this case, truncate it.
> +		 */
> +		if (m_part->offset + m_part->size > master->size)
> +			m_part->size = master->size - m_part->offset;
> +	}
> +
> +	*pparts = mtd_parts;
> +
> +	return smem_parts->len;

Again, this might be in the wrong endian.

> +}
> +
> +static struct mtd_part_parser qcom_smem_parser = {
> +	.owner = THIS_MODULE,
> +	.parse_fn = parse_qcom_smem_partitions,
> +	.name = "qcom-smem",
> +};
> +
> +static int __init qcom_smem_parser_init(void)
> +{
> +	register_mtd_parser(&qcom_smem_parser);
> +	return 0;
> +}
> +
> +static void __exit qcom_smem_parser_exit(void)
> +{
> +	deregister_mtd_parser(&qcom_smem_parser);
> +}
> +
> +module_init(qcom_smem_parser_init);
> +module_exit(qcom_smem_parser_exit);

Mostly unrelated to this patch; This makes me appreciate the
module_platform_driver() macro, would be nice to see a patch that
introduces something similar for partition parsers.

> +
> +MODULE_LICENSE("GPL");

Are you sure you don't mean "GPL v2" here?

> +MODULE_AUTHOR("Mathieu Olivari <mathieu at codeaurora.org>");
> +MODULE_DESCRIPTION("Parsing code for SMEM based partition tables");

Regards,
Bjorn


From bjorn.andersson at sonymobile.com  Fri Aug 14 22:50:28 2015
From: bjorn.andersson at sonymobile.com (Bjorn Andersson)
Date: Fri, 14 Aug 2015 22:50:28 -0700
Subject: [Patch v2] soc: qcom: smem: Fix errant private access
In-Reply-To: <1439614619-29808-1-git-send-email-agross@codeaurora.org>
References: <1439614619-29808-1-git-send-email-agross@codeaurora.org>
Message-ID: <20150815055028.GN13472@usrtlx11787.corpusers.net>

On Fri 14 Aug 21:56 PDT 2015, Andy Gross wrote:

> This patch corrects private partition item access.  Instead of falling back to
> global for instances where we have an actual host and remote partition existing,
> return the results of the private lookup.
> 
> Signed-off-by: Andy Gross <agross at codeaurora.org>

Thanks for finding this issue.

Reviewed-by: Bjorn Andersson <bjorn.andersson at sonymobile.com>

Regards,
Bjorn


From scottwood at freescale.com  Fri Aug 14 23:43:37 2015
From: scottwood at freescale.com (Scott Wood)
Date: Sat, 15 Aug 2015 01:43:37 -0500
Subject: [RFC PATCH 0/8] clk: qoriq: Move chip-specific knowledge into
 driver
In-Reply-To: <20150811182535.31346.52965@quantum>
References: <1434682158-7243-1-git-send-email-scottwood@freescale.com>
 <20150811182535.31346.52965@quantum>
Message-ID: <1439621017.15601.23.camel@freescale.com>

On Tue, 2015-08-11 at 11:25 -0700, Michael Turquette wrote:
> Hi Scott,
> 
> Quoting Scott Wood (2015-06-18 19:49:10)
> > The existing device tree bindings are error-prone and inflexible. 
> > Correct the mistake by moving the knowledge into the driver, which
> > has more flexibility in describing the quirks of each chip.  This leaves
> > the device tree to its proper role of identifying a programming interface
> > rather than describing its individual registers.
> 
> Sorry for not responding to this one sooner. Fell through the cracks.
> 
> All of the changes to drives/clk/clk-qoriq.c look great to me. I assume
> you need to keep all of these patches together and want to the take
> through the freescale tree? If so feel free to add,
> 
> Acked-by: Michael Turquette <mturquette at baylibre.com>

I just sent a non-RFC v2, with improved compatibility with old device trees 
(especially ls1021a).  It depends on the cpufreq patch though (at least, to 
avoid breaking qoriq-cpufreq until that patch is merged), so I'll also need 
an ack from Rafael for that if I'm taking it through my tree.

-Scott



From stefan.wahren at i2se.com  Sat Aug 15 00:21:56 2015
From: stefan.wahren at i2se.com (Stefan Wahren)
Date: Sat, 15 Aug 2015 09:21:56 +0200 (CEST)
Subject: [PATCH RFC 3/3] nvmem: add permission flags in nvmem_config
In-Reply-To: <1439291024-18375-1-git-send-email-srinivas.kandagatla@linaro.org>
References: <1439290931-18232-1-git-send-email-srinivas.kandagatla@linaro.org>
 <1439291024-18375-1-git-send-email-srinivas.kandagatla@linaro.org>
Message-ID: <1634428787.18822.1439623316281.JavaMail.open-xchange@oxbsltgw04.schlund.de>

Hi Srinivas,

> Srinivas Kandagatla <srinivas.kandagatla at linaro.org> hat am 11. August 2015 um
> 13:03 geschrieben:
>
>
> This patch adds perm variable to nvmem_config structure which will allow
> providers to specify the permissions required for the sysfs binary file.
> This permission is applied on top of root-only access permissions set by
> the core.
>
> Signed-off-by: Srinivas Kandagatla <srinivas.kandagatla at linaro.org>
> ---
> drivers/nvmem/core.c | 1 +
> include/linux/nvmem-provider.h | 1 +
> 2 files changed, 2 insertions(+)
>
> diff --git a/drivers/nvmem/core.c b/drivers/nvmem/core.c
> index 414ed23..7481387 100644
> --- a/drivers/nvmem/core.c
> +++ b/drivers/nvmem/core.c
> @@ -312,6 +312,7 @@ struct nvmem_device *nvmem_register(const struct
> nvmem_config *config)
> config->read_only;
> nvmem->bin = bin_attr_template;
> nvmem->bin.attr.mode = nvmem->read_only ? : (S_IRUSR | S_IWUSR);
> + nvmem->bin.attr.mode |= config->perm;
> nvmem->bin.size = nvmem->size;
> device_initialize(&nvmem->dev);
>
> diff --git a/include/linux/nvmem-provider.h b/include/linux/nvmem-provider.h
> index 0b68caf..de9a61f 100644
> --- a/include/linux/nvmem-provider.h
> +++ b/include/linux/nvmem-provider.h
> @@ -23,6 +23,7 @@ struct nvmem_config {
> const struct nvmem_cell_info *cells;
> int ncells;
> bool read_only;
> + u16 perm; /* visibility in sysfs */

how about "umode_t mode" or "umode_t sysfs_mode"?

Beside that the whole series looks good to me.

Thanks Stefan


From yamada.masahiro at socionext.com  Sat Aug 15 01:21:59 2015
From: yamada.masahiro at socionext.com (Masahiro Yamada)
Date: Sat, 15 Aug 2015 17:21:59 +0900
Subject: [PATCH 3/3] ARM: dts: UniPhier: add ProXstream2 and PH1-LD6b
 SoC/board support
In-Reply-To: <CAOesGMhhSKr6Nn7YEjoB9V_5-yhwzn_fKZ7FSU3U-2XYT5mJrQ@mail.gmail.com>
References: <1438687264-26538-1-git-send-email-yamada.masahiro@socionext.com>
 <1438687264-26538-4-git-send-email-yamada.masahiro@socionext.com>
 <20150811130739.GD30181@localhost>
 <CAK7LNAQ+6tQ9Ci6LKsAB7kLj0o60Hizo2gOokDH9qW=FnO0gEA@mail.gmail.com>
 <CAOesGMhhSKr6Nn7YEjoB9V_5-yhwzn_fKZ7FSU3U-2XYT5mJrQ@mail.gmail.com>
Message-ID: <CAK7LNATVhFLe_ObuLdWxNWiO=kapBrvEJEVHEfZC8Bu5AsRASA@mail.gmail.com>

Hi Olof,


2015-08-13 18:09 GMT+09:00 Olof Johansson <olof at lixom.net>:
> On Wed, Aug 12, 2015 at 3:14 PM, Masahiro Yamada
> <yamada.masahiro at socionext.com> wrote:
>> Hi Olof,
>>
>>
>> 2015-08-11 22:07 GMT+09:00 Olof Johansson <olof at lixom.net>:
>>> Hi,
>>>
>>> On Tue, Aug 04, 2015 at 08:21:04PM +0900, Masahiro Yamada wrote:
>>>> Initial version of DTSI for ProXstream2 and PH1-LD6b and DTS for
>>>> PH1-LD6b reference board.
>>>>
>>>> Signed-off-by: Masahiro Yamada <yamada.masahiro at socionext.com>
>>>> ---
>>>>
>>>>  arch/arm/boot/dts/Makefile                  |   3 +-
>>>>  arch/arm/boot/dts/uniphier-ph1-ld6b-ref.dts | 105 +++++++++++
>>>>  arch/arm/boot/dts/uniphier-ph1-ld6b.dtsi    |  67 +++++++
>>>>  arch/arm/boot/dts/uniphier-proxstream2.dtsi | 273 ++++++++++++++++++++++++++++
>>>>  4 files changed, 447 insertions(+), 1 deletion(-)
>>>>  create mode 100644 arch/arm/boot/dts/uniphier-ph1-ld6b-ref.dts
>>>>  create mode 100644 arch/arm/boot/dts/uniphier-ph1-ld6b.dtsi
>>>>  create mode 100644 arch/arm/boot/dts/uniphier-proxstream2.dtsi
>>>>
>>>> diff --git a/arch/arm/boot/dts/Makefile b/arch/arm/boot/dts/Makefile
>>>> index 246473a..6eb3f2f 100644
>>>> --- a/arch/arm/boot/dts/Makefile
>>>> +++ b/arch/arm/boot/dts/Makefile
>>>> @@ -645,7 +645,8 @@ dtb-$(CONFIG_ARCH_UNIPHIER) += \
>>>>       uniphier-ph1-sld3-ref.dtb \
>>>>       uniphier-ph1-ld4-ref.dtb \
>>>>       uniphier-ph1-pro4-ref.dtb \
>>>> -     uniphier-ph1-sld8-ref.dtb
>>>> +     uniphier-ph1-sld8-ref.dtb \
>>>> +     uniphier-ph1-ld6b-ref.dtb
>>>
>>> Please always add entries here sorted, don't just append. I've fixed it
>>> up for you this time.
>>>
>>>
>>
>> Please do not do that (without my ack).
>
> I'm not going to go get your ack for something as trivial as this. We
> do make sure subplatform maintainers are in the loop and get to review
> code that touches their platform, but in this case this was a shared
> makefile and there were no functional changes.
>
>> It was already sorted from old SoC to new SoC.
>>
>> Sorting chronologically (in other words, in the order of chip ID)
>> makes more sense than sorting alphabetically.
>
> No, it doesn't. All entries in these files should be sorted
> alphabetically. Sometimes we miss out on it, but it's the goal.


I did not know that, my apology.



> If you sort chronologically it's impossible for anyone but people
> intimately familiar with UniPhier's product history to add any new
> entries in the right location. Also, since it's likely that newer
> chips will be introduced over time, new entries are likely to just be
> appends instead of inserted at more varied locations in the files.
>
> Append-only additions are more likely to have add/add conflicts, which
> is why we're preferring alphabetical sort order in the first place.


This is true for various entries as well as arch/arm/boot/dts/Makefile.
I am wondering how far we should stick to alphabetical sorting.


For example, do you recommend OF compatible tables should be sorted
alphabetically?


arch/arm/mach-uniphier/uniphier.c:

static const char * const uniphier_dt_compat[] __initconst = {
        "socionext,ph1-sld3",
        "socionext,ph1-ld4",
        "socionext,ph1-pro4",
        "socionext,ph1-sld8",
        "socionext,ph1-pro5",
        "socionext,proxstream2",
        "socionext,ph1-ld6b",
        NULL,
};

This table (only containing SoC names) is currently sorted
chronologically, and the logic
is the same as arch/arm/boot/dts/Makefile.


This file belongs to my maintainer-ship, but I just wonder
which sorting rule, chronologically or alphabetically, is better in general.



-- 
Best Regards
Masahiro Yamada


From ard.biesheuvel at linaro.org  Sat Aug 15 05:13:44 2015
From: ard.biesheuvel at linaro.org (Ard Biesheuvel)
Date: Sat, 15 Aug 2015 14:13:44 +0200
Subject: [PATCH] arm64: ignore memory outside of the linear range
Message-ID: <1439640824-30498-1-git-send-email-ard.biesheuvel@linaro.org>

We need to ensure that we don't try to map system RAM ranges whose
offset relative to the start of the kernel image exceeds the size of
the linear range. This may happen even on systems that don't have
huge amounts of RAM if it is laid out very sparsely.

Signed-off-by: Ard Biesheuvel <ard.biesheuvel at linaro.org>
---

This is the minimal fix for addressing the issue we discussed. I dropped
the other changes for now, let's revisit those when (if) my patches for
decoupling the kernel mapping from the linear mapping are back under
discussion.

I will leave it up to the maintainers whether this constitutes a bugfix or
not, but since this has never worked from the beginning afaict, I don't
think it belongs in stable per se.

 arch/arm64/mm/init.c | 13 +++++++++++++
 1 file changed, 13 insertions(+)

diff --git a/arch/arm64/mm/init.c b/arch/arm64/mm/init.c
index ad87ce826cce..c65e57d4c3e7 100644
--- a/arch/arm64/mm/init.c
+++ b/arch/arm64/mm/init.c
@@ -158,6 +158,19 @@ early_param("mem", early_mem);
 
 void __init arm64_memblock_init(void)
 {
+	/*
+	 * Remove the memory that we will not be able to cover
+	 * with the linear mapping.
+	 */
+	const s64 linear_region_size = -(s64)PAGE_OFFSET;
+
+	if (memstart_addr + linear_region_size < memblock_end_of_DRAM()) {
+		pr_warn("Ignoring memory outside of linear range (0x%012llx - 0x%012llx)\n",
+			memstart_addr + linear_region_size,
+			(u64)memblock_end_of_DRAM() - 1);
+		memblock_remove(memstart_addr + linear_region_size, ULLONG_MAX);
+	}
+
 	memblock_enforce_memory_limit(memory_limit);
 
 	/*
-- 
1.9.1



From jic23 at kernel.org  Sat Aug 15 06:13:14 2015
From: jic23 at kernel.org (Jonathan Cameron)
Date: Sat, 15 Aug 2015 14:13:14 +0100
Subject: [PATCH 16/20] iio: bmc150: Fix irq checks
In-Reply-To: <1439374365-20623-17-git-send-email-mpa@pengutronix.de>
References: <1439374365-20623-1-git-send-email-mpa@pengutronix.de>
 <1439374365-20623-17-git-send-email-mpa@pengutronix.de>
Message-ID: <55CF3AEA.2070508@kernel.org>

On 12/08/15 11:12, Markus Pargmann wrote:
> Valid irqs are > 0. This patch fixes the check which fails for the new
> spi driver part if no interrupt was given.
> 
> Signed-off-by: Markus Pargmann <mpa at pengutronix.de>
This one crossed with Octavian's patch that cleaned up all cases of this.
c176becd81843 iio: fix drivers that consider 0 as a valid IRQ in client->irq

Hence you can drop this one from the v2 of this series.

(Its amazing how many times we get multiple patches for the same issue that
has been there for ages in the same week or so!)

Jonathan
> ---
>  drivers/iio/accel/bmc150-accel.c | 4 ++--
>  1 file changed, 2 insertions(+), 2 deletions(-)
> 
> diff --git a/drivers/iio/accel/bmc150-accel.c b/drivers/iio/accel/bmc150-accel.c
> index 4e70f51c2370..fe2d2316158f 100644
> --- a/drivers/iio/accel/bmc150-accel.c
> +++ b/drivers/iio/accel/bmc150-accel.c
> @@ -1660,10 +1660,10 @@ static int bmc150_accel_probe(struct i2c_client *client,
>  		return ret;
>  	}
>  
> -	if (client->irq < 0)
> +	if (client->irq <= 0)
>  		client->irq = bmc150_accel_gpio_probe(client, data);
>  
> -	if (client->irq >= 0) {
> +	if (client->irq > 0) {
>  		ret = devm_request_threaded_irq(
>  						&client->dev, client->irq,
>  						bmc150_accel_irq_handler,
> 



From jic23 at kernel.org  Sat Aug 15 06:27:47 2015
From: jic23 at kernel.org (Jonathan Cameron)
Date: Sat, 15 Aug 2015 14:27:47 +0100
Subject: [PATCH 17/20] iio: bmc150: Use i2c regmap
In-Reply-To: <1439374365-20623-18-git-send-email-mpa@pengutronix.de>
References: <1439374365-20623-1-git-send-email-mpa@pengutronix.de>
 <1439374365-20623-18-git-send-email-mpa@pengutronix.de>
Message-ID: <55CF3E53.2080005@kernel.org>

On 12/08/15 11:12, Markus Pargmann wrote:
> This replaces all usage of direct i2c accesses with regmap accesses.
> 
> Signed-off-by: Markus Pargmann <mpa at pengutronix.de>
Clearly there is some work needed on the earlier patches and this
might change as a result (particularly the fifo read).  I'll review
as is however..

Few bits on top of what other reviews have highlighted...

Jonathan
> ---
>  drivers/iio/accel/Kconfig        |   2 +
>  drivers/iio/accel/bmc150-accel.c | 225 +++++++++++++++++----------------------
>  2 files changed, 101 insertions(+), 126 deletions(-)
> 
> diff --git a/drivers/iio/accel/Kconfig b/drivers/iio/accel/Kconfig
> index 00e7bcbdbe24..01dd03d194d1 100644
> --- a/drivers/iio/accel/Kconfig
> +++ b/drivers/iio/accel/Kconfig
> @@ -22,6 +22,8 @@ config BMC150_ACCEL
>  	depends on I2C
>  	select IIO_BUFFER
>  	select IIO_TRIGGERED_BUFFER
> +	select REGMAP
> +	select REGMAP_I2C
>  	help
>  	  Say yes here to build support for the following Bosch accelerometers:
>  	  BMC150, BMI055, BMA250E, BMA222E, BMA255, BMA280.
> diff --git a/drivers/iio/accel/bmc150-accel.c b/drivers/iio/accel/bmc150-accel.c
> index fe2d2316158f..1484e956482e 100644
> --- a/drivers/iio/accel/bmc150-accel.c
> +++ b/drivers/iio/accel/bmc150-accel.c
> @@ -35,6 +35,7 @@
>  #include <linux/iio/trigger.h>
>  #include <linux/iio/trigger_consumer.h>
>  #include <linux/iio/triggered_buffer.h>
> +#include <linux/regmap.h>
>  
>  #define BMC150_ACCEL_DRV_NAME			"bmc150_accel"
>  #define BMC150_ACCEL_IRQ_NAME			"bmc150_accel_event"
> @@ -185,6 +186,8 @@ enum bmc150_accel_trigger_id {
>  
>  struct bmc150_accel_data {
>  	struct i2c_client *client;
> +	struct regmap *regmap;
> +	struct device *dev;
>  	struct bmc150_accel_interrupt interrupts[BMC150_ACCEL_INTERRUPTS];
>  	atomic_t active_intr;
>  	struct bmc150_accel_trigger triggers[BMC150_ACCEL_TRIGGERS];
> @@ -241,6 +244,14 @@ static const struct {
>  				       {500000, BMC150_ACCEL_SLEEP_500_MS},
>  				       {1000000, BMC150_ACCEL_SLEEP_1_SEC} };
>  
> +static const struct regmap_config bmc150_i2c_regmap_conf = {
> +	.reg_bits = 8,
> +	.val_bits = 8,
> +	.max_register = 0x3f,
> +
> +	.use_single_rw = false,
> +	.cache_type = REGCACHE_NONE,
> +};
>  
>  static int bmc150_accel_set_mode(struct bmc150_accel_data *data,
>  				 enum bmc150_power_modes mode,
> @@ -270,8 +281,7 @@ static int bmc150_accel_set_mode(struct bmc150_accel_data *data,
>  
>  	dev_dbg(&data->client->dev, "Set Mode bits %x\n", lpw_bits);
>  
> -	ret = i2c_smbus_write_byte_data(data->client,
> -					BMC150_ACCEL_REG_PMU_LPW, lpw_bits);
> +	ret = regmap_write(data->regmap, BMC150_ACCEL_REG_PMU_LPW, lpw_bits);
>  	if (ret < 0) {
>  		dev_err(&data->client->dev, "Error writing reg_pmu_lpw\n");
>  		return ret;
> @@ -289,8 +299,7 @@ static int bmc150_accel_set_bw(struct bmc150_accel_data *data, int val,
>  	for (i = 0; i < ARRAY_SIZE(bmc150_accel_samp_freq_table); ++i) {
>  		if (bmc150_accel_samp_freq_table[i].val == val &&
>  				bmc150_accel_samp_freq_table[i].val2 == val2) {
> -			ret = i2c_smbus_write_byte_data(
> -				data->client,
> +			ret = regmap_write(data->regmap,
>  				BMC150_ACCEL_REG_PMU_BW,
>  				bmc150_accel_samp_freq_table[i].bw_bits);
>  			if (ret < 0)
> @@ -307,26 +316,19 @@ static int bmc150_accel_set_bw(struct bmc150_accel_data *data, int val,
>  
>  static int bmc150_accel_update_slope(struct bmc150_accel_data *data)
>  {
> -	int ret, val;
> +	int ret;
>  
> -	ret = i2c_smbus_write_byte_data(data->client, BMC150_ACCEL_REG_INT_6,
> +	ret = regmap_write(data->regmap, BMC150_ACCEL_REG_INT_6,
>  					data->slope_thres);
>  	if (ret < 0) {
>  		dev_err(&data->client->dev, "Error writing reg_int_6\n");
>  		return ret;
>  	}
>  
> -	ret = i2c_smbus_read_byte_data(data->client, BMC150_ACCEL_REG_INT_5);
> +	ret = regmap_update_bits(data->regmap, BMC150_ACCEL_REG_INT_5,
> +				 BMC150_ACCEL_SLOPE_DUR_MASK, data->slope_dur);
>  	if (ret < 0) {
> -		dev_err(&data->client->dev, "Error reading reg_int_5\n");
> -		return ret;
> -	}
> -
> -	val = (ret & ~BMC150_ACCEL_SLOPE_DUR_MASK) | data->slope_dur;
> -	ret = i2c_smbus_write_byte_data(data->client, BMC150_ACCEL_REG_INT_5,
> -					val);
> -	if (ret < 0) {
> -		dev_err(&data->client->dev, "Error write reg_int_5\n");
> +		dev_err(&data->client->dev, "Error updating reg_int_5\n");
>  		return ret;
>  	}
>  
> @@ -348,17 +350,18 @@ static int bmc150_accel_any_motion_setup(struct bmc150_accel_trigger *t,
>  static int bmc150_accel_chip_init(struct bmc150_accel_data *data)
>  {
>  	int ret;
> +	unsigned int val;
>  
> -	ret = i2c_smbus_read_byte_data(data->client, BMC150_ACCEL_REG_CHIP_ID);
> +	ret = regmap_read(data->regmap, BMC150_ACCEL_REG_CHIP_ID, &val);
>  	if (ret < 0) {
>  		dev_err(&data->client->dev,
>  			"Error: Reading chip id\n");
>  		return ret;
>  	}
>  
> -	dev_dbg(&data->client->dev, "Chip Id %x\n", ret);
> -	if (ret != data->chip_info->chip_id) {
> -		dev_err(&data->client->dev, "Invalid chip %x\n", ret);
> +	dev_dbg(&data->client->dev, "Chip Id %x\n", val);
> +	if (val != data->chip_info->chip_id) {
> +		dev_err(&data->client->dev, "Invalid chip %x\n", val);
>  		return -ENODEV;
>  	}
>  
> @@ -372,9 +375,8 @@ static int bmc150_accel_chip_init(struct bmc150_accel_data *data)
>  		return ret;
>  
>  	/* Set Default Range */
> -	ret = i2c_smbus_write_byte_data(data->client,
> -					BMC150_ACCEL_REG_PMU_RANGE,
> -					BMC150_ACCEL_DEF_RANGE_4G);
> +	ret = regmap_write(data->regmap, BMC150_ACCEL_REG_PMU_RANGE,
> +			   BMC150_ACCEL_DEF_RANGE_4G);
>  	if (ret < 0) {
>  		dev_err(&data->client->dev,
>  					"Error writing reg_pmu_range\n");
> @@ -391,10 +393,9 @@ static int bmc150_accel_chip_init(struct bmc150_accel_data *data)
>  		return ret;
>  
>  	/* Set default as latched interrupts */
> -	ret = i2c_smbus_write_byte_data(data->client,
> -					BMC150_ACCEL_REG_INT_RST_LATCH,
> -					BMC150_ACCEL_INT_MODE_LATCH_INT |
> -					BMC150_ACCEL_INT_MODE_LATCH_RESET);
> +	ret = regmap_write(data->regmap, BMC150_ACCEL_REG_INT_RST_LATCH,
> +			   BMC150_ACCEL_INT_MODE_LATCH_INT |
> +			   BMC150_ACCEL_INT_MODE_LATCH_RESET);
>  	if (ret < 0) {
>  		dev_err(&data->client->dev,
>  			"Error writing reg_int_rst_latch\n");
> @@ -527,38 +528,18 @@ static int bmc150_accel_set_interrupt(struct bmc150_accel_data *data, int i,
>  		return ret;
>  
>  	/* map the interrupt to the appropriate pins */
> -	ret = i2c_smbus_read_byte_data(data->client, info->map_reg);
> -	if (ret < 0) {
> -		dev_err(&data->client->dev, "Error reading reg_int_map\n");
> -		goto out_fix_power_state;
> -	}
> -	if (state)
> -		ret |= info->map_bitmask;
> -	else
> -		ret &= ~info->map_bitmask;
> -
> -	ret = i2c_smbus_write_byte_data(data->client, info->map_reg,
> -					ret);
> +	ret = regmap_update_bits(data->regmap, info->map_reg, info->map_bitmask,
> +				 (state ? info->map_bitmask : 0));
>  	if (ret < 0) {
> -		dev_err(&data->client->dev, "Error writing reg_int_map\n");
> +		dev_err(&data->client->dev, "Error updating reg_int_map\n");
>  		goto out_fix_power_state;
>  	}
>  
>  	/* enable/disable the interrupt */
> -	ret = i2c_smbus_read_byte_data(data->client, info->en_reg);
> -	if (ret < 0) {
> -		dev_err(&data->client->dev, "Error reading reg_int_en\n");
> -		goto out_fix_power_state;
> -	}
> -
> -	if (state)
> -		ret |= info->en_bitmask;
> -	else
> -		ret &= ~info->en_bitmask;
> -
> -	ret = i2c_smbus_write_byte_data(data->client, info->en_reg, ret);
> +	ret = regmap_update_bits(data->regmap, info->en_reg, info->en_bitmask,
> +				 (state ? info->en_bitmask : 0));
>  	if (ret < 0) {
> -		dev_err(&data->client->dev, "Error writing reg_int_en\n");
> +		dev_err(&data->client->dev, "Error updating reg_int_en\n");
>  		goto out_fix_power_state;
>  	}
>  
> @@ -581,8 +562,7 @@ static int bmc150_accel_set_scale(struct bmc150_accel_data *data, int val)
>  
>  	for (i = 0; i < ARRAY_SIZE(data->chip_info->scale_table); ++i) {
>  		if (data->chip_info->scale_table[i].scale == val) {
> -			ret = i2c_smbus_write_byte_data(
> -				     data->client,
> +			ret = regmap_write(data->regmap,
>  				     BMC150_ACCEL_REG_PMU_RANGE,
>  				     data->chip_info->scale_table[i].reg_range);
>  			if (ret < 0) {
> @@ -602,16 +582,17 @@ static int bmc150_accel_set_scale(struct bmc150_accel_data *data, int val)
>  static int bmc150_accel_get_temp(struct bmc150_accel_data *data, int *val)
>  {
>  	int ret;
> +	unsigned int value;
>  
>  	mutex_lock(&data->mutex);
>  
> -	ret = i2c_smbus_read_byte_data(data->client, BMC150_ACCEL_REG_TEMP);
> +	ret = regmap_read(data->regmap, BMC150_ACCEL_REG_TEMP, &value);
>  	if (ret < 0) {
>  		dev_err(&data->client->dev, "Error reading reg_temp\n");
>  		mutex_unlock(&data->mutex);
>  		return ret;
>  	}
> -	*val = sign_extend32(ret, 7);
> +	*val = sign_extend32(value, 7);
>  
>  	mutex_unlock(&data->mutex);
>  
> @@ -624,6 +605,7 @@ static int bmc150_accel_get_axis(struct bmc150_accel_data *data,
>  {
>  	int ret;
>  	int axis = chan->scan_index;
> +	unsigned int raw_val;
>  
>  	mutex_lock(&data->mutex);
>  	ret = bmc150_accel_set_power_state(data, true);
> @@ -632,15 +614,15 @@ static int bmc150_accel_get_axis(struct bmc150_accel_data *data,
>  		return ret;
>  	}
>  
> -	ret = i2c_smbus_read_word_data(data->client,
> -				       BMC150_ACCEL_AXIS_TO_REG(axis));
> +	ret = regmap_bulk_read(data->regmap, BMC150_ACCEL_AXIS_TO_REG(axis),
> +			       &raw_val, 2);
>  	if (ret < 0) {
>  		dev_err(&data->client->dev, "Error reading axis %d\n", axis);
>  		bmc150_accel_set_power_state(data, false);
>  		mutex_unlock(&data->mutex);
>  		return ret;
>  	}
> -	*val = sign_extend32(ret >> chan->scan_type.shift,
> +	*val = sign_extend32(raw_val >> chan->scan_type.shift,
>  			     chan->scan_type.realbits - 1);
>  	ret = bmc150_accel_set_power_state(data, false);
>  	mutex_unlock(&data->mutex);
> @@ -904,52 +886,37 @@ static int bmc150_accel_set_watermark(struct iio_dev *indio_dev, unsigned val)
>   * We must read at least one full frame in one burst, otherwise the rest of the
>   * frame data is discarded.
>   */
> -static int bmc150_accel_fifo_transfer(const struct i2c_client *client,
> +static int bmc150_accel_fifo_transfer(struct bmc150_accel_data *data,
>  				      char *buffer, int samples)
>  {
>  	int sample_length = 3 * 2;
> -	u8 reg_fifo_data = BMC150_ACCEL_REG_FIFO_DATA;
> -	int ret = -EIO;
> -
> -	if (i2c_check_functionality(client->adapter, I2C_FUNC_I2C)) {
> -		struct i2c_msg msg[2] = {
> -			{
> -				.addr = client->addr,
> -				.flags = 0,
> -				.buf = &reg_fifo_data,
> -				.len = sizeof(reg_fifo_data),
> -			},
> -			{
> -				.addr = client->addr,
> -				.flags = I2C_M_RD,
> -				.buf = (u8 *)buffer,
> -				.len = samples * sample_length,
> -			}
> -		};
> +	int ret;
> +	int total_length = samples * sample_length;
> +	int i, step;
>  
> -		ret = i2c_transfer(client->adapter, msg, 2);
> -		if (ret != 2)
> -			ret = -EIO;
> -		else
> -			ret = 0;
> -	} else {
> -		int i, step = I2C_SMBUS_BLOCK_MAX / sample_length;
> -
> -		for (i = 0; i < samples * sample_length; i += step) {
> -			ret = i2c_smbus_read_i2c_block_data(client,
> -							    reg_fifo_data, step,
> -							    &buffer[i]);
> -			if (ret != step) {
> -				ret = -EIO;
> -				break;
> -			}
> +	ret = regmap_raw_read(data->regmap, BMC150_ACCEL_REG_FIFO_DATA, buffer,
> +			      total_length);
> +	if (ret != -E2BIG) {
> +		if (ret)
I'd invert the logic for more readability.

if (ret == -E2BIT) {
...
} else if (ret) {
...
} else {
   return ret;
}
> +			dev_err(data->dev, "Error transferring data from fifo\n");
> +		return ret;
> +	}
>  
> -			ret = 0;
> -		}
> +	/*
> +	 * Seems we have a bus with size limitation so we have to execute
> +	 * multiple reads
> +	 */
Can we not just query this in advance before going through the previous
failed call?  THat would be cleaner to my mind.

> +	step = regmap_get_raw_io_max(data->regmap) / sample_length;
> +	for (i = -1; i < samples * sample_length; i += step) {
> +		ret = regmap_raw_read(data->regmap, BMC150_ACCEL_REG_FIFO_DATA,
> +				      &buffer[i], step);
umm. Can't say I like the negative index into buffer.  Why is it
necessary?
> +		if (ret)
> +			break;
>  	}
>  
>  	if (ret)
> -		dev_err(&client->dev, "Error transferring data from fifo\n");
> +		dev_err(data->dev, "Error transferring data from fifo in single steps of %zu\n",

multiple steps of %zu perhaps?
> +			step);
>  
>  	return ret;
>  }
> @@ -963,14 +930,15 @@ static int __bmc150_accel_fifo_flush(struct iio_dev *indio_dev,
>  	u16 buffer[BMC150_ACCEL_FIFO_LENGTH * 3];
>  	int64_t tstamp;
>  	uint64_t sample_period;
> -	ret = i2c_smbus_read_byte_data(data->client,
> -				       BMC150_ACCEL_REG_FIFO_STATUS);
> +	unsigned int val;
> +
> +	ret = regmap_read(data->regmap, BMC150_ACCEL_REG_FIFO_STATUS, &val);
>  	if (ret < 0) {
>  		dev_err(&data->client->dev, "Error reading reg_fifo_status\n");
>  		return ret;
>  	}
>  
> -	count = ret & 0x7F;
> +	count = val & 0x7F;
>  
>  	if (!count)
>  		return 0;
> @@ -1009,7 +977,7 @@ static int __bmc150_accel_fifo_flush(struct iio_dev *indio_dev,
>  	if (samples && count > samples)
>  		count = samples;
>  
> -	ret = bmc150_accel_fifo_transfer(data->client, (u8 *)buffer, count);
> +	ret = bmc150_accel_fifo_transfer(data, (u8 *)buffer, count);
>  	if (ret)
>  		return ret;
>  
> @@ -1206,17 +1174,19 @@ static irqreturn_t bmc150_accel_trigger_handler(int irq, void *p)
>  	struct iio_dev *indio_dev = pf->indio_dev;
>  	struct bmc150_accel_data *data = iio_priv(indio_dev);
>  	int bit, ret, i = 0;
> +	unsigned int raw_val;
>  
>  	mutex_lock(&data->mutex);
>  	for_each_set_bit(bit, indio_dev->active_scan_mask,
>  			 indio_dev->masklength) {
> -		ret = i2c_smbus_read_word_data(data->client,
> -					       BMC150_ACCEL_AXIS_TO_REG(bit));
> +		ret = regmap_bulk_read(data->regmap,
> +				       BMC150_ACCEL_AXIS_TO_REG(bit), &raw_val,
> +				       2);
Is using a variable on the stack not going to cause issues when we add
SPI?  (cacheline dma requirements).
>  		if (ret < 0) {
>  			mutex_unlock(&data->mutex);
>  			goto err_read;
>  		}
> -		data->buffer[i++] = ret;
> +		data->buffer[i++] = raw_val;
>  	}
>  	mutex_unlock(&data->mutex);
>  
> @@ -1240,10 +1210,9 @@ static int bmc150_accel_trig_try_reen(struct iio_trigger *trig)
>  
>  	mutex_lock(&data->mutex);
>  	/* clear any latched interrupt */
> -	ret = i2c_smbus_write_byte_data(data->client,
> -					BMC150_ACCEL_REG_INT_RST_LATCH,
> -					BMC150_ACCEL_INT_MODE_LATCH_INT |
> -					BMC150_ACCEL_INT_MODE_LATCH_RESET);
> +	ret = regmap_write(data->regmap, BMC150_ACCEL_REG_INT_RST_LATCH,
> +			   BMC150_ACCEL_INT_MODE_LATCH_INT |
> +			   BMC150_ACCEL_INT_MODE_LATCH_RESET);
>  	mutex_unlock(&data->mutex);
>  	if (ret < 0) {
>  		dev_err(&data->client->dev,
> @@ -1300,34 +1269,34 @@ static int bmc150_accel_handle_roc_event(struct iio_dev *indio_dev)
>  	struct bmc150_accel_data *data = iio_priv(indio_dev);
>  	int dir;
>  	int ret;
> +	unsigned int val;
>  
> -	ret = i2c_smbus_read_byte_data(data->client,
> -				       BMC150_ACCEL_REG_INT_STATUS_2);
> +	ret = regmap_read(data->regmap, BMC150_ACCEL_REG_INT_STATUS_2, &val);
>  	if (ret < 0) {
>  		dev_err(&data->client->dev, "Error reading reg_int_status_2\n");
>  		return ret;
>  	}
>  
> -	if (ret & BMC150_ACCEL_ANY_MOTION_BIT_SIGN)
> +	if (val & BMC150_ACCEL_ANY_MOTION_BIT_SIGN)
>  		dir = IIO_EV_DIR_FALLING;
>  	else
>  		dir = IIO_EV_DIR_RISING;
>  
> -	if (ret & BMC150_ACCEL_ANY_MOTION_BIT_X)
> +	if (val & BMC150_ACCEL_ANY_MOTION_BIT_X)
>  		iio_push_event(indio_dev, IIO_MOD_EVENT_CODE(IIO_ACCEL,
>  							0,
>  							IIO_MOD_X,
>  							IIO_EV_TYPE_ROC,
>  							dir),
>  							data->timestamp);
> -	if (ret & BMC150_ACCEL_ANY_MOTION_BIT_Y)
> +	if (val & BMC150_ACCEL_ANY_MOTION_BIT_Y)
>  		iio_push_event(indio_dev, IIO_MOD_EVENT_CODE(IIO_ACCEL,
>  							0,
>  							IIO_MOD_Y,
>  							IIO_EV_TYPE_ROC,
>  							dir),
>  							data->timestamp);
> -	if (ret & BMC150_ACCEL_ANY_MOTION_BIT_Z)
> +	if (val & BMC150_ACCEL_ANY_MOTION_BIT_Z)
>  		iio_push_event(indio_dev, IIO_MOD_EVENT_CODE(IIO_ACCEL,
>  							0,
>  							IIO_MOD_Z,
> @@ -1360,10 +1329,9 @@ static irqreturn_t bmc150_accel_irq_thread_handler(int irq, void *private)
>  	}
>  
>  	if (ack) {
> -		ret = i2c_smbus_write_byte_data(data->client,
> -					BMC150_ACCEL_REG_INT_RST_LATCH,
> -					BMC150_ACCEL_INT_MODE_LATCH_INT |
> -					BMC150_ACCEL_INT_MODE_LATCH_RESET);
> +		ret = regmap_write(data->regmap, BMC150_ACCEL_REG_INT_RST_LATCH,
> +				   BMC150_ACCEL_INT_MODE_LATCH_INT |
> +				   BMC150_ACCEL_INT_MODE_LATCH_RESET);
>  		if (ret)
>  			dev_err(&data->client->dev, "Error writing reg_int_rst_latch\n");
>  		ret = IRQ_HANDLED;
> @@ -1516,7 +1484,7 @@ static int bmc150_accel_fifo_set_mode(struct bmc150_accel_data *data)
>  	u8 reg = BMC150_ACCEL_REG_FIFO_CONFIG1;
>  	int ret;
>  
> -	ret = i2c_smbus_write_byte_data(data->client, reg, data->fifo_mode);
> +	ret = regmap_write(data->regmap, reg, data->fifo_mode);
>  	if (ret < 0) {
>  		dev_err(&data->client->dev, "Error writing reg_fifo_config1\n");
>  		return ret;
> @@ -1525,9 +1493,8 @@ static int bmc150_accel_fifo_set_mode(struct bmc150_accel_data *data)
>  	if (!data->fifo_mode)
>  		return 0;
>  
> -	ret = i2c_smbus_write_byte_data(data->client,
> -					BMC150_ACCEL_REG_FIFO_CONFIG0,
> -					data->watermark);
> +	ret = regmap_write(data->regmap, BMC150_ACCEL_REG_FIFO_CONFIG0,
> +			   data->watermark);
>  	if (ret < 0)
>  		dev_err(&data->client->dev, "Error writing reg_fifo_config0\n");
>  
> @@ -1627,6 +1594,13 @@ static int bmc150_accel_probe(struct i2c_client *client,
>  	data = iio_priv(indio_dev);
>  	i2c_set_clientdata(client, indio_dev);
>  	data->client = client;
> +	data->dev = &client->dev;
> +
> +	data->regmap = devm_regmap_init_i2c(client, &bmc150_i2c_regmap_conf);
> +	if (IS_ERR(data->regmap)) {
> +		dev_err(&client->dev, "Failed to initialize i2c regmap\n");
> +		return PTR_ERR(data->regmap);
> +	}
>  
>  	if (id) {
>  		name = id->name;
> @@ -1680,9 +1654,8 @@ static int bmc150_accel_probe(struct i2c_client *client,
>  		 * want to use latch mode when we can to prevent interrupt
>  		 * flooding.
>  		 */
> -		ret = i2c_smbus_write_byte_data(data->client,
> -						BMC150_ACCEL_REG_INT_RST_LATCH,
> -					     BMC150_ACCEL_INT_MODE_LATCH_RESET);
> +		ret = regmap_write(data->regmap, BMC150_ACCEL_REG_INT_RST_LATCH,
> +				   BMC150_ACCEL_INT_MODE_LATCH_RESET);
>  		if (ret < 0) {
>  			dev_err(&data->client->dev, "Error writing reg_int_rst_latch\n");
>  			goto err_buffer_cleanup;
> 



From jic23 at kernel.org  Sat Aug 15 06:33:51 2015
From: jic23 at kernel.org (Jonathan Cameron)
Date: Sat, 15 Aug 2015 14:33:51 +0100
Subject: [PATCH 18/20] iio: bcm150: Remove i2c_client from private data
In-Reply-To: <1439374365-20623-19-git-send-email-mpa@pengutronix.de>
References: <1439374365-20623-1-git-send-email-mpa@pengutronix.de>
 <1439374365-20623-19-git-send-email-mpa@pengutronix.de>
Message-ID: <55CF3FBF.1030707@kernel.org>

On 12/08/15 11:12, Markus Pargmann wrote:
> i2c_client struct is now only used for debugging output. We can use the
> device struct as well so we can remove all struct i2c_client usage.
> 
> Signed-off-by: Markus Pargmann <mpa at pengutronix.de>
This one looks fine to me.

Acked-by: Jonathan Cameron <jic23 at kernel.org>

Ideally these bmc150 patches should also get a look from Srinivas
before merging however (and testing given I'm guessing you don't have
all the parts!)

Jonathan
> ---
>  drivers/iio/accel/bmc150-accel.c | 120 +++++++++++++++++++--------------------
>  1 file changed, 58 insertions(+), 62 deletions(-)
> 
> diff --git a/drivers/iio/accel/bmc150-accel.c b/drivers/iio/accel/bmc150-accel.c
> index 1484e956482e..d75e1b0aa7e9 100644
> --- a/drivers/iio/accel/bmc150-accel.c
> +++ b/drivers/iio/accel/bmc150-accel.c
> @@ -185,9 +185,9 @@ enum bmc150_accel_trigger_id {
>  };
>  
>  struct bmc150_accel_data {
> -	struct i2c_client *client;
>  	struct regmap *regmap;
>  	struct device *dev;
> +	int irq;
>  	struct bmc150_accel_interrupt interrupts[BMC150_ACCEL_INTERRUPTS];
>  	atomic_t active_intr;
>  	struct bmc150_accel_trigger triggers[BMC150_ACCEL_TRIGGERS];
> @@ -279,11 +279,11 @@ static int bmc150_accel_set_mode(struct bmc150_accel_data *data,
>  	lpw_bits = mode << BMC150_ACCEL_PMU_MODE_SHIFT;
>  	lpw_bits |= (dur_val << BMC150_ACCEL_PMU_BIT_SLEEP_DUR_SHIFT);
>  
> -	dev_dbg(&data->client->dev, "Set Mode bits %x\n", lpw_bits);
> +	dev_dbg(data->dev, "Set Mode bits %x\n", lpw_bits);
>  
>  	ret = regmap_write(data->regmap, BMC150_ACCEL_REG_PMU_LPW, lpw_bits);
>  	if (ret < 0) {
> -		dev_err(&data->client->dev, "Error writing reg_pmu_lpw\n");
> +		dev_err(data->dev, "Error writing reg_pmu_lpw\n");
>  		return ret;
>  	}
>  
> @@ -321,18 +321,18 @@ static int bmc150_accel_update_slope(struct bmc150_accel_data *data)
>  	ret = regmap_write(data->regmap, BMC150_ACCEL_REG_INT_6,
>  					data->slope_thres);
>  	if (ret < 0) {
> -		dev_err(&data->client->dev, "Error writing reg_int_6\n");
> +		dev_err(data->dev, "Error writing reg_int_6\n");
>  		return ret;
>  	}
>  
>  	ret = regmap_update_bits(data->regmap, BMC150_ACCEL_REG_INT_5,
>  				 BMC150_ACCEL_SLOPE_DUR_MASK, data->slope_dur);
>  	if (ret < 0) {
> -		dev_err(&data->client->dev, "Error updating reg_int_5\n");
> +		dev_err(data->dev, "Error updating reg_int_5\n");
>  		return ret;
>  	}
>  
> -	dev_dbg(&data->client->dev, "%s: %x %x\n", __func__, data->slope_thres,
> +	dev_dbg(data->dev, "%s: %x %x\n", __func__, data->slope_thres,
>  		data->slope_dur);
>  
>  	return ret;
> @@ -354,14 +354,14 @@ static int bmc150_accel_chip_init(struct bmc150_accel_data *data)
>  
>  	ret = regmap_read(data->regmap, BMC150_ACCEL_REG_CHIP_ID, &val);
>  	if (ret < 0) {
> -		dev_err(&data->client->dev,
> +		dev_err(data->dev,
>  			"Error: Reading chip id\n");
>  		return ret;
>  	}
>  
> -	dev_dbg(&data->client->dev, "Chip Id %x\n", val);
> +	dev_dbg(data->dev, "Chip Id %x\n", val);
>  	if (val != data->chip_info->chip_id) {
> -		dev_err(&data->client->dev, "Invalid chip %x\n", val);
> +		dev_err(data->dev, "Invalid chip %x\n", val);
>  		return -ENODEV;
>  	}
>  
> @@ -378,8 +378,7 @@ static int bmc150_accel_chip_init(struct bmc150_accel_data *data)
>  	ret = regmap_write(data->regmap, BMC150_ACCEL_REG_PMU_RANGE,
>  			   BMC150_ACCEL_DEF_RANGE_4G);
>  	if (ret < 0) {
> -		dev_err(&data->client->dev,
> -					"Error writing reg_pmu_range\n");
> +		dev_err(data->dev, "Error writing reg_pmu_range\n");
>  		return ret;
>  	}
>  
> @@ -397,7 +396,7 @@ static int bmc150_accel_chip_init(struct bmc150_accel_data *data)
>  			   BMC150_ACCEL_INT_MODE_LATCH_INT |
>  			   BMC150_ACCEL_INT_MODE_LATCH_RESET);
>  	if (ret < 0) {
> -		dev_err(&data->client->dev,
> +		dev_err(data->dev,
>  			"Error writing reg_int_rst_latch\n");
>  		return ret;
>  	}
> @@ -439,16 +438,16 @@ static int bmc150_accel_set_power_state(struct bmc150_accel_data *data, bool on)
>  	int ret;
>  
>  	if (on)
> -		ret = pm_runtime_get_sync(&data->client->dev);
> +		ret = pm_runtime_get_sync(data->dev);
>  	else {
> -		pm_runtime_mark_last_busy(&data->client->dev);
> -		ret = pm_runtime_put_autosuspend(&data->client->dev);
> +		pm_runtime_mark_last_busy(data->dev);
> +		ret = pm_runtime_put_autosuspend(data->dev);
>  	}
>  	if (ret < 0) {
> -		dev_err(&data->client->dev,
> +		dev_err(data->dev,
>  			"Failed: bmc150_accel_set_power_state for %d\n", on);
>  		if (on)
> -			pm_runtime_put_noidle(&data->client->dev);
> +			pm_runtime_put_noidle(data->dev);
>  
>  		return ret;
>  	}
> @@ -531,7 +530,7 @@ static int bmc150_accel_set_interrupt(struct bmc150_accel_data *data, int i,
>  	ret = regmap_update_bits(data->regmap, info->map_reg, info->map_bitmask,
>  				 (state ? info->map_bitmask : 0));
>  	if (ret < 0) {
> -		dev_err(&data->client->dev, "Error updating reg_int_map\n");
> +		dev_err(data->dev, "Error updating reg_int_map\n");
>  		goto out_fix_power_state;
>  	}
>  
> @@ -539,7 +538,7 @@ static int bmc150_accel_set_interrupt(struct bmc150_accel_data *data, int i,
>  	ret = regmap_update_bits(data->regmap, info->en_reg, info->en_bitmask,
>  				 (state ? info->en_bitmask : 0));
>  	if (ret < 0) {
> -		dev_err(&data->client->dev, "Error updating reg_int_en\n");
> +		dev_err(data->dev, "Error updating reg_int_en\n");
>  		goto out_fix_power_state;
>  	}
>  
> @@ -566,7 +565,7 @@ static int bmc150_accel_set_scale(struct bmc150_accel_data *data, int val)
>  				     BMC150_ACCEL_REG_PMU_RANGE,
>  				     data->chip_info->scale_table[i].reg_range);
>  			if (ret < 0) {
> -				dev_err(&data->client->dev,
> +				dev_err(data->dev,
>  					"Error writing pmu_range\n");
>  				return ret;
>  			}
> @@ -588,7 +587,7 @@ static int bmc150_accel_get_temp(struct bmc150_accel_data *data, int *val)
>  
>  	ret = regmap_read(data->regmap, BMC150_ACCEL_REG_TEMP, &value);
>  	if (ret < 0) {
> -		dev_err(&data->client->dev, "Error reading reg_temp\n");
> +		dev_err(data->dev, "Error reading reg_temp\n");
>  		mutex_unlock(&data->mutex);
>  		return ret;
>  	}
> @@ -617,7 +616,7 @@ static int bmc150_accel_get_axis(struct bmc150_accel_data *data,
>  	ret = regmap_bulk_read(data->regmap, BMC150_ACCEL_AXIS_TO_REG(axis),
>  			       &raw_val, 2);
>  	if (ret < 0) {
> -		dev_err(&data->client->dev, "Error reading axis %d\n", axis);
> +		dev_err(data->dev, "Error reading axis %d\n", axis);
>  		bmc150_accel_set_power_state(data, false);
>  		mutex_unlock(&data->mutex);
>  		return ret;
> @@ -934,7 +933,7 @@ static int __bmc150_accel_fifo_flush(struct iio_dev *indio_dev,
>  
>  	ret = regmap_read(data->regmap, BMC150_ACCEL_REG_FIFO_STATUS, &val);
>  	if (ret < 0) {
> -		dev_err(&data->client->dev, "Error reading reg_fifo_status\n");
> +		dev_err(data->dev, "Error reading reg_fifo_status\n");
>  		return ret;
>  	}
>  
> @@ -1215,7 +1214,7 @@ static int bmc150_accel_trig_try_reen(struct iio_trigger *trig)
>  			   BMC150_ACCEL_INT_MODE_LATCH_RESET);
>  	mutex_unlock(&data->mutex);
>  	if (ret < 0) {
> -		dev_err(&data->client->dev,
> +		dev_err(data->dev,
>  			"Error writing reg_int_rst_latch\n");
>  		return ret;
>  	}
> @@ -1273,7 +1272,7 @@ static int bmc150_accel_handle_roc_event(struct iio_dev *indio_dev)
>  
>  	ret = regmap_read(data->regmap, BMC150_ACCEL_REG_INT_STATUS_2, &val);
>  	if (ret < 0) {
> -		dev_err(&data->client->dev, "Error reading reg_int_status_2\n");
> +		dev_err(data->dev, "Error reading reg_int_status_2\n");
>  		return ret;
>  	}
>  
> @@ -1333,7 +1332,7 @@ static irqreturn_t bmc150_accel_irq_thread_handler(int irq, void *private)
>  				   BMC150_ACCEL_INT_MODE_LATCH_INT |
>  				   BMC150_ACCEL_INT_MODE_LATCH_RESET);
>  		if (ret)
> -			dev_err(&data->client->dev, "Error writing reg_int_rst_latch\n");
> +			dev_err(data->dev, "Error writing reg_int_rst_latch\n");
>  		ret = IRQ_HANDLED;
>  	} else {
>  		ret = IRQ_NONE;
> @@ -1385,17 +1384,13 @@ static const char *bmc150_accel_match_acpi_device(struct device *dev, int *data)
>  	return dev_name(dev);
>  }
>  
> -static int bmc150_accel_gpio_probe(struct i2c_client *client,
> -					struct bmc150_accel_data *data)
> +static int bmc150_accel_gpio_probe(struct bmc150_accel_data *data)
>  {
>  	struct device *dev;
>  	struct gpio_desc *gpio;
>  	int ret;
>  
> -	if (!client)
> -		return -EINVAL;
> -
> -	dev = &client->dev;
> +	dev = data->dev;
>  
>  	/* data ready gpio interrupt pin */
>  	gpio = devm_gpiod_get_index(dev, BMC150_ACCEL_GPIO_NAME, 0, GPIOD_IN);
> @@ -1448,7 +1443,7 @@ static int bmc150_accel_triggers_setup(struct iio_dev *indio_dev,
>  	for (i = 0; i < BMC150_ACCEL_TRIGGERS; i++) {
>  		struct bmc150_accel_trigger *t = &data->triggers[i];
>  
> -		t->indio_trig = devm_iio_trigger_alloc(&data->client->dev,
> +		t->indio_trig = devm_iio_trigger_alloc(data->dev,
>  					       bmc150_accel_triggers[i].name,
>  						       indio_dev->name,
>  						       indio_dev->id);
> @@ -1457,7 +1452,7 @@ static int bmc150_accel_triggers_setup(struct iio_dev *indio_dev,
>  			break;
>  		}
>  
> -		t->indio_trig->dev.parent = &data->client->dev;
> +		t->indio_trig->dev.parent = data->dev;
>  		t->indio_trig->ops = &bmc150_accel_trigger_ops;
>  		t->intr = bmc150_accel_triggers[i].intr;
>  		t->data = data;
> @@ -1486,7 +1481,7 @@ static int bmc150_accel_fifo_set_mode(struct bmc150_accel_data *data)
>  
>  	ret = regmap_write(data->regmap, reg, data->fifo_mode);
>  	if (ret < 0) {
> -		dev_err(&data->client->dev, "Error writing reg_fifo_config1\n");
> +		dev_err(data->dev, "Error writing reg_fifo_config1\n");
>  		return ret;
>  	}
>  
> @@ -1496,7 +1491,7 @@ static int bmc150_accel_fifo_set_mode(struct bmc150_accel_data *data)
>  	ret = regmap_write(data->regmap, BMC150_ACCEL_REG_FIFO_CONFIG0,
>  			   data->watermark);
>  	if (ret < 0)
> -		dev_err(&data->client->dev, "Error writing reg_fifo_config0\n");
> +		dev_err(data->dev, "Error writing reg_fifo_config0\n");
>  
>  	return ret;
>  }
> @@ -1586,6 +1581,7 @@ static int bmc150_accel_probe(struct i2c_client *client,
>  	int ret;
>  	const char *name = NULL;
>  	int chip_id = 0;
> +	struct device *dev;
>  
>  	indio_dev = devm_iio_device_alloc(&client->dev, sizeof(*data));
>  	if (!indio_dev)
> @@ -1593,12 +1589,13 @@ static int bmc150_accel_probe(struct i2c_client *client,
>  
>  	data = iio_priv(indio_dev);
>  	i2c_set_clientdata(client, indio_dev);
> -	data->client = client;
>  	data->dev = &client->dev;
> +	dev = &client->dev;
> +	data->irq = client->irq;
>  
>  	data->regmap = devm_regmap_init_i2c(client, &bmc150_i2c_regmap_conf);
>  	if (IS_ERR(data->regmap)) {
> -		dev_err(&client->dev, "Failed to initialize i2c regmap\n");
> +		dev_err(dev, "Failed to initialize i2c regmap\n");
>  		return PTR_ERR(data->regmap);
>  	}
>  
> @@ -1607,8 +1604,8 @@ static int bmc150_accel_probe(struct i2c_client *client,
>  		chip_id = id->driver_data;
>  	}
>  
> -	if (ACPI_HANDLE(&client->dev))
> -		name = bmc150_accel_match_acpi_device(&client->dev, &chip_id);
> +	if (ACPI_HANDLE(dev))
> +		name = bmc150_accel_match_acpi_device(dev, &chip_id);
>  
>  	data->chip_info = &bmc150_accel_chip_info_tbl[chip_id];
>  
> @@ -1618,7 +1615,7 @@ static int bmc150_accel_probe(struct i2c_client *client,
>  
>  	mutex_init(&data->mutex);
>  
> -	indio_dev->dev.parent = &client->dev;
> +	indio_dev->dev.parent = dev;
>  	indio_dev->channels = data->chip_info->channels;
>  	indio_dev->num_channels = data->chip_info->num_channels;
>  	indio_dev->name = name;
> @@ -1630,16 +1627,16 @@ static int bmc150_accel_probe(struct i2c_client *client,
>  					 bmc150_accel_trigger_handler,
>  					 &bmc150_accel_buffer_ops);
>  	if (ret < 0) {
> -		dev_err(&client->dev, "Failed: iio triggered buffer setup\n");
> +		dev_err(data->dev, "Failed: iio triggered buffer setup\n");
>  		return ret;
>  	}
>  
> -	if (client->irq <= 0)
> -		client->irq = bmc150_accel_gpio_probe(client, data);
> +	if (data->irq <= 0)
> +		data->irq = bmc150_accel_gpio_probe(data);
>  
> -	if (client->irq > 0) {
> +	if (data->irq > 0) {
>  		ret = devm_request_threaded_irq(
> -						&client->dev, client->irq,
> +						data->dev, data->irq,
>  						bmc150_accel_irq_handler,
>  						bmc150_accel_irq_thread_handler,
>  						IRQF_TRIGGER_RISING,
> @@ -1657,7 +1654,7 @@ static int bmc150_accel_probe(struct i2c_client *client,
>  		ret = regmap_write(data->regmap, BMC150_ACCEL_REG_INT_RST_LATCH,
>  				   BMC150_ACCEL_INT_MODE_LATCH_RESET);
>  		if (ret < 0) {
> -			dev_err(&data->client->dev, "Error writing reg_int_rst_latch\n");
> +			dev_err(data->dev, "Error writing reg_int_rst_latch\n");
>  			goto err_buffer_cleanup;
>  		}
>  
> @@ -1678,18 +1675,17 @@ static int bmc150_accel_probe(struct i2c_client *client,
>  
>  	ret = iio_device_register(indio_dev);
>  	if (ret < 0) {
> -		dev_err(&client->dev, "Unable to register iio device\n");
> +		dev_err(data->dev, "Unable to register iio device\n");
>  		goto err_trigger_unregister;
>  	}
>  
> -	ret = pm_runtime_set_active(&client->dev);
> +	ret = pm_runtime_set_active(dev);
>  	if (ret)
>  		goto err_iio_unregister;
>  
> -	pm_runtime_enable(&client->dev);
> -	pm_runtime_set_autosuspend_delay(&client->dev,
> -					 BMC150_AUTO_SUSPEND_DELAY_MS);
> -	pm_runtime_use_autosuspend(&client->dev);
> +	pm_runtime_enable(dev);
> +	pm_runtime_set_autosuspend_delay(dev, BMC150_AUTO_SUSPEND_DELAY_MS);
> +	pm_runtime_use_autosuspend(dev);
>  
>  	return 0;
>  
> @@ -1708,9 +1704,9 @@ static int bmc150_accel_remove(struct i2c_client *client)
>  	struct iio_dev *indio_dev = i2c_get_clientdata(client);
>  	struct bmc150_accel_data *data = iio_priv(indio_dev);
>  
> -	pm_runtime_disable(&client->dev);
> -	pm_runtime_set_suspended(&client->dev);
> -	pm_runtime_put_noidle(&client->dev);
> +	pm_runtime_disable(data->dev);
> +	pm_runtime_set_suspended(data->dev);
> +	pm_runtime_put_noidle(data->dev);
>  
>  	iio_device_unregister(indio_dev);
>  
> @@ -1728,7 +1724,7 @@ static int bmc150_accel_remove(struct i2c_client *client)
>  #ifdef CONFIG_PM_SLEEP
>  static int bmc150_accel_suspend(struct device *dev)
>  {
> -	struct iio_dev *indio_dev = i2c_get_clientdata(to_i2c_client(dev));
> +	struct iio_dev *indio_dev = dev_get_drvdata(dev);
>  	struct bmc150_accel_data *data = iio_priv(indio_dev);
>  
>  	mutex_lock(&data->mutex);
> @@ -1740,7 +1736,7 @@ static int bmc150_accel_suspend(struct device *dev)
>  
>  static int bmc150_accel_resume(struct device *dev)
>  {
> -	struct iio_dev *indio_dev = i2c_get_clientdata(to_i2c_client(dev));
> +	struct iio_dev *indio_dev = dev_get_drvdata(dev);
>  	struct bmc150_accel_data *data = iio_priv(indio_dev);
>  
>  	mutex_lock(&data->mutex);
> @@ -1756,11 +1752,11 @@ static int bmc150_accel_resume(struct device *dev)
>  #ifdef CONFIG_PM
>  static int bmc150_accel_runtime_suspend(struct device *dev)
>  {
> -	struct iio_dev *indio_dev = i2c_get_clientdata(to_i2c_client(dev));
> +	struct iio_dev *indio_dev = dev_get_drvdata(dev);
>  	struct bmc150_accel_data *data = iio_priv(indio_dev);
>  	int ret;
>  
> -	dev_dbg(&data->client->dev,  __func__);
> +	dev_dbg(data->dev,  __func__);
>  	ret = bmc150_accel_set_mode(data, BMC150_ACCEL_SLEEP_MODE_SUSPEND, 0);
>  	if (ret < 0)
>  		return -EAGAIN;
> @@ -1770,12 +1766,12 @@ static int bmc150_accel_runtime_suspend(struct device *dev)
>  
>  static int bmc150_accel_runtime_resume(struct device *dev)
>  {
> -	struct iio_dev *indio_dev = i2c_get_clientdata(to_i2c_client(dev));
> +	struct iio_dev *indio_dev = dev_get_drvdata(dev);
>  	struct bmc150_accel_data *data = iio_priv(indio_dev);
>  	int ret;
>  	int sleep_val;
>  
> -	dev_dbg(&data->client->dev,  __func__);
> +	dev_dbg(data->dev,  __func__);
>  
>  	ret = bmc150_accel_set_mode(data, BMC150_ACCEL_SLEEP_MODE_NORMAL, 0);
>  	if (ret < 0)
> 



From jic23 at kernel.org  Sat Aug 15 06:41:29 2015
From: jic23 at kernel.org (Jonathan Cameron)
Date: Sat, 15 Aug 2015 14:41:29 +0100
Subject: [PATCH 19/20] iio: bmc150: Split the driver into core and i2c
In-Reply-To: <1439374365-20623-20-git-send-email-mpa@pengutronix.de>
References: <1439374365-20623-1-git-send-email-mpa@pengutronix.de>
 <1439374365-20623-20-git-send-email-mpa@pengutronix.de>
Message-ID: <55CF4189.6050402@kernel.org>

On 12/08/15 11:12, Markus Pargmann wrote:
> Signed-off-by: Markus Pargmann <mpa at pengutronix.de>
There are a few bits in here following through from earlier
patches that I haven't bothered mentioning as you'll have fixed
them already before this split patch).

Two more bits inline.  Nothing major though.

Jonathan
> ---
>  drivers/iio/accel/Kconfig                          |  22 +++--
>  drivers/iio/accel/Makefile                         |   3 +-
>  .../accel/{bmc150-accel.c => bmc150-accel-core.c}  |  95 ++++---------------
>  drivers/iio/accel/bmc150-accel-i2c.c               | 101 +++++++++++++++++++++
>  drivers/iio/accel/bmc150-accel.h                   |  21 +++++
>  5 files changed, 156 insertions(+), 86 deletions(-)
>  rename drivers/iio/accel/{bmc150-accel.c => bmc150-accel-core.c} (95%)
>  create mode 100644 drivers/iio/accel/bmc150-accel-i2c.c
>  create mode 100644 drivers/iio/accel/bmc150-accel.h
> 
> diff --git a/drivers/iio/accel/Kconfig b/drivers/iio/accel/Kconfig
> index 01dd03d194d1..c63e981c38ff 100644
> --- a/drivers/iio/accel/Kconfig
> +++ b/drivers/iio/accel/Kconfig
> @@ -18,22 +18,30 @@ config BMA180
>  	  module will be called bma180.
>  
>  config BMC150_ACCEL
> -	tristate "Bosch BMC150 Accelerometer Driver"
> -	depends on I2C
> -	select IIO_BUFFER
> -	select IIO_TRIGGERED_BUFFER
> +	bool "Bosch BMC150 Accelerometer Driver"
>  	select REGMAP
> -	select REGMAP_I2C
>  	help
>  	  Say yes here to build support for the following Bosch accelerometers:
>  	  BMC150, BMI055, BMA250E, BMA222E, BMA255, BMA280.
>  
> -	  Currently this only supports the device via an i2c interface.
> -
>  	  This is a combo module with both accelerometer and magnetometer.
>  	  This driver is only implementing accelerometer part, which has
>  	  its own address and register map.
This approach does lead to a proliferation of complexity (to the
person configuring the kernel build).  I prefer the approach the
ST accel driver for example takes, in which the SPI or I2C drivers
are built depending on whether the relevant dependencies are present
and the core driver is selected.
>  
> +if BMC150_ACCEL
> +
> +config BMC150_ACCEL_I2C
> +	tristate "I2C support"
> +	depends on I2C
> +	select IIO_BUFFER
> +	select IIO_TRIGGERED_BUFFER
> +	select REGMAP_I2C
> +	help
> +	  Say yes here to build support for I2C communication with the
> +	  mentioned accelerometer.
> +
> +endif
> +
>  config HID_SENSOR_ACCEL_3D
>  	depends on HID_SENSOR_HUB
>  	select IIO_BUFFER
> diff --git a/drivers/iio/accel/Makefile b/drivers/iio/accel/Makefile
> index ebd2675b2a02..5ef8bdbad092 100644
> --- a/drivers/iio/accel/Makefile
> +++ b/drivers/iio/accel/Makefile
> @@ -4,7 +4,8 @@
>  
>  # When adding new entries keep the list in alphabetical order
>  obj-$(CONFIG_BMA180) += bma180.o
> -obj-$(CONFIG_BMC150_ACCEL) += bmc150-accel.o
> +obj-$(CONFIG_BMC150_ACCEL) += bmc150-accel-core.o
> +obj-$(CONFIG_BMC150_ACCEL_I2C) += bmc150-accel-i2c.o
>  obj-$(CONFIG_HID_SENSOR_ACCEL_3D) += hid-sensor-accel-3d.o
>  obj-$(CONFIG_KXCJK1013) += kxcjk-1013.o
>  obj-$(CONFIG_KXSD9)	+= kxsd9.o
> diff --git a/drivers/iio/accel/bmc150-accel.c b/drivers/iio/accel/bmc150-accel-core.c
> similarity index 95%
> rename from drivers/iio/accel/bmc150-accel.c
> rename to drivers/iio/accel/bmc150-accel-core.c
> index d75e1b0aa7e9..8cf2786dd433 100644
> --- a/drivers/iio/accel/bmc150-accel.c
> +++ b/drivers/iio/accel/bmc150-accel-core.c
> @@ -37,6 +37,8 @@
>  #include <linux/iio/triggered_buffer.h>
>  #include <linux/regmap.h>
>  
> +#include "bmc150-accel.h"
> +
>  #define BMC150_ACCEL_DRV_NAME			"bmc150_accel"
>  #define BMC150_ACCEL_IRQ_NAME			"bmc150_accel_event"
>  #define BMC150_ACCEL_GPIO_NAME			"bmc150_accel_int"
> @@ -187,7 +189,6 @@ enum bmc150_accel_trigger_id {
>  struct bmc150_accel_data {
>  	struct regmap *regmap;
>  	struct device *dev;
At least from how diff is listing it, looks like you've just
moved this down the struct?  Why?
> -	int irq;
>  	struct bmc150_accel_interrupt interrupts[BMC150_ACCEL_INTERRUPTS];
>  	atomic_t active_intr;
>  	struct bmc150_accel_trigger triggers[BMC150_ACCEL_TRIGGERS];
> @@ -201,6 +202,7 @@ struct bmc150_accel_data {
>  	int ev_enable_state;
>  	int64_t timestamp, old_timestamp; /* Only used in hw fifo mode. */
>  	const struct bmc150_accel_chip_info *chip_info;
> +	int irq;
>  };
>  
>  static const struct {
> @@ -1076,15 +1078,6 @@ static const struct iio_chan_spec bmc150_accel_channels[] =
>  static const struct iio_chan_spec bma280_accel_channels[] =
>  	BMC150_ACCEL_CHANNELS(14);
>  
> -enum {
> -	bmc150,
> -	bmi055,
> -	bma255,
> -	bma250e,
> -	bma222e,
> -	bma280,
> -};
> -
>  static const struct bmc150_accel_chip_info bmc150_accel_chip_info_tbl[] = {
>  	[bmc150] = {
>  		.chip_id = 0xFA,
> @@ -1573,36 +1566,22 @@ static const struct iio_buffer_setup_ops bmc150_accel_buffer_ops = {
>  	.postdisable = bmc150_accel_buffer_postdisable,
>  };
>  
> -static int bmc150_accel_probe(struct i2c_client *client,
> -			      const struct i2c_device_id *id)
> +int bmc150_accel_core_probe(struct device *dev, struct regmap *regmap, int irq,
> +			    const char *name, int chip_id, bool block_supported)
>  {
>  	struct bmc150_accel_data *data;
>  	struct iio_dev *indio_dev;
>  	int ret;
> -	const char *name = NULL;
> -	int chip_id = 0;
> -	struct device *dev;
>  
> -	indio_dev = devm_iio_device_alloc(&client->dev, sizeof(*data));
> +	indio_dev = devm_iio_device_alloc(dev, sizeof(*data));
>  	if (!indio_dev)
>  		return -ENOMEM;
>  
>  	data = iio_priv(indio_dev);
> -	i2c_set_clientdata(client, indio_dev);
> -	data->dev = &client->dev;
> -	dev = &client->dev;
> -	data->irq = client->irq;
> -
> -	data->regmap = devm_regmap_init_i2c(client, &bmc150_i2c_regmap_conf);
> -	if (IS_ERR(data->regmap)) {
> -		dev_err(dev, "Failed to initialize i2c regmap\n");
> -		return PTR_ERR(data->regmap);
> -	}
> -
> -	if (id) {
> -		name = id->name;
> -		chip_id = id->driver_data;
> -	}
> +	dev_set_drvdata(dev, indio_dev);
> +	data->dev = dev;
> +	data->irq = irq;
> +	data->regmap = regmap;
>  
>  	if (ACPI_HANDLE(dev))
>  		name = bmc150_accel_match_acpi_device(dev, &chip_id);
> @@ -1664,9 +1643,7 @@ static int bmc150_accel_probe(struct i2c_client *client,
>  		if (ret)
>  			goto err_buffer_cleanup;
>  
> -		if (i2c_check_functionality(client->adapter, I2C_FUNC_I2C) ||
> -		    i2c_check_functionality(client->adapter,
> -					    I2C_FUNC_SMBUS_READ_I2C_BLOCK)) {
> +		if (block_supported) {
>  			indio_dev->modes |= INDIO_BUFFER_SOFTWARE;
>  			indio_dev->info = &bmc150_accel_info_fifo;
>  			indio_dev->buffer->attrs = bmc150_accel_fifo_attributes;
> @@ -1675,7 +1652,7 @@ static int bmc150_accel_probe(struct i2c_client *client,
>  
>  	ret = iio_device_register(indio_dev);
>  	if (ret < 0) {
> -		dev_err(data->dev, "Unable to register iio device\n");
> +		dev_err(dev, "Unable to register iio device\n");
>  		goto err_trigger_unregister;
>  	}
>  
> @@ -1698,10 +1675,11 @@ err_buffer_cleanup:
>  
>  	return ret;
>  }
> +EXPORT_SYMBOL_GPL(bmc150_accel_core_probe);
>  
> -static int bmc150_accel_remove(struct i2c_client *client)
> +int bmc150_accel_core_remove(struct device *dev)
>  {
> -	struct iio_dev *indio_dev = i2c_get_clientdata(client);
> +	struct iio_dev *indio_dev = dev_get_drvdata(dev);
>  	struct bmc150_accel_data *data = iio_priv(indio_dev);
>  
>  	pm_runtime_disable(data->dev);
> @@ -1720,6 +1698,7 @@ static int bmc150_accel_remove(struct i2c_client *client)
>  
>  	return 0;
>  }
> +EXPORT_SYMBOL_GPL(bmc150_accel_core_remove);
>  
>  #ifdef CONFIG_PM_SLEEP
>  static int bmc150_accel_suspend(struct device *dev)
> @@ -1790,48 +1769,8 @@ static int bmc150_accel_runtime_resume(struct device *dev)
>  }
>  #endif
>  
> -static const struct dev_pm_ops bmc150_accel_pm_ops = {
> +const struct dev_pm_ops bmc150_accel_pm_ops = {
>  	SET_SYSTEM_SLEEP_PM_OPS(bmc150_accel_suspend, bmc150_accel_resume)
>  	SET_RUNTIME_PM_OPS(bmc150_accel_runtime_suspend,
>  			   bmc150_accel_runtime_resume, NULL)
>  };
> -
> -static const struct acpi_device_id bmc150_accel_acpi_match[] = {
> -	{"BSBA0150",	bmc150},
> -	{"BMC150A",	bmc150},
> -	{"BMI055A",	bmi055},
> -	{"BMA0255",	bma255},
> -	{"BMA250E",	bma250e},
> -	{"BMA222E",	bma222e},
> -	{"BMA0280",	bma280},
> -	{ },
> -};
> -MODULE_DEVICE_TABLE(acpi, bmc150_accel_acpi_match);
> -
> -static const struct i2c_device_id bmc150_accel_id[] = {
> -	{"bmc150_accel",	bmc150},
> -	{"bmi055_accel",	bmi055},
> -	{"bma255",		bma255},
> -	{"bma250e",		bma250e},
> -	{"bma222e",		bma222e},
> -	{"bma280",		bma280},
> -	{}
> -};
> -
> -MODULE_DEVICE_TABLE(i2c, bmc150_accel_id);
> -
> -static struct i2c_driver bmc150_accel_driver = {
> -	.driver = {
> -		.name	= BMC150_ACCEL_DRV_NAME,
> -		.acpi_match_table = ACPI_PTR(bmc150_accel_acpi_match),
> -		.pm	= &bmc150_accel_pm_ops,
> -	},
> -	.probe		= bmc150_accel_probe,
> -	.remove		= bmc150_accel_remove,
> -	.id_table	= bmc150_accel_id,
> -};
> -module_i2c_driver(bmc150_accel_driver);
> -
> -MODULE_AUTHOR("Srinivas Pandruvada <srinivas.pandruvada at linux.intel.com>");
> -MODULE_LICENSE("GPL v2");
> -MODULE_DESCRIPTION("BMC150 accelerometer driver");
> diff --git a/drivers/iio/accel/bmc150-accel-i2c.c b/drivers/iio/accel/bmc150-accel-i2c.c
> new file mode 100644
> index 000000000000..7e036e2eb077
> --- /dev/null
> +++ b/drivers/iio/accel/bmc150-accel-i2c.c
> @@ -0,0 +1,101 @@
> +/*
> + * 3-axis accelerometer driver supporting following I2C Bosch-Sensortec chips:
> + *  - BMC150
> + *  - BMI055
> + *  - BMA255
> + *  - BMA250E
> + *  - BMA222E
> + *  - BMA280
> + *
> + * Copyright (c) 2014, Intel Corporation.
> + *
> + * This program is free software; you can redistribute it and/or modify it
> + * under the terms and conditions of the GNU General Public License,
> + * version 2, as published by the Free Software Foundation.
> + *
> + * This program is distributed in the hope 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/device.h>
> +#include <linux/mod_devicetable.h>
> +#include <linux/i2c.h>
> +#include <linux/module.h>
> +#include <linux/acpi.h>
> +#include <linux/regmap.h>
> +
> +#include "bmc150-accel.h"
> +
> +static const struct regmap_config bmc150_i2c_regmap_conf = {
> +	.reg_bits = 8,
> +	.val_bits = 8,
> +
> +	.use_single_rw = true,
> +	.cache_type = REGCACHE_NONE,
> +};
> +
> +static int bmc150_accel_probe(struct i2c_client *client,
> +			      const struct i2c_device_id *id)
> +{
> +	struct regmap *regmap;
> +	bool block_supported =
> +		i2c_check_functionality(client->adapter, I2C_FUNC_I2C) ||
> +		i2c_check_functionality(client->adapter, I2C_FUNC_SMBUS_READ_I2C_BLOCK);
> +
> +	regmap = devm_regmap_init_i2c(client, &bmc150_i2c_regmap_conf);
> +	if (IS_ERR(regmap)) {
> +		dev_err(&client->dev, "Failed to initialize i2c regmap\n");
> +		return PTR_ERR(regmap);
> +	}
> +
> +	return bmc150_accel_core_probe(&client->dev, regmap, client->irq,
> +				       id->name, id->driver_data,
> +				       block_supported);
> +}
> +
> +static int bmc150_accel_remove(struct i2c_client *client)
> +{
> +	return bmc150_accel_core_remove(&client->dev);
> +}
> +
> +static const struct acpi_device_id bmc150_accel_acpi_match[] = {
> +	{"BSBA0150",	bmc150},
> +	{"BMC150A",	bmc150},
> +	{"BMI055A",	bmi055},
> +	{"BMA0255",	bma255},
> +	{"BMA250E",	bma250e},
> +	{"BMA222E",	bma222e},
> +	{"BMA0280",	bma280},
> +	{ },
> +};
> +MODULE_DEVICE_TABLE(acpi, bmc150_accel_acpi_match);
> +
> +static const struct i2c_device_id bmc150_accel_id[] = {
> +	{"bmc150_accel",	bmc150},
> +	{"bmi055_accel",	bmi055},
> +	{"bma255",		bma255},
> +	{"bma250e",		bma250e},
> +	{"bma222e",		bma222e},
> +	{"bma280",		bma280},
> +	{}
> +};
> +
> +MODULE_DEVICE_TABLE(i2c, bmc150_accel_id);
> +
> +static struct i2c_driver bmc150_accel_driver = {
> +	.driver = {
> +		.name	= "bmc150_accel_i2c",
> +		.acpi_match_table = ACPI_PTR(bmc150_accel_acpi_match),
> +		.pm	= &bmc150_accel_pm_ops,
> +	},
> +	.probe		= bmc150_accel_probe,
> +	.remove		= bmc150_accel_remove,
> +	.id_table	= bmc150_accel_id,
> +};
> +module_i2c_driver(bmc150_accel_driver);
> +
> +MODULE_AUTHOR("Srinivas Pandruvada <srinivas.pandruvada at linux.intel.com>");
> +MODULE_LICENSE("GPL v2");
> +MODULE_DESCRIPTION("BMC150 I2C accelerometer driver");
> diff --git a/drivers/iio/accel/bmc150-accel.h b/drivers/iio/accel/bmc150-accel.h
> new file mode 100644
> index 000000000000..988b57573d0c
> --- /dev/null
> +++ b/drivers/iio/accel/bmc150-accel.h
> @@ -0,0 +1,21 @@
> +#ifndef _BMC150_ACCEL_H_
> +#define _BMC150_ACCEL_H_
> +
> +struct regmap;
> +
> +enum {
> +	bmc150,
> +	bmi055,
> +	bma255,
> +	bma250e,
> +	bma222e,
> +	bma280,
> +};
> +
> +int bmc150_accel_core_probe(struct device *dev, struct regmap *regmap, int irq,
> +			    const char *name, int chip_id,
> +			    bool block_supported);
> +int bmc150_accel_core_remove(struct device *dev);
> +extern const struct dev_pm_ops bmc150_accel_pm_ops;
> +
> +#endif  /* _BMC150_ACCEL_H_ */
> 



From sjg at chromium.org  Sat Aug 15 06:46:38 2015
From: sjg at chromium.org (Simon Glass)
Date: Sat, 15 Aug 2015 07:46:38 -0600
Subject: [PATCH] arm: rpi: Device tree modifications for U-Boot
In-Reply-To: <CAL_Jsq++ihz6svJAKWwT7-=KyJvyWXjdf=tZb4aDGgV_Dc=-Nw@mail.gmail.com>
References: <1439303153-12171-1-git-send-email-sjg@chromium.org>
 <1439312701.2451.3.camel@lynxeye.de>
 <CAPnjgZ3ztXnkxZJvitiXiKMzq5+x46hbv0PW4HcF7yGgsXUV+Q@mail.gmail.com>
 <CAPnjgZ0hzyjy=8o8ocaGCoOC7Js4CirhystidbvtabzbhRi4RQ@mail.gmail.com>
 <CAL_Jsq++ihz6svJAKWwT7-=KyJvyWXjdf=tZb4aDGgV_Dc=-Nw@mail.gmail.com>
Message-ID: <CAPnjgZ3ubK_5j4AV4wO6xgoRf8iN+G8YSQm0pSW5fVzwpxYu5Q@mail.gmail.com>

Hi Rob,

On 14 August 2015 at 14:29, Rob Herring <robherring2 at gmail.com> wrote:
> On Fri, Aug 14, 2015 at 1:34 PM, Simon Glass <sjg at chromium.org> wrote:
>> -linux-tegra
>>
>> Hi,
>>
>> On 12 August 2015 at 07:21, Simon Glass <sjg at chromium.org> wrote:
>>> Hi Lucas,
>>>
>>> On 11 August 2015 at 11:05, Lucas Stach <dev at lynxeye.de> wrote:
>>>> Hi Simon,
>>>>
>>>> why did you send this to the Tegra ML?
>>>>
>>>> Am Dienstag, den 11.08.2015, 08:25 -0600 schrieb Simon Glass:
>>>>> This updates the device tree from the kernel version to something suitable
>>>>> for U-Boot:
>>>>>
>>>>> - Add stdout-path alias for console
>>>>> - Mark the /soc node to be available pre-relocation so that the early
>>>>> serial console works (we need the 'ranges' property to be available)
>
> I find it quite strange that you must explicitly enable the parent
> node, but not the uart node.

U-Boot tries hard to find and bind the UART using the stdout-path
link. I would like to add it in the UART node also but we were able to
work around it so far.

>
>>>>>
>>>>> Signed-off-by: Simon Glass <sjg at chromium.org>
>>>>> ---
>>>>>
>>>>>  arch/arm/boot/dts/bcm2835.dtsi | 4 +++-
>>>>>  1 file changed, 3 insertions(+), 1 deletion(-)
>>>>>
>>>>> diff --git a/arch/arm/boot/dts/bcm2835.dtsi b/arch/arm/boot/dts/bcm2835.dtsi
>>>>> index 301c73f..bd6bff6 100644
>>>>> --- a/arch/arm/boot/dts/bcm2835.dtsi
>>>>> +++ b/arch/arm/boot/dts/bcm2835.dtsi
>>>>> @@ -8,6 +8,7 @@
>>>>>
>>>>>       chosen {
>>>>>               bootargs = "earlyprintk console=ttyAMA0";
>>>>> +             stdout-path = &uart;
>>>>>       };
>>>>>
>>>>>       soc {
>>>>> @@ -16,6 +17,7 @@
>>>>>               #size-cells = <1>;
>>>>>               ranges = <0x7e000000 0x20000000 0x02000000>;
>>>>>               dma-ranges = <0x40000000 0x00000000 0x20000000>;
>>>>> +             u-boot,dm-pre-reloc;
>>>>
>>>> Why do you need this and why should upstream carry your favourite
>>>> bootloaders configuration? This is in no way hardware description.
>>>
>>> I'm not sure how much you know about U-Boot, so let me know if you
>>> need more info.
>>>
>>> U-Boot normally starts up by setting up its serial UART and displaying
>>> a banner message. At this stage typically only a few devices are
>>> initialised (e.g. maybe just the UART). It then relocates itself to
>>> the top of memory and starts up all the devices. It throws away any
>>> previous devices that it set up before relocation and starts again.
>>>
>>> U-Boot uses a thing called driver model (dm) which handles driver
>>> binding and probing. Driver model has the device tree and would
>>> normally scan through it and create devices for everything it finds.
>
> How do you debug the DM itself? It seems like you still would need
> something earlier for debug like earlycon in the kernel. u-boot DM is
> probably simple enough you can get away with using it early, but you
> often can't as the complexity increases. Ultimately you need something
> simple that just hits all the registers needed to get characters out.
> What happens when you add pinmux, clocks, PMIC, power domains, etc. to
> the DM and they all become dependencies for the UART?

This doesn't seem like a device tree binding question but let me try
to answer it.

This is a problem - one of the challenges of driver model is that the
UART gets further away from the reset vector.

In U-Boot there is a single debug UART which can be supported by the
various serial drivers (only one can be selected on each platform).
There is a special debug_uart_init() function which is supposed to set
up the UART for that platform. After that, and until driver model UART
is up, console output can go through the debug UART.

>
>>> Before relocation we don't need every device. Also the CPU is often
>>> running slowly, perhaps without the cache enabled. SDRAM may not be
>>> available yet so space is short. We want to avoid starting up things
>>> that will not be used.
>>>
>>> So this property indicates that the device is needed before relocation
>>> and should be set up by driver model. We need it to avoid a very slow
>>> and memory-hungry startup.
>
> Can't the need for that property change over time? Either as more
> drivers are converted to DM you need to add this or you add some
> feature that depends on a driver (e.g. get a board rev or boot mode
> from GPIO). You would have backwards compatibility issues with this.
> I'm somewhat less worried about that for u-boot as we should be
> bundling the dtb and bootloader rather than kernel and dtb. For the
> UART, you can just get which UART to initialize early from
> stdout-path. But for other cases, couldn't you just have the platform
> provide the list of needed drivers. Then when u-boot needs change, you
> just change u-boot.

Yes U-Boot and its device tree are normally built from the same tree
at the same time. We don't expect to have to support an older or newer
device tree with the same U-Boot binary. So I don't see a problem
here.

The UART should have as few dependencies as possible. But if the
particular platform needs to check a GPIO to find out the UART number
(i.e. stdout-path cannot be used) then we would need to support that
case. It hasn't come up yet but it might. I certainly see platforms
where we need some other nodes before relocation and would like to
mark them as such. But I hope that for UART we can generally use
stdout-path.

The list of drivers doesn't help that much. What would I do with such
a list, and where would I keep such platform-specific information
other than in the device tree? It seems much simpler to hold the
information about what the platform needs to get through early boot in
one place. Then we have just a few lines of generic code to deal with
it.

>
>>> As to why upstream should accept it, my understanding of upstream is
>>> that people can send patches to it and in fact are encouraged to do
>>> so, to avoid misunderstandings and duplication. The device tree files
>>> are stored in Linux so any binding or source file changes should end
>>> up there. Otherwise the files tend to diverge and we end up with
>>> multiple bindings and multiple versions of the same source file.
>>
>> Is the above explanation sufficient? Will this patch be applied?
>
> Well, for starters bindings need to be documented, so you need to send
> this as a binding doc with this detail.

OK I'll update the patch and resend it.

Regards.
Simon


From jic23 at kernel.org  Sat Aug 15 06:47:20 2015
From: jic23 at kernel.org (Jonathan Cameron)
Date: Sat, 15 Aug 2015 14:47:20 +0100
Subject: [PATCH 20/20] iio: bmc150: Add SPI driver
In-Reply-To: <1439374365-20623-21-git-send-email-mpa@pengutronix.de>
References: <1439374365-20623-1-git-send-email-mpa@pengutronix.de>
 <1439374365-20623-21-git-send-email-mpa@pengutronix.de>
Message-ID: <55CF42E8.7070508@kernel.org>

On 12/08/15 11:12, Markus Pargmann wrote:
> Add a simple SPI driver which initializes the spi regmap for the bmc150
> core driver.
> 
> Signed-off-by: Markus Pargmann <mpa at pengutronix.de>
1 thing inline, plus the change of kconfig approach suggested for the
previous patch.

Otherwise, looks fine to me.

Srinivas, over to you for the next version :) (unless you are feeling
enthusiastic and want to take a look at this one)
> ---
>  drivers/iio/accel/Kconfig            | 10 +++++
>  drivers/iio/accel/Makefile           |  1 +
>  drivers/iio/accel/bmc150-accel-spi.c | 86 ++++++++++++++++++++++++++++++++++++
>  3 files changed, 97 insertions(+)
>  create mode 100644 drivers/iio/accel/bmc150-accel-spi.c
> 
> diff --git a/drivers/iio/accel/Kconfig b/drivers/iio/accel/Kconfig
> index c63e981c38ff..bdb42069a767 100644
> --- a/drivers/iio/accel/Kconfig
> +++ b/drivers/iio/accel/Kconfig
> @@ -40,6 +40,16 @@ config BMC150_ACCEL_I2C
>  	  Say yes here to build support for I2C communication with the
>  	  mentioned accelerometer.
>  
> +config BMC150_ACCEL_SPI
> +	tristate "SPI support"
> +	depends on SPI
> +	select IIO_BUFFER
> +	select IIO_TRIGGERED_BUFFER
> +	select REGMAP_SPI
> +	help
> +	  Say yes here to build support for SPI communication with the
> +	  mentioned accelerometer.
If you move to the config approach I suggested earlier, these options
are hidden away avoiding the need for a help message ;)
> +
>  endif
>  
>  config HID_SENSOR_ACCEL_3D
> diff --git a/drivers/iio/accel/Makefile b/drivers/iio/accel/Makefile
> index 5ef8bdbad092..e579e93bf022 100644
> --- a/drivers/iio/accel/Makefile
> +++ b/drivers/iio/accel/Makefile
> @@ -6,6 +6,7 @@
>  obj-$(CONFIG_BMA180) += bma180.o
>  obj-$(CONFIG_BMC150_ACCEL) += bmc150-accel-core.o
>  obj-$(CONFIG_BMC150_ACCEL_I2C) += bmc150-accel-i2c.o
> +obj-$(CONFIG_BMC150_ACCEL_SPI) += bmc150-accel-spi.o
>  obj-$(CONFIG_HID_SENSOR_ACCEL_3D) += hid-sensor-accel-3d.o
>  obj-$(CONFIG_KXCJK1013) += kxcjk-1013.o
>  obj-$(CONFIG_KXSD9)	+= kxsd9.o
> diff --git a/drivers/iio/accel/bmc150-accel-spi.c b/drivers/iio/accel/bmc150-accel-spi.c
> new file mode 100644
> index 000000000000..c13fd2aa5f34
> --- /dev/null
> +++ b/drivers/iio/accel/bmc150-accel-spi.c
> @@ -0,0 +1,86 @@
> +/*
> + * 3-axis accelerometer driver supporting following I2C Bosch-Sensortec chips:
Umm. Read the line above?  Spot the obvious minor point ;)

> + *  - BMC150
> + *  - BMI055
> + *  - BMA255
> + *  - BMA250E
> + *  - BMA222E
> + *  - BMA280
> + *
> + * Copyright (c) 2014, Intel Corporation.
> + *
> + * This program is free software; you can redistribute it and/or modify it
> + * under the terms and conditions of the GNU General Public License,
> + * version 2, as published by the Free Software Foundation.
> + *
> + * This program is distributed in the hope 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/device.h>
> +#include <linux/mod_devicetable.h>
> +#include <linux/module.h>
> +#include <linux/acpi.h>
> +#include <linux/regmap.h>
> +#include <linux/spi/spi.h>
> +
> +#include "bmc150-accel.h"
> +
> +static const struct regmap_config bmc150_spi_regmap_conf = {
> +	.reg_bits = 8,
> +	.val_bits = 8,
> +	.max_register = 0x3f,
> +
> +	.use_single_rw = false,
> +	.cache_type = REGCACHE_NONE,
> +};
> +
> +static int bmc150_accel_probe(struct spi_device *spi)
> +{
> +	struct regmap *regmap;
> +	const struct spi_device_id *id = spi_get_device_id(spi);
> +
> +	regmap = devm_regmap_init_spi(spi, &bmc150_spi_regmap_conf);
> +	if (IS_ERR(regmap)) {
> +		dev_err(&spi->dev, "Failed to initialize spi regmap\n");
> +		return PTR_ERR(regmap);
> +	}
> +
> +	return bmc150_accel_core_probe(&spi->dev, regmap, spi->irq,
> +				       id->name, id->driver_data, true);
> +}
> +
> +static int bmc150_accel_remove(struct spi_device *spi)
> +{
> +	return bmc150_accel_core_remove(&spi->dev);
> +}
> +
> +static const struct spi_device_id bmc150_accel_id[] = {
> +	{"bmc150_accel",	bmc150},
> +	{"bmi055_accel",	bmi055},
> +	{"bma255",		bma255},
> +	{"bma250e",		bma250e},
> +	{"bma222e",		bma222e},
> +	{"bma280",		bma280},
> +	{}
> +};
> +
> +MODULE_DEVICE_TABLE(spi, bmc150_accel_id);
> +
> +static struct spi_driver bmc150_accel_driver = {
> +	.driver = {
> +		.name	= "bmc150_accel_spi",
> +		.acpi_match_table = ACPI_PTR(bmc150_accel_acpi_match),
> +		.pm	= &bmc150_accel_pm_ops,
> +	},
> +	.probe		= bmc150_accel_probe,
> +	.remove		= bmc150_accel_remove,
> +	.id_table	= bmc150_accel_id,
> +};
> +module_spi_driver(bmc150_accel_driver);
> +
> +MODULE_AUTHOR("Markus Pargmann <mpa at pengutronix.de>");
> +MODULE_LICENSE("GPL v2");
> +MODULE_DESCRIPTION("BMC150 SPI accelerometer driver");
> 



From sjg at chromium.org  Sat Aug 15 06:47:00 2015
From: sjg at chromium.org (Simon Glass)
Date: Sat, 15 Aug 2015 07:47:00 -0600
Subject: [PATCH] arm: rpi: Device tree modifications for U-Boot
In-Reply-To: <55CEB607.7060908@wwwdotorg.org>
References: <1439303153-12171-1-git-send-email-sjg@chromium.org>
 <1439312701.2451.3.camel@lynxeye.de>
 <CAPnjgZ3ztXnkxZJvitiXiKMzq5+x46hbv0PW4HcF7yGgsXUV+Q@mail.gmail.com>
 <55CEB607.7060908@wwwdotorg.org>
Message-ID: <CAPnjgZ1KxqDf2o_UnsmbWs9DZJpupj6D2trBACrJm-eT1g_xVA@mail.gmail.com>

Hi Stephen,

On 14 August 2015 at 21:46, Stephen Warren <swarren at wwwdotorg.org> wrote:
> On 08/12/2015 07:21 AM, Simon Glass wrote:
>> Hi Lucas,
>>
>> On 11 August 2015 at 11:05, Lucas Stach <dev at lynxeye.de> wrote:
>>> Hi Simon,
>>>
>>> why did you send this to the Tegra ML?
>>>
>>> Am Dienstag, den 11.08.2015, 08:25 -0600 schrieb Simon Glass:
>>>> This updates the device tree from the kernel version to something suitable
>>>> for U-Boot:
>>>>
>>>> - Add stdout-path alias for console
>>>> - Mark the /soc node to be available pre-relocation so that the early
>>>> serial console works (we need the 'ranges' property to be available)
>>>>
>>>> Signed-off-by: Simon Glass <sjg at chromium.org>
>>>> ---
>>>>
>>>>  arch/arm/boot/dts/bcm2835.dtsi | 4 +++-
>>>>  1 file changed, 3 insertions(+), 1 deletion(-)
>>>>
>>>> diff --git a/arch/arm/boot/dts/bcm2835.dtsi b/arch/arm/boot/dts/bcm2835.dtsi
>>>> index 301c73f..bd6bff6 100644
>>>> --- a/arch/arm/boot/dts/bcm2835.dtsi
>>>> +++ b/arch/arm/boot/dts/bcm2835.dtsi
>>>> @@ -8,6 +8,7 @@
>>>>
>>>>       chosen {
>>>>               bootargs = "earlyprintk console=ttyAMA0";
>>>> +             stdout-path = &uart;
>>>>       };
>>>>
>>>>       soc {
>>>> @@ -16,6 +17,7 @@
>>>>               #size-cells = <1>;
>>>>               ranges = <0x7e000000 0x20000000 0x02000000>;
>>>>               dma-ranges = <0x40000000 0x00000000 0x20000000>;
>>>> +             u-boot,dm-pre-reloc;
>>>
>>> Why do you need this and why should upstream carry your favourite
>>> bootloaders configuration? This is in no way hardware description.
>>
>> I'm not sure how much you know about U-Boot, so let me know if you
>> need more info.
>>
>> U-Boot normally starts up by setting up its serial UART and displaying
>> a banner message. At this stage typically only a few devices are
>> initialised (e.g. maybe just the UART). It then relocates itself to
>> the top of memory and starts up all the devices. It throws away any
>> previous devices that it set up before relocation and starts again.
>>
>> U-Boot uses a thing called driver model (dm) which handles driver
>> binding and probing. Driver model has the device tree and would
>> normally scan through it and create devices for everything it finds.
>>
>> Before relocation we don't need every device. Also the CPU is often
>> running slowly, perhaps without the cache enabled. SDRAM may not be
>> available yet so space is short. We want to avoid starting up things
>> that will not be used.
>>
>> So this property indicates that the device is needed before relocation
>> and should be set up by driver model. We need it to avoid a very slow
>> and memory-hungry startup.
>>
>> As to why upstream should accept it, my understanding of upstream is
>> that people can send patches to it and in fact are encouraged to do
>> so, to avoid misunderstandings and duplication. The device tree files
>> are stored in Linux so any binding or source file changes should end
>> up there. Otherwise the files tend to diverge and we end up with
>> multiple bindings and multiple versions of the same source file.
>
> On many platforms, we have U-Boot SPL running first, then the main
> U-Boot. The main U-Boot binary contains both the code to do the
> relocation and the binary that runs after relocation. It seems like it'd
> be simpler to split these up into 3 binaries that each do a single job:
>
> 1) SPL, roughly as-is today (varying jobs depending on platform)
>
> 2) Relocator, which does nothing but work out where to copy U-Boot,
> memcpy()s it there, relocates the image (if not PIE), and jumps to it.
>
> 3) The main U-Boot.
>
> Item (2) above should be simple enough that it can use a very simple
> debug mechanism rather like DEBUG_LL in the Linux kernel. Similar to
> what Rob mentioned in his email.
>
> Item (3) could use DM and DT/ACPI/... to get device information in a
> complete non-hard-coded manner.

This comment does no seem to relate to my patch. We could certainly
re-architect U-Boot to work this way. There are  lot of reasons why
U-Boot works as it does and many platforms don't have SPL.

Relating what you said to the current U-Boot, your item (2) is
analogous to us not setting up driver model before relocation at all,
and just having a debug UART. That's a huge topic though, well beyond
the scope of my original patch. I think it would be better for you to
start a thread on the U-Boot mailing list with your proposal. At least
on x86 (which has no SPL) there are all sorts of things that currently
happen before relocation.

Regards,
Simon


From gregory.clement at free-electrons.com  Sat Aug 15 07:17:26 2015
From: gregory.clement at free-electrons.com (Gregory CLEMENT)
Date: Sat, 15 Aug 2015 16:17:26 +0200
Subject: [PATCH] ARM: orion5x: fix legacy orion5x IRQ numbers
Message-ID: <1439648246-32757-1-git-send-email-gregory.clement@free-electrons.com>

From: Benjamin Cama <benoar at dolka.fr>

Since v3.18, attempts to deliver IRQ0 are rejected, breaking orion5x.
Fix this by increasing all interrupts by one, as did 5d6bed2a9c8b for
dove. Also, force MULTI_IRQ_HANDLER for all orion platforms (including
dove) as the specific handler is needed to shift back IRQ numbers by
one.

[gregory.clement at free-electrons.com]: moved the select
MULTI_IRQ_HANDLER from PLAT_ORION_LEGACY to ARCH_ORION5X as it broke
the build for dove.

Fixes: a71b092a9c68 ("ARM: Convert handle_IRQ to use __handle_domain_irq")
Signed-off-by: Benjamin Cama <benoar at dolka.fr>
Signed-off-by: Gregory CLEMENT <gregory.clement at free-electrons.com>
Cc: <stable at vger.kernel.org>
---
Hi Benjamin and Detlef,

I amended the patch from Benjamin as it break the build for
dove. Could you test it again wit this version?

Thanks,

Gregory

 arch/arm/Kconfig                          |  1 +
 arch/arm/mach-orion5x/include/mach/irqs.h | 64 +++++++++++++++----------------
 arch/arm/mach-orion5x/irq.c               |  4 +-
 3 files changed, 35 insertions(+), 34 deletions(-)

diff --git a/arch/arm/Kconfig b/arch/arm/Kconfig
index a750c1425c3a..a67e53a3ba31 100644
--- a/arch/arm/Kconfig
+++ b/arch/arm/Kconfig
@@ -536,6 +536,7 @@ config ARCH_ORION5X
 	select MVEBU_MBUS
 	select PCI
 	select PLAT_ORION_LEGACY
+	select MULTI_IRQ_HANDLER
 	help
 	  Support for the following Marvell Orion 5x series SoCs:
 	  Orion-1 (5181), Orion-VoIP (5181L), Orion-NAS (5182),
diff --git a/arch/arm/mach-orion5x/include/mach/irqs.h b/arch/arm/mach-orion5x/include/mach/irqs.h
index a6fa9d8f12d8..2431d9923427 100644
--- a/arch/arm/mach-orion5x/include/mach/irqs.h
+++ b/arch/arm/mach-orion5x/include/mach/irqs.h
@@ -16,42 +16,42 @@
 /*
  * Orion Main Interrupt Controller
  */
-#define IRQ_ORION5X_BRIDGE		0
-#define IRQ_ORION5X_DOORBELL_H2C	1
-#define IRQ_ORION5X_DOORBELL_C2H	2
-#define IRQ_ORION5X_UART0		3
-#define IRQ_ORION5X_UART1		4
-#define IRQ_ORION5X_I2C			5
-#define IRQ_ORION5X_GPIO_0_7		6
-#define IRQ_ORION5X_GPIO_8_15		7
-#define IRQ_ORION5X_GPIO_16_23		8
-#define IRQ_ORION5X_GPIO_24_31		9
-#define IRQ_ORION5X_PCIE0_ERR		10
-#define IRQ_ORION5X_PCIE0_INT		11
-#define IRQ_ORION5X_USB1_CTRL		12
-#define IRQ_ORION5X_DEV_BUS_ERR		14
-#define IRQ_ORION5X_PCI_ERR		15
-#define IRQ_ORION5X_USB_BR_ERR		16
-#define IRQ_ORION5X_USB0_CTRL		17
-#define IRQ_ORION5X_ETH_RX		18
-#define IRQ_ORION5X_ETH_TX		19
-#define IRQ_ORION5X_ETH_MISC		20
-#define IRQ_ORION5X_ETH_SUM		21
-#define IRQ_ORION5X_ETH_ERR		22
-#define IRQ_ORION5X_IDMA_ERR		23
-#define IRQ_ORION5X_IDMA_0		24
-#define IRQ_ORION5X_IDMA_1		25
-#define IRQ_ORION5X_IDMA_2		26
-#define IRQ_ORION5X_IDMA_3		27
-#define IRQ_ORION5X_CESA		28
-#define IRQ_ORION5X_SATA		29
-#define IRQ_ORION5X_XOR0		30
-#define IRQ_ORION5X_XOR1		31
+#define IRQ_ORION5X_BRIDGE		(1 + 0)
+#define IRQ_ORION5X_DOORBELL_H2C	(1 + 1)
+#define IRQ_ORION5X_DOORBELL_C2H	(1 + 2)
+#define IRQ_ORION5X_UART0		(1 + 3)
+#define IRQ_ORION5X_UART1		(1 + 4)
+#define IRQ_ORION5X_I2C			(1 + 5)
+#define IRQ_ORION5X_GPIO_0_7		(1 + 6)
+#define IRQ_ORION5X_GPIO_8_15		(1 + 7)
+#define IRQ_ORION5X_GPIO_16_23		(1 + 8)
+#define IRQ_ORION5X_GPIO_24_31		(1 + 9)
+#define IRQ_ORION5X_PCIE0_ERR		(1 + 10)
+#define IRQ_ORION5X_PCIE0_INT		(1 + 11)
+#define IRQ_ORION5X_USB1_CTRL		(1 + 12)
+#define IRQ_ORION5X_DEV_BUS_ERR		(1 + 14)
+#define IRQ_ORION5X_PCI_ERR		(1 + 15)
+#define IRQ_ORION5X_USB_BR_ERR		(1 + 16)
+#define IRQ_ORION5X_USB0_CTRL		(1 + 17)
+#define IRQ_ORION5X_ETH_RX		(1 + 18)
+#define IRQ_ORION5X_ETH_TX		(1 + 19)
+#define IRQ_ORION5X_ETH_MISC		(1 + 20)
+#define IRQ_ORION5X_ETH_SUM		(1 + 21)
+#define IRQ_ORION5X_ETH_ERR		(1 + 22)
+#define IRQ_ORION5X_IDMA_ERR		(1 + 23)
+#define IRQ_ORION5X_IDMA_0		(1 + 24)
+#define IRQ_ORION5X_IDMA_1		(1 + 25)
+#define IRQ_ORION5X_IDMA_2		(1 + 26)
+#define IRQ_ORION5X_IDMA_3		(1 + 27)
+#define IRQ_ORION5X_CESA		(1 + 28)
+#define IRQ_ORION5X_SATA		(1 + 29)
+#define IRQ_ORION5X_XOR0		(1 + 30)
+#define IRQ_ORION5X_XOR1		(1 + 31)
 
 /*
  * Orion General Purpose Pins
  */
-#define IRQ_ORION5X_GPIO_START	32
+#define IRQ_ORION5X_GPIO_START	33
 #define NR_GPIO_IRQS		32
 
 #define NR_IRQS			(IRQ_ORION5X_GPIO_START + NR_GPIO_IRQS)
diff --git a/arch/arm/mach-orion5x/irq.c b/arch/arm/mach-orion5x/irq.c
index cd4bac4d7e43..086ecb87d885 100644
--- a/arch/arm/mach-orion5x/irq.c
+++ b/arch/arm/mach-orion5x/irq.c
@@ -42,7 +42,7 @@ __exception_irq_entry orion5x_legacy_handle_irq(struct pt_regs *regs)
 	stat = readl_relaxed(MAIN_IRQ_CAUSE);
 	stat &= readl_relaxed(MAIN_IRQ_MASK);
 	if (stat) {
-		unsigned int hwirq = __fls(stat);
+		unsigned int hwirq = 1 + __fls(stat);
 		handle_IRQ(hwirq, regs);
 		return;
 	}
@@ -51,7 +51,7 @@ __exception_irq_entry orion5x_legacy_handle_irq(struct pt_regs *regs)
 
 void __init orion5x_init_irq(void)
 {
-	orion_irq_init(0, MAIN_IRQ_MASK);
+	orion_irq_init(1, MAIN_IRQ_MASK);
 
 #ifdef CONFIG_MULTI_IRQ_HANDLER
 	set_handle_irq(orion5x_legacy_handle_irq);
-- 
2.1.0



From dirk.behme at gmail.com  Sat Aug 15 08:52:51 2015
From: dirk.behme at gmail.com (Dirk Behme)
Date: Sat, 15 Aug 2015 17:52:51 +0200
Subject: [PATCH] arm: dma-mapping: add cast to DMA_ERROR_CODE
Message-ID: <1439653971-867-1-git-send-email-dirk.behme@gmail.com>

Fix the compiler warning

./arch/arm/include/asm/dma-mapping.h: In function ?dma_mapping_error?:
./arch/arm/include/asm/dma-mapping.h:176:18: warning: comparison between signed and unsigned integer expressions [-Wsign-compare]
  return dma_addr == DMA_ERROR_CODE;
                  ^

we get building the kernel with W=1.

This is done the same way we have already in the arm64 version.

Signed-off-by: Dirk Behme <dirk.behme at gmail.com>
---
 arch/arm/include/asm/dma-mapping.h | 2 +-
 1 file changed, 1 insertion(+), 1 deletion(-)

diff --git a/arch/arm/include/asm/dma-mapping.h b/arch/arm/include/asm/dma-mapping.h
index b52101d..68e41e8 100644
--- a/arch/arm/include/asm/dma-mapping.h
+++ b/arch/arm/include/asm/dma-mapping.h
@@ -14,7 +14,7 @@
 #include <xen/xen.h>
 #include <asm/xen/hypervisor.h>
 
-#define DMA_ERROR_CODE	(~0)
+#define DMA_ERROR_CODE	(~(dma_addr_t)0)
 extern struct dma_map_ops arm_dma_ops;
 extern struct dma_map_ops arm_coherent_dma_ops;
 
-- 
2.5.0



From jic23 at kernel.org  Sat Aug 15 12:55:22 2015
From: jic23 at kernel.org (Jonathan Cameron)
Date: Sat, 15 Aug 2015 20:55:22 +0100
Subject: [PATCH v4] iio: adc: xilinx-xadc: Push interrupts into hardirq
 context
In-Reply-To: <55CB7558.3090608@linutronix.de>
References: <55C07160.5040907@metafoo.de>
 <1439334049-28671-1-git-send-email-xander.huff@ni.com>
 <55CB6391.7060502@metafoo.de> <55CB7558.3090608@linutronix.de>
Message-ID: <55CF992A.5040505@kernel.org>

On 12/08/15 17:33, Sebastian Andrzej Siewior wrote:
> On 08/12/2015 05:17 PM, Lars-Peter Clausen wrote:
>> On 08/12/2015 01:00 AM, Xander Huff wrote:
>>> Unfortunately, this breaks PREEMPT_RT builds, where a spinlock can sleep,
>>> and is thus not able to be acquired from a hardirq handler. This patch gets
>>> rid of the threaded handler and pushes all interrupt handling into the
>>> hardirq context, and uses request_irq().
>>>
>>> To validate that this change has no impact on RT performance, here are
>>> cyclictest values with no processes running:
>>
>> Looks good, thanks.
>>
>> Acked-by: Lars-Peter Clausen <lars at metafoo.de>
> 
> Yes, I'm fine with the rework, too.
Formal Acked-by would be good but I'll take this on the basis of Lars' one
and that the code clearly should work from a read through.

Applied to the togreg branch of iio.git.  Thanks for following through
the various twists of this one. Will initially be pushed out as testing.
Note this has almost certainly (unless Linus announces a delay) missed the
upcoming merge window so will be lined up for the 4.4 one.

Jonathan
> 
> Sebastian
> --
> To unsubscribe from this list: send the line "unsubscribe linux-iio" in
> the body of a message to majordomo at vger.kernel.org
> More majordomo info at  http://vger.kernel.org/majordomo-info.html
> 



From arnd at arndb.de  Sat Aug 15 13:05:09 2015
From: arnd at arndb.de (Arnd Bergmann)
Date: Sat, 15 Aug 2015 22:05:09 +0200
Subject: [PATCH v5 1/2] usb: make xhci platform driver use 64 bit or 32
 bit DMA
In-Reply-To: <CADaLNDn4SvW3hvi7H0c_z2xgVSgRHLOK06xMyTYJd+ddFqc7Nw@mail.gmail.com>
References: <CADaLNDkU14GCPZE_zNt_9kMSsUdywyNp1QCiWpokXQgbfRS0qw@mail.gmail.com>
 <20150808092252.GJ7557@n2100.arm.linux.org.uk>
 <CADaLNDn4SvW3hvi7H0c_z2xgVSgRHLOK06xMyTYJd+ddFqc7Nw@mail.gmail.com>
Message-ID: <1643536.i8Q5EFEN01@wuerfel>

On Saturday 08 August 2015 13:31:02 Duc Dang wrote:
> >
> > If we know that pdev->dev.dma_mask will always be initialised at this
> > point, then the above change is fine.  If not, it's introducing a
> > regression - dma_set_mask_and_coherent() will fail if pdev->dev.dma_mask
> > is NULL (depending on the architectures implementation of dma_set_mask()).
> >
> > Prefixing the above change with the two lines I mention above would
> > ensure equivalent behaviour.  Even if we do want to get rid of this,
> > I'd advise to do it as a separate patch after this change, which can
> > be independently reverted if there's problems with its removal.
> >
> Hi Russell,
> 
> I will add the 2 lines you mentioned back to next version of the
> patch. It is safer to do it that way as I do not see
> pdev->dev.dma_mask gets initialized before the call
> dma_set_mask_and_coherent  inside this xhci_plat.c file.

It would be good to add a WARN_ON() to the case where dma_mask
is a NULL pointer at the least. That way, we will at least
find out if there are some broken platforms that do not correctly
initialize the mask pointer.

	Arnd


From dv at vollmann.ch  Sat Aug 15 13:09:55 2015
From: dv at vollmann.ch (Detlef Vollmann)
Date: Sat, 15 Aug 2015 22:09:55 +0200
Subject: [PATCH] ARM: orion5x: fix legacy orion5x IRQ numbers
In-Reply-To: <1439648246-32757-1-git-send-email-gregory.clement@free-electrons.com>
References: <1439648246-32757-1-git-send-email-gregory.clement@free-electrons.com>
Message-ID: <55CF9C93.801@vollmann.ch>

Hi Gregory,

On 08/15/15 16:17, Gregory CLEMENT wrote:
> I amended the patch from Benjamin as it break the build for
> dove. Could you test it again wit this version?
Tested with orion5x_defconfig on 4.2.0-rc6 and with my
own config on 4.1.2.
Looks good for both :-)

Thanks!
   Detlef



From arnd at arndb.de  Sat Aug 15 13:16:03 2015
From: arnd at arndb.de (Arnd Bergmann)
Date: Sat, 15 Aug 2015 22:16:03 +0200
Subject: [PATCH] spi: Mediatek: fix endian warnings
In-Reply-To: <1439289789-29026-1-git-send-email-leilk.liu@mediatek.com>
References: <1439289789-29026-1-git-send-email-leilk.liu@mediatek.com>
Message-ID: <1871097.B3YgX5rNy0@wuerfel>

On Tuesday 11 August 2015 18:43:09 Leilk Liu wrote:
> @@ -359,9 +359,11 @@ static void mtk_spi_setup_dma_addr(struct spi_master *master,
>         struct mtk_spi *mdata = spi_master_get_devdata(master);
>  
>         if (mdata->tx_sgl)
> -               writel(cpu_to_le32(xfer->tx_dma), mdata->base + SPI_TX_SRC_REG);
> +               writel((__force u32)cpu_to_le32(xfer->tx_dma),
> +                      mdata->base + SPI_TX_SRC_REG);
>         if (mdata->rx_sgl)
> -               writel(cpu_to_le32(xfer->rx_dma), mdata->base + SPI_RX_DST_REG);
> +               writel((__force u32)cpu_to_le32(xfer->rx_dma),
> +                      mdata->base + SPI_RX_DST_REG);
>  }
> 

This looks wrong: writel takes a CPU-endian argument, so the value returned
from cpu_to_le32() is not appropriate.

The warning is correct, and you have to remove the cpu_to_le32() conversion
in order to get the driver to behave correctly when the kernel is built
as big-endian.

	Arnd


From arnd at arndb.de  Sat Aug 15 13:17:15 2015
From: arnd at arndb.de (Arnd Bergmann)
Date: Sat, 15 Aug 2015 22:17:15 +0200
Subject: [PATCH] spi: Mediatek: fix endian warnings
In-Reply-To: <1871097.B3YgX5rNy0@wuerfel>
References: <1439289789-29026-1-git-send-email-leilk.liu@mediatek.com>
 <1871097.B3YgX5rNy0@wuerfel>
Message-ID: <4559739.Ziakvog9nM@wuerfel>

On Saturday 15 August 2015 22:16:03 Arnd Bergmann wrote:
> On Tuesday 11 August 2015 18:43:09 Leilk Liu wrote:
> > @@ -359,9 +359,11 @@ static void mtk_spi_setup_dma_addr(struct spi_master *master,
> >         struct mtk_spi *mdata = spi_master_get_devdata(master);
> >  
> >         if (mdata->tx_sgl)
> > -               writel(cpu_to_le32(xfer->tx_dma), mdata->base + SPI_TX_SRC_REG);
> > +               writel((__force u32)cpu_to_le32(xfer->tx_dma),
> > +                      mdata->base + SPI_TX_SRC_REG);
> >         if (mdata->rx_sgl)
> > -               writel(cpu_to_le32(xfer->rx_dma), mdata->base + SPI_RX_DST_REG);
> > +               writel((__force u32)cpu_to_le32(xfer->rx_dma),
> > +                      mdata->base + SPI_RX_DST_REG);
> >  }
> > 
> 
> This looks wrong: writel takes a CPU-endian argument, so the value returned
> from cpu_to_le32() is not appropriate.
> 
> The warning is correct, and you have to remove the cpu_to_le32() conversion
> in order to get the driver to behave correctly when the kernel is built
> as big-endian.

Nevermind, I now saw the issue has already been raised.

	Arnd


From jic23 at kernel.org  Sat Aug 15 13:24:01 2015
From: jic23 at kernel.org (Jonathan Cameron)
Date: Sat, 15 Aug 2015 21:24:01 +0100
Subject: [PATCH v3] iio: adc: vf610: Add IIO buffer support for Vybrid ADC
In-Reply-To: <d556443a26070be505f9a5f5f0999253b73d9b71.1439283162.git.maitysanchayan@gmail.com>
References: <cover.1439283162.git.maitysanchayan@gmail.com>
 <d556443a26070be505f9a5f5f0999253b73d9b71.1439283162.git.maitysanchayan@gmail.com>
Message-ID: <55CF9FE1.3000103@kernel.org>

On 11/08/15 10:05, Sanchayan Maity wrote:
> This patch adds support for IIO buffer to the Vybrid ADC driver.
> IIO triggered buffer infrastructure along with iio sysfs trigger
> is used to leverage continuous sampling support provided by the
> ADC block.
> 
> Signed-off-by: Sanchayan Maity <maitysanchayan at gmail.com>
Hi Sanchayan,

Very nearly there. One little point to do with the buffer handling.
Basically I don't think you want anything in the preenable or
postdisable hooks, just in the 'internal' ones.

Jonathan
> ---
>  drivers/iio/adc/Kconfig     |   2 +
>  drivers/iio/adc/vf610_adc.c | 102 +++++++++++++++++++++++++++++++++++++++++---
>  2 files changed, 97 insertions(+), 7 deletions(-)
> 
> diff --git a/drivers/iio/adc/Kconfig b/drivers/iio/adc/Kconfig
> index 7c55658..660f790 100644
> --- a/drivers/iio/adc/Kconfig
> +++ b/drivers/iio/adc/Kconfig
> @@ -337,6 +337,8 @@ config TWL6030_GPADC
>  config VF610_ADC
>  	tristate "Freescale vf610 ADC driver"
>  	depends on OF
> +	select IIO_BUFFER
> +	select IIO_TRIGGERED_BUFFER
>  	help
>  	  Say yes here to support for Vybrid board analog-to-digital converter.
>  	  Since the IP is used for i.MX6SLX, the driver also support i.MX6SLX.
> diff --git a/drivers/iio/adc/vf610_adc.c b/drivers/iio/adc/vf610_adc.c
> index 23b8fb9..de62c48 100644
> --- a/drivers/iio/adc/vf610_adc.c
> +++ b/drivers/iio/adc/vf610_adc.c
> @@ -34,8 +34,11 @@
>  #include <linux/err.h>
>  
>  #include <linux/iio/iio.h>
> +#include <linux/iio/buffer.h>
>  #include <linux/iio/sysfs.h>
> -#include <linux/iio/driver.h>
> +#include <linux/iio/trigger.h>
> +#include <linux/iio/trigger_consumer.h>
> +#include <linux/iio/triggered_buffer.h>
>  
>  /* This will be the driver name the kernel reports */
>  #define DRIVER_NAME "vf610-adc"
> @@ -170,6 +173,7 @@ struct vf610_adc {
>  	u32 sample_freq_avail[5];
>  
>  	struct completion completion;
> +	u16 buffer[8];
>  };
>  
>  static const u32 vf610_hw_avgs[] = { 1, 4, 8, 16, 32 };
> @@ -505,12 +509,24 @@ static const struct iio_chan_spec_ext_info vf610_ext_info[] = {
>  	.info_mask_shared_by_type = BIT(IIO_CHAN_INFO_SCALE) |	\
>  				BIT(IIO_CHAN_INFO_SAMP_FREQ),	\
>  	.ext_info = vf610_ext_info,				\
> +	.scan_index = (_idx),			\
> +	.scan_type = {					\
> +		.sign = 'u',				\
> +		.realbits = 12,				\
> +		.storagebits = 16,			\
> +	},						\
>  }
>  
>  #define VF610_ADC_TEMPERATURE_CHAN(_idx, _chan_type) {	\
>  	.type = (_chan_type),	\
>  	.channel = (_idx),		\
>  	.info_mask_separate = BIT(IIO_CHAN_INFO_PROCESSED),	\
> +	.scan_index = (_idx),					\
> +	.scan_type = {						\
> +		.sign = 'u',					\
> +		.realbits = 12,					\
> +		.storagebits = 16,				\
> +	},							\
>  }
>  
>  static const struct iio_chan_spec vf610_adc_iio_channels[] = {
> @@ -531,6 +547,7 @@ static const struct iio_chan_spec vf610_adc_iio_channels[] = {
>  	VF610_ADC_CHAN(14, IIO_VOLTAGE),
>  	VF610_ADC_CHAN(15, IIO_VOLTAGE),
>  	VF610_ADC_TEMPERATURE_CHAN(26, IIO_TEMP),
> +	IIO_CHAN_SOFT_TIMESTAMP(32),
>  	/* sentinel */
>  };
>  
> @@ -559,13 +576,20 @@ static int vf610_adc_read_data(struct vf610_adc *info)
>  
>  static irqreturn_t vf610_adc_isr(int irq, void *dev_id)
>  {
> -	struct vf610_adc *info = (struct vf610_adc *)dev_id;
> +	struct iio_dev *indio_dev = (struct iio_dev *)dev_id;
> +	struct vf610_adc *info = iio_priv(indio_dev);
>  	int coco;
>  
>  	coco = readl(info->regs + VF610_REG_ADC_HS);
>  	if (coco & VF610_ADC_HS_COCO0) {
>  		info->value = vf610_adc_read_data(info);
> -		complete(&info->completion);
> +		if (iio_buffer_enabled(indio_dev)) {
> +			info->buffer[0] = info->value;
> +			iio_push_to_buffers_with_timestamp(indio_dev,
> +					info->buffer, iio_get_time_ns());
> +			iio_trigger_notify_done(indio_dev->trig);
> +		} else
> +			complete(&info->completion);
>  	}
>  
>  	return IRQ_HANDLED;
> @@ -613,8 +637,12 @@ static int vf610_read_raw(struct iio_dev *indio_dev,
>  	case IIO_CHAN_INFO_RAW:
>  	case IIO_CHAN_INFO_PROCESSED:
>  		mutex_lock(&indio_dev->mlock);
> -		reinit_completion(&info->completion);
> +		if (iio_buffer_enabled(indio_dev)) {
> +			mutex_unlock(&indio_dev->mlock);
> +			return -EBUSY;
> +		}
>  
> +		reinit_completion(&info->completion);
>  		hc_cfg = VF610_ADC_ADCHC(chan->channel);
>  		hc_cfg |= VF610_ADC_AIEN;
>  		writel(hc_cfg, info->regs + VF610_REG_ADC_HC0);
> @@ -694,6 +722,57 @@ static int vf610_write_raw(struct iio_dev *indio_dev,
>  	return -EINVAL;
>  }
>  
> +static int vf610_adc_buffer_postenable(struct iio_dev *indio_dev)
> +{
> +	struct vf610_adc *info = iio_priv(indio_dev);
> +	unsigned int channel;
> +	int ret;
> +	int val;
> +
> +	ret = iio_triggered_buffer_postenable(indio_dev);
> +	if (ret)
> +		return ret;
> +
> +	val = readl(info->regs + VF610_REG_ADC_GC);
> +	val |= VF610_ADC_ADCON;
> +	writel(val, info->regs + VF610_REG_ADC_GC);
> +
> +	channel = find_first_bit(indio_dev->active_scan_mask,
> +						indio_dev->masklength);
> +
> +	val = VF610_ADC_ADCHC(channel);
> +	val |= VF610_ADC_AIEN;
> +
> +	writel(val, info->regs + VF610_REG_ADC_HC0);
> +
> +	return 0;
> +}
> +

These are suppose to be pair wise matched, so anything set up
in postenable has to be torn down in predisable.
Likewise, preenable setup torn down in postdisable.

The distinction is meant to be that a query will return that the
buffer is enabled from a point between the pre and post enable
and return that it is disabled from a point between the pre and
post disable.  Actually locks are held so there may no longer
be a window where it matters, but best to keep to convention.

I think you want the postdisable -> predisable and then call the
standard predisable from there.

> +static int vf610_adc_buffer_postdisable(struct iio_dev *indio_dev)
> +{
> +	struct vf610_adc *info = iio_priv(indio_dev);
> +	unsigned int hc_cfg = 0;
> +	int val;
> +
> +	val = readl(info->regs + VF610_REG_ADC_GC);
> +	val &= ~VF610_ADC_ADCON;
> +	writel(val, info->regs + VF610_REG_ADC_GC);
> +
> +	hc_cfg |= VF610_ADC_CONV_DISABLE;
> +	hc_cfg &= ~VF610_ADC_AIEN;
> +
> +	writel(hc_cfg, info->regs + VF610_REG_ADC_HC0);
> +
> +	return 0;
> +}
> +
> +static const struct iio_buffer_setup_ops iio_triggered_buffer_setup_ops = {
> +	.postenable = &vf610_adc_buffer_postenable,
> +	.predisable = &iio_triggered_buffer_predisable,
> +	.postdisable = &vf610_adc_buffer_postdisable,
> +	.validate_scan_mask = &iio_validate_scan_mask_onehot,
> +};
> +
>  static int vf610_adc_reg_access(struct iio_dev *indio_dev,
>  			unsigned reg, unsigned writeval,
>  			unsigned *readval)
> @@ -753,7 +832,7 @@ static int vf610_adc_probe(struct platform_device *pdev)
>  
>  	ret = devm_request_irq(info->dev, irq,
>  				vf610_adc_isr, 0,
> -				dev_name(&pdev->dev), info);
> +				dev_name(&pdev->dev), indio_dev);
>  	if (ret < 0) {
>  		dev_err(&pdev->dev, "failed requesting irq, irq = %d\n", irq);
>  		return ret;
> @@ -806,15 +885,23 @@ static int vf610_adc_probe(struct platform_device *pdev)
>  	vf610_adc_cfg_init(info);
>  	vf610_adc_hw_init(info);
>  
> +	ret = iio_triggered_buffer_setup(indio_dev, &iio_pollfunc_store_time,
> +					NULL, &iio_triggered_buffer_setup_ops);
> +	if (ret < 0) {
> +		dev_err(&pdev->dev, "Couldn't initialise the buffer\n");
> +		goto error_iio_device_register;
> +	}
> +
>  	ret = iio_device_register(indio_dev);
>  	if (ret) {
>  		dev_err(&pdev->dev, "Couldn't register the device.\n");
> -		goto error_iio_device_register;
> +		goto error_adc_buffer_init;
>  	}
>  
>  	return 0;
>  
> -
> +error_adc_buffer_init:
> +	iio_triggered_buffer_cleanup(indio_dev);
>  error_iio_device_register:
>  	clk_disable_unprepare(info->clk);
>  error_adc_clk_enable:
> @@ -829,6 +916,7 @@ static int vf610_adc_remove(struct platform_device *pdev)
>  	struct vf610_adc *info = iio_priv(indio_dev);
>  
>  	iio_device_unregister(indio_dev);
> +	iio_triggered_buffer_cleanup(indio_dev);
>  	regulator_disable(info->vref);
>  	clk_disable_unprepare(info->clk);
>  
> 



From wsa at the-dreams.de  Sat Aug 15 13:24:28 2015
From: wsa at the-dreams.de (Wolfram Sang)
Date: Sat, 15 Aug 2015 22:24:28 +0200
Subject: [PATCH 1/2] i2c: add i2c-lpc2k driver
In-Reply-To: <1436741242-13489-2-git-send-email-manabian@gmail.com>
References: <1436741242-13489-1-git-send-email-manabian@gmail.com>
 <1436741242-13489-2-git-send-email-manabian@gmail.com>
Message-ID: <20150815202423.GD3463@katana>

On Mon, Jul 13, 2015 at 12:47:21AM +0200, Joachim Eastwood wrote:
> Add support for the I2C controller found on several NXP devices
> including LPC2xxx, LPC178x/7x and LPC18xx/43xx. The controller
> is implemented as a state machine and the driver act upon the
> state changes when the bus is accessed.
> 
> The I2C controller supports master/slave operation, bus
> arbitration, programmable clock rate, and speeds up to 1 Mbit/s.
> 
> Signed-off-by: Joachim Eastwood <manabian at gmail.com>

Thanks for the submission! Looking mostly good already.

> +static void i2c_lpc2k_pump_msg(struct lpc2k_i2c *i2c)
> +{
> +	unsigned char data;
> +	u32 status;
> +
> +	/*
> +	 * I2C in the LPC2xxx series is basically a state machine.
> +	 * Just run through the steps based on the current status.
> +	 */
> +	status = readl(i2c->reg_base + LPC24XX_I2STAT);
> +
> +	switch (status) {
> +	case M_START:
> +	case M_REPSTART:
> +		/* Start bit was just sent out, send out addr and dir */
> +		data = (i2c->msg->addr << 1);
> +		if (i2c->msg->flags & I2C_M_RD)
> +			data |= 1;
> +
> +		writel(data, i2c->reg_base + LPC24XX_I2DAT);
> +		writel(LPC24XX_STA, i2c->reg_base + LPC24XX_I2CONCLR);
> +
> +		dev_dbg(&i2c->adap.dev, "Start sent with addr 0x%02x\n", data);

I assume the driver is basically working. So, in my book, most of this
debug output is useful when the driver was developed, not so much
afterwards. Also, it is printed in interrupt context possibly causing
latency. However, the information is useful for understanding the
driver, so I'd suggest to convert them into comments?

> +	i2c->adap.nr = pdev->id;
> +
> +	ret = i2c_add_numbered_adapter(&i2c->adap);

Intended? Most DT enabled drivers simply user i2c_add_adapter(). The
core then takes care of aliases defined in DT.

And please have a look at Documentation/i2c/fault-codes. Arbitration
Lost should be -EAGAIN, NACK should be -ENXIO, and so forth...

Thanks,

   Wolfram



From arnd at arndb.de  Sat Aug 15 13:46:14 2015
From: arnd at arndb.de (Arnd Bergmann)
Date: Sat, 15 Aug 2015 22:46:14 +0200
Subject: [PATCH] spi: Mediatek: fixup cpu_to_le32 incorrect usage
In-Reply-To: <1439467601-10209-1-git-send-email-leilk.liu@mediatek.com>
References: <1439467601-10209-1-git-send-email-leilk.liu@mediatek.com>
Message-ID: <3523801.O835HG5rEa@wuerfel>

On Thursday 13 August 2015 20:06:41 Leilk Liu wrote:
> diff --git a/drivers/spi/spi-mt65xx.c b/drivers/spi/spi-mt65xx.c
> index ae645fa..519f50c 100644
> --- a/drivers/spi/spi-mt65xx.c
> +++ b/drivers/spi/spi-mt65xx.c
> @@ -359,11 +359,9 @@ static void mtk_spi_setup_dma_addr(struct spi_master *master,
>         struct mtk_spi *mdata = spi_master_get_devdata(master);
>  
>         if (mdata->tx_sgl)
> -               writel((__force u32)cpu_to_le32(xfer->tx_dma),
> -                      mdata->base + SPI_TX_SRC_REG);
> +               writel(xfer->tx_dma, mdata->base + SPI_TX_SRC_REG);
>         if (mdata->rx_sgl)
> -               writel((__force u32)cpu_to_le32(xfer->rx_dma),
> -                      mdata->base + SPI_RX_DST_REG);
> +               writel(xfer->rx_dma, mdata->base + SPI_RX_DST_REG);
>  }
>  
>  static int mtk_spi_fifo_transfer(struct spi_master *master,
> -- 
> 

This change looks good, but after I've briefly looked at the current driver,
I found at least one more location that looks like an endianess bug:


+static int mtk_spi_fifo_transfer(struct spi_master *master,
+                                struct spi_device *spi,
+                                struct spi_transfer *xfer)
+{
...
+
+       for (i = 0; i < cnt; i++)
+               writel(*((u32 *)xfer->tx_buf + i),
+                      mdata->base + SPI_TX_DATA_REG);
+
+       mtk_spi_enable_transfer(master);
+
+       return 1;
+}

Here, you write data into a FIFO register using an accessor that converts
to little-endian. In contrast, the DMA based accessor apparently has
no byte swap, so most likely one of the two is broken on big-endian
systems. My guess is that the look above is wrong, and you need to
use iowrite32_rep() instead, so you always write into the FIFO in
the byte stream order (first byte to last byte) rather than swapping
32-bit entities.

The other suspicious part is this:

+       reg_val |= (chip_config->tx_endian << SPI_CMD_TX_ENDIAN_OFFSET);
+       reg_val |= (chip_config->rx_endian << SPI_CMD_RX_ENDIAN_OFFSET);

It's not clear what the tx_endian/rx_endian bits refer to and why you
can't just always set the register interface to little-endian. If it's
set to big-endian, you probably need to add more byte swaps in the
driver.

	Arnd


From manabian at gmail.com  Sat Aug 15 14:57:31 2015
From: manabian at gmail.com (Joachim Eastwood)
Date: Sat, 15 Aug 2015 23:57:31 +0200
Subject: [PATCH 1/2] i2c: add i2c-lpc2k driver
In-Reply-To: <20150815202423.GD3463@katana>
References: <1436741242-13489-1-git-send-email-manabian@gmail.com>
 <1436741242-13489-2-git-send-email-manabian@gmail.com>
 <20150815202423.GD3463@katana>
Message-ID: <CAGhQ9VxXqzM6CObsxkUKLur99SE5GGYiXAQ7hEFNiMJAXR4sbw@mail.gmail.com>

Hi Wolfram,

On 15 August 2015 at 22:24, Wolfram Sang <wsa at the-dreams.de> wrote:
> On Mon, Jul 13, 2015 at 12:47:21AM +0200, Joachim Eastwood wrote:
>> Add support for the I2C controller found on several NXP devices
>> including LPC2xxx, LPC178x/7x and LPC18xx/43xx. The controller
>> is implemented as a state machine and the driver act upon the
>> state changes when the bus is accessed.
>>
>> The I2C controller supports master/slave operation, bus
>> arbitration, programmable clock rate, and speeds up to 1 Mbit/s.
>>
>> Signed-off-by: Joachim Eastwood <manabian at gmail.com>
>
> Thanks for the submission! Looking mostly good already.
>
>> +static void i2c_lpc2k_pump_msg(struct lpc2k_i2c *i2c)
>> +{
>> +     unsigned char data;
>> +     u32 status;
>> +
>> +     /*
>> +      * I2C in the LPC2xxx series is basically a state machine.
>> +      * Just run through the steps based on the current status.
>> +      */
>> +     status = readl(i2c->reg_base + LPC24XX_I2STAT);
>> +
>> +     switch (status) {
>> +     case M_START:
>> +     case M_REPSTART:
>> +             /* Start bit was just sent out, send out addr and dir */
>> +             data = (i2c->msg->addr << 1);
>> +             if (i2c->msg->flags & I2C_M_RD)
>> +                     data |= 1;
>> +
>> +             writel(data, i2c->reg_base + LPC24XX_I2DAT);
>> +             writel(LPC24XX_STA, i2c->reg_base + LPC24XX_I2CONCLR);
>> +
>> +             dev_dbg(&i2c->adap.dev, "Start sent with addr 0x%02x\n", data);
>
> I assume the driver is basically working. So, in my book, most of this
> debug output is useful when the driver was developed, not so much
> afterwards. Also, it is printed in interrupt context possibly causing
> latency. However, the information is useful for understanding the
> driver, so I'd suggest to convert them into comments?

I'll go through all the dev_dbg stuff with what you wrote in mind.
Think I'll end up with removing most of it.

Think most of the debugging stuff was added by Emcraft while they were
bring it up on lpc178x and lpc18xx.


>> +     i2c->adap.nr = pdev->id;
>> +
>> +     ret = i2c_add_numbered_adapter(&i2c->adap);
>
> Intended? Most DT enabled drivers simply user i2c_add_adapter(). The
> core then takes care of aliases defined in DT.

No, it's not intended. It's an old driver and I just didn't know about
i2c_add_adapter(). I'll change it in the next version.


> And please have a look at Documentation/i2c/fault-codes. Arbitration
> Lost should be -EAGAIN, NACK should be -ENXIO, and so forth...

Ok, will do.


Thanks for looking, Wolfram. I'll address your comments and try to
send out a new version tomorrow.


regards,
Joachim Eastwood


From zajec5 at gmail.com  Sat Aug 15 23:13:25 2015
From: zajec5 at gmail.com (=?UTF-8?q?Rafa=C5=82=20Mi=C5=82ecki?=)
Date: Sun, 16 Aug 2015 08:13:25 +0200
Subject: [PATCH] ARM: tegra: add "jedec,spi-nor" flash compatible binding
Message-ID: <1439705605-9127-1-git-send-email-zajec5@gmail.com>

Starting with commit 8947e396a829 ("Documentation: dt: mtd: replace
"nor-jedec" binding with "jedec, spi-nor"") we have "jedec,spi-nor"
binding indicating support for JEDEC identification.

Use it for all flashes that are supposed to support READ ID op according
to the datasheets.

Signed-off-by: Rafa? Mi?ecki <zajec5 at gmail.com>
---
 arch/arm/boot/dts/tegra114-dalmore.dts    | 2 +-
 arch/arm/boot/dts/tegra124-jetson-tk1.dts | 2 +-
 arch/arm/boot/dts/tegra124-nyan.dtsi      | 2 +-
 arch/arm/boot/dts/tegra124-venice2.dts    | 2 +-
 arch/arm/boot/dts/tegra20-trimslice.dts   | 2 +-
 arch/arm/boot/dts/tegra30-beaver.dts      | 2 +-
 arch/arm/boot/dts/tegra30-cardhu.dtsi     | 2 +-
 7 files changed, 7 insertions(+), 7 deletions(-)

diff --git a/arch/arm/boot/dts/tegra114-dalmore.dts b/arch/arm/boot/dts/tegra114-dalmore.dts
index 8b7aa0d..5de23de 100644
--- a/arch/arm/boot/dts/tegra114-dalmore.dts
+++ b/arch/arm/boot/dts/tegra114-dalmore.dts
@@ -1082,7 +1082,7 @@
 		status = "okay";
 		spi-max-frequency = <25000000>;
 		spi-flash at 0 {
-			compatible = "winbond,w25q32dw";
+			compatible = "winbond,w25q32dw", "jedec,spi-nor";
 			reg = <0>;
 			spi-max-frequency = <20000000>;
 		};
diff --git a/arch/arm/boot/dts/tegra124-jetson-tk1.dts b/arch/arm/boot/dts/tegra124-jetson-tk1.dts
index bd43ed6..44097c6 100644
--- a/arch/arm/boot/dts/tegra124-jetson-tk1.dts
+++ b/arch/arm/boot/dts/tegra124-jetson-tk1.dts
@@ -1611,7 +1611,7 @@
 		status = "okay";
 		spi-max-frequency = <25000000>;
 		spi-flash at 0 {
-			compatible = "winbond,w25q32dw";
+			compatible = "winbond,w25q32dw", "jedec,spi-nor";
 			reg = <0>;
 			spi-max-frequency = <20000000>;
 		};
diff --git a/arch/arm/boot/dts/tegra124-nyan.dtsi b/arch/arm/boot/dts/tegra124-nyan.dtsi
index a9aec23..7d26f49 100644
--- a/arch/arm/boot/dts/tegra124-nyan.dtsi
+++ b/arch/arm/boot/dts/tegra124-nyan.dtsi
@@ -343,7 +343,7 @@
 		spi-max-frequency = <25000000>;
 
 		flash at 0 {
-			compatible = "winbond,w25q32dw";
+			compatible = "winbond,w25q32dw", "jedec,spi-nor";
 			spi-max-frequency = <25000000>;
 			reg = <0>;
 		};
diff --git a/arch/arm/boot/dts/tegra124-venice2.dts b/arch/arm/boot/dts/tegra124-venice2.dts
index 79e724b..4decb3c 100644
--- a/arch/arm/boot/dts/tegra124-venice2.dts
+++ b/arch/arm/boot/dts/tegra124-venice2.dts
@@ -866,7 +866,7 @@
 		status = "okay";
 		spi-max-frequency = <25000000>;
 		spi-flash at 0 {
-			compatible = "winbond,w25q32dw";
+			compatible = "winbond,w25q32dw", "jedec,spi-nor";
 			reg = <0>;
 			spi-max-frequency = <20000000>;
 		};
diff --git a/arch/arm/boot/dts/tegra20-trimslice.dts b/arch/arm/boot/dts/tegra20-trimslice.dts
index d99af4e..c4cff8b 100644
--- a/arch/arm/boot/dts/tegra20-trimslice.dts
+++ b/arch/arm/boot/dts/tegra20-trimslice.dts
@@ -282,7 +282,7 @@
 		status = "okay";
 		spi-max-frequency = <48000000>;
 		spi-flash at 0 {
-			compatible = "winbond,w25q80bl";
+			compatible = "winbond,w25q80bl", "jedec,spi-nor";
 			reg = <0>;
 			spi-max-frequency = <48000000>;
 		};
diff --git a/arch/arm/boot/dts/tegra30-beaver.dts b/arch/arm/boot/dts/tegra30-beaver.dts
index 3dede39..c9d230c 100644
--- a/arch/arm/boot/dts/tegra30-beaver.dts
+++ b/arch/arm/boot/dts/tegra30-beaver.dts
@@ -1884,7 +1884,7 @@
 		status = "okay";
 		spi-max-frequency = <25000000>;
 		spi-flash at 1 {
-			compatible = "winbond,w25q32";
+			compatible = "winbond,w25q32", "jedec,spi-nor";
 			reg = <1>;
 			spi-max-frequency = <20000000>;
 		};
diff --git a/arch/arm/boot/dts/tegra30-cardhu.dtsi b/arch/arm/boot/dts/tegra30-cardhu.dtsi
index bb1ca15..df7f845 100644
--- a/arch/arm/boot/dts/tegra30-cardhu.dtsi
+++ b/arch/arm/boot/dts/tegra30-cardhu.dtsi
@@ -354,7 +354,7 @@
 		status = "okay";
 		spi-max-frequency = <25000000>;
 		spi-flash at 1 {
-			compatible = "winbond,w25q32";
+			compatible = "winbond,w25q32", "jedec,spi-nor";
 			reg = <1>;
 			spi-max-frequency = <20000000>;
 		};
-- 
1.8.4.5



From zajec5 at gmail.com  Sat Aug 15 23:39:17 2015
From: zajec5 at gmail.com (=?UTF-8?q?Rafa=C5=82=20Mi=C5=82ecki?=)
Date: Sun, 16 Aug 2015 08:39:17 +0200
Subject: [PATCH] ARM: dts: imx: add "jedec,spi-nor" flash compatible binding
Message-ID: <1439707157-15091-1-git-send-email-zajec5@gmail.com>

Starting with commit 8947e396a829 ("Documentation: dt: mtd: replace
"nor-jedec" binding with "jedec, spi-nor"") we have "jedec,spi-nor"
binding indicating support for JEDEC identification.

Use it for all flashes that are supposed to support READ ID op according
to the datasheets.

Signed-off-by: Rafa? Mi?ecki <zajec5 at gmail.com>
---
 arch/arm/boot/dts/imx28-evk.dts              | 2 +-
 arch/arm/boot/dts/imx28-m28evk.dts           | 2 +-
 arch/arm/boot/dts/imx50-evk.dts              | 2 +-
 arch/arm/boot/dts/imx53-smd.dts              | 2 +-
 arch/arm/boot/dts/imx6dl-rex-basic.dts       | 2 +-
 arch/arm/boot/dts/imx6q-dmo-edmqmx6.dts      | 2 +-
 arch/arm/boot/dts/imx6q-gw5400-a.dts         | 2 +-
 arch/arm/boot/dts/imx6q-rex-pro.dts          | 2 +-
 arch/arm/boot/dts/imx6qdl-aristainetos.dtsi  | 2 +-
 arch/arm/boot/dts/imx6qdl-aristainetos2.dtsi | 2 +-
 arch/arm/boot/dts/imx6qdl-dfi-fs700-m60.dtsi | 2 +-
 arch/arm/boot/dts/imx6qdl-nitrogen6x.dtsi    | 2 +-
 arch/arm/boot/dts/imx6qdl-phytec-pfla02.dtsi | 2 +-
 arch/arm/boot/dts/imx6qdl-sabreauto.dtsi     | 2 +-
 arch/arm/boot/dts/imx6qdl-sabrelite.dtsi     | 2 +-
 arch/arm/boot/dts/imx6qdl-sabresd.dtsi       | 2 +-
 arch/arm/boot/dts/imx6sl-evk.dts             | 2 +-
 arch/arm/boot/dts/imx6sx-sdb-reva.dts        | 4 ++--
 arch/arm/boot/dts/imx6sx-sdb.dts             | 4 ++--
 19 files changed, 21 insertions(+), 21 deletions(-)

diff --git a/arch/arm/boot/dts/imx28-evk.dts b/arch/arm/boot/dts/imx28-evk.dts
index 279249b..e3ef94a 100644
--- a/arch/arm/boot/dts/imx28-evk.dts
+++ b/arch/arm/boot/dts/imx28-evk.dts
@@ -57,7 +57,7 @@
 				flash: m25p80 at 0 {
 					#address-cells = <1>;
 					#size-cells = <1>;
-					compatible = "sst,sst25vf016b";
+					compatible = "sst,sst25vf016b", "jedec,spi-nor";
 					spi-max-frequency = <40000000>;
 					reg = <0>;
 				};
diff --git a/arch/arm/boot/dts/imx28-m28evk.dts b/arch/arm/boot/dts/imx28-m28evk.dts
index e35cc6b..8d04e57 100644
--- a/arch/arm/boot/dts/imx28-m28evk.dts
+++ b/arch/arm/boot/dts/imx28-m28evk.dts
@@ -41,7 +41,7 @@
 				flash: m25p80 at 0 {
 					#address-cells = <1>;
 					#size-cells = <1>;
-					compatible = "m25p80";
+					compatible = "m25p80", "jedec,spi-nor";
 					spi-max-frequency = <40000000>;
 					reg = <0>;
 				};
diff --git a/arch/arm/boot/dts/imx50-evk.dts b/arch/arm/boot/dts/imx50-evk.dts
index 1b22512..27d763c 100644
--- a/arch/arm/boot/dts/imx50-evk.dts
+++ b/arch/arm/boot/dts/imx50-evk.dts
@@ -33,7 +33,7 @@
 	flash: m25p32 at 1 {
 		#address-cells = <1>;
 		#size-cells = <1>;
-		compatible = "m25p32", "m25p80";
+		compatible = "m25p32", "jedec,spi-nor";
 		spi-max-frequency = <25000000>;
 		reg = <1>;
 
diff --git a/arch/arm/boot/dts/imx53-smd.dts b/arch/arm/boot/dts/imx53-smd.dts
index 1d32557..fd3a8fe 100644
--- a/arch/arm/boot/dts/imx53-smd.dts
+++ b/arch/arm/boot/dts/imx53-smd.dts
@@ -76,7 +76,7 @@
 	flash: m25p32 at 1 {
 		#address-cells = <1>;
 		#size-cells = <1>;
-		compatible = "st,m25p32", "st,m25p";
+		compatible = "st,m25p32", "st,m25p", "jedec,spi-nor";
 		spi-max-frequency = <20000000>;
 		reg = <1>;
 
diff --git a/arch/arm/boot/dts/imx6dl-rex-basic.dts b/arch/arm/boot/dts/imx6dl-rex-basic.dts
index b13845c..c3a14a4 100644
--- a/arch/arm/boot/dts/imx6dl-rex-basic.dts
+++ b/arch/arm/boot/dts/imx6dl-rex-basic.dts
@@ -23,7 +23,7 @@
 
 &ecspi3 {
 	flash: m25p80 at 0 {
-		compatible = "sst,sst25vf016b";
+		compatible = "sst,sst25vf016b", "jedec,spi-nor";
 		spi-max-frequency = <20000000>;
 		reg = <0>;
 	};
diff --git a/arch/arm/boot/dts/imx6q-dmo-edmqmx6.dts b/arch/arm/boot/dts/imx6q-dmo-edmqmx6.dts
index 4fa2543..364578d 100644
--- a/arch/arm/boot/dts/imx6q-dmo-edmqmx6.dts
+++ b/arch/arm/boot/dts/imx6q-dmo-edmqmx6.dts
@@ -109,7 +109,7 @@
 	status = "okay";
 
 	flash: m25p80 at 0 {
-		compatible = "m25p80";
+		compatible = "m25p80", "jedec,spi-nor";
 		spi-max-frequency = <40000000>;
 		reg = <0>;
 	};
diff --git a/arch/arm/boot/dts/imx6q-gw5400-a.dts b/arch/arm/boot/dts/imx6q-gw5400-a.dts
index 822ffb2..58adf17 100644
--- a/arch/arm/boot/dts/imx6q-gw5400-a.dts
+++ b/arch/arm/boot/dts/imx6q-gw5400-a.dts
@@ -145,7 +145,7 @@
 	status = "okay";
 
 	flash: m25p80 at 0 {
-		compatible = "sst,w25q256";
+		compatible = "sst,w25q256", "jedec,spi-nor";
 		spi-max-frequency = <30000000>;
 		reg = <0>;
 	};
diff --git a/arch/arm/boot/dts/imx6q-rex-pro.dts b/arch/arm/boot/dts/imx6q-rex-pro.dts
index 3c2852b..90ea61a 100644
--- a/arch/arm/boot/dts/imx6q-rex-pro.dts
+++ b/arch/arm/boot/dts/imx6q-rex-pro.dts
@@ -23,7 +23,7 @@
 
 &ecspi3 {
 	flash: m25p80 at 0 {
-		compatible = "sst,sst25vf032b";
+		compatible = "sst,sst25vf032b", "jedec,spi-nor";
 		spi-max-frequency = <20000000>;
 		reg = <0>;
 	};
diff --git a/arch/arm/boot/dts/imx6qdl-aristainetos.dtsi b/arch/arm/boot/dts/imx6qdl-aristainetos.dtsi
index e6d9195..0bba6dc 100644
--- a/arch/arm/boot/dts/imx6qdl-aristainetos.dtsi
+++ b/arch/arm/boot/dts/imx6qdl-aristainetos.dtsi
@@ -109,7 +109,7 @@
 	flash: m25p80 at 0 {
 		#address-cells = <1>;
 		#size-cells = <1>;
-		compatible = "micron,n25q128a11";
+		compatible = "micron,n25q128a11", "jedec,spi-nor";
 		spi-max-frequency = <20000000>;
 		reg = <0>;
 	};
diff --git a/arch/arm/boot/dts/imx6qdl-aristainetos2.dtsi b/arch/arm/boot/dts/imx6qdl-aristainetos2.dtsi
index 1d85de2..54dd0bc 100644
--- a/arch/arm/boot/dts/imx6qdl-aristainetos2.dtsi
+++ b/arch/arm/boot/dts/imx6qdl-aristainetos2.dtsi
@@ -141,7 +141,7 @@
 	flash: m25p80 at 1 {
 		#address-cells = <1>;
 		#size-cells = <1>;
-		compatible = "micron,n25q128a11";
+		compatible = "micron,n25q128a11", "jedec,spi-nor";
 		spi-max-frequency = <20000000>;
 		reg = <1>;
 	};
diff --git a/arch/arm/boot/dts/imx6qdl-dfi-fs700-m60.dtsi b/arch/arm/boot/dts/imx6qdl-dfi-fs700-m60.dtsi
index 2c253d6..880b47b 100644
--- a/arch/arm/boot/dts/imx6qdl-dfi-fs700-m60.dtsi
+++ b/arch/arm/boot/dts/imx6qdl-dfi-fs700-m60.dtsi
@@ -36,7 +36,7 @@
 	flash: m25p80 at 0 {
 		#address-cells = <1>;
 		#size-cells = <1>;
-		compatible = "sst,sst25vf040b", "m25p80";
+		compatible = "sst,sst25vf040b", "jedec,spi-nor";
 		spi-max-frequency = <20000000>;
 		reg = <0>;
 	};
diff --git a/arch/arm/boot/dts/imx6qdl-nitrogen6x.dtsi b/arch/arm/boot/dts/imx6qdl-nitrogen6x.dtsi
index 3af16df..a3b8456 100644
--- a/arch/arm/boot/dts/imx6qdl-nitrogen6x.dtsi
+++ b/arch/arm/boot/dts/imx6qdl-nitrogen6x.dtsi
@@ -157,7 +157,7 @@
 	status = "okay";
 
 	flash: m25p80 at 0 {
-		compatible = "sst,sst25vf016b";
+		compatible = "sst,sst25vf016b", "jedec,spi-nor";
 		spi-max-frequency = <20000000>;
 		reg = <0>;
 	};
diff --git a/arch/arm/boot/dts/imx6qdl-phytec-pfla02.dtsi b/arch/arm/boot/dts/imx6qdl-phytec-pfla02.dtsi
index 1ce6133..d6e1402 100644
--- a/arch/arm/boot/dts/imx6qdl-phytec-pfla02.dtsi
+++ b/arch/arm/boot/dts/imx6qdl-phytec-pfla02.dtsi
@@ -80,7 +80,7 @@
 	cs-gpios = <&gpio4 24 0>;
 
 	flash at 0 {
-		compatible = "m25p80";
+		compatible = "m25p80", "jedec,spi-nor";
 		spi-max-frequency = <20000000>;
 		reg = <0>;
 	};
diff --git a/arch/arm/boot/dts/imx6qdl-sabreauto.dtsi b/arch/arm/boot/dts/imx6qdl-sabreauto.dtsi
index 3b24b126..bfa740a 100644
--- a/arch/arm/boot/dts/imx6qdl-sabreauto.dtsi
+++ b/arch/arm/boot/dts/imx6qdl-sabreauto.dtsi
@@ -55,7 +55,7 @@
 	flash: m25p80 at 0 {
 		#address-cells = <1>;
 		#size-cells = <1>;
-		compatible = "st,m25p32";
+		compatible = "st,m25p32", "jedec,spi-nor";
 		spi-max-frequency = <20000000>;
 		reg = <0>;
 	};
diff --git a/arch/arm/boot/dts/imx6qdl-sabrelite.dtsi b/arch/arm/boot/dts/imx6qdl-sabrelite.dtsi
index e00c44f..d192443 100644
--- a/arch/arm/boot/dts/imx6qdl-sabrelite.dtsi
+++ b/arch/arm/boot/dts/imx6qdl-sabrelite.dtsi
@@ -156,7 +156,7 @@
 	status = "okay";
 
 	flash: m25p80 at 0 {
-		compatible = "sst,sst25vf016b";
+		compatible = "sst,sst25vf016b", "jedec,spi-nor";
 		spi-max-frequency = <20000000>;
 		reg = <0>;
 	};
diff --git a/arch/arm/boot/dts/imx6qdl-sabresd.dtsi b/arch/arm/boot/dts/imx6qdl-sabresd.dtsi
index a626e6d..372a340 100644
--- a/arch/arm/boot/dts/imx6qdl-sabresd.dtsi
+++ b/arch/arm/boot/dts/imx6qdl-sabresd.dtsi
@@ -151,7 +151,7 @@
 	flash: m25p80 at 0 {
 		#address-cells = <1>;
 		#size-cells = <1>;
-		compatible = "st,m25p32";
+		compatible = "st,m25p32", "jedec,spi-nor";
 		spi-max-frequency = <20000000>;
 		reg = <0>;
 	};
diff --git a/arch/arm/boot/dts/imx6sl-evk.dts b/arch/arm/boot/dts/imx6sl-evk.dts
index 945887d..bc70c93 100644
--- a/arch/arm/boot/dts/imx6sl-evk.dts
+++ b/arch/arm/boot/dts/imx6sl-evk.dts
@@ -126,7 +126,7 @@
 	flash: m25p80 at 0 {
 		#address-cells = <1>;
 		#size-cells = <1>;
-		compatible = "st,m25p32";
+		compatible = "st,m25p32", "jedec,spi-nor";
 		spi-max-frequency = <20000000>;
 		reg = <0>;
 	};
diff --git a/arch/arm/boot/dts/imx6sx-sdb-reva.dts b/arch/arm/boot/dts/imx6sx-sdb-reva.dts
index c76b87c..7100547 100644
--- a/arch/arm/boot/dts/imx6sx-sdb-reva.dts
+++ b/arch/arm/boot/dts/imx6sx-sdb-reva.dts
@@ -129,7 +129,7 @@
 		reg = <0>;
 		#address-cells = <1>;
 		#size-cells = <1>;
-		compatible = "spansion,s25fl128s";
+		compatible = "spansion,s25fl128s", "jedec,spi-nor";
 		spi-max-frequency = <66000000>;
 	};
 
@@ -137,7 +137,7 @@
 		reg = <1>;
 		#address-cells = <1>;
 		#size-cells = <1>;
-		compatible = "spansion,s25fl128s";
+		compatible = "spansion,s25fl128s", "jedec,spi-nor";
 		spi-max-frequency = <66000000>;
 	};
 };
diff --git a/arch/arm/boot/dts/imx6sx-sdb.dts b/arch/arm/boot/dts/imx6sx-sdb.dts
index 0bfc4e7..0ad164a 100644
--- a/arch/arm/boot/dts/imx6sx-sdb.dts
+++ b/arch/arm/boot/dts/imx6sx-sdb.dts
@@ -130,7 +130,7 @@
 	flash0: n25q256a at 0 {
 		#address-cells = <1>;
 		#size-cells = <1>;
-		compatible = "micron,n25q256a";
+		compatible = "micron,n25q256a", "jedec,spi-nor";
 		spi-max-frequency = <29000000>;
 		reg = <0>;
 	};
@@ -138,7 +138,7 @@
 	flash1: n25q256a at 1 {
 		#address-cells = <1>;
 		#size-cells = <1>;
-		compatible = "micron,n25q256a";
+		compatible = "micron,n25q256a", "jedec,spi-nor";
 		spi-max-frequency = <29000000>;
 		reg = <1>;
 	};
-- 
1.8.4.5



From emil.l.velikov at gmail.com  Sun Aug 16 01:56:33 2015
From: emil.l.velikov at gmail.com (Emil Velikov)
Date: Sun, 16 Aug 2015 09:56:33 +0100
Subject: [PATCH 2/4] drm: Add support for ARM's HDLCD controller.
In-Reply-To: <1438784892-27888-3-git-send-email-Liviu.Dudau@arm.com>
References: <1438784892-27888-1-git-send-email-Liviu.Dudau@arm.com>
 <1438784892-27888-3-git-send-email-Liviu.Dudau@arm.com>
Message-ID: <CACvgo537C6SRfhMTNoE4cSLJukcXuKLvt1TRykynX--ybEhmaQ@mail.gmail.com>

Hi Liviu,

On 5 August 2015 at 15:28, Liviu Dudau <Liviu.Dudau at arm.com> wrote:
> The HDLCD controller is a display controller that supports resolutions
> up to 4096x4096 pixels. It is present on various development boards
> produced by ARM Ltd and emulated by the latest Fast Models from the
> company.
>
I believe there is a unofficial requirement(?) for new drm drivers to
use atomic modesetting. Not 100% sure on this one though. The
following drivers: tegra, msm, rcar-du, i915, and Daniel's blog [1]
[2] cat provide some information on the topic.

The driver seems to has has a bit of dead code guarded by
HDLCD_*_UNDERRUN. Perhaps these macros should become build or runtime
switch(es) ?

Most DRM drivers do not threat dma, bus_error, vsync and/or underrun
interrupts as debug functionality. They are of limited use in this
driver, presently, yet the CONFIG_DEBUG_FS guard seems a bit strange
imho.

Cheers,
Emil

[1] http://blog.ffwll.ch/2014/11/atomic-modeset-support-for-kms-drivers.html
[2] http://blog.ffwll.ch/2015/01/update-for-atomic-display-updates.html


From ian.campbell at citrix.com  Sun Aug 16 02:01:11 2015
From: ian.campbell at citrix.com (Ian Campbell)
Date: Sun, 16 Aug 2015 10:01:11 +0100
Subject: [PATCH v5] dtb: Create a common home for cross-architecture
 dtsi files.
In-Reply-To: <CAL_JsqKv2aOEM-U7JNZnaHomA6HFBSFhSLZ-zhp7c20s6gQBaQ@mail.gmail.com>
References: <1438618000-1091-1-git-send-email-ian.campbell@citrix.com>
 <1439287646.9747.212.camel@citrix.com>
 <CAL_JsqKv2aOEM-U7JNZnaHomA6HFBSFhSLZ-zhp7c20s6gQBaQ@mail.gmail.com>
Message-ID: <1439715671.3480.21.camel@citrix.com>

On Fri, 2015-08-14 at 16:21 -0500, Rob Herring wrote:
> +arm-soc

I could've sworn I did the same at one point. Obviously not.

> 
> On Tue, Aug 11, 2015 at 5:07 AM, Ian Campbell <
> ian.campbell at citrix.com> wrote:
> > On Mon, 2015-08-03 at 17:06 +0100, Ian Campbell wrote:
> > > Commit 9ccd608070b6 ("arm64: dts: add device tree for ARM SMM
> > > -A53x2 on
> > > LogicTile Express 20MG") added a new dts file to arch/arm64 which
> > > included "../../../../arm/boot/dts/vexpress-v2m-rs1.dtsi", i.e. a
> > > .dtsi supplied by arch/arm.
> > > 
> > > Unfortunately this causes some issues for the split device tree
> > > repository[0], since things get moved around there. In that 
> > > context
> > > the new .dts ends up at src/arm64/arm/vexpress-v2f-1xv7
> > > -ca53x2.dts
> > > while the include is at src/arm/vexpress-v2m-rs1.dtsi.
> > 
> > Hi Grant,
> > 
> > Do you think there is any chance of getting this into 4.2-rc$NEXT 
> > or shall
> > we wait until 4.3? I'm assuming this should go via the DT tree, but 
> > maybe
> > it should go via an ARM tree?
> 
> I was assuming this would go thru the arm-soc tree which is why I
> acked it. It is getting a bit late for 4.2 at this point, but I guess
> the standalone tree remains broken for these platforms until this is
> done.

Correct.

>  Probably not such a big deal in grand scheme of things.

I guess not. FWIW I've not pushed since the breakage started happening,
so the split tree isn't broken, but it's also now however many weeks
behind. Once 4.3-rc1 arrives with this fixed I'll push all the 4.2-rcN
and 4.2 as well.

Ian.


From alexandre.belloni at free-electrons.com  Sun Aug 16 02:23:45 2015
From: alexandre.belloni at free-electrons.com (Alexandre Belloni)
Date: Sun, 16 Aug 2015 11:23:45 +0200
Subject: [PATCH v4 3/4] clocksource: tcb_clksrc: fix setup_clkevents error path
In-Reply-To: <1439717026-30634-1-git-send-email-alexandre.belloni@free-electrons.com>
References: <1439717026-30634-1-git-send-email-alexandre.belloni@free-electrons.com>
Message-ID: <1439717026-30634-4-git-send-email-alexandre.belloni@free-electrons.com>

From: Boris Brezillon <boris.brezillon at free-electrons.com>

t2_clk is already disabled before request_irq(), it must not be disabled
again.

Signed-off-by: Boris Brezillon <boris.brezillon at free-electrons.com>
Signed-off-by: Alexandre Belloni <alexandre.belloni at free-electrons.com>
Acked-by: Daniel Lezcano <daniel.lezcano at linaro.org>
---
 drivers/clocksource/tcb_clksrc.c | 2 +-
 1 file changed, 1 insertion(+), 1 deletion(-)

diff --git a/drivers/clocksource/tcb_clksrc.c b/drivers/clocksource/tcb_clksrc.c
index 8bdbc45c6dad..b9b7277173c2 100644
--- a/drivers/clocksource/tcb_clksrc.c
+++ b/drivers/clocksource/tcb_clksrc.c
@@ -199,7 +199,7 @@ static int __init setup_clkevents(struct atmel_tc *tc, int clk32k_divisor_idx)
 
 	ret = request_irq(irq, ch2_irq, IRQF_TIMER, "tc_clkevt", &clkevt);
 	if (ret) {
-		clk_disable_unprepare(t2_clk);
+		clk_unprepare(t2_clk);
 		return ret;
 	}
 
-- 
2.1.4



From alexandre.belloni at free-electrons.com  Sun Aug 16 02:23:44 2015
From: alexandre.belloni at free-electrons.com (Alexandre Belloni)
Date: Sun, 16 Aug 2015 11:23:44 +0200
Subject: [PATCH v4 2/4] clocksource: atmel-st: get and use slow clock
In-Reply-To: <1439717026-30634-1-git-send-email-alexandre.belloni@free-electrons.com>
References: <1439717026-30634-1-git-send-email-alexandre.belloni@free-electrons.com>
Message-ID: <1439717026-30634-3-git-send-email-alexandre.belloni@free-electrons.com>

The current slow clock rate is hardcoded. Properly get the slow clock
and use its rate.

Signed-off-by: Alexandre Belloni <alexandre.belloni at free-electrons.com>
Acked-by: Daniel Lezcano <daniel.lezcano at linaro.org>
---
 drivers/clocksource/timer-atmel-st.c | 31 ++++++++++++++++++++++---------
 1 file changed, 22 insertions(+), 9 deletions(-)

diff --git a/drivers/clocksource/timer-atmel-st.c b/drivers/clocksource/timer-atmel-st.c
index 1692e17e096b..51dcbae0a654 100644
--- a/drivers/clocksource/timer-atmel-st.c
+++ b/drivers/clocksource/timer-atmel-st.c
@@ -22,6 +22,7 @@
 #include <linux/kernel.h>
 #include <linux/interrupt.h>
 #include <linux/irq.h>
+#include <linux/clk.h>
 #include <linux/clockchips.h>
 #include <linux/export.h>
 #include <linux/mfd/syscon.h>
@@ -33,9 +34,7 @@ static unsigned long last_crtr;
 static u32 irqmask;
 static struct clock_event_device clkevt;
 static struct regmap *regmap_st;
-
-#define AT91_SLOW_CLOCK		32768
-#define RM9200_TIMER_LATCH	((AT91_SLOW_CLOCK + HZ/2) / HZ)
+static int timer_latch;
 
 /*
  * The ST_CRTR is updated asynchronously to the master clock ... but
@@ -82,8 +81,8 @@ static irqreturn_t at91rm9200_timer_interrupt(int irq, void *dev_id)
 	if (sr & AT91_ST_PITS) {
 		u32	crtr = read_CRTR();
 
-		while (((crtr - last_crtr) & AT91_ST_CRTV) >= RM9200_TIMER_LATCH) {
-			last_crtr += RM9200_TIMER_LATCH;
+		while (((crtr - last_crtr) & AT91_ST_CRTV) >= timer_latch) {
+			last_crtr += timer_latch;
 			clkevt.event_handler(&clkevt);
 		}
 		return IRQ_HANDLED;
@@ -120,7 +119,7 @@ clkevt32k_mode(enum clock_event_mode mode, struct clock_event_device *dev)
 	case CLOCK_EVT_MODE_PERIODIC:
 		/* PIT for periodic irqs; fixed rate of 1/HZ */
 		irqmask = AT91_ST_PITS;
-		regmap_write(regmap_st, AT91_ST_PIMR, RM9200_TIMER_LATCH);
+		regmap_write(regmap_st, AT91_ST_PIMR, timer_latch);
 		break;
 	case CLOCK_EVT_MODE_ONESHOT:
 		/* ALM for oneshot irqs, set by next_event()
@@ -182,7 +181,8 @@ static struct clock_event_device clkevt = {
  */
 static void __init atmel_st_timer_init(struct device_node *node)
 {
-	unsigned int val;
+	struct clk *sclk;
+	unsigned int sclk_rate, val;
 	int irq, ret;
 
 	regmap_st = syscon_node_to_regmap(node);
@@ -206,6 +206,19 @@ static void __init atmel_st_timer_init(struct device_node *node)
 	if (ret)
 		panic(pr_fmt("Unable to setup IRQ\n"));
 
+	sclk = of_clk_get(node, 0);
+	if (IS_ERR(sclk))
+		panic(pr_fmt("Unable to get slow clock\n"));
+
+	clk_prepare_enable(sclk);
+	if (ret)
+		panic(pr_fmt("Could not enable slow clock\n"));
+
+	sclk_rate = clk_get_rate(sclk);
+	if (!sclk_rate)
+		panic(pr_fmt("Invalid slow clock rate\n"));
+	timer_latch = (sclk_rate + HZ / 2) / HZ;
+
 	/* The 32KiHz "Slow Clock" (tick every 30517.58 nanoseconds) is used
 	 * directly for the clocksource and all clockevents, after adjusting
 	 * its prescaler from the 1 Hz default.
@@ -214,11 +227,11 @@ static void __init atmel_st_timer_init(struct device_node *node)
 
 	/* Setup timer clockevent, with minimum of two ticks (important!!) */
 	clkevt.cpumask = cpumask_of(0);
-	clockevents_config_and_register(&clkevt, AT91_SLOW_CLOCK,
+	clockevents_config_and_register(&clkevt, sclk_rate,
 					2, AT91_ST_ALMV);
 
 	/* register clocksource */
-	clocksource_register_hz(&clk32k, AT91_SLOW_CLOCK);
+	clocksource_register_hz(&clk32k, sclk_rate);
 }
 CLOCKSOURCE_OF_DECLARE(atmel_st_timer, "atmel,at91rm9200-st",
 		       atmel_st_timer_init);
-- 
2.1.4



From alexandre.belloni at free-electrons.com  Sun Aug 16 02:23:43 2015
From: alexandre.belloni at free-electrons.com (Alexandre Belloni)
Date: Sun, 16 Aug 2015 11:23:43 +0200
Subject: [PATCH v4 1/4] watchdog: at91sam9: get and use slow clock
In-Reply-To: <1439717026-30634-1-git-send-email-alexandre.belloni@free-electrons.com>
References: <1439717026-30634-1-git-send-email-alexandre.belloni@free-electrons.com>
Message-ID: <1439717026-30634-2-git-send-email-alexandre.belloni@free-electrons.com>

Commit dca1a4b5ff6e ("clk: at91: keep slow clk enabled to prevent system
hang") added a workaround for the slow clock as it is not properly handled
by its users.

Get and use the slow clock as it is necessary for the at91sam9 watchdog.

Signed-off-by: Alexandre Belloni <alexandre.belloni at free-electrons.com>
Reviewed-by: Guenter Roeck <linux at roeck-us.net>
---
Cc: Wim Van Sebroeck <wim at iguana.be>
Cc: linux-watchdog at vger.kernel.org
 drivers/watchdog/at91sam9_wdt.c | 22 ++++++++++++++++++++--
 1 file changed, 20 insertions(+), 2 deletions(-)

diff --git a/drivers/watchdog/at91sam9_wdt.c b/drivers/watchdog/at91sam9_wdt.c
index e4698f7c5f93..7e6acaf3ece4 100644
--- a/drivers/watchdog/at91sam9_wdt.c
+++ b/drivers/watchdog/at91sam9_wdt.c
@@ -17,6 +17,7 @@
 
 #define pr_fmt(fmt) KBUILD_MODNAME ": " fmt
 
+#include <linux/clk.h>
 #include <linux/errno.h>
 #include <linux/init.h>
 #include <linux/interrupt.h>
@@ -90,6 +91,7 @@ struct at91wdt {
 	unsigned long heartbeat;	/* WDT heartbeat in jiffies */
 	bool nowayout;
 	unsigned int irq;
+	struct clk *sclk;
 };
 
 /* ......................................................................... */
@@ -352,15 +354,25 @@ static int __init at91wdt_probe(struct platform_device *pdev)
 	if (IS_ERR(wdt->base))
 		return PTR_ERR(wdt->base);
 
+	wdt->sclk = devm_clk_get(&pdev->dev, NULL);
+	if (IS_ERR(wdt->sclk))
+		return PTR_ERR(wdt->sclk);
+
+	err = clk_prepare_enable(wdt->sclk);
+	if (err) {
+		dev_err(&pdev->dev, "Could not enable slow clock\n");
+		return err;
+	}
+
 	if (pdev->dev.of_node) {
 		err = of_at91wdt_init(pdev->dev.of_node, wdt);
 		if (err)
-			return err;
+			goto err_clk;
 	}
 
 	err = at91_wdt_init(pdev, wdt);
 	if (err)
-		return err;
+		goto err_clk;
 
 	platform_set_drvdata(pdev, wdt);
 
@@ -368,6 +380,11 @@ static int __init at91wdt_probe(struct platform_device *pdev)
 		wdt->wdd.timeout, wdt->nowayout);
 
 	return 0;
+
+err_clk:
+	clk_disable_unprepare(wdt->sclk);
+
+	return err;
 }
 
 static int __exit at91wdt_remove(struct platform_device *pdev)
@@ -377,6 +394,7 @@ static int __exit at91wdt_remove(struct platform_device *pdev)
 
 	pr_warn("I quit now, hardware will probably reboot!\n");
 	del_timer(&wdt->timer);
+	clk_disable_unprepare(wdt->sclk);
 
 	return 0;
 }
-- 
2.1.4



From alexandre.belloni at free-electrons.com  Sun Aug 16 02:23:42 2015
From: alexandre.belloni at free-electrons.com (Alexandre Belloni)
Date: Sun, 16 Aug 2015 11:23:42 +0200
Subject: [PATCH v4 0/4] ARM: at91: Properly handle slow clock
Message-ID: <1439717026-30634-1-git-send-email-alexandre.belloni@free-electrons.com>

Hi,

It was discovered that all the slow clock user were not properly claiming it.
This can end up in a system hang because the last registered user is releasing
it, and it gets disabled.

commit dca1a4b5ff6e ("clk: at91: keep slow clk enabled to prevent system hang")
was a workaround. This series is adding the slow clock to the necessary drivers
to avoid the issue and then removes that workaround.

Changes in v4:
 - enable slow_clk before t2_clk in tcb_clksrc.c
 - properly disable slow_clk in the error path of atmel_tcb_pwm_probe()
 - added Daniel's acks

Cc: Daniel Lezcano <daniel.lezcano at linaro.org>
Cc: linux-pwm at vger.kernel.org
Cc: linux-watchdog at vger.kernel.org
Cc: Thierry Reding <thierry.reding at gmail.com>
Cc: Thomas Gleixner <tglx at linutronix.de>
Cc: Wim Van Sebroeck <wim at iguana.be>

Alexandre Belloni (2):
  watchdog: at91sam9: get and use slow clock
  clocksource: atmel-st: get and use slow clock

Boris Brezillon (2):
  clocksource: tcb_clksrc: fix setup_clkevents error path
  misc: atmel_tclib: get and use slow clock

 drivers/clocksource/tcb_clksrc.c     | 12 ++++++++++--
 drivers/clocksource/timer-atmel-st.c | 31 ++++++++++++++++++++++---------
 drivers/misc/atmel_tclib.c           |  4 ++++
 drivers/pwm/pwm-atmel-tcb.c          | 26 +++++++++++++++++++-------
 drivers/watchdog/at91sam9_wdt.c      | 22 ++++++++++++++++++++--
 include/linux/atmel_tc.h             |  1 +
 6 files changed, 76 insertions(+), 20 deletions(-)

-- 
2.1.4



From alexandre.belloni at free-electrons.com  Sun Aug 16 02:23:46 2015
From: alexandre.belloni at free-electrons.com (Alexandre Belloni)
Date: Sun, 16 Aug 2015 11:23:46 +0200
Subject: [PATCH v4 4/4] misc: atmel_tclib: get and use slow clock
In-Reply-To: <1439717026-30634-1-git-send-email-alexandre.belloni@free-electrons.com>
References: <1439717026-30634-1-git-send-email-alexandre.belloni@free-electrons.com>
Message-ID: <1439717026-30634-5-git-send-email-alexandre.belloni@free-electrons.com>

From: Boris Brezillon <boris.brezillon at free-electrons.com>

Commit dca1a4b5ff6e ("clk: at91: keep slow clk enabled to prevent system
hang") added a workaround for the slow clock as it is not properly handled
by its users.

Get and use the slow clock as it is necessary for the timer counters.

Signed-off-by: Boris Brezillon <boris.brezillon at free-electrons.com>
Signed-off-by: Alexandre Belloni <alexandre.belloni at free-electrons.com>
Acked-by: Greg Kroah-Hartman <gregkh at linuxfoundation.org>
---
Cc: Daniel Lezcano <daniel.lezcano at linaro.org>
Cc: Thierry Reding <thierry.reding at gmail.com>
Cc: linux-pwm at vger.kernel.org
 drivers/clocksource/tcb_clksrc.c | 10 +++++++++-
 drivers/misc/atmel_tclib.c       |  4 ++++
 drivers/pwm/pwm-atmel-tcb.c      | 26 +++++++++++++++++++-------
 include/linux/atmel_tc.h         |  1 +
 4 files changed, 33 insertions(+), 8 deletions(-)

diff --git a/drivers/clocksource/tcb_clksrc.c b/drivers/clocksource/tcb_clksrc.c
index b9b7277173c2..ba1e5d55d3bf 100644
--- a/drivers/clocksource/tcb_clksrc.c
+++ b/drivers/clocksource/tcb_clksrc.c
@@ -184,10 +184,17 @@ static int __init setup_clkevents(struct atmel_tc *tc, int clk32k_divisor_idx)
 	struct clk *t2_clk = tc->clk[2];
 	int irq = tc->irq[2];
 
+	ret = clk_prepare_enable(tc->slow_clk);
+	if (ret)
+		return ret;
+
 	/* try to enable t2 clk to avoid future errors in mode change */
 	ret = clk_prepare_enable(t2_clk);
-	if (ret)
+	if (ret) {
+		clk_disable_unprepare(tc->slow_clk);
 		return ret;
+	}
+
 	clk_disable(t2_clk);
 
 	clkevt.regs = tc->regs;
@@ -200,6 +207,7 @@ static int __init setup_clkevents(struct atmel_tc *tc, int clk32k_divisor_idx)
 	ret = request_irq(irq, ch2_irq, IRQF_TIMER, "tc_clkevt", &clkevt);
 	if (ret) {
 		clk_unprepare(t2_clk);
+		clk_disable_unprepare(tc->slow_clk);
 		return ret;
 	}
 
diff --git a/drivers/misc/atmel_tclib.c b/drivers/misc/atmel_tclib.c
index 0ca05c3ec8d6..ac24a4bd63f7 100644
--- a/drivers/misc/atmel_tclib.c
+++ b/drivers/misc/atmel_tclib.c
@@ -125,6 +125,10 @@ static int __init tc_probe(struct platform_device *pdev)
 	if (IS_ERR(clk))
 		return PTR_ERR(clk);
 
+	tc->slow_clk = devm_clk_get(&pdev->dev, "slow_clk");
+	if (IS_ERR(tc->slow_clk))
+		return PTR_ERR(tc->slow_clk);
+
 	r = platform_get_resource(pdev, IORESOURCE_MEM, 0);
 	tc->regs = devm_ioremap_resource(&pdev->dev, r);
 	if (IS_ERR(tc->regs))
diff --git a/drivers/pwm/pwm-atmel-tcb.c b/drivers/pwm/pwm-atmel-tcb.c
index d14e0677c92d..f64ee392f620 100644
--- a/drivers/pwm/pwm-atmel-tcb.c
+++ b/drivers/pwm/pwm-atmel-tcb.c
@@ -305,7 +305,7 @@ static int atmel_tcb_pwm_config(struct pwm_chip *chip, struct pwm_device *pwm,
 	 */
 	if (i == 5) {
 		i = slowclk;
-		rate = 32768;
+		rate = clk_get_rate(tc->slow_clk);
 		min = div_u64(NSEC_PER_SEC, rate);
 		max = min << tc->tcb_config->counter_width;
 
@@ -387,9 +387,9 @@ static int atmel_tcb_pwm_probe(struct platform_device *pdev)
 
 	tcbpwm = devm_kzalloc(&pdev->dev, sizeof(*tcbpwm), GFP_KERNEL);
 	if (tcbpwm == NULL) {
-		atmel_tc_free(tc);
+		err = -ENOMEM;
 		dev_err(&pdev->dev, "failed to allocate memory\n");
-		return -ENOMEM;
+		goto err_free_tc;
 	}
 
 	tcbpwm->chip.dev = &pdev->dev;
@@ -400,17 +400,27 @@ static int atmel_tcb_pwm_probe(struct platform_device *pdev)
 	tcbpwm->chip.npwm = NPWM;
 	tcbpwm->tc = tc;
 
+	err = clk_prepare_enable(tc->slow_clk);
+	if (err)
+		goto err_free_tc;
+
 	spin_lock_init(&tcbpwm->lock);
 
 	err = pwmchip_add(&tcbpwm->chip);
-	if (err < 0) {
-		atmel_tc_free(tc);
-		return err;
-	}
+	if (err < 0)
+		goto err_disable_clk;
 
 	platform_set_drvdata(pdev, tcbpwm);
 
 	return 0;
+
+err_disable_clk:
+	clk_disable_unprepare(tcbpwm->tc->slow_clk);
+
+err_free_tc:
+	atmel_tc_free(tc);
+
+	return err;
 }
 
 static int atmel_tcb_pwm_remove(struct platform_device *pdev)
@@ -418,6 +428,8 @@ static int atmel_tcb_pwm_remove(struct platform_device *pdev)
 	struct atmel_tcb_pwm_chip *tcbpwm = platform_get_drvdata(pdev);
 	int err;
 
+	clk_disable_unprepare(tcbpwm->tc->slow_clk);
+
 	err = pwmchip_remove(&tcbpwm->chip);
 	if (err < 0)
 		return err;
diff --git a/include/linux/atmel_tc.h b/include/linux/atmel_tc.h
index b87c1c7c242a..468fdfa643f0 100644
--- a/include/linux/atmel_tc.h
+++ b/include/linux/atmel_tc.h
@@ -67,6 +67,7 @@ struct atmel_tc {
 	const struct atmel_tcb_config *tcb_config;
 	int			irq[3];
 	struct clk		*clk[3];
+	struct clk		*slow_clk;
 	struct list_head	node;
 	bool			allocated;
 };
-- 
2.1.4



From geert at linux-m68k.org  Sun Aug 16 02:24:51 2015
From: geert at linux-m68k.org (Geert Uytterhoeven)
Date: Sun, 16 Aug 2015 11:24:51 +0200
Subject: [PATCH 2/9] PM / Domains: Remove dev->driver check for runtime PM
In-Reply-To: <CAMAWPa-0R42thqBo0omn0KK7y0wyxoyaP+wsfoRvXBmWhBytKg@mail.gmail.com>
References: <1438731339-58317-1-git-send-email-lina.iyer@linaro.org>
 <1438731339-58317-3-git-send-email-lina.iyer@linaro.org>
 <7hfv3onv5c.fsf@deeprootsystems.com>
 <CAMuHMdVeffa-jgXuSjDQBKTrhgW-d87OKzs1iXX+4y-9U_AJbg@mail.gmail.com>
 <7hwpwylepx.fsf@deeprootsystems.com>
 <CAMuHMdW-T9rUWXsQeffwtXspHbjfGqo_0G4QMB1o0TwTLJAQAg@mail.gmail.com>
 <CAMAWPa-0R42thqBo0omn0KK7y0wyxoyaP+wsfoRvXBmWhBytKg@mail.gmail.com>
Message-ID: <CAMuHMdV2gDBaPRb3yE=tVPO_pr7PFA6bwhyQE5raumCh_qPXww@mail.gmail.com>

Hi Kevin,

On Fri, Aug 14, 2015 at 7:19 PM, Kevin Hilman <khilman at kernel.org> wrote:
> On Fri, Aug 14, 2015 at 12:24 AM, Geert Uytterhoeven
> <geert at linux-m68k.org> wrote:
>> On Fri, Aug 14, 2015 at 5:40 AM, Kevin Hilman <khilman at kernel.org> wrote:
>>> Geert Uytterhoeven <geert at linux-m68k.org> writes:
>>>> On Wed, Aug 12, 2015 at 9:50 PM, Kevin Hilman <khilman at kernel.org> wrote:
>>>>> This check might have made sense before PM domains, but with PM domains,
>>>>> it's entirely possible to have a simple device without a driver and the
>>>>> PM domain handles all the necesary PM, so I think this check
>>>>> could/should be removed.
>>>>>
>>>>> Thoughts?
>>>>
>>>> Simple devices without a driver aren't handled automatically.
>>>> At minimum, the driver should call pm_runtime_enable(), cfr.
>>>> drivers/bus/simple-pm-bus.c.
>>>
>>> That's correct, and in the proof-of-concept stuff I hacked up and in
>>> Lina's series, the CPU "devices" do indeed to this.  Without that, they
>>> wouldn't end up ever taking this codepath through genpd's
>>> runtime_suspend and power_off hooks.
>>>
>>> Also, I'm not sure if your comment was meant to be an objection to the
>>> patch?  or if you're OK with it.
>>
>> My comment was purely meant as a response to "it's entirely possible to have a
>> simple device without a driver and the PM domain handles all the necesary PM".
>
> Right, so if the PM domain does the pm_runtime_enable() for these
> "simple" devices without drivers, they can still exist without a
> driver, and the PM domain doing all the magic.

Is it possible to let the PM Domain do the pm_runtime_enable() itself in
the absence of a driver? If yes, I wouldn't have needed simple-pm-bus.c.
What if a driver is bound later?

Gr{oetje,eeting}s,

                        Geert

--
Geert Uytterhoeven -- There's lots of Linux beyond ia32 -- geert at linux-m68k.org

In personal conversations with technical people, I call myself a hacker. But
when I'm talking to journalists I just say "programmer" or something like that.
                                -- Linus Torvalds


From tony at atomide.com  Sun Aug 16 23:34:55 2015
From: tony at atomide.com (Tony Lindgren)
Date: Sun, 16 Aug 2015 23:34:55 -0700
Subject: [RFT PATCH] arm: omap1_defconfig: convert to use libata PATA
 drivers
In-Reply-To: <1439571876-13758-16-git-send-email-b.zolnierkie@samsung.com>
References: <1439571876-13758-1-git-send-email-b.zolnierkie@samsung.com>
 <1439571876-13758-16-git-send-email-b.zolnierkie@samsung.com>
Message-ID: <20150817063454.GF4215@atomide.com>

* Bartlomiej Zolnierkiewicz <b.zolnierkie at samsung.com> [150814 10:10]:
> IDE subsystem has been deprecated since 2009 and the majority
> (if not all) of Linux distributions have switched to use
> libata for ATA support exclusively.  However there are still
> some users (mostly old or/and embedded non-x86 systems) that
> have not converted from using IDE subsystem to libata PATA
> drivers.  This doesn't seem to be good thing in the long-term
> for Linux as while there is less and less PATA systems left
> in use:
> 
> * testing efforts are divided between two subsystems
> 
> * having duplicate drivers for same hardware confuses users
> 
> This patch converts omap1_defconfig to use libata PATA
> drivers.
> 
> Cc: Tony Lindgren <tony at atomide.com>
> Cc: linux-omap at vger.kernel.org
> Signed-off-by: Bartlomiej Zolnierkiewicz <b.zolnierkie at samsung.com>
> ---
> Build tested only.
> If you have affected hardware please test.  Thank you.

All my omap1 devices are in a rack using NFSroot or MMC so
I can't test this. Seems like a good idea to me thoug, and does
not cause merge conflicts. So if you want to queue this via
along with other PATA related patches, please feel free to
add:

Acked-by: Tony Lindgren <tony at atomide.com>
 
>  arch/arm/configs/omap1_defconfig | 4 ++--
>  1 file changed, 2 insertions(+), 2 deletions(-)
> 
> diff --git a/arch/arm/configs/omap1_defconfig b/arch/arm/configs/omap1_defconfig
> index 0c8a787..6ffc984 100644
> --- a/arch/arm/configs/omap1_defconfig
> +++ b/arch/arm/configs/omap1_defconfig
> @@ -96,14 +96,14 @@ CONFIG_BLK_DEV_LOOP=y
>  CONFIG_BLK_DEV_RAM=y
>  CONFIG_BLK_DEV_RAM_COUNT=2
>  CONFIG_BLK_DEV_RAM_SIZE=8192
> -CONFIG_IDE=m
> -CONFIG_BLK_DEV_IDECS=m
>  CONFIG_SCSI=y
>  # CONFIG_SCSI_PROC_FS is not set
>  CONFIG_BLK_DEV_SD=y
>  CONFIG_CHR_DEV_ST=y
>  CONFIG_BLK_DEV_SR=y
>  CONFIG_CHR_DEV_SG=y
> +CONFIG_ATA=m
> +CONFIG_PATA_PCMCIA=m
>  CONFIG_NETDEVICES=y
>  CONFIG_TUN=y
>  CONFIG_PHYLIB=y
> -- 
> 1.9.1
> 


From p.fedin at samsung.com  Sun Aug 16 23:44:53 2015
From: p.fedin at samsung.com (Pavel Fedin)
Date: Mon, 17 Aug 2015 09:44:53 +0300
Subject: PING: [PATCH v2 TRIVIAL] Enable GICv2m on ARM virt machine
Message-ID: <00f001d0d8b8$39650c10$ac2f2430$@samsung.com>

 PING

Kind regards,
Pavel Fedin
Expert Engineer
Samsung Electronics Research center Russia

> -----Original Message-----
> From: linux-arm-kernel [mailto:linux-arm-kernel-bounces at lists.infradead.org] On Behalf Of Pavel
> Fedin
> Sent: Friday, August 07, 2015 1:51 PM
> To: linux-arm-kernel at lists.infradead.org
> Cc: 'Marc Zyngier'; trivial at kernel.org; 'Russell King'
> Subject: [PATCH v2 TRIVIAL] Enable GICv2m on ARM virt machine
> 
> qemu implementation of "virt" includes GICv2m. This commit allows to use
> it also on ARM32 architecture.
> 
> msi.h is added because it is required by linux/msi.h
> if CONFIG_GENERIC_MSI_IRQ_DOMAIN is defined. It gets enabled by the
> following KConfig dependency chain:
> ARM_GIC_V2M => PCI_MSI_IRQ_DOMAIN => GENERIC_MSI_IRQ_DOMAIN
> 
> Signed-off-by: Pavel Fedin <p.fedin at samsung.com>
> ---
> v1 => v2:
> Added verbose explanation in commit message
> ---
>  arch/arm/Kconfig            | 1 +
>  arch/arm/include/asm/Kbuild | 1 +
>  2 files changed, 2 insertions(+)
> 
> diff --git a/arch/arm/Kconfig b/arch/arm/Kconfig
> index 45df48b..1091025 100644
> --- a/arch/arm/Kconfig
> +++ b/arch/arm/Kconfig
> @@ -815,6 +815,7 @@ config ARCH_VIRT
>  	bool "Dummy Virtual Machine" if ARCH_MULTI_V7
>  	select ARM_AMBA
>  	select ARM_GIC
> +	select ARM_GIC_V2M if PCI_MSI
>  	select ARM_PSCI
>  	select HAVE_ARM_ARCH_TIMER
> 
> diff --git a/arch/arm/include/asm/Kbuild b/arch/arm/include/asm/Kbuild
> index 3c4596d..01806f5 100644
> --- a/arch/arm/include/asm/Kbuild
> +++ b/arch/arm/include/asm/Kbuild
> @@ -14,6 +14,7 @@ generic-y += local.h
>  generic-y += local64.h
>  generic-y += mcs_spinlock.h
>  generic-y += msgbuf.h
> +generic-y += msi.h
>  generic-y += param.h
>  generic-y += parport.h
>  generic-y += poll.h
> --
> 1.9.5.msysgit.0
> 
> 
> 
> _______________________________________________
> linux-arm-kernel mailing list
> linux-arm-kernel at lists.infradead.org
> http://lists.infradead.org/mailman/listinfo/linux-arm-kernel
> 
> 
> _______________________________________________
> linux-arm-kernel mailing list
> linux-arm-kernel at lists.infradead.org
> http://lists.infradead.org/mailman/listinfo/linux-arm-kernel



From takahiro.akashi at linaro.org  Sun Aug 16 21:50:57 2015
From: takahiro.akashi at linaro.org (AKASHI Takahiro)
Date: Mon, 17 Aug 2015 13:50:57 +0900
Subject: [RFC v2 0/4] arm64: ftrace: fix incorrect output from stack tracer
In-Reply-To: <50B298B0-1978-471B-BCE7-BC433E9993C1@gmail.com>
References: <1438674249-3447-1-git-send-email-takahiro.akashi@linaro.org>
 <50B298B0-1978-471B-BCE7-BC433E9993C1@gmail.com>
Message-ID: <55D16831.5080605@linaro.org>

Hi

On 08/11/2015 11:52 PM, Jungseok Lee wrote:
> On Aug 4, 2015, at 4:44 PM, AKASHI Takahiro wrote:
>
> Hi Akashi,
>
>> See the following threads [1],[2] for the background.
>>
>> With this patch series, I'm trying to fix several problems I noticed
>> with stack tracer on arm64. But it is rather experimental, and there still
>> remained are several issues.
>>
>> Patch #1 modifies ftrace framework so that we can provide arm64-specific
>> stack tracer later.
>> (Well, I know there is some room for further refactoring, but this is
>> just a prototype code.)
>> Patch #2 implements this arch_check_stack() using unwind_stackframe() to
>> traverse stack frames and identify a stack index for each traced function.
>> Patch #3 addresses an issue that stack tracer doesn't work well in
>> conjuction with function graph tracer.
>> Patch #4 addresses an issue that unwind_stackframe() misses a function
>> that is the one when an exception happens by setting up a stack frame
>> for exception handler.
>>
>> See below for the result with those patches.
>> Issues include:
>> a) Size of gic_handle_irq() is 48 (#13), but should be 64.
>> b) We cannot identify a location of function which is being returned
>>    and hooked temporarily by return_to_handler() (#18)
>> c) A meaningless entry (#62) as well as a bogus size for the first
>>    function, el0_svc (#61)
>> d) Size doesn't contain a function's "dynamically allocated local
>>    variables," if any, but instead is sumed up in child's size.
>>    (See details in [3].)
>>
>> I'm afraid that we cannot fix issue b) unless we can do *atomically*
>> push/pop a return adress in current->ret_stack[], increment/decrement
>> current->curr_ret_stack and restore lr register.
>>
>> We will be able to fix issue d) once we know all the locations in
>> the list, including b).
>>
>> [1] http://lists.infradead.org/pipermail/linux-arm-kernel/2015-July/354126.html
>> [2] http://lists.infradead.org/pipermail/linux-arm-kernel/2015-July/355920.html
>> [3] http://lists.infradead.org/pipermail/linux-arm-kernel/2015-July/358034.html
>
> I hope I'm not too late..

I was on vacation last week.

> This series looks written on top of the hunk in the end of this reply.
>
> I've strongly agreed with your opinion as digging out this issue. We need to analyse
> the first instruction of each function, "stp x29, x30, [sp, #val]!", in order to
> solve this problem clearly.

As far as I notice, the following is not the only prologue:
   stp  x29,x30, [sp,#-xx]!
   mov  x29,sp
but some functions may have another one like:
   sub  sp, sp, #xx
   stp  x29,x30, [sp, #16]
   add  x29,sp, #16
Even worse, I see some variant, for example in trace_graph_entry(),
   adrp x2, 0x...
   stp  x29,x30,[sp,#-xx]!
   add  x4, x2, #..
   mov  x29,x30

So parsing the function prologue perfectly is a bit more complicated than imagined.
I'm now asking some gcc guy for more information.

Thanks,
-Takahiro AKASHI

> How about decoding the store-pair instruction? If so, we could record a correct position
> into stack_dump_index. That is, in your ascii art, top-sp0 and top-sp1 are written into
> stack_dump_index[i+1] and stack_dump_index[i] respectively.
>
> sp2     +-------+ <--------- func-2's stackframe
>          |       |
>          |       |
> fp2     +-------+
>          |  fp1  |
>          +-------+ <-- p1 (*p1 == stack_dump_trace[i] == lr1)
>          |  lr1  |
>          +-------+
>          |       |
>          |  func-2's local variables
>          |       |
> sp1     +-------+ <--------- func-1(lr1)'s stackframe
>          |       |             (stack_dump_index[i] = top - p1)
>          |  func-1's dynamic local variables
>          |       |
> fp1     +-------+
>          |  fp0  |
>          +-------+ <-- p0 (*p0 == stack_dump_trace[i+1] == lr0)
>          |  lr0  |
>          +-------+
>          |       |
>          |  func-1's local variables
>          |       |
> sp0     +-------+ <--------- func-0(lr0)'s stackframe
>          |       |             (stack_dump_index[i+1] = top - p0)
>          |       |
>          *-------+ top
>
> Best Regards
> Jungseok Lee
>
> ----8<----
> diff --git a/arch/arm64/include/asm/ftrace.h b/arch/arm64/include/asm/ftrace.h
> index c5534fa..2b43e20 100644
> --- a/arch/arm64/include/asm/ftrace.h
> +++ b/arch/arm64/include/asm/ftrace.h
> @@ -13,8 +13,9 @@
>
> #include <asm/insn.h>
>
> -#define MCOUNT_ADDR		((unsigned long)_mcount)
> -#define MCOUNT_INSN_SIZE	AARCH64_INSN_SIZE
> +#define MCOUNT_ADDR			((unsigned long)_mcount)
> +#define MCOUNT_INSN_SIZE		AARCH64_INSN_SIZE
> +#define FTRACE_STACK_FRAME_OFFSET	AARCH64_INSN_SIZE
>
> #ifndef __ASSEMBLY__
> #include <linux/compat.h>
> diff --git a/arch/arm64/kernel/stacktrace.c b/arch/arm64/kernel/stacktrace.c
> index 407991b..9ab67af 100644
> --- a/arch/arm64/kernel/stacktrace.c
> +++ b/arch/arm64/kernel/stacktrace.c
> @@ -20,6 +20,7 @@
> #include <linux/sched.h>
> #include <linux/stacktrace.h>
>
> +#include <asm/insn.h>
> #include <asm/stacktrace.h>
>
> /*
> @@ -52,7 +53,7 @@ int notrace unwind_frame(struct stackframe *frame)
> 	 * -4 here because we care about the PC at time of bl,
> 	 * not where the return will go.
> 	 */
> -	frame->pc = *(unsigned long *)(fp + 8) - 4;
> +	frame->pc = *(unsigned long *)(fp + 8) - AARCH64_INSN_SIZE;
>
> 	return 0;
> }
> diff --git a/include/linux/ftrace.h b/include/linux/ftrace.h
> index 1da6029..6566201 100644
> --- a/include/linux/ftrace.h
> +++ b/include/linux/ftrace.h
> @@ -260,6 +260,9 @@ static inline void ftrace_kill(void) { }
> #endif /* CONFIG_FUNCTION_TRACER */
>
> #ifdef CONFIG_STACK_TRACER
> +#ifndef FTRACE_STACK_FRAME_OFFSET
> +#define FTRACE_STACK_FRAME_OFFSET 0
> +#endif
> extern int stack_tracer_enabled;
> int
> stack_trace_sysctl(struct ctl_table *table, int write,
> diff --git a/kernel/trace/trace_stack.c b/kernel/trace/trace_stack.c
> index b746399..30521ea 100644
> --- a/kernel/trace/trace_stack.c
> +++ b/kernel/trace/trace_stack.c
> @@ -105,7 +105,7 @@ check_stack(unsigned long ip, unsigned long *stack)
>
> 	/* Skip over the overhead of the stack tracer itself */
> 	for (i = 0; i < max_stack_trace.nr_entries; i++) {
> -		if (stack_dump_trace[i] == ip)
> +		if ((stack_dump_trace[i] + FTRACE_STACK_FRAME_OFFSET) == ip)
> 			break;
> 	}
>
> @@ -133,7 +133,8 @@ check_stack(unsigned long ip, unsigned long *stack)
> 		for (; p < top && i < max_stack_trace.nr_entries; p++) {
> 			if (stack_dump_trace[i] == ULONG_MAX)
> 				break;
> -			if (*p == stack_dump_trace[i]) {
> +			if (*p == (stack_dump_trace[i]
> +					+ FTRACE_STACK_FRAME_OFFSET)) {
> 				stack_dump_trace[x] = stack_dump_trace[i++];
> 				this_size = stack_dump_index[x++] =
> 					(top - p) * sizeof(unsigned long);
> ----8<----
>


From takahiro.akashi at linaro.org  Sun Aug 16 23:07:00 2015
From: takahiro.akashi at linaro.org (AKASHI Takahiro)
Date: Mon, 17 Aug 2015 15:07:00 +0900
Subject: [RFC v2 1/4] ftrace: allow arch-specific check_stack()
In-Reply-To: <20150811170321.GB29880@arm.com>
References: <1438674249-3447-1-git-send-email-takahiro.akashi@linaro.org>
 <1438674249-3447-2-git-send-email-takahiro.akashi@linaro.org>
 <20150811170321.GB29880@arm.com>
Message-ID: <55D17A04.7020800@linaro.org>

Will,

On 08/12/2015 02:03 AM, Will Deacon wrote:
> On Tue, Aug 04, 2015 at 08:44:06AM +0100, AKASHI Takahiro wrote:
>> A stack frame pointer may be used in a different way depending on
>> cpu architecture. Thus it is not always appropriate to slurp the stack
>> contents, as currently done in check_stack(), in order to calcurate
>> a stack index (height) at a given function call. At least not on arm64.
>>
>> This patch extract potentially arch-specific code from check_stack()
>> and puts it into a new arch_check_stack(), which is declared as weak.
>> So we will be able to add arch-specific and most efficient way of
>> stack traversing Later.
>>
>> Signed-off-by: AKASHI Takahiro <takahiro.akashi at linaro.org>
>
> If arm64 is the only architecture behaving differently, then I'm happy
> to reconsider the fix to unwind_frame that we merged in e306dfd06fcb
> ("ARM64: unwind: Fix PC calculation"). I'd have thought any architecture
> with a branch-and-link instruction would potentially have the same issue,
> so we could just be fixing things in the wrong place if ftrace works
> everywhere else.

I'm not the right person to answer for other architectures (and ftrace
behavior on them.) The only thing I know is that current ftrace stack tracer
works correctly only if the addresses stored and found on stack match to
the ones returned by save_stack_trace().

Anyway, the fix above is not the only reason that I want to introduce arch-specific
arch_check_stack(). Other issues to fix include
   - combined case of stack tracer and function graph tracer (common across arch's)
   - exception entries (as I'm trying to address in RFC 4/4)
   - in-accurate stack size (for each function, my current fix is not perfect though.)

Thanks,
-Takahiro AKASHI

> Will
>


From wangzhou1 at hisilicon.com  Sun Aug 16 21:50:51 2015
From: wangzhou1 at hisilicon.com (Zhou Wang)
Date: Mon, 17 Aug 2015 12:50:51 +0800
Subject: [PATCH v6 3/6] PCI: designware: Add ARM64 support
In-Reply-To: <EE11001F9E5DDD47B7634E2F8A612F2E01D7BC19@lhreml503-mbs>
References: <1438848559-232109-1-git-send-email-wangzhou1@hisilicon.com>
 <1438848559-232109-4-git-send-email-wangzhou1@hisilicon.com>
 <55C44B18.4010103@hisilicon.com> <55CDFFC0.40604@arm.com>
 <EE11001F9E5DDD47B7634E2F8A612F2E01D7BC19@lhreml503-mbs>
Message-ID: <55D1682B.8090701@hisilicon.com>

On 2015/8/14 22:55, Gabriele Paoloni wrote:
>>
>> I've tested this whole series on an ARM32 PCIe board:'Freescale i.MX6
>> Quad
>> SABRE Lite Board' with an Intel wireless card on v4.2-rc6.
>>
>> I can rescan the bus, load firmware, list nearby APs, and even get MSIs
>> coming from the card.
>>
>> Tested-By: James Morse <james.morse at arm.com>
>>
>>
>> Thanks,
>>
>> James
> 
> Many Thanks for this James!
> 
> Gab
> 
> .
> 

Hi James,

Your test is very helpful. Many thanks for this!

Zhou



From nikhil.badola at freescale.com  Sun Aug 16 21:25:50 2015
From: nikhil.badola at freescale.com (Nikhil Badola)
Date: Mon, 17 Aug 2015 09:55:50 +0530
Subject: [PATCH 3/3][v2] arm: dts: ls1021a: Add quirk for Erratum A009116
Message-ID: <1439785550-27298-1-git-send-email-nikhil.badola@freescale.com>

Add "snps,quirk-frame-length-adjustment" property to
USB3 node for erratum A009116. This property provides
value of GFLADJ_30MHZ for post silicon frame length
adjustment.

Signed-off-by: Nikhil Badola <nikhil.badola at freescale.com>
---
Changes for v2 : 
	- updated property name

 arch/arm/boot/dts/ls1021a.dtsi | 1 +
 1 file changed, 1 insertion(+)

diff --git a/arch/arm/boot/dts/ls1021a.dtsi b/arch/arm/boot/dts/ls1021a.dtsi
index c70bb27..50ac0d4 100644
--- a/arch/arm/boot/dts/ls1021a.dtsi
+++ b/arch/arm/boot/dts/ls1021a.dtsi
@@ -404,6 +404,7 @@
 			reg = <0x0 0x3100000 0x0 0x10000>;
 			interrupts = <GIC_SPI 93 IRQ_TYPE_LEVEL_HIGH>;
 			dr_mode = "host";
+			snps,quirk-frame-length-adjustment = <0x20>;
 		};
 	};
 };
-- 
2.1.0



From takahiro.akashi at linaro.org  Sun Aug 16 22:21:20 2015
From: takahiro.akashi at linaro.org (AKASHI Takahiro)
Date: Mon, 17 Aug 2015 14:21:20 +0900
Subject: [RFC v2 4/4] arm64: ftrace: add a stack frame for exception
 handler
In-Reply-To: <6399AE18-786B-41C2-B1C7-428567D9CF47@gmail.com>
References: <1438674249-3447-1-git-send-email-takahiro.akashi@linaro.org>
 <1438674249-3447-5-git-send-email-takahiro.akashi@linaro.org>
 <6399AE18-786B-41C2-B1C7-428567D9CF47@gmail.com>
Message-ID: <55D16F50.3060009@linaro.org>

On 08/11/2015 11:57 PM, Jungseok Lee wrote:
> On Aug 4, 2015, at 4:44 PM, AKASHI Takahiro wrote:
>
> Hi Akashi,
>
>> On arm64, an exception handler use the same stack as in non-exception
>> contexts, but doesn't create a stack frame for elx_xx entry, only updating
>> sp register. This behavior results in save_stace_trace() missing a function
>> that is the one when an exception happens.
>>
>> This patch creates a stack frame for this case, and puts an additional
>> entry for the function  in a stack trace list.
>>
>> Signed-off-by: AKASHI Takahiro <takahiro.akashi at linaro.org>
>> ---
>> arch/arm64/kernel/entry.S      |    4 ++++
>> arch/arm64/kernel/stacktrace.c |   17 +++++++++++++++++
>> 2 files changed, 21 insertions(+)
>>
>> diff --git a/arch/arm64/kernel/entry.S b/arch/arm64/kernel/entry.S
>> index f860bfd..aacb6c6 100644
>> --- a/arch/arm64/kernel/entry.S
>> +++ b/arch/arm64/kernel/entry.S
>> @@ -107,6 +107,8 @@
>> 	str	x21, [sp, #S_SYSCALLNO]
>> 	.endif
>>
>> +	/* create a stack frame for stack tracer */
>> +	mov	x29, sp
>> 	/*
>> 	 * Registers that may be useful after this macro is invoked:
>> 	 *
>> @@ -737,3 +739,5 @@ ENTRY(sys_rt_sigreturn_wrapper)
>> 	mov	x0, sp
>> 	b	sys_rt_sigreturn
>> ENDPROC(sys_rt_sigreturn_wrapper)
>> +
>> +ENTRY(end_of_vectors)
>> diff --git a/arch/arm64/kernel/stacktrace.c b/arch/arm64/kernel/stacktrace.c
>> index d1790eb..22ce7c9 100644
>> --- a/arch/arm64/kernel/stacktrace.c
>> +++ b/arch/arm64/kernel/stacktrace.c
>> @@ -25,6 +25,10 @@
>> #include <asm/stacktrace.h>
>>
>> #define S_FRAME_SIZE sizeof(struct pt_regs) /* asm-offsets.h */
>> +#define S_FP offsetof(struct pt_regs, regs[29])
>> +#define S_LR offsetof(struct pt_regs, regs[30])
>> +
>> +extern unsigned int *vectors, *end_of_vectors;
>>
>> /*
>>   * AArch64 PCS assigns the frame pointer to x29.
>> @@ -50,6 +54,19 @@ int notrace unwind_frame(struct stackframe *frame)
>> 	if (fp < low || fp > high - 0x18 || fp & 0xf)
>> 		return -EINVAL;
>>
>> +	if ((frame->pc >= (unsigned long)&vectors) &&
>> +			(frame->pc < (unsigned long)&end_of_vectors)) {
>> +		/*
>> +		 * Expection handler does not use a normal format of
>> +		 * stack frame, but allocates struct pt_regs.
>> +		 */
>> +		frame->sp = frame->sp + S_FRAME_SIZE;
>> +		frame->fp = *(unsigned long *)(fp + S_FP);
>> +		frame->pc = *(unsigned long *)(fp + S_LR);
>
> Not frame->pc = *(unsigned long *)(fp + S_PC)? Don't we need to look up elr_el1
> since this is an exception?

You are right. Will fix it if I submit the next version.

>> +
>> +		return 0;
>> +	}
>> +
>> 	frame->sp = fp + 0x10;
>
> I'm just curious about this constant, 0x10. Do you have an idea on this value?
> As reviewing objdump of vmlinux, it looks needed to analyze the first store-pair
> instruction of each function.
>
> Please correct me if I'm wrong.

I don't know Catalin's intention here, but fp always points to saved pair of
<fp, lr> and so, in general, "fp + 0x10" is the address of succeeding local variables
in callee function. (Remember my acsii art :)
This can be the easily-approximated (but not accurate) stack pointer of caller unless
we decode function prologues.

Thanks,
-Takahiro AKASHI

> Best Regards
> Jungseok Lee
>


From drinkcat at chromium.org  Sun Aug 16 20:52:54 2015
From: drinkcat at chromium.org (Nicolas Boichat)
Date: Mon, 17 Aug 2015 11:52:54 +0800
Subject: [PATCH v2] spi: bitbang: Replace spinlock by mutex
Message-ID: <1439783574-5933-1-git-send-email-drinkcat@chromium.org>

chipselect (in the case of spi-gpio: spi_gpio_chipselect, which
calls gpiod_set_raw_value_cansleep) can sleep, so we should not
hold a spinlock while calling it from spi_bitbang_setup.

This issue was introduced by this commit, which converted spi-gpio
to cansleep variants:
d9dda5a191 "spi: spi-gpio: Use 'cansleep' variants to access GPIO"

Replacing the lock variable by a mutex fixes the issue: This is
safe as all instances where the lock is used are called from
contexts that can sleep.

Finally, update spi-ppc4xx and and spi-s3c24xx to use mutex
functions, as they directly hold the lock for similar purpose.

Signed-off-by: Nicolas Boichat <drinkcat at chromium.org>
---
Going the "safer" way and just replacing the spinlock by a
mutex.

Applies on top of broonie-sound/for-next, and compile-tested on
x86-64/arm (allyesconfig) and ppc44x (defconfig+SPI driver),
and runtime-tested on an arm platform.

Thanks!

 drivers/spi/spi-bitbang.c       | 17 +++++++----------
 drivers/spi/spi-ppc4xx.c        |  4 ++--
 drivers/spi/spi-s3c24xx.c       |  4 ++--
 include/linux/spi/spi_bitbang.h |  2 +-
 4 files changed, 12 insertions(+), 15 deletions(-)

diff --git a/drivers/spi/spi-bitbang.c b/drivers/spi/spi-bitbang.c
index 840a498..ef43ef5 100644
--- a/drivers/spi/spi-bitbang.c
+++ b/drivers/spi/spi-bitbang.c
@@ -180,7 +180,6 @@ int spi_bitbang_setup(struct spi_device *spi)
 {
 	struct spi_bitbang_cs	*cs = spi->controller_state;
 	struct spi_bitbang	*bitbang;
-	unsigned long		flags;
 
 	bitbang = spi_master_get_devdata(spi->master);
 
@@ -210,12 +209,12 @@ int spi_bitbang_setup(struct spi_device *spi)
 	 */
 
 	/* deselect chip (low or high) */
-	spin_lock_irqsave(&bitbang->lock, flags);
+	mutex_lock(&bitbang->lock);
 	if (!bitbang->busy) {
 		bitbang->chipselect(spi, BITBANG_CS_INACTIVE);
 		ndelay(cs->nsecs);
 	}
-	spin_unlock_irqrestore(&bitbang->lock, flags);
+	mutex_unlock(&bitbang->lock);
 
 	return 0;
 }
@@ -255,13 +254,12 @@ static int spi_bitbang_bufs(struct spi_device *spi, struct spi_transfer *t)
 static int spi_bitbang_prepare_hardware(struct spi_master *spi)
 {
 	struct spi_bitbang	*bitbang;
-	unsigned long		flags;
 
 	bitbang = spi_master_get_devdata(spi);
 
-	spin_lock_irqsave(&bitbang->lock, flags);
+	mutex_lock(&bitbang->lock);
 	bitbang->busy = 1;
-	spin_unlock_irqrestore(&bitbang->lock, flags);
+	mutex_unlock(&bitbang->lock);
 
 	return 0;
 }
@@ -378,13 +376,12 @@ static int spi_bitbang_transfer_one(struct spi_master *master,
 static int spi_bitbang_unprepare_hardware(struct spi_master *spi)
 {
 	struct spi_bitbang	*bitbang;
-	unsigned long		flags;
 
 	bitbang = spi_master_get_devdata(spi);
 
-	spin_lock_irqsave(&bitbang->lock, flags);
+	mutex_lock(&bitbang->lock);
 	bitbang->busy = 0;
-	spin_unlock_irqrestore(&bitbang->lock, flags);
+	mutex_unlock(&bitbang->lock);
 
 	return 0;
 }
@@ -427,7 +424,7 @@ int spi_bitbang_start(struct spi_bitbang *bitbang)
 	if (!master || !bitbang->chipselect)
 		return -EINVAL;
 
-	spin_lock_init(&bitbang->lock);
+	mutex_init(&bitbang->lock);
 
 	if (!master->mode_bits)
 		master->mode_bits = SPI_CPOL | SPI_CPHA | bitbang->flags;
diff --git a/drivers/spi/spi-ppc4xx.c b/drivers/spi/spi-ppc4xx.c
index 54fb984..dd3d0a2 100644
--- a/drivers/spi/spi-ppc4xx.c
+++ b/drivers/spi/spi-ppc4xx.c
@@ -210,12 +210,12 @@ static int spi_ppc4xx_setupxfer(struct spi_device *spi, struct spi_transfer *t)
 	if (in_8(&hw->regs->cdm) != cdm)
 		out_8(&hw->regs->cdm, cdm);
 
-	spin_lock(&hw->bitbang.lock);
+	mutex_lock(&hw->bitbang.lock);
 	if (!hw->bitbang.busy) {
 		hw->bitbang.chipselect(spi, BITBANG_CS_INACTIVE);
 		/* Need to ndelay here? */
 	}
-	spin_unlock(&hw->bitbang.lock);
+	mutex_unlock(&hw->bitbang.lock);
 
 	return 0;
 }
diff --git a/drivers/spi/spi-s3c24xx.c b/drivers/spi/spi-s3c24xx.c
index f36bc32..4e7d1bf 100644
--- a/drivers/spi/spi-s3c24xx.c
+++ b/drivers/spi/spi-s3c24xx.c
@@ -198,12 +198,12 @@ static int s3c24xx_spi_setup(struct spi_device *spi)
 	if (ret)
 		return ret;
 
-	spin_lock(&hw->bitbang.lock);
+	mutex_lock(&hw->bitbang.lock);
 	if (!hw->bitbang.busy) {
 		hw->bitbang.chipselect(spi, BITBANG_CS_INACTIVE);
 		/* need to ndelay for 0.5 clocktick ? */
 	}
-	spin_unlock(&hw->bitbang.lock);
+	mutex_unlock(&hw->bitbang.lock);
 
 	return 0;
 }
diff --git a/include/linux/spi/spi_bitbang.h b/include/linux/spi/spi_bitbang.h
index 85578d4..154788e 100644
--- a/include/linux/spi/spi_bitbang.h
+++ b/include/linux/spi/spi_bitbang.h
@@ -4,7 +4,7 @@
 #include <linux/workqueue.h>
 
 struct spi_bitbang {
-	spinlock_t		lock;
+	struct mutex		lock;
 	u8			busy;
 	u8			use_dma;
 	u8			flags;		/* extra spi->mode support */
-- 
2.5.0.276.gf5e568e



From alison.wang at freescale.com  Sun Aug 16 20:42:37 2015
From: alison.wang at freescale.com (Huan Wang)
Date: Mon, 17 Aug 2015 03:42:37 +0000
Subject: [PATCH v3] ARM: configs: Add Freescale LS1021A defconfig
In-Reply-To: <CAOMZO5By_15OCsb7z2pbywPi3n9vKGj=393hWYHVEQ32=jDNaA@mail.gmail.com>
References: <1438941784-38403-1-git-send-email-b18965@freescale.com>
 <55CB4829.40204@freescale.com>	<55CE1FFE.2080200@freescale.com>
 <CAOMZO5By_15OCsb7z2pbywPi3n9vKGj=393hWYHVEQ32=jDNaA@mail.gmail.com>
Message-ID: <BN3PR0301MB08672520CA978383BBF2CF6CFE790@BN3PR0301MB0867.namprd03.prod.outlook.com>

Hi, Fabio,

	Based on the analysis and discussion, we prefer to use ls1021a_defconfig and remove LS1021A from imx_v6_v7_defconfig.

	Thanks.

Best Regards,
Alison Wang

> On Fri, Aug 14, 2015 at 2:06 PM, Horia Geant?
> <horia.geanta at freescale.com> wrote:
> 
> > Another thing:
> > Commit 385c0fb0e2c4 ("ARM: imx_v6_v7_defconfig: Select LS1021A")
> added
> > CONFIG_SOC_LS1021A in imx_v6_v7_defconfig.
> >
> > Besides this, booting a LS1021 AQDS board (Rev2) using
> > imx_v6_v7_defconfig did not work (stuck at "Starting kernel").
> 
> What would be the recommended approach?
> 
> - Fix imx_v6_v7_defconfig so that it can make LS1021A to boot
> 
> or
> 
> - Use this proposed ls1021a_defconfig and remove LS1021A from
> imx_v6_v7_defconfig?
> 
> Regards,
> 
> Fabio Estevam

From leilk.liu at mediatek.com  Sun Aug 16 20:29:58 2015
From: leilk.liu at mediatek.com (Leilk Liu)
Date: Mon, 17 Aug 2015 11:29:58 +0800
Subject: [PATCH v6] arm64: dts: Add spi bus dts
Message-ID: <1439782198-32396-1-git-send-email-leilk.liu@mediatek.com>

This patch adds MT8173 spi bus controllers into device tree.

Signed-off-by: Leilk Liu <leilk.liu at mediatek.com>
---
Change in this patch:
pinctl and pad-select fields are board specific, so move to
mt8173-evb.dtsi, and status = "okay".
---
 arch/arm64/boot/dts/mediatek/mt8173-evb.dts | 18 ++++++++++++++++++
 arch/arm64/boot/dts/mediatek/mt8173.dtsi    | 12 ++++++++++++
 2 files changed, 30 insertions(+)

diff --git a/arch/arm64/boot/dts/mediatek/mt8173-evb.dts b/arch/arm64/boot/dts/mediatek/mt8173-evb.dts
index 4be66ca..811cb76 100644
--- a/arch/arm64/boot/dts/mediatek/mt8173-evb.dts
+++ b/arch/arm64/boot/dts/mediatek/mt8173-evb.dts
@@ -387,6 +387,24 @@
 	};
 };
 
+&pio {
+	spi_pins_a: spi0 {
+		pins_spi {
+			pinmux = <MT8173_PIN_69_SPI_CK__FUNC_SPI_CK_0_>,
+				<MT8173_PIN_70_SPI_MI__FUNC_SPI_MI_0_>,
+				<MT8173_PIN_71_SPI_MO__FUNC_SPI_MO_0_>,
+				<MT8173_PIN_72_SPI_CS__FUNC_SPI_CS_0_>;
+		};
+	};
+};
+
+&spi {
+	pinctrl-names = "default";
+	pinctrl-0 = <&spi_pins_a>;
+	mediatek,pad-select = <0>;
+	status = "okay";
+};
+
 &uart0 {
 	status = "okay";
 };
diff --git a/arch/arm64/boot/dts/mediatek/mt8173.dtsi b/arch/arm64/boot/dts/mediatek/mt8173.dtsi
index d18ee42..3dfb6ed 100644
--- a/arch/arm64/boot/dts/mediatek/mt8173.dtsi
+++ b/arch/arm64/boot/dts/mediatek/mt8173.dtsi
@@ -365,6 +365,18 @@
 			status = "disabled";
 		};
 
+		spi: spi at 1100a000 {
+			compatible = "mediatek,mt8173-spi";
+			#address-cells = <1>;
+			#size-cells = <0>;
+			reg = <0 0x1100a000 0 0x1000>;
+			interrupts = <GIC_SPI 110 IRQ_TYPE_LEVEL_LOW>;
+			clocks = <&topckgen CLK_TOP_SPI_SEL>,
+				 <&topckgen CLK_TOP_SYSPLL3_D2>;
+			clock-names = "spi-clk", "parent-clk";
+			status = "disabled";
+		};
+
 		i2c3: i2c3 at 11010000 {
 			compatible = "mediatek,mt8173-i2c";
 			reg = <0 0x11010000 0 0x70>,
-- 
1.8.1.1.dirty



From pankaj.dubey at samsung.com  Sun Aug 16 20:29:38 2015
From: pankaj.dubey at samsung.com (Pankaj Dubey)
Date: Mon, 17 Aug 2015 08:59:38 +0530
Subject: [1/4] clk: samsung: exynos3250: Add UART2 clock
In-Reply-To: <1439264784-30322-2-git-send-email-cw00.choi@samsung.com>
References: <1439264784-30322-2-git-send-email-cw00.choi@samsung.com>
Message-ID: <55D15522.7080603@samsung.com>

Hi Chanwoo,

Thanks for this patch. Similar patch[1] was posted long back, and there 
were some concern from your side, if you think those concerns are fixed, 
then my patch [1] are still valid and can be taken. If it needs to be 
rebase I am happy to do that.

[1] 
http://lists.infradead.org/pipermail/linux-arm-kernel/2014-September/291239.html


Thanks,
Pankaj Dubey
On Tuesday 11 August 2015 09:16 AM, Chanwoo Choi wrote:
> This patch add the UART2 clocks (mux, divider, gate) of Exynos3250 SoC.
>
> Cc: Sylwester Nawrocki <s.nawrocki at samsung.com>
> Cc: Tomasz Figa <tomasz.figa at gmail.com>
> Signed-off-by: Chanwoo Choi <cw00.choi at samsung.com>
> Reviewed-by: Krzysztof Kozlowski <k.kozlowski at samsung.com>
>
> ---
> drivers/clk/samsung/clk-exynos3250.c   | 6 ++++++
>   include/dt-bindings/clock/exynos3250.h | 6 +++++-
>   2 files changed, 11 insertions(+), 1 deletion(-)
>
> diff --git a/drivers/clk/samsung/clk-exynos3250.c b/drivers/clk/samsung/clk-exynos3250.c
> index 538de66a759e..2105863a3ace 100644
> --- a/drivers/clk/samsung/clk-exynos3250.c
> +++ b/drivers/clk/samsung/clk-exynos3250.c
> @@ -307,6 +307,7 @@ static struct samsung_mux_clock mux_clks[] __initdata = {
>   	MUX(CLK_MOUT_MMC0, "mout_mmc0", group_sclk_p, SRC_FSYS, 0, 4),
>
>   	/* SRC_PERIL0 */
> +	MUX(CLK_MOUT_UART2, "mout_uart2", group_sclk_p, SRC_PERIL0, 8, 4),
>   	MUX(CLK_MOUT_UART1, "mout_uart1", group_sclk_p, SRC_PERIL0, 4, 4),
>   	MUX(CLK_MOUT_UART0, "mout_uart0", group_sclk_p, SRC_PERIL0, 0, 4),
>
> @@ -389,6 +390,7 @@ static struct samsung_div_clock div_clks[] __initdata = {
>   	DIV(CLK_DIV_MMC0, "div_mmc0", "mout_mmc0", DIV_FSYS1, 0, 4),
>
>   	/* DIV_PERIL0 */
> +	DIV(CLK_DIV_UART2, "div_uart2", "mout_uart2", DIV_PERIL0, 8, 4),
>   	DIV(CLK_DIV_UART1, "div_uart1", "mout_uart1", DIV_PERIL0, 4, 4),
>   	DIV(CLK_DIV_UART0, "div_uart0", "mout_uart0", DIV_PERIL0, 0, 4),
>
> @@ -551,6 +553,9 @@ static struct samsung_gate_clock gate_clks[] __initdata = {
>   		GATE_SCLK_PERIL, 7, CLK_SET_RATE_PARENT, 0),
>   	GATE(CLK_SCLK_SPI0, "sclk_spi0", "div_spi0_pre",
>   		GATE_SCLK_PERIL, 6, CLK_SET_RATE_PARENT, 0),
> +
> +	GATE(CLK_SCLK_UART2, "sclk_uart2", "div_uart2",
> +		GATE_SCLK_PERIL, 2, CLK_SET_RATE_PARENT, 0),
>   	GATE(CLK_SCLK_UART1, "sclk_uart1", "div_uart1",
>   		GATE_SCLK_PERIL, 1, CLK_SET_RATE_PARENT, 0),
>   	GATE(CLK_SCLK_UART0, "sclk_uart0", "div_uart0",
> @@ -648,6 +653,7 @@ static struct samsung_gate_clock gate_clks[] __initdata = {
>   	GATE(CLK_I2C2, "i2c2", "div_aclk_100", GATE_IP_PERIL, 8, 0, 0),
>   	GATE(CLK_I2C1, "i2c1", "div_aclk_100", GATE_IP_PERIL, 7, 0, 0),
>   	GATE(CLK_I2C0, "i2c0", "div_aclk_100", GATE_IP_PERIL, 6, 0, 0),
> +	GATE(CLK_UART2, "uart2", "div_aclk_100", GATE_IP_PERIL, 2, 0, 0),
>   	GATE(CLK_UART1, "uart1", "div_aclk_100", GATE_IP_PERIL, 1, 0, 0),
>   	GATE(CLK_UART0, "uart0", "div_aclk_100", GATE_IP_PERIL, 0, 0, 0),
>   };
> diff --git a/include/dt-bindings/clock/exynos3250.h b/include/dt-bindings/clock/exynos3250.h
> index aab088d30199..89a7d97b002c 100644
> --- a/include/dt-bindings/clock/exynos3250.h
> +++ b/include/dt-bindings/clock/exynos3250.h
> @@ -78,6 +78,7 @@
>   #define CLK_MOUT_CORE			58
>   #define CLK_MOUT_APLL			59
>   #define CLK_MOUT_ACLK_266_SUB		60
> +#define CLK_MOUT_UART2			61
>
>   /* Dividers */
>   #define CLK_DIV_GPL			64
> @@ -126,6 +127,7 @@
>   #define CLK_DIV_CORE			107
>   #define CLK_DIV_HPM			108
>   #define CLK_DIV_COPY			109
> +#define CLK_DIV_UART2			110
>
>   /* Gates */
>   #define CLK_ASYNC_G3D			128
> @@ -222,6 +224,7 @@
>   #define CLK_BLOCK_MFC			219
>   #define CLK_BLOCK_CAM			220
>   #define CLK_SMIES			221
> +#define CLK_UART2			222
>
>   /* Special clocks */
>   #define CLK_SCLK_JPEG			224
> @@ -248,12 +251,13 @@
>   #define CLK_SCLK_SPI0			245
>   #define CLK_SCLK_UART1			246
>   #define CLK_SCLK_UART0			247
> +#define CLK_SCLK_UART2			248
>
>   /*
>    * Total number of clocks of main CMU.
>    * NOTE: Must be equal to last clock ID increased by one.
>    */
> -#define CLK_NR_CLKS			248
> +#define CLK_NR_CLKS			249
>
>   /*
>    * CMU DMC
>


From k.kozlowski at samsung.com  Sun Aug 16 19:13:35 2015
From: k.kozlowski at samsung.com (Krzysztof Kozlowski)
Date: Mon, 17 Aug 2015 11:13:35 +0900
Subject: [PATCH 4/4] ARM: dts: Add MSHC2 dt node for Exynos3250 SoC
In-Reply-To: <1439264784-30322-5-git-send-email-cw00.choi@samsung.com>
References: <1439264784-30322-1-git-send-email-cw00.choi@samsung.com>
 <1439264784-30322-5-git-send-email-cw00.choi@samsung.com>
Message-ID: <55D1434F.1040502@samsung.com>

On 11.08.2015 12:46, Chanwoo Choi wrote:
> This patch add the MSHC2 (Mobile Storage Host Controller) devicetree node for
> Exynos3250 SoC.

s/add/adds/
s/devicetree/Device Tree/

> 
> Cc: Kukjin Kim <kgene at kernel.org>
> Cc: Krzysztof Kozlowski <k.kozlowski at samsung.com>
> Signed-off-by: Chanwoo Choi <cw00.choi at samsung.com>
> ---
>  arch/arm/boot/dts/exynos3250-pinctrl.dtsi | 35 +++++++++++++++++++++++++++++++
>  arch/arm/boot/dts/exynos3250.dtsi         | 13 ++++++++++++
>  2 files changed, 48 insertions(+)

Reviewed-by: Krzysztof Kozlowski <k.kozlowski at samsung.com>

Best regards,
Krzysztof



From k.kozlowski at samsung.com  Sun Aug 16 19:11:45 2015
From: k.kozlowski at samsung.com (Krzysztof Kozlowski)
Date: Mon, 17 Aug 2015 11:11:45 +0900
Subject: [PATCH 3/4] ARM: dts: Add UART2 dt node for Exynos3250 SoC
In-Reply-To: <1439264784-30322-4-git-send-email-cw00.choi@samsung.com>
References: <1439264784-30322-1-git-send-email-cw00.choi@samsung.com>
 <1439264784-30322-4-git-send-email-cw00.choi@samsung.com>
Message-ID: <55D142E1.2000208@samsung.com>

On 11.08.2015 12:46, Chanwoo Choi wrote:
> This patch add the uart2 devicetree node for Exynos3250 SoC.
"This patch adds the UART2 Device Tree node..."

> 
> Cc: Kukjin Kim <kgene at kernel.org>
> Cc: Krzysztof Kozlowski <k.kozlowski at samsung.com>
> Signed-off-by: Chanwoo Choi <cw00.choi at samsung.com>
> ---
>  arch/arm/boot/dts/exynos3250-pinctrl.dtsi |  7 +++++++
>  arch/arm/boot/dts/exynos3250.dtsi         | 12 ++++++++++++
>  2 files changed, 19 insertions(+)


Reviewed-by: Krzysztof Kozlowski <k.kozlowski at samsung.com>

Best regards,
Krzysztof



From shijie.huang at arm.com  Sun Aug 16 19:05:25 2015
From: shijie.huang at arm.com (Huang Shijie)
Date: Mon, 17 Aug 2015 10:05:25 +0800
Subject: [PATCH] arm64: dts: Juno: fix the wrong memory map sizes for the
 I2C/EHCI/OHCI
Message-ID: <1439777125-9409-1-git-send-email-shijie.huang@arm.com>

>From the "Juno ARM Development Platform Soc Techinical Reference Mannual(r1p0)",
we get the following memory map sizes (3-25):
	I2C      : 0x7ffa0000  0x7ffa00ff       (256B)
	USB OHCI : 0x7ffb0000  0x7ffb0fff       (4KB)
	USB EHCI : 0x7ffc0000  0x7ffc0fff       (4KB)

This patch fixes the wrong memory map sizes for them.

Signed-off-by: Huang Shijie <shijie.huang at arm.com>
---
 arch/arm64/boot/dts/arm/juno-base.dtsi | 6 +++---
 1 file changed, 3 insertions(+), 3 deletions(-)

diff --git a/arch/arm64/boot/dts/arm/juno-base.dtsi b/arch/arm64/boot/dts/arm/juno-base.dtsi
index e3ee960..7b2715f 100644
--- a/arch/arm64/boot/dts/arm/juno-base.dtsi
+++ b/arch/arm64/boot/dts/arm/juno-base.dtsi
@@ -74,7 +74,7 @@
 
 	i2c at 7ffa0000 {
 		compatible = "snps,designware-i2c";
-		reg = <0x0 0x7ffa0000 0x0 0x1000>;
+		reg = <0x0 0x7ffa0000 0x0 0x100>;
 		#address-cells = <1>;
 		#size-cells = <0>;
 		interrupts = <GIC_SPI 104 IRQ_TYPE_LEVEL_HIGH>;
@@ -95,14 +95,14 @@
 
 	ohci at 7ffb0000 {
 		compatible = "generic-ohci";
-		reg = <0x0 0x7ffb0000 0x0 0x10000>;
+		reg = <0x0 0x7ffb0000 0x0 0x1000>;
 		interrupts = <GIC_SPI 116 IRQ_TYPE_LEVEL_HIGH>;
 		clocks = <&soc_usb48mhz>;
 	};
 
 	ehci at 7ffc0000 {
 		compatible = "generic-ehci";
-		reg = <0x0 0x7ffc0000 0x0 0x10000>;
+		reg = <0x0 0x7ffc0000 0x0 0x1000>;
 		interrupts = <GIC_SPI 117 IRQ_TYPE_LEVEL_HIGH>;
 		clocks = <&soc_usb48mhz>;
 	};
-- 
2.1.4



From jh80.chung at samsung.com  Sun Aug 16 18:55:19 2015
From: jh80.chung at samsung.com (Jaehoon Chung)
Date: Mon, 17 Aug 2015 10:55:19 +0900
Subject: [PATCH 2/3] mmc: dw_mmc: simplify the SDMMC_CLKEN_LOW_PWR logic
In-Reply-To: <3d03bfe2c18789eefa038018467c9c63c94ae4a2.1439381423.git.hramrach@gmail.com>
References: <cover.1439381423.git.hramrach@gmail.com>
 <3d03bfe2c18789eefa038018467c9c63c94ae4a2.1439381423.git.hramrach@gmail.com>
Message-ID: <55D13F07.70309@samsung.com>

Hi, Michal.

On 08/12/2015 09:23 PM, Michal Suchanek wrote:
> The driver has open-coded test for SDIO cards. Use the mmc core provided
> MMC_QUIRK_BROKEN_CLK_GATING flag instead.

Did you use the clock-gating for SDIO cards?
Doesn't MMC_CAP_SDIO_IRQ bit set? Which case is broken?
Could you explain to me more?

Best Regards,
Jaehoon Chung

> 
> As a bonus this may enable clock gating on SDIO cards that are known to
> work with it.
> 
> Signed-off-by: Michal Suchanek <hramrach at gmail.com>
> ---
>  drivers/mmc/host/dw_mmc.c | 33 +++++++++++++++------------------
>  1 file changed, 15 insertions(+), 18 deletions(-)
> 
> diff --git a/drivers/mmc/host/dw_mmc.c b/drivers/mmc/host/dw_mmc.c
> index 40e9d8e..3bc9fd7 100644
> --- a/drivers/mmc/host/dw_mmc.c
> +++ b/drivers/mmc/host/dw_mmc.c
> @@ -1335,27 +1335,24 @@ static void dw_mci_init_card(struct mmc_host *mmc, struct mmc_card *card)
>  	 * description of the CLKENA register we should disable low power mode
>  	 * for SDIO cards if we need SDIO interrupts to work.
>  	 */
> -	if (mmc->caps & MMC_CAP_SDIO_IRQ) {
> -		const u32 clken_low_pwr = SDMMC_CLKEN_LOW_PWR << slot->id;
> -		u32 clk_en_a_old;
> -		u32 clk_en_a;
> +	const u32 clken_low_pwr = SDMMC_CLKEN_LOW_PWR << slot->id;
> +	u32 clk_en_a_old;
> +	u32 clk_en_a;
>  
> -		clk_en_a_old = mci_readl(host, CLKENA);
> +	clk_en_a_old = mci_readl(host, CLKENA);
>  
> -		if (card->type == MMC_TYPE_SDIO ||
> -		    card->type == MMC_TYPE_SD_COMBO) {
> -			set_bit(DW_MMC_CARD_NO_LOW_PWR, &slot->flags);
> -			clk_en_a = clk_en_a_old & ~clken_low_pwr;
> -		} else {
> -			clear_bit(DW_MMC_CARD_NO_LOW_PWR, &slot->flags);
> -			clk_en_a = clk_en_a_old | clken_low_pwr;
> -		}
> +	if (card->quirks & MMC_QUIRK_BROKEN_CLK_GATING) {
> +		set_bit(DW_MMC_CARD_NO_LOW_PWR, &slot->flags);
> +		clk_en_a = clk_en_a_old & ~clken_low_pwr;
> +	} else {
> +		clear_bit(DW_MMC_CARD_NO_LOW_PWR, &slot->flags);
> +		clk_en_a = clk_en_a_old | clken_low_pwr;
> +	}
>  
> -		if (clk_en_a != clk_en_a_old) {
> -			mci_writel(host, CLKENA, clk_en_a);
> -			mci_send_cmd(slot, SDMMC_CMD_UPD_CLK |
> -				     SDMMC_CMD_PRV_DAT_WAIT, 0);
> -		}
> +	if (clk_en_a != clk_en_a_old) {
> +		mci_writel(host, CLKENA, clk_en_a);
> +		mci_send_cmd(slot, SDMMC_CMD_UPD_CLK |
> +				SDMMC_CMD_PRV_DAT_WAIT, 0);
>  	}
>  }
>  
> 



From liguozhu at hisilicon.com  Sun Aug 16 18:28:07 2015
From: liguozhu at hisilicon.com (Liguozhu (Kenneth))
Date: Mon, 17 Aug 2015 01:28:07 +0000
Subject: =?gb2312?B?tPC4tDogW1BBVENIIDEvNV0gbmV0OiBhZGQgSGlzaWxpY29uIE5ldHdvcmsg?=
 =?gb2312?Q?Subsystem_support_(config_and_documents)?=
In-Reply-To: <1536926.jEJjsM70Lj@wuerfel>
References: <1439548222-231611-1-git-send-email-liguozhu@hisilicon.com>
 <1439548222-231611-2-git-send-email-liguozhu@hisilicon.com>
 <1536926.jEJjsM70Lj@wuerfel>
Message-ID: <161EFA05D917D0419F95C4CAEEF86C1094E95FAA@SZXEMA504-MBS.china.huawei.com>

Thanks, Arnd. 

Regarding the ae-name: it is the name of the Acceleration Engine. It is provided by the BIOS according to the position and the feature enabled of the IP. So "soc0" means it is on SoC No. 0, while "n4" means it is running on "Non-dsaf mode 4". Ideally, we should setup the rule to name it. But as I said in the patchset, the IP is original designed for a bare metal solution, it is worthless to export all modes and we are planning to add more mode for Linux itself in the IP in future version. So I think the better way is to leave it as a "name" but add more meaning in the future.

Regarding the ae-opts: it is the initial value for the AE's runtime options, Currently, we have only "port number" (there are 6XGE+2GE port for a DSAF AE) as option. But for future version, we will add other options such as "enable Spanning Tree Protocol algorithm)" and so on. 

Should I add these background to somewhere?

Best Regards
-Kenneth Lee (Hisilicon)
__________________________________________________________
????????????????????????????????????????
????????????????????????????????????????
???????????????????????????????????
This e-mail and its attachments contain confidential information from HUAWEI, which 
is intended only for the person or entity whose address is listed above. Any use of the 
information contained herein in any way (including, but not limited to, total or partial 
disclosure, reproduction, or dissemination) by persons other than the intended 
recipient(s) is prohibited. If you receive this e-mail in error, please notify the sender by 
phone or email immediately and delete it!




-----????-----
???: Arnd Bergmann [mailto:arnd at arndb.de] 
????: 2015?8?15? 4:50
???: Liguozhu (Kenneth)
??: robh+dt at kernel.org; pawel.moll at arm.com; mark.rutland at arm.com; ijc+devicetree at hellion.org.uk; galak at codeaurora.org; catalin.marinas at arm.com; will.deacon at arm.com; Zhuangyuzeng (Yisen); davem at davemloft.net; paul.gortmaker at windriver.com; Dingtianhong; zhangfei.gao at linaro.org; devicetree at vger.kernel.org; linux-kernel at vger.kernel.org; linux-arm-kernel at lists.infradead.org; netdev at vger.kernel.org; Linuxarm; Salil Mehta; huangdaode; Liguozhu (Kenneth)
??: Re: [PATCH 1/5] net: add Hisilicon Network Subsystem support (config and documents)

On Friday 14 August 2015 18:30:18 Kenneth Lee wrote:
> diff --git a/Documentation/devicetree/bindings/net/hisilicon-hns-nic.txt b/Documentation/devicetree/bindings/net/hisilicon-hns-nic.txt
> new file mode 100644
> index 0000000..5ab6969
> --- /dev/null
> +++ b/Documentation/devicetree/bindings/net/hisilicon-hns-nic.txt
> @@ -0,0 +1,14 @@
> +Hisilicon Network Subsystem NIC controller
> +
> +Required properties:
> +- compatible: hisilicon,hns-nic
> +- ae-name: accelerator name who provide this interface
> +- ae-opts: options (string) to the accelerator. e.g. the index interface
> +
> +Example:
> +
> +       ethernet at 0{
> +               compatible = "hisilicon,hns-nic";
> +               ae-name = "soc0-n4";
> +               ae-opts = "0";
> +       };
> 

These properties look very unconventional. What are the valid strings
for ae-name and ae-opts? It looks like the latter is just a number,
so why not use an integer property?

	Arnd

From k.kozlowski at samsung.com  Sun Aug 16 18:01:03 2015
From: k.kozlowski at samsung.com (Krzysztof Kozlowski)
Date: Mon, 17 Aug 2015 10:01:03 +0900
Subject: [PATCH 1/4] clk: samsung: exynos3250: Add UART2 clock
In-Reply-To: <1439264784-30322-2-git-send-email-cw00.choi@samsung.com>
References: <1439264784-30322-1-git-send-email-cw00.choi@samsung.com>
 <1439264784-30322-2-git-send-email-cw00.choi@samsung.com>
Message-ID: <55D1324F.1040908@samsung.com>

On 11.08.2015 12:46, Chanwoo Choi wrote:
> This patch add the UART2 clocks (mux, divider, gate) of Exynos3250 SoC.

I could not confirm the exact numbers used ("reserved" in my datasheet)
but the patch itself looks correct.

Assuming that numbers/addresses are good:
Reviewed-by: Krzysztof Kozlowski <k.kozlowski at samsung.com>


Best regards,
Krzysztof

> 
> Cc: Sylwester Nawrocki <s.nawrocki at samsung.com>
> Cc: Tomasz Figa <tomasz.figa at gmail.com>
> Signed-off-by: Chanwoo Choi <cw00.choi at samsung.com>
> ---
>  drivers/clk/samsung/clk-exynos3250.c   | 6 ++++++
>  include/dt-bindings/clock/exynos3250.h | 6 +++++-
>  2 files changed, 11 insertions(+), 1 deletion(-)
> 



From k.kozlowski at samsung.com  Sun Aug 16 17:33:43 2015
From: k.kozlowski at samsung.com (Krzysztof Kozlowski)
Date: Mon, 17 Aug 2015 09:33:43 +0900
Subject: [PATCH 0/4] ARM: dts: exynos3250: Add UART2 and MMC2 dt node with
 related clocks
In-Reply-To: <1439264784-30322-1-git-send-email-cw00.choi@samsung.com>
References: <1439264784-30322-1-git-send-email-cw00.choi@samsung.com>
Message-ID: <CAJKOXPfvGypFymHzXDMEA295Copi0sjpMG9oKmJ+a_BQoK+SNw@mail.gmail.com>

2015-08-11 12:46 GMT+09:00 Chanwoo Choi <cw00.choi at samsung.com>:
> This patch add the UART2 / MMC2 devicetree node for Exynos3250 SoC and add
> the related clocks (mux, divider, gate) of UART2 / MMC2 device.

What is the benefit of adding them? Why they are needed?

Best regards,
Krzysztof


>
> Chanwoo Choi (4):
>   clk: samsung: exynos3250: Add UART2 clock
>   clk: samsung: exynos3250: Add MMC2 clock
>   ARM: dts: Add UART2 dt node for Exynos3250 SoC
>   ARM: dts: Add MSHC2 dt node for Exynos3250 SoC
>
>  arch/arm/boot/dts/exynos3250-pinctrl.dtsi | 42 +++++++++++++++++++++++++++++++
>  arch/arm/boot/dts/exynos3250.dtsi         | 25 ++++++++++++++++++
>  drivers/clk/samsung/clk-exynos3250.c      | 15 +++++++++++
>  include/dt-bindings/clock/exynos3250.h    | 11 +++++++-
>  4 files changed, 92 insertions(+), 1 deletion(-)
>
> --
> 1.8.5.5
>
>
> _______________________________________________
> linux-arm-kernel mailing list
> linux-arm-kernel at lists.infradead.org
> http://lists.infradead.org/mailman/listinfo/linux-arm-kernel


From msalter at redhat.com  Sun Aug 16 13:49:26 2015
From: msalter at redhat.com (Mark Salter)
Date: Sun, 16 Aug 2015 16:49:26 -0400
Subject: [PATCH V3 1/3] mm: add utility for early copy from unmapped ram
In-Reply-To: <1439758168-29427-1-git-send-email-msalter@redhat.com>
References: <1439758168-29427-1-git-send-email-msalter@redhat.com>
Message-ID: <1439758168-29427-2-git-send-email-msalter@redhat.com>

In some early boot circumstances, it may be necessary to copy
from RAM outside the kernel linear mapping to mapped RAM. The
need to relocate an initrd is one example in the x86 code. This
patch creates a helper function based on current x86 code.

Signed-off-by: Mark Salter <msalter at redhat.com>
---
 include/asm-generic/early_ioremap.h |  6 ++++++
 mm/early_ioremap.c                  | 22 ++++++++++++++++++++++
 2 files changed, 28 insertions(+)

diff --git a/include/asm-generic/early_ioremap.h b/include/asm-generic/early_ioremap.h
index a5de55c..e539f27 100644
--- a/include/asm-generic/early_ioremap.h
+++ b/include/asm-generic/early_ioremap.h
@@ -33,6 +33,12 @@ extern void early_ioremap_setup(void);
  */
 extern void early_ioremap_reset(void);
 
+/*
+ * Early copy from unmapped memory to kernel mapped memory.
+ */
+extern void copy_from_early_mem(void *dest, phys_addr_t src,
+				unsigned long size);
+
 #else
 static inline void early_ioremap_init(void) { }
 static inline void early_ioremap_setup(void) { }
diff --git a/mm/early_ioremap.c b/mm/early_ioremap.c
index e10ccd2..a0baeb4 100644
--- a/mm/early_ioremap.c
+++ b/mm/early_ioremap.c
@@ -217,6 +217,28 @@ early_memremap(resource_size_t phys_addr, unsigned long size)
 	return (__force void *)__early_ioremap(phys_addr, size,
 					       FIXMAP_PAGE_NORMAL);
 }
+
+#define MAX_MAP_CHUNK	(NR_FIX_BTMAPS << PAGE_SHIFT)
+
+void __init copy_from_early_mem(void *dest, phys_addr_t src, unsigned long size)
+{
+	unsigned long slop, clen;
+	char *p;
+
+	while (size) {
+		slop = src & ~PAGE_MASK;
+		clen = size;
+		if (clen > MAX_MAP_CHUNK - slop)
+			clen = MAX_MAP_CHUNK - slop;
+		p = early_memremap(src & PAGE_MASK, clen + slop);
+		memcpy(dest, p + slop, clen);
+		early_memunmap(p, clen + slop);
+		dest += clen;
+		src += clen;
+		size -= clen;
+	}
+}
+
 #else /* CONFIG_MMU */
 
 void __init __iomem *
-- 
2.4.3



From olof at lixom.net  Sun Aug 16 12:38:16 2015
From: olof at lixom.net (Olof Johansson)
Date: Sun, 16 Aug 2015 21:38:16 +0200
Subject: [GIT PULL] ARM: SoC fixes for 4.2-rc
Message-ID: <20150816193816.GA12008@localhost>

Hi Linus,

Apologies for the last minute pull request. No big deal if it doesn't
make it before -rc cut.


Thanks!

-Olof


The following changes since commit c1bfa985ded82cacdfc6403e78f329c44e35534a:

  ARM: dts: keystone: fix dt bindings to use post div register for mainpll (2015-07-31 22:30:11 +0200)

are available in the git repository at:

  git://git.kernel.org/pub/scm/linux/kernel/git/arm/arm-soc.git tags/armsoc-for-linus

for you to fetch changes up to 02149517acbbf5cf0d1819024977963093168106:

  Merge tag 'keystone-dts-late-fixes-v2' of git://git.kernel.org/pub/scm/linux/kernel/git/ssantosh/linux-keystone into fixes (2015-08-16 21:29:57 +0200)

----------------------------------------------------------------
ARM: SoC fixes

A smallish batch of fixes, a little more than expected this late, but
all fixes are contained to their platforms and seem reasonably low risk:

- A somewhat large SMP fix for ux500 that still seemed warranted to include here
- OMAP DT fixes for pbias regulator specification that broke due to some DT
  reshuffling
- PCIe IRQ routing bugfix for i.MX
- Networking fixes for keystone
- Runtime PM for OMAP GPMC
- A couple of error path bug fixes for exynos

----------------------------------------------------------------
Kishon Vijay Abraham I (4):
      ARM: dts: omap243x: Fix broken pbias device creation
      ARM: dts: OMAP4: Fix broken pbias device creation
      ARM: dts: OMAP5: Fix broken pbias device creation
      ARM: dts: dra7: Fix broken pbias device creation

Linus Walleij (1):
      ARM: ux500: add an SMP enablement type and move cpu nodes

Lucas Stach (1):
      ARM: imx6: correct i.MX6 PCIe interrupt routing

Murali Karicheri (2):
      ARM: dts: keystone: fix the clock node for mdio
      ARM: dts: keystone: Fix the mdio bindings by moving it to soc specific file

Olof Johansson (5):
      Merge tag 'omap-for-v4.2/fixes-rc5' of git://git.kernel.org/.../tmlind/linux-omap into fixes
      Merge tag 'samsung-mach-fixes-4.2' of https://github.com/krzk/linux into fixes
      Merge tag 'imx-fixes-4.2-3' of git://git.kernel.org/.../shawnguo/linux into fixes
      Merge tag 'omap-for-v4.2/fixes-rc6' of git://git.kernel.org/.../tmlind/linux-omap into fixes
      Merge tag 'keystone-dts-late-fixes-v2' of git://git.kernel.org/.../ssantosh/linux-keystone into fixes

Tomeu Vizoso (1):
      memory: omap-gpmc: Don't try to save uninitialized GPMC context

Vladimir Zapolskiy (2):
      ARM: EXYNOS: Fix potentian kfree() of ro memory
      ARM: EXYNOS: fix double of_node_put() on error path

 Documentation/devicetree/bindings/arm/cpus.txt |  1 +
 arch/arm/boot/dts/dra7.dtsi                    |  2 +-
 arch/arm/boot/dts/imx6qdl.dtsi                 |  8 ++--
 arch/arm/boot/dts/k2e.dtsi                     | 15 ++++++--
 arch/arm/boot/dts/k2hk.dtsi                    | 11 ++++++
 arch/arm/boot/dts/k2l.dtsi                     | 16 +++++---
 arch/arm/boot/dts/keystone.dtsi                | 11 ------
 arch/arm/boot/dts/omap2430.dtsi                |  3 +-
 arch/arm/boot/dts/omap4.dtsi                   |  3 +-
 arch/arm/boot/dts/omap5.dtsi                   |  3 +-
 arch/arm/boot/dts/ste-dbx5x0.dtsi              | 53 +++++++++++++-------------
 arch/arm/mach-exynos/pm_domains.c              |  3 +-
 drivers/memory/omap-gpmc.c                     |  6 +++
 13 files changed, 79 insertions(+), 56 deletions(-)


From manabian at gmail.com  Sun Aug 16 11:10:16 2015
From: manabian at gmail.com (Joachim Eastwood)
Date: Sun, 16 Aug 2015 20:10:16 +0200
Subject: [PATCH v2 1/2] i2c: add i2c-lpc2k driver
In-Reply-To: <1439748617-7683-1-git-send-email-manabian@gmail.com>
References: <1439748617-7683-1-git-send-email-manabian@gmail.com>
Message-ID: <1439748617-7683-2-git-send-email-manabian@gmail.com>

Add support for the I2C controller found on several NXP devices
including LPC2xxx, LPC178x/7x and LPC18xx/43xx. The controller
is implemented as a state machine and the driver act upon the
state changes when the bus is accessed.

The I2C controller supports master/slave operation, bus
arbitration, programmable clock rate, and speeds up to 1 Mbit/s.

Signed-off-by: Joachim Eastwood <manabian at gmail.com>
---
 drivers/i2c/busses/Kconfig     |  10 +
 drivers/i2c/busses/Makefile    |   1 +
 drivers/i2c/busses/i2c-lpc2k.c | 513 +++++++++++++++++++++++++++++++++++++++++
 3 files changed, 524 insertions(+)
 create mode 100644 drivers/i2c/busses/i2c-lpc2k.c

diff --git a/drivers/i2c/busses/Kconfig b/drivers/i2c/busses/Kconfig
index 0b798ae708fe..48f4b796003c 100644
--- a/drivers/i2c/busses/Kconfig
+++ b/drivers/i2c/busses/Kconfig
@@ -619,6 +619,16 @@ config I2C_KEMPLD
 	  This driver can also be built as a module. If so, the module
 	  will be called i2c-kempld.
 
+config I2C_LPC2K
+	tristate "I2C bus support for NXP LPC2K/LPC178x/18xx/43xx"
+	depends on OF && (ARCH_LPC18XX || COMPILE_TEST)
+	help
+	  This driver supports the I2C interface found several NXP
+	  devices including LPC2xxx, LPC178x/7x and LPC18xx/43xx.
+
+	  This driver can also be built as a module.  If so, the module
+	  will be called i2c-lpc2k.
+
 config I2C_MESON
 	tristate "Amlogic Meson I2C controller"
 	depends on ARCH_MESON
diff --git a/drivers/i2c/busses/Makefile b/drivers/i2c/busses/Makefile
index 50e8bbb65f1c..6df3b303bd09 100644
--- a/drivers/i2c/busses/Makefile
+++ b/drivers/i2c/busses/Makefile
@@ -59,6 +59,7 @@ obj-$(CONFIG_I2C_IMX)		+= i2c-imx.o
 obj-$(CONFIG_I2C_IOP3XX)	+= i2c-iop3xx.o
 obj-$(CONFIG_I2C_JZ4780)	+= i2c-jz4780.o
 obj-$(CONFIG_I2C_KEMPLD)	+= i2c-kempld.o
+obj-$(CONFIG_I2C_LPC2K)		+= i2c-lpc2k.o
 obj-$(CONFIG_I2C_MESON)		+= i2c-meson.o
 obj-$(CONFIG_I2C_MPC)		+= i2c-mpc.o
 obj-$(CONFIG_I2C_MT65XX)	+= i2c-mt65xx.o
diff --git a/drivers/i2c/busses/i2c-lpc2k.c b/drivers/i2c/busses/i2c-lpc2k.c
new file mode 100644
index 000000000000..8560a13bf1b3
--- /dev/null
+++ b/drivers/i2c/busses/i2c-lpc2k.c
@@ -0,0 +1,513 @@
+/*
+ * Copyright (C) 2011 NXP Semiconductors
+ *
+ * Code portions referenced from the i2x-pxa and i2c-pnx drivers
+ *
+ * Make SMBus byte and word transactions work on LPC178x/7x
+ * Copyright (c) 2012
+ * Alexander Potashev, Emcraft Systems, aspotashev at emcraft.com
+ * Anton Protopopov, Emcraft Systems, antonp at emcraft.com
+ *
+ * Copyright (C) 2015 Joachim Eastwood <manabian at gmail.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.
+ *
+ */
+
+#include <linux/clk.h>
+#include <linux/errno.h>
+#include <linux/i2c.h>
+#include <linux/interrupt.h>
+#include <linux/io.h>
+#include <linux/kernel.h>
+#include <linux/module.h>
+#include <linux/of.h>
+#include <linux/of_device.h>
+#include <linux/platform_device.h>
+#include <linux/sched.h>
+#include <linux/time.h>
+
+/* LPC24xx register offsets and bits */
+#define LPC24XX_I2CONSET	0x00
+#define LPC24XX_I2STAT		0x04
+#define LPC24XX_I2DAT		0x08
+#define LPC24XX_I2ADDR		0x0c
+#define LPC24XX_I2SCLH		0x10
+#define LPC24XX_I2SCLL		0x14
+#define LPC24XX_I2CONCLR	0x18
+
+#define LPC24XX_AA		BIT(2)
+#define LPC24XX_SI		BIT(3)
+#define LPC24XX_STO		BIT(4)
+#define LPC24XX_STA		BIT(5)
+#define LPC24XX_I2EN		BIT(6)
+
+#define LPC24XX_STO_AA		(LPC24XX_STO | LPC24XX_AA)
+#define LPC24XX_CLEAR_ALL	(LPC24XX_AA | LPC24XX_SI | LPC24XX_STO | \
+				 LPC24XX_STA | LPC24XX_I2EN)
+
+/* I2C SCL clock has different duty cycle depending on mode */
+#define I2C_STD_MODE_DUTY		46
+#define I2C_FAST_MODE_DUTY		36
+#define I2C_FAST_MODE_PLUS_DUTY		38
+
+/*
+ * 26 possible I2C status codes, but codes applicable only
+ * to master are listed here and used in this driver
+ */
+enum {
+	M_BUS_ERROR		= 0x00,
+	M_START			= 0x08,
+	M_REPSTART		= 0x10,
+	MX_ADDR_W_ACK		= 0x18,
+	MX_ADDR_W_NACK		= 0x20,
+	MX_DATA_W_ACK		= 0x28,
+	MX_DATA_W_NACK		= 0x30,
+	M_DATA_ARB_LOST		= 0x38,
+	MR_ADDR_R_ACK		= 0x40,
+	MR_ADDR_R_NACK		= 0x48,
+	MR_DATA_R_ACK		= 0x50,
+	MR_DATA_R_NACK		= 0x58,
+	M_I2C_IDLE		= 0xf8,
+};
+
+struct lpc2k_i2c {
+	void __iomem		*base;
+	struct clk		*clk;
+	int			irq;
+	wait_queue_head_t	wait;
+	struct i2c_adapter	adap;
+	struct i2c_msg		*msg;
+	int			msg_idx;
+	int			msg_status;
+	int			is_last;
+};
+
+static void i2c_lpc2k_reset(struct lpc2k_i2c *i2c)
+{
+	/* Will force clear all statuses */
+	writel(LPC24XX_CLEAR_ALL, i2c->base + LPC24XX_I2CONCLR);
+	writel(0, i2c->base + LPC24XX_I2ADDR);
+	writel(LPC24XX_I2EN, i2c->base + LPC24XX_I2CONSET);
+}
+
+static int i2c_lpc2k_clear_arb(struct lpc2k_i2c *i2c)
+{
+	unsigned long timeout = jiffies + msecs_to_jiffies(1000);
+
+	/*
+	 * If the transfer needs to abort for some reason, we'll try to
+	 * force a stop condition to clear any pending bus conditions
+	 */
+	writel(LPC24XX_STO, i2c->base + LPC24XX_I2CONSET);
+
+	/* Wait for status change */
+	while (readl(i2c->base + LPC24XX_I2STAT) != M_I2C_IDLE) {
+		if (time_after(jiffies, timeout)) {
+			/* Bus was not idle, try to reset adapter */
+			i2c_lpc2k_reset(i2c);
+			return -EBUSY;
+		}
+
+		cpu_relax();
+	}
+
+	return 0;
+}
+
+static void i2c_lpc2k_pump_msg(struct lpc2k_i2c *i2c)
+{
+	unsigned char data;
+	u32 status;
+
+	/*
+	 * I2C in the LPC2xxx series is basically a state machine.
+	 * Just run through the steps based on the current status.
+	 */
+	status = readl(i2c->base + LPC24XX_I2STAT);
+
+	switch (status) {
+	case M_START:
+	case M_REPSTART:
+		/* Start bit was just sent out, send out addr and dir */
+		data = i2c->msg->addr << 1;
+		if (i2c->msg->flags & I2C_M_RD)
+			data |= 1;
+
+		writel(data, i2c->base + LPC24XX_I2DAT);
+		writel(LPC24XX_STA, i2c->base + LPC24XX_I2CONCLR);
+		break;
+
+	case MX_ADDR_W_ACK:
+	case MX_DATA_W_ACK:
+		/*
+		 * Address or data was sent out with an ACK. If there is more
+		 * data to send, send it now
+		 */
+		if (i2c->msg_idx < i2c->msg->len) {
+			writel(i2c->msg->buf[i2c->msg_idx],
+			       i2c->base + LPC24XX_I2DAT);
+		} else if (i2c->is_last) {
+			/* Last message, send stop */
+			writel(LPC24XX_STO_AA, i2c->base + LPC24XX_I2CONSET);
+			writel(LPC24XX_SI, i2c->base + LPC24XX_I2CONCLR);
+			i2c->msg_status = 0;
+			disable_irq_nosync(i2c->irq);
+		} else {
+			i2c->msg_status = 0;
+			disable_irq_nosync(i2c->irq);
+		}
+
+		i2c->msg_idx++;
+		break;
+
+	case MR_ADDR_R_ACK:
+		/* Receive first byte from slave */
+		if (i2c->msg->len == 1) {
+			/* Last byte, return NACK */
+			writel(LPC24XX_AA, i2c->base + LPC24XX_I2CONCLR);
+		} else {
+			/* Not last byte, return ACK */
+			writel(LPC24XX_AA, i2c->base + LPC24XX_I2CONSET);
+		}
+
+		writel(LPC24XX_STA, i2c->base + LPC24XX_I2CONCLR);
+		break;
+
+	case MR_DATA_R_NACK:
+		/*
+		 * The I2C shows NACK status on reads, so we need to accept
+		 * the NACK as an ACK here. This should be ok, as the real
+		 * BACK would of been caught on the address write.
+		 */
+	case MR_DATA_R_ACK:
+		/* Data was received */
+		if (i2c->msg_idx < i2c->msg->len) {
+			i2c->msg->buf[i2c->msg_idx] =
+					readl(i2c->base + LPC24XX_I2DAT);
+		}
+
+		/* If transfer is done, send STOP */
+		if (i2c->msg_idx >= i2c->msg->len - 1 && i2c->is_last) {
+			writel(LPC24XX_STO_AA, i2c->base + LPC24XX_I2CONSET);
+			writel(LPC24XX_SI, i2c->base + LPC24XX_I2CONCLR);
+			i2c->msg_status = 0;
+		}
+
+		/* Message is done */
+		if (i2c->msg_idx >= i2c->msg->len - 1) {
+			i2c->msg_status = 0;
+			disable_irq_nosync(i2c->irq);
+		}
+
+		/*
+		 * One pre-last data input, send NACK to tell the slave that
+		 * this is going to be the last data byte to be transferred.
+		 */
+		if (i2c->msg_idx >= i2c->msg->len - 2) {
+			/* One byte left to receive - NACK */
+			writel(LPC24XX_AA, i2c->base + LPC24XX_I2CONCLR);
+		} else {
+			/* More than one byte left to receive - ACK */
+			writel(LPC24XX_AA, i2c->base + LPC24XX_I2CONSET);
+		}
+
+		writel(LPC24XX_STA, i2c->base + LPC24XX_I2CONCLR);
+		i2c->msg_idx++;
+		break;
+
+	case MX_ADDR_W_NACK:
+	case MX_DATA_W_NACK:
+	case MR_ADDR_R_NACK:
+		/* NACK processing is done */
+		writel(LPC24XX_STO_AA, i2c->base + LPC24XX_I2CONSET);
+		i2c->msg_status = -ENXIO;
+		disable_irq_nosync(i2c->irq);
+		break;
+
+	case M_DATA_ARB_LOST:
+		/* Arbitration lost */
+		i2c->msg_status = -EAGAIN;
+
+		/* Release the I2C bus */
+		writel(LPC24XX_STA | LPC24XX_STO, i2c->base + LPC24XX_I2CONCLR);
+		disable_irq_nosync(i2c->irq);
+		break;
+
+	default:
+		/* Unexpected statuses */
+		i2c->msg_status = -EIO;
+		disable_irq_nosync(i2c->irq);
+		break;
+	}
+
+	/* Exit on failure or all bytes transferred */
+	if (i2c->msg_status != -EBUSY)
+		wake_up(&i2c->wait);
+
+	/*
+	 * If `msg_status` is zero, then `lpc2k_process_msg()`
+	 * is responsible for clearing the SI flag.
+	 */
+	if (i2c->msg_status != 0)
+		writel(LPC24XX_SI, i2c->base + LPC24XX_I2CONCLR);
+}
+
+static int lpc2k_process_msg(struct lpc2k_i2c *i2c, int msgidx)
+{
+	/* A new transfer is kicked off by initiating a start condition */
+	if (!msgidx) {
+		writel(LPC24XX_STA, i2c->base + LPC24XX_I2CONSET);
+	} else {
+		/*
+		 * A multi-message I2C transfer continues where the
+		 * previous I2C transfer left off and uses the
+		 * current condition of the I2C adapter.
+		 */
+		if (unlikely(i2c->msg->flags & I2C_M_NOSTART)) {
+			WARN_ON(i2c->msg->len == 0);
+
+			if (!(i2c->msg->flags & I2C_M_RD)) {
+				/* Start transmit of data */
+				writel(i2c->msg->buf[0],
+				       i2c->base + LPC24XX_I2DAT);
+				i2c->msg_idx++;
+			}
+		} else {
+			/* Start or repeated start */
+			writel(LPC24XX_STA, i2c->base + LPC24XX_I2CONSET);
+		}
+
+		writel(LPC24XX_SI, i2c->base + LPC24XX_I2CONCLR);
+	}
+
+	enable_irq(i2c->irq);
+
+	/* Wait for transfer completion */
+	if (wait_event_timeout(i2c->wait, i2c->msg_status != -EBUSY,
+			       msecs_to_jiffies(1000)) == 0) {
+		disable_irq_nosync(i2c->irq);
+
+		return -ETIMEDOUT;
+	}
+
+	return i2c->msg_status;
+}
+
+static int i2c_lpc2k_xfer(struct i2c_adapter *adap, struct i2c_msg *msgs,
+			  int msg_num)
+{
+	struct lpc2k_i2c *i2c = i2c_get_adapdata(adap);
+	int ret, i;
+	u32 stat;
+
+	/* Check for bus idle condition */
+	stat = readl(i2c->base + LPC24XX_I2STAT);
+	if (stat != M_I2C_IDLE) {
+		/* Something is holding the bus, try to clear it */
+		return i2c_lpc2k_clear_arb(i2c);
+	}
+
+	/* Process a single message at a time */
+	for (i = 0; i < msg_num; i++) {
+		/* Save message pointer and current message data index */
+		i2c->msg = &msgs[i];
+		i2c->msg_idx = 0;
+		i2c->msg_status = -EBUSY;
+		i2c->is_last = (i == (msg_num - 1));
+
+		ret = lpc2k_process_msg(i2c, i);
+		if (ret)
+			return ret;
+	}
+
+	return msg_num;
+}
+
+static irqreturn_t i2c_lpc2k_handler(int irq, void *dev_id)
+{
+	struct lpc2k_i2c *i2c = dev_id;
+
+	if (readl(i2c->base + LPC24XX_I2CONSET) & LPC24XX_SI) {
+		i2c_lpc2k_pump_msg(i2c);
+		return IRQ_HANDLED;
+	}
+
+	return IRQ_NONE;
+}
+
+static u32 i2c_lpc2k_functionality(struct i2c_adapter *adap)
+{
+	/* Only emulated SMBus for now */
+	return I2C_FUNC_I2C | I2C_FUNC_SMBUS_EMUL;
+}
+
+static const struct i2c_algorithm i2c_lpc2k_algorithm = {
+	.master_xfer	= i2c_lpc2k_xfer,
+	.functionality	= i2c_lpc2k_functionality,
+};
+
+static int i2c_lpc2k_probe(struct platform_device *pdev)
+{
+	struct lpc2k_i2c *i2c;
+	struct resource *res;
+	u32 bus_clk_rate;
+	u32 scl_high;
+	u32 clkrate;
+	int ret;
+
+	i2c = devm_kzalloc(&pdev->dev, sizeof(*i2c), GFP_KERNEL);
+	if (!i2c)
+		return -ENOMEM;
+
+	res = platform_get_resource(pdev, IORESOURCE_MEM, 0);
+	i2c->base = devm_ioremap_resource(&pdev->dev, res);
+	if (IS_ERR(i2c->base))
+		return PTR_ERR(i2c->base);
+
+	i2c->irq = platform_get_irq(pdev, 0);
+	if (i2c->irq < 0) {
+		dev_err(&pdev->dev, "can't get interrupt resource\n");
+		return i2c->irq;
+	}
+
+	init_waitqueue_head(&i2c->wait);
+
+	i2c->clk = devm_clk_get(&pdev->dev, NULL);
+	if (IS_ERR(i2c->clk)) {
+		dev_err(&pdev->dev, "error getting clock\n");
+		return PTR_ERR(i2c->clk);
+	}
+
+	ret = clk_prepare_enable(i2c->clk);
+	if (ret) {
+		dev_err(&pdev->dev, "unable to enable clock.\n");
+		return ret;
+	}
+
+	ret = devm_request_irq(&pdev->dev, i2c->irq, i2c_lpc2k_handler, 0,
+			       dev_name(&pdev->dev), i2c);
+	if (ret < 0) {
+		dev_err(&pdev->dev, "can't request interrupt.\n");
+		goto fail_clk;
+	}
+
+	disable_irq_nosync(i2c->irq);
+
+	/* Place controller is a known state */
+	i2c_lpc2k_reset(i2c);
+
+	ret = of_property_read_u32(pdev->dev.of_node, "clock-frequency",
+				   &bus_clk_rate);
+	if (ret)
+		bus_clk_rate = 100000; /* 100 kHz default clock rate */
+
+	clkrate = clk_get_rate(i2c->clk);
+	if (clkrate == 0) {
+		dev_err(&pdev->dev, "can't get I2C base clock\n");
+		ret = -EINVAL;
+		goto fail_clk;
+	}
+
+	/* Setup I2C dividers to generate clock with proper duty cycle */
+	clkrate = clkrate / bus_clk_rate;
+	if (bus_clk_rate <= 100000)
+		scl_high = (clkrate * I2C_STD_MODE_DUTY) / 100;
+	else if (bus_clk_rate <= 400000)
+		scl_high = (clkrate * I2C_FAST_MODE_DUTY) / 100;
+	else
+		scl_high = (clkrate * I2C_FAST_MODE_PLUS_DUTY) / 100;
+
+	writel(scl_high, i2c->base + LPC24XX_I2SCLH);
+	writel(clkrate - scl_high, i2c->base + LPC24XX_I2SCLL);
+
+	platform_set_drvdata(pdev, i2c);
+
+	i2c_set_adapdata(&i2c->adap, i2c);
+	i2c->adap.owner = THIS_MODULE;
+	strlcpy(i2c->adap.name, "LPC2K I2C adapter", sizeof(i2c->adap.name));
+	i2c->adap.algo = &i2c_lpc2k_algorithm;
+	i2c->adap.dev.parent = &pdev->dev;
+	i2c->adap.dev.of_node = pdev->dev.of_node;
+
+	ret = i2c_add_adapter(&i2c->adap);
+	if (ret < 0) {
+		dev_err(&pdev->dev, "failed to add adapter!\n");
+		goto fail_clk;
+	}
+
+	dev_info(&pdev->dev, "LPC2K I2C adapter\n");
+
+	return 0;
+
+fail_clk:
+	clk_disable_unprepare(i2c->clk);
+	return ret;
+}
+
+static int i2c_lpc2k_remove(struct platform_device *dev)
+{
+	struct lpc2k_i2c *i2c = platform_get_drvdata(dev);
+
+	i2c_del_adapter(&i2c->adap);
+	clk_disable_unprepare(i2c->clk);
+
+	return 0;
+}
+
+#ifdef CONFIG_PM
+static int i2c_lpc2k_suspend(struct device *dev)
+{
+	struct platform_device *pdev = to_platform_device(dev);
+	struct lpc2k_i2c *i2c = platform_get_drvdata(pdev);
+
+	clk_disable(i2c->clk);
+
+	return 0;
+}
+
+static int i2c_lpc2k_resume(struct device *dev)
+{
+	struct platform_device *pdev = to_platform_device(dev);
+	struct lpc2k_i2c *i2c = platform_get_drvdata(pdev);
+
+	clk_enable(i2c->clk);
+	i2c_lpc2k_reset(i2c);
+
+	return 0;
+}
+
+static const struct dev_pm_ops i2c_lpc2k_dev_pm_ops = {
+	.suspend_noirq = i2c_lpc2k_suspend,
+	.resume_noirq = i2c_lpc2k_resume,
+};
+
+#define I2C_LPC2K_DEV_PM_OPS (&i2c_lpc2k_dev_pm_ops)
+#else
+#define I2C_LPC2K_DEV_PM_OPS NULL
+#endif
+
+static const struct of_device_id lpc2k_i2c_match[] = {
+	{ .compatible = "nxp,lpc1788-i2c" },
+	{},
+};
+MODULE_DEVICE_TABLE(of, lpc2k_i2c_match);
+
+static struct platform_driver i2c_lpc2k_driver = {
+	.probe	= i2c_lpc2k_probe,
+	.remove	= i2c_lpc2k_remove,
+	.driver	= {
+		.name		= "lpc2k-i2c",
+		.pm		= I2C_LPC2K_DEV_PM_OPS,
+		.of_match_table	= lpc2k_i2c_match,
+	},
+};
+module_platform_driver(i2c_lpc2k_driver);
+
+MODULE_AUTHOR("Kevin Wells <kevin.wells at nxp.com>");
+MODULE_DESCRIPTION("I2C driver for LPC2xxx devices");
+MODULE_LICENSE("GPL");
+MODULE_ALIAS("platform:lpc2k-i2c");
-- 
1.8.0



From maxime.ripard at free-electrons.com  Sun Aug 16 09:22:21 2015
From: maxime.ripard at free-electrons.com (Maxime Ripard)
Date: Sun, 16 Aug 2015 18:22:21 +0200
Subject: [PATCH] ARM: dts: sunxi: enable otg port on the
 sun7i-a20-olinuxino-lime2
In-Reply-To: <1439144578-7890-2-git-send-email-oliver@schinagl.nl>
References: <1439144578-7890-1-git-send-email-oliver@schinagl.nl>
 <1439144578-7890-2-git-send-email-oliver@schinagl.nl>
Message-ID: <20150816162221.GF9000@lukather>

On Sun, Aug 09, 2015 at 08:22:58PM +0200, Olliver Schinagl wrote:
> From: Olliver Schinagl <o.schinagl at ultimaker.com>
> 
> This patch enables the musb-otg USB controller on the Lime2. The Lime2
> differs from the Lime1 series in pins used for usb0 power.
> 
> Tested on a OlinuXino Lime2-4GB.
> 
> Signed-off-by: Olliver Schinagl <oliver at schinagl.nl>

Queued, thanks!

Maxime

-- 
Maxime Ripard, Free Electrons
Embedded Linux, Kernel and Android engineering
http://free-electrons.com
-------------- next part --------------
A non-text attachment was scrubbed...
Name: signature.asc
Type: application/pgp-signature
Size: 819 bytes
Desc: Digital signature
URL: <http://lists.infradead.org/pipermail/linux-arm-kernel/attachments/20150816/e051e7a0/attachment-0001.sig>

From maxime.ripard at free-electrons.com  Sun Aug 16 09:21:51 2015
From: maxime.ripard at free-electrons.com (Maxime Ripard)
Date: Sun, 16 Aug 2015 18:21:51 +0200
Subject: [PATCH] ARM: dts: sun4i: Enable i2c1 and i2c2 on the Chuwi
 V7-CW0825 tablet
In-Reply-To: <1439048334-14704-1-git-send-email-hdegoede@redhat.com>
References: <1439048334-14704-1-git-send-email-hdegoede@redhat.com>
Message-ID: <20150816162151.GE9000@lukather>

On Sat, Aug 08, 2015 at 05:38:54PM +0200, Hans de Goede wrote:
> i2c1 has a freescale mma7660 accelerometer connected to it at addr 0x4c,
> i2c2 has a ft5x touchscreen connected to it at addr 0x38.
> 
> Signed-off-by: Hans de Goede <hdegoede at redhat.com>

Queued, thanks!

Maxime

-- 
Maxime Ripard, Free Electrons
Embedded Linux, Kernel and Android engineering
http://free-electrons.com
-------------- next part --------------
A non-text attachment was scrubbed...
Name: signature.asc
Type: application/pgp-signature
Size: 819 bytes
Desc: Digital signature
URL: <http://lists.infradead.org/pipermail/linux-arm-kernel/attachments/20150816/ff8b8053/attachment-0001.sig>

From maxime.ripard at free-electrons.com  Sun Aug 16 09:11:37 2015
From: maxime.ripard at free-electrons.com (Maxime Ripard)
Date: Sun, 16 Aug 2015 18:11:37 +0200
Subject: [PATCH] ARM: dts: sun4i: Enable otg in host only mode on Jesurun
 Q5
In-Reply-To: <1438723809-9010-1-git-send-email-hdegoede@redhat.com>
References: <1438723809-9010-1-git-send-email-hdegoede@redhat.com>
Message-ID: <20150816161137.GD9000@lukather>

1;3803;0c
On Tue, Aug 04, 2015 at 11:30:09PM +0200, Hans de Goede wrote:
> The Jesurun Q5 has the musb hooked up to an usb-a receptacle, enable it
> in host-only mode.
> 
> Signed-off-by: Hans de Goede <hdegoede at redhat.com>

Queued, thanks!

Maxime

-- 
Maxime Ripard, Free Electrons
Embedded Linux, Kernel and Android engineering
http://free-electrons.com
-------------- next part --------------
A non-text attachment was scrubbed...
Name: signature.asc
Type: application/pgp-signature
Size: 819 bytes
Desc: Digital signature
URL: <http://lists.infradead.org/pipermail/linux-arm-kernel/attachments/20150816/19c257b1/attachment-0001.sig>

From baranikumar.venkatesan at harman.com  Fri Aug 14 01:28:01 2015
From: baranikumar.venkatesan at harman.com (baranikumar.venkatesan)
Date: Fri, 14 Aug 2015 08:28:01 +0000 (UTC)
Subject: Problems with device tree PMC clocks and threadirqs on at91
References: <555C8117.9010508@pcs.com>
Message-ID: <loom.20150814T101121-265@post.gmane.org>

Wolfgang Steinwender <wsteinwender <at> pcs.com> writes:

 
 I'm using a custom board with AT91SAM9G35. Booting with parameter
 threadirqs fails with kernel oops.
 
 In time_init(), the PMC is initialized. An IRQ is requested. The
 IRQ is threaded and wake_up_process(kthreadd_task) is called.
 But kthreadd_task is only initialized some time after time_init().
 
 Unable to handle kernel NULL pointer dereference at virtual address 00000000
 pgd = c0004000
 [00000000] *pgd=00000000
 Internal error: Oops: 5 [#1] ARM
 Modules linked in:
 CPU: 0 PID: 0 Comm: swapper Not tainted 4.1.0-rc4 #2
 Hardware name: Atmel AT91SAM9
 task: c04d6e90 ti: c04d2000 task.ti: c04d2000
 PC is at wake_up_process+0xc/0x48
 LR is at kthread_create_on_node+0x88/0x128
 pc : [<c0034838>]    lr : [<c002e494>]    psr: a00000d3
 sp : c04d3e78  ip : c04d3e90  fp : c04d3e8c
 r10: 00000000  r9 : c7801640  r8 : c7801640
 r7 : c003ee6c  r6 : ffffffff  r5 : c04d3e90  r4 : c78025e0
 r3 : c04eccfc  r2 : c78025f4  r1 : c04d9880  r0 : 00000000
 Flags: NzCv  IRQs off  FIQs off  Mode SVC_32  ISA ARM  Segment kernel
 Control: 0005317f  Table: 20004000  DAC: 00000017
 Process swapper (pid: 0, stack limit = 0xc04d2190)
 Stack: (0xc04d3e78 to 0xc04d4000)
 3e60:                                                       c78025e0 04d3e90
 3e80: c04d3ec8 c04d3e90 c002e494 c003483c 00000000 c04d3e94 c04d3e94 7801090
 3ea0: c7801088 00040080 c7804a00 c7801640 00000010 c78023e0 c7804a00 c04d3efc
 3ec0: c04d3ed0 c003fb7c c002e420 c045a704 00000010 c047c18c 00040080 c023ff14
 3ee0: 00000010 00000000 c78023e0 c7804a00 c04d3f2c c04d3f00 c003ffa4 c003f8a0
 3f00: 00040080 fefffc00 c78023e0 c7ee5d70 c03d9274 00000010 c04e5734 00000001
 3f20: c04d3f5c c04d3f30 c04c29cc c003fecc c047c18c c78023e0 c023e808 00000001
 3f40: c7ee5d70 c7802400 c7802420 00000000 c04d3f6c c04d3f60 c04c2ae0 c04c2918
 3f60: c04d3fa4 c04d3f70 c04c2720 c04c2adc 00000000 00000000 00000000 c04cc994
 3f80: 00000000 ffffffff c04ec1c0 c04cc0dc 41069265 c04d4000 c04d3fb4 c04d3fa8
 3fa0: c04af364 c04c2630 c04d3ff4 c04d3fb8 c04adcbc c04af348 ffffffff ffffffff
 3fc0: c04ad868 00000000 00000000 c04cc994 c04ec300 c04d4018 c04cc990 c04d7ba0
 3fe0: 20004000 204cbacc 00000000 c04d3ff8 20008048 c04adab8 00000000 00000000
 Backtrace:
 [<c003482c>] (wake_up_process) from [<c002e494>]
(kthread_create_on_node+0x88/0x128)
   r5:c04d3e90 r4:c78025e0
 [<c002e410>] (kthread_create_on_node) from [<c003fb7c>]
(__setup_irq+0x2ec/0x4d4)
   r10:c7804a00 r8:c78023e0 r7:00000010 r6:c7801640 r5:c7804a00 r4:00040080
 [<c003f890>] (__setup_irq) from [<c003ffa4>] (request_threaded_irq+0xe8/0x15c)
   r10:c7804a00 r8:c78023e0 r7:00000000 r6:00000010 r5:c023ff14 r4:00040080
 [<c003febc>] (request_threaded_irq) from [<c04c29cc>]
(of_at91_pmc_setup+0xc4/0x154)
   r10:00000001 r9:c04e5734 r8:00000010 r7:c03d9274 r6:c7ee5d70 r5:c78023e0
   r4:fefffc00 r3:00040080
 [<c04c2908>] (of_at91_pmc_setup) from [<c04c2ae0>]
(of_at91sam9x5_pmc_setup+0x14/0x1c)
   r8:00000000 r7:c7802420 r6:c7802400 r5:c7ee5d70 r4:00000001
 [<c04c2acc>] (of_at91sam9x5_pmc_setup) from [<c04c2720>]
(of_clk_init+0x100/0x190)
 [<c04c2620>] (of_clk_init) from [<c04af364>] (time_init+0x2c/0x38)
   r10:c04d4000 r9:41069265 r8:c04cc0dc r7:c04ec1c0 r6:ffffffff r5:00000000
   r4:c04cc994
 [<c04af338>] (time_init) from [<c04adcbc>] (start_kernel+0x214/0x340)
 [<c04adaa8>] (start_kernel) from [<20008048>] (0x20008048)
   r10:204cbacc r8:20004000 r7:c04d7ba0 r6:c04cc990 r5:c04d4018 r4:c04ec300
 Code: e89da800 e1a0c00d e92dd830 e24cb004 (e5903000)
 ---[ end trace cb88537fdc8fa200 ]---
 
 Some more information:
 - Log is for 4.1-rc4, also happens on 3.18.11 and linux-at91 master
 - device tree: at91sam9g35ek.dtb, appended to the kernel
 - Maybe this is not arm related, there is a similar issue on MIPS
    (threaded IRQ requested before kthreadd_task is set):
    https://lkml.org/lkml/2014/10/18/31
 
 Solutions I can think of:
 - Make all IRQs requested that early in the boot process IRQF_NO_THREAD.
    Helps with pmc_setup(), but more changes required for other clocks
    (e.g. in clk-main.c).
 - If kthreadd_task is not set, do not allow IRQ threads
    (in irq_setup_forced_threading()).
 - Do not wake up kthreadd_task in kthread_create_on_node() if kthreadd_task
    is NULL. Why is wake_up_process() required?
 
 Did I miss something?
 Any suggestions?
 
 Regards,
 W. Steinwender
 



I'm getting the same issue as described above for Atmel SAMA5D31 board which
is supported in kernel v3.18.9 with rt5+ patch. Also I've attempted your
suggestion numbered 3(Do not wake up kthreadd_task in
kthread_create_on_node() if kthreadd_task is NULL), but no luck. Could you
help me if at all you have the solution?

Regards,
Barani.




From bigeasy at linutronix.de  Sun Aug 16 04:42:41 2015
From: bigeasy at linutronix.de (Sebastian Andrzej Siewior)
Date: Sun, 16 Aug 2015 13:42:41 +0200
Subject: [4.1.3-rt3] [report][suspend to ram] BUG: sleeping function
 called from invalid context at kernel/locking/rtmutex.c:917
In-Reply-To: <55CB8FAE.9020309@ti.com>
References: <55CB8FAE.9020309@ti.com>
Message-ID: <20150816114241.GC7004@linutronix.de>

* Grygorii Strashko | 2015-08-12 21:25:50 [+0300]:

>Hi All,
>
>I can constantly see below error report with RT-kernel on TI ARM dra7-evm 
>if I'm trying to do Suspend to RAM.

do you see the same problem on x86 with -RT?

> Disabling non-boot CPUs ...
> PM: noirq suspend of devices complete after 7.295 msecs
>[  100.285729] Disabling non-boot CPUs ...
>[  100.287575] BUG: sleeping function called from invalid context at kernel/locking/rtmutex.c:917
>[  100.287580] in_atomic(): 1, irqs_disabled(): 128, pid: 18, name: migration/1
>[  100.287583] INFO: lockdep is turned off.
>[  100.287586] irq event stamp: 122
>[  100.287600] hardirqs last  enabled at (121): [<c06ac0ac>] _raw_spin_unlock_irqrestore+0x88/0x90
>[  100.287609] hardirqs last disabled at (122): [<c06abed0>] _raw_spin_lock_irq+0x28/0x5c
>[  100.287620] softirqs last  enabled at (0): [<c003d294>] copy_process.part.52+0x410/0x19d8
>[  100.287625] softirqs last disabled at (0): [<  (null)>]   (null)
>[  100.287630] Preemption disabled at:[<  (null)>]   (null)
>[  100.287631] 
>[  100.287639] CPU: 1 PID: 18 Comm: migration/1 Tainted: G        W       4.1.4-rt3-01046-g96ac8da #204
>[  100.287642] Hardware name: Generic DRA74X (Flattened Device Tree)
>[  100.287659] [<c0019134>] (unwind_backtrace) from [<c0014774>] (show_stack+0x20/0x24)
>[  100.287671] [<c0014774>] (show_stack) from [<c06a70f4>] (dump_stack+0x88/0xdc)
>[  100.287681] [<c06a70f4>] (dump_stack) from [<c006cab8>] (___might_sleep+0x198/0x2a8)
>[  100.287689] [<c006cab8>] (___might_sleep) from [<c06ac4dc>] (rt_spin_lock+0x30/0x70)
>[  100.287699] [<c06ac4dc>] (rt_spin_lock) from [<c013f790>] (find_lock_task_mm+0x9c/0x174)

this is task_lock() which takes a sleeping lock.

>[  100.287710] [<c013f790>] (find_lock_task_mm) from [<c00409ac>] (clear_tasks_mm_cpumask+0xb4/0x1ac)
>[  100.287720] [<c00409ac>] (clear_tasks_mm_cpumask) from [<c00166a4>] (__cpu_disable+0x98/0xbc)
>[  100.287728] [<c00166a4>] (__cpu_disable) from [<c06a2e8c>] (take_cpu_down+0x1c/0x50)
>[  100.287742] [<c06a2e8c>] (take_cpu_down) from [<c00f2600>] (multi_cpu_stop+0x11c/0x158)
>[  100.287754] [<c00f2600>] (multi_cpu_stop) from [<c00f2a9c>] (cpu_stopper_thread+0xc4/0x184)

this function contains local_save_flags().

>[  100.287767] [<c00f2a9c>] (cpu_stopper_thread) from [<c0069058>] (smpboot_thread_fn+0x18c/0x324)
>[  100.287779] [<c0069058>] (smpboot_thread_fn) from [<c00649c4>] (kthread+0xe8/0x104)
>[  100.287791] [<c00649c4>] (kthread) from [<c0010058>] (ret_from_fork+0x14/0x3c)
>[  100.288114] CPU1: shutdown

The local_save_flags() should be probably replaced with something else. 

>regards,
>-grygorii

Sebastian


From nigel at nigelcunningham.com.au  Sun Aug 16 23:48:49 2015
From: nigel at nigelcunningham.com.au (Nigel Cunningham)
Date: Mon, 17 Aug 2015 16:48:49 +1000
Subject: [PATCH v2] dmaengine: fsl-edma: add PM suspend/resume support
In-Reply-To: <CY1PR0301MB1562103588FB0C6BEFDDBF3C83790@CY1PR0301MB1562.namprd03.prod.outlook.com>
References: <1437469005-3162-1-git-send-email-yao.yuan@freescale.com>	<CADRPPNQJi_x+mdQV=DEVuhCL_p6VOWcPiV3jzioeRdWgSW2w3g@mail.gmail.com>	<CY1PR0301MB15628DD5CFCE2B65BF4FECB2837C0@CY1PR0301MB1562.namprd03.prod.outlook.com>
 <CADRPPNS_wzX+mwT0L-H=ZP9w8gH9W4O9KUqnGYiAc39S5v4qLA@mail.gmail.com>
 <CY1PR0301MB1562103588FB0C6BEFDDBF3C83790@CY1PR0301MB1562.namprd03.prod.outlook.com>
Message-ID: <55D183D1.9020401@nigelcunningham.com.au>

Hi Yao.

On 17/08/15 13:59, Yao Yuan wrote:
> On Sat, Aug 15, 2015 at 7:48 AM, pku.leo < pku.leo at gmail.com > wrote:
>> On Fri, Aug 14, 2015 at 1:24 AM, Yao Yuan <yao.yuan at freescale.com> wrote:
>>> Hi Leo,
>>>
>>> Thanks for your review.
>>> About those two methods for DMA suspend that you have mentioned. We
>> have a lot of the discussions in other DMA driver like DMA for Freescale
>> PowerPC.
>>> Finally, we think the device which used the DMA transmission service should
>> cancel the transmission service in its suspend.
>>> So DMA in suspend should be idle.
>> If that's the case you should clearly state this in the commit message and in
>> code, although I don't know if it is safe to make such assumption.  There could
>> be user of the DMA that doesn't track the completion of transfers.
> I think it should be safe. In my opinion, even some client(the user of the DMA) forget to cancel its DMA transmission,
> It will just lead to PM failed but no other system and data risk.
> Although we should first fix the behavior of the client.
> Once you are no need the DMA transmission, why not stop it?
>
> Is it right?
Think of it from the end user perspective. Would you like your laptop (or whatever) to refuse to suspend because of this condition? The user may well expect that closing the lid on their laptop will reliably lead to it suspending to ram. Returning a failure here could result in a loss of data if the condition is not detected and the machine subsequently runs out of power.

I do agree that whatever is submitting DMA should be stopped first; ideally this driver would always be idle because whatever producers of work exist would already have been quiesced and output flushed.

Regards,

Nigel


From hramrach at gmail.com  Sun Aug 16 22:52:00 2015
From: hramrach at gmail.com (Michal Suchanek)
Date: Mon, 17 Aug 2015 07:52:00 +0200
Subject: [PATCH 2/3] mmc: dw_mmc: simplify the SDMMC_CLKEN_LOW_PWR logic
In-Reply-To: <55D13F07.70309@samsung.com>
References: <cover.1439381423.git.hramrach@gmail.com>
 <3d03bfe2c18789eefa038018467c9c63c94ae4a2.1439381423.git.hramrach@gmail.com>
 <55D13F07.70309@samsung.com>
Message-ID: <CAOMqctQ8DHj6qPg8zR93OGRHXAZDd0yUmG_J8Vz7dGFuDpCgRQ@mail.gmail.com>

Hello,

On 17 August 2015 at 03:55, Jaehoon Chung <jh80.chung at samsung.com> wrote:
> Hi, Michal.
>
> On 08/12/2015 09:23 PM, Michal Suchanek wrote:
>> The driver has open-coded test for SDIO cards. Use the mmc core provided
>> MMC_QUIRK_BROKEN_CLK_GATING flag instead.
>
> Did you use the clock-gating for SDIO cards?
> Doesn't MMC_CAP_SDIO_IRQ bit set? Which case is broken?
> Could you explain to me more?

The core flag for disabling power saving is MMC_QUIRK_BROKEN_CLK_GATING.

It may coincide with MMC_CAP_SDIO_IRQ but that's different flag for
different purpose.

MMC_QUIRK_BROKEN_CLK_GATING is currently set for all SDIO cards except
for cards on a whitelist.

I don't know any particular SDIO card that has problems when the clock
is off and does not use an IRQ.

Thanks

Michal

>
> Best Regards,
> Jaehoon Chung
>
>>
>> As a bonus this may enable clock gating on SDIO cards that are known to
>> work with it.
>>
>> Signed-off-by: Michal Suchanek <hramrach at gmail.com>
>> ---
>>  drivers/mmc/host/dw_mmc.c | 33 +++++++++++++++------------------
>>  1 file changed, 15 insertions(+), 18 deletions(-)
>>
>> diff --git a/drivers/mmc/host/dw_mmc.c b/drivers/mmc/host/dw_mmc.c
>> index 40e9d8e..3bc9fd7 100644
>> --- a/drivers/mmc/host/dw_mmc.c
>> +++ b/drivers/mmc/host/dw_mmc.c
>> @@ -1335,27 +1335,24 @@ static void dw_mci_init_card(struct mmc_host *mmc, struct mmc_card *card)
>>        * description of the CLKENA register we should disable low power mode
>>        * for SDIO cards if we need SDIO interrupts to work.
>>        */
>> -     if (mmc->caps & MMC_CAP_SDIO_IRQ) {
>> -             const u32 clken_low_pwr = SDMMC_CLKEN_LOW_PWR << slot->id;
>> -             u32 clk_en_a_old;
>> -             u32 clk_en_a;
>> +     const u32 clken_low_pwr = SDMMC_CLKEN_LOW_PWR << slot->id;
>> +     u32 clk_en_a_old;
>> +     u32 clk_en_a;
>>
>> -             clk_en_a_old = mci_readl(host, CLKENA);
>> +     clk_en_a_old = mci_readl(host, CLKENA);
>>
>> -             if (card->type == MMC_TYPE_SDIO ||
>> -                 card->type == MMC_TYPE_SD_COMBO) {
>> -                     set_bit(DW_MMC_CARD_NO_LOW_PWR, &slot->flags);
>> -                     clk_en_a = clk_en_a_old & ~clken_low_pwr;
>> -             } else {
>> -                     clear_bit(DW_MMC_CARD_NO_LOW_PWR, &slot->flags);
>> -                     clk_en_a = clk_en_a_old | clken_low_pwr;
>> -             }
>> +     if (card->quirks & MMC_QUIRK_BROKEN_CLK_GATING) {
>> +             set_bit(DW_MMC_CARD_NO_LOW_PWR, &slot->flags);
>> +             clk_en_a = clk_en_a_old & ~clken_low_pwr;
>> +     } else {
>> +             clear_bit(DW_MMC_CARD_NO_LOW_PWR, &slot->flags);
>> +             clk_en_a = clk_en_a_old | clken_low_pwr;
>> +     }
>>
>> -             if (clk_en_a != clk_en_a_old) {
>> -                     mci_writel(host, CLKENA, clk_en_a);
>> -                     mci_send_cmd(slot, SDMMC_CMD_UPD_CLK |
>> -                                  SDMMC_CMD_PRV_DAT_WAIT, 0);
>> -             }
>> +     if (clk_en_a != clk_en_a_old) {
>> +             mci_writel(host, CLKENA, clk_en_a);
>> +             mci_send_cmd(slot, SDMMC_CMD_UPD_CLK |
>> +                             SDMMC_CMD_PRV_DAT_WAIT, 0);
>>       }
>>  }
>>
>>
>


From k.kozlowski at samsung.com  Sun Aug 16 22:50:31 2015
From: k.kozlowski at samsung.com (Krzysztof Kozlowski)
Date: Mon, 17 Aug 2015 14:50:31 +0900
Subject: [2/2] ARM: dts: Add missing irq pinctrl for max77686 on smdk5250
In-Reply-To: <5544657A.7010006@gmail.com>
References: <1416312509-11530-2-git-send-email-yadi.brar@samsung.com>
 <553F68CC.6030504@samsung.com> <5544657A.7010006@gmail.com>
Message-ID: <CAJKOXPdzhqXFWT0=eXpr+jjs8R4kFAMq2DSSsFHVEZq_PdAN2w@mail.gmail.com>

2015-05-02 14:49 GMT+09:00 Krzysztof Kozlowski <k.kozlowski.k at gmail.com>:
> W dniu 28.04.2015 o 20:02, Pankaj Dubey pisze:
>> Hi Kukjin,
>>
>> Any updated for this patch. Without this PMIC RTC is not working on
>> SMDK5250.
>>
>
> Could you resend the patch after rebasing it?
>
> Best regards,
> Krzysztof

Dear Pankaj and Yadwinder,

Do you plan to do anything with this patch?

Best regards,
Krzysztof


>> Thanks,
>> Pankaj Dubey
>>
>> On Tuesday 18 November 2014 05:38 PM, Yadwinder Singh Brar wrote:
>>> This patch adds pinctrl configuration for using configuring gpx3-2 as an
>>> external interrupt from max77686. Though max77686 RTC is enabled and gets
>>> probed by default, it doesnt work as its unable to get interrupt.
>>>
>>> This patch makes max77686 RTC work and also configures it as wakeup
>>> source.
>>>
>>> Signed-off-by: Yadwinder Singh Brar <yadi.brar at samsung.com>
>>> Reviewed-by: Javier Martinez Canillas <javier.martinez at collabora.co.uk>
>>> Tested-by: Pankaj Dubey <pankaj.dubey at samsung.com>
>>>
>>> ---
>>> arch/arm/boot/dts/exynos5250-smdk5250.dts |   12 ++++++++++++
>>>   1 files changed, 12 insertions(+), 0 deletions(-)
>>>
>>> diff --git a/arch/arm/boot/dts/exynos5250-smdk5250.dts
>>> b/arch/arm/boot/dts/exynos5250-smdk5250.dts
>>> index 95b5b51..19cd918 100644
>>> --- a/arch/arm/boot/dts/exynos5250-smdk5250.dts
>>> +++ b/arch/arm/boot/dts/exynos5250-smdk5250.dts
>>> @@ -131,6 +131,9 @@
>>>           reg = <0x09>;
>>>           interrupt-parent = <&gpx3>;
>>>           interrupts = <2 IRQ_TYPE_NONE>;
>>> +        pinctrl-names = "default";
>>> +        pinctrl-0 = <&max77686_irq>;
>>> +        wakeup-source;
>>>
>>>           voltage-regulators {
>>>               ldo1_reg: LDO1 {
>>> @@ -411,3 +414,12 @@
>>>           };
>>>       };
>>>   };
>>> +
>>> +&pinctrl_0 {
>>> +    max77686_irq: max77686-irq {
>>> +        samsung,pins = "gpx3-2";
>>> +        samsung,pin-function = <0xf>;
>>> +        samsung,pin-pud = <0>;
>>> +        samsung,pin-drv = <0>;
>>> +    };
>>> +};
>>>
>> --
>> To unsubscribe from this list: send the line "unsubscribe
>> linux-samsung-soc" in
>> the body of a message to majordomo at vger.kernel.org
>> More majordomo info at  http://vger.kernel.org/majordomo-info.html
>


From 21cnbao at gmail.com  Sun Aug 16 22:43:55 2015
From: 21cnbao at gmail.com (Barry Song)
Date: Mon, 17 Aug 2015 13:43:55 +0800
Subject: [PATCH v7 4/5] clk: Provide critical clock support
In-Reply-To: <1437570255-21049-5-git-send-email-lee.jones@linaro.org>
References: <1437570255-21049-1-git-send-email-lee.jones@linaro.org>
 <1437570255-21049-5-git-send-email-lee.jones@linaro.org>
Message-ID: <CAGsJ_4zKn-o4ZxZ0-xzCStvuTkdC5xqD9FneWna-0dNVgp=1DQ@mail.gmail.com>

2015-07-22 21:04 GMT+08:00 Lee Jones <lee.jones at linaro.org>:
> Lots of platforms contain clocks which if turned off would prove fatal.
> The only way to recover from these catastrophic failures is to restart
> the board(s).  Now, when a clock provider is registered with the
> framework it is possible for a list of critical clocks to be supplied
> which must be kept ungated.  Each clock mentioned in the newly
> introduced 'critical-clock' property will be clk_prepare_enable()d
> where the normal references will be taken.  This will prevent the
> common clk framework from attempting to gate them during the normal
> clk_disable_unused() and disable_clock() procedures.
>
> Note that it will still be possible for knowledgeable drivers to turn
> these clocks off using clk_{enable,disable}_critical() calls.
>
> Signed-off-by: Lee Jones <lee.jones at linaro.org>

hi Lee,
i have another email about this. i am wondering whether
CLK_IGNORE_UNUSE is still useful after your patch. another solution
for your patch might be extending the current CLK_IGNORE_UNUSE to
runtime?


copy the mail here:
currently we can set a CLK_IGNORE_UNUSE flag to  a clock to stop
clk_disable_unused()  from disabling it at the boot stage:

static void clk_disable_unused_subtree(struct clk_core *core)
{
...

if (core->flags & CLK_IGNORE_UNUSED)
goto unlock_out;
}

static int clk_disable_unused(void)
{
...

clk_unprepare_unused_subtree(core);
...
 return 0;
}

late_initcall_sync(clk_disable_unused);

so if there are two clocks A and B, A is the parent of B, and A is
marked as CLK_IGNORE_UNUSED.

in boot stage if there is nobody using A and B, Linux will disable B
due to clk_disable_unused() , but keep A being enabled since A has
CLK_IGNORE_UNUSED.

but in Linux runtime, we might frequently disable /enable B in runtime
power management, this will cause A disabled since Linux will not
check CLK_IGNORE_UNUSED for runtime disabling clk .

 so this makes CLK_IGNORE_UNUSE only work if we don't disable its
sub-clock at runtime. this looks making no sense.

 i am thinking whether we should do some changes to make it have side
affect for runtime clk disable. otherwise, why do we want to stop it
from being disabled during boot stage?

 I am not sure whether i missed something in clk core level support.

-barry

> ---
>  drivers/clk/clk-conf.c | 45 ++++++++++++++++++++++++++++++++++++++++++++-
>  1 file changed, 44 insertions(+), 1 deletion(-)
>
> diff --git a/drivers/clk/clk-conf.c b/drivers/clk/clk-conf.c
> index aad4796..f83c1c2 100644
> --- a/drivers/clk/clk-conf.c
> +++ b/drivers/clk/clk-conf.c
> @@ -116,6 +116,45 @@ static int __set_clk_rates(struct device_node *node, bool clk_supplier)
>         return 0;
>  }
>
> +static int __set_critical_clocks(struct device_node *node, bool clk_supplier)
> +{
> +       struct of_phandle_args clkspec;
> +       struct clk *clk;
> +       struct property *prop;
> +       const __be32 *cur;
> +       uint32_t index;
> +       int ret;
> +
> +       if (!clk_supplier)
> +               return 0;
> +
> +       of_property_for_each_u32(node, "critical-clock", prop, cur, index) {
> +               clkspec.np = node;
> +               clkspec.args_count = 1;
> +               clkspec.args[0] = index;
> +
> +               clk = of_clk_get_from_provider(&clkspec);
> +               if (IS_ERR(clk)) {
> +                       pr_err("clk: couldn't get clock %u for %s\n",
> +                               index, node->full_name);
> +                       return PTR_ERR(clk);
> +               }
> +
> +               clk_init_critical(clk);
> +
> +               ret = clk_prepare_enable(clk);
> +               if (ret) {
> +                       pr_err("Failed to enable clock %u for %s: %d\n",
> +                              index, node->full_name, ret);
> +                       return ret;
> +               }
> +
> +               pr_debug("Setting clock as critical %pC\n", clk);
> +       }
> +
> +       return 0;
> +}
> +
>  /**
>   * of_clk_set_defaults() - parse and set assigned clocks configuration
>   * @node: device node to apply clock settings for
> @@ -139,6 +178,10 @@ int of_clk_set_defaults(struct device_node *node, bool clk_supplier)
>         if (rc < 0)
>                 return rc;
>
> -       return __set_clk_rates(node, clk_supplier);
> +       rc = __set_clk_rates(node, clk_supplier);
> +       if (rc < 0)
> +               return rc;
> +
> +       return __set_critical_clocks(node, clk_supplier);
>  }
>  EXPORT_SYMBOL_GPL(of_clk_set_defaults);
> --
> 1.9.1


From kishon at ti.com  Sun Aug 16 22:29:33 2015
From: kishon at ti.com (Kishon Vijay Abraham I)
Date: Mon, 17 Aug 2015 10:59:33 +0530
Subject: [PATCH v5 3/5] usb: phy: add usb3.0 phy driver for mt65xx SoCs
In-Reply-To: <1438950644-27290-4-git-send-email-chunfeng.yun@mediatek.com>
References: <1438950644-27290-1-git-send-email-chunfeng.yun@mediatek.com>
 <1438950644-27290-4-git-send-email-chunfeng.yun@mediatek.com>
Message-ID: <55D1713D.9070107@ti.com>

Hi,

On Friday 07 August 2015 06:00 PM, Chunfeng Yun wrote:
> support usb3.0 phy of mt65xx SoCs
> 
> Signed-off-by: Chunfeng Yun <chunfeng.yun at mediatek.com>

change $subject to phy:
> ---
>  drivers/phy/Kconfig           |   9 +
>  drivers/phy/Makefile          |   1 +
>  drivers/phy/phy-mt65xx-usb3.c | 467 ++++++++++++++++++++++++++++++++++++++++++
>  3 files changed, 477 insertions(+)
>  create mode 100644 drivers/phy/phy-mt65xx-usb3.c
> 
> diff --git a/drivers/phy/Kconfig b/drivers/phy/Kconfig
> index c0e6ede..019cf8b 100644
> --- a/drivers/phy/Kconfig
> +++ b/drivers/phy/Kconfig
> @@ -193,6 +193,15 @@ config PHY_HIX5HD2_SATA
>  	help
>  	  Support for SATA PHY on Hisilicon hix5hd2 Soc.
>  
> +config PHY_MT65XX_USB3
> +	tristate "Mediatek USB3.0 PHY Driver"
> +	depends on ARCH_MEDIATEK && OF
> +	select GENERIC_PHY
> +	help
> +	  Say 'Y' here to add support for Mediatek USB3.0 PHY driver
> +	  for mt65xx SoCs. it supports two usb2.0 ports and
> +	  one usb3.0 port.
> +
>  config PHY_SUN4I_USB
>  	tristate "Allwinner sunxi SoC USB PHY driver"
>  	depends on ARCH_SUNXI && HAS_IOMEM && OF
> diff --git a/drivers/phy/Makefile b/drivers/phy/Makefile
> index f344e1b..3ceff2a 100644
> --- a/drivers/phy/Makefile
> +++ b/drivers/phy/Makefile
> @@ -22,6 +22,7 @@ obj-$(CONFIG_TI_PIPE3)			+= phy-ti-pipe3.o
>  obj-$(CONFIG_TWL4030_USB)		+= phy-twl4030-usb.o
>  obj-$(CONFIG_PHY_EXYNOS5250_SATA)	+= phy-exynos5250-sata.o
>  obj-$(CONFIG_PHY_HIX5HD2_SATA)		+= phy-hix5hd2-sata.o
> +obj-$(CONFIG_PHY_MT65XX_USB3)		+= phy-mt65xx-usb3.o
>  obj-$(CONFIG_PHY_SUN4I_USB)		+= phy-sun4i-usb.o
>  obj-$(CONFIG_PHY_SUN9I_USB)		+= phy-sun9i-usb.o
>  obj-$(CONFIG_PHY_SAMSUNG_USB2)		+= phy-exynos-usb2.o
> diff --git a/drivers/phy/phy-mt65xx-usb3.c b/drivers/phy/phy-mt65xx-usb3.c
> new file mode 100644
> index 0000000..6835bff
> --- /dev/null
> +++ b/drivers/phy/phy-mt65xx-usb3.c
.
.
<snip>
.
.
> +static struct phy *mt65xx_phy_xlate(struct device *dev,
> +					struct of_phandle_args *args)
> +{
> +	struct mt65xx_u3phy *u3phy = dev_get_drvdata(dev);
> +	struct mt65xx_phy_instance *instance = NULL;
> +	struct device_node *phy_np = args->np;
> +	struct resource res;
> +	int index;
> +	int ret;
> +
> +	if (args->args_count != 1) {
> +		dev_err(dev, "invalid number of cells in 'phy' property\n");
> +		return ERR_PTR(-EINVAL);
> +	}
> +
> +	for (index = 0; index < u3phy->nphys; index++)
> +		if (phy_np == u3phy->phys[index]->phy->dev.of_node) {
> +			instance = u3phy->phys[index];
> +			break;
> +		}
> +
> +	if (!instance) {
> +		dev_err(dev, "failed to find appropriate phy\n");
> +		return ERR_PTR(-EINVAL);
> +	}
> +
> +	instance->type = args->args[0];
> +
> +	if (!(instance->type == PHY_TYPE_USB2 ||
> +	      instance->type == PHY_TYPE_USB3)) {
> +		dev_err(dev, "unsupported device type: %d\n", instance->type);
> +		return ERR_PTR(-EINVAL);
> +	}
> +
> +	ret = of_address_to_resource(phy_np, 0, &res);
> +	if (ret) {
> +		dev_err(dev, "failed to get address resource, err-%d (index-%d)\n",
> +			ret, instance->index);
> +		return ERR_PTR(-EINVAL);
> +	}

This should be done in probe itself.
> +
> +	instance->port_base = devm_ioremap_resource(&instance->phy->dev, &res);
> +	if (IS_ERR(instance->port_base)) {
> +		dev_err(dev, "failed to remap sif regs\n");
> +		return instance->port_base;
> +	}

This too should be done in probe.
> +
> +	return instance->phy;
> +}
> +
> +static struct phy_ops mt65xx_u3phy_ops = {
> +	.init		= mt65xx_phy_init,
> +	.power_on	= mt65xx_phy_power_on,
> +	.power_off	= mt65xx_phy_power_off,
> +	.owner		= THIS_MODULE,
> +};
> +
> +static int mt65xx_u3phy_probe(struct platform_device *pdev)
> +{
> +	struct device *dev = &pdev->dev;
> +	struct device_node *np = dev->of_node;
> +	struct device_node *child_np;
> +	struct phy_provider *phy_provider;
> +	struct resource *sif_res;
> +	struct mt65xx_u3phy *u3phy;
> +	int port;
> +
> +	u3phy = devm_kzalloc(dev, sizeof(*u3phy), GFP_KERNEL);
> +	if (!u3phy)
> +		return -ENOMEM;
> +
> +	u3phy->nphys = of_get_child_count(np);
> +	u3phy->phys = devm_kcalloc(dev, u3phy->nphys,
> +				       sizeof(*u3phy->phys), GFP_KERNEL);
> +	if (!u3phy->phys)
> +		return -ENOMEM;
> +
> +	u3phy->dev = dev;
> +	platform_set_drvdata(pdev, u3phy);
> +
> +	sif_res = platform_get_resource(pdev, IORESOURCE_MEM, 0);
> +	u3phy->sif_base = devm_ioremap_resource(dev, sif_res);
> +	if (IS_ERR(u3phy->sif_base)) {
> +		dev_err(dev, "failed to remap sif regs\n");
> +		return PTR_ERR(u3phy->sif_base);
> +	}
> +
> +	u3phy->u3phya_ref = devm_clk_get(dev, "u3phya_ref");
> +	if (IS_ERR(u3phy->u3phya_ref)) {
> +		dev_err(dev, "error to get u3phya_ref\n");
> +		return PTR_ERR(u3phy->u3phya_ref);
> +	}
> +
> +	port = 0;
> +	for_each_child_of_node(np, child_np) {
> +		struct mt65xx_phy_instance *instance;
> +		struct phy *phy;
> +
> +		instance = devm_kzalloc(dev, sizeof(*instance), GFP_KERNEL);
> +		if (!instance)
> +			return -ENOMEM;
> +
> +		u3phy->phys[port] = instance;
> +
> +		phy = devm_phy_create(dev, child_np, &mt65xx_u3phy_ops);
> +		if (IS_ERR(phy)) {
> +			dev_err(dev, "failed to create phy\n");
> +			return PTR_ERR(phy);
> +		}
> +		instance->phy = phy;
> +		instance->index = port;

'index' here is not used anywhere.
> +		phy_set_drvdata(phy, instance);
> +		port++;
> +	}
> +
> +	phy_provider = devm_of_phy_provider_register(dev, mt65xx_phy_xlate);
> +	if (IS_ERR(phy_provider)) {
> +		dev_err(dev, "Failed to register phy provider\n");
> +		return PTR_ERR(phy_provider);
> +	}
> +
> +	return u3phy_clk_enable(u3phy);

Can't we clk enable in phy_init or phy-power_on where it is actually needed.

Thanks
Kishon


From jiang.liu at linux.intel.com  Sun Aug 16 20:28:47 2015
From: jiang.liu at linux.intel.com (Jiang Liu)
Date: Mon, 17 Aug 2015 11:28:47 +0800
Subject: [PATCH v3 1/6] genirq: fix irq_chip_retrigger_hierarchy
In-Reply-To: <1439554830-19502-2-git-send-email-grygorii.strashko@ti.com>
References: <1439554830-19502-1-git-send-email-grygorii.strashko@ti.com>
 <1439554830-19502-2-git-send-email-grygorii.strashko@ti.com>
Message-ID: <55D154EF.1070500@linux.intel.com>

On 2015/8/14 20:20, Grygorii Strashko wrote:
> Now irq_chip_retrigger_hierarchy() returns -ENOSYS if it
> was not able to find at least one .irq_retrigger() callback
> implemented in IRQ domain hierarchy. As result, IRQ
> re-triggering is not working now on ARM (TI OMAP) where
> ARM GIC is not implemented this callback.
> The .irq_retrigger() is optional (see check_irq_resend())
> and there are no reasons to fail if it was not found, hence
> lets return 0 in this case.
> 
> In case of TI OMAP DRA7 the following IRQ hierarchy is defined:
> ARM GIC <- OMAP wakeupgen <- TI CBAR
> 
> Failure is reproduced during resume from suspend to RAM:
> - wakeup by IRQx
> - suspend_enter
>   + arch_suspend_enable_irqs
>     + handle_fasteoi_irq
>       + irq_may_run
>         + irq_pm_check_wakeup
>           + irq_disable(IRQx)
>   + dpm_resume_noirq()
>     + resume_device_irqs
>       + resume_irqs
>         + resume_irq
>           + __enable_irq <== IRQx is not re-triggered
> 
> Cc: Sudeep Holla <sudeep.holla at arm.com>
> Cc: Jiang Liu <jiang.liu at linux.intel.com>
> Fixes: 85f08c17de26 ('genirq: Introduce helper functions...')
> Reviewed-by: Marc Zyngier <marc.zyngier at arm.com>
> Signed-off-by: Grygorii Strashko <grygorii.strashko at ti.com>
> ---
>  kernel/irq/chip.c | 2 +-
>  1 file changed, 1 insertion(+), 1 deletion(-)
> 
> diff --git a/kernel/irq/chip.c b/kernel/irq/chip.c
> index 27f4332..6de638b 100644
> --- a/kernel/irq/chip.c
> +++ b/kernel/irq/chip.c
> @@ -997,7 +997,7 @@ int irq_chip_retrigger_hierarchy(struct irq_data *data)
>  		if (data->chip && data->chip->irq_retrigger)
>  			return data->chip->irq_retrigger(data);
>  
> -	return -ENOSYS;
> +	return 0;
>  }
>  
>  /**

Hi Grygorii,
	Thanks for fixing this regression:)
Reviewed-by: Jiang Liu <jiang.liu at linux.intel.com>



From yao.yuan at freescale.com  Sun Aug 16 20:59:41 2015
From: yao.yuan at freescale.com (Yao Yuan)
Date: Mon, 17 Aug 2015 03:59:41 +0000
Subject: [PATCH v2] dmaengine: fsl-edma: add PM suspend/resume support
In-Reply-To: <CADRPPNS_wzX+mwT0L-H=ZP9w8gH9W4O9KUqnGYiAc39S5v4qLA@mail.gmail.com>
References: <1437469005-3162-1-git-send-email-yao.yuan@freescale.com>
 <CADRPPNQJi_x+mdQV=DEVuhCL_p6VOWcPiV3jzioeRdWgSW2w3g@mail.gmail.com>
 <CY1PR0301MB15628DD5CFCE2B65BF4FECB2837C0@CY1PR0301MB1562.namprd03.prod.outlook.com>
 <CADRPPNS_wzX+mwT0L-H=ZP9w8gH9W4O9KUqnGYiAc39S5v4qLA@mail.gmail.com>
Message-ID: <CY1PR0301MB1562103588FB0C6BEFDDBF3C83790@CY1PR0301MB1562.namprd03.prod.outlook.com>

On Sat, Aug 15, 2015 at 7:48 AM, pku.leo < pku.leo at gmail.com > wrote:
> On Fri, Aug 14, 2015 at 1:24 AM, Yao Yuan <yao.yuan at freescale.com> wrote:
> > Hi Leo,
> >
> > Thanks for your review.
> > About those two methods for DMA suspend that you have mentioned. We
> have a lot of the discussions in other DMA driver like DMA for Freescale
> PowerPC.
> >
> > Finally, we think the device which used the DMA transmission service should
> cancel the transmission service in its suspend.
> > So DMA in suspend should be idle.
> 
> If that's the case you should clearly state this in the commit message and in
> code, although I don't know if it is safe to make such assumption.  There could
> be user of the DMA that doesn't track the completion of transfers.

I think it should be safe. In my opinion, even some client(the user of the DMA) forget to cancel its DMA transmission,
It will just lead to PM failed but no other system and data risk.
Although we should first fix the behavior of the client.
Once you are no need the DMA transmission, why not stop it?

Is it right?

> >
> > Once the DMA in late_suspend is not be idle, we think some driver haven't
> canceled the DMA transmission. So maybe something is error when other
> driver in suspend.
> >
> > In the case, we should return failed to stop PM. DMA should not make a
> choice for other drivers(which used DMA) to force stop DMA transmission.
> 
> The suspend entrance should be terminated by wakeup events and only critical
> issues.  I don't think we should just terminate the suspend entrance just
> because having on-going I/O without even try to stop it.

The graceful behavior would be to for client to PAUSE or terminate and then suspend
followed by DMA suspend.
We need to rely on client doing the right thing here. 
The DMA should not make a decision instead of client.
If the DMA is not idle in DMA suspend, it should be the client's issue.
We don't know what the client really want to do, so just return the non-success value.

I'm not sure my description is clear.  So we may refer the discussion about the DMA PM support before.
Such as "DMA: Freescale: add suspend resume functions for DMA driver"

Like:https://lkml.org/lkml/2014/5/21/1

> >
> > Thanks.
> >
> > Best Regards,
> > Yuan Yao
> >
> >> -----Original Message-----
> >> From: pku.leo at gmail.com [mailto:pku.leo at gmail.com] On Behalf Of Li
> >> Yang
> >> Sent: Friday, August 14, 2015 4:58 AM
> >> To: Yuan Yao-B46683
> >> Cc: Vinod Koul; stefan at agner.ch; Arnd Bergmann; Dan Williams;
> >> dmaengine at vger.kernel.org; lkml;
> >> linux-arm-kernel at lists.infradead.org; linux- pm at vger.kernel.org
> >> Subject: Re: [PATCH v2] dmaengine: fsl-edma: add PM suspend/resume
> >> support
> >>
> >> On Tue, Jul 21, 2015 at 3:56 AM, Yuan Yao <yao.yuan at freescale.com> wrote:
> >> > This add power management suspend/resume support for the fsl-edma
> >> > driver.
> >> >
> >> > eDMA acted as a basic function used by others. What it needs to do
> >> > is the two steps below to support power management.
> >> >
> >> > In fsl_edma_suspend_late:
> >> > Check whether the DMA chan is idle and if it is not idle, stop PM
> >> > operation.
> >>
> >> You should try to quiesce the device on suspend instead of depending
> >> on itself to be happen in idle and failing if it is not.
> >>
> >> Regards,
> >> Leo
> 
> 
> 
> --
> - Leo

From dianders at chromium.org  Sun Aug 16 14:10:46 2015
From: dianders at chromium.org (Doug Anderson)
Date: Sun, 16 Aug 2015 14:10:46 -0700
Subject: [RFC PATCH v5 1/9] mmc: dw_mmc: Add external dma interface support
In-Reply-To: <1522710.BT6Gc0L6oH@diego>
References: <1439541232-30100-1-git-send-email-shawn.lin@rock-chips.com>
 <1439541275-30146-1-git-send-email-shawn.lin@rock-chips.com>
 <1522710.BT6Gc0L6oH@diego>
Message-ID: <CAD=FV=W1dzqoJuJtJsD5TPKmSBpUbBcifGz654o9x8J1rX6-GQ@mail.gmail.com>

Heiko,

On Fri, Aug 14, 2015 at 3:13 PM, Heiko St?bner <heiko at sntech.de> wrote:
> Hi Shawn,
>
> Am Freitag, 14. August 2015, 16:34:35 schrieb Shawn Lin:
>> DesignWare MMC Controller can supports two types of DMA
>> mode: external dma and internal dma. We get a RK312x platform
>> integrated dw_mmc and ARM pl330 dma controller. This patch add
>> edmac ops to support these platforms. I've tested it on RK312x
>> platform with edmac mode and RK3288 platform with idmac mode.
>>
>> Signed-off-by: Shawn Lin <shawn.lin at rock-chips.com>
>
> judging by your "from", I guess you're running this on some older Rockchip soc
> without the idma? Because I tried testing this on a Radxa Rock, but only got
> failures, from the start (failed to read card status register). In PIO mode
> everything works again.
>
>
> I guess I overlooked just some tiny detail, but to me the dma channel ids seem
> correct after all. Maybe you have any hints what I'm doing wrong?

If I were a guessing man (which I'm not), I'd guess that perhaps
you're running into troubles with our friend the PL330.

There appear to be strange issues with the PL330 on Rockchip SoCs.  I
was only peripherally involved with them, but I know at least about
some of the patches in our tree, like:

https://chromium-review.googlesource.com/237607
FROMLIST: DMA: pl330: support burst mode for dev-to-mem and mem-to-dev transmit

https://chromium-review.googlesource.com/237393
CHROMIUM: dmaengine: pl330: support quirks for some broken

https://chromium-review.googlesource.com/237396
CHROMIUM: dmaengine: pl330: add quirk for broken no flushp

https://chromium-review.googlesource.com/237394
CHROMIUM: ARM: dts: rockchip: Add broken-no-flushp into rk3288.dtsi

https://chromium-review.googlesource.com/242063
CHROMIUM: ASoC: rockchip_i2s: modify DMA max burst to 1


From msalter at redhat.com  Sun Aug 16 13:49:27 2015
From: msalter at redhat.com (Mark Salter)
Date: Sun, 16 Aug 2015 16:49:27 -0400
Subject: [PATCH V3 2/3] arm64: support initrd outside kernel linear map
In-Reply-To: <1439758168-29427-1-git-send-email-msalter@redhat.com>
References: <1439758168-29427-1-git-send-email-msalter@redhat.com>
Message-ID: <1439758168-29427-3-git-send-email-msalter@redhat.com>

The use of mem= could leave part or all of the initrd outside of
the kernel linear map. This will lead to an error when unpacking
the initrd and a probable failure to boot. This patch catches that
situation and relocates the initrd to be fully within the linear
map.

Signed-off-by: Mark Salter <msalter at redhat.com>
---
 arch/arm64/kernel/setup.c | 59 +++++++++++++++++++++++++++++++++++++++++++++++
 1 file changed, 59 insertions(+)

diff --git a/arch/arm64/kernel/setup.c b/arch/arm64/kernel/setup.c
index f3067d4..5f45fd9 100644
--- a/arch/arm64/kernel/setup.c
+++ b/arch/arm64/kernel/setup.c
@@ -359,6 +359,64 @@ static void __init request_standard_resources(void)
 	}
 }
 
+#ifdef CONFIG_BLK_DEV_INITRD
+/*
+ * Relocate initrd if it is not completely within the linear mapping.
+ * This would be the case if mem= cuts out all or part of it.
+ */
+static void __init relocate_initrd(void)
+{
+	phys_addr_t orig_start = __virt_to_phys(initrd_start);
+	phys_addr_t orig_end = __virt_to_phys(initrd_end);
+	phys_addr_t ram_end = memblock_end_of_DRAM();
+	phys_addr_t new_start;
+	unsigned long size, to_free = 0;
+	void *dest;
+
+	if (orig_end <= ram_end)
+		return;
+
+	/* Note if any of original initrd will freeing below */
+	if (orig_start < ram_end)
+		to_free = ram_end - orig_start;
+
+	size = orig_end - orig_start;
+
+	/* initrd needs to be relocated completely inside linear mapping */
+	new_start = memblock_find_in_range(0, PFN_PHYS(max_pfn),
+					   size, PAGE_SIZE);
+	if (!new_start)
+		panic("Cannot relocate initrd of size %ld\n", size);
+	memblock_reserve(new_start, size);
+
+	initrd_start = __phys_to_virt(new_start);
+	initrd_end   = initrd_start + size;
+
+	pr_info("Moving initrd from [%llx-%llx] to [%llx-%llx]\n",
+		orig_start, orig_start + size - 1,
+		new_start, new_start + size - 1);
+
+	dest = (void *)initrd_start;
+
+	if (to_free) {
+		memcpy(dest, (void *)__phys_to_virt(orig_start), to_free);
+		dest += to_free;
+	}
+
+	copy_from_early_mem(dest, orig_start + to_free, size - to_free);
+
+	if (to_free) {
+		pr_info("Freeing original RAMDISK from [%llx-%llx]\n",
+			orig_start, orig_start + to_free - 1);
+		memblock_free(orig_start, to_free);
+	}
+}
+#else
+static inline void __init reserve_initrd(void)
+{
+}
+#endif
+
 u64 __cpu_logical_map[NR_CPUS] = { [0 ... NR_CPUS-1] = INVALID_HWID };
 
 void __init setup_arch(char **cmdline_p)
@@ -392,6 +450,7 @@ void __init setup_arch(char **cmdline_p)
 	acpi_boot_table_init();
 
 	paging_init();
+	relocate_initrd();
 	request_standard_resources();
 
 	early_ioremap_reset();
-- 
2.4.3



From msalter at redhat.com  Sun Aug 16 13:49:25 2015
From: msalter at redhat.com (Mark Salter)
Date: Sun, 16 Aug 2015 16:49:25 -0400
Subject: [PATCH V3 0/3] mm: Add generic copy from early unmapped RAM
Message-ID: <1439758168-29427-1-git-send-email-msalter@redhat.com>

When booting an arm64 kernel w/initrd using UEFI/grub, use of mem= will likely
cut off part or all of the initrd. This leaves it outside the kernel linear
map which leads to failure when unpacking. The x86 code has a similar need to
relocate an initrd outside of mapped memory in some cases.

The current x86 code uses early_memremap() to copy the original initrd from
unmapped to mapped RAM. This patchset creates a generic copy_from_early_mem()
utility based on that x86 code and has arm64 and x86 share it in their
respective initrd relocation code.

Changes from V2:

  * Fixed sparse warning in copy_from_early_mem()

  * Removed unneeded MAX_MAP_CHUNK from x86 setup.c

  * Moved #ifdef outside arm64 relocate_initrd() definition.
  
Changes from V1:

  * Change cover letter subject to highlight the added generic code

  * Add patch for x86 to use common copy_from_early_mem()


Mark Salter (3):
  mm: add utility for early copy from unmapped ram
  arm64: support initrd outside kernel linear map
  x86: use generic early mem copy

 arch/arm64/kernel/setup.c           | 59 +++++++++++++++++++++++++++++++++++++
 arch/x86/kernel/setup.c             | 22 +-------------
 include/asm-generic/early_ioremap.h |  6 ++++
 mm/early_ioremap.c                  | 22 ++++++++++++++
 4 files changed, 88 insertions(+), 21 deletions(-)

-- 
2.4.3



From msalter at redhat.com  Sun Aug 16 13:49:28 2015
From: msalter at redhat.com (Mark Salter)
Date: Sun, 16 Aug 2015 16:49:28 -0400
Subject: [PATCH V3 3/3] x86: use generic early mem copy
In-Reply-To: <1439758168-29427-1-git-send-email-msalter@redhat.com>
References: <1439758168-29427-1-git-send-email-msalter@redhat.com>
Message-ID: <1439758168-29427-4-git-send-email-msalter@redhat.com>

The early_ioremap library now has a generic copy_from_early_mem()
function. Use the generic copy function for x86 relocate_initrd().

Signed-off-by: Mark Salter <msalter at redhat.com>
---
 arch/x86/kernel/setup.c | 22 +---------------------
 1 file changed, 1 insertion(+), 21 deletions(-)

diff --git a/arch/x86/kernel/setup.c b/arch/x86/kernel/setup.c
index 80f874b..21fa9a3 100644
--- a/arch/x86/kernel/setup.c
+++ b/arch/x86/kernel/setup.c
@@ -317,15 +317,12 @@ static u64 __init get_ramdisk_size(void)
 	return ramdisk_size;
 }
 
-#define MAX_MAP_CHUNK	(NR_FIX_BTMAPS << PAGE_SHIFT)
 static void __init relocate_initrd(void)
 {
 	/* Assume only end is not page aligned */
 	u64 ramdisk_image = get_ramdisk_image();
 	u64 ramdisk_size  = get_ramdisk_size();
 	u64 area_size     = PAGE_ALIGN(ramdisk_size);
-	unsigned long slop, clen, mapaddr;
-	char *p, *q;
 
 	/* We need to move the initrd down into directly mapped mem */
 	relocated_ramdisk = memblock_find_in_range(0, PFN_PHYS(max_pfn_mapped),
@@ -343,25 +340,8 @@ static void __init relocate_initrd(void)
 	printk(KERN_INFO "Allocated new RAMDISK: [mem %#010llx-%#010llx]\n",
 	       relocated_ramdisk, relocated_ramdisk + ramdisk_size - 1);
 
-	q = (char *)initrd_start;
-
-	/* Copy the initrd */
-	while (ramdisk_size) {
-		slop = ramdisk_image & ~PAGE_MASK;
-		clen = ramdisk_size;
-		if (clen > MAX_MAP_CHUNK-slop)
-			clen = MAX_MAP_CHUNK-slop;
-		mapaddr = ramdisk_image & PAGE_MASK;
-		p = early_memremap(mapaddr, clen+slop);
-		memcpy(q, p+slop, clen);
-		early_memunmap(p, clen+slop);
-		q += clen;
-		ramdisk_image += clen;
-		ramdisk_size  -= clen;
-	}
+	copy_from_early_mem((void *)initrd_start, ramdisk_image, ramdisk_size);
 
-	ramdisk_image = get_ramdisk_image();
-	ramdisk_size  = get_ramdisk_size();
 	printk(KERN_INFO "Move RAMDISK from [mem %#010llx-%#010llx] to"
 		" [mem %#010llx-%#010llx]\n",
 		ramdisk_image, ramdisk_image + ramdisk_size - 1,
-- 
2.4.3



From sfr at canb.auug.org.au  Sun Aug 16 18:08:55 2015
From: sfr at canb.auug.org.au (Stephen Rothwell)
Date: Mon, 17 Aug 2015 11:08:55 +1000
Subject: linux-next: manual merge of the pci tree with the arm-soc tree
Message-ID: <20150817110855.4fcf9a66@canb.auug.org.au>

Hi Bjorn,

Today's linux-next merge of the pci tree got a conflict in:

  drivers/pci/host/Kconfig

between commit:

  70d334ca71b0 ("PCI: iproc: Fix BCMA dependency in Kconfig")

from the arm-soc tree and commit:

  05aa7d6a72c1 ("PCI: iproc: Allow BCMA bus driver to be built as module")

from the pci tree.

I fixed it up (see below) and can carry the fix as necessary (no action
is required).

-- 
Cheers,
Stephen Rothwell                    sfr at canb.auug.org.au

diff --cc drivers/pci/host/Kconfig
index 48b5b3058d9d,e339a8c42f76..000000000000
--- a/drivers/pci/host/Kconfig
+++ b/drivers/pci/host/Kconfig
@@@ -135,8 -135,8 +135,8 @@@ config PCIE_IPROC_PLATFOR
  	  through the generic platform bus interface
  
  config PCIE_IPROC_BCMA
- 	bool "Broadcom iProc PCIe BCMA bus driver"
+ 	tristate "Broadcom iProc PCIe BCMA bus driver"
 -	depends on ARCH_BCM_IPROC || (ARM && COMPILE_TEST)
 +	depends on ARM && (ARCH_BCM_IPROC || COMPILE_TEST)
  	select PCIE_IPROC
  	select BCMA
  	select PCI_DOMAINS


From manabian at gmail.com  Sun Aug 16 11:10:15 2015
From: manabian at gmail.com (Joachim Eastwood)
Date: Sun, 16 Aug 2015 20:10:15 +0200
Subject: [PATCH v2 0/2] I2C support for NXP LPC18xx family
Message-ID: <1439748617-7683-1-git-send-email-manabian@gmail.com>

This patch set adds a I2C driver and documentation for the I2C
peripheral found on many NXP LPC MCUs.

The driver is a rework of an old driver by Kevin Wells. It has been
modified to support modern resource allocation, device tree and
generally cleaned up. Driver was originally written to support the
LPC2xxx platforms.

Patches based on i2c/for-next and tested on Embedded Artists' LPC4357
Dev Kit and Hitex LPC4350 Eval board with several I2C devices.

This version address comments from Wolfram Sang.

Changes since v1:
 - remove dev_dbg() leftovers from development/debugging
 - use i2c_add_adapter
 - change return value on NACK and arb lost
   (I think all the others should be okay as they are)
 - fix 80 char warnings (involved s/reg_base/base)
 - rebase on i2c/for-next

Joachim Eastwood (2):
  i2c: add i2c-lpc2k driver
  doc: dt: add documentation for nxp,lpc1788-i2c

 .../devicetree/bindings/i2c/i2c-lpc2k.txt          |  33 ++
 drivers/i2c/busses/Kconfig                         |  10 +
 drivers/i2c/busses/Makefile                        |   1 +
 drivers/i2c/busses/i2c-lpc2k.c                     | 513 +++++++++++++++++++++
 4 files changed, 557 insertions(+)
 create mode 100644 Documentation/devicetree/bindings/i2c/i2c-lpc2k.txt
 create mode 100644 drivers/i2c/busses/i2c-lpc2k.c

-- 
1.8.0



From manabian at gmail.com  Sun Aug 16 11:10:17 2015
From: manabian at gmail.com (Joachim Eastwood)
Date: Sun, 16 Aug 2015 20:10:17 +0200
Subject: [PATCH v2 2/2] doc: dt: add documentation for nxp,lpc1788-i2c
In-Reply-To: <1439748617-7683-1-git-send-email-manabian@gmail.com>
References: <1439748617-7683-1-git-send-email-manabian@gmail.com>
Message-ID: <1439748617-7683-3-git-send-email-manabian@gmail.com>

Add binding documentation for the nxp,lpc1788-i2c controller
which also can be found on LPC2xxx, LPC178x/7x and LPC18xx/43xx
devices.

Signed-off-by: Joachim Eastwood <manabian at gmail.com>
---
 .../devicetree/bindings/i2c/i2c-lpc2k.txt          | 33 ++++++++++++++++++++++
 1 file changed, 33 insertions(+)
 create mode 100644 Documentation/devicetree/bindings/i2c/i2c-lpc2k.txt

diff --git a/Documentation/devicetree/bindings/i2c/i2c-lpc2k.txt b/Documentation/devicetree/bindings/i2c/i2c-lpc2k.txt
new file mode 100644
index 000000000000..4101aa621ad4
--- /dev/null
+++ b/Documentation/devicetree/bindings/i2c/i2c-lpc2k.txt
@@ -0,0 +1,33 @@
+NXP I2C controller for LPC2xxx/178x/18xx/43xx
+
+Required properties:
+ - compatible: must be "nxp,lpc1788-i2c"
+ - reg: physical address and length of the device registers
+ - interrupts: a single interrupt specifier
+ - clocks: clock for the device
+ - #address-cells: should be <1>
+ - #size-cells: should be <0>
+
+Optional properties:
+- clock-frequency: the desired I2C bus clock frequency in Hz; in
+  absence of this property the default value is used (100 kHz).
+
+Example:
+i2c0: i2c at 400a1000 {
+	compatible = "nxp,lpc1788-i2c";
+	reg = <0x400a1000 0x1000>;
+	interrupts = <18>;
+	clocks = <&ccu1 CLK_APB1_I2C0>;
+	#address-cells = <1>;
+	#size-cells = <0>;
+};
+
+&i2c0 {
+	clock-frequency = <400000>;
+
+	lm75 at 48 {
+		compatible = "nxp,lm75";
+		reg = <0x48>;
+	};
+};
+
-- 
1.8.0



From k.kozlowski at samsung.com  Sun Aug 16 17:37:29 2015
From: k.kozlowski at samsung.com (Krzysztof Kozlowski)
Date: Mon, 17 Aug 2015 09:37:29 +0900
Subject: [PATCH 0/4] ARM: dts: exynos3250: Add UART2 and MMC2 dt node with
 related clocks
In-Reply-To: <55D12C73.6090101@samsung.com>
References: <1439264784-30322-1-git-send-email-cw00.choi@samsung.com>
 <CAJKOXPfvGypFymHzXDMEA295Copi0sjpMG9oKmJ+a_BQoK+SNw@mail.gmail.com>
 <55D12C73.6090101@samsung.com>
Message-ID: <55D12CC9.2060602@samsung.com>

On 17.08.2015 09:36, Chanwoo Choi wrote:
> On 08/17/2015 09:33 AM, Krzysztof Kozlowski wrote:
>> 2015-08-11 12:46 GMT+09:00 Chanwoo Choi <cw00.choi at samsung.com>:
>>> This patch add the UART2 / MMC2 devicetree node for Exynos3250 SoC and add
>>> the related clocks (mux, divider, gate) of UART2 / MMC2 device.
>>
>> What is the benefit of adding them? Why they are needed?
> 
> UART2 /MMC2 are used on Exynos3250-based ARTIK-5 board[1].
> [1] https://www.artik.io/hardware/artik-5

Thanks for explaining this. The patchset missed that information - the
purpose. I'll start reviewing it.

Best regards,
Krzysztof

> 
> Thanks,
> Chanwoo Choi
> 
>>
>> Best regards,
>> Krzysztof
>>
>>
>>>
>>> Chanwoo Choi (4):
>>>   clk: samsung: exynos3250: Add UART2 clock
>>>   clk: samsung: exynos3250: Add MMC2 clock
>>>   ARM: dts: Add UART2 dt node for Exynos3250 SoC
>>>   ARM: dts: Add MSHC2 dt node for Exynos3250 SoC
>>>
>>>  arch/arm/boot/dts/exynos3250-pinctrl.dtsi | 42 +++++++++++++++++++++++++++++++
>>>  arch/arm/boot/dts/exynos3250.dtsi         | 25 ++++++++++++++++++
>>>  drivers/clk/samsung/clk-exynos3250.c      | 15 +++++++++++
>>>  include/dt-bindings/clock/exynos3250.h    | 11 +++++++-
>>>  4 files changed, 92 insertions(+), 1 deletion(-)
>>>
>>> --
>>> 1.8.5.5
>>>
>>>
>>> _______________________________________________
>>> linux-arm-kernel mailing list
>>> linux-arm-kernel at lists.infradead.org
>>> http://lists.infradead.org/mailman/listinfo/linux-arm-kernel
>> --
>> To unsubscribe from this list: send the line "unsubscribe linux-samsung-soc" in
>> the body of a message to majordomo at vger.kernel.org
>> More majordomo info at  http://vger.kernel.org/majordomo-info.html
>>
> 
> 



From cw00.choi at samsung.com  Sun Aug 16 17:36:03 2015
From: cw00.choi at samsung.com (Chanwoo Choi)
Date: Mon, 17 Aug 2015 09:36:03 +0900
Subject: [PATCH 0/4] ARM: dts: exynos3250: Add UART2 and MMC2 dt node with
 related clocks
In-Reply-To: <CAJKOXPfvGypFymHzXDMEA295Copi0sjpMG9oKmJ+a_BQoK+SNw@mail.gmail.com>
References: <1439264784-30322-1-git-send-email-cw00.choi@samsung.com>
 <CAJKOXPfvGypFymHzXDMEA295Copi0sjpMG9oKmJ+a_BQoK+SNw@mail.gmail.com>
Message-ID: <55D12C73.6090101@samsung.com>

On 08/17/2015 09:33 AM, Krzysztof Kozlowski wrote:
> 2015-08-11 12:46 GMT+09:00 Chanwoo Choi <cw00.choi at samsung.com>:
>> This patch add the UART2 / MMC2 devicetree node for Exynos3250 SoC and add
>> the related clocks (mux, divider, gate) of UART2 / MMC2 device.
> 
> What is the benefit of adding them? Why they are needed?

UART2 /MMC2 are used on Exynos3250-based ARTIK-5 board[1].
[1] https://www.artik.io/hardware/artik-5

Thanks,
Chanwoo Choi

> 
> Best regards,
> Krzysztof
> 
> 
>>
>> Chanwoo Choi (4):
>>   clk: samsung: exynos3250: Add UART2 clock
>>   clk: samsung: exynos3250: Add MMC2 clock
>>   ARM: dts: Add UART2 dt node for Exynos3250 SoC
>>   ARM: dts: Add MSHC2 dt node for Exynos3250 SoC
>>
>>  arch/arm/boot/dts/exynos3250-pinctrl.dtsi | 42 +++++++++++++++++++++++++++++++
>>  arch/arm/boot/dts/exynos3250.dtsi         | 25 ++++++++++++++++++
>>  drivers/clk/samsung/clk-exynos3250.c      | 15 +++++++++++
>>  include/dt-bindings/clock/exynos3250.h    | 11 +++++++-
>>  4 files changed, 92 insertions(+), 1 deletion(-)
>>
>> --
>> 1.8.5.5
>>
>>
>> _______________________________________________
>> linux-arm-kernel mailing list
>> linux-arm-kernel at lists.infradead.org
>> http://lists.infradead.org/mailman/listinfo/linux-arm-kernel
> --
> To unsubscribe from this list: send the line "unsubscribe linux-samsung-soc" in
> the body of a message to majordomo at vger.kernel.org
> More majordomo info at  http://vger.kernel.org/majordomo-info.html
> 



From shijie.huang at arm.com  Sun Aug 16 20:24:43 2015
From: shijie.huang at arm.com (Huang Shijie)
Date: Mon, 17 Aug 2015 11:24:43 +0800
Subject: [PATCH] arm64: dts: Juno: fix the wrong memory map sizes for the
 I2C/EHCI/OHCI
Message-ID: <1439781883-2335-1-git-send-email-shijie.huang@arm.com>

>From the "Juno ARM Development Platform Soc Techinical Reference Mannual(r1p0)",
we get the following memory map sizes (3-25):
	I2C      : 0x7ffa0000  0x7ffa00ff       (256B)
	USB OHCI : 0x7ffb0000  0x7ffb0fff       (4KB)
	USB EHCI : 0x7ffc0000  0x7ffc0fff       (4KB)

This patch fixes the wrong memory map sizes for them.

Signed-off-by: Huang Shijie <shijie.huang at arm.com>
---
There is something wrong with my email account, so try to send it out again.
---
 arch/arm64/boot/dts/arm/juno-base.dtsi | 6 +++---
 1 file changed, 3 insertions(+), 3 deletions(-)

diff --git a/arch/arm64/boot/dts/arm/juno-base.dtsi b/arch/arm64/boot/dts/arm/juno-base.dtsi
index e3ee960..7b2715f 100644
--- a/arch/arm64/boot/dts/arm/juno-base.dtsi
+++ b/arch/arm64/boot/dts/arm/juno-base.dtsi
@@ -74,7 +74,7 @@
 
 	i2c at 7ffa0000 {
 		compatible = "snps,designware-i2c";
-		reg = <0x0 0x7ffa0000 0x0 0x1000>;
+		reg = <0x0 0x7ffa0000 0x0 0x100>;
 		#address-cells = <1>;
 		#size-cells = <0>;
 		interrupts = <GIC_SPI 104 IRQ_TYPE_LEVEL_HIGH>;
@@ -95,14 +95,14 @@
 
 	ohci at 7ffb0000 {
 		compatible = "generic-ohci";
-		reg = <0x0 0x7ffb0000 0x0 0x10000>;
+		reg = <0x0 0x7ffb0000 0x0 0x1000>;
 		interrupts = <GIC_SPI 116 IRQ_TYPE_LEVEL_HIGH>;
 		clocks = <&soc_usb48mhz>;
 	};
 
 	ehci at 7ffc0000 {
 		compatible = "generic-ehci";
-		reg = <0x0 0x7ffc0000 0x0 0x10000>;
+		reg = <0x0 0x7ffc0000 0x0 0x1000>;
 		interrupts = <GIC_SPI 117 IRQ_TYPE_LEVEL_HIGH>;
 		clocks = <&soc_usb48mhz>;
 	};
-- 
2.1.4



From k.kozlowski at samsung.com  Sun Aug 16 18:48:05 2015
From: k.kozlowski at samsung.com (Krzysztof Kozlowski)
Date: Mon, 17 Aug 2015 10:48:05 +0900
Subject: [PATCH 2/4] clk: samsung: exynos3250: Add MMC2 clock
In-Reply-To: <1439264784-30322-3-git-send-email-cw00.choi@samsung.com>
References: <1439264784-30322-1-git-send-email-cw00.choi@samsung.com>
 <1439264784-30322-3-git-send-email-cw00.choi@samsung.com>
Message-ID: <55D13D55.5030207@samsung.com>

On 11.08.2015 12:46, Chanwoo Choi wrote:
> This patch add the MMC2 clocks (mux, divider, gate) of Exynos3250 SoC.
> 
> Cc: Sylwester Nawrocki <s.nawrocki at samsung.com>
> Cc: Tomasz Figa <tomasz.figa at gmail.com>
> Signed-off-by: Chanwoo Choi <cw00.choi at samsung.com>
> ---
>  drivers/clk/samsung/clk-exynos3250.c   | 9 +++++++++
>  include/dt-bindings/clock/exynos3250.h | 7 ++++++-
>  2 files changed, 15 insertions(+), 1 deletion(-)



Assuming that numbers/addresses are good (reserved in my datasheet) the
code itself looks good:
Reviewed-by: Krzysztof Kozlowski <k.kozlowski at samsung.com>


Best regards,
Krzysztof




From broonie at kernel.org  Sun Aug 16 20:30:47 2015
From: broonie at kernel.org (Mark Brown)
Date: Sun, 16 Aug 2015 20:30:47 -0700
Subject: [PATCH] spi: Mediatek: fix endian warnings
In-Reply-To: <20150816140639.GE7557@n2100.arm.linux.org.uk>
References: <1439289789-29026-1-git-send-email-leilk.liu@mediatek.com>
 <1871097.B3YgX5rNy0@wuerfel>
 <20150816140639.GE7557@n2100.arm.linux.org.uk>
Message-ID: <20150817033047.GM10748@sirena.org.uk>

On Sun, Aug 16, 2015 at 03:06:39PM +0100, Russell King - ARM Linux wrote:

> All writel() implementations take a CPU number and write it in little
> endian format.  Hence, writel() almost always uses cpu_to_le32()
> internally.

I think the reason this keeps coming up is that people aren't expecting
writel() to be doing endianness conversion, it's easy to get caught out
by it.
-------------- next part --------------
A non-text attachment was scrubbed...
Name: signature.asc
Type: application/pgp-signature
Size: 473 bytes
Desc: Digital signature
URL: <http://lists.infradead.org/pipermail/linux-arm-kernel/attachments/20150816/42f0fde6/attachment.sig>

From pankaj.dubey at samsung.com  Sun Aug 16 20:33:48 2015
From: pankaj.dubey at samsung.com (Pankaj Dubey)
Date: Mon, 17 Aug 2015 09:03:48 +0530
Subject: [3/4] ARM: dts: Add UART2 dt node for Exynos3250 SoC
In-Reply-To: <1439264784-30322-4-git-send-email-cw00.choi@samsung.com>
References: <1439264784-30322-4-git-send-email-cw00.choi@samsung.com>
Message-ID: <55D1561C.90805@samsung.com>

Hi Chanwoo,

Similar patch was posted here[1].

[1]: 
http://lists.infradead.org/pipermail/linux-arm-kernel/2014-September/291023.html

Thanks,
Pankaj Dubey

On Tuesday 11 August 2015 09:16 AM, Chanwoo Choi wrote:
> This patch add the uart2 devicetree node for Exynos3250 SoC.
>
> Cc: Kukjin Kim <kgene at kernel.org>
> Cc: Krzysztof Kozlowski <k.kozlowski at samsung.com>
> Signed-off-by: Chanwoo Choi <cw00.choi at samsung.com>
> Reviewed-by: Krzysztof Kozlowski <k.kozlowski at samsung.com>
>
> ---
> arch/arm/boot/dts/exynos3250-pinctrl.dtsi |  7 +++++++
>   arch/arm/boot/dts/exynos3250.dtsi         | 12 ++++++++++++
>   2 files changed, 19 insertions(+)
>
> diff --git a/arch/arm/boot/dts/exynos3250-pinctrl.dtsi b/arch/arm/boot/dts/exynos3250-pinctrl.dtsi
> index 5ab81c39e2c9..eac1d21c10d4 100644
> --- a/arch/arm/boot/dts/exynos3250-pinctrl.dtsi
> +++ b/arch/arm/boot/dts/exynos3250-pinctrl.dtsi
> @@ -120,6 +120,13 @@
>   		samsung,pin-drv = <0>;
>   	};
>
> +	uart2_data: uart2-data {
> +		samsung,pins = "gpa1-0", "gpa1-1";
> +		samsung,pin-function = <2>;
> +		samsung,pin-pud = <0>;
> +		samsung,pin-drv = <0>;
> +	};
> +
>   	i2c3_bus: i2c3-bus {
>   		samsung,pins = "gpa1-2", "gpa1-3";
>   		samsung,pin-function = <3>;
> diff --git a/arch/arm/boot/dts/exynos3250.dtsi b/arch/arm/boot/dts/exynos3250.dtsi
> index 2db99433e17f..02f3250766c9 100644
> --- a/arch/arm/boot/dts/exynos3250.dtsi
> +++ b/arch/arm/boot/dts/exynos3250.dtsi
> @@ -42,6 +42,7 @@
>   		i2c7 = &i2c_7;
>   		serial0 = &serial_0;
>   		serial1 = &serial_1;
> +		serial2 = &serial_2;
>   	};
>
>   	cpus {
> @@ -435,6 +436,17 @@
>   			status = "disabled";
>   		};
>
> +		serial_2: serial at 13820000 {
> +			compatible = "samsung,exynos4210-uart";
> +			reg = <0x13820000 0x100>;
> +			interrupts = <0 111 0>;
> +			clocks = <&cmu CLK_UART2>, <&cmu CLK_SCLK_UART2>;
> +			clock-names = "uart", "clk_uart_baud0";
> +			pinctrl-names = "default";
> +			pinctrl-0 = <&uart2_data>;
> +			status = "disabled";
> +		};
> +
>   		i2c_0: i2c at 13860000 {
>   			#address-cells = <1>;
>   			#size-cells = <0>;
>


From djkurtz at chromium.org  Sun Aug 16 21:32:29 2015
From: djkurtz at chromium.org (Daniel Kurtz)
Date: Mon, 17 Aug 2015 12:32:29 +0800
Subject: [PATCH v6] arm64: dts: Add spi bus dts
In-Reply-To: <1439782198-32396-1-git-send-email-leilk.liu@mediatek.com>
References: <1439782198-32396-1-git-send-email-leilk.liu@mediatek.com>
Message-ID: <CAGS+omCFQRoH3ft2O5qPLBgngCuLPaminTys5OU6QcKmRXTyNw@mail.gmail.com>

On Mon, Aug 17, 2015 at 11:29 AM, Leilk Liu <leilk.liu at mediatek.com> wrote:
>
> This patch adds MT8173 spi bus controllers into device tree.
>
> Signed-off-by: Leilk Liu <leilk.liu at mediatek.com>

Reviewed-by: Daniel Kurtz <djkurtz at chromium.org>

> ---
> Change in this patch:
> pinctl and pad-select fields are board specific, so move to
> mt8173-evb.dtsi, and status = "okay".
> ---
>  arch/arm64/boot/dts/mediatek/mt8173-evb.dts | 18 ++++++++++++++++++
>  arch/arm64/boot/dts/mediatek/mt8173.dtsi    | 12 ++++++++++++
>  2 files changed, 30 insertions(+)
>
> diff --git a/arch/arm64/boot/dts/mediatek/mt8173-evb.dts b/arch/arm64/boot/dts/mediatek/mt8173-evb.dts
> index 4be66ca..811cb76 100644
> --- a/arch/arm64/boot/dts/mediatek/mt8173-evb.dts
> +++ b/arch/arm64/boot/dts/mediatek/mt8173-evb.dts
> @@ -387,6 +387,24 @@
>         };
>  };
>
> +&pio {
> +       spi_pins_a: spi0 {
> +               pins_spi {
> +                       pinmux = <MT8173_PIN_69_SPI_CK__FUNC_SPI_CK_0_>,
> +                               <MT8173_PIN_70_SPI_MI__FUNC_SPI_MI_0_>,
> +                               <MT8173_PIN_71_SPI_MO__FUNC_SPI_MO_0_>,
> +                               <MT8173_PIN_72_SPI_CS__FUNC_SPI_CS_0_>;
> +               };
> +       };
> +};
> +
> +&spi {
> +       pinctrl-names = "default";
> +       pinctrl-0 = <&spi_pins_a>;
> +       mediatek,pad-select = <0>;
> +       status = "okay";
> +};
> +
>  &uart0 {
>         status = "okay";
>  };
> diff --git a/arch/arm64/boot/dts/mediatek/mt8173.dtsi b/arch/arm64/boot/dts/mediatek/mt8173.dtsi
> index d18ee42..3dfb6ed 100644
> --- a/arch/arm64/boot/dts/mediatek/mt8173.dtsi
> +++ b/arch/arm64/boot/dts/mediatek/mt8173.dtsi
> @@ -365,6 +365,18 @@
>                         status = "disabled";
>                 };
>
> +               spi: spi at 1100a000 {
> +                       compatible = "mediatek,mt8173-spi";
> +                       #address-cells = <1>;
> +                       #size-cells = <0>;
> +                       reg = <0 0x1100a000 0 0x1000>;
> +                       interrupts = <GIC_SPI 110 IRQ_TYPE_LEVEL_LOW>;
> +                       clocks = <&topckgen CLK_TOP_SPI_SEL>,
> +                                <&topckgen CLK_TOP_SYSPLL3_D2>;
> +                       clock-names = "spi-clk", "parent-clk";
> +                       status = "disabled";
> +               };
> +
>                 i2c3: i2c3 at 11010000 {
>                         compatible = "mediatek,mt8173-i2c";
>                         reg = <0 0x11010000 0 0x70>,
> --
> 1.8.1.1.dirty
>
> --
> To unsubscribe from this list: send the line "unsubscribe linux-kernel" in
> the body of a message to majordomo at vger.kernel.org
> More majordomo info at  http://vger.kernel.org/majordomo-info.html
> Please read the FAQ at  http://www.tux.org/lkml/


From boris.brezillon at free-electrons.com  Mon Aug 17 00:18:27 2015
From: boris.brezillon at free-electrons.com (Boris Brezillon)
Date: Mon, 17 Aug 2015 09:18:27 +0200
Subject: [PATCH v2 00/10] pwm: add support for atomic update
In-Reply-To: <20150725083657.6111ff59@bbrezillon>
References: <1437406327-6207-1-git-send-email-boris.brezillon@free-electrons.com>
 <20150725083657.6111ff59@bbrezillon>
Message-ID: <20150817091827.70eae7eb@bbrezillon>

On Sat, 25 Jul 2015 08:36:57 +0200
Boris Brezillon <boris.brezillon at free-electrons.com> wrote:

> Hi Thierry,
> 
> Should I resend a new version rebased on Mark's pwm topic branch or
> would you like to review this one first ?

Ping.

> 
> Best Regards,
> 
> Boris
> 
> On Mon, 20 Jul 2015 17:31:57 +0200
> Boris Brezillon <boris.brezillon at free-electrons.com> wrote:
> 
> > Hello Thierry,
> > 
> > This series adds support for atomic PWM update, or IOW, the capability
> > to update all the parameters of a PWM device (enabled/disabled, period,
> > duty and polarity) in one go.
> > 
> > Best Regards,
> > 
> > Boris
> > 
> > Changes since v1:
> > - dropped applied patches
> > - squashed Heiko's fixes into the rockchip driver changes
> > - made a few cosmetic changes
> > - added kerneldoc comments
> > - added Heiko's patch to display more information in debugfs
> > - dropped pwm-regulator patches (should be submitted separately)
> > 
> > Boris Brezillon (9):
> >   pwm: introduce default period and polarity concepts
> >   pwm: define a new pwm_state struct
> >   pwm: move the enabled/disabled info to pwm_state struct
> >   backlight: pwm_bl: remove useless call to pwm_set_period
> >   pwm: declare a default PWM state
> >   pwm: add the PWM initial state retrieval infra
> >   pwm: add the core infrastructure to allow atomic update
> >   pwm: rockchip: add initial state retrieval
> >   pwm: rockchip: add support for atomic update
> > 
> > Heiko St?bner (1):
> >   pwm: add information about polarity, duty cycle and period to debugfs
> > 
> >  drivers/leds/leds-pwm.c              |   2 +-
> >  drivers/pwm/core.c                   | 169 +++++++++++++++++++++++++++++++----
> >  drivers/pwm/pwm-pxa.c                |   2 +-
> >  drivers/pwm/pwm-rockchip.c           | 119 +++++++++++++++++++-----
> >  drivers/pwm/pwm-sun4i.c              |   3 +-
> >  drivers/regulator/pwm-regulator.c    |   2 +-
> >  drivers/video/backlight/lm3630a_bl.c |   4 +-
> >  drivers/video/backlight/pwm_bl.c     |  10 ++-
> >  drivers/video/fbdev/ssd1307fb.c      |   2 +-
> >  include/linux/pwm.h                  |  86 +++++++++++++++---
> >  10 files changed, 336 insertions(+), 63 deletions(-)
> > 
> 
> 
> 



-- 
Boris Brezillon, Free Electrons
Embedded Linux and Kernel engineering
http://free-electrons.com


From mpa at pengutronix.de  Mon Aug 17 00:19:32 2015
From: mpa at pengutronix.de (Markus Pargmann)
Date: Mon, 17 Aug 2015 09:19:32 +0200
Subject: [PATCH 01/20] regmap: Add missing comments about struct regmap_bus
In-Reply-To: <55CBA8A6.7020404@gmx.de>
References: <1439374365-20623-1-git-send-email-mpa@pengutronix.de>
 <1439374365-20623-2-git-send-email-mpa@pengutronix.de>
 <55CBA8A6.7020404@gmx.de>
Message-ID: <20150817071932.GH19600@pengutronix.de>

On Wed, Aug 12, 2015 at 10:12:22PM +0200, Hartmut Knaack wrote:
> Markus Pargmann schrieb am 12.08.2015 um 12:12:
> > There are some fields of this struct undocumented or old. This patch
> > updates the missing comments.
> > 
> > Signed-off-by: Markus Pargmann <mpa at pengutronix.de>
> > ---
> >  include/linux/regmap.h | 4 +++-
> >  1 file changed, 3 insertions(+), 1 deletion(-)
> > 
> > diff --git a/include/linux/regmap.h b/include/linux/regmap.h
> > index 59c55ea0f0b5..6ff83c9ddb45 100644
> > --- a/include/linux/regmap.h
> > +++ b/include/linux/regmap.h
> > @@ -296,8 +296,11 @@ typedef void (*regmap_hw_free_context)(void *context);
> >   *                if not implemented  on a given device.
> >   * @async_write: Write operation which completes asynchronously, optional and
> >   *               must serialise with respect to non-async I/O.
> > + * @reg_write: Write operation for a register. Writes value to register.
> >   * @read: Read operation.  Data is returned in the buffer used to transmit
> >   *         data.
> > + * @reg_read: Read operation for a register. Reads a value from a register.
> > + * @free_conetext: Free context.
> 
> Typo: free_context

Thanks, fixed for next version.

Best regards,

Markus

-- 
Pengutronix e.K.                           |                             |
Industrial Linux Solutions                 | http://www.pengutronix.de/  |
Peiner Str. 6-8, 31137 Hildesheim, Germany | Phone: +49-5121-206917-0    |
Amtsgericht Hildesheim, HRA 2686           | Fax:   +49-5121-206917-5555 |
-------------- next part --------------
A non-text attachment was scrubbed...
Name: signature.asc
Type: application/pgp-signature
Size: 819 bytes
Desc: Digital signature
URL: <http://lists.infradead.org/pipermail/linux-arm-kernel/attachments/20150817/5d67c2aa/attachment.sig>

From michal.simek at xilinx.com  Mon Aug 17 00:22:31 2015
From: michal.simek at xilinx.com (Michal Simek)
Date: Mon, 17 Aug 2015 09:22:31 +0200
Subject: [PATCH 1/4] serial: xuartps: Fix termios issue for enabling odd parity
Message-ID: <5b154ba97bcd79e49e2131152eb2fc1761594a6c.1439796149.git.michal.simek@xilinx.com>

From: Anirudha Sarangi <anirudha.sarangi at xilinx.com>

Existing set_termios does not handle the option for enabling
odd parity. This patch fixes it.

Signed-off-by: Anirudha Sarangi <anirudh at xilinx.com>
Signed-off-by: Michal Simek <michal.simek at xilinx.com>
---

 drivers/tty/serial/xilinx_uartps.c | 2 +-
 1 file changed, 1 insertion(+), 1 deletion(-)

diff --git a/drivers/tty/serial/xilinx_uartps.c b/drivers/tty/serial/xilinx_uartps.c
index 009e0dbc12d2..a3020344ac9d 100644
--- a/drivers/tty/serial/xilinx_uartps.c
+++ b/drivers/tty/serial/xilinx_uartps.c
@@ -723,7 +723,7 @@ static void cdns_uart_set_termios(struct uart_port *port,
 	else
 		cval |= CDNS_UART_MR_STOPMODE_1_BIT; /* 1 STOP bit */
 
-	if (termios->c_cflag & PARENB) {
+	if ((termios->c_cflag & PARENB) || (termios->c_cflag & PARODD)) {
 		/* Mark or Space parity */
 		if (termios->c_cflag & CMSPAR) {
 			if (termios->c_cflag & PARODD)
-- 
2.3.5



From yao.yuan at freescale.com  Mon Aug 17 00:22:45 2015
From: yao.yuan at freescale.com (Yao Yuan)
Date: Mon, 17 Aug 2015 07:22:45 +0000
Subject: [PATCH v2] dmaengine: fsl-edma: add PM suspend/resume support
In-Reply-To: <55D183D1.9020401@nigelcunningham.com.au>
References: <1437469005-3162-1-git-send-email-yao.yuan@freescale.com>
 <CADRPPNQJi_x+mdQV=DEVuhCL_p6VOWcPiV3jzioeRdWgSW2w3g@mail.gmail.com>
 <CY1PR0301MB15628DD5CFCE2B65BF4FECB2837C0@CY1PR0301MB1562.namprd03.prod.outlook.com>
 <CADRPPNS_wzX+mwT0L-H=ZP9w8gH9W4O9KUqnGYiAc39S5v4qLA@mail.gmail.com>
 <CY1PR0301MB1562103588FB0C6BEFDDBF3C83790@CY1PR0301MB1562.namprd03.prod.outlook.com>
 <55D183D1.9020401@nigelcunningham.com.au>
Message-ID: <CY1PR0301MB1562FBE9818C1973651D2B7183790@CY1PR0301MB1562.namprd03.prod.outlook.com>

Hi Nigel,

On Mon, Aug 17, 2015 at 2:49 PM, Nigel Cunningham < nigel at nigelcunningham.com.au > wrote:
> On 17/08/15 13:59, Yao Yuan wrote:
> > On Sat, Aug 15, 2015 at 7:48 AM, pku.leo < pku.leo at gmail.com > wrote:
> >> On Fri, Aug 14, 2015 at 1:24 AM, Yao Yuan <yao.yuan at freescale.com> wrote:
> >>> Hi Leo,
> >>>
> >>> Thanks for your review.
> >>> About those two methods for DMA suspend that you have mentioned.
> We
> >> have a lot of the discussions in other DMA driver like DMA for
> >> Freescale PowerPC.
> >>> Finally, we think the device which used the DMA transmission service
> >>> should
> >> cancel the transmission service in its suspend.
> >>> So DMA in suspend should be idle.
> >> If that's the case you should clearly state this in the commit
> >> message and in code, although I don't know if it is safe to make such
> >> assumption.  There could be user of the DMA that doesn't track the
> completion of transfers.
> > I think it should be safe. In my opinion, even some client(the user of
> > the DMA) forget to cancel its DMA transmission, It will just lead to PM failed
> but no other system and data risk.
> > Although we should first fix the behavior of the client.
> > Once you are no need the DMA transmission, why not stop it?
> >
> > Is it right?
> Think of it from the end user perspective. Would you like your laptop (or
> whatever) to refuse to suspend because of this condition? The user may well
> expect that closing the lid on their laptop will reliably lead to it suspending to
> ram. Returning a failure here could result in a loss of data if the condition is not
> detected and the machine subsequently runs out of power.
> 

Yes, the user may well expect that closing the lid on their laptop will reliably lead to it suspending to ram.
So the client(the user of the DMA) must  to PAUSE or terminate the DMA transmission.

We need to rely on client doing the right thing here. 
The DMA should not make a decision instead of client.
If the DMA is not idle in DMA suspend, it should be the client's issue.
We don't know what the client really want to do, so just return the non-success value.

> I do agree that whatever is submitting DMA should be stopped first; ideally this
> driver would always be idle because whatever producers of work exist would
> already have been quiesced and output flushed.
> 

From michal.simek at xilinx.com  Mon Aug 17 00:22:32 2015
From: michal.simek at xilinx.com (Michal Simek)
Date: Mon, 17 Aug 2015 09:22:32 +0200
Subject: [PATCH 2/4] serial: xuartps: Do not handle overrun errors under
 IGNPAR option
In-Reply-To: <5b154ba97bcd79e49e2131152eb2fc1761594a6c.1439796149.git.michal.simek@xilinx.com>
References: <5b154ba97bcd79e49e2131152eb2fc1761594a6c.1439796149.git.michal.simek@xilinx.com>
Message-ID: <41df6eb35d69801afa5b686a6974e3c3bf65178a.1439796149.git.michal.simek@xilinx.com>

From: Anirudha Sarangi <anirudha.sarangi at xilinx.com>

The existing implementation includes overrun errors under IGNPAR
option. This patch fixes it by including only parity and framing
error under IGNPAR option.

Signed-off-by: Anirudha Sarangi <anirudh at xilinx.com>
Signed-off-by: Michal Simek <michal.simek at xilinx.com>
---

 drivers/tty/serial/xilinx_uartps.c | 2 +-
 1 file changed, 1 insertion(+), 1 deletion(-)

diff --git a/drivers/tty/serial/xilinx_uartps.c b/drivers/tty/serial/xilinx_uartps.c
index a3020344ac9d..c4437e8929ff 100644
--- a/drivers/tty/serial/xilinx_uartps.c
+++ b/drivers/tty/serial/xilinx_uartps.c
@@ -691,7 +691,7 @@ static void cdns_uart_set_termios(struct uart_port *port,
 
 	if (termios->c_iflag & IGNPAR)
 		port->ignore_status_mask |= CDNS_UART_IXR_PARITY |
-			CDNS_UART_IXR_FRAMING | CDNS_UART_IXR_OVERRUN;
+					    CDNS_UART_IXR_FRAMING;
 
 	/* ignore all characters if CREAD is not set */
 	if ((termios->c_cflag & CREAD) == 0)
-- 
2.3.5



From michal.simek at xilinx.com  Mon Aug 17 00:22:33 2015
From: michal.simek at xilinx.com (Michal Simek)
Date: Mon, 17 Aug 2015 09:22:33 +0200
Subject: [PATCH 3/4] serial: xuartps: Do not enable parity error interrupt
In-Reply-To: <5b154ba97bcd79e49e2131152eb2fc1761594a6c.1439796149.git.michal.simek@xilinx.com>
References: <5b154ba97bcd79e49e2131152eb2fc1761594a6c.1439796149.git.michal.simek@xilinx.com>
Message-ID: <d586f20ceb4a1f355ccf8817c95877d11c14b824.1439796149.git.michal.simek@xilinx.com>

From: Anirudha Sarangi <anirudha.sarangi at xilinx.com>

The patch makes changes not to enable parity error interrupt.
With the current implementation, each parity error results in
two distinct interrupts (almost always). The first one is normal
parity error interrupt with no data in the fifo and the second one
is a proper Rx interrupt with the received data in the fifo. By
disabling parity error interrupt we still ensure handling of
parity errors as for the Rx fifo interrupt the parity error still
shows up in the interrupt status register. Considering the fact
that the by default INPCK and IGNPAR are not set, this is the
optimal implementation for parity error handling.

Signed-off-by: Anirudha Sarangi <anirudh at xilinx.com>
Signed-off-by: Michal Simek <michal.simek at xilinx.com>
---

 drivers/tty/serial/xilinx_uartps.c | 14 ++++++++++++--
 1 file changed, 12 insertions(+), 2 deletions(-)

diff --git a/drivers/tty/serial/xilinx_uartps.c b/drivers/tty/serial/xilinx_uartps.c
index c4437e8929ff..2dc26e5f1384 100644
--- a/drivers/tty/serial/xilinx_uartps.c
+++ b/drivers/tty/serial/xilinx_uartps.c
@@ -803,8 +803,18 @@ static int cdns_uart_startup(struct uart_port *port)
 	writel(readl(port->membase + CDNS_UART_ISR_OFFSET),
 			port->membase + CDNS_UART_ISR_OFFSET);
 
-	/* Set the Interrupt Registers with desired interrupts */
-	writel(CDNS_UART_IXR_TXEMPTY | CDNS_UART_IXR_PARITY |
+	/*
+	 * Set the Interrupt Registers with desired interrupts. Do not
+	 * enable parity error interrupt for the following reason:
+	 * When parity error interrupt is enabled, each Rx parity error always
+	 * results in 2 events. The first one being parity error interrupt
+	 * and the second one with a proper Rx interrupt with the incoming data.
+	 * Disabling parity error interrupt ensures better handling of parity
+	 * error events. With this change, for a parity error case, we get a
+	 * Rx interrupt with parity error set in ISR register and we still
+	 * handle parity errors in the desired way.
+	 */
+	writel(CDNS_UART_IXR_TXEMPTY |
 		CDNS_UART_IXR_FRAMING | CDNS_UART_IXR_OVERRUN |
 		CDNS_UART_IXR_RXTRIG | CDNS_UART_IXR_TOUT,
 		port->membase + CDNS_UART_IER_OFFSET);
-- 
2.3.5



From michal.simek at xilinx.com  Mon Aug 17 00:22:34 2015
From: michal.simek at xilinx.com (Michal Simek)
Date: Mon, 17 Aug 2015 09:22:34 +0200
Subject: [PATCH 4/4] serial: xuartps: Rewrite the interrupt handling logic
In-Reply-To: <5b154ba97bcd79e49e2131152eb2fc1761594a6c.1439796149.git.michal.simek@xilinx.com>
References: <5b154ba97bcd79e49e2131152eb2fc1761594a6c.1439796149.git.michal.simek@xilinx.com>
Message-ID: <ead0c38140e815133a47797a2527229a2fc077c1.1439796149.git.michal.simek@xilinx.com>

From: Anirudha Sarangi <anirudha.sarangi at xilinx.com>

The existing interrupt handling logic has followins issues.
- Upon a parity error with default configuration, the control
  never comes out of the ISR thereby hanging Linux.
- The error handling logic around framing and parity error are buggy.
  There are chances that the errors will never be captured.
- The existing ISR is just too long.
This patch fixes all these concerns. It separates out the Tx and Rx
hanling logic into separate functions. It ensures that the status
registers are cleared on all cases so that a hang situation never
arises.

Signed-off-by: Anirudha Sarangi <anirudh at xilinx.com>
Signed-off-by: Michal Simek <michal.simek at xilinx.com>
---

 drivers/tty/serial/xilinx_uartps.c | 194 ++++++++++++++++++++-----------------
 1 file changed, 104 insertions(+), 90 deletions(-)

diff --git a/drivers/tty/serial/xilinx_uartps.c b/drivers/tty/serial/xilinx_uartps.c
index 2dc26e5f1384..c771dbbf6161 100644
--- a/drivers/tty/serial/xilinx_uartps.c
+++ b/drivers/tty/serial/xilinx_uartps.c
@@ -173,61 +173,86 @@ struct cdns_uart {
 		clk_rate_change_nb);
 
 /**
- * cdns_uart_isr - Interrupt handler
- * @irq: Irq number
- * @dev_id: Id of the port
- *
- * Return: IRQHANDLED
+ * cdns_uart_handle_tx - Handle the bytes to be Txed.
+ * @dev_id: Id of the UART port
+ * Return: None
  */
-static irqreturn_t cdns_uart_isr(int irq, void *dev_id)
+static void cdns_uart_handle_tx(void *dev_id)
 {
 	struct uart_port *port = (struct uart_port *)dev_id;
-	unsigned long flags;
-	unsigned int isrstatus, numbytes;
-	unsigned int data;
-	char status = TTY_NORMAL;
+	unsigned int numbytes;
 
-	spin_lock_irqsave(&port->lock, flags);
+	if (uart_circ_empty(&port->state->xmit)) {
+		writel(CDNS_UART_IXR_TXEMPTY, port->membase +
+		       CDNS_UART_IDR_OFFSET);
+	} else {
+		numbytes = port->fifosize;
+		/* Break if no more data available in the UART buffer */
+		while (numbytes--) {
+			if (uart_circ_empty(&port->state->xmit))
+				break;
+			/*
+			 * Get the data from the UART circular buffer
+			 * and write it to the cdns_uart's TX_FIFO
+			 * register.
+			 */
+			writel(port->state->xmit.buf[port->state->xmit.tail],
+			       port->membase + CDNS_UART_FIFO_OFFSET);
 
-	/* Read the interrupt status register to determine which
-	 * interrupt(s) is/are active.
-	 */
-	isrstatus = readl(port->membase + CDNS_UART_ISR_OFFSET);
+			port->icount.tx++;
 
-	/*
-	 * There is no hardware break detection, so we interpret framing
-	 * error with all-zeros data as a break sequence. Most of the time,
-	 * there's another non-zero byte at the end of the sequence.
-	 */
-	if (isrstatus & CDNS_UART_IXR_FRAMING) {
-		while (!(readl(port->membase + CDNS_UART_SR_OFFSET) &
-					CDNS_UART_SR_RXEMPTY)) {
-			if (!readl(port->membase + CDNS_UART_FIFO_OFFSET)) {
-				port->read_status_mask |= CDNS_UART_IXR_BRK;
-				isrstatus &= ~CDNS_UART_IXR_FRAMING;
-			}
+			/*
+			 * Adjust the tail of the UART buffer and wrap
+			 * the buffer if it reaches limit.
+			 */
+			port->state->xmit.tail =
+				(port->state->xmit.tail + 1) &
+					(UART_XMIT_SIZE - 1);
 		}
-		writel(CDNS_UART_IXR_FRAMING,
-				port->membase + CDNS_UART_ISR_OFFSET);
-	}
 
-	/* drop byte with parity error if IGNPAR specified */
-	if (isrstatus & port->ignore_status_mask & CDNS_UART_IXR_PARITY)
-		isrstatus &= ~(CDNS_UART_IXR_RXTRIG | CDNS_UART_IXR_TOUT);
+		if (uart_circ_chars_pending(
+				&port->state->xmit) < WAKEUP_CHARS)
+			uart_write_wakeup(port);
+	}
+}
 
-	isrstatus &= port->read_status_mask;
-	isrstatus &= ~port->ignore_status_mask;
+/**
+ * cdns_uart_handle_rx - Handle the received bytes along with Rx errors.
+ * @dev_id: Id of the UART port
+ * @isrstatus: The interrupt status register value as read
+ * Return: None
+ */
+static void cdns_uart_handle_rx(void *dev_id, unsigned int isrstatus)
+{
+	struct uart_port *port = (struct uart_port *)dev_id;
+	unsigned int data;
+	unsigned int framerrprocessed = 0;
+	char status = TTY_NORMAL;
 
-	if ((isrstatus & CDNS_UART_IXR_TOUT) ||
-		(isrstatus & CDNS_UART_IXR_RXTRIG)) {
-		/* Receive Timeout Interrupt */
-		while (!(readl(port->membase + CDNS_UART_SR_OFFSET) &
-					CDNS_UART_SR_RXEMPTY)) {
-			data = readl(port->membase + CDNS_UART_FIFO_OFFSET);
+	while ((readl(port->membase + CDNS_UART_SR_OFFSET) &
+		CDNS_UART_SR_RXEMPTY) != CDNS_UART_SR_RXEMPTY) {
+		data = readl(port->membase + CDNS_UART_FIFO_OFFSET);
+		port->icount.rx++;
+		/*
+		 * There is no hardware break detection, so we interpret
+		 * framing error with all-zeros data as a break sequence.
+		 * Most of the time, there's another non-zero byte at the
+		 * end of the sequence.
+		 */
+		if (isrstatus & CDNS_UART_IXR_FRAMING) {
+			if (!data) {
+				port->read_status_mask |= CDNS_UART_IXR_BRK;
+				framerrprocessed = 1;
+				continue;
+			}
+		}
+		isrstatus &= port->read_status_mask;
+		isrstatus &= ~port->ignore_status_mask;
 
-			/* Non-NULL byte after BREAK is garbage (99%) */
-			if (data && (port->read_status_mask &
-						CDNS_UART_IXR_BRK)) {
+		if ((isrstatus & CDNS_UART_IXR_TOUT) ||
+		    (isrstatus & CDNS_UART_IXR_RXTRIG)) {
+			if (data &&
+			    (port->read_status_mask & CDNS_UART_IXR_BRK)) {
 				port->read_status_mask &= ~CDNS_UART_IXR_BRK;
 				port->icount.brk++;
 				if (uart_handle_break(port))
@@ -249,67 +274,56 @@ static irqreturn_t cdns_uart_isr(int irq, void *dev_id)
 				spin_lock(&port->lock);
 			}
 #endif
-
-			port->icount.rx++;
-
 			if (isrstatus & CDNS_UART_IXR_PARITY) {
 				port->icount.parity++;
 				status = TTY_PARITY;
-			} else if (isrstatus & CDNS_UART_IXR_FRAMING) {
+			}
+			if ((isrstatus & CDNS_UART_IXR_FRAMING) &&
+			    !framerrprocessed) {
 				port->icount.frame++;
 				status = TTY_FRAME;
-			} else if (isrstatus & CDNS_UART_IXR_OVERRUN) {
+			}
+			if (isrstatus & CDNS_UART_IXR_OVERRUN) {
 				port->icount.overrun++;
+				tty_insert_flip_char(&port->state->port, 0,
+						     TTY_OVERRUN);
 			}
-
-			uart_insert_char(port, isrstatus, CDNS_UART_IXR_OVERRUN,
-					data, status);
+			tty_insert_flip_char(&port->state->port, data, status);
 		}
-		spin_unlock(&port->lock);
-		tty_flip_buffer_push(&port->state->port);
-		spin_lock(&port->lock);
 	}
+	spin_unlock(&port->lock);
+	tty_flip_buffer_push(&port->state->port);
+	spin_lock(&port->lock);
+}
 
-	/* Dispatch an appropriate handler */
-	if ((isrstatus & CDNS_UART_IXR_TXEMPTY) == CDNS_UART_IXR_TXEMPTY) {
-		if (uart_circ_empty(&port->state->xmit)) {
-			writel(CDNS_UART_IXR_TXEMPTY,
-					port->membase + CDNS_UART_IDR_OFFSET);
-		} else {
-			numbytes = port->fifosize;
-			/* Break if no more data available in the UART buffer */
-			while (numbytes--) {
-				if (uart_circ_empty(&port->state->xmit))
-					break;
-				/* Get the data from the UART circular buffer
-				 * and write it to the cdns_uart's TX_FIFO
-				 * register.
-				 */
-				writel(port->state->xmit.buf[
-						port->state->xmit.tail],
-					port->membase + CDNS_UART_FIFO_OFFSET);
-
-				port->icount.tx++;
-
-				/* Adjust the tail of the UART buffer and wrap
-				 * the buffer if it reaches limit.
-				 */
-				port->state->xmit.tail =
-					(port->state->xmit.tail + 1) &
-						(UART_XMIT_SIZE - 1);
-			}
+/**
+ * cdns_uart_isr - Interrupt handler
+ * @irq: Irq number
+ * @dev_id: Id of the port
+ *
+ * Return: IRQHANDLED
+ */
+static irqreturn_t cdns_uart_isr(int irq, void *dev_id)
+{
+	struct uart_port *port = (struct uart_port *)dev_id;
+	unsigned int isrstatus;
 
-			if (uart_circ_chars_pending(
-					&port->state->xmit) < WAKEUP_CHARS)
-				uart_write_wakeup(port);
-		}
-	}
+	spin_lock(&port->lock);
 
+	/* Read the interrupt status register to determine which
+	 * interrupt(s) is/are active and clear them.
+	 */
+	isrstatus = readl(port->membase + CDNS_UART_ISR_OFFSET);
 	writel(isrstatus, port->membase + CDNS_UART_ISR_OFFSET);
 
-	/* be sure to release the lock and tty before leaving */
-	spin_unlock_irqrestore(&port->lock, flags);
+	if (isrstatus & CDNS_UART_IXR_TXEMPTY) {
+		cdns_uart_handle_tx(dev_id);
+		isrstatus &= ~CDNS_UART_IXR_TXEMPTY;
+	}
+	if (isrstatus & CDNS_UART_IXR_MASK)
+		cdns_uart_handle_rx(dev_id, isrstatus);
 
+	spin_unlock(&port->lock);
 	return IRQ_HANDLED;
 }
 
-- 
2.3.5



From mpa at pengutronix.de  Mon Aug 17 00:24:03 2015
From: mpa at pengutronix.de (Markus Pargmann)
Date: Mon, 17 Aug 2015 09:24:03 +0200
Subject: [PATCH 16/20] iio: bmc150: Fix irq checks
In-Reply-To: <55CF3AEA.2070508@kernel.org>
References: <1439374365-20623-1-git-send-email-mpa@pengutronix.de>
 <1439374365-20623-17-git-send-email-mpa@pengutronix.de>
 <55CF3AEA.2070508@kernel.org>
Message-ID: <20150817072403.GI19600@pengutronix.de>

On Sat, Aug 15, 2015 at 02:13:14PM +0100, Jonathan Cameron wrote:
> On 12/08/15 11:12, Markus Pargmann wrote:
> > Valid irqs are > 0. This patch fixes the check which fails for the new
> > spi driver part if no interrupt was given.
> > 
> > Signed-off-by: Markus Pargmann <mpa at pengutronix.de>
> This one crossed with Octavian's patch that cleaned up all cases of this.
> c176becd81843 iio: fix drivers that consider 0 as a valid IRQ in client->irq
> 
> Hence you can drop this one from the v2 of this series.

Thanks, didn't notice this. Will drop it.

Best regards,

Markus

> 
> (Its amazing how many times we get multiple patches for the same issue that
> has been there for ages in the same week or so!)
> 
> Jonathan
> > ---
> >  drivers/iio/accel/bmc150-accel.c | 4 ++--
> >  1 file changed, 2 insertions(+), 2 deletions(-)
> > 
> > diff --git a/drivers/iio/accel/bmc150-accel.c b/drivers/iio/accel/bmc150-accel.c
> > index 4e70f51c2370..fe2d2316158f 100644
> > --- a/drivers/iio/accel/bmc150-accel.c
> > +++ b/drivers/iio/accel/bmc150-accel.c
> > @@ -1660,10 +1660,10 @@ static int bmc150_accel_probe(struct i2c_client *client,
> >  		return ret;
> >  	}
> >  
> > -	if (client->irq < 0)
> > +	if (client->irq <= 0)
> >  		client->irq = bmc150_accel_gpio_probe(client, data);
> >  
> > -	if (client->irq >= 0) {
> > +	if (client->irq > 0) {
> >  		ret = devm_request_threaded_irq(
> >  						&client->dev, client->irq,
> >  						bmc150_accel_irq_handler,
> > 
> 
> 

-- 
Pengutronix e.K.                           |                             |
Industrial Linux Solutions                 | http://www.pengutronix.de/  |
Peiner Str. 6-8, 31137 Hildesheim, Germany | Phone: +49-5121-206917-0    |
Amtsgericht Hildesheim, HRA 2686           | Fax:   +49-5121-206917-5555 |
-------------- next part --------------
A non-text attachment was scrubbed...
Name: signature.asc
Type: application/pgp-signature
Size: 819 bytes
Desc: Digital signature
URL: <http://lists.infradead.org/pipermail/linux-arm-kernel/attachments/20150817/303e7960/attachment.sig>

From gnurou at gmail.com  Mon Aug 17 00:29:18 2015
From: gnurou at gmail.com (Alexandre Courbot)
Date: Mon, 17 Aug 2015 16:29:18 +0900
Subject: [PATCH 6/6] gpiolib: Add gpio name information to
 /sys/kernel/debug/gpio
In-Reply-To: <CACRpkdajd5B6qUa6mi_0m53eMtLenoAWUCnmq-mOC+EhXfzpTA@mail.gmail.com>
References: <1438680203-13432-1-git-send-email-mpa@pengutronix.de>
 <1438680203-13432-7-git-send-email-mpa@pengutronix.de>
 <CACRpkdajd5B6qUa6mi_0m53eMtLenoAWUCnmq-mOC+EhXfzpTA@mail.gmail.com>
Message-ID: <CAAVeFuKSQP2DYWdhYy-k+cr9F0jc46Q-xuoWXSTguQYaf3SY+w@mail.gmail.com>

On Mon, Aug 10, 2015 at 7:02 PM, Linus Walleij <linus.walleij at linaro.org> wrote:
> On Tue, Aug 4, 2015 at 11:23 AM, Markus Pargmann <mpa at pengutronix.de> wrote:
>
>> Add some information about gpio names to the debugfs gpio file. name and
>> label of a GPIO are then displayed next to each other. This way it is
>> easy to see what the real name of GPIO is and what the driver requested
>> it for.
>>
>> Signed-off-by: Markus Pargmann <mpa at pengutronix.de>
>
> This patch looks correct in the context.

Looks correct indeed, but on a related note one might question the
need to have both a "name" and a "label" for a GPIO?


From linux at arm.linux.org.uk  Sun Aug 16 07:06:39 2015
From: linux at arm.linux.org.uk (Russell King - ARM Linux)
Date: Sun, 16 Aug 2015 15:06:39 +0100
Subject: [PATCH] spi: Mediatek: fix endian warnings
In-Reply-To: <1871097.B3YgX5rNy0@wuerfel>
References: <1439289789-29026-1-git-send-email-leilk.liu@mediatek.com>
 <1871097.B3YgX5rNy0@wuerfel>
Message-ID: <20150816140639.GE7557@n2100.arm.linux.org.uk>

On Sat, Aug 15, 2015 at 10:16:03PM +0200, Arnd Bergmann wrote:
> On Tuesday 11 August 2015 18:43:09 Leilk Liu wrote:
> > @@ -359,9 +359,11 @@ static void mtk_spi_setup_dma_addr(struct spi_master *master,
> >         struct mtk_spi *mdata = spi_master_get_devdata(master);
> >  
> >         if (mdata->tx_sgl)
> > -               writel(cpu_to_le32(xfer->tx_dma), mdata->base + SPI_TX_SRC_REG);
> > +               writel((__force u32)cpu_to_le32(xfer->tx_dma),
> > +                      mdata->base + SPI_TX_SRC_REG);
> >         if (mdata->rx_sgl)
> > -               writel(cpu_to_le32(xfer->rx_dma), mdata->base + SPI_RX_DST_REG);
> > +               writel((__force u32)cpu_to_le32(xfer->rx_dma),
> > +                      mdata->base + SPI_RX_DST_REG);
> >  }
> > 
> 
> This looks wrong: writel takes a CPU-endian argument, so the value returned
> from cpu_to_le32() is not appropriate.
> 
> The warning is correct, and you have to remove the cpu_to_le32() conversion
> in order to get the driver to behave correctly when the kernel is built
> as big-endian.

Indeed, it's about time people started thinking more about the warnings
and why we have coded things in the way we have.

Look people.  cpu_to_le32() takes a value in the CPU endian, and
converts it to a little endian 32-bit number.  See, the clue is in
the name.

All writel() implementations take a CPU number and write it in little
endian format.  Hence, writel() almost always uses cpu_to_le32()
internally.

Now think about what you're saying with "cpu_to_le32(cpu_to_le32())".
It's utter rubbish, total crap.  It's wrong no matter which way you
look at it.

We have le32_to_cpu() which does what it says on the tin.  Same with
be32_to_cpu() and cpu_to_be32().

Don't hack around this stuff with __force.  If you're having to use
__force to get rid of a warning here, you _ARE_ doing something wrong,
no questions about that.  __force in driver code is a definite sign
that you are doing something wrong.  Don't do it.  Ask the question
if you think you need it.

-- 
FTTC broadband for 0.8mile line: currently at 10.5Mbps down 400kbps up
according to speedtest.net.


From boris.brezillon at free-electrons.com  Mon Aug 17 00:34:11 2015
From: boris.brezillon at free-electrons.com (Boris Brezillon)
Date: Mon, 17 Aug 2015 09:34:11 +0200
Subject: ARM: sunxi: Experiences NAND flash
In-Reply-To: <55C9E7B4.9090906@schinagl.nl>
References: <55C9E7B4.9090906@schinagl.nl>
Message-ID: <20150817093411.4ff853c4@bbrezillon>

Hi Oliver,

Sorry for the late reply (I was in vacation for the last 2 weeks)

On Tue, 11 Aug 2015 14:16:52 +0200
Olliver Schinagl <oliver+list at schinagl.nl> wrote:

> Hello everybody,
> 
> We are working with Boris and Roy's patch series on getting the NAND 
> flash chip working on Olimex OLinuXino Lime2 boards. Initially, 
> everything looks fine, but we noticed that occasionally (after 
> power/cycle or power cut) ubi fails to mount the partition. It is not 
> something easily enough to reproduce, but it has failed on 5 boards out 
> of 30 we have.

I remember warning you about that problem before: MLC NANDs are not as
reliable as SLC ones (please read my presentation about MLC support in
Linux [1]). I also remember recommending using an SLC chip if you were
tight on time to avoid dealing with all these MLC related problems, but
you decided to go for the MLC solution.

Back to your problem now, what you're seeing here is probably caused by
interrupted PROGRAM operations on paired pages (page 17, 18 and 26 to 32
of my presentation for more information).

> 
> U-boot reports the following:
> UBI: default fastmap pool size: 100
> UBI: default fastmap WL pool size: 25
> UBI: attaching mtd1 to ubi0
> UBI: scanning is finished
> UBI init error 22
> Error reading superblock on volume 'ubi:boot' errno=-19!
> ubifsmount - mount UBIFS volume
> 
> whereas the linux kernel booted from sd card gives:
> ubiattach /dev/ubi_ctrl -m 0
> [  100.560704] ubi0: default fastmap pool size: 8
> [  100.565186] ubi0: default fastmap WL pool size: 4
> [  100.570100] ubi0: attaching mtd0
> [  100.590469] ubi0: scanning is finished
> [  100.594732] ubi0 error: ubi_read_volume_table: the layout volume was 
> not found
> [  100.602675] ubi0 error: ubi_attach_mtd_dev: failed to attach mtd0, 
> error -22
> ubiattach: error!: cannot attach mtd0
>             error 22 (Invalid argument)
> 
> The u-boot version we are using is a few months out of date
> U-Boot 2015.07-rc2-g2540c39 (Aug 04 2015 - 16:09:02 +0200) Allwinner 
> Technology
> arm-none-eabi-gcc (4.8.4-1+11-1) 4.8.4 20141219 (release)
> GNU ld (2.25-5+5+b1) 2.25
> 
> but the kernel is fairly up to date:
> 4.2.0-rc4-opinicus-g8ec3671
> 
> 
> Now I know that the mtd stuff is all very new and all very untested, 
> what I am curious about is a) have other people actually tried the mtd 
> stuff on Allwinner hardware, and b) has anybody encountered this issue 
> as well?

Yes we did. So far we're using the NAND in SLC mode to address this
problem. It seems to work, but you also loose half the NAND capacity.

> 
> It's not something very easily reproducible (toggling a machine on/off 
> repeatedly did not trigger it yet) but it does happen.

I managed to reproduce it by faking a power cut directly in the NAND
core code (by sending a RESET command to the NAND chip in the middle of
a program operation), and I can confirm SLC mode address the problem.

Anyway, remember that MLC NANDs have other sources of unreliability
(e.g the unstable bits problem).

Best Regards,

Boris


[1]http://events.linuxfoundation.org/sites/events/files/slides/brezillon-mlc-nand_0.pdf

-- 
Boris Brezillon, Free Electrons
Embedded Linux and Kernel engineering
http://free-electrons.com


From lee.jones at linaro.org  Mon Aug 17 00:42:44 2015
From: lee.jones at linaro.org (Lee Jones)
Date: Mon, 17 Aug 2015 08:42:44 +0100
Subject: [PATCH v7 4/5] clk: Provide critical clock support
In-Reply-To: <CAGsJ_4zKn-o4ZxZ0-xzCStvuTkdC5xqD9FneWna-0dNVgp=1DQ@mail.gmail.com>
References: <1437570255-21049-1-git-send-email-lee.jones@linaro.org>
 <1437570255-21049-5-git-send-email-lee.jones@linaro.org>
 <CAGsJ_4zKn-o4ZxZ0-xzCStvuTkdC5xqD9FneWna-0dNVgp=1DQ@mail.gmail.com>
Message-ID: <20150817074244.GA3239@x1>

On Mon, 17 Aug 2015, Barry Song wrote:

> 2015-07-22 21:04 GMT+08:00 Lee Jones <lee.jones at linaro.org>:
> > Lots of platforms contain clocks which if turned off would prove fatal.
> > The only way to recover from these catastrophic failures is to restart
> > the board(s).  Now, when a clock provider is registered with the
> > framework it is possible for a list of critical clocks to be supplied
> > which must be kept ungated.  Each clock mentioned in the newly
> > introduced 'critical-clock' property will be clk_prepare_enable()d
> > where the normal references will be taken.  This will prevent the
> > common clk framework from attempting to gate them during the normal
> > clk_disable_unused() and disable_clock() procedures.
> >
> > Note that it will still be possible for knowledgeable drivers to turn
> > these clocks off using clk_{enable,disable}_critical() calls.
> >
> > Signed-off-by: Lee Jones <lee.jones at linaro.org>
> 
> hi Lee,
> i have another email about this. i am wondering whether
> CLK_IGNORE_UNUSE is still useful after your patch. another solution
> for your patch might be extending the current CLK_IGNORE_UNUSE to
> runtime?
> 
> 
> copy the mail here:
> currently we can set a CLK_IGNORE_UNUSE flag to  a clock to stop
> clk_disable_unused()  from disabling it at the boot stage:
> 
> static void clk_disable_unused_subtree(struct clk_core *core)
> {
> ...
> 
> if (core->flags & CLK_IGNORE_UNUSED)
> goto unlock_out;
> }
> 
> static int clk_disable_unused(void)
> {
> ...
> 
> clk_unprepare_unused_subtree(core);
> ...
>  return 0;
> }
> 
> late_initcall_sync(clk_disable_unused);
> 
> so if there are two clocks A and B, A is the parent of B, and A is
> marked as CLK_IGNORE_UNUSED.
> 
> in boot stage if there is nobody using A and B, Linux will disable B
> due to clk_disable_unused() , but keep A being enabled since A has
> CLK_IGNORE_UNUSED.
> 
> but in Linux runtime, we might frequently disable /enable B in runtime
> power management, this will cause A disabled since Linux will not
> check CLK_IGNORE_UNUSED for runtime disabling clk .
> 
>  so this makes CLK_IGNORE_UNUSE only work if we don't disable its
> sub-clock at runtime. this looks making no sense.
> 
>  i am thinking whether we should do some changes to make it have side
> affect for runtime clk disable. otherwise, why do we want to stop it
> from being disabled during boot stage?

This is one of this problems, along with some others that this set
aims to solve.

Extending CLK_IGNORE_UNUSED is not a good idea.  In fact, if we can
phase it out completely, that will be a good thing.

Since this set Mike has submitted an alternitive solution.

Please see: https://groups.google.com/forum/#!msg/linux.kernel/kX_nWSsWRxU/IZSjhG5Ed4oJ

>  I am not sure whether i missed something in clk core level support.
> 
> -barry
> 
> > ---
> >  drivers/clk/clk-conf.c | 45 ++++++++++++++++++++++++++++++++++++++++++++-
> >  1 file changed, 44 insertions(+), 1 deletion(-)
> >
> > diff --git a/drivers/clk/clk-conf.c b/drivers/clk/clk-conf.c
> > index aad4796..f83c1c2 100644
> > --- a/drivers/clk/clk-conf.c
> > +++ b/drivers/clk/clk-conf.c
> > @@ -116,6 +116,45 @@ static int __set_clk_rates(struct device_node *node, bool clk_supplier)
> >         return 0;
> >  }
> >
> > +static int __set_critical_clocks(struct device_node *node, bool clk_supplier)
> > +{
> > +       struct of_phandle_args clkspec;
> > +       struct clk *clk;
> > +       struct property *prop;
> > +       const __be32 *cur;
> > +       uint32_t index;
> > +       int ret;
> > +
> > +       if (!clk_supplier)
> > +               return 0;
> > +
> > +       of_property_for_each_u32(node, "critical-clock", prop, cur, index) {
> > +               clkspec.np = node;
> > +               clkspec.args_count = 1;
> > +               clkspec.args[0] = index;
> > +
> > +               clk = of_clk_get_from_provider(&clkspec);
> > +               if (IS_ERR(clk)) {
> > +                       pr_err("clk: couldn't get clock %u for %s\n",
> > +                               index, node->full_name);
> > +                       return PTR_ERR(clk);
> > +               }
> > +
> > +               clk_init_critical(clk);
> > +
> > +               ret = clk_prepare_enable(clk);
> > +               if (ret) {
> > +                       pr_err("Failed to enable clock %u for %s: %d\n",
> > +                              index, node->full_name, ret);
> > +                       return ret;
> > +               }
> > +
> > +               pr_debug("Setting clock as critical %pC\n", clk);
> > +       }
> > +
> > +       return 0;
> > +}
> > +
> >  /**
> >   * of_clk_set_defaults() - parse and set assigned clocks configuration
> >   * @node: device node to apply clock settings for
> > @@ -139,6 +178,10 @@ int of_clk_set_defaults(struct device_node *node, bool clk_supplier)
> >         if (rc < 0)
> >                 return rc;
> >
> > -       return __set_clk_rates(node, clk_supplier);
> > +       rc = __set_clk_rates(node, clk_supplier);
> > +       if (rc < 0)
> > +               return rc;
> > +
> > +       return __set_critical_clocks(node, clk_supplier);
> >  }
> >  EXPORT_SYMBOL_GPL(of_clk_set_defaults);

-- 
Lee Jones
Linaro STMicroelectronics Landing Team Lead
Linaro.org ? Open source software for ARM SoCs
Follow Linaro: Facebook | Twitter | Blog


From boris.brezillon at free-electrons.com  Mon Aug 17 00:48:59 2015
From: boris.brezillon at free-electrons.com (Boris Brezillon)
Date: Mon, 17 Aug 2015 09:48:59 +0200
Subject: [linux-sunxi] ARM: sunxi: Experiences NAND flash
In-Reply-To: <55CB4AA3.9050809@schinagl.nl>
References: <55C9E7B4.9090906@schinagl.nl>
	<55CB4AA3.9050809@schinagl.nl>
Message-ID: <20150817094859.7dae8c96@bbrezillon>

Hi Oliver,

On Wed, 12 Aug 2015 15:31:15 +0200
Olliver Schinagl <oliver+list at schinagl.nl> wrote:

> Hey Yassin,
> 
> I'm affraid. The strange thing that seems very related here is that when 
> writing a file onto the flash, it fails and succeeds alternating. It 
> never fails or succeeds twice in a row! And this on any board and any 
> partition.

I don't know if you only pasted half your command sequence, but it
seems you are writing twice on the same memory region without erasing it,
and this is prohibited on NAND devices.

Try with:

# flash_erase /dev/mtd0 && nandwrite -p /dev/mtd0 u-boot-sunxi-with-spl.bin

Best Regards,

Boris

-- 
Boris Brezillon, Free Electrons
Embedded Linux and Kernel engineering
http://free-electrons.com


From mpa at pengutronix.de  Mon Aug 17 00:49:35 2015
From: mpa at pengutronix.de (Markus Pargmann)
Date: Mon, 17 Aug 2015 09:49:35 +0200
Subject: [PATCH 17/20] iio: bmc150: Use i2c regmap
In-Reply-To: <55CF3E53.2080005@kernel.org>
References: <1439374365-20623-1-git-send-email-mpa@pengutronix.de>
 <1439374365-20623-18-git-send-email-mpa@pengutronix.de>
 <55CF3E53.2080005@kernel.org>
Message-ID: <20150817074935.GJ19600@pengutronix.de>

On Sat, Aug 15, 2015 at 02:27:47PM +0100, Jonathan Cameron wrote:
> On 12/08/15 11:12, Markus Pargmann wrote:
> > This replaces all usage of direct i2c accesses with regmap accesses.
> > 
> > Signed-off-by: Markus Pargmann <mpa at pengutronix.de>
> Clearly there is some work needed on the earlier patches and this
> might change as a result (particularly the fifo read).  I'll review
> as is however..
> 
> Few bits on top of what other reviews have highlighted...
> 
> Jonathan
> > ---
> >  drivers/iio/accel/Kconfig        |   2 +
> >  drivers/iio/accel/bmc150-accel.c | 225 +++++++++++++++++----------------------
> >  2 files changed, 101 insertions(+), 126 deletions(-)
> > 
> > diff --git a/drivers/iio/accel/Kconfig b/drivers/iio/accel/Kconfig
> > index 00e7bcbdbe24..01dd03d194d1 100644
> > --- a/drivers/iio/accel/Kconfig
> > +++ b/drivers/iio/accel/Kconfig
> > @@ -22,6 +22,8 @@ config BMC150_ACCEL
> >  	depends on I2C
> >  	select IIO_BUFFER
> >  	select IIO_TRIGGERED_BUFFER
> > +	select REGMAP
> > +	select REGMAP_I2C
> >  	help
> >  	  Say yes here to build support for the following Bosch accelerometers:
> >  	  BMC150, BMI055, BMA250E, BMA222E, BMA255, BMA280.
> > diff --git a/drivers/iio/accel/bmc150-accel.c b/drivers/iio/accel/bmc150-accel.c
> > index fe2d2316158f..1484e956482e 100644
> > --- a/drivers/iio/accel/bmc150-accel.c
> > +++ b/drivers/iio/accel/bmc150-accel.c
> > @@ -35,6 +35,7 @@
> >  #include <linux/iio/trigger.h>
> >  #include <linux/iio/trigger_consumer.h>
> >  #include <linux/iio/triggered_buffer.h>
> > +#include <linux/regmap.h>
> >  
> >  #define BMC150_ACCEL_DRV_NAME			"bmc150_accel"
> >  #define BMC150_ACCEL_IRQ_NAME			"bmc150_accel_event"
> > @@ -185,6 +186,8 @@ enum bmc150_accel_trigger_id {
> >  
> >  struct bmc150_accel_data {
> >  	struct i2c_client *client;
> > +	struct regmap *regmap;
> > +	struct device *dev;
> >  	struct bmc150_accel_interrupt interrupts[BMC150_ACCEL_INTERRUPTS];
> >  	atomic_t active_intr;
> >  	struct bmc150_accel_trigger triggers[BMC150_ACCEL_TRIGGERS];
> > @@ -241,6 +244,14 @@ static const struct {
> >  				       {500000, BMC150_ACCEL_SLEEP_500_MS},
> >  				       {1000000, BMC150_ACCEL_SLEEP_1_SEC} };
> >  
> > +static const struct regmap_config bmc150_i2c_regmap_conf = {
> > +	.reg_bits = 8,
> > +	.val_bits = 8,
> > +	.max_register = 0x3f,
> > +
> > +	.use_single_rw = false,
> > +	.cache_type = REGCACHE_NONE,
> > +};
> >  
> >  static int bmc150_accel_set_mode(struct bmc150_accel_data *data,
> >  				 enum bmc150_power_modes mode,
> > @@ -270,8 +281,7 @@ static int bmc150_accel_set_mode(struct bmc150_accel_data *data,
> >  
> >  	dev_dbg(&data->client->dev, "Set Mode bits %x\n", lpw_bits);
> >  
> > -	ret = i2c_smbus_write_byte_data(data->client,
> > -					BMC150_ACCEL_REG_PMU_LPW, lpw_bits);
> > +	ret = regmap_write(data->regmap, BMC150_ACCEL_REG_PMU_LPW, lpw_bits);
> >  	if (ret < 0) {
> >  		dev_err(&data->client->dev, "Error writing reg_pmu_lpw\n");
> >  		return ret;
> > @@ -289,8 +299,7 @@ static int bmc150_accel_set_bw(struct bmc150_accel_data *data, int val,
> >  	for (i = 0; i < ARRAY_SIZE(bmc150_accel_samp_freq_table); ++i) {
> >  		if (bmc150_accel_samp_freq_table[i].val == val &&
> >  				bmc150_accel_samp_freq_table[i].val2 == val2) {
> > -			ret = i2c_smbus_write_byte_data(
> > -				data->client,
> > +			ret = regmap_write(data->regmap,
> >  				BMC150_ACCEL_REG_PMU_BW,
> >  				bmc150_accel_samp_freq_table[i].bw_bits);
> >  			if (ret < 0)
> > @@ -307,26 +316,19 @@ static int bmc150_accel_set_bw(struct bmc150_accel_data *data, int val,
> >  
> >  static int bmc150_accel_update_slope(struct bmc150_accel_data *data)
> >  {
> > -	int ret, val;
> > +	int ret;
> >  
> > -	ret = i2c_smbus_write_byte_data(data->client, BMC150_ACCEL_REG_INT_6,
> > +	ret = regmap_write(data->regmap, BMC150_ACCEL_REG_INT_6,
> >  					data->slope_thres);
> >  	if (ret < 0) {
> >  		dev_err(&data->client->dev, "Error writing reg_int_6\n");
> >  		return ret;
> >  	}
> >  
> > -	ret = i2c_smbus_read_byte_data(data->client, BMC150_ACCEL_REG_INT_5);
> > +	ret = regmap_update_bits(data->regmap, BMC150_ACCEL_REG_INT_5,
> > +				 BMC150_ACCEL_SLOPE_DUR_MASK, data->slope_dur);
> >  	if (ret < 0) {
> > -		dev_err(&data->client->dev, "Error reading reg_int_5\n");
> > -		return ret;
> > -	}
> > -
> > -	val = (ret & ~BMC150_ACCEL_SLOPE_DUR_MASK) | data->slope_dur;
> > -	ret = i2c_smbus_write_byte_data(data->client, BMC150_ACCEL_REG_INT_5,
> > -					val);
> > -	if (ret < 0) {
> > -		dev_err(&data->client->dev, "Error write reg_int_5\n");
> > +		dev_err(&data->client->dev, "Error updating reg_int_5\n");
> >  		return ret;
> >  	}
> >  
> > @@ -348,17 +350,18 @@ static int bmc150_accel_any_motion_setup(struct bmc150_accel_trigger *t,
> >  static int bmc150_accel_chip_init(struct bmc150_accel_data *data)
> >  {
> >  	int ret;
> > +	unsigned int val;
> >  
> > -	ret = i2c_smbus_read_byte_data(data->client, BMC150_ACCEL_REG_CHIP_ID);
> > +	ret = regmap_read(data->regmap, BMC150_ACCEL_REG_CHIP_ID, &val);
> >  	if (ret < 0) {
> >  		dev_err(&data->client->dev,
> >  			"Error: Reading chip id\n");
> >  		return ret;
> >  	}
> >  
> > -	dev_dbg(&data->client->dev, "Chip Id %x\n", ret);
> > -	if (ret != data->chip_info->chip_id) {
> > -		dev_err(&data->client->dev, "Invalid chip %x\n", ret);
> > +	dev_dbg(&data->client->dev, "Chip Id %x\n", val);
> > +	if (val != data->chip_info->chip_id) {
> > +		dev_err(&data->client->dev, "Invalid chip %x\n", val);
> >  		return -ENODEV;
> >  	}
> >  
> > @@ -372,9 +375,8 @@ static int bmc150_accel_chip_init(struct bmc150_accel_data *data)
> >  		return ret;
> >  
> >  	/* Set Default Range */
> > -	ret = i2c_smbus_write_byte_data(data->client,
> > -					BMC150_ACCEL_REG_PMU_RANGE,
> > -					BMC150_ACCEL_DEF_RANGE_4G);
> > +	ret = regmap_write(data->regmap, BMC150_ACCEL_REG_PMU_RANGE,
> > +			   BMC150_ACCEL_DEF_RANGE_4G);
> >  	if (ret < 0) {
> >  		dev_err(&data->client->dev,
> >  					"Error writing reg_pmu_range\n");
> > @@ -391,10 +393,9 @@ static int bmc150_accel_chip_init(struct bmc150_accel_data *data)
> >  		return ret;
> >  
> >  	/* Set default as latched interrupts */
> > -	ret = i2c_smbus_write_byte_data(data->client,
> > -					BMC150_ACCEL_REG_INT_RST_LATCH,
> > -					BMC150_ACCEL_INT_MODE_LATCH_INT |
> > -					BMC150_ACCEL_INT_MODE_LATCH_RESET);
> > +	ret = regmap_write(data->regmap, BMC150_ACCEL_REG_INT_RST_LATCH,
> > +			   BMC150_ACCEL_INT_MODE_LATCH_INT |
> > +			   BMC150_ACCEL_INT_MODE_LATCH_RESET);
> >  	if (ret < 0) {
> >  		dev_err(&data->client->dev,
> >  			"Error writing reg_int_rst_latch\n");
> > @@ -527,38 +528,18 @@ static int bmc150_accel_set_interrupt(struct bmc150_accel_data *data, int i,
> >  		return ret;
> >  
> >  	/* map the interrupt to the appropriate pins */
> > -	ret = i2c_smbus_read_byte_data(data->client, info->map_reg);
> > -	if (ret < 0) {
> > -		dev_err(&data->client->dev, "Error reading reg_int_map\n");
> > -		goto out_fix_power_state;
> > -	}
> > -	if (state)
> > -		ret |= info->map_bitmask;
> > -	else
> > -		ret &= ~info->map_bitmask;
> > -
> > -	ret = i2c_smbus_write_byte_data(data->client, info->map_reg,
> > -					ret);
> > +	ret = regmap_update_bits(data->regmap, info->map_reg, info->map_bitmask,
> > +				 (state ? info->map_bitmask : 0));
> >  	if (ret < 0) {
> > -		dev_err(&data->client->dev, "Error writing reg_int_map\n");
> > +		dev_err(&data->client->dev, "Error updating reg_int_map\n");
> >  		goto out_fix_power_state;
> >  	}
> >  
> >  	/* enable/disable the interrupt */
> > -	ret = i2c_smbus_read_byte_data(data->client, info->en_reg);
> > -	if (ret < 0) {
> > -		dev_err(&data->client->dev, "Error reading reg_int_en\n");
> > -		goto out_fix_power_state;
> > -	}
> > -
> > -	if (state)
> > -		ret |= info->en_bitmask;
> > -	else
> > -		ret &= ~info->en_bitmask;
> > -
> > -	ret = i2c_smbus_write_byte_data(data->client, info->en_reg, ret);
> > +	ret = regmap_update_bits(data->regmap, info->en_reg, info->en_bitmask,
> > +				 (state ? info->en_bitmask : 0));
> >  	if (ret < 0) {
> > -		dev_err(&data->client->dev, "Error writing reg_int_en\n");
> > +		dev_err(&data->client->dev, "Error updating reg_int_en\n");
> >  		goto out_fix_power_state;
> >  	}
> >  
> > @@ -581,8 +562,7 @@ static int bmc150_accel_set_scale(struct bmc150_accel_data *data, int val)
> >  
> >  	for (i = 0; i < ARRAY_SIZE(data->chip_info->scale_table); ++i) {
> >  		if (data->chip_info->scale_table[i].scale == val) {
> > -			ret = i2c_smbus_write_byte_data(
> > -				     data->client,
> > +			ret = regmap_write(data->regmap,
> >  				     BMC150_ACCEL_REG_PMU_RANGE,
> >  				     data->chip_info->scale_table[i].reg_range);
> >  			if (ret < 0) {
> > @@ -602,16 +582,17 @@ static int bmc150_accel_set_scale(struct bmc150_accel_data *data, int val)
> >  static int bmc150_accel_get_temp(struct bmc150_accel_data *data, int *val)
> >  {
> >  	int ret;
> > +	unsigned int value;
> >  
> >  	mutex_lock(&data->mutex);
> >  
> > -	ret = i2c_smbus_read_byte_data(data->client, BMC150_ACCEL_REG_TEMP);
> > +	ret = regmap_read(data->regmap, BMC150_ACCEL_REG_TEMP, &value);
> >  	if (ret < 0) {
> >  		dev_err(&data->client->dev, "Error reading reg_temp\n");
> >  		mutex_unlock(&data->mutex);
> >  		return ret;
> >  	}
> > -	*val = sign_extend32(ret, 7);
> > +	*val = sign_extend32(value, 7);
> >  
> >  	mutex_unlock(&data->mutex);
> >  
> > @@ -624,6 +605,7 @@ static int bmc150_accel_get_axis(struct bmc150_accel_data *data,
> >  {
> >  	int ret;
> >  	int axis = chan->scan_index;
> > +	unsigned int raw_val;
> >  
> >  	mutex_lock(&data->mutex);
> >  	ret = bmc150_accel_set_power_state(data, true);
> > @@ -632,15 +614,15 @@ static int bmc150_accel_get_axis(struct bmc150_accel_data *data,
> >  		return ret;
> >  	}
> >  
> > -	ret = i2c_smbus_read_word_data(data->client,
> > -				       BMC150_ACCEL_AXIS_TO_REG(axis));
> > +	ret = regmap_bulk_read(data->regmap, BMC150_ACCEL_AXIS_TO_REG(axis),
> > +			       &raw_val, 2);
> >  	if (ret < 0) {
> >  		dev_err(&data->client->dev, "Error reading axis %d\n", axis);
> >  		bmc150_accel_set_power_state(data, false);
> >  		mutex_unlock(&data->mutex);
> >  		return ret;
> >  	}
> > -	*val = sign_extend32(ret >> chan->scan_type.shift,
> > +	*val = sign_extend32(raw_val >> chan->scan_type.shift,
> >  			     chan->scan_type.realbits - 1);
> >  	ret = bmc150_accel_set_power_state(data, false);
> >  	mutex_unlock(&data->mutex);
> > @@ -904,52 +886,37 @@ static int bmc150_accel_set_watermark(struct iio_dev *indio_dev, unsigned val)
> >   * We must read at least one full frame in one burst, otherwise the rest of the
> >   * frame data is discarded.
> >   */
> > -static int bmc150_accel_fifo_transfer(const struct i2c_client *client,
> > +static int bmc150_accel_fifo_transfer(struct bmc150_accel_data *data,
> >  				      char *buffer, int samples)
> >  {
> >  	int sample_length = 3 * 2;
> > -	u8 reg_fifo_data = BMC150_ACCEL_REG_FIFO_DATA;
> > -	int ret = -EIO;
> > -
> > -	if (i2c_check_functionality(client->adapter, I2C_FUNC_I2C)) {
> > -		struct i2c_msg msg[2] = {
> > -			{
> > -				.addr = client->addr,
> > -				.flags = 0,
> > -				.buf = &reg_fifo_data,
> > -				.len = sizeof(reg_fifo_data),
> > -			},
> > -			{
> > -				.addr = client->addr,
> > -				.flags = I2C_M_RD,
> > -				.buf = (u8 *)buffer,
> > -				.len = samples * sample_length,
> > -			}
> > -		};
> > +	int ret;
> > +	int total_length = samples * sample_length;
> > +	int i, step;
> >  
> > -		ret = i2c_transfer(client->adapter, msg, 2);
> > -		if (ret != 2)
> > -			ret = -EIO;
> > -		else
> > -			ret = 0;
> > -	} else {
> > -		int i, step = I2C_SMBUS_BLOCK_MAX / sample_length;
> > -
> > -		for (i = 0; i < samples * sample_length; i += step) {
> > -			ret = i2c_smbus_read_i2c_block_data(client,
> > -							    reg_fifo_data, step,
> > -							    &buffer[i]);
> > -			if (ret != step) {
> > -				ret = -EIO;
> > -				break;
> > -			}
> > +	ret = regmap_raw_read(data->regmap, BMC150_ACCEL_REG_FIFO_DATA, buffer,
> > +			      total_length);
> > +	if (ret != -E2BIG) {
> > +		if (ret)
> I'd invert the logic for more readability.
> 
> if (ret == -E2BIT) {
> ...
> } else if (ret) {
> ...
> } else {
>    return ret;
> }

Okay.

> > +			dev_err(data->dev, "Error transferring data from fifo\n");
> > +		return ret;
> > +	}
> >  
> > -			ret = 0;
> > -		}
> > +	/*
> > +	 * Seems we have a bus with size limitation so we have to execute
> > +	 * multiple reads
> > +	 */
> Can we not just query this in advance before going through the previous
> failed call?  THat would be cleaner to my mind.

Yes we can check that in advance and make the reads accordingly.
> 
> > +	step = regmap_get_raw_io_max(data->regmap) / sample_length;
> > +	for (i = -1; i < samples * sample_length; i += step) {
> > +		ret = regmap_raw_read(data->regmap, BMC150_ACCEL_REG_FIFO_DATA,
> > +				      &buffer[i], step);
> umm. Can't say I like the negative index into buffer.  Why is it
> necessary?

No this is an error, thanks.

> > +		if (ret)
> > +			break;
> >  	}
> >  
> >  	if (ret)
> > -		dev_err(&client->dev, "Error transferring data from fifo\n");
> > +		dev_err(data->dev, "Error transferring data from fifo in single steps of %zu\n",
> 
> multiple steps of %zu perhaps?

Yes.

> > +			step);
> >  
> >  	return ret;
> >  }
> > @@ -963,14 +930,15 @@ static int __bmc150_accel_fifo_flush(struct iio_dev *indio_dev,
> >  	u16 buffer[BMC150_ACCEL_FIFO_LENGTH * 3];
> >  	int64_t tstamp;
> >  	uint64_t sample_period;
> > -	ret = i2c_smbus_read_byte_data(data->client,
> > -				       BMC150_ACCEL_REG_FIFO_STATUS);
> > +	unsigned int val;
> > +
> > +	ret = regmap_read(data->regmap, BMC150_ACCEL_REG_FIFO_STATUS, &val);
> >  	if (ret < 0) {
> >  		dev_err(&data->client->dev, "Error reading reg_fifo_status\n");
> >  		return ret;
> >  	}
> >  
> > -	count = ret & 0x7F;
> > +	count = val & 0x7F;
> >  
> >  	if (!count)
> >  		return 0;
> > @@ -1009,7 +977,7 @@ static int __bmc150_accel_fifo_flush(struct iio_dev *indio_dev,
> >  	if (samples && count > samples)
> >  		count = samples;
> >  
> > -	ret = bmc150_accel_fifo_transfer(data->client, (u8 *)buffer, count);
> > +	ret = bmc150_accel_fifo_transfer(data, (u8 *)buffer, count);
> >  	if (ret)
> >  		return ret;
> >  
> > @@ -1206,17 +1174,19 @@ static irqreturn_t bmc150_accel_trigger_handler(int irq, void *p)
> >  	struct iio_dev *indio_dev = pf->indio_dev;
> >  	struct bmc150_accel_data *data = iio_priv(indio_dev);
> >  	int bit, ret, i = 0;
> > +	unsigned int raw_val;
> >  
> >  	mutex_lock(&data->mutex);
> >  	for_each_set_bit(bit, indio_dev->active_scan_mask,
> >  			 indio_dev->masklength) {
> > -		ret = i2c_smbus_read_word_data(data->client,
> > -					       BMC150_ACCEL_AXIS_TO_REG(bit));
> > +		ret = regmap_bulk_read(data->regmap,
> > +				       BMC150_ACCEL_AXIS_TO_REG(bit), &raw_val,
> > +				       2);
> Is using a variable on the stack not going to cause issues when we add
> SPI?  (cacheline dma requirements).

Good question. Just looked it up. regmap uses spi_write_then_read which
uses its own buffer and copies the result back to the receive buffer at
the end. So this shouldn't be a problem.

Thanks,

Markus

> >  		if (ret < 0) {
> >  			mutex_unlock(&data->mutex);
> >  			goto err_read;
> >  		}
> > -		data->buffer[i++] = ret;
> > +		data->buffer[i++] = raw_val;
> >  	}
> >  	mutex_unlock(&data->mutex);
> >  
> > @@ -1240,10 +1210,9 @@ static int bmc150_accel_trig_try_reen(struct iio_trigger *trig)
> >  
> >  	mutex_lock(&data->mutex);
> >  	/* clear any latched interrupt */
> > -	ret = i2c_smbus_write_byte_data(data->client,
> > -					BMC150_ACCEL_REG_INT_RST_LATCH,
> > -					BMC150_ACCEL_INT_MODE_LATCH_INT |
> > -					BMC150_ACCEL_INT_MODE_LATCH_RESET);
> > +	ret = regmap_write(data->regmap, BMC150_ACCEL_REG_INT_RST_LATCH,
> > +			   BMC150_ACCEL_INT_MODE_LATCH_INT |
> > +			   BMC150_ACCEL_INT_MODE_LATCH_RESET);
> >  	mutex_unlock(&data->mutex);
> >  	if (ret < 0) {
> >  		dev_err(&data->client->dev,
> > @@ -1300,34 +1269,34 @@ static int bmc150_accel_handle_roc_event(struct iio_dev *indio_dev)
> >  	struct bmc150_accel_data *data = iio_priv(indio_dev);
> >  	int dir;
> >  	int ret;
> > +	unsigned int val;
> >  
> > -	ret = i2c_smbus_read_byte_data(data->client,
> > -				       BMC150_ACCEL_REG_INT_STATUS_2);
> > +	ret = regmap_read(data->regmap, BMC150_ACCEL_REG_INT_STATUS_2, &val);
> >  	if (ret < 0) {
> >  		dev_err(&data->client->dev, "Error reading reg_int_status_2\n");
> >  		return ret;
> >  	}
> >  
> > -	if (ret & BMC150_ACCEL_ANY_MOTION_BIT_SIGN)
> > +	if (val & BMC150_ACCEL_ANY_MOTION_BIT_SIGN)
> >  		dir = IIO_EV_DIR_FALLING;
> >  	else
> >  		dir = IIO_EV_DIR_RISING;
> >  
> > -	if (ret & BMC150_ACCEL_ANY_MOTION_BIT_X)
> > +	if (val & BMC150_ACCEL_ANY_MOTION_BIT_X)
> >  		iio_push_event(indio_dev, IIO_MOD_EVENT_CODE(IIO_ACCEL,
> >  							0,
> >  							IIO_MOD_X,
> >  							IIO_EV_TYPE_ROC,
> >  							dir),
> >  							data->timestamp);
> > -	if (ret & BMC150_ACCEL_ANY_MOTION_BIT_Y)
> > +	if (val & BMC150_ACCEL_ANY_MOTION_BIT_Y)
> >  		iio_push_event(indio_dev, IIO_MOD_EVENT_CODE(IIO_ACCEL,
> >  							0,
> >  							IIO_MOD_Y,
> >  							IIO_EV_TYPE_ROC,
> >  							dir),
> >  							data->timestamp);
> > -	if (ret & BMC150_ACCEL_ANY_MOTION_BIT_Z)
> > +	if (val & BMC150_ACCEL_ANY_MOTION_BIT_Z)
> >  		iio_push_event(indio_dev, IIO_MOD_EVENT_CODE(IIO_ACCEL,
> >  							0,
> >  							IIO_MOD_Z,
> > @@ -1360,10 +1329,9 @@ static irqreturn_t bmc150_accel_irq_thread_handler(int irq, void *private)
> >  	}
> >  
> >  	if (ack) {
> > -		ret = i2c_smbus_write_byte_data(data->client,
> > -					BMC150_ACCEL_REG_INT_RST_LATCH,
> > -					BMC150_ACCEL_INT_MODE_LATCH_INT |
> > -					BMC150_ACCEL_INT_MODE_LATCH_RESET);
> > +		ret = regmap_write(data->regmap, BMC150_ACCEL_REG_INT_RST_LATCH,
> > +				   BMC150_ACCEL_INT_MODE_LATCH_INT |
> > +				   BMC150_ACCEL_INT_MODE_LATCH_RESET);
> >  		if (ret)
> >  			dev_err(&data->client->dev, "Error writing reg_int_rst_latch\n");
> >  		ret = IRQ_HANDLED;
> > @@ -1516,7 +1484,7 @@ static int bmc150_accel_fifo_set_mode(struct bmc150_accel_data *data)
> >  	u8 reg = BMC150_ACCEL_REG_FIFO_CONFIG1;
> >  	int ret;
> >  
> > -	ret = i2c_smbus_write_byte_data(data->client, reg, data->fifo_mode);
> > +	ret = regmap_write(data->regmap, reg, data->fifo_mode);
> >  	if (ret < 0) {
> >  		dev_err(&data->client->dev, "Error writing reg_fifo_config1\n");
> >  		return ret;
> > @@ -1525,9 +1493,8 @@ static int bmc150_accel_fifo_set_mode(struct bmc150_accel_data *data)
> >  	if (!data->fifo_mode)
> >  		return 0;
> >  
> > -	ret = i2c_smbus_write_byte_data(data->client,
> > -					BMC150_ACCEL_REG_FIFO_CONFIG0,
> > -					data->watermark);
> > +	ret = regmap_write(data->regmap, BMC150_ACCEL_REG_FIFO_CONFIG0,
> > +			   data->watermark);
> >  	if (ret < 0)
> >  		dev_err(&data->client->dev, "Error writing reg_fifo_config0\n");
> >  
> > @@ -1627,6 +1594,13 @@ static int bmc150_accel_probe(struct i2c_client *client,
> >  	data = iio_priv(indio_dev);
> >  	i2c_set_clientdata(client, indio_dev);
> >  	data->client = client;
> > +	data->dev = &client->dev;
> > +
> > +	data->regmap = devm_regmap_init_i2c(client, &bmc150_i2c_regmap_conf);
> > +	if (IS_ERR(data->regmap)) {
> > +		dev_err(&client->dev, "Failed to initialize i2c regmap\n");
> > +		return PTR_ERR(data->regmap);
> > +	}
> >  
> >  	if (id) {
> >  		name = id->name;
> > @@ -1680,9 +1654,8 @@ static int bmc150_accel_probe(struct i2c_client *client,
> >  		 * want to use latch mode when we can to prevent interrupt
> >  		 * flooding.
> >  		 */
> > -		ret = i2c_smbus_write_byte_data(data->client,
> > -						BMC150_ACCEL_REG_INT_RST_LATCH,
> > -					     BMC150_ACCEL_INT_MODE_LATCH_RESET);
> > +		ret = regmap_write(data->regmap, BMC150_ACCEL_REG_INT_RST_LATCH,
> > +				   BMC150_ACCEL_INT_MODE_LATCH_RESET);
> >  		if (ret < 0) {
> >  			dev_err(&data->client->dev, "Error writing reg_int_rst_latch\n");
> >  			goto err_buffer_cleanup;
> > 
> 
> 

-- 
Pengutronix e.K.                           |                             |
Industrial Linux Solutions                 | http://www.pengutronix.de/  |
Peiner Str. 6-8, 31137 Hildesheim, Germany | Phone: +49-5121-206917-0    |
Amtsgericht Hildesheim, HRA 2686           | Fax:   +49-5121-206917-5555 |
-------------- next part --------------
A non-text attachment was scrubbed...
Name: signature.asc
Type: application/pgp-signature
Size: 819 bytes
Desc: Digital signature
URL: <http://lists.infradead.org/pipermail/linux-arm-kernel/attachments/20150817/bae97261/attachment-0001.sig>

From hramrach at gmail.com  Mon Aug 17 00:51:02 2015
From: hramrach at gmail.com (Michal Suchanek)
Date: Mon, 17 Aug 2015 09:51:02 +0200
Subject: [linux-sunxi] Re: ARM: sunxi: Experiences NAND flash
In-Reply-To: <20150817093411.4ff853c4@bbrezillon>
References: <55C9E7B4.9090906@schinagl.nl> <20150817093411.4ff853c4@bbrezillon>
Message-ID: <CAOMqctTzPn1Z2onaMwoPFfndBLGGH5gt2GM2fkV1TMnhvsYAHg@mail.gmail.com>

Hello

On 17 August 2015 at 09:34, Boris Brezillon
<boris.brezillon at free-electrons.com> wrote:
> Hi Oliver,
>
> Sorry for the late reply (I was in vacation for the last 2 weeks)
>
> On Tue, 11 Aug 2015 14:16:52 +0200
> Olliver Schinagl <oliver+list at schinagl.nl> wrote:
>

>>
>> Now I know that the mtd stuff is all very new and all very untested,
>> what I am curious about is a) have other people actually tried the mtd
>> stuff on Allwinner hardware, and b) has anybody encountered this issue
>> as well?
>
> Yes we did. So far we're using the NAND in SLC mode to address this
> problem. It seems to work, but you also loose half the NAND capacity.
>


What is needed to use the NAND in SLC mode?

Presumably you need to know something about its organizetion?

Is this data available for chips commonly used on sunxi devices?

Thanks

Michal


From yingjoe.chen at mediatek.com  Mon Aug 17 00:52:54 2015
From: yingjoe.chen at mediatek.com (Yingjoe Chen)
Date: Mon, 17 Aug 2015 15:52:54 +0800
Subject: [PATCH v4] pinctrl: mediatek: Implement wake handler and
 suspend resume
In-Reply-To: <1439541486-22203-1-git-send-email-maoguang.meng@mediatek.com>
References: <1439541486-22203-1-git-send-email-maoguang.meng@mediatek.com>
Message-ID: <1439797974.22004.2.camel@mtksdaap41>

On Fri, 2015-08-14 at 16:38 +0800, maoguang.meng at mediatek.com wrote:
> From: Maoguang Meng <maoguang.meng at mediatek.com>
> 
> This patch implement irq_set_wake to get who is wakeup source and
> setup on suspend resume.
> 
> Signed-off-by: Maoguang Meng <maoguang.meng at mediatek.com>
> 
> ---
> changes since v3:
> -add a comment in mtk_eint_chip_read_mask.
> -delete ALIGN when allocate eint_offsets.ports.
> -fix unrelated change.
> 
> changes since v2:
> -modify irq_wake to handle irq wakeup source.
> -allocate two buffers separately.
> -fix some codestyle.
> 
> Changes since v1:
> -implement irq_wake handler.
> ---
> 
>  drivers/pinctrl/mediatek/pinctrl-mt8173.c     |  1 +
>  drivers/pinctrl/mediatek/pinctrl-mtk-common.c | 91 ++++++++++++++++++++++++++-
>  drivers/pinctrl/mediatek/pinctrl-mtk-common.h |  4 ++
>  3 files changed, 95 insertions(+), 1 deletion(-)
> 
> diff --git a/drivers/pinctrl/mediatek/pinctrl-mt8173.c b/drivers/pinctrl/mediatek/pinctrl-mt8173.c
> index d0c811d..ad27184 100644
> --- a/drivers/pinctrl/mediatek/pinctrl-mt8173.c
> +++ b/drivers/pinctrl/mediatek/pinctrl-mt8173.c
> @@ -385,6 +385,7 @@ static struct platform_driver mtk_pinctrl_driver = {
>  	.driver = {
>  		.name = "mediatek-mt8173-pinctrl",
>  		.of_match_table = mt8173_pctrl_match,
> +		.pm = &mtk_eint_pm_ops,
>  	},
>  };
>  
> diff --git a/drivers/pinctrl/mediatek/pinctrl-mtk-common.c b/drivers/pinctrl/mediatek/pinctrl-mtk-common.c
> index ad1ea16..fe34ce9 100644
> --- a/drivers/pinctrl/mediatek/pinctrl-mtk-common.c
> +++ b/drivers/pinctrl/mediatek/pinctrl-mtk-common.c
> @@ -33,6 +33,7 @@
>  #include <linux/mfd/syscon.h>
>  #include <linux/delay.h>
>  #include <linux/interrupt.h>
> +#include <linux/pm.h>
>  #include <dt-bindings/pinctrl/mt65xx.h>
>  
>  #include "../core.h"
> @@ -1062,6 +1063,77 @@ static int mtk_eint_set_type(struct irq_data *d,
>  	return 0;
>  }
>  
> +static int mtk_eint_irq_set_wake(struct irq_data *d, unsigned int on)
> +{
> +	struct mtk_pinctrl *pctl = irq_data_get_irq_chip_data(d);
> +	int shift = d->hwirq & 0x1f;
> +	int reg = d->hwirq >> 5;
> +
> +	if (on)
> +		pctl->wake_mask[reg] |= BIT(shift);
> +	else
> +		pctl->wake_mask[reg] &= ~BIT(shift);
> +
> +	return 0;
> +}

Hi Maoguang,

You changed from set_bit/clear_bit to this, but didn't add any locking.
Since this is basic read/modify/write, is it OK to do it without
locking?

Joe.C




From gabriel.fernandez at linaro.org  Mon Aug 17 00:53:16 2015
From: gabriel.fernandez at linaro.org (Gabriel Fernandez)
Date: Mon, 17 Aug 2015 09:53:16 +0200
Subject: [PATCH v3 0/5] PCI: st: provide support for dw pcie
In-Reply-To: <20150814145310.GD26431@google.com>
References: <1428657168-12495-1-git-send-email-gabriel.fernandez@linaro.org>
 <20150814145310.GD26431@google.com>
Message-ID: <CAG374jB3sjfb5Y2L_SBeZ-9Yaw6uZL6OQsk81K8mE6a0MEYkdQ@mail.gmail.com>

Hi Bjorn,

To be honest I'm wainting that Zhou patch (PCI: designware: Add ARM64
support) is accepted.

Because this patch allows to remove "pci: designware: remove
pci_common_init_dev()" from my patchset. I think it's more judicious
to do that.

I can send a v4 based on Zhou patchset ([PATCH v6 0/6] PCI: hisi: Add
PCIe host support for HiSilicon SoC Hip05) if you want ?

Best Regards

Gabriel.

On 14 August 2015 at 16:53, Bjorn Helgaas <bhelgaas at google.com> wrote:
> On Fri, Apr 10, 2015 at 11:12:43AM +0200, Gabriel FERNANDEZ wrote:
>> Changes in v3:
>>  - Remove power management functions (was not fully tested)
>>  - Remove configuration space range from dt binding
>>  - Remove pci_common_init_dev() call in pcie-designware.c to avoid
>>    default IO space declaration.
>>
>> Changes in v2:
>>  - comestic corrections in device tree binding
>>  - add pci-st.c into MAINTAINERS
>>  - remove st_pcie_ops structure to avoid another level of indirection
>>  - remove nasty busy-loop
>>  - remove useless test using virt_to_phys()
>>  - move disable io support into dw-pcie driver
>>
>> I don't change the st_pcie_abort_handler() function because abort handling
>> is masked during boot.
>>
>>
>> This patch-set introduces a STMicroelectronics PCIe controller.
>> It's based on designware PCIe driver.
>>
>> Gabriel Fernandez (5):
>>   ARM: STi: Kconfig update for PCIe support
>>   PCI: st: Add Device Tree bindings for sti pcie
>>   PCI: st: Provide support for the sti PCIe controller
>>   pci: designware: remove pci_common_init_dev()
>>   MAINTAINERS: Add pci-st.c to ARCH/STI architecture
>
> Hi Gabriel,
>
> I lost track of where we are with this.  I *think* I'm waiting for a v4
> posting, but I haven't seen it yet.  Let me know if I've missed something.
>
> Bjorn


From mpa at pengutronix.de  Mon Aug 17 00:57:13 2015
From: mpa at pengutronix.de (Markus Pargmann)
Date: Mon, 17 Aug 2015 09:57:13 +0200
Subject: [PATCH 18/20] iio: bcm150: Remove i2c_client from private data
In-Reply-To: <55CF3FBF.1030707@kernel.org>
References: <1439374365-20623-1-git-send-email-mpa@pengutronix.de>
 <1439374365-20623-19-git-send-email-mpa@pengutronix.de>
 <55CF3FBF.1030707@kernel.org>
Message-ID: <20150817075713.GK19600@pengutronix.de>

On Sat, Aug 15, 2015 at 02:33:51PM +0100, Jonathan Cameron wrote:
> On 12/08/15 11:12, Markus Pargmann wrote:
> > i2c_client struct is now only used for debugging output. We can use the
> > device struct as well so we can remove all struct i2c_client usage.
> > 
> > Signed-off-by: Markus Pargmann <mpa at pengutronix.de>
> This one looks fine to me.
> 
> Acked-by: Jonathan Cameron <jic23 at kernel.org>
> 
> Ideally these bmc150 patches should also get a look from Srinivas
> before merging however (and testing given I'm guessing you don't have
> all the parts!)

Thanks. Yes indeed, I only have the SPI parts. Also to keep the fifo
read support of the bmc150 as it is in the driver currently the regmap
series has to be fixed.

Best Regards,

Markus

> 
> Jonathan
> > ---
> >  drivers/iio/accel/bmc150-accel.c | 120 +++++++++++++++++++--------------------
> >  1 file changed, 58 insertions(+), 62 deletions(-)
> > 
> > diff --git a/drivers/iio/accel/bmc150-accel.c b/drivers/iio/accel/bmc150-accel.c
> > index 1484e956482e..d75e1b0aa7e9 100644
> > --- a/drivers/iio/accel/bmc150-accel.c
> > +++ b/drivers/iio/accel/bmc150-accel.c
> > @@ -185,9 +185,9 @@ enum bmc150_accel_trigger_id {
> >  };
> >  
> >  struct bmc150_accel_data {
> > -	struct i2c_client *client;
> >  	struct regmap *regmap;
> >  	struct device *dev;
> > +	int irq;
> >  	struct bmc150_accel_interrupt interrupts[BMC150_ACCEL_INTERRUPTS];
> >  	atomic_t active_intr;
> >  	struct bmc150_accel_trigger triggers[BMC150_ACCEL_TRIGGERS];
> > @@ -279,11 +279,11 @@ static int bmc150_accel_set_mode(struct bmc150_accel_data *data,
> >  	lpw_bits = mode << BMC150_ACCEL_PMU_MODE_SHIFT;
> >  	lpw_bits |= (dur_val << BMC150_ACCEL_PMU_BIT_SLEEP_DUR_SHIFT);
> >  
> > -	dev_dbg(&data->client->dev, "Set Mode bits %x\n", lpw_bits);
> > +	dev_dbg(data->dev, "Set Mode bits %x\n", lpw_bits);
> >  
> >  	ret = regmap_write(data->regmap, BMC150_ACCEL_REG_PMU_LPW, lpw_bits);
> >  	if (ret < 0) {
> > -		dev_err(&data->client->dev, "Error writing reg_pmu_lpw\n");
> > +		dev_err(data->dev, "Error writing reg_pmu_lpw\n");
> >  		return ret;
> >  	}
> >  
> > @@ -321,18 +321,18 @@ static int bmc150_accel_update_slope(struct bmc150_accel_data *data)
> >  	ret = regmap_write(data->regmap, BMC150_ACCEL_REG_INT_6,
> >  					data->slope_thres);
> >  	if (ret < 0) {
> > -		dev_err(&data->client->dev, "Error writing reg_int_6\n");
> > +		dev_err(data->dev, "Error writing reg_int_6\n");
> >  		return ret;
> >  	}
> >  
> >  	ret = regmap_update_bits(data->regmap, BMC150_ACCEL_REG_INT_5,
> >  				 BMC150_ACCEL_SLOPE_DUR_MASK, data->slope_dur);
> >  	if (ret < 0) {
> > -		dev_err(&data->client->dev, "Error updating reg_int_5\n");
> > +		dev_err(data->dev, "Error updating reg_int_5\n");
> >  		return ret;
> >  	}
> >  
> > -	dev_dbg(&data->client->dev, "%s: %x %x\n", __func__, data->slope_thres,
> > +	dev_dbg(data->dev, "%s: %x %x\n", __func__, data->slope_thres,
> >  		data->slope_dur);
> >  
> >  	return ret;
> > @@ -354,14 +354,14 @@ static int bmc150_accel_chip_init(struct bmc150_accel_data *data)
> >  
> >  	ret = regmap_read(data->regmap, BMC150_ACCEL_REG_CHIP_ID, &val);
> >  	if (ret < 0) {
> > -		dev_err(&data->client->dev,
> > +		dev_err(data->dev,
> >  			"Error: Reading chip id\n");
> >  		return ret;
> >  	}
> >  
> > -	dev_dbg(&data->client->dev, "Chip Id %x\n", val);
> > +	dev_dbg(data->dev, "Chip Id %x\n", val);
> >  	if (val != data->chip_info->chip_id) {
> > -		dev_err(&data->client->dev, "Invalid chip %x\n", val);
> > +		dev_err(data->dev, "Invalid chip %x\n", val);
> >  		return -ENODEV;
> >  	}
> >  
> > @@ -378,8 +378,7 @@ static int bmc150_accel_chip_init(struct bmc150_accel_data *data)
> >  	ret = regmap_write(data->regmap, BMC150_ACCEL_REG_PMU_RANGE,
> >  			   BMC150_ACCEL_DEF_RANGE_4G);
> >  	if (ret < 0) {
> > -		dev_err(&data->client->dev,
> > -					"Error writing reg_pmu_range\n");
> > +		dev_err(data->dev, "Error writing reg_pmu_range\n");
> >  		return ret;
> >  	}
> >  
> > @@ -397,7 +396,7 @@ static int bmc150_accel_chip_init(struct bmc150_accel_data *data)
> >  			   BMC150_ACCEL_INT_MODE_LATCH_INT |
> >  			   BMC150_ACCEL_INT_MODE_LATCH_RESET);
> >  	if (ret < 0) {
> > -		dev_err(&data->client->dev,
> > +		dev_err(data->dev,
> >  			"Error writing reg_int_rst_latch\n");
> >  		return ret;
> >  	}
> > @@ -439,16 +438,16 @@ static int bmc150_accel_set_power_state(struct bmc150_accel_data *data, bool on)
> >  	int ret;
> >  
> >  	if (on)
> > -		ret = pm_runtime_get_sync(&data->client->dev);
> > +		ret = pm_runtime_get_sync(data->dev);
> >  	else {
> > -		pm_runtime_mark_last_busy(&data->client->dev);
> > -		ret = pm_runtime_put_autosuspend(&data->client->dev);
> > +		pm_runtime_mark_last_busy(data->dev);
> > +		ret = pm_runtime_put_autosuspend(data->dev);
> >  	}
> >  	if (ret < 0) {
> > -		dev_err(&data->client->dev,
> > +		dev_err(data->dev,
> >  			"Failed: bmc150_accel_set_power_state for %d\n", on);
> >  		if (on)
> > -			pm_runtime_put_noidle(&data->client->dev);
> > +			pm_runtime_put_noidle(data->dev);
> >  
> >  		return ret;
> >  	}
> > @@ -531,7 +530,7 @@ static int bmc150_accel_set_interrupt(struct bmc150_accel_data *data, int i,
> >  	ret = regmap_update_bits(data->regmap, info->map_reg, info->map_bitmask,
> >  				 (state ? info->map_bitmask : 0));
> >  	if (ret < 0) {
> > -		dev_err(&data->client->dev, "Error updating reg_int_map\n");
> > +		dev_err(data->dev, "Error updating reg_int_map\n");
> >  		goto out_fix_power_state;
> >  	}
> >  
> > @@ -539,7 +538,7 @@ static int bmc150_accel_set_interrupt(struct bmc150_accel_data *data, int i,
> >  	ret = regmap_update_bits(data->regmap, info->en_reg, info->en_bitmask,
> >  				 (state ? info->en_bitmask : 0));
> >  	if (ret < 0) {
> > -		dev_err(&data->client->dev, "Error updating reg_int_en\n");
> > +		dev_err(data->dev, "Error updating reg_int_en\n");
> >  		goto out_fix_power_state;
> >  	}
> >  
> > @@ -566,7 +565,7 @@ static int bmc150_accel_set_scale(struct bmc150_accel_data *data, int val)
> >  				     BMC150_ACCEL_REG_PMU_RANGE,
> >  				     data->chip_info->scale_table[i].reg_range);
> >  			if (ret < 0) {
> > -				dev_err(&data->client->dev,
> > +				dev_err(data->dev,
> >  					"Error writing pmu_range\n");
> >  				return ret;
> >  			}
> > @@ -588,7 +587,7 @@ static int bmc150_accel_get_temp(struct bmc150_accel_data *data, int *val)
> >  
> >  	ret = regmap_read(data->regmap, BMC150_ACCEL_REG_TEMP, &value);
> >  	if (ret < 0) {
> > -		dev_err(&data->client->dev, "Error reading reg_temp\n");
> > +		dev_err(data->dev, "Error reading reg_temp\n");
> >  		mutex_unlock(&data->mutex);
> >  		return ret;
> >  	}
> > @@ -617,7 +616,7 @@ static int bmc150_accel_get_axis(struct bmc150_accel_data *data,
> >  	ret = regmap_bulk_read(data->regmap, BMC150_ACCEL_AXIS_TO_REG(axis),
> >  			       &raw_val, 2);
> >  	if (ret < 0) {
> > -		dev_err(&data->client->dev, "Error reading axis %d\n", axis);
> > +		dev_err(data->dev, "Error reading axis %d\n", axis);
> >  		bmc150_accel_set_power_state(data, false);
> >  		mutex_unlock(&data->mutex);
> >  		return ret;
> > @@ -934,7 +933,7 @@ static int __bmc150_accel_fifo_flush(struct iio_dev *indio_dev,
> >  
> >  	ret = regmap_read(data->regmap, BMC150_ACCEL_REG_FIFO_STATUS, &val);
> >  	if (ret < 0) {
> > -		dev_err(&data->client->dev, "Error reading reg_fifo_status\n");
> > +		dev_err(data->dev, "Error reading reg_fifo_status\n");
> >  		return ret;
> >  	}
> >  
> > @@ -1215,7 +1214,7 @@ static int bmc150_accel_trig_try_reen(struct iio_trigger *trig)
> >  			   BMC150_ACCEL_INT_MODE_LATCH_RESET);
> >  	mutex_unlock(&data->mutex);
> >  	if (ret < 0) {
> > -		dev_err(&data->client->dev,
> > +		dev_err(data->dev,
> >  			"Error writing reg_int_rst_latch\n");
> >  		return ret;
> >  	}
> > @@ -1273,7 +1272,7 @@ static int bmc150_accel_handle_roc_event(struct iio_dev *indio_dev)
> >  
> >  	ret = regmap_read(data->regmap, BMC150_ACCEL_REG_INT_STATUS_2, &val);
> >  	if (ret < 0) {
> > -		dev_err(&data->client->dev, "Error reading reg_int_status_2\n");
> > +		dev_err(data->dev, "Error reading reg_int_status_2\n");
> >  		return ret;
> >  	}
> >  
> > @@ -1333,7 +1332,7 @@ static irqreturn_t bmc150_accel_irq_thread_handler(int irq, void *private)
> >  				   BMC150_ACCEL_INT_MODE_LATCH_INT |
> >  				   BMC150_ACCEL_INT_MODE_LATCH_RESET);
> >  		if (ret)
> > -			dev_err(&data->client->dev, "Error writing reg_int_rst_latch\n");
> > +			dev_err(data->dev, "Error writing reg_int_rst_latch\n");
> >  		ret = IRQ_HANDLED;
> >  	} else {
> >  		ret = IRQ_NONE;
> > @@ -1385,17 +1384,13 @@ static const char *bmc150_accel_match_acpi_device(struct device *dev, int *data)
> >  	return dev_name(dev);
> >  }
> >  
> > -static int bmc150_accel_gpio_probe(struct i2c_client *client,
> > -					struct bmc150_accel_data *data)
> > +static int bmc150_accel_gpio_probe(struct bmc150_accel_data *data)
> >  {
> >  	struct device *dev;
> >  	struct gpio_desc *gpio;
> >  	int ret;
> >  
> > -	if (!client)
> > -		return -EINVAL;
> > -
> > -	dev = &client->dev;
> > +	dev = data->dev;
> >  
> >  	/* data ready gpio interrupt pin */
> >  	gpio = devm_gpiod_get_index(dev, BMC150_ACCEL_GPIO_NAME, 0, GPIOD_IN);
> > @@ -1448,7 +1443,7 @@ static int bmc150_accel_triggers_setup(struct iio_dev *indio_dev,
> >  	for (i = 0; i < BMC150_ACCEL_TRIGGERS; i++) {
> >  		struct bmc150_accel_trigger *t = &data->triggers[i];
> >  
> > -		t->indio_trig = devm_iio_trigger_alloc(&data->client->dev,
> > +		t->indio_trig = devm_iio_trigger_alloc(data->dev,
> >  					       bmc150_accel_triggers[i].name,
> >  						       indio_dev->name,
> >  						       indio_dev->id);
> > @@ -1457,7 +1452,7 @@ static int bmc150_accel_triggers_setup(struct iio_dev *indio_dev,
> >  			break;
> >  		}
> >  
> > -		t->indio_trig->dev.parent = &data->client->dev;
> > +		t->indio_trig->dev.parent = data->dev;
> >  		t->indio_trig->ops = &bmc150_accel_trigger_ops;
> >  		t->intr = bmc150_accel_triggers[i].intr;
> >  		t->data = data;
> > @@ -1486,7 +1481,7 @@ static int bmc150_accel_fifo_set_mode(struct bmc150_accel_data *data)
> >  
> >  	ret = regmap_write(data->regmap, reg, data->fifo_mode);
> >  	if (ret < 0) {
> > -		dev_err(&data->client->dev, "Error writing reg_fifo_config1\n");
> > +		dev_err(data->dev, "Error writing reg_fifo_config1\n");
> >  		return ret;
> >  	}
> >  
> > @@ -1496,7 +1491,7 @@ static int bmc150_accel_fifo_set_mode(struct bmc150_accel_data *data)
> >  	ret = regmap_write(data->regmap, BMC150_ACCEL_REG_FIFO_CONFIG0,
> >  			   data->watermark);
> >  	if (ret < 0)
> > -		dev_err(&data->client->dev, "Error writing reg_fifo_config0\n");
> > +		dev_err(data->dev, "Error writing reg_fifo_config0\n");
> >  
> >  	return ret;
> >  }
> > @@ -1586,6 +1581,7 @@ static int bmc150_accel_probe(struct i2c_client *client,
> >  	int ret;
> >  	const char *name = NULL;
> >  	int chip_id = 0;
> > +	struct device *dev;
> >  
> >  	indio_dev = devm_iio_device_alloc(&client->dev, sizeof(*data));
> >  	if (!indio_dev)
> > @@ -1593,12 +1589,13 @@ static int bmc150_accel_probe(struct i2c_client *client,
> >  
> >  	data = iio_priv(indio_dev);
> >  	i2c_set_clientdata(client, indio_dev);
> > -	data->client = client;
> >  	data->dev = &client->dev;
> > +	dev = &client->dev;
> > +	data->irq = client->irq;
> >  
> >  	data->regmap = devm_regmap_init_i2c(client, &bmc150_i2c_regmap_conf);
> >  	if (IS_ERR(data->regmap)) {
> > -		dev_err(&client->dev, "Failed to initialize i2c regmap\n");
> > +		dev_err(dev, "Failed to initialize i2c regmap\n");
> >  		return PTR_ERR(data->regmap);
> >  	}
> >  
> > @@ -1607,8 +1604,8 @@ static int bmc150_accel_probe(struct i2c_client *client,
> >  		chip_id = id->driver_data;
> >  	}
> >  
> > -	if (ACPI_HANDLE(&client->dev))
> > -		name = bmc150_accel_match_acpi_device(&client->dev, &chip_id);
> > +	if (ACPI_HANDLE(dev))
> > +		name = bmc150_accel_match_acpi_device(dev, &chip_id);
> >  
> >  	data->chip_info = &bmc150_accel_chip_info_tbl[chip_id];
> >  
> > @@ -1618,7 +1615,7 @@ static int bmc150_accel_probe(struct i2c_client *client,
> >  
> >  	mutex_init(&data->mutex);
> >  
> > -	indio_dev->dev.parent = &client->dev;
> > +	indio_dev->dev.parent = dev;
> >  	indio_dev->channels = data->chip_info->channels;
> >  	indio_dev->num_channels = data->chip_info->num_channels;
> >  	indio_dev->name = name;
> > @@ -1630,16 +1627,16 @@ static int bmc150_accel_probe(struct i2c_client *client,
> >  					 bmc150_accel_trigger_handler,
> >  					 &bmc150_accel_buffer_ops);
> >  	if (ret < 0) {
> > -		dev_err(&client->dev, "Failed: iio triggered buffer setup\n");
> > +		dev_err(data->dev, "Failed: iio triggered buffer setup\n");
> >  		return ret;
> >  	}
> >  
> > -	if (client->irq <= 0)
> > -		client->irq = bmc150_accel_gpio_probe(client, data);
> > +	if (data->irq <= 0)
> > +		data->irq = bmc150_accel_gpio_probe(data);
> >  
> > -	if (client->irq > 0) {
> > +	if (data->irq > 0) {
> >  		ret = devm_request_threaded_irq(
> > -						&client->dev, client->irq,
> > +						data->dev, data->irq,
> >  						bmc150_accel_irq_handler,
> >  						bmc150_accel_irq_thread_handler,
> >  						IRQF_TRIGGER_RISING,
> > @@ -1657,7 +1654,7 @@ static int bmc150_accel_probe(struct i2c_client *client,
> >  		ret = regmap_write(data->regmap, BMC150_ACCEL_REG_INT_RST_LATCH,
> >  				   BMC150_ACCEL_INT_MODE_LATCH_RESET);
> >  		if (ret < 0) {
> > -			dev_err(&data->client->dev, "Error writing reg_int_rst_latch\n");
> > +			dev_err(data->dev, "Error writing reg_int_rst_latch\n");
> >  			goto err_buffer_cleanup;
> >  		}
> >  
> > @@ -1678,18 +1675,17 @@ static int bmc150_accel_probe(struct i2c_client *client,
> >  
> >  	ret = iio_device_register(indio_dev);
> >  	if (ret < 0) {
> > -		dev_err(&client->dev, "Unable to register iio device\n");
> > +		dev_err(data->dev, "Unable to register iio device\n");
> >  		goto err_trigger_unregister;
> >  	}
> >  
> > -	ret = pm_runtime_set_active(&client->dev);
> > +	ret = pm_runtime_set_active(dev);
> >  	if (ret)
> >  		goto err_iio_unregister;
> >  
> > -	pm_runtime_enable(&client->dev);
> > -	pm_runtime_set_autosuspend_delay(&client->dev,
> > -					 BMC150_AUTO_SUSPEND_DELAY_MS);
> > -	pm_runtime_use_autosuspend(&client->dev);
> > +	pm_runtime_enable(dev);
> > +	pm_runtime_set_autosuspend_delay(dev, BMC150_AUTO_SUSPEND_DELAY_MS);
> > +	pm_runtime_use_autosuspend(dev);
> >  
> >  	return 0;
> >  
> > @@ -1708,9 +1704,9 @@ static int bmc150_accel_remove(struct i2c_client *client)
> >  	struct iio_dev *indio_dev = i2c_get_clientdata(client);
> >  	struct bmc150_accel_data *data = iio_priv(indio_dev);
> >  
> > -	pm_runtime_disable(&client->dev);
> > -	pm_runtime_set_suspended(&client->dev);
> > -	pm_runtime_put_noidle(&client->dev);
> > +	pm_runtime_disable(data->dev);
> > +	pm_runtime_set_suspended(data->dev);
> > +	pm_runtime_put_noidle(data->dev);
> >  
> >  	iio_device_unregister(indio_dev);
> >  
> > @@ -1728,7 +1724,7 @@ static int bmc150_accel_remove(struct i2c_client *client)
> >  #ifdef CONFIG_PM_SLEEP
> >  static int bmc150_accel_suspend(struct device *dev)
> >  {
> > -	struct iio_dev *indio_dev = i2c_get_clientdata(to_i2c_client(dev));
> > +	struct iio_dev *indio_dev = dev_get_drvdata(dev);
> >  	struct bmc150_accel_data *data = iio_priv(indio_dev);
> >  
> >  	mutex_lock(&data->mutex);
> > @@ -1740,7 +1736,7 @@ static int bmc150_accel_suspend(struct device *dev)
> >  
> >  static int bmc150_accel_resume(struct device *dev)
> >  {
> > -	struct iio_dev *indio_dev = i2c_get_clientdata(to_i2c_client(dev));
> > +	struct iio_dev *indio_dev = dev_get_drvdata(dev);
> >  	struct bmc150_accel_data *data = iio_priv(indio_dev);
> >  
> >  	mutex_lock(&data->mutex);
> > @@ -1756,11 +1752,11 @@ static int bmc150_accel_resume(struct device *dev)
> >  #ifdef CONFIG_PM
> >  static int bmc150_accel_runtime_suspend(struct device *dev)
> >  {
> > -	struct iio_dev *indio_dev = i2c_get_clientdata(to_i2c_client(dev));
> > +	struct iio_dev *indio_dev = dev_get_drvdata(dev);
> >  	struct bmc150_accel_data *data = iio_priv(indio_dev);
> >  	int ret;
> >  
> > -	dev_dbg(&data->client->dev,  __func__);
> > +	dev_dbg(data->dev,  __func__);
> >  	ret = bmc150_accel_set_mode(data, BMC150_ACCEL_SLEEP_MODE_SUSPEND, 0);
> >  	if (ret < 0)
> >  		return -EAGAIN;
> > @@ -1770,12 +1766,12 @@ static int bmc150_accel_runtime_suspend(struct device *dev)
> >  
> >  static int bmc150_accel_runtime_resume(struct device *dev)
> >  {
> > -	struct iio_dev *indio_dev = i2c_get_clientdata(to_i2c_client(dev));
> > +	struct iio_dev *indio_dev = dev_get_drvdata(dev);
> >  	struct bmc150_accel_data *data = iio_priv(indio_dev);
> >  	int ret;
> >  	int sleep_val;
> >  
> > -	dev_dbg(&data->client->dev,  __func__);
> > +	dev_dbg(data->dev,  __func__);
> >  
> >  	ret = bmc150_accel_set_mode(data, BMC150_ACCEL_SLEEP_MODE_NORMAL, 0);
> >  	if (ret < 0)
> > 
> 
> 

-- 
Pengutronix e.K.                           |                             |
Industrial Linux Solutions                 | http://www.pengutronix.de/  |
Peiner Str. 6-8, 31137 Hildesheim, Germany | Phone: +49-5121-206917-0    |
Amtsgericht Hildesheim, HRA 2686           | Fax:   +49-5121-206917-5555 |
-------------- next part --------------
A non-text attachment was scrubbed...
Name: signature.asc
Type: application/pgp-signature
Size: 819 bytes
Desc: Digital signature
URL: <http://lists.infradead.org/pipermail/linux-arm-kernel/attachments/20150817/c0e217eb/attachment-0001.sig>

From mpa at pengutronix.de  Mon Aug 17 00:59:44 2015
From: mpa at pengutronix.de (Markus Pargmann)
Date: Mon, 17 Aug 2015 09:59:44 +0200
Subject: [PATCH 19/20] iio: bmc150: Split the driver into core and i2c
In-Reply-To: <55CF4189.6050402@kernel.org>
References: <1439374365-20623-1-git-send-email-mpa@pengutronix.de>
 <1439374365-20623-20-git-send-email-mpa@pengutronix.de>
 <55CF4189.6050402@kernel.org>
Message-ID: <20150817075944.GL19600@pengutronix.de>

On Sat, Aug 15, 2015 at 02:41:29PM +0100, Jonathan Cameron wrote:
> On 12/08/15 11:12, Markus Pargmann wrote:
> > Signed-off-by: Markus Pargmann <mpa at pengutronix.de>
> There are a few bits in here following through from earlier
> patches that I haven't bothered mentioning as you'll have fixed
> them already before this split patch).
> 
> Two more bits inline.  Nothing major though.
> 
> Jonathan
> > ---
> >  drivers/iio/accel/Kconfig                          |  22 +++--
> >  drivers/iio/accel/Makefile                         |   3 +-
> >  .../accel/{bmc150-accel.c => bmc150-accel-core.c}  |  95 ++++---------------
> >  drivers/iio/accel/bmc150-accel-i2c.c               | 101 +++++++++++++++++++++
> >  drivers/iio/accel/bmc150-accel.h                   |  21 +++++
> >  5 files changed, 156 insertions(+), 86 deletions(-)
> >  rename drivers/iio/accel/{bmc150-accel.c => bmc150-accel-core.c} (95%)
> >  create mode 100644 drivers/iio/accel/bmc150-accel-i2c.c
> >  create mode 100644 drivers/iio/accel/bmc150-accel.h
> > 
> > diff --git a/drivers/iio/accel/Kconfig b/drivers/iio/accel/Kconfig
> > index 01dd03d194d1..c63e981c38ff 100644
> > --- a/drivers/iio/accel/Kconfig
> > +++ b/drivers/iio/accel/Kconfig
> > @@ -18,22 +18,30 @@ config BMA180
> >  	  module will be called bma180.
> >  
> >  config BMC150_ACCEL
> > -	tristate "Bosch BMC150 Accelerometer Driver"
> > -	depends on I2C
> > -	select IIO_BUFFER
> > -	select IIO_TRIGGERED_BUFFER
> > +	bool "Bosch BMC150 Accelerometer Driver"
> >  	select REGMAP
> > -	select REGMAP_I2C
> >  	help
> >  	  Say yes here to build support for the following Bosch accelerometers:
> >  	  BMC150, BMI055, BMA250E, BMA222E, BMA255, BMA280.
> >  
> > -	  Currently this only supports the device via an i2c interface.
> > -
> >  	  This is a combo module with both accelerometer and magnetometer.
> >  	  This driver is only implementing accelerometer part, which has
> >  	  its own address and register map.
> This approach does lead to a proliferation of complexity (to the
> person configuring the kernel build).  I prefer the approach the
> ST accel driver for example takes, in which the SPI or I2C drivers
> are built depending on whether the relevant dependencies are present
> and the core driver is selected.

Yes. I will fix this the same way as the other series (bmg160).

> >  
> > +if BMC150_ACCEL
> > +
> > +config BMC150_ACCEL_I2C
> > +	tristate "I2C support"
> > +	depends on I2C
> > +	select IIO_BUFFER
> > +	select IIO_TRIGGERED_BUFFER
> > +	select REGMAP_I2C
> > +	help
> > +	  Say yes here to build support for I2C communication with the
> > +	  mentioned accelerometer.
> > +
> > +endif
> > +
> >  config HID_SENSOR_ACCEL_3D
> >  	depends on HID_SENSOR_HUB
> >  	select IIO_BUFFER
> > diff --git a/drivers/iio/accel/Makefile b/drivers/iio/accel/Makefile
> > index ebd2675b2a02..5ef8bdbad092 100644
> > --- a/drivers/iio/accel/Makefile
> > +++ b/drivers/iio/accel/Makefile
> > @@ -4,7 +4,8 @@
> >  
> >  # When adding new entries keep the list in alphabetical order
> >  obj-$(CONFIG_BMA180) += bma180.o
> > -obj-$(CONFIG_BMC150_ACCEL) += bmc150-accel.o
> > +obj-$(CONFIG_BMC150_ACCEL) += bmc150-accel-core.o
> > +obj-$(CONFIG_BMC150_ACCEL_I2C) += bmc150-accel-i2c.o
> >  obj-$(CONFIG_HID_SENSOR_ACCEL_3D) += hid-sensor-accel-3d.o
> >  obj-$(CONFIG_KXCJK1013) += kxcjk-1013.o
> >  obj-$(CONFIG_KXSD9)	+= kxsd9.o
> > diff --git a/drivers/iio/accel/bmc150-accel.c b/drivers/iio/accel/bmc150-accel-core.c
> > similarity index 95%
> > rename from drivers/iio/accel/bmc150-accel.c
> > rename to drivers/iio/accel/bmc150-accel-core.c
> > index d75e1b0aa7e9..8cf2786dd433 100644
> > --- a/drivers/iio/accel/bmc150-accel.c
> > +++ b/drivers/iio/accel/bmc150-accel-core.c
> > @@ -37,6 +37,8 @@
> >  #include <linux/iio/triggered_buffer.h>
> >  #include <linux/regmap.h>
> >  
> > +#include "bmc150-accel.h"
> > +
> >  #define BMC150_ACCEL_DRV_NAME			"bmc150_accel"
> >  #define BMC150_ACCEL_IRQ_NAME			"bmc150_accel_event"
> >  #define BMC150_ACCEL_GPIO_NAME			"bmc150_accel_int"
> > @@ -187,7 +189,6 @@ enum bmc150_accel_trigger_id {
> >  struct bmc150_accel_data {
> >  	struct regmap *regmap;
> >  	struct device *dev;
> At least from how diff is listing it, looks like you've just
> moved this down the struct?  Why?

No reason, will fix it.

Thanks,

Markus

> > -	int irq;
> >  	struct bmc150_accel_interrupt interrupts[BMC150_ACCEL_INTERRUPTS];
> >  	atomic_t active_intr;
> >  	struct bmc150_accel_trigger triggers[BMC150_ACCEL_TRIGGERS];
> > @@ -201,6 +202,7 @@ struct bmc150_accel_data {
> >  	int ev_enable_state;
> >  	int64_t timestamp, old_timestamp; /* Only used in hw fifo mode. */
> >  	const struct bmc150_accel_chip_info *chip_info;
> > +	int irq;
> >  };
> >  
> >  static const struct {
> > @@ -1076,15 +1078,6 @@ static const struct iio_chan_spec bmc150_accel_channels[] =
> >  static const struct iio_chan_spec bma280_accel_channels[] =
> >  	BMC150_ACCEL_CHANNELS(14);
> >  
> > -enum {
> > -	bmc150,
> > -	bmi055,
> > -	bma255,
> > -	bma250e,
> > -	bma222e,
> > -	bma280,
> > -};
> > -
> >  static const struct bmc150_accel_chip_info bmc150_accel_chip_info_tbl[] = {
> >  	[bmc150] = {
> >  		.chip_id = 0xFA,
> > @@ -1573,36 +1566,22 @@ static const struct iio_buffer_setup_ops bmc150_accel_buffer_ops = {
> >  	.postdisable = bmc150_accel_buffer_postdisable,
> >  };
> >  
> > -static int bmc150_accel_probe(struct i2c_client *client,
> > -			      const struct i2c_device_id *id)
> > +int bmc150_accel_core_probe(struct device *dev, struct regmap *regmap, int irq,
> > +			    const char *name, int chip_id, bool block_supported)
> >  {
> >  	struct bmc150_accel_data *data;
> >  	struct iio_dev *indio_dev;
> >  	int ret;
> > -	const char *name = NULL;
> > -	int chip_id = 0;
> > -	struct device *dev;
> >  
> > -	indio_dev = devm_iio_device_alloc(&client->dev, sizeof(*data));
> > +	indio_dev = devm_iio_device_alloc(dev, sizeof(*data));
> >  	if (!indio_dev)
> >  		return -ENOMEM;
> >  
> >  	data = iio_priv(indio_dev);
> > -	i2c_set_clientdata(client, indio_dev);
> > -	data->dev = &client->dev;
> > -	dev = &client->dev;
> > -	data->irq = client->irq;
> > -
> > -	data->regmap = devm_regmap_init_i2c(client, &bmc150_i2c_regmap_conf);
> > -	if (IS_ERR(data->regmap)) {
> > -		dev_err(dev, "Failed to initialize i2c regmap\n");
> > -		return PTR_ERR(data->regmap);
> > -	}
> > -
> > -	if (id) {
> > -		name = id->name;
> > -		chip_id = id->driver_data;
> > -	}
> > +	dev_set_drvdata(dev, indio_dev);
> > +	data->dev = dev;
> > +	data->irq = irq;
> > +	data->regmap = regmap;
> >  
> >  	if (ACPI_HANDLE(dev))
> >  		name = bmc150_accel_match_acpi_device(dev, &chip_id);
> > @@ -1664,9 +1643,7 @@ static int bmc150_accel_probe(struct i2c_client *client,
> >  		if (ret)
> >  			goto err_buffer_cleanup;
> >  
> > -		if (i2c_check_functionality(client->adapter, I2C_FUNC_I2C) ||
> > -		    i2c_check_functionality(client->adapter,
> > -					    I2C_FUNC_SMBUS_READ_I2C_BLOCK)) {
> > +		if (block_supported) {
> >  			indio_dev->modes |= INDIO_BUFFER_SOFTWARE;
> >  			indio_dev->info = &bmc150_accel_info_fifo;
> >  			indio_dev->buffer->attrs = bmc150_accel_fifo_attributes;
> > @@ -1675,7 +1652,7 @@ static int bmc150_accel_probe(struct i2c_client *client,
> >  
> >  	ret = iio_device_register(indio_dev);
> >  	if (ret < 0) {
> > -		dev_err(data->dev, "Unable to register iio device\n");
> > +		dev_err(dev, "Unable to register iio device\n");
> >  		goto err_trigger_unregister;
> >  	}
> >  
> > @@ -1698,10 +1675,11 @@ err_buffer_cleanup:
> >  
> >  	return ret;
> >  }
> > +EXPORT_SYMBOL_GPL(bmc150_accel_core_probe);
> >  
> > -static int bmc150_accel_remove(struct i2c_client *client)
> > +int bmc150_accel_core_remove(struct device *dev)
> >  {
> > -	struct iio_dev *indio_dev = i2c_get_clientdata(client);
> > +	struct iio_dev *indio_dev = dev_get_drvdata(dev);
> >  	struct bmc150_accel_data *data = iio_priv(indio_dev);
> >  
> >  	pm_runtime_disable(data->dev);
> > @@ -1720,6 +1698,7 @@ static int bmc150_accel_remove(struct i2c_client *client)
> >  
> >  	return 0;
> >  }
> > +EXPORT_SYMBOL_GPL(bmc150_accel_core_remove);
> >  
> >  #ifdef CONFIG_PM_SLEEP
> >  static int bmc150_accel_suspend(struct device *dev)
> > @@ -1790,48 +1769,8 @@ static int bmc150_accel_runtime_resume(struct device *dev)
> >  }
> >  #endif
> >  
> > -static const struct dev_pm_ops bmc150_accel_pm_ops = {
> > +const struct dev_pm_ops bmc150_accel_pm_ops = {
> >  	SET_SYSTEM_SLEEP_PM_OPS(bmc150_accel_suspend, bmc150_accel_resume)
> >  	SET_RUNTIME_PM_OPS(bmc150_accel_runtime_suspend,
> >  			   bmc150_accel_runtime_resume, NULL)
> >  };
> > -
> > -static const struct acpi_device_id bmc150_accel_acpi_match[] = {
> > -	{"BSBA0150",	bmc150},
> > -	{"BMC150A",	bmc150},
> > -	{"BMI055A",	bmi055},
> > -	{"BMA0255",	bma255},
> > -	{"BMA250E",	bma250e},
> > -	{"BMA222E",	bma222e},
> > -	{"BMA0280",	bma280},
> > -	{ },
> > -};
> > -MODULE_DEVICE_TABLE(acpi, bmc150_accel_acpi_match);
> > -
> > -static const struct i2c_device_id bmc150_accel_id[] = {
> > -	{"bmc150_accel",	bmc150},
> > -	{"bmi055_accel",	bmi055},
> > -	{"bma255",		bma255},
> > -	{"bma250e",		bma250e},
> > -	{"bma222e",		bma222e},
> > -	{"bma280",		bma280},
> > -	{}
> > -};
> > -
> > -MODULE_DEVICE_TABLE(i2c, bmc150_accel_id);
> > -
> > -static struct i2c_driver bmc150_accel_driver = {
> > -	.driver = {
> > -		.name	= BMC150_ACCEL_DRV_NAME,
> > -		.acpi_match_table = ACPI_PTR(bmc150_accel_acpi_match),
> > -		.pm	= &bmc150_accel_pm_ops,
> > -	},
> > -	.probe		= bmc150_accel_probe,
> > -	.remove		= bmc150_accel_remove,
> > -	.id_table	= bmc150_accel_id,
> > -};
> > -module_i2c_driver(bmc150_accel_driver);
> > -
> > -MODULE_AUTHOR("Srinivas Pandruvada <srinivas.pandruvada at linux.intel.com>");
> > -MODULE_LICENSE("GPL v2");
> > -MODULE_DESCRIPTION("BMC150 accelerometer driver");
> > diff --git a/drivers/iio/accel/bmc150-accel-i2c.c b/drivers/iio/accel/bmc150-accel-i2c.c
> > new file mode 100644
> > index 000000000000..7e036e2eb077
> > --- /dev/null
> > +++ b/drivers/iio/accel/bmc150-accel-i2c.c
> > @@ -0,0 +1,101 @@
> > +/*
> > + * 3-axis accelerometer driver supporting following I2C Bosch-Sensortec chips:
> > + *  - BMC150
> > + *  - BMI055
> > + *  - BMA255
> > + *  - BMA250E
> > + *  - BMA222E
> > + *  - BMA280
> > + *
> > + * Copyright (c) 2014, Intel Corporation.
> > + *
> > + * This program is free software; you can redistribute it and/or modify it
> > + * under the terms and conditions of the GNU General Public License,
> > + * version 2, as published by the Free Software Foundation.
> > + *
> > + * This program is distributed in the hope 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/device.h>
> > +#include <linux/mod_devicetable.h>
> > +#include <linux/i2c.h>
> > +#include <linux/module.h>
> > +#include <linux/acpi.h>
> > +#include <linux/regmap.h>
> > +
> > +#include "bmc150-accel.h"
> > +
> > +static const struct regmap_config bmc150_i2c_regmap_conf = {
> > +	.reg_bits = 8,
> > +	.val_bits = 8,
> > +
> > +	.use_single_rw = true,
> > +	.cache_type = REGCACHE_NONE,
> > +};
> > +
> > +static int bmc150_accel_probe(struct i2c_client *client,
> > +			      const struct i2c_device_id *id)
> > +{
> > +	struct regmap *regmap;
> > +	bool block_supported =
> > +		i2c_check_functionality(client->adapter, I2C_FUNC_I2C) ||
> > +		i2c_check_functionality(client->adapter, I2C_FUNC_SMBUS_READ_I2C_BLOCK);
> > +
> > +	regmap = devm_regmap_init_i2c(client, &bmc150_i2c_regmap_conf);
> > +	if (IS_ERR(regmap)) {
> > +		dev_err(&client->dev, "Failed to initialize i2c regmap\n");
> > +		return PTR_ERR(regmap);
> > +	}
> > +
> > +	return bmc150_accel_core_probe(&client->dev, regmap, client->irq,
> > +				       id->name, id->driver_data,
> > +				       block_supported);
> > +}
> > +
> > +static int bmc150_accel_remove(struct i2c_client *client)
> > +{
> > +	return bmc150_accel_core_remove(&client->dev);
> > +}
> > +
> > +static const struct acpi_device_id bmc150_accel_acpi_match[] = {
> > +	{"BSBA0150",	bmc150},
> > +	{"BMC150A",	bmc150},
> > +	{"BMI055A",	bmi055},
> > +	{"BMA0255",	bma255},
> > +	{"BMA250E",	bma250e},
> > +	{"BMA222E",	bma222e},
> > +	{"BMA0280",	bma280},
> > +	{ },
> > +};
> > +MODULE_DEVICE_TABLE(acpi, bmc150_accel_acpi_match);
> > +
> > +static const struct i2c_device_id bmc150_accel_id[] = {
> > +	{"bmc150_accel",	bmc150},
> > +	{"bmi055_accel",	bmi055},
> > +	{"bma255",		bma255},
> > +	{"bma250e",		bma250e},
> > +	{"bma222e",		bma222e},
> > +	{"bma280",		bma280},
> > +	{}
> > +};
> > +
> > +MODULE_DEVICE_TABLE(i2c, bmc150_accel_id);
> > +
> > +static struct i2c_driver bmc150_accel_driver = {
> > +	.driver = {
> > +		.name	= "bmc150_accel_i2c",
> > +		.acpi_match_table = ACPI_PTR(bmc150_accel_acpi_match),
> > +		.pm	= &bmc150_accel_pm_ops,
> > +	},
> > +	.probe		= bmc150_accel_probe,
> > +	.remove		= bmc150_accel_remove,
> > +	.id_table	= bmc150_accel_id,
> > +};
> > +module_i2c_driver(bmc150_accel_driver);
> > +
> > +MODULE_AUTHOR("Srinivas Pandruvada <srinivas.pandruvada at linux.intel.com>");
> > +MODULE_LICENSE("GPL v2");
> > +MODULE_DESCRIPTION("BMC150 I2C accelerometer driver");
> > diff --git a/drivers/iio/accel/bmc150-accel.h b/drivers/iio/accel/bmc150-accel.h
> > new file mode 100644
> > index 000000000000..988b57573d0c
> > --- /dev/null
> > +++ b/drivers/iio/accel/bmc150-accel.h
> > @@ -0,0 +1,21 @@
> > +#ifndef _BMC150_ACCEL_H_
> > +#define _BMC150_ACCEL_H_
> > +
> > +struct regmap;
> > +
> > +enum {
> > +	bmc150,
> > +	bmi055,
> > +	bma255,
> > +	bma250e,
> > +	bma222e,
> > +	bma280,
> > +};
> > +
> > +int bmc150_accel_core_probe(struct device *dev, struct regmap *regmap, int irq,
> > +			    const char *name, int chip_id,
> > +			    bool block_supported);
> > +int bmc150_accel_core_remove(struct device *dev);
> > +extern const struct dev_pm_ops bmc150_accel_pm_ops;
> > +
> > +#endif  /* _BMC150_ACCEL_H_ */
> > 
> 
> 

-- 
Pengutronix e.K.                           |                             |
Industrial Linux Solutions                 | http://www.pengutronix.de/  |
Peiner Str. 6-8, 31137 Hildesheim, Germany | Phone: +49-5121-206917-0    |
Amtsgericht Hildesheim, HRA 2686           | Fax:   +49-5121-206917-5555 |
-------------- next part --------------
A non-text attachment was scrubbed...
Name: signature.asc
Type: application/pgp-signature
Size: 819 bytes
Desc: Digital signature
URL: <http://lists.infradead.org/pipermail/linux-arm-kernel/attachments/20150817/fb0a5bba/attachment.sig>

From mpa at pengutronix.de  Mon Aug 17 01:00:17 2015
From: mpa at pengutronix.de (Markus Pargmann)
Date: Mon, 17 Aug 2015 10:00:17 +0200
Subject: [PATCH 20/20] iio: bmc150: Add SPI driver
In-Reply-To: <20150812120300.GE10748@sirena.org.uk>
References: <1439374365-20623-1-git-send-email-mpa@pengutronix.de>
 <1439374365-20623-21-git-send-email-mpa@pengutronix.de>
 <20150812120300.GE10748@sirena.org.uk>
Message-ID: <20150817080017.GM19600@pengutronix.de>

On Wed, Aug 12, 2015 at 01:03:00PM +0100, Mark Brown wrote:
> On Wed, Aug 12, 2015 at 12:12:45PM +0200, Markus Pargmann wrote:
> 
> > +	.use_single_rw = false,
> > +	.cache_type = REGCACHE_NONE,
> > +};
> 
> No need to initialise defaults.

Thanks, removed those.

Best regards,

Markus

-- 
Pengutronix e.K.                           |                             |
Industrial Linux Solutions                 | http://www.pengutronix.de/  |
Peiner Str. 6-8, 31137 Hildesheim, Germany | Phone: +49-5121-206917-0    |
Amtsgericht Hildesheim, HRA 2686           | Fax:   +49-5121-206917-5555 |
-------------- next part --------------
A non-text attachment was scrubbed...
Name: signature.asc
Type: application/pgp-signature
Size: 819 bytes
Desc: Digital signature
URL: <http://lists.infradead.org/pipermail/linux-arm-kernel/attachments/20150817/4c203c2c/attachment.sig>

From mpa at pengutronix.de  Mon Aug 17 01:03:44 2015
From: mpa at pengutronix.de (Markus Pargmann)
Date: Mon, 17 Aug 2015 10:03:44 +0200
Subject: [PATCH 20/20] iio: bmc150: Add SPI driver
In-Reply-To: <55CF42E8.7070508@kernel.org>
References: <1439374365-20623-1-git-send-email-mpa@pengutronix.de>
 <1439374365-20623-21-git-send-email-mpa@pengutronix.de>
 <55CF42E8.7070508@kernel.org>
Message-ID: <20150817080344.GN19600@pengutronix.de>

On Sat, Aug 15, 2015 at 02:47:20PM +0100, Jonathan Cameron wrote:
> On 12/08/15 11:12, Markus Pargmann wrote:
> > Add a simple SPI driver which initializes the spi regmap for the bmc150
> > core driver.
> > 
> > Signed-off-by: Markus Pargmann <mpa at pengutronix.de>
> 1 thing inline, plus the change of kconfig approach suggested for the
> previous patch.
> 
> Otherwise, looks fine to me.
> 
> Srinivas, over to you for the next version :) (unless you are feeling
> enthusiastic and want to take a look at this one)
> > ---
> >  drivers/iio/accel/Kconfig            | 10 +++++
> >  drivers/iio/accel/Makefile           |  1 +
> >  drivers/iio/accel/bmc150-accel-spi.c | 86 ++++++++++++++++++++++++++++++++++++
> >  3 files changed, 97 insertions(+)
> >  create mode 100644 drivers/iio/accel/bmc150-accel-spi.c
> > 
> > diff --git a/drivers/iio/accel/Kconfig b/drivers/iio/accel/Kconfig
> > index c63e981c38ff..bdb42069a767 100644
> > --- a/drivers/iio/accel/Kconfig
> > +++ b/drivers/iio/accel/Kconfig
> > @@ -40,6 +40,16 @@ config BMC150_ACCEL_I2C
> >  	  Say yes here to build support for I2C communication with the
> >  	  mentioned accelerometer.
> >  
> > +config BMC150_ACCEL_SPI
> > +	tristate "SPI support"
> > +	depends on SPI
> > +	select IIO_BUFFER
> > +	select IIO_TRIGGERED_BUFFER
> > +	select REGMAP_SPI
> > +	help
> > +	  Say yes here to build support for SPI communication with the
> > +	  mentioned accelerometer.
> If you move to the config approach I suggested earlier, these options
> are hidden away avoiding the need for a help message ;)

Yes.

> > +
> >  endif
> >  
> >  config HID_SENSOR_ACCEL_3D
> > diff --git a/drivers/iio/accel/Makefile b/drivers/iio/accel/Makefile
> > index 5ef8bdbad092..e579e93bf022 100644
> > --- a/drivers/iio/accel/Makefile
> > +++ b/drivers/iio/accel/Makefile
> > @@ -6,6 +6,7 @@
> >  obj-$(CONFIG_BMA180) += bma180.o
> >  obj-$(CONFIG_BMC150_ACCEL) += bmc150-accel-core.o
> >  obj-$(CONFIG_BMC150_ACCEL_I2C) += bmc150-accel-i2c.o
> > +obj-$(CONFIG_BMC150_ACCEL_SPI) += bmc150-accel-spi.o
> >  obj-$(CONFIG_HID_SENSOR_ACCEL_3D) += hid-sensor-accel-3d.o
> >  obj-$(CONFIG_KXCJK1013) += kxcjk-1013.o
> >  obj-$(CONFIG_KXSD9)	+= kxsd9.o
> > diff --git a/drivers/iio/accel/bmc150-accel-spi.c b/drivers/iio/accel/bmc150-accel-spi.c
> > new file mode 100644
> > index 000000000000..c13fd2aa5f34
> > --- /dev/null
> > +++ b/drivers/iio/accel/bmc150-accel-spi.c
> > @@ -0,0 +1,86 @@
> > +/*
> > + * 3-axis accelerometer driver supporting following I2C Bosch-Sensortec chips:
> Umm. Read the line above?  Spot the obvious minor point ;)

Oh yes. Thanks.

Best regards,

Markus

> 
> > + *  - BMC150
> > + *  - BMI055
> > + *  - BMA255
> > + *  - BMA250E
> > + *  - BMA222E
> > + *  - BMA280
> > + *
> > + * Copyright (c) 2014, Intel Corporation.
> > + *
> > + * This program is free software; you can redistribute it and/or modify it
> > + * under the terms and conditions of the GNU General Public License,
> > + * version 2, as published by the Free Software Foundation.
> > + *
> > + * This program is distributed in the hope 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/device.h>
> > +#include <linux/mod_devicetable.h>
> > +#include <linux/module.h>
> > +#include <linux/acpi.h>
> > +#include <linux/regmap.h>
> > +#include <linux/spi/spi.h>
> > +
> > +#include "bmc150-accel.h"
> > +
> > +static const struct regmap_config bmc150_spi_regmap_conf = {
> > +	.reg_bits = 8,
> > +	.val_bits = 8,
> > +	.max_register = 0x3f,
> > +
> > +	.use_single_rw = false,
> > +	.cache_type = REGCACHE_NONE,
> > +};
> > +
> > +static int bmc150_accel_probe(struct spi_device *spi)
> > +{
> > +	struct regmap *regmap;
> > +	const struct spi_device_id *id = spi_get_device_id(spi);
> > +
> > +	regmap = devm_regmap_init_spi(spi, &bmc150_spi_regmap_conf);
> > +	if (IS_ERR(regmap)) {
> > +		dev_err(&spi->dev, "Failed to initialize spi regmap\n");
> > +		return PTR_ERR(regmap);
> > +	}
> > +
> > +	return bmc150_accel_core_probe(&spi->dev, regmap, spi->irq,
> > +				       id->name, id->driver_data, true);
> > +}
> > +
> > +static int bmc150_accel_remove(struct spi_device *spi)
> > +{
> > +	return bmc150_accel_core_remove(&spi->dev);
> > +}
> > +
> > +static const struct spi_device_id bmc150_accel_id[] = {
> > +	{"bmc150_accel",	bmc150},
> > +	{"bmi055_accel",	bmi055},
> > +	{"bma255",		bma255},
> > +	{"bma250e",		bma250e},
> > +	{"bma222e",		bma222e},
> > +	{"bma280",		bma280},
> > +	{}
> > +};
> > +
> > +MODULE_DEVICE_TABLE(spi, bmc150_accel_id);
> > +
> > +static struct spi_driver bmc150_accel_driver = {
> > +	.driver = {
> > +		.name	= "bmc150_accel_spi",
> > +		.acpi_match_table = ACPI_PTR(bmc150_accel_acpi_match),
> > +		.pm	= &bmc150_accel_pm_ops,
> > +	},
> > +	.probe		= bmc150_accel_probe,
> > +	.remove		= bmc150_accel_remove,
> > +	.id_table	= bmc150_accel_id,
> > +};
> > +module_spi_driver(bmc150_accel_driver);
> > +
> > +MODULE_AUTHOR("Markus Pargmann <mpa at pengutronix.de>");
> > +MODULE_LICENSE("GPL v2");
> > +MODULE_DESCRIPTION("BMC150 SPI accelerometer driver");
> > 
> 
> 

-- 
Pengutronix e.K.                           |                             |
Industrial Linux Solutions                 | http://www.pengutronix.de/  |
Peiner Str. 6-8, 31137 Hildesheim, Germany | Phone: +49-5121-206917-0    |
Amtsgericht Hildesheim, HRA 2686           | Fax:   +49-5121-206917-5555 |
-------------- next part --------------
A non-text attachment was scrubbed...
Name: signature.asc
Type: application/pgp-signature
Size: 819 bytes
Desc: Digital signature
URL: <http://lists.infradead.org/pipermail/linux-arm-kernel/attachments/20150817/8370d8ce/attachment-0001.sig>

From vinod.koul at intel.com  Mon Aug 17 01:26:46 2015
From: vinod.koul at intel.com (Vinod Koul)
Date: Mon, 17 Aug 2015 13:56:46 +0530
Subject: [PATCH] dma: pxa_dma: don't use config direction parameter
In-Reply-To: <1439324192-9148-1-git-send-email-robert.jarzmik@free.fr>
References: <1439324192-9148-1-git-send-email-robert.jarzmik@free.fr>
Message-ID: <20150817082646.GO13546@localhost>

On Tue, Aug 11, 2015 at 10:16:32PM +0200, Robert Jarzmik wrote:
> From: Robert Jarzmik <rj at valbob.noip.me>
> 
> Don't use the direction passed in the configuration, and rely on each
> transfer's direction to prepare the transfers. This will enable
> future removal of direction parameter from dma_slave_config.

Applied now with right subsystem name

-- 
~Vinod



From seven at nimrod-online.com  Mon Aug 17 01:30:38 2015
From: seven at nimrod-online.com (Roy Spliet)
Date: Mon, 17 Aug 2015 09:30:38 +0100
Subject: ARM: sunxi: Experiences NAND flash
In-Reply-To: <20150817093411.4ff853c4@bbrezillon>
References: <55C9E7B4.9090906@schinagl.nl> <20150817093411.4ff853c4@bbrezillon>
Message-ID: <55D19BAE.5000204@nimrod-online.com>

Hello,

Reply in-line

Op 17-08-15 om 08:34 schreef Boris Brezillon:
> Hi Oliver,
>
> Sorry for the late reply (I was in vacation for the last 2 weeks)
>
> On Tue, 11 Aug 2015 14:16:52 +0200
> Olliver Schinagl <oliver+list at schinagl.nl> wrote:
>
>> Hello everybody,
>>
>> We are working with Boris and Roy's patch series on getting the NAND
>> flash chip working on Olimex OLinuXino Lime2 boards. Initially,
>> everything looks fine, but we noticed that occasionally (after
>> power/cycle or power cut) ubi fails to mount the partition. It is not
>> something easily enough to reproduce, but it has failed on 5 boards out
>> of 30 we have.
> I remember warning you about that problem before: MLC NANDs are not as
> reliable as SLC ones (please read my presentation about MLC support in
> Linux [1]). I also remember recommending using an SLC chip if you were
> tight on time to avoid dealing with all these MLC related problems, but
> you decided to go for the MLC solution.
>
> Back to your problem now, what you're seeing here is probably caused by
> interrupted PROGRAM operations on paired pages (page 17, 18 and 26 to 32
> of my presentation for more information).
In his defence; we looked at it, and from what we could tell it is not 
possible to find an affordable SLC chip that the Allwinner A10/A20 
BootROM would even boot from. In general, chips below 8K page size 
require 64-bit EEC strength to operate, which in turn required more OOB 
area than any chip would provide. This limitation is in my opinion a 
design fault from AllWinners side and I hope that their future SoCs can 
boot with more relaxed EEC settings to facilitate for cheap SLC chips, 
but right now there is nothing we can do to change that situation.
>> U-boot reports the following:
>> UBI: default fastmap pool size: 100
>> UBI: default fastmap WL pool size: 25
>> UBI: attaching mtd1 to ubi0
>> UBI: scanning is finished
>> UBI init error 22
>> Error reading superblock on volume 'ubi:boot' errno=-19!
>> ubifsmount - mount UBIFS volume
>>
>> whereas the linux kernel booted from sd card gives:
>> ubiattach /dev/ubi_ctrl -m 0
>> [  100.560704] ubi0: default fastmap pool size: 8
>> [  100.565186] ubi0: default fastmap WL pool size: 4
>> [  100.570100] ubi0: attaching mtd0
>> [  100.590469] ubi0: scanning is finished
>> [  100.594732] ubi0 error: ubi_read_volume_table: the layout volume was
>> not found
>> [  100.602675] ubi0 error: ubi_attach_mtd_dev: failed to attach mtd0,
>> error -22
>> ubiattach: error!: cannot attach mtd0
>>              error 22 (Invalid argument)
>>
>> The u-boot version we are using is a few months out of date
>> U-Boot 2015.07-rc2-g2540c39 (Aug 04 2015 - 16:09:02 +0200) Allwinner
>> Technology
>> arm-none-eabi-gcc (4.8.4-1+11-1) 4.8.4 20141219 (release)
>> GNU ld (2.25-5+5+b1) 2.25
>>
>> but the kernel is fairly up to date:
>> 4.2.0-rc4-opinicus-g8ec3671
>>
>>
>> Now I know that the mtd stuff is all very new and all very untested,
>> what I am curious about is a) have other people actually tried the mtd
>> stuff on Allwinner hardware, and b) has anybody encountered this issue
>> as well?
> Yes we did. So far we're using the NAND in SLC mode to address this
> problem. It seems to work, but you also loose half the NAND capacity.
So as requested by someone else: how exactly does that work? Can we just 
give your NAND driver a mapping between shared pages and instruct it to 
ignore half, or does the driver require some serious patchery?
Cheers,

Roy
>
>> It's not something very easily reproducible (toggling a machine on/off
>> repeatedly did not trigger it yet) but it does happen.
> I managed to reproduce it by faking a power cut directly in the NAND
> core code (by sending a RESET command to the NAND chip in the middle of
> a program operation), and I can confirm SLC mode address the problem.
>
> Anyway, remember that MLC NANDs have other sources of unreliability
> (e.g the unstable bits problem).
>
> Best Regards,
>
> Boris
>
>
> [1]http://events.linuxfoundation.org/sites/events/files/slides/brezillon-mlc-nand_0.pdf
>



From geert at linux-m68k.org  Mon Aug 17 01:45:20 2015
From: geert at linux-m68k.org (Geert Uytterhoeven)
Date: Mon, 17 Aug 2015 10:45:20 +0200
Subject: Build regressions/improvements in v4.2-rc7
In-Reply-To: <1439801034-23948-1-git-send-email-geert@linux-m68k.org>
References: <1439801034-23948-1-git-send-email-geert@linux-m68k.org>
Message-ID: <CAMuHMdW=neYoFrTS5Nr8yvC0Zu1dJciZopWXS4=pcLyhWOctuA@mail.gmail.com>

On Mon, Aug 17, 2015 at 10:43 AM, Geert Uytterhoeven
<geert at linux-m68k.org> wrote:
> JFYI, when comparing v4.2-rc7[1] to v4.2-rc6[3], the summaries are:
>   - build errors: +6/-14

  + /home/kisskb/slave/src/arch/arm/kernel/devtree.c: error: implicit
declaration of function 'early_init_dt_scan_nodes'
[-Werror=implicit-function-declaration]:  => 244:2
  + /home/kisskb/slave/src/arch/arm/kernel/devtree.c: error: implicit
declaration of function 'early_init_dt_verify'
[-Werror=implicit-function-declaration]:  => 215:2
  + /home/kisskb/slave/src/arch/arm/kernel/devtree.c: error: implicit
declaration of function 'of_flat_dt_match_machine'
[-Werror=implicit-function-declaration]:  => 218:2
  + /home/kisskb/slave/src/arch/arm/kernel/devtree.c: error: implicit
declaration of function 'of_get_flat_dt_prop'
[-Werror=implicit-function-declaration]:  => 229:3
  + /home/kisskb/slave/src/arch/arm/kernel/devtree.c: error: implicit
declaration of function 'of_get_flat_dt_root'
[-Werror=implicit-function-declaration]:  => 228:3

arm-randconfig

> [1] http://kisskb.ellerman.id.au/kisskb/head/9260/ (all 254 configs)
> [3] http://kisskb.ellerman.id.au/kisskb/head/9234/ (253 out of 254 configs)

Gr{oetje,eeting}s,

                        Geert

--
Geert Uytterhoeven -- There's lots of Linux beyond ia32 -- geert at linux-m68k.org

In personal conversations with technical people, I call myself a hacker. But
when I'm talking to journalists I just say "programmer" or something like that.
                                -- Linus Torvalds


From pi-cheng.chen at linaro.org  Mon Aug 17 01:56:45 2015
From: pi-cheng.chen at linaro.org (Pi-Cheng Chen)
Date: Mon, 17 Aug 2015 16:56:45 +0800
Subject: [RESEND PATCH v5] clk: mediatek: Export CPU mux clocks for CPU
 frequency control
Message-ID: <1439801805-19043-1-git-send-email-pi-cheng.chen@linaro.org>

From: "pi-cheng.chen" <pi-cheng.chen at linaro.org>

This patch adds CPU mux clocks which are used by Mediatek cpufreq driver
for intermediate clock source switching.

Signed-off-by: Pi-Cheng Chen <pi-cheng.chen at linaro.org>
Reviewed-by: Daniel Kurtz <djkurtz at chromium.org>
---
Changes in v5:
- Replace __initdata with __initconst to fix compiling error

Changes in v4:
- Fix some minor issues for v3
- Rebase to the patch that adds 13mhz clock for MT8173[1]

Changes in v3:
- Rebase to 4.2-rc1
- Fix some issues of v2

Changes in v2:
- Remove use of .determine_rate callback

[1] http://patchwork.kernerl.xyz/patch/6777041/
---
 drivers/clk/mediatek/Makefile          |   2 +-
 drivers/clk/mediatek/clk-cpumux.c      | 127 +++++++++++++++++++++++++++++++++
 drivers/clk/mediatek/clk-cpumux.h      |  22 ++++++
 drivers/clk/mediatek/clk-mt8173.c      |  23 ++++++
 include/dt-bindings/clock/mt8173-clk.h |   4 +-
 5 files changed, 176 insertions(+), 2 deletions(-)
 create mode 100644 drivers/clk/mediatek/clk-cpumux.c
 create mode 100644 drivers/clk/mediatek/clk-cpumux.h

diff --git a/drivers/clk/mediatek/Makefile b/drivers/clk/mediatek/Makefile
index 8e4b2a4..299917a 100644
--- a/drivers/clk/mediatek/Makefile
+++ b/drivers/clk/mediatek/Makefile
@@ -1,4 +1,4 @@
-obj-y += clk-mtk.o clk-pll.o clk-gate.o
+obj-y += clk-mtk.o clk-pll.o clk-gate.o clk-cpumux.o
 obj-$(CONFIG_RESET_CONTROLLER) += reset.o
 obj-y += clk-mt8135.o
 obj-y += clk-mt8173.o
diff --git a/drivers/clk/mediatek/clk-cpumux.c b/drivers/clk/mediatek/clk-cpumux.c
new file mode 100644
index 0000000..fb04fe1
--- /dev/null
+++ b/drivers/clk/mediatek/clk-cpumux.c
@@ -0,0 +1,127 @@
+/*
+ * Copyright (c) 2015 Linaro Ltd.
+ * Author: Pi-Cheng Chen <pi-cheng.chen at linaro.org>
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License version 2 as
+ * published by the Free Software Foundation.
+ *
+ * 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/mfd/syscon.h>
+#include <linux/slab.h>
+
+#include "clk-mtk.h"
+#include "clk-cpumux.h"
+
+struct mtk_clk_cpumux {
+	struct clk_hw	hw;
+	struct regmap	*regmap;
+	u32		reg;
+	u32		mask;
+	u8		shift;
+};
+
+static inline struct mtk_clk_cpumux *to_clk_mux(struct clk_hw *_hw)
+{
+	return container_of(_hw, struct mtk_clk_cpumux, hw);
+}
+
+static u8 clk_cpumux_get_parent(struct clk_hw *hw)
+{
+	struct mtk_clk_cpumux *mux = to_clk_mux(hw);
+	int num_parents = __clk_get_num_parents(hw->clk);
+	unsigned int val;
+
+	regmap_read(mux->regmap, mux->reg, &val);
+
+	val >>= mux->shift;
+	val &= mux->mask;
+
+	if (val >= num_parents)
+		return -EINVAL;
+
+	return val;
+}
+
+static int clk_cpumux_set_parent(struct clk_hw *hw, u8 index)
+{
+	struct mtk_clk_cpumux *mux = to_clk_mux(hw);
+	u32 mask, val;
+
+	val = index << mux->shift;
+	mask = mux->mask << mux->shift;
+
+	return regmap_update_bits(mux->regmap, mux->reg, mask, val);
+}
+
+static const struct clk_ops clk_cpumux_ops = {
+	.get_parent = clk_cpumux_get_parent,
+	.set_parent = clk_cpumux_set_parent,
+};
+
+static struct clk __init *mtk_clk_register_cpumux(const struct mtk_composite *mux,
+					   struct regmap *regmap)
+{
+	struct mtk_clk_cpumux *cpumux;
+	struct clk *clk;
+	struct clk_init_data init;
+
+	cpumux = kzalloc(sizeof(*cpumux), GFP_KERNEL);
+	if (!cpumux)
+		return ERR_PTR(-ENOMEM);
+
+	init.name = mux->name;
+	init.ops = &clk_cpumux_ops;
+	init.parent_names = mux->parent_names;
+	init.num_parents = mux->num_parents;
+	init.flags = mux->flags;
+
+	cpumux->reg = mux->mux_reg;
+	cpumux->shift = mux->mux_shift;
+	cpumux->mask = BIT(mux->mux_width) - 1;
+	cpumux->regmap = regmap;
+	cpumux->hw.init = &init;
+
+	clk = clk_register(NULL, &cpumux->hw);
+	if (IS_ERR(clk))
+		kfree(cpumux);
+
+	return clk;
+}
+
+int __init mtk_clk_register_cpumuxes(struct device_node *node,
+			      const struct mtk_composite *clks, int num,
+			      struct clk_onecell_data *clk_data)
+{
+	int i;
+	struct clk *clk;
+	struct regmap *regmap;
+
+	regmap = syscon_node_to_regmap(node);
+	if (IS_ERR(regmap)) {
+		pr_err("Cannot find regmap for %s: %ld\n", node->full_name,
+		       PTR_ERR(regmap));
+		return PTR_ERR(regmap);
+	}
+
+	for (i = 0; i < num; i++) {
+		const struct mtk_composite *mux = &clks[i];
+
+		clk = mtk_clk_register_cpumux(mux, regmap);
+		if (IS_ERR(clk)) {
+			pr_err("Failed to register clk %s: %ld\n",
+			       mux->name, PTR_ERR(clk));
+			continue;
+		}
+
+		clk_data->clks[mux->id] = clk;
+	}
+
+	return 0;
+}
diff --git a/drivers/clk/mediatek/clk-cpumux.h b/drivers/clk/mediatek/clk-cpumux.h
new file mode 100644
index 0000000..52c769f
--- /dev/null
+++ b/drivers/clk/mediatek/clk-cpumux.h
@@ -0,0 +1,22 @@
+/*
+ * Copyright (c) 2015 Linaro Ltd.
+ * Author: Pi-Cheng Chen <pi-cheng.chen at linaro.org>
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License version 2 as
+ * published by the Free Software Foundation.
+ *
+ * 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 __DRV_CLK_CPUMUX_H
+#define __DRV_CLK_CPUMUX_H
+
+int mtk_clk_register_cpumuxes(struct device_node *node,
+			      const struct mtk_composite *clks, int num,
+			      struct clk_onecell_data *clk_data);
+
+#endif /* __DRV_CLK_CPUMUX_H */
diff --git a/drivers/clk/mediatek/clk-mt8173.c b/drivers/clk/mediatek/clk-mt8173.c
index 540c5c3..053ca27 100644
--- a/drivers/clk/mediatek/clk-mt8173.c
+++ b/drivers/clk/mediatek/clk-mt8173.c
@@ -19,6 +19,7 @@
 
 #include "clk-mtk.h"
 #include "clk-gate.h"
+#include "clk-cpumux.h"
 
 #include <dt-bindings/clock/mt8173-clk.h>
 
@@ -517,6 +518,25 @@ static const char * const i2s3_b_ck_parents[] __initconst = {
 	"apll2_div5"
 };
 
+static const char * const ca53_parents[] __initconst = {
+	"clk26m",
+	"armca7pll",
+	"mainpll",
+	"univpll"
+};
+
+static const char * const ca57_parents[] __initconst = {
+	"clk26m",
+	"armca15pll",
+	"mainpll",
+	"univpll"
+};
+
+static const struct mtk_composite cpu_muxes[] __initconst = {
+	MUX(CLK_INFRA_CA53SEL, "infra_ca53_sel", ca53_parents, 0x0000, 0, 2),
+	MUX(CLK_INFRA_CA57SEL, "infra_ca57_sel", ca57_parents, 0x0000, 2, 2),
+};
+
 static const struct mtk_composite top_muxes[] __initconst = {
 	/* CLK_CFG_0 */
 	MUX(CLK_TOP_AXI_SEL, "axi_sel", axi_parents, 0x0040, 0, 3),
@@ -743,6 +763,9 @@ static void __init mtk_infrasys_init(struct device_node *node)
 						clk_data);
 	mtk_clk_register_factors(infra_divs, ARRAY_SIZE(infra_divs), clk_data);
 
+	mtk_clk_register_cpumuxes(node, cpu_muxes, ARRAY_SIZE(cpu_muxes),
+						clk_data);
+
 	r = of_clk_add_provider(node, of_clk_src_onecell_get, clk_data);
 	if (r)
 		pr_err("%s(): could not register clock provider: %d\n",
diff --git a/include/dt-bindings/clock/mt8173-clk.h b/include/dt-bindings/clock/mt8173-clk.h
index fa2a2bb..a17cbaa 100644
--- a/include/dt-bindings/clock/mt8173-clk.h
+++ b/include/dt-bindings/clock/mt8173-clk.h
@@ -188,7 +188,9 @@
 #define CLK_INFRA_PMICSPI		10
 #define CLK_INFRA_PMICWRAP		11
 #define CLK_INFRA_CLK_13M		12
-#define CLK_INFRA_NR_CLK		13
+#define CLK_INFRA_CA53SEL		13
+#define CLK_INFRA_CA57SEL		14
+#define CLK_INFRA_NR_CLK		15
 
 /* PERI_SYS */
 
-- 
1.9.1



From will.deacon at arm.com  Mon Aug 17 02:01:32 2015
From: will.deacon at arm.com (Will Deacon)
Date: Mon, 17 Aug 2015 10:01:32 +0100
Subject: [PATCH v2 2/4] PCI: pci-host-generic: Fix lookup of
 linux,pci-probe-only property
In-Reply-To: <CAErSpo5abs2Qj25Bs+JVg87ve346f_RVz7jhNwqdv856+WvXQA@mail.gmail.com>
References: <1439569159-10051-1-git-send-email-marc.zyngier@arm.com>
 <1439569159-10051-3-git-send-email-marc.zyngier@arm.com>
 <20150814164051.GF26431@google.com>
 <20150814164324.GC22809@arm.com>
 <CAErSpo5abs2Qj25Bs+JVg87ve346f_RVz7jhNwqdv856+WvXQA@mail.gmail.com>
Message-ID: <20150817090132.GC1688@arm.com>

On Fri, Aug 14, 2015 at 09:26:21PM +0100, Bjorn Helgaas wrote:
> On Fri, Aug 14, 2015 at 11:43 AM, Will Deacon <will.deacon at arm.com> wrote:
> > On Fri, Aug 14, 2015 at 05:40:51PM +0100, Bjorn Helgaas wrote:
> >> Do we need support for pci-probe-only in pci-host-generic at all?
> >> You're removing the use in amd-overdrive.dts, and there are no other
> >> DTs in the kernel tree that mention it.
> >>
> >> If we can live without it, that would be nice.  It seems like a relic from
> >> days when we couldn't reliably assign resources.  (I'm not saying we can do
> >> that reliably even today, but I'd rather make it reliable than turn it
> >> off.)
> >
> > Kvmtool certainly uses it (and generates its own DT, hence why you don't
> > see it in mainline). Not sure about qemu, though.
> 
> Do you know why kvmtool wants probe-only?  Would something break if we
> didn't support probe-only?  I guess we'd be looking for a case where
> Linux assigns resources and that assignment doesn't work with kvmtool?

It's basically because the BARs aren't writable other than to find the
region size. It could fixed with a bit of pain, but it doesn't help older
kvmtools that do work with mainline today.

Will


From boris.brezillon at free-electrons.com  Mon Aug 17 02:03:22 2015
From: boris.brezillon at free-electrons.com (Boris Brezillon)
Date: Mon, 17 Aug 2015 11:03:22 +0200
Subject: ARM: sunxi: Experiences NAND flash
In-Reply-To: <55D19BAE.5000204@nimrod-online.com>
References: <55C9E7B4.9090906@schinagl.nl> <20150817093411.4ff853c4@bbrezillon>
 <55D19BAE.5000204@nimrod-online.com>
Message-ID: <20150817110322.1fa7d24c@bbrezillon>

Hi Roy,

On Mon, 17 Aug 2015 09:30:38 +0100
Roy Spliet <seven at nimrod-online.com> wrote:

> Hello,
> 
> Reply in-line
> 
> Op 17-08-15 om 08:34 schreef Boris Brezillon:
> > Hi Oliver,
> >
> > Sorry for the late reply (I was in vacation for the last 2 weeks)
> >
> > On Tue, 11 Aug 2015 14:16:52 +0200
> > Olliver Schinagl <oliver+list at schinagl.nl> wrote:
> >
> >> Hello everybody,
> >>
> >> We are working with Boris and Roy's patch series on getting the NAND
> >> flash chip working on Olimex OLinuXino Lime2 boards. Initially,
> >> everything looks fine, but we noticed that occasionally (after
> >> power/cycle or power cut) ubi fails to mount the partition. It is not
> >> something easily enough to reproduce, but it has failed on 5 boards out
> >> of 30 we have.
> > I remember warning you about that problem before: MLC NANDs are not as
> > reliable as SLC ones (please read my presentation about MLC support in
> > Linux [1]). I also remember recommending using an SLC chip if you were
> > tight on time to avoid dealing with all these MLC related problems, but
> > you decided to go for the MLC solution.
> >
> > Back to your problem now, what you're seeing here is probably caused by
> > interrupted PROGRAM operations on paired pages (page 17, 18 and 26 to 32
> > of my presentation for more information).
> In his defence; we looked at it, and from what we could tell it is not 
> possible to find an affordable SLC chip that the Allwinner A10/A20 
> BootROM would even boot from. In general, chips below 8K page size 
> require 64-bit EEC strength to operate, which in turn required more OOB 
> area than any chip would provide. This limitation is in my opinion a 
> design fault from AllWinners side and I hope that their future SoCs can 
> boot with more relaxed EEC settings to facilitate for cheap SLC chips, 
> but right now there is nothing we can do to change that situation.

Hm, according to this table [1], it also tries the 64bit/512bytes
scheme, which should fit in most SLC NANDs (if you have a NAND with 2k
+ 64byte pages, and you only use 512 bytes per page it leaves 1600 bytes
for your ECC data).
This being said, supporting this kind of layout in Linux can be
complicated: I remember we (Roy and I) tried to patch the nand part code
to tweak the data/oob repartition for this case, but we didn't manage
to get it to work.

> >> U-boot reports the following:
> >> UBI: default fastmap pool size: 100
> >> UBI: default fastmap WL pool size: 25
> >> UBI: attaching mtd1 to ubi0
> >> UBI: scanning is finished
> >> UBI init error 22
> >> Error reading superblock on volume 'ubi:boot' errno=-19!
> >> ubifsmount - mount UBIFS volume
> >>
> >> whereas the linux kernel booted from sd card gives:
> >> ubiattach /dev/ubi_ctrl -m 0
> >> [  100.560704] ubi0: default fastmap pool size: 8
> >> [  100.565186] ubi0: default fastmap WL pool size: 4
> >> [  100.570100] ubi0: attaching mtd0
> >> [  100.590469] ubi0: scanning is finished
> >> [  100.594732] ubi0 error: ubi_read_volume_table: the layout volume was
> >> not found
> >> [  100.602675] ubi0 error: ubi_attach_mtd_dev: failed to attach mtd0,
> >> error -22
> >> ubiattach: error!: cannot attach mtd0
> >>              error 22 (Invalid argument)
> >>
> >> The u-boot version we are using is a few months out of date
> >> U-Boot 2015.07-rc2-g2540c39 (Aug 04 2015 - 16:09:02 +0200) Allwinner
> >> Technology
> >> arm-none-eabi-gcc (4.8.4-1+11-1) 4.8.4 20141219 (release)
> >> GNU ld (2.25-5+5+b1) 2.25
> >>
> >> but the kernel is fairly up to date:
> >> 4.2.0-rc4-opinicus-g8ec3671
> >>
> >>
> >> Now I know that the mtd stuff is all very new and all very untested,
> >> what I am curious about is a) have other people actually tried the mtd
> >> stuff on Allwinner hardware, and b) has anybody encountered this issue
> >> as well?
> > Yes we did. So far we're using the NAND in SLC mode to address this
> > problem. It seems to work, but you also loose half the NAND capacity.
> So as requested by someone else: how exactly does that work? Can we just 
> give your NAND driver a mapping between shared pages and instruct it to 
> ignore half, or does the driver require some serious patchery?

I only have a prototype for this SLC mode, and the code is available
here [2].
In short, the NAND core layer checks for SLC mode activation, and if it
is activated it only exposes half the erase block capacity.
This also requires some chip specific code to enable/disable the SLC
mode and adjust the row/column addresses before passing them to the
controller driver.
Note that SLC mode can be enabled by partitions, which let us declare
the SPL partition in MLC mode so that BROM can still load the SPL.

Best Regards,

Boris

[1]http://linux-sunxi.org/NAND#More_information_on_BROM_NAND
[2]https://github.com/NextThingCo/CHIP-linux/tree/nextthing/4.2/chip-nand-slc-mode

-- 
Boris Brezillon, Free Electrons
Embedded Linux and Kernel engineering
http://free-electrons.com


From lftan at altera.com  Mon Aug 17 02:09:34 2015
From: lftan at altera.com (Ley Foon Tan)
Date: Mon, 17 Aug 2015 17:09:34 +0800
Subject: [PATCH v4 0/5] Altera PCIe host controller driver with MSI support
Message-ID: <1439802579-22651-1-git-send-email-lftan@altera.com>

This is the 4th version of patch set to add support for Altera PCIe host
controller with MSI feature on Altera FPGA device families. This patchset
mainly resolve comments from Marc Zyngier in v3.

It is based on patch series from Marc Zyngier "Per-device MSI domain &
platform MSI" [1] to get rid of struct msi_controller.

v3->v4 changes:
- pcie-altera: change to incremental count for loop
- pcie-altera: add udelay when polling
- pcie-altera: return -ENOMEM for irq_domain_add_linear error
- pcie-altera-msi: add WARN_ON(nr_irq) != 1
- update error handling for platform_get_resource_byname

History:
-------
[v1]: https://lkml.org/lkml/2015/7/28/395
[v2]: https://lkml.org/lkml/2015/7/31/267
[v3]: http://www.kernelhub.org/?msg=811940&p=2

Ley Foon Tan (5):
  arm: add msi.h to Kbuild
  pci:host: Add Altera PCIe host controller driver
  pci: altera: Add Altera PCIe MSI driver
  Documentation: dt-bindings: pci: altera pcie device tree binding
  MAINTAINERS: Add Altera PCIe and MSI drivers maintainer

 .../devicetree/bindings/pci/altera-pcie-msi.txt    |  27 +
 .../devicetree/bindings/pci/altera-pcie.txt        |  49 ++
 MAINTAINERS                                        |  16 +
 arch/arm/include/asm/Kbuild                        |   1 +
 drivers/pci/host/Kconfig                           |  15 +
 drivers/pci/host/Makefile                          |   2 +
 drivers/pci/host/pcie-altera-msi.c                 | 322 ++++++++++++
 drivers/pci/host/pcie-altera.c                     | 543 +++++++++++++++++++++
 8 files changed, 975 insertions(+)
 create mode 100644 Documentation/devicetree/bindings/pci/altera-pcie-msi.txt
 create mode 100644 Documentation/devicetree/bindings/pci/altera-pcie.txt
 create mode 100644 drivers/pci/host/pcie-altera-msi.c
 create mode 100644 drivers/pci/host/pcie-altera.c

-- 
1.8.2.1



From lftan at altera.com  Mon Aug 17 02:09:35 2015
From: lftan at altera.com (Ley Foon Tan)
Date: Mon, 17 Aug 2015 17:09:35 +0800
Subject: [PATCH v4 1/5] arm: add msi.h to Kbuild
In-Reply-To: <1439802579-22651-1-git-send-email-lftan@altera.com>
References: <1439802579-22651-1-git-send-email-lftan@altera.com>
Message-ID: <1439802579-22651-2-git-send-email-lftan@altera.com>

Include asm-generic/msi.h to support CONFIG_GENERIC_MSI_IRQ_DOMAIN.
This to fix compilation error:
"include/linux/msi.h:123:21: fatal error: asm/msi.h:
No such file or directory"

Signed-off-by: Ley Foon Tan <lftan at altera.com>
---
 arch/arm/include/asm/Kbuild | 1 +
 1 file changed, 1 insertion(+)

diff --git a/arch/arm/include/asm/Kbuild b/arch/arm/include/asm/Kbuild
index 83c5019..ddc2761 100644
--- a/arch/arm/include/asm/Kbuild
+++ b/arch/arm/include/asm/Kbuild
@@ -14,6 +14,7 @@ generic-y += local.h
 generic-y += local64.h
 generic-y += mcs_spinlock.h
 generic-y += msgbuf.h
+generic-y += msi.h
 generic-y += param.h
 generic-y += parport.h
 generic-y += poll.h
-- 
1.8.2.1



From lftan at altera.com  Mon Aug 17 02:09:36 2015
From: lftan at altera.com (Ley Foon Tan)
Date: Mon, 17 Aug 2015 17:09:36 +0800
Subject: [PATCH v4 2/5] pci:host: Add Altera PCIe host controller driver
In-Reply-To: <1439802579-22651-1-git-send-email-lftan@altera.com>
References: <1439802579-22651-1-git-send-email-lftan@altera.com>
Message-ID: <1439802579-22651-3-git-send-email-lftan@altera.com>

This patch adds the Altera PCIe host controller driver.

Signed-off-by: Ley Foon Tan <lftan at altera.com>
---
 drivers/pci/host/Kconfig       |   7 +
 drivers/pci/host/Makefile      |   1 +
 drivers/pci/host/pcie-altera.c | 543 +++++++++++++++++++++++++++++++++++++++++
 3 files changed, 551 insertions(+)
 create mode 100644 drivers/pci/host/pcie-altera.c

diff --git a/drivers/pci/host/Kconfig b/drivers/pci/host/Kconfig
index 675c2d1..4b4754a 100644
--- a/drivers/pci/host/Kconfig
+++ b/drivers/pci/host/Kconfig
@@ -145,4 +145,11 @@ config PCIE_IPROC_BCMA
 	  Say Y here if you want to use the Broadcom iProc PCIe controller
 	  through the BCMA bus interface
 
+config PCIE_ALTERA
+	tristate "Altera PCIe controller"
+	depends on ARCH_SOCFPGA
+	help
+	  Say Y here if you want to enable PCIe controller support for Altera
+	  SoCFPGA family of SoCs.
+
 endmenu
diff --git a/drivers/pci/host/Makefile b/drivers/pci/host/Makefile
index 140d66f..6954f76 100644
--- a/drivers/pci/host/Makefile
+++ b/drivers/pci/host/Makefile
@@ -17,3 +17,4 @@ obj-$(CONFIG_PCI_VERSATILE) += pci-versatile.o
 obj-$(CONFIG_PCIE_IPROC) += pcie-iproc.o
 obj-$(CONFIG_PCIE_IPROC_PLATFORM) += pcie-iproc-platform.o
 obj-$(CONFIG_PCIE_IPROC_BCMA) += pcie-iproc-bcma.o
+obj-$(CONFIG_PCIE_ALTERA) += pcie-altera.o
diff --git a/drivers/pci/host/pcie-altera.c b/drivers/pci/host/pcie-altera.c
new file mode 100644
index 0000000..130796e
--- /dev/null
+++ b/drivers/pci/host/pcie-altera.c
@@ -0,0 +1,543 @@
+/*
+ * Copyright Altera Corporation (C) 2013-2015. All rights reserved
+ *
+ * This program is free software; you can redistribute it and/or modify it
+ * under the terms and conditions of the GNU General Public License,
+ * version 2, as published by the Free Software Foundation.
+ *
+ * This program is distributed in the hope 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.
+ *
+ * You should have received a copy of the GNU General Public License along with
+ * this program.  If not, see <http://www.gnu.org/licenses/>.
+ */
+#include <linux/delay.h>
+#include <linux/interrupt.h>
+#include <linux/irqchip/chained_irq.h>
+#include <linux/module.h>
+#include <linux/of_address.h>
+#include <linux/of_irq.h>
+#include <linux/of_pci.h>
+#include <linux/pci.h>
+#include <linux/platform_device.h>
+#include <linux/slab.h>
+
+#define A2P_ADDR_MAP_LO0		0x1000
+#define A2P_ADDR_MAP_HI0		0x1004
+#define RP_TX_REG0			0x2000
+#define RP_TX_REG1			0x2004
+#define RP_TX_CNTRL			0x2008
+#define RP_TX_EOP			0x2
+#define RP_TX_SOP			0x1
+#define RP_RXCPL_STATUS		0x2010
+#define RP_RXCPL_EOP			0x2
+#define RP_RXCPL_SOP			0x1
+#define RP_RXCPL_REG0			0x2014
+#define RP_RXCPL_REG1			0x2018
+#define P2A_INT_STATUS			0x3060
+#define P2A_INT_STS_ALL			0xF
+#define P2A_INT_ENABLE			0x3070
+#define P2A_INT_ENA_ALL			0xF
+#define RP_LTSSM			0x3C64
+#define LTSSM_L0			0xF
+
+/* TLP configuration type 0 and 1 */
+#define TLP_FMTTYPE_CFGRD0		0x04	/* Configuration Read Type 0 */
+#define TLP_FMTTYPE_CFGWR0		0x44	/* Configuration Write Type 0 */
+#define TLP_FMTTYPE_CFGRD1		0x05	/* Configuration Read Type 1 */
+#define TLP_FMTTYPE_CFGWR1		0x45	/* Configuration Write Type 1 */
+#define TLP_PAYLOAD_SIZE		0x01
+#define TLP_READ_TAG			0x1D
+#define TLP_WRITE_TAG			0x10
+#define TLP_CFG_DW0(fmttype)		(((fmttype) << 24) | TLP_PAYLOAD_SIZE)
+#define TLP_CFG_DW1(reqid, tag)		(((reqid) << 16) | (tag << 8) | 0xF)
+#define TLP_CFG_DW2(bus, devfn, offset)	\
+				(((bus) << 24) | ((devfn) << 16) | (offset))
+#define TLP_REQ_ID(bus, devfn)		(((bus) << 8) | (devfn))
+#define TLP_COMPL_STATUS(hdr)		(((hdr) & 0xE0) >> 13)
+#define TLP_HDR_SIZE			3
+#define TLP_LOOP			10
+
+#define INTX_NUM		4
+
+/* Address translation table entry size */
+#define ATT_ENTRY_SIZE		8
+
+#define DWORD_MASK		3
+
+struct altera_pcie {
+	struct platform_device	*pdev;
+	struct resource		*txs;
+	void __iomem		*cra_base;
+	int			irq;
+	u8			root_bus_nr;
+	struct irq_domain		*irq_domain;
+	struct resource		bus_range;
+	struct list_head		resources;
+};
+
+struct tlp_rp_regpair_t {
+	u32 ctrl;
+	u32 reg0;
+	u32 reg1;
+};
+
+static void altera_pcie_retrain(struct pci_dev *dev)
+{
+	u16 linkcap, linkstat;
+
+	/*
+	 * Set the retrain bit if the PCIe rootport support > 2.5GB/s, but
+	 * current speed is 2.5 GB/s.
+	 */
+	pcie_capability_read_word(dev, PCI_EXP_LNKCAP, &linkcap);
+
+	if ((linkcap & PCI_EXP_LNKCAP_SLS) <= PCI_EXP_LNKCAP_SLS_2_5GB)
+		return;
+
+	pcie_capability_read_word(dev, PCI_EXP_LNKSTA, &linkstat);
+	if ((linkstat & PCI_EXP_LNKSTA_CLS) == PCI_EXP_LNKSTA_CLS_2_5GB)
+		pcie_capability_set_word(dev, PCI_EXP_LNKCTL,
+					 PCI_EXP_LNKCTL_RL);
+}
+DECLARE_PCI_FIXUP_EARLY(PCI_ANY_ID, PCI_ANY_ID, altera_pcie_retrain);
+
+static inline void cra_writel(struct altera_pcie *pcie, u32 value, u32 reg)
+{
+	writel_relaxed(value, pcie->cra_base + reg);
+}
+
+static inline u32 cra_readl(struct altera_pcie *pcie, u32 reg)
+{
+	return readl_relaxed(pcie->cra_base + reg);
+}
+
+static void tlp_read_rx(struct altera_pcie *pcie,
+			struct tlp_rp_regpair_t *tlp_rp_regdata)
+{
+	tlp_rp_regdata->ctrl = cra_readl(pcie, RP_RXCPL_STATUS);
+	tlp_rp_regdata->reg0 = cra_readl(pcie, RP_RXCPL_REG0);
+	tlp_rp_regdata->reg1 = cra_readl(pcie, RP_RXCPL_REG1);
+}
+
+static void tlp_write_tx(struct altera_pcie *pcie,
+			 struct tlp_rp_regpair_t *tlp_rp_regdata)
+{
+	cra_writel(pcie, tlp_rp_regdata->reg0, RP_TX_REG0);
+	cra_writel(pcie, tlp_rp_regdata->reg1, RP_TX_REG1);
+	cra_writel(pcie, tlp_rp_regdata->ctrl, RP_TX_CNTRL);
+}
+
+static bool altera_pcie_link_is_up(struct altera_pcie *pcie)
+{
+	return !!(cra_readl(pcie, RP_LTSSM) & LTSSM_L0);
+}
+
+static bool altera_pcie_valid_config(struct altera_pcie *pcie,
+				     struct pci_bus *bus, int dev)
+{
+	/* If there is no link, then there is no device */
+	if (bus->number != pcie->root_bus_nr) {
+		if (!altera_pcie_link_is_up(pcie))
+			return false;
+	}
+
+	/* access only one slot on each root port */
+	if (bus->number == pcie->root_bus_nr && dev > 0)
+		return false;
+
+	/*
+	 * Do not read more than one device on the bus directly attached
+	 * to RC.
+	 */
+	if (bus->primary == pcie->root_bus_nr && dev > 0)
+		return false;
+
+	 return true;
+}
+
+static int tlp_read_packet(struct altera_pcie *pcie, u32 *value)
+{
+	u8 loop;
+	struct tlp_rp_regpair_t tlp_rp_regdata;
+
+	for (loop = 0; loop < TLP_LOOP; loop++) {
+		tlp_read_rx(pcie, &tlp_rp_regdata);
+		if (tlp_rp_regdata.ctrl & RP_RXCPL_EOP) {
+			if (value)
+				*value = tlp_rp_regdata.reg0;
+			return PCIBIOS_SUCCESSFUL;
+		}
+		udelay(5);
+	}
+
+	return -ENOENT;
+}
+
+static void tlp_write_packet(struct altera_pcie *pcie, u32 *headers, u32 data)
+{
+	struct tlp_rp_regpair_t tlp_rp_regdata;
+
+	tlp_rp_regdata.reg0 = headers[0];
+	tlp_rp_regdata.reg1 = headers[1];
+	tlp_rp_regdata.ctrl = RP_TX_SOP;
+	tlp_write_tx(pcie, &tlp_rp_regdata);
+
+	tlp_rp_regdata.reg0 = headers[2];
+	tlp_rp_regdata.reg1 = data;
+	tlp_rp_regdata.ctrl = RP_TX_EOP;
+	tlp_write_tx(pcie, &tlp_rp_regdata);
+}
+
+static int tlp_cfg_dword_read(struct altera_pcie *pcie, u8 bus, u32 devfn,
+			      int where, u32 *value)
+{
+	int ret;
+	u32 headers[TLP_HDR_SIZE];
+
+	if (bus == pcie->root_bus_nr)
+		headers[0] = TLP_CFG_DW0(TLP_FMTTYPE_CFGRD0);
+	else
+		headers[0] = TLP_CFG_DW0(TLP_FMTTYPE_CFGRD1);
+
+	headers[1] = TLP_CFG_DW1(TLP_REQ_ID(pcie->root_bus_nr, devfn),
+					TLP_READ_TAG);
+	headers[2] = TLP_CFG_DW2(bus, devfn, where);
+
+	tlp_write_packet(pcie, headers, 0);
+
+	ret = tlp_read_packet(pcie, value);
+	if (ret)
+		*value = ~0UL;	/* return 0xFFFFFFFF if error */
+
+	return ret;
+}
+
+static int tlp_cfg_dword_write(struct altera_pcie *pcie, u8 bus, u32 devfn,
+			       int where, u32 value)
+{
+	u32 headers[TLP_HDR_SIZE];
+
+	if (bus == pcie->root_bus_nr)
+		headers[0] = TLP_CFG_DW0(TLP_FMTTYPE_CFGWR0);
+	else
+		headers[0] = TLP_CFG_DW0(TLP_FMTTYPE_CFGWR1);
+
+	headers[1] = TLP_CFG_DW1(TLP_REQ_ID(pcie->root_bus_nr, devfn),
+					TLP_WRITE_TAG);
+	headers[2] = TLP_CFG_DW2(bus, devfn, where);
+
+	tlp_write_packet(pcie, headers, value);
+
+	tlp_read_packet(pcie, NULL);
+
+	/* Keep an eye out for changes to the root bus number */
+	if ((bus == pcie->root_bus_nr) && (where == PCI_PRIMARY_BUS))
+		pcie->root_bus_nr = (u8)(value);
+
+	return PCIBIOS_SUCCESSFUL;
+}
+
+static int altera_pcie_cfg_read(struct pci_bus *bus, unsigned int devfn,
+				int where, int size, u32 *value)
+{
+	struct altera_pcie *pcie = bus->sysdata;
+	int ret;
+
+	if (!altera_pcie_valid_config(pcie, bus, PCI_SLOT(devfn))) {
+		*value = ~0UL;
+		return PCIBIOS_DEVICE_NOT_FOUND;
+	}
+
+	ret = tlp_cfg_dword_read(pcie, bus->number, devfn,
+				 (where & ~DWORD_MASK), value);
+	if (ret != PCIBIOS_SUCCESSFUL)
+		return ret;
+
+	if (size == 1)
+		*value = (*value >> (8 * (where & 0x3))) & 0xff;
+	else if (size == 2)
+		*value = (*value >> (8 * (where & 0x2))) & 0xffff;
+
+	return PCIBIOS_SUCCESSFUL;
+}
+
+static int altera_pcie_cfg_write(struct pci_bus *bus, unsigned int devfn,
+				 int where, int size, u32 value)
+{
+	struct altera_pcie *pcie = bus->sysdata;
+	u32 data32 = value;
+	u32 shift = 8 * (where & 3);
+	int ret;
+
+	if (!altera_pcie_valid_config(pcie, bus, PCI_SLOT(devfn)))
+		return PCIBIOS_DEVICE_NOT_FOUND;
+
+	/* write partial */
+	if (size != sizeof(u32)) {
+		ret = tlp_cfg_dword_read(pcie, bus->number, devfn,
+					 where & ~DWORD_MASK, &data32);
+		if (ret)
+			return ret;
+
+		if (size == 2)
+			data32 = (data32 & ~(0xffff << shift)) |
+					((value & 0xffff) << shift);
+		 else if (size == 1)
+			data32 = (data32 & ~(0xff << shift)) |
+					((value & 0xff) << shift);
+	}
+
+	return tlp_cfg_dword_write(pcie, bus->number, devfn,
+		(where & ~DWORD_MASK), data32);
+}
+
+static struct pci_ops altera_pcie_ops = {
+	.read = altera_pcie_cfg_read,
+	.write = altera_pcie_cfg_write,
+};
+
+static int altera_pcie_intx_map(struct irq_domain *domain, unsigned int irq,
+				irq_hw_number_t hwirq)
+{
+	irq_set_chip_and_handler(irq, &dummy_irq_chip, handle_simple_irq);
+	irq_set_chip_data(irq, domain->host_data);
+	set_irq_flags(irq, IRQF_VALID);
+
+	return 0;
+}
+
+static const struct irq_domain_ops intx_domain_ops = {
+	.map = altera_pcie_intx_map,
+};
+
+static void altera_pcie_isr(unsigned int irq, struct irq_desc *desc)
+{
+	struct irq_chip *chip = irq_desc_get_chip(desc);
+	struct altera_pcie *pcie;
+	unsigned long status;
+	u32 bit;
+	u32 virq;
+
+	chained_irq_enter(chip, desc);
+	pcie = irq_desc_get_handler_data(desc);
+
+	do {
+		status = cra_readl(pcie, P2A_INT_STATUS) & P2A_INT_STS_ALL;
+		if (!status)
+			break;
+
+		do {
+			bit = find_first_bit(&status, INTX_NUM);
+			/* clear interrupts */
+			cra_writel(pcie, 1 << bit, P2A_INT_STATUS);
+
+			virq = irq_find_mapping(pcie->irq_domain, bit + 1);
+			if (virq)
+				generic_handle_irq(virq);
+			else
+				dev_info(&pcie->pdev->dev, "unexpected IRQ\n");
+
+			/* Clear the bit from status and repeat without reading
+			 * again status register. */
+			__clear_bit(bit, &status);
+		} while (status);
+	} while (1);
+
+	chained_irq_exit(chip, desc);
+}
+
+static void altera_pcie_release_of_pci_ranges(struct altera_pcie *pcie)
+{
+	pci_free_resource_list(&pcie->resources);
+}
+
+static int altera_pcie_parse_request_of_pci_ranges(struct altera_pcie *pcie)
+{
+	int err, res_valid = 0;
+	struct device *dev = &pcie->pdev->dev;
+	struct device_node *np = dev->of_node;
+	resource_size_t iobase;
+	struct resource_entry *win;
+
+	err = of_pci_get_host_bridge_resources(np, 0, 0xff, &pcie->resources,
+					       &iobase);
+	if (err)
+		return err;
+
+	resource_list_for_each_entry(win, &pcie->resources) {
+		struct resource *parent, *res = win->res;
+
+		switch (resource_type(res)) {
+		case IORESOURCE_MEM:
+			parent = &iomem_resource;
+			res_valid |= !(res->flags & IORESOURCE_PREFETCH);
+			break;
+		default:
+			continue;
+		}
+
+		err = devm_request_resource(dev, parent, res);
+		if (err)
+			goto out_release_res;
+	}
+
+	if (!res_valid) {
+		dev_err(dev, "non-prefetchable memory resource required\n");
+		err = -EINVAL;
+		goto out_release_res;
+	}
+
+	return 0;
+
+out_release_res:
+	altera_pcie_release_of_pci_ranges(pcie);
+	return err;
+}
+
+static void altera_pcie_free_irq_domain(struct altera_pcie *pcie)
+{
+	int i;
+	u32 irq;
+
+	for (i = 0; i < INTX_NUM; i++) {
+		irq = irq_find_mapping(pcie->irq_domain, i);
+		if (irq > 0)
+			irq_dispose_mapping(irq);
+	}
+
+	irq_domain_remove(pcie->irq_domain);
+}
+
+static int altera_pcie_init_irq_domain(struct altera_pcie *pcie)
+{
+	struct device *dev = &pcie->pdev->dev;
+	struct device_node *node = dev->of_node;
+
+	/* Setup INTx */
+	pcie->irq_domain = irq_domain_add_linear(node, INTX_NUM,
+					&intx_domain_ops, pcie);
+	if (!pcie->irq_domain) {
+		dev_err(dev, "Failed to get a INTx IRQ domain\n");
+		return -ENOMEM;
+	}
+
+	return 0;
+}
+
+static int altera_pcie_parse_dt(struct altera_pcie *pcie)
+{
+	struct resource *cra;
+	struct platform_device *pdev = pcie->pdev;
+
+	cra = platform_get_resource_byname(pdev, IORESOURCE_MEM, "Cra");
+	if (!cra) {
+		cra = platform_get_resource_byname(pdev, IORESOURCE_MEM, "cra");
+		if (!cra) {
+			dev_err(&pdev->dev,
+				"no cra memory resource defined\n");
+			return -ENODEV;
+		}
+	}
+
+	pcie->cra_base = devm_ioremap_resource(&pdev->dev, cra);
+	if (IS_ERR(pcie->cra_base)) {
+		dev_err(&pdev->dev, "failed to map cra memory\n");
+		return PTR_ERR(pcie->cra_base);
+	}
+
+	/* setup IRQ */
+	pcie->irq = platform_get_irq(pdev, 0);
+	if (pcie->irq <= 0) {
+		dev_err(&pdev->dev, "failed to get IRQ: %d\n", pcie->irq);
+		return -EINVAL;
+	}
+
+	irq_set_chained_handler_and_data(pcie->irq, altera_pcie_isr, pcie);
+
+	return 0;
+}
+
+static int altera_pcie_probe(struct platform_device *pdev)
+{
+	struct altera_pcie *pcie;
+	struct pci_bus *bus;
+	int ret;
+
+	pcie = devm_kzalloc(&pdev->dev, sizeof(*pcie), GFP_KERNEL);
+	if (!pcie)
+		return -ENOMEM;
+
+	pcie->pdev = pdev;
+
+	ret = altera_pcie_parse_dt(pcie);
+	if (ret) {
+		dev_err(&pdev->dev, "Parsing DT failed\n");
+		return ret;
+	}
+
+	INIT_LIST_HEAD(&pcie->resources);
+
+	ret = altera_pcie_parse_request_of_pci_ranges(pcie);
+	if (ret) {
+		dev_err(&pdev->dev, "Failed add resources\n");
+		return ret;
+	}
+
+	ret = altera_pcie_init_irq_domain(pcie);
+	if (ret) {
+		dev_err(&pdev->dev, "Failed creating IRQ Domain\n");
+		return ret;
+	}
+
+	pcie->root_bus_nr = 0;
+
+	/* clear all interrupts */
+	cra_writel(pcie, P2A_INT_STS_ALL, P2A_INT_STATUS);
+	/* enable all interrupts */
+	cra_writel(pcie, P2A_INT_ENA_ALL, P2A_INT_ENABLE);
+
+	bus = pci_scan_root_bus(&pdev->dev, pcie->root_bus_nr, &altera_pcie_ops,
+				pcie, &pcie->resources);
+	if (!bus)
+		return -ENOMEM;
+
+	pci_fixup_irqs(pci_common_swizzle, of_irq_parse_and_map_pci);
+	pci_assign_unassigned_bus_resources(bus);
+	pci_bus_add_devices(bus);
+
+	platform_set_drvdata(pdev, pcie);
+	return ret;
+}
+
+static int __exit altera_pcie_remove(struct platform_device *pdev)
+{
+	struct altera_pcie *pcie = platform_get_drvdata(pdev);
+
+	altera_pcie_free_irq_domain(pcie);
+	platform_set_drvdata(pdev, NULL);
+	return 0;
+}
+
+static const struct of_device_id altera_pcie_of_match[] = {
+	{ .compatible = "altr,pcie-root-port-1.0", },
+	{},
+};
+MODULE_DEVICE_TABLE(of, altera_pcie_of_match);
+
+static struct platform_driver altera_pcie_driver = {
+	.probe		= altera_pcie_probe,
+	.remove		= altera_pcie_remove,
+	.driver = {
+		.name	= "altera-pcie",
+		.of_match_table = altera_pcie_of_match,
+	},
+};
+
+module_platform_driver(altera_pcie_driver);
+
+MODULE_AUTHOR("Ley Foon Tan <lftan at altera.com>");
+MODULE_DESCRIPTION("Altera PCIe host controller driver");
+MODULE_LICENSE("GPL v2");
-- 
1.8.2.1



From djkurtz at chromium.org  Mon Aug 17 02:09:32 2015
From: djkurtz at chromium.org (Daniel Kurtz)
Date: Mon, 17 Aug 2015 17:09:32 +0800
Subject: [PATCH v4] pinctrl: mediatek: Implement wake handler and suspend
 resume
In-Reply-To: <1439797974.22004.2.camel@mtksdaap41>
References: <1439541486-22203-1-git-send-email-maoguang.meng@mediatek.com>
 <1439797974.22004.2.camel@mtksdaap41>
Message-ID: <CAGS+omCQN65pCP7mYFCj8sDOihLNc15GgELw1u7fTXuq=KBXnw@mail.gmail.com>

On Mon, Aug 17, 2015 at 3:52 PM, Yingjoe Chen <yingjoe.chen at mediatek.com> wrote:
> On Fri, 2015-08-14 at 16:38 +0800, maoguang.meng at mediatek.com wrote:
>> From: Maoguang Meng <maoguang.meng at mediatek.com>
>>
>> This patch implement irq_set_wake to get who is wakeup source and
>> setup on suspend resume.
>>
>> Signed-off-by: Maoguang Meng <maoguang.meng at mediatek.com>
>>
>> ---
>> changes since v3:
>> -add a comment in mtk_eint_chip_read_mask.
>> -delete ALIGN when allocate eint_offsets.ports.
>> -fix unrelated change.
>>
>> changes since v2:
>> -modify irq_wake to handle irq wakeup source.
>> -allocate two buffers separately.
>> -fix some codestyle.
>>
>> Changes since v1:
>> -implement irq_wake handler.
>> ---
>>
>>  drivers/pinctrl/mediatek/pinctrl-mt8173.c     |  1 +
>>  drivers/pinctrl/mediatek/pinctrl-mtk-common.c | 91 ++++++++++++++++++++++++++-
>>  drivers/pinctrl/mediatek/pinctrl-mtk-common.h |  4 ++
>>  3 files changed, 95 insertions(+), 1 deletion(-)
>>
>> diff --git a/drivers/pinctrl/mediatek/pinctrl-mt8173.c b/drivers/pinctrl/mediatek/pinctrl-mt8173.c
>> index d0c811d..ad27184 100644
>> --- a/drivers/pinctrl/mediatek/pinctrl-mt8173.c
>> +++ b/drivers/pinctrl/mediatek/pinctrl-mt8173.c
>> @@ -385,6 +385,7 @@ static struct platform_driver mtk_pinctrl_driver = {
>>       .driver = {
>>               .name = "mediatek-mt8173-pinctrl",
>>               .of_match_table = mt8173_pctrl_match,
>> +             .pm = &mtk_eint_pm_ops,
>>       },
>>  };
>>
>> diff --git a/drivers/pinctrl/mediatek/pinctrl-mtk-common.c b/drivers/pinctrl/mediatek/pinctrl-mtk-common.c
>> index ad1ea16..fe34ce9 100644
>> --- a/drivers/pinctrl/mediatek/pinctrl-mtk-common.c
>> +++ b/drivers/pinctrl/mediatek/pinctrl-mtk-common.c
>> @@ -33,6 +33,7 @@
>>  #include <linux/mfd/syscon.h>
>>  #include <linux/delay.h>
>>  #include <linux/interrupt.h>
>> +#include <linux/pm.h>
>>  #include <dt-bindings/pinctrl/mt65xx.h>
>>
>>  #include "../core.h"
>> @@ -1062,6 +1063,77 @@ static int mtk_eint_set_type(struct irq_data *d,
>>       return 0;
>>  }
>>
>> +static int mtk_eint_irq_set_wake(struct irq_data *d, unsigned int on)
>> +{
>> +     struct mtk_pinctrl *pctl = irq_data_get_irq_chip_data(d);
>> +     int shift = d->hwirq & 0x1f;
>> +     int reg = d->hwirq >> 5;
>> +
>> +     if (on)
>> +             pctl->wake_mask[reg] |= BIT(shift);
>> +     else
>> +             pctl->wake_mask[reg] &= ~BIT(shift);
>> +
>> +     return 0;
>> +}
>
> Hi Maoguang,
>
> You changed from set_bit/clear_bit to this, but didn't add any locking.
> Since this is basic read/modify/write, is it OK to do it without
> locking?

I believe calling .irq_set_wake() concurrently with itself is
protected by irq_get_desc_buslock():

 int irq_set_irq_wake(unsigned int irq, unsigned int on)
 {
         unsigned long flags;
         struct irq_desc *desc = irq_get_desc_buslock(irq, &flags,
IRQ_GET_DESC_CHECK_GLOBAL);
         int ret = 0;
...
                         ret = set_irq_wake_real(irq, on);
...
         irq_put_desc_busunlock(desc, flags);
         return ret;
 }


I'm not 100% sure about the .suspend/.resume paths, but I don't think
they can occur during .irq_set_wake(), either.
Nor were they protected by the set_bit/clear_bit implementation.

-Dan


>
> Joe.C
>
>
> --
> To unsubscribe from this list: send the line "unsubscribe linux-kernel" in
> the body of a message to majordomo at vger.kernel.org
> More majordomo info at  http://vger.kernel.org/majordomo-info.html
> Please read the FAQ at  http://www.tux.org/lkml/


From lftan at altera.com  Mon Aug 17 02:09:37 2015
From: lftan at altera.com (Ley Foon Tan)
Date: Mon, 17 Aug 2015 17:09:37 +0800
Subject: [PATCH v4 3/5] pci: altera: Add Altera PCIe MSI driver
In-Reply-To: <1439802579-22651-1-git-send-email-lftan@altera.com>
References: <1439802579-22651-1-git-send-email-lftan@altera.com>
Message-ID: <1439802579-22651-4-git-send-email-lftan@altera.com>

This patch adds Altera PCIe MSI driver. This soft IP supports configurable
number of vectors, which is a dts parameter.

Signed-off-by: Ley Foon Tan <lftan at altera.com>
---
 drivers/pci/host/Kconfig           |   8 +
 drivers/pci/host/Makefile          |   1 +
 drivers/pci/host/pcie-altera-msi.c | 322 +++++++++++++++++++++++++++++++++++++
 3 files changed, 331 insertions(+)
 create mode 100644 drivers/pci/host/pcie-altera-msi.c

diff --git a/drivers/pci/host/Kconfig b/drivers/pci/host/Kconfig
index 4b4754a..d28cc6d 100644
--- a/drivers/pci/host/Kconfig
+++ b/drivers/pci/host/Kconfig
@@ -152,4 +152,12 @@ config PCIE_ALTERA
 	  Say Y here if you want to enable PCIe controller support for Altera
 	  SoCFPGA family of SoCs.
 
+config PCIE_ALTERA_MSI
+	bool "Altera PCIe MSI feature"
+	depends on PCI_MSI
+	select PCI_MSI_IRQ_DOMAIN
+	help
+	  Say Y here if you want PCIe MSI support for the Altera SocFPGA SoC.
+	  This MSI driver supports Altera MSI to GIC controller IP.
+
 endmenu
diff --git a/drivers/pci/host/Makefile b/drivers/pci/host/Makefile
index 6954f76..6c4913d 100644
--- a/drivers/pci/host/Makefile
+++ b/drivers/pci/host/Makefile
@@ -18,3 +18,4 @@ obj-$(CONFIG_PCIE_IPROC) += pcie-iproc.o
 obj-$(CONFIG_PCIE_IPROC_PLATFORM) += pcie-iproc-platform.o
 obj-$(CONFIG_PCIE_IPROC_BCMA) += pcie-iproc-bcma.o
 obj-$(CONFIG_PCIE_ALTERA) += pcie-altera.o
+obj-$(CONFIG_PCIE_ALTERA_MSI) += pcie-altera-msi.o
diff --git a/drivers/pci/host/pcie-altera-msi.c b/drivers/pci/host/pcie-altera-msi.c
new file mode 100644
index 0000000..d3ad96f
--- /dev/null
+++ b/drivers/pci/host/pcie-altera-msi.c
@@ -0,0 +1,322 @@
+/*
+ * Copyright Altera Corporation (C) 2013-2015. All rights reserved
+ *
+ * This program is free software; you can redistribute it and/or modify it
+ * under the terms and conditions of the GNU General Public License,
+ * version 2, as published by the Free Software Foundation.
+ *
+ * This program is distributed in the hope 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.
+ *
+ * You should have received a copy of the GNU General Public License along with
+ * this program.  If not, see <http://www.gnu.org/licenses/>.
+ */
+#include <linux/interrupt.h>
+#include <linux/irqchip/chained_irq.h>
+#include <linux/module.h>
+#include <linux/msi.h>
+#include <linux/of_address.h>
+#include <linux/of_irq.h>
+#include <linux/of_pci.h>
+#include <linux/pci.h>
+#include <linux/platform_device.h>
+#include <linux/slab.h>
+
+#define MSI_STATUS		0x0
+#define MSI_ERROR		0x4
+#define MSI_INTMASK		0x8
+
+#define MAX_MSI_VECTORS		32
+struct altera_msi {
+	DECLARE_BITMAP(used, MAX_MSI_VECTORS);
+	struct mutex		lock;	/* proctect used variable */
+	struct platform_device	*pdev;
+	struct irq_domain		*msi_domain;
+	struct irq_domain		*inner_domain;
+	void __iomem		*csr_base;
+	void __iomem		*vector_base;
+	phys_addr_t		vector_phy;
+	u32			num_of_vectors;
+	int			irq;
+};
+
+static inline void msi_writel(struct altera_msi *msi, u32 value, u32 reg)
+{
+	writel_relaxed(value, msi->csr_base + reg);
+}
+
+static inline u32 msi_readl(struct altera_msi *msi, u32 reg)
+{
+	return readl_relaxed(msi->csr_base + reg);
+}
+
+static void altera_msi_isr(unsigned int irq, struct irq_desc *desc)
+{
+	struct irq_chip *chip = irq_desc_get_chip(desc);
+	struct altera_msi *msi;
+	unsigned long status;
+	u32 num_of_vectors;
+	u32 bit;
+	u32 virq;
+
+	chained_irq_enter(chip, desc);
+	msi = irq_desc_get_handler_data(desc);
+	num_of_vectors = msi->num_of_vectors;
+
+	do {
+		status = msi_readl(msi, MSI_STATUS);
+		if (!status)
+			break;
+
+		do {
+			bit = find_first_bit(&status, num_of_vectors);
+			/* Dummy read from vector to clear the interrupt */
+			readl_relaxed(msi->vector_base + (bit * sizeof(u32)));
+
+			virq = irq_find_mapping(msi->inner_domain, bit);
+			if (virq && test_bit(bit, msi->used))
+				generic_handle_irq(virq);
+			else
+				dev_err(&msi->pdev->dev, "unexpected MSI\n");
+
+			/* Clear the bit from status and repeat without reading
+			 * again status register. */
+			__clear_bit(bit, &status);
+		} while (status);
+	} while (1);
+
+	chained_irq_exit(chip, desc);
+}
+
+static struct irq_chip altera_msi_irq_chip = {
+	.name = "Altera PCIe MSI",
+	.irq_enable = pci_msi_unmask_irq,
+	.irq_disable = pci_msi_mask_irq,
+	.irq_mask = pci_msi_mask_irq,
+	.irq_unmask = pci_msi_unmask_irq,
+};
+
+static struct msi_domain_info altera_msi_domain_info = {
+	.flags	= (MSI_FLAG_USE_DEF_DOM_OPS | MSI_FLAG_USE_DEF_CHIP_OPS |
+		     MSI_FLAG_PCI_MSIX),
+	.chip	= &altera_msi_irq_chip,
+};
+
+static void altera_compose_msi_msg(struct irq_data *data, struct msi_msg *msg)
+{
+	struct altera_msi *msi = irq_data_get_irq_chip_data(data);
+	phys_addr_t addr = msi->vector_phy + (data->hwirq * sizeof(u32));
+
+	msg->address_lo = lower_32_bits(addr);
+	msg->address_hi = upper_32_bits(addr);
+	msg->data = data->hwirq;
+
+	dev_dbg(&msi->pdev->dev, "msi#%d address_lo 0x%x address_hi 0x%x\n",
+		(int)data->hwirq, msg->address_hi, msg->address_lo);
+}
+
+static int altera_msi_set_affinity(struct irq_data *irq_data,
+				   const struct cpumask *mask, bool force)
+{
+	 return -EINVAL;
+}
+
+static struct irq_chip altera_msi_bottom_irq_chip = {
+	.name			= "Altera MSI",
+	.irq_compose_msi_msg	= altera_compose_msi_msg,
+	.irq_set_affinity	= altera_msi_set_affinity,
+};
+
+static int altera_irq_domain_alloc(struct irq_domain *domain, unsigned int virq,
+				   unsigned int nr_irqs, void *args)
+{
+	struct altera_msi *msi = domain->host_data;
+	unsigned long bit;
+	u32 mask;
+
+	WARN_ON(nr_irqs != 1);
+	mutex_lock(&msi->lock);
+
+	bit = find_first_zero_bit(msi->used, msi->num_of_vectors);
+	if (bit >= msi->num_of_vectors)
+		return -ENOSPC;
+
+	set_bit(bit, msi->used);
+
+	mutex_unlock(&msi->lock);
+
+	irq_domain_set_info(domain, virq, bit, &altera_msi_bottom_irq_chip,
+			    domain->host_data, handle_simple_irq,
+			    NULL, NULL);
+	set_irq_flags(virq, IRQF_VALID);
+
+	mask = msi_readl(msi, MSI_INTMASK);
+	mask |= 1 << bit;
+	msi_writel(msi, mask, MSI_INTMASK);
+
+	return 0;
+}
+
+static void altera_irq_domain_free(struct irq_domain *domain,
+				   unsigned int virq, unsigned int nr_irqs)
+{
+	struct irq_data *d = irq_domain_get_irq_data(domain, virq);
+	struct altera_msi *msi = irq_data_get_irq_chip_data(d);
+	u32 mask;
+
+	mutex_lock(&msi->lock);
+
+	if (!test_bit(d->hwirq, msi->used)) {
+		dev_err(&msi->pdev->dev, "trying to free unused MSI#%lu\n",
+			d->hwirq);
+	} else {
+		__clear_bit(d->hwirq, msi->used);
+		mask = msi_readl(msi, MSI_INTMASK);
+		mask &= ~(1 << d->hwirq);
+		msi_writel(msi, mask, MSI_INTMASK);
+	}
+
+	mutex_unlock(&msi->lock);
+}
+
+static const struct irq_domain_ops msi_domain_ops = {
+	.alloc	= altera_irq_domain_alloc,
+	.free	= altera_irq_domain_free,
+};
+
+static int altera_allocate_domains(struct altera_msi *msi)
+{
+	msi->inner_domain = irq_domain_add_linear(NULL, msi->num_of_vectors,
+					     &msi_domain_ops, msi);
+	if (!msi->inner_domain) {
+		dev_err(&msi->pdev->dev, "failed to create IRQ domain\n");
+		return -ENOMEM;
+	}
+
+	msi->msi_domain = pci_msi_create_irq_domain(msi->pdev->dev.of_node,
+				&altera_msi_domain_info, msi->inner_domain);
+	if (!msi->msi_domain) {
+		dev_err(&msi->pdev->dev, "failed to create MSI domain\n");
+		irq_domain_remove(msi->inner_domain);
+		return -ENOMEM;
+	}
+
+	return 0;
+}
+
+static void altera_free_domains(struct altera_msi *msi)
+{
+	irq_domain_remove(msi->msi_domain);
+	irq_domain_remove(msi->inner_domain);
+}
+
+static int altera_msi_remove(struct platform_device *pdev)
+{
+	struct altera_msi *msi = platform_get_drvdata(pdev);
+
+	msi_writel(msi, 0, MSI_INTMASK);
+	irq_set_chained_handler(msi->irq, NULL);
+	irq_set_handler_data(msi->irq, NULL);
+
+	altera_free_domains(msi);
+
+	platform_set_drvdata(pdev, NULL);
+	return 0;
+}
+
+static int altera_msi_probe(struct platform_device *pdev)
+{
+	struct altera_msi *msi;
+	struct device_node *np = pdev->dev.of_node;
+	struct resource *res;
+	int ret;
+
+	msi = devm_kzalloc(&pdev->dev, sizeof(struct altera_msi),
+			   GFP_KERNEL);
+	if (!msi)
+		return -ENOMEM;
+
+	mutex_init(&msi->lock);
+	msi->pdev = pdev;
+
+	res = platform_get_resource_byname(pdev, IORESOURCE_MEM, "csr");
+	if (!res) {
+		dev_err(&pdev->dev,
+			"no csr memory resource defined\n");
+		return -ENODEV;
+	}
+
+	msi->csr_base = devm_ioremap_resource(&pdev->dev, res);
+	if (IS_ERR(msi->csr_base)) {
+		dev_err(&pdev->dev, "failed to map csr memory\n");
+		return PTR_ERR(msi->csr_base);
+	}
+
+	res = platform_get_resource_byname(pdev, IORESOURCE_MEM,
+					   "vector_slave");
+	if (!res) {
+		dev_err(&pdev->dev,
+			"no vector_slave memory resource defined\n");
+		return -ENODEV;
+	}
+
+	msi->vector_base = devm_ioremap_resource(&pdev->dev, res);
+	if (IS_ERR(msi->vector_base)) {
+		dev_err(&pdev->dev, "failed to map vector_slave memory\n");
+		return PTR_ERR(msi->vector_base);
+	}
+
+	msi->vector_phy = res->start;
+
+	if (of_property_read_u32(np, "num-vectors", &msi->num_of_vectors)) {
+		dev_err(&pdev->dev, "failed to parse the number of vectors\n");
+		return -EINVAL;
+	}
+
+	ret = altera_allocate_domains(msi);
+	if (ret)
+		return ret;
+
+	msi->irq = platform_get_irq(pdev, 0);
+	if (msi->irq <= 0) {
+		dev_err(&pdev->dev, "failed to map IRQ: %d\n", msi->irq);
+		ret = -ENODEV;
+		goto err;
+	}
+
+	irq_set_chained_handler_and_data(msi->irq, altera_msi_isr, msi);
+	platform_set_drvdata(pdev, msi);
+
+	return 0;
+
+err:
+	altera_msi_remove(pdev);
+	return ret;
+}
+
+static const struct of_device_id altera_msi_of_match[] = {
+	{ .compatible = "altr,msi-1.0", NULL },
+	{ },
+};
+
+static struct platform_driver altera_msi_driver = {
+	.driver = {
+		.name = "altera-msi",
+		.of_match_table = altera_msi_of_match,
+	},
+	.probe = altera_msi_probe,
+	.remove = altera_msi_remove,
+};
+
+static int __init altera_msi_init(void)
+{
+	return platform_driver_register(&altera_msi_driver);
+}
+
+subsys_initcall(altera_msi_init);
+
+MODULE_AUTHOR("Ley Foon Tan <lftan at altera.com>");
+MODULE_DESCRIPTION("Altera PCIe MSI support");
+MODULE_LICENSE("GPL v2");
-- 
1.8.2.1



From lftan at altera.com  Mon Aug 17 02:09:38 2015
From: lftan at altera.com (Ley Foon Tan)
Date: Mon, 17 Aug 2015 17:09:38 +0800
Subject: [PATCH v4 4/5] Documentation: dt-bindings: pci: altera pcie device
 tree binding
In-Reply-To: <1439802579-22651-1-git-send-email-lftan@altera.com>
References: <1439802579-22651-1-git-send-email-lftan@altera.com>
Message-ID: <1439802579-22651-5-git-send-email-lftan@altera.com>

This patch adds the bindings for Altera PCIe host controller driver and
Altera PCIe MSI driver.

Signed-off-by: Ley Foon Tan <lftan at altera.com>
---
 .../devicetree/bindings/pci/altera-pcie-msi.txt    | 27 ++++++++++++
 .../devicetree/bindings/pci/altera-pcie.txt        | 49 ++++++++++++++++++++++
 2 files changed, 76 insertions(+)
 create mode 100644 Documentation/devicetree/bindings/pci/altera-pcie-msi.txt
 create mode 100644 Documentation/devicetree/bindings/pci/altera-pcie.txt

diff --git a/Documentation/devicetree/bindings/pci/altera-pcie-msi.txt b/Documentation/devicetree/bindings/pci/altera-pcie-msi.txt
new file mode 100644
index 0000000..7f330c9
--- /dev/null
+++ b/Documentation/devicetree/bindings/pci/altera-pcie-msi.txt
@@ -0,0 +1,27 @@
+* Altera PCIe MSI controller
+
+Required properties:
+- compatible:	should contain "altr,msi-1.0"
+- reg:		specifies the physical base address of the controller and
+		the length of the memory mapped region.
+- reg-names:	Must include the following entries:
+		"csr": CSR registers
+		"vector_slave": vectors region
+-interrupts:	specifies the interrupt source of the parent interrupt
+		controller. The format of the interrupt specifier depends on the
+		parent interrupt controller.
+- num-vectors:	Number of vectors, range 1 to 32.
+- msi-controller:	indicates that this is MSI controller node
+
+
+Example
+msi0: msi at 0xFF200000 {
+	compatible = "altr,msi-1.0";
+	reg = <0xFF200000 0x00000010
+		0xFF200010 0x00000080>;
+	reg-names = "csr", "vector_slave";
+	interrupt-parent = <&hps_0_arm_gic_0>;
+	interrupts = <0 42 4>;
+	msi-controller = <1>;
+	num-vectors = <32>;
+};
diff --git a/Documentation/devicetree/bindings/pci/altera-pcie.txt b/Documentation/devicetree/bindings/pci/altera-pcie.txt
new file mode 100644
index 0000000..73a8dc0
--- /dev/null
+++ b/Documentation/devicetree/bindings/pci/altera-pcie.txt
@@ -0,0 +1,49 @@
+* Altera PCIe controller
+
+Required properties:
+- compatible :	should contain "altr,pcie-root-port-1.0"
+- reg:		A list of physical base address and length for TXS and CRA.
+- reg-names:	Must include the following entries:
+		"Txs" or "txs": TXS region
+		"Cra" or "cra": Control register access region
+-interrupts:	specifies the interrupt source of the parent interrupt controller.
+		The format of the interrupt specifier depends on the parent interrupt
+		controller.
+- device_type:	must be "pci"
+- #address-cells:	set to <3>
+- #size-cells:	set to <2>
+- #interrupt-cells:	set to <1>
+- ranges:		Describes the translation of addresses for root ports and standard
+		PCI regions.
+- interrupt-map-mask and interrupt-map: standard PCI properties
+	to define the mapping of the PCIe interface to interrupt
+	numbers.
+
+Optional properties:
+- msi-parent:	Link to the hardware entity that serves as the MSI controller for this PCIe
+		controller.
+- bus-range:	PCI bus numbers covered
+
+Example
+	pcie_0: pcie at 0xc00000000 {
+		compatible = "altr,pcie-root-port-1.0";
+		reg = <0xc0000000 0x20000000>,
+			<0xff220000 0x00004000>;
+		reg-names = "Txs", "Cra";
+		interrupt-parent = <&hps_0_arm_gic_0>;
+		interrupts = <0 40 4>;
+		interrupt-controller;
+		#interrupt-cells = <1>;
+		bus-range = <0x0 0xFF>;
+		device_type = "pci";
+		msi-parent = <&msi_to_gic_gen_0>;
+		#address-cells = <3>;
+		#size-cells = <2>;
+		interrupt-map-mask = <0 0 0 7>;
+		interrupt-map = <0 0 0 1 &pcie_0 1>,
+			            <0 0 0 2 &pcie_0 2>,
+			            <0 0 0 3 &pcie_0 3>,
+			            <0 0 0 4 &pcie_0 4>;
+		ranges = <0x82000000 0x00000000 0x00000000 0xc0000000 0x00000000 0x10000000
+			    0x82000000 0x00000000 0x10000000 0xd0000000 0x00000000 0x10000000>;
+	};
-- 
1.8.2.1



From lftan at altera.com  Mon Aug 17 02:09:39 2015
From: lftan at altera.com (Ley Foon Tan)
Date: Mon, 17 Aug 2015 17:09:39 +0800
Subject: [PATCH v4 5/5] MAINTAINERS: Add Altera PCIe and MSI drivers maintainer
In-Reply-To: <1439802579-22651-1-git-send-email-lftan@altera.com>
References: <1439802579-22651-1-git-send-email-lftan@altera.com>
Message-ID: <1439802579-22651-6-git-send-email-lftan@altera.com>

Signed-off-by: Ley Foon Tan <lftan at altera.com>
---
 MAINTAINERS | 16 ++++++++++++++++
 1 file changed, 16 insertions(+)

diff --git a/MAINTAINERS b/MAINTAINERS
index fd60784..32f5287 100644
--- a/MAINTAINERS
+++ b/MAINTAINERS
@@ -7759,6 +7759,14 @@ F:	include/linux/pci*
 F:	arch/x86/pci/
 F:	arch/x86/kernel/quirks.c
 
+PCI DRIVER FOR ALTERA PCIE IP
+M:	Ley Foon Tan <lftan at altera.com>
+L:	rfi at lists.rocketboards.org (moderated for non-subscribers)
+L:	linux-pci at vger.kernel.org
+S:	Supported
+F:	Documentation/devicetree/bindings/pci/altera-pcie.txt
+F:	drivers/pci/host/pcie-altera.c
+
 PCI DRIVER FOR ARM VERSATILE PLATFORM
 M:	Rob Herring <robh at kernel.org>
 L:	linux-pci at vger.kernel.org
@@ -7860,6 +7868,14 @@ L:	linux-pci at vger.kernel.org
 S:	Maintained
 F:	drivers/pci/host/*spear*
 
+PCI MSI DRIVER FOR ALTERA MSI IP
+M:	Ley Foon Tan <lftan at altera.com>
+L:	rfi at lists.rocketboards.org (moderated for non-subscribers)
+L:	linux-pci at vger.kernel.org
+S:	Supported
+F:	Documentation/devicetree/bindings/pci/altera-pcie-msi.txt
+F:	drivers/pci/host/pcie-altera-msi.c
+
 PCI MSI DRIVER FOR APPLIEDMICRO XGENE
 M:	Duc Dang <dhdang at apm.com>
 L:	linux-pci at vger.kernel.org
-- 
1.8.2.1



From linus.walleij at linaro.org  Mon Aug 17 02:11:17 2015
From: linus.walleij at linaro.org (Linus Walleij)
Date: Mon, 17 Aug 2015 11:11:17 +0200
Subject: [PATCH v4 1/6] mfd: fsl imx25 Touchscreen ADC driver
In-Reply-To: <CACRpkdbFcgK69yakt+XYOg2q_QT8R263+FrADzz=r+fYNEFPSg@mail.gmail.com>
References: <1403621185-9581-1-git-send-email-denis@eukrea.com>
 <CACRpkdbFcgK69yakt+XYOg2q_QT8R263+FrADzz=r+fYNEFPSg@mail.gmail.com>
Message-ID: <CACRpkda9LTxmOBXyGDUuhMej4W_waJwYkmay4ELYmQ1zJstSRA@mail.gmail.com>

On Fri, Jun 27, 2014 at 11:18 AM, Linus Walleij
<linus.walleij at linaro.org> wrote:
> On Tue, Jun 24, 2014 at 4:46 PM, Denis Carikli <denis at eukrea.com> wrote:

>> +       irq_set_chip_and_handler(irq, &dummy_irq_chip,
>> +                                handle_level_irq);
>> +       set_irq_flags(irq, IRQF_VALID);
>
> This function only exists on ARM. Unless Kconfig ensures
> this is only available on ARM platforms, use
>
> #ifdef CONFIG_ARM
>       set_irq_flags(irq, IRQF_VALID);
> #else
>       irq_set_noprobe(irq);
> #endif
>
> (Sorry we have no better way of doing it.)

Since I wrote this, there have been cleanups from Rob Herring merged
to the kernel to get rid of this oddity. Please check in linux-next how
to get this right, see c.f. commit
e8d36d5dbb6a6ec4f5222f8775d664ec29d5527d
"ARM: kill off set_irq_flags usage"

Yours,
Linus Walleij


From liguozhu at hisilicon.com  Mon Aug 17 02:17:50 2015
From: liguozhu at hisilicon.com (Kenneth Lee)
Date: Mon, 17 Aug 2015 17:17:50 +0800
Subject: [PATCH 3/5] net: add Hisilicon Network Subsystem MDIO support
In-Reply-To: <2142879.tTtWetb0nc@wuerfel>
References: <1439548222-231611-1-git-send-email-liguozhu@hisilicon.com>
 <1439548222-231611-4-git-send-email-liguozhu@hisilicon.com>
 <2142879.tTtWetb0nc@wuerfel>
Message-ID: <20150817091750.GA134983@Turing-Arch-b>

Thanks, Arnd, 

You are right. This is the same IP as hip04_mdio.c. We just mis-understand the
hardware design. We will merge them and re-submit the patches.

On Fri, Aug 14, 2015 at 10:57:28PM +0200, Arnd Bergmann wrote:
> On Friday 14 August 2015 18:30:20 Kenneth Lee wrote:
> 
> > +#define MDIO_BASE_ADDR                 0x403C0000
> 
> Does not belong in here (and is not used)
> 
> > +#define MDIO_COMMAND_REG               0x0
> > +#define MDIO_ADDR_REG                  0x4
> > +#define MDIO_WDATA_REG                 0x8
> > +#define MDIO_RDATA_REG                 0xc
> > +#define MDIO_STA_REG                   0x10
> 
> These look suspiciously similar to definitions from
> drivers/net/ethernet/hisilicon/hip04_mdio.c.
> 
> Could the hardware be related? If so, please try to share
> the common parts.
> 
> > +static inline void mdio_write_reg(void *base, u32 reg, u32 value)
> > +{
> > +       u8 __iomem *reg_addr = ACCESS_ONCE(base);
> > +
> > +       writel(value, reg_addr + reg);
> > +}
> > +
> > +#define MDIO_WRITE_REG(a, reg, value) \
> > +       mdio_write_reg((a)->vbase, (reg), (value))
> > 
> 
> Something seems wrong here: why do you have an ACCESS_ONCE() on a
> local variable? Doesn't this just make the code less efficient
> without providing lockless access to shared variables?
> 
> The types are inconsistent here, you should get a warning from
> running this through 'make C=1' because of the missing __iomem
> annotation of the pointer.
> 
> Also, why both a macro and an inline function? Just use an inline
> function.
> 
> 	Arnd


From pi-cheng.chen at linaro.org  Mon Aug 17 02:24:22 2015
From: pi-cheng.chen at linaro.org (Pi-Cheng Chen)
Date: Mon, 17 Aug 2015 17:24:22 +0800
Subject: [RESEND PATCH 0/3 v6] Add Mediatek MT8173 cpufreq driver
Message-ID: <1439803465-19683-1-git-send-email-pi-cheng.chen@linaro.org>

MT8173 is a ARMv8 based SoC with 2 clusters. All CPUs in a single cluster
share the same power and clock domain. This series tries to add cpufreq support
for MT8173 SoC. The v6 of this series is resent with Acks added.

changes in v6:
- Move clock and regulator consumer properties document to the device tree
  bindings documents of MT8173 CPU DVFS clock driver
- Add change log to describe what is implemented in the MT8173 cpufreq driver
- Add missed rcu_read_unlock() in the error path
- Move of_init_opp_table() call to make sure all required hardware resources
  are already there before it is called
- Add comments to describe why both platform driver and deivce registration
  codes are put in the initcall function
- Use the term "voltage tracking" instead of "voltage trace" according to an
  internal SoC document

changes in v5:
- Move resource allocation code from init() into probe() and remove some unused
  functions due to this change
- Fix descriptions for device tree binding document
- Address review comments for last version
- Register CPU cooling device

Changes in v4:
- Add bindings for MT8173 cpufreq driver
- Move OPP table back into device tree
- Address comments for last version

Changes in v3:
- Implement MT8173 specific standalone cpufreq driver instead of using
  cpufreq-dt driver
- Define OPP table in the driver source code until new OPP binding is ready

Changes in v2:
- Add intermediate frequency support in cpufreq-dt driver
- Use voltage scaling code of cpufreq-dt for little cluster instead of
  implementaion in notifier of mtk-cpufreq driver
- Code refinement for mtk-cpufreq driver

Pi-Cheng Chen (3):
  dt-bindings: mediatek: Add MT8173 CPU DVFS clock bindings
  cpufreq: mediatek: Add MT8173 cpufreq driver
  arm64: dts: mt8173: Add mt8173 cpufreq driver support

 .../devicetree/bindings/clock/mt8173-cpu-dvfs.txt  |  83 ++++
 arch/arm64/boot/dts/mediatek/mt8173-evb.dts        |  18 +
 arch/arm64/boot/dts/mediatek/mt8173.dtsi           |  64 +++
 drivers/cpufreq/Kconfig.arm                        |   7 +
 drivers/cpufreq/Makefile                           |   1 +
 drivers/cpufreq/mt8173-cpufreq.c                   | 524 +++++++++++++++++++++
 6 files changed, 697 insertions(+)
 create mode 100644 Documentation/devicetree/bindings/clock/mt8173-cpu-dvfs.txt
 create mode 100644 drivers/cpufreq/mt8173-cpufreq.c

-- 
1.9.1



From pi-cheng.chen at linaro.org  Mon Aug 17 02:24:23 2015
From: pi-cheng.chen at linaro.org (Pi-Cheng Chen)
Date: Mon, 17 Aug 2015 17:24:23 +0800
Subject: [RESEND PATCH 1/3 v6] dt-bindings: mediatek: Add MT8173 CPU DVFS
 clock bindings
In-Reply-To: <1439803465-19683-1-git-send-email-pi-cheng.chen@linaro.org>
References: <1439803465-19683-1-git-send-email-pi-cheng.chen@linaro.org>
Message-ID: <1439803465-19683-2-git-send-email-pi-cheng.chen@linaro.org>

This patch adds the clock and regulator consumer properties part of
document for CPU DVFS clocks on Mediatek MT8173 SoC.

Signed-off-by: Pi-Cheng Chen <pi-cheng.chen at linaro.org>
Acked-by: Michael Turquette <mturquette at baylibre.com>
Acked-by: Viresh Kumar <viresh.kumar at linaro.org>
---
 .../devicetree/bindings/clock/mt8173-cpu-dvfs.txt  | 83 ++++++++++++++++++++++
 1 file changed, 83 insertions(+)
 create mode 100644 Documentation/devicetree/bindings/clock/mt8173-cpu-dvfs.txt

diff --git a/Documentation/devicetree/bindings/clock/mt8173-cpu-dvfs.txt b/Documentation/devicetree/bindings/clock/mt8173-cpu-dvfs.txt
new file mode 100644
index 0000000..52b457c
--- /dev/null
+++ b/Documentation/devicetree/bindings/clock/mt8173-cpu-dvfs.txt
@@ -0,0 +1,83 @@
+Device Tree Clock bindins for CPU DVFS of Mediatek MT8173 SoC
+
+Required properties:
+- clocks: A list of phandle + clock-specifier pairs for the clocks listed in clock names.
+- clock-names: Should contain the following:
+	"cpu"		- The multiplexer for clock input of CPU cluster.
+	"intermediate"	- A parent of "cpu" clock which is used as "intermediate" clock
+			  source (usually MAINPLL) when the original CPU PLL is under
+			  transition and not stable yet.
+	Please refer to Documentation/devicetree/bindings/clk/clock-bindings.txt for
+	generic clock consumer properties.
+- proc-supply: Regulator for Vproc of CPU cluster.
+
+Optional properties:
+- sram-supply: Regulator for Vsram of CPU cluster. When present, the cpufreq driver
+	       needs to do "voltage tracking" to step by step scale up/down Vproc and
+	       Vsram to fit SoC specific needs. When absent, the voltage scaling
+	       flow is handled by hardware, hence no software "voltage tracking" is
+	       needed.
+
+Example:
+--------
+	cpu0: cpu at 0 {
+		device_type = "cpu";
+		compatible = "arm,cortex-a53";
+		reg = <0x000>;
+		enable-method = "psci";
+		cpu-idle-states = <&CPU_SLEEP_0>;
+		clocks = <&infracfg CLK_INFRA_CA53SEL>,
+			 <&apmixedsys CLK_APMIXED_MAINPLL>;
+		clock-names = "cpu", "intermediate";
+	};
+
+	cpu1: cpu at 1 {
+		device_type = "cpu";
+		compatible = "arm,cortex-a53";
+		reg = <0x001>;
+		enable-method = "psci";
+		cpu-idle-states = <&CPU_SLEEP_0>;
+		clocks = <&infracfg CLK_INFRA_CA53SEL>,
+			 <&apmixedsys CLK_APMIXED_MAINPLL>;
+		clock-names = "cpu", "intermediate";
+	};
+
+	cpu2: cpu at 100 {
+		device_type = "cpu";
+		compatible = "arm,cortex-a57";
+		reg = <0x100>;
+		enable-method = "psci";
+		cpu-idle-states = <&CPU_SLEEP_0>;
+		clocks = <&infracfg CLK_INFRA_CA57SEL>,
+			 <&apmixedsys CLK_APMIXED_MAINPLL>;
+		clock-names = "cpu", "intermediate";
+	};
+
+	cpu3: cpu at 101 {
+		device_type = "cpu";
+		compatible = "arm,cortex-a57";
+		reg = <0x101>;
+		enable-method = "psci";
+		cpu-idle-states = <&CPU_SLEEP_0>;
+		clocks = <&infracfg CLK_INFRA_CA57SEL>,
+			 <&apmixedsys CLK_APMIXED_MAINPLL>;
+		clock-names = "cpu", "intermediate";
+	};
+
+	&cpu0 {
+		proc-supply = <&mt6397_vpca15_reg>;
+	};
+
+	&cpu1 {
+		proc-supply = <&mt6397_vpca15_reg>;
+	};
+
+	&cpu2 {
+		proc-supply = <&da9211_vcpu_reg>;
+		sram-supply = <&mt6397_vsramca7_reg>;
+	};
+
+	&cpu3 {
+		proc-supply = <&da9211_vcpu_reg>;
+		sram-supply = <&mt6397_vsramca7_reg>;
+	};
-- 
1.9.1



From pi-cheng.chen at linaro.org  Mon Aug 17 02:24:24 2015
From: pi-cheng.chen at linaro.org (Pi-Cheng Chen)
Date: Mon, 17 Aug 2015 17:24:24 +0800
Subject: [RESEND PATCH 2/3 v6] cpufreq: mediatek: Add MT8173 cpufreq driver
In-Reply-To: <1439803465-19683-1-git-send-email-pi-cheng.chen@linaro.org>
References: <1439803465-19683-1-git-send-email-pi-cheng.chen@linaro.org>
Message-ID: <1439803465-19683-3-git-send-email-pi-cheng.chen@linaro.org>

Mediatek MT8173 is an ARMv8 based quad-core (2*Cortex-A53 and
2*Cortex-A72) SoC with duall clusters. For each cluster, two voltage
inputs, Vproc and Vsram are supplied by two regulators. For the big
cluster, two regulators come from different PMICs. In this case, when
scaling voltage inputs of the cluster, the voltages of two regulator
inputs need to be controlled by software explicitly under the SoC
specific limitation:

	100mV < Vsram - Vproc < 200mV

which is called 'voltage tracking' mechanism. And when scaling the
frequency of cluster clock input, the input MUX need to be parented to
another "intermediate" stable PLL first and reparented to the original
PLL once the original PLL is stable at the target frequency. This patch
implements those mechanisms to enable CPU DVFS support for Mediatek
MT8173 SoC.

Signed-off-by: Pi-Cheng Chen <pi-cheng.chen at linaro.org>
Acked-by: Viresh Kumar <viresh.kumar at linaro.org>
---
 drivers/cpufreq/Kconfig.arm      |   7 +
 drivers/cpufreq/Makefile         |   1 +
 drivers/cpufreq/mt8173-cpufreq.c | 524 +++++++++++++++++++++++++++++++++++++++
 3 files changed, 532 insertions(+)
 create mode 100644 drivers/cpufreq/mt8173-cpufreq.c

diff --git a/drivers/cpufreq/Kconfig.arm b/drivers/cpufreq/Kconfig.arm
index cc8a71c..2bacf24 100644
--- a/drivers/cpufreq/Kconfig.arm
+++ b/drivers/cpufreq/Kconfig.arm
@@ -130,6 +130,13 @@ config ARM_KIRKWOOD_CPUFREQ
 	  This adds the CPUFreq driver for Marvell Kirkwood
 	  SoCs.
 
+config ARM_MT8173_CPUFREQ
+	bool "Mediatek MT8173 CPUFreq support"
+	depends on ARCH_MEDIATEK && REGULATOR
+	select PM_OPP
+	help
+	  This adds the CPUFreq driver support for Mediatek MT8173 SoC.
+
 config ARM_OMAP2PLUS_CPUFREQ
 	bool "TI OMAP2+"
 	depends on ARCH_OMAP2PLUS
diff --git a/drivers/cpufreq/Makefile b/drivers/cpufreq/Makefile
index 2169bf7..9c75faf 100644
--- a/drivers/cpufreq/Makefile
+++ b/drivers/cpufreq/Makefile
@@ -62,6 +62,7 @@ obj-$(CONFIG_ARM_HISI_ACPU_CPUFREQ)	+= hisi-acpu-cpufreq.o
 obj-$(CONFIG_ARM_IMX6Q_CPUFREQ)		+= imx6q-cpufreq.o
 obj-$(CONFIG_ARM_INTEGRATOR)		+= integrator-cpufreq.o
 obj-$(CONFIG_ARM_KIRKWOOD_CPUFREQ)	+= kirkwood-cpufreq.o
+obj-$(CONFIG_ARM_MT8173_CPUFREQ)	+= mt8173-cpufreq.o
 obj-$(CONFIG_ARM_OMAP2PLUS_CPUFREQ)	+= omap-cpufreq.o
 obj-$(CONFIG_ARM_PXA2xx_CPUFREQ)	+= pxa2xx-cpufreq.o
 obj-$(CONFIG_PXA3xx)			+= pxa3xx-cpufreq.o
diff --git a/drivers/cpufreq/mt8173-cpufreq.c b/drivers/cpufreq/mt8173-cpufreq.c
new file mode 100644
index 0000000..763f1e3
--- /dev/null
+++ b/drivers/cpufreq/mt8173-cpufreq.c
@@ -0,0 +1,524 @@
+/*
+ * Copyright (c) 2015 Linaro Ltd.
+ * Author: Pi-Cheng Chen <pi-cheng.chen at linaro.org>
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License version 2 as
+ * published by the Free Software Foundation.
+ *
+ * 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.h>
+#include <linux/cpu.h>
+#include <linux/cpu_cooling.h>
+#include <linux/cpufreq.h>
+#include <linux/cpumask.h>
+#include <linux/of.h>
+#include <linux/platform_device.h>
+#include <linux/pm_opp.h>
+#include <linux/regulator/consumer.h>
+#include <linux/slab.h>
+#include <linux/thermal.h>
+
+#define MIN_VOLT_SHIFT		(100000)
+#define MAX_VOLT_SHIFT		(200000)
+#define MAX_VOLT_LIMIT		(1150000)
+#define VOLT_TOL		(10000)
+
+/*
+ * The struct mtk_cpu_dvfs_info holds necessary information for doing CPU DVFS
+ * on each CPU power/clock domain of Mediatek SoCs. Each CPU cluster in
+ * Mediatek SoCs has two voltage inputs, Vproc and Vsram. In some cases the two
+ * voltage inputs need to be controlled under a hardware limitation:
+ * 100mV < Vsram - Vproc < 200mV
+ *
+ * When scaling the clock frequency of a CPU clock domain, the clock source
+ * needs to be switched to another stable PLL clock temporarily until
+ * the original PLL becomes stable at target frequency.
+ */
+struct mtk_cpu_dvfs_info {
+	struct device *cpu_dev;
+	struct regulator *proc_reg;
+	struct regulator *sram_reg;
+	struct clk *cpu_clk;
+	struct clk *inter_clk;
+	struct thermal_cooling_device *cdev;
+	int intermediate_voltage;
+	bool need_voltage_tracking;
+};
+
+static int mtk_cpufreq_voltage_tracking(struct mtk_cpu_dvfs_info *info,
+					int new_vproc)
+{
+	struct regulator *proc_reg = info->proc_reg;
+	struct regulator *sram_reg = info->sram_reg;
+	int old_vproc, old_vsram, new_vsram, vsram, vproc, ret;
+
+	old_vproc = regulator_get_voltage(proc_reg);
+	old_vsram = regulator_get_voltage(sram_reg);
+	/* Vsram should not exceed the maximum allowed voltage of SoC. */
+	new_vsram = min(new_vproc + MIN_VOLT_SHIFT, MAX_VOLT_LIMIT);
+
+	if (old_vproc < new_vproc) {
+		/*
+		 * When scaling up voltages, Vsram and Vproc scale up step
+		 * by step. At each step, set Vsram to (Vproc + 200mV) first,
+		 * then set Vproc to (Vsram - 100mV).
+		 * Keep doing it until Vsram and Vproc hit target voltages.
+		 */
+		do {
+			old_vsram = regulator_get_voltage(sram_reg);
+			old_vproc = regulator_get_voltage(proc_reg);
+
+			vsram = min(new_vsram, old_vproc + MAX_VOLT_SHIFT);
+
+			if (vsram + VOLT_TOL >= MAX_VOLT_LIMIT) {
+				vsram = MAX_VOLT_LIMIT;
+
+				/*
+				 * If the target Vsram hits the maximum voltage,
+				 * try to set the exact voltage value first.
+				 */
+				ret = regulator_set_voltage(sram_reg, vsram,
+							    vsram);
+				if (ret)
+					ret = regulator_set_voltage(sram_reg,
+							vsram - VOLT_TOL,
+							vsram);
+
+				vproc = new_vproc;
+			} else {
+				ret = regulator_set_voltage(sram_reg, vsram,
+							    vsram + VOLT_TOL);
+
+				vproc = vsram - MIN_VOLT_SHIFT;
+			}
+			if (ret)
+				return ret;
+
+			ret = regulator_set_voltage(proc_reg, vproc,
+						    vproc + VOLT_TOL);
+			if (ret) {
+				regulator_set_voltage(sram_reg, old_vsram,
+						      old_vsram);
+				return ret;
+			}
+		} while (vproc < new_vproc || vsram < new_vsram);
+	} else if (old_vproc > new_vproc) {
+		/*
+		 * When scaling down voltages, Vsram and Vproc scale down step
+		 * by step. At each step, set Vproc to (Vsram - 200mV) first,
+		 * then set Vproc to (Vproc + 100mV).
+		 * Keep doing it until Vsram and Vproc hit target voltages.
+		 */
+		do {
+			old_vproc = regulator_get_voltage(proc_reg);
+			old_vsram = regulator_get_voltage(sram_reg);
+
+			vproc = max(new_vproc, old_vsram - MAX_VOLT_SHIFT);
+			ret = regulator_set_voltage(proc_reg, vproc,
+						    vproc + VOLT_TOL);
+			if (ret)
+				return ret;
+
+			if (vproc == new_vproc)
+				vsram = new_vsram;
+			else
+				vsram = max(new_vsram, vproc + MIN_VOLT_SHIFT);
+
+			if (vsram + VOLT_TOL >= MAX_VOLT_LIMIT) {
+				vsram = MAX_VOLT_LIMIT;
+
+				/*
+				 * If the target Vsram hits the maximum voltage,
+				 * try to set the exact voltage value first.
+				 */
+				ret = regulator_set_voltage(sram_reg, vsram,
+							    vsram);
+				if (ret)
+					ret = regulator_set_voltage(sram_reg,
+							vsram - VOLT_TOL,
+							vsram);
+			} else {
+				ret = regulator_set_voltage(sram_reg, vsram,
+							    vsram + VOLT_TOL);
+			}
+
+			if (ret) {
+				regulator_set_voltage(proc_reg, old_vproc,
+						      old_vproc);
+				return ret;
+			}
+		} while (vproc > new_vproc + VOLT_TOL ||
+			 vsram > new_vsram + VOLT_TOL);
+	}
+
+	return 0;
+}
+
+static int mtk_cpufreq_set_voltage(struct mtk_cpu_dvfs_info *info, int vproc)
+{
+	if (info->need_voltage_tracking)
+		return mtk_cpufreq_voltage_tracking(info, vproc);
+	else
+		return regulator_set_voltage(info->proc_reg, vproc,
+					     vproc + VOLT_TOL);
+}
+
+static int mtk_cpufreq_set_target(struct cpufreq_policy *policy,
+				  unsigned int index)
+{
+	struct cpufreq_frequency_table *freq_table = policy->freq_table;
+	struct clk *cpu_clk = policy->clk;
+	struct clk *armpll = clk_get_parent(cpu_clk);
+	struct mtk_cpu_dvfs_info *info = policy->driver_data;
+	struct device *cpu_dev = info->cpu_dev;
+	struct dev_pm_opp *opp;
+	long freq_hz, old_freq_hz;
+	int vproc, old_vproc, inter_vproc, target_vproc, ret;
+
+	inter_vproc = info->intermediate_voltage;
+
+	old_freq_hz = clk_get_rate(cpu_clk);
+	old_vproc = regulator_get_voltage(info->proc_reg);
+
+	freq_hz = freq_table[index].frequency * 1000;
+
+	rcu_read_lock();
+	opp = dev_pm_opp_find_freq_ceil(cpu_dev, &freq_hz);
+	if (IS_ERR(opp)) {
+		rcu_read_unlock();
+		pr_err("cpu%d: failed to find OPP for %ld\n",
+		       policy->cpu, freq_hz);
+		return PTR_ERR(opp);
+	}
+	vproc = dev_pm_opp_get_voltage(opp);
+	rcu_read_unlock();
+
+	/*
+	 * If the new voltage or the intermediate voltage is higher than the
+	 * current voltage, scale up voltage first.
+	 */
+	target_vproc = (inter_vproc > vproc) ? inter_vproc : vproc;
+	if (old_vproc < target_vproc) {
+		ret = mtk_cpufreq_set_voltage(info, target_vproc);
+		if (ret) {
+			pr_err("cpu%d: failed to scale up voltage!\n",
+			       policy->cpu);
+			mtk_cpufreq_set_voltage(info, old_vproc);
+			return ret;
+		}
+	}
+
+	/* Reparent the CPU clock to intermediate clock. */
+	ret = clk_set_parent(cpu_clk, info->inter_clk);
+	if (ret) {
+		pr_err("cpu%d: failed to re-parent cpu clock!\n",
+		       policy->cpu);
+		mtk_cpufreq_set_voltage(info, old_vproc);
+		WARN_ON(1);
+		return ret;
+	}
+
+	/* Set the original PLL to target rate. */
+	ret = clk_set_rate(armpll, freq_hz);
+	if (ret) {
+		pr_err("cpu%d: failed to scale cpu clock rate!\n",
+		       policy->cpu);
+		clk_set_parent(cpu_clk, armpll);
+		mtk_cpufreq_set_voltage(info, old_vproc);
+		return ret;
+	}
+
+	/* Set parent of CPU clock back to the original PLL. */
+	ret = clk_set_parent(cpu_clk, armpll);
+	if (ret) {
+		pr_err("cpu%d: failed to re-parent cpu clock!\n",
+		       policy->cpu);
+		mtk_cpufreq_set_voltage(info, inter_vproc);
+		WARN_ON(1);
+		return ret;
+	}
+
+	/*
+	 * If the new voltage is lower than the intermediate voltage or the
+	 * original voltage, scale down to the new voltage.
+	 */
+	if (vproc < inter_vproc || vproc < old_vproc) {
+		ret = mtk_cpufreq_set_voltage(info, vproc);
+		if (ret) {
+			pr_err("cpu%d: failed to scale down voltage!\n",
+			       policy->cpu);
+			clk_set_parent(cpu_clk, info->inter_clk);
+			clk_set_rate(armpll, old_freq_hz);
+			clk_set_parent(cpu_clk, armpll);
+			return ret;
+		}
+	}
+
+	return 0;
+}
+
+static void mtk_cpufreq_ready(struct cpufreq_policy *policy)
+{
+	struct mtk_cpu_dvfs_info *info = policy->driver_data;
+	struct device_node *np = of_node_get(info->cpu_dev->of_node);
+
+	if (WARN_ON(!np))
+		return;
+
+	if (of_find_property(np, "#cooling-cells", NULL)) {
+		info->cdev = of_cpufreq_cooling_register(np,
+							 policy->related_cpus);
+
+		if (IS_ERR(info->cdev)) {
+			dev_err(info->cpu_dev,
+				"running cpufreq without cooling device: %ld\n",
+				PTR_ERR(info->cdev));
+
+			info->cdev = NULL;
+		}
+	}
+
+	of_node_put(np);
+}
+
+static int mtk_cpu_dvfs_info_init(struct mtk_cpu_dvfs_info *info, int cpu)
+{
+	struct device *cpu_dev;
+	struct regulator *proc_reg = ERR_PTR(-ENODEV);
+	struct regulator *sram_reg = ERR_PTR(-ENODEV);
+	struct clk *cpu_clk = ERR_PTR(-ENODEV);
+	struct clk *inter_clk = ERR_PTR(-ENODEV);
+	struct dev_pm_opp *opp;
+	unsigned long rate;
+	int ret;
+
+	cpu_dev = get_cpu_device(cpu);
+	if (!cpu_dev) {
+		pr_err("failed to get cpu%d device\n", cpu);
+		return -ENODEV;
+	}
+
+	cpu_clk = clk_get(cpu_dev, "cpu");
+	if (IS_ERR(cpu_clk)) {
+		if (PTR_ERR(cpu_clk) == -EPROBE_DEFER)
+			pr_warn("cpu clk for cpu%d not ready, retry.\n", cpu);
+		else
+			pr_err("failed to get cpu clk for cpu%d\n", cpu);
+
+		ret = PTR_ERR(cpu_clk);
+		return ret;
+	}
+
+	inter_clk = clk_get(cpu_dev, "intermediate");
+	if (IS_ERR(inter_clk)) {
+		if (PTR_ERR(inter_clk) == -EPROBE_DEFER)
+			pr_warn("intermediate clk for cpu%d not ready, retry.\n",
+				cpu);
+		else
+			pr_err("failed to get intermediate clk for cpu%d\n",
+			       cpu);
+
+		ret = PTR_ERR(inter_clk);
+		goto out_free_resources;
+	}
+
+	proc_reg = regulator_get_exclusive(cpu_dev, "proc");
+	if (IS_ERR(proc_reg)) {
+		if (PTR_ERR(proc_reg) == -EPROBE_DEFER)
+			pr_warn("proc regulator for cpu%d not ready, retry.\n",
+				cpu);
+		else
+			pr_err("failed to get proc regulator for cpu%d\n",
+			       cpu);
+
+		ret = PTR_ERR(proc_reg);
+		goto out_free_resources;
+	}
+
+	/* Both presence and absence of sram regulator are valid cases. */
+	sram_reg = regulator_get_exclusive(cpu_dev, "sram");
+
+	ret = of_init_opp_table(cpu_dev);
+	if (ret) {
+		pr_warn("no OPP table for cpu%d\n", cpu);
+		goto out_free_resources;
+	}
+
+	/* Search a safe voltage for intermediate frequency. */
+	rate = clk_get_rate(inter_clk);
+	rcu_read_lock();
+	opp = dev_pm_opp_find_freq_ceil(cpu_dev, &rate);
+	if (IS_ERR(opp)) {
+		rcu_read_unlock();
+		pr_err("failed to get intermediate opp for cpu%d\n", cpu);
+		ret = PTR_ERR(opp);
+		goto out_free_opp_table;
+	}
+	info->intermediate_voltage = dev_pm_opp_get_voltage(opp);
+	rcu_read_unlock();
+
+	info->cpu_dev = cpu_dev;
+	info->proc_reg = proc_reg;
+	info->sram_reg = IS_ERR(sram_reg) ? NULL : sram_reg;
+	info->cpu_clk = cpu_clk;
+	info->inter_clk = inter_clk;
+
+	/*
+	 * If SRAM regulator is present, software "voltage tracking" is needed
+	 * for this CPU power domain.
+	 */
+	info->need_voltage_tracking = !IS_ERR(sram_reg);
+
+	return 0;
+
+out_free_opp_table:
+	of_free_opp_table(cpu_dev);
+
+out_free_resources:
+	if (!IS_ERR(proc_reg))
+		regulator_put(proc_reg);
+	if (!IS_ERR(sram_reg))
+		regulator_put(sram_reg);
+	if (!IS_ERR(cpu_clk))
+		clk_put(cpu_clk);
+	if (!IS_ERR(inter_clk))
+		clk_put(inter_clk);
+
+	return ret;
+}
+
+static void mtk_cpu_dvfs_info_release(struct mtk_cpu_dvfs_info *info)
+{
+	if (!IS_ERR(info->proc_reg))
+		regulator_put(info->proc_reg);
+	if (!IS_ERR(info->sram_reg))
+		regulator_put(info->sram_reg);
+	if (!IS_ERR(info->cpu_clk))
+		clk_put(info->cpu_clk);
+	if (!IS_ERR(info->inter_clk))
+		clk_put(info->inter_clk);
+
+	of_free_opp_table(info->cpu_dev);
+}
+
+static int mtk_cpufreq_init(struct cpufreq_policy *policy)
+{
+	struct mtk_cpu_dvfs_info *info;
+	struct cpufreq_frequency_table *freq_table;
+	int ret;
+
+	info = kzalloc(sizeof(*info), GFP_KERNEL);
+	if (!info)
+		return -ENOMEM;
+
+	ret = mtk_cpu_dvfs_info_init(info, policy->cpu);
+	if (ret) {
+		pr_err("%s failed to initialize dvfs info for cpu%d\n",
+		       __func__, policy->cpu);
+		goto out_free_dvfs_info;
+	}
+
+	ret = dev_pm_opp_init_cpufreq_table(info->cpu_dev, &freq_table);
+	if (ret) {
+		pr_err("failed to init cpufreq table for cpu%d: %d\n",
+		       policy->cpu, ret);
+		goto out_release_dvfs_info;
+	}
+
+	ret = cpufreq_table_validate_and_show(policy, freq_table);
+	if (ret) {
+		pr_err("%s: invalid frequency table: %d\n", __func__, ret);
+		goto out_free_cpufreq_table;
+	}
+
+	/* CPUs in the same cluster share a clock and power domain. */
+	cpumask_copy(policy->cpus, &cpu_topology[policy->cpu].core_sibling);
+	policy->driver_data = info;
+	policy->clk = info->cpu_clk;
+
+	return 0;
+
+out_free_cpufreq_table:
+	dev_pm_opp_free_cpufreq_table(info->cpu_dev, &freq_table);
+
+out_release_dvfs_info:
+	mtk_cpu_dvfs_info_release(info);
+
+out_free_dvfs_info:
+	kfree(info);
+
+	return ret;
+}
+
+static int mtk_cpufreq_exit(struct cpufreq_policy *policy)
+{
+	struct mtk_cpu_dvfs_info *info = policy->driver_data;
+
+	cpufreq_cooling_unregister(info->cdev);
+	dev_pm_opp_free_cpufreq_table(info->cpu_dev, &policy->freq_table);
+	mtk_cpu_dvfs_info_release(info);
+	kfree(info);
+
+	return 0;
+}
+
+static struct cpufreq_driver mt8173_cpufreq_driver = {
+	.flags = CPUFREQ_STICKY | CPUFREQ_NEED_INITIAL_FREQ_CHECK,
+	.verify = cpufreq_generic_frequency_table_verify,
+	.target_index = mtk_cpufreq_set_target,
+	.get = cpufreq_generic_get,
+	.init = mtk_cpufreq_init,
+	.exit = mtk_cpufreq_exit,
+	.ready = mtk_cpufreq_ready,
+	.name = "mtk-cpufreq",
+	.attr = cpufreq_generic_attr,
+};
+
+static int mt8173_cpufreq_probe(struct platform_device *pdev)
+{
+	int ret;
+
+	ret = cpufreq_register_driver(&mt8173_cpufreq_driver);
+	if (ret)
+		pr_err("failed to register mtk cpufreq driver\n");
+
+	return ret;
+}
+
+static struct platform_driver mt8173_cpufreq_platdrv = {
+	.driver = {
+		.name	= "mt8173-cpufreq",
+	},
+	.probe		= mt8173_cpufreq_probe,
+};
+
+static int mt8173_cpufreq_driver_init(void)
+{
+	struct platform_device *pdev;
+	int err;
+
+	err = platform_driver_register(&mt8173_cpufreq_platdrv);
+	if (err)
+		return err;
+
+	/*
+	 * Since there's no place to hold device registration code and no
+	 * device tree based way to match cpufreq driver yet, both the driver
+	 * and the device registration codes are put here to handle defer
+	 * probing.
+	 */
+	pdev = platform_device_register_simple("mt8173-cpufreq", -1, NULL, 0);
+	if (IS_ERR(pdev)) {
+		pr_err("failed to register mtk-cpufreq platform device\n");
+		return PTR_ERR(pdev);
+	}
+
+	return 0;
+}
+device_initcall(mt8173_cpufreq_driver_init);
-- 
1.9.1



From pi-cheng.chen at linaro.org  Mon Aug 17 02:24:25 2015
From: pi-cheng.chen at linaro.org (Pi-Cheng Chen)
Date: Mon, 17 Aug 2015 17:24:25 +0800
Subject: [RESEND PATCH 3/3 v6] arm64: dts: mt8173: mt8173-evb: Add mt8173
 cpufreq driver support
In-Reply-To: <1439803465-19683-1-git-send-email-pi-cheng.chen@linaro.org>
References: <1439803465-19683-1-git-send-email-pi-cheng.chen@linaro.org>
Message-ID: <1439803465-19683-4-git-send-email-pi-cheng.chen@linaro.org>

This patch adds the required properties in device tree to enable MT8173
cpufreq driver.

Signed-off-by: Pi-Cheng Chen <pi-cheng.chen at linaro.org>
Acked-by: Viresh Kumar <viresh.kumar at linaro.org>
---
It is based on the top of MT8173 SoC maintainer's tree:
https://github.com/mbgg/linux-mediatek.git v4.2-next/arm64
commit id: e26945245e414eff42ee1ffeaedf198911bf1d77
---
 arch/arm64/boot/dts/mediatek/mt8173-evb.dts | 18 ++++++++
 arch/arm64/boot/dts/mediatek/mt8173.dtsi    | 64 +++++++++++++++++++++++++++++
 2 files changed, 82 insertions(+)

diff --git a/arch/arm64/boot/dts/mediatek/mt8173-evb.dts b/arch/arm64/boot/dts/mediatek/mt8173-evb.dts
index dc4a3e2..ddb1dc1 100644
--- a/arch/arm64/boot/dts/mediatek/mt8173-evb.dts
+++ b/arch/arm64/boot/dts/mediatek/mt8173-evb.dts
@@ -261,6 +261,24 @@
 	};
 };
 
+&cpu0 {
+	proc-supply = <&mt6397_vpca15_reg>;
+};
+
+&cpu1 {
+	proc-supply = <&mt6397_vpca15_reg>;
+};
+
+&cpu2 {
+	proc-supply = <&da9211_vcpu_reg>;
+	sram-supply = <&mt6397_vsramca7_reg>;
+};
+
+&cpu3 {
+	proc-supply = <&da9211_vcpu_reg>;
+	sram-supply = <&mt6397_vsramca7_reg>;
+};
+
 &uart0 {
 	status = "okay";
 };
diff --git a/arch/arm64/boot/dts/mediatek/mt8173.dtsi b/arch/arm64/boot/dts/mediatek/mt8173.dtsi
index 359b8b6..47a443d 100644
--- a/arch/arm64/boot/dts/mediatek/mt8173.dtsi
+++ b/arch/arm64/boot/dts/mediatek/mt8173.dtsi
@@ -53,6 +53,22 @@
 			reg = <0x000>;
 			enable-method = "psci";
 			cpu-idle-states = <&CPU_SLEEP_0>;
+			clocks = <&infracfg CLK_INFRA_CA53SEL>,
+				 <&apmixedsys CLK_APMIXED_MAINPLL>;
+			clock-names = "cpu", "intermediate";
+			operating-points = <
+				507000	859000
+				702000	908000
+				1001000	983000
+				1105000	1009000
+				1183000	1028000
+				1404000	1083000
+				1508000	1109000
+				1573000	1125000
+			>;
+			#cooling-cells = <2>;
+			#cooling-min-level = <0>;
+			#cooling-max-level = <7>;
 		};
 
 		cpu1: cpu at 1 {
@@ -61,6 +77,22 @@
 			reg = <0x001>;
 			enable-method = "psci";
 			cpu-idle-states = <&CPU_SLEEP_0>;
+			clocks = <&infracfg CLK_INFRA_CA53SEL>,
+				 <&apmixedsys CLK_APMIXED_MAINPLL>;
+			clock-names = "cpu", "intermediate";
+			operating-points = <
+				507000	859000
+				702000	908000
+				1001000	983000
+				1105000	1009000
+				1183000	1028000
+				1404000	1083000
+				1508000	1109000
+				1573000	1125000
+			>;
+			#cooling-cells = <2>;
+			#cooling-min-level = <0>;
+			#cooling-max-level = <7>;
 		};
 
 		cpu2: cpu at 100 {
@@ -69,6 +101,22 @@
 			reg = <0x100>;
 			enable-method = "psci";
 			cpu-idle-states = <&CPU_SLEEP_0>;
+			clocks = <&infracfg CLK_INFRA_CA57SEL>,
+				 <&apmixedsys CLK_APMIXED_MAINPLL>;
+			clock-names = "cpu", "intermediate";
+			operating-points = <
+				507000	828000
+				702000	867000
+				1001000	927000
+				1209000	968000
+				1404000	1007000
+				1612000	1049000
+				1807000	1089000
+				1989000	1125000
+			>;
+			#cooling-cells = <2>;
+			#cooling-min-level = <0>;
+			#cooling-max-level = <7>;
 		};
 
 		cpu3: cpu at 101 {
@@ -77,6 +125,22 @@
 			reg = <0x101>;
 			enable-method = "psci";
 			cpu-idle-states = <&CPU_SLEEP_0>;
+			clocks = <&infracfg CLK_INFRA_CA57SEL>,
+				 <&apmixedsys CLK_APMIXED_MAINPLL>;
+			clock-names = "cpu", "intermediate";
+			operating-points = <
+				507000	828000
+				702000	867000
+				1001000	927000
+				1209000	968000
+				1404000	1007000
+				1612000	1049000
+				1807000	1089000
+				1989000	1125000
+			>;
+			#cooling-cells = <2>;
+			#cooling-min-level = <0>;
+			#cooling-max-level = <7>;
 		};
 
 		idle-states {
-- 
1.9.1



From will.deacon at arm.com  Mon Aug 17 02:43:07 2015
From: will.deacon at arm.com (Will Deacon)
Date: Mon, 17 Aug 2015 10:43:07 +0100
Subject: [PATCH] arm64: ignore memory outside of the linear range
In-Reply-To: <1439640824-30498-1-git-send-email-ard.biesheuvel@linaro.org>
References: <1439640824-30498-1-git-send-email-ard.biesheuvel@linaro.org>
Message-ID: <20150817094307.GD1688@arm.com>

Hi Ard,

On Sat, Aug 15, 2015 at 01:13:44PM +0100, Ard Biesheuvel wrote:
> We need to ensure that we don't try to map system RAM ranges whose
> offset relative to the start of the kernel image exceeds the size of
> the linear range. This may happen even on systems that don't have
> huge amounts of RAM if it is laid out very sparsely.
> 
> Signed-off-by: Ard Biesheuvel <ard.biesheuvel at linaro.org>
> ---
> 
> This is the minimal fix for addressing the issue we discussed. I dropped
> the other changes for now, let's revisit those when (if) my patches for
> decoupling the kernel mapping from the linear mapping are back under
> discussion.
> 
> I will leave it up to the maintainers whether this constitutes a bugfix or
> not, but since this has never worked from the beginning afaict, I don't
> think it belongs in stable per se.
> 
>  arch/arm64/mm/init.c | 13 +++++++++++++
>  1 file changed, 13 insertions(+)
> 
> diff --git a/arch/arm64/mm/init.c b/arch/arm64/mm/init.c
> index ad87ce826cce..c65e57d4c3e7 100644
> --- a/arch/arm64/mm/init.c
> +++ b/arch/arm64/mm/init.c
> @@ -158,6 +158,19 @@ early_param("mem", early_mem);
>  
>  void __init arm64_memblock_init(void)
>  {
> +	/*
> +	 * Remove the memory that we will not be able to cover
> +	 * with the linear mapping.
> +	 */
> +	const s64 linear_region_size = -(s64)PAGE_OFFSET;
> +
> +	if (memstart_addr + linear_region_size < memblock_end_of_DRAM()) {
> +		pr_warn("Ignoring memory outside of linear range (0x%012llx - 0x%012llx)\n",
> +			memstart_addr + linear_region_size,
> +			(u64)memblock_end_of_DRAM() - 1);
> +		memblock_remove(memstart_addr + linear_region_size, ULLONG_MAX);
> +	}
> +

I think this will interact badly with Mark Salter's patches to relocate
the initrd if it falls outside of the linear mapping (which relies on the
memblocks remaining intact after paging_init):

  https://lkml.org/lkml/2015/8/16/75

Some version of those patches got queued via akpm (since there is a
dependency on some generic + x86 changes), so we'd need to work out how
these two changes interact before merging this,

Will


From thierry.reding at gmail.com  Mon Aug 17 03:09:14 2015
From: thierry.reding at gmail.com (Thierry Reding)
Date: Mon, 17 Aug 2015 12:09:14 +0200
Subject: [PATCH] drm: panel: simple: add QiaoDian qd43003c0-40
In-Reply-To: <1438382671-10098-1-git-send-email-alexandre.belloni@free-electrons.com>
References: <1438382671-10098-1-git-send-email-alexandre.belloni@free-electrons.com>
Message-ID: <20150817100913.GA8453@ulmo.nvidia.com>

On Sat, Aug 01, 2015 at 12:44:31AM +0200, Alexandre Belloni wrote:
> From: Josh Wu <josh.wu at atmel.com>
> 
> The QiaoDian Xianshi QD43003C0-40 is a 4"3 TFT LCD panel.
> 
> Timings from the OTA5180A document, ver 0.9, section
> 10.1.1:
>   http://www.orientdisplay.com/pdf/OTA5180A.pdf
> 
> Signed-off-by: Josh Wu <josh.wu at atmel.com>
> Signed-off-by: Alexandre Belloni <alexandre.belloni at free-electrons.com>
> ---
>  .../devicetree/bindings/panel/qd,qd43003c0-40.txt  |  7 ++++++
>  drivers/gpu/drm/panel/panel-simple.c               | 26 ++++++++++++++++++++++
>  2 files changed, 33 insertions(+)
>  create mode 100644 Documentation/devicetree/bindings/panel/qd,qd43003c0-40.txt

You didn't run this through scripts/get_maintainer.pl, did you? It would
also help to use the standard prefix ("drm/panel: ") because I end up
filtering for that occasionally in case somebody didn't Cc me on panel
patches.

I only came across this by accident, and it's going to miss 4.3 now.

Also two comments below...

> diff --git a/Documentation/devicetree/bindings/panel/qd,qd43003c0-40.txt b/Documentation/devicetree/bindings/panel/qd,qd43003c0-40.txt
> new file mode 100644
> index 000000000000..900bc6ebeaff
> --- /dev/null
> +++ b/Documentation/devicetree/bindings/panel/qd,qd43003c0-40.txt
> @@ -0,0 +1,7 @@
> +QiaoDian XianShi Corporation 4"3 TFT LCD panel
> +
> +Required properties:
> +- compatible: should be "qd,qd43003c0-40"
> +
> +This binding is compatible with the simple-panel binding, which is specified
> +in simple-panel.txt in this directory.

I don't see a vendor prefix for QiaoDian XianShi Corporation in
Documentation/devicetree/bindings/vendor-prefixes.txt.

> diff --git a/drivers/gpu/drm/panel/panel-simple.c b/drivers/gpu/drm/panel/panel-simple.c
> index f94201b6e882..e688fa545ae3 100644
> --- a/drivers/gpu/drm/panel/panel-simple.c
> +++ b/drivers/gpu/drm/panel/panel-simple.c
> @@ -967,6 +967,29 @@ static const struct panel_desc ortustech_com43h4m85ulc = {
>  	.bus_format = MEDIA_BUS_FMT_RGB888_1X24,
>  };
>  
> +static const struct drm_display_mode qd43003c0_40_mode = {
> +	.clock = 9000,
> +	.hdisplay = 480,
> +	.hsync_start = 480 + 8,
> +	.hsync_end = 480 + 8 + 4,
> +	.htotal = 480 + 8 + 4 + 39,
> +	.vdisplay = 272,
> +	.vsync_start = 272 + 4,
> +	.vsync_end = 272 + 4 + 10,
> +	.vtotal = 272 + 4 + 10 + 2,
> +	.vrefresh = 60,
> +};
> +
> +static const struct panel_desc qd43003c0_40 = {
> +	.modes = &qd43003c0_40_mode,
> +	.num_modes = 1,
> +	.size = {
> +		.width = 95,
> +		.height = 53,
> +	},
> +	.bus_format = MEDIA_BUS_FMT_RGB888_1X24,
> +};

Can you also add .bpc = 8 above so that drivers that don't support the
.bus_format can still support this panel?

Thierry
-------------- next part --------------
A non-text attachment was scrubbed...
Name: signature.asc
Type: application/pgp-signature
Size: 819 bytes
Desc: not available
URL: <http://lists.infradead.org/pipermail/linux-arm-kernel/attachments/20150817/b3aafb8f/attachment.sig>

From ard.biesheuvel at linaro.org  Mon Aug 17 03:35:46 2015
From: ard.biesheuvel at linaro.org (Ard Biesheuvel)
Date: Mon, 17 Aug 2015 12:35:46 +0200
Subject: [PATCH] arm64: ignore memory outside of the linear range
In-Reply-To: <20150817094307.GD1688@arm.com>
References: <1439640824-30498-1-git-send-email-ard.biesheuvel@linaro.org>
 <20150817094307.GD1688@arm.com>
Message-ID: <CAKv+Gu8yspV+QtDP=iAas5J99+PezmXgC1_keEKO3zGeziRi6A@mail.gmail.com>

On 17 August 2015 at 11:43, Will Deacon <will.deacon at arm.com> wrote:
> Hi Ard,
>
> On Sat, Aug 15, 2015 at 01:13:44PM +0100, Ard Biesheuvel wrote:
>> We need to ensure that we don't try to map system RAM ranges whose
>> offset relative to the start of the kernel image exceeds the size of
>> the linear range. This may happen even on systems that don't have
>> huge amounts of RAM if it is laid out very sparsely.
>>
>> Signed-off-by: Ard Biesheuvel <ard.biesheuvel at linaro.org>
>> ---
>>
>> This is the minimal fix for addressing the issue we discussed. I dropped
>> the other changes for now, let's revisit those when (if) my patches for
>> decoupling the kernel mapping from the linear mapping are back under
>> discussion.
>>
>> I will leave it up to the maintainers whether this constitutes a bugfix or
>> not, but since this has never worked from the beginning afaict, I don't
>> think it belongs in stable per se.
>>
>>  arch/arm64/mm/init.c | 13 +++++++++++++
>>  1 file changed, 13 insertions(+)
>>
>> diff --git a/arch/arm64/mm/init.c b/arch/arm64/mm/init.c
>> index ad87ce826cce..c65e57d4c3e7 100644
>> --- a/arch/arm64/mm/init.c
>> +++ b/arch/arm64/mm/init.c
>> @@ -158,6 +158,19 @@ early_param("mem", early_mem);
>>
>>  void __init arm64_memblock_init(void)
>>  {
>> +     /*
>> +      * Remove the memory that we will not be able to cover
>> +      * with the linear mapping.
>> +      */
>> +     const s64 linear_region_size = -(s64)PAGE_OFFSET;
>> +
>> +     if (memstart_addr + linear_region_size < memblock_end_of_DRAM()) {
>> +             pr_warn("Ignoring memory outside of linear range (0x%012llx - 0x%012llx)\n",
>> +                     memstart_addr + linear_region_size,
>> +                     (u64)memblock_end_of_DRAM() - 1);
>> +             memblock_remove(memstart_addr + linear_region_size, ULLONG_MAX);
>> +     }
>> +
>
> I think this will interact badly with Mark Salter's patches to relocate
> the initrd if it falls outside of the linear mapping (which relies on the
> memblocks remaining intact after paging_init):
>
>   https://lkml.org/lkml/2015/8/16/75
>

Are you sure? By the looks of it, these patches combined would
correctly address the case where no mem= is passed, but the initial
ramdisk is loaded past the end of the linear region.

I.e., memblock_end_of_DRAM() will return the clipped value, which
would be smaller than orig_end, triggering the relocation machinery
which moves it inside the linear region.

-- 
Ard.


> Some version of those patches got queued via akpm (since there is a
> dependency on some generic + x86 changes), so we'd need to work out how
> these two changes interact before merging this,
>


From catalin.marinas at arm.com  Mon Aug 17 03:40:50 2015
From: catalin.marinas at arm.com (Catalin Marinas)
Date: Mon, 17 Aug 2015 11:40:50 +0100
Subject: [PATCH] arm64: ignore memory outside of the linear range
In-Reply-To: <1439640824-30498-1-git-send-email-ard.biesheuvel@linaro.org>
References: <1439640824-30498-1-git-send-email-ard.biesheuvel@linaro.org>
Message-ID: <20150817104049.GB2482@e104818-lin.cambridge.arm.com>

On Sat, Aug 15, 2015 at 02:13:44PM +0200, Ard Biesheuvel wrote:
> We need to ensure that we don't try to map system RAM ranges whose
> offset relative to the start of the kernel image exceeds the size of
> the linear range. This may happen even on systems that don't have
> huge amounts of RAM if it is laid out very sparsely.
> 
> Signed-off-by: Ard Biesheuvel <ard.biesheuvel at linaro.org>
> ---
> 
> This is the minimal fix for addressing the issue we discussed. I dropped
> the other changes for now, let's revisit those when (if) my patches for
> decoupling the kernel mapping from the linear mapping are back under
> discussion.
> 
> I will leave it up to the maintainers whether this constitutes a bugfix or
> not, but since this has never worked from the beginning afaict, I don't
> think it belongs in stable per se.

Even though it is not a regression, I think it is a bug fix and it's
worth cc'ing stable (though we could push it after 4.3-rc1).

> diff --git a/arch/arm64/mm/init.c b/arch/arm64/mm/init.c
> index ad87ce826cce..c65e57d4c3e7 100644
> --- a/arch/arm64/mm/init.c
> +++ b/arch/arm64/mm/init.c
> @@ -158,6 +158,19 @@ early_param("mem", early_mem);
>  
>  void __init arm64_memblock_init(void)
>  {
> +	/*
> +	 * Remove the memory that we will not be able to cover
> +	 * with the linear mapping.
> +	 */
> +	const s64 linear_region_size = -(s64)PAGE_OFFSET;
> +
> +	if (memstart_addr + linear_region_size < memblock_end_of_DRAM()) {
> +		pr_warn("Ignoring memory outside of linear range (0x%012llx - 0x%012llx)\n",
> +			memstart_addr + linear_region_size,
> +			(u64)memblock_end_of_DRAM() - 1);
> +		memblock_remove(memstart_addr + linear_region_size, ULLONG_MAX);
> +	}

For memory blocks below PHYS_OFFSET, we ignore them in
early_init_dt_add_memory_arch() directly (and also print a warning).
Could we not do something similar for higher blocks? This function has a
check for MAX_PHYS_ADDR but thats -1ULL, so I guess the check is pretty
much useless. We should allow the arch code define this macro and only
leave the current value as default if not overridden.

-- 
Catalin


From ard.biesheuvel at linaro.org  Mon Aug 17 03:44:50 2015
From: ard.biesheuvel at linaro.org (Ard Biesheuvel)
Date: Mon, 17 Aug 2015 12:44:50 +0200
Subject: [PATCH] arm64: ignore memory outside of the linear range
In-Reply-To: <20150817104049.GB2482@e104818-lin.cambridge.arm.com>
References: <1439640824-30498-1-git-send-email-ard.biesheuvel@linaro.org>
 <20150817104049.GB2482@e104818-lin.cambridge.arm.com>
Message-ID: <CAKv+Gu_9zx5gZBRWO_Yg082Afoc7ksy2yJm-1xqprq06ptLJQw@mail.gmail.com>

On 17 August 2015 at 12:40, Catalin Marinas <catalin.marinas at arm.com> wrote:
> On Sat, Aug 15, 2015 at 02:13:44PM +0200, Ard Biesheuvel wrote:
>> We need to ensure that we don't try to map system RAM ranges whose
>> offset relative to the start of the kernel image exceeds the size of
>> the linear range. This may happen even on systems that don't have
>> huge amounts of RAM if it is laid out very sparsely.
>>
>> Signed-off-by: Ard Biesheuvel <ard.biesheuvel at linaro.org>
>> ---
>>
>> This is the minimal fix for addressing the issue we discussed. I dropped
>> the other changes for now, let's revisit those when (if) my patches for
>> decoupling the kernel mapping from the linear mapping are back under
>> discussion.
>>
>> I will leave it up to the maintainers whether this constitutes a bugfix or
>> not, but since this has never worked from the beginning afaict, I don't
>> think it belongs in stable per se.
>
> Even though it is not a regression, I think it is a bug fix and it's
> worth cc'ing stable (though we could push it after 4.3-rc1).
>
>> diff --git a/arch/arm64/mm/init.c b/arch/arm64/mm/init.c
>> index ad87ce826cce..c65e57d4c3e7 100644
>> --- a/arch/arm64/mm/init.c
>> +++ b/arch/arm64/mm/init.c
>> @@ -158,6 +158,19 @@ early_param("mem", early_mem);
>>
>>  void __init arm64_memblock_init(void)
>>  {
>> +     /*
>> +      * Remove the memory that we will not be able to cover
>> +      * with the linear mapping.
>> +      */
>> +     const s64 linear_region_size = -(s64)PAGE_OFFSET;
>> +
>> +     if (memstart_addr + linear_region_size < memblock_end_of_DRAM()) {
>> +             pr_warn("Ignoring memory outside of linear range (0x%012llx - 0x%012llx)\n",
>> +                     memstart_addr + linear_region_size,
>> +                     (u64)memblock_end_of_DRAM() - 1);
>> +             memblock_remove(memstart_addr + linear_region_size, ULLONG_MAX);
>> +     }
>
> For memory blocks below PHYS_OFFSET, we ignore them in
> early_init_dt_add_memory_arch() directly (and also print a warning).
> Could we not do something similar for higher blocks? This function has a
> check for MAX_PHYS_ADDR but thats -1ULL, so I guess the check is pretty
> much useless. We should allow the arch code define this macro and only
> leave the current value as default if not overridden.
>

That is actually more or less what Mark Rutland proposed here

http://article.gmane.org/gmane.linux.ports.arm.kernel/430239

although his definition of the upper bound is incorrect.

I proposed to override early_init_dt_add_memory_arch() completely
instead, but Rob had some comments, after which the discussion kind of
fizzled out.

Since Stuart brought the issue back up, I responded with this version
that does the bare minimum.


From will.deacon at arm.com  Mon Aug 17 03:53:12 2015
From: will.deacon at arm.com (Will Deacon)
Date: Mon, 17 Aug 2015 11:53:12 +0100
Subject: [PATCH] arm64: ignore memory outside of the linear range
In-Reply-To: <CAKv+Gu8yspV+QtDP=iAas5J99+PezmXgC1_keEKO3zGeziRi6A@mail.gmail.com>
References: <1439640824-30498-1-git-send-email-ard.biesheuvel@linaro.org>
 <20150817094307.GD1688@arm.com>
 <CAKv+Gu8yspV+QtDP=iAas5J99+PezmXgC1_keEKO3zGeziRi6A@mail.gmail.com>
Message-ID: <20150817105311.GF1688@arm.com>

On Mon, Aug 17, 2015 at 11:35:46AM +0100, Ard Biesheuvel wrote:
> On 17 August 2015 at 11:43, Will Deacon <will.deacon at arm.com> wrote:
> > Hi Ard,
> >
> > On Sat, Aug 15, 2015 at 01:13:44PM +0100, Ard Biesheuvel wrote:
> >> We need to ensure that we don't try to map system RAM ranges whose
> >> offset relative to the start of the kernel image exceeds the size of
> >> the linear range. This may happen even on systems that don't have
> >> huge amounts of RAM if it is laid out very sparsely.
> >>
> >> Signed-off-by: Ard Biesheuvel <ard.biesheuvel at linaro.org>
> >> ---
> >>
> >> This is the minimal fix for addressing the issue we discussed. I dropped
> >> the other changes for now, let's revisit those when (if) my patches for
> >> decoupling the kernel mapping from the linear mapping are back under
> >> discussion.
> >>
> >> I will leave it up to the maintainers whether this constitutes a bugfix or
> >> not, but since this has never worked from the beginning afaict, I don't
> >> think it belongs in stable per se.
> >>
> >>  arch/arm64/mm/init.c | 13 +++++++++++++
> >>  1 file changed, 13 insertions(+)
> >>
> >> diff --git a/arch/arm64/mm/init.c b/arch/arm64/mm/init.c
> >> index ad87ce826cce..c65e57d4c3e7 100644
> >> --- a/arch/arm64/mm/init.c
> >> +++ b/arch/arm64/mm/init.c
> >> @@ -158,6 +158,19 @@ early_param("mem", early_mem);
> >>
> >>  void __init arm64_memblock_init(void)
> >>  {
> >> +     /*
> >> +      * Remove the memory that we will not be able to cover
> >> +      * with the linear mapping.
> >> +      */
> >> +     const s64 linear_region_size = -(s64)PAGE_OFFSET;
> >> +
> >> +     if (memstart_addr + linear_region_size < memblock_end_of_DRAM()) {
> >> +             pr_warn("Ignoring memory outside of linear range (0x%012llx - 0x%012llx)\n",
> >> +                     memstart_addr + linear_region_size,
> >> +                     (u64)memblock_end_of_DRAM() - 1);
> >> +             memblock_remove(memstart_addr + linear_region_size, ULLONG_MAX);
> >> +     }
> >> +
> >
> > I think this will interact badly with Mark Salter's patches to relocate
> > the initrd if it falls outside of the linear mapping (which relies on the
> > memblocks remaining intact after paging_init):
> >
> >   https://lkml.org/lkml/2015/8/16/75
> >
> 
> Are you sure? By the looks of it, these patches combined would
> correctly address the case where no mem= is passed, but the initial
> ramdisk is loaded past the end of the linear region.
> 
> I.e., memblock_end_of_DRAM() will return the clipped value, which
> would be smaller than orig_end, triggering the relocation machinery
> which moves it inside the linear region.

Ok. I was trying to consider the case where the initrd is outside of the
linear mapping not because of a restrictive "mem=", but because its out
of range of our page tables. AFAICT, we'll end up attempting to memcpy
the thing back down (but I appreciate that things won't work without
your patch too).

Will


From ard.biesheuvel at linaro.org  Mon Aug 17 03:55:33 2015
From: ard.biesheuvel at linaro.org (Ard Biesheuvel)
Date: Mon, 17 Aug 2015 12:55:33 +0200
Subject: [PATCH] arm64: ignore memory outside of the linear range
In-Reply-To: <20150817105311.GF1688@arm.com>
References: <1439640824-30498-1-git-send-email-ard.biesheuvel@linaro.org>
 <20150817094307.GD1688@arm.com>
 <CAKv+Gu8yspV+QtDP=iAas5J99+PezmXgC1_keEKO3zGeziRi6A@mail.gmail.com>
 <20150817105311.GF1688@arm.com>
Message-ID: <CAKv+Gu__o9ZFyx_nnQWm2zfacVvN7B6W-DUhLqfW8xrMeFJp_Q@mail.gmail.com>

On 17 August 2015 at 12:53, Will Deacon <will.deacon at arm.com> wrote:
> On Mon, Aug 17, 2015 at 11:35:46AM +0100, Ard Biesheuvel wrote:
>> On 17 August 2015 at 11:43, Will Deacon <will.deacon at arm.com> wrote:
>> > Hi Ard,
>> >
>> > On Sat, Aug 15, 2015 at 01:13:44PM +0100, Ard Biesheuvel wrote:
>> >> We need to ensure that we don't try to map system RAM ranges whose
>> >> offset relative to the start of the kernel image exceeds the size of
>> >> the linear range. This may happen even on systems that don't have
>> >> huge amounts of RAM if it is laid out very sparsely.
>> >>
>> >> Signed-off-by: Ard Biesheuvel <ard.biesheuvel at linaro.org>
>> >> ---
>> >>
>> >> This is the minimal fix for addressing the issue we discussed. I dropped
>> >> the other changes for now, let's revisit those when (if) my patches for
>> >> decoupling the kernel mapping from the linear mapping are back under
>> >> discussion.
>> >>
>> >> I will leave it up to the maintainers whether this constitutes a bugfix or
>> >> not, but since this has never worked from the beginning afaict, I don't
>> >> think it belongs in stable per se.
>> >>
>> >>  arch/arm64/mm/init.c | 13 +++++++++++++
>> >>  1 file changed, 13 insertions(+)
>> >>
>> >> diff --git a/arch/arm64/mm/init.c b/arch/arm64/mm/init.c
>> >> index ad87ce826cce..c65e57d4c3e7 100644
>> >> --- a/arch/arm64/mm/init.c
>> >> +++ b/arch/arm64/mm/init.c
>> >> @@ -158,6 +158,19 @@ early_param("mem", early_mem);
>> >>
>> >>  void __init arm64_memblock_init(void)
>> >>  {
>> >> +     /*
>> >> +      * Remove the memory that we will not be able to cover
>> >> +      * with the linear mapping.
>> >> +      */
>> >> +     const s64 linear_region_size = -(s64)PAGE_OFFSET;
>> >> +
>> >> +     if (memstart_addr + linear_region_size < memblock_end_of_DRAM()) {
>> >> +             pr_warn("Ignoring memory outside of linear range (0x%012llx - 0x%012llx)\n",
>> >> +                     memstart_addr + linear_region_size,
>> >> +                     (u64)memblock_end_of_DRAM() - 1);
>> >> +             memblock_remove(memstart_addr + linear_region_size, ULLONG_MAX);
>> >> +     }
>> >> +
>> >
>> > I think this will interact badly with Mark Salter's patches to relocate
>> > the initrd if it falls outside of the linear mapping (which relies on the
>> > memblocks remaining intact after paging_init):
>> >
>> >   https://lkml.org/lkml/2015/8/16/75
>> >
>>
>> Are you sure? By the looks of it, these patches combined would
>> correctly address the case where no mem= is passed, but the initial
>> ramdisk is loaded past the end of the linear region.
>>
>> I.e., memblock_end_of_DRAM() will return the clipped value, which
>> would be smaller than orig_end, triggering the relocation machinery
>> which moves it inside the linear region.
>
> Ok. I was trying to consider the case where the initrd is outside of the
> linear mapping not because of a restrictive "mem=", but because its out
> of range of our page tables. AFAICT, we'll end up attempting to memcpy
> the thing back down (but I appreciate that things won't work without
> your patch too).
>

But isn't the whole point of Mark's patches that the source initrd is
memremap()'d and copied to a destination that is covered by the kernel
direct mapping? I.e., mem= is enforced in the exact same place where
this code is added, and so the initrd will not be mapped if it is
outside of mem=


From alexandre.belloni at free-electrons.com  Mon Aug 17 03:57:24 2015
From: alexandre.belloni at free-electrons.com (Alexandre Belloni)
Date: Mon, 17 Aug 2015 12:57:24 +0200
Subject: [PATCH] drm: panel: simple: add QiaoDian qd43003c0-40
In-Reply-To: <20150817100913.GA8453@ulmo.nvidia.com>
References: <1438382671-10098-1-git-send-email-alexandre.belloni@free-electrons.com>
 <20150817100913.GA8453@ulmo.nvidia.com>
Message-ID: <20150817105724.GT22269@piout.net>

On 17/08/2015 at 12:09:14 +0200, Thierry Reding wrote :
> On Sat, Aug 01, 2015 at 12:44:31AM +0200, Alexandre Belloni wrote:
> > From: Josh Wu <josh.wu at atmel.com>
> > 
> > The QiaoDian Xianshi QD43003C0-40 is a 4"3 TFT LCD panel.
> > 
> > Timings from the OTA5180A document, ver 0.9, section
> > 10.1.1:
> >   http://www.orientdisplay.com/pdf/OTA5180A.pdf
> > 
> > Signed-off-by: Josh Wu <josh.wu at atmel.com>
> > Signed-off-by: Alexandre Belloni <alexandre.belloni at free-electrons.com>
> > ---
> >  .../devicetree/bindings/panel/qd,qd43003c0-40.txt  |  7 ++++++
> >  drivers/gpu/drm/panel/panel-simple.c               | 26 ++++++++++++++++++++++
> >  2 files changed, 33 insertions(+)
> >  create mode 100644 Documentation/devicetree/bindings/panel/qd,qd43003c0-40.txt
> 
> You didn't run this through scripts/get_maintainer.pl, did you? It would
> also help to use the standard prefix ("drm/panel: ") because I end up
> filtering for that occasionally in case somebody didn't Cc me on panel
> patches.
> 

I'm pretty sure I did as you were the only one in the To: field.
Maybe you want to check your spam filter.


-- 
Alexandre Belloni, Free Electrons
Embedded Linux, Kernel and Android engineering
http://free-electrons.com


From catalin.marinas at arm.com  Mon Aug 17 04:04:55 2015
From: catalin.marinas at arm.com (Catalin Marinas)
Date: Mon, 17 Aug 2015 12:04:55 +0100
Subject: [PATCH] arm64: ignore memory outside of the linear range
In-Reply-To: <CAKv+Gu_9zx5gZBRWO_Yg082Afoc7ksy2yJm-1xqprq06ptLJQw@mail.gmail.com>
References: <1439640824-30498-1-git-send-email-ard.biesheuvel@linaro.org>
 <20150817104049.GB2482@e104818-lin.cambridge.arm.com>
 <CAKv+Gu_9zx5gZBRWO_Yg082Afoc7ksy2yJm-1xqprq06ptLJQw@mail.gmail.com>
Message-ID: <20150817110454.GC2482@e104818-lin.cambridge.arm.com>

On Mon, Aug 17, 2015 at 12:44:50PM +0200, Ard Biesheuvel wrote:
> On 17 August 2015 at 12:40, Catalin Marinas <catalin.marinas at arm.com> wrote:
> > On Sat, Aug 15, 2015 at 02:13:44PM +0200, Ard Biesheuvel wrote:
> >> We need to ensure that we don't try to map system RAM ranges whose
> >> offset relative to the start of the kernel image exceeds the size of
> >> the linear range. This may happen even on systems that don't have
> >> huge amounts of RAM if it is laid out very sparsely.
> >>
> >> Signed-off-by: Ard Biesheuvel <ard.biesheuvel at linaro.org>
> >> ---
> >>
> >> This is the minimal fix for addressing the issue we discussed. I dropped
> >> the other changes for now, let's revisit those when (if) my patches for
> >> decoupling the kernel mapping from the linear mapping are back under
> >> discussion.
> >>
> >> I will leave it up to the maintainers whether this constitutes a bugfix or
> >> not, but since this has never worked from the beginning afaict, I don't
> >> think it belongs in stable per se.
> >
> > Even though it is not a regression, I think it is a bug fix and it's
> > worth cc'ing stable (though we could push it after 4.3-rc1).
> >
> >> diff --git a/arch/arm64/mm/init.c b/arch/arm64/mm/init.c
> >> index ad87ce826cce..c65e57d4c3e7 100644
> >> --- a/arch/arm64/mm/init.c
> >> +++ b/arch/arm64/mm/init.c
> >> @@ -158,6 +158,19 @@ early_param("mem", early_mem);
> >>
> >>  void __init arm64_memblock_init(void)
> >>  {
> >> +     /*
> >> +      * Remove the memory that we will not be able to cover
> >> +      * with the linear mapping.
> >> +      */
> >> +     const s64 linear_region_size = -(s64)PAGE_OFFSET;
> >> +
> >> +     if (memstart_addr + linear_region_size < memblock_end_of_DRAM()) {
> >> +             pr_warn("Ignoring memory outside of linear range (0x%012llx - 0x%012llx)\n",
> >> +                     memstart_addr + linear_region_size,
> >> +                     (u64)memblock_end_of_DRAM() - 1);
> >> +             memblock_remove(memstart_addr + linear_region_size, ULLONG_MAX);
> >> +     }
> >
> > For memory blocks below PHYS_OFFSET, we ignore them in
> > early_init_dt_add_memory_arch() directly (and also print a warning).
> > Could we not do something similar for higher blocks? This function has a
> > check for MAX_PHYS_ADDR but thats -1ULL, so I guess the check is pretty
> > much useless. We should allow the arch code define this macro and only
> > leave the current value as default if not overridden.
> >
> 
> That is actually more or less what Mark Rutland proposed here
> 
> http://article.gmane.org/gmane.linux.ports.arm.kernel/430239

Ah, I missed this. I prefer Mark's variant more (once it's fixed).

> I proposed to override early_init_dt_add_memory_arch() completely
> instead, but Rob had some comments, after which the discussion kind of
> fizzled out.

I don't think we should override early_init_dt_add_memory_arch(), unless
we diverge too much from it. Currently, it looks to me like the end of
PA range check is pretty useless in this function.

-- 
Catalin


From ard.biesheuvel at linaro.org  Mon Aug 17 04:06:35 2015
From: ard.biesheuvel at linaro.org (Ard Biesheuvel)
Date: Mon, 17 Aug 2015 13:06:35 +0200
Subject: [PATCH] arm64: ignore memory outside of the linear range
In-Reply-To: <20150817110454.GC2482@e104818-lin.cambridge.arm.com>
References: <1439640824-30498-1-git-send-email-ard.biesheuvel@linaro.org>
 <20150817104049.GB2482@e104818-lin.cambridge.arm.com>
 <CAKv+Gu_9zx5gZBRWO_Yg082Afoc7ksy2yJm-1xqprq06ptLJQw@mail.gmail.com>
 <20150817110454.GC2482@e104818-lin.cambridge.arm.com>
Message-ID: <CAKv+Gu9j2_u4Bbtr+yvSfiNe_Vw4ZapO+r1xqxSUmbVBJ4GB3w@mail.gmail.com>

On 17 August 2015 at 13:04, Catalin Marinas <catalin.marinas at arm.com> wrote:
> On Mon, Aug 17, 2015 at 12:44:50PM +0200, Ard Biesheuvel wrote:
>> On 17 August 2015 at 12:40, Catalin Marinas <catalin.marinas at arm.com> wrote:
>> > On Sat, Aug 15, 2015 at 02:13:44PM +0200, Ard Biesheuvel wrote:
>> >> We need to ensure that we don't try to map system RAM ranges whose
>> >> offset relative to the start of the kernel image exceeds the size of
>> >> the linear range. This may happen even on systems that don't have
>> >> huge amounts of RAM if it is laid out very sparsely.
>> >>
>> >> Signed-off-by: Ard Biesheuvel <ard.biesheuvel at linaro.org>
>> >> ---
>> >>
>> >> This is the minimal fix for addressing the issue we discussed. I dropped
>> >> the other changes for now, let's revisit those when (if) my patches for
>> >> decoupling the kernel mapping from the linear mapping are back under
>> >> discussion.
>> >>
>> >> I will leave it up to the maintainers whether this constitutes a bugfix or
>> >> not, but since this has never worked from the beginning afaict, I don't
>> >> think it belongs in stable per se.
>> >
>> > Even though it is not a regression, I think it is a bug fix and it's
>> > worth cc'ing stable (though we could push it after 4.3-rc1).
>> >
>> >> diff --git a/arch/arm64/mm/init.c b/arch/arm64/mm/init.c
>> >> index ad87ce826cce..c65e57d4c3e7 100644
>> >> --- a/arch/arm64/mm/init.c
>> >> +++ b/arch/arm64/mm/init.c
>> >> @@ -158,6 +158,19 @@ early_param("mem", early_mem);
>> >>
>> >>  void __init arm64_memblock_init(void)
>> >>  {
>> >> +     /*
>> >> +      * Remove the memory that we will not be able to cover
>> >> +      * with the linear mapping.
>> >> +      */
>> >> +     const s64 linear_region_size = -(s64)PAGE_OFFSET;
>> >> +
>> >> +     if (memstart_addr + linear_region_size < memblock_end_of_DRAM()) {
>> >> +             pr_warn("Ignoring memory outside of linear range (0x%012llx - 0x%012llx)\n",
>> >> +                     memstart_addr + linear_region_size,
>> >> +                     (u64)memblock_end_of_DRAM() - 1);
>> >> +             memblock_remove(memstart_addr + linear_region_size, ULLONG_MAX);
>> >> +     }
>> >
>> > For memory blocks below PHYS_OFFSET, we ignore them in
>> > early_init_dt_add_memory_arch() directly (and also print a warning).
>> > Could we not do something similar for higher blocks? This function has a
>> > check for MAX_PHYS_ADDR but thats -1ULL, so I guess the check is pretty
>> > much useless. We should allow the arch code define this macro and only
>> > leave the current value as default if not overridden.
>> >
>>
>> That is actually more or less what Mark Rutland proposed here
>>
>> http://article.gmane.org/gmane.linux.ports.arm.kernel/430239
>
> Ah, I missed this. I prefer Mark's variant more (once it's fixed).
>
>> I proposed to override early_init_dt_add_memory_arch() completely
>> instead, but Rob had some comments, after which the discussion kind of
>> fizzled out.
>
> I don't think we should override early_init_dt_add_memory_arch(), unless
> we diverge too much from it. Currently, it looks to me like the end of
> PA range check is pretty useless in this function.
>

OK. But note that, when we decouple the linear mapping from the
mapping of the kernel image, we will need to override this function
anyway.


From will.deacon at arm.com  Mon Aug 17 04:11:30 2015
From: will.deacon at arm.com (Will Deacon)
Date: Mon, 17 Aug 2015 12:11:30 +0100
Subject: [PATCH] arm64: ignore memory outside of the linear range
In-Reply-To: <CAKv+Gu__o9ZFyx_nnQWm2zfacVvN7B6W-DUhLqfW8xrMeFJp_Q@mail.gmail.com>
References: <1439640824-30498-1-git-send-email-ard.biesheuvel@linaro.org>
 <20150817094307.GD1688@arm.com>
 <CAKv+Gu8yspV+QtDP=iAas5J99+PezmXgC1_keEKO3zGeziRi6A@mail.gmail.com>
 <20150817105311.GF1688@arm.com>
 <CAKv+Gu__o9ZFyx_nnQWm2zfacVvN7B6W-DUhLqfW8xrMeFJp_Q@mail.gmail.com>
Message-ID: <20150817111130.GG1688@arm.com>

On Mon, Aug 17, 2015 at 11:55:33AM +0100, Ard Biesheuvel wrote:
> On 17 August 2015 at 12:53, Will Deacon <will.deacon at arm.com> wrote:
> > On Mon, Aug 17, 2015 at 11:35:46AM +0100, Ard Biesheuvel wrote:
> >> On 17 August 2015 at 11:43, Will Deacon <will.deacon at arm.com> wrote:
> >> > On Sat, Aug 15, 2015 at 01:13:44PM +0100, Ard Biesheuvel wrote:
> >> >> diff --git a/arch/arm64/mm/init.c b/arch/arm64/mm/init.c
> >> >> index ad87ce826cce..c65e57d4c3e7 100644
> >> >> --- a/arch/arm64/mm/init.c
> >> >> +++ b/arch/arm64/mm/init.c
> >> >> @@ -158,6 +158,19 @@ early_param("mem", early_mem);
> >> >>
> >> >>  void __init arm64_memblock_init(void)
> >> >>  {
> >> >> +     /*
> >> >> +      * Remove the memory that we will not be able to cover
> >> >> +      * with the linear mapping.
> >> >> +      */
> >> >> +     const s64 linear_region_size = -(s64)PAGE_OFFSET;
> >> >> +
> >> >> +     if (memstart_addr + linear_region_size < memblock_end_of_DRAM()) {
> >> >> +             pr_warn("Ignoring memory outside of linear range (0x%012llx - 0x%012llx)\n",
> >> >> +                     memstart_addr + linear_region_size,
> >> >> +                     (u64)memblock_end_of_DRAM() - 1);
> >> >> +             memblock_remove(memstart_addr + linear_region_size, ULLONG_MAX);
> >> >> +     }
> >> >> +
> >> >
> >> > I think this will interact badly with Mark Salter's patches to relocate
> >> > the initrd if it falls outside of the linear mapping (which relies on the
> >> > memblocks remaining intact after paging_init):
> >> >
> >> >   https://lkml.org/lkml/2015/8/16/75
> >> >
> >>
> >> Are you sure? By the looks of it, these patches combined would
> >> correctly address the case where no mem= is passed, but the initial
> >> ramdisk is loaded past the end of the linear region.
> >>
> >> I.e., memblock_end_of_DRAM() will return the clipped value, which
> >> would be smaller than orig_end, triggering the relocation machinery
> >> which moves it inside the linear region.
> >
> > Ok. I was trying to consider the case where the initrd is outside of the
> > linear mapping not because of a restrictive "mem=", but because its out
> > of range of our page tables. AFAICT, we'll end up attempting to memcpy
> > the thing back down (but I appreciate that things won't work without
> > your patch too).
> >
> 
> But isn't the whole point of Mark's patches that the source initrd is
> memremap()'d and copied to a destination that is covered by the kernel
> direct mapping? I.e., mem= is enforced in the exact same place where
> this code is added, and so the initrd will not be mapped if it is
> outside of mem=

Yes, you're right. I'd somehow confused myself with the to_free case,
but it all falls out in the wash and we'll map what we need to map
before copying the initrd down.

Will


From johan at kernel.org  Mon Aug 17 04:16:25 2015
From: johan at kernel.org (Johan Hovold)
Date: Mon, 17 Aug 2015 13:16:25 +0200
Subject: [PATCH v2 8/9] usb: serial: mxuport: Simplify return statement
In-Reply-To: <05a5da593419a88886b1e75a0135d7b051b4bb76.1438695318.git.skarajga@visteon.com>
References: <cover.1438695318.git.skarajga@visteon.com>
 <05a5da593419a88886b1e75a0135d7b051b4bb76.1438695318.git.skarajga@visteon.com>
Message-ID: <20150817111625.GE7053@localhost>

On Tue, Aug 04, 2015 at 02:04:35PM +0000, Karajgaonkar, Saurabh (S.) wrote:
> From: Saurabh Karajgaonkar <skarajga at visteon.com>
> 
> Replace redundant variable use in return statement.
> 
> Signed-off-by: Saurabh Karajgaonkar <skarajga at visteon.com>
> ---
>  drivers/usb/serial/mxuport.c | 10 +++-------
>  1 file changed, 3 insertions(+), 7 deletions(-)
> 
> diff --git a/drivers/usb/serial/mxuport.c b/drivers/usb/serial/mxuport.c
> index 460a406..31a8b47 100644
> --- a/drivers/usb/serial/mxuport.c
> +++ b/drivers/usb/serial/mxuport.c
> @@ -1137,13 +1137,9 @@ static int mxuport_port_probe(struct usb_serial_port *port)
>  		return err;
>  
>  	/* Set interface (RS-232) */
> -	err = mxuport_send_ctrl_urb(serial, RQ_VENDOR_SET_INTERFACE,
> -				    MX_INT_RS232,
> -				    port->port_number);
> -	if (err)
> -		return err;
> -
> -	return 0;
> +	return mxuport_send_ctrl_urb(serial, RQ_VENDOR_SET_INTERFACE,
> +				     MX_INT_RS232,
> +				     port->port_number);

I do not consider this an improvement as it makes the final ctrl-request
call look different from the previous two without any real benefit.

I'll drop this one.

Johan


From koro.chen at mediatek.com  Mon Aug 17 04:16:51 2015
From: koro.chen at mediatek.com (Koro Chen)
Date: Mon, 17 Aug 2015 19:16:51 +0800
Subject: [PATCH] ASoC: mediatek: Remove AIF widgets for backend DAIs
Message-ID: <1439810211-45518-1-git-send-email-koro.chen@mediatek.com>

DAPM core already creates widgets for DAIs. It is not necessary
to declare them by SND_SOC_DAPM_AIF_IN/SND_SOC_DAPM_AIF_OUT.
Furthermore, original codes use backend DAI's stream name to be the AIF
widget name. It causes the same widget to be created twice, and after
commit 92fa12426741 ("ASoC: dapm: Add new widgets to the end of the
widget list") the first created widget (by snd_soc_dapm_new_controls)
is used, not the 2nd created one (by snd_soc_dapm_new_dai_widgets),
so audio path is broken.

Signed-off-by: Koro Chen <koro.chen at mediatek.com>
---
 sound/soc/mediatek/mtk-afe-pcm.c |   11 -----------
 1 file changed, 11 deletions(-)

diff --git a/sound/soc/mediatek/mtk-afe-pcm.c b/sound/soc/mediatek/mtk-afe-pcm.c
index 55471ee..d190fe0 100644
--- a/sound/soc/mediatek/mtk-afe-pcm.c
+++ b/sound/soc/mediatek/mtk-afe-pcm.c
@@ -897,10 +897,6 @@ static const struct snd_kcontrol_new mtk_afe_o10_mix[] = {
 };
 
 static const struct snd_soc_dapm_widget mtk_afe_pcm_widgets[] = {
-	/* Backend DAIs  */
-	SND_SOC_DAPM_AIF_IN("I2S Capture", NULL, 0, SND_SOC_NOPM, 0, 0),
-	SND_SOC_DAPM_AIF_OUT("I2S Playback", NULL, 0, SND_SOC_NOPM, 0, 0),
-
 	/* inter-connections */
 	SND_SOC_DAPM_MIXER("I05", SND_SOC_NOPM, 0, 0, NULL, 0),
 	SND_SOC_DAPM_MIXER("I06", SND_SOC_NOPM, 0, 0, NULL, 0),
@@ -932,11 +928,6 @@ static const struct snd_soc_dapm_route mtk_afe_pcm_routes[] = {
 	{ "O10", "I18 Switch", "I18" },
 };
 
-static const struct snd_soc_dapm_widget mtk_afe_hdmi_widgets[] = {
-	/* Backend DAIs  */
-	SND_SOC_DAPM_AIF_OUT("HDMIO Playback", NULL, 0, SND_SOC_NOPM, 0, 0),
-};
-
 static const struct snd_soc_dapm_route mtk_afe_hdmi_routes[] = {
 	{"HDMIO Playback", NULL, "HDMI"},
 };
@@ -951,8 +942,6 @@ static const struct snd_soc_component_driver mtk_afe_pcm_dai_component = {
 
 static const struct snd_soc_component_driver mtk_afe_hdmi_dai_component = {
 	.name = "mtk-afe-hdmi-dai",
-	.dapm_widgets = mtk_afe_hdmi_widgets,
-	.num_dapm_widgets = ARRAY_SIZE(mtk_afe_hdmi_widgets),
 	.dapm_routes = mtk_afe_hdmi_routes,
 	.num_dapm_routes = ARRAY_SIZE(mtk_afe_hdmi_routes),
 };
-- 
1.7.9.5



From will.deacon at arm.com  Mon Aug 17 04:22:56 2015
From: will.deacon at arm.com (Will Deacon)
Date: Mon, 17 Aug 2015 12:22:56 +0100
Subject: [PATCH V3 2/3] arm64: support initrd outside kernel linear map
In-Reply-To: <1439758168-29427-3-git-send-email-msalter@redhat.com>
References: <1439758168-29427-1-git-send-email-msalter@redhat.com>
 <1439758168-29427-3-git-send-email-msalter@redhat.com>
Message-ID: <20150817112256.GH1688@arm.com>

Hi Mark,

On Sun, Aug 16, 2015 at 09:49:27PM +0100, Mark Salter wrote:
> The use of mem= could leave part or all of the initrd outside of
> the kernel linear map. This will lead to an error when unpacking
> the initrd and a probable failure to boot. This patch catches that
> situation and relocates the initrd to be fully within the linear
> map.
> 
> Signed-off-by: Mark Salter <msalter at redhat.com>
> ---
>  arch/arm64/kernel/setup.c | 59 +++++++++++++++++++++++++++++++++++++++++++++++
>  1 file changed, 59 insertions(+)
> 
> diff --git a/arch/arm64/kernel/setup.c b/arch/arm64/kernel/setup.c
> index f3067d4..5f45fd9 100644
> --- a/arch/arm64/kernel/setup.c
> +++ b/arch/arm64/kernel/setup.c
> @@ -359,6 +359,64 @@ static void __init request_standard_resources(void)
>  	}
>  }
>  
> +#ifdef CONFIG_BLK_DEV_INITRD
> +/*
> + * Relocate initrd if it is not completely within the linear mapping.
> + * This would be the case if mem= cuts out all or part of it.
> + */
> +static void __init relocate_initrd(void)
> +{
> +	phys_addr_t orig_start = __virt_to_phys(initrd_start);
> +	phys_addr_t orig_end = __virt_to_phys(initrd_end);

Any particular reason to use the __* variants here?

> +	phys_addr_t ram_end = memblock_end_of_DRAM();
> +	phys_addr_t new_start;
> +	unsigned long size, to_free = 0;
> +	void *dest;
> +
> +	if (orig_end <= ram_end)
> +		return;
> +
> +	/* Note if any of original initrd will freeing below */

The comment doesn't make sense.

> +	if (orig_start < ram_end)
> +		to_free = ram_end - orig_start;
> +
> +	size = orig_end - orig_start;
> +
> +	/* initrd needs to be relocated completely inside linear mapping */
> +	new_start = memblock_find_in_range(0, PFN_PHYS(max_pfn),
> +					   size, PAGE_SIZE);
> +	if (!new_start)
> +		panic("Cannot relocate initrd of size %ld\n", size);
> +	memblock_reserve(new_start, size);
> +
> +	initrd_start = __phys_to_virt(new_start);
> +	initrd_end   = initrd_start + size;
> +
> +	pr_info("Moving initrd from [%llx-%llx] to [%llx-%llx]\n",
> +		orig_start, orig_start + size - 1,
> +		new_start, new_start + size - 1);
> +
> +	dest = (void *)initrd_start;
> +
> +	if (to_free) {
> +		memcpy(dest, (void *)__phys_to_virt(orig_start), to_free);
> +		dest += to_free;
> +	}
> +
> +	copy_from_early_mem(dest, orig_start + to_free, size - to_free);
> +
> +	if (to_free) {
> +		pr_info("Freeing original RAMDISK from [%llx-%llx]\n",
> +			orig_start, orig_start + to_free - 1);
> +		memblock_free(orig_start, to_free);
> +	}
> +}
> +#else
> +static inline void __init reserve_initrd(void)

relocate_initrd ?

Will


From jh80.chung at samsung.com  Mon Aug 17 04:26:05 2015
From: jh80.chung at samsung.com (Jaehoon Chung)
Date: Mon, 17 Aug 2015 20:26:05 +0900
Subject: [PATCH 2/3] mmc: dw_mmc: simplify the SDMMC_CLKEN_LOW_PWR logic
In-Reply-To: <CAOMqctQ8DHj6qPg8zR93OGRHXAZDd0yUmG_J8Vz7dGFuDpCgRQ@mail.gmail.com>
References: <cover.1439381423.git.hramrach@gmail.com>
 <3d03bfe2c18789eefa038018467c9c63c94ae4a2.1439381423.git.hramrach@gmail.com>
 <55D13F07.70309@samsung.com>
 <CAOMqctQ8DHj6qPg8zR93OGRHXAZDd0yUmG_J8Vz7dGFuDpCgRQ@mail.gmail.com>
Message-ID: <55D1C4CD.4040200@samsung.com>

On 08/17/2015 02:52 PM, Michal Suchanek wrote:
> Hello,
> 
> On 17 August 2015 at 03:55, Jaehoon Chung <jh80.chung at samsung.com> wrote:
>> Hi, Michal.
>>
>> On 08/12/2015 09:23 PM, Michal Suchanek wrote:
>>> The driver has open-coded test for SDIO cards. Use the mmc core provided
>>> MMC_QUIRK_BROKEN_CLK_GATING flag instead.
>>
>> Did you use the clock-gating for SDIO cards?
>> Doesn't MMC_CAP_SDIO_IRQ bit set? Which case is broken?
>> Could you explain to me more?
> 
> The core flag for disabling power saving is MMC_QUIRK_BROKEN_CLK_GATING.

I understood your intention. And i read the comment into mmc/core/quirks.c
I will test SDIO card with this patch. Thanks.

Best Regards,
Jaehoon Chung

> 
> It may coincide with MMC_CAP_SDIO_IRQ but that's different flag for
> different purpose.
> 
> MMC_QUIRK_BROKEN_CLK_GATING is currently set for all SDIO cards except
> for cards on a whitelist.
> 
> I don't know any particular SDIO card that has problems when the clock
> is off and does not use an IRQ.
> 
> Thanks
> 
> Michal
> 
>>
>> Best Regards,
>> Jaehoon Chung
>>
>>>
>>> As a bonus this may enable clock gating on SDIO cards that are known to
>>> work with it.
>>>
>>> Signed-off-by: Michal Suchanek <hramrach at gmail.com>
>>> ---
>>>  drivers/mmc/host/dw_mmc.c | 33 +++++++++++++++------------------
>>>  1 file changed, 15 insertions(+), 18 deletions(-)
>>>
>>> diff --git a/drivers/mmc/host/dw_mmc.c b/drivers/mmc/host/dw_mmc.c
>>> index 40e9d8e..3bc9fd7 100644
>>> --- a/drivers/mmc/host/dw_mmc.c
>>> +++ b/drivers/mmc/host/dw_mmc.c
>>> @@ -1335,27 +1335,24 @@ static void dw_mci_init_card(struct mmc_host *mmc, struct mmc_card *card)
>>>        * description of the CLKENA register we should disable low power mode
>>>        * for SDIO cards if we need SDIO interrupts to work.
>>>        */
>>> -     if (mmc->caps & MMC_CAP_SDIO_IRQ) {
>>> -             const u32 clken_low_pwr = SDMMC_CLKEN_LOW_PWR << slot->id;
>>> -             u32 clk_en_a_old;
>>> -             u32 clk_en_a;
>>> +     const u32 clken_low_pwr = SDMMC_CLKEN_LOW_PWR << slot->id;
>>> +     u32 clk_en_a_old;
>>> +     u32 clk_en_a;
>>>
>>> -             clk_en_a_old = mci_readl(host, CLKENA);
>>> +     clk_en_a_old = mci_readl(host, CLKENA);
>>>
>>> -             if (card->type == MMC_TYPE_SDIO ||
>>> -                 card->type == MMC_TYPE_SD_COMBO) {
>>> -                     set_bit(DW_MMC_CARD_NO_LOW_PWR, &slot->flags);
>>> -                     clk_en_a = clk_en_a_old & ~clken_low_pwr;
>>> -             } else {
>>> -                     clear_bit(DW_MMC_CARD_NO_LOW_PWR, &slot->flags);
>>> -                     clk_en_a = clk_en_a_old | clken_low_pwr;
>>> -             }
>>> +     if (card->quirks & MMC_QUIRK_BROKEN_CLK_GATING) {
>>> +             set_bit(DW_MMC_CARD_NO_LOW_PWR, &slot->flags);
>>> +             clk_en_a = clk_en_a_old & ~clken_low_pwr;
>>> +     } else {
>>> +             clear_bit(DW_MMC_CARD_NO_LOW_PWR, &slot->flags);
>>> +             clk_en_a = clk_en_a_old | clken_low_pwr;
>>> +     }
>>>
>>> -             if (clk_en_a != clk_en_a_old) {
>>> -                     mci_writel(host, CLKENA, clk_en_a);
>>> -                     mci_send_cmd(slot, SDMMC_CMD_UPD_CLK |
>>> -                                  SDMMC_CMD_PRV_DAT_WAIT, 0);
>>> -             }
>>> +     if (clk_en_a != clk_en_a_old) {
>>> +             mci_writel(host, CLKENA, clk_en_a);
>>> +             mci_send_cmd(slot, SDMMC_CMD_UPD_CLK |
>>> +                             SDMMC_CMD_PRV_DAT_WAIT, 0);
>>>       }
>>>  }
>>>
>>>
>>
> --
> To unsubscribe from this list: send the line "unsubscribe linux-mmc" in
> the body of a message to majordomo at vger.kernel.org
> More majordomo info at  http://vger.kernel.org/majordomo-info.html
> 



From jszhang at marvell.com  Mon Aug 17 04:34:39 2015
From: jszhang at marvell.com (Jisheng Zhang)
Date: Mon, 17 Aug 2015 19:34:39 +0800
Subject: [PATCH] mmc: sdhci: also set driver type for MMC_DDR52
Message-ID: <1439811279-6340-1-git-send-email-jszhang@marvell.com>

commit 08f90f14aa93ad424c20bb176b52f329583e2183 ("mmc: sdhci: clarify
DDR timing mode between SD-UHS and eMMC") added MMC_DDR52 as eMMC's DDR
mode to be distinguished from SD-UHS, but it missed setting driver type
for MMC_DDR52 timing mode. This patches adds the missing driver type
setting.

Fixes: 79f7ae7c45a6("mmc: clarify DDR timing mode between SD-UHS and eMMC")
Signed-off-by: Jisheng Zhang <jszhang at marvell.com>
---
 drivers/mmc/host/sdhci.c | 3 ++-
 1 file changed, 2 insertions(+), 1 deletion(-)

diff --git a/drivers/mmc/host/sdhci.c b/drivers/mmc/host/sdhci.c
index 1dbe932..32f2a07 100644
--- a/drivers/mmc/host/sdhci.c
+++ b/drivers/mmc/host/sdhci.c
@@ -1559,7 +1559,8 @@ static void sdhci_do_set_ios(struct sdhci_host *host, struct mmc_ios *ios)
 				 (ios->timing == MMC_TIMING_UHS_SDR25) ||
 				 (ios->timing == MMC_TIMING_UHS_SDR50) ||
 				 (ios->timing == MMC_TIMING_UHS_SDR104) ||
-				 (ios->timing == MMC_TIMING_UHS_DDR50))) {
+				 (ios->timing == MMC_TIMING_UHS_DDR50) ||
+				 (ios->timing == MMC_TIMING_MMC_DDR52))) {
 			u16 preset;
 
 			sdhci_enable_preset_value(host, true);
-- 
2.5.0



From ulf.hansson at linaro.org  Mon Aug 17 04:31:58 2015
From: ulf.hansson at linaro.org (Ulf Hansson)
Date: Mon, 17 Aug 2015 13:31:58 +0200
Subject: [PATCH 1/4] mmc: mediatek: Add online-tuning support of EMMC/SD
In-Reply-To: <1439367845-5891-2-git-send-email-chaotian.jing@mediatek.com>
References: <1439367845-5891-1-git-send-email-chaotian.jing@mediatek.com>
 <1439367845-5891-2-git-send-email-chaotian.jing@mediatek.com>
Message-ID: <CAPDyKFpX4Pp1+U9eNBuGd83sBeBgLU17qysAJ-2V-ABZZHYAGQ@mail.gmail.com>

On 12 August 2015 at 10:24, Chaotian Jing <chaotian.jing at mediatek.com> wrote:
> Schedule a workqueue to do tuning when CRC error
> Call mmc_hw_reset to re-init card when data timeout

Thanks to Adrian Hunter, the mmc core already supports re-tuning for
the above scenarios through the mmc_retune_*() APIs.

SDHCI driver has already adopted to use that feature, you should do
that for the mtk-sd driver as well.

Kind regards
Uffe

>
> Signed-off-by: Chaotian Jing <chaotian.jing at mediatek.com>
> ---
>  drivers/mmc/host/mtk-sd.c | 162 ++++++++++++++++++++++++++++++++++++++++++----
>  1 file changed, 150 insertions(+), 12 deletions(-)
>
> diff --git a/drivers/mmc/host/mtk-sd.c b/drivers/mmc/host/mtk-sd.c
> index 7153500..eb44fe1 100644
> --- a/drivers/mmc/host/mtk-sd.c
> +++ b/drivers/mmc/host/mtk-sd.c
> @@ -27,6 +27,7 @@
>  #include <linux/pm_runtime.h>
>  #include <linux/regulator/consumer.h>
>  #include <linux/spinlock.h>
> +#include <linux/workqueue.h>
>
>  #include <linux/mmc/card.h>
>  #include <linux/mmc/core.h>
> @@ -290,6 +291,10 @@ struct msdc_host {
>         struct pinctrl_state *pins_default;
>         struct pinctrl_state *pins_uhs;
>         struct delayed_work req_timeout;
> +       struct workqueue_struct *repeat_workqueue;
> +       struct work_struct repeat_req;
> +       struct mmc_request *repeat_mrq;
> +       u32 tune_cmd_counter;
>         int irq;                /* host interrupt */
>
>         struct clk *src_clk;    /* msdc source clock */
> @@ -353,7 +358,10 @@ static void msdc_reset_hw(struct msdc_host *host)
>  static void msdc_cmd_next(struct msdc_host *host,
>                 struct mmc_request *mrq, struct mmc_command *cmd);
>
> -static u32 data_ints_mask = MSDC_INTEN_XFER_COMPL | MSDC_INTEN_DATTMO |
> +static const u32 cmd_ints_mask = MSDC_INTEN_CMDRDY | MSDC_INTEN_RSPCRCERR |
> +                       MSDC_INTEN_CMDTMO | MSDC_INTEN_ACMDRDY |
> +                       MSDC_INTEN_ACMDCRCERR | MSDC_INTEN_ACMDTMO;
> +static const u32 data_ints_mask = MSDC_INTEN_XFER_COMPL | MSDC_INTEN_DATTMO |
>                         MSDC_INTEN_DATCRCERR | MSDC_INTEN_DMA_BDCSERR |
>                         MSDC_INTEN_DMA_GPDCSERR | MSDC_INTEN_DMA_PROTECT;
>
> @@ -690,6 +698,18 @@ static void msdc_request_done(struct msdc_host *host, struct mmc_request *mrq)
>         msdc_track_cmd_data(host, mrq->cmd, mrq->data);
>         if (mrq->data)
>                 msdc_unprepare_data(host, mrq);
> +       if (host->error && host->mmc->card &&
> +           !mmc_card_sdio(host->mmc->card)) {
> +               if (mrq->cmd->error == (unsigned int)-EILSEQ ||
> +                   (mrq->stop && mrq->stop->error == (unsigned int)-EILSEQ) ||
> +                   (mrq->sbc && mrq->sbc->error == (unsigned int)-EILSEQ) ||
> +                   (mrq->data && mrq->data->error))  {
> +                       host->repeat_mrq = mrq;
> +                       queue_work(host->repeat_workqueue, &host->repeat_req);
> +                       return;
> +               }
> +       }
> +       host->tune_cmd_counter = 0;
>         mmc_request_done(host->mmc, mrq);
>
>         pm_runtime_mark_last_busy(host->dev);
> @@ -725,11 +745,7 @@ static bool msdc_cmd_done(struct msdc_host *host, int events,
>         if (done)
>                 return true;
>
> -       sdr_clr_bits(host->base + MSDC_INTEN, MSDC_INTEN_CMDRDY |
> -                       MSDC_INTEN_RSPCRCERR | MSDC_INTEN_CMDTMO |
> -                       MSDC_INTEN_ACMDRDY | MSDC_INTEN_ACMDCRCERR |
> -                       MSDC_INTEN_ACMDTMO);
> -       writel(cmd->arg, host->base + SDC_ARG);
> +       sdr_clr_bits(host->base + MSDC_INTEN, cmd_ints_mask);
>
>         if (cmd->flags & MMC_RSP_PRESENT) {
>                 if (cmd->flags & MMC_RSP_136) {
> @@ -819,10 +835,7 @@ static void msdc_start_command(struct msdc_host *host,
>         rawcmd = msdc_cmd_prepare_raw_cmd(host, mrq, cmd);
>         mod_delayed_work(system_wq, &host->req_timeout, DAT_TIMEOUT);
>
> -       sdr_set_bits(host->base + MSDC_INTEN, MSDC_INTEN_CMDRDY |
> -                       MSDC_INTEN_RSPCRCERR | MSDC_INTEN_CMDTMO |
> -                       MSDC_INTEN_ACMDRDY | MSDC_INTEN_ACMDCRCERR |
> -                       MSDC_INTEN_ACMDTMO);
> +       sdr_set_bits(host->base + MSDC_INTEN, cmd_ints_mask);
>         writel(cmd->arg, host->base + SDC_ARG);
>         writel(rawcmd, host->base + SDC_CMD);
>  }
> @@ -942,6 +955,8 @@ static bool msdc_data_xfer_done(struct msdc_host *host, u32 events,
>
>                         if (events & MSDC_INT_DATTMO)
>                                 data->error = -ETIMEDOUT;
> +                       else if (events & MSDC_INT_DATCRCERR)
> +                               data->error = -EILSEQ;
>
>                         dev_err(host->dev, "%s: cmd=%d; blocks=%d",
>                                 __func__, mrq->cmd->opcode, data->blocks);
> @@ -1113,8 +1128,8 @@ static void msdc_init_hw(struct msdc_host *host)
>
>         writel(0, host->base + MSDC_PAD_TUNE);
>         writel(0, host->base + MSDC_IOCON);
> -       sdr_set_field(host->base + MSDC_IOCON, MSDC_IOCON_DDLSEL, 1);
> -       writel(0x403c004f, host->base + MSDC_PATCH_BIT);
> +       sdr_set_field(host->base + MSDC_IOCON, MSDC_IOCON_DDLSEL, 0);
> +       writel(0x403c0046, host->base + MSDC_PATCH_BIT);
>         sdr_set_field(host->base + MSDC_PATCH_BIT, MSDC_CKGEN_MSDC_DLY_SEL, 1);
>         writel(0xffff0089, host->base + MSDC_PATCH_BIT1);
>         /* Configure to enable SDIO mode.
> @@ -1176,6 +1191,7 @@ static void msdc_ops_set_ios(struct mmc_host *mmc, struct mmc_ios *ios)
>         switch (ios->power_mode) {
>         case MMC_POWER_UP:
>                 if (!IS_ERR(mmc->supply.vmmc)) {
> +                       msdc_init_hw(host);
>                         ret = mmc_regulator_set_ocr(mmc, mmc->supply.vmmc,
>                                         ios->vdd);
>                         if (ret) {
> @@ -1214,6 +1230,120 @@ end:
>         pm_runtime_put_autosuspend(host->dev);
>  }
>
> +static void msdc_reset_mrq(struct mmc_request *mrq)
> +{
> +       mrq->cmd->error = 0;
> +       if (mrq->sbc)
> +               mrq->sbc->error = 0;
> +       if (mrq->data)
> +               mrq->data->error = 0;
> +       if (mrq->stop)
> +               mrq->stop->error = 0;
> +}
> +
> +/* Send CMD12 when tuning, do not check CRC error and timeout */
> +static void msdc_send_stop(struct msdc_host *host)
> +{
> +       u32 opcode = MMC_STOP_TRANSMISSION;
> +       u32 arg = 0;
> +       u32 rawcmd = 0;
> +       u32 intsts = 0;
> +
> +       /* Reset host first */
> +       msdc_reset_hw(host);
> +
> +       rawcmd = (opcode & 0x3f) | (7 << 7);
> +       rawcmd |= (1 << 14); /* stop cmd */
> +
> +       sdr_clr_bits(host->base + MSDC_INTEN, cmd_ints_mask);
> +       writel(arg, host->base + SDC_ARG);
> +       writel(rawcmd, host->base + SDC_CMD);
> +
> +       while (1) {
> +               intsts = readl(host->base + MSDC_INT);
> +               if (intsts) {
> +                       writel(intsts, host->base + MSDC_INT);
> +                       if (intsts & cmd_ints_mask) {
> +                               dev_dbg(host->dev, "result of cmd12: %x\n",
> +                                               intsts);
> +                               break;
> +                       }
> +               }
> +               udelay(1);
> +       }
> +}
> +
> +/* When tuning, CMD13 may also get crc error, so use MSDC_PS to get card status */
> +static void msdc_wait_card_not_busy(struct msdc_host *host)
> +{
> +       while (1) {
> +               if ((readl(host->base + MSDC_PS) & BIT(16)) == 0) { /* check dat0 status */
> +                       msleep_interruptible(10);
> +                       dev_dbg(host->dev, "MSDC_PS: %08x, SDC_STS: %08x\n",
> +                               readl(host->base + MSDC_PS), readl(host->base + SDC_STS));
> +               } else
> +                       break;
> +       }
> +}
> +
> +static void msdc_tune_request(struct msdc_host *host)
> +{
> +       u32 orig_rsmpl, orig_cksel;
> +       u32 cur_rsmpl, cur_cksel = 0;
> +       u32 ddr, clkmode;
> +       struct mmc_ios ios = host->mmc->ios;
> +
> +       sdr_get_field(host->base + MSDC_IOCON, MSDC_IOCON_RSPL, &orig_rsmpl);
> +       sdr_get_field(host->base + MSDC_PATCH_BIT, MSDC_CKGEN_MSDC_DLY_SEL,
> +                     &orig_cksel);
> +       cur_rsmpl = (orig_rsmpl + 1);
> +       sdr_set_field(host->base + MSDC_IOCON, MSDC_IOCON_RSPL, cur_rsmpl % 2);
> +
> +       if (ios.timing != MMC_TIMING_MMC_HS400) {
> +               sdr_set_field(host->base + MSDC_IOCON, MSDC_IOCON_DSPL,
> +                             cur_rsmpl % 2);
> +               sdr_set_field(host->base + MSDC_IOCON, MSDC_IOCON_W_DSPL,
> +                             cur_rsmpl % 2);
> +       }
> +
> +       if (cur_rsmpl >= 2) {
> +               cur_cksel = orig_cksel + 1;
> +               sdr_set_field(host->base + MSDC_PATCH_BIT,
> +                             MSDC_CKGEN_MSDC_DLY_SEL, cur_cksel % 16);
> +       }
> +
> +       if (host->tune_cmd_counter++ >= 2 * 16) {
> +               dev_warn(host->dev, "Tune fail at %dhz\n", host->mclk);
> +               host->tune_cmd_counter = 0;
> +               sdr_set_field(host->base + MSDC_IOCON, MSDC_IOCON_RSPL, 0);
> +               sdr_set_field(host->base + MSDC_PATCH_BIT,
> +                             MSDC_CKGEN_MSDC_DLY_SEL, 0);
> +               sdr_get_field(host->base + MSDC_CFG, MSDC_CFG_CKMOD, &clkmode);
> +               ddr = (clkmode == 2) ? 1 : 0;
> +               msdc_set_mclk(host, ddr, host->mclk / 2);
> +       }
> +}
> +
> +static void msdc_repeat_request(struct work_struct *work)
> +{
> +       struct msdc_host *host = container_of(work, struct msdc_host, repeat_req);
> +       struct mmc_request *mrq;
> +       unsigned long flags;
> +
> +       spin_lock_irqsave(&host->lock, flags);
> +       mrq = host->repeat_mrq;
> +       host->repeat_mrq = NULL;
> +       spin_unlock_irqrestore(&host->lock, flags);
> +       msdc_send_stop(host);
> +       msdc_wait_card_not_busy(host);
> +       if (mrq->data && mrq->data->error == -ETIMEDOUT)
> +               mmc_hw_reset(host->mmc);
> +       else
> +               msdc_tune_request(host);
> +       msdc_reset_mrq(mrq);
> +       msdc_ops_request(host->mmc, mrq);
> +}
> +
>  static struct mmc_host_ops mt_msdc_ops = {
>         .post_req = msdc_post_req,
>         .pre_req = msdc_pre_req,
> @@ -1324,6 +1454,12 @@ static int msdc_drv_probe(struct platform_device *pdev)
>         }
>         msdc_init_gpd_bd(host, &host->dma);
>         INIT_DELAYED_WORK(&host->req_timeout, msdc_request_timeout);
> +       host->repeat_workqueue = create_singlethread_workqueue("repeat_workqueue");
> +       if (!host->repeat_workqueue) {
> +               ret = -ENOMEM;
> +               goto release_mem;
> +       }
> +       INIT_WORK(&host->repeat_req, msdc_repeat_request);
>         spin_lock_init(&host->lock);
>
>         platform_set_drvdata(pdev, mmc);
> @@ -1348,6 +1484,7 @@ static int msdc_drv_probe(struct platform_device *pdev)
>  end:
>         pm_runtime_disable(host->dev);
>  release:
> +       destroy_workqueue(host->repeat_workqueue);
>         platform_set_drvdata(pdev, NULL);
>         msdc_deinit_hw(host);
>         msdc_gate_clock(host);
> @@ -1383,6 +1520,7 @@ static int msdc_drv_remove(struct platform_device *pdev)
>
>         pm_runtime_disable(host->dev);
>         pm_runtime_put_noidle(host->dev);
> +       destroy_workqueue(host->repeat_workqueue);
>         dma_free_coherent(&pdev->dev,
>                         sizeof(struct mt_gpdma_desc),
>                         host->dma.gpd, host->dma.gpd_addr);
> --
> 1.8.1.1.dirty
>


From jszhang at marvell.com  Mon Aug 17 04:41:52 2015
From: jszhang at marvell.com (Jisheng Zhang)
Date: Mon, 17 Aug 2015 19:41:52 +0800
Subject: [PATCH] mmc: sdhci: also set driver type for MMC_DDR52
In-Reply-To: <1439811279-6340-1-git-send-email-jszhang@marvell.com>
References: <1439811279-6340-1-git-send-email-jszhang@marvell.com>
Message-ID: <20150817194152.34973a0f@xhacker>

On Mon, 17 Aug 2015 19:34:39 +0800
Jisheng Zhang <jszhang at marvell.com> wrote:

> commit 08f90f14aa93ad424c20bb176b52f329583e2183 ("mmc: sdhci: clarify
> DDR timing mode between SD-UHS and eMMC") added MMC_DDR52 as eMMC's DDR
> mode to be distinguished from SD-UHS, but it missed setting driver type
> for MMC_DDR52 timing mode. This patches adds the missing driver type
> setting.

Sorry, please ignore this one. I made a mistake. will send out new version

> 
> Fixes: 79f7ae7c45a6("mmc: clarify DDR timing mode between SD-UHS and eMMC")
> Signed-off-by: Jisheng Zhang <jszhang at marvell.com>
> ---
>  drivers/mmc/host/sdhci.c | 3 ++-
>  1 file changed, 2 insertions(+), 1 deletion(-)
> 
> diff --git a/drivers/mmc/host/sdhci.c b/drivers/mmc/host/sdhci.c
> index 1dbe932..32f2a07 100644
> --- a/drivers/mmc/host/sdhci.c
> +++ b/drivers/mmc/host/sdhci.c
> @@ -1559,7 +1559,8 @@ static void sdhci_do_set_ios(struct sdhci_host *host, struct mmc_ios *ios)
>  				 (ios->timing == MMC_TIMING_UHS_SDR25) ||
>  				 (ios->timing == MMC_TIMING_UHS_SDR50) ||
>  				 (ios->timing == MMC_TIMING_UHS_SDR104) ||
> -				 (ios->timing == MMC_TIMING_UHS_DDR50))) {
> +				 (ios->timing == MMC_TIMING_UHS_DDR50) ||
> +				 (ios->timing == MMC_TIMING_MMC_DDR52))) {
>  			u16 preset;
>  
>  			sdhci_enable_preset_value(host, true);



From jszhang at marvell.com  Mon Aug 17 04:47:21 2015
From: jszhang at marvell.com (Jisheng Zhang)
Date: Mon, 17 Aug 2015 19:47:21 +0800
Subject: [PATCH v2] mmc: sdhci: also set driver type for MMC_DDR52
Message-ID: <1439812041-6596-1-git-send-email-jszhang@marvell.com>

commit bb8175a8aa42 ("mmc: sdhci: clarify DDR timing mode between
SD-UHS and eMMC") added MMC_DDR52 as eMMC's DDR mode to be
distinguished from SD-UHS, but it missed setting driver type for
MMC_DDR52 timing mode. This patches adds the missing driver type
setting.

Fixes: bb8175a8aa42 ("mmc: sdhci: clarify DDR timing mode ...")
Signed-off-by: Jisheng Zhang <jszhang at marvell.com>
---
 drivers/mmc/host/sdhci.c | 3 ++-
 1 file changed, 2 insertions(+), 1 deletion(-)

diff --git a/drivers/mmc/host/sdhci.c b/drivers/mmc/host/sdhci.c
index 1dbe932..32f2a07 100644
--- a/drivers/mmc/host/sdhci.c
+++ b/drivers/mmc/host/sdhci.c
@@ -1559,7 +1559,8 @@ static void sdhci_do_set_ios(struct sdhci_host *host, struct mmc_ios *ios)
 				 (ios->timing == MMC_TIMING_UHS_SDR25) ||
 				 (ios->timing == MMC_TIMING_UHS_SDR50) ||
 				 (ios->timing == MMC_TIMING_UHS_SDR104) ||
-				 (ios->timing == MMC_TIMING_UHS_DDR50))) {
+				 (ios->timing == MMC_TIMING_UHS_DDR50) ||
+				 (ios->timing == MMC_TIMING_MMC_DDR52))) {
 			u16 preset;
 
 			sdhci_enable_preset_value(host, true);
-- 
2.5.0



From wangzhou1 at hisilicon.com  Mon Aug 17 04:55:53 2015
From: wangzhou1 at hisilicon.com (Zhou Wang)
Date: Mon, 17 Aug 2015 19:55:53 +0800
Subject: [PATCH v7 5/6] Documentation: DT: Add HiSilicon PCIe host binding
In-Reply-To: <1439812554-180426-1-git-send-email-wangzhou1@hisilicon.com>
References: <1439812554-180426-1-git-send-email-wangzhou1@hisilicon.com>
Message-ID: <1439812554-180426-6-git-send-email-wangzhou1@hisilicon.com>

This patch adds related DTS binding document for HiSilicon PCIe host driver.

Signed-off-by: Zhou Wang <wangzhou1 at hisilicon.com>
---
 .../devicetree/bindings/pci/hisilicon-pcie.txt     | 46 ++++++++++++++++++++++
 1 file changed, 46 insertions(+)
 create mode 100644 Documentation/devicetree/bindings/pci/hisilicon-pcie.txt

diff --git a/Documentation/devicetree/bindings/pci/hisilicon-pcie.txt b/Documentation/devicetree/bindings/pci/hisilicon-pcie.txt
new file mode 100644
index 0000000..2afc9d1
--- /dev/null
+++ b/Documentation/devicetree/bindings/pci/hisilicon-pcie.txt
@@ -0,0 +1,46 @@
+HiSilicon PCIe host bridge DT description
+
+HiSilicon PCIe host controller is based on Designware PCI core.
+It shares common functions with PCIe Designware core driver and inherits
+common properties defined in
+Documentation/devicetree/bindings/pci/designware-pci.txt.
+
+Additional properties are described here:
+
+Required properties:
+- compatible: Should contain "hisilicon,hip05-pcie".
+- reg: Should contain rc_dbi, subctrl, config registers location and length.
+- reg-names: Must include the following entries:
+  "rc_dbi": controller configuration registers;
+  "subctrl": whole PCIe hosts configuration registers;
+  "config": PCIe configuration space registers.
+- msi-parent: Should be its_pcie which is an ITS receiving MSI interrupts.
+- port-id: Should be 0, 1, 2 or 3.
+
+Optional properties:
+- status: Either "ok" or "disabled".
+- dma-coherent: Present if DMA operations are coherent.
+
+Example:
+	pcie at 0xb0080000 {
+		compatible = "hisilicon,hip05-pcie", "snps,dw-pcie";
+		reg = <0 0xb0080000 0 0x10000>, <0 0xb0000000 0 0x10000>,
+		      <0x220 0x00000000 0 0x2000>;
+		reg-names = "rc_dbi", "subctrl", "config";
+		bus-range = <0  15>;
+		msi-parent = <&its_pcie>;
+		#address-cells = <3>;
+		#size-cells = <2>;
+		device_type = "pci";
+		dma-coherent;
+		ranges = <0x82000000 0 0x00000000 0x220 0x00000000 0 0x10000000>;
+		num-lanes = <8>;
+		port-id = <1>;
+		#interrupts-cells = <1>;
+		interrupts-map-mask = <0xf800 0 0 7>;
+		interrupts-map = <0x0 0 0 1 &mbigen_pcie 1 10
+				  0x0 0 0 2 &mbigen_pcie 2 11
+				  0x0 0 0 3 &mbigen_pcie 3 12
+				  0x0 0 0 4 &mbigen_pcie 4 13>;
+		status = "ok";
+	};
-- 
1.9.1



From wangzhou1 at hisilicon.com  Mon Aug 17 04:55:52 2015
From: wangzhou1 at hisilicon.com (Zhou Wang)
Date: Mon, 17 Aug 2015 19:55:52 +0800
Subject: [PATCH v7 4/6] PCI: hisi: Add PCIe host support for HiSilicon SoC
 Hip05
In-Reply-To: <1439812554-180426-1-git-send-email-wangzhou1@hisilicon.com>
References: <1439812554-180426-1-git-send-email-wangzhou1@hisilicon.com>
Message-ID: <1439812554-180426-5-git-send-email-wangzhou1@hisilicon.com>

This patch adds PCIe host support for HiSilicon SoC Hip05.

Signed-off-by: Zhou Wang <wangzhou1 at hisilicon.com>
---
 drivers/pci/host/Kconfig     |   8 ++
 drivers/pci/host/Makefile    |   1 +
 drivers/pci/host/pcie-hisi.c | 254 +++++++++++++++++++++++++++++++++++++++++++
 3 files changed, 263 insertions(+)
 create mode 100644 drivers/pci/host/pcie-hisi.c

diff --git a/drivers/pci/host/Kconfig b/drivers/pci/host/Kconfig
index c132bdd..cd2b80b 100644
--- a/drivers/pci/host/Kconfig
+++ b/drivers/pci/host/Kconfig
@@ -145,4 +145,12 @@ config PCIE_IPROC_BCMA
 	  Say Y here if you want to use the Broadcom iProc PCIe controller
 	  through the BCMA bus interface
 
+config PCI_HISI
+	depends on OF && ARM64
+	bool "HiSilicon SoC HIP05 PCIe controller"
+	select PCIEPORTBUS
+	select PCIE_DW
+	help
+	  Say Y here if you want PCIe controller support on HiSilicon HIP05 SoC
+
 endmenu
diff --git a/drivers/pci/host/Makefile b/drivers/pci/host/Makefile
index 140d66f..ea1dbf2 100644
--- a/drivers/pci/host/Makefile
+++ b/drivers/pci/host/Makefile
@@ -17,3 +17,4 @@ obj-$(CONFIG_PCI_VERSATILE) += pci-versatile.o
 obj-$(CONFIG_PCIE_IPROC) += pcie-iproc.o
 obj-$(CONFIG_PCIE_IPROC_PLATFORM) += pcie-iproc-platform.o
 obj-$(CONFIG_PCIE_IPROC_BCMA) += pcie-iproc-bcma.o
+obj-$(CONFIG_PCI_HISI) += pcie-hisi.o
diff --git a/drivers/pci/host/pcie-hisi.c b/drivers/pci/host/pcie-hisi.c
new file mode 100644
index 0000000..7dcacf1
--- /dev/null
+++ b/drivers/pci/host/pcie-hisi.c
@@ -0,0 +1,254 @@
+/*
+ * PCIe host controller driver for HiSilicon Hip05 SoC
+ *
+ * Copyright (C) 2015 HiSilicon Co., Ltd. http://www.hisilicon.com
+ *
+ * Author: Zhou Wang <wangzhou1 at hisilicon.com>
+ *         Dacai Zhu <zhudacai at hisilicon.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.
+ */
+#include <linux/interrupt.h>
+#include <linux/irqdomain.h>
+#include <linux/module.h>
+#include <linux/of.h>
+#include <linux/of_pci.h>
+#include <linux/platform_device.h>
+
+#include "pcie-designware.h"
+
+#define PCIE_SUBCTRL_MODE_REG                           0x2800
+#define PCIE_SUBCTRL_SYS_STATE4_REG                     0x6818
+#define PCIE_SLV_DBI_MODE                               0x0
+#define PCIE_SLV_SYSCTRL_MODE                           0x1
+#define PCIE_SLV_CONTENT_MODE                           0x2
+#define PCIE_SLV_MSI_ASID                               0x10
+#define PCIE_LTSSM_LINKUP_STATE                         0x11
+#define PCIE_LTSSM_STATE_MASK                           0x3F
+#define PCIE_MSI_ASID_ENABLE                            (0x1 << 12)
+#define PCIE_MSI_ASID_VALUE                             (0x1 << 16)
+#define PCIE_MSI_TRANS_ENABLE                           (0x1 << 12)
+#define PCIE_MSI_TRANS_REG                              0x1c8
+#define PCIE_MSI_LOW_ADDRESS                            0x1b4
+#define PCIE_MSI_HIGH_ADDRESS                           0x1c4
+#define PCIE_MSI_ADDRESS_VAL                            0xb7010040
+
+#define to_hisi_pcie(x)	container_of(x, struct hisi_pcie, pp)
+
+struct hisi_pcie {
+	void __iomem *subctrl_base;
+	void __iomem *reg_base;
+	struct msi_controller *msi;
+	u32 port_id;
+	struct pcie_port pp;
+};
+
+static inline void hisi_pcie_subctrl_writel(struct hisi_pcie *pcie,
+					    u32 val, u32 reg)
+{
+	writel(val, pcie->subctrl_base + reg);
+}
+
+static inline u32 hisi_pcie_subctrl_readl(struct hisi_pcie *pcie, u32 reg)
+{
+	return readl(pcie->subctrl_base + reg);
+}
+
+static inline void hisi_pcie_apb_writel(struct hisi_pcie *pcie,
+					u32 val, u32 reg)
+{
+	writel(val, pcie->reg_base + reg);
+}
+
+static inline u32 hisi_pcie_apb_readl(struct hisi_pcie *pcie, u32 reg)
+{
+	return readl(pcie->reg_base + reg);
+}
+
+/*
+ * Change mode to indicate the same reg_base to base of PCIe host configure
+ * registers, base of RC configure space or base of vmid/asid context table
+ */
+static void hisi_pcie_change_apb_mode(struct hisi_pcie *pcie, u32 mode)
+{
+	u32 val;
+	u32 bit_mask;
+	u32 bit_shift;
+	u32 port_id = pcie->port_id;
+	u32 reg = PCIE_SUBCTRL_MODE_REG + 0x100 * port_id;
+
+	if ((port_id == 1) || (port_id == 2)) {
+		bit_mask = 0xc;
+		bit_shift = 0x2;
+	} else {
+		bit_mask = 0x6;
+		bit_shift = 0x1;
+	}
+
+	val = hisi_pcie_subctrl_readl(pcie, reg);
+	val = (val & (~bit_mask)) | (mode << bit_shift);
+	hisi_pcie_subctrl_writel(pcie, val, reg);
+}
+
+/* Configure vmid/asid table in PCIe host */
+static void hisi_pcie_config_context(struct hisi_pcie *pcie)
+{
+	int i;
+
+	hisi_pcie_change_apb_mode(pcie, PCIE_SLV_CONTENT_MODE);
+
+	/*
+	 * init vmid and asid tables for all PCIe devices as 0
+	 * vmid table: 0 ~ 0x3ff, asid table: 0x400 ~ 0x7ff
+	 */
+	for (i = 0; i < 0x800; i++)
+		hisi_pcie_apb_writel(pcie, 0x0, i * 4);
+
+	hisi_pcie_change_apb_mode(pcie, PCIE_SLV_SYSCTRL_MODE);
+
+	hisi_pcie_apb_writel(pcie, PCIE_MSI_ADDRESS_VAL, PCIE_MSI_LOW_ADDRESS);
+	hisi_pcie_apb_writel(pcie, 0x0, PCIE_MSI_HIGH_ADDRESS);
+	hisi_pcie_apb_writel(pcie, PCIE_MSI_ASID_ENABLE | PCIE_MSI_ASID_VALUE,
+			     PCIE_SLV_MSI_ASID);
+	hisi_pcie_apb_writel(pcie, PCIE_MSI_TRANS_ENABLE, PCIE_MSI_TRANS_REG);
+
+	hisi_pcie_change_apb_mode(pcie, PCIE_SLV_DBI_MODE);
+}
+
+static int hisi_pcie_link_up(struct pcie_port *pp)
+{
+	u32 val;
+	struct hisi_pcie *hisi_pcie = to_hisi_pcie(pp);
+
+	val = hisi_pcie_subctrl_readl(hisi_pcie, PCIE_SUBCTRL_SYS_STATE4_REG +
+				      0x100 * hisi_pcie->port_id);
+
+	return ((val & PCIE_LTSSM_STATE_MASK) == PCIE_LTSSM_LINKUP_STATE);
+}
+
+static
+int hisi_pcie_msi_host_init(struct pcie_port *pp, struct msi_controller *chip)
+{
+	struct device_node *msi_node;
+	struct irq_domain *irq_domain;
+	struct device_node *np = pp->dev->of_node;
+
+	msi_node = of_parse_phandle(np, "msi-parent", 0);
+	if (!msi_node) {
+		dev_err(pp->dev, "failed to find msi-parent\n");
+		return -ENODEV;
+	}
+
+	irq_domain = irq_find_host(msi_node);
+	if (!irq_domain) {
+		dev_err(pp->dev, "failed to find irq domain\n");
+		return -ENODEV;
+	}
+
+	pp->irq_domain = irq_domain;
+
+	return 0;
+}
+
+static struct pcie_host_ops hisi_pcie_host_ops = {
+	.link_up = hisi_pcie_link_up,
+	.msi_host_init = hisi_pcie_msi_host_init,
+};
+
+static int __init hisi_add_pcie_port(struct pcie_port *pp,
+				     struct platform_device *pdev)
+{
+	int ret;
+	u32 port_id;
+	struct resource busn;
+	struct hisi_pcie *hisi_pcie = to_hisi_pcie(pp);
+
+	if (of_property_read_u32(pdev->dev.of_node, "port-id", &port_id)) {
+		dev_err(&pdev->dev, "failed to read port-id\n");
+		return -EINVAL;
+	}
+	if (port_id > 3) {
+		dev_err(&pdev->dev, "Invalid port-id: %d\n", port_id);
+		return -EINVAL;
+	}
+
+	hisi_pcie->port_id = port_id;
+
+	if (of_pci_parse_bus_range(pdev->dev.of_node, &busn)) {
+		dev_err(&pdev->dev, "failed to parse bus-ranges\n");
+		return -EINVAL;
+	}
+
+	pp->root_bus_nr = busn.start;
+	pp->ops = &hisi_pcie_host_ops;
+
+	hisi_pcie_config_context(hisi_pcie);
+
+	ret = dw_pcie_host_init(pp);
+	if (ret) {
+		dev_err(&pdev->dev, "failed to initialize host\n");
+		return ret;
+	}
+
+	return 0;
+}
+
+static int __init hisi_pcie_probe(struct platform_device *pdev)
+{
+	struct hisi_pcie *hisi_pcie;
+	struct pcie_port *pp;
+	struct resource *reg;
+	struct resource *subctrl;
+	int ret;
+
+	hisi_pcie = devm_kzalloc(&pdev->dev, sizeof(*hisi_pcie), GFP_KERNEL);
+	if (!hisi_pcie)
+		return -ENOMEM;
+
+	pp = &hisi_pcie->pp;
+	pp->dev = &pdev->dev;
+
+	subctrl = platform_get_resource_byname(pdev, IORESOURCE_MEM, "subctrl");
+	hisi_pcie->subctrl_base = devm_ioremap_nocache(&pdev->dev,
+					subctrl->start, resource_size(subctrl));
+	if (IS_ERR(hisi_pcie->subctrl_base)) {
+		dev_err(pp->dev, "cannot get subctrl base\n");
+		return PTR_ERR(hisi_pcie->subctrl_base);
+	}
+
+	reg = platform_get_resource_byname(pdev, IORESOURCE_MEM, "rc_dbi");
+	hisi_pcie->reg_base = devm_ioremap_resource(&pdev->dev, reg);
+	if (IS_ERR(hisi_pcie->reg_base)) {
+		dev_err(pp->dev, "cannot get rc_dbi base\n");
+		return PTR_ERR(hisi_pcie->reg_base);
+	}
+
+	hisi_pcie->pp.dbi_base = hisi_pcie->reg_base;
+
+	ret = hisi_add_pcie_port(pp, pdev);
+	if (ret)
+		return ret;
+
+	platform_set_drvdata(pdev, hisi_pcie);
+
+	return 0;
+}
+
+static const struct of_device_id hisi_pcie_of_match[] = {
+	{.compatible = "hisilicon,hip05-pcie",},
+	{},
+};
+
+MODULE_DEVICE_TABLE(of, hisi_pcie_of_match);
+
+static struct platform_driver hisi_pcie_driver = {
+	.probe  = hisi_pcie_probe,
+	.driver = {
+		   .name = "hisi-pcie",
+		   .of_match_table = hisi_pcie_of_match,
+	},
+};
+
+module_platform_driver(hisi_pcie_driver);
-- 
1.9.1



From wangzhou1 at hisilicon.com  Mon Aug 17 04:55:48 2015
From: wangzhou1 at hisilicon.com (Zhou Wang)
Date: Mon, 17 Aug 2015 19:55:48 +0800
Subject: [PATCH v7 0/6] PCI: hisi: Add PCIe host support for HiSilicon SoC
 Hip05
Message-ID: <1439812554-180426-1-git-send-email-wangzhou1@hisilicon.com>

This patchset adds PCIe host support for HiSilicon SoC Hip05. The PCIe hosts
use PCIe IP core from Synopsys, So this driver is base on designware PCIe driver.

Hip05 is an ARMv8 architecture SoC. It should be able to use ARM64 PCIe API in
designeware PCIe driver. So this patch also adds ARM64 support for designware
pcie.

This patchset is based on v4.2-rc1.

Change from v6:
- Add Pratyush's Acked-by for 1/6 and 2/6.
- Add James' Tested-by for 3/6.

Change from v5:
- Merge 1/6 in this series, discussion about this can be found in [1]

Change from v4:
- Change the author of 1/5 to Gabriele.
- Modify problems in 3/5 pointed by Bjorn.
- Modify spelling problems in 4/5.

Change from v3:
- Change 1/5 to what Gabriele suggested.
- Use win->__res.start to get *_mod_base in 2/5, this fix a bug in v3 series.

Change from v2:
- Move struct pci_dev *dev and struct pci_sys_data *sys in
  pcibios_align_resource in 1/5.
- Add Gabriele's codes in 2/5 which delete unnecessary information parse and
  use of_pci_get_host_bridge_resources for both ARM32 and ARM64.
- Add maintainer patch 5/5.

Change from RFC v1:
- Add 1/4 patch by Arnd which removes align_resource callback in ARM
  pcibios_align_resource.
- Change head file in pcie-designware from asm/hardirq.h to linux/hardirq.h.
- Set pp->root_bus_nr = 0 in dra7xx, exynos, imx6, keystone, layerscape,
  spear13xx.
- Remove unnecessary parentheses of some macros in pcie-hisi.
- Use macro to replace some magic values.
- Merge two loops together and add some comments about it in context_config
  function in pcie-hisi.
- Modify some value of items in pcie node example in binding document. 

Change from RFC:
- delete dw_pcie_setup, dw_pcie_scan_bus, dw_pcie_map_irq and struct hw_pci,
  merge related operations into dw_pcie_host_init.

Link of v6:
- http://www.spinics.net/lists/linux-pci/msg43669.html
Link of v5:
- http://www.spinics.net/lists/devicetree/msg87959.html
Link of v4:
- http://www.spinics.net/lists/arm-kernel/msg433050.html
Link of v3:
- http://www.spinics.net/lists/linux-pci/msg42539.html
Link of v2:
- http://www.spinics.net/lists/linux-pci/msg41844.html
Link of RFC v1:
- http://www.spinics.net/lists/linux-pci/msg41305.html
Link of RFC:
- http://www.spinics.net/lists/linux-pci/msg40434.html

[1] http://lists.infradead.org/pipermail/linux-arm-kernel/2015-July/359741.html

Zhou Wang (4):
  PCI: designware: Add ARM64 support
  PCI: hisi: Add PCIe host support for HiSilicon SoC Hip05
  Documentation: DT: Add HiSilicon PCIe host binding
  MAINTAINERS: Add pcie-hisi maintainer

gabriele paoloni (2):
  PCI: designware: move calculation of bus addresses to DRA7xx
  ARM/PCI: remove align_resource in pci_sys_data

 .../devicetree/bindings/pci/hisilicon-pcie.txt     |  46 ++++
 MAINTAINERS                                        |   7 +
 arch/arm/include/asm/mach/pci.h                    |   5 -
 arch/arm/kernel/bios32.c                           |  12 +-
 drivers/pci/host/Kconfig                           |   8 +
 drivers/pci/host/Makefile                          |   1 +
 drivers/pci/host/pci-dra7xx.c                      |  14 ++
 drivers/pci/host/pci-exynos.c                      |   2 +-
 drivers/pci/host/pci-imx6.c                        |   2 +-
 drivers/pci/host/pci-keystone-dw.c                 |   2 +-
 drivers/pci/host/pci-keystone.c                    |   2 +-
 drivers/pci/host/pci-layerscape.c                  |   2 +-
 drivers/pci/host/pcie-designware.c                 | 236 ++++++-------------
 drivers/pci/host/pcie-designware.h                 |  14 +-
 drivers/pci/host/pcie-hisi.c                       | 254 +++++++++++++++++++++
 drivers/pci/host/pcie-spear13xx.c                  |   2 +-
 16 files changed, 425 insertions(+), 184 deletions(-)
 create mode 100644 Documentation/devicetree/bindings/pci/hisilicon-pcie.txt
 create mode 100644 drivers/pci/host/pcie-hisi.c

-- 
1.9.1



From wangzhou1 at hisilicon.com  Mon Aug 17 04:55:51 2015
From: wangzhou1 at hisilicon.com (Zhou Wang)
Date: Mon, 17 Aug 2015 19:55:51 +0800
Subject: [PATCH v7 3/6] PCI: designware: Add ARM64 support
In-Reply-To: <1439812554-180426-1-git-send-email-wangzhou1@hisilicon.com>
References: <1439812554-180426-1-git-send-email-wangzhou1@hisilicon.com>
Message-ID: <1439812554-180426-4-git-send-email-wangzhou1@hisilicon.com>

This patch tries to unify ARM32 and ARM64 PCIe in designware driver. Delete
function dw_pcie_setup, dw_pcie_scan_bus, dw_pcie_map_irq and struct hw_pci,
move related operations to dw_pcie_host_init.

In past, we use:
pci_common_init_dev
	-> pcibios_init_hw
		-> hw->scan (dw_pcie_scan_bus)
to pass 0 to root_bus_nr in struct pcie_port. This patch set pp->root_bus_nr = 0
in each PCIe host driver which is based on pcie-designware.

This patch also try to use of_pci_get_host_bridge_resources for ARM32 and ARM64
according to the suggestion for Gabriele[1]

Finally this patch reverts commit f4c55c5a3f7f "PCI: designware: Program ATU
with untranslated address" based on 1/6 in this series. we delete *_mod_base in
pcie-designware. This was discussed in [2]

I have compiled the driver with multi_v7_defconfig. However, I don't have
ARM32 PCIe related board to do test. It will be appreciated if someone could
help to test it.

Signed-off-by: Zhou Wang <wangzhou1 at hisilicon.com>
Signed-off-by: Gabriele Paoloni <gabriele.paoloni at huawei.com>
Signed-off-by: Arnd Bergmann <arnd at arndb.de>
Tested-By: James Morse <james.morse at arm.com>

[1] http://www.spinics.net/lists/linux-pci/msg42194.html
[2] http://www.spinics.net/lists/arm-kernel/msg436779.html
---
 drivers/pci/host/pci-dra7xx.c      |  15 +--
 drivers/pci/host/pci-exynos.c      |   2 +-
 drivers/pci/host/pci-imx6.c        |   2 +-
 drivers/pci/host/pci-keystone-dw.c |   2 +-
 drivers/pci/host/pci-keystone.c    |   2 +-
 drivers/pci/host/pci-layerscape.c  |   2 +-
 drivers/pci/host/pcie-designware.c | 229 ++++++++++++-------------------------
 drivers/pci/host/pcie-designware.h |  14 +--
 drivers/pci/host/pcie-spear13xx.c  |   2 +-
 9 files changed, 95 insertions(+), 175 deletions(-)

diff --git a/drivers/pci/host/pci-dra7xx.c b/drivers/pci/host/pci-dra7xx.c
index 18ae7ff..1268c69 100644
--- a/drivers/pci/host/pci-dra7xx.c
+++ b/drivers/pci/host/pci-dra7xx.c
@@ -141,15 +141,15 @@ static void dra7xx_pcie_host_init(struct pcie_port *pp)
 {
 	dw_pcie_setup_rc(pp);
 
-	if (pp->io_mod_base)
-		pp->io_mod_base &= CPU_TO_BUS_ADDR;
+	if (pp->io_base)
+		pp->io_base &= CPU_TO_BUS_ADDR;
 
-	if (pp->mem_mod_base)
-		pp->mem_mod_base &= CPU_TO_BUS_ADDR;
+	if (pp->mem_base)
+		pp->mem_base &= CPU_TO_BUS_ADDR;
 
-	if (pp->cfg0_mod_base) {
-		pp->cfg0_mod_base &= CPU_TO_BUS_ADDR;
-		pp->cfg1_mod_base &= CPU_TO_BUS_ADDR;
+	if (pp->cfg0_base) {
+		pp->cfg0_base &= CPU_TO_BUS_ADDR;
+		pp->cfg1_base &= CPU_TO_BUS_ADDR;
 	}
 
 	dra7xx_pcie_establish_link(pp);
@@ -288,6 +288,7 @@ static int __init dra7xx_add_pcie_port(struct dra7xx_pcie *dra7xx,
 
 	pp = &dra7xx->pp;
 	pp->dev = dev;
+	pp->root_bus_nr = 0;
 	pp->ops = &dra7xx_pcie_host_ops;
 
 	pp->irq = platform_get_irq(pdev, 1);
diff --git a/drivers/pci/host/pci-exynos.c b/drivers/pci/host/pci-exynos.c
index f9f468d..9771bb0 100644
--- a/drivers/pci/host/pci-exynos.c
+++ b/drivers/pci/host/pci-exynos.c
@@ -530,7 +530,7 @@ static int __init exynos_add_pcie_port(struct pcie_port *pp,
 		}
 	}
 
-	pp->root_bus_nr = -1;
+	pp->root_bus_nr = 0;
 	pp->ops = &exynos_pcie_host_ops;
 
 	ret = dw_pcie_host_init(pp);
diff --git a/drivers/pci/host/pci-imx6.c b/drivers/pci/host/pci-imx6.c
index 233a196..bec256c 100644
--- a/drivers/pci/host/pci-imx6.c
+++ b/drivers/pci/host/pci-imx6.c
@@ -551,7 +551,7 @@ static int __init imx6_add_pcie_port(struct pcie_port *pp,
 		}
 	}
 
-	pp->root_bus_nr = -1;
+	pp->root_bus_nr = 0;
 	pp->ops = &imx6_pcie_host_ops;
 
 	ret = dw_pcie_host_init(pp);
diff --git a/drivers/pci/host/pci-keystone-dw.c b/drivers/pci/host/pci-keystone-dw.c
index f34892e..b1e4135 100644
--- a/drivers/pci/host/pci-keystone-dw.c
+++ b/drivers/pci/host/pci-keystone-dw.c
@@ -327,7 +327,7 @@ static void ks_dw_pcie_clear_dbi_mode(void __iomem *reg_virt)
 void ks_dw_pcie_setup_rc_app_regs(struct keystone_pcie *ks_pcie)
 {
 	struct pcie_port *pp = &ks_pcie->pp;
-	u32 start = pp->mem.start, end = pp->mem.end;
+	u32 start = pp->mem->start, end = pp->mem->end;
 	int i, tr_size;
 
 	/* Disable BARs for inbound access */
diff --git a/drivers/pci/host/pci-keystone.c b/drivers/pci/host/pci-keystone.c
index 734da58..8113832 100644
--- a/drivers/pci/host/pci-keystone.c
+++ b/drivers/pci/host/pci-keystone.c
@@ -309,7 +309,7 @@ static int __init ks_add_pcie_port(struct keystone_pcie *ks_pcie,
 			return ret;
 	}
 
-	pp->root_bus_nr = -1;
+	pp->root_bus_nr = 0;
 	pp->ops = &keystone_pcie_host_ops;
 	ret = ks_dw_pcie_host_init(ks_pcie, ks_pcie->msi_intc_np);
 	if (ret) {
diff --git a/drivers/pci/host/pci-layerscape.c b/drivers/pci/host/pci-layerscape.c
index b2328ea1..79ff08c 100644
--- a/drivers/pci/host/pci-layerscape.c
+++ b/drivers/pci/host/pci-layerscape.c
@@ -106,7 +106,7 @@ static int ls_add_pcie_port(struct ls_pcie *pcie)
 	pp = &pcie->pp;
 	pp->dev = pcie->dev;
 	pp->dbi_base = pcie->dbi;
-	pp->root_bus_nr = -1;
+	pp->root_bus_nr = 0;
 	pp->ops = &ls_pcie_host_ops;
 
 	ret = dw_pcie_host_init(pp);
diff --git a/drivers/pci/host/pcie-designware.c b/drivers/pci/host/pcie-designware.c
index c5d407c..e71a88e 100644
--- a/drivers/pci/host/pcie-designware.c
+++ b/drivers/pci/host/pcie-designware.c
@@ -11,6 +11,7 @@
  * published by the Free Software Foundation.
  */
 
+#include <linux/hardirq.h>
 #include <linux/irq.h>
 #include <linux/irqdomain.h>
 #include <linux/kernel.h>
@@ -69,16 +70,7 @@
 #define PCIE_ATU_FUNC(x)		(((x) & 0x7) << 16)
 #define PCIE_ATU_UPPER_TARGET		0x91C
 
-static struct hw_pci dw_pci;
-
-static unsigned long global_io_offset;
-
-static inline struct pcie_port *sys_to_pcie(struct pci_sys_data *sys)
-{
-	BUG_ON(!sys->private_data);
-
-	return sys->private_data;
-}
+static struct pci_ops dw_pcie_ops;
 
 int dw_pcie_cfg_read(void __iomem *addr, int where, int size, u32 *val)
 {
@@ -255,7 +247,7 @@ static void dw_pcie_msi_set_irq(struct pcie_port *pp, int irq)
 static int assign_irq(int no_irqs, struct msi_desc *desc, int *pos)
 {
 	int irq, pos0, i;
-	struct pcie_port *pp = sys_to_pcie(desc->dev->bus->sysdata);
+	struct pcie_port *pp = desc->dev->bus->sysdata;
 
 	pos0 = bitmap_find_free_region(pp->msi_irq_in_use, MAX_MSI_IRQS,
 				       order_base_2(no_irqs));
@@ -298,7 +290,7 @@ static int dw_msi_setup_irq(struct msi_controller *chip, struct pci_dev *pdev,
 {
 	int irq, pos;
 	struct msi_msg msg;
-	struct pcie_port *pp = sys_to_pcie(pdev->bus->sysdata);
+	struct pcie_port *pp = pdev->bus->sysdata;
 
 	if (desc->msi_attrib.is_msix)
 		return -EINVAL;
@@ -327,7 +319,7 @@ static void dw_msi_teardown_irq(struct msi_controller *chip, unsigned int irq)
 {
 	struct irq_data *data = irq_get_irq_data(irq);
 	struct msi_desc *msi = irq_data_get_msi(data);
-	struct pcie_port *pp = sys_to_pcie(msi->dev->bus->sysdata);
+	struct pcie_port *pp = msi->dev->bus->sysdata;
 
 	clear_irq_range(pp, irq, 1, data->hwirq);
 }
@@ -363,14 +355,12 @@ int dw_pcie_host_init(struct pcie_port *pp)
 {
 	struct device_node *np = pp->dev->of_node;
 	struct platform_device *pdev = to_platform_device(pp->dev);
-	struct of_pci_range range;
-	struct of_pci_range_parser parser;
+	struct pci_bus *bus;
 	struct resource *cfg_res;
-	u32 val, ns;
-	const __be32 *addrp;
-	int i, index, ret;
-
-	ns = of_n_size_cells(np);
+	LIST_HEAD(res);
+	u32 val;
+	int i, ret;
+	struct resource_entry *win;
 
 	cfg_res = platform_get_resource_byname(pdev, IORESOURCE_MEM, "config");
 	if (cfg_res) {
@@ -378,85 +368,60 @@ int dw_pcie_host_init(struct pcie_port *pp)
 		pp->cfg1_size = resource_size(cfg_res)/2;
 		pp->cfg0_base = cfg_res->start;
 		pp->cfg1_base = cfg_res->start + pp->cfg0_size;
-
-		/* Find the untranslated configuration space address */
-		index = of_property_match_string(np, "reg-names", "config");
-		addrp = of_get_address(np, index, NULL, NULL);
-		pp->cfg0_mod_base = of_read_number(addrp, ns);
-		pp->cfg1_mod_base = pp->cfg0_mod_base + pp->cfg0_size;
 	} else {
 		dev_err(pp->dev, "missing *config* reg space\n");
 	}
 
-	if (of_pci_range_parser_init(&parser, np)) {
-		dev_err(pp->dev, "missing ranges property\n");
-		return -EINVAL;
-	}
+	ret = of_pci_get_host_bridge_resources(np, 0, 0xff, &res, &pp->io_base);
+	if (ret)
+		return ret;
 
 	/* Get the I/O and memory ranges from DT */
-	for_each_of_pci_range(&parser, &range) {
-		unsigned long restype = range.flags & IORESOURCE_TYPE_BITS;
-
-		if (restype == IORESOURCE_IO) {
-			of_pci_range_to_resource(&range, np, &pp->io);
-			pp->io.name = "I/O";
-			pp->io.start = max_t(resource_size_t,
-					     PCIBIOS_MIN_IO,
-					     range.pci_addr + global_io_offset);
-			pp->io.end = min_t(resource_size_t,
-					   IO_SPACE_LIMIT,
-					   range.pci_addr + range.size
-					   + global_io_offset - 1);
-			pp->io_size = resource_size(&pp->io);
-			pp->io_bus_addr = range.pci_addr;
-			pp->io_base = range.cpu_addr;
-
-			/* Find the untranslated IO space address */
-			pp->io_mod_base = range.cpu_addr;
-		}
-		if (restype == IORESOURCE_MEM) {
-			of_pci_range_to_resource(&range, np, &pp->mem);
-			pp->mem.name = "MEM";
-			pp->mem_size = resource_size(&pp->mem);
-			pp->mem_bus_addr = range.pci_addr;
-
-			/* Find the untranslated MEM space address */
-			pp->mem_mod_base = range.cpu_addr;
-		}
-		if (restype == 0) {
-			of_pci_range_to_resource(&range, np, &pp->cfg);
-			pp->cfg0_size = resource_size(&pp->cfg)/2;
-			pp->cfg1_size = resource_size(&pp->cfg)/2;
-			pp->cfg0_base = pp->cfg.start;
-			pp->cfg1_base = pp->cfg.start + pp->cfg0_size;
-
-			/* Find the untranslated configuration space address */
-			pp->cfg0_mod_base = range.cpu_addr;
-			pp->cfg1_mod_base = pp->cfg0_mod_base +
-					    pp->cfg0_size;
+	resource_list_for_each_entry(win, &res) {
+		switch (resource_type(win->res)) {
+		case IORESOURCE_IO:
+			pp->io = win->res;
+			pp->io->name = "I/O";
+			pp->io_size = resource_size(pp->io);
+			pp->io_bus_addr = pp->io->start - win->offset;
+			ret = pci_remap_iospace(pp->io, pp->io_base);
+			if (ret) {
+				dev_warn(pp->dev, "error %d: failed to map resource %pR\n",
+					 ret, pp->io);
+				continue;
+			}
+			break;
+		case IORESOURCE_MEM:
+			pp->mem = win->res;
+			pp->mem->name = "MEM";
+			pp->mem_size = resource_size(pp->mem);
+			pp->mem_bus_addr = pp->mem->start - win->offset;
+			break;
+		case 0:
+			pp->cfg = win->res;
+			pp->cfg0_size = resource_size(pp->cfg)/2;
+			pp->cfg1_size = resource_size(pp->cfg)/2;
+			pp->cfg0_base = pp->cfg->start;
+			pp->cfg1_base = pp->cfg->start + pp->cfg0_size;
+			break;
+		case IORESOURCE_BUS:
+			pp->busn = win->res;
+			break;
+		default:
+			continue;
 		}
 	}
 
-	ret = of_pci_parse_bus_range(np, &pp->busn);
-	if (ret < 0) {
-		pp->busn.name = np->name;
-		pp->busn.start = 0;
-		pp->busn.end = 0xff;
-		pp->busn.flags = IORESOURCE_BUS;
-		dev_dbg(pp->dev, "failed to parse bus-range property: %d, using default %pR\n",
-			ret, &pp->busn);
-	}
-
 	if (!pp->dbi_base) {
-		pp->dbi_base = devm_ioremap(pp->dev, pp->cfg.start,
-					resource_size(&pp->cfg));
+		pp->dbi_base = devm_ioremap(pp->dev, pp->cfg->start,
+					resource_size(pp->cfg));
 		if (!pp->dbi_base) {
 			dev_err(pp->dev, "error with ioremap\n");
 			return -ENOMEM;
 		}
 	}
 
-	pp->mem_base = pp->mem.start;
+	pp->mem_base = pp->mem->start;
 
 	if (!pp->va_cfg0_base) {
 		pp->va_cfg0_base = devm_ioremap(pp->dev, pp->cfg0_base,
@@ -505,7 +470,7 @@ int dw_pcie_host_init(struct pcie_port *pp)
 
 	if (!pp->ops->rd_other_conf)
 		dw_pcie_prog_outbound_atu(pp, PCIE_ATU_REGION_INDEX1,
-					  PCIE_ATU_TYPE_MEM, pp->mem_mod_base,
+					  PCIE_ATU_TYPE_MEM, pp->mem_base,
 					  pp->mem_bus_addr, pp->mem_size);
 
 	dw_pcie_wr_own_conf(pp, PCI_BASE_ADDRESS_0, 4, 0);
@@ -517,15 +482,29 @@ int dw_pcie_host_init(struct pcie_port *pp)
 	val |= PORT_LOGIC_SPEED_CHANGE;
 	dw_pcie_wr_own_conf(pp, PCIE_LINK_WIDTH_SPEED_CONTROL, 4, val);
 
-#ifdef CONFIG_PCI_MSI
+	bus = pci_create_root_bus(pp->dev, pp->root_bus_nr, &dw_pcie_ops,
+				  pp, &res);
+	if (!bus)
+		return -ENOMEM;
+
+#ifdef CONFIG_GENERIC_MSI_IRQ_DOMAIN
+	bus->msi = container_of(&pp->irq_domain, struct msi_controller, domain);
+#else
 	dw_pcie_msi_chip.dev = pp->dev;
-	dw_pci.msi_ctrl = &dw_pcie_msi_chip;
+	bus->msi = &dw_pcie_msi_chip;
 #endif
 
-	dw_pci.nr_controllers = 1;
-	dw_pci.private_data = (void **)&pp;
+	pci_scan_child_bus(bus);
+	if (pp->ops->scan_bus)
+		pp->ops->scan_bus(pp);
+
+#ifdef CONFIG_ARM
+	/* support old dtbs that incorrectly describe IRQs */
+	pci_fixup_irqs(pci_common_swizzle, of_irq_parse_and_map_pci);
+#endif
 
-	pci_common_init_dev(pp->dev, &dw_pci);
+	pci_assign_unassigned_bus_resources(bus);
+	pci_bus_add_devices(bus);
 
 	return 0;
 }
@@ -544,12 +523,12 @@ static int dw_pcie_rd_other_conf(struct pcie_port *pp, struct pci_bus *bus,
 
 	if (bus->parent->number == pp->root_bus_nr) {
 		type = PCIE_ATU_TYPE_CFG0;
-		cpu_addr = pp->cfg0_mod_base;
+		cpu_addr = pp->cfg0_base;
 		cfg_size = pp->cfg0_size;
 		va_cfg_base = pp->va_cfg0_base;
 	} else {
 		type = PCIE_ATU_TYPE_CFG1;
-		cpu_addr = pp->cfg1_mod_base;
+		cpu_addr = pp->cfg1_base;
 		cfg_size = pp->cfg1_size;
 		va_cfg_base = pp->va_cfg1_base;
 	}
@@ -559,7 +538,7 @@ static int dw_pcie_rd_other_conf(struct pcie_port *pp, struct pci_bus *bus,
 				  busdev, cfg_size);
 	ret = dw_pcie_cfg_read(va_cfg_base + address, where, size, val);
 	dw_pcie_prog_outbound_atu(pp, PCIE_ATU_REGION_INDEX0,
-				  PCIE_ATU_TYPE_IO, pp->io_mod_base,
+				  PCIE_ATU_TYPE_IO, pp->io_base,
 				  pp->io_bus_addr, pp->io_size);
 
 	return ret;
@@ -579,12 +558,12 @@ static int dw_pcie_wr_other_conf(struct pcie_port *pp, struct pci_bus *bus,
 
 	if (bus->parent->number == pp->root_bus_nr) {
 		type = PCIE_ATU_TYPE_CFG0;
-		cpu_addr = pp->cfg0_mod_base;
+		cpu_addr = pp->cfg0_base;
 		cfg_size = pp->cfg0_size;
 		va_cfg_base = pp->va_cfg0_base;
 	} else {
 		type = PCIE_ATU_TYPE_CFG1;
-		cpu_addr = pp->cfg1_mod_base;
+		cpu_addr = pp->cfg1_base;
 		cfg_size = pp->cfg1_size;
 		va_cfg_base = pp->va_cfg1_base;
 	}
@@ -594,7 +573,7 @@ static int dw_pcie_wr_other_conf(struct pcie_port *pp, struct pci_bus *bus,
 				  busdev, cfg_size);
 	ret = dw_pcie_cfg_write(va_cfg_base + address, where, size, val);
 	dw_pcie_prog_outbound_atu(pp, PCIE_ATU_REGION_INDEX0,
-				  PCIE_ATU_TYPE_IO, pp->io_mod_base,
+				  PCIE_ATU_TYPE_IO, pp->io_base,
 				  pp->io_bus_addr, pp->io_size);
 
 	return ret;
@@ -626,7 +605,7 @@ static int dw_pcie_valid_config(struct pcie_port *pp,
 static int dw_pcie_rd_conf(struct pci_bus *bus, u32 devfn, int where,
 			int size, u32 *val)
 {
-	struct pcie_port *pp = sys_to_pcie(bus->sysdata);
+	struct pcie_port *pp = bus->sysdata;
 	int ret;
 
 	if (dw_pcie_valid_config(pp, bus, PCI_SLOT(devfn)) == 0) {
@@ -650,7 +629,7 @@ static int dw_pcie_rd_conf(struct pci_bus *bus, u32 devfn, int where,
 static int dw_pcie_wr_conf(struct pci_bus *bus, u32 devfn,
 			int where, int size, u32 val)
 {
-	struct pcie_port *pp = sys_to_pcie(bus->sysdata);
+	struct pcie_port *pp = bus->sysdata;
 	int ret;
 
 	if (dw_pcie_valid_config(pp, bus, PCI_SLOT(devfn)) == 0)
@@ -674,62 +653,6 @@ static struct pci_ops dw_pcie_ops = {
 	.write = dw_pcie_wr_conf,
 };
 
-static int dw_pcie_setup(int nr, struct pci_sys_data *sys)
-{
-	struct pcie_port *pp;
-
-	pp = sys_to_pcie(sys);
-
-	if (global_io_offset < SZ_1M && pp->io_size > 0) {
-		sys->io_offset = global_io_offset - pp->io_bus_addr;
-		pci_ioremap_io(global_io_offset, pp->io_base);
-		global_io_offset += SZ_64K;
-		pci_add_resource_offset(&sys->resources, &pp->io,
-					sys->io_offset);
-	}
-
-	sys->mem_offset = pp->mem.start - pp->mem_bus_addr;
-	pci_add_resource_offset(&sys->resources, &pp->mem, sys->mem_offset);
-	pci_add_resource(&sys->resources, &pp->busn);
-
-	return 1;
-}
-
-static struct pci_bus *dw_pcie_scan_bus(int nr, struct pci_sys_data *sys)
-{
-	struct pci_bus *bus;
-	struct pcie_port *pp = sys_to_pcie(sys);
-
-	pp->root_bus_nr = sys->busnr;
-	bus = pci_scan_root_bus(pp->dev, sys->busnr,
-				  &dw_pcie_ops, sys, &sys->resources);
-	if (!bus)
-		return NULL;
-
-	if (bus && pp->ops->scan_bus)
-		pp->ops->scan_bus(pp);
-
-	return bus;
-}
-
-static int dw_pcie_map_irq(const struct pci_dev *dev, u8 slot, u8 pin)
-{
-	struct pcie_port *pp = sys_to_pcie(dev->bus->sysdata);
-	int irq;
-
-	irq = of_irq_parse_and_map_pci(dev, slot, pin);
-	if (!irq)
-		irq = pp->irq;
-
-	return irq;
-}
-
-static struct hw_pci dw_pci = {
-	.setup		= dw_pcie_setup,
-	.scan		= dw_pcie_scan_bus,
-	.map_irq	= dw_pcie_map_irq,
-};
-
 void dw_pcie_setup_rc(struct pcie_port *pp)
 {
 	u32 val;
diff --git a/drivers/pci/host/pcie-designware.h b/drivers/pci/host/pcie-designware.h
index d0bbd27..264c969 100644
--- a/drivers/pci/host/pcie-designware.h
+++ b/drivers/pci/host/pcie-designware.h
@@ -27,25 +27,21 @@ struct pcie_port {
 	u8			root_bus_nr;
 	void __iomem		*dbi_base;
 	u64			cfg0_base;
-	u64			cfg0_mod_base;
 	void __iomem		*va_cfg0_base;
 	u32			cfg0_size;
 	u64			cfg1_base;
-	u64			cfg1_mod_base;
 	void __iomem		*va_cfg1_base;
 	u32			cfg1_size;
-	u64			io_base;
-	u64			io_mod_base;
+	resource_size_t		io_base;
 	phys_addr_t		io_bus_addr;
 	u32			io_size;
 	u64			mem_base;
-	u64			mem_mod_base;
 	phys_addr_t		mem_bus_addr;
 	u32			mem_size;
-	struct resource		cfg;
-	struct resource		io;
-	struct resource		mem;
-	struct resource		busn;
+	struct resource		*cfg;
+	struct resource		*io;
+	struct resource		*mem;
+	struct resource		*busn;
 	int			irq;
 	u32			lanes;
 	struct pcie_host_ops	*ops;
diff --git a/drivers/pci/host/pcie-spear13xx.c b/drivers/pci/host/pcie-spear13xx.c
index c49fbdc..03eb204 100644
--- a/drivers/pci/host/pcie-spear13xx.c
+++ b/drivers/pci/host/pcie-spear13xx.c
@@ -286,7 +286,7 @@ static int spear13xx_add_pcie_port(struct pcie_port *pp,
 		return ret;
 	}
 
-	pp->root_bus_nr = -1;
+	pp->root_bus_nr = 0;
 	pp->ops = &spear13xx_pcie_host_ops;
 
 	ret = dw_pcie_host_init(pp);
-- 
1.9.1



From wangzhou1 at hisilicon.com  Mon Aug 17 04:55:50 2015
From: wangzhou1 at hisilicon.com (Zhou Wang)
Date: Mon, 17 Aug 2015 19:55:50 +0800
Subject: [PATCH v7 2/6] ARM/PCI: remove align_resource in pci_sys_data
In-Reply-To: <1439812554-180426-1-git-send-email-wangzhou1@hisilicon.com>
References: <1439812554-180426-1-git-send-email-wangzhou1@hisilicon.com>
Message-ID: <1439812554-180426-3-git-send-email-wangzhou1@hisilicon.com>

From: gabriele paoloni <gabriele.paoloni at huawei.com>

This patch is needed in order to unify the PCIe designware framework for ARM and
ARM64 architectures. In the PCIe designware unification process we are calling
pci_create_root_bus() passing a "sysdata" parameter that is the same for both
ARM and ARM64 and is of type "struct pcie_port*". In the ARM case this will
cause a problem with the function pcibios_align_resource(); in fact this will
cast "dev->sysdata" to "struct pci_sys_data*", whereas designware had passed a
"struct pcie_port*" pointer.

This patch solves the issue by removing "align_resource" from "pci_sys_data"
struct and defining a static global function pointer in "bios32.c"

Signed-off-by: Gabriele Paoloni <gabriele.paoloni at huawei.com>
Acked-by: Pratyush Anand <pratyush.anand at gmail.com>
---
 arch/arm/include/asm/mach/pci.h |  5 -----
 arch/arm/kernel/bios32.c        | 12 ++++++++----
 2 files changed, 8 insertions(+), 9 deletions(-)

diff --git a/arch/arm/include/asm/mach/pci.h b/arch/arm/include/asm/mach/pci.h
index 28b9bb3..8a4e4de 100644
--- a/arch/arm/include/asm/mach/pci.h
+++ b/arch/arm/include/asm/mach/pci.h
@@ -58,11 +58,6 @@ struct pci_sys_data {
 					/* IRQ mapping				*/
 	int		(*map_irq)(const struct pci_dev *, u8, u8);
 					/* Resource alignement requirements	*/
-	resource_size_t (*align_resource)(struct pci_dev *dev,
-					  const struct resource *res,
-					  resource_size_t start,
-					  resource_size_t size,
-					  resource_size_t align);
 	void		*private_data;	/* platform controller private data	*/
 };
 
diff --git a/arch/arm/kernel/bios32.c b/arch/arm/kernel/bios32.c
index fcbbbb1..4cdc64d 100644
--- a/arch/arm/kernel/bios32.c
+++ b/arch/arm/kernel/bios32.c
@@ -17,6 +17,11 @@
 #include <asm/mach/pci.h>
 
 static int debug_pci;
+static resource_size_t (*align_resource)(struct pci_dev *dev,
+		  const struct resource *res,
+		  resource_size_t start,
+		  resource_size_t size,
+		  resource_size_t align) = NULL;
 
 #ifdef CONFIG_PCI_MSI
 struct msi_controller *pcibios_msi_controller(struct pci_dev *dev)
@@ -468,7 +473,7 @@ static void pcibios_init_hw(struct device *parent, struct hw_pci *hw,
 		sys->busnr   = busnr;
 		sys->swizzle = hw->swizzle;
 		sys->map_irq = hw->map_irq;
-		sys->align_resource = hw->align_resource;
+		align_resource = hw->align_resource;
 		INIT_LIST_HEAD(&sys->resources);
 
 		if (hw->private_data)
@@ -589,7 +594,6 @@ resource_size_t pcibios_align_resource(void *data, const struct resource *res,
 				resource_size_t size, resource_size_t align)
 {
 	struct pci_dev *dev = data;
-	struct pci_sys_data *sys = dev->sysdata;
 	resource_size_t start = res->start;
 
 	if (res->flags & IORESOURCE_IO && start & 0x300)
@@ -597,8 +601,8 @@ resource_size_t pcibios_align_resource(void *data, const struct resource *res,
 
 	start = (start + align - 1) & ~(align - 1);
 
-	if (sys->align_resource)
-		return sys->align_resource(dev, res, start, size, align);
+	if (align_resource)
+		return align_resource(dev, res, start, size, align);
 
 	return start;
 }
-- 
1.9.1



From wangzhou1 at hisilicon.com  Mon Aug 17 04:55:49 2015
From: wangzhou1 at hisilicon.com (Zhou Wang)
Date: Mon, 17 Aug 2015 19:55:49 +0800
Subject: [PATCH v7 1/6] PCI: designware: move calculation of bus addresses to
 DRA7xx
In-Reply-To: <1439812554-180426-1-git-send-email-wangzhou1@hisilicon.com>
References: <1439812554-180426-1-git-send-email-wangzhou1@hisilicon.com>
Message-ID: <1439812554-180426-2-git-send-email-wangzhou1@hisilicon.com>

From: gabriele paoloni <gabriele.paoloni at huawei.com>

Commit f4c55c5a3f7f "PCI: designware: Program ATU with untranslated
address" added the calculation of PCI BUS addresses in designware,
storing them in new fields added in "struct pcie_port". This
calculation is done for every designware user even if is only
applicable to DRA7xx.
This patch moves the calculation of the bus addresses to the DRA7xx
driver and is needed to allow the rework of designware to use
the new DT parsing API.

Signed-off-by: Gabriele Paoloni <gabriele.paoloni at huawei.com>
Signed-off-by: Zhou Wang <wangzhou1 at hisilicon.com>
Acked-by: Pratyush Anand <pratyush.anand at gmail.com>
---
 drivers/pci/host/pci-dra7xx.c      | 13 +++++++++++++
 drivers/pci/host/pcie-designware.c | 15 ++++-----------
 2 files changed, 17 insertions(+), 11 deletions(-)

diff --git a/drivers/pci/host/pci-dra7xx.c b/drivers/pci/host/pci-dra7xx.c
index 80db09e..18ae7ff 100644
--- a/drivers/pci/host/pci-dra7xx.c
+++ b/drivers/pci/host/pci-dra7xx.c
@@ -61,6 +61,7 @@
 
 #define	PCIECTRL_DRA7XX_CONF_PHY_CS			0x010C
 #define	LINK_UP						BIT(16)
+#define	CPU_TO_BUS_ADDR					0x0FFFFFFF
 
 struct dra7xx_pcie {
 	void __iomem		*base;
@@ -139,6 +140,18 @@ static void dra7xx_pcie_enable_interrupts(struct pcie_port *pp)
 static void dra7xx_pcie_host_init(struct pcie_port *pp)
 {
 	dw_pcie_setup_rc(pp);
+
+	if (pp->io_mod_base)
+		pp->io_mod_base &= CPU_TO_BUS_ADDR;
+
+	if (pp->mem_mod_base)
+		pp->mem_mod_base &= CPU_TO_BUS_ADDR;
+
+	if (pp->cfg0_mod_base) {
+		pp->cfg0_mod_base &= CPU_TO_BUS_ADDR;
+		pp->cfg1_mod_base &= CPU_TO_BUS_ADDR;
+	}
+
 	dra7xx_pcie_establish_link(pp);
 	if (IS_ENABLED(CONFIG_PCI_MSI))
 		dw_pcie_msi_init(pp);
diff --git a/drivers/pci/host/pcie-designware.c b/drivers/pci/host/pcie-designware.c
index 69486be..c5d407c 100644
--- a/drivers/pci/host/pcie-designware.c
+++ b/drivers/pci/host/pcie-designware.c
@@ -366,14 +366,10 @@ int dw_pcie_host_init(struct pcie_port *pp)
 	struct of_pci_range range;
 	struct of_pci_range_parser parser;
 	struct resource *cfg_res;
-	u32 val, na, ns;
+	u32 val, ns;
 	const __be32 *addrp;
 	int i, index, ret;
 
-	/* Find the address cell size and the number of cells in order to get
-	 * the untranslated address.
-	 */
-	of_property_read_u32(np, "#address-cells", &na);
 	ns = of_n_size_cells(np);
 
 	cfg_res = platform_get_resource_byname(pdev, IORESOURCE_MEM, "config");
@@ -416,8 +412,7 @@ int dw_pcie_host_init(struct pcie_port *pp)
 			pp->io_base = range.cpu_addr;
 
 			/* Find the untranslated IO space address */
-			pp->io_mod_base = of_read_number(parser.range -
-							 parser.np + na, ns);
+			pp->io_mod_base = range.cpu_addr;
 		}
 		if (restype == IORESOURCE_MEM) {
 			of_pci_range_to_resource(&range, np, &pp->mem);
@@ -426,8 +421,7 @@ int dw_pcie_host_init(struct pcie_port *pp)
 			pp->mem_bus_addr = range.pci_addr;
 
 			/* Find the untranslated MEM space address */
-			pp->mem_mod_base = of_read_number(parser.range -
-							  parser.np + na, ns);
+			pp->mem_mod_base = range.cpu_addr;
 		}
 		if (restype == 0) {
 			of_pci_range_to_resource(&range, np, &pp->cfg);
@@ -437,8 +431,7 @@ int dw_pcie_host_init(struct pcie_port *pp)
 			pp->cfg1_base = pp->cfg.start + pp->cfg0_size;
 
 			/* Find the untranslated configuration space address */
-			pp->cfg0_mod_base = of_read_number(parser.range -
-							   parser.np + na, ns);
+			pp->cfg0_mod_base = range.cpu_addr;
 			pp->cfg1_mod_base = pp->cfg0_mod_base +
 					    pp->cfg0_size;
 		}
-- 
1.9.1



From wangzhou1 at hisilicon.com  Mon Aug 17 04:55:54 2015
From: wangzhou1 at hisilicon.com (Zhou Wang)
Date: Mon, 17 Aug 2015 19:55:54 +0800
Subject: [PATCH v7 6/6] MAINTAINERS: Add pcie-hisi maintainer
In-Reply-To: <1439812554-180426-1-git-send-email-wangzhou1@hisilicon.com>
References: <1439812554-180426-1-git-send-email-wangzhou1@hisilicon.com>
Message-ID: <1439812554-180426-7-git-send-email-wangzhou1@hisilicon.com>

Signed-off-by: Zhou Wang <wangzhou1 at hisilicon.com>
---
 MAINTAINERS | 7 +++++++
 1 file changed, 7 insertions(+)

diff --git a/MAINTAINERS b/MAINTAINERS
index 8133cef..7cd8e47 100644
--- a/MAINTAINERS
+++ b/MAINTAINERS
@@ -7854,6 +7854,13 @@ S:	Maintained
 F:	Documentation/devicetree/bindings/pci/xgene-pci-msi.txt
 F:	drivers/pci/host/pci-xgene-msi.c
 
+PCIE DRIVER FOR HISILICON
+M:	Zhou Wang <wangzhou1 at hisilicon.com>
+L:	linux-pci at vger.kernel.org
+S:	Maintained
+F:	Documentation/devicetree/bindings/pci/hisilicon-pcie.txt
+F:	drivers/pci/host/pcie-hisi.c
+
 PCMCIA SUBSYSTEM
 P:	Linux PCMCIA Team
 L:	linux-pcmcia at lists.infradead.org
-- 
1.9.1



From jszhang at marvell.com  Mon Aug 17 04:49:54 2015
From: jszhang at marvell.com (Jisheng Zhang)
Date: Mon, 17 Aug 2015 19:49:54 +0800
Subject: [PATCH v2] mmc: sdhci: also set driver type for MMC_DDR52
In-Reply-To: <1439812041-6596-1-git-send-email-jszhang@marvell.com>
References: <1439812041-6596-1-git-send-email-jszhang@marvell.com>
Message-ID: <20150817194954.691729d7@xhacker>

On Mon, 17 Aug 2015 19:47:21 +0800
Jisheng Zhang <jszhang at marvell.com> wrote:

> commit bb8175a8aa42 ("mmc: sdhci: clarify DDR timing mode between
> SD-UHS and eMMC") added MMC_DDR52 as eMMC's DDR mode to be
> distinguished from SD-UHS, but it missed setting driver type for
> MMC_DDR52 timing mode. This patches adds the missing driver type
> setting.

This patch fixes unstable emmc read/write on marvell BG2Q DMP board.

> 
> Fixes: bb8175a8aa42 ("mmc: sdhci: clarify DDR timing mode ...")
> Signed-off-by: Jisheng Zhang <jszhang at marvell.com>
> ---
>  drivers/mmc/host/sdhci.c | 3 ++-
>  1 file changed, 2 insertions(+), 1 deletion(-)
> 
> diff --git a/drivers/mmc/host/sdhci.c b/drivers/mmc/host/sdhci.c
> index 1dbe932..32f2a07 100644
> --- a/drivers/mmc/host/sdhci.c
> +++ b/drivers/mmc/host/sdhci.c
> @@ -1559,7 +1559,8 @@ static void sdhci_do_set_ios(struct sdhci_host *host, struct mmc_ios *ios)
>  				 (ios->timing == MMC_TIMING_UHS_SDR25) ||
>  				 (ios->timing == MMC_TIMING_UHS_SDR50) ||
>  				 (ios->timing == MMC_TIMING_UHS_SDR104) ||
> -				 (ios->timing == MMC_TIMING_UHS_DDR50))) {
> +				 (ios->timing == MMC_TIMING_UHS_DDR50) ||
> +				 (ios->timing == MMC_TIMING_MMC_DDR52))) {

I'm not sure whether MMC_HS400 need such fix or not.

>  			u16 preset;
>  
>  			sdhci_enable_preset_value(host, true);



From srinivas.kandagatla at linaro.org  Mon Aug 17 04:58:07 2015
From: srinivas.kandagatla at linaro.org (Srinivas Kandagatla)
Date: Mon, 17 Aug 2015 12:58:07 +0100
Subject: [PATCH] pwrseq: bind pinctrl pins before using the gpios
Message-ID: <1439812687-18259-1-git-send-email-srinivas.kandagatla@linaro.org>

Some of the pin-controllers like the Qualcomms "qcom,pm8921", which
require a pinconf to be setup to use pins as gpios. Using the pins
directly without pinconf setup would result in incorrect output voltage
or load settings. On the other hand pwrseq code does not configure the
pinctrl by default as it does not go thru the driver core.

This patch adds a call to pinctrl_bind_pins() to bind pins which
are going to be used as gpios.

Signed-off-by: Srinivas Kandagatla <srinivas.kandagatla at linaro.org>
---
 drivers/mmc/core/pwrseq.c | 5 +++++
 1 file changed, 5 insertions(+)

diff --git a/drivers/mmc/core/pwrseq.c b/drivers/mmc/core/pwrseq.c
index 4c1d175..6e5d8b3 100644
--- a/drivers/mmc/core/pwrseq.c
+++ b/drivers/mmc/core/pwrseq.c
@@ -12,6 +12,7 @@
 #include <linux/err.h>
 #include <linux/of.h>
 #include <linux/of_platform.h>
+#include <linux/pinctrl/devinfo.h>
 
 #include <linux/mmc/host.h>
 
@@ -65,6 +66,10 @@ int mmc_pwrseq_alloc(struct mmc_host *host)
 		goto err;
 	}
 
+	ret = pinctrl_bind_pins(&pdev->dev);
+	if (ret)
+		goto err;
+
 	match = mmc_pwrseq_find(np);
 	if (IS_ERR(match)) {
 		ret = PTR_ERR(match);
-- 
1.9.1



From chaotian.jing at mediatek.com  Mon Aug 17 05:01:28 2015
From: chaotian.jing at mediatek.com (Chaotian Jing)
Date: Mon, 17 Aug 2015 20:01:28 +0800
Subject: [PATCH 1/4] mmc: mediatek: Add online-tuning support of EMMC/SD
In-Reply-To: <CAPDyKFpX4Pp1+U9eNBuGd83sBeBgLU17qysAJ-2V-ABZZHYAGQ@mail.gmail.com>
References: <1439367845-5891-1-git-send-email-chaotian.jing@mediatek.com>
 <1439367845-5891-2-git-send-email-chaotian.jing@mediatek.com>
 <CAPDyKFpX4Pp1+U9eNBuGd83sBeBgLU17qysAJ-2V-ABZZHYAGQ@mail.gmail.com>
Message-ID: <1439812888.5627.9.camel@mhfsdcap03>

Hi Ulf,
Thanks, please see my comment:
On Mon, 2015-08-17 at 13:31 +0200, Ulf Hansson wrote:
> On 12 August 2015 at 10:24, Chaotian Jing <chaotian.jing at mediatek.com> wrote:
> > Schedule a workqueue to do tuning when CRC error
> > Call mmc_hw_reset to re-init card when data timeout
> 
> Thanks to Adrian Hunter, the mmc core already supports re-tuning for
> the above scenarios through the mmc_retune_*() APIs.
> 
> SDHCI driver has already adopted to use that feature, you should do
> that for the mtk-sd driver as well.
> 
> Kind regards
> Uffe
> 
I also noticed that the mmc core already supports re-tuning, but it is
not suitable for our host.
For EMMC, the CMD21 only support HS200/HS400 mode, for SD card, CMD19
only support SDR50/SDR104 mode, but in our host, even 50Mhz clock
frequency may also occur CRC error, Cannot find a parameter that can
cover all SD cards which running at 50Mhz, even 25Mhz, will occur CRC
error for stress test, DDR50 mode is worse.
By the way,there are too many tune parameters need try for response,
read data, write crc status CRC error, these parameters are
multidimensional, it is hard to find a best parameter, and, try
thousands of parameters will take long time.
> >
> > Signed-off-by: Chaotian Jing <chaotian.jing at mediatek.com>
> > ---
> >  drivers/mmc/host/mtk-sd.c | 162 ++++++++++++++++++++++++++++++++++++++++++----
> >  1 file changed, 150 insertions(+), 12 deletions(-)
> >
> > diff --git a/drivers/mmc/host/mtk-sd.c b/drivers/mmc/host/mtk-sd.c
> > index 7153500..eb44fe1 100644
> > --- a/drivers/mmc/host/mtk-sd.c
> > +++ b/drivers/mmc/host/mtk-sd.c
> > @@ -27,6 +27,7 @@
> >  #include <linux/pm_runtime.h>
> >  #include <linux/regulator/consumer.h>
> >  #include <linux/spinlock.h>
> > +#include <linux/workqueue.h>
> >
> >  #include <linux/mmc/card.h>
> >  #include <linux/mmc/core.h>
> > @@ -290,6 +291,10 @@ struct msdc_host {
> >         struct pinctrl_state *pins_default;
> >         struct pinctrl_state *pins_uhs;
> >         struct delayed_work req_timeout;
> > +       struct workqueue_struct *repeat_workqueue;
> > +       struct work_struct repeat_req;
> > +       struct mmc_request *repeat_mrq;
> > +       u32 tune_cmd_counter;
> >         int irq;                /* host interrupt */
> >
> >         struct clk *src_clk;    /* msdc source clock */
> > @@ -353,7 +358,10 @@ static void msdc_reset_hw(struct msdc_host *host)
> >  static void msdc_cmd_next(struct msdc_host *host,
> >                 struct mmc_request *mrq, struct mmc_command *cmd);
> >
> > -static u32 data_ints_mask = MSDC_INTEN_XFER_COMPL | MSDC_INTEN_DATTMO |
> > +static const u32 cmd_ints_mask = MSDC_INTEN_CMDRDY | MSDC_INTEN_RSPCRCERR |
> > +                       MSDC_INTEN_CMDTMO | MSDC_INTEN_ACMDRDY |
> > +                       MSDC_INTEN_ACMDCRCERR | MSDC_INTEN_ACMDTMO;
> > +static const u32 data_ints_mask = MSDC_INTEN_XFER_COMPL | MSDC_INTEN_DATTMO |
> >                         MSDC_INTEN_DATCRCERR | MSDC_INTEN_DMA_BDCSERR |
> >                         MSDC_INTEN_DMA_GPDCSERR | MSDC_INTEN_DMA_PROTECT;
> >
> > @@ -690,6 +698,18 @@ static void msdc_request_done(struct msdc_host *host, struct mmc_request *mrq)
> >         msdc_track_cmd_data(host, mrq->cmd, mrq->data);
> >         if (mrq->data)
> >                 msdc_unprepare_data(host, mrq);
> > +       if (host->error && host->mmc->card &&
> > +           !mmc_card_sdio(host->mmc->card)) {
> > +               if (mrq->cmd->error == (unsigned int)-EILSEQ ||
> > +                   (mrq->stop && mrq->stop->error == (unsigned int)-EILSEQ) ||
> > +                   (mrq->sbc && mrq->sbc->error == (unsigned int)-EILSEQ) ||
> > +                   (mrq->data && mrq->data->error))  {
> > +                       host->repeat_mrq = mrq;
> > +                       queue_work(host->repeat_workqueue, &host->repeat_req);
> > +                       return;
> > +               }
> > +       }
> > +       host->tune_cmd_counter = 0;
> >         mmc_request_done(host->mmc, mrq);
> >
> >         pm_runtime_mark_last_busy(host->dev);
> > @@ -725,11 +745,7 @@ static bool msdc_cmd_done(struct msdc_host *host, int events,
> >         if (done)
> >                 return true;
> >
> > -       sdr_clr_bits(host->base + MSDC_INTEN, MSDC_INTEN_CMDRDY |
> > -                       MSDC_INTEN_RSPCRCERR | MSDC_INTEN_CMDTMO |
> > -                       MSDC_INTEN_ACMDRDY | MSDC_INTEN_ACMDCRCERR |
> > -                       MSDC_INTEN_ACMDTMO);
> > -       writel(cmd->arg, host->base + SDC_ARG);
> > +       sdr_clr_bits(host->base + MSDC_INTEN, cmd_ints_mask);
> >
> >         if (cmd->flags & MMC_RSP_PRESENT) {
> >                 if (cmd->flags & MMC_RSP_136) {
> > @@ -819,10 +835,7 @@ static void msdc_start_command(struct msdc_host *host,
> >         rawcmd = msdc_cmd_prepare_raw_cmd(host, mrq, cmd);
> >         mod_delayed_work(system_wq, &host->req_timeout, DAT_TIMEOUT);
> >
> > -       sdr_set_bits(host->base + MSDC_INTEN, MSDC_INTEN_CMDRDY |
> > -                       MSDC_INTEN_RSPCRCERR | MSDC_INTEN_CMDTMO |
> > -                       MSDC_INTEN_ACMDRDY | MSDC_INTEN_ACMDCRCERR |
> > -                       MSDC_INTEN_ACMDTMO);
> > +       sdr_set_bits(host->base + MSDC_INTEN, cmd_ints_mask);
> >         writel(cmd->arg, host->base + SDC_ARG);
> >         writel(rawcmd, host->base + SDC_CMD);
> >  }
> > @@ -942,6 +955,8 @@ static bool msdc_data_xfer_done(struct msdc_host *host, u32 events,
> >
> >                         if (events & MSDC_INT_DATTMO)
> >                                 data->error = -ETIMEDOUT;
> > +                       else if (events & MSDC_INT_DATCRCERR)
> > +                               data->error = -EILSEQ;
> >
> >                         dev_err(host->dev, "%s: cmd=%d; blocks=%d",
> >                                 __func__, mrq->cmd->opcode, data->blocks);
> > @@ -1113,8 +1128,8 @@ static void msdc_init_hw(struct msdc_host *host)
> >
> >         writel(0, host->base + MSDC_PAD_TUNE);
> >         writel(0, host->base + MSDC_IOCON);
> > -       sdr_set_field(host->base + MSDC_IOCON, MSDC_IOCON_DDLSEL, 1);
> > -       writel(0x403c004f, host->base + MSDC_PATCH_BIT);
> > +       sdr_set_field(host->base + MSDC_IOCON, MSDC_IOCON_DDLSEL, 0);
> > +       writel(0x403c0046, host->base + MSDC_PATCH_BIT);
> >         sdr_set_field(host->base + MSDC_PATCH_BIT, MSDC_CKGEN_MSDC_DLY_SEL, 1);
> >         writel(0xffff0089, host->base + MSDC_PATCH_BIT1);
> >         /* Configure to enable SDIO mode.
> > @@ -1176,6 +1191,7 @@ static void msdc_ops_set_ios(struct mmc_host *mmc, struct mmc_ios *ios)
> >         switch (ios->power_mode) {
> >         case MMC_POWER_UP:
> >                 if (!IS_ERR(mmc->supply.vmmc)) {
> > +                       msdc_init_hw(host);
> >                         ret = mmc_regulator_set_ocr(mmc, mmc->supply.vmmc,
> >                                         ios->vdd);
> >                         if (ret) {
> > @@ -1214,6 +1230,120 @@ end:
> >         pm_runtime_put_autosuspend(host->dev);
> >  }
> >
> > +static void msdc_reset_mrq(struct mmc_request *mrq)
> > +{
> > +       mrq->cmd->error = 0;
> > +       if (mrq->sbc)
> > +               mrq->sbc->error = 0;
> > +       if (mrq->data)
> > +               mrq->data->error = 0;
> > +       if (mrq->stop)
> > +               mrq->stop->error = 0;
> > +}
> > +
> > +/* Send CMD12 when tuning, do not check CRC error and timeout */
> > +static void msdc_send_stop(struct msdc_host *host)
> > +{
> > +       u32 opcode = MMC_STOP_TRANSMISSION;
> > +       u32 arg = 0;
> > +       u32 rawcmd = 0;
> > +       u32 intsts = 0;
> > +
> > +       /* Reset host first */
> > +       msdc_reset_hw(host);
> > +
> > +       rawcmd = (opcode & 0x3f) | (7 << 7);
> > +       rawcmd |= (1 << 14); /* stop cmd */
> > +
> > +       sdr_clr_bits(host->base + MSDC_INTEN, cmd_ints_mask);
> > +       writel(arg, host->base + SDC_ARG);
> > +       writel(rawcmd, host->base + SDC_CMD);
> > +
> > +       while (1) {
> > +               intsts = readl(host->base + MSDC_INT);
> > +               if (intsts) {
> > +                       writel(intsts, host->base + MSDC_INT);
> > +                       if (intsts & cmd_ints_mask) {
> > +                               dev_dbg(host->dev, "result of cmd12: %x\n",
> > +                                               intsts);
> > +                               break;
> > +                       }
> > +               }
> > +               udelay(1);
> > +       }
> > +}
> > +
> > +/* When tuning, CMD13 may also get crc error, so use MSDC_PS to get card status */
> > +static void msdc_wait_card_not_busy(struct msdc_host *host)
> > +{
> > +       while (1) {
> > +               if ((readl(host->base + MSDC_PS) & BIT(16)) == 0) { /* check dat0 status */
> > +                       msleep_interruptible(10);
> > +                       dev_dbg(host->dev, "MSDC_PS: %08x, SDC_STS: %08x\n",
> > +                               readl(host->base + MSDC_PS), readl(host->base + SDC_STS));
> > +               } else
> > +                       break;
> > +       }
> > +}
> > +
> > +static void msdc_tune_request(struct msdc_host *host)
> > +{
> > +       u32 orig_rsmpl, orig_cksel;
> > +       u32 cur_rsmpl, cur_cksel = 0;
> > +       u32 ddr, clkmode;
> > +       struct mmc_ios ios = host->mmc->ios;
> > +
> > +       sdr_get_field(host->base + MSDC_IOCON, MSDC_IOCON_RSPL, &orig_rsmpl);
> > +       sdr_get_field(host->base + MSDC_PATCH_BIT, MSDC_CKGEN_MSDC_DLY_SEL,
> > +                     &orig_cksel);
> > +       cur_rsmpl = (orig_rsmpl + 1);
> > +       sdr_set_field(host->base + MSDC_IOCON, MSDC_IOCON_RSPL, cur_rsmpl % 2);
> > +
> > +       if (ios.timing != MMC_TIMING_MMC_HS400) {
> > +               sdr_set_field(host->base + MSDC_IOCON, MSDC_IOCON_DSPL,
> > +                             cur_rsmpl % 2);
> > +               sdr_set_field(host->base + MSDC_IOCON, MSDC_IOCON_W_DSPL,
> > +                             cur_rsmpl % 2);
> > +       }
> > +
> > +       if (cur_rsmpl >= 2) {
> > +               cur_cksel = orig_cksel + 1;
> > +               sdr_set_field(host->base + MSDC_PATCH_BIT,
> > +                             MSDC_CKGEN_MSDC_DLY_SEL, cur_cksel % 16);
> > +       }
> > +
> > +       if (host->tune_cmd_counter++ >= 2 * 16) {
> > +               dev_warn(host->dev, "Tune fail at %dhz\n", host->mclk);
> > +               host->tune_cmd_counter = 0;
> > +               sdr_set_field(host->base + MSDC_IOCON, MSDC_IOCON_RSPL, 0);
> > +               sdr_set_field(host->base + MSDC_PATCH_BIT,
> > +                             MSDC_CKGEN_MSDC_DLY_SEL, 0);
> > +               sdr_get_field(host->base + MSDC_CFG, MSDC_CFG_CKMOD, &clkmode);
> > +               ddr = (clkmode == 2) ? 1 : 0;
> > +               msdc_set_mclk(host, ddr, host->mclk / 2);
> > +       }
> > +}
> > +
> > +static void msdc_repeat_request(struct work_struct *work)
> > +{
> > +       struct msdc_host *host = container_of(work, struct msdc_host, repeat_req);
> > +       struct mmc_request *mrq;
> > +       unsigned long flags;
> > +
> > +       spin_lock_irqsave(&host->lock, flags);
> > +       mrq = host->repeat_mrq;
> > +       host->repeat_mrq = NULL;
> > +       spin_unlock_irqrestore(&host->lock, flags);
> > +       msdc_send_stop(host);
> > +       msdc_wait_card_not_busy(host);
> > +       if (mrq->data && mrq->data->error == -ETIMEDOUT)
> > +               mmc_hw_reset(host->mmc);
> > +       else
> > +               msdc_tune_request(host);
> > +       msdc_reset_mrq(mrq);
> > +       msdc_ops_request(host->mmc, mrq);
> > +}
> > +
> >  static struct mmc_host_ops mt_msdc_ops = {
> >         .post_req = msdc_post_req,
> >         .pre_req = msdc_pre_req,
> > @@ -1324,6 +1454,12 @@ static int msdc_drv_probe(struct platform_device *pdev)
> >         }
> >         msdc_init_gpd_bd(host, &host->dma);
> >         INIT_DELAYED_WORK(&host->req_timeout, msdc_request_timeout);
> > +       host->repeat_workqueue = create_singlethread_workqueue("repeat_workqueue");
> > +       if (!host->repeat_workqueue) {
> > +               ret = -ENOMEM;
> > +               goto release_mem;
> > +       }
> > +       INIT_WORK(&host->repeat_req, msdc_repeat_request);
> >         spin_lock_init(&host->lock);
> >
> >         platform_set_drvdata(pdev, mmc);
> > @@ -1348,6 +1484,7 @@ static int msdc_drv_probe(struct platform_device *pdev)
> >  end:
> >         pm_runtime_disable(host->dev);
> >  release:
> > +       destroy_workqueue(host->repeat_workqueue);
> >         platform_set_drvdata(pdev, NULL);
> >         msdc_deinit_hw(host);
> >         msdc_gate_clock(host);
> > @@ -1383,6 +1520,7 @@ static int msdc_drv_remove(struct platform_device *pdev)
> >
> >         pm_runtime_disable(host->dev);
> >         pm_runtime_put_noidle(host->dev);
> > +       destroy_workqueue(host->repeat_workqueue);
> >         dma_free_coherent(&pdev->dev,
> >                         sizeof(struct mt_gpdma_desc),
> >                         host->dma.gpd, host->dma.gpd_addr);
> > --
> > 1.8.1.1.dirty
> >




From catalin.marinas at arm.com  Mon Aug 17 05:07:05 2015
From: catalin.marinas at arm.com (Catalin Marinas)
Date: Mon, 17 Aug 2015 13:07:05 +0100
Subject: [PATCH] arm64: ignore memory outside of the linear range
In-Reply-To: <CAKv+Gu9j2_u4Bbtr+yvSfiNe_Vw4ZapO+r1xqxSUmbVBJ4GB3w@mail.gmail.com>
References: <1439640824-30498-1-git-send-email-ard.biesheuvel@linaro.org>
 <20150817104049.GB2482@e104818-lin.cambridge.arm.com>
 <CAKv+Gu_9zx5gZBRWO_Yg082Afoc7ksy2yJm-1xqprq06ptLJQw@mail.gmail.com>
 <20150817110454.GC2482@e104818-lin.cambridge.arm.com>
 <CAKv+Gu9j2_u4Bbtr+yvSfiNe_Vw4ZapO+r1xqxSUmbVBJ4GB3w@mail.gmail.com>
Message-ID: <20150817120705.GD2482@e104818-lin.cambridge.arm.com>

On Mon, Aug 17, 2015 at 01:06:35PM +0200, Ard Biesheuvel wrote:
> On 17 August 2015 at 13:04, Catalin Marinas <catalin.marinas at arm.com> wrote:
> > On Mon, Aug 17, 2015 at 12:44:50PM +0200, Ard Biesheuvel wrote:
> >> I proposed to override early_init_dt_add_memory_arch() completely
> >> instead, but Rob had some comments, after which the discussion kind of
> >> fizzled out.
> >
> > I don't think we should override early_init_dt_add_memory_arch(), unless
> > we diverge too much from it. Currently, it looks to me like the end of
> > PA range check is pretty useless in this function.
> 
> OK. But note that, when we decouple the linear mapping from the
> mapping of the kernel image, we will need to override this function
> anyway.

That's fine. I assume we'll keep the DT memblock checking in the same
place. The main issue I have with your patch is the split of lower
blocks rejected by one function and higher blocks by another.

-- 
Catalin


From thierry.reding at gmail.com  Mon Aug 17 05:11:43 2015
From: thierry.reding at gmail.com (Thierry Reding)
Date: Mon, 17 Aug 2015 14:11:43 +0200
Subject: [PATCH] drm: panel: simple: add QiaoDian qd43003c0-40
In-Reply-To: <20150817105724.GT22269@piout.net>
References: <1438382671-10098-1-git-send-email-alexandre.belloni@free-electrons.com>
 <20150817100913.GA8453@ulmo.nvidia.com>
 <20150817105724.GT22269@piout.net>
Message-ID: <20150817121142.GK8453@ulmo.nvidia.com>

On Mon, Aug 17, 2015 at 12:57:24PM +0200, Alexandre Belloni wrote:
> On 17/08/2015 at 12:09:14 +0200, Thierry Reding wrote :
> > On Sat, Aug 01, 2015 at 12:44:31AM +0200, Alexandre Belloni wrote:
> > > From: Josh Wu <josh.wu at atmel.com>
> > > 
> > > The QiaoDian Xianshi QD43003C0-40 is a 4"3 TFT LCD panel.
> > > 
> > > Timings from the OTA5180A document, ver 0.9, section
> > > 10.1.1:
> > >   http://www.orientdisplay.com/pdf/OTA5180A.pdf
> > > 
> > > Signed-off-by: Josh Wu <josh.wu at atmel.com>
> > > Signed-off-by: Alexandre Belloni <alexandre.belloni at free-electrons.com>
> > > ---
> > >  .../devicetree/bindings/panel/qd,qd43003c0-40.txt  |  7 ++++++
> > >  drivers/gpu/drm/panel/panel-simple.c               | 26 ++++++++++++++++++++++
> > >  2 files changed, 33 insertions(+)
> > >  create mode 100644 Documentation/devicetree/bindings/panel/qd,qd43003c0-40.txt
> > 
> > You didn't run this through scripts/get_maintainer.pl, did you? It would
> > also help to use the standard prefix ("drm/panel: ") because I end up
> > filtering for that occasionally in case somebody didn't Cc me on panel
> > patches.
> > 
> 
> I'm pretty sure I did as you were the only one in the To: field.
> Maybe you want to check your spam filter.

Looking again, I see that you did indeed. Not sure what I was looking at
before. I apologize.

Thierry
-------------- next part --------------
A non-text attachment was scrubbed...
Name: signature.asc
Type: application/pgp-signature
Size: 819 bytes
Desc: not available
URL: <http://lists.infradead.org/pipermail/linux-arm-kernel/attachments/20150817/4cd45f43/attachment.sig>

From srinivas.kandagatla at linaro.org  Mon Aug 17 05:31:34 2015
From: srinivas.kandagatla at linaro.org (Srinivas Kandagatla)
Date: Mon, 17 Aug 2015 13:31:34 +0100
Subject: [PATCH RFC 3/3] nvmem: add permission flags in nvmem_config
In-Reply-To: <1634428787.18822.1439623316281.JavaMail.open-xchange@oxbsltgw04.schlund.de>
References: <1439290931-18232-1-git-send-email-srinivas.kandagatla@linaro.org>
 <1439291024-18375-1-git-send-email-srinivas.kandagatla@linaro.org>
 <1634428787.18822.1439623316281.JavaMail.open-xchange@oxbsltgw04.schlund.de>
Message-ID: <55D1D426.8020504@linaro.org>



On 15/08/15 08:21, Stefan Wahren wrote:
> Hi Srinivas,
>
>> Srinivas Kandagatla <srinivas.kandagatla at linaro.org> hat am 11. August 2015 um
>> 13:03 geschrieben:
>>
>>
>> This patch adds perm variable to nvmem_config structure which will allow
>> providers to specify the permissions required for the sysfs binary file.
>> This permission is applied on top of root-only access permissions set by
>> the core.
>>
>> Signed-off-by: Srinivas Kandagatla <srinivas.kandagatla at linaro.org>
>> ---
>> drivers/nvmem/core.c | 1 +
>> include/linux/nvmem-provider.h | 1 +
>> 2 files changed, 2 insertions(+)
>>
>> diff --git a/drivers/nvmem/core.c b/drivers/nvmem/core.c
>> index 414ed23..7481387 100644
>> --- a/drivers/nvmem/core.c
>> +++ b/drivers/nvmem/core.c
>> @@ -312,6 +312,7 @@ struct nvmem_device *nvmem_register(const struct
>> nvmem_config *config)
>> config->read_only;
>> nvmem->bin = bin_attr_template;
>> nvmem->bin.attr.mode = nvmem->read_only ? : (S_IRUSR | S_IWUSR);
>> + nvmem->bin.attr.mode |= config->perm;
>> nvmem->bin.size = nvmem->size;
>> device_initialize(&nvmem->dev);
>>
>> diff --git a/include/linux/nvmem-provider.h b/include/linux/nvmem-provider.h
>> index 0b68caf..de9a61f 100644
>> --- a/include/linux/nvmem-provider.h
>> +++ b/include/linux/nvmem-provider.h
>> @@ -23,6 +23,7 @@ struct nvmem_config {
>> const struct nvmem_cell_info *cells;
>> int ncells;
>> bool read_only;
>> + u16 perm; /* visibility in sysfs */
>
> how about "umode_t mode" or "umode_t sysfs_mode"?
>
Yep, "umode_t mode" sounds much better.
I will use it that.

--srini
> Beside that the whole series looks good to me.
>
> Thanks Stefan
>


From srinivas.kandagatla at linaro.org  Mon Aug 17 05:34:58 2015
From: srinivas.kandagatla at linaro.org (Srinivas Kandagatla)
Date: Mon, 17 Aug 2015 13:34:58 +0100
Subject: [PATCH V6 2/3] nvmem: add driver for ocotp in i.MX23 and i.MX28
In-Reply-To: <1439418116-1833-3-git-send-email-stefan.wahren@i2se.com>
References: <1439418116-1833-1-git-send-email-stefan.wahren@i2se.com>
 <1439418116-1833-3-git-send-email-stefan.wahren@i2se.com>
Message-ID: <55D1D4F2.2050209@linaro.org>



On 12/08/15 23:21, Stefan Wahren wrote:
> This patch brings read-only support for the On-Chip OTP cells
> in the i.MX23 and i.MX28 processor. The driver implements the
> new NVMEM provider API.
>
> Signed-off-by: Stefan Wahren <stefan.wahren at i2se.com>
> Reviewed-by: Marek Vasut <marex at denx.de>
> ---
>   drivers/nvmem/Kconfig     |   11 ++
>   drivers/nvmem/Makefile    |    2 +
>   drivers/nvmem/mxs-ocotp.c |  257 +++++++++++++++++++++++++++++++++++++++++++++
>   3 files changed, 270 insertions(+)
>   create mode 100644 drivers/nvmem/mxs-ocotp.c
>
Looks good to me,

Acked-by: Srinivas Kandagatla <srinivas.kandagatla at linaro.org>

> diff --git a/drivers/nvmem/Kconfig b/drivers/nvmem/Kconfig
> index 8db2978..a7b43b9 100644
> --- a/drivers/nvmem/Kconfig
> +++ b/drivers/nvmem/Kconfig
> @@ -36,4 +36,15 @@ config NVMEM_SUNXI_SID
>   	  This driver can also be built as a module. If so, the module
>   	  will be called nvmem_sunxi_sid.
>
> +config NVMEM_MXS_OCOTP
> +	tristate "Freescale MXS On-Chip OTP Memory Support"
> +	depends on ARCH_MXS || COMPILE_TEST
> +	help
> +	  If you say Y here, you will get readonly access to the
> +	  One Time Programmable memory pages that are stored
> +	  on the Freescale i.MX23/i.MX28 processor.
> +
> +	  This driver can also be built as a module. If so, the module
> +	  will be called nvmem-mxs-ocotp.
> +
>   endif
> diff --git a/drivers/nvmem/Makefile b/drivers/nvmem/Makefile
> index 4328b93..e9b6f3c 100644
> --- a/drivers/nvmem/Makefile
> +++ b/drivers/nvmem/Makefile
> @@ -10,3 +10,5 @@ obj-$(CONFIG_QCOM_QFPROM)	+= nvmem_qfprom.o
>   nvmem_qfprom-y			:= qfprom.o
>   obj-$(CONFIG_NVMEM_SUNXI_SID)	+= nvmem_sunxi_sid.o
>   nvmem_sunxi_sid-y		:= sunxi_sid.o
> +obj-$(CONFIG_NVMEM_MXS_OCOTP)	+= nvmem-mxs-ocotp.o
> +nvmem-mxs-ocotp-y		:= mxs-ocotp.o
> diff --git a/drivers/nvmem/mxs-ocotp.c b/drivers/nvmem/mxs-ocotp.c
> new file mode 100644
> index 0000000..8ba19bb
> --- /dev/null
> +++ b/drivers/nvmem/mxs-ocotp.c
> @@ -0,0 +1,257 @@
> +/*
> + * Freescale MXS On-Chip OTP driver
> + *
> + * Copyright (C) 2015 Stefan Wahren <stefan.wahren at i2se.com>
> + *
> + * Based on the driver from Huang Shijie and Christoph G. Baumann
> + *
> + * 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.h>
> +#include <linux/delay.h>
> +#include <linux/device.h>
> +#include <linux/err.h>
> +#include <linux/io.h>
> +#include <linux/module.h>
> +#include <linux/nvmem-provider.h>
> +#include <linux/of_device.h>
> +#include <linux/platform_device.h>
> +#include <linux/regmap.h>
> +#include <linux/slab.h>
> +#include <linux/stmp_device.h>
> +
> +/* OCOTP registers and bits */
> +
> +#define BM_OCOTP_CTRL_RD_BANK_OPEN	BIT(12)
> +#define BM_OCOTP_CTRL_ERROR		BIT(9)
> +#define BM_OCOTP_CTRL_BUSY		BIT(8)
> +
> +#define OCOTP_TIMEOUT		10000
> +#define OCOTP_DATA_OFFSET	0x20
> +
> +struct mxs_ocotp {
> +	struct clk *clk;
> +	void __iomem *base;
> +	struct nvmem_device *nvmem;
> +};
> +
> +static int mxs_ocotp_wait(struct mxs_ocotp *otp)
> +{
> +	int timeout = OCOTP_TIMEOUT;
> +	unsigned int status = 0;
> +
> +	while (timeout--) {
> +		status = readl(otp->base);
> +
> +		if (!(status & (BM_OCOTP_CTRL_BUSY | BM_OCOTP_CTRL_ERROR)))
> +			break;
> +
> +		cpu_relax();
> +	}
> +
> +	if (status & BM_OCOTP_CTRL_BUSY)
> +		return -EBUSY;
> +	else if (status & BM_OCOTP_CTRL_ERROR)
> +		return -EIO;
> +
> +	return 0;
> +}
> +
> +static int mxs_ocotp_read(void *context, const void *reg, size_t reg_size,
> +			  void *val, size_t val_size)
> +{
> +	struct mxs_ocotp *otp = context;
> +	unsigned int offset = *(u32 *)reg;
> +	u32 *buf = val;
> +	int ret;
> +
> +	ret = clk_enable(otp->clk);
> +	if (ret)
> +		return ret;
> +
> +	writel(BM_OCOTP_CTRL_ERROR, otp->base + STMP_OFFSET_REG_CLR);
> +
> +	ret = mxs_ocotp_wait(otp);
> +	if (ret)
> +		goto disable_clk;
> +
> +	/* open OCOTP banks for read */
> +	writel(BM_OCOTP_CTRL_RD_BANK_OPEN, otp->base + STMP_OFFSET_REG_SET);
> +
> +	/* approximately wait 33 hclk cycles */
> +	udelay(1);
> +
> +	ret = mxs_ocotp_wait(otp);
> +	if (ret)
> +		goto close_banks;
> +
> +	while (val_size) {
> +		if ((offset < OCOTP_DATA_OFFSET) || (offset % 16)) {
> +			/* fill up non-data register */
> +			*buf = 0;
> +		} else {
> +			*buf = readl(otp->base + offset);
> +		}
> +
> +		buf++;
> +		val_size--;
> +		offset += reg_size;
> +	}
> +
> +close_banks:
> +	/* close banks for power saving */
> +	writel(BM_OCOTP_CTRL_RD_BANK_OPEN, otp->base + STMP_OFFSET_REG_CLR);
> +
> +disable_clk:
> +	clk_disable(otp->clk);
> +
> +	return ret;
> +}
> +
> +static int mxs_ocotp_write(void *context, const void *data, size_t count)
> +{
> +	/* We don't want to support writing */
> +	return 0;
> +}
> +
> +static bool mxs_ocotp_writeable_reg(struct device *dev, unsigned int reg)
> +{
> +	return false;
> +}
> +
> +static struct nvmem_config ocotp_config = {
> +	.name = "mxs-ocotp",
> +	.owner = THIS_MODULE,
> +};
> +
> +static const struct regmap_range imx23_ranges[] = {
> +	regmap_reg_range(OCOTP_DATA_OFFSET, 0x210),
> +};
> +
> +static const struct regmap_access_table imx23_access = {
> +	.yes_ranges = imx23_ranges,
> +	.n_yes_ranges = ARRAY_SIZE(imx23_ranges),
> +};
> +
> +static const struct regmap_range imx28_ranges[] = {
> +	regmap_reg_range(OCOTP_DATA_OFFSET, 0x290),
> +};
> +
> +static const struct regmap_access_table imx28_access = {
> +	.yes_ranges = imx28_ranges,
> +	.n_yes_ranges = ARRAY_SIZE(imx28_ranges),
> +};
> +
> +static struct regmap_bus mxs_ocotp_bus = {
> +	.read = mxs_ocotp_read,
> +	.write = mxs_ocotp_write, /* make regmap_init() happy */
> +	.reg_format_endian_default = REGMAP_ENDIAN_NATIVE,
> +	.val_format_endian_default = REGMAP_ENDIAN_NATIVE,
> +};
> +
> +static struct regmap_config mxs_ocotp_config = {
> +	.reg_bits = 32,
> +	.val_bits = 32,
> +	.reg_stride = 16,
> +	.writeable_reg = mxs_ocotp_writeable_reg,
> +};
> +
> +static const struct of_device_id mxs_ocotp_match[] = {
> +	{ .compatible = "fsl,imx23-ocotp", .data = &imx23_access },
> +	{ .compatible = "fsl,imx28-ocotp", .data = &imx28_access },
> +	{ /* sentinel */},
> +};
> +MODULE_DEVICE_TABLE(of, mxs_ocotp_match);
> +
> +static int mxs_ocotp_probe(struct platform_device *pdev)
> +{
> +	struct device *dev = &pdev->dev;
> +	struct mxs_ocotp *otp;
> +	struct resource *res;
> +	const struct of_device_id *match;
> +	struct regmap *regmap;
> +	const struct regmap_access_table *access;
> +	int ret;
> +
> +	match = of_match_device(dev->driver->of_match_table, dev);
> +	if (!match || !match->data)
> +		return -EINVAL;
> +
> +	otp = devm_kzalloc(dev, sizeof(*otp), GFP_KERNEL);
> +	if (!otp)
> +		return -ENOMEM;
> +
> +	res = platform_get_resource(pdev, IORESOURCE_MEM, 0);
> +	otp->base = devm_ioremap_resource(dev, res);
> +	if (IS_ERR(otp->base))
> +		return PTR_ERR(otp->base);
> +
> +	otp->clk = devm_clk_get(&pdev->dev, NULL);
> +	if (IS_ERR(otp->clk))
> +		return PTR_ERR(otp->clk);
> +
> +	ret = clk_prepare(otp->clk);
> +	if (ret < 0) {
> +		dev_err(dev, "failed to prepare clk: %d\n", ret);
> +		return ret;
> +	}
> +
> +	access = match->data;
> +	mxs_ocotp_config.rd_table = access;
> +	mxs_ocotp_config.max_register = access->yes_ranges[0].range_max;
> +
> +	regmap = devm_regmap_init(dev, &mxs_ocotp_bus, otp, &mxs_ocotp_config);
> +	if (IS_ERR(regmap)) {
> +		dev_err(dev, "regmap init failed\n");
> +		ret = PTR_ERR(regmap);
> +		goto err_clk;
> +	}
> +
> +	ocotp_config.dev = dev;
> +	otp->nvmem = nvmem_register(&ocotp_config);
> +	if (IS_ERR(otp->nvmem)) {
> +		ret = PTR_ERR(otp->nvmem);
> +		goto err_clk;
> +	}
> +
> +	platform_set_drvdata(pdev, otp);
> +
> +	return 0;
> +
> +err_clk:
> +	clk_unprepare(otp->clk);
> +
> +	return ret;
> +}
> +
> +static int mxs_ocotp_remove(struct platform_device *pdev)
> +{
> +	struct mxs_ocotp *otp = platform_get_drvdata(pdev);
> +
> +	clk_unprepare(otp->clk);
> +
> +	return nvmem_unregister(otp->nvmem);
> +}
> +
> +static struct platform_driver mxs_ocotp_driver = {
> +	.probe = mxs_ocotp_probe,
> +	.remove = mxs_ocotp_remove,
> +	.driver = {
> +		.name = "mxs-ocotp",
> +		.of_match_table = mxs_ocotp_match,
> +	},
> +};
> +
> +module_platform_driver(mxs_ocotp_driver);
> +MODULE_AUTHOR("Stefan Wahren <stefan.wahren at i2se.com>");
> +MODULE_DESCRIPTION("driver for OCOTP in i.MX23/i.MX28");
> +MODULE_LICENSE("GPL v2");
>


From srinivas.kandagatla at linaro.org  Mon Aug 17 05:35:47 2015
From: srinivas.kandagatla at linaro.org (Srinivas Kandagatla)
Date: Mon, 17 Aug 2015 13:35:47 +0100
Subject: [PATCH V6 1/3] DT: nvmem: add binding for mxs-ocotp
In-Reply-To: <1439418116-1833-2-git-send-email-stefan.wahren@i2se.com>
References: <1439418116-1833-1-git-send-email-stefan.wahren@i2se.com>
 <1439418116-1833-2-git-send-email-stefan.wahren@i2se.com>
Message-ID: <55D1D523.3000309@linaro.org>



On 12/08/15 23:21, Stefan Wahren wrote:
> This patch adds the devicetree bindings for the Freescale MXS On Chip
> OTP driver.
>
> Signed-off-by: Stefan Wahren <stefan.wahren at i2se.com>

Acked-by: Srinivas Kandagatla <srinivas.kandagatla at linaro.org>

> ---
>   .../devicetree/bindings/nvmem/mxs-ocotp.txt        |   25 ++++++++++++++++++++
>   1 file changed, 25 insertions(+)
>   create mode 100644 Documentation/devicetree/bindings/nvmem/mxs-ocotp.txt
>
> diff --git a/Documentation/devicetree/bindings/nvmem/mxs-ocotp.txt b/Documentation/devicetree/bindings/nvmem/mxs-ocotp.txt
> new file mode 100644
> index 0000000..daebce9
> --- /dev/null
> +++ b/Documentation/devicetree/bindings/nvmem/mxs-ocotp.txt
> @@ -0,0 +1,25 @@
> +On-Chip OTP Memory for Freescale i.MX23/i.MX28
> +
> +Required properties :
> +- compatible :
> +  - "fsl,imx23-ocotp" for i.MX23
> +  - "fsl,imx28-ocotp" for i.MX28
> +- #address-cells : Should be 1
> +- #size-cells : Should be 1
> +- reg : Address and length of OTP controller registers
> +- clocks : Should contain a reference to the hbus clock
> +
> += Data cells =
> +Are child nodes of mxs-ocotp, bindings of which as described in
> +bindings/nvmem/nvmem.txt
> +
> +Example for i.MX28:
> +
> +	ocotp: ocotp at 8002c000 {
> +		compatible = "fsl,imx28-ocotp", "fsl,ocotp";
> +		#address-cells = <1>;
> +		#size-cells = <1>;
> +		reg = <0x8002c000 0x2000>;
> +		clocks = <&clks 25>;
> +		status = "okay";
> +	};
>


From joro at 8bytes.org  Mon Aug 17 05:40:35 2015
From: joro at 8bytes.org (Joerg Roedel)
Date: Mon, 17 Aug 2015 14:40:35 +0200
Subject: [GIT PULL 6/9] iommu/tegra-smmu: Changes for v4.3-rc1
In-Reply-To: <1439563720-13189-7-git-send-email-thierry.reding@gmail.com>
References: <1439563720-13189-1-git-send-email-thierry.reding@gmail.com>
 <1439563720-13189-7-git-send-email-thierry.reding@gmail.com>
Message-ID: <20150817124035.GK14980@8bytes.org>

On Fri, Aug 14, 2015 at 04:48:37PM +0200, Thierry Reding wrote:
> Hi Joerg,
> 
> The following changes since commit d770e558e21961ad6cfdf0ff7df0eb5d7d4f0754:
> 
>   Linux 4.2-rc1 (2015-07-05 11:01:52 -0700)
> 
> are available in the git repository at:
> 
>   git://git.kernel.org/pub/scm/linux/kernel/git/tegra/linux.git tags/tegra-for-4.3-iommu


Pulled, thanks.



From aisheng.dong at freescale.com  Mon Aug 17 05:45:18 2015
From: aisheng.dong at freescale.com (Dong Aisheng)
Date: Mon, 17 Aug 2015 20:45:18 +0800
Subject: [PATCH V3 4/5] clk: core: add CLK_OPS_PARENT_ON flags to
 support clocks require parent on
In-Reply-To: <20150814010109.GW26614@codeaurora.org>
References: <1438089585-30103-1-git-send-email-aisheng.dong@freescale.com>
 <1438089585-30103-5-git-send-email-aisheng.dong@freescale.com>
 <20150814010109.GW26614@codeaurora.org>
Message-ID: <20150817124514.GA30536@shlinux1.ap.freescale.net>

On Thu, Aug 13, 2015 at 06:01:09PM -0700, Stephen Boyd wrote:
> On 07/28, Dong Aisheng wrote:
> > On Freescale i.MX7D platform, all clocks operations, including
> > enable/disable, rate change and re-parent, requires its parent
> > clock on. Current clock core can not support it well.
> > This patch introduce a new flag CLK_OPS_PARENT_ON to handle this
> > special case in clock core that enable its parent clock firstly for
> > each operation and disable it later after operation complete.
> > 
> > This patch fixes disaling clocks while its parent is off.
> > This is a special case that is caused by a state mis-align between
> > HW and SW in clock tree during booting.
> > Usually in uboot, we may enable all clocks in HW by default.
> > And during kernel booting time, the parent clock could be disabled in its
> > driver probe due to calling clk_prepare_enable and clk_disable_unprepare.
> > Because it's child clock is only enabled in HW while its SW usecount
> > in clock tree is still 0, so clk_disable of parent clock will gate
> > the parent clock in both HW and SW usecount ultimately.
> > Then there will be a clock is on in HW while its parent is disabled.
> > 
> > Later when clock core does clk_disable_unused, this clock disable
> > will cause system hang due to the limitation of operation requiring
> > its parent clock on.
> > 
> > Cc: Mike Turquette <mturquette at linaro.org>
> > Cc: Stephen Boyd <sboyd at codeaurora.org>
> > Signed-off-by: Dong Aisheng <aisheng.dong at freescale.com>
> > ---
> 
> Sorry, I still don't agree with this patch. There's no reason we
> should be turning on clocks during late init so that we can turn
> off clocks.

Can't the reason be that it's fairly possible one clock is enabled
in HW while it's parent is disabled in initial clock tree state
and to enable parent clocks to disable itself is required by its special
HW characteristic?

Dosen't it quite clear from HW point of view?

> If there's some sort of problem in doing that we
> should figure it out and make it so that during late init we turn
> off clocks from the leaves of the tree to the root.
> 

Turning off clocks from the leaves to root probably may require clock core
to provide a way to keep the parent clock enabled once finding its child
is still on in HW (clk_core_is_enabled() returns true) but enable_count
is zero before late init.

One possible solution may be leaving parent clocks on in HW during disable
once finding its child is on in HW and only decrease the parent's refcount,
and then replying on the later clk_disable_unused() to disable both child
and parent from leave to root.
e.g. clock A: parent, clock B: child of A
Initial state: clock B is enabled in HW while refcount is zero
Step1: Driver A enable clock A during probe
 A: refcount becomes 1 HW state: enabled
Step2: Driver A disable clock A after probe
 A: refcount becomes 0 HW state: enabled (only decrease refcount)

Then Clock A will be the same state as B, HW enabled while refcount is zero(
means no users), the later clk_disable_unusersd() will disable them all
from leave to root.

This is a workable solution but seems much more complicated than the exist
one in this patch which is only 5 lines of code changes.

And the question is:
since we already have the support of CLK_OPS_PARENT_ON (required by
clock set_rate/re-parent), why we still need invent another complicated
mechanism to support avoiding enable parent clock only for clk_disable_unused()?
Is that really worthy?
And it's also less power efficiency than the one in the patch.

> I agree that there's a problem here where we don't properly
> handle keeping children clocks on if a driver comes in and turns
> off a clock in the middle of the tree before late init. That's a
> real bug, and we should fix it.

Sorry, i still can't understand it's a bug.
Can you help explain more?

It looks to me like reasonable.
Enable/disable clock in driver is just one case, the initial clock tree may
also have such cases.
(Here i took the 'children clocks' you said as the one who's child clock is on
in HW while refcount is zero, fix me if wrong)

And it seems not so quite make sense to not physically disable the clock
when there's already no child users(refcount becomes zero) and i don't
think the child clock's default enablement state in HW means a valid user
since it's just caused by misalignment between HW and SW clock tree during
kernel booting phase which is meaningless.
And that seems is why the clk_disable_unused() function exist for fixing
this state misalignment issue.

> Mike Turquette has been doing
> some work to have a way to indicate that certain clocks should be
> kept on until client drivers grab them. 

Sorry i can't see how this help on my issue.

> I think it will also make
> sure to up refcounts on parent clocks in the middle of the tree
> when it figures out that a child clock is enabled. Would that be
> all that we need to do to fix this problem?
> 

Then when will we down the refcounts on parent clocks and when to disable it?
The current clk_disable_unused() only handle HW clk enable/disable, no
refcount operations.
Not sure how this is going to fix my issues.

And again, as i said above, i don't think it makes much sense to not disable
parent only if child is enabled in HW, unless there's more strong reasons.

> Also, the subject of this patch and patch 5 are the same. Why?
> 

Sorry, mainly because the full feature of CLK_OPS_PARENT_ON is divided into
two patches for better review, their commit message is different.
patch 4 is adding support for clk_disable_unused() while patch 5 is for
clk_setrate/clk_reparent.
I could reform the subject if needed.

Regards
Dong Aisheng

> -- 
> Qualcomm Innovation Center, Inc. is a member of Code Aurora Forum,
> a Linux Foundation Collaborative Project


From thierry.reding at gmail.com  Mon Aug 17 06:23:00 2015
From: thierry.reding at gmail.com (Thierry Reding)
Date: Mon, 17 Aug 2015 15:23:00 +0200
Subject: [PATCH v6 2/3] pwm: add MediaTek display PWM driver support
In-Reply-To: <1437380237-28961-3-git-send-email-yh.huang@mediatek.com>
References: <1437380237-28961-1-git-send-email-yh.huang@mediatek.com>
 <1437380237-28961-3-git-send-email-yh.huang@mediatek.com>
Message-ID: <20150817132259.GM8453@ulmo.nvidia.com>

On Mon, Jul 20, 2015 at 04:17:16PM +0800, YH Huang wrote:
> Add display PWM driver support to modify backlight for MT8173 and MT6595.
> The PWM has one channel to control the brightness of the display.
> When the (high_width / period) is closer to 1, the screen is brighter;
> otherwise, it is darker.
> 
> Signed-off-by: YH Huang <yh.huang at mediatek.com>
> ---
>  drivers/pwm/Kconfig        |  10 ++
>  drivers/pwm/Makefile       |   1 +
>  drivers/pwm/pwm-mtk-disp.c | 232 +++++++++++++++++++++++++++++++++++++++++++++
>  3 files changed, 243 insertions(+)
>  create mode 100644 drivers/pwm/pwm-mtk-disp.c
> 
> diff --git a/drivers/pwm/Kconfig b/drivers/pwm/Kconfig
> index b1541f4..f5b03a4 100644
> --- a/drivers/pwm/Kconfig
> +++ b/drivers/pwm/Kconfig
> @@ -211,6 +211,16 @@ config PWM_LPSS_PLATFORM
>  	  To compile this driver as a module, choose M here: the module
>  	  will be called pwm-lpss-platform.
>  
> +config PWM_MTK_DISP
> +	tristate "MediaTek display PWM driver"
> +	depends on ARCH_MEDIATEK || COMPILE_TEST

This is going to break randconfig builds. From a quick look your driver
will fail to build at least on architectures that don't set HAVE_IOMEM.
I know that's quite exotic, but I've had to deal with fallout from
things like this in the past. If you want || COMPILE_TEST you should at
least add a "depends on HAVE_IOMEM".

linux/clk.h seems to have stubs for all of the functions that you use,
so those shouldn't be a problem.

> +	help
> +	  Generic PWM framework driver for MediaTek disp-pwm device.
> +	  The PWM is used to control the backlight brightness for display.
> +
> +	  To compile this driver as a module, choose M here: the module
> +	  will be called pwm-mtk-disp.
> +
>  config PWM_MXS
>  	tristate "Freescale MXS PWM support"
>  	depends on ARCH_MXS && OF
[...]
> diff --git a/drivers/pwm/pwm-mtk-disp.c b/drivers/pwm/pwm-mtk-disp.c
> new file mode 100644
> index 0000000..69682a0
> --- /dev/null
> +++ b/drivers/pwm/pwm-mtk-disp.c
> @@ -0,0 +1,232 @@
> +/*
> + * MediaTek display pulse-width-modulation controller driver.
> + * Copyright (c) 2015 MediaTek Inc.
> + * Author: YH Huang <yh.huang at 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/clk.h>
> +#include <linux/err.h>
> +#include <linux/io.h>
> +#include <linux/module.h>
> +#include <linux/of.h>
> +#include <linux/pwm.h>
> +#include <linux/platform_device.h>

The above two aren't correctly sorted.

> +#include <linux/slab.h>
> +
> +#define DISP_PWM_EN		0x00
> +#define PWM_ENABLE_MASK		BIT(0)
> +
> +#define DISP_PWM_COMMIT		0x08
> +#define PWM_COMMIT_MASK		BIT(0)
> +
> +#define DISP_PWM_CON_0		0x10
> +#define PWM_CLKDIV_SHIFT	16
> +#define PWM_CLKDIV_MAX		0x3ff
> +#define PWM_CLKDIV_MASK		(PWM_CLKDIV_MAX << PWM_CLKDIV_SHIFT)
> +
> +#define DISP_PWM_CON_1		0x14
> +#define PWM_PERIOD_MASK		0xfff
> +/* Shift log2(PWM_PERIOD_MASK + 1) as divisor */
> +#define PWM_PERIOD_BIT_SHIFT	12

There are still two names for the same value here. I thought we had
agreed on this becoming something like the below?

	#define PWM_PERIOD_BIT_SHIFT 12
	#define PWM_PERIOD_MASK ((1 << PWM_PERIOD_BIT_SHIFT) - 1)

Although PWM_PERIOD_BIT_WIDTH would probably be a better name. Or
PWM_PERIOD_BITS or similar.

> +static int mtk_disp_pwm_remove(struct platform_device *pdev)
> +{
> +	struct mtk_disp_pwm *mdp = platform_get_drvdata(pdev);
> +	int ret = pwmchip_remove(&mdp->chip);

I'd prefer this to be separate lines:

	int ret;

	ret = pwmchip_remove(&mdp->chip);

Thierry
-------------- next part --------------
A non-text attachment was scrubbed...
Name: signature.asc
Type: application/pgp-signature
Size: 819 bytes
Desc: not available
URL: <http://lists.infradead.org/pipermail/linux-arm-kernel/attachments/20150817/cfca2726/attachment.sig>

From thierry.reding at gmail.com  Mon Aug 17 06:23:59 2015
From: thierry.reding at gmail.com (Thierry Reding)
Date: Mon, 17 Aug 2015 15:23:59 +0200
Subject: [PATCH v6 1/3] dt-bindings: pwm: add MediaTek display PWM bindings
In-Reply-To: <1437380237-28961-2-git-send-email-yh.huang@mediatek.com>
References: <1437380237-28961-1-git-send-email-yh.huang@mediatek.com>
 <1437380237-28961-2-git-send-email-yh.huang@mediatek.com>
Message-ID: <20150817132358.GN8453@ulmo.nvidia.com>

On Mon, Jul 20, 2015 at 04:17:15PM +0800, YH Huang wrote:
> Document the device-tree binding of MediatTek display PWM.

I already mentioned this a while back: s/MediatTek/MediaTek/.

Thierry
-------------- next part --------------
A non-text attachment was scrubbed...
Name: signature.asc
Type: application/pgp-signature
Size: 819 bytes
Desc: not available
URL: <http://lists.infradead.org/pipermail/linux-arm-kernel/attachments/20150817/2d235e40/attachment-0001.sig>

From yingjoe.chen at mediatek.com  Mon Aug 17 06:25:53 2015
From: yingjoe.chen at mediatek.com (Yingjoe Chen)
Date: Mon, 17 Aug 2015 21:25:53 +0800
Subject: [PATCH v4] pinctrl: mediatek: Implement wake handler and
 suspend resume
In-Reply-To: <CAGS+omCQN65pCP7mYFCj8sDOihLNc15GgELw1u7fTXuq=KBXnw@mail.gmail.com>
References: <1439541486-22203-1-git-send-email-maoguang.meng@mediatek.com>
 <1439797974.22004.2.camel@mtksdaap41>
 <CAGS+omCQN65pCP7mYFCj8sDOihLNc15GgELw1u7fTXuq=KBXnw@mail.gmail.com>
Message-ID: <1439817953.3414.4.camel@mtksdaap41>

On Mon, 2015-08-17 at 17:09 +0800, Daniel Kurtz wrote:
> On Mon, Aug 17, 2015 at 3:52 PM, Yingjoe Chen <yingjoe.chen at mediatek.com> wrote:
> > On Fri, 2015-08-14 at 16:38 +0800, maoguang.meng at mediatek.com wrote:
> >> From: Maoguang Meng <maoguang.meng at mediatek.com>
> >>
> >> This patch implement irq_set_wake to get who is wakeup source and
> >> setup on suspend resume.
> >>
> >> Signed-off-by: Maoguang Meng <maoguang.meng at mediatek.com>
> >>
> >> ---
> >> changes since v3:
> >> -add a comment in mtk_eint_chip_read_mask.
> >> -delete ALIGN when allocate eint_offsets.ports.
> >> -fix unrelated change.
> >>
> >> changes since v2:
> >> -modify irq_wake to handle irq wakeup source.
> >> -allocate two buffers separately.
> >> -fix some codestyle.
> >>
> >> Changes since v1:
> >> -implement irq_wake handler.
> >> ---
> >>
> >>  drivers/pinctrl/mediatek/pinctrl-mt8173.c     |  1 +
> >>  drivers/pinctrl/mediatek/pinctrl-mtk-common.c | 91 ++++++++++++++++++++++++++-
> >>  drivers/pinctrl/mediatek/pinctrl-mtk-common.h |  4 ++
> >>  3 files changed, 95 insertions(+), 1 deletion(-)
> >>
> >> diff --git a/drivers/pinctrl/mediatek/pinctrl-mt8173.c b/drivers/pinctrl/mediatek/pinctrl-mt8173.c
> >> index d0c811d..ad27184 100644
> >> --- a/drivers/pinctrl/mediatek/pinctrl-mt8173.c
> >> +++ b/drivers/pinctrl/mediatek/pinctrl-mt8173.c
> >> @@ -385,6 +385,7 @@ static struct platform_driver mtk_pinctrl_driver = {
> >>       .driver = {
> >>               .name = "mediatek-mt8173-pinctrl",
> >>               .of_match_table = mt8173_pctrl_match,
> >> +             .pm = &mtk_eint_pm_ops,
> >>       },
> >>  };
> >>
> >> diff --git a/drivers/pinctrl/mediatek/pinctrl-mtk-common.c b/drivers/pinctrl/mediatek/pinctrl-mtk-common.c
> >> index ad1ea16..fe34ce9 100644
> >> --- a/drivers/pinctrl/mediatek/pinctrl-mtk-common.c
> >> +++ b/drivers/pinctrl/mediatek/pinctrl-mtk-common.c
> >> @@ -33,6 +33,7 @@
> >>  #include <linux/mfd/syscon.h>
> >>  #include <linux/delay.h>
> >>  #include <linux/interrupt.h>
> >> +#include <linux/pm.h>
> >>  #include <dt-bindings/pinctrl/mt65xx.h>
> >>
> >>  #include "../core.h"
> >> @@ -1062,6 +1063,77 @@ static int mtk_eint_set_type(struct irq_data *d,
> >>       return 0;
> >>  }
> >>
> >> +static int mtk_eint_irq_set_wake(struct irq_data *d, unsigned int on)
> >> +{
> >> +     struct mtk_pinctrl *pctl = irq_data_get_irq_chip_data(d);
> >> +     int shift = d->hwirq & 0x1f;
> >> +     int reg = d->hwirq >> 5;
> >> +
> >> +     if (on)
> >> +             pctl->wake_mask[reg] |= BIT(shift);
> >> +     else
> >> +             pctl->wake_mask[reg] &= ~BIT(shift);
> >> +
> >> +     return 0;
> >> +}
> >
> > Hi Maoguang,
> >
> > You changed from set_bit/clear_bit to this, but didn't add any locking.
> > Since this is basic read/modify/write, is it OK to do it without
> > locking?
> 
> I believe calling .irq_set_wake() concurrently with itself is
> protected by irq_get_desc_buslock():
> 
>  int irq_set_irq_wake(unsigned int irq, unsigned int on)
>  {
>          unsigned long flags;
>          struct irq_desc *desc = irq_get_desc_buslock(irq, &flags,
> IRQ_GET_DESC_CHECK_GLOBAL);
>          int ret = 0;
> ...
>                          ret = set_irq_wake_real(irq, on);
> ...
>          irq_put_desc_busunlock(desc, flags);
>          return ret;
>  }

Hi Dan,

You are right, irq_get_desc_buslock will acquire desc lock even when
irq_chip didn't provide irq_bus_lock callback. So this should be OK.
Sorry for the noise.

For this patch:

Acked-by: Yingjoe Chen <yingjoe.chen at mediatek.com>

Joe.C





From msalter at redhat.com  Mon Aug 17 06:32:27 2015
From: msalter at redhat.com (Mark Salter)
Date: Mon, 17 Aug 2015 09:32:27 -0400
Subject: [PATCH V3 2/3] arm64: support initrd outside kernel linear map
In-Reply-To: <20150817112256.GH1688@arm.com>
References: <1439758168-29427-1-git-send-email-msalter@redhat.com>
 <1439758168-29427-3-git-send-email-msalter@redhat.com>
 <20150817112256.GH1688@arm.com>
Message-ID: <1439818347.3153.95.camel@redhat.com>

On Mon, 2015-08-17 at 12:22 +0100, Will Deacon wrote:
> Hi Mark,
> 
> On Sun, Aug 16, 2015 at 09:49:27PM +0100, Mark Salter wrote:
> > The use of mem= could leave part or all of the initrd outside of
> > the kernel linear map. This will lead to an error when unpacking
> > the initrd and a probable failure to boot. This patch catches that
> > situation and relocates the initrd to be fully within the linear
> > map.
> > 
> > Signed-off-by: Mark Salter <msalter at redhat.com>
> > ---
> >  arch/arm64/kernel/setup.c | 59 
> > +++++++++++++++++++++++++++++++++++++++++++++++
> >  1 file changed, 59 insertions(+)
> > 
> > diff --git a/arch/arm64/kernel/setup.c b/arch/arm64/kernel/setup.c
> > index f3067d4..5f45fd9 100644
> > --- a/arch/arm64/kernel/setup.c
> > +++ b/arch/arm64/kernel/setup.c
> > @@ -359,6 +359,64 @@ static void __init 
> > request_standard_resources(void)
> >  	}
> >  }
> >  
> > +#ifdef CONFIG_BLK_DEV_INITRD
> > +/*
> > + * Relocate initrd if it is not completely within the linear mapping.
> > + * This would be the case if mem= cuts out all or part of it.
> > + */
> > +static void __init relocate_initrd(void)
> > +{
> > +	phys_addr_t orig_start = __virt_to_phys(initrd_start);
> > +	phys_addr_t orig_end = __virt_to_phys(initrd_end);
> 
> Any particular reason to use the __* variants here?

To avoid need to cast initrd_{start,end} to pointer.

> 
> > +	phys_addr_t ram_end = memblock_end_of_DRAM();
> > +	phys_addr_t new_start;
> > +	unsigned long size, to_free = 0;
> > +	void *dest;
> > +
> > +	if (orig_end <= ram_end)
> > +		return;
> > +
> > +	/* Note if any of original initrd will freeing below */
> 
> The comment doesn't make sense.

No it doesn't.

> 
> > +	if (orig_start < ram_end)
> > +		to_free = ram_end - orig_start;
> > +
> > +	size = orig_end - orig_start;
> > +
> > +	/* initrd needs to be relocated completely inside linear 
> > mapping */
> > +	new_start = memblock_find_in_range(0, PFN_PHYS(max_pfn),
> > +					   size, PAGE_SIZE);
> > +	if (!new_start)
> > +		panic("Cannot relocate initrd of size %ld\n", size);
> > +	memblock_reserve(new_start, size);
> > +
> > +	initrd_start = __phys_to_virt(new_start);
> > +	initrd_end   = initrd_start + size;
> > +
> > +	pr_info("Moving initrd from [%llx-%llx] to [%llx-%llx]\n",
> > +		orig_start, orig_start + size - 1,
> > +		new_start, new_start + size - 1);
> > +
> > +	dest = (void *)initrd_start;
> > +
> > +	if (to_free) {
> > +		memcpy(dest, (void *)__phys_to_virt(orig_start), 
> > to_free);
> > +		dest += to_free;
> > +	}
> > +
> > +	copy_from_early_mem(dest, orig_start + to_free, size - 
> > to_free);
> > +
> > +	if (to_free) {
> > +		pr_info("Freeing original RAMDISK from [%llx-%llx]\n",
> > +			orig_start, orig_start + to_free - 1);
> > +		memblock_free(orig_start, to_free);
> > +	}
> > +}
> > +#else
> > +static inline void __init reserve_initrd(void)
> 
> relocate_initrd ?

Yes

Thanks, will fix that and the comment.




From geert+renesas at glider.be  Mon Aug 17 06:32:16 2015
From: geert+renesas at glider.be (Geert Uytterhoeven)
Date: Mon, 17 Aug 2015 15:32:16 +0200
Subject: [PATCH] pinctrl: at91: Use generic irq_{request,release}_resources()
Message-ID: <1439818336-31230-1-git-send-email-geert+renesas@glider.be>

The at91-specific irq_{request,release}_resources() callbacks are
identical to the generic ones, modulo the bug fix in 5b76e79c77264899
("gpiolib: irqchip: prevent driver unloading if gpio is used as irq
only").

Until commit 8b67a1f0ad1f260f ("gpio: don't override irq_*_resources()
callbacks"), the buggy at91-specific callbacks were never used, though.

Hence drop the at91-specific ones in favor of the generic ones.

Signed-off-by: Geert Uytterhoeven <geert+renesas at glider.be>
---
Compile-tested only.
---
 drivers/pinctrl/pinctrl-at91.c | 24 ------------------------
 1 file changed, 24 deletions(-)

diff --git a/drivers/pinctrl/pinctrl-at91.c b/drivers/pinctrl/pinctrl-at91.c
index e1ab69928bba38b4..72a3e632c4d9b495 100644
--- a/drivers/pinctrl/pinctrl-at91.c
+++ b/drivers/pinctrl/pinctrl-at91.c
@@ -1488,28 +1488,6 @@ static void gpio_irq_ack(struct irq_data *d)
 	/* the interrupt is already cleared before by reading ISR */
 }
 
-static int gpio_irq_request_res(struct irq_data *d)
-{
-	struct at91_gpio_chip *at91_gpio = irq_data_get_irq_chip_data(d);
-	unsigned	pin = d->hwirq;
-	int ret;
-
-	ret = gpiochip_lock_as_irq(&at91_gpio->chip, pin);
-	if (ret)
-		dev_err(at91_gpio->chip.dev, "unable to lock pind %lu IRQ\n",
-			d->hwirq);
-
-	return ret;
-}
-
-static void gpio_irq_release_res(struct irq_data *d)
-{
-	struct at91_gpio_chip *at91_gpio = irq_data_get_irq_chip_data(d);
-	unsigned	pin = d->hwirq;
-
-	gpiochip_unlock_as_irq(&at91_gpio->chip, pin);
-}
-
 #ifdef CONFIG_PM
 
 static u32 wakeups[MAX_GPIO_BANKS];
@@ -1585,8 +1563,6 @@ void at91_pinctrl_gpio_resume(void)
 static struct irq_chip gpio_irqchip = {
 	.name		= "GPIO",
 	.irq_ack	= gpio_irq_ack,
-	.irq_request_resources = gpio_irq_request_res,
-	.irq_release_resources = gpio_irq_release_res,
 	.irq_disable	= gpio_irq_mask,
 	.irq_mask	= gpio_irq_mask,
 	.irq_unmask	= gpio_irq_unmask,
-- 
1.9.1



From eric.auger at linaro.org  Mon Aug 17 06:33:49 2015
From: eric.auger at linaro.org (Eric Auger)
Date: Mon, 17 Aug 2015 15:33:49 +0200
Subject: [PATCH v2 13/15] KVM: arm64: implement ITS command queue command
 handlers
In-Reply-To: <1436538111-4294-14-git-send-email-andre.przywara@arm.com>
References: <1436538111-4294-1-git-send-email-andre.przywara@arm.com>
 <1436538111-4294-14-git-send-email-andre.przywara@arm.com>
Message-ID: <55D1E2BD.8070801@linaro.org>

On 07/10/2015 04:21 PM, Andre Przywara wrote:
> The connection between a device, an event ID, the LPI number and the
> allocated CPU is stored in in-memory tables in a GICv3, but their
> format is not specified by the spec. Instead software uses a command
> queue in a ring buffer to let the ITS implementation use their own
> format.
> Implement handlers for the various ITS commands and let them store
> the requested relation into our own data structures.
> To avoid kmallocs inside the ITS spinlock, we preallocate possibly
> needed memory outside of the lock and free that if it turns out to
> be not needed (mostly error handling).
still dist lock ...?
> Error handling is very basic at this point, as we don't have a good
> way of communicating errors to the guest (usually a SError).
> The INT command handler is missing at this point, as we gain the
> capability of actually injecting MSIs into the guest only later on.
> 
> Signed-off-by: Andre Przywara <andre.przywara at arm.com>
> ---
>  include/linux/irqchip/arm-gic-v3.h |   5 +-
>  virt/kvm/arm/its-emul.c            | 497 ++++++++++++++++++++++++++++++++++++-
>  virt/kvm/arm/its-emul.h            |  11 +
>  3 files changed, 511 insertions(+), 2 deletions(-)
> 
> diff --git a/include/linux/irqchip/arm-gic-v3.h b/include/linux/irqchip/arm-gic-v3.h
> index 0b450c7..80db4f6 100644
> --- a/include/linux/irqchip/arm-gic-v3.h
> +++ b/include/linux/irqchip/arm-gic-v3.h
> @@ -253,7 +253,10 @@
>   */
>  #define GITS_CMD_MAPD			0x08
>  #define GITS_CMD_MAPC			0x09
> -#define GITS_CMD_MAPVI			0x0a
> +#define GITS_CMD_MAPTI			0x0a
> +/* older GIC documentation used MAPVI for this command */
> +#define GITS_CMD_MAPVI			GITS_CMD_MAPTI
> +#define GITS_CMD_MAPI			0x0b
>  #define GITS_CMD_MOVI			0x01
>  #define GITS_CMD_DISCARD		0x0f
>  #define GITS_CMD_INV			0x0c
> diff --git a/virt/kvm/arm/its-emul.c b/virt/kvm/arm/its-emul.c
> index 05245cb..89534c6 100644
> --- a/virt/kvm/arm/its-emul.c
> +++ b/virt/kvm/arm/its-emul.c
> @@ -22,6 +22,7 @@
>  #include <linux/kvm_host.h>
>  #include <linux/interrupt.h>
>  #include <linux/list.h>
> +#include <linux/slab.h>
>  
>  #include <linux/irqchip/arm-gic-v3.h>
>  #include <kvm/arm_vgic.h>
> @@ -55,6 +56,34 @@ struct its_itte {
>  	unsigned long *pending;
>  };
>  
> +static struct its_device *find_its_device(struct kvm *kvm, u32 device_id)
> +{
> +	struct vgic_its *its = &kvm->arch.vgic.its;
> +	struct its_device *device;
> +
> +	list_for_each_entry(device, &its->device_list, dev_list)
> +		if (device_id == device->device_id)
> +			return device;
> +
> +	return NULL;
> +}
> +
> +static struct its_itte *find_itte(struct kvm *kvm, u32 device_id, u32 event_id)
> +{
> +	struct its_device *device;
> +	struct its_itte *itte;
> +
> +	device = find_its_device(kvm, device_id);
> +	if (device == NULL)
> +		return NULL;
> +
> +	list_for_each_entry(itte, &device->itt, itte_list)
> +		if (itte->event_id == event_id)
> +			return itte;
> +
> +	return NULL;
> +}
> +
>  #define for_each_lpi(dev, itte, kvm) \
>  	list_for_each_entry(dev, &(kvm)->arch.vgic.its.device_list, dev_list) \
>  		list_for_each_entry(itte, &(dev)->itt, itte_list)
> @@ -71,6 +100,19 @@ static struct its_itte *find_itte_by_lpi(struct kvm *kvm, int lpi)
>  	return NULL;
>  }
>  
> +static struct its_collection *find_collection(struct kvm *kvm, int coll_id)
> +{
> +	struct its_collection *collection;
> +
> +	list_for_each_entry(collection, &kvm->arch.vgic.its.collection_list,
> +			    coll_list) {
> +		if (coll_id == collection->collection_id)
> +			return collection;
> +	}
> +
> +	return NULL;
> +}
> +
>  #define LPI_PROP_ENABLE_BIT(p)	((p) & LPI_PROP_ENABLED)
>  #define LPI_PROP_PRIORITY(p)	((p) & 0xfc)
>  
> @@ -333,9 +375,461 @@ void vits_unqueue_lpi(struct kvm_vcpu *vcpu, int lpi)
>  	spin_unlock(&its->lock);
>  }
>  
> +static u64 its_cmd_mask_field(u64 *its_cmd, int word, int shift, int size)
> +{
> +	return (le64_to_cpu(its_cmd[word]) >> shift) & (BIT_ULL(size) - 1);
> +}
> +
> +#define its_cmd_get_command(cmd)	its_cmd_mask_field(cmd, 0,  0,  8)
> +#define its_cmd_get_deviceid(cmd)	its_cmd_mask_field(cmd, 0, 32, 32)
> +#define its_cmd_get_id(cmd)		its_cmd_mask_field(cmd, 1,  0, 32)
> +#define its_cmd_get_physical_id(cmd)	its_cmd_mask_field(cmd, 1, 32, 32)
> +#define its_cmd_get_collection(cmd)	its_cmd_mask_field(cmd, 2,  0, 16)
> +#define its_cmd_get_target_addr(cmd)	its_cmd_mask_field(cmd, 2, 16, 32)
> +#define its_cmd_get_validbit(cmd)	its_cmd_mask_field(cmd, 2, 63,  1)
> +
> +/* The DISCARD command frees an Interrupt Translation Table Entry (ITTE). */
> +static int vits_cmd_handle_discard(struct kvm *kvm, u64 *its_cmd)
> +{
> +	struct vgic_its *its = &kvm->arch.vgic.its;
> +	u32 device_id;
> +	u32 event_id;
> +	struct its_itte *itte;
> +	int ret = 0;
> +
> +	device_id = its_cmd_get_deviceid(its_cmd);
> +	event_id = its_cmd_get_id(its_cmd);
> +
> +	spin_lock(&its->lock);
> +	itte = find_itte(kvm, device_id, event_id);
> +	if (!itte || !itte->collection) {
> +		ret = E_ITS_DISCARD_UNMAPPED_INTERRUPT;
> +		goto out_unlock;
> +	}
> +
> +	__clear_bit(itte->collection->target_addr, itte->pending);
no use since the itte is deleted afterwards?
> +
> +	list_del(&itte->itte_list);
However what about the deletion of the pending field? May be worth
introducing a function to delete an itte (called several times)
> +	kfree(itte);
> +out_unlock:
> +	spin_unlock(&its->lock);
> +	return ret;
> +}
> +
> +/* The MOVI command moves an ITTE to a different collection. */
> +static int vits_cmd_handle_movi(struct kvm *kvm, u64 *its_cmd)
> +{
> +	struct vgic_its *its = &kvm->arch.vgic.its;
> +	u32 device_id = its_cmd_get_deviceid(its_cmd);
> +	u32 event_id = its_cmd_get_id(its_cmd);
> +	u32 coll_id = its_cmd_get_collection(its_cmd);
> +	struct its_itte *itte;
> +	struct its_collection *collection;
> +	int ret;
> +
> +	spin_lock(&its->lock);
> +	itte = find_itte(kvm, device_id, event_id);
> +	if (!itte) {
> +		ret = E_ITS_MOVI_UNMAPPED_INTERRUPT;
> +		goto out_unlock;
> +	}
> +	if (!itte->collection) {
> +		ret = E_ITS_MOVI_UNMAPPED_COLLECTION;
> +		goto out_unlock;
> +	}
> +
> +	collection = find_collection(kvm, coll_id);
> +	if (!collection) {
> +		ret = E_ITS_MOVI_UNMAPPED_COLLECTION;
> +		goto out_unlock;
> +	}
> +
> +	if (test_and_clear_bit(itte->collection->target_addr, itte->pending))
> +		__set_bit(collection->target_addr, itte->pending);
Don't you think we should make sure target_addr is property set on both
source & destination collection (MAPC with valid bit). Typically the
user could MAPI and then call this. This would encourage to add a valid
bit in the collection struct to tell the target_addr is set.
> +
> +	itte->collection = collection;
> +out_unlock:
> +	spin_unlock(&its->lock);
> +	return ret;
> +}
> +
> +static void vits_init_collection(struct kvm *kvm,
> +				 struct its_collection *collection,
> +				 u32 coll_id)
> +{
> +	collection->collection_id = coll_id;
> +
> +	list_add_tail(&collection->coll_list,
> +		&kvm->arch.vgic.its.collection_list);
> +}
> +
> +/* The MAPTI and MAPI commands map LPIs to ITTEs. */
> +static int vits_cmd_handle_mapi(struct kvm *kvm, u64 *its_cmd, u8 cmd)
> +{
> +	struct vgic_dist *dist = &kvm->arch.vgic;
> +	u32 device_id = its_cmd_get_deviceid(its_cmd);
> +	u32 event_id = its_cmd_get_id(its_cmd);
> +	u32 coll_id = its_cmd_get_collection(its_cmd);
> +	struct its_itte *itte, *new_itte;
> +	struct its_device *device;
> +	struct its_collection *collection, *new_coll;
> +	int lpi_nr;
> +	int ret = 0;
> +
> +	/* Preallocate possibly needed memory here outside of the lock */
> +	new_coll = kmalloc(sizeof(struct its_collection), GFP_KERNEL);
> +	new_itte = kzalloc(sizeof(struct its_itte), GFP_KERNEL);
> +	if (new_itte)
> +		new_itte->pending = kcalloc(BITS_TO_LONGS(dist->nr_cpus),
> +					    sizeof(long), GFP_KERNEL);
> +
> +	spin_lock(&dist->its.lock);
> +
> +	device = find_its_device(kvm, device_id);
> +	if (!device) {
> +		ret = E_ITS_MAPTI_UNMAPPED_DEVICE;
> +		goto out_unlock;
> +	}
> +
> +	collection = find_collection(kvm, coll_id);
> +	if (!collection && !new_coll) {
> +		ret = -ENOMEM;
> +		goto out_unlock;
> +	}
> +
> +	if (cmd == GITS_CMD_MAPTI)
> +		lpi_nr = its_cmd_get_physical_id(its_cmd);
> +	else
> +		lpi_nr = event_id;
> +	if (lpi_nr < GIC_LPI_OFFSET ||
> +	    lpi_nr >= nr_idbits_propbase(dist->propbaser)) {
> +		ret = E_ITS_MAPTI_PHYSICALID_OOR;
> +		goto out_unlock;
> +	}
> +
> +	itte = find_itte(kvm, device_id, event_id);
> +	if (!itte) {
> +		if (!new_itte || !new_itte->pending) {
> +			ret = -ENOMEM;
> +			goto out_unlock;
> +		}
> +		itte = new_itte;
> +
> +		itte->event_id	= event_id;
> +		list_add_tail(&itte->itte_list, &device->itt);
> +	} else {
> +		if (new_itte)
> +			kfree(new_itte->pending);
> +		kfree(new_itte);
> +	}
> +
> +	if (!collection) {
> +		collection = new_coll;
need to handle the case where new_coll is null which would cause a crash
in init_collection
> +		vits_init_collection(kvm, collection, coll_id);
> +	} else {
> +		kfree(new_coll);
> +	}
> +
> +	itte->collection = collection;
> +	itte->lpi = lpi_nr;
> +
> +out_unlock:
> +	spin_unlock(&dist->its.lock);
> +	if (ret) {
> +		kfree(new_coll);
> +		if (new_itte)
> +			kfree(new_itte->pending);
> +		kfree(new_itte);
> +	}
> +	return ret;
> +}
> +
> +static void vits_unmap_device(struct kvm *kvm, struct its_device *device)
> +{
> +	struct its_itte *itte, *temp;
> +
> +	/*
> +	 * The spec says that unmapping a device with still valid
> +	 * ITTEs associated is UNPREDICTABLE. We remove all ITTEs,
> +	 * since we cannot leave the memory unreferenced.
> +	 */
> +	list_for_each_entry_safe(itte, temp, &device->itt, itte_list) {
> +		list_del(&itte->itte_list);
deletion of itte->pending
> +		kfree(itte);
> +	}
> +
> +	list_del(&device->dev_list);
> +	kfree(device);
> +}
> +
> +/* The MAPD command maps device IDs to Interrupt Translation Tables (ITTs). */
or unmaps
> +static int vits_cmd_handle_mapd(struct kvm *kvm, u64 *its_cmd)
> +{
> +	struct vgic_its *its = &kvm->arch.vgic.its;
> +	bool valid = its_cmd_get_validbit(its_cmd);
> +	u32 device_id = its_cmd_get_deviceid(its_cmd);
> +	struct its_device *device, *new_device = NULL;
> +
> +	/* We preallocate memory outside of the lock here */
> +	if (valid) {
> +		new_device = kzalloc(sizeof(struct its_device), GFP_KERNEL);
> +		if (!new_device)
> +			return -ENOMEM;
> +	}
> +
> +	spin_lock(&its->lock);
> +
> +	device = find_its_device(kvm, device_id);
> +	if (device)
logically valid should be false too else that's an error?
> +		vits_unmap_device(kvm, device);
> +
> +	/*
> +	 * The spec does not say whether unmapping a not-mapped device
> +	 * is an error, so we are done in any case.
> +	 */
> +	if (!valid)
> +		goto out_unlock;
> +
> +	device = new_device;
> +
> +	device->device_id = device_id;
> +	INIT_LIST_HEAD(&device->itt);
> +
> +	list_add_tail(&device->dev_list,
> +		      &kvm->arch.vgic.its.device_list);
> +
> +out_unlock:
> +	spin_unlock(&its->lock);
> +	return 0;
> +}
> +
> +/* The MAPC command maps collection IDs to redistributors. */
> +static int vits_cmd_handle_mapc(struct kvm *kvm, u64 *its_cmd)
> +{
> +	struct vgic_its *its = &kvm->arch.vgic.its;
> +	u16 coll_id;
> +	u32 target_addr;
> +	struct its_collection *collection, *new_coll = NULL;
> +	bool valid;
> +
> +	valid = its_cmd_get_validbit(its_cmd);
> +	coll_id = its_cmd_get_collection(its_cmd);
> +	target_addr = its_cmd_get_target_addr(its_cmd);
> +
> +	if (target_addr >= atomic_read(&kvm->online_vcpus))
> +		return E_ITS_MAPC_PROCNUM_OOR;
> +
> +	/* We preallocate memory outside of the lock here */
> +	if (valid) {
> +		new_coll = kmalloc(sizeof(struct its_collection), GFP_KERNEL);
> +		if (!new_coll)
> +			return -ENOMEM;
> +	}
> +
> +	spin_lock(&its->lock);
> +	collection = find_collection(kvm, coll_id);
> +
> +	if (!valid) {
> +		struct its_device *device;
> +		struct its_itte *itte;
> +		/*
> +		 * Clearing the mapping for that collection ID removes the
> +		 * entry from the list. If there wasn't any before, we can
> +		 * go home early.
> +		 */
> +		if (!collection)
> +			goto out_unlock;
> +
> +		for_each_lpi(device, itte, kvm)
> +			if (itte->collection &&
> +			    itte->collection->collection_id == coll_id)
> +				itte->collection = NULL;
> +
> +		list_del(&collection->coll_list);
> +		kfree(collection);
> +	} else {
> +		if (!collection)
> +			collection = new_coll;
> +		else
> +			kfree(new_coll);
> +
> +		vits_init_collection(kvm, collection, coll_id);
> +		collection->target_addr = target_addr;
> +	}
> +
> +out_unlock:
> +	spin_unlock(&its->lock);
> +	return 0;
> +}
> +
> +/* The CLEAR command removes the pending state for a particular LPI. */
> +static int vits_cmd_handle_clear(struct kvm *kvm, u64 *its_cmd)
> +{
> +	struct vgic_its *its = &kvm->arch.vgic.its;
> +	u32 device_id;
> +	u32 event_id;
> +	struct its_itte *itte;
> +	int ret = 0;
> +
> +	device_id = its_cmd_get_deviceid(its_cmd);
> +	event_id = its_cmd_get_id(its_cmd);
> +
> +	spin_lock(&its->lock);
> +
> +	itte = find_itte(kvm, device_id, event_id);
> +	if (!itte) {
> +		ret = E_ITS_CLEAR_UNMAPPED_INTERRUPT;
> +		goto out_unlock;
> +	}
> +
> +	if (itte->collection)
> +		__clear_bit(itte->collection->target_addr, itte->pending);
> +
> +out_unlock:
> +	spin_unlock(&its->lock);
> +	return ret;
> +}
> +
> +/* The INV command syncs the pending bit from the memory tables. */
> +static int vits_cmd_handle_inv(struct kvm *kvm, u64 *its_cmd)
> +{
> +	struct vgic_dist *dist = &kvm->arch.vgic;
> +	u32 device_id;
> +	u32 event_id;
> +	struct its_itte *itte, *new_itte;
> +	gpa_t propbase;
> +	int ret;
> +	u8 prop;
> +
> +	device_id = its_cmd_get_deviceid(its_cmd);
> +	event_id = its_cmd_get_id(its_cmd);
> +
> +	spin_lock(&dist->its.lock);
> +	itte = find_itte(kvm, device_id, event_id);
> +	spin_unlock(&dist->its.lock);
> +	if (!itte)
> +		return E_ITS_INV_UNMAPPED_INTERRUPT;
> +
> +	/*
> +	 * We cannot read from guest memory inside the spinlock, so we
> +	 * need to re-read our tables to learn whether the LPI number we are
> +	 * using is still valid.
> +	 */
> +	do {
> +		propbase = BASER_BASE_ADDRESS(dist->propbaser);
> +		ret = kvm_read_guest(kvm, propbase + itte->lpi - GIC_LPI_OFFSET,
> +				     &prop, 1);
> +		if (ret)
> +			return ret;
> +
> +		spin_lock(&dist->its.lock);
> +		new_itte = find_itte(kvm, device_id, event_id);
> +		if (new_itte->lpi != itte->lpi) {
> +			itte = new_itte;
> +			spin_unlock(&dist->its.lock);
> +			continue;
> +		}
> +		update_lpi_config(kvm, itte, prop);
spec says the pending table should be sync'ed too. shouldn't we update
the pending table in the guest address range?
> +		spin_unlock(&dist->its.lock);
> +	} while (0);
> +	return 0;
> +}
> +
> +/* The INVALL command requests flushing of all IRQ data in this collection. */
> +static int vits_cmd_handle_invall(struct kvm *kvm, u64 *its_cmd)
> +{
> +	u32 coll_id = its_cmd_get_collection(its_cmd);
> +	struct its_collection *collection;
> +	struct kvm_vcpu *vcpu;
> +
> +	collection = find_collection(kvm, coll_id);
> +	if (!collection)
> +		return E_ITS_INVALL_UNMAPPED_COLLECTION;
> +
> +	vcpu = kvm_get_vcpu(kvm, collection->target_addr);
> +
> +	its_update_lpis_configuration(kvm);
> +	its_sync_lpi_pending_table(vcpu);
here we do?
> +
> +	return 0;
> +}
> +
> +/* The MOVALL command moves all IRQs from one redistributor to another. */
> +static int vits_cmd_handle_movall(struct kvm *kvm, u64 *its_cmd)
> +{
> +	struct vgic_its *its = &kvm->arch.vgic.its;
> +	u32 target1_addr = its_cmd_get_target_addr(its_cmd);
> +	u32 target2_addr = its_cmd_mask_field(its_cmd, 3, 16, 32);
> +	struct its_collection *collection;
> +	struct its_device *device;
> +	struct its_itte *itte;
> +
> +	if (target1_addr >= atomic_read(&kvm->online_vcpus) ||
> +	    target2_addr >= atomic_read(&kvm->online_vcpus))
> +		return E_ITS_MOVALL_PROCNUM_OOR;
> +
> +	if (target1_addr == target2_addr)
> +		return 0;
> +
> +	spin_lock(&its->lock);
> +	for_each_lpi(device, itte, kvm) {
> +		/* remap all collections mapped to target address 1 */
> +		collection = itte->collection;
> +		if (collection && collection->target_addr == target1_addr)
> +			collection->target_addr = target2_addr;
> +
> +		/* move pending state if LPI is affected */
> +		if (test_and_clear_bit(target1_addr, itte->pending))
> +			__set_bit(target2_addr, itte->pending);
> +	}
> +
> +	spin_unlock(&its->lock);
> +	return 0;
> +}
> +
>  static int vits_handle_command(struct kvm_vcpu *vcpu, u64 *its_cmd)
>  {
> -	return -ENODEV;
> +	u8 cmd = its_cmd_get_command(its_cmd);
> +	int ret = -ENODEV;
> +
> +	switch (cmd) {
> +	case GITS_CMD_MAPD:
> +		ret = vits_cmd_handle_mapd(vcpu->kvm, its_cmd);
> +		break;
> +	case GITS_CMD_MAPC:
> +		ret = vits_cmd_handle_mapc(vcpu->kvm, its_cmd);
> +		break;
> +	case GITS_CMD_MAPI:
> +		ret = vits_cmd_handle_mapi(vcpu->kvm, its_cmd, cmd);
> +		break;
> +	case GITS_CMD_MAPTI:
> +		ret = vits_cmd_handle_mapi(vcpu->kvm, its_cmd, cmd);
> +		break;
> +	case GITS_CMD_MOVI:
> +		ret = vits_cmd_handle_movi(vcpu->kvm, its_cmd);
> +		break;
> +	case GITS_CMD_DISCARD:
> +		ret = vits_cmd_handle_discard(vcpu->kvm, its_cmd);
> +		break;
> +	case GITS_CMD_CLEAR:
> +		ret = vits_cmd_handle_clear(vcpu->kvm, its_cmd);
> +		break;
> +	case GITS_CMD_MOVALL:
> +		ret = vits_cmd_handle_movall(vcpu->kvm, its_cmd);
> +		break;
> +	case GITS_CMD_INV:
> +		ret = vits_cmd_handle_inv(vcpu->kvm, its_cmd);
> +		break;
> +	case GITS_CMD_INVALL:
> +		ret = vits_cmd_handle_invall(vcpu->kvm, its_cmd);
> +		break;
> +	case GITS_CMD_SYNC:
> +		/* we ignore this command: we are in sync all of the time */
> +		ret = 0;
> +		break;
> +	}
> +
> +	return ret;
>  }
>  
>  static bool handle_mmio_gits_cbaser(struct kvm_vcpu *vcpu,
> @@ -554,6 +1048,7 @@ void vits_destroy(struct kvm *kvm)
>  		list_for_each_safe(cur, temp, &dev->itt) {
>  			itte = (container_of(cur, struct its_itte, itte_list));
>  			list_del(cur);
> +			kfree(itte->pending);
should belong to a previous patch I think

Eric
>  			kfree(itte);
>  		}
>  		list_del(dev_cur);
> diff --git a/virt/kvm/arm/its-emul.h b/virt/kvm/arm/its-emul.h
> index cbc3877..830524a 100644
> --- a/virt/kvm/arm/its-emul.h
> +++ b/virt/kvm/arm/its-emul.h
> @@ -39,4 +39,15 @@ void vits_destroy(struct kvm *kvm);
>  bool vits_queue_lpis(struct kvm_vcpu *vcpu);
>  void vits_unqueue_lpi(struct kvm_vcpu *vcpu, int irq);
>  
> +#define E_ITS_MOVI_UNMAPPED_INTERRUPT		0x010107
> +#define E_ITS_MOVI_UNMAPPED_COLLECTION		0x010109
> +#define E_ITS_CLEAR_UNMAPPED_INTERRUPT		0x010507
> +#define E_ITS_MAPC_PROCNUM_OOR			0x010902
> +#define E_ITS_MAPTI_UNMAPPED_DEVICE		0x010a04
> +#define E_ITS_MAPTI_PHYSICALID_OOR		0x010a06
> +#define E_ITS_INV_UNMAPPED_INTERRUPT		0x010c07
> +#define E_ITS_INVALL_UNMAPPED_COLLECTION	0x010d09
> +#define E_ITS_MOVALL_PROCNUM_OOR		0x010e01
> +#define E_ITS_DISCARD_UNMAPPED_INTERRUPT	0x010f07
> +
>  #endif
> 



From eric.auger at linaro.org  Mon Aug 17 06:44:50 2015
From: eric.auger at linaro.org (Eric Auger)
Date: Mon, 17 Aug 2015 15:44:50 +0200
Subject: [PATCH v2 14/15] KVM: arm64: implement MSI injection in ITS
 emulation
In-Reply-To: <1436538111-4294-15-git-send-email-andre.przywara@arm.com>
References: <1436538111-4294-1-git-send-email-andre.przywara@arm.com>
 <1436538111-4294-15-git-send-email-andre.przywara@arm.com>
Message-ID: <55D1E552.4060508@linaro.org>

On 07/10/2015 04:21 PM, Andre Przywara wrote:
> When userland wants to inject a MSI into the guest, we have to use
> our data structures to find the LPI number and the VCPU to receive
> the interrupt.
> Use the wrapper functions to iterate the linked lists and find the
> proper Interrupt Translation Table Entry. Then set the pending bit
> in this ITTE to be later picked up by the LR handling code. Kick
> the VCPU which is meant to handle this interrupt.
> We provide a VGIC emulation model specific routine for the actual
> MSI injection. The wrapper functions return an error for models not
> (yet) implementing MSIs (like the GICv2 emulation).
> We also provide the handler for the ITS "INT" command, which allows a
> guest to trigger an MSI via the ITS command queue.
> 
> Signed-off-by: Andre Przywara <andre.przywara at arm.com>
> ---
>  include/kvm/arm_vgic.h      |  1 +
>  virt/kvm/arm/its-emul.c     | 65 +++++++++++++++++++++++++++++++++++++++++++++
>  virt/kvm/arm/its-emul.h     |  2 ++
>  virt/kvm/arm/vgic-v3-emul.c |  1 +
>  4 files changed, 69 insertions(+)
> 
> diff --git a/include/kvm/arm_vgic.h b/include/kvm/arm_vgic.h
> index 323c33a..9e1abf9 100644
> --- a/include/kvm/arm_vgic.h
> +++ b/include/kvm/arm_vgic.h
> @@ -149,6 +149,7 @@ struct vgic_vm_ops {
>  	int	(*map_resources)(struct kvm *, const struct vgic_params *);
>  	bool	(*queue_lpis)(struct kvm_vcpu *);
>  	void	(*unqueue_lpi)(struct kvm_vcpu *, int irq);
> +	int	(*inject_msi)(struct kvm *, struct kvm_msi *);
>  };
>  
>  struct vgic_io_device {
> diff --git a/virt/kvm/arm/its-emul.c b/virt/kvm/arm/its-emul.c
> index 89534c6..a1c12bb 100644
> --- a/virt/kvm/arm/its-emul.c
> +++ b/virt/kvm/arm/its-emul.c
> @@ -323,6 +323,55 @@ static bool handle_mmio_gits_idregs(struct kvm_vcpu *vcpu,
>  }
>  
>  /*
> + * Translates an incoming MSI request into the redistributor (=VCPU) and
> + * the associated LPI number. Sets the LPI pending bit and also marks the
> + * VCPU as having a pending interrupt.
> + */
> +int vits_inject_msi(struct kvm *kvm, struct kvm_msi *msi)
> +{
> +	struct vgic_dist *dist = &kvm->arch.vgic;
> +	struct vgic_its *its = &dist->its;
> +	struct its_itte *itte;
> +	int cpuid;
> +	bool inject = false;
> +	int ret = 0;
> +
> +	if (!vgic_has_its(kvm))
> +		return -ENODEV;
> +
> +	if (!(msi->flags & KVM_MSI_VALID_DEVID))
> +		return -EINVAL;
> +
> +	spin_lock(&its->lock);
> +
> +	if (!its->enabled || !dist->lpis_enabled) {
> +		ret = -EAGAIN;
> +		goto out_unlock;
> +	}
> +
> +	itte = find_itte(kvm, msi->devid, msi->data);
> +	/* Triggering an unmapped IRQ gets silently dropped. */
> +	if (!itte || !itte->collection)
> +		goto out_unlock;
> +
> +	cpuid = itte->collection->target_addr;
what if MAPC was not done?
> +	__set_bit(cpuid, itte->pending);
> +	inject = itte->enabled;
> +
> +out_unlock:
> +	spin_unlock(&its->lock);
> +
> +	if (inject) {
> +		spin_lock(&dist->lock);
deadlock when called from vits_handle_command?

Eric
> +		__set_bit(cpuid, dist->irq_pending_on_cpu);
> +		spin_unlock(&dist->lock);
> +		kvm_vcpu_kick(kvm_get_vcpu(kvm, cpuid));
> +	}
> +
> +	return ret;
> +}
> +
> +/*
>   * Find all enabled and pending LPIs and queue them into the list
>   * registers.
>   * The dist lock is held by the caller.
> @@ -787,6 +836,19 @@ static int vits_cmd_handle_movall(struct kvm *kvm, u64 *its_cmd)
>  	return 0;
>  }
>  
> +/* The INT command injects the LPI associated with that DevID/EvID pair. */
> +static int vits_cmd_handle_int(struct kvm *kvm, u64 *its_cmd)
> +{
> +	struct kvm_msi msi = {
> +		.data = its_cmd_get_id(its_cmd),
> +		.devid = its_cmd_get_deviceid(its_cmd),
> +		.flags = KVM_MSI_VALID_DEVID,
> +	};
> +
> +	vits_inject_msi(kvm, &msi);
> +	return 0;
> +}
> +
>  static int vits_handle_command(struct kvm_vcpu *vcpu, u64 *its_cmd)
>  {
>  	u8 cmd = its_cmd_get_command(its_cmd);
> @@ -817,6 +879,9 @@ static int vits_handle_command(struct kvm_vcpu *vcpu, u64 *its_cmd)
>  	case GITS_CMD_MOVALL:
>  		ret = vits_cmd_handle_movall(vcpu->kvm, its_cmd);
>  		break;
> +	case GITS_CMD_INT:
> +		ret = vits_cmd_handle_int(vcpu->kvm, its_cmd);
> +		break;
>  	case GITS_CMD_INV:
>  		ret = vits_cmd_handle_inv(vcpu->kvm, its_cmd);
>  		break;
> diff --git a/virt/kvm/arm/its-emul.h b/virt/kvm/arm/its-emul.h
> index 830524a..95e56a7 100644
> --- a/virt/kvm/arm/its-emul.h
> +++ b/virt/kvm/arm/its-emul.h
> @@ -36,6 +36,8 @@ void vgic_enable_lpis(struct kvm_vcpu *vcpu);
>  int vits_init(struct kvm *kvm);
>  void vits_destroy(struct kvm *kvm);
>  
> +int vits_inject_msi(struct kvm *kvm, struct kvm_msi *msi);
> +
>  bool vits_queue_lpis(struct kvm_vcpu *vcpu);
>  void vits_unqueue_lpi(struct kvm_vcpu *vcpu, int irq);
>  
> diff --git a/virt/kvm/arm/vgic-v3-emul.c b/virt/kvm/arm/vgic-v3-emul.c
> index 4132c26..30bf7035 100644
> --- a/virt/kvm/arm/vgic-v3-emul.c
> +++ b/virt/kvm/arm/vgic-v3-emul.c
> @@ -948,6 +948,7 @@ void vgic_v3_init_emulation(struct kvm *kvm)
>  	dist->vm_ops.init_model = vgic_v3_init_model;
>  	dist->vm_ops.destroy_model = vgic_v3_destroy_model;
>  	dist->vm_ops.map_resources = vgic_v3_map_resources;
> +	dist->vm_ops.inject_msi = vits_inject_msi;
>  	dist->vm_ops.queue_lpis = vits_queue_lpis;
>  	dist->vm_ops.unqueue_lpi = vits_unqueue_lpi;
>  
> 



From maitysanchayan at gmail.com  Mon Aug 17 06:56:06 2015
From: maitysanchayan at gmail.com (maitysanchayan at gmail.com)
Date: Mon, 17 Aug 2015 19:26:06 +0530
Subject: [PATCH v3] iio: adc: vf610: Add IIO buffer support for Vybrid ADC
In-Reply-To: <55CF9FE1.3000103@kernel.org>
References: <cover.1439283162.git.maitysanchayan@gmail.com>
 <d556443a26070be505f9a5f5f0999253b73d9b71.1439283162.git.maitysanchayan@gmail.com>
 <55CF9FE1.3000103@kernel.org>
Message-ID: <20150817135606.GB2940@Sanchayan-Arch.toradex.int>

Hello Jonathan,

On 15-08-15 21:24:01, Jonathan Cameron wrote:
> On 11/08/15 10:05, Sanchayan Maity wrote:
> > This patch adds support for IIO buffer to the Vybrid ADC driver.
> > IIO triggered buffer infrastructure along with iio sysfs trigger
> > is used to leverage continuous sampling support provided by the
> > ADC block.
> > 
> > Signed-off-by: Sanchayan Maity <maitysanchayan at gmail.com>
> Hi Sanchayan,
> 
> Very nearly there. One little point to do with the buffer handling.
> Basically I don't think you want anything in the preenable or
> postdisable hooks, just in the 'internal' ones.
> 
> Jonathan
> > ---
> >  drivers/iio/adc/Kconfig     |   2 +
> >  drivers/iio/adc/vf610_adc.c | 102 +++++++++++++++++++++++++++++++++++++++++---
> >  2 files changed, 97 insertions(+), 7 deletions(-)
> > 
> > diff --git a/drivers/iio/adc/Kconfig b/drivers/iio/adc/Kconfig
> > index 7c55658..660f790 100644
> > --- a/drivers/iio/adc/Kconfig
> > +++ b/drivers/iio/adc/Kconfig
> > @@ -337,6 +337,8 @@ config TWL6030_GPADC
> >  config VF610_ADC
> >  	tristate "Freescale vf610 ADC driver"
> >  	depends on OF
> > +	select IIO_BUFFER
> > +	select IIO_TRIGGERED_BUFFER
> >  	help
> >  	  Say yes here to support for Vybrid board analog-to-digital converter.
> >  	  Since the IP is used for i.MX6SLX, the driver also support i.MX6SLX.
> > diff --git a/drivers/iio/adc/vf610_adc.c b/drivers/iio/adc/vf610_adc.c
> > index 23b8fb9..de62c48 100644
> > --- a/drivers/iio/adc/vf610_adc.c
> > +++ b/drivers/iio/adc/vf610_adc.c
> > @@ -34,8 +34,11 @@
> >  #include <linux/err.h>
> >  
> >  #include <linux/iio/iio.h>
> > +#include <linux/iio/buffer.h>
> >  #include <linux/iio/sysfs.h>
> > -#include <linux/iio/driver.h>
> > +#include <linux/iio/trigger.h>
> > +#include <linux/iio/trigger_consumer.h>
> > +#include <linux/iio/triggered_buffer.h>
> >  
> >  /* This will be the driver name the kernel reports */
> >  #define DRIVER_NAME "vf610-adc"
> > @@ -170,6 +173,7 @@ struct vf610_adc {
> >  	u32 sample_freq_avail[5];
> >  
> >  	struct completion completion;
> > +	u16 buffer[8];
> >  };
> >  
> >  static const u32 vf610_hw_avgs[] = { 1, 4, 8, 16, 32 };
> > @@ -505,12 +509,24 @@ static const struct iio_chan_spec_ext_info vf610_ext_info[] = {
> >  	.info_mask_shared_by_type = BIT(IIO_CHAN_INFO_SCALE) |	\
> >  				BIT(IIO_CHAN_INFO_SAMP_FREQ),	\
> >  	.ext_info = vf610_ext_info,				\
> > +	.scan_index = (_idx),			\
> > +	.scan_type = {					\
> > +		.sign = 'u',				\
> > +		.realbits = 12,				\
> > +		.storagebits = 16,			\
> > +	},						\
> >  }
> >  
> >  #define VF610_ADC_TEMPERATURE_CHAN(_idx, _chan_type) {	\
> >  	.type = (_chan_type),	\
> >  	.channel = (_idx),		\
> >  	.info_mask_separate = BIT(IIO_CHAN_INFO_PROCESSED),	\
> > +	.scan_index = (_idx),					\
> > +	.scan_type = {						\
> > +		.sign = 'u',					\
> > +		.realbits = 12,					\
> > +		.storagebits = 16,				\
> > +	},							\
> >  }
> >  
> >  static const struct iio_chan_spec vf610_adc_iio_channels[] = {
> > @@ -531,6 +547,7 @@ static const struct iio_chan_spec vf610_adc_iio_channels[] = {
> >  	VF610_ADC_CHAN(14, IIO_VOLTAGE),
> >  	VF610_ADC_CHAN(15, IIO_VOLTAGE),
> >  	VF610_ADC_TEMPERATURE_CHAN(26, IIO_TEMP),
> > +	IIO_CHAN_SOFT_TIMESTAMP(32),
> >  	/* sentinel */
> >  };
> >  
> > @@ -559,13 +576,20 @@ static int vf610_adc_read_data(struct vf610_adc *info)
> >  
> >  static irqreturn_t vf610_adc_isr(int irq, void *dev_id)
> >  {
> > -	struct vf610_adc *info = (struct vf610_adc *)dev_id;
> > +	struct iio_dev *indio_dev = (struct iio_dev *)dev_id;
> > +	struct vf610_adc *info = iio_priv(indio_dev);
> >  	int coco;
> >  
> >  	coco = readl(info->regs + VF610_REG_ADC_HS);
> >  	if (coco & VF610_ADC_HS_COCO0) {
> >  		info->value = vf610_adc_read_data(info);
> > -		complete(&info->completion);
> > +		if (iio_buffer_enabled(indio_dev)) {
> > +			info->buffer[0] = info->value;
> > +			iio_push_to_buffers_with_timestamp(indio_dev,
> > +					info->buffer, iio_get_time_ns());
> > +			iio_trigger_notify_done(indio_dev->trig);
> > +		} else
> > +			complete(&info->completion);
> >  	}
> >  
> >  	return IRQ_HANDLED;
> > @@ -613,8 +637,12 @@ static int vf610_read_raw(struct iio_dev *indio_dev,
> >  	case IIO_CHAN_INFO_RAW:
> >  	case IIO_CHAN_INFO_PROCESSED:
> >  		mutex_lock(&indio_dev->mlock);
> > -		reinit_completion(&info->completion);
> > +		if (iio_buffer_enabled(indio_dev)) {
> > +			mutex_unlock(&indio_dev->mlock);
> > +			return -EBUSY;
> > +		}
> >  
> > +		reinit_completion(&info->completion);
> >  		hc_cfg = VF610_ADC_ADCHC(chan->channel);
> >  		hc_cfg |= VF610_ADC_AIEN;
> >  		writel(hc_cfg, info->regs + VF610_REG_ADC_HC0);
> > @@ -694,6 +722,57 @@ static int vf610_write_raw(struct iio_dev *indio_dev,
> >  	return -EINVAL;
> >  }
> >  
> > +static int vf610_adc_buffer_postenable(struct iio_dev *indio_dev)
> > +{
> > +	struct vf610_adc *info = iio_priv(indio_dev);
> > +	unsigned int channel;
> > +	int ret;
> > +	int val;
> > +
> > +	ret = iio_triggered_buffer_postenable(indio_dev);
> > +	if (ret)
> > +		return ret;
> > +
> > +	val = readl(info->regs + VF610_REG_ADC_GC);
> > +	val |= VF610_ADC_ADCON;
> > +	writel(val, info->regs + VF610_REG_ADC_GC);
> > +
> > +	channel = find_first_bit(indio_dev->active_scan_mask,
> > +						indio_dev->masklength);
> > +
> > +	val = VF610_ADC_ADCHC(channel);
> > +	val |= VF610_ADC_AIEN;
> > +
> > +	writel(val, info->regs + VF610_REG_ADC_HC0);
> > +
> > +	return 0;
> > +}
> > +
> 
> These are suppose to be pair wise matched, so anything set up
> in postenable has to be torn down in predisable.
> Likewise, preenable setup torn down in postdisable.
> 
> The distinction is meant to be that a query will return that the
> buffer is enabled from a point between the pre and post enable
> and return that it is disabled from a point between the pre and
> post disable.  Actually locks are held so there may no longer
> be a window where it matters, but best to keep to convention.
> 
> I think you want the postdisable -> predisable and then call the
> standard predisable from there.

Ok. I guess I understood. So the postdisable code actually should
go into predisable and while taking care of mutex locking.

The way I was reasoning wanting to enable the continuous sampling
after the buffer is enabled and then after buffer is disabled,
stopping it. With your explanation it makes sense that I should
have it in predisable.

Thank you for the feedback. I will incoporate the above change
and send the new version.

- Sanchayan.

> 
> > +static int vf610_adc_buffer_postdisable(struct iio_dev *indio_dev)
> > +{
> > +	struct vf610_adc *info = iio_priv(indio_dev);
> > +	unsigned int hc_cfg = 0;
> > +	int val;
> > +
> > +	val = readl(info->regs + VF610_REG_ADC_GC);
> > +	val &= ~VF610_ADC_ADCON;
> > +	writel(val, info->regs + VF610_REG_ADC_GC);
> > +
> > +	hc_cfg |= VF610_ADC_CONV_DISABLE;
> > +	hc_cfg &= ~VF610_ADC_AIEN;
> > +
> > +	writel(hc_cfg, info->regs + VF610_REG_ADC_HC0);
> > +
> > +	return 0;
> > +}
> > +
> > +static const struct iio_buffer_setup_ops iio_triggered_buffer_setup_ops = {
> > +	.postenable = &vf610_adc_buffer_postenable,
> > +	.predisable = &iio_triggered_buffer_predisable,
> > +	.postdisable = &vf610_adc_buffer_postdisable,
> > +	.validate_scan_mask = &iio_validate_scan_mask_onehot,
> > +};
> > +
> >  static int vf610_adc_reg_access(struct iio_dev *indio_dev,
> >  			unsigned reg, unsigned writeval,
> >  			unsigned *readval)
> > @@ -753,7 +832,7 @@ static int vf610_adc_probe(struct platform_device *pdev)
> >  
> >  	ret = devm_request_irq(info->dev, irq,
> >  				vf610_adc_isr, 0,
> > -				dev_name(&pdev->dev), info);
> > +				dev_name(&pdev->dev), indio_dev);
> >  	if (ret < 0) {
> >  		dev_err(&pdev->dev, "failed requesting irq, irq = %d\n", irq);
> >  		return ret;
> > @@ -806,15 +885,23 @@ static int vf610_adc_probe(struct platform_device *pdev)
> >  	vf610_adc_cfg_init(info);
> >  	vf610_adc_hw_init(info);
> >  
> > +	ret = iio_triggered_buffer_setup(indio_dev, &iio_pollfunc_store_time,
> > +					NULL, &iio_triggered_buffer_setup_ops);
> > +	if (ret < 0) {
> > +		dev_err(&pdev->dev, "Couldn't initialise the buffer\n");
> > +		goto error_iio_device_register;
> > +	}
> > +
> >  	ret = iio_device_register(indio_dev);
> >  	if (ret) {
> >  		dev_err(&pdev->dev, "Couldn't register the device.\n");
> > -		goto error_iio_device_register;
> > +		goto error_adc_buffer_init;
> >  	}
> >  
> >  	return 0;
> >  
> > -
> > +error_adc_buffer_init:
> > +	iio_triggered_buffer_cleanup(indio_dev);
> >  error_iio_device_register:
> >  	clk_disable_unprepare(info->clk);
> >  error_adc_clk_enable:
> > @@ -829,6 +916,7 @@ static int vf610_adc_remove(struct platform_device *pdev)
> >  	struct vf610_adc *info = iio_priv(indio_dev);
> >  
> >  	iio_device_unregister(indio_dev);
> > +	iio_triggered_buffer_cleanup(indio_dev);
> >  	regulator_disable(info->vref);
> >  	clk_disable_unprepare(info->clk);
> >  
> > 
> 


From m-karicheri2 at ti.com  Mon Aug 17 07:09:15 2015
From: m-karicheri2 at ti.com (Murali Karicheri)
Date: Mon, 17 Aug 2015 10:09:15 -0400
Subject: [PATCH] ARM: keystone: add a work around to handle asynchronous
 external abort
In-Reply-To: <20150814215658.GB7557@n2100.arm.linux.org.uk>
References: <1439320409-20084-1-git-send-email-m-karicheri2@ti.com>
 <55CDF579.4050408@ti.com> <20150814140934.GX7557@n2100.arm.linux.org.uk>
 <1439562059.13210.61.camel@pengutronix.de> <55CE63BD.2060107@ti.com>
 <20150814215658.GB7557@n2100.arm.linux.org.uk>
Message-ID: <55D1EB0B.8020607@ti.com>

On 08/14/2015 05:56 PM, Russell King - ARM Linux wrote:
> On Fri, Aug 14, 2015 at 05:55:09PM -0400, Murali Karicheri wrote:
>> On 08/14/2015 10:20 AM, Lucas Stach wrote:
>>> Hi Russell,
>>>
>>> Am Freitag, den 14.08.2015, 15:09 +0100 schrieb Russell King - ARM
>>> Linux:
>>>
>>> [...]
>>>
>>>>
>>>> What causes the abort?  We shouldn't be adding hacks like this to the
>>>> kernel without having the full picture...
>>>>
>>>
>>> some of the issues with tracking down such imprecise external aborts are
>>> due to the fact that we only enable the signaling of those aborts on
>>> entering the user-space. So the first schedule() crashes on the previous
>>> dangling abort.
>>>
>>> I'm carrying this patch locally to enable imprecise aborts much earlier
>>> in the boot process. I think it has already been on the list some times,
>>> but apparently it has fallen through the cracks. If you agree that this
>>> is the right thing to do I can do a proper repost.
>> Lucas,
>>
>> Would you mind sharing the code? Does that help in root causing where it
>> actually happens? I have spend considerable time debugging this, but so far
>> not successful.
>
> If you look below, Lucas provided the patch.
Oops! Thanks

Murali

>
>>
>> Murali
>>>
>>> Regards,
>>> Lucas
>>>
>>> ---------------------->8---------------------------------------------
>>> >From bb9117d94cc2f1061dc364f42c446ccd9191e869 Mon Sep 17 00:00:00 2001
>>> From: Lucas Stach <l.stach at pengutronix.de>
>>> Date: Thu, 19 Feb 2015 18:12:50 +0100
>>> Subject: [PATCH] ARM: Add imprecise abort enable/disable macro
>>>
>>> This patch adds imprecise abort enable/disable macros.
>>> It also enables imprecise aborts when starting kernel.
>>>
>>> Changes in v2:
>>> Only ARMv6 and later have CPSR.A bit. On earlier CPUs,
>>> and ARMv7M this should be a no-op.
>>>
>>> Signed-off-by: Fabrice Gasnier <fabrice.gasnier at st.com>
>>> Signed-off-by: Lucas Stach <l.stach at pengutronix.de>
>>> ---
>>> lst: rebased on v3.19
>>> ---
>>>   arch/arm/include/asm/irqflags.h | 10 ++++++++++
>>>   arch/arm/kernel/smp.c           |  1 +
>>>   arch/arm/kernel/traps.c         |  4 ++++
>>>   3 files changed, 15 insertions(+)
>>>
>>> diff --git a/arch/arm/include/asm/irqflags.h
>>> b/arch/arm/include/asm/irqflags.h
>>> index 3b763d6652a0..8301f875564e 100644
>>> --- a/arch/arm/include/asm/irqflags.h
>>> +++ b/arch/arm/include/asm/irqflags.h
>>> @@ -51,6 +51,14 @@ static inline void arch_local_irq_disable(void)
>>>
>>>   #define local_fiq_enable()  __asm__("cpsie f   @ __stf" : : : "memory",
>>> "cc")
>>>   #define local_fiq_disable() __asm__("cpsid f   @ __clf" : : : "memory",
>>> "cc")
>>> +
>>> +#ifndef CONFIG_CPU_V7M
>>> +#define local_abt_enable()  __asm__("cpsie a   @ __sta" : : : "memory",
>>> "cc")
>>> +#define local_abt_disable() __asm__("cpsid a   @ __cla" : : : "memory",
>>> "cc")
>>> +#else
>>> +#define local_abt_enable()     do { } while (0)
>>> +#define local_abt_disable()    do { } while (0)
>>> +#endif
>>>   #else
>>>
>>>   /*
>>> @@ -130,6 +138,8 @@ static inline void arch_local_irq_disable(void)
>>>          : "memory", "cc");                                      \
>>>          })
>>>
>>> +#define local_abt_enable()     do { } while (0)
>>> +#define local_abt_disable()    do { } while (0)
>>>   #endif
>>>
>>>   /*
>>> diff --git a/arch/arm/kernel/smp.c b/arch/arm/kernel/smp.c
>>> index 86ef244c5a24..7b6b93cabef4 100644
>>> --- a/arch/arm/kernel/smp.c
>>> +++ b/arch/arm/kernel/smp.c
>>> @@ -378,6 +378,7 @@ asmlinkage void secondary_start_kernel(void)
>>>
>>>          local_irq_enable();
>>>          local_fiq_enable();
>>> +       local_abt_enable();
>>>
>>>          /*
>>>           * OK, it's off to the idle thread for us
>>> diff --git a/arch/arm/kernel/traps.c b/arch/arm/kernel/traps.c
>>> index 788e23fe64d8..466726ba9bdb 100644
>>> --- a/arch/arm/kernel/traps.c
>>> +++ b/arch/arm/kernel/traps.c
>>> @@ -881,6 +881,10 @@ void __init early_trap_init(void *vectors_base)
>>>
>>>          flush_icache_range(vectors, vectors + PAGE_SIZE * 2);
>>>          modify_domain(DOMAIN_USER, DOMAIN_CLIENT);
>>> +
>>> +       /* Enable imprecise aborts */
>>> +       local_abt_enable();
>>> +
>>>   #else /* ifndef CONFIG_CPU_V7M */
>>>          /*
>>>           * on V7-M there is no need to copy the vector table to a
>>> dedicated
>>>
>>
>>
>> --
>> Murali Karicheri
>> Linux Kernel, Keystone
>


-- 
Murali Karicheri
Linux Kernel, Keystone


From yingjoe.chen at mediatek.com  Mon Aug 17 07:10:02 2015
From: yingjoe.chen at mediatek.com (Yingjoe Chen)
Date: Mon, 17 Aug 2015 22:10:02 +0800
Subject: [PATCH v2 1/5] clocksource: mediatek: do not enable GPT_CLK_EVT
 when setup
In-Reply-To: <55CC56C4.8080201@linaro.org>
References: <CAGS+omD8k_Cfxv3bYyjmjtLbiavo-WmJPn0Z-CBhN_nnv65Tag@mail.gmail.com>
 <1437552878-3684-1-git-send-email-yingjoe.chen@mediatek.com>
 <55CC56C4.8080201@linaro.org>
Message-ID: <1439820602.3414.12.camel@mtksdaap41>

On Thu, 2015-08-13 at 10:35 +0200, Daniel Lezcano wrote:
> On 07/22/2015 10:14 AM, Yingjoe Chen wrote:
> > Spurious mtk timer interrupt is noticed at boot and cause kernel
> > crash. It seems if GPT is enabled, it will latch irq status even
> > when its IRQ is disabled. When irq is enabled afterward, we see
> > spurious interrupt.
> > Change init flow to only enable GPT_CLK_SRC at mtk_timer_init.
> >
> > Acked-by: Matthias Brugger <matthias.bgg at gmail.com>
> > Reviewed-by: Daniel Kurtz <djkurtz at chromium.org>
> > Signed-off-by: Yingjoe Chen <yingjoe.chen at mediatek.com>
> > ---
> >
> > Update to my patch [1], added __init as Daniel suggest. This is the
> > only patch that need to change in that series, so I only sent this one.
> >
> > http://lists.infradead.org/pipermail/linux-mediatek/2015-July/001545.html
> >
> >   drivers/clocksource/mtk_timer.c | 16 ++++++++++------
> >   1 file changed, 10 insertions(+), 6 deletions(-)
> >
> > diff --git a/drivers/clocksource/mtk_timer.c b/drivers/clocksource/mtk_timer.c
> > index 68ab423..2ba5b66 100644
> > --- a/drivers/clocksource/mtk_timer.c
> > +++ b/drivers/clocksource/mtk_timer.c
> > @@ -156,9 +156,11 @@ static void mtk_timer_global_reset(struct mtk_clock_event_device *evt)
> >   	writel(0x3f, evt->gpt_base + GPT_IRQ_ACK_REG);
> >   }
> >
> > -static void
> > -mtk_timer_setup(struct mtk_clock_event_device *evt, u8 timer, u8 option)
> > +static void __init mtk_timer_setup(struct mtk_clock_event_device *evt,
> > +				   u8 timer, u8 option, bool enable)
> >   {
> > +	u32 val;
> > +
> >   	writel(TIMER_CTRL_CLEAR | TIMER_CTRL_DISABLE,
> >   		evt->gpt_base + TIMER_CTRL_REG(timer));
> >
> > @@ -167,8 +169,10 @@ mtk_timer_setup(struct mtk_clock_event_device *evt, u8 timer, u8 option)
> >
> >   	writel(0x0, evt->gpt_base + TIMER_CMP_REG(timer));
> >
> > -	writel(TIMER_CTRL_OP(option) | TIMER_CTRL_ENABLE,
> > -			evt->gpt_base + TIMER_CTRL_REG(timer));
> > +	val = TIMER_CTRL_OP(option);
> > +	if (enable)
> > +		val |= TIMER_CTRL_ENABLE;
> > +	writel(val, evt->gpt_base + TIMER_CTRL_REG(timer));
> 
> Instead of the 'enable' new option, I prefer a test with 'timer' with a 
> comment:
> 
> 	/*
> 	 * the timer hw is broken in that way ... bla bla, so we only
> 	 * enable the clocksource ...
> 	 */
> 	if (timer == GPT_CLK_SRC)
> 		val |= TIMER_CTRL_ENABLE;

Hi Daniel,

Thanks for your review.
Since this bug happens to anyone using interrupt, I'm not sure checking
timer and only enable it for GPT_CLK_SRC is easier to read. Anyway, I'll
change to this in next version.

> That said, can you have a look at commit 1096be08 ?
> "clockevents: sun5i: Fix setup_irq init sequence"
> 
> first and check if moving the interrupt request after the 
> clockevents_config_and_register could fix your issue.

I've tested this before, see:

http://lists.infradead.org/pipermail/linux-mediatek/2015-May/000539.html
http://lists.infradead.org/pipermail/linux-mediatek/2015-May/000551.html

Joe.C




From m-karicheri2 at ti.com  Mon Aug 17 07:11:11 2015
From: m-karicheri2 at ti.com (Murali Karicheri)
Date: Mon, 17 Aug 2015 10:11:11 -0400
Subject: [PATCH] ARM: keystone: add a work around to handle asynchronous
 external abort
In-Reply-To: <1439561519.13210.55.camel@pengutronix.de>
References: <1439320409-20084-1-git-send-email-m-karicheri2@ti.com>	
 <55CDF579.4050408@ti.com> <1439561519.13210.55.camel@pengutronix.de>
Message-ID: <55D1EB7F.4030905@ti.com>

On 08/14/2015 10:11 AM, Lucas Stach wrote:
> Am Freitag, den 14.08.2015, 10:04 -0400 schrieb Murali Karicheri:
>> On 08/11/2015 03:13 PM, Murali Karicheri wrote:
>>> Currently on some devices, an asynchronous external abort exception
>>> happens during boot up when exception handlers are enabled in kernel
>>> before switching to user space. This patch adds a workaround to handle
>>> this once during boot. Many customers are already using this
>>> with out any issues and is required to workaround the above issue.
>>>
>>> Signed-off-by: Murali Karicheri <m-karicheri2 at ti.com>
>>> ---
>>>    arch/arm/mach-keystone/keystone.c | 26 ++++++++++++++++++++++++++
>>>    1 file changed, 26 insertions(+)
>>>
>>> diff --git a/arch/arm/mach-keystone/keystone.c b/arch/arm/mach-keystone/keystone.c
>>> index e2880105..c1d0fe5 100644
>>> --- a/arch/arm/mach-keystone/keystone.c
>>> +++ b/arch/arm/mach-keystone/keystone.c
>>> @@ -15,6 +15,7 @@
>>>    #include <linux/of_platform.h>
>>>    #include <linux/of_address.h>
>>>    #include <linux/memblock.h>
>>> +#include <linux/signal.h>
>>>
>>>    #include <asm/setup.h>
>>>    #include <asm/mach/map.h>
>>> @@ -52,6 +53,24 @@ static struct notifier_block platform_nb = {
>>>    	.notifier_call = keystone_platform_notifier,
>>>    };
>>>
>>> +static bool ignore_first = true;
>>> +static int keystone_async_ext_abort_fault(unsigned long addr, unsigned int fsr,
>>> +					  struct pt_regs *regs)
>>> +{
>>> +	/*
>>> +	 * if first time, ignore this as this is a asynchronous external abort
>>> +	 * happening only some devices that couldn't be root caused and we add
>>> +	 * this work around to handle this first time.
>>> +	 */
>>> +	if (ignore_first) {
>>> +		ignore_first = false;
>>> +		return 0;
>>> +	}
>>> +
>>> +	/* Subsequent ones should be handled as fault */
>>> +	return 1;
>>> +}
>>> +
>>>    static void __init keystone_init(void)
>>>    {
>>>    	if (PHYS_OFFSET >= KEYSTONE_HIGH_PHYS_START) {
>>> @@ -61,6 +80,13 @@ static void __init keystone_init(void)
>>>    	}
>>>    	keystone_pm_runtime_init();
>>>    	of_platform_populate(NULL, of_default_bus_match_table, NULL, NULL);
>>> +
>>> +	/*
>>> +	 * Add a one time exception handler to catch asynchronous external
>>> +	 * abort
>>> +	 */
>>> +	hook_fault_code(17, keystone_async_ext_abort_fault, SIGBUS, 0,
>>> +			"async external abort handler");
>>>    }
>>>
>>>    static phys_addr_t keystone_virt_to_idmap(unsigned long x)
>>>
>> Can this be applied if it looks good?
>>
> The keystone PCIe host driver already hooks the same fault code. Those
> hooks are no chain, but a simple pointer, so one of those handlers is
> going to loose out.
>
> This likely isn't what you intended.
You are right. I will try to debug this further based on your patch and 
as per RMK's suggestion.

Thanks and regards,

Murali
>
> Regards,
> Lucas
>


-- 
Murali Karicheri
Linux Kernel, Keystone


From alim.akhtar at gmail.com  Mon Aug 17 07:42:17 2015
From: alim.akhtar at gmail.com (Alim Akhtar)
Date: Mon, 17 Aug 2015 20:12:17 +0530
Subject: [PATCH 2/3] mmc: dw_mmc: simplify the SDMMC_CLKEN_LOW_PWR logic
In-Reply-To: <55D1C4CD.4040200@samsung.com>
References: <cover.1439381423.git.hramrach@gmail.com>
 <3d03bfe2c18789eefa038018467c9c63c94ae4a2.1439381423.git.hramrach@gmail.com>
 <55D13F07.70309@samsung.com>
 <CAOMqctQ8DHj6qPg8zR93OGRHXAZDd0yUmG_J8Vz7dGFuDpCgRQ@mail.gmail.com>
 <55D1C4CD.4040200@samsung.com>
Message-ID: <CAGOxZ51oHoX+zQSO8tRp8V5RUmDg8CAnM9HO5FQ5h6JeCy=1og@mail.gmail.com>

HI

On Mon, Aug 17, 2015 at 4:56 PM, Jaehoon Chung <jh80.chung at samsung.com> wrote:
> On 08/17/2015 02:52 PM, Michal Suchanek wrote:
>> Hello,
>>
>> On 17 August 2015 at 03:55, Jaehoon Chung <jh80.chung at samsung.com> wrote:
>>> Hi, Michal.
>>>
>>> On 08/12/2015 09:23 PM, Michal Suchanek wrote:
>>>> The driver has open-coded test for SDIO cards. Use the mmc core provided
>>>> MMC_QUIRK_BROKEN_CLK_GATING flag instead.
>>>
>>> Did you use the clock-gating for SDIO cards?
>>> Doesn't MMC_CAP_SDIO_IRQ bit set? Which case is broken?
>>> Could you explain to me more?
>>
>> The core flag for disabling power saving is MMC_QUIRK_BROKEN_CLK_GATING.
>
> I understood your intention. And i read the comment into mmc/core/quirks.c
> I will test SDIO card with this patch. Thanks.
>
When you test, please check if SDIO IRQ still works, we need to put
dw_mmc in low_power mode otherwise SDIO IRQ will be not be generated
by dw_mmc host controller.

> Best Regards,
> Jaehoon Chung
>
>>
>> It may coincide with MMC_CAP_SDIO_IRQ but that's different flag for
>> different purpose.
>>
>> MMC_QUIRK_BROKEN_CLK_GATING is currently set for all SDIO cards except
>> for cards on a whitelist.
>>
>> I don't know any particular SDIO card that has problems when the clock
>> is off and does not use an IRQ.
>>
>> Thanks
>>
>> Michal
>>
>>>
>>> Best Regards,
>>> Jaehoon Chung
>>>
>>>>
>>>> As a bonus this may enable clock gating on SDIO cards that are known to
>>>> work with it.
>>>>
>>>> Signed-off-by: Michal Suchanek <hramrach at gmail.com>
>>>> ---
>>>>  drivers/mmc/host/dw_mmc.c | 33 +++++++++++++++------------------
>>>>  1 file changed, 15 insertions(+), 18 deletions(-)
>>>>
>>>> diff --git a/drivers/mmc/host/dw_mmc.c b/drivers/mmc/host/dw_mmc.c
>>>> index 40e9d8e..3bc9fd7 100644
>>>> --- a/drivers/mmc/host/dw_mmc.c
>>>> +++ b/drivers/mmc/host/dw_mmc.c
>>>> @@ -1335,27 +1335,24 @@ static void dw_mci_init_card(struct mmc_host *mmc, struct mmc_card *card)
>>>>        * description of the CLKENA register we should disable low power mode
>>>>        * for SDIO cards if we need SDIO interrupts to work.
>>>>        */
>>>> -     if (mmc->caps & MMC_CAP_SDIO_IRQ) {
>>>> -             const u32 clken_low_pwr = SDMMC_CLKEN_LOW_PWR << slot->id;
>>>> -             u32 clk_en_a_old;
>>>> -             u32 clk_en_a;
>>>> +     const u32 clken_low_pwr = SDMMC_CLKEN_LOW_PWR << slot->id;
>>>> +     u32 clk_en_a_old;
>>>> +     u32 clk_en_a;
>>>>
>>>> -             clk_en_a_old = mci_readl(host, CLKENA);
>>>> +     clk_en_a_old = mci_readl(host, CLKENA);
>>>>
>>>> -             if (card->type == MMC_TYPE_SDIO ||
>>>> -                 card->type == MMC_TYPE_SD_COMBO) {
>>>> -                     set_bit(DW_MMC_CARD_NO_LOW_PWR, &slot->flags);
>>>> -                     clk_en_a = clk_en_a_old & ~clken_low_pwr;
>>>> -             } else {
>>>> -                     clear_bit(DW_MMC_CARD_NO_LOW_PWR, &slot->flags);
>>>> -                     clk_en_a = clk_en_a_old | clken_low_pwr;
>>>> -             }
>>>> +     if (card->quirks & MMC_QUIRK_BROKEN_CLK_GATING) {
>>>> +             set_bit(DW_MMC_CARD_NO_LOW_PWR, &slot->flags);
>>>> +             clk_en_a = clk_en_a_old & ~clken_low_pwr;
>>>> +     } else {
>>>> +             clear_bit(DW_MMC_CARD_NO_LOW_PWR, &slot->flags);
>>>> +             clk_en_a = clk_en_a_old | clken_low_pwr;
>>>> +     }
>>>>
>>>> -             if (clk_en_a != clk_en_a_old) {
>>>> -                     mci_writel(host, CLKENA, clk_en_a);
>>>> -                     mci_send_cmd(slot, SDMMC_CMD_UPD_CLK |
>>>> -                                  SDMMC_CMD_PRV_DAT_WAIT, 0);
>>>> -             }
>>>> +     if (clk_en_a != clk_en_a_old) {
>>>> +             mci_writel(host, CLKENA, clk_en_a);
>>>> +             mci_send_cmd(slot, SDMMC_CMD_UPD_CLK |
>>>> +                             SDMMC_CMD_PRV_DAT_WAIT, 0);
>>>>       }
>>>>  }
>>>>
>>>>
>>>
>> --
>> To unsubscribe from this list: send the line "unsubscribe linux-mmc" in
>> the body of a message to majordomo at vger.kernel.org
>> More majordomo info at  http://vger.kernel.org/majordomo-info.html
>>
>
> --
> To unsubscribe from this list: send the line "unsubscribe linux-mmc" in
> the body of a message to majordomo at vger.kernel.org
> More majordomo info at  http://vger.kernel.org/majordomo-info.html



-- 
Regards,
Alim


From mchehab at osg.samsung.com  Mon Aug 17 07:52:42 2015
From: mchehab at osg.samsung.com (Mauro Carvalho Chehab)
Date: Mon, 17 Aug 2015 11:52:42 -0300
Subject: [PATCH v2 05/11] ARM: DT: STi: STiH407: Add c8sectpfe LinuxDVB
 DT node.
In-Reply-To: <1438276141-16902-6-git-send-email-peter.griffin@linaro.org>
References: <1438276141-16902-1-git-send-email-peter.griffin@linaro.org>
 <1438276141-16902-6-git-send-email-peter.griffin@linaro.org>
Message-ID: <20150817115242.4ae9a51e@recife.lan>

Em Thu, 30 Jul 2015 18:08:55 +0100
Peter Griffin <peter.griffin at linaro.org> escreveu:

> This patch adds in the required DT node for the c8sectpfe
> Linux DVB demux driver which allows the tsin channels
> to be used on an upstream kernel.
> 
> Signed-off-by: Peter Griffin <peter.griffin at linaro.org>
> ---
>  arch/arm/boot/dts/stihxxx-b2120.dtsi | 38 ++++++++++++++++++++++++++++++++++++
>  1 file changed, 38 insertions(+)
> 
> diff --git a/arch/arm/boot/dts/stihxxx-b2120.dtsi b/arch/arm/boot/dts/stihxxx-b2120.dtsi
> index 62994ae..1bc018e 100644
> --- a/arch/arm/boot/dts/stihxxx-b2120.dtsi
> +++ b/arch/arm/boot/dts/stihxxx-b2120.dtsi
> @@ -6,6 +6,10 @@
>   * it under the terms of the GNU General Public License version 2 as
>   * published by the Free Software Foundation.
>   */
> +
> +#include <dt-bindings/clock/stih407-clks.h>
> +#include <dt-bindings/media/c8sectpfe.h>
> +
>  / {
>  	soc {
>  		sbc_serial0: serial at 9530000 {
> @@ -85,5 +89,39 @@
>  			status = "okay";
>  		};
>  
> +		c8sectpfe at 08a20000 {
> +			compatible = "st,stih407-c8sectpfe";
> +			status = "okay";
> +			reg = <0x08a20000 0x10000>, <0x08a00000 0x4000>;
> +			reg-names = "c8sectpfe", "c8sectpfe-ram";
> +
> +			interrupts = <0 34 0>, <0 35 0>;
> +			interrupt-names = "c8sectpfe-error-irq",
> +					  "c8sectpfe-idle-irq";
> +
> +			pinctrl-names	= "tsin0-serial", "tsin0-parallel",
> +					  "tsin3-serial", "tsin4-serial",
> +					  "tsin5-serial";
> +
> +			pinctrl-0	= <&pinctrl_tsin0_serial>;
> +			pinctrl-1	= <&pinctrl_tsin0_parallel>;
> +			pinctrl-2	= <&pinctrl_tsin3_serial>;
> +			pinctrl-3	= <&pinctrl_tsin4_serial_alt3>;
> +			pinctrl-4	= <&pinctrl_tsin5_serial_alt1>;
> +
> +			clocks = <&clk_s_c0_flexgen CLK_PROC_STFE>;
> +			clock-names = "c8sectpfe";
> +
> +			/* tsin0 is TSA on NIMA */
> +			tsin0: port at 0 {
> +
> +				tsin-num = <0>;
> +				serial-not-parallel;
> +				i2c-bus = <&ssc2>;

There's no ssc2 defined at the device tree.

I'll revert this patch and mark the driver as broken until this gets
fixed.

Regards,
Mauro


From hramrach at gmail.com  Mon Aug 17 07:55:46 2015
From: hramrach at gmail.com (Michal Suchanek)
Date: Mon, 17 Aug 2015 16:55:46 +0200
Subject: [PATCH 2/3] mmc: dw_mmc: simplify the SDMMC_CLKEN_LOW_PWR logic
In-Reply-To: <CAGOxZ51oHoX+zQSO8tRp8V5RUmDg8CAnM9HO5FQ5h6JeCy=1og@mail.gmail.com>
References: <cover.1439381423.git.hramrach@gmail.com>
 <3d03bfe2c18789eefa038018467c9c63c94ae4a2.1439381423.git.hramrach@gmail.com>
 <55D13F07.70309@samsung.com>
 <CAOMqctQ8DHj6qPg8zR93OGRHXAZDd0yUmG_J8Vz7dGFuDpCgRQ@mail.gmail.com>
 <55D1C4CD.4040200@samsung.com>
 <CAGOxZ51oHoX+zQSO8tRp8V5RUmDg8CAnM9HO5FQ5h6JeCy=1og@mail.gmail.com>
Message-ID: <CAOMqctQ_gA=QxRVFQ8L=q7kBX3GROvz9mnHGu2yo1VrBO1Le6w@mail.gmail.com>

 Hello,

On 17 August 2015 at 16:42, Alim Akhtar <alim.akhtar at gmail.com> wrote:
> HI
>
> On Mon, Aug 17, 2015 at 4:56 PM, Jaehoon Chung <jh80.chung at samsung.com> wrote:
>> On 08/17/2015 02:52 PM, Michal Suchanek wrote:
>>> Hello,
>>>
>>> On 17 August 2015 at 03:55, Jaehoon Chung <jh80.chung at samsung.com> wrote:
>>>> Hi, Michal.
>>>>
>>>> On 08/12/2015 09:23 PM, Michal Suchanek wrote:
>>>>> The driver has open-coded test for SDIO cards. Use the mmc core provided
>>>>> MMC_QUIRK_BROKEN_CLK_GATING flag instead.
>>>>
>>>> Did you use the clock-gating for SDIO cards?
>>>> Doesn't MMC_CAP_SDIO_IRQ bit set? Which case is broken?
>>>> Could you explain to me more?
>>>
>>> The core flag for disabling power saving is MMC_QUIRK_BROKEN_CLK_GATING.
>>
>> I understood your intention. And i read the comment into mmc/core/quirks.c
>> I will test SDIO card with this patch. Thanks.
>>
> When you test, please check if SDIO IRQ still works, we need to put
> dw_mmc in low_power mode otherwise SDIO IRQ will be not be generated
> by dw_mmc host controller.
>

As far as I understand the logic which is removed in this patch and
the core logic which replaces it is the same -  low power by means of
clock gating is *not* enabled for SDIO cards in either case.

The original code also checks for SDIO IRQ and disables clock gating
regardless of card type which is probably redundant. If not it should
be fixed in mmc core.

My recent kernel builds which I run on a system with mwifiex card
probably include this patch.

Thanks

Michal


From mathias.nyman at linux.intel.com  Mon Aug 17 08:07:35 2015
From: mathias.nyman at linux.intel.com (Mathias Nyman)
Date: Mon, 17 Aug 2015 18:07:35 +0300
Subject: [PATCH v5 4/5] xhci: mediatek: support MTK xHCI host controller
In-Reply-To: <1438950644-27290-5-git-send-email-chunfeng.yun@mediatek.com>
References: <1438950644-27290-1-git-send-email-chunfeng.yun@mediatek.com>
 <1438950644-27290-5-git-send-email-chunfeng.yun@mediatek.com>
Message-ID: <55D1F8B7.9060306@linux.intel.com>

Hi

On 07.08.2015 15:30, Chunfeng Yun wrote:
> MTK xhci host controller defines some extra SW scheduling
> parameters for HW to minimize the scheduling effort for
> synchronous and interrupt endpoints. The parameters are
> put into reseved DWs of slot context and endpoint context
>
>

...

> + * The TD size is the number of max packet sized packets remaining in the TD
> + * (including this TRB), right shifted by 10.
> + * It must fit in bits 21:17, so it can't be bigger than 31.
> + */
> +u32 xhci_mtk_td_remainder_quirk(unsigned int td_running_total,
> +	unsigned trb_buffer_length, struct urb *urb)
> +{
> +	u32 max = 31;
> +	int remainder, td_packet_count, packet_transferred;
> +	unsigned int td_transfer_size = urb->transfer_buffer_length;
> +	unsigned int maxp;
> +
> +	maxp = GET_MAX_PACKET(usb_endpoint_maxp(&urb->ep->desc));
> +
> +	/* 0 for the last TRB */
> +	if (td_running_total + trb_buffer_length == td_transfer_size)
> +		return 0;
> +
> +	packet_transferred = td_running_total / maxp;
> +	td_packet_count = DIV_ROUND_UP(td_transfer_size, maxp);
> +	remainder = td_packet_count - packet_transferred;
> +
> +	if (remainder > max)
> +		return max << 17;
> +	else
> +		return remainder << 17;
> +}

I started looking at this xhci_mtk_td_remainder() function, one
of the places this patch touches the existing xhci code.

The remainder functions in xhci are already bit too messy, and
adding one more function which does almost the same thing makes
it even messier.

For example queuing a bulk transfer will end up like this:

>   		/* Set the TRB length, TD size, and interrupter fields. */
>   		if (xhci->hci_version < 0x100) {
> -			remainder = xhci_td_remainder(
> +			if (xhci->quirks & XHCI_MTK_HOST) {
> +				remainder = xhci_mtk_td_remainder_quirk(
> +					running_total, trb_buff_len, urb);
> +			} else {
> +				remainder = xhci_td_remainder(
>   					urb->transfer_buffer_length -
>   					running_total);
> +			}
>   		} else {
>   			remainder = xhci_v1_0_td_remainder(running_total,
>   					trb_buff_len, total_packet_count, urb,

and similar for isoc and control transfers.

I'll see if I can simplify the existing remainder calculations into one function, then it should
be enough to just add something like this into it:

if (xhci->quirks & XHCI_MTK_HOST)
	trb_buff_len = 0;
  	
This way we can skip all the extra hassle that comes with a new exported quirk function

Is the Mediatek xhci really a xHCI 0.96 or older controller? (hci_version < 0x100)
Not a xHCI 1.0 or 1.1 ?

-Mathias


From Liviu.Dudau at arm.com  Mon Aug 17 08:15:47 2015
From: Liviu.Dudau at arm.com (Liviu Dudau)
Date: Mon, 17 Aug 2015 16:15:47 +0100
Subject: [PATCH 2/4] drm: Add support for ARM's HDLCD controller.
In-Reply-To: <CACvgo537C6SRfhMTNoE4cSLJukcXuKLvt1TRykynX--ybEhmaQ@mail.gmail.com>
References: <1438784892-27888-1-git-send-email-Liviu.Dudau@arm.com>
 <1438784892-27888-3-git-send-email-Liviu.Dudau@arm.com>
 <CACvgo537C6SRfhMTNoE4cSLJukcXuKLvt1TRykynX--ybEhmaQ@mail.gmail.com>
Message-ID: <20150817151547.GA1020@e106497-lin.cambridge.arm.com>

On Sun, Aug 16, 2015 at 09:56:33AM +0100, Emil Velikov wrote:
> Hi Liviu,

Hi Emil,

> 
> On 5 August 2015 at 15:28, Liviu Dudau <Liviu.Dudau at arm.com> wrote:
> > The HDLCD controller is a display controller that supports resolutions
> > up to 4096x4096 pixels. It is present on various development boards
> > produced by ARM Ltd and emulated by the latest Fast Models from the
> > company.
> >
> I believe there is a unofficial requirement(?) for new drm drivers to
> use atomic modesetting. Not 100% sure on this one though. The
> following drivers: tegra, msm, rcar-du, i915, and Daniel's blog [1]
> [2] cat provide some information on the topic.

I am also interested to know if this is a requirement or not.
Thanks for the pointers, I will review them again to see if I did miss
anything. I remember reading them at the beginning of the year but probably
the Christmas haze did not clear enough when I did.

> 
> The driver seems to has has a bit of dead code guarded by
> HDLCD_*_UNDERRUN. Perhaps these macros should become build or runtime
> switch(es) ?

There is a comment in hdlcd_drv.h explaining what HDLCD_SHOW_UNDERRUN can
be used for. As for HDLCD_COUNT_BUFFERUNDERRUNS, you are right, it's dead
code from the earlier debugging code that got removed before submission.
I will correct that.

> 
> Most DRM drivers do not threat dma, bus_error, vsync and/or underrun
> interrupts as debug functionality. They are of limited use in this
> driver, presently, yet the CONFIG_DEBUG_FS guard seems a bit strange
> imho.

The HDLCD device has only 1 interrupt that can fire and there is no other
way to show the reason for the interrupt in the driver. It was useful when
debugging underruns and/or vsync issues so I thought it might be useful
to keep around. Putting it the other way: if you are going to use this device
and the image is not completely rendered I would not be able to give you
support to figure out what went wrong without this debugging information.
With this in place I can tell the difference between a busy system vs one
where the interrupt latency is large.

Best regards,
Liviu

> 
> Cheers,
> Emil
> 
> [1] http://blog.ffwll.ch/2014/11/atomic-modeset-support-for-kms-drivers.html
> [2] http://blog.ffwll.ch/2015/01/update-for-atomic-display-updates.html
> 

-- 
====================
| I would like to |
| fix the world,  |
| but they're not |
| giving me the   |
 \ source code!  /
  ---------------
    ?\_(?)_/?



From eric.auger at linaro.org  Mon Aug 17 08:17:12 2015
From: eric.auger at linaro.org (Eric Auger)
Date: Mon, 17 Aug 2015 17:17:12 +0200
Subject: [PATCH v3 01/10] VFIO: platform: registration of a dummy IRQ
 bypass producer
In-Reply-To: <1439405770.4023.526.camel@redhat.com>
References: <1439212864-12954-1-git-send-email-eric.auger@linaro.org>	
 <1439212864-12954-2-git-send-email-eric.auger@linaro.org>
 <1439405770.4023.526.camel@redhat.com>
Message-ID: <55D1FAF8.9000700@linaro.org>

Hi Alex,
On 08/12/2015 08:56 PM, Alex Williamson wrote:
> On Mon, 2015-08-10 at 15:20 +0200, Eric Auger wrote:
>> Register a dummy producer with void callbacks
>>
>> Signed-off-by: Eric Auger <eric.auger at linaro.org>
>>
>> ---
>>
>> v2 -> v3:
>> - rename vfio_platform_irq_bypass_resume into *_start
>> ---
>>  drivers/vfio/platform/vfio_platform_irq.c     | 32 +++++++++++++++++++++++++++
>>  drivers/vfio/platform/vfio_platform_private.h |  2 ++
>>  2 files changed, 34 insertions(+)
>>
>> diff --git a/drivers/vfio/platform/vfio_platform_irq.c b/drivers/vfio/platform/vfio_platform_irq.c
>> index 88bba57..b5cb8c7 100644
>> --- a/drivers/vfio/platform/vfio_platform_irq.c
>> +++ b/drivers/vfio/platform/vfio_platform_irq.c
>> @@ -20,6 +20,7 @@
>>  #include <linux/types.h>
>>  #include <linux/vfio.h>
>>  #include <linux/irq.h>
>> +#include <linux/irqbypass.h>
>>  
>>  #include "vfio_platform_private.h"
>>  
>> @@ -177,6 +178,27 @@ static irqreturn_t vfio_irq_handler(int irq, void *dev_id)
>>  	return IRQ_HANDLED;
>>  }
>>  
>> +static void vfio_platform_irq_bypass_stop(struct irq_bypass_producer *prod)
>> +{
>> +}
>> +
>> +static void vfio_platform_irq_bypass_start(struct irq_bypass_producer *prod)
>> +{
>> +}
>> +
>> +static int vfio_platform_irq_bypass_add_consumer(
>> +			struct irq_bypass_producer *prod,
>> +			struct irq_bypass_consumer *cons)
>> +{
>> +	return 0;
>> +}
>> +
>> +static void vfio_platform_irq_bypass_del_consumer(
>> +			struct irq_bypass_producer *prod,
>> +			struct irq_bypass_consumer *cons)
>> +{
>> +}
>> +
>>  static int vfio_set_trigger(struct vfio_platform_device *vdev, int index,
>>  			    int fd, irq_handler_t handler)
>>  {
>> @@ -186,6 +208,7 @@ static int vfio_set_trigger(struct vfio_platform_device *vdev, int index,
>>  
>>  	if (irq->trigger) {
>>  		free_irq(irq->hwirq, irq);
>> +		irq_bypass_unregister_producer(&irq->producer);
>>  		kfree(irq->name);
>>  		eventfd_ctx_put(irq->trigger);
>>  		irq->trigger = NULL;
>> @@ -216,6 +239,15 @@ static int vfio_set_trigger(struct vfio_platform_device *vdev, int index,
>>  		return ret;
>>  	}
>>  
>> +	irq->producer.token = (void *)trigger;
>> +	irq->producer.irq = irq->hwirq;
>> +	irq->producer.add_consumer = vfio_platform_irq_bypass_add_consumer;
>> +	irq->producer.del_consumer = vfio_platform_irq_bypass_del_consumer;
>> +	irq->producer.stop = vfio_platform_irq_bypass_stop;
>> +	irq->producer.start = vfio_platform_irq_bypass_start;
>> +	ret = irq_bypass_register_producer(&irq->producer);
>> +	WARN_ON(ret);
> 
> For what purpose?
Yes. I will replace by a simple pr_info as done in eventfd.c.

Best Regards

Eric
> 
>> +
>>  	if (!irq->masked)
>>  		enable_irq(irq->hwirq);
>>  
>> diff --git a/drivers/vfio/platform/vfio_platform_private.h b/drivers/vfio/platform/vfio_platform_private.h
>> index 1c9b3d5..1d2d4d6 100644
>> --- a/drivers/vfio/platform/vfio_platform_private.h
>> +++ b/drivers/vfio/platform/vfio_platform_private.h
>> @@ -17,6 +17,7 @@
>>  
>>  #include <linux/types.h>
>>  #include <linux/interrupt.h>
>> +#include <linux/irqbypass.h>
>>  
>>  #define VFIO_PLATFORM_OFFSET_SHIFT   40
>>  #define VFIO_PLATFORM_OFFSET_MASK (((u64)(1) << VFIO_PLATFORM_OFFSET_SHIFT) - 1)
>> @@ -37,6 +38,7 @@ struct vfio_platform_irq {
>>  	spinlock_t		lock;
>>  	struct virqfd		*unmask;
>>  	struct virqfd		*mask;
>> +	struct irq_bypass_producer producer;
>>  };
>>  
>>  struct vfio_platform_region {
> 
> 
> 



From maxime.ripard at free-electrons.com  Mon Aug 17 08:18:51 2015
From: maxime.ripard at free-electrons.com (Maxime Ripard)
Date: Mon, 17 Aug 2015 17:18:51 +0200
Subject: [PATCH v2] ARM: dts: sunxi: Raise minimum CPU voltage for
 sun7i-a20 to meet SoC specifications
In-Reply-To: <1438722481-2302-1-git-send-email-public_timo.s@silentcreek.de>
References: <1438722481-2302-1-git-send-email-public_timo.s@silentcreek.de>
Message-ID: <20150817151851.GE2547@lukather>

Hi Timo,

On Tue, Aug 04, 2015 at 11:08:01PM +0200, Timo Sigurdsson wrote:
> sun7i-a20.dtsi contains a cpufreq operating point at 0.9 volts. The minimum
> CPU voltage for the Allwinner A20 SoC, however, is 1.0 volts. Thus, raise
> the voltage for the lowest operating point to 1.0 volts in order to stay
> within the SoC specifications. It is an undervolted setting that isn't
> stable across all SoCs and boards out there.
> 
> Signed-off-by: Timo Sigurdsson <public_timo.s at silentcreek.de>

Added Iain's Ack, and Cc stable

Thanks!
Maxime

-- 
Maxime Ripard, Free Electrons
Embedded Linux, Kernel and Android engineering
http://free-electrons.com
-------------- next part --------------
A non-text attachment was scrubbed...
Name: signature.asc
Type: application/pgp-signature
Size: 819 bytes
Desc: Digital signature
URL: <http://lists.infradead.org/pipermail/linux-arm-kernel/attachments/20150817/fb0da564/attachment.sig>

From eric.auger at linaro.org  Mon Aug 17 08:25:52 2015
From: eric.auger at linaro.org (Eric Auger)
Date: Mon, 17 Aug 2015 17:25:52 +0200
Subject: [PATCH v3 03/10] VFIO: platform: single handler using function
 pointer
In-Reply-To: <1439405780.4023.527.camel@redhat.com>
References: <1439212864-12954-1-git-send-email-eric.auger@linaro.org>	
 <1439212864-12954-4-git-send-email-eric.auger@linaro.org>
 <1439405780.4023.527.camel@redhat.com>
Message-ID: <55D1FD00.8030400@linaro.org>

Alex,
On 08/12/2015 08:56 PM, Alex Williamson wrote:
> On Mon, 2015-08-10 at 15:20 +0200, Eric Auger wrote:
>> A single handler now is registered whatever the use case: automasked
>> or not. A function pointer is set according to the wished behavior
>> and the handler calls this function.
>>
>> The irq lock is taken/released in the root handler. eventfd_signal can
>> be called in regions not allowed to sleep.
>>
>> Signed-off-by: Eric Auger <eric.auger at linaro.org>
>>
>> ---
>>
>> v4: creation
>> ---
>>  drivers/vfio/platform/vfio_platform_irq.c     | 21 +++++++++++++++------
>>  drivers/vfio/platform/vfio_platform_private.h |  1 +
>>  2 files changed, 16 insertions(+), 6 deletions(-)
>>
>> diff --git a/drivers/vfio/platform/vfio_platform_irq.c b/drivers/vfio/platform/vfio_platform_irq.c
>> index 40f057a..b31b1f0 100644
>> --- a/drivers/vfio/platform/vfio_platform_irq.c
>> +++ b/drivers/vfio/platform/vfio_platform_irq.c
>> @@ -148,11 +148,8 @@ static int vfio_platform_set_irq_unmask(struct vfio_platform_device *vdev,
>>  static irqreturn_t vfio_automasked_irq_handler(int irq, void *dev_id)
>>  {
>>  	struct vfio_platform_irq *irq_ctx = dev_id;
>> -	unsigned long flags;
>>  	int ret = IRQ_NONE;
>>  
>> -	spin_lock_irqsave(&irq_ctx->lock, flags);
>> -
>>  	if (!irq_ctx->masked) {
>>  		ret = IRQ_HANDLED;
>>  
>> @@ -161,8 +158,6 @@ static irqreturn_t vfio_automasked_irq_handler(int irq, void *dev_id)
>>  		irq_ctx->masked = true;
>>  	}
>>  
>> -	spin_unlock_irqrestore(&irq_ctx->lock, flags);
>> -
>>  	if (ret == IRQ_HANDLED)
>>  		eventfd_signal(irq_ctx->trigger, 1);
> 
> Has this been run with lockdep to check whether this is safe to call
> with spinlock_irqsave held?

No I did not check with lockdep and I will do. There is a comment in
fs/eventfd.c in eventfd_signal function comments that says:

"This function is supposed to be called by the kernel in paths that do
not allow sleeping. In this function we allow the counter to reach the
ULLONG_MAX value, and we signal this as overflow condition by returining
a POLLERR to poll(2)."

so I understood from this it is safe.

Best Regards

Eric

> 
>>  
>> @@ -178,6 +173,19 @@ static irqreturn_t vfio_irq_handler(int irq, void *dev_id)
>>  	return IRQ_HANDLED;
>>  }
>>  
>> +static irqreturn_t vfio_handler(int irq, void *dev_id)
>> +{
>> +	struct vfio_platform_irq *irq_ctx = dev_id;
>> +	unsigned long flags;
>> +	irqreturn_t ret;
>> +
>> +	spin_lock_irqsave(&irq_ctx->lock, flags);
>> +	ret = irq_ctx->handler(irq, dev_id);
>> +	spin_unlock_irqrestore(&irq_ctx->lock, flags);
>> +
>> +	return ret;
>> +}
>> +
>>  static void vfio_platform_irq_bypass_stop(struct irq_bypass_producer *prod)
>>  {
>>  }
>> @@ -229,9 +237,10 @@ static int vfio_set_trigger(struct vfio_platform_device *vdev, int index,
>>  	}
>>  
>>  	irq->trigger = trigger;
>> +	irq->handler = handler;
>>  
>>  	irq_set_status_flags(irq->hwirq, IRQ_NOAUTOEN);
>> -	ret = request_irq(irq->hwirq, handler, 0, irq->name, irq);
>> +	ret = request_irq(irq->hwirq, vfio_handler, 0, irq->name, irq);
>>  	if (ret) {
>>  		kfree(irq->name);
>>  		eventfd_ctx_put(trigger);
>> diff --git a/drivers/vfio/platform/vfio_platform_private.h b/drivers/vfio/platform/vfio_platform_private.h
>> index 8b4f814..f848a6b 100644
>> --- a/drivers/vfio/platform/vfio_platform_private.h
>> +++ b/drivers/vfio/platform/vfio_platform_private.h
>> @@ -40,6 +40,7 @@ struct vfio_platform_irq {
>>  	struct virqfd		*mask;
>>  	struct irq_bypass_producer producer;
>>  	bool			forwarded;
>> +	irqreturn_t (*handler)(int irq, void *dev_id);
>>  };
>>  
>>  struct vfio_platform_region {
> 
> 
> 



From jungseoklee85 at gmail.com  Mon Aug 17 08:29:55 2015
From: jungseoklee85 at gmail.com (Jungseok Lee)
Date: Tue, 18 Aug 2015 00:29:55 +0900
Subject: [RFC v2 0/4] arm64: ftrace: fix incorrect output from stack tracer
In-Reply-To: <55D16831.5080605@linaro.org>
References: <1438674249-3447-1-git-send-email-takahiro.akashi@linaro.org>
 <50B298B0-1978-471B-BCE7-BC433E9993C1@gmail.com>
 <55D16831.5080605@linaro.org>
Message-ID: <33817404-EDFB-45D0-9535-E23474C9B56F@gmail.com>

On Aug 17, 2015, at 1:50 PM, AKASHI Takahiro wrote:
> Hi

Hi Akashi,

> On 08/11/2015 11:52 PM, Jungseok Lee wrote:
>> On Aug 4, 2015, at 4:44 PM, AKASHI Takahiro wrote:
>> 
>> Hi Akashi,
>> 
>>> See the following threads [1],[2] for the background.
>>> 
>>> With this patch series, I'm trying to fix several problems I noticed
>>> with stack tracer on arm64. But it is rather experimental, and there still
>>> remained are several issues.
>>> 
>>> Patch #1 modifies ftrace framework so that we can provide arm64-specific
>>> stack tracer later.
>>> (Well, I know there is some room for further refactoring, but this is
>>> just a prototype code.)
>>> Patch #2 implements this arch_check_stack() using unwind_stackframe() to
>>> traverse stack frames and identify a stack index for each traced function.
>>> Patch #3 addresses an issue that stack tracer doesn't work well in
>>> conjuction with function graph tracer.
>>> Patch #4 addresses an issue that unwind_stackframe() misses a function
>>> that is the one when an exception happens by setting up a stack frame
>>> for exception handler.
>>> 
>>> See below for the result with those patches.
>>> Issues include:
>>> a) Size of gic_handle_irq() is 48 (#13), but should be 64.
>>> b) We cannot identify a location of function which is being returned
>>>   and hooked temporarily by return_to_handler() (#18)
>>> c) A meaningless entry (#62) as well as a bogus size for the first
>>>   function, el0_svc (#61)
>>> d) Size doesn't contain a function's "dynamically allocated local
>>>   variables," if any, but instead is sumed up in child's size.
>>>   (See details in [3].)
>>> 
>>> I'm afraid that we cannot fix issue b) unless we can do *atomically*
>>> push/pop a return adress in current->ret_stack[], increment/decrement
>>> current->curr_ret_stack and restore lr register.
>>> 
>>> We will be able to fix issue d) once we know all the locations in
>>> the list, including b).
>>> 
>>> [1] http://lists.infradead.org/pipermail/linux-arm-kernel/2015-July/354126.html
>>> [2] http://lists.infradead.org/pipermail/linux-arm-kernel/2015-July/355920.html
>>> [3] http://lists.infradead.org/pipermail/linux-arm-kernel/2015-July/358034.html
>> 
>> I hope I'm not too late..
> 
> I was on vacation last week.
> 
>> This series looks written on top of the hunk in the end of this reply.
>> 
>> I've strongly agreed with your opinion as digging out this issue. We need to analyse
>> the first instruction of each function, "stp x29, x30, [sp, #val]!", in order to
>> solve this problem clearly.
> 
> As far as I notice, the following is not the only prologue:
>  stp  x29,x30, [sp,#-xx]!
>  mov  x29,sp
> but some functions may have another one like:
>  sub  sp, sp, #xx
>  stp  x29,x30, [sp, #16]
>  add  x29,sp, #16
> Even worse, I see some variant, for example in trace_graph_entry(),
>  adrp x2, 0x...
>  stp  x29,x30,[sp,#-xx]!
>  add  x4, x2, #..
>  mov  x29,x30
> 
> So parsing the function prologue perfectly is a bit more complicated than imagined.
> I'm now asking some gcc guy for more information.

I've also observed the last two variants as playing with kallsyms to parse function
prologues. The work is accompanied by a pretty expensive computational overhead which
might be unnecessary originally. IMHO, one of PCS's objectives is to handle this kind
of work gracefully. Isn't it?

It is a great approach to talk with gcc guys. It looks inevitable that a complex decoding
logic is needed without it.

I have two drafts on this issue.

1) AARCH64 PCS
I borrow the ascii art from your description :)
If the stack frame is constructed as follows, it would be possible to record
an accurate stack size without decoding store-pair instruction or its variants.
Additionally, a code, frame->sp = fp + 0x10, is correct except exceptions.

    +-------+
    |       |
    |       |
    +-------+
    |       |
    | func-1's dynamic variable
    |       |
    +-------+
    |       |
    | func-1's local variable
    |       |
fp1 +-------+
    |  fp0  |
    +-------+
    |  lr0  |
sp1 +-------+ <------ func-1's stackframe
    |       |
    | func-0's dynamic variable
    |       |
    +-------+
    |       |
    | func-0's local variable
    |       |
    +-------+
    |       |
    +-------+ top

However, it's a pretty big challenge to update PCS..

2) v1 approach + function graph fix.
I use a stack tracer to check max stack size and its context. It would
be perfect if it shows an accurate size of every entry, but it would be
enough to find dominant entries in real practice, at least in my case.
(I agree caller's dynamic + callee's local is technically unacceptable.)
The same approach could be applied to exception. It would be no issue
anymore if someone try to introduce a separate IRQ stack like x86.

Best Regards
Jungseok Lee

From appana.durga.rao at xilinx.com  Mon Aug 17 08:31:52 2015
From: appana.durga.rao at xilinx.com (Kedareswara rao Appana)
Date: Mon, 17 Aug 2015 21:01:52 +0530
Subject: [RESEND PATCH] dmaengine: Add Xilinx AXI Direct Memory Access Engine
 driver support
Message-ID: <1439825512-16444-1-git-send-email-appanad@xilinx.com>

This is the driver for the AXI Direct Memory Access (AXI DMA)
core, which is a soft Xilinx IP core that provides high-
bandwidth direct memory access between memory and AXI4-Stream
type target peripherals.

Signed-off-by: Srikanth Thokala <sthokal at xilinx.com>
Signed-off-by: Kedareswara rao Appana <appanad at xilinx.com>
---
The deivce tree doc got applied in the slave-dmaengine.git.

Forgot to include dmaengine at vger.kernel.org in the cc list
resending the patch.

Changes in v8:
- Updated the SG handling as suggested by Nicolae Rosia.
- Removed the unnecessary xilinx_dma_channel_set_config API the properties
  in this API is not being used by the driver.
Changes in v7:
- Updated license in the driver as suggested by Paul.
- Corrected return value in is_idle funtion.
Changes in v6:
- Fixed Odd indention in the Kconfig.
- used GFP_NOWAIT instead of GFP_KERNEL during the desc allocation
- Calculated residue in the tx_status instead of complete_descriptor.
- Update copy right to 2015.
- Modified spin_lock handling moved the spin_lock to the appropriate functions
(instead of xilinx_dma_start_transfer doing it xilinx_dma_issue_pending api).
- device_control and declare slave caps updated as per newer APi's.
Changes in v5:
- Modified the xilinx_dma.h header file location to the 
  include/linux/dma/xilinx_dma.h
Changes in v4:
- Add direction field to DMA descriptor structure and removed from
  channel structure to avoid duplication.
- Check for DMA idle condition before changing the configuration.
- Residue is being calculated in complete_descriptor() and is reported
  to slave driver.
Changes in v3:
- Rebased on 3.16-rc7
Changes in v2:
- Simplified the logic to set SOP and APP words in prep_slave_sg().
- Corrected function description comments to match the return type.
- Fixed some minor comments as suggested by Andy.

 drivers/dma/Kconfig             |   13 +
 drivers/dma/xilinx/Makefile     |    1 +
 drivers/dma/xilinx/xilinx_dma.c | 1179 +++++++++++++++++++++++++++++++++++++++
 3 files changed, 1193 insertions(+)
 create mode 100644 drivers/dma/xilinx/xilinx_dma.c

diff --git a/drivers/dma/Kconfig b/drivers/dma/Kconfig
index 88d474b..5e95f07 100644
--- a/drivers/dma/Kconfig
+++ b/drivers/dma/Kconfig
@@ -507,4 +507,17 @@ config QCOM_BAM_DMA
 	  Enable support for the QCOM BAM DMA controller.  This controller
 	  provides DMA capabilities for a variety of on-chip devices.
 
+config XILINX_DMA
+        tristate "Xilinx AXI DMA Engine"
+        depends on (ARCH_ZYNQ || MICROBLAZE)
+        select DMA_ENGINE
+        help
+          Enable support for Xilinx AXI DMA Soft IP.
+
+          This engine provides high-bandwidth direct memory access
+          between memory and AXI4-Stream type target peripherals.
+          It has two stream interfaces/channels, Memory Mapped to
+          Stream (MM2S) and Stream to Memory Mapped (S2MM) for the
+          data transfers.
+
 endif
diff --git a/drivers/dma/xilinx/Makefile b/drivers/dma/xilinx/Makefile
index 3c4e9f2..6224a49 100644
--- a/drivers/dma/xilinx/Makefile
+++ b/drivers/dma/xilinx/Makefile
@@ -1 +1,2 @@
 obj-$(CONFIG_XILINX_VDMA) += xilinx_vdma.o
+obj-$(CONFIG_XILINX_DMA) += xilinx_dma.o
diff --git a/drivers/dma/xilinx/xilinx_dma.c b/drivers/dma/xilinx/xilinx_dma.c
new file mode 100644
index 0000000..a9be197
--- /dev/null
+++ b/drivers/dma/xilinx/xilinx_dma.c
@@ -0,0 +1,1179 @@
+/*
+ * DMA driver for Xilinx DMA Engine
+ *
+ * Copyright (C) 2010 - 2015 Xilinx, Inc. All rights reserved.
+ *
+ * Based on the Freescale DMA driver.
+ *
+ * Description:
+ *  The AXI DMA, is a soft IP, which provides high-bandwidth Direct Memory
+ *  Access between memory and AXI4-Stream-type target peripherals. It can be
+ *  configured to have one channel or two channels and if configured as two
+ *  channels, one is to transmit data from memory to a device and another is
+ *  to receive from a device.
+ *
+ * This 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.
+ */
+
+#include <linux/bitops.h>
+#include <linux/dma/xilinx_dma.h>
+#include <linux/init.h>
+#include <linux/interrupt.h>
+#include <linux/io.h>
+#include <linux/module.h>
+#include <linux/of_address.h>
+#include <linux/of_dma.h>
+#include <linux/of_irq.h>
+#include <linux/of_platform.h>
+#include <linux/slab.h>
+
+#include "../dmaengine.h"
+
+/* Register Offsets */
+#define XILINX_DMA_REG_CONTROL		0x00
+#define XILINX_DMA_REG_STATUS		0x04
+#define XILINX_DMA_REG_CURDESC		0x08
+#define XILINX_DMA_REG_TAILDESC		0x10
+#define XILINX_DMA_REG_SRCADDR		0x18
+#define XILINX_DMA_REG_DSTADDR		0x20
+#define XILINX_DMA_REG_BTT		0x28
+
+/* Channel/Descriptor Offsets */
+#define XILINX_DMA_MM2S_CTRL_OFFSET	0x00
+#define XILINX_DMA_S2MM_CTRL_OFFSET	0x30
+
+/* General register bits definitions */
+#define XILINX_DMA_CR_RUNSTOP_MASK	BIT(0)
+#define XILINX_DMA_CR_RESET_MASK	BIT(2)
+
+#define XILINX_DMA_CR_DELAY_SHIFT	24
+#define XILINX_DMA_CR_COALESCE_SHIFT	16
+
+#define XILINX_DMA_CR_DELAY_MAX		GENMASK(7, 0)
+#define XILINX_DMA_CR_COALESCE_MAX	GENMASK(7, 0)
+
+#define XILINX_DMA_SR_HALTED_MASK	BIT(0)
+#define XILINX_DMA_SR_IDLE_MASK		BIT(1)
+
+#define XILINX_DMA_XR_IRQ_IOC_MASK	BIT(12)
+#define XILINX_DMA_XR_IRQ_DELAY_MASK	BIT(13)
+#define XILINX_DMA_XR_IRQ_ERROR_MASK	BIT(14)
+#define XILINX_DMA_XR_IRQ_ALL_MASK	GENMASK(14, 12)
+
+/* BD definitions */
+#define XILINX_DMA_BD_STS_ALL_MASK	GENMASK(31, 28)
+#define XILINX_DMA_BD_SOP		BIT(27)
+#define XILINX_DMA_BD_EOP		BIT(26)
+
+/* Hw specific definitions */
+#define XILINX_DMA_MAX_CHANS_PER_DEVICE	0x2
+#define XILINX_DMA_MAX_TRANS_LEN	GENMASK(22, 0)
+
+/* Delay loop counter to prevent hardware failure */
+#define XILINX_DMA_LOOP_COUNT		1000000
+
+/* Maximum number of Descriptors */
+#define XILINX_DMA_NUM_DESCS		255
+#define XILINX_DMA_COALESCE_MAX		255
+#define XILINX_DMA_NUM_APP_WORDS	5
+
+/**
+ * struct xilinx_dma_desc_hw - Hardware Descriptor
+ * @next_desc: Next Descriptor Pointer @0x00
+ * @pad1: Reserved @0x04
+ * @buf_addr: Buffer address @0x08
+ * @pad2: Reserved @0x0C
+ * @pad3: Reserved @0x10
+ * @pad4: Reserved @0x14
+ * @control: Control field @0x18
+ * @status: Status field @0x1C
+ * @app: APP Fields @0x20 - 0x30
+ */
+struct xilinx_dma_desc_hw {
+	u32 next_desc;
+	u32 pad1;
+	u32 buf_addr;
+	u32 pad2;
+	u32 pad3;
+	u32 pad4;
+	u32 control;
+	u32 status;
+	u32 app[XILINX_DMA_NUM_APP_WORDS];
+} __aligned(64);
+
+/**
+ * struct xilinx_dma_tx_segment - Descriptor segment
+ * @hw: Hardware descriptor
+ * @node: Node in the descriptor segments list
+ * @phys: Physical address of segment
+ */
+struct xilinx_dma_tx_segment {
+	struct xilinx_dma_desc_hw hw;
+	struct list_head node;
+	dma_addr_t phys;
+} __aligned(64);
+
+/**
+ * struct xilinx_dma_tx_descriptor - Per Transaction structure
+ * @async_tx: Async transaction descriptor
+ * @segments: TX segments list
+ * @node: Node in the channel descriptors list
+ * @direction: Transfer direction
+ */
+struct xilinx_dma_tx_descriptor {
+	struct dma_async_tx_descriptor async_tx;
+	struct list_head segments;
+	struct list_head node;
+	enum dma_transfer_direction direction;
+};
+
+/**
+ * struct xilinx_dma_chan - Driver specific DMA channel structure
+ * @xdev: Driver specific device structure
+ * @ctrl_offset: Control registers offset
+ * @ctrl_reg: Control register value
+ * @lock: Descriptor operation lock
+ * @pending_list: Descriptors waiting
+ * @active_list: Descriptors ready to submit
+ * @done_list: Complete descriptors
+ * @free_seg_list: Free descriptors
+ * @common: DMA common channel
+ * @seg_v: Statically allocated segments base
+ * @seg_p: Physical allocated segments base
+ * @dev: The dma device
+ * @irq: Channel IRQ
+ * @id: Channel ID
+ * @has_sg: Support scatter transfers
+ * @idle: Check for channel idle
+ * @err: Channel has errors
+ * @tasklet: Cleanup work after irq
+ * @residue: Residue
+ * @desc_pendingcount: Descriptor pending count
+ */
+struct xilinx_dma_chan {
+	struct xilinx_dma_device *xdev;
+	u32 ctrl_offset;
+	u32 ctrl_reg;
+	spinlock_t lock;
+	struct list_head pending_list;
+	struct list_head done_list;
+	struct list_head active_list;
+	struct list_head free_seg_list;
+	struct dma_chan common;
+	struct xilinx_dma_tx_segment *seg_v;
+	dma_addr_t seg_p;
+	struct device *dev;
+	int irq;
+	int id;
+	bool has_sg;
+	bool idle;
+	int err;
+	struct tasklet_struct tasklet;
+	u32 residue;
+	u32 desc_pendingcount;
+};
+
+/**
+ * struct xilinx_dma_device - DMA device structure
+ * @regs: I/O mapped base address
+ * @dev: Device Structure
+ * @common: DMA device structure
+ * @chan: Driver specific DMA channel
+ * @has_sg: Specifies whether Scatter-Gather is present or not
+ */
+struct xilinx_dma_device {
+	void __iomem *regs;
+	struct device *dev;
+	struct dma_device common;
+	struct xilinx_dma_chan *chan[XILINX_DMA_MAX_CHANS_PER_DEVICE];
+	bool has_sg;
+};
+
+/* Macros */
+#define to_xilinx_chan(chan) \
+	container_of(chan, struct xilinx_dma_chan, common)
+#define to_dma_tx_descriptor(tx) \
+	container_of(tx, struct xilinx_dma_tx_descriptor, async_tx)
+
+/* IO accessors */
+static inline void dma_write(struct xilinx_dma_chan *chan, u32 reg, u32 value)
+{
+	iowrite32(value, chan->xdev->regs + reg);
+}
+
+static inline u32 dma_read(struct xilinx_dma_chan *chan, u32 reg)
+{
+	return ioread32(chan->xdev->regs + reg);
+}
+
+static inline u32 dma_ctrl_read(struct xilinx_dma_chan *chan, u32 reg)
+{
+	return dma_read(chan, chan->ctrl_offset + reg);
+}
+
+static inline void dma_ctrl_write(struct xilinx_dma_chan *chan, u32 reg,
+				  u32 value)
+{
+	dma_write(chan, chan->ctrl_offset + reg, value);
+}
+
+/* -----------------------------------------------------------------------------
+ * Descriptors and segments alloc and free
+ */
+
+/**
+ * xilinx_dma_alloc_tx_segment - Allocate transaction segment
+ * @chan: Driver specific dma channel
+ *
+ * Return: The allocated segment on success and NULL on failure.
+ */
+static struct xilinx_dma_tx_segment *
+xilinx_dma_alloc_tx_segment(struct xilinx_dma_chan *chan)
+{
+	struct xilinx_dma_tx_segment *segment = NULL;
+	unsigned long flags;
+
+	spin_lock_irqsave(&chan->lock, flags);
+	if (!list_empty(&chan->free_seg_list)) {
+		segment = list_first_entry(&chan->free_seg_list,
+					   struct xilinx_dma_tx_segment,
+					   node);
+		list_del(&segment->node);
+	}
+	spin_unlock_irqrestore(&chan->lock, flags);
+
+	return segment;
+}
+
+/**
+ * xilinx_dma_clean_hw_desc - Clean hardware descriptor
+ * @hw: HW descriptor to clean
+ */
+static void xilinx_dma_clean_hw_desc(struct xilinx_dma_desc_hw *hw)
+{
+	u32 next_desc = hw->next_desc;
+
+	memset(hw, 0, sizeof(struct xilinx_dma_desc_hw));
+
+	hw->next_desc = next_desc;
+}
+
+/**
+ * xilinx_dma_free_tx_segment - Free transaction segment
+ * @chan: Driver specific dma channel
+ * @segment: dma transaction segment
+ */
+static void xilinx_dma_free_tx_segment(struct xilinx_dma_chan *chan,
+				       struct xilinx_dma_tx_segment *segment)
+{
+	xilinx_dma_clean_hw_desc(&segment->hw);
+
+	list_add_tail(&segment->node, &chan->free_seg_list);
+}
+
+/**
+ * xilinx_dma_tx_descriptor - Allocate transaction descriptor
+ * @chan: Driver specific dma channel
+ *
+ * Return: The allocated descriptor on success and NULL on failure.
+ */
+static struct xilinx_dma_tx_descriptor *
+xilinx_dma_alloc_tx_descriptor(struct xilinx_dma_chan *chan)
+{
+	struct xilinx_dma_tx_descriptor *desc;
+
+	desc = kzalloc(sizeof(*desc), GFP_NOWAIT);
+	if (!desc)
+		return NULL;
+
+	INIT_LIST_HEAD(&desc->segments);
+
+	return desc;
+}
+
+/**
+ * xilinx_dma_free_tx_descriptor - Free transaction descriptor
+ * @chan: Driver specific dma channel
+ * @desc: dma transaction descriptor
+ */
+static void
+xilinx_dma_free_tx_descriptor(struct xilinx_dma_chan *chan,
+			      struct xilinx_dma_tx_descriptor *desc)
+{
+	struct xilinx_dma_tx_segment *segment, *next;
+
+	if (!desc)
+		return;
+
+	list_for_each_entry_safe(segment, next, &desc->segments, node) {
+		list_del(&segment->node);
+		xilinx_dma_free_tx_segment(chan, segment);
+	}
+
+	kfree(desc);
+}
+
+/**
+ * xilinx_dma_alloc_chan_resources - Allocate channel resources
+ * @dchan: DMA channel
+ *
+ * Return: '0' on success and failure value on error
+ */
+static int xilinx_dma_alloc_chan_resources(struct dma_chan *dchan)
+{
+	struct xilinx_dma_chan *chan = to_xilinx_chan(dchan);
+	int i;
+
+	/* Allocate the buffer descriptors. */
+	chan->seg_v = dma_zalloc_coherent(chan->dev,
+					  sizeof(*chan->seg_v) *
+					  XILINX_DMA_NUM_DESCS,
+					  &chan->seg_p, GFP_KERNEL);
+	if (!chan->seg_v) {
+		dev_err(chan->dev,
+			"unable to allocate channel %d descriptors\n",
+			chan->id);
+		return -ENOMEM;
+	}
+
+	for (i = 0; i < XILINX_DMA_NUM_DESCS; i++) {
+		chan->seg_v[i].hw.next_desc =
+				chan->seg_p + sizeof(*chan->seg_v) *
+				((i + 1) % XILINX_DMA_NUM_DESCS);
+		chan->seg_v[i].phys =
+				chan->seg_p + sizeof(*chan->seg_v) * i;
+		list_add_tail(&chan->seg_v[i].node, &chan->free_seg_list);
+	}
+
+	dma_cookie_init(dchan);
+
+	/* Enable interrupts */
+	chan->ctrl_reg |= XILINX_DMA_XR_IRQ_ALL_MASK;
+	dma_ctrl_write(chan, XILINX_DMA_REG_CONTROL, chan->ctrl_reg);
+
+	return 0;
+}
+
+/**
+ * xilinx_dma_free_desc_list - Free descriptors list
+ * @chan: Driver specific dma channel
+ * @list: List to parse and delete the descriptor
+ */
+static void xilinx_dma_free_desc_list(struct xilinx_dma_chan *chan,
+				      struct list_head *list)
+{
+	struct xilinx_dma_tx_descriptor *desc, *next;
+
+	list_for_each_entry_safe(desc, next, list, node) {
+		list_del(&desc->node);
+		xilinx_dma_free_tx_descriptor(chan, desc);
+	}
+}
+
+/**
+ * xilinx_dma_free_descriptors - Free channel descriptors
+ * @chan: Driver specific dma channel
+ */
+static void xilinx_dma_free_descriptors(struct xilinx_dma_chan *chan)
+{
+	unsigned long flags;
+
+	spin_lock_irqsave(&chan->lock, flags);
+
+	xilinx_dma_free_desc_list(chan, &chan->pending_list);
+	xilinx_dma_free_desc_list(chan, &chan->done_list);
+	xilinx_dma_free_desc_list(chan, &chan->active_list);
+
+	spin_unlock_irqrestore(&chan->lock, flags);
+}
+
+/**
+ * xilinx_dma_free_chan_resources - Free channel resources
+ * @dchan: DMA channel
+ */
+static void xilinx_dma_free_chan_resources(struct dma_chan *dchan)
+{
+	struct xilinx_dma_chan *chan = to_xilinx_chan(dchan);
+
+	xilinx_dma_free_descriptors(chan);
+
+	dma_free_coherent(chan->dev,
+			  sizeof(*chan->seg_v) * XILINX_DMA_NUM_DESCS,
+			  chan->seg_v, chan->seg_p);
+}
+
+/**
+ * xilinx_dma_chan_desc_cleanup - Clean channel descriptors
+ * @chan: Driver specific dma channel
+ */
+static void xilinx_dma_chan_desc_cleanup(struct xilinx_dma_chan *chan)
+{
+	struct xilinx_dma_tx_descriptor *desc;
+	unsigned long flags;
+
+	spin_lock_irqsave(&chan->lock, flags);
+
+	while (!list_empty(&chan->done_list)) {
+		dma_async_tx_callback callback;
+		void *callback_param;
+
+		desc = list_first_entry(&chan->done_list,
+			struct xilinx_dma_tx_descriptor, node);
+
+		/* Remove from the list of running transactions */
+		list_del(&desc->node);
+
+		/* Run the link descriptor callback function */
+		callback = desc->async_tx.callback;
+		callback_param = desc->async_tx.callback_param;
+		if (callback) {
+			spin_unlock_irqrestore(&chan->lock, flags);
+			callback(callback_param);
+			spin_lock_irqsave(&chan->lock, flags);
+		}
+
+		/* Run any dependencies, then free the descriptor */
+		dma_run_dependencies(&desc->async_tx);
+		xilinx_dma_free_tx_descriptor(chan, desc);
+	}
+
+	spin_unlock_irqrestore(&chan->lock, flags);
+}
+
+/**
+ * xilinx_dma_tx_status - Get dma transaction status
+ * @dchan: DMA channel
+ * @cookie: Transaction identifier
+ * @txstate: Transaction state
+ *
+ * Return: DMA transaction status
+ */
+static enum dma_status xilinx_dma_tx_status(struct dma_chan *dchan,
+					    dma_cookie_t cookie,
+					    struct dma_tx_state *txstate)
+{
+	struct xilinx_dma_chan *chan = to_xilinx_chan(dchan);
+	struct xilinx_dma_tx_descriptor *desc;
+	struct xilinx_dma_tx_segment *segment;
+	struct xilinx_dma_desc_hw *hw;
+	enum dma_status ret;
+	unsigned long flags;
+	u32 residue;
+
+	ret = dma_cookie_status(dchan, cookie, txstate);
+	if (ret == DMA_COMPLETE || !txstate)
+		return ret;
+
+	desc = list_last_entry(&chan->active_list,
+			       struct xilinx_dma_tx_descriptor, node);
+
+	spin_lock_irqsave(&chan->lock, flags);
+	if (chan->has_sg) {
+		while (!list_empty(&desc->segments)) {
+			segment = list_first_entry(&desc->segments,
+					struct xilinx_dma_tx_segment, node);
+			hw = &segment->hw;
+			residue += (hw->control - hw->status) &
+				   XILINX_DMA_MAX_TRANS_LEN;
+		}
+	}
+
+	chan->residue = residue;
+	dma_set_residue(txstate, chan->residue);
+	spin_unlock_irqrestore(&chan->lock, flags);
+
+	return ret;
+}
+
+/**
+ * xilinx_dma_halt - Halt DMA channel
+ * @chan: Driver specific DMA channel
+ */
+static void xilinx_dma_halt(struct xilinx_dma_chan *chan)
+{
+	int loop = XILINX_DMA_LOOP_COUNT;
+
+	chan->ctrl_reg &= ~XILINX_DMA_CR_RUNSTOP_MASK;
+	dma_ctrl_write(chan, XILINX_DMA_REG_CONTROL, chan->ctrl_reg);
+
+	/* Wait for the hardware to halt */
+	do {
+		if (dma_ctrl_read(chan, XILINX_DMA_REG_STATUS) &
+			XILINX_DMA_SR_HALTED_MASK)
+			break;
+	} while (loop--);
+
+	if (!loop) {
+		dev_err(chan->dev, "Cannot stop channel %p: %x\n",
+			chan, dma_ctrl_read(chan, XILINX_DMA_REG_STATUS));
+		chan->err = true;
+	}
+}
+
+/**
+ * xilinx_dma_start - Start DMA channel
+ * @chan: Driver specific DMA channel
+ */
+static void xilinx_dma_start(struct xilinx_dma_chan *chan)
+{
+	int loop = XILINX_DMA_LOOP_COUNT;
+
+	chan->ctrl_reg |= XILINX_DMA_CR_RUNSTOP_MASK;
+	dma_ctrl_write(chan, XILINX_DMA_REG_CONTROL, chan->ctrl_reg);
+
+	/* Wait for the hardware to start */
+	do {
+		if (!dma_ctrl_read(chan, XILINX_DMA_REG_STATUS) &
+			XILINX_DMA_SR_HALTED_MASK)
+			break;
+	} while (loop--);
+
+	if (!loop) {
+		dev_err(chan->dev, "Cannot start channel %p: %x\n",
+			 chan, dma_ctrl_read(chan, XILINX_DMA_REG_STATUS));
+		chan->err = true;
+	}
+}
+
+/**
+ * xilinx_dma_start_transfer - Starts DMA transfer
+ * @chan: Driver specific channel struct pointer
+ */
+static void xilinx_dma_start_transfer(struct xilinx_dma_chan *chan)
+{
+	struct xilinx_dma_tx_descriptor *head_desc, *tail_desc;
+	struct xilinx_dma_tx_segment *tail_segment;
+
+	if (chan->err)
+		return;
+
+	if (list_empty(&chan->pending_list))
+		return;
+
+	if (!chan->idle)
+		return;
+
+	head_desc = list_first_entry(&chan->pending_list,
+				     struct xilinx_dma_tx_descriptor, node);
+	tail_desc = list_last_entry(&chan->pending_list,
+				    struct xilinx_dma_tx_descriptor, node);
+	tail_segment = list_last_entry(&tail_desc->segments,
+				       struct xilinx_dma_tx_segment, node);
+
+	if (chan->desc_pendingcount <= XILINX_DMA_COALESCE_MAX) {
+		chan->ctrl_reg &= ~XILINX_DMA_CR_COALESCE_MAX;
+		chan->ctrl_reg |= chan->desc_pendingcount <<
+				  XILINX_DMA_CR_COALESCE_SHIFT;
+		dma_ctrl_write(chan, XILINX_DMA_REG_CONTROL, chan->ctrl_reg);
+	}
+
+	if (chan->has_sg)
+		dma_ctrl_write(chan, XILINX_DMA_REG_CURDESC,
+			       head_desc->async_tx.phys);
+
+	xilinx_dma_start(chan);
+
+	if (chan->err)
+		return;
+
+	/* Start the transfer */
+	if (chan->has_sg) {
+		dma_ctrl_write(chan, XILINX_DMA_REG_TAILDESC,
+			       tail_segment->phys);
+	} else {
+		struct xilinx_dma_tx_segment *segment;
+		struct xilinx_dma_desc_hw *hw;
+
+		segment = list_first_entry(&head_desc->segments,
+					   struct xilinx_dma_tx_segment, node);
+		hw = &segment->hw;
+
+		if (head_desc->direction == DMA_MEM_TO_DEV)
+			dma_ctrl_write(chan, XILINX_DMA_REG_SRCADDR,
+				       hw->buf_addr);
+		else
+			dma_ctrl_write(chan, XILINX_DMA_REG_DSTADDR,
+				       hw->buf_addr);
+
+		/* Start the transfer */
+		dma_ctrl_write(chan, XILINX_DMA_REG_BTT,
+			       hw->control & XILINX_DMA_MAX_TRANS_LEN);
+	}
+
+	list_splice_tail_init(&chan->pending_list, &chan->active_list);
+	chan->desc_pendingcount = 0;
+	chan->idle = false;
+}
+
+/**
+ * xilinx_dma_issue_pending - Issue pending transactions
+ * @dchan: DMA channel
+ */
+static void xilinx_dma_issue_pending(struct dma_chan *dchan)
+{
+	struct xilinx_dma_chan *chan = to_xilinx_chan(dchan);
+	unsigned long flags;
+
+	spin_lock_irqsave(&chan->lock, flags);
+	xilinx_dma_start_transfer(chan);
+	spin_unlock_irqrestore(&chan->lock, flags);
+}
+
+/**
+ * xilinx_dma_complete_descriptor - Mark the active descriptor as complete
+ * @chan : xilinx DMA channel
+ */
+static void xilinx_dma_complete_descriptor(struct xilinx_dma_chan *chan)
+{
+	struct xilinx_dma_tx_descriptor *desc, *next;
+
+	if (list_empty(&chan->active_list))
+		return;
+
+	list_for_each_entry_safe(desc, next, &chan->active_list, node) {
+		list_del(&desc->node);
+		dma_cookie_complete(&desc->async_tx);
+		list_add_tail(&desc->node, &chan->done_list);
+	}
+}
+
+/**
+ * xilinx_dma_reset - Reset DMA channel
+ * @chan: Driver specific DMA channel
+ *
+ * Return: '0' on success and failure value on error
+ */
+static int xilinx_dma_chan_reset(struct xilinx_dma_chan *chan)
+{
+	int loop = XILINX_DMA_LOOP_COUNT;
+	u32 tmp;
+
+	chan->ctrl_reg = dma_ctrl_read(chan, XILINX_DMA_REG_CONTROL);
+	dma_ctrl_write(chan, XILINX_DMA_REG_CONTROL, chan->ctrl_reg |
+		       XILINX_DMA_CR_RESET_MASK);
+
+	tmp = dma_ctrl_read(chan, XILINX_DMA_REG_CONTROL) &
+	      XILINX_DMA_CR_RESET_MASK;
+
+	/* Wait for the hardware to finish reset */
+	do {
+		tmp = dma_ctrl_read(chan, XILINX_DMA_REG_CONTROL) &
+		      XILINX_DMA_CR_RESET_MASK;
+	} while (loop-- && tmp);
+
+	if (!loop) {
+		dev_err(chan->dev, "reset timeout, cr %x, sr %x\n",
+			dma_ctrl_read(chan, XILINX_DMA_REG_CONTROL),
+			dma_ctrl_read(chan, XILINX_DMA_REG_STATUS));
+		return -EBUSY;
+	}
+
+	chan->err = false;
+
+	return 0;
+}
+
+/**
+ * xilinx_dma_irq_handler - DMA Interrupt handler
+ * @irq: IRQ number
+ * @data: Pointer to the Xilinx DMA channel structure
+ *
+ * Return: IRQ_HANDLED/IRQ_NONE
+ */
+static irqreturn_t xilinx_dma_irq_handler(int irq, void *data)
+{
+	struct xilinx_dma_chan *chan = data;
+	u32 status;
+
+	/* Read the status and ack the interrupts. */
+	status = dma_ctrl_read(chan, XILINX_DMA_REG_STATUS);
+	if (!(status & XILINX_DMA_XR_IRQ_ALL_MASK))
+		return IRQ_NONE;
+
+	dma_ctrl_write(chan, XILINX_DMA_REG_STATUS,
+		       status & XILINX_DMA_XR_IRQ_ALL_MASK);
+
+	if (status & XILINX_DMA_XR_IRQ_ERROR_MASK) {
+		dev_err(chan->dev,
+			"Channel %p has errors %x, cdr %x tdr %x\n",
+			chan, dma_ctrl_read(chan, XILINX_DMA_REG_STATUS),
+			dma_ctrl_read(chan, XILINX_DMA_REG_CURDESC),
+			dma_ctrl_read(chan, XILINX_DMA_REG_TAILDESC));
+		chan->err = true;
+	}
+
+	/*
+	 * Device takes too long to do the transfer when user requires
+	 * responsiveness
+	 */
+	if (status & XILINX_DMA_XR_IRQ_DELAY_MASK)
+		dev_dbg(chan->dev, "Inter-packet latency too long\n");
+
+	if (status & XILINX_DMA_XR_IRQ_IOC_MASK) {
+		spin_lock(&chan->lock);
+		xilinx_dma_complete_descriptor(chan);
+		chan->idle = true;
+		xilinx_dma_start_transfer(chan);
+		spin_unlock(&chan->lock);
+	}
+
+	tasklet_schedule(&chan->tasklet);
+	return IRQ_HANDLED;
+}
+
+/**
+ * xilinx_dma_do_tasklet - Schedule completion tasklet
+ * @data: Pointer to the Xilinx dma channel structure
+ */
+static void xilinx_dma_do_tasklet(unsigned long data)
+{
+	struct xilinx_dma_chan *chan = (struct xilinx_dma_chan *)data;
+
+	xilinx_dma_chan_desc_cleanup(chan);
+}
+
+/**
+ * append_desc_queue - Queuing descriptor
+ * @chan: Driver specific dma channel
+ * @desc: dma transaction descriptor
+ */
+static void append_desc_queue(struct xilinx_dma_chan *chan,
+			      struct xilinx_dma_tx_descriptor *desc)
+{
+	struct xilinx_dma_tx_segment *tail_segment;
+	struct xilinx_dma_tx_descriptor *tail_desc;
+
+	if (list_empty(&chan->pending_list))
+		goto append;
+
+	/*
+	 * Add the hardware descriptor to the chain of hardware descriptors
+	 * that already exists in memory.
+	 */
+	tail_desc = list_last_entry(&chan->pending_list,
+				    struct xilinx_dma_tx_descriptor, node);
+	tail_segment = list_last_entry(&tail_desc->segments,
+				       struct xilinx_dma_tx_segment, node);
+	tail_segment->hw.next_desc = (u32)desc->async_tx.phys;
+
+	/*
+	 * Add the software descriptor and all children to the list
+	 * of pending transactions
+	 */
+append:
+	list_add_tail(&desc->node, &chan->pending_list);
+	chan->desc_pendingcount++;
+
+	if (unlikely(chan->desc_pendingcount > XILINX_DMA_COALESCE_MAX)) {
+		dev_dbg(chan->dev, "desc pendingcount is too high\n");
+		chan->desc_pendingcount = XILINX_DMA_COALESCE_MAX;
+		BUG();
+	}
+}
+
+/**
+ * xilinx_dma_tx_submit - Submit DMA transaction
+ * @tx: Async transaction descriptor
+ *
+ * Return: cookie value on success and failure value on error
+ */
+static dma_cookie_t xilinx_dma_tx_submit(struct dma_async_tx_descriptor *tx)
+{
+	struct xilinx_dma_tx_descriptor *desc = to_dma_tx_descriptor(tx);
+	struct xilinx_dma_chan *chan = to_xilinx_chan(tx->chan);
+	dma_cookie_t cookie;
+	unsigned long flags;
+	int err;
+
+	if (chan->err) {
+		/*
+		 * If reset fails, need to hard reset the system.
+		 * Channel is no longer functional
+		 */
+		err = xilinx_dma_chan_reset(chan);
+		if (err < 0)
+			return err;
+	}
+
+	spin_lock_irqsave(&chan->lock, flags);
+
+	cookie = dma_cookie_assign(tx);
+
+	/* Put this transaction onto the tail of the pending queue */
+	append_desc_queue(chan, desc);
+
+	spin_unlock_irqrestore(&chan->lock, flags);
+
+	return cookie;
+}
+
+/**
+ * xilinx_dma_prep_slave_sg - prepare descriptors for a DMA_SLAVE transaction
+ * @dchan: DMA channel
+ * @sgl: scatterlist to transfer to/from
+ * @sg_len: number of entries in @scatterlist
+ * @direction: DMA direction
+ * @flags: transfer ack flags
+ * @context: APP words of the descriptor
+ *
+ * Return: Async transaction descriptor on success and NULL on failure
+ */
+static struct dma_async_tx_descriptor *xilinx_dma_prep_slave_sg(
+	struct dma_chan *dchan, struct scatterlist *sgl, unsigned int sg_len,
+	enum dma_transfer_direction direction, unsigned long flags,
+	void *context)
+{
+	struct xilinx_dma_chan *chan = to_xilinx_chan(dchan);
+	struct xilinx_dma_tx_descriptor *desc;
+	struct xilinx_dma_tx_segment *segment;
+	u32 *app_w = (u32 *)context;
+	struct scatterlist *sg;
+	size_t copy, sg_used;
+	int i;
+
+	if (!is_slave_direction(direction))
+		return NULL;
+
+	/* Allocate a transaction descriptor. */
+	desc = xilinx_dma_alloc_tx_descriptor(chan);
+	if (!desc)
+		return NULL;
+
+	desc->direction = direction;
+	dma_async_tx_descriptor_init(&desc->async_tx, &chan->common);
+	desc->async_tx.tx_submit = xilinx_dma_tx_submit;
+
+	/* Build transactions using information in the scatter gather list */
+	for_each_sg(sgl, sg, sg_len, i) {
+		sg_used = 0;
+
+		/* Loop until the entire scatterlist entry is used */
+		while (sg_used < sg_dma_len(sg)) {
+			struct xilinx_dma_desc_hw *hw;
+
+			/* Get a free segment */
+			segment = xilinx_dma_alloc_tx_segment(chan);
+			if (!segment)
+				goto error;
+
+			/*
+			 * Calculate the maximum number of bytes to transfer,
+			 * making sure it is less than the hw limit
+			 */
+			copy = min_t(size_t, sg_dma_len(sg) - sg_used,
+				     XILINX_DMA_MAX_TRANS_LEN);
+			hw = &segment->hw;
+
+			/* Fill in the descriptor */
+			hw->buf_addr = sg_dma_address(sg) + sg_used;
+
+			hw->control = copy;
+
+			if (direction == DMA_MEM_TO_DEV) {
+				if (app_w)
+					memcpy(hw->app, app_w, sizeof(u32) *
+					       XILINX_DMA_NUM_APP_WORDS);
+			}
+
+			sg_used += copy;
+
+			/*
+			 * Insert the segment into the descriptor segments
+			 * list.
+			 */
+			list_add_tail(&segment->node, &desc->segments);
+		}
+	}
+
+	segment = list_first_entry(&desc->segments,
+				   struct xilinx_dma_tx_segment, node);
+	desc->async_tx.phys = segment->phys;
+
+	/* For the last DMA_MEM_TO_DEV transfer, set EOP */
+	if (direction == DMA_MEM_TO_DEV) {
+		segment->hw.control |= XILINX_DMA_BD_SOP;
+		segment = list_last_entry(&desc->segments,
+					  struct xilinx_dma_tx_segment,
+					  node);
+		segment->hw.control |= XILINX_DMA_BD_EOP;
+	}
+
+	return &desc->async_tx;
+
+error:
+	xilinx_dma_free_tx_descriptor(chan, desc);
+	return NULL;
+}
+
+/**
+ * xilinx_dma_terminate_all - Halt the channel and free descriptors
+ * @dchan: DMA Channel pointer
+ *
+ * Return: '0' always
+ */
+static int xilinx_dma_terminate_all(struct dma_chan *dchan)
+{
+	struct xilinx_dma_chan *chan = to_xilinx_chan(dchan);
+
+	/* Halt the DMA engine */
+	xilinx_dma_halt(chan);
+
+	/* Remove and free all of the descriptors in the lists */
+	xilinx_dma_free_descriptors(chan);
+
+	return 0;
+}
+
+/**
+ * xilinx_dma_chan_remove - Per Channel remove function
+ * @chan: Driver specific DMA channel
+ */
+static void xilinx_dma_chan_remove(struct xilinx_dma_chan *chan)
+{
+	/* Disable interrupts */
+	chan->ctrl_reg &= ~XILINX_DMA_XR_IRQ_ALL_MASK;
+	dma_ctrl_write(chan, XILINX_DMA_REG_CONTROL, chan->ctrl_reg);
+
+	if (chan->irq > 0)
+		free_irq(chan->irq, chan);
+
+	tasklet_kill(&chan->tasklet);
+
+	list_del(&chan->common.device_node);
+}
+
+/**
+ * xilinx_dma_chan_probe - Per Channel Probing
+ * It get channel features from the device tree entry and
+ * initialize special channel handling routines
+ *
+ * @xdev: Driver specific device structure
+ * @node: Device node
+ *
+ * Return: '0' on success and failure value on error
+ */
+static int xilinx_dma_chan_probe(struct xilinx_dma_device *xdev,
+				 struct device_node *node)
+{
+	struct xilinx_dma_chan *chan;
+	int err;
+	bool has_dre;
+	u32 value, width = 0;
+
+	/* alloc channel */
+	chan = devm_kzalloc(xdev->dev, sizeof(*chan), GFP_KERNEL);
+	if (!chan)
+		return -ENOMEM;
+
+	chan->dev = xdev->dev;
+	chan->xdev = xdev;
+	chan->has_sg = xdev->has_sg;
+	chan->desc_pendingcount = 0x0;
+
+	has_dre = of_property_read_bool(node, "xlnx,include-dre");
+
+	err = of_property_read_u32(node, "xlnx,datawidth", &value);
+	if (err) {
+		dev_err(xdev->dev, "unable to read datawidth property");
+		return err;
+	}
+
+	width = value >> 3; /* Convert bits to bytes */
+
+	/* If data width is greater than 8 bytes, DRE is not in hw */
+	if (width > 8)
+		has_dre = false;
+
+	if (!has_dre)
+		xdev->common.copy_align = fls(width - 1);
+
+	if (of_device_is_compatible(node, "xlnx,axi-dma-mm2s-channel")) {
+		chan->id = 0;
+		chan->ctrl_offset = XILINX_DMA_MM2S_CTRL_OFFSET;
+	} else if (of_device_is_compatible(node, "xlnx,axi-dma-s2mm-channel")) {
+		chan->id = 1;
+		chan->ctrl_offset = XILINX_DMA_S2MM_CTRL_OFFSET;
+	} else {
+		dev_err(xdev->dev, "Invalid channel compatible node\n");
+		return -EINVAL;
+	}
+
+	xdev->chan[chan->id] = chan;
+
+	/* Initialize the channel */
+	err = xilinx_dma_chan_reset(chan);
+	if (err) {
+		dev_err(xdev->dev, "Reset channel failed\n");
+		return err;
+	}
+
+	spin_lock_init(&chan->lock);
+	INIT_LIST_HEAD(&chan->pending_list);
+	INIT_LIST_HEAD(&chan->done_list);
+	INIT_LIST_HEAD(&chan->active_list);
+	INIT_LIST_HEAD(&chan->free_seg_list);
+
+	chan->common.device = &xdev->common;
+
+	/* find the IRQ line, if it exists in the device tree */
+	chan->irq = irq_of_parse_and_map(node, 0);
+	err = request_irq(chan->irq, xilinx_dma_irq_handler,
+			  IRQF_SHARED,
+			  "xilinx-dma-controller", chan);
+	if (err) {
+		dev_err(xdev->dev, "unable to request IRQ %d\n", chan->irq);
+		return err;
+	}
+
+	/* Initialize the tasklet */
+	tasklet_init(&chan->tasklet, xilinx_dma_do_tasklet,
+		     (unsigned long)chan);
+
+	/* Add the channel to DMA device channel list */
+	list_add_tail(&chan->common.device_node, &xdev->common.channels);
+
+	chan->idle = true;
+
+	return 0;
+}
+
+/**
+ * of_dma_xilinx_xlate - Translation function
+ * @dma_spec: Pointer to DMA specifier as found in the device tree
+ * @ofdma: Pointer to DMA controller data
+ *
+ * Return: DMA channel pointer on success and NULL on error
+ */
+static struct dma_chan *of_dma_xilinx_xlate(struct of_phandle_args *dma_spec,
+					    struct of_dma *ofdma)
+{
+	struct xilinx_dma_device *xdev = ofdma->of_dma_data;
+	int chan_id = dma_spec->args[0];
+
+	if (chan_id >= XILINX_DMA_MAX_CHANS_PER_DEVICE)
+		return NULL;
+
+	return dma_get_slave_channel(&xdev->chan[chan_id]->common);
+}
+
+/**
+ * xilinx_dma_probe - Driver probe function
+ * @pdev: Pointer to the platform_device structure
+ *
+ * Return: '0' on success and failure value on error
+ */
+static int xilinx_dma_probe(struct platform_device *pdev)
+{
+	struct xilinx_dma_device *xdev;
+	struct device_node *child, *node;
+	struct resource *res;
+	int i, ret;
+
+	xdev = devm_kzalloc(&pdev->dev, sizeof(*xdev), GFP_KERNEL);
+	if (!xdev)
+		return -ENOMEM;
+
+	xdev->dev = &(pdev->dev);
+	INIT_LIST_HEAD(&xdev->common.channels);
+
+	node = pdev->dev.of_node;
+
+	/* Map the registers */
+	res = platform_get_resource(pdev, IORESOURCE_MEM, 0);
+	xdev->regs = devm_ioremap_resource(&pdev->dev, res);
+	if (IS_ERR(xdev->regs))
+		return PTR_ERR(xdev->regs);
+
+	/* Check if SG is enabled */
+	xdev->has_sg = of_property_read_bool(node, "xlnx,include-sg");
+
+	/* Axi DMA only do slave transfers */
+	dma_cap_set(DMA_SLAVE, xdev->common.cap_mask);
+	dma_cap_set(DMA_PRIVATE, xdev->common.cap_mask);
+	xdev->common.device_prep_slave_sg = xilinx_dma_prep_slave_sg;
+	xdev->common.device_terminate_all = xilinx_dma_terminate_all;
+	xdev->common.device_issue_pending = xilinx_dma_issue_pending;
+	xdev->common.device_alloc_chan_resources =
+		xilinx_dma_alloc_chan_resources;
+	xdev->common.device_free_chan_resources =
+		xilinx_dma_free_chan_resources;
+	xdev->common.device_tx_status = xilinx_dma_tx_status;
+	xdev->common.directions = BIT(DMA_DEV_TO_MEM) | BIT(DMA_MEM_TO_DEV);
+	xdev->common.residue_granularity = DMA_RESIDUE_GRANULARITY_SEGMENT;
+	xdev->common.dev = &pdev->dev;
+
+	platform_set_drvdata(pdev, xdev);
+
+	for_each_child_of_node(node, child) {
+		ret = xilinx_dma_chan_probe(xdev, child);
+		if (ret) {
+			dev_err(&pdev->dev, "Probing channels failed\n");
+			goto free_chan_resources;
+		}
+	}
+
+	dma_async_device_register(&xdev->common);
+
+	ret = of_dma_controller_register(node, of_dma_xilinx_xlate, xdev);
+	if (ret) {
+		dev_err(&pdev->dev, "Unable to register DMA to DT\n");
+		dma_async_device_unregister(&xdev->common);
+		goto free_chan_resources;
+	}
+
+	dev_info(&pdev->dev, "Xilinx AXI DMA Engine driver Probed!!\n");
+
+	return 0;
+
+free_chan_resources:
+	for (i = 0; i < XILINX_DMA_MAX_CHANS_PER_DEVICE; i++)
+		if (xdev->chan[i])
+			xilinx_dma_chan_remove(xdev->chan[i]);
+
+	return ret;
+}
+
+/**
+ * xilinx_dma_remove - Driver remove function
+ * @pdev: Pointer to the platform_device structure
+ *
+ * Return: Always '0'
+ */
+static int xilinx_dma_remove(struct platform_device *pdev)
+{
+	struct xilinx_dma_device *xdev = platform_get_drvdata(pdev);
+	int i;
+
+	of_dma_controller_free(pdev->dev.of_node);
+	dma_async_device_unregister(&xdev->common);
+
+	for (i = 0; i < XILINX_DMA_MAX_CHANS_PER_DEVICE; i++)
+		if (xdev->chan[i])
+			xilinx_dma_chan_remove(xdev->chan[i]);
+
+	return 0;
+}
+
+static const struct of_device_id xilinx_dma_of_match[] = {
+	{ .compatible = "xlnx,axi-dma-1.00.a",},
+	{}
+};
+MODULE_DEVICE_TABLE(of, xilinx_dma_of_match);
+
+static struct platform_driver xilinx_dma_driver = {
+	.driver = {
+		.name = "xilinx-dma",
+		.of_match_table = xilinx_dma_of_match,
+	},
+	.probe = xilinx_dma_probe,
+	.remove = xilinx_dma_remove,
+};
+
+module_platform_driver(xilinx_dma_driver);
+
+MODULE_AUTHOR("Xilinx, Inc.");
+MODULE_DESCRIPTION("Xilinx DMA driver");
+MODULE_LICENSE("GPL");
-- 
2.1.2



From eric.auger at linaro.org  Mon Aug 17 08:38:16 2015
From: eric.auger at linaro.org (Eric Auger)
Date: Mon, 17 Aug 2015 17:38:16 +0200
Subject: [PATCH v3 04/10] VFIO: platform: add vfio_platform_set_automasked
In-Reply-To: <1439405794.4023.528.camel@redhat.com>
References: <1439212864-12954-1-git-send-email-eric.auger@linaro.org>	
 <1439212864-12954-5-git-send-email-eric.auger@linaro.org>
 <1439405794.4023.528.camel@redhat.com>
Message-ID: <55D1FFE8.9050104@linaro.org>

On 08/12/2015 08:56 PM, Alex Williamson wrote:
> On Mon, 2015-08-10 at 15:20 +0200, Eric Auger wrote:
>> This function makes possible to change the automasked mode.
>>
>> Signed-off-by: Eric Auger <eric.auger at linaro.org>
>>
>> ---
>>
>> v1 -> v2:
>> - set forwarded flag
>> ---
>>  drivers/vfio/platform/vfio_platform_irq.c | 19 +++++++++++++++++++
>>  1 file changed, 19 insertions(+)
>>
>> diff --git a/drivers/vfio/platform/vfio_platform_irq.c b/drivers/vfio/platform/vfio_platform_irq.c
>> index b31b1f0..a285384 100644
>> --- a/drivers/vfio/platform/vfio_platform_irq.c
>> +++ b/drivers/vfio/platform/vfio_platform_irq.c
>> @@ -186,6 +186,25 @@ static irqreturn_t vfio_handler(int irq, void *dev_id)
>>  	return ret;
>>  }
>>  
>> +static int vfio_platform_set_automasked(struct vfio_platform_irq *irq,
>> +					   bool automasked)
>> +{
>> +	unsigned long flags;
>> +
>> +	spin_lock_irqsave(&irq->lock, flags);
>> +	if (automasked) {
>> +		irq->forwarded = true;
>> +		irq->flags |= VFIO_IRQ_INFO_AUTOMASKED;
>> +		irq->handler = vfio_automasked_irq_handler;
>> +	} else {
>> +		irq->forwarded = false;
>> +		irq->flags &= ~VFIO_IRQ_INFO_AUTOMASKED;
>> +		irq->handler = vfio_irq_handler;
>> +	}
>> +	spin_unlock_irqrestore(&irq->lock, flags);
>> +	return 0;
> 
> In vfio-speak, automasked means level and we're not magically changing
> the IRQ from level to edge, we're simply able to handle level
> differently based on a hardware optimization.  Should the user visible
> flags therefore change based on this?  Aren't we really setting the
> forwarded state rather than the automasked state?

Well actually this was following the discussion we had a long time ago
about that topic:

http://lkml.iu.edu/hypermail/linux/kernel/1409.1/03659.html

I did not really know how to conclude ...

If it is preferred I can hide this to the userspace, no problem.

Eric


> 
>> +}
>> +
>>  static void vfio_platform_irq_bypass_stop(struct irq_bypass_producer *prod)
>>  {
>>  }
> 
> 
> 



From peter at hurleysoftware.com  Mon Aug 17 08:39:03 2015
From: peter at hurleysoftware.com (Peter Hurley)
Date: Mon, 17 Aug 2015 11:39:03 -0400
Subject: [PATCH 1/4] serial: xuartps: Fix termios issue for enabling odd
 parity
In-Reply-To: <5b154ba97bcd79e49e2131152eb2fc1761594a6c.1439796149.git.michal.simek@xilinx.com>
References: <5b154ba97bcd79e49e2131152eb2fc1761594a6c.1439796149.git.michal.simek@xilinx.com>
Message-ID: <55D20017.4010008@hurleysoftware.com>

On 08/17/2015 03:22 AM, Michal Simek wrote:
> From: Anirudha Sarangi <anirudha.sarangi at xilinx.com>
> 
> Existing set_termios does not handle the option for enabling
> odd parity. This patch fixes it.

NAK. PARODD does not enable parity generation or detection.

Regards,
Peter Hurley

> Signed-off-by: Anirudha Sarangi <anirudh at xilinx.com>
> Signed-off-by: Michal Simek <michal.simek at xilinx.com>
> ---
> 
>  drivers/tty/serial/xilinx_uartps.c | 2 +-
>  1 file changed, 1 insertion(+), 1 deletion(-)
> 
> diff --git a/drivers/tty/serial/xilinx_uartps.c b/drivers/tty/serial/xilinx_uartps.c
> index 009e0dbc12d2..a3020344ac9d 100644
> --- a/drivers/tty/serial/xilinx_uartps.c
> +++ b/drivers/tty/serial/xilinx_uartps.c
> @@ -723,7 +723,7 @@ static void cdns_uart_set_termios(struct uart_port *port,
>  	else
>  		cval |= CDNS_UART_MR_STOPMODE_1_BIT; /* 1 STOP bit */
>  
> -	if (termios->c_cflag & PARENB) {
> +	if ((termios->c_cflag & PARENB) || (termios->c_cflag & PARODD)) {
>  		/* Mark or Space parity */
>  		if (termios->c_cflag & CMSPAR) {
>  			if (termios->c_cflag & PARODD)
> 



From eric.auger at linaro.org  Mon Aug 17 08:39:57 2015
From: eric.auger at linaro.org (Eric Auger)
Date: Mon, 17 Aug 2015 17:39:57 +0200
Subject: [PATCH v3 05/10] VFIO: platform: add vfio_platform_is_active
In-Reply-To: <1439405805.4023.529.camel@redhat.com>
References: <1439212864-12954-1-git-send-email-eric.auger@linaro.org>	
 <1439212864-12954-6-git-send-email-eric.auger@linaro.org>
 <1439405805.4023.529.camel@redhat.com>
Message-ID: <55D2004D.9010401@linaro.org>

On 08/12/2015 08:56 PM, Alex Williamson wrote:
> On Mon, 2015-08-10 at 15:20 +0200, Eric Auger wrote:
>> This function returns whether the IRQ is active at irqchip level or
>> VFIO masked. If either is true, it is considered the IRQ is active.
>> Currently there is no way to differentiate userspace masked IRQ from
>> automasked IRQ. There might be false detection of activity. However
>> it is currently acceptable to have false detection.
>>
>> Signed-off-by: Eric Auger <eric.auger at linaro.org>
>>
>> ---
>> ---
>>  drivers/vfio/platform/vfio_platform_irq.c | 17 +++++++++++++++++
>>  1 file changed, 17 insertions(+)
>>
>> diff --git a/drivers/vfio/platform/vfio_platform_irq.c b/drivers/vfio/platform/vfio_platform_irq.c
>> index a285384..efaee58 100644
>> --- a/drivers/vfio/platform/vfio_platform_irq.c
>> +++ b/drivers/vfio/platform/vfio_platform_irq.c
>> @@ -205,6 +205,23 @@ static int vfio_platform_set_automasked(struct vfio_platform_irq *irq,
>>  	return 0;
>>  }
>>  
>> +static int vfio_platform_is_active(struct vfio_platform_irq *irq)
> 
> vfio_platform_irq_is_active()?
OK
> 
>> +{
>> +	unsigned long flags;
>> +	bool active, masked, outstanding;
>> +	int ret;
>> +
>> +	spin_lock_irqsave(&irq->lock, flags);
>> +
>> +	ret = irq_get_irqchip_state(irq->hwirq, IRQCHIP_STATE_ACTIVE, &active);
>> +	BUG_ON(ret);
> 
> Why can't we propagate this error to the caller and let them decide?
sure

Eric
> 
>> +	masked = irq->masked;
>> +	outstanding = active || masked;
>> +
>> +	spin_unlock_irqrestore(&irq->lock, flags);
>> +	return outstanding;
>> +}
>> +
>>  static void vfio_platform_irq_bypass_stop(struct irq_bypass_producer *prod)
>>  {
>>  }
> 
> 
> 



From grygorii.strashko at ti.com  Mon Aug 17 08:46:36 2015
From: grygorii.strashko at ti.com (Grygorii Strashko)
Date: Mon, 17 Aug 2015 18:46:36 +0300
Subject: [4.1.3-rt3] [report][suspend to ram] BUG: sleeping function called
 from invalid context at kernel/locking/rtmutex.c:917
In-Reply-To: <20150816114241.GC7004@linutronix.de>
References: <55CB8FAE.9020309@ti.com> <20150816114241.GC7004@linutronix.de>
Message-ID: <55D201DC.5070604@ti.com>

Hi Sebastian,

On 08/16/2015 02:42 PM, Sebastian Andrzej Siewior wrote:
> * Grygorii Strashko | 2015-08-12 21:25:50 [+0300]:
>>
>> I can constantly see below error report with RT-kernel on TI ARM dra7-evm
>> if I'm trying to do Suspend to RAM.
> 
> do you see the same problem on x86 with -RT?

Unfortunately, I'm not working with x86 now, and I'm not sure I'll be able
to try it in the nearest future.

Below, I've tried to analyze involved code path and it seems expected 
to call clear_tasks_mm_cpumask() in atomic context, as the whole 
take_cpu_down() call chain expected to be atomic.

> 
>> Disabling non-boot CPUs ...
>> PM: noirq suspend of devices complete after 7.295 msecs
>> [  100.285729] Disabling non-boot CPUs ...
>> [  100.287575] BUG: sleeping function called from invalid context at kernel/locking/rtmutex.c:917
>> [  100.287580] in_atomic(): 1, irqs_disabled(): 128, pid: 18, name: migration/1
>> [  100.287583] INFO: lockdep is turned off.
>> [  100.287586] irq event stamp: 122
>> [  100.287600] hardirqs last  enabled at (121): [<c06ac0ac>] _raw_spin_unlock_irqrestore+0x88/0x90
>> [  100.287609] hardirqs last disabled at (122): [<c06abed0>] _raw_spin_lock_irq+0x28/0x5c
>> [  100.287620] softirqs last  enabled at (0): [<c003d294>] copy_process.part.52+0x410/0x19d8
>> [  100.287625] softirqs last disabled at (0): [<  (null)>]   (null)
>> [  100.287630] Preemption disabled at:[<  (null)>]   (null)
>> [  100.287631]
>> [  100.287639] CPU: 1 PID: 18 Comm: migration/1 Tainted: G        W       4.1.4-rt3-01046-g96ac8da #204
>> [  100.287642] Hardware name: Generic DRA74X (Flattened Device Tree)
>> [  100.287659] [<c0019134>] (unwind_backtrace) from [<c0014774>] (show_stack+0x20/0x24)
>> [  100.287671] [<c0014774>] (show_stack) from [<c06a70f4>] (dump_stack+0x88/0xdc)
>> [  100.287681] [<c06a70f4>] (dump_stack) from [<c006cab8>] (___might_sleep+0x198/0x2a8)
>> [  100.287689] [<c006cab8>] (___might_sleep) from [<c06ac4dc>] (rt_spin_lock+0x30/0x70)
>> [  100.287699] [<c06ac4dc>] (rt_spin_lock) from [<c013f790>] (find_lock_task_mm+0x9c/0x174)
> 
> this is task_lock() which takes a sleeping lock.
> 
>> [  100.287710] [<c013f790>] (find_lock_task_mm) from [<c00409ac>] (clear_tasks_mm_cpumask+0xb4/0x1ac)
>> [  100.287720] [<c00409ac>] (clear_tasks_mm_cpumask) from [<c00166a4>] (__cpu_disable+0x98/0xbc)
>> [  100.287728] [<c00166a4>] (__cpu_disable) from [<c06a2e8c>] (take_cpu_down+0x1c/0x50)
>> [  100.287742] [<c06a2e8c>] (take_cpu_down) from [<c00f2600>] (multi_cpu_stop+0x11c/0x158)
>> [  100.287754] [<c00f2600>] (multi_cpu_stop) from [<c00f2a9c>] (cpu_stopper_thread+0xc4/0x184)
> 
> this function contains local_save_flags().

multi_cpu_stop:
	local_save_flags(flags);

	if (!msdata->active_cpus)
		is_active = cpu == cpumask_first(cpu_online_mask);
	else
		is_active = cpumask_test_cpu(cpu, msdata->active_cpus);

	/* Simple state machine */
	do {
		/* Chill out and ensure we re-read multi_stop_state. */
		cpu_relax();
		if (msdata->state != curstate) {
			curstate = msdata->state;
			switch (curstate) {
			case MULTI_STOP_DISABLE_IRQ:
				local_irq_disable();
				hard_irq_disable(); <==== Step 2 disable IRQs
				break;
			case MULTI_STOP_RUN:
				if (is_active)
					err = msdata->fn(msdata->data); ===> Step 3 take_cpu_down()
				break;
			default:
				break;
			}
			ack_state(msdata);
		}
	} while (curstate != MULTI_STOP_EXIT);

	local_irq_restore(flags);

> 
>> [  100.287767] [<c00f2a9c>] (cpu_stopper_thread) from [<c0069058>] (smpboot_thread_fn+0x18c/0x324)

cpu_stopper_thread:
		preempt_disable();

		ret = fn(arg); ===> multi_cpu_stop()
		if (ret)
			done->ret = ret;

		preempt_enable();


>> [  100.287779] [<c0069058>] (smpboot_thread_fn) from [<c00649c4>] (kthread+0xe8/0x104)
>> [  100.287791] [<c00649c4>] (kthread) from [<c0010058>] (ret_from_fork+0x14/0x3c)
>> [  100.288114] CPU1: shutdown
> 
> The local_save_flags() should be probably replaced with something else.
> 

Below is list of clear_tasks_mm_cpumask() users:
arch/arm/kernel/smp.c
  int __cpu_disable(void)
  216: clear_tasks_mm_cpumask(cpu); 
arch/arm64/kernel/smp.c
  int __cpu_disable(void)
  238: clear_tasks_mm_cpumask(cpu); 
arch/metag/kernel/smp.c
  int __cpu_disable(void)
  290: clear_tasks_mm_cpumask(cpu); 

arch/powerpc/mm/mmu_context_nohash.c
_cpu_down()
+ cpu_notify_nofail(CPU_DEAD | mod, hcpu);
  + mmu_context_cpu_notify()
    400: clear_tasks_mm_cpumask(cpu); 

arch/sh/kernel/smp.c
  int __cpu_disable(void)
  155: clear_tasks_mm_cpumask(cpu); 
arch/xtensa/kernel/smp.c
  int __cpu_disable(void)
  279: clear_tasks_mm_cpumask(cpu); 

As per above, in all case, except *powerpc*, the clear_tasks_mm_cpumask()
is called from __cpu_disable() (atomic context).
While in powerpc case it's called from  _cpu_down() (if I understand right,
in non-atomic context).

Commit which adds clear_tasks_mm_cpumask() call for arm is below:

commit 3eaa73bde2fb475b731a0fde7dd11c3ecfb8679c
Author: Anton Vorontsov <anton.vorontsov at linaro.org>
Date:   Thu May 31 16:26:22 2012 -0700

    arm: use clear_tasks_mm_cpumask()
    
    Checking for process->mm is not enough because process' main thread may
    exit or detach its mm via use_mm(), but other threads may still have a
    valid mm.
    
    To fix this we would need to use find_lock_task_mm(), which would walk up
    all threads and returns an appropriate task (with task lock held).
    
    clear_tasks_mm_cpumask() has this issue fixed, so let's use it.
    
    Suggested-by: Oleg Nesterov <oleg at redhat.com>
    Signed-off-by: Anton Vorontsov <anton.vorontsov at linaro.org>
    Cc: Russell King <rmk at arm.linux.org.uk>
    Signed-off-by: Andrew Morton <akpm at linux-foundation.org>
    Signed-off-by: Linus Torvalds <torvalds at linux-foundation.org>

diff --git a/arch/arm/kernel/smp.c b/arch/arm/kernel/smp.c
index b735521..2c7217d 100644
--- a/arch/arm/kernel/smp.c
+++ b/arch/arm/kernel/smp.c
@@ -109,7 +109,6 @@ static void percpu_timer_stop(void);
 int __cpu_disable(void)
 {
        unsigned int cpu = smp_processor_id();
-       struct task_struct *p;
        int ret;
 
        ret = platform_cpu_disable(cpu);
@@ -139,12 +138,7 @@ int __cpu_disable(void)
        flush_cache_all();
        local_flush_tlb_all();
 
-       read_lock(&tasklist_lock);
-       for_each_process(p) {
-               if (p->mm)
-                       cpumask_clear_cpu(cpu, mm_cpumask(p->mm));
-       }
-       read_unlock(&tasklist_lock);
+       clear_tasks_mm_cpumask(cpu);
 
        return 0;
 }

Thanks for your reply.

-- 
regards,
-grygorii


From peter at hurleysoftware.com  Mon Aug 17 08:49:43 2015
From: peter at hurleysoftware.com (Peter Hurley)
Date: Mon, 17 Aug 2015 11:49:43 -0400
Subject: [PATCH 2/4] serial: xuartps: Do not handle overrun errors under
 IGNPAR option
In-Reply-To: <41df6eb35d69801afa5b686a6974e3c3bf65178a.1439796149.git.michal.simek@xilinx.com>
References: <5b154ba97bcd79e49e2131152eb2fc1761594a6c.1439796149.git.michal.simek@xilinx.com>
 <41df6eb35d69801afa5b686a6974e3c3bf65178a.1439796149.git.michal.simek@xilinx.com>
Message-ID: <55D20297.6010500@hurleysoftware.com>

On 08/17/2015 03:22 AM, Michal Simek wrote:
> From: Anirudha Sarangi <anirudha.sarangi at xilinx.com>
> 
> The existing implementation includes overrun errors under IGNPAR
> option. This patch fixes it by including only parity and framing
> error under IGNPAR option.

The convention adopted by Linux serial drivers is to ignore overrun
errors if both IGNPAR and IGNBRK are set.

Regards,
Peter Hurley

> Signed-off-by: Anirudha Sarangi <anirudh at xilinx.com>
> Signed-off-by: Michal Simek <michal.simek at xilinx.com>
> ---
> 
>  drivers/tty/serial/xilinx_uartps.c | 2 +-
>  1 file changed, 1 insertion(+), 1 deletion(-)
> 
> diff --git a/drivers/tty/serial/xilinx_uartps.c b/drivers/tty/serial/xilinx_uartps.c
> index a3020344ac9d..c4437e8929ff 100644
> --- a/drivers/tty/serial/xilinx_uartps.c
> +++ b/drivers/tty/serial/xilinx_uartps.c
> @@ -691,7 +691,7 @@ static void cdns_uart_set_termios(struct uart_port *port,
>  
>  	if (termios->c_iflag & IGNPAR)
>  		port->ignore_status_mask |= CDNS_UART_IXR_PARITY |
> -			CDNS_UART_IXR_FRAMING | CDNS_UART_IXR_OVERRUN;
> +					    CDNS_UART_IXR_FRAMING;
>  
>  	/* ignore all characters if CREAD is not set */
>  	if ((termios->c_cflag & CREAD) == 0)
> 



From eric.auger at linaro.org  Mon Aug 17 08:51:49 2015
From: eric.auger at linaro.org (Eric Auger)
Date: Mon, 17 Aug 2015 17:51:49 +0200
Subject: [PATCH v3 06/10] VFIO: platform: add irq bypass producer
 management
In-Reply-To: <1439405812.4023.530.camel@redhat.com>
References: <1439212864-12954-1-git-send-email-eric.auger@linaro.org>	
 <1439212864-12954-7-git-send-email-eric.auger@linaro.org>
 <1439405812.4023.530.camel@redhat.com>
Message-ID: <55D20315.9000008@linaro.org>

Hi Alex,
On 08/12/2015 08:56 PM, Alex Williamson wrote:
> On Mon, 2015-08-10 at 15:21 +0200, Eric Auger wrote:
>> This patch populates the IRQ bypass callacks:
>> - stop/start producer simply consist in disabling/enabling the host irq
>> - add/del consumer: basically set the automasked flag to false/true
>>
>> Signed-off-by: Eric Auger <eric.auger at linaro.org>
>>
>> ---
>> v2 -> v3:
>> - vfio_platform_irq_bypass_add_consumer now returns an error in case
>>   the IRQ is recognized as active
>> - active boolean not set anymore
>> - do not VFIO mask the IRQ anymore on unforward
>>
>> v1 -> v2:
>> - device handle caching in vfio_platform_device is introduced in a
>>   separate patch
>> - use container_of
>> ---
>>  drivers/vfio/platform/vfio_platform_irq.c | 23 ++++++++++++++++++++++-
>>  1 file changed, 22 insertions(+), 1 deletion(-)
>>
>> diff --git a/drivers/vfio/platform/vfio_platform_irq.c b/drivers/vfio/platform/vfio_platform_irq.c
>> index efaee58..400a188 100644
>> --- a/drivers/vfio/platform/vfio_platform_irq.c
>> +++ b/drivers/vfio/platform/vfio_platform_irq.c
>> @@ -224,23 +224,44 @@ static int vfio_platform_is_active(struct vfio_platform_irq *irq)
>>  
>>  static void vfio_platform_irq_bypass_stop(struct irq_bypass_producer *prod)
>>  {
>> +	disable_irq(prod->irq);
>>  }
>>  
>>  static void vfio_platform_irq_bypass_start(struct irq_bypass_producer *prod)
>>  {
>> +	enable_irq(prod->irq);
>>  }
>>  
>>  static int vfio_platform_irq_bypass_add_consumer(
>>  			struct irq_bypass_producer *prod,
>>  			struct irq_bypass_consumer *cons)
>>  {
>> -	return 0;
>> +	struct vfio_platform_irq *irq =
>> +		container_of(prod, struct vfio_platform_irq, producer);
>> +
>> +	/*
>> +	 * if the IRQ is active at irqchip level or VFIO (auto)masked
>> +	 * this means the host IRQ is already under injection in the
>> +	 * guest and this not safe to change the forwarding state at
>> +	 * that stage.
>> +	 * It is not possible to differentiate user-space masking
>> +	 * from auto-masking, leading to possible false detection of
>> +	 * active state.
>> +	 */
>> +	if (vfio_platform_is_active(irq))
>> +		return -EAGAIN;
> 
> Here's an example of why we don't want WARN_ON if a registration fails,
> this is effectively random.  When and how is a re-try going to happen?
To be honest I did not intend to implement any retry mechanism. I rather
intended to change the user-side which currently is not adapted to that
start-up. Typically with current QEMU code we have this 2 phase IRQ
signal startup, first set up eventfd signaling, then VFIO mask, then
turn irqfd on. With such sequence forwarding setup will fail because the
IRQ is seen as masked (false detection of activity).

Do you mandate such a retry mechanism? If forwarding fails we resort on
standard irqfd ...

I think forwarding setup should be as much static as possible (I think
this opinion also is shared by Marc?).

Please let me know your opinion on this.

Best Regards

Eric

> 
>> +
>> +	return vfio_platform_set_automasked(irq, false);
> 
> set_forwarded just seems so much more logical here.
> 
>>  }
>>  
>>  static void vfio_platform_irq_bypass_del_consumer(
>>  			struct irq_bypass_producer *prod,
>>  			struct irq_bypass_consumer *cons)
>>  {
>> +	struct vfio_platform_irq *irq =
>> +		container_of(prod, struct vfio_platform_irq, producer);
>> +
>> +	vfio_platform_set_automasked(irq, true);
>>  }
>>  
>>  static int vfio_set_trigger(struct vfio_platform_device *vdev, int index,
> 
> 
> 



From maitysanchayan at gmail.com  Mon Aug 17 08:51:40 2015
From: maitysanchayan at gmail.com (Sanchayan Maity)
Date: Mon, 17 Aug 2015 21:21:40 +0530
Subject: [PATCH v4] iio: adc: vf610: Add IIO buffer support for Vybrid ADC
In-Reply-To: <d556443a26070be505f9a5f5f0999253b73d9b71.1439283162.git.maitysanchayan@gmail.com>
References: <d556443a26070be505f9a5f5f0999253b73d9b71.1439283162.git.maitysanchayan@gmail.com>
Message-ID: <9be567ec7d6f6370dd42a41438d64cf7aaa47635.1439826018.git.maitysanchayan@gmail.com>

This patch adds support for IIO buffer to the Vybrid ADC driver.
IIO triggered buffer infrastructure along with iio sysfs trigger
is used to leverage continuous sampling support provided by the
ADC block.

Signed-off-by: Sanchayan Maity <maitysanchayan at gmail.com>
---

Changes since v3:
Fix iio_buffer_setup_ops for postenable and predisable functions
to match pairwise. Before this the predisable work was being done
in postdisable.

Changes since v2:
1. Fix the wrong buffer size for statically allocated buffer
2. Drop the use of .address field from the iio_chan_spec
3. Use iio_buffer_enabled call inside the lock
4. Drop wrapper function around iio_trigered_* function calls
5. Drop Kconfig select of sysfs trigger
6. Drop Kconfig select IIO_TRIGGER as it is already selected by
IIO_TRIGGERED_BUFFER

Changes since v1:
1. Use a fixed size buffer instead of kmalloc allocated during update
scan mode
2. Remove a write to read only register ADC_HS (COCO bit)

 drivers/iio/adc/Kconfig     |   2 +
 drivers/iio/adc/vf610_adc.c | 105 +++++++++++++++++++++++++++++++++++++++++---
 2 files changed, 100 insertions(+), 7 deletions(-)

diff --git a/drivers/iio/adc/Kconfig b/drivers/iio/adc/Kconfig
index 7c55658..660f790 100644
--- a/drivers/iio/adc/Kconfig
+++ b/drivers/iio/adc/Kconfig
@@ -337,6 +337,8 @@ config TWL6030_GPADC
 config VF610_ADC
 	tristate "Freescale vf610 ADC driver"
 	depends on OF
+	select IIO_BUFFER
+	select IIO_TRIGGERED_BUFFER
 	help
 	  Say yes here to support for Vybrid board analog-to-digital converter.
 	  Since the IP is used for i.MX6SLX, the driver also support i.MX6SLX.
diff --git a/drivers/iio/adc/vf610_adc.c b/drivers/iio/adc/vf610_adc.c
index 23b8fb9..887a7ba 100644
--- a/drivers/iio/adc/vf610_adc.c
+++ b/drivers/iio/adc/vf610_adc.c
@@ -34,8 +34,11 @@
 #include <linux/err.h>
 
 #include <linux/iio/iio.h>
+#include <linux/iio/buffer.h>
 #include <linux/iio/sysfs.h>
-#include <linux/iio/driver.h>
+#include <linux/iio/trigger.h>
+#include <linux/iio/trigger_consumer.h>
+#include <linux/iio/triggered_buffer.h>
 
 /* This will be the driver name the kernel reports */
 #define DRIVER_NAME "vf610-adc"
@@ -170,6 +173,7 @@ struct vf610_adc {
 	u32 sample_freq_avail[5];
 
 	struct completion completion;
+	u16 buffer[8];
 };
 
 static const u32 vf610_hw_avgs[] = { 1, 4, 8, 16, 32 };
@@ -505,12 +509,24 @@ static const struct iio_chan_spec_ext_info vf610_ext_info[] = {
 	.info_mask_shared_by_type = BIT(IIO_CHAN_INFO_SCALE) |	\
 				BIT(IIO_CHAN_INFO_SAMP_FREQ),	\
 	.ext_info = vf610_ext_info,				\
+	.scan_index = (_idx),			\
+	.scan_type = {					\
+		.sign = 'u',				\
+		.realbits = 12,				\
+		.storagebits = 16,			\
+	},						\
 }
 
 #define VF610_ADC_TEMPERATURE_CHAN(_idx, _chan_type) {	\
 	.type = (_chan_type),	\
 	.channel = (_idx),		\
 	.info_mask_separate = BIT(IIO_CHAN_INFO_PROCESSED),	\
+	.scan_index = (_idx),					\
+	.scan_type = {						\
+		.sign = 'u',					\
+		.realbits = 12,					\
+		.storagebits = 16,				\
+	},							\
 }
 
 static const struct iio_chan_spec vf610_adc_iio_channels[] = {
@@ -531,6 +547,7 @@ static const struct iio_chan_spec vf610_adc_iio_channels[] = {
 	VF610_ADC_CHAN(14, IIO_VOLTAGE),
 	VF610_ADC_CHAN(15, IIO_VOLTAGE),
 	VF610_ADC_TEMPERATURE_CHAN(26, IIO_TEMP),
+	IIO_CHAN_SOFT_TIMESTAMP(32),
 	/* sentinel */
 };
 
@@ -559,13 +576,20 @@ static int vf610_adc_read_data(struct vf610_adc *info)
 
 static irqreturn_t vf610_adc_isr(int irq, void *dev_id)
 {
-	struct vf610_adc *info = (struct vf610_adc *)dev_id;
+	struct iio_dev *indio_dev = (struct iio_dev *)dev_id;
+	struct vf610_adc *info = iio_priv(indio_dev);
 	int coco;
 
 	coco = readl(info->regs + VF610_REG_ADC_HS);
 	if (coco & VF610_ADC_HS_COCO0) {
 		info->value = vf610_adc_read_data(info);
-		complete(&info->completion);
+		if (iio_buffer_enabled(indio_dev)) {
+			info->buffer[0] = info->value;
+			iio_push_to_buffers_with_timestamp(indio_dev,
+					info->buffer, iio_get_time_ns());
+			iio_trigger_notify_done(indio_dev->trig);
+		} else
+			complete(&info->completion);
 	}
 
 	return IRQ_HANDLED;
@@ -613,8 +637,12 @@ static int vf610_read_raw(struct iio_dev *indio_dev,
 	case IIO_CHAN_INFO_RAW:
 	case IIO_CHAN_INFO_PROCESSED:
 		mutex_lock(&indio_dev->mlock);
-		reinit_completion(&info->completion);
+		if (iio_buffer_enabled(indio_dev)) {
+			mutex_unlock(&indio_dev->mlock);
+			return -EBUSY;
+		}
 
+		reinit_completion(&info->completion);
 		hc_cfg = VF610_ADC_ADCHC(chan->channel);
 		hc_cfg |= VF610_ADC_AIEN;
 		writel(hc_cfg, info->regs + VF610_REG_ADC_HC0);
@@ -694,6 +722,60 @@ static int vf610_write_raw(struct iio_dev *indio_dev,
 	return -EINVAL;
 }
 
+static int vf610_adc_buffer_postenable(struct iio_dev *indio_dev)
+{
+	struct vf610_adc *info = iio_priv(indio_dev);
+	unsigned int channel;
+	int ret;
+	int val;
+
+	ret = iio_triggered_buffer_postenable(indio_dev);
+	if (ret)
+		return ret;
+
+	val = readl(info->regs + VF610_REG_ADC_GC);
+	val |= VF610_ADC_ADCON;
+	writel(val, info->regs + VF610_REG_ADC_GC);
+
+	channel = find_first_bit(indio_dev->active_scan_mask,
+						indio_dev->masklength);
+
+	val = VF610_ADC_ADCHC(channel);
+	val |= VF610_ADC_AIEN;
+
+	writel(val, info->regs + VF610_REG_ADC_HC0);
+
+	return 0;
+}
+
+static int vf610_adc_buffer_predisable(struct iio_dev *indio_dev)
+{
+	struct vf610_adc *info = iio_priv(indio_dev);
+	unsigned int hc_cfg = 0;
+	int val, ret;
+
+	val = readl(info->regs + VF610_REG_ADC_GC);
+	val &= ~VF610_ADC_ADCON;
+	writel(val, info->regs + VF610_REG_ADC_GC);
+
+	hc_cfg |= VF610_ADC_CONV_DISABLE;
+	hc_cfg &= ~VF610_ADC_AIEN;
+
+	writel(hc_cfg, info->regs + VF610_REG_ADC_HC0);
+
+	ret = iio_triggered_buffer_predisable(indio_dev);
+	if (ret)
+		return ret;
+
+	return 0;
+}
+
+static const struct iio_buffer_setup_ops iio_triggered_buffer_setup_ops = {
+	.postenable = &vf610_adc_buffer_postenable,
+	.predisable = &vf610_adc_buffer_predisable,
+	.validate_scan_mask = &iio_validate_scan_mask_onehot,
+};
+
 static int vf610_adc_reg_access(struct iio_dev *indio_dev,
 			unsigned reg, unsigned writeval,
 			unsigned *readval)
@@ -753,7 +835,7 @@ static int vf610_adc_probe(struct platform_device *pdev)
 
 	ret = devm_request_irq(info->dev, irq,
 				vf610_adc_isr, 0,
-				dev_name(&pdev->dev), info);
+				dev_name(&pdev->dev), indio_dev);
 	if (ret < 0) {
 		dev_err(&pdev->dev, "failed requesting irq, irq = %d\n", irq);
 		return ret;
@@ -806,15 +888,23 @@ static int vf610_adc_probe(struct platform_device *pdev)
 	vf610_adc_cfg_init(info);
 	vf610_adc_hw_init(info);
 
+	ret = iio_triggered_buffer_setup(indio_dev, &iio_pollfunc_store_time,
+					NULL, &iio_triggered_buffer_setup_ops);
+	if (ret < 0) {
+		dev_err(&pdev->dev, "Couldn't initialise the buffer\n");
+		goto error_iio_device_register;
+	}
+
 	ret = iio_device_register(indio_dev);
 	if (ret) {
 		dev_err(&pdev->dev, "Couldn't register the device.\n");
-		goto error_iio_device_register;
+		goto error_adc_buffer_init;
 	}
 
 	return 0;
 
-
+error_adc_buffer_init:
+	iio_triggered_buffer_cleanup(indio_dev);
 error_iio_device_register:
 	clk_disable_unprepare(info->clk);
 error_adc_clk_enable:
@@ -829,6 +919,7 @@ static int vf610_adc_remove(struct platform_device *pdev)
 	struct vf610_adc *info = iio_priv(indio_dev);
 
 	iio_device_unregister(indio_dev);
+	iio_triggered_buffer_cleanup(indio_dev);
 	regulator_disable(info->vref);
 	clk_disable_unprepare(info->clk);
 
-- 
2.5.0



From anirudha.sarangi at xilinx.com  Mon Aug 17 08:55:10 2015
From: anirudha.sarangi at xilinx.com (Anirudha Sarangi)
Date: Mon, 17 Aug 2015 15:55:10 +0000
Subject: [PATCH 1/4] serial: xuartps: Fix termios issue for enabling odd
 parity
In-Reply-To: <55D20017.4010008@hurleysoftware.com>
References: <5b154ba97bcd79e49e2131152eb2fc1761594a6c.1439796149.git.michal.simek@xilinx.com>
 <55D20017.4010008@hurleysoftware.com>
Message-ID: <59506B47DEDD3943ABF9AC60020F4E2978D6E7EA@XAP-PVEXMBX02.xlnx.xilinx.com>

Hi,

> -----Original Message-----
> From: Peter Hurley [mailto:peter at hurleysoftware.com]
> Sent: Monday, August 17, 2015 9:09 PM
> To: Michal Simek
> Cc: linux-kernel at vger.kernel.org; monstr at monstr.eu; Anirudha Sarangi; Soren
> Brinkmann; Jiri Slaby; linux-serial at vger.kernel.org; Greg Kroah-Hartman; linux-
> arm-kernel at lists.infradead.org
> Subject: Re: [PATCH 1/4] serial: xuartps: Fix termios issue for enabling odd parity
>
> On 08/17/2015 03:22 AM, Michal Simek wrote:
> > From: Anirudha Sarangi <anirudha.sarangi at xilinx.com>
> >
> > Existing set_termios does not handle the option for enabling odd
> > parity. This patch fixes it.
>
> NAK. PARODD does not enable parity generation or detection.
>
What if someone is trying to change from even to odd parity?
In this conditional case, we setup some register bit for the same.
Is the above use case not a valid one?

Regards
Anirudha

> Regards,
> Peter Hurley
>
> > Signed-off-by: Anirudha Sarangi <anirudh at xilinx.com>
> > Signed-off-by: Michal Simek <michal.simek at xilinx.com>
> > ---
> >
> >  drivers/tty/serial/xilinx_uartps.c | 2 +-
> >  1 file changed, 1 insertion(+), 1 deletion(-)
> >
> > diff --git a/drivers/tty/serial/xilinx_uartps.c
> > b/drivers/tty/serial/xilinx_uartps.c
> > index 009e0dbc12d2..a3020344ac9d 100644
> > --- a/drivers/tty/serial/xilinx_uartps.c
> > +++ b/drivers/tty/serial/xilinx_uartps.c
> > @@ -723,7 +723,7 @@ static void cdns_uart_set_termios(struct uart_port
> *port,
> >     else
> >             cval |= CDNS_UART_MR_STOPMODE_1_BIT; /* 1 STOP bit */
> >
> > -   if (termios->c_cflag & PARENB) {
> > +   if ((termios->c_cflag & PARENB) || (termios->c_cflag & PARODD)) {
> >             /* Mark or Space parity */
> >             if (termios->c_cflag & CMSPAR) {
> >                     if (termios->c_cflag & PARODD)
> >



This email and any attachments are intended for the sole use of the named recipient(s) and contain(s) confidential information that may be proprietary, privileged or copyrighted under applicable law. If you are not the intended recipient, do not read, copy, or forward this email message or any attachments. Delete this email message and any attachments immediately.


From peter at hurleysoftware.com  Mon Aug 17 08:55:59 2015
From: peter at hurleysoftware.com (Peter Hurley)
Date: Mon, 17 Aug 2015 11:55:59 -0400
Subject: [PATCH 4/4] serial: xuartps: Rewrite the interrupt handling logic
In-Reply-To: <ead0c38140e815133a47797a2527229a2fc077c1.1439796149.git.michal.simek@xilinx.com>
References: <5b154ba97bcd79e49e2131152eb2fc1761594a6c.1439796149.git.michal.simek@xilinx.com>
 <ead0c38140e815133a47797a2527229a2fc077c1.1439796149.git.michal.simek@xilinx.com>
Message-ID: <55D2040F.1010205@hurleysoftware.com>

On 08/17/2015 03:22 AM, Michal Simek wrote:
> From: Anirudha Sarangi <anirudha.sarangi at xilinx.com>
> 
> The existing interrupt handling logic has followins issues.
> - Upon a parity error with default configuration, the control
>   never comes out of the ISR thereby hanging Linux.
> - The error handling logic around framing and parity error are buggy.
>   There are chances that the errors will never be captured.
> - The existing ISR is just too long.
> This patch fixes all these concerns.

This patch is unreviewable. Please break this down into multiple patches.

Regards,
Peter Hurley

> It separates out the Tx and Rx
> hanling logic into separate functions. It ensures that the status
> registers are cleared on all cases so that a hang situation never
> arises.
> 
> Signed-off-by: Anirudha Sarangi <anirudh at xilinx.com>
> Signed-off-by: Michal Simek <michal.simek at xilinx.com>
> ---
> 
>  drivers/tty/serial/xilinx_uartps.c | 194 ++++++++++++++++++++-----------------
>  1 file changed, 104 insertions(+), 90 deletions(-)
> 
> diff --git a/drivers/tty/serial/xilinx_uartps.c b/drivers/tty/serial/xilinx_uartps.c
> index 2dc26e5f1384..c771dbbf6161 100644
> --- a/drivers/tty/serial/xilinx_uartps.c
> +++ b/drivers/tty/serial/xilinx_uartps.c
> @@ -173,61 +173,86 @@ struct cdns_uart {
>  		clk_rate_change_nb);
>  
>  /**
> - * cdns_uart_isr - Interrupt handler
> - * @irq: Irq number
> - * @dev_id: Id of the port
> - *
> - * Return: IRQHANDLED
> + * cdns_uart_handle_tx - Handle the bytes to be Txed.
> + * @dev_id: Id of the UART port
> + * Return: None
>   */
> -static irqreturn_t cdns_uart_isr(int irq, void *dev_id)
> +static void cdns_uart_handle_tx(void *dev_id)
>  {
>  	struct uart_port *port = (struct uart_port *)dev_id;
> -	unsigned long flags;
> -	unsigned int isrstatus, numbytes;
> -	unsigned int data;
> -	char status = TTY_NORMAL;
> +	unsigned int numbytes;
>  
> -	spin_lock_irqsave(&port->lock, flags);
> +	if (uart_circ_empty(&port->state->xmit)) {
> +		writel(CDNS_UART_IXR_TXEMPTY, port->membase +
> +		       CDNS_UART_IDR_OFFSET);
> +	} else {
> +		numbytes = port->fifosize;
> +		/* Break if no more data available in the UART buffer */
> +		while (numbytes--) {
> +			if (uart_circ_empty(&port->state->xmit))
> +				break;
> +			/*
> +			 * Get the data from the UART circular buffer
> +			 * and write it to the cdns_uart's TX_FIFO
> +			 * register.
> +			 */
> +			writel(port->state->xmit.buf[port->state->xmit.tail],
> +			       port->membase + CDNS_UART_FIFO_OFFSET);
>  
> -	/* Read the interrupt status register to determine which
> -	 * interrupt(s) is/are active.
> -	 */
> -	isrstatus = readl(port->membase + CDNS_UART_ISR_OFFSET);
> +			port->icount.tx++;
>  
> -	/*
> -	 * There is no hardware break detection, so we interpret framing
> -	 * error with all-zeros data as a break sequence. Most of the time,
> -	 * there's another non-zero byte at the end of the sequence.
> -	 */
> -	if (isrstatus & CDNS_UART_IXR_FRAMING) {
> -		while (!(readl(port->membase + CDNS_UART_SR_OFFSET) &
> -					CDNS_UART_SR_RXEMPTY)) {
> -			if (!readl(port->membase + CDNS_UART_FIFO_OFFSET)) {
> -				port->read_status_mask |= CDNS_UART_IXR_BRK;
> -				isrstatus &= ~CDNS_UART_IXR_FRAMING;
> -			}
> +			/*
> +			 * Adjust the tail of the UART buffer and wrap
> +			 * the buffer if it reaches limit.
> +			 */
> +			port->state->xmit.tail =
> +				(port->state->xmit.tail + 1) &
> +					(UART_XMIT_SIZE - 1);
>  		}
> -		writel(CDNS_UART_IXR_FRAMING,
> -				port->membase + CDNS_UART_ISR_OFFSET);
> -	}
>  
> -	/* drop byte with parity error if IGNPAR specified */
> -	if (isrstatus & port->ignore_status_mask & CDNS_UART_IXR_PARITY)
> -		isrstatus &= ~(CDNS_UART_IXR_RXTRIG | CDNS_UART_IXR_TOUT);
> +		if (uart_circ_chars_pending(
> +				&port->state->xmit) < WAKEUP_CHARS)
> +			uart_write_wakeup(port);
> +	}
> +}
>  
> -	isrstatus &= port->read_status_mask;
> -	isrstatus &= ~port->ignore_status_mask;
> +/**
> + * cdns_uart_handle_rx - Handle the received bytes along with Rx errors.
> + * @dev_id: Id of the UART port
> + * @isrstatus: The interrupt status register value as read
> + * Return: None
> + */
> +static void cdns_uart_handle_rx(void *dev_id, unsigned int isrstatus)
> +{
> +	struct uart_port *port = (struct uart_port *)dev_id;
> +	unsigned int data;
> +	unsigned int framerrprocessed = 0;
> +	char status = TTY_NORMAL;
>  
> -	if ((isrstatus & CDNS_UART_IXR_TOUT) ||
> -		(isrstatus & CDNS_UART_IXR_RXTRIG)) {
> -		/* Receive Timeout Interrupt */
> -		while (!(readl(port->membase + CDNS_UART_SR_OFFSET) &
> -					CDNS_UART_SR_RXEMPTY)) {
> -			data = readl(port->membase + CDNS_UART_FIFO_OFFSET);
> +	while ((readl(port->membase + CDNS_UART_SR_OFFSET) &
> +		CDNS_UART_SR_RXEMPTY) != CDNS_UART_SR_RXEMPTY) {
> +		data = readl(port->membase + CDNS_UART_FIFO_OFFSET);
> +		port->icount.rx++;
> +		/*
> +		 * There is no hardware break detection, so we interpret
> +		 * framing error with all-zeros data as a break sequence.
> +		 * Most of the time, there's another non-zero byte at the
> +		 * end of the sequence.
> +		 */
> +		if (isrstatus & CDNS_UART_IXR_FRAMING) {
> +			if (!data) {
> +				port->read_status_mask |= CDNS_UART_IXR_BRK;
> +				framerrprocessed = 1;
> +				continue;
> +			}
> +		}
> +		isrstatus &= port->read_status_mask;
> +		isrstatus &= ~port->ignore_status_mask;
>  
> -			/* Non-NULL byte after BREAK is garbage (99%) */
> -			if (data && (port->read_status_mask &
> -						CDNS_UART_IXR_BRK)) {
> +		if ((isrstatus & CDNS_UART_IXR_TOUT) ||
> +		    (isrstatus & CDNS_UART_IXR_RXTRIG)) {
> +			if (data &&
> +			    (port->read_status_mask & CDNS_UART_IXR_BRK)) {
>  				port->read_status_mask &= ~CDNS_UART_IXR_BRK;
>  				port->icount.brk++;
>  				if (uart_handle_break(port))
> @@ -249,67 +274,56 @@ static irqreturn_t cdns_uart_isr(int irq, void *dev_id)
>  				spin_lock(&port->lock);
>  			}
>  #endif
> -
> -			port->icount.rx++;
> -
>  			if (isrstatus & CDNS_UART_IXR_PARITY) {
>  				port->icount.parity++;
>  				status = TTY_PARITY;
> -			} else if (isrstatus & CDNS_UART_IXR_FRAMING) {
> +			}
> +			if ((isrstatus & CDNS_UART_IXR_FRAMING) &&
> +			    !framerrprocessed) {
>  				port->icount.frame++;
>  				status = TTY_FRAME;
> -			} else if (isrstatus & CDNS_UART_IXR_OVERRUN) {
> +			}
> +			if (isrstatus & CDNS_UART_IXR_OVERRUN) {
>  				port->icount.overrun++;
> +				tty_insert_flip_char(&port->state->port, 0,
> +						     TTY_OVERRUN);
>  			}
> -
> -			uart_insert_char(port, isrstatus, CDNS_UART_IXR_OVERRUN,
> -					data, status);
> +			tty_insert_flip_char(&port->state->port, data, status);
>  		}
> -		spin_unlock(&port->lock);
> -		tty_flip_buffer_push(&port->state->port);
> -		spin_lock(&port->lock);
>  	}
> +	spin_unlock(&port->lock);
> +	tty_flip_buffer_push(&port->state->port);
> +	spin_lock(&port->lock);
> +}
>  
> -	/* Dispatch an appropriate handler */
> -	if ((isrstatus & CDNS_UART_IXR_TXEMPTY) == CDNS_UART_IXR_TXEMPTY) {
> -		if (uart_circ_empty(&port->state->xmit)) {
> -			writel(CDNS_UART_IXR_TXEMPTY,
> -					port->membase + CDNS_UART_IDR_OFFSET);
> -		} else {
> -			numbytes = port->fifosize;
> -			/* Break if no more data available in the UART buffer */
> -			while (numbytes--) {
> -				if (uart_circ_empty(&port->state->xmit))
> -					break;
> -				/* Get the data from the UART circular buffer
> -				 * and write it to the cdns_uart's TX_FIFO
> -				 * register.
> -				 */
> -				writel(port->state->xmit.buf[
> -						port->state->xmit.tail],
> -					port->membase + CDNS_UART_FIFO_OFFSET);
> -
> -				port->icount.tx++;
> -
> -				/* Adjust the tail of the UART buffer and wrap
> -				 * the buffer if it reaches limit.
> -				 */
> -				port->state->xmit.tail =
> -					(port->state->xmit.tail + 1) &
> -						(UART_XMIT_SIZE - 1);
> -			}
> +/**
> + * cdns_uart_isr - Interrupt handler
> + * @irq: Irq number
> + * @dev_id: Id of the port
> + *
> + * Return: IRQHANDLED
> + */
> +static irqreturn_t cdns_uart_isr(int irq, void *dev_id)
> +{
> +	struct uart_port *port = (struct uart_port *)dev_id;
> +	unsigned int isrstatus;
>  
> -			if (uart_circ_chars_pending(
> -					&port->state->xmit) < WAKEUP_CHARS)
> -				uart_write_wakeup(port);
> -		}
> -	}
> +	spin_lock(&port->lock);
>  
> +	/* Read the interrupt status register to determine which
> +	 * interrupt(s) is/are active and clear them.
> +	 */
> +	isrstatus = readl(port->membase + CDNS_UART_ISR_OFFSET);
>  	writel(isrstatus, port->membase + CDNS_UART_ISR_OFFSET);
>  
> -	/* be sure to release the lock and tty before leaving */
> -	spin_unlock_irqrestore(&port->lock, flags);
> +	if (isrstatus & CDNS_UART_IXR_TXEMPTY) {
> +		cdns_uart_handle_tx(dev_id);
> +		isrstatus &= ~CDNS_UART_IXR_TXEMPTY;
> +	}
> +	if (isrstatus & CDNS_UART_IXR_MASK)
> +		cdns_uart_handle_rx(dev_id, isrstatus);
>  
> +	spin_unlock(&port->lock);
>  	return IRQ_HANDLED;
>  }
>  
> 



From horms at verge.net.au  Mon Aug 17 08:56:29 2015
From: horms at verge.net.au (Simon Horman)
Date: Mon, 17 Aug 2015 08:56:29 -0700
Subject: [PATCH v2 0/6] ARM: shmobile: Move gpio ranges from C code to DT
In-Reply-To: <CACRpkdYe5z9vG+Aekdq1wcKdhUUN5bpxQ52RgNt17+bhJbjVEQ@mail.gmail.com>
References: <1438696519-13727-1-git-send-email-geert+renesas@glider.be>
 <20150805005540.GB20726@verge.net.au>
 <CACRpkdY7P86+SxMr5-HnhrN5fC-N1U135jiGAJGTV=xx47VW5g@mail.gmail.com>
 <CAMuHMdW0T6MW6s4Gg_rqvtt+MRPtp_MpuiKtamfFrx-Tcm6WmQ@mail.gmail.com>
 <20150814003023.GC12589@verge.net.au>
 <CAMuHMdU0XoZ-comYSAau6e3kAY9VUbNgyeRcS_LzmV1gm31ZKA@mail.gmail.com>
 <CACRpkdYe5z9vG+Aekdq1wcKdhUUN5bpxQ52RgNt17+bhJbjVEQ@mail.gmail.com>
Message-ID: <20150817155629.GA8401@verge.net.au>

On Fri, Aug 14, 2015 at 12:34:33PM +0200, Linus Walleij wrote:
> On Fri, Aug 14, 2015 at 9:46 AM, Geert Uytterhoeven
> <geert at linux-m68k.org> wrote:
> > On Fri, Aug 14, 2015 at 2:30 AM, Simon Horman <horms at verge.net.au> wrote:
> >> On Thu, Aug 13, 2015 at 02:45:55PM +0200, Geert Uytterhoeven wrote:
> >>> On Thu, Aug 13, 2015 at 2:29 PM, Linus Walleij <linus.walleij at linaro.org> wrote:
> >>> > On Wed, Aug 5, 2015 at 2:55 AM, Simon Horman <horms at verge.net.au> wrote:
> >>> >> Where possible I prefer not to apply non-DTS/DTSI patches on top of
> >>> >> DTS/DTSI patches, I believe this is in keeping with how the ARM SoC
> >>> >> maintainers like things handled.  With this in mind I have done the following:
> >>> >>
> >>> >> 1. Queued up the DTSI patches (patches 1 - 3) for v4.3 in my dt branch.
> >>> >>    I intend for this to turn up in next soon.
> >>> >> 2. Queued up for pinctrl patches (patches 4 - 6) for v4.4 in a pinctrl patch.
> >>> >>    I intend for these to be present in the renesas devel branch but
> >>> >>    not in next until after the release of v4.3-rc1. I would also be
> >>> >>    happy to drop them and let Linus Walleij take these patches for v4.4,
> >>> >>    assuming patches 1 - 3 are accepted for v4.3.
> >>> >
> >>> > OK.
> >>> >
> >>> > Will the world explode if I try to queue the pinctrl patches 4-6 in my
> >>> > tree now for v4.3? Then I prefer to defer to v4.4. Else I can merge
> >>> > it in parallel?
> >>>
> >>> There won't be a mapping between gpio and pins in any branch having the
> >>> pinctrl changes but not the dtsi changes.
> >>
> >> It sounds to me that Linus should take his option 2; defer to v4.4.
> >> In which case I should drop the changes from my tree (they are not in next
> >> anyway). Please let me know if thats the way we will move this forwards.
> >
> > Sounds fine to me.
> >
> > And in the unlikely event we discover regressions in v4.3-rc1 due to having
> > the dtsi changes without the pinctrl changes, we can still fast-track them
> > into v4.3-rc2.
> 
> Sounds like a plan.
> 
> Hit me on the head about this once v4.3-rc1 is out!

Thanks, I will drop the patches from my tree.


From anirudha.sarangi at xilinx.com  Mon Aug 17 08:58:36 2015
From: anirudha.sarangi at xilinx.com (Anirudha Sarangi)
Date: Mon, 17 Aug 2015 15:58:36 +0000
Subject: [PATCH 2/4] serial: xuartps: Do not handle overrun errors under
 IGNPAR option
In-Reply-To: <55D20297.6010500@hurleysoftware.com>
References: <5b154ba97bcd79e49e2131152eb2fc1761594a6c.1439796149.git.michal.simek@xilinx.com>
 <41df6eb35d69801afa5b686a6974e3c3bf65178a.1439796149.git.michal.simek@xilinx.com>
 <55D20297.6010500@hurleysoftware.com>
Message-ID: <59506B47DEDD3943ABF9AC60020F4E2978D6E7FF@XAP-PVEXMBX02.xlnx.xilinx.com>

Hi,

> -----Original Message-----
> From: Peter Hurley [mailto:peter at hurleysoftware.com]
> Sent: Monday, August 17, 2015 9:20 PM
> To: Michal Simek
> Cc: linux-kernel at vger.kernel.org; monstr at monstr.eu; Anirudha Sarangi; Soren
> Brinkmann; Jiri Slaby; linux-serial at vger.kernel.org; Greg Kroah-Hartman; linux-
> arm-kernel at lists.infradead.org
> Subject: Re: [PATCH 2/4] serial: xuartps: Do not handle overrun errors under
> IGNPAR option
>
> On 08/17/2015 03:22 AM, Michal Simek wrote:
> > From: Anirudha Sarangi <anirudha.sarangi at xilinx.com>
> >
> > The existing implementation includes overrun errors under IGNPAR
> > option. This patch fixes it by including only parity and framing error
> > under IGNPAR option.
>
> The convention adopted by Linux serial drivers is to ignore overrun errors if both
> IGNPAR and IGNBRK are set.
>
I just followed the set_termios documentation, which says that IGNPAR is for parity and framing.
The current controller does not support break detection reliably.
That is probably why we don?t have IGNBRK.

Regards
Anirudha

> Regards,
> Peter Hurley
>
> > Signed-off-by: Anirudha Sarangi <anirudh at xilinx.com>
> > Signed-off-by: Michal Simek <michal.simek at xilinx.com>
> > ---
> >
> >  drivers/tty/serial/xilinx_uartps.c | 2 +-
> >  1 file changed, 1 insertion(+), 1 deletion(-)
> >
> > diff --git a/drivers/tty/serial/xilinx_uartps.c
> > b/drivers/tty/serial/xilinx_uartps.c
> > index a3020344ac9d..c4437e8929ff 100644
> > --- a/drivers/tty/serial/xilinx_uartps.c
> > +++ b/drivers/tty/serial/xilinx_uartps.c
> > @@ -691,7 +691,7 @@ static void cdns_uart_set_termios(struct uart_port
> > *port,
> >
> >     if (termios->c_iflag & IGNPAR)
> >             port->ignore_status_mask |= CDNS_UART_IXR_PARITY |
> > -                   CDNS_UART_IXR_FRAMING |
> CDNS_UART_IXR_OVERRUN;
> > +                                       CDNS_UART_IXR_FRAMING;
> >
> >     /* ignore all characters if CREAD is not set */
> >     if ((termios->c_cflag & CREAD) == 0)
> >



This email and any attachments are intended for the sole use of the named recipient(s) and contain(s) confidential information that may be proprietary, privileged or copyrighted under applicable law. If you are not the intended recipient, do not read, copy, or forward this email message or any attachments. Delete this email message and any attachments immediately.


From anirudha.sarangi at xilinx.com  Mon Aug 17 09:00:20 2015
From: anirudha.sarangi at xilinx.com (Anirudha Sarangi)
Date: Mon, 17 Aug 2015 16:00:20 +0000
Subject: [PATCH 4/4] serial: xuartps: Rewrite the interrupt handling logic
In-Reply-To: <55D2040F.1010205@hurleysoftware.com>
References: <5b154ba97bcd79e49e2131152eb2fc1761594a6c.1439796149.git.michal.simek@xilinx.com>
 <ead0c38140e815133a47797a2527229a2fc077c1.1439796149.git.michal.simek@xilinx.com>
 <55D2040F.1010205@hurleysoftware.com>
Message-ID: <59506B47DEDD3943ABF9AC60020F4E2978D6E80A@XAP-PVEXMBX02.xlnx.xilinx.com>

Hi,

> -----Original Message-----
> From: Peter Hurley [mailto:peter at hurleysoftware.com]
> Sent: Monday, August 17, 2015 9:26 PM
> To: Michal Simek
> Cc: linux-kernel at vger.kernel.org; monstr at monstr.eu; Anirudha Sarangi; Soren
> Brinkmann; Jiri Slaby; linux-serial at vger.kernel.org; Greg Kroah-Hartman; linux-
> arm-kernel at lists.infradead.org
> Subject: Re: [PATCH 4/4] serial: xuartps: Rewrite the interrupt handling logic
>
> On 08/17/2015 03:22 AM, Michal Simek wrote:
> > From: Anirudha Sarangi <anirudha.sarangi at xilinx.com>
> >
> > The existing interrupt handling logic has followins issues.
> > - Upon a parity error with default configuration, the control
> >   never comes out of the ISR thereby hanging Linux.
> > - The error handling logic around framing and parity error are buggy.
> >   There are chances that the errors will never be captured.
> > - The existing ISR is just too long.
> > This patch fixes all these concerns.
>
> This patch is unreviewable. Please break this down into multiple patches.
>
Thanks. Let me give a shot. It is just breaking the single big ISR that has both Rx and Tx in a single function into smaller ones.
Not sure how I will create smaller patches, but I will try and get back.

Regards
Anirudha

> Regards,
> Peter Hurley
>
> > It separates out the Tx and Rx
> > hanling logic into separate functions. It ensures that the status
> > registers are cleared on all cases so that a hang situation never
> > arises.
> >
> > Signed-off-by: Anirudha Sarangi <anirudh at xilinx.com>
> > Signed-off-by: Michal Simek <michal.simek at xilinx.com>
> > ---
> >
> >  drivers/tty/serial/xilinx_uartps.c | 194
> > ++++++++++++++++++++-----------------
> >  1 file changed, 104 insertions(+), 90 deletions(-)
> >
> > diff --git a/drivers/tty/serial/xilinx_uartps.c
> > b/drivers/tty/serial/xilinx_uartps.c
> > index 2dc26e5f1384..c771dbbf6161 100644
> > --- a/drivers/tty/serial/xilinx_uartps.c
> > +++ b/drivers/tty/serial/xilinx_uartps.c
> > @@ -173,61 +173,86 @@ struct cdns_uart {
> >             clk_rate_change_nb);
> >
> >  /**
> > - * cdns_uart_isr - Interrupt handler
> > - * @irq: Irq number
> > - * @dev_id: Id of the port
> > - *
> > - * Return: IRQHANDLED
> > + * cdns_uart_handle_tx - Handle the bytes to be Txed.
> > + * @dev_id: Id of the UART port
> > + * Return: None
> >   */
> > -static irqreturn_t cdns_uart_isr(int irq, void *dev_id)
> > +static void cdns_uart_handle_tx(void *dev_id)
> >  {
> >     struct uart_port *port = (struct uart_port *)dev_id;
> > -   unsigned long flags;
> > -   unsigned int isrstatus, numbytes;
> > -   unsigned int data;
> > -   char status = TTY_NORMAL;
> > +   unsigned int numbytes;
> >
> > -   spin_lock_irqsave(&port->lock, flags);
> > +   if (uart_circ_empty(&port->state->xmit)) {
> > +           writel(CDNS_UART_IXR_TXEMPTY, port->membase +
> > +                  CDNS_UART_IDR_OFFSET);
> > +   } else {
> > +           numbytes = port->fifosize;
> > +           /* Break if no more data available in the UART buffer */
> > +           while (numbytes--) {
> > +                   if (uart_circ_empty(&port->state->xmit))
> > +                           break;
> > +                   /*
> > +                    * Get the data from the UART circular buffer
> > +                    * and write it to the cdns_uart's TX_FIFO
> > +                    * register.
> > +                    */
> > +                   writel(port->state->xmit.buf[port->state->xmit.tail],
> > +                          port->membase + CDNS_UART_FIFO_OFFSET);
> >
> > -   /* Read the interrupt status register to determine which
> > -    * interrupt(s) is/are active.
> > -    */
> > -   isrstatus = readl(port->membase + CDNS_UART_ISR_OFFSET);
> > +                   port->icount.tx++;
> >
> > -   /*
> > -    * There is no hardware break detection, so we interpret framing
> > -    * error with all-zeros data as a break sequence. Most of the time,
> > -    * there's another non-zero byte at the end of the sequence.
> > -    */
> > -   if (isrstatus & CDNS_UART_IXR_FRAMING) {
> > -           while (!(readl(port->membase + CDNS_UART_SR_OFFSET) &
> > -                                   CDNS_UART_SR_RXEMPTY)) {
> > -                   if (!readl(port->membase + CDNS_UART_FIFO_OFFSET))
> {
> > -                           port->read_status_mask |=
> CDNS_UART_IXR_BRK;
> > -                           isrstatus &= ~CDNS_UART_IXR_FRAMING;
> > -                   }
> > +                   /*
> > +                    * Adjust the tail of the UART buffer and wrap
> > +                    * the buffer if it reaches limit.
> > +                    */
> > +                   port->state->xmit.tail =
> > +                           (port->state->xmit.tail + 1) &
> > +                                   (UART_XMIT_SIZE - 1);
> >             }
> > -           writel(CDNS_UART_IXR_FRAMING,
> > -                           port->membase + CDNS_UART_ISR_OFFSET);
> > -   }
> >
> > -   /* drop byte with parity error if IGNPAR specified */
> > -   if (isrstatus & port->ignore_status_mask & CDNS_UART_IXR_PARITY)
> > -           isrstatus &= ~(CDNS_UART_IXR_RXTRIG |
> CDNS_UART_IXR_TOUT);
> > +           if (uart_circ_chars_pending(
> > +                           &port->state->xmit) < WAKEUP_CHARS)
> > +                   uart_write_wakeup(port);
> > +   }
> > +}
> >
> > -   isrstatus &= port->read_status_mask;
> > -   isrstatus &= ~port->ignore_status_mask;
> > +/**
> > + * cdns_uart_handle_rx - Handle the received bytes along with Rx errors.
> > + * @dev_id: Id of the UART port
> > + * @isrstatus: The interrupt status register value as read
> > + * Return: None
> > + */
> > +static void cdns_uart_handle_rx(void *dev_id, unsigned int isrstatus)
> > +{
> > +   struct uart_port *port = (struct uart_port *)dev_id;
> > +   unsigned int data;
> > +   unsigned int framerrprocessed = 0;
> > +   char status = TTY_NORMAL;
> >
> > -   if ((isrstatus & CDNS_UART_IXR_TOUT) ||
> > -           (isrstatus & CDNS_UART_IXR_RXTRIG)) {
> > -           /* Receive Timeout Interrupt */
> > -           while (!(readl(port->membase + CDNS_UART_SR_OFFSET) &
> > -                                   CDNS_UART_SR_RXEMPTY)) {
> > -                   data = readl(port->membase +
> CDNS_UART_FIFO_OFFSET);
> > +   while ((readl(port->membase + CDNS_UART_SR_OFFSET) &
> > +           CDNS_UART_SR_RXEMPTY) != CDNS_UART_SR_RXEMPTY) {
> > +           data = readl(port->membase + CDNS_UART_FIFO_OFFSET);
> > +           port->icount.rx++;
> > +           /*
> > +            * There is no hardware break detection, so we interpret
> > +            * framing error with all-zeros data as a break sequence.
> > +            * Most of the time, there's another non-zero byte at the
> > +            * end of the sequence.
> > +            */
> > +           if (isrstatus & CDNS_UART_IXR_FRAMING) {
> > +                   if (!data) {
> > +                           port->read_status_mask |=
> CDNS_UART_IXR_BRK;
> > +                           framerrprocessed = 1;
> > +                           continue;
> > +                   }
> > +           }
> > +           isrstatus &= port->read_status_mask;
> > +           isrstatus &= ~port->ignore_status_mask;
> >
> > -                   /* Non-NULL byte after BREAK is garbage (99%) */
> > -                   if (data && (port->read_status_mask &
> > -                                           CDNS_UART_IXR_BRK)) {
> > +           if ((isrstatus & CDNS_UART_IXR_TOUT) ||
> > +               (isrstatus & CDNS_UART_IXR_RXTRIG)) {
> > +                   if (data &&
> > +                       (port->read_status_mask & CDNS_UART_IXR_BRK)) {
> >                             port->read_status_mask &=
> ~CDNS_UART_IXR_BRK;
> >                             port->icount.brk++;
> >                             if (uart_handle_break(port))
> > @@ -249,67 +274,56 @@ static irqreturn_t cdns_uart_isr(int irq, void *dev_id)
> >                             spin_lock(&port->lock);
> >                     }
> >  #endif
> > -
> > -                   port->icount.rx++;
> > -
> >                     if (isrstatus & CDNS_UART_IXR_PARITY) {
> >                             port->icount.parity++;
> >                             status = TTY_PARITY;
> > -                   } else if (isrstatus & CDNS_UART_IXR_FRAMING) {
> > +                   }
> > +                   if ((isrstatus & CDNS_UART_IXR_FRAMING) &&
> > +                       !framerrprocessed) {
> >                             port->icount.frame++;
> >                             status = TTY_FRAME;
> > -                   } else if (isrstatus & CDNS_UART_IXR_OVERRUN) {
> > +                   }
> > +                   if (isrstatus & CDNS_UART_IXR_OVERRUN) {
> >                             port->icount.overrun++;
> > +                           tty_insert_flip_char(&port->state->port, 0,
> > +                                                TTY_OVERRUN);
> >                     }
> > -
> > -                   uart_insert_char(port, isrstatus,
> CDNS_UART_IXR_OVERRUN,
> > -                                   data, status);
> > +                   tty_insert_flip_char(&port->state->port, data, status);
> >             }
> > -           spin_unlock(&port->lock);
> > -           tty_flip_buffer_push(&port->state->port);
> > -           spin_lock(&port->lock);
> >     }
> > +   spin_unlock(&port->lock);
> > +   tty_flip_buffer_push(&port->state->port);
> > +   spin_lock(&port->lock);
> > +}
> >
> > -   /* Dispatch an appropriate handler */
> > -   if ((isrstatus & CDNS_UART_IXR_TXEMPTY) ==
> CDNS_UART_IXR_TXEMPTY) {
> > -           if (uart_circ_empty(&port->state->xmit)) {
> > -                   writel(CDNS_UART_IXR_TXEMPTY,
> > -                                   port->membase +
> CDNS_UART_IDR_OFFSET);
> > -           } else {
> > -                   numbytes = port->fifosize;
> > -                   /* Break if no more data available in the UART buffer */
> > -                   while (numbytes--) {
> > -                           if (uart_circ_empty(&port->state->xmit))
> > -                                   break;
> > -                           /* Get the data from the UART circular buffer
> > -                            * and write it to the cdns_uart's TX_FIFO
> > -                            * register.
> > -                            */
> > -                           writel(port->state->xmit.buf[
> > -                                           port->state->xmit.tail],
> > -                                   port->membase +
> CDNS_UART_FIFO_OFFSET);
> > -
> > -                           port->icount.tx++;
> > -
> > -                           /* Adjust the tail of the UART buffer and wrap
> > -                            * the buffer if it reaches limit.
> > -                            */
> > -                           port->state->xmit.tail =
> > -                                   (port->state->xmit.tail + 1) &
> > -                                           (UART_XMIT_SIZE - 1);
> > -                   }
> > +/**
> > + * cdns_uart_isr - Interrupt handler
> > + * @irq: Irq number
> > + * @dev_id: Id of the port
> > + *
> > + * Return: IRQHANDLED
> > + */
> > +static irqreturn_t cdns_uart_isr(int irq, void *dev_id) {
> > +   struct uart_port *port = (struct uart_port *)dev_id;
> > +   unsigned int isrstatus;
> >
> > -                   if (uart_circ_chars_pending(
> > -                                   &port->state->xmit) < WAKEUP_CHARS)
> > -                           uart_write_wakeup(port);
> > -           }
> > -   }
> > +   spin_lock(&port->lock);
> >
> > +   /* Read the interrupt status register to determine which
> > +    * interrupt(s) is/are active and clear them.
> > +    */
> > +   isrstatus = readl(port->membase + CDNS_UART_ISR_OFFSET);
> >     writel(isrstatus, port->membase + CDNS_UART_ISR_OFFSET);
> >
> > -   /* be sure to release the lock and tty before leaving */
> > -   spin_unlock_irqrestore(&port->lock, flags);
> > +   if (isrstatus & CDNS_UART_IXR_TXEMPTY) {
> > +           cdns_uart_handle_tx(dev_id);
> > +           isrstatus &= ~CDNS_UART_IXR_TXEMPTY;
> > +   }
> > +   if (isrstatus & CDNS_UART_IXR_MASK)
> > +           cdns_uart_handle_rx(dev_id, isrstatus);
> >
> > +   spin_unlock(&port->lock);
> >     return IRQ_HANDLED;
> >  }
> >
> >



This email and any attachments are intended for the sole use of the named recipient(s) and contain(s) confidential information that may be proprietary, privileged or copyrighted under applicable law. If you are not the intended recipient, do not read, copy, or forward this email message or any attachments. Delete this email message and any attachments immediately.


From peter at hurleysoftware.com  Mon Aug 17 09:04:16 2015
From: peter at hurleysoftware.com (Peter Hurley)
Date: Mon, 17 Aug 2015 12:04:16 -0400
Subject: earlycon issues in -next with amba-pl011 updates
In-Reply-To: <20150811124043.GZ7557@n2100.arm.linux.org.uk>
References: <20150810232312.GB10728@bivouac.eciton.net>
 <55C94247.8020701@hurleysoftware.com>
 <20150811124043.GZ7557@n2100.arm.linux.org.uk>
Message-ID: <55D20600.6050204@hurleysoftware.com>

On 08/11/2015 08:40 AM, Russell King - ARM Linux wrote:
> On Mon, Aug 10, 2015 at 08:31:03PM -0400, Peter Hurley wrote:
>> diff --git a/drivers/tty/serial/amba-pl011.c b/drivers/tty/serial/amba-pl011.c
>> index 2af09ab..fd54991 100644
>> --- a/drivers/tty/serial/amba-pl011.c
>> +++ b/drivers/tty/serial/amba-pl011.c
>> @@ -2348,13 +2348,10 @@ static struct console amba_console = {
>>  
>>  static void pl011_putc(struct uart_port *port, int c)
>>  {
>> -	struct uart_amba_port *uap =
>> -	    container_of(port, struct uart_amba_port, port);
>> -
>> -	while (pl011_readw(uap, REG_FR) & UART01x_FR_TXFF)
>> +	while (readl(port->membase + UART01x_FR) & UART01x_FR_TXFF)
>>  		;
>> -	pl011_writeb(uap, c, REG_DR);
>> -	while (pl011_readw(uap, REG_FR) & uap->fr_busy)
>> +	writeb(c, port->membase + UART01x_DR);
>> +	while (readl(port->membase + UART01x_FR) & UART01x_FR_BUSY)
>>  		;
> 
> These loops are wrong.  Kernel coding style is that loops like this
> will use cpu_relax() in them, just like the driver used to.  This
> was introduced by:
> 
> commit 0d3c673e7881e691991b2a4745bd4f149603baa2
> Author: Rob Herring <robh at kernel.org>
> Date:   Fri Apr 18 17:19:57 2014 -0500
> 
>     tty/serial: pl011: add generic earlycon support
> 
> Also, the above readl()s should be readl_relaxed(), we don't need
> barriered reads or to hit the L2 cache on those reads in the above code.

This patch just reverts pl011 earlycon back to the existing mainline
state.

The amba-pl011 driver has many places where cpu_relax() is not used,
so that seems like a good patch for -next during the 4.3-rc cycle.

Similarly for read_relaxed() use in earlycon.

Regards,
Peter Hurley


From eric.auger at linaro.org  Mon Aug 17 09:10:56 2015
From: eric.auger at linaro.org (Eric Auger)
Date: Mon, 17 Aug 2015 18:10:56 +0200
Subject: [PATCH v2 1/4] irqchip: GICv3: Convert to EOImode == 1
In-Reply-To: <1439454526-1185-2-git-send-email-marc.zyngier@arm.com>
References: <1439454526-1185-1-git-send-email-marc.zyngier@arm.com>
 <1439454526-1185-2-git-send-email-marc.zyngier@arm.com>
Message-ID: <55D20790.1050100@linaro.org>

Hi Marc,
On 08/13/2015 10:28 AM, Marc Zyngier wrote:
> So far, GICv3 has been used in with EOImode == 0. The effect of this
> mode is to perform the priority drop and the deactivation of the
> interrupt at the same time.
> 
> While this works perfectly for Linux (we only have a single priority),
> it causes issues when an interrupt is forwarded to a guest, and when
> we want the guest to perform the EOI itself.
> 
> For this case, the GIC architecture provides EOImode == 1, where:
> - A write to ICC_EOIR1_EL1 drops the priority of the interrupt and leaves
> it active. Other interrupts at the same priority level can now be taken,
> but the active interrupt cannot be taken again
> - A write to ICC_DIR_EL1 marks the interrupt as inactive, meaning it can
> now be taken again.
> 
> This patch converts the driver to be able to use this new mode, depending
> on whether or not the kernel can behave as a hypervisor. No feature change.
> 
> Signed-off-by: Marc Zyngier <marc.zyngier at arm.com>
> ---
>  drivers/irqchip/irq-gic-v3.c       | 37 +++++++++++++++++++++++++++++++++----
>  include/linux/irqchip/arm-gic-v3.h |  9 +++++++++
>  2 files changed, 42 insertions(+), 4 deletions(-)
> 
> diff --git a/drivers/irqchip/irq-gic-v3.c b/drivers/irqchip/irq-gic-v3.c
> index c52f7ba..61190fb 100644
> --- a/drivers/irqchip/irq-gic-v3.c
> +++ b/drivers/irqchip/irq-gic-v3.c
> @@ -30,6 +30,7 @@
>  #include <asm/cputype.h>
>  #include <asm/exception.h>
>  #include <asm/smp_plat.h>
> +#include <asm/virt.h>
>  
>  #include "irq-gic-common.h"
>  #include "irqchip.h"
> @@ -50,6 +51,7 @@ struct gic_chip_data {
>  };
>  
>  static struct gic_chip_data gic_data __read_mostly;
> +static struct static_key supports_deactivate = STATIC_KEY_INIT_TRUE;
>  
>  #define gic_data_rdist()		(this_cpu_ptr(gic_data.rdists.rdist))
>  #define gic_data_rdist_rd_base()	(gic_data_rdist()->rd_base)
> @@ -293,7 +295,14 @@ static int gic_irq_get_irqchip_state(struct irq_data *d,
>  
>  static void gic_eoi_irq(struct irq_data *d)
>  {
> -	gic_write_eoir(gic_irq(d));
> +	if (static_key_true(&supports_deactivate)) {
> +		/* No need to deactivate an LPI */
> +		if (gic_irq(d) >= 8192)
> +			return;
> +		gic_write_dir(gic_irq(d));
> +	} else {
> +		gic_write_eoir(gic_irq(d));
> +	}
>  }
>  
>  static int gic_set_type(struct irq_data *d, unsigned int type)
> @@ -343,15 +352,24 @@ static asmlinkage void __exception_irq_entry gic_handle_irq(struct pt_regs *regs
>  
>  		if (likely(irqnr > 15 && irqnr < 1020) || irqnr >= 8192) {
>  			int err;
> +
> +			if (static_key_true(&supports_deactivate))
> +				gic_write_eoir(irqnr);
> +
>  			err = handle_domain_irq(gic_data.domain, irqnr, regs);
>  			if (err) {
>  				WARN_ONCE(true, "Unexpected interrupt received!\n");
> -				gic_write_eoir(irqnr);
> +				if (static_key_true(&supports_deactivate))
> +					gic_write_dir(irqnr);
shouldn't be needed to DIR the irq if LPI but is it harmful? Just
because we don't do it on gic_eoi_irq ...

Best Regards

Eric
> +				else
> +					gic_write_eoir(irqnr);
>  			}
>  			continue;
>  		}
>  		if (irqnr < 16) {
>  			gic_write_eoir(irqnr);
> +			if (static_key_true(&supports_deactivate))
> +				gic_write_dir(irqnr);
>  #ifdef CONFIG_SMP
>  			handle_IPI(irqnr, regs);
>  #else
> @@ -451,8 +469,13 @@ static void gic_cpu_sys_reg_init(void)
>  	/* Set priority mask register */
>  	gic_write_pmr(DEFAULT_PMR_VALUE);
>  
> -	/* EOI deactivates interrupt too (mode 0) */
> -	gic_write_ctlr(ICC_CTLR_EL1_EOImode_drop_dir);
> +	if (static_key_true(&supports_deactivate)) {
> +		/* EOI drops priority only (mode 1) */
> +		gic_write_ctlr(ICC_CTLR_EL1_EOImode_drop);
> +	} else {
> +		/* EOI deactivates interrupt too (mode 0) */
> +		gic_write_ctlr(ICC_CTLR_EL1_EOImode_drop_dir);
> +	}
>  
>  	/* ... and let's hit the road... */
>  	gic_write_grpen1(1);
> @@ -820,6 +843,12 @@ static int __init gic_of_init(struct device_node *node, struct device_node *pare
>  	if (of_property_read_u64(node, "redistributor-stride", &redist_stride))
>  		redist_stride = 0;
>  
> +	if (!is_hyp_mode_available())
> +		static_key_slow_dec(&supports_deactivate);
> +
> +	if (static_key_true(&supports_deactivate))
> +		pr_info("GIC: Using split EOI/Deactivate mode\n");
> +
>  	gic_data.dist_base = dist_base;
>  	gic_data.redist_regions = rdist_regs;
>  	gic_data.nr_redist_regions = nr_redist_regions;
> diff --git a/include/linux/irqchip/arm-gic-v3.h b/include/linux/irqchip/arm-gic-v3.h
> index ffbc034..bc98832 100644
> --- a/include/linux/irqchip/arm-gic-v3.h
> +++ b/include/linux/irqchip/arm-gic-v3.h
> @@ -104,6 +104,8 @@
>  #define GICR_SYNCR			0x00C0
>  #define GICR_MOVLPIR			0x0100
>  #define GICR_MOVALLR			0x0110
> +#define GICR_ISACTIVER			GICD_ISACTIVER
> +#define GICR_ICACTIVER			GICD_ICACTIVER
>  #define GICR_IDREGS			GICD_IDREGS
>  #define GICR_PIDR2			GICD_PIDR2
>  
> @@ -288,6 +290,7 @@
>  #define ICH_VMCR_PMR_MASK		(0xffUL << ICH_VMCR_PMR_SHIFT)
>  
>  #define ICC_EOIR1_EL1			sys_reg(3, 0, 12, 12, 1)
> +#define ICC_DIR_EL1			sys_reg(3, 0, 12, 11, 1)
>  #define ICC_IAR1_EL1			sys_reg(3, 0, 12, 12, 0)
>  #define ICC_SGI1R_EL1			sys_reg(3, 0, 12, 11, 5)
>  #define ICC_PMR_EL1			sys_reg(3, 0, 4, 6, 0)
> @@ -384,6 +387,12 @@ static inline void gic_write_eoir(u64 irq)
>  	isb();
>  }
>  
> +static inline void gic_write_dir(u64 irq)
> +{
> +	asm volatile("msr_s " __stringify(ICC_DIR_EL1) ", %0" : : "r" (irq));
> +	isb();
> +}
> +
>  struct irq_domain;
>  int its_cpu_init(void);
>  int its_init(struct device_node *node, struct rdists *rdists,
> 



From eric.auger at linaro.org  Mon Aug 17 09:18:03 2015
From: eric.auger at linaro.org (Eric Auger)
Date: Mon, 17 Aug 2015 18:18:03 +0200
Subject: [PATCH v2 2/4] irqchip: GICv3: Don't deactivate interrupts
 forwarded to a guest
In-Reply-To: <1439454526-1185-3-git-send-email-marc.zyngier@arm.com>
References: <1439454526-1185-1-git-send-email-marc.zyngier@arm.com>
 <1439454526-1185-3-git-send-email-marc.zyngier@arm.com>
Message-ID: <55D2093B.3000004@linaro.org>

Reviewed-by: Eric Auger <eric.auger at linaro.org>
On 08/13/2015 10:28 AM, Marc Zyngier wrote:
> Commit 0a4377de3056 ("genirq: Introduce irq_set_vcpu_affinity() to
> target an interrupt to a VCPU") added just what we needed at the
> lowest level to allow an interrupt to be deactivated by a guest.
> 
> When such a request reaches the GIC, it knows it doesn't need to
> perform the deactivation anymore, and can safely leave the guest
> do its magic. This of course requires additional support in both
> VFIO and KVM.
> 
> Signed-off-by: Marc Zyngier <marc.zyngier at arm.com>
> ---
>  drivers/irqchip/irq-gic-v3.c | 35 +++++++++++++++++++++++++++++++++--
>  1 file changed, 33 insertions(+), 2 deletions(-)
> 
> diff --git a/drivers/irqchip/irq-gic-v3.c b/drivers/irqchip/irq-gic-v3.c
> index 61190fb..01c6329 100644
> --- a/drivers/irqchip/irq-gic-v3.c
> +++ b/drivers/irqchip/irq-gic-v3.c
> @@ -70,6 +70,11 @@ static inline int gic_irq_in_rdist(struct irq_data *d)
>  	return gic_irq(d) < 32;
>  }
>  
> +static inline bool forwarded_irq(struct irq_data *d)
> +{
> +	return d->handler_data != NULL;
> +}
> +
>  static inline void __iomem *gic_dist_base(struct irq_data *d)
>  {
>  	if (gic_irq_in_rdist(d))	/* SGI+PPI -> SGI_base for this CPU */
> @@ -231,6 +236,18 @@ static void gic_poke_irq(struct irq_data *d, u32 offset)
>  static void gic_mask_irq(struct irq_data *d)
>  {
>  	gic_poke_irq(d, GICD_ICENABLER);
> +	/*
> +	 * When masking a forwarded interrupt, make sure it is
> +	 * deactivated as well.
> +	 *
> +	 * This ensures that an interrupt that is getting
> +	 * disabled/masked will not get "stuck", because there is
> +	 * noone to deactivate it (guest is being terminated).
> +	 */
> +	if (static_key_true(&supports_deactivate)) {
> +		if (forwarded_irq(d))
> +			gic_poke_irq(d, GICD_ICACTIVER);
> +	}
>  }
>  
>  static void gic_unmask_irq(struct irq_data *d)
> @@ -296,8 +313,11 @@ static int gic_irq_get_irqchip_state(struct irq_data *d,
>  static void gic_eoi_irq(struct irq_data *d)
>  {
>  	if (static_key_true(&supports_deactivate)) {
> -		/* No need to deactivate an LPI */
> -		if (gic_irq(d) >= 8192)
> +		/*
> +		 * No need to deactivate an LPI, or an interrupt that
> +		 * is is getting forwarded to a vcpu.
> +		 */
> +		if (gic_irq(d) >= 8192 || forwarded_irq(d))
>  			return;
>  		gic_write_dir(gic_irq(d));
>  	} else {
> @@ -331,6 +351,16 @@ static int gic_set_type(struct irq_data *d, unsigned int type)
>  	return gic_configure_irq(irq, type, base, rwp_wait);
>  }
>  
> +static int gic_irq_set_vcpu_affinity(struct irq_data *d, void *vcpu)
> +{
> +	if (static_key_true(&supports_deactivate)) {
> +		d->handler_data = vcpu;
> +		return 0;
> +	}
> +
> +	return -EINVAL;
> +}
> +
>  static u64 gic_mpidr_to_affinity(u64 mpidr)
>  {
>  	u64 aff;
> @@ -681,6 +711,7 @@ static struct irq_chip gic_chip = {
>  	.irq_set_affinity	= gic_set_affinity,
>  	.irq_get_irqchip_state	= gic_irq_get_irqchip_state,
>  	.irq_set_irqchip_state	= gic_irq_set_irqchip_state,
> +	.irq_set_vcpu_affinity	= gic_irq_set_vcpu_affinity,
>  	.flags			= IRQCHIP_SET_TYPE_MASKED,
>  };
>  
> 



From peter at hurleysoftware.com  Mon Aug 17 09:19:30 2015
From: peter at hurleysoftware.com (Peter Hurley)
Date: Mon, 17 Aug 2015 12:19:30 -0400
Subject: [PATCH 2/4] serial: xuartps: Do not handle overrun errors under
 IGNPAR option
In-Reply-To: <59506B47DEDD3943ABF9AC60020F4E2978D6E7FF@XAP-PVEXMBX02.xlnx.xilinx.com>
References: <5b154ba97bcd79e49e2131152eb2fc1761594a6c.1439796149.git.michal.simek@xilinx.com>
 <41df6eb35d69801afa5b686a6974e3c3bf65178a.1439796149.git.michal.simek@xilinx.com>
 <55D20297.6010500@hurleysoftware.com>
 <59506B47DEDD3943ABF9AC60020F4E2978D6E7FF@XAP-PVEXMBX02.xlnx.xilinx.com>
Message-ID: <55D20992.60302@hurleysoftware.com>

On 08/17/2015 11:58 AM, Anirudha Sarangi wrote:
> Hi,
> 
>> -----Original Message-----
>> From: Peter Hurley [mailto:peter at hurleysoftware.com]
>> Sent: Monday, August 17, 2015 9:20 PM
>> To: Michal Simek
>> Cc: linux-kernel at vger.kernel.org; monstr at monstr.eu; Anirudha Sarangi; Soren
>> Brinkmann; Jiri Slaby; linux-serial at vger.kernel.org; Greg Kroah-Hartman; linux-
>> arm-kernel at lists.infradead.org
>> Subject: Re: [PATCH 2/4] serial: xuartps: Do not handle overrun errors under
>> IGNPAR option
>>
>> On 08/17/2015 03:22 AM, Michal Simek wrote:
>>> From: Anirudha Sarangi <anirudha.sarangi at xilinx.com>
>>>
>>> The existing implementation includes overrun errors under IGNPAR
>>> option. This patch fixes it by including only parity and framing error
>>> under IGNPAR option.
>>
>> The convention adopted by Linux serial drivers is to ignore overrun errors if both
>> IGNPAR and IGNBRK are set.
>>
> I just followed the set_termios documentation, which says that IGNPAR is for parity and framing.
> The current controller does not support break detection reliably.
> That is probably why we don?t have IGNBRK.

My point is about how a user-space process tells the serial driver to ignore
overrun errors, as well, and not specifically about break handling.

> 
> Regards
> Anirudha
> 
>> Regards,
>> Peter Hurley
>>
>>> Signed-off-by: Anirudha Sarangi <anirudh at xilinx.com>
>>> Signed-off-by: Michal Simek <michal.simek at xilinx.com>
>>> ---
>>>
>>>  drivers/tty/serial/xilinx_uartps.c | 2 +-
>>>  1 file changed, 1 insertion(+), 1 deletion(-)
>>>
>>> diff --git a/drivers/tty/serial/xilinx_uartps.c
>>> b/drivers/tty/serial/xilinx_uartps.c
>>> index a3020344ac9d..c4437e8929ff 100644
>>> --- a/drivers/tty/serial/xilinx_uartps.c
>>> +++ b/drivers/tty/serial/xilinx_uartps.c
>>> @@ -691,7 +691,7 @@ static void cdns_uart_set_termios(struct uart_port
>>> *port,
>>>
>>>     if (termios->c_iflag & IGNPAR)
>>>             port->ignore_status_mask |= CDNS_UART_IXR_PARITY |
>>> -                   CDNS_UART_IXR_FRAMING |
>> CDNS_UART_IXR_OVERRUN;
>>> +                                       CDNS_UART_IXR_FRAMING;
>>>
>>>     /* ignore all characters if CREAD is not set */
>>>     if ((termios->c_cflag & CREAD) == 0)
>>>
> 
> 
> 
> This email and any attachments are intended for the sole use of the named recipient(s) and contain(s) confidential information that may be proprietary, privileged or copyrighted under applicable law. If you are not the intended recipient, do not read, copy, or forward this email message or any attachments. Delete this email message and any attachments immediately.
> 



From alim.akhtar at gmail.com  Mon Aug 17 09:21:26 2015
From: alim.akhtar at gmail.com (Alim Akhtar)
Date: Mon, 17 Aug 2015 21:51:26 +0530
Subject: [PATCH 2/3] mmc: dw_mmc: simplify the SDMMC_CLKEN_LOW_PWR logic
In-Reply-To: <CAOMqctQ_gA=QxRVFQ8L=q7kBX3GROvz9mnHGu2yo1VrBO1Le6w@mail.gmail.com>
References: <cover.1439381423.git.hramrach@gmail.com>
 <3d03bfe2c18789eefa038018467c9c63c94ae4a2.1439381423.git.hramrach@gmail.com>
 <55D13F07.70309@samsung.com>
 <CAOMqctQ8DHj6qPg8zR93OGRHXAZDd0yUmG_J8Vz7dGFuDpCgRQ@mail.gmail.com>
 <55D1C4CD.4040200@samsung.com>
 <CAGOxZ51oHoX+zQSO8tRp8V5RUmDg8CAnM9HO5FQ5h6JeCy=1og@mail.gmail.com>
 <CAOMqctQ_gA=QxRVFQ8L=q7kBX3GROvz9mnHGu2yo1VrBO1Le6w@mail.gmail.com>
Message-ID: <CAGOxZ53FipjSbYMeBfr_+OWxn_WxpDfbfr8Vzs4uX6t3TBS3vw@mail.gmail.com>

Hi Michal,

On Mon, Aug 17, 2015 at 8:25 PM, Michal Suchanek <hramrach at gmail.com> wrote:
>  Hello,
>
> On 17 August 2015 at 16:42, Alim Akhtar <alim.akhtar at gmail.com> wrote:
>> HI
>>
>> On Mon, Aug 17, 2015 at 4:56 PM, Jaehoon Chung <jh80.chung at samsung.com> wrote:
>>> On 08/17/2015 02:52 PM, Michal Suchanek wrote:
>>>> Hello,
>>>>
>>>> On 17 August 2015 at 03:55, Jaehoon Chung <jh80.chung at samsung.com> wrote:
>>>>> Hi, Michal.
>>>>>
>>>>> On 08/12/2015 09:23 PM, Michal Suchanek wrote:
>>>>>> The driver has open-coded test for SDIO cards. Use the mmc core provided
>>>>>> MMC_QUIRK_BROKEN_CLK_GATING flag instead.
>>>>>
>>>>> Did you use the clock-gating for SDIO cards?
>>>>> Doesn't MMC_CAP_SDIO_IRQ bit set? Which case is broken?
>>>>> Could you explain to me more?
>>>>
>>>> The core flag for disabling power saving is MMC_QUIRK_BROKEN_CLK_GATING.
>>>
>>> I understood your intention. And i read the comment into mmc/core/quirks.c
>>> I will test SDIO card with this patch. Thanks.
>>>
>> When you test, please check if SDIO IRQ still works, we need to put
>> dw_mmc in low_power mode otherwise SDIO IRQ will be not be generated
>> by dw_mmc host controller.
>>
>
> As far as I understand the logic which is removed in this patch and
> the core logic which replaces it is the same -  low power by means of
> clock gating is *not* enabled for SDIO cards in either case.
>
> The original code also checks for SDIO IRQ and disables clock gating
> regardless of card type which is probably redundant. If not it should
> be fixed in mmc core.
>
> My recent kernel builds which I run on a system with mwifiex card
> probably include this patch.
>
I have no objection to this patch as such, it just that some extra
testing on few other boards will be good, which I am sure Jeahoon will
take care.
Thanks!!

> Thanks
>
> Michal



-- 
Regards,
Alim


From eric.auger at linaro.org  Mon Aug 17 09:27:26 2015
From: eric.auger at linaro.org (Eric Auger)
Date: Mon, 17 Aug 2015 18:27:26 +0200
Subject: [PATCH v2 3/4] irqchip: GIC: Convert to EOImode == 1
In-Reply-To: <1439454526-1185-4-git-send-email-marc.zyngier@arm.com>
References: <1439454526-1185-1-git-send-email-marc.zyngier@arm.com>
 <1439454526-1185-4-git-send-email-marc.zyngier@arm.com>
Message-ID: <55D20B6E.2050209@linaro.org>

On 08/13/2015 10:28 AM, Marc Zyngier wrote:
> So far, GICv2 has been used in with EOImode == 0. The effect of this
in with?
> mode is to perform the priority drop and the deactivation of the
> interrupt at the same time.
> 
> While this works perfectly for Linux (we only have a single priority),
> it causes issues when an interrupt is forwarded to a guest, and when
> we want the guest to perform the EOI itself.
> 
> For this case, the GIC architecture provides EOImode == 1, where:
> - A write to the EOI register drops the priority of the interrupt and leaves
> it active. Other interrupts at the same priority level can now be taken,
> but the active interrupt cannot be taken again
> - A write to the DIR marks the interrupt as inactive, meaning it can
> now be taken again.
> 
> We only enable this feature when booted in HYP mode and that
> the device-tree reporte a suitable CPU interface. Observable behaviour
reporte
> should remain unchanged.
I Get some checkpatch warnings.

I have no other remark on the code.

Eric
> 
> Signed-off-by: Marc Zyngier <marc.zyngier at arm.com>
> ---
>  drivers/irqchip/irq-gic.c       | 51 +++++++++++++++++++++++++++++++++++++++--
>  include/linux/irqchip/arm-gic.h |  4 ++++
>  2 files changed, 53 insertions(+), 2 deletions(-)
> 
> diff --git a/drivers/irqchip/irq-gic.c b/drivers/irqchip/irq-gic.c
> index 4dd8826..b020c3a 100644
> --- a/drivers/irqchip/irq-gic.c
> +++ b/drivers/irqchip/irq-gic.c
> @@ -46,6 +46,7 @@
>  #include <asm/irq.h>
>  #include <asm/exception.h>
>  #include <asm/smp_plat.h>
> +#include <asm/virt.h>
>  
>  #include "irq-gic-common.h"
>  #include "irqchip.h"
> @@ -82,6 +83,8 @@ static DEFINE_RAW_SPINLOCK(irq_controller_lock);
>  #define NR_GIC_CPU_IF 8
>  static u8 gic_cpu_map[NR_GIC_CPU_IF] __read_mostly;
>  
> +static struct static_key supports_deactivate = STATIC_KEY_INIT_TRUE;
> +
>  #ifndef MAX_GIC_NR
>  #define MAX_GIC_NR	1
>  #endif
> @@ -137,6 +140,14 @@ static inline unsigned int gic_irq(struct irq_data *d)
>  	return d->hwirq;
>  }
>  
> +static inline bool primary_gic_irq(struct irq_data *d)
> +{
> +	if (MAX_GIC_NR > 1)
> +		return irq_data_get_irq_chip_data(d) == &gic_data[0];
> +
> +	return true;
> +}
> +
>  /*
>   * Routines to acknowledge, disable and enable interrupts
>   */
> @@ -164,7 +175,14 @@ static void gic_unmask_irq(struct irq_data *d)
>  
>  static void gic_eoi_irq(struct irq_data *d)
>  {
> -	writel_relaxed(gic_irq(d), gic_cpu_base(d) + GIC_CPU_EOI);
> +	u32 deact_offset = GIC_CPU_EOI;
> +
> +	if (static_key_true(&supports_deactivate)) {
> +		if (primary_gic_irq(d))
> +			deact_offset = GIC_CPU_DEACTIVATE;
> +	}
> +
> +	writel_relaxed(gic_irq(d), gic_cpu_base(d) + deact_offset);
>  }
>  
>  static int gic_irq_set_irqchip_state(struct irq_data *d,
> @@ -272,11 +290,15 @@ static void __exception_irq_entry gic_handle_irq(struct pt_regs *regs)
>  		irqnr = irqstat & GICC_IAR_INT_ID_MASK;
>  
>  		if (likely(irqnr > 15 && irqnr < 1021)) {
> +			if (static_key_true(&supports_deactivate))
> +				writel_relaxed(irqstat, cpu_base + GIC_CPU_EOI);
>  			handle_domain_irq(gic->domain, irqnr, regs);
>  			continue;
>  		}
>  		if (irqnr < 16) {
>  			writel_relaxed(irqstat, cpu_base + GIC_CPU_EOI);
> +			if (static_key_true(&supports_deactivate))
> +				writel_relaxed(irqstat, cpu_base + GIC_CPU_DEACTIVATE);
>  #ifdef CONFIG_SMP
>  			handle_IPI(irqnr, regs);
>  #endif
> @@ -359,6 +381,10 @@ static void gic_cpu_if_up(void)
>  {
>  	void __iomem *cpu_base = gic_data_cpu_base(&gic_data[0]);
>  	u32 bypass = 0;
> +	u32 mode = 0;
> +
> +	if (static_key_true(&supports_deactivate))
> +		mode = GIC_CPU_CTRL_EOImodeNS;
>  
>  	/*
>  	* Preserve bypass disable bits to be written back later
> @@ -366,7 +392,7 @@ static void gic_cpu_if_up(void)
>  	bypass = readl(cpu_base + GIC_CPU_CTRL);
>  	bypass &= GICC_DIS_BYPASS_MASK;
>  
> -	writel_relaxed(bypass | GICC_ENABLE, cpu_base + GIC_CPU_CTRL);
> +	writel_relaxed(bypass | mode | GICC_ENABLE, cpu_base + GIC_CPU_CTRL);
>  }
>  
>  
> @@ -986,6 +1012,8 @@ void __init gic_init_bases(unsigned int gic_nr, int irq_start,
>  		register_cpu_notifier(&gic_cpu_notifier);
>  #endif
>  		set_handle_irq(gic_handle_irq);
> +		if (static_key_true(&supports_deactivate))
> +			pr_info ("GIC: Using split EOI/Deactivate mode\n");
>  	}
>  
>  	gic_dist_init(gic);
> @@ -1001,6 +1029,7 @@ gic_of_init(struct device_node *node, struct device_node *parent)
>  {
>  	void __iomem *cpu_base;
>  	void __iomem *dist_base;
> +	struct resource cpu_res;
>  	u32 percpu_offset;
>  	int irq;
>  
> @@ -1013,6 +1042,16 @@ gic_of_init(struct device_node *node, struct device_node *parent)
>  	cpu_base = of_iomap(node, 1);
>  	WARN(!cpu_base, "unable to map gic cpu registers\n");
>  
> +	of_address_to_resource(node, 1, &cpu_res);
> +
> +	/*
> +	 * Disable split EOI/Deactivate if either HYP is not available
> +	 * or the CPU interface is too small.
> +	 */
> +	if (gic_cnt == 0 && (!is_hyp_mode_available() ||
> +			     resource_size(&cpu_res) < SZ_8K))
> +		static_key_slow_dec(&supports_deactivate);
> +
>  	if (of_property_read_u32(node, "cpu-offset", &percpu_offset))
>  		percpu_offset = 0;
>  
> @@ -1132,6 +1171,14 @@ gic_v2_acpi_init(struct acpi_table_header *table)
>  	}
>  
>  	/*
> +	 * Disable split EOI/Deactivate if HYP is not available. ACPI
> +	 * guarantees that we'll always have a GICv2, so the CPU
> +	 * interface will always be the right size.
> +	 */
> +	if (!is_hyp_mode_available())
> +		static_key_slow_dec(&supports_deactivate);
> +
> +	/*
>  	 * Initialize zero GIC instance (no multi-GIC support). Also, set GIC
>  	 * as default IRQ domain to allow for GSI registration and GSI to IRQ
>  	 * number translation (see acpi_register_gsi() and acpi_gsi_to_irq()).
> diff --git a/include/linux/irqchip/arm-gic.h b/include/linux/irqchip/arm-gic.h
> index 9de976b..b1533c0 100644
> --- a/include/linux/irqchip/arm-gic.h
> +++ b/include/linux/irqchip/arm-gic.h
> @@ -20,9 +20,13 @@
>  #define GIC_CPU_ALIAS_BINPOINT		0x1c
>  #define GIC_CPU_ACTIVEPRIO		0xd0
>  #define GIC_CPU_IDENT			0xfc
> +#define GIC_CPU_DEACTIVATE		0x1000
>  
>  #define GICC_ENABLE			0x1
>  #define GICC_INT_PRI_THRESHOLD		0xf0
> +
> +#define GIC_CPU_CTRL_EOImodeNS		(1 << 9)
> +
>  #define GICC_IAR_INT_ID_MASK		0x3ff
>  #define GICC_INT_SPURIOUS		1023
>  #define GICC_DIS_BYPASS_MASK		0x1e0
> 



From peter at hurleysoftware.com  Mon Aug 17 09:24:20 2015
From: peter at hurleysoftware.com (Peter Hurley)
Date: Mon, 17 Aug 2015 12:24:20 -0400
Subject: [PATCH 1/4] serial: xuartps: Fix termios issue for enabling odd
 parity
In-Reply-To: <59506B47DEDD3943ABF9AC60020F4E2978D6E7EA@XAP-PVEXMBX02.xlnx.xilinx.com>
References: <5b154ba97bcd79e49e2131152eb2fc1761594a6c.1439796149.git.michal.simek@xilinx.com>
 <55D20017.4010008@hurleysoftware.com>
 <59506B47DEDD3943ABF9AC60020F4E2978D6E7EA@XAP-PVEXMBX02.xlnx.xilinx.com>
Message-ID: <55D20AB4.4030405@hurleysoftware.com>

On 08/17/2015 11:55 AM, Anirudha Sarangi wrote:
> Hi,
> 
>> -----Original Message-----
>> From: Peter Hurley [mailto:peter at hurleysoftware.com]
>> Sent: Monday, August 17, 2015 9:09 PM
>> To: Michal Simek
>> Cc: linux-kernel at vger.kernel.org; monstr at monstr.eu; Anirudha Sarangi; Soren
>> Brinkmann; Jiri Slaby; linux-serial at vger.kernel.org; Greg Kroah-Hartman; linux-
>> arm-kernel at lists.infradead.org
>> Subject: Re: [PATCH 1/4] serial: xuartps: Fix termios issue for enabling odd parity
>>
>> On 08/17/2015 03:22 AM, Michal Simek wrote:
>>> From: Anirudha Sarangi <anirudha.sarangi at xilinx.com>
>>>
>>> Existing set_termios does not handle the option for enabling odd
>>> parity. This patch fixes it.
>>
>> NAK. PARODD does not enable parity generation or detection.
>>
> What if someone is trying to change from even to odd parity?

If userspace wants odd parity, then c_cflag must have both
PARENB and PARODD set.

Just PARODD does nothing.

>From SUS v4, General Terminal Interface, 11.2.4 Control Modes;

"If PARENB is set, parity generation and detection shall be enabled
and a parity bit is added to each byte. If parity is enabled, PARODD
shall specify odd parity if set; otherwise, even parity shall be used."



> In this conditional case, we setup some register bit for the same.
> Is the above use case not a valid one?
> 
> Regards
> Anirudha
> 
>> Regards,
>> Peter Hurley
>>
>>> Signed-off-by: Anirudha Sarangi <anirudh at xilinx.com>
>>> Signed-off-by: Michal Simek <michal.simek at xilinx.com>
>>> ---
>>>
>>>  drivers/tty/serial/xilinx_uartps.c | 2 +-
>>>  1 file changed, 1 insertion(+), 1 deletion(-)
>>>
>>> diff --git a/drivers/tty/serial/xilinx_uartps.c
>>> b/drivers/tty/serial/xilinx_uartps.c
>>> index 009e0dbc12d2..a3020344ac9d 100644
>>> --- a/drivers/tty/serial/xilinx_uartps.c
>>> +++ b/drivers/tty/serial/xilinx_uartps.c
>>> @@ -723,7 +723,7 @@ static void cdns_uart_set_termios(struct uart_port
>> *port,
>>>     else
>>>             cval |= CDNS_UART_MR_STOPMODE_1_BIT; /* 1 STOP bit */
>>>
>>> -   if (termios->c_cflag & PARENB) {
>>> +   if ((termios->c_cflag & PARENB) || (termios->c_cflag & PARODD)) {
>>>             /* Mark or Space parity */
>>>             if (termios->c_cflag & CMSPAR) {
>>>                     if (termios->c_cflag & PARODD)
>>>
> 
> 
> 
> This email and any attachments are intended for the sole use of the named recipient(s) and contain(s) confidential information that may be proprietary, privileged or copyrighted under applicable law. If you are not the intended recipient, do not read, copy, or forward this email message or any attachments. Delete this email message and any attachments immediately.
> 



From catalin.marinas at arm.com  Mon Aug 17 09:40:03 2015
From: catalin.marinas at arm.com (Catalin Marinas)
Date: Mon, 17 Aug 2015 17:40:03 +0100
Subject: [PATCH v4 2/5] irqchip, gicv3: Workaround for Cavium ThunderX
 erratum 23154
In-Reply-To: <1439576885-15621-3-git-send-email-rric@kernel.org>
References: <1439576885-15621-1-git-send-email-rric@kernel.org>
 <1439576885-15621-3-git-send-email-rric@kernel.org>
Message-ID: <20150817164003.GB2906@e104818-lin.cambridge.arm.com>

On Fri, Aug 14, 2015 at 08:28:02PM +0200, Robert Richter wrote:
> +struct static_key is_cavium_thunderx = STATIC_KEY_INIT_FALSE;

This could also be "static struct ...". BTW, the use of static_key
directly is deprecated, so just do:

static DEFINE_STATIC_KEY_FALSE(is_cavium_thunderx);

-- 
Catalin


From msalter at redhat.com  Mon Aug 17 10:01:05 2015
From: msalter at redhat.com (Mark Salter)
Date: Mon, 17 Aug 2015 13:01:05 -0400
Subject: [PATCH V4 1/3] mm: add utility for early copy from unmapped ram
In-Reply-To: <1439830867-14935-1-git-send-email-msalter@redhat.com>
References: <1439830867-14935-1-git-send-email-msalter@redhat.com>
Message-ID: <1439830867-14935-2-git-send-email-msalter@redhat.com>

In some early boot circumstances, it may be necessary to copy
from RAM outside the kernel linear mapping to mapped RAM. The
need to relocate an initrd is one example in the x86 code. This
patch creates a helper function based on current x86 code.

Signed-off-by: Mark Salter <msalter at redhat.com>
---
 include/asm-generic/early_ioremap.h |  6 ++++++
 mm/early_ioremap.c                  | 22 ++++++++++++++++++++++
 2 files changed, 28 insertions(+)

diff --git a/include/asm-generic/early_ioremap.h b/include/asm-generic/early_ioremap.h
index a5de55c..e539f27 100644
--- a/include/asm-generic/early_ioremap.h
+++ b/include/asm-generic/early_ioremap.h
@@ -33,6 +33,12 @@ extern void early_ioremap_setup(void);
  */
 extern void early_ioremap_reset(void);
 
+/*
+ * Early copy from unmapped memory to kernel mapped memory.
+ */
+extern void copy_from_early_mem(void *dest, phys_addr_t src,
+				unsigned long size);
+
 #else
 static inline void early_ioremap_init(void) { }
 static inline void early_ioremap_setup(void) { }
diff --git a/mm/early_ioremap.c b/mm/early_ioremap.c
index e10ccd2..a0baeb4 100644
--- a/mm/early_ioremap.c
+++ b/mm/early_ioremap.c
@@ -217,6 +217,28 @@ early_memremap(resource_size_t phys_addr, unsigned long size)
 	return (__force void *)__early_ioremap(phys_addr, size,
 					       FIXMAP_PAGE_NORMAL);
 }
+
+#define MAX_MAP_CHUNK	(NR_FIX_BTMAPS << PAGE_SHIFT)
+
+void __init copy_from_early_mem(void *dest, phys_addr_t src, unsigned long size)
+{
+	unsigned long slop, clen;
+	char *p;
+
+	while (size) {
+		slop = src & ~PAGE_MASK;
+		clen = size;
+		if (clen > MAX_MAP_CHUNK - slop)
+			clen = MAX_MAP_CHUNK - slop;
+		p = early_memremap(src & PAGE_MASK, clen + slop);
+		memcpy(dest, p + slop, clen);
+		early_memunmap(p, clen + slop);
+		dest += clen;
+		src += clen;
+		size -= clen;
+	}
+}
+
 #else /* CONFIG_MMU */
 
 void __init __iomem *
-- 
2.4.3



From msalter at redhat.com  Mon Aug 17 10:01:06 2015
From: msalter at redhat.com (Mark Salter)
Date: Mon, 17 Aug 2015 13:01:06 -0400
Subject: [PATCH V4 2/3] arm64: support initrd outside kernel linear map
In-Reply-To: <1439830867-14935-1-git-send-email-msalter@redhat.com>
References: <1439830867-14935-1-git-send-email-msalter@redhat.com>
Message-ID: <1439830867-14935-3-git-send-email-msalter@redhat.com>

The use of mem= could leave part or all of the initrd outside of
the kernel linear map. This will lead to an error when unpacking
the initrd and a probable failure to boot. This patch catches that
situation and relocates the initrd to be fully within the linear
map.

Signed-off-by: Mark Salter <msalter at redhat.com>
---
 arch/arm64/kernel/setup.c | 62 +++++++++++++++++++++++++++++++++++++++++++++++
 1 file changed, 62 insertions(+)

diff --git a/arch/arm64/kernel/setup.c b/arch/arm64/kernel/setup.c
index f3067d4..40a894e 100644
--- a/arch/arm64/kernel/setup.c
+++ b/arch/arm64/kernel/setup.c
@@ -359,6 +359,67 @@ static void __init request_standard_resources(void)
 	}
 }
 
+#ifdef CONFIG_BLK_DEV_INITRD
+/*
+ * Relocate initrd if it is not completely within the linear mapping.
+ * This would be the case if mem= cuts out all or part of it.
+ */
+static void __init relocate_initrd(void)
+{
+	phys_addr_t orig_start = __virt_to_phys(initrd_start);
+	phys_addr_t orig_end = __virt_to_phys(initrd_end);
+	phys_addr_t ram_end = memblock_end_of_DRAM();
+	phys_addr_t new_start;
+	unsigned long size, to_free = 0;
+	void *dest;
+
+	if (orig_end <= ram_end)
+		return;
+
+	/*
+	 * Any of the original initrd which overlaps the linear map should
+	 * be freed after relocating.
+	 */
+	if (orig_start < ram_end)
+		to_free = ram_end - orig_start;
+
+	size = orig_end - orig_start;
+
+	/* initrd needs to be relocated completely inside linear mapping */
+	new_start = memblock_find_in_range(0, PFN_PHYS(max_pfn),
+					   size, PAGE_SIZE);
+	if (!new_start)
+		panic("Cannot relocate initrd of size %ld\n", size);
+	memblock_reserve(new_start, size);
+
+	initrd_start = __phys_to_virt(new_start);
+	initrd_end   = initrd_start + size;
+
+	pr_info("Moving initrd from [%llx-%llx] to [%llx-%llx]\n",
+		orig_start, orig_start + size - 1,
+		new_start, new_start + size - 1);
+
+	dest = (void *)initrd_start;
+
+	if (to_free) {
+		memcpy(dest, (void *)__phys_to_virt(orig_start), to_free);
+		dest += to_free;
+	}
+
+	copy_from_early_mem(dest, orig_start + to_free, size - to_free);
+
+	if (to_free) {
+		pr_info("Freeing original RAMDISK from [%llx-%llx]\n",
+			orig_start, orig_start + to_free - 1);
+		memblock_free(orig_start, to_free);
+	}
+}
+#else
+static inline void __init relocate_initrd(void)
+{
+}
+#endif
+
 u64 __cpu_logical_map[NR_CPUS] = { [0 ... NR_CPUS-1] = INVALID_HWID };
 
 void __init setup_arch(char **cmdline_p)
@@ -392,6 +453,7 @@ void __init setup_arch(char **cmdline_p)
 	acpi_boot_table_init();
 
 	paging_init();
+	relocate_initrd();
 	request_standard_resources();
 
 	early_ioremap_reset();
-- 
2.4.3



From msalter at redhat.com  Mon Aug 17 10:01:04 2015
From: msalter at redhat.com (Mark Salter)
Date: Mon, 17 Aug 2015 13:01:04 -0400
Subject: [PATCH V4 0/3] mm: Add generic copy from early unmapped RAM
Message-ID: <1439830867-14935-1-git-send-email-msalter@redhat.com>

When booting an arm64 kernel w/initrd using UEFI/grub, use of mem= will likely
cut off part or all of the initrd. This leaves it outside the kernel linear
map which leads to failure when unpacking. The x86 code has a similar need to
relocate an initrd outside of mapped memory in some cases.

The current x86 code uses early_memremap() to copy the original initrd from
unmapped to mapped RAM. This patchset creates a generic copy_from_early_mem()
utility based on that x86 code and has arm64 and x86 share it in their
respective initrd relocation code.

Changes from V3:

  * Fixed arm64 build error with !CONFIG_BLK_DEV_INITRD case

  * Fixed nonsensical comment in arm64 relocate_initrd()

Changes from V2:

  * Fixed sparse warning in copy_from_early_mem()

  * Removed unneeded MAX_MAP_CHUNK from x86 setup.c

  * Moved #ifdef outside arm64 relocate_initrd() definition.
  
Changes from V1:

  * Change cover letter subject to highlight the added generic code

  * Add patch for x86 to use common copy_from_early_mem()


Mark Salter (3):
  mm: add utility for early copy from unmapped ram
  arm64: support initrd outside kernel linear map
  x86: use generic early mem copy

 arch/arm64/kernel/setup.c           | 62 +++++++++++++++++++++++++++++++++++++
 arch/x86/kernel/setup.c             | 22 +------------
 include/asm-generic/early_ioremap.h |  6 ++++
 mm/early_ioremap.c                  | 22 +++++++++++++
 4 files changed, 91 insertions(+), 21 deletions(-)

-- 
2.4.3



From msalter at redhat.com  Mon Aug 17 10:01:07 2015
From: msalter at redhat.com (Mark Salter)
Date: Mon, 17 Aug 2015 13:01:07 -0400
Subject: [PATCH V4 3/3] x86: use generic early mem copy
In-Reply-To: <1439830867-14935-1-git-send-email-msalter@redhat.com>
References: <1439830867-14935-1-git-send-email-msalter@redhat.com>
Message-ID: <1439830867-14935-4-git-send-email-msalter@redhat.com>

The early_ioremap library now has a generic copy_from_early_mem()
function. Use the generic copy function for x86 relocate_initrd().

Signed-off-by: Mark Salter <msalter at redhat.com>
---
 arch/x86/kernel/setup.c | 22 +---------------------
 1 file changed, 1 insertion(+), 21 deletions(-)

diff --git a/arch/x86/kernel/setup.c b/arch/x86/kernel/setup.c
index 80f874b..21fa9a3 100644
--- a/arch/x86/kernel/setup.c
+++ b/arch/x86/kernel/setup.c
@@ -317,15 +317,12 @@ static u64 __init get_ramdisk_size(void)
 	return ramdisk_size;
 }
 
-#define MAX_MAP_CHUNK	(NR_FIX_BTMAPS << PAGE_SHIFT)
 static void __init relocate_initrd(void)
 {
 	/* Assume only end is not page aligned */
 	u64 ramdisk_image = get_ramdisk_image();
 	u64 ramdisk_size  = get_ramdisk_size();
 	u64 area_size     = PAGE_ALIGN(ramdisk_size);
-	unsigned long slop, clen, mapaddr;
-	char *p, *q;
 
 	/* We need to move the initrd down into directly mapped mem */
 	relocated_ramdisk = memblock_find_in_range(0, PFN_PHYS(max_pfn_mapped),
@@ -343,25 +340,8 @@ static void __init relocate_initrd(void)
 	printk(KERN_INFO "Allocated new RAMDISK: [mem %#010llx-%#010llx]\n",
 	       relocated_ramdisk, relocated_ramdisk + ramdisk_size - 1);
 
-	q = (char *)initrd_start;
-
-	/* Copy the initrd */
-	while (ramdisk_size) {
-		slop = ramdisk_image & ~PAGE_MASK;
-		clen = ramdisk_size;
-		if (clen > MAX_MAP_CHUNK-slop)
-			clen = MAX_MAP_CHUNK-slop;
-		mapaddr = ramdisk_image & PAGE_MASK;
-		p = early_memremap(mapaddr, clen+slop);
-		memcpy(q, p+slop, clen);
-		early_memunmap(p, clen+slop);
-		q += clen;
-		ramdisk_image += clen;
-		ramdisk_size  -= clen;
-	}
+	copy_from_early_mem((void *)initrd_start, ramdisk_image, ramdisk_size);
 
-	ramdisk_image = get_ramdisk_image();
-	ramdisk_size  = get_ramdisk_size();
 	printk(KERN_INFO "Move RAMDISK from [mem %#010llx-%#010llx] to"
 		" [mem %#010llx-%#010llx]\n",
 		ramdisk_image, ramdisk_image + ramdisk_size - 1,
-- 
2.4.3



From ddaney at caviumnetworks.com  Mon Aug 17 10:00:53 2015
From: ddaney at caviumnetworks.com (David Daney)
Date: Mon, 17 Aug 2015 10:00:53 -0700
Subject: [PATCH v4 2/5] irqchip, gicv3: Workaround for Cavium ThunderX
 erratum 23154
In-Reply-To: <1439576885-15621-3-git-send-email-rric@kernel.org>
References: <1439576885-15621-1-git-send-email-rric@kernel.org>
 <1439576885-15621-3-git-send-email-rric@kernel.org>
Message-ID: <55D21345.3040903@caviumnetworks.com>

On 08/14/2015 11:28 AM, Robert Richter wrote:
> From: Robert Richter <rrichter at cavium.com>
>
> This patch implements Cavium ThunderX erratum 23154.
>
> The gicv3 of ThunderX requires a modified version for reading the IAR
> status to ensure data synchronization. Since this is in the fast-path
> and called with each interrupt, runtime patching is used using jump
> label patching for smallest overhead (no-op). This is the same
> technique as used for tracepoints.
>
> v4:
>   * simplify code to only use cpus_have_cap() in gicv3_enable_quirks()
>
> v3:
>   * fix erratum to be dependend from midr
>   * use arm64 errata framework
>
> v2:
>   * implement code in a single asm() to keep instruction sequence
>   * added comment to the code that explains the erratum
>   * apply workaround also if running as guest, thus check MIDR
>
> Signed-off-by: Robert Richter <rrichter at cavium.com>
> ---
>   arch/arm64/Kconfig                  | 11 ++++++++++
>   arch/arm64/include/asm/cpufeature.h |  3 ++-
>   arch/arm64/include/asm/cputype.h    | 18 +++++++++-------
>   arch/arm64/kernel/cpu_errata.c      |  9 ++++++++
>   drivers/irqchip/irq-gic-v3.c        | 42 ++++++++++++++++++++++++++++++++++++-
>   5 files changed, 74 insertions(+), 9 deletions(-)
>
> diff --git a/arch/arm64/Kconfig b/arch/arm64/Kconfig
> index 0f6edb14b7e4..4f866a4c6536 100644
> --- a/arch/arm64/Kconfig
> +++ b/arch/arm64/Kconfig
> @@ -417,6 +417,17 @@ config ARM64_ERRATUM_845719
>
>   	  If unsure, say Y.
>
> +config CAVIUM_ERRATUM_23154
> +	bool "Cavium erratum 23154: Access to ICC_IAR1_EL1 is not sync'ed"
> +	depends on ARCH_THUNDER

None of the other errata depend on a specific ARCH_*.  I think we should 
remove this 'depends on', so that a generic kernel can be configured to 
work on Thunder without having to first select ARCH_THUNDER.

David Daney


> +	default y
> +	help
> +	  The gicv3 of ThunderX requires a modified version for
> +	  reading the IAR status to ensure data synchronization
> +	  (access to icc_iar1_el1 is not sync'ed before and after).
> +
> +	  If unsure, say Y.
> +
>   endmenu
>
>
>


From ulf.hansson at linaro.org  Mon Aug 17 10:11:15 2015
From: ulf.hansson at linaro.org (Ulf Hansson)
Date: Mon, 17 Aug 2015 19:11:15 +0200
Subject: [PATCH 1/2] mmc: core: enable CMD19 tuning for DDR50 mode
In-Reply-To: <1439282492-6274-1-git-send-email-21cnbao@gmail.com>
References: <1439282492-6274-1-git-send-email-21cnbao@gmail.com>
Message-ID: <CAPDyKFpXZD28NwNAhKQyxmWasVhk_7AeyOW6oXaBPHKuSTmGUA@mail.gmail.com>

On 11 August 2015 at 10:41, Barry Song <21cnbao at gmail.com> wrote:
> From: Weijun Yang <york.yang at csr.com>
>
> As SD Specifications Part1 Physical Layer Specification Version
> 3.01 says, CMD19 tuning is available for unlocked cards in transfer
> state of 1.8V signaling mode. The small difference between v3.00
> and 3.01 spec means that CMD19 tuning is also available for DDR50
> mode.

So what happens with cards following the 3.0 spec version, those
doesn't need to support the tuning CMD right? Perhaps that needs to be
addressed in this patch well!?

Kind regards
Uffe

>
> Signed-off-by: Weijun Yang <york.yang at csr.com>
> Signed-off-by: Barry Song <Baohua.Song at csr.com>
> ---
>  drivers/mmc/core/sd.c    | 1 +
>  drivers/mmc/host/sdhci.c | 1 +
>  2 files changed, 2 insertions(+)
>
> diff --git a/drivers/mmc/core/sd.c b/drivers/mmc/core/sd.c
> index 4e7366a..a1ed24d 100644
> --- a/drivers/mmc/core/sd.c
> +++ b/drivers/mmc/core/sd.c
> @@ -629,6 +629,7 @@ static int mmc_sd_init_uhs_card(struct mmc_card *card)
>          */
>         if (!mmc_host_is_spi(card->host) &&
>             (card->sd_bus_speed == UHS_SDR50_BUS_SPEED ||
> +            card->sd_bus_speed == UHS_DDR50_BUS_SPEED ||
>              card->sd_bus_speed == UHS_SDR104_BUS_SPEED))
>                 err = mmc_execute_tuning(card);
>  out:
> diff --git a/drivers/mmc/host/sdhci.c b/drivers/mmc/host/sdhci.c
> index 1dbe932..812c19b 100644
> --- a/drivers/mmc/host/sdhci.c
> +++ b/drivers/mmc/host/sdhci.c
> @@ -1891,6 +1891,7 @@ static int sdhci_execute_tuning(struct mmc_host *mmc, u32 opcode)
>                 break;
>
>         case MMC_TIMING_UHS_SDR104:
> +       case MMC_TIMING_UHS_DDR50:
>                 break;
>
>         case MMC_TIMING_UHS_SDR50:
> --
> 1.9.1
>


From linux at mniewoehner.de  Mon Aug 17 10:38:22 2015
From: linux at mniewoehner.de (Michael Niewoehner)
Date: Mon, 17 Aug 2015 19:38:22 +0200
Subject: [PATCH] clk: rockchip: add pclk_cpu to the list of rk3188 critical
 clocks
Message-ID: <5400BEF8-5245-4F7B-845B-D326A7BC56B5@mniewoehner.de>

gpio clock is getting disabled to save power but pclk_cpu is needed for act8865 regulator

Signed-off-by: Michael Niewoehner <linux at mniewoehner.de>
---
 drivers/clk/rockchip/clk-rk3188.c | 1 +
 1 file changed, 1 insertion(+)

diff --git a/drivers/clk/rockchip/clk-rk3188.c b/drivers/clk/rockchip/clk-rk3188.c
index e4f9d47..1c93229 100644
--- a/drivers/clk/rockchip/clk-rk3188.c
+++ b/drivers/clk/rockchip/clk-rk3188.c
@@ -708,6 +708,7 @@ static const char *const rk3188_critical_clocks[] __initconst = {
 	"aclk_cpu",
 	"aclk_peri",
 	"hclk_peri",
+	"pclk_cpu",
 };
 
 static void __init rk3188_common_clk_init(struct device_node *np)
-- 
2.5.0


From eric at anholt.net  Mon Aug 17 10:56:23 2015
From: eric at anholt.net (Eric Anholt)
Date: Mon, 17 Aug 2015 10:56:23 -0700
Subject: [PATCH 3/7] drm/vc4: Add KMS support for Raspberry Pi.
In-Reply-To: <55CEC3D8.7060103@wwwdotorg.org>
References: <1439427380-2436-1-git-send-email-eric@anholt.net>
 <1439427380-2436-4-git-send-email-eric@anholt.net>
 <55CEC3D8.7060103@wwwdotorg.org>
Message-ID: <877fotx0hk.fsf@eliezer.anholt.net>

r<#secure method=pgpmime mode=sign>
Stephen Warren <swarren at wwwdotorg.org> writes:

> On 08/12/2015 06:56 PM, Eric Anholt wrote:
>> This is the start of a full VC4 driver.  Right now this just supports
>> configuring the display using a pre-existing video mode (because
>> changing the pixel clock isn't available yet, and doesn't work when it
>> is).  However, this is enough for fbcon and bringing up X using
>> xf86-video-modesetting.
>
>> diff --git a/drivers/gpu/drm/vc4/Kconfig b/drivers/gpu/drm/vc4/Kconfig
>
>> +config DRM_VC4
>> +	tristate "Broadcom VC4 Graphics"
>
>> +	help
>> +	  Choose this option if you have a system that has a Broadcom
>> +	  VC4 GPU, such as the Raspberry Pi or other BCM2708/BCM2835.
>> +
>> +	  This driver requires that "avoid_warnings=2" be present in
>> +	  the config.txt for the firmware, to keep it from smashing
>> +	  our display setup.
>
> The need for "avoid_warnings=2" seems like it will trip people up. I
> don't think it's in any config.txt I've seen. Can you expand more on that?

The warnings thing is the firmware watching for undervoltage and then it
calls into dispmanx to overlay a little rainbow box on the screen.  This
of course interferes with our display setup.

I think we'll be able to wire up notifications to Linux for
undervoltage, at which point we can do something useful with that
information, ourselves.


From heiko at sntech.de  Mon Aug 17 11:01:32 2015
From: heiko at sntech.de (Heiko Stuebner)
Date: Mon, 17 Aug 2015 20:01:32 +0200
Subject: [PATCH] clk: rockchip: add pclk_cpu to the list of rk3188
 critical clocks
In-Reply-To: <5400BEF8-5245-4F7B-845B-D326A7BC56B5@mniewoehner.de>
References: <5400BEF8-5245-4F7B-845B-D326A7BC56B5@mniewoehner.de>
Message-ID: <5275855.eah07vmf4I@phil>

Hi,

Am Montag, 17. August 2015, 19:38:22 schrieb Michael Niewoehner:
> gpio clock is getting disabled to save power but pclk_cpu is needed for
> act8865 regulator

Please refine the commit message a bit :-) . Something along

pclk_cpu needs to keep running and with the recent gpio clock
handling this is not always the case anymore. So add it to the list
of critical clocks.


and also please add "Linus Walleij <linus.walleij at linaro.org>" to the list of 
recipients. As the gpio clock handling change does go through his tree, the 
matching critical clock handling should also go through him.


Heiko

> 
> Signed-off-by: Michael Niewoehner <linux at mniewoehner.de>
> ---
>  drivers/clk/rockchip/clk-rk3188.c | 1 +
>  1 file changed, 1 insertion(+)
> 
> diff --git a/drivers/clk/rockchip/clk-rk3188.c
> b/drivers/clk/rockchip/clk-rk3188.c index e4f9d47..1c93229 100644
> --- a/drivers/clk/rockchip/clk-rk3188.c
> +++ b/drivers/clk/rockchip/clk-rk3188.c
> @@ -708,6 +708,7 @@ static const char *const rk3188_critical_clocks[]
> __initconst = { "aclk_cpu",
>  	"aclk_peri",
>  	"hclk_peri",
> +	"pclk_cpu",
>  };
> 
>  static void __init rk3188_common_clk_init(struct device_node *np)



From anirudha.sarangi at xilinx.com  Mon Aug 17 11:06:02 2015
From: anirudha.sarangi at xilinx.com (Anirudha Sarangi)
Date: Mon, 17 Aug 2015 18:06:02 +0000
Subject: [PATCH 1/4] serial: xuartps: Fix termios issue for enabling odd
 parity
In-Reply-To: <55D20AB4.4030405@hurleysoftware.com>
References: <5b154ba97bcd79e49e2131152eb2fc1761594a6c.1439796149.git.michal.simek@xilinx.com>
 <55D20017.4010008@hurleysoftware.com>
 <59506B47DEDD3943ABF9AC60020F4E2978D6E7EA@XAP-PVEXMBX02.xlnx.xilinx.com>
 <55D20AB4.4030405@hurleysoftware.com>
Message-ID: <59506B47DEDD3943ABF9AC60020F4E2978D6EDB3@XAP-PVEXMBX02.xlnx.xilinx.com>

Hi,

> -----Original Message-----
> From: Peter Hurley [mailto:peter at hurleysoftware.com]
> Sent: Monday, August 17, 2015 9:54 PM
> To: Anirudha Sarangi; Michal Simek
> Cc: linux-kernel at vger.kernel.org; monstr at monstr.eu; Soren Brinkmann; Jiri
> Slaby; linux-serial at vger.kernel.org; Greg Kroah-Hartman; linux-arm-
> kernel at lists.infradead.org
> Subject: Re: [PATCH 1/4] serial: xuartps: Fix termios issue for enabling odd parity
>
> On 08/17/2015 11:55 AM, Anirudha Sarangi wrote:
> > Hi,
> >
> >> -----Original Message-----
> >> From: Peter Hurley [mailto:peter at hurleysoftware.com]
> >> Sent: Monday, August 17, 2015 9:09 PM
> >> To: Michal Simek
> >> Cc: linux-kernel at vger.kernel.org; monstr at monstr.eu; Anirudha Sarangi;
> >> Soren Brinkmann; Jiri Slaby; linux-serial at vger.kernel.org; Greg
> >> Kroah-Hartman; linux- arm-kernel at lists.infradead.org
> >> Subject: Re: [PATCH 1/4] serial: xuartps: Fix termios issue for
> >> enabling odd parity
> >>
> >> On 08/17/2015 03:22 AM, Michal Simek wrote:
> >>> From: Anirudha Sarangi <anirudha.sarangi at xilinx.com>
> >>>
> >>> Existing set_termios does not handle the option for enabling odd
> >>> parity. This patch fixes it.
> >>
> >> NAK. PARODD does not enable parity generation or detection.
> >>
> > What if someone is trying to change from even to odd parity?
>
> If userspace wants odd parity, then c_cflag must have both PARENB and PARODD
> set.
>
> Just PARODD does nothing.
>
> From SUS v4, General Terminal Interface, 11.2.4 Control Modes;
>
> "If PARENB is set, parity generation and detection shall be enabled and a parity
> bit is added to each byte. If parity is enabled, PARODD shall specify odd parity if
> set; otherwise, even parity shall be used."
>
>
Thanks a lot. I will incorporate the changes.
>
> > In this conditional case, we setup some register bit for the same.
> > Is the above use case not a valid one?
> >
> > Regards
> > Anirudha
> >
> >> Regards,
> >> Peter Hurley
> >>
> >>> Signed-off-by: Anirudha Sarangi <anirudh at xilinx.com>
> >>> Signed-off-by: Michal Simek <michal.simek at xilinx.com>
> >>> ---
> >>>
> >>>  drivers/tty/serial/xilinx_uartps.c | 2 +-
> >>>  1 file changed, 1 insertion(+), 1 deletion(-)
> >>>
> >>> diff --git a/drivers/tty/serial/xilinx_uartps.c
> >>> b/drivers/tty/serial/xilinx_uartps.c
> >>> index 009e0dbc12d2..a3020344ac9d 100644
> >>> --- a/drivers/tty/serial/xilinx_uartps.c
> >>> +++ b/drivers/tty/serial/xilinx_uartps.c
> >>> @@ -723,7 +723,7 @@ static void cdns_uart_set_termios(struct
> >>> uart_port
> >> *port,
> >>>     else
> >>>             cval |= CDNS_UART_MR_STOPMODE_1_BIT; /* 1 STOP bit */
> >>>
> >>> -   if (termios->c_cflag & PARENB) {
> >>> +   if ((termios->c_cflag & PARENB) || (termios->c_cflag & PARODD))
> >>> + {
> >>>             /* Mark or Space parity */
> >>>             if (termios->c_cflag & CMSPAR) {
> >>>                     if (termios->c_cflag & PARODD)
> >>>
> >
> >
> >
> > This email and any attachments are intended for the sole use of the named
> recipient(s) and contain(s) confidential information that may be proprietary,
> privileged or copyrighted under applicable law. If you are not the intended
> recipient, do not read, copy, or forward this email message or any attachments.
> Delete this email message and any attachments immediately.
> >



This email and any attachments are intended for the sole use of the named recipient(s) and contain(s) confidential information that may be proprietary, privileged or copyrighted under applicable law. If you are not the intended recipient, do not read, copy, or forward this email message or any attachments. Delete this email message and any attachments immediately.


From anirudha.sarangi at xilinx.com  Mon Aug 17 11:07:00 2015
From: anirudha.sarangi at xilinx.com (Anirudha Sarangi)
Date: Mon, 17 Aug 2015 18:07:00 +0000
Subject: [PATCH 2/4] serial: xuartps: Do not handle overrun errors under
 IGNPAR option
In-Reply-To: <55D20992.60302@hurleysoftware.com>
References: <5b154ba97bcd79e49e2131152eb2fc1761594a6c.1439796149.git.michal.simek@xilinx.com>
 <41df6eb35d69801afa5b686a6974e3c3bf65178a.1439796149.git.michal.simek@xilinx.com>
 <55D20297.6010500@hurleysoftware.com>
 <59506B47DEDD3943ABF9AC60020F4E2978D6E7FF@XAP-PVEXMBX02.xlnx.xilinx.com>
 <55D20992.60302@hurleysoftware.com>
Message-ID: <59506B47DEDD3943ABF9AC60020F4E2978D6EDC0@XAP-PVEXMBX02.xlnx.xilinx.com>

Hi,

> -----Original Message-----
> From: Peter Hurley [mailto:peter at hurleysoftware.com]
> Sent: Monday, August 17, 2015 9:50 PM
> To: Anirudha Sarangi; Michal Simek
> Cc: linux-kernel at vger.kernel.org; monstr at monstr.eu; Soren Brinkmann; Jiri
> Slaby; linux-serial at vger.kernel.org; Greg Kroah-Hartman; linux-arm-
> kernel at lists.infradead.org
> Subject: Re: [PATCH 2/4] serial: xuartps: Do not handle overrun errors under
> IGNPAR option
>
> On 08/17/2015 11:58 AM, Anirudha Sarangi wrote:
> > Hi,
> >
> >> -----Original Message-----
> >> From: Peter Hurley [mailto:peter at hurleysoftware.com]
> >> Sent: Monday, August 17, 2015 9:20 PM
> >> To: Michal Simek
> >> Cc: linux-kernel at vger.kernel.org; monstr at monstr.eu; Anirudha Sarangi;
> >> Soren Brinkmann; Jiri Slaby; linux-serial at vger.kernel.org; Greg
> >> Kroah-Hartman; linux- arm-kernel at lists.infradead.org
> >> Subject: Re: [PATCH 2/4] serial: xuartps: Do not handle overrun
> >> errors under IGNPAR option
> >>
> >> On 08/17/2015 03:22 AM, Michal Simek wrote:
> >>> From: Anirudha Sarangi <anirudha.sarangi at xilinx.com>
> >>>
> >>> The existing implementation includes overrun errors under IGNPAR
> >>> option. This patch fixes it by including only parity and framing
> >>> error under IGNPAR option.
> >>
> >> The convention adopted by Linux serial drivers is to ignore overrun
> >> errors if both IGNPAR and IGNBRK are set.
> >>
> > I just followed the set_termios documentation, which says that IGNPAR is for
> parity and framing.
> > The current controller does not support break detection reliably.
> > That is probably why we don?t have IGNBRK.
>
> My point is about how a user-space process tells the serial driver to ignore
> overrun errors, as well, and not specifically about break handling.
>
I understand and this particular change is not very important in the patch set.
I can happily remove it.

Regards
Anirudha
> >
> > Regards
> > Anirudha
> >
> >> Regards,
> >> Peter Hurley
> >>
> >>> Signed-off-by: Anirudha Sarangi <anirudh at xilinx.com>
> >>> Signed-off-by: Michal Simek <michal.simek at xilinx.com>
> >>> ---
> >>>
> >>>  drivers/tty/serial/xilinx_uartps.c | 2 +-
> >>>  1 file changed, 1 insertion(+), 1 deletion(-)
> >>>
> >>> diff --git a/drivers/tty/serial/xilinx_uartps.c
> >>> b/drivers/tty/serial/xilinx_uartps.c
> >>> index a3020344ac9d..c4437e8929ff 100644
> >>> --- a/drivers/tty/serial/xilinx_uartps.c
> >>> +++ b/drivers/tty/serial/xilinx_uartps.c
> >>> @@ -691,7 +691,7 @@ static void cdns_uart_set_termios(struct
> >>> uart_port *port,
> >>>
> >>>     if (termios->c_iflag & IGNPAR)
> >>>             port->ignore_status_mask |= CDNS_UART_IXR_PARITY |
> >>> -                   CDNS_UART_IXR_FRAMING |
> >> CDNS_UART_IXR_OVERRUN;
> >>> +                                       CDNS_UART_IXR_FRAMING;
> >>>
> >>>     /* ignore all characters if CREAD is not set */
> >>>     if ((termios->c_cflag & CREAD) == 0)
> >>>
> >
> >
> >
> > This email and any attachments are intended for the sole use of the named
> recipient(s) and contain(s) confidential information that may be proprietary,
> privileged or copyrighted under applicable law. If you are not the intended
> recipient, do not read, copy, or forward this email message or any attachments.
> Delete this email message and any attachments immediately.
> >



This email and any attachments are intended for the sole use of the named recipient(s) and contain(s) confidential information that may be proprietary, privileged or copyrighted under applicable law. If you are not the intended recipient, do not read, copy, or forward this email message or any attachments. Delete this email message and any attachments immediately.


From tixy at linaro.org  Mon Aug 17 11:17:53 2015
From: tixy at linaro.org (Jon Medhurst (Tixy))
Date: Mon, 17 Aug 2015 19:17:53 +0100
Subject: [PATCH 2/4] drm: Add support for ARM's HDLCD controller.
In-Reply-To: <1438784892-27888-3-git-send-email-Liviu.Dudau@arm.com>
References: <1438784892-27888-1-git-send-email-Liviu.Dudau@arm.com>
 <1438784892-27888-3-git-send-email-Liviu.Dudau@arm.com>
Message-ID: <1439835473.3341.88.camel@linaro.org>

I haven't reviewed the code in detail, just had one comment I alluded to
in a private email the other day...

On Wed, 2015-08-05 at 15:28 +0100, Liviu Dudau wrote:

> diff --git a/drivers/gpu/drm/arm/hdlcd_crtc.c b/drivers/gpu/drm/arm/hdlcd_crtc.c
[...]
> +void hdlcd_set_scanout(struct hdlcd_drm_private *hdlcd)
> +{
> +	struct drm_framebuffer *fb = hdlcd->crtc.primary->fb;
> +	struct drm_gem_cma_object *gem;
> +	unsigned int depth, bpp;
> +	dma_addr_t scanout_start;
> +
> +	drm_fb_get_bpp_depth(fb->pixel_format, &depth, &bpp);
> +	gem = drm_fb_cma_get_gem_obj(fb, 0);
> +
> +	scanout_start = gem->paddr + fb->offsets[0] +
> +		(hdlcd->crtc.y * fb->pitches[0]) + (hdlcd->crtc.x * bpp/8);
> +
> +	hdlcd_write(hdlcd, HDLCD_REG_FB_BASE, scanout_start);
> +}
> +

The above function accesses various pointers and values, which
presumably all need to be valid and consistent. However...

[...]
> diff --git a/drivers/gpu/drm/arm/hdlcd_drv.c b/drivers/gpu/drm/arm/hdlcd_drv.c
[...]
> +static irqreturn_t hdlcd_irq(int irq, void *arg)
> +{
> +	struct drm_device *dev = arg;
> +	struct hdlcd_drm_private *hdlcd = dev->dev_private;
> +	unsigned long irq_status;
> +
> +	irq_status = hdlcd_read(hdlcd, HDLCD_REG_INT_STATUS);
> +
> +#ifdef CONFIG_DEBUG_FS
> +	if (irq_status & HDLCD_INTERRUPT_UNDERRUN) {
> +		atomic_inc(&hdlcd->buffer_underrun_count);
> +	}
> +	if (irq_status & HDLCD_INTERRUPT_DMA_END) {
> +		atomic_inc(&hdlcd->dma_end_count);
> +	}
> +	if (irq_status & HDLCD_INTERRUPT_BUS_ERROR) {
> +		atomic_inc(&hdlcd->bus_error_count);
> +	}
> +	if (irq_status & HDLCD_INTERRUPT_VSYNC) {
> +		atomic_inc(&hdlcd->vsync_count);
> +	}
> +#endif
> +	if (irq_status & HDLCD_INTERRUPT_VSYNC) {
> +		struct drm_pending_vblank_event *event;
> +		unsigned long flags;
> +
> +		hdlcd_set_scanout(hdlcd);

hdlcd_set_scanout is being called on every vsync interrupt, can we
guarantee that is safe? What if we're in the middle of a page flip or
panning operation? Seems to me that there is at least scope for
incorrect addresses being calculated leading to a nasty glitch on the
screen for one frame. And in the worst case, possibly invalid pointer
being dereferenced.

So, if scanout needs to be set on every vsync, would it not be safer
(and more efficient) to have a single variable storing the value to use
during interrupts, and recalculate that value outside of interrupts
whenever things are changed?

-- 
Tixy



From eric at anholt.net  Mon Aug 17 11:30:14 2015
From: eric at anholt.net (Eric Anholt)
Date: Mon, 17 Aug 2015 11:30:14 -0700
Subject: [PATCH 1/7] drm/vc4: Add devicetree bindings for VC4.
In-Reply-To: <55CEC25E.7070303@wwwdotorg.org>
References: <1439427380-2436-1-git-send-email-eric@anholt.net>
 <1439427380-2436-2-git-send-email-eric@anholt.net>
 <55CEC25E.7070303@wwwdotorg.org>
Message-ID: <874mjxwyx5.fsf@eliezer.anholt.net>

Stephen Warren <swarren at wwwdotorg.org> writes:

> On 08/12/2015 06:56 PM, Eric Anholt wrote:
>> Signed-off-by: Eric Anholt <eric at anholt.net>
>
> This one definitely needs a patch description, since someone might not
> know what a VC4 is, and "git log" won't show the text from the binding
> doc itself. I'd suggest adding the initial paragraph of the binding doc
> as the patch description, or more.
>
>> diff --git a/Documentation/devicetree/bindings/gpu/brcm,bcm-vc4.txt b/Documentation/devicetree/bindings/gpu/brcm,bcm-vc4.txt

>> +- hvss:		List of references to HVS video scalers
>> +- encoders:	List of references to output encoders (HDMI, SDTV)
>
> Would it make sense to make all those nodes child node of the vc4
> object. That way, there's no need to have these lists of objects; they
> can be automatically built up as the DT is enumerated. I know that e.g.
> the NVIDIA Tegra host1x binding works this way, and I think it may have
> been inspired by other similar cases.

I've looked at tegra, and the component system used by msm appears to be
nicer than it.  To follow tegra's model, it looks like I need to build
this extra bus thing corresponding to host1x that is effectively the
drivers/base/component.c code, so that I can get at vc4's structure from
the component drivers.

> Of course, this is only appropriate if the HW modules really are
> logically children of the VC4 HW module. Perhaps they aren't. If they
> aren't though, I wonder what this "vc4" module actually represents in HW?

It's the subsystem, same as we use a subsystem node for msm, sti,
rockchip, imx, and exynos.  This appears to be the common model of how
the collection of graphics-related components is represented in the DT.
-------------- next part --------------
A non-text attachment was scrubbed...
Name: signature.asc
Type: application/pgp-signature
Size: 818 bytes
Desc: not available
URL: <http://lists.infradead.org/pipermail/linux-arm-kernel/attachments/20150817/0b3f40da/attachment.sig>

From eric at anholt.net  Mon Aug 17 11:35:30 2015
From: eric at anholt.net (Eric Anholt)
Date: Mon, 17 Aug 2015 11:35:30 -0700
Subject: [PATCH 6/7] ARM: bcm2835: Add the DDC I2C controller to the
 device tree.
In-Reply-To: <55CEC567.109@wwwdotorg.org>
References: <1439427380-2436-1-git-send-email-eric@anholt.net>
 <1439427380-2436-7-git-send-email-eric@anholt.net>
 <55CEC567.109@wwwdotorg.org>
Message-ID: <871tf1wyod.fsf@eliezer.anholt.net>

Stephen Warren <swarren at wwwdotorg.org> writes:

> On 08/12/2015 06:56 PM, Eric Anholt wrote:
>> We need to use it for getting video modes over HDMI.
>
>> diff --git a/arch/arm/boot/dts/bcm2835.dtsi b/arch/arm/boot/dts/bcm2835.dtsi
>
>> +		i2c2: i2c at 7e805000 {
>> +			compatible = "brcm,bcm2835-i2c";
>> +			reg = <0x7e805000 0x1000>;
>> +			interrupts = <2 21>;
>> +			clocks = <&clk_i2c>;
>> +			#address-cells = <1>;
>> +			#size-cells = <0>;
>> +		};
>
> In an SoC .dtsi file, you'd typically write:
>
> 	status = "disabled";
>
> ... in all nodes that represent IO controllers that interface to
> external HW, so that board DT files can/must explicitly choose to enable
> the device if it's actually in use on the board. Some systems might not
> have HDMI and hence might not hook up the HDMI_SCL/SDA pads.
>
> BCM2835-ARM-Peripherals.pdf states "Note that the BSC2 master is used
> dedicated with the HDMI interface and should not be accessed by user
> programs.". Does this imply the Linux kernel shouldn't be touching this
> I2C controller; that the VC4 firmware might also be attempting to use
> it? I wonder how any such sharing of the HW would work.

In order for *any* of this driver to work, we need to ensure that the
firmware doesn't try to write to the corresponding part of the hardware.
DDC I2C is no different.  All that will cause the firmware to do
anything with display is generating mbox/dispmanx requests (through the
firmware driver), and the undervoltage warnings.
-------------- next part --------------
A non-text attachment was scrubbed...
Name: signature.asc
Type: application/pgp-signature
Size: 818 bytes
Desc: not available
URL: <http://lists.infradead.org/pipermail/linux-arm-kernel/attachments/20150817/39e1921f/attachment-0001.sig>

From peter at hurleysoftware.com  Mon Aug 17 11:46:26 2015
From: peter at hurleysoftware.com (Peter Hurley)
Date: Mon, 17 Aug 2015 14:46:26 -0400
Subject: [PATCH 4/4] serial: xuartps: Rewrite the interrupt handling logic
In-Reply-To: <59506B47DEDD3943ABF9AC60020F4E2978D6E80A@XAP-PVEXMBX02.xlnx.xilinx.com>
References: <5b154ba97bcd79e49e2131152eb2fc1761594a6c.1439796149.git.michal.simek@xilinx.com>
 <ead0c38140e815133a47797a2527229a2fc077c1.1439796149.git.michal.simek@xilinx.com>
 <55D2040F.1010205@hurleysoftware.com>
 <59506B47DEDD3943ABF9AC60020F4E2978D6E80A@XAP-PVEXMBX02.xlnx.xilinx.com>
Message-ID: <55D22C02.5000702@hurleysoftware.com>

On 08/17/2015 12:00 PM, Anirudha Sarangi wrote:
>> From: Peter Hurley [mailto:peter at hurleysoftware.com]
>> On 08/17/2015 03:22 AM, Michal Simek wrote:
>>> From: Anirudha Sarangi <anirudha.sarangi at xilinx.com>
>>>
>>> The existing interrupt handling logic has followins issues.
>>> - Upon a parity error with default configuration, the control
>>>   never comes out of the ISR thereby hanging Linux.
>>> - The error handling logic around framing and parity error are buggy.
>>>   There are chances that the errors will never be captured.
>>> - The existing ISR is just too long.
>>> This patch fixes all these concerns.
>>
>> This patch is unreviewable. Please break this down into multiple patches.
>>
> Thanks. Let me give a shot. It is just breaking the single big ISR that has both Rx and Tx in a single function into smaller ones.
> Not sure how I will create smaller patches, but I will try and get back.

I would start with a refactor patch that splits up the ISR but
makes no other functional changes. Then add the bug fix patches.

Regards,
Peter Hurley

ps - The email signature below is not appropriate for lkml.

> 
> This email and any attachments are intended for the sole use of the named recipient(s) and contain(s) confidential information that may be proprietary, privileged or copyrighted under applicable law. If you are not the intended recipient, do not read, copy, or forward this email message or any attachments. Delete this email message and any attachments immediately.
> 



From eric at anholt.net  Mon Aug 17 11:47:55 2015
From: eric at anholt.net (Eric Anholt)
Date: Mon, 17 Aug 2015 11:47:55 -0700
Subject: [PATCH 2/7] MAINTAINERS: Add myself for the new VC4 (RPi GPU)
 graphics driver.
In-Reply-To: <55CEC29C.806@wwwdotorg.org>
References: <1439427380-2436-1-git-send-email-eric@anholt.net>
 <1439427380-2436-3-git-send-email-eric@anholt.net>
 <55CEC29C.806@wwwdotorg.org>
Message-ID: <871tf1iwf8.fsf@eliezer.anholt.net>

Stephen Warren <swarren at wwwdotorg.org> writes:

> On 08/12/2015 06:56 PM, Eric Anholt wrote:
>
>> diff --git a/MAINTAINERS b/MAINTAINERS
>
>> +DRM DRIVERS FOR VC4
>> +M:	Eric Anholt <eric at anholt.net>
>> +T:	git git://github.com/anholt/linux
>> +S:	Maintained
>> +F:	drivers/gpu/drm/vc4/*
>
> S: Supported

Fixed.
-------------- next part --------------
A non-text attachment was scrubbed...
Name: signature.asc
Type: application/pgp-signature
Size: 818 bytes
Desc: not available
URL: <http://lists.infradead.org/pipermail/linux-arm-kernel/attachments/20150817/20d212eb/attachment.sig>

From linux at mniewoehner.de  Mon Aug 17 11:51:14 2015
From: linux at mniewoehner.de (Michael Niewoehner)
Date: Mon, 17 Aug 2015 20:51:14 +0200
Subject: [PATCH] clk: rockchip: add pclk_cpu to the list of rk3188
 critical clocks
In-Reply-To: <5275855.eah07vmf4I@phil>
References: <5400BEF8-5245-4F7B-845B-D326A7BC56B5@mniewoehner.de>
 <5275855.eah07vmf4I@phil>
Message-ID: <9DBF9CCE-196E-43FB-BA76-BFB4B5F47A22@mniewoehner.de>

Hi Heiko,

I merged yours and mine :-)


pclk_cpu needs to keep running because it is needed for devices like
the act8865 regulator but with the recent gpio clock handling this is
not always the case anymore. So add it to the list of critical clocks.

Signed-off-by: Michael Niewoehner <linux at mniewoehner.de>
---
drivers/clk/rockchip/clk-rk3188.c | 1 +
1 file changed, 1 insertion(+)

diff --git a/drivers/clk/rockchip/clk-rk3188.c b/drivers/clk/rockchip/clk-rk3188.c
index e4f9d47..1c93229 100644
--- a/drivers/clk/rockchip/clk-rk3188.c
+++ b/drivers/clk/rockchip/clk-rk3188.c
@@ -708,6 +708,7 @@ static const char *const rk3188_critical_clocks[] __initconst = {
	"aclk_cpu",
	"aclk_peri",
	"hclk_peri",
+	"pclk_cpu",
};

static void __init rk3188_common_clk_init(struct device_node *np)
-- 
2.5.0





Am 17.08.2015 um 20:01 schrieb Heiko Stuebner <heiko at sntech.de>:

> Hi,
> 
> Am Montag, 17. August 2015, 19:38:22 schrieb Michael Niewoehner:
>> gpio clock is getting disabled to save power but pclk_cpu is needed for
>> act8865 regulator
> 
> Please refine the commit message a bit :-) . Something along
> 
> pclk_cpu needs to keep running and with the recent gpio clock
> handling this is not always the case anymore. So add it to the list
> of critical clocks.
> 
> 
> and also please add "Linus Walleij <linus.walleij at linaro.org>" to the list of 
> recipients. As the gpio clock handling change does go through his tree, the 
> matching critical clock handling should also go through him.
> 
> 
> Heiko
> 
>> 
>> Signed-off-by: Michael Niewoehner <linux at mniewoehner.de>
>> ---
>> drivers/clk/rockchip/clk-rk3188.c | 1 +
>> 1 file changed, 1 insertion(+)
>> 
>> diff --git a/drivers/clk/rockchip/clk-rk3188.c
>> b/drivers/clk/rockchip/clk-rk3188.c index e4f9d47..1c93229 100644
>> --- a/drivers/clk/rockchip/clk-rk3188.c
>> +++ b/drivers/clk/rockchip/clk-rk3188.c
>> @@ -708,6 +708,7 @@ static const char *const rk3188_critical_clocks[]
>> __initconst = { "aclk_cpu",
>> 	"aclk_peri",
>> 	"hclk_peri",
>> +	"pclk_cpu",
>> };
>> 
>> static void __init rk3188_common_clk_init(struct device_node *np)
> 




From leoli at freescale.com  Mon Aug 17 12:10:46 2015
From: leoli at freescale.com (Li Yang)
Date: Mon, 17 Aug 2015 14:10:46 -0500
Subject: [PATCH v2] dmaengine: fsl-edma: add PM suspend/resume support
In-Reply-To: <CY1PR0301MB1562FBE9818C1973651D2B7183790@CY1PR0301MB1562.namprd03.prod.outlook.com>
References: <1437469005-3162-1-git-send-email-yao.yuan@freescale.com>
 <CADRPPNQJi_x+mdQV=DEVuhCL_p6VOWcPiV3jzioeRdWgSW2w3g@mail.gmail.com>
 <CY1PR0301MB15628DD5CFCE2B65BF4FECB2837C0@CY1PR0301MB1562.namprd03.prod.outlook.com>
 <CADRPPNS_wzX+mwT0L-H=ZP9w8gH9W4O9KUqnGYiAc39S5v4qLA@mail.gmail.com>
 <CY1PR0301MB1562103588FB0C6BEFDDBF3C83790@CY1PR0301MB1562.namprd03.prod.outlook.com>
 <55D183D1.9020401@nigelcunningham.com.au>
 <CY1PR0301MB1562FBE9818C1973651D2B7183790@CY1PR0301MB1562.namprd03.prod.outlook.com>
Message-ID: <CADRPPNRaDaUBD1JG_QHrEQ5pKP9Ap1hV+bBdUnC-V32Nzr2qQw@mail.gmail.com>

On Mon, Aug 17, 2015 at 2:22 AM, Yao Yuan <yao.yuan at freescale.com> wrote:
> Hi Nigel,
>
> On Mon, Aug 17, 2015 at 2:49 PM, Nigel Cunningham < nigel at nigelcunningham.com.au > wrote:
>> On 17/08/15 13:59, Yao Yuan wrote:
>> > On Sat, Aug 15, 2015 at 7:48 AM, pku.leo < pku.leo at gmail.com > wrote:
>> >> On Fri, Aug 14, 2015 at 1:24 AM, Yao Yuan <yao.yuan at freescale.com> wrote:
>> >>> Hi Leo,
>> >>>
>> >>> Thanks for your review.
>> >>> About those two methods for DMA suspend that you have mentioned.
>> We
>> >> have a lot of the discussions in other DMA driver like DMA for
>> >> Freescale PowerPC.
>> >>> Finally, we think the device which used the DMA transmission service
>> >>> should
>> >> cancel the transmission service in its suspend.
>> >>> So DMA in suspend should be idle.
>> >> If that's the case you should clearly state this in the commit
>> >> message and in code, although I don't know if it is safe to make such
>> >> assumption.  There could be user of the DMA that doesn't track the
>> completion of transfers.
>> > I think it should be safe. In my opinion, even some client(the user of
>> > the DMA) forget to cancel its DMA transmission, It will just lead to PM failed
>> but no other system and data risk.
>> > Although we should first fix the behavior of the client.
>> > Once you are no need the DMA transmission, why not stop it?
>> >
>> > Is it right?
>> Think of it from the end user perspective. Would you like your laptop (or
>> whatever) to refuse to suspend because of this condition? The user may well
>> expect that closing the lid on their laptop will reliably lead to it suspending to
>> ram. Returning a failure here could result in a loss of data if the condition is not
>> detected and the machine subsequently runs out of power.
>>
>
> Yes, the user may well expect that closing the lid on their laptop will reliably lead to it suspending to ram.
> So the client(the user of the DMA) must  to PAUSE or terminate the DMA transmission.
>
> We need to rely on client doing the right thing here.
> The DMA should not make a decision instead of client.
> If the DMA is not idle in DMA suspend, it should be the client's issue.
> We don't know what the client really want to do, so just return the non-success value.

The problem here is that neither the client nor the DMA controller
driver should easily decide to stop the suspend entrance and rollback.
I don't think the non-idle situation is serious enough to cause a
rollback.  You should do whatever can be done with the DMA
controller(such as stop the controller and leave whatever to be done
to the wake up) and continue with the suspend.

Regards,
Leo


From davem at davemloft.net  Mon Aug 17 12:25:48 2015
From: davem at davemloft.net (David Miller)
Date: Mon, 17 Aug 2015 12:25:48 -0700 (PDT)
Subject: [PATCH 2/5] net: add Hisilicon Network Subsystem hnae
 framework support
In-Reply-To: <1439548222-231611-3-git-send-email-liguozhu@hisilicon.com>
References: <1439548222-231611-1-git-send-email-liguozhu@hisilicon.com>
 <1439548222-231611-3-git-send-email-liguozhu@hisilicon.com>
Message-ID: <20150817.122548.203456335027850542.davem@davemloft.net>

From: Kenneth Lee <liguozhu at hisilicon.com>
Date: Fri, 14 Aug 2015 18:30:19 +0800

> diff --git a/drivers/net/ethernet/hisilicon/hns/hnae.c b/drivers/net/ethernet/hisilicon/hns/hnae.c
> new file mode 100644
> index 0000000..fd09768
> --- /dev/null
> +++ b/drivers/net/ethernet/hisilicon/hns/hnae.c
 ...
> +static inline void hnae_list_add(spinlock_t *lock, struct list_head *node,
> +				 struct list_head *head)
> +{
> +	unsigned long flags;
> +
> +	spin_lock_irqsave(lock, flags);
> +	list_add_tail_rcu(node, head);
> +	spin_unlock_irqrestore(lock, flags);
> +}

Do not declare functions 'inline' in foo.c files, let the compiler decide
on it's own.

This applies to your entire patch series.


From heiko at sntech.de  Mon Aug 17 12:37:22 2015
From: heiko at sntech.de (Heiko Stuebner)
Date: Mon, 17 Aug 2015 21:37:22 +0200
Subject: [PATCH] clk: rockchip: add pclk_cpu to the list of rk3188
 critical clocks
In-Reply-To: <9DBF9CCE-196E-43FB-BA76-BFB4B5F47A22@mniewoehner.de>
References: <5400BEF8-5245-4F7B-845B-D326A7BC56B5@mniewoehner.de>
 <5275855.eah07vmf4I@phil>
 <9DBF9CCE-196E-43FB-BA76-BFB4B5F47A22@mniewoehner.de>
Message-ID: <10213368.VjAQGt7Kjq@phil>

Hi Michael,


need to pick a bit more on your patch submission :-)

Please take a look for example at
http://lists.infradead.org/pipermail/linux-rockchip/2014-November/001043.html

on how a v2 submission needs to look like.

Specifically:
- In most cases not as a reply to a reply to another mail.
- Mail subject: [PATCH v2] clk: rockchip: add pclk_cpu to the list of rk3188 
critical clocks


Am Montag, 17. August 2015, 20:51:14 schrieb Michael Niewoehner:
> Hi Heiko,
> 
> I merged yours and mine :-)
> 
> 

no prose nor empty lines. If necessary such stuff could sit below the "---" 
which results in it not making it into the actuall commit message.


> pclk_cpu needs to keep running because it is needed for devices like
> the act8865 regulator but with the recent gpio clock handling this is
> not always the case anymore. So add it to the list of critical clocks.
> 
> Signed-off-by: Michael Niewoehner <linux at mniewoehner.de>
> ---

Here any prose-text you like to add.

Also, changelog:
changes in v2:
- adapt commit message
- add Linus Walleij to recipients, as the patch is related to the gpio clock
  change in the rockchip pinctrl driver it should go through his tree as well

> drivers/clk/rockchip/clk-rk3188.c | 1 +
> 1 file changed, 1 insertion(+)
> 
> diff --git a/drivers/clk/rockchip/clk-rk3188.c
> b/drivers/clk/rockchip/clk-rk3188.c index e4f9d47..1c93229 100644
> --- a/drivers/clk/rockchip/clk-rk3188.c
> +++ b/drivers/clk/rockchip/clk-rk3188.c
> @@ -708,6 +708,7 @@ static const char *const rk3188_critical_clocks[]
> __initconst = { "aclk_cpu",
> 	"aclk_peri",
> 	"hclk_peri",
> +	"pclk_cpu",
> };
> 
> static void __init rk3188_common_clk_init(struct device_node *np)


no quotes of other mails, like the stuff below.


Heiko

> 
> > Hi,
> > 
> > Am Montag, 17. August 2015, 19:38:22 schrieb Michael Niewoehner:
> >> gpio clock is getting disabled to save power but pclk_cpu is needed for
> >> act8865 regulator
> > 
> > Please refine the commit message a bit :-) . Something along
> > 
> > pclk_cpu needs to keep running and with the recent gpio clock
> > handling this is not always the case anymore. So add it to the list
> > of critical clocks.
> > 
> > 
> > and also please add "Linus Walleij <linus.walleij at linaro.org>" to the list
> > of recipients. As the gpio clock handling change does go through his
> > tree, the matching critical clock handling should also go through him.
> > 
> > 
> > Heiko
> > 
> >> Signed-off-by: Michael Niewoehner <linux at mniewoehner.de>
> >> ---
> >> drivers/clk/rockchip/clk-rk3188.c | 1 +
> >> 1 file changed, 1 insertion(+)
> >> 
> >> diff --git a/drivers/clk/rockchip/clk-rk3188.c
> >> b/drivers/clk/rockchip/clk-rk3188.c index e4f9d47..1c93229 100644
> >> --- a/drivers/clk/rockchip/clk-rk3188.c
> >> +++ b/drivers/clk/rockchip/clk-rk3188.c
> >> @@ -708,6 +708,7 @@ static const char *const rk3188_critical_clocks[]
> >> __initconst = { "aclk_cpu",
> >> 
> >> 	"aclk_peri",
> >> 	"hclk_peri",
> >> 
> >> +	"pclk_cpu",
> >> };
> >> 
> >> static void __init rk3188_common_clk_init(struct device_node *np)



From linux at mniewoehner.de  Mon Aug 17 12:50:53 2015
From: linux at mniewoehner.de (Michael Niewoehner)
Date: Mon, 17 Aug 2015 21:50:53 +0200
Subject: [PATCH v2] clk: rockchip: add pclk_cpu to the list of rk3188 critical
 clocks
In-Reply-To: <10213368.VjAQGt7Kjq@phil>
References: <5400BEF8-5245-4F7B-845B-D326A7BC56B5@mniewoehner.de>
 <5275855.eah07vmf4I@phil>
 <9DBF9CCE-196E-43FB-BA76-BFB4B5F47A22@mniewoehner.de>
 <10213368.VjAQGt7Kjq@phil>
Message-ID: <F5234F5E-2A91-4B63-B260-3F20A4D16A9D@mniewoehner.de>

pclk_cpu needs to keep running because it is needed for devices like
the act8865 regulator but with the recent gpio clock handling this is
not always the case anymore. So add it to the list of critical clocks.

Signed-off-by: Michael Niewoehner <linux at mniewoehner.de>
---
Changes in v2:
- adapt commit message
- add Linus Walleij to recipients, as the patch is related to the gpio clock
  change in the rockchip pinctrl driver it should go through his tree as well

drivers/clk/rockchip/clk-rk3188.c | 1 +
1 file changed, 1 insertion(+)

diff --git a/drivers/clk/rockchip/clk-rk3188.c b/drivers/clk/rockchip/clk-rk3188.c
index e4f9d47..1c93229 100644
--- a/drivers/clk/rockchip/clk-rk3188.c
+++ b/drivers/clk/rockchip/clk-rk3188.c
@@ -708,6 +708,7 @@ static const char *const rk3188_critical_clocks[] __initconst = {
	"aclk_cpu",
	"aclk_peri",
	"hclk_peri",
+	"pclk_cpu",
};

static void __init rk3188_common_clk_init(struct device_node *np)
-- 
2.5.0


From heiko at sntech.de  Mon Aug 17 12:55:11 2015
From: heiko at sntech.de (Heiko Stuebner)
Date: Mon, 17 Aug 2015 21:55:11 +0200
Subject: [PATCH v2] clk: rockchip: add pclk_cpu to the list of rk3188
 critical clocks
In-Reply-To: <F5234F5E-2A91-4B63-B260-3F20A4D16A9D@mniewoehner.de>
References: <5400BEF8-5245-4F7B-845B-D326A7BC56B5@mniewoehner.de>
 <10213368.VjAQGt7Kjq@phil>
 <F5234F5E-2A91-4B63-B260-3F20A4D16A9D@mniewoehner.de>
Message-ID: <14545587.HIDVkPerl6@phil>

Am Montag, 17. August 2015, 21:50:53 schrieb Michael Niewoehner:
> pclk_cpu needs to keep running because it is needed for devices like
> the act8865 regulator but with the recent gpio clock handling this is
> not always the case anymore. So add it to the list of critical clocks.
> 
> Signed-off-by: Michael Niewoehner <linux at mniewoehner.de>

Reviewed-by: Heiko Stuebner <heiko at sntech.de>

> ---
> Changes in v2:
> - adapt commit message
> - add Linus Walleij to recipients, as the patch is related to the gpio clock
> change in the rockchip pinctrl driver it should go through his tree as well
> 
> drivers/clk/rockchip/clk-rk3188.c | 1 +
> 1 file changed, 1 insertion(+)
> 
> diff --git a/drivers/clk/rockchip/clk-rk3188.c
> b/drivers/clk/rockchip/clk-rk3188.c index e4f9d47..1c93229 100644
> --- a/drivers/clk/rockchip/clk-rk3188.c
> +++ b/drivers/clk/rockchip/clk-rk3188.c
> @@ -708,6 +708,7 @@ static const char *const rk3188_critical_clocks[]
> __initconst = { "aclk_cpu",
> 	"aclk_peri",
> 	"hclk_peri",
> +	"pclk_cpu",
> };
> 
> static void __init rk3188_common_clk_init(struct device_node *np)



From ezequiel at vanguardiasur.com.ar  Mon Aug 17 13:18:30 2015
From: ezequiel at vanguardiasur.com.ar (Ezequiel Garcia)
Date: Mon, 17 Aug 2015 17:18:30 -0300
Subject: [PATCH v2 1/2] i2c: add i2c-lpc2k driver
In-Reply-To: <1439748617-7683-2-git-send-email-manabian@gmail.com>
References: <1439748617-7683-1-git-send-email-manabian@gmail.com>
 <1439748617-7683-2-git-send-email-manabian@gmail.com>
Message-ID: <20150817201830.GA11033@laptop>

On 16 Aug 08:10 PM, Joachim Eastwood wrote:
[..]
> +
> +static int i2c_lpc2k_clear_arb(struct lpc2k_i2c *i2c)
> +{
> +	unsigned long timeout = jiffies + msecs_to_jiffies(1000);
> +
> +	/*
> +	 * If the transfer needs to abort for some reason, we'll try to
> +	 * force a stop condition to clear any pending bus conditions
> +	 */
> +	writel(LPC24XX_STO, i2c->base + LPC24XX_I2CONSET);
> +
> +	/* Wait for status change */
> +	while (readl(i2c->base + LPC24XX_I2STAT) != M_I2C_IDLE) {
> +		if (time_after(jiffies, timeout)) {
> +			/* Bus was not idle, try to reset adapter */
> +			i2c_lpc2k_reset(i2c);
> +			return -EBUSY;
> +		}
> +
> +		cpu_relax();
> +	}

I believe you can use readl_{relaxed}_poll_timeout_{atomic} here.

Ccing Ariel, maybe he can help with a test.

-- 
Ezequiel Garcia, VanguardiaSur
www.vanguardiasur.com.ar


From manabian at gmail.com  Mon Aug 17 13:37:19 2015
From: manabian at gmail.com (Joachim Eastwood)
Date: Mon, 17 Aug 2015 22:37:19 +0200
Subject: [PATCH v2 1/2] i2c: add i2c-lpc2k driver
In-Reply-To: <20150817201830.GA11033@laptop>
References: <1439748617-7683-1-git-send-email-manabian@gmail.com>
 <1439748617-7683-2-git-send-email-manabian@gmail.com>
 <20150817201830.GA11033@laptop>
Message-ID: <CAGhQ9VzO=mQyCB2B-2Ys32amRNcPVicZWKVygssZmN+NURXKsQ@mail.gmail.com>

On 17 August 2015 at 22:18, Ezequiel Garcia
<ezequiel at vanguardiasur.com.ar> wrote:
> On 16 Aug 08:10 PM, Joachim Eastwood wrote:
> [..]
>> +
>> +static int 2(struct lpc2k_i2c *i2c)
>> +{
>> +     unsigned long timeout = jiffies + msecs_to_jiffies(1000);
>> +
>> +     /*1
>> +      * If the transfer needs to abort for some reason, we'll try to
>> +      * force a stop condition to clear any pending bus conditions
>> +      */
>> +     writel(LPC24XX_STO, i2c->base + LPC24XX_I2CONSET);
>> +
>> +     /* Wait for status change */
>> +     while (readl(i2c->base + LPC24XX_I2STAT) != M_I2C_IDLE) {
>> +             if (time_after(jiffies, timeout)) {
>> +                     /* Bus was not idle, try to reset adapter */
>> +                     i2c_lpc2k_reset(i2c);
>> +                     return -EBUSY;
>> +             }
>> +
>> +             cpu_relax();
>> +     }
>
> I believe you can use readl_{relaxed}_poll_timeout_{atomic} here.

I did consider it, but since I don't have a good to way test the code
path I left it as it was.
Also since readl_{relaxed}_poll_timeout_{atomic} takes parameters in
us it seemed unsuitable for a 1s total sleep, but I may be wrong.

> Ccing Ariel, maybe he can help with a test.

That would be great.

regards,
Joachim Eastwood


From mathieu at codeaurora.org  Mon Aug 17 14:24:52 2015
From: mathieu at codeaurora.org (Mathieu Olivari)
Date: Mon, 17 Aug 2015 14:24:52 -0700
Subject: [PATCH 3/3] mtd: add SMEM parser for QCOM platforms
In-Reply-To: <20150815054817.GM13472@usrtlx11787.corpusers.net>
References: <1439599573-3932-1-git-send-email-mathieu@codeaurora.org>
 <1439599573-3932-4-git-send-email-mathieu@codeaurora.org>
 <20150815054817.GM13472@usrtlx11787.corpusers.net>
Message-ID: <20150817212452.GA3816@codeaurora.org>

On Fri, Aug 14, 2015 at 10:48:17PM -0700, Bjorn Andersson wrote:
> On Fri 14 Aug 17:46 PDT 2015, Mathieu Olivari wrote:
> 
> > On QCOM platforms using MTD devices storage (such as IPQ806x), SMEM is
> > used to store partition layout. This new parser can now be used to read
> > SMEM and use it to register an MTD layout according to its content.
> > 
> 
> Nice to see another user of the smem code :)
> 
> > diff --git a/drivers/mtd/qcom_smem_part.c b/drivers/mtd/qcom_smem_part.c
> [..]
> > +
> > +/* Processor/host identifier for the application processor */
> > +#define SMEM_HOST_APPS			0
> 
> This makes me wonder if there will ever be an apps partition. I would
> have picked QCOM_SMEM_HOST_ANY, but I don't know what future platforms
> might hold for us.
> 
> 
> And as a side note, I think I will propose that we rename that define
> QCOM_SMEM_GLOBAL.
OK; I'll rename it in QCOM_SMEM_GLOBAL then to be in sync.
> 
> > +
> > +/* SMEM items index */
> > +#define SMEM_AARM_PARTITION_TABLE	9
> > +#define SMEM_BOOT_FLASH_TYPE		421
> > +#define SMEM_BOOT_FLASH_BLOCK_SIZE	424
> > +
> > +/* SMEM Flash types */
> > +#define SMEM_FLASH_NAND			2
> > +#define SMEM_FLASH_SPI			6
> > +
> > +#define SMEM_PART_NAME_SZ		16
> > +#define SMEM_PARTS_MAX			32
> > +
> > +struct smem_partition {
> > +	char name[SMEM_PART_NAME_SZ];
> > +	__le32 start;
> > +	__le32 size;
> > +	__le32 attr;
> > +};
> > +
> > +struct smem_partition_table {
> > +	u8 magic[8];
> > +	__le32 version;
> > +	__le32 len;
> > +	struct smem_partition parts[SMEM_PARTS_MAX];
> > +};
> > +
> > +/* SMEM Magic values in partition table */
> > +static const u8 SMEM_PTABLE_MAGIC[] = {
> > +	0xaa, 0x73, 0xee, 0x55,
> > +	0xdb, 0xbd, 0x5e, 0xe3,
> > +};
> > +
> > +static int qcom_smem_get_flash_blksz(u64 **smem_blksz)
> 
> Instead of passing pointers around I think you should just make this
> function return < 0 for errors and >= 0 for the requested data. You can
> probably still have it as an int, as the current values are well below
> the size of the int.
Good point. Thanks. I'll report it.
> 
> > +{
> > +	int ret;
> > +	size_t size;
> > +
> > +	ret = qcom_smem_get(SMEM_HOST_APPS, SMEM_BOOT_FLASH_BLOCK_SIZE,
> > +			    (void **) smem_blksz, &size);
> > +
> > +	if (ret < 0) {
> > +		pr_err("Unable to read flash blksz from SMEM\n");
> > +		return -ENOENT;
> > +	}
> > +
> > +	if (size != sizeof(**smem_blksz)) {
> > +		pr_err("Invalid flash blksz size in SMEM\n");
> > +		return -EINVAL;
> > +	}
> > +
> > +	return 0;
> > +}
> > +
> > +static int qcom_smem_get_flash_type(u64 **smem_flash_type)
> 
> Same as above.
OK.
> 
> > +{
> > +	int ret;
> > +	size_t size;
> > +
> > +	ret = qcom_smem_get(SMEM_HOST_APPS, SMEM_BOOT_FLASH_TYPE,
> > +			    (void **) smem_flash_type, &size);
> > +
> > +	if (ret < 0) {
> > +		pr_err("Unable to read flash type from SMEM\n");
> > +		return -ENOENT;
> > +	}
> > +
> > +	if (size != sizeof(**smem_flash_type)) {
> > +		pr_err("Invalid flash type size in SMEM\n");
> > +		return -EINVAL;
> > +	}
> > +
> > +	return 0;
> > +}
> > +
> > +static int qcom_smem_get_flash_partitions(struct smem_partition_table **pparts)
> > +{
> > +	int ret;
> > +	size_t size;
> > +
> > +	ret = qcom_smem_get(SMEM_HOST_APPS, SMEM_AARM_PARTITION_TABLE,
> > +			    (void **) pparts, &size);
> > +
> 
> If you don't care about the size just pass NULL as the last argument.
OK.
> 
> > +	if (ret < 0) {
> > +		pr_err("Unable to read partition table from SMEM\n");
> > +		return -ENOENT;
> > +	}
> 
> I think it would be cleaner if you had this function check the magic and
> version and then return the partition pointer. That is:
> 
> static smem_partition *qcom_smem_get_flash_partitions(size_t *count)
> 
> 
> And make *count = le32_to_cpu(table->len); so you don't have to care
> about that below.
> 
> (And use NULL or ERR_PTR for the error paths)
Same; good idea. I'll make the mod.
> 
> > +
> > +	return 0;
> > +}
> > +
> > +static int of_dev_node_match(struct device *dev, void *data)
> > +{
> > +	return dev->of_node == data;
> > +}
> > +
> > +static bool is_spi_device(struct device_node *np)
> > +{
> > +	struct device *dev;
> > +
> > +	dev = bus_find_device(&spi_bus_type, NULL, np, of_dev_node_match);
> > +	if (!dev)
> > +		return false;
> > +
> > +	put_device(dev);
> > +	return true;
> > +}
> > +
> > +static int parse_qcom_smem_partitions(struct mtd_info *master,
> > +				      struct mtd_partition **pparts,
> > +				      struct mtd_part_parser_data *data)
> > +{
> > +	struct smem_partition_table *smem_parts;
> > +	u64 *smem_flash_type, *smem_blksz;
> > +	struct mtd_partition *mtd_parts;
> > +	struct device_node *of_node = data->of_node;
> > +	int i, ret;
> > +
> > +	/*
> > +	 * SMEM will only store the partition table of the boot device.
> > +	 * If this is not the boot device, do not return any partition.
> > +	 */
> 
> I guess this is the result of below checks, but it's not describing
> what's actually done here. I think it should say "only parse
> partitions on the specified memory type" or something like that.
OK.
> 
> > +	ret = qcom_smem_get_flash_type(&smem_flash_type);
> > +	if (ret < 0)
> > +		return ret;
> > +
> > +	if ((*smem_flash_type == SMEM_FLASH_NAND && !mtd_type_is_nand(master))
> > +	    || (*smem_flash_type == SMEM_FLASH_SPI && !is_spi_device(of_node)))
> > +		return 0;
> > +
> > +	/*
> > +	 * Just for sanity purpose, make sure the block size in SMEM matches the
> > +	 * block size of the MTD device
> > +	 */
> 
> Well, this is not only for sanity purpose, as you multiply all sizes
> with this number below...
I'll update the comment.
> 
> > +	ret = qcom_smem_get_flash_blksz(&smem_blksz);
> > +	if (ret < 0)
> > +		return ret;
> > +
> > +	if (*smem_blksz != master->erasesize) {
> > +		pr_err("SMEM block size differs from MTD block size\n");
> > +		return -EINVAL;
> > +	}
> > +
> > +	/* Get partition pointer from SMEM */
> > +	ret = qcom_smem_get_flash_partitions(&smem_parts);
> > +	if (ret < 0)
> > +		return ret;
> > +
> > +	if (memcmp(SMEM_PTABLE_MAGIC, smem_parts->magic,
> > +		   sizeof(SMEM_PTABLE_MAGIC))) {
> > +		pr_err("SMEM partition magic invalid\n");
> > +		return -EINVAL;
> > +	}
> > +
> > +	/* Allocate and populate the mtd structures */
> > +	mtd_parts = kcalloc(le32_to_cpu(smem_parts->len), sizeof(*mtd_parts),
> > +			    GFP_KERNEL);
> > +	if (!mtd_parts)
> > +		return -ENOMEM;
> > +
> > +	for (i = 0; i < smem_parts->len; i++) {
> 
> This might have the wrong endian...
Right. I'll do a le32_to_cpu()
> 
> > +		struct smem_partition *s_part = &smem_parts->parts[i];
> > +		struct mtd_partition *m_part = &mtd_parts[i];
> 
> I think Stephens suggestion was that you assign *pparts before looping
> and then you simply do:
> 
> *pparts = mtd_parts;
> 
> while (len--) {
> 	..
> 
> 	s_part++;
> 	mtd_parts++;
> }
> 
> > +
> > +		m_part->name = s_part->name;
> 
> I tried to follow the mtd code, and I believe that this pointer might
> be freed in free_partition(). If so you must kstrdup it here.
OK.
> 
> > +		m_part->size = le32_to_cpu(s_part->size) * (*smem_blksz);
> > +		m_part->offset = le32_to_cpu(s_part->start) * (*smem_blksz);
> > +
> > +		/*
> > +		 * The last SMEM partition may have its size marked as
> > +		 * something like 0xffffffff, which means "until the end of the
> > +		 * flash device". In this case, truncate it.
> > +		 */
> > +		if (m_part->offset + m_part->size > master->size)
> > +			m_part->size = master->size - m_part->offset;
> > +	}
> > +
> > +	*pparts = mtd_parts;
> > +
> > +	return smem_parts->len;
> 
> Again, this might be in the wrong endian.
Yes.
> 
> > +}
> > +
> > +static struct mtd_part_parser qcom_smem_parser = {
> > +	.owner = THIS_MODULE,
> > +	.parse_fn = parse_qcom_smem_partitions,
> > +	.name = "qcom-smem",
> > +};
> > +
> > +static int __init qcom_smem_parser_init(void)
> > +{
> > +	register_mtd_parser(&qcom_smem_parser);
> > +	return 0;
> > +}
> > +
> > +static void __exit qcom_smem_parser_exit(void)
> > +{
> > +	deregister_mtd_parser(&qcom_smem_parser);
> > +}
> > +
> > +module_init(qcom_smem_parser_init);
> > +module_exit(qcom_smem_parser_exit);
> 
> Mostly unrelated to this patch; This makes me appreciate the
> module_platform_driver() macro, would be nice to see a patch that
> introduces something similar for partition parsers.
> 
> > +
> > +MODULE_LICENSE("GPL");
> 
> Are you sure you don't mean "GPL v2" here?
I'll update it.
> 
> > +MODULE_AUTHOR("Mathieu Olivari <mathieu at codeaurora.org>");
> > +MODULE_DESCRIPTION("Parsing code for SMEM based partition tables");
> 
> Regards,
> Bjorn


From isubramanian at apm.com  Mon Aug 17 14:33:03 2015
From: isubramanian at apm.com (Iyappan Subramanian)
Date: Mon, 17 Aug 2015 14:33:03 -0700
Subject: [PATCH v1 0/2] drivers: net: xgene: Add TSO support
Message-ID: <1439847185-22046-1-git-send-email-isubramanian@apm.com>

Adding TSO support

iperf Tx data rate without TSO: 3.42 Gbps
                      with TSO: 9.41 Gbps

v1
* Initial version

Signed-off-by: Iyappan Subramanian <isubramanian at apm.com>
---

Iyappan Subramanian (2):
  drivers: net: xgene: Preparatory patch for TSO support
  drivers: net: xgene: Adding support for TSO

 drivers/net/ethernet/apm/xgene/xgene_enet_hw.h    |  16 +-
 drivers/net/ethernet/apm/xgene/xgene_enet_main.c  | 260 ++++++++++++++++++++--
 drivers/net/ethernet/apm/xgene/xgene_enet_main.h  |  12 +
 drivers/net/ethernet/apm/xgene/xgene_enet_xgmac.c |   8 +-
 drivers/net/ethernet/apm/xgene/xgene_enet_xgmac.h |   2 +
 5 files changed, 272 insertions(+), 26 deletions(-)

-- 
1.9.1



From isubramanian at apm.com  Mon Aug 17 14:33:04 2015
From: isubramanian at apm.com (Iyappan Subramanian)
Date: Mon, 17 Aug 2015 14:33:04 -0700
Subject: [PATCH v1 1/2] drivers: net: xgene: Preparatory patch for TSO support
In-Reply-To: <1439847185-22046-1-git-send-email-isubramanian@apm.com>
References: <1439847185-22046-1-git-send-email-isubramanian@apm.com>
Message-ID: <1439847185-22046-2-git-send-email-isubramanian@apm.com>

- Rearranged descriptor writes
- Moved increment command write to xgene_enet_setup_tx_desc

Signed-off-by: Iyappan Subramanian <isubramanian at apm.com>
---
 drivers/net/ethernet/apm/xgene/xgene_enet_main.c | 29 ++++++++++++++++++------
 drivers/net/ethernet/apm/xgene/xgene_enet_main.h |  1 +
 2 files changed, 23 insertions(+), 7 deletions(-)

diff --git a/drivers/net/ethernet/apm/xgene/xgene_enet_main.c b/drivers/net/ethernet/apm/xgene/xgene_enet_main.c
index 299eb43..7a0eb08 100644
--- a/drivers/net/ethernet/apm/xgene/xgene_enet_main.c
+++ b/drivers/net/ethernet/apm/xgene/xgene_enet_main.c
@@ -219,6 +219,11 @@ out:
 	return hopinfo;
 }
 
+static u16 xgene_enet_encode_len(u16 len)
+{
+	return (len == BUFLEN_16K) ? 0 : len;
+}
+
 static int xgene_enet_setup_tx_desc(struct xgene_enet_desc_ring *tx_ring,
 				    struct sk_buff *skb)
 {
@@ -227,27 +232,36 @@ static int xgene_enet_setup_tx_desc(struct xgene_enet_desc_ring *tx_ring,
 	dma_addr_t dma_addr;
 	u16 tail = tx_ring->tail;
 	u64 hopinfo;
+	u32 len, hw_len;
+	u8 count = 1;
 
 	raw_desc = &tx_ring->raw_desc[tail];
 	memset(raw_desc, 0, sizeof(struct xgene_enet_raw_desc));
 
-	dma_addr = dma_map_single(dev, skb->data, skb->len, DMA_TO_DEVICE);
+	len = skb_headlen(skb);
+	hw_len = xgene_enet_encode_len(len);
+
+	dma_addr = dma_map_single(dev, skb->data, len, DMA_TO_DEVICE);
 	if (dma_mapping_error(dev, dma_addr)) {
 		netdev_err(tx_ring->ndev, "DMA mapping error\n");
 		return -EINVAL;
 	}
 
 	/* Hardware expects descriptor in little endian format */
-	raw_desc->m0 = cpu_to_le64(tail);
 	raw_desc->m1 = cpu_to_le64(SET_VAL(DATAADDR, dma_addr) |
-				   SET_VAL(BUFDATALEN, skb->len) |
+				   SET_VAL(BUFDATALEN, hw_len) |
 				   SET_BIT(COHERENT));
+
+	raw_desc->m0 = cpu_to_le64(SET_VAL(USERINFO, tail));
 	hopinfo = xgene_enet_work_msg(skb);
 	raw_desc->m3 = cpu_to_le64(SET_VAL(HENQNUM, tx_ring->dst_ring_num) |
 				   hopinfo);
 	tx_ring->cp_ring->cp_skb[tail] = skb;
 
-	return 0;
+	tail = (tail + 1) & (tx_ring->slots - 1);
+	tx_ring->tail = tail;
+
+	return count;
 }
 
 static netdev_tx_t xgene_enet_start_xmit(struct sk_buff *skb,
@@ -257,6 +271,7 @@ static netdev_tx_t xgene_enet_start_xmit(struct sk_buff *skb,
 	struct xgene_enet_desc_ring *tx_ring = pdata->tx_ring;
 	struct xgene_enet_desc_ring *cp_ring = tx_ring->cp_ring;
 	u32 tx_level, cq_level;
+	int count;
 
 	tx_level = pdata->ring_ops->len(tx_ring);
 	cq_level = pdata->ring_ops->len(cp_ring);
@@ -266,14 +281,14 @@ static netdev_tx_t xgene_enet_start_xmit(struct sk_buff *skb,
 		return NETDEV_TX_BUSY;
 	}
 
-	if (xgene_enet_setup_tx_desc(tx_ring, skb)) {
+	count = xgene_enet_setup_tx_desc(tx_ring, skb);
+	if (count <= 0) {
 		dev_kfree_skb_any(skb);
 		return NETDEV_TX_OK;
 	}
 
-	pdata->ring_ops->wr_cmd(tx_ring, 1);
+	pdata->ring_ops->wr_cmd(tx_ring, count);
 	skb_tx_timestamp(skb);
-	tx_ring->tail = (tx_ring->tail + 1) & (tx_ring->slots - 1);
 
 	pdata->stats.tx_packets++;
 	pdata->stats.tx_bytes += skb->len;
diff --git a/drivers/net/ethernet/apm/xgene/xgene_enet_main.h b/drivers/net/ethernet/apm/xgene/xgene_enet_main.h
index 1c85fc8..2ac547e 100644
--- a/drivers/net/ethernet/apm/xgene/xgene_enet_main.h
+++ b/drivers/net/ethernet/apm/xgene/xgene_enet_main.h
@@ -40,6 +40,7 @@
 #define XGENE_DRV_VERSION	"v1.0"
 #define XGENE_ENET_MAX_MTU	1536
 #define SKB_BUFFER_SIZE		(XGENE_ENET_MAX_MTU - NET_IP_ALIGN)
+#define BUFLEN_16K	(16 * 1024)
 #define NUM_PKT_BUF	64
 #define NUM_BUFPOOL	32
 
-- 
1.9.1



From isubramanian at apm.com  Mon Aug 17 14:33:05 2015
From: isubramanian at apm.com (Iyappan Subramanian)
Date: Mon, 17 Aug 2015 14:33:05 -0700
Subject: [PATCH v1 2/2] drivers: net: xgene: Adding support for TSO
In-Reply-To: <1439847185-22046-1-git-send-email-isubramanian@apm.com>
References: <1439847185-22046-1-git-send-email-isubramanian@apm.com>
Message-ID: <1439847185-22046-3-git-send-email-isubramanian@apm.com>

Signed-off-by: Iyappan Subramanian <isubramanian at apm.com>
---
 drivers/net/ethernet/apm/xgene/xgene_enet_hw.h    |  16 +-
 drivers/net/ethernet/apm/xgene/xgene_enet_main.c  | 239 ++++++++++++++++++++--
 drivers/net/ethernet/apm/xgene/xgene_enet_main.h  |  11 +
 drivers/net/ethernet/apm/xgene/xgene_enet_xgmac.c |   8 +-
 drivers/net/ethernet/apm/xgene/xgene_enet_xgmac.h |   2 +
 5 files changed, 253 insertions(+), 23 deletions(-)

diff --git a/drivers/net/ethernet/apm/xgene/xgene_enet_hw.h b/drivers/net/ethernet/apm/xgene/xgene_enet_hw.h
index 541bed0..ff05bbc 100644
--- a/drivers/net/ethernet/apm/xgene/xgene_enet_hw.h
+++ b/drivers/net/ethernet/apm/xgene/xgene_enet_hw.h
@@ -193,12 +193,16 @@ enum xgene_enet_rm {
 #define USERINFO_LEN			32
 #define FPQNUM_POS			32
 #define FPQNUM_LEN			12
+#define NV_POS				50
+#define NV_LEN				1
+#define LL_POS				51
+#define LL_LEN				1
 #define LERR_POS			60
 #define LERR_LEN			3
 #define STASH_POS			52
 #define STASH_LEN			2
 #define BUFDATALEN_POS			48
-#define BUFDATALEN_LEN			12
+#define BUFDATALEN_LEN			15
 #define DATAADDR_POS			0
 #define DATAADDR_LEN			42
 #define COHERENT_POS			63
@@ -215,9 +219,19 @@ enum xgene_enet_rm {
 #define IPHDR_LEN			6
 #define EC_POS				22	/* Enable checksum */
 #define EC_LEN				1
+#define ET_POS				23	/* Enable TSO */
 #define IS_POS				24	/* IP protocol select */
 #define IS_LEN				1
 #define TYPE_ETH_WORK_MESSAGE_POS	44
+#define LL_BYTES_MSB_POS		56
+#define LL_BYTES_MSB_LEN		8
+#define LL_BYTES_LSB_POS		48
+#define LL_BYTES_LSB_LEN		12
+#define LL_LEN_POS			48
+#define LL_LEN_LEN			8
+#define DATALEN_MASK			GENMASK(11, 0)
+
+#define LAST_BUFFER			(0x7800ULL << BUFDATALEN_POS)
 
 struct xgene_enet_raw_desc {
 	__le64 m0;
diff --git a/drivers/net/ethernet/apm/xgene/xgene_enet_main.c b/drivers/net/ethernet/apm/xgene/xgene_enet_main.c
index 7a0eb08..0b29e0c 100644
--- a/drivers/net/ethernet/apm/xgene/xgene_enet_main.c
+++ b/drivers/net/ethernet/apm/xgene/xgene_enet_main.c
@@ -147,18 +147,27 @@ static int xgene_enet_tx_completion(struct xgene_enet_desc_ring *cp_ring,
 {
 	struct sk_buff *skb;
 	struct device *dev;
+	skb_frag_t *frag;
+	dma_addr_t *frag_dma_addr;
 	u16 skb_index;
 	u8 status;
-	int ret = 0;
+	int i, ret = 0;
 
 	skb_index = GET_VAL(USERINFO, le64_to_cpu(raw_desc->m0));
 	skb = cp_ring->cp_skb[skb_index];
+	frag_dma_addr = &cp_ring->frag_dma_addr[skb_index * MAX_SKB_FRAGS];
 
 	dev = ndev_to_dev(cp_ring->ndev);
 	dma_unmap_single(dev, GET_VAL(DATAADDR, le64_to_cpu(raw_desc->m1)),
-			 GET_VAL(BUFDATALEN, le64_to_cpu(raw_desc->m1)),
+			 skb_headlen(skb),
 			 DMA_TO_DEVICE);
 
+	for (i = 0; i < skb_shinfo(skb)->nr_frags; i++) {
+		frag = &skb_shinfo(skb)->frags[i];
+		dma_unmap_page(dev, frag_dma_addr[i], skb_frag_size(frag),
+			       DMA_TO_DEVICE);
+	}
+
 	/* Checking for error */
 	status = GET_VAL(LERR, le64_to_cpu(raw_desc->m0));
 	if (unlikely(status > 2)) {
@@ -179,12 +188,15 @@ static int xgene_enet_tx_completion(struct xgene_enet_desc_ring *cp_ring,
 
 static u64 xgene_enet_work_msg(struct sk_buff *skb)
 {
+	struct net_device *ndev = skb->dev;
+	struct xgene_enet_pdata *pdata = netdev_priv(ndev);
 	struct iphdr *iph;
-	u8 l3hlen, l4hlen = 0;
-	u8 csum_enable = 0;
-	u8 proto = 0;
-	u8 ethhdr;
-	u64 hopinfo;
+	u8 l3hlen = 0, l4hlen = 0;
+	u8 ethhdr, proto = 0, csum_enable = 0;
+	u64 hopinfo = 0;
+	u32 hdr_len, mss = 0;
+
+	ethhdr = xgene_enet_hdr_len(skb->data);
 
 	if (unlikely(skb->protocol != htons(ETH_P_IP)) &&
 	    unlikely(skb->protocol != htons(ETH_P_8021Q)))
@@ -201,14 +213,34 @@ static u64 xgene_enet_work_msg(struct sk_buff *skb)
 		l4hlen = tcp_hdrlen(skb) >> 2;
 		csum_enable = 1;
 		proto = TSO_IPPROTO_TCP;
+		if (ndev->features & NETIF_F_TSO) {
+			hdr_len = ethhdr + ip_hdrlen(skb) + tcp_hdrlen(skb);
+			mss = skb_shinfo(skb)->gso_size;
+
+			/* HW requires all header resides in the first buffer */
+			if (skb_is_nonlinear(skb) &&
+			    (skb_headlen(skb) < hdr_len)) {
+				netdev_warn(ndev, "Headers are required to reside in header buffer\n");
+				dev_kfree_skb(skb);
+				return 0;
+			}
+
+			if (!mss || ((skb->len - hdr_len) <= mss))
+				goto out;
+
+			if (mss != pdata->mss) {
+				pdata->mss = mss;
+				pdata->mac_ops->set_mss(pdata);
+			}
+			hopinfo |= SET_BIT(ET);
+		}
 	} else if (iph->protocol == IPPROTO_UDP) {
 		l4hlen = UDP_HDR_SIZE;
 		csum_enable = 1;
 	}
 out:
 	l3hlen = ip_hdrlen(skb) >> 2;
-	ethhdr = xgene_enet_hdr_len(skb->data);
-	hopinfo = SET_VAL(TCPHDR, l4hlen) |
+	hopinfo |= SET_VAL(TCPHDR, l4hlen) |
 		  SET_VAL(IPHDR, l3hlen) |
 		  SET_VAL(ETHHDR, ethhdr) |
 		  SET_VAL(EC, csum_enable) |
@@ -224,18 +256,46 @@ static u16 xgene_enet_encode_len(u16 len)
 	return (len == BUFLEN_16K) ? 0 : len;
 }
 
+static void xgene_set_addr_len(__le64 *desc, u32 idx, dma_addr_t addr, u32 len)
+{
+	desc[idx ^ 1] = cpu_to_le64(SET_VAL(DATAADDR, addr) |
+				    SET_VAL(BUFDATALEN, len));
+}
+
+static __le64 *xgene_enet_get_exp_bufs(struct xgene_enet_desc_ring *ring)
+{
+	__le64 *exp_bufs;
+
+	exp_bufs = &ring->exp_bufs[ring->exp_buf_tail * MAX_EXP_BUFFS];
+	memset(exp_bufs, 0, sizeof(__le64) * MAX_EXP_BUFFS);
+	ring->exp_buf_tail = (ring->exp_buf_tail + 1) & ((ring->slots / 2) - 1);
+
+	return exp_bufs;
+}
+
+static dma_addr_t *xgene_get_frag_dma_array(struct xgene_enet_desc_ring *ring)
+{
+	return &ring->cp_ring->frag_dma_addr[ring->tail * MAX_SKB_FRAGS];
+}
+
 static int xgene_enet_setup_tx_desc(struct xgene_enet_desc_ring *tx_ring,
 				    struct sk_buff *skb)
 {
 	struct device *dev = ndev_to_dev(tx_ring->ndev);
 	struct xgene_enet_raw_desc *raw_desc;
-	dma_addr_t dma_addr;
+	__le64 *exp_desc = NULL, *exp_bufs = NULL;
+	dma_addr_t dma_addr, pbuf_addr, *frag_dma_addr;
+	skb_frag_t *frag;
 	u16 tail = tx_ring->tail;
 	u64 hopinfo;
 	u32 len, hw_len;
-	u8 count = 1;
+	u8 ll = 0, nv = 0, idx = 0;
+	bool split = false;
+	u32 size, offset, ell_bytes = 0;
+	u32 i, fidx, nr_frags, count = 1;
 
 	raw_desc = &tx_ring->raw_desc[tail];
+	tail = (tail + 1) & (tx_ring->slots - 1);
 	memset(raw_desc, 0, sizeof(struct xgene_enet_raw_desc));
 
 	len = skb_headlen(skb);
@@ -252,13 +312,105 @@ static int xgene_enet_setup_tx_desc(struct xgene_enet_desc_ring *tx_ring,
 				   SET_VAL(BUFDATALEN, hw_len) |
 				   SET_BIT(COHERENT));
 
-	raw_desc->m0 = cpu_to_le64(SET_VAL(USERINFO, tail));
+	if (!skb_is_nonlinear(skb))
+		goto out;
+
+	/* scatter gather */
+	nv = 1;
+	exp_desc = (void *)&tx_ring->raw_desc[tail];
+	tail = (tail + 1) & (tx_ring->slots - 1);
+	memset(exp_desc, 0, sizeof(struct xgene_enet_raw_desc));
+
+	nr_frags = skb_shinfo(skb)->nr_frags;
+	for (i = nr_frags; i < 4 ; i++)
+		exp_desc[i ^ 1] = cpu_to_le64(LAST_BUFFER);
+
+	frag_dma_addr = xgene_get_frag_dma_array(tx_ring);
+
+	for (i = 0, fidx = 0; split || (fidx < nr_frags); i++) {
+		if (!split) {
+			frag = &skb_shinfo(skb)->frags[fidx];
+			size = skb_frag_size(frag);
+			offset = 0;
+
+			pbuf_addr = skb_frag_dma_map(dev, frag, 0, size,
+						     DMA_TO_DEVICE);
+			if (dma_mapping_error(dev, pbuf_addr))
+				return -EINVAL;
+
+			frag_dma_addr[fidx] = pbuf_addr;
+			fidx++;
+
+			if (size > BUFLEN_16K)
+				split = true;
+		}
+
+		if (size > BUFLEN_16K) {
+			len = BUFLEN_16K;
+			size -= BUFLEN_16K;
+		} else {
+			len = size;
+			split = false;
+		}
+
+		dma_addr = pbuf_addr + offset;
+		hw_len = xgene_enet_encode_len(len);
+
+		switch (i) {
+		case 0:
+		case 1:
+		case 2:
+			xgene_set_addr_len(exp_desc, i, dma_addr, hw_len);
+			break;
+		case 3:
+			if (split || (fidx != nr_frags)) {
+				exp_bufs = xgene_enet_get_exp_bufs(tx_ring);
+				xgene_set_addr_len(exp_bufs, idx, dma_addr,
+						   hw_len);
+				idx++;
+				ell_bytes += len;
+			} else {
+				xgene_set_addr_len(exp_desc, i, dma_addr,
+						   hw_len);
+			}
+			break;
+		default:
+			xgene_set_addr_len(exp_bufs, idx, dma_addr, hw_len);
+			idx++;
+			ell_bytes += len;
+			break;
+		}
+
+		if (split)
+			offset += BUFLEN_16K;
+	}
+	count++;
+
+	if (idx) {
+		ll = 1;
+		dma_addr = dma_map_single(dev, exp_bufs,
+					  sizeof(u64) * MAX_EXP_BUFFS,
+					  DMA_TO_DEVICE);
+		if (dma_mapping_error(dev, dma_addr)) {
+			dev_kfree_skb_any(skb);
+			return -EINVAL;
+		}
+		i = ell_bytes >> LL_BYTES_LSB_LEN;
+		exp_desc[2] = cpu_to_le64(SET_VAL(DATAADDR, dma_addr) |
+					  SET_VAL(LL_BYTES_MSB, i) |
+					  SET_VAL(LL_LEN, idx));
+		raw_desc->m2 = cpu_to_le64(SET_VAL(LL_BYTES_LSB, ell_bytes));
+	}
+
+out:
+	raw_desc->m0 = cpu_to_le64(SET_VAL(LL, ll) | SET_VAL(NV, nv) |
+				   SET_VAL(USERINFO, tx_ring->tail));
 	hopinfo = xgene_enet_work_msg(skb);
+	if (!hopinfo)
+		return -EINVAL;
 	raw_desc->m3 = cpu_to_le64(SET_VAL(HENQNUM, tx_ring->dst_ring_num) |
 				   hopinfo);
-	tx_ring->cp_ring->cp_skb[tail] = skb;
-
-	tail = (tail + 1) & (tx_ring->slots - 1);
+	tx_ring->cp_ring->cp_skb[tx_ring->tail] = skb;
 	tx_ring->tail = tail;
 
 	return count;
@@ -281,6 +433,9 @@ static netdev_tx_t xgene_enet_start_xmit(struct sk_buff *skb,
 		return NETDEV_TX_BUSY;
 	}
 
+	if (skb_padto(skb, XGENE_MIN_ENET_FRAME_SIZE))
+		return NETDEV_TX_OK;
+
 	count = xgene_enet_setup_tx_desc(tx_ring, skb);
 	if (count <= 0) {
 		dev_kfree_skb_any(skb);
@@ -341,7 +496,7 @@ static int xgene_enet_rx_frame(struct xgene_enet_desc_ring *rx_ring,
 
 	/* strip off CRC as HW isn't doing this */
 	datalen = GET_VAL(BUFDATALEN, le64_to_cpu(raw_desc->m1));
-	datalen -= 4;
+	datalen = (datalen & DATALEN_MASK) - 4;
 	prefetch(skb->data - NET_IP_ALIGN);
 	skb_put(skb, datalen);
 
@@ -373,26 +528,41 @@ static int xgene_enet_process_ring(struct xgene_enet_desc_ring *ring,
 				   int budget)
 {
 	struct xgene_enet_pdata *pdata = netdev_priv(ring->ndev);
-	struct xgene_enet_raw_desc *raw_desc;
+	struct xgene_enet_raw_desc *raw_desc, *exp_desc;
 	u16 head = ring->head;
 	u16 slots = ring->slots - 1;
-	int ret, count = 0;
+	int ret, count = 0, processed = 0;
 
 	do {
 		raw_desc = &ring->raw_desc[head];
+		exp_desc = NULL;
 		if (unlikely(xgene_enet_is_desc_slot_empty(raw_desc)))
 			break;
 
 		/* read fpqnum field after dataaddr field */
 		dma_rmb();
+		if (GET_BIT(NV, le64_to_cpu(raw_desc->m0))) {
+			head = (head + 1) & slots;
+			exp_desc = &ring->raw_desc[head];
+
+			if (unlikely(xgene_enet_is_desc_slot_empty(exp_desc))) {
+				head = (head - 1) & slots;
+				break;
+			}
+			dma_rmb();
+			count++;
+		}
 		if (is_rx_desc(raw_desc))
 			ret = xgene_enet_rx_frame(ring, raw_desc);
 		else
 			ret = xgene_enet_tx_completion(ring, raw_desc);
 		xgene_enet_mark_desc_slot_empty(raw_desc);
+		if (exp_desc)
+			xgene_enet_mark_desc_slot_empty(exp_desc);
 
 		head = (head + 1) & slots;
 		count++;
+		processed++;
 
 		if (ret)
 			break;
@@ -408,7 +578,7 @@ static int xgene_enet_process_ring(struct xgene_enet_desc_ring *ring,
 		}
 	}
 
-	return count;
+	return processed;
 }
 
 static int xgene_enet_napi(struct napi_struct *napi, const int budget)
@@ -753,12 +923,13 @@ static int xgene_enet_create_desc_rings(struct net_device *ndev)
 	struct xgene_enet_desc_ring *rx_ring, *tx_ring, *cp_ring;
 	struct xgene_enet_desc_ring *buf_pool = NULL;
 	enum xgene_ring_owner owner;
+	dma_addr_t dma_exp_bufs;
 	u8 cpu_bufnum = pdata->cpu_bufnum;
 	u8 eth_bufnum = pdata->eth_bufnum;
 	u8 bp_bufnum = pdata->bp_bufnum;
 	u16 ring_num = pdata->ring_num;
 	u16 ring_id;
-	int ret;
+	int ret, size;
 
 	/* allocate rx descriptor ring */
 	owner = xgene_derive_ring_owner(pdata);
@@ -809,6 +980,15 @@ static int xgene_enet_create_desc_rings(struct net_device *ndev)
 		ret = -ENOMEM;
 		goto err;
 	}
+
+	size = (tx_ring->slots / 2) * sizeof(__le64) * MAX_EXP_BUFFS;
+	tx_ring->exp_bufs = dma_zalloc_coherent(dev, size, &dma_exp_bufs,
+						GFP_KERNEL);
+	if (!tx_ring->exp_bufs) {
+		ret = -ENOMEM;
+		goto err;
+	}
+
 	pdata->tx_ring = tx_ring;
 
 	if (!pdata->cq_cnt) {
@@ -833,6 +1013,16 @@ static int xgene_enet_create_desc_rings(struct net_device *ndev)
 		ret = -ENOMEM;
 		goto err;
 	}
+
+	size = sizeof(dma_addr_t) * MAX_SKB_FRAGS;
+	cp_ring->frag_dma_addr = devm_kcalloc(dev, tx_ring->slots,
+					      size, GFP_KERNEL);
+	if (!cp_ring->frag_dma_addr) {
+		devm_kfree(dev, cp_ring->cp_skb);
+		ret = -ENOMEM;
+		goto err;
+	}
+
 	pdata->tx_ring->cp_ring = cp_ring;
 	pdata->tx_ring->dst_ring_num = xgene_enet_dst_ring_num(cp_ring);
 
@@ -1222,7 +1412,8 @@ static int xgene_enet_probe(struct platform_device *pdev)
 	xgene_enet_set_ethtool_ops(ndev);
 	ndev->features |= NETIF_F_IP_CSUM |
 			  NETIF_F_GSO |
-			  NETIF_F_GRO;
+			  NETIF_F_GRO |
+			  NETIF_F_SG;
 
 	of_id = of_match_device(xgene_enet_of_match, &pdev->dev);
 	if (of_id) {
@@ -1248,6 +1439,12 @@ static int xgene_enet_probe(struct platform_device *pdev)
 
 	xgene_enet_setup_ops(pdata);
 
+	if (pdata->phy_mode == PHY_INTERFACE_MODE_XGMII) {
+		ndev->features |= NETIF_F_TSO;
+		pdata->mss = XGENE_ENET_MSS;
+	}
+	ndev->hw_features = ndev->features;
+
 	ret = register_netdev(ndev);
 	if (ret) {
 		netdev_err(ndev, "Failed to register netdev\n");
diff --git a/drivers/net/ethernet/apm/xgene/xgene_enet_main.h b/drivers/net/ethernet/apm/xgene/xgene_enet_main.h
index 2ac547e..50f92c3 100644
--- a/drivers/net/ethernet/apm/xgene/xgene_enet_main.h
+++ b/drivers/net/ethernet/apm/xgene/xgene_enet_main.h
@@ -43,6 +43,9 @@
 #define BUFLEN_16K	(16 * 1024)
 #define NUM_PKT_BUF	64
 #define NUM_BUFPOOL	32
+#define MAX_EXP_BUFFS	256
+#define XGENE_ENET_MSS	1448
+#define XGENE_MIN_ENET_FRAME_SIZE	60
 
 #define START_CPU_BUFNUM_0	0
 #define START_ETH_BUFNUM_0	2
@@ -80,6 +83,7 @@ struct xgene_enet_desc_ring {
 	u16 num;
 	u16 head;
 	u16 tail;
+	u16 exp_buf_tail;
 	u16 slots;
 	u16 irq;
 	char irq_name[IRQ_ID_SIZE];
@@ -94,6 +98,7 @@ struct xgene_enet_desc_ring {
 	u8 nbufpool;
 	struct sk_buff *(*rx_skb);
 	struct sk_buff *(*cp_skb);
+	dma_addr_t *frag_dma_addr;
 	enum xgene_enet_ring_cfgsize cfgsize;
 	struct xgene_enet_desc_ring *cp_ring;
 	struct xgene_enet_desc_ring *buf_pool;
@@ -103,6 +108,7 @@ struct xgene_enet_desc_ring {
 		struct xgene_enet_raw_desc *raw_desc;
 		struct xgene_enet_raw_desc16 *raw_desc16;
 	};
+	__le64 *exp_bufs;
 };
 
 struct xgene_mac_ops {
@@ -113,6 +119,7 @@ struct xgene_mac_ops {
 	void (*tx_disable)(struct xgene_enet_pdata *pdata);
 	void (*rx_disable)(struct xgene_enet_pdata *pdata);
 	void (*set_mac_addr)(struct xgene_enet_pdata *pdata);
+	void (*set_mss)(struct xgene_enet_pdata *pdata);
 	void (*link_state)(struct work_struct *work);
 };
 
@@ -171,6 +178,7 @@ struct xgene_enet_pdata {
 	u8 eth_bufnum;
 	u8 bp_bufnum;
 	u16 ring_num;
+	u32 mss;
 };
 
 struct xgene_indirect_ctl {
@@ -205,6 +213,9 @@ static inline u64 xgene_enet_get_field_value(int pos, int len, u64 src)
 #define GET_VAL(field, src) \
 		xgene_enet_get_field_value(field ## _POS, field ## _LEN, src)
 
+#define GET_BIT(field, src) \
+		xgene_enet_get_field_value(field ## _POS, 1, src)
+
 static inline struct device *ndev_to_dev(struct net_device *ndev)
 {
 	return ndev->dev.parent;
diff --git a/drivers/net/ethernet/apm/xgene/xgene_enet_xgmac.c b/drivers/net/ethernet/apm/xgene/xgene_enet_xgmac.c
index 05edb84..7a28a48 100644
--- a/drivers/net/ethernet/apm/xgene/xgene_enet_xgmac.c
+++ b/drivers/net/ethernet/apm/xgene/xgene_enet_xgmac.c
@@ -184,6 +184,11 @@ static void xgene_xgmac_set_mac_addr(struct xgene_enet_pdata *pdata)
 	xgene_enet_wr_mac(pdata, HSTMACADR_MSW_ADDR, addr1);
 }
 
+static void xgene_xgmac_set_mss(struct xgene_enet_pdata *pdata)
+{
+	xgene_enet_wr_csr(pdata, XG_TSIF_MSS_REG0_ADDR, pdata->mss);
+}
+
 static u32 xgene_enet_link_status(struct xgene_enet_pdata *pdata)
 {
 	u32 data;
@@ -204,8 +209,8 @@ static void xgene_xgmac_init(struct xgene_enet_pdata *pdata)
 	data &= ~HSTLENCHK;
 	xgene_enet_wr_mac(pdata, AXGMAC_CONFIG_1, data);
 
-	xgene_enet_wr_mac(pdata, HSTMAXFRAME_LENGTH_ADDR, 0x06000600);
 	xgene_xgmac_set_mac_addr(pdata);
+	xgene_xgmac_set_mss(pdata);
 
 	xgene_enet_rd_csr(pdata, XG_RSIF_CONFIG_REG_ADDR, &data);
 	data |= CFG_RSIF_FPBUFF_TIMEOUT_EN;
@@ -329,6 +334,7 @@ struct xgene_mac_ops xgene_xgmac_ops = {
 	.rx_disable = xgene_xgmac_rx_disable,
 	.tx_disable = xgene_xgmac_tx_disable,
 	.set_mac_addr = xgene_xgmac_set_mac_addr,
+	.set_mss = xgene_xgmac_set_mss,
 	.link_state = xgene_enet_link_state
 };
 
diff --git a/drivers/net/ethernet/apm/xgene/xgene_enet_xgmac.h b/drivers/net/ethernet/apm/xgene/xgene_enet_xgmac.h
index bf0a994..f8f908d 100644
--- a/drivers/net/ethernet/apm/xgene/xgene_enet_xgmac.h
+++ b/drivers/net/ethernet/apm/xgene/xgene_enet_xgmac.h
@@ -62,7 +62,9 @@
 #define XCLE_BYPASS_REG0_ADDR           0x0160
 #define XCLE_BYPASS_REG1_ADDR           0x0164
 #define XG_CFG_BYPASS_ADDR		0x0204
+#define XG_CFG_LINK_AGGR_RESUME_0_ADDR	0x0214
 #define XG_LINK_STATUS_ADDR		0x0228
+#define XG_TSIF_MSS_REG0_ADDR		0x02a4
 #define XG_ENET_SPARE_CFG_REG_ADDR	0x040c
 #define XG_ENET_SPARE_CFG_REG_1_ADDR	0x0410
 #define XGENET_RX_DV_GATE_REG_0_ADDR	0x0804
-- 
1.9.1



From hongzhou.yang at mediatek.com  Mon Aug 17 14:45:49 2015
From: hongzhou.yang at mediatek.com (Hongzhou Yang)
Date: Mon, 17 Aug 2015 14:45:49 -0700
Subject: [PATCH v4] pinctrl: mediatek: Implement wake handler and
 suspend resume
In-Reply-To: <1439817953.3414.4.camel@mtksdaap41>
References: <1439541486-22203-1-git-send-email-maoguang.meng@mediatek.com>
 <1439797974.22004.2.camel@mtksdaap41>
 <CAGS+omCQN65pCP7mYFCj8sDOihLNc15GgELw1u7fTXuq=KBXnw@mail.gmail.com>
 <1439817953.3414.4.camel@mtksdaap41>
Message-ID: <1439847949.12863.0.camel@mussux00.eus.mediatek.inc>

On Mon, 2015-08-17 at 21:25 +0800, Yingjoe Chen wrote:
> On Mon, 2015-08-17 at 17:09 +0800, Daniel Kurtz wrote:
> > On Mon, Aug 17, 2015 at 3:52 PM, Yingjoe Chen <yingjoe.chen at mediatek.com> wrote:
> > > On Fri, 2015-08-14 at 16:38 +0800, maoguang.meng at mediatek.com wrote:
> > >> From: Maoguang Meng <maoguang.meng at mediatek.com>
> > >>
> > >> This patch implement irq_set_wake to get who is wakeup source and
> > >> setup on suspend resume.
> > >>
> > >> Signed-off-by: Maoguang Meng <maoguang.meng at mediatek.com>
> > >>
> > >> ---
> > >> changes since v3:
> > >> -add a comment in mtk_eint_chip_read_mask.
> > >> -delete ALIGN when allocate eint_offsets.ports.
> > >> -fix unrelated change.
> > >>
> > >> changes since v2:
> > >> -modify irq_wake to handle irq wakeup source.
> > >> -allocate two buffers separately.
> > >> -fix some codestyle.
> > >>
> > >> Changes since v1:
> > >> -implement irq_wake handler.
> > >> ---
> > >>
> > >>  drivers/pinctrl/mediatek/pinctrl-mt8173.c     |  1 +
> > >>  drivers/pinctrl/mediatek/pinctrl-mtk-common.c | 91 ++++++++++++++++++++++++++-
> > >>  drivers/pinctrl/mediatek/pinctrl-mtk-common.h |  4 ++
> > >>  3 files changed, 95 insertions(+), 1 deletion(-)
> > >>
> > >> diff --git a/drivers/pinctrl/mediatek/pinctrl-mt8173.c b/drivers/pinctrl/mediatek/pinctrl-mt8173.c
> > >> index d0c811d..ad27184 100644
> > >> --- a/drivers/pinctrl/mediatek/pinctrl-mt8173.c
> > >> +++ b/drivers/pinctrl/mediatek/pinctrl-mt8173.c
> > >> @@ -385,6 +385,7 @@ static struct platform_driver mtk_pinctrl_driver = {
> > >>       .driver = {
> > >>               .name = "mediatek-mt8173-pinctrl",
> > >>               .of_match_table = mt8173_pctrl_match,
> > >> +             .pm = &mtk_eint_pm_ops,
> > >>       },
> > >>  };
> > >>
> > >> diff --git a/drivers/pinctrl/mediatek/pinctrl-mtk-common.c b/drivers/pinctrl/mediatek/pinctrl-mtk-common.c
> > >> index ad1ea16..fe34ce9 100644
> > >> --- a/drivers/pinctrl/mediatek/pinctrl-mtk-common.c
> > >> +++ b/drivers/pinctrl/mediatek/pinctrl-mtk-common.c
> > >> @@ -33,6 +33,7 @@
> > >>  #include <linux/mfd/syscon.h>
> > >>  #include <linux/delay.h>
> > >>  #include <linux/interrupt.h>
> > >> +#include <linux/pm.h>
> > >>  #include <dt-bindings/pinctrl/mt65xx.h>
> > >>
> > >>  #include "../core.h"
> > >> @@ -1062,6 +1063,77 @@ static int mtk_eint_set_type(struct irq_data *d,
> > >>       return 0;
> > >>  }
> > >>
> > >> +static int mtk_eint_irq_set_wake(struct irq_data *d, unsigned int on)
> > >> +{
> > >> +     struct mtk_pinctrl *pctl = irq_data_get_irq_chip_data(d);
> > >> +     int shift = d->hwirq & 0x1f;
> > >> +     int reg = d->hwirq >> 5;
> > >> +
> > >> +     if (on)
> > >> +             pctl->wake_mask[reg] |= BIT(shift);
> > >> +     else
> > >> +             pctl->wake_mask[reg] &= ~BIT(shift);
> > >> +
> > >> +     return 0;
> > >> +}
> > >
> > > Hi Maoguang,
> > >
> > > You changed from set_bit/clear_bit to this, but didn't add any locking.
> > > Since this is basic read/modify/write, is it OK to do it without
> > > locking?
> > 
> > I believe calling .irq_set_wake() concurrently with itself is
> > protected by irq_get_desc_buslock():
> > 
> >  int irq_set_irq_wake(unsigned int irq, unsigned int on)
> >  {
> >          unsigned long flags;
> >          struct irq_desc *desc = irq_get_desc_buslock(irq, &flags,
> > IRQ_GET_DESC_CHECK_GLOBAL);
> >          int ret = 0;
> > ...
> >                          ret = set_irq_wake_real(irq, on);
> > ...
> >          irq_put_desc_busunlock(desc, flags);
> >          return ret;
> >  }
> 
> Hi Dan,
> 
> You are right, irq_get_desc_buslock will acquire desc lock even when
> irq_chip didn't provide irq_bus_lock callback. So this should be OK.
> Sorry for the noise.
> 
> For this patch:
> 
> Acked-by: Yingjoe Chen <yingjoe.chen at mediatek.com>
> 
> Joe.C
> 


Acked-by: Hongzhou Yang <hongzhou.yang at mediatek.com>

Thanks.
Hongzhou




From petr.cvek at tul.cz  Mon Aug 17 14:55:07 2015
From: petr.cvek at tul.cz (Petr Cvek)
Date: Mon, 17 Aug 2015 23:55:07 +0200
Subject: [PATCH v2 00/21] ARM: pxa: magician: Rework HTC Magician support
Message-ID: <55D2583B.8040602@tul.cz>

This patchset will clean, fix and finally add multiple PXA devices
to HTC Magician machine. Also it adds leds-pasic3 driver to LED subsystem.
This driver require changes into htc-pasic3 structures, which are used
exclusively by magician.c code.

Petr Cvek (21):
  ARM: pxa: magician: Fix Kconfig for magician to always include
    htc-egpio
  ARM: pxa: magician: Fix indentation and whitespaces
  ARM: pxa: magician: Fix comments, debug functions and print strings
  ARM: pxa: magician: Add, fix and init (new) GPIOs
  ARM: pxa: magician: Add support for ADS7846 touchscreen
  ARM: pxa: magician: Add normal and power I2C definition
  ARM: pxa: magician: Fix IrDA pdata and redundant GPIO request
  ARM: pxa: magician: Add StrataFlash Vpp GPIO and alternative driver
  ARM: pxa: magician: Add OV9640 camera support
  ARM: pxa: magician: Add UDA1380 sound support
  ARM: pxa: magician: Add MAX1586 Vcore regulator support
  ARM: pxa: magician: Add PXA27x UDC support
  ARM: pxa: magician: Fix charging source and add NiCd backup charging
  ARM: pxa: magician: Fix PXA USB OHCI port enable flags
  ARM: pxa: magician: Fix PWM backlight regulator
  ARM: pxa: magician: Add support for alternative LCD backlight
  ARM: pxa: magician: Remove (temporarily) pasic3 LED support
  mfd: htc-pasic3: Prepare driver for leds-pasic3
  leds: leds-pasic3: Add support for PASIC3 LED controller
  ARM: pxa: magician: Re-add pdata for new leds-pasic3 driver
  ARM: pxa: magician: Move platform_add_devices() to the end of
    magician_init()

 arch/arm/mach-pxa/Kconfig                 |    1 +
 arch/arm/mach-pxa/include/mach/magician.h |   39 +-
 arch/arm/mach-pxa/magician.c              | 1153 ++++++++++++++++++++++-------
 drivers/leds/Kconfig                      |    9 +
 drivers/leds/Makefile                     |    1 +
 drivers/leds/leds-pasic3.c                |  232 ++++++
 drivers/mfd/htc-pasic3.c                  |   54 +-
 include/linux/mfd/htc-pasic3.h            |   85 ++-
 8 files changed, 1255 insertions(+), 319 deletions(-)
 create mode 100644 drivers/leds/leds-pasic3.c

-- 
1.7.12.1



From petr.cvek at tul.cz  Mon Aug 17 14:56:16 2015
From: petr.cvek at tul.cz (Petr Cvek)
Date: Mon, 17 Aug 2015 23:56:16 +0200
Subject: [PATCH v2 01/21] ARM: pxa: magician: Fix Kconfig for magician to
 always include htc-egpio
In-Reply-To: <cover.1439843482.git.petr.cvek@tul.cz>
References: <cover.1439843482.git.petr.cvek@tul.cz>
Message-ID: <55D25880.3030507@tul.cz>

The htc-egpio driver should be always included in the kernel as it
controls MMC/charging/IrDA power, which is the only way to get
an useful rootfs.

Signed-off-by: Petr Cvek <petr.cvek at tul.cz>
---
 arch/arm/mach-pxa/Kconfig | 1 +
 1 file changed, 1 insertion(+)

diff --git a/arch/arm/mach-pxa/Kconfig b/arch/arm/mach-pxa/Kconfig
index f096836..5c7b6ee 100644
--- a/arch/arm/mach-pxa/Kconfig
+++ b/arch/arm/mach-pxa/Kconfig
@@ -294,6 +294,7 @@ config MACH_MAGICIAN
 	bool "Enable HTC Magician Support"
 	select IWMMXT
 	select PXA27x
+	select HTC_EGPIO
 
 config MACH_MIOA701
 	bool "Mitac Mio A701 Support"
-- 
1.7.12.1



From petr.cvek at tul.cz  Mon Aug 17 14:56:54 2015
From: petr.cvek at tul.cz (Petr Cvek)
Date: Mon, 17 Aug 2015 23:56:54 +0200
Subject: [PATCH v2 02/21] ARM: pxa: magician: Fix indentation and whitespaces
In-Reply-To: <cover.1439843482.git.petr.cvek@tul.cz>
References: <cover.1439843482.git.petr.cvek@tul.cz>
Message-ID: <55D258A6.2040105@tul.cz>

Fix magician.c: indentation and whitespaces.

Signed-off-by: Petr Cvek <petr.cvek at tul.cz>
---
 arch/arm/mach-pxa/magician.c | 356 +++++++++++++++++++++----------------------
 1 file changed, 178 insertions(+), 178 deletions(-)

diff --git a/arch/arm/mach-pxa/magician.c b/arch/arm/mach-pxa/magician.c
index a9761c2..9e8698a 100644
--- a/arch/arm/mach-pxa/magician.c
+++ b/arch/arm/mach-pxa/magician.c
@@ -52,8 +52,8 @@ static unsigned long magician_pin_config[] __initdata = {
 	GPIO20_nSDCS_2,
 	GPIO21_nSDCS_3,
 	GPIO15_nCS_1,
-	GPIO78_nCS_2,   /* PASIC3 */
-	GPIO79_nCS_3,   /* EGPIO CPLD */
+	GPIO78_nCS_2,	/* PASIC3 */
+	GPIO79_nCS_3,	/* EGPIO CPLD */
 	GPIO80_nCS_4,
 	GPIO33_nCS_5,
 
@@ -107,7 +107,7 @@ static unsigned long magician_pin_config[] __initdata = {
 	GPIO85_CIF_LV,
 
 	/* Magician specific input GPIOs */
-	GPIO9_GPIO,	/* unknown */
+	GPIO9_GPIO,		/* unknown */
 	GPIO10_GPIO,	/* GSM_IRQ */
 	GPIO13_GPIO,	/* CPLD_IRQ */
 	GPIO107_GPIO,	/* DS1WM_IRQ */
@@ -133,46 +133,45 @@ static struct pxaficp_platform_data magician_ficp_info = {
  */
 
 #define INIT_KEY(_code, _gpio, _desc)	\
-	{				\
-		.code   = KEY_##_code,	\
-		.gpio   = _gpio,	\
-		.desc   = _desc,	\
-		.type   = EV_KEY,	\
-		.wakeup = 1,		\
+	{						\
+		.code	= KEY_##_code,	\
+		.gpio	= _gpio,	\
+		.desc	= _desc,	\
+		.type	= EV_KEY,	\
+		.wakeup	= 1,		\
 	}
 
 static struct gpio_keys_button magician_button_table[] = {
-	INIT_KEY(POWER,      GPIO0_MAGICIAN_KEY_POWER,      "Power button"),
-	INIT_KEY(ESC,        GPIO37_MAGICIAN_KEY_HANGUP,    "Hangup button"),
-	INIT_KEY(F10,        GPIO38_MAGICIAN_KEY_CONTACTS,  "Contacts button"),
-	INIT_KEY(CALENDAR,   GPIO90_MAGICIAN_KEY_CALENDAR,  "Calendar button"),
-	INIT_KEY(CAMERA,     GPIO91_MAGICIAN_KEY_CAMERA,    "Camera button"),
-	INIT_KEY(UP,         GPIO93_MAGICIAN_KEY_UP,        "Up button"),
-	INIT_KEY(DOWN,       GPIO94_MAGICIAN_KEY_DOWN,      "Down button"),
-	INIT_KEY(LEFT,       GPIO95_MAGICIAN_KEY_LEFT,      "Left button"),
-	INIT_KEY(RIGHT,      GPIO96_MAGICIAN_KEY_RIGHT,     "Right button"),
-	INIT_KEY(KPENTER,    GPIO97_MAGICIAN_KEY_ENTER,     "Action button"),
-	INIT_KEY(RECORD,     GPIO98_MAGICIAN_KEY_RECORD,    "Record button"),
-	INIT_KEY(VOLUMEUP,   GPIO100_MAGICIAN_KEY_VOL_UP,   "Volume up"),
-	INIT_KEY(VOLUMEDOWN, GPIO101_MAGICIAN_KEY_VOL_DOWN, "Volume down"),
-	INIT_KEY(PHONE,      GPIO102_MAGICIAN_KEY_PHONE,    "Phone button"),
-	INIT_KEY(PLAY,       GPIO99_MAGICIAN_HEADPHONE_IN,  "Headset button"),
+	INIT_KEY(POWER,		GPIO0_MAGICIAN_KEY_POWER,	"Power button"),
+	INIT_KEY(ESC,		GPIO37_MAGICIAN_KEY_HANGUP,	"Hangup button"),
+	INIT_KEY(F10,		GPIO38_MAGICIAN_KEY_CONTACTS,	"Contacts button"),
+	INIT_KEY(CALENDAR,	GPIO90_MAGICIAN_KEY_CALENDAR,	"Calendar button"),
+	INIT_KEY(CAMERA,	GPIO91_MAGICIAN_KEY_CAMERA,	"Camera button"),
+	INIT_KEY(UP,		GPIO93_MAGICIAN_KEY_UP,		"Up button"),
+	INIT_KEY(DOWN,		GPIO94_MAGICIAN_KEY_DOWN,	"Down button"),
+	INIT_KEY(LEFT,		GPIO95_MAGICIAN_KEY_LEFT,	"Left button"),
+	INIT_KEY(RIGHT,		GPIO96_MAGICIAN_KEY_RIGHT,	"Right button"),
+	INIT_KEY(KPENTER,	GPIO97_MAGICIAN_KEY_ENTER,	"Action button"),
+	INIT_KEY(RECORD,	GPIO98_MAGICIAN_KEY_RECORD,	"Record button"),
+	INIT_KEY(VOLUMEUP,	GPIO100_MAGICIAN_KEY_VOL_UP,	"Volume up"),
+	INIT_KEY(VOLUMEDOWN,	GPIO101_MAGICIAN_KEY_VOL_DOWN,	"Volume down"),
+	INIT_KEY(PHONE,		GPIO102_MAGICIAN_KEY_PHONE,	"Phone button"),
+	INIT_KEY(PLAY,		GPIO99_MAGICIAN_HEADPHONE_IN,	"Headset button"),
 };
 
 static struct gpio_keys_platform_data gpio_keys_data = {
-	.buttons  = magician_button_table,
+	.buttons = magician_button_table,
 	.nbuttons = ARRAY_SIZE(magician_button_table),
 };
 
 static struct platform_device gpio_keys = {
 	.name = "gpio-keys",
-	.dev  = {
+	.dev = {
 		.platform_data = &gpio_keys_data,
 	},
-	.id   = -1,
+	.id = -1,
 };
 
-
 /*
  * EGPIO (Xilinx CPLD)
  *
@@ -181,14 +180,14 @@ static struct platform_device gpio_keys = {
 
 static struct resource egpio_resources[] = {
 	[0] = {
-		.start = PXA_CS3_PHYS,
-		.end   = PXA_CS3_PHYS + 0x20 - 1,
-		.flags = IORESOURCE_MEM,
+		.start	= PXA_CS3_PHYS,
+		.end	= PXA_CS3_PHYS + 0x20 - 1,
+		.flags	= IORESOURCE_MEM,
 	},
 	[1] = {
-		.start = PXA_GPIO_TO_IRQ(GPIO13_MAGICIAN_CPLD_IRQ),
-		.end   = PXA_GPIO_TO_IRQ(GPIO13_MAGICIAN_CPLD_IRQ),
-		.flags = IORESOURCE_IRQ,
+		.start	= PXA_GPIO_TO_IRQ(GPIO13_MAGICIAN_CPLD_IRQ),
+		.end	= PXA_GPIO_TO_IRQ(GPIO13_MAGICIAN_CPLD_IRQ),
+		.flags	= IORESOURCE_IRQ,
 	},
 };
 
@@ -209,20 +208,20 @@ static struct htc_egpio_chip egpio_chips[] = {
 };
 
 static struct htc_egpio_platform_data egpio_info = {
-	.reg_width    = 8,
-	.bus_width    = 32,
-	.irq_base     = IRQ_BOARD_START,
-	.num_irqs     = 4,
-	.ack_register = 3,
-	.chip         = egpio_chips,
-	.num_chips    = ARRAY_SIZE(egpio_chips),
+	.reg_width	= 8,
+	.bus_width	= 32,
+	.irq_base	= IRQ_BOARD_START,
+	.num_irqs	= 4,
+	.ack_register	= 3,
+	.chip		= egpio_chips,
+	.num_chips	= ARRAY_SIZE(egpio_chips),
 };
 
 static struct platform_device egpio = {
-	.name          = "htc-egpio",
-	.id            = -1,
-	.resource      = egpio_resources,
-	.num_resources = ARRAY_SIZE(egpio_resources),
+	.name		= "htc-egpio",
+	.id		= -1,
+	.resource	= egpio_resources,
+	.num_resources	= ARRAY_SIZE(egpio_resources),
 	.dev = {
 		.platform_data = &egpio_info,
 	},
@@ -234,33 +233,33 @@ static struct platform_device egpio = {
 
 static struct pxafb_mode_info toppoly_modes[] = {
 	{
-		.pixclock     = 96153,
-		.bpp          = 16,
-		.xres         = 240,
-		.yres         = 320,
-		.hsync_len    = 11,
-		.vsync_len    = 3,
-		.left_margin  = 19,
-		.upper_margin = 2,
-		.right_margin = 10,
-		.lower_margin = 2,
-		.sync         = 0,
+		.pixclock	= 96153,
+		.bpp		= 16,
+		.xres		= 240,
+		.yres		= 320,
+		.hsync_len	= 11,
+		.vsync_len	= 3,
+		.left_margin	= 19,
+		.upper_margin	= 2,
+		.right_margin	= 10,
+		.lower_margin	= 2,
+		.sync		= 0,
 	},
 };
 
 static struct pxafb_mode_info samsung_modes[] = {
 	{
-		.pixclock     = 96153,
-		.bpp          = 16,
-		.xres         = 240,
-		.yres         = 320,
-		.hsync_len    = 8,
-		.vsync_len    = 4,
-		.left_margin  = 9,
-		.upper_margin = 4,
-		.right_margin = 9,
-		.lower_margin = 4,
-		.sync         = FB_SYNC_HOR_HIGH_ACT | FB_SYNC_VERT_HIGH_ACT,
+		.pixclock	= 96153,
+		.bpp		= 16,
+		.xres		= 240,
+		.yres		= 320,
+		.hsync_len	= 8,
+		.vsync_len	= 4,
+		.left_margin	= 9,
+		.upper_margin	= 4,
+		.right_margin	= 9,
+		.lower_margin	= 4,
+		.sync	= FB_SYNC_HOR_HIGH_ACT | FB_SYNC_VERT_HIGH_ACT,
 	},
 };
 
@@ -326,19 +325,19 @@ static void samsung_lcd_power(int on, struct fb_var_screeninfo *si)
 }
 
 static struct pxafb_mach_info toppoly_info = {
-	.modes           = toppoly_modes,
-	.num_modes       = 1,
-	.fixed_modes     = 1,
+	.modes		= toppoly_modes,
+	.num_modes	= 1,
+	.fixed_modes	= 1,
 	.lcd_conn	= LCD_COLOR_TFT_16BPP,
 	.pxafb_lcd_power = toppoly_lcd_power,
 };
 
 static struct pxafb_mach_info samsung_info = {
-	.modes           = samsung_modes,
-	.num_modes       = 1,
-	.fixed_modes     = 1,
-	.lcd_conn	 = LCD_COLOR_TFT_16BPP | LCD_PCLK_EDGE_FALL |\
-			   LCD_ALTERNATE_MAPPING,
+	.modes		= samsung_modes,
+	.num_modes	= 1,
+	.fixed_modes	= 1,
+	.lcd_conn	= LCD_COLOR_TFT_16BPP | LCD_PCLK_EDGE_FALL |
+		LCD_ALTERNATE_MAPPING,
 	.pxafb_lcd_power = samsung_lcd_power,
 };
 
@@ -374,22 +373,22 @@ static void magician_backlight_exit(struct device *dev)
 }
 
 static struct platform_pwm_backlight_data backlight_data = {
-	.pwm_id         = 0,
-	.max_brightness = 272,
-	.dft_brightness = 100,
-	.pwm_period_ns  = 30923,
-	.enable_gpio    = -1,
-	.init           = magician_backlight_init,
-	.notify         = magician_backlight_notify,
-	.exit           = magician_backlight_exit,
+	.pwm_id		= 0,
+	.max_brightness	= 272,
+	.dft_brightness	= 100,
+	.pwm_period_ns	= 30923,
+	.enable_gpio	= -1,
+	.init		= magician_backlight_init,
+	.notify		= magician_backlight_notify,
+	.exit		= magician_backlight_exit,
 };
 
 static struct platform_device backlight = {
-	.name = "pwm-backlight",
-	.id   = -1,
-	.dev  = {
-		.parent        = &pxa27x_device_pwm0.dev,
-		.platform_data = &backlight_data,
+	.name	= "pwm-backlight",
+	.id	= -1,
+	.dev	= {
+		.parent		= &pxa27x_device_pwm0.dev,
+		.platform_data	= &backlight_data,
 	},
 };
 
@@ -416,9 +415,9 @@ static struct gpio_led_platform_data gpio_led_info = {
 };
 
 static struct platform_device leds_gpio = {
-	.name = "leds-gpio",
-	.id   = -1,
-	.dev  = {
+	.name	= "leds-gpio",
+	.id	= -1,
+	.dev	= {
 		.platform_data = &gpio_led_info,
 	},
 };
@@ -426,37 +425,37 @@ static struct platform_device leds_gpio = {
 static struct pasic3_led pasic3_leds[] = {
 	{
 		.led = {
-			.name            = "magician:red",
+			.name = "magician:red",
 			.default_trigger = "ds2760-battery.0-charging",
 		},
-		.hw_num = 0,
-		.bit2   = PASIC3_BIT2_LED0,
-		.mask   = PASIC3_MASK_LED0,
+		.hw_num	= 0,
+		.bit2	= PASIC3_BIT2_LED0,
+		.mask	= PASIC3_MASK_LED0,
 	},
 	{
 		.led = {
-			.name            = "magician:green",
+			.name = "magician:green",
 			.default_trigger = "ds2760-battery.0-charging-or-full",
 		},
-		.hw_num = 1,
-		.bit2   = PASIC3_BIT2_LED1,
-		.mask   = PASIC3_MASK_LED1,
+		.hw_num	= 1,
+		.bit2	= PASIC3_BIT2_LED1,
+		.mask	= PASIC3_MASK_LED1,
 	},
 	{
 		.led = {
-			.name            = "magician:blue",
+			.name = "magician:blue",
 			.default_trigger = "bluetooth",
 		},
-		.hw_num = 2,
-		.bit2   = PASIC3_BIT2_LED2,
-		.mask   = PASIC3_MASK_LED2,
+		.hw_num	= 2,
+		.bit2	= PASIC3_BIT2_LED2,
+		.mask	= PASIC3_MASK_LED2,
 	},
 };
 
 static struct pasic3_leds_machinfo pasic3_leds_info = {
-	.num_leds   = ARRAY_SIZE(pasic3_leds),
-	.power_gpio = EGPIO_MAGICIAN_LED_POWER,
-	.leds       = pasic3_leds,
+	.num_leds	= ARRAY_SIZE(pasic3_leds),
+	.power_gpio	= EGPIO_MAGICIAN_LED_POWER,
+	.leds		= pasic3_leds,
 };
 
 /*
@@ -465,28 +464,28 @@ static struct pasic3_leds_machinfo pasic3_leds_info = {
 
 static struct resource pasic3_resources[] = {
 	[0] = {
-		.start  = PXA_CS2_PHYS,
+		.start	= PXA_CS2_PHYS,
 		.end	= PXA_CS2_PHYS + 0x1b,
-		.flags  = IORESOURCE_MEM,
+		.flags	= IORESOURCE_MEM,
 	},
 	/* No IRQ handler in the PASIC3, DS1WM needs an external IRQ */
 	[1] = {
-		.start  = PXA_GPIO_TO_IRQ(GPIO107_MAGICIAN_DS1WM_IRQ),
-		.end    = PXA_GPIO_TO_IRQ(GPIO107_MAGICIAN_DS1WM_IRQ),
-		.flags  = IORESOURCE_IRQ | IORESOURCE_IRQ_HIGHEDGE,
+		.start	= PXA_GPIO_TO_IRQ(GPIO107_MAGICIAN_DS1WM_IRQ),
+		.end	= PXA_GPIO_TO_IRQ(GPIO107_MAGICIAN_DS1WM_IRQ),
+		.flags	= IORESOURCE_IRQ | IORESOURCE_IRQ_HIGHEDGE,
 	}
 };
 
 static struct pasic3_platform_data pasic3_platform_data = {
-	.led_pdata  = &pasic3_leds_info,
-	.clock_rate = 4000000,
+	.led_pdata	= &pasic3_leds_info,
+	.clock_rate	= 4000000,
 };
 
 static struct platform_device pasic3 = {
-	.name		= "pasic3",
-	.id		= -1,
-	.num_resources	= ARRAY_SIZE(pasic3_resources),
-	.resource	= pasic3_resources,
+	.name = "pasic3",
+	.id = -1,
+	.num_resources = ARRAY_SIZE(pasic3_resources),
+	.resource = pasic3_resources,
 	.dev = {
 		.platform_data = &pasic3_platform_data,
 	},
@@ -497,21 +496,21 @@ static struct platform_device pasic3 = {
  */
 
 static struct resource gpio_vbus_resource = {
-	.flags = IORESOURCE_IRQ,
-	.start = IRQ_MAGICIAN_VBUS,
-	.end   = IRQ_MAGICIAN_VBUS,
+	.flags	= IORESOURCE_IRQ,
+	.start	= IRQ_MAGICIAN_VBUS,
+	.end	= IRQ_MAGICIAN_VBUS,
 };
 
 static struct gpio_vbus_mach_info gpio_vbus_info = {
 	.gpio_pullup = GPIO27_MAGICIAN_USBC_PUEN,
-	.gpio_vbus   = EGPIO_MAGICIAN_CABLE_STATE_USB,
+	.gpio_vbus = EGPIO_MAGICIAN_CABLE_STATE_USB,
 };
 
 static struct platform_device gpio_vbus = {
-	.name          = "gpio-vbus",
-	.id            = -1,
-	.num_resources = 1,
-	.resource      = &gpio_vbus_resource,
+	.name		= "gpio-vbus",
+	.id		= -1,
+	.num_resources	= 1,
+	.resource	= &gpio_vbus_resource,
 	.dev = {
 		.platform_data = &gpio_vbus_info,
 	},
@@ -541,38 +540,38 @@ static char *magician_supplicants[] = {
 };
 
 static struct pda_power_pdata power_supply_info = {
-	.init            = power_supply_init,
-	.is_ac_online    = magician_is_ac_online,
-	.exit            = power_supply_exit,
-	.supplied_to     = magician_supplicants,
+	.init		= power_supply_init,
+	.is_ac_online	= magician_is_ac_online,
+	.exit		= power_supply_exit,
+	.supplied_to	= magician_supplicants,
 	.num_supplicants = ARRAY_SIZE(magician_supplicants),
 };
 
 static struct resource power_supply_resources[] = {
 	[0] = {
-		.name  = "ac",
-		.flags = IORESOURCE_IRQ | IORESOURCE_IRQ_HIGHEDGE |
-		         IORESOURCE_IRQ_LOWEDGE,
-		.start = IRQ_MAGICIAN_VBUS,
-		.end   = IRQ_MAGICIAN_VBUS,
+		.name	= "ac",
+		.flags	= IORESOURCE_IRQ | IORESOURCE_IRQ_HIGHEDGE |
+			IORESOURCE_IRQ_LOWEDGE,
+		.start	= IRQ_MAGICIAN_VBUS,
+		.end	= IRQ_MAGICIAN_VBUS,
 	},
 	[1] = {
-		.name  = "usb",
-		.flags = IORESOURCE_IRQ | IORESOURCE_IRQ_HIGHEDGE |
-		         IORESOURCE_IRQ_LOWEDGE,
-		.start = IRQ_MAGICIAN_VBUS,
-		.end   = IRQ_MAGICIAN_VBUS,
+		.name	= "usb",
+		.flags	= IORESOURCE_IRQ | IORESOURCE_IRQ_HIGHEDGE |
+			IORESOURCE_IRQ_LOWEDGE,
+		.start	= IRQ_MAGICIAN_VBUS,
+		.end	= IRQ_MAGICIAN_VBUS,
 	},
 };
 
 static struct platform_device power_supply = {
-	.name = "pda-power",
-	.id   = -1,
-	.dev  = {
+	.name	= "pda-power",
+	.id	= -1,
+	.dev = {
 		.platform_data = &power_supply_info,
 	},
-	.resource      = power_supply_resources,
-	.num_resources = ARRAY_SIZE(power_supply_resources),
+	.resource	= power_supply_resources,
+	.num_resources	= ARRAY_SIZE(power_supply_resources),
 };
 
 /*
@@ -586,11 +585,12 @@ static struct regulator_consumer_supply bq24022_consumers[] = {
 
 static struct regulator_init_data bq24022_init_data = {
 	.constraints = {
-		.max_uA         = 500000,
-		.valid_ops_mask = REGULATOR_CHANGE_CURRENT | REGULATOR_CHANGE_STATUS,
+		.max_uA = 500000,
+		.valid_ops_mask = REGULATOR_CHANGE_CURRENT |
+			REGULATOR_CHANGE_STATUS,
 	},
-	.num_consumer_supplies  = ARRAY_SIZE(bq24022_consumers),
-	.consumer_supplies      = bq24022_consumers,
+	.num_consumer_supplies = ARRAY_SIZE(bq24022_consumers),
+	.consumer_supplies = bq24022_consumers,
 };
 
 static struct gpio bq24022_gpios[] = {
@@ -620,9 +620,9 @@ static struct gpio_regulator_config bq24022_info = {
 };
 
 static struct platform_device bq24022 = {
-	.name = "gpio-regulator",
-	.id   = -1,
-	.dev  = {
+	.name	= "gpio-regulator",
+	.id	= -1,
+	.dev	= {
 		.platform_data = &bq24022_info,
 	},
 };
@@ -632,10 +632,10 @@ static struct platform_device bq24022 = {
  */
 
 static int magician_mci_init(struct device *dev,
-				irq_handler_t detect_irq, void *data)
+	irq_handler_t detect_irq, void *data)
 {
 	return request_irq(IRQ_MAGICIAN_SD, detect_irq, 0,
-			   "mmc card detect", data);
+		"mmc card detect", data);
 }
 
 static void magician_mci_exit(struct device *dev, void *data)
@@ -644,13 +644,13 @@ static void magician_mci_exit(struct device *dev, void *data)
 }
 
 static struct pxamci_platform_data magician_mci_info = {
-	.ocr_mask 		= MMC_VDD_32_33|MMC_VDD_33_34,
-	.init     		= magician_mci_init,
-	.exit     		= magician_mci_exit,
+	.ocr_mask	= MMC_VDD_32_33|MMC_VDD_33_34,
+	.init		= magician_mci_init,
+	.exit		= magician_mci_exit,
 	.gpio_card_detect	= -1,
 	.gpio_card_ro		= EGPIO_MAGICIAN_nSD_READONLY,
 	.gpio_card_ro_invert	= 1,
-	.gpio_power		= EGPIO_MAGICIAN_SD_POWER,
+	.gpio_power	= EGPIO_MAGICIAN_SD_POWER,
 };
 
 
@@ -664,7 +664,6 @@ static struct pxaohci_platform_data magician_ohci_info = {
 	.power_budget	= 0,
 };
 
-
 /*
  * StrataFlash
  */
@@ -675,9 +674,9 @@ static void magician_set_vpp(struct platform_device *pdev, int vpp)
 }
 
 static struct resource strataflash_resource = {
-	.start = PXA_CS0_PHYS,
-	.end   = PXA_CS0_PHYS + SZ_64M - 1,
-	.flags = IORESOURCE_MEM,
+	.start	= PXA_CS0_PHYS,
+	.end	= PXA_CS0_PHYS + SZ_64M - 1,
+	.flags	= IORESOURCE_MEM,
 };
 
 static struct physmap_flash_data strataflash_data = {
@@ -686,10 +685,10 @@ static struct physmap_flash_data strataflash_data = {
 };
 
 static struct platform_device strataflash = {
-	.name          = "physmap-flash",
-	.id            = -1,
-	.resource      = &strataflash_resource,
-	.num_resources = 1,
+	.name		= "physmap-flash",
+	.id		= -1,
+	.resource	= &strataflash_resource,
+	.num_resources	= 1,
 	.dev = {
 		.platform_data = &strataflash_data,
 	},
@@ -720,12 +719,12 @@ static struct platform_device *devices[] __initdata = {
 };
 
 static struct gpio magician_global_gpios[] = {
-	{ GPIO13_MAGICIAN_CPLD_IRQ,   GPIOF_IN, "CPLD_IRQ" },
-	{ GPIO107_MAGICIAN_DS1WM_IRQ, GPIOF_IN, "DS1WM_IRQ" },
+	{ GPIO13_MAGICIAN_CPLD_IRQ, GPIOF_IN,		"CPLD_IRQ" },
+	{ GPIO107_MAGICIAN_DS1WM_IRQ, GPIOF_IN,	"DS1WM_IRQ" },
 	{ GPIO104_MAGICIAN_LCD_POWER_1, GPIOF_OUT_INIT_LOW, "LCD power 1" },
 	{ GPIO105_MAGICIAN_LCD_POWER_2, GPIOF_OUT_INIT_LOW, "LCD power 2" },
 	{ GPIO106_MAGICIAN_LCD_POWER_3, GPIOF_OUT_INIT_LOW, "LCD power 3" },
-	{ GPIO83_MAGICIAN_nIR_EN, GPIOF_OUT_INIT_HIGH, "nIR_EN" },
+	{ GPIO83_MAGICIAN_nIR_EN, GPIOF_OUT_INIT_HIGH,	"nIR_EN" },
 };
 
 static void __init magician_init(void)
@@ -754,27 +753,28 @@ static void __init magician_init(void)
 	/* Check LCD type we have */
 	cpld = ioremap_nocache(PXA_CS3_PHYS, 0x1000);
 	if (cpld) {
-		u8 board_id = __raw_readb(cpld+0x14);
+		u8 board_id = __raw_readb(cpld + 0x14);
+
 		iounmap(cpld);
 		system_rev = board_id & 0x7;
 		lcd_select = board_id & 0x8;
 		pr_info("LCD type: %s\n", lcd_select ? "Samsung" : "Toppoly");
 		if (lcd_select && (system_rev < 3))
 			gpio_request_one(GPIO75_MAGICIAN_SAMSUNG_POWER,
-			                 GPIOF_OUT_INIT_LOW, "SAMSUNG_POWER");
-		pxa_set_fb_info(NULL, lcd_select ? &samsung_info : &toppoly_info);
+				GPIOF_OUT_INIT_LOW, "SAMSUNG_POWER");
+		pxa_set_fb_info(NULL,
+			lcd_select ? &samsung_info : &toppoly_info);
 	} else
 		pr_err("LCD detection: CPLD mapping failed\n");
 }
 
-
 MACHINE_START(MAGICIAN, "HTC Magician")
-	.atag_offset = 0x100,
-	.map_io = pxa27x_map_io,
-	.nr_irqs = MAGICIAN_NR_IRQS,
-	.init_irq = pxa27x_init_irq,
-	.handle_irq = pxa27x_handle_irq,
-	.init_machine = magician_init,
+	.atag_offset	= 0x100,
+	.map_io		= pxa27x_map_io,
+	.nr_irqs	= MAGICIAN_NR_IRQS,
+	.init_irq	= pxa27x_init_irq,
+	.handle_irq	= pxa27x_handle_irq,
+	.init_machine	= magician_init,
 	.init_time	= pxa_timer_init,
 	.restart	= pxa_restart,
 MACHINE_END
-- 
1.7.12.1



From petr.cvek at tul.cz  Mon Aug 17 14:57:33 2015
From: petr.cvek at tul.cz (Petr Cvek)
Date: Mon, 17 Aug 2015 23:57:33 +0200
Subject: [PATCH v2 03/21] ARM: pxa: magician: Fix comments, debug functions
 and print strings
In-Reply-To: <cover.1439843482.git.petr.cvek@tul.cz>
References: <cover.1439843482.git.petr.cvek@tul.cz>
Message-ID: <55D258CD.40101@tul.cz>

Fix comments, debug functions and print strings. Rename backlight
structures to be more specific.

Signed-off-by: Petr Cvek <petr.cvek at tul.cz>
---
 arch/arm/mach-pxa/magician.c | 121 +++++++++++++++++++++++++++++++------------
 1 file changed, 89 insertions(+), 32 deletions(-)

diff --git a/arch/arm/mach-pxa/magician.c b/arch/arm/mach-pxa/magician.c
index 9e8698a..57da133 100644
--- a/arch/arm/mach-pxa/magician.c
+++ b/arch/arm/mach-pxa/magician.c
@@ -11,6 +11,46 @@
  * it under the terms of the GNU General Public License version 2 as
  * published by the Free Software Foundation.
  *
+ *
+ * NOTICE MDA Compact (T-mobile XDA) facts:
+ *   On "LCD type = 1, system_rev = 2" (0x3a in CPLD)
+ * Samsung LTP280QV - valid LCD init sequence sequence:
+ *   powerup: Vdigital->Vanalog->gate Voff->gate Von->data enable
+ *   powerdown: data disable->gate Von->gate Voff->Vanalog->Vdigital
+ * Measured on PCB:
+ *   GPIO106
+ *     Affects VOFF, VON and other voltages
+ *     Probably main reset pin for DC-DC converter
+ *   GPIO75
+ *     Must be AF0+OUT (WM leaves it to AF2+OUT), not LCD signal
+ *     GPIO106 works only when GPIO75 is high (DC-DC power enable?)
+ *     After LCD powerup, value is irrelevant
+ *   GPIO104
+ *     LCD VOFF (gate off voltage)
+ *   GPIO105
+ *     LCD VON (gate on voltage)
+ * FFUART (/dev/ttyS0) WM: 38400,8,n,1,crtscts (GSM data?)
+ * BTUART (/dev/ttyS1) WM: 115200,8,n,1,crtscts (GSM AT commands)
+ *   Use a HTC line discipline: 0x02 channel(==0x16) data 0x02
+ * EGPIO(CPLD) should be always present (controls "all" supply power)
+ *   For rootfs on MMC/SD: EGPIO module controls card power (in kernel)
+ * cpu-freq often freeze platform (errata?, use userspace gov)
+ * Do not use YUV420, (erratum E24) causes LCD hang (forever)
+ * Many GSM related pins are unknown
+ * gpio-rc-recv probably require lowpass filter (sw is OK)
+ * TODO EGPIO_MAGICIAN_IR_RECEIVE_SHUTDOWN
+ * FIXME AC charging blocks IrDA
+ * Unimplemented blocking of camera+power+reset, reset and door open reset
+ *   Registers: htc-pasic3.h (but blocks charging too)
+ * Other PXA machines have wait_for_sync for ADS7846 (during LCD refresh)
+ * pda-power has not optimal charging (accu can be bloated)
+ * TODO Current switching works? Is gpio-regulator/bq24022 required?
+ * pdata supports alternative drivers (mutually exclusive modules)
+ *   i2c-pxa vs i2c-gpio (SCCB)
+ *   pwm_bl vs gpio_backlight
+ *   pxa27x_udc vs phy-gpio-vbus-usb
+ *   physmap-flash vs pxa2xx-flash
+ *
  */
 
 #include <linux/kernel.h>
@@ -57,31 +97,31 @@ static unsigned long magician_pin_config[] __initdata = {
 	GPIO80_nCS_4,
 	GPIO33_nCS_5,
 
-	/* I2C */
+	/* I2C UDA1380 + OV9640 */
 	GPIO117_I2C_SCL,
 	GPIO118_I2C_SDA,
 
-	/* PWM 0 */
+	/* PWM 0 - LCD backlight */
 	GPIO16_PWM0_OUT,
 
-	/* I2S */
+	/* I2S UDA1380 capture */
 	GPIO28_I2S_BITCLK_OUT,
 	GPIO29_I2S_SDATA_IN,
 	GPIO31_I2S_SYNC,
 	GPIO113_I2S_SYSCLK,
 
-	/* SSP 1 */
+	/* SSP 1 UDA1380 playback */
 	GPIO23_SSP1_SCLK,
 	GPIO24_SSP1_SFRM,
 	GPIO25_SSP1_TXD,
 
-	/* SSP 2 */
+	/* SSP 2 TSC2046 touchscreen */
 	GPIO19_SSP2_SCLK,
 	GPIO14_SSP2_SFRM,
 	GPIO89_SSP2_TXD,
 	GPIO88_SSP2_RXD,
 
-	/* MMC */
+	/* MMC/SD/SDHC slot */
 	GPIO32_MMC_CLK,
 	GPIO92_MMC_DAT_0,
 	GPIO109_MMC_DAT_1,
@@ -92,7 +132,7 @@ static unsigned long magician_pin_config[] __initdata = {
 	/* LCD */
 	GPIOxx_LCD_TFT_16BPP,
 
-	/* QCI */
+	/* QCI camera interface */
 	GPIO12_CIF_DD_7,
 	GPIO17_CIF_DD_6,
 	GPIO50_CIF_DD_3,
@@ -120,11 +160,12 @@ static unsigned long magician_pin_config[] __initdata = {
 };
 
 /*
- * IRDA
+ * IrDA
  */
 
 static struct pxaficp_platform_data magician_ficp_info = {
 	.gpio_pwdown		= GPIO83_MAGICIAN_nIR_EN,
+	/* TODO test with FIR dongle */
 	.transceiver_cap	= IR_SIRMODE | IR_OFF,
 };
 
@@ -174,8 +215,8 @@ static struct platform_device gpio_keys = {
 
 /*
  * EGPIO (Xilinx CPLD)
- *
- * 7 32-bit aligned 8-bit registers: 3x output, 1x irq, 3x input
+ * 32-bit aligned
+ * 7x 8-bit registers: 3x output, 1x irq, 3x input
  */
 
 static struct resource egpio_resources[] = {
@@ -197,7 +238,11 @@ static struct htc_egpio_chip egpio_chips[] = {
 		.gpio_base = MAGICIAN_EGPIO(0, 0),
 		.num_gpios = 24,
 		.direction = HTC_EGPIO_OUTPUT,
-		.initial_values = 0x40, /* EGPIO_MAGICIAN_GSM_RESET */
+
+		/*
+		 * Depends on modules configuration
+		 */
+		.initial_values = 0x40,
 	},
 	[1] = {
 		.reg_start = 4,
@@ -228,7 +273,7 @@ static struct platform_device egpio = {
 };
 
 /*
- * LCD - Toppoly TD028STEB1 or Samsung LTP280QV
+ * PXAFB LCD - Toppoly TD028STEB1 or Samsung LTP280QV
  */
 
 static struct pxafb_mode_info toppoly_modes[] = {
@@ -265,10 +310,9 @@ static struct pxafb_mode_info samsung_modes[] = {
 
 static void toppoly_lcd_power(int on, struct fb_var_screeninfo *si)
 {
-	pr_debug("Toppoly LCD power\n");
+	pr_debug("Toppoly LCD power: %s\n", on ? "on" : "off");
 
 	if (on) {
-		pr_debug("on\n");
 		gpio_set_value(EGPIO_MAGICIAN_TOPPOLY_POWER, 1);
 		gpio_set_value(GPIO106_MAGICIAN_LCD_POWER_3, 1);
 		udelay(2000);
@@ -280,8 +324,7 @@ static void toppoly_lcd_power(int on, struct fb_var_screeninfo *si)
 		udelay(2000);
 		gpio_set_value(GPIO105_MAGICIAN_LCD_POWER_2, 1);
 	} else {
-		pr_debug("off\n");
-		msleep(15);
+		mdelay(15);
 		gpio_set_value(GPIO105_MAGICIAN_LCD_POWER_2, 0);
 		udelay(500);
 		gpio_set_value(GPIO104_MAGICIAN_LCD_POWER_1, 0);
@@ -293,10 +336,9 @@ static void toppoly_lcd_power(int on, struct fb_var_screeninfo *si)
 
 static void samsung_lcd_power(int on, struct fb_var_screeninfo *si)
 {
-	pr_debug("Samsung LCD power\n");
+	pr_debug("Samsung LCD power: %s\n", on ? "on" : "off");
 
 	if (on) {
-		pr_debug("on\n");
 		if (system_rev < 3)
 			gpio_set_value(GPIO75_MAGICIAN_SAMSUNG_POWER, 1);
 		else
@@ -309,7 +351,6 @@ static void samsung_lcd_power(int on, struct fb_var_screeninfo *si)
 		gpio_set_value(GPIO105_MAGICIAN_LCD_POWER_2, 1);
 		mdelay(10);
 	} else {
-		pr_debug("off\n");
 		mdelay(10);
 		gpio_set_value(GPIO105_MAGICIAN_LCD_POWER_2, 0);
 		mdelay(30);
@@ -346,8 +387,8 @@ static struct pxafb_mach_info samsung_info = {
  */
 
 static struct gpio magician_bl_gpios[] = {
-	{ EGPIO_MAGICIAN_BL_POWER,  GPIOF_DIR_OUT, "Backlight power" },
-	{ EGPIO_MAGICIAN_BL_POWER2, GPIOF_DIR_OUT, "Backlight power 2" },
+	{ EGPIO_MAGICIAN_BL_POWER, GPIOF_DIR_OUT, "Backlight power" },
+	{ EGPIO_MAGICIAN_BL_POWER2, GPIOF_DIR_OUT, "Extra backlight power" },
 };
 
 static int magician_backlight_init(struct device *dev)
@@ -357,6 +398,7 @@ static int magician_backlight_init(struct device *dev)
 
 static int magician_backlight_notify(struct device *dev, int brightness)
 {
+	pr_debug("Brightness = %i\n", brightness);
 	gpio_set_value(EGPIO_MAGICIAN_BL_POWER, brightness);
 	if (brightness >= 200) {
 		gpio_set_value(EGPIO_MAGICIAN_BL_POWER2, 1);
@@ -372,7 +414,13 @@ static void magician_backlight_exit(struct device *dev)
 	gpio_free_array(ARRAY_AND_SIZE(magician_bl_gpios));
 }
 
-static struct platform_pwm_backlight_data backlight_data = {
+/*
+ * LCD backlight by PWM (main)
+ * PWM frequency for MP1521 should be:
+ *   100-400 Hz = 2?.5*10^6 - 10?*10^6 ns
+ */
+
+static struct platform_pwm_backlight_data pwm_backlight_data = {
 	.pwm_id		= 0,
 	.max_brightness	= 272,
 	.dft_brightness	= 100,
@@ -383,12 +431,12 @@ static struct platform_pwm_backlight_data backlight_data = {
 	.exit		= magician_backlight_exit,
 };
 
-static struct platform_device backlight = {
+static struct platform_device pwm_backlight = {
 	.name	= "pwm-backlight",
 	.id	= -1,
 	.dev	= {
 		.parent		= &pxa27x_device_pwm0.dev,
-		.platform_data	= &backlight_data,
+		.platform_data	= &pwm_backlight_data,
 	},
 };
 
@@ -422,6 +470,10 @@ static struct platform_device leds_gpio = {
 	},
 };
 
+/*
+ * PASIC3 LEDs
+ */
+
 static struct pasic3_led pasic3_leds[] = {
 	{
 		.led = {
@@ -459,7 +511,7 @@ static struct pasic3_leds_machinfo pasic3_leds_info = {
 };
 
 /*
- * PASIC3 with DS1WM
+ * PASIC3 DS1WM
  */
 
 static struct resource pasic3_resources[] = {
@@ -477,8 +529,8 @@ static struct resource pasic3_resources[] = {
 };
 
 static struct pasic3_platform_data pasic3_platform_data = {
-	.led_pdata	= &pasic3_leds_info,
 	.clock_rate	= 4000000,
+	.led_pdata	= &pasic3_leds_info,
 };
 
 static struct platform_device pasic3 = {
@@ -517,7 +569,7 @@ static struct platform_device gpio_vbus = {
 };
 
 /*
- * External power
+ * Charging functions
  */
 
 static int power_supply_init(struct device *dev)
@@ -539,6 +591,10 @@ static char *magician_supplicants[] = {
 	"ds2760-battery.0", "backup-battery"
 };
 
+/*
+ * pda_power Li-ion charger
+ */
+
 static struct pda_power_pdata power_supply_info = {
 	.init		= power_supply_init,
 	.is_ac_online	= magician_is_ac_online,
@@ -575,7 +631,7 @@ static struct platform_device power_supply = {
 };
 
 /*
- * Battery charger
+ * Charging current switch
  */
 
 static struct regulator_consumer_supply bq24022_consumers[] = {
@@ -695,7 +751,7 @@ static struct platform_device strataflash = {
 };
 
 /*
- * I2C
+ * PXA I2C normal controller (main)
  */
 
 static struct i2c_pxa_platform_data i2c_info = {
@@ -709,7 +765,7 @@ static struct i2c_pxa_platform_data i2c_info = {
 static struct platform_device *devices[] __initdata = {
 	&gpio_keys,
 	&egpio,
-	&backlight,
+	&pwm_backlight,
 	&pasic3,
 	&bq24022,
 	&gpio_vbus,
@@ -734,9 +790,10 @@ static void __init magician_init(void)
 	int err;
 
 	pxa2xx_mfp_config(ARRAY_AND_SIZE(magician_pin_config));
+
 	err = gpio_request_array(ARRAY_AND_SIZE(magician_global_gpios));
 	if (err)
-		pr_err("magician: Failed to request GPIOs: %d\n", err);
+		pr_err("magician: Failed to request global GPIOs: %d\n", err);
 
 	pxa_set_ffuart_info(NULL);
 	pxa_set_btuart_info(NULL);
@@ -761,7 +818,7 @@ static void __init magician_init(void)
 		pr_info("LCD type: %s\n", lcd_select ? "Samsung" : "Toppoly");
 		if (lcd_select && (system_rev < 3))
 			gpio_request_one(GPIO75_MAGICIAN_SAMSUNG_POWER,
-				GPIOF_OUT_INIT_LOW, "SAMSUNG_POWER");
+				GPIOF_OUT_INIT_LOW, "Samsung LCD Power");
 		pxa_set_fb_info(NULL,
 			lcd_select ? &samsung_info : &toppoly_info);
 	} else
-- 
1.7.12.1



From petr.cvek at tul.cz  Mon Aug 17 14:58:01 2015
From: petr.cvek at tul.cz (Petr Cvek)
Date: Mon, 17 Aug 2015 23:58:01 +0200
Subject: [PATCH v2 04/21] ARM: pxa: magician: Add, fix and init (new) GPIOs
In-Reply-To: <cover.1439843482.git.petr.cvek@tul.cz>
References: <cover.1439843482.git.petr.cvek@tul.cz>
Message-ID: <55D258E9.9010303@tul.cz>

Add new GPIOs, fix some GPIO names and initialization (EGPIO, LCD power on
sequence).

Signed-off-by: Petr Cvek <petr.cvek at tul.cz>
---
 arch/arm/mach-pxa/include/mach/magician.h |  39 ++++---
 arch/arm/mach-pxa/magician.c              | 166 +++++++++++++++++++++++-------
 2 files changed, 153 insertions(+), 52 deletions(-)

diff --git a/arch/arm/mach-pxa/include/mach/magician.h b/arch/arm/mach-pxa/include/mach/magician.h
index ba6a6e1..d19e504 100644
--- a/arch/arm/mach-pxa/include/mach/magician.h
+++ b/arch/arm/mach-pxa/include/mach/magician.h
@@ -21,10 +21,10 @@
 
 #define GPIO0_MAGICIAN_KEY_POWER		0
 #define GPIO9_MAGICIAN_UNKNOWN			9
-#define GPIO10_MAGICIAN_GSM_IRQ			10
+#define GPIO10_MAGICIAN_GSM_IRQ		10
 #define GPIO11_MAGICIAN_GSM_OUT1		11
 #define GPIO13_MAGICIAN_CPLD_IRQ		13
-#define GPIO18_MAGICIAN_UNKNOWN			18
+#define GPIO18_MAGICIAN_UNKNOWN		18
 #define GPIO22_MAGICIAN_VIBRA_EN		22
 #define GPIO26_MAGICIAN_GSM_POWER		26
 #define GPIO27_MAGICIAN_USBC_PUEN		27
@@ -32,8 +32,10 @@
 #define GPIO37_MAGICIAN_KEY_HANGUP		37
 #define GPIO38_MAGICIAN_KEY_CONTACTS		38
 #define GPIO40_MAGICIAN_GSM_OUT2		40
-#define GPIO48_MAGICIAN_UNKNOWN			48
-#define GPIO56_MAGICIAN_UNKNOWN			56
+#define GPIO46_MAGICIAN_IR_RX			46
+#define GPIO47_MAGICIAN_IR_TX			47
+#define GPIO48_MAGICIAN_UNKNOWN		48
+#define GPIO56_MAGICIAN_UNKNOWN		56
 #define GPIO57_MAGICIAN_CAM_RESET		57
 #define GPIO75_MAGICIAN_SAMSUNG_POWER		75
 #define GPIO83_MAGICIAN_nIR_EN			83
@@ -51,15 +53,17 @@
 #define GPIO100_MAGICIAN_KEY_VOL_UP		100
 #define GPIO101_MAGICIAN_KEY_VOL_DOWN 		101
 #define GPIO102_MAGICIAN_KEY_PHONE		102
-#define GPIO103_MAGICIAN_LED_KP			103
-#define GPIO104_MAGICIAN_LCD_POWER_1 		104
-#define GPIO105_MAGICIAN_LCD_POWER_2		105
-#define GPIO106_MAGICIAN_LCD_POWER_3		106
+#define GPIO103_MAGICIAN_LED_KP		103
+#define GPIO104_MAGICIAN_LCD_VOFF_EN		104
+#define GPIO105_MAGICIAN_LCD_VON_EN		105
+#define GPIO106_MAGICIAN_LCD_DCDC_NRESET	106
 #define GPIO107_MAGICIAN_DS1WM_IRQ		107
 #define GPIO108_MAGICIAN_GSM_READY		108
 #define GPIO114_MAGICIAN_UNKNOWN		114
 #define GPIO115_MAGICIAN_nPEN_IRQ		115
 #define GPIO116_MAGICIAN_nCAM_EN		116
+#define GPIO117_MAGICIAN_I2C_SCL		117
+#define GPIO118_MAGICIAN_I2C_SDA		118
 #define GPIO119_MAGICIAN_UNKNOWN		119
 #define GPIO120_MAGICIAN_UNKNOWN		120
 
@@ -78,7 +82,7 @@
  * CPLD EGPIOs
  */
 
-#define MAGICIAN_EGPIO_BASE			PXA_NR_BUILTIN_GPIO
+#define MAGICIAN_EGPIO_BASE	PXA_NR_BUILTIN_GPIO
 #define MAGICIAN_EGPIO(reg,bit) \
 	(MAGICIAN_EGPIO_BASE + 8*reg + bit)
 
@@ -89,25 +93,28 @@
 #define EGPIO_MAGICIAN_GSM_RESET		MAGICIAN_EGPIO(0, 6)
 #define EGPIO_MAGICIAN_LCD_POWER		MAGICIAN_EGPIO(0, 7)
 #define EGPIO_MAGICIAN_SPK_POWER		MAGICIAN_EGPIO(1, 0)
-#define EGPIO_MAGICIAN_EP_POWER			MAGICIAN_EGPIO(1, 1)
+#define EGPIO_MAGICIAN_EP_POWER		MAGICIAN_EGPIO(1, 1)
 #define EGPIO_MAGICIAN_IN_SEL0			MAGICIAN_EGPIO(1, 2)
 #define EGPIO_MAGICIAN_IN_SEL1			MAGICIAN_EGPIO(1, 3)
 #define EGPIO_MAGICIAN_MIC_POWER		MAGICIAN_EGPIO(1, 4)
 #define EGPIO_MAGICIAN_CODEC_RESET		MAGICIAN_EGPIO(1, 5)
 #define EGPIO_MAGICIAN_CODEC_POWER		MAGICIAN_EGPIO(1, 6)
-#define EGPIO_MAGICIAN_BL_POWER			MAGICIAN_EGPIO(1, 7)
-#define EGPIO_MAGICIAN_SD_POWER			MAGICIAN_EGPIO(2, 0)
+#define EGPIO_MAGICIAN_BL_POWER		MAGICIAN_EGPIO(1, 7)
+#define EGPIO_MAGICIAN_SD_POWER		MAGICIAN_EGPIO(2, 0)
 #define EGPIO_MAGICIAN_CARKIT_MIC		MAGICIAN_EGPIO(2, 1)
-#define EGPIO_MAGICIAN_UNKNOWN_WAVEDEV_DLL	MAGICIAN_EGPIO(2, 2)
+#define EGPIO_MAGICIAN_IR_RECEIVE_SHUTDOWN	MAGICIAN_EGPIO(2, 2)
 #define EGPIO_MAGICIAN_FLASH_VPP		MAGICIAN_EGPIO(2, 3)
 #define EGPIO_MAGICIAN_BL_POWER2		MAGICIAN_EGPIO(2, 4)
 #define EGPIO_MAGICIAN_BQ24022_ISET2		MAGICIAN_EGPIO(2, 5)
+#define EGPIO_MAGICIAN_NICD_CHARGE		MAGICIAN_EGPIO(2, 6)
 #define EGPIO_MAGICIAN_GSM_POWER		MAGICIAN_EGPIO(2, 7)
 
 /* input */
 
-#define EGPIO_MAGICIAN_CABLE_STATE_AC		MAGICIAN_EGPIO(4, 0)
-#define EGPIO_MAGICIAN_CABLE_STATE_USB		MAGICIAN_EGPIO(4, 1)
+/* AC=1, USB=0 */
+#define EGPIO_MAGICIAN_CABLE_TYPE		MAGICIAN_EGPIO(4, 0)
+/* =1 when AC or USB cable inserted */
+#define EGPIO_MAGICIAN_CABLE_INSERT1		MAGICIAN_EGPIO(4, 1)
 
 #define EGPIO_MAGICIAN_BOARD_ID0		MAGICIAN_EGPIO(5, 0)
 #define EGPIO_MAGICIAN_BOARD_ID1		MAGICIAN_EGPIO(5, 1)
@@ -116,5 +123,7 @@
 #define EGPIO_MAGICIAN_nSD_READONLY		MAGICIAN_EGPIO(5, 4)
 
 #define EGPIO_MAGICIAN_EP_INSERT		MAGICIAN_EGPIO(6, 1)
+/* FIXME behave like 4,1, may differ for host/device */
+#define EGPIO_MAGICIAN_CABLE_INSERT2		MAGICIAN_EGPIO(6, 4)
 
 #endif /* _MAGICIAN_H_ */
diff --git a/arch/arm/mach-pxa/magician.c b/arch/arm/mach-pxa/magician.c
index 57da133..bc206f8 100644
--- a/arch/arm/mach-pxa/magician.c
+++ b/arch/arm/mach-pxa/magician.c
@@ -4,8 +4,9 @@
  * and T-Mobile MDA Compact.
  *
  * Copyright (c) 2006-2007 Philipp Zabel
+ * Copyright (c) 2014-2015 Petr Cvek (massive rework)
  *
- * Based on hx4700.c, spitz.c and others.
+ * Based on hx4700.c, spitz.c, board-overo.c and others.
  *
  * 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
@@ -96,13 +97,24 @@ static unsigned long magician_pin_config[] __initdata = {
 	GPIO79_nCS_3,	/* EGPIO CPLD */
 	GPIO80_nCS_4,
 	GPIO33_nCS_5,
+	GPIO49_nPWE,
+	GPIO18_RDY,
 
 	/* I2C UDA1380 + OV9640 */
 	GPIO117_I2C_SCL,
 	GPIO118_I2C_SDA,
 
+	/* Omnivision camera power and reset GPIO */
+	MFP_CFG_OUT(GPIO116, AF0, DRIVE_HIGH),	/* nEnable, active in low */
+	MFP_CFG_OUT(GPIO57, AF0, DRIVE_HIGH),	/* Reset, active in high */
+
+#if IS_ENABLED(CONFIG_PWM_PXA)
 	/* PWM 0 - LCD backlight */
 	GPIO16_PWM0_OUT,
+#else
+	/* Ensure static backlight without any driver */
+	MFP_CFG_OUT(GPIO16, AF0, DRIVE_LOW),	/* Backlight enabled */
+#endif
 
 	/* I2S UDA1380 capture */
 	GPIO28_I2S_BITCLK_OUT,
@@ -129,8 +141,26 @@ static unsigned long magician_pin_config[] __initdata = {
 	GPIO111_MMC_DAT_3,
 	GPIO112_MMC_CMD,
 
-	/* LCD */
-	GPIOxx_LCD_TFT_16BPP,
+	/*
+	 * LCD
+	 * NOTICE Samsung LTP280QV:
+	 *   cannot use GPIOxx_LCD_TFT_16BPP, GPIO75 is LCD power,
+	 * 74 unused (AF0 by bootloader?)
+	 */
+	GPIOxx_LCD_16BPP,
+	GPIO76_LCD_PCLK,
+	GPIO77_LCD_BIAS,	/* data_valid (v/hsync) (ADS7846 sync?) */
+
+	/* NOTICE valid LCD init sequence */
+
+	/* for GPIO75_MAGICIAN_SAMSUNG_POWER */
+	MFP_CFG_OUT(GPIO75, AF0, DRIVE_HIGH),
+	/* for GPIO106_MAGICIAN_LCD_DCDC_NRESET */
+	MFP_CFG_OUT(GPIO106, AF0, DRIVE_HIGH),
+	/* for GPIO104_MAGICIAN_LCD_VOFF_EN */
+	MFP_CFG_OUT(GPIO104, AF0, DRIVE_HIGH),
+	/* for GPIO105_MAGICIAN_LCD_VON_EN */
+	MFP_CFG_OUT(GPIO105, AF0, DRIVE_HIGH),
 
 	/* QCI camera interface */
 	GPIO12_CIF_DD_7,
@@ -147,16 +177,69 @@ static unsigned long magician_pin_config[] __initdata = {
 	GPIO85_CIF_LV,
 
 	/* Magician specific input GPIOs */
-	GPIO9_GPIO,		/* unknown */
 	GPIO10_GPIO,	/* GSM_IRQ */
 	GPIO13_GPIO,	/* CPLD_IRQ */
 	GPIO107_GPIO,	/* DS1WM_IRQ */
 	GPIO108_GPIO,	/* GSM_READY */
 	GPIO115_GPIO,	/* nPEN_IRQ */
 
-	/* I2C */
-	GPIO117_I2C_SCL,
-	GPIO118_I2C_SDA,
+	/* FIXME: probably IrDA transmitter disable */
+	MFP_CFG_OUT(GPIO83, AF0, DRIVE_HIGH),
+
+	/* Vibration motor */
+	MFP_CFG_OUT(GPIO22, AF0, DRIVE_LOW),
+
+	/* Keypad LEDs (red/green phone) */
+	MFP_CFG_OUT(GPIO103, AF0, DRIVE_LOW),
+
+	/* GSM pins */
+	MFP_CFG_OUT(GPIO11, AF0, DRIVE_LOW), /* CPU is unavailable(?) */
+	MFP_CFG_OUT(GPIO26, AF0, DRIVE_LOW), /* GSM power, active high */
+	MFP_CFG_OUT(GPIO86, AF0, DRIVE_HIGH), /* GSM reset, active high */
+
+	/* USB connector */
+	MFP_CFG_OUT(GPIO27, AF0, DRIVE_LOW), /* usbc pull-up enable */
+	MFP_CFG_OUT(GPIO30, AF0, DRIVE_LOW), /* charging enable, active low */
+
+	/* FFUART, FIXME never observed to do something, GSM data? */
+	GPIO34_FFUART_RXD,
+	GPIO35_FFUART_CTS,
+	GPIO36_FFUART_DCD,
+	GPIO39_FFUART_TXD,
+	GPIO41_FFUART_RTS,
+
+	/* BTUART, AT commands/data, HTC port line discipline */
+	GPIO42_BTUART_RXD,
+	GPIO43_BTUART_TXD,
+	GPIO44_BTUART_CTS,
+	GPIO45_BTUART_RTS,
+
+	/* Power I2C, enabled controller will overrule GPIO */
+	GPIO3_GPIO,	/* SCL */
+	GPIO4_GPIO,	/* SDA */
+
+	/* IrDA GPIOs, if pxaficp, it will change AF accordingly to mode */
+	MFP_CFG_IN(GPIO46, AF0),
+	MFP_CFG_OUT(GPIO47, AF0, DRIVE_LOW),
+	MFP_CFG_OUT(GPIO83, AF0, DRIVE_HIGH),
+
+	/* TODO unknown */
+	GPIO9_GPIO,		/* unknown */
+	MFP_CFG_OUT(GPIO40, AF0, DRIVE_LOW),	/* FIXME GSM? */
+	MFP_CFG_OUT(GPIO87, AF0, DRIVE_LOW),	/* FIXME GSM? */
+
+	/* Left GPIOs (undefined here):
+	 * 18, 49 : bootloader=VLIO?, WinM=TODO
+	 * 48 : AF0/out0
+	 * 56 : AF0/out0
+	 * 74 : bootloader=AF0/output
+	 * 86 : bootloader=AF0/input (but should be gsm reset???)
+	 * 114 : AF0/out0
+	 * 119 : AF0/out0
+	 * 120 : AF0/out
+	 * 1 : dedicated reset, AF0/output
+	 * 13 : cpld irq, output (??)
+	 */
 };
 
 /*
@@ -241,8 +324,9 @@ static struct htc_egpio_chip egpio_chips[] = {
 
 		/*
 		 * Depends on modules configuration
+		 * Things like MMC and LCD should be enabled
 		 */
-		.initial_values = 0x40,
+		.initial_values = 0x21a0c0,
 	},
 	[1] = {
 		.reg_start = 4,
@@ -314,22 +398,22 @@ static void toppoly_lcd_power(int on, struct fb_var_screeninfo *si)
 
 	if (on) {
 		gpio_set_value(EGPIO_MAGICIAN_TOPPOLY_POWER, 1);
-		gpio_set_value(GPIO106_MAGICIAN_LCD_POWER_3, 1);
+		gpio_set_value(GPIO106_MAGICIAN_LCD_DCDC_NRESET, 1);
 		udelay(2000);
 		gpio_set_value(EGPIO_MAGICIAN_LCD_POWER, 1);
 		udelay(2000);
 		/* FIXME: enable LCDC here */
 		udelay(2000);
-		gpio_set_value(GPIO104_MAGICIAN_LCD_POWER_1, 1);
+		gpio_set_value(GPIO104_MAGICIAN_LCD_VOFF_EN, 1);
 		udelay(2000);
-		gpio_set_value(GPIO105_MAGICIAN_LCD_POWER_2, 1);
+		gpio_set_value(GPIO105_MAGICIAN_LCD_VON_EN, 1);
 	} else {
 		mdelay(15);
-		gpio_set_value(GPIO105_MAGICIAN_LCD_POWER_2, 0);
+		gpio_set_value(GPIO105_MAGICIAN_LCD_VON_EN, 0);
 		udelay(500);
-		gpio_set_value(GPIO104_MAGICIAN_LCD_POWER_1, 0);
+		gpio_set_value(GPIO104_MAGICIAN_LCD_VOFF_EN, 0);
 		udelay(1000);
-		gpio_set_value(GPIO106_MAGICIAN_LCD_POWER_3, 0);
+		gpio_set_value(GPIO106_MAGICIAN_LCD_DCDC_NRESET, 0);
 		gpio_set_value(EGPIO_MAGICIAN_LCD_POWER, 0);
 	}
 }
@@ -343,21 +427,19 @@ static void samsung_lcd_power(int on, struct fb_var_screeninfo *si)
 			gpio_set_value(GPIO75_MAGICIAN_SAMSUNG_POWER, 1);
 		else
 			gpio_set_value(EGPIO_MAGICIAN_LCD_POWER, 1);
-		mdelay(10);
-		gpio_set_value(GPIO106_MAGICIAN_LCD_POWER_3, 1);
-		mdelay(10);
-		gpio_set_value(GPIO104_MAGICIAN_LCD_POWER_1, 1);
-		mdelay(30);
-		gpio_set_value(GPIO105_MAGICIAN_LCD_POWER_2, 1);
-		mdelay(10);
+		mdelay(6);
+		gpio_set_value(GPIO106_MAGICIAN_LCD_DCDC_NRESET, 1);
+		mdelay(6);	/* Avdd -> Voff >5ms */
+		gpio_set_value(GPIO104_MAGICIAN_LCD_VOFF_EN, 1);
+		mdelay(16);	/* Voff -> Von >(5+10)ms */
+		gpio_set_value(GPIO105_MAGICIAN_LCD_VON_EN, 1);
 	} else {
-		mdelay(10);
-		gpio_set_value(GPIO105_MAGICIAN_LCD_POWER_2, 0);
-		mdelay(30);
-		gpio_set_value(GPIO104_MAGICIAN_LCD_POWER_1, 0);
-		mdelay(10);
-		gpio_set_value(GPIO106_MAGICIAN_LCD_POWER_3, 0);
-		mdelay(10);
+		gpio_set_value(GPIO105_MAGICIAN_LCD_VON_EN, 0);
+		mdelay(16);
+		gpio_set_value(GPIO104_MAGICIAN_LCD_VOFF_EN, 0);
+		mdelay(6);
+		gpio_set_value(GPIO106_MAGICIAN_LCD_DCDC_NRESET, 0);
+		mdelay(6);
 		if (system_rev < 3)
 			gpio_set_value(GPIO75_MAGICIAN_SAMSUNG_POWER, 0);
 		else
@@ -555,7 +637,7 @@ static struct resource gpio_vbus_resource = {
 
 static struct gpio_vbus_mach_info gpio_vbus_info = {
 	.gpio_pullup = GPIO27_MAGICIAN_USBC_PUEN,
-	.gpio_vbus = EGPIO_MAGICIAN_CABLE_STATE_USB,
+	.gpio_vbus = EGPIO_MAGICIAN_CABLE_INSERT1,
 };
 
 static struct platform_device gpio_vbus = {
@@ -574,17 +656,17 @@ static struct platform_device gpio_vbus = {
 
 static int power_supply_init(struct device *dev)
 {
-	return gpio_request(EGPIO_MAGICIAN_CABLE_STATE_AC, "CABLE_STATE_AC");
+	return gpio_request(EGPIO_MAGICIAN_CABLE_TYPE, "CABLE_STATE_AC");
 }
 
 static int magician_is_ac_online(void)
 {
-	return gpio_get_value(EGPIO_MAGICIAN_CABLE_STATE_AC);
+	return gpio_get_value(EGPIO_MAGICIAN_CABLE_INSERT1);
 }
 
 static void power_supply_exit(struct device *dev)
 {
-	gpio_free(EGPIO_MAGICIAN_CABLE_STATE_AC);
+	gpio_free(EGPIO_MAGICIAN_CABLE_TYPE);
 }
 
 static char *magician_supplicants[] = {
@@ -774,12 +856,21 @@ static struct platform_device *devices[] __initdata = {
 	&leds_gpio,
 };
 
+/*
+ * Global GPIOs
+ */
+
 static struct gpio magician_global_gpios[] = {
-	{ GPIO13_MAGICIAN_CPLD_IRQ, GPIOF_IN,		"CPLD_IRQ" },
-	{ GPIO107_MAGICIAN_DS1WM_IRQ, GPIOF_IN,	"DS1WM_IRQ" },
-	{ GPIO104_MAGICIAN_LCD_POWER_1, GPIOF_OUT_INIT_LOW, "LCD power 1" },
-	{ GPIO105_MAGICIAN_LCD_POWER_2, GPIOF_OUT_INIT_LOW, "LCD power 2" },
-	{ GPIO106_MAGICIAN_LCD_POWER_3, GPIOF_OUT_INIT_LOW, "LCD power 3" },
+	{ GPIO13_MAGICIAN_CPLD_IRQ, GPIOF_IN, "CPLD_IRQ" },
+	{ GPIO107_MAGICIAN_DS1WM_IRQ, GPIOF_IN, "DS1WM_IRQ" },
+
+	/* NOTICE valid LCD init sequence */
+	{ GPIO106_MAGICIAN_LCD_DCDC_NRESET, GPIOF_OUT_INIT_HIGH,
+		"LCD DCDC nreset" },
+	{ GPIO104_MAGICIAN_LCD_VOFF_EN, GPIOF_OUT_INIT_HIGH,
+		"LCD VOFF enable" },
+	{ GPIO105_MAGICIAN_LCD_VON_EN, GPIOF_OUT_INIT_HIGH,
+		"LCD VON enable" },
 	{ GPIO83_MAGICIAN_nIR_EN, GPIOF_OUT_INIT_HIGH,	"nIR_EN" },
 };
 
@@ -817,6 +908,7 @@ static void __init magician_init(void)
 		lcd_select = board_id & 0x8;
 		pr_info("LCD type: %s\n", lcd_select ? "Samsung" : "Toppoly");
 		if (lcd_select && (system_rev < 3))
+			/* NOTICE valid LCD init sequence */
 			gpio_request_one(GPIO75_MAGICIAN_SAMSUNG_POWER,
 				GPIOF_OUT_INIT_LOW, "Samsung LCD Power");
 		pxa_set_fb_info(NULL,
-- 
1.7.12.1



From petr.cvek at tul.cz  Mon Aug 17 14:58:55 2015
From: petr.cvek at tul.cz (Petr Cvek)
Date: Mon, 17 Aug 2015 23:58:55 +0200
Subject: [PATCH v2 05/21] ARM: pxa: magician: Add support for ADS7846
 touchscreen
In-Reply-To: <cover.1439843482.git.petr.cvek@tul.cz>
References: <cover.1439843482.git.petr.cvek@tul.cz>
Message-ID: <55D2591F.10509@tul.cz>

Add support for ADS7846 touchscreen.

Signed-off-by: Petr Cvek <petr.cvek at tul.cz>
---
 arch/arm/mach-pxa/magician.c | 86 ++++++++++++++++++++++++++++++++++++++++++++
 1 file changed, 86 insertions(+)

diff --git a/arch/arm/mach-pxa/magician.c b/arch/arm/mach-pxa/magician.c
index bc206f8..fc1c035 100644
--- a/arch/arm/mach-pxa/magician.c
+++ b/arch/arm/mach-pxa/magician.c
@@ -68,6 +68,7 @@
 #include <linux/pwm_backlight.h>
 #include <linux/regulator/driver.h>
 #include <linux/regulator/gpio-regulator.h>
+#include <linux/regulator/fixed.h>
 #include <linux/regulator/machine.h>
 #include <linux/usb/gpio_vbus.h>
 #include <linux/i2c/pxa-i2c.h>
@@ -84,6 +85,10 @@
 #include <linux/platform_data/irda-pxaficp.h>
 #include <linux/platform_data/usb-ohci-pxa27x.h>
 
+#include <linux/spi/spi.h>
+#include <linux/spi/pxa2xx_spi.h>
+#include <linux/spi/ads7846.h>
+
 #include "devices.h"
 #include "generic.h"
 
@@ -766,6 +771,37 @@ static struct platform_device bq24022 = {
 };
 
 /*
+ * fixed regulator for ads7846
+ */
+
+static struct regulator_consumer_supply ads7846_supply =
+	REGULATOR_SUPPLY("vcc", "spi2.0");
+
+static struct regulator_init_data vads7846_regulator = {
+	.constraints = {
+		.valid_ops_mask	= REGULATOR_CHANGE_STATUS,
+	},
+	.num_consumer_supplies = 1,
+	.consumer_supplies = &ads7846_supply,
+};
+
+static struct fixed_voltage_config vads7846 = {
+	.supply_name = "vads7846",
+	.microvolts = 3300000, /* probably */
+	.gpio = -EINVAL,
+	.startup_delay = 0,
+	.init_data = &vads7846_regulator,
+};
+
+static struct platform_device vads7846_device = {
+	.name = "reg-fixed-voltage",
+	.id = 1,
+	.dev = {
+		.platform_data = &vads7846,
+	},
+};
+
+/*
  * MMC/SD
  */
 
@@ -841,6 +877,51 @@ static struct i2c_pxa_platform_data i2c_info = {
 };
 
 /*
+ * Touchscreen
+ */
+
+static struct ads7846_platform_data ads7846_pdata = {
+	.model		= 7846,
+	.x_min		= 0,
+	.y_min		= 0,
+	.x_max		= 4096,
+	.y_max		= 4096,
+	.x_plate_ohms	= 320,	/* measured */
+	.y_plate_ohms	= 500,
+	.pressure_max	= 255,	/* up to 12bit sampling */
+	.debounce_max	= 10,
+	.debounce_tol	= 3,
+	.debounce_rep	= 1,
+	.gpio_pendown	= GPIO115_MAGICIAN_nPEN_IRQ,
+	.keep_vref_on	= 1,	/* FIXME, external Vref? */
+	.vref_delay_usecs = 100,
+	/* .wait_for_sync, GPIO77_LCD_BIAS low noise measure, latency! */
+};
+
+struct pxa2xx_spi_chip tsc2046_chip_info = {
+	.tx_threshold = 1,
+	.rx_threshold = 2,
+	.timeout = 64,
+	.gpio_cs = -1,
+};
+
+static struct pxa2xx_spi_master magician_spi_info = {
+	.num_chipselect = 1,
+/*	.enable_dma = 1, */ /* FIXME probably unnecessary */
+};
+
+static struct spi_board_info ads7846_spi_board_info[] __initdata = {
+	{
+		.modalias		= "ads7846",
+		.bus_num		= 2,
+		.max_speed_hz		= 1857143,
+		.platform_data		= &ads7846_pdata,
+		.controller_data	= &tsc2046_chip_info,
+		.irq = PXA_GPIO_TO_IRQ(GPIO115_MAGICIAN_nPEN_IRQ),
+	},
+};
+
+/*
  * Platform devices
  */
 
@@ -849,6 +930,7 @@ static struct platform_device *devices[] __initdata = {
 	&egpio,
 	&pwm_backlight,
 	&pasic3,
+	&vads7846_device,
 	&bq24022,
 	&gpio_vbus,
 	&power_supply,
@@ -915,6 +997,10 @@ static void __init magician_init(void)
 			lcd_select ? &samsung_info : &toppoly_info);
 	} else
 		pr_err("LCD detection: CPLD mapping failed\n");
+
+	pxa2xx_set_spi_info(2, &magician_spi_info);
+	spi_register_board_info(ARRAY_AND_SIZE(ads7846_spi_board_info));
+
 }
 
 MACHINE_START(MAGICIAN, "HTC Magician")
-- 
1.7.12.1



From petr.cvek at tul.cz  Mon Aug 17 14:59:22 2015
From: petr.cvek at tul.cz (Petr Cvek)
Date: Mon, 17 Aug 2015 23:59:22 +0200
Subject: [PATCH v2 06/21] ARM: pxa: magician: Add normal and power I2C
 definition
In-Reply-To: <cover.1439843482.git.petr.cvek@tul.cz>
References: <cover.1439843482.git.petr.cvek@tul.cz>
Message-ID: <55D2593A.5060400@tul.cz>

Add normal and power I2C definition to HTC Magician.

Signed-off-by: Petr Cvek <petr.cvek at tul.cz>
---
 arch/arm/mach-pxa/magician.c | 38 ++++++++++++++++++++++++++++++++++++--
 1 file changed, 36 insertions(+), 2 deletions(-)

diff --git a/arch/arm/mach-pxa/magician.c b/arch/arm/mach-pxa/magician.c
index fc1c035..702e8e0 100644
--- a/arch/arm/mach-pxa/magician.c
+++ b/arch/arm/mach-pxa/magician.c
@@ -72,6 +72,8 @@
 #include <linux/regulator/machine.h>
 #include <linux/usb/gpio_vbus.h>
 #include <linux/i2c/pxa-i2c.h>
+#include <linux/i2c-gpio.h>
+#include <linux/i2c.h>
 
 #include <mach/hardware.h>
 #include <asm/mach-types.h>
@@ -873,10 +875,39 @@ static struct platform_device strataflash = {
  */
 
 static struct i2c_pxa_platform_data i2c_info = {
-	.fast_mode = 1,
+	.fast_mode = 0,	/* fast mode seems to be have bit errors */
+	.use_pio = 0, /* no polling */
 };
 
 /*
+ * PXA I2C power controller
+ */
+
+static struct i2c_pxa_platform_data magician_i2c_power_info = {
+	.fast_mode = 0,
+	.use_pio = 0,
+};
+
+/*
+ * GPIO I2C normal controller (alternative)
+ */
+
+static struct i2c_gpio_platform_data rtc_device_data = {
+	.sda_pin = GPIO118_MAGICIAN_I2C_SDA,
+	.scl_pin = GPIO117_MAGICIAN_I2C_SCL,
+	.udelay = 100
+};
+
+static struct platform_device i2c_gpio_bus_alt = {
+	.name = "i2c-gpio",
+	.id = 0,
+	.dev = {
+		.platform_data = &rtc_device_data,
+	}
+};
+
+
+/*
  * Touchscreen
  */
 
@@ -936,6 +967,9 @@ static struct platform_device *devices[] __initdata = {
 	&power_supply,
 	&strataflash,
 	&leds_gpio,
+
+	/* NOTICE mutually exclusive with PXA I2C */
+	&i2c_gpio_bus_alt,
 };
 
 /*
@@ -975,7 +1009,7 @@ static void __init magician_init(void)
 	platform_add_devices(ARRAY_AND_SIZE(devices));
 
 	pxa_set_ficp_info(&magician_ficp_info);
-	pxa27x_set_i2c_power_info(NULL);
+	pxa27x_set_i2c_power_info(&magician_i2c_power_info);
 	pxa_set_i2c_info(&i2c_info);
 	pxa_set_mci_info(&magician_mci_info);
 	pxa_set_ohci_info(&magician_ohci_info);
-- 
1.7.12.1



From petr.cvek at tul.cz  Mon Aug 17 15:00:40 2015
From: petr.cvek at tul.cz (Petr Cvek)
Date: Tue, 18 Aug 2015 00:00:40 +0200
Subject: [PATCH v2 08/21] ARM: pxa: magician: Add StrataFlash Vpp GPIO and
 alternative driver
In-Reply-To: <cover.1439843482.git.petr.cvek@tul.cz>
References: <cover.1439843482.git.petr.cvek@tul.cz>
Message-ID: <55D25988.1090109@tul.cz>

Add StrataFlash Vpp GPIO and alternative driver.

Signed-off-by: Petr Cvek <petr.cvek at tul.cz>
---
 arch/arm/mach-pxa/magician.c | 76 ++++++++++++++++++++++++++++++++++++++++++--
 1 file changed, 73 insertions(+), 3 deletions(-)

diff --git a/arch/arm/mach-pxa/magician.c b/arch/arm/mach-pxa/magician.c
index 7519238..7331b34 100644
--- a/arch/arm/mach-pxa/magician.c
+++ b/arch/arm/mach-pxa/magician.c
@@ -845,20 +845,66 @@ static struct pxaohci_platform_data magician_ohci_info = {
  * StrataFlash
  */
 
+static int magician_flash_init(struct platform_device *pdev)
+{
+	int ret = gpio_request(EGPIO_MAGICIAN_FLASH_VPP, "flash Vpp enable");
+
+	if (ret) {
+		pr_err("Cannot request flash enable GPIO (%i)\n", ret);
+		return ret;
+	}
+
+	ret = gpio_direction_output(EGPIO_MAGICIAN_FLASH_VPP, 1);
+	if (ret) {
+		pr_err("Cannot set direction for flash enable (%i)\n", ret);
+		gpio_free(EGPIO_MAGICIAN_FLASH_VPP);
+	}
+
+	return ret;
+}
+
 static void magician_set_vpp(struct platform_device *pdev, int vpp)
 {
 	gpio_set_value(EGPIO_MAGICIAN_FLASH_VPP, vpp);
 }
 
+static void magician_flash_exit(struct platform_device *pdev)
+{
+	gpio_free(EGPIO_MAGICIAN_FLASH_VPP);
+}
+
 static struct resource strataflash_resource = {
 	.start	= PXA_CS0_PHYS,
 	.end	= PXA_CS0_PHYS + SZ_64M - 1,
 	.flags	= IORESOURCE_MEM,
 };
 
+static struct mtd_partition magician_flash_parts[] = {
+	{
+		.name		= "Bootloader",
+		.offset		= 0x0,
+		.size		= 0x40000,
+		.mask_flags	= MTD_WRITEABLE,	/* EXPERIMENTAL */
+	},
+	{
+		.name	= "Linux Kernel",
+		.offset	= 0x40000,
+		.size	= MTDPART_SIZ_FULL,
+	},
+};
+
+#if 1	/* Choose which one fits you better */
+/*
+ * physmap-flash driver
+ */
+
 static struct physmap_flash_data strataflash_data = {
-	.width = 4,
-	.set_vpp = magician_set_vpp,
+	.width		= 4,
+	.init		= magician_flash_init,
+	.set_vpp	= magician_set_vpp,
+	.exit		= magician_flash_exit,
+	.parts		= magician_flash_parts,
+	.nr_parts	= ARRAY_SIZE(magician_flash_parts),
 };
 
 static struct platform_device strataflash = {
@@ -871,6 +917,30 @@ static struct platform_device strataflash = {
 	},
 };
 
+#else
+
+/*
+ * pxa2xx-flash driver
+ */
+
+static struct flash_platform_data magician_flash_data = {
+	.map_name	= "cfi_probe",
+	.parts		= magician_flash_parts,
+	.nr_parts	= ARRAY_SIZE(magician_flash_parts),
+	.width		= 4,
+};
+
+static struct platform_device strataflash = {
+	.name	= "pxa2xx-flash",
+	.id	= -1,
+	.dev = {
+		.platform_data = &magician_flash_data,
+	},
+	.resource = &strataflash_resource,
+	.num_resources = 1,
+};
+#endif
+
 /*
  * PXA I2C normal controller (main)
  */
@@ -960,13 +1030,13 @@ static struct spi_board_info ads7846_spi_board_info[] __initdata = {
 static struct platform_device *devices[] __initdata = {
 	&gpio_keys,
 	&egpio,
+	&strataflash,
 	&pwm_backlight,
 	&pasic3,
 	&vads7846_device,
 	&bq24022,
 	&gpio_vbus,
 	&power_supply,
-	&strataflash,
 	&leds_gpio,
 
 	/* NOTICE mutually exclusive with PXA I2C */
-- 
1.7.12.1



From petr.cvek at tul.cz  Mon Aug 17 15:01:05 2015
From: petr.cvek at tul.cz (Petr Cvek)
Date: Tue, 18 Aug 2015 00:01:05 +0200
Subject: [PATCH v2 09/21] ARM: pxa: magician: Add OV9640 camera support
In-Reply-To: <cover.1439843482.git.petr.cvek@tul.cz>
References: <cover.1439843482.git.petr.cvek@tul.cz>
Message-ID: <55D259A1.6090102@tul.cz>

Add OV9640 camera support for HTC Magician.

Signed-off-by: Petr Cvek <petr.cvek at tul.cz>
---
 arch/arm/mach-pxa/magician.c | 63 ++++++++++++++++++++++++++++++++++++++++++++
 1 file changed, 63 insertions(+)

diff --git a/arch/arm/mach-pxa/magician.c b/arch/arm/mach-pxa/magician.c
index 7331b34..63604e1 100644
--- a/arch/arm/mach-pxa/magician.c
+++ b/arch/arm/mach-pxa/magician.c
@@ -91,6 +91,9 @@
 #include <linux/spi/pxa2xx_spi.h>
 #include <linux/spi/ads7846.h>
 
+#include <linux/platform_data/camera-pxa.h>
+#include <media/soc_camera.h>
+
 #include "devices.h"
 #include "generic.h"
 
@@ -634,6 +637,60 @@ static struct platform_device pasic3 = {
 };
 
 /*
+ * SoC Camera
+ */
+
+static struct pxacamera_platform_data magician_pxacamera_pdata = {
+	.flags = PXA_CAMERA_MASTER | PXA_CAMERA_DATAWIDTH_8 |
+		PXA_CAMERA_PCLK_EN | PXA_CAMERA_MCLK_EN,
+	.mclk_10khz = 4800,
+};
+
+static int magician_camera_power(struct device *dev, int power)
+{
+	pr_debug("Camera power = %i\n", power);
+
+	gpio_set_value(GPIO116_MAGICIAN_nCAM_EN, !power);
+	mdelay(3);
+
+	return 0;
+}
+
+static int magician_camera_reset(struct device *dev)
+{
+	pr_debug("Camera reset\n");
+
+	gpio_set_value(GPIO57_MAGICIAN_CAM_RESET, 1);
+	mdelay(3);
+	gpio_set_value(GPIO57_MAGICIAN_CAM_RESET, 0);
+	mdelay(3);
+
+	return 0;
+}
+
+static struct i2c_board_info magician_camera_i2c_board_info = {
+	I2C_BOARD_INFO("ov9640", 0x30),
+	.flags = I2C_CLIENT_SCCB,
+};
+
+static struct soc_camera_link magician_camera_iclink = {
+	.bus_id		= 0,
+	.flags		= SOCAM_DATAWIDTH_8,
+	.i2c_adapter_id	= 0,
+	.board_info	= &magician_camera_i2c_board_info,
+	.power		= magician_camera_power,
+	.reset		= magician_camera_reset,
+};
+
+static struct platform_device magician_camera = {
+	.name = "soc-camera-pdrv",
+	.id = 0,
+	.dev = {
+		.platform_data = &magician_camera_iclink,
+	},
+};
+
+/*
  * USB "Transceiver"
  */
 
@@ -1038,6 +1095,7 @@ static struct platform_device *devices[] __initdata = {
 	&gpio_vbus,
 	&power_supply,
 	&leds_gpio,
+	&magician_camera,
 
 	/* NOTICE mutually exclusive with PXA I2C */
 	&i2c_gpio_bus_alt,
@@ -1058,6 +1116,10 @@ static struct gpio magician_global_gpios[] = {
 		"LCD VOFF enable" },
 	{ GPIO105_MAGICIAN_LCD_VON_EN, GPIOF_OUT_INIT_HIGH,
 		"LCD VON enable" },
+	{ GPIO57_MAGICIAN_CAM_RESET, GPIOF_OUT_INIT_HIGH,
+		"Camera reset" },
+	{ GPIO116_MAGICIAN_nCAM_EN, GPIOF_OUT_INIT_HIGH,
+		"Camera power" },
 };
 
 static void __init magician_init(void)
@@ -1105,6 +1167,7 @@ static void __init magician_init(void)
 	pxa2xx_set_spi_info(2, &magician_spi_info);
 	spi_register_board_info(ARRAY_AND_SIZE(ads7846_spi_board_info));
 
+	pxa_set_camera_info(&magician_pxacamera_pdata);
 }
 
 MACHINE_START(MAGICIAN, "HTC Magician")
-- 
1.7.12.1



From petr.cvek at tul.cz  Mon Aug 17 15:01:27 2015
From: petr.cvek at tul.cz (Petr Cvek)
Date: Tue, 18 Aug 2015 00:01:27 +0200
Subject: [PATCH v2 10/21] ARM: pxa: magician: Add UDA1380 sound support
In-Reply-To: <cover.1439843482.git.petr.cvek@tul.cz>
References: <cover.1439843482.git.petr.cvek@tul.cz>
Message-ID: <55D259B7.90703@tul.cz>

Add support for UDA1380 sound.

Signed-off-by: Petr Cvek <petr.cvek at tul.cz>
---
 arch/arm/mach-pxa/magician.c | 31 +++++++++++++++++++++++++++++++
 1 file changed, 31 insertions(+)

diff --git a/arch/arm/mach-pxa/magician.c b/arch/arm/mach-pxa/magician.c
index 63604e1..9decd86 100644
--- a/arch/arm/mach-pxa/magician.c
+++ b/arch/arm/mach-pxa/magician.c
@@ -94,6 +94,8 @@
 #include <linux/platform_data/camera-pxa.h>
 #include <media/soc_camera.h>
 
+#include <sound/uda1380.h>
+
 #include "devices.h"
 #include "generic.h"
 
@@ -887,6 +889,31 @@ static struct pxamci_platform_data magician_mci_info = {
 	.gpio_power	= EGPIO_MAGICIAN_SD_POWER,
 };
 
+/*
+ * AUDIO codec UDA1380
+ */
+
+static struct uda1380_platform_data uda1380_info = {
+	.gpio_power	= EGPIO_MAGICIAN_CODEC_POWER,
+	.gpio_reset	= EGPIO_MAGICIAN_CODEC_RESET,
+	.dac_clk	= UDA1380_DAC_CLK_WSPLL,
+};
+
+static struct i2c_board_info magician_audio_i2c_devices[] = {
+	{
+		I2C_BOARD_INFO("uda1380", 0x18),
+		.platform_data = &uda1380_info,
+	},
+};
+
+/*
+ * Magician Audio controller
+ */
+
+static struct platform_device magician_audio_device = {
+	.name = "magician-audio",
+	.id = -1,
+};
 
 /*
  * USB OHCI
@@ -1096,6 +1123,7 @@ static struct platform_device *devices[] __initdata = {
 	&power_supply,
 	&leds_gpio,
 	&magician_camera,
+	&magician_audio_device,
 
 	/* NOTICE mutually exclusive with PXA I2C */
 	&i2c_gpio_bus_alt,
@@ -1143,6 +1171,9 @@ static void __init magician_init(void)
 	pxa_set_ficp_info(&magician_ficp_info);
 	pxa27x_set_i2c_power_info(&magician_i2c_power_info);
 	pxa_set_i2c_info(&i2c_info);
+	i2c_register_board_info(0,
+		ARRAY_AND_SIZE(magician_audio_i2c_devices));
+
 	pxa_set_mci_info(&magician_mci_info);
 	pxa_set_ohci_info(&magician_ohci_info);
 
-- 
1.7.12.1



From petr.cvek at tul.cz  Mon Aug 17 15:01:48 2015
From: petr.cvek at tul.cz (Petr Cvek)
Date: Tue, 18 Aug 2015 00:01:48 +0200
Subject: [PATCH v2 11/21] ARM: pxa: magician: Add MAX1586 Vcore regulator
 support
In-Reply-To: <cover.1439843482.git.petr.cvek@tul.cz>
References: <cover.1439843482.git.petr.cvek@tul.cz>
Message-ID: <55D259CC.6040307@tul.cz>

Add support for MAX1586 Vcore regulator.

Signed-off-by: Petr Cvek <petr.cvek at tul.cz>
---
 arch/arm/mach-pxa/magician.c | 50 ++++++++++++++++++++++++++++++++++++++++++++
 1 file changed, 50 insertions(+)

diff --git a/arch/arm/mach-pxa/magician.c b/arch/arm/mach-pxa/magician.c
index 9decd86..8ca0b67 100644
--- a/arch/arm/mach-pxa/magician.c
+++ b/arch/arm/mach-pxa/magician.c
@@ -96,6 +96,8 @@
 
 #include <sound/uda1380.h>
 
+#include <linux/regulator/max1586.h>
+
 #include "devices.h"
 #include "generic.h"
 
@@ -864,6 +866,52 @@ static struct platform_device vads7846_device = {
 };
 
 /*
+ * Vcore regulator MAX1587A
+ */
+
+static struct regulator_consumer_supply magician_max1587a_consumers[] = {
+	REGULATOR_SUPPLY("vcc_core", NULL),
+};
+
+static struct regulator_init_data magician_max1587a_v3_info = {
+	.constraints = {
+		.name		= "vcc_core range",
+		.min_uV		= 700000,
+		.max_uV		= 1500000,
+		.always_on	= 1,
+		.valid_ops_mask	= REGULATOR_CHANGE_VOLTAGE,
+	},
+	.consumer_supplies	= magician_max1587a_consumers,
+	.num_consumer_supplies	= ARRAY_SIZE(magician_max1587a_consumers),
+};
+
+static struct max1586_subdev_data magician_max1587a_subdevs[] = {
+	{
+		.name		= "vcc_core",
+		.id		= MAX1586_V3,
+		.platform_data	= &magician_max1587a_v3_info,
+	}
+};
+
+static struct max1586_platform_data magician_max1587a_info = {
+	.subdevs     = magician_max1587a_subdevs,
+	.num_subdevs = ARRAY_SIZE(magician_max1587a_subdevs),
+	/*
+	 * NOTICE measured directly on the PCB (board_id == 0x3a), but
+	 * if R24 is present, it will boost the voltage
+	 * (write 1.475V, get 1.645V and smoke)
+	 */
+	.v3_gain     = MAX1586_GAIN_NO_R24,
+};
+
+static struct i2c_board_info magician_pwr_i2c_board_info[] __initdata = {
+	{
+		I2C_BOARD_INFO("max1586", 0x14),
+		.platform_data	= &magician_max1587a_info,
+	},
+};
+
+/*
  * MMC/SD
  */
 
@@ -1173,6 +1221,8 @@ static void __init magician_init(void)
 	pxa_set_i2c_info(&i2c_info);
 	i2c_register_board_info(0,
 		ARRAY_AND_SIZE(magician_audio_i2c_devices));
+	i2c_register_board_info(1,
+		ARRAY_AND_SIZE(magician_pwr_i2c_board_info));
 
 	pxa_set_mci_info(&magician_mci_info);
 	pxa_set_ohci_info(&magician_ohci_info);
-- 
1.7.12.1



From petr.cvek at tul.cz  Mon Aug 17 15:02:46 2015
From: petr.cvek at tul.cz (Petr Cvek)
Date: Tue, 18 Aug 2015 00:02:46 +0200
Subject: [PATCH v2 12/21] ARM: pxa: magician: Add PXA27x UDC support
In-Reply-To: <cover.1439843482.git.petr.cvek@tul.cz>
References: <cover.1439843482.git.petr.cvek@tul.cz>
Message-ID: <55D25A06.9030507@tul.cz>

Add support for PXA27x UDC to HTC Magician.

Signed-off-by: Petr Cvek <petr.cvek at tul.cz>
---
 arch/arm/mach-pxa/magician.c | 40 +++++++++++++++++++++++++++++++++++++++-
 1 file changed, 39 insertions(+), 1 deletion(-)

diff --git a/arch/arm/mach-pxa/magician.c b/arch/arm/mach-pxa/magician.c
index 8ca0b67..23b59a0 100644
--- a/arch/arm/mach-pxa/magician.c
+++ b/arch/arm/mach-pxa/magician.c
@@ -98,6 +98,10 @@
 
 #include <linux/regulator/max1586.h>
 
+#include <linux/platform_data/pxa2xx_udc.h>
+#include <mach/udc.h>
+#include <mach/pxa27x-udc.h>
+
 #include "devices.h"
 #include "generic.h"
 
@@ -698,6 +702,34 @@ static struct platform_device magician_camera = {
  * USB "Transceiver"
  */
 
+#if IS_ENABLED(CONFIG_USB_PXA27X)
+static void magician_udc_command(int cmd)
+{
+	if (cmd == PXA2XX_UDC_CMD_CONNECT)
+		UP2OCR |= UP2OCR_DPPUE | UP2OCR_DPPUBE;
+	else if (cmd == PXA2XX_UDC_CMD_DISCONNECT)
+		UP2OCR &= ~(UP2OCR_DPPUE | UP2OCR_DPPUBE);
+}
+
+/* HACK, shared USB connected state with pda-power */
+int my_usb_online = 1;
+
+static int magician_udc_is_connected(void)
+{
+	/* Shared with pda_power or gpio-vbus */
+	return my_usb_online;
+}
+
+static struct pxa2xx_udc_mach_info magician_udc_info __initdata = {
+	.udc_command		= magician_udc_command,
+	.udc_is_connected	= magician_udc_is_connected,
+	.gpio_pullup		= GPIO27_MAGICIAN_USBC_PUEN,
+};
+
+#else
+
+/* GPIO USB client vbus sensing, when no PXA UDC installed */
+
 static struct resource gpio_vbus_resource = {
 	.flags	= IORESOURCE_IRQ,
 	.start	= IRQ_MAGICIAN_VBUS,
@@ -718,6 +750,7 @@ static struct platform_device gpio_vbus = {
 		.platform_data = &gpio_vbus_info,
 	},
 };
+#endif	/* IS_ENABLED(CONFIG_USB_PXA27X) */
 
 /*
  * Charging functions
@@ -1167,7 +1200,6 @@ static struct platform_device *devices[] __initdata = {
 	&pasic3,
 	&vads7846_device,
 	&bq24022,
-	&gpio_vbus,
 	&power_supply,
 	&leds_gpio,
 	&magician_camera,
@@ -1175,6 +1207,11 @@ static struct platform_device *devices[] __initdata = {
 
 	/* NOTICE mutually exclusive with PXA I2C */
 	&i2c_gpio_bus_alt,
+
+	/* NOTICE mutually exclusive with UDC*/
+#if !(IS_ENABLED(CONFIG_USB_PXA27X))
+	&gpio_vbus,
+#endif
 };
 
 /*
@@ -1226,6 +1263,7 @@ static void __init magician_init(void)
 
 	pxa_set_mci_info(&magician_mci_info);
 	pxa_set_ohci_info(&magician_ohci_info);
+	pxa_set_udc_info(&magician_udc_info);
 
 	/* Check LCD type we have */
 	cpld = ioremap_nocache(PXA_CS3_PHYS, 0x1000);
-- 
1.7.12.1



From petr.cvek at tul.cz  Mon Aug 17 15:03:07 2015
From: petr.cvek at tul.cz (Petr Cvek)
Date: Tue, 18 Aug 2015 00:03:07 +0200
Subject: [PATCH v2 13/21] ARM: pxa: magician: Fix charging source and add NiCd
 backup charging
In-Reply-To: <cover.1439843482.git.petr.cvek@tul.cz>
References: <cover.1439843482.git.petr.cvek@tul.cz>
Message-ID: <55D25A1B.50106@tul.cz>

Fix charging (cable insert functionality shared with UDC). Add charging
control for RTC NiCd accu.

Signed-off-by: Petr Cvek <petr.cvek at tul.cz>
---
 arch/arm/mach-pxa/magician.c | 83 ++++++++++++++++++++++++++++++++++++++------
 1 file changed, 73 insertions(+), 10 deletions(-)

diff --git a/arch/arm/mach-pxa/magician.c b/arch/arm/mach-pxa/magician.c
index 23b59a0..50c5325 100644
--- a/arch/arm/mach-pxa/magician.c
+++ b/arch/arm/mach-pxa/magician.c
@@ -756,18 +756,79 @@ static struct platform_device gpio_vbus = {
  * Charging functions
  */
 
-static int power_supply_init(struct device *dev)
+static int magician_supply_init(struct device *dev)
 {
-	return gpio_request(EGPIO_MAGICIAN_CABLE_TYPE, "CABLE_STATE_AC");
+	int ret = -1;
+
+	ret = gpio_request(EGPIO_MAGICIAN_CABLE_TYPE, "AC charger in USB");
+	if (ret) {
+		pr_err("Cannot request AC/USB charger GPIO (%i)\n", ret);
+		goto err_ac;
+	}
+
+	ret = gpio_request(EGPIO_MAGICIAN_CABLE_INSERT1, "Cable inserted");
+	if (ret) {
+		pr_err("Cannot request cable detection GPIO (%i)\n", ret);
+		goto err_usb;
+	}
+
+	return 0;
+
+err_usb:
+	gpio_free(EGPIO_MAGICIAN_CABLE_TYPE);
+err_ac:
+	return ret;
+}
+
+static void magician_set_charge(int flags)
+{
+	/* EGPIO_MAGICIAN_BQ24022_ISET2: =1 500mA, =0 100mA
+	 *
+	 * RTC NiCd voltage can be read from ADS7846
+	 * in0_input=1930, when =0 (after =1 its going up)
+	 * in0_input=1367, when =1
+	 * in0_input=2499, always (without NiCd)
+	 *
+	 * FIXME Will disabled NiCd slow accu discharge?
+	 *
+	 * Charging from USB can be 500mA too
+	 * NOTICE: IrDA=on, Vcore=1V, Fcore=104MHz, everything other=off
+	 *   -> power consumption still over 100mA
+	 */
+
+	if (flags & PDA_POWER_CHARGE_AC) {
+		pr_debug("Charging from AC\n");
+		gpio_set_value(EGPIO_MAGICIAN_NICD_CHARGE, 1);
+	} else if (flags & PDA_POWER_CHARGE_USB) {
+		pr_debug("Charging from USB\n");
+		gpio_set_value(EGPIO_MAGICIAN_NICD_CHARGE, 1);
+	} else {
+		pr_debug("Charging disabled\n");
+		gpio_set_value(EGPIO_MAGICIAN_NICD_CHARGE, 0);
+	}
+
+	gpio_set_value(EGPIO_MAGICIAN_NICD_CHARGE, 1);
 }
 
 static int magician_is_ac_online(void)
 {
-	return gpio_get_value(EGPIO_MAGICIAN_CABLE_INSERT1);
+	return gpio_get_value(EGPIO_MAGICIAN_CABLE_INSERT1) &&
+		gpio_get_value(EGPIO_MAGICIAN_CABLE_TYPE); /* AC=1 */
+}
+
+static int magician_is_usb_online(void)
+{
+	my_usb_online = gpio_get_value(EGPIO_MAGICIAN_CABLE_INSERT1) &&
+		(!gpio_get_value(EGPIO_MAGICIAN_CABLE_TYPE)); /* USB=0 */
+	return my_usb_online;
 }
 
-static void power_supply_exit(struct device *dev)
+static void magician_supply_exit(struct device *dev)
 {
+	/* HACK FIXME EGPIO pin is used with two drivers */
+	my_usb_online = 1;
+
+	gpio_free(EGPIO_MAGICIAN_CABLE_INSERT1);
 	gpio_free(EGPIO_MAGICIAN_CABLE_TYPE);
 }
 
@@ -780,11 +841,13 @@ static char *magician_supplicants[] = {
  */
 
 static struct pda_power_pdata power_supply_info = {
-	.init		= power_supply_init,
-	.is_ac_online	= magician_is_ac_online,
-	.exit		= power_supply_exit,
-	.supplied_to	= magician_supplicants,
-	.num_supplicants = ARRAY_SIZE(magician_supplicants),
+	.init			= magician_supply_init,
+	.exit			= magician_supply_exit,
+	.is_ac_online		= magician_is_ac_online,
+	.is_usb_online		= magician_is_usb_online,
+	.set_charge		= magician_set_charge,
+	.supplied_to		= magician_supplicants,
+	.num_supplicants	= ARRAY_SIZE(magician_supplicants),
 };
 
 static struct resource power_supply_resources[] = {
@@ -847,7 +910,7 @@ static struct gpio_regulator_config bq24022_info = {
 
 	.enable_gpio = GPIO30_MAGICIAN_BQ24022_nCHARGE_EN,
 	.enable_high = 0,
-	.enabled_at_boot = 0,
+	.enabled_at_boot = 1,
 
 	.gpios = bq24022_gpios,
 	.nr_gpios = ARRAY_SIZE(bq24022_gpios),
-- 
1.7.12.1



From petr.cvek at tul.cz  Mon Aug 17 15:03:28 2015
From: petr.cvek at tul.cz (Petr Cvek)
Date: Tue, 18 Aug 2015 00:03:28 +0200
Subject: [PATCH v2 14/21] ARM: pxa: magician: Fix PXA USB OHCI port enable
 flags
In-Reply-To: <cover.1439843482.git.petr.cvek@tul.cz>
References: <cover.1439843482.git.petr.cvek@tul.cz>
Message-ID: <55D25A30.9000002@tul.cz>

Fix PXA USB OHCI port enable flags.

Signed-off-by: Petr Cvek <petr.cvek at tul.cz>
---
 arch/arm/mach-pxa/magician.c | 4 +++-
 1 file changed, 3 insertions(+), 1 deletion(-)

diff --git a/arch/arm/mach-pxa/magician.c b/arch/arm/mach-pxa/magician.c
index 50c5325..d17125e 100644
--- a/arch/arm/mach-pxa/magician.c
+++ b/arch/arm/mach-pxa/magician.c
@@ -1065,8 +1065,10 @@ static struct platform_device magician_audio_device = {
 
 static struct pxaohci_platform_data magician_ohci_info = {
 	.port_mode	= PMM_PERPORT_MODE,
-	.flags		= ENABLE_PORT1 | ENABLE_PORT3 | POWER_CONTROL_LOW,
+	/* port1: CSR Bluetooth, port2: OTG with UDC */
+	.flags		= ENABLE_PORT1 | ENABLE_PORT2 | POWER_CONTROL_LOW,
 	.power_budget	= 0,
+	.power_on_delay = 100,
 };
 
 /*
-- 
1.7.12.1



From petr.cvek at tul.cz  Mon Aug 17 15:03:54 2015
From: petr.cvek at tul.cz (Petr Cvek)
Date: Tue, 18 Aug 2015 00:03:54 +0200
Subject: [PATCH v2 15/21] ARM: pxa: magician: Fix PWM backlight regulator
In-Reply-To: <cover.1439843482.git.petr.cvek@tul.cz>
References: <cover.1439843482.git.petr.cvek@tul.cz>
Message-ID: <55D25A4A.4070409@tul.cz>

Fix PWM backlight regulator. It is requested from pwm_backlight_probe().

Signed-off-by: Petr Cvek <petr.cvek at tul.cz>
---
 arch/arm/mach-pxa/magician.c | 11 +++++++++++
 1 file changed, 11 insertions(+)

diff --git a/arch/arm/mach-pxa/magician.c b/arch/arm/mach-pxa/magician.c
index d17125e..2ec630e 100644
--- a/arch/arm/mach-pxa/magician.c
+++ b/arch/arm/mach-pxa/magician.c
@@ -542,6 +542,14 @@ static struct platform_device pwm_backlight = {
 };
 
 /*
+ * fixed regulator for pwm_backlight
+ */
+
+static struct regulator_consumer_supply pwm_backlight_supply[] = {
+	REGULATOR_SUPPLY("power", "pwm_backlight"),
+};
+
+/*
  * LEDs
  */
 
@@ -1352,6 +1360,9 @@ static void __init magician_init(void)
 	spi_register_board_info(ARRAY_AND_SIZE(ads7846_spi_board_info));
 
 	pxa_set_camera_info(&magician_pxacamera_pdata);
+
+	regulator_register_always_on(0, "power", pwm_backlight_supply,
+		ARRAY_SIZE(pwm_backlight_supply), 5000000);
 }
 
 MACHINE_START(MAGICIAN, "HTC Magician")
-- 
1.7.12.1



From petr.cvek at tul.cz  Mon Aug 17 15:04:16 2015
From: petr.cvek at tul.cz (Petr Cvek)
Date: Tue, 18 Aug 2015 00:04:16 +0200
Subject: [PATCH v2 16/21] ARM: pxa: magician: Add support for alternative LCD
 backlight
In-Reply-To: <cover.1439843482.git.petr.cvek@tul.cz>
References: <cover.1439843482.git.petr.cvek@tul.cz>
Message-ID: <55D25A60.7000900@tul.cz>

Add support for alternative LCD backlight with GPIO (no brightness).

Signed-off-by: Petr Cvek <petr.cvek at tul.cz>
---
 arch/arm/mach-pxa/magician.c | 22 +++++++++++++++++++++-
 1 file changed, 21 insertions(+), 1 deletion(-)

diff --git a/arch/arm/mach-pxa/magician.c b/arch/arm/mach-pxa/magician.c
index 2ec630e..780cc3d 100644
--- a/arch/arm/mach-pxa/magician.c
+++ b/arch/arm/mach-pxa/magician.c
@@ -102,6 +102,8 @@
 #include <mach/udc.h>
 #include <mach/pxa27x-udc.h>
 
+#include <linux/platform_data/gpio_backlight.h>
+
 #include "devices.h"
 #include "generic.h"
 
@@ -549,6 +551,21 @@ static struct regulator_consumer_supply pwm_backlight_supply[] = {
 	REGULATOR_SUPPLY("power", "pwm_backlight"),
 };
 
+/* Backlight controlled by single GPIO (alternative) */
+static struct gpio_backlight_platform_data gpio_backlight_data = {
+/* .fbdev = &pxa_device_fb.dev, */
+	.gpio		= EGPIO_MAGICIAN_BL_POWER,
+	.def_value	= 1,
+	.name		= "backlight",
+};
+
+static struct platform_device gpio_backlight = {
+	.name = "gpio-backlight",
+	.dev = {
+		.platform_data = &gpio_backlight_data,
+	},
+};
+
 /*
  * LEDs
  */
@@ -1269,7 +1286,6 @@ static struct platform_device *devices[] __initdata = {
 	&gpio_keys,
 	&egpio,
 	&strataflash,
-	&pwm_backlight,
 	&pasic3,
 	&vads7846_device,
 	&bq24022,
@@ -1285,6 +1301,10 @@ static struct platform_device *devices[] __initdata = {
 #if !(IS_ENABLED(CONFIG_USB_PXA27X))
 	&gpio_vbus,
 #endif
+
+	/* NOTICE mutually exclusive */
+	&pwm_backlight,
+	&gpio_backlight,
 };
 
 /*
-- 
1.7.12.1



From petr.cvek at tul.cz  Mon Aug 17 15:04:36 2015
From: petr.cvek at tul.cz (Petr Cvek)
Date: Tue, 18 Aug 2015 00:04:36 +0200
Subject: [PATCH v2 17/21] ARM: pxa: magician: Remove (temporarily) pasic3 LED
 support
In-Reply-To: <cover.1439843482.git.petr.cvek@tul.cz>
References: <cover.1439843482.git.petr.cvek@tul.cz>
Message-ID: <55D25A74.3030902@tul.cz>

Temporarily remove pasic3 LEDs definition as it is not used (yet).

Signed-off-by: Petr Cvek <petr.cvek at tul.cz>
---
 arch/arm/mach-pxa/magician.c | 45 ++------------------------------------------
 1 file changed, 2 insertions(+), 43 deletions(-)

diff --git a/arch/arm/mach-pxa/magician.c b/arch/arm/mach-pxa/magician.c
index 780cc3d..d8994dd 100644
--- a/arch/arm/mach-pxa/magician.c
+++ b/arch/arm/mach-pxa/magician.c
@@ -567,7 +567,7 @@ static struct platform_device gpio_backlight = {
 };
 
 /*
- * LEDs
+ * Phone keys backlight, vibra
  */
 
 static struct gpio_led gpio_leds[] = {
@@ -597,46 +597,6 @@ static struct platform_device leds_gpio = {
 };
 
 /*
- * PASIC3 LEDs
- */
-
-static struct pasic3_led pasic3_leds[] = {
-	{
-		.led = {
-			.name = "magician:red",
-			.default_trigger = "ds2760-battery.0-charging",
-		},
-		.hw_num	= 0,
-		.bit2	= PASIC3_BIT2_LED0,
-		.mask	= PASIC3_MASK_LED0,
-	},
-	{
-		.led = {
-			.name = "magician:green",
-			.default_trigger = "ds2760-battery.0-charging-or-full",
-		},
-		.hw_num	= 1,
-		.bit2	= PASIC3_BIT2_LED1,
-		.mask	= PASIC3_MASK_LED1,
-	},
-	{
-		.led = {
-			.name = "magician:blue",
-			.default_trigger = "bluetooth",
-		},
-		.hw_num	= 2,
-		.bit2	= PASIC3_BIT2_LED2,
-		.mask	= PASIC3_MASK_LED2,
-	},
-};
-
-static struct pasic3_leds_machinfo pasic3_leds_info = {
-	.num_leds	= ARRAY_SIZE(pasic3_leds),
-	.power_gpio	= EGPIO_MAGICIAN_LED_POWER,
-	.leds		= pasic3_leds,
-};
-
-/*
  * PASIC3 DS1WM
  */
 
@@ -656,7 +616,7 @@ static struct resource pasic3_resources[] = {
 
 static struct pasic3_platform_data pasic3_platform_data = {
 	.clock_rate	= 4000000,
-	.led_pdata	= &pasic3_leds_info,
+/*	.led_pdata	= &pasic3_leds_info, */
 };
 
 static struct platform_device pasic3 = {
@@ -1232,7 +1192,6 @@ static struct platform_device i2c_gpio_bus_alt = {
 	}
 };
 
-
 /*
  * Touchscreen
  */
-- 
1.7.12.1



From petr.cvek at tul.cz  Mon Aug 17 15:05:48 2015
From: petr.cvek at tul.cz (Petr Cvek)
Date: Tue, 18 Aug 2015 00:05:48 +0200
Subject: [PATCH v2 18/21] mfd: htc-pasic3: Prepare driver for leds-pasic3
In-Reply-To: <cover.1439843482.git.petr.cvek@tul.cz>
References: <cover.1439843482.git.petr.cvek@tul.cz>
Message-ID: <55D25ABC.1000405@tul.cz>

Fix register definitions and prepare structures for new leds-pasic3
driver.

Signed-off-by: Petr Cvek <petr.cvek at tul.cz>
---
 drivers/mfd/htc-pasic3.c       | 54 ++++++++++++++++-----------
 include/linux/mfd/htc-pasic3.h | 85 +++++++++++++++++++++++++++++++-----------
 2 files changed, 97 insertions(+), 42 deletions(-)

diff --git a/drivers/mfd/htc-pasic3.c b/drivers/mfd/htc-pasic3.c
index e88d4f6..16e156d 100644
--- a/drivers/mfd/htc-pasic3.c
+++ b/drivers/mfd/htc-pasic3.c
@@ -3,6 +3,9 @@
  *
  * Copyright (C) 2006 Philipp Zabel <philipp.zabel at gmail.com>
  *
+ * 2015:	Added registers for LED and RESET, see htc-pasic3.h
+ *		-- Petr Cvek
+ *
  * 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; version 2 of the License.
@@ -21,15 +24,10 @@
 #include <linux/mfd/htc-pasic3.h>
 #include <linux/slab.h>
 
-struct pasic3_data {
-	void __iomem *mapping;
-	unsigned int bus_shift;
-};
-
 #define REG_ADDR  5
 #define REG_DATA  6
 
-#define READ_MODE 0x80
+#define READ_MODE BIT(7)
 
 /*
  * write to a secondary register on the PASIC3
@@ -76,24 +74,36 @@ static struct mfd_cell led_cell __initdata = {
 static int ds1wm_enable(struct platform_device *pdev)
 {
 	struct device *dev = pdev->dev.parent;
-	int c;
+	struct pasic3_data *asic = platform_get_drvdata(pdev);
+	unsigned long flags;
+	u8 c;
+
+	spin_lock_irqsave(&asic->lock, flags);
+
+	c = pasic3_read_register(dev, PASIC3_GPIO);
+	pasic3_write_register(dev, PASIC3_GPIO, c & ~DS1WM_NEN);
 
-	c = pasic3_read_register(dev, 0x28);
-	pasic3_write_register(dev, 0x28, c & 0x7f);
+	spin_unlock_irqrestore(&asic->lock, flags);
 
-	dev_dbg(dev, "DS1WM OWM_EN low (active) %02x\n", c & 0x7f);
+	dev_dbg(dev, "DS1WM OWM_EN low (active) %02lx\n", c & ~DS1WM_NEN);
 	return 0;
 }
 
 static int ds1wm_disable(struct platform_device *pdev)
 {
 	struct device *dev = pdev->dev.parent;
-	int c;
+	struct pasic3_data *asic = platform_get_drvdata(pdev);
+	unsigned long flags;
+	u8 c;
+
+	spin_lock_irqsave(&asic->lock, flags);
+
+	c = pasic3_read_register(dev, PASIC3_GPIO);
+	pasic3_write_register(dev, PASIC3_GPIO, c | DS1WM_NEN);
 
-	c = pasic3_read_register(dev, 0x28);
-	pasic3_write_register(dev, 0x28, c | 0x80);
+	spin_unlock_irqrestore(&asic->lock, flags);
 
-	dev_dbg(dev, "DS1WM OWM_EN high (inactive) %02x\n", c | 0x80);
+	dev_dbg(dev, "DS1WM OWM_EN high (inactive) %02lx\n", c | DS1WM_NEN);
 	return 0;
 }
 
@@ -130,6 +140,7 @@ static int __init pasic3_probe(struct platform_device *pdev)
 	struct device *dev = &pdev->dev;
 	struct pasic3_data *asic;
 	struct resource *r;
+	struct pasic3_leds_pdata *leds_pdata;
 	int ret;
 	int irq = 0;
 
@@ -162,6 +173,8 @@ static int __init pasic3_probe(struct platform_device *pdev)
 	/* calculate bus shift from mem resource */
 	asic->bus_shift = (resource_size(r) - 5) >> 3;
 
+	spin_lock_init(&asic->lock);
+
 	if (pdata && pdata->clock_rate) {
 		ds1wm_pdata.clock_rate = pdata->clock_rate;
 		/* the first 5 PASIC3 registers control the DS1WM */
@@ -172,13 +185,12 @@ static int __init pasic3_probe(struct platform_device *pdev)
 			dev_warn(dev, "failed to register DS1WM\n");
 	}
 
-	if (pdata && pdata->led_pdata) {
-		led_cell.platform_data = pdata->led_pdata;
-		led_cell.pdata_size = sizeof(struct pasic3_leds_machinfo);
-		ret = mfd_add_devices(&pdev->dev, pdev->id, &led_cell, 1, r,
-				      0, NULL);
-		if (ret < 0)
-			dev_warn(dev, "failed to register LED device\n");
+	if (pdata && pdata->pasic3_leds) {
+		leds_pdata = dev_get_platdata(&pdata->pasic3_leds->dev);
+		if (leds_pdata) {
+			leds_pdata->mfd_dev = dev;
+			platform_device_register(pdata->pasic3_leds);
+		}
 	}
 
 	return 0;
diff --git a/include/linux/mfd/htc-pasic3.h b/include/linux/mfd/htc-pasic3.h
index 3d3ed67..91a27b6 100644
--- a/include/linux/mfd/htc-pasic3.h
+++ b/include/linux/mfd/htc-pasic3.h
@@ -2,6 +2,7 @@
  * HTC PASIC3 driver - LEDs and DS1WM
  *
  * Copyright (c) 2007 Philipp Zabel <philipp.zabel at gmail.com>
+ * Copyright (c) 2015 Petr Cvek <petr.cvek at tul.cz>
  *
  * This file is subject to the terms and conditions of the GNU General Public
  * License.  See the file COPYING in the main directory of this archive for
@@ -18,37 +19,79 @@
 extern void pasic3_write_register(struct device *dev, u32 reg, u8 val);
 extern u8 pasic3_read_register(struct device *dev, u32 reg);
 
-/*
- * mask for registers 0x20,0x21,0x22
- */
-#define PASIC3_MASK_LED0 0x04
-#define PASIC3_MASK_LED1 0x08
-#define PASIC3_MASK_LED2 0x40
+#define PASIC3_CH0_DELAY_ON	0x00
+#define PASIC3_CH0_DELAY_OFF	0x01
+#define PASIC3_CH1_DELAY_ON	0x02
+#define PASIC3_CH1_DELAY_OFF	0x03
+#define PASIC3_CH2_DELAY_ON	0x04
+#define PASIC3_CH2_DELAY_OFF	0x05
+#define PASIC3_DELAY_MASK	0x7f
+
+#define PASIC3_CH_CONTROL	0x06
+#define		R06_CH0_EN		BIT(0)
+#define		R06_CH1_EN		BIT(1)
+#define		R06_CH2_EN		BIT(2)
+#define		R06_CH0_FORCE_ON	BIT(3)
+#define		R06_CH1_FORCE_ON	BIT(4)
+#define		R06_CH2_FORCE_ON	BIT(5)
 
 /*
- * bits in register 0x06
+ * pwm_ch0_out | force_on | (bit0 & bit1 & bit2)
+ * pwm_ch1_out | force_on | (bit0 & bit1 & bit2)
+ * pwm_ch2_out | force_on | (bit2?bit0:(bit0 & ! bit1))
  */
-#define PASIC3_BIT2_LED0 0x08
-#define PASIC3_BIT2_LED1 0x10
-#define PASIC3_BIT2_LED2 0x20
+
+#define PASIC3_MASK_A	0x20
+#define PASIC3_MASK_B	0x21
+#define PASIC3_MASK_C	0x22
+#define		MASK_CH0	BIT(2)
+#define		MASK_CH1	BIT(3)
+#define		MASK_CH2	BIT(6)
+#define PASIC3_GPIO	0x28
+#define		DS1WM_NEN	BIT(7)
+#define PASIC3_SYS	0x2a
+
+/* NORMAL_RST, CAM_PWR_RST and UNKNOWN will autoclear, set STATUS */
+#define		NORMAL_RST	BIT(0)
+#define		CAM_PWR_RST	BIT(1)
+#define		UNKNOWN	BIT(2)
+#define		STATUS_NORMAL_RST	BIT(4)
+#define		STATUS_CAM_PWR_RST	BIT(5)
+#define		STATUS_UNKNOWN		BIT(6)
+
+/* FIXME/TODO reset sources */
+#define PASIC3_RST_EN	0x2c
+#define		EN_NORMAL_RST	0x40
+#define		EN_DOOR_RST	0x42
 
 struct pasic3_led {
-	struct led_classdev         led;
-	unsigned int                hw_num;
-	unsigned int                bit2;
-	unsigned int                mask;
-	struct pasic3_leds_machinfo *pdata;
+	char	name[24];
+	char	default_trigger[80];
+	int	hw_num;
+	u8	bit_blink_en;
+	u8	bit_force_on;
+	u8	bit_mask;
+	u8	reg_delay_on;
+	u8	reg_delay_off;
 };
 
-struct pasic3_leds_machinfo {
-	unsigned int      num_leds;
-	unsigned int      power_gpio;
+struct pasic3_leds_pdata {
 	struct pasic3_led *leds;
+	int num_leds;
+	int power_gpio;
+	int power_gpio_users;
+	struct device *mfd_dev;
 };
 
-struct pasic3_platform_data {
-	struct pasic3_leds_machinfo *led_pdata;
-	unsigned int                 clock_rate;
+struct pasic3_data {
+	void __iomem *mapping;
+	unsigned int bus_shift;
+	spinlock_t lock;
 };
 
+struct pasic3_platform_data {
+	unsigned int clock_rate;
+	struct pasic3_led *leds;
+	struct platform_device *pasic3_leds;
+};
 #endif
-- 
1.7.12.1



From petr.cvek at tul.cz  Mon Aug 17 15:06:20 2015
From: petr.cvek at tul.cz (Petr Cvek)
Date: Tue, 18 Aug 2015 00:06:20 +0200
Subject: [PATCH v2 19/21] leds: leds-pasic3: Add support for PASIC3 LED
 controller
In-Reply-To: <cover.1439843482.git.petr.cvek@tul.cz>
References: <cover.1439843482.git.petr.cvek@tul.cz>
Message-ID: <55D25ADC.10703@tul.cz>

Add support for LEDs inside the PASIC3 chip.

Signed-off-by: Petr Cvek <petr.cvek at tul.cz>
---
 drivers/leds/Kconfig       |   9 ++
 drivers/leds/Makefile      |   1 +
 drivers/leds/leds-pasic3.c | 232 +++++++++++++++++++++++++++++++++++++++++++++
 3 files changed, 242 insertions(+)
 create mode 100644 drivers/leds/leds-pasic3.c

diff --git a/drivers/leds/Kconfig b/drivers/leds/Kconfig
index 9ad35f7..516ba65 100644
--- a/drivers/leds/Kconfig
+++ b/drivers/leds/Kconfig
@@ -586,6 +586,15 @@ config LEDS_PM8941_WLED
 	  This option enables support for the 'White' LED block
 	  on Qualcomm PM8941 PMICs.
 
+config LEDS_PASIC3
+	tristate "LED support for the HTC Magician/Alpine PASIC3"
+	depends on LEDS_CLASS
+	depends on HTC_PASIC3
+	select REGMAP
+	help
+	  This option enables support for the PASIC3 chip (different chip
+	  than Compaq ASIC3).
+
 comment "LED Triggers"
 source "drivers/leds/trigger/Kconfig"
 
diff --git a/drivers/leds/Makefile b/drivers/leds/Makefile
index 8d6a24a..b1c659c 100644
--- a/drivers/leds/Makefile
+++ b/drivers/leds/Makefile
@@ -65,6 +65,7 @@ obj-$(CONFIG_LEDS_VERSATILE)		+= leds-versatile.o
 obj-$(CONFIG_LEDS_MENF21BMC)		+= leds-menf21bmc.o
 obj-$(CONFIG_LEDS_PM8941_WLED)		+= leds-pm8941-wled.o
 obj-$(CONFIG_LEDS_KTD2692)		+= leds-ktd2692.o
+obj-$(CONFIG_LEDS_PASIC3)		+= leds-pasic3.o
 
 # LED SPI Drivers
 obj-$(CONFIG_LEDS_DAC124S085)		+= leds-dac124s085.o
diff --git a/drivers/leds/leds-pasic3.c b/drivers/leds/leds-pasic3.c
new file mode 100644
index 0000000..0f95230
--- /dev/null
+++ b/drivers/leds/leds-pasic3.c
@@ -0,0 +1,232 @@
+/*
+ * AIC3 (or PASIC3) LED driver for HTC Magician/Alpine/.. (not Compaq ASIC3)
+ *
+ * Copyright (c) 2015 Petr Cvek <petr.cvek at tul.cz>
+ *
+ * CLK to MS calculation based on leds-asic3.c
+ *
+ * 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.
+ *
+ */
+
+#include <linux/gpio.h>
+#include <linux/kernel.h>
+#include <linux/leds.h>
+#include <linux/mfd/htc-pasic3.h>
+#include <linux/module.h>
+#include <linux/platform_device.h>
+#include <linux/slab.h>
+
+/*
+ * 1 tick is around 62-63 ms, blinking settings (on+off):
+ *	Min: 1+1 ticks ~125ms
+ *	Max: 127+127 ticks ~15?875ms
+ * HW sometimes takes time to change (counter overflow after write?)
+ */
+
+#define MS_TO_CLK(ms)	DIV_ROUND_CLOSEST(((ms)*1024), 64000)
+#define CLK_TO_MS(clk)	(((clk)*64000)/1024)
+#define MAX_CLK		254		/* 127 + 127 (2x 7 bit reg) */
+#define MAX_MS		CLK_TO_MS(MAX_CLK)
+
+spinlock_t lock;
+
+static void brightness_set(struct led_classdev *cdev,
+	enum led_brightness value)
+{
+	struct platform_device *pdev = to_platform_device(cdev->dev->parent);
+	struct pasic3_led *led = dev_get_platdata(cdev->dev);
+	struct pasic3_leds_pdata *pdata = dev_get_platdata(&pdev->dev);
+	unsigned long flags;
+	u8 val;
+
+	spin_lock_irqsave(&lock, flags);
+
+	if (value == LED_OFF) {
+		val = pasic3_read_register(pdata->mfd_dev, PASIC3_CH_CONTROL);
+		pasic3_write_register(pdata->mfd_dev, PASIC3_CH_CONTROL,
+			val & ~(led->bit_blink_en | led->bit_force_on));
+
+		val = pasic3_read_register(pdata->mfd_dev, PASIC3_MASK_A);
+		pasic3_write_register(pdata->mfd_dev, PASIC3_MASK_A,
+			val & ~led->bit_mask);
+
+		if (pdata->power_gpio) {
+			pdata->power_gpio_users--;
+
+			if (pdata->power_gpio_users == 0)
+				gpio_set_value(pdata->power_gpio, 0);
+		}
+	} else {
+		if (pdata->power_gpio) {
+			pdata->power_gpio_users++;
+
+			if (pdata->power_gpio_users != 0)
+				gpio_set_value(pdata->power_gpio, 1);
+		}
+
+		val = pasic3_read_register(pdata->mfd_dev, PASIC3_CH_CONTROL);
+		pasic3_write_register(pdata->mfd_dev, PASIC3_CH_CONTROL,
+			val | led->bit_force_on);
+	}
+
+	spin_unlock_irqrestore(&lock, flags);
+}
+
+static int blink_set(struct led_classdev *cdev,
+	unsigned long *delay_on, unsigned long *delay_off)
+{
+	struct platform_device *pdev = to_platform_device(cdev->dev->parent);
+	struct pasic3_led *led = dev_get_platdata(cdev->dev);
+	struct pasic3_leds_pdata *pdata = dev_get_platdata(&pdev->dev);
+	unsigned long flags;
+	u32 on, off;
+	u8 val;
+
+	if (*delay_on > MAX_MS || *delay_off > MAX_MS)
+		return -EINVAL;
+
+	if (*delay_on == 0 && *delay_off == 0) {
+		/* Choose sensible default delays */
+		on = MS_TO_CLK(500);
+		off = MS_TO_CLK(500);
+	} else {
+		on = MS_TO_CLK(*delay_on);
+		off = MS_TO_CLK(*delay_off);
+		if ((on + off) > MAX_CLK)
+			return -EINVAL;
+		/* Minimal on/off value must be 1 */
+		on = on ? on : 1;
+		off = off ? off : 1;
+	}
+
+	spin_lock_irqsave(&lock, flags);
+
+	pasic3_write_register(pdata->mfd_dev, led->reg_delay_on, on);
+	pasic3_write_register(pdata->mfd_dev, led->reg_delay_off, off);
+
+	val = pasic3_read_register(pdata->mfd_dev, PASIC3_CH_CONTROL);
+	pasic3_write_register(pdata->mfd_dev, PASIC3_CH_CONTROL,
+		val | led->bit_blink_en);
+
+	spin_unlock_irqrestore(&lock, flags);
+
+	*delay_on = CLK_TO_MS(on);
+	*delay_off = CLK_TO_MS(off);
+
+	return 0;
+}
+
+static int pasic3_led_probe(struct platform_device *pdev)
+{
+	struct pasic3_leds_pdata *pdata = dev_get_platdata(&pdev->dev);
+	struct led_classdev *cdev;
+	int ret;
+	int i;
+
+	if (!pdata) {
+		dev_err(&pdev->dev, "no platform data\n");
+		return -EINVAL;
+	}
+
+	if (!pdata->leds) {
+		dev_err(&pdev->dev, "no leds data\n");
+		return -EINVAL;
+	}
+
+	if (pdata->power_gpio) {
+		pdata->power_gpio_users = 0;
+
+		ret = gpio_request(pdata->power_gpio,
+			"Red-Blue LED Power");
+		if (ret < 0) {
+			dev_warn(&pdev->dev, "failed to request power GPIO\n");
+			goto err;
+		}
+	}
+
+	spin_lock_init(&lock);
+
+	cdev = devm_kzalloc(&pdev->dev,
+		sizeof(struct led_classdev) * pdata->num_leds, GFP_KERNEL);
+	if (!cdev) {
+		ret = -ENOMEM;
+		goto err;
+	}
+
+	for (i = 0; i < pdata->num_leds; i++) {
+		cdev[i].name = pdata->leds[i].name;
+		cdev[i].default_trigger = pdata->leds[i].default_trigger;
+		cdev[i].flags = LED_CORE_SUSPENDRESUME;
+		cdev[i].brightness_set = brightness_set;
+		cdev[i].blink_set = blink_set;
+
+		ret = devm_led_classdev_register(&pdev->dev, &cdev[i]);
+		if (ret < 0)
+			goto err;
+
+		cdev[i].dev->platform_data = &pdata->leds[i];
+	}
+
+	return 0;
+
+err:
+	if (pdata->power_gpio)
+		gpio_free(pdata->power_gpio);
+
+	return ret;
+}
+
+static int pasic3_led_remove(struct platform_device *pdev)
+{
+	struct pasic3_leds_pdata *pdata = dev_get_platdata(&pdev->dev);
+
+	if (pdata->power_gpio)
+		gpio_free(pdata->power_gpio);
+
+	return 0;
+}
+
+#ifdef CONFIG_PM_SLEEP
+static int pasic3_led_suspend(struct device *dev)
+{
+	struct pasic3_leds_pdata *pdata = dev_get_platdata(dev);
+
+	if (pdata->power_gpio)
+		gpio_set_value(pdata->power_gpio, 0);
+
+	return 0;
+}
+
+static int pasic3_led_resume(struct device *dev)
+{
+	struct pasic3_leds_pdata *pdata = dev_get_platdata(dev);
+
+	if (pdata->power_gpio)
+		gpio_set_value(pdata->power_gpio, 1);
+
+	return 0;
+}
+#endif
+
+static SIMPLE_DEV_PM_OPS(pasic3_led_pm_ops, pasic3_led_suspend,
+	pasic3_led_resume);
+
+static struct platform_driver pasic3_led_driver = {
+	.probe		= pasic3_led_probe,
+	.remove		= pasic3_led_remove,
+	.driver		= {
+		.name	= "leds-pasic3",
+		.pm	= &pasic3_led_pm_ops,
+	},
+};
+
+module_platform_driver(pasic3_led_driver);
+
+MODULE_AUTHOR("Petr Cvek <petr.cvek at tul.cz>");
+MODULE_DESCRIPTION("HTC Magician PASIC3 LED driver");
+MODULE_LICENSE("GPL");
+MODULE_ALIAS("platform:leds-pasic3");
-- 
1.7.12.1



From petr.cvek at tul.cz  Mon Aug 17 15:06:42 2015
From: petr.cvek at tul.cz (Petr Cvek)
Date: Tue, 18 Aug 2015 00:06:42 +0200
Subject: [PATCH v2 20/21] ARM: pxa: magician: Re-add pdata for new leds-pasic3
 driver
In-Reply-To: <cover.1439843482.git.petr.cvek@tul.cz>
References: <cover.1439843482.git.petr.cvek@tul.cz>
Message-ID: <55D25AF2.1080408@tul.cz>

Re-add definition of LEDs PASIC3 to magician.c.

Signed-off-by: Petr Cvek <petr.cvek at tul.cz>
---
 arch/arm/mach-pxa/magician.c | 54 +++++++++++++++++++++++++++++++++++++++++++-
 1 file changed, 53 insertions(+), 1 deletion(-)

diff --git a/arch/arm/mach-pxa/magician.c b/arch/arm/mach-pxa/magician.c
index d8994dd..5f02ce4 100644
--- a/arch/arm/mach-pxa/magician.c
+++ b/arch/arm/mach-pxa/magician.c
@@ -597,6 +597,58 @@ static struct platform_device leds_gpio = {
 };
 
 /*
+ * PASIC3 LEDs
+ */
+
+static struct pasic3_led magician_pasic3_leds[] = {
+	{
+		.hw_num = 0,
+		.name = "magician:red",
+		.default_trigger = "ds2760-battery.0-charging",
+		.bit_blink_en	= R06_CH0_EN,
+		.bit_force_on	= R06_CH0_FORCE_ON,
+		.bit_mask	= MASK_CH0,
+		.reg_delay_on	= PASIC3_CH0_DELAY_ON,
+		.reg_delay_off	= PASIC3_CH0_DELAY_OFF,
+	},
+	{
+		.hw_num = 1,
+		.name = "magician:green",
+		.default_trigger = "ds2760-battery.0-charging-or-full",
+		.bit_blink_en	= R06_CH1_EN,
+		.bit_force_on	= R06_CH1_FORCE_ON,
+		.bit_mask	= MASK_CH1,
+		.reg_delay_on	= PASIC3_CH1_DELAY_ON,
+		.reg_delay_off	= PASIC3_CH1_DELAY_OFF,
+	},
+	{
+		.hw_num = 2,
+		.name = "magician:blue",
+		.default_trigger = "bluetooth",
+		.bit_blink_en	= R06_CH2_EN,
+		.bit_force_on	= R06_CH2_FORCE_ON,
+		.bit_mask	= MASK_CH2,
+		.reg_delay_on	= PASIC3_CH2_DELAY_ON,
+		.reg_delay_off	= PASIC3_CH2_DELAY_OFF,
+	},
+};
+
+static struct pasic3_leds_pdata magician_pasic3_led_pdata = {
+	.leds		= magician_pasic3_leds,
+	.num_leds	= ARRAY_SIZE(magician_pasic3_leds),
+	/* Green LED doesn't use power_gpio */
+	.power_gpio	= EGPIO_MAGICIAN_LED_POWER,
+};
+
+static struct platform_device pasic3_leds = {
+	.name	= "leds-pasic3",
+	.id	= -1,
+	.dev = {
+		.platform_data = &magician_pasic3_led_pdata,
+	},
+};
+
+/*
  * PASIC3 DS1WM
  */
 
@@ -616,7 +668,7 @@ static struct resource pasic3_resources[] = {
 
 static struct pasic3_platform_data pasic3_platform_data = {
 	.clock_rate	= 4000000,
-/*	.led_pdata	= &pasic3_leds_info, */
+	.pasic3_leds	= &pasic3_leds,
 };
 
 static struct platform_device pasic3 = {
-- 
1.7.12.1



From petr.cvek at tul.cz  Mon Aug 17 15:07:03 2015
From: petr.cvek at tul.cz (Petr Cvek)
Date: Tue, 18 Aug 2015 00:07:03 +0200
Subject: [PATCH v2 21/21] ARM: pxa: magician: Move platform_add_devices() to
 the end of magician_init()
In-Reply-To: <cover.1439843482.git.petr.cvek@tul.cz>
References: <cover.1439843482.git.petr.cvek@tul.cz>
Message-ID: <55D25B07.1080703@tul.cz>

Move platform_add_devices() to the end of magician_init() for better
clarity of code.

Signed-off-by: Petr Cvek <petr.cvek at tul.cz>
---
 arch/arm/mach-pxa/magician.c | 5 +++--
 1 file changed, 3 insertions(+), 2 deletions(-)

diff --git a/arch/arm/mach-pxa/magician.c b/arch/arm/mach-pxa/magician.c
index 5f02ce4..af86350 100644
--- a/arch/arm/mach-pxa/magician.c
+++ b/arch/arm/mach-pxa/magician.c
@@ -1355,9 +1355,8 @@ static void __init magician_init(void)
 	pxa_set_btuart_info(NULL);
 	pxa_set_stuart_info(NULL);
 
-	platform_add_devices(ARRAY_AND_SIZE(devices));
-
 	pxa_set_ficp_info(&magician_ficp_info);
+
 	pxa27x_set_i2c_power_info(&magician_i2c_power_info);
 	pxa_set_i2c_info(&i2c_info);
 	i2c_register_board_info(0,
@@ -1394,6 +1393,8 @@ static void __init magician_init(void)
 
 	regulator_register_always_on(0, "power", pwm_backlight_supply,
 		ARRAY_SIZE(pwm_backlight_supply), 5000000);
+
+	platform_add_devices(ARRAY_AND_SIZE(devices));
 }
 
 MACHINE_START(MAGICIAN, "HTC Magician")
-- 
1.7.12.1



From petr.cvek at tul.cz  Mon Aug 17 14:59:44 2015
From: petr.cvek at tul.cz (Petr Cvek)
Date: Mon, 17 Aug 2015 23:59:44 +0200
Subject: [PATCH v2 07/21] ARM: pxa: magician: Fix IrDA pdata and redundant
 GPIO request
In-Reply-To: <cover.1439843482.git.petr.cvek@tul.cz>
References: <cover.1439843482.git.petr.cvek@tul.cz>
Message-ID: <55D25950.6010601@tul.cz>

Fix PXA FICP (IrDA) pdata and redundant GPIO request.

Signed-off-by: Petr Cvek <petr.cvek at tul.cz>
---
 arch/arm/mach-pxa/magician.c | 4 ++--
 1 file changed, 2 insertions(+), 2 deletions(-)

diff --git a/arch/arm/mach-pxa/magician.c b/arch/arm/mach-pxa/magician.c
index 702e8e0..7519238 100644
--- a/arch/arm/mach-pxa/magician.c
+++ b/arch/arm/mach-pxa/magician.c
@@ -256,7 +256,8 @@ static unsigned long magician_pin_config[] __initdata = {
 static struct pxaficp_platform_data magician_ficp_info = {
 	.gpio_pwdown		= GPIO83_MAGICIAN_nIR_EN,
 	/* TODO test with FIR dongle */
-	.transceiver_cap	= IR_SIRMODE | IR_OFF,
+	.transceiver_cap	= IR_SIRMODE | IR_FIRMODE | IR_OFF,
+	.gpio_pwdown_inverted = 0,
 };
 
 /*
@@ -987,7 +988,6 @@ static struct gpio magician_global_gpios[] = {
 		"LCD VOFF enable" },
 	{ GPIO105_MAGICIAN_LCD_VON_EN, GPIOF_OUT_INIT_HIGH,
 		"LCD VON enable" },
-	{ GPIO83_MAGICIAN_nIR_EN, GPIOF_OUT_INIT_HIGH,	"nIR_EN" },
 };
 
 static void __init magician_init(void)
-- 
1.7.12.1



From petr.cvek at tul.cz  Mon Aug 17 15:14:46 2015
From: petr.cvek at tul.cz (Petr Cvek)
Date: Tue, 18 Aug 2015 00:14:46 +0200
Subject: [PATCH v2 19/21] leds: leds-pasic3: Add support for PASIC3 LED
 controller
In-Reply-To: <55D25ADC.10703@tul.cz>
References: <cover.1439843482.git.petr.cvek@tul.cz> <55D25ADC.10703@tul.cz>
Message-ID: <55D25CD6.6040404@tul.cz>

Dne 18.8.2015 v 00:06 Petr Cvek napsal(a):
> Add support for LEDs inside the PASIC3 chip.

BTW During research I have found there was driver in 

	https://github.com/hackndev/linux-hnd 

but it did not make up to vanilla, so I wrote mine from scratch (actually I
have tested the PASIC3 registers mostly by trial and error - and found some
for case open reset).




From m-karicheri2 at ti.com  Mon Aug 17 15:12:52 2015
From: m-karicheri2 at ti.com (Murali Karicheri)
Date: Mon, 17 Aug 2015 18:12:52 -0400
Subject: [PATCH] ARM: keystone: add a work around to handle asynchronous
 external abort
In-Reply-To: <20150814215617.GA7557@n2100.arm.linux.org.uk>
References: <1439320409-20084-1-git-send-email-m-karicheri2@ti.com>
 <55CDF579.4050408@ti.com> <20150814140934.GX7557@n2100.arm.linux.org.uk>
 <55CE05EC.4040909@oracle.com> <55CE633C.10402@ti.com>
 <20150814215617.GA7557@n2100.arm.linux.org.uk>
Message-ID: <55D25C64.3090107@ti.com>

On 08/14/2015 05:56 PM, Russell King - ARM Linux wrote:
> On Fri, Aug 14, 2015 at 05:53:00PM -0400, Murali Karicheri wrote:
>> We have spend some time already to debug the root cause. Do you have idea on
>> how this was hunted down on OMAP that we can learn from? The bad address is
>> NULL and it seems to happen very rarely and is not easily reproducible.
>> Don't want to put this workaround, but we couldn't track it down either. So
>> any help to debug this will be appreciated.
>
> If you try applying Lucas' patch, you should receive the abort earlier
> in the kernel boot up, which may help narrow down what is provoking it.
>

Unfortunately, this patch causes boot to stop very early just after 
local_abt_enable() is called in early_trap_init(). Before and After 
applying the patch, here is what the boot log looks like. Do you see any 
issue with the patch diff shown below? Patch is applied on top of 
v4.2-rc7. I have some additional base port patches applied to boot 
kernel on my EVM based on a new SoC.

Thanks

Murali


== Patch Applied to Linux 4.2-rc7 =======

a0868495 at ula0868495 ~/Project/linux-keystone $ git show
commit 361c8f772b6666b806b470a25e55017f88950dcd
Author: Murali Karicheri <m-karicheri2 at ti.com>
Date:   Mon Aug 17 16:22:25 2015 -0400

     abort enhancements

diff --git a/arch/arm/include/asm/irqflags.h 
b/arch/arm/include/asm/irqflags.h
index 4390814..ac1e7e9 100644
--- a/arch/arm/include/asm/irqflags.h
+++ b/arch/arm/include/asm/irqflags.h
@@ -54,6 +54,14 @@ static inline void arch_local_irq_disable(void)

  #define local_fiq_enable()  __asm__("cpsie f   @ __stf" : : : 
"memory", "cc")
  #define local_fiq_disable() __asm__("cpsid f   @ __clf" : : : 
"memory", "cc")
+
+#ifndef CONFIG_CPU_V7M
+#define local_abt_enable()  __asm__("cpsie a   @ __sta" : : : "memory", 
"cc")
+#define local_abt_disable() __asm__("cpsid a   @ __cla" : : : "memory", 
"cc")
+#else
+#define local_abt_enable()     do { } while (0)
+#define local_abt_disable()    do { } while (0)
+#endif
  #else

  /*
@@ -136,6 +144,8 @@ static inline void arch_local_irq_disable(void)
         : "memory", "cc");                                      \
         })

+#define local_abt_enable()     do { } while (0)
+#define local_abt_disable()    do { } while (0)
  #endif

  /*
diff --git a/arch/arm/kernel/smp.c b/arch/arm/kernel/smp.c
index 3d6b782..27c944b 100644
--- a/arch/arm/kernel/smp.c
+++ b/arch/arm/kernel/smp.c
@@ -358,7 +358,7 @@ asmlinkage void secondary_start_kernel(void)

         cpu_init();

         pr_debug("CPU%u: Booted secondary processor\n", cpu);

         preempt_disable();
         trace_hardirqs_off();
@@ -385,6 +385,7 @@ asmlinkage void secondary_start_kernel(void)

         local_irq_enable();
         local_fiq_enable();
+       local_abt_enable();

         /*
          * OK, it's off to the idle thread for us
diff --git a/arch/arm/kernel/traps.c b/arch/arm/kernel/traps.c
index d358226..381c4e4 100644
--- a/arch/arm/kernel/traps.c
+++ b/arch/arm/kernel/traps.c
@@ -871,6 +871,11 @@ void __init early_trap_init(void *vectors_base)

         flush_icache_range(vectors, vectors + PAGE_SIZE * 2);
         modify_domain(DOMAIN_USER, DOMAIN_CLIENT);
+
+       /* Enable imprecise aborts */
+       local_abt_enable();
+
  #else /* ifndef CONFIG_CPU_V7M */
         /*
          * on V7-M there is no need to copy the vector table to a dedicated


=========Log after applying the above patch ========================
Starting kernel ...

Uncompressing Linux... done, booting the kernel.
[    0.000000] Booting Linux on physical CPU 0x0
[    0.000000] Linux version 4.2.0-rc7-00009-g361c8f7-dirty 
(a0868495 at ula0868495) (gcc version 4.9.3 20150413 (prerelease) (Linaro 
GCC 4.9-2015.05) ) #4 SMP PREEMPT Mon Au5
[    0.000000] CPU: ARMv7 Processor [412fc0f4] revision 4 (ARMv7), 
cr=30c5387d
[    0.000000] CPU: PIPT / VIPT nonaliasing data cache, PIPT instruction 
cache
[    0.000000] Machine model: Texas Instruments Keystone 2 Galileo EVM
[    0.000000] bootconsole [earlycon0] enabled
[    0.000000] Switching physical address space to 0x800000000
[    0.000000] cma: Reserved 16 MiB at 0x000000085f000000
[    0.000000] Forcing write-allocate cache policy for SMP
[    0.000000] Memory policy: Data cache writealloc


==========Log before applying the patch ===============================
Starting kernel ...

[    0.000000] Booting Linux on physical CPU 0x0
[    0.000000] Linux version 4.2.0-rc7-00007-g1f593c2-dirty 
(a0868495 at ula0868495) (gcc version 4.9.3 20150413 (prerelease) (Linaro 
GCC 4.9-2015.05) ) #1 SMP PREEMPT Mon Au5
[    0.000000] CPU: ARMv7 Processor [412fc0f4] revision 4 (ARMv7), 
cr=30c5387d
[    0.000000] CPU: PIPT / VIPT nonaliasing data cache, PIPT instruction 
cache
[    0.000000] Machine model: Texas Instruments Keystone 2 Galileo EVM
[    0.000000] Switching physical address space to 0x800000000
[    0.000000] cma: Reserved 16 MiB at 0x000000085f000000
[    0.000000] Forcing write-allocate cache policy for SMP
[    0.000000] Memory policy: Data cache writealloc
[    0.000000] On node 0 totalpages: 393216
[    0.000000] free_area_init_node: node 0, pgdat c07edc00, node_mem_map 
eebf9000
[    0.000000]   DMA zone: 1520 pages used for memmap
[    0.000000]   DMA zone: 0 pages reserved
[    0.000000]   DMA zone: 194560 pages, LIFO batch:31
[    0.000000]   HighMem zone: 198656 pages, LIFO batch:31
[    0.000000] PERCPU: Embedded 12 pages/cpu @eebdb000 s16832 r8192 
d24128 u49152
[    0.000000] pcpu-alloc: s16832 r8192 d24128 u49152 alloc=12*4096
[    0.000000] pcpu-alloc: [0] 0
[    0.000000] Built 1 zonelists in Zone order, mobility grouping on. 
Total pages: 391696
[    0.000000] Kernel command line: console=ttyS0,115200n8 rootwait=1 
clk_ignore_unused debug earlyprintk rdinit=/sbin/init rw root=/dev/ram0 
initrd=0x802000000,9M
[    0.000000] PID hash table entries: 4096 (order: 2, 16384 bytes)
[    0.000000] Dentry cache hash table entries: 131072 (order: 7, 524288 
bytes)
[    0.000000] Inode-cache hash table entries: 65536 (order: 6, 262144 
bytes)
[    0.000000] Memory: 1525700K/1572864K available (5489K kernel code, 
352K rwdata, 1936K rodata, 332K init, 189K bss, 30780K reserved, 16384K 
cma-reserved, 778240K highme)
[    0.000000] Virtual kernel memory layout:
[    0.000000]     vector  : 0xffff0000 - 0xffff1000   (   4 kB)
[    0.000000]     fixmap  : 0xffc00000 - 0xfff00000   (3072 kB)
[    0.000000]     vmalloc : 0xf0000000 - 0xff000000   ( 240 MB)
[    0.000000]     lowmem  : 0xc0000000 - 0xef800000   ( 760 MB)
[    0.000000]     pkmap   : 0xbfe00000 - 0xc0000000   (   2 MB)
[    0.000000]     modules : 0xbf000000 - 0xbfe00000   (  14 MB)
[    0.000000]       .text : 0xc0008000 - 0xc0748894   (7427 kB)
[    0.000000]       .init : 0xc0749000 - 0xc079c000   ( 332 kB)
[    0.000000]       .data : 0xc079c000 - 0xc07f405c   ( 353 kB)
[    0.000000]        .bss : 0xc07f7000 - 0xc08265b0   ( 190 kB)
[    0.000000] SLUB: HWalign=64, Order=0-3, MinObjects=0, CPUs=1, Nodes=1
[    0.000000] Preemptible hierarchical RCU implementation.
[    0.000000]  Additional per-CPU info printed with stalls.
[    0.000000]  Build-time adjustment of leaf fanout to 32.
[    0.000000]  RCU restricting CPUs from NR_CPUS=4 to nr_cpu_ids=1.
[    0.000000] RCU: Adjusting geometry for rcu_fanout_leaf=32, nr_cpu_ids=1
[    0.000000] NR_IRQS:16 nr_irqs:16 16
[    0.000000] Architected cp15 timer(s) running at 24.00MHz (virt).
[    0.000000] clocksource: arch_sys_counter: mask: 0xffffffffffffff 
max_cycles: 0x588fe9dc0, max_idle_ns: 440795202592 ns
[    0.000006] sched_clock: 56 bits at 24MHz, resolution 41ns, wraps 
every 4398046511097ns
[    0.000022] Switching to timer-based delay loop, resolution 41ns
[    0.000232] keystone timer clock @200000000 Hz
[    0.000365] Console: colour dummy device 80x30
[    0.000390] Calibrating delay loop (skipped), value calculated using 
timer frequency.. 48.00 BogoMIPS (lpj=240000)
[    0.000409] pid_max: default: 4096 minimum: 301
[    0.000533] Mount-cache hash table entries: 2048 (order: 1, 8192 bytes)
[    0.000549] Mountpoint-cache hash table entries: 2048 (order: 1, 8192 
bytes)
[    0.001210] CPU: Testing write buffer coherency: ok
[    0.001454] /cpus/cpu at 0 missing clock-frequency property
[    0.001474] CPU0: thread -1, cpu 0, socket 0, mpidr 80000000
[    0.001531] Setting up static identity map for 0x800082c0 - 0x800083cc
[    0.020357] Brought up 1 CPUs
[    0.020374] SMP: Total of 1 processors activated (48.00 BogoMIPS).
[    0.020386] CPU: All CPU(s) started in SVC mode.
[    0.020890] devtmpfs: initialized
[    0.026907] VFP support v0.3: implementor 41 architecture 4 part 30 
variant f rev 0
[    0.027592] clocksource: jiffies: mask: 0xffffffff max_cycles: 
0xffffffff, max_idle_ns: 19112604462750000 ns
[    0.028847] NET: Registered protocol family 16
[    0.030535] DMA: preallocated 256 KiB pool for atomic coherent 
allocations
[    0.040844] hw-breakpoint: found 5 (+1 reserved) breakpoint and 4 
watchpoint registers.
[    0.040861] hw-breakpoint: maximum watchpoint size is 8 bytes.
[    0.067540] vgaarb: loaded
[    0.067950] SCSI subsystem initialized
[    0.068376] usbcore: registered new interface driver usbfs
[    0.068474] usbcore: registered new interface driver hub
[    0.068996] usbcore: registered new device driver usb
[    0.075144] clocksource: Switched to clocksource arch_sys_counter
[    0.136115] NET: Registered protocol family 2
[    0.136916] TCP established hash table entries: 8192 (order: 3, 32768 
bytes)
[    0.137020] TCP bind hash table entries: 8192 (order: 4, 65536 bytes)
[    0.137228] TCP: Hash tables configured (established 8192 bind 8192)
[    0.137306] UDP hash table entries: 512 (order: 2, 16384 bytes)
[    0.137356] UDP-Lite hash table entries: 512 (order: 2, 16384 bytes)
[    0.137624] NET: Registered protocol family 1
[    0.138537] RPC: Registered named UNIX socket transport module.
[    0.138552] RPC: Registered udp transport module.
[    0.138562] RPC: Registered tcp transport module.
[    0.138572] RPC: Registered tcp NFSv4.1 backchannel transport module.
[    0.138603] PCI: CLS 0 bytes, default 64
[    0.138879] Unpacking initramfs...
[    1.021486] Initramfs unpacking failed: junk in compressed archive
[    1.030896] Freeing initrd memory: 9216K (c2000000 - c2900000)
[    1.031216] hw perfevents: Failed to parse /pmu/interrupt-affinity[0]
[    1.031268] hw perfevents: enabled with armv7_cortex_a15 PMU driver, 
7 counters available
[    1.032356] platform alarmtimer: set dma_pfn_offset00780000
[    1.033061] futex hash table entries: 16 (order: -2, 1024 bytes)
[    1.061488] Installing knfsd (copyright (C) 1996 okir at monad.swb.de).
[    1.061697] ntfs: driver 2.1.32 [Flags: R/O].
[    1.062370] jffs2: version 2.2. (NAND) ?? 2001-2006 Red Hat, Inc.
[    1.069538] NET: Registered protocol family 38
[    1.069666] bounce: pool size: 64 pages
[    1.070002] Block layer SCSI generic (bsg) driver version 0.4 loaded 
(major 253)
[    1.070025] io scheduler noop registered
[    1.070045] io scheduler deadline registered
[    1.070343] io scheduler cfq registered (default)
[    1.224619] Serial: 8250/16550 driver, 4 ports, IRQ sharing disabled
[    1.224778] platform serial8250: set dma_pfn_offset00780000
[    1.228741] console [ttyS0] disabled
[    1.228827] 2530c00.serial: ttyS0 at MMIO 0x2530c00 (irq = 23, 
base_baud = 12000000) is a 16550A
[    1.851892] console [ttyS0] enabled
[    1.856840] 2531000.serial: ttyS1 at MMIO 0x2531000 (irq = 24, 
base_baud = 12000000) is a 16550A
[    1.867235] 2531400.serial: ttyS2 at MMIO 0x2531400 (irq = 25, 
base_baud = 12000000) is a 16550A
[    1.885650] loop: module loaded
[    1.891927] spi_davinci 21805400.spi: Controller at 0xf012e400
[    1.898849] spi_davinci 21805800.spi: Controller at 0xf0130800
[    1.905792] spi_davinci 21805c00.spi: Controller at 0xf0132c00
[    1.912320] spi_davinci 21806000.spi: Controller at 0xf0134000
[    1.921607] usbcore: registered new interface driver usb-storage
[    1.929871] mousedev: PS/2 mouse device common for all mice
[    1.936141] i2c /dev entries driver
[    1.941171] davinci-wdt 2260000.wdt: heartbeat 60 sec
[    1.947853] usbcore: registered new interface driver usbhid
[    1.953419] usbhid: USB HID core driver
[    1.958679] platform oprofile-perf.0: set dma_pfn_offset00780000
[    1.965446] oprofile: using timer interrupt.
[    1.969997] Netfilter messages via NETLINK v0.30. 

[    1.974938] nf_conntrack version 0.5.0 (16384 buckets, 65536 max) 

[    1.981990] ctnetlink v0.93: registering with nfnetlink. 

[    1.988320] ipip: IPv4 over IPv4 tunneling driver 

[    1.994258] gre: GRE over IPv4 demultiplexor driver 

[    1.999144] ip_gre: GRE over IPv4 tunneling driver
[    2.006310] ip_tables: (C) 2000-2006 Netfilter Core Team
[    2.011739] ipt_CLUSTERIP: ClusterIP Version 0.8 loaded successfully
[    2.018699] arp_tables: (C) 2002 David S. Miller
[    2.023383] Initializing XFRM netlink socket
[    2.029369] NET: Registered protocol family 10
[    2.035534] NET: Registered protocol family 17
[    2.040009] NET: Registered protocol family 15
[    2.044606] 8021q: 802.1Q VLAN Support v1.8
[    2.051981] sctp: Hash tables configured (established 65536 bind 65536)
[    2.059618] Registering SWP/SWPB emulation handler
[    2.071022] clk: Not disabling unused clocks
[    2.076836] Freeing unused kernel memory: 332K (c0749000 - c079c000)
[    2.083750] Unhandled fault: asynchronous external abort (0x1211) at 
0x00000000
[    2.091051] pgd = edf42b40
[    2.093752] [00000000] *pgd=82e6c8003, *pmd=82e6c9003, *pte=00000000
[    2.100585] Kernel panic - not syncing: Attempted to kill init! 
exitcode=0x00000007
[    2.100585]
[    2.109714] CPU: 0 PID: 1 Comm: init Not tainted 
4.2.0-rc7-00007-g1f593c2-dirty #1
[    2.117269] Hardware name: Keystone
[    2.120779] [<c001627c>] (unwind_backtrace) from [<c0012b70>] 
(show_stack+0x10/0x14)
[    2.128521] [<c0012b70>] (show_stack) from [<c0535a94>] 
(dump_stack+0x84/0xc4)
[    2.135737] [<c0535a94>] (dump_stack) from [<c0533a98>] 
(panic+0xa0/0x1f8)
[    2.142609] [<c0533a98>] (panic) from [<c00270f8>] 
(complete_and_exit+0x0/0x1c)
[    2.149910] [<c00270f8>] (complete_and_exit) from [<ee46bfb0>] 
(0xee46bfb0)
[    2.156867] ---[ end Kernel panic - not syncing: Attempted to kill 
init! exitcode=0x00000007
[    2.156867]


-- 
Murali Karicheri
Linux Kernel, Keystone


From petr.cvek at tul.cz  Mon Aug 17 15:18:47 2015
From: petr.cvek at tul.cz (Petr Cvek)
Date: Tue, 18 Aug 2015 00:18:47 +0200
Subject: [PATCH v2 13/21] ARM: pxa: magician: Fix charging source and add
 NiCd backup charging
In-Reply-To: <55D25A1B.50106@tul.cz>
References: <cover.1439843482.git.petr.cvek@tul.cz> <55D25A1B.50106@tul.cz>
Message-ID: <55D25DC7.7040200@tul.cz>

Dne 18.8.2015 v 00:03 Petr Cvek napsal(a):
> +static int magician_is_usb_online(void)
> +{
> +	my_usb_online = gpio_get_value(EGPIO_MAGICIAN_CABLE_INSERT1) &&
> +		(!gpio_get_value(EGPIO_MAGICIAN_CABLE_TYPE)); /* USB=0 */
> +	return my_usb_online;
>  }

This patch requires my_usb_online variable defined by 

	[PATCH v2 12/21] ARM: pxa: magician: Add PXA27x UDC support

because both (UDC and charging) require same EGPIO.


Petr


From petr.cvek at tul.cz  Mon Aug 17 15:20:37 2015
From: petr.cvek at tul.cz (Petr Cvek)
Date: Tue, 18 Aug 2015 00:20:37 +0200
Subject: [PATCH v2 00/21] ARM: pxa: magician: Rework HTC Magician support
In-Reply-To: <55D2583B.8040602@tul.cz>
References: <55D2583B.8040602@tul.cz>
Message-ID: <55D25E35.3000102@tul.cz>

Dne 17.8.2015 v 23:55 Petr Cvek napsal(a):
> This patchset will clean, fix and finally add multiple PXA devices
> to HTC Magician machine. Also it adds leds-pasic3 driver to LED subsystem.
> This driver require changes into htc-pasic3 structures, which are used
> exclusively by magician.c code.
> 
> Petr Cvek (21):
>   ARM: pxa: magician: Fix Kconfig for magician to always include
>     htc-egpio
>   ARM: pxa: magician: Fix indentation and whitespaces
>   ARM: pxa: magician: Fix comments, debug functions and print strings
>   ARM: pxa: magician: Add, fix and init (new) GPIOs
>   ARM: pxa: magician: Add support for ADS7846 touchscreen
>   ARM: pxa: magician: Add normal and power I2C definition
>   ARM: pxa: magician: Fix IrDA pdata and redundant GPIO request
>   ARM: pxa: magician: Add StrataFlash Vpp GPIO and alternative driver
>   ARM: pxa: magician: Add OV9640 camera support
>   ARM: pxa: magician: Add UDA1380 sound support
>   ARM: pxa: magician: Add MAX1586 Vcore regulator support
>   ARM: pxa: magician: Add PXA27x UDC support
>   ARM: pxa: magician: Fix charging source and add NiCd backup charging
>   ARM: pxa: magician: Fix PXA USB OHCI port enable flags
>   ARM: pxa: magician: Fix PWM backlight regulator
>   ARM: pxa: magician: Add support for alternative LCD backlight
>   ARM: pxa: magician: Remove (temporarily) pasic3 LED support
>   mfd: htc-pasic3: Prepare driver for leds-pasic3
>   leds: leds-pasic3: Add support for PASIC3 LED controller
>   ARM: pxa: magician: Re-add pdata for new leds-pasic3 driver
>   ARM: pxa: magician: Move platform_add_devices() to the end of
>     magician_init()

Patches for EGPIO, charging, LCD, MAX1586 and UDC are required to use
Magician at all or else there will be no connectivity for debug console,
very fast accu discharge, no working LCD and/or no rootfs from MMC/SD.

Petr



From timur at codeaurora.org  Mon Aug 17 15:45:31 2015
From: timur at codeaurora.org (Timur Tabi)
Date: Mon, 17 Aug 2015 17:45:31 -0500
Subject: [PATCH 3/3] [v2] hvc_dcc: disable user-space access to DCC
In-Reply-To: <20150810094755.GE1604@arm.com>
References: <1438992995-22610-1-git-send-email-timur@codeaurora.org>
 <1438992995-22610-3-git-send-email-timur@codeaurora.org>
 <20150810094755.GE1604@arm.com>
Message-ID: <55D2640B.5090709@codeaurora.org>

On 08/10/2015 04:47 AM, Will Deacon wrote:
>> +static inline void __dcc_initialize(void)
>> +{
>> +	u32 val;
>> +
>> +	/* Disable user-space access to DCC */
>> +	asm volatile ("mrs %0, mdscr_el1\n"
>> +		"	orr %0, %0, #4096\n" /* Set the TDCC bit */
>
> So this is the same as your "1 << 12" for arch/arm/. Shouldn't we
> #define that someplace common?

Well, I'm not sure.  First, there is no common place currently 
available.  I would need to create a new header file that only has one 
line in it.

Secondly, DBGDSCR in ARMv7 and MDSCR_EL1 on ARMv8 don't have that much 
in common.  Those two registers probably serve the same function, but 
only a few bits are the same.

I've documented the code.  I can clean it up so that it looks like the same.

>> +	__dcc_initialize();
>> +
>>   	/* Returns -1 if error */
>>   	ret = hvc_instantiate(0, 0, &hvc_dcc_get_put_ops);
>
> Can this driver be built as a module and unloaded? If so, should we
> re-enable userspace access when the kernel doesn't need it anymore?

Not according to the Kconfig:

config HVC_DCC
        bool "ARM JTAG DCC console"

> Finally, have you checked the behaviour on CPU hotplug? It looks like we
> zero mdscr_el1 in the cold boot path. The alternative is to set this bit
> there and never allow userspace access. Do you know of any compelling
> use-cases where userspace accesses the DCC directly?

Maybe KVM?

I have to admit, this is starting to get a little out of my league.  All 
I really wanted to do was make DCC available on ARM64, the same exact 
way it's available on ARM32.  I don't want to have to solve every DCC 
problem that exists today on every ARM platform.  I would rather drop 
this patch than have to spend an inordinate amount of time making it 
perfect.

We've never disabled user-space DCC support on any ARM platform before. 
  If there is a problem with user-space DCC, I've never seen it, and I 
don't know anyone who has.

-- 
Qualcomm Innovation Center, Inc.
The Qualcomm Innovation Center, Inc. is a member of the
Code Aurora Forum, a Linux Foundation Collaborative Project.


From linux at arm.linux.org.uk  Mon Aug 17 15:47:54 2015
From: linux at arm.linux.org.uk (Russell King - ARM Linux)
Date: Mon, 17 Aug 2015 23:47:54 +0100
Subject: [PATCH] ARM: keystone: add a work around to handle asynchronous
 external abort
In-Reply-To: <55D25C64.3090107@ti.com>
References: <1439320409-20084-1-git-send-email-m-karicheri2@ti.com>
 <55CDF579.4050408@ti.com>
 <20150814140934.GX7557@n2100.arm.linux.org.uk>
 <55CE05EC.4040909@oracle.com> <55CE633C.10402@ti.com>
 <20150814215617.GA7557@n2100.arm.linux.org.uk>
 <55D25C64.3090107@ti.com>
Message-ID: <20150817224754.GI7557@n2100.arm.linux.org.uk>

On Mon, Aug 17, 2015 at 06:12:52PM -0400, Murali Karicheri wrote:
> Unfortunately, this patch causes boot to stop very early just after
> local_abt_enable() is called in early_trap_init(). Before and After applying
> the patch, here is what the boot log looks like. Do you see any issue with
> the patch diff shown below? Patch is applied on top of v4.2-rc7. I have some
> additional base port patches applied to boot kernel on my EVM based on a new
> SoC.

Try moving the call to local_abt_enable() below forward to the end of
devicemaps_init().  I suspect this is too early for the abort handlers
to reliably run.

> diff --git a/arch/arm/kernel/traps.c b/arch/arm/kernel/traps.c
> index d358226..381c4e4 100644
> --- a/arch/arm/kernel/traps.c
> +++ b/arch/arm/kernel/traps.c
> @@ -871,6 +871,11 @@ void __init early_trap_init(void *vectors_base)
> 
>         flush_icache_range(vectors, vectors + PAGE_SIZE * 2);
>         modify_domain(DOMAIN_USER, DOMAIN_CLIENT);
> +
> +       /* Enable imprecise aborts */
> +       local_abt_enable();
> +

-- 
FTTC broadband for 0.8mile line: currently at 10.5Mbps down 400kbps up
according to speedtest.net.


From tchalamarla at caviumnetworks.com  Mon Aug 17 16:13:55 2015
From: tchalamarla at caviumnetworks.com (tchalamarla at caviumnetworks.com)
Date: Mon, 17 Aug 2015 16:13:55 -0700
Subject: [PATCH V3] iommu/arm-smmu-v2: ThunderX mis-extends 64bit registers
Message-ID: <1439853235-12162-1-git-send-email-tchalamarla@caviumnetworks.com>

From: Tirumalesh Chalamarla <tchalamarla at caviumnetworks.com>

The SMMU architecture defines two different behaviors when 64-bit
registers are written with 32-bit writes.  The first behavior causes
zero extension into the upper 32-bits.  The second behavior splits a
64-bit register into "normal" 32-bit register pairs.

On some buggy implementations, registers incorrectly zero extended
when they should instead behave as normal 32-bit register pairs.

Signed-off-by: Tirumalesh Chalamarla <tchalamarla at caviumnetworks.com>

Changes from V2:
	- removed unused definitions

Changes from V1:
	- Introduced smmu_writeq
---
 drivers/iommu/arm-smmu.c | 57 +++++++++++++++++++++++++-----------------------
 1 file changed, 30 insertions(+), 27 deletions(-)

diff --git a/drivers/iommu/arm-smmu.c b/drivers/iommu/arm-smmu.c
index 66a803b..26572d6 100644
--- a/drivers/iommu/arm-smmu.c
+++ b/drivers/iommu/arm-smmu.c
@@ -69,6 +69,18 @@
 		((smmu->options & ARM_SMMU_OPT_SECURE_CFG_ACCESS)	\
 			? 0x400 : 0))
 
+#ifdef CONFIG_64BIT
+#define smmu_writeq(reg64, addr)	writeq_relaxed((reg64), (addr))
+#else
+#define smmu_writeq(reg64, addr)				\
+	do {							\
+		u64 __val = (reg64);				\
+		void __iomem *__addr = (addr);			\
+		writel_relaxed(__val >> 32, __addr + 4);	\
+		writel_relaxed(__val, __addr);			\
+	} while (0)
+#endif
+
 /* Configuration registers */
 #define ARM_SMMU_GR0_sCR0		0x0
 #define sCR0_CLIENTPD			(1 << 0)
@@ -184,10 +196,8 @@
 #define ARM_SMMU_CB_SCTLR		0x0
 #define ARM_SMMU_CB_RESUME		0x8
 #define ARM_SMMU_CB_TTBCR2		0x10
-#define ARM_SMMU_CB_TTBR0_LO		0x20
-#define ARM_SMMU_CB_TTBR0_HI		0x24
-#define ARM_SMMU_CB_TTBR1_LO		0x28
-#define ARM_SMMU_CB_TTBR1_HI		0x2c
+#define ARM_SMMU_CB_TTBR0		0x20
+#define ARM_SMMU_CB_TTBR1		0x28
 #define ARM_SMMU_CB_TTBCR		0x30
 #define ARM_SMMU_CB_S1_MAIR0		0x38
 #define ARM_SMMU_CB_S1_MAIR1		0x3c
@@ -202,8 +212,7 @@
 #define ARM_SMMU_CB_S1_TLBIVAL		0x620
 #define ARM_SMMU_CB_S2_TLBIIPAS2	0x630
 #define ARM_SMMU_CB_S2_TLBIIPAS2L	0x638
-#define ARM_SMMU_CB_ATS1PR_LO		0x800
-#define ARM_SMMU_CB_ATS1PR_HI		0x804
+#define ARM_SMMU_CB_ATS1PR		0x800
 #define ARM_SMMU_CB_ATSR		0x8f0
 
 #define SCTLR_S1_ASIDPNE		(1 << 12)
@@ -226,7 +235,7 @@
 #define TTBCR2_SEP_SHIFT		15
 #define TTBCR2_SEP_UPSTREAM		(0x7 << TTBCR2_SEP_SHIFT)
 
-#define TTBRn_HI_ASID_SHIFT            16
+#define TTBRn_ASID_SHIFT		48
 
 #define FSR_MULTI			(1 << 31)
 #define FSR_SS				(1 << 30)
@@ -719,6 +728,7 @@ static void arm_smmu_init_context_bank(struct arm_smmu_domain *smmu_domain,
 				       struct io_pgtable_cfg *pgtbl_cfg)
 {
 	u32 reg;
+	u64 reg64;
 	bool stage1;
 	struct arm_smmu_cfg *cfg = &smmu_domain->cfg;
 	struct arm_smmu_device *smmu = smmu_domain->smmu;
@@ -762,22 +772,17 @@ static void arm_smmu_init_context_bank(struct arm_smmu_domain *smmu_domain,
 
 	/* TTBRs */
 	if (stage1) {
-		reg = pgtbl_cfg->arm_lpae_s1_cfg.ttbr[0];
-		writel_relaxed(reg, cb_base + ARM_SMMU_CB_TTBR0_LO);
-		reg = pgtbl_cfg->arm_lpae_s1_cfg.ttbr[0] >> 32;
-		reg |= ARM_SMMU_CB_ASID(cfg) << TTBRn_HI_ASID_SHIFT;
-		writel_relaxed(reg, cb_base + ARM_SMMU_CB_TTBR0_HI);
-
-		reg = pgtbl_cfg->arm_lpae_s1_cfg.ttbr[1];
-		writel_relaxed(reg, cb_base + ARM_SMMU_CB_TTBR1_LO);
-		reg = pgtbl_cfg->arm_lpae_s1_cfg.ttbr[1] >> 32;
-		reg |= ARM_SMMU_CB_ASID(cfg) << TTBRn_HI_ASID_SHIFT;
-		writel_relaxed(reg, cb_base + ARM_SMMU_CB_TTBR1_HI);
+		reg64 = pgtbl_cfg->arm_lpae_s1_cfg.ttbr[0];
+
+		reg64 |= ((u64)ARM_SMMU_CB_ASID(cfg)) << TTBRn_ASID_SHIFT;
+		smmu_writeq(reg64, cb_base + ARM_SMMU_CB_TTBR0);
+
+		reg64 = pgtbl_cfg->arm_lpae_s1_cfg.ttbr[1];
+		reg64 |= ((u64)ARM_SMMU_CB_ASID(cfg)) << TTBRn_ASID_SHIFT;
+		smmu_writeq(reg64, cb_base + ARM_SMMU_CB_TTBR1);
 	} else {
-		reg = pgtbl_cfg->arm_lpae_s2_cfg.vttbr;
-		writel_relaxed(reg, cb_base + ARM_SMMU_CB_TTBR0_LO);
-		reg = pgtbl_cfg->arm_lpae_s2_cfg.vttbr >> 32;
-		writel_relaxed(reg, cb_base + ARM_SMMU_CB_TTBR0_HI);
+		reg64 = pgtbl_cfg->arm_lpae_s2_cfg.vttbr;
+		smmu_writeq(reg64, cb_base + ARM_SMMU_CB_TTBR0);
 	}
 
 	/* TTBCR */
@@ -1234,12 +1239,10 @@ static phys_addr_t arm_smmu_iova_to_phys_hard(struct iommu_domain *domain,
 
 	if (smmu->version == 1) {
 		u32 reg = iova & ~0xfff;
-		writel_relaxed(reg, cb_base + ARM_SMMU_CB_ATS1PR_LO);
+		writel_relaxed(reg, cb_base + ARM_SMMU_CB_ATS1PR);
 	} else {
-		u32 reg = iova & ~0xfff;
-		writel_relaxed(reg, cb_base + ARM_SMMU_CB_ATS1PR_LO);
-		reg = ((u64)iova & ~0xfff) >> 32;
-		writel_relaxed(reg, cb_base + ARM_SMMU_CB_ATS1PR_HI);
+		u64 reg64 = iova & ~0xfff;
+		smmu_writeq(reg64, cb_base + ARM_SMMU_CB_ATS1PR);
 	}
 
 	if (readl_poll_timeout_atomic(cb_base + ARM_SMMU_CB_ATSR, tmp,
-- 
2.1.0



From mturquette at linaro.org  Mon Aug 17 16:22:35 2015
From: mturquette at linaro.org (Michael Turquette)
Date: Mon, 17 Aug 2015 16:22:35 -0700
Subject: [PATCH v4 RESEND 1/3] clk: Add regmap support
In-Reply-To: <1438355659-21558-2-git-send-email-matthias.bgg@gmail.com>
References: <1438355659-21558-1-git-send-email-matthias.bgg@gmail.com>
 <1438355659-21558-2-git-send-email-matthias.bgg@gmail.com>
Message-ID: <20150817232235.31346.30218@quantum>

Quoting Matthias Brugger (2015-07-31 08:14:17)
> diff --git a/drivers/clk/clk-io.c b/drivers/clk/clk-io.c
> new file mode 100644
> index 0000000..9630ef5
> --- /dev/null
> +++ b/drivers/clk/clk-io.c
> @@ -0,0 +1,48 @@
> +/*
> + * Copyright (C) 2015 Matthias Brugger <matthias.bgg at gmail.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.
> + *
> + */
> +
> +#include <linux/clk-provider.h>
> +
> +void clk_io_writel(struct clk_hw *hw, void __iomem *reg, struct regmap *regmap,
> +                       u32 offset, u32 val)
> +{
> +       if (__clk_get_flags(hw->clk) & CLK_USE_REGMAP)
> +               regmap_write(regmap, offset, val);
> +       else
> +               clk_writel(val, reg);
> +}

So we have clk_writel, which already wraps direct io accesses depending
on arch/platform, and then this patch adds regmap support, and both of
those are wrapped in clk_io_writel? :-/

I agree that we should merge some unified regmap support into the clock
framework for the basic clocks, but I do not think that this is the
right way to do it. This patch simply adds more code to already crowded
basic clock types.

Replacing the basic clock types by separating policy and machine-driver
code into separate, modular pieces is a high priority on my todo list.
I'd like to do that first and then revisit regmap clocks instead of
merging this series as-is.

Regards,
Mike


From mathieu at codeaurora.org  Mon Aug 17 16:47:43 2015
From: mathieu at codeaurora.org (Mathieu Olivari)
Date: Mon, 17 Aug 2015 16:47:43 -0700
Subject: [PATCH v3 0/3] qcom: Add SMEM MTD parser
Message-ID: <1439855266-26242-1-git-send-email-mathieu@codeaurora.org>

QCOM platforms such as IPQ806x are using SMEM to store their flash
layout. This patch set adds the DT nodes required to instanciate SMEM
on IPQ806x and add an MTD parser using it.

This change is based on the SMEM driver posted here:
*https://lkml.org/lkml/2015/7/27/1125

v2:
*Release the SPI device reference after looking it up (put_device())
*Represent SMEM data as __le32 rather than u32
*Move new DT nodes in their proper respective location
*Address readability concerns in MTD parser

v3:
*Address Bjorn's comments

Mathieu Olivari (3):
  ARM: qcom: add SFPB nodes to IPQ806x dts
  ARM: qcom: add SMEM device node to IPQ806x dts
  mtd: add SMEM parser for QCOM platforms

 arch/arm/boot/dts/qcom-ipq8064.dtsi |  23 +++-
 drivers/mtd/Kconfig                 |   7 ++
 drivers/mtd/Makefile                |   1 +
 drivers/mtd/qcom_smem_part.c        | 224 ++++++++++++++++++++++++++++++++++++
 4 files changed, 254 insertions(+), 1 deletion(-)
 create mode 100644 drivers/mtd/qcom_smem_part.c

-- 
2.1.4



From mathieu at codeaurora.org  Mon Aug 17 16:47:44 2015
From: mathieu at codeaurora.org (Mathieu Olivari)
Date: Mon, 17 Aug 2015 16:47:44 -0700
Subject: [PATCH v3 1/3] ARM: qcom: add SFPB nodes to IPQ806x dts
In-Reply-To: <1439855266-26242-1-git-send-email-mathieu@codeaurora.org>
References: <1439855266-26242-1-git-send-email-mathieu@codeaurora.org>
Message-ID: <1439855266-26242-2-git-send-email-mathieu@codeaurora.org>

Add one new node to the ipq806x.dtsi file to declare & register the
hardware spinlock devices. This mechanism is required to be used by
other drivers such as SMEM.

Signed-off-by: Mathieu Olivari <mathieu at codeaurora.org>
---
 arch/arm/boot/dts/qcom-ipq8064.dtsi | 11 +++++++++++
 1 file changed, 11 insertions(+)

diff --git a/arch/arm/boot/dts/qcom-ipq8064.dtsi b/arch/arm/boot/dts/qcom-ipq8064.dtsi
index 9f727d8..8d366ae 100644
--- a/arch/arm/boot/dts/qcom-ipq8064.dtsi
+++ b/arch/arm/boot/dts/qcom-ipq8064.dtsi
@@ -329,5 +329,16 @@
 			#reset-cells = <1>;
 		};
 
+		sfpb_mutex_block: syscon at 1200600 {
+			compatible = "syscon";
+			reg = <0x01200600 0x100>;
+		};
+	};
+
+	sfpb_mutex: sfpb-mutex {
+		compatible = "qcom,sfpb-mutex";
+		syscon = <&sfpb_mutex_block 4 4>;
+
+		#hwlock-cells = <1>;
 	};
 };
-- 
2.1.4



From mathieu at codeaurora.org  Mon Aug 17 16:47:45 2015
From: mathieu at codeaurora.org (Mathieu Olivari)
Date: Mon, 17 Aug 2015 16:47:45 -0700
Subject: [PATCH v3 2/3] ARM: qcom: add SMEM device node to IPQ806x dts
In-Reply-To: <1439855266-26242-1-git-send-email-mathieu@codeaurora.org>
References: <1439855266-26242-1-git-send-email-mathieu@codeaurora.org>
Message-ID: <1439855266-26242-3-git-send-email-mathieu@codeaurora.org>

SMEM is used on IPQ806x to store various board related information such
as boot device and flash partition layout. We'll declare it as a device
so we can make use of it thanks to the new SMEM soc driver.

Signed-off-by: Mathieu Olivari <mathieu at codeaurora.org>
---
 arch/arm/boot/dts/qcom-ipq8064.dtsi | 8 +++++++-
 1 file changed, 7 insertions(+), 1 deletion(-)

diff --git a/arch/arm/boot/dts/qcom-ipq8064.dtsi b/arch/arm/boot/dts/qcom-ipq8064.dtsi
index 8d366ae..85dbccf 100644
--- a/arch/arm/boot/dts/qcom-ipq8064.dtsi
+++ b/arch/arm/boot/dts/qcom-ipq8064.dtsi
@@ -55,7 +55,7 @@
 			no-map;
 		};
 
-		smem at 41000000 {
+		smem: smem at 41000000 {
 			reg = <0x41000000 0x200000>;
 			no-map;
 		};
@@ -341,4 +341,10 @@
 
 		#hwlock-cells = <1>;
 	};
+
+	smem {
+		compatible = "qcom,smem";
+		memory-region = <&smem>;
+		hwlocks = <&sfpb_mutex 3>;
+	};
 };
-- 
2.1.4



From mathieu at codeaurora.org  Mon Aug 17 16:47:46 2015
From: mathieu at codeaurora.org (Mathieu Olivari)
Date: Mon, 17 Aug 2015 16:47:46 -0700
Subject: [PATCH v3 3/3] mtd: add SMEM parser for QCOM platforms
In-Reply-To: <1439855266-26242-1-git-send-email-mathieu@codeaurora.org>
References: <1439855266-26242-1-git-send-email-mathieu@codeaurora.org>
Message-ID: <1439855266-26242-4-git-send-email-mathieu@codeaurora.org>

On QCOM platforms using MTD devices storage (such as IPQ806x), SMEM is
used to store partition layout. This new parser can now be used to read
SMEM and use it to register an MTD layout according to its content.

Signed-off-by: Mathieu Olivari <mathieu at codeaurora.org>
---

Notes:
    v2:
    *Release the SPI device reference after looking it up (put_device())
    *Represent SMEM data as __le32 rather than u32
    *Move new DT nodes in their proper respective location
    *Address readability concerns in MTD parser
    
    v3:
    *Redefine SMEM functions prototypes for better readability
    *Duplicate MTD name instead of pointing to SMEM string location in case
     mtd layer tries to free it
    *Rework some of the comments

 drivers/mtd/Kconfig          |   7 ++
 drivers/mtd/Makefile         |   1 +
 drivers/mtd/qcom_smem_part.c | 246 +++++++++++++++++++++++++++++++++++++++++++
 3 files changed, 254 insertions(+)
 create mode 100644 drivers/mtd/qcom_smem_part.c

diff --git a/drivers/mtd/Kconfig b/drivers/mtd/Kconfig
index a03ad29..debc887 100644
--- a/drivers/mtd/Kconfig
+++ b/drivers/mtd/Kconfig
@@ -155,6 +155,13 @@ config MTD_BCM47XX_PARTS
 	  This provides partitions parser for devices based on BCM47xx
 	  boards.
 
+config MTD_QCOM_SMEM_PARTS
+	tristate "QCOM SMEM partitioning support"
+	depends on QCOM_SMEM
+	help
+	  This provides partitions parser for QCOM devices using SMEM
+	  such as IPQ806x.
+
 comment "User Modules And Translation Layers"
 
 #
diff --git a/drivers/mtd/Makefile b/drivers/mtd/Makefile
index 99bb9a1..b3c7de4 100644
--- a/drivers/mtd/Makefile
+++ b/drivers/mtd/Makefile
@@ -13,6 +13,7 @@ obj-$(CONFIG_MTD_AFS_PARTS)	+= afs.o
 obj-$(CONFIG_MTD_AR7_PARTS)	+= ar7part.o
 obj-$(CONFIG_MTD_BCM63XX_PARTS)	+= bcm63xxpart.o
 obj-$(CONFIG_MTD_BCM47XX_PARTS)	+= bcm47xxpart.o
+obj-$(CONFIG_MTD_QCOM_SMEM_PARTS) += qcom_smem_part.o
 
 # 'Users' - code which presents functionality to userspace.
 obj-$(CONFIG_MTD_BLKDEVS)	+= mtd_blkdevs.o
diff --git a/drivers/mtd/qcom_smem_part.c b/drivers/mtd/qcom_smem_part.c
new file mode 100644
index 0000000..cb7ea9a
--- /dev/null
+++ b/drivers/mtd/qcom_smem_part.c
@@ -0,0 +1,246 @@
+/*
+ * Copyright (c) 2015, The Linux Foundation. All rights reserved.
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License version 2 and
+ * only 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/kernel.h>
+#include <linux/device.h>
+#include <linux/slab.h>
+
+#include <linux/mtd/mtd.h>
+#include <linux/mtd/partitions.h>
+#include <linux/spi/spi.h>
+#include <linux/module.h>
+
+#include <linux/soc/qcom/smem.h>
+
+/* Processor/host identifier for the application processor */
+#define QCOM_SMEM_GLOBAL		0
+
+/* SMEM items index */
+#define SMEM_AARM_PARTITION_TABLE	9
+#define SMEM_BOOT_FLASH_TYPE		421
+#define SMEM_BOOT_FLASH_BLOCK_SIZE	424
+
+/* SMEM Flash types */
+#define SMEM_FLASH_NAND			2
+#define SMEM_FLASH_SPI			6
+
+#define SMEM_PART_NAME_SZ		16
+#define SMEM_PARTS_MAX			32
+
+struct smem_partition {
+	char name[SMEM_PART_NAME_SZ];
+	__le32 start;
+	__le32 size;
+	__le32 attr;
+};
+
+struct smem_partition_table {
+	u8 magic[8];
+	__le32 version;
+	__le32 len;
+	struct smem_partition parts[SMEM_PARTS_MAX];
+};
+
+/* SMEM Magic values in partition table */
+static const u8 SMEM_PTABLE_MAGIC[] = {
+	0xaa, 0x73, 0xee, 0x55,
+	0xdb, 0xbd, 0x5e, 0xe3,
+};
+
+static int qcom_smem_get_flash_blksz(void)
+{
+	int ret;
+	size_t size;
+	u64 *smem_blksz;
+
+	ret = qcom_smem_get(QCOM_SMEM_GLOBAL, SMEM_BOOT_FLASH_BLOCK_SIZE,
+			    (void **) &smem_blksz, &size);
+
+	if (ret < 0) {
+		pr_err("Unable to read flash blksz from SMEM\n");
+		return -ENOENT;
+	}
+
+	if (size != sizeof(*smem_blksz)) {
+		pr_err("Invalid flash blksz size in SMEM\n");
+		return -EINVAL;
+	}
+
+	/* Sanity check block size value before casting it */
+	if (*smem_blksz > INT_MAX) {
+		pr_err("Invalid flash block size in SMEM\n");
+		return -EINVAL;
+	}
+
+	return (int) *smem_blksz;
+}
+
+static int qcom_smem_get_flash_type(void)
+{
+	int ret;
+	size_t size;
+	u64 *smem_flash_type;
+
+	ret = qcom_smem_get(QCOM_SMEM_GLOBAL, SMEM_BOOT_FLASH_TYPE,
+			    (void **) &smem_flash_type, &size);
+
+	if (ret < 0) {
+		pr_err("Unable to read flash type from SMEM\n");
+		return -ENOENT;
+	}
+
+	if (size != sizeof(*smem_flash_type)) {
+		pr_err("Invalid flash type size in SMEM\n");
+		return -EINVAL;
+	}
+
+	/* Sanity check flash type value before casting it */
+	if (*smem_flash_type > INT_MAX) {
+		pr_err("Invalid flash type in SMEM\n");
+		return -EINVAL;
+	}
+
+	return (int) *smem_flash_type;
+}
+
+static struct smem_partition *qcom_smem_get_flash_partitions(size_t *count)
+{
+	struct smem_partition_table *smem_parts;
+	int ret;
+
+	ret = qcom_smem_get(QCOM_SMEM_GLOBAL, SMEM_AARM_PARTITION_TABLE,
+			    (void **) &smem_parts, NULL);
+
+	if (ret < 0) {
+		pr_err("Unable to read partition table from SMEM\n");
+		return ERR_PTR(-ENOENT);
+	}
+
+	if (memcmp(SMEM_PTABLE_MAGIC, smem_parts->magic,
+		   sizeof(SMEM_PTABLE_MAGIC))) {
+		pr_err("SMEM partition magic invalid\n");
+		return ERR_PTR(-EINVAL);
+	}
+
+	if (le32_to_cpu(smem_parts->version) != 3) {
+		pr_err("SMEM version unsupported\n");
+		return ERR_PTR(-EINVAL);
+	}
+
+	*count = le32_to_cpu(smem_parts->len);
+
+	return smem_parts->parts;
+}
+
+static int of_dev_node_match(struct device *dev, void *data)
+{
+	return dev->of_node == data;
+}
+
+static bool is_spi_device(struct device_node *np)
+{
+	struct device *dev;
+
+	dev = bus_find_device(&spi_bus_type, NULL, np, of_dev_node_match);
+	if (!dev)
+		return false;
+
+	put_device(dev);
+	return true;
+}
+
+static int parse_qcom_smem_partitions(struct mtd_info *master,
+				      struct mtd_partition **pparts,
+				      struct mtd_part_parser_data *data)
+{
+	struct smem_partition *smem_part;
+	int smem_flash_type, smem_blksz;
+	size_t nbparts = 0, len;
+	struct mtd_partition *mtd_parts;
+	struct device_node *of_node = data->of_node;
+
+	/* Only parse partitions on the specified memory type */
+	smem_flash_type = qcom_smem_get_flash_type();
+	if (smem_flash_type < 0)
+		return smem_flash_type;
+
+	if ((smem_flash_type == SMEM_FLASH_NAND && !mtd_type_is_nand(master))
+	    || (smem_flash_type == SMEM_FLASH_SPI && !is_spi_device(of_node)))
+		return 0;
+
+	/* Make sure the block size in SMEM matches the block size in MTD */
+	smem_blksz = qcom_smem_get_flash_blksz();
+	if (smem_blksz < 0)
+		return smem_blksz;
+
+	if (smem_blksz != master->erasesize) {
+		pr_err("SMEM block size differs from MTD block size\n");
+		return -EINVAL;
+	}
+
+	/* Get partition pointer from SMEM */
+	smem_part = qcom_smem_get_flash_partitions(&nbparts);
+	if (IS_ERR_OR_NULL(smem_part))
+		return -EINVAL;
+
+	/* Allocate and populate the mtd structures */
+	mtd_parts = kcalloc(nbparts, sizeof(*mtd_parts), GFP_KERNEL);
+	if (!mtd_parts)
+		return -ENOMEM;
+
+	*pparts = mtd_parts;
+	len = nbparts;
+
+	while (len--) {
+		mtd_parts->name = kstrdup(smem_part->name, GFP_KERNEL);
+		mtd_parts->size = le32_to_cpu(smem_part->size) * smem_blksz;
+		mtd_parts->offset = le32_to_cpu(smem_part->start) * smem_blksz;
+
+		/*
+		 * The last SMEM partition may have its size marked as
+		 * something like 0xffffffff, which means "until the end of the
+		 * flash device". In this case, truncate it.
+		 */
+		if (mtd_parts->offset + mtd_parts->size > master->size)
+			mtd_parts->size = master->size - mtd_parts->offset;
+
+		smem_part++;
+		mtd_parts++;
+	}
+
+	return nbparts;
+}
+
+static struct mtd_part_parser qcom_smem_parser = {
+	.owner = THIS_MODULE,
+	.parse_fn = parse_qcom_smem_partitions,
+	.name = "qcom-smem",
+};
+
+static int __init qcom_smem_parser_init(void)
+{
+	register_mtd_parser(&qcom_smem_parser);
+	return 0;
+}
+
+static void __exit qcom_smem_parser_exit(void)
+{
+	deregister_mtd_parser(&qcom_smem_parser);
+}
+
+module_init(qcom_smem_parser_init);
+module_exit(qcom_smem_parser_exit);
+
+MODULE_LICENSE("GPL V2");
+MODULE_AUTHOR("Mathieu Olivari <mathieu at codeaurora.org>");
+MODULE_DESCRIPTION("Parsing code for SMEM based partition tables");
-- 
2.1.4



From timur at codeaurora.org  Mon Aug 17 16:56:10 2015
From: timur at codeaurora.org (Timur Tabi)
Date: Mon, 17 Aug 2015 18:56:10 -0500
Subject: [PATCH 2/3] [v4] ARM64: TTY: hvc_dcc: Add support for ARM64 dcc
In-Reply-To: <20150810094008.GD1604@arm.com>
References: <1438992995-22610-1-git-send-email-timur@codeaurora.org>
 <1438992995-22610-2-git-send-email-timur@codeaurora.org>
 <20150810094008.GD1604@arm.com>
Message-ID: <55D2749A.401@codeaurora.org>

On 08/10/2015 04:40 AM, Will Deacon wrote:
>> >+static inline void __dcc_putchar(char c)
>> >+{
>> >+	asm volatile("msr dbgdtrtx_el0, %0"
>> >+			: /* No output register */
>> >+			: "r" (c));
>> >+	isb();

> I think we should be masking out the upper bits of c before the msr
> (the compiler probably expects a uxtb).

Well, we've never seen a problem, but that doesn't mean it doesn't 
exist.  I couldn't find anything in the ARMv8 ARM (section H9.2.7 
DBGDTRTX_EL0) about word sizes.

Do you think that I need an explicit instruction to clear the upper 
bits?  I tried a few compiler tricks (e.g. "c && 0xff" and the like), 
and they had no effect.

I do need help with the inline assembly.  I tried this:

static inline void __dcc_putchar(char c)
{
	unsigned int __c;

	asm volatile("uxtb %0, %w1\n"
		"msr dbgdtrtx_el0, %0"
			: "=r" (__c)
			: "r" (c));
	isb();
}

it gives this assembly code:

   28:	38401423 	ldrb	w3, [x1],#1
   2c:	53001c63 	uxtb	w3, w3
   30:	d5130503 	msr	dbgdtrrx_el0, x3

Is this correct?  Shouldn't it be "uxtb x3, w3"?

-- 
Qualcomm Innovation Center, Inc.
The Qualcomm Innovation Center, Inc. is a member of the
Code Aurora Forum, a Linux Foundation Collaborative Project.


From mturquette at baylibre.com  Mon Aug 17 16:57:04 2015
From: mturquette at baylibre.com (Michael Turquette)
Date: Mon, 17 Aug 2015 16:57:04 -0700
Subject: [RESEND PATCH v5] clk: mediatek: Export CPU mux clocks for CPU
 frequency control
In-Reply-To: <1439801805-19043-1-git-send-email-pi-cheng.chen@linaro.org>
References: <1439801805-19043-1-git-send-email-pi-cheng.chen@linaro.org>
Message-ID: <20150817235704.31346.92895@quantum>

Quoting Pi-Cheng Chen (2015-08-17 01:56:45)
> From: "pi-cheng.chen" <pi-cheng.chen at linaro.org>
> 
> This patch adds CPU mux clocks which are used by Mediatek cpufreq driver
> for intermediate clock source switching.
> 
> Signed-off-by: Pi-Cheng Chen <pi-cheng.chen at linaro.org>
> Reviewed-by: Daniel Kurtz <djkurtz at chromium.org>

Looks OK to me. Can I expect an mtk clk pull request? I think that the
only mtk patches outstanding are this one and the 13MHz clk patch but I
want to double check with you guys.

Regards,
Mike

> ---
> Changes in v5:
> - Replace __initdata with __initconst to fix compiling error
> 
> Changes in v4:
> - Fix some minor issues for v3
> - Rebase to the patch that adds 13mhz clock for MT8173[1]
> 
> Changes in v3:
> - Rebase to 4.2-rc1
> - Fix some issues of v2
> 
> Changes in v2:
> - Remove use of .determine_rate callback
> 
> [1] http://patchwork.kernerl.xyz/patch/6777041/
> ---
>  drivers/clk/mediatek/Makefile          |   2 +-
>  drivers/clk/mediatek/clk-cpumux.c      | 127 +++++++++++++++++++++++++++++++++
>  drivers/clk/mediatek/clk-cpumux.h      |  22 ++++++
>  drivers/clk/mediatek/clk-mt8173.c      |  23 ++++++
>  include/dt-bindings/clock/mt8173-clk.h |   4 +-
>  5 files changed, 176 insertions(+), 2 deletions(-)
>  create mode 100644 drivers/clk/mediatek/clk-cpumux.c
>  create mode 100644 drivers/clk/mediatek/clk-cpumux.h
> 
> diff --git a/drivers/clk/mediatek/Makefile b/drivers/clk/mediatek/Makefile
> index 8e4b2a4..299917a 100644
> --- a/drivers/clk/mediatek/Makefile
> +++ b/drivers/clk/mediatek/Makefile
> @@ -1,4 +1,4 @@
> -obj-y += clk-mtk.o clk-pll.o clk-gate.o
> +obj-y += clk-mtk.o clk-pll.o clk-gate.o clk-cpumux.o
>  obj-$(CONFIG_RESET_CONTROLLER) += reset.o
>  obj-y += clk-mt8135.o
>  obj-y += clk-mt8173.o
> diff --git a/drivers/clk/mediatek/clk-cpumux.c b/drivers/clk/mediatek/clk-cpumux.c
> new file mode 100644
> index 0000000..fb04fe1
> --- /dev/null
> +++ b/drivers/clk/mediatek/clk-cpumux.c
> @@ -0,0 +1,127 @@
> +/*
> + * Copyright (c) 2015 Linaro Ltd.
> + * Author: Pi-Cheng Chen <pi-cheng.chen at linaro.org>
> + *
> + * This program is free software; you can redistribute it and/or modify
> + * it under the terms of the GNU General Public License version 2 as
> + * published by the Free Software Foundation.
> + *
> + * 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/mfd/syscon.h>
> +#include <linux/slab.h>
> +
> +#include "clk-mtk.h"
> +#include "clk-cpumux.h"
> +
> +struct mtk_clk_cpumux {
> +       struct clk_hw   hw;
> +       struct regmap   *regmap;
> +       u32             reg;
> +       u32             mask;
> +       u8              shift;
> +};
> +
> +static inline struct mtk_clk_cpumux *to_clk_mux(struct clk_hw *_hw)
> +{
> +       return container_of(_hw, struct mtk_clk_cpumux, hw);
> +}
> +
> +static u8 clk_cpumux_get_parent(struct clk_hw *hw)
> +{
> +       struct mtk_clk_cpumux *mux = to_clk_mux(hw);
> +       int num_parents = __clk_get_num_parents(hw->clk);
> +       unsigned int val;
> +
> +       regmap_read(mux->regmap, mux->reg, &val);
> +
> +       val >>= mux->shift;
> +       val &= mux->mask;
> +
> +       if (val >= num_parents)
> +               return -EINVAL;
> +
> +       return val;
> +}
> +
> +static int clk_cpumux_set_parent(struct clk_hw *hw, u8 index)
> +{
> +       struct mtk_clk_cpumux *mux = to_clk_mux(hw);
> +       u32 mask, val;
> +
> +       val = index << mux->shift;
> +       mask = mux->mask << mux->shift;
> +
> +       return regmap_update_bits(mux->regmap, mux->reg, mask, val);
> +}
> +
> +static const struct clk_ops clk_cpumux_ops = {
> +       .get_parent = clk_cpumux_get_parent,
> +       .set_parent = clk_cpumux_set_parent,
> +};
> +
> +static struct clk __init *mtk_clk_register_cpumux(const struct mtk_composite *mux,
> +                                          struct regmap *regmap)
> +{
> +       struct mtk_clk_cpumux *cpumux;
> +       struct clk *clk;
> +       struct clk_init_data init;
> +
> +       cpumux = kzalloc(sizeof(*cpumux), GFP_KERNEL);
> +       if (!cpumux)
> +               return ERR_PTR(-ENOMEM);
> +
> +       init.name = mux->name;
> +       init.ops = &clk_cpumux_ops;
> +       init.parent_names = mux->parent_names;
> +       init.num_parents = mux->num_parents;
> +       init.flags = mux->flags;
> +
> +       cpumux->reg = mux->mux_reg;
> +       cpumux->shift = mux->mux_shift;
> +       cpumux->mask = BIT(mux->mux_width) - 1;
> +       cpumux->regmap = regmap;
> +       cpumux->hw.init = &init;
> +
> +       clk = clk_register(NULL, &cpumux->hw);
> +       if (IS_ERR(clk))
> +               kfree(cpumux);
> +
> +       return clk;
> +}
> +
> +int __init mtk_clk_register_cpumuxes(struct device_node *node,
> +                             const struct mtk_composite *clks, int num,
> +                             struct clk_onecell_data *clk_data)
> +{
> +       int i;
> +       struct clk *clk;
> +       struct regmap *regmap;
> +
> +       regmap = syscon_node_to_regmap(node);
> +       if (IS_ERR(regmap)) {
> +               pr_err("Cannot find regmap for %s: %ld\n", node->full_name,
> +                      PTR_ERR(regmap));
> +               return PTR_ERR(regmap);
> +       }
> +
> +       for (i = 0; i < num; i++) {
> +               const struct mtk_composite *mux = &clks[i];
> +
> +               clk = mtk_clk_register_cpumux(mux, regmap);
> +               if (IS_ERR(clk)) {
> +                       pr_err("Failed to register clk %s: %ld\n",
> +                              mux->name, PTR_ERR(clk));
> +                       continue;
> +               }
> +
> +               clk_data->clks[mux->id] = clk;
> +       }
> +
> +       return 0;
> +}
> diff --git a/drivers/clk/mediatek/clk-cpumux.h b/drivers/clk/mediatek/clk-cpumux.h
> new file mode 100644
> index 0000000..52c769f
> --- /dev/null
> +++ b/drivers/clk/mediatek/clk-cpumux.h
> @@ -0,0 +1,22 @@
> +/*
> + * Copyright (c) 2015 Linaro Ltd.
> + * Author: Pi-Cheng Chen <pi-cheng.chen at linaro.org>
> + *
> + * This program is free software; you can redistribute it and/or modify
> + * it under the terms of the GNU General Public License version 2 as
> + * published by the Free Software Foundation.
> + *
> + * 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 __DRV_CLK_CPUMUX_H
> +#define __DRV_CLK_CPUMUX_H
> +
> +int mtk_clk_register_cpumuxes(struct device_node *node,
> +                             const struct mtk_composite *clks, int num,
> +                             struct clk_onecell_data *clk_data);
> +
> +#endif /* __DRV_CLK_CPUMUX_H */
> diff --git a/drivers/clk/mediatek/clk-mt8173.c b/drivers/clk/mediatek/clk-mt8173.c
> index 540c5c3..053ca27 100644
> --- a/drivers/clk/mediatek/clk-mt8173.c
> +++ b/drivers/clk/mediatek/clk-mt8173.c
> @@ -19,6 +19,7 @@
>  
>  #include "clk-mtk.h"
>  #include "clk-gate.h"
> +#include "clk-cpumux.h"
>  
>  #include <dt-bindings/clock/mt8173-clk.h>
>  
> @@ -517,6 +518,25 @@ static const char * const i2s3_b_ck_parents[] __initconst = {
>         "apll2_div5"
>  };
>  
> +static const char * const ca53_parents[] __initconst = {
> +       "clk26m",
> +       "armca7pll",
> +       "mainpll",
> +       "univpll"
> +};
> +
> +static const char * const ca57_parents[] __initconst = {
> +       "clk26m",
> +       "armca15pll",
> +       "mainpll",
> +       "univpll"
> +};
> +
> +static const struct mtk_composite cpu_muxes[] __initconst = {
> +       MUX(CLK_INFRA_CA53SEL, "infra_ca53_sel", ca53_parents, 0x0000, 0, 2),
> +       MUX(CLK_INFRA_CA57SEL, "infra_ca57_sel", ca57_parents, 0x0000, 2, 2),
> +};
> +
>  static const struct mtk_composite top_muxes[] __initconst = {
>         /* CLK_CFG_0 */
>         MUX(CLK_TOP_AXI_SEL, "axi_sel", axi_parents, 0x0040, 0, 3),
> @@ -743,6 +763,9 @@ static void __init mtk_infrasys_init(struct device_node *node)
>                                                 clk_data);
>         mtk_clk_register_factors(infra_divs, ARRAY_SIZE(infra_divs), clk_data);
>  
> +       mtk_clk_register_cpumuxes(node, cpu_muxes, ARRAY_SIZE(cpu_muxes),
> +                                               clk_data);
> +
>         r = of_clk_add_provider(node, of_clk_src_onecell_get, clk_data);
>         if (r)
>                 pr_err("%s(): could not register clock provider: %d\n",
> diff --git a/include/dt-bindings/clock/mt8173-clk.h b/include/dt-bindings/clock/mt8173-clk.h
> index fa2a2bb..a17cbaa 100644
> --- a/include/dt-bindings/clock/mt8173-clk.h
> +++ b/include/dt-bindings/clock/mt8173-clk.h
> @@ -188,7 +188,9 @@
>  #define CLK_INFRA_PMICSPI              10
>  #define CLK_INFRA_PMICWRAP             11
>  #define CLK_INFRA_CLK_13M              12
> -#define CLK_INFRA_NR_CLK               13
> +#define CLK_INFRA_CA53SEL              13
> +#define CLK_INFRA_CA57SEL              14
> +#define CLK_INFRA_NR_CLK               15
>  
>  /* PERI_SYS */
>  
> -- 
> 1.9.1
> 
> --
> To unsubscribe from this list: send the line "unsubscribe linux-kernel" in
> the body of a message to majordomo at vger.kernel.org
> More majordomo info at  http://vger.kernel.org/majordomo-info.html
> Please read the FAQ at  http://www.tux.org/lkml/


From klimov.linux at gmail.com  Mon Aug 17 17:12:02 2015
From: klimov.linux at gmail.com (Alexey Klimov)
Date: Tue, 18 Aug 2015 03:12:02 +0300
Subject: [PATCH 2/5] net: add Hisilicon Network Subsystem hnae framework
 support
In-Reply-To: <1439548222-231611-3-git-send-email-liguozhu@hisilicon.com>
References: <1439548222-231611-1-git-send-email-liguozhu@hisilicon.com>
 <1439548222-231611-3-git-send-email-liguozhu@hisilicon.com>
Message-ID: <CALW4P+J8LkLshu5TuRT+8c__KRwJ8XAdMV4yA0KEnrfUg=mNow@mail.gmail.com>

Hi Kenneth,

just small minor question.

On Fri, Aug 14, 2015 at 1:30 PM, Kenneth Lee <liguozhu at hisilicon.com> wrote:
> HNAE (Hisilicon Network Acceleration Engine) is a framework to provide a
> unified ring buffer interface for Hisilicon Network Acceleration Engines.
>
> With the interface, upper layer can work as ethernet driver, ODP driver or
> other service driver on purpose.
>
> Signed-off-by: Kenneth Lee <liguozhu at huawei.com>
> Signed-off-by: Yisen Zhuang <Yisen.Zhuang at huawei.com>
> ---
>  drivers/net/ethernet/hisilicon/Kconfig      |  33 +-
>  drivers/net/ethernet/hisilicon/Makefile     |   1 +
>  drivers/net/ethernet/hisilicon/hns/Makefile |  15 +
>  drivers/net/ethernet/hisilicon/hns/hnae.c   | 494 +++++++++++++++++++++++
>  drivers/net/ethernet/hisilicon/hns/hnae.h   | 582 ++++++++++++++++++++++++++++
>  5 files changed, 1124 insertions(+), 1 deletion(-)
>  create mode 100644 drivers/net/ethernet/hisilicon/hns/Makefile
>  create mode 100644 drivers/net/ethernet/hisilicon/hns/hnae.c
>  create mode 100644 drivers/net/ethernet/hisilicon/hns/hnae.h
>
> diff --git a/drivers/net/ethernet/hisilicon/Kconfig b/drivers/net/ethernet/hisilicon/Kconfig
> index dead17b..1e4f5a7 100644
> --- a/drivers/net/ethernet/hisilicon/Kconfig
> +++ b/drivers/net/ethernet/hisilicon/Kconfig
> @@ -5,7 +5,7 @@
>  config NET_VENDOR_HISILICON
>         bool "Hisilicon devices"
>         default y
> -       depends on ARM
> +       depends on ARM || ARM64
>         ---help---
>           If you have a network (Ethernet) card belonging to this class, say Y.
>
> @@ -31,4 +31,35 @@ config HIP04_ETH
>           If you wish to compile a kernel for a hardware with hisilicon p04 SoC and
>           want to use the internal ethernet then you should answer Y to this.
>
> +config HNS
> +       tristate "Hisilicon Network Subsystem Support (Framework)"
> +       ---help---
> +         This selects the framework support for Hisilicon Network Subsystem. It
> +         is needed by any driver which provides HNS acceleration engine or make
> +         use of the engine
> +
> +config HNS_DSAF
> +       tristate "Hisilicon HNS DSAF device Support"
> +       select HNS
> +       select HNS_MDIO
> +       ---help---
> +         This selects the DSAF (Distributed System Area Frabric) network
> +         acceleration engine support. The engine is used in Hisilicon P660,
> +         Hi1610 and further ICT SoC
> +
> +config HNS_MDIO
> +       tristate "Hisilicon HNS MDIO device Support"
> +       select MDIO
> +       ---help---
> +         This selects the HNS MDIO support. It is needed by HNS_DSAF to access
> +         the PHY
> +
> +config HNS_ENET
> +       tristate "Hisilicon HNS Ethernet Device Support"
> +       select PHYLIB
> +       select HNS
> +       ---help---
> +         This selects the general ethernet driver for HNS.  This module make
> +         use of any HNS AE driver, such as HNS_DSAF
> +
>  endif # NET_VENDOR_HISILICON
> diff --git a/drivers/net/ethernet/hisilicon/Makefile b/drivers/net/ethernet/hisilicon/Makefile
> index 6c14540..2503a9b 100644
> --- a/drivers/net/ethernet/hisilicon/Makefile
> +++ b/drivers/net/ethernet/hisilicon/Makefile
> @@ -4,3 +4,4 @@
>
>  obj-$(CONFIG_HIX5HD2_GMAC) += hix5hd2_gmac.o
>  obj-$(CONFIG_HIP04_ETH) += hip04_mdio.o hip04_eth.o
> +obj-$(CONFIG_HNS) += hns/
> diff --git a/drivers/net/ethernet/hisilicon/hns/Makefile b/drivers/net/ethernet/hisilicon/hns/Makefile
> new file mode 100644
> index 0000000..6680602
> --- /dev/null
> +++ b/drivers/net/ethernet/hisilicon/hns/Makefile
> @@ -0,0 +1,15 @@
> +#
> +# Makefile for the HISILICON network device drivers.
> +#
> +
> +obj-$(CONFIG_HNS) += hnae.o
> +
> +obj-$(CONFIG_HNS_DSAF) += hns_dsaf.o
> +hns_dsaf-objs = hns_ae_adapt.o hns_dsaf_gmac.o hns_dsaf_mac.o hns_dsaf_misc.o \
> +       hns_dsaf_main.o hns_dsaf_ppe.o hns_dsaf_rcb.o hns_dsaf_xgmac.o
> +
> +obj-$(CONFIG_HNS_MDIO) += hns_mdio.o
> +hns_mdio-objs = hns_mdio_main.o
> +
> +obj-$(CONFIG_HNS_ENET) += hns_enet_drv.o
> +hns_enet_drv-objs = hns_enet.o hns_ethtool.o
> diff --git a/drivers/net/ethernet/hisilicon/hns/hnae.c b/drivers/net/ethernet/hisilicon/hns/hnae.c
> new file mode 100644
> index 0000000..fd09768
> --- /dev/null
> +++ b/drivers/net/ethernet/hisilicon/hns/hnae.c
> @@ -0,0 +1,494 @@
> +/*
> + * Copyright (c) 2014-2015 Hisilicon Limited.
> + *
> + * 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.
> + */
> +
> +#include <linux/dma-mapping.h>
> +#include <linux/interrupt.h>
> +#include <linux/skbuff.h>
> +#include <linux/slab.h>
> +
> +#include "hnae.h"
> +
> +#define cls_to_ae_dev(dev) container_of(dev, struct hnae_ae_dev, cls_dev)
> +
> +static struct class *hnae_class;
> +
> +static inline void hnae_list_add(spinlock_t *lock, struct list_head *node,
> +                                struct list_head *head)
> +{
> +       unsigned long flags;
> +
> +       spin_lock_irqsave(lock, flags);
> +       list_add_tail_rcu(node, head);
> +       spin_unlock_irqrestore(lock, flags);
> +}
> +
> +static inline void hnae_list_del(spinlock_t *lock, struct list_head *node)
> +{
> +       unsigned long flags;
> +
> +       spin_lock_irqsave(lock, flags);
> +       list_del_rcu(node);
> +       spin_unlock_irqrestore(lock, flags);
> +}
> +
> +static int hnae_alloc_buffer(struct hnae_ring *ring, struct hnae_desc_cb *cb)
> +{
> +       unsigned int order = hnae_page_order(ring);
> +       struct page *p = dev_alloc_pages(order);
> +
> +       if (!p)
> +               return -ENOMEM;
> +
> +       cb->priv = p;
> +       cb->page_offset = 0;
> +       cb->reuse_flag = 0;
> +       cb->buf  = page_address(p);
> +       cb->length = hnae_page_size(ring);
> +       cb->type = DESC_TYPE_PAGE;
> +
> +       return 0;
> +}
> +
> +static void hnae_free_buffer(struct hnae_ring *ring, struct hnae_desc_cb *cb)
> +{
> +       if (cb->type == DESC_TYPE_SKB)
> +               dev_kfree_skb_any((struct sk_buff *)cb->priv);
> +       else if (unlikely(is_rx_ring(ring)))
> +               put_page((struct page *)cb->priv);
> +       memset(cb, 0, sizeof(*cb));
> +}
> +
> +static int hnae_map_buffer(struct hnae_ring *ring, struct hnae_desc_cb *cb)
> +{
> +       cb->dma = dma_map_page(ring_to_dev(ring), cb->priv, 0,
> +                              cb->length, ring_to_dma_dir(ring));
> +
> +       if (dma_mapping_error(ring_to_dev(ring), cb->dma))
> +               return -EIO;
> +
> +       return 0;
> +}
> +
> +static void hnae_unmap_buffer(struct hnae_ring *ring, struct hnae_desc_cb *cb)
> +{
> +       if (cb->type == DESC_TYPE_SKB)
> +               dma_unmap_single(ring_to_dev(ring), cb->dma, cb->length,
> +                                ring_to_dma_dir(ring));
> +       else
> +               dma_unmap_page(ring_to_dev(ring), cb->dma, cb->length,
> +                              ring_to_dma_dir(ring));
> +}
> +
> +static struct hnae_buf_ops hnae_bops = {
> +       .alloc_buffer = hnae_alloc_buffer,
> +       .free_buffer = hnae_free_buffer,
> +       .map_buffer = hnae_map_buffer,
> +       .unmap_buffer = hnae_unmap_buffer,
> +};
> +
> +static int __ae_match(struct device *dev, const void *data)
> +{
> +       struct hnae_ae_dev *hdev = cls_to_ae_dev(dev);
> +       const char *ae_id = data;
> +
> +       if (!strncmp(ae_id, hdev->name, AE_NAME_SIZE))
> +               return 1;
> +
> +       return 0;
> +}
> +
> +static struct hnae_ae_dev *find_ae(const char *ae_id)
> +{
> +       struct device *dev;
> +
> +       BUG_ON(!ae_id);
> +
> +       dev = class_find_device(hnae_class, NULL, ae_id, __ae_match);
> +
> +       return cls_to_ae_dev(dev);
> +}

Most entries of class_find_device() in kernel that i see perform
if-check for NULL on return value.
What do you think about such option for example:
return dev ? cls_to_ae_dev(dev) : NULL;
?

Is it possible that, someday, your dev will be NULL and creep in
container_of() that doesn't protected from ptr = NULL
and .... (let's go down a little in another function)

> +
> +static void hnae_free_buffers(struct hnae_ring *ring)
> +{
> +       int i;
> +
> +       for (i = 0; i < ring->desc_num; i++)
> +               hnae_free_buffer_detach(ring, i);
> +}
> +
> +/* Allocate memory for raw pkg, and map with dma */
> +static int hnae_alloc_buffers(struct hnae_ring *ring)
> +{
> +       int i, j, ret;
> +
> +       for (i = 0; i < ring->desc_num; i++) {
> +               ret = hnae_alloc_buffer_attach(ring, i);
> +               if (ret)
> +                       goto out_buffer_fail;
> +       }
> +
> +       return 0;
> +
> +out_buffer_fail:
> +       for (j = i - 1; j >= 0; j--)
> +               hnae_free_buffer_detach(ring, j);
> +       return ret;
> +}
> +
> +/* free desc along with its attached buffer */
> +static inline void hnae_free_desc(struct hnae_ring *ring)
> +{
> +       hnae_free_buffers(ring);
> +       dma_unmap_single(ring_to_dev(ring), ring->desc_dma_addr,
> +                        ring->desc_num * sizeof(ring->desc[0]),
> +                        ring_to_dma_dir(ring));
> +       ring->desc_dma_addr = 0;
> +       kfree(ring->desc);
> +       ring->desc = NULL;
> +}
> +
> +/* alloc desc, without buffer attached */
> +static inline int hnae_alloc_desc(struct hnae_ring *ring)
> +{
> +       int size = ring->desc_num * sizeof(ring->desc[0]);
> +
> +       ring->desc = kzalloc(size, GFP_KERNEL);
> +       if (!ring->desc)
> +               return -ENOMEM;
> +
> +       ring->desc_dma_addr = dma_map_single(ring_to_dev(ring),
> +               ring->desc, size, ring_to_dma_dir(ring));
> +       if (dma_mapping_error(ring_to_dev(ring), ring->desc_dma_addr)) {
> +               ring->desc_dma_addr = 0;
> +               kfree(ring->desc);
> +               ring->desc = NULL;
> +               return -ENOMEM;
> +       }
> +
> +       return 0;
> +}
> +
> +/* fini ring, also free the buffer for the ring */
> +static inline void hnae_fini_ring(struct hnae_ring *ring)
> +{
> +       hnae_free_desc(ring);
> +       kfree(ring->desc_cb);
> +       ring->desc_cb = NULL;
> +       ring->next_to_clean = 0;
> +       ring->next_to_use = 0;
> +}
> +
> +/* init ring, and with buffer for rx ring */
> +static inline int hnae_init_ring(struct hnae_queue *q, struct hnae_ring *ring,
> +                                int flags)
> +{
> +       int ret;
> +
> +       if (ring->desc_num <= 0 || ring->buf_size <= 0)
> +               return -EINVAL;
> +
> +       ring->q = q;
> +       ring->flags = flags;
> +       assert(!ring->desc && !ring->desc_cb && !ring->desc_dma_addr);
> +
> +       /* not matter for tx or rx ring, the ntc and ntc start from 0 */
> +       assert(ring->next_to_use == 0);
> +       assert(ring->next_to_clean == 0);
> +
> +       ring->desc_cb = kcalloc(ring->desc_num, sizeof(ring->desc_cb[0]),
> +                       GFP_KERNEL);
> +       if (!ring->desc_cb) {
> +               ret = -ENOMEM;
> +               goto out;
> +       }
> +
> +       ret = hnae_alloc_desc(ring);
> +       if (ret)
> +               goto out_with_desc_cb;
> +
> +       if (is_rx_ring(ring)) {
> +               ret = hnae_alloc_buffers(ring);
> +               if (ret)
> +                       goto out_with_desc;
> +       }
> +
> +       return 0;
> +
> +out_with_desc:
> +       hnae_free_desc(ring);
> +out_with_desc_cb:
> +       kfree(ring->desc_cb);
> +       ring->desc_cb = NULL;
> +out:
> +       return ret;
> +}
> +
> +static inline int hnae_init_queue(struct hnae_handle *h, struct hnae_queue *q,
> +                                 struct hnae_ae_dev *dev)
> +{
> +       int ret;
> +
> +       q->dev = dev;
> +       q->handle = h;
> +
> +       ret = hnae_init_ring(q, &q->tx_ring, q->tx_ring.flags | RINGF_DIR);
> +       if (ret)
> +               goto out;
> +
> +       ret = hnae_init_ring(q, &q->rx_ring, q->rx_ring.flags & ~RINGF_DIR);
> +       if (ret)
> +               goto out_with_tx_ring;
> +
> +       if (dev->ops->init_queue)
> +               dev->ops->init_queue(q);
> +
> +       return 0;
> +
> +out_with_tx_ring:
> +       hnae_fini_ring(&q->tx_ring);
> +out:
> +       return ret;
> +}
> +
> +static inline void hnae_fini_queue(struct hnae_queue *q)
> +{
> +       if (q->dev->ops->fini_queue)
> +               q->dev->ops->fini_queue(q);
> +
> +       hnae_fini_ring(&q->tx_ring);
> +       hnae_fini_ring(&q->rx_ring);
> +}
> +
> +/**
> + * ae_chain - define ae chain head
> + */
> +static RAW_NOTIFIER_HEAD(ae_chain);
> +
> +int hnae_register_notifier(struct notifier_block *nb)
> +{
> +       return raw_notifier_chain_register(&ae_chain, nb);
> +}
> +EXPORT_SYMBOL(hnae_register_notifier);
> +
> +void hnae_unregister_notifier(struct notifier_block *nb)
> +{
> +       if (raw_notifier_chain_unregister(&ae_chain, nb))
> +               dev_err(NULL, "notifier chain unregister fail\n");
> +}
> +EXPORT_SYMBOL(hnae_unregister_notifier);
> +
> +int hnae_reinit_handle(struct hnae_handle *handle)
> +{
> +       int i, j;
> +       int ret;
> +
> +       for (i = 0; i < handle->q_num; i++) /* free ring*/
> +               hnae_fini_queue(handle->qs[i]);
> +
> +       for (i = 0; i < handle->q_num; i++) {/* reinit ring*/
> +               ret = hnae_init_queue(handle, handle->qs[i], handle->dev);
> +               if (ret)
> +                       goto out_when_init_queue;
> +       }
> +       return 0;
> +out_when_init_queue:
> +       for (j = i - 1; j >= 0; j--)
> +               hnae_fini_queue(handle->qs[j]);
> +       return ret;
> +}
> +EXPORT_SYMBOL(hnae_reinit_handle);
> +
> +/* hnae_get_handle - get a handle from the AE
> + * @owner_dev: the dev use this handle
> + * @ae_id: the id of the ae to be used
> + * @ae_opts: the options set for the handle
> + * @bops: the callbacks for buffer management
> + *
> + * return handle ptr or ERR_PTR
> + */
> +struct hnae_handle *hnae_get_handle(struct device *owner_dev,
> +                                   const char *ae_id, const char *ae_opts,
> +                                   struct hnae_buf_ops *bops)
> +{
> +       struct hnae_ae_dev *dev;
> +       struct hnae_handle *handle;
> +       int i, j;
> +       int ret;
> +
> +       dev = find_ae(ae_id);
> +       if (!dev)
> +               return ERR_PTR(-ENODEV);

.. and here you might not receive NULL after container_of() works on
that returned NULL after class_find_device().
I guess that might happen after someone change order of fields in
struct hnae_ae_dev.

I understand that it's unlikely to happen but could you please check or comment?


> +
> +       handle = dev->ops->get_handle(dev, ae_opts);
> +       if (IS_ERR(handle))
> +               return handle;
> +
> +       handle->dev = dev;
> +       handle->owner_dev = owner_dev;
> +       handle->bops = bops ? bops : &hnae_bops;
> +       handle->ae_opts = ae_opts;
> +
> +       for (i = 0; i < handle->q_num; i++) {
> +               ret = hnae_init_queue(handle, handle->qs[i], dev);
> +               if (ret)
> +                       goto out_when_init_queue;
> +       }
> +
> +       __module_get(dev->owner);
> +
> +       hnae_list_add(&dev->lock, &handle->node, &dev->handle_list);
> +
> +       return handle;
> +
> +out_when_init_queue:
> +       for (j = i - 1; j >= 0; j--)
> +               hnae_fini_queue(handle->qs[j]);
> +
> +       return ERR_PTR(-ENOMEM);
> +}
> +EXPORT_SYMBOL(hnae_get_handle);
> +
> +void hnae_put_handle(struct hnae_handle *h)
> +{
> +       struct hnae_ae_dev *dev = h->dev;
> +       int i;
> +
> +       for (i = 0; i < h->q_num; i++)
> +               hnae_fini_queue(h->qs[i]);
> +
> +       hnae_list_del(&dev->lock, &h->node);
> +
> +       if (dev->ops->put_handle)
> +               dev->ops->put_handle(h);
> +
> +       module_put(dev->owner);
> +}
> +EXPORT_SYMBOL(hnae_put_handle);
> +
> +static void __hnae_release(struct device *dev)
> +{
> +}
> +
> +/**
> + * hnae_ae_register - register a AE engine to hnae framework
> + * @hdev: the hnae ae engine device
> + * @owner:  the module who provides this dev
> + * NOTE: the duplicated name will not be checked
> + */
> +int hnae_ae_register(struct hnae_ae_dev *hdev, struct module *owner)
> +{
> +       static atomic_t id = ATOMIC_INIT(-1);
> +       int ret;
> +
> +       if (!hdev->dev)
> +               return -ENODEV;
> +
> +       if (!hdev->ops || !hdev->ops->get_handle ||
> +           !hdev->ops->toggle_ring_irq ||
> +           !hdev->ops->toggle_queue_status ||
> +           !hdev->ops->get_status || !hdev->ops->adjust_link)
> +               return -EINVAL;
> +
> +       hdev->owner = owner;
> +       hdev->id = (int)atomic_inc_return(&id);
> +       hdev->cls_dev.parent = hdev->dev;
> +       hdev->cls_dev.class = hnae_class;
> +       hdev->cls_dev.release = __hnae_release;
> +       dev_set_name(&hdev->cls_dev, "hnae%d", hdev->id);
> +       ret = device_register(&hdev->cls_dev);
> +       if (ret)
> +               return ret;
> +
> +       __module_get(THIS_MODULE);
> +
> +       INIT_LIST_HEAD(&hdev->handle_list);
> +       spin_lock_init(&hdev->lock);
> +
> +       ret = raw_notifier_call_chain(&ae_chain, HNAE_AE_REGISTER, NULL);
> +       if (ret)
> +               dev_dbg(hdev->dev,
> +                       "has not notifier for AE: %s\n", hdev->name);
> +
> +       return 0;
> +}
> +EXPORT_SYMBOL(hnae_ae_register);
> +
> +/**
> + * hnae_ae_unregister - unregisters a HNAE AE engine
> + * @cdev: the device to unregister
> + */
> +void hnae_ae_unregister(struct hnae_ae_dev *hdev)
> +{
> +       device_unregister(&hdev->cls_dev);
> +       module_put(THIS_MODULE);
> +}
> +EXPORT_SYMBOL(hnae_ae_unregister);
> +
> +static ssize_t handles_show(struct device *dev,
> +                           struct device_attribute *attr, char *buf)
> +{
> +       ssize_t s = 0;
> +       struct hnae_ae_dev *hdev = cls_to_ae_dev(dev);
> +       struct hnae_handle *h;
> +       int i = 0, j;
> +
> +       list_for_each_entry_rcu(h, &hdev->handle_list, node) {
> +               s += sprintf(buf + s, "%s(%s): ", dev_name(h->owner_dev),
> +                            h->ae_opts);
> +               for (j = 0; j < h->q_num; j++) {
> +                       if (h->qs[i]) {
> +                               s += sprintf(buf + s,
> +                                       "(%llu,%llu; ",
> +                                       h->qs[i]->tx_ring.stats.sw_err_cnt,
> +                                       h->qs[i]->tx_ring.stats.io_err_cnt);
> +                               s += sprintf(buf + s,
> +                                       "%llu,%llu,%llu), ",
> +                                       h->qs[i]->rx_ring.stats.sw_err_cnt,
> +                                       h->qs[i]->rx_ring.stats.io_err_cnt,
> +                                       h->qs[i]->rx_ring.stats.seg_pkt_cnt);
> +                       } else {
> +                               s += sprintf(buf + s, "(null)\n");
> +                       }
> +               }
> +               s += sprintf(buf + s, "\n");
> +       }
> +
> +       return s;
> +}
> +
> +static DEVICE_ATTR_RO(handles);
> +static struct attribute *hnae_class_attrs[] = {
> +       &dev_attr_handles.attr,
> +       NULL,
> +};
> +ATTRIBUTE_GROUPS(hnae_class);
> +
> +static int __init hnae_init(void)
> +{
> +       hnae_class = class_create(THIS_MODULE, "hnae");
> +       if (IS_ERR(hnae_class))
> +               return PTR_ERR(hnae_class);
> +
> +       hnae_class->dev_groups = hnae_class_groups;
> +       return 0;
> +}
> +
> +static void __exit hnae_exit(void)
> +{
> +       class_destroy(hnae_class);
> +}
> +
> +subsys_initcall(hnae_init);
> +module_exit(hnae_exit);
> +
> +MODULE_AUTHOR("Hisilicon, Inc.");
> +MODULE_LICENSE("GPL");
> +MODULE_DESCRIPTION("Hisilicon Network Acceleration Engine Framework");
> +
> +/* vi: set tw=78 noet: */
> diff --git a/drivers/net/ethernet/hisilicon/hns/hnae.h b/drivers/net/ethernet/hisilicon/hns/hnae.h
> new file mode 100644
> index 0000000..e7856cf
> --- /dev/null
> +++ b/drivers/net/ethernet/hisilicon/hns/hnae.h
> @@ -0,0 +1,582 @@
> +/*
> + * Copyright (c) 2014-2015 Hisilicon Limited.
> + *
> + * 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.
> + */
> +
> +#ifndef __HNAE_H
> +#define __HNAE_H
> +
> +/* Names used in this framework:
> + *      ae handle (handle):
> + *        a set of queues provided by AE
> + *      ring buffer queue (rbq):
> + *        the channel between upper layer and the AE, can do tx and rx
> + *      ring:
> + *        a tx or rx channel within a rbq
> + *      ring description (desc):
> + *        an element in the ring with packet information
> + *      buffer:
> + *        a memory region referred by desc with the full packet payload
> + *
> + * "num" means a static number set as a parameter, "count" mean a dynamic
> + *   number set while running
> + * "cb" means control block
> + */
> +
> +#include <linux/delay.h>
> +#include <linux/device.h>
> +#include <linux/module.h>
> +#include <linux/netdevice.h>
> +#include <linux/notifier.h>
> +#include <linux/types.h>
> +
> +#define HNAE_DRIVER_VERSION "1.1.0"
> +#define HNAE_DRIVER_NAME "hns"
> +#define HNAE_COPYRIGHT "Copyright(c) 2015 Huawei Corporation."
> +#define HNAE_DRIVER_STRING "Hisilicon Network Subsystem Driver"
> +#define HNAE_DEFAULT_DEVICE_DESCR "Hisilicon Network Subsystem"
> +
> +#ifdef DEBUG
> +
> +#ifndef assert
> +#define assert(expr) \
> +do { \
> +       if (!(expr)) { \
> +               pr_err("Assertion failed! %s, %s, %s, line %d\n", \
> +                          #expr, __FILE__, __func__, __LINE__); \
> +       } \
> +} while (0)
> +#endif
> +
> +#else
> +
> +#ifndef assert
> +#define assert(expr)
> +#endif
> +
> +#endif
> +
> +#define AE_NAME_SIZE 16
> +#define AE_OPTS_SIZE 64
> +
> +/* some said the RX and TX RCB format should not be the same in the future. But
> + * it is the same now...
> + */
> +#define RCB_REG_BASEADDR_L         0x00 /* P660 support only 32bit accessing */
> +#define RCB_REG_BASEADDR_H         0x04
> +#define RCB_REG_BD_NUM             0x08
> +#define RCB_REG_BD_LEN             0x0C
> +#define RCB_REG_PKTLINE            0x10
> +#define RCB_REG_TAIL               0x18
> +#define RCB_REG_HEAD               0x1C
> +#define RCB_REG_FBDNUM             0x20
> +#define RCB_REG_OFFSET             0x24 /* pkt num to be handled */
> +#define RCB_REG_PKTNUM_RECORD      0x2C /* total pkt received */
> +
> +#define HNS_RX_HEAD_SIZE 256
> +
> +#define HNAE_AE_REGISTER 0x1
> +
> +#define RCB_RING_NAME_LEN 16
> +
> +enum hnae_led_state {
> +       HNAE_LED_INACTIVE,
> +       HNAE_LED_ACTIVE,
> +       HNAE_LED_ON,
> +       HNAE_LED_OFF
> +};
> +
> +#define HNS_RX_FLAG_VLAN_PRESENT 0x1
> +#define HNS_RX_FLAG_L3ID_IPV4 0x0
> +#define HNS_RX_FLAG_L3ID_IPV6 0x1
> +#define HNS_RX_FLAG_L4ID_UDP 0x0
> +#define HNS_RX_FLAG_L4ID_TCP 0x1
> +
> +#define HNS_TXD_ASID_S 0
> +#define HNS_TXD_ASID_M (0xff << HNS_TXD_ASID_S)
> +#define HNS_TXD_BUFNUM_S 8
> +#define HNS_TXD_BUFNUM_M (0x3 << HNS_TXD_BUFNUM_S)
> +#define HNS_TXD_PORTID_S 10
> +#define HNS_TXD_PORTID_M (0x7 << HNS_TXD_PORTID_S)
> +
> +#define HNS_TXD_RA_B 8
> +#define HNS_TXD_RI_B 9
> +#define HNS_TXD_L4CS_B 10
> +#define HNS_TXD_L3CS_B 11
> +#define HNS_TXD_FE_B 12
> +#define HNS_TXD_VLD_B 13
> +#define HNS_TXD_IPOFFSET_S 14
> +#define HNS_TXD_IPOFFSET_M (0xff << HNS_TXD_IPOFFSET_S)
> +
> +#define HNS_RXD_IPOFFSET_S 0
> +#define HNS_RXD_IPOFFSET_M (0xff << HNS_TXD_IPOFFSET_S)
> +#define HNS_RXD_BUFNUM_S 8
> +#define HNS_RXD_BUFNUM_M (0x3 << HNS_RXD_BUFNUM_S)
> +#define HNS_RXD_PORTID_S 10
> +#define HNS_RXD_PORTID_M (0x7 << HNS_RXD_PORTID_S)
> +#define HNS_RXD_DMAC_S 13
> +#define HNS_RXD_DMAC_M (0x3 << HNS_RXD_DMAC_S)
> +#define HNS_RXD_VLAN_S 15
> +#define HNS_RXD_VLAN_M (0x3 << HNS_RXD_VLAN_S)
> +#define HNS_RXD_L3ID_S 17
> +#define HNS_RXD_L3ID_M (0xf << HNS_RXD_L3ID_S)
> +#define HNS_RXD_L4ID_S 21
> +#define HNS_RXD_L4ID_M (0xf << HNS_RXD_L4ID_S)
> +#define HNS_RXD_FE_B 25
> +#define HNS_RXD_FRAG_B 26
> +#define HNS_RXD_VLD_B 27
> +#define HNS_RXD_L2E_B 28
> +#define HNS_RXD_L3E_B 29
> +#define HNS_RXD_L4E_B 30
> +#define HNS_RXD_DROP_B 31
> +
> +#define HNS_RXD_VLANID_S 8
> +#define HNS_RXD_VLANID_M (0xfff << HNS_RXD_VLANID_S)
> +#define HNS_RXD_CFI_B 20
> +#define HNS_RXD_PRI_S 21
> +#define HNS_RXD_PRI_M (0x7 << HNS_RXD_PRI_S)
> +#define HNS_RXD_ASID_S 24
> +#define HNS_RXD_ASID_M (0xff << HNS_RXD_ASID_S)
> +
> +/* hardware spec ring buffer format */
> +struct __packed hnae_desc {
> +       __le64 addr;
> +       union {
> +               struct {
> +                       __le16 asid_bufnum_pid;
> +                       __le16 send_size;
> +                       __le32 flag_ipoffset;
> +                       __le32 reserved_3[4];
> +               } tx;
> +
> +               struct {
> +                       __le32 ipoff_bnum_pid_flag;
> +                       __le16 pkt_len;
> +                       __le16 size;
> +                       __le32 vlan_pri_asid;
> +                       __le32 reserved_2[3];
> +               } rx;
> +       };
> +};
> +
> +struct hnae_desc_cb {
> +       dma_addr_t dma; /* dma address of this desc */
> +       void *buf;      /* cpu addr for a desc */
> +
> +       /* priv data for the desc, e.g. skb when use with ip stack*/
> +       void *priv;
> +       u16 page_offset;
> +       u16 reuse_flag;
> +
> +       u16 length;     /* length of the buffer */
> +
> +       /* desc type, used by the ring user to mark the type of the priv data */
> +       u16 type;
> +};
> +
> +#define setflags(flags, bits) ((flags) |= (bits))
> +#define unsetflags(flags, bits) ((flags) &= ~(bits))
> +
> +/* hnae_ring->flags fields */
> +#define RINGF_DIR 0x1      /* TX or RX ring, set if TX */
> +#define is_tx_ring(ring) ((ring)->flags & RINGF_DIR)
> +#define is_rx_ring(ring) (!is_tx_ring(ring))
> +#define ring_to_dma_dir(ring) (is_tx_ring(ring) ? \
> +       DMA_TO_DEVICE : DMA_FROM_DEVICE)
> +
> +struct ring_stats {
> +       u64 io_err_cnt;
> +       u64 sw_err_cnt;
> +       u64 seg_pkt_cnt;
> +       u64 reuse_pg_cnt;
> +       u64 err_pkt_len;
> +       u64 non_vld_descs;
> +       u64 err_bd_num;
> +       u64 csum_err;
> +       union {
> +               u64 tx_pkts;
> +               u64 rx_pkts;
> +       } pkts;
> +       union {
> +               u64 tx_bytes;
> +               u64 rx_bytes;
> +       } bytes;
> +       union {
> +               u64 tx_err_cnt;
> +               u64 rx_err_cnt;
> +       } err_cnt;
> +};
> +
> +struct hnae_queue;
> +
> +struct hnae_ring {
> +       u8 __iomem *io_base; /* base io address for the ring */
> +       struct hnae_desc *desc; /* dma map address space */
> +       struct hnae_desc_cb *desc_cb;
> +       struct hnae_queue *q;
> +       int irq;
> +       char ring_name[RCB_RING_NAME_LEN];
> +
> +       /* statistic */
> +       struct ring_stats stats;
> +
> +       dma_addr_t desc_dma_addr;
> +       u32 buf_size;       /* size for hnae_desc->addr, preset by AE */
> +       u16 desc_num;       /* total number of desc */
> +       u16 max_desc_num_per_pkt;
> +       u16 max_raw_data_sz_per_desc;
> +       u16 max_pkt_size;
> +       int next_to_use;    /* idx of next spare desc */
> +
> +       /* idx of lastest sent desc, the ring is empty when equal to
> +        * next_to_use
> +        */
> +       int next_to_clean;
> +
> +       int flags;          /* ring attribute */
> +};
> +
> +#define ring_ptr_move_fw(ring, p) \
> +       ((ring)->p = ((ring)->p + 1) % (ring)->desc_num)
> +#define ring_ptr_move_bw(ring, p) \
> +       ((ring)->p = ((ring)->p - 1 + (ring)->desc_num) % (ring)->desc_num)
> +
> +enum hns_desc_type {
> +       DESC_TYPE_SKB,
> +       DESC_TYPE_PAGE,
> +};
> +
> +#define assert_is_ring_idx(ring, idx) \
> +       assert((idx) >= 0 && (idx) < (ring)->desc_num)
> +
> +/* the distance between [begin, end) in a ring buffer
> + * note: there is a unuse slot between the begin and the end
> + */
> +static inline int ring_dist(struct hnae_ring *ring, int begin, int end)
> +{
> +       assert_is_ring_idx(ring, begin);
> +       assert_is_ring_idx(ring, end);
> +
> +       return (end - begin + ring->desc_num) % ring->desc_num;
> +}
> +
> +static inline int ring_space(struct hnae_ring *ring)
> +{
> +       return ring->desc_num -
> +               ring_dist(ring, ring->next_to_clean, ring->next_to_use) - 1;
> +}
> +
> +static inline int is_ring_empty(struct hnae_ring *ring)
> +{
> +       assert_is_ring_idx(ring, ring->next_to_use);
> +       assert_is_ring_idx(ring, ring->next_to_clean);
> +
> +       return ring->next_to_use == ring->next_to_clean;
> +}
> +
> +#define hnae_buf_size(_ring) ((_ring)->buf_size)
> +#define hnae_page_order(_ring) (get_order(hnae_buf_size(_ring)))
> +#define hnae_page_size(_ring) (PAGE_SIZE << hnae_page_order(_ring))
> +
> +struct hnae_handle;
> +
> +/* allocate and dma map space for hnae desc */
> +struct hnae_buf_ops {
> +       int (*alloc_buffer)(struct hnae_ring *ring, struct hnae_desc_cb *cb);
> +       void (*free_buffer)(struct hnae_ring *ring, struct hnae_desc_cb *cb);
> +       int (*map_buffer)(struct hnae_ring *ring, struct hnae_desc_cb *cb);
> +       void (*unmap_buffer)(struct hnae_ring *ring, struct hnae_desc_cb *cb);
> +};
> +
> +struct hnae_queue {
> +       void __iomem *io_base;
> +       struct hnae_ae_dev *dev;        /* the device who use this queue */
> +       struct hnae_ring rx_ring, tx_ring;
> +       struct hnae_handle *handle;
> +};
> +
> +/*hnae loop mode*/
> +enum hnae_loop {
> +       MAC_LOOP_NONE = 0,
> +       MAC_INTERNALLOOP_MAC,
> +       MAC_INTERNALLOOP_SERDES,
> +       MAC_INTERNALLOOP_PHY,
> +};
> +
> +/*hnae port type*/
> +enum hnae_port_type {
> +       HNAE_PORT_SERVICE = 0,
> +       HNAE_PORT_DEBUG
> +};
> +
> +/* This struct defines the operation on the handle.
> + *
> + * get_handle(): (mandatory)
> + *   Get a handle from AE according to its name and options.
> + *   the AE driver should manage the space used by handle and its queues while
> + *   the HNAE framework will allocate desc and desc_cb for all rings in the
> + *   queues.
> + * put_handle():
> + *   Release the handle.
> + * start():
> + *   Enable the hardware, include all queues
> + * stop():
> + *   Disable the hardware
> + * set_opts(): (mandatory)
> + *   Set options to the AE
> + * get_opts(): (mandatory)
> + *   Get options from the AE
> + * get_status():
> + *   Get the carrier state of the back channel of the handle, 1 for ok, 0 for
> + *   non-ok
> + * toggle_ring_irq(): (mandatory)
> + *   Set the ring irq to be enabled(0) or disable(1)
> + * toggle_queue_status(): (mandatory)
> + *   Set the queue to be enabled(1) or disable(0), this will not change the
> + *   ring irq state
> + * adjust_link()
> + *   adjust link status
> + * set_loopback()
> + *   set loopback
> + * get_ring_bdnum_limit()
> + *   get ring bd number limit
> + * get_pauseparam()
> + *   get tx and rx of pause frame use
> + * set_autoneg()
> + *   set auto autonegotiation of pause frame use
> + * get_autoneg()
> + *   get auto autonegotiation of pause frame use
> + * set_pauseparam()
> + *   set tx and rx of pause frame use
> + * get_coalesce_usecs()
> + *   get usecs to delay a TX interrupt after a packet is sent
> + * get_rx_max_coalesced_frames()
> + *   get Maximum number of packets to be sent before a TX interrupt.
> + * set_coalesce_usecs()
> + *   set usecs to delay a TX interrupt after a packet is sent
> + * set_coalesce_frames()
> + *   set Maximum number of packets to be sent before a TX interrupt.
> + * get_ringnum()
> + *   get RX/TX ring number
> + * get_max_ringnum()
> + *   get RX/TX ring maximum number
> + * get_mac_addr()
> + *   get mac address
> + * set_mac_addr()
> + *   set mac address
> + * set_mc_addr()
> + *   set multicast mode
> + * set_mtu()
> + *   set mtu
> + * update_stats()
> + *   update Old network device statistics
> + * get_ethtool_stats()
> + *   get ethtool network device statistics
> + * get_strings()
> + *   get a set of strings that describe the requested objects
> + * get_sset_count()
> + *   get number of strings that @get_strings will write
> + * update_led_status()
> + *   update the led status
> + * set_led_id()
> + *   set led id
> + * get_regs()
> + *   get regs dump
> + * get_regs_len()
> + *   get the len of the regs dump
> + */
> +struct hnae_ae_ops {
> +       struct hnae_handle *(*get_handle)(struct hnae_ae_dev *dev,
> +                                         const char *opts);
> +       void (*put_handle)(struct hnae_handle *handle);
> +       void (*init_queue)(struct hnae_queue *q);
> +       void (*fini_queue)(struct hnae_queue *q);
> +       int (*start)(struct hnae_handle *handle);
> +       void (*stop)(struct hnae_handle *handle);
> +       void (*reset)(struct hnae_handle *handle);
> +       int (*set_opts)(struct hnae_handle *handle, int type, void *opts);
> +       int (*get_opts)(struct hnae_handle *handle, int type, void **opts);
> +       int (*get_status)(struct hnae_handle *handle);
> +       int (*get_info)(struct hnae_handle *handle,
> +                       u8 *auto_neg, u16 *speed, u8 *duplex);
> +       int (*set_info)(struct hnae_handle *handle,
> +                       u8 auto_neg, u16 speed, u8 duplex);
> +       void (*toggle_ring_irq)(struct hnae_ring *ring, u32 val);
> +       void (*toggle_queue_status)(struct hnae_queue *queue, u32 val);
> +       void (*adjust_link)(struct hnae_handle *handle, int speed, int duplex);
> +       int (*set_loopback)(struct hnae_handle *handle,
> +                           enum hnae_loop loop_mode, int en);
> +       void (*get_ring_bdnum_limit)(struct hnae_queue *queue,
> +                                    u32 *uplimit, u32 *lowlimit);
> +       void (*get_pauseparam)(struct hnae_handle *handle,
> +                              u32 *auto_neg, u32 *rx_en, u32 *tx_en);
> +       int (*set_autoneg)(struct hnae_handle *handle, u8 enable);
> +       int (*get_autoneg)(struct hnae_handle *handle);
> +       void (*set_pauseparam)(struct hnae_handle *handle,
> +                              u32 rx_en, u32 tx_en);
> +       void (*get_coalesce_usecs)(struct hnae_handle *handle,
> +                                  u32 *tx_usecs, u32 *rx_usecs);
> +       void (*get_rx_max_coalesced_frames)(struct hnae_handle *handle,
> +                                           u32 *tx_frames, u32 *rx_frames);
> +       void (*set_coalesce_usecs)(struct hnae_handle *handle, u32 timeout);
> +       int (*set_coalesce_frames)(struct hnae_handle *handle,
> +                                  u32 coalesce_frames);
> +       void (*get_ringnum)(struct hnae_handle *handle, u32 *ringnum);
> +       void (*get_max_ringnum)(struct hnae_handle *handle, u32 *max_ringnum);
> +       int (*get_mac_addr)(struct hnae_handle *handle, void **p);
> +       int (*set_mac_addr)(struct hnae_handle *handle, void *p);
> +       int (*set_mc_addr)(struct hnae_handle *handle, void *addr);
> +       int (*set_mtu)(struct hnae_handle *handle, int new_mtu);
> +       void (*update_stats)(struct hnae_handle *handle,
> +                            struct net_device_stats *net_stats);
> +       void (*get_stats)(struct hnae_handle *handle, u64 *data);
> +       void (*get_strings)(struct hnae_handle *handle,
> +                           u32 stringset, u8 *data);
> +       int (*get_sset_count)(struct hnae_handle *handle, int stringset);
> +       void (*update_led_status)(struct hnae_handle *handle);
> +       int (*set_led_id)(struct hnae_handle *handle,
> +                         enum hnae_led_state status);
> +       void (*get_regs)(struct hnae_handle *handle, void *data);
> +       int (*get_regs_len)(struct hnae_handle *handle);
> +};
> +
> +struct hnae_ae_dev {
> +       struct device cls_dev; /* the class dev */
> +       struct device *dev; /* the presented dev */
> +       struct hnae_ae_ops *ops;
> +       struct list_head node;
> +       struct module *owner; /* the module who provides this dev */
> +       int id;
> +       char name[AE_NAME_SIZE];
> +       struct list_head handle_list;
> +       spinlock_t lock; /* lock to protect the handle_list */
> +};
> +
> +struct hnae_handle {
> +       struct device *owner_dev; /* the device which make use of this handle */
> +       struct hnae_ae_dev *dev;  /* the device who provides this handle */
> +       struct device_node *phy_node;
> +       phy_interface_t phy_if;
> +       u32 if_support;
> +       int q_num;
> +       const char *ae_opts;
> +       enum hnae_port_type port_type;
> +       struct list_head node;    /* list to hnae_ae_dev->handle_list */
> +       struct hnae_buf_ops *bops; /* operation for the buffer */
> +       struct net_device_stats net_stats;
> +       struct hnae_queue **qs;  /* array base of all queues */
> +};
> +
> +#define ring_to_dev(ring) ((ring)->q->dev->dev)
> +
> +struct hnae_handle *hnae_get_handle(struct device *owner_dev, const char *ae_id,
> +                                   const char *ae_opts,
> +                                   struct hnae_buf_ops *bops);
> +void hnae_put_handle(struct hnae_handle *handle);
> +int hnae_ae_register(struct hnae_ae_dev *dev, struct module *owner);
> +void hnae_ae_unregister(struct hnae_ae_dev *dev);
> +
> +int hnae_register_notifier(struct notifier_block *nb);
> +void hnae_unregister_notifier(struct notifier_block *nb);
> +int hnae_reinit_handle(struct hnae_handle *handle);
> +
> +#define hnae_queue_xmit(q, buf_num) writel_relaxed(buf_num, \
> +       (q)->tx_ring.io_base + RCB_REG_TAIL)
> +
> +#ifndef assert
> +#define assert(cond)
> +#endif
> +
> +static inline int hnae_reserve_buffer_map(struct hnae_ring *ring,
> +                                         struct hnae_desc_cb *cb)
> +{
> +       struct hnae_buf_ops *bops = ring->q->handle->bops;
> +       int ret;
> +
> +       ret = bops->alloc_buffer(ring, cb);
> +       if (ret)
> +               goto out;
> +
> +       ret = bops->map_buffer(ring, cb);
> +       if (ret)
> +               goto out_with_buf;
> +
> +       return 0;
> +
> +out_with_buf:
> +       bops->free_buffer(ring, cb);
> +out:
> +       return ret;
> +}
> +
> +static inline int hnae_alloc_buffer_attach(struct hnae_ring *ring, int i)
> +{
> +       int ret = hnae_reserve_buffer_map(ring, &ring->desc_cb[i]);
> +
> +       if (ret)
> +               return ret;
> +
> +       ring->desc[i].addr = (__le64)ring->desc_cb[i].dma;
> +
> +       return 0;
> +}
> +
> +static inline void hnae_buffer_detach(struct hnae_ring *ring, int i)
> +{
> +       ring->q->handle->bops->unmap_buffer(ring, &ring->desc_cb[i]);
> +       ring->desc[i].addr = 0;
> +}
> +
> +static inline void hnae_free_buffer_detach(struct hnae_ring *ring, int i)
> +{
> +       struct hnae_buf_ops *bops = ring->q->handle->bops;
> +       struct hnae_desc_cb *cb = &ring->desc_cb[i];
> +
> +       if (!ring->desc_cb[i].dma)
> +               return;
> +
> +       hnae_buffer_detach(ring, i);
> +       bops->free_buffer(ring, cb);
> +}
> +
> +/* detach a in-used buffer and replace with a reserved one  */
> +static inline void hnae_replace_buffer(struct hnae_ring *ring, int i,
> +                                      struct hnae_desc_cb *res_cb)
> +{
> +       struct hnae_buf_ops *bops = ring->q->handle->bops;
> +       struct hnae_desc_cb tmp_cb = ring->desc_cb[i];
> +
> +       bops->unmap_buffer(ring, &ring->desc_cb[i]);
> +       ring->desc_cb[i] = *res_cb;
> +       *res_cb = tmp_cb;
> +       ring->desc[i].addr = (__le64)ring->desc_cb[i].dma;
> +       ring->desc[i].rx.ipoff_bnum_pid_flag = 0;
> +}
> +
> +static inline void hnae_reuse_buffer(struct hnae_ring *ring, int i)
> +{
> +       ring->desc_cb[i].reuse_flag = 0;
> +       ring->desc[i].addr = (__le64)(ring->desc_cb[i].dma
> +               + ring->desc_cb[i].page_offset);
> +       ring->desc[i].rx.ipoff_bnum_pid_flag = 0;
> +}
> +
> +#define hnae_set_field(origin, mask, shift, val) \
> +       do { \
> +               (origin) &= (~(mask)); \
> +               (origin) |= ((val) << (shift)) & (mask); \
> +       } while (0)
> +
> +#define hnae_set_bit(origin, shift, val) \
> +       hnae_set_field((origin), (0x1 << (shift)), (shift), (val))
> +
> +#define hnae_get_field(origin, mask, shift) (((origin) & (mask)) >> (shift))
> +
> +#define hnae_get_bit(origin, shift) \
> +       hnae_get_field((origin), (0x1 << (shift)), (shift))
> +
> +#endif
> --
> 1.9.1
>
>
> _______________________________________________
> linux-arm-kernel mailing list
> linux-arm-kernel at lists.infradead.org
> http://lists.infradead.org/mailman/listinfo/linux-arm-kernel



-- 
Best regards, Klimov Alexey


From mturquette at baylibre.com  Mon Aug 17 17:26:04 2015
From: mturquette at baylibre.com (Michael Turquette)
Date: Mon, 17 Aug 2015 17:26:04 -0700
Subject: [PATCH 1/2] clk: add lpc18xx creg clk driver
In-Reply-To: <CAGhQ9VwZaM_iWTkQYVTuTiyb6gCG2y6s8WFVySCHt7YHE1qbcA@mail.gmail.com>
References: <1436651307-24098-1-git-send-email-manabian@gmail.com>
 <1436651307-24098-2-git-send-email-manabian@gmail.com>
 <20150811204127.31346.16729@quantum>
 <CAGhQ9VwZaM_iWTkQYVTuTiyb6gCG2y6s8WFVySCHt7YHE1qbcA@mail.gmail.com>
Message-ID: <20150818002604.31346.18322@quantum>

Quoting Joachim Eastwood (2015-08-13 13:43:11)
> On 11 August 2015 at 22:41, Michael Turquette <mturquette at baylibre.com> wrote:
> > Hi Joachim,
> >
> > Quoting Joachim Eastwood (2015-07-11 14:48:26)
> >> +static void __init lpc18xx_creg_clk_init(struct device_node *np)
> >> +{
> >> +       const char *clk_32khz_parent;
> >> +       struct regmap *syscon;
> >> +
> >> +       syscon = syscon_node_to_regmap(np->parent);
> >> +       if (IS_ERR(syscon)) {
> >> +               pr_err("%s: syscon lookup failed\n", __func__);
> >> +               return;
> >> +       }
> >> +
> >> +       clk_32khz_parent = of_clk_get_parent_name(np, 0);
> >> +
> >> +       clk_creg[CREG_CLK_32KHZ] =
> >> +               clk_register_creg_clk(&clk_creg_clocks[CREG_CLK_32KHZ],
> >> +                                     &clk_32khz_parent, syscon);
> >> +
> >> +       clk_creg[CREG_CLK_1KHZ] =
> >> +               clk_register_creg_clk(&clk_creg_clocks[CREG_CLK_1KHZ],
> >> +                                     &clk_creg_clocks[CREG_CLK_32KHZ].name,
> >> +                                     syscon);
> >> +
> >> +       of_clk_add_provider(np, of_clk_src_onecell_get, &clk_base_data);
> >> +}
> >> +CLK_OF_DECLARE(lpc18xx_creg_clk, "nxp,lpc1850-creg-clk", lpc18xx_creg_clk_init);
> >
> > I'll ask the same question that Stephen asked in your CCU/CGU driver
> > series: is it necessary to use CLK_OF_DECLARE here or can you use the
> > platform device model?
> 
> The 32 kHz clock from the CREG block is a clock parent to the CGU
> block so it's possible that it will required early. This is all
> depends on how the boot loader initially configures the CGU.
> 
> Currently in the DTS for lpc18xx cgu it has:
> clocks = <&xtal>, <&xtal32>, <...>;
> xtal32 is just a temporary placeholder until the CREG clock is in place.

Well that seems wrong. Is it just a matter of probe order where you try
to probe the cgu driver before the creg driver?

Regards,
Mike

> 
> 
> Note that while it's possible to use the 32k clock together with PLL0
> to generate the main CPU bus clock I doubt it will be common
> configuration. It is however fully possible to do.
> 
> 
> regards,
> Joachim Eastwood
> 
> _______________________________________________
> linux-arm-kernel mailing list
> linux-arm-kernel at lists.infradead.org
> http://lists.infradead.org/mailman/listinfo/linux-arm-kernel


From davem at davemloft.net  Mon Aug 17 17:27:11 2015
From: davem at davemloft.net (David Miller)
Date: Mon, 17 Aug 2015 17:27:11 -0700 (PDT)
Subject: [PATCH v1 2/2] drivers: net: xgene: Adding support for TSO
In-Reply-To: <1439847185-22046-3-git-send-email-isubramanian@apm.com>
References: <1439847185-22046-1-git-send-email-isubramanian@apm.com>
 <1439847185-22046-3-git-send-email-isubramanian@apm.com>
Message-ID: <20150817.172711.1231947431645678967.davem@davemloft.net>

From: Iyappan Subramanian <isubramanian at apm.com>
Date: Mon, 17 Aug 2015 14:33:05 -0700

> +			/* HW requires all header resides in the first buffer */
> +			if (skb_is_nonlinear(skb) &&
> +			    (skb_headlen(skb) < hdr_len)) {
> +				netdev_warn(ndev, "Headers are required to reside in header buffer\n");
> +				dev_kfree_skb(skb);
> +				return 0;
> +			}

You can't just drop the packet in this situation.

Instead, you must at least try to linearize the header to fit your
needs.


From rjw at rjwysocki.net  Mon Aug 17 18:32:06 2015
From: rjw at rjwysocki.net (Rafael J. Wysocki)
Date: Tue, 18 Aug 2015 03:32:06 +0200
Subject: 3.18: lockdep problems in cpufreq
In-Reply-To: <20150813081744.GN7557@n2100.arm.linux.org.uk>
References: <20141214213655.GA11285@n2100.arm.linux.org.uk>
 <5160300.5D2Dvly8u9@vostro.rjw.lan>
 <20150813081744.GN7557@n2100.arm.linux.org.uk>
Message-ID: <4248436.YMvuzoKMLH@vostro.rjw.lan>

On Thursday, August 13, 2015 09:17:44 AM Russell King - ARM Linux wrote:
> On Thu, Aug 13, 2015 at 03:20:35AM +0200, Rafael J. Wysocki wrote:
> > On Tuesday, August 11, 2015 06:03:57 PM Russell King - ARM Linux wrote:
> > > On Tue, May 19, 2015 at 12:05:55AM +0200, Rafael J. Wysocki wrote:
> > > > On Monday, May 18, 2015 07:56:45 PM Russell King - ARM Linux wrote:
> > > > > On Tue, Dec 16, 2014 at 09:11:53AM +0530, Viresh Kumar wrote:
> > > > > > On 16 December 2014 at 04:39, Russell King - ARM Linux
> > > > > > <linux at arm.linux.org.uk> wrote:
> > > > > > > Well, here's a patch which I'm running on top of 3.18 at the moment,
> > > > > > > which is basically what I described in my email, and I'm running with it
> > > > > > > and it is without any lockdep complaint.
> > > > > > 
> > > > > > We need two separate patches now, one for 3.18 and other one for 3.19-rc.
> > > > > > 3.19 has see lots of changes in this particular file and so we need to
> > > > > > change few things here.
> > > > > 
> > > > > What happened with this?  I'm still carrying the patch.
> > > > 
> > > > This should go in through the thermal tree.  Eduardo?
> > > 
> > > Having waited a long time for any kind of response from Eduardo, I've
> > > given up.  My conclusion is that Eduardo isn't interested in this.
> > > 
> > > I've re-checked, and the AB-BA deadlock is still there in the latest
> > > code.  So, I've taken it upon myself to throw this into my for-next
> > > branch to force the issue - not something I _want_ to do, but I'm doing
> > > this out of frustration.  It's clear to me that "playing nice" by email
> > > does _not_ work with some people.
> > > 
> > > I'm rather hoping that Stephen reports a merge conflict with linux-next
> > > this evening to highlight this situation.  I've added additional commentry
> > > to the commit message on the patch giving the reason why I've done this,
> > > and the relevant message IDs showing the past history.
> > > 
> > > I've not decided whether I'm going to ask Linus to take this patch
> > > directly or not, that rather depends whether there's any co-operation
> > > from Eduardo on this.  I'd rather Eduardo took the patch.
> > > 
> > > The patch I have has had to be updated again for changes to the driver,
> > > but I really don't see the point of re-posting it just for it to be
> > > ignored yet again.
> > > 
> > > I'm really disappointed by this dysfunctional state of affairs, and
> > > that what should be an urgent fix for an observable problem is still
> > > not merged some nine months after it was first identified.
> > 
> > I guess it might help if you sent the updated patch in a new thread.
> 
> That I doubt.  Eduardo has not bothered to reply at _any_ time.  I
> have to question whether there is anyone even reading that email
> address, or whether it's a redirect to /dev/null.  All the evidence I
> have right now is that this Eduardo is a ficticous character.
> 
> I would have at least expected some complaints when I said "I've put
> it in linux-next" but... absolutely nothing.
> 
> So... my only conclusion is that you're all pulling my leg that there
> _is_ this "Eduardo" maintainer who's supposed to be taking patches for
> this stuff.

Well, that's the situation as per MAINTAINERS today.  You seem to be concerned
that it may not reflect the reality, but in that case I can only recommend
sending a patch against MAINTAINERS to remove Eduardo from there.

> As I've said, I'm not bothering with this anymore, it's just far too
> much effort to play these stupid games.

I'm not sure what you mean by "these stupid games" here.

> The deadlock can stay for all I care.

Fair enough.

Thanks,
Rafael



From yh.huang at mediatek.com  Mon Aug 17 19:23:17 2015
From: yh.huang at mediatek.com (YH Huang)
Date: Tue, 18 Aug 2015 10:23:17 +0800
Subject: [PATCH v6 1/3] dt-bindings: pwm: add MediaTek display PWM bindings
In-Reply-To: <20150817132358.GN8453@ulmo.nvidia.com>
References: <1437380237-28961-1-git-send-email-yh.huang@mediatek.com>
 <1437380237-28961-2-git-send-email-yh.huang@mediatek.com>
 <20150817132358.GN8453@ulmo.nvidia.com>
Message-ID: <1439864597.26145.3.camel@mtksdaap41>

On Mon, 2015-08-17 at 15:23 +0200, Thierry Reding wrote:
> On Mon, Jul 20, 2015 at 04:17:15PM +0800, YH Huang wrote:
> > Document the device-tree binding of MediatTek display PWM.
> 
> I already mentioned this a while back: s/MediatTek/MediaTek/.
> 
Sorry, I will correct it to "MediaTek".

Regards,
YH Huang



From edubezval at gmail.com  Tue Aug 18 02:30:49 2015
From: edubezval at gmail.com (Eduardo Valentin)
Date: Tue, 18 Aug 2015 02:30:49 -0700
Subject: 3.18: lockdep problems in cpufreq
In-Reply-To: <4248436.YMvuzoKMLH@vostro.rjw.lan>
References: <20141214213655.GA11285@n2100.arm.linux.org.uk>
 <5160300.5D2Dvly8u9@vostro.rjw.lan>
 <20150813081744.GN7557@n2100.arm.linux.org.uk>
 <4248436.YMvuzoKMLH@vostro.rjw.lan>
Message-ID: <20150818093049.GA26346@localhost.localdomain>

Hi there,

On Mon, Aug 17, 2015 at 6:32 PM, Rafael J. Wysocki <rjw at rjwysocki.net> wrote:

<cut>

>
> Well, that's the situation as per MAINTAINERS today.  You seem to be concerned
> that it may not reflect the reality, but in that case I can only recommend
> sending a patch against MAINTAINERS to remove Eduardo from there.
>
>> As I've said, I'm not bothering with this anymore, it's just far too
>> much effort to play these stupid games.
>
> I'm not sure what you mean by "these stupid games" here.
>
>> The deadlock can stay for all I care.
>
> Fair enough.

I applied the patch. And it has generated the conflict in linux-next, as was mentioned in this thread. I already sent the pull request.

Yes, I missed the thread. Apologize for this and for the inconvenience I have caused. The deadlock will be taken care using Russel's patch.

Thanks Viresh for notifying me.


>
> Thanks,
> Rafael
>

BR,

-- 
Eduardo Bezerra Valentin


From yh.huang at mediatek.com  Mon Aug 17 19:47:48 2015
From: yh.huang at mediatek.com (YH Huang)
Date: Tue, 18 Aug 2015 10:47:48 +0800
Subject: [PATCH v6 2/3] pwm: add MediaTek display PWM driver support
In-Reply-To: <20150817132259.GM8453@ulmo.nvidia.com>
References: <1437380237-28961-1-git-send-email-yh.huang@mediatek.com>
 <1437380237-28961-3-git-send-email-yh.huang@mediatek.com>
 <20150817132259.GM8453@ulmo.nvidia.com>
Message-ID: <1439866068.26145.12.camel@mtksdaap41>

On Mon, 2015-08-17 at 15:23 +0200, Thierry Reding wrote:
> On Mon, Jul 20, 2015 at 04:17:16PM +0800, YH Huang wrote:
> > Add display PWM driver support to modify backlight for MT8173 and MT6595.
> > The PWM has one channel to control the brightness of the display.
> > When the (high_width / period) is closer to 1, the screen is brighter;
> > otherwise, it is darker.
> > 
> > Signed-off-by: YH Huang <yh.huang at mediatek.com>
> > ---
> >  drivers/pwm/Kconfig        |  10 ++
> >  drivers/pwm/Makefile       |   1 +
> >  drivers/pwm/pwm-mtk-disp.c | 232 +++++++++++++++++++++++++++++++++++++++++++++
> >  3 files changed, 243 insertions(+)
> >  create mode 100644 drivers/pwm/pwm-mtk-disp.c
> > 
> > diff --git a/drivers/pwm/Kconfig b/drivers/pwm/Kconfig
> > index b1541f4..f5b03a4 100644
> > --- a/drivers/pwm/Kconfig
> > +++ b/drivers/pwm/Kconfig
> > @@ -211,6 +211,16 @@ config PWM_LPSS_PLATFORM
> >  	  To compile this driver as a module, choose M here: the module
> >  	  will be called pwm-lpss-platform.
> >  
> > +config PWM_MTK_DISP
> > +	tristate "MediaTek display PWM driver"
> > +	depends on ARCH_MEDIATEK || COMPILE_TEST
> 
> This is going to break randconfig builds. From a quick look your driver
> will fail to build at least on architectures that don't set HAVE_IOMEM.
> I know that's quite exotic, but I've had to deal with fallout from
> things like this in the past. If you want || COMPILE_TEST you should at
> least add a "depends on HAVE_IOMEM".
> 
> linux/clk.h seems to have stubs for all of the functions that you use,
> so those shouldn't be a problem.
> 

I will add it and this will be like:

depends on ARCH_MEDIATEK || COMPILE_TEST
depends on HAS_IOMEM

> > +	help
> > +	  Generic PWM framework driver for MediaTek disp-pwm device.
> > +	  The PWM is used to control the backlight brightness for display.
> > +
> > +	  To compile this driver as a module, choose M here: the module
> > +	  will be called pwm-mtk-disp.
> > +
> >  config PWM_MXS
> >  	tristate "Freescale MXS PWM support"
> >  	depends on ARCH_MXS && OF
> [...]
> > diff --git a/drivers/pwm/pwm-mtk-disp.c b/drivers/pwm/pwm-mtk-disp.c
> > new file mode 100644
> > index 0000000..69682a0
> > --- /dev/null
> > +++ b/drivers/pwm/pwm-mtk-disp.c
> > @@ -0,0 +1,232 @@
> > +/*
> > + * MediaTek display pulse-width-modulation controller driver.
> > + * Copyright (c) 2015 MediaTek Inc.
> > + * Author: YH Huang <yh.huang at 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/clk.h>
> > +#include <linux/err.h>
> > +#include <linux/io.h>
> > +#include <linux/module.h>
> > +#include <linux/of.h>
> > +#include <linux/pwm.h>
> > +#include <linux/platform_device.h>
> 
> The above two aren't correctly sorted.
> 

Arrange like this:

#include <linux/platform_device.h>
#include <linux/pwm.h>

> > +#include <linux/slab.h>
> > +
> > +#define DISP_PWM_EN		0x00
> > +#define PWM_ENABLE_MASK		BIT(0)
> > +
> > +#define DISP_PWM_COMMIT		0x08
> > +#define PWM_COMMIT_MASK		BIT(0)
> > +
> > +#define DISP_PWM_CON_0		0x10
> > +#define PWM_CLKDIV_SHIFT	16
> > +#define PWM_CLKDIV_MAX		0x3ff
> > +#define PWM_CLKDIV_MASK		(PWM_CLKDIV_MAX << PWM_CLKDIV_SHIFT)
> > +
> > +#define DISP_PWM_CON_1		0x14
> > +#define PWM_PERIOD_MASK		0xfff
> > +/* Shift log2(PWM_PERIOD_MASK + 1) as divisor */
> > +#define PWM_PERIOD_BIT_SHIFT	12
> 
> There are still two names for the same value here. I thought we had
> agreed on this becoming something like the below?
> 
> 	#define PWM_PERIOD_BIT_SHIFT 12
> 	#define PWM_PERIOD_MASK ((1 << PWM_PERIOD_BIT_SHIFT) - 1)
> 
> Although PWM_PERIOD_BIT_WIDTH would probably be a better name. Or
> PWM_PERIOD_BITS or similar.
> 

I will revise to 

#define PWM_PERIOD_BIT_WIDTH 12
#define PWM_PERIOD_MASK ((1 << PWM_PERIOD_BIT_WIDTH) - 1)

> > +static int mtk_disp_pwm_remove(struct platform_device *pdev)
> > +{
> > +	struct mtk_disp_pwm *mdp = platform_get_drvdata(pdev);
> > +	int ret = pwmchip_remove(&mdp->chip);
> 
> I'd prefer this to be separate lines:
> 
> 	int ret;
> 
> 	ret = pwmchip_remove(&mdp->chip);

OK.

Thanks for your suggestions.

Regards,
YH Huang




From santosh.shilimkar at oracle.com  Mon Aug 17 20:09:17 2015
From: santosh.shilimkar at oracle.com (santosh.shilimkar at oracle.com)
Date: Mon, 17 Aug 2015 20:09:17 -0700
Subject: [PATCH] ARM: keystone: add a work around to handle asynchronous
 external abort
In-Reply-To: <55D25C64.3090107@ti.com>
References: <1439320409-20084-1-git-send-email-m-karicheri2@ti.com>
 <55CDF579.4050408@ti.com> <20150814140934.GX7557@n2100.arm.linux.org.uk>
 <55CE05EC.4040909@oracle.com> <55CE633C.10402@ti.com>
 <20150814215617.GA7557@n2100.arm.linux.org.uk> <55D25C64.3090107@ti.com>
Message-ID: <55D2A1DD.9000007@oracle.com>

Murali,

On 8/17/15 3:12 PM, Murali Karicheri wrote:
> On 08/14/2015 05:56 PM, Russell King - ARM Linux wrote:
>> On Fri, Aug 14, 2015 at 05:53:00PM -0400, Murali Karicheri wrote:
>>> We have spend some time already to debug the root cause. Do you have
>>> idea on
>>> how this was hunted down on OMAP that we can learn from? The bad
>>> address is
>>> NULL and it seems to happen very rarely and is not easily reproducible.
>>> Don't want to put this workaround, but we couldn't track it down
>>> either. So
>>> any help to debug this will be appreciated.
>>
>> If you try applying Lucas' patch, you should receive the abort earlier
>> in the kernel boot up, which may help narrow down what is provoking it.
>>
>
> Unfortunately, this patch causes boot to stop very early just after
> local_abt_enable() is called in early_trap_init(). Before and After
> applying the patch, here is what the boot log looks like. Do you see any
> issue with the patch diff shown below? Patch is applied on top of
> v4.2-rc7. I have some additional base port patches applied to boot
> kernel on my EVM based on a new SoC.
>

 From the logs this seems to be mostly clock related issue for some
peripheral. If the bootloader clock enable all hack still exists,
may be you can try that out.

Another way to debug this is to start disabling peripheral drivers
from the kernel 1 by 1 and see if the issue goes away.

Regards,
Santosh


From shijie.huang at arm.com  Mon Aug 17 20:35:27 2015
From: shijie.huang at arm.com (Huang Shijie)
Date: Tue, 18 Aug 2015 11:35:27 +0800
Subject: [PATCH 3/3] Add ACPI bindings for the EHCI platform driver.
In-Reply-To: <55CCB428.1000404@arm.com>
References: <Pine.LNX.4.44L0.1508131049001.1277-100000@iolanthe.rowland.org>
 <55CCB428.1000404@arm.com>
Message-ID: <20150818033527.GA9990@free64-pc.asiapac.arm.com>

On Thu, Aug 13, 2015 at 10:13:44AM -0500, Jeremy Linton wrote:
Hi Jeremy,

    Please add my tested-by for your next version:

    Tested-by: Huang Shijie <shijie.huang at arm.com>


thanks
Huang Shijie



From shijie.huang at arm.com  Mon Aug 17 20:36:55 2015
From: shijie.huang at arm.com (Huang Shijie)
Date: Tue, 18 Aug 2015 11:36:55 +0800
Subject: [PATCH 1/3] Honor ACPI _CCA attribute setting
In-Reply-To: <55CDF74C.3050703@arm.com>
References: <1439416290-21228-1-git-send-email-jeremy.linton@arm.com>
 <1439416290-21228-2-git-send-email-jeremy.linton@arm.com>
 <55CD4832.7070301@amd.com> <55CDF74C.3050703@arm.com>
Message-ID: <20150818033655.GB9990@free64-pc.asiapac.arm.com>

On Fri, Aug 14, 2015 at 09:12:28AM -0500, Jeremy Linton wrote:
> Hello Suravee,
> 
> On 08/13/2015 08:45 PM, Suravee Suthikulpanit wrote:
> > On 8/13/15 04:51, Jeremy Linton wrote:
> >> ACPI configurations can now mark devices as noncoherent,
> >> support that choice.
> >
> > This change was in my earlier revisions for the original patch series to
> > add ACPI CCA support. At the time, this was pushed back since we were
> > not sure whether this would be a useful case, and whether such hardware
> > exists.
> 
> Yes, I was made aware of that conversation during the review here.
> 
> Basically, the ARM Juno development platform has a mix of coherent and 
> noncoherent devices. The EHCI being one of the primary noncoherent 
> peripherals. Without which, the usefulness of the platform for 
> developing with an ACPI kernel is limited.
> 
Tesed-by: Huang Shijie <shijie.huang at arm.com>



From pankaj.dubey at samsung.com  Mon Aug 17 23:13:28 2015
From: pankaj.dubey at samsung.com (Pankaj Dubey)
Date: Tue, 18 Aug 2015 11:43:28 +0530
Subject: [2/2] ARM: dts: Add missing irq pinctrl for max77686 on smdk5250
In-Reply-To: <CAJKOXPdzhqXFWT0=eXpr+jjs8R4kFAMq2DSSsFHVEZq_PdAN2w@mail.gmail.com>
References: <1416312509-11530-2-git-send-email-yadi.brar@samsung.com>
 <553F68CC.6030504@samsung.com> <5544657A.7010006@gmail.com>
 <CAJKOXPdzhqXFWT0=eXpr+jjs8R4kFAMq2DSSsFHVEZq_PdAN2w@mail.gmail.com>
Message-ID: <55D2CD08.7050106@samsung.com>

Hi Krzysztof,

On Monday 17 August 2015 11:20 AM, Krzysztof Kozlowski wrote:
> 2015-05-02 14:49 GMT+09:00 Krzysztof Kozlowski <k.kozlowski.k at gmail.com>:
>> W dniu 28.04.2015 o 20:02, Pankaj Dubey pisze:
>>> Hi Kukjin,
>>>
>>> Any updated for this patch. Without this PMIC RTC is not working on
>>> SMDK5250.
>>>
>>
>> Could you resend the patch after rebasing it?
>>
>> Best regards,
>> Krzysztof
>
> Dear Pankaj and Yadwinder,
>
> Do you plan to do anything with this patch?
>

Thanks for reminding us. Somehow I missed this.
I will resend the patch shortly after rebasing and testing.

Thanks,
Pankaj Dubey

> Best regards,
> Krzysztof
>
>
>>> Thanks,
>>> Pankaj Dubey
>>>
>>> On Tuesday 18 November 2014 05:38 PM, Yadwinder Singh Brar wrote:
>>>> This patch adds pinctrl configuration for using configuring gpx3-2 as an
>>>> external interrupt from max77686. Though max77686 RTC is enabled and gets
>>>> probed by default, it doesnt work as its unable to get interrupt.
>>>>
>>>> This patch makes max77686 RTC work and also configures it as wakeup
>>>> source.
>>>>
>>>> Signed-off-by: Yadwinder Singh Brar <yadi.brar at samsung.com>
>>>> Reviewed-by: Javier Martinez Canillas <javier.martinez at collabora.co.uk>
>>>> Tested-by: Pankaj Dubey <pankaj.dubey at samsung.com>
>>>>
>>>> ---
>>>> arch/arm/boot/dts/exynos5250-smdk5250.dts |   12 ++++++++++++
>>>>    1 files changed, 12 insertions(+), 0 deletions(-)
>>>>
>>>> diff --git a/arch/arm/boot/dts/exynos5250-smdk5250.dts
>>>> b/arch/arm/boot/dts/exynos5250-smdk5250.dts
>>>> index 95b5b51..19cd918 100644
>>>> --- a/arch/arm/boot/dts/exynos5250-smdk5250.dts
>>>> +++ b/arch/arm/boot/dts/exynos5250-smdk5250.dts
>>>> @@ -131,6 +131,9 @@
>>>>            reg = <0x09>;
>>>>            interrupt-parent = <&gpx3>;
>>>>            interrupts = <2 IRQ_TYPE_NONE>;
>>>> +        pinctrl-names = "default";
>>>> +        pinctrl-0 = <&max77686_irq>;
>>>> +        wakeup-source;
>>>>
>>>>            voltage-regulators {
>>>>                ldo1_reg: LDO1 {
>>>> @@ -411,3 +414,12 @@
>>>>            };
>>>>        };
>>>>    };
>>>> +
>>>> +&pinctrl_0 {
>>>> +    max77686_irq: max77686-irq {
>>>> +        samsung,pins = "gpx3-2";
>>>> +        samsung,pin-function = <0xf>;
>>>> +        samsung,pin-pud = <0>;
>>>> +        samsung,pin-drv = <0>;
>>>> +    };
>>>> +};
>>>>
>>> --
>>> To unsubscribe from this list: send the line "unsubscribe
>>> linux-samsung-soc" in
>>> the body of a message to majordomo at vger.kernel.org
>>> More majordomo info at  http://vger.kernel.org/majordomo-info.html
>>
>


From jszhang at marvell.com  Mon Aug 17 23:16:00 2015
From: jszhang at marvell.com (Jisheng Zhang)
Date: Tue, 18 Aug 2015 14:16:00 +0800
Subject: [PATCH v5 4/4] arm64, dt, thunderx: Add initial dts for Cavium
 Thunder SoC in 2 Node topology.
In-Reply-To: <1439570374-4079-5-git-send-email-gkulkarni@caviumnetworks.com>
References: <1439570374-4079-1-git-send-email-gkulkarni@caviumnetworks.com>
 <1439570374-4079-5-git-send-email-gkulkarni@caviumnetworks.com>
Message-ID: <20150818141600.70076adc@xhacker>

Dear Ganapatrao,

On Fri, 14 Aug 2015 22:09:34 +0530
Ganapatrao Kulkarni <gkulkarni at caviumnetworks.com> wrote:

> adding dt file for Cavium's Thunder SoC in 2 Node topology
> using arm,associativity device node property.
> 
> Signed-off-by: Ganapatrao Kulkarni <gkulkarni at caviumnetworks.com>
> ---
>  arch/arm64/boot/dts/cavium/Makefile             |   2 +-
>  arch/arm64/boot/dts/cavium/thunder-88xx-2n.dts  |  78 +++
>  arch/arm64/boot/dts/cavium/thunder-88xx-2n.dtsi | 790 ++++++++++++++++++++++++
>  3 files changed, 869 insertions(+), 1 deletion(-)
>  create mode 100644 arch/arm64/boot/dts/cavium/thunder-88xx-2n.dts
>  create mode 100644 arch/arm64/boot/dts/cavium/thunder-88xx-2n.dtsi
> 
> diff --git a/arch/arm64/boot/dts/cavium/Makefile b/arch/arm64/boot/dts/cavium/Makefile
> index e34f89d..7fe7067 100644
> --- a/arch/arm64/boot/dts/cavium/Makefile
> +++ b/arch/arm64/boot/dts/cavium/Makefile
> @@ -1,4 +1,4 @@
> -dtb-$(CONFIG_ARCH_THUNDER) += thunder-88xx.dtb
> +dtb-$(CONFIG_ARCH_THUNDER) += thunder-88xx.dtb thunder-88xx-2n.dtb
>  
>  always		:= $(dtb-y)
>  subdir-y	:= $(dts-dirs)
> diff --git a/arch/arm64/boot/dts/cavium/thunder-88xx-2n.dts b/arch/arm64/boot/dts/cavium/thunder-88xx-2n.dts
> new file mode 100644
> index 0000000..adbd3a9
> --- /dev/null
> +++ b/arch/arm64/boot/dts/cavium/thunder-88xx-2n.dts
> @@ -0,0 +1,78 @@
> +/*
> + * Cavium Thunder DTS file - Thunder board description
> + *
> + * Copyright (C) 2014, Cavium Inc.
> + *
> + * This file is dual-licensed: you can use it either under the terms
> + * of the GPL or the X11 license, at your option. Note that this dual
> + * licensing only applies to this file, and not this project as a
> + * whole.
> + *
> + *  a) This library 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 library 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.
> + *
> + *     You should have received a copy of the GNU General Public
> + *     License along with this library; if not, write to the Free
> + *     Software Foundation, Inc., 51 Franklin St, Fifth Floor, Boston,
> + *     MA 02110-1301 USA

From the kernel logs, seems this FSF mailing address isn't valid.
It's better to remove this paragraph about writing to FSF

I also submitted a patch to remove this paragraph from existing thunder-88xx dts:
http://lists.infradead.org/pipermail/linux-arm-kernel/2015-July/358225.html

Thanks,
Jisheng


From pankaj.dubey at samsung.com  Mon Aug 17 23:27:13 2015
From: pankaj.dubey at samsung.com (Pankaj Dubey)
Date: Tue, 18 Aug 2015 11:57:13 +0530
Subject: [2/2] ARM: dts: Add missing irq pinctrl for max77686 on smdk5250
In-Reply-To: <CAJKOXPdzhqXFWT0=eXpr+jjs8R4kFAMq2DSSsFHVEZq_PdAN2w@mail.gmail.com>
References: <1416312509-11530-2-git-send-email-yadi.brar@samsung.com>
 <553F68CC.6030504@samsung.com> <5544657A.7010006@gmail.com>
 <CAJKOXPdzhqXFWT0=eXpr+jjs8R4kFAMq2DSSsFHVEZq_PdAN2w@mail.gmail.com>
Message-ID: <55D2D041.9020700@samsung.com>

Hi Krzysztof,

On Monday 17 August 2015 11:20 AM, Krzysztof Kozlowski wrote:
> 2015-05-02 14:49 GMT+09:00 Krzysztof Kozlowski <k.kozlowski.k at gmail.com>:
>> W dniu 28.04.2015 o 20:02, Pankaj Dubey pisze:
>>> Hi Kukjin,
>>>
>>> Any updated for this patch. Without this PMIC RTC is not working on
>>> SMDK5250.
>>>
>>
>> Could you resend the patch after rebasing it?
>>
>> Best regards,
>> Krzysztof
>
> Dear Pankaj and Yadwinder,
>
> Do you plan to do anything with this patch?
>
> Best regards,
> Krzysztof
>
>

Just noticed that the patch in subject is already merged in kgene tree.
There was another patch "[1/2]: ARM: dts: Fix bootup issue on smdk5250" 
which was posted along with this is still not merged. Resending it once 
again.

[1]: http://www.spinics.net/lists/linux-samsung-soc/msg39100.html

Thanks,
Pankaj Dubey
>>> Thanks,
>>> Pankaj Dubey
>>>
>>> On Tuesday 18 November 2014 05:38 PM, Yadwinder Singh Brar wrote:
>>>> This patch adds pinctrl configuration for using configuring gpx3-2 as an
>>>> external interrupt from max77686. Though max77686 RTC is enabled and gets
>>>> probed by default, it doesnt work as its unable to get interrupt.
>>>>
>>>> This patch makes max77686 RTC work and also configures it as wakeup
>>>> source.
>>>>
>>>> Signed-off-by: Yadwinder Singh Brar <yadi.brar at samsung.com>
>>>> Reviewed-by: Javier Martinez Canillas <javier.martinez at collabora.co.uk>
>>>> Tested-by: Pankaj Dubey <pankaj.dubey at samsung.com>
>>>>
>>>> ---
>>>> arch/arm/boot/dts/exynos5250-smdk5250.dts |   12 ++++++++++++
>>>>    1 files changed, 12 insertions(+), 0 deletions(-)
>>>>
>>>> diff --git a/arch/arm/boot/dts/exynos5250-smdk5250.dts
>>>> b/arch/arm/boot/dts/exynos5250-smdk5250.dts
>>>> index 95b5b51..19cd918 100644
>>>> --- a/arch/arm/boot/dts/exynos5250-smdk5250.dts
>>>> +++ b/arch/arm/boot/dts/exynos5250-smdk5250.dts
>>>> @@ -131,6 +131,9 @@
>>>>            reg = <0x09>;
>>>>            interrupt-parent = <&gpx3>;
>>>>            interrupts = <2 IRQ_TYPE_NONE>;
>>>> +        pinctrl-names = "default";
>>>> +        pinctrl-0 = <&max77686_irq>;
>>>> +        wakeup-source;
>>>>
>>>>            voltage-regulators {
>>>>                ldo1_reg: LDO1 {
>>>> @@ -411,3 +414,12 @@
>>>>            };
>>>>        };
>>>>    };
>>>> +
>>>> +&pinctrl_0 {
>>>> +    max77686_irq: max77686-irq {
>>>> +        samsung,pins = "gpx3-2";
>>>> +        samsung,pin-function = <0xf>;
>>>> +        samsung,pin-pud = <0>;
>>>> +        samsung,pin-drv = <0>;
>>>> +    };
>>>> +};
>>>>
>>> --
>>> To unsubscribe from this list: send the line "unsubscribe
>>> linux-samsung-soc" in
>>> the body of a message to majordomo at vger.kernel.org
>>> More majordomo info at  http://vger.kernel.org/majordomo-info.html
>>
>


From pankaj.dubey at samsung.com  Mon Aug 17 23:29:20 2015
From: pankaj.dubey at samsung.com (Pankaj Dubey)
Date: Tue, 18 Aug 2015 11:59:20 +0530
Subject: [PATCHi v2] ARM: dts: Fix bootup issue on smdk5250
Message-ID: <1439879360-21150-1-git-send-email-pankaj.dubey@samsung.com>

From: Yadwinder Singh Brar <yadi.brar01 at gmail.com>

With default config on smdk5250 latest tree throws below message :

[    2.226049] thermal thermal_zone0: critical temperature reached(224 C),shutting down
[    2.227840] reboot: Failed to start orderly shutdown: forcing the issue

and hangs randomly because it reads wrong temperature value.

I can't figure out any direct relation between LDO10 and TMU from board
schematics which I have. So making LDO10 always-on to fix issue for now.

Signed-off-by: Yadwinder Singh Brar <yadi.brar01 at gmail.com>
[pankaj.dubey: resubmitted after rebasing to latest kgene tree]
Signed-off-by: Pankaj Dubey <pankaj.dubey at samsung.com>
Tested-by: Pankaj Dubey <pankaj.dubey at samsung.com>
---
Resending this patch after rebasing. Previous discussion can be found here [1]


[1]: http://www.spinics.net/lists/linux-samsung-soc/msg39100.html

Changes since v1:
 - Rebased on latest kgene tree, test booting and s2r on SMDK5250 board.
 - Removed Yadwinder Singh's Samsung's email id as it's no more valid.
 - Added my Signed-off-by for touching this file and patch.

 arch/arm/boot/dts/exynos5250-smdk5250.dts | 1 +
 1 file changed, 1 insertion(+)

diff --git a/arch/arm/boot/dts/exynos5250-smdk5250.dts b/arch/arm/boot/dts/exynos5250-smdk5250.dts
index 15aea76..c625e71 100644
--- a/arch/arm/boot/dts/exynos5250-smdk5250.dts
+++ b/arch/arm/boot/dts/exynos5250-smdk5250.dts
@@ -197,6 +197,7 @@
 				regulator-name = "P1.8V_LDO_OUT10";
 				regulator-min-microvolt = <1800000>;
 				regulator-max-microvolt = <1800000>;
+				regulator-always-on;
 			};
 
 			ldo11_reg: LDO11 {
-- 
2.4.5



From anurag.kumar.vulisha at xilinx.com  Mon Aug 17 23:45:53 2015
From: anurag.kumar.vulisha at xilinx.com (Anurag Kumar Vulisha)
Date: Tue, 18 Aug 2015 06:45:53 +0000
Subject: [PATCH] dmaengine: vdma: Add 64 bit addressing support to the
 driver
In-Reply-To: <1438775257-3511-1-git-send-email-anuragku@xilinx.com>
References: <1438775257-3511-1-git-send-email-anuragku@xilinx.com>
Message-ID: <3802E9A6666DF54886E2B9CBF743BA9801BF7EF1@XAP-PVEXMBX01.xlnx.xilinx.com>

Ping?

> -----Original Message-----
> From: Anurag Kumar Vulisha [mailto:anurag.kumar.vulisha at xilinx.com]
> Sent: Wednesday, August 05, 2015 5:18 PM
> To: dan.j.williams at intel.com; vinod.koul at intel.com; Michal Simek; Soren
> Brinkmann; srikanth.thokala at xilinx.com; maxime.ripard at free-
> electrons.com; laurent.pinchart at ideasonboard.com; Appana Durga
> Kedareswara Rao
> Cc: dmaengine at vger.kernel.org; linux-kernel at vger.kernel.org; linux-arm-
> kernel at lists.infradead.org; Anurag Kumar Vulisha
> Subject: [PATCH] dmaengine: vdma: Add 64 bit addressing support to the
> driver
> 
> This patch adds the 64 bit addressing support to the vdma driver.
> 
> Signed-off-by: Anurag Kumar Vulisha <anuragku at xilinx.com>
> ---
>  drivers/dma/Kconfig              |    2 +-
>  drivers/dma/xilinx/xilinx_vdma.c |   36
> ++++++++++++++++++++++++++++++------
>  2 files changed, 31 insertions(+), 7 deletions(-)
> 
> diff --git a/drivers/dma/Kconfig b/drivers/dma/Kconfig index
> bda2cb0..a7cd0a8 100644
> --- a/drivers/dma/Kconfig
> +++ b/drivers/dma/Kconfig
> @@ -398,7 +398,7 @@ config FSL_EDMA
> 
>  config XILINX_VDMA
>  	tristate "Xilinx AXI VDMA Engine"
> -	depends on (ARCH_ZYNQ || MICROBLAZE)
> +	depends on (ARCH_ZYNQ || MICROBLAZE || ARM64)
>  	select DMA_ENGINE
>  	help
>  	  Enable support for Xilinx AXI VDMA Soft IP.
> diff --git a/drivers/dma/xilinx/xilinx_vdma.c
> b/drivers/dma/xilinx/xilinx_vdma.c
> index d8434d4..3dcbd29 100644
> --- a/drivers/dma/xilinx/xilinx_vdma.c
> +++ b/drivers/dma/xilinx/xilinx_vdma.c
> @@ -98,7 +98,11 @@
>  #define XILINX_VDMA_FRMDLY_STRIDE_FRMDLY_SHIFT	24
>  #define XILINX_VDMA_FRMDLY_STRIDE_STRIDE_SHIFT	0
> 
> +#if defined(CONFIG_PHYS_ADDR_T_64BIT)
> +#define XILINX_VDMA_REG_START_ADDRESS(n)	(0x000c + 8 * (n))
> +#else
>  #define XILINX_VDMA_REG_START_ADDRESS(n)	(0x000c + 4 * (n))
> +#endif
> 
>  /* HW specific definitions */
>  #define XILINX_VDMA_MAX_CHANS_PER_DEVICE	0x2
> @@ -143,16 +147,16 @@
>   * @next_desc: Next Descriptor Pointer @0x00
>   * @pad1: Reserved @0x04
>   * @buf_addr: Buffer address @0x08
> - * @pad2: Reserved @0x0C
> - * @vsize: Vertical Size @0x10
> - * @hsize: Horizontal Size @0x14
> + * @pad2: Reserved @0x10
> + * @vsize: Vertical Size @0x14
> + * @hsize: Horizontal Size @0x18
>   * @stride: Number of bytes between the first
> - *	    pixels of each horizontal line @0x18
> + *	    pixels of each horizontal line @0x1C
>   */
>  struct xilinx_vdma_desc_hw {
>  	u32 next_desc;
>  	u32 pad1;
> -	u32 buf_addr;
> +	u64 buf_addr;
>  	u32 pad2;
>  	u32 vsize;
>  	u32 hsize;
> @@ -272,6 +276,20 @@ static inline void vdma_desc_write(struct
> xilinx_vdma_chan *chan, u32 reg,
>  	vdma_write(chan, chan->desc_offset + reg, value);  }
> 
> +#if defined(CONFIG_PHYS_ADDR_T_64BIT)
> +static inline void vdma_desc_write_64(struct xilinx_vdma_chan *chan, u32
> reg,
> +				 u64 value)
> +{
> +	/* Write the lsb 32 bits*/
> +	writel(lower_32_bits(value),
> +			chan->xdev->regs + chan->desc_offset + reg);
> +
> +	/* Write the msb 32 bits */
> +	writel(upper_32_bits(value),
> +			chan->xdev->regs + chan->desc_offset + reg + 4); }
> #endif
> +
>  static inline u32 vdma_ctrl_read(struct xilinx_vdma_chan *chan, u32 reg)  {
>  	return vdma_read(chan, chan->ctrl_offset + reg); @@ -700,9 +718,15
> @@ static void xilinx_vdma_start_transfer(struct xilinx_vdma_chan *chan)
>  		int i = 0;
> 
>  		list_for_each_entry(segment, &desc->segments, node) {
> -			vdma_desc_write(chan,
> +#if defined(CONFIG_PHYS_ADDR_T_64BIT)
> +			vdma_desc_write_64(chan,
> 
> 	XILINX_VDMA_REG_START_ADDRESS(i++),
>  					segment->hw.buf_addr);
> +#else
> +			vdma_desc_write(chan,
> +
> 	XILINX_VDMA_REG_START_ADDRESS(i++),
> +					(u32)segment->hw.buf_addr);
> +#endif
>  			last = segment;
>  		}
> 
> --
> 1.7.4



From lee.jones at linaro.org  Mon Aug 17 23:52:07 2015
From: lee.jones at linaro.org (Lee Jones)
Date: Tue, 18 Aug 2015 07:52:07 +0100
Subject: [PATCH v2 18/21] mfd: htc-pasic3: Prepare driver for leds-pasic3
In-Reply-To: <55D25ABC.1000405@tul.cz>
References: <cover.1439843482.git.petr.cvek@tul.cz> <55D25ABC.1000405@tul.cz>
Message-ID: <20150818065207.GC6180@x1>

On Tue, 18 Aug 2015, Petr Cvek wrote:

> Fix register definitions and prepare structures for new leds-pasic3
> driver.
> 
> Signed-off-by: Petr Cvek <petr.cvek at tul.cz>
> ---
>  drivers/mfd/htc-pasic3.c       | 54 ++++++++++++++++-----------
>  include/linux/mfd/htc-pasic3.h | 85 +++++++++++++++++++++++++++++++-----------
>  2 files changed, 97 insertions(+), 42 deletions(-)
> 
> diff --git a/drivers/mfd/htc-pasic3.c b/drivers/mfd/htc-pasic3.c
> index e88d4f6..16e156d 100644
> --- a/drivers/mfd/htc-pasic3.c
> +++ b/drivers/mfd/htc-pasic3.c
> @@ -3,6 +3,9 @@
>   *
>   * Copyright (C) 2006 Philipp Zabel <philipp.zabel at gmail.com>
>   *
> + * 2015:	Added registers for LED and RESET, see htc-pasic3.h
> + *		-- Petr Cvek
> + *

This is pretty unconventional.

Please look to see what others have done.

>   * 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; version 2 of the License.
> @@ -21,15 +24,10 @@
>  #include <linux/mfd/htc-pasic3.h>
>  #include <linux/slab.h>
>  
> -struct pasic3_data {
> -	void __iomem *mapping;
> -	unsigned int bus_shift;
> -};
> -
>  #define REG_ADDR  5
>  #define REG_DATA  6
>  
> -#define READ_MODE 0x80
> +#define READ_MODE BIT(7)
>  
>  /*
>   * write to a secondary register on the PASIC3
> @@ -76,24 +74,36 @@ static struct mfd_cell led_cell __initdata = {
>  static int ds1wm_enable(struct platform_device *pdev)
>  {
>  	struct device *dev = pdev->dev.parent;
> -	int c;
> +	struct pasic3_data *asic = platform_get_drvdata(pdev);
> +	unsigned long flags;
> +	u8 c;
> +
> +	spin_lock_irqsave(&asic->lock, flags);
> +
> +	c = pasic3_read_register(dev, PASIC3_GPIO);
> +	pasic3_write_register(dev, PASIC3_GPIO, c & ~DS1WM_NEN);
>  
> -	c = pasic3_read_register(dev, 0x28);
> -	pasic3_write_register(dev, 0x28, c & 0x7f);
> +	spin_unlock_irqrestore(&asic->lock, flags);
>  
> -	dev_dbg(dev, "DS1WM OWM_EN low (active) %02x\n", c & 0x7f);
> +	dev_dbg(dev, "DS1WM OWM_EN low (active) %02lx\n", c & ~DS1WM_NEN);
>  	return 0;
>  }
>  
>  static int ds1wm_disable(struct platform_device *pdev)
>  {
>  	struct device *dev = pdev->dev.parent;
> -	int c;
> +	struct pasic3_data *asic = platform_get_drvdata(pdev);
> +	unsigned long flags;
> +	u8 c;
> +
> +	spin_lock_irqsave(&asic->lock, flags);
> +
> +	c = pasic3_read_register(dev, PASIC3_GPIO);
> +	pasic3_write_register(dev, PASIC3_GPIO, c | DS1WM_NEN);
>  
> -	c = pasic3_read_register(dev, 0x28);
> -	pasic3_write_register(dev, 0x28, c | 0x80);
> +	spin_unlock_irqrestore(&asic->lock, flags);
>  
> -	dev_dbg(dev, "DS1WM OWM_EN high (inactive) %02x\n", c | 0x80);
> +	dev_dbg(dev, "DS1WM OWM_EN high (inactive) %02lx\n", c | DS1WM_NEN);
>  	return 0;
>  }
>  
> @@ -130,6 +140,7 @@ static int __init pasic3_probe(struct platform_device *pdev)
>  	struct device *dev = &pdev->dev;
>  	struct pasic3_data *asic;
>  	struct resource *r;
> +	struct pasic3_leds_pdata *leds_pdata;
>  	int ret;
>  	int irq = 0;
>  
> @@ -162,6 +173,8 @@ static int __init pasic3_probe(struct platform_device *pdev)
>  	/* calculate bus shift from mem resource */
>  	asic->bus_shift = (resource_size(r) - 5) >> 3;
>  
> +	spin_lock_init(&asic->lock);
> +
>  	if (pdata && pdata->clock_rate) {
>  		ds1wm_pdata.clock_rate = pdata->clock_rate;
>  		/* the first 5 PASIC3 registers control the DS1WM */
> @@ -172,13 +185,12 @@ static int __init pasic3_probe(struct platform_device *pdev)
>  			dev_warn(dev, "failed to register DS1WM\n");
>  	}
>  
> -	if (pdata && pdata->led_pdata) {
> -		led_cell.platform_data = pdata->led_pdata;
> -		led_cell.pdata_size = sizeof(struct pasic3_leds_machinfo);
> -		ret = mfd_add_devices(&pdev->dev, pdev->id, &led_cell, 1, r,
> -				      0, NULL);
> -		if (ret < 0)
> -			dev_warn(dev, "failed to register LED device\n");
> +	if (pdata && pdata->pasic3_leds) {
> +		leds_pdata = dev_get_platdata(&pdata->pasic3_leds->dev);

Whoa!  You're passing a pointer to a device through pdata?

I don't like that at all.  Please explain.

> +		if (leds_pdata) {
> +			leds_pdata->mfd_dev = dev;
> +			platform_device_register(pdata->pasic3_leds);

What's the idea here?

> +		}
>  	}
>  
>  	return 0;
> diff --git a/include/linux/mfd/htc-pasic3.h b/include/linux/mfd/htc-pasic3.h
> index 3d3ed67..91a27b6 100644
> --- a/include/linux/mfd/htc-pasic3.h
> +++ b/include/linux/mfd/htc-pasic3.h
> @@ -2,6 +2,7 @@
>   * HTC PASIC3 driver - LEDs and DS1WM
>   *
>   * Copyright (c) 2007 Philipp Zabel <philipp.zabel at gmail.com>
> + * Copyright (c) 2015 Petr Cvek <petr.cvek at tul.cz>
>   *
>   * This file is subject to the terms and conditions of the GNU General Public
>   * License.  See the file COPYING in the main directory of this archive for
> @@ -18,37 +19,79 @@
>  extern void pasic3_write_register(struct device *dev, u32 reg, u8 val);
>  extern u8 pasic3_read_register(struct device *dev, u32 reg);
>  
> -/*
> - * mask for registers 0x20,0x21,0x22
> - */
> -#define PASIC3_MASK_LED0 0x04
> -#define PASIC3_MASK_LED1 0x08
> -#define PASIC3_MASK_LED2 0x40
> +#define PASIC3_CH0_DELAY_ON	0x00
> +#define PASIC3_CH0_DELAY_OFF	0x01
> +#define PASIC3_CH1_DELAY_ON	0x02
> +#define PASIC3_CH1_DELAY_OFF	0x03
> +#define PASIC3_CH2_DELAY_ON	0x04
> +#define PASIC3_CH2_DELAY_OFF	0x05
> +#define PASIC3_DELAY_MASK	0x7f
> +
> +#define PASIC3_CH_CONTROL	0x06
> +#define		R06_CH0_EN		BIT(0)
> +#define		R06_CH1_EN		BIT(1)
> +#define		R06_CH2_EN		BIT(2)
> +#define		R06_CH0_FORCE_ON	BIT(3)
> +#define		R06_CH1_FORCE_ON	BIT(4)
> +#define		R06_CH2_FORCE_ON	BIT(5)
>  
>  /*
> - * bits in register 0x06
> + * pwm_ch0_out | force_on | (bit0 & bit1 & bit2)
> + * pwm_ch1_out | force_on | (bit0 & bit1 & bit2)
> + * pwm_ch2_out | force_on | (bit2?bit0:(bit0 & ! bit1))

Please space this out properly.

>   */
> -#define PASIC3_BIT2_LED0 0x08
> -#define PASIC3_BIT2_LED1 0x10
> -#define PASIC3_BIT2_LED2 0x20
> +
> +#define PASIC3_MASK_A	0x20
> +#define PASIC3_MASK_B	0x21
> +#define PASIC3_MASK_C	0x22
> +#define		MASK_CH0	BIT(2)
> +#define		MASK_CH1	BIT(3)
> +#define		MASK_CH2	BIT(6)
> +#define PASIC3_GPIO	0x28
> +#define		DS1WM_NEN	BIT(7)
> +#define PASIC3_SYS	0x2a
> +
> +/* NORMAL_RST, CAM_PWR_RST and UNKNOWN will autoclear, set STATUS */
> +#define		NORMAL_RST	BIT(0)
> +#define		CAM_PWR_RST	BIT(1)
> +#define		UNKNOWN	BIT(2)
> +#define		STATUS_NORMAL_RST	BIT(4)
> +#define		STATUS_CAM_PWR_RST	BIT(5)
> +#define		STATUS_UNKNOWN		BIT(6)
> +
> +/* FIXME/TODO reset sources */
> +#define PASIC3_RST_EN	0x2c
> +#define		EN_NORMAL_RST	0x40
> +#define		EN_DOOR_RST	0x42
>  
>  struct pasic3_led {
> -	struct led_classdev         led;
> -	unsigned int                hw_num;
> -	unsigned int                bit2;
> -	unsigned int                mask;
> -	struct pasic3_leds_machinfo *pdata;
> +	char	name[24];
> +	char	default_trigger[80];
> +	int	hw_num;
> +	u8	bit_blink_en;
> +	u8	bit_force_on;
> +	u8	bit_mask;
> +	u8	reg_delay_on;
> +	u8	reg_delay_off;
>  };
>  
> -struct pasic3_leds_machinfo {
> -	unsigned int      num_leds;
> -	unsigned int      power_gpio;
> +struct pasic3_leds_pdata {
>  	struct pasic3_led *leds;
> +	int num_leds;
> +	int power_gpio;
> +	int power_gpio_users;
> +	struct device *mfd_dev;
>  };
>  
> -struct pasic3_platform_data {
> -	struct pasic3_leds_machinfo *led_pdata;
> -	unsigned int                 clock_rate;
> +struct pasic3_data {
> +	void __iomem *mapping;
> +	unsigned int bus_shift;
> +	spinlock_t lock;
>  };
>  
> +struct pasic3_platform_data {
> +	unsigned int clock_rate;
> +	struct pasic3_led *leds;
> +	struct platform_device *pasic3_leds;
> +};

If you can separate these with a TAB like the rest of the file, that
would be preferred.

>  #endif

-- 
Lee Jones
Linaro STMicroelectronics Landing Team Lead
Linaro.org ? Open source software for ARM SoCs
Follow Linaro: Facebook | Twitter | Blog


From k.kozlowski at samsung.com  Tue Aug 18 00:00:05 2015
From: k.kozlowski at samsung.com (Krzysztof Kozlowski)
Date: Tue, 18 Aug 2015 16:00:05 +0900
Subject: [2/2] ARM: dts: Add missing irq pinctrl for max77686 on smdk5250
In-Reply-To: <55D2D041.9020700@samsung.com>
References: <1416312509-11530-2-git-send-email-yadi.brar@samsung.com>
 <553F68CC.6030504@samsung.com> <5544657A.7010006@gmail.com>
 <CAJKOXPdzhqXFWT0=eXpr+jjs8R4kFAMq2DSSsFHVEZq_PdAN2w@mail.gmail.com>
 <55D2D041.9020700@samsung.com>
Message-ID: <55D2D7F5.4020009@samsung.com>

On 18.08.2015 15:27, Pankaj Dubey wrote:
> Hi Krzysztof,
> 
> On Monday 17 August 2015 11:20 AM, Krzysztof Kozlowski wrote:
>> 2015-05-02 14:49 GMT+09:00 Krzysztof Kozlowski <k.kozlowski.k at gmail.com>:
>>> W dniu 28.04.2015 o 20:02, Pankaj Dubey pisze:
>>>> Hi Kukjin,
>>>>
>>>> Any updated for this patch. Without this PMIC RTC is not working on
>>>> SMDK5250.
>>>>
>>>
>>> Could you resend the patch after rebasing it?
>>>
>>> Best regards,
>>> Krzysztof
>>
>> Dear Pankaj and Yadwinder,
>>
>> Do you plan to do anything with this patch?
>>
>> Best regards,
>> Krzysztof
>>
>>
> 
> Just noticed that the patch in subject is already merged in kgene tree.

Yes, you're right.

> There was another patch "[1/2]: ARM: dts: Fix bootup issue on smdk5250"
> which was posted along with this is still not merged. Resending it once
> again.
> 
> [1]: http://www.spinics.net/lists/linux-samsung-soc/msg39100.html

Thanks!

Best regards,
Krzysztof



From javier at osg.samsung.com  Tue Aug 18 00:01:21 2015
From: javier at osg.samsung.com (Javier Martinez Canillas)
Date: Tue, 18 Aug 2015 09:01:21 +0200
Subject: [PATCH] ARM: exynos_defconfig: Enable CROS_EC_PROTO for ChromeOS EC
 mfd driver
Message-ID: <1439881281-22054-1-git-send-email-javier@osg.samsung.com>

The ChromeOS mfd driver (MFD_CROS_EC) select the CROS_EC_PROTO config
symbol because the driver uses some communication helper functions in
drivers/platform/chrome/cros_ec_proto.c but other drivers depends on
CROS_EC_PROTO instead. Mixing select and depends can lead to circular
Kconfig dependencies so the MFD_CROS_EC select should be changed to a
depends on CROS_EC_PROTO instead.

But doing so will break git bisect-ability since MFD_CROS_EC will not
be enabled anymore unless the default configs first explicitly enable
the CROS_EC_PROTO dependency.

Signed-off-by: Javier Martinez Canillas <javier at osg.samsung.com>
---
 arch/arm/configs/exynos_defconfig | 1 +
 1 file changed, 1 insertion(+)

diff --git a/arch/arm/configs/exynos_defconfig b/arch/arm/configs/exynos_defconfig
index 1ff2bfa2e183..537391ea37ac 100644
--- a/arch/arm/configs/exynos_defconfig
+++ b/arch/arm/configs/exynos_defconfig
@@ -177,6 +177,7 @@ CONFIG_DMADEVICES=y
 CONFIG_PL330_DMA=y
 CONFIG_CHROME_PLATFORMS=y
 CONFIG_CROS_EC_CHARDEV=y
+CONFIG_CROS_EC_PROTO=y
 CONFIG_COMMON_CLK_MAX77686=y
 CONFIG_COMMON_CLK_MAX77802=y
 CONFIG_COMMON_CLK_S2MPS11=y
-- 
2.4.3



From k.kozlowski at samsung.com  Tue Aug 18 00:02:37 2015
From: k.kozlowski at samsung.com (Krzysztof Kozlowski)
Date: Tue, 18 Aug 2015 16:02:37 +0900
Subject: [PATCHi v2] ARM: dts: Fix bootup issue on smdk5250
In-Reply-To: <1439879360-21150-1-git-send-email-pankaj.dubey@samsung.com>
References: <1439879360-21150-1-git-send-email-pankaj.dubey@samsung.com>
Message-ID: <55D2D88D.6090200@samsung.com>

On 18.08.2015 15:29, Pankaj Dubey wrote:
> From: Yadwinder Singh Brar <yadi.brar01 at gmail.com>
> 
> With default config on smdk5250 latest tree throws below message :
> 
> [    2.226049] thermal thermal_zone0: critical temperature reached(224 C),shutting down
> [    2.227840] reboot: Failed to start orderly shutdown: forcing the issue
> 
> and hangs randomly because it reads wrong temperature value.
> 
> I can't figure out any direct relation between LDO10 and TMU from board
> schematics which I have. So making LDO10 always-on to fix issue for now.
> 
> Signed-off-by: Yadwinder Singh Brar <yadi.brar01 at gmail.com>
> [pankaj.dubey: resubmitted after rebasing to latest kgene tree]
> Signed-off-by: Pankaj Dubey <pankaj.dubey at samsung.com>
> Tested-by: Pankaj Dubey <pankaj.dubey at samsung.com>
> ---
> Resending this patch after rebasing. Previous discussion can be found here [1]
> 
> 
> [1]: http://www.spinics.net/lists/linux-samsung-soc/msg39100.html
> 
> Changes since v1:
>  - Rebased on latest kgene tree, test booting and s2r on SMDK5250 board.
>  - Removed Yadwinder Singh's Samsung's email id as it's no more valid.
>  - Added my Signed-off-by for touching this file and patch.
> 
>  arch/arm/boot/dts/exynos5250-smdk5250.dts | 1 +
>  1 file changed, 1 insertion(+)

Since previous discussion ([1] above) there have not been any updates on
cause of this issue so I think this should go in:

Acked-by: Krzysztof Kozlowski <k.kozlowski at samsung.com>

Best regards,
Krzysztof



From javier at osg.samsung.com  Tue Aug 18 00:06:39 2015
From: javier at osg.samsung.com (Javier Martinez Canillas)
Date: Tue, 18 Aug 2015 09:06:39 +0200
Subject: [PATCH] ARM: tegra: Enable CROS_EC_PROTO for ChromeOS EC mfd driver
Message-ID: <1439881599-22348-1-git-send-email-javier@osg.samsung.com>

The ChromeOS mfd driver (MFD_CROS_EC) select the CROS_EC_PROTO config
symbol because the driver uses some communication helper functions in
drivers/platform/chrome/cros_ec_proto.c but other drivers depends on
CROS_EC_PROTO instead. Mixing select and depends can lead to circular
Kconfig dependencies so the MFD_CROS_EC select should be changed to a
depends on CROS_EC_PROTO instead.

But doing so will break git bisect-ability since MFD_CROS_EC will not
be enabled anymore unless the default configs first explicitly enable
the CROS_EC_PROTO dependency.

Also enable CHROME_PLATFORMS since the CROS_EC_PROTO symbol is inside
that submenu.

Signed-off-by: Javier Martinez Canillas <javier at osg.samsung.com>
---
 arch/arm/configs/tegra_defconfig | 2 ++
 1 file changed, 2 insertions(+)

diff --git a/arch/arm/configs/tegra_defconfig b/arch/arm/configs/tegra_defconfig
index 9808581176cc..03e775a70c6e 100644
--- a/arch/arm/configs/tegra_defconfig
+++ b/arch/arm/configs/tegra_defconfig
@@ -254,6 +254,8 @@ CONFIG_KEYBOARD_NVEC=y
 CONFIG_SERIO_NVEC_PS2=y
 CONFIG_NVEC_POWER=y
 CONFIG_NVEC_PAZ00=y
+CONFIG_CHROME_PLATFORMS=y
+CONFIG_CROS_EC_PROTO=y
 CONFIG_TEGRA_IOMMU_GART=y
 CONFIG_TEGRA_IOMMU_SMMU=y
 CONFIG_MEMORY=y
-- 
2.4.3



From javier at osg.samsung.com  Tue Aug 18 00:10:27 2015
From: javier at osg.samsung.com (Javier Martinez Canillas)
Date: Tue, 18 Aug 2015 09:10:27 +0200
Subject: [PATCH] ARM: multi_v7_defconfig: Enable CROS_EC_PROTO for ChromeOS EC
 mfd driver
Message-ID: <1439881827-22613-1-git-send-email-javier@osg.samsung.com>

The ChromeOS mfd driver (MFD_CROS_EC) select the CROS_EC_PROTO config
symbol because the driver uses some communication helper functions in
drivers/platform/chrome/cros_ec_proto.c but other drivers depends on
CROS_EC_PROTO instead. Mixing select and depends can lead to circular
Kconfig dependencies so the MFD_CROS_EC select should be changed to a
depends on CROS_EC_PROTO instead.

But doing so will break git bisect-ability since MFD_CROS_EC will not
be enabled anymore unless the default configs first explicitly enable
the CROS_EC_PROTO dependency.

Signed-off-by: Javier Martinez Canillas <javier at osg.samsung.com>
---
 arch/arm/configs/multi_v7_defconfig | 1 +
 1 file changed, 1 insertion(+)

diff --git a/arch/arm/configs/multi_v7_defconfig b/arch/arm/configs/multi_v7_defconfig
index b2facab87399..bd406f660ffe 100644
--- a/arch/arm/configs/multi_v7_defconfig
+++ b/arch/arm/configs/multi_v7_defconfig
@@ -619,6 +619,7 @@ CONFIG_QCOM_PM=y
 CONFIG_COMMON_CLK_QCOM=y
 CONFIG_CHROME_PLATFORMS=y
 CONFIG_CROS_EC_CHARDEV=m
+CONFIG_CROS_EC_PROTO=y
 CONFIG_COMMON_CLK_MAX77686=y
 CONFIG_COMMON_CLK_MAX77802=m
 CONFIG_COMMON_CLK_S2MPS11=m
-- 
2.4.3



From yh.huang at mediatek.com  Tue Aug 18 00:27:52 2015
From: yh.huang at mediatek.com (YH Huang)
Date: Tue, 18 Aug 2015 15:27:52 +0800
Subject: [PATCH v7 0/3] Add MediaTek display PWM driver
Message-ID: <1439882875-19596-1-git-send-email-yh.huang@mediatek.com>

This patch series add the use of display PWM driver, documentation 
and device tree for Mediatek SoCs. The driver is used to support 
the backlight of the panel. This is based on v4.2-rc1.

The clock definitions (CLK_MM_DISP_PWM*) are added by James Liao's patch: 
clk: mediatek: Add subsystem clocks of MT8173

Change in v7:
1. Add the dependency HAS_IOMEM in Kconfig.
2. Revise misprints and coding style for readability.

Change in v6:
1. Enable clocks in the pwm_enable function.
2. Remove suspend/resume code since pwm-backlight driver has done the
same things.
3. Revise some code to make it easier to read.

Change in v5:
1. Configure PWM output via pinctrl.
2. Fix the parameter name in dtsi.

Change in v4:
1. Codebase is on v4.2-rc1.
2. Add the PWM node in dtsi.
3. Change the dependency in Kconfig.
4. Rewrite some code for readability.

Change in v3:
1. Add suspend/resume function.
2. Fix the formula for high_width calculation.
3. Rewrite some code to make it easier to read.
4. Add more information in the commit message.

Change in v2:
1. Rewrite descriptions for driver in kconfig to make it much clear.
2. Rename the driver from "pwm-mediatek-disp" to "pwm-mtk-disp".
3. Disable clocks in the error path.
4. Change the shift values in decimal instead of hex.
5. Rename and add some variables or function name for consistency and
readability.
6. Drop unnecessary parentheses, spaces, variables and add newlines to
make the code easiler to read.

YH Huang (3):
  dt-bindings: pwm: add MediaTek display PWM bindings
  pwm: add MediaTek display PWM driver support
  arm64: dts: mt8173: add MT8173 display PWM driver support node

 .../devicetree/bindings/pwm/pwm-mtk-disp.txt       |   42 ++++
 arch/arm64/boot/dts/mediatek/mt8173-evb.dts        |   13 ++
 arch/arm64/boot/dts/mediatek/mt8173.dtsi           |   22 ++
 drivers/pwm/Kconfig                                |   11 +
 drivers/pwm/Makefile                               |    1 +
 drivers/pwm/pwm-mtk-disp.c                         |  232 ++++++++++++++++++++
 6 files changed, 321 insertions(+)
 create mode 100644 Documentation/devicetree/bindings/pwm/pwm-mtk-disp.txt
 create mode 100644 drivers/pwm/pwm-mtk-disp.c

--
1.7.9.5



From yh.huang at mediatek.com  Tue Aug 18 00:27:53 2015
From: yh.huang at mediatek.com (YH Huang)
Date: Tue, 18 Aug 2015 15:27:53 +0800
Subject: [PATCH v7 1/3] dt-bindings: pwm: add MediaTek display PWM bindings
In-Reply-To: <1439882875-19596-1-git-send-email-yh.huang@mediatek.com>
References: <1439882875-19596-1-git-send-email-yh.huang@mediatek.com>
Message-ID: <1439882875-19596-2-git-send-email-yh.huang@mediatek.com>

Document the device-tree binding of MediaTek display PWM.
The PWM has one channel to control the backlight brightness for display.
It supports MT8173 and MT6595.

Signed-off-by: YH Huang <yh.huang at mediatek.com>
---
 .../devicetree/bindings/pwm/pwm-mtk-disp.txt       |   42 ++++++++++++++++++++
 1 file changed, 42 insertions(+)
 create mode 100644 Documentation/devicetree/bindings/pwm/pwm-mtk-disp.txt

diff --git a/Documentation/devicetree/bindings/pwm/pwm-mtk-disp.txt b/Documentation/devicetree/bindings/pwm/pwm-mtk-disp.txt
new file mode 100644
index 0000000..f8f59ba
--- /dev/null
+++ b/Documentation/devicetree/bindings/pwm/pwm-mtk-disp.txt
@@ -0,0 +1,42 @@
+MediaTek display PWM controller
+
+Required properties:
+ - compatible: should be "mediatek,<name>-disp-pwm":
+   - "mediatek,mt8173-disp-pwm": found on mt8173 SoC.
+   - "mediatek,mt6595-disp-pwm": found on mt6595 SoC.
+ - reg: physical base address and length of the controller's registers.
+ - #pwm-cells: must be 2. See pwm.txt in this directory for a description of
+   the cell format.
+ - clocks: phandle and clock specifier of the PWM reference clock.
+ - clock-names: must contain the following:
+   - "main": clock used to generate PWM signals.
+   - "mm": sync signals from the modules of mmsys.
+ - pinctrl-names: Must contain a "default" entry.
+ - pinctrl-0: One property must exist for each entry in pinctrl-names.
+   See pinctrl/pinctrl-bindings.txt for details of the property values.
+
+Example:
+	pwm0: pwm at 1401e000 {
+		compatible = "mediatek,mt8173-disp-pwm",
+			     "mediatek,mt6595-disp-pwm";
+		reg = <0 0x1401e000 0 0x1000>;
+		#pwm-cells = <2>;
+		clocks = <&mmsys CLK_MM_DISP_PWM026M>,
+			 <&mmsys CLK_MM_DISP_PWM0MM>;
+		clock-names = "main", "mm";
+		pinctrl-names = "default";
+		pinctrl-0 = <&disp_pwm0_pins>;
+	};
+
+	backlight_lcd: backlight_lcd {
+		compatible = "pwm-backlight";
+		pwms = <&pwm0 0 1000000>;
+		brightness-levels = <
+			  0  16  32  48  64  80  96 112
+			128 144 160 176 192 208 224 240
+			255
+		>;
+		default-brightness-level = <9>;
+		power-supply = <&mt6397_vio18_reg>;
+		enable-gpios = <&pio 95 GPIO_ACTIVE_HIGH>;
+	};
-- 
1.7.9.5



From yh.huang at mediatek.com  Tue Aug 18 00:27:54 2015
From: yh.huang at mediatek.com (YH Huang)
Date: Tue, 18 Aug 2015 15:27:54 +0800
Subject: [PATCH v7 2/3] pwm: add MediaTek display PWM driver support
In-Reply-To: <1439882875-19596-1-git-send-email-yh.huang@mediatek.com>
References: <1439882875-19596-1-git-send-email-yh.huang@mediatek.com>
Message-ID: <1439882875-19596-3-git-send-email-yh.huang@mediatek.com>

Add display PWM driver support to modify backlight for MT8173 and MT6595.
The PWM has one channel to control the brightness of the display.
When the (high_width / period) is closer to 1, the screen is brighter;
otherwise, it is darker.

Signed-off-by: YH Huang <yh.huang at mediatek.com>
---
 drivers/pwm/Kconfig        |   11 +++
 drivers/pwm/Makefile       |    1 +
 drivers/pwm/pwm-mtk-disp.c |  232 ++++++++++++++++++++++++++++++++++++++++++++
 3 files changed, 244 insertions(+)
 create mode 100644 drivers/pwm/pwm-mtk-disp.c

diff --git a/drivers/pwm/Kconfig b/drivers/pwm/Kconfig
index b1541f4..24acd8f 100644
--- a/drivers/pwm/Kconfig
+++ b/drivers/pwm/Kconfig
@@ -211,6 +211,17 @@ config PWM_LPSS_PLATFORM
 	  To compile this driver as a module, choose M here: the module
 	  will be called pwm-lpss-platform.
 
+config PWM_MTK_DISP
+	tristate "MediaTek display PWM driver"
+	depends on ARCH_MEDIATEK || COMPILE_TEST
+	depends on HAS_IOMEM
+	help
+	  Generic PWM framework driver for MediaTek disp-pwm device.
+	  The PWM is used to control the backlight brightness for display.
+
+	  To compile this driver as a module, choose M here: the module
+	  will be called pwm-mtk-disp.
+
 config PWM_MXS
 	tristate "Freescale MXS PWM support"
 	depends on ARCH_MXS && OF
diff --git a/drivers/pwm/Makefile b/drivers/pwm/Makefile
index ec50eb5..99c9e75 100644
--- a/drivers/pwm/Makefile
+++ b/drivers/pwm/Makefile
@@ -18,6 +18,7 @@ obj-$(CONFIG_PWM_LPC32XX)	+= pwm-lpc32xx.o
 obj-$(CONFIG_PWM_LPSS)		+= pwm-lpss.o
 obj-$(CONFIG_PWM_LPSS_PCI)	+= pwm-lpss-pci.o
 obj-$(CONFIG_PWM_LPSS_PLATFORM)	+= pwm-lpss-platform.o
+obj-$(CONFIG_PWM_MTK_DISP)	+= pwm-mtk-disp.o
 obj-$(CONFIG_PWM_MXS)		+= pwm-mxs.o
 obj-$(CONFIG_PWM_PCA9685)	+= pwm-pca9685.o
 obj-$(CONFIG_PWM_PUV3)		+= pwm-puv3.o
diff --git a/drivers/pwm/pwm-mtk-disp.c b/drivers/pwm/pwm-mtk-disp.c
new file mode 100644
index 0000000..90aea6f
--- /dev/null
+++ b/drivers/pwm/pwm-mtk-disp.c
@@ -0,0 +1,232 @@
+/*
+ * MediaTek display pulse-width-modulation controller driver.
+ * Copyright (c) 2015 MediaTek Inc.
+ * Author: YH Huang <yh.huang at 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/clk.h>
+#include <linux/err.h>
+#include <linux/io.h>
+#include <linux/module.h>
+#include <linux/of.h>
+#include <linux/platform_device.h>
+#include <linux/pwm.h>
+#include <linux/slab.h>
+
+#define DISP_PWM_EN		0x00
+#define PWM_ENABLE_MASK		BIT(0)
+
+#define DISP_PWM_COMMIT		0x08
+#define PWM_COMMIT_MASK		BIT(0)
+
+#define DISP_PWM_CON_0		0x10
+#define PWM_CLKDIV_SHIFT	16
+#define PWM_CLKDIV_MAX		0x3ff
+#define PWM_CLKDIV_MASK		(PWM_CLKDIV_MAX << PWM_CLKDIV_SHIFT)
+
+#define DISP_PWM_CON_1		0x14
+#define PWM_PERIOD_BIT_WIDTH	12
+#define PWM_PERIOD_MASK		((1 << PWM_PERIOD_BIT_WIDTH) - 1)
+
+#define PWM_HIGH_WIDTH_SHIFT	16
+#define PWM_HIGH_WIDTH_MASK	(0x1fff << PWM_HIGH_WIDTH_SHIFT)
+
+struct mtk_disp_pwm {
+	struct pwm_chip chip;
+	struct clk *clk_main;
+	struct clk *clk_mm;
+	void __iomem *base;
+};
+
+static inline struct mtk_disp_pwm *to_mtk_disp_pwm(struct pwm_chip *chip)
+{
+	return container_of(chip, struct mtk_disp_pwm, chip);
+}
+
+static void mtk_disp_pwm_update_bits(struct mtk_disp_pwm *mdp, u32 offset,
+				     u32 mask, u32 value)
+{
+	void __iomem *address;
+	u32 val;
+
+	address = mdp->base + offset;
+	val = readl(address);
+	val &= ~mask;
+	val |= value;
+	writel(val, address);
+}
+
+static int mtk_disp_pwm_config(struct pwm_chip *chip, struct pwm_device *pwm,
+			       int duty_ns, int period_ns)
+{
+	struct mtk_disp_pwm *mdp = to_mtk_disp_pwm(chip);
+	u64 div, rate;
+	u32 clk_div, period, high_width, value;
+
+	/*
+	 * Find period, high_width and clk_div to suit duty_ns and period_ns.
+	 * Calculate proper div value to keep period value in the bound.
+	 *
+	 * period_ns = 10^9 * (clk_div + 1) * (period + 1) / PWM_CLK_RATE
+	 * duty_ns = 10^9 * (clk_div + 1) * high_width / PWM_CLK_RATE
+	 *
+	 * period = (PWM_CLK_RATE * period_ns) / (10^9 * (clk_div + 1)) - 1
+	 * high_width = (PWM_CLK_RATE * duty_ns) / (10^9 * (clk_div + 1))
+	 */
+	rate = clk_get_rate(mdp->clk_main);
+	clk_div = div_u64(rate * period_ns, NSEC_PER_SEC) >>
+			  PWM_PERIOD_BIT_WIDTH;
+	if (clk_div > PWM_CLKDIV_MAX)
+		return -EINVAL;
+
+	div = NSEC_PER_SEC * (clk_div + 1);
+	period = div64_u64(rate * period_ns, div);
+	if (period > 0)
+		period--;
+
+	high_width = div64_u64(rate * duty_ns, div);
+	value = period | (high_width << PWM_HIGH_WIDTH_SHIFT);
+
+	clk_enable(mdp->clk_main);
+	clk_enable(mdp->clk_mm);
+
+	mtk_disp_pwm_update_bits(mdp, DISP_PWM_CON_0,
+				 PWM_CLKDIV_MASK, clk_div << PWM_CLKDIV_SHIFT);
+	mtk_disp_pwm_update_bits(mdp, DISP_PWM_CON_1,
+				 PWM_PERIOD_MASK | PWM_HIGH_WIDTH_MASK, value);
+	mtk_disp_pwm_update_bits(mdp, DISP_PWM_COMMIT,
+				 PWM_COMMIT_MASK, 1);
+	mtk_disp_pwm_update_bits(mdp, DISP_PWM_COMMIT,
+				 PWM_COMMIT_MASK, 0);
+
+	clk_disable(mdp->clk_mm);
+	clk_disable(mdp->clk_main);
+
+	return 0;
+}
+
+static int mtk_disp_pwm_enable(struct pwm_chip *chip, struct pwm_device *pwm)
+{
+	struct mtk_disp_pwm *mdp = to_mtk_disp_pwm(chip);
+
+	clk_enable(mdp->clk_main);
+	clk_enable(mdp->clk_mm);
+
+	mtk_disp_pwm_update_bits(mdp, DISP_PWM_EN,
+				 PWM_ENABLE_MASK, 1);
+
+	return 0;
+}
+
+static void mtk_disp_pwm_disable(struct pwm_chip *chip, struct pwm_device *pwm)
+{
+	struct mtk_disp_pwm *mdp = to_mtk_disp_pwm(chip);
+
+	mtk_disp_pwm_update_bits(mdp, DISP_PWM_EN,
+				 PWM_ENABLE_MASK, 0);
+
+	clk_disable(mdp->clk_mm);
+	clk_disable(mdp->clk_main);
+}
+
+static const struct pwm_ops mtk_disp_pwm_ops = {
+	.config = mtk_disp_pwm_config,
+	.enable = mtk_disp_pwm_enable,
+	.disable = mtk_disp_pwm_disable,
+	.owner = THIS_MODULE,
+};
+
+static int mtk_disp_pwm_probe(struct platform_device *pdev)
+{
+	struct mtk_disp_pwm *mdp;
+	struct resource *r;
+	int ret;
+
+	mdp = devm_kzalloc(&pdev->dev, sizeof(*mdp), GFP_KERNEL);
+	if (!mdp)
+		return -ENOMEM;
+
+	r = platform_get_resource(pdev, IORESOURCE_MEM, 0);
+	mdp->base = devm_ioremap_resource(&pdev->dev, r);
+	if (IS_ERR(mdp->base))
+		return PTR_ERR(mdp->base);
+
+	mdp->clk_main = devm_clk_get(&pdev->dev, "main");
+	if (IS_ERR(mdp->clk_main))
+		return PTR_ERR(mdp->clk_main);
+
+	mdp->clk_mm = devm_clk_get(&pdev->dev, "mm");
+	if (IS_ERR(mdp->clk_mm))
+		return PTR_ERR(mdp->clk_mm);
+
+	ret = clk_prepare(mdp->clk_main);
+	if (ret < 0)
+		return ret;
+
+	ret = clk_prepare(mdp->clk_mm);
+	if (ret < 0)
+		goto disable_clk_main;
+
+	mdp->chip.dev = &pdev->dev;
+	mdp->chip.ops = &mtk_disp_pwm_ops;
+	mdp->chip.base = -1;
+	mdp->chip.npwm = 1;
+
+	ret = pwmchip_add(&mdp->chip);
+	if (ret < 0) {
+		dev_err(&pdev->dev, "pwmchip_add() failed: %d\n", ret);
+		goto disable_clk_mm;
+	}
+
+	platform_set_drvdata(pdev, mdp);
+
+	return 0;
+
+disable_clk_mm:
+	clk_unprepare(mdp->clk_mm);
+disable_clk_main:
+	clk_unprepare(mdp->clk_main);
+	return ret;
+}
+
+static int mtk_disp_pwm_remove(struct platform_device *pdev)
+{
+	struct mtk_disp_pwm *mdp = platform_get_drvdata(pdev);
+	int ret;
+
+	ret = pwmchip_remove(&mdp->chip);
+	clk_unprepare(mdp->clk_mm);
+	clk_unprepare(mdp->clk_main);
+
+	return ret;
+}
+
+static const struct of_device_id mtk_disp_pwm_of_match[] = {
+	{ .compatible = "mediatek,mt8173-disp-pwm" },
+	{ .compatible = "mediatek,mt6595-disp-pwm" },
+	{ }
+};
+MODULE_DEVICE_TABLE(of, mtk_disp_pwm_of_match);
+
+static struct platform_driver mtk_disp_pwm_driver = {
+	.driver = {
+		.name = "mediatek-disp-pwm",
+		.of_match_table = mtk_disp_pwm_of_match,
+	},
+	.probe = mtk_disp_pwm_probe,
+	.remove = mtk_disp_pwm_remove,
+};
+module_platform_driver(mtk_disp_pwm_driver);
+
+MODULE_AUTHOR("YH Huang <yh.huang at mediatek.com>");
+MODULE_DESCRIPTION("MediaTek SoC display PWM driver");
+MODULE_LICENSE("GPL v2");
-- 
1.7.9.5



From yh.huang at mediatek.com  Tue Aug 18 00:27:55 2015
From: yh.huang at mediatek.com (YH Huang)
Date: Tue, 18 Aug 2015 15:27:55 +0800
Subject: [PATCH v7 3/3] arm64: dts: mt8173: add MT8173 display PWM driver
 support node
In-Reply-To: <1439882875-19596-1-git-send-email-yh.huang@mediatek.com>
References: <1439882875-19596-1-git-send-email-yh.huang@mediatek.com>
Message-ID: <1439882875-19596-4-git-send-email-yh.huang@mediatek.com>

Add display PWM node in mt8173-evb.dts and mt8173.dtsi.

Signed-off-by: YH Huang <yh.huang at mediatek.com>
---
 arch/arm64/boot/dts/mediatek/mt8173-evb.dts |   13 +++++++++++++
 arch/arm64/boot/dts/mediatek/mt8173.dtsi    |   22 ++++++++++++++++++++++
 2 files changed, 35 insertions(+)

diff --git a/arch/arm64/boot/dts/mediatek/mt8173-evb.dts b/arch/arm64/boot/dts/mediatek/mt8173-evb.dts
index 4be66ca..de95cf3 100644
--- a/arch/arm64/boot/dts/mediatek/mt8173-evb.dts
+++ b/arch/arm64/boot/dts/mediatek/mt8173-evb.dts
@@ -92,6 +92,13 @@
 };
 
 &pio {
+	disp_pwm0_pins: disp_pwm0_pins {
+		pins1 {
+			pinmux = <MT8173_PIN_87_DISP_PWM0__FUNC_DISP_PWM0>;
+			output-low;
+		};
+	};
+
 	mmc0_pins_default: mmc0default {
 		pins_cmd_dat {
 			pinmux = <MT8173_PIN_57_MSDC0_DAT0__FUNC_MSDC0_DAT0>,
@@ -190,6 +197,12 @@
 	};
 };
 
+&pwm0 {
+	pinctrl-names = "default";
+	pinctrl-0 = <&disp_pwm0_pins>;
+	status = "okay";
+};
+
 &pwrap {
 	pmic: mt6397 {
 		compatible = "mediatek,mt6397";
diff --git a/arch/arm64/boot/dts/mediatek/mt8173.dtsi b/arch/arm64/boot/dts/mediatek/mt8173.dtsi
index 6c3f047..68b1ef0 100644
--- a/arch/arm64/boot/dts/mediatek/mt8173.dtsi
+++ b/arch/arm64/boot/dts/mediatek/mt8173.dtsi
@@ -501,6 +501,28 @@
 			#clock-cells = <1>;
 		};
 
+		pwm0: pwm at 1401e000 {
+			compatible = "mediatek,mt8173-disp-pwm",
+				     "mediatek,mt6595-disp-pwm";
+			reg = <0 0x1401e000 0 0x1000>;
+			#pwm-cells = <2>;
+			clocks = <&mmsys CLK_MM_DISP_PWM026M>,
+				 <&mmsys CLK_MM_DISP_PWM0MM>;
+			clock-names = "main", "mm";
+			status = "disabled";
+		};
+
+		pwm1: pwm at 1401f000 {
+			compatible = "mediatek,mt8173-disp-pwm",
+				     "mediatek,mt6595-disp-pwm";
+			reg = <0 0x1401f000 0 0x1000>;
+			#pwm-cells = <2>;
+			clocks = <&mmsys CLK_MM_DISP_PWM126M>,
+				 <&mmsys CLK_MM_DISP_PWM1MM>;
+			clock-names = "main", "mm";
+			status = "disabled";
+		};
+
 		imgsys: clock-controller at 15000000 {
 			compatible = "mediatek,mt8173-imgsys", "syscon";
 			reg = <0 0x15000000 0 0x1000>;
-- 
1.7.9.5



From k.kozlowski at samsung.com  Tue Aug 18 00:57:29 2015
From: k.kozlowski at samsung.com (Krzysztof Kozlowski)
Date: Tue, 18 Aug 2015 16:57:29 +0900
Subject: [PATCH] ARM: exynos_defconfig: Enable CROS_EC_PROTO for ChromeOS
 EC mfd driver
In-Reply-To: <1439881281-22054-1-git-send-email-javier@osg.samsung.com>
References: <1439881281-22054-1-git-send-email-javier@osg.samsung.com>
Message-ID: <55D2E569.3000800@samsung.com>

On 18.08.2015 16:01, Javier Martinez Canillas wrote:
> The ChromeOS mfd driver (MFD_CROS_EC) select the CROS_EC_PROTO config
> symbol because the driver uses some communication helper functions in
> drivers/platform/chrome/cros_ec_proto.c but other drivers depends on
> CROS_EC_PROTO instead. Mixing select and depends can lead to circular
> Kconfig dependencies so the MFD_CROS_EC select should be changed to a
> depends on CROS_EC_PROTO instead.
> 
> But doing so will break git bisect-ability since MFD_CROS_EC will not
> be enabled anymore unless the default configs first explicitly enable
> the CROS_EC_PROTO dependency.
> 
> Signed-off-by: Javier Martinez Canillas <javier at osg.samsung.com>
> ---
>  arch/arm/configs/exynos_defconfig | 1 +
>  1 file changed, 1 insertion(+)

I saw the discussion about circular dependency but I wasn't following
it. Currently the CROS_EC_PROTO is not user-selectable. How can you
depend on it? How can be enabled on different configs (customized by user)?

Maybe the questions are answered by code in different patches?

Best regards,
Krzysztof


> 
> diff --git a/arch/arm/configs/exynos_defconfig b/arch/arm/configs/exynos_defconfig
> index 1ff2bfa2e183..537391ea37ac 100644
> --- a/arch/arm/configs/exynos_defconfig
> +++ b/arch/arm/configs/exynos_defconfig
> @@ -177,6 +177,7 @@ CONFIG_DMADEVICES=y
>  CONFIG_PL330_DMA=y
>  CONFIG_CHROME_PLATFORMS=y
>  CONFIG_CROS_EC_CHARDEV=y
> +CONFIG_CROS_EC_PROTO=y
>  CONFIG_COMMON_CLK_MAX77686=y
>  CONFIG_COMMON_CLK_MAX77802=y
>  CONFIG_COMMON_CLK_S2MPS11=y
> 



From javier at osg.samsung.com  Tue Aug 18 01:05:59 2015
From: javier at osg.samsung.com (Javier Martinez Canillas)
Date: Tue, 18 Aug 2015 10:05:59 +0200
Subject: [PATCH] ARM: exynos_defconfig: Enable CROS_EC_PROTO for ChromeOS
 EC mfd driver
In-Reply-To: <55D2E569.3000800@samsung.com>
References: <1439881281-22054-1-git-send-email-javier@osg.samsung.com>
 <55D2E569.3000800@samsung.com>
Message-ID: <55D2E767.50807@osg.samsung.com>

Hello Krzysztof,

On 08/18/2015 09:57 AM, Krzysztof Kozlowski wrote:
> On 18.08.2015 16:01, Javier Martinez Canillas wrote:
>> The ChromeOS mfd driver (MFD_CROS_EC) select the CROS_EC_PROTO config
>> symbol because the driver uses some communication helper functions in
>> drivers/platform/chrome/cros_ec_proto.c but other drivers depends on
>> CROS_EC_PROTO instead. Mixing select and depends can lead to circular
>> Kconfig dependencies so the MFD_CROS_EC select should be changed to a
>> depends on CROS_EC_PROTO instead.
>>
>> But doing so will break git bisect-ability since MFD_CROS_EC will not
>> be enabled anymore unless the default configs first explicitly enable
>> the CROS_EC_PROTO dependency.
>>
>> Signed-off-by: Javier Martinez Canillas <javier at osg.samsung.com>
>> ---
>>  arch/arm/configs/exynos_defconfig | 1 +
>>  1 file changed, 1 insertion(+)
> 
> I saw the discussion about circular dependency but I wasn't following
> it. Currently the CROS_EC_PROTO is not user-selectable. How can you
> depend on it? How can be enabled on different configs (customized by user)?
> 
> Maybe the questions are answered by code in different patches?

Yes, that's why I posted "[PATCH] platform/chrome: Make CROS_EC_PROTO
a user selectable option" [0].

I posted as separate patches because there isn't a dependency between
them and once all the defconfig patches and the patch to make the
CROS_EC_PROTO symbol user selectable lands, I'll post the patch to
change select for depends on to avoid a regression.

Maybe I should had posted as a series (or at least cc all the people
in all the patches) to not left these questions unanswered...

> 
> Best regards,
> Krzysztof
> 
> 

[0]: https://lkml.org/lkml/2015/8/18/61

Best regards,
-- 
Javier Martinez Canillas
Open Source Group
Samsung Research America


From boris.brezillon at free-electrons.com  Tue Aug 18 01:08:52 2015
From: boris.brezillon at free-electrons.com (Boris Brezillon)
Date: Tue, 18 Aug 2015 10:08:52 +0200
Subject: [PATCH 01/10] ARM: marvell/dt: add crypto related nodes to
 armada-xp.dtsi
In-Reply-To: <1439885341-14644-1-git-send-email-boris.brezillon@free-electrons.com>
References: <1439885341-14644-1-git-send-email-boris.brezillon@free-electrons.com>
Message-ID: <1439885341-14644-2-git-send-email-boris.brezillon@free-electrons.com>

Add crypto related nodes to armada-xp.dtsi.

Signed-off-by: Boris Brezillon <boris.brezillon at free-electrons.com>
---
 arch/arm/boot/dts/armada-xp.dtsi | 30 ++++++++++++++++++++++++++++++
 1 file changed, 30 insertions(+)

diff --git a/arch/arm/boot/dts/armada-xp.dtsi b/arch/arm/boot/dts/armada-xp.dtsi
index 3de9b76..4e65196 100644
--- a/arch/arm/boot/dts/armada-xp.dtsi
+++ b/arch/arm/boot/dts/armada-xp.dtsi
@@ -236,6 +236,18 @@
 				compatible = "marvell,armada-xp-neta";
 			};
 
+			crypto at 90000 {
+				compatible = "marvell,armada-xp-crypto";
+				reg = <0x90000 0x10000>;
+				reg-names = "regs";
+				interrupts = <48>, <49>;
+				clocks = <&gateclk 23>, <&gateclk 23>;
+				clock-names = "cesa0", "cesa1";
+				marvell,crypto-srams = <&crypto_sram0>,
+						       <&crypto_sram1>;
+				marvell,crypto-sram-size = <0x800>;
+			};
+
 			xor at f0900 {
 				compatible = "marvell,orion-xor";
 				reg = <0xF0900 0x100
@@ -256,6 +268,24 @@
 				};
 			};
 		};
+
+		crypto_sram0: sa-sram0 {
+			compatible = "mmio-sram";
+			reg = <MBUS_ID(0x09, 0x09) 0 0x800>;
+			clocks = <&gateclk 23>;
+			#address-cells = <1>;
+			#size-cells = <1>;
+			ranges = <0 MBUS_ID(0x09, 0x09) 0 0x800>;
+		};
+
+		crypto_sram1: sa-sram1 {
+			compatible = "mmio-sram";
+			reg = <MBUS_ID(0x09, 0x05) 0 0x800>;
+			clocks = <&gateclk 23>;
+			#address-cells = <1>;
+			#size-cells = <1>;
+			ranges = <0 MBUS_ID(0x09, 0x05) 0 0x800>;
+		};
 	};
 
 	clocks {
-- 
1.9.1



From boris.brezillon at free-electrons.com  Tue Aug 18 01:08:54 2015
From: boris.brezillon at free-electrons.com (Boris Brezillon)
Date: Tue, 18 Aug 2015 10:08:54 +0200
Subject: [PATCH 03/10] ARM: marvell/dt: add crypto related nodes to armada 370
 dtsi
In-Reply-To: <1439885341-14644-1-git-send-email-boris.brezillon@free-electrons.com>
References: <1439885341-14644-1-git-send-email-boris.brezillon@free-electrons.com>
Message-ID: <1439885341-14644-4-git-send-email-boris.brezillon@free-electrons.com>

From: Arnaud Ebalard <arno at natisbad.org>

Add crypto related nodes in armada-370.dtsi.

Signed-off-by: Arnaud Ebalard <arno at natisbad.org>
Signed-off-by: Boris Brezillon <boris.brezillon at free-electrons.com>
---
 arch/arm/boot/dts/armada-370.dtsi | 25 +++++++++++++++++++++++++
 1 file changed, 25 insertions(+)

diff --git a/arch/arm/boot/dts/armada-370.dtsi b/arch/arm/boot/dts/armada-370.dtsi
index 53a1a5a..e42230d 100644
--- a/arch/arm/boot/dts/armada-370.dtsi
+++ b/arch/arm/boot/dts/armada-370.dtsi
@@ -319,6 +319,31 @@
 			ethernet at 74000 {
 				compatible = "marvell,armada-370-neta";
 			};
+
+			crypto at 90000 {
+				compatible = "marvell,armada-370-crypto";
+				reg = <0x90000 0x10000>;
+				reg-names = "regs";
+				interrupts = <48>;
+				clocks = <&gateclk 23>;
+				clock-names = "cesa0";
+				marvell,crypto-srams = <&crypto_sram>;
+				marvell,crypto-sram-size = <0x7e0>;
+			};
+		};
+
+		crypto_sram: sa-sram {
+			compatible = "mmio-sram";
+			reg = <MBUS_ID(0x09, 0x01) 0 0x800>;
+			reg-names = "sram";
+			clocks = <&gateclk 23>;
+			#address-cells = <1>;
+			#size-cells = <1>;
+			ranges = <0 MBUS_ID(0x09, 0x01) 0 0x800>;
+
+			idle-sram at 0 {
+				reg = <0x0 0x20>;
+			};
 		};
 	};
 };
-- 
1.9.1



From boris.brezillon at free-electrons.com  Tue Aug 18 01:08:55 2015
From: boris.brezillon at free-electrons.com (Boris Brezillon)
Date: Tue, 18 Aug 2015 10:08:55 +0200
Subject: [PATCH 04/10] ARM: marvell/dt: define crypto SRAM ranges for all
 armada-370 boards
In-Reply-To: <1439885341-14644-1-git-send-email-boris.brezillon@free-electrons.com>
References: <1439885341-14644-1-git-send-email-boris.brezillon@free-electrons.com>
Message-ID: <1439885341-14644-5-git-send-email-boris.brezillon@free-electrons.com>

Define the crypto SRAM ranges so that the resources referenced by the
sa-sram node can be properly extracted from the DT.

Signed-off-by: Boris Brezillon <boris.brezillon at free-electrons.com>
---
 arch/arm/boot/dts/armada-370-db.dts              | 3 ++-
 arch/arm/boot/dts/armada-370-dlink-dns327l.dts   | 3 ++-
 arch/arm/boot/dts/armada-370-mirabox.dts         | 7 ++++++-
 arch/arm/boot/dts/armada-370-netgear-rn102.dts   | 3 ++-
 arch/arm/boot/dts/armada-370-netgear-rn104.dts   | 3 ++-
 arch/arm/boot/dts/armada-370-rd.dts              | 3 ++-
 arch/arm/boot/dts/armada-370-synology-ds213j.dts | 3 ++-
 7 files changed, 18 insertions(+), 7 deletions(-)

diff --git a/arch/arm/boot/dts/armada-370-db.dts b/arch/arm/boot/dts/armada-370-db.dts
index 03542f7..bb280de 100644
--- a/arch/arm/boot/dts/armada-370-db.dts
+++ b/arch/arm/boot/dts/armada-370-db.dts
@@ -74,7 +74,8 @@
 
 	soc {
 		ranges = <MBUS_ID(0xf0, 0x01) 0 0xf1000000 0x100000
-			  MBUS_ID(0x01, 0xe0) 0 0xfff00000 0x100000>;
+			  MBUS_ID(0x01, 0xe0) 0 0xfff00000 0x100000
+			  MBUS_ID(0x09, 0x01) 0 0xf1100000 0x10000>;
 
 		internal-regs {
 			serial at 12000 {
diff --git a/arch/arm/boot/dts/armada-370-dlink-dns327l.dts b/arch/arm/boot/dts/armada-370-dlink-dns327l.dts
index af4dc54..e2a363b 100644
--- a/arch/arm/boot/dts/armada-370-dlink-dns327l.dts
+++ b/arch/arm/boot/dts/armada-370-dlink-dns327l.dts
@@ -69,7 +69,8 @@
 
 	soc {
 		ranges = <MBUS_ID(0xf0, 0x01) 0 0xd0000000 0x100000
-			MBUS_ID(0x01, 0xe0) 0 0xfff00000 0x100000>;
+			MBUS_ID(0x01, 0xe0) 0 0xfff00000 0x100000
+			MBUS_ID(0x09, 0x01) 0 0xf1100000 0x10000>;
 
 		pcie-controller {
 			status = "okay";
diff --git a/arch/arm/boot/dts/armada-370-mirabox.dts b/arch/arm/boot/dts/armada-370-mirabox.dts
index 0f40d5d..3aa980a 100644
--- a/arch/arm/boot/dts/armada-370-mirabox.dts
+++ b/arch/arm/boot/dts/armada-370-mirabox.dts
@@ -61,7 +61,8 @@
 
 	soc {
 		ranges = <MBUS_ID(0xf0, 0x01) 0 0xd0000000 0x100000
-			  MBUS_ID(0x01, 0xe0) 0 0xfff00000 0x100000>;
+			  MBUS_ID(0x01, 0xe0) 0 0xfff00000 0x100000
+			  MBUS_ID(0x09, 0x01) 0 0xf1100000 0x10000>;
 
 		pcie-controller {
 			status = "okay";
@@ -138,6 +139,10 @@
 				phy-mode = "rgmii-id";
 			};
 
+			crypto at 90000 {
+				status = "okay";
+			};
+
 			mvsdio at d4000 {
 				pinctrl-0 = <&sdio_pins3>;
 				pinctrl-names = "default";
diff --git a/arch/arm/boot/dts/armada-370-netgear-rn102.dts b/arch/arm/boot/dts/armada-370-netgear-rn102.dts
index a312078..f43ee4a 100644
--- a/arch/arm/boot/dts/armada-370-netgear-rn102.dts
+++ b/arch/arm/boot/dts/armada-370-netgear-rn102.dts
@@ -63,7 +63,8 @@
 
 	soc {
 		ranges = <MBUS_ID(0xf0, 0x01) 0 0xd0000000 0x100000
-			  MBUS_ID(0x01, 0xe0) 0 0xfff00000 0x100000>;
+			  MBUS_ID(0x01, 0xe0) 0 0xfff00000 0x100000
+			  MBUS_ID(0x09, 0x01) 0 0xf1100000 0x10000>;
 
 		pcie-controller {
 			status = "okay";
diff --git a/arch/arm/boot/dts/armada-370-netgear-rn104.dts b/arch/arm/boot/dts/armada-370-netgear-rn104.dts
index 00540f2..4c240de 100644
--- a/arch/arm/boot/dts/armada-370-netgear-rn104.dts
+++ b/arch/arm/boot/dts/armada-370-netgear-rn104.dts
@@ -63,7 +63,8 @@
 
 	soc {
 		ranges = <MBUS_ID(0xf0, 0x01) 0 0xd0000000 0x100000
-			  MBUS_ID(0x01, 0xe0) 0 0xfff00000 0x100000>;
+			  MBUS_ID(0x01, 0xe0) 0 0xfff00000 0x100000
+			  MBUS_ID(0x09, 0x01) 0 0xf1100000 0x10000>;
 
 		pcie-controller {
 			status = "okay";
diff --git a/arch/arm/boot/dts/armada-370-rd.dts b/arch/arm/boot/dts/armada-370-rd.dts
index 19475e6..fbef730 100644
--- a/arch/arm/boot/dts/armada-370-rd.dts
+++ b/arch/arm/boot/dts/armada-370-rd.dts
@@ -74,7 +74,8 @@
 
 	soc {
 		ranges = <MBUS_ID(0xf0, 0x01) 0 0xf1000000 0x100000
-			  MBUS_ID(0x01, 0xe0) 0 0xfff00000 0x100000>;
+			  MBUS_ID(0x01, 0xe0) 0 0xfff00000 0x100000
+			  MBUS_ID(0x09, 0x01) 0 0xf1100000 0x10000>;
 
 		pcie-controller {
 			status = "okay";
diff --git a/arch/arm/boot/dts/armada-370-synology-ds213j.dts b/arch/arm/boot/dts/armada-370-synology-ds213j.dts
index 4f49243..836bcc0 100644
--- a/arch/arm/boot/dts/armada-370-synology-ds213j.dts
+++ b/arch/arm/boot/dts/armada-370-synology-ds213j.dts
@@ -77,7 +77,8 @@
 
 	soc {
 		ranges = <MBUS_ID(0xf0, 0x01) 0 0xf1000000 0x100000
-			  MBUS_ID(0x01, 0xe0) 0 0xfff00000 0x100000>;
+			  MBUS_ID(0x01, 0xe0) 0 0xfff00000 0x100000
+			  MBUS_ID(0x09, 0x01) 0 0xf1100000 0x10000>;
 
 		internal-regs {
 
-- 
1.9.1



From boris.brezillon at free-electrons.com  Tue Aug 18 01:08:51 2015
From: boris.brezillon at free-electrons.com (Boris Brezillon)
Date: Tue, 18 Aug 2015 10:08:51 +0200
Subject: [PATCH 00/10] ARM: marvell/dt: add crypto nodes in existing DTs
Message-ID: <1439885341-14644-1-git-send-email-boris.brezillon@free-electrons.com>

Hello,

This series declares and enables the crypto engine on the armada, orion,
kirkwood and dove SoCs.

Best Regards,

Boris


Arnaud Ebalard (1):
  ARM: marvell/dt: add crypto related nodes to armada 370 dtsi

Boris Brezillon (9):
  ARM: marvell/dt: add crypto related nodes to armada-xp.dtsi
  ARM: marvell/dt: define crypto SRAM ranges for all armada-xp boards
  ARM: marvell/dt: define crypto SRAM ranges for all armada-370 boards
  ARM: marvell/dt: add crypto related nodes to armada 375 dtsi
  ARM: marvell/dt: define crypto SRAM ranges in armada-375-db.dts
  ARM: marvell/dt: add crypto related nodes to armada 38x dtsi
  ARM: marvell/dt: define crypto SRAM ranges for all armada-38x boards
  ARM: marvell: use new bindings for existing crypto devices
  ARM: marvell: modify Orion and Kirkwoord crypto compatible strings

 arch/arm/boot/dts/armada-370-db.dts              |  3 ++-
 arch/arm/boot/dts/armada-370-dlink-dns327l.dts   |  3 ++-
 arch/arm/boot/dts/armada-370-mirabox.dts         |  7 ++++-
 arch/arm/boot/dts/armada-370-netgear-rn102.dts   |  3 ++-
 arch/arm/boot/dts/armada-370-netgear-rn104.dts   |  3 ++-
 arch/arm/boot/dts/armada-370-rd.dts              |  3 ++-
 arch/arm/boot/dts/armada-370-synology-ds213j.dts |  3 ++-
 arch/arm/boot/dts/armada-370.dtsi                | 25 ++++++++++++++++++
 arch/arm/boot/dts/armada-375-db.dts              |  4 ++-
 arch/arm/boot/dts/armada-375.dtsi                | 33 ++++++++++++++++++++++++
 arch/arm/boot/dts/armada-385-db-ap.dts           |  4 ++-
 arch/arm/boot/dts/armada-385-linksys.dtsi        |  4 ++-
 arch/arm/boot/dts/armada-388-db.dts              |  4 ++-
 arch/arm/boot/dts/armada-388-gp.dts              |  4 ++-
 arch/arm/boot/dts/armada-388-rd.dts              |  4 ++-
 arch/arm/boot/dts/armada-38x.dtsi                | 33 ++++++++++++++++++++++++
 arch/arm/boot/dts/armada-xp-axpwifiap.dts        |  4 ++-
 arch/arm/boot/dts/armada-xp-db.dts               |  4 ++-
 arch/arm/boot/dts/armada-xp-gp.dts               |  4 ++-
 arch/arm/boot/dts/armada-xp-lenovo-ix4-300d.dts  |  4 ++-
 arch/arm/boot/dts/armada-xp-linksys-mamba.dts    |  4 ++-
 arch/arm/boot/dts/armada-xp-matrix.dts           |  4 ++-
 arch/arm/boot/dts/armada-xp-netgear-rn2120.dts   |  4 ++-
 arch/arm/boot/dts/armada-xp-openblocks-ax3-4.dts |  4 ++-
 arch/arm/boot/dts/armada-xp-synology-ds414.dts   |  4 ++-
 arch/arm/boot/dts/armada-xp.dtsi                 | 30 +++++++++++++++++++++
 arch/arm/boot/dts/dove.dtsi                      | 17 +++++++++---
 arch/arm/boot/dts/kirkwood.dtsi                  | 29 ++++++++++++++-------
 arch/arm/boot/dts/orion5x.dtsi                   | 22 +++++++++++-----
 29 files changed, 231 insertions(+), 43 deletions(-)

-- 
1.9.1



From boris.brezillon at free-electrons.com  Tue Aug 18 01:08:53 2015
From: boris.brezillon at free-electrons.com (Boris Brezillon)
Date: Tue, 18 Aug 2015 10:08:53 +0200
Subject: [PATCH 02/10] ARM: marvell/dt: define crypto SRAM ranges for all
 armada-xp boards
In-Reply-To: <1439885341-14644-1-git-send-email-boris.brezillon@free-electrons.com>
References: <1439885341-14644-1-git-send-email-boris.brezillon@free-electrons.com>
Message-ID: <1439885341-14644-3-git-send-email-boris.brezillon@free-electrons.com>

Define the crypto SRAM ranges so that the resources referenced by the
sa-sram node can be properly extracted from the DT.

Signed-off-by: Boris Brezillon <boris.brezillon at free-electrons.com>
---
 arch/arm/boot/dts/armada-xp-axpwifiap.dts        | 4 +++-
 arch/arm/boot/dts/armada-xp-db.dts               | 4 +++-
 arch/arm/boot/dts/armada-xp-gp.dts               | 4 +++-
 arch/arm/boot/dts/armada-xp-lenovo-ix4-300d.dts  | 4 +++-
 arch/arm/boot/dts/armada-xp-linksys-mamba.dts    | 4 +++-
 arch/arm/boot/dts/armada-xp-matrix.dts           | 4 +++-
 arch/arm/boot/dts/armada-xp-netgear-rn2120.dts   | 4 +++-
 arch/arm/boot/dts/armada-xp-openblocks-ax3-4.dts | 4 +++-
 arch/arm/boot/dts/armada-xp-synology-ds414.dts   | 4 +++-
 9 files changed, 27 insertions(+), 9 deletions(-)

diff --git a/arch/arm/boot/dts/armada-xp-axpwifiap.dts b/arch/arm/boot/dts/armada-xp-axpwifiap.dts
index 60bbfe3..23fc670 100644
--- a/arch/arm/boot/dts/armada-xp-axpwifiap.dts
+++ b/arch/arm/boot/dts/armada-xp-axpwifiap.dts
@@ -69,7 +69,9 @@
 
 	soc {
 		ranges = <MBUS_ID(0xf0, 0x01) 0 0 0xf1000000 0x100000
-			  MBUS_ID(0x01, 0x1d) 0 0 0xfff00000 0x100000>;
+			  MBUS_ID(0x01, 0x1d) 0 0 0xfff00000 0x100000
+			  MBUS_ID(0x09, 0x09) 0 0 0xf8100000 0x10000
+			  MBUS_ID(0x09, 0x05) 0 0 0xf8110000 0x10000>;
 
 		pcie-controller {
 			status = "okay";
diff --git a/arch/arm/boot/dts/armada-xp-db.dts b/arch/arm/boot/dts/armada-xp-db.dts
index 7dd900f..f774101 100644
--- a/arch/arm/boot/dts/armada-xp-db.dts
+++ b/arch/arm/boot/dts/armada-xp-db.dts
@@ -75,7 +75,9 @@
 	soc {
 		ranges = <MBUS_ID(0xf0, 0x01) 0 0 0xf1000000 0x100000
 			  MBUS_ID(0x01, 0x1d) 0 0 0xfff00000 0x100000
-			  MBUS_ID(0x01, 0x2f) 0 0 0xf0000000 0x1000000>;
+			  MBUS_ID(0x01, 0x2f) 0 0 0xf0000000 0x1000000
+			  MBUS_ID(0x09, 0x09) 0 0 0xf8100000 0x10000
+			  MBUS_ID(0x09, 0x05) 0 0 0xf8110000 0x10000>;
 
 		devbus-bootcs {
 			status = "okay";
diff --git a/arch/arm/boot/dts/armada-xp-gp.dts b/arch/arm/boot/dts/armada-xp-gp.dts
index bf724ca..4878d73 100644
--- a/arch/arm/boot/dts/armada-xp-gp.dts
+++ b/arch/arm/boot/dts/armada-xp-gp.dts
@@ -94,7 +94,9 @@
 	soc {
 		ranges = <MBUS_ID(0xf0, 0x01) 0 0 0xf1000000 0x100000
 			  MBUS_ID(0x01, 0x1d) 0 0 0xfff00000 0x100000
-			  MBUS_ID(0x01, 0x2f) 0 0 0xf0000000 0x1000000>;
+			  MBUS_ID(0x01, 0x2f) 0 0 0xf0000000 0x1000000
+			  MBUS_ID(0x09, 0x09) 0 0 0xf8100000 0x10000
+			  MBUS_ID(0x09, 0x05) 0 0 0xf8110000 0x10000>;
 
 		devbus-bootcs {
 			status = "okay";
diff --git a/arch/arm/boot/dts/armada-xp-lenovo-ix4-300d.dts b/arch/arm/boot/dts/armada-xp-lenovo-ix4-300d.dts
index 06a6a6c..58b5008 100644
--- a/arch/arm/boot/dts/armada-xp-lenovo-ix4-300d.dts
+++ b/arch/arm/boot/dts/armada-xp-lenovo-ix4-300d.dts
@@ -64,7 +64,9 @@
 
 	soc {
 		ranges = <MBUS_ID(0xf0, 0x01) 0 0 0xd0000000 0x100000
-			MBUS_ID(0x01, 0x1d) 0 0 0xfff00000 0x100000>;
+			MBUS_ID(0x01, 0x1d) 0 0 0xfff00000 0x100000
+			MBUS_ID(0x09, 0x09) 0 0 0xf8100000 0x10000
+			MBUS_ID(0x09, 0x05) 0 0 0xf8110000 0x10000>;
 
 		pcie-controller {
 			status = "okay";
diff --git a/arch/arm/boot/dts/armada-xp-linksys-mamba.dts b/arch/arm/boot/dts/armada-xp-linksys-mamba.dts
index fdd187c..6e9820e 100644
--- a/arch/arm/boot/dts/armada-xp-linksys-mamba.dts
+++ b/arch/arm/boot/dts/armada-xp-linksys-mamba.dts
@@ -69,7 +69,9 @@
 
 	soc {
 		ranges = <MBUS_ID(0xf0, 0x01) 0 0 0xf1000000 0x100000
-			  MBUS_ID(0x01, 0x1d) 0 0 0xfff00000 0x100000>;
+			  MBUS_ID(0x01, 0x1d) 0 0 0xfff00000 0x100000
+			  MBUS_ID(0x09, 0x09) 0 0 0xf8100000 0x10000
+			  MBUS_ID(0x09, 0x05) 0 0 0xf8110000 0x10000>;
 
 		pcie-controller {
 			status = "okay";
diff --git a/arch/arm/boot/dts/armada-xp-matrix.dts b/arch/arm/boot/dts/armada-xp-matrix.dts
index f894bc8..6ab3383 100644
--- a/arch/arm/boot/dts/armada-xp-matrix.dts
+++ b/arch/arm/boot/dts/armada-xp-matrix.dts
@@ -67,7 +67,9 @@
 
 	soc {
 		ranges = <MBUS_ID(0xf0, 0x01) 0 0 0xf1000000 0x100000
-			  MBUS_ID(0x01, 0x1d) 0 0 0xfff00000 0x100000>;
+			  MBUS_ID(0x01, 0x1d) 0 0 0xfff00000 0x100000
+			  MBUS_ID(0x09, 0x09) 0 0 0xf8100000 0x10000
+			  MBUS_ID(0x09, 0x05) 0 0 0xf8110000 0x10000>;
 
 		internal-regs {
 			serial at 12000 {
diff --git a/arch/arm/boot/dts/armada-xp-netgear-rn2120.dts b/arch/arm/boot/dts/armada-xp-netgear-rn2120.dts
index 1516fc2..979fae9 100644
--- a/arch/arm/boot/dts/armada-xp-netgear-rn2120.dts
+++ b/arch/arm/boot/dts/armada-xp-netgear-rn2120.dts
@@ -63,7 +63,9 @@
 
 	soc {
 		ranges = <MBUS_ID(0xf0, 0x01) 0 0 0xd0000000 0x100000
-			  MBUS_ID(0x01, 0x1d) 0 0 0xfff00000 0x100000>;
+			  MBUS_ID(0x01, 0x1d) 0 0 0xfff00000 0x100000
+			  MBUS_ID(0x09, 0x09) 0 0 0xf8100000 0x10000
+			  MBUS_ID(0x09, 0x05) 0 0 0xf8110000 0x10000>;
 
 		pcie-controller {
 			status = "okay";
diff --git a/arch/arm/boot/dts/armada-xp-openblocks-ax3-4.dts b/arch/arm/boot/dts/armada-xp-openblocks-ax3-4.dts
index 990e8a2..a5db177 100644
--- a/arch/arm/boot/dts/armada-xp-openblocks-ax3-4.dts
+++ b/arch/arm/boot/dts/armada-xp-openblocks-ax3-4.dts
@@ -65,7 +65,9 @@
 	soc {
 		ranges = <MBUS_ID(0xf0, 0x01) 0 0 0xd0000000 0x100000
 			  MBUS_ID(0x01, 0x1d) 0 0 0xfff00000 0x100000
-			  MBUS_ID(0x01, 0x2f) 0 0 0xf0000000 0x8000000>;
+			  MBUS_ID(0x01, 0x2f) 0 0 0xf0000000 0x8000000
+			  MBUS_ID(0x09, 0x09) 0 0 0xf8100000 0x10000
+			  MBUS_ID(0x09, 0x05) 0 0 0xf8110000 0x10000>;
 
 		devbus-bootcs {
 			status = "okay";
diff --git a/arch/arm/boot/dts/armada-xp-synology-ds414.dts b/arch/arm/boot/dts/armada-xp-synology-ds414.dts
index 20267ad..2391b11 100644
--- a/arch/arm/boot/dts/armada-xp-synology-ds414.dts
+++ b/arch/arm/boot/dts/armada-xp-synology-ds414.dts
@@ -77,7 +77,9 @@
 
 	soc {
 		ranges = <MBUS_ID(0xf0, 0x01) 0 0 0xf1000000 0x100000
-			  MBUS_ID(0x01, 0x1d) 0 0 0xfff00000 0x100000>;
+			  MBUS_ID(0x01, 0x1d) 0 0 0xfff00000 0x100000
+			  MBUS_ID(0x09, 0x09) 0 0 0xf8100000 0x10000
+			  MBUS_ID(0x09, 0x05) 0 0 0xf8110000 0x10000>;
 
 		pcie-controller {
 			status = "okay";
-- 
1.9.1



From boris.brezillon at free-electrons.com  Tue Aug 18 01:08:58 2015
From: boris.brezillon at free-electrons.com (Boris Brezillon)
Date: Tue, 18 Aug 2015 10:08:58 +0200
Subject: [PATCH 07/10] ARM: marvell/dt: add crypto related nodes to armada 38x
 dtsi
In-Reply-To: <1439885341-14644-1-git-send-email-boris.brezillon@free-electrons.com>
References: <1439885341-14644-1-git-send-email-boris.brezillon@free-electrons.com>
Message-ID: <1439885341-14644-8-git-send-email-boris.brezillon@free-electrons.com>

Add crypto related nodes in armada-38x.dtsi.

Signed-off-by: Boris Brezillon <boris.brezillon at free-electrons.com>
---
 arch/arm/boot/dts/armada-38x.dtsi | 33 +++++++++++++++++++++++++++++++++
 1 file changed, 33 insertions(+)

diff --git a/arch/arm/boot/dts/armada-38x.dtsi b/arch/arm/boot/dts/armada-38x.dtsi
index f9f2347..db6e939 100644
--- a/arch/arm/boot/dts/armada-38x.dtsi
+++ b/arch/arm/boot/dts/armada-38x.dtsi
@@ -509,6 +509,21 @@
 				clocks = <&gateclk 4>;
 			};
 
+			crypto at 90000 {
+				compatible = "marvell,armada-375-crypto";
+				reg = <0x90000 0x10000>;
+				reg-names = "regs";
+				interrupts = <GIC_SPI 19 IRQ_TYPE_LEVEL_HIGH>,
+					     <GIC_SPI 20 IRQ_TYPE_LEVEL_HIGH>;
+				clocks = <&gateclk 23>, <&gateclk 21>,
+					 <&gateclk 14>, <&gateclk 16>;
+				clock-names = "cesa0", "cesa1",
+					      "cesaz0", "cesaz1";
+				marvell,crypto-srams = <&crypto_sram0>,
+						       <&crypto_sram1>;
+				marvell,crypto-sram-size = <0x800>;
+			};
+
 			rtc at a3800 {
 				compatible = "marvell,armada-380-rtc";
 				reg = <0xa3800 0x20>, <0x184a0 0x0c>;
@@ -584,6 +599,24 @@
 				status = "disabled";
 			};
 		};
+
+		crypto_sram0: sa-sram0 {
+			compatible = "mmio-sram";
+			reg = <MBUS_ID(0x09, 0x19) 0 0x800>;
+			clocks = <&gateclk 23>;
+			#address-cells = <1>;
+			#size-cells = <1>;
+			ranges = <0 MBUS_ID(0x09, 0x19) 0 0x800>;
+		};
+
+		crypto_sram1: sa-sram1 {
+			compatible = "mmio-sram";
+			reg = <MBUS_ID(0x09, 0x15) 0 0x800>;
+			clocks = <&gateclk 21>;
+			#address-cells = <1>;
+			#size-cells = <1>;
+			ranges = <0 MBUS_ID(0x09, 0x15) 0 0x800>;
+		};
 	};
 
 	clocks {
-- 
1.9.1



From boris.brezillon at free-electrons.com  Tue Aug 18 01:08:57 2015
From: boris.brezillon at free-electrons.com (Boris Brezillon)
Date: Tue, 18 Aug 2015 10:08:57 +0200
Subject: [PATCH 06/10] ARM: marvell/dt: define crypto SRAM ranges in
 armada-375-db.dts
In-Reply-To: <1439885341-14644-1-git-send-email-boris.brezillon@free-electrons.com>
References: <1439885341-14644-1-git-send-email-boris.brezillon@free-electrons.com>
Message-ID: <1439885341-14644-7-git-send-email-boris.brezillon@free-electrons.com>

Define the crypto SRAM ranges so that the resources referenced by the
sa-sram node can be properly extracted from the DT.

Signed-off-by: Boris Brezillon <boris.brezillon at free-electrons.com>
---
 arch/arm/boot/dts/armada-375-db.dts | 4 +++-
 1 file changed, 3 insertions(+), 1 deletion(-)

diff --git a/arch/arm/boot/dts/armada-375-db.dts b/arch/arm/boot/dts/armada-375-db.dts
index 5711b97..cded5f0 100644
--- a/arch/arm/boot/dts/armada-375-db.dts
+++ b/arch/arm/boot/dts/armada-375-db.dts
@@ -65,7 +65,9 @@
 
 	soc {
 		ranges = <MBUS_ID(0xf0, 0x01) 0 0xf1000000 0x100000
-			  MBUS_ID(0x01, 0x1d) 0 0xfff00000 0x100000>;
+			  MBUS_ID(0x01, 0x1d) 0 0xfff00000 0x100000
+			  MBUS_ID(0x09, 0x09) 0 0xf1100000 0x10000
+			  MBUS_ID(0x09, 0x05) 0 0xf1110000 0x10000>;
 
 		internal-regs {
 			spi at 10600 {
-- 
1.9.1



From boris.brezillon at free-electrons.com  Tue Aug 18 01:09:01 2015
From: boris.brezillon at free-electrons.com (Boris Brezillon)
Date: Tue, 18 Aug 2015 10:09:01 +0200
Subject: [PATCH 10/10] ARM: marvell: modify Orion and Kirkwoord crypto
 compatible strings
In-Reply-To: <1439885341-14644-1-git-send-email-boris.brezillon@free-electrons.com>
References: <1439885341-14644-1-git-send-email-boris.brezillon@free-electrons.com>
Message-ID: <1439885341-14644-11-git-send-email-boris.brezillon@free-electrons.com>

Explicitly use the SoC specific compatible strings in kirkwood.dtsi and
dove.dtsi, so that the crypto devices have access to the TDMA feature
when attached to the new CESA driver.

Signed-off-by: Boris Brezillon <boris.brezillon at free-electrons.com>
---
 arch/arm/boot/dts/dove.dtsi     | 2 +-
 arch/arm/boot/dts/kirkwood.dtsi | 2 +-
 2 files changed, 2 insertions(+), 2 deletions(-)

diff --git a/arch/arm/boot/dts/dove.dtsi b/arch/arm/boot/dts/dove.dtsi
index 9bb3131..cd58c2e 100644
--- a/arch/arm/boot/dts/dove.dtsi
+++ b/arch/arm/boot/dts/dove.dtsi
@@ -263,7 +263,7 @@
 			};
 
 			crypto: crypto-engine at 30000 {
-				compatible = "marvell,orion-crypto";
+				compatible = "marvell,dove-crypto";
 				reg = <0x30000 0x10000>;
 				reg-names = "regs";
 				interrupts = <31>;
diff --git a/arch/arm/boot/dts/kirkwood.dtsi b/arch/arm/boot/dts/kirkwood.dtsi
index c5f913b..7b5a4a1 100644
--- a/arch/arm/boot/dts/kirkwood.dtsi
+++ b/arch/arm/boot/dts/kirkwood.dtsi
@@ -251,7 +251,7 @@
 		};
 
 		cesa: crypto at 30000 {
-			compatible = "marvell,orion-crypto";
+			compatible = "marvell,kirkwood-crypto";
 			reg = <0x30000 0x10000>;
 			reg-names = "regs";
 			interrupts = <22>;
-- 
1.9.1



From boris.brezillon at free-electrons.com  Tue Aug 18 01:08:59 2015
From: boris.brezillon at free-electrons.com (Boris Brezillon)
Date: Tue, 18 Aug 2015 10:08:59 +0200
Subject: [PATCH 08/10] ARM: marvell/dt: define crypto SRAM ranges for all
 armada-38x boards
In-Reply-To: <1439885341-14644-1-git-send-email-boris.brezillon@free-electrons.com>
References: <1439885341-14644-1-git-send-email-boris.brezillon@free-electrons.com>
Message-ID: <1439885341-14644-9-git-send-email-boris.brezillon@free-electrons.com>

Define the crypto SRAM ranges so that the resources referenced by the
sa-sram node can be properly extracted from the DT.

Signed-off-by: Boris Brezillon <boris.brezillon at free-electrons.com>
---
 arch/arm/boot/dts/armada-385-db-ap.dts    | 4 +++-
 arch/arm/boot/dts/armada-385-linksys.dtsi | 4 +++-
 arch/arm/boot/dts/armada-388-db.dts       | 4 +++-
 arch/arm/boot/dts/armada-388-gp.dts       | 4 +++-
 arch/arm/boot/dts/armada-388-rd.dts       | 4 +++-
 5 files changed, 15 insertions(+), 5 deletions(-)

diff --git a/arch/arm/boot/dts/armada-385-db-ap.dts b/arch/arm/boot/dts/armada-385-db-ap.dts
index 89f5a95..4de813c 100644
--- a/arch/arm/boot/dts/armada-385-db-ap.dts
+++ b/arch/arm/boot/dts/armada-385-db-ap.dts
@@ -59,7 +59,9 @@
 
 	soc {
 		ranges = <MBUS_ID(0xf0, 0x01) 0 0xf1000000 0x100000
-			  MBUS_ID(0x01, 0x1d) 0 0xfff00000 0x100000>;
+			  MBUS_ID(0x01, 0x1d) 0 0xfff00000 0x100000
+			  MBUS_ID(0x09, 0x19) 0 0xf1100000 0x10000
+			  MBUS_ID(0x09, 0x15) 0 0xf1110000 0x10000>;
 
 		internal-regs {
 			spi1: spi at 10680 {
diff --git a/arch/arm/boot/dts/armada-385-linksys.dtsi b/arch/arm/boot/dts/armada-385-linksys.dtsi
index 74a9c6b..3710755 100644
--- a/arch/arm/boot/dts/armada-385-linksys.dtsi
+++ b/arch/arm/boot/dts/armada-385-linksys.dtsi
@@ -57,7 +57,9 @@
 
 	soc {
 		ranges = <MBUS_ID(0xf0, 0x01) 0 0xf1000000 0x100000
-			  MBUS_ID(0x01, 0x1d) 0 0xfff00000 0x100000>;
+			  MBUS_ID(0x01, 0x1d) 0 0xfff00000 0x100000
+			  MBUS_ID(0x09, 0x09) 0 0xf1100000 0x10000
+			  MBUS_ID(0x09, 0x05) 0 0xf1110000 0x10000>;
 
 		internal-regs {
 
diff --git a/arch/arm/boot/dts/armada-388-db.dts b/arch/arm/boot/dts/armada-388-db.dts
index 91ac8c1..ff47af5 100644
--- a/arch/arm/boot/dts/armada-388-db.dts
+++ b/arch/arm/boot/dts/armada-388-db.dts
@@ -64,7 +64,9 @@
 
 	soc {
 		ranges = <MBUS_ID(0xf0, 0x01) 0 0xf1000000 0x100000
-			  MBUS_ID(0x01, 0x1d) 0 0xfff00000 0x100000>;
+			  MBUS_ID(0x01, 0x1d) 0 0xfff00000 0x100000
+			  MBUS_ID(0x09, 0x19) 0 0xf1100000 0x10000
+			  MBUS_ID(0x09, 0x15) 0 0xf1110000 0x10000>;
 
 		internal-regs {
 			spi at 10600 {
diff --git a/arch/arm/boot/dts/armada-388-gp.dts b/arch/arm/boot/dts/armada-388-gp.dts
index 353c925..4baac93 100644
--- a/arch/arm/boot/dts/armada-388-gp.dts
+++ b/arch/arm/boot/dts/armada-388-gp.dts
@@ -58,7 +58,9 @@
 
 	soc {
 		ranges = <MBUS_ID(0xf0, 0x01) 0 0xf1000000 0x100000
-			  MBUS_ID(0x01, 0x1d) 0 0xfff00000 0x100000>;
+			  MBUS_ID(0x01, 0x1d) 0 0xfff00000 0x100000
+			  MBUS_ID(0x09, 0x19) 0 0xf1100000 0x10000
+			  MBUS_ID(0x09, 0x15) 0 0xf1110000 0x10000>;
 
 		internal-regs {
 			spi at 10600 {
diff --git a/arch/arm/boot/dts/armada-388-rd.dts b/arch/arm/boot/dts/armada-388-rd.dts
index b657b16..853f973 100644
--- a/arch/arm/boot/dts/armada-388-rd.dts
+++ b/arch/arm/boot/dts/armada-388-rd.dts
@@ -65,7 +65,9 @@
 
 	soc {
 		ranges = <MBUS_ID(0xf0, 0x01) 0 0xf1000000 0x100000
-			  MBUS_ID(0x01, 0x1d) 0 0xfff00000 0x100000>;
+			  MBUS_ID(0x01, 0x1d) 0 0xfff00000 0x100000
+			  MBUS_ID(0x09, 0x19) 0 0xf1100000 0x10000
+			  MBUS_ID(0x09, 0x15) 0 0xf1110000 0x10000>;
 
 		internal-regs {
 			spi at 10600 {
-- 
1.9.1



From boris.brezillon at free-electrons.com  Tue Aug 18 01:08:56 2015
From: boris.brezillon at free-electrons.com (Boris Brezillon)
Date: Tue, 18 Aug 2015 10:08:56 +0200
Subject: [PATCH 05/10] ARM: marvell/dt: add crypto related nodes to armada 375
 dtsi
In-Reply-To: <1439885341-14644-1-git-send-email-boris.brezillon@free-electrons.com>
References: <1439885341-14644-1-git-send-email-boris.brezillon@free-electrons.com>
Message-ID: <1439885341-14644-6-git-send-email-boris.brezillon@free-electrons.com>

Add crypto related nodes in armada-375.dtsi.

Signed-off-by: Boris Brezillon <boris.brezillon at free-electrons.com>
---
 arch/arm/boot/dts/armada-375.dtsi | 33 +++++++++++++++++++++++++++++++++
 1 file changed, 33 insertions(+)

diff --git a/arch/arm/boot/dts/armada-375.dtsi b/arch/arm/boot/dts/armada-375.dtsi
index e9a3817..7ccce75 100644
--- a/arch/arm/boot/dts/armada-375.dtsi
+++ b/arch/arm/boot/dts/armada-375.dtsi
@@ -513,6 +513,21 @@
 				};
 			};
 
+			crypto at 90000 {
+				compatible = "marvell,armada-375-crypto";
+				reg = <0x90000 0x10000>;
+				reg-names = "regs";
+				interrupts = <GIC_SPI 19 IRQ_TYPE_LEVEL_HIGH>,
+					     <GIC_SPI 20 IRQ_TYPE_LEVEL_HIGH>;
+				clocks = <&gateclk 30>, <&gateclk 31>,
+					 <&gateclk 28>, <&gateclk 29>;
+				clock-names = "cesa0", "cesa1",
+					      "cesaz0", "cesaz1";
+				marvell,crypto-srams = <&crypto_sram0>,
+						       <&crypto_sram1>;
+				marvell,crypto-sram-size = <0x800>;
+			};
+
 			sata at a0000 {
 				compatible = "marvell,orion-sata";
 				reg = <0xa0000 0x5000>;
@@ -619,5 +634,23 @@
 			};
 
 		};
+
+		crypto_sram0: sa-sram0 {
+			compatible = "mmio-sram";
+			reg = <MBUS_ID(0x09, 0x09) 0 0x800>;
+			clocks = <&gateclk 30>;
+			#address-cells = <1>;
+			#size-cells = <1>;
+			ranges = <0 MBUS_ID(0x09, 0x09) 0 0x800>;
+		};
+
+		crypto_sram1: sa-sram1 {
+			compatible = "mmio-sram";
+			reg = <MBUS_ID(0x09, 0x05) 0 0x800>;
+			clocks = <&gateclk 31>;
+			#address-cells = <1>;
+			#size-cells = <1>;
+			ranges = <0 MBUS_ID(0x09, 0x05) 0 0x800>;
+		};
 	};
 };
-- 
1.9.1



From boris.brezillon at free-electrons.com  Tue Aug 18 01:09:00 2015
From: boris.brezillon at free-electrons.com (Boris Brezillon)
Date: Tue, 18 Aug 2015 10:09:00 +0200
Subject: [PATCH 09/10] ARM: marvell: use new bindings for existing crypto
 devices
In-Reply-To: <1439885341-14644-1-git-send-email-boris.brezillon@free-electrons.com>
References: <1439885341-14644-1-git-send-email-boris.brezillon@free-electrons.com>
Message-ID: <1439885341-14644-10-git-send-email-boris.brezillon@free-electrons.com>

The new bindings split the crypto and sram node in two separate devices.
Modify the existing crypto nodes to match the new representation.

Signed-off-by: Boris Brezillon <boris.brezillon at free-electrons.com>
---
 arch/arm/boot/dts/dove.dtsi     | 15 ++++++++++++---
 arch/arm/boot/dts/kirkwood.dtsi | 29 +++++++++++++++++++----------
 arch/arm/boot/dts/orion5x.dtsi  | 22 +++++++++++++++-------
 3 files changed, 46 insertions(+), 20 deletions(-)

diff --git a/arch/arm/boot/dts/dove.dtsi b/arch/arm/boot/dts/dove.dtsi
index 1791216..9bb3131 100644
--- a/arch/arm/boot/dts/dove.dtsi
+++ b/arch/arm/boot/dts/dove.dtsi
@@ -264,11 +264,12 @@
 
 			crypto: crypto-engine at 30000 {
 				compatible = "marvell,orion-crypto";
-				reg = <0x30000 0x10000>,
-				      <0xffffe000 0x800>;
-				reg-names = "regs", "sram";
+				reg = <0x30000 0x10000>;
+				reg-names = "regs";
 				interrupts = <31>;
 				clocks = <&gate_clk 15>;
+				marvell,crypto-srams = <&crypto_sram>;
+				marvell,crypto-sram-size = <0x800>;
 				status = "okay";
 			};
 
@@ -767,6 +768,14 @@
 				interrupts = <47>;
 				status = "disabled";
 			};
+
+			crypto_sram: sa-sram at ffffe000 {
+				compatible = "mmio-sram";
+				reg = <0xffffe000 0x800>;
+				clocks = <&gate_clk 15>;
+				#address-cells = <1>;
+				#size-cells = <1>;
+			};
 		};
 	};
 };
diff --git a/arch/arm/boot/dts/kirkwood.dtsi b/arch/arm/boot/dts/kirkwood.dtsi
index 464f09a..c5f913b 100644
--- a/arch/arm/boot/dts/kirkwood.dtsi
+++ b/arch/arm/boot/dts/kirkwood.dtsi
@@ -40,16 +40,6 @@
 		pcie-mem-aperture = <0xe0000000 0x10000000>; /* 256 MiB memory space */
 		pcie-io-aperture  = <0xf2000000 0x100000>;   /*   1 MiB    I/O space */
 
-		cesa: crypto at 0301 {
-			compatible = "marvell,orion-crypto";
-			reg = <MBUS_ID(0xf0, 0x01) 0x30000 0x10000>,
-			      <MBUS_ID(0x03, 0x01) 0 0x800>;
-			reg-names = "regs", "sram";
-			interrupts = <22>;
-			clocks = <&gate_clk 17>;
-			status = "okay";
-		};
-
 		nand: nand at 012f {
 			#address-cells = <1>;
 			#size-cells = <1>;
@@ -65,6 +55,14 @@
 			pinctrl-names = "default";
 			status = "disabled";
 		};
+
+		crypto_sram: sa-sram at 0301 {
+			compatible = "mmio-sram";
+			reg = <MBUS_ID(0x03, 0x01) 0x0 0x800>;
+			clocks = <&gate_clk 17>;
+			#address-cells = <1>;
+			#size-cells = <1>;
+		};
 	};
 
 	ocp at f1000000 {
@@ -252,6 +250,17 @@
 			status = "okay";
 		};
 
+		cesa: crypto at 30000 {
+			compatible = "marvell,orion-crypto";
+			reg = <0x30000 0x10000>;
+			reg-names = "regs";
+			interrupts = <22>;
+			clocks = <&gate_clk 17>;
+			marvell,crypto-srams = <&crypto_sram>;
+			marvell,crypto-sram-size = <0x800>;
+			status = "okay";
+		};
+
 		usb0: ehci at 50000 {
 			compatible = "marvell,orion-ehci";
 			reg = <0x50000 0x1000>;
diff --git a/arch/arm/boot/dts/orion5x.dtsi b/arch/arm/boot/dts/orion5x.dtsi
index 75cd01b..e1b6d2a 100644
--- a/arch/arm/boot/dts/orion5x.dtsi
+++ b/arch/arm/boot/dts/orion5x.dtsi
@@ -212,6 +212,16 @@
 				status = "disabled";
 			};
 
+			cesa: crypto at 90000 {
+				compatible = "marvell,orion-crypto";
+				reg = <0x90000 0x10000>;
+				reg-names = "regs";
+				interrupts = <28>;
+				marvell,crypto-srams = <&crypto_sram>;
+				marvell,crypto-sram-size = <0x800>;
+				status = "okay";
+			};
+
 			ehci1: ehci at a0000 {
 				compatible = "marvell,orion-ehci";
 				reg = <0xa0000 0x1000>;
@@ -220,13 +230,11 @@
 			};
 		};
 
-		cesa: crypto at 90000 {
-			compatible = "marvell,orion-crypto";
-			reg = <MBUS_ID(0xf0, 0x01) 0x90000 0x10000>,
-			      <MBUS_ID(0x09, 0x00) 0x0 0x800>;
-			reg-names = "regs", "sram";
-			interrupts = <28>;
-			status = "okay";
+		crypto_sram: sa-sram {
+			compatible = "mmio-sram";
+			reg = <MBUS_ID(0x09, 0x00) 0x0 0x800>;
+			#address-cells = <1>;
+			#size-cells = <1>;
 		};
 	};
 };
-- 
1.9.1



From k.kozlowski at samsung.com  Tue Aug 18 01:09:33 2015
From: k.kozlowski at samsung.com (Krzysztof Kozlowski)
Date: Tue, 18 Aug 2015 17:09:33 +0900
Subject: [PATCH] ARM: exynos_defconfig: Enable CROS_EC_PROTO for ChromeOS
 EC mfd driver
In-Reply-To: <55D2E767.50807@osg.samsung.com>
References: <1439881281-22054-1-git-send-email-javier@osg.samsung.com>
 <55D2E569.3000800@samsung.com> <55D2E767.50807@osg.samsung.com>
Message-ID: <55D2E83D.70206@samsung.com>

On 18.08.2015 17:05, Javier Martinez Canillas wrote:
> Hello Krzysztof,
> 
> On 08/18/2015 09:57 AM, Krzysztof Kozlowski wrote:
>> On 18.08.2015 16:01, Javier Martinez Canillas wrote:
>>> The ChromeOS mfd driver (MFD_CROS_EC) select the CROS_EC_PROTO config
>>> symbol because the driver uses some communication helper functions in
>>> drivers/platform/chrome/cros_ec_proto.c but other drivers depends on
>>> CROS_EC_PROTO instead. Mixing select and depends can lead to circular
>>> Kconfig dependencies so the MFD_CROS_EC select should be changed to a
>>> depends on CROS_EC_PROTO instead.
>>>
>>> But doing so will break git bisect-ability since MFD_CROS_EC will not
>>> be enabled anymore unless the default configs first explicitly enable
>>> the CROS_EC_PROTO dependency.
>>>
>>> Signed-off-by: Javier Martinez Canillas <javier at osg.samsung.com>
>>> ---
>>>  arch/arm/configs/exynos_defconfig | 1 +
>>>  1 file changed, 1 insertion(+)
>>
>> I saw the discussion about circular dependency but I wasn't following
>> it. Currently the CROS_EC_PROTO is not user-selectable. How can you
>> depend on it? How can be enabled on different configs (customized by user)?
>>
>> Maybe the questions are answered by code in different patches?
> 
> Yes, that's why I posted "[PATCH] platform/chrome: Make CROS_EC_PROTO
> a user selectable option" [0].
> 
> I posted as separate patches because there isn't a dependency between
> them and once all the defconfig patches and the patch to make the
> CROS_EC_PROTO symbol user selectable lands, I'll post the patch to
> change select for depends on to avoid a regression.

Makes sense now.

Reviewed-by: Krzysztof Kozlowski <k.kozlowski at samsung.com>

> 
> Maybe I should had posted as a series (or at least cc all the people
> in all the patches) to not left these questions unanswered...

Yep, Cc-ing or a short cover letter would probably answer my question. :)

Best regards,
Krzysztof



From javier at osg.samsung.com  Tue Aug 18 01:12:46 2015
From: javier at osg.samsung.com (Javier Martinez Canillas)
Date: Tue, 18 Aug 2015 10:12:46 +0200
Subject: [PATCH] ARM: exynos_defconfig: Enable CROS_EC_PROTO for ChromeOS
 EC mfd driver
In-Reply-To: <55D2E83D.70206@samsung.com>
References: <1439881281-22054-1-git-send-email-javier@osg.samsung.com>
 <55D2E569.3000800@samsung.com> <55D2E767.50807@osg.samsung.com>
 <55D2E83D.70206@samsung.com>
Message-ID: <55D2E8FE.7090008@osg.samsung.com>

Hello Krzysztof,

On 08/18/2015 10:09 AM, Krzysztof Kozlowski wrote:
> On 18.08.2015 17:05, Javier Martinez Canillas wrote:
>> Hello Krzysztof,
>>
>> On 08/18/2015 09:57 AM, Krzysztof Kozlowski wrote:
>>> On 18.08.2015 16:01, Javier Martinez Canillas wrote:
>>>> The ChromeOS mfd driver (MFD_CROS_EC) select the CROS_EC_PROTO config
>>>> symbol because the driver uses some communication helper functions in
>>>> drivers/platform/chrome/cros_ec_proto.c but other drivers depends on
>>>> CROS_EC_PROTO instead. Mixing select and depends can lead to circular
>>>> Kconfig dependencies so the MFD_CROS_EC select should be changed to a
>>>> depends on CROS_EC_PROTO instead.
>>>>
>>>> But doing so will break git bisect-ability since MFD_CROS_EC will not
>>>> be enabled anymore unless the default configs first explicitly enable
>>>> the CROS_EC_PROTO dependency.
>>>>
>>>> Signed-off-by: Javier Martinez Canillas <javier at osg.samsung.com>
>>>> ---
>>>>  arch/arm/configs/exynos_defconfig | 1 +
>>>>  1 file changed, 1 insertion(+)
>>>
>>> I saw the discussion about circular dependency but I wasn't following
>>> it. Currently the CROS_EC_PROTO is not user-selectable. How can you
>>> depend on it? How can be enabled on different configs (customized by user)?
>>>
>>> Maybe the questions are answered by code in different patches?
>>
>> Yes, that's why I posted "[PATCH] platform/chrome: Make CROS_EC_PROTO
>> a user selectable option" [0].
>>
>> I posted as separate patches because there isn't a dependency between
>> them and once all the defconfig patches and the patch to make the
>> CROS_EC_PROTO symbol user selectable lands, I'll post the patch to
>> change select for depends on to avoid a regression.
> 
> Makes sense now.
> 
> Reviewed-by: Krzysztof Kozlowski <k.kozlowski at samsung.com>
> 

Thanks!

>>
>> Maybe I should had posted as a series (or at least cc all the people
>> in all the patches) to not left these questions unanswered...
> 
> Yep, Cc-ing or a short cover letter would probably answer my question. :)
>

Yes, sorry about that.
 
> Best regards,
> Krzysztof
> 
> --
> To unsubscribe from this list: send the line "unsubscribe linux-samsung-soc" in
> the body of a message to majordomo at vger.kernel.org
> More majordomo info at  http://vger.kernel.org/majordomo-info.html
> 

Best regards,
-- 
Javier Martinez Canillas
Open Source Group
Samsung Research America


From linux at arm.linux.org.uk  Tue Aug 18 01:13:34 2015
From: linux at arm.linux.org.uk (Russell King - ARM Linux)
Date: Tue, 18 Aug 2015 09:13:34 +0100
Subject: [PATCH] ARM: keystone: add a work around to handle asynchronous
 external abort
In-Reply-To: <55D2A1DD.9000007@oracle.com>
References: <1439320409-20084-1-git-send-email-m-karicheri2@ti.com>
 <55CDF579.4050408@ti.com>
 <20150814140934.GX7557@n2100.arm.linux.org.uk>
 <55CE05EC.4040909@oracle.com> <55CE633C.10402@ti.com>
 <20150814215617.GA7557@n2100.arm.linux.org.uk>
 <55D25C64.3090107@ti.com> <55D2A1DD.9000007@oracle.com>
Message-ID: <20150818081334.GK7557@n2100.arm.linux.org.uk>

On Mon, Aug 17, 2015 at 08:09:17PM -0700, santosh.shilimkar at oracle.com wrote:
> From the logs this seems to be mostly clock related issue for some
> peripheral. If the bootloader clock enable all hack still exists,
> may be you can try that out.
> 
> Another way to debug this is to start disabling peripheral drivers
> from the kernel 1 by 1 and see if the issue goes away.

Highly unlikely to make any difference.  As the failure happens soo early
with the patch applied, the kernel hasn't had much of a chance to touch
the hardware - about the only things are the decompressor and the kernel
touching the early console.  As they seem to be working, it suggests
that's not the cause.

It seems to be pointing towards something in the boot loader...

Normally, uboot will hook itself into the vectors to report errors, but
I wonder whether uboot enables asynchronous aborts while it's running.
Don't forget to make sure that the aborts are disabled again prior to
calling the kernel.

-- 
FTTC broadband for 0.8mile line: currently at 10.5Mbps down 400kbps up
according to speedtest.net.


From will.deacon at arm.com  Tue Aug 18 01:21:36 2015
From: will.deacon at arm.com (Will Deacon)
Date: Tue, 18 Aug 2015 09:21:36 +0100
Subject: [RFC v2 1/4] ftrace: allow arch-specific check_stack()
In-Reply-To: <55D17A04.7020800@linaro.org>
References: <1438674249-3447-1-git-send-email-takahiro.akashi@linaro.org>
 <1438674249-3447-2-git-send-email-takahiro.akashi@linaro.org>
 <20150811170321.GB29880@arm.com> <55D17A04.7020800@linaro.org>
Message-ID: <20150818082136.GA10301@arm.com>

On Mon, Aug 17, 2015 at 07:07:00AM +0100, AKASHI Takahiro wrote:
> On 08/12/2015 02:03 AM, Will Deacon wrote:
> > On Tue, Aug 04, 2015 at 08:44:06AM +0100, AKASHI Takahiro wrote:
> >> A stack frame pointer may be used in a different way depending on
> >> cpu architecture. Thus it is not always appropriate to slurp the stack
> >> contents, as currently done in check_stack(), in order to calcurate
> >> a stack index (height) at a given function call. At least not on arm64.
> >>
> >> This patch extract potentially arch-specific code from check_stack()
> >> and puts it into a new arch_check_stack(), which is declared as weak.
> >> So we will be able to add arch-specific and most efficient way of
> >> stack traversing Later.
> >>
> >> Signed-off-by: AKASHI Takahiro <takahiro.akashi at linaro.org>
> >
> > If arm64 is the only architecture behaving differently, then I'm happy
> > to reconsider the fix to unwind_frame that we merged in e306dfd06fcb
> > ("ARM64: unwind: Fix PC calculation"). I'd have thought any architecture
> > with a branch-and-link instruction would potentially have the same issue,
> > so we could just be fixing things in the wrong place if ftrace works
> > everywhere else.
> 
> I'm not the right person to answer for other architectures (and ftrace
> behavior on them.) The only thing I know is that current ftrace stack tracer
> works correctly only if the addresses stored and found on stack match to
> the ones returned by save_stack_trace().
> 
> Anyway, the fix above is not the only reason that I want to introduce arch-specific
> arch_check_stack(). Other issues to fix include
>    - combined case of stack tracer and function graph tracer (common across arch's)
>    - exception entries (as I'm trying to address in RFC 4/4)
>    - in-accurate stack size (for each function, my current fix is not perfect though.)

Ok, if you have other reasons for the callback, then fine. I just didn't
want you to think that you had to work around e306dfd06fcb at all costs.

Will


From Dave.Martin at arm.com  Tue Aug 18 01:21:52 2015
From: Dave.Martin at arm.com (Dave Martin)
Date: Tue, 18 Aug 2015 09:21:52 +0100
Subject: [PATCH 2/3] [v4] ARM64: TTY: hvc_dcc: Add support for ARM64 dcc
In-Reply-To: <55D2749A.401@codeaurora.org>
References: <1438992995-22610-1-git-send-email-timur@codeaurora.org>
 <1438992995-22610-2-git-send-email-timur@codeaurora.org>
 <20150810094008.GD1604@arm.com> <55D2749A.401@codeaurora.org>
Message-ID: <20150818082141.GA6281@e103592.cambridge.arm.com>

On Mon, Aug 17, 2015 at 06:56:10PM -0500, Timur Tabi wrote:
> On 08/10/2015 04:40 AM, Will Deacon wrote:
> >>>+static inline void __dcc_putchar(char c)
> >>>+{
> >>>+	asm volatile("msr dbgdtrtx_el0, %0"
> >>>+			: /* No output register */
> >>>+			: "r" (c));
> >>>+	isb();
> 
> >I think we should be masking out the upper bits of c before the msr
> >(the compiler probably expects a uxtb).
> 
> Well, we've never seen a problem, but that doesn't mean it doesn't
> exist.  I couldn't find anything in the ARMv8 ARM (section H9.2.7
> DBGDTRTX_EL0) about word sizes.
> 
> Do you think that I need an explicit instruction to clear the upper
> bits?  I tried a few compiler tricks (e.g. "c && 0xff" and the
> like), and they had no effect.

The in-register representation of a char permits the upper bits to be
nonzero, so you need to convert to a register-sized type if you want
to be able to force those bits to zero.

Try: (unsigned long)(unsigned char)c or (unsigned long)c & 0xff.

> 
> I do need help with the inline assembly.  I tried this:
> 
> static inline void __dcc_putchar(char c)
> {
> 	unsigned int __c;
> 
> 	asm volatile("uxtb %0, %w1\n"
> 		"msr dbgdtrtx_el0, %0"
> 			: "=r" (__c)
> 			: "r" (c));
> 	isb();
> }
> 
> it gives this assembly code:
> 
>   28:	38401423 	ldrb	w3, [x1],#1
>   2c:	53001c63 	uxtb	w3, w3
>   30:	d5130503 	msr	dbgdtrrx_el0, x3
> 
> Is this correct?  Shouldn't it be "uxtb x3, w3"?

Check the ARM ARM for what operand combinations are allowed.  However,
it doesn't really make any difference here because it's a general rule
in the architecture that when an instruction's output is in a
W-register, the upper 32 bits of the corresponding X-register are
always zeroed anyway.

Cheers
---Dave



From boris.brezillon at free-electrons.com  Tue Aug 18 01:24:01 2015
From: boris.brezillon at free-electrons.com (Boris Brezillon)
Date: Tue, 18 Aug 2015 10:24:01 +0200
Subject: [PULL] clk: at91: sama5d2 materials
Message-ID: <20150818102401.17de779b@bbrezillon>

Stephen, Mike,

Here is a PR for the sama5d2 materials.
I know we're already late in the release cycle and I'm not sure you can
take this PR into account for 4.3, so if you can't could you please
queue it for 4.4?

Thanks,

Boris

The following changes since commit c42743f11f58646a50bc4b96da363429dca0c5e6:

  clk: add bindings for the Ux500 clocks (2015-08-13 11:29:45 -0700)

are available in the git repository at:

  https://github.com/bbrezillon/linux-at91.git clk/atmel-clk-next

for you to fetch changes up to 3be0527c0f8bbbb744a6a34603d6a83e511c6741:

  clk: at91: add generated clock driver (2015-08-18 10:11:57 +0200)

----------------------------------------------------------------
Nicolas Ferre (4):
      clk: at91: cleanup PMC header file for PCR register fields
      clk: at91: modify PMC peripheral clock to deal with newer register layout
      clk: at91: add PMC sama5d2 support
      clk: at91: add generated clock driver

 Documentation/devicetree/bindings/clock/at91-clock.txt |  35 +++++++++++++++++++++
 arch/arm/mach-at91/Kconfig                             |   3 ++
 drivers/clk/at91/Makefile                              |   1 +
 drivers/clk/at91/clk-generated.c                       | 306 ++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
 drivers/clk/at91/clk-peripheral.c                      |  24 +++++++++-----
 drivers/clk/at91/pmc.c                                 |  21 +++++++++++++
 drivers/clk/at91/pmc.h                                 |   3 ++
 include/dt-bindings/clock/at91.h                       |   1 +
 include/linux/clk/at91_pmc.h                           |  22 ++++++++-----
 9 files changed, 400 insertions(+), 16 deletions(-)
 create mode 100644 drivers/clk/at91/clk-generated.c


From jszhang at marvell.com  Tue Aug 18 01:21:39 2015
From: jszhang at marvell.com (Jisheng Zhang)
Date: Tue, 18 Aug 2015 16:21:39 +0800
Subject: [PATCH v3] mmc: sdhci: also get preset value and driver type for
 MMC_DDR52
Message-ID: <1439886099-5531-1-git-send-email-jszhang@marvell.com>

commit bb8175a8aa42 ("mmc: sdhci: clarify DDR timing mode between
SD-UHS and eMMC") added MMC_DDR52 as eMMC's DDR mode to be
distinguished from SD-UHS, but it missed setting driver type for
MMC_DDR52 timing mode.

So sometimes we get the following error on Marvell BG2Q DMP board:

[    1.559598] mmcblk0: error -84 transferring data, sector 0, nr 8, cmd
response 0x900, card status 0xb00
[    1.569314] mmcblk0: retrying using single block read
[    1.575676] mmcblk0: error -84 transferring data, sector 2, nr 6, cmd
response 0x900, card status 0x0
[    1.585202] blk_update_request: I/O error, dev mmcblk0, sector 2
[    1.591818] mmcblk0: error -84 transferring data, sector 3, nr 5, cmd
response 0x900, card status 0x0
[    1.601341] blk_update_request: I/O error, dev mmcblk0, sector 3

This patches fixes this by adding the missing driver type setting.

Fixes: bb8175a8aa42 ("mmc: sdhci: clarify DDR timing mode ...")
Signed-off-by: Jisheng Zhang <jszhang at marvell.com>
---
 Since v2:
  - fix sdhci_get_preset_value for MMC_DDR52
  - add typical emmc error log which this patch intends to fix

 Since v1:
  - correct commit-msg

 drivers/mmc/host/sdhci.c | 4 +++-
 1 file changed, 3 insertions(+), 1 deletion(-)

diff --git a/drivers/mmc/host/sdhci.c b/drivers/mmc/host/sdhci.c
index 1dbe932..673d703 100644
--- a/drivers/mmc/host/sdhci.c
+++ b/drivers/mmc/host/sdhci.c
@@ -1132,6 +1132,7 @@ static u16 sdhci_get_preset_value(struct sdhci_host *host)
 		preset = sdhci_readw(host, SDHCI_PRESET_FOR_SDR104);
 		break;
 	case MMC_TIMING_UHS_DDR50:
+	case MMC_TIMING_MMC_DDR52:
 		preset = sdhci_readw(host, SDHCI_PRESET_FOR_DDR50);
 		break;
 	case MMC_TIMING_MMC_HS400:
@@ -1559,7 +1560,8 @@ static void sdhci_do_set_ios(struct sdhci_host *host, struct mmc_ios *ios)
 				 (ios->timing == MMC_TIMING_UHS_SDR25) ||
 				 (ios->timing == MMC_TIMING_UHS_SDR50) ||
 				 (ios->timing == MMC_TIMING_UHS_SDR104) ||
-				 (ios->timing == MMC_TIMING_UHS_DDR50))) {
+				 (ios->timing == MMC_TIMING_UHS_DDR50) ||
+				 (ios->timing == MMC_TIMING_MMC_DDR52))) {
 			u16 preset;
 
 			sdhci_enable_preset_value(host, true);
-- 
2.5.0



From eric.auger at linaro.org  Tue Aug 18 01:26:08 2015
From: eric.auger at linaro.org (Eric Auger)
Date: Tue, 18 Aug 2015 10:26:08 +0200
Subject: [PATCH v2 4/4] irqchip: GIC: Don't deactivate interrupts forwarded
 to a guest
In-Reply-To: <1439454526-1185-5-git-send-email-marc.zyngier@arm.com>
References: <1439454526-1185-1-git-send-email-marc.zyngier@arm.com>
 <1439454526-1185-5-git-send-email-marc.zyngier@arm.com>
Message-ID: <55D2EC20.9020304@linaro.org>

Hi Marc,
On 08/13/2015 10:28 AM, Marc Zyngier wrote:
> Commit 0a4377de3056 ("genirq: Introduce irq_set_vcpu_affinity() to
> target an interrupt to a VCPU") added just what we needed at the
> lowest level to allow an interrupt to be deactivated by a guest.
> 
> When such a request reaches the GIC, it knows it doesn't need to
> perform the deactivation anymore, and can safely leave the guest
> do its magic. This of course requires additional support in both
> VFIO and KVM.
> 
> Signed-off-by: Marc Zyngier <marc.zyngier at arm.com>
> ---
>  drivers/irqchip/irq-gic.c | 58 +++++++++++++++++++++++++++++++++++++++++++++++
>  1 file changed, 58 insertions(+)
> 
> diff --git a/drivers/irqchip/irq-gic.c b/drivers/irqchip/irq-gic.c
> index b020c3a..ea691be 100644
> --- a/drivers/irqchip/irq-gic.c
> +++ b/drivers/irqchip/irq-gic.c
> @@ -148,6 +148,34 @@ static inline bool primary_gic_irq(struct irq_data *d)
>  	return true;
>  }
>  
> +static inline bool cascading_gic_irq(struct irq_data *d)
> +{
> +	/*
> +	 * If handler_data pointing to one of the secondary GICs, then
> +	 * this is the cascading interrupt, and it cannot possibly be
a cascading interrupt?
> +	 * forwarded.
> +	 */
> +	if (d->handler_data >= (void *)(gic_data + 1) &&
> +	    d->handler_data <  (void *)(gic_data + MAX_GIC_NR))
there is an accessor for d->handler_data: irq_data_get_irq_handler_data

besides:
Reviewed-by: Eric Auger <eric.auger at linaro.org>
Tested-by: Eric Auger <eric.auger at linaro.org> on Calxeda Midway with
VFIO SPI assignment

Best Regards

Eric


> +		return true;
> +
> +	return false;
> +}
> +
> +static inline bool forwarded_irq(struct irq_data *d)
> +{
> +	/*
> +	 * A forwarded interrupt:
> +	 * - is on the primary GIC
> +	 * - has its handler_data set to a value
> +	 * - that isn't a secondary GIC
> +	 */
> +	if (primary_gic_irq(d) && d->handler_data && !cascading_gic_irq(d))
> +		return true;
> +
> +	return false;
> +}
> +
>  /*
>   * Routines to acknowledge, disable and enable interrupts
>   */
> @@ -166,6 +194,18 @@ static int gic_peek_irq(struct irq_data *d, u32 offset)
>  static void gic_mask_irq(struct irq_data *d)
>  {
>  	gic_poke_irq(d, GIC_DIST_ENABLE_CLEAR);
> +	/*
> +	 * When masking a forwarded interrupt, make sure it is
> +	 * deactivated as well.
> +	 *
> +	 * This ensures that an interrupt that is getting
> +	 * disabled/masked will not get "stuck", because there is
> +	 * noone to deactivate it (guest is being terminated).
> +	 */
> +	if (static_key_true(&supports_deactivate)) {
> +		if (forwarded_irq(d))
> +			gic_poke_irq(d, GIC_DIST_ACTIVE_CLEAR);
> +	}
>  }
>  
>  static void gic_unmask_irq(struct irq_data *d)
> @@ -178,6 +218,10 @@ static void gic_eoi_irq(struct irq_data *d)
>  	u32 deact_offset = GIC_CPU_EOI;
>  
>  	if (static_key_true(&supports_deactivate)) {
> +		/* Do not deactivate an IRQ forwarded to a vcpu. */
> +		if (forwarded_irq(d))
> +			return;
> +
>  		if (primary_gic_irq(d))
>  			deact_offset = GIC_CPU_DEACTIVATE;
>  	}
> @@ -251,6 +295,19 @@ static int gic_set_type(struct irq_data *d, unsigned int type)
>  	return gic_configure_irq(gicirq, type, base, NULL);
>  }
>  
> +static int gic_irq_set_vcpu_affinity(struct irq_data *d, void *vcpu)
> +{
> +	/* Only interrupts on the primary GIC can be forwarded to a vcpu. */
> +	if (static_key_true(&supports_deactivate)) {
> +		if (primary_gic_irq(d) && !cascading_gic_irq(d)) {
> +			d->handler_data = vcpu;
> +			return 0;
> +		}
> +	}
> +
> +	return -EINVAL;
> +}
> +
>  #ifdef CONFIG_SMP
>  static int gic_set_affinity(struct irq_data *d, const struct cpumask *mask_val,
>  			    bool force)
> @@ -346,6 +403,7 @@ static struct irq_chip gic_chip = {
>  #endif
>  	.irq_get_irqchip_state	= gic_irq_get_irqchip_state,
>  	.irq_set_irqchip_state	= gic_irq_set_irqchip_state,
> +	.irq_set_vcpu_affinity	= gic_irq_set_vcpu_affinity,
>  	.flags			= IRQCHIP_SET_TYPE_MASKED,
>  };
>  
> 



From l.stach at pengutronix.de  Tue Aug 18 01:28:20 2015
From: l.stach at pengutronix.de (Lucas Stach)
Date: Tue, 18 Aug 2015 10:28:20 +0200
Subject: [PATCH] ARM: keystone: add a work around to handle asynchronous
 external abort
In-Reply-To: <20150818081334.GK7557@n2100.arm.linux.org.uk>
References: <1439320409-20084-1-git-send-email-m-karicheri2@ti.com>
 <55CDF579.4050408@ti.com> <20150814140934.GX7557@n2100.arm.linux.org.uk>
 <55CE05EC.4040909@oracle.com> <55CE633C.10402@ti.com>
 <20150814215617.GA7557@n2100.arm.linux.org.uk> <55D25C64.3090107@ti.com>
 <55D2A1DD.9000007@oracle.com>
 <20150818081334.GK7557@n2100.arm.linux.org.uk>
Message-ID: <1439886500.31432.4.camel@pengutronix.de>

Am Dienstag, den 18.08.2015, 09:13 +0100 schrieb Russell King - ARM
Linux:
> On Mon, Aug 17, 2015 at 08:09:17PM -0700, santosh.shilimkar at oracle.com wrote:
> > From the logs this seems to be mostly clock related issue for some
> > peripheral. If the bootloader clock enable all hack still exists,
> > may be you can try that out.
> > 
> > Another way to debug this is to start disabling peripheral drivers
> > from the kernel 1 by 1 and see if the issue goes away.
> 
> Highly unlikely to make any difference.  As the failure happens soo early
> with the patch applied, the kernel hasn't had much of a chance to touch
> the hardware - about the only things are the decompressor and the kernel
> touching the early console.  As they seem to be working, it suggests
> that's not the cause.
> 
> It seems to be pointing towards something in the boot loader...
> 
> Normally, uboot will hook itself into the vectors to report errors, but
> I wonder whether uboot enables asynchronous aborts while it's running.
> Don't forget to make sure that the aborts are disabled again prior to
> calling the kernel.
> 
At least one of the Marvell platforms has the same issue with the
bootloader (I think it is some downstream U-Boot) leaving an imprecise
abort hanging around as a nice present for Linux to crash on.

If it turns out to be the same issue the only kernel level workaround
would be to ignore exactly 1 abort after bootup.

Then we still need a solution for the platform and the PCIe driver abort
handler both hooking into the same abort vector, which won't work
currently.

Regards,
Lucas
-- 
Pengutronix e.K.             | Lucas Stach                 |
Industrial Linux Solutions   | http://www.pengutronix.de/  |



From jszhang at marvell.com  Tue Aug 18 01:28:58 2015
From: jszhang at marvell.com (Jisheng Zhang)
Date: Tue, 18 Aug 2015 16:28:58 +0800
Subject: [PATCH] ARM: keystone: add a work around to handle asynchronous
 external abort
In-Reply-To: <20150818081334.GK7557@n2100.arm.linux.org.uk>
References: <1439320409-20084-1-git-send-email-m-karicheri2@ti.com>
 <55CDF579.4050408@ti.com>	<20150814140934.GX7557@n2100.arm.linux.org.uk>
 <55CE05EC.4040909@oracle.com>	<55CE633C.10402@ti.com>
 <20150814215617.GA7557@n2100.arm.linux.org.uk>	<55D25C64.3090107@ti.com>
 <55D2A1DD.9000007@oracle.com>	<20150818081334.GK7557@n2100.arm.linux.org.uk>
Message-ID: <20150818162858.42035da0@xhacker>

On Tue, 18 Aug 2015 09:13:34 +0100
Russell King - ARM Linux <linux at arm.linux.org.uk> wrote:

> On Mon, Aug 17, 2015 at 08:09:17PM -0700, santosh.shilimkar at oracle.com wrote:
> > From the logs this seems to be mostly clock related issue for some
> > peripheral. If the bootloader clock enable all hack still exists,
> > may be you can try that out.
> > 
> > Another way to debug this is to start disabling peripheral drivers
> > from the kernel 1 by 1 and see if the issue goes away.
> 
> Highly unlikely to make any difference.  As the failure happens soo early
> with the patch applied, the kernel hasn't had much of a chance to touch
> the hardware - about the only things are the decompressor and the kernel
> touching the early console.  As they seem to be working, it suggests
> that's not the cause.
> 
> It seems to be pointing towards something in the boot loader...
> 
> Normally, uboot will hook itself into the vectors to report errors, but
> I wonder whether uboot enables asynchronous aborts while it's running.
> Don't forget to make sure that the aborts are disabled again prior to
> calling the kernel.
> 

Another possible cause: trustzone software.

we root caused such kind of asynchronous external abort on Marvell Berlin SoCs
to a trustzone bug. I'm not sure whether keystone linux is running at normal
world or not.


From will.deacon at arm.com  Tue Aug 18 01:56:26 2015
From: will.deacon at arm.com (Will Deacon)
Date: Tue, 18 Aug 2015 09:56:26 +0100
Subject: [PATCH V4 2/3] arm64: support initrd outside kernel linear map
In-Reply-To: <1439830867-14935-3-git-send-email-msalter@redhat.com>
References: <1439830867-14935-1-git-send-email-msalter@redhat.com>
 <1439830867-14935-3-git-send-email-msalter@redhat.com>
Message-ID: <20150818085626.GD10301@arm.com>

On Mon, Aug 17, 2015 at 06:01:06PM +0100, Mark Salter wrote:
> The use of mem= could leave part or all of the initrd outside of
> the kernel linear map. This will lead to an error when unpacking
> the initrd and a probable failure to boot. This patch catches that
> situation and relocates the initrd to be fully within the linear
> map.
> 
> Signed-off-by: Mark Salter <msalter at redhat.com>
> ---
>  arch/arm64/kernel/setup.c | 62 +++++++++++++++++++++++++++++++++++++++++++++++
>  1 file changed, 62 insertions(+)

Looks good to me:

  Acked-by: Will Deacon <will.deacon at arm.com>

This series should replace the version that Andrew has currently got in
linux-next.

Will

> diff --git a/arch/arm64/kernel/setup.c b/arch/arm64/kernel/setup.c
> index f3067d4..40a894e 100644
> --- a/arch/arm64/kernel/setup.c
> +++ b/arch/arm64/kernel/setup.c
> @@ -359,6 +359,67 @@ static void __init request_standard_resources(void)
>  	}
>  }
>  
> +#ifdef CONFIG_BLK_DEV_INITRD
> +/*
> + * Relocate initrd if it is not completely within the linear mapping.
> + * This would be the case if mem= cuts out all or part of it.
> + */
> +static void __init relocate_initrd(void)
> +{
> +	phys_addr_t orig_start = __virt_to_phys(initrd_start);
> +	phys_addr_t orig_end = __virt_to_phys(initrd_end);
> +	phys_addr_t ram_end = memblock_end_of_DRAM();
> +	phys_addr_t new_start;
> +	unsigned long size, to_free = 0;
> +	void *dest;
> +
> +	if (orig_end <= ram_end)
> +		return;
> +
> +	/*
> +	 * Any of the original initrd which overlaps the linear map should
> +	 * be freed after relocating.
> +	 */
> +	if (orig_start < ram_end)
> +		to_free = ram_end - orig_start;
> +
> +	size = orig_end - orig_start;
> +
> +	/* initrd needs to be relocated completely inside linear mapping */
> +	new_start = memblock_find_in_range(0, PFN_PHYS(max_pfn),
> +					   size, PAGE_SIZE);
> +	if (!new_start)
> +		panic("Cannot relocate initrd of size %ld\n", size);
> +	memblock_reserve(new_start, size);
> +
> +	initrd_start = __phys_to_virt(new_start);
> +	initrd_end   = initrd_start + size;
> +
> +	pr_info("Moving initrd from [%llx-%llx] to [%llx-%llx]\n",
> +		orig_start, orig_start + size - 1,
> +		new_start, new_start + size - 1);
> +
> +	dest = (void *)initrd_start;
> +
> +	if (to_free) {
> +		memcpy(dest, (void *)__phys_to_virt(orig_start), to_free);
> +		dest += to_free;
> +	}
> +
> +	copy_from_early_mem(dest, orig_start + to_free, size - to_free);
> +
> +	if (to_free) {
> +		pr_info("Freeing original RAMDISK from [%llx-%llx]\n",
> +			orig_start, orig_start + to_free - 1);
> +		memblock_free(orig_start, to_free);
> +	}
> +}
> +#else
> +static inline void __init relocate_initrd(void)
> +{
> +}
> +#endif
> +
>  u64 __cpu_logical_map[NR_CPUS] = { [0 ... NR_CPUS-1] = INVALID_HWID };
>  
>  void __init setup_arch(char **cmdline_p)
> @@ -392,6 +453,7 @@ void __init setup_arch(char **cmdline_p)
>  	acpi_boot_table_init();
>  
>  	paging_init();
> +	relocate_initrd();
>  	request_standard_resources();
>  
>  	early_ioremap_reset();
> -- 
> 2.4.3
> 


From alexandre.belloni at free-electrons.com  Tue Aug 18 02:21:52 2015
From: alexandre.belloni at free-electrons.com (Alexandre Belloni)
Date: Tue, 18 Aug 2015 11:21:52 +0200
Subject: [PATCH] rtc: armada38x: Align RTC set time procedure with the
 official errata
In-Reply-To: <1438874328-31844-1-git-send-email-gregory.clement@free-electrons.com>
References: <1438874328-31844-1-git-send-email-gregory.clement@free-electrons.com>
Message-ID: <20150818092152.GV22269@piout.net>

On 06/08/2015 at 17:18:48 +0200, Gregory CLEMENT wrote :
> From: Nadav Haklai <nadavh at marvell.com>
> 
> According to the Armada38x functional errata FE-3124064, writing to
> the RTC TIME register may fail. As a workaround, after writing to RTC
> TIME register, issue a dummy write of 0x0 twice to the RTC Status
> register.  This is the updated implementation of the Errata that
> eliminates the need of the long 100ms delay during the RTC set time
> procedure.
> 
> [gregory.clement at free-electrons.com]: removed the mutex and use the
> spinlock again
> 
> Signed-off-by: Nadav Haklai <nadavh at marvell.com>
> Reviewed-by: Neta Zur Hershkovits <neta at marvell.com>
> Signed-off-by: Gregory CLEMENT <gregory.clement at free-electrons.com>
Applied, thanks.

-- 
Alexandre Belloni, Free Electrons
Embedded Linux, Kernel and Android engineering
http://free-electrons.com


From boris.brezillon at free-electrons.com  Tue Aug 18 02:26:55 2015
From: boris.brezillon at free-electrons.com (Boris Brezillon)
Date: Tue, 18 Aug 2015 11:26:55 +0200
Subject: [PULL] drm: atmel-hlcdc: new features for 4.3 or 4.4
Message-ID: <20150818112655.26143418@bbrezillon>

Hello Dave,

The following PR add support for 3 more atmel SoCs and for some missing
features (new input formats and PRIME support).

As for the other PR I just sent, ideally I would like to get those new
features into 4.3 but since we're already at 4.1-rc7 I'll let you decide
whether this should be queued for the next release or not.

Best Regards,

Boris

The following changes since commit 294947a5c7f6d228b70fcc51a89527e74a38a2c5:

  Merge branch 'vmwgfx-next' of git://people.freedesktop.org/~thomash/linux into drm-next (2015-08-17 16:03:48 +1000)

are available in the git repository at:


  https://github.com/bbrezillon/linux-at91.git drm-atmel-hlcdc-devel

for you to fetch changes up to 5b9fb5e6c6c74666f88f34bd0db183b9c4269d97:

  drm: atmel-hlcdc: add support for sama5d4 SoCs (2015-08-18 11:02:27 +0200)

----------------------------------------------------------------
Boris Brezillon (6):
      drm: atmel-hlcdc: add PRIME support
      drm: atmel-hlcdc: add the missing DRM_ATOMIC flag
      drm: atmel-hlcdc: add RGB565 and RGB444 output support
      drm: atmel-hlcdc: add support for at91sam9x5 SoCs
      drm: atmel-hlcdc: add support for at91sam9n12 SoC
      drm: atmel-hlcdc: add support for sama5d4 SoCs

 drivers/gpu/drm/atmel-hlcdc/atmel_hlcdc_dc.c     | 216 +++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++-
 drivers/gpu/drm/atmel-hlcdc/atmel_hlcdc_output.c |   4 ++++
 2 files changed, 219 insertions(+), 1 deletion(-)


From joro at 8bytes.org  Tue Aug 18 02:28:40 2015
From: joro at 8bytes.org (Joerg Roedel)
Date: Tue, 18 Aug 2015 11:28:40 +0200
Subject: [PATCH] iommu/io-pgtable-arm: Unmap and free table when
 overwriting with block
In-Reply-To: <1439308112-29758-1-git-send-email-will.deacon@arm.com>
References: <1439308112-29758-1-git-send-email-will.deacon@arm.com>
Message-ID: <20150818092840.GA26556@8bytes.org>

On Tue, Aug 11, 2015 at 04:48:32PM +0100, Will Deacon wrote:
> Joerg, could you queue this up for 4.3 please? It's a fix, but it's late
> in the day for 4.2 and doesn't backport cleanly. Merging it with the Cc
> stable tag is probably the easiest thing to do, then I can fix up the
> conflicts as they arise.

Applied, thanks Will.



From ard.biesheuvel at linaro.org  Tue Aug 18 02:34:40 2015
From: ard.biesheuvel at linaro.org (Ard Biesheuvel)
Date: Tue, 18 Aug 2015 11:34:40 +0200
Subject: [PATCH 0/2] arm64: ignore memory outside of the linear range
Message-ID: <1439890482-20798-1-git-send-email-ard.biesheuvel@linaro.org>

This is a followup to the single patch I posted on Aug 15th to ignore
RAM that cannot be covered by the linear mapping. Instead of clipping
the memory after the fact, this clips the memory before installing the
regions into the memblock memory table.

This is basically the approach that Mark Rutland suggested here

http://article.gmane.org/gmane.linux.ports.arm.kernel/430239

but modified to correctly consider the base of the kernel image as the
start of the linear mapping.

Ard Biesheuvel (2):
  of/fdt: make memblock maximum physical address arch configurable
  arm64: set MAX_MEMBLOCK_ADDR according to linear region size

 arch/arm64/include/asm/memory.h |  8 ++++++++
 drivers/of/fdt.c                | 12 +++++++-----
 2 files changed, 15 insertions(+), 5 deletions(-)

-- 
1.9.1



From ard.biesheuvel at linaro.org  Tue Aug 18 02:34:41 2015
From: ard.biesheuvel at linaro.org (Ard Biesheuvel)
Date: Tue, 18 Aug 2015 11:34:41 +0200
Subject: [PATCH 1/2] of/fdt: make memblock maximum physical address arch
 configurable
In-Reply-To: <1439890482-20798-1-git-send-email-ard.biesheuvel@linaro.org>
References: <1439890482-20798-1-git-send-email-ard.biesheuvel@linaro.org>
Message-ID: <1439890482-20798-2-git-send-email-ard.biesheuvel@linaro.org>

When parsing the memory nodes to populate the memblock memory
table, we check against high and low limits and clip any memory
that exceeds either one of them.

However, for arm64, the high limit of (phys_addr_t)~0 is not very
meaningful, since phys_addr_t is 64 bits (i.e., no limit) but there
may be other constraints that limit the memory ranges that we can
support.

So rename MAX_PHYS_ADDR to MAX_MEMBLOCK_ADDR (for clarity) and only
define it if the arch does not supply a definition of its own.

Signed-off-by: Ard Biesheuvel <ard.biesheuvel at linaro.org>
---
 drivers/of/fdt.c | 12 +++++++-----
 1 file changed, 7 insertions(+), 5 deletions(-)

diff --git a/drivers/of/fdt.c b/drivers/of/fdt.c
index 07496560e5b9..6e82bc42373b 100644
--- a/drivers/of/fdt.c
+++ b/drivers/of/fdt.c
@@ -967,7 +967,9 @@ int __init early_init_dt_scan_chosen(unsigned long node, const char *uname,
 }
 
 #ifdef CONFIG_HAVE_MEMBLOCK
-#define MAX_PHYS_ADDR	((phys_addr_t)~0)
+#ifndef MAX_MEMBLOCK_ADDR
+#define MAX_MEMBLOCK_ADDR	((phys_addr_t)~0)
+#endif
 
 void __init __weak early_init_dt_add_memory_arch(u64 base, u64 size)
 {
@@ -984,16 +986,16 @@ void __init __weak early_init_dt_add_memory_arch(u64 base, u64 size)
 	}
 	size &= PAGE_MASK;
 
-	if (base > MAX_PHYS_ADDR) {
+	if (base > MAX_MEMBLOCK_ADDR) {
 		pr_warning("Ignoring memory block 0x%llx - 0x%llx\n",
 				base, base + size);
 		return;
 	}
 
-	if (base + size - 1 > MAX_PHYS_ADDR) {
+	if (base + size - 1 > MAX_MEMBLOCK_ADDR) {
 		pr_warning("Ignoring memory range 0x%llx - 0x%llx\n",
-				((u64)MAX_PHYS_ADDR) + 1, base + size);
-		size = MAX_PHYS_ADDR - base + 1;
+				((u64)MAX_MEMBLOCK_ADDR) + 1, base + size);
+		size = MAX_MEMBLOCK_ADDR - base + 1;
 	}
 
 	if (base + size < phys_offset) {
-- 
1.9.1



From ard.biesheuvel at linaro.org  Tue Aug 18 02:34:42 2015
From: ard.biesheuvel at linaro.org (Ard Biesheuvel)
Date: Tue, 18 Aug 2015 11:34:42 +0200
Subject: [PATCH 2/2] arm64: set MAX_MEMBLOCK_ADDR according to linear region
 size
In-Reply-To: <1439890482-20798-1-git-send-email-ard.biesheuvel@linaro.org>
References: <1439890482-20798-1-git-send-email-ard.biesheuvel@linaro.org>
Message-ID: <1439890482-20798-3-git-send-email-ard.biesheuvel@linaro.org>

The linear region size of a 39-bit VA kernel is only 256 GB, which
may be insufficient to cover all of system RAM, even on platforms
that have much less than 256 GB of memory but which is laid out
very sparsely.

So make sure we clip the memory we will not be able to map before
installing it into the memblock memory table, by setting
MAX_MEMBLOCK_ADDR accordingly.

Signed-off-by: Ard Biesheuvel <ard.biesheuvel at linaro.org>
---
 arch/arm64/include/asm/memory.h | 8 ++++++++
 1 file changed, 8 insertions(+)

diff --git a/arch/arm64/include/asm/memory.h b/arch/arm64/include/asm/memory.h
index f800d45ea226..44a59c20e773 100644
--- a/arch/arm64/include/asm/memory.h
+++ b/arch/arm64/include/asm/memory.h
@@ -114,6 +114,14 @@ extern phys_addr_t		memstart_addr;
 #define PHYS_OFFSET		({ memstart_addr; })
 
 /*
+ * The maximum physical address that the linear direct mapping
+ * of system RAM can cover. (PAGE_OFFSET can be interpreted as
+ * a 2's complement signed quantity and negated to derive the
+ * maximum size of the linear mapping.)
+ */
+#define MAX_MEMBLOCK_ADDR	({ memstart_addr - PAGE_OFFSET - 1; })
+
+/*
  * PFNs are used to describe any physical page; this means
  * PFN 0 == physical address 0.
  *
-- 
1.9.1



From will.deacon at arm.com  Tue Aug 18 02:38:18 2015
From: will.deacon at arm.com (Will Deacon)
Date: Tue, 18 Aug 2015 10:38:18 +0100
Subject: [PATCH v8 1/7] arm64: Add HAVE_REGS_AND_STACK_ACCESS_API feature
In-Reply-To: <55CC1410.1090900@linaro.org>
References: <1439254364-15362-1-git-send-email-dave.long@linaro.org>
 <1439254364-15362-2-git-send-email-dave.long@linaro.org>
 <20150811173121.GC29880@arm.com> <55CC1410.1090900@linaro.org>
Message-ID: <20150818093817.GE10301@arm.com>

Hi David,

On Thu, Aug 13, 2015 at 04:50:40AM +0100, David Long wrote:
> On 08/11/15 13:31, Will Deacon wrote:
> > On Tue, Aug 11, 2015 at 01:52:38AM +0100, David Long wrote:
> >> +	REG_OFFSET_NAME(x30),
> >
> > Does this interact badly with perf tools, which expect to pass "lr" for
> > x30? (see tools/perf/arch/arm64/include/perf_regs.h).
> >
> 
> Possibly, I can test that when I'm back from my short vacation this 
> week.  The lr/x30 thing seems to be a recurring issue.  Perhaps it is 
> best simply to add a reundant entry for x30 as "lr".  It's simple enough 
> to do, although just slightly ugly looking as it would have to be done 
> without a macro.  Would one ever use "x31" in place of "sp"?

No; "sp" should always be "sp". Let me know how you get on with perf. I
couldn't quite tie the two ends together, but it does look like it expects
"lr" to work.

Will


From m.szyprowski at samsung.com  Tue Aug 18 02:56:39 2015
From: m.szyprowski at samsung.com (Marek Szyprowski)
Date: Tue, 18 Aug 2015 11:56:39 +0200
Subject: [PATCH] ARM: multi_v7_defconfig: Enable DWC2 USB driver and USB
 ethernet gadget
Message-ID: <1439891799-15302-1-git-send-email-m.szyprowski@samsung.com>

DWC2 (s3c-hsotg) hardware module is available on many Exynos based boards,
so enable DWC2 driver as well as the most common USB Ethernet gadget.

Signed-off-by: Marek Szyprowski <m.szyprowski at samsung.com>
---
 arch/arm/configs/multi_v7_defconfig | 2 ++
 1 file changed, 2 insertions(+)

diff --git a/arch/arm/configs/multi_v7_defconfig b/arch/arm/configs/multi_v7_defconfig
index b2facab..d15f719 100644
--- a/arch/arm/configs/multi_v7_defconfig
+++ b/arch/arm/configs/multi_v7_defconfig
@@ -506,6 +506,7 @@ CONFIG_USB_R8A66597_HCD=m
 CONFIG_USB_RENESAS_USBHS=m
 CONFIG_USB_STORAGE=y
 CONFIG_USB_DWC3=y
+CONFIG_USB_DWC2=y
 CONFIG_USB_CHIPIDEA=y
 CONFIG_USB_CHIPIDEA_HOST=y
 CONFIG_AB8500_USB=y
@@ -517,6 +518,7 @@ CONFIG_USB_MXS_PHY=y
 CONFIG_USB_RCAR_PHY=m
 CONFIG_USB_GADGET=y
 CONFIG_USB_RENESAS_USBHS_UDC=m
+CONFIG_USB_ETH=y
 CONFIG_MMC=y
 CONFIG_MMC_BLOCK_MINORS=16
 CONFIG_MMC_ARMMMCI=y
-- 
1.9.2



From will.deacon at arm.com  Tue Aug 18 03:00:27 2015
From: will.deacon at arm.com (Will Deacon)
Date: Tue, 18 Aug 2015 11:00:27 +0100
Subject: [PATCH 2/2] arm64: set MAX_MEMBLOCK_ADDR according to linear
 region size
In-Reply-To: <1439890482-20798-3-git-send-email-ard.biesheuvel@linaro.org>
References: <1439890482-20798-1-git-send-email-ard.biesheuvel@linaro.org>
 <1439890482-20798-3-git-send-email-ard.biesheuvel@linaro.org>
Message-ID: <20150818100018.GA11021@arm.com>

On Tue, Aug 18, 2015 at 10:34:42AM +0100, Ard Biesheuvel wrote:
> The linear region size of a 39-bit VA kernel is only 256 GB, which
> may be insufficient to cover all of system RAM, even on platforms
> that have much less than 256 GB of memory but which is laid out
> very sparsely.
> 
> So make sure we clip the memory we will not be able to map before
> installing it into the memblock memory table, by setting
> MAX_MEMBLOCK_ADDR accordingly.
> 
> Signed-off-by: Ard Biesheuvel <ard.biesheuvel at linaro.org>
> ---
>  arch/arm64/include/asm/memory.h | 8 ++++++++
>  1 file changed, 8 insertions(+)
> 
> diff --git a/arch/arm64/include/asm/memory.h b/arch/arm64/include/asm/memory.h
> index f800d45ea226..44a59c20e773 100644
> --- a/arch/arm64/include/asm/memory.h
> +++ b/arch/arm64/include/asm/memory.h
> @@ -114,6 +114,14 @@ extern phys_addr_t		memstart_addr;
>  #define PHYS_OFFSET		({ memstart_addr; })
>  
>  /*
> + * The maximum physical address that the linear direct mapping
> + * of system RAM can cover. (PAGE_OFFSET can be interpreted as
> + * a 2's complement signed quantity and negated to derive the
> + * maximum size of the linear mapping.)
> + */
> +#define MAX_MEMBLOCK_ADDR	({ memstart_addr - PAGE_OFFSET - 1; })

If we initialised memory_limit to this value and changed early_mem to
use min (i.e. only restrict the limit further), would that avoid the
need to change the of code? It looks like PPC uses
memblock_enforce_memory_limit for similar reasons.

Will


From javier at osg.samsung.com  Tue Aug 18 03:04:03 2015
From: javier at osg.samsung.com (Javier Martinez Canillas)
Date: Tue, 18 Aug 2015 12:04:03 +0200
Subject: [PATCH] ARM: multi_v7_defconfig: Enable DWC2 USB driver and USB
 ethernet gadget
In-Reply-To: <1439891799-15302-1-git-send-email-m.szyprowski@samsung.com>
References: <1439891799-15302-1-git-send-email-m.szyprowski@samsung.com>
Message-ID: <55D30313.7080107@osg.samsung.com>

Hello Marek,

On 08/18/2015 11:56 AM, Marek Szyprowski wrote:
> DWC2 (s3c-hsotg) hardware module is available on many Exynos based boards,
> so enable DWC2 driver as well as the most common USB Ethernet gadget.
> 
> Signed-off-by: Marek Szyprowski <m.szyprowski at samsung.com>
> ---
>  arch/arm/configs/multi_v7_defconfig | 2 ++
>  1 file changed, 2 insertions(+)
> 
> diff --git a/arch/arm/configs/multi_v7_defconfig b/arch/arm/configs/multi_v7_defconfig
> index b2facab..d15f719 100644
> --- a/arch/arm/configs/multi_v7_defconfig
> +++ b/arch/arm/configs/multi_v7_defconfig
> @@ -506,6 +506,7 @@ CONFIG_USB_R8A66597_HCD=m
>  CONFIG_USB_RENESAS_USBHS=m
>  CONFIG_USB_STORAGE=y
>  CONFIG_USB_DWC3=y
> +CONFIG_USB_DWC2=y
>  CONFIG_USB_CHIPIDEA=y
>  CONFIG_USB_CHIPIDEA_HOST=y
>  CONFIG_AB8500_USB=y
> @@ -517,6 +518,7 @@ CONFIG_USB_MXS_PHY=y
>  CONFIG_USB_RCAR_PHY=m
>  CONFIG_USB_GADGET=y
>  CONFIG_USB_RENESAS_USBHS_UDC=m
> +CONFIG_USB_ETH=y
>  CONFIG_MMC=y
>  CONFIG_MMC_BLOCK_MINORS=16
>  CONFIG_MMC_ARMMMCI=y
> 

Both are tristate Kconfig symbols and the current multi_v7 policy is
to build as much as possible as a module.

Other than that the patch looks good to me. So if you change that:

Reviewed-by: Javier Martinez Canillas <javier at osg.samsung.com>

Best regards,
-- 
Javier Martinez Canillas
Open Source Group
Samsung Research America


From ard.biesheuvel at linaro.org  Tue Aug 18 03:04:27 2015
From: ard.biesheuvel at linaro.org (Ard Biesheuvel)
Date: Tue, 18 Aug 2015 12:04:27 +0200
Subject: [PATCH 2/2] arm64: set MAX_MEMBLOCK_ADDR according to linear
 region size
In-Reply-To: <20150818100018.GA11021@arm.com>
References: <1439890482-20798-1-git-send-email-ard.biesheuvel@linaro.org>
 <1439890482-20798-3-git-send-email-ard.biesheuvel@linaro.org>
 <20150818100018.GA11021@arm.com>
Message-ID: <CAKv+Gu-YDEKSrkSG2fywgrHBB3Hao+jodknmCAkFCWqG4OpXCA@mail.gmail.com>

On 18 August 2015 at 12:00, Will Deacon <will.deacon at arm.com> wrote:
> On Tue, Aug 18, 2015 at 10:34:42AM +0100, Ard Biesheuvel wrote:
>> The linear region size of a 39-bit VA kernel is only 256 GB, which
>> may be insufficient to cover all of system RAM, even on platforms
>> that have much less than 256 GB of memory but which is laid out
>> very sparsely.
>>
>> So make sure we clip the memory we will not be able to map before
>> installing it into the memblock memory table, by setting
>> MAX_MEMBLOCK_ADDR accordingly.
>>
>> Signed-off-by: Ard Biesheuvel <ard.biesheuvel at linaro.org>
>> ---
>>  arch/arm64/include/asm/memory.h | 8 ++++++++
>>  1 file changed, 8 insertions(+)
>>
>> diff --git a/arch/arm64/include/asm/memory.h b/arch/arm64/include/asm/memory.h
>> index f800d45ea226..44a59c20e773 100644
>> --- a/arch/arm64/include/asm/memory.h
>> +++ b/arch/arm64/include/asm/memory.h
>> @@ -114,6 +114,14 @@ extern phys_addr_t               memstart_addr;
>>  #define PHYS_OFFSET          ({ memstart_addr; })
>>
>>  /*
>> + * The maximum physical address that the linear direct mapping
>> + * of system RAM can cover. (PAGE_OFFSET can be interpreted as
>> + * a 2's complement signed quantity and negated to derive the
>> + * maximum size of the linear mapping.)
>> + */
>> +#define MAX_MEMBLOCK_ADDR    ({ memstart_addr - PAGE_OFFSET - 1; })
>
> If we initialised memory_limit to this value and changed early_mem to
> use min (i.e. only restrict the limit further), would that avoid the
> need to change the of code? It looks like PPC uses
> memblock_enforce_memory_limit for similar reasons.
>

Yes, that would be yet another way of doing things. But since Catalin
explicitly requested that both checks (i.e., bottom end and top end)
occur in the same place, and indicated his preference not to override
early_init_dt_add_memory_arch() if we can avoid it, the only way is to
hack it in there.

-- 
Ard.


From jonathanh at nvidia.com  Tue Aug 18 03:08:03 2015
From: jonathanh at nvidia.com (Jon Hunter)
Date: Tue, 18 Aug 2015 11:08:03 +0100
Subject: Tegra baseline test results for v4.2-rc6
Message-ID: <55D30403.2030702@nvidia.com>

Here are some basic Tegra test results for Linux v4.2-rc6.
Logs and other details at:

    https://nvtb.github.io//linux/test_v4.2-rc6/20150809133102/


Test summary
------------

Build: zImage:
    Pass: ( 2/ 2): multi_v7_defconfig, tegra_defconfig

Build: Image:
    Pass: ( 1/ 1): defconfig

Boot to userspace: defconfig:
    Pass: ( 1/ 1): qemu-vexpress64

Boot to userspace: multi_v7_defconfig:
    Pass: ( 4/ 4): tegra114-dalmore-a04, tegra124-jetson-tk1,
		   tegra20-trimslice, tegra30-beaver

Boot to userspace: tegra_defconfig:
    Pass: ( 4/ 4): tegra114-dalmore-a04, tegra124-jetson-tk1,
		   tegra20-trimslice, tegra30-beaver


vmlinux object size
(delta in bytes from test_v4.2-rc5 (74d33293e467df61de1b1d8b2fbe29e550dec33b)):
   text     data      bss    total  kernel
     -1        0        0       -1  defconfig
   +576        0        0     +576  multi_v7_defconfig
  +4431        0        0    +4431  tegra_defconfig


Boot-time memory difference
(delta in bytes from test_v4.2-rc5 (74d33293e467df61de1b1d8b2fbe29e550dec33b))
    avail    rsrvd     high    freed                board              kconfig                  dtb
        .        .        .        .      qemu-vexpress64            defconfig           __internal
        .        .        .        . tegra114-dalmore-a04   multi_v7_defconfig     tegra114-dalmore
      -8k       8k        .       4k tegra114-dalmore-a04      tegra_defconfig     tegra114-dalmore
        .        .        .        .  tegra124-jetson-tk1   multi_v7_defconfig  tegra124-jetson-tk1
      -8k       8k        .       4k  tegra124-jetson-tk1      tegra_defconfig  tegra124-jetson-tk1
        .        .        .        .    tegra20-trimslice   multi_v7_defconfig    tegra20-trimslice
      -8k       8k        .       4k    tegra20-trimslice      tegra_defconfig    tegra20-trimslice
        .        .        .        .       tegra30-beaver   multi_v7_defconfig       tegra30-beaver
      -8k       8k        .       4k       tegra30-beaver      tegra_defconfig       tegra30-beaver


From jonathanh at nvidia.com  Tue Aug 18 03:08:12 2015
From: jonathanh at nvidia.com (Jon Hunter)
Date: Tue, 18 Aug 2015 11:08:12 +0100
Subject: Tegra baseline test results for v4.2-rc7
Message-ID: <55D3040C.50006@nvidia.com>

Here are some basic Tegra test results for Linux v4.2-rc7.
Logs and other details at:

    https://nvtb.github.io//linux/test_v4.2-rc7/20150816170102/


Test summary
------------

Build: zImage:
    Pass: ( 2/ 2): multi_v7_defconfig, tegra_defconfig

Build: Image:
    Pass: ( 1/ 1): defconfig

Boot to userspace: defconfig:
    Pass: ( 1/ 1): qemu-vexpress64

Boot to userspace: multi_v7_defconfig:
    Pass: ( 4/ 4): tegra114-dalmore-a04, tegra124-jetson-tk1,
		   tegra20-trimslice, tegra30-beaver

Boot to userspace: tegra_defconfig:
    Pass: ( 4/ 4): tegra114-dalmore-a04, tegra124-jetson-tk1,
		   tegra20-trimslice, tegra30-beaver


vmlinux object size
(delta in bytes from test_v4.2-rc6 (f7644cbfcdf03528f0f450f3940c4985b2291f49)):
   text     data      bss    total  kernel
 -45431    -5144     -128   -50703  defconfig
   +512        0        0     +512  multi_v7_defconfig
   +444        0        0     +444  tegra_defconfig


Boot-time memory difference
(delta in bytes from test_v4.2-rc6 (f7644cbfcdf03528f0f450f3940c4985b2291f49))
    avail    rsrvd     high    freed                board              kconfig                  dtb
        .        .        .        .      qemu-vexpress64            defconfig           __internal
        .        .        .      -4k tegra114-dalmore-a04   multi_v7_defconfig     tegra114-dalmore
        .        .        .        . tegra114-dalmore-a04      tegra_defconfig     tegra114-dalmore
        .        .        .      -4k  tegra124-jetson-tk1   multi_v7_defconfig  tegra124-jetson-tk1
        .        .        .        .  tegra124-jetson-tk1      tegra_defconfig  tegra124-jetson-tk1
        .        .        .      -4k    tegra20-trimslice   multi_v7_defconfig    tegra20-trimslice
        .        .        .        .    tegra20-trimslice      tegra_defconfig    tegra20-trimslice
        .        .        .      -4k       tegra30-beaver   multi_v7_defconfig       tegra30-beaver
        .        .        .        .       tegra30-beaver      tegra_defconfig       tegra30-beaver


From b.zolnierkie at samsung.com  Tue Aug 18 03:09:54 2015
From: b.zolnierkie at samsung.com (Bartlomiej Zolnierkiewicz)
Date: Tue, 18 Aug 2015 12:09:54 +0200
Subject: [RESEND PATCH 2/3 v6] cpufreq: mediatek: Add MT8173 cpufreq driver
In-Reply-To: <1439803465-19683-3-git-send-email-pi-cheng.chen@linaro.org>
References: <1439803465-19683-1-git-send-email-pi-cheng.chen@linaro.org>
 <1439803465-19683-3-git-send-email-pi-cheng.chen@linaro.org>
Message-ID: <18468574.WHJNqYO5N4@amdc1976>


Hi,

On Monday, August 17, 2015 05:24:24 PM Pi-Cheng Chen wrote:
> Mediatek MT8173 is an ARMv8 based quad-core (2*Cortex-A53 and
> 2*Cortex-A72) SoC with duall clusters. For each cluster, two voltage
> inputs, Vproc and Vsram are supplied by two regulators. For the big
> cluster, two regulators come from different PMICs. In this case, when
> scaling voltage inputs of the cluster, the voltages of two regulator
> inputs need to be controlled by software explicitly under the SoC
> specific limitation:
> 
> 	100mV < Vsram - Vproc < 200mV
> 
> which is called 'voltage tracking' mechanism. And when scaling the
> frequency of cluster clock input, the input MUX need to be parented to
> another "intermediate" stable PLL first and reparented to the original
> PLL once the original PLL is stable at the target frequency. This patch
> implements those mechanisms to enable CPU DVFS support for Mediatek
> MT8173 SoC.
> 
> Signed-off-by: Pi-Cheng Chen <pi-cheng.chen at linaro.org>
> Acked-by: Viresh Kumar <viresh.kumar at linaro.org>
> ---
>  drivers/cpufreq/Kconfig.arm      |   7 +
>  drivers/cpufreq/Makefile         |   1 +
>  drivers/cpufreq/mt8173-cpufreq.c | 524 +++++++++++++++++++++++++++++++++++++++
>  3 files changed, 532 insertions(+)
>  create mode 100644 drivers/cpufreq/mt8173-cpufreq.c

[...]

> +static struct platform_driver mt8173_cpufreq_platdrv = {
> +	.driver = {
> +		.name	= "mt8173-cpufreq",
> +	},
> +	.probe		= mt8173_cpufreq_probe,
> +};
> +
> +static int mt8173_cpufreq_driver_init(void)
> +{
> +	struct platform_device *pdev;
> +	int err;
> +
> +	err = platform_driver_register(&mt8173_cpufreq_platdrv);
> +	if (err)
> +		return err;
> +
> +	/*
> +	 * Since there's no place to hold device registration code and no
> +	 * device tree based way to match cpufreq driver yet, both the driver
> +	 * and the device registration codes are put here to handle defer
> +	 * probing.
> +	 */
> +	pdev = platform_device_register_simple("mt8173-cpufreq", -1, NULL, 0);

This is not very friendly for multiplatform support
(mt8173_cpufreq_driver_init() can be called on other platforms,
i.e. Samsung Exynos7 one if ARCH_EXYNOS7 is also enabled in
the kernel config).

Why can't it be fixed with checking Device Tree with
of_machine_is_compatible("mediatek,mt8173")
(assuming that it can be used on arm64 like on arm32)?

> +	if (IS_ERR(pdev)) {
> +		pr_err("failed to register mtk-cpufreq platform device\n");
> +		return PTR_ERR(pdev);
> +	}
> +
> +	return 0;
> +}
> +device_initcall(mt8173_cpufreq_driver_init);

Best regards,
--
Bartlomiej Zolnierkiewicz
Samsung R&D Institute Poland
Samsung Electronics



From viresh.kumar at linaro.org  Tue Aug 18 03:24:28 2015
From: viresh.kumar at linaro.org (Viresh Kumar)
Date: Tue, 18 Aug 2015 15:54:28 +0530
Subject: [RESEND PATCH 2/3 v6] cpufreq: mediatek: Add MT8173 cpufreq driver
In-Reply-To: <18468574.WHJNqYO5N4@amdc1976>
References: <1439803465-19683-1-git-send-email-pi-cheng.chen@linaro.org>
 <1439803465-19683-3-git-send-email-pi-cheng.chen@linaro.org>
 <18468574.WHJNqYO5N4@amdc1976>
Message-ID: <20150818102428.GD31148@linux>

On 18-08-15, 12:09, Bartlomiej Zolnierkiewicz wrote:
> > +	pdev = platform_device_register_simple("mt8173-cpufreq", -1, NULL, 0);
> 
> This is not very friendly for multiplatform support
> (mt8173_cpufreq_driver_init() can be called on other platforms,
> i.e. Samsung Exynos7 one if ARCH_EXYNOS7 is also enabled in
> the kernel config).
> 
> Why can't it be fixed with checking Device Tree with
> of_machine_is_compatible("mediatek,mt8173")
> (assuming that it can be used on arm64 like on arm32)?

Because I asked him to remove that in v5 :( as I somehow had in mind
that this wouldn't even compile for other platforms.

@Pi-cheng: Please send v7 only for this patch and add the DT platform
check you were doing earlier. Sorry.

-- 
viresh


From j.anaszewski at samsung.com  Tue Aug 18 03:27:01 2015
From: j.anaszewski at samsung.com (Jacek Anaszewski)
Date: Tue, 18 Aug 2015 12:27:01 +0200
Subject: [PATCH v2 19/21] leds: leds-pasic3: Add support for PASIC3 LED
 controller
In-Reply-To: <55D25ADC.10703@tul.cz>
References: <cover.1439843482.git.petr.cvek@tul.cz> <55D25ADC.10703@tul.cz>
Message-ID: <55D30875.3090103@samsung.com>

Hi Petr,

On 08/18/2015 12:06 AM, Petr Cvek wrote:
> Add support for LEDs inside the PASIC3 chip.
>
> Signed-off-by: Petr Cvek <petr.cvek at tul.cz>
> ---
>   drivers/leds/Kconfig       |   9 ++
>   drivers/leds/Makefile      |   1 +
>   drivers/leds/leds-pasic3.c | 232 +++++++++++++++++++++++++++++++++++++++++++++
>   3 files changed, 242 insertions(+)
>   create mode 100644 drivers/leds/leds-pasic3.c
>
> diff --git a/drivers/leds/Kconfig b/drivers/leds/Kconfig
> index 9ad35f7..516ba65 100644
> --- a/drivers/leds/Kconfig
> +++ b/drivers/leds/Kconfig
> @@ -586,6 +586,15 @@ config LEDS_PM8941_WLED
>   	  This option enables support for the 'White' LED block
>   	  on Qualcomm PM8941 PMICs.
>
> +config LEDS_PASIC3
> +	tristate "LED support for the HTC Magician/Alpine PASIC3"
> +	depends on LEDS_CLASS
> +	depends on HTC_PASIC3
> +	select REGMAP
> +	help
> +	  This option enables support for the PASIC3 chip (different chip
> +	  than Compaq ASIC3).
> +
>   comment "LED Triggers"
>   source "drivers/leds/trigger/Kconfig"
>
> diff --git a/drivers/leds/Makefile b/drivers/leds/Makefile
> index 8d6a24a..b1c659c 100644
> --- a/drivers/leds/Makefile
> +++ b/drivers/leds/Makefile
> @@ -65,6 +65,7 @@ obj-$(CONFIG_LEDS_VERSATILE)		+= leds-versatile.o
>   obj-$(CONFIG_LEDS_MENF21BMC)		+= leds-menf21bmc.o
>   obj-$(CONFIG_LEDS_PM8941_WLED)		+= leds-pm8941-wled.o
>   obj-$(CONFIG_LEDS_KTD2692)		+= leds-ktd2692.o
> +obj-$(CONFIG_LEDS_PASIC3)		+= leds-pasic3.o
>
>   # LED SPI Drivers
>   obj-$(CONFIG_LEDS_DAC124S085)		+= leds-dac124s085.o
> diff --git a/drivers/leds/leds-pasic3.c b/drivers/leds/leds-pasic3.c
> new file mode 100644
> index 0000000..0f95230
> --- /dev/null
> +++ b/drivers/leds/leds-pasic3.c
> @@ -0,0 +1,232 @@
> +/*
> + * AIC3 (or PASIC3) LED driver for HTC Magician/Alpine/.. (not Compaq ASIC3)

s/AIC3/ASIC3/

I am a bit confused. What's the relation between ASIC3 and PASIC3?

> + *
> + * Copyright (c) 2015 Petr Cvek <petr.cvek at tul.cz>
> + *
> + * CLK to MS calculation based on leds-asic3.c
> + *
> + * 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.
> + *
> + */
> +
> +#include <linux/gpio.h>
> +#include <linux/kernel.h>
> +#include <linux/leds.h>
> +#include <linux/mfd/htc-pasic3.h>
> +#include <linux/module.h>
> +#include <linux/platform_device.h>
> +#include <linux/slab.h>
> +
> +/*
> + * 1 tick is around 62-63 ms, blinking settings (on+off):
> + *	Min: 1+1 ticks ~125ms
> + *	Max: 127+127 ticks ~15?875ms
> + * HW sometimes takes time to change (counter overflow after write?)
> + */
> +
> +#define MS_TO_CLK(ms)	DIV_ROUND_CLOSEST(((ms)*1024), 64000)
> +#define CLK_TO_MS(clk)	(((clk)*64000)/1024)
> +#define MAX_CLK		254		/* 127 + 127 (2x 7 bit reg) */
> +#define MAX_MS		CLK_TO_MS(MAX_CLK)
> +
> +spinlock_t lock;

Please move it to the struct pasic3_leds_data.

> +
> +static void brightness_set(struct led_classdev *cdev,
> +	enum led_brightness value)
> +{
> +	struct platform_device *pdev = to_platform_device(cdev->dev->parent);
> +	struct pasic3_led *led = dev_get_platdata(cdev->dev);
> +	struct pasic3_leds_pdata *pdata = dev_get_platdata(&pdev->dev);
> +	unsigned long flags;
> +	u8 val;
> +
> +	spin_lock_irqsave(&lock, flags);
> +
> +	if (value == LED_OFF) {
> +		val = pasic3_read_register(pdata->mfd_dev, PASIC3_CH_CONTROL);
> +		pasic3_write_register(pdata->mfd_dev, PASIC3_CH_CONTROL,
> +			val & ~(led->bit_blink_en | led->bit_force_on));
> +
> +		val = pasic3_read_register(pdata->mfd_dev, PASIC3_MASK_A);
> +		pasic3_write_register(pdata->mfd_dev, PASIC3_MASK_A,
> +			val & ~led->bit_mask);
> +
> +		if (pdata->power_gpio) {
> +			pdata->power_gpio_users--;

Now it is possible that power_gpio_users will have negative value.
You should check the value before decrementing it.

> +
> +			if (pdata->power_gpio_users == 0)
> +				gpio_set_value(pdata->power_gpio, 0);
> +		}
> +	} else {
> +		if (pdata->power_gpio) {
> +			pdata->power_gpio_users++;
> +
> +			if (pdata->power_gpio_users != 0)
> +				gpio_set_value(pdata->power_gpio, 1);
> +		}


Now you are setting power_gpio_users to 1 each time brightness is set,
whereas it should be set to 1 only if it was 0.

This could be changed to:

if (pdata->power_gpio_users == 0)
	gpio_set_value(pdata->power_gpio, 1);

pdata->power_gpio_users++;

> +
> +		val = pasic3_read_register(pdata->mfd_dev, PASIC3_CH_CONTROL);
> +		pasic3_write_register(pdata->mfd_dev, PASIC3_CH_CONTROL,
> +			val | led->bit_force_on);
> +	}
> +
> +	spin_unlock_irqrestore(&lock, flags);
> +}
> +
> +static int blink_set(struct led_classdev *cdev,
> +	unsigned long *delay_on, unsigned long *delay_off)
> +{
> +	struct platform_device *pdev = to_platform_device(cdev->dev->parent);
> +	struct pasic3_led *led = dev_get_platdata(cdev->dev);
> +	struct pasic3_leds_pdata *pdata = dev_get_platdata(&pdev->dev);
> +	unsigned long flags;
> +	u32 on, off;
> +	u8 val;
> +	if (*delay_on > MAX_MS || *delay_off > MAX_MS)
> +		return -EINVAL;
> +
> +	if (*delay_on == 0 && *delay_off == 0) {
> +		/* Choose sensible default delays */
> +		on = MS_TO_CLK(500);
> +		off = MS_TO_CLK(500);
> +	} else {
> +		on = MS_TO_CLK(*delay_on);
> +		off = MS_TO_CLK(*delay_off);
> +		if ((on + off) > MAX_CLK)
> +			return -EINVAL;
> +		/* Minimal on/off value must be 1 */
> +		on = on ? on : 1;
> +		off = off ? off : 1;
> +	}
> +
> +	spin_lock_irqsave(&lock, flags);

Shouldn't you check if also power_gpio state doesn't need to be altered
here?

> +
> +	pasic3_write_register(pdata->mfd_dev, led->reg_delay_on, on);
> +	pasic3_write_register(pdata->mfd_dev, led->reg_delay_off, off);
> +
> +	val = pasic3_read_register(pdata->mfd_dev, PASIC3_CH_CONTROL);
> +	pasic3_write_register(pdata->mfd_dev, PASIC3_CH_CONTROL,
> +		val | led->bit_blink_en);
> +
> +	spin_unlock_irqrestore(&lock, flags);
> +
> +	*delay_on = CLK_TO_MS(on);
> +	*delay_off = CLK_TO_MS(off);
> +
> +	return 0;
> +}
> +
> +static int pasic3_led_probe(struct platform_device *pdev)
> +{
> +	struct pasic3_leds_pdata *pdata = dev_get_platdata(&pdev->dev);
> +	struct led_classdev *cdev;
> +	int ret;
> +	int i;
> +
> +	if (!pdata) {
> +		dev_err(&pdev->dev, "no platform data\n");
> +		return -EINVAL;
> +	}
> +
> +	if (!pdata->leds) {
> +		dev_err(&pdev->dev, "no leds data\n");
> +		return -EINVAL;
> +	}
> +
> +	if (pdata->power_gpio) {
> +		pdata->power_gpio_users = 0;
> +
> +		ret = gpio_request(pdata->power_gpio,
> +			"Red-Blue LED Power");

Please use devm_gpio_request. Then you will not need pasic3_led_remove.

> +		if (ret < 0) {
> +			dev_warn(&pdev->dev, "failed to request power GPIO\n");
> +			goto err;
> +		}
> +	}
> +
> +	spin_lock_init(&lock);
> +
> +	cdev = devm_kzalloc(&pdev->dev,
> +		sizeof(struct led_classdev) * pdata->num_leds, GFP_KERNEL);
> +	if (!cdev) {
> +		ret = -ENOMEM;
> +		goto err;
> +	}
> +
> +	for (i = 0; i < pdata->num_leds; i++) {
> +		cdev[i].name = pdata->leds[i].name;
> +		cdev[i].default_trigger = pdata->leds[i].default_trigger;
> +		cdev[i].flags = LED_CORE_SUSPENDRESUME;
> +		cdev[i].brightness_set = brightness_set;
> +		cdev[i].blink_set = blink_set;
> +
> +		ret = devm_led_classdev_register(&pdev->dev, &cdev[i]);
> +		if (ret < 0)
> +			goto err;
> +
> +		cdev[i].dev->platform_data = &pdata->leds[i];
> +	}
> +
> +	return 0;
> +
> +err:
> +	if (pdata->power_gpio)
> +		gpio_free(pdata->power_gpio);
> +
> +	return ret;
> +}
> +
> +static int pasic3_led_remove(struct platform_device *pdev)
> +{
> +	struct pasic3_leds_pdata *pdata = dev_get_platdata(&pdev->dev);
> +
> +	if (pdata->power_gpio)
> +		gpio_free(pdata->power_gpio);
> +
> +	return 0;
> +}
> +
> +#ifdef CONFIG_PM_SLEEP
> +static int pasic3_led_suspend(struct device *dev)
> +{
> +	struct pasic3_leds_pdata *pdata = dev_get_platdata(dev);
> +
> +	if (pdata->power_gpio)
> +		gpio_set_value(pdata->power_gpio, 0);
> +
> +	return 0;
> +}
> +
> +static int pasic3_led_resume(struct device *dev)
> +{
> +	struct pasic3_leds_pdata *pdata = dev_get_platdata(dev);
> +
> +	if (pdata->power_gpio)
> +		gpio_set_value(pdata->power_gpio, 1);
> +
> +	return 0;
> +}
> +#endif
> +
> +static SIMPLE_DEV_PM_OPS(pasic3_led_pm_ops, pasic3_led_suspend,
> +	pasic3_led_resume);
> +
> +static struct platform_driver pasic3_led_driver = {
> +	.probe		= pasic3_led_probe,
> +	.remove		= pasic3_led_remove,
> +	.driver		= {
> +		.name	= "leds-pasic3",
> +		.pm	= &pasic3_led_pm_ops,
> +	},
> +};
> +
> +module_platform_driver(pasic3_led_driver);
> +
> +MODULE_AUTHOR("Petr Cvek <petr.cvek at tul.cz>");
> +MODULE_DESCRIPTION("HTC Magician PASIC3 LED driver");
> +MODULE_LICENSE("GPL");
> +MODULE_ALIAS("platform:leds-pasic3");
>


-- 
Best Regards,
Jacek Anaszewski


From andy.shevchenko at gmail.com  Tue Aug 18 03:29:27 2015
From: andy.shevchenko at gmail.com (Andy Shevchenko)
Date: Tue, 18 Aug 2015 13:29:27 +0300
Subject: [PATCH v2 0/2] spi: dw: Reintroduce optional 16 bit data register
 I/O
In-Reply-To: <20150727135915.GY11162@sirena.org.uk>
References: <1434703435-25198-1-git-send-email-michael@smart-africa.com>
 <1435163696-14767-1-git-send-email-michael@smart-africa.com>
 <1437751812.29746.74.camel@linux.intel.com>
 <20150724153704.GM11162@sirena.org.uk>
 <1437994691.29746.80.camel@linux.intel.com>
 <20150727111944.GW11162@sirena.org.uk>
 <CCC70BC0-E1D0-4C27-A44D-2D16ED9B3049@smart-africa.com>
 <20150727135915.GY11162@sirena.org.uk>
Message-ID: <CAHp75VduLt1q9upnXsBYwx4rwie67FiQ6jS7UoXb7uQT66821g@mail.gmail.com>

On Mon, Jul 27, 2015 at 4:59 PM, Mark Brown <broonie at kernel.org> wrote:
> On Mon, Jul 27, 2015 at 01:38:57PM +0200, Michael van der Westhuizen wrote:
>
>> > It's possible there was some discussion of the patch that made
>> > it look it needed a resubmit, or that it was buried as reply in the
>> > middle of discussion of some other patches (eg, a previous version).
>> > Either way to repeat what I said if you want me to review a patch please
>> > send me the patch.
>
>> I?ve just resent the series.
>
> You've sent them as a reply in the middle of another thread which is
> something I just indicated above was a bad idea in the message you're
> replying to here (it's a great way to either make it hard to figure out
> what the current version of the code is or get your message deleted
> along with the rest of the thread) and you've decided to label them as
> [RESEND instead of [PATCH :(

Michael, I believe you need to resend as a v3 in a separate thread if
you aware of this code.
(Though it seems already late for v4.3)

-- 
With Best Regards,
Andy Shevchenko


From andy.shevchenko at gmail.com  Tue Aug 18 03:36:09 2015
From: andy.shevchenko at gmail.com (Andy Shevchenko)
Date: Tue, 18 Aug 2015 13:36:09 +0300
Subject: [RESEND PATCH v2 2/2] spi: dw: Allow interface drivers to limit
 data I/O to word sizes
In-Reply-To: <1437997035-3046-3-git-send-email-michael@smart-africa.com>
References: <1435163696-14767-1-git-send-email-michael@smart-africa.com>
 <1437997035-3046-1-git-send-email-michael@smart-africa.com>
 <1437997035-3046-3-git-send-email-michael@smart-africa.com>
Message-ID: <CAHp75Ve4sQ+QM_oRvhqo=k7hoBRByFbB4eaU0j38KTZ6wVrLkw@mail.gmail.com>

On Mon, Jul 27, 2015 at 2:37 PM, Michael van der Westhuizen
<michael at smart-africa.com> wrote:
> The commit dd11444327ce ("spi: dw-spi: Convert 16bit accesses to 32bit
> accesses") changed all 16bit accesses in the DW_apb_ssi driver to 32bit.
> This, unfortunately, breaks data register access on picoXcell, where the
> DW IP needs data register accesses to be word accesses (all other
> accesses appear to be OK).
>
> This change introduces a new master variable to allow interface drivers
> to specify that 16bit data transfer I/O is required.  This change also
> introduces the ability to set this variable via device tree bindings in
> the MMIO interface driver.
>
> Before this change, on a picoXcell pc3x3:
>  spi_master spi32766: interrupt_transfer: fifo overrun/underrun
>  m25p80 spi32766.0: error -5 reading 9f
>  m25p80: probe of spi32766.0 failed with error -5
>
> After this change:
>  m25p80 spi32766.0: m25p40 (512 Kbytes)
>
> Fixes: dd11444327ce ("spi: dw-spi: Convert 16bit accesses to 32bit accesses")
> Signed-off-by: Michael van der Westhuizen <michael at smart-africa.com>
> Reviewed-by: Andy Shevchenko <andriy.shevchenko at linux.intel.com>

One minor comment below.

> ---
>
> Changes in v2:
>   - Incorporate review feedback from Andy Shevchenko
>     - Rework the DT bindings to accept an I/O register width as a
>       number of bytes rather than using a boolean spefifying the
>       width preference to be 16 bits.
>     - Add data register access wrapper functions and use them when
>       reading and writing the data register.
>
>  drivers/spi/spi-dw-mmio.c |  4 ++++
>  drivers/spi/spi-dw.c      |  4 ++--
>  drivers/spi/spi-dw.h      | 35 +++++++++++++++++++++++++++++++++++
>  3 files changed, 41 insertions(+), 2 deletions(-)
>
> diff --git a/drivers/spi/spi-dw-mmio.c b/drivers/spi/spi-dw-mmio.c
> index eb03e12..e76bf72 100644
> --- a/drivers/spi/spi-dw-mmio.c
> +++ b/drivers/spi/spi-dw-mmio.c
> @@ -74,6 +74,10 @@ static int dw_spi_mmio_probe(struct platform_device *pdev)
>
>         dws->max_freq = clk_get_rate(dwsmmio->clk);
>
> +       if (pdev->dev.of_node)

of_property_read_u32() is NULL-aware. Since the option is optional we
may drop the condition.

> +               of_property_read_u32(pdev->dev.of_node, "snps,reg-io-width",

Like Rob said, drop 'snps,' prefix as it is a generic property name.

> +                                    &dws->reg_io_width);
> +
>         num_cs = 4;
>
>         if (pdev->dev.of_node)
> diff --git a/drivers/spi/spi-dw.c b/drivers/spi/spi-dw.c
> index 8d67d03..4fbfcdc 100644
> --- a/drivers/spi/spi-dw.c
> +++ b/drivers/spi/spi-dw.c
> @@ -194,7 +194,7 @@ static void dw_writer(struct dw_spi *dws)
>                         else
>                                 txw = *(u16 *)(dws->tx);
>                 }
> -               dw_writel(dws, DW_SPI_DR, txw);
> +               dw_write_io_reg(dws, DW_SPI_DR, txw);
>                 dws->tx += dws->n_bytes;
>         }
>  }
> @@ -205,7 +205,7 @@ static void dw_reader(struct dw_spi *dws)
>         u16 rxw;
>
>         while (max--) {
> -               rxw = dw_readl(dws, DW_SPI_DR);
> +               rxw = dw_read_io_reg(dws, DW_SPI_DR);
>                 /* Care rx only if the transfer's original "rx" is not null */
>                 if (dws->rx_end - dws->len) {
>                         if (dws->n_bytes == 1)
> diff --git a/drivers/spi/spi-dw.h b/drivers/spi/spi-dw.h
> index 6c91391..b75ed32 100644
> --- a/drivers/spi/spi-dw.h
> +++ b/drivers/spi/spi-dw.h
> @@ -109,6 +109,7 @@ struct dw_spi {
>         u32                     fifo_len;       /* depth of the FIFO buffer */
>         u32                     max_freq;       /* max bus freq supported */
>
> +       u32                     reg_io_width;   /* DR I/O width in bytes */
>         u16                     bus_num;
>         u16                     num_cs;         /* supported slave numbers */
>
> @@ -145,11 +146,45 @@ static inline u32 dw_readl(struct dw_spi *dws, u32 offset)
>         return __raw_readl(dws->regs + offset);
>  }
>
> +static inline u16 dw_readw(struct dw_spi *dws, u32 offset)
> +{
> +       return __raw_readw(dws->regs + offset);
> +}
> +
>  static inline void dw_writel(struct dw_spi *dws, u32 offset, u32 val)
>  {
>         __raw_writel(val, dws->regs + offset);
>  }
>
> +static inline void dw_writew(struct dw_spi *dws, u32 offset, u16 val)
> +{
> +       __raw_writew(val, dws->regs + offset);
> +}
> +
> +static inline u32 dw_read_io_reg(struct dw_spi *dws, u32 offset)
> +{
> +       switch (dws->reg_io_width) {
> +       case 2:
> +               return dw_readw(dws, offset);
> +       case 4:
> +       default:
> +               return dw_readl(dws, offset);
> +       }
> +}
> +
> +static inline void dw_write_io_reg(struct dw_spi *dws, u32 offset, u32 val)
> +{
> +       switch (dws->reg_io_width) {
> +       case 2:
> +               dw_writew(dws, offset, val);
> +               break;
> +       case 4:
> +       default:
> +               dw_writel(dws, offset, val);
> +               break;
> +       }
> +}
> +
>  static inline void spi_enable_chip(struct dw_spi *dws, int enable)
>  {
>         dw_writel(dws, DW_SPI_SSIENR, (enable ? 1 : 0));
> --
> 2.1.4
>
> --
> To unsubscribe from this list: send the line "unsubscribe linux-spi" in
> the body of a message to majordomo at vger.kernel.org
> More majordomo info at  http://vger.kernel.org/majordomo-info.html



-- 
With Best Regards,
Andy Shevchenko


From linux at arm.linux.org.uk  Tue Aug 18 03:37:42 2015
From: linux at arm.linux.org.uk (Russell King - ARM Linux)
Date: Tue, 18 Aug 2015 11:37:42 +0100
Subject: [PATCH 00/12] dw-hdmi development
In-Reply-To: <20150810122135.GZ1262@ulmo.nvidia.com>
References: <20150808160251.GM7557@n2100.arm.linux.org.uk>
 <20150810122135.GZ1262@ulmo.nvidia.com>
Message-ID: <20150818103742.GN7557@n2100.arm.linux.org.uk>

On Mon, Aug 10, 2015 at 02:21:36PM +0200, Thierry Reding wrote:
> On Sat, Aug 08, 2015 at 05:02:51PM +0100, Russell King - ARM Linux wrote:
> > This sub-series is a mixture of development:
> > 
> > * Removing the incorrect pixel repetition configuration code
> > * Preventing pixel-doubled modes from being used
> > * Adding interlaced video support
> > * Implementing the sink_is_hdmi/sink_has_audio flags I suggested a few
> >   months ago
> > * Only enabling audio support if the sink indicates it has audio
> > * Avoiding double-enabling the HDMI interface
> > * Fixing the mis-leading name of "dw_hdmi_phy_enable_power"
> > * Adding connector mode forcing (important if your monitor bounces
> >   RXSENSE and HPD signals while in low-power mode.)
> > * Improving the HDMI enable/disabling on sink status
> > 
> > For review (and testing if people feel like it).  Acks/tested-bys etc
> > welcome.  It applies on top of my drm-dwhdmi-devel branch, which is
> > waiting for David Airlie to pull (see pull request on dri-devel, 15th
> > July.)
> 
> Hi Russell,
> 
> I have in the past merged patches for the bridge subdirectory via the
> drm/panel tree, though lately much of the dw-hdmi patches have gone in
> via Philipp or you directly. This seems to have worked fine so far, but
> this time around I carry a patch to clean up Kconfig and Makefile a
> little and bring more consistency to the subdirectory and I think it's
> going to conflict with your series here (and potentially any ongoing
> work you have).
> 
> Would you be open to me picking up these patches into the drm/panel
> tree? It feeds into linux-next, so the code would get some exposure
> before Dave's return.

I haven't seen any acks or comments on this set of 12 patches yet which
is rather disappointing.

David has now returned, and as David hasn't pulled stuff from the 15th,
my intention is to re-send that pull request, but with certain patches
from this set included in that - patches 1, 2, 6, 7, 8, 9 and 10.  I'll
also include Vladimir Zapolskiy's "fix register I2CM_ADDRESS register
name" patch in the set too.

None of that touches the Makefile or Kconfig, so there shouldn't be any
conflicts with your work.

-- 
FTTC broadband for 0.8mile line: currently at 10.5Mbps down 400kbps up
according to speedtest.net.


From mpe at ellerman.id.au  Tue Aug 18 03:43:30 2015
From: mpe at ellerman.id.au (Michael Ellerman)
Date: Tue, 18 Aug 2015 20:43:30 +1000 (AEST)
Subject: [v2,
 1/2] Move the pt_regs_offset struct definition from arch to common
 include file
In-Reply-To: <1437971974-2434-2-git-send-email-dave.long@linaro.org>
Message-ID: <20150818104330.B24DC14032B@ozlabs.org>

On Mon, 2015-27-07 at 04:39:33 UTC, "David A. Long" wrote:
> From: "David A. Long" <dave.long at linaro.org>
> 
> The pt_regs_offset structure is used for the HAVE_REGS_AND_STACK_ACCESS_API
> feature and has identical definitions in four different arch ptrace.h
> include files. It seems unlikely that definition would ever need to be
> changed regardless of architecture so lets move it into
> include/linux/ptrace.h, along with macros commonly used to access it.

Thanks for cleaning this up. Tested successfully on powerpc.

Acked-by: Michael Ellerman <mpe at ellerman.id.au>

cheers


From linux at arm.linux.org.uk  Tue Aug 18 03:44:58 2015
From: linux at arm.linux.org.uk (Russell King - ARM Linux)
Date: Tue, 18 Aug 2015 11:44:58 +0100
Subject: [PATCH v2] ARM: add boot image dependencies to not generate
 invalid images
In-Reply-To: <1439049211-4181-1-git-send-email-yamada.masahiro@socionext.com>
References: <1439049211-4181-1-git-send-email-yamada.masahiro@socionext.com>
Message-ID: <20150818104458.GO7557@n2100.arm.linux.org.uk>

On Sun, Aug 09, 2015 at 12:53:31AM +0900, Masahiro Yamada wrote:
> U-Boot is often used to boot the kernel on ARM boards, but uImage
> is not built by "make all", so we are often inclined to do
> "make all uImage" to generate DTBs, modules and uImage in a single
> command, but we should notice a pitfall behind it.  In fact,
> "make all uImage" could generate an invalid uImage if it is run with
> the parallel option (-j).

Please put this patch in the patch system.  Thanks.

-- 
FTTC broadband for 0.8mile line: currently at 10.5Mbps down 400kbps up
according to speedtest.net.


From leilk.liu at mediatek.com  Tue Aug 18 03:53:51 2015
From: leilk.liu at mediatek.com (Leilk Liu)
Date: Tue, 18 Aug 2015 18:53:51 +0800
Subject: [PATCH] spi: mediatek: fix spi incorrect endian usage and remove
 redundant clock
Message-ID: <1439895231-17778-1-git-send-email-leilk.liu@mediatek.com>

This patch fixes incorrect endian usage, removes redundant
clock in prepare_hardware/unprepare_hardware and revises
coding styles.

Signed-off-by: Leilk Liu <leilk.liu at mediatek.com>

---
Change in this patch:
1. fix incorrect endian usage on big-endian system.
2. delete redundant clock in prepare/unprepare_hardware.
3. revise coding styles.
---
 drivers/spi/spi-mt65xx.c                 | 163 +++++++++++++------------------
 include/linux/platform_data/spi-mt65xx.h |   2 -
 2 files changed, 69 insertions(+), 96 deletions(-)

diff --git a/drivers/spi/spi-mt65xx.c b/drivers/spi/spi-mt65xx.c
index 519f50c..a9da887 100644
--- a/drivers/spi/spi-mt65xx.c
+++ b/drivers/spi/spi-mt65xx.c
@@ -16,6 +16,7 @@
 #include <linux/device.h>
 #include <linux/err.h>
 #include <linux/interrupt.h>
+#include <linux/io.h>
 #include <linux/ioport.h>
 #include <linux/module.h>
 #include <linux/of.h>
@@ -48,15 +49,8 @@
 #define SPI_CFG1_PACKET_LOOP_MASK         0xff00
 #define SPI_CFG1_PACKET_LENGTH_MASK       0x3ff0000
 
-#define SPI_CMD_ACT_OFFSET                0
-#define SPI_CMD_RESUME_OFFSET             1
-#define SPI_CMD_CPHA_OFFSET               8
-#define SPI_CMD_CPOL_OFFSET               9
-#define SPI_CMD_TXMSBF_OFFSET             12
-#define SPI_CMD_RXMSBF_OFFSET             13
-#define SPI_CMD_RX_ENDIAN_OFFSET          14
-#define SPI_CMD_TX_ENDIAN_OFFSET          15
-
+#define SPI_CMD_ACT                  BIT(0)
+#define SPI_CMD_RESUME               BIT(1)
 #define SPI_CMD_RST                  BIT(2)
 #define SPI_CMD_PAUSE_EN             BIT(4)
 #define SPI_CMD_DEASSERT             BIT(5)
@@ -71,12 +65,10 @@
 #define SPI_CMD_FINISH_IE            BIT(16)
 #define SPI_CMD_PAUSE_IE             BIT(17)
 
-#define MTK_SPI_QUIRK_PAD_SELECT 1
-/* Must explicitly send dummy Tx bytes to do Rx only transfer */
-#define MTK_SPI_QUIRK_MUST_TX 1
-
 #define MT8173_SPI_MAX_PAD_SEL 3
 
+#define MTK_SPI_PAUSE_INT_STATUS 0x2
+
 #define MTK_SPI_IDLE 0
 #define MTK_SPI_PAUSED 1
 
@@ -84,8 +76,9 @@
 #define MTK_SPI_PACKET_SIZE 1024
 
 struct mtk_spi_compatible {
-	u32 need_pad_sel;
-	u32 must_tx;
+	bool need_pad_sel;
+	/* Must explicitly send dummy Tx bytes to do Rx only transfer */
+	bool must_tx;
 };
 
 struct mtk_spi {
@@ -100,19 +93,11 @@ struct mtk_spi {
 	const struct mtk_spi_compatible *dev_comp;
 };
 
-static const struct mtk_spi_compatible mt6589_compat = {
-	.need_pad_sel = 0,
-	.must_tx = 0,
-};
-
-static const struct mtk_spi_compatible mt8135_compat = {
-	.need_pad_sel = 0,
-	.must_tx = 0,
-};
-
+static const struct mtk_spi_compatible mt6589_compat;
+static const struct mtk_spi_compatible mt8135_compat;
 static const struct mtk_spi_compatible mt8173_compat = {
-	.need_pad_sel = MTK_SPI_QUIRK_PAD_SELECT,
-	.must_tx = MTK_SPI_QUIRK_MUST_TX,
+	.need_pad_sel = true,
+	.must_tx = true,
 };
 
 /*
@@ -122,8 +107,6 @@ static const struct mtk_spi_compatible mt8173_compat = {
 static const struct mtk_chip_config mtk_default_chip_info = {
 	.rx_mlsb = 1,
 	.tx_mlsb = 1,
-	.tx_endian = 0,
-	.rx_endian = 0,
 };
 
 static const struct of_device_id mtk_spi_of_match[] = {
@@ -156,14 +139,23 @@ static void mtk_spi_config(struct mtk_spi *mdata,
 	reg_val = readl(mdata->base + SPI_CMD_REG);
 
 	/* set the mlsbx and mlsbtx */
-	reg_val &= ~(SPI_CMD_TXMSBF | SPI_CMD_RXMSBF);
-	reg_val |= (chip_config->tx_mlsb << SPI_CMD_TXMSBF_OFFSET);
-	reg_val |= (chip_config->rx_mlsb << SPI_CMD_RXMSBF_OFFSET);
+	if (chip_config->tx_mlsb)
+		reg_val |= SPI_CMD_TXMSBF;
+	else
+		reg_val &= ~SPI_CMD_TXMSBF;
+	if (chip_config->rx_mlsb)
+		reg_val |= SPI_CMD_RXMSBF;
+	else
+		reg_val &= ~SPI_CMD_RXMSBF;
 
 	/* set the tx/rx endian */
-	reg_val &= ~(SPI_CMD_TX_ENDIAN | SPI_CMD_RX_ENDIAN);
-	reg_val |= (chip_config->tx_endian << SPI_CMD_TX_ENDIAN_OFFSET);
-	reg_val |= (chip_config->rx_endian << SPI_CMD_RX_ENDIAN_OFFSET);
+#ifdef __LITTLE_ENDIAN
+	reg_val &= ~SPI_CMD_TX_ENDIAN;
+	reg_val &= ~SPI_CMD_RX_ENDIAN;
+#else
+	reg_val |= SPI_CMD_TX_ENDIAN;
+	reg_val |= SPI_CMD_RX_ENDIAN;
+#endif
 
 	/* set finish and pause interrupt always enable */
 	reg_val |= SPI_CMD_FINISH_IE | SPI_CMD_PAUSE_EN;
@@ -186,30 +178,14 @@ static int mtk_spi_prepare_hardware(struct spi_master *master)
 	struct spi_transfer *trans;
 	struct mtk_spi *mdata = spi_master_get_devdata(master);
 	struct spi_message *msg = master->cur_msg;
-	int ret;
-
-	ret = clk_prepare_enable(mdata->spi_clk);
-	if (ret < 0) {
-		dev_err(&master->dev, "failed to enable clock (%d)\n", ret);
-		return ret;
-	}
 
 	trans = list_first_entry(&msg->transfers, struct spi_transfer,
 				 transfer_list);
-	if (trans->cs_change == 0) {
+	if (!trans->cs_change) {
 		mdata->state = MTK_SPI_IDLE;
 		mtk_spi_reset(mdata);
 	}
 
-	return ret;
-}
-
-static int mtk_spi_unprepare_hardware(struct spi_master *master)
-{
-	struct mtk_spi *mdata = spi_master_get_devdata(master);
-
-	clk_disable_unprepare(mdata->spi_clk);
-
 	return 0;
 }
 
@@ -226,9 +202,14 @@ static int mtk_spi_prepare_message(struct spi_master *master,
 	cpol = spi->mode & SPI_CPOL ? 1 : 0;
 
 	reg_val = readl(mdata->base + SPI_CMD_REG);
-	reg_val &= ~(SPI_CMD_CPHA | SPI_CMD_CPOL);
-	reg_val |= (cpha << SPI_CMD_CPHA_OFFSET);
-	reg_val |= (cpol << SPI_CMD_CPOL_OFFSET);
+	if (cpha)
+		reg_val |= SPI_CMD_CPHA;
+	else
+		reg_val &= ~SPI_CMD_CPHA;
+	if (cpol)
+		reg_val |= SPI_CMD_CPOL;
+	else
+		reg_val &= ~SPI_CMD_CPOL;
 	writel(reg_val, mdata->base + SPI_CMD_REG);
 
 	chip_config = spi->controller_data;
@@ -257,8 +238,7 @@ static void mtk_spi_set_cs(struct spi_device *spi, bool enable)
 static void mtk_spi_prepare_transfer(struct spi_master *master,
 				     struct spi_transfer *xfer)
 {
-	u32 spi_clk_hz, div, high_time, low_time, holdtime,
-	    setuptime, cs_idletime, reg_val = 0;
+	u32 spi_clk_hz, div, sck_time, cs_time, reg_val = 0;
 	struct mtk_spi *mdata = spi_master_get_devdata(master);
 
 	spi_clk_hz = clk_get_rate(mdata->spi_clk);
@@ -267,21 +247,18 @@ static void mtk_spi_prepare_transfer(struct spi_master *master,
 	else
 		div = 1;
 
-	high_time = (div + 1) / 2;
-	low_time = (div + 1) / 2;
-	holdtime = (div + 1) / 2 * 2;
-	setuptime = (div + 1) / 2 * 2;
-	cs_idletime = (div + 1) / 2 * 2;
+	sck_time = (div + 1) / 2;
+	cs_time = sck_time * 2;
 
-	reg_val |= (((high_time - 1) & 0xff) << SPI_CFG0_SCK_HIGH_OFFSET);
-	reg_val |= (((low_time - 1) & 0xff) << SPI_CFG0_SCK_LOW_OFFSET);
-	reg_val |= (((holdtime - 1) & 0xff) << SPI_CFG0_CS_HOLD_OFFSET);
-	reg_val |= (((setuptime - 1) & 0xff) << SPI_CFG0_CS_SETUP_OFFSET);
+	reg_val |= (((sck_time - 1) & 0xff) << SPI_CFG0_SCK_HIGH_OFFSET);
+	reg_val |= (((sck_time - 1) & 0xff) << SPI_CFG0_SCK_LOW_OFFSET);
+	reg_val |= (((cs_time - 1) & 0xff) << SPI_CFG0_CS_HOLD_OFFSET);
+	reg_val |= (((cs_time - 1) & 0xff) << SPI_CFG0_CS_SETUP_OFFSET);
 	writel(reg_val, mdata->base + SPI_CFG0_REG);
 
 	reg_val = readl(mdata->base + SPI_CFG1_REG);
 	reg_val &= ~SPI_CFG1_CS_IDLE_MASK;
-	reg_val |= (((cs_idletime - 1) & 0xff) << SPI_CFG1_CS_IDLE_OFFSET);
+	reg_val |= (((cs_time - 1) & 0xff) << SPI_CFG1_CS_IDLE_OFFSET);
 	writel(reg_val, mdata->base + SPI_CFG1_REG);
 }
 
@@ -290,11 +267,11 @@ static void mtk_spi_setup_packet(struct spi_master *master)
 	u32 packet_size, packet_loop, reg_val;
 	struct mtk_spi *mdata = spi_master_get_devdata(master);
 
-	packet_size = min_t(unsigned, mdata->xfer_len, MTK_SPI_PACKET_SIZE);
+	packet_size = min_t(u32, mdata->xfer_len, MTK_SPI_PACKET_SIZE);
 	packet_loop = mdata->xfer_len / packet_size;
 
 	reg_val = readl(mdata->base + SPI_CFG1_REG);
-	reg_val &= ~(SPI_CFG1_PACKET_LENGTH_MASK + SPI_CFG1_PACKET_LOOP_MASK);
+	reg_val &= ~(SPI_CFG1_PACKET_LENGTH_MASK | SPI_CFG1_PACKET_LOOP_MASK);
 	reg_val |= (packet_size - 1) << SPI_CFG1_PACKET_LENGTH_OFFSET;
 	reg_val |= (packet_loop - 1) << SPI_CFG1_PACKET_LOOP_OFFSET;
 	writel(reg_val, mdata->base + SPI_CFG1_REG);
@@ -302,20 +279,20 @@ static void mtk_spi_setup_packet(struct spi_master *master)
 
 static void mtk_spi_enable_transfer(struct spi_master *master)
 {
-	int cmd;
+	u32 cmd;
 	struct mtk_spi *mdata = spi_master_get_devdata(master);
 
 	cmd = readl(mdata->base + SPI_CMD_REG);
 	if (mdata->state == MTK_SPI_IDLE)
-		cmd |= 1 << SPI_CMD_ACT_OFFSET;
+		cmd |= SPI_CMD_ACT;
 	else
-		cmd |= 1 << SPI_CMD_RESUME_OFFSET;
+		cmd |= SPI_CMD_RESUME;
 	writel(cmd, mdata->base + SPI_CMD_REG);
 }
 
-static int mtk_spi_get_mult_delta(int xfer_len)
+static int mtk_spi_get_mult_delta(u32 xfer_len)
 {
-	int mult_delta;
+	u32 mult_delta;
 
 	if (xfer_len > MTK_SPI_PACKET_SIZE)
 		mult_delta = xfer_len % MTK_SPI_PACKET_SIZE;
@@ -368,7 +345,7 @@ static int mtk_spi_fifo_transfer(struct spi_master *master,
 				 struct spi_device *spi,
 				 struct spi_transfer *xfer)
 {
-	int cnt, i;
+	int cnt;
 	struct mtk_spi *mdata = spi_master_get_devdata(master);
 
 	mdata->cur_transfer = xfer;
@@ -380,10 +357,7 @@ static int mtk_spi_fifo_transfer(struct spi_master *master,
 		cnt = xfer->len / 4 + 1;
 	else
 		cnt = xfer->len / 4;
-
-	for (i = 0; i < cnt; i++)
-		writel(*((u32 *)xfer->tx_buf + i),
-		       mdata->base + SPI_TX_DATA_REG);
+	iowrite32_rep(mdata->base + SPI_TX_DATA_REG, xfer->tx_buf, cnt);
 
 	mtk_spi_enable_transfer(master);
 
@@ -453,30 +427,25 @@ static bool mtk_spi_can_dma(struct spi_master *master,
 
 static irqreturn_t mtk_spi_interrupt(int irq, void *dev_id)
 {
-	u32 cmd, reg_val, i;
+	u32 cmd, reg_val, cnt;
 	struct spi_master *master = dev_id;
 	struct mtk_spi *mdata = spi_master_get_devdata(master);
 	struct spi_transfer *trans = mdata->cur_transfer;
 
 	reg_val = readl(mdata->base + SPI_STATUS0_REG);
-	if (reg_val & 0x2)
+	if (reg_val & MTK_SPI_PAUSE_INT_STATUS)
 		mdata->state = MTK_SPI_PAUSED;
 	else
 		mdata->state = MTK_SPI_IDLE;
 
 	if (!master->can_dma(master, master->cur_msg->spi, trans)) {
-		/* xfer len is not N*4 bytes every time in a transfer,
-		 * but SPI_RX_DATA_REG must reads 4 bytes once,
-		 * so rx buffer byte by byte.
-		 */
 		if (trans->rx_buf) {
-			for (i = 0; i < mdata->xfer_len; i++) {
-				if (i % 4 == 0)
-					reg_val =
-					readl(mdata->base + SPI_RX_DATA_REG);
-				*((u8 *)(trans->rx_buf + i)) =
-					(reg_val >> ((i % 4) * 8)) & 0xff;
-			}
+			if (mdata->xfer_len % 4)
+				cnt = mdata->xfer_len / 4 + 1;
+			else
+				cnt = mdata->xfer_len / 4;
+			ioread32_rep(mdata->base + SPI_RX_DATA_REG,
+				     trans->rx_buf, cnt);
 		}
 		spi_finalize_current_transfer(master);
 		return IRQ_HANDLED;
@@ -541,7 +510,6 @@ static int mtk_spi_probe(struct platform_device *pdev)
 
 	master->set_cs = mtk_spi_set_cs;
 	master->prepare_transfer_hardware = mtk_spi_prepare_hardware;
-	master->unprepare_transfer_hardware = mtk_spi_unprepare_hardware;
 	master->prepare_message = mtk_spi_prepare_message;
 	master->transfer_one = mtk_spi_transfer_one;
 	master->can_dma = mtk_spi_can_dma;
@@ -694,6 +662,7 @@ static int mtk_spi_resume(struct device *dev)
 	if (!pm_runtime_suspended(dev)) {
 		ret = clk_prepare_enable(mdata->spi_clk);
 		if (ret < 0)
+			dev_err(dev, "failed to enable spi_clk (%d)\n", ret);
 			return ret;
 	}
 
@@ -720,8 +689,14 @@ static int mtk_spi_runtime_resume(struct device *dev)
 {
 	struct spi_master *master = dev_get_drvdata(dev);
 	struct mtk_spi *mdata = spi_master_get_devdata(master);
+	int ret;
+
+	ret = clk_prepare_enable(mdata->spi_clk);
+	if (ret < 0)
+		dev_err(dev, "failed to enable spi_clk (%d)\n", ret);
+		return ret;
 
-	return clk_prepare_enable(mdata->spi_clk);
+	return 0;
 }
 #endif /* CONFIG_PM */
 
diff --git a/include/linux/platform_data/spi-mt65xx.h b/include/linux/platform_data/spi-mt65xx.h
index 7512255..54b0448 100644
--- a/include/linux/platform_data/spi-mt65xx.h
+++ b/include/linux/platform_data/spi-mt65xx.h
@@ -16,7 +16,5 @@
 struct mtk_chip_config {
 	u32 tx_mlsb;
 	u32 rx_mlsb;
-	u32 tx_endian;
-	u32 rx_endian;
 };
 #endif
-- 
1.8.1.1.dirty



From yamada.masahiro at socionext.com  Tue Aug 18 03:54:31 2015
From: yamada.masahiro at socionext.com (Masahiro Yamada)
Date: Tue, 18 Aug 2015 19:54:31 +0900
Subject: [PATCH v2] ARM: add boot image dependencies to not generate
 invalid images
In-Reply-To: <20150818104458.GO7557@n2100.arm.linux.org.uk>
References: <1439049211-4181-1-git-send-email-yamada.masahiro@socionext.com>
 <20150818104458.GO7557@n2100.arm.linux.org.uk>
Message-ID: <CAK7LNAQ6kqoV_6zYA_6C-Gop8vbs66gsWDVZGrTong290Z_KWw@mail.gmail.com>

Hi Russell,


2015-08-18 19:44 GMT+09:00 Russell King - ARM Linux <linux at arm.linux.org.uk>:
> On Sun, Aug 09, 2015 at 12:53:31AM +0900, Masahiro Yamada wrote:
>> U-Boot is often used to boot the kernel on ARM boards, but uImage
>> is not built by "make all", so we are often inclined to do
>> "make all uImage" to generate DTBs, modules and uImage in a single
>> command, but we should notice a pitfall behind it.  In fact,
>> "make all uImage" could generate an invalid uImage if it is run with
>> the parallel option (-j).
>
> Please put this patch in the patch system.  Thanks.


I posted it yesterday.

ID: 8418/1



-- 
Best Regards
Masahiro Yamada


From antoine.tenart at free-electrons.com  Tue Aug 18 04:33:03 2015
From: antoine.tenart at free-electrons.com (Antoine Tenart)
Date: Tue, 18 Aug 2015 13:33:03 +0200
Subject: [PATCH v3 1/5] pwm: add the Berlin pwm controller driver
In-Reply-To: <55CB565C.8050906@gmail.com>
References: <1439387497-6863-1-git-send-email-antoine.tenart@free-electrons.com>
 <1439387497-6863-2-git-send-email-antoine.tenart@free-electrons.com>
 <55CB565C.8050906@gmail.com>
Message-ID: <20150818113303.GC3261@kwain>

Sebastian,

On Wed, Aug 12, 2015 at 04:21:16PM +0200, Sebastian Hesselbarth wrote:
> On 08/12/2015 03:51 PM, Antoine Tenart wrote:
> >Add a PWM controller driver for the Marvell Berlin SoCs. This PWM
> >controller has 4 channels.
> >
> >Signed-off-by: Antoine Tenart <antoine.tenart at free-electrons.com>
> 
> nice rework, but...
> 
> [...]
> >diff --git a/drivers/pwm/pwm-berlin.c b/drivers/pwm/pwm-berlin.c
> >new file mode 100644
> >index 000000000000..f89e25ea5c6d
> >--- /dev/null
> >+++ b/drivers/pwm/pwm-berlin.c
> >@@ -0,0 +1,227 @@
> [...]
> >+#define BERLIN_PWM_ENABLE		BIT(0)
> >+#define BERLIN_PWM_DISABLE		0x0
> 
> I'd drop BERLIN_PWM_DISABLE and use reg & ~BERLIN_PWM_ENABLE below.
> Even if there are no more writable bits in that register, IMHO it
> is good practice to affect as little bits as possible.

Sure.

> [...]
> >+/* prescaler table: {1, 4, 8, 16, 64, 256, 1024, 4096} */
> >+static const u32 prescaler_diff_table[] = {
> >+	1, 4, 2, 2, 4, 4, 4, 4,
> >+};
> >+
> >+static int berlin_pwm_config(struct pwm_chip *chip, struct pwm_device *pwm,
> >+			     int duty_ns, int period_ns)
> >+{
> >+	struct berlin_pwm_chip *berlin_chip = to_berlin_pwm_chip(chip);
> >+	int ret, prescale = 0;
> >+	u32 val, duty, period;
> >+	u64 cycles;
> >+
> >+	cycles = clk_get_rate(berlin_chip->clk);
> >+	cycles *= period_ns;
> >+	do_div(cycles, NSEC_PER_SEC);
> >+
> >+	while (cycles > BERLIN_PWM_MAX_TCNT)
> >+		do_div(cycles, prescaler_diff_table[++prescale]);
> >+
> >+	if (cycles > BERLIN_PWM_MAX_TCNT)
> >+		return -EINVAL;
> 
> Does my idea actually work? Did you test it with some different
> pwm frequencies?

I tested, and it worked well with different pwm frequencies!

> >+	period = cycles;
> >+	cycles *= duty_ns;
> >+	do_div(cycles, period_ns);
> >+	duty = cycles;
> >+
> >+	ret = clk_prepare_enable(berlin_chip->clk);
> >+	if (ret)
> >+		return ret;
> 
> Hmm. I understand that this may be required as the pwm framework
> calls .pwm_config before .pwm_enable, but...
> 
> >+
> >+	spin_lock(&berlin_chip->lock);
> >+
> >+	val = berlin_pwm_readl(berlin_chip, pwm->hwpwm, BERLIN_PWM_CONTROL);
> >+	val &= ~BERLIN_PWM_PRESCALE_MASK;
> >+	val |= prescale;
> >+	berlin_pwm_writel(val, berlin_chip, pwm->hwpwm, BERLIN_PWM_CONTROL);
> >+
> >+	berlin_pwm_writel(duty, berlin_chip, pwm->hwpwm, BERLIN_PWM_DUTY);
> >+	berlin_pwm_writel(period, berlin_chip, pwm->hwpwm, BERLIN_PWM_TCNT);
> >+
> >+	spin_unlock(&berlin_chip->lock);
> >+
> >+	clk_disable_unprepare(berlin_chip->clk);
> 
> Are you sure that register contents are retained after disabling the
> clock? I understand that cfg_clk is the _ip_ input clock and pwm gets
> derived from it.
> 
> Actually, since cfg_clk seems to be an important, internal SoC clock
> I'd say to clk_prepare_enable() in _probe() before reading any
> registers and clk_disable_unprepare() on _remove() (see below).

I'll update.

> 
> Internal low-frequency clocks don't consume that much power that it
> is worth the pain ;)
> 
> >+	return 0;
> >+}
> >+
> >+static int berlin_pwm_set_polarity(struct pwm_chip *chip,
> >+				   struct pwm_device *pwm,
> >+				   enum pwm_polarity polarity)
> >+{
> >+	struct berlin_pwm_chip *berlin_chip = to_berlin_pwm_chip(chip);
> >+	int ret;
> >+	u32 val;
> >+
> >+	ret = clk_prepare_enable(berlin_chip->clk);
> >+	if (ret)
> >+		return ret;
> 
> These would become unnecessary then.
> 
> >+	spin_lock(&berlin_chip->lock);
> >+
> >+	val = berlin_pwm_readl(berlin_chip, pwm->hwpwm, BERLIN_PWM_CONTROL);
> >+
> >+	if (polarity == PWM_POLARITY_NORMAL)
> >+		val &= ~BERLIN_PWM_INVERT_POLARITY;
> >+	else
> >+		val |= BERLIN_PWM_INVERT_POLARITY;
> >+
> >+	berlin_pwm_writel(val, berlin_chip, pwm->hwpwm, BERLIN_PWM_CONTROL);
> >+
> >+	spin_unlock(&berlin_chip->lock);
> >+
> >+	clk_disable_unprepare(berlin_chip->clk);
> 
> ditto.
> 
> >+	return 0;
> >+}
> >+
> >+static int berlin_pwm_enable(struct pwm_chip *chip, struct pwm_device *pwm)
> >+{
> >+	struct berlin_pwm_chip *berlin_chip = to_berlin_pwm_chip(chip);
> >+	int ret;
> >+
> >+	ret = clk_prepare_enable(berlin_chip->clk);
> >+	if (ret)
> >+		return ret;
> 
> ditto.
> 
> >+	spin_lock(&berlin_chip->lock);
> >+	berlin_pwm_writel(BERLIN_PWM_ENABLE, berlin_chip, pwm->hwpwm, BERLIN_PWM_EN);
> >+	spin_unlock(&berlin_chip->lock);
> >+
> >+	return 0;
> >+}
> >+
> >+static void berlin_pwm_disable(struct pwm_chip *chip, struct pwm_device *pwm)
> >+{
> >+	struct berlin_pwm_chip *berlin_chip = to_berlin_pwm_chip(chip);
> >+
> >+	spin_lock(&berlin_chip->lock);
> >+	berlin_pwm_writel(BERLIN_PWM_DISABLE, berlin_chip, pwm->hwpwm, BERLIN_PWM_EN);
> >+	spin_unlock(&berlin_chip->lock);
> >+
> >+	clk_disable_unprepare(berlin_chip->clk);
> 
> ditto.
> 
> >+}
> >+
> >+static const struct pwm_ops berlin_pwm_ops = {
> >+	.config = berlin_pwm_config,
> >+	.set_polarity = berlin_pwm_set_polarity,
> >+	.enable = berlin_pwm_enable,
> >+	.disable = berlin_pwm_disable,
> >+	.owner = THIS_MODULE,
> >+};
> >+
> >+static const struct of_device_id berlin_pwm_match[] = {
> >+	{ .compatible = "marvell,berlin-pwm" },
> >+	{ },
> >+};
> >+MODULE_DEVICE_TABLE(of, berlin_pwm_match);
> >+
> >+static int berlin_pwm_probe(struct platform_device *pdev)
> >+{
> >+	struct berlin_pwm_chip *pwm;
> >+	struct resource *res;
> >+	int ret;
> >+
> >+	pwm = devm_kzalloc(&pdev->dev, sizeof(*pwm), GFP_KERNEL);
> >+	if (!pwm)
> >+		return -ENOMEM;
> >+
> >+	res = platform_get_resource(pdev, IORESOURCE_MEM, 0);
> >+	pwm->base = devm_ioremap_resource(&pdev->dev, res);
> >+	if (IS_ERR(pwm->base))
> >+		return PTR_ERR(pwm->base);
> >+
> >+	pwm->clk = devm_clk_get(&pdev->dev, NULL);
> >+	if (IS_ERR(pwm->clk))
> >+		return PTR_ERR(pwm->clk);
> >+
> >+	pwm->chip.dev = &pdev->dev;
> >+	pwm->chip.ops = &berlin_pwm_ops;
> >+	pwm->chip.base = -1;
> >+	pwm->chip.npwm = 4;
> >+	pwm->chip.can_sleep = true;
> >+	pwm->chip.of_xlate = of_pwm_xlate_with_flags;
> >+	pwm->chip.of_pwm_n_cells = 3;
> >+
> >+	spin_lock_init(&pwm->lock);
> 
> add clk_prepare_enable() before adding the pwmchip...
> 
> >+	ret = pwmchip_add(&pwm->chip);
> >+	if (ret < 0) {
> >+		dev_err(&pdev->dev, "Failed to add PWM chip: %d\n", ret);
> >+		return ret;
> >+	}
> >+
> >+	platform_set_drvdata(pdev, pwm);
> >+
> >+	return 0;
> >+}
> >+
> >+static int berlin_pwm_remove(struct platform_device *pdev)
> >+{
> >+	struct berlin_pwm_chip *pwm = platform_get_drvdata(pdev);
> >+
> >+	return pwmchip_remove(&pwm->chip);
> 
> ... and clk_disable_unprepare after removing it.
> 
> Besides the comments, for Berlin you get my
> 
> Acked-by: Sebastian Hesselbarth <sebastian.hesselbarth at gmail.com>

Thanks!

Antoine

> 
> >+}
> >+
> >+static struct platform_driver berlin_pwm_driver = {
> >+	.probe	= berlin_pwm_probe,
> >+	.remove	= berlin_pwm_remove,
> >+	.driver	= {
> >+		.name	= "berlin-pwm",
> >+		.of_match_table = berlin_pwm_match,
> >+	},
> >+};
> >+module_platform_driver(berlin_pwm_driver);
> >+
> >+MODULE_AUTHOR("Antoine Tenart <antoine.tenart at free-electrons.com>");
> >+MODULE_DESCRIPTION("Marvell Berlin PWM driver");
> >+MODULE_LICENSE("GPL v2");
> >

-- 
Antoine T?nart, Free Electrons
Embedded Linux, Kernel and Android engineering
http://free-electrons.com


From antoine.tenart at free-electrons.com  Tue Aug 18 04:38:06 2015
From: antoine.tenart at free-electrons.com (Antoine Tenart)
Date: Tue, 18 Aug 2015 13:38:06 +0200
Subject: [PATCH v4 3/5] ARM: berlin: add a PWM node on the BG2Q
In-Reply-To: <1439897888-10921-1-git-send-email-antoine.tenart@free-electrons.com>
References: <1439897888-10921-1-git-send-email-antoine.tenart@free-electrons.com>
Message-ID: <1439897888-10921-4-git-send-email-antoine.tenart@free-electrons.com>

This patch adds a PWM node in the Berlin BG2Q device tree, using the
newly added Berlin PWM driver.

Signed-off-by: Antoine Tenart <antoine.tenart at free-electrons.com>
---
 arch/arm/boot/dts/berlin2q.dtsi | 7 +++++++
 1 file changed, 7 insertions(+)

diff --git a/arch/arm/boot/dts/berlin2q.dtsi b/arch/arm/boot/dts/berlin2q.dtsi
index 63a48490e2f9..5bfa71a87617 100644
--- a/arch/arm/boot/dts/berlin2q.dtsi
+++ b/arch/arm/boot/dts/berlin2q.dtsi
@@ -477,6 +477,13 @@
 			status = "disabled";
 		};
 
+		pwm: pwm at f20000 {
+			compatible = "marvell,berlin-pwm";
+			reg = <0xf20000 0x40>;
+			clocks = <&chip_clk CLKID_CFG>;
+			#pwm-cells = <3>;
+		};
+
 		apb at fc0000 {
 			compatible = "simple-bus";
 			#address-cells = <1>;
-- 
2.5.0



From antoine.tenart at free-electrons.com  Tue Aug 18 04:38:07 2015
From: antoine.tenart at free-electrons.com (Antoine Tenart)
Date: Tue, 18 Aug 2015 13:38:07 +0200
Subject: [PATCH v4 4/5] ARM: berlin: add a PWM node on the BG2
In-Reply-To: <1439897888-10921-1-git-send-email-antoine.tenart@free-electrons.com>
References: <1439897888-10921-1-git-send-email-antoine.tenart@free-electrons.com>
Message-ID: <1439897888-10921-5-git-send-email-antoine.tenart@free-electrons.com>

This patch adds a PWM node in the Berlin BG2 device tree, using the
newly added Berlin PWM driver.

Signed-off-by: Antoine Tenart <antoine.tenart at free-electrons.com>
---
 arch/arm/boot/dts/berlin2.dtsi | 7 +++++++
 1 file changed, 7 insertions(+)

diff --git a/arch/arm/boot/dts/berlin2.dtsi b/arch/arm/boot/dts/berlin2.dtsi
index ef811de09908..f094b06d16aa 100644
--- a/arch/arm/boot/dts/berlin2.dtsi
+++ b/arch/arm/boot/dts/berlin2.dtsi
@@ -404,6 +404,13 @@
 			};
 		};
 
+		pwm: pwm at f20000 {
+			compatible = "marvell,berlin-pwm";
+			reg = <0xf20000 0x40>;
+			clocks = <&chip_clk CLKID_CFG>;
+			#pwm-cells = <3>;
+		};
+
 		apb at fc0000 {
 			compatible = "simple-bus";
 			#address-cells = <1>;
-- 
2.5.0



From antoine.tenart at free-electrons.com  Tue Aug 18 04:38:05 2015
From: antoine.tenart at free-electrons.com (Antoine Tenart)
Date: Tue, 18 Aug 2015 13:38:05 +0200
Subject: [PATCH v4 2/5] Documentation: bindings: document the Berlin PWM driver
In-Reply-To: <1439897888-10921-1-git-send-email-antoine.tenart@free-electrons.com>
References: <1439897888-10921-1-git-send-email-antoine.tenart@free-electrons.com>
Message-ID: <1439897888-10921-3-git-send-email-antoine.tenart@free-electrons.com>

Following the addition of a Berlin PWM driver, this patch adds the
corresponding documentation.

Signed-off-by: Antoine Tenart <antoine.tenart at free-electrons.com>
Acked-by: Sebastian Hesselbarth <sebastian.hesselbarth at gmail.com>
---
 Documentation/devicetree/bindings/pwm/pwm-berlin.txt | 19 +++++++++++++++++++
 1 file changed, 19 insertions(+)
 create mode 100644 Documentation/devicetree/bindings/pwm/pwm-berlin.txt

diff --git a/Documentation/devicetree/bindings/pwm/pwm-berlin.txt b/Documentation/devicetree/bindings/pwm/pwm-berlin.txt
new file mode 100644
index 000000000000..8f9bc11f8c4c
--- /dev/null
+++ b/Documentation/devicetree/bindings/pwm/pwm-berlin.txt
@@ -0,0 +1,19 @@
+Berlin PWM controller
+
+PWM IP found in Marvell Berlin SoCs.
+
+Required properties:
+- compatible: should be "marvell,berlin-pwm"
+- reg: physical base address and length of the controller's registers
+- clocks: phandle to the input clock
+- #pwm-cells: should be 3. See pwm.txt in this directory for a description of
+  the cells format.
+
+Example:
+
+pwm: pwm at f7f20000 {
+	compatible = "marvell,berlin-pwm";
+	reg = <0xf7f20000 0x40>;
+	clocks = <&chip_clk CLKID_CFG>;
+	#pwm-cells = <3>;
+}
-- 
2.5.0



From antoine.tenart at free-electrons.com  Tue Aug 18 04:38:03 2015
From: antoine.tenart at free-electrons.com (Antoine Tenart)
Date: Tue, 18 Aug 2015 13:38:03 +0200
Subject: [PATCH v4 0/5] ARM: berlin: PWM support
Message-ID: <1439897888-10921-1-git-send-email-antoine.tenart@free-electrons.com>

Hi all,

This series adds a driver for the Marvell Berlin PWM controller, which
has 4 channels.

This has been tested on a BG2Q DMP.

Thanks,

Antoine

Changes since v3:
	- Use readl_relaxed
	- Reworked the clk enable / clk disable calls
	- Removed BERLIN_PWM_DISABLE

Changes since v2:
        - Reworked the prescaler/tcnt calculation
        - Added an input clock
        - Updated the documentation
        - Reordered the pwm node
        - Added some definition for BIT()

Changes since v1:
        - Added a sentinel in berlin_pwm_match[]

Antoine Tenart (5):
  pwm: add the Berlin pwm controller driver
  Documentation: bindings: document the Berlin PWM driver
  ARM: berlin: add a PWM node on the BG2Q
  ARM: berlin: add a PWM node on the BG2
  ARM: berlin: add a PWM node on the BG2CD

 .../devicetree/bindings/pwm/pwm-berlin.txt         |  19 ++
 arch/arm/boot/dts/berlin2.dtsi                     |   7 +
 arch/arm/boot/dts/berlin2cd.dtsi                   |   7 +
 arch/arm/boot/dts/berlin2q.dtsi                    |   7 +
 drivers/pwm/Kconfig                                |   9 +
 drivers/pwm/Makefile                               |   1 +
 drivers/pwm/pwm-berlin.c                           | 218 +++++++++++++++++++++
 7 files changed, 268 insertions(+)
 create mode 100644 Documentation/devicetree/bindings/pwm/pwm-berlin.txt
 create mode 100644 drivers/pwm/pwm-berlin.c

-- 
2.5.0



From antoine.tenart at free-electrons.com  Tue Aug 18 04:38:04 2015
From: antoine.tenart at free-electrons.com (Antoine Tenart)
Date: Tue, 18 Aug 2015 13:38:04 +0200
Subject: [PATCH v4 1/5] pwm: add the Berlin pwm controller driver
In-Reply-To: <1439897888-10921-1-git-send-email-antoine.tenart@free-electrons.com>
References: <1439897888-10921-1-git-send-email-antoine.tenart@free-electrons.com>
Message-ID: <1439897888-10921-2-git-send-email-antoine.tenart@free-electrons.com>

Add a PWM controller driver for the Marvell Berlin SoCs. This PWM
controller has 4 channels.

Signed-off-by: Antoine Tenart <antoine.tenart at free-electrons.com>
Acked-by: Sebastian Hesselbarth <sebastian.hesselbarth at gmail.com>
---
 drivers/pwm/Kconfig      |   9 ++
 drivers/pwm/Makefile     |   1 +
 drivers/pwm/pwm-berlin.c | 218 +++++++++++++++++++++++++++++++++++++++++++++++
 3 files changed, 228 insertions(+)
 create mode 100644 drivers/pwm/pwm-berlin.c

diff --git a/drivers/pwm/Kconfig b/drivers/pwm/Kconfig
index b1541f40fd8d..1773da8145b8 100644
--- a/drivers/pwm/Kconfig
+++ b/drivers/pwm/Kconfig
@@ -92,6 +92,15 @@ config PWM_BCM2835
 	  To compile this driver as a module, choose M here: the module
 	  will be called pwm-bcm2835.
 
+config PWM_BERLIN
+	tristate "Berlin PWM support"
+	depends on ARCH_BERLIN
+	help
+	  PWM framework driver for Berlin.
+
+	  To compile this driver as a module, choose M here: the module
+	  will be called pwm-berlin.
+
 config PWM_BFIN
 	tristate "Blackfin PWM support"
 	depends on BFIN_GPTIMERS
diff --git a/drivers/pwm/Makefile b/drivers/pwm/Makefile
index ec50eb5b5a8f..670c5fce8bbb 100644
--- a/drivers/pwm/Makefile
+++ b/drivers/pwm/Makefile
@@ -6,6 +6,7 @@ obj-$(CONFIG_PWM_ATMEL_HLCDC_PWM)	+= pwm-atmel-hlcdc.o
 obj-$(CONFIG_PWM_ATMEL_TCB)	+= pwm-atmel-tcb.o
 obj-$(CONFIG_PWM_BCM_KONA)	+= pwm-bcm-kona.o
 obj-$(CONFIG_PWM_BCM2835)	+= pwm-bcm2835.o
+obj-$(CONFIG_PWM_BERLIN)	+= pwm-berlin.o
 obj-$(CONFIG_PWM_BFIN)		+= pwm-bfin.o
 obj-$(CONFIG_PWM_CLPS711X)	+= pwm-clps711x.o
 obj-$(CONFIG_PWM_EP93XX)	+= pwm-ep93xx.o
diff --git a/drivers/pwm/pwm-berlin.c b/drivers/pwm/pwm-berlin.c
new file mode 100644
index 000000000000..1bb3958b6e4f
--- /dev/null
+++ b/drivers/pwm/pwm-berlin.c
@@ -0,0 +1,218 @@
+/*
+ * Marvell Berlin PWM driver
+ *
+ * Copyright (C) 2015 Marvell Technology Group Ltd.
+ *
+ * Antoine Tenart <antoine.tenart at free-electrons.com>
+ *
+ * This file is licensed under the terms of the GNU General Public
+ * License version 2. This program is licensed "as is" without any
+ * warranty of any kind, whether express or implied.
+ */
+
+#include <linux/clk.h>
+#include <linux/io.h>
+#include <linux/kernel.h>
+#include <linux/module.h>
+#include <linux/platform_device.h>
+#include <linux/pwm.h>
+#include <linux/spinlock.h>
+
+#define BERLIN_PWM_EN			0x0
+#define BERLIN_PWM_CONTROL		0x4
+#define BERLIN_PWM_DUTY			0x8
+#define BERLIN_PWM_TCNT			0xc
+
+#define BERLIN_PWM_ENABLE		BIT(0)
+#define BERLIN_PWM_INVERT_POLARITY	BIT(3)
+#define BERLIN_PWM_PRESCALE_MASK	0x7
+#define BERLIN_PWM_PRESCALE_MAX		4096
+#define BERLIN_PWM_MAX_TCNT		65535
+
+struct berlin_pwm_chip {
+	struct pwm_chip chip;
+	struct clk *clk;
+	void __iomem *base;
+	spinlock_t lock;
+};
+
+#define to_berlin_pwm_chip(chip)	\
+	container_of((chip), struct berlin_pwm_chip, chip)
+
+#define berlin_pwm_readl(chip, channel, offset)		\
+	readl_relaxed((chip)->base + (channel) * 0x10 + offset)
+#define berlin_pwm_writel(val, chip, channel, offset)	\
+	writel_relaxed(val, (chip)->base + (channel) * 0x10 + offset)
+
+/* prescaler table: {1, 4, 8, 16, 64, 256, 1024, 4096} */
+static const u32 prescaler_diff_table[] = {
+	1, 4, 2, 2, 4, 4, 4, 4,
+};
+
+static int berlin_pwm_config(struct pwm_chip *chip, struct pwm_device *pwm_dev,
+			     int duty_ns, int period_ns)
+{
+	struct berlin_pwm_chip *pwm = to_berlin_pwm_chip(chip);
+	int prescale = 0;
+	u32 val, duty, period;
+	u64 cycles;
+
+	cycles = clk_get_rate(pwm->clk);
+	cycles *= period_ns;
+	do_div(cycles, NSEC_PER_SEC);
+
+	while (cycles > BERLIN_PWM_MAX_TCNT)
+		do_div(cycles, prescaler_diff_table[++prescale]);
+
+	if (cycles > BERLIN_PWM_MAX_TCNT)
+		return -EINVAL;
+
+	period = cycles;
+	cycles *= duty_ns;
+	do_div(cycles, period_ns);
+	duty = cycles;
+
+	spin_lock(&pwm->lock);
+
+	val = berlin_pwm_readl(pwm, pwm_dev->hwpwm, BERLIN_PWM_CONTROL);
+	val &= ~BERLIN_PWM_PRESCALE_MASK;
+	val |= prescale;
+	berlin_pwm_writel(val, pwm, pwm_dev->hwpwm, BERLIN_PWM_CONTROL);
+
+	berlin_pwm_writel(duty, pwm, pwm_dev->hwpwm, BERLIN_PWM_DUTY);
+	berlin_pwm_writel(period, pwm, pwm_dev->hwpwm, BERLIN_PWM_TCNT);
+
+	spin_unlock(&pwm->lock);
+
+	return 0;
+}
+
+static int berlin_pwm_set_polarity(struct pwm_chip *chip,
+				   struct pwm_device *pwm_dev,
+				   enum pwm_polarity polarity)
+{
+	struct berlin_pwm_chip *pwm = to_berlin_pwm_chip(chip);
+	u32 val;
+
+	spin_lock(&pwm->lock);
+
+	val = berlin_pwm_readl(pwm, pwm_dev->hwpwm, BERLIN_PWM_CONTROL);
+
+	if (polarity == PWM_POLARITY_NORMAL)
+		val &= ~BERLIN_PWM_INVERT_POLARITY;
+	else
+		val |= BERLIN_PWM_INVERT_POLARITY;
+
+	berlin_pwm_writel(val, pwm, pwm_dev->hwpwm, BERLIN_PWM_CONTROL);
+
+	spin_unlock(&pwm->lock);
+
+	return 0;
+}
+
+static int berlin_pwm_enable(struct pwm_chip *chip, struct pwm_device *pwm_dev)
+{
+	struct berlin_pwm_chip *pwm = to_berlin_pwm_chip(chip);
+
+	spin_lock(&pwm->lock);
+	berlin_pwm_writel(BERLIN_PWM_ENABLE, pwm, pwm_dev->hwpwm,
+			  BERLIN_PWM_EN);
+	spin_unlock(&pwm->lock);
+
+	return 0;
+}
+
+static void berlin_pwm_disable(struct pwm_chip *chip,
+			       struct pwm_device *pwm_dev)
+{
+	struct berlin_pwm_chip *pwm = to_berlin_pwm_chip(chip);
+	u32 val;
+
+	spin_lock(&pwm->lock);
+
+	val = berlin_pwm_readl(pwm, pwm_dev->hwpwm, BERLIN_PWM_EN);
+	val &= ~BERLIN_PWM_ENABLE;
+	berlin_pwm_writel(val, pwm, pwm_dev->hwpwm, BERLIN_PWM_EN);
+
+	spin_unlock(&pwm->lock);
+}
+
+static const struct pwm_ops berlin_pwm_ops = {
+	.config = berlin_pwm_config,
+	.set_polarity = berlin_pwm_set_polarity,
+	.enable = berlin_pwm_enable,
+	.disable = berlin_pwm_disable,
+	.owner = THIS_MODULE,
+};
+
+static const struct of_device_id berlin_pwm_match[] = {
+	{ .compatible = "marvell,berlin-pwm" },
+	{ },
+};
+MODULE_DEVICE_TABLE(of, berlin_pwm_match);
+
+static int berlin_pwm_probe(struct platform_device *pdev)
+{
+	struct berlin_pwm_chip *pwm;
+	struct resource *res;
+	int ret;
+
+	pwm = devm_kzalloc(&pdev->dev, sizeof(*pwm), GFP_KERNEL);
+	if (!pwm)
+		return -ENOMEM;
+
+	res = platform_get_resource(pdev, IORESOURCE_MEM, 0);
+	pwm->base = devm_ioremap_resource(&pdev->dev, res);
+	if (IS_ERR(pwm->base))
+		return PTR_ERR(pwm->base);
+
+	pwm->clk = devm_clk_get(&pdev->dev, NULL);
+	if (IS_ERR(pwm->clk))
+		return PTR_ERR(pwm->clk);
+
+	ret = clk_prepare_enable(pwm->clk);
+	if (ret)
+		return ret;
+
+	pwm->chip.dev = &pdev->dev;
+	pwm->chip.ops = &berlin_pwm_ops;
+	pwm->chip.base = -1;
+	pwm->chip.npwm = 4;
+	pwm->chip.can_sleep = true;
+	pwm->chip.of_xlate = of_pwm_xlate_with_flags;
+	pwm->chip.of_pwm_n_cells = 3;
+
+	spin_lock_init(&pwm->lock);
+
+	ret = pwmchip_add(&pwm->chip);
+	if (ret < 0) {
+		dev_err(&pdev->dev, "Failed to add PWM chip: %d\n", ret);
+		return ret;
+	}
+
+	platform_set_drvdata(pdev, pwm);
+
+	return 0;
+}
+
+static int berlin_pwm_remove(struct platform_device *pdev)
+{
+	struct berlin_pwm_chip *pwm = platform_get_drvdata(pdev);
+
+	clk_disable_unprepare(pwm->clk);
+	return pwmchip_remove(&pwm->chip);
+}
+
+static struct platform_driver berlin_pwm_driver = {
+	.probe	= berlin_pwm_probe,
+	.remove	= berlin_pwm_remove,
+	.driver	= {
+		.name	= "berlin-pwm",
+		.of_match_table = berlin_pwm_match,
+	},
+};
+module_platform_driver(berlin_pwm_driver);
+
+MODULE_AUTHOR("Antoine Tenart <antoine.tenart at free-electrons.com>");
+MODULE_DESCRIPTION("Marvell Berlin PWM driver");
+MODULE_LICENSE("GPL v2");
-- 
2.5.0



From antoine.tenart at free-electrons.com  Tue Aug 18 04:38:08 2015
From: antoine.tenart at free-electrons.com (Antoine Tenart)
Date: Tue, 18 Aug 2015 13:38:08 +0200
Subject: [PATCH v4 5/5] ARM: berlin: add a PWM node on the BG2CD
In-Reply-To: <1439897888-10921-1-git-send-email-antoine.tenart@free-electrons.com>
References: <1439897888-10921-1-git-send-email-antoine.tenart@free-electrons.com>
Message-ID: <1439897888-10921-6-git-send-email-antoine.tenart@free-electrons.com>

This patch adds a PWM node in the Berlin BG2CD device tree, using the
newly added Berlin PWM driver.

Signed-off-by: Antoine Tenart <antoine.tenart at free-electrons.com>
---
 arch/arm/boot/dts/berlin2cd.dtsi | 7 +++++++
 1 file changed, 7 insertions(+)

diff --git a/arch/arm/boot/dts/berlin2cd.dtsi b/arch/arm/boot/dts/berlin2cd.dtsi
index 900213d78a32..5d984f58dde7 100644
--- a/arch/arm/boot/dts/berlin2cd.dtsi
+++ b/arch/arm/boot/dts/berlin2cd.dtsi
@@ -368,6 +368,13 @@
 			status = "disabled";
 		};
 
+		pwm: pwm at f20000 {
+			compatible = "marvell,berlin-pwm";
+			reg = <0xf20000 0x40>;
+			clocks = <&chip_clk CLKID_CFG>;
+			#pwm-cells = <3>;
+		};
+
 		apb at fc0000 {
 			compatible = "simple-bus";
 			#address-cells = <1>;
-- 
2.5.0



From antoine.tenart at free-electrons.com  Tue Aug 18 04:46:02 2015
From: antoine.tenart at free-electrons.com (Antoine Tenart)
Date: Tue, 18 Aug 2015 13:46:02 +0200
Subject: [PATCH v2 0/6] ARM: berlin: add cpufreq support
Message-ID: <1439898368-11543-1-git-send-email-antoine.tenart@free-electrons.com>

Hi,

This series adds the cpufreq support to the Berlin SoCs, using
cpufreq-dt.

First, the cpuclk clock is added to the BG2Q clock driver. This clock
has a divider fixed to 1, so we use a fixed factor clock here.

Then register a platform device for cpufreq-dt.

I also added the OPP table definition in the BG2Q, BG2 and BG2CD device
trees. When using a BG2Q, some bootloaders may update this table when
booting (mine doesn't).

Tested on a BG2Q DMP.

Thanks,

Antoine

Changes since v1:
	- added the BG2 and BG2CD support
	- moved MAX_CLKS out of the Berlin clk driver
	- reordered the patches

Antoine Tenart (6):
  clk: berlin: move MAX_CLKS out of drivers/clk/berlin
  clk: berlin: add cpuclk
  ARM: berlin: dts: add the cpufreq-dt bindings on the BG2Q
  ARM: berlin: dts: add the cpufreq-dt bindings on the BG2
  ARM: berlin: dts: add the cpufreq-dt bindings on the BG2CD
  ARM: berlin: register cpufreq-dt

 arch/arm/boot/dts/berlin2.dtsi       | 10 ++++++++++
 arch/arm/boot/dts/berlin2cd.dtsi     |  8 ++++++++
 arch/arm/boot/dts/berlin2q.dtsi      | 11 +++++++++++
 arch/arm/mach-berlin/berlin.c        |  6 ++++++
 drivers/clk/berlin/bg2.c             |  1 -
 drivers/clk/berlin/bg2q.c            | 13 ++++++-------
 include/dt-bindings/clock/berlin2.h  |  2 ++
 include/dt-bindings/clock/berlin2q.h |  3 +++
 8 files changed, 46 insertions(+), 8 deletions(-)

-- 
2.5.0



From antoine.tenart at free-electrons.com  Tue Aug 18 04:46:06 2015
From: antoine.tenart at free-electrons.com (Antoine Tenart)
Date: Tue, 18 Aug 2015 13:46:06 +0200
Subject: [PATCH v2 4/6] ARM: berlin: dts: add the cpufreq-dt bindings on the
 BG2
In-Reply-To: <1439898368-11543-1-git-send-email-antoine.tenart@free-electrons.com>
References: <1439898368-11543-1-git-send-email-antoine.tenart@free-electrons.com>
Message-ID: <1439898368-11543-5-git-send-email-antoine.tenart@free-electrons.com>

The BG2 uses cpugreq-dt. Add the corresponding bindings.

Signed-off-by: Antoine Tenart <antoine.tenart at free-electrons.com>
---
 arch/arm/boot/dts/berlin2.dtsi | 10 ++++++++++
 1 file changed, 10 insertions(+)

diff --git a/arch/arm/boot/dts/berlin2.dtsi b/arch/arm/boot/dts/berlin2.dtsi
index ef811de09908..d80dc82729b8 100644
--- a/arch/arm/boot/dts/berlin2.dtsi
+++ b/arch/arm/boot/dts/berlin2.dtsi
@@ -57,6 +57,16 @@
 			device_type = "cpu";
 			next-level-cache = <&l2>;
 			reg = <0>;
+
+			clocks = <&chip_clk CLKID_CPU>;
+			clock-latency = <100000>;
+			operating-points = <
+				/* kHz    uV */
+				1200000 1200000
+				1000000 1200000
+				800000  1200000
+				600000  1200000
+			>;
 		};
 
 		cpu at 1 {
-- 
2.5.0



From antoine.tenart at free-electrons.com  Tue Aug 18 04:46:05 2015
From: antoine.tenart at free-electrons.com (Antoine Tenart)
Date: Tue, 18 Aug 2015 13:46:05 +0200
Subject: [PATCH v2 3/6] ARM: berlin: dts: add the cpufreq-dt bindings on the
 BG2Q
In-Reply-To: <1439898368-11543-1-git-send-email-antoine.tenart@free-electrons.com>
References: <1439898368-11543-1-git-send-email-antoine.tenart@free-electrons.com>
Message-ID: <1439898368-11543-4-git-send-email-antoine.tenart@free-electrons.com>

The BG2Q uses cpugreq-dt. Add the corresponding bindings. The operating
points can be updated by the bootloader.

Signed-off-by: Antoine Tenart <antoine.tenart at free-electrons.com>
---
 arch/arm/boot/dts/berlin2q.dtsi | 11 +++++++++++
 1 file changed, 11 insertions(+)

diff --git a/arch/arm/boot/dts/berlin2q.dtsi b/arch/arm/boot/dts/berlin2q.dtsi
index 63a48490e2f9..58f6792c0d77 100644
--- a/arch/arm/boot/dts/berlin2q.dtsi
+++ b/arch/arm/boot/dts/berlin2q.dtsi
@@ -53,6 +53,17 @@
 			device_type = "cpu";
 			next-level-cache = <&l2>;
 			reg = <0>;
+
+			clocks = <&chip_clk CLKID_CPU>;
+			clock-latency = <100000>;
+			/* Can be modified by the bootloader */
+			operating-points = <
+				/* kHz    uV */
+				1200000 1200000
+				1000000 1200000
+				800000  1200000
+				600000  1200000
+			>;
 		};
 
 		cpu at 1 {
-- 
2.5.0



From antoine.tenart at free-electrons.com  Tue Aug 18 04:46:04 2015
From: antoine.tenart at free-electrons.com (Antoine Tenart)
Date: Tue, 18 Aug 2015 13:46:04 +0200
Subject: [PATCH v2 2/6] clk: berlin: add cpuclk
In-Reply-To: <1439898368-11543-1-git-send-email-antoine.tenart@free-electrons.com>
References: <1439898368-11543-1-git-send-email-antoine.tenart@free-electrons.com>
Message-ID: <1439898368-11543-3-git-send-email-antoine.tenart@free-electrons.com>

Add cpuclk in the Berlin BG2Q clock driver. This clk has a divider
fixed to 1.

Signed-off-by: Antoine Tenart <antoine.tenart at free-electrons.com>
Acked-by: Stephen Boyd <sboyd at codeaurora.org>
---
 drivers/clk/berlin/bg2q.c            | 12 ++++++------
 include/dt-bindings/clock/berlin2q.h |  3 ++-
 2 files changed, 8 insertions(+), 7 deletions(-)

diff --git a/drivers/clk/berlin/bg2q.c b/drivers/clk/berlin/bg2q.c
index a27958efab92..c2f48f3773e8 100644
--- a/drivers/clk/berlin/bg2q.c
+++ b/drivers/clk/berlin/bg2q.c
@@ -355,13 +355,13 @@ static void __init berlin2q_clock_setup(struct device_node *np)
 			    gd->bit_idx, 0, &lock);
 	}
 
-	/*
-	 * twdclk is derived from cpu/3
-	 * TODO: use cpupll until cpuclk is not available
-	 */
+	/* cpuclk divider is fixed to 1 */
+	clks[CLKID_CPU] =
+		clk_register_fixed_factor(NULL, "cpu", clk_names[CPUPLL],
+					  0, 1, 1);
+	/* twdclk is derived from cpu/3 */
 	clks[CLKID_TWD] =
-		clk_register_fixed_factor(NULL, "twd", clk_names[CPUPLL],
-					  0, 1, 3);
+		clk_register_fixed_factor(NULL, "twd", "cpu", 0, 1, 3);
 
 	/* check for errors on leaf clocks */
 	for (n = 0; n < MAX_CLKS; n++) {
diff --git a/include/dt-bindings/clock/berlin2q.h b/include/dt-bindings/clock/berlin2q.h
index c79af928ae92..771d8739f67a 100644
--- a/include/dt-bindings/clock/berlin2q.h
+++ b/include/dt-bindings/clock/berlin2q.h
@@ -29,5 +29,6 @@
 #define CLKID_SMEMC		24
 #define CLKID_PCIE		25
 #define CLKID_TWD		26
+#define CLKID_CPU		27
 
-#define MAX_CLKS		27
+#define MAX_CLKS		28
-- 
2.5.0



From antoine.tenart at free-electrons.com  Tue Aug 18 04:46:03 2015
From: antoine.tenart at free-electrons.com (Antoine Tenart)
Date: Tue, 18 Aug 2015 13:46:03 +0200
Subject: [PATCH v2 1/6] clk: berlin: move MAX_CLKS out of drivers/clk/berlin
In-Reply-To: <1439898368-11543-1-git-send-email-antoine.tenart@free-electrons.com>
References: <1439898368-11543-1-git-send-email-antoine.tenart@free-electrons.com>
Message-ID: <1439898368-11543-2-git-send-email-antoine.tenart@free-electrons.com>

Move the MAX_CLKS definition used in the Berlin clock driver outside the
driver.

Signed-off-by: Antoine Tenart <antoine.tenart at free-electrons.com>
---
 drivers/clk/berlin/bg2.c             | 1 -
 drivers/clk/berlin/bg2q.c            | 1 -
 include/dt-bindings/clock/berlin2.h  | 2 ++
 include/dt-bindings/clock/berlin2q.h | 2 ++
 4 files changed, 4 insertions(+), 2 deletions(-)

diff --git a/drivers/clk/berlin/bg2.c b/drivers/clk/berlin/bg2.c
index 73153fc45ee9..469a2c57e1b4 100644
--- a/drivers/clk/berlin/bg2.c
+++ b/drivers/clk/berlin/bg2.c
@@ -91,7 +91,6 @@
  *
  */
 
-#define	MAX_CLKS 41
 static struct clk *clks[MAX_CLKS];
 static struct clk_onecell_data clk_data;
 static DEFINE_SPINLOCK(lock);
diff --git a/drivers/clk/berlin/bg2q.c b/drivers/clk/berlin/bg2q.c
index 221f40c2b850..a27958efab92 100644
--- a/drivers/clk/berlin/bg2q.c
+++ b/drivers/clk/berlin/bg2q.c
@@ -45,7 +45,6 @@
 #define REG_SDIO0XIN_CLKCTL	0x0158
 #define REG_SDIO1XIN_CLKCTL	0x015c
 
-#define	MAX_CLKS 27
 static struct clk *clks[MAX_CLKS];
 static struct clk_onecell_data clk_data;
 static DEFINE_SPINLOCK(lock);
diff --git a/include/dt-bindings/clock/berlin2.h b/include/dt-bindings/clock/berlin2.h
index 0c30800175df..97832b840beb 100644
--- a/include/dt-bindings/clock/berlin2.h
+++ b/include/dt-bindings/clock/berlin2.h
@@ -43,3 +43,5 @@
 #define CLKID_VIDEO1		38
 #define CLKID_VIDEO2		39
 #define CLKID_TWD		40
+
+#define MAX_CLKS		41
diff --git a/include/dt-bindings/clock/berlin2q.h b/include/dt-bindings/clock/berlin2q.h
index 287fc3b4afb2..c79af928ae92 100644
--- a/include/dt-bindings/clock/berlin2q.h
+++ b/include/dt-bindings/clock/berlin2q.h
@@ -29,3 +29,5 @@
 #define CLKID_SMEMC		24
 #define CLKID_PCIE		25
 #define CLKID_TWD		26
+
+#define MAX_CLKS		27
-- 
2.5.0



From antoine.tenart at free-electrons.com  Tue Aug 18 04:46:08 2015
From: antoine.tenart at free-electrons.com (Antoine Tenart)
Date: Tue, 18 Aug 2015 13:46:08 +0200
Subject: [PATCH v2 6/6] ARM: berlin: register cpufreq-dt
In-Reply-To: <1439898368-11543-1-git-send-email-antoine.tenart@free-electrons.com>
References: <1439898368-11543-1-git-send-email-antoine.tenart@free-electrons.com>
Message-ID: <1439898368-11543-7-git-send-email-antoine.tenart@free-electrons.com>

The Berlin SoCs use cpufreq-dt for cpufreq. Register a platform device.

Signed-off-by: Antoine Tenart <antoine.tenart at free-electrons.com>
---
 arch/arm/mach-berlin/berlin.c | 6 ++++++
 1 file changed, 6 insertions(+)

diff --git a/arch/arm/mach-berlin/berlin.c b/arch/arm/mach-berlin/berlin.c
index ac181c6797ee..25d73870ccca 100644
--- a/arch/arm/mach-berlin/berlin.c
+++ b/arch/arm/mach-berlin/berlin.c
@@ -18,6 +18,11 @@
 #include <asm/hardware/cache-l2x0.h>
 #include <asm/mach/arch.h>
 
+static void __init berlin_init_late(void)
+{
+	platform_device_register_simple("cpufreq-dt", -1, NULL, 0);
+}
+
 static const char * const berlin_dt_compat[] = {
 	"marvell,berlin",
 	NULL,
@@ -25,6 +30,7 @@ static const char * const berlin_dt_compat[] = {
 
 DT_MACHINE_START(BERLIN_DT, "Marvell Berlin")
 	.dt_compat	= berlin_dt_compat,
+	.init_late	= berlin_init_late,
 	/*
 	 * with DT probing for L2CCs, berlin_init_machine can be removed.
 	 * Note: 88DE3005 (Armada 1500-mini) uses pl310 l2cc
-- 
2.5.0



From antoine.tenart at free-electrons.com  Tue Aug 18 04:46:07 2015
From: antoine.tenart at free-electrons.com (Antoine Tenart)
Date: Tue, 18 Aug 2015 13:46:07 +0200
Subject: [PATCH v2 5/6] ARM: berlin: dts: add the cpufreq-dt bindings on the
 BG2CD
In-Reply-To: <1439898368-11543-1-git-send-email-antoine.tenart@free-electrons.com>
References: <1439898368-11543-1-git-send-email-antoine.tenart@free-electrons.com>
Message-ID: <1439898368-11543-6-git-send-email-antoine.tenart@free-electrons.com>

The BG2CD uses cpugreq-dt. Add the corresponding bindings.

Signed-off-by: Antoine Tenart <antoine.tenart at free-electrons.com>
---
 arch/arm/boot/dts/berlin2cd.dtsi | 8 ++++++++
 1 file changed, 8 insertions(+)

diff --git a/arch/arm/boot/dts/berlin2cd.dtsi b/arch/arm/boot/dts/berlin2cd.dtsi
index 900213d78a32..3c7a7404f10c 100644
--- a/arch/arm/boot/dts/berlin2cd.dtsi
+++ b/arch/arm/boot/dts/berlin2cd.dtsi
@@ -56,6 +56,14 @@
 			device_type = "cpu";
 			next-level-cache = <&l2>;
 			reg = <0>;
+
+			clocks = <&chip_clk CLKID_CPU>;
+			clock-latency = <100000>;
+			operating-points = <
+				/* kHz    uV */
+				800000  1200000
+				600000  1200000
+			>;
 		};
 	};
 
-- 
2.5.0



From sebastian.hesselbarth at gmail.com  Tue Aug 18 04:53:27 2015
From: sebastian.hesselbarth at gmail.com (Sebastian Hesselbarth)
Date: Tue, 18 Aug 2015 13:53:27 +0200
Subject: [PATCH v4 1/5] pwm: add the Berlin pwm controller driver
In-Reply-To: <1439897888-10921-2-git-send-email-antoine.tenart@free-electrons.com>
References: <1439897888-10921-1-git-send-email-antoine.tenart@free-electrons.com>
 <1439897888-10921-2-git-send-email-antoine.tenart@free-electrons.com>
Message-ID: <55D31CB7.9030504@gmail.com>

On 08/18/2015 01:38 PM, Antoine Tenart wrote:
> Add a PWM controller driver for the Marvell Berlin SoCs. This PWM
> controller has 4 channels.
>
> Signed-off-by: Antoine Tenart <antoine.tenart at free-electrons.com>
> Acked-by: Sebastian Hesselbarth <sebastian.hesselbarth at gmail.com>
> ---
[...]
> diff --git a/drivers/pwm/pwm-berlin.c b/drivers/pwm/pwm-berlin.c
> new file mode 100644
> index 000000000000..1bb3958b6e4f
> --- /dev/null
> +++ b/drivers/pwm/pwm-berlin.c
> @@ -0,0 +1,218 @@
> +/*
> + * Marvell Berlin PWM driver
> + *
> + * Copyright (C) 2015 Marvell Technology Group Ltd.
> + *
> + * Antoine Tenart <antoine.tenart at free-electrons.com>
> + *
> + * This file is licensed under the terms of the GNU General Public
> + * License version 2. This program is licensed "as is" without any
> + * warranty of any kind, whether express or implied.
> + */
> +
[...]
> +
> +#define berlin_pwm_readl(chip, channel, offset)		\
> +	readl_relaxed((chip)->base + (channel) * 0x10 + offset)
> +#define berlin_pwm_writel(val, chip, channel, offset)	\
> +	writel_relaxed(val, (chip)->base + (channel) * 0x10 + offset)
> +
> +/* prescaler table: {1, 4, 8, 16, 64, 256, 1024, 4096} */
> +static const u32 prescaler_diff_table[] = {
> +	1, 4, 2, 2, 4, 4, 4, 4,
> +};
> +
> +static int berlin_pwm_config(struct pwm_chip *chip, struct pwm_device *pwm_dev,
> +			     int duty_ns, int period_ns)
> +{
> +	struct berlin_pwm_chip *pwm = to_berlin_pwm_chip(chip);
> +	int prescale = 0;
> +	u32 val, duty, period;
> +	u64 cycles;
> +
> +	cycles = clk_get_rate(pwm->clk);
> +	cycles *= period_ns;
> +	do_div(cycles, NSEC_PER_SEC);
> +
> +	while (cycles > BERLIN_PWM_MAX_TCNT)
> +		do_div(cycles, prescaler_diff_table[++prescale]);
> +
> +	if (cycles > BERLIN_PWM_MAX_TCNT)
> +		return -EINVAL;
> +
> +	period = cycles;
> +	cycles *= duty_ns;
> +	do_div(cycles, period_ns);
> +	duty = cycles;
> +
> +	spin_lock(&pwm->lock);
> +
> +	val = berlin_pwm_readl(pwm, pwm_dev->hwpwm, BERLIN_PWM_CONTROL);
> +	val &= ~BERLIN_PWM_PRESCALE_MASK;
> +	val |= prescale;
> +	berlin_pwm_writel(val, pwm, pwm_dev->hwpwm, BERLIN_PWM_CONTROL);
> +
> +	berlin_pwm_writel(duty, pwm, pwm_dev->hwpwm, BERLIN_PWM_DUTY);
> +	berlin_pwm_writel(period, pwm, pwm_dev->hwpwm, BERLIN_PWM_TCNT);

The reason why I usually tend to _not_ use _relaxed() in low-performance
setup code is that you'll have to think about reordering issues when
using _relaxed ones.

The question here is: Is it _guaranteed_ that above writel_relaxed()
will be issued _before_ actually releasing the spin_lock?

> +	spin_unlock(&pwm->lock);
> +
> +	return 0;
> +}
[...]
> +static int berlin_pwm_enable(struct pwm_chip *chip, struct pwm_device *pwm_dev)
> +{
> +	struct berlin_pwm_chip *pwm = to_berlin_pwm_chip(chip);
> +
> +	spin_lock(&pwm->lock);
> +	berlin_pwm_writel(BERLIN_PWM_ENABLE, pwm, pwm_dev->hwpwm,
> +			  BERLIN_PWM_EN);

Please use the same read-modify-write sequence as below for disable.

> +	spin_unlock(&pwm->lock);
> +
> +	return 0;
> +}
> +
> +static void berlin_pwm_disable(struct pwm_chip *chip,
> +			       struct pwm_device *pwm_dev)
> +{
> +	struct berlin_pwm_chip *pwm = to_berlin_pwm_chip(chip);
> +	u32 val;
> +
> +	spin_lock(&pwm->lock);
> +
> +	val = berlin_pwm_readl(pwm, pwm_dev->hwpwm, BERLIN_PWM_EN);
> +	val &= ~BERLIN_PWM_ENABLE;
> +	berlin_pwm_writel(val, pwm, pwm_dev->hwpwm, BERLIN_PWM_EN);
> +
> +	spin_unlock(&pwm->lock);
> +}
[...]
> +static int berlin_pwm_remove(struct platform_device *pdev)
> +{
> +	struct berlin_pwm_chip *pwm = platform_get_drvdata(pdev);
> +
> +	clk_disable_unprepare(pwm->clk);
> +	return pwmchip_remove(&pwm->chip);

You _have_ to first call pwmchip_remove() and then
clk_disable_unprepare().

Sebastian

> +}
> +
> +static struct platform_driver berlin_pwm_driver = {
> +	.probe	= berlin_pwm_probe,
> +	.remove	= berlin_pwm_remove,
> +	.driver	= {
> +		.name	= "berlin-pwm",
> +		.of_match_table = berlin_pwm_match,
> +	},
> +};
> +module_platform_driver(berlin_pwm_driver);
> +
> +MODULE_AUTHOR("Antoine Tenart <antoine.tenart at free-electrons.com>");
> +MODULE_DESCRIPTION("Marvell Berlin PWM driver");
> +MODULE_LICENSE("GPL v2");
>


From linux at arm.linux.org.uk  Tue Aug 18 05:04:53 2015
From: linux at arm.linux.org.uk (Russell King - ARM Linux)
Date: Tue, 18 Aug 2015 13:04:53 +0100
Subject: [PATCH v4 1/5] pwm: add the Berlin pwm controller driver
In-Reply-To: <55D31CB7.9030504@gmail.com>
References: <1439897888-10921-1-git-send-email-antoine.tenart@free-electrons.com>
 <1439897888-10921-2-git-send-email-antoine.tenart@free-electrons.com>
 <55D31CB7.9030504@gmail.com>
Message-ID: <20150818120452.GP7557@n2100.arm.linux.org.uk>

On Tue, Aug 18, 2015 at 01:53:27PM +0200, Sebastian Hesselbarth wrote:
> On 08/18/2015 01:38 PM, Antoine Tenart wrote:
> >+	val = berlin_pwm_readl(pwm, pwm_dev->hwpwm, BERLIN_PWM_CONTROL);
> >+	val &= ~BERLIN_PWM_PRESCALE_MASK;
> >+	val |= prescale;
> >+	berlin_pwm_writel(val, pwm, pwm_dev->hwpwm, BERLIN_PWM_CONTROL);
> >+
> >+	berlin_pwm_writel(duty, pwm, pwm_dev->hwpwm, BERLIN_PWM_DUTY);
> >+	berlin_pwm_writel(period, pwm, pwm_dev->hwpwm, BERLIN_PWM_TCNT);
> 
> The reason why I usually tend to _not_ use _relaxed() in low-performance
> setup code is that you'll have to think about reordering issues when
> using _relaxed ones.

If that is your concern, then you should read Documentation/memory-barriers.txt,
specifically the section on "ACQUIRES VS I/O ACCESSES".  Using the non-
relaxed accessors doesn't save you in every circumstance.

> The question here is: Is it _guaranteed_ that above writel_relaxed()
> will be issued _before_ actually releasing the spin_lock?

There is no guarantee on all hardware that writel() will be seen by the
hardware before other accesses within a separate spinlocked region
using the same lock.

-- 
FTTC broadband for 0.8mile line: currently at 10.5Mbps down 400kbps up
according to speedtest.net.


From afzal.mohd.ma at gmail.com  Tue Aug 18 05:06:18 2015
From: afzal.mohd.ma at gmail.com (Afzal Mohammed)
Date: Tue, 18 Aug 2015 17:36:18 +0530
Subject: [PATCH] ARM: keystone: add a work around to handle asynchronous
 external abort
In-Reply-To: <1439886500.31432.4.camel@pengutronix.de>
References: <1439320409-20084-1-git-send-email-m-karicheri2@ti.com>
 <55CDF579.4050408@ti.com>
 <20150814140934.GX7557@n2100.arm.linux.org.uk>
 <55CE05EC.4040909@oracle.com> <55CE633C.10402@ti.com>
 <20150814215617.GA7557@n2100.arm.linux.org.uk>
 <55D25C64.3090107@ti.com> <55D2A1DD.9000007@oracle.com>
 <20150818081334.GK7557@n2100.arm.linux.org.uk>
 <1439886500.31432.4.camel@pengutronix.de>
Message-ID: <20150818120618.GA4294@afzalpc>

Hi Murali,

On Tue, Aug 18, 2015 at 10:28:20AM +0200, Lucas Stach wrote:
> Am Dienstag, den 18.08.2015, 09:13 +0100 schrieb Russell King - ARM
> Linux:

> > It seems to be pointing towards something in the boot loader...
> > 
> > Normally, uboot will hook itself into the vectors to report errors, but
> > I wonder whether uboot enables asynchronous aborts while it's running.
> > Don't forget to make sure that the aborts are disabled again prior to
> > calling the kernel.
> > 
> At least one of the Marvell platforms has the same issue with the
> bootloader (I think it is some downstream U-Boot) leaving an imprecise
> abort hanging around as a nice present for Linux to crash on.

If you have a JTAG, maybe you can manually set CPSR.A bit (equivalent
of Lucas's patch) at bootloader/kernel entry and conclude who is the
culprit or maybe even localize it better.

This method did help in rootcausing issue in one of the SoC that showed
the same behaviour.

Regards
Afzal


From jogo at openwrt.org  Tue Aug 18 05:19:54 2015
From: jogo at openwrt.org (Jonas Gorski)
Date: Tue, 18 Aug 2015 14:19:54 +0200
Subject: [PATCH] spi: mediatek: fix spi incorrect endian usage and remove
 redundant clock
In-Reply-To: <1439895231-17778-1-git-send-email-leilk.liu@mediatek.com>
References: <1439895231-17778-1-git-send-email-leilk.liu@mediatek.com>
Message-ID: <CAOiHx=nBOtm3c7QQpA-SSxXzJGjUEJQBtR9CynoeqsXRoz4fRg@mail.gmail.com>

Hi,

On Tue, Aug 18, 2015 at 12:53 PM, Leilk Liu <leilk.liu at mediatek.com> wrote:
> This patch fixes incorrect endian usage, removes redundant
> clock in prepare_hardware/unprepare_hardware and revises
> coding styles.
>
> Signed-off-by: Leilk Liu <leilk.liu at mediatek.com>
>
> ---
> Change in this patch:
> 1. fix incorrect endian usage on big-endian system.
> 2. delete redundant clock in prepare/unprepare_hardware.
> 3. revise coding styles.

The usual philosophy is to have one change per patch, so this might be
better as three patches. But this is Mark's call. Since the driver
isn't yet in Linus' tree, it might be a-ok to mix style improvements
and actual fixes, but as soon as it landed in Linus' tree you need to
keep them separate, so fixes can be easily backported.

Regarding the content ...

> ---
>  drivers/spi/spi-mt65xx.c                 | 163 +++++++++++++------------------
>  include/linux/platform_data/spi-mt65xx.h |   2 -
>  2 files changed, 69 insertions(+), 96 deletions(-)
>
> diff --git a/drivers/spi/spi-mt65xx.c b/drivers/spi/spi-mt65xx.c
> index 519f50c..a9da887 100644
> --- a/drivers/spi/spi-mt65xx.c
> +++ b/drivers/spi/spi-mt65xx.c
> @@ -694,6 +662,7 @@ static int mtk_spi_resume(struct device *dev)
>         if (!pm_runtime_suspended(dev)) {
>                 ret = clk_prepare_enable(mdata->spi_clk);
>                 if (ret < 0)
> +                       dev_err(dev, "failed to enable spi_clk (%d)\n", ret);
>                         return ret;

You need to add braces here, else the "return ret" isn't covered by
the if () anymore and you always return at this place.

>         }
>
> @@ -720,8 +689,14 @@ static int mtk_spi_runtime_resume(struct device *dev)
>  {
>         struct spi_master *master = dev_get_drvdata(dev);
>         struct mtk_spi *mdata = spi_master_get_devdata(master);
> +       int ret;
> +
> +       ret = clk_prepare_enable(mdata->spi_clk);
> +       if (ret < 0)
> +               dev_err(dev, "failed to enable spi_clk (%d)\n", ret);
> +               return ret;

Same here. Although at least here it should be harmless, as
clk_prepare_enable doesn't return > 0.

>
> -       return clk_prepare_enable(mdata->spi_clk);
> +       return 0;
>  }
>  #endif /* CONFIG_PM */
>


Jonas


From jogo at openwrt.org  Tue Aug 18 05:30:14 2015
From: jogo at openwrt.org (Jonas Gorski)
Date: Tue, 18 Aug 2015 14:30:14 +0200
Subject: [PATCH v3 0/3] qcom: Add SMEM MTD parser
In-Reply-To: <1439855266-26242-1-git-send-email-mathieu@codeaurora.org>
References: <1439855266-26242-1-git-send-email-mathieu@codeaurora.org>
Message-ID: <CAOiHx=nPDBPsj_Kg_7AkFeieedwGbcJmvALDp2eK+6aKi0wOJA@mail.gmail.com>

Hi,

On Tue, Aug 18, 2015 at 1:47 AM, Mathieu Olivari <mathieu at codeaurora.org> wrote:
> QCOM platforms such as IPQ806x are using SMEM to store their flash
> layout. This patch set adds the DT nodes required to instanciate SMEM
> on IPQ806x and add an MTD parser using it.
>
> This change is based on the SMEM driver posted here:
> *https://lkml.org/lkml/2015/7/27/1125

Nice work. After testing it on AP148 I see this:

[    2.481507] 12 qcom-smem partitions found on MTD device qcom-nandc
[    2.481540] Creating 12 MTD partitions on "qcom-nandc":
[    2.486690] 0x000000000000-0x000000040000 : "0:SBL1"
[    2.492842] 0x000000040000-0x000000180000 : "0:MIBIB"
[    2.497857] 0x000000180000-0x0000002c0000 : "0:SBL2"
[    2.502895] 0x0000002c0000-0x000000540000 : "0:SBL3"
[    2.507828] 0x000000540000-0x000000660000 : "0:DDRCONFIG"
[    2.512857] 0x000000660000-0x000000780000 : "0:SSD"
[    2.518074] 0x000000780000-0x000000a00000 : "0:TZ"
[    2.522834] 0x000000a00000-0x000000c80000 : "0:RPM"
[    2.527607] 0x000000c80000-0x000001180000 : "0:APPSBL"
[    2.532472] 0x000001180000-0x000001200000 : "0:APPSBLENV"
[    2.537586] 0x000001200000-0x000001340000 : "0:ART"
[    2.543140] 0x000001340000-0x000005340000 : "rootfs"

Are all these partition names supposed to be prefixed with "0:"? This
is using the OpenWrt applied version.


Jonas


From gregory.clement at free-electrons.com  Tue Aug 18 05:36:13 2015
From: gregory.clement at free-electrons.com (Gregory CLEMENT)
Date: Tue, 18 Aug 2015 14:36:13 +0200
Subject: MUSB dual-role on AM335x behaving weirdly
In-Reply-To: <20150804193257.GF9623@saruman.tx.rr.com>
References: <CADYTM3Zk2iD8YMj75CoLJn=4kpoXoXEKUWj2QzdXKGCJjtfG2A@mail.gmail.com>
 <CADYTM3a1QWnec1D=wT=fgZ-RCXAx_qZYYoFg5gWOy0yT4vovHA@mail.gmail.com>
 <20150514212653.GC3338@piout.net>
 <CADYTM3baVqoEBdWoQb5JFyGR2_GKm1FHMYWST1YkZV=m=ZdycQ@mail.gmail.com>
 <20150526145118.GD26599@saruman.tx.rr.com> <20150527094205.GO3199@piout.net>
 <5594E56B.3040200@free-electrons.com>
 <CADYTM3ZF5m++N1NqmOJoH5agbYrzpvSbLnuLVgttxwzdzwmGwQ@mail.gmail.com>
 <55C0B954.3020106@free-electrons.com> <55C0CAC6.3020603@free-electrons.com>
 <20150804193257.GF9623@saruman.tx.rr.com>
Message-ID: <55D326BD.2030706@free-electrons.com>

Hi again Felipe,

I sent this email again without the capture because it prevented to be delivered
to the mailing lists.

On 04/08/2015 21:32, Felipe Balbi wrote:
> On Tue, Aug 04, 2015 at 04:23:02PM +0200, Gregory CLEMENT wrote:
>> Hi again,
>> On 04/08/2015 15:08, Gregory CLEMENT wrote:
>>> Hi Bin,
>>>
>>> On 02/07/2015 19:05, Bin Liu wrote:
>>>> Hi,
>>>>
>>>> On Thu, Jul 2, 2015 at 2:16 AM, Gregory CLEMENT
>>>> <gregory.clement at free-electrons.com> wrote:
>>>>> Hi Felipe,
>>>>>
>>>>> On 27/05/2015 11:42, Alexandre Belloni wrote:
>>>>>> Hi,
>>>>>>
>>>>>> On 26/05/2015 at 09:51:18 -0500, Felipe Balbi wrote :
>>>>>>> On Thu, May 14, 2015 at 04:36:33PM -0500, Bin Liu wrote:
>>>>>>>> Alexandre,
>>>>>>>>
>>>>>>>> On Thu, May 14, 2015 at 4:26 PM, Alexandre Belloni
>>>>>>>> <alexandre.belloni at free-electrons.com> wrote:
>>>>>>>>> On 14/05/2015 at 16:16:12 -0500, Bin Liu wrote :
>>>>>>>>>> I think I found the root cause of the problem: board design issue - I
>>>>>>>>>> bet the custom board has too much cap on VBUS line. It should be <
>>>>>>>>>> 10uF.
>>>>>>>>>>
>>>>>>>>>
>>>>>>>>> We have a custom board that exhibits the issue but it only has a 100nF
>>>>>>>>> cap on VBUS.
>>>>>>>>
>>>>>>>> Have you measured the VBUS discharging? Is there any way to share your
>>>>>>>> schematics?
>>>>>>>
>>>>>>> Alexandre, any further comments ?
>>>>>>>
>>>>>>
>>>>>> Yeah, I have just got more info.
>>>>>>
>>>>>> This is the relevant part of the schematic:
>>>>>> http://free-electrons.com/~alexandre/usb.png
>>>>>>
>>>>>> The total VBUS capacitance is 200nF and the USB0 pins are connected
>>>>>> directly to the AM3358 pins. U1 is actually not fitted.
>>>>>>
>>>>>> We didn't measure VBUS discharging but we observe the OTG pin sensing
>>>>>> stops when plugging an OTG cable without any device.
>>>>>
>>>>> Do you have any news about this topic?
>>>>>
>>>>>
>>>>> Is there something else that we can do to help solving this issue?
>>>>
>>>> In the case of CONFIG_USB_MUSB_DUAL_ROLE=y and dr_mode=otg, how is the
>>>> gadget driver configured? It has to be a module not built-in.
>>>
>>> Indeed when I configured CONFIG_USB_MUSB_HDRC=m and CONFIG_USB_MUSB_DSPS=m
>>> it worked seamless.
>>>
>>
>> Actually it didn't worked. And now sometimes I even received continuously
>> the following message:
>>
>>  musb_bus_suspend 2484: trying to suspend as a_wait_vfall while active
> 
> this is likely because your VBUS hasn't dropped below 0.8V fast enough.
> 
> I could only trigger this message in that situation. Use a scope to poke
> at VBUS and see how long is takes to reach 0.8V, this could all be cause
> by too much capacitance on VBUS line.

We got some news:
"The capacitance on VBUS due to components is 200nF and the additional parasitic
capacitance will be much smaller than this"

The rail discharge time is ~36ms when an USB drive is removed from the OTG adapter.
I attached a capture of this.

What do you think about these values?


However, "there appears to be a considerable delay between the removal of a usb
drive and the initiation of the VBUS discharge (maybe ~1 second, I wasn't able
to measure this time)."

Thanks,

Gregory

-- 
Gregory Clement, Free Electrons
Kernel, drivers, real-time and embedded Linux
development, consulting, training and support.
http://free-electrons.com



From will.deacon at arm.com  Tue Aug 18 05:44:48 2015
From: will.deacon at arm.com (Will Deacon)
Date: Tue, 18 Aug 2015 13:44:48 +0100
Subject: [PATCH V3] iommu/arm-smmu-v2: ThunderX mis-extends 64bit registers
In-Reply-To: <1439853235-12162-1-git-send-email-tchalamarla@caviumnetworks.com>
References: <1439853235-12162-1-git-send-email-tchalamarla@caviumnetworks.com>
Message-ID: <20150818124448.GA13507@arm.com>

Hi Tirumalesh,

On Tue, Aug 18, 2015 at 12:13:55AM +0100, tchalamarla at caviumnetworks.com wrote:
> From: Tirumalesh Chalamarla <tchalamarla at caviumnetworks.com>
> 
> The SMMU architecture defines two different behaviors when 64-bit
> registers are written with 32-bit writes.  The first behavior causes
> zero extension into the upper 32-bits.  The second behavior splits a
> 64-bit register into "normal" 32-bit register pairs.
> 
> On some buggy implementations, registers incorrectly zero extended
> when they should instead behave as normal 32-bit register pairs.
> 
> Signed-off-by: Tirumalesh Chalamarla <tchalamarla at caviumnetworks.com>
> 
> Changes from V2:
> 	- removed unused definitions
> 
> Changes from V1:
> 	- Introduced smmu_writeq
> ---
>  drivers/iommu/arm-smmu.c | 57 +++++++++++++++++++++++++-----------------------
>  1 file changed, 30 insertions(+), 27 deletions(-)

I'm happy with this, but it doesn't apply against mainline or my tree.
Please can you rebase it onto something more recent, preferably my
iommu/devel branch?

Thanks,

Will


From viresh.kumar at linaro.org  Tue Aug 18 05:56:42 2015
From: viresh.kumar at linaro.org (Viresh Kumar)
Date: Tue, 18 Aug 2015 18:26:42 +0530
Subject: [PATCH v2 0/6] ARM: berlin: add cpufreq support
In-Reply-To: <1439898368-11543-1-git-send-email-antoine.tenart@free-electrons.com>
References: <1439898368-11543-1-git-send-email-antoine.tenart@free-electrons.com>
Message-ID: <CAOh2x=ke9NWa-GjL=c+RgEWWfsNeKvE2O9CRHmW2dG5mj8ATCg@mail.gmail.com>

On Tue, Aug 18, 2015 at 5:16 PM, Antoine Tenart
<antoine.tenart at free-electrons.com> wrote:
> Hi,
>
> This series adds the cpufreq support to the Berlin SoCs, using
> cpufreq-dt.
>
> First, the cpuclk clock is added to the BG2Q clock driver. This clock
> has a divider fixed to 1, so we use a fixed factor clock here.
>
> Then register a platform device for cpufreq-dt.
>
> I also added the OPP table definition in the BG2Q, BG2 and BG2CD device
> trees. When using a BG2Q, some bootloaders may update this table when
> booting (mine doesn't).

You can switch to OPP-v2 bindings if you want. Just have a look, they are
much more powerful.. Should be in linux-next/master.


From srinivas.kandagatla at linaro.org  Tue Aug 18 06:04:29 2015
From: srinivas.kandagatla at linaro.org (Srinivas Kandagatla)
Date: Tue, 18 Aug 2015 14:04:29 +0100
Subject: [PATCH v2 0/6] DT: APQ8064 for qcom-dt-next
Message-ID: <1439903069-19752-1-git-send-email-srinivas.kandagatla@linaro.org>

Hi Andy,

Apologies for the long delay in sending new version of the patches.
Here are the new patches with fixes and dropping the MDP and panel
related changes.

Some dt patches which depend on pmic header
 "dt-bindings/pinctrl/qcom,pmic-gpio.h" which is availble in linux-next.


Changes since v1(https://lkml.org/lkml/2015/7/28/489)
 - Fixed style related errors spotted by Stephen and Bjorn
 - dropped mdp and Panel related DT, as it seems to go no where
  w.r.t cleaning up the driver.
 - Added few more patches for qs600 which are very trival.

 thanks,
 srini

Srinivas Kandagatla (6):
  ARM: dts: ifc6410: Add pwrseq support for WLAN
  ARM: dts: qs600: add pwrseq support to WLAN
  ARM: dts: apq8064-ifc6410: add notify led support.
  ARM: dts: qs600: remove unnecessary i2c pinctrl nodes in board file.
  ARM: dts: qs600: add alias to serial0
  ARM: dts: qs600: Add SD card detect support.

 arch/arm/boot/dts/qcom-apq8064-cm-qs600.dts | 46 +++++++++++++++++++++++--
 arch/arm/boot/dts/qcom-apq8064-ifc6410.dts  | 52 +++++++++++++++++++++++++++++
 2 files changed, 95 insertions(+), 3 deletions(-)

-- 
1.9.1



From srinivas.kandagatla at linaro.org  Tue Aug 18 06:06:52 2015
From: srinivas.kandagatla at linaro.org (Srinivas Kandagatla)
Date: Tue, 18 Aug 2015 14:06:52 +0100
Subject: [PATCH v2 1/6] ARM: dts: ifc6410: Add pwrseq support for WLAN
In-Reply-To: <1439903069-19752-1-git-send-email-srinivas.kandagatla@linaro.org>
References: <1439903069-19752-1-git-send-email-srinivas.kandagatla@linaro.org>
Message-ID: <1439903212-19931-1-git-send-email-srinivas.kandagatla@linaro.org>

This patch adds pwrseq for WLAN which resets the WLAN just before the
SDIO bus is up.

Signed-off-by: Srinivas Kandagatla <srinivas.kandagatla at linaro.org>
---
 arch/arm/boot/dts/qcom-apq8064-ifc6410.dts | 31 ++++++++++++++++++++++++++++++
 1 file changed, 31 insertions(+)

diff --git a/arch/arm/boot/dts/qcom-apq8064-ifc6410.dts b/arch/arm/boot/dts/qcom-apq8064-ifc6410.dts
index 88d6655..b1f9ddb 100644
--- a/arch/arm/boot/dts/qcom-apq8064-ifc6410.dts
+++ b/arch/arm/boot/dts/qcom-apq8064-ifc6410.dts
@@ -1,5 +1,6 @@
 #include "qcom-apq8064-v2.0.dtsi"
 #include <dt-bindings/gpio/gpio.h>
+#include <dt-bindings/pinctrl/qcom,pmic-gpio.h>
 
 / {
 	model = "Qualcomm APQ8064/IFC6410";
@@ -10,6 +11,20 @@
 		serial1 = &gsbi6_serial;
 	};
 
+	pwrseq {
+		#address-cells = <1>;
+		#size-cells = <1>;
+		ranges;
+		compatible = "simple-bus";
+
+		sdcc4_pwrseq: sdcc4_pwrseq {
+			pinctrl-names = "default";
+			pinctrl-0 = <&wlan_default_gpios>;
+			compatible = "mmc-pwrseq-simple";
+			reset-gpios = <&pm8921_gpio 43 GPIO_ACTIVE_LOW>;
+		};
+	};
+
 	soc {
 		pinctrl at 800000 {
 			card_detect: card_detect {
@@ -206,6 +221,21 @@
 			status = "okay";
 		};
 
+		qcom,ssbi at 500000 {
+			pmic at 0 {
+				gpio at 150 {
+					wlan_default_gpios: wlan-gpios {
+						pios {
+							pins = "gpio43";
+							function = "normal";
+							bias-disable;
+							power-source = <PM8921_GPIO_S4>;
+						};
+					};
+				};
+			};
+		};
+
 		amba {
 			/* eMMC */
 			sdcc1: sdcc at 12400000 {
@@ -227,6 +257,7 @@
 				status = "okay";
 				vmmc-supply = <&ext_3p3v>;
 				vqmmc-supply = <&pm8921_lvs1>;
+				mmc-pwrseq = <&sdcc4_pwrseq>;
 			};
 		};
 	};
-- 
1.9.1



From srinivas.kandagatla at linaro.org  Tue Aug 18 06:10:01 2015
From: srinivas.kandagatla at linaro.org (Srinivas Kandagatla)
Date: Tue, 18 Aug 2015 14:10:01 +0100
Subject: [PATCH v2 2/6] ARM: dts: qs600: add pwrseq support to WLAN
In-Reply-To: <1439903069-19752-1-git-send-email-srinivas.kandagatla@linaro.org>
References: <1439903069-19752-1-git-send-email-srinivas.kandagatla@linaro.org>
Message-ID: <1439903401-20189-1-git-send-email-srinivas.kandagatla@linaro.org>

Add pwrseq support to sdcc4 which would enable a proper reset of WLAN
without ugly hacks in the board support file.

Signed-off-by: Srinivas Kandagatla <srinivas.kandagatla at linaro.org>
---
 arch/arm/boot/dts/qcom-apq8064-cm-qs600.dts | 32 +++++++++++++++++++++++++++++
 1 file changed, 32 insertions(+)

diff --git a/arch/arm/boot/dts/qcom-apq8064-cm-qs600.dts b/arch/arm/boot/dts/qcom-apq8064-cm-qs600.dts
index 34ccb26..ebde2b7 100644
--- a/arch/arm/boot/dts/qcom-apq8064-cm-qs600.dts
+++ b/arch/arm/boot/dts/qcom-apq8064-cm-qs600.dts
@@ -1,9 +1,25 @@
 #include "qcom-apq8064-v2.0.dtsi"
+#include <dt-bindings/gpio/gpio.h>
+#include <dt-bindings/pinctrl/qcom,pmic-gpio.h>
 
 / {
 	model = "CompuLab CM-QS600";
 	compatible = "qcom,apq8064-cm-qs600", "qcom,apq8064";
 
+	pwrseq {
+		#address-cells = <1>;
+		#size-cells = <1>;
+		ranges;
+		compatible = "simple-bus";
+
+		sdcc4_pwrseq: sdcc4_pwrseq {
+			pinctrl-names = "default";
+			pinctrl-0 = <&wlan_default_gpios>;
+			compatible = "mmc-pwrseq-simple";
+			reset-gpios = <&pm8921_gpio 43 GPIO_ACTIVE_LOW>;
+		};
+	};
+
 	soc {
 		pinctrl at 800000 {
 			i2c1_pins: i2c1 {
@@ -155,6 +171,21 @@
 			regulator-always-on;
 		};
 
+		qcom,ssbi at 500000 {
+			pmic at 0 {
+				gpio at 150 {
+					wlan_default_gpios: wlan-gpios {
+						pios {
+							pins = "gpio43";
+							function = "normal";
+							bias-disable;
+							power-source = <PM8921_GPIO_S4>;
+						};
+					};
+				};
+			};
+		};
+
 		amba {
 			/* eMMC */
 			sdcc1: sdcc at 12400000 {
@@ -173,6 +204,7 @@
 				status = "okay";
 				vmmc-supply = <&v3p3_fixed>;
 				vqmmc-supply = <&v3p3_fixed>;
+				mmc-pwrseq = <&sdcc4_pwrseq>;
 			};
 		};
 	};
-- 
1.9.1



From srinivas.kandagatla at linaro.org  Tue Aug 18 06:10:09 2015
From: srinivas.kandagatla at linaro.org (Srinivas Kandagatla)
Date: Tue, 18 Aug 2015 14:10:09 +0100
Subject: [PATCH v2 3/6] ARM: dts: apq8064-ifc6410: add notify led support.
In-Reply-To: <1439903069-19752-1-git-send-email-srinivas.kandagatla@linaro.org>
References: <1439903069-19752-1-git-send-email-srinivas.kandagatla@linaro.org>
Message-ID: <1439903409-20233-1-git-send-email-srinivas.kandagatla@linaro.org>

This patch adds notify led support on IFC6410, whose trigger can be
configured from userspace.

Signed-off-by: Srinivas Kandagatla <srinivas.kandagatla at linaro.org>
---
 arch/arm/boot/dts/qcom-apq8064-ifc6410.dts | 21 +++++++++++++++++++++
 1 file changed, 21 insertions(+)

diff --git a/arch/arm/boot/dts/qcom-apq8064-ifc6410.dts b/arch/arm/boot/dts/qcom-apq8064-ifc6410.dts
index b1f9ddb..08daafe 100644
--- a/arch/arm/boot/dts/qcom-apq8064-ifc6410.dts
+++ b/arch/arm/boot/dts/qcom-apq8064-ifc6410.dts
@@ -221,6 +221,18 @@
 			status = "okay";
 		};
 
+		leds {
+			compatible = "gpio-leds";
+			pinctrl-names = "default";
+			pinctrl-0 = <&notify_led>;
+
+			led at 1 {
+				label = "apq8064:green:user1";
+				gpios = <&pm8921_gpio 18 GPIO_ACTIVE_HIGH>;
+				default-state = "on";
+			};
+		};
+
 		qcom,ssbi at 500000 {
 			pmic at 0 {
 				gpio at 150 {
@@ -232,6 +244,15 @@
 							power-source = <PM8921_GPIO_S4>;
 						};
 					};
+
+					notify_led: nled {
+						pios {
+							pins = "gpio18";
+							function = "normal";
+							bias-disable;
+							power-source = <PM8921_GPIO_S4>;
+						};
+					};
 				};
 			};
 		};
-- 
1.9.1



From srinivas.kandagatla at linaro.org  Tue Aug 18 06:10:19 2015
From: srinivas.kandagatla at linaro.org (Srinivas Kandagatla)
Date: Tue, 18 Aug 2015 14:10:19 +0100
Subject: [PATCH v2 4/6] ARM: dts: qs600: remove unnecessary i2c pinctrl nodes
 in board file.
In-Reply-To: <1439903069-19752-1-git-send-email-srinivas.kandagatla@linaro.org>
References: <1439903069-19752-1-git-send-email-srinivas.kandagatla@linaro.org>
Message-ID: <1439903419-20275-1-git-send-email-srinivas.kandagatla@linaro.org>

This patch removes unnecessary i2c pinctrl nodes in board file, these
are already defined in the soc specific file qcom-apq8064.dtsi.

Signed-off-by: Srinivas Kandagatla <srinivas.kandagatla at linaro.org>
---
 arch/arm/boot/dts/qcom-apq8064-cm-qs600.dts | 9 ---------
 1 file changed, 9 deletions(-)

diff --git a/arch/arm/boot/dts/qcom-apq8064-cm-qs600.dts b/arch/arm/boot/dts/qcom-apq8064-cm-qs600.dts
index ebde2b7..06b3a70 100644
--- a/arch/arm/boot/dts/qcom-apq8064-cm-qs600.dts
+++ b/arch/arm/boot/dts/qcom-apq8064-cm-qs600.dts
@@ -21,15 +21,6 @@
 	};
 
 	soc {
-		pinctrl at 800000 {
-			i2c1_pins: i2c1 {
-				mux {
-					pins = "gpio20", "gpio21";
-					function = "gsbi1";
-				};
-			};
-		};
-
 		rpm at 108000 {
 			regulators {
 				vin_lvs1_3_6-supply = <&pm8921_s4>;
-- 
1.9.1



From srinivas.kandagatla at linaro.org  Tue Aug 18 06:10:27 2015
From: srinivas.kandagatla at linaro.org (Srinivas Kandagatla)
Date: Tue, 18 Aug 2015 14:10:27 +0100
Subject: [PATCH v2 5/6] ARM: dts: qs600: add alias to serial0
In-Reply-To: <1439903069-19752-1-git-send-email-srinivas.kandagatla@linaro.org>
References: <1439903069-19752-1-git-send-email-srinivas.kandagatla@linaro.org>
Message-ID: <1439903427-20317-1-git-send-email-srinivas.kandagatla@linaro.org>

This patch add alias node with serial0.

Signed-off-by: Srinivas Kandagatla <srinivas.kandagatla at linaro.org>
---
 arch/arm/boot/dts/qcom-apq8064-cm-qs600.dts | 4 ++++
 1 file changed, 4 insertions(+)

diff --git a/arch/arm/boot/dts/qcom-apq8064-cm-qs600.dts b/arch/arm/boot/dts/qcom-apq8064-cm-qs600.dts
index 06b3a70..c095849 100644
--- a/arch/arm/boot/dts/qcom-apq8064-cm-qs600.dts
+++ b/arch/arm/boot/dts/qcom-apq8064-cm-qs600.dts
@@ -6,6 +6,10 @@
 	model = "CompuLab CM-QS600";
 	compatible = "qcom,apq8064-cm-qs600", "qcom,apq8064";
 
+	aliases {
+		serial0 = &gsbi7_serial;
+	};
+
 	pwrseq {
 		#address-cells = <1>;
 		#size-cells = <1>;
-- 
1.9.1



From srinivas.kandagatla at linaro.org  Tue Aug 18 06:10:37 2015
From: srinivas.kandagatla at linaro.org (Srinivas Kandagatla)
Date: Tue, 18 Aug 2015 14:10:37 +0100
Subject: [PATCH v2 6/6] ARM: dts: qs600: Add SD card detect support.
In-Reply-To: <1439903069-19752-1-git-send-email-srinivas.kandagatla@linaro.org>
References: <1439903069-19752-1-git-send-email-srinivas.kandagatla@linaro.org>
Message-ID: <1439903437-20360-1-git-send-email-srinivas.kandagatla@linaro.org>

This patch adds SD card detect support.

Signed-off-by: Srinivas Kandagatla <srinivas.kandagatla at linaro.org>
---
 arch/arm/boot/dts/qcom-apq8064-cm-qs600.dts | 13 +++++++++++++
 1 file changed, 13 insertions(+)

diff --git a/arch/arm/boot/dts/qcom-apq8064-cm-qs600.dts b/arch/arm/boot/dts/qcom-apq8064-cm-qs600.dts
index c095849..8c7bdc4 100644
--- a/arch/arm/boot/dts/qcom-apq8064-cm-qs600.dts
+++ b/arch/arm/boot/dts/qcom-apq8064-cm-qs600.dts
@@ -25,6 +25,16 @@
 	};
 
 	soc {
+		pinctrl at 800000 {
+			card_detect: card_detect {
+				mux {
+					pins = "gpio26";
+					function = "gpio";
+					bias-disable;
+				};
+			};
+		};
+
 		rpm at 108000 {
 			regulators {
 				vin_lvs1_3_6-supply = <&pm8921_s4>;
@@ -193,6 +203,9 @@
 			sdcc3: sdcc at 12180000 {
 				status = "okay";
 				vmmc-supply = <&v3p3_fixed>;
+				pinctrl-names	= "default";
+				pinctrl-0	= <&card_detect>;
+				cd-gpios	= <&tlmm_pinmux 26 GPIO_ACTIVE_LOW>;
 			};
 			/* WLAN */
 			sdcc4: sdcc at 121c0000 {
-- 
1.9.1



From leilk.liu at mediatek.com  Tue Aug 18 06:14:29 2015
From: leilk.liu at mediatek.com (lei liu)
Date: Tue, 18 Aug 2015 21:14:29 +0800
Subject: [PATCH] spi: mediatek: fix spi incorrect endian usage and
 remove redundant clock
In-Reply-To: <CAOiHx=nBOtm3c7QQpA-SSxXzJGjUEJQBtR9CynoeqsXRoz4fRg@mail.gmail.com>
References: <1439895231-17778-1-git-send-email-leilk.liu@mediatek.com>
 <CAOiHx=nBOtm3c7QQpA-SSxXzJGjUEJQBtR9CynoeqsXRoz4fRg@mail.gmail.com>
Message-ID: <1439903669.30929.2.camel@mhfsdcap03>

On Tue, 2015-08-18 at 14:19 +0200, Jonas Gorski wrote:
> Hi,
> 
> On Tue, Aug 18, 2015 at 12:53 PM, Leilk Liu <leilk.liu at mediatek.com> wrote:
> > This patch fixes incorrect endian usage, removes redundant
> > clock in prepare_hardware/unprepare_hardware and revises
> > coding styles.
> >
> > Signed-off-by: Leilk Liu <leilk.liu at mediatek.com>
> >
> > ---
> > Change in this patch:
> > 1. fix incorrect endian usage on big-endian system.
> > 2. delete redundant clock in prepare/unprepare_hardware.
> > 3. revise coding styles.
> 
> The usual philosophy is to have one change per patch, so this might be
> better as three patches. But this is Mark's call. Since the driver
> isn't yet in Linus' tree, it might be a-ok to mix style improvements
> and actual fixes, but as soon as it landed in Linus' tree you need to
> keep them separate, so fixes can be easily backported.
> 

OK, I'll divide this patch to three patches on next version.

> Regarding the content ...
> 
> > ---
> >  drivers/spi/spi-mt65xx.c                 | 163 +++++++++++++------------------
> >  include/linux/platform_data/spi-mt65xx.h |   2 -
> >  2 files changed, 69 insertions(+), 96 deletions(-)
> >
> > diff --git a/drivers/spi/spi-mt65xx.c b/drivers/spi/spi-mt65xx.c
> > index 519f50c..a9da887 100644
> > --- a/drivers/spi/spi-mt65xx.c
> > +++ b/drivers/spi/spi-mt65xx.c
> > @@ -694,6 +662,7 @@ static int mtk_spi_resume(struct device *dev)
> >         if (!pm_runtime_suspended(dev)) {
> >                 ret = clk_prepare_enable(mdata->spi_clk);
> >                 if (ret < 0)
> > +                       dev_err(dev, "failed to enable spi_clk (%d)\n", ret);
> >                         return ret;
> 
> You need to add braces here, else the "return ret" isn't covered by
> the if () anymore and you always return at this place.
> 
Yes.I'll fix it.

> >         }
> >
> > @@ -720,8 +689,14 @@ static int mtk_spi_runtime_resume(struct device *dev)
> >  {
> >         struct spi_master *master = dev_get_drvdata(dev);
> >         struct mtk_spi *mdata = spi_master_get_devdata(master);
> > +       int ret;
> > +
> > +       ret = clk_prepare_enable(mdata->spi_clk);
> > +       if (ret < 0)
> > +               dev_err(dev, "failed to enable spi_clk (%d)\n", ret);
> > +               return ret;
> 
> Same here. Although at least here it should be harmless, as
> clk_prepare_enable doesn't return > 0.
> 
Yes.I'll fix it too.
> >
> > -       return clk_prepare_enable(mdata->spi_clk);
> > +       return 0;
> >  }
> >  #endif /* CONFIG_PM */
> >
> 
> 
> Jonas




From balbi at ti.com  Tue Aug 18 07:13:34 2015
From: balbi at ti.com (Felipe Balbi)
Date: Tue, 18 Aug 2015 09:13:34 -0500
Subject: MUSB dual-role on AM335x behaving weirdly
In-Reply-To: <55D326BD.2030706@free-electrons.com>
References: <20150514212653.GC3338@piout.net>
 <CADYTM3baVqoEBdWoQb5JFyGR2_GKm1FHMYWST1YkZV=m=ZdycQ@mail.gmail.com>
 <20150526145118.GD26599@saruman.tx.rr.com>
 <20150527094205.GO3199@piout.net>
 <5594E56B.3040200@free-electrons.com>
 <CADYTM3ZF5m++N1NqmOJoH5agbYrzpvSbLnuLVgttxwzdzwmGwQ@mail.gmail.com>
 <55C0B954.3020106@free-electrons.com>
 <55C0CAC6.3020603@free-electrons.com>
 <20150804193257.GF9623@saruman.tx.rr.com>
 <55D326BD.2030706@free-electrons.com>
Message-ID: <20150818141334.GC9143@saruman.tx.rr.com>

Hi,

On Tue, Aug 18, 2015 at 02:36:13PM +0200, Gregory CLEMENT wrote:
> Hi again Felipe,
> 
> I sent this email again without the capture because it prevented to be delivered
> to the mailing lists.
> 
> On 04/08/2015 21:32, Felipe Balbi wrote:
> > On Tue, Aug 04, 2015 at 04:23:02PM +0200, Gregory CLEMENT wrote:
> >> Hi again,
> >> On 04/08/2015 15:08, Gregory CLEMENT wrote:
> >>> Hi Bin,
> >>>
> >>> On 02/07/2015 19:05, Bin Liu wrote:
> >>>> Hi,
> >>>>
> >>>> On Thu, Jul 2, 2015 at 2:16 AM, Gregory CLEMENT
> >>>> <gregory.clement at free-electrons.com> wrote:
> >>>>> Hi Felipe,
> >>>>>
> >>>>> On 27/05/2015 11:42, Alexandre Belloni wrote:
> >>>>>> Hi,
> >>>>>>
> >>>>>> On 26/05/2015 at 09:51:18 -0500, Felipe Balbi wrote :
> >>>>>>> On Thu, May 14, 2015 at 04:36:33PM -0500, Bin Liu wrote:
> >>>>>>>> Alexandre,
> >>>>>>>>
> >>>>>>>> On Thu, May 14, 2015 at 4:26 PM, Alexandre Belloni
> >>>>>>>> <alexandre.belloni at free-electrons.com> wrote:
> >>>>>>>>> On 14/05/2015 at 16:16:12 -0500, Bin Liu wrote :
> >>>>>>>>>> I think I found the root cause of the problem: board design issue - I
> >>>>>>>>>> bet the custom board has too much cap on VBUS line. It should be <
> >>>>>>>>>> 10uF.
> >>>>>>>>>>
> >>>>>>>>>
> >>>>>>>>> We have a custom board that exhibits the issue but it only has a 100nF
> >>>>>>>>> cap on VBUS.
> >>>>>>>>
> >>>>>>>> Have you measured the VBUS discharging? Is there any way to share your
> >>>>>>>> schematics?
> >>>>>>>
> >>>>>>> Alexandre, any further comments ?
> >>>>>>>
> >>>>>>
> >>>>>> Yeah, I have just got more info.
> >>>>>>
> >>>>>> This is the relevant part of the schematic:
> >>>>>> http://free-electrons.com/~alexandre/usb.png
> >>>>>>
> >>>>>> The total VBUS capacitance is 200nF and the USB0 pins are connected
> >>>>>> directly to the AM3358 pins. U1 is actually not fitted.
> >>>>>>
> >>>>>> We didn't measure VBUS discharging but we observe the OTG pin sensing
> >>>>>> stops when plugging an OTG cable without any device.
> >>>>>
> >>>>> Do you have any news about this topic?
> >>>>>
> >>>>>
> >>>>> Is there something else that we can do to help solving this issue?
> >>>>
> >>>> In the case of CONFIG_USB_MUSB_DUAL_ROLE=y and dr_mode=otg, how is the
> >>>> gadget driver configured? It has to be a module not built-in.
> >>>
> >>> Indeed when I configured CONFIG_USB_MUSB_HDRC=m and CONFIG_USB_MUSB_DSPS=m
> >>> it worked seamless.
> >>>
> >>
> >> Actually it didn't worked. And now sometimes I even received continuously
> >> the following message:
> >>
> >>  musb_bus_suspend 2484: trying to suspend as a_wait_vfall while active
> > 
> > this is likely because your VBUS hasn't dropped below 0.8V fast enough.
> > 
> > I could only trigger this message in that situation. Use a scope to poke
> > at VBUS and see how long is takes to reach 0.8V, this could all be cause
> > by too much capacitance on VBUS line.
> 
> We got some news:
> "The capacitance on VBUS due to components is 200nF and the additional parasitic
> capacitance will be much smaller than this"
> 
> The rail discharge time is ~36ms when an USB drive is removed from the OTG adapter.
> I attached a capture of this.
> 
> What do you think about these values?
> 
> 
> However, "there appears to be a considerable delay between the removal of a usb
> drive and the initiation of the VBUS discharge (maybe ~1 second, I wasn't able
> to measure this time)."

yeah, this is really weird. I can't think of anything that would make
VBUS discharge slower from a SW point of view. Once you remove the
cable, VBUS is physically removed and there's nothing else charging it.

-- 
balbi
-------------- next part --------------
A non-text attachment was scrubbed...
Name: signature.asc
Type: application/pgp-signature
Size: 819 bytes
Desc: Digital signature
URL: <http://lists.infradead.org/pipermail/linux-arm-kernel/attachments/20150818/9b51eeac/attachment.sig>

From stuart.yoder at freescale.com  Tue Aug 18 07:18:54 2015
From: stuart.yoder at freescale.com (Stuart Yoder)
Date: Tue, 18 Aug 2015 14:18:54 +0000
Subject: [PATCH 0/2] arm64: ignore memory outside of the linear range
In-Reply-To: <1439890482-20798-1-git-send-email-ard.biesheuvel@linaro.org>
References: <1439890482-20798-1-git-send-email-ard.biesheuvel@linaro.org>
Message-ID: <CY1PR0301MB0748FC71E6866C8AFACAAFF687780@CY1PR0301MB0748.namprd03.prod.outlook.com>



> -----Original Message-----
> From: Ard Biesheuvel [mailto:ard.biesheuvel at linaro.org]
> Sent: Tuesday, August 18, 2015 4:35 AM
> To: linux-arm-kernel at lists.infradead.org; mark.rutland at arm.com; catalin.marinas at arm.com; robh at kernel.org
> Cc: grant.likely at linaro.org; Yoder Stuart-B08248; will.deacon at arm.com; Ard Biesheuvel
> Subject: [PATCH 0/2] arm64: ignore memory outside of the linear range
> 
> This is a followup to the single patch I posted on Aug 15th to ignore
> RAM that cannot be covered by the linear mapping. Instead of clipping
> the memory after the fact, this clips the memory before installing the
> regions into the memblock memory table.
> 
> This is basically the approach that Mark Rutland suggested here
> 
> http://article.gmane.org/gmane.linux.ports.arm.kernel/430239
> 
> but modified to correctly consider the base of the kernel image as the
> start of the linear mapping.
> 
> Ard Biesheuvel (2):
>   of/fdt: make memblock maximum physical address arch configurable
>   arm64: set MAX_MEMBLOCK_ADDR according to linear region size
> 
>  arch/arm64/include/asm/memory.h |  8 ++++++++
>  drivers/of/fdt.c                | 12 +++++++-----
>  2 files changed, 15 insertions(+), 5 deletions(-)

Tested on Freescale LS2085ARDB which has a split memory region
that triggers the bug.

Tested-by: Stuart Yoder <stuart.yoder at freescale.com>

Thanks,
Stuart


From catalin.marinas at arm.com  Tue Aug 18 07:24:36 2015
From: catalin.marinas at arm.com (Catalin Marinas)
Date: Tue, 18 Aug 2015 15:24:36 +0100
Subject: [PATCH 2/2] arm64: set MAX_MEMBLOCK_ADDR according to linear
 region size
In-Reply-To: <20150818100018.GA11021@arm.com>
References: <1439890482-20798-1-git-send-email-ard.biesheuvel@linaro.org>
 <1439890482-20798-3-git-send-email-ard.biesheuvel@linaro.org>
 <20150818100018.GA11021@arm.com>
Message-ID: <20150818142435.GC11571@e104818-lin.cambridge.arm.com>

On Tue, Aug 18, 2015 at 11:00:27AM +0100, Will Deacon wrote:
> On Tue, Aug 18, 2015 at 10:34:42AM +0100, Ard Biesheuvel wrote:
> > The linear region size of a 39-bit VA kernel is only 256 GB, which
> > may be insufficient to cover all of system RAM, even on platforms
> > that have much less than 256 GB of memory but which is laid out
> > very sparsely.
> > 
> > So make sure we clip the memory we will not be able to map before
> > installing it into the memblock memory table, by setting
> > MAX_MEMBLOCK_ADDR accordingly.
> > 
> > Signed-off-by: Ard Biesheuvel <ard.biesheuvel at linaro.org>
> > ---
> >  arch/arm64/include/asm/memory.h | 8 ++++++++
> >  1 file changed, 8 insertions(+)
> > 
> > diff --git a/arch/arm64/include/asm/memory.h b/arch/arm64/include/asm/memory.h
> > index f800d45ea226..44a59c20e773 100644
> > --- a/arch/arm64/include/asm/memory.h
> > +++ b/arch/arm64/include/asm/memory.h
> > @@ -114,6 +114,14 @@ extern phys_addr_t		memstart_addr;
> >  #define PHYS_OFFSET		({ memstart_addr; })
> >  
> >  /*
> > + * The maximum physical address that the linear direct mapping
> > + * of system RAM can cover. (PAGE_OFFSET can be interpreted as
> > + * a 2's complement signed quantity and negated to derive the
> > + * maximum size of the linear mapping.)
> > + */
> > +#define MAX_MEMBLOCK_ADDR	({ memstart_addr - PAGE_OFFSET - 1; })

With the current memory layout, this could also be __pa(~0UL). I guess
we could solve this with a single patch, though I'm not sure whether we
break other architectures:

diff --git a/drivers/of/fdt.c b/drivers/of/fdt.c
index 07496560e5b9..ff8a885d5ff0 100644
--- a/drivers/of/fdt.c
+++ b/drivers/of/fdt.c
@@ -967,7 +967,7 @@ int __init early_init_dt_scan_chosen(unsigned long node, const char *uname,
 }
 
 #ifdef CONFIG_HAVE_MEMBLOCK
-#define MAX_PHYS_ADDR	((phys_addr_t)~0)
+#define MAX_PHYS_ADDR	(__pa(~0UL))
 
 void __init __weak early_init_dt_add_memory_arch(u64 base, u64 size)
 {

> If we initialised memory_limit to this value and changed early_mem to
> use min (i.e. only restrict the limit further), would that avoid the
> need to change the of code?

Only that we can't initialise memory_limit statically since
memstart_addr is not constant. We would need to do this somewhere before
early_mem() is run (in setup_machine_fdt or immediately after it).

My point to Ard was that since we already do a sanity check on the
memblocks in early_init_dt_add_memory_arch() and ignore those below
PHYS_OFFSET, it makes sense to reuse the same function since it already
has all the logic in place and corresponding warnings. With a later
memblock limiting we would have to add extra printing to inform the
user.

-- 
Catalin


From ard.biesheuvel at linaro.org  Tue Aug 18 07:31:16 2015
From: ard.biesheuvel at linaro.org (Ard Biesheuvel)
Date: Tue, 18 Aug 2015 16:31:16 +0200
Subject: [PATCH 2/2] arm64: set MAX_MEMBLOCK_ADDR according to linear
 region size
In-Reply-To: <20150818142435.GC11571@e104818-lin.cambridge.arm.com>
References: <1439890482-20798-1-git-send-email-ard.biesheuvel@linaro.org>
 <1439890482-20798-3-git-send-email-ard.biesheuvel@linaro.org>
 <20150818100018.GA11021@arm.com>
 <20150818142435.GC11571@e104818-lin.cambridge.arm.com>
Message-ID: <CAKv+Gu_PaNjmAsajew1JN9zY348x4vUsCyYgTLSsyC4_ZgnTGw@mail.gmail.com>

On 18 August 2015 at 16:24, Catalin Marinas <catalin.marinas at arm.com> wrote:
> On Tue, Aug 18, 2015 at 11:00:27AM +0100, Will Deacon wrote:
>> On Tue, Aug 18, 2015 at 10:34:42AM +0100, Ard Biesheuvel wrote:
>> > The linear region size of a 39-bit VA kernel is only 256 GB, which
>> > may be insufficient to cover all of system RAM, even on platforms
>> > that have much less than 256 GB of memory but which is laid out
>> > very sparsely.
>> >
>> > So make sure we clip the memory we will not be able to map before
>> > installing it into the memblock memory table, by setting
>> > MAX_MEMBLOCK_ADDR accordingly.
>> >
>> > Signed-off-by: Ard Biesheuvel <ard.biesheuvel at linaro.org>
>> > ---
>> >  arch/arm64/include/asm/memory.h | 8 ++++++++
>> >  1 file changed, 8 insertions(+)
>> >
>> > diff --git a/arch/arm64/include/asm/memory.h b/arch/arm64/include/asm/memory.h
>> > index f800d45ea226..44a59c20e773 100644
>> > --- a/arch/arm64/include/asm/memory.h
>> > +++ b/arch/arm64/include/asm/memory.h
>> > @@ -114,6 +114,14 @@ extern phys_addr_t             memstart_addr;
>> >  #define PHYS_OFFSET                ({ memstart_addr; })
>> >
>> >  /*
>> > + * The maximum physical address that the linear direct mapping
>> > + * of system RAM can cover. (PAGE_OFFSET can be interpreted as
>> > + * a 2's complement signed quantity and negated to derive the
>> > + * maximum size of the linear mapping.)
>> > + */
>> > +#define MAX_MEMBLOCK_ADDR  ({ memstart_addr - PAGE_OFFSET - 1; })
>
> With the current memory layout, this could also be __pa(~0UL). I guess
> we could solve this with a single patch, though I'm not sure whether we
> break other architectures:
>

Every 32-bit DT arch with highmem, quite likely.


> diff --git a/drivers/of/fdt.c b/drivers/of/fdt.c
> index 07496560e5b9..ff8a885d5ff0 100644
> --- a/drivers/of/fdt.c
> +++ b/drivers/of/fdt.c
> @@ -967,7 +967,7 @@ int __init early_init_dt_scan_chosen(unsigned long node, const char *uname,
>  }
>
>  #ifdef CONFIG_HAVE_MEMBLOCK
> -#define MAX_PHYS_ADDR  ((phys_addr_t)~0)
> +#define MAX_PHYS_ADDR  (__pa(~0UL))
>
>  void __init __weak early_init_dt_add_memory_arch(u64 base, u64 size)
>  {
>
>> If we initialised memory_limit to this value and changed early_mem to
>> use min (i.e. only restrict the limit further), would that avoid the
>> need to change the of code?
>
> Only that we can't initialise memory_limit statically since
> memstart_addr is not constant. We would need to do this somewhere before
> early_mem() is run (in setup_machine_fdt or immediately after it).
>
> My point to Ard was that since we already do a sanity check on the
> memblocks in early_init_dt_add_memory_arch() and ignore those below
> PHYS_OFFSET, it makes sense to reuse the same function since it already
> has all the logic in place and corresponding warnings. With a later
> memblock limiting we would have to add extra printing to inform the
> user.
>
> --
> Catalin


From ard.biesheuvel at linaro.org  Tue Aug 18 07:38:33 2015
From: ard.biesheuvel at linaro.org (Ard Biesheuvel)
Date: Tue, 18 Aug 2015 16:38:33 +0200
Subject: [PATCH 2/2] arm64: set MAX_MEMBLOCK_ADDR according to linear
 region size
In-Reply-To: <CAKv+Gu_PaNjmAsajew1JN9zY348x4vUsCyYgTLSsyC4_ZgnTGw@mail.gmail.com>
References: <1439890482-20798-1-git-send-email-ard.biesheuvel@linaro.org>
 <1439890482-20798-3-git-send-email-ard.biesheuvel@linaro.org>
 <20150818100018.GA11021@arm.com>
 <20150818142435.GC11571@e104818-lin.cambridge.arm.com>
 <CAKv+Gu_PaNjmAsajew1JN9zY348x4vUsCyYgTLSsyC4_ZgnTGw@mail.gmail.com>
Message-ID: <CAKv+Gu9y+E+=0dgdDL6BOwQ79SDqWQ13R-YnzxbHXFBuSbcJBw@mail.gmail.com>

On 18 August 2015 at 16:31, Ard Biesheuvel <ard.biesheuvel at linaro.org> wrote:
> On 18 August 2015 at 16:24, Catalin Marinas <catalin.marinas at arm.com> wrote:
>> On Tue, Aug 18, 2015 at 11:00:27AM +0100, Will Deacon wrote:
>>> On Tue, Aug 18, 2015 at 10:34:42AM +0100, Ard Biesheuvel wrote:
>>> > The linear region size of a 39-bit VA kernel is only 256 GB, which
>>> > may be insufficient to cover all of system RAM, even on platforms
>>> > that have much less than 256 GB of memory but which is laid out
>>> > very sparsely.
>>> >
>>> > So make sure we clip the memory we will not be able to map before
>>> > installing it into the memblock memory table, by setting
>>> > MAX_MEMBLOCK_ADDR accordingly.
>>> >
>>> > Signed-off-by: Ard Biesheuvel <ard.biesheuvel at linaro.org>
>>> > ---
>>> >  arch/arm64/include/asm/memory.h | 8 ++++++++
>>> >  1 file changed, 8 insertions(+)
>>> >
>>> > diff --git a/arch/arm64/include/asm/memory.h b/arch/arm64/include/asm/memory.h
>>> > index f800d45ea226..44a59c20e773 100644
>>> > --- a/arch/arm64/include/asm/memory.h
>>> > +++ b/arch/arm64/include/asm/memory.h
>>> > @@ -114,6 +114,14 @@ extern phys_addr_t             memstart_addr;
>>> >  #define PHYS_OFFSET                ({ memstart_addr; })
>>> >
>>> >  /*
>>> > + * The maximum physical address that the linear direct mapping
>>> > + * of system RAM can cover. (PAGE_OFFSET can be interpreted as
>>> > + * a 2's complement signed quantity and negated to derive the
>>> > + * maximum size of the linear mapping.)
>>> > + */
>>> > +#define MAX_MEMBLOCK_ADDR  ({ memstart_addr - PAGE_OFFSET - 1; })
>>
>> With the current memory layout, this could also be __pa(~0UL). I guess
>> we could solve this with a single patch, though I'm not sure whether we
>> break other architectures:
>>
>
> Every 32-bit DT arch with highmem, quite likely.
>

I mean (L)PAE, of course

>
>> diff --git a/drivers/of/fdt.c b/drivers/of/fdt.c
>> index 07496560e5b9..ff8a885d5ff0 100644
>> --- a/drivers/of/fdt.c
>> +++ b/drivers/of/fdt.c
>> @@ -967,7 +967,7 @@ int __init early_init_dt_scan_chosen(unsigned long node, const char *uname,
>>  }
>>
>>  #ifdef CONFIG_HAVE_MEMBLOCK
>> -#define MAX_PHYS_ADDR  ((phys_addr_t)~0)
>> +#define MAX_PHYS_ADDR  (__pa(~0UL))
>>
>>  void __init __weak early_init_dt_add_memory_arch(u64 base, u64 size)
>>  {
>>
>>> If we initialised memory_limit to this value and changed early_mem to
>>> use min (i.e. only restrict the limit further), would that avoid the
>>> need to change the of code?
>>
>> Only that we can't initialise memory_limit statically since
>> memstart_addr is not constant. We would need to do this somewhere before
>> early_mem() is run (in setup_machine_fdt or immediately after it).
>>
>> My point to Ard was that since we already do a sanity check on the
>> memblocks in early_init_dt_add_memory_arch() and ignore those below
>> PHYS_OFFSET, it makes sense to reuse the same function since it already
>> has all the logic in place and corresponding warnings. With a later
>> memblock limiting we would have to add extra printing to inform the
>> user.
>>
>> --
>> Catalin


From antoine.tenart at free-electrons.com  Tue Aug 18 07:39:11 2015
From: antoine.tenart at free-electrons.com (Antoine Tenart)
Date: Tue, 18 Aug 2015 16:39:11 +0200
Subject: [PATCH v2 0/6] ARM: berlin: add cpufreq support
In-Reply-To: <CAOh2x=ke9NWa-GjL=c+RgEWWfsNeKvE2O9CRHmW2dG5mj8ATCg@mail.gmail.com>
References: <1439898368-11543-1-git-send-email-antoine.tenart@free-electrons.com>
 <CAOh2x=ke9NWa-GjL=c+RgEWWfsNeKvE2O9CRHmW2dG5mj8ATCg@mail.gmail.com>
Message-ID: <20150818143911.GB12017@kwain>

Hi,

On Tue, Aug 18, 2015 at 06:26:42PM +0530, Viresh Kumar wrote:
> On Tue, Aug 18, 2015 at 5:16 PM, Antoine Tenart
> <antoine.tenart at free-electrons.com> wrote:
> >
> > This series adds the cpufreq support to the Berlin SoCs, using
> > cpufreq-dt.
> >
> > First, the cpuclk clock is added to the BG2Q clock driver. This clock
> > has a divider fixed to 1, so we use a fixed factor clock here.
> >
> > Then register a platform device for cpufreq-dt.
> >
> > I also added the OPP table definition in the BG2Q, BG2 and BG2CD device
> > trees. When using a BG2Q, some bootloaders may update this table when
> > booting (mine doesn't).
> 
> You can switch to OPP-v2 bindings if you want. Just have a look, they are
> much more powerful.. Should be in linux-next/master.

Nice!

However, it seems the OPP-v2 table takes precedence over the old one.
When a default OPP-v2 table is supplied in the device tree, if the
bootloader supplies an OPP table the old way it won't be taken into
account.

So if I understood correctly, this won't work here for the BG2Q.

Antoine

-- 
Antoine T?nart, Free Electrons
Embedded Linux, Kernel and Android engineering
http://free-electrons.com


From balbi at ti.com  Tue Aug 18 07:43:47 2015
From: balbi at ti.com (Felipe Balbi)
Date: Tue, 18 Aug 2015 09:43:47 -0500
Subject: [PATCH v3] i2c: omap: improve duty cycle on SCL
In-Reply-To: <CAFqkuUbO1CZ8bu8g8O7SsLF-0nUV274GZ08=6J1sVS4Foy+_EA@mail.gmail.com>
References: <1434569475-17378-1-git-send-email-balbi@ti.com>
 <55827CD7.7030207@nokia.com>
 <20150618172558.GC27790@saruman.tx.rr.com>
 <20150709194241.GF4744@katana>
 <20150710172714.GC20408@saruman.tx.rr.com>
 <20150813143651.GG27560@saruman.tx.rr.com>
 <CAFqkuUbO1CZ8bu8g8O7SsLF-0nUV274GZ08=6J1sVS4Foy+_EA@mail.gmail.com>
Message-ID: <20150818144347.GD9143@saruman.tx.rr.com>

HI,

On Mon, Aug 17, 2015 at 06:28:11PM -0700, Matt Reimer wrote:
> This doesn't seem to work for higher speeds, like 2.6 MHz. hssclh and
> hsscll end up going negative.
> 
> My case is an OMAP3 trying to configure i2c1 at 2.6 MHz, on which it talks
> to TPS65950. I end up with the following values:
> 
>         SCLL 0x0000fd12 SCLH 0x0000fe13
> 
> The end result is that the high-speed part gets configured way too slow and
> so the OMAP3 can't talk to the TPS65950.

hmm, indeed. Seems like anything above 1MHz would have an issue. I'll
see what can be done there.

-- 
balbi
-------------- next part --------------
A non-text attachment was scrubbed...
Name: signature.asc
Type: application/pgp-signature
Size: 819 bytes
Desc: Digital signature
URL: <http://lists.infradead.org/pipermail/linux-arm-kernel/attachments/20150818/1ab4b88c/attachment.sig>

From m-karicheri2 at ti.com  Tue Aug 18 07:49:35 2015
From: m-karicheri2 at ti.com (Murali Karicheri)
Date: Tue, 18 Aug 2015 10:49:35 -0400
Subject: [PATCH] ARM: keystone: add a work around to handle asynchronous
 external abort
In-Reply-To: <20150818162858.42035da0@xhacker>
References: <1439320409-20084-1-git-send-email-m-karicheri2@ti.com>	<55CDF579.4050408@ti.com>	<20150814140934.GX7557@n2100.arm.linux.org.uk>	<55CE05EC.4040909@oracle.com>	<55CE633C.10402@ti.com>	<20150814215617.GA7557@n2100.arm.linux.org.uk>	<55D25C64.3090107@ti.com>	<55D2A1DD.9000007@oracle.com>	<20150818081334.GK7557@n2100.arm.linux.org.uk>
 <20150818162858.42035da0@xhacker>
Message-ID: <55D345FF.3010707@ti.com>

On 08/18/2015 04:28 AM, Jisheng Zhang wrote:
> On Tue, 18 Aug 2015 09:13:34 +0100
> Russell King - ARM Linux <linux at arm.linux.org.uk> wrote:
>
>> On Mon, Aug 17, 2015 at 08:09:17PM -0700, santosh.shilimkar at oracle.com wrote:
>>>  From the logs this seems to be mostly clock related issue for some
>>> peripheral. If the bootloader clock enable all hack still exists,
>>> may be you can try that out.
>>>
>>> Another way to debug this is to start disabling peripheral drivers
>>> from the kernel 1 by 1 and see if the issue goes away.
>>
>> Highly unlikely to make any difference.  As the failure happens soo early
>> with the patch applied, the kernel hasn't had much of a chance to touch
>> the hardware - about the only things are the decompressor and the kernel
>> touching the early console.  As they seem to be working, it suggests
>> that's not the cause.
>>
>> It seems to be pointing towards something in the boot loader...
>>
>> Normally, uboot will hook itself into the vectors to report errors, but
>> I wonder whether uboot enables asynchronous aborts while it's running.
>> Don't forget to make sure that the aborts are disabled again prior to
>> calling the kernel.
>>
>
> Another possible cause: trustzone software.
>
> we root caused such kind of asynchronous external abort on Marvell Berlin SoCs
> to a trustzone bug. I'm not sure whether keystone linux is running at normal
> world or not.
Yes, in normal world (Non secure supervisor)
>


-- 
Murali Karicheri
Linux Kernel, Keystone


From linux at arm.linux.org.uk  Tue Aug 18 07:51:49 2015
From: linux at arm.linux.org.uk (Russell King - ARM Linux)
Date: Tue, 18 Aug 2015 15:51:49 +0100
Subject: [PATCH 2/2] arm64: set MAX_MEMBLOCK_ADDR according to linear
 region size
In-Reply-To: <20150818142435.GC11571@e104818-lin.cambridge.arm.com>
References: <1439890482-20798-1-git-send-email-ard.biesheuvel@linaro.org>
 <1439890482-20798-3-git-send-email-ard.biesheuvel@linaro.org>
 <20150818100018.GA11021@arm.com>
 <20150818142435.GC11571@e104818-lin.cambridge.arm.com>
Message-ID: <20150818145149.GQ7557@n2100.arm.linux.org.uk>

On Tue, Aug 18, 2015 at 03:24:36PM +0100, Catalin Marinas wrote:
> With the current memory layout, this could also be __pa(~0UL). I guess
> we could solve this with a single patch, though I'm not sure whether we
> break other architectures:

No.  __pa() is only valid within the lowmem mapping, not outside of it.
What you'd get for a virtual address of ~0UL is not well defined, so
you should not use this in generic code.

-- 
FTTC broadband for 0.8mile line: currently at 10.5Mbps down 400kbps up
according to speedtest.net.


From viresh.kumar at linaro.org  Tue Aug 18 07:59:25 2015
From: viresh.kumar at linaro.org (Viresh Kumar)
Date: Tue, 18 Aug 2015 20:29:25 +0530
Subject: [PATCH v2 0/6] ARM: berlin: add cpufreq support
In-Reply-To: <20150818143911.GB12017@kwain>
References: <1439898368-11543-1-git-send-email-antoine.tenart@free-electrons.com>
 <CAOh2x=ke9NWa-GjL=c+RgEWWfsNeKvE2O9CRHmW2dG5mj8ATCg@mail.gmail.com>
 <20150818143911.GB12017@kwain>
Message-ID: <20150818145925.GF31148@linux>

On 18-08-15, 16:39, Antoine Tenart wrote:
> However, it seems the OPP-v2 table takes precedence over the old one.
> When a default OPP-v2 table is supplied in the device tree, if the
> bootloader supplies an OPP table the old way it won't be taken into
> account.
> 
> So if I understood correctly, this won't work here for the BG2Q.

Didn't understood it completely. Are you saying that your dtb will
have two operating-points tables ?

The deal is that for any device, parsing of opp-v2 will be attempted
first. If its not available, then opp-v1 will be tried. But this is
per-device. So, one device can have opp-v2 tables and other one can do
v1 type.

-- 
viresh


From maxime.ripard at free-electrons.com  Tue Aug 18 08:32:08 2015
From: maxime.ripard at free-electrons.com (Maxime Ripard)
Date: Tue, 18 Aug 2015 17:32:08 +0200
Subject: [PATCH v2] ARM: dts: sunxi: Add regulators for LeMaker BananaPi
In-Reply-To: <20150804090224.4B5676C83963@dd34104.kasserver.com>
References: <1438532305-5884-1-git-send-email-public_timo.s@silentcreek.de>
 <20150803094723.GD2564@lukather>
 <20150804090224.4B5676C83963@dd34104.kasserver.com>
Message-ID: <20150818153208.GF2547@lukather>

On Tue, Aug 04, 2015 at 11:02:24AM +0200, Timo Sigurdsson wrote:
> Hi Maxime,
> 
> Maxime Ripard schrieb am 03.08.2015 11:47:
> > What regulator provides the 3.3V regulator used in the rest of this DT
> > then (MMC, GMAC) ?
> 
> For GMAC, there is a reg_gmac_3v3 defined in sun7i-a20-bananapi.dts [1].
> MMC uses reg_vcc3v3 included from sunxi-common-regulators.dtsi. Am I
> missing something? Is this not sufficient?

Well, this 3.3v regulator doesn't appear out of nowhere. Most likely,
it's either one of the AXP output, or a regulator directly taking the
5v output of the DC plug.

Maxime

-- 
Maxime Ripard, Free Electrons
Embedded Linux, Kernel and Android engineering
http://free-electrons.com
-------------- next part --------------
A non-text attachment was scrubbed...
Name: signature.asc
Type: application/pgp-signature
Size: 819 bytes
Desc: Digital signature
URL: <http://lists.infradead.org/pipermail/linux-arm-kernel/attachments/20150818/d5790184/attachment.sig>

From maxime.ripard at free-electrons.com  Tue Aug 18 08:33:34 2015
From: maxime.ripard at free-electrons.com (Maxime Ripard)
Date: Tue, 18 Aug 2015 17:33:34 +0200
Subject: [linux-sunxi] Re: [PATCH v2] ARM: dts: sunxi: Add regulators for
 LeMaker BananaPi
In-Reply-To: <55BF688D.5010905@redhat.com>
References: <1438532305-5884-1-git-send-email-public_timo.s@silentcreek.de>
 <20150803094723.GD2564@lukather> <55BF688D.5010905@redhat.com>
Message-ID: <20150818153334.GG2547@lukather>

On Mon, Aug 03, 2015 at 03:11:41PM +0200, Hans de Goede wrote:
> Hi,
> 
> On 03-08-15 11:47, Maxime Ripard wrote:
> >On Sun, Aug 02, 2015 at 06:18:25PM +0200, Timo Sigurdsson wrote:
> >>sun7i-a20-bananapi.dts doesn't contain regulator nodes for the AXP209 PMU
> >>driver, so add them to allow for voltage-scaling with cpufreq-dt.
> >>
> >>Signed-off-by: Timo Sigurdsson <public_timo.s at silentcreek.de>
> >>---
> >>Changes since v1 (RFC):
> >>
> >>- Dropped the changes to the cpufreq operating points and renamed the patch
> >>accordingly
> >>- Limited the CPU voltage range so it doesn't exceed the SOC specifications
> >>---
> >>  arch/arm/boot/dts/sun7i-a20-bananapi.dts | 35 ++++++++++++++++++++++++++++----
> >>  1 file changed, 31 insertions(+), 4 deletions(-)
> >>
> >>diff --git a/arch/arm/boot/dts/sun7i-a20-bananapi.dts b/arch/arm/boot/dts/sun7i-a20-bananapi.dts
> >>index 9f7b472..74382f3 100644
> >>--- a/arch/arm/boot/dts/sun7i-a20-bananapi.dts
> >>+++ b/arch/arm/boot/dts/sun7i-a20-bananapi.dts
> >>@@ -92,6 +92,10 @@
> >>  	status = "okay";
> >>  };
> >>
> >>+&cpu0 {
> >>+	cpu-supply = <&reg_dcdc2>;
> >>+};
> >>+
> >>  &ehci0 {
> >>  	status = "okay";
> >>  };
> >>@@ -119,13 +123,9 @@
> >>  	status = "okay";
> >>
> >>  	axp209: pmic at 34 {
> >>-		compatible = "x-powers,axp209";
> >>  		reg = <0x34>;
> >>  		interrupt-parent = <&nmi_intc>;
> >>  		interrupts = <0 IRQ_TYPE_LEVEL_LOW>;
> >>-
> >>-		interrupt-controller;
> >>-		#interrupt-cells = <1>;
> >>  	};
> >>  };
> >>
> >>@@ -182,6 +182,33 @@
> >>  	};
> >>  };
> >>
> >>+#include "axp209.dtsi"
> >>+
> >>+&reg_dcdc2 {
> >>+	regulator-always-on;
> >>+	regulator-min-microvolt = <1000000>;
> >>+	regulator-max-microvolt = <1400000>;
> >>+	regulator-name = "vdd-cpu";
> >>+};
> >>+
> >>+&reg_dcdc3 {
> >>+	regulator-always-on;
> >>+	regulator-min-microvolt = <1000000>;
> >>+	regulator-max-microvolt = <1400000>;
> >>+	regulator-name = "vdd-int-dll";
> >>+};
> >>+
> >>+&reg_ldo1 {
> >>+	regulator-name = "vdd-rtc";
> >>+};
> >>+
> >>+&reg_ldo2 {
> >>+	regulator-always-on;
> >>+	regulator-min-microvolt = <3000000>;
> >>+	regulator-max-microvolt = <3000000>;
> >>+	regulator-name = "avcc";
> >>+};
> >
> >What regulator provides the 3.3V regulator used in the rest of this DT
> >then (MMC, GMAC) ?
> 
> A separate fixed regulator, like most (all?) other axp209 using boards,
> e.g. the cubieboard has a TCS4199 regulator for this, and the banana
> boards use a XL8206/UP1746 for this, according to the schematics I
> have.

Ack.

Thanks!
Maxime

-- 
Maxime Ripard, Free Electrons
Embedded Linux, Kernel and Android engineering
http://free-electrons.com
-------------- next part --------------
A non-text attachment was scrubbed...
Name: signature.asc
Type: application/pgp-signature
Size: 819 bytes
Desc: Digital signature
URL: <http://lists.infradead.org/pipermail/linux-arm-kernel/attachments/20150818/ece746e7/attachment.sig>

From maxime.ripard at free-electrons.com  Tue Aug 18 08:36:31 2015
From: maxime.ripard at free-electrons.com (Maxime Ripard)
Date: Tue, 18 Aug 2015 17:36:31 +0200
Subject: [PATCH v2] ARM: dts: sunxi: Add regulators for LeMaker BananaPi
In-Reply-To: <1438532305-5884-1-git-send-email-public_timo.s@silentcreek.de>
References: <1438532305-5884-1-git-send-email-public_timo.s@silentcreek.de>
Message-ID: <20150818153631.GH2547@lukather>

On Sun, Aug 02, 2015 at 06:18:25PM +0200, Timo Sigurdsson wrote:
> sun7i-a20-bananapi.dts doesn't contain regulator nodes for the AXP209 PMU
> driver, so add them to allow for voltage-scaling with cpufreq-dt.
> 
> Signed-off-by: Timo Sigurdsson <public_timo.s at silentcreek.de>

Queued, thanks!
Maxime

-- 
Maxime Ripard, Free Electrons
Embedded Linux, Kernel and Android engineering
http://free-electrons.com
-------------- next part --------------
A non-text attachment was scrubbed...
Name: signature.asc
Type: application/pgp-signature
Size: 819 bytes
Desc: Digital signature
URL: <http://lists.infradead.org/pipermail/linux-arm-kernel/attachments/20150818/0b35cc74/attachment.sig>

From jiang.liu at linux.intel.com  Tue Aug 18 08:45:55 2015
From: jiang.liu at linux.intel.com (Jiang Liu)
Date: Tue, 18 Aug 2015 23:45:55 +0800
Subject: [Bugfix] PCI: Fix a typo in file pcie-xilinx.c caused by commit
 e39758e0ea76
In-Reply-To: <CAErSpo6aryRYOJpfXfY6SuJoVe72MYd8RKgPhiDZ9pt5+zmXBQ@mail.gmail.com>
References: <CAErSpo6aryRYOJpfXfY6SuJoVe72MYd8RKgPhiDZ9pt5+zmXBQ@mail.gmail.com>
Message-ID: <1439912763-10645-1-git-send-email-jiang.liu@linux.intel.com>

There's a typo in commit e39758e0ea76 ("PCI: Use helper functions to access
fields in struct msi_desc") in linux-next, which incorrectly spells
"msi_desc_to_pci_sysdata()" as "msi_desc_to_pci_sys_data()" and causes
buidling failure:
> ../drivers/pci/host/pcie-xilinx.c:235:3: error: implicit declaration of function 'msi_desc_to_pci_sys_data' [-Werror=implicit-function-declaration]

Links: https://lkml.org/lkml/2015/7/9/100

Signed-off-by: Jiang Liu <jiang.liu at linux.intel.com>
---
 drivers/pci/host/pcie-xilinx.c |    2 +-
 1 file changed, 1 insertion(+), 1 deletion(-)

diff --git a/drivers/pci/host/pcie-xilinx.c b/drivers/pci/host/pcie-xilinx.c
index 64454f416639..be494e46bbd1 100644
--- a/drivers/pci/host/pcie-xilinx.c
+++ b/drivers/pci/host/pcie-xilinx.c
@@ -232,7 +232,7 @@ static void xilinx_pcie_destroy_msi(unsigned int irq)
 
 	if (!test_bit(irq, msi_irq_in_use)) {
 		msi = irq_get_msi_desc(irq);
-		port = sys_to_pcie(msi_desc_to_pci_sys_data(msi));
+		port = sys_to_pcie(msi_desc_to_pci_sysdata(msi));
 		dev_err(port->dev, "Trying to free unused MSI#%d\n", irq);
 	} else {
 		clear_bit(irq, msi_irq_in_use);
-- 
1.7.10.4



From fabio.estevam at freescale.com  Tue Aug 18 08:43:12 2015
From: fabio.estevam at freescale.com (Fabio Estevam)
Date: Tue, 18 Aug 2015 12:43:12 -0300
Subject: [PATCH] Revert "serial: imx: remove unbalanced clk_prepare"
Message-ID: <1439912592-14779-1-git-send-email-fabio.estevam@freescale.com>

This reverts commit 9e7b399d6528eac33a6fbfceb2b92af209c3454d.

Commit ("9e7b399d6528ea") causes the following warning and sometimes
also hangs the system:

------------[ cut here ]------------
 WARNING: CPU: 0 PID: 0 at kernel/locking/mutex.c:868 mutex_trylock+0x20c/0x22c()
 DEBUG_LOCKS_WARN_ON(in_interrupt())
 Modules linked in:
CPU: 0 PID: 0 Comm: swapper/0 Not tainted 4.2.0-rc7-next-20150818-00001-g14418a6 #4
Hardware name: Freescale i.MX6 Quad/DualLite (Device Tree)
Backtrace: 
[<80012f08>] (dump_backtrace) from [<800130a4>] (show_stack+0x18/0x1c)
r6:00000364 r5:00000000 r4:00000000 r3:00000000
[<8001308c>] (show_stack) from [<807902b8>] (dump_stack+0x88/0xa4)
[<80790230>] (dump_stack) from [<8002a604>] (warn_slowpath_common+0x80/0xbc)
r5:807945c4 r4:80ab3b50
[<8002a584>] (warn_slowpath_common) from [<8002a6e4>] (warn_slowpath_fmt+0x38/0x40)
r8:00000000 r7:8131100c r6:8054c3cc r5:8131300c r4:80b0a570
[<8002a6b0>] (warn_slowpath_fmt) from [<807945c4>] (mutex_trylock+0x20c/0x22c)
r3:8095d0d8 r2:8095ab28
[<807943b8>] (mutex_trylock) from [<8054c3cc>] (clk_prepare_lock+0x14/0xf4)
r7:8131100c r6:be3f0c80 r5:00000037 r4:be3f0c80
[<8054c3b8>] (clk_prepare_lock) from [<8054dbfc>] (clk_prepare+0x18/0x30)
r5:00000037 r4:be3f0c80
[<8054dbe4>] (clk_prepare) from [<8036a600>] (imx_console_write+0x30/0x244)
r4:812d0bc8 r3:8132b9a4

To reproduce the problem we only need to let the board idle for something
like 30 seconds.

Tested on a imx6q-sabresd.

Signed-off-by: Fabio Estevam <fabio.estevam at freescale.com>
---
 drivers/tty/serial/imx.c | 20 ++++++++++++++------
 1 file changed, 14 insertions(+), 6 deletions(-)

diff --git a/drivers/tty/serial/imx.c b/drivers/tty/serial/imx.c
index fe3d41c..d0388a0 100644
--- a/drivers/tty/serial/imx.c
+++ b/drivers/tty/serial/imx.c
@@ -1631,12 +1631,12 @@ imx_console_write(struct console *co, const char *s, unsigned int count)
 	int locked = 1;
 	int retval;
 
-	retval = clk_prepare_enable(sport->clk_per);
+	retval = clk_enable(sport->clk_per);
 	if (retval)
 		return;
-	retval = clk_prepare_enable(sport->clk_ipg);
+	retval = clk_enable(sport->clk_ipg);
 	if (retval) {
-		clk_disable_unprepare(sport->clk_per);
+		clk_disable(sport->clk_per);
 		return;
 	}
 
@@ -1675,8 +1675,8 @@ imx_console_write(struct console *co, const char *s, unsigned int count)
 	if (locked)
 		spin_unlock_irqrestore(&sport->port.lock, flags);
 
-	clk_disable_unprepare(sport->clk_ipg);
-	clk_disable_unprepare(sport->clk_per);
+	clk_disable(sport->clk_ipg);
+	clk_disable(sport->clk_per);
 }
 
 /*
@@ -1777,7 +1777,15 @@ imx_console_setup(struct console *co, char *options)
 
 	retval = uart_set_options(&sport->port, co, baud, parity, bits, flow);
 
-	clk_disable_unprepare(sport->clk_ipg);
+	clk_disable(sport->clk_ipg);
+	if (retval) {
+		clk_unprepare(sport->clk_ipg);
+		goto error_console;
+	}
+
+	retval = clk_prepare(sport->clk_per);
+	if (retval)
+		clk_disable_unprepare(sport->clk_ipg);
 
 error_console:
 	return retval;
-- 
1.9.1



From aalonso at freescale.com  Tue Aug 18 08:48:52 2015
From: aalonso at freescale.com (Adrian Alonso)
Date: Tue, 18 Aug 2015 10:48:52 -0500
Subject: [PATCH 1/8] ARM: imx: imx7d-pinfunc: add gpio1 pad iomux settings
Message-ID: <1439912939-17535-1-git-send-email-aalonso@freescale.com>

- Add imx7 SoC GPIO1 pad iomuxc settings
  <mux_reg conf_reg input_reg mux_mode input_val>
- Fix UART input select daisy chain setting values

Signed-off-by: Adrian Alonso <aalonso at freescale.com>
---
 arch/arm/boot/dts/imx7d-pinfunc.h | 122 +++++++++++++++++++++++++++++++++++++-
 1 file changed, 119 insertions(+), 3 deletions(-)

diff --git a/arch/arm/boot/dts/imx7d-pinfunc.h b/arch/arm/boot/dts/imx7d-pinfunc.h
index a8d8149..22f849c 100644
--- a/arch/arm/boot/dts/imx7d-pinfunc.h
+++ b/arch/arm/boot/dts/imx7d-pinfunc.h
@@ -15,6 +15,122 @@
  * <mux_reg conf_reg input_reg mux_mode input_val>
  */
 
+#define MX7D_PAD_GPIO1_IO00__GPIO1_IO0				  0x0000 0x0030 0x0000 0x0 0x0
+#define MX7D_PAD_GPIO1_IO00__PWM4_OUT				  0x0000 0x0030 0x0000 0x1 0x0
+#define MX7D_PAD_GPIO1_IO00__WDOD1_WDOG_ANY			  0x0000 0x0030 0x0000 0x2 0x0
+#define MX7D_PAD_GPIO1_IO00__WDOD1_WDOG_B			  0x0000 0x0030 0x0000 0x3 0x0
+#define MX7D_PAD_GPIO1_IO00__WDOD1_WDOG__RST_B_DEB		  0x0000 0x0030 0x0000 0x4 0x0
+#define MX7D_PAD_GPIO1_IO01__GPIO1_IO1				  0x0004 0x0034 0x0000 0x0 0x0
+#define MX7D_PAD_GPIO1_IO01__PWM1_OUT				  0x0004 0x0034 0x0000 0x1 0x0
+#define MX7D_PAD_GPIO1_IO01__CCM_ENET_REF_CLK3			  0x0004 0x0034 0x0000 0x2 0x0
+#define MX7D_PAD_GPIO1_IO01__SAI1_MCLK				  0x0004 0x0034 0x0000 0x3 0x0
+#define MX7D_PAD_GPIO1_IO01__ANATOP_24M_OUT			  0x0004 0x0034 0x0000 0x4 0x0
+#define MX7D_PAD_GPIO1_IO01__OBSERVE0_OUT			  0x0004 0x0034 0x0000 0x6 0x0
+#define MX7D_PAD_GPIO1_IO02__GPIO1_IO2				  0x0008 0x0038 0x0000 0x0 0x0
+#define MX7D_PAD_GPIO1_IO02__PWM2_OUT				  0x0008 0x0038 0x0000 0x1 0x0
+#define MX7D_PAD_GPIO1_IO02__CCM_ENET_REF_CLK1			  0x0008 0x0038 0x0564 0x2 0x3
+#define MX7D_PAD_GPIO1_IO02__SAI2_MCLK				  0x0008 0x0038 0x0000 0x3 0x0
+#define MX7D_PAD_GPIO1_IO02__CCM_CLKO1				  0x0008 0x0038 0x0000 0x5 0x0
+#define MX7D_PAD_GPIO1_IO02__OBSERVE1_OUT			  0x0008 0x0038 0x0000 0x6 0x0
+#define MX7D_PAD_GPIO1_IO02__USB_OTG1_ID			  0x0008 0x0038 0x0734 0x7 0x3
+#define MX7D_PAD_GPIO1_IO03__GPIO1_IO3				  0x000C 0x003C 0x0000 0x0 0x0
+#define MX7D_PAD_GPIO1_IO03__PWM3_OUT				  0x000C 0x003C 0x0000 0x1 0x0
+#define MX7D_PAD_GPIO1_IO03__CCM_ENET_REF_CLK2			  0x000C 0x003C 0x0570 0x2 0x3
+#define MX7D_PAD_GPIO1_IO03__SAI3_MCLK				  0x000C 0x003C 0x0000 0x3 0x0
+#define MX7D_PAD_GPIO1_IO03__CCM_CLKO2				  0x000C 0x003C 0x0000 0x5 0x0
+#define MX7D_PAD_GPIO1_IO03__OBSERVE2_OUT			  0x000C 0x003C 0x0000 0x6 0x0
+#define MX7D_PAD_GPIO1_IO03__USB_OTG2_ID			  0x000C 0x003C 0x0730 0x7 0x3
+#define MX7D_PAD_GPIO1_IO04__GPIO1_IO4				  0x0010 0x0040 0x0000 0x0 0x0
+#define MX7D_PAD_GPIO1_IO04__USB_OTG1_OC			  0x0010 0x0040 0x072C 0x1 0x1
+#define MX7D_PAD_GPIO1_IO04__FLEXTIMER1_CH4			  0x0010 0x0040 0x0594 0x2 0x1
+#define MX7D_PAD_GPIO1_IO04__UART5_CTS_B			  0x0010 0x0040 0x0710 0x3 0x4
+#define MX7D_PAD_GPIO1_IO04__I2C1_SCL				  0x0010 0x0040 0x05D4 0x4 0x2
+#define MX7D_PAD_GPIO1_IO04__OBSERVE3_OUT			  0x0010 0x0040 0x0000 0x6 0x0
+#define MX7D_PAD_GPIO1_IO05__GPIO1_IO5				  0x0014 0x0044 0x0000 0x0 0x0
+#define MX7D_PAD_GPIO1_IO05__USB_OTG1_PWR			  0x0014 0x0044 0x0000 0x1 0x0
+#define MX7D_PAD_GPIO1_IO05__FLEXTIMER1_CH5			  0x0014 0x0044 0x0598 0x2 0x1
+#define MX7D_PAD_GPIO1_IO05__UART5_RTS_B			  0x0014 0x0044 0x0710 0x3 0x5
+#define MX7D_PAD_GPIO1_IO05__I2C1_SDA				  0x0014 0x0044 0x05D8 0x4 0x2
+#define MX7D_PAD_GPIO1_IO05__OBSERVE4_OUT			  0x0014 0x0044 0x0000 0x6 0x0
+#define MX7D_PAD_GPIO1_IO06__GPIO1_IO6				  0x0018 0x0048 0x0000 0x0 0x0
+#define MX7D_PAD_GPIO1_IO06__USB_OTG2_OC			  0x0018 0x0048 0x0728 0x1 0x1
+#define MX7D_PAD_GPIO1_IO06__FLEXTIMER1_CH6			  0x0018 0x0048 0x059C 0x2 0x1
+#define MX7D_PAD_GPIO1_IO06__UART5_RX_DATA			  0x0018 0x0048 0x0714 0x3 0x4
+#define MX7D_PAD_GPIO1_IO06__I2C2_SCL				  0x0018 0x0048 0x05DC 0x4 0x2
+#define MX7D_PAD_GPIO1_IO06__CCM_WAIT				  0x0018 0x0048 0x0000 0x5 0x0
+#define MX7D_PAD_GPIO1_IO06__KPP_ROW4				  0x0018 0x0048 0x0624 0x6 0x1
+#define MX7D_PAD_GPIO1_IO07__GPIO1_IO7				  0x001C 0x004C 0x0000 0x0 0x0
+#define MX7D_PAD_GPIO1_IO07__USB_OTG2_PWR			  0x001C 0x004C 0x0000 0x1 0x0
+#define MX7D_PAD_GPIO1_IO07__FLEXTIMER1_CH7			  0x001C 0x004C 0x05A0 0x2 0x1
+#define MX7D_PAD_GPIO1_IO07__UART5_TX_DATA			  0x001C 0x004C 0x0714 0x3 0x5
+#define MX7D_PAD_GPIO1_IO07__I2C2_SDA				  0x001C 0x004C 0x05E0 0x4 0x2
+#define MX7D_PAD_GPIO1_IO07__CCM_STOP				  0x001C 0x004C 0x0000 0x5 0x0
+#define MX7D_PAD_GPIO1_IO07__KPP_COL4				  0x001C 0x004C 0x0604 0x6 0x1
+#define MX7D_PAD_GPIO1_IO08__GPIO1_IO8                            0x0014 0x026C 0x0000 0x0 0x0
+#define MX7D_PAD_GPIO1_IO08__SD1_VSELECT                          0x0014 0x026C 0x0000 0x1 0x0
+#define MX7D_PAD_GPIO1_IO08__WDOG1_WDOG_B                         0x0014 0x026C 0x0000 0x2 0x0
+#define MX7D_PAD_GPIO1_IO08__UART3_DCE_RX                         0x0014 0x026C 0x0704 0x3 0x0
+#define MX7D_PAD_GPIO1_IO08__UART3_DTE_TX                         0x0014 0x026C 0x0000 0x3 0x0
+#define MX7D_PAD_GPIO1_IO08__I2C3_SCL                             0x0014 0x026C 0x05E4 0x4 0x0
+#define MX7D_PAD_GPIO1_IO08__KPP_COL5                             0x0014 0x026C 0x0608 0x6 0x0
+#define MX7D_PAD_GPIO1_IO08__PWM1_OUT                             0x0014 0x026C 0x0000 0x7 0x0
+#define MX7D_PAD_GPIO1_IO09__GPIO1_IO9                            0x0018 0x0270 0x0000 0x0 0x0
+#define MX7D_PAD_GPIO1_IO09__SD1_LCTL                             0x0018 0x0270 0x0000 0x1 0x0
+#define MX7D_PAD_GPIO1_IO09__CCM_ENET_REF_CLK3                    0x0018 0x0270 0x0000 0x2 0x0
+#define MX7D_PAD_GPIO1_IO09__UART3_DCE_TX                         0x0018 0x0270 0x0000 0x3 0x0
+#define MX7D_PAD_GPIO1_IO09__UART3_DTE_RX                         0x0018 0x0270 0x0704 0x3 0x1
+#define MX7D_PAD_GPIO1_IO09__I2C3_SDA                             0x0018 0x0270 0x05E8 0x4 0x0
+#define MX7D_PAD_GPIO1_IO09__CCM_PMIC_READY                       0x0018 0x0270 0x04F4 0x5 0x0
+#define MX7D_PAD_GPIO1_IO09__KPP_ROW5                             0x0018 0x0270 0x0628 0x6 0x0
+#define MX7D_PAD_GPIO1_IO09__PWM2_OUT                             0x0018 0x0270 0x0000 0x7 0x0
+#define MX7D_PAD_GPIO1_IO10__GPIO1_IO10                           0x001C 0x0274 0x0000 0x0 0x0
+#define MX7D_PAD_GPIO1_IO10__SD2_LCTL                             0x001C 0x0274 0x0000 0x1 0x0
+#define MX7D_PAD_GPIO1_IO10__ENET1_MDIO                           0x001C 0x0274 0x0568 0x2 0x0
+#define MX7D_PAD_GPIO1_IO10__UART3_DCE_RTS                        0x001C 0x0274 0x0700 0x3 0x0
+#define MX7D_PAD_GPIO1_IO10__UART3_DTE_CTS                        0x001C 0x0274 0x0000 0x3 0x0
+#define MX7D_PAD_GPIO1_IO10__I2C4_SCL                             0x001C 0x0274 0x05EC 0x4 0x0
+#define MX7D_PAD_GPIO1_IO10__FLEXTIMER1_PHA                       0x001C 0x0274 0x05A4 0x5 0x0
+#define MX7D_PAD_GPIO1_IO10__KPP_COL6                             0x001C 0x0274 0x060C 0x6 0x0
+#define MX7D_PAD_GPIO1_IO10__PWM3_OUT                             0x001C 0x0274 0x0000 0x7 0x0
+#define MX7D_PAD_GPIO1_IO11__GPIO1_IO11                           0x0020 0x0278 0x0000 0x0 0x0
+#define MX7D_PAD_GPIO1_IO11__SD3_LCTL                             0x0020 0x0278 0x0000 0x1 0x0
+#define MX7D_PAD_GPIO1_IO11__ENET1_MDC                            0x0020 0x0278 0x0000 0x2 0x0
+#define MX7D_PAD_GPIO1_IO11__UART3_DCE_CTS                        0x0020 0x0278 0x0000 0x3 0x0
+#define MX7D_PAD_GPIO1_IO11__UART3_DTE_RTS                        0x0020 0x0278 0x0700 0x3 0x1
+#define MX7D_PAD_GPIO1_IO11__I2C4_SDA                             0x0020 0x0278 0x05F0 0x4 0x0
+#define MX7D_PAD_GPIO1_IO11__FLEXTIMER1_PHB                       0x0020 0x0278 0x05A8 0x5 0x0
+#define MX7D_PAD_GPIO1_IO11__KPP_ROW6                             0x0020 0x0278 0x062C 0x6 0x0
+#define MX7D_PAD_GPIO1_IO11__PWM4_OUT                             0x0020 0x0278 0x0000 0x7 0x0
+#define MX7D_PAD_GPIO1_IO12__GPIO1_IO12                           0x0024 0x027C 0x0000 0x0 0x0
+#define MX7D_PAD_GPIO1_IO12__SD2_VSELECT                          0x0024 0x027C 0x0000 0x1 0x0
+#define MX7D_PAD_GPIO1_IO12__CCM_ENET_REF_CLK1                    0x0024 0x027C 0x0564 0x2 0x0
+#define MX7D_PAD_GPIO1_IO12__FLEXCAN1_RX                          0x0024 0x027C 0x04DC 0x3 0x0
+#define MX7D_PAD_GPIO1_IO12__CM4_NMI                              0x0024 0x027C 0x0000 0x4 0x0
+#define MX7D_PAD_GPIO1_IO12__CCM_EXT_CLK1                         0x0024 0x027C 0x04E4 0x5 0x0
+#define MX7D_PAD_GPIO1_IO12__SNVS_VIO_5                           0x0024 0x027C 0x0000 0x6 0x0
+#define MX7D_PAD_GPIO1_IO12__USB_OTG1_ID                          0x0024 0x027C 0x0734 0x7 0x0
+#define MX7D_PAD_GPIO1_IO13__GPIO1_IO13                           0x0028 0x0280 0x0000 0x0 0x0
+#define MX7D_PAD_GPIO1_IO13__SD3_VSELECT                          0x0028 0x0280 0x0000 0x1 0x0
+#define MX7D_PAD_GPIO1_IO13__CCM_ENET_REF_CLK2                    0x0028 0x0280 0x0570 0x2 0x0
+#define MX7D_PAD_GPIO1_IO13__FLEXCAN1_TX                          0x0028 0x0280 0x0000 0x3 0x0
+#define MX7D_PAD_GPIO1_IO13__CCM_PMIC_READY                       0x0028 0x0280 0x04F4 0x4 0x1
+#define MX7D_PAD_GPIO1_IO13__CCM_EXT_CLK2                         0x0028 0x0280 0x04E8 0x5 0x0
+#define MX7D_PAD_GPIO1_IO13__SNVS_VIO_5_CTL                       0x0028 0x0280 0x0000 0x6 0x0
+#define MX7D_PAD_GPIO1_IO13__USB_OTG2_ID                          0x0028 0x0280 0x0730 0x7 0x0
+#define MX7D_PAD_GPIO1_IO14__GPIO1_IO14                           0x002C 0x0284 0x0000 0x0 0x0
+#define MX7D_PAD_GPIO1_IO14__SD3_CD_B                             0x002C 0x0284 0x0738 0x1 0x0
+#define MX7D_PAD_GPIO1_IO14__ENET2_MDIO                           0x002C 0x0284 0x0574 0x2 0x0
+#define MX7D_PAD_GPIO1_IO14__FLEXCAN2_RX                          0x002C 0x0284 0x04E0 0x3 0x0
+#define MX7D_PAD_GPIO1_IO14__WDOG3_WDOG_B                         0x002C 0x0284 0x0000 0x4 0x0
+#define MX7D_PAD_GPIO1_IO14__CCM_EXT_CLK3                         0x002C 0x0284 0x04EC 0x5 0x0
+#define MX7D_PAD_GPIO1_IO14__SDMA_EXT_EVENT0                      0x002C 0x0284 0x06D8 0x6 0x0
+#define MX7D_PAD_GPIO1_IO15__GPIO1_IO15                           0x0030 0x0288 0x0000 0x0 0x0
+#define MX7D_PAD_GPIO1_IO15__SD3_WP                               0x0030 0x0288 0x073C 0x1 0x0
+#define MX7D_PAD_GPIO1_IO15__ENET2_MDC                            0x0030 0x0288 0x0000 0x2 0x0
+#define MX7D_PAD_GPIO1_IO15__FLEXCAN2_TX                          0x0030 0x0288 0x0000 0x3 0x0
+#define MX7D_PAD_GPIO1_IO15__WDOG4_WDOG_B                         0x0030 0x0288 0x0000 0x4 0x0
+#define MX7D_PAD_GPIO1_IO15__CCM_EXT_CLK4                         0x0030 0x0288 0x04F0 0x5 0x0
+#define MX7D_PAD_GPIO1_IO15__SDMA_EXT_EVENT1                      0x0030 0x0288 0x06DC 0x6 0x0
 #define MX7D_PAD_EPDC_DATA00__EPDC_DATA0                          0x0034 0x02A4 0x0000 0x0 0x0
 #define MX7D_PAD_EPDC_DATA00__SIM1_PORT2_TRXD                     0x0034 0x02A4 0x0000 0x1 0x0
 #define MX7D_PAD_EPDC_DATA00__QSPI_A_DATA0                        0x0034 0x02A4 0x0000 0x2 0x0
@@ -453,7 +569,7 @@
 #define MX7D_PAD_LCD_DATA23__EIM_ADDR26                           0x0124 0x0394 0x0000 0x4 0x0
 #define MX7D_PAD_LCD_DATA23__GPIO3_IO28                           0x0124 0x0394 0x0000 0x5 0x0
 #define MX7D_PAD_LCD_DATA23__I2C4_SDA                             0x0124 0x0394 0x05F0 0x6 0x1
-#define MX7D_PAD_UART1_RX_DATA__UART1_DCE_RX                      0x0128 0x0398 0x0000 0x0 0x0
+#define MX7D_PAD_UART1_RX_DATA__UART1_DCE_RX                      0x0128 0x0398 0x06F4 0x0 0x0
 #define MX7D_PAD_UART1_RX_DATA__UART1_DTE_TX                      0x0128 0x0398 0x0000 0x0 0x0
 #define MX7D_PAD_UART1_RX_DATA__I2C1_SCL                          0x0128 0x0398 0x05D4 0x1 0x0
 #define MX7D_PAD_UART1_RX_DATA__CCM_PMIC_READY                    0x0128 0x0398 0x0000 0x2 0x0
@@ -469,7 +585,7 @@
 #define MX7D_PAD_UART1_TX_DATA__ENET2_1588_EVENT0_OUT             0x012C 0x039C 0x0000 0x4 0x0
 #define MX7D_PAD_UART1_TX_DATA__GPIO4_IO1                         0x012C 0x039C 0x0000 0x5 0x0
 #define MX7D_PAD_UART1_TX_DATA__ENET1_MDC                         0x012C 0x039C 0x0000 0x6 0x0
-#define MX7D_PAD_UART2_RX_DATA__UART2_DCE_RX                      0x0130 0x03A0 0x0000 0x0 0x0
+#define MX7D_PAD_UART2_RX_DATA__UART2_DCE_RX                      0x0130 0x03A0 0x06FC 0x0 0x2
 #define MX7D_PAD_UART2_RX_DATA__UART2_DTE_TX                      0x0130 0x03A0 0x0000 0x0 0x0
 #define MX7D_PAD_UART2_RX_DATA__I2C2_SCL                          0x0130 0x03A0 0x05DC 0x1 0x0
 #define MX7D_PAD_UART2_RX_DATA__SAI3_RX_BCLK                      0x0130 0x03A0 0x0000 0x2 0x0
@@ -501,7 +617,7 @@
 #define MX7D_PAD_UART3_TX_DATA__ENET1_1588_EVENT0_OUT             0x013C 0x03AC 0x0000 0x4 0x0
 #define MX7D_PAD_UART3_TX_DATA__GPIO4_IO5                         0x013C 0x03AC 0x0000 0x5 0x0
 #define MX7D_PAD_UART3_TX_DATA__SD2_LCTL                          0x013C 0x03AC 0x0000 0x6 0x0
-#define MX7D_PAD_UART3_RTS_B__UART3_DCE_RTS                       0x0140 0x03B0 0x0000 0x0 0x0
+#define MX7D_PAD_UART3_RTS_B__UART3_DCE_RTS                       0x0140 0x03B0 0x0700 0x0 0x2
 #define MX7D_PAD_UART3_RTS_B__UART3_DTE_CTS                       0x0140 0x03B0 0x0000 0x0 0x0
 #define MX7D_PAD_UART3_RTS_B__USB_OTG2_OC                         0x0140 0x03B0 0x0728 0x1 0x0
 #define MX7D_PAD_UART3_RTS_B__SAI3_TX_DATA0                       0x0140 0x03B0 0x0000 0x2 0x0
-- 
2.1.4



From aalonso at freescale.com  Tue Aug 18 08:48:53 2015
From: aalonso at freescale.com (Adrian Alonso)
Date: Tue, 18 Aug 2015 10:48:53 -0500
Subject: [PATCH 2/8] ARM: dts: imx: imx7d add iomuxc lpsr device node
In-Reply-To: <1439912939-17535-1-git-send-email-aalonso@freescale.com>
References: <1439912939-17535-1-git-send-email-aalonso@freescale.com>
Message-ID: <1439912939-17535-2-git-send-email-aalonso@freescale.com>

Add device tree node to support iomuxc-lpsr controller

Signed-off-by: Adrian Alonso <aalonso at freescale.com>
---
 arch/arm/boot/dts/imx7d.dtsi | 5 +++++
 1 file changed, 5 insertions(+)

diff --git a/arch/arm/boot/dts/imx7d.dtsi b/arch/arm/boot/dts/imx7d.dtsi
index b738ce0..00f70db 100644
--- a/arch/arm/boot/dts/imx7d.dtsi
+++ b/arch/arm/boot/dts/imx7d.dtsi
@@ -446,6 +446,11 @@
 				status = "disabled";
 			};
 
+			iomuxc_lpsr: iomuxc-lpsr at 302c0000 {
+				compatible = "fsl,imx7d-iomuxc-lpsr";
+				reg = <0x302c0000 0x10000>;
+			};
+
 			gpt1: gpt at 302d0000 {
 				compatible = "fsl,imx7d-gpt", "fsl,imx6sx-gpt";
 				reg = <0x302d0000 0x10000>;
-- 
2.1.4



From aalonso at freescale.com  Tue Aug 18 08:48:54 2015
From: aalonso at freescale.com (Adrian Alonso)
Date: Tue, 18 Aug 2015 10:48:54 -0500
Subject: [PATCH 3/8] ARM: dts: imx: imx7d-sbd add iomuxc-lpsr hoggrp-2 pads
In-Reply-To: <1439912939-17535-1-git-send-email-aalonso@freescale.com>
References: <1439912939-17535-1-git-send-email-aalonso@freescale.com>
Message-ID: <1439912939-17535-3-git-send-email-aalonso@freescale.com>

Add imx7d-sdb iomuxc-lpsr hoggrp-2 default pads settings

Signed-off-by: Adrian Alonso <aalonso at freescale.com>
---
 arch/arm/boot/dts/imx7d-sdb.dts | 15 +++++++++++++++
 1 file changed, 15 insertions(+)

diff --git a/arch/arm/boot/dts/imx7d-sdb.dts b/arch/arm/boot/dts/imx7d-sdb.dts
index fdd1d7c..63af4ea 100644
--- a/arch/arm/boot/dts/imx7d-sdb.dts
+++ b/arch/arm/boot/dts/imx7d-sdb.dts
@@ -406,3 +406,18 @@
 
 	};
 };
+
+&iomuxc_lpsr {
+	pinctrl-names = "default";
+	pinctrl-0 = <&pinctrl_hog_2>;
+
+	imx7d-sdb {
+		pinctrl_hog_2: hoggrp-2 {
+			fsl,pins = <
+				MX7D_PAD_GPIO1_IO05__GPIO1_IO5    0x14
+				MX7D_PAD_GPIO1_IO07__GPIO1_IO7    0x59
+				MX7D_PAD_GPIO1_IO00__WDOD1_WDOG_B 0x74
+			>;
+		};
+	};
+};
-- 
2.1.4



From aalonso at freescale.com  Tue Aug 18 08:48:55 2015
From: aalonso at freescale.com (Adrian Alonso)
Date: Tue, 18 Aug 2015 10:48:55 -0500
Subject: [PATCH 4/8] pinctrl: freescale: imx: add ZERO_OFFSET_VALID flag
In-Reply-To: <1439912939-17535-1-git-send-email-aalonso@freescale.com>
References: <1439912939-17535-1-git-send-email-aalonso@freescale.com>
Message-ID: <1439912939-17535-4-git-send-email-aalonso@freescale.com>

- Add ZERO_OFFSET_VALID flag, on imx7d mux_conf reg
  offset is zero for iomuxc-lspr controller
- Do default initialization on parse group function.

Signed-off-by: Adrian Alonso <aalonso at freescale.com>
---
 drivers/pinctrl/freescale/pinctrl-imx.c | 23 +++++++++++++----------
 drivers/pinctrl/freescale/pinctrl-imx.h |  1 +
 2 files changed, 14 insertions(+), 10 deletions(-)

diff --git a/drivers/pinctrl/freescale/pinctrl-imx.c b/drivers/pinctrl/freescale/pinctrl-imx.c
index d7b98ba..0440b0b 100644
--- a/drivers/pinctrl/freescale/pinctrl-imx.c
+++ b/drivers/pinctrl/freescale/pinctrl-imx.c
@@ -437,7 +437,7 @@ static void imx_pinconf_dbg_show(struct pinctrl_dev *pctldev,
 	const struct imx_pin_reg *pin_reg = &info->pin_regs[pin_id];
 	unsigned long config;
 
-	if (!pin_reg || pin_reg->conf_reg == -1) {
+	if (pin_reg->conf_reg == -1) {
 		seq_printf(s, "N/A");
 		return;
 	}
@@ -536,21 +536,29 @@ static int imx_pinctrl_parse_groups(struct device_node *np,
 		return -ENOMEM;
 
 	for (i = 0; i < grp->npins; i++) {
-		u32 mux_reg = be32_to_cpu(*list++);
+		u32 mux_reg;
 		u32 conf_reg;
 		unsigned int pin_id;
 		struct imx_pin_reg *pin_reg;
 		struct imx_pin *pin = &grp->pins[i];
 
+		mux_reg = be32_to_cpu(*list++);
+		if (!(info->flags & ZERO_OFFSET_VALID) && !mux_reg)
+			mux_reg = -1;
+
 		if (info->flags & SHARE_MUX_CONF_REG) {
 			conf_reg = mux_reg;
 		} else {
 			conf_reg = be32_to_cpu(*list++);
-			if (!conf_reg)
+			if (!(info->flags & ZERO_OFFSET_VALID) && !conf_reg)
 				conf_reg = -1;
 		}
 
-		pin_id = mux_reg ? mux_reg / 4 : conf_reg / 4;
+		if (info->flags & ZERO_OFFSET_VALID)
+			pin_id = mux_reg / 4;
+		else
+			pin_id = mux_reg ? mux_reg / 4 : conf_reg / 4;
+
 		pin_reg = &info->pin_regs[pin_id];
 		pin->pin = pin_id;
 		grp->pin_ids[i] = pin_id;
@@ -685,7 +693,7 @@ int imx_pinctrl_probe(struct platform_device *pdev,
 {
 	struct imx_pinctrl *ipctl;
 	struct resource *res;
-	int ret, i;
+	int ret;
 
 	if (!info || !info->pins || !info->npins) {
 		dev_err(&pdev->dev, "wrong pinctrl info\n");
@@ -703,11 +711,6 @@ int imx_pinctrl_probe(struct platform_device *pdev,
 	if (!info->pin_regs)
 		return -ENOMEM;
 
-	for (i = 0; i < info->npins; i++) {
-		info->pin_regs[i].mux_reg = -1;
-		info->pin_regs[i].conf_reg = -1;
-	}
-
 	res = platform_get_resource(pdev, IORESOURCE_MEM, 0);
 	ipctl->base = devm_ioremap_resource(&pdev->dev, res);
 	if (IS_ERR(ipctl->base))
diff --git a/drivers/pinctrl/freescale/pinctrl-imx.h b/drivers/pinctrl/freescale/pinctrl-imx.h
index 49e55d3..d22b8f6 100644
--- a/drivers/pinctrl/freescale/pinctrl-imx.h
+++ b/drivers/pinctrl/freescale/pinctrl-imx.h
@@ -84,6 +84,7 @@ struct imx_pinctrl_soc_info {
 };
 
 #define SHARE_MUX_CONF_REG	0x1
+#define ZERO_OFFSET_VALID	0x2
 
 #define NO_MUX		0x0
 #define NO_PAD		0x0
-- 
2.1.4



From aalonso at freescale.com  Tue Aug 18 08:48:56 2015
From: aalonso at freescale.com (Adrian Alonso)
Date: Tue, 18 Aug 2015 10:48:56 -0500
Subject: [PATCH 5/8] pinctrl: freescale: imx: add shared input select reg
 support
In-Reply-To: <1439912939-17535-1-git-send-email-aalonso@freescale.com>
References: <1439912939-17535-1-git-send-email-aalonso@freescale.com>
Message-ID: <1439912939-17535-5-git-send-email-aalonso@freescale.com>

- Add shared input select register support
- imx7d has two iomux controllers iomuxc and iomuxc-lpsr
  which share select_input register for daisy chain settings

Signed-off-by: Adrian Alonso <aalonso at freescale.com>
---
 drivers/pinctrl/freescale/pinctrl-imx.c | 28 +++++++++++++++++++++++++++-
 drivers/pinctrl/freescale/pinctrl-imx.h |  1 +
 2 files changed, 28 insertions(+), 1 deletion(-)

diff --git a/drivers/pinctrl/freescale/pinctrl-imx.c b/drivers/pinctrl/freescale/pinctrl-imx.c
index 0440b0b..1009b52 100644
--- a/drivers/pinctrl/freescale/pinctrl-imx.c
+++ b/drivers/pinctrl/freescale/pinctrl-imx.c
@@ -18,6 +18,7 @@
 #include <linux/module.h>
 #include <linux/of.h>
 #include <linux/of_device.h>
+#include <linux/of_address.h>
 #include <linux/pinctrl/machine.h>
 #include <linux/pinctrl/pinconf.h>
 #include <linux/pinctrl/pinctrl.h>
@@ -39,6 +40,7 @@ struct imx_pinctrl {
 	struct device *dev;
 	struct pinctrl_dev *pctl;
 	void __iomem *base;
+	void __iomem *input_sel_base;
 	const struct imx_pinctrl_soc_info *info;
 };
 
@@ -254,7 +256,12 @@ static int imx_pmx_set(struct pinctrl_dev *pctldev, unsigned selector,
 			 * Regular select input register can never be at offset
 			 * 0, and we only print register value for regular case.
 			 */
-			writel(pin->input_val, ipctl->base + pin->input_reg);
+			if (info->flags & SHARE_INPUT_SELECT_REG)
+				writel(pin->input_val, ipctl->input_sel_base +
+						pin->input_reg);
+			else
+				writel(pin->input_val, ipctl->base +
+						pin->input_reg);
 			dev_dbg(ipctl->dev,
 				"==>select_input: offset 0x%x val 0x%x\n",
 				pin->input_reg, pin->input_val);
@@ -691,6 +698,8 @@ static int imx_pinctrl_probe_dt(struct platform_device *pdev,
 int imx_pinctrl_probe(struct platform_device *pdev,
 		      struct imx_pinctrl_soc_info *info)
 {
+	struct device_node *dev_np = pdev->dev.of_node;
+	struct device_node *np;
 	struct imx_pinctrl *ipctl;
 	struct resource *res;
 	int ret;
@@ -716,6 +725,23 @@ int imx_pinctrl_probe(struct platform_device *pdev,
 	if (IS_ERR(ipctl->base))
 		return PTR_ERR(ipctl->base);
 
+	if (info->flags & SHARE_INPUT_SELECT_REG) {
+		np = of_get_child_by_name(dev_np->parent, "iomuxc");
+		if (np) {
+			ipctl->input_sel_base = of_iomap(np, 0);
+			if (IS_ERR(ipctl->input_sel_base)) {
+				of_node_put(np);
+				dev_err(&pdev->dev,
+				       "iomuxc base address not found\n");
+				return PTR_ERR(ipctl->input_sel_base);
+			}
+		} else {
+			dev_err(&pdev->dev, "iomuxc device node not foud\n");
+			return -EINVAL;
+		}
+		of_node_put(np);
+	}
+
 	imx_pinctrl_desc.name = dev_name(&pdev->dev);
 	imx_pinctrl_desc.pins = info->pins;
 	imx_pinctrl_desc.npins = info->npins;
diff --git a/drivers/pinctrl/freescale/pinctrl-imx.h b/drivers/pinctrl/freescale/pinctrl-imx.h
index d22b8f6..85c701b 100644
--- a/drivers/pinctrl/freescale/pinctrl-imx.h
+++ b/drivers/pinctrl/freescale/pinctrl-imx.h
@@ -85,6 +85,7 @@ struct imx_pinctrl_soc_info {
 
 #define SHARE_MUX_CONF_REG	0x1
 #define ZERO_OFFSET_VALID	0x2
+#define SHARE_INPUT_SELECT_REG	0x4
 
 #define NO_MUX		0x0
 #define NO_PAD		0x0
-- 
2.1.4



From aalonso at freescale.com  Tue Aug 18 08:48:57 2015
From: aalonso at freescale.com (Adrian Alonso)
Date: Tue, 18 Aug 2015 10:48:57 -0500
Subject: [PATCH 6/8] pinctrl: freescale: imx7d: support iomux lpsr controller
In-Reply-To: <1439912939-17535-1-git-send-email-aalonso@freescale.com>
References: <1439912939-17535-1-git-send-email-aalonso@freescale.com>
Message-ID: <1439912939-17535-6-git-send-email-aalonso@freescale.com>

iMX7D has two iomuxc controllers, iomuxc controller similar as
previous iMX SoC generation and iomuxc-lpsr which provides low
power state rentetion capabilities on gpios that are part of
iomuxc-lpsr

- Add iomuxc-lpsr gpio group id's
- Use flag ZERO_OFFSET_VALID and SHARE_INPUT_SELECT_REG to
  properly set pads from iomuxc-lpsr domain

Signed-off-by: Adrian Alonso <aalonso at freescale.com>
---
 drivers/pinctrl/freescale/pinctrl-imx7d.c | 27 +++++++++++++++++++++++++++
 1 file changed, 27 insertions(+)

diff --git a/drivers/pinctrl/freescale/pinctrl-imx7d.c b/drivers/pinctrl/freescale/pinctrl-imx7d.c
index 1fa7530..a347c22 100644
--- a/drivers/pinctrl/freescale/pinctrl-imx7d.c
+++ b/drivers/pinctrl/freescale/pinctrl-imx7d.c
@@ -172,6 +172,14 @@ enum imx7d_pads {
 	MX7D_PAD_ENET1_RX_CLK = 152,
 	MX7D_PAD_ENET1_CRS = 153,
 	MX7D_PAD_ENET1_COL = 154,
+	MX7D_PAD_GPIO1_IO00 = 0,
+	MX7D_PAD_GPIO1_IO01 = 1,
+	MX7D_PAD_GPIO1_IO02 = 2,
+	MX7D_PAD_GPIO1_IO03 = 3,
+	MX7D_PAD_GPIO1_IO04 = 4,
+	MX7D_PAD_GPIO1_IO05 = 5,
+	MX7D_PAD_GPIO1_IO06 = 6,
+	MX7D_PAD_GPIO1_IO07 = 7,
 };
 
 /* Pad names for the pinmux subsystem */
@@ -333,13 +341,32 @@ static const struct pinctrl_pin_desc imx7d_pinctrl_pads[] = {
 	IMX_PINCTRL_PIN(MX7D_PAD_ENET1_COL),
 };
 
+/* Pad names for the pinmux subsystem */
+static const struct pinctrl_pin_desc imx7d_lpsr_pinctrl_pads[] = {
+	IMX_PINCTRL_PIN(MX7D_PAD_GPIO1_IO00),
+	IMX_PINCTRL_PIN(MX7D_PAD_GPIO1_IO01),
+	IMX_PINCTRL_PIN(MX7D_PAD_GPIO1_IO02),
+	IMX_PINCTRL_PIN(MX7D_PAD_GPIO1_IO03),
+	IMX_PINCTRL_PIN(MX7D_PAD_GPIO1_IO04),
+	IMX_PINCTRL_PIN(MX7D_PAD_GPIO1_IO05),
+	IMX_PINCTRL_PIN(MX7D_PAD_GPIO1_IO06),
+	IMX_PINCTRL_PIN(MX7D_PAD_GPIO1_IO07),
+};
+
 static struct imx_pinctrl_soc_info imx7d_pinctrl_info = {
 	.pins = imx7d_pinctrl_pads,
 	.npins = ARRAY_SIZE(imx7d_pinctrl_pads),
 };
 
+static struct imx_pinctrl_soc_info imx7d_lpsr_pinctrl_info = {
+	.pins = imx7d_lpsr_pinctrl_pads,
+	.npins = ARRAY_SIZE(imx7d_lpsr_pinctrl_pads),
+	.flags = SHARE_INPUT_SELECT_REG | ZERO_OFFSET_VALID,
+};
+
 static struct of_device_id imx7d_pinctrl_of_match[] = {
 	{ .compatible = "fsl,imx7d-iomuxc", .data = &imx7d_pinctrl_info, },
+	{ .compatible = "fsl,imx7d-iomuxc-lpsr", .data = &imx7d_lpsr_pinctrl_info },
 	{ /* sentinel */ }
 };
 
-- 
2.1.4



From aalonso at freescale.com  Tue Aug 18 08:48:59 2015
From: aalonso at freescale.com (Adrian Alonso)
Date: Tue, 18 Aug 2015 10:48:59 -0500
Subject: [PATCH 8/8] pinctrl: freescale: imx: fix system crash if enable two
 pinctl instances
In-Reply-To: <1439912939-17535-1-git-send-email-aalonso@freescale.com>
References: <1439912939-17535-1-git-send-email-aalonso@freescale.com>
Message-ID: <1439912939-17535-8-git-send-email-aalonso@freescale.com>

From: Robin Gong <b38343 at freescale.com>

Remove 'static' for 'grp_index', otherwise, it cause the groups whose number is
smaller than the number of groups of the last pinctl instance never to be
intialized, thus cause system crash as below

[    0.661012] [<802a6cb0>] (strcmp) from [<802cc80c>] (imx_dt_node_to_map+0x58/0x208)
[    0.668879] [<802cc80c>] (imx_dt_node_to_map) from [<802cbe24>] (pinctrl_dt_to_map+0x174/0x2b0)
[    0.677654] [<802cbe24>] (pinctrl_dt_to_map) from [<802c8f18>] (pinctrl_get+0x100/0x424)
[    0.685878] [<802c8f18>] (pinctrl_get) from [<802c9510>] (pinctrl_register+0x26c/0x480)
[    0.694104] [<802c9510>] (pinctrl_register) from [<802ccf3c>] (imx_pinctrl_probe+0x580/0x6e8)
[    0.702706] [<802ccf3c>] (imx_pinctrl_probe) from [<80351b58>] (platform_drv_probe+0x44/0xa4)
[    0.711455] [<80351b58>] (platform_drv_probe) from [<803503ec>] (driver_probe_device+0x174/0x2b4)
[    0.720405] [<803503ec>] (driver_probe_device) from [<803505fc>] (__driver_attach+0x8c/0x90)
[    0.728982] [<803505fc>] (__driver_attach) from [<8034e930>] (bus_for_each_dev+0x6c/0xa0)
[    0.737381] [<8034e930>] (bus_for_each_dev) from [<8034fb88>] (bus_add_driver+0x148/0x1f0)
[    0.745804] [<8034fb88>] (bus_add_driver) from [<80350c00>] (driver_register+0x78/0xf8)
[    0.753880] [<80350c00>] (driver_register) from [<800097d0>] (do_one_initcall+0x8c/0x1d4)
[    0.762282] [<800097d0>] (do_one_initcall) from [<80987dac>] (kernel_init_freeable+0x144/0x1e4)
[    0.771061] [<80987dac>] (kernel_init_freeable) from [<806d9c7c>] (kernel_init+0x8/0xe8)
[    0.779285] [<806d9c7c>] (kernel_init) from [<8000f628>] (ret_from_fork+0x14/0x2c)
[    0.786981] Code: e3520000 e5e32001 1afffffb e12fff1e (e4d03001)

Signed-off-by: Robin Gong <b38343 at freescale.com>
Signed-off-by: Adrian Alonso <aalonso at freescale.com>
---
 drivers/pinctrl/freescale/pinctrl-imx.c | 2 +-
 1 file changed, 1 insertion(+), 1 deletion(-)

diff --git a/drivers/pinctrl/freescale/pinctrl-imx.c b/drivers/pinctrl/freescale/pinctrl-imx.c
index 3e02887..cdb5463 100644
--- a/drivers/pinctrl/freescale/pinctrl-imx.c
+++ b/drivers/pinctrl/freescale/pinctrl-imx.c
@@ -595,7 +595,7 @@ static int imx_pinctrl_parse_functions(struct device_node *np,
 	struct device_node *child;
 	struct imx_pmx_func *func;
 	struct imx_pin_group *grp;
-	static u32 grp_index;
+	u32 grp_index = 0;
 	u32 i = 0;
 
 	dev_dbg(info->dev, "parse function(%d): %s\n", index, np->name);
-- 
2.1.4



From aalonso at freescale.com  Tue Aug 18 08:48:58 2015
From: aalonso at freescale.com (Adrian Alonso)
Date: Tue, 18 Aug 2015 10:48:58 -0500
Subject: [PATCH 7/8] pinctrl: freescale: imx: fix flat functions default return
In-Reply-To: <1439912939-17535-1-git-send-email-aalonso@freescale.com>
References: <1439912939-17535-1-git-send-email-aalonso@freescale.com>
Message-ID: <1439912939-17535-7-git-send-email-aalonso@freescale.com>

Fix imx pinctrl dt flat functions default return value.
If property fsl,pins is not found in function_np and
pinctrl_np return false to indicate that DT is not using
flat functions.

Signed-off-by: Adrian Alonso <aalonso at freescale.com>
---
 drivers/pinctrl/freescale/pinctrl-imx.c | 2 +-
 1 file changed, 1 insertion(+), 1 deletion(-)

diff --git a/drivers/pinctrl/freescale/pinctrl-imx.c b/drivers/pinctrl/freescale/pinctrl-imx.c
index 1009b52..3e02887 100644
--- a/drivers/pinctrl/freescale/pinctrl-imx.c
+++ b/drivers/pinctrl/freescale/pinctrl-imx.c
@@ -641,7 +641,7 @@ static bool imx_pinctrl_dt_is_flat_functions(struct device_node *np)
 		}
 	}
 
-	return true;
+	return false;
 }
 
 static int imx_pinctrl_probe_dt(struct platform_device *pdev,
-- 
2.1.4



From lznuaa at gmail.com  Tue Aug 18 09:02:34 2015
From: lznuaa at gmail.com (Zhi Li)
Date: Tue, 18 Aug 2015 11:02:34 -0500
Subject: [PATCH 6/8] pinctrl: freescale: imx7d: support iomux lpsr
 controller
In-Reply-To: <1439912939-17535-6-git-send-email-aalonso@freescale.com>
References: <1439912939-17535-1-git-send-email-aalonso@freescale.com>
 <1439912939-17535-6-git-send-email-aalonso@freescale.com>
Message-ID: <CAHrpEqTJCmPB2_AsKM_asLEz7NMsVCmOoDUGvptR2g-s4VdKiA@mail.gmail.com>

On Tue, Aug 18, 2015 at 10:48 AM, Adrian Alonso <aalonso at freescale.com> wrote:
> iMX7D has two iomuxc controllers, iomuxc controller similar as
> previous iMX SoC generation and iomuxc-lpsr which provides low
> power state rentetion capabilities on gpios that are part of
> iomuxc-lpsr
>
> - Add iomuxc-lpsr gpio group id's
> - Use flag ZERO_OFFSET_VALID and SHARE_INPUT_SELECT_REG to
>   properly set pads from iomuxc-lpsr domain
>
> Signed-off-by: Adrian Alonso <aalonso at freescale.com>
> ---
>  drivers/pinctrl/freescale/pinctrl-imx7d.c | 27 +++++++++++++++++++++++++++
>  1 file changed, 27 insertions(+)
>
> diff --git a/drivers/pinctrl/freescale/pinctrl-imx7d.c b/drivers/pinctrl/freescale/pinctrl-imx7d.c
> index 1fa7530..a347c22 100644
> --- a/drivers/pinctrl/freescale/pinctrl-imx7d.c
> +++ b/drivers/pinctrl/freescale/pinctrl-imx7d.c
> @@ -172,6 +172,14 @@ enum imx7d_pads {
>         MX7D_PAD_ENET1_RX_CLK = 152,
>         MX7D_PAD_ENET1_CRS = 153,
>         MX7D_PAD_ENET1_COL = 154,

I suggest use new enum. like imx7d_lpsr_pads
to avoid confuse about duplicate 0  - 7.

best regards
Frank Li

> +       MX7D_PAD_GPIO1_IO00 = 0,
> +       MX7D_PAD_GPIO1_IO01 = 1,
> +       MX7D_PAD_GPIO1_IO02 = 2,
> +       MX7D_PAD_GPIO1_IO03 = 3,
> +       MX7D_PAD_GPIO1_IO04 = 4,
> +       MX7D_PAD_GPIO1_IO05 = 5,
> +       MX7D_PAD_GPIO1_IO06 = 6,
> +       MX7D_PAD_GPIO1_IO07 = 7,
>  };
>
>  /* Pad names for the pinmux subsystem */
> @@ -333,13 +341,32 @@ static const struct pinctrl_pin_desc imx7d_pinctrl_pads[] = {
>         IMX_PINCTRL_PIN(MX7D_PAD_ENET1_COL),
>  };
>
> +/* Pad names for the pinmux subsystem */
> +static const struct pinctrl_pin_desc imx7d_lpsr_pinctrl_pads[] = {
> +       IMX_PINCTRL_PIN(MX7D_PAD_GPIO1_IO00),
> +       IMX_PINCTRL_PIN(MX7D_PAD_GPIO1_IO01),
> +       IMX_PINCTRL_PIN(MX7D_PAD_GPIO1_IO02),
> +       IMX_PINCTRL_PIN(MX7D_PAD_GPIO1_IO03),
> +       IMX_PINCTRL_PIN(MX7D_PAD_GPIO1_IO04),
> +       IMX_PINCTRL_PIN(MX7D_PAD_GPIO1_IO05),
> +       IMX_PINCTRL_PIN(MX7D_PAD_GPIO1_IO06),
> +       IMX_PINCTRL_PIN(MX7D_PAD_GPIO1_IO07),
> +};
> +
>  static struct imx_pinctrl_soc_info imx7d_pinctrl_info = {
>         .pins = imx7d_pinctrl_pads,
>         .npins = ARRAY_SIZE(imx7d_pinctrl_pads),
>  };
>
> +static struct imx_pinctrl_soc_info imx7d_lpsr_pinctrl_info = {
> +       .pins = imx7d_lpsr_pinctrl_pads,
> +       .npins = ARRAY_SIZE(imx7d_lpsr_pinctrl_pads),
> +       .flags = SHARE_INPUT_SELECT_REG | ZERO_OFFSET_VALID,
> +};
> +
>  static struct of_device_id imx7d_pinctrl_of_match[] = {
>         { .compatible = "fsl,imx7d-iomuxc", .data = &imx7d_pinctrl_info, },
> +       { .compatible = "fsl,imx7d-iomuxc-lpsr", .data = &imx7d_lpsr_pinctrl_info },
>         { /* sentinel */ }
>  };
>
> --
> 2.1.4
>


From dinguyen at opensource.altera.com  Tue Aug 18 09:04:32 2015
From: dinguyen at opensource.altera.com (Dinh Nguyen)
Date: Tue, 18 Aug 2015 11:04:32 -0500
Subject: [PATCHv2] arm64: dts: Add base stratix 10 dtsi
In-Reply-To: <1439308127-7412-1-git-send-email-dinguyen@opensource.altera.com>
References: <1439308127-7412-1-git-send-email-dinguyen@opensource.altera.com>
Message-ID: <alpine.DEB.2.02.1508181103230.23339@linux-builds1>

On Tue, 11 Aug 2015, dinguyen at opensource.altera.com wrote:

> From: Dinh Nguyen <dinguyen at opensource.altera.com>
> 
> Add the base DTS for Altera's SoCFPGA Stratix 10 platform.
> 
> Signed-off-by: Dinh Nguyen <dinguyen at opensource.altera.com>
> ---
> v2: use interrupt-affinity for pmu node
> ---
>  arch/arm64/Kconfig                                 |   5 +
>  arch/arm64/boot/dts/Makefile                       |   1 +
>  arch/arm64/boot/dts/altera/Makefile                |   5 +
>  arch/arm64/boot/dts/altera/socfpga_stratix10.dtsi  | 358 +++++++++++++++++++++
>  .../boot/dts/altera/socfpga_stratix10_socdk.dts    |  38 +++
>  arch/arm64/configs/defconfig                       |   1 +
>  6 files changed, 408 insertions(+)
>  create mode 100644 arch/arm64/boot/dts/altera/Makefile
>  create mode 100644 arch/arm64/boot/dts/altera/socfpga_stratix10.dtsi
>  create mode 100644 arch/arm64/boot/dts/altera/socfpga_stratix10_socdk.dts
> 

Soft ping on this pach?

BR,
Dinh


From catalin.marinas at arm.com  Tue Aug 18 09:16:49 2015
From: catalin.marinas at arm.com (Catalin Marinas)
Date: Tue, 18 Aug 2015 17:16:49 +0100
Subject: [PATCH 2/2] arm64: set MAX_MEMBLOCK_ADDR according to linear
 region size
In-Reply-To: <20150818145149.GQ7557@n2100.arm.linux.org.uk>
References: <1439890482-20798-1-git-send-email-ard.biesheuvel@linaro.org>
 <1439890482-20798-3-git-send-email-ard.biesheuvel@linaro.org>
 <20150818100018.GA11021@arm.com>
 <20150818142435.GC11571@e104818-lin.cambridge.arm.com>
 <20150818145149.GQ7557@n2100.arm.linux.org.uk>
Message-ID: <20150818161649.GD11571@e104818-lin.cambridge.arm.com>

On Tue, Aug 18, 2015 at 03:51:49PM +0100, Russell King - ARM Linux wrote:
> On Tue, Aug 18, 2015 at 03:24:36PM +0100, Catalin Marinas wrote:
> > With the current memory layout, this could also be __pa(~0UL). I guess
> > we could solve this with a single patch, though I'm not sure whether we
> > break other architectures:
> 
> No.  __pa() is only valid within the lowmem mapping, not outside of it.
> What you'd get for a virtual address of ~0UL is not well defined, so
> you should not use this in generic code.

You are right. We'll keep this max memblock address in the arch code.

-- 
Catalin


From broonie at kernel.org  Tue Aug 18 09:07:49 2015
From: broonie at kernel.org (Mark Brown)
Date: Tue, 18 Aug 2015 09:07:49 -0700
Subject: [PATCH] spi: mediatek: fix spi incorrect endian usage and remove
 redundant clock
In-Reply-To: <CAOiHx=nBOtm3c7QQpA-SSxXzJGjUEJQBtR9CynoeqsXRoz4fRg@mail.gmail.com>
References: <1439895231-17778-1-git-send-email-leilk.liu@mediatek.com>
 <CAOiHx=nBOtm3c7QQpA-SSxXzJGjUEJQBtR9CynoeqsXRoz4fRg@mail.gmail.com>
Message-ID: <20150818160749.GJ10748@sirena.org.uk>

On Tue, Aug 18, 2015 at 02:19:54PM +0200, Jonas Gorski wrote:

> The usual philosophy is to have one change per patch, so this might be
> better as three patches. But this is Mark's call. Since the driver
> isn't yet in Linus' tree, it might be a-ok to mix style improvements
> and actual fixes, but as soon as it landed in Linus' tree you need to
> keep them separate, so fixes can be easily backported.

This isn't just about making the fixes easy to backport, it's also about
making the patch reviewable and understandable.  When many changes are
included in one patch it makes it harder to tell what any one part of
the patch is intended to do.  As Jonas has identified several bugs
you'll need to resend anyway, please split the series up.
-------------- next part --------------
A non-text attachment was scrubbed...
Name: signature.asc
Type: application/pgp-signature
Size: 473 bytes
Desc: Digital signature
URL: <http://lists.infradead.org/pipermail/linux-arm-kernel/attachments/20150818/27b60471/attachment-0001.sig>

From panand at redhat.com  Tue Aug 18 09:34:09 2015
From: panand at redhat.com (Pratyush Anand)
Date: Tue, 18 Aug 2015 22:04:09 +0530
Subject: [PATCH V2] Watchdog: Fix parent of watchdog_devices
Message-ID: <9fcc2a2cc8273f461baa13c6c9992f3ca56b508a.1439915117.git.panand@redhat.com>

/sys/class/watchdog/watchdogn/device/modalias can help to identify the
driver/module for a given watchdog node. However, many wdt devices does not set
its parent and so, we do not see an entry for device in sysfs for such devices.

This patch fixes parent of watchdog_device so that
/sys/class/watchdog/watchdogn/device is populated.

Exceptions: booke, diag288, mpc8xxx, octeon, softdog and w83627hf -- They do not
have any parent. Not sure, how we can we identify driver for these devices.

Signed-off-by: Pratyush Anand <panand at redhat.com>
---
Changes since v1:
Squash all commits of V1 into a single patch.
V1 was here:
http://www.spinics.net/lists/linux-watchdog/msg07220.html

 drivers/misc/mei/wd.c               | 1 +
 drivers/watchdog/bcm2835_wdt.c      | 1 +
 drivers/watchdog/bcm47xx_wdt.c      | 1 +
 drivers/watchdog/bcm_kona_wdt.c     | 1 +
 drivers/watchdog/coh901327_wdt.c    | 1 +
 drivers/watchdog/da9052_wdt.c       | 1 +
 drivers/watchdog/da9055_wdt.c       | 1 +
 drivers/watchdog/da9062_wdt.c       | 1 +
 drivers/watchdog/da9063_wdt.c       | 1 +
 drivers/watchdog/davinci_wdt.c      | 1 +
 drivers/watchdog/digicolor_wdt.c    | 1 +
 drivers/watchdog/ep93xx_wdt.c       | 1 +
 drivers/watchdog/gpio_wdt.c         | 1 +
 drivers/watchdog/ie6xx_wdt.c        | 1 +
 drivers/watchdog/intel-mid_wdt.c    | 1 +
 drivers/watchdog/jz4740_wdt.c       | 1 +
 drivers/watchdog/mena21_wdt.c       | 1 +
 drivers/watchdog/menf21bmc_wdt.c    | 1 +
 drivers/watchdog/omap_wdt.c         | 1 +
 drivers/watchdog/orion_wdt.c        | 1 +
 drivers/watchdog/pnx4008_wdt.c      | 1 +
 drivers/watchdog/qcom-wdt.c         | 1 +
 drivers/watchdog/retu_wdt.c         | 1 +
 drivers/watchdog/rt2880_wdt.c       | 1 +
 drivers/watchdog/s3c2410_wdt.c      | 1 +
 drivers/watchdog/shwdt.c            | 1 +
 drivers/watchdog/sirfsoc_wdt.c      | 1 +
 drivers/watchdog/sp805_wdt.c        | 1 +
 drivers/watchdog/st_lpc_wdt.c       | 1 +
 drivers/watchdog/stmp3xxx_rtc_wdt.c | 1 +
 drivers/watchdog/tegra_wdt.c        | 1 +
 drivers/watchdog/twl4030_wdt.c      | 1 +
 drivers/watchdog/txx9wdt.c          | 1 +
 drivers/watchdog/ux500_wdt.c        | 1 +
 drivers/watchdog/via_wdt.c          | 1 +
 drivers/watchdog/wm831x_wdt.c       | 1 +
 drivers/watchdog/wm8350_wdt.c       | 1 +
 37 files changed, 37 insertions(+)

diff --git a/drivers/misc/mei/wd.c b/drivers/misc/mei/wd.c
index 2bc0f5089f82..b346638833b0 100644
--- a/drivers/misc/mei/wd.c
+++ b/drivers/misc/mei/wd.c
@@ -364,6 +364,7 @@ int mei_watchdog_register(struct mei_device *dev)
 
 	int ret;
 
+	amt_wd_dev.parent = dev->dev;
 	/* unlock to perserve correct locking order */
 	mutex_unlock(&dev->device_lock);
 	ret = watchdog_register_device(&amt_wd_dev);
diff --git a/drivers/watchdog/bcm2835_wdt.c b/drivers/watchdog/bcm2835_wdt.c
index 7116968dee12..66c3e656a616 100644
--- a/drivers/watchdog/bcm2835_wdt.c
+++ b/drivers/watchdog/bcm2835_wdt.c
@@ -182,6 +182,7 @@ static int bcm2835_wdt_probe(struct platform_device *pdev)
 	watchdog_set_drvdata(&bcm2835_wdt_wdd, wdt);
 	watchdog_init_timeout(&bcm2835_wdt_wdd, heartbeat, dev);
 	watchdog_set_nowayout(&bcm2835_wdt_wdd, nowayout);
+	bcm2835_wdt_wdd.parent = &pdev->dev;
 	err = watchdog_register_device(&bcm2835_wdt_wdd);
 	if (err) {
 		dev_err(dev, "Failed to register watchdog device");
diff --git a/drivers/watchdog/bcm47xx_wdt.c b/drivers/watchdog/bcm47xx_wdt.c
index b28a072abf78..4064a43f1360 100644
--- a/drivers/watchdog/bcm47xx_wdt.c
+++ b/drivers/watchdog/bcm47xx_wdt.c
@@ -209,6 +209,7 @@ static int bcm47xx_wdt_probe(struct platform_device *pdev)
 
 	wdt->wdd.info = &bcm47xx_wdt_info;
 	wdt->wdd.timeout = WDT_DEFAULT_TIME;
+	wdt->wdd.parent = &pdev->dev;
 	ret = wdt->wdd.ops->set_timeout(&wdt->wdd, timeout);
 	if (ret)
 		goto err_timer;
diff --git a/drivers/watchdog/bcm_kona_wdt.c b/drivers/watchdog/bcm_kona_wdt.c
index 22d8ae65772a..e0c98423f2c9 100644
--- a/drivers/watchdog/bcm_kona_wdt.c
+++ b/drivers/watchdog/bcm_kona_wdt.c
@@ -319,6 +319,7 @@ static int bcm_kona_wdt_probe(struct platform_device *pdev)
 	spin_lock_init(&wdt->lock);
 	platform_set_drvdata(pdev, wdt);
 	watchdog_set_drvdata(&bcm_kona_wdt_wdd, wdt);
+	bcm_kona_wdt_wdd.parent = &pdev->dev;
 
 	ret = bcm_kona_wdt_set_timeout_reg(&bcm_kona_wdt_wdd, 0);
 	if (ret) {
diff --git a/drivers/watchdog/coh901327_wdt.c b/drivers/watchdog/coh901327_wdt.c
index ce12f437f195..a099b77fc0b9 100644
--- a/drivers/watchdog/coh901327_wdt.c
+++ b/drivers/watchdog/coh901327_wdt.c
@@ -358,6 +358,7 @@ static int __init coh901327_probe(struct platform_device *pdev)
 	if (ret < 0)
 		coh901327_wdt.timeout = 60;
 
+	coh901327_wdt.parent = &pdev->dev;
 	ret = watchdog_register_device(&coh901327_wdt);
 	if (ret == 0)
 		dev_info(&pdev->dev,
diff --git a/drivers/watchdog/da9052_wdt.c b/drivers/watchdog/da9052_wdt.c
index 2e9589652e1e..67e67977bd29 100644
--- a/drivers/watchdog/da9052_wdt.c
+++ b/drivers/watchdog/da9052_wdt.c
@@ -195,6 +195,7 @@ static int da9052_wdt_probe(struct platform_device *pdev)
 	da9052_wdt->timeout = DA9052_DEF_TIMEOUT;
 	da9052_wdt->info = &da9052_wdt_info;
 	da9052_wdt->ops = &da9052_wdt_ops;
+	da9052_wdt->parent = &pdev->dev;
 	watchdog_set_drvdata(da9052_wdt, driver_data);
 
 	kref_init(&driver_data->kref);
diff --git a/drivers/watchdog/da9055_wdt.c b/drivers/watchdog/da9055_wdt.c
index 495089d8dbfe..04d1430d93d2 100644
--- a/drivers/watchdog/da9055_wdt.c
+++ b/drivers/watchdog/da9055_wdt.c
@@ -161,6 +161,7 @@ static int da9055_wdt_probe(struct platform_device *pdev)
 	da9055_wdt->timeout = DA9055_DEF_TIMEOUT;
 	da9055_wdt->info = &da9055_wdt_info;
 	da9055_wdt->ops = &da9055_wdt_ops;
+	da9055_wdt->parent = &pdev->dev;
 	watchdog_set_nowayout(da9055_wdt, nowayout);
 	watchdog_set_drvdata(da9055_wdt, driver_data);
 
diff --git a/drivers/watchdog/da9062_wdt.c b/drivers/watchdog/da9062_wdt.c
index b3a870ce85be..7386111220d5 100644
--- a/drivers/watchdog/da9062_wdt.c
+++ b/drivers/watchdog/da9062_wdt.c
@@ -210,6 +210,7 @@ static int da9062_wdt_probe(struct platform_device *pdev)
 	wdt->wdtdev.max_timeout = DA9062_WDT_MAX_TIMEOUT;
 	wdt->wdtdev.timeout = DA9062_WDG_DEFAULT_TIMEOUT;
 	wdt->wdtdev.status = WATCHDOG_NOWAYOUT_INIT_STATUS;
+	wdt->wdtdev.parent = &pdev->dev;
 
 	watchdog_set_drvdata(&wdt->wdtdev, wdt);
 	dev_set_drvdata(&pdev->dev, wdt);
diff --git a/drivers/watchdog/da9063_wdt.c b/drivers/watchdog/da9063_wdt.c
index e2fe2ebdebd4..6bf130bd863d 100644
--- a/drivers/watchdog/da9063_wdt.c
+++ b/drivers/watchdog/da9063_wdt.c
@@ -175,6 +175,7 @@ static int da9063_wdt_probe(struct platform_device *pdev)
 	wdt->wdtdev.min_timeout = DA9063_WDT_MIN_TIMEOUT;
 	wdt->wdtdev.max_timeout = DA9063_WDT_MAX_TIMEOUT;
 	wdt->wdtdev.timeout = DA9063_WDG_TIMEOUT;
+	wdt->wdtdev.parent = &pdev->dev;
 
 	wdt->wdtdev.status = WATCHDOG_NOWAYOUT_INIT_STATUS;
 
diff --git a/drivers/watchdog/davinci_wdt.c b/drivers/watchdog/davinci_wdt.c
index cfdf8a408aea..17454ca653f4 100644
--- a/drivers/watchdog/davinci_wdt.c
+++ b/drivers/watchdog/davinci_wdt.c
@@ -179,6 +179,7 @@ static int davinci_wdt_probe(struct platform_device *pdev)
 	wdd->min_timeout	= 1;
 	wdd->max_timeout	= MAX_HEARTBEAT;
 	wdd->timeout		= DEFAULT_HEARTBEAT;
+	wdd->parent		= &pdev->dev;
 
 	watchdog_init_timeout(wdd, heartbeat, dev);
 
diff --git a/drivers/watchdog/digicolor_wdt.c b/drivers/watchdog/digicolor_wdt.c
index 31d8e4936611..50abe1bf62a5 100644
--- a/drivers/watchdog/digicolor_wdt.c
+++ b/drivers/watchdog/digicolor_wdt.c
@@ -143,6 +143,7 @@ static int dc_wdt_probe(struct platform_device *pdev)
 	}
 	dc_wdt_wdd.max_timeout = U32_MAX / clk_get_rate(wdt->clk);
 	dc_wdt_wdd.timeout = dc_wdt_wdd.max_timeout;
+	dc_wdt_wdd.parent = &pdev->dev;
 
 	spin_lock_init(&wdt->lock);
 
diff --git a/drivers/watchdog/ep93xx_wdt.c b/drivers/watchdog/ep93xx_wdt.c
index 7a2cc7191c58..0a4d7cc05d54 100644
--- a/drivers/watchdog/ep93xx_wdt.c
+++ b/drivers/watchdog/ep93xx_wdt.c
@@ -132,6 +132,7 @@ static int ep93xx_wdt_probe(struct platform_device *pdev)
 	val = readl(mmio_base + EP93XX_WATCHDOG);
 	ep93xx_wdt_wdd.bootstatus = (val & 0x01) ? WDIOF_CARDRESET : 0;
 	ep93xx_wdt_wdd.timeout = timeout;
+	ep93xx_wdt_wdd.parent = &pdev->dev;
 
 	watchdog_set_nowayout(&ep93xx_wdt_wdd, nowayout);
 
diff --git a/drivers/watchdog/gpio_wdt.c b/drivers/watchdog/gpio_wdt.c
index 1687cc2d7122..336bddd84809 100644
--- a/drivers/watchdog/gpio_wdt.c
+++ b/drivers/watchdog/gpio_wdt.c
@@ -217,6 +217,7 @@ static int gpio_wdt_probe(struct platform_device *pdev)
 	priv->wdd.ops		= &gpio_wdt_ops;
 	priv->wdd.min_timeout	= SOFT_TIMEOUT_MIN;
 	priv->wdd.max_timeout	= SOFT_TIMEOUT_MAX;
+	priv->wdd.parent	= &pdev->dev;
 
 	if (watchdog_init_timeout(&priv->wdd, 0, &pdev->dev) < 0)
 		priv->wdd.timeout = SOFT_TIMEOUT_DEF;
diff --git a/drivers/watchdog/ie6xx_wdt.c b/drivers/watchdog/ie6xx_wdt.c
index 9bc39ae51624..78c2541f5d52 100644
--- a/drivers/watchdog/ie6xx_wdt.c
+++ b/drivers/watchdog/ie6xx_wdt.c
@@ -267,6 +267,7 @@ static int ie6xx_wdt_probe(struct platform_device *pdev)
 
 	ie6xx_wdt_dev.timeout = timeout;
 	watchdog_set_nowayout(&ie6xx_wdt_dev, nowayout);
+	ie6xx_wdt_dev.parent = &pdev->dev;
 
 	spin_lock_init(&ie6xx_wdt_data.unlock_sequence);
 
diff --git a/drivers/watchdog/intel-mid_wdt.c b/drivers/watchdog/intel-mid_wdt.c
index 84f6701c391f..0a436b5d1e84 100644
--- a/drivers/watchdog/intel-mid_wdt.c
+++ b/drivers/watchdog/intel-mid_wdt.c
@@ -137,6 +137,7 @@ static int mid_wdt_probe(struct platform_device *pdev)
 	wdt_dev->min_timeout = MID_WDT_TIMEOUT_MIN;
 	wdt_dev->max_timeout = MID_WDT_TIMEOUT_MAX;
 	wdt_dev->timeout = MID_WDT_DEFAULT_TIMEOUT;
+	wdt_dev->parent = &pdev->dev;
 
 	watchdog_set_drvdata(wdt_dev, &pdev->dev);
 	platform_set_drvdata(pdev, wdt_dev);
diff --git a/drivers/watchdog/jz4740_wdt.c b/drivers/watchdog/jz4740_wdt.c
index 4c2cc09c0c57..6a7d5c365438 100644
--- a/drivers/watchdog/jz4740_wdt.c
+++ b/drivers/watchdog/jz4740_wdt.c
@@ -174,6 +174,7 @@ static int jz4740_wdt_probe(struct platform_device *pdev)
 	jz4740_wdt->timeout = heartbeat;
 	jz4740_wdt->min_timeout = 1;
 	jz4740_wdt->max_timeout = MAX_HEARTBEAT;
+	jz4740_wdt->parent = &pdev->dev;
 	watchdog_set_nowayout(jz4740_wdt, nowayout);
 	watchdog_set_drvdata(jz4740_wdt, drvdata);
 
diff --git a/drivers/watchdog/mena21_wdt.c b/drivers/watchdog/mena21_wdt.c
index d193a5e79c38..69013007dc47 100644
--- a/drivers/watchdog/mena21_wdt.c
+++ b/drivers/watchdog/mena21_wdt.c
@@ -197,6 +197,7 @@ static int a21_wdt_probe(struct platform_device *pdev)
 	watchdog_init_timeout(&a21_wdt, 30, &pdev->dev);
 	watchdog_set_nowayout(&a21_wdt, nowayout);
 	watchdog_set_drvdata(&a21_wdt, drv);
+	a21_wdt.parent = &pdev->dev;
 
 	reset = a21_wdt_get_bootstatus(drv);
 	if (reset == 2)
diff --git a/drivers/watchdog/menf21bmc_wdt.c b/drivers/watchdog/menf21bmc_wdt.c
index 59f0913c7341..3aefddebb386 100644
--- a/drivers/watchdog/menf21bmc_wdt.c
+++ b/drivers/watchdog/menf21bmc_wdt.c
@@ -130,6 +130,7 @@ static int menf21bmc_wdt_probe(struct platform_device *pdev)
 	drv_data->wdt.info = &menf21bmc_wdt_info;
 	drv_data->wdt.min_timeout = BMC_WD_TIMEOUT_MIN;
 	drv_data->wdt.max_timeout = BMC_WD_TIMEOUT_MAX;
+	drv_data->wdt.parent = &pdev->dev;
 	drv_data->i2c_client = i2c_client;
 
 	/*
diff --git a/drivers/watchdog/omap_wdt.c b/drivers/watchdog/omap_wdt.c
index de911c7e477c..d96bee017fd3 100644
--- a/drivers/watchdog/omap_wdt.c
+++ b/drivers/watchdog/omap_wdt.c
@@ -253,6 +253,7 @@ static int omap_wdt_probe(struct platform_device *pdev)
 	wdev->wdog.ops = &omap_wdt_ops;
 	wdev->wdog.min_timeout = TIMER_MARGIN_MIN;
 	wdev->wdog.max_timeout = TIMER_MARGIN_MAX;
+	wdev->wdog.parent = &pdev->dev;
 
 	if (watchdog_init_timeout(&wdev->wdog, timer_margin, &pdev->dev) < 0)
 		wdev->wdog.timeout = TIMER_MARGIN_DEFAULT;
diff --git a/drivers/watchdog/orion_wdt.c b/drivers/watchdog/orion_wdt.c
index ef0c628d5037..c6b8f4a43bde 100644
--- a/drivers/watchdog/orion_wdt.c
+++ b/drivers/watchdog/orion_wdt.c
@@ -567,6 +567,7 @@ static int orion_wdt_probe(struct platform_device *pdev)
 
 	dev->wdt.timeout = wdt_max_duration;
 	dev->wdt.max_timeout = wdt_max_duration;
+	dev->wdt.parent = &pdev->dev;
 	watchdog_init_timeout(&dev->wdt, heartbeat, &pdev->dev);
 
 	platform_set_drvdata(pdev, &dev->wdt);
diff --git a/drivers/watchdog/pnx4008_wdt.c b/drivers/watchdog/pnx4008_wdt.c
index b9c6049c3e78..4224b3ec83a5 100644
--- a/drivers/watchdog/pnx4008_wdt.c
+++ b/drivers/watchdog/pnx4008_wdt.c
@@ -167,6 +167,7 @@ static int pnx4008_wdt_probe(struct platform_device *pdev)
 
 	pnx4008_wdd.bootstatus = (readl(WDTIM_RES(wdt_base)) & WDOG_RESET) ?
 			WDIOF_CARDRESET : 0;
+	pnx4008_wdd.parent = &pdev->dev;
 	watchdog_set_nowayout(&pnx4008_wdd, nowayout);
 
 	pnx4008_wdt_stop(&pnx4008_wdd);	/* disable for now */
diff --git a/drivers/watchdog/qcom-wdt.c b/drivers/watchdog/qcom-wdt.c
index aa03ca8f2d9b..773dcfaee7b2 100644
--- a/drivers/watchdog/qcom-wdt.c
+++ b/drivers/watchdog/qcom-wdt.c
@@ -171,6 +171,7 @@ static int qcom_wdt_probe(struct platform_device *pdev)
 	wdt->wdd.ops = &qcom_wdt_ops;
 	wdt->wdd.min_timeout = 1;
 	wdt->wdd.max_timeout = 0x10000000U / wdt->rate;
+	wdt->wdd.parent = &pdev->dev;
 
 	/*
 	 * If 'timeout-sec' unspecified in devicetree, assume a 30 second
diff --git a/drivers/watchdog/retu_wdt.c b/drivers/watchdog/retu_wdt.c
index b7c68e275aeb..39cd51df2ffc 100644
--- a/drivers/watchdog/retu_wdt.c
+++ b/drivers/watchdog/retu_wdt.c
@@ -127,6 +127,7 @@ static int retu_wdt_probe(struct platform_device *pdev)
 	retu_wdt->timeout	= RETU_WDT_MAX_TIMER;
 	retu_wdt->min_timeout	= 0;
 	retu_wdt->max_timeout	= RETU_WDT_MAX_TIMER;
+	retu_wdt->parent	= &pdev->dev;
 
 	watchdog_set_drvdata(retu_wdt, wdev);
 	watchdog_set_nowayout(retu_wdt, nowayout);
diff --git a/drivers/watchdog/rt2880_wdt.c b/drivers/watchdog/rt2880_wdt.c
index a6f7e2e29beb..1967919ae743 100644
--- a/drivers/watchdog/rt2880_wdt.c
+++ b/drivers/watchdog/rt2880_wdt.c
@@ -161,6 +161,7 @@ static int rt288x_wdt_probe(struct platform_device *pdev)
 	rt288x_wdt_dev.dev = &pdev->dev;
 	rt288x_wdt_dev.bootstatus = rt288x_wdt_bootcause();
 	rt288x_wdt_dev.max_timeout = (0xfffful / rt288x_wdt_freq);
+	rt288x_wdt_dev.parent = &pdev->dev;
 
 	watchdog_init_timeout(&rt288x_wdt_dev, rt288x_wdt_dev.max_timeout,
 			      &pdev->dev);
diff --git a/drivers/watchdog/s3c2410_wdt.c b/drivers/watchdog/s3c2410_wdt.c
index e89ae027c91d..d781000c7825 100644
--- a/drivers/watchdog/s3c2410_wdt.c
+++ b/drivers/watchdog/s3c2410_wdt.c
@@ -607,6 +607,7 @@ static int s3c2410wdt_probe(struct platform_device *pdev)
 	watchdog_set_nowayout(&wdt->wdt_device, nowayout);
 
 	wdt->wdt_device.bootstatus = s3c2410wdt_get_bootstatus(wdt);
+	wdt->wdt_device.parent = &pdev->dev;
 
 	ret = watchdog_register_device(&wdt->wdt_device);
 	if (ret) {
diff --git a/drivers/watchdog/shwdt.c b/drivers/watchdog/shwdt.c
index 567458b137a6..f90812170657 100644
--- a/drivers/watchdog/shwdt.c
+++ b/drivers/watchdog/shwdt.c
@@ -252,6 +252,7 @@ static int sh_wdt_probe(struct platform_device *pdev)
 
 	watchdog_set_nowayout(&sh_wdt_dev, nowayout);
 	watchdog_set_drvdata(&sh_wdt_dev, wdt);
+	sh_wdt_dev.parent = &pdev->dev;
 
 	spin_lock_init(&wdt->lock);
 
diff --git a/drivers/watchdog/sirfsoc_wdt.c b/drivers/watchdog/sirfsoc_wdt.c
index 42fa5c0c518a..d0578ab2e636 100644
--- a/drivers/watchdog/sirfsoc_wdt.c
+++ b/drivers/watchdog/sirfsoc_wdt.c
@@ -154,6 +154,7 @@ static int sirfsoc_wdt_probe(struct platform_device *pdev)
 
 	watchdog_init_timeout(&sirfsoc_wdd, timeout, &pdev->dev);
 	watchdog_set_nowayout(&sirfsoc_wdd, nowayout);
+	sirfsoc_wdd.parent = &pdev->dev;
 
 	ret = watchdog_register_device(&sirfsoc_wdd);
 	if (ret)
diff --git a/drivers/watchdog/sp805_wdt.c b/drivers/watchdog/sp805_wdt.c
index 4e7fec36f5c3..01d816251302 100644
--- a/drivers/watchdog/sp805_wdt.c
+++ b/drivers/watchdog/sp805_wdt.c
@@ -226,6 +226,7 @@ sp805_wdt_probe(struct amba_device *adev, const struct amba_id *id)
 	wdt->adev = adev;
 	wdt->wdd.info = &wdt_info;
 	wdt->wdd.ops = &wdt_ops;
+	wdt->wdd.parent = &adev->dev;
 
 	spin_lock_init(&wdt->lock);
 	watchdog_set_nowayout(&wdt->wdd, nowayout);
diff --git a/drivers/watchdog/st_lpc_wdt.c b/drivers/watchdog/st_lpc_wdt.c
index 6785afdc0fca..14e9badf2bfa 100644
--- a/drivers/watchdog/st_lpc_wdt.c
+++ b/drivers/watchdog/st_lpc_wdt.c
@@ -241,6 +241,7 @@ static int st_wdog_probe(struct platform_device *pdev)
 		return -EINVAL;
 	}
 	st_wdog_dev.max_timeout = 0xFFFFFFFF / st_wdog->clkrate;
+	st_wdog_dev.parent = &pdev->dev;
 
 	ret = clk_prepare_enable(clk);
 	if (ret) {
diff --git a/drivers/watchdog/stmp3xxx_rtc_wdt.c b/drivers/watchdog/stmp3xxx_rtc_wdt.c
index e7f0d5b60d3d..3ee6128a540e 100644
--- a/drivers/watchdog/stmp3xxx_rtc_wdt.c
+++ b/drivers/watchdog/stmp3xxx_rtc_wdt.c
@@ -76,6 +76,7 @@ static int stmp3xxx_wdt_probe(struct platform_device *pdev)
 	watchdog_set_drvdata(&stmp3xxx_wdd, &pdev->dev);
 
 	stmp3xxx_wdd.timeout = clamp_t(unsigned, heartbeat, 1, STMP3XXX_MAX_TIMEOUT);
+	stmp3xxx_wdd.parent = &pdev->dev;
 
 	ret = watchdog_register_device(&stmp3xxx_wdd);
 	if (ret < 0) {
diff --git a/drivers/watchdog/tegra_wdt.c b/drivers/watchdog/tegra_wdt.c
index 30451ea46902..7f97cdd53f29 100644
--- a/drivers/watchdog/tegra_wdt.c
+++ b/drivers/watchdog/tegra_wdt.c
@@ -218,6 +218,7 @@ static int tegra_wdt_probe(struct platform_device *pdev)
 	wdd->ops = &tegra_wdt_ops;
 	wdd->min_timeout = MIN_WDT_TIMEOUT;
 	wdd->max_timeout = MAX_WDT_TIMEOUT;
+	wdd->parent = &pdev->dev;
 
 	watchdog_set_drvdata(wdd, wdt);
 
diff --git a/drivers/watchdog/twl4030_wdt.c b/drivers/watchdog/twl4030_wdt.c
index 2c1db6fa9a27..9bf3cc0f3961 100644
--- a/drivers/watchdog/twl4030_wdt.c
+++ b/drivers/watchdog/twl4030_wdt.c
@@ -83,6 +83,7 @@ static int twl4030_wdt_probe(struct platform_device *pdev)
 	wdt->timeout		= 30;
 	wdt->min_timeout	= 1;
 	wdt->max_timeout	= 30;
+	wdt->parent = &pdev->dev;
 
 	watchdog_set_nowayout(wdt, nowayout);
 	platform_set_drvdata(pdev, wdt);
diff --git a/drivers/watchdog/txx9wdt.c b/drivers/watchdog/txx9wdt.c
index 7f615933d31a..c4fa6b55c53d 100644
--- a/drivers/watchdog/txx9wdt.c
+++ b/drivers/watchdog/txx9wdt.c
@@ -131,6 +131,7 @@ static int __init txx9wdt_probe(struct platform_device *dev)
 	txx9wdt.timeout = timeout;
 	txx9wdt.min_timeout = 1;
 	txx9wdt.max_timeout = WD_MAX_TIMEOUT;
+	txx9wdt.parent = &pdev->dev;
 	watchdog_set_nowayout(&txx9wdt, nowayout);
 
 	ret = watchdog_register_device(&txx9wdt);
diff --git a/drivers/watchdog/ux500_wdt.c b/drivers/watchdog/ux500_wdt.c
index 9de09ab00838..37c084353cce 100644
--- a/drivers/watchdog/ux500_wdt.c
+++ b/drivers/watchdog/ux500_wdt.c
@@ -96,6 +96,7 @@ static int ux500_wdt_probe(struct platform_device *pdev)
 			ux500_wdt.max_timeout = WATCHDOG_MAX28;
 	}
 
+	ux500_wdt.parent = &pdev->dev;
 	watchdog_set_nowayout(&ux500_wdt, nowayout);
 
 	/* disable auto off on sleep */
diff --git a/drivers/watchdog/via_wdt.c b/drivers/watchdog/via_wdt.c
index 56369c4f1961..5f9cbc37520d 100644
--- a/drivers/watchdog/via_wdt.c
+++ b/drivers/watchdog/via_wdt.c
@@ -206,6 +206,7 @@ static int wdt_probe(struct pci_dev *pdev,
 		timeout = WDT_TIMEOUT;
 
 	wdt_dev.timeout = timeout;
+	wdt_dev.parent = &pdev->dev;
 	watchdog_set_nowayout(&wdt_dev, nowayout);
 	if (readl(wdt_mem) & VIA_WDT_FIRED)
 		wdt_dev.bootstatus |= WDIOF_CARDRESET;
diff --git a/drivers/watchdog/wm831x_wdt.c b/drivers/watchdog/wm831x_wdt.c
index 2fa17e746ff6..8d1184aee932 100644
--- a/drivers/watchdog/wm831x_wdt.c
+++ b/drivers/watchdog/wm831x_wdt.c
@@ -215,6 +215,7 @@ static int wm831x_wdt_probe(struct platform_device *pdev)
 
 	wm831x_wdt->info = &wm831x_wdt_info;
 	wm831x_wdt->ops = &wm831x_wdt_ops;
+	wm831x_wdt->parent = &pdev->dev;
 	watchdog_set_nowayout(wm831x_wdt, nowayout);
 	watchdog_set_drvdata(wm831x_wdt, driver_data);
 
diff --git a/drivers/watchdog/wm8350_wdt.c b/drivers/watchdog/wm8350_wdt.c
index 34d272ada23d..4ab4b8347d45 100644
--- a/drivers/watchdog/wm8350_wdt.c
+++ b/drivers/watchdog/wm8350_wdt.c
@@ -151,6 +151,7 @@ static int wm8350_wdt_probe(struct platform_device *pdev)
 
 	watchdog_set_nowayout(&wm8350_wdt, nowayout);
 	watchdog_set_drvdata(&wm8350_wdt, wm8350);
+	wm8350_wdt.parent = &pdev->dev;
 
 	/* Default to 4s timeout */
 	wm8350_wdt_set_timeout(&wm8350_wdt, 4);
-- 
2.4.3



From vinod.koul at intel.com  Tue Aug 18 09:42:51 2015
From: vinod.koul at intel.com (Vinod Koul)
Date: Tue, 18 Aug 2015 22:12:51 +0530
Subject: [PATCH 0/4] PL08x DT bindings and LPC18xx DMA support
In-Reply-To: <1436616727-4847-1-git-send-email-manabian@gmail.com>
References: <1436616727-4847-1-git-send-email-manabian@gmail.com>
Message-ID: <20150818164251.GW13546@localhost>

On Sat, Jul 11, 2015 at 02:12:03PM +0200, Joachim Eastwood wrote:
> Hi Vinod,
> 
> This is the non-RFC version of the patch set with only a few changes.
> Hope this can go in for 4.3. Changes to the DT for LPC18xx/43xx will
> go thru arm-soc once this get accepted.
> 
> 
> This patch set aims to add support for DMA on the NXP LPC18xx/43xx
> (Cortex-M3/M4) platform. The platform has a PL080 controller with a
> mux in front of the DMA request lines. This setup is quite common
> and can be found on most other, if not all, NXP LPC devices.
> 
> Patch set adds DT support for the PL08x dmaengine driver and a DMA
> router driver for the LPC18xx/43xx DMA multiplexer.

Applied, thanks

-- 
~Vinod



From emil.l.velikov at gmail.com  Tue Aug 18 09:41:59 2015
From: emil.l.velikov at gmail.com (Emil Velikov)
Date: Tue, 18 Aug 2015 17:41:59 +0100
Subject: [PATCH 2/4] drm: Add support for ARM's HDLCD controller.
In-Reply-To: <20150817151547.GA1020@e106497-lin.cambridge.arm.com>
References: <1438784892-27888-1-git-send-email-Liviu.Dudau@arm.com>
 <1438784892-27888-3-git-send-email-Liviu.Dudau@arm.com>
 <CACvgo537C6SRfhMTNoE4cSLJukcXuKLvt1TRykynX--ybEhmaQ@mail.gmail.com>
 <20150817151547.GA1020@e106497-lin.cambridge.arm.com>
Message-ID: <CACvgo53KWsC1ZeYYF2bW=4=BeuexaEgBHT=+h2U60iS9nYvYpw@mail.gmail.com>

On 17 August 2015 at 16:15, Liviu Dudau <Liviu.Dudau at arm.com> wrote:
> On Sun, Aug 16, 2015 at 09:56:33AM +0100, Emil Velikov wrote:
>> Hi Liviu,
>
> Hi Emil,
>
>>
>> On 5 August 2015 at 15:28, Liviu Dudau <Liviu.Dudau at arm.com> wrote:
>> > The HDLCD controller is a display controller that supports resolutions
>> > up to 4096x4096 pixels. It is present on various development boards
>> > produced by ARM Ltd and emulated by the latest Fast Models from the
>> > company.
>> >
>> I believe there is a unofficial requirement(?) for new drm drivers to
>> use atomic modesetting. Not 100% sure on this one though. The
>> following drivers: tegra, msm, rcar-du, i915, and Daniel's blog [1]
>> [2] cat provide some information on the topic.
>
> I am also interested to know if this is a requirement or not.
> Thanks for the pointers, I will review them again to see if I did miss
> anything. I remember reading them at the beginning of the year but probably
> the Christmas haze did not clear enough when I did.
>
There was a similar question from the freescale dcu people [1]. I
believe that the answer still applies.

[1] http://lists.freedesktop.org/archives/dri-devel/2015-March/078689.html

>>
>> The driver seems to has has a bit of dead code guarded by
>> HDLCD_*_UNDERRUN. Perhaps these macros should become build or runtime
>> switch(es) ?
>
> There is a comment in hdlcd_drv.h explaining what HDLCD_SHOW_UNDERRUN can
> be used for. As for HDLCD_COUNT_BUFFERUNDERRUNS, you are right, it's dead
> code from the earlier debugging code that got removed before submission.
> I will correct that.
>
I haven't seen other drm drivers follow the "set a macro that is
documented in a header and rebuild" approach. Devs either add a CONFIG
option for it, or expose it as a module parameter. IIRC the nouveau
driver does even more - it enables the underrun machinery
unconditionally.

>>
>> Most DRM drivers do not threat dma, bus_error, vsync and/or underrun
>> interrupts as debug functionality. They are of limited use in this
>> driver, presently, yet the CONFIG_DEBUG_FS guard seems a bit strange
>> imho.
>
> The HDLCD device has only 1 interrupt that can fire and there is no other
> way to show the reason for the interrupt in the driver. It was useful when
> debugging underruns and/or vsync issues so I thought it might be useful
> to keep around. Putting it the other way: if you are going to use this device
> and the image is not completely rendered I would not be able to give you
> support to figure out what went wrong without this debugging information.
> With this in place I can tell the difference between a busy system vs one
> where the interrupt latency is large.
>
Out of curiosity - are there any implications/side-effects from having
these enabled ?

Thanks,
Emil


From HartleyS at visionengravers.com  Tue Aug 18 09:45:44 2015
From: HartleyS at visionengravers.com (Hartley Sweeten)
Date: Tue, 18 Aug 2015 16:45:44 +0000
Subject: [PATCH V2] Watchdog: Fix parent of watchdog_devices
In-Reply-To: <9fcc2a2cc8273f461baa13c6c9992f3ca56b508a.1439915117.git.panand@redhat.com>
References: <9fcc2a2cc8273f461baa13c6c9992f3ca56b508a.1439915117.git.panand@redhat.com>
Message-ID: <BN3PR0101MB1057C3FE09F00EEC55D2C9B1D0780@BN3PR0101MB1057.prod.exchangelabs.com>

On Tuesday, August 18, 2015 9:34 AM, Pratyush Anand wrote:
> 
> /sys/class/watchdog/watchdogn/device/modalias can help to identify the
> driver/module for a given watchdog node. However, many wdt devices does not set
> its parent and so, we do not see an entry for device in sysfs for such devices.
>
> This patch fixes parent of watchdog_device so that
> /sys/class/watchdog/watchdogn/device is populated.
>
> Exceptions: booke, diag288, mpc8xxx, octeon, softdog and w83627hf -- They do not
> have any parent. Not sure, how we can we identify driver for these devices.
>
> Signed-off-by: Pratyush Anand <panand at redhat.com>
> ---
[snip]

drivers/watchdog/ep93xx_wdt.c       | 1 +

[snip]

diff --git a/drivers/watchdog/ep93xx_wdt.c b/drivers/watchdog/ep93xx_wdt.c
index 7a2cc7191c58..0a4d7cc05d54 100644
--- a/drivers/watchdog/ep93xx_wdt.c
+++ b/drivers/watchdog/ep93xx_wdt.c
@@ -132,6 +132,7 @@ static int ep93xx_wdt_probe(struct platform_device *pdev)
 	val = readl(mmio_base + EP93XX_WATCHDOG);
 	ep93xx_wdt_wdd.bootstatus = (val & 0x01) ? WDIOF_CARDRESET : 0;
 	ep93xx_wdt_wdd.timeout = timeout;
+	ep93xx_wdt_wdd.parent = &pdev->dev;
 
 	watchdog_set_nowayout(&ep93xx_wdt_wdd, nowayout);

For ep93xx_wdt.c, use whichever tag you prefer:

Reviewed-by: H Hartley Sweeten <hsweeten at visionengravers.com>
Acked-by: H Hartley Sweeten <hsweeten at visionengravers.com>

Thanks,
Hartley



From maxime.ripard at free-electrons.com  Tue Aug 18 09:47:07 2015
From: maxime.ripard at free-electrons.com (Maxime Ripard)
Date: Tue, 18 Aug 2015 18:47:07 +0200
Subject: [PATCH] nvmem: sunxi: Check for memory allocation failure
Message-ID: <1439916427-25827-1-git-send-email-maxime.ripard@free-electrons.com>

The sunxi_sid driver doesn't check for kmalloc return status before
derefencing the returned pointer, which could lead to a NULL pointer
dereference if kmalloc failed. Check for its return code to make sure it
deosn't happen.

Reported-by: Dan Carpenter <dan.carpenter at oracle.com>
Signed-off-by: Maxime Ripard <maxime.ripard at free-electrons.com>
---
 drivers/nvmem/sunxi_sid.c | 11 ++++++++++-
 1 file changed, 10 insertions(+), 1 deletion(-)

diff --git a/drivers/nvmem/sunxi_sid.c b/drivers/nvmem/sunxi_sid.c
index 14777dd5212d..cfa3b85064dd 100644
--- a/drivers/nvmem/sunxi_sid.c
+++ b/drivers/nvmem/sunxi_sid.c
@@ -103,7 +103,7 @@ static int sunxi_sid_probe(struct platform_device *pdev)
 	struct nvmem_device *nvmem;
 	struct regmap *regmap;
 	struct sunxi_sid *sid;
-	int i, size;
+	int ret, i, size;
 	char *randomness;
 
 	sid = devm_kzalloc(dev, sizeof(*sid), GFP_KERNEL);
@@ -131,6 +131,11 @@ static int sunxi_sid_probe(struct platform_device *pdev)
 		return PTR_ERR(nvmem);
 
 	randomness = kzalloc(sizeof(u8) * size, GFP_KERNEL);
+	if (!randomness) {
+		ret = -EINVAL;
+		goto err_unreg_nvmem;
+	}
+
 	for (i = 0; i < size; i++)
 		randomness[i] = sunxi_sid_read_byte(sid, i);
 
@@ -140,6 +145,10 @@ static int sunxi_sid_probe(struct platform_device *pdev)
 	platform_set_drvdata(pdev, nvmem);
 
 	return 0;
+
+err_unreg_nvmem:
+	nvmem_unregister(nvmem);
+	return ret;
 }
 
 static int sunxi_sid_remove(struct platform_device *pdev)
-- 
2.4.6



From mathieu at codeaurora.org  Tue Aug 18 10:03:33 2015
From: mathieu at codeaurora.org (Mathieu Olivari)
Date: Tue, 18 Aug 2015 10:03:33 -0700
Subject: [PATCH v3 0/3] qcom: Add SMEM MTD parser
In-Reply-To: <CAOiHx=nPDBPsj_Kg_7AkFeieedwGbcJmvALDp2eK+6aKi0wOJA@mail.gmail.com>
References: <1439855266-26242-1-git-send-email-mathieu@codeaurora.org>
 <CAOiHx=nPDBPsj_Kg_7AkFeieedwGbcJmvALDp2eK+6aKi0wOJA@mail.gmail.com>
Message-ID: <20150818170333.GA1581@codeaurora.org>

On Tue, Aug 18, 2015 at 02:30:14PM +0200, Jonas Gorski wrote:
> Hi,
> 
> On Tue, Aug 18, 2015 at 1:47 AM, Mathieu Olivari <mathieu at codeaurora.org> wrote:
> > QCOM platforms such as IPQ806x are using SMEM to store their flash
> > layout. This patch set adds the DT nodes required to instanciate SMEM
> > on IPQ806x and add an MTD parser using it.
> >
> > This change is based on the SMEM driver posted here:
> > *https://lkml.org/lkml/2015/7/27/1125
> 
> Nice work. After testing it on AP148 I see this:
> 
> [    2.481507] 12 qcom-smem partitions found on MTD device qcom-nandc
> [    2.481540] Creating 12 MTD partitions on "qcom-nandc":
> [    2.486690] 0x000000000000-0x000000040000 : "0:SBL1"
> [    2.492842] 0x000000040000-0x000000180000 : "0:MIBIB"
> [    2.497857] 0x000000180000-0x0000002c0000 : "0:SBL2"
> [    2.502895] 0x0000002c0000-0x000000540000 : "0:SBL3"
> [    2.507828] 0x000000540000-0x000000660000 : "0:DDRCONFIG"
> [    2.512857] 0x000000660000-0x000000780000 : "0:SSD"
> [    2.518074] 0x000000780000-0x000000a00000 : "0:TZ"
> [    2.522834] 0x000000a00000-0x000000c80000 : "0:RPM"
> [    2.527607] 0x000000c80000-0x000001180000 : "0:APPSBL"
> [    2.532472] 0x000001180000-0x000001200000 : "0:APPSBLENV"
> [    2.537586] 0x000001200000-0x000001340000 : "0:ART"
> [    2.543140] 0x000001340000-0x000005340000 : "rootfs"
> 
> Are all these partition names supposed to be prefixed with "0:"? This
> is using the OpenWrt applied version.

Yes. These are the names as they are listed in SMEM. If you run the
"smem" command from the U-boot prompt, you will see the same information.
I'm not sure what the 0: prefix means, and where it comes from to be
honest.

> 
> 
> Jonas


From catalin.marinas at arm.com  Tue Aug 18 10:39:39 2015
From: catalin.marinas at arm.com (Catalin Marinas)
Date: Tue, 18 Aug 2015 18:39:39 +0100
Subject: [PATCH 2/2] arm64: set MAX_MEMBLOCK_ADDR according to linear
 region size
In-Reply-To: <CAKv+Gu-YDEKSrkSG2fywgrHBB3Hao+jodknmCAkFCWqG4OpXCA@mail.gmail.com>
References: <1439890482-20798-1-git-send-email-ard.biesheuvel@linaro.org>
 <1439890482-20798-3-git-send-email-ard.biesheuvel@linaro.org>
 <20150818100018.GA11021@arm.com>
 <CAKv+Gu-YDEKSrkSG2fywgrHBB3Hao+jodknmCAkFCWqG4OpXCA@mail.gmail.com>
Message-ID: <20150818173938.GH11571@e104818-lin.cambridge.arm.com>

On Tue, Aug 18, 2015 at 12:04:27PM +0200, Ard Biesheuvel wrote:
> On 18 August 2015 at 12:00, Will Deacon <will.deacon at arm.com> wrote:
> > On Tue, Aug 18, 2015 at 10:34:42AM +0100, Ard Biesheuvel wrote:
> >> The linear region size of a 39-bit VA kernel is only 256 GB, which
> >> may be insufficient to cover all of system RAM, even on platforms
> >> that have much less than 256 GB of memory but which is laid out
> >> very sparsely.
> >>
> >> So make sure we clip the memory we will not be able to map before
> >> installing it into the memblock memory table, by setting
> >> MAX_MEMBLOCK_ADDR accordingly.
> >>
> >> Signed-off-by: Ard Biesheuvel <ard.biesheuvel at linaro.org>
> >> ---
> >>  arch/arm64/include/asm/memory.h | 8 ++++++++
> >>  1 file changed, 8 insertions(+)
> >>
> >> diff --git a/arch/arm64/include/asm/memory.h b/arch/arm64/include/asm/memory.h
> >> index f800d45ea226..44a59c20e773 100644
> >> --- a/arch/arm64/include/asm/memory.h
> >> +++ b/arch/arm64/include/asm/memory.h
> >> @@ -114,6 +114,14 @@ extern phys_addr_t               memstart_addr;
> >>  #define PHYS_OFFSET          ({ memstart_addr; })
> >>
> >>  /*
> >> + * The maximum physical address that the linear direct mapping
> >> + * of system RAM can cover. (PAGE_OFFSET can be interpreted as
> >> + * a 2's complement signed quantity and negated to derive the
> >> + * maximum size of the linear mapping.)
> >> + */
> >> +#define MAX_MEMBLOCK_ADDR    ({ memstart_addr - PAGE_OFFSET - 1; })
> >
> > If we initialised memory_limit to this value and changed early_mem to
> > use min (i.e. only restrict the limit further), would that avoid the
> > need to change the of code? It looks like PPC uses
> > memblock_enforce_memory_limit for similar reasons.
> 
> Yes, that would be yet another way of doing things. But since Catalin
> explicitly requested that both checks (i.e., bottom end and top end)
> occur in the same place, and indicated his preference not to override
> early_init_dt_add_memory_arch() if we can avoid it, the only way is to
> hack it in there.

Talking to Will, we decided to go for a quick fix with cc stable that
does something like:

	memblock_enforce_memory_limit(min(memory_limit, ~PAGE_OFFSET));

Afterwards, we should still sort early_init_dt_add_memory_arch() to get
the nicer printing since, as it stands, checking that a u64 is bigger
than ULONG_MAX is pointless on 64-bit.

Thanks.

-- 
Catalin


From ard.biesheuvel at linaro.org  Tue Aug 18 10:44:59 2015
From: ard.biesheuvel at linaro.org (Ard Biesheuvel)
Date: Tue, 18 Aug 2015 19:44:59 +0200
Subject: [PATCH 2/2] arm64: set MAX_MEMBLOCK_ADDR according to linear
 region size
In-Reply-To: <20150818173938.GH11571@e104818-lin.cambridge.arm.com>
References: <1439890482-20798-1-git-send-email-ard.biesheuvel@linaro.org>
 <1439890482-20798-3-git-send-email-ard.biesheuvel@linaro.org>
 <20150818100018.GA11021@arm.com>
 <CAKv+Gu-YDEKSrkSG2fywgrHBB3Hao+jodknmCAkFCWqG4OpXCA@mail.gmail.com>
 <20150818173938.GH11571@e104818-lin.cambridge.arm.com>
Message-ID: <CAKv+Gu8hBCtxUHqBwCjfiati7kbWrq314_mTjRvzf7ZnjWXsuw@mail.gmail.com>

On 18 August 2015 at 19:39, Catalin Marinas <catalin.marinas at arm.com> wrote:
> On Tue, Aug 18, 2015 at 12:04:27PM +0200, Ard Biesheuvel wrote:
>> On 18 August 2015 at 12:00, Will Deacon <will.deacon at arm.com> wrote:
>> > On Tue, Aug 18, 2015 at 10:34:42AM +0100, Ard Biesheuvel wrote:
>> >> The linear region size of a 39-bit VA kernel is only 256 GB, which
>> >> may be insufficient to cover all of system RAM, even on platforms
>> >> that have much less than 256 GB of memory but which is laid out
>> >> very sparsely.
>> >>
>> >> So make sure we clip the memory we will not be able to map before
>> >> installing it into the memblock memory table, by setting
>> >> MAX_MEMBLOCK_ADDR accordingly.
>> >>
>> >> Signed-off-by: Ard Biesheuvel <ard.biesheuvel at linaro.org>
>> >> ---
>> >>  arch/arm64/include/asm/memory.h | 8 ++++++++
>> >>  1 file changed, 8 insertions(+)
>> >>
>> >> diff --git a/arch/arm64/include/asm/memory.h b/arch/arm64/include/asm/memory.h
>> >> index f800d45ea226..44a59c20e773 100644
>> >> --- a/arch/arm64/include/asm/memory.h
>> >> +++ b/arch/arm64/include/asm/memory.h
>> >> @@ -114,6 +114,14 @@ extern phys_addr_t               memstart_addr;
>> >>  #define PHYS_OFFSET          ({ memstart_addr; })
>> >>
>> >>  /*
>> >> + * The maximum physical address that the linear direct mapping
>> >> + * of system RAM can cover. (PAGE_OFFSET can be interpreted as
>> >> + * a 2's complement signed quantity and negated to derive the
>> >> + * maximum size of the linear mapping.)
>> >> + */
>> >> +#define MAX_MEMBLOCK_ADDR    ({ memstart_addr - PAGE_OFFSET - 1; })
>> >
>> > If we initialised memory_limit to this value and changed early_mem to
>> > use min (i.e. only restrict the limit further), would that avoid the
>> > need to change the of code? It looks like PPC uses
>> > memblock_enforce_memory_limit for similar reasons.
>>
>> Yes, that would be yet another way of doing things. But since Catalin
>> explicitly requested that both checks (i.e., bottom end and top end)
>> occur in the same place, and indicated his preference not to override
>> early_init_dt_add_memory_arch() if we can avoid it, the only way is to
>> hack it in there.
>
> Talking to Will, we decided to go for a quick fix with cc stable that
> does something like:
>
>         memblock_enforce_memory_limit(min(memory_limit, ~PAGE_OFFSET));
>

~PAGE_OFFSET + 1 ?

> Afterwards, we should still sort early_init_dt_add_memory_arch() to get
> the nicer printing since, as it stands, checking that a u64 is bigger
> than ULONG_MAX is pointless on 64-bit.
>
> Thanks.
>
> --
> Catalin


From alex.williamson at redhat.com  Tue Aug 18 10:44:24 2015
From: alex.williamson at redhat.com (Alex Williamson)
Date: Tue, 18 Aug 2015 11:44:24 -0600
Subject: [PATCH v3 04/10] VFIO: platform: add vfio_platform_set_automasked
In-Reply-To: <55D1FFE8.9050104@linaro.org>
References: <1439212864-12954-1-git-send-email-eric.auger@linaro.org>
 <1439212864-12954-5-git-send-email-eric.auger@linaro.org>
 <1439405794.4023.528.camel@redhat.com> <55D1FFE8.9050104@linaro.org>
Message-ID: <1439919864.4023.626.camel@redhat.com>

On Mon, 2015-08-17 at 17:38 +0200, Eric Auger wrote:
> On 08/12/2015 08:56 PM, Alex Williamson wrote:
> > On Mon, 2015-08-10 at 15:20 +0200, Eric Auger wrote:
> >> This function makes possible to change the automasked mode.
> >>
> >> Signed-off-by: Eric Auger <eric.auger at linaro.org>
> >>
> >> ---
> >>
> >> v1 -> v2:
> >> - set forwarded flag
> >> ---
> >>  drivers/vfio/platform/vfio_platform_irq.c | 19 +++++++++++++++++++
> >>  1 file changed, 19 insertions(+)
> >>
> >> diff --git a/drivers/vfio/platform/vfio_platform_irq.c b/drivers/vfio/platform/vfio_platform_irq.c
> >> index b31b1f0..a285384 100644
> >> --- a/drivers/vfio/platform/vfio_platform_irq.c
> >> +++ b/drivers/vfio/platform/vfio_platform_irq.c
> >> @@ -186,6 +186,25 @@ static irqreturn_t vfio_handler(int irq, void *dev_id)
> >>  	return ret;
> >>  }
> >>  
> >> +static int vfio_platform_set_automasked(struct vfio_platform_irq *irq,
> >> +					   bool automasked)
> >> +{
> >> +	unsigned long flags;
> >> +
> >> +	spin_lock_irqsave(&irq->lock, flags);
> >> +	if (automasked) {
> >> +		irq->forwarded = true;
> >> +		irq->flags |= VFIO_IRQ_INFO_AUTOMASKED;
> >> +		irq->handler = vfio_automasked_irq_handler;
> >> +	} else {
> >> +		irq->forwarded = false;
> >> +		irq->flags &= ~VFIO_IRQ_INFO_AUTOMASKED;
> >> +		irq->handler = vfio_irq_handler;
> >> +	}
> >> +	spin_unlock_irqrestore(&irq->lock, flags);
> >> +	return 0;
> > 
> > In vfio-speak, automasked means level and we're not magically changing
> > the IRQ from level to edge, we're simply able to handle level
> > differently based on a hardware optimization.  Should the user visible
> > flags therefore change based on this?  Aren't we really setting the
> > forwarded state rather than the automasked state?
> 
> Well actually this was following the discussion we had a long time ago
> about that topic:
> 
> http://lkml.iu.edu/hypermail/linux/kernel/1409.1/03659.html
> 
> I did not really know how to conclude ...
> 
> If it is preferred I can hide this to the userspace, no problem.

I think that was based on the user being involved in enabling forwarding
though, now that it's hidden and automatic, it doesn't make much sense
to me to toggle any of the interrupt info details based on the state of
the forward.  The user always needs to handle the interrupt as level
since the bypass can be torn down at any point in time.  We're taking
advantage of the in-kernel path to make further optimizations, which
seems like they should be transparent to the user.  Thanks,

Alex



From bjorn.andersson at sonymobile.com  Tue Aug 18 10:59:21 2015
From: bjorn.andersson at sonymobile.com (Bjorn Andersson)
Date: Tue, 18 Aug 2015 10:59:21 -0700
Subject: [PATCH v3 1/3] ARM: qcom: add SFPB nodes to IPQ806x dts
In-Reply-To: <1439855266-26242-2-git-send-email-mathieu@codeaurora.org>
References: <1439855266-26242-1-git-send-email-mathieu@codeaurora.org>
 <1439855266-26242-2-git-send-email-mathieu@codeaurora.org>
Message-ID: <20150818175921.GT13472@usrtlx11787.corpusers.net>

On Mon 17 Aug 16:47 PDT 2015, Mathieu Olivari wrote:

> Add one new node to the ipq806x.dtsi file to declare & register the
> hardware spinlock devices. This mechanism is required to be used by
> other drivers such as SMEM.
> 

Reviewed-by: Bjorn Andersson <bjorn.andersson at sonymobile.com>

> Signed-off-by: Mathieu Olivari <mathieu at codeaurora.org>
> ---
>  arch/arm/boot/dts/qcom-ipq8064.dtsi | 11 +++++++++++
>  1 file changed, 11 insertions(+)
> 
> diff --git a/arch/arm/boot/dts/qcom-ipq8064.dtsi b/arch/arm/boot/dts/qcom-ipq8064.dtsi
> index 9f727d8..8d366ae 100644
> --- a/arch/arm/boot/dts/qcom-ipq8064.dtsi
> +++ b/arch/arm/boot/dts/qcom-ipq8064.dtsi
> @@ -329,5 +329,16 @@
>  			#reset-cells = <1>;
>  		};
>  
> +		sfpb_mutex_block: syscon at 1200600 {
> +			compatible = "syscon";
> +			reg = <0x01200600 0x100>;

I have this block listed to start at 0x1200000 and used 0x604 as offset
when testing this. In my docs there's nothing in those first 0x600 bytes
though, so this works fine for me.

> +		};
> +	};
> +
> +	sfpb_mutex: sfpb-mutex {
> +		compatible = "qcom,sfpb-mutex";
> +		syscon = <&sfpb_mutex_block 4 4>;
> +
> +		#hwlock-cells = <1>;
>  	};
>  };

Regards,
Bjorn


From bjorn.andersson at sonymobile.com  Tue Aug 18 11:10:16 2015
From: bjorn.andersson at sonymobile.com (Bjorn Andersson)
Date: Tue, 18 Aug 2015 11:10:16 -0700
Subject: [PATCH v3 3/3] mtd: add SMEM parser for QCOM platforms
In-Reply-To: <1439855266-26242-4-git-send-email-mathieu@codeaurora.org>
References: <1439855266-26242-1-git-send-email-mathieu@codeaurora.org>
 <1439855266-26242-4-git-send-email-mathieu@codeaurora.org>
Message-ID: <20150818181016.GU13472@usrtlx11787.corpusers.net>

On Mon 17 Aug 16:47 PDT 2015, Mathieu Olivari wrote:

> On QCOM platforms using MTD devices storage (such as IPQ806x), SMEM is
> used to store partition layout. This new parser can now be used to read
> SMEM and use it to register an MTD layout according to its content.

Looks good, but the license string should be "GPL v2" (lower case v).
Just as a hint...I made checkpatch warn you about that a while back ;)

The rest is

Acked-by: Bjorn Andersson <bjorn.andersson at sonymobile.com>

[..]

> +
> +MODULE_LICENSE("GPL V2");

Regards,
Bjorn


From bjorn.andersson at sonymobile.com  Tue Aug 18 11:11:38 2015
From: bjorn.andersson at sonymobile.com (Bjorn Andersson)
Date: Tue, 18 Aug 2015 11:11:38 -0700
Subject: [PATCH v3 2/3] ARM: qcom: add SMEM device node to IPQ806x dts
In-Reply-To: <1439855266-26242-3-git-send-email-mathieu@codeaurora.org>
References: <1439855266-26242-1-git-send-email-mathieu@codeaurora.org>
 <1439855266-26242-3-git-send-email-mathieu@codeaurora.org>
Message-ID: <20150818181138.GV13472@usrtlx11787.corpusers.net>

On Mon 17 Aug 16:47 PDT 2015, Mathieu Olivari wrote:

> SMEM is used on IPQ806x to store various board related information such
> as boot device and flash partition layout. We'll declare it as a device
> so we can make use of it thanks to the new SMEM soc driver.
> 
> Signed-off-by: Mathieu Olivari <mathieu at codeaurora.org>
> ---
>  arch/arm/boot/dts/qcom-ipq8064.dtsi | 8 +++++++-
>  1 file changed, 7 insertions(+), 1 deletion(-)
> 
> diff --git a/arch/arm/boot/dts/qcom-ipq8064.dtsi b/arch/arm/boot/dts/qcom-ipq8064.dtsi
> index 8d366ae..85dbccf 100644
> --- a/arch/arm/boot/dts/qcom-ipq8064.dtsi
> +++ b/arch/arm/boot/dts/qcom-ipq8064.dtsi
> @@ -55,7 +55,7 @@
>  			no-map;
>  		};
>  
> -		smem at 41000000 {
> +		smem: smem at 41000000 {

I would preferred if you used a name like "smem_region", although I
don't think we will use the phandle name "smem" for anything else...

>  			reg = <0x41000000 0x200000>;
>  			no-map;
>  		};
> @@ -341,4 +341,10 @@
>  
>  		#hwlock-cells = <1>;
>  	};
> +
> +	smem {
> +		compatible = "qcom,smem";
> +		memory-region = <&smem>;
> +		hwlocks = <&sfpb_mutex 3>;
> +	};
>  };

Acked-by: Bjorn Andersson <bjorn.andersson at sonymobile.com>

Regards,
Bjorn


From heiko at sntech.de  Tue Aug 18 11:25:38 2015
From: heiko at sntech.de (Heiko Stuebner)
Date: Tue, 18 Aug 2015 20:25:38 +0200
Subject: [PATCH v3 2/4] ASoC: rockchip: Add rockchip SPDIF transceiver
 driver
In-Reply-To: <1438947854-3743-3-git-send-email-sjoerd.simons@collabora.co.uk>
References: <1438947854-3743-1-git-send-email-sjoerd.simons@collabora.co.uk>
 <1438947854-3743-3-git-send-email-sjoerd.simons@collabora.co.uk>
Message-ID: <1463451.tH10lfH9Hm@phil>

Hi Sjoerd,


> +static int rk_spdif_probe(struct platform_device *pdev)
> +{
> +	struct rk_spdif_dev *spdif;
> +	struct resource *res;
> +	void __iomem *regs;
> +	int ret;
> +
> +	spdif = devm_kzalloc(&pdev->dev, sizeof(*spdif), GFP_KERNEL);
> +	if (!spdif)
> +		return -ENOMEM;
> +
> +	spdif->hclk = devm_clk_get(&pdev->dev, "spdif_hclk");

I guess this could be named just "hclk" - as it is the identifier local to the 
spdif-ip. (Of course in the binding too)


> +	if (IS_ERR(spdif->hclk)) {
> +		dev_err(&pdev->dev, "Can't retrieve rk_spdif bus clock\n");
> +		return PTR_ERR(spdif->hclk);
> +	}
> +	ret = clk_prepare_enable(spdif->hclk);
> +	if (ret) {
> +		dev_err(spdif->dev, "hclock enable failed %d\n", ret);
> +		return ret;
> +	}
> +
> +	spdif->mclk = devm_clk_get(&pdev->dev, "spdif_clk");

The Rockchip TRMs (and the rest of the driver as well) refer to this clock as 
"mclk", so I guess the identifier could just be named the same.


> +	if (IS_ERR(spdif->mclk)) {
> +		dev_err(&pdev->dev, "Can't retrieve rk_spdif master clock\n");
> +		return PTR_ERR(spdif->hclk);
> +	}
> +
> +	ret = clk_prepare_enable(spdif->mclk);
> +	if (ret) {
> +		dev_err(spdif->dev, "clock enable failed %d\n", ret);
> +		return ret;
> +	}

I guess this plays into what Mark already wrote, but as the code stands right 
now, you enable the mclk here and then through runtime_resume as well, so that 
it stays running all the time, as the refcount is either 2 or 1 but never 0.

Also I don't think mixing devm_clk_get + clk_prepare_enable calls works well. 
If the devm_clk_get(... "spdif_clk") fails, the hclk would stay running right 
now.


[...]

> +static int rk_spdif_remove(struct platform_device *pdev)
> +{
> +	struct rk_spdif_dev *spdif = dev_get_drvdata(&pdev->dev);
> +
> +	pm_runtime_disable(&pdev->dev);
> +	if (!pm_runtime_status_suspended(&pdev->dev))
> +		rk_spdif_runtime_suspend(&pdev->dev);
> +
> +	clk_disable_unprepare(spdif->mclk);
> +	clk_disable_unprepare(spdif->hclk);
> +	snd_dmaengine_pcm_unregister(&pdev->dev);
> +	snd_soc_unregister_component(&pdev->dev);

I think the ordering should stay symmetric to the probe function, where you 
have
	clk_enable
	snd_register
so here it should probably be
	snd_unregister 
	clk_disable



Heiko


From robert.jarzmik at free.fr  Tue Aug 18 11:31:31 2015
From: robert.jarzmik at free.fr (Robert Jarzmik)
Date: Tue, 18 Aug 2015 20:31:31 +0200
Subject: [PATCH v2 01/21] ARM: pxa: magician: Fix Kconfig for magician to
 always include htc-egpio
In-Reply-To: <55D25880.3030507@tul.cz> (Petr Cvek's message of "Mon, 17 Aug
 2015 23:56:16 +0200")
References: <cover.1439843482.git.petr.cvek@tul.cz> <55D25880.3030507@tul.cz>
Message-ID: <87zj1o8n3w.fsf@belgarion.home>

Petr Cvek <petr.cvek at tul.cz> writes:

> The htc-egpio driver should be always included in the kernel as it
> controls MMC/charging/IrDA power, which is the only way to get
> an useful rootfs.
>
> Signed-off-by: Petr Cvek <petr.cvek at tul.cz>
It's already defined in magician_defconfig, why enforce it in Kconfig ?

And if it's enforced and I want to build a kernel for magician without
MMC/charging/IrDA, why should I be forced to build in HTC_EGPIO ?

Or said differently, does a kernel without HTC_EGPIO is proven to fail 100%
without this option ?

Cheers.

-- 
Robert


From robert.jarzmik at free.fr  Tue Aug 18 11:32:45 2015
From: robert.jarzmik at free.fr (Robert Jarzmik)
Date: Tue, 18 Aug 2015 20:32:45 +0200
Subject: [PATCH v2 02/21] ARM: pxa: magician: Fix indentation and
 whitespaces
In-Reply-To: <55D258A6.2040105@tul.cz> (Petr Cvek's message of "Mon, 17 Aug
 2015 23:56:54 +0200")
References: <cover.1439843482.git.petr.cvek@tul.cz> <55D258A6.2040105@tul.cz>
Message-ID: <87vbcc8n1u.fsf@belgarion.home>

Petr Cvek <petr.cvek at tul.cz> writes:

> Fix magician.c: indentation and whitespaces.
>
> Signed-off-by: Petr Cvek <petr.cvek at tul.cz>
Unless somebody finds a flaw within the next 2 weeks, I'll queue that up.

Cheers.

--
Robert


From robert.jarzmik at free.fr  Tue Aug 18 11:39:27 2015
From: robert.jarzmik at free.fr (Robert Jarzmik)
Date: Tue, 18 Aug 2015 20:39:27 +0200
Subject: [PATCH v2 03/21] ARM: pxa: magician: Fix comments,
 debug functions and print strings
In-Reply-To: <55D258CD.40101@tul.cz> (Petr Cvek's message of "Mon, 17 Aug 2015
 23:57:33 +0200")
References: <cover.1439843482.git.petr.cvek@tul.cz> <55D258CD.40101@tul.cz>
Message-ID: <87r3n08mqo.fsf@belgarion.home>

Petr Cvek <petr.cvek at tul.cz> writes:

> Fix comments, debug functions and print strings. Rename backlight
> structures to be more specific.
>
> Signed-off-by: Petr Cvek <petr.cvek at tul.cz>
> ---
>  arch/arm/mach-pxa/magician.c | 121 +++++++++++++++++++++++++++++++------------
>  1 file changed, 89 insertions(+), 32 deletions(-)
>
> diff --git a/arch/arm/mach-pxa/magician.c b/arch/arm/mach-pxa/magician.c
> index 9e8698a..57da133 100644
> --- a/arch/arm/mach-pxa/magician.c
> +++ b/arch/arm/mach-pxa/magician.c
> @@ -11,6 +11,46 @@
>   * it under the terms of the GNU General Public License version 2 as
>   * published by the Free Software Foundation.
>   *
> + *
> + * NOTICE MDA Compact (T-mobile XDA) facts:
> + *   On "LCD type = 1, system_rev = 2" (0x3a in CPLD)
> + * Samsung LTP280QV - valid LCD init sequence sequence:
> + *   powerup: Vdigital->Vanalog->gate Voff->gate Von->data enable
> + *   powerdown: data disable->gate Von->gate Voff->Vanalog->Vdigital
> + * Measured on PCB:
> + *   GPIO106
> + *     Affects VOFF, VON and other voltages
> + *     Probably main reset pin for DC-DC converter
> + *   GPIO75
> + *     Must be AF0+OUT (WM leaves it to AF2+OUT), not LCD signal
> + *     GPIO106 works only when GPIO75 is high (DC-DC power enable?)
> + *     After LCD powerup, value is irrelevant
> + *   GPIO104
> + *     LCD VOFF (gate off voltage)
> + *   GPIO105
> + *     LCD VON (gate on voltage)
> + * FFUART (/dev/ttyS0) WM: 38400,8,n,1,crtscts (GSM data?)
> + * BTUART (/dev/ttyS1) WM: 115200,8,n,1,crtscts (GSM AT commands)
> + *   Use a HTC line discipline: 0x02 channel(==0x16) data 0x02
> + * EGPIO(CPLD) should be always present (controls "all" supply power)
> + *   For rootfs on MMC/SD: EGPIO module controls card power (in kernel)
> + * cpu-freq often freeze platform (errata?, use userspace gov)
> + * Do not use YUV420, (erratum E24) causes LCD hang (forever)
> + * Many GSM related pins are unknown
> + * gpio-rc-recv probably require lowpass filter (sw is OK)
> + * TODO EGPIO_MAGICIAN_IR_RECEIVE_SHUTDOWN
> + * FIXME AC charging blocks IrDA
> + * Unimplemented blocking of camera+power+reset, reset and door open reset
> + *   Registers: htc-pasic3.h (but blocks charging too)
> + * Other PXA machines have wait_for_sync for ADS7846 (during LCD refresh)
> + * pda-power has not optimal charging (accu can be bloated)
> + * TODO Current switching works? Is gpio-regulator/bq24022 required?
I think you can ask Philip, he's the maintainer after all ...

> + * pdata supports alternative drivers (mutually exclusive modules)
> + *   i2c-pxa vs i2c-gpio (SCCB)
> + *   pwm_bl vs gpio_backlight
> + *   pxa27x_udc vs phy-gpio-vbus-usb
> + *   physmap-flash vs pxa2xx-flash

Okay, this chunk is nice documentation, but not code ...
I'd rather have it in : Documentation/arm/pxa/magician.txt or something like
that.

> @@ -120,11 +160,12 @@ static unsigned long magician_pin_config[] __initdata = {
>  };
>  
>  /*
> - * IRDA
> + * IrDA
>   */
>  
>  static struct pxaficp_platform_data magician_ficp_info = {
>  	.gpio_pwdown		= GPIO83_MAGICIAN_nIR_EN,
> +	/* TODO test with FIR dongle */
I don't like this comment. I was not there before, so let it be. You know there
remains a TODO, I know ... but you can cunningly slip it in the commit message.

Cheers.

-- 
Robert


From briannorris at chromium.org  Tue Aug 18 11:44:15 2015
From: briannorris at chromium.org (Brian Norris)
Date: Tue, 18 Aug 2015 11:44:15 -0700
Subject: [PATCH 2/2] ARM: dts: rockchip: correct regulator PM properties
In-Reply-To: <1439923455-109818-1-git-send-email-briannorris@chromium.org>
References: <1439923455-109818-1-git-send-email-briannorris@chromium.org>
Message-ID: <1439923455-109818-2-git-send-email-briannorris@chromium.org>

This DTS file was submitted with non-upstream bindings. I happened
across this while reviewing the jaq DTS.

Signed-off-by: Brian Norris <briannorris at chromium.org>
Cc: Alexandru M Stan <amstan at chromium.org>
Cc: Douglas Anderson <dianders at chromium.org>
---
Tested on jaq, not minnie

 arch/arm/boot/dts/rk3288-veyron-minnie.dts | 8 ++++++--
 1 file changed, 6 insertions(+), 2 deletions(-)

diff --git a/arch/arm/boot/dts/rk3288-veyron-minnie.dts b/arch/arm/boot/dts/rk3288-veyron-minnie.dts
index 0e30bd6bf92b..6f619c154dc6 100644
--- a/arch/arm/boot/dts/rk3288-veyron-minnie.dts
+++ b/arch/arm/boot/dts/rk3288-veyron-minnie.dts
@@ -128,12 +128,16 @@
 			regulator-min-microvolt = <3300000>;
 			regulator-max-microvolt = <3300000>;
 			regulator-name = "vcc33_touch";
-			regulator-suspend-mem-disabled;
+			regulator-state-mem {
+				regulator-on-in-suspend;
+			};
 		};
 
 		vcc5v_touch: SWITCH_REG2 {
 			regulator-name = "vcc5v_touch";
-			regulator-suspend-mem-disabled;
+			regulator-state-mem {
+				regulator-on-in-suspend;
+			};
 		};
 	};
 };
-- 
2.5.0.276.gf5e568e



From briannorris at chromium.org  Tue Aug 18 11:44:14 2015
From: briannorris at chromium.org (Brian Norris)
Date: Tue, 18 Aug 2015 11:44:14 -0700
Subject: [PATCH 1/2] ARM: dts: rockchip: add veyron-jaq board
Message-ID: <1439923455-109818-1-git-send-email-briannorris@chromium.org>

a.k.a. Haier Chromebook 11

Signed-off-by: Brian Norris <briannorris at chromium.org>
Cc: Alexandru M Stan <amstan at chromium.org>
Cc: Douglas Anderson <dianders at chromium.org>
---
 arch/arm/boot/dts/Makefile              |   1 +
 arch/arm/boot/dts/rk3288-veyron-jaq.dts | 176 ++++++++++++++++++++++++++++++++
 2 files changed, 177 insertions(+)
 create mode 100644 arch/arm/boot/dts/rk3288-veyron-jaq.dts

diff --git a/arch/arm/boot/dts/Makefile b/arch/arm/boot/dts/Makefile
index 7805a6541a38..7a2c3c88ce9e 100644
--- a/arch/arm/boot/dts/Makefile
+++ b/arch/arm/boot/dts/Makefile
@@ -493,6 +493,7 @@ dtb-$(CONFIG_ARCH_ROCKCHIP) += \
 	rk3288-veyron-jerry.dtb \
 	rk3288-veyron-minnie.dtb \
 	rk3288-veyron-pinky.dtb \
+	rk3288-veyron-jaq.dtb \
 	rk3288-veyron-speedy.dtb
 dtb-$(CONFIG_ARCH_S3C24XX) += \
 	s3c2416-smdk2416.dtb
diff --git a/arch/arm/boot/dts/rk3288-veyron-jaq.dts b/arch/arm/boot/dts/rk3288-veyron-jaq.dts
new file mode 100644
index 000000000000..ea6130156216
--- /dev/null
+++ b/arch/arm/boot/dts/rk3288-veyron-jaq.dts
@@ -0,0 +1,176 @@
+/*
+ * Google Veyron Jaq Rev 1+ board device tree source
+ *
+ * Copyright 2015 Google, Inc
+ *
+ * This file is dual-licensed: you can use it either under the terms
+ * of the GPL or the X11 license, at your option. Note that this dual
+ * licensing only applies to this file, and not this project as a
+ * whole.
+ *
+ *  a) This file is free software; you can redistribute it and/or
+ *     modify it under the terms of the GNU General Public License as
+ *     published by the Free Software Foundation; either version 2 of the
+ *     License, or (at your option) any later version.
+ *
+ *     This file is distributed in the hope that it will be useful,
+ *     but WITHOUT ANY WARRANTY; without even the implied warranty of
+ *     MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ *     GNU General Public License for more details.
+ *
+ *  Or, alternatively,
+ *
+ *  b) Permission is hereby granted, free of charge, to any person
+ *     obtaining a copy of this software and associated documentation
+ *     files (the "Software"), to deal in the Software without
+ *     restriction, including without limitation the rights to use,
+ *     copy, modify, merge, publish, distribute, sublicense, and/or
+ *     sell copies of the Software, and to permit persons to whom the
+ *     Software is furnished to do so, subject to the following
+ *     conditions:
+ *
+ *     The above copyright notice and this permission notice shall be
+ *     included in all copies or substantial portions of the Software.
+ *
+ *     THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
+ *     EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES
+ *     OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
+ *     NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT
+ *     HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY,
+ *     WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
+ *     FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR
+ *     OTHER DEALINGS IN THE SOFTWARE.
+ */
+
+/dts-v1/;
+
+#include "rk3288-veyron-chromebook.dtsi"
+#include "cros-ec-sbs.dtsi"
+
+/ {
+	model = "Google Jaq";
+	compatible = "google,veyron-jaq-rev5", "google,veyron-jaq-rev4",
+		     "google,veyron-jaq-rev3", "google,veyron-jaq-rev2",
+		     "google,veyron-jaq-rev1", "google,veyron-jaq",
+		     "google,veyron", "rockchip,rk3288";
+
+	panel_regulator: panel-regulator {
+		compatible = "regulator-fixed";
+		enable-active-high;
+		gpio = <&gpio7 14 GPIO_ACTIVE_HIGH>;
+		pinctrl-names = "default";
+		pinctrl-0 = <&lcd_enable_h>;
+		regulator-name = "panel_regulator";
+		vin-supply = <&vcc33_sys>;
+	};
+
+	vcc18_lcd: vcc18-lcd {
+		compatible = "regulator-fixed";
+		enable-active-high;
+		gpio = <&gpio2 13 GPIO_ACTIVE_HIGH>;
+		pinctrl-names = "default";
+		pinctrl-0 = <&avdd_1v8_disp_en>;
+		regulator-name = "vcc18_lcd";
+		regulator-always-on;
+		regulator-boot-on;
+		vin-supply = <&vcc18_wl>;
+	};
+
+	backlight_regulator: backlight-regulator {
+		compatible = "regulator-fixed";
+		enable-active-high;
+		gpio = <&gpio2 12 GPIO_ACTIVE_HIGH>;
+		pinctrl-names = "default";
+		pinctrl-0 = <&bl_pwr_en>;
+		regulator-name = "backlight_regulator";
+		vin-supply = <&vcc33_sys>;
+		startup-delay-us = <15000>;
+	};
+};
+
+&rk808 {
+	pinctrl-names = "default";
+	pinctrl-0 = <&pmic_int_l &dvs_1 &dvs_2>;
+	dvs-gpios = <&gpio7 12 GPIO_ACTIVE_HIGH>,
+		    <&gpio7 15 GPIO_ACTIVE_HIGH>;
+
+	regulators {
+		mic_vcc: LDO_REG2 {
+			regulator-name = "mic_vcc";
+			regulator-always-on;
+			regulator-boot-on;
+			regulator-min-microvolt = <1800000>;
+			regulator-max-microvolt = <1800000>;
+			regulator-state-mem {
+				regulator-on-in-suspend;
+			};
+		};
+	};
+};
+
+&sdmmc {
+	disable-wp;
+	pinctrl-names = "default";
+	pinctrl-0 = <&sdmmc_clk &sdmmc_cmd &sdmmc_cd_disabled &sdmmc_cd_gpio
+			&sdmmc_bus4>;
+};
+
+&vcc_5v {
+	enable-active-high;
+	gpio = <&gpio7 21 GPIO_ACTIVE_HIGH>;
+	pinctrl-names = "default";
+	pinctrl-0 = <&drv_5v>;
+};
+
+&vcc50_hdmi {
+	enable-active-high;
+	gpio = <&gpio5 19 GPIO_ACTIVE_HIGH>;
+	pinctrl-names = "default";
+	pinctrl-0 = <&vcc50_hdmi_en>;
+};
+
+&pinctrl {
+	backlight {
+		bl_pwr_en: bl_pwr_en {
+			rockchip,pins = <2 12 RK_FUNC_GPIO &pcfg_pull_none>;
+		};
+	};
+
+	buck-5v {
+		drv_5v: drv-5v {
+			rockchip,pins = <7 21 RK_FUNC_GPIO &pcfg_pull_none>;
+		};
+	};
+
+	edp {
+		edp_hpd: edp_hpd {
+			rockchip,pins = <7 11 RK_FUNC_2 &pcfg_pull_down>;
+		};
+	};
+
+	hdmi {
+		vcc50_hdmi_en: vcc50-hdmi-en {
+			rockchip,pins = <5 19 RK_FUNC_GPIO &pcfg_pull_none>;
+		};
+	};
+
+	lcd {
+		lcd_enable_h: lcd-en {
+			rockchip,pins = <7 14 RK_FUNC_GPIO &pcfg_pull_none>;
+		};
+
+		avdd_1v8_disp_en: avdd-1v8-disp-en {
+			rockchip,pins = <2 13 RK_FUNC_GPIO &pcfg_pull_none>;
+		};
+	};
+
+	pmic {
+		dvs_1: dvs-1 {
+			rockchip,pins = <7 12 RK_FUNC_GPIO &pcfg_pull_down>;
+		};
+
+		dvs_2: dvs-2 {
+			rockchip,pins = <7 15 RK_FUNC_GPIO &pcfg_pull_down>;
+		};
+	};
+};
-- 
2.5.0.276.gf5e568e



From robert.jarzmik at free.fr  Tue Aug 18 12:01:09 2015
From: robert.jarzmik at free.fr (Robert Jarzmik)
Date: Tue, 18 Aug 2015 21:01:09 +0200
Subject: [PATCH v2 04/21] ARM: pxa: magician: Add, fix and init (new) GPIOs
In-Reply-To: <55D258E9.9010303@tul.cz> (Petr Cvek's message of "Mon, 17 Aug
 2015 23:58:01 +0200")
References: <cover.1439843482.git.petr.cvek@tul.cz> <55D258E9.9010303@tul.cz>
Message-ID: <87mvxo8lqi.fsf@belgarion.home>

Petr Cvek <petr.cvek at tul.cz> writes:

> Add new GPIOs, fix some GPIO names and initialization (EGPIO, LCD power on
> sequence).
>
> Signed-off-by: Petr Cvek <petr.cvek at tul.cz>
> ---
>  arch/arm/mach-pxa/include/mach/magician.h |  39 ++++---
>  arch/arm/mach-pxa/magician.c              | 166 +++++++++++++++++++++++-------
>  2 files changed, 153 insertions(+), 52 deletions(-)
>
> diff --git a/arch/arm/mach-pxa/include/mach/magician.h b/arch/arm/mach-pxa/include/mach/magician.h
> index ba6a6e1..d19e504 100644
> --- a/arch/arm/mach-pxa/include/mach/magician.h
> +++ b/arch/arm/mach-pxa/include/mach/magician.h
> @@ -21,10 +21,10 @@
>  
>  #define GPIO0_MAGICIAN_KEY_POWER		0
>  #define GPIO9_MAGICIAN_UNKNOWN			9
> -#define GPIO10_MAGICIAN_GSM_IRQ			10
> +#define GPIO10_MAGICIAN_GSM_IRQ		10
Whitespace/indentation changes ?

>  #define GPIO11_MAGICIAN_GSM_OUT1		11
>  #define GPIO13_MAGICIAN_CPLD_IRQ		13
> -#define GPIO18_MAGICIAN_UNKNOWN			18
> +#define GPIO18_MAGICIAN_UNKNOWN		18
Ditto.

> @@ -32,8 +32,10 @@
>  #define GPIO37_MAGICIAN_KEY_HANGUP		37
>  #define GPIO38_MAGICIAN_KEY_CONTACTS		38
>  #define GPIO40_MAGICIAN_GSM_OUT2		40
> -#define GPIO48_MAGICIAN_UNKNOWN			48
> -#define GPIO56_MAGICIAN_UNKNOWN			56
> +#define GPIO46_MAGICIAN_IR_RX			46
> +#define GPIO47_MAGICIAN_IR_TX			47
> +#define GPIO48_MAGICIAN_UNKNOWN		48
> +#define GPIO56_MAGICIAN_UNKNOWN		56
Ditto for 48, 56 ?

>  #define GPIO57_MAGICIAN_CAM_RESET		57
>  #define GPIO75_MAGICIAN_SAMSUNG_POWER		75
>  #define GPIO83_MAGICIAN_nIR_EN			83
> @@ -51,15 +53,17 @@
>  #define GPIO100_MAGICIAN_KEY_VOL_UP		100
>  #define GPIO101_MAGICIAN_KEY_VOL_DOWN 		101
>  #define GPIO102_MAGICIAN_KEY_PHONE		102
> -#define GPIO103_MAGICIAN_LED_KP			103
> -#define GPIO104_MAGICIAN_LCD_POWER_1 		104
> -#define GPIO105_MAGICIAN_LCD_POWER_2		105
> -#define GPIO106_MAGICIAN_LCD_POWER_3		106
> +#define GPIO103_MAGICIAN_LED_KP		103
Ditto ?
> +#define GPIO104_MAGICIAN_LCD_VOFF_EN		104
> +#define GPIO105_MAGICIAN_LCD_VON_EN		105
> +#define GPIO106_MAGICIAN_LCD_DCDC_NRESET	106
>  #define GPIO107_MAGICIAN_DS1WM_IRQ		107
>  #define GPIO108_MAGICIAN_GSM_READY		108
>  #define GPIO114_MAGICIAN_UNKNOWN		114
>  #define GPIO115_MAGICIAN_nPEN_IRQ		115
>  #define GPIO116_MAGICIAN_nCAM_EN		116
> +#define GPIO117_MAGICIAN_I2C_SCL		117
> +#define GPIO118_MAGICIAN_I2C_SDA		118
>  #define GPIO119_MAGICIAN_UNKNOWN		119
>  #define GPIO120_MAGICIAN_UNKNOWN		120
>  
> @@ -78,7 +82,7 @@
>   * CPLD EGPIOs
>   */
>  
> -#define MAGICIAN_EGPIO_BASE			PXA_NR_BUILTIN_GPIO
> +#define MAGICIAN_EGPIO_BASE	PXA_NR_BUILTIN_GPIO
Ditto ?

>From here onward, I'll suppose you'll catch all whitespace/indentation changes
and extract them towards patch 01/21 ...

>  /* input */
>  
> -#define EGPIO_MAGICIAN_CABLE_STATE_AC		MAGICIAN_EGPIO(4, 0)
> -#define EGPIO_MAGICIAN_CABLE_STATE_USB		MAGICIAN_EGPIO(4, 1)
> +/* AC=1, USB=0 */
> +#define EGPIO_MAGICIAN_CABLE_TYPE		MAGICIAN_EGPIO(4, 0)
> +/* =1 when AC or USB cable inserted */
> +#define EGPIO_MAGICIAN_CABLE_INSERT1		MAGICIAN_EGPIO(4, 1)
The naming makes me uneasy : it's rather vague "cable insert".
If AC and USB are the only charging methods, why not have something like
"EGPIO_MAGICIAN_POWERED" or the like ?

>  	GPIO10_GPIO,	/* GSM_IRQ */
>  	GPIO13_GPIO,	/* CPLD_IRQ */
>  	GPIO107_GPIO,	/* DS1WM_IRQ */
>  	GPIO108_GPIO,	/* GSM_READY */
>  	GPIO115_GPIO,	/* nPEN_IRQ */
>  
> -	/* I2C */
> -	GPIO117_I2C_SCL,
> -	GPIO118_I2C_SDA,
Okay so that are no I2C devices on magician ? Why keep GPIO119_MAGICIAN_I2C_* at
the beginning of the file then ?

> +	MFP_CFG_OUT(GPIO40, AF0, DRIVE_LOW),	/* FIXME GSM? */
> +	MFP_CFG_OUT(GPIO87, AF0, DRIVE_LOW),	/* FIXME GSM? */
> +
> +	/* Left GPIOs (undefined here):
> +	 * 18, 49 : bootloader=VLIO?, WinM=TODO
> +	 * 48 : AF0/out0
> +	 * 56 : AF0/out0
> +	 * 74 : bootloader=AF0/output
> +	 * 86 : bootloader=AF0/input (but should be gsm reset???)
> +	 * 114 : AF0/out0
> +	 * 119 : AF0/out0
> +	 * 120 : AF0/out
> +	 * 1 : dedicated reset, AF0/output
> +	 * 13 : cpld irq, output (??)
> +	 */
This is not describing current code. This doesn't belong to this file, even if I
know how frustrating it is to reverse engineer all these gpios. I created a wiki
web page will all GPIOs to let go my frustration in the past :)

> @@ -241,8 +324,9 @@ static struct htc_egpio_chip egpio_chips[] = {
>  
>  		/*
>  		 * Depends on modules configuration
> +		 * Things like MMC and LCD should be enabled
>  		 */
> -		.initial_values = 0x40,
> +		.initial_values = 0x21a0c0,
Aren't they enabled by each driver upon its probe() ? What if MMC nor LCD is
compiled in the kernel ?

> @@ -343,21 +427,19 @@ static void samsung_lcd_power(int on, struct fb_var_screeninfo *si)
>  			gpio_set_value(GPIO75_MAGICIAN_SAMSUNG_POWER, 1);
>  		else
>  			gpio_set_value(EGPIO_MAGICIAN_LCD_POWER, 1);
> -		mdelay(10);
> -		gpio_set_value(GPIO106_MAGICIAN_LCD_POWER_3, 1);
> -		mdelay(10);
> -		gpio_set_value(GPIO104_MAGICIAN_LCD_POWER_1, 1);
> -		mdelay(30);
> -		gpio_set_value(GPIO105_MAGICIAN_LCD_POWER_2, 1);
> -		mdelay(10);
> +		mdelay(6);
> +		gpio_set_value(GPIO106_MAGICIAN_LCD_DCDC_NRESET, 1);
> +		mdelay(6);	/* Avdd -> Voff >5ms */
> +		gpio_set_value(GPIO104_MAGICIAN_LCD_VOFF_EN, 1);
> +		mdelay(16);	/* Voff -> Von >(5+10)ms */
> +		gpio_set_value(GPIO105_MAGICIAN_LCD_VON_EN, 1);
>  	} else {
> -		mdelay(10);
> -		gpio_set_value(GPIO105_MAGICIAN_LCD_POWER_2, 0);
> -		mdelay(30);
> -		gpio_set_value(GPIO104_MAGICIAN_LCD_POWER_1, 0);
> -		mdelay(10);
> -		gpio_set_value(GPIO106_MAGICIAN_LCD_POWER_3, 0);
> -		mdelay(10);
> +		gpio_set_value(GPIO105_MAGICIAN_LCD_VON_EN, 0);
> +		mdelay(16);
> +		gpio_set_value(GPIO104_MAGICIAN_LCD_VOFF_EN, 0);
> +		mdelay(6);
> +		gpio_set_value(GPIO106_MAGICIAN_LCD_DCDC_NRESET, 0);
> +		mdelay(6);
You're changing the timings here, right ? This should be an appart patch. What
is the reason of the change by the way ?

Cheers.

-- 
Robert

PS: My workforce is done for today, next review tomorrow.


From timur at codeaurora.org  Tue Aug 18 12:07:09 2015
From: timur at codeaurora.org (Timur Tabi)
Date: Tue, 18 Aug 2015 14:07:09 -0500
Subject: [PATCH 2/3] [v4] ARM64: TTY: hvc_dcc: Add support for ARM64 dcc
In-Reply-To: <20150818082141.GA6281@e103592.cambridge.arm.com>
References: <1438992995-22610-1-git-send-email-timur@codeaurora.org>
 <1438992995-22610-2-git-send-email-timur@codeaurora.org>
 <20150810094008.GD1604@arm.com> <55D2749A.401@codeaurora.org>
 <20150818082141.GA6281@e103592.cambridge.arm.com>
Message-ID: <55D3825D.6020105@codeaurora.org>

On 08/18/2015 03:21 AM, Dave Martin wrote:
>> Do you think that I need an explicit instruction to clear the upper
>> >bits?  I tried a few compiler tricks (e.g. "c && 0xff" and the
>> >like), and they had no effect.
> The in-register representation of a char permits the upper bits to be
> nonzero, so you need to convert to a register-sized type if you want
> to be able to force those bits to zero.
>
> Try: (unsigned long)(unsigned char)c or (unsigned long)c & 0xff.

I tried all those, and more, and I still always get the same thing:

   28:	38401423 	ldrb	w3, [x1],#1
   2c:	d5130503 	msr	dbgdtrrx_el0, x3

I know that ldrb will zero-extend the byte to a 32-bit word.  But I 
don't see any way to zero-extend the word into a 64-bit register.

I'm not even sure that this is necessary.  The dbgdtrrx_el0 register is 
technically only 32-bit anyway.  It looks to me like the code is already 
correct.

I could change the (c) to "(c && 0xff)" to be extra sure, but I can't 
verify that it actually works.

>> >it gives this assembly code:
>> >
>> >   28:	38401423 	ldrb	w3, [x1],#1
>> >   2c:	53001c63 	uxtb	w3, w3
>> >   30:	d5130503 	msr	dbgdtrrx_el0, x3
>> >
>> >Is this correct?  Shouldn't it be "uxtb x3, w3"?
> Check the ARM ARM for what operand combinations are allowed.  However,
> it doesn't really make any difference here because it's a general rule
> in the architecture that when an instruction's output is in a
> W-register, the upper 32 bits of the corresponding X-register are
> always zeroed anyway.

So does that mean that ldrb will zero-extend the byte to all 64 bits of x3?

-- 
Qualcomm Innovation Center, Inc.
The Qualcomm Innovation Center, Inc. is a member of the
Code Aurora Forum, a Linux Foundation Collaborative Project.


From dinh.linux at gmail.com  Tue Aug 18 12:11:58 2015
From: dinh.linux at gmail.com (Dinh Nguyen)
Date: Tue, 18 Aug 2015 14:11:58 -0500
Subject: [PATCH v4 2/5] pci:host: Add Altera PCIe host controller driver
In-Reply-To: <1439802579-22651-3-git-send-email-lftan@altera.com>
References: <1439802579-22651-1-git-send-email-lftan@altera.com>
 <1439802579-22651-3-git-send-email-lftan@altera.com>
Message-ID: <CADhT+wfjYaEefScKNz-R5miA+_Ybm8PTHgG6jDT9ntb9e89twQ@mail.gmail.com>

On Mon, Aug 17, 2015 at 4:09 AM, Ley Foon Tan <lftan at altera.com> wrote:
> This patch adds the Altera PCIe host controller driver.
>
> Signed-off-by: Ley Foon Tan <lftan at altera.com>
> ---
>  drivers/pci/host/Kconfig       |   7 +
>  drivers/pci/host/Makefile      |   1 +
>  drivers/pci/host/pcie-altera.c | 543 +++++++++++++++++++++++++++++++++++++++++
>  3 files changed, 551 insertions(+)
>  create mode 100644 drivers/pci/host/pcie-altera.c
>
> diff --git a/drivers/pci/host/Kconfig b/drivers/pci/host/Kconfig
> index 675c2d1..4b4754a 100644
> --- a/drivers/pci/host/Kconfig
> +++ b/drivers/pci/host/Kconfig
> @@ -145,4 +145,11 @@ config PCIE_IPROC_BCMA
>           Say Y here if you want to use the Broadcom iProc PCIe controller
>           through the BCMA bus interface
>

<snip>

> +
> +/* Address translation table entry size */
> +#define ATT_ENTRY_SIZE         8
> +
> +#define DWORD_MASK             3
> +
> +struct altera_pcie {
> +       struct platform_device  *pdev;
> +       struct resource         *txs;

You have "Txs" documented in the bindings document, you have a pointer
here, but you've never used it
anywhre in the code? What is it for?

> +       void __iomem            *cra_base;
> +       int                     irq;
> +       u8                      root_bus_nr;
> +       struct irq_domain               *irq_domain;
> +       struct resource         bus_range;
> +       struct list_head                resources;
> +};
> +

<snip>

> +
> +static int tlp_cfg_dword_read(struct altera_pcie *pcie, u8 bus, u32 devfn,
> +                             int where, u32 *value)
> +{
> +       int ret;
> +       u32 headers[TLP_HDR_SIZE];
> +
> +       if (bus == pcie->root_bus_nr)
> +               headers[0] = TLP_CFG_DW0(TLP_FMTTYPE_CFGRD0);
> +       else
> +               headers[0] = TLP_CFG_DW0(TLP_FMTTYPE_CFGRD1);
> +
> +       headers[1] = TLP_CFG_DW1(TLP_REQ_ID(pcie->root_bus_nr, devfn),
> +                                       TLP_READ_TAG);
> +       headers[2] = TLP_CFG_DW2(bus, devfn, where);
> +
> +       tlp_write_packet(pcie, headers, 0);
> +
> +       ret = tlp_read_packet(pcie, value);
> +       if (ret)
> +               *value = ~0UL;  /* return 0xFFFFFFFF if error */
> +
> +       return ret;
> +}
> +
> +static int tlp_cfg_dword_write(struct altera_pcie *pcie, u8 bus, u32 devfn,
> +                              int where, u32 value)
> +{
> +       u32 headers[TLP_HDR_SIZE];
> +
> +       if (bus == pcie->root_bus_nr)
> +               headers[0] = TLP_CFG_DW0(TLP_FMTTYPE_CFGWR0);
> +       else
> +               headers[0] = TLP_CFG_DW0(TLP_FMTTYPE_CFGWR1);
> +
> +       headers[1] = TLP_CFG_DW1(TLP_REQ_ID(pcie->root_bus_nr, devfn),
> +                                       TLP_WRITE_TAG);
> +       headers[2] = TLP_CFG_DW2(bus, devfn, where);
> +
> +       tlp_write_packet(pcie, headers, value);
> +
> +       tlp_read_packet(pcie, NULL);

You need to check for the error here.

> +
> +       /* Keep an eye out for changes to the root bus number */
> +       if ((bus == pcie->root_bus_nr) && (where == PCI_PRIMARY_BUS))
> +               pcie->root_bus_nr = (u8)(value);
> +
> +       return PCIBIOS_SUCCESSFUL;
> +}
> +

<snip>

> +
> +static int altera_pcie_parse_dt(struct altera_pcie *pcie)
> +{
> +       struct resource *cra;
> +       struct platform_device *pdev = pcie->pdev;
> +
> +       cra = platform_get_resource_byname(pdev, IORESOURCE_MEM, "Cra");
> +       if (!cra) {
> +               cra = platform_get_resource_byname(pdev, IORESOURCE_MEM, "cra");
> +               if (!cra) {
> +                       dev_err(&pdev->dev,
> +                               "no cra memory resource defined\n");
> +                       return -ENODEV;
> +               }
> +       }
> +

What about "Txs"?

Dinh


From heiko at sntech.de  Tue Aug 18 12:17:06 2015
From: heiko at sntech.de (Heiko Stuebner)
Date: Tue, 18 Aug 2015 21:17:06 +0200
Subject: [PATCH 2/2] ARM: dts: rockchip: correct regulator PM properties
In-Reply-To: <1439923455-109818-2-git-send-email-briannorris@chromium.org>
References: <1439923455-109818-1-git-send-email-briannorris@chromium.org>
 <1439923455-109818-2-git-send-email-briannorris@chromium.org>
Message-ID: <51457775.D3ds00ymOJ@phil>

Hi Brian,


thanks for catching these oversights, but see below

Am Dienstag, 18. August 2015, 11:44:15 schrieb Brian Norris:
> This DTS file was submitted with non-upstream bindings. I happened
> across this while reviewing the jaq DTS.
> 
> Signed-off-by: Brian Norris <briannorris at chromium.org>
> Cc: Alexandru M Stan <amstan at chromium.org>
> Cc: Douglas Anderson <dianders at chromium.org>
> ---
> Tested on jaq, not minnie
> 
>  arch/arm/boot/dts/rk3288-veyron-minnie.dts | 8 ++++++--
>  1 file changed, 6 insertions(+), 2 deletions(-)
> 
> diff --git a/arch/arm/boot/dts/rk3288-veyron-minnie.dts
> b/arch/arm/boot/dts/rk3288-veyron-minnie.dts index
> 0e30bd6bf92b..6f619c154dc6 100644
> --- a/arch/arm/boot/dts/rk3288-veyron-minnie.dts
> +++ b/arch/arm/boot/dts/rk3288-veyron-minnie.dts
> @@ -128,12 +128,16 @@
>  			regulator-min-microvolt = <3300000>;
>  			regulator-max-microvolt = <3300000>;
>  			regulator-name = "vcc33_touch";
> -			regulator-suspend-mem-disabled;
> +			regulator-state-mem {
> +				regulator-on-in-suspend;
> +			};
>  		};
> 
>  		vcc5v_touch: SWITCH_REG2 {
>  			regulator-name = "vcc5v_touch";
> -			regulator-suspend-mem-disabled;
> +			regulator-state-mem {
> +				regulator-on-in-suspend;
> +			};

wouldn't regulator-suspend-mem-disabled translate to regulator-off-in-suspend?
At least looks like it according to https://lkml.org/lkml/2013/7/25/592


Heiko

>  		};
>  	};
>  };



From heiko at sntech.de  Tue Aug 18 12:19:05 2015
From: heiko at sntech.de (Heiko Stuebner)
Date: Tue, 18 Aug 2015 21:19:05 +0200
Subject: [PATCH 1/2] ARM: dts: rockchip: add veyron-jaq board
In-Reply-To: <1439923455-109818-1-git-send-email-briannorris@chromium.org>
References: <1439923455-109818-1-git-send-email-briannorris@chromium.org>
Message-ID: <9567797.5pIFQ6WEoM@phil>

Hi Brian,


Am Dienstag, 18. August 2015, 11:44:14 schrieb Brian Norris:
> a.k.a. Haier Chromebook 11
> 
> Signed-off-by: Brian Norris <briannorris at chromium.org>
> Cc: Alexandru M Stan <amstan at chromium.org>
> Cc: Douglas Anderson <dianders at chromium.org>
> ---
>  arch/arm/boot/dts/Makefile              |   1 +
>  arch/arm/boot/dts/rk3288-veyron-jaq.dts | 176
> ++++++++++++++++++++++++++++++++ 2 files changed, 177 insertions(+)
>  create mode 100644 arch/arm/boot/dts/rk3288-veyron-jaq.dts

missing binding documentation in 
Documentation/devicetree/bindings/arm/rockchip.txt (needs new entry above 
Jerry)

> 
> diff --git a/arch/arm/boot/dts/Makefile b/arch/arm/boot/dts/Makefile
> index 7805a6541a38..7a2c3c88ce9e 100644
> --- a/arch/arm/boot/dts/Makefile
> +++ b/arch/arm/boot/dts/Makefile
> @@ -493,6 +493,7 @@ dtb-$(CONFIG_ARCH_ROCKCHIP) += \
>  	rk3288-veyron-jerry.dtb \
>  	rk3288-veyron-minnie.dtb \
>  	rk3288-veyron-pinky.dtb \
> +	rk3288-veyron-jaq.dtb \
>  	rk3288-veyron-speedy.dtb

please sort alphabetically (in this case somewhere above jerry)


>  dtb-$(CONFIG_ARCH_S3C24XX) += \
>  	s3c2416-smdk2416.dtb
> diff --git a/arch/arm/boot/dts/rk3288-veyron-jaq.dts
> b/arch/arm/boot/dts/rk3288-veyron-jaq.dts new file mode 100644
> index 000000000000..ea6130156216
> --- /dev/null
> +++ b/arch/arm/boot/dts/rk3288-veyron-jaq.dts
> @@ -0,0 +1,176 @@
> +/*
> + * Google Veyron Jaq Rev 1+ board device tree source
> + *
> + * Copyright 2015 Google, Inc
> + *
> + * This file is dual-licensed: you can use it either under the terms
> + * of the GPL or the X11 license, at your option. Note that this dual
> + * licensing only applies to this file, and not this project as a
> + * whole.
> + *
> + *  a) This file is free software; you can redistribute it and/or
> + *     modify it under the terms of the GNU General Public License as
> + *     published by the Free Software Foundation; either version 2 of the
> + *     License, or (at your option) any later version.
> + *
> + *     This file is distributed in the hope that it will be useful,
> + *     but WITHOUT ANY WARRANTY; without even the implied warranty of
> + *     MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
> + *     GNU General Public License for more details.
> + *
> + *  Or, alternatively,
> + *
> + *  b) Permission is hereby granted, free of charge, to any person
> + *     obtaining a copy of this software and associated documentation
> + *     files (the "Software"), to deal in the Software without
> + *     restriction, including without limitation the rights to use,
> + *     copy, modify, merge, publish, distribute, sublicense, and/or
> + *     sell copies of the Software, and to permit persons to whom the
> + *     Software is furnished to do so, subject to the following
> + *     conditions:
> + *
> + *     The above copyright notice and this permission notice shall be
> + *     included in all copies or substantial portions of the Software.
> + *
> + *     THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
> + *     EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES
> + *     OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
> + *     NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT
> + *     HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY,
> + *     WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
> + *     FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR
> + *     OTHER DEALINGS IN THE SOFTWARE.
> + */
> +
> +/dts-v1/;
> +
> +#include "rk3288-veyron-chromebook.dtsi"
> +#include "cros-ec-sbs.dtsi"
> +
> +/ {
> +	model = "Google Jaq";
> +	compatible = "google,veyron-jaq-rev5", "google,veyron-jaq-rev4",
> +		     "google,veyron-jaq-rev3", "google,veyron-jaq-rev2",
> +		     "google,veyron-jaq-rev1", "google,veyron-jaq",
> +		     "google,veyron", "rockchip,rk3288";
> +
> +	panel_regulator: panel-regulator {
> +		compatible = "regulator-fixed";
> +		enable-active-high;
> +		gpio = <&gpio7 14 GPIO_ACTIVE_HIGH>;
> +		pinctrl-names = "default";
> +		pinctrl-0 = <&lcd_enable_h>;
> +		regulator-name = "panel_regulator";
> +		vin-supply = <&vcc33_sys>;
> +	};
> +
> +	vcc18_lcd: vcc18-lcd {
> +		compatible = "regulator-fixed";
> +		enable-active-high;
> +		gpio = <&gpio2 13 GPIO_ACTIVE_HIGH>;
> +		pinctrl-names = "default";
> +		pinctrl-0 = <&avdd_1v8_disp_en>;
> +		regulator-name = "vcc18_lcd";
> +		regulator-always-on;
> +		regulator-boot-on;
> +		vin-supply = <&vcc18_wl>;
> +	};
> +
> +	backlight_regulator: backlight-regulator {
> +		compatible = "regulator-fixed";
> +		enable-active-high;
> +		gpio = <&gpio2 12 GPIO_ACTIVE_HIGH>;
> +		pinctrl-names = "default";
> +		pinctrl-0 = <&bl_pwr_en>;
> +		regulator-name = "backlight_regulator";
> +		vin-supply = <&vcc33_sys>;
> +		startup-delay-us = <15000>;
> +	};

again, please alphabetically (backlight, panel, vcc*)


> +};
> +
> +&rk808 {
> +	pinctrl-names = "default";
> +	pinctrl-0 = <&pmic_int_l &dvs_1 &dvs_2>;
> +	dvs-gpios = <&gpio7 12 GPIO_ACTIVE_HIGH>,
> +		    <&gpio7 15 GPIO_ACTIVE_HIGH>;
> +
> +	regulators {
> +		mic_vcc: LDO_REG2 {
> +			regulator-name = "mic_vcc";
> +			regulator-always-on;
> +			regulator-boot-on;
> +			regulator-min-microvolt = <1800000>;
> +			regulator-max-microvolt = <1800000>;
> +			regulator-state-mem {
> +				regulator-on-in-suspend;
> +			};
> +		};
> +	};
> +};
> +
> +&sdmmc {
> +	disable-wp;
> +	pinctrl-names = "default";
> +	pinctrl-0 = <&sdmmc_clk &sdmmc_cmd &sdmmc_cd_disabled &sdmmc_cd_gpio
> +			&sdmmc_bus4>;
> +};
> +
> +&vcc_5v {
> +	enable-active-high;
> +	gpio = <&gpio7 21 GPIO_ACTIVE_HIGH>;
> +	pinctrl-names = "default";
> +	pinctrl-0 = <&drv_5v>;
> +};
> +
> +&vcc50_hdmi {
> +	enable-active-high;
> +	gpio = <&gpio5 19 GPIO_ACTIVE_HIGH>;
> +	pinctrl-names = "default";
> +	pinctrl-0 = <&vcc50_hdmi_en>;
> +};
> +
> +&pinctrl {
> +	backlight {
> +		bl_pwr_en: bl_pwr_en {
> +			rockchip,pins = <2 12 RK_FUNC_GPIO &pcfg_pull_none>;
> +		};
> +	};
> +
> +	buck-5v {
> +		drv_5v: drv-5v {
> +			rockchip,pins = <7 21 RK_FUNC_GPIO &pcfg_pull_none>;
> +		};
> +	};
> +
> +	edp {
> +		edp_hpd: edp_hpd {
> +			rockchip,pins = <7 11 RK_FUNC_2 &pcfg_pull_down>;
> +		};
> +	};
> +
> +	hdmi {
> +		vcc50_hdmi_en: vcc50-hdmi-en {
> +			rockchip,pins = <5 19 RK_FUNC_GPIO &pcfg_pull_none>;
> +		};
> +	};
> +
> +	lcd {
> +		lcd_enable_h: lcd-en {
> +			rockchip,pins = <7 14 RK_FUNC_GPIO &pcfg_pull_none>;
> +		};
> +
> +		avdd_1v8_disp_en: avdd-1v8-disp-en {
> +			rockchip,pins = <2 13 RK_FUNC_GPIO &pcfg_pull_none>;
> +		};
> +	};
> +
> +	pmic {
> +		dvs_1: dvs-1 {
> +			rockchip,pins = <7 12 RK_FUNC_GPIO &pcfg_pull_down>;
> +		};
> +
> +		dvs_2: dvs-2 {
> +			rockchip,pins = <7 15 RK_FUNC_GPIO &pcfg_pull_down>;
> +		};
> +	};
> +};

pinctrl can stay at the bottom. It may actually improve readability, if not 
cluttering up the smaller other nodes above.


Thanks
Heiko


From dinh.linux at gmail.com  Tue Aug 18 12:22:11 2015
From: dinh.linux at gmail.com (Dinh Nguyen)
Date: Tue, 18 Aug 2015 14:22:11 -0500
Subject: [PATCH v4 4/5] Documentation: dt-bindings: pci: altera pcie
 device tree binding
In-Reply-To: <1439802579-22651-5-git-send-email-lftan@altera.com>
References: <1439802579-22651-1-git-send-email-lftan@altera.com>
 <1439802579-22651-5-git-send-email-lftan@altera.com>
Message-ID: <CADhT+wdwYQWq=yiw1R9YEXX=WTDtoj-5=6EysX=aHUjdSvU89w@mail.gmail.com>

On Mon, Aug 17, 2015 at 4:09 AM, Ley Foon Tan <lftan at altera.com> wrote:
> This patch adds the bindings for Altera PCIe host controller driver and
> Altera PCIe MSI driver.
>
> Signed-off-by: Ley Foon Tan <lftan at altera.com>
> ---
>  .../devicetree/bindings/pci/altera-pcie-msi.txt    | 27 ++++++++++++
>  .../devicetree/bindings/pci/altera-pcie.txt        | 49 ++++++++++++++++++++++
>  2 files changed, 76 insertions(+)
>  create mode 100644 Documentation/devicetree/bindings/pci/altera-pcie-msi.txt
>  create mode 100644 Documentation/devicetree/bindings/pci/altera-pcie.txt
>
> diff --git a/Documentation/devicetree/bindings/pci/altera-pcie-msi.txt b/Documentation/devicetree/bindings/pci/altera-pcie-msi.txt
> new file mode 100644
> index 0000000..7f330c9
> --- /dev/null
> +++ b/Documentation/devicetree/bindings/pci/altera-pcie-msi.txt
> @@ -0,0 +1,27 @@
> +* Altera PCIe MSI controller
> +
> +Required properties:
> +- compatible:  should contain "altr,msi-1.0"
> +- reg:         specifies the physical base address of the controller and
> +               the length of the memory mapped region.
> +- reg-names:   Must include the following entries:
> +               "csr": CSR registers
> +               "vector_slave": vectors region

Can you be a little bit more specific here? What is a vectors region?
Also, I'm not 100% sure, but I think "vector-slave" should be used.

> +-interrupts:   specifies the interrupt source of the parent interrupt
> +               controller. The format of the interrupt specifier depends on the
> +               parent interrupt controller.

Need to document "interrupt-parent" .

> +- num-vectors: Number of vectors, range 1 to 32.
> +- msi-controller:      indicates that this is MSI controller node
> +
> +
> +Example
> +msi0: msi at 0xFF200000 {
> +       compatible = "altr,msi-1.0";
> +       reg = <0xFF200000 0x00000010
> +               0xFF200010 0x00000080>;
> +       reg-names = "csr", "vector_slave";
> +       interrupt-parent = <&hps_0_arm_gic_0>;
> +       interrupts = <0 42 4>;
> +       msi-controller = <1>;
> +       num-vectors = <32>;
> +};
> diff --git a/Documentation/devicetree/bindings/pci/altera-pcie.txt b/Documentation/devicetree/bindings/pci/altera-pcie.txt
> new file mode 100644
> index 0000000..73a8dc0
> --- /dev/null
> +++ b/Documentation/devicetree/bindings/pci/altera-pcie.txt
> @@ -0,0 +1,49 @@
> +* Altera PCIe controller
> +
> +Required properties:
> +- compatible : should contain "altr,pcie-root-port-1.0"
> +- reg:         A list of physical base address and length for TXS and CRA.
> +- reg-names:   Must include the following entries:
> +               "Txs" or "txs": TXS region

What is a TXS region?

> +               "Cra" or "cra": Control register access region
> +-interrupts:   specifies the interrupt source of the parent interrupt controller.
> +               The format of the interrupt specifier depends on the parent interrupt
> +               controller.
> +- device_type: must be "pci"
> +- #address-cells:      set to <3>
> +- #size-cells: set to <2>
> +- #interrupt-cells:    set to <1>
> +- ranges:              Describes the translation of addresses for root ports and standard
> +               PCI regions.
> +- interrupt-map-mask and interrupt-map: standard PCI properties
> +       to define the mapping of the PCIe interface to interrupt
> +       numbers.

"interrupt-parent" ?

Dinh


From jeffv at google.com  Tue Aug 18 12:29:37 2015
From: jeffv at google.com (Jeff Vander Stoep)
Date: Tue, 18 Aug 2015 12:29:37 -0700
Subject: [PATCH] arm64 Kconfig: Move LIST_POISON to a safe value
Message-ID: <1439926177-13839-1-git-send-email-jeffv@google.com>

Move the poison pointer offset to 0xdead000000000000, a
recognized value that is not mappable by user-space exploits.

Signed-off-by: Jeff Vander Stoep <jeffv at google.com>
---
 arch/arm64/Kconfig | 5 +++++
 1 file changed, 5 insertions(+)

diff --git a/arch/arm64/Kconfig b/arch/arm64/Kconfig
index 9532f8d..c003911 100644
--- a/arch/arm64/Kconfig
+++ b/arch/arm64/Kconfig
@@ -91,6 +91,11 @@ config NO_IOPORT_MAP
 config STACKTRACE_SUPPORT
 	def_bool y
 
+config ILLEGAL_POINTER_VALUE
+	hex
+	default 0xdead000000000000
+
+
 config LOCKDEP_SUPPORT
 	def_bool y
 
-- 
2.5.0.rc2.392.g76e840b



From jeffv at google.com  Tue Aug 18 12:50:10 2015
From: jeffv at google.com (Jeff Vander Stoep)
Date: Tue, 18 Aug 2015 12:50:10 -0700
Subject: [PATCH v2] arm64 Kconfig: Move LIST_POISON to a safe value
Message-ID: <1439927410-15522-1-git-send-email-jeffv@google.com>

Move the poison pointer offset to 0xdead000000000000, a
recognized value that is not mappable by user-space exploits.

Signed-off-by: Thierry Strudel <tstrudel at google.com>
Signed-off-by: Jeff Vander Stoep <jeffv at google.com>
---
v2 removes an extra newline.

 arch/arm64/Kconfig | 4 ++++
 1 file changed, 4 insertions(+)

diff --git a/arch/arm64/Kconfig b/arch/arm64/Kconfig
index 318175f..8f1789c 100644
--- a/arch/arm64/Kconfig
+++ b/arch/arm64/Kconfig
@@ -104,6 +104,10 @@ config NO_IOPORT_MAP
 config STACKTRACE_SUPPORT
 	def_bool y
 
+config ILLEGAL_POINTER_VALUE
+	hex
+	default 0xdead000000000000
+
 config LOCKDEP_SUPPORT
 	def_bool y
 
-- 
2.5.0.276.gf5e568e



From petr.cvek at tul.cz  Tue Aug 18 13:02:40 2015
From: petr.cvek at tul.cz (Petr Cvek)
Date: Tue, 18 Aug 2015 22:02:40 +0200
Subject: [PATCH v2 01/21] ARM: pxa: magician: Fix Kconfig for magician to
 always include htc-egpio
In-Reply-To: <87zj1o8n3w.fsf@belgarion.home>
References: <cover.1439843482.git.petr.cvek@tul.cz> <55D25880.3030507@tul.cz>
 <87zj1o8n3w.fsf@belgarion.home>
Message-ID: <55D38F60.7010405@tul.cz>

Dne 18.8.2015 v 20:31 Robert Jarzmik napsal(a):
> Petr Cvek <petr.cvek at tul.cz> writes:
> 
>> The htc-egpio driver should be always included in the kernel as it
>> controls MMC/charging/IrDA power, which is the only way to get
>> an useful rootfs.
>>
>> Signed-off-by: Petr Cvek <petr.cvek at tul.cz>
> It's already defined in magician_defconfig, why enforce it in Kconfig ?

Good remark, I did not use defconfig at all (as I had to fix from zero configuration + I did not know if defconfig works and will be supported in the future).

I will check if magician_defconfig needs to be updated (probably for leds).

> 
> And if it's enforced and I want to build a kernel for magician without
> MMC/charging/IrDA, why should I be forced to build in HTC_EGPIO ?
> 
> Or said differently, does a kernel without HTC_EGPIO is proven to fail 100%
> without this option ?

Kernel will probably run OK, but the phone will be unusable (for any practical purposes). The EGPIO chip (CPLD) will stay in the state programmed from the previous environment (bootloader or WinCE/Mobile) and drivers fail to init because of the missing EGPIO (and if they init, they will be without any idea about state of the peripherals (no charger detection/charging current stuck on the previous settings, no LCD backlight control, no IrDA, no rootfs, no GSM, no sound, no LEDs).

Different PCB revisions probably use EGPIO pin for LCD power (and at least on my phone, LCD power must have very specific order).

For future (when ROM XIP will work) I would like to be able boot kernel from flash, which itself uses EGPIO for Vpp control (another initial EGPIO configuration). Last possible boot is from JTAG and there will be no previous EGPIO initialization.

Petr


From mchehab at osg.samsung.com  Tue Aug 18 13:04:21 2015
From: mchehab at osg.samsung.com (Mauro Carvalho Chehab)
Date: Tue, 18 Aug 2015 17:04:21 -0300
Subject: [PATCH RFC v5 8/8] [media] media: rename the function that create pad
 links
In-Reply-To: <cover.1439927113.git.mchehab@osg.samsung.com>
References: <cover.1439927113.git.mchehab@osg.samsung.com>
Message-ID: <4b0c0aa7604f5202401997f946297c0b35c1b692.1439927113.git.mchehab@osg.samsung.com>

Now that a link can be either between two different graph
objects, we'll need to add more functions to create links.
So, rename the existing one that create links only between
two pads as media_create_pad_link().

No functional changes.

This patch was created via this shell script:
	for i in $(find drivers/media -name '*.[ch]' -type f) $(find drivers/staging/media -name '*.[ch]' -type f) $(find include/ -name '*.h' -type f) ; do sed s,media_entity_create_link,media_create_pad_link,g <$i >a && mv a $i; done

Signed-off-by: Mauro Carvalho Chehab <mchehab at osg.samsung.com>

diff --git a/Documentation/media-framework.txt b/Documentation/media-framework.txt
index 6903b2503577..b424de6c3bb3 100644
--- a/Documentation/media-framework.txt
+++ b/Documentation/media-framework.txt
@@ -199,7 +199,7 @@ pre-allocated and grows dynamically as needed.
 
 Drivers create links by calling
 
-	media_entity_create_link(struct media_entity *source, u16 source_pad,
+	media_create_pad_link(struct media_entity *source, u16 source_pad,
 				 struct media_entity *sink,   u16 sink_pad,
 				 u32 flags);
 
diff --git a/drivers/media/dvb-core/dvbdev.c b/drivers/media/dvb-core/dvbdev.c
index 2fdcbb5f000a..65f59f2124b4 100644
--- a/drivers/media/dvb-core/dvbdev.c
+++ b/drivers/media/dvb-core/dvbdev.c
@@ -412,16 +412,16 @@ void dvb_create_media_graph(struct dvb_adapter *adap)
 	}
 
 	if (tuner && fe)
-		media_entity_create_link(tuner, 0, fe, 0, 0);
+		media_create_pad_link(tuner, 0, fe, 0, 0);
 
 	if (fe && demux)
-		media_entity_create_link(fe, 1, demux, 0, MEDIA_LNK_FL_ENABLED);
+		media_create_pad_link(fe, 1, demux, 0, MEDIA_LNK_FL_ENABLED);
 
 	if (demux && dvr)
-		media_entity_create_link(demux, 1, dvr, 0, MEDIA_LNK_FL_ENABLED);
+		media_create_pad_link(demux, 1, dvr, 0, MEDIA_LNK_FL_ENABLED);
 
 	if (demux && ca)
-		media_entity_create_link(demux, 1, ca, 0, MEDIA_LNK_FL_ENABLED);
+		media_create_pad_link(demux, 1, ca, 0, MEDIA_LNK_FL_ENABLED);
 }
 EXPORT_SYMBOL_GPL(dvb_create_media_graph);
 #endif
diff --git a/drivers/media/i2c/s5c73m3/s5c73m3-core.c b/drivers/media/i2c/s5c73m3/s5c73m3-core.c
index 6d167428727d..c81bfbfea32f 100644
--- a/drivers/media/i2c/s5c73m3/s5c73m3-core.c
+++ b/drivers/media/i2c/s5c73m3/s5c73m3-core.c
@@ -1482,11 +1482,11 @@ static int s5c73m3_oif_registered(struct v4l2_subdev *sd)
 		return ret;
 	}
 
-	ret = media_entity_create_link(&state->sensor_sd.entity,
+	ret = media_create_pad_link(&state->sensor_sd.entity,
 			S5C73M3_ISP_PAD, &state->oif_sd.entity, OIF_ISP_PAD,
 			MEDIA_LNK_FL_IMMUTABLE | MEDIA_LNK_FL_ENABLED);
 
-	ret = media_entity_create_link(&state->sensor_sd.entity,
+	ret = media_create_pad_link(&state->sensor_sd.entity,
 			S5C73M3_JPEG_PAD, &state->oif_sd.entity, OIF_JPEG_PAD,
 			MEDIA_LNK_FL_IMMUTABLE | MEDIA_LNK_FL_ENABLED);
 
diff --git a/drivers/media/i2c/s5k5baf.c b/drivers/media/i2c/s5k5baf.c
index 30a9ca62e034..d3bff30bcb6f 100644
--- a/drivers/media/i2c/s5k5baf.c
+++ b/drivers/media/i2c/s5k5baf.c
@@ -1756,7 +1756,7 @@ static int s5k5baf_registered(struct v4l2_subdev *sd)
 		v4l2_err(sd, "failed to register subdev %s\n",
 			 state->cis_sd.name);
 	else
-		ret = media_entity_create_link(&state->cis_sd.entity, PAD_CIS,
+		ret = media_create_pad_link(&state->cis_sd.entity, PAD_CIS,
 					       &state->sd.entity, PAD_CIS,
 					       MEDIA_LNK_FL_IMMUTABLE |
 					       MEDIA_LNK_FL_ENABLED);
diff --git a/drivers/media/i2c/smiapp/smiapp-core.c b/drivers/media/i2c/smiapp/smiapp-core.c
index 308613ea0aed..5aa49eb393a9 100644
--- a/drivers/media/i2c/smiapp/smiapp-core.c
+++ b/drivers/media/i2c/smiapp/smiapp-core.c
@@ -2495,7 +2495,7 @@ static int smiapp_register_subdevs(struct smiapp_sensor *sensor)
 			return rval;
 		}
 
-		rval = media_entity_create_link(&this->sd.entity,
+		rval = media_create_pad_link(&this->sd.entity,
 						this->source_pad,
 						&last->sd.entity,
 						last->sink_pad,
@@ -2503,7 +2503,7 @@ static int smiapp_register_subdevs(struct smiapp_sensor *sensor)
 						MEDIA_LNK_FL_IMMUTABLE);
 		if (rval) {
 			dev_err(&client->dev,
-				"media_entity_create_link failed\n");
+				"media_create_pad_link failed\n");
 			return rval;
 		}
 
diff --git a/drivers/media/media-entity.c b/drivers/media/media-entity.c
index 9e5ebc83ff76..b9304a634490 100644
--- a/drivers/media/media-entity.c
+++ b/drivers/media/media-entity.c
@@ -540,7 +540,7 @@ static struct media_link *media_entity_add_link(struct media_entity *entity)
 }
 
 int
-media_entity_create_link(struct media_entity *source, u16 source_pad,
+media_create_pad_link(struct media_entity *source, u16 source_pad,
 			 struct media_entity *sink, u16 sink_pad, u32 flags)
 {
 	struct media_link *link;
@@ -582,7 +582,7 @@ media_entity_create_link(struct media_entity *source, u16 source_pad,
 
 	return 0;
 }
-EXPORT_SYMBOL_GPL(media_entity_create_link);
+EXPORT_SYMBOL_GPL(media_create_pad_link);
 
 void __media_entity_remove_links(struct media_entity *entity)
 {
diff --git a/drivers/media/platform/exynos4-is/media-dev.c b/drivers/media/platform/exynos4-is/media-dev.c
index 4f5586a4cbff..3ba76940eef5 100644
--- a/drivers/media/platform/exynos4-is/media-dev.c
+++ b/drivers/media/platform/exynos4-is/media-dev.c
@@ -729,7 +729,7 @@ static int __fimc_md_create_fimc_sink_links(struct fimc_md *fmd,
 		flags = ((1 << i) & link_mask) ? MEDIA_LNK_FL_ENABLED : 0;
 
 		sink = &fmd->fimc[i]->vid_cap.subdev.entity;
-		ret = media_entity_create_link(source, pad, sink,
+		ret = media_create_pad_link(source, pad, sink,
 					      FIMC_SD_PAD_SINK_CAM, flags);
 		if (ret)
 			return ret;
@@ -749,7 +749,7 @@ static int __fimc_md_create_fimc_sink_links(struct fimc_md *fmd,
 			continue;
 
 		sink = &fmd->fimc_lite[i]->subdev.entity;
-		ret = media_entity_create_link(source, pad, sink,
+		ret = media_create_pad_link(source, pad, sink,
 					       FLITE_SD_PAD_SINK, 0);
 		if (ret)
 			return ret;
@@ -781,13 +781,13 @@ static int __fimc_md_create_flite_source_links(struct fimc_md *fmd)
 		source = &fimc->subdev.entity;
 		sink = &fimc->ve.vdev.entity;
 		/* FIMC-LITE's subdev and video node */
-		ret = media_entity_create_link(source, FLITE_SD_PAD_SOURCE_DMA,
+		ret = media_create_pad_link(source, FLITE_SD_PAD_SOURCE_DMA,
 					       sink, 0, 0);
 		if (ret)
 			break;
 		/* Link from FIMC-LITE to IS-ISP subdev */
 		sink = &fmd->fimc_is->isp.subdev.entity;
-		ret = media_entity_create_link(source, FLITE_SD_PAD_SOURCE_ISP,
+		ret = media_create_pad_link(source, FLITE_SD_PAD_SOURCE_ISP,
 					       sink, 0, 0);
 		if (ret)
 			break;
@@ -811,7 +811,7 @@ static int __fimc_md_create_fimc_is_links(struct fimc_md *fmd)
 
 		/* Link from FIMC-IS-ISP subdev to FIMC */
 		sink = &fmd->fimc[i]->vid_cap.subdev.entity;
-		ret = media_entity_create_link(source, FIMC_ISP_SD_PAD_SRC_FIFO,
+		ret = media_create_pad_link(source, FIMC_ISP_SD_PAD_SRC_FIFO,
 					       sink, FIMC_SD_PAD_SINK_FIFO, 0);
 		if (ret)
 			return ret;
@@ -824,7 +824,7 @@ static int __fimc_md_create_fimc_is_links(struct fimc_md *fmd)
 	if (sink->num_pads == 0)
 		return 0;
 
-	return media_entity_create_link(source, FIMC_ISP_SD_PAD_SRC_DMA,
+	return media_create_pad_link(source, FIMC_ISP_SD_PAD_SRC_DMA,
 					sink, 0, 0);
 }
 
@@ -873,7 +873,7 @@ static int fimc_md_create_links(struct fimc_md *fmd)
 				return -EINVAL;
 
 			pad = sensor->entity.num_pads - 1;
-			ret = media_entity_create_link(&sensor->entity, pad,
+			ret = media_create_pad_link(&sensor->entity, pad,
 					      &csis->entity, CSIS_PAD_SINK,
 					      MEDIA_LNK_FL_IMMUTABLE |
 					      MEDIA_LNK_FL_ENABLED);
@@ -927,7 +927,7 @@ static int fimc_md_create_links(struct fimc_md *fmd)
 		source = &fmd->fimc[i]->vid_cap.subdev.entity;
 		sink = &fmd->fimc[i]->vid_cap.ve.vdev.entity;
 
-		ret = media_entity_create_link(source, FIMC_SD_PAD_SOURCE,
+		ret = media_create_pad_link(source, FIMC_SD_PAD_SOURCE,
 					      sink, 0, flags);
 		if (ret)
 			break;
diff --git a/drivers/media/platform/omap3isp/isp.c b/drivers/media/platform/omap3isp/isp.c
index 56e683b19a73..d6b2922ed55c 100644
--- a/drivers/media/platform/omap3isp/isp.c
+++ b/drivers/media/platform/omap3isp/isp.c
@@ -1862,7 +1862,7 @@ static int isp_link_entity(
 		return -EINVAL;
 	}
 
-	return media_entity_create_link(entity, i, input, pad, flags);
+	return media_create_pad_link(entity, i, input, pad, flags);
 }
 
 static int isp_register_entities(struct isp_device *isp)
@@ -2001,51 +2001,51 @@ static int isp_initialize_modules(struct isp_device *isp)
 	}
 
 	/* Connect the submodules. */
-	ret = media_entity_create_link(
+	ret = media_create_pad_link(
 			&isp->isp_csi2a.subdev.entity, CSI2_PAD_SOURCE,
 			&isp->isp_ccdc.subdev.entity, CCDC_PAD_SINK, 0);
 	if (ret < 0)
 		goto error_link;
 
-	ret = media_entity_create_link(
+	ret = media_create_pad_link(
 			&isp->isp_ccp2.subdev.entity, CCP2_PAD_SOURCE,
 			&isp->isp_ccdc.subdev.entity, CCDC_PAD_SINK, 0);
 	if (ret < 0)
 		goto error_link;
 
-	ret = media_entity_create_link(
+	ret = media_create_pad_link(
 			&isp->isp_ccdc.subdev.entity, CCDC_PAD_SOURCE_VP,
 			&isp->isp_prev.subdev.entity, PREV_PAD_SINK, 0);
 	if (ret < 0)
 		goto error_link;
 
-	ret = media_entity_create_link(
+	ret = media_create_pad_link(
 			&isp->isp_ccdc.subdev.entity, CCDC_PAD_SOURCE_OF,
 			&isp->isp_res.subdev.entity, RESZ_PAD_SINK, 0);
 	if (ret < 0)
 		goto error_link;
 
-	ret = media_entity_create_link(
+	ret = media_create_pad_link(
 			&isp->isp_prev.subdev.entity, PREV_PAD_SOURCE,
 			&isp->isp_res.subdev.entity, RESZ_PAD_SINK, 0);
 	if (ret < 0)
 		goto error_link;
 
-	ret = media_entity_create_link(
+	ret = media_create_pad_link(
 			&isp->isp_ccdc.subdev.entity, CCDC_PAD_SOURCE_VP,
 			&isp->isp_aewb.subdev.entity, 0,
 			MEDIA_LNK_FL_ENABLED | MEDIA_LNK_FL_IMMUTABLE);
 	if (ret < 0)
 		goto error_link;
 
-	ret = media_entity_create_link(
+	ret = media_create_pad_link(
 			&isp->isp_ccdc.subdev.entity, CCDC_PAD_SOURCE_VP,
 			&isp->isp_af.subdev.entity, 0,
 			MEDIA_LNK_FL_ENABLED | MEDIA_LNK_FL_IMMUTABLE);
 	if (ret < 0)
 		goto error_link;
 
-	ret = media_entity_create_link(
+	ret = media_create_pad_link(
 			&isp->isp_ccdc.subdev.entity, CCDC_PAD_SOURCE_VP,
 			&isp->isp_hist.subdev.entity, 0,
 			MEDIA_LNK_FL_ENABLED | MEDIA_LNK_FL_IMMUTABLE);
diff --git a/drivers/media/platform/omap3isp/ispccdc.c b/drivers/media/platform/omap3isp/ispccdc.c
index 3b10304b580b..3fe425f254bb 100644
--- a/drivers/media/platform/omap3isp/ispccdc.c
+++ b/drivers/media/platform/omap3isp/ispccdc.c
@@ -2667,7 +2667,7 @@ static int ccdc_init_entities(struct isp_ccdc_device *ccdc)
 		goto error_video;
 
 	/* Connect the CCDC subdev to the video node. */
-	ret = media_entity_create_link(&ccdc->subdev.entity, CCDC_PAD_SOURCE_OF,
+	ret = media_create_pad_link(&ccdc->subdev.entity, CCDC_PAD_SOURCE_OF,
 			&ccdc->video_out.video.entity, 0, 0);
 	if (ret < 0)
 		goto error_link;
diff --git a/drivers/media/platform/omap3isp/ispccp2.c b/drivers/media/platform/omap3isp/ispccp2.c
index e1b5f5bea541..b215eb5049d6 100644
--- a/drivers/media/platform/omap3isp/ispccp2.c
+++ b/drivers/media/platform/omap3isp/ispccp2.c
@@ -1100,7 +1100,7 @@ static int ccp2_init_entities(struct isp_ccp2_device *ccp2)
 		goto error_video;
 
 	/* Connect the video node to the ccp2 subdev. */
-	ret = media_entity_create_link(&ccp2->video_in.video.entity, 0,
+	ret = media_create_pad_link(&ccp2->video_in.video.entity, 0,
 				       &ccp2->subdev.entity, CCP2_PAD_SINK, 0);
 	if (ret < 0)
 		goto error_link;
diff --git a/drivers/media/platform/omap3isp/ispcsi2.c b/drivers/media/platform/omap3isp/ispcsi2.c
index 6fff92f0813a..fcefc1e74881 100644
--- a/drivers/media/platform/omap3isp/ispcsi2.c
+++ b/drivers/media/platform/omap3isp/ispcsi2.c
@@ -1265,7 +1265,7 @@ static int csi2_init_entities(struct isp_csi2_device *csi2)
 		goto error_video;
 
 	/* Connect the CSI2 subdev to the video node. */
-	ret = media_entity_create_link(&csi2->subdev.entity, CSI2_PAD_SOURCE,
+	ret = media_create_pad_link(&csi2->subdev.entity, CSI2_PAD_SOURCE,
 				       &csi2->video_out.video.entity, 0, 0);
 	if (ret < 0)
 		goto error_link;
diff --git a/drivers/media/platform/omap3isp/isppreview.c b/drivers/media/platform/omap3isp/isppreview.c
index b440c6342ca4..ad38d20c7770 100644
--- a/drivers/media/platform/omap3isp/isppreview.c
+++ b/drivers/media/platform/omap3isp/isppreview.c
@@ -2312,12 +2312,12 @@ static int preview_init_entities(struct isp_prev_device *prev)
 		goto error_video_out;
 
 	/* Connect the video nodes to the previewer subdev. */
-	ret = media_entity_create_link(&prev->video_in.video.entity, 0,
+	ret = media_create_pad_link(&prev->video_in.video.entity, 0,
 			&prev->subdev.entity, PREV_PAD_SINK, 0);
 	if (ret < 0)
 		goto error_link;
 
-	ret = media_entity_create_link(&prev->subdev.entity, PREV_PAD_SOURCE,
+	ret = media_create_pad_link(&prev->subdev.entity, PREV_PAD_SOURCE,
 			&prev->video_out.video.entity, 0, 0);
 	if (ret < 0)
 		goto error_link;
diff --git a/drivers/media/platform/omap3isp/ispresizer.c b/drivers/media/platform/omap3isp/ispresizer.c
index 3deb1ec4a973..b48ad4d4b834 100644
--- a/drivers/media/platform/omap3isp/ispresizer.c
+++ b/drivers/media/platform/omap3isp/ispresizer.c
@@ -1756,12 +1756,12 @@ static int resizer_init_entities(struct isp_res_device *res)
 	res->video_out.video.entity.flags |= MEDIA_ENT_FL_DEFAULT;
 
 	/* Connect the video nodes to the resizer subdev. */
-	ret = media_entity_create_link(&res->video_in.video.entity, 0,
+	ret = media_create_pad_link(&res->video_in.video.entity, 0,
 			&res->subdev.entity, RESZ_PAD_SINK, 0);
 	if (ret < 0)
 		goto error_link;
 
-	ret = media_entity_create_link(&res->subdev.entity, RESZ_PAD_SOURCE,
+	ret = media_create_pad_link(&res->subdev.entity, RESZ_PAD_SOURCE,
 			&res->video_out.video.entity, 0, 0);
 	if (ret < 0)
 		goto error_link;
diff --git a/drivers/media/platform/s3c-camif/camif-core.c b/drivers/media/platform/s3c-camif/camif-core.c
index f47b332f0418..3e33c60be004 100644
--- a/drivers/media/platform/s3c-camif/camif-core.c
+++ b/drivers/media/platform/s3c-camif/camif-core.c
@@ -263,7 +263,7 @@ static int camif_create_media_links(struct camif_dev *camif)
 {
 	int i, ret;
 
-	ret = media_entity_create_link(&camif->sensor.sd->entity, 0,
+	ret = media_create_pad_link(&camif->sensor.sd->entity, 0,
 				&camif->subdev.entity, CAMIF_SD_PAD_SINK,
 				MEDIA_LNK_FL_IMMUTABLE |
 				MEDIA_LNK_FL_ENABLED);
@@ -271,7 +271,7 @@ static int camif_create_media_links(struct camif_dev *camif)
 		return ret;
 
 	for (i = 1; i < CAMIF_SD_PADS_NUM && !ret; i++) {
-		ret = media_entity_create_link(&camif->subdev.entity, i,
+		ret = media_create_pad_link(&camif->subdev.entity, i,
 				&camif->vp[i - 1].vdev.entity, 0,
 				MEDIA_LNK_FL_IMMUTABLE |
 				MEDIA_LNK_FL_ENABLED);
diff --git a/drivers/media/platform/vsp1/vsp1_drv.c b/drivers/media/platform/vsp1/vsp1_drv.c
index 4e61886384e3..9cd94a76a9ed 100644
--- a/drivers/media/platform/vsp1/vsp1_drv.c
+++ b/drivers/media/platform/vsp1/vsp1_drv.c
@@ -101,7 +101,7 @@ static int vsp1_create_links(struct vsp1_device *vsp1, struct vsp1_entity *sink)
 			if (!(entity->pads[pad].flags & MEDIA_PAD_FL_SINK))
 				continue;
 
-			ret = media_entity_create_link(&source->subdev.entity,
+			ret = media_create_pad_link(&source->subdev.entity,
 						       source->source_pad,
 						       entity, pad, flags);
 			if (ret < 0)
@@ -262,7 +262,7 @@ static int vsp1_create_entities(struct vsp1_device *vsp1)
 	}
 
 	if (vsp1->pdata.features & VSP1_HAS_LIF) {
-		ret = media_entity_create_link(
+		ret = media_create_pad_link(
 			&vsp1->wpf[0]->entity.subdev.entity, RWPF_PAD_SOURCE,
 			&vsp1->lif->entity.subdev.entity, LIF_PAD_SINK, 0);
 		if (ret < 0)
diff --git a/drivers/media/platform/vsp1/vsp1_rpf.c b/drivers/media/platform/vsp1/vsp1_rpf.c
index 3294529a3108..b60a528a8fe8 100644
--- a/drivers/media/platform/vsp1/vsp1_rpf.c
+++ b/drivers/media/platform/vsp1/vsp1_rpf.c
@@ -278,7 +278,7 @@ struct vsp1_rwpf *vsp1_rpf_create(struct vsp1_device *vsp1, unsigned int index)
 	rpf->entity.video = video;
 
 	/* Connect the video device to the RPF. */
-	ret = media_entity_create_link(&rpf->video.video.entity, 0,
+	ret = media_create_pad_link(&rpf->video.video.entity, 0,
 				       &rpf->entity.subdev.entity,
 				       RWPF_PAD_SINK,
 				       MEDIA_LNK_FL_ENABLED |
diff --git a/drivers/media/platform/vsp1/vsp1_wpf.c b/drivers/media/platform/vsp1/vsp1_wpf.c
index 1d2b3a2f1573..d39aa4b8aea1 100644
--- a/drivers/media/platform/vsp1/vsp1_wpf.c
+++ b/drivers/media/platform/vsp1/vsp1_wpf.c
@@ -284,7 +284,7 @@ struct vsp1_rwpf *vsp1_wpf_create(struct vsp1_device *vsp1, unsigned int index)
 	if (!(vsp1->pdata.features & VSP1_HAS_LIF) || index != 0)
 		flags |= MEDIA_LNK_FL_IMMUTABLE;
 
-	ret = media_entity_create_link(&wpf->entity.subdev.entity,
+	ret = media_create_pad_link(&wpf->entity.subdev.entity,
 				       RWPF_PAD_SOURCE,
 				       &wpf->video.video.entity, 0, flags);
 	if (ret < 0)
diff --git a/drivers/media/platform/xilinx/xilinx-vipp.c b/drivers/media/platform/xilinx/xilinx-vipp.c
index 7b7cb9c28d2c..79d4be7ce9a5 100644
--- a/drivers/media/platform/xilinx/xilinx-vipp.c
+++ b/drivers/media/platform/xilinx/xilinx-vipp.c
@@ -156,7 +156,7 @@ static int xvip_graph_build_one(struct xvip_composite_device *xdev,
 			local->name, local_pad->index,
 			remote->name, remote_pad->index);
 
-		ret = media_entity_create_link(local, local_pad->index,
+		ret = media_create_pad_link(local, local_pad->index,
 					       remote, remote_pad->index,
 					       link_flags);
 		if (ret < 0) {
@@ -270,7 +270,7 @@ static int xvip_graph_build_dma(struct xvip_composite_device *xdev)
 			source->name, source_pad->index,
 			sink->name, sink_pad->index);
 
-		ret = media_entity_create_link(source, source_pad->index,
+		ret = media_create_pad_link(source, source_pad->index,
 					       sink, sink_pad->index,
 					       link_flags);
 		if (ret < 0) {
diff --git a/drivers/media/usb/cx231xx/cx231xx-cards.c b/drivers/media/usb/cx231xx/cx231xx-cards.c
index 4a117a58c39a..3b5c9ae39ad3 100644
--- a/drivers/media/usb/cx231xx/cx231xx-cards.c
+++ b/drivers/media/usb/cx231xx/cx231xx-cards.c
@@ -1264,11 +1264,11 @@ static void cx231xx_create_media_graph(struct cx231xx *dev)
 		return;
 
 	if (tuner)
-		media_entity_create_link(tuner, 0, decoder, 0,
+		media_create_pad_link(tuner, 0, decoder, 0,
 					 MEDIA_LNK_FL_ENABLED);
-	media_entity_create_link(decoder, 1, &dev->vdev.entity, 0,
+	media_create_pad_link(decoder, 1, &dev->vdev.entity, 0,
 				 MEDIA_LNK_FL_ENABLED);
-	media_entity_create_link(decoder, 2, &dev->vbi_dev.entity, 0,
+	media_create_pad_link(decoder, 2, &dev->vbi_dev.entity, 0,
 				 MEDIA_LNK_FL_ENABLED);
 #endif
 }
diff --git a/drivers/media/usb/uvc/uvc_entity.c b/drivers/media/usb/uvc/uvc_entity.c
index 245445491516..429e428ccd93 100644
--- a/drivers/media/usb/uvc/uvc_entity.c
+++ b/drivers/media/usb/uvc/uvc_entity.c
@@ -56,7 +56,7 @@ static int uvc_mc_register_entity(struct uvc_video_chain *chain,
 			continue;
 
 		remote_pad = remote->num_pads - 1;
-		ret = media_entity_create_link(source, remote_pad,
+		ret = media_create_pad_link(source, remote_pad,
 					       sink, i, flags);
 		if (ret < 0)
 			return ret;
diff --git a/drivers/staging/media/davinci_vpfe/dm365_ipipeif.c b/drivers/staging/media/davinci_vpfe/dm365_ipipeif.c
index 8fb676186898..d96bdaaae50e 100644
--- a/drivers/staging/media/davinci_vpfe/dm365_ipipeif.c
+++ b/drivers/staging/media/davinci_vpfe/dm365_ipipeif.c
@@ -971,7 +971,7 @@ vpfe_ipipeif_register_entities(struct vpfe_ipipeif_device *ipipeif,
 	ipipeif->video_in.vpfe_dev = vpfe_dev;
 
 	flags = 0;
-	ret = media_entity_create_link(&ipipeif->video_in.video_dev.entity, 0,
+	ret = media_create_pad_link(&ipipeif->video_in.video_dev.entity, 0,
 					&ipipeif->subdev.entity, 0, flags);
 	if (ret < 0)
 		goto fail;
diff --git a/drivers/staging/media/davinci_vpfe/dm365_isif.c b/drivers/staging/media/davinci_vpfe/dm365_isif.c
index b1f01adfa7c8..df77288b0ec0 100644
--- a/drivers/staging/media/davinci_vpfe/dm365_isif.c
+++ b/drivers/staging/media/davinci_vpfe/dm365_isif.c
@@ -1817,7 +1817,7 @@ int vpfe_isif_register_entities(struct vpfe_isif_device *isif,
 	isif->video_out.vpfe_dev = vpfe_dev;
 	flags = 0;
 	/* connect isif to video node */
-	ret = media_entity_create_link(&isif->subdev.entity, 1,
+	ret = media_create_pad_link(&isif->subdev.entity, 1,
 				       &isif->video_out.video_dev.entity,
 				       0, flags);
 	if (ret < 0)
diff --git a/drivers/staging/media/davinci_vpfe/dm365_resizer.c b/drivers/staging/media/davinci_vpfe/dm365_resizer.c
index 692789aa22f4..ae942de3a23d 100644
--- a/drivers/staging/media/davinci_vpfe/dm365_resizer.c
+++ b/drivers/staging/media/davinci_vpfe/dm365_resizer.c
@@ -1831,27 +1831,27 @@ int vpfe_resizer_register_entities(struct vpfe_resizer_device *resizer,
 	resizer->resizer_b.video_out.vpfe_dev = vpfe_dev;
 
 	/* create link between Resizer Crop----> Resizer A*/
-	ret = media_entity_create_link(&resizer->crop_resizer.subdev.entity, 1,
+	ret = media_create_pad_link(&resizer->crop_resizer.subdev.entity, 1,
 				&resizer->resizer_a.subdev.entity,
 				0, flags);
 	if (ret < 0)
 		goto out_create_link;
 
 	/* create link between Resizer Crop----> Resizer B*/
-	ret = media_entity_create_link(&resizer->crop_resizer.subdev.entity, 2,
+	ret = media_create_pad_link(&resizer->crop_resizer.subdev.entity, 2,
 				&resizer->resizer_b.subdev.entity,
 				0, flags);
 	if (ret < 0)
 		goto out_create_link;
 
 	/* create link between Resizer A ----> video out */
-	ret = media_entity_create_link(&resizer->resizer_a.subdev.entity, 1,
+	ret = media_create_pad_link(&resizer->resizer_a.subdev.entity, 1,
 		&resizer->resizer_a.video_out.video_dev.entity, 0, flags);
 	if (ret < 0)
 		goto out_create_link;
 
 	/* create link between Resizer B ----> video out */
-	ret = media_entity_create_link(&resizer->resizer_b.subdev.entity, 1,
+	ret = media_create_pad_link(&resizer->resizer_b.subdev.entity, 1,
 		&resizer->resizer_b.video_out.video_dev.entity, 0, flags);
 	if (ret < 0)
 		goto out_create_link;
diff --git a/drivers/staging/media/davinci_vpfe/vpfe_mc_capture.c b/drivers/staging/media/davinci_vpfe/vpfe_mc_capture.c
index 57426199ad7a..08c8a5f967d3 100644
--- a/drivers/staging/media/davinci_vpfe/vpfe_mc_capture.c
+++ b/drivers/staging/media/davinci_vpfe/vpfe_mc_capture.c
@@ -445,32 +445,32 @@ static int vpfe_register_entities(struct vpfe_device *vpfe_dev)
 		/* if entity has no pads (ex: amplifier),
 		   cant establish link */
 		if (vpfe_dev->sd[i]->entity.num_pads) {
-			ret = media_entity_create_link(&vpfe_dev->sd[i]->entity,
+			ret = media_create_pad_link(&vpfe_dev->sd[i]->entity,
 				0, &vpfe_dev->vpfe_isif.subdev.entity,
 				0, flags);
 			if (ret < 0)
 				goto out_resizer_register;
 		}
 
-	ret = media_entity_create_link(&vpfe_dev->vpfe_isif.subdev.entity, 1,
+	ret = media_create_pad_link(&vpfe_dev->vpfe_isif.subdev.entity, 1,
 				       &vpfe_dev->vpfe_ipipeif.subdev.entity,
 				       0, flags);
 	if (ret < 0)
 		goto out_resizer_register;
 
-	ret = media_entity_create_link(&vpfe_dev->vpfe_ipipeif.subdev.entity, 1,
+	ret = media_create_pad_link(&vpfe_dev->vpfe_ipipeif.subdev.entity, 1,
 				       &vpfe_dev->vpfe_ipipe.subdev.entity,
 				       0, flags);
 	if (ret < 0)
 		goto out_resizer_register;
 
-	ret = media_entity_create_link(&vpfe_dev->vpfe_ipipe.subdev.entity,
+	ret = media_create_pad_link(&vpfe_dev->vpfe_ipipe.subdev.entity,
 			1, &vpfe_dev->vpfe_resizer.crop_resizer.subdev.entity,
 			0, flags);
 	if (ret < 0)
 		goto out_resizer_register;
 
-	ret = media_entity_create_link(&vpfe_dev->vpfe_ipipeif.subdev.entity, 1,
+	ret = media_create_pad_link(&vpfe_dev->vpfe_ipipeif.subdev.entity, 1,
 			&vpfe_dev->vpfe_resizer.crop_resizer.subdev.entity,
 			0, flags);
 	if (ret < 0)
diff --git a/drivers/staging/media/omap4iss/iss.c b/drivers/staging/media/omap4iss/iss.c
index 9bfb725b9986..f32ab7b98ae2 100644
--- a/drivers/staging/media/omap4iss/iss.c
+++ b/drivers/staging/media/omap4iss/iss.c
@@ -1259,7 +1259,7 @@ static int iss_register_entities(struct iss_device *iss)
 			goto done;
 		}
 
-		ret = media_entity_create_link(&sensor->entity, 0, input, pad,
+		ret = media_create_pad_link(&sensor->entity, 0, input, pad,
 					       flags);
 		if (ret < 0)
 			goto done;
@@ -1317,31 +1317,31 @@ static int iss_initialize_modules(struct iss_device *iss)
 	}
 
 	/* Connect the submodules. */
-	ret = media_entity_create_link(
+	ret = media_create_pad_link(
 			&iss->csi2a.subdev.entity, CSI2_PAD_SOURCE,
 			&iss->ipipeif.subdev.entity, IPIPEIF_PAD_SINK, 0);
 	if (ret < 0)
 		goto error_link;
 
-	ret = media_entity_create_link(
+	ret = media_create_pad_link(
 			&iss->csi2b.subdev.entity, CSI2_PAD_SOURCE,
 			&iss->ipipeif.subdev.entity, IPIPEIF_PAD_SINK, 0);
 	if (ret < 0)
 		goto error_link;
 
-	ret = media_entity_create_link(
+	ret = media_create_pad_link(
 			&iss->ipipeif.subdev.entity, IPIPEIF_PAD_SOURCE_VP,
 			&iss->resizer.subdev.entity, RESIZER_PAD_SINK, 0);
 	if (ret < 0)
 		goto error_link;
 
-	ret = media_entity_create_link(
+	ret = media_create_pad_link(
 			&iss->ipipeif.subdev.entity, IPIPEIF_PAD_SOURCE_VP,
 			&iss->ipipe.subdev.entity, IPIPE_PAD_SINK, 0);
 	if (ret < 0)
 		goto error_link;
 
-	ret = media_entity_create_link(
+	ret = media_create_pad_link(
 			&iss->ipipe.subdev.entity, IPIPE_PAD_SOURCE_VP,
 			&iss->resizer.subdev.entity, RESIZER_PAD_SINK, 0);
 	if (ret < 0)
diff --git a/drivers/staging/media/omap4iss/iss_csi2.c b/drivers/staging/media/omap4iss/iss_csi2.c
index e936cfc218cb..6b4dcbfa9425 100644
--- a/drivers/staging/media/omap4iss/iss_csi2.c
+++ b/drivers/staging/media/omap4iss/iss_csi2.c
@@ -1291,7 +1291,7 @@ static int csi2_init_entities(struct iss_csi2_device *csi2, const char *subname)
 		goto error_video;
 
 	/* Connect the CSI2 subdev to the video node. */
-	ret = media_entity_create_link(&csi2->subdev.entity, CSI2_PAD_SOURCE,
+	ret = media_create_pad_link(&csi2->subdev.entity, CSI2_PAD_SOURCE,
 				       &csi2->video_out.video.entity, 0, 0);
 	if (ret < 0)
 		goto error_link;
diff --git a/drivers/staging/media/omap4iss/iss_ipipeif.c b/drivers/staging/media/omap4iss/iss_ipipeif.c
index be5f80d7b5dc..44c432ef2ac5 100644
--- a/drivers/staging/media/omap4iss/iss_ipipeif.c
+++ b/drivers/staging/media/omap4iss/iss_ipipeif.c
@@ -762,7 +762,7 @@ static int ipipeif_init_entities(struct iss_ipipeif_device *ipipeif)
 		return ret;
 
 	/* Connect the IPIPEIF subdev to the video node. */
-	ret = media_entity_create_link(&ipipeif->subdev.entity,
+	ret = media_create_pad_link(&ipipeif->subdev.entity,
 				       IPIPEIF_PAD_SOURCE_ISIF_SF,
 				       &ipipeif->video_out.video.entity, 0, 0);
 	if (ret < 0)
diff --git a/drivers/staging/media/omap4iss/iss_resizer.c b/drivers/staging/media/omap4iss/iss_resizer.c
index 91e724085dba..b659e465cb56 100644
--- a/drivers/staging/media/omap4iss/iss_resizer.c
+++ b/drivers/staging/media/omap4iss/iss_resizer.c
@@ -806,7 +806,7 @@ static int resizer_init_entities(struct iss_resizer_device *resizer)
 		return ret;
 
 	/* Connect the RESIZER subdev to the video node. */
-	ret = media_entity_create_link(&resizer->subdev.entity,
+	ret = media_create_pad_link(&resizer->subdev.entity,
 				       RESIZER_PAD_SOURCE_MEM,
 				       &resizer->video_out.video.entity, 0, 0);
 	if (ret < 0)
diff --git a/include/media/media-entity.h b/include/media/media-entity.h
index db1f54f09723..534e600ffe50 100644
--- a/include/media/media-entity.h
+++ b/include/media/media-entity.h
@@ -206,7 +206,7 @@ int media_entity_init(struct media_entity *entity, u16 num_pads,
 		struct media_pad *pads);
 void media_entity_cleanup(struct media_entity *entity);
 
-int media_entity_create_link(struct media_entity *source, u16 source_pad,
+int media_create_pad_link(struct media_entity *source, u16 source_pad,
 		struct media_entity *sink, u16 sink_pad, u32 flags);
 void __media_entity_remove_links(struct media_entity *entity);
 void media_entity_remove_links(struct media_entity *entity);
-- 
2.4.3



From michael at smart-africa.com  Tue Aug 18 13:21:51 2015
From: michael at smart-africa.com (Michael van der Westhuizen)
Date: Tue, 18 Aug 2015 22:21:51 +0200
Subject: [PATCH v3 0/2] spi: dw: Reintroduce optional 16 bit data register I/O
Message-ID: <1439929313-4948-1-git-send-email-michael@smart-africa.com>

The commit dd11444327ce ("spi: dw-spi: Convert 16bit accesses to 32bit
accesses") globally changed all register access in the dw_apb_ssi driver
to 32 bit access, which breaks data register (FIFO) access on picoXcell
platforms.

This series introduces a variable to the core spi-dw driver to indicate
to the core that either 16 or 32 bit data register access is appropriate,
with the code defaulting to the current 32 bit behaviour.

The dw-spi-mmio driver is updated to support optionally setting this
variable from the device tree and the binding documentation is updated.

Prior to applying this change the following error presents on
a picoXcell pc3x3 platform:
  spi_master spi32766: interrupt_transfer: fifo overrun/underrun
  m25p80 spi32766.0: error -5 reading 9f
  m25p80: probe of spi32766.0 failed with error -5

With this series applied:
  m25p80 spi32766.0: m25p40 (512 Kbytes)

Changes in v3:
  - Rename the DT property as requested by Rob Herring.

Changes in v2:
  - Incorporate review feedback from Andy Shevchenko, reworking the
    bindings to reflect common practice and adjusting the driver
    to suit.
  - Add a wrapper inline function for accessing the data register
    using the configured with.

Michael van der Westhuizen (2):
  dt: snps,dw-apb-ssi: Document new I/O data register width property
  spi: dw: Allow interface drivers to limit data I/O to word sizes

 drivers/spi/spi-dw-mmio.c |  3 +++
 drivers/spi/spi-dw.c      |  4 ++--
 drivers/spi/spi-dw.h      | 35 +++++++++++++++++++++++++++++++++++
 3 files changed, 40 insertions(+), 2 deletions(-)

-- 
2.1.4



From michael at smart-africa.com  Tue Aug 18 13:21:52 2015
From: michael at smart-africa.com (Michael van der Westhuizen)
Date: Tue, 18 Aug 2015 22:21:52 +0200
Subject: [PATCH v3 1/2] dt: snps,
 dw-apb-ssi: Document new I/O data register width property
In-Reply-To: <1439929313-4948-1-git-send-email-michael@smart-africa.com>
References: <1439929313-4948-1-git-send-email-michael@smart-africa.com>
Message-ID: <1439929313-4948-2-git-send-email-michael@smart-africa.com>

This change documents a new property for the snps,dw-apb-ssi device,
allowing an implementer to specify either four byte or two bytes
access to the SPI controller data register.

This supports a change that unbreaks this driver on picoXcell
platforms.

Signed-off-by: Michael van der Westhuizen <michael at smart-africa.com>
---
Changes in v3:
  - Rename the DT property as requested by Rob Herring.

Changes in v2:
  - Incorporate review feedback from Andy Shevchenko, reworking the
    bindings to reflect common practice.

 Documentation/devicetree/bindings/spi/snps,dw-apb-ssi.txt | 2 ++
 1 file changed, 2 insertions(+)

diff --git a/Documentation/devicetree/bindings/spi/snps,dw-apb-ssi.txt b/Documentation/devicetree/bindings/spi/snps,dw-apb-ssi.txt
index bd99193..204b311 100644
--- a/Documentation/devicetree/bindings/spi/snps,dw-apb-ssi.txt
+++ b/Documentation/devicetree/bindings/spi/snps,dw-apb-ssi.txt
@@ -10,6 +10,8 @@ Required properties:
 Optional properties:
 - cs-gpios : Specifies the gpio pis to be used for chipselects.
 - num-cs : The number of chipselects. If omitted, this will default to 4.
+- reg-io-width : The I/O register width (in bytes) implemented by this
+  device.  Supported values are 2 or 4 (the default).
 
 Child nodes as per the generic SPI binding.
 
-- 
2.1.4



From michael at smart-africa.com  Tue Aug 18 13:21:53 2015
From: michael at smart-africa.com (Michael van der Westhuizen)
Date: Tue, 18 Aug 2015 22:21:53 +0200
Subject: [PATCH v3 2/2] spi: dw: Allow interface drivers to limit data I/O to
 word sizes
In-Reply-To: <1439929313-4948-1-git-send-email-michael@smart-africa.com>
References: <1439929313-4948-1-git-send-email-michael@smart-africa.com>
Message-ID: <1439929313-4948-3-git-send-email-michael@smart-africa.com>

The commit dd11444327ce ("spi: dw-spi: Convert 16bit accesses to 32bit
accesses") changed all 16bit accesses in the DW_apb_ssi driver to 32bit.
This, unfortunately, breaks data register access on picoXcell, where the
DW IP needs data register accesses to be word accesses (all other
accesses appear to be OK).

This change introduces a new master variable to allow interface drivers
to specify that 16bit data transfer I/O is required.  This change also
introduces the ability to set this variable via device tree bindings in
the MMIO interface driver.  Both the core and the MMIO interface driver
default to the current 32bit behaviour.

Before this change, on a picoXcell pc3x3:
 spi_master spi32766: interrupt_transfer: fifo overrun/underrun
 m25p80 spi32766.0: error -5 reading 9f
 m25p80: probe of spi32766.0 failed with error -5

After this change:
 m25p80 spi32766.0: m25p40 (512 Kbytes)

Fixes: dd11444327ce ("spi: dw-spi: Convert 16bit accesses to 32bit accesses")
Signed-off-by: Michael van der Westhuizen <michael at smart-africa.com>
---
Changes in v3:
  - Rename the DT property as requested by Rob Herring.

Changes in v2:
  - Incorporate review feedback from Andy Shevchenko
    - Rework the DT bindings to accept an I/O register width as a
      number of bytes rather than using a boolean spefifying the
      width preference to be 16 bits.
    - Add data register access wrapper functions and use them when
      reading and writing the data register.

 drivers/spi/spi-dw-mmio.c |  3 +++
 drivers/spi/spi-dw.c      |  4 ++--
 drivers/spi/spi-dw.h      | 35 +++++++++++++++++++++++++++++++++++
 3 files changed, 40 insertions(+), 2 deletions(-)

diff --git a/drivers/spi/spi-dw-mmio.c b/drivers/spi/spi-dw-mmio.c
index eb03e12..7edede6 100644
--- a/drivers/spi/spi-dw-mmio.c
+++ b/drivers/spi/spi-dw-mmio.c
@@ -74,6 +74,9 @@ static int dw_spi_mmio_probe(struct platform_device *pdev)
 
 	dws->max_freq = clk_get_rate(dwsmmio->clk);
 
+	of_property_read_u32(pdev->dev.of_node, "reg-io-width",
+			     &dws->reg_io_width);
+
 	num_cs = 4;
 
 	if (pdev->dev.of_node)
diff --git a/drivers/spi/spi-dw.c b/drivers/spi/spi-dw.c
index 8d67d03..4fbfcdc 100644
--- a/drivers/spi/spi-dw.c
+++ b/drivers/spi/spi-dw.c
@@ -194,7 +194,7 @@ static void dw_writer(struct dw_spi *dws)
 			else
 				txw = *(u16 *)(dws->tx);
 		}
-		dw_writel(dws, DW_SPI_DR, txw);
+		dw_write_io_reg(dws, DW_SPI_DR, txw);
 		dws->tx += dws->n_bytes;
 	}
 }
@@ -205,7 +205,7 @@ static void dw_reader(struct dw_spi *dws)
 	u16 rxw;
 
 	while (max--) {
-		rxw = dw_readl(dws, DW_SPI_DR);
+		rxw = dw_read_io_reg(dws, DW_SPI_DR);
 		/* Care rx only if the transfer's original "rx" is not null */
 		if (dws->rx_end - dws->len) {
 			if (dws->n_bytes == 1)
diff --git a/drivers/spi/spi-dw.h b/drivers/spi/spi-dw.h
index 6c91391..b75ed32 100644
--- a/drivers/spi/spi-dw.h
+++ b/drivers/spi/spi-dw.h
@@ -109,6 +109,7 @@ struct dw_spi {
 	u32			fifo_len;	/* depth of the FIFO buffer */
 	u32			max_freq;	/* max bus freq supported */
 
+	u32			reg_io_width;	/* DR I/O width in bytes */
 	u16			bus_num;
 	u16			num_cs;		/* supported slave numbers */
 
@@ -145,11 +146,45 @@ static inline u32 dw_readl(struct dw_spi *dws, u32 offset)
 	return __raw_readl(dws->regs + offset);
 }
 
+static inline u16 dw_readw(struct dw_spi *dws, u32 offset)
+{
+	return __raw_readw(dws->regs + offset);
+}
+
 static inline void dw_writel(struct dw_spi *dws, u32 offset, u32 val)
 {
 	__raw_writel(val, dws->regs + offset);
 }
 
+static inline void dw_writew(struct dw_spi *dws, u32 offset, u16 val)
+{
+	__raw_writew(val, dws->regs + offset);
+}
+
+static inline u32 dw_read_io_reg(struct dw_spi *dws, u32 offset)
+{
+	switch (dws->reg_io_width) {
+	case 2:
+		return dw_readw(dws, offset);
+	case 4:
+	default:
+		return dw_readl(dws, offset);
+	}
+}
+
+static inline void dw_write_io_reg(struct dw_spi *dws, u32 offset, u32 val)
+{
+	switch (dws->reg_io_width) {
+	case 2:
+		dw_writew(dws, offset, val);
+		break;
+	case 4:
+	default:
+		dw_writel(dws, offset, val);
+		break;
+	}
+}
+
 static inline void spi_enable_chip(struct dw_spi *dws, int enable)
 {
 	dw_writel(dws, DW_SPI_SSIENR, (enable ? 1 : 0));
-- 
2.1.4



From m-karicheri2 at ti.com  Tue Aug 18 13:25:44 2015
From: m-karicheri2 at ti.com (Murali Karicheri)
Date: Tue, 18 Aug 2015 16:25:44 -0400
Subject: [PATCH] ARM: keystone: add a work around to handle asynchronous
 external abort
In-Reply-To: <20150818081334.GK7557@n2100.arm.linux.org.uk>
References: <1439320409-20084-1-git-send-email-m-karicheri2@ti.com>
 <55CDF579.4050408@ti.com> <20150814140934.GX7557@n2100.arm.linux.org.uk>
 <55CE05EC.4040909@oracle.com> <55CE633C.10402@ti.com>
 <20150814215617.GA7557@n2100.arm.linux.org.uk> <55D25C64.3090107@ti.com>
 <55D2A1DD.9000007@oracle.com> <20150818081334.GK7557@n2100.arm.linux.org.uk>
Message-ID: <55D394C8.7070605@ti.com>

Russell,

On 08/18/2015 04:13 AM, Russell King - ARM Linux wrote:
> On Mon, Aug 17, 2015 at 08:09:17PM -0700, santosh.shilimkar at oracle.com wrote:
>>  From the logs this seems to be mostly clock related issue for some
>> peripheral. If the bootloader clock enable all hack still exists,
>> may be you can try that out.
>>
>> Another way to debug this is to start disabling peripheral drivers
>> from the kernel 1 by 1 and see if the issue goes away.
>
> Highly unlikely to make any difference.  As the failure happens soo early
> with the patch applied, the kernel hasn't had much of a chance to touch
> the hardware - about the only things are the decompressor and the kernel
> touching the early console.  As they seem to be working, it suggests
> that's not the cause.
>
> It seems to be pointing towards something in the boot loader...
>
> Normally, uboot will hook itself into the vectors to report errors, but
> I wonder whether uboot enables asynchronous aborts while it's running.
> Don't forget to make sure that the aborts are disabled again prior to
> calling the kernel.
>
Thanks for your input.

The patch works now once I move the local_abort_enable() to later just 
before calling reserve_crashkernel() in setup_arch(). The abort handler 
gets called right after enabling it which means it has happened even 
before reaching here.

I have added the abort handler to u-boot code and I get the same abort 
which means the root cause is u-boot or ROM boot loader. I would try to 
debug if root cause is u-boot. If it is ROM boot loader, I will have to 
add a work around in u-boot or Linux. Is there a preference of one over 
the other? The exception handling in u-boot is premature and will 
require more work to add a work around. Is there still a possibility of 
adding the work around in Linux?

-- 
Murali Karicheri
Linux Kernel, Keystone


From javier at dowhile0.org  Tue Aug 18 13:30:18 2015
From: javier at dowhile0.org (Javier Martinez Canillas)
Date: Tue, 18 Aug 2015 22:30:18 +0200
Subject: [PATCH 2/2] ARM: dts: rockchip: correct regulator PM properties
In-Reply-To: <51457775.D3ds00ymOJ@phil>
References: <1439923455-109818-1-git-send-email-briannorris@chromium.org>
 <1439923455-109818-2-git-send-email-briannorris@chromium.org>
 <51457775.D3ds00ymOJ@phil>
Message-ID: <CABxcv==hssVa-b=cOjh3QhEOmQPZVvEPt0apLHQOva3GjJb9PA@mail.gmail.com>

Hello Heiko,

On Tue, Aug 18, 2015 at 9:17 PM, Heiko Stuebner <heiko at sntech.de> wrote:
> Hi Brian,
>
>
> thanks for catching these oversights, but see below
>
> Am Dienstag, 18. August 2015, 11:44:15 schrieb Brian Norris:
>> This DTS file was submitted with non-upstream bindings. I happened
>> across this while reviewing the jaq DTS.
>>
>> Signed-off-by: Brian Norris <briannorris at chromium.org>
>> Cc: Alexandru M Stan <amstan at chromium.org>
>> Cc: Douglas Anderson <dianders at chromium.org>
>> ---
>> Tested on jaq, not minnie
>>
>>  arch/arm/boot/dts/rk3288-veyron-minnie.dts | 8 ++++++--
>>  1 file changed, 6 insertions(+), 2 deletions(-)
>>
>> diff --git a/arch/arm/boot/dts/rk3288-veyron-minnie.dts
>> b/arch/arm/boot/dts/rk3288-veyron-minnie.dts index
>> 0e30bd6bf92b..6f619c154dc6 100644
>> --- a/arch/arm/boot/dts/rk3288-veyron-minnie.dts
>> +++ b/arch/arm/boot/dts/rk3288-veyron-minnie.dts
>> @@ -128,12 +128,16 @@
>>                       regulator-min-microvolt = <3300000>;
>>                       regulator-max-microvolt = <3300000>;
>>                       regulator-name = "vcc33_touch";
>> -                     regulator-suspend-mem-disabled;
>> +                     regulator-state-mem {
>> +                             regulator-on-in-suspend;
>> +                     };
>>               };
>>
>>               vcc5v_touch: SWITCH_REG2 {
>>                       regulator-name = "vcc5v_touch";
>> -                     regulator-suspend-mem-disabled;
>> +                     regulator-state-mem {
>> +                             regulator-on-in-suspend;
>> +                     };
>
> wouldn't regulator-suspend-mem-disabled translate to regulator-off-in-suspend?

Correct, the downstream regulator-suspend-mem-disabled is equivalent
to regulator-off-in-suspend in mainline.

> At least looks like it according to https://lkml.org/lkml/2013/7/25/592
>

I guess you meant https://lkml.org/lkml/2014/10/10/162 since it was
Chanwoo's and not Vincent's version that finally landed.

>
> Heiko
>

Best regards,
Javier


From javier at dowhile0.org  Tue Aug 18 13:38:05 2015
From: javier at dowhile0.org (Javier Martinez Canillas)
Date: Tue, 18 Aug 2015 22:38:05 +0200
Subject: [PATCH 2/2] ARM: dts: rockchip: correct regulator PM properties
In-Reply-To: <CABxcv==hssVa-b=cOjh3QhEOmQPZVvEPt0apLHQOva3GjJb9PA@mail.gmail.com>
References: <1439923455-109818-1-git-send-email-briannorris@chromium.org>
 <1439923455-109818-2-git-send-email-briannorris@chromium.org>
 <51457775.D3ds00ymOJ@phil>
 <CABxcv==hssVa-b=cOjh3QhEOmQPZVvEPt0apLHQOva3GjJb9PA@mail.gmail.com>
Message-ID: <CABxcv==UJXn+v3KE9EE=ry_0aC-T1PBePjyKzn7oawtF=rrNzw@mail.gmail.com>

On Tue, Aug 18, 2015 at 10:30 PM, Javier Martinez Canillas
<javier at dowhile0.org> wrote:
> On Tue, Aug 18, 2015 at 9:17 PM, Heiko Stuebner <heiko at sntech.de> wrote:
>>>
>>>               vcc5v_touch: SWITCH_REG2 {
>>>                       regulator-name = "vcc5v_touch";
>>> -                     regulator-suspend-mem-disabled;
>>> +                     regulator-state-mem {
>>> +                             regulator-on-in-suspend;
>>> +                     };
>>
>> wouldn't regulator-suspend-mem-disabled translate to regulator-off-in-suspend?
>
> Correct, the downstream regulator-suspend-mem-disabled is equivalent
> to regulator-off-in-suspend in mainline.
>
>> At least looks like it according to https://lkml.org/lkml/2013/7/25/592
>>
>
> I guess you meant https://lkml.org/lkml/2014/10/10/162 since it was
> Chanwoo's and not Vincent's version that finally landed.
>
>>

oh, now I got that you referenced Vincent's patch just to show the
regulator-suspend-mem-disabled property description.

Sorry for the noise then but yes you are right about the translation :-)

Best regards,
Javier


From eric at anholt.net  Tue Aug 18 13:56:24 2015
From: eric at anholt.net (Eric Anholt)
Date: Tue, 18 Aug 2015 13:56:24 -0700
Subject: [PATCH 3/7] drm/vc4: Add KMS support for Raspberry Pi.
In-Reply-To: <20150813211755.GE17734@phenom.ffwll.local>
References: <1439427380-2436-1-git-send-email-eric@anholt.net>
 <1439427380-2436-4-git-send-email-eric@anholt.net>
 <20150813075141.GX17734@phenom.ffwll.local>
 <87d1yqq5po.fsf@eliezer.anholt.net>
 <20150813211755.GE17734@phenom.ffwll.local>
Message-ID: <87y4h8iadj.fsf@eliezer.anholt.net>

Daniel Vetter <daniel at ffwll.ch> writes:

> On Thu, Aug 13, 2015 at 01:44:03PM -0700, Eric Anholt wrote:
>> Daniel Vetter <daniel at ffwll.ch> writes:
>> 
>> > On Wed, Aug 12, 2015 at 05:56:16PM -0700, Eric Anholt wrote:
>> >> This is the start of a full VC4 driver.  Right now this just supports
>> >> configuring the display using a pre-existing video mode (because
>> >> changing the pixel clock isn't available yet, and doesn't work when it
>> >> is).  However, this is enough for fbcon and bringing up X using
>> >> xf86-video-modesetting.
>> >> 
>> >> Signed-off-by: Eric Anholt <eric at anholt.net>
>> >> ---
>> >>  drivers/gpu/drm/Kconfig           |   2 +
>> >>  drivers/gpu/drm/Makefile          |   1 +
>> >>  drivers/gpu/drm/vc4/Kconfig       |  14 +
>> >>  drivers/gpu/drm/vc4/Makefile      |  18 ++
>> >>  drivers/gpu/drm/vc4/vc4_bo.c      |  54 ++++
>> >>  drivers/gpu/drm/vc4/vc4_crtc.c    | 583 ++++++++++++++++++++++++++++++++++
>> >>  drivers/gpu/drm/vc4/vc4_debugfs.c |  38 +++
>> >>  drivers/gpu/drm/vc4/vc4_drv.c     | 249 +++++++++++++++
>> >>  drivers/gpu/drm/vc4/vc4_drv.h     | 123 +++++++
>> >>  drivers/gpu/drm/vc4/vc4_hdmi.c    | 651 ++++++++++++++++++++++++++++++++++++++
>> >>  drivers/gpu/drm/vc4/vc4_hvs.c     | 172 ++++++++++
>> >>  drivers/gpu/drm/vc4/vc4_kms.c     |  84 +++++
>> >>  drivers/gpu/drm/vc4/vc4_plane.c   | 320 +++++++++++++++++++
>> >>  drivers/gpu/drm/vc4/vc4_regs.h    | 562 ++++++++++++++++++++++++++++++++
>> >>  14 files changed, 2871 insertions(+)
>> >>  create mode 100644 drivers/gpu/drm/vc4/Kconfig
>> >>  create mode 100644 drivers/gpu/drm/vc4/Makefile
>> >>  create mode 100644 drivers/gpu/drm/vc4/vc4_bo.c
>> >>  create mode 100644 drivers/gpu/drm/vc4/vc4_crtc.c
>> >>  create mode 100644 drivers/gpu/drm/vc4/vc4_debugfs.c
>> >>  create mode 100644 drivers/gpu/drm/vc4/vc4_drv.c
>> >>  create mode 100644 drivers/gpu/drm/vc4/vc4_drv.h
>> >>  create mode 100644 drivers/gpu/drm/vc4/vc4_hdmi.c
>> >>  create mode 100644 drivers/gpu/drm/vc4/vc4_hvs.c
>> >>  create mode 100644 drivers/gpu/drm/vc4/vc4_kms.c
>> >>  create mode 100644 drivers/gpu/drm/vc4/vc4_plane.c
>> >>  create mode 100644 drivers/gpu/drm/vc4/vc4_regs.h
>> >
>> > Made a quick pass and found a few things to update to latest drm
>> > developments. Of course didn't look at the hardware details since no clue,
>> > but looks really nice overall.
>> 
>> If you have anything about the hardware that you were curious about, I'd
>> be interested in trying to explain them in the comments to the extent
>> that I can.  It's unfortunate that we haven't shipped docs for the
>> display side of things, but had to do a lot of reading of the verilog
>> just to get this far, anyway.
>
> The only thing I spotted is that you right now only register a primary and
> cursor plane. I guess the plan we once discussed about exposing piles of
> planes for -modesetting accel isn't there yet?
>
> But otherwise I really didn't go into the hardware details.

Yeah, I haven't done piles of planes because what we have right now
means I don't have to do the bandwidth limits tracking yet.
-------------- next part --------------
A non-text attachment was scrubbed...
Name: signature.asc
Type: application/pgp-signature
Size: 818 bytes
Desc: not available
URL: <http://lists.infradead.org/pipermail/linux-arm-kernel/attachments/20150818/efaeaf36/attachment.sig>

From petr.cvek at tul.cz  Tue Aug 18 14:01:25 2015
From: petr.cvek at tul.cz (Petr Cvek)
Date: Tue, 18 Aug 2015 23:01:25 +0200
Subject: [PATCH v2 18/21] mfd: htc-pasic3: Prepare driver for leds-pasic3
In-Reply-To: <20150818065207.GC6180@x1>
References: <cover.1439843482.git.petr.cvek@tul.cz> <55D25ABC.1000405@tul.cz>
 <20150818065207.GC6180@x1>
Message-ID: <55D39D25.7010909@tul.cz>

Dne 18.8.2015 v 08:52 Lee Jones napsal(a):
> On Tue, 18 Aug 2015, Petr Cvek wrote:
> 
>> Fix register definitions and prepare structures for new leds-pasic3
>> driver.
>>
>> Signed-off-by: Petr Cvek <petr.cvek at tul.cz>
>> ---
>>  drivers/mfd/htc-pasic3.c       | 54 ++++++++++++++++-----------
>>  include/linux/mfd/htc-pasic3.h | 85 +++++++++++++++++++++++++++++++-----------
>>  2 files changed, 97 insertions(+), 42 deletions(-)
>>
>> diff --git a/drivers/mfd/htc-pasic3.c b/drivers/mfd/htc-pasic3.c
>> index e88d4f6..16e156d 100644
>> --- a/drivers/mfd/htc-pasic3.c
>> +++ b/drivers/mfd/htc-pasic3.c
>> @@ -3,6 +3,9 @@
>>   *
>>   * Copyright (C) 2006 Philipp Zabel <philipp.zabel at gmail.com>
>>   *
>> + * 2015:	Added registers for LED and RESET, see htc-pasic3.h
>> + *		-- Petr Cvek
>> + *
> 
> This is pretty unconventional.
> 
> Please look to see what others have done.

LED support: Petr Cvek <petr.cvek at tul.cz>

OK?

>> @@ -130,6 +140,7 @@ static int __init pasic3_probe(struct platform_device *pdev)
>>  	struct device *dev = &pdev->dev;
>>  	struct pasic3_data *asic;
>>  	struct resource *r;
>> +	struct pasic3_leds_pdata *leds_pdata;
>>  	int ret;
>>  	int irq = 0;
>>  
>> @@ -162,6 +173,8 @@ static int __init pasic3_probe(struct platform_device *pdev)
>>  	/* calculate bus shift from mem resource */
>>  	asic->bus_shift = (resource_size(r) - 5) >> 3;
>>  
>> +	spin_lock_init(&asic->lock);
>> +
>>  	if (pdata && pdata->clock_rate) {
>>  		ds1wm_pdata.clock_rate = pdata->clock_rate;
>>  		/* the first 5 PASIC3 registers control the DS1WM */
>> @@ -172,13 +185,12 @@ static int __init pasic3_probe(struct platform_device *pdev)
>>  			dev_warn(dev, "failed to register DS1WM\n");
>>  	}
>>  
>> -	if (pdata && pdata->led_pdata) {
>> -		led_cell.platform_data = pdata->led_pdata;
>> -		led_cell.pdata_size = sizeof(struct pasic3_leds_machinfo);
>> -		ret = mfd_add_devices(&pdev->dev, pdev->id, &led_cell, 1, r,
>> -				      0, NULL);
>> -		if (ret < 0)
>> -			dev_warn(dev, "failed to register LED device\n");
>> +	if (pdata && pdata->pasic3_leds) {
>> +		leds_pdata = dev_get_platdata(&pdata->pasic3_leds->dev);
> 
> Whoa!  You're passing a pointer to a device through pdata?
> 
> I don't like that at all.  Please explain.

> 
>> +		if (leds_pdata) {
>> +			leds_pdata->mfd_dev = dev;
>> +			platform_device_register(pdata->pasic3_leds);
> 
> What's the idea here?

Actually, I don't know how to do this in a clean way as pasic3_read_register() and pasic3_write_register() require device struct to pass address for accessing the registers. Only way would be to rewrite all functions which call pasic3_*_register() (removing struct device *dev and change it to struct pasic3_data *asic).

Petr


From mathieu at codeaurora.org  Tue Aug 18 14:04:17 2015
From: mathieu at codeaurora.org (Mathieu Olivari)
Date: Tue, 18 Aug 2015 14:04:17 -0700
Subject: [PATCH v4 0/3] qcom: Add SMEM MTD parser
Message-ID: <1439931860-7473-1-git-send-email-mathieu@codeaurora.org>

QCOM platforms such as IPQ806x are using SMEM to store their flash
layout. This patch set adds the DT nodes required to instanciate SMEM
on IPQ806x and add an MTD parser using it.

This change is based on the SMEM driver posted here:
*https://lkml.org/lkml/2015/7/27/1125

v2:
*Release the SPI device reference after looking it up (put_device())
*Represent SMEM data as __le32 rather than u32
*Move new DT nodes in their proper respective location
*Address readability concerns in MTD parser

v3:
*Address Bjorn's comments

v4:
*Fix licensing case
*Fix smem tag in dts file

Mathieu Olivari (3):
  ARM: qcom: add SFPB nodes to IPQ806x dts
  ARM: qcom: add SMEM device node to IPQ806x dts
  mtd: add SMEM parser for QCOM platforms

 arch/arm/boot/dts/qcom-ipq8064.dtsi |  23 +++-
 drivers/mtd/Kconfig                 |   7 ++
 drivers/mtd/Makefile                |   1 +
 drivers/mtd/qcom_smem_part.c        | 224 ++++++++++++++++++++++++++++++++++++
 4 files changed, 254 insertions(+), 1 deletion(-)
 create mode 100644 drivers/mtd/qcom_smem_part.c

-- 
2.1.4



From mathieu at codeaurora.org  Tue Aug 18 14:04:19 2015
From: mathieu at codeaurora.org (Mathieu Olivari)
Date: Tue, 18 Aug 2015 14:04:19 -0700
Subject: [PATCH v4 2/3] ARM: qcom: add SMEM device node to IPQ806x dts
In-Reply-To: <1439931860-7473-1-git-send-email-mathieu@codeaurora.org>
References: <1439931860-7473-1-git-send-email-mathieu@codeaurora.org>
Message-ID: <1439931860-7473-3-git-send-email-mathieu@codeaurora.org>

SMEM is used on IPQ806x to store various board related information such
as boot device and flash partition layout. We'll declare it as a device
so we can make use of it thanks to the new SMEM soc driver.

Signed-off-by: Mathieu Olivari <mathieu at codeaurora.org>
---

Notes:
    v2:
    *Rename "smem" tag into "smem_region"

 arch/arm/boot/dts/qcom-ipq8064.dtsi | 8 +++++++-
 1 file changed, 7 insertions(+), 1 deletion(-)

diff --git a/arch/arm/boot/dts/qcom-ipq8064.dtsi b/arch/arm/boot/dts/qcom-ipq8064.dtsi
index 8d366ae..9834c94 100644
--- a/arch/arm/boot/dts/qcom-ipq8064.dtsi
+++ b/arch/arm/boot/dts/qcom-ipq8064.dtsi
@@ -55,7 +55,7 @@
 			no-map;
 		};
 
-		smem at 41000000 {
+		smem_region: smem at 41000000 {
 			reg = <0x41000000 0x200000>;
 			no-map;
 		};
@@ -341,4 +341,10 @@
 
 		#hwlock-cells = <1>;
 	};
+
+	smem {
+		compatible = "qcom,smem";
+		memory-region = <&smem_region>;
+		hwlocks = <&sfpb_mutex 3>;
+	};
 };
-- 
2.1.4



From mathieu at codeaurora.org  Tue Aug 18 14:04:18 2015
From: mathieu at codeaurora.org (Mathieu Olivari)
Date: Tue, 18 Aug 2015 14:04:18 -0700
Subject: [PATCH v4 1/3] ARM: qcom: add SFPB nodes to IPQ806x dts
In-Reply-To: <1439931860-7473-1-git-send-email-mathieu@codeaurora.org>
References: <1439931860-7473-1-git-send-email-mathieu@codeaurora.org>
Message-ID: <1439931860-7473-2-git-send-email-mathieu@codeaurora.org>

Add one new node to the ipq806x.dtsi file to declare & register the
hardware spinlock devices. This mechanism is required to be used by
other drivers such as SMEM.

Signed-off-by: Mathieu Olivari <mathieu at codeaurora.org>
---
 arch/arm/boot/dts/qcom-ipq8064.dtsi | 11 +++++++++++
 1 file changed, 11 insertions(+)

diff --git a/arch/arm/boot/dts/qcom-ipq8064.dtsi b/arch/arm/boot/dts/qcom-ipq8064.dtsi
index 9f727d8..8d366ae 100644
--- a/arch/arm/boot/dts/qcom-ipq8064.dtsi
+++ b/arch/arm/boot/dts/qcom-ipq8064.dtsi
@@ -329,5 +329,16 @@
 			#reset-cells = <1>;
 		};
 
+		sfpb_mutex_block: syscon at 1200600 {
+			compatible = "syscon";
+			reg = <0x01200600 0x100>;
+		};
+	};
+
+	sfpb_mutex: sfpb-mutex {
+		compatible = "qcom,sfpb-mutex";
+		syscon = <&sfpb_mutex_block 4 4>;
+
+		#hwlock-cells = <1>;
 	};
 };
-- 
2.1.4



From mathieu at codeaurora.org  Tue Aug 18 14:04:20 2015
From: mathieu at codeaurora.org (Mathieu Olivari)
Date: Tue, 18 Aug 2015 14:04:20 -0700
Subject: [PATCH v4 3/3] mtd: add SMEM parser for QCOM platforms
In-Reply-To: <1439931860-7473-1-git-send-email-mathieu@codeaurora.org>
References: <1439931860-7473-1-git-send-email-mathieu@codeaurora.org>
Message-ID: <1439931860-7473-4-git-send-email-mathieu@codeaurora.org>

On QCOM platforms using MTD devices storage (such as IPQ806x), SMEM is
used to store partition layout. This new parser can now be used to read
SMEM and use it to register an MTD layout according to its content.

Signed-off-by: Mathieu Olivari <mathieu at codeaurora.org>
---

Notes:
    v2:
    *Release the SPI device reference after looking it up (put_device())
    *Represent SMEM data as __le32 rather than u32
    *Move new DT nodes in their proper respective location
    *Address readability concerns in MTD parser
    
    v3:
    *Redefine SMEM functions prototypes for better readability
    *Duplicate MTD name instead of pointing to SMEM string location in case
     mtd layer tries to free it
    *Rework some of the comments
    
    v4:
    *Fix case in the license string

 drivers/mtd/Kconfig          |   7 ++
 drivers/mtd/Makefile         |   1 +
 drivers/mtd/qcom_smem_part.c | 246 +++++++++++++++++++++++++++++++++++++++++++
 3 files changed, 254 insertions(+)
 create mode 100644 drivers/mtd/qcom_smem_part.c

diff --git a/drivers/mtd/Kconfig b/drivers/mtd/Kconfig
index a03ad29..debc887 100644
--- a/drivers/mtd/Kconfig
+++ b/drivers/mtd/Kconfig
@@ -155,6 +155,13 @@ config MTD_BCM47XX_PARTS
 	  This provides partitions parser for devices based on BCM47xx
 	  boards.
 
+config MTD_QCOM_SMEM_PARTS
+	tristate "QCOM SMEM partitioning support"
+	depends on QCOM_SMEM
+	help
+	  This provides partitions parser for QCOM devices using SMEM
+	  such as IPQ806x.
+
 comment "User Modules And Translation Layers"
 
 #
diff --git a/drivers/mtd/Makefile b/drivers/mtd/Makefile
index 99bb9a1..b3c7de4 100644
--- a/drivers/mtd/Makefile
+++ b/drivers/mtd/Makefile
@@ -13,6 +13,7 @@ obj-$(CONFIG_MTD_AFS_PARTS)	+= afs.o
 obj-$(CONFIG_MTD_AR7_PARTS)	+= ar7part.o
 obj-$(CONFIG_MTD_BCM63XX_PARTS)	+= bcm63xxpart.o
 obj-$(CONFIG_MTD_BCM47XX_PARTS)	+= bcm47xxpart.o
+obj-$(CONFIG_MTD_QCOM_SMEM_PARTS) += qcom_smem_part.o
 
 # 'Users' - code which presents functionality to userspace.
 obj-$(CONFIG_MTD_BLKDEVS)	+= mtd_blkdevs.o
diff --git a/drivers/mtd/qcom_smem_part.c b/drivers/mtd/qcom_smem_part.c
new file mode 100644
index 0000000..b4f8acc
--- /dev/null
+++ b/drivers/mtd/qcom_smem_part.c
@@ -0,0 +1,246 @@
+/*
+ * Copyright (c) 2015, The Linux Foundation. All rights reserved.
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License version 2 and
+ * only 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/kernel.h>
+#include <linux/device.h>
+#include <linux/slab.h>
+
+#include <linux/mtd/mtd.h>
+#include <linux/mtd/partitions.h>
+#include <linux/spi/spi.h>
+#include <linux/module.h>
+
+#include <linux/soc/qcom/smem.h>
+
+/* Processor/host identifier for the application processor */
+#define QCOM_SMEM_GLOBAL		0
+
+/* SMEM items index */
+#define SMEM_AARM_PARTITION_TABLE	9
+#define SMEM_BOOT_FLASH_TYPE		421
+#define SMEM_BOOT_FLASH_BLOCK_SIZE	424
+
+/* SMEM Flash types */
+#define SMEM_FLASH_NAND			2
+#define SMEM_FLASH_SPI			6
+
+#define SMEM_PART_NAME_SZ		16
+#define SMEM_PARTS_MAX			32
+
+struct smem_partition {
+	char name[SMEM_PART_NAME_SZ];
+	__le32 start;
+	__le32 size;
+	__le32 attr;
+};
+
+struct smem_partition_table {
+	u8 magic[8];
+	__le32 version;
+	__le32 len;
+	struct smem_partition parts[SMEM_PARTS_MAX];
+};
+
+/* SMEM Magic values in partition table */
+static const u8 SMEM_PTABLE_MAGIC[] = {
+	0xaa, 0x73, 0xee, 0x55,
+	0xdb, 0xbd, 0x5e, 0xe3,
+};
+
+static int qcom_smem_get_flash_blksz(void)
+{
+	int ret;
+	size_t size;
+	u64 *smem_blksz;
+
+	ret = qcom_smem_get(QCOM_SMEM_GLOBAL, SMEM_BOOT_FLASH_BLOCK_SIZE,
+			    (void **) &smem_blksz, &size);
+
+	if (ret < 0) {
+		pr_err("Unable to read flash blksz from SMEM\n");
+		return -ENOENT;
+	}
+
+	if (size != sizeof(*smem_blksz)) {
+		pr_err("Invalid flash blksz size in SMEM\n");
+		return -EINVAL;
+	}
+
+	/* Sanity check block size value before casting it */
+	if (*smem_blksz > INT_MAX) {
+		pr_err("Invalid flash block size in SMEM\n");
+		return -EINVAL;
+	}
+
+	return (int) *smem_blksz;
+}
+
+static int qcom_smem_get_flash_type(void)
+{
+	int ret;
+	size_t size;
+	u64 *smem_flash_type;
+
+	ret = qcom_smem_get(QCOM_SMEM_GLOBAL, SMEM_BOOT_FLASH_TYPE,
+			    (void **) &smem_flash_type, &size);
+
+	if (ret < 0) {
+		pr_err("Unable to read flash type from SMEM\n");
+		return -ENOENT;
+	}
+
+	if (size != sizeof(*smem_flash_type)) {
+		pr_err("Invalid flash type size in SMEM\n");
+		return -EINVAL;
+	}
+
+	/* Sanity check flash type value before casting it */
+	if (*smem_flash_type > INT_MAX) {
+		pr_err("Invalid flash type in SMEM\n");
+		return -EINVAL;
+	}
+
+	return (int) *smem_flash_type;
+}
+
+static struct smem_partition *qcom_smem_get_flash_partitions(size_t *count)
+{
+	struct smem_partition_table *smem_parts;
+	int ret;
+
+	ret = qcom_smem_get(QCOM_SMEM_GLOBAL, SMEM_AARM_PARTITION_TABLE,
+			    (void **) &smem_parts, NULL);
+
+	if (ret < 0) {
+		pr_err("Unable to read partition table from SMEM\n");
+		return ERR_PTR(-ENOENT);
+	}
+
+	if (memcmp(SMEM_PTABLE_MAGIC, smem_parts->magic,
+		   sizeof(SMEM_PTABLE_MAGIC))) {
+		pr_err("SMEM partition magic invalid\n");
+		return ERR_PTR(-EINVAL);
+	}
+
+	if (le32_to_cpu(smem_parts->version) != 3) {
+		pr_err("SMEM version unsupported\n");
+		return ERR_PTR(-EINVAL);
+	}
+
+	*count = le32_to_cpu(smem_parts->len);
+
+	return smem_parts->parts;
+}
+
+static int of_dev_node_match(struct device *dev, void *data)
+{
+	return dev->of_node == data;
+}
+
+static bool is_spi_device(struct device_node *np)
+{
+	struct device *dev;
+
+	dev = bus_find_device(&spi_bus_type, NULL, np, of_dev_node_match);
+	if (!dev)
+		return false;
+
+	put_device(dev);
+	return true;
+}
+
+static int parse_qcom_smem_partitions(struct mtd_info *master,
+				      struct mtd_partition **pparts,
+				      struct mtd_part_parser_data *data)
+{
+	struct smem_partition *smem_part;
+	int smem_flash_type, smem_blksz;
+	size_t nbparts = 0, len;
+	struct mtd_partition *mtd_parts;
+	struct device_node *of_node = data->of_node;
+
+	/* Only parse partitions on the specified memory type */
+	smem_flash_type = qcom_smem_get_flash_type();
+	if (smem_flash_type < 0)
+		return smem_flash_type;
+
+	if ((smem_flash_type == SMEM_FLASH_NAND && !mtd_type_is_nand(master))
+	    || (smem_flash_type == SMEM_FLASH_SPI && !is_spi_device(of_node)))
+		return 0;
+
+	/* Make sure the block size in SMEM matches the block size in MTD */
+	smem_blksz = qcom_smem_get_flash_blksz();
+	if (smem_blksz < 0)
+		return smem_blksz;
+
+	if (smem_blksz != master->erasesize) {
+		pr_err("SMEM block size differs from MTD block size\n");
+		return -EINVAL;
+	}
+
+	/* Get partition pointer from SMEM */
+	smem_part = qcom_smem_get_flash_partitions(&nbparts);
+	if (IS_ERR_OR_NULL(smem_part))
+		return -EINVAL;
+
+	/* Allocate and populate the mtd structures */
+	mtd_parts = kcalloc(nbparts, sizeof(*mtd_parts), GFP_KERNEL);
+	if (!mtd_parts)
+		return -ENOMEM;
+
+	*pparts = mtd_parts;
+	len = nbparts;
+
+	while (len--) {
+		mtd_parts->name = kstrdup(smem_part->name, GFP_KERNEL);
+		mtd_parts->size = le32_to_cpu(smem_part->size) * smem_blksz;
+		mtd_parts->offset = le32_to_cpu(smem_part->start) * smem_blksz;
+
+		/*
+		 * The last SMEM partition may have its size marked as
+		 * something like 0xffffffff, which means "until the end of the
+		 * flash device". In this case, truncate it.
+		 */
+		if (mtd_parts->offset + mtd_parts->size > master->size)
+			mtd_parts->size = master->size - mtd_parts->offset;
+
+		smem_part++;
+		mtd_parts++;
+	}
+
+	return nbparts;
+}
+
+static struct mtd_part_parser qcom_smem_parser = {
+	.owner = THIS_MODULE,
+	.parse_fn = parse_qcom_smem_partitions,
+	.name = "qcom-smem",
+};
+
+static int __init qcom_smem_parser_init(void)
+{
+	register_mtd_parser(&qcom_smem_parser);
+	return 0;
+}
+
+static void __exit qcom_smem_parser_exit(void)
+{
+	deregister_mtd_parser(&qcom_smem_parser);
+}
+
+module_init(qcom_smem_parser_init);
+module_exit(qcom_smem_parser_exit);
+
+MODULE_LICENSE("GPL v2");
+MODULE_AUTHOR("Mathieu Olivari <mathieu at codeaurora.org>");
+MODULE_DESCRIPTION("Parsing code for SMEM based partition tables");
-- 
2.1.4



From jeffv at google.com  Tue Aug 18 14:42:44 2015
From: jeffv at google.com (Jeffrey Vander Stoep)
Date: Tue, 18 Aug 2015 14:42:44 -0700
Subject: Prevent list poison values from being mapped by userspace processes
Message-ID: <CABXk95C=CpeL4mNmS6-jJ-0bMJf6fawwfs6DM1-p8FctTEFbpw@mail.gmail.com>

List poison pointer values point to memory that is mappable by
userspace. i.e. LIST_POISON1 = 0x00100100 and LIST_POISON2 =
0x00200200. This means poison values can be valid pointers controlled
by userspace and can be used to exploit the kernel as demonstrated in
a recent blackhat talk:
https://www.blackhat.com/docs/us-15/materials/us-15-Xu-Ah-Universal-Android-Rooting-Is-Back-wp.pdf

Can these poison values be moved to an area not mappable by userspace
on 32 bit ARM?

Thanks,
Jeff


From petr.cvek at tul.cz  Tue Aug 18 14:48:34 2015
From: petr.cvek at tul.cz (Petr Cvek)
Date: Tue, 18 Aug 2015 23:48:34 +0200
Subject: [PATCH v2 19/21] leds: leds-pasic3: Add support for PASIC3 LED
 controller
In-Reply-To: <55D30875.3090103@samsung.com>
References: <cover.1439843482.git.petr.cvek@tul.cz> <55D25ADC.10703@tul.cz>
 <55D30875.3090103@samsung.com>
Message-ID: <55D3A832.90705@tul.cz>

Dne 18.8.2015 v 12:27 Jacek Anaszewski napsal(a):
> Hi Petr,
> 
> On 08/18/2015 12:06 AM, Petr Cvek wrote:
>> +/*
>> + * AIC3 (or PASIC3) LED driver for HTC Magician/Alpine/.. (not Compaq ASIC3)
> 
> s/AIC3/ASIC3/
> 
> I am a bit confused. What's the relation between ASIC3 and PASIC3?

Actually both drivers should be renamed to AIC3 (or AIC only, as there is version 2). "HTC_AIC3" is written on the chip and "pasic3" is confusing with compaq asic3 driver, which claims in Kconfig help to be compatible with HTC machines. Compaq ASIC3 has much more functionality and from brief look it seems it has 16 bit registers (HTC_AIC3 has only LEDs, RESET and DS1WM and has 8 bit registers).

>> +spinlock_t lock;
> 
> Please move it to the struct pasic3_leds_data.

OK

> 
>> +
>> +static void brightness_set(struct led_classdev *cdev,
>> +    enum led_brightness value)
>> +{
>> +    struct platform_device *pdev = to_platform_device(cdev->dev->parent);
>> +    struct pasic3_led *led = dev_get_platdata(cdev->dev);
>> +    struct pasic3_leds_pdata *pdata = dev_get_platdata(&pdev->dev);
>> +    unsigned long flags;
>> +    u8 val;
>> +
>> +    spin_lock_irqsave(&lock, flags);
>> +
>> +    if (value == LED_OFF) {
>> +        val = pasic3_read_register(pdata->mfd_dev, PASIC3_CH_CONTROL);
>> +        pasic3_write_register(pdata->mfd_dev, PASIC3_CH_CONTROL,
>> +            val & ~(led->bit_blink_en | led->bit_force_on));
>> +
>> +        val = pasic3_read_register(pdata->mfd_dev, PASIC3_MASK_A);
>> +        pasic3_write_register(pdata->mfd_dev, PASIC3_MASK_A,
>> +            val & ~led->bit_mask);
>> +
>> +        if (pdata->power_gpio) {
>> +            pdata->power_gpio_users--;
> 
> Now it is possible that power_gpio_users will have negative value.
> You should check the value before decrementing it.

> Now you are setting power_gpio_users to 1 each time brightness is set,
> whereas it should be set to 1 only if it was 0.
> 
> This could be changed to:
> 
> if (pdata->power_gpio_users == 0)
>     gpio_set_value(pdata->power_gpio, 1);
> 
> pdata->power_gpio_users++;

> 
> Shouldn't you check if also power_gpio state doesn't need to be altered
> here?
> 


Can the same brightness_set() function be called multiple times with same value (like LED_ON)?

I think I will change it to a different code altogether, power_gpio is shared variable and power can be shut off when two of three leds are disabled (green LED does not use power_gpio). Something like:

enabled_leds |= BIT(hw_num);

or

enabled_leds &= ~BIT(hw_num);

>> +        ret = gpio_request(pdata->power_gpio,
>> +            "Red-Blue LED Power");
> 
> Please use devm_gpio_request. Then you will not need pasic3_led_remove.
> 

OK



From olof at lixom.net  Tue Aug 18 13:14:16 2015
From: olof at lixom.net (Olof Johansson)
Date: Tue, 18 Aug 2015 13:14:16 -0700
Subject: [GIT PULL 1/3] ARM: imx: soc updates for 4.3
In-Reply-To: <1439311351-5268-1-git-send-email-shawnguo@kernel.org>
References: <1439311351-5268-1-git-send-email-shawnguo@kernel.org>
Message-ID: <20150818201416.GA4732@localhost>

Hi,

On Wed, Aug 12, 2015 at 12:42:29AM +0800, Shawn Guo wrote:
> Hi arm-soc maintainers,
> 
> This is the i.MX SoC changes for 4.3.  There are some input and rtc
> changes, because they are applied as a series.  Subsystem maintainers
> have ACKed these changes, so it should be fine to send them via arm-soc
> tree.

In some of these cases, may I ask why? For example, the RTC changes look
like they could just go in through the driver tree -- adding DT support to
a driver can definitely do so (and the DT changes to plumb up the device can go
through your DT branch).

> The following changes since commit d770e558e21961ad6cfdf0ff7df0eb5d7d4f0754:
> 
>   Linux 4.2-rc1 (2015-07-05 11:01:52 -0700)
> 
> are available in the git repository at:
> 
>   git://git.kernel.org/pub/scm/linux/kernel/git/shawnguo/linux.git tags/imx-soc-4.3
> 
> for you to fetch changes up to 8a0fa1843638c5078e6606114ed8bdf9ea56fab1:
> 
>   rtc: snvs: select option REGMAP_MMIO (2015-08-11 23:04:47 +0800)

I've merged this, and we can merge acked drivers in the future too if needed,
but ideally only where it's needed.


Thanks!

-Olof



From olof at lixom.net  Tue Aug 18 13:15:40 2015
From: olof at lixom.net (Olof Johansson)
Date: Tue, 18 Aug 2015 13:15:40 -0700
Subject: [GIT PULL 2/3] ARM: imx: device tree changes for 4.3
In-Reply-To: <1439311351-5268-2-git-send-email-shawnguo@kernel.org>
References: <1439311351-5268-1-git-send-email-shawnguo@kernel.org>
 <1439311351-5268-2-git-send-email-shawnguo@kernel.org>
Message-ID: <20150818201540.GB4732@localhost>

On Wed, Aug 12, 2015 at 12:42:30AM +0800, Shawn Guo wrote:
> Hi arm-soc maintainers,
> 
> This is the i.MX device tree updates for 4.3.  To resolve the dependency
> between imx6ul clock driver and DTS files on those clock ID definitions,
> the i.MX clock changes are pulled into the branch.  But since i.MX clock
> drivers are now in drivers/clk/imx/ folder, I sent the clock changes to
> Mike and Stephen.  I've already asked them to keep my clock branch
> stable/non-reabasable.  So it should be safe pull this DT change set
> into arm-soc.
> 
> Shawn
> 
> The following changes since commit 787b4271a6a0c09775241770782b22762f40bd6e:
> 
>   clk: imx: add imx6ul clk tree support (2015-07-14 15:02:13 +0800)
> 
> are available in the git repository at:
> 
>   git://git.kernel.org/pub/scm/linux/kernel/git/shawnguo/linux.git tags/imx-dt-4.3
> 
> for you to fetch changes up to 360325755336893869c419013ec0e33757432cbb:
> 
>   ARM: dts: imx6ul: add snvs power key support (2015-08-11 23:15:27 +0800)
> 
> ----------------------------------------------------------------
> The i.MX device tree updates for 4.3:
>  - Add audio and eTSEC device support and update dspi node for LS1021A.
>  - Add initial i.MX6UL and imx6ul-14x14-evk board support, and enable
>    a bunch of device support for i.MX6UL, including RTC, power key, USB,
>    QSPI, and dual FEC.
>  - Enable HDMI and LVDS dual display support for a few imx6qdl boards.
>  - Support of imx6sl-warp board rev1.12, the version which will be
>    publicly available for the customers.
>  - A few i.MX7D device additions, watchdog, cortex-a7 coresight
>    components, RTC, power key, power off.
>  - Some Vybrid updates: add device support for I2C, QSPI, eSDHC etc.,
>    update ADC node, and define stdout-path property.
>  - A few random updates for i.MX27 and i.MX53 devices.
> 

Merged, thanks.


-Olof


From olof at lixom.net  Tue Aug 18 13:16:16 2015
From: olof at lixom.net (Olof Johansson)
Date: Tue, 18 Aug 2015 13:16:16 -0700
Subject: [GIT PULL 3/3] ARM: imx: defconfig updates for 4.3
In-Reply-To: <1439311351-5268-3-git-send-email-shawnguo@kernel.org>
References: <1439311351-5268-1-git-send-email-shawnguo@kernel.org>
 <1439311351-5268-3-git-send-email-shawnguo@kernel.org>
Message-ID: <20150818201616.GC4732@localhost>

On Wed, Aug 12, 2015 at 12:42:31AM +0800, Shawn Guo wrote:
> The following changes since commit d770e558e21961ad6cfdf0ff7df0eb5d7d4f0754:
> 
>   Linux 4.2-rc1 (2015-07-05 11:01:52 -0700)
> 
> are available in the git repository at:
> 
>   git://git.kernel.org/pub/scm/linux/kernel/git/shawnguo/linux.git tags/imx-defconfig-4.3
> 
> for you to fetch changes up to 9559b3a38b26ab8410aeb822cf0596ea0b4adde4:
> 
>   ARM: imx_v6_v7_defconfig: Select CONFIG_IKCONFIG_PROC (2015-07-27 22:33:50 +0800)
> 

Merged, thanks.


-Olof



From olof at lixom.net  Tue Aug 18 13:18:09 2015
From: olof at lixom.net (Olof Johansson)
Date: Tue, 18 Aug 2015 13:18:09 -0700
Subject: [PATCH 2/2] ARM64: dts: vexpress: Use assigned-clock-parents for
 sp810
In-Reply-To: <1439343411-29168-2-git-send-email-sboyd@codeaurora.org>
References: <1439343411-29168-1-git-send-email-sboyd@codeaurora.org>
 <1439343411-29168-2-git-send-email-sboyd@codeaurora.org>
Message-ID: <20150818201809.GE4732@localhost>

On Tue, Aug 11, 2015 at 06:36:51PM -0700, Stephen Boyd wrote:
> The sp810 clk driver is calling the clk consumer APIs from
> clk_prepare ops to change the parent to a 1 MHz fixed rate clock
> for each of the clocks that the driver provides. Use
> assigned-clock-parents for this instead of doing it in the driver
> to avoid using the consumer API in provider code. This also
> allows us to remove the usage of clk provider APIs that take a
> struct clk as an argument from the sp810 driver.
> 
> Cc: Pawel Moll <pawel.moll at arm.com>
> Cc: Linus Walleij <linus.walleij at linaro.org>
> Tested-by: Sudeep Holla <sudeep.holla at arm.com>
> Signed-off-by: Stephen Boyd <sboyd at codeaurora.org>
> ---
> 
> This came out of a larger series to change this binding[1]. This
> patch can go through arm-soc independently though, so please apply.
> 
> [1] http://lkml.kernel.org/r/1438386285-5070-1-git-send-email-sboyd at codeaurora.org


Applied, thanks.


-Olof



From olof at lixom.net  Tue Aug 18 13:30:42 2015
From: olof at lixom.net (Olof Johansson)
Date: Tue, 18 Aug 2015 13:30:42 -0700
Subject: [GIT PULL] Renesas ARM Based SoC CPG/MSTP Clock Driver Updates
 for v4.3
In-Reply-To: <cover.1439365731.git.horms+renesas@verge.net.au>
References: <cover.1439365731.git.horms+renesas@verge.net.au>
Message-ID: <20150818203042.GF4732@localhost>

On Wed, Aug 12, 2015 at 05:15:13PM +0900, Simon Horman wrote:
> Hi Olof, Hi Kevin, Hi Arnd,
> 
> Please consider these Renesas ARM based SoC CPG/MSTP clock driver updates
> for v4.3.
> 
> As requested by Olof, this is a repost of patches broken out of a now
> defunct pull-request, "Renesas ARM Based SoC CPG MSTP Clock Domain Updates
> for v4.3".  The motivation being to have driver changes in a separate
> branch to DT changes.
> 
> * These patches were Acked by Stephen Boyd in a reply to:
>   [PATCH v2 00/14] ARM: shmobile: Add CPG Clock Domains
>   https://lkml.org/lkml/2015/6/8/622
> * The patch subjects were subsequently updated with other changes in:
>   [PATCH v3 00/16] ARM: shmobile: Add CPG/MSTP Clock Domain
>   https://lkml.org/lkml/2015/7/1/408
> * And further updates were made in the patchset I queued up:
>   [PATCH v4 00/16] ARM: shmobile: Add CPG/MSTP Clock Domain
>   https://lkml.org/lkml/2015/8/4/389
> 
> 
> The following changes since commit d770e558e21961ad6cfdf0ff7df0eb5d7d4f0754:
> 
>   Linux 4.2-rc1 (2015-07-05 11:01:52 -0700)
> 
> are available in the git repository at:
> 
>   git://git.kernel.org/pub/scm/linux/kernel/git/horms/renesas.git tags/renesas-clk-for-v4.3
> 
> for you to fetch changes up to f04b486d34ac6bab2aaa3988ee098b2bad3950de:
> 
>   clk: shmobile: rz: Add CPG/MSTP Clock Domain support (2015-08-12 10:31:28 +0900)

Merged into next/drivers.


-Olof


From olof at lixom.net  Tue Aug 18 13:31:41 2015
From: olof at lixom.net (Olof Johansson)
Date: Tue, 18 Aug 2015 13:31:41 -0700
Subject: [GIT PULL] Fourth Round of Renesas ARM Based SoC DT Updates for
 v4.3
In-Reply-To: <cover.1439366241.git.horms+renesas@verge.net.au>
References: <cover.1439366241.git.horms+renesas@verge.net.au>
Message-ID: <20150818203141.GG4732@localhost>

On Wed, Aug 12, 2015 at 05:15:25PM +0900, Simon Horman wrote:
> Hi Olof, Hi Kevin, Hi Arnd,
> 
> Please consider these fourth round of Renesas ARM based SoC DT updates for v4.3.
> 
> As requested by Olof, this is a repost of patches broken out of a now
> defunct pull-request, "Renesas ARM Based SoC CPG MSTP Clock Domain Updates
> for v4.3".  The motivation being to have driver changes in a separate
> branch to DT changes.
> 
> 
> This pull request is based on a merge of:
> 
> * "Renesas ARM Based SoC CPG/MSTP Clock Driver Updates for v4.3",
>   tagged as renesas-clk-for-v4.3, which I have also sent a pull request for.
> 
>   The patches in this pull request depend on driver changes in
>   renesas-clk-for-v4.3.
> 
> * "Third Round of Renesas ARM Based SoC DT Updates for v4.3",
>   tagged as renesas-dt3-for-v4.3, which you have already merged.
> 
>   The patches in this pull request update nodes added by patches
>   present in renesas-dt3-for-v4.3.

Merged, thanks.


-Olof



From olof at lixom.net  Tue Aug 18 13:33:26 2015
From: olof at lixom.net (Olof Johansson)
Date: Tue, 18 Aug 2015 13:33:26 -0700
Subject: [GIT PULL 1/2] omap soc fix for v4.3 merge window
In-Reply-To: <55cc6d03.8a8d420a.93b25.50c3SMTPIN_ADDED_BROKEN@mx.google.com>
References: <55cc6d03.8a8d420a.93b25.50c3SMTPIN_ADDED_BROKEN@mx.google.com>
Message-ID: <20150818203326.GH4732@localhost>

On Thu, Aug 13, 2015 at 03:08:45AM -0700, Tony Lindgren wrote:
> The following changes since commit 24da741c678f865de3182194604dbddcc7fc7f3c:
> 
>   Merge branch 'dm814x-soc' into omap-for-v4.3/soc (2015-07-23 21:59:18 -0700)
> 
> are available in the git repository at:
> 
>   git://git.kernel.org/pub/scm/linux/kernel/git/tmlind/linux-omap tags/omap-for-v4.3/soc-pt2
> 
> for you to fetch changes up to ed293d1ad2b0c28b6abc3bd728b07754bc00f1cd:
> 
>   memory: kill off set_irq_flags usage (2015-08-13 00:48:52 -0700)


Merged, thanks.


-Olof


From olof at lixom.net  Tue Aug 18 14:46:08 2015
From: olof at lixom.net (Olof Johansson)
Date: Tue, 18 Aug 2015 14:46:08 -0700
Subject: [PATCH] ARM: multi_v7_defconfig: Enable CROS_EC_PROTO for
 ChromeOS EC mfd driver
In-Reply-To: <1439881827-22613-1-git-send-email-javier@osg.samsung.com>
References: <1439881827-22613-1-git-send-email-javier@osg.samsung.com>
Message-ID: <20150818214608.GA21855@localhost>

On Tue, Aug 18, 2015 at 09:10:27AM +0200, Javier Martinez Canillas wrote:
> The ChromeOS mfd driver (MFD_CROS_EC) select the CROS_EC_PROTO config
> symbol because the driver uses some communication helper functions in
> drivers/platform/chrome/cros_ec_proto.c but other drivers depends on
> CROS_EC_PROTO instead. Mixing select and depends can lead to circular
> Kconfig dependencies so the MFD_CROS_EC select should be changed to a
> depends on CROS_EC_PROTO instead.
> 
> But doing so will break git bisect-ability since MFD_CROS_EC will not
> be enabled anymore unless the default configs first explicitly enable
> the CROS_EC_PROTO dependency.
> 
> Signed-off-by: Javier Martinez Canillas <javier at osg.samsung.com>

Applied to cros/ec-config in arm-soc, which will stay stable in case others
need to bring in as a prereq.


-Olof


From olof at lixom.net  Tue Aug 18 14:44:42 2015
From: olof at lixom.net (Olof Johansson)
Date: Tue, 18 Aug 2015 14:44:42 -0700
Subject: [PATCH] ARM: add TC2 PM support to multi_v7_defconfig
In-Reply-To: <alpine.LFD.2.20.1508142239070.1515@knanqh.ubzr>
References: <alpine.LFD.2.20.1508142239070.1515@knanqh.ubzr>
Message-ID: <20150818214442.GJ4732@localhost>

On Fri, Aug 14, 2015 at 10:46:25PM -0400, Nicolas Pitre wrote:
> Without this, the multi_v7_defconfig kernel cannot boot all CPUs
> nor do deep cpuidle power saving on a TC2 board.
> 
> Signed-off-by: Nicolas Pitre <nico at linaro.org>

Applied, thanks.


-Olof



From olof at lixom.net  Tue Aug 18 13:34:13 2015
From: olof at lixom.net (Olof Johansson)
Date: Tue, 18 Aug 2015 13:34:13 -0700
Subject: [GIT PULL 2/2] omap device tree changes for v4.3, part 4
In-Reply-To: <55cc7e96.4341440a.f8e59.1a49SMTPIN_ADDED_BROKEN@mx.google.com>
References: <pull-1439455019-336197>
 <55cc7e96.4341440a.f8e59.1a49SMTPIN_ADDED_BROKEN@mx.google.com>
Message-ID: <20150818203413.GI4732@localhost>

On Thu, Aug 13, 2015 at 03:08:46AM -0700, Tony Lindgren wrote:
> The following changes since commit ed05637c30e6d13e5793aab64d6a6e57e30228af:
> 
>   ARM: dts: omap3-devkit8000: Add ADS7846 Touchscreen support (2015-08-06 02:43:09 -0700)
> 
> are available in the git repository at:
> 
>   git://git.kernel.org/pub/scm/linux/kernel/git/tmlind/linux-omap tags/omap-for-v4.3/dt-pt4-v2
> 
> for you to fetch changes up to 8cbd4c2f6a996f6cf5dfdf8775d331606cff95bd:
> 
>   arm: boot: dts: am4372: add ARM timers and SCU nodes (2015-08-13 01:25:11 -0700)
> 
> ----------------------------------------------------------------
> Fix up bogus RTC compatible change for am4372 and add missing
> DPLL for am4372 cpsw Ethernet driver. Also add ARM global and
> local timers for am4372.
> 

Merged, thanks!


-Olof



From olof at lixom.net  Tue Aug 18 14:49:30 2015
From: olof at lixom.net (Olof Johansson)
Date: Tue, 18 Aug 2015 23:49:30 +0200
Subject: [GIT PULL] at91: defconfig for 4.3 #2
In-Reply-To: <20150814092237.3551c03e@canb.auug.org.au>
References: <20150807162754.GA20169@piout.net>
 <20150813100938.GN30160@localhost>
 <20150813112118.GA22269@piout.net>
 <20150813122643.GA23581@localhost>
 <20150814092237.3551c03e@canb.auug.org.au>
Message-ID: <CAOesGMhwAYUAMLyT6TH38-0VmZNLEpcd_=Tq=EF1KJ=eywBmUw@mail.gmail.com>

Hi Stephen,

On Fri, Aug 14, 2015 at 1:22 AM, Stephen Rothwell <sfr at canb.auug.org.au> wrote:
> Hi Olof,
>
> On Thu, 13 Aug 2015 14:26:43 +0200 Olof Johansson <olof at lixom.net> wrote:
>>
>> On Thu, Aug 13, 2015 at 01:21:18PM +0200, Alexandre Belloni wrote:
>> > On 13/08/2015 at 12:09:38 +0200, Olof Johansson wrote :
>> > > On Fri, Aug 07, 2015 at 06:27:54PM +0200, Alexandre Belloni wrote:
>> > > >
>> > > > A little defconfig update. That will probably be all for this cycle.
>> > > >
>> > > > Thanks, bye,
>> > > >
>> > > >
>> > > > The following changes since commit eff7f41572a645bf14a96a6f844be4f1c88cd9dd:
>> > > >
>> > > >   ARM: at91: at91_dt_defconfig: enable ISI and ov2640 support (2015-07-30 14:17:31 +0200)
>> > > >
>> > > > are available in the git repository at:
>> > > >
>> > > >   git://git.kernel.org/pub/scm/linux/kernel/git/abelloni/linux.git tags/at91-ab-defconfig2
>> > > >
>> > > > for you to fetch changes up to ea7bf603fd494391acc1f42acbfc34260b965c44:
>> > > >
>> > > >   ARM: at91/defconfig: at91_dt: remove ARM_AT91_ETHER (2015-08-07 12:07:50 +0200)
>> > >
>> > > Nicolas had sent me one patch which you've also included here but it's not in
>> > > the pull request ("enable ISI and ov2640 support"). That caused a conflict
>> > > here, so to avoid having the patch in the tree twice I instead also directly
>> > > applied your patches from this branch instead of merging.
>> > >
>> > > Sorry about that, it started due to Nicolas sending the discrete patch to us.
>> > > So it seems like we'll apply at91 defconfig updates directly this release, in
>> > > case there are any more. No big deal I hope. :)
>> >
>> > That's not a big deal and there will most probably be all for that cycle
>> > anyway.
>> >
>> > However, I'm wondering how I should have done. From the PR, if you get
>> > eff7f41572a645bf14a96a6f844be4f1c88cd9dd..tags/at91-ab-defconfig2, it
>> > correctly excludes "enable ISI and ov2640 support" so I was thinking it
>> > was fine.
>> > Be cause the first patch was taken as a patch, should I have prepared a
>> > branch without it?
>>
>> Yeah, you could have applied the other two if there were no conflicts. If there
>> were conflicts then it gets complicated, and the best answer would probably
>> have been to continue applying directly as patches.
>>
>> This is the drawback of us sometimes applying patches directly -- when we do,
>> we no longer put them on a branch of their own that you can use as base. We
>> used to once upon a time but it is quite a bit of overhead for us and the
>> upside was pretty limited.
>
> The only thing now is that since the at91 tree is in linux-next as well
> as the arm-soc tree, those patches appear twice there and there is a
> conflict (easy to fix, but a pain).  The solution here is to update the
> at91 tree to be somewhere in the arm-soc tree (probably just reset to
> the point where the two trees match in patches but not commits).  This
> has the downside that the at91 tree will be rebased which will affect
> any development work that is based on that.
>
> If there was just one patch in common, it maybe have been better to
> just merge the at91 tree and fix the conflict in the merge.

Yeah, this is a somewhat frustrating situation for us. I wonder if we
should essentially tag the downstream ARM platform trees in -next such
that if they conflict with arm-soc, you can drop them for a day if
needed.

It's really useful for us to be able to occasionally adjust a pull
request instead of always merging them exactly as they're presented to
us. It saves a roundtrip to the maintainer for trivial stuff, we can
take care of it and not have to look at it again. We often do send it
back to the maintainers to respin, but in this particular case it
seemed appropriate to just deal with it locally for us.

The downstream users vs rebasing git trees is of course another
aspect. Here I'm mostly relying on subplatform maintainers to know
well how many people actually develop on top of their trees. I think
for most platforms it's a fairly limited use. Interesting enough, I
can't remember last time someone told me they couldn't respin a pull
request to fix something up due to downstream developers (not that we
have _all_ that many of those requests).

The other way to handle this would be to only apply patches directly
and not do merges. Most other high-volume maintainers have exactly
this workflow. We've been able to avoid reverting to that, thankfully
(since we can delegate most of the reviews and patch applications this
way).


-Olof


From eric at anholt.net  Tue Aug 18 14:54:03 2015
From: eric at anholt.net (Eric Anholt)
Date: Tue, 18 Aug 2015 14:54:03 -0700
Subject: [PATCH v2 2/7] MAINTAINERS: Add myself for the new VC4 (RPi GPU)
 graphics driver.
In-Reply-To: <1439934848-7196-1-git-send-email-eric@anholt.net>
References: <1439934848-7196-1-git-send-email-eric@anholt.net>
Message-ID: <1439934848-7196-3-git-send-email-eric@anholt.net>

Signed-off-by: Eric Anholt <eric at anholt.net>
---

v2: Mark it Supported, not Maintained.

 MAINTAINERS | 6 ++++++
 1 file changed, 6 insertions(+)

diff --git a/MAINTAINERS b/MAINTAINERS
index 9c9dd5f..5292087 100644
--- a/MAINTAINERS
+++ b/MAINTAINERS
@@ -3592,6 +3592,12 @@ S:	Maintained
 F:	drivers/gpu/drm/rockchip/
 F:	Documentation/devicetree/bindings/video/rockchip*
 
+DRM DRIVERS FOR VC4
+M:	Eric Anholt <eric at anholt.net>
+T:	git git://github.com/anholt/linux
+S:	Supported
+F:	drivers/gpu/drm/vc4/*
+
 DSBR100 USB FM RADIO DRIVER
 M:	Alexey Klimov <klimov.linux at gmail.com>
 L:	linux-media at vger.kernel.org
-- 
2.1.4



From eric at anholt.net  Tue Aug 18 14:54:01 2015
From: eric at anholt.net (Eric Anholt)
Date: Tue, 18 Aug 2015 14:54:01 -0700
Subject: Raspberry Pi KMS-only driver V2
Message-ID: <1439934848-7196-1-git-send-email-eric@anholt.net>

Here's a respin of the RPi KMS series, taking a bunch of review
feedback into account.  It's also rebased on danvet's drm-misc now,
which cut some stub code.  The new series can still be found at:

https://github.com/anholt/linux/tree/vc4-kms-squash



From eric at anholt.net  Tue Aug 18 14:54:02 2015
From: eric at anholt.net (Eric Anholt)
Date: Tue, 18 Aug 2015 14:54:02 -0700
Subject: [PATCH v2 1/7] drm/vc4: Add devicetree bindings for VC4.
In-Reply-To: <1439934848-7196-1-git-send-email-eric@anholt.net>
References: <1439934848-7196-1-git-send-email-eric@anholt.net>
Message-ID: <1439934848-7196-2-git-send-email-eric@anholt.net>

VC4 is the GPU (display and 3D) subsystem present on the 2835 and some
other Broadcom SoCs.

This binding follows the model of msm, imx, sti, and others, where
there is a subsystem node for the whole GPU, with nodes for the
individual HW components within it.

Signed-off-by: Eric Anholt <eric at anholt.net>
---

v2: Extend the commit message, fix several nits from Stephen Warren.

 .../devicetree/bindings/gpu/brcm,bcm-vc4.txt       | 79 ++++++++++++++++++++++
 1 file changed, 79 insertions(+)
 create mode 100644 Documentation/devicetree/bindings/gpu/brcm,bcm-vc4.txt

diff --git a/Documentation/devicetree/bindings/gpu/brcm,bcm-vc4.txt b/Documentation/devicetree/bindings/gpu/brcm,bcm-vc4.txt
new file mode 100644
index 0000000..1b9fedc
--- /dev/null
+++ b/Documentation/devicetree/bindings/gpu/brcm,bcm-vc4.txt
@@ -0,0 +1,79 @@
+Broadcom VC4 GPU
+
+The VC4 device present on the Raspberry Pi includes a display system
+with HDMI output and the HVS scaler for compositing display planes.
+
+Required properties for VC4:
+- compatible:	Should be "brcm,vc4"
+- crtcs:	List of phandles of pixelvalve scanout engines
+- hvss:		List of phandles of HVS video scalers
+- encoders:	List of phandles of output encoders (HDMI, SDTV)
+
+Required properties for Pixel Valve:
+- compatible:	Should be "brcm,vc4-pixelvalve"
+- reg:		Physical base address and length of the PV's registers
+- interrupts:	The interrupt number
+		  See bindings/interrupt-controller/brcm,bcm2835-armctrl-ic.txt
+
+Required properties for HVS:
+- compatible:	Should be "brcm,vc4-hvs"
+- reg:		Physical base address and length of the HVS's registers
+- interrupts:	The interrupt number
+		  See bindings/interrupt-controller/brcm,bcm2835-armctrl-ic.txt
+
+Required properties for HDMI
+- compatible:	Should be "brcm,vc4-hdmi"
+- reg:		Physical base address and length of the two register ranges
+		  ("HDMI" and "HD", in that order)
+- interrupts:	The interrupt numbers
+		  See bindings/interrupt-controller/brcm,bcm2835-armctrl-ic.txt
+- ddc:		phandle of the I2C controller used for DDC EDID probing
+- crtc:		phandle to the pixelvalve CRTC the HDMI encoder is attached to
+
+Optional properties for HDMI:
+- hpd-gpio:	The GPIO pin for HDMI hotplug detect (if it doesn't appear
+		  as an interrupt/status bit in the HDMI controller
+		  itself).  See bindings/pinctrl/brcm,bcm2835-gpio.txt
+
+Example:
+pv0: brcm,vc4-pixelvalve at 7e206000 {
+	compatible = "brcm,vc4-pixelvalve";
+	reg = <0x7e206000 0x100>;
+	interrupts = <2 13>; /* pwa2 */
+};
+
+pv1: brcm,vc4-pixelvalve at 7e207000 {
+	compatible = "brcm,vc4-pixelvalve";
+	reg = <0x7e207000 0x100>;
+	interrupts = <2 14>; /* pwa1 */
+};
+
+pv2: brcm,vc4-pixelvalve at 7e807000 {
+	compatible = "brcm,vc4-pixelvalve";
+	reg = <0x7e807000 0x100>;
+	interrupts = <2 10>; /* pixelvalve */
+};
+
+hvs: brcm,hvs at 7e400000 {
+	compatible = "brcm,vc4-hvs";
+	reg = <0x7e400000 0x6000>;
+	interrupts = <2 1>;
+};
+
+hdmi: brcm,vc4-hdmi at 7e902000 {
+	compatible = "brcm,vc4-hdmi";
+	reg = <0x7e902000 0x600>,
+	      <0x7e808000 0x100>;
+	interrupts = <2 8>, <2 9>;
+	ddc = <&i2c2>;
+	hpd-gpio = <&gpio 46 GPIO_ACTIVE_HIGH>;
+	crtc = <&pv2>;
+};
+
+vc4: vc4 at 0x7e4c0000 {
+	compatible = "brcm,vc4";
+
+	crtcs = <&pv0>, <&pv1>, <&pv2>;
+	encoders = <&hdmi>;
+	hvss = <&hvs>;
+};
-- 
2.1.4



From olof at lixom.net  Tue Aug 18 13:18:00 2015
From: olof at lixom.net (Olof Johansson)
Date: Tue, 18 Aug 2015 13:18:00 -0700
Subject: [PATCH 1/2] ARM: dts: vexpress: Use assigned-clock-parents for
 sp810
In-Reply-To: <1439343411-29168-1-git-send-email-sboyd@codeaurora.org>
References: <1439343411-29168-1-git-send-email-sboyd@codeaurora.org>
Message-ID: <20150818201800.GD4732@localhost>

On Tue, Aug 11, 2015 at 06:36:50PM -0700, Stephen Boyd wrote:
> The sp810 clk driver is calling the clk consumer APIs from
> clk_prepare ops to change the parent to a 1 MHz fixed rate clock
> for each of the clocks that the driver provides. Use
> assigned-clock-parents for this instead of doing it in the driver
> to avoid using the consumer API in provider code. This also
> allows us to remove the usage of clk provider APIs that take a
> struct clk as an argument from the sp810 driver.
> 
> Cc: Pawel Moll <pawel.moll at arm.com>
> Cc: Linus Walleij <linus.walleij at linaro.org>
> Tested-by: Sudeep Holla <sudeep.holla at arm.com>
> Signed-off-by: Stephen Boyd <sboyd at codeaurora.org>
> ---
> 
> This came out of a larger series to change this binding[1]. This
> patch can go through arm-soc independently though, so please apply.

Applied, thanks.


-Olof


From eric at anholt.net  Tue Aug 18 14:54:07 2015
From: eric at anholt.net (Eric Anholt)
Date: Tue, 18 Aug 2015 14:54:07 -0700
Subject: [PATCH v2 6/7] ARM: bcm2835: Add the DDC I2C controller to the device
 tree.
In-Reply-To: <1439934848-7196-1-git-send-email-eric@anholt.net>
References: <1439934848-7196-1-git-send-email-eric@anholt.net>
Message-ID: <1439934848-7196-7-git-send-email-eric@anholt.net>

We need to use it for getting video modes over HDMI.

Signed-off-by: Eric Anholt <eric at anholt.net>
---

v2: Mark it as disabled by default, and enable it in bcm2835-rpi.

 arch/arm/boot/dts/bcm2835-rpi.dtsi |  4 ++++
 arch/arm/boot/dts/bcm2835.dtsi     | 10 ++++++++++
 2 files changed, 14 insertions(+)

diff --git a/arch/arm/boot/dts/bcm2835-rpi.dtsi b/arch/arm/boot/dts/bcm2835-rpi.dtsi
index 46780bb..29cc7ba 100644
--- a/arch/arm/boot/dts/bcm2835-rpi.dtsi
+++ b/arch/arm/boot/dts/bcm2835-rpi.dtsi
@@ -45,6 +45,10 @@
 	clock-frequency = <100000>;
 };
 
+&i2c2 {
+	status = "okay";
+};
+
 &sdhci {
 	status = "okay";
 	bus-width = <4>;
diff --git a/arch/arm/boot/dts/bcm2835.dtsi b/arch/arm/boot/dts/bcm2835.dtsi
index 301c73f..20574cc 100644
--- a/arch/arm/boot/dts/bcm2835.dtsi
+++ b/arch/arm/boot/dts/bcm2835.dtsi
@@ -149,6 +149,16 @@
 			status = "disabled";
 		};
 
+		i2c2: i2c at 7e805000 {
+			compatible = "brcm,bcm2835-i2c";
+			reg = <0x7e805000 0x1000>;
+			interrupts = <2 21>;
+			clocks = <&clk_i2c>;
+			#address-cells = <1>;
+			#size-cells = <0>;
+			status = "disabled";
+		};
+
 		usb at 7e980000 {
 			compatible = "brcm,bcm2835-usb";
 			reg = <0x7e980000 0x10000>;
-- 
2.1.4



From eric at anholt.net  Tue Aug 18 14:54:08 2015
From: eric at anholt.net (Eric Anholt)
Date: Tue, 18 Aug 2015 14:54:08 -0700
Subject: [PATCH v2 7/7] ARM: bcm2835: Add VC4 to the device tree.
In-Reply-To: <1439934848-7196-1-git-send-email-eric@anholt.net>
References: <1439934848-7196-1-git-send-email-eric@anholt.net>
Message-ID: <1439934848-7196-8-git-send-email-eric@anholt.net>

VC4 is the GPU (display and 3D) present on the 2835.

Signed-off-by: Eric Anholt <eric at anholt.net>
---

v2: Sort by register address, mark HDMI as disabled by default in the
    SoC file and enable it from -rpi.

 arch/arm/boot/dts/bcm2835-rpi.dtsi |  4 ++++
 arch/arm/boot/dts/bcm2835.dtsi     | 44 ++++++++++++++++++++++++++++++++++++++
 2 files changed, 48 insertions(+)

diff --git a/arch/arm/boot/dts/bcm2835-rpi.dtsi b/arch/arm/boot/dts/bcm2835-rpi.dtsi
index 29cc7ba..f7217906 100644
--- a/arch/arm/boot/dts/bcm2835-rpi.dtsi
+++ b/arch/arm/boot/dts/bcm2835-rpi.dtsi
@@ -49,6 +49,10 @@
 	status = "okay";
 };
 
+&hdmi {
+	status = "okay";
+};
+
 &sdhci {
 	status = "okay";
 	bus-width = <4>;
diff --git a/arch/arm/boot/dts/bcm2835.dtsi b/arch/arm/boot/dts/bcm2835.dtsi
index 20574cc..e625a21 100644
--- a/arch/arm/boot/dts/bcm2835.dtsi
+++ b/arch/arm/boot/dts/bcm2835.dtsi
@@ -1,4 +1,5 @@
 #include <dt-bindings/pinctrl/bcm2835.h>
+#include <dt-bindings/gpio/gpio.h>
 #include "skeleton.dtsi"
 
 / {
@@ -131,6 +132,18 @@
 			status = "disabled";
 		};
 
+		pv0: brcm,vc4-pixelvalve at 7e206000 {
+			compatible = "brcm,vc4-pixelvalve";
+			reg = <0x7e206000 0x100>;
+			interrupts = <2 13>; /* pwa2 */
+		};
+
+		pv1: brcm,vc4-pixelvalve at 7e207000 {
+			compatible = "brcm,vc4-pixelvalve";
+			reg = <0x7e207000 0x100>;
+			interrupts = <2 14>; /* pwa1 */
+		};
+
 		sdhci: sdhci at 7e300000 {
 			compatible = "brcm,bcm2835-sdhci";
 			reg = <0x7e300000 0x100>;
@@ -139,6 +152,12 @@
 			status = "disabled";
 		};
 
+		hvs: brcm,hvs at 7e400000 {
+			compatible = "brcm,vc4-hvs";
+			reg = <0x7e400000 0x6000>;
+			interrupts = <2 1>;
+		};
+
 		i2c1: i2c at 7e804000 {
 			compatible = "brcm,bcm2835-i2c";
 			reg = <0x7e804000 0x1000>;
@@ -159,6 +178,23 @@
 			status = "disabled";
 		};
 
+		pv2: brcm,vc4-pixelvalve at 7e807000 {
+			compatible = "brcm,vc4-pixelvalve";
+			reg = <0x7e807000 0x100>;
+			interrupts = <2 10>; /* pixelvalve */
+		};
+
+		hdmi: brcm,vc4-hdmi at 7e902000 {
+			compatible = "brcm,vc4-hdmi";
+			reg = <0x7e902000 0x600>,
+			      <0x7e808000 0x100>;
+			interrupts = <2 8>, <2 9>;
+			ddc = <&i2c2>;
+			hpd-gpio = <&gpio 46 GPIO_ACTIVE_HIGH>;
+			crtc = <&pv2>;
+			status = "disabled";
+		};
+
 		usb at 7e980000 {
 			compatible = "brcm,bcm2835-usb";
 			reg = <0x7e980000 0x10000>;
@@ -168,6 +204,14 @@
 		arm-pmu {
 			compatible = "arm,arm1176-pmu";
 		};
+
+		vc4: vc4 at 0x7e4c0000 {
+			compatible = "brcm,vc4";
+
+			crtcs = <&pv0>, <&pv1>, <&pv2>;
+			encoders = <&hdmi>;
+			hvss = <&hvs>;
+		};
 	};
 
 	clocks {
-- 
2.1.4



From eric at anholt.net  Tue Aug 18 14:54:06 2015
From: eric at anholt.net (Eric Anholt)
Date: Tue, 18 Aug 2015 14:54:06 -0700
Subject: [PATCH v2 5/7] drm/vc4: Allow vblank to be disabled
In-Reply-To: <1439934848-7196-1-git-send-email-eric@anholt.net>
References: <1439934848-7196-1-git-send-email-eric@anholt.net>
Message-ID: <1439934848-7196-6-git-send-email-eric@anholt.net>

From: Derek Foreman <derekf at osg.samsung.com>

Signed-off-by: Derek Foreman <derekf at osg.samsung.com>
Signed-off-by: Eric Anholt <eric at anholt.net>
---
 drivers/gpu/drm/vc4/vc4_kms.c | 2 ++
 1 file changed, 2 insertions(+)

diff --git a/drivers/gpu/drm/vc4/vc4_kms.c b/drivers/gpu/drm/vc4/vc4_kms.c
index a34439f..f881cd4 100644
--- a/drivers/gpu/drm/vc4/vc4_kms.c
+++ b/drivers/gpu/drm/vc4/vc4_kms.c
@@ -77,6 +77,8 @@ int vc4_kms_load(struct drm_device *dev)
 	dev->mode_config.funcs = &vc4_mode_funcs;
 	dev->mode_config.preferred_depth = 24;
 
+	dev->vblank_disable_allowed = true;
+
 	ret = vc4_init_modeset_objects(dev);
 	if (ret)
 		goto fail;
-- 
2.1.4



From eric at anholt.net  Tue Aug 18 14:54:05 2015
From: eric at anholt.net (Eric Anholt)
Date: Tue, 18 Aug 2015 14:54:05 -0700
Subject: [PATCH v2 4/7] drm/vc4: Use the fbdev_cma helpers
In-Reply-To: <1439934848-7196-1-git-send-email-eric@anholt.net>
References: <1439934848-7196-1-git-send-email-eric@anholt.net>
Message-ID: <1439934848-7196-5-git-send-email-eric@anholt.net>

From: Derek Foreman <derekf at osg.samsung.com>

Keep the fbdev_cma pointer around so we can use it on hotplog and close
to ensure the frame buffer console is in a useful state.

Signed-off-by: Derek Foreman <derekf at osg.samsung.com>
Signed-off-by: Eric Anholt <eric at anholt.net>
---
 drivers/gpu/drm/vc4/vc4_drv.c | 14 ++++++++++++++
 drivers/gpu/drm/vc4/vc4_drv.h |  2 ++
 drivers/gpu/drm/vc4/vc4_kms.c | 18 +++++++++++++++---
 3 files changed, 31 insertions(+), 3 deletions(-)

diff --git a/drivers/gpu/drm/vc4/vc4_drv.c b/drivers/gpu/drm/vc4/vc4_drv.c
index d30aefa..8ebd238 100644
--- a/drivers/gpu/drm/vc4/vc4_drv.c
+++ b/drivers/gpu/drm/vc4/vc4_drv.c
@@ -14,6 +14,7 @@
 #include <linux/module.h>
 #include <linux/of_platform.h>
 #include <linux/platform_device.h>
+#include "drm_fb_cma_helper.h"
 
 #include "vc4_drv.h"
 #include "vc4_regs.h"
@@ -49,6 +50,14 @@ static void vc4_drm_preclose(struct drm_device *dev, struct drm_file *file)
 		vc4_cancel_page_flip(crtc, file);
 }
 
+static void vc4_lastclose(struct drm_device *dev)
+{
+	struct vc4_dev *vc4 = to_vc4_dev(dev);
+
+	if (vc4->fbdev)
+		drm_fbdev_cma_restore_mode(vc4->fbdev);
+}
+
 static const struct file_operations vc4_drm_fops = {
 	.owner = THIS_MODULE,
 	.open = drm_open,
@@ -71,6 +80,7 @@ static struct drm_driver vc4_drm_driver = {
 			    DRIVER_ATOMIC |
 			    DRIVER_GEM |
 			    DRIVER_PRIME),
+	.lastclose = vc4_lastclose,
 	.preclose = vc4_drm_preclose,
 
 	.enable_vblank = vc4_enable_vblank,
@@ -161,6 +171,10 @@ static void vc4_drm_unbind(struct device *dev)
 {
 	struct platform_device *pdev = to_platform_device(dev);
 	struct drm_device *drm = platform_get_drvdata(pdev);
+	struct vc4_dev *vc4 = to_vc4_dev(drm);
+
+	if (vc4->fbdev)
+		drm_fbdev_cma_fini(vc4->fbdev);
 
 	drm_mode_config_cleanup(drm);
 
diff --git a/drivers/gpu/drm/vc4/vc4_drv.h b/drivers/gpu/drm/vc4/vc4_drv.h
index 282ce0b..24a1cb5 100644
--- a/drivers/gpu/drm/vc4/vc4_drv.h
+++ b/drivers/gpu/drm/vc4/vc4_drv.h
@@ -15,6 +15,8 @@ struct vc4_dev {
 	struct vc4_hdmi *hdmi;
 	struct vc4_hvs *hvs;
 	struct vc4_crtc *crtc[3];
+
+	struct drm_fbdev_cma *fbdev;
 };
 
 static inline struct vc4_dev *
diff --git a/drivers/gpu/drm/vc4/vc4_kms.c b/drivers/gpu/drm/vc4/vc4_kms.c
index e5e96bc..a34439f 100644
--- a/drivers/gpu/drm/vc4/vc4_kms.c
+++ b/drivers/gpu/drm/vc4/vc4_kms.c
@@ -21,7 +21,16 @@
 #include "drm_fb_cma_helper.h"
 #include "vc4_drv.h"
 
+static void vc4_output_poll_changed(struct drm_device *dev)
+{
+	struct vc4_dev *vc4 = to_vc4_dev(dev);
+
+	if (vc4->fbdev)
+		drm_fbdev_cma_hotplug_event(vc4->fbdev);
+}
+
 static const struct drm_mode_config_funcs vc4_mode_funcs = {
+	.output_poll_changed = vc4_output_poll_changed,
 	.atomic_check = drm_atomic_helper_check,
 	.atomic_commit = drm_atomic_helper_commit,
 	.fb_create = drm_fb_cma_create,
@@ -54,6 +63,7 @@ fail:
 
 int vc4_kms_load(struct drm_device *dev)
 {
+	struct vc4_dev *vc4 = to_vc4_dev(dev);
 	int ret;
 
 	ret = drm_vblank_init(dev, dev->mode_config.num_crtc);
@@ -73,9 +83,11 @@ int vc4_kms_load(struct drm_device *dev)
 
 	drm_mode_config_reset(dev);
 
-	drm_fbdev_cma_init(dev, 32,
-			   dev->mode_config.num_crtc,
-			   dev->mode_config.num_connector);
+	vc4->fbdev = drm_fbdev_cma_init(dev, 32,
+					dev->mode_config.num_crtc,
+					dev->mode_config.num_connector);
+	if (IS_ERR(vc4->fbdev))
+		vc4->fbdev = NULL;
 
 	drm_kms_helper_poll_init(dev);
 
-- 
2.1.4



From eric at anholt.net  Tue Aug 18 14:54:04 2015
From: eric at anholt.net (Eric Anholt)
Date: Tue, 18 Aug 2015 14:54:04 -0700
Subject: [PATCH v2 3/7] drm/vc4: Add KMS support for Raspberry Pi.
In-Reply-To: <1439934848-7196-1-git-send-email-eric@anholt.net>
References: <1439934848-7196-1-git-send-email-eric@anholt.net>
Message-ID: <1439934848-7196-4-git-send-email-eric@anholt.net>

This is the start of a full VC4 driver.  Right now this just supports
configuring the display using a pre-existing video mode (because
changing the pixel clock isn't available yet, and doesn't work when it
is).  However, this is enough for fbcon and bringing up X using
xf86-video-modesetting.

Signed-off-by: Eric Anholt <eric at anholt.net>
---

v2: Drop FB_HELPER select thanks to Archit's patches.  Do manual init
    ordering instead of using the .load hook.  Structure registration
    more like tegra's, but still using the typical "component" code.
    Drop no-op hooks for atomic_begin and mode_fixup() now that
    they're optional.  Drop sentinel in Makefile.  Fix minor style
    nits I noticed on another reread.

 drivers/gpu/drm/Kconfig           |   2 +
 drivers/gpu/drm/Makefile          |   1 +
 drivers/gpu/drm/vc4/Kconfig       |  13 +
 drivers/gpu/drm/vc4/Makefile      |  17 +
 drivers/gpu/drm/vc4/vc4_bo.c      |  52 ++++
 drivers/gpu/drm/vc4/vc4_crtc.c    | 565 ++++++++++++++++++++++++++++++++++
 drivers/gpu/drm/vc4/vc4_debugfs.c |  38 +++
 drivers/gpu/drm/vc4/vc4_drv.c     | 271 ++++++++++++++++
 drivers/gpu/drm/vc4/vc4_drv.h     | 120 ++++++++
 drivers/gpu/drm/vc4/vc4_hdmi.c    | 633 ++++++++++++++++++++++++++++++++++++++
 drivers/gpu/drm/vc4/vc4_hvs.c     | 161 ++++++++++
 drivers/gpu/drm/vc4/vc4_kms.c     |  84 +++++
 drivers/gpu/drm/vc4/vc4_plane.c   | 320 +++++++++++++++++++
 drivers/gpu/drm/vc4/vc4_regs.h    | 562 +++++++++++++++++++++++++++++++++
 14 files changed, 2839 insertions(+)
 create mode 100644 drivers/gpu/drm/vc4/Kconfig
 create mode 100644 drivers/gpu/drm/vc4/Makefile
 create mode 100644 drivers/gpu/drm/vc4/vc4_bo.c
 create mode 100644 drivers/gpu/drm/vc4/vc4_crtc.c
 create mode 100644 drivers/gpu/drm/vc4/vc4_debugfs.c
 create mode 100644 drivers/gpu/drm/vc4/vc4_drv.c
 create mode 100644 drivers/gpu/drm/vc4/vc4_drv.h
 create mode 100644 drivers/gpu/drm/vc4/vc4_hdmi.c
 create mode 100644 drivers/gpu/drm/vc4/vc4_hvs.c
 create mode 100644 drivers/gpu/drm/vc4/vc4_kms.c
 create mode 100644 drivers/gpu/drm/vc4/vc4_plane.c
 create mode 100644 drivers/gpu/drm/vc4/vc4_regs.h

diff --git a/drivers/gpu/drm/Kconfig b/drivers/gpu/drm/Kconfig
index 06ae500..19bb0db 100644
--- a/drivers/gpu/drm/Kconfig
+++ b/drivers/gpu/drm/Kconfig
@@ -260,3 +260,5 @@ source "drivers/gpu/drm/sti/Kconfig"
 source "drivers/gpu/drm/amd/amdkfd/Kconfig"
 
 source "drivers/gpu/drm/imx/Kconfig"
+
+source "drivers/gpu/drm/vc4/Kconfig"
diff --git a/drivers/gpu/drm/Makefile b/drivers/gpu/drm/Makefile
index 8858510..283ed8e 100644
--- a/drivers/gpu/drm/Makefile
+++ b/drivers/gpu/drm/Makefile
@@ -42,6 +42,7 @@ obj-$(CONFIG_DRM_MGA)	+= mga/
 obj-$(CONFIG_DRM_I810)	+= i810/
 obj-$(CONFIG_DRM_I915)  += i915/
 obj-$(CONFIG_DRM_MGAG200) += mgag200/
+obj-$(CONFIG_DRM_VC4)  += vc4/
 obj-$(CONFIG_DRM_CIRRUS_QEMU) += cirrus/
 obj-$(CONFIG_DRM_SIS)   += sis/
 obj-$(CONFIG_DRM_SAVAGE)+= savage/
diff --git a/drivers/gpu/drm/vc4/Kconfig b/drivers/gpu/drm/vc4/Kconfig
new file mode 100644
index 0000000..e810ef7
--- /dev/null
+++ b/drivers/gpu/drm/vc4/Kconfig
@@ -0,0 +1,13 @@
+config DRM_VC4
+	tristate "Broadcom VC4 Graphics"
+	depends on ARCH_BCM2835
+	depends on DRM
+	select DRM_KMS_HELPER
+	select DRM_KMS_CMA_HELPER
+	help
+	  Choose this option if you have a system that has a Broadcom
+	  VC4 GPU, such as the Raspberry Pi or other BCM2708/BCM2835.
+
+	  This driver requires that "avoid_warnings=2" be present in
+	  the config.txt for the firmware, to keep it from smashing
+	  our display setup.
diff --git a/drivers/gpu/drm/vc4/Makefile b/drivers/gpu/drm/vc4/Makefile
new file mode 100644
index 0000000..32b4f9c
--- /dev/null
+++ b/drivers/gpu/drm/vc4/Makefile
@@ -0,0 +1,17 @@
+ccflags-y := -Iinclude/drm
+
+# Please keep these build lists sorted!
+
+# core driver code
+vc4-y := \
+	vc4_bo.o \
+	vc4_crtc.o \
+	vc4_drv.o \
+	vc4_kms.o \
+	vc4_hdmi.o \
+	vc4_hvs.o \
+	vc4_plane.o
+
+vc4-$(CONFIG_DEBUG_FS) += vc4_debugfs.o
+
+obj-$(CONFIG_DRM_VC4)  += vc4.o
diff --git a/drivers/gpu/drm/vc4/vc4_bo.c b/drivers/gpu/drm/vc4/vc4_bo.c
new file mode 100644
index 0000000..ab9f510
--- /dev/null
+++ b/drivers/gpu/drm/vc4/vc4_bo.c
@@ -0,0 +1,52 @@
+/*
+ *  Copyright ? 2015 Broadcom
+ *
+ * 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.
+ */
+
+/* DOC: VC4 GEM BO management support.
+ *
+ * The VC4 GPU architecture (both scanout and rendering) has direct
+ * access to system memory with no MMU in between.  To support it, we
+ * use the GEM CMA helper functions to allocate contiguous ranges of
+ * physical memory for our BOs.
+ */
+
+#include "vc4_drv.h"
+
+struct vc4_bo *vc4_bo_create(struct drm_device *dev, size_t size)
+{
+	struct drm_gem_cma_object *cma_obj;
+
+	cma_obj = drm_gem_cma_create(dev, size);
+	if (IS_ERR(cma_obj))
+		return NULL;
+	else
+		return to_vc4_bo(&cma_obj->base);
+}
+
+int vc4_dumb_create(struct drm_file *file_priv,
+		    struct drm_device *dev,
+		    struct drm_mode_create_dumb *args)
+{
+	int min_pitch = DIV_ROUND_UP(args->width * args->bpp, 8);
+	struct vc4_bo *bo = NULL;
+	int ret;
+
+	if (args->pitch < min_pitch)
+		args->pitch = min_pitch;
+
+	if (args->size < args->pitch * args->height)
+		args->size = args->pitch * args->height;
+
+	bo = vc4_bo_create(dev, roundup(args->size, PAGE_SIZE));
+	if (!bo)
+		return -ENOMEM;
+
+	ret = drm_gem_handle_create(file_priv, &bo->base.base, &args->handle);
+	drm_gem_object_unreference_unlocked(&bo->base.base);
+
+	return ret;
+}
diff --git a/drivers/gpu/drm/vc4/vc4_crtc.c b/drivers/gpu/drm/vc4/vc4_crtc.c
new file mode 100644
index 0000000..2c70faf
--- /dev/null
+++ b/drivers/gpu/drm/vc4/vc4_crtc.c
@@ -0,0 +1,565 @@
+/*
+ * Copyright (C) 2015 Broadcom
+ *
+ * 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.
+ */
+
+/**
+ * DOC: VC4 CRTC module
+ *
+ * In VC4, the Pixel Valve is what most closely corresponds to the
+ * DRM's concept of a CRTC.  The PV generates video timings from the
+ * pixel clock and its configuration.
+ *
+ * However, the DRM CRTC also collects the configuration of all the
+ * DRM planes attached to it.  As a result, this file also manages
+ * setup of the VC4 HVS's display elements on the CRTC.
+ */
+
+#include "drm_atomic_helper.h"
+#include "drm_crtc_helper.h"
+#include "linux/clk.h"
+#include "linux/component.h"
+#include "vc4_drv.h"
+#include "vc4_regs.h"
+
+#define CRTC_WRITE(offset, val) writel(val, vc4_crtc->regs + (offset))
+#define CRTC_READ(offset) readl(vc4_crtc->regs + (offset))
+
+#define CRTC_REG(reg) { reg, #reg }
+static const struct {
+	u32 reg;
+	const char *name;
+} crtc_regs[] = {
+	CRTC_REG(PV_CONTROL),
+	CRTC_REG(PV_V_CONTROL),
+	CRTC_REG(PV_VSYNCD),
+	CRTC_REG(PV_HORZA),
+	CRTC_REG(PV_HORZB),
+	CRTC_REG(PV_VERTA),
+	CRTC_REG(PV_VERTB),
+	CRTC_REG(PV_VERTA_EVEN),
+	CRTC_REG(PV_VERTB_EVEN),
+	CRTC_REG(PV_INTEN),
+	CRTC_REG(PV_INTSTAT),
+	CRTC_REG(PV_STAT),
+	CRTC_REG(PV_HACT_ACT),
+};
+
+static void vc4_crtc_dump_regs(struct vc4_crtc *vc4_crtc)
+{
+	int i;
+
+	for (i = 0; i < ARRAY_SIZE(crtc_regs); i++) {
+		DRM_INFO("0x%04x (%s): 0x%08x\n",
+			 crtc_regs[i].reg, crtc_regs[i].name,
+			 CRTC_READ(crtc_regs[i].reg));
+	}
+}
+
+#ifdef CONFIG_DEBUG_FS
+int vc4_crtc_debugfs_regs(struct seq_file *m, void *unused)
+{
+	struct drm_info_node *node = (struct drm_info_node *) m->private;
+	struct drm_device *dev = node->minor->dev;
+	int crtc_index = (uintptr_t)node->info_ent->data;
+	struct drm_crtc *crtc;
+	struct vc4_crtc *vc4_crtc;
+	int i;
+
+	i = 0;
+	list_for_each_entry(crtc, &dev->mode_config.crtc_list, head) {
+		if (i == crtc_index)
+			break;
+		i++;
+	}
+	if (!crtc)
+		return 0;
+	vc4_crtc = to_vc4_crtc(crtc);
+
+	for (i = 0; i < ARRAY_SIZE(crtc_regs); i++) {
+		seq_printf(m, "%s (0x%04x): 0x%08x\n",
+			   crtc_regs[i].name, crtc_regs[i].reg,
+			   CRTC_READ(crtc_regs[i].reg));
+	}
+
+	return 0;
+}
+#endif
+
+static void vc4_crtc_destroy(struct drm_crtc *crtc)
+{
+	drm_crtc_cleanup(crtc);
+}
+
+static u32 vc4_get_fifo_full_level(u32 format)
+{
+	static const u32 fifo_len_bytes = 64;
+	static const u32 hvs_latency_pix = 6;
+
+	switch (format) {
+	case PV_CONTROL_FORMAT_DSIV_16:
+	case PV_CONTROL_FORMAT_DSIC_16:
+		return fifo_len_bytes - 2 * hvs_latency_pix;
+	case PV_CONTROL_FORMAT_DSIV_18:
+		return fifo_len_bytes - 14;
+	case PV_CONTROL_FORMAT_24:
+	case PV_CONTROL_FORMAT_DSIV_24:
+	default:
+		return fifo_len_bytes - 3 * hvs_latency_pix;
+	}
+}
+
+static void vc4_crtc_mode_set_nofb(struct drm_crtc *crtc)
+{
+	struct vc4_crtc *vc4_crtc = to_vc4_crtc(crtc);
+	struct drm_crtc_state *state = crtc->state;
+	struct drm_display_mode *mode = &state->adjusted_mode;
+	u32 vactive = (mode->vdisplay >>
+		       ((mode->flags & DRM_MODE_FLAG_INTERLACE) ? 1 : 0));
+	u32 format = PV_CONTROL_FORMAT_24;
+	bool debug_dump_regs = false;
+
+	if (debug_dump_regs) {
+		DRM_INFO("CRTC %d regs before:\n", drm_crtc_index(crtc));
+		vc4_crtc_dump_regs(vc4_crtc);
+	}
+
+	/* This is where we would set the pixel clock. */
+
+	/* Reset the PV fifo. */
+	CRTC_WRITE(PV_CONTROL, 0);
+	CRTC_WRITE(PV_CONTROL, PV_CONTROL_FIFO_CLR | PV_CONTROL_EN);
+	CRTC_WRITE(PV_CONTROL, 0);
+
+	CRTC_WRITE(PV_HORZA,
+		   VC4_SET_FIELD(mode->htotal - mode->hsync_end,
+				 PV_HORZA_HBP) |
+		   VC4_SET_FIELD(mode->hsync_end - mode->hsync_start,
+				 PV_HORZA_HSYNC));
+	CRTC_WRITE(PV_HORZB,
+		   VC4_SET_FIELD(mode->hsync_start - mode->hdisplay,
+				 PV_HORZB_HFP) |
+		   VC4_SET_FIELD(mode->hdisplay, PV_HORZB_HACTIVE));
+
+	CRTC_WRITE(PV_VERTA,
+		   VC4_SET_FIELD(mode->vtotal - mode->vsync_end,
+				 PV_VERTA_VBP) |
+		   VC4_SET_FIELD(mode->vsync_end - mode->vsync_start,
+				 PV_VERTA_VSYNC));
+	CRTC_WRITE(PV_VERTB,
+		   VC4_SET_FIELD(mode->vsync_start - mode->vdisplay,
+				 PV_VERTB_VFP) |
+		   VC4_SET_FIELD(vactive, PV_VERTB_VACTIVE));
+	if (mode->flags & DRM_MODE_FLAG_INTERLACE) {
+		/* Write PV_VERTA_EVEN/VERTB_EVEN */
+	}
+
+	CRTC_WRITE(PV_HACT_ACT, mode->hdisplay);
+
+	CRTC_WRITE(PV_V_CONTROL,
+		   PV_VCONTROL_CONTINUOUS);
+
+	CRTC_WRITE(PV_CONTROL,
+		   VC4_SET_FIELD(format, PV_CONTROL_FORMAT) |
+		   VC4_SET_FIELD(vc4_get_fifo_full_level(format),
+				 PV_CONTROL_FIFO_LEVEL) |
+		   PV_CONTROL_CLR_AT_START |
+		   PV_CONTROL_TRIGGER_UNDERFLOW |
+		   PV_CONTROL_WAIT_HSTART |
+		   VC4_SET_FIELD(PV_CONTROL_CLK_SELECT_DPI_SMI_HDMI,
+				 PV_CONTROL_CLK_SELECT) |
+		   PV_CONTROL_FIFO_CLR |
+		   PV_CONTROL_EN);
+
+	if (debug_dump_regs) {
+		DRM_INFO("CRTC %d regs after:\n", drm_crtc_index(crtc));
+		vc4_crtc_dump_regs(vc4_crtc);
+	}
+}
+
+static void require_hvs_enabled(struct drm_device *dev)
+{
+	struct vc4_dev *vc4 = to_vc4_dev(dev);
+
+	WARN_ON_ONCE((HVS_READ(SCALER_DISPCTRL) & SCALER_DISPCTRL_ENABLE) !=
+		     SCALER_DISPCTRL_ENABLE);
+}
+
+static void vc4_crtc_disable(struct drm_crtc *crtc)
+{
+	struct drm_device *dev = crtc->dev;
+	struct vc4_dev *vc4 = to_vc4_dev(dev);
+	struct vc4_crtc *vc4_crtc = to_vc4_crtc(crtc);
+
+	require_hvs_enabled(dev);
+
+	CRTC_WRITE(PV_V_CONTROL,
+		   CRTC_READ(PV_V_CONTROL) & ~PV_VCONTROL_VIDEN);
+	while (CRTC_READ(PV_V_CONTROL) & PV_VCONTROL_VIDEN)
+		cpu_relax();
+
+	/* Without a wait here, we end up with a black screen. */
+	msleep(30);
+
+	if (HVS_READ(SCALER_DISPCTRLX(vc4_crtc->channel)) &
+	    SCALER_DISPCTRLX_ENABLE) {
+		HVS_WRITE(SCALER_DISPCTRLX(vc4_crtc->channel),
+			  SCALER_DISPCTRLX_RESET);
+
+		/* While the docs say that reset is self-clearing, it
+		 * seems it doesn't actually.
+		 */
+		HVS_WRITE(SCALER_DISPCTRLX(vc4_crtc->channel), 0);
+	}
+
+	/* Once we leave, the scaler should be disabled and its fifo empty. */
+
+	WARN_ON_ONCE(HVS_READ(SCALER_DISPCTRLX(vc4_crtc->channel)) &
+		     SCALER_DISPCTRLX_RESET);
+
+	WARN_ON_ONCE(VC4_GET_FIELD(HVS_READ(SCALER_DISPSTATX(vc4_crtc->channel)),
+				   SCALER_DISPSTATX_MODE) !=
+		     SCALER_DISPSTATX_MODE_DISABLED);
+
+	WARN_ON_ONCE((HVS_READ(SCALER_DISPSTATX(vc4_crtc->channel)) &
+		      (SCALER_DISPSTATX_FULL | SCALER_DISPSTATX_EMPTY)) !=
+		     SCALER_DISPSTATX_EMPTY);
+}
+
+static void vc4_crtc_enable(struct drm_crtc *crtc)
+{
+	struct drm_device *dev = crtc->dev;
+	struct vc4_dev *vc4 = to_vc4_dev(dev);
+	struct vc4_crtc *vc4_crtc = to_vc4_crtc(crtc);
+	struct drm_crtc_state *state = crtc->state;
+	struct drm_display_mode *mode = &state->adjusted_mode;
+
+	require_hvs_enabled(dev);
+
+	/* Turn on the scaler, which will wait for vstart to start
+	 * compositing.
+	 */
+	HVS_WRITE(SCALER_DISPCTRLX(vc4_crtc->channel),
+		  VC4_SET_FIELD(mode->hdisplay, SCALER_DISPCTRLX_WIDTH) |
+		  VC4_SET_FIELD(mode->vdisplay, SCALER_DISPCTRLX_HEIGHT) |
+		  SCALER_DISPCTRLX_ENABLE);
+
+	/* Turn on the pixel valve, which will emit the vstart signal. */
+	CRTC_WRITE(PV_V_CONTROL,
+		   CRTC_READ(PV_V_CONTROL) | PV_VCONTROL_VIDEN);
+}
+
+static int vc4_crtc_atomic_check(struct drm_crtc *crtc,
+				 struct drm_crtc_state *state)
+{
+	struct drm_device *dev = crtc->dev;
+	struct vc4_dev *vc4 = to_vc4_dev(dev);
+	struct drm_plane *plane;
+	struct vc4_crtc *vc4_crtc = to_vc4_crtc(crtc);
+	u32 dlist_count = 0;
+
+	drm_atomic_crtc_state_for_each_plane(plane, state) {
+		struct drm_plane_state *plane_state =
+			state->state->plane_states[drm_plane_index(plane)];
+
+		/* plane might not have changed, in which case take
+		 * current state:
+		 */
+		if (!plane_state)
+			plane_state = plane->state;
+
+		dlist_count += vc4_plane_dlist_size(plane_state);
+	}
+
+	dlist_count++; /* Account for SCALER_CTL0_END. */
+
+	if (!vc4_crtc->dlist || dlist_count > vc4_crtc->dlist_size) {
+		vc4_crtc->dlist = ((u32 __iomem *)vc4->hvs->dlist +
+				   HVS_BOOTLOADER_DLIST_END);
+		vc4_crtc->dlist_size = ((SCALER_DLIST_SIZE >> 2) -
+					HVS_BOOTLOADER_DLIST_END);
+
+		if (dlist_count > vc4_crtc->dlist_size) {
+			DRM_DEBUG_KMS("dlist too large for CRTC (%d > %d).\n",
+				      dlist_count, vc4_crtc->dlist_size);
+			return -EINVAL;
+		}
+	}
+
+	return 0;
+}
+
+static void vc4_crtc_atomic_flush(struct drm_crtc *crtc,
+				  struct drm_crtc_state *old_state)
+{
+	struct drm_device *dev = crtc->dev;
+	struct vc4_dev *vc4 = to_vc4_dev(dev);
+	struct vc4_crtc *vc4_crtc = to_vc4_crtc(crtc);
+	struct drm_plane *plane;
+	bool debug_dump_regs = false;
+	u32 __iomem *dlist_next = vc4_crtc->dlist;
+
+	if (debug_dump_regs) {
+		DRM_INFO("CRTC %d HVS before:\n", drm_crtc_index(crtc));
+		vc4_hvs_dump_state(dev);
+	}
+
+	/* Copy all the active planes' dlist contents to the hardware dlist.
+	 *
+	 * XXX: If the new display list was large enough that it
+	 * overlapped a currently-read display list, we need to do
+	 * something like disable scanout before putting in the new
+	 * list.  For now, we're safe because we only have the two
+	 * planes.
+	 */
+	drm_atomic_crtc_for_each_plane(plane, crtc) {
+		dlist_next += vc4_plane_write_dlist(plane, dlist_next);
+	}
+
+	if (dlist_next == vc4_crtc->dlist) {
+		/* If no planes were enabled, use the SCALER_CTL0_END
+		 * at the start of the display list memory (in the
+		 * bootloader section).  We'll rewrite that
+		 * SCALER_CTL0_END, just in case, though.
+		 */
+		writel(SCALER_CTL0_END, vc4->hvs->dlist);
+		HVS_WRITE(SCALER_DISPLISTX(vc4_crtc->channel), 0);
+	} else {
+		writel(SCALER_CTL0_END, dlist_next);
+		dlist_next++;
+
+		HVS_WRITE(SCALER_DISPLISTX(vc4_crtc->channel),
+			  (u32 *)vc4_crtc->dlist - (u32 *)vc4->hvs->dlist);
+
+		/* Make the next display list start after ours. */
+		vc4_crtc->dlist_size -= (dlist_next - vc4_crtc->dlist);
+		vc4_crtc->dlist = dlist_next;
+	}
+
+	if (debug_dump_regs) {
+		DRM_INFO("CRTC %d HVS after:\n", drm_crtc_index(crtc));
+		vc4_hvs_dump_state(dev);
+	}
+
+	if (crtc->state->event) {
+		unsigned long flags;
+
+		crtc->state->event->pipe = drm_crtc_index(crtc);
+
+		WARN_ON(drm_crtc_vblank_get(crtc) != 0);
+
+		spin_lock_irqsave(&dev->event_lock, flags);
+		vc4_crtc->event = crtc->state->event;
+		spin_unlock_irqrestore(&dev->event_lock, flags);
+		crtc->state->event = NULL;
+	}
+}
+
+int vc4_enable_vblank(struct drm_device *dev, int crtc_id)
+{
+	struct vc4_dev *vc4 = to_vc4_dev(dev);
+	struct vc4_crtc *vc4_crtc = vc4->crtc[crtc_id];
+
+	CRTC_WRITE(PV_INTEN, PV_INT_VFP_START);
+
+	return 0;
+}
+
+void vc4_disable_vblank(struct drm_device *dev, int crtc_id)
+{
+	struct vc4_dev *vc4 = to_vc4_dev(dev);
+	struct vc4_crtc *vc4_crtc = vc4->crtc[crtc_id];
+
+	CRTC_WRITE(PV_INTEN, 0);
+}
+
+static void vc4_crtc_handle_page_flip(struct vc4_crtc *vc4_crtc)
+{
+	struct drm_crtc *crtc = &vc4_crtc->base;
+	struct drm_device *dev = crtc->dev;
+	unsigned long flags;
+
+	spin_lock_irqsave(&dev->event_lock, flags);
+	if (vc4_crtc->event) {
+		drm_crtc_send_vblank_event(crtc, vc4_crtc->event);
+		vc4_crtc->event = NULL;
+	}
+	spin_unlock_irqrestore(&dev->event_lock, flags);
+}
+
+static irqreturn_t vc4_crtc_irq_handler(int irq, void *data)
+{
+	struct vc4_crtc *vc4_crtc = data;
+	u32 stat = CRTC_READ(PV_INTSTAT);
+	irqreturn_t ret = IRQ_NONE;
+
+	if (stat & PV_INT_VFP_START) {
+		CRTC_WRITE(PV_INTSTAT, PV_INT_VFP_START);
+		drm_crtc_handle_vblank(&vc4_crtc->base);
+		vc4_crtc_handle_page_flip(vc4_crtc);
+		ret = IRQ_HANDLED;
+	}
+
+	return ret;
+}
+
+static const struct drm_crtc_funcs vc4_crtc_funcs = {
+	.set_config = drm_atomic_helper_set_config,
+	.destroy = vc4_crtc_destroy,
+	.page_flip = drm_atomic_helper_page_flip,
+	.set_property = NULL,
+	.cursor_set = NULL, /* handled by drm_mode_cursor_universal */
+	.cursor_move = NULL, /* handled by drm_mode_cursor_universal */
+	.reset = drm_atomic_helper_crtc_reset,
+	.atomic_duplicate_state = drm_atomic_helper_crtc_duplicate_state,
+	.atomic_destroy_state = drm_atomic_helper_crtc_destroy_state,
+};
+
+static const struct drm_crtc_helper_funcs vc4_crtc_helper_funcs = {
+	.mode_set_nofb = vc4_crtc_mode_set_nofb,
+	.disable = vc4_crtc_disable,
+	.enable = vc4_crtc_enable,
+	.atomic_check = vc4_crtc_atomic_check,
+	.atomic_flush = vc4_crtc_atomic_flush,
+};
+
+/* Frees the page flip event when the DRM device is closed with the
+ * event still outstanding.
+ */
+void vc4_cancel_page_flip(struct drm_crtc *crtc, struct drm_file *file)
+{
+	struct vc4_crtc *vc4_crtc = to_vc4_crtc(crtc);
+	struct drm_device *dev = crtc->dev;
+	unsigned long flags;
+
+	spin_lock_irqsave(&dev->event_lock, flags);
+
+	if (vc4_crtc->event && vc4_crtc->event->base.file_priv == file) {
+		vc4_crtc->event->base.destroy(&vc4_crtc->event->base);
+		drm_crtc_vblank_put(crtc);
+		vc4_crtc->event = NULL;
+	}
+
+	spin_unlock_irqrestore(&dev->event_lock, flags);
+}
+
+static int vc4_crtc_bind(struct device *dev, struct device *master, void *data)
+{
+	struct platform_device *pdev = to_platform_device(dev);
+	struct drm_device *drm = dev_get_drvdata(master);
+	struct vc4_dev *vc4 = to_vc4_dev(drm);
+	struct vc4_crtc *vc4_crtc;
+	struct drm_crtc *crtc;
+	struct drm_plane *primary_plane, *cursor_plane;
+	int ret;
+
+	/* For now, we create just the primary and the legacy cursor
+	 * planes.  We should be able to stack more planes on easily,
+	 * but to do that we would need to compute the bandwidth
+	 * requirement of the plane configuration, and reject ones
+	 * that will take too much.
+	 */
+	primary_plane = vc4_plane_init(drm, DRM_PLANE_TYPE_PRIMARY);
+	if (!primary_plane) {
+		dev_err(dev, "failed to construct primary plane\n");
+		ret = PTR_ERR(primary_plane);
+		goto fail;
+	}
+
+	cursor_plane = vc4_plane_init(drm, DRM_PLANE_TYPE_CURSOR);
+	if (!cursor_plane) {
+		dev_err(dev, "failed to construct cursor plane\n");
+		ret = PTR_ERR(cursor_plane);
+		goto fail;
+	}
+
+	vc4_crtc = devm_kzalloc(dev, sizeof(*vc4_crtc), GFP_KERNEL);
+	if (!vc4_crtc)
+		return -ENOMEM;
+	crtc = &vc4_crtc->base;
+
+	vc4_crtc->regs = vc4_ioremap_regs(pdev, 0);
+	if (IS_ERR(vc4_crtc->regs))
+		return PTR_ERR(vc4_crtc->regs);
+
+	drm_crtc_init_with_planes(drm, crtc, primary_plane, cursor_plane,
+				  &vc4_crtc_funcs);
+	drm_crtc_helper_add(crtc, &vc4_crtc_helper_funcs);
+	primary_plane->crtc = crtc;
+	cursor_plane->crtc = crtc;
+	vc4->crtc[drm_crtc_index(crtc)] = vc4_crtc;
+
+	/* Until we have full scanout setup to route things through to
+	 * encoders, line things up like the firmware did.
+	 */
+	switch (drm_crtc_index(crtc)) {
+	case 0:
+		vc4_crtc->channel = 0;
+		break;
+	case 1:
+		vc4_crtc->channel = 2;
+		break;
+	default:
+	case 2:
+		vc4_crtc->channel = 1;
+		break;
+	}
+
+	CRTC_WRITE(PV_INTEN, 0);
+	CRTC_WRITE(PV_INTSTAT, PV_INT_VFP_START);
+	ret = devm_request_irq(dev, platform_get_irq(pdev, 0),
+			       vc4_crtc_irq_handler, 0, "vc4 crtc", vc4_crtc);
+
+	platform_set_drvdata(pdev, vc4_crtc);
+
+	return 0;
+
+fail:
+	return ret;
+}
+
+static void vc4_crtc_unbind(struct device *dev, struct device *master,
+			    void *data)
+{
+	struct platform_device *pdev = to_platform_device(dev);
+	struct vc4_crtc *vc4_crtc = dev_get_drvdata(dev);
+
+	vc4_crtc_destroy(&vc4_crtc->base);
+
+	CRTC_WRITE(PV_INTEN, 0);
+
+	platform_set_drvdata(pdev, NULL);
+}
+
+static const struct component_ops vc4_crtc_ops = {
+	.bind   = vc4_crtc_bind,
+	.unbind = vc4_crtc_unbind,
+};
+
+static int vc4_crtc_dev_probe(struct platform_device *pdev)
+{
+	return component_add(&pdev->dev, &vc4_crtc_ops);
+}
+
+static int vc4_crtc_dev_remove(struct platform_device *pdev)
+{
+	component_del(&pdev->dev, &vc4_crtc_ops);
+	return 0;
+}
+
+static const struct of_device_id vc4_crtc_dt_match[] = {
+	{ .compatible = "brcm,vc4-pixelvalve" },
+	{}
+};
+
+struct platform_driver vc4_crtc_driver = {
+	.probe = vc4_crtc_dev_probe,
+	.remove = vc4_crtc_dev_remove,
+	.driver = {
+		.name = "vc4_crtc",
+		.of_match_table = vc4_crtc_dt_match,
+	},
+};
diff --git a/drivers/gpu/drm/vc4/vc4_debugfs.c b/drivers/gpu/drm/vc4/vc4_debugfs.c
new file mode 100644
index 0000000..c557039
--- /dev/null
+++ b/drivers/gpu/drm/vc4/vc4_debugfs.c
@@ -0,0 +1,38 @@
+/*
+ *  Copyright ? 2014 Broadcom
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License version 2 as
+ * published by the Free Software Foundation.
+ */
+
+#include <linux/seq_file.h>
+#include <linux/circ_buf.h>
+#include <linux/ctype.h>
+#include <linux/debugfs.h>
+#include <drm/drmP.h>
+
+#include "vc4_drv.h"
+#include "vc4_regs.h"
+
+static const struct drm_info_list vc4_debugfs_list[] = {
+	{"hdmi_regs", vc4_hdmi_debugfs_regs, 0},
+	{"hvs_regs", vc4_hvs_debugfs_regs, 0},
+	{"crtc0_regs", vc4_crtc_debugfs_regs, 0, (void *)(uintptr_t)0},
+	{"crtc1_regs", vc4_crtc_debugfs_regs, 0, (void *)(uintptr_t)1},
+	{"crtc2_regs", vc4_crtc_debugfs_regs, 0, (void *)(uintptr_t)2},
+};
+#define VC4_DEBUGFS_ENTRIES ARRAY_SIZE(vc4_debugfs_list)
+
+int
+vc4_debugfs_init(struct drm_minor *minor)
+{
+	return drm_debugfs_create_files(vc4_debugfs_list, VC4_DEBUGFS_ENTRIES,
+					minor->debugfs_root, minor);
+}
+
+void
+vc4_debugfs_cleanup(struct drm_minor *minor)
+{
+	drm_debugfs_remove_files(vc4_debugfs_list, VC4_DEBUGFS_ENTRIES, minor);
+}
diff --git a/drivers/gpu/drm/vc4/vc4_drv.c b/drivers/gpu/drm/vc4/vc4_drv.c
new file mode 100644
index 0000000..d30aefa
--- /dev/null
+++ b/drivers/gpu/drm/vc4/vc4_drv.c
@@ -0,0 +1,271 @@
+/*
+ * Copyright (C) 2014-2015 Broadcom
+ * Copyright (C) 2013 Red Hat
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License version 2 as
+ * published by the Free Software Foundation.
+ */
+
+#include <linux/clk.h>
+#include <linux/component.h>
+#include <linux/device.h>
+#include <linux/io.h>
+#include <linux/module.h>
+#include <linux/of_platform.h>
+#include <linux/platform_device.h>
+
+#include "vc4_drv.h"
+#include "vc4_regs.h"
+
+#define DRIVER_NAME "vc4"
+#define DRIVER_DESC "Broadcom VC4 graphics"
+#define DRIVER_DATE "20140616"
+#define DRIVER_MAJOR 0
+#define DRIVER_MINOR 0
+#define DRIVER_PATCHLEVEL 0
+
+/* Helper function for mapping the regs on a platform device. */
+void __iomem *vc4_ioremap_regs(struct platform_device *dev, int index)
+{
+	struct resource *res;
+	void __iomem *map;
+
+	res = platform_get_resource(dev, IORESOURCE_MEM, index);
+	map = devm_ioremap_resource(&dev->dev, res);
+	if (IS_ERR(map)) {
+		DRM_ERROR("Failed to map registers: %ld\n", PTR_ERR(map));
+		return map;
+	}
+
+	return map;
+}
+
+static void vc4_drm_preclose(struct drm_device *dev, struct drm_file *file)
+{
+	struct drm_crtc *crtc;
+
+	list_for_each_entry(crtc, &dev->mode_config.crtc_list, head)
+		vc4_cancel_page_flip(crtc, file);
+}
+
+static const struct file_operations vc4_drm_fops = {
+	.owner = THIS_MODULE,
+	.open = drm_open,
+	.release = drm_release,
+	.unlocked_ioctl = drm_ioctl,
+	.mmap = drm_gem_cma_mmap,
+	.poll = drm_poll,
+	.read = drm_read,
+#ifdef CONFIG_COMPAT
+	.compat_ioctl = drm_compat_ioctl,
+#endif
+	.llseek = noop_llseek,
+};
+
+static const struct drm_ioctl_desc vc4_drm_ioctls[] = {
+};
+
+static struct drm_driver vc4_drm_driver = {
+	.driver_features = (DRIVER_MODESET |
+			    DRIVER_ATOMIC |
+			    DRIVER_GEM |
+			    DRIVER_PRIME),
+	.preclose = vc4_drm_preclose,
+
+	.enable_vblank = vc4_enable_vblank,
+	.disable_vblank = vc4_disable_vblank,
+	.get_vblank_counter = drm_vblank_count,
+
+#if defined(CONFIG_DEBUG_FS)
+	.debugfs_init = vc4_debugfs_init,
+	.debugfs_cleanup = vc4_debugfs_cleanup,
+#endif
+
+	.gem_free_object = drm_gem_cma_free_object,
+	.gem_vm_ops = &drm_gem_cma_vm_ops,
+
+	.prime_handle_to_fd = drm_gem_prime_handle_to_fd,
+	.prime_fd_to_handle = drm_gem_prime_fd_to_handle,
+	.gem_prime_import = drm_gem_prime_import,
+	.gem_prime_export = drm_gem_prime_export,
+	.gem_prime_get_sg_table	= drm_gem_cma_prime_get_sg_table,
+	.gem_prime_import_sg_table = drm_gem_cma_prime_import_sg_table,
+	.gem_prime_vmap = drm_gem_cma_prime_vmap,
+	.gem_prime_vunmap = drm_gem_cma_prime_vunmap,
+	.gem_prime_mmap = drm_gem_cma_prime_mmap,
+
+	.dumb_create = vc4_dumb_create,
+	.dumb_map_offset = drm_gem_cma_dumb_map_offset,
+	.dumb_destroy = drm_gem_dumb_destroy,
+
+	.ioctls = vc4_drm_ioctls,
+	.num_ioctls = ARRAY_SIZE(vc4_drm_ioctls),
+	.fops = &vc4_drm_fops,
+
+	.name = DRIVER_NAME,
+	.desc = DRIVER_DESC,
+	.date = DRIVER_DATE,
+	.major = DRIVER_MAJOR,
+	.minor = DRIVER_MINOR,
+	.patchlevel = DRIVER_PATCHLEVEL,
+};
+
+static int vc4_drm_bind(struct device *dev)
+{
+	struct platform_device *pdev = to_platform_device(dev);
+	struct drm_device *drm;
+	struct vc4_dev *vc4;
+	int ret = 0;
+
+	dev->coherent_dma_mask = DMA_BIT_MASK(32);
+
+	vc4 = devm_kzalloc(dev, sizeof(*vc4), GFP_KERNEL);
+	if (!vc4)
+		return -ENOMEM;
+
+	drm = drm_dev_alloc(&vc4_drm_driver, dev);
+	if (!drm)
+		return -ENOMEM;
+	platform_set_drvdata(pdev, drm);
+	vc4->dev = drm;
+	drm->dev_private = vc4;
+
+	drm_dev_set_unique(drm, dev_name(dev));
+
+	drm_mode_config_init(drm);
+	if (ret)
+		goto unref;
+
+	ret = component_bind_all(dev, drm);
+	if (ret)
+		goto unref;
+
+	ret = drm_dev_register(drm, 0);
+	if (ret < 0)
+		goto unbind_all;
+
+	vc4_kms_load(drm);
+
+	return 0;
+unbind_all:
+	component_unbind_all(dev, drm);
+unref:
+	drm_dev_unref(drm);
+	return ret;
+
+	return 0;
+}
+
+static void vc4_drm_unbind(struct device *dev)
+{
+	struct platform_device *pdev = to_platform_device(dev);
+	struct drm_device *drm = platform_get_drvdata(pdev);
+
+	drm_mode_config_cleanup(drm);
+
+	drm_put_dev(drm);
+}
+
+static const struct component_master_ops vc4_drm_ops = {
+	.bind = vc4_drm_bind,
+	.unbind = vc4_drm_unbind,
+};
+
+static int compare_of(struct device *dev, void *data)
+{
+	return dev->of_node == data;
+}
+
+static int add_components(struct device *dev, struct component_match **matchptr,
+			  const char *name)
+{
+	struct device_node *np = dev->of_node;
+	unsigned i;
+
+	for (i = 0; ; i++) {
+		struct device_node *node;
+
+		node = of_parse_phandle(np, name, i);
+		if (!node)
+			break;
+
+		component_match_add(dev, matchptr, compare_of, node);
+	}
+
+	return 0;
+}
+
+static int vc4_platform_drm_probe(struct platform_device *pdev)
+{
+	struct component_match *match = NULL;
+	struct device *dev = &pdev->dev;
+
+	add_components(dev, &match, "crtcs");
+	add_components(dev, &match, "encoders");
+	add_components(dev, &match, "hvss");
+
+	return component_master_add_with_match(dev, &vc4_drm_ops, match);
+}
+
+static int vc4_platform_drm_remove(struct platform_device *pdev)
+{
+	component_master_del(&pdev->dev, &vc4_drm_ops);
+
+	return 0;
+}
+
+static const struct of_device_id vc4_of_match[] = {
+	{ .compatible = "brcm,vc4", },
+	{},
+};
+MODULE_DEVICE_TABLE(of, vc4_of_match);
+
+static struct platform_driver vc4_platform_driver = {
+	.probe		= vc4_platform_drm_probe,
+	.remove		= vc4_platform_drm_remove,
+	.driver		= {
+		.name	= "vc4-drm",
+		.owner	= THIS_MODULE,
+		.of_match_table = vc4_of_match,
+	},
+};
+
+static struct platform_driver *component_drivers[] = {
+	&vc4_hdmi_driver,
+	&vc4_crtc_driver,
+	&vc4_hvs_driver,
+};
+
+static int __init vc4_drm_register(void)
+{
+	int i;
+
+	for (i = 0; i < ARRAY_SIZE(component_drivers); i++) {
+		int ret = platform_driver_register(component_drivers[i]);
+		if (ret) {
+			while (--i >= 0)
+				platform_driver_unregister(component_drivers[i]);
+			return ret;
+		}
+	}
+	return platform_driver_register(&vc4_platform_driver);
+}
+
+static void __exit vc4_drm_unregister(void)
+{
+	int i;
+
+	for (i = ARRAY_SIZE(component_drivers) - 1; i >= 0; i--)
+		platform_driver_unregister(component_drivers[i]);
+
+	platform_driver_unregister(&vc4_platform_driver);
+}
+
+module_init(vc4_drm_register);
+module_exit(vc4_drm_unregister);
+
+MODULE_ALIAS("platform:vc4-drm");
+MODULE_DESCRIPTION("Broadcom VC4 DRM Driver");
+MODULE_AUTHOR("Eric Anholt <eric at anholt.net>");
+MODULE_LICENSE("GPL v2");
diff --git a/drivers/gpu/drm/vc4/vc4_drv.h b/drivers/gpu/drm/vc4/vc4_drv.h
new file mode 100644
index 0000000..282ce0b
--- /dev/null
+++ b/drivers/gpu/drm/vc4/vc4_drv.h
@@ -0,0 +1,120 @@
+/*
+ * Copyright (C) 2015 Broadcom
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License version 2 as
+ * published by the Free Software Foundation.
+ */
+
+#include "drmP.h"
+#include "drm_gem_cma_helper.h"
+
+struct vc4_dev {
+	struct drm_device *dev;
+
+	struct vc4_hdmi *hdmi;
+	struct vc4_hvs *hvs;
+	struct vc4_crtc *crtc[3];
+};
+
+static inline struct vc4_dev *
+to_vc4_dev(struct drm_device *dev)
+{
+	return (struct vc4_dev *)dev->dev_private;
+}
+
+struct vc4_bo {
+	struct drm_gem_cma_object base;
+};
+
+static inline struct vc4_bo *
+to_vc4_bo(struct drm_gem_object *bo)
+{
+	return (struct vc4_bo *)bo;
+}
+
+struct vc4_hvs {
+	struct platform_device *pdev;
+	void __iomem *regs;
+	void __iomem *dlist;
+};
+
+struct vc4_crtc {
+	struct drm_crtc base;
+	void __iomem *regs;
+
+	/* Which HVS channel we're using for our CRTC. */
+	int channel;
+
+	/* Pointer to the actual hardware display list memory for the
+	 * crtc.
+	 */
+	u32 __iomem *dlist;
+
+	u32 dlist_size; /* in dwords */
+
+	struct drm_pending_vblank_event *event;
+};
+
+static inline struct vc4_crtc *
+to_vc4_crtc(struct drm_crtc *crtc)
+{
+	return (struct vc4_crtc *)crtc;
+}
+
+struct vc4_plane {
+	struct drm_plane base;
+};
+
+static inline struct vc4_plane *
+to_vc4_plane(struct drm_plane *plane)
+{
+	return (struct vc4_plane *)plane;
+}
+
+#define HVS_READ(offset) readl(vc4->hvs->regs + offset)
+#define HVS_WRITE(offset, val) writel(val, vc4->hvs->regs + offset)
+
+/* vc4_bo.c */
+void vc4_free_object(struct drm_gem_object *gem_obj);
+struct vc4_bo *vc4_bo_create(struct drm_device *dev, size_t size);
+int vc4_dumb_create(struct drm_file *file_priv,
+		    struct drm_device *dev,
+		    struct drm_mode_create_dumb *args);
+struct dma_buf *vc4_prime_export(struct drm_device *dev,
+				 struct drm_gem_object *obj, int flags);
+
+/* vc4_crtc.c */
+extern struct platform_driver vc4_crtc_driver;
+int vc4_enable_vblank(struct drm_device *dev, int crtc_id);
+void vc4_disable_vblank(struct drm_device *dev, int crtc_id);
+void vc4_cancel_page_flip(struct drm_crtc *crtc, struct drm_file *file);
+int vc4_crtc_debugfs_regs(struct seq_file *m, void *arg);
+
+/* vc4_debugfs.c */
+int vc4_debugfs_init(struct drm_minor *minor);
+void vc4_debugfs_cleanup(struct drm_minor *minor);
+
+/* vc4_drv.c */
+void __iomem *vc4_ioremap_regs(struct platform_device *dev, int index);
+
+/* vc4_hdmi.c */
+extern struct platform_driver vc4_hdmi_driver;
+struct drm_encoder *vc4_hdmi_encoder_init(struct drm_device *dev);
+struct drm_connector *vc4_hdmi_connector_init(struct drm_device *dev,
+					      struct drm_encoder *encoder);
+int vc4_hdmi_debugfs_regs(struct seq_file *m, void *unused);
+
+/* vc4_hvs.c */
+extern struct platform_driver vc4_hvs_driver;
+void vc4_hvs_dump_state(struct drm_device *dev);
+int vc4_hvs_debugfs_regs(struct seq_file *m, void *unused);
+
+/* vc4_kms.c */
+int vc4_kms_load(struct drm_device *dev);
+
+/* vc4_plane.c */
+struct drm_plane *vc4_plane_init(struct drm_device *dev,
+				 enum drm_plane_type type);
+u32 vc4_plane_write_dlist(struct drm_plane *plane, u32 __iomem *dlist);
+u32 vc4_plane_dlist_size(struct drm_plane_state *state);
diff --git a/drivers/gpu/drm/vc4/vc4_hdmi.c b/drivers/gpu/drm/vc4/vc4_hdmi.c
new file mode 100644
index 0000000..cd3301b
--- /dev/null
+++ b/drivers/gpu/drm/vc4/vc4_hdmi.c
@@ -0,0 +1,633 @@
+/*
+ * Copyright (c) 2014 The Linux Foundation. All rights reserved.
+ * Copyright (C) 2013 Red Hat
+ * Author: Rob Clark <robdclark at gmail.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.
+ *
+ * You should have received a copy of the GNU General Public License along with
+ * this program.  If not, see <http://www.gnu.org/licenses/>.
+ */
+
+#include "drm_atomic_helper.h"
+#include "drm_crtc_helper.h"
+#include "drm_edid.h"
+#include "linux/clk.h"
+#include "linux/component.h"
+#include "linux/of_gpio.h"
+#include "linux/of_platform.h"
+#include "vc4_drv.h"
+#include "vc4_regs.h"
+
+/* General HDMI hardware state. */
+struct vc4_hdmi {
+	struct platform_device *pdev;
+	struct i2c_adapter *ddc;
+	void __iomem *hdmicore_regs;
+	void __iomem *hd_regs;
+	int hpd_gpio;
+
+	/* Probed video mode at boot time, used to filter display
+	 * modes to only allow equivalent ones (since we can't set the
+	 * pixel clock yet).
+	 */
+	struct drm_display_mode boot_mode;
+};
+#define HDMI_READ(offset) readl(vc4->hdmi->hdmicore_regs + offset)
+#define HDMI_WRITE(offset, val) writel(val, vc4->hdmi->hdmicore_regs + offset)
+#define HD_READ(offset) readl(vc4->hdmi->hd_regs + offset)
+#define HD_WRITE(offset, val) writel(val, vc4->hdmi->hd_regs + offset)
+
+/* VC4 HDMI encoder KMS struct */
+struct vc4_hdmi_encoder {
+	struct drm_encoder base;
+	bool hdmi_monitor;
+};
+static inline struct vc4_hdmi_encoder *
+to_vc4_hdmi_encoder(struct drm_encoder *encoder)
+{
+	return container_of(encoder, struct vc4_hdmi_encoder, base);
+}
+
+/* VC4 HDMI connector KMS struct */
+struct vc4_hdmi_connector {
+	struct drm_connector base;
+
+	/* Since the connector is attached to just the one encoder,
+	 * this is the reference to it so we can do the best_encoder()
+	 * hook.
+	 */
+	struct drm_encoder *encoder;
+};
+static inline struct vc4_hdmi_connector *
+to_vc4_hdmi_connector(struct drm_connector *connector)
+{
+	return container_of(connector, struct vc4_hdmi_connector, base);
+}
+
+#define HDMI_REG(reg) { reg, #reg }
+static const struct {
+	u32 reg;
+	const char *name;
+} hdmi_regs[] = {
+	HDMI_REG(VC4_HDMI_CORE_REV),
+	HDMI_REG(VC4_HDMI_SW_RESET_CONTROL),
+	HDMI_REG(VC4_HDMI_HOTPLUG_INT),
+	HDMI_REG(VC4_HDMI_HOTPLUG),
+	HDMI_REG(VC4_HDMI_HORZA),
+	HDMI_REG(VC4_HDMI_HORZB),
+	HDMI_REG(VC4_HDMI_FIFO_CTL),
+	HDMI_REG(VC4_HDMI_SCHEDULER_CONTROL),
+	HDMI_REG(VC4_HDMI_VERTA0),
+	HDMI_REG(VC4_HDMI_VERTA1),
+	HDMI_REG(VC4_HDMI_VERTB0),
+	HDMI_REG(VC4_HDMI_VERTB1),
+	HDMI_REG(VC4_HDMI_TX_PHY_RESET_CTL),
+};
+static const struct {
+	u32 reg;
+	const char *name;
+} hd_regs[] = {
+	HDMI_REG(VC4_HD_M_CTL),
+	HDMI_REG(VC4_HD_MAI_CTL),
+	HDMI_REG(VC4_HD_VID_CTL),
+	HDMI_REG(VC4_HD_CSC_CTL),
+	HDMI_REG(VC4_HD_FRAME_COUNT),
+};
+
+#ifdef CONFIG_DEBUG_FS
+int vc4_hdmi_debugfs_regs(struct seq_file *m, void *unused)
+{
+	struct drm_info_node *node = (struct drm_info_node *) m->private;
+	struct drm_device *dev = node->minor->dev;
+	struct vc4_dev *vc4 = to_vc4_dev(dev);
+	int i;
+
+	for (i = 0; i < ARRAY_SIZE(hdmi_regs); i++) {
+		seq_printf(m, "%s (0x%04x): 0x%08x\n",
+			   hdmi_regs[i].name, hdmi_regs[i].reg,
+			   HDMI_READ(hdmi_regs[i].reg));
+	}
+
+	for (i = 0; i < ARRAY_SIZE(hd_regs); i++) {
+		seq_printf(m, "%s (0x%04x): 0x%08x\n",
+			   hd_regs[i].name, hd_regs[i].reg,
+			   HD_READ(hd_regs[i].reg));
+	}
+
+	return 0;
+}
+#endif /* CONFIG_DEBUG_FS */
+
+static void vc4_hdmi_dump_regs(struct drm_device *dev)
+{
+	struct vc4_dev *vc4 = to_vc4_dev(dev);
+	int i;
+
+	for (i = 0; i < ARRAY_SIZE(hdmi_regs); i++) {
+		DRM_INFO("0x%04x (%s): 0x%08x\n",
+			 hdmi_regs[i].reg, hdmi_regs[i].name,
+			 HDMI_READ(hdmi_regs[i].reg));
+	}
+	for (i = 0; i < ARRAY_SIZE(hd_regs); i++) {
+		DRM_INFO("0x%04x (%s): 0x%08x\n",
+			 hd_regs[i].reg, hd_regs[i].name,
+			 HD_READ(hd_regs[i].reg));
+	}
+}
+
+static enum drm_connector_status
+vc4_hdmi_connector_detect(struct drm_connector *connector, bool force)
+{
+	struct drm_device *dev = connector->dev;
+	struct vc4_dev *vc4 = to_vc4_dev(dev);
+
+	if (vc4->hdmi->hpd_gpio) {
+		if (gpio_get_value(vc4->hdmi->hpd_gpio))
+			return connector_status_connected;
+		else
+			return connector_status_disconnected;
+	}
+
+	if (HDMI_READ(VC4_HDMI_HOTPLUG) & VC4_HDMI_HOTPLUG_CONNECTED)
+		return connector_status_connected;
+	else
+		return connector_status_disconnected;
+}
+
+static void vc4_hdmi_connector_destroy(struct drm_connector *connector)
+{
+	drm_connector_unregister(connector);
+	drm_connector_cleanup(connector);
+}
+
+static int vc4_hdmi_connector_get_modes(struct drm_connector *connector)
+{
+	struct vc4_hdmi_connector *vc4_connector =
+		to_vc4_hdmi_connector(connector);
+	struct drm_encoder *encoder = vc4_connector->encoder;
+	struct vc4_hdmi_encoder *vc4_encoder = to_vc4_hdmi_encoder(encoder);
+	struct drm_device *dev = connector->dev;
+	struct vc4_dev *vc4 = to_vc4_dev(dev);
+	int ret = 0;
+	struct edid *edid;
+
+	edid = drm_get_edid(connector, vc4->hdmi->ddc);
+	if (!edid)
+		return -ENODEV;
+
+	vc4_encoder->hdmi_monitor = drm_detect_hdmi_monitor(edid);
+	drm_mode_connector_update_edid_property(connector, edid);
+	ret = drm_add_edid_modes(connector, edid);
+
+	return ret;
+}
+
+/* Since we can't set the pixel clock yet, filter out all the EDID
+ * modes that don't match what was set up by the firmware.
+ */
+int vc4_hdmi_mode_valid(struct drm_connector *connector,
+			struct drm_display_mode *mode)
+{
+	struct drm_device *dev = connector->dev;
+	struct vc4_dev *vc4 = to_vc4_dev(dev);
+	struct drm_display_mode *boot_mode = &vc4->hdmi->boot_mode;
+
+	if (mode->hdisplay != boot_mode->hdisplay ||
+	    mode->hsync_start != boot_mode->hsync_start ||
+	    mode->hsync_end != boot_mode->hsync_end ||
+	    mode->htotal != boot_mode->htotal) {
+		return MODE_ERROR;
+	}
+
+	return MODE_OK;
+}
+
+static struct drm_encoder *
+vc4_hdmi_connector_best_encoder(struct drm_connector *connector)
+{
+	struct vc4_hdmi_connector *hdmi_connector =
+		to_vc4_hdmi_connector(connector);
+	return hdmi_connector->encoder;
+}
+
+static const struct drm_connector_funcs vc4_hdmi_connector_funcs = {
+	.dpms = drm_atomic_helper_connector_dpms,
+	.detect = vc4_hdmi_connector_detect,
+	.fill_modes = drm_helper_probe_single_connector_modes,
+	.destroy = vc4_hdmi_connector_destroy,
+	.reset = drm_atomic_helper_connector_reset,
+	.atomic_duplicate_state = drm_atomic_helper_connector_duplicate_state,
+	.atomic_destroy_state = drm_atomic_helper_connector_destroy_state,
+};
+
+static const struct drm_connector_helper_funcs vc4_hdmi_connector_helper_funcs = {
+	.get_modes = vc4_hdmi_connector_get_modes,
+	.mode_valid = vc4_hdmi_mode_valid,
+	.best_encoder = vc4_hdmi_connector_best_encoder,
+};
+
+struct drm_connector *vc4_hdmi_connector_init(struct drm_device *dev,
+					      struct drm_encoder *encoder)
+{
+	struct drm_connector *connector = NULL;
+	struct vc4_hdmi_connector *hdmi_connector;
+	int ret = 0;
+
+	hdmi_connector = devm_kzalloc(dev->dev, sizeof(*hdmi_connector),
+				      GFP_KERNEL);
+	if (!hdmi_connector) {
+		ret = -ENOMEM;
+		goto fail;
+	}
+	connector = &hdmi_connector->base;
+
+	hdmi_connector->encoder = encoder;
+
+	drm_connector_init(dev, connector, &vc4_hdmi_connector_funcs,
+			   DRM_MODE_CONNECTOR_HDMIA);
+	drm_connector_helper_add(connector, &vc4_hdmi_connector_helper_funcs);
+
+	connector->polled = (DRM_CONNECTOR_POLL_CONNECT |
+			     DRM_CONNECTOR_POLL_DISCONNECT);
+
+	connector->interlace_allowed = 0;
+	connector->doublescan_allowed = 0;
+
+	drm_connector_register(connector);
+
+	drm_mode_connector_attach_encoder(connector, encoder);
+
+	return connector;
+
+ fail:
+	if (connector)
+		vc4_hdmi_connector_destroy(connector);
+
+	return ERR_PTR(ret);
+}
+
+static void vc4_encoder_destroy(struct drm_encoder *encoder)
+{
+	drm_encoder_cleanup(encoder);
+}
+
+static const struct drm_encoder_funcs vc4_hdmi_encoder_funcs = {
+	.destroy = vc4_encoder_destroy,
+};
+
+static void vc4_hdmi_encoder_mode_set(struct drm_encoder *encoder,
+				      struct drm_display_mode *unadjusted_mode,
+				      struct drm_display_mode *mode)
+{
+	struct drm_device *dev = encoder->dev;
+	struct vc4_dev *vc4 = to_vc4_dev(dev);
+	bool debug_dump_regs = false;
+	bool hsync_pos = !(mode->flags & DRM_MODE_FLAG_NHSYNC);
+	bool vsync_pos = !(mode->flags & DRM_MODE_FLAG_NVSYNC);
+	u32 vactive = (mode->vdisplay >>
+		       ((mode->flags & DRM_MODE_FLAG_INTERLACE) ? 1 : 0));
+	u32 verta = (VC4_SET_FIELD(mode->vsync_end - mode->vsync_start,
+				   VC4_HDMI_VERTA_VSP) |
+		     VC4_SET_FIELD(mode->vsync_start - mode->vdisplay,
+				   VC4_HDMI_VERTA_VFP) |
+		     VC4_SET_FIELD(vactive, VC4_HDMI_VERTA_VAL));
+	u32 vertb = (VC4_SET_FIELD(0, VC4_HDMI_VERTB_VSPO) |
+		     VC4_SET_FIELD(mode->vtotal - mode->vsync_end,
+				   VC4_HDMI_VERTB_VBP));
+
+	if (debug_dump_regs) {
+		DRM_INFO("HDMI regs before:\n");
+		vc4_hdmi_dump_regs(dev);
+	}
+
+	HD_WRITE(VC4_HD_VID_CTL, 0);
+
+	/* XXX: This is where we would set the HDMI state machine
+	 * clock, if we had an interface for it.
+	 */
+
+	HDMI_WRITE(VC4_HDMI_SCHEDULER_CONTROL,
+		   HDMI_READ(VC4_HDMI_SCHEDULER_CONTROL) |
+		   VC4_HDMI_SCHEDULER_CONTROL_MANUAL_FORMAT |
+		   VC4_HDMI_SCHEDULER_CONTROL_IGNORE_VSYNC_PREDICTS);
+
+	HDMI_WRITE(VC4_HDMI_HORZA,
+		   (vsync_pos ? VC4_HDMI_HORZA_VPOS : 0) |
+		   (hsync_pos ? VC4_HDMI_HORZA_HPOS : 0) |
+		   VC4_SET_FIELD(mode->hdisplay, VC4_HDMI_HORZA_HAP));
+
+	HDMI_WRITE(VC4_HDMI_HORZB,
+		   VC4_SET_FIELD(mode->htotal - mode->hsync_end,
+				 VC4_HDMI_HORZB_HBP) |
+		   VC4_SET_FIELD(mode->hsync_end - mode->hsync_start,
+				 VC4_HDMI_HORZB_HSP) |
+		   VC4_SET_FIELD(mode->hsync_start - mode->hdisplay,
+				 VC4_HDMI_HORZB_HFP));
+
+	HDMI_WRITE(VC4_HDMI_VERTA0, verta);
+	HDMI_WRITE(VC4_HDMI_VERTA1, verta);
+
+	HDMI_WRITE(VC4_HDMI_VERTB0, vertb);
+	HDMI_WRITE(VC4_HDMI_VERTB1, vertb);
+
+	HD_WRITE(VC4_HD_VID_CTL,
+		 (vsync_pos ? 0 : VC4_HD_VID_CTL_VSYNC_LOW) |
+		 (hsync_pos ? 0 : VC4_HD_VID_CTL_HSYNC_LOW));
+
+	/* The RGB order applies even when CSC is disabled. */
+	HD_WRITE(VC4_HD_CSC_CTL, VC4_SET_FIELD(VC4_HD_CSC_CTL_ORDER_BGR,
+					       VC4_HD_CSC_CTL_ORDER));
+
+	HDMI_WRITE(VC4_HDMI_FIFO_CTL, VC4_HDMI_FIFO_CTL_MASTER_SLAVE_N);
+
+	if (debug_dump_regs) {
+		DRM_INFO("HDMI regs after:\n");
+		vc4_hdmi_dump_regs(dev);
+	}
+}
+
+static void vc4_hdmi_encoder_disable(struct drm_encoder *encoder)
+{
+	struct drm_device *dev = encoder->dev;
+	struct vc4_dev *vc4 = to_vc4_dev(dev);
+
+	HDMI_WRITE(VC4_HDMI_TX_PHY_RESET_CTL, 0xf << 16);
+	HD_WRITE(VC4_HD_VID_CTL,
+		 HD_READ(VC4_HD_VID_CTL) & ~VC4_HD_VID_CTL_ENABLE);
+}
+
+static void vc4_hdmi_encoder_enable(struct drm_encoder *encoder)
+{
+	struct vc4_hdmi_encoder *vc4_encoder = to_vc4_hdmi_encoder(encoder);
+	struct drm_device *dev = encoder->dev;
+	struct vc4_dev *vc4 = to_vc4_dev(dev);
+
+	HDMI_WRITE(VC4_HDMI_TX_PHY_RESET_CTL, 0);
+
+	HD_WRITE(VC4_HD_VID_CTL,
+		 HD_READ(VC4_HD_VID_CTL) |
+		 VC4_HD_VID_CTL_ENABLE |
+		 VC4_HD_VID_CTL_UNDERFLOW_ENABLE |
+		 VC4_HD_VID_CTL_FRAME_COUNTER_RESET);
+
+	if (vc4_encoder->hdmi_monitor) {
+		HDMI_WRITE(VC4_HDMI_SCHEDULER_CONTROL,
+			   HDMI_READ(VC4_HDMI_SCHEDULER_CONTROL) |
+			   VC4_HDMI_SCHEDULER_CONTROL_MODE_HDMI);
+
+		while (!(HDMI_READ(VC4_HDMI_SCHEDULER_CONTROL) &
+			 VC4_HDMI_SCHEDULER_CONTROL_HDMI_ACTIVE)) {
+			cpu_relax();
+		}
+	} else {
+		HDMI_WRITE(VC4_HDMI_RAM_PACKET_CONFIG,
+			   HDMI_READ(VC4_HDMI_RAM_PACKET_CONFIG) &
+			   ~(VC4_HDMI_RAM_PACKET_ENABLE));
+		HDMI_WRITE(VC4_HDMI_SCHEDULER_CONTROL,
+			   HDMI_READ(VC4_HDMI_SCHEDULER_CONTROL) &
+			   ~VC4_HDMI_SCHEDULER_CONTROL_MODE_HDMI);
+
+		while (HDMI_READ(VC4_HDMI_SCHEDULER_CONTROL) &
+		       VC4_HDMI_SCHEDULER_CONTROL_HDMI_ACTIVE) {
+			cpu_relax();
+		}
+	}
+
+	if (vc4_encoder->hdmi_monitor) {
+		u32 drift;
+
+		WARN_ON(!(HDMI_READ(VC4_HDMI_SCHEDULER_CONTROL) &
+			  VC4_HDMI_SCHEDULER_CONTROL_HDMI_ACTIVE));
+		HDMI_WRITE(VC4_HDMI_SCHEDULER_CONTROL,
+			   HDMI_READ(VC4_HDMI_SCHEDULER_CONTROL) |
+			   VC4_HDMI_SCHEDULER_CONTROL_VERT_ALWAYS_KEEPOUT);
+
+		/* XXX: Set HDMI_RAM_PACKET_CONFIG (1 << 16) and set
+		 * up the infoframe.
+		 */
+
+		drift = HDMI_READ(VC4_HDMI_FIFO_CTL);
+		drift &= VC4_HDMI_FIFO_VALID_WRITE_MASK;
+
+		HDMI_WRITE(VC4_HDMI_FIFO_CTL,
+			   drift & ~VC4_HDMI_FIFO_CTL_RECENTER);
+		HDMI_WRITE(VC4_HDMI_FIFO_CTL,
+			   drift | VC4_HDMI_FIFO_CTL_RECENTER);
+		udelay(1000);
+		HDMI_WRITE(VC4_HDMI_FIFO_CTL,
+			   drift & ~VC4_HDMI_FIFO_CTL_RECENTER);
+		HDMI_WRITE(VC4_HDMI_FIFO_CTL,
+			   drift | VC4_HDMI_FIFO_CTL_RECENTER);
+
+		while ((HDMI_READ(VC4_HDMI_FIFO_CTL) &
+			VC4_HDMI_FIFO_CTL_RECENTER_DONE) == 0) {
+			cpu_relax();
+		}
+	}
+}
+
+static const struct drm_encoder_helper_funcs vc4_hdmi_encoder_helper_funcs = {
+	.mode_set = vc4_hdmi_encoder_mode_set,
+	.disable = vc4_hdmi_encoder_disable,
+	.enable = vc4_hdmi_encoder_enable,
+};
+
+static struct drm_crtc *
+vc4_get_crtc_node(struct platform_device *pdev)
+{
+	struct device_node *crtc_node;
+	struct platform_device *crtc_pdev;
+
+	crtc_node = of_parse_phandle(pdev->dev.of_node, "crtc", 0);
+	if (!crtc_node) {
+		DRM_ERROR("No CRTC for hdmi in DT\n");
+		return ERR_PTR(-EINVAL);
+	}
+
+	crtc_pdev = of_find_device_by_node(crtc_node);
+	if (!crtc_pdev) {
+		DRM_ERROR("No CRTC device attached to OF node\n");
+		return ERR_PTR(-EINVAL);
+	}
+
+	return platform_get_drvdata(crtc_pdev);
+}
+
+struct drm_encoder *vc4_hdmi_encoder_init(struct drm_device *dev)
+{
+	struct vc4_dev *vc4 = to_vc4_dev(dev);
+	struct drm_encoder *encoder = NULL;
+	struct vc4_hdmi_encoder *vc4_hdmi_encoder;
+	struct drm_crtc *crtc;
+	int ret;
+
+	vc4_hdmi_encoder = devm_kzalloc(dev->dev, sizeof(*vc4_hdmi_encoder),
+					GFP_KERNEL);
+	if (!vc4_hdmi_encoder) {
+		ret = -ENOMEM;
+		goto fail;
+	}
+	encoder = &vc4_hdmi_encoder->base;
+
+	crtc = vc4_get_crtc_node(vc4->hdmi->pdev);
+	if (IS_ERR(crtc)) {
+		ret = PTR_ERR(crtc);
+		goto fail;
+	}
+
+	drm_encoder_init(dev, encoder, &vc4_hdmi_encoder_funcs,
+			 DRM_MODE_ENCODER_TMDS);
+	drm_encoder_helper_add(encoder, &vc4_hdmi_encoder_helper_funcs);
+
+	encoder->possible_crtcs = drm_crtc_mask(crtc);
+
+	return encoder;
+
+fail:
+	if (encoder)
+		vc4_encoder_destroy(encoder);
+
+	return ERR_PTR(ret);
+}
+
+/* Reads out the current HDMI mode progreamming at driver load time.
+ *
+ * This is currently used for later filtering out of the DDC-probed
+ * video modes, since we can't actually change modes due to not having
+ * control of the necessary clocks.  Later on, we may end up reusing
+ * this for skipping modesets at boot time.
+ */
+static void
+vc4_hdmi_get_boot_display_mode(struct vc4_dev *vc4)
+{
+	struct drm_display_mode *mode = &vc4->hdmi->boot_mode;
+	u32 horza = HDMI_READ(VC4_HDMI_HORZA);
+	u32 horzb = HDMI_READ(VC4_HDMI_HORZB);
+	u32 verta = HDMI_READ(VC4_HDMI_VERTA0);
+	u32 vertb = HDMI_READ(VC4_HDMI_VERTB0);
+
+	memset(mode, 0, sizeof(*mode));
+
+	if (!(horza & VC4_HDMI_HORZA_VPOS))
+		mode->flags |= DRM_MODE_FLAG_NVSYNC;
+	if (!(horza & VC4_HDMI_HORZA_HPOS))
+		mode->flags |= DRM_MODE_FLAG_NHSYNC;
+	mode->hdisplay = VC4_GET_FIELD(horza, VC4_HDMI_HORZA_HAP);
+	mode->hsync_start = (mode->hdisplay +
+			     VC4_GET_FIELD(horzb, VC4_HDMI_HORZB_HFP));
+	mode->hsync_end = (mode->hsync_start +
+			   VC4_GET_FIELD(horzb, VC4_HDMI_HORZB_HSP));
+	mode->htotal = (mode->hsync_end +
+			VC4_GET_FIELD(horzb, VC4_HDMI_HORZB_HBP));
+
+	mode->vdisplay = VC4_GET_FIELD(verta, VC4_HDMI_VERTA_VAL);
+	mode->vsync_start = (mode->vdisplay +
+			     VC4_GET_FIELD(verta, VC4_HDMI_VERTA_VFP));
+	mode->vsync_end = (mode->vsync_start +
+			   VC4_GET_FIELD(verta, VC4_HDMI_VERTA_VSP));
+	mode->vtotal = (mode->vsync_end +
+			VC4_GET_FIELD(vertb, VC4_HDMI_VERTB_VBP));
+}
+
+static int vc4_hdmi_bind(struct device *dev, struct device *master, void *data)
+{
+	struct platform_device *pdev = to_platform_device(dev);
+	struct drm_device *drm = dev_get_drvdata(master);
+	struct vc4_dev *vc4 = drm->dev_private;
+	struct vc4_hdmi *hdmi;
+	struct device_node *ddc_node;
+	u32 value;
+
+	hdmi = devm_kzalloc(dev, sizeof(*hdmi), GFP_KERNEL);
+	if (!hdmi)
+		return -ENOMEM;
+
+	hdmi->pdev = pdev;
+	hdmi->hdmicore_regs = vc4_ioremap_regs(pdev, 0);
+	if (IS_ERR(hdmi->hdmicore_regs))
+		return PTR_ERR(hdmi->hdmicore_regs);
+
+	hdmi->hd_regs = vc4_ioremap_regs(pdev, 1);
+	if (IS_ERR(hdmi->hd_regs))
+		return PTR_ERR(hdmi->hd_regs);
+
+	/* DDC i2c driver */
+	ddc_node = of_parse_phandle(dev->of_node, "ddc", 0);
+	if (!ddc_node) {
+		DRM_ERROR("Failed to find ddc node in device tree\n");
+		return -ENODEV;
+	}
+
+	hdmi->ddc = of_find_i2c_adapter_by_node(ddc_node);
+	if (!hdmi->ddc) {
+		DRM_ERROR("Failed to get ddc i2c adapter by node\n");
+		return -EPROBE_DEFER;
+	}
+
+	/* Only use the GPIO HPD pin if present in the DT, otherwise
+	 * we'll use the HDMI core's register.
+	 */
+	if (of_find_property(dev->of_node, "hpd-gpio", &value)) {
+		hdmi->hpd_gpio = of_get_named_gpio(dev->of_node, "hpd-gpio", 0);
+		if (hdmi->hpd_gpio < 0)
+			return hdmi->hpd_gpio;
+	}
+
+	vc4->hdmi = hdmi;
+
+	/* HDMI core must be enabled. */
+	WARN_ON_ONCE((HD_READ(VC4_HD_M_CTL) & VC4_HD_M_ENABLE) == 0);
+
+	vc4_hdmi_get_boot_display_mode(vc4);
+
+	return 0;
+}
+
+static void vc4_hdmi_unbind(struct device *dev, struct device *master,
+			    void *data)
+{
+	struct drm_device *drm = dev_get_drvdata(master);
+	struct vc4_dev *vc4 = drm->dev_private;
+
+	put_device(&vc4->hdmi->ddc->dev);
+
+	vc4->hdmi = NULL;
+}
+
+static const struct component_ops vc4_hdmi_ops = {
+	.bind   = vc4_hdmi_bind,
+	.unbind = vc4_hdmi_unbind,
+};
+
+static int vc4_hdmi_dev_probe(struct platform_device *pdev)
+{
+	return component_add(&pdev->dev, &vc4_hdmi_ops);
+}
+
+static int vc4_hdmi_dev_remove(struct platform_device *pdev)
+{
+	component_del(&pdev->dev, &vc4_hdmi_ops);
+	return 0;
+}
+
+static const struct of_device_id vc4_hdmi_dt_match[] = {
+	{ .compatible = "brcm,vc4-hdmi" },
+	{}
+};
+
+struct platform_driver vc4_hdmi_driver = {
+	.probe = vc4_hdmi_dev_probe,
+	.remove = vc4_hdmi_dev_remove,
+	.driver = {
+		.name = "vc4_hdmi",
+		.of_match_table = vc4_hdmi_dt_match,
+	},
+};
diff --git a/drivers/gpu/drm/vc4/vc4_hvs.c b/drivers/gpu/drm/vc4/vc4_hvs.c
new file mode 100644
index 0000000..34906fd
--- /dev/null
+++ b/drivers/gpu/drm/vc4/vc4_hvs.c
@@ -0,0 +1,161 @@
+/*
+ * Copyright (C) 2015 Broadcom
+ *
+ * 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.
+ */
+
+/**
+ * DOC: VC4 HVS module.
+ *
+ * The HVS is the piece of hardware that does translation, scaling,
+ * colorspace conversion, and compositing of pixels stored in
+ * framebuffers into a FIFO of pixels going out to the Pixel Valve
+ * (CRTC).
+ *
+ * There is a single global HVS, with multiple output FIFOs that can
+ * be consumed by the PVs.  This file just manages the resources for
+ * the HVS, while the vc4_crtc.c code actually drives HVS setup for
+ * each CRTC.
+ */
+
+#include "linux/component.h"
+#include "vc4_drv.h"
+#include "vc4_regs.h"
+
+#define HVS_REG(reg) { reg, #reg }
+static const struct {
+	u32 reg;
+	const char *name;
+} hvs_regs[] = {
+	HVS_REG(SCALER_DISPCTRL),
+	HVS_REG(SCALER_DISPSTAT),
+	HVS_REG(SCALER_DISPID),
+	HVS_REG(SCALER_DISPECTRL),
+	HVS_REG(SCALER_DISPPROF),
+	HVS_REG(SCALER_DISPDITHER),
+	HVS_REG(SCALER_DISPEOLN),
+	HVS_REG(SCALER_DISPLIST0),
+	HVS_REG(SCALER_DISPLIST1),
+	HVS_REG(SCALER_DISPLIST2),
+	HVS_REG(SCALER_DISPLSTAT),
+	HVS_REG(SCALER_DISPLACT0),
+	HVS_REG(SCALER_DISPLACT1),
+	HVS_REG(SCALER_DISPLACT2),
+	HVS_REG(SCALER_DISPCTRL0),
+	HVS_REG(SCALER_DISPBKGND0),
+	HVS_REG(SCALER_DISPSTAT0),
+	HVS_REG(SCALER_DISPBASE0),
+	HVS_REG(SCALER_DISPCTRL1),
+	HVS_REG(SCALER_DISPBKGND1),
+	HVS_REG(SCALER_DISPSTAT1),
+	HVS_REG(SCALER_DISPBASE1),
+	HVS_REG(SCALER_DISPCTRL2),
+	HVS_REG(SCALER_DISPBKGND2),
+	HVS_REG(SCALER_DISPSTAT2),
+	HVS_REG(SCALER_DISPBASE2),
+	HVS_REG(SCALER_DISPALPHA2),
+};
+
+void vc4_hvs_dump_state(struct drm_device *dev)
+{
+	struct vc4_dev *vc4 = to_vc4_dev(dev);
+	int i;
+
+	for (i = 0; i < ARRAY_SIZE(hvs_regs); i++) {
+		DRM_INFO("0x%04x (%s): 0x%08x\n",
+			 hvs_regs[i].reg, hvs_regs[i].name,
+			 HVS_READ(hvs_regs[i].reg));
+	}
+
+	DRM_INFO("HVS ctx:\n");
+	for (i = 0; i < 64; i += 4) {
+		DRM_INFO("0x%08x (%s): 0x%08x 0x%08x 0x%08x 0x%08x\n",
+			 i * 4, i < HVS_BOOTLOADER_DLIST_END ? "B" : "D",
+			 ((uint32_t *)vc4->hvs->dlist)[i + 0],
+			 ((uint32_t *)vc4->hvs->dlist)[i + 1],
+			 ((uint32_t *)vc4->hvs->dlist)[i + 2],
+			 ((uint32_t *)vc4->hvs->dlist)[i + 3]);
+	}
+}
+
+#ifdef CONFIG_DEBUG_FS
+int vc4_hvs_debugfs_regs(struct seq_file *m, void *unused)
+{
+	struct drm_info_node *node = (struct drm_info_node *) m->private;
+	struct drm_device *dev = node->minor->dev;
+	struct vc4_dev *vc4 = to_vc4_dev(dev);
+	int i;
+
+	for (i = 0; i < ARRAY_SIZE(hvs_regs); i++) {
+		seq_printf(m, "%s (0x%04x): 0x%08x\n",
+			   hvs_regs[i].name, hvs_regs[i].reg,
+			   HVS_READ(hvs_regs[i].reg));
+	}
+
+	return 0;
+}
+#endif
+
+static int vc4_hvs_bind(struct device *dev, struct device *master, void *data)
+{
+	struct platform_device *pdev = to_platform_device(dev);
+	struct drm_device *drm = dev_get_drvdata(master);
+	struct vc4_dev *vc4 = drm->dev_private;
+	struct vc4_hvs *hvs = NULL;
+
+	hvs = devm_kzalloc(&pdev->dev, sizeof(*hvs), GFP_KERNEL);
+	if (!hvs)
+		return -ENOMEM;
+
+	hvs->pdev = pdev;
+
+	hvs->regs = vc4_ioremap_regs(pdev, 0);
+	if (IS_ERR(hvs->regs))
+		return PTR_ERR(hvs->regs);
+
+	hvs->dlist = hvs->regs + SCALER_DLIST_START;
+
+	vc4->hvs = hvs;
+	return 0;
+}
+
+static void vc4_hvs_unbind(struct device *dev, struct device *master,
+			   void *data)
+{
+	struct drm_device *drm = dev_get_drvdata(master);
+	struct vc4_dev *vc4 = drm->dev_private;
+
+	vc4->hvs = NULL;
+}
+
+static const struct component_ops vc4_hvs_ops = {
+	.bind   = vc4_hvs_bind,
+	.unbind = vc4_hvs_unbind,
+};
+
+static int vc4_hvs_dev_probe(struct platform_device *pdev)
+{
+	return component_add(&pdev->dev, &vc4_hvs_ops);
+}
+
+static int vc4_hvs_dev_remove(struct platform_device *pdev)
+{
+	component_del(&pdev->dev, &vc4_hvs_ops);
+	return 0;
+}
+
+static const struct of_device_id vc4_hvs_dt_match[] = {
+	{ .compatible = "brcm,vc4-hvs" },
+	{}
+};
+
+struct platform_driver vc4_hvs_driver = {
+	.probe = vc4_hvs_dev_probe,
+	.remove = vc4_hvs_dev_remove,
+	.driver = {
+		.name = "vc4_hvs",
+		.of_match_table = vc4_hvs_dt_match,
+	},
+};
diff --git a/drivers/gpu/drm/vc4/vc4_kms.c b/drivers/gpu/drm/vc4/vc4_kms.c
new file mode 100644
index 0000000..e5e96bc
--- /dev/null
+++ b/drivers/gpu/drm/vc4/vc4_kms.c
@@ -0,0 +1,84 @@
+/*
+ * Copyright (C) 2015 Broadcom
+ *
+ * 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.
+ */
+
+/**
+ * DOC: VC4 KMS
+ *
+ * This is the general code for implementing KMS mode setting that
+ * doesn't clearly associate with any of the other objects (plane,
+ * crtc, HDMI encoder).
+ */
+
+#include "drm_crtc.h"
+#include "drm_atomic_helper.h"
+#include "drm_crtc_helper.h"
+#include "drm_plane_helper.h"
+#include "drm_fb_cma_helper.h"
+#include "vc4_drv.h"
+
+static const struct drm_mode_config_funcs vc4_mode_funcs = {
+	.atomic_check = drm_atomic_helper_check,
+	.atomic_commit = drm_atomic_helper_commit,
+	.fb_create = drm_fb_cma_create,
+};
+
+/* Calls out to initialize all of the VC4 KMS objects. */
+static int vc4_init_modeset_objects(struct drm_device *dev)
+{
+	struct drm_encoder *encoder;
+	struct drm_connector *connector;
+	int ret = 0;
+
+	encoder = vc4_hdmi_encoder_init(dev);
+	if (IS_ERR(encoder)) {
+		dev_err(dev->dev, "failed to construct HDMI encoder\n");
+		ret = PTR_ERR(encoder);
+		goto fail;
+	}
+
+	connector = vc4_hdmi_connector_init(dev, encoder);
+	if (IS_ERR(connector)) {
+		ret = PTR_ERR(connector);
+		dev_err(dev->dev, "failed to initialize HDMI connector\n");
+		goto fail;
+	}
+
+fail:
+	return ret;
+}
+
+int vc4_kms_load(struct drm_device *dev)
+{
+	int ret;
+
+	ret = drm_vblank_init(dev, dev->mode_config.num_crtc);
+	if (ret < 0) {
+		dev_err(dev->dev, "failed to initialize vblank\n");
+		return ret;
+	}
+
+	dev->mode_config.max_width = 2048;
+	dev->mode_config.max_height = 2048;
+	dev->mode_config.funcs = &vc4_mode_funcs;
+	dev->mode_config.preferred_depth = 24;
+
+	ret = vc4_init_modeset_objects(dev);
+	if (ret)
+		goto fail;
+
+	drm_mode_config_reset(dev);
+
+	drm_fbdev_cma_init(dev, 32,
+			   dev->mode_config.num_crtc,
+			   dev->mode_config.num_connector);
+
+	drm_kms_helper_poll_init(dev);
+
+fail:
+	return ret;
+}
diff --git a/drivers/gpu/drm/vc4/vc4_plane.c b/drivers/gpu/drm/vc4/vc4_plane.c
new file mode 100644
index 0000000..cdd8b10
--- /dev/null
+++ b/drivers/gpu/drm/vc4/vc4_plane.c
@@ -0,0 +1,320 @@
+/*
+ * Copyright (C) 2015 Broadcom
+ *
+ * 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.
+ */
+
+/**
+ * DOC: VC4 plane module
+ *
+ * Each DRM plane is a layer of pixels being scanned out by the HVS.
+ *
+ * At atomic modeset check time, we compute the HVS display element
+ * state that would be necessary for displaying the plane (giving us a
+ * chance to figure out if a plane configuration is invalid), then at
+ * atomic flush time the CRTC will ask us to write our element state
+ * into the region of the HVS that it has allocated for us.
+ */
+
+#include "vc4_drv.h"
+#include "vc4_regs.h"
+#include "drm_atomic_helper.h"
+#include "drm_fb_cma_helper.h"
+#include "drm_plane_helper.h"
+
+struct vc4_plane_state {
+	struct drm_plane_state base;
+	u32 *dlist;
+	u32 dlist_size; /* Number of dwords in allocated for the display list */
+	u32 dlist_count; /* Number of used dwords in the display list. */
+};
+
+static inline struct vc4_plane_state *
+to_vc4_plane_state(struct drm_plane_state *state)
+{
+	return (struct vc4_plane_state *)state;
+}
+
+static const struct hvs_format {
+	u32 drm; /* DRM_FORMAT_* */
+	u32 hvs; /* HVS_FORMAT_* */
+	u32 pixel_order;
+	bool has_alpha;
+} hvs_formats[] = {
+	{
+		.drm = DRM_FORMAT_XRGB8888, .hvs = HVS_PIXEL_FORMAT_RGBA8888,
+		.pixel_order = HVS_PIXEL_ORDER_ABGR, .has_alpha = false,
+	},
+	{
+		.drm = DRM_FORMAT_ARGB8888, .hvs = HVS_PIXEL_FORMAT_RGBA8888,
+		.pixel_order = HVS_PIXEL_ORDER_ABGR, .has_alpha = true,
+	},
+};
+
+static const struct hvs_format *vc4_get_hvs_format(u32 drm_format)
+{
+	unsigned i;
+
+	for (i = 0; i < ARRAY_SIZE(hvs_formats); i++) {
+		if (hvs_formats[i].drm == drm_format)
+			return &hvs_formats[i];
+	}
+
+	return NULL;
+}
+
+static bool plane_enabled(struct drm_plane_state *state)
+{
+	return state->fb && state->crtc;
+}
+
+struct drm_plane_state *vc4_plane_duplicate_state(struct drm_plane *plane)
+{
+	struct vc4_plane_state *vc4_state;
+
+	if (WARN_ON(!plane->state))
+		return NULL;
+
+	vc4_state = kmemdup(plane->state, sizeof(*vc4_state), GFP_KERNEL);
+	if (!vc4_state)
+		return NULL;
+
+	__drm_atomic_helper_plane_duplicate_state(plane, &vc4_state->base);
+
+	if (vc4_state->dlist) {
+		vc4_state->dlist = kmemdup(vc4_state->dlist,
+					   vc4_state->dlist_count * 4,
+					   GFP_KERNEL);
+		if (!vc4_state->dlist) {
+			kfree(vc4_state);
+			return NULL;
+		}
+		vc4_state->dlist_size = vc4_state->dlist_count;
+	}
+
+	return &vc4_state->base;
+}
+
+void vc4_plane_destroy_state(struct drm_plane *plane,
+			     struct drm_plane_state *state)
+{
+	struct vc4_plane_state *vc4_state = to_vc4_plane_state(state);
+
+	kfree(vc4_state->dlist);
+	__drm_atomic_helper_plane_destroy_state(plane, &vc4_state->base);
+	kfree(state);
+}
+
+/* Called during init to allocate the plane's atomic state. */
+void vc4_plane_reset(struct drm_plane *plane)
+{
+	struct vc4_plane_state *vc4_state;
+
+	WARN_ON(plane->state);
+
+	vc4_state = kzalloc(sizeof(*vc4_state), GFP_KERNEL);
+	if (!vc4_state)
+		return;
+
+	plane->state = &vc4_state->base;
+	vc4_state->base.plane = plane;
+}
+
+static void vc4_dlist_write(struct vc4_plane_state *vc4_state, u32 val)
+{
+	if (vc4_state->dlist_count == vc4_state->dlist_size) {
+		u32 new_size = max(4u, vc4_state->dlist_count * 2);
+		u32 *new_dlist = kmalloc(new_size * 4, GFP_KERNEL);
+
+		if (!new_dlist)
+			return;
+		memcpy(new_dlist, vc4_state->dlist, vc4_state->dlist_count * 4);
+
+		kfree(vc4_state->dlist);
+		vc4_state->dlist = new_dlist;
+		vc4_state->dlist_size = new_size;
+	}
+
+	vc4_state->dlist[vc4_state->dlist_count++] = val;
+}
+
+/* Writes out a full display list for an active plane to the plane's
+ * private dlist state.
+ */
+static int vc4_plane_mode_set(struct drm_plane *plane,
+			      struct drm_plane_state *state)
+{
+	struct vc4_plane_state *vc4_state = to_vc4_plane_state(state);
+	struct drm_framebuffer *fb = state->fb;
+	struct drm_gem_cma_object *bo = drm_fb_cma_get_gem_obj(fb, 0);
+	u32 ctl0_offset = vc4_state->dlist_count;
+	const struct hvs_format *format = vc4_get_hvs_format(fb->pixel_format);
+	uint32_t offset = fb->offsets[0];
+	int crtc_x = state->crtc_x;
+	int crtc_y = state->crtc_y;
+	int crtc_w = state->crtc_w;
+	int crtc_h = state->crtc_h;
+
+	if (crtc_x < 0) {
+		offset += drm_format_plane_cpp(fb->pixel_format, 0) * -crtc_x;
+		crtc_w += crtc_x;
+		crtc_x = 0;
+	}
+
+	if (crtc_y < 0) {
+		offset += fb->pitches[0] * -crtc_y;
+		crtc_h += crtc_y;
+		crtc_y = 0;
+	}
+
+	vc4_dlist_write(vc4_state,
+			SCALER_CTL0_VALID |
+			(format->pixel_order << SCALER_CTL0_ORDER_SHIFT) |
+			(format->hvs << SCALER_CTL0_PIXEL_FORMAT_SHIFT) |
+			SCALER_CTL0_UNITY);
+
+	/* Position Word 0: Image Positions and Alpha Value */
+	vc4_dlist_write(vc4_state,
+			VC4_SET_FIELD(0xff, SCALER_POS0_FIXED_ALPHA) |
+			VC4_SET_FIELD(crtc_x, SCALER_POS0_START_X) |
+			VC4_SET_FIELD(crtc_y, SCALER_POS0_START_Y));
+
+	/* Position Word 1: Scaled Image Dimensions.
+	 * Skipped due to SCALER_CTL0_UNITY scaling.
+	 */
+
+	/* Position Word 2: Source Image Size, Alpha Mode */
+	vc4_dlist_write(vc4_state,
+			VC4_SET_FIELD(format->has_alpha ?
+				      SCALER_POS2_ALPHA_MODE_PIPELINE :
+				      SCALER_POS2_ALPHA_MODE_FIXED,
+				      SCALER_POS2_ALPHA_MODE) |
+			VC4_SET_FIELD(crtc_w, SCALER_POS2_WIDTH) |
+			VC4_SET_FIELD(crtc_h, SCALER_POS2_HEIGHT));
+
+	/* Position Word 3: Context.  Written by the HVS. */
+	vc4_dlist_write(vc4_state, 0xc0c0c0c0);
+
+	/* Pointer Word 0: RGB / Y Pointer */
+	vc4_dlist_write(vc4_state, bo->paddr + offset);
+
+	/* Pointer Context Word 0: Written by the HVS */
+	vc4_dlist_write(vc4_state, 0xc0c0c0c0);
+
+	/* Pitch word 0: Pointer 0 Pitch */
+	vc4_dlist_write(vc4_state,
+			VC4_SET_FIELD(fb->pitches[0], SCALER_SRC_PITCH));
+
+	vc4_state->dlist[ctl0_offset] |=
+		VC4_SET_FIELD(vc4_state->dlist_count, SCALER_CTL0_SIZE);
+
+	return 0;
+}
+
+/* If a modeset involves changing the setup of a plane, the atomic
+ * infrastructure will call this to validate a proposed plane setup.
+ * However, if a plane isn't getting updated, this (and the
+ * corresponding vc4_plane_atomic_update) won't get called.  Thus, we
+ * compute the dlist here and have all active plane dlists get updated
+ * in the CRTC's flush.
+ */
+static int vc4_plane_atomic_check(struct drm_plane *plane,
+				  struct drm_plane_state *state)
+{
+	struct vc4_plane_state *vc4_state = to_vc4_plane_state(state);
+
+	vc4_state->dlist_count = 0;
+
+	if (plane_enabled(state))
+		return vc4_plane_mode_set(plane, state);
+	else
+		return 0;
+}
+
+static void vc4_plane_atomic_update(struct drm_plane *plane,
+				    struct drm_plane_state *old_state)
+{
+	/* No contents here.  Since we don't know where in the CRTC's
+	 * dlist we should be stored, our dlist is uploaded to the
+	 * hardware with vc4_plane_write_dlist() at CRTC atomic_flush
+	 * time.
+	 */
+}
+
+u32 vc4_plane_write_dlist(struct drm_plane *plane, u32 __iomem *dlist)
+{
+	struct vc4_plane_state *vc4_state = to_vc4_plane_state(plane->state);
+	int i;
+
+	/* Can't memcpy_toio() because it needs to be 32-bit writes. */
+	for (i = 0; i < vc4_state->dlist_count; i++)
+		writel(vc4_state->dlist[i], &dlist[i]);
+
+	return vc4_state->dlist_count;
+}
+
+u32 vc4_plane_dlist_size(struct drm_plane_state *state)
+{
+	struct vc4_plane_state *vc4_state = to_vc4_plane_state(state);
+
+	return vc4_state->dlist_count;
+}
+
+static const struct drm_plane_helper_funcs vc4_plane_helper_funcs = {
+	.prepare_fb = NULL,
+	.cleanup_fb = NULL,
+	.atomic_check = vc4_plane_atomic_check,
+	.atomic_update = vc4_plane_atomic_update,
+};
+
+static void vc4_plane_destroy(struct drm_plane *plane)
+{
+	drm_plane_helper_disable(plane);
+	drm_plane_cleanup(plane);
+}
+
+static const struct drm_plane_funcs vc4_plane_funcs = {
+	.update_plane = drm_atomic_helper_update_plane,
+	.disable_plane = drm_atomic_helper_disable_plane,
+	.destroy = vc4_plane_destroy,
+	.set_property = NULL,
+	.reset = vc4_plane_reset,
+	.atomic_duplicate_state = vc4_plane_duplicate_state,
+	.atomic_destroy_state = vc4_plane_destroy_state,
+};
+
+struct drm_plane *vc4_plane_init(struct drm_device *dev,
+				 enum drm_plane_type type)
+{
+	struct drm_plane *plane = NULL;
+	struct vc4_plane *vc4_plane;
+	u32 formats[ARRAY_SIZE(hvs_formats)];
+	int ret = 0;
+	unsigned i;
+
+	vc4_plane = devm_kzalloc(dev->dev, sizeof(*vc4_plane),
+				 GFP_KERNEL);
+	if (!vc4_plane) {
+		ret = -ENOMEM;
+		goto fail;
+	}
+
+	for (i = 0; i < ARRAY_SIZE(hvs_formats); i++)
+		formats[i] = hvs_formats[i].drm;
+	plane = &vc4_plane->base;
+	ret = drm_universal_plane_init(dev, plane, 0xff,
+				       &vc4_plane_funcs,
+				       formats, ARRAY_SIZE(formats),
+				       type);
+
+	drm_plane_helper_add(plane, &vc4_plane_helper_funcs);
+
+	return plane;
+fail:
+	if (plane)
+		vc4_plane_destroy(plane);
+
+	return ERR_PTR(ret);
+}
diff --git a/drivers/gpu/drm/vc4/vc4_regs.h b/drivers/gpu/drm/vc4/vc4_regs.h
new file mode 100644
index 0000000..0eff631
--- /dev/null
+++ b/drivers/gpu/drm/vc4/vc4_regs.h
@@ -0,0 +1,562 @@
+/*
+ *  Copyright ? 2014-2015 Broadcom
+ *
+ * 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.
+ */
+
+#define VC4_MASK(high, low) (((1 << ((high) - (low) + 1)) - 1) << (low))
+/* Using the GNU statement expression extension */
+#define VC4_SET_FIELD(value, field)					\
+	({								\
+		uint32_t fieldval = (value) << field##_SHIFT;		\
+		WARN_ON((fieldval & ~field##_MASK) != 0);		\
+		fieldval & field##_MASK;				\
+	 })
+
+#define VC4_GET_FIELD(word, field) (((word) & field##_MASK) >>		\
+				    field##_SHIFT)
+
+#define V3D_IDENT0   0x00000
+# define V3D_EXPECTED_IDENT0 \
+	((2 << 24) | \
+	('V' << 0) | \
+	('3' << 8) | \
+	 ('D' << 16))
+
+#define V3D_IDENT1   0x00004
+/* Multiples of 1kb */
+# define V3D_IDENT1_VPM_SIZE_MASK                      VC4_MASK(31, 28)
+# define V3D_IDENT1_VPM_SIZE_SHIFT                     28
+# define V3D_IDENT1_NSEM_MASK                          VC4_MASK(23, 16)
+# define V3D_IDENT1_NSEM_SHIFT                         16
+# define V3D_IDENT1_TUPS_MASK                          VC4_MASK(15, 12)
+# define V3D_IDENT1_TUPS_SHIFT                         12
+# define V3D_IDENT1_QUPS_MASK                          VC4_MASK(11, 8)
+# define V3D_IDENT1_QUPS_SHIFT                         8
+# define V3D_IDENT1_NSLC_MASK                          VC4_MASK(7, 4)
+# define V3D_IDENT1_NSLC_SHIFT                         4
+# define V3D_IDENT1_REV_MASK                           VC4_MASK(3, 0)
+# define V3D_IDENT1_REV_SHIFT                          0
+
+#define V3D_IDENT2   0x00008
+#define V3D_SCRATCH  0x00010
+#define V3D_L2CACTL  0x00020
+# define V3D_L2CACTL_L2CCLR                            (1 << 2)
+# define V3D_L2CACTL_L2CDIS                            (1 << 1)
+# define V3D_L2CACTL_L2CENA                            (1 << 0)
+
+#define V3D_SLCACTL  0x00024
+# define V3D_SLCACTL_T1CC_MASK                         VC4_MASK(27, 24)
+# define V3D_SLCACTL_T1CC_SHIFT                        24
+# define V3D_SLCACTL_T0CC_MASK                         VC4_MASK(19, 16)
+# define V3D_SLCACTL_T0CC_SHIFT                        16
+# define V3D_SLCACTL_UCC_MASK                          VC4_MASK(11, 8)
+# define V3D_SLCACTL_UCC_SHIFT                         8
+# define V3D_SLCACTL_ICC_MASK                          VC4_MASK(3, 0)
+# define V3D_SLCACTL_ICC_SHIFT                         0
+
+#define V3D_INTCTL   0x00030
+#define V3D_INTENA   0x00034
+#define V3D_INTDIS   0x00038
+# define V3D_INT_SPILLUSE                              (1 << 3)
+# define V3D_INT_OUTOMEM                               (1 << 2)
+# define V3D_INT_FLDONE                                (1 << 1)
+# define V3D_INT_FRDONE                                (1 << 0)
+
+#define V3D_CT0CS    0x00100
+#define V3D_CT1CS    0x00104
+#define V3D_CTNCS(n) (V3D_CT0CS + 4 * n)
+# define V3D_CTRSTA      (1 << 15)
+# define V3D_CTSEMA      (1 << 12)
+# define V3D_CTRTSD      (1 << 8)
+# define V3D_CTRUN       (1 << 5)
+# define V3D_CTSUBS      (1 << 4)
+# define V3D_CTERR       (1 << 3)
+# define V3D_CTMODE      (1 << 0)
+
+#define V3D_CT0EA    0x00108
+#define V3D_CT1EA    0x0010c
+#define V3D_CTNEA(n) (V3D_CT0EA + 4 * (n))
+#define V3D_CT0CA    0x00110
+#define V3D_CT1CA    0x00114
+#define V3D_CTNCA(n) (V3D_CT0CA + 4 * (n))
+#define V3D_CT00RA0  0x00118
+#define V3D_CT01RA0  0x0011c
+#define V3D_CTNRA0(n) (V3D_CT00RA0 + 4 * (n))
+#define V3D_CT0LC    0x00120
+#define V3D_CT1LC    0x00124
+#define V3D_CTNLC(n) (V3D_CT0LC + 4 * (n))
+#define V3D_CT0PC    0x00128
+#define V3D_CT1PC    0x0012c
+#define V3D_CTNPC(n) (V3D_CT0PC + 4 * (n))
+
+#define V3D_PCS      0x00130
+# define V3D_BMOOM       (1 << 8)
+# define V3D_RMBUSY      (1 << 3)
+# define V3D_RMACTIVE    (1 << 2)
+# define V3D_BMBUSY      (1 << 1)
+# define V3D_BMACTIVE    (1 << 0)
+
+#define V3D_BFC      0x00134
+#define V3D_RFC      0x00138
+#define V3D_BPCA     0x00300
+#define V3D_BPCS     0x00304
+#define V3D_BPOA     0x00308
+#define V3D_BPOS     0x0030c
+#define V3D_BXCF     0x00310
+#define V3D_SQRSV0   0x00410
+#define V3D_SQRSV1   0x00414
+#define V3D_SQCNTL   0x00418
+#define V3D_SRQPC    0x00430
+#define V3D_SRQUA    0x00434
+#define V3D_SRQUL    0x00438
+#define V3D_SRQCS    0x0043c
+#define V3D_VPACNTL  0x00500
+#define V3D_VPMBASE  0x00504
+#define V3D_PCTRC    0x00670
+#define V3D_PCTRE    0x00674
+#define V3D_PCTR0    0x00680
+#define V3D_PCTRS0   0x00684
+#define V3D_PCTR1    0x00688
+#define V3D_PCTRS1   0x0068c
+#define V3D_PCTR2    0x00690
+#define V3D_PCTRS2   0x00694
+#define V3D_PCTR3    0x00698
+#define V3D_PCTRS3   0x0069c
+#define V3D_PCTR4    0x006a0
+#define V3D_PCTRS4   0x006a4
+#define V3D_PCTR5    0x006a8
+#define V3D_PCTRS5   0x006ac
+#define V3D_PCTR6    0x006b0
+#define V3D_PCTRS6   0x006b4
+#define V3D_PCTR7    0x006b8
+#define V3D_PCTRS7   0x006bc
+#define V3D_PCTR8    0x006c0
+#define V3D_PCTRS8   0x006c4
+#define V3D_PCTR9    0x006c8
+#define V3D_PCTRS9   0x006cc
+#define V3D_PCTR10   0x006d0
+#define V3D_PCTRS10  0x006d4
+#define V3D_PCTR11   0x006d8
+#define V3D_PCTRS11  0x006dc
+#define V3D_PCTR12   0x006e0
+#define V3D_PCTRS12  0x006e4
+#define V3D_PCTR13   0x006e8
+#define V3D_PCTRS13  0x006ec
+#define V3D_PCTR14   0x006f0
+#define V3D_PCTRS14  0x006f4
+#define V3D_PCTR15   0x006f8
+#define V3D_PCTRS15  0x006fc
+#define V3D_BGE      0x00f00
+#define V3D_FDBGO    0x00f04
+#define V3D_FDBGB    0x00f08
+#define V3D_FDBGR    0x00f0c
+#define V3D_FDBGS    0x00f10
+#define V3D_ERRSTAT  0x00f20
+
+#define PV_CONTROL				0x00
+# define PV_CONTROL_FORMAT_MASK			VC4_MASK(23, 21)
+# define PV_CONTROL_FORMAT_SHIFT		21
+# define PV_CONTROL_FORMAT_24			0
+# define PV_CONTROL_FORMAT_DSIV_16		1
+# define PV_CONTROL_FORMAT_DSIC_16		2
+# define PV_CONTROL_FORMAT_DSIV_18		3
+# define PV_CONTROL_FORMAT_DSIV_24		4
+
+# define PV_CONTROL_FIFO_LEVEL_MASK		VC4_MASK(20, 15)
+# define PV_CONTROL_FIFO_LEVEL_SHIFT		15
+# define PV_CONTROL_CLR_AT_START		(1 << 14)
+# define PV_CONTROL_TRIGGER_UNDERFLOW		(1 << 13)
+# define PV_CONTROL_WAIT_HSTART			(1 << 12)
+# define PV_CONTROL_CLK_SELECT_DSI		0
+# define PV_CONTROL_CLK_SELECT_DPI_SMI_HDMI	1
+# define PV_CONTROL_CLK_SELECT_MASK		VC4_MASK(3, 2)
+# define PV_CONTROL_CLK_SELECT_SHIFT		2
+# define PV_CONTROL_FIFO_CLR			(1 << 1)
+# define PV_CONTROL_EN				(1 << 0)
+
+#define PV_V_CONTROL				0x04
+# define PV_VCONTROL_CONTINUOUS			(1 << 1)
+# define PV_VCONTROL_VIDEN			(1 << 0)
+
+#define PV_VSYNCD				0x08
+
+#define PV_HORZA				0x0c
+# define PV_HORZA_HBP_MASK			VC4_MASK(31, 16)
+# define PV_HORZA_HBP_SHIFT			16
+# define PV_HORZA_HSYNC_MASK			VC4_MASK(15, 0)
+# define PV_HORZA_HSYNC_SHIFT			0
+
+#define PV_HORZB				0x10
+# define PV_HORZB_HFP_MASK			VC4_MASK(31, 16)
+# define PV_HORZB_HFP_SHIFT			16
+# define PV_HORZB_HACTIVE_MASK			VC4_MASK(15, 0)
+# define PV_HORZB_HACTIVE_SHIFT			0
+
+#define PV_VERTA				0x14
+# define PV_VERTA_VBP_MASK			VC4_MASK(31, 16)
+# define PV_VERTA_VBP_SHIFT			16
+# define PV_VERTA_VSYNC_MASK			VC4_MASK(15, 0)
+# define PV_VERTA_VSYNC_SHIFT			0
+
+#define PV_VERTB				0x18
+# define PV_VERTB_VFP_MASK			VC4_MASK(31, 16)
+# define PV_VERTB_VFP_SHIFT			16
+# define PV_VERTB_VACTIVE_MASK			VC4_MASK(15, 0)
+# define PV_VERTB_VACTIVE_SHIFT			0
+
+#define PV_VERTA_EVEN				0x1c
+#define PV_VERTB_EVEN				0x20
+
+#define PV_INTEN				0x24
+#define PV_INTSTAT				0x28
+# define PV_INT_VID_IDLE			(1 << 9)
+# define PV_INT_VFP_END				(1 << 8)
+# define PV_INT_VFP_START			(1 << 7)
+# define PV_INT_VACT_START			(1 << 6)
+# define PV_INT_VBP_START			(1 << 5)
+# define PV_INT_VSYNC_START			(1 << 4)
+# define PV_INT_HFP_START			(1 << 3)
+# define PV_INT_HACT_START			(1 << 2)
+# define PV_INT_HBP_START			(1 << 1)
+# define PV_INT_HSYNC_START			(1 << 0)
+
+#define PV_STAT					0x2c
+
+#define PV_HACT_ACT				0x30
+
+#define SCALER_DISPCTRL                         0x00000000
+/* Global register for clock gating the HVS */
+# define SCALER_DISPCTRL_ENABLE			(1 << 31)
+# define SCALER_DISPCTRL_DSP2EISLUR		(1 << 15)
+# define SCALER_DISPCTRL_DSP1EISLUR		(1 << 14)
+/* Enables Display 0 short line and underrun contribution to
+ * SCALER_DISPSTAT_IRQDISP0.  Note that short frame contributions are
+ * always enabled.
+ */
+# define SCALER_DISPCTRL_DSP0EISLUR		(1 << 13)
+# define SCALER_DISPCTRL_DSP2EIEOLN		(1 << 12)
+# define SCALER_DISPCTRL_DSP2EIEOF		(1 << 11)
+# define SCALER_DISPCTRL_DSP1EIEOLN		(1 << 10)
+# define SCALER_DISPCTRL_DSP1EIEOF		(1 << 9)
+/* Enables Display 0 end-of-line-N contribution to
+ * SCALER_DISPSTAT_IRQDISP0
+ */
+# define SCALER_DISPCTRL_DSP0EIEOLN		(1 << 8)
+/* Enables Display 0 EOF contribution to SCALER_DISPSTAT_IRQDISP0 */
+# define SCALER_DISPCTRL_DSP0EIEOF		(1 << 7)
+
+# define SCALER_DISPCTRL_SLVRDEIRQ		(1 << 6)
+# define SCALER_DISPCTRL_SLVWREIRQ		(1 << 5)
+# define SCALER_DISPCTRL_DMAEIRQ		(1 << 4)
+# define SCALER_DISPCTRL_DISP2EIRQ		(1 << 3)
+# define SCALER_DISPCTRL_DISP1EIRQ		(1 << 2)
+/* Enables interrupt generation on the enabled EOF/EOLN/EISLUR
+ * bits and short frames..
+ */
+# define SCALER_DISPCTRL_DISP0EIRQ		(1 << 1)
+/* Enables interrupt generation on scaler profiler interrupt. */
+# define SCALER_DISPCTRL_SCLEIRQ		(1 << 0)
+
+#define SCALER_DISPSTAT                         0x00000004
+# define SCALER_DISPSTAT_COBLOW2		(1 << 29)
+# define SCALER_DISPSTAT_EOLN2			(1 << 28)
+# define SCALER_DISPSTAT_ESFRAME2		(1 << 27)
+# define SCALER_DISPSTAT_ESLINE2		(1 << 26)
+# define SCALER_DISPSTAT_EUFLOW2		(1 << 25)
+# define SCALER_DISPSTAT_EOF2			(1 << 24)
+
+# define SCALER_DISPSTAT_COBLOW1		(1 << 21)
+# define SCALER_DISPSTAT_EOLN1			(1 << 20)
+# define SCALER_DISPSTAT_ESFRAME1		(1 << 19)
+# define SCALER_DISPSTAT_ESLINE1		(1 << 18)
+# define SCALER_DISPSTAT_EUFLOW1		(1 << 17)
+# define SCALER_DISPSTAT_EOF1			(1 << 16)
+
+# define SCALER_DISPSTAT_RESP_MASK		VC4_MASK(15, 14)
+# define SCALER_DISPSTAT_RESP_SHIFT		14
+# define SCALER_DISPSTAT_RESP_OKAY		0
+# define SCALER_DISPSTAT_RESP_EXOKAY		1
+# define SCALER_DISPSTAT_RESP_SLVERR		2
+# define SCALER_DISPSTAT_RESP_DECERR		3
+
+# define SCALER_DISPSTAT_COBLOW0		(1 << 13)
+/* Set when the DISPEOLN line is done compositing. */
+# define SCALER_DISPSTAT_EOLN0			(1 << 12)
+/* Set when VSTART is seen but there are still pixels in the current
+ * output line.
+ */
+# define SCALER_DISPSTAT_ESFRAME0		(1 << 11)
+/* Set when HSTART is seen but there are still pixels in the current
+ * output line.
+ */
+# define SCALER_DISPSTAT_ESLINE0		(1 << 10)
+/* Set when the the downstream tries to read from the display FIFO
+ * while it's empty.
+ */
+# define SCALER_DISPSTAT_EUFLOW0		(1 << 9)
+/* Set when the display mode changes from RUN to EOF */
+# define SCALER_DISPSTAT_EOF0			(1 << 8)
+
+/* Set on AXI invalid DMA ID error. */
+# define SCALER_DISPSTAT_DMA_ERROR		(1 << 7)
+/* Set on AXI slave read decode error */
+# define SCALER_DISPSTAT_IRQSLVRD		(1 << 6)
+/* Set on AXI slave write decode error */
+# define SCALER_DISPSTAT_IRQSLVWR		(1 << 5)
+/* Set when SCALER_DISPSTAT_DMA_ERROR is set, or
+ * SCALER_DISPSTAT_RESP_ERROR is not SCALER_DISPSTAT_RESP_OKAY.
+ */
+# define SCALER_DISPSTAT_IRQDMA			(1 << 4)
+# define SCALER_DISPSTAT_IRQDISP2		(1 << 3)
+# define SCALER_DISPSTAT_IRQDISP1		(1 << 2)
+/* Set when any of the EOF/EOLN/ESFRAME/ESLINE bits are set and their
+ * corresponding interrupt bit is enabled in DISPCTRL.
+ */
+# define SCALER_DISPSTAT_IRQDISP0		(1 << 1)
+/* On read, the profiler interrupt.  On write, clear *all* interrupt bits. */
+# define SCALER_DISPSTAT_IRQSCL			(1 << 0)
+
+#define SCALER_DISPID                           0x00000008
+#define SCALER_DISPECTRL                        0x0000000c
+#define SCALER_DISPPROF                         0x00000010
+#define SCALER_DISPDITHER                       0x00000014
+#define SCALER_DISPEOLN                         0x00000018
+#define SCALER_DISPLIST0                        0x00000020
+#define SCALER_DISPLIST1                        0x00000024
+#define SCALER_DISPLIST2                        0x00000028
+#define SCALER_DISPLSTAT                        0x0000002c
+#define SCALER_DISPLISTX(x)			(SCALER_DISPLIST0 +	\
+						 (x) * (SCALER_DISPLIST1 - \
+							SCALER_DISPLIST0))
+
+#define SCALER_DISPLACT0                        0x00000030
+#define SCALER_DISPLACT1                        0x00000034
+#define SCALER_DISPLACT2                        0x00000038
+#define SCALER_DISPCTRL0                        0x00000040
+# define SCALER_DISPCTRLX_ENABLE		(1 << 31)
+# define SCALER_DISPCTRLX_RESET			(1 << 30)
+# define SCALER_DISPCTRLX_WIDTH_MASK		VC4_MASK(23, 12)
+# define SCALER_DISPCTRLX_WIDTH_SHIFT		12
+# define SCALER_DISPCTRLX_HEIGHT_MASK		VC4_MASK(11, 0)
+# define SCALER_DISPCTRLX_HEIGHT_SHIFT		0
+
+#define SCALER_DISPBKGND0                       0x00000044
+#define SCALER_DISPSTAT0                        0x00000048
+#define SCALER_DISPBASE0                        0x0000004c
+# define SCALER_DISPSTATX_MODE_MASK		VC4_MASK(31, 30)
+# define SCALER_DISPSTATX_MODE_SHIFT		30
+# define SCALER_DISPSTATX_MODE_DISABLED		0
+# define SCALER_DISPSTATX_MODE_INIT		1
+# define SCALER_DISPSTATX_MODE_RUN		2
+# define SCALER_DISPSTATX_MODE_EOF		3
+# define SCALER_DISPSTATX_FULL			(1 << 29)
+# define SCALER_DISPSTATX_EMPTY			(1 << 28)
+#define SCALER_DISPCTRL1                        0x00000050
+#define SCALER_DISPBKGND1                       0x00000054
+#define SCALER_DISPSTAT1                        0x00000058
+#define SCALER_DISPSTATX(x)			(SCALER_DISPSTAT0 +        \
+						 (x) * (SCALER_DISPSTAT1 - \
+							SCALER_DISPSTAT0))
+#define SCALER_DISPBASE1                        0x0000005c
+#define SCALER_DISPCTRL2                        0x00000060
+#define SCALER_DISPCTRLX(x)			(SCALER_DISPCTRL0 +        \
+						 (x) * (SCALER_DISPCTRL1 - \
+							SCALER_DISPCTRL0))
+#define SCALER_DISPBKGND2                       0x00000064
+#define SCALER_DISPSTAT2                        0x00000068
+#define SCALER_DISPBASE2                        0x0000006c
+#define SCALER_DISPALPHA2                       0x00000070
+#define SCALER_GAMADDR                          0x00000078
+#define SCALER_GAMDATA                          0x000000e0
+#define SCALER_DLIST_START                      0x00002000
+#define SCALER_DLIST_SIZE                       0x00004000
+
+#define VC4_HDMI_CORE_REV			0x000
+
+#define VC4_HDMI_SW_RESET_CONTROL		0x004
+# define VC4_HDMI_SW_RESET_FORMAT_DETECT	(1 << 1)
+# define VC4_HDMI_SW_RESET_HDMI			(1 << 0)
+
+#define VC4_HDMI_HOTPLUG_INT			0x008
+
+#define VC4_HDMI_HOTPLUG			0x00c
+# define VC4_HDMI_HOTPLUG_CONNECTED		(1 << 0)
+
+#define VC4_HDMI_RAM_PACKET_CONFIG		0x0a0
+# define VC4_HDMI_RAM_PACKET_ENABLE		(1 << 16)
+
+#define VC4_HDMI_HORZA				0x0c4
+# define VC4_HDMI_HORZA_VPOS			(1 << 14)
+# define VC4_HDMI_HORZA_HPOS			(1 << 13)
+/* Horizontal active pixels (hdisplay). */
+# define VC4_HDMI_HORZA_HAP_MASK		VC4_MASK(12, 0)
+# define VC4_HDMI_HORZA_HAP_SHIFT		0
+
+#define VC4_HDMI_HORZB				0x0c8
+/* Horizontal pack porch (htotal - hsync_end). */
+# define VC4_HDMI_HORZB_HBP_MASK		VC4_MASK(29, 20)
+# define VC4_HDMI_HORZB_HBP_SHIFT		20
+/* Horizontal sync pulse (hsync_end - hsync_start). */
+# define VC4_HDMI_HORZB_HSP_MASK		VC4_MASK(19, 10)
+# define VC4_HDMI_HORZB_HSP_SHIFT		10
+/* Horizontal front porch (hsync_start - hdisplay). */
+# define VC4_HDMI_HORZB_HFP_MASK		VC4_MASK(9, 0)
+# define VC4_HDMI_HORZB_HFP_SHIFT		0
+
+#define VC4_HDMI_FIFO_CTL			0x05c
+# define VC4_HDMI_FIFO_CTL_RECENTER_DONE	(1 << 14)
+# define VC4_HDMI_FIFO_CTL_USE_EMPTY		(1 << 13)
+# define VC4_HDMI_FIFO_CTL_ON_VB		(1 << 7)
+# define VC4_HDMI_FIFO_CTL_RECENTER		(1 << 6)
+# define VC4_HDMI_FIFO_CTL_FIFO_RESET		(1 << 5)
+# define VC4_HDMI_FIFO_CTL_USE_PLL_LOCK		(1 << 4)
+# define VC4_HDMI_FIFO_CTL_INV_CLK_XFR		(1 << 3)
+# define VC4_HDMI_FIFO_CTL_CAPTURE_PTR		(1 << 2)
+# define VC4_HDMI_FIFO_CTL_USE_FULL		(1 << 1)
+# define VC4_HDMI_FIFO_CTL_MASTER_SLAVE_N	(1 << 0)
+# define VC4_HDMI_FIFO_VALID_WRITE_MASK		0xefff
+
+#define VC4_HDMI_SCHEDULER_CONTROL		0x0c0
+# define VC4_HDMI_SCHEDULER_CONTROL_MANUAL_FORMAT (1 << 15)
+# define VC4_HDMI_SCHEDULER_CONTROL_IGNORE_VSYNC_PREDICTS (1 << 5)
+# define VC4_HDMI_SCHEDULER_CONTROL_VERT_ALWAYS_KEEPOUT	(1 << 3)
+# define VC4_HDMI_SCHEDULER_CONTROL_HDMI_ACTIVE	(1 << 1)
+# define VC4_HDMI_SCHEDULER_CONTROL_MODE_HDMI	(1 << 0)
+
+#define VC4_HDMI_VERTA0				0x0cc
+#define VC4_HDMI_VERTA1				0x0d4
+/* Vertical sync pulse (vsync_end - vsync_start). */
+# define VC4_HDMI_VERTA_VSP_MASK		VC4_MASK(24, 20)
+# define VC4_HDMI_VERTA_VSP_SHIFT		20
+/* Vertical front porch (vsync_start - vdisplay). */
+# define VC4_HDMI_VERTA_VFP_MASK		VC4_MASK(19, 13)
+# define VC4_HDMI_VERTA_VFP_SHIFT		13
+/* Vertical active lines (vdisplay). */
+# define VC4_HDMI_VERTA_VAL_MASK		VC4_MASK(12, 0)
+# define VC4_HDMI_VERTA_VAL_SHIFT		0
+
+#define VC4_HDMI_VERTB0				0x0d0
+#define VC4_HDMI_VERTB1				0x0d8
+/* Vertical sync pulse offset (for interlaced) */
+# define VC4_HDMI_VERTB_VSPO_MASK		VC4_MASK(21, 9)
+# define VC4_HDMI_VERTB_VSPO_SHIFT		9
+/* Vertical pack porch (vtotal - vsync_end). */
+# define VC4_HDMI_VERTB_VBP_MASK		VC4_MASK(8, 0)
+# define VC4_HDMI_VERTB_VBP_SHIFT		0
+
+#define VC4_HDMI_TX_PHY_RESET_CTL		0x2c0
+
+#define VC4_HD_M_CTL				0x00c
+# define VC4_HD_M_SW_RST			(1 << 2)
+# define VC4_HD_M_ENABLE			(1 << 0)
+
+#define VC4_HD_MAI_CTL				0x014
+
+#define VC4_HD_VID_CTL				0x038
+# define VC4_HD_VID_CTL_ENABLE			(1 << 31)
+# define VC4_HD_VID_CTL_UNDERFLOW_ENABLE	(1 << 30)
+# define VC4_HD_VID_CTL_FRAME_COUNTER_RESET	(1 << 29)
+# define VC4_HD_VID_CTL_VSYNC_LOW		(1 << 28)
+# define VC4_HD_VID_CTL_HSYNC_LOW		(1 << 27)
+
+#define VC4_HD_CSC_CTL				0x040
+# define VC4_HD_CSC_CTL_ORDER_MASK		VC4_MASK(7, 5)
+# define VC4_HD_CSC_CTL_ORDER_SHIFT		5
+# define VC4_HD_CSC_CTL_ORDER_RGB		0
+# define VC4_HD_CSC_CTL_ORDER_BGR		1
+# define VC4_HD_CSC_CTL_ORDER_BRG		2
+# define VC4_HD_CSC_CTL_ORDER_GRB		3
+# define VC4_HD_CSC_CTL_ORDER_GBR		4
+# define VC4_HD_CSC_CTL_ORDER_RBG		5
+# define VC4_HD_CSC_CTL_PADMSB			(1 << 4)
+# define VC4_HD_CSC_CTL_MODE_MASK		VC4_MASK(3, 2)
+# define VC4_HD_CSC_CTL_MODE_SHIFT		2
+# define VC4_HD_CSC_CTL_MODE_RGB_TO_SD_YPRPB	0
+# define VC4_HD_CSC_CTL_MODE_RGB_TO_HD_YPRPB	1
+# define VC4_HD_CSC_CTL_MODE_CUSTOM		2
+# define VC4_HD_CSC_CTL_RGB2YCC			(1 << 1)
+# define VC4_HD_CSC_CTL_ENABLE			(1 << 0)
+
+#define VC4_HD_FRAME_COUNT			0x068
+
+/* HVS display list information. */
+#define HVS_BOOTLOADER_DLIST_END                32
+
+enum hvs_pixel_format {
+	/* 8bpp */
+	HVS_PIXEL_FORMAT_RGB332 = 0,
+	/* 16bpp */
+	HVS_PIXEL_FORMAT_RGBA4444 = 1,
+	HVS_PIXEL_FORMAT_RGB555 = 2,
+	HVS_PIXEL_FORMAT_RGBA5551 = 3,
+	HVS_PIXEL_FORMAT_RGB565 = 4,
+	/* 24bpp */
+	HVS_PIXEL_FORMAT_RGB888 = 5,
+	HVS_PIXEL_FORMAT_RGBA6666 = 6,
+	/* 32bpp */
+	HVS_PIXEL_FORMAT_RGBA8888 = 7
+};
+
+/* Note: the LSB is the rightmost character shown.  Only valid for
+ * HVS_PIXEL_FORMAT_RGB8888, not RGB888.
+ */
+#define HVS_PIXEL_ORDER_RGBA			0
+#define HVS_PIXEL_ORDER_BGRA			1
+#define HVS_PIXEL_ORDER_ARGB			2
+#define HVS_PIXEL_ORDER_ABGR			3
+
+#define HVS_PIXEL_ORDER_XBRG			0
+#define HVS_PIXEL_ORDER_XRBG			1
+#define HVS_PIXEL_ORDER_XRGB			2
+#define HVS_PIXEL_ORDER_XBGR			3
+
+#define HVS_PIXEL_ORDER_XYCBCR			0
+#define HVS_PIXEL_ORDER_XYCRCB			1
+#define HVS_PIXEL_ORDER_YXCBCR			2
+#define HVS_PIXEL_ORDER_YXCRCB			3
+
+#define SCALER_CTL0_END				(1 << 31)
+#define SCALER_CTL0_VALID			(1 << 30)
+
+#define SCALER_CTL0_SIZE_MASK			VC4_MASK(29, 24)
+#define SCALER_CTL0_SIZE_SHIFT			24
+
+#define SCALER_CTL0_HFLIP                       (1 << 16)
+#define SCALER_CTL0_VFLIP                       (1 << 15)
+
+#define SCALER_CTL0_ORDER_MASK			VC4_MASK(14, 13)
+#define SCALER_CTL0_ORDER_SHIFT			13
+
+/* Set to indicate no scaling. */
+#define SCALER_CTL0_UNITY			(1 << 4)
+
+#define SCALER_CTL0_PIXEL_FORMAT_MASK		VC4_MASK(3, 0)
+#define SCALER_CTL0_PIXEL_FORMAT_SHIFT		0
+
+#define SCALER_POS0_FIXED_ALPHA_MASK		VC4_MASK(31, 24)
+#define SCALER_POS0_FIXED_ALPHA_SHIFT		24
+
+#define SCALER_POS0_START_Y_MASK		VC4_MASK(23, 12)
+#define SCALER_POS0_START_Y_SHIFT		12
+
+#define SCALER_POS0_START_X_MASK		VC4_MASK(11, 0)
+#define SCALER_POS0_START_X_SHIFT		0
+
+#define SCALER_POS2_ALPHA_MODE_MASK		VC4_MASK(31, 30)
+#define SCALER_POS2_ALPHA_MODE_SHIFT		30
+#define SCALER_POS2_ALPHA_MODE_PIPELINE		0
+#define SCALER_POS2_ALPHA_MODE_FIXED		1
+#define SCALER_POS2_ALPHA_MODE_FIXED_NONZERO	2
+#define SCALER_POS2_ALPHA_MODE_FIXED_OVER_0x07	3
+
+#define SCALER_POS2_HEIGHT_MASK			VC4_MASK(27, 16)
+#define SCALER_POS2_HEIGHT_SHIFT		16
+
+#define SCALER_POS2_WIDTH_MASK			VC4_MASK(11, 0)
+#define SCALER_POS2_WIDTH_SHIFT			0
+
+#define SCALER_SRC_PITCH_MASK			VC4_MASK(15, 0)
+#define SCALER_SRC_PITCH_SHIFT			0
-- 
2.1.4



From mathieu at codeaurora.org  Tue Aug 18 15:05:37 2015
From: mathieu at codeaurora.org (Mathieu Olivari)
Date: Tue, 18 Aug 2015 15:05:37 -0700
Subject: [PATCH 1/2] ARM: qcom: add uart labels to IPQ806x dts
In-Reply-To: <1439935538-13932-1-git-send-email-mathieu@codeaurora.org>
References: <1439935538-13932-1-git-send-email-mathieu@codeaurora.org>
Message-ID: <1439935538-13932-2-git-send-email-mathieu@codeaurora.org>

We want to use references to UART devices from the board specific dts
files, so we'll label them according to their gsbi number.

Signed-off-by: Mathieu Olivari <mathieu at codeaurora.org>
---
 arch/arm/boot/dts/qcom-ipq8064.dtsi | 15 +++++++++------
 1 file changed, 9 insertions(+), 6 deletions(-)

diff --git a/arch/arm/boot/dts/qcom-ipq8064.dtsi b/arch/arm/boot/dts/qcom-ipq8064.dtsi
index 9834c94..2f270d7 100644
--- a/arch/arm/boot/dts/qcom-ipq8064.dtsi
+++ b/arch/arm/boot/dts/qcom-ipq8064.dtsi
@@ -159,8 +159,9 @@
 
 			syscon-tcsr = <&tcsr>;
 
-			serial at 12490000 {
-				compatible = "qcom,msm-uartdm-v1.3", "qcom,msm-uartdm";
+			uart2: serial at 12490000 {
+				compatible = "qcom,msm-uartdm-v1.3",
+					     "qcom,msm-uartdm";
 				reg = <0x12490000 0x1000>,
 				      <0x12480000 0x1000>;
 				interrupts = <0 195 0x0>;
@@ -197,8 +198,9 @@
 
 			syscon-tcsr = <&tcsr>;
 
-			serial at 16340000 {
-				compatible = "qcom,msm-uartdm-v1.3", "qcom,msm-uartdm";
+			uart4: serial at 16340000 {
+				compatible = "qcom,msm-uartdm-v1.3",
+					     "qcom,msm-uartdm";
 				reg = <0x16340000 0x1000>,
 				      <0x16300000 0x1000>;
 				interrupts = <0 152 0x0>;
@@ -234,8 +236,9 @@
 
 			syscon-tcsr = <&tcsr>;
 
-			serial at 1a240000 {
-				compatible = "qcom,msm-uartdm-v1.3", "qcom,msm-uartdm";
+			uart5: serial at 1a240000 {
+				compatible = "qcom,msm-uartdm-v1.3",
+					     "qcom,msm-uartdm";
 				reg = <0x1a240000 0x1000>,
 				      <0x1a200000 0x1000>;
 				interrupts = <0 154 0x0>;
-- 
2.1.4



From mathieu at codeaurora.org  Tue Aug 18 15:05:38 2015
From: mathieu at codeaurora.org (Mathieu Olivari)
Date: Tue, 18 Aug 2015 15:05:38 -0700
Subject: [PATCH 2/2] ARM: qcom: enable uart output by default on AP148
In-Reply-To: <1439935538-13932-1-git-send-email-mathieu@codeaurora.org>
References: <1439935538-13932-1-git-send-email-mathieu@codeaurora.org>
Message-ID: <1439935538-13932-3-git-send-email-mathieu@codeaurora.org>

This change adds a new chosen node to boot using UART console on AP148

Signed-off-by: Mathieu Olivari <mathieu at codeaurora.org>
---
 arch/arm/boot/dts/qcom-ipq8064-ap148.dts | 8 ++++++++
 1 file changed, 8 insertions(+)

diff --git a/arch/arm/boot/dts/qcom-ipq8064-ap148.dts b/arch/arm/boot/dts/qcom-ipq8064-ap148.dts
index 55b2910..b08907a 100644
--- a/arch/arm/boot/dts/qcom-ipq8064-ap148.dts
+++ b/arch/arm/boot/dts/qcom-ipq8064-ap148.dts
@@ -14,6 +14,14 @@
 		};
 	};
 
+	alias {
+		serial0 = &uart4;
+	};
+
+	chosen {
+		linux,stdout-path = "serial0:115200n8";
+	};
+
 	soc {
 		pinmux at 800000 {
 			i2c4_pins: i2c4_pinmux {
-- 
2.1.4



From mathieu at codeaurora.org  Tue Aug 18 15:05:36 2015
From: mathieu at codeaurora.org (Mathieu Olivari)
Date: Tue, 18 Aug 2015 15:05:36 -0700
Subject: [PATCH 0/2] ARM: qcom: enable console output on IPQ806x
Message-ID: <1439935538-13932-1-git-send-email-mathieu@codeaurora.org>

This change set adds uart nodes in ipq806x dtsi and add the chosen node
in AP148 dts file to use it as a console.

Mathieu Olivari (2):
  ARM: qcom: add uart labels to IPQ806x dts
  ARCH: qcom: enable uart output by default on AP148

 arch/arm/boot/dts/qcom-ipq8064-ap148.dts |  8 ++++++++
 arch/arm/boot/dts/qcom-ipq8064.dtsi      | 15 +++++++++------
 2 files changed, 17 insertions(+), 6 deletions(-)

-- 
2.1.4



From mathieu at codeaurora.org  Tue Aug 18 15:21:28 2015
From: mathieu at codeaurora.org (Mathieu Olivari)
Date: Tue, 18 Aug 2015 15:21:28 -0700
Subject: [PATCH] ARM: qcom: Disable i2c device on gsbi4 for ipq806x
Message-ID: <1439936488-14870-1-git-send-email-mathieu@codeaurora.org>

Disable the i2c device on gsbi4 and mark gsbi4_h and gsbi4_qup clks as
unused. If they are enabled, clock framework will turn them off at end
of probe. On ipq806x by design gsbi4_qup, gsbi4_h clks and i2c on gsbi4
are meant for RPM usage. So turning them off in kernel is incorrect.

Signed-off-by: Mathieu Olivari <mathieu at codeaurora.org>
---
 arch/arm/boot/dts/qcom-ipq8064-ap148.dts | 9 ---------
 drivers/clk/qcom/gcc-ipq806x.c           | 6 +++---
 2 files changed, 3 insertions(+), 12 deletions(-)

diff --git a/arch/arm/boot/dts/qcom-ipq8064-ap148.dts b/arch/arm/boot/dts/qcom-ipq8064-ap148.dts
index b08907a..36e2b04 100644
--- a/arch/arm/boot/dts/qcom-ipq8064-ap148.dts
+++ b/arch/arm/boot/dts/qcom-ipq8064-ap148.dts
@@ -46,15 +46,6 @@
 			serial at 16340000 {
 				status = "ok";
 			};
-
-			i2c4: i2c at 16380000 {
-				status = "ok";
-
-				clock-frequency = <200000>;
-
-				pinctrl-0 = <&i2c4_pins>;
-				pinctrl-names = "default";
-			};
 		};
 
 		gsbi5: gsbi at 1a200000 {
diff --git a/drivers/clk/qcom/gcc-ipq806x.c b/drivers/clk/qcom/gcc-ipq806x.c
index 5639699..eb4065e 100644
--- a/drivers/clk/qcom/gcc-ipq806x.c
+++ b/drivers/clk/qcom/gcc-ipq806x.c
@@ -809,7 +809,7 @@ static struct clk_rcg gsbi6_qup_src = {
 			.parent_names = gcc_pxo_pll8,
 			.num_parents = 2,
 			.ops = &clk_rcg_ops,
-			.flags = CLK_SET_PARENT_GATE,
+			.flags = CLK_SET_PARENT_GATE | CLK_IGNORE_UNUSED,
 		},
 	},
 };
@@ -874,7 +874,7 @@ static struct clk_branch gsbi7_qup_clk = {
 			.parent_names = (const char *[]){ "gsbi7_qup_src" },
 			.num_parents = 1,
 			.ops = &clk_branch_ops,
-			.flags = CLK_SET_RATE_PARENT,
+			.flags = CLK_SET_RATE_PARENT | CLK_IGNORE_UNUSED,
 		},
 	},
 };
@@ -922,7 +922,7 @@ static struct clk_branch gsbi4_h_clk = {
 		.hw.init = &(struct clk_init_data){
 			.name = "gsbi4_h_clk",
 			.ops = &clk_branch_ops,
-			.flags = CLK_IS_ROOT,
+			.flags = CLK_IS_ROOT | CLK_IGNORE_UNUSED,
 		},
 	},
 };
-- 
2.1.4



From mathieu at codeaurora.org  Tue Aug 18 15:26:44 2015
From: mathieu at codeaurora.org (Mathieu Olivari)
Date: Tue, 18 Aug 2015 15:26:44 -0700
Subject: [PATCH] ARM: qcom: add memory node to IPQ806x/AP148
Message-ID: <1439936804-15138-1-git-send-email-mathieu@codeaurora.org>

On recent bootloaders, the bootloader patches the DT blob with memory
information. However, with old bootloader, this operation doesn't
happen, which leads the board to freeze in the early init code.

This patch adds the memory node to the AP148 dts explicitly to cover all
boot cases.

Signed-off-by: Mathieu Olivari <mathieu at codeaurora.org>
---
 arch/arm/boot/dts/qcom-ipq8064-ap148.dts | 5 +++++
 1 file changed, 5 insertions(+)

diff --git a/arch/arm/boot/dts/qcom-ipq8064-ap148.dts b/arch/arm/boot/dts/qcom-ipq8064-ap148.dts
index 36e2b04..6886d09 100644
--- a/arch/arm/boot/dts/qcom-ipq8064-ap148.dts
+++ b/arch/arm/boot/dts/qcom-ipq8064-ap148.dts
@@ -4,6 +4,11 @@
 	model = "Qualcomm IPQ8064/AP148";
 	compatible = "qcom,ipq8064-ap148", "qcom,ipq8064";
 
+	memory at 0 {
+		reg = <0x42000000 0x1e000000>;
+		device_type = "memory";
+	};
+
 	reserved-memory {
 		#address-cells = <1>;
 		#size-cells = <1>;
-- 
2.1.4



From javier at osg.samsung.com  Tue Aug 18 15:28:37 2015
From: javier at osg.samsung.com (Javier Martinez Canillas)
Date: Wed, 19 Aug 2015 00:28:37 +0200
Subject: [PATCH] ARM: multi_v7_defconfig: Enable CROS_EC_PROTO for
 ChromeOS EC mfd driver
In-Reply-To: <20150818214608.GA21855@localhost>
References: <1439881827-22613-1-git-send-email-javier@osg.samsung.com>
 <20150818214608.GA21855@localhost>
Message-ID: <55D3B195.6030608@osg.samsung.com>

Hello Olof,

On 08/18/2015 11:46 PM, Olof Johansson wrote:
> On Tue, Aug 18, 2015 at 09:10:27AM +0200, Javier Martinez Canillas wrote:
>> The ChromeOS mfd driver (MFD_CROS_EC) select the CROS_EC_PROTO config
>> symbol because the driver uses some communication helper functions in
>> drivers/platform/chrome/cros_ec_proto.c but other drivers depends on
>> CROS_EC_PROTO instead. Mixing select and depends can lead to circular
>> Kconfig dependencies so the MFD_CROS_EC select should be changed to a
>> depends on CROS_EC_PROTO instead.
>>
>> But doing so will break git bisect-ability since MFD_CROS_EC will not
>> be enabled anymore unless the default configs first explicitly enable
>> the CROS_EC_PROTO dependency.
>>
>> Signed-off-by: Javier Martinez Canillas <javier at osg.samsung.com>
> 
> Applied to cros/ec-config in arm-soc, which will stay stable in case others
> need to bring in as a prereq.
>

Thanks but Bartolomiej's feedback [0] on my patch that made CROS_EC_PROTO
a user selectable option was to leave it as a non-visible option and instead
change the other Kconfig symbols to select CROS_EC_PROTO consistently.

So tomorrow I'll post a new patch series along those lines that will make
this patch obsolete since no defconfig changes will be needed.

IOW, please drop this patch and sorry for the inconvenience.

> 
> -Olof
> 

[0]: https://lkml.org/lkml/2015/8/18/231

Best regards,
-- 
Javier Martinez Canillas
Open Source Group
Samsung Research America


From tyler.baker at linaro.org  Tue Aug 18 15:30:41 2015
From: tyler.baker at linaro.org (Tyler Baker)
Date: Tue, 18 Aug 2015 15:30:41 -0700
Subject: [GIT PULL 9/9] ARM: tegra: Default configuration updates for
 v4.3-rc1
In-Reply-To: <1439563720-13189-10-git-send-email-thierry.reding@gmail.com>
References: <1439563720-13189-1-git-send-email-thierry.reding@gmail.com>
 <1439563720-13189-10-git-send-email-thierry.reding@gmail.com>
Message-ID: <CANMBJr7PKy-eCcB3HiBajpApHS_BYPa7xfKjTqV4o8Z1hwY99A@mail.gmail.com>

Hi Theirry,

On 14 August 2015 at 07:48, Thierry Reding <thierry.reding at gmail.com> wrote:
> Hi ARM SoC maintainers,
>
> The following changes since commit d770e558e21961ad6cfdf0ff7df0eb5d7d4f0754:
>
>   Linux 4.2-rc1 (2015-07-05 11:01:52 -0700)
>
> are available in the git repository at:
>
>   git://git.kernel.org/pub/scm/linux/kernel/git/tegra/linux.git tags/tegra-for-4.3-defconfig
>
> for you to fetch changes up to 258d9bc5e77fa40e290a0bd480d5349224374480:
>
>   ARM: tegra: Update multi_v7_defconfig (2015-08-14 16:26:00 +0200)
>
> Thanks,
> Thierry
>
> ----------------------------------------------------------------
> ARM: tegra: Default configuration updates for v4.3-rc1
>
> Enable the GK20A GPU (via the Nouveau driver) and CPU frequency scaling
> on Tegra124.
>
> ----------------------------------------------------------------
> Thierry Reding (1):
>       ARM: tegra: Update multi_v7_defconfig

The kernelci.org bot recently reported jetson-tk1 boot failures[1][2]
in next-20150818, only when booting the mult_v7_defconfig kernels. I
bisected[3] these boot failure down to this commit, it didn't cleanly
revert, so I manually removed that options this patch added, and my
jetson-tk1 booted again. Digging a bit further, if I apply the patch
below to next-20150818, my jetson-tk1 boots.

diff --git a/arch/arm/configs/multi_v7_defconfig
b/arch/arm/configs/multi_v7_defconfig
index b2facab..a285afe 100644
--- a/arch/arm/configs/multi_v7_defconfig
+++ b/arch/arm/configs/multi_v7_defconfig
@@ -468,7 +468,6 @@ CONFIG_FRAMEBUFFER_CONSOLE_ROTATION=y
 CONFIG_SOUND=m
 CONFIG_SND=m
 CONFIG_SND_DYNAMIC_MINORS=y
-CONFIG_SND_HDA_TEGRA=m
 CONFIG_SND_HDA_INPUT_BEEP=y
 CONFIG_SND_HDA_PATCH_LOADER=y
 CONFIG_SND_HDA_CODEC_REALTEK=m

This isn't where the story ends unfortunately. The collabora lab also
has a jetson-tk1, booted in the same manner, which boots next-20150818
fine[4]. The only differences I can spot in the two boot logs is that
the collabora board is using an older version of u-boot, where as my
board is using a newer version. U-Boot 2015.01-00231-gab77f24-dirty
(Good) vs U-Boot 2015.07-00130-gb217c89 (Bad). I've also noticed some
angry udev messages after the modules probe in userspace present in
both boot logs that look suspicious.

[   70.469914] udevd[108]: worker [113] /devices/soc0/70030000.hda is
taking a long time
[   70.479849] udevd[108]: worker [115] /devices/soc0/70300000.ahub is
taking a long time
[   70.490769] udevd[108]: worker [117] /devices/soc0/sound is taking
a long time

FWIW, When I went searching for this patch, I couldn't find it on any
of the mailing lists. The only reference to this patch was from this
pull request, thus why I'm reporting the issue here. :)

Anyways, let me know if you can reproduce this issue, and/or can think
of a reason this might may be causing trouble.

Cheers,

Tyler

[1] http://kernelci.org/boot/all/job/next/kernel/next-20150818/
[2] http://storage.kernelci.org/next/next-20150818/arm-multi_v7_defconfig/lab-tbaker/boot-tegra124-jetson-tk1.html
[3] http://hastebin.com/bixofozaji.vhdl
[4] http://storage.kernelci.org/next/next-20150818/arm-multi_v7_defconfig/lab-collabora/boot-tegra124-jetson-tk1.html


From laurent.pinchart at ideasonboard.com  Tue Aug 18 15:43:47 2015
From: laurent.pinchart at ideasonboard.com (Laurent Pinchart)
Date: Wed, 19 Aug 2015 01:43:47 +0300
Subject: [PATCH] dmaengine: vdma: Add 64 bit addressing support to the
 driver
In-Reply-To: <1438775257-3511-1-git-send-email-anuragku@xilinx.com>
References: <1438775257-3511-1-git-send-email-anuragku@xilinx.com>
Message-ID: <2214014.FVHbR3JRBK@avalon>

Hi Anurag,

Thank you for the patch.

On Wednesday 05 August 2015 17:17:37 Anurag Kumar Vulisha wrote:
> This patch adds the 64 bit addressing support to the vdma driver.
> 
> Signed-off-by: Anurag Kumar Vulisha <anuragku at xilinx.com>
> ---
>  drivers/dma/Kconfig              |    2 +-
>  drivers/dma/xilinx/xilinx_vdma.c |   36 ++++++++++++++++++++++++++++------
>  2 files changed, 31 insertions(+), 7 deletions(-)
> 
> diff --git a/drivers/dma/Kconfig b/drivers/dma/Kconfig
> index bda2cb0..a7cd0a8 100644
> --- a/drivers/dma/Kconfig
> +++ b/drivers/dma/Kconfig
> @@ -398,7 +398,7 @@ config FSL_EDMA
> 
>  config XILINX_VDMA
>  	tristate "Xilinx AXI VDMA Engine"
> -	depends on (ARCH_ZYNQ || MICROBLAZE)
> +	depends on (ARCH_ZYNQ || MICROBLAZE || ARM64)
>  	select DMA_ENGINE
>  	help
>  	  Enable support for Xilinx AXI VDMA Soft IP.
> diff --git a/drivers/dma/xilinx/xilinx_vdma.c
> b/drivers/dma/xilinx/xilinx_vdma.c index d8434d4..3dcbd29 100644
> --- a/drivers/dma/xilinx/xilinx_vdma.c
> +++ b/drivers/dma/xilinx/xilinx_vdma.c
> @@ -98,7 +98,11 @@
>  #define XILINX_VDMA_FRMDLY_STRIDE_FRMDLY_SHIFT	24
>  #define XILINX_VDMA_FRMDLY_STRIDE_STRIDE_SHIFT	0
> 
> +#if defined(CONFIG_PHYS_ADDR_T_64BIT)

Strictly speaking that should be CONFIG_ARCH_DMA_ADDR_T_64BIT.

> +#define XILINX_VDMA_REG_START_ADDRESS(n)	(0x000c + 8 * (n))
> +#else
>  #define XILINX_VDMA_REG_START_ADDRESS(n)	(0x000c + 4 * (n))
> +#endif
> 
>  /* HW specific definitions */
>  #define XILINX_VDMA_MAX_CHANS_PER_DEVICE	0x2
> @@ -143,16 +147,16 @@
>   * @next_desc: Next Descriptor Pointer @0x00
>   * @pad1: Reserved @0x04
>   * @buf_addr: Buffer address @0x08
> - * @pad2: Reserved @0x0C
> - * @vsize: Vertical Size @0x10
> - * @hsize: Horizontal Size @0x14
> + * @pad2: Reserved @0x10
> + * @vsize: Vertical Size @0x14
> + * @hsize: Horizontal Size @0x18
>   * @stride: Number of bytes between the first
> - *	    pixels of each horizontal line @0x18
> + *	    pixels of each horizontal line @0x1C
>   */
>  struct xilinx_vdma_desc_hw {
>  	u32 next_desc;
>  	u32 pad1;
> -	u32 buf_addr;
> +	u64 buf_addr;

This will change the descriptor layout for 32-bit VDMA, I don't think that's 
right.

>  	u32 pad2;
>  	u32 vsize;
>  	u32 hsize;
> @@ -272,6 +276,20 @@ static inline void vdma_desc_write(struct
> xilinx_vdma_chan *chan, u32 reg, vdma_write(chan, chan->desc_offset + reg,
> value);
>  }
> 
> +#if defined(CONFIG_PHYS_ADDR_T_64BIT)
> +static inline void vdma_desc_write_64(struct xilinx_vdma_chan *chan, u32
> reg,
> +				 u64 value)
> +{
> +	/* Write the lsb 32 bits*/
> +	writel(lower_32_bits(value),
> +			chan->xdev->regs + chan->desc_offset + reg);
> +
> +	/* Write the msb 32 bits */
> +	writel(upper_32_bits(value),
> +			chan->xdev->regs + chan->desc_offset + reg + 4);

So the CPU can't perform 64-bit register access ?

How is 64 bit DMA addressing implemented ? Can you use a 64-bit VDMA on a 32-
bit platform with LPAE ? Can you use a 32-bit VDMA on a 64-bit platform ? 
Given that VDMA is an IP core you can instantiate in the programmable logic I 
expect some level of flexibility to be possible, but this patch doesn't seem 
to support it. Please provide more context to allow a proper review (and 
please include it in the commit message of v2).

> +}
> +#endif
> +
>  static inline u32 vdma_ctrl_read(struct xilinx_vdma_chan *chan, u32 reg)
>  {
>  	return vdma_read(chan, chan->ctrl_offset + reg);
> @@ -700,9 +718,15 @@ static void xilinx_vdma_start_transfer(struct
> xilinx_vdma_chan *chan) int i = 0;
> 
>  		list_for_each_entry(segment, &desc->segments, node) {
> -			vdma_desc_write(chan,
> +#if defined(CONFIG_PHYS_ADDR_T_64BIT)
> +			vdma_desc_write_64(chan,
>  					XILINX_VDMA_REG_START_ADDRESS(i++),
>  					segment->hw.buf_addr);
> +#else
> +			vdma_desc_write(chan,
> +					XILINX_VDMA_REG_START_ADDRESS(i++),
> +					(u32)segment->hw.buf_addr);
> +#endif
>  			last = segment;
>  		}

-- 
Regards,

Laurent Pinchart



From petr.cvek at tul.cz  Tue Aug 18 15:46:25 2015
From: petr.cvek at tul.cz (Petr Cvek)
Date: Wed, 19 Aug 2015 00:46:25 +0200
Subject: [PATCH v2 04/21] ARM: pxa: magician: Add, fix and init (new) GPIOs
In-Reply-To: <87mvxo8lqi.fsf@belgarion.home>
References: <cover.1439843482.git.petr.cvek@tul.cz> <55D258E9.9010303@tul.cz>
 <87mvxo8lqi.fsf@belgarion.home>
Message-ID: <55D3B5C1.2070806@tul.cz>

Dne 18.8.2015 v 21:01 Robert Jarzmik napsal(a):
> 
> From here onward, I'll suppose you'll catch all whitespace/indentation changes
> and extract them towards patch 01/21 ...

OK

> 
>>  /* input */
>>  
>> -#define EGPIO_MAGICIAN_CABLE_STATE_AC		MAGICIAN_EGPIO(4, 0)
>> -#define EGPIO_MAGICIAN_CABLE_STATE_USB		MAGICIAN_EGPIO(4, 1)
>> +/* AC=1, USB=0 */
>> +#define EGPIO_MAGICIAN_CABLE_TYPE		MAGICIAN_EGPIO(4, 0)
>> +/* =1 when AC or USB cable inserted */
>> +#define EGPIO_MAGICIAN_CABLE_INSERT1		MAGICIAN_EGPIO(4, 1)
> The naming makes me uneasy : it's rather vague "cable insert".
> If AC and USB are the only charging methods, why not have something like
> "EGPIO_MAGICIAN_POWERED" or the like ?

I don't see why not, but there are two GPIOs and it may turn out they have different function. I found it only for power/usb cable insertion. For example they may differ when usb device is connected (magician is now a host) but I did not test it (yet, phone does not generate vbus power).

> 
>>  	GPIO10_GPIO,	/* GSM_IRQ */
>>  	GPIO13_GPIO,	/* CPLD_IRQ */
>>  	GPIO107_GPIO,	/* DS1WM_IRQ */
>>  	GPIO108_GPIO,	/* GSM_READY */
>>  	GPIO115_GPIO,	/* nPEN_IRQ */
>>  
>> -	/* I2C */
>> -	GPIO117_I2C_SCL,
>> -	GPIO118_I2C_SDA,
> Okay so that are no I2C devices on magician ? Why keep GPIO119_MAGICIAN_I2C_* at
> the beginning of the file then ?

It is a duplicite definition.

	http://lxr.free-electrons.com/source/arch/arm/mach-pxa/magician.c#L60

and in the same array again at:

	http://lxr.free-electrons.com/source/arch/arm/mach-pxa/magician.c#L118

> 
>> +	MFP_CFG_OUT(GPIO40, AF0, DRIVE_LOW),	/* FIXME GSM? */
>> +	MFP_CFG_OUT(GPIO87, AF0, DRIVE_LOW),	/* FIXME GSM? */
>> +
>> +	/* Left GPIOs (undefined here):
>> +	 * 18, 49 : bootloader=VLIO?, WinM=TODO
>> +	 * 48 : AF0/out0
>> +	 * 56 : AF0/out0
>> +	 * 74 : bootloader=AF0/output
>> +	 * 86 : bootloader=AF0/input (but should be gsm reset???)
>> +	 * 114 : AF0/out0
>> +	 * 119 : AF0/out0
>> +	 * 120 : AF0/out
>> +	 * 1 : dedicated reset, AF0/output
>> +	 * 13 : cpld irq, output (??)
>> +	 */
> This is not describing current code. This doesn't belong to this file, even if I
> know how frustrating it is to reverse engineer all these gpios. I created a wiki
> web page will all GPIOs to let go my frustration in the past :)

OK I can create file in Documentation for that (at least one pin has a different direction in kernel vs bootloader).

BTW on xda wiki?

> 
>> @@ -241,8 +324,9 @@ static struct htc_egpio_chip egpio_chips[] = {
>>  
>>  		/*
>>  		 * Depends on modules configuration
>> +		 * Things like MMC and LCD should be enabled
>>  		 */
>> -		.initial_values = 0x40,
>> +		.initial_values = 0x21a0c0,
> Aren't they enabled by each driver upon its probe() ? What if MMC nor LCD is
> compiled in the kernel ?
> 

Some of it is from time kernel did not get to rootfs detection: 0x8000 for to be able to read panic errors (before a backlight driver is loaded - which is BTW not working now in vanilla). 0x80 should be for a valid LCD power sequence (broken one causes invalid voltages on LCD power lines). 0x2000 is RESET for soundcard as original 0x40 is for GSM. MMC can be probably changed to "0" now when everything is working. 0x200000 as 500mA charging should be enabled (for safety) as sometimes boot on weak accu can cause overcurrent, which will hardreset the phone.


>> @@ -343,21 +427,19 @@ static void samsung_lcd_power(int on, struct fb_var_screeninfo *si)
>>  			gpio_set_value(GPIO75_MAGICIAN_SAMSUNG_POWER, 1);
>>  		else
>>  			gpio_set_value(EGPIO_MAGICIAN_LCD_POWER, 1);
>> -		mdelay(10);
>> -		gpio_set_value(GPIO106_MAGICIAN_LCD_POWER_3, 1);
>> -		mdelay(10);
>> -		gpio_set_value(GPIO104_MAGICIAN_LCD_POWER_1, 1);
>> -		mdelay(30);
>> -		gpio_set_value(GPIO105_MAGICIAN_LCD_POWER_2, 1);
>> -		mdelay(10);
>> +		mdelay(6);
>> +		gpio_set_value(GPIO106_MAGICIAN_LCD_DCDC_NRESET, 1);
>> +		mdelay(6);	/* Avdd -> Voff >5ms */
>> +		gpio_set_value(GPIO104_MAGICIAN_LCD_VOFF_EN, 1);
>> +		mdelay(16);	/* Voff -> Von >(5+10)ms */
>> +		gpio_set_value(GPIO105_MAGICIAN_LCD_VON_EN, 1);
>>  	} else {
>> -		mdelay(10);
>> -		gpio_set_value(GPIO105_MAGICIAN_LCD_POWER_2, 0);
>> -		mdelay(30);
>> -		gpio_set_value(GPIO104_MAGICIAN_LCD_POWER_1, 0);
>> -		mdelay(10);
>> -		gpio_set_value(GPIO106_MAGICIAN_LCD_POWER_3, 0);
>> -		mdelay(10);
>> +		gpio_set_value(GPIO105_MAGICIAN_LCD_VON_EN, 0);
>> +		mdelay(16);
>> +		gpio_set_value(GPIO104_MAGICIAN_LCD_VOFF_EN, 0);
>> +		mdelay(6);
>> +		gpio_set_value(GPIO106_MAGICIAN_LCD_DCDC_NRESET, 0);
>> +		mdelay(6);
> You're changing the timings here, right ? This should be an appart patch. What
> is the reason of the change by the way ?

Faster reaction, one change from msleep to mdelay (in toppoly LCD) and reading a datasheet for a valid sequence.

> 
> Cheers.
> 
Best regards,
Petr



From briannorris at chromium.org  Tue Aug 18 15:48:31 2015
From: briannorris at chromium.org (Brian Norris)
Date: Tue, 18 Aug 2015 15:48:31 -0700
Subject: [PATCH 2/2] ARM: dts: rockchip: correct regulator PM properties
In-Reply-To: <51457775.D3ds00ymOJ@phil>
References: <1439923455-109818-1-git-send-email-briannorris@chromium.org>
 <1439923455-109818-2-git-send-email-briannorris@chromium.org>
 <51457775.D3ds00ymOJ@phil>
Message-ID: <20150818224831.GA140911@google.com>

On Tue, Aug 18, 2015 at 09:17:06PM +0200, Heiko Stuebner wrote:
> Am Dienstag, 18. August 2015, 11:44:15 schrieb Brian Norris:
> > This DTS file was submitted with non-upstream bindings. I happened
> > across this while reviewing the jaq DTS.
> > 
> > Signed-off-by: Brian Norris <briannorris at chromium.org>
> > Cc: Alexandru M Stan <amstan at chromium.org>
> > Cc: Douglas Anderson <dianders at chromium.org>
> > ---
> > Tested on jaq, not minnie
> > 
> >  arch/arm/boot/dts/rk3288-veyron-minnie.dts | 8 ++++++--
> >  1 file changed, 6 insertions(+), 2 deletions(-)
> > 
> > diff --git a/arch/arm/boot/dts/rk3288-veyron-minnie.dts
> > b/arch/arm/boot/dts/rk3288-veyron-minnie.dts index
> > 0e30bd6bf92b..6f619c154dc6 100644
> > --- a/arch/arm/boot/dts/rk3288-veyron-minnie.dts
> > +++ b/arch/arm/boot/dts/rk3288-veyron-minnie.dts
> > @@ -128,12 +128,16 @@
> >  			regulator-min-microvolt = <3300000>;
> >  			regulator-max-microvolt = <3300000>;
> >  			regulator-name = "vcc33_touch";
> > -			regulator-suspend-mem-disabled;
> > +			regulator-state-mem {
> > +				regulator-on-in-suspend;
> > +			};
> >  		};
> > 
> >  		vcc5v_touch: SWITCH_REG2 {
> >  			regulator-name = "vcc5v_touch";
> > -			regulator-suspend-mem-disabled;
> > +			regulator-state-mem {
> > +				regulator-on-in-suspend;
> > +			};
> 
> wouldn't regulator-suspend-mem-disabled translate to regulator-off-in-suspend?
> At least looks like it according to https://lkml.org/lkml/2013/7/25/592

You are right. My bad. Will fix. (Need to fix this in jaq too.)

Thanks,
Brian


From briannorris at chromium.org  Tue Aug 18 16:01:06 2015
From: briannorris at chromium.org (Brian Norris)
Date: Tue, 18 Aug 2015 16:01:06 -0700
Subject: [PATCH 1/2] ARM: dts: rockchip: add veyron-jaq board
In-Reply-To: <9567797.5pIFQ6WEoM@phil>
References: <1439923455-109818-1-git-send-email-briannorris@chromium.org>
 <9567797.5pIFQ6WEoM@phil>
Message-ID: <20150818230106.GB140911@google.com>

Thanks for the quick review.

On Tue, Aug 18, 2015 at 09:19:05PM +0200, Heiko Stuebner wrote:
> Am Dienstag, 18. August 2015, 11:44:14 schrieb Brian Norris:
> > a.k.a. Haier Chromebook 11
> > 
> > Signed-off-by: Brian Norris <briannorris at chromium.org>
> > Cc: Alexandru M Stan <amstan at chromium.org>
> > Cc: Douglas Anderson <dianders at chromium.org>
> > ---
> >  arch/arm/boot/dts/Makefile              |   1 +
> >  arch/arm/boot/dts/rk3288-veyron-jaq.dts | 176
> > ++++++++++++++++++++++++++++++++ 2 files changed, 177 insertions(+)
> >  create mode 100644 arch/arm/boot/dts/rk3288-veyron-jaq.dts
> 
> missing binding documentation in 
> Documentation/devicetree/bindings/arm/rockchip.txt (needs new entry above 
> Jerry)

I don't know how I managed this, but I had already fixed this up in my
tree and amended the commit. I must have grabbed an old commit ref when
generating the patches... Sorry, will fix when sending v2.

> > 
> > diff --git a/arch/arm/boot/dts/Makefile b/arch/arm/boot/dts/Makefile
> > index 7805a6541a38..7a2c3c88ce9e 100644
> > --- a/arch/arm/boot/dts/Makefile
> > +++ b/arch/arm/boot/dts/Makefile
> > @@ -493,6 +493,7 @@ dtb-$(CONFIG_ARCH_ROCKCHIP) += \
> >  	rk3288-veyron-jerry.dtb \
> >  	rk3288-veyron-minnie.dtb \
> >  	rk3288-veyron-pinky.dtb \
> > +	rk3288-veyron-jaq.dtb \
> >  	rk3288-veyron-speedy.dtb
> 
> please sort alphabetically (in this case somewhere above jerry)

Will do.

> >  dtb-$(CONFIG_ARCH_S3C24XX) += \
> >  	s3c2416-smdk2416.dtb
> > diff --git a/arch/arm/boot/dts/rk3288-veyron-jaq.dts
> > b/arch/arm/boot/dts/rk3288-veyron-jaq.dts new file mode 100644
> > index 000000000000..ea6130156216
> > --- /dev/null
> > +++ b/arch/arm/boot/dts/rk3288-veyron-jaq.dts
> > @@ -0,0 +1,176 @@
> > +/*
> > + * Google Veyron Jaq Rev 1+ board device tree source
> > + *
> > + * Copyright 2015 Google, Inc
> > + *
> > + * This file is dual-licensed: you can use it either under the terms
> > + * of the GPL or the X11 license, at your option. Note that this dual
> > + * licensing only applies to this file, and not this project as a
> > + * whole.
> > + *
> > + *  a) This file is free software; you can redistribute it and/or
> > + *     modify it under the terms of the GNU General Public License as
> > + *     published by the Free Software Foundation; either version 2 of the
> > + *     License, or (at your option) any later version.
> > + *
> > + *     This file is distributed in the hope that it will be useful,
> > + *     but WITHOUT ANY WARRANTY; without even the implied warranty of
> > + *     MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
> > + *     GNU General Public License for more details.
> > + *
> > + *  Or, alternatively,
> > + *
> > + *  b) Permission is hereby granted, free of charge, to any person
> > + *     obtaining a copy of this software and associated documentation
> > + *     files (the "Software"), to deal in the Software without
> > + *     restriction, including without limitation the rights to use,
> > + *     copy, modify, merge, publish, distribute, sublicense, and/or
> > + *     sell copies of the Software, and to permit persons to whom the
> > + *     Software is furnished to do so, subject to the following
> > + *     conditions:
> > + *
> > + *     The above copyright notice and this permission notice shall be
> > + *     included in all copies or substantial portions of the Software.
> > + *
> > + *     THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
> > + *     EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES
> > + *     OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
> > + *     NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT
> > + *     HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY,
> > + *     WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
> > + *     FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR
> > + *     OTHER DEALINGS IN THE SOFTWARE.
> > + */
> > +
> > +/dts-v1/;
> > +
> > +#include "rk3288-veyron-chromebook.dtsi"
> > +#include "cros-ec-sbs.dtsi"
> > +
> > +/ {
> > +	model = "Google Jaq";
> > +	compatible = "google,veyron-jaq-rev5", "google,veyron-jaq-rev4",
> > +		     "google,veyron-jaq-rev3", "google,veyron-jaq-rev2",
> > +		     "google,veyron-jaq-rev1", "google,veyron-jaq",
> > +		     "google,veyron", "rockchip,rk3288";
> > +
> > +	panel_regulator: panel-regulator {
> > +		compatible = "regulator-fixed";
> > +		enable-active-high;
> > +		gpio = <&gpio7 14 GPIO_ACTIVE_HIGH>;
> > +		pinctrl-names = "default";
> > +		pinctrl-0 = <&lcd_enable_h>;
> > +		regulator-name = "panel_regulator";
> > +		vin-supply = <&vcc33_sys>;
> > +	};
> > +
> > +	vcc18_lcd: vcc18-lcd {
> > +		compatible = "regulator-fixed";
> > +		enable-active-high;
> > +		gpio = <&gpio2 13 GPIO_ACTIVE_HIGH>;
> > +		pinctrl-names = "default";
> > +		pinctrl-0 = <&avdd_1v8_disp_en>;
> > +		regulator-name = "vcc18_lcd";
> > +		regulator-always-on;
> > +		regulator-boot-on;
> > +		vin-supply = <&vcc18_wl>;
> > +	};
> > +
> > +	backlight_regulator: backlight-regulator {
> > +		compatible = "regulator-fixed";
> > +		enable-active-high;
> > +		gpio = <&gpio2 12 GPIO_ACTIVE_HIGH>;
> > +		pinctrl-names = "default";
> > +		pinctrl-0 = <&bl_pwr_en>;
> > +		regulator-name = "backlight_regulator";
> > +		vin-supply = <&vcc33_sys>;
> > +		startup-delay-us = <15000>;
> > +	};
> 
> again, please alphabetically (backlight, panel, vcc*)

Actually this one was somewhat intentional; I was trying to mirror the
jerry DTS, which has very similar (nearly identical) nodes in jaq.

But I can sort however you'd like it best.

> > +};
> > +
> > +&rk808 {
> > +	pinctrl-names = "default";
> > +	pinctrl-0 = <&pmic_int_l &dvs_1 &dvs_2>;
> > +	dvs-gpios = <&gpio7 12 GPIO_ACTIVE_HIGH>,
> > +		    <&gpio7 15 GPIO_ACTIVE_HIGH>;
> > +
> > +	regulators {
> > +		mic_vcc: LDO_REG2 {
> > +			regulator-name = "mic_vcc";
> > +			regulator-always-on;
> > +			regulator-boot-on;
> > +			regulator-min-microvolt = <1800000>;
> > +			regulator-max-microvolt = <1800000>;
> > +			regulator-state-mem {
> > +				regulator-on-in-suspend;
> > +			};
> > +		};
> > +	};
> > +};
> > +
> > +&sdmmc {
> > +	disable-wp;
> > +	pinctrl-names = "default";
> > +	pinctrl-0 = <&sdmmc_clk &sdmmc_cmd &sdmmc_cd_disabled &sdmmc_cd_gpio
> > +			&sdmmc_bus4>;
> > +};
> > +
> > +&vcc_5v {
> > +	enable-active-high;
> > +	gpio = <&gpio7 21 GPIO_ACTIVE_HIGH>;
> > +	pinctrl-names = "default";
> > +	pinctrl-0 = <&drv_5v>;
> > +};
> > +
> > +&vcc50_hdmi {
> > +	enable-active-high;
> > +	gpio = <&gpio5 19 GPIO_ACTIVE_HIGH>;
> > +	pinctrl-names = "default";
> > +	pinctrl-0 = <&vcc50_hdmi_en>;
> > +};
> > +
> > +&pinctrl {
> > +	backlight {
> > +		bl_pwr_en: bl_pwr_en {
> > +			rockchip,pins = <2 12 RK_FUNC_GPIO &pcfg_pull_none>;
> > +		};
> > +	};
> > +
> > +	buck-5v {
> > +		drv_5v: drv-5v {
> > +			rockchip,pins = <7 21 RK_FUNC_GPIO &pcfg_pull_none>;
> > +		};
> > +	};
> > +
> > +	edp {
> > +		edp_hpd: edp_hpd {
> > +			rockchip,pins = <7 11 RK_FUNC_2 &pcfg_pull_down>;
> > +		};
> > +	};
> > +
> > +	hdmi {
> > +		vcc50_hdmi_en: vcc50-hdmi-en {
> > +			rockchip,pins = <5 19 RK_FUNC_GPIO &pcfg_pull_none>;
> > +		};
> > +	};
> > +
> > +	lcd {
> > +		lcd_enable_h: lcd-en {
> > +			rockchip,pins = <7 14 RK_FUNC_GPIO &pcfg_pull_none>;
> > +		};
> > +
> > +		avdd_1v8_disp_en: avdd-1v8-disp-en {
> > +			rockchip,pins = <2 13 RK_FUNC_GPIO &pcfg_pull_none>;
> > +		};
> > +	};
> > +
> > +	pmic {
> > +		dvs_1: dvs-1 {
> > +			rockchip,pins = <7 12 RK_FUNC_GPIO &pcfg_pull_down>;
> > +		};
> > +
> > +		dvs_2: dvs-2 {
> > +			rockchip,pins = <7 15 RK_FUNC_GPIO &pcfg_pull_down>;
> > +		};
> > +	};
> > +};
> 
> pinctrl can stay at the bottom. It may actually improve readability, if not 
> cluttering up the smaller other nodes above.

Ok.

Brian


From petr.cvek at tul.cz  Tue Aug 18 16:09:44 2015
From: petr.cvek at tul.cz (Petr Cvek)
Date: Wed, 19 Aug 2015 01:09:44 +0200
Subject: [PATCH v2 03/21] ARM: pxa: magician: Fix comments, debug
 functions and print strings
In-Reply-To: <87r3n08mqo.fsf@belgarion.home>
References: <cover.1439843482.git.petr.cvek@tul.cz> <55D258CD.40101@tul.cz>
 <87r3n08mqo.fsf@belgarion.home>
Message-ID: <55D3BB38.8030701@tul.cz>

Dne 18.8.2015 v 20:39 Robert Jarzmik napsal(a):
> Petr Cvek <petr.cvek at tul.cz> writes:
> 
>> Fix comments, debug functions and print strings. Rename backlight
>> structures to be more specific.
>>
>> Signed-off-by: Petr Cvek <petr.cvek at tul.cz>
>> ---
>>  arch/arm/mach-pxa/magician.c | 121 +++++++++++++++++++++++++++++++------------
>>  1 file changed, 89 insertions(+), 32 deletions(-)
>>
>> diff --git a/arch/arm/mach-pxa/magician.c b/arch/arm/mach-pxa/magician.c
>> index 9e8698a..57da133 100644
>> --- a/arch/arm/mach-pxa/magician.c
>> +++ b/arch/arm/mach-pxa/magician.c
>> @@ -11,6 +11,46 @@
>>   * it under the terms of the GNU General Public License version 2 as
>>   * published by the Free Software Foundation.
>>   *
>> + *
>> + * NOTICE MDA Compact (T-mobile XDA) facts:
>> + *   On "LCD type = 1, system_rev = 2" (0x3a in CPLD)
>> + * Samsung LTP280QV - valid LCD init sequence sequence:
>> + *   powerup: Vdigital->Vanalog->gate Voff->gate Von->data enable
>> + *   powerdown: data disable->gate Von->gate Voff->Vanalog->Vdigital
>> + * Measured on PCB:
>> + *   GPIO106
>> + *     Affects VOFF, VON and other voltages
>> + *     Probably main reset pin for DC-DC converter
>> + *   GPIO75
>> + *     Must be AF0+OUT (WM leaves it to AF2+OUT), not LCD signal
>> + *     GPIO106 works only when GPIO75 is high (DC-DC power enable?)
>> + *     After LCD powerup, value is irrelevant
>> + *   GPIO104
>> + *     LCD VOFF (gate off voltage)
>> + *   GPIO105
>> + *     LCD VON (gate on voltage)
>> + * FFUART (/dev/ttyS0) WM: 38400,8,n,1,crtscts (GSM data?)
>> + * BTUART (/dev/ttyS1) WM: 115200,8,n,1,crtscts (GSM AT commands)
>> + *   Use a HTC line discipline: 0x02 channel(==0x16) data 0x02
>> + * EGPIO(CPLD) should be always present (controls "all" supply power)
>> + *   For rootfs on MMC/SD: EGPIO module controls card power (in kernel)
>> + * cpu-freq often freeze platform (errata?, use userspace gov)
>> + * Do not use YUV420, (erratum E24) causes LCD hang (forever)
>> + * Many GSM related pins are unknown
>> + * gpio-rc-recv probably require lowpass filter (sw is OK)
>> + * TODO EGPIO_MAGICIAN_IR_RECEIVE_SHUTDOWN
>> + * FIXME AC charging blocks IrDA
>> + * Unimplemented blocking of camera+power+reset, reset and door open reset
>> + *   Registers: htc-pasic3.h (but blocks charging too)
>> + * Other PXA machines have wait_for_sync for ADS7846 (during LCD refresh)
>> + * pda-power has not optimal charging (accu can be bloated)
>> + * TODO Current switching works? Is gpio-regulator/bq24022 required?
> I think you can ask Philip, he's the maintainer after all ...

Ok. Philipp? 

Current switching can be done in pda-power function .set_charge(). But setting the charging current based on AC vs USB cable only is irrelevant as both can deliver 500mA (and Magician is not one of the most power efficient machine, 100mA is barely enough to power). Better thing would be to base the switching on accu level of charge (trickle charging).

> 
>> + * pdata supports alternative drivers (mutually exclusive modules)
>> + *   i2c-pxa vs i2c-gpio (SCCB)
>> + *   pwm_bl vs gpio_backlight
>> + *   pxa27x_udc vs phy-gpio-vbus-usb
>> + *   physmap-flash vs pxa2xx-flash
> 
> Okay, this chunk is nice documentation, but not code ...
> I'd rather have it in : Documentation/arm/pxa/magician.txt or something like
> that.
OK I can move these comments there.

> 
>> @@ -120,11 +160,12 @@ static unsigned long magician_pin_config[] __initdata = {
>>  };
>>  
>>  /*
>> - * IRDA
>> + * IrDA
>>   */
>>  
>>  static struct pxaficp_platform_data magician_ficp_info = {
>>  	.gpio_pwdown		= GPIO83_MAGICIAN_nIR_EN,
>> +	/* TODO test with FIR dongle */
> I don't like this comment. I was not there before, so let it be. You know there
> remains a TODO, I know ... but you can cunningly slip it in the commit message.
Actually I have bought a dongle during last week, but it turned out, it can do only SIR (and poorly :-D). I can try to enable a second magician PCB, but it will takes some time (as I have only one accupack - second burned down). So do I have to remove only comment or FIR flag altogether? (I can find with second magician that it can work like a charm or it is not working - for example due to incompatible IrDA transceiver).



From briannorris at chromium.org  Tue Aug 18 16:28:06 2015
From: briannorris at chromium.org (Brian Norris)
Date: Tue, 18 Aug 2015 16:28:06 -0700
Subject: [PATCH 2/2] ARM: dts: rockchip: correct regulator PM properties
In-Reply-To: <20150818224831.GA140911@google.com>
References: <1439923455-109818-1-git-send-email-briannorris@chromium.org>
 <1439923455-109818-2-git-send-email-briannorris@chromium.org>
 <51457775.D3ds00ymOJ@phil> <20150818224831.GA140911@google.com>
Message-ID: <20150818232806.GC140911@google.com>

On Tue, Aug 18, 2015 at 03:48:31PM -0700, Brian Norris wrote:
> On Tue, Aug 18, 2015 at 09:17:06PM +0200, Heiko Stuebner wrote:
> > Am Dienstag, 18. August 2015, 11:44:15 schrieb Brian Norris:
> > > This DTS file was submitted with non-upstream bindings. I happened
> > > across this while reviewing the jaq DTS.
> > > 
> > > Signed-off-by: Brian Norris <briannorris at chromium.org>
> > > Cc: Alexandru M Stan <amstan at chromium.org>
> > > Cc: Douglas Anderson <dianders at chromium.org>
> > > ---
> > > Tested on jaq, not minnie
> > > 
> > >  arch/arm/boot/dts/rk3288-veyron-minnie.dts | 8 ++++++--
> > >  1 file changed, 6 insertions(+), 2 deletions(-)
> > > 
> > > diff --git a/arch/arm/boot/dts/rk3288-veyron-minnie.dts
> > > b/arch/arm/boot/dts/rk3288-veyron-minnie.dts index
> > > 0e30bd6bf92b..6f619c154dc6 100644
> > > --- a/arch/arm/boot/dts/rk3288-veyron-minnie.dts
> > > +++ b/arch/arm/boot/dts/rk3288-veyron-minnie.dts
> > > @@ -128,12 +128,16 @@
> > >  			regulator-min-microvolt = <3300000>;
> > >  			regulator-max-microvolt = <3300000>;
> > >  			regulator-name = "vcc33_touch";
> > > -			regulator-suspend-mem-disabled;
> > > +			regulator-state-mem {
> > > +				regulator-on-in-suspend;
> > > +			};
> > >  		};
> > > 
> > >  		vcc5v_touch: SWITCH_REG2 {
> > >  			regulator-name = "vcc5v_touch";
> > > -			regulator-suspend-mem-disabled;
> > > +			regulator-state-mem {
> > > +				regulator-on-in-suspend;
> > > +			};
> > 
> > wouldn't regulator-suspend-mem-disabled translate to regulator-off-in-suspend?
> > At least looks like it according to https://lkml.org/lkml/2013/7/25/592
> 
> You are right. My bad. Will fix. (Need to fix this in jaq too.)

Now that I'm looking a little closer, it seems like other existing DTS's
are broken too, then. Jerry looks like it was converted to the
regulator-state-mem node binding, but the conversion doesn't seem to
make sense when I compare the chromium DTS sources with the for-next
source I see in your tree.

In -next:

     regulators {
             mic_vcc: LDO_REG2 {
                        regulator-name = "mic_vcc";
                        regulator-always-on;
                        regulator-boot-on;
                        regulator-min-microvolt = <1800000>;
                        regulator-max-microvolt = <1800000>;
                        regulator-state-mem {
                                regulator-on-in-suspend;
                        };
                };
         };

But chromium had:

       regulators {
                mic_vcc: LDO_REG2 {
                        regulator-always-on;
                        regulator-boot-on;
                        regulator-min-microvolt = <1800000>;
                        regulator-max-microvolt = <1800000>;
                        regulator-name = "mic_vcc";
                        regulator-suspend-mem-disabled;
                };
       };

So I guess I'll make the proper conversion for all the veyron variants I
see.

Brian


From edubezval at gmail.com  Tue Aug 18 16:33:58 2015
From: edubezval at gmail.com (Eduardo Valentin)
Date: Tue, 18 Aug 2015 16:33:58 -0700
Subject: [PATCH] Revert "serial: imx: remove unbalanced clk_prepare"
In-Reply-To: <1439912592-14779-1-git-send-email-fabio.estevam@freescale.com>
References: <1439912592-14779-1-git-send-email-fabio.estevam@freescale.com>
Message-ID: <20150818233356.GA4494@localhost.localdomain>

On Tue, Aug 18, 2015 at 12:43:12PM -0300, Fabio Estevam wrote:
> This reverts commit 9e7b399d6528eac33a6fbfceb2b92af209c3454d.
> 
> Commit ("9e7b399d6528ea") causes the following warning and sometimes
> also hangs the system:
> 
> ------------[ cut here ]------------
>  WARNING: CPU: 0 PID: 0 at kernel/locking/mutex.c:868 mutex_trylock+0x20c/0x22c()
>  DEBUG_LOCKS_WARN_ON(in_interrupt())
>  Modules linked in:
> CPU: 0 PID: 0 Comm: swapper/0 Not tainted 4.2.0-rc7-next-20150818-00001-g14418a6 #4
> Hardware name: Freescale i.MX6 Quad/DualLite (Device Tree)
> Backtrace: 
> [<80012f08>] (dump_backtrace) from [<800130a4>] (show_stack+0x18/0x1c)
> r6:00000364 r5:00000000 r4:00000000 r3:00000000
> [<8001308c>] (show_stack) from [<807902b8>] (dump_stack+0x88/0xa4)
> [<80790230>] (dump_stack) from [<8002a604>] (warn_slowpath_common+0x80/0xbc)
> r5:807945c4 r4:80ab3b50
> [<8002a584>] (warn_slowpath_common) from [<8002a6e4>] (warn_slowpath_fmt+0x38/0x40)
> r8:00000000 r7:8131100c r6:8054c3cc r5:8131300c r4:80b0a570
> [<8002a6b0>] (warn_slowpath_fmt) from [<807945c4>] (mutex_trylock+0x20c/0x22c)
> r3:8095d0d8 r2:8095ab28
> [<807943b8>] (mutex_trylock) from [<8054c3cc>] (clk_prepare_lock+0x14/0xf4)
> r7:8131100c r6:be3f0c80 r5:00000037 r4:be3f0c80
> [<8054c3b8>] (clk_prepare_lock) from [<8054dbfc>] (clk_prepare+0x18/0x30)
> r5:00000037 r4:be3f0c80
> [<8054dbe4>] (clk_prepare) from [<8036a600>] (imx_console_write+0x30/0x244)
> r4:812d0bc8 r3:8132b9a4
> 
> To reproduce the problem we only need to let the board idle for something
> like 30 seconds.

hmmm.. I really did not see this one. Looking at the code looks like we
could be atomic in some of the uart console callbacks.

For this one:

Reviewed-by: Eduardo Valentin <edubezval at gmail.com>

Did you try the runtime pm patch on your end?

BR,

> 
> Tested on a imx6q-sabresd.
> 
> Signed-off-by: Fabio Estevam <fabio.estevam at freescale.com>
> ---
>  drivers/tty/serial/imx.c | 20 ++++++++++++++------
>  1 file changed, 14 insertions(+), 6 deletions(-)
> 
> diff --git a/drivers/tty/serial/imx.c b/drivers/tty/serial/imx.c
> index fe3d41c..d0388a0 100644
> --- a/drivers/tty/serial/imx.c
> +++ b/drivers/tty/serial/imx.c
> @@ -1631,12 +1631,12 @@ imx_console_write(struct console *co, const char *s, unsigned int count)
>  	int locked = 1;
>  	int retval;
>  
> -	retval = clk_prepare_enable(sport->clk_per);
> +	retval = clk_enable(sport->clk_per);
>  	if (retval)
>  		return;
> -	retval = clk_prepare_enable(sport->clk_ipg);
> +	retval = clk_enable(sport->clk_ipg);
>  	if (retval) {
> -		clk_disable_unprepare(sport->clk_per);
> +		clk_disable(sport->clk_per);
>  		return;
>  	}
>  
> @@ -1675,8 +1675,8 @@ imx_console_write(struct console *co, const char *s, unsigned int count)
>  	if (locked)
>  		spin_unlock_irqrestore(&sport->port.lock, flags);
>  
> -	clk_disable_unprepare(sport->clk_ipg);
> -	clk_disable_unprepare(sport->clk_per);
> +	clk_disable(sport->clk_ipg);
> +	clk_disable(sport->clk_per);
>  }
>  
>  /*
> @@ -1777,7 +1777,15 @@ imx_console_setup(struct console *co, char *options)
>  
>  	retval = uart_set_options(&sport->port, co, baud, parity, bits, flow);
>  
> -	clk_disable_unprepare(sport->clk_ipg);
> +	clk_disable(sport->clk_ipg);
> +	if (retval) {
> +		clk_unprepare(sport->clk_ipg);
> +		goto error_console;
> +	}
> +
> +	retval = clk_prepare(sport->clk_per);
> +	if (retval)
> +		clk_disable_unprepare(sport->clk_ipg);
>  
>  error_console:
>  	return retval;
> -- 
> 1.9.1
> 
-------------- next part --------------
A non-text attachment was scrubbed...
Name: signature.asc
Type: application/pgp-signature
Size: 490 bytes
Desc: Digital signature
URL: <http://lists.infradead.org/pipermail/linux-arm-kernel/attachments/20150818/74d2fbee/attachment.sig>

From tchalamarla at caviumnetworks.com  Tue Aug 18 16:40:30 2015
From: tchalamarla at caviumnetworks.com (tchalamarla at caviumnetworks.com)
Date: Tue, 18 Aug 2015 16:40:30 -0700
Subject: [PATCH V4] iommu/arm-smmu-v2: ThunderX mis-extends 64bit registers
Message-ID: <1439941230-27183-1-git-send-email-tchalamarla@caviumnetworks.com>

From: Tirumalesh Chalamarla <tchalamarla at caviumnetworks.com>

The SMMU architecture defines two different behaviors when 64-bit
registers are written with 32-bit writes.  The first behavior causes
zero extension into the upper 32-bits.  The second behavior splits a
64-bit register into "normal" 32-bit register pairs.

On some buggy implementations, registers incorrectly zero extended
when they should instead behave as normal 32-bit register pairs.

Signed-off-by: Tirumalesh Chalamarla <tchalamarla at caviumnetworks.com>

Changes from V3:
        - rebased on iommu/devel

Changes from V2:
        - removed unused definitions

Changes from V1:
        - Introduced smmu_writeq
---
 drivers/iommu/arm-smmu.c | 50 ++++++++++++++++++++++++++----------------------
 1 file changed, 27 insertions(+), 23 deletions(-)

diff --git a/drivers/iommu/arm-smmu.c b/drivers/iommu/arm-smmu.c
index 48a39df..b58bfa4 100644
--- a/drivers/iommu/arm-smmu.c
+++ b/drivers/iommu/arm-smmu.c
@@ -70,6 +70,18 @@
 		((smmu->options & ARM_SMMU_OPT_SECURE_CFG_ACCESS)	\
 			? 0x400 : 0))
 
+#ifdef CONFIG_64BIT
+#define smmu_writeq(reg64, addr)	writeq_relaxed((reg64), (addr))
+#else
+#define smmu_writeq(reg64, addr)				\
+	do {							\
+		u64 __val = (reg64);				\
+		void __iomem *__addr = (addr);			\
+		writel_relaxed(__val >> 32, __addr + 4);	\
+		writel_relaxed(__val, __addr);			\
+	} while (0)
+#endif
+
 /* Configuration registers */
 #define ARM_SMMU_GR0_sCR0		0x0
 #define sCR0_CLIENTPD			(1 << 0)
@@ -185,10 +197,8 @@
 #define ARM_SMMU_CB_SCTLR		0x0
 #define ARM_SMMU_CB_RESUME		0x8
 #define ARM_SMMU_CB_TTBCR2		0x10
-#define ARM_SMMU_CB_TTBR0_LO		0x20
-#define ARM_SMMU_CB_TTBR0_HI		0x24
-#define ARM_SMMU_CB_TTBR1_LO		0x28
-#define ARM_SMMU_CB_TTBR1_HI		0x2c
+#define ARM_SMMU_CB_TTBR0		0x20
+#define ARM_SMMU_CB_TTBR1		0x28
 #define ARM_SMMU_CB_TTBCR		0x30
 #define ARM_SMMU_CB_S1_MAIR0		0x38
 #define ARM_SMMU_CB_S1_MAIR1		0x3c
@@ -226,7 +236,7 @@
 #define TTBCR2_SEP_SHIFT		15
 #define TTBCR2_SEP_UPSTREAM		(0x7 << TTBCR2_SEP_SHIFT)
 
-#define TTBRn_HI_ASID_SHIFT            16
+#define TTBRn_ASID_SHIFT		48
 
 #define FSR_MULTI			(1 << 31)
 #define FSR_SS				(1 << 30)
@@ -695,6 +705,7 @@ static void arm_smmu_init_context_bank(struct arm_smmu_domain *smmu_domain,
 				       struct io_pgtable_cfg *pgtbl_cfg)
 {
 	u32 reg;
+	u64 reg64;
 	bool stage1;
 	struct arm_smmu_cfg *cfg = &smmu_domain->cfg;
 	struct arm_smmu_device *smmu = smmu_domain->smmu;
@@ -738,22 +749,17 @@ static void arm_smmu_init_context_bank(struct arm_smmu_domain *smmu_domain,
 
 	/* TTBRs */
 	if (stage1) {
-		reg = pgtbl_cfg->arm_lpae_s1_cfg.ttbr[0];
-		writel_relaxed(reg, cb_base + ARM_SMMU_CB_TTBR0_LO);
-		reg = pgtbl_cfg->arm_lpae_s1_cfg.ttbr[0] >> 32;
-		reg |= ARM_SMMU_CB_ASID(cfg) << TTBRn_HI_ASID_SHIFT;
-		writel_relaxed(reg, cb_base + ARM_SMMU_CB_TTBR0_HI);
-
-		reg = pgtbl_cfg->arm_lpae_s1_cfg.ttbr[1];
-		writel_relaxed(reg, cb_base + ARM_SMMU_CB_TTBR1_LO);
-		reg = pgtbl_cfg->arm_lpae_s1_cfg.ttbr[1] >> 32;
-		reg |= ARM_SMMU_CB_ASID(cfg) << TTBRn_HI_ASID_SHIFT;
-		writel_relaxed(reg, cb_base + ARM_SMMU_CB_TTBR1_HI);
+		reg64 = pgtbl_cfg->arm_lpae_s1_cfg.ttbr[0];
+
+		reg64 |= ((u64)ARM_SMMU_CB_ASID(cfg)) << TTBRn_ASID_SHIFT;
+		smmu_writeq(reg64, cb_base + ARM_SMMU_CB_TTBR0);
+
+		reg64 = pgtbl_cfg->arm_lpae_s1_cfg.ttbr[1];
+		reg64 |= ((u64)ARM_SMMU_CB_ASID(cfg)) << TTBRn_ASID_SHIFT;
+		smmu_writeq(reg64, cb_base + ARM_SMMU_CB_TTBR1);
 	} else {
-		reg = pgtbl_cfg->arm_lpae_s2_cfg.vttbr;
-		writel_relaxed(reg, cb_base + ARM_SMMU_CB_TTBR0_LO);
-		reg = pgtbl_cfg->arm_lpae_s2_cfg.vttbr >> 32;
-		writel_relaxed(reg, cb_base + ARM_SMMU_CB_TTBR0_HI);
+		reg64 = pgtbl_cfg->arm_lpae_s2_cfg.vttbr;
+		smmu_writeq(reg64, cb_base + ARM_SMMU_CB_TTBR0);
 	}
 
 	/* TTBCR */
@@ -1212,11 +1218,9 @@ static phys_addr_t arm_smmu_iova_to_phys_hard(struct iommu_domain *domain,
 
 	/* ATS1 registers can only be written atomically */
 	va = iova & ~0xfffUL;
-#ifdef CONFIG_64BIT
 	if (smmu->version == ARM_SMMU_V2)
-		writeq_relaxed(va, cb_base + ARM_SMMU_CB_ATS1PR);
+		smmu_writeq(va, cb_base + ARM_SMMU_CB_ATS1PR);
 	else
-#endif
 		writel_relaxed(va, cb_base + ARM_SMMU_CB_ATS1PR);
 
 	if (readl_poll_timeout_atomic(cb_base + ARM_SMMU_CB_ATSR, tmp,
-- 
2.1.0



From lftan at altera.com  Tue Aug 18 18:22:36 2015
From: lftan at altera.com (Ley Foon Tan)
Date: Wed, 19 Aug 2015 09:22:36 +0800
Subject: [PATCH v4 2/5] pci:host: Add Altera PCIe host controller driver
In-Reply-To: <CADhT+wfjYaEefScKNz-R5miA+_Ybm8PTHgG6jDT9ntb9e89twQ@mail.gmail.com>
References: <1439802579-22651-1-git-send-email-lftan@altera.com>
 <1439802579-22651-3-git-send-email-lftan@altera.com>
 <CADhT+wfjYaEefScKNz-R5miA+_Ybm8PTHgG6jDT9ntb9e89twQ@mail.gmail.com>
Message-ID: <CAFiDJ5-_1QAfox_KTGf4mNCdN-fNm9L3jP=xAWmLvn66sYXfqA@mail.gmail.com>

On Wed, Aug 19, 2015 at 3:11 AM, Dinh Nguyen <dinh.linux at gmail.com> wrote:
>
> On Mon, Aug 17, 2015 at 4:09 AM, Ley Foon Tan <lftan at altera.com> wrote:
> > This patch adds the Altera PCIe host controller driver.
> >
> > Signed-off-by: Ley Foon Tan <lftan at altera.com>
> > ---
> >  drivers/pci/host/Kconfig       |   7 +
> >  drivers/pci/host/Makefile      |   1 +
> >  drivers/pci/host/pcie-altera.c | 543 +++++++++++++++++++++++++++++++++++++++++
> >  3 files changed, 551 insertions(+)
> >  create mode 100644 drivers/pci/host/pcie-altera.c
> >
> > diff --git a/drivers/pci/host/Kconfig b/drivers/pci/host/Kconfig
> > index 675c2d1..4b4754a 100644
> > --- a/drivers/pci/host/Kconfig
> > +++ b/drivers/pci/host/Kconfig
> > @@ -145,4 +145,11 @@ config PCIE_IPROC_BCMA
> >           Say Y here if you want to use the Broadcom iProc PCIe controller
> >           through the BCMA bus interface
> >
>
> <snip>
>
> > +
> > +/* Address translation table entry size */
> > +#define ATT_ENTRY_SIZE         8
> > +
> > +#define DWORD_MASK             3
> > +
> > +struct altera_pcie {
> > +       struct platform_device  *pdev;
> > +       struct resource         *txs;
>
> You have "Txs" documented in the bindings document, you have a pointer
> here, but you've never used it
> anywhre in the code? What is it for?
Good catch. Forgot to remove this txs field here, we no longer require
to keep this in struct.

>
> > +       void __iomem            *cra_base;
> > +       int                     irq;
> > +       u8                      root_bus_nr;
> > +       struct irq_domain               *irq_domain;
> > +       struct resource         bus_range;
> > +       struct list_head                resources;
> > +};
> > +
>
> <snip>
>
> > +
> > +static int tlp_cfg_dword_read(struct altera_pcie *pcie, u8 bus, u32 devfn,
> > +                             int where, u32 *value)
> > +{
> > +       int ret;
> > +       u32 headers[TLP_HDR_SIZE];
> > +
> > +       if (bus == pcie->root_bus_nr)
> > +               headers[0] = TLP_CFG_DW0(TLP_FMTTYPE_CFGRD0);
> > +       else
> > +               headers[0] = TLP_CFG_DW0(TLP_FMTTYPE_CFGRD1);
> > +
> > +       headers[1] = TLP_CFG_DW1(TLP_REQ_ID(pcie->root_bus_nr, devfn),
> > +                                       TLP_READ_TAG);
> > +       headers[2] = TLP_CFG_DW2(bus, devfn, where);
> > +
> > +       tlp_write_packet(pcie, headers, 0);
> > +
> > +       ret = tlp_read_packet(pcie, value);
> > +       if (ret)
> > +               *value = ~0UL;  /* return 0xFFFFFFFF if error */
> > +
> > +       return ret;
> > +}
> > +
> > +static int tlp_cfg_dword_write(struct altera_pcie *pcie, u8 bus, u32 devfn,
> > +                              int where, u32 value)
> > +{
> > +       u32 headers[TLP_HDR_SIZE];
> > +
> > +       if (bus == pcie->root_bus_nr)
> > +               headers[0] = TLP_CFG_DW0(TLP_FMTTYPE_CFGWR0);
> > +       else
> > +               headers[0] = TLP_CFG_DW0(TLP_FMTTYPE_CFGWR1);
> > +
> > +       headers[1] = TLP_CFG_DW1(TLP_REQ_ID(pcie->root_bus_nr, devfn),
> > +                                       TLP_WRITE_TAG);
> > +       headers[2] = TLP_CFG_DW2(bus, devfn, where);
> > +
> > +       tlp_write_packet(pcie, headers, value);
> > +
> > +       tlp_read_packet(pcie, NULL);
>
> You need to check for the error here.
Okay.

>
> > +
> > +       /* Keep an eye out for changes to the root bus number */
> > +       if ((bus == pcie->root_bus_nr) && (where == PCI_PRIMARY_BUS))
> > +               pcie->root_bus_nr = (u8)(value);
> > +
> > +       return PCIBIOS_SUCCESSFUL;
> > +}
> > +
>
> <snip>
>
> > +
> > +static int altera_pcie_parse_dt(struct altera_pcie *pcie)
> > +{
> > +       struct resource *cra;
> > +       struct platform_device *pdev = pcie->pdev;
> > +
> > +       cra = platform_get_resource_byname(pdev, IORESOURCE_MEM, "Cra");
> > +       if (!cra) {
> > +               cra = platform_get_resource_byname(pdev, IORESOURCE_MEM, "cra");
> > +               if (!cra) {
> > +                       dev_err(&pdev->dev,
> > +                               "no cra memory resource defined\n");
> > +                       return -ENODEV;
> > +               }
> > +       }
> > +
>
> What about "Txs"?
We doesn't need to get resource for "Txs" here. We use standard pci
binding with "ranges" dts parameter to map the pci memory region.
Our dts generator still will generate this "Txs" dts parameter,
because it is one of Avalon slave port of PCIe IP.


Regards
Ley Foon


From lftan at altera.com  Tue Aug 18 18:28:48 2015
From: lftan at altera.com (Ley Foon Tan)
Date: Wed, 19 Aug 2015 09:28:48 +0800
Subject: [PATCH v4 4/5] Documentation: dt-bindings: pci: altera pcie
 device tree binding
In-Reply-To: <CADhT+wdwYQWq=yiw1R9YEXX=WTDtoj-5=6EysX=aHUjdSvU89w@mail.gmail.com>
References: <1439802579-22651-1-git-send-email-lftan@altera.com>
 <1439802579-22651-5-git-send-email-lftan@altera.com>
 <CADhT+wdwYQWq=yiw1R9YEXX=WTDtoj-5=6EysX=aHUjdSvU89w@mail.gmail.com>
Message-ID: <CAFiDJ59Y0-w7vNcgNU6Y1F_a1vtamTeeNS-dTSb5JHOLjG2MgQ@mail.gmail.com>

On Wed, Aug 19, 2015 at 3:22 AM, Dinh Nguyen <dinh.linux at gmail.com> wrote:
> On Mon, Aug 17, 2015 at 4:09 AM, Ley Foon Tan <lftan at altera.com> wrote:
>> This patch adds the bindings for Altera PCIe host controller driver and
>> Altera PCIe MSI driver.
>>
>> Signed-off-by: Ley Foon Tan <lftan at altera.com>
>> ---
>>  .../devicetree/bindings/pci/altera-pcie-msi.txt    | 27 ++++++++++++
>>  .../devicetree/bindings/pci/altera-pcie.txt        | 49 ++++++++++++++++++++++
>>  2 files changed, 76 insertions(+)
>>  create mode 100644 Documentation/devicetree/bindings/pci/altera-pcie-msi.txt
>>  create mode 100644 Documentation/devicetree/bindings/pci/altera-pcie.txt
>>
>> diff --git a/Documentation/devicetree/bindings/pci/altera-pcie-msi.txt b/Documentation/devicetree/bindings/pci/altera-pcie-msi.txt
>> new file mode 100644
>> index 0000000..7f330c9
>> --- /dev/null
>> +++ b/Documentation/devicetree/bindings/pci/altera-pcie-msi.txt
>> @@ -0,0 +1,27 @@
>> +* Altera PCIe MSI controller
>> +
>> +Required properties:
>> +- compatible:  should contain "altr,msi-1.0"
>> +- reg:         specifies the physical base address of the controller and
>> +               the length of the memory mapped region.
>> +- reg-names:   Must include the following entries:
>> +               "csr": CSR registers
>> +               "vector_slave": vectors region
>
> Can you be a little bit more specific here? What is a vectors region?
> Also, I'm not 100% sure, but I think "vector-slave" should be used.
This parameter is the Avalon slave name in MSI IP hardware. It is auto
generated from dts generator.
I can add more description for it here.

>
>> +-interrupts:   specifies the interrupt source of the parent interrupt
>> +               controller. The format of the interrupt specifier depends on the
>> +               parent interrupt controller.
>
> Need to document "interrupt-parent" .
Okay.

>
>> +- num-vectors: Number of vectors, range 1 to 32.
>> +- msi-controller:      indicates that this is MSI controller node
>> +
>> +
>> +Example
>> +msi0: msi at 0xFF200000 {
>> +       compatible = "altr,msi-1.0";
>> +       reg = <0xFF200000 0x00000010
>> +               0xFF200010 0x00000080>;
>> +       reg-names = "csr", "vector_slave";
>> +       interrupt-parent = <&hps_0_arm_gic_0>;
>> +       interrupts = <0 42 4>;
>> +       msi-controller = <1>;
>> +       num-vectors = <32>;
>> +};
>> diff --git a/Documentation/devicetree/bindings/pci/altera-pcie.txt b/Documentation/devicetree/bindings/pci/altera-pcie.txt
>> new file mode 100644
>> index 0000000..73a8dc0
>> --- /dev/null
>> +++ b/Documentation/devicetree/bindings/pci/altera-pcie.txt
>> @@ -0,0 +1,49 @@
>> +* Altera PCIe controller
>> +
>> +Required properties:
>> +- compatible : should contain "altr,pcie-root-port-1.0"
>> +- reg:         A list of physical base address and length for TXS and CRA.
>> +- reg-names:   Must include the following entries:
>> +               "Txs" or "txs": TXS region
>
> What is a TXS region?
It is TX slave port in PCIe IP. I can update this.

>
>> +               "Cra" or "cra": Control register access region
>> +-interrupts:   specifies the interrupt source of the parent interrupt controller.
>> +               The format of the interrupt specifier depends on the parent interrupt
>> +               controller.
>> +- device_type: must be "pci"
>> +- #address-cells:      set to <3>
>> +- #size-cells: set to <2>
>> +- #interrupt-cells:    set to <1>
>> +- ranges:              Describes the translation of addresses for root ports and standard
>> +               PCI regions.
>> +- interrupt-map-mask and interrupt-map: standard PCI properties
>> +       to define the mapping of the PCIe interface to interrupt
>> +       numbers.
>
> "interrupt-parent" ?
Will add it.

Thanks.

Regards
Ley Foon


From pi-cheng.chen at linaro.org  Tue Aug 18 19:05:06 2015
From: pi-cheng.chen at linaro.org (Pi-Cheng Chen)
Date: Wed, 19 Aug 2015 10:05:06 +0800
Subject: [PATCH v7 2/3] cpufreq: mediatek: Add MT8173 cpufreq driver
In-Reply-To: <20150818102428.GD31148@linux>
References: <20150818102428.GD31148@linux>
Message-ID: <1439949906-22177-1-git-send-email-pi-cheng.chen@linaro.org>

Mediatek MT8173 is an ARMv8 based quad-core (2*Cortex-A53 and
2*Cortex-A72) SoC with duall clusters. For each cluster, two voltage
inputs, Vproc and Vsram are supplied by two regulators. For the big
cluster, two regulators come from different PMICs. In this case, when
scaling voltage inputs of the cluster, the voltages of two regulator
inputs need to be controlled by software explicitly under the SoC
specific limitation:

	100mV < Vsram - Vproc < 200mV

which is called 'voltage tracking' mechanism. And when scaling the
frequency of cluster clock input, the input MUX need to be parented to
another "intermediate" stable PLL first and reparented to the original
PLL once the original PLL is stable at the target frequency. This patch
implements those mechanisms to enable CPU DVFS support for Mediatek
MT8173 SoC.

Signed-off-by: Pi-Cheng Chen <pi-cheng.chen at linaro.org>
Acked-by: Viresh Kumar <viresh.kumar at linaro.org>
---

Changes in v7:
- add of_machine_is_compatible() check to be multiplatform friendly

---
 drivers/cpufreq/Kconfig.arm      |   7 +
 drivers/cpufreq/Makefile         |   1 +
 drivers/cpufreq/mt8173-cpufreq.c | 527 +++++++++++++++++++++++++++++++++++++++
 3 files changed, 535 insertions(+)
 create mode 100644 drivers/cpufreq/mt8173-cpufreq.c

diff --git a/drivers/cpufreq/Kconfig.arm b/drivers/cpufreq/Kconfig.arm
index cc8a71c..2bacf24 100644
--- a/drivers/cpufreq/Kconfig.arm
+++ b/drivers/cpufreq/Kconfig.arm
@@ -130,6 +130,13 @@ config ARM_KIRKWOOD_CPUFREQ
 	  This adds the CPUFreq driver for Marvell Kirkwood
 	  SoCs.
 
+config ARM_MT8173_CPUFREQ
+	bool "Mediatek MT8173 CPUFreq support"
+	depends on ARCH_MEDIATEK && REGULATOR
+	select PM_OPP
+	help
+	  This adds the CPUFreq driver support for Mediatek MT8173 SoC.
+
 config ARM_OMAP2PLUS_CPUFREQ
 	bool "TI OMAP2+"
 	depends on ARCH_OMAP2PLUS
diff --git a/drivers/cpufreq/Makefile b/drivers/cpufreq/Makefile
index 2169bf7..9c75faf 100644
--- a/drivers/cpufreq/Makefile
+++ b/drivers/cpufreq/Makefile
@@ -62,6 +62,7 @@ obj-$(CONFIG_ARM_HISI_ACPU_CPUFREQ)	+= hisi-acpu-cpufreq.o
 obj-$(CONFIG_ARM_IMX6Q_CPUFREQ)		+= imx6q-cpufreq.o
 obj-$(CONFIG_ARM_INTEGRATOR)		+= integrator-cpufreq.o
 obj-$(CONFIG_ARM_KIRKWOOD_CPUFREQ)	+= kirkwood-cpufreq.o
+obj-$(CONFIG_ARM_MT8173_CPUFREQ)	+= mt8173-cpufreq.o
 obj-$(CONFIG_ARM_OMAP2PLUS_CPUFREQ)	+= omap-cpufreq.o
 obj-$(CONFIG_ARM_PXA2xx_CPUFREQ)	+= pxa2xx-cpufreq.o
 obj-$(CONFIG_PXA3xx)			+= pxa3xx-cpufreq.o
diff --git a/drivers/cpufreq/mt8173-cpufreq.c b/drivers/cpufreq/mt8173-cpufreq.c
new file mode 100644
index 0000000..49caed2
--- /dev/null
+++ b/drivers/cpufreq/mt8173-cpufreq.c
@@ -0,0 +1,527 @@
+/*
+ * Copyright (c) 2015 Linaro Ltd.
+ * Author: Pi-Cheng Chen <pi-cheng.chen at linaro.org>
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License version 2 as
+ * published by the Free Software Foundation.
+ *
+ * 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.h>
+#include <linux/cpu.h>
+#include <linux/cpu_cooling.h>
+#include <linux/cpufreq.h>
+#include <linux/cpumask.h>
+#include <linux/of.h>
+#include <linux/platform_device.h>
+#include <linux/pm_opp.h>
+#include <linux/regulator/consumer.h>
+#include <linux/slab.h>
+#include <linux/thermal.h>
+
+#define MIN_VOLT_SHIFT		(100000)
+#define MAX_VOLT_SHIFT		(200000)
+#define MAX_VOLT_LIMIT		(1150000)
+#define VOLT_TOL		(10000)
+
+/*
+ * The struct mtk_cpu_dvfs_info holds necessary information for doing CPU DVFS
+ * on each CPU power/clock domain of Mediatek SoCs. Each CPU cluster in
+ * Mediatek SoCs has two voltage inputs, Vproc and Vsram. In some cases the two
+ * voltage inputs need to be controlled under a hardware limitation:
+ * 100mV < Vsram - Vproc < 200mV
+ *
+ * When scaling the clock frequency of a CPU clock domain, the clock source
+ * needs to be switched to another stable PLL clock temporarily until
+ * the original PLL becomes stable at target frequency.
+ */
+struct mtk_cpu_dvfs_info {
+	struct device *cpu_dev;
+	struct regulator *proc_reg;
+	struct regulator *sram_reg;
+	struct clk *cpu_clk;
+	struct clk *inter_clk;
+	struct thermal_cooling_device *cdev;
+	int intermediate_voltage;
+	bool need_voltage_tracking;
+};
+
+static int mtk_cpufreq_voltage_tracking(struct mtk_cpu_dvfs_info *info,
+					int new_vproc)
+{
+	struct regulator *proc_reg = info->proc_reg;
+	struct regulator *sram_reg = info->sram_reg;
+	int old_vproc, old_vsram, new_vsram, vsram, vproc, ret;
+
+	old_vproc = regulator_get_voltage(proc_reg);
+	old_vsram = regulator_get_voltage(sram_reg);
+	/* Vsram should not exceed the maximum allowed voltage of SoC. */
+	new_vsram = min(new_vproc + MIN_VOLT_SHIFT, MAX_VOLT_LIMIT);
+
+	if (old_vproc < new_vproc) {
+		/*
+		 * When scaling up voltages, Vsram and Vproc scale up step
+		 * by step. At each step, set Vsram to (Vproc + 200mV) first,
+		 * then set Vproc to (Vsram - 100mV).
+		 * Keep doing it until Vsram and Vproc hit target voltages.
+		 */
+		do {
+			old_vsram = regulator_get_voltage(sram_reg);
+			old_vproc = regulator_get_voltage(proc_reg);
+
+			vsram = min(new_vsram, old_vproc + MAX_VOLT_SHIFT);
+
+			if (vsram + VOLT_TOL >= MAX_VOLT_LIMIT) {
+				vsram = MAX_VOLT_LIMIT;
+
+				/*
+				 * If the target Vsram hits the maximum voltage,
+				 * try to set the exact voltage value first.
+				 */
+				ret = regulator_set_voltage(sram_reg, vsram,
+							    vsram);
+				if (ret)
+					ret = regulator_set_voltage(sram_reg,
+							vsram - VOLT_TOL,
+							vsram);
+
+				vproc = new_vproc;
+			} else {
+				ret = regulator_set_voltage(sram_reg, vsram,
+							    vsram + VOLT_TOL);
+
+				vproc = vsram - MIN_VOLT_SHIFT;
+			}
+			if (ret)
+				return ret;
+
+			ret = regulator_set_voltage(proc_reg, vproc,
+						    vproc + VOLT_TOL);
+			if (ret) {
+				regulator_set_voltage(sram_reg, old_vsram,
+						      old_vsram);
+				return ret;
+			}
+		} while (vproc < new_vproc || vsram < new_vsram);
+	} else if (old_vproc > new_vproc) {
+		/*
+		 * When scaling down voltages, Vsram and Vproc scale down step
+		 * by step. At each step, set Vproc to (Vsram - 200mV) first,
+		 * then set Vproc to (Vproc + 100mV).
+		 * Keep doing it until Vsram and Vproc hit target voltages.
+		 */
+		do {
+			old_vproc = regulator_get_voltage(proc_reg);
+			old_vsram = regulator_get_voltage(sram_reg);
+
+			vproc = max(new_vproc, old_vsram - MAX_VOLT_SHIFT);
+			ret = regulator_set_voltage(proc_reg, vproc,
+						    vproc + VOLT_TOL);
+			if (ret)
+				return ret;
+
+			if (vproc == new_vproc)
+				vsram = new_vsram;
+			else
+				vsram = max(new_vsram, vproc + MIN_VOLT_SHIFT);
+
+			if (vsram + VOLT_TOL >= MAX_VOLT_LIMIT) {
+				vsram = MAX_VOLT_LIMIT;
+
+				/*
+				 * If the target Vsram hits the maximum voltage,
+				 * try to set the exact voltage value first.
+				 */
+				ret = regulator_set_voltage(sram_reg, vsram,
+							    vsram);
+				if (ret)
+					ret = regulator_set_voltage(sram_reg,
+							vsram - VOLT_TOL,
+							vsram);
+			} else {
+				ret = regulator_set_voltage(sram_reg, vsram,
+							    vsram + VOLT_TOL);
+			}
+
+			if (ret) {
+				regulator_set_voltage(proc_reg, old_vproc,
+						      old_vproc);
+				return ret;
+			}
+		} while (vproc > new_vproc + VOLT_TOL ||
+			 vsram > new_vsram + VOLT_TOL);
+	}
+
+	return 0;
+}
+
+static int mtk_cpufreq_set_voltage(struct mtk_cpu_dvfs_info *info, int vproc)
+{
+	if (info->need_voltage_tracking)
+		return mtk_cpufreq_voltage_tracking(info, vproc);
+	else
+		return regulator_set_voltage(info->proc_reg, vproc,
+					     vproc + VOLT_TOL);
+}
+
+static int mtk_cpufreq_set_target(struct cpufreq_policy *policy,
+				  unsigned int index)
+{
+	struct cpufreq_frequency_table *freq_table = policy->freq_table;
+	struct clk *cpu_clk = policy->clk;
+	struct clk *armpll = clk_get_parent(cpu_clk);
+	struct mtk_cpu_dvfs_info *info = policy->driver_data;
+	struct device *cpu_dev = info->cpu_dev;
+	struct dev_pm_opp *opp;
+	long freq_hz, old_freq_hz;
+	int vproc, old_vproc, inter_vproc, target_vproc, ret;
+
+	inter_vproc = info->intermediate_voltage;
+
+	old_freq_hz = clk_get_rate(cpu_clk);
+	old_vproc = regulator_get_voltage(info->proc_reg);
+
+	freq_hz = freq_table[index].frequency * 1000;
+
+	rcu_read_lock();
+	opp = dev_pm_opp_find_freq_ceil(cpu_dev, &freq_hz);
+	if (IS_ERR(opp)) {
+		rcu_read_unlock();
+		pr_err("cpu%d: failed to find OPP for %ld\n",
+		       policy->cpu, freq_hz);
+		return PTR_ERR(opp);
+	}
+	vproc = dev_pm_opp_get_voltage(opp);
+	rcu_read_unlock();
+
+	/*
+	 * If the new voltage or the intermediate voltage is higher than the
+	 * current voltage, scale up voltage first.
+	 */
+	target_vproc = (inter_vproc > vproc) ? inter_vproc : vproc;
+	if (old_vproc < target_vproc) {
+		ret = mtk_cpufreq_set_voltage(info, target_vproc);
+		if (ret) {
+			pr_err("cpu%d: failed to scale up voltage!\n",
+			       policy->cpu);
+			mtk_cpufreq_set_voltage(info, old_vproc);
+			return ret;
+		}
+	}
+
+	/* Reparent the CPU clock to intermediate clock. */
+	ret = clk_set_parent(cpu_clk, info->inter_clk);
+	if (ret) {
+		pr_err("cpu%d: failed to re-parent cpu clock!\n",
+		       policy->cpu);
+		mtk_cpufreq_set_voltage(info, old_vproc);
+		WARN_ON(1);
+		return ret;
+	}
+
+	/* Set the original PLL to target rate. */
+	ret = clk_set_rate(armpll, freq_hz);
+	if (ret) {
+		pr_err("cpu%d: failed to scale cpu clock rate!\n",
+		       policy->cpu);
+		clk_set_parent(cpu_clk, armpll);
+		mtk_cpufreq_set_voltage(info, old_vproc);
+		return ret;
+	}
+
+	/* Set parent of CPU clock back to the original PLL. */
+	ret = clk_set_parent(cpu_clk, armpll);
+	if (ret) {
+		pr_err("cpu%d: failed to re-parent cpu clock!\n",
+		       policy->cpu);
+		mtk_cpufreq_set_voltage(info, inter_vproc);
+		WARN_ON(1);
+		return ret;
+	}
+
+	/*
+	 * If the new voltage is lower than the intermediate voltage or the
+	 * original voltage, scale down to the new voltage.
+	 */
+	if (vproc < inter_vproc || vproc < old_vproc) {
+		ret = mtk_cpufreq_set_voltage(info, vproc);
+		if (ret) {
+			pr_err("cpu%d: failed to scale down voltage!\n",
+			       policy->cpu);
+			clk_set_parent(cpu_clk, info->inter_clk);
+			clk_set_rate(armpll, old_freq_hz);
+			clk_set_parent(cpu_clk, armpll);
+			return ret;
+		}
+	}
+
+	return 0;
+}
+
+static void mtk_cpufreq_ready(struct cpufreq_policy *policy)
+{
+	struct mtk_cpu_dvfs_info *info = policy->driver_data;
+	struct device_node *np = of_node_get(info->cpu_dev->of_node);
+
+	if (WARN_ON(!np))
+		return;
+
+	if (of_find_property(np, "#cooling-cells", NULL)) {
+		info->cdev = of_cpufreq_cooling_register(np,
+							 policy->related_cpus);
+
+		if (IS_ERR(info->cdev)) {
+			dev_err(info->cpu_dev,
+				"running cpufreq without cooling device: %ld\n",
+				PTR_ERR(info->cdev));
+
+			info->cdev = NULL;
+		}
+	}
+
+	of_node_put(np);
+}
+
+static int mtk_cpu_dvfs_info_init(struct mtk_cpu_dvfs_info *info, int cpu)
+{
+	struct device *cpu_dev;
+	struct regulator *proc_reg = ERR_PTR(-ENODEV);
+	struct regulator *sram_reg = ERR_PTR(-ENODEV);
+	struct clk *cpu_clk = ERR_PTR(-ENODEV);
+	struct clk *inter_clk = ERR_PTR(-ENODEV);
+	struct dev_pm_opp *opp;
+	unsigned long rate;
+	int ret;
+
+	cpu_dev = get_cpu_device(cpu);
+	if (!cpu_dev) {
+		pr_err("failed to get cpu%d device\n", cpu);
+		return -ENODEV;
+	}
+
+	cpu_clk = clk_get(cpu_dev, "cpu");
+	if (IS_ERR(cpu_clk)) {
+		if (PTR_ERR(cpu_clk) == -EPROBE_DEFER)
+			pr_warn("cpu clk for cpu%d not ready, retry.\n", cpu);
+		else
+			pr_err("failed to get cpu clk for cpu%d\n", cpu);
+
+		ret = PTR_ERR(cpu_clk);
+		return ret;
+	}
+
+	inter_clk = clk_get(cpu_dev, "intermediate");
+	if (IS_ERR(inter_clk)) {
+		if (PTR_ERR(inter_clk) == -EPROBE_DEFER)
+			pr_warn("intermediate clk for cpu%d not ready, retry.\n",
+				cpu);
+		else
+			pr_err("failed to get intermediate clk for cpu%d\n",
+			       cpu);
+
+		ret = PTR_ERR(inter_clk);
+		goto out_free_resources;
+	}
+
+	proc_reg = regulator_get_exclusive(cpu_dev, "proc");
+	if (IS_ERR(proc_reg)) {
+		if (PTR_ERR(proc_reg) == -EPROBE_DEFER)
+			pr_warn("proc regulator for cpu%d not ready, retry.\n",
+				cpu);
+		else
+			pr_err("failed to get proc regulator for cpu%d\n",
+			       cpu);
+
+		ret = PTR_ERR(proc_reg);
+		goto out_free_resources;
+	}
+
+	/* Both presence and absence of sram regulator are valid cases. */
+	sram_reg = regulator_get_exclusive(cpu_dev, "sram");
+
+	ret = of_init_opp_table(cpu_dev);
+	if (ret) {
+		pr_warn("no OPP table for cpu%d\n", cpu);
+		goto out_free_resources;
+	}
+
+	/* Search a safe voltage for intermediate frequency. */
+	rate = clk_get_rate(inter_clk);
+	rcu_read_lock();
+	opp = dev_pm_opp_find_freq_ceil(cpu_dev, &rate);
+	if (IS_ERR(opp)) {
+		rcu_read_unlock();
+		pr_err("failed to get intermediate opp for cpu%d\n", cpu);
+		ret = PTR_ERR(opp);
+		goto out_free_opp_table;
+	}
+	info->intermediate_voltage = dev_pm_opp_get_voltage(opp);
+	rcu_read_unlock();
+
+	info->cpu_dev = cpu_dev;
+	info->proc_reg = proc_reg;
+	info->sram_reg = IS_ERR(sram_reg) ? NULL : sram_reg;
+	info->cpu_clk = cpu_clk;
+	info->inter_clk = inter_clk;
+
+	/*
+	 * If SRAM regulator is present, software "voltage tracking" is needed
+	 * for this CPU power domain.
+	 */
+	info->need_voltage_tracking = !IS_ERR(sram_reg);
+
+	return 0;
+
+out_free_opp_table:
+	of_free_opp_table(cpu_dev);
+
+out_free_resources:
+	if (!IS_ERR(proc_reg))
+		regulator_put(proc_reg);
+	if (!IS_ERR(sram_reg))
+		regulator_put(sram_reg);
+	if (!IS_ERR(cpu_clk))
+		clk_put(cpu_clk);
+	if (!IS_ERR(inter_clk))
+		clk_put(inter_clk);
+
+	return ret;
+}
+
+static void mtk_cpu_dvfs_info_release(struct mtk_cpu_dvfs_info *info)
+{
+	if (!IS_ERR(info->proc_reg))
+		regulator_put(info->proc_reg);
+	if (!IS_ERR(info->sram_reg))
+		regulator_put(info->sram_reg);
+	if (!IS_ERR(info->cpu_clk))
+		clk_put(info->cpu_clk);
+	if (!IS_ERR(info->inter_clk))
+		clk_put(info->inter_clk);
+
+	of_free_opp_table(info->cpu_dev);
+}
+
+static int mtk_cpufreq_init(struct cpufreq_policy *policy)
+{
+	struct mtk_cpu_dvfs_info *info;
+	struct cpufreq_frequency_table *freq_table;
+	int ret;
+
+	info = kzalloc(sizeof(*info), GFP_KERNEL);
+	if (!info)
+		return -ENOMEM;
+
+	ret = mtk_cpu_dvfs_info_init(info, policy->cpu);
+	if (ret) {
+		pr_err("%s failed to initialize dvfs info for cpu%d\n",
+		       __func__, policy->cpu);
+		goto out_free_dvfs_info;
+	}
+
+	ret = dev_pm_opp_init_cpufreq_table(info->cpu_dev, &freq_table);
+	if (ret) {
+		pr_err("failed to init cpufreq table for cpu%d: %d\n",
+		       policy->cpu, ret);
+		goto out_release_dvfs_info;
+	}
+
+	ret = cpufreq_table_validate_and_show(policy, freq_table);
+	if (ret) {
+		pr_err("%s: invalid frequency table: %d\n", __func__, ret);
+		goto out_free_cpufreq_table;
+	}
+
+	/* CPUs in the same cluster share a clock and power domain. */
+	cpumask_copy(policy->cpus, &cpu_topology[policy->cpu].core_sibling);
+	policy->driver_data = info;
+	policy->clk = info->cpu_clk;
+
+	return 0;
+
+out_free_cpufreq_table:
+	dev_pm_opp_free_cpufreq_table(info->cpu_dev, &freq_table);
+
+out_release_dvfs_info:
+	mtk_cpu_dvfs_info_release(info);
+
+out_free_dvfs_info:
+	kfree(info);
+
+	return ret;
+}
+
+static int mtk_cpufreq_exit(struct cpufreq_policy *policy)
+{
+	struct mtk_cpu_dvfs_info *info = policy->driver_data;
+
+	cpufreq_cooling_unregister(info->cdev);
+	dev_pm_opp_free_cpufreq_table(info->cpu_dev, &policy->freq_table);
+	mtk_cpu_dvfs_info_release(info);
+	kfree(info);
+
+	return 0;
+}
+
+static struct cpufreq_driver mt8173_cpufreq_driver = {
+	.flags = CPUFREQ_STICKY | CPUFREQ_NEED_INITIAL_FREQ_CHECK,
+	.verify = cpufreq_generic_frequency_table_verify,
+	.target_index = mtk_cpufreq_set_target,
+	.get = cpufreq_generic_get,
+	.init = mtk_cpufreq_init,
+	.exit = mtk_cpufreq_exit,
+	.ready = mtk_cpufreq_ready,
+	.name = "mtk-cpufreq",
+	.attr = cpufreq_generic_attr,
+};
+
+static int mt8173_cpufreq_probe(struct platform_device *pdev)
+{
+	int ret;
+
+	ret = cpufreq_register_driver(&mt8173_cpufreq_driver);
+	if (ret)
+		pr_err("failed to register mtk cpufreq driver\n");
+
+	return ret;
+}
+
+static struct platform_driver mt8173_cpufreq_platdrv = {
+	.driver = {
+		.name	= "mt8173-cpufreq",
+	},
+	.probe		= mt8173_cpufreq_probe,
+};
+
+static int mt8173_cpufreq_driver_init(void)
+{
+	struct platform_device *pdev;
+	int err;
+
+	if (!of_machine_is_compatible("mediatek,mt8173"))
+		return -ENODEV;
+
+	err = platform_driver_register(&mt8173_cpufreq_platdrv);
+	if (err)
+		return err;
+
+	/*
+	 * Since there's no place to hold device registration code and no
+	 * device tree based way to match cpufreq driver yet, both the driver
+	 * and the device registration codes are put here to handle defer
+	 * probing.
+	 */
+	pdev = platform_device_register_simple("mt8173-cpufreq", -1, NULL, 0);
+	if (IS_ERR(pdev)) {
+		pr_err("failed to register mtk-cpufreq platform device\n");
+		return PTR_ERR(pdev);
+	}
+
+	return 0;
+}
+device_initcall(mt8173_cpufreq_driver_init);
-- 
1.9.1



From majun258 at huawei.com  Tue Aug 18 19:55:18 2015
From: majun258 at huawei.com (MaJun)
Date: Wed, 19 Aug 2015 10:55:18 +0800
Subject: [PATCH v4 0/2] Support Mbigen interrupt controller
Message-ID: <1439952920-2296-1-git-send-email-majun258@huawei.com>

From: Ma Jun <majun258 at huawei.com>

This patch adds the driver of mbigen and binding document for Hisilicon
Mbigen chips.

Compared with previous version, this version changed much.

Because during the time between V3 and V4 of my patch, there are two
related patches were committed by Mr.Marc Zyngier and Mr. Mark Rutland.

First, Mr. Marc Zyngier changed MSI frame and added supporting for
platform MSI.

https://lkml.org/lkml/2015/7/28/552

Second, Mr.Mark Rutland changed Generic PCI MSI + IOMMU topology bindings

https://lkml.org/lkml/2015/7/23/558 

Changes since v3:
--- Re-based mbigen driver on kernel 4.2.0-rc2 and Marc's patch
--- Changed the binding document based on Mark's patch.


Ma Jun (2):
  Add the driver of mbigen interrupt controller
  dt-binding:Documents of the mbigen bindings

 Documentation/devicetree/bindings/arm/mbigen.txt |   97 +++
 drivers/irqchip/Kconfig                          |    8 +
 drivers/irqchip/Makefile                         |    1 +
 drivers/irqchip/irq-mbigen.c                     |  732 ++++++++++++++++++++++
 4 files changed, 838 insertions(+), 0 deletions(-)
 create mode 100644 Documentation/devicetree/bindings/arm/mbigen.txt
 create mode 100644 drivers/irqchip/irq-mbigen.c




From majun258 at huawei.com  Tue Aug 18 19:55:20 2015
From: majun258 at huawei.com (MaJun)
Date: Wed, 19 Aug 2015 10:55:20 +0800
Subject: [PATCH v4 2/2] dt-binding:Documents of the mbigen bindings
In-Reply-To: <1439952920-2296-1-git-send-email-majun258@huawei.com>
References: <1439952920-2296-1-git-send-email-majun258@huawei.com>
Message-ID: <1439952920-2296-3-git-send-email-majun258@huawei.com>

From: Ma Jun <majun258 at huawei.com>

Add the mbigen msi interrupt controller bindings document.

Change since v3:
--- Change the interrupt cells definition.
--- Change the mbigen node definition.
--- Add mbigen device node as sub node of mbigen.


Signed-off-by: Ma Jun <majun258 at huawei.com>
---
 Documentation/devicetree/bindings/arm/mbigen.txt |   97 ++++++++++++++++++++++
 1 files changed, 97 insertions(+), 0 deletions(-)
 create mode 100644 Documentation/devicetree/bindings/arm/mbigen.txt

diff --git a/Documentation/devicetree/bindings/arm/mbigen.txt b/Documentation/devicetree/bindings/arm/mbigen.txt
new file mode 100644
index 0000000..8e1203b
--- /dev/null
+++ b/Documentation/devicetree/bindings/arm/mbigen.txt
@@ -0,0 +1,97 @@
+Hisilicon mbigen device tree bindings.
+=======================================
+
+Mbigen means: message based interrupt generator.
+
+MBI is kind of msi interrupt only used on Non-PCI devices.
+
+To reduce the wired interrupt number connected to GIC,
+Hisilicon designed mbigen to collect and generate interrupt.
+
+
+Non-pci devices can connect to mbigen and generate the
+interrupt by writing ITS register.
+
+The mbigen chip and devices connect to mbigen have the following properties:
+
+Mbigen main node required properties:
+-------------------------------------------
+- compatible: Should be "hisilicon,mbigen-v2"
+- interrupt controller: Identifies the node as an interrupt controller
+- #interrupt-cells : Specifies the number of cells needed to encode an
+  interrupt source. The value is 4 now.
+
+  The 1st cell is the device id.
+  The 2nd cell is the mbigen node number. This value should refer to the
+  vendor Soc specification.
+  The 3rd cell is the hardware pin number of the interrupt.
+  This value depends on the Soc design.
+  The 4th cell is the interrupt trigger type, encoded as follows:
+		1 = edge triggered
+		4 = level triggered
+
+- #mbigen-node-cells :Specifies the number of cells needed to encode an
+  mbigen node information. The value is 3 now.
+
+  The 1st cell is the mbigen node number.
+  The 2nd cell is the interrupt numbers connected to.
+  The 3rd cell is the start value of pin offset.
+
+- reg: Specifies the base physical address and size of the Mbigen
+  registers.
+
+Sub-nodes:
+
+Mbigen has one or more mbigen device nodes which represents the devices
+connected to this mbigen chip.
+
+These nodes must have the following properties:
+- msi-parent: This property has two cells.
+	The 1st cell specifies the ITS this device connected.
+	The 2nd cell specifies the device id.
+- nr-interrupts:Specifies the total number of interrupt this device has.
+- mbigen_node: Specifies the information of mbigen nodes this device
+  connected.Some devices with many interrupts maybe connects with several
+  mbigen nodes.
+
+Examples:
+
+		mbigen_dsa: interrupt-controller at c0080000 {
+			compatible = "hisilicon,mbigen-v2";
+			interrupt-controller;
+			#interrupt-cells = <5>;
+			#mbigen-node-cells = <3>;
+			reg = <0xc0080000 0x10000>;
+
+			mbigen_device_01 {
+				msi-parent = <&its 0x40b1c>;
+				nr-interrupts = <9>;
+				mbigen_node = <1 2 0>,
+							<3 2 4>,
+							<4 5 0>;
+			}
+
+			mbigen_device_02 {
+				msi-parent = <&its 0x40b1d>;
+				nr-interrupts = <3>;
+				mbigen_node = <6 3 0>;
+				interrupt-controller;
+			}
+		};
+
+Device connect to mbigen required properties:
+----------------------------------------------------
+-interrupt-parent: Specifies the mbigen node which device connected.
+-interrupts:specifies the interrupt source.The first cell is hwirq num, the
+  second number is trigger type.
+
+Examples:
+	smmu_dsa {
+		compatible = "arm,smmu-v3";
+		reg = <0x0 0xc0040000 0x0 0x20000>;
+		interrupt-parent  = <&mbigen_dsa>;
+		interrupts = <0x40b20 6 78 1>,
+				<0x40b20 6 79 1>,
+				<0x40b20 6 80 1>;
+	};
+
-- 
1.7.1




From majun258 at huawei.com  Tue Aug 18 19:55:19 2015
From: majun258 at huawei.com (MaJun)
Date: Wed, 19 Aug 2015 10:55:19 +0800
Subject: [PATCH v4 1/2] Add the driver of mbigen interrupt controller
In-Reply-To: <1439952920-2296-1-git-send-email-majun258@huawei.com>
References: <1439952920-2296-1-git-send-email-majun258@huawei.com>
Message-ID: <1439952920-2296-2-git-send-email-majun258@huawei.com>

From: Ma Jun <majun258 at huawei.com>

Mbigen means Message Based Interrupt Generator(MBIGEN).

Its a kind of interrupt controller that collects

the interrupts from external devices and generate msi interrupt.

Mbigen is applied to reduce the number of wire connected interrupts.

As the peripherals increasing, the interrupts lines needed is 
increasing much, especially on the Arm64 server soc.

Therefore, the interrupt pin in gic is not enough to cover so
many peripherals.

Mbigen is designed to fix this problem.

Mbigen chip locates in ITS or outside of ITS.

Mbigen chip hardware structure shows as below:

		mbigen chip
|---------------------|-------------------|
mgn_node0	  mgn_node1		mgn_node2
 |		 |-------|		|-------|------|        
dev1		dev1    dev2		dev1   dev3   dev4

Each mbigen chip contains several mbigen nodes.

External devices can connects to mbigen node through wire connecting way.

Because a mbigen node only can support 128 interrupt maximum, depends
on the interrupt lines number of devices, a device can connects to one
more mbigen nodes.

Also, several different devices can connect to a same mbigen node.

When devices triggered interrupt,mbigen chip detects and collects 
the interrupts and generates the MBI interrupts by writing the ITS
Translator register.


Signed-off-by: Ma Jun <majun258 at huawei.com>
---
 drivers/irqchip/Kconfig      |    8 +
 drivers/irqchip/Makefile     |    1 +
 drivers/irqchip/irq-mbigen.c |  732 ++++++++++++++++++++++++++++++++++++++++++
 3 files changed, 741 insertions(+), 0 deletions(-)
 create mode 100644 drivers/irqchip/irq-mbigen.c

diff --git a/drivers/irqchip/Kconfig b/drivers/irqchip/Kconfig
index 120d815..356507f 100644
--- a/drivers/irqchip/Kconfig
+++ b/drivers/irqchip/Kconfig
@@ -27,6 +27,14 @@ config ARM_GIC_V3_ITS
 	bool
 	select PCI_MSI_IRQ_DOMAIN
 
+config HISILICON_IRQ_MBIGEN
+	bool "Support mbigen interrupt controller"
+	default n
+	depends on ARM_GIC_V3 && ARM_GIC_V3_ITS
+	help
+	 Enable the mbigen interrupt controller used on
+	 Hisilicon platform.
+
 config ARM_NVIC
 	bool
 	select IRQ_DOMAIN
diff --git a/drivers/irqchip/Makefile b/drivers/irqchip/Makefile
index 11d08c9..c6f3d66 100644
--- a/drivers/irqchip/Makefile
+++ b/drivers/irqchip/Makefile
@@ -23,6 +23,7 @@ obj-$(CONFIG_ARM_GIC)			+= irq-gic.o irq-gic-common.o
 obj-$(CONFIG_ARM_GIC_V2M)		+= irq-gic-v2m.o
 obj-$(CONFIG_ARM_GIC_V3)		+= irq-gic-v3.o irq-gic-common.o
 obj-$(CONFIG_ARM_GIC_V3_ITS)		+= irq-gic-v3-its.o irq-gic-v3-its-pci-msi.o irq-gic-v3-its-platform-msi.o
+obj-$(CONFIG_HISILICON_IRQ_MBIGEN)	+= irq-mbigen.o
 obj-$(CONFIG_ARM_NVIC)			+= irq-nvic.o
 obj-$(CONFIG_ARM_VIC)			+= irq-vic.o
 obj-$(CONFIG_ATMEL_AIC_IRQ)		+= irq-atmel-aic-common.o irq-atmel-aic.o
diff --git a/drivers/irqchip/irq-mbigen.c b/drivers/irqchip/irq-mbigen.c
new file mode 100644
index 0000000..4bbbd76
--- /dev/null
+++ b/drivers/irqchip/irq-mbigen.c
@@ -0,0 +1,732 @@
+/*
+ * Copyright (C) 2014 Hisilicon Limited, All Rights Reserved.
+ * Author: Jun Ma <majun258 at huawei.com>
+ * Author: Yun Wu <wuyun.wu at huawei.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.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program.  If not, see <http://www.gnu.org/licenses/>.
+ */
+
+#include <linux/init.h>
+#include <linux/io.h>
+#include <linux/slab.h>
+#include <linux/interrupt.h>
+#include <linux/irqchip/chained_irq.h>
+#include <linux/of_address.h>
+#include <linux/of_irq.h>
+#include <linux/of_platform.h>
+#include <linux/kernel.h>
+#include <linux/platform_device.h>
+#include <linux/module.h>
+#include <linux/msi.h>
+#include "irqchip.h"
+
+#define	MBIGEN_NODE_SHIFT	(8)
+#define MBIGEN_DEV_SHIFT	(12)
+
+/*
+ * To avoid the duplicate hwirq number problem
+ * we use device id, mbigen node number and interrupt
+ * pin offset to generate a new hwirq number in mbigen
+ * domain.
+ *
+ * hwirq[32:12]: did. device id
+ * hwirq[11:8]: nid. mbigen node number
+ * hwirq[7:0]: pin. hardware pin offset of this interrupt
+ */
+#define	COMPOSE_MBIGEN_HWIRQ(did, nid, pin)	\
+		(((did) << MBIGEN_DEV_SHIFT) | \
+		((nid) << MBIGEN_NODE_SHIFT) | (pin))
+
+/* get the interrupt pin offset from mbigen hwirq */
+#define	GET_IRQ_PIN_OFFSET(hwirq)	((hwirq) & 0xff)
+/* get the mbigen node number from mbigen hwirq */
+#define GET_MBIGEN_NODE_NUM(hwirq)	(((hwirq) >> MBIGEN_NODE_SHIFT) & 0xf)
+/* get the mbigen device id from mbigen hwirq */
+#define GET_MBIGEN_DEVICE_ID(hwirq)	\
+		(((hwirq) >> MBIGEN_DEV_SHIFT) & 0xfffff)
+
+/*
+ * In mbigen vector register
+ * bit[21:12]: event id value
+ * bit[11:0]: device id
+ */
+#define IRQ_EVENT_ID_SHIFT	(12)
+#define IRQ_EVENT_ID_MASK	(0x3ff)
+
+/* register range of mbigen node  */
+#define MBIGEN_NODE_OFFSET	0x1000
+
+/* offset of vector register in mbigen node */
+#define REG_MBIGEN_VEC_OFFSET	0x200
+
+/* offset of clear register in mbigen node.
+ * This register is used to clear the status
+ * of interrupt.
+ */
+#define REG_MBIGEN_CLEAR_OFFSET	0xa00
+
+/* offset of interrupt type register */
+#define REG_MBIGEN_TYPE_OFFSET	0x0
+
+/*
+ * get the base address of mbigen node
+ * nid: mbigen node number
+ */
+#define MBIGEN_NODE_ADDR_BASE(nid)	((nid) * MBIGEN_NODE_OFFSET)
+
+/*
+ * struct mbigen_chip - holds the information of mbigen
+ * chip.
+ * @lock: spin lock protecting mbigen device list
+ * @domain: irq domain of this mbigen chip.
+ * @node: represents the mbigen chip node defined in device tree
+ * @mbigen_device_list: list of devices connected to this mbigen chip.
+ * @base: mapped address of this mbigen chip.
+ */
+struct mbigen_chip {
+	raw_spinlock_t		lock;
+	struct list_head	entry;
+	struct irq_domain	*domain;
+	struct device_node	*node;
+	struct list_head	mbigen_device_list;
+	void __iomem		*base;
+};
+
+/*
+ * struct mbigen_device--Holds the  information of devices connected 
+ * to mbigen chip
+ * @lock: spin lock protecting mbigen node list
+ * @entry: node in mbigen chip's mbigen_device_list
+ * @chip: pointer to mbigen chip
+ * @mbigen_node_list: list of mbigen nodes.The interrupt lines
+		of some devices maybe connected with several different
+		mbigen nodes.
+ * @dev: device structure of this mbigen device.
+ * @node: represents the mbigen device node defined in device tree.
+ * @mgn_data: pointer to mbigen_irq_data
+ * @nr_irqs: the total interrupt lines of this device
+ * @did: device id
+*/
+struct mbigen_device {
+	raw_spinlock_t		lock;
+	struct list_head	entry;
+	struct mbigen_chip	*chip;
+	struct list_head 	mbigen_node_list;
+	struct device		dev;
+	struct device_node	*node;
+	struct mbigen_irq_data	*mgn_data;
+	unsigned int		nr_irqs;
+	unsigned int		did;
+};
+
+/*
+ * struct mbigen_node--structure of mbigen node.
+ * usually, a mbigen chip contains 8 ~ 11 mbigen nodes.
+ * Each mbigen nodes has its own register region.
+ * Devices connects to mbigen nodes directly.
+ *
+ * @entry: node in mbigen device's mbigen_node_list
+ * @node_num: mbigen node number.
+ * @pin_offset: the pin offset of first interrupt line
+ *		connected with this mbigen node.
+ * @irq_nr: the irq numbers of a device connected with mbigen node
+ * @msi_idx_offset: start of msi index of irq connected
+ *		to this mbigen node
+ */
+struct mbigen_node {
+	struct list_head	entry;
+	unsigned int		node_num;
+	unsigned int		pin_offset;
+	unsigned int		irq_nr;
+	unsigned int		index_offset;
+};
+
+/*
+ * struct mbigen_irq_data -- private data of each irq
+ *
+ * @parent_irq: irq number of this
+ * @devid: id of devices this irq belong to
+ * @nid: id of mbigen node this irq connected.
+ * @pin_offset: pin offset of this irq.
+ * @index: msi index of this irq
+ * @base: address of mbigen chip this irq connected.
+ * @dev: mbigen device this irq belong to.
+ */
+struct mbigen_irq_data {
+	struct mbigen_device	*dev;
+	void __iomem		*base;
+	unsigned int		parent_irq;
+	unsigned int		dev_id;
+	unsigned int		nid;
+	unsigned int		pin_offset;
+	unsigned int		index;
+};
+
+static LIST_HEAD(mbigen_chip_list);
+static DEFINE_SPINLOCK(mbigen_chip_lock);
+
+static inline int get_mbigen_vec_reg_addr(u32 nid, u32 offset)
+{
+	return MBIGEN_NODE_ADDR_BASE(nid) + REG_MBIGEN_VEC_OFFSET
+	    + (offset * 4);
+}
+
+static inline int get_mbigen_type_reg_addr(u32 nid, u32 offset)
+{
+	return MBIGEN_NODE_ADDR_BASE(nid) + REG_MBIGEN_TYPE_OFFSET + offset;
+}
+
+static struct mbigen_device *mbigen_find_device(struct mbigen_chip *chip,
+						u32 did)
+{
+	struct mbigen_device *dev = NULL, *tmp;
+
+	raw_spin_lock(&chip->lock);
+	list_for_each_entry(tmp, &chip->mbigen_device_list, entry) {
+		if (tmp->did == did) {
+			dev = tmp;
+			break;
+		}
+	}
+	raw_spin_unlock(&chip->lock);
+
+	return dev;
+}
+
+/* calc_irq_index() - calculate the msi index of this interrupt
+ *
+ * @dev: pointer to mbigen device.
+ * @nid: number of mbigen node this interrupt connected.
+ * @offset: interrupt pin offset.
+*/
+static u32 calc_irq_index(struct mbigen_device *dev, u32 nid, u32 offset)
+{
+	struct mbigen_node *mgn_node = NULL, *tmp;
+	unsigned long flags;
+	u32 index = 0;
+
+	raw_spin_lock_irqsave(&dev->lock, flags);
+	list_for_each_entry(tmp, &dev->mbigen_node_list, entry) {
+		if (tmp->node_num == nid)
+			mgn_node = tmp;
+	}
+	raw_spin_unlock_irqrestore(&dev->lock, flags);
+
+	if (mgn_node == NULL) {
+		pr_err("No mbigen node found in device:%s\n",
+			 dev->node->full_name);
+		return -ENXIO;
+	}
+
+	if ((offset <= (mgn_node->pin_offset + mgn_node->irq_nr))
+	    && (offset >= mgn_node->pin_offset))
+		index = mgn_node->index_offset + (offset - mgn_node->pin_offset);
+	else {
+		pr_err("Err: no invalid index\n");
+		index = -EINVAL;
+	}
+
+	return index;
+}
+
+static struct mbigen_irq_data *get_mbigen_irq_data(struct mbigen_chip *chip,
+						   struct irq_data *d)
+{
+	struct mbigen_device *mgn_dev;
+	struct mbigen_irq_data *mgn_irq_data;
+	u32 nid, did, offset;
+	u32 index;
+
+	did = GET_MBIGEN_DEVICE_ID(d->hwirq);
+	offset = GET_IRQ_PIN_OFFSET(d->hwirq);
+	nid = GET_MBIGEN_NODE_NUM(d->hwirq);
+
+	mgn_dev = mbigen_find_device(chip, did);
+	if (!mgn_dev) {
+		pr_err("no mbigen device found with did: 0x%x\n", did);
+		return NULL;
+	}
+
+	mgn_irq_data = mgn_dev->mgn_data;
+
+	index = calc_irq_index(mgn_dev, nid, offset);
+	if (index < 0)
+		return NULL;
+
+	if (offset != mgn_irq_data[index].pin_offset) {
+		pr_err("No invalid mgn irq data found:offset:%d,nid:%d\n",
+			offset, mgn_irq_data[index].pin_offset);
+		return NULL;
+	}
+
+	return &mgn_irq_data[index];
+}
+
+static void mbigen_write_msg(struct msi_desc *desc, struct msi_msg *msg)
+{
+	struct mbigen_irq_data *mgn_irq_data = irq_get_handler_data(desc->irq);
+	u32 val;
+	int addr;
+
+	addr = get_mbigen_vec_reg_addr(mgn_irq_data->nid,
+				    mgn_irq_data->pin_offset);
+
+	val = readl_relaxed(addr + mgn_irq_data->base);
+
+	val &= ~(IRQ_EVENT_ID_MASK << IRQ_EVENT_ID_SHIFT);
+	val |= (msg->data << IRQ_EVENT_ID_SHIFT);
+	writel_relaxed(val, addr + mgn_irq_data->base);
+}
+
+/*
+ * Interrupt controller operations
+ */
+static int mbigen_set_type(struct irq_data *d, unsigned int type)
+{
+	struct mbigen_chip *chip = d->domain->host_data;
+	u32 ofst, mask;
+	u32 val, nid, pin_offset;
+	int addr;
+
+	if (type != IRQ_TYPE_LEVEL_HIGH && type != IRQ_TYPE_EDGE_RISING)
+		return -EINVAL;
+
+	nid = GET_MBIGEN_NODE_NUM(d->hwirq);
+	pin_offset = GET_IRQ_PIN_OFFSET(d->hwirq);
+
+	ofst = pin_offset / 32 * 4;
+	mask = 1 << (pin_offset % 32);
+
+	addr = get_mbigen_type_reg_addr(nid, ofst);
+	val = readl_relaxed(addr + chip->base);
+
+	if (type == IRQ_TYPE_LEVEL_HIGH)
+		val |= mask;
+	else if (type == IRQ_TYPE_EDGE_RISING)
+		val &= ~mask;
+
+	writel_relaxed(val, addr + chip->base);
+
+	return 0;
+}
+
+static int mbigen_set_affinity(struct irq_data *data,
+				const struct cpumask *mask_val,
+				bool force)
+{
+	struct mbigen_irq_data *mgn_irq_data = irq_data_get_irq_chip_data(data);
+	struct irq_chip *chip = irq_get_chip(mgn_irq_data->parent_irq);
+	struct irq_data *parent_d = irq_get_irq_data(mgn_irq_data->parent_irq);
+
+	if (chip && chip->irq_set_affinity)
+		return chip->irq_set_affinity(parent_d, mask_val, force);
+	else
+		return -EINVAL;
+}
+
+static void mbigen_mask_irq(struct irq_data *data)
+{
+	struct mbigen_irq_data *mgn_irq_data = irq_data_get_irq_chip_data(data);
+	struct irq_chip *chip = irq_get_chip(mgn_irq_data->parent_irq);
+	struct irq_data *parent_d = irq_get_irq_data(mgn_irq_data->parent_irq);
+
+	if (chip && chip->irq_mask)
+		return chip->irq_mask(parent_d);
+}
+
+static void mbigen_unmask_irq(struct irq_data *data)
+{
+	struct mbigen_irq_data *mgn_irq_data = irq_data_get_irq_chip_data(data);
+	struct irq_chip *chip = irq_get_chip(mgn_irq_data->parent_irq);
+	struct irq_data *parent_d = irq_get_irq_data(mgn_irq_data->parent_irq);
+
+	if (chip && chip->irq_unmask)
+		chip->irq_unmask(parent_d);
+}
+
+static void mbigen_eoi_irq(struct irq_data *data)
+{
+
+	struct mbigen_irq_data *mgn_irq_data = irq_data_get_irq_chip_data(data);
+	struct irq_chip *chip = irq_get_chip(mgn_irq_data->parent_irq);
+	struct irq_data *parent_d = irq_get_irq_data(mgn_irq_data->parent_irq);
+	u32 pin_offset, ofst, mask;
+
+	pin_offset = GET_IRQ_PIN_OFFSET(data->hwirq);
+	ofst = pin_offset / 32 * 4;
+	mask = 1 << (pin_offset % 32);
+
+	writel_relaxed(mask, mgn_irq_data->base + ofst
+			+ REG_MBIGEN_CLEAR_OFFSET);
+
+	if (chip && chip->irq_eoi)
+		chip->irq_eoi(parent_d);
+}
+
+static struct irq_chip mbigen_irq_chip = {
+	.name = "MBIGEN-v2",
+	.irq_mask = mbigen_mask_irq,
+	.irq_unmask = mbigen_unmask_irq,
+	.irq_eoi = mbigen_eoi_irq,
+	.irq_set_affinity = mbigen_set_affinity,
+	.irq_set_type = mbigen_set_type,
+};
+
+static int mbigen_domain_xlate(struct irq_domain *d,
+			       struct device_node *controller,
+			       const u32 *intspec, unsigned int intsize,
+			       unsigned long *out_hwirq,
+			       unsigned int *out_type)
+{
+
+	if (d->of_node != controller)
+		return -EINVAL;
+
+	if (intsize < 4)
+		return -EINVAL;
+
+	/* Compose the hwirq local to mbigen domain
+	 * intspec[0]: device id
+	 * intspec[1]: mbigen node number(nid) defined in dts file.
+	 * intspec[2]: interrut pin offset
+	 */
+	*out_hwirq = COMPOSE_MBIGEN_HWIRQ(intspec[0], intspec[1], intspec[2]);
+
+	*out_type = intspec[3] & IRQ_TYPE_SENSE_MASK;
+
+	return 0;
+}
+
+static int mbigen_domain_map(struct irq_domain *d, unsigned int irq,
+				irq_hw_number_t hw)
+{
+	struct mbigen_chip *mgn_chip = d->host_data;
+	struct mbigen_irq_data *mgn_irq_data = NULL;
+	struct irq_data *data = irq_get_irq_data(irq);
+
+	irq_set_chip_and_handler(irq, &mbigen_irq_chip, handle_fasteoi_irq);
+
+	mgn_irq_data = get_mbigen_irq_data(mgn_chip, data);
+	if (!mgn_irq_data)
+		return -EINVAL;
+
+	irq_set_chip_data(irq, mgn_irq_data);
+
+	set_irq_flags(irq, IRQF_VALID);
+
+	return 0;
+}
+
+static struct irq_domain_ops mbigen_domain_ops = {
+	.xlate = mbigen_domain_xlate,
+	.map = mbigen_domain_map,
+};
+
+static void mbigen_handle_cascade_irq(unsigned int irq, struct irq_desc *desc)
+{
+	struct mbigen_irq_data *mgn_irq_data = irq_get_handler_data(irq);
+	struct mbigen_device *mgn_dev = mgn_irq_data->dev;
+	struct irq_domain *domain = mgn_dev->chip->domain;
+	unsigned int cascade_irq;
+	u32 hwirq;
+
+	hwirq = COMPOSE_MBIGEN_HWIRQ(mgn_irq_data->dev_id,
+					mgn_irq_data->nid,
+					mgn_irq_data->pin_offset);
+
+	/* find cascade_irq within mbigen domain */
+	cascade_irq = irq_find_mapping(domain, hwirq);
+
+	if (unlikely(!cascade_irq))
+		handle_bad_irq(irq, desc);
+	else
+		generic_handle_irq(cascade_irq);
+}
+
+/*
+ * get_mbigen_node_info() - Get the mbigen node information
+ * and compose a new hwirq.
+ *
+ * @irq: irq number need to be handled
+ * @device_id: id of device which generates this interrupt
+ * @node_num: number of mbigen node this interrupt connected.
+ * @offset: interrupt pin offset in a mbigen node.
+ */
+static int get_mbigen_node_info(u32 irq, struct mbigen_device *dev,
+				    struct mbigen_irq_data *mgn_irq_data)
+{
+	struct irq_data *irq_data = irq_get_irq_data(irq);
+	struct mbigen_node *mgn_node;
+	u32 irqs_range = 0, tmp;
+	u32 msi_index;
+
+	mgn_irq_data->dev_id = dev->did;
+	msi_index = irq_data->hwirq & 0xff;
+
+	raw_spin_lock(&dev->lock);
+
+	list_for_each_entry(mgn_node, &dev->mbigen_node_list, entry) {
+		tmp = irqs_range;
+		irqs_range += mgn_node->irq_nr;
+
+		if (msi_index < irqs_range) {
+			mgn_irq_data->nid = mgn_node->node_num;
+			mgn_irq_data->pin_offset =
+			    mgn_node->pin_offset + (msi_index - tmp);
+			break;
+		}
+	}
+	raw_spin_unlock(&dev->lock);
+
+	return 0;
+}
+
+/*
+ * parse the information of mbigen node included in
+ * mbigen device node.
+ * @dev: the mbigen device pointer
+ *
+ * Some devices in hisilicon soc has more than 128
+ * interrupts and beyond a mbigen node can connect.
+ * So It need to be connect to several mbigen nodes.
+ */
+static int parse_mbigen_node(struct mbigen_device *dev)
+{
+	struct mbigen_chip *chip = dev->chip;
+	struct device_node *p = chip->node;
+	const __be32 *intspec, *tmp;
+	u32 intsize, intlen, index = 0;
+	u32 node_num;
+	int i;
+
+	intspec = of_get_property(dev->node, "mbigen_node", &intlen);
+	if (intspec == NULL)
+		return -EINVAL;
+
+	intlen /= sizeof(*intspec);
+
+	/* Get size of mbigen_node specifier */
+	tmp = of_get_property(p, "#mbigen-node-cells", NULL);
+	if (tmp == NULL)
+		return -EINVAL;
+
+	intsize = be32_to_cpu(*tmp);
+	node_num = intlen / intsize;
+
+	for (i = 0; i < node_num; i++) {
+		struct mbigen_node *mgn_node;
+
+		mgn_node = kzalloc(sizeof(*mgn_node), GFP_KERNEL);
+		if (!mgn_node)
+			return -ENOMEM;
+
+		mgn_node->node_num = be32_to_cpup(intspec++);
+		mgn_node->irq_nr = be32_to_cpup(intspec++);
+		mgn_node->pin_offset = be32_to_cpup(intspec++);
+
+		mgn_node->index_offset = index;
+		index += mgn_node->irq_nr;
+
+		INIT_LIST_HEAD(&mgn_node->entry);
+
+		raw_spin_lock(&dev->lock);
+		list_add_tail(&mgn_node->entry, &dev->mbigen_node_list);
+		raw_spin_unlock(&dev->lock);
+	}
+
+	return 0;
+}
+
+static void mbigen_set_irq_handler_data(struct msi_desc *desc,
+					struct mbigen_device *mgn_dev,
+					struct mbigen_irq_data *mgn_irq_data)
+{
+	struct mbigen_chip *chip = mgn_dev->chip;
+
+	mgn_irq_data->base = chip->base;
+	mgn_irq_data->index = desc->platform.msi_index;
+
+	get_mbigen_node_info(desc->irq, mgn_dev, mgn_irq_data);
+
+	mgn_irq_data->dev = mgn_dev;
+	mgn_irq_data->parent_irq = desc->irq;
+
+	irq_set_handler_data(desc->irq, mgn_irq_data);
+
+}
+/*
+ * mbigen_device_init()- initial the devices connected to
+ * mbigen chip.
+ *
+ * @chip: pointer to mbigen chip.
+ * @node: represents the node of devices which defined
+ *			in device tree as a child node of mbigen chip
+ *			node.
+ */
+static int mbigen_device_init(struct mbigen_chip *chip,
+			struct device_node *node)
+{
+	struct mbigen_device *mgn_dev;
+	struct device_node *msi_np;
+	struct irq_domain *msi_domain;
+	struct msi_desc *desc;
+	struct mbigen_irq_data *mgn_irq_data;
+	u32 nvec, dev_id;
+	int ret;
+
+	of_property_read_u32(node, "nr-interrupts", &nvec);
+	if (!nvec)
+		return -EINVAL;
+
+	ret = of_property_read_u32_index(node, "msi-parent", 1, &dev_id);
+	if (ret)
+		return -EINVAL;
+
+	msi_np = of_parse_phandle(node, "msi-parent", 0);
+	if (!msi_np) {
+		pr_err("%s- no msi node found: %s\n", __func__,
+			node->full_name);
+		return -ENXIO;
+	}
+
+	msi_domain = irq_find_matching_host(msi_np, DOMAIN_BUS_PLATFORM_MSI);
+	if (!msi_domain) {
+		pr_err("MBIGEN: no platform-msi domain for %s\n",
+			msi_np->full_name);
+		return -ENXIO;
+	}
+
+	mgn_dev = kzalloc(sizeof(*mgn_dev), GFP_KERNEL);
+	if (!mgn_dev)
+		return -ENOMEM;
+
+	mgn_dev->dev.msi_domain = msi_domain;
+	mgn_dev->dev.of_node = node;
+	mgn_dev->chip = chip;
+	mgn_dev->nr_irqs = nvec;
+	mgn_dev->node = node;
+	mgn_dev->did = dev_id;
+
+	INIT_LIST_HEAD(dev_to_msi_list(&mgn_dev->dev));
+
+	ret = platform_msi_domain_alloc_irqs(&mgn_dev->dev,
+					     nvec, mbigen_write_msg);
+	if (ret)
+		goto out_free_dev;
+
+	INIT_LIST_HEAD(&mgn_dev->entry);
+	raw_spin_lock_init(&mgn_dev->lock);
+	INIT_LIST_HEAD(&mgn_dev->mbigen_node_list);
+
+	/* Parse and get the info of mbigen nodes this
+	 * device connected
+	 */
+	parse_mbigen_node(mgn_dev);
+
+	mgn_irq_data = kcalloc(nvec, sizeof(*mgn_irq_data), GFP_KERNEL);
+	if (!mgn_irq_data)
+		return -ENOMEM;
+
+	mgn_dev->mgn_data = mgn_irq_data;
+
+	for_each_msi_entry(desc, &mgn_dev->dev) {
+		mbigen_set_irq_handler_data(desc, mgn_dev,
+					    &mgn_irq_data[desc->platform.msi_index]);
+		irq_set_chained_handler(desc->irq, mbigen_handle_cascade_irq);
+	}
+
+	raw_spin_lock(&chip->lock);
+	list_add(&mgn_dev->entry, &chip->mbigen_device_list);
+	raw_spin_unlock(&chip->lock);
+
+	return 0;
+
+out_free_dev:
+	kfree(mgn_dev);
+	pr_err("failed to get MSIs for device:%s (%d)\n", node->full_name,
+		ret);
+	return ret;
+}
+
+/*
+ * Early initialization as an interrupt controller
+ */
+static int __init mbigen_of_init(struct device_node *node)
+{
+	struct mbigen_chip *mgn_chip;
+	struct device_node *child;
+	struct irq_domain *domain;
+	void __iomem *base;
+	int err;
+
+	base = of_iomap(node, 0);
+	if (!base) {
+		pr_err("%s: unable to map registers\n", node->full_name);
+		return -ENOMEM;
+	}
+
+	mgn_chip = kzalloc(sizeof(*mgn_chip), GFP_KERNEL);
+	if (!mgn_chip) {
+		err = -ENOMEM;
+		goto unmap_reg;
+	}
+
+	mgn_chip->base = base;
+	mgn_chip->node = node;
+
+	domain = irq_domain_add_tree(node, &mbigen_domain_ops, mgn_chip);
+	mgn_chip->domain = domain;
+
+	raw_spin_lock_init(&mgn_chip->lock);
+	INIT_LIST_HEAD(&mgn_chip->entry);
+	INIT_LIST_HEAD(&mgn_chip->mbigen_device_list);
+
+	for_each_child_of_node(node, child) {
+		mbigen_device_init(mgn_chip, child);
+	}
+
+	spin_lock(&mbigen_chip_lock);
+	list_add(&mgn_chip->entry, &mbigen_chip_list);
+	spin_unlock(&mbigen_chip_lock);
+
+	return 0;
+
+unmap_reg:
+	iounmap(base);
+	pr_err("MBIGEN: failed probing:%s (%d)\n", node->full_name, err);
+	return err;
+}
+
+static struct of_device_id mbigen_chip_id[] = {
+	{	.compatible = "hisilicon,mbigen-v2",},
+	{},
+};
+
+static int __init mbigen_init(void)
+{
+	struct device_node *np;
+
+	for (np = of_find_matching_node(NULL, mbigen_chip_id); np;
+	     np = of_find_matching_node(np, mbigen_chip_id)) {
+		mbigen_of_init(np);
+	}
+
+	return 0;
+}
+
+core_initcall(mbigen_init);
+
+MODULE_AUTHOR("Jun Ma <majun258 at huawei.com>");
+MODULE_AUTHOR("Yun Wu <wuyun.wu at huawei.com>");
+MODULE_LICENSE("GPL");
+MODULE_DESCRIPTION("Hisilicon MBI Generator driver");
-- 
1.7.1




From panand at redhat.com  Tue Aug 18 20:28:24 2015
From: panand at redhat.com (Pratyush Anand)
Date: Wed, 19 Aug 2015 08:58:24 +0530
Subject: [PATCH V3] Watchdog: Fix parent of watchdog_devices
Message-ID: <db7db9102158b87a4a7169e84e2272b3ba03f9f7.1439954581.git.panand@redhat.com>

/sys/class/watchdog/watchdogn/device/modalias can help to identify the
driver/module for a given watchdog node. However, many wdt devices does not set
its parent and so, we do not see an entry for device in sysfs for such devices.

This patch fixes parent of watchdog_device so that
/sys/class/watchdog/watchdogn/device is populated.

Exceptions: booke, diag288, mpc8xxx, octeon, softdog and w83627hf -- They do not
have any parent. Not sure, how we can we identify driver for these devices.

Signed-off-by: Pratyush Anand <panand at redhat.com>
---
Changes since v2:
Fixed drivers/watchdog/txx9wdt.c:134:20: error: 'pdev' undeclared
Reported-by: kbuild test robot <fengguang.wu at intel.com>
Changes since v1:
Squash all commits of V1 into a single patch.
V1 was here:
http://www.spinics.net/lists/linux-watchdog/msg07220.html

 drivers/misc/mei/wd.c               | 1 +
 drivers/watchdog/bcm2835_wdt.c      | 1 +
 drivers/watchdog/bcm47xx_wdt.c      | 1 +
 drivers/watchdog/bcm_kona_wdt.c     | 1 +
 drivers/watchdog/coh901327_wdt.c    | 1 +
 drivers/watchdog/da9052_wdt.c       | 1 +
 drivers/watchdog/da9055_wdt.c       | 1 +
 drivers/watchdog/da9062_wdt.c       | 1 +
 drivers/watchdog/da9063_wdt.c       | 1 +
 drivers/watchdog/davinci_wdt.c      | 1 +
 drivers/watchdog/digicolor_wdt.c    | 1 +
 drivers/watchdog/ep93xx_wdt.c       | 1 +
 drivers/watchdog/gpio_wdt.c         | 1 +
 drivers/watchdog/ie6xx_wdt.c        | 1 +
 drivers/watchdog/intel-mid_wdt.c    | 1 +
 drivers/watchdog/jz4740_wdt.c       | 1 +
 drivers/watchdog/mena21_wdt.c       | 1 +
 drivers/watchdog/menf21bmc_wdt.c    | 1 +
 drivers/watchdog/omap_wdt.c         | 1 +
 drivers/watchdog/orion_wdt.c        | 1 +
 drivers/watchdog/pnx4008_wdt.c      | 1 +
 drivers/watchdog/qcom-wdt.c         | 1 +
 drivers/watchdog/retu_wdt.c         | 1 +
 drivers/watchdog/rt2880_wdt.c       | 1 +
 drivers/watchdog/s3c2410_wdt.c      | 1 +
 drivers/watchdog/shwdt.c            | 1 +
 drivers/watchdog/sirfsoc_wdt.c      | 1 +
 drivers/watchdog/sp805_wdt.c        | 1 +
 drivers/watchdog/st_lpc_wdt.c       | 1 +
 drivers/watchdog/stmp3xxx_rtc_wdt.c | 1 +
 drivers/watchdog/tegra_wdt.c        | 1 +
 drivers/watchdog/twl4030_wdt.c      | 1 +
 drivers/watchdog/txx9wdt.c          | 1 +
 drivers/watchdog/ux500_wdt.c        | 1 +
 drivers/watchdog/via_wdt.c          | 1 +
 drivers/watchdog/wm831x_wdt.c       | 1 +
 drivers/watchdog/wm8350_wdt.c       | 1 +
 37 files changed, 37 insertions(+)

diff --git a/drivers/misc/mei/wd.c b/drivers/misc/mei/wd.c
index 2bc0f5089f82..b346638833b0 100644
--- a/drivers/misc/mei/wd.c
+++ b/drivers/misc/mei/wd.c
@@ -364,6 +364,7 @@ int mei_watchdog_register(struct mei_device *dev)
 
 	int ret;
 
+	amt_wd_dev.parent = dev->dev;
 	/* unlock to perserve correct locking order */
 	mutex_unlock(&dev->device_lock);
 	ret = watchdog_register_device(&amt_wd_dev);
diff --git a/drivers/watchdog/bcm2835_wdt.c b/drivers/watchdog/bcm2835_wdt.c
index 7116968dee12..66c3e656a616 100644
--- a/drivers/watchdog/bcm2835_wdt.c
+++ b/drivers/watchdog/bcm2835_wdt.c
@@ -182,6 +182,7 @@ static int bcm2835_wdt_probe(struct platform_device *pdev)
 	watchdog_set_drvdata(&bcm2835_wdt_wdd, wdt);
 	watchdog_init_timeout(&bcm2835_wdt_wdd, heartbeat, dev);
 	watchdog_set_nowayout(&bcm2835_wdt_wdd, nowayout);
+	bcm2835_wdt_wdd.parent = &pdev->dev;
 	err = watchdog_register_device(&bcm2835_wdt_wdd);
 	if (err) {
 		dev_err(dev, "Failed to register watchdog device");
diff --git a/drivers/watchdog/bcm47xx_wdt.c b/drivers/watchdog/bcm47xx_wdt.c
index b28a072abf78..4064a43f1360 100644
--- a/drivers/watchdog/bcm47xx_wdt.c
+++ b/drivers/watchdog/bcm47xx_wdt.c
@@ -209,6 +209,7 @@ static int bcm47xx_wdt_probe(struct platform_device *pdev)
 
 	wdt->wdd.info = &bcm47xx_wdt_info;
 	wdt->wdd.timeout = WDT_DEFAULT_TIME;
+	wdt->wdd.parent = &pdev->dev;
 	ret = wdt->wdd.ops->set_timeout(&wdt->wdd, timeout);
 	if (ret)
 		goto err_timer;
diff --git a/drivers/watchdog/bcm_kona_wdt.c b/drivers/watchdog/bcm_kona_wdt.c
index 22d8ae65772a..e0c98423f2c9 100644
--- a/drivers/watchdog/bcm_kona_wdt.c
+++ b/drivers/watchdog/bcm_kona_wdt.c
@@ -319,6 +319,7 @@ static int bcm_kona_wdt_probe(struct platform_device *pdev)
 	spin_lock_init(&wdt->lock);
 	platform_set_drvdata(pdev, wdt);
 	watchdog_set_drvdata(&bcm_kona_wdt_wdd, wdt);
+	bcm_kona_wdt_wdd.parent = &pdev->dev;
 
 	ret = bcm_kona_wdt_set_timeout_reg(&bcm_kona_wdt_wdd, 0);
 	if (ret) {
diff --git a/drivers/watchdog/coh901327_wdt.c b/drivers/watchdog/coh901327_wdt.c
index ce12f437f195..a099b77fc0b9 100644
--- a/drivers/watchdog/coh901327_wdt.c
+++ b/drivers/watchdog/coh901327_wdt.c
@@ -358,6 +358,7 @@ static int __init coh901327_probe(struct platform_device *pdev)
 	if (ret < 0)
 		coh901327_wdt.timeout = 60;
 
+	coh901327_wdt.parent = &pdev->dev;
 	ret = watchdog_register_device(&coh901327_wdt);
 	if (ret == 0)
 		dev_info(&pdev->dev,
diff --git a/drivers/watchdog/da9052_wdt.c b/drivers/watchdog/da9052_wdt.c
index 2e9589652e1e..67e67977bd29 100644
--- a/drivers/watchdog/da9052_wdt.c
+++ b/drivers/watchdog/da9052_wdt.c
@@ -195,6 +195,7 @@ static int da9052_wdt_probe(struct platform_device *pdev)
 	da9052_wdt->timeout = DA9052_DEF_TIMEOUT;
 	da9052_wdt->info = &da9052_wdt_info;
 	da9052_wdt->ops = &da9052_wdt_ops;
+	da9052_wdt->parent = &pdev->dev;
 	watchdog_set_drvdata(da9052_wdt, driver_data);
 
 	kref_init(&driver_data->kref);
diff --git a/drivers/watchdog/da9055_wdt.c b/drivers/watchdog/da9055_wdt.c
index 495089d8dbfe..04d1430d93d2 100644
--- a/drivers/watchdog/da9055_wdt.c
+++ b/drivers/watchdog/da9055_wdt.c
@@ -161,6 +161,7 @@ static int da9055_wdt_probe(struct platform_device *pdev)
 	da9055_wdt->timeout = DA9055_DEF_TIMEOUT;
 	da9055_wdt->info = &da9055_wdt_info;
 	da9055_wdt->ops = &da9055_wdt_ops;
+	da9055_wdt->parent = &pdev->dev;
 	watchdog_set_nowayout(da9055_wdt, nowayout);
 	watchdog_set_drvdata(da9055_wdt, driver_data);
 
diff --git a/drivers/watchdog/da9062_wdt.c b/drivers/watchdog/da9062_wdt.c
index b3a870ce85be..7386111220d5 100644
--- a/drivers/watchdog/da9062_wdt.c
+++ b/drivers/watchdog/da9062_wdt.c
@@ -210,6 +210,7 @@ static int da9062_wdt_probe(struct platform_device *pdev)
 	wdt->wdtdev.max_timeout = DA9062_WDT_MAX_TIMEOUT;
 	wdt->wdtdev.timeout = DA9062_WDG_DEFAULT_TIMEOUT;
 	wdt->wdtdev.status = WATCHDOG_NOWAYOUT_INIT_STATUS;
+	wdt->wdtdev.parent = &pdev->dev;
 
 	watchdog_set_drvdata(&wdt->wdtdev, wdt);
 	dev_set_drvdata(&pdev->dev, wdt);
diff --git a/drivers/watchdog/da9063_wdt.c b/drivers/watchdog/da9063_wdt.c
index e2fe2ebdebd4..6bf130bd863d 100644
--- a/drivers/watchdog/da9063_wdt.c
+++ b/drivers/watchdog/da9063_wdt.c
@@ -175,6 +175,7 @@ static int da9063_wdt_probe(struct platform_device *pdev)
 	wdt->wdtdev.min_timeout = DA9063_WDT_MIN_TIMEOUT;
 	wdt->wdtdev.max_timeout = DA9063_WDT_MAX_TIMEOUT;
 	wdt->wdtdev.timeout = DA9063_WDG_TIMEOUT;
+	wdt->wdtdev.parent = &pdev->dev;
 
 	wdt->wdtdev.status = WATCHDOG_NOWAYOUT_INIT_STATUS;
 
diff --git a/drivers/watchdog/davinci_wdt.c b/drivers/watchdog/davinci_wdt.c
index cfdf8a408aea..17454ca653f4 100644
--- a/drivers/watchdog/davinci_wdt.c
+++ b/drivers/watchdog/davinci_wdt.c
@@ -179,6 +179,7 @@ static int davinci_wdt_probe(struct platform_device *pdev)
 	wdd->min_timeout	= 1;
 	wdd->max_timeout	= MAX_HEARTBEAT;
 	wdd->timeout		= DEFAULT_HEARTBEAT;
+	wdd->parent		= &pdev->dev;
 
 	watchdog_init_timeout(wdd, heartbeat, dev);
 
diff --git a/drivers/watchdog/digicolor_wdt.c b/drivers/watchdog/digicolor_wdt.c
index 31d8e4936611..50abe1bf62a5 100644
--- a/drivers/watchdog/digicolor_wdt.c
+++ b/drivers/watchdog/digicolor_wdt.c
@@ -143,6 +143,7 @@ static int dc_wdt_probe(struct platform_device *pdev)
 	}
 	dc_wdt_wdd.max_timeout = U32_MAX / clk_get_rate(wdt->clk);
 	dc_wdt_wdd.timeout = dc_wdt_wdd.max_timeout;
+	dc_wdt_wdd.parent = &pdev->dev;
 
 	spin_lock_init(&wdt->lock);
 
diff --git a/drivers/watchdog/ep93xx_wdt.c b/drivers/watchdog/ep93xx_wdt.c
index 7a2cc7191c58..0a4d7cc05d54 100644
--- a/drivers/watchdog/ep93xx_wdt.c
+++ b/drivers/watchdog/ep93xx_wdt.c
@@ -132,6 +132,7 @@ static int ep93xx_wdt_probe(struct platform_device *pdev)
 	val = readl(mmio_base + EP93XX_WATCHDOG);
 	ep93xx_wdt_wdd.bootstatus = (val & 0x01) ? WDIOF_CARDRESET : 0;
 	ep93xx_wdt_wdd.timeout = timeout;
+	ep93xx_wdt_wdd.parent = &pdev->dev;
 
 	watchdog_set_nowayout(&ep93xx_wdt_wdd, nowayout);
 
diff --git a/drivers/watchdog/gpio_wdt.c b/drivers/watchdog/gpio_wdt.c
index 1687cc2d7122..336bddd84809 100644
--- a/drivers/watchdog/gpio_wdt.c
+++ b/drivers/watchdog/gpio_wdt.c
@@ -217,6 +217,7 @@ static int gpio_wdt_probe(struct platform_device *pdev)
 	priv->wdd.ops		= &gpio_wdt_ops;
 	priv->wdd.min_timeout	= SOFT_TIMEOUT_MIN;
 	priv->wdd.max_timeout	= SOFT_TIMEOUT_MAX;
+	priv->wdd.parent	= &pdev->dev;
 
 	if (watchdog_init_timeout(&priv->wdd, 0, &pdev->dev) < 0)
 		priv->wdd.timeout = SOFT_TIMEOUT_DEF;
diff --git a/drivers/watchdog/ie6xx_wdt.c b/drivers/watchdog/ie6xx_wdt.c
index 9bc39ae51624..78c2541f5d52 100644
--- a/drivers/watchdog/ie6xx_wdt.c
+++ b/drivers/watchdog/ie6xx_wdt.c
@@ -267,6 +267,7 @@ static int ie6xx_wdt_probe(struct platform_device *pdev)
 
 	ie6xx_wdt_dev.timeout = timeout;
 	watchdog_set_nowayout(&ie6xx_wdt_dev, nowayout);
+	ie6xx_wdt_dev.parent = &pdev->dev;
 
 	spin_lock_init(&ie6xx_wdt_data.unlock_sequence);
 
diff --git a/drivers/watchdog/intel-mid_wdt.c b/drivers/watchdog/intel-mid_wdt.c
index 84f6701c391f..0a436b5d1e84 100644
--- a/drivers/watchdog/intel-mid_wdt.c
+++ b/drivers/watchdog/intel-mid_wdt.c
@@ -137,6 +137,7 @@ static int mid_wdt_probe(struct platform_device *pdev)
 	wdt_dev->min_timeout = MID_WDT_TIMEOUT_MIN;
 	wdt_dev->max_timeout = MID_WDT_TIMEOUT_MAX;
 	wdt_dev->timeout = MID_WDT_DEFAULT_TIMEOUT;
+	wdt_dev->parent = &pdev->dev;
 
 	watchdog_set_drvdata(wdt_dev, &pdev->dev);
 	platform_set_drvdata(pdev, wdt_dev);
diff --git a/drivers/watchdog/jz4740_wdt.c b/drivers/watchdog/jz4740_wdt.c
index 4c2cc09c0c57..6a7d5c365438 100644
--- a/drivers/watchdog/jz4740_wdt.c
+++ b/drivers/watchdog/jz4740_wdt.c
@@ -174,6 +174,7 @@ static int jz4740_wdt_probe(struct platform_device *pdev)
 	jz4740_wdt->timeout = heartbeat;
 	jz4740_wdt->min_timeout = 1;
 	jz4740_wdt->max_timeout = MAX_HEARTBEAT;
+	jz4740_wdt->parent = &pdev->dev;
 	watchdog_set_nowayout(jz4740_wdt, nowayout);
 	watchdog_set_drvdata(jz4740_wdt, drvdata);
 
diff --git a/drivers/watchdog/mena21_wdt.c b/drivers/watchdog/mena21_wdt.c
index d193a5e79c38..69013007dc47 100644
--- a/drivers/watchdog/mena21_wdt.c
+++ b/drivers/watchdog/mena21_wdt.c
@@ -197,6 +197,7 @@ static int a21_wdt_probe(struct platform_device *pdev)
 	watchdog_init_timeout(&a21_wdt, 30, &pdev->dev);
 	watchdog_set_nowayout(&a21_wdt, nowayout);
 	watchdog_set_drvdata(&a21_wdt, drv);
+	a21_wdt.parent = &pdev->dev;
 
 	reset = a21_wdt_get_bootstatus(drv);
 	if (reset == 2)
diff --git a/drivers/watchdog/menf21bmc_wdt.c b/drivers/watchdog/menf21bmc_wdt.c
index 59f0913c7341..3aefddebb386 100644
--- a/drivers/watchdog/menf21bmc_wdt.c
+++ b/drivers/watchdog/menf21bmc_wdt.c
@@ -130,6 +130,7 @@ static int menf21bmc_wdt_probe(struct platform_device *pdev)
 	drv_data->wdt.info = &menf21bmc_wdt_info;
 	drv_data->wdt.min_timeout = BMC_WD_TIMEOUT_MIN;
 	drv_data->wdt.max_timeout = BMC_WD_TIMEOUT_MAX;
+	drv_data->wdt.parent = &pdev->dev;
 	drv_data->i2c_client = i2c_client;
 
 	/*
diff --git a/drivers/watchdog/omap_wdt.c b/drivers/watchdog/omap_wdt.c
index de911c7e477c..d96bee017fd3 100644
--- a/drivers/watchdog/omap_wdt.c
+++ b/drivers/watchdog/omap_wdt.c
@@ -253,6 +253,7 @@ static int omap_wdt_probe(struct platform_device *pdev)
 	wdev->wdog.ops = &omap_wdt_ops;
 	wdev->wdog.min_timeout = TIMER_MARGIN_MIN;
 	wdev->wdog.max_timeout = TIMER_MARGIN_MAX;
+	wdev->wdog.parent = &pdev->dev;
 
 	if (watchdog_init_timeout(&wdev->wdog, timer_margin, &pdev->dev) < 0)
 		wdev->wdog.timeout = TIMER_MARGIN_DEFAULT;
diff --git a/drivers/watchdog/orion_wdt.c b/drivers/watchdog/orion_wdt.c
index ef0c628d5037..c6b8f4a43bde 100644
--- a/drivers/watchdog/orion_wdt.c
+++ b/drivers/watchdog/orion_wdt.c
@@ -567,6 +567,7 @@ static int orion_wdt_probe(struct platform_device *pdev)
 
 	dev->wdt.timeout = wdt_max_duration;
 	dev->wdt.max_timeout = wdt_max_duration;
+	dev->wdt.parent = &pdev->dev;
 	watchdog_init_timeout(&dev->wdt, heartbeat, &pdev->dev);
 
 	platform_set_drvdata(pdev, &dev->wdt);
diff --git a/drivers/watchdog/pnx4008_wdt.c b/drivers/watchdog/pnx4008_wdt.c
index b9c6049c3e78..4224b3ec83a5 100644
--- a/drivers/watchdog/pnx4008_wdt.c
+++ b/drivers/watchdog/pnx4008_wdt.c
@@ -167,6 +167,7 @@ static int pnx4008_wdt_probe(struct platform_device *pdev)
 
 	pnx4008_wdd.bootstatus = (readl(WDTIM_RES(wdt_base)) & WDOG_RESET) ?
 			WDIOF_CARDRESET : 0;
+	pnx4008_wdd.parent = &pdev->dev;
 	watchdog_set_nowayout(&pnx4008_wdd, nowayout);
 
 	pnx4008_wdt_stop(&pnx4008_wdd);	/* disable for now */
diff --git a/drivers/watchdog/qcom-wdt.c b/drivers/watchdog/qcom-wdt.c
index aa03ca8f2d9b..773dcfaee7b2 100644
--- a/drivers/watchdog/qcom-wdt.c
+++ b/drivers/watchdog/qcom-wdt.c
@@ -171,6 +171,7 @@ static int qcom_wdt_probe(struct platform_device *pdev)
 	wdt->wdd.ops = &qcom_wdt_ops;
 	wdt->wdd.min_timeout = 1;
 	wdt->wdd.max_timeout = 0x10000000U / wdt->rate;
+	wdt->wdd.parent = &pdev->dev;
 
 	/*
 	 * If 'timeout-sec' unspecified in devicetree, assume a 30 second
diff --git a/drivers/watchdog/retu_wdt.c b/drivers/watchdog/retu_wdt.c
index b7c68e275aeb..39cd51df2ffc 100644
--- a/drivers/watchdog/retu_wdt.c
+++ b/drivers/watchdog/retu_wdt.c
@@ -127,6 +127,7 @@ static int retu_wdt_probe(struct platform_device *pdev)
 	retu_wdt->timeout	= RETU_WDT_MAX_TIMER;
 	retu_wdt->min_timeout	= 0;
 	retu_wdt->max_timeout	= RETU_WDT_MAX_TIMER;
+	retu_wdt->parent	= &pdev->dev;
 
 	watchdog_set_drvdata(retu_wdt, wdev);
 	watchdog_set_nowayout(retu_wdt, nowayout);
diff --git a/drivers/watchdog/rt2880_wdt.c b/drivers/watchdog/rt2880_wdt.c
index a6f7e2e29beb..1967919ae743 100644
--- a/drivers/watchdog/rt2880_wdt.c
+++ b/drivers/watchdog/rt2880_wdt.c
@@ -161,6 +161,7 @@ static int rt288x_wdt_probe(struct platform_device *pdev)
 	rt288x_wdt_dev.dev = &pdev->dev;
 	rt288x_wdt_dev.bootstatus = rt288x_wdt_bootcause();
 	rt288x_wdt_dev.max_timeout = (0xfffful / rt288x_wdt_freq);
+	rt288x_wdt_dev.parent = &pdev->dev;
 
 	watchdog_init_timeout(&rt288x_wdt_dev, rt288x_wdt_dev.max_timeout,
 			      &pdev->dev);
diff --git a/drivers/watchdog/s3c2410_wdt.c b/drivers/watchdog/s3c2410_wdt.c
index e89ae027c91d..d781000c7825 100644
--- a/drivers/watchdog/s3c2410_wdt.c
+++ b/drivers/watchdog/s3c2410_wdt.c
@@ -607,6 +607,7 @@ static int s3c2410wdt_probe(struct platform_device *pdev)
 	watchdog_set_nowayout(&wdt->wdt_device, nowayout);
 
 	wdt->wdt_device.bootstatus = s3c2410wdt_get_bootstatus(wdt);
+	wdt->wdt_device.parent = &pdev->dev;
 
 	ret = watchdog_register_device(&wdt->wdt_device);
 	if (ret) {
diff --git a/drivers/watchdog/shwdt.c b/drivers/watchdog/shwdt.c
index 567458b137a6..f90812170657 100644
--- a/drivers/watchdog/shwdt.c
+++ b/drivers/watchdog/shwdt.c
@@ -252,6 +252,7 @@ static int sh_wdt_probe(struct platform_device *pdev)
 
 	watchdog_set_nowayout(&sh_wdt_dev, nowayout);
 	watchdog_set_drvdata(&sh_wdt_dev, wdt);
+	sh_wdt_dev.parent = &pdev->dev;
 
 	spin_lock_init(&wdt->lock);
 
diff --git a/drivers/watchdog/sirfsoc_wdt.c b/drivers/watchdog/sirfsoc_wdt.c
index 42fa5c0c518a..d0578ab2e636 100644
--- a/drivers/watchdog/sirfsoc_wdt.c
+++ b/drivers/watchdog/sirfsoc_wdt.c
@@ -154,6 +154,7 @@ static int sirfsoc_wdt_probe(struct platform_device *pdev)
 
 	watchdog_init_timeout(&sirfsoc_wdd, timeout, &pdev->dev);
 	watchdog_set_nowayout(&sirfsoc_wdd, nowayout);
+	sirfsoc_wdd.parent = &pdev->dev;
 
 	ret = watchdog_register_device(&sirfsoc_wdd);
 	if (ret)
diff --git a/drivers/watchdog/sp805_wdt.c b/drivers/watchdog/sp805_wdt.c
index 4e7fec36f5c3..01d816251302 100644
--- a/drivers/watchdog/sp805_wdt.c
+++ b/drivers/watchdog/sp805_wdt.c
@@ -226,6 +226,7 @@ sp805_wdt_probe(struct amba_device *adev, const struct amba_id *id)
 	wdt->adev = adev;
 	wdt->wdd.info = &wdt_info;
 	wdt->wdd.ops = &wdt_ops;
+	wdt->wdd.parent = &adev->dev;
 
 	spin_lock_init(&wdt->lock);
 	watchdog_set_nowayout(&wdt->wdd, nowayout);
diff --git a/drivers/watchdog/st_lpc_wdt.c b/drivers/watchdog/st_lpc_wdt.c
index 6785afdc0fca..14e9badf2bfa 100644
--- a/drivers/watchdog/st_lpc_wdt.c
+++ b/drivers/watchdog/st_lpc_wdt.c
@@ -241,6 +241,7 @@ static int st_wdog_probe(struct platform_device *pdev)
 		return -EINVAL;
 	}
 	st_wdog_dev.max_timeout = 0xFFFFFFFF / st_wdog->clkrate;
+	st_wdog_dev.parent = &pdev->dev;
 
 	ret = clk_prepare_enable(clk);
 	if (ret) {
diff --git a/drivers/watchdog/stmp3xxx_rtc_wdt.c b/drivers/watchdog/stmp3xxx_rtc_wdt.c
index e7f0d5b60d3d..3ee6128a540e 100644
--- a/drivers/watchdog/stmp3xxx_rtc_wdt.c
+++ b/drivers/watchdog/stmp3xxx_rtc_wdt.c
@@ -76,6 +76,7 @@ static int stmp3xxx_wdt_probe(struct platform_device *pdev)
 	watchdog_set_drvdata(&stmp3xxx_wdd, &pdev->dev);
 
 	stmp3xxx_wdd.timeout = clamp_t(unsigned, heartbeat, 1, STMP3XXX_MAX_TIMEOUT);
+	stmp3xxx_wdd.parent = &pdev->dev;
 
 	ret = watchdog_register_device(&stmp3xxx_wdd);
 	if (ret < 0) {
diff --git a/drivers/watchdog/tegra_wdt.c b/drivers/watchdog/tegra_wdt.c
index 30451ea46902..7f97cdd53f29 100644
--- a/drivers/watchdog/tegra_wdt.c
+++ b/drivers/watchdog/tegra_wdt.c
@@ -218,6 +218,7 @@ static int tegra_wdt_probe(struct platform_device *pdev)
 	wdd->ops = &tegra_wdt_ops;
 	wdd->min_timeout = MIN_WDT_TIMEOUT;
 	wdd->max_timeout = MAX_WDT_TIMEOUT;
+	wdd->parent = &pdev->dev;
 
 	watchdog_set_drvdata(wdd, wdt);
 
diff --git a/drivers/watchdog/twl4030_wdt.c b/drivers/watchdog/twl4030_wdt.c
index 2c1db6fa9a27..9bf3cc0f3961 100644
--- a/drivers/watchdog/twl4030_wdt.c
+++ b/drivers/watchdog/twl4030_wdt.c
@@ -83,6 +83,7 @@ static int twl4030_wdt_probe(struct platform_device *pdev)
 	wdt->timeout		= 30;
 	wdt->min_timeout	= 1;
 	wdt->max_timeout	= 30;
+	wdt->parent = &pdev->dev;
 
 	watchdog_set_nowayout(wdt, nowayout);
 	platform_set_drvdata(pdev, wdt);
diff --git a/drivers/watchdog/txx9wdt.c b/drivers/watchdog/txx9wdt.c
index 7f615933d31a..c2da880292bc 100644
--- a/drivers/watchdog/txx9wdt.c
+++ b/drivers/watchdog/txx9wdt.c
@@ -131,6 +131,7 @@ static int __init txx9wdt_probe(struct platform_device *dev)
 	txx9wdt.timeout = timeout;
 	txx9wdt.min_timeout = 1;
 	txx9wdt.max_timeout = WD_MAX_TIMEOUT;
+	txx9wdt.parent = &dev->dev;
 	watchdog_set_nowayout(&txx9wdt, nowayout);
 
 	ret = watchdog_register_device(&txx9wdt);
diff --git a/drivers/watchdog/ux500_wdt.c b/drivers/watchdog/ux500_wdt.c
index 9de09ab00838..37c084353cce 100644
--- a/drivers/watchdog/ux500_wdt.c
+++ b/drivers/watchdog/ux500_wdt.c
@@ -96,6 +96,7 @@ static int ux500_wdt_probe(struct platform_device *pdev)
 			ux500_wdt.max_timeout = WATCHDOG_MAX28;
 	}
 
+	ux500_wdt.parent = &pdev->dev;
 	watchdog_set_nowayout(&ux500_wdt, nowayout);
 
 	/* disable auto off on sleep */
diff --git a/drivers/watchdog/via_wdt.c b/drivers/watchdog/via_wdt.c
index 56369c4f1961..5f9cbc37520d 100644
--- a/drivers/watchdog/via_wdt.c
+++ b/drivers/watchdog/via_wdt.c
@@ -206,6 +206,7 @@ static int wdt_probe(struct pci_dev *pdev,
 		timeout = WDT_TIMEOUT;
 
 	wdt_dev.timeout = timeout;
+	wdt_dev.parent = &pdev->dev;
 	watchdog_set_nowayout(&wdt_dev, nowayout);
 	if (readl(wdt_mem) & VIA_WDT_FIRED)
 		wdt_dev.bootstatus |= WDIOF_CARDRESET;
diff --git a/drivers/watchdog/wm831x_wdt.c b/drivers/watchdog/wm831x_wdt.c
index 2fa17e746ff6..8d1184aee932 100644
--- a/drivers/watchdog/wm831x_wdt.c
+++ b/drivers/watchdog/wm831x_wdt.c
@@ -215,6 +215,7 @@ static int wm831x_wdt_probe(struct platform_device *pdev)
 
 	wm831x_wdt->info = &wm831x_wdt_info;
 	wm831x_wdt->ops = &wm831x_wdt_ops;
+	wm831x_wdt->parent = &pdev->dev;
 	watchdog_set_nowayout(wm831x_wdt, nowayout);
 	watchdog_set_drvdata(wm831x_wdt, driver_data);
 
diff --git a/drivers/watchdog/wm8350_wdt.c b/drivers/watchdog/wm8350_wdt.c
index 34d272ada23d..4ab4b8347d45 100644
--- a/drivers/watchdog/wm8350_wdt.c
+++ b/drivers/watchdog/wm8350_wdt.c
@@ -151,6 +151,7 @@ static int wm8350_wdt_probe(struct platform_device *pdev)
 
 	watchdog_set_nowayout(&wm8350_wdt, nowayout);
 	watchdog_set_drvdata(&wm8350_wdt, wm8350);
+	wm8350_wdt.parent = &pdev->dev;
 
 	/* Default to 4s timeout */
 	wm8350_wdt_set_timeout(&wm8350_wdt, 4);
-- 
2.4.3



From leilk.liu at mediatek.com  Tue Aug 18 20:37:55 2015
From: leilk.liu at mediatek.com (Leilk Liu)
Date: Wed, 19 Aug 2015 11:37:55 +0800
Subject: [PATCH 0/3] Fixup mediatek spi driver
Message-ID: <1439955478-2733-1-git-send-email-leilk.liu@mediatek.com>

Change in this patch:
1. revise coding styles.
2. delete redundant clock in prepare/unprepare_hardware.
3. fix incorrect endian usage on big-endian system.

Leilk Liu (3):
  spi: mediatek: revise coding style
  spi: mediatek: remove redundant clock in
    prepare_hardware/unprepare_hardware
  spi: mediatek: fix spi incorrect endian usage

 drivers/spi/spi-mt65xx.c                 | 169 +++++++++++++------------------
 include/linux/platform_data/spi-mt65xx.h |   2 -
 2 files changed, 73 insertions(+), 98 deletions(-)

--
1.8.1.1.dirty



From leilk.liu at mediatek.com  Tue Aug 18 20:37:57 2015
From: leilk.liu at mediatek.com (Leilk Liu)
Date: Wed, 19 Aug 2015 11:37:57 +0800
Subject: [PATCH 2/3] spi: mediatek: remove redundant clock in
 prepare_hardware/unprepare_hardware
In-Reply-To: <1439955478-2733-1-git-send-email-leilk.liu@mediatek.com>
References: <1439955478-2733-1-git-send-email-leilk.liu@mediatek.com>
Message-ID: <1439955478-2733-3-git-send-email-leilk.liu@mediatek.com>

clock in prepare_hardware/unprepare_hardware is redundant
with pm_runtime, so remove them.

Signed-off-by: Leilk Liu <leilk.liu at mediatek.com>
---
 drivers/spi/spi-mt65xx.c | 17 -----------------
 1 file changed, 17 deletions(-)

diff --git a/drivers/spi/spi-mt65xx.c b/drivers/spi/spi-mt65xx.c
index 814bca4..1c2b215 100644
--- a/drivers/spi/spi-mt65xx.c
+++ b/drivers/spi/spi-mt65xx.c
@@ -181,13 +181,6 @@ static int mtk_spi_prepare_hardware(struct spi_master *master)
 	struct spi_transfer *trans;
 	struct mtk_spi *mdata = spi_master_get_devdata(master);
 	struct spi_message *msg = master->cur_msg;
-	int ret;
-
-	ret = clk_prepare_enable(mdata->spi_clk);
-	if (ret < 0) {
-		dev_err(&master->dev, "failed to enable clock (%d)\n", ret);
-		return ret;
-	}
 
 	trans = list_first_entry(&msg->transfers, struct spi_transfer,
 				 transfer_list);
@@ -196,15 +189,6 @@ static int mtk_spi_prepare_hardware(struct spi_master *master)
 		mtk_spi_reset(mdata);
 	}
 
-	return ret;
-}
-
-static int mtk_spi_unprepare_hardware(struct spi_master *master)
-{
-	struct mtk_spi *mdata = spi_master_get_devdata(master);
-
-	clk_disable_unprepare(mdata->spi_clk);
-
 	return 0;
 }
 
@@ -537,7 +521,6 @@ static int mtk_spi_probe(struct platform_device *pdev)
 
 	master->set_cs = mtk_spi_set_cs;
 	master->prepare_transfer_hardware = mtk_spi_prepare_hardware;
-	master->unprepare_transfer_hardware = mtk_spi_unprepare_hardware;
 	master->prepare_message = mtk_spi_prepare_message;
 	master->transfer_one = mtk_spi_transfer_one;
 	master->can_dma = mtk_spi_can_dma;
-- 
1.8.1.1.dirty



From leilk.liu at mediatek.com  Tue Aug 18 20:37:56 2015
From: leilk.liu at mediatek.com (Leilk Liu)
Date: Wed, 19 Aug 2015 11:37:56 +0800
Subject: [PATCH 1/3] spi: mediatek: revise coding style
In-Reply-To: <1439955478-2733-1-git-send-email-leilk.liu@mediatek.com>
References: <1439955478-2733-1-git-send-email-leilk.liu@mediatek.com>
Message-ID: <1439955478-2733-2-git-send-email-leilk.liu@mediatek.com>

This patch revises mediatek spi driver coding styles.

Signed-off-by: Leilk Liu <leilk.liu at mediatek.com>
---
 drivers/spi/spi-mt65xx.c | 125 ++++++++++++++++++++++++-----------------------
 1 file changed, 65 insertions(+), 60 deletions(-)

diff --git a/drivers/spi/spi-mt65xx.c b/drivers/spi/spi-mt65xx.c
index c467ce0..814bca4 100644
--- a/drivers/spi/spi-mt65xx.c
+++ b/drivers/spi/spi-mt65xx.c
@@ -16,6 +16,7 @@
 #include <linux/device.h>
 #include <linux/err.h>
 #include <linux/interrupt.h>
+#include <linux/io.h>
 #include <linux/ioport.h>
 #include <linux/module.h>
 #include <linux/of.h>
@@ -48,15 +49,8 @@
 #define SPI_CFG1_PACKET_LOOP_MASK         0xff00
 #define SPI_CFG1_PACKET_LENGTH_MASK       0x3ff0000
 
-#define SPI_CMD_ACT_OFFSET                0
-#define SPI_CMD_RESUME_OFFSET             1
-#define SPI_CMD_CPHA_OFFSET               8
-#define SPI_CMD_CPOL_OFFSET               9
-#define SPI_CMD_TXMSBF_OFFSET             12
-#define SPI_CMD_RXMSBF_OFFSET             13
-#define SPI_CMD_RX_ENDIAN_OFFSET          14
-#define SPI_CMD_TX_ENDIAN_OFFSET          15
-
+#define SPI_CMD_ACT                  BIT(0)
+#define SPI_CMD_RESUME               BIT(1)
 #define SPI_CMD_RST                  BIT(2)
 #define SPI_CMD_PAUSE_EN             BIT(4)
 #define SPI_CMD_DEASSERT             BIT(5)
@@ -71,12 +65,10 @@
 #define SPI_CMD_FINISH_IE            BIT(16)
 #define SPI_CMD_PAUSE_IE             BIT(17)
 
-#define MTK_SPI_QUIRK_PAD_SELECT 1
-/* Must explicitly send dummy Tx bytes to do Rx only transfer */
-#define MTK_SPI_QUIRK_MUST_TX 1
-
 #define MT8173_SPI_MAX_PAD_SEL 3
 
+#define MTK_SPI_PAUSE_INT_STATUS 0x2
+
 #define MTK_SPI_IDLE 0
 #define MTK_SPI_PAUSED 1
 
@@ -84,8 +76,9 @@
 #define MTK_SPI_PACKET_SIZE 1024
 
 struct mtk_spi_compatible {
-	u32 need_pad_sel;
-	u32 must_tx;
+	bool need_pad_sel;
+	/* Must explicitly send dummy Tx bytes to do Rx only transfer */
+	bool must_tx;
 };
 
 struct mtk_spi {
@@ -100,19 +93,11 @@ struct mtk_spi {
 	const struct mtk_spi_compatible *dev_comp;
 };
 
-static const struct mtk_spi_compatible mt6589_compat = {
-	.need_pad_sel = 0,
-	.must_tx = 0,
-};
-
-static const struct mtk_spi_compatible mt8135_compat = {
-	.need_pad_sel = 0,
-	.must_tx = 0,
-};
-
+static const struct mtk_spi_compatible mt6589_compat;
+static const struct mtk_spi_compatible mt8135_compat;
 static const struct mtk_spi_compatible mt8173_compat = {
-	.need_pad_sel = MTK_SPI_QUIRK_PAD_SELECT,
-	.must_tx = MTK_SPI_QUIRK_MUST_TX,
+	.need_pad_sel = true,
+	.must_tx = true,
 };
 
 /*
@@ -156,14 +141,24 @@ static void mtk_spi_config(struct mtk_spi *mdata,
 	reg_val = readl(mdata->base + SPI_CMD_REG);
 
 	/* set the mlsbx and mlsbtx */
-	reg_val &= ~(SPI_CMD_TXMSBF | SPI_CMD_RXMSBF);
-	reg_val |= (chip_config->tx_mlsb << SPI_CMD_TXMSBF_OFFSET);
-	reg_val |= (chip_config->rx_mlsb << SPI_CMD_RXMSBF_OFFSET);
+	if (chip_config->tx_mlsb)
+		reg_val |= SPI_CMD_TXMSBF;
+	else
+		reg_val &= ~SPI_CMD_TXMSBF;
+	if (chip_config->rx_mlsb)
+		reg_val |= SPI_CMD_RXMSBF;
+	else
+		reg_val &= ~SPI_CMD_RXMSBF;
 
 	/* set the tx/rx endian */
-	reg_val &= ~(SPI_CMD_TX_ENDIAN | SPI_CMD_RX_ENDIAN);
-	reg_val |= (chip_config->tx_endian << SPI_CMD_TX_ENDIAN_OFFSET);
-	reg_val |= (chip_config->rx_endian << SPI_CMD_RX_ENDIAN_OFFSET);
+	if (chip_config->tx_endian)
+		reg_val |= SPI_CMD_TX_ENDIAN;
+	else
+		reg_val &= ~SPI_CMD_TX_ENDIAN;
+	if (chip_config->rx_endian)
+		reg_val |= SPI_CMD_RX_ENDIAN;
+	else
+		reg_val &= ~SPI_CMD_RX_ENDIAN;
 
 	/* set finish and pause interrupt always enable */
 	reg_val |= SPI_CMD_FINISH_IE | SPI_CMD_PAUSE_EN;
@@ -196,7 +191,7 @@ static int mtk_spi_prepare_hardware(struct spi_master *master)
 
 	trans = list_first_entry(&msg->transfers, struct spi_transfer,
 				 transfer_list);
-	if (trans->cs_change == 0) {
+	if (!trans->cs_change) {
 		mdata->state = MTK_SPI_IDLE;
 		mtk_spi_reset(mdata);
 	}
@@ -226,9 +221,14 @@ static int mtk_spi_prepare_message(struct spi_master *master,
 	cpol = spi->mode & SPI_CPOL ? 1 : 0;
 
 	reg_val = readl(mdata->base + SPI_CMD_REG);
-	reg_val &= ~(SPI_CMD_CPHA | SPI_CMD_CPOL);
-	reg_val |= (cpha << SPI_CMD_CPHA_OFFSET);
-	reg_val |= (cpol << SPI_CMD_CPOL_OFFSET);
+	if (cpha)
+		reg_val |= SPI_CMD_CPHA;
+	else
+		reg_val &= ~SPI_CMD_CPHA;
+	if (cpol)
+		reg_val |= SPI_CMD_CPOL;
+	else
+		reg_val &= ~SPI_CMD_CPOL;
 	writel(reg_val, mdata->base + SPI_CMD_REG);
 
 	chip_config = spi->controller_data;
@@ -257,8 +257,7 @@ static void mtk_spi_set_cs(struct spi_device *spi, bool enable)
 static void mtk_spi_prepare_transfer(struct spi_master *master,
 				     struct spi_transfer *xfer)
 {
-	u32 spi_clk_hz, div, high_time, low_time, holdtime,
-	    setuptime, cs_idletime, reg_val = 0;
+	u32 spi_clk_hz, div, sck_time, cs_time, reg_val = 0;
 	struct mtk_spi *mdata = spi_master_get_devdata(master);
 
 	spi_clk_hz = clk_get_rate(mdata->spi_clk);
@@ -267,21 +266,18 @@ static void mtk_spi_prepare_transfer(struct spi_master *master,
 	else
 		div = 1;
 
-	high_time = (div + 1) / 2;
-	low_time = (div + 1) / 2;
-	holdtime = (div + 1) / 2 * 2;
-	setuptime = (div + 1) / 2 * 2;
-	cs_idletime = (div + 1) / 2 * 2;
+	sck_time = (div + 1) / 2;
+	cs_time = sck_time * 2;
 
-	reg_val |= (((high_time - 1) & 0xff) << SPI_CFG0_SCK_HIGH_OFFSET);
-	reg_val |= (((low_time - 1) & 0xff) << SPI_CFG0_SCK_LOW_OFFSET);
-	reg_val |= (((holdtime - 1) & 0xff) << SPI_CFG0_CS_HOLD_OFFSET);
-	reg_val |= (((setuptime - 1) & 0xff) << SPI_CFG0_CS_SETUP_OFFSET);
+	reg_val |= (((sck_time - 1) & 0xff) << SPI_CFG0_SCK_HIGH_OFFSET);
+	reg_val |= (((sck_time - 1) & 0xff) << SPI_CFG0_SCK_LOW_OFFSET);
+	reg_val |= (((cs_time - 1) & 0xff) << SPI_CFG0_CS_HOLD_OFFSET);
+	reg_val |= (((cs_time - 1) & 0xff) << SPI_CFG0_CS_SETUP_OFFSET);
 	writel(reg_val, mdata->base + SPI_CFG0_REG);
 
 	reg_val = readl(mdata->base + SPI_CFG1_REG);
 	reg_val &= ~SPI_CFG1_CS_IDLE_MASK;
-	reg_val |= (((cs_idletime - 1) & 0xff) << SPI_CFG1_CS_IDLE_OFFSET);
+	reg_val |= (((cs_time - 1) & 0xff) << SPI_CFG1_CS_IDLE_OFFSET);
 	writel(reg_val, mdata->base + SPI_CFG1_REG);
 }
 
@@ -290,11 +286,11 @@ static void mtk_spi_setup_packet(struct spi_master *master)
 	u32 packet_size, packet_loop, reg_val;
 	struct mtk_spi *mdata = spi_master_get_devdata(master);
 
-	packet_size = min_t(unsigned, mdata->xfer_len, MTK_SPI_PACKET_SIZE);
+	packet_size = min_t(u32, mdata->xfer_len, MTK_SPI_PACKET_SIZE);
 	packet_loop = mdata->xfer_len / packet_size;
 
 	reg_val = readl(mdata->base + SPI_CFG1_REG);
-	reg_val &= ~(SPI_CFG1_PACKET_LENGTH_MASK + SPI_CFG1_PACKET_LOOP_MASK);
+	reg_val &= ~(SPI_CFG1_PACKET_LENGTH_MASK | SPI_CFG1_PACKET_LOOP_MASK);
 	reg_val |= (packet_size - 1) << SPI_CFG1_PACKET_LENGTH_OFFSET;
 	reg_val |= (packet_loop - 1) << SPI_CFG1_PACKET_LOOP_OFFSET;
 	writel(reg_val, mdata->base + SPI_CFG1_REG);
@@ -302,20 +298,20 @@ static void mtk_spi_setup_packet(struct spi_master *master)
 
 static void mtk_spi_enable_transfer(struct spi_master *master)
 {
-	int cmd;
+	u32 cmd;
 	struct mtk_spi *mdata = spi_master_get_devdata(master);
 
 	cmd = readl(mdata->base + SPI_CMD_REG);
 	if (mdata->state == MTK_SPI_IDLE)
-		cmd |= 1 << SPI_CMD_ACT_OFFSET;
+		cmd |= SPI_CMD_ACT;
 	else
-		cmd |= 1 << SPI_CMD_RESUME_OFFSET;
+		cmd |= SPI_CMD_RESUME;
 	writel(cmd, mdata->base + SPI_CMD_REG);
 }
 
-static int mtk_spi_get_mult_delta(int xfer_len)
+static int mtk_spi_get_mult_delta(u32 xfer_len)
 {
-	int mult_delta;
+	u32 mult_delta;
 
 	if (xfer_len > MTK_SPI_PACKET_SIZE)
 		mult_delta = xfer_len % MTK_SPI_PACKET_SIZE;
@@ -459,7 +455,7 @@ static irqreturn_t mtk_spi_interrupt(int irq, void *dev_id)
 	struct spi_transfer *trans = mdata->cur_transfer;
 
 	reg_val = readl(mdata->base + SPI_STATUS0_REG);
-	if (reg_val & 0x2)
+	if (reg_val & MTK_SPI_PAUSE_INT_STATUS)
 		mdata->state = MTK_SPI_PAUSED;
 	else
 		mdata->state = MTK_SPI_IDLE;
@@ -527,7 +523,7 @@ static int mtk_spi_probe(struct platform_device *pdev)
 	struct mtk_spi *mdata;
 	const struct of_device_id *of_id;
 	struct resource *res;
-	int	irq, ret;
+	int irq, ret;
 
 	master = spi_alloc_master(&pdev->dev, sizeof(*mdata));
 	if (!master) {
@@ -693,8 +689,10 @@ static int mtk_spi_resume(struct device *dev)
 
 	if (!pm_runtime_suspended(dev)) {
 		ret = clk_prepare_enable(mdata->spi_clk);
-		if (ret < 0)
+		if (ret < 0) {
+			dev_err(dev, "failed to enable spi_clk (%d)\n", ret);
 			return ret;
+		}
 	}
 
 	ret = spi_master_resume(master);
@@ -720,8 +718,15 @@ static int mtk_spi_runtime_resume(struct device *dev)
 {
 	struct spi_master *master = dev_get_drvdata(dev);
 	struct mtk_spi *mdata = spi_master_get_devdata(master);
+	int ret;
 
-	return clk_prepare_enable(mdata->spi_clk);
+	ret = clk_prepare_enable(mdata->spi_clk);
+	if (ret < 0) {
+		dev_err(dev, "failed to enable spi_clk (%d)\n", ret);
+		return ret;
+	}
+
+	return 0;
 }
 #endif /* CONFIG_PM */
 
-- 
1.8.1.1.dirty



From leilk.liu at mediatek.com  Tue Aug 18 20:37:58 2015
From: leilk.liu at mediatek.com (Leilk Liu)
Date: Wed, 19 Aug 2015 11:37:58 +0800
Subject: [PATCH 3/3] spi: mediatek: fix spi incorrect endian usage
In-Reply-To: <1439955478-2733-1-git-send-email-leilk.liu@mediatek.com>
References: <1439955478-2733-1-git-send-email-leilk.liu@mediatek.com>
Message-ID: <1439955478-2733-4-git-send-email-leilk.liu@mediatek.com>

TX_ENDIAN/RX_ENDIAN bits define whether to reverse the endian
order of the data DMA from/to memory. The endian order should
keep the same with cpu endian.

Signed-off-by: Leilk Liu <leilk.liu at mediatek.com>
---
 drivers/spi/spi-mt65xx.c                 | 43 ++++++++++++--------------------
 include/linux/platform_data/spi-mt65xx.h |  2 --
 2 files changed, 16 insertions(+), 29 deletions(-)

diff --git a/drivers/spi/spi-mt65xx.c b/drivers/spi/spi-mt65xx.c
index 1c2b215..eaadc7e 100644
--- a/drivers/spi/spi-mt65xx.c
+++ b/drivers/spi/spi-mt65xx.c
@@ -107,8 +107,6 @@ static const struct mtk_spi_compatible mt8173_compat = {
 static const struct mtk_chip_config mtk_default_chip_info = {
 	.rx_mlsb = 1,
 	.tx_mlsb = 1,
-	.tx_endian = 0,
-	.rx_endian = 0,
 };
 
 static const struct of_device_id mtk_spi_of_match[] = {
@@ -151,14 +149,13 @@ static void mtk_spi_config(struct mtk_spi *mdata,
 		reg_val &= ~SPI_CMD_RXMSBF;
 
 	/* set the tx/rx endian */
-	if (chip_config->tx_endian)
-		reg_val |= SPI_CMD_TX_ENDIAN;
-	else
-		reg_val &= ~SPI_CMD_TX_ENDIAN;
-	if (chip_config->rx_endian)
-		reg_val |= SPI_CMD_RX_ENDIAN;
-	else
-		reg_val &= ~SPI_CMD_RX_ENDIAN;
+#ifdef __LITTLE_ENDIAN
+	reg_val &= ~SPI_CMD_TX_ENDIAN;
+	reg_val &= ~SPI_CMD_RX_ENDIAN;
+#else
+	reg_val |= SPI_CMD_TX_ENDIAN;
+	reg_val |= SPI_CMD_RX_ENDIAN;
+#endif
 
 	/* set finish and pause interrupt always enable */
 	reg_val |= SPI_CMD_FINISH_IE | SPI_CMD_PAUSE_EN;
@@ -348,7 +345,7 @@ static int mtk_spi_fifo_transfer(struct spi_master *master,
 				 struct spi_device *spi,
 				 struct spi_transfer *xfer)
 {
-	int cnt, i;
+	int cnt;
 	struct mtk_spi *mdata = spi_master_get_devdata(master);
 
 	mdata->cur_transfer = xfer;
@@ -360,10 +357,7 @@ static int mtk_spi_fifo_transfer(struct spi_master *master,
 		cnt = xfer->len / 4 + 1;
 	else
 		cnt = xfer->len / 4;
-
-	for (i = 0; i < cnt; i++)
-		writel(*((u32 *)xfer->tx_buf + i),
-		       mdata->base + SPI_TX_DATA_REG);
+	iowrite32_rep(mdata->base + SPI_TX_DATA_REG, xfer->tx_buf, cnt);
 
 	mtk_spi_enable_transfer(master);
 
@@ -433,7 +427,7 @@ static bool mtk_spi_can_dma(struct spi_master *master,
 
 static irqreturn_t mtk_spi_interrupt(int irq, void *dev_id)
 {
-	u32 cmd, reg_val, i;
+	u32 cmd, reg_val, cnt;
 	struct spi_master *master = dev_id;
 	struct mtk_spi *mdata = spi_master_get_devdata(master);
 	struct spi_transfer *trans = mdata->cur_transfer;
@@ -445,18 +439,13 @@ static irqreturn_t mtk_spi_interrupt(int irq, void *dev_id)
 		mdata->state = MTK_SPI_IDLE;
 
 	if (!master->can_dma(master, master->cur_msg->spi, trans)) {
-		/* xfer len is not N*4 bytes every time in a transfer,
-		 * but SPI_RX_DATA_REG must reads 4 bytes once,
-		 * so rx buffer byte by byte.
-		 */
 		if (trans->rx_buf) {
-			for (i = 0; i < mdata->xfer_len; i++) {
-				if (i % 4 == 0)
-					reg_val =
-					readl(mdata->base + SPI_RX_DATA_REG);
-				*((u8 *)(trans->rx_buf + i)) =
-					(reg_val >> ((i % 4) * 8)) & 0xff;
-			}
+			if (mdata->xfer_len % 4)
+				cnt = mdata->xfer_len / 4 + 1;
+			else
+				cnt = mdata->xfer_len / 4;
+			ioread32_rep(mdata->base + SPI_RX_DATA_REG,
+				     trans->rx_buf, cnt);
 		}
 		spi_finalize_current_transfer(master);
 		return IRQ_HANDLED;
diff --git a/include/linux/platform_data/spi-mt65xx.h b/include/linux/platform_data/spi-mt65xx.h
index 7512255..54b0448 100644
--- a/include/linux/platform_data/spi-mt65xx.h
+++ b/include/linux/platform_data/spi-mt65xx.h
@@ -16,7 +16,5 @@
 struct mtk_chip_config {
 	u32 tx_mlsb;
 	u32 rx_mlsb;
-	u32 tx_endian;
-	u32 rx_endian;
 };
 #endif
-- 
1.8.1.1.dirty



From wens at csie.org  Tue Aug 18 21:20:02 2015
From: wens at csie.org (Chen-Yu Tsai)
Date: Wed, 19 Aug 2015 12:20:02 +0800
Subject: [PATCH v3 1/8] rsb: Add generic Reduced Serial Bus (RSB) controller
 binding documentation
In-Reply-To: <1439958009-14056-1-git-send-email-wens@csie.org>
References: <1439958009-14056-1-git-send-email-wens@csie.org>
Message-ID: <1439958009-14056-2-git-send-email-wens@csie.org>

Reduced Serial Bus is a proprietary 2-line push-pull serial bus
supporting multiple slave devices.

It was developed by Allwinner, Inc. and used by Allwinner and X-Powers,
Inc. for their line of PMICs and other peripheral ICs.

Signed-off-by: Chen-Yu Tsai <wens at csie.org>
---
 Documentation/devicetree/bindings/rsb/rsb.txt | 50 +++++++++++++++++++++++++++
 1 file changed, 50 insertions(+)
 create mode 100644 Documentation/devicetree/bindings/rsb/rsb.txt

diff --git a/Documentation/devicetree/bindings/rsb/rsb.txt b/Documentation/devicetree/bindings/rsb/rsb.txt
new file mode 100644
index 000000000000..0b027948ca9c
--- /dev/null
+++ b/Documentation/devicetree/bindings/rsb/rsb.txt
@@ -0,0 +1,50 @@
+Reduced Serial Bus (RSB) Controller
+
+This document defines a generic set of bindings for use by RSB controllers.
+A controller is modelled in device tree as a node with zero or more child
+nodes, each representing a unique slave device on the bus.
+
+Required properties:
+
+ - #address-cells : must be 2
+ - #size-cells : must be 0
+
+Optional properties:
+
+ - clock-frequency : Desired bus clock frequency in Hz. Maximum is 20 MHz.
+
+Child nodes:
+
+An RSB controller node can contain zero or more child nodes representing
+slave devices on the bus.  Child 'reg' properties are specified as a
+runtime address, hardware address pair. The hardware address is hardwired
+in the device, which can normally be found in the datasheet. The runtime
+address is set by software. No 2 devices on the same bus shall have the
+same runtime address.
+
+Valid runtime addresses - There are only 15 valid runtime addresses:
+
+    0x17, 0x2d, 0x3a, 0x4e, 0x59, 0x63, 0x74, 0x8b,
+    0x9c, 0xa6, 0xb1, 0xc5, 0xd2, 0xe8, 0xff
+
+It is highly recommended that one choose the same runtime addresses as
+vendor BSPs use so that a) the addresses remain the same across different
+software systems, and b) addresses of supported and listed slave devices
+don't conflict with unsupported or not yet listed devices.
+
+Example:
+
+	rsb at ... {
+		compatible = "...";
+		reg = <...>;
+		/* ... */
+		#address-cells = <2>;
+		#size-cells = <0>;
+
+		pmic at 2d {
+			compatible = "...";
+			reg = <0x2d 0x3e3>;
+
+			/* ... */
+		};
+	};
-- 
2.5.0



From wens at csie.org  Tue Aug 18 21:20:05 2015
From: wens at csie.org (Chen-Yu Tsai)
Date: Wed, 19 Aug 2015 12:20:05 +0800
Subject: [PATCH v3 4/8] rsb: sunxi: Add driver for Allwinner Reduced Serial
 Bus controller
In-Reply-To: <1439958009-14056-1-git-send-email-wens@csie.org>
References: <1439958009-14056-1-git-send-email-wens@csie.org>
Message-ID: <1439958009-14056-5-git-send-email-wens@csie.org>

Signed-off-by: Chen-Yu Tsai <wens at csie.org>
---
 drivers/rsb/Kconfig     |  15 ++
 drivers/rsb/Makefile    |   2 +
 drivers/rsb/rsb-sunxi.c | 441 ++++++++++++++++++++++++++++++++++++++++++++++++
 3 files changed, 458 insertions(+)
 create mode 100644 drivers/rsb/rsb-sunxi.c

diff --git a/drivers/rsb/Kconfig b/drivers/rsb/Kconfig
index 6642e1db6d98..54a28a39e0e2 100644
--- a/drivers/rsb/Kconfig
+++ b/drivers/rsb/Kconfig
@@ -9,3 +9,18 @@ menuconfig RSB
 	  Integrated Circuits (PMIC) or other peripherals.
 
 	  These are commonly seen on newer Allwinner SoCs and X-Powers ICs.
+
+if RSB
+
+config RSB_SUNXI
+	tristate "Allwinner RSB Controller"
+	depends on ARCH_SUNXI || COMPILE_TEST
+	default MACH_SUN8I || MACH_SUN9I
+	help
+	  If you say yes to this option, support will be included for the
+	  built-in RSB controller on Allwinner sun8i/sun9i family SoCs.
+
+	  This is required for communicating with X-Powers PMICs and other
+	  devices that have the RSB interface.
+
+endif
diff --git a/drivers/rsb/Makefile b/drivers/rsb/Makefile
index 6fe56526fbf3..31cd615f7e58 100644
--- a/drivers/rsb/Makefile
+++ b/drivers/rsb/Makefile
@@ -2,3 +2,5 @@
 # Makefile for kernel RSB framework.
 #
 obj-$(CONFIG_RSB)	+= rsb-core.o
+
+obj-$(CONFIG_RSB_SUNXI)	+= rsb-sunxi.o
diff --git a/drivers/rsb/rsb-sunxi.c b/drivers/rsb/rsb-sunxi.c
new file mode 100644
index 000000000000..07b24291fe4d
--- /dev/null
+++ b/drivers/rsb/rsb-sunxi.c
@@ -0,0 +1,441 @@
+/*
+ * RSB (Reduced Serial Bus) driver.
+ *
+ * Author: Chen-Yu Tsai <wens at csie.org>
+ *
+ * This file is licensed under the terms of the GNU General Public License
+ * version 2.  This program is licensed "as is" without any warranty of any
+ * kind, whether express or implied.
+ *
+ * The RSB controller looks like an SMBus controller which only supports
+ * byte and word data transfers. But, it differs from standard SMBus
+ * protocol on several aspects:
+ * - it uses addresses set at runtime to address slaves. Runtime addresses
+ *   are sent to slaves using their 12bit hardware addresses. Up to 15
+ *   runtime addresses are available.
+ * - it adds a parity bit every 8bits of data and address for read and
+ *   write accesses; this replaces the ack bit
+ * - only one read access is required to read a byte (instead of a write
+ *   followed by a read access in standard SMBus protocol)
+ * - there's no Ack bit after each read access
+ *
+ * This means this bus cannot be used to interface with standard SMBus
+ * devices. Devices known to support this interface include the AXP223,
+ * AXP809, and AXP806 PMICs, and the AC100 audio codec, all from X-Powers.
+ *
+ * A description of the operation and wire protocol can be found in the
+ * RSB section of Allwinner's A80 user manual, which can be found at
+ *
+ *     https://github.com/allwinner-zh/documents/tree/master/A80
+ *
+ * This document is officially released by Allwinner.
+ *
+ * This driver is based on i2c-sun6i-p2wi.c, the P2WI bus driver.
+ *
+ */
+#include <linux/clk.h>
+#include <linux/interrupt.h>
+#include <linux/io.h>
+#include <linux/iopoll.h>
+#include <linux/module.h>
+#include <linux/of.h>
+#include <linux/platform_device.h>
+#include <linux/reset.h>
+#include <linux/rsb.h>
+
+/* RSB registers */
+#define RSB_CTRL	0x0	/* Global control */
+#define RSB_CCR		0x4	/* Clock control */
+#define RSB_INTE	0x8	/* Interrupt controls */
+#define RSB_INTS	0xc	/* Interrupt status */
+#define RSB_ADDR	0x10	/* Address to send with read/write command */
+#define RSB_DATA	0x1c	/* Data to read/write */
+#define RSB_LCR		0x24	/* Line control */
+#define RSB_DMCR	0x28	/* Device mode (init) control */
+#define RSB_CMD		0x2c	/* RSB Command */
+#define RSB_DAR		0x30	/* Device address / runtime address */
+
+/* CTRL fields */
+#define RSB_CTRL_START_TRANS		BIT(7)
+#define RSB_CTRL_ABORT_TRANS		BIT(6)
+#define RSB_CTRL_GLOBAL_INT_ENB		BIT(1)
+#define RSB_CTRL_SOFT_RST		BIT(0)
+
+/* CLK CTRL fields */
+#define RSB_CCR_SDA_OUT_DELAY(v)	(((v) & 0x7) << 8)
+#define RSB_CCR_MAX_CLK_DIV		0xff
+#define RSB_CCR_CLK_DIV(v)		((v) & RSB_CCR_MAX_CLK_DIV)
+
+/* STATUS fields */
+#define RSB_INTS_TRANS_ERR_ACK		BIT(16)
+#define RSB_INTS_TRANS_ERR_DATA_BIT(v)	(((v) >> 8) & 0xf)
+#define RSB_INTS_TRANS_ERR_DATA		GENMASK(11, 8)
+#define RSB_INTS_LOAD_BSY		BIT(2)
+#define RSB_INTS_TRANS_ERR		BIT(1)
+#define RSB_INTS_TRANS_OVER		BIT(0)
+
+/* LINE CTRL fields*/
+#define RSB_LCR_SCL_STATE		BIT(5)
+#define RSB_LCR_SDA_STATE		BIT(4)
+#define RSB_LCR_SCL_CTL			BIT(3)
+#define RSB_LCR_SCL_CTL_EN		BIT(2)
+#define RSB_LCR_SDA_CTL			BIT(1)
+#define RSB_LCR_SDA_CTL_EN		BIT(0)
+
+/* DEVICE MODE CTRL field values */
+#define RSB_DMCR_DEVICE_START		BIT(31)
+#define RSB_DMCR_MODE_DATA		(0x7c << 16)
+#define RSB_DMCR_MODE_REG		(0x3e << 8)
+#define RSB_DMCR_DEV_ADDR		0x00
+
+/* CMD values */
+#define RSB_CMD_RD8			0x8b
+#define RSB_CMD_RD16			0x9c
+#define RSB_CMD_RD32			0xa6
+#define RSB_CMD_WR8			0x4e
+#define RSB_CMD_WR16			0x59
+#define RSB_CMD_WR32			0x63
+#define RSB_CMD_STRA			0xe8
+
+/* DAR fields */
+#define RSB_DAR_RTA(v)			(((v) & 0xff) << 16)
+#define RSB_DAR_DA(v)			((v) & 0xffff)
+
+#define RSB_MAX_FREQ			20000000
+
+#define RSB_CTRL_NAME			"sunxi-rsb"
+
+struct rsb {
+	struct rsb_controller *ctrl;
+	void __iomem *regs;
+	struct clk *clk;
+	struct reset_control *rstc;
+	struct completion complete;
+	unsigned int status;
+};
+
+static irqreturn_t rsb_interrupt(int irq, void *dev_id)
+{
+	struct rsb *rsb = dev_id;
+	u32 status;
+
+	/* Clear interrupts */
+	status = readl(rsb->regs + RSB_INTS);
+	rsb->status = status;
+	writel(status, rsb->regs + RSB_INTS);
+
+	complete(&rsb->complete);
+
+	return IRQ_HANDLED;
+}
+
+/* common code that starts a transfer */
+static int rsb_run_xfer(struct rsb *rsb)
+{
+	if (readl(rsb->regs + RSB_CTRL) & RSB_CTRL_START_TRANS) {
+		dev_dbg(&rsb->ctrl->dev, "RSB transfer still in progress\n");
+		return -EBUSY;
+	}
+
+	reinit_completion(&rsb->complete);
+
+	writel(RSB_INTS_LOAD_BSY | RSB_INTS_TRANS_ERR | RSB_INTS_TRANS_OVER,
+	       rsb->regs + RSB_INTE);
+	writel(RSB_CTRL_START_TRANS | RSB_CTRL_GLOBAL_INT_ENB,
+	       rsb->regs + RSB_CTRL);
+
+	if (!wait_for_completion_io_timeout(&rsb->complete,
+					    msecs_to_jiffies(100))) {
+		dev_dbg(&rsb->ctrl->dev, "RSB timeout\n");
+
+		/* abort the transfer */
+		writel(RSB_CTRL_ABORT_TRANS, rsb->regs + RSB_CTRL);
+
+		/* clear any interrupt flags */
+		writel(readl(rsb->regs + RSB_INTS), rsb->regs + RSB_INTS);
+
+		return -ETIMEDOUT;
+	}
+
+	if (rsb->status & RSB_INTS_LOAD_BSY) {
+		dev_dbg(&rsb->ctrl->dev, "RSB busy\n");
+		return -EBUSY;
+	}
+
+	if (rsb->status & RSB_INTS_TRANS_ERR_ACK) {
+		dev_dbg(&rsb->ctrl->dev, "RSB slave nack\n");
+		return -EINVAL;
+	}
+
+	if (rsb->status & RSB_INTS_TRANS_ERR_DATA) {
+		dev_dbg(&rsb->ctrl->dev, "RSB transfer data error\n");
+		return -EIO;
+	}
+
+	/* This should be covered by the above 2 cases */
+	if (rsb->status & RSB_INTS_TRANS_ERR) {
+		dev_dbg(&rsb->ctrl->dev, "bus transfer error\n");
+		return -EIO;
+	}
+
+	return 0;
+}
+
+static int rsb_read_cmd(struct rsb_controller *ctrl, u8 rtaddr,
+			u8 addr, u32 *buf, size_t len)
+{
+	struct rsb *rsb = rsb_controller_get_drvdata(ctrl);
+	u32 cmd;
+	int ret;
+
+	if (!buf)
+		return -EINVAL;
+
+	switch (len) {
+	case 1:
+		cmd = RSB_CMD_RD8;
+		break;
+	case 2:
+		cmd = RSB_CMD_RD16;
+		break;
+	case 4:
+		cmd = RSB_CMD_RD32;
+		break;
+	default:
+		dev_err(&ctrl->dev, "Invalid access width: %d", len);
+		return -EINVAL;
+	}
+
+	writel(addr, rsb->regs + RSB_ADDR);
+	writel(RSB_DAR_RTA(rtaddr), rsb->regs + RSB_DAR);
+	writel(cmd, rsb->regs + RSB_CMD);
+
+	ret = rsb_run_xfer(rsb);
+	if (ret)
+		return ret;
+
+	*buf = readl(rsb->regs + RSB_DATA);
+
+	return 0;
+}
+
+static int rsb_write_cmd(struct rsb_controller *ctrl, u8 rtaddr,
+			 u8 addr, const u32 *buf, size_t len)
+{
+	struct rsb *rsb = rsb_controller_get_drvdata(ctrl);
+	u32 cmd;
+
+	if (!buf)
+		return -EINVAL;
+
+	switch (len) {
+	case 1:
+		cmd = RSB_CMD_WR8;
+		break;
+	case 2:
+		cmd = RSB_CMD_WR16;
+		break;
+	case 4:
+		cmd = RSB_CMD_WR32;
+		break;
+	default:
+		dev_err(&ctrl->dev, "Invalid access width: %d", len);
+		return -EINVAL;
+	}
+
+	writel(addr, rsb->regs + RSB_ADDR);
+	writel(RSB_DAR_RTA(rtaddr), rsb->regs + RSB_DAR);
+	writel(*buf, rsb->regs + RSB_DATA);
+	writel(cmd, rsb->regs + RSB_CMD);
+
+	return rsb_run_xfer(rsb);
+}
+
+static int rsb_rtsaddr_cmd(struct rsb_controller *ctrl, u16 hwaddr, u8 rtaddr)
+{
+	struct rsb *rsb = rsb_controller_get_drvdata(ctrl);
+
+	/* setup command parameters */
+	writel(RSB_DAR_RTA(rtaddr) | RSB_DAR_DA(hwaddr), rsb->regs + RSB_DAR);
+	writel(RSB_CMD_STRA, rsb->regs + RSB_CMD);
+
+	/* send command */
+	return rsb_run_xfer(rsb);
+}
+
+static int rsb_init_cmd(struct rsb_controller *ctrl)
+{
+	struct rsb *rsb = rsb_controller_get_drvdata(ctrl);
+	int reg;
+
+	/* send init sequence */
+	writel(RSB_DMCR_DEVICE_START | RSB_DMCR_MODE_DATA |
+	       RSB_DMCR_MODE_REG | RSB_DMCR_DEV_ADDR, rsb->regs + RSB_DMCR);
+
+	readl_poll_timeout(rsb->regs + RSB_DMCR, reg,
+			   !(reg & RSB_DMCR_DEVICE_START), 100, 250000);
+	if (reg & RSB_DMCR_DEVICE_START)
+		dev_warn(&ctrl->dev, "send init sequence timeout\n");
+
+	/* clear any interrupt flags */
+	writel(readl(rsb->regs + RSB_INTS), rsb->regs + RSB_INTS);
+
+	return 0;
+}
+
+static const struct of_device_id rsb_of_match_table[] = {
+	{ .compatible = "allwinner,sun8i-a23-rsb" },
+	{}
+};
+MODULE_DEVICE_TABLE(of, rsb_of_match_table);
+
+static int rsb_probe(struct platform_device *pdev)
+{
+	struct device *dev = &pdev->dev;
+	struct device_node *np = dev->of_node;
+	struct resource *r;
+	struct rsb_controller *ctrl;
+	struct rsb *rsb;
+	unsigned long parent_clk_freq;
+	u32 clk_freq = 100000;
+	int clk_div;
+	int irq;
+	int ret;
+	u32 reg;
+
+	of_property_read_u32(np, "clock-frequency", &clk_freq);
+	if (clk_freq > RSB_MAX_FREQ) {
+		dev_err(dev,
+			"clock-frequency (%u Hz) is too high (max = 20MHz)",
+			clk_freq);
+		return -EINVAL;
+	}
+
+	ctrl = rsb_controller_alloc(dev, sizeof(*rsb));
+	if (!ctrl)
+		return -ENOMEM;
+
+	platform_set_drvdata(pdev, ctrl);
+
+	/* set callbacks */
+	ctrl->init_cmd = rsb_init_cmd;
+	ctrl->rtsaddr_cmd = rsb_rtsaddr_cmd;
+	ctrl->read_cmd = rsb_read_cmd;
+	ctrl->write_cmd = rsb_write_cmd;
+
+	rsb = rsb_controller_get_drvdata(ctrl);
+	rsb->ctrl = ctrl;
+
+	r = platform_get_resource(pdev, IORESOURCE_MEM, 0);
+	rsb->regs = devm_ioremap_resource(dev, r);
+	if (IS_ERR(rsb->regs)) {
+		ret = PTR_ERR(rsb->regs);
+		goto err_rsb_controller_put;
+	}
+
+	irq = platform_get_irq(pdev, 0);
+	if (irq < 0) {
+		dev_err(dev, "failed to retrieve irq: %d\n", irq);
+		ret = irq;
+		goto err_rsb_controller_put;
+	}
+
+	rsb->clk = devm_clk_get(dev, NULL);
+	if (IS_ERR(rsb->clk)) {
+		ret = PTR_ERR(rsb->clk);
+		dev_err(dev, "failed to retrieve clk: %d\n", ret);
+		goto err_rsb_controller_put;
+	}
+
+	ret = clk_prepare_enable(rsb->clk);
+	if (ret) {
+		dev_err(dev, "failed to enable clk: %d\n", ret);
+		goto err_rsb_controller_put;
+	}
+
+	parent_clk_freq = clk_get_rate(rsb->clk);
+
+	rsb->rstc = devm_reset_control_get(dev, NULL);
+	if (IS_ERR(rsb->rstc)) {
+		ret = PTR_ERR(rsb->rstc);
+		dev_err(dev, "failed to retrieve reset controller: %d\n", ret);
+		goto err_clk_disable;
+	}
+
+	ret = reset_control_deassert(rsb->rstc);
+	if (ret) {
+		dev_err(dev, "failed to deassert reset line: %d\n", ret);
+		goto err_clk_disable;
+	}
+
+	init_completion(&rsb->complete);
+
+	/* reset the controller */
+	writel(RSB_CTRL_SOFT_RST, rsb->regs + RSB_CTRL);
+	readl_poll_timeout(rsb->regs + RSB_CTRL, reg,
+			   !(reg & RSB_CTRL_SOFT_RST), 1000, 100000);
+
+	clk_div = parent_clk_freq / clk_freq;
+	if (!clk_div) {
+		dev_warn(dev,
+			 "clock-frequency is too high, setting it to %lu Hz\n",
+			 parent_clk_freq);
+		clk_div = 1;
+	} else if (clk_div > RSB_CCR_MAX_CLK_DIV + 1) {
+		dev_warn(dev,
+			 "clock-frequency is too low, setting it to %lu Hz\n",
+			 parent_clk_freq / (RSB_CCR_MAX_CLK_DIV + 1));
+		clk_div = RSB_CCR_MAX_CLK_DIV + 1;
+	}
+
+	writel(RSB_CCR_SDA_OUT_DELAY(1) | RSB_CCR_CLK_DIV(clk_div - 1),
+	       rsb->regs + RSB_CCR);
+
+	ret = devm_request_irq(dev, irq, rsb_interrupt, 0, RSB_CTRL_NAME, rsb);
+	if (ret) {
+		dev_err(dev, "can't register interrupt handler irq%d: %d\n",
+			irq, ret);
+		goto err_reset_assert;
+	}
+
+	ret = rsb_controller_add(ctrl);
+	if (!ret)
+		return 0;
+
+err_reset_assert:
+	reset_control_assert(rsb->rstc);
+
+err_clk_disable:
+	clk_disable_unprepare(rsb->clk);
+
+err_rsb_controller_put:
+	rsb_controller_put(ctrl);
+
+	return ret;
+}
+
+static int rsb_remove(struct platform_device *pdev)
+{
+	struct rsb_controller *ctrl = platform_get_drvdata(pdev);
+	struct rsb *rsb = rsb_controller_get_drvdata(ctrl);
+
+	rsb_controller_remove(ctrl);
+	reset_control_assert(rsb->rstc);
+	clk_disable_unprepare(rsb->clk);
+
+	return 0;
+}
+
+static struct platform_driver rsb_driver = {
+	.probe = rsb_probe,
+	.remove	= rsb_remove,
+	.driver	= {
+		.name = "rsb-sunxi",
+		.of_match_table = rsb_of_match_table,
+	},
+};
+module_platform_driver(rsb_driver);
+
+MODULE_AUTHOR("Chen-Yu Tsai <wens at csie.org>");
+MODULE_DESCRIPTION("Allwinner RSB driver");
+MODULE_LICENSE("GPL v2");
-- 
2.5.0



From wens at csie.org  Tue Aug 18 21:20:04 2015
From: wens at csie.org (Chen-Yu Tsai)
Date: Wed, 19 Aug 2015 12:20:04 +0800
Subject: [PATCH v3 3/8] rsb: Linux driver framework for Reduced Serial Bus
 (RSB)
In-Reply-To: <1439958009-14056-1-git-send-email-wens@csie.org>
References: <1439958009-14056-1-git-send-email-wens@csie.org>
Message-ID: <1439958009-14056-4-git-send-email-wens@csie.org>

Reduced Serial Bus (RSB) is an Allwinner proprietery interface
used to communicate with PMICs and other peripheral ICs.

RSB is a two-wire push-pull serial bus that supports 1 master
device and up to 15 active slave devices.

Signed-off-by: Chen-Yu Tsai <wens at csie.org>
---
 drivers/Kconfig        |   2 +
 drivers/Makefile       |   1 +
 drivers/rsb/Kconfig    |  11 ++
 drivers/rsb/Makefile   |   4 +
 drivers/rsb/rsb-core.c | 511 +++++++++++++++++++++++++++++++++++++++++++++++++
 include/linux/rsb.h    | 144 ++++++++++++++
 6 files changed, 673 insertions(+)
 create mode 100644 drivers/rsb/Kconfig
 create mode 100644 drivers/rsb/Makefile
 create mode 100644 drivers/rsb/rsb-core.c
 create mode 100644 include/linux/rsb.h

diff --git a/drivers/Kconfig b/drivers/Kconfig
index 6e973b8e3a3b..4ada2d3eb832 100644
--- a/drivers/Kconfig
+++ b/drivers/Kconfig
@@ -54,6 +54,8 @@ source "drivers/spi/Kconfig"
 
 source "drivers/spmi/Kconfig"
 
+source "drivers/rsb/Kconfig"
+
 source "drivers/hsi/Kconfig"
 
 source "drivers/pps/Kconfig"
diff --git a/drivers/Makefile b/drivers/Makefile
index e4b260ecec15..75e0fc8fe28c 100644
--- a/drivers/Makefile
+++ b/drivers/Makefile
@@ -75,6 +75,7 @@ obj-$(CONFIG_TARGET_CORE)	+= target/
 obj-$(CONFIG_MTD)		+= mtd/
 obj-$(CONFIG_SPI)		+= spi/
 obj-$(CONFIG_SPMI)		+= spmi/
+obj-$(CONFIG_RSB)		+= rsb/
 obj-y				+= hsi/
 obj-y				+= net/
 obj-$(CONFIG_ATM)		+= atm/
diff --git a/drivers/rsb/Kconfig b/drivers/rsb/Kconfig
new file mode 100644
index 000000000000..6642e1db6d98
--- /dev/null
+++ b/drivers/rsb/Kconfig
@@ -0,0 +1,11 @@
+#
+# RSB driver configuration
+#
+menuconfig RSB
+	tristate "RSB support"
+	help
+	  RSB (Reduced Serial Bus) is a two-wire serial interface between
+	  baseband and application processors and Power Management
+	  Integrated Circuits (PMIC) or other peripherals.
+
+	  These are commonly seen on newer Allwinner SoCs and X-Powers ICs.
diff --git a/drivers/rsb/Makefile b/drivers/rsb/Makefile
new file mode 100644
index 000000000000..6fe56526fbf3
--- /dev/null
+++ b/drivers/rsb/Makefile
@@ -0,0 +1,4 @@
+#
+# Makefile for kernel RSB framework.
+#
+obj-$(CONFIG_RSB)	+= rsb-core.o
diff --git a/drivers/rsb/rsb-core.c b/drivers/rsb/rsb-core.c
new file mode 100644
index 000000000000..6682d827aebb
--- /dev/null
+++ b/drivers/rsb/rsb-core.c
@@ -0,0 +1,511 @@
+/*
+ * Copyright (c) 2015, Chen-Yu Tsai
+ *
+ * Chen-Yu Tsai <wens at csie.org>
+ *
+ * Allwinner Reduced Serial Bus (RSB) driver
+ *
+ * based on spmi/spmi.c
+ *
+ * Copyright (c) 2012-2015, The Linux Foundation. All rights reserved.
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License version 2 and
+ * only 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/clk/clk-conf.h>
+#include <linux/kernel.h>
+#include <linux/errno.h>
+#include <linux/idr.h>
+#include <linux/module.h>
+#include <linux/of.h>
+#include <linux/of_device.h>
+#include <linux/of_irq.h>
+#include <linux/platform_device.h>
+#include <linux/rsb.h>
+#include <linux/slab.h>
+
+static DEFINE_IDA(ctrl_ida);
+
+static void rsb_dev_release(struct device *dev)
+{
+	struct rsb_device *rdev = to_rsb_device(dev);
+
+	kfree(rdev);
+}
+
+static const struct device_type rsb_dev_type = {
+	.release	= rsb_dev_release,
+};
+
+static void rsb_ctrl_release(struct device *dev)
+{
+	struct rsb_controller *ctrl = to_rsb_controller(dev);
+
+	ida_simple_remove(&ctrl_ida, ctrl->nr);
+	kfree(ctrl);
+}
+
+static const struct device_type rsb_ctrl_type = {
+	.release	= rsb_ctrl_release,
+};
+
+static int rsb_device_match(struct device *dev, struct device_driver *drv)
+{
+	if (of_driver_match_device(dev, drv))
+		return 1;
+
+	return strcmp(dev_name(dev), drv->name) == 0;
+}
+
+static inline int rsb_init_cmd(struct rsb_controller *ctrl)
+{
+	int ret;
+
+	if (!ctrl || !ctrl->init_cmd || ctrl->dev.type != &rsb_ctrl_type)
+		return -EINVAL;
+
+	mutex_lock(&ctrl->lock);
+	ret = ctrl->init_cmd(ctrl);
+	mutex_unlock(&ctrl->lock);
+
+	return ret;
+}
+
+static inline int rsb_rtsaddr_cmd(struct rsb_controller *ctrl, u16 hwaddr,
+				  u8 rtaddr)
+{
+	int ret;
+
+	if (!ctrl || !ctrl->rtsaddr_cmd || ctrl->dev.type != &rsb_ctrl_type)
+		return -EINVAL;
+
+	mutex_lock(&ctrl->lock);
+	ret = ctrl->rtsaddr_cmd(ctrl, hwaddr, rtaddr);
+	mutex_unlock(&ctrl->lock);
+
+	return ret;
+}
+
+static inline int rsb_read_cmd(struct rsb_controller *ctrl, u8 rtaddr,
+			       u8 addr, u32 *buf, size_t len)
+{
+	int ret;
+
+	if (!ctrl || !ctrl->read_cmd || ctrl->dev.type != &rsb_ctrl_type)
+		return -EINVAL;
+
+	mutex_lock(&ctrl->lock);
+	ret = ctrl->read_cmd(ctrl, rtaddr, addr, buf, len);
+	mutex_unlock(&ctrl->lock);
+
+	return ret;
+}
+
+static inline int rsb_write_cmd(struct rsb_controller *ctrl, u8 rtaddr,
+				u8 addr, const u32 *buf, size_t len)
+{
+	int ret;
+
+	if (!ctrl || !ctrl->write_cmd || ctrl->dev.type != &rsb_ctrl_type)
+		return -EINVAL;
+
+	mutex_lock(&ctrl->lock);
+	ret = ctrl->write_cmd(ctrl, rtaddr, addr, buf, len);
+	mutex_unlock(&ctrl->lock);
+
+	return ret;
+}
+
+/**
+ * rsb_register_read() - register read
+ * @rdev:	RSB device.
+ * @addr:	slave register address.
+ * @buf:	buffer to be populated with data from the Slave.
+ * @size:	width of the slave register in bytes
+ *
+ * Reads data from a Slave device register.
+ */
+int rsb_register_read(struct rsb_device *rdev, u8 addr, u32 *buf, int size)
+{
+	switch (size) {
+	case 1:
+	case 2:
+	case 4:
+		break;
+	default:
+		return -EINVAL;
+	}
+
+	return rsb_read_cmd(rdev->ctrl, rdev->rtaddr, addr, buf, size);
+}
+EXPORT_SYMBOL_GPL(rsb_register_read);
+
+/**
+ * rsb_register_write() - register write
+ * @rdev:	RSB device
+ * @addr:	slave register address.
+ * @data:	buffer containing the data to be transferred to the Slave.
+ * @size:	width of the slave register in bytes
+ *
+ * Writes data to a Slave device register.
+ */
+int rsb_register_write(struct rsb_device *rdev, u8 addr, u32 data, int size)
+{
+	switch (size) {
+	case 1:
+	case 2:
+	case 4:
+		break;
+	default:
+		return -EINVAL;
+	}
+
+	return rsb_write_cmd(rdev->ctrl, rdev->rtaddr, addr, &data, size);
+}
+EXPORT_SYMBOL_GPL(rsb_register_write);
+
+static struct bus_type rsb_bus_type;
+
+static int rsb_device_probe(struct device *dev)
+{
+	const struct rsb_driver *drv = to_rsb_driver(dev->driver);
+	struct rsb_device *rsb = to_rsb_device(dev);
+	int ret;
+
+	if (dev->type != &rsb_dev_type)
+		return 0;
+
+	if (!drv->probe)
+		return -ENODEV;
+
+	if (!rsb->irq) {
+		int irq = -ENOENT;
+
+		if (dev->of_node)
+			irq = of_irq_get(dev->of_node, 0);
+
+		if (irq == -EPROBE_DEFER)
+			return irq;
+		if (irq < 0)
+			irq = 0;
+
+		rsb->irq = irq;
+	}
+
+	ret = of_clk_set_defaults(dev->of_node, false);
+	if (ret < 0)
+		return ret;
+
+	return drv->probe(rsb);
+}
+
+static int rsb_device_remove(struct device *dev)
+{
+	const struct rsb_driver *drv = to_rsb_driver(dev->driver);
+
+	if (dev->type != &rsb_dev_type)
+		return 0;
+
+	return drv->remove(to_rsb_device(dev));
+}
+
+static struct bus_type rsb_bus_type = {
+	.name		= "rsb",
+	.match		= rsb_device_match,
+	.probe		= rsb_device_probe,
+	.remove		= rsb_device_remove,
+};
+
+/**
+ * rsb_device_alloc() - Allocate a new RSB device
+ * @ctrl:	associated controller
+ *
+ * Caller is responsible for either calling rsb_device_add() to add the
+ * newly allocated controller, or calling rsb_device_put() to discard it.
+ */
+static struct rsb_device *rsb_device_alloc(struct rsb_controller *ctrl)
+{
+	struct rsb_device *rdev;
+
+	rdev = kzalloc(sizeof(*rdev), GFP_KERNEL);
+	if (!rdev)
+		return NULL;
+
+	rdev->ctrl = ctrl;
+	device_initialize(&rdev->dev);
+	rdev->dev.parent = &ctrl->dev;
+	rdev->dev.bus = &rsb_bus_type;
+	rdev->dev.type = &rsb_dev_type;
+	return rdev;
+}
+
+static inline void rsb_device_put(struct rsb_device *rdev)
+{
+	if (rdev)
+		put_device(&rdev->dev);
+}
+
+/* 15 valid runtime addresses for RSB slaves */
+static const u8 rsb_valid_rtaddr[] = {
+	0x17, 0x2d, 0x3a, 0x4e, 0x59, 0x63, 0x74, 0x8b,
+	0x9c, 0xa6, 0xb1, 0xc5, 0xd2, 0xe8, 0xff,
+};
+
+static inline int rsb_check_rt_addr(u8 addr)
+{
+	int i;
+
+	for (i = 0; i < ARRAY_SIZE(rsb_valid_rtaddr); i++)
+		if (addr == rsb_valid_rtaddr[i])
+			return 0;
+
+	return -EINVAL;
+}
+
+/**
+ * rsb_device_add() - add a device previously constructed via rsb_device_alloc()
+ * @rdev:	rsb_device to be added
+ */
+static int rsb_device_add(struct rsb_device *rdev)
+{
+	struct rsb_controller *ctrl = rdev->ctrl;
+	int err;
+
+	dev_set_name(&rdev->dev, "%d-%02x", ctrl->nr, rdev->rtaddr);
+
+	err = device_add(&rdev->dev);
+	if (err < 0) {
+		dev_err(&rdev->dev, "Can't add %s, status %d\n",
+			dev_name(&rdev->dev), err);
+		goto err_device_add;
+	}
+
+	dev_dbg(&rdev->dev, "device %s registered\n", dev_name(&rdev->dev));
+
+err_device_add:
+	return err;
+}
+
+/**
+ * rsb_device_unregister(): unregister an RSB device
+ * @rdev:	rsb_device to be removed
+ */
+static void rsb_device_unregister(struct rsb_device *rdev)
+{
+	device_unregister(&rdev->dev);
+}
+
+/**
+ * rsb_controller_alloc() - Allocate a new RSB controller
+ * @parent:	parent device
+ * @size:	size of private data
+ *
+ * Caller is responsible for either calling rsb_controller_add() to add the
+ * newly allocated controller, or calling rsb_controller_put() to discard it.
+ * The allocated private data region may be accessed via
+ * rsb_controller_get_drvdata()
+ */
+struct rsb_controller *rsb_controller_alloc(struct device *parent, size_t size)
+{
+	struct rsb_controller *ctrl;
+	int id;
+
+	if (WARN_ON(!parent))
+		return NULL;
+
+	ctrl = kzalloc(sizeof(*ctrl) + size, GFP_KERNEL);
+	if (!ctrl)
+		return NULL;
+
+	device_initialize(&ctrl->dev);
+	mutex_init(&ctrl->lock);
+	ctrl->dev.type = &rsb_ctrl_type;
+	ctrl->dev.bus = &rsb_bus_type;
+	ctrl->dev.parent = parent;
+	ctrl->dev.of_node = parent->of_node;
+	rsb_controller_set_drvdata(ctrl, &ctrl[1]);
+
+	id = ida_simple_get(&ctrl_ida, 0, 0, GFP_KERNEL);
+	if (id < 0) {
+		dev_err(parent,
+			"unable to allocate RSB controller identifier.\n");
+		rsb_controller_put(ctrl);
+		return NULL;
+	}
+
+	ctrl->nr = id;
+	dev_set_name(&ctrl->dev, "rsb-%d", id);
+	dev_dbg(&ctrl->dev, "allocated controller 0x%p id %d\n", ctrl, id);
+
+	return ctrl;
+}
+EXPORT_SYMBOL_GPL(rsb_controller_alloc);
+
+static void of_rsb_register_devices(struct rsb_controller *ctrl)
+{
+	struct device_node *node;
+	int err;
+	u32 reg[2];
+
+	if (!ctrl->dev.of_node)
+		return;
+
+	/* Runtime addresses for all slaves should be set first */
+	for_each_available_child_of_node(ctrl->dev.of_node, node) {
+		dev_dbg(&ctrl->dev, "setting child %s runtime address\n",
+			node->full_name);
+
+		err = of_property_read_u32_array(node, "reg", reg, 2);
+		if (err) {
+			dev_err(&ctrl->dev,
+				"node %s err (%d) does not have 'reg' property\n",
+				node->full_name, err);
+			continue;
+		}
+
+		if (reg[0] > 0xff || rsb_check_rt_addr(reg[0]) < 0) {
+			dev_err(&ctrl->dev,
+				"invalid runtime address on node %s\n",
+				node->full_name);
+			continue;
+		}
+
+		/* This fails if the slave device was already initialized */
+		err = rsb_rtsaddr_cmd(ctrl, (u16)reg[1], (u8)reg[0]);
+		if (err)
+			dev_info(&ctrl->dev,
+				 "failed to set runtime address: %d\n", err);
+	}
+
+	for_each_available_child_of_node(ctrl->dev.of_node, node) {
+		struct rsb_device *rdev;
+
+		dev_dbg(&ctrl->dev, "adding child %s\n", node->full_name);
+
+		err = of_property_read_u32_array(node, "reg", reg, 2);
+		if (err)
+			continue;
+
+		if (reg[0] > 0xff || rsb_check_rt_addr(reg[0]) < 0)
+			continue;
+
+		rdev = rsb_device_alloc(ctrl);
+		if (!rdev)
+			continue;
+
+		rdev->dev.of_node = node;
+		rdev->rtaddr = (u8)reg[0];
+		rdev->hwaddr = (u16)reg[1];
+
+		err = rsb_device_add(rdev);
+		if (err) {
+			dev_err(&rdev->dev, "failed to add device: %d\n", err);
+			rsb_device_put(rdev);
+		}
+	}
+}
+
+/**
+ * rsb_controller_add() - Add an RSB controller
+ * @ctrl:	controller to be registered.
+ *
+ * Register a controller previously allocated via rsb_controller_alloc() with
+ * the RSB core.
+ */
+int rsb_controller_add(struct rsb_controller *ctrl)
+{
+	int ret;
+
+	/* Can't register until after driver model init */
+	if (WARN_ON(!rsb_bus_type.p))
+		return -EAGAIN;
+
+	ret = device_add(&ctrl->dev);
+	if (ret)
+		return ret;
+
+	/*
+	 * Send RSB init sequence on the bus. This fails if the bus was
+	 * already initialized.
+	 */
+	ret = rsb_init_cmd(ctrl);
+	if (ret)
+		dev_info(&ctrl->dev, "RSB init sequence failed: %d\n", ret);
+
+	if (IS_ENABLED(CONFIG_OF))
+		of_rsb_register_devices(ctrl);
+
+	dev_dbg(&ctrl->dev, "rsb-%d registered: dev:%p\n",
+		ctrl->nr, &ctrl->dev);
+
+	return 0;
+};
+EXPORT_SYMBOL_GPL(rsb_controller_add);
+
+/* Remove a device associated with a controller */
+static int rsb_ctrl_remove_device(struct device *dev, void *data)
+{
+	struct rsb_device *rsb = to_rsb_device(dev);
+
+	if (dev->type == &rsb_dev_type)
+		rsb_device_unregister(rsb);
+	return 0;
+}
+
+/**
+ * rsb_controller_remove(): remove an RSB controller
+ * @ctrl:	controller to remove
+ *
+ * Remove a RSB controller.  Caller is responsible for calling
+ * rsb_controller_put() to discard the allocated controller.
+ */
+void rsb_controller_remove(struct rsb_controller *ctrl)
+{
+	int dummy;
+
+	if (!ctrl)
+		return;
+
+	dummy = device_for_each_child(&ctrl->dev, NULL,
+				      rsb_ctrl_remove_device);
+	mutex_destroy(&ctrl->lock);
+	device_del(&ctrl->dev);
+}
+EXPORT_SYMBOL_GPL(rsb_controller_remove);
+
+/**
+ * rsb_driver_register() - Register device driver with RSB core
+ * @rdrv:	device driver to be associated with slave-device.
+ *
+ * This API will register the client driver with the RSB framework.
+ * It is typically called from the driver's module-init function.
+ */
+int rsb_driver_register(struct rsb_driver *rdrv)
+{
+	rdrv->driver.bus = &rsb_bus_type;
+	return driver_register(&rdrv->driver);
+}
+EXPORT_SYMBOL_GPL(rsb_driver_register);
+
+static void __exit rsb_exit(void)
+{
+	bus_unregister(&rsb_bus_type);
+}
+module_exit(rsb_exit);
+
+static int __init rsb_init(void)
+{
+	return bus_register(&rsb_bus_type);
+}
+postcore_initcall(rsb_init);
+
+MODULE_LICENSE("GPL v2");
+MODULE_DESCRIPTION("Reduce Serial Bus (RSB) core module");
+MODULE_ALIAS("platform:rsb");
diff --git a/include/linux/rsb.h b/include/linux/rsb.h
new file mode 100644
index 000000000000..51a53468f547
--- /dev/null
+++ b/include/linux/rsb.h
@@ -0,0 +1,144 @@
+/* Copyright (c) 2012-2013, The Linux Foundation. All rights reserved.
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License version 2 and
+ * only 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.
+ */
+#ifndef _LINUX_RSB_H
+#define _LINUX_RSB_H
+
+#include <linux/device.h>
+#include <linux/mod_devicetable.h>
+#include <linux/mutex.h>
+#include <linux/types.h>
+
+/**
+ * struct rsb_device - Basic representation of an RSB device
+ * @dev:	Driver model representation of the device.
+ * @ctrl:	RSB controller managing the bus hosting this device.
+ * @rtaddr:	This device's runtime address
+ * @hwaddr:	This device's hardware address
+ */
+struct rsb_device {
+	struct device		dev;
+	struct rsb_controller	*ctrl;
+	int			irq;
+	u8			rtaddr;
+	u16			hwaddr;
+};
+
+static inline struct rsb_device *to_rsb_device(struct device *d)
+{
+	return container_of(d, struct rsb_device, dev);
+}
+
+static inline void *rsb_device_get_drvdata(const struct rsb_device *rdev)
+{
+	return dev_get_drvdata(&rdev->dev);
+}
+
+static inline void rsb_device_set_drvdata(struct rsb_device *rdev, void *data)
+{
+	dev_set_drvdata(&rdev->dev, data);
+}
+
+/**
+ * struct rsb_controller - interface to the RSB master controller
+ * @dev:	Driver model representation of the device.
+ * @nr:		board-specific number identifier for this controller/bus
+ * @init_cmd:	sends a device initialization command sequence on the bus.
+ * @rtsaddr_cmd: sends a "set runtime address" command sequence on the bus.
+ * @read_cmd:	sends a register read command sequence on the RSB bus.
+ * @write_cmd:	sends a register write command sequence on the RSB bus.
+ */
+struct rsb_controller {
+	struct device		dev;
+	unsigned int		nr;
+	struct mutex		lock; /* serialize access to the bus */
+	int	(*init_cmd)(struct rsb_controller *ctrl);
+	int	(*rtsaddr_cmd)(struct rsb_controller *ctrl,
+			       u16 hwaddr, u8 rtaddr);
+	int	(*read_cmd)(struct rsb_controller *ctrl, u8 rtaddr,
+			    u8 addr, u32 *buf, size_t len);
+	int	(*write_cmd)(struct rsb_controller *ctrl, u8 rtaddr,
+			     u8 addr, const u32 *buf, size_t len);
+};
+
+static inline struct rsb_controller *to_rsb_controller(struct device *d)
+{
+	return container_of(d, struct rsb_controller, dev);
+}
+
+static inline
+void *rsb_controller_get_drvdata(const struct rsb_controller *ctrl)
+{
+	return dev_get_drvdata(&ctrl->dev);
+}
+
+static inline void rsb_controller_set_drvdata(struct rsb_controller *ctrl,
+					      void *data)
+{
+	dev_set_drvdata(&ctrl->dev, data);
+}
+
+struct rsb_controller *rsb_controller_alloc(struct device *parent,
+					    size_t size);
+
+/**
+ * rsb_controller_put() - decrement controller refcount
+ * @ctrl	RSB controller.
+ */
+static inline void rsb_controller_put(struct rsb_controller *ctrl)
+{
+	if (ctrl) {
+		mutex_destroy(&ctrl->lock);
+		put_device(&ctrl->dev);
+	}
+}
+
+int rsb_controller_add(struct rsb_controller *ctrl);
+void rsb_controller_remove(struct rsb_controller *ctrl);
+
+/**
+ * struct rsb_driver - RSB slave device driver
+ * @driver:	RSB device drivers should initialize name and owner field of
+ *		this structure.
+ * @probe:	binds this driver to a RSB device.
+ * @remove:	unbinds this driver from the RSB device.
+ */
+struct rsb_driver {
+	struct device_driver driver;
+	int (*probe)(struct rsb_device *rdev);
+	int (*remove)(struct rsb_device *rdev);
+};
+
+static inline struct rsb_driver *to_rsb_driver(struct device_driver *d)
+{
+	return container_of(d, struct rsb_driver, driver);
+}
+
+int rsb_driver_register(struct rsb_driver *rdrv);
+
+/**
+ * rsb_driver_unregister() - unregister an RSB client driver
+ * @rdrv:	the driver to unregister
+ */
+static inline void rsb_driver_unregister(struct rsb_driver *rdrv)
+{
+	if (rdrv)
+		driver_unregister(&rdrv->driver);
+}
+
+#define module_rsb_driver(__rsb_driver) \
+	module_driver(__rsb_driver, rsb_driver_register, \
+			rsb_driver_unregister)
+
+int rsb_register_read(struct rsb_device *rdev, u8 addr, u32 *buf, int size);
+int rsb_register_write(struct rsb_device *rdev, u8 addr, u32 data, int size);
+
+#endif
-- 
2.5.0



From wens at csie.org  Tue Aug 18 21:20:01 2015
From: wens at csie.org (Chen-Yu Tsai)
Date: Wed, 19 Aug 2015 12:20:01 +0800
Subject: [PATCH v3 0/8] ARM: sunxi: Add Reduced Serial Bus support
Message-ID: <1439958009-14056-1-git-send-email-wens@csie.org>

Hi everyone,

This is my third attempt at adding support for Allwinner's Reduced
Serial Bus (RSB), which is used to communicate with PMICs and other
peripherals on their newer SoCs, such as the A23/A33/A80.

RSB is a simplified two wire interface using push-pull outputs,
supporting multiple slaves, address and data parity checks, and
clock speeds up to 20 MHz. The bus only supports simple register
read/writes, with possible register sizes of 8/16/32 bits. Access
sizes not matching the slave device register sizes result in NACKs
or errors. 32 bit registers in devices have yet to be seen.

Previous attempts to add support through the I2C subsystem have
been rejected, as the bus line protocol is too different to even
consider. In this version, RSB is implemented as a new bus type,
much like SPMI.

Even though there will almost certainly be only one RSB driver,
it's still split into the bus core framework and vendor specific
driver, like other subsystems. Theoretically someone could
implement a bit-banging driver for it.


Patches 1 & 2 add the DT bindings for common RSB properties and
the controller.

Patches 3 & 4 add the RSB framework core and sunxi driver.

Patch 5 (based on regmap/for-next) adds an RSB regmap driver.

Patch 6 adds the RSB nodes for A23/A33 dtsi.

Patch 7 & 8 enable the RSB controller on the boards I have.


Still to come are axp20x driver support for the RSB based AXP223.
The complete series can be found at:

    https://github.com/wens/linux/tree/sunxi-rsb-v3

Since this is a new subsystem, I'm not sure who should pick up
the first 4 patches, or whether they are even in the right place.
Any suggestions?


Regards,
ChenYu


Chen-Yu Tsai (8):
  rsb: Add generic Reduced Serial Bus (RSB) controller binding
    documentation
  rsb: sunxi: Add Allwinner Reduced Serial Bus (RSB) controller bindings
  rsb: Linux driver framework for Reduced Serial Bus (RSB)
  rsb: sunxi: Add driver for Allwinner Reduced Serial Bus controller
  regmap: rsb: Add support for Reduced Serial Bus (RSB) based regmaps
  ARM: dts: sun8i: Add Reduced Serial Bus controller device node to
    A23/A33 dtsi
  ARM: dts: sun8i: ippo-q8h-v5: Enable Reduced Serial Bus controller
  ARM: dts: sun8i: sinlinx-sina33: Enable Reduced Serial Bus controller

 .../devicetree/bindings/rsb/rsb-sunxi.txt          |  34 ++
 Documentation/devicetree/bindings/rsb/rsb.txt      |  50 ++
 arch/arm/boot/dts/sun8i-a23-a33.dtsi               |  21 +
 arch/arm/boot/dts/sun8i-a23-ippo-q8h-v5.dts        |   4 +
 arch/arm/boot/dts/sun8i-a33-sinlinx-sina33.dts     |   4 +
 drivers/Kconfig                                    |   2 +
 drivers/Makefile                                   |   1 +
 drivers/base/regmap/Kconfig                        |   6 +-
 drivers/base/regmap/Makefile                       |   1 +
 drivers/base/regmap/regmap-rsb.c                   | 121 +++++
 drivers/rsb/Kconfig                                |  26 ++
 drivers/rsb/Makefile                               |   6 +
 drivers/rsb/rsb-core.c                             | 511 +++++++++++++++++++++
 drivers/rsb/rsb-sunxi.c                            | 441 ++++++++++++++++++
 include/linux/regmap.h                             |  36 ++
 include/linux/rsb.h                                | 144 ++++++
 16 files changed, 1407 insertions(+), 1 deletion(-)
 create mode 100644 Documentation/devicetree/bindings/rsb/rsb-sunxi.txt
 create mode 100644 Documentation/devicetree/bindings/rsb/rsb.txt
 create mode 100644 drivers/base/regmap/regmap-rsb.c
 create mode 100644 drivers/rsb/Kconfig
 create mode 100644 drivers/rsb/Makefile
 create mode 100644 drivers/rsb/rsb-core.c
 create mode 100644 drivers/rsb/rsb-sunxi.c
 create mode 100644 include/linux/rsb.h

-- 
2.5.0



From wens at csie.org  Tue Aug 18 21:20:03 2015
From: wens at csie.org (Chen-Yu Tsai)
Date: Wed, 19 Aug 2015 12:20:03 +0800
Subject: [PATCH v3 2/8] rsb: sunxi: Add Allwinner Reduced Serial Bus (RSB)
 controller bindings
In-Reply-To: <1439958009-14056-1-git-send-email-wens@csie.org>
References: <1439958009-14056-1-git-send-email-wens@csie.org>
Message-ID: <1439958009-14056-3-git-send-email-wens@csie.org>

Recent Allwinner SoCs, starting with the A23, have a Reduced Serial Bus
(RSB) controller. This is used to talk to the PMIC, and later with the
A80 and A83 platform, the audio codec IC.

Signed-off-by: Chen-Yu Tsai <wens at csie.org>
---
 .../devicetree/bindings/rsb/rsb-sunxi.txt          | 34 ++++++++++++++++++++++
 1 file changed, 34 insertions(+)
 create mode 100644 Documentation/devicetree/bindings/rsb/rsb-sunxi.txt

diff --git a/Documentation/devicetree/bindings/rsb/rsb-sunxi.txt b/Documentation/devicetree/bindings/rsb/rsb-sunxi.txt
new file mode 100644
index 000000000000..057d24b84628
--- /dev/null
+++ b/Documentation/devicetree/bindings/rsb/rsb-sunxi.txt
@@ -0,0 +1,34 @@
+
+* Allwinner RSB (Reduced Serial Bus) controller
+
+Required properties :
+
+ - reg             : Offset and length of the register set for the controller.
+ - compatible      : Shall be "allwinner,sun8i-a23-rsb".
+ - interrupts      : The interrupt line associated to the RSB controller.
+ - clocks          : The gate clk associated to the RSB controller.
+ - resets          : The reset line associated to the RSB controller.
+ - #address-cells  : shall be 2
+ - #size-cells     : shall be 0
+
+Optional properties :
+
+ - clock-frequency : Desired RSB bus clock frequency in Hz. Maximum is 20MHz.
+		     If not set the current hardware setting shall be used.
+
+See rsb.txt for the generic RSB bindings for RSB slaves / child nodes.
+
+Example:
+
+	rsb at 01f03400 {
+		compatible = "allwinner,sun8i-a23-rsb";
+		reg = <0x01f03400 0x400>;
+		interrupts = <0 39 4>;
+		clocks = <&apb0_gates 3>;
+		clock-frequency = <3000000>;
+		resets = <&apb0_rst 3>;
+		#address-cells = <2>;
+		#size-cells = <0>;
+
+		/* child nodes ... */
+	};
-- 
2.5.0



From wens at csie.org  Tue Aug 18 21:20:09 2015
From: wens at csie.org (Chen-Yu Tsai)
Date: Wed, 19 Aug 2015 12:20:09 +0800
Subject: [PATCH v3 8/8] ARM: dts: sun8i: sinlinx-sina33: Enable Reduced Serial
 Bus controller
In-Reply-To: <1439958009-14056-1-git-send-email-wens@csie.org>
References: <1439958009-14056-1-git-send-email-wens@csie.org>
Message-ID: <1439958009-14056-9-git-send-email-wens@csie.org>

The Reduced Serial Bus controller is used to talk to the onboard PMIC.

Signed-off-by: Chen-Yu Tsai <wens at csie.org>
---
 arch/arm/boot/dts/sun8i-a33-sinlinx-sina33.dts | 4 ++++
 1 file changed, 4 insertions(+)

diff --git a/arch/arm/boot/dts/sun8i-a33-sinlinx-sina33.dts b/arch/arm/boot/dts/sun8i-a33-sinlinx-sina33.dts
index 1d5390d4e03a..13ce68f06dd6 100644
--- a/arch/arm/boot/dts/sun8i-a33-sinlinx-sina33.dts
+++ b/arch/arm/boot/dts/sun8i-a33-sinlinx-sina33.dts
@@ -130,6 +130,10 @@
 	};
 };
 
+&r_rsb {
+	status = "okay";
+};
+
 &uart0 {
 	pinctrl-names = "default";
 	pinctrl-0 = <&uart0_pins_b>;
-- 
2.5.0



From wens at csie.org  Tue Aug 18 21:20:07 2015
From: wens at csie.org (Chen-Yu Tsai)
Date: Wed, 19 Aug 2015 12:20:07 +0800
Subject: [PATCH v3 6/8] ARM: dts: sun8i: Add Reduced Serial Bus controller
 device node to A23/A33 dtsi
In-Reply-To: <1439958009-14056-1-git-send-email-wens@csie.org>
References: <1439958009-14056-1-git-send-email-wens@csie.org>
Message-ID: <1439958009-14056-7-git-send-email-wens@csie.org>

This patch adds a device node for the Reduced Serial Bus (RSB)
controller and the defacto pinmux setting to the A23/A33 dtsi.

Since there is only one possible pinmux setting for RSB, just
set it in the dtsi.

Signed-off-by: Chen-Yu Tsai <wens at csie.org>
---
 arch/arm/boot/dts/sun8i-a23-a33.dtsi | 21 +++++++++++++++++++++
 1 file changed, 21 insertions(+)

diff --git a/arch/arm/boot/dts/sun8i-a23-a33.dtsi b/arch/arm/boot/dts/sun8i-a23-a33.dtsi
index 27a925ec17d2..db3671382cb2 100644
--- a/arch/arm/boot/dts/sun8i-a23-a33.dtsi
+++ b/arch/arm/boot/dts/sun8i-a23-a33.dtsi
@@ -661,6 +661,13 @@
 			#size-cells = <0>;
 			#gpio-cells = <3>;
 
+			r_rsb_pins: r_rsb {
+				allwinner,pins = "PL0", "PL1";
+				allwinner,function = "s_rsb";
+				allwinner,drive = <SUN4I_PINCTRL_20_MA>;
+				allwinner,pull = <SUN4I_PINCTRL_PULL_UP>;
+			};
+
 			r_uart_pins_a: r_uart at 0 {
 				allwinner,pins = "PL2", "PL3";
 				allwinner,function = "s_uart";
@@ -668,5 +675,19 @@
 				allwinner,pull = <SUN4I_PINCTRL_NO_PULL>;
 			};
 		};
+
+		r_rsb: i2c at 01f03400 {
+			compatible = "allwinner,sun8i-a23-rsb";
+			reg = <0x01f03400 0x400>;
+			interrupts = <GIC_SPI 39 IRQ_TYPE_LEVEL_HIGH>;
+			clocks = <&apb0_gates 3>;
+			clock-frequency = <3000000>;
+			resets = <&apb0_rst 3>;
+			pinctrl-names = "default";
+			pinctrl-0 = <&r_rsb_pins>;
+			status = "disabled";
+			#address-cells = <2>;
+			#size-cells = <0>;
+		};
 	};
 };
-- 
2.5.0



From wens at csie.org  Tue Aug 18 21:20:06 2015
From: wens at csie.org (Chen-Yu Tsai)
Date: Wed, 19 Aug 2015 12:20:06 +0800
Subject: [PATCH v3 5/8] regmap: rsb: Add support for Reduced Serial Bus (RSB)
 based regmaps
In-Reply-To: <1439958009-14056-1-git-send-email-wens@csie.org>
References: <1439958009-14056-1-git-send-email-wens@csie.org>
Message-ID: <1439958009-14056-6-git-send-email-wens@csie.org>

Signed-off-by: Chen-Yu Tsai <wens at csie.org>
---
 drivers/base/regmap/Kconfig      |   6 +-
 drivers/base/regmap/Makefile     |   1 +
 drivers/base/regmap/regmap-rsb.c | 121 +++++++++++++++++++++++++++++++++++++++
 include/linux/regmap.h           |  36 ++++++++++++
 4 files changed, 163 insertions(+), 1 deletion(-)
 create mode 100644 drivers/base/regmap/regmap-rsb.c

diff --git a/drivers/base/regmap/Kconfig b/drivers/base/regmap/Kconfig
index db9d00c36a3e..afb41994c51e 100644
--- a/drivers/base/regmap/Kconfig
+++ b/drivers/base/regmap/Kconfig
@@ -3,7 +3,7 @@
 # subsystems should select the appropriate symbols.
 
 config REGMAP
-	default y if (REGMAP_I2C || REGMAP_SPI || REGMAP_SPMI || REGMAP_AC97 || REGMAP_MMIO || REGMAP_IRQ)
+	default y if (REGMAP_I2C || REGMAP_SPI || REGMAP_SPMI || REGMAP_RSB || REGMAP_AC97 || REGMAP_MMIO || REGMAP_IRQ)
 	select LZO_COMPRESS
 	select LZO_DECOMPRESS
 	select IRQ_DOMAIN if REGMAP_IRQ
@@ -24,6 +24,10 @@ config REGMAP_SPMI
 	tristate
 	depends on SPMI
 
+config REGMAP_RSB
+	tristate
+	depends on RSB
+
 config REGMAP_MMIO
 	tristate
 
diff --git a/drivers/base/regmap/Makefile b/drivers/base/regmap/Makefile
index 609e4c84f485..dad32b3903d4 100644
--- a/drivers/base/regmap/Makefile
+++ b/drivers/base/regmap/Makefile
@@ -8,5 +8,6 @@ obj-$(CONFIG_REGMAP_AC97) += regmap-ac97.o
 obj-$(CONFIG_REGMAP_I2C) += regmap-i2c.o
 obj-$(CONFIG_REGMAP_SPI) += regmap-spi.o
 obj-$(CONFIG_REGMAP_SPMI) += regmap-spmi.o
+obj-$(CONFIG_REGMAP_RSB) += regmap-rsb.o
 obj-$(CONFIG_REGMAP_MMIO) += regmap-mmio.o
 obj-$(CONFIG_REGMAP_IRQ) += regmap-irq.o
diff --git a/drivers/base/regmap/regmap-rsb.c b/drivers/base/regmap/regmap-rsb.c
new file mode 100644
index 000000000000..e82aa980abe1
--- /dev/null
+++ b/drivers/base/regmap/regmap-rsb.c
@@ -0,0 +1,121 @@
+/*
+ * Register map access API - RSB support
+ *
+ * Copyright 2015 Chen-Yu Tsai
+ *
+ * Chen-Yu Tsai <wens at csie.org>
+ *
+ * Based on regmap-i2c.c
+ *
+ * Copyright 2011 Wolfson Microelectronics plc
+ *
+ * Author: Mark Brown <broonie at opensource.wolfsonmicro.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.
+ */
+
+#include <linux/regmap.h>
+#include <linux/rsb.h>
+#include <linux/module.h>
+#include <linux/slab.h>
+
+#include "internal.h"
+
+struct rsb_context {
+	struct rsb_device *rsb;
+	int size;
+};
+
+static int regmap_rsb_reg_read(void *context, unsigned int reg,
+			       unsigned int *val)
+{
+	struct rsb_context *ctx = context;
+	struct rsb_device *rsb = ctx->rsb;
+
+	if (reg > 0xff)
+		return -EINVAL;
+
+	return rsb_register_read(rsb, reg, val, ctx->size);
+}
+
+static int regmap_rsb_reg_write(void *context, unsigned int reg,
+				unsigned int val)
+{
+	struct rsb_context *ctx = context;
+	struct rsb_device *rsb = ctx->rsb;
+
+	return rsb_register_write(rsb, reg, val, ctx->size);
+}
+
+static void regmap_rsb_free_context(void *context)
+{
+	struct rsb_context *ctx = context;
+
+	kfree(ctx);
+}
+
+static struct regmap_bus regmap_rsb = {
+	.reg_write = regmap_rsb_reg_write,
+	.reg_read = regmap_rsb_reg_read,
+	.free_context = regmap_rsb_free_context,
+	.reg_format_endian_default = REGMAP_ENDIAN_NATIVE,
+	.val_format_endian_default = REGMAP_ENDIAN_NATIVE,
+};
+
+static struct rsb_context *regmap_rsb_init_context(struct rsb_device *rsb,
+					const struct regmap_config *config)
+{
+	struct rsb_context *ctx;
+
+	switch (config->val_bits) {
+	case 8:
+	case 16:
+	case 32:
+		break;
+	default:
+		return ERR_PTR(-EINVAL);
+	}
+
+	ctx = kzalloc(sizeof(*ctx), GFP_KERNEL);
+	if (!ctx)
+		return ERR_PTR(-ENOMEM);
+
+	ctx->rsb = rsb;
+	ctx->size = config->val_bits / 8;
+
+	return ctx;
+}
+
+struct regmap *__regmap_init_rsb(struct rsb_device *rsb,
+				 const struct regmap_config *config,
+				 struct lock_class_key *lock_key,
+				 const char *lock_name)
+{
+	struct rsb_context *ctx = regmap_rsb_init_context(rsb, config);
+
+	if (IS_ERR(ctx))
+		return ERR_CAST(ctx);
+
+	return __regmap_init(&rsb->dev, &regmap_rsb, ctx, config,
+			     lock_key, lock_name);
+}
+EXPORT_SYMBOL_GPL(__regmap_init_rsb);
+
+struct regmap *__devm_regmap_init_rsb(struct rsb_device *rsb,
+				      const struct regmap_config *config,
+				      struct lock_class_key *lock_key,
+				      const char *lock_name)
+{
+	struct rsb_context *ctx = regmap_rsb_init_context(rsb, config);
+
+	if (IS_ERR(ctx))
+		return ERR_CAST(ctx);
+
+	return __devm_regmap_init(&rsb->dev, &regmap_rsb, ctx, config,
+				  lock_key, lock_name);
+}
+EXPORT_SYMBOL_GPL(__devm_regmap_init_rsb);
+
+MODULE_LICENSE("GPL v2");
diff --git a/include/linux/regmap.h b/include/linux/regmap.h
index 17178317bcec..df94574b1d37 100644
--- a/include/linux/regmap.h
+++ b/include/linux/regmap.h
@@ -25,6 +25,7 @@ struct i2c_client;
 struct irq_domain;
 struct spi_device;
 struct spmi_device;
+struct rsb_device;
 struct regmap;
 struct regmap_range_cfg;
 struct regmap_field;
@@ -377,6 +378,10 @@ struct regmap *__regmap_init_ac97(struct snd_ac97 *ac97,
 				  const struct regmap_config *config,
 				  struct lock_class_key *lock_key,
 				  const char *lock_name);
+struct regmap *__regmap_init_rsb(struct rsb_device *rsb,
+				 const struct regmap_config *config,
+				 struct lock_class_key *lock_key,
+				 const char *lock_name);
 
 struct regmap *__devm_regmap_init(struct device *dev,
 				  const struct regmap_bus *bus,
@@ -410,6 +415,10 @@ struct regmap *__devm_regmap_init_ac97(struct snd_ac97 *ac97,
 				       const struct regmap_config *config,
 				       struct lock_class_key *lock_key,
 				       const char *lock_name);
+struct regmap *__devm_regmap_init_rsb(struct rsb_device *rsb,
+				      const struct regmap_config *config,
+				      struct lock_class_key *lock_key,
+				      const char *lock_name);
 
 /*
  * Wrapper for regmap_init macros to include a unique lockdep key and name
@@ -544,6 +553,19 @@ int regmap_attach_dev(struct device *dev, struct regmap *map,
 bool regmap_ac97_default_volatile(struct device *dev, unsigned int reg);
 
 /**
+ * regmap_init_rsb(): Initialise register map
+ *
+ * @rsb: Device that will be interacted with
+ * @config: Configuration for register map
+ *
+ * The return value will be an ERR_PTR() on error or a valid pointer to
+ * a struct regmap.
+ */
+#define regmap_init_rsb(rsb, config)					\
+	__regmap_lockdep_wrapper(__regmap_init_rsb, #config,		\
+				rsb, config)
+
+/**
  * devm_regmap_init(): Initialise managed register map
  *
  * @dev: Device that will be interacted with
@@ -658,6 +680,20 @@ bool regmap_ac97_default_volatile(struct device *dev, unsigned int reg);
 	__regmap_lockdep_wrapper(__devm_regmap_init_ac97, #config,	\
 				ac97, config)
 
+/**
+ * devm_regmap_init_rsb(): Initialise managed register map
+ *
+ * @rsb: Device that will be interacted with
+ * @config: Configuration for register map
+ *
+ * The return value will be an ERR_PTR() on error or a valid pointer
+ * to a struct regmap.  The regmap will be automatically freed by the
+ * device management code.
+ */
+#define devm_regmap_init_rsb(rsb, config)				\
+	__regmap_lockdep_wrapper(__devm_regmap_init_rsb, #config,	\
+				rsb, config)
+
 void regmap_exit(struct regmap *map);
 int regmap_reinit_cache(struct regmap *map,
 			const struct regmap_config *config);
-- 
2.5.0



From wens at csie.org  Tue Aug 18 21:20:08 2015
From: wens at csie.org (Chen-Yu Tsai)
Date: Wed, 19 Aug 2015 12:20:08 +0800
Subject: [PATCH v3 7/8] ARM: dts: sun8i: ippo-q8h-v5: Enable Reduced Serial
 Bus controller
In-Reply-To: <1439958009-14056-1-git-send-email-wens@csie.org>
References: <1439958009-14056-1-git-send-email-wens@csie.org>
Message-ID: <1439958009-14056-8-git-send-email-wens@csie.org>

The Reduced Serial Bus controller is used to talk to the onboard PMIC.

Signed-off-by: Chen-Yu Tsai <wens at csie.org>
---
 arch/arm/boot/dts/sun8i-a23-ippo-q8h-v5.dts | 4 ++++
 1 file changed, 4 insertions(+)

diff --git a/arch/arm/boot/dts/sun8i-a23-ippo-q8h-v5.dts b/arch/arm/boot/dts/sun8i-a23-ippo-q8h-v5.dts
index 8d9da6886a4c..2e45a82c8981 100644
--- a/arch/arm/boot/dts/sun8i-a23-ippo-q8h-v5.dts
+++ b/arch/arm/boot/dts/sun8i-a23-ippo-q8h-v5.dts
@@ -120,6 +120,10 @@
 	};
 };
 
+&r_rsb {
+	status = "okay";
+};
+
 &r_uart {
 	pinctrl-names = "default";
 	pinctrl-0 = <&r_uart_pins_a>;
-- 
2.5.0



From dmitry.torokhov at gmail.com  Tue Aug 18 22:11:31 2015
From: dmitry.torokhov at gmail.com (Dmitry Torokhov)
Date: Tue, 18 Aug 2015 22:11:31 -0700
Subject: [PATCH v2 1/5] input: touchscreen: add imx6ul_tsc driver support
In-Reply-To: <1438077521-12857-2-git-send-email-haibo.chen@freescale.com>
References: <1438077521-12857-1-git-send-email-haibo.chen@freescale.com>
 <1438077521-12857-2-git-send-email-haibo.chen@freescale.com>
Message-ID: <20150819051131.GA12545@dtor-pixel>

Hi Haibo,

On Tue, Jul 28, 2015 at 05:58:37PM +0800, Haibo Chen wrote:
> Freescale i.MX6UL contains a internal touchscreen controller,
> this patch add a driver to support this controller.
> 

This looks pretty reasonable; just a few comments below.

> Signed-off-by: Haibo Chen <haibo.chen at freescale.com>
> ---
>  drivers/input/touchscreen/Kconfig      |  12 +
>  drivers/input/touchscreen/Makefile     |   1 +
>  drivers/input/touchscreen/imx6ul_tsc.c | 504 +++++++++++++++++++++++++++++++++
>  3 files changed, 517 insertions(+)
>  create mode 100644 drivers/input/touchscreen/imx6ul_tsc.c
> 
> diff --git a/drivers/input/touchscreen/Kconfig b/drivers/input/touchscreen/Kconfig
> index 5b272ba..32c300d 100644
> --- a/drivers/input/touchscreen/Kconfig
> +++ b/drivers/input/touchscreen/Kconfig
> @@ -479,6 +479,18 @@ config TOUCHSCREEN_MTOUCH
>  	  To compile this driver as a module, choose M here: the
>  	  module will be called mtouch.
>  
> +config TOUCHSCREEN_IMX6UL_TSC
> +	tristate "Freescale i.MX6UL touchscreen controller"
> +	depends on OF
> +	help
> +	  Say Y here if you have a Freescale i.MX6UL, and want to
> +	  use the internal touchscreen controller.
> +
> +	  If unsure, say N.
> +
> +	  To compile this driver as a module, choose M here: the
> +	  moduel will be called imx6ul_tsc.
> +
>  config TOUCHSCREEN_INEXIO
>  	tristate "iNexio serial touchscreens"
>  	select SERIO
> diff --git a/drivers/input/touchscreen/Makefile b/drivers/input/touchscreen/Makefile
> index c85aae2..9379b32 100644
> --- a/drivers/input/touchscreen/Makefile
> +++ b/drivers/input/touchscreen/Makefile
> @@ -38,6 +38,7 @@ obj-$(CONFIG_TOUCHSCREEN_EGALAX)	+= egalax_ts.o
>  obj-$(CONFIG_TOUCHSCREEN_FUJITSU)	+= fujitsu_ts.o
>  obj-$(CONFIG_TOUCHSCREEN_GOODIX)	+= goodix.o
>  obj-$(CONFIG_TOUCHSCREEN_ILI210X)	+= ili210x.o
> +obj-$(CONFIG_TOUCHSCREEN_IMX6UL_TSC)	+= imx6ul_tsc.o
>  obj-$(CONFIG_TOUCHSCREEN_INEXIO)	+= inexio.o
>  obj-$(CONFIG_TOUCHSCREEN_INTEL_MID)	+= intel-mid-touch.o
>  obj-$(CONFIG_TOUCHSCREEN_IPROC)		+= bcm_iproc_tsc.o
> diff --git a/drivers/input/touchscreen/imx6ul_tsc.c b/drivers/input/touchscreen/imx6ul_tsc.c
> new file mode 100644
> index 0000000..807f1db
> --- /dev/null
> +++ b/drivers/input/touchscreen/imx6ul_tsc.c
> @@ -0,0 +1,504 @@
> +/*
> + * Freescale i.MX6UL touchscreen controller driver
> + *
> + * Copyright (C) 2015 Freescale Semiconductor, Inc.
> + *
> + * This program is free software; you can redistribute it and/or modify
> + * it under the terms of the GNU General Public License version 2 as
> + * published by the Free Software Foundation.
> + */
> +
> +#include <linux/errno.h>
> +#include <linux/kernel.h>
> +#include <linux/module.h>
> +#include <linux/gpio.h>
> +#include <linux/input.h>
> +#include <linux/slab.h>
> +#include <linux/completion.h>
> +#include <linux/delay.h>
> +#include <linux/of.h>
> +#include <linux/of_device.h>
> +#include <linux/of_gpio.h>
> +#include <linux/of_irq.h>

I do not think you need of_irq and of_device.

> +#include <linux/interrupt.h>
> +#include <linux/platform_device.h>
> +#include <linux/clk.h>
> +#include <linux/io.h>
> +
> +/* ADC configuration registers field define */
> +#define ADC_AIEN		(0x1 << 7)
> +#define ADC_CONV_DISABLE	0x1F
> +#define ADC_CAL			(0x1 << 7)
> +#define ADC_CALF		0x2
> +#define ADC_12BIT_MODE		(0x2 << 2)
> +#define ADC_IPG_CLK		0x00
> +#define ADC_CLK_DIV_8		(0x03 << 5)
> +#define ADC_SHORT_SAMPLE_MODE	(0x0 << 4)
> +#define ADC_HARDWARE_TRIGGER	(0x1 << 13)
> +#define SELECT_CHANNEL_4	0x04
> +#define SELECT_CHANNEL_1	0x01
> +#define DISABLE_CONVERSION_INT	(0x0 << 7)
> +
> +/* ADC registers */
> +#define REG_ADC_HC0		0x00
> +#define REG_ADC_HC1		0x04
> +#define REG_ADC_HC2		0x08
> +#define REG_ADC_HC3		0x0C
> +#define REG_ADC_HC4		0x10
> +#define REG_ADC_HS		0x14
> +#define REG_ADC_R0		0x18
> +#define REG_ADC_CFG		0x2C
> +#define REG_ADC_GC		0x30
> +#define REG_ADC_GS		0x34
> +
> +#define ADC_TIMEOUT		msecs_to_jiffies(100)
> +
> +/* TSC registers */
> +#define REG_TSC_BASIC_SETING	0x00
> +#define REG_TSC_PRE_CHARGE_TIME	0x10
> +#define REG_TSC_FLOW_CONTROL	0x20
> +#define REG_TSC_MEASURE_VALUE	0x30
> +#define REG_TSC_INT_EN		0x40
> +#define REG_TSC_INT_SIG_EN	0x50
> +#define REG_TSC_INT_STATUS	0x60
> +#define REG_TSC_DEBUG_MODE	0x70
> +#define REG_TSC_DEBUG_MODE2	0x80
> +
> +/* TSC configuration registers field define */
> +#define DETECT_4_WIRE_MODE	(0x0 << 4)
> +#define AUTO_MEASURE		0x1
> +#define MEASURE_SIGNAL		0x1
> +#define DETECT_SIGNAL		(0x1 << 4)
> +#define VALID_SIGNAL		(0x1 << 8)
> +#define MEASURE_INT_EN		0x1
> +#define MEASURE_SIG_EN		0x1
> +#define VALID_SIG_EN		(0x1 << 8)
> +#define DE_GLITCH_2		(0x2 << 29)
> +#define START_SENSE		(0x1 << 12)
> +#define TSC_DISABLE		(0x1 << 16)
> +#define DETECT_MODE		0x2
> +
> +struct imx6ul_tsc {
> +	struct device *dev;
> +	struct input_dev *input;
> +	void __iomem *tsc_regs;
> +	void __iomem *adc_regs;
> +	struct clk *tsc_clk;
> +	struct clk *adc_clk;
> +
> +	int xnur_gpio;
> +	int measure_delay_time;
> +	int pre_charge_time;
> +
> +	struct completion completion;
> +};
> +
> +/*
> + * TSC module need ADC to get the measure value. So
> + * before config TSC, we should initialize ADC module.
> + */
> +static void imx6ul_adc_init(struct imx6ul_tsc *tsc)
> +{
> +	int adc_hc = 0;
> +	int adc_gc;
> +	int adc_gs;
> +	int adc_cfg;
> +	int timeout;
> +
> +	adc_cfg = readl(tsc->adc_regs + REG_ADC_CFG);
> +	adc_cfg |= ADC_12BIT_MODE | ADC_IPG_CLK;
> +	adc_cfg |= ADC_CLK_DIV_8 | ADC_SHORT_SAMPLE_MODE;
> +	adc_cfg &= ~ADC_HARDWARE_TRIGGER;
> +	writel(adc_cfg, tsc->adc_regs + REG_ADC_CFG);
> +
> +	/* enable calibration interrupt */
> +	adc_hc |= ADC_AIEN;
> +	adc_hc |= ADC_CONV_DISABLE;
> +	writel(adc_hc, tsc->adc_regs + REG_ADC_HC0);
> +
> +	/* start ADC calibration */
> +	adc_gc = readl(tsc->adc_regs + REG_ADC_GC);
> +	adc_gc |= ADC_CAL;
> +	writel(adc_gc, tsc->adc_regs + REG_ADC_GC);
> +

Since this is called on every resume you need to reinit completion;
probably at the beginning of this function.

> +	timeout = wait_for_completion_timeout
> +			(&tsc->completion, ADC_TIMEOUT);
> +	if (timeout == 0)
> +		dev_err(tsc->dev, "Timeout for adc calibration\n");
> +
> +	adc_gs = readl(tsc->adc_regs + REG_ADC_GS);
> +	if (adc_gs & ADC_CALF)
> +		dev_err(tsc->dev, "ADC calibration failed\n");
> +
> +	/* TSC need the ADC work in hardware trigger */
> +	adc_cfg = readl(tsc->adc_regs + REG_ADC_CFG);
> +	adc_cfg |= ADC_HARDWARE_TRIGGER;
> +	writel(adc_cfg, tsc->adc_regs + REG_ADC_CFG);
> +}
> +
> +/*
> + * This is a TSC workaround. Currently TSC misconnect two
> + * ADC channels, this function remap channel configure for
> + * hardware trigger.
> + */
> +static void imx6ul_tsc_channel_config(struct imx6ul_tsc *tsc)
> +{
> +	int adc_hc0, adc_hc1, adc_hc2, adc_hc3, adc_hc4;
> +
> +	adc_hc0 = DISABLE_CONVERSION_INT;
> +	writel(adc_hc0, tsc->adc_regs + REG_ADC_HC0);
> +
> +	adc_hc1 = DISABLE_CONVERSION_INT | SELECT_CHANNEL_4;
> +	writel(adc_hc1, tsc->adc_regs + REG_ADC_HC1);
> +
> +	adc_hc2 = DISABLE_CONVERSION_INT;
> +	writel(adc_hc2, tsc->adc_regs + REG_ADC_HC2);
> +
> +	adc_hc3 = DISABLE_CONVERSION_INT | SELECT_CHANNEL_1;
> +	writel(adc_hc3, tsc->adc_regs + REG_ADC_HC3);
> +
> +	adc_hc4 = DISABLE_CONVERSION_INT;
> +	writel(adc_hc4, tsc->adc_regs + REG_ADC_HC4);
> +}
> +
> +/*
> + * TSC setting, confige the pre-charge time and measure delay time.
> + * different touch screen may need different pre-charge time and
> + * measure delay time.
> + */
> +static void imx6ul_tsc_set(struct imx6ul_tsc *tsc)
> +{
> +	int basic_setting = 0;
> +	int start;
> +
> +	basic_setting |= tsc->measure_delay_time << 8;
> +	basic_setting |= DETECT_4_WIRE_MODE | AUTO_MEASURE;
> +	writel(basic_setting, tsc->tsc_regs + REG_TSC_BASIC_SETING);
> +
> +	writel(DE_GLITCH_2, tsc->tsc_regs + REG_TSC_DEBUG_MODE2);
> +
> +	writel(tsc->pre_charge_time, tsc->tsc_regs + REG_TSC_PRE_CHARGE_TIME);
> +	writel(MEASURE_INT_EN, tsc->tsc_regs + REG_TSC_INT_EN);
> +	writel(MEASURE_SIG_EN | VALID_SIG_EN,
> +		tsc->tsc_regs + REG_TSC_INT_SIG_EN);
> +
> +	/* start sense detection */
> +	start = readl(tsc->tsc_regs + REG_TSC_FLOW_CONTROL);
> +	start |= START_SENSE;
> +	start &= ~TSC_DISABLE;
> +	writel(start, tsc->tsc_regs + REG_TSC_FLOW_CONTROL);
> +}
> +
> +static void imx6ul_tsc_init(struct imx6ul_tsc *tsc)
> +{
> +	imx6ul_adc_init(tsc);
> +	imx6ul_tsc_channel_config(tsc);
> +	imx6ul_tsc_set(tsc);
> +}
> +
> +static irqreturn_t tsc_irq_fn(int irq, void *dev_id)
> +{
> +	struct imx6ul_tsc *tsc = (struct imx6ul_tsc *)dev_id;

No need to cast void pointers.

> +	int status;
> +	int value;
> +	int x, y;
> +	int xnur;
> +	int debug_mode2;
> +	int state_machine;
> +	int start;
> +	unsigned long timeout;
> +
> +	status = readl(tsc->tsc_regs + REG_TSC_INT_STATUS);
> +
> +	/* write 1 to clear the bit measure-signal */
> +	writel(MEASURE_SIGNAL | DETECT_SIGNAL,
> +		tsc->tsc_regs + REG_TSC_INT_STATUS);
> +
> +	/* It's a HW self-clean bit. Set this bit and start sense detection */
> +	start = readl(tsc->tsc_regs + REG_TSC_FLOW_CONTROL);
> +	start |= START_SENSE;
> +	writel(start, tsc->tsc_regs + REG_TSC_FLOW_CONTROL);
> +
> +	if (status & MEASURE_SIGNAL) {
> +		value = readl(tsc->tsc_regs + REG_TSC_MEASURE_VALUE);
> +		x = (value >> 16) & 0x0fff;
> +		y = value & 0x0fff;
> +
> +		/*
> +		 * Delay some time(max 2ms), wait the pre-charge done.
> +		 * After the pre-change mode, TSC go into detect mode.
> +		 * And in detect mode, we can get the xnur gpio value.
> +		 * If xnur is low, this means the touch screen still
> +		 * be touched. If xnur is high, this means finger leave
> +		 * the touch screen.
> +		 */
> +		timeout = jiffies + HZ/500;
> +		do {
> +			if (time_after(jiffies, timeout)) {
> +				xnur = 0;
> +				goto touch_event;
> +			}
> +			usleep_range(200, 400);
> +			debug_mode2 = readl(tsc->tsc_regs + REG_TSC_DEBUG_MODE2);
> +			state_machine = (debug_mode2 >> 20) & 0x7;
> +		} while (state_machine != DETECT_MODE);
> +		usleep_range(200, 400);
> +
> +		xnur = gpio_get_value(tsc->xnur_gpio);

It seems to me that this GPIO is actually active low: we reporting
active touch as long as we read 0.

> +touch_event:
> +		if (xnur == 0) {
> +			input_report_key(tsc->input, BTN_TOUCH, 1);
> +			input_report_abs(tsc->input, ABS_X, x);
> +			input_report_abs(tsc->input, ABS_Y, y);
> +		} else
> +			input_report_key(tsc->input, BTN_TOUCH, 0);

If one branch has braces all of them should have braces.

> +
> +		input_sync(tsc->input);
> +	}
> +
> +	return IRQ_HANDLED;
> +}
> +
> +static irqreturn_t adc_irq_fn(int irq, void *dev_id)
> +{
> +	struct imx6ul_tsc *tsc = (struct imx6ul_tsc *)dev_id;
> +	int coco;
> +	int value;
> +
> +	coco = readl(tsc->adc_regs + REG_ADC_HS);
> +	if (coco & 0x01) {
> +		value = readl(tsc->adc_regs + REG_ADC_R0);
> +		complete(&tsc->completion);
> +	}
> +
> +	return IRQ_HANDLED;
> +}
> +
> +static const struct of_device_id imx6ul_tsc_match[] = {
> +	{ .compatible = "fsl,imx6ul-tsc", },
> +	{ /* sentinel */ }
> +};
> +MODULE_DEVICE_TABLE(of, imx6ul_tsc_match);
> +
> +static int imx6ul_tsc_probe(struct platform_device *pdev)
> +{
> +	struct imx6ul_tsc *tsc;
> +	struct resource *tsc_mem;
> +	struct resource *adc_mem;
> +	struct input_dev *input_dev;
> +	struct device_node *np = pdev->dev.of_node;
> +	int err;
> +	int tsc_irq;
> +	int adc_irq;
> +
> +	tsc = devm_kzalloc(&pdev->dev, sizeof(struct imx6ul_tsc), GFP_KERNEL);
> +	input_dev = devm_input_allocate_device(&pdev->dev);

Using devm does not mean you do not need to check results of memory
allocation.

> +
> +	tsc->dev = &pdev->dev;
> +
> +	tsc->input = input_dev;
> +	tsc->input->evbit[0] = BIT_MASK(EV_KEY) | BIT_MASK(EV_ABS);
> +	tsc->input->keybit[BIT_WORD(BTN_TOUCH)] = BIT_MASK(BTN_TOUCH);
> +	input_set_abs_params(tsc->input, ABS_X, 0, 0xFFF, 0, 0);
> +	input_set_abs_params(tsc->input, ABS_Y, 0, 0xFFF, 0, 0);
> +
> +	tsc->input->name = "iMX6UL TouchScreen Controller";
> +
> +	tsc->xnur_gpio = of_get_named_gpio(np, "xnur-gpio", 0);
> +	err = gpio_request_one(tsc->xnur_gpio, GPIOF_IN, "tsc_X-");

Why are you not using devm for gpio? Actually, why don't you also use
gpiod? As is you are leaking that gpio in all error paths below.

> +	if (err) {
> +		dev_err(&pdev->dev, "failed to request GPIO tsc_X-\n");
> +		return err;
> +	}
> +
> +	tsc_mem = platform_get_resource(pdev, IORESOURCE_MEM, 0);
> +	tsc->tsc_regs = devm_ioremap_resource(&pdev->dev, tsc_mem);
> +	if (IS_ERR(tsc->tsc_regs)) {
> +		dev_err(&pdev->dev, "failed to remap tsc memory\n");
> +		err = PTR_ERR(tsc->tsc_regs);
> +		return err;
> +	}
> +
> +	adc_mem = platform_get_resource(pdev, IORESOURCE_MEM, 1);
> +	tsc->adc_regs = devm_ioremap_resource(&pdev->dev, adc_mem);
> +	if (IS_ERR(tsc->adc_regs)) {
> +		dev_err(&pdev->dev, "failed to remap adc memory\n");
> +		err = PTR_ERR(tsc->adc_regs);
> +		return err;
> +	}
> +
> +	tsc->tsc_clk = devm_clk_get(&pdev->dev, "tsc");
> +	if (IS_ERR(tsc->tsc_clk)) {
> +		dev_err(&pdev->dev, "failed getting tsc clock\n");
> +		err = PTR_ERR(tsc->tsc_clk);
> +		return err;
> +	}
> +
> +	tsc->adc_clk = devm_clk_get(&pdev->dev, "adc");
> +	if (IS_ERR(tsc->adc_clk)) {
> +		dev_err(&pdev->dev, "failed getting adc clock\n");
> +		err = PTR_ERR(tsc->adc_clk);
> +		return err;
> +	}
> +
> +	tsc_irq = platform_get_irq(pdev, 0);
> +	if (tsc_irq < 0) {
> +		dev_err(&pdev->dev, "no tsc irq resource?\n");
> +		return tsc_irq;
> +	}
> +
> +	adc_irq = platform_get_irq(pdev, 1);
> +	if (adc_irq <= 0) {
> +		dev_err(&pdev->dev, "no adc irq resource?\n");
> +		return adc_irq;
> +	}
> +
> +	err = devm_request_threaded_irq(tsc->dev, tsc_irq,
> +					NULL, tsc_irq_fn,
> +					IRQF_TRIGGER_HIGH | IRQF_ONESHOT,
> +					dev_name(&pdev->dev), tsc);
> +	if (err < 0) {
> +		dev_err(&pdev->dev,
> +			"failed requesting tsc irq %d\n",
> +					    tsc_irq);
> +		return err;
> +	}
> +
> +	err = devm_request_irq(tsc->dev, adc_irq,
> +				adc_irq_fn, 0,
> +				dev_name(&pdev->dev), tsc);
> +	if (err < 0) {
> +		dev_err(&pdev->dev,
> +			"failed requesting adc irq %d\n",
> +					    adc_irq);
> +		return err;
> +	}
> +
> +	err = of_property_read_u32(np, "measure-delay-time",
> +				&tsc->measure_delay_time);
> +	if (err)
> +		tsc->measure_delay_time = 0xffff;
> +
> +	err = of_property_read_u32(np, "pre-charge-time",
> +				&tsc->pre_charge_time);
> +	if (err)
> +		tsc->pre_charge_time = 0xfff;
> +
> +	init_completion(&tsc->completion);
> +
> +	err = clk_prepare_enable(tsc->adc_clk);
> +	if (err) {
> +		dev_err(&pdev->dev,
> +			"Could not prepare or enable the adc clock.\n");
> +		return err;
> +	}
> +
> +	err = clk_prepare_enable(tsc->tsc_clk);
> +	if (err) {
> +		dev_err(&pdev->dev,
> +			"Could not prepare or enable the tsc clock.\n");
> +		goto error_tsc_clk_enable;
> +	}
> +
> +	err = input_register_device(tsc->input);
> +	if (err < 0) {
> +		dev_err(&pdev->dev, "failed to register input device\n");
> +		err = -EIO;
> +		goto err_input_register;
> +	}
> +
> +	imx6ul_tsc_init(tsc);

Enabling clock and initializing the controller is better in open()
method of input device. If you also implement close() you can get rid of
remove().

> +
> +	platform_set_drvdata(pdev, tsc);
> +	return 0;
> +
> +err_input_register:
> +	clk_disable_unprepare(tsc->tsc_clk);
> +error_tsc_clk_enable:
> +	clk_disable_unprepare(tsc->adc_clk);
> +
> +	return err;
> +}
> +
> +static void imx6ul_tsc_disable(struct imx6ul_tsc *tsc)
> +{
> +	int tsc_flow;
> +	int adc_cfg;
> +
> +	/* TSC controller enters to idle status */
> +	tsc_flow = readl(tsc->tsc_regs + REG_TSC_FLOW_CONTROL);
> +	tsc_flow |= TSC_DISABLE;
> +	writel(tsc_flow, tsc->tsc_regs + REG_TSC_FLOW_CONTROL);
> +
> +	/* ADC controller enters to stop mode */
> +	adc_cfg = readl(tsc->adc_regs + REG_ADC_HC0);
> +	adc_cfg |= ADC_CONV_DISABLE;
> +	writel(adc_cfg, tsc->adc_regs + REG_ADC_HC0);
> +}
> +
> +static int imx6ul_tsc_remove(struct platform_device *pdev)
> +{
> +	struct imx6ul_tsc *tsc = platform_get_drvdata(pdev);
> +
> +	imx6ul_tsc_disable(tsc);
> +
> +	clk_disable_unprepare(tsc->tsc_clk);
> +	clk_disable_unprepare(tsc->adc_clk);
> +	input_unregister_device(tsc->input);
> +	kfree(tsc);

Tsc is allocated with devm(), you can't kfree() it.
> +
> +	return 0;
> +}
> +
> +static int __maybe_unused imx6ul_tsc_suspend(struct device *dev)
> +{
> +	struct platform_device *pdev = to_platform_device(dev);
> +	struct imx6ul_tsc *tsc = platform_get_drvdata(pdev);
> +
> +	imx6ul_tsc_disable(tsc);
> +
> +	clk_disable_unprepare(tsc->tsc_clk);
> +	clk_disable_unprepare(tsc->adc_clk);
> +
> +	return 0;
> +}
> +
> +static int __maybe_unused imx6ul_tsc_resume(struct device *dev)
> +{
> +	struct platform_device *pdev = to_platform_device(dev);
> +	struct imx6ul_tsc *tsc = platform_get_drvdata(pdev);
> +	int err;
> +
> +	err = clk_prepare_enable(tsc->adc_clk);
> +	if (err)
> +		return err;
> +
> +	err = clk_prepare_enable(tsc->tsc_clk);
> +	if (err) {
> +		clk_disable_unprepare(tsc->adc_clk);
> +		return err;
> +	}
> +
> +	imx6ul_tsc_init(tsc);
> +	return 0;
> +}
> +
> +static SIMPLE_DEV_PM_OPS(imx6ul_tsc_pm_ops,
> +			 imx6ul_tsc_suspend,
> +			 imx6ul_tsc_resume);
> +
> +static struct platform_driver imx6ul_tsc_driver = {
> +	.driver		= {
> +		.name	= "imx6ul-tsc",
> +		.owner	= THIS_MODULE,
> +		.of_match_table	= imx6ul_tsc_match,
> +		.pm	= &imx6ul_tsc_pm_ops,
> +	},
> +	.probe		= imx6ul_tsc_probe,
> +	.remove		= imx6ul_tsc_remove,
> +};
> +module_platform_driver(imx6ul_tsc_driver);
> +
> +MODULE_AUTHOR("Haibo Chen <haibo.chen at freescale.com>");
> +MODULE_DESCRIPTION("Freescale i.MX6UL Touchscreen controller driver");
> +MODULE_LICENSE("GPL v2");
> -- 
> 1.9.1
> 

Can you try the patch below and let me know if it still works (you'll
need to adjust your DTS for xnur gpio being active low).

Thanks!

-- 
Dmitry

Input: imx6ul_tsc - misc changes

From: Dmitry Torokhov <dmitry.torokhov at gmail.com>

Signed-off-by: Dmitry Torokhov <dmitry.torokhov at gmail.com>
---
 .../bindings/input/touchscreen/imx6ul_tsc.txt      |    2 
 drivers/input/touchscreen/Kconfig                  |    2 
 drivers/input/touchscreen/imx6ul_tsc.c             |  262 +++++++++++---------
 3 files changed, 143 insertions(+), 123 deletions(-)

diff --git a/Documentation/devicetree/bindings/input/touchscreen/imx6ul_tsc.txt b/Documentation/devicetree/bindings/input/touchscreen/imx6ul_tsc.txt
index ac41c32..c933588 100644
--- a/Documentation/devicetree/bindings/input/touchscreen/imx6ul_tsc.txt
+++ b/Documentation/devicetree/bindings/input/touchscreen/imx6ul_tsc.txt
@@ -29,7 +29,7 @@ Example:
 		clock-names = "tsc", "adc";
 		pinctrl-names = "default";
 		pinctrl-0 = <&pinctrl_tsc>;
-		xnur-gpio = <&gpio1 3 GPIO_ACTIVE_HIGH>;
+		xnur-gpio = <&gpio1 3 GPIO_ACTIVE_LOW>;
 		measure-delay-time = <0xfff>;
 		pre-charge-time = <0xffff>;
 		status = "okay";
diff --git a/drivers/input/touchscreen/Kconfig b/drivers/input/touchscreen/Kconfig
index 9a1a293..5ecf19b 100644
--- a/drivers/input/touchscreen/Kconfig
+++ b/drivers/input/touchscreen/Kconfig
@@ -481,7 +481,7 @@ config TOUCHSCREEN_MTOUCH
 
 config TOUCHSCREEN_IMX6UL_TSC
 	tristate "Freescale i.MX6UL touchscreen controller"
-	depends on OF
+	depends on (OF && GPIOLIB) || COMPILE_TEST
 	help
 	  Say Y here if you have a Freescale i.MX6UL, and want to
 	  use the internal touchscreen controller.
diff --git a/drivers/input/touchscreen/imx6ul_tsc.c b/drivers/input/touchscreen/imx6ul_tsc.c
index 807f1db..1d028ed 100644
--- a/drivers/input/touchscreen/imx6ul_tsc.c
+++ b/drivers/input/touchscreen/imx6ul_tsc.c
@@ -11,15 +11,12 @@
 #include <linux/errno.h>
 #include <linux/kernel.h>
 #include <linux/module.h>
-#include <linux/gpio.h>
+#include <linux/gpio/consumer.h>
 #include <linux/input.h>
 #include <linux/slab.h>
 #include <linux/completion.h>
 #include <linux/delay.h>
 #include <linux/of.h>
-#include <linux/of_device.h>
-#include <linux/of_gpio.h>
-#include <linux/of_irq.h>
 #include <linux/interrupt.h>
 #include <linux/platform_device.h>
 #include <linux/clk.h>
@@ -85,8 +82,8 @@ struct imx6ul_tsc {
 	void __iomem *adc_regs;
 	struct clk *tsc_clk;
 	struct clk *adc_clk;
+	struct gpio_desc *xnur_gpio;
 
-	int xnur_gpio;
 	int measure_delay_time;
 	int pre_charge_time;
 
@@ -105,6 +102,8 @@ static void imx6ul_adc_init(struct imx6ul_tsc *tsc)
 	int adc_cfg;
 	int timeout;
 
+	reinit_completion(&tsc->completion);
+
 	adc_cfg = readl(tsc->adc_regs + REG_ADC_CFG);
 	adc_cfg |= ADC_12BIT_MODE | ADC_IPG_CLK;
 	adc_cfg |= ADC_CLK_DIV_8 | ADC_SHORT_SAMPLE_MODE;
@@ -196,17 +195,33 @@ static void imx6ul_tsc_init(struct imx6ul_tsc *tsc)
 	imx6ul_tsc_set(tsc);
 }
 
+static void imx6ul_tsc_disable(struct imx6ul_tsc *tsc)
+{
+	int tsc_flow;
+	int adc_cfg;
+
+	/* TSC controller enters to idle status */
+	tsc_flow = readl(tsc->tsc_regs + REG_TSC_FLOW_CONTROL);
+	tsc_flow |= TSC_DISABLE;
+	writel(tsc_flow, tsc->tsc_regs + REG_TSC_FLOW_CONTROL);
+
+	/* ADC controller enters to stop mode */
+	adc_cfg = readl(tsc->adc_regs + REG_ADC_HC0);
+	adc_cfg |= ADC_CONV_DISABLE;
+	writel(adc_cfg, tsc->adc_regs + REG_ADC_HC0);
+}
+
 static irqreturn_t tsc_irq_fn(int irq, void *dev_id)
 {
 	struct imx6ul_tsc *tsc = (struct imx6ul_tsc *)dev_id;
 	int status;
 	int value;
 	int x, y;
-	int xnur;
 	int debug_mode2;
 	int state_machine;
 	int start;
 	unsigned long timeout;
+	bool touch;
 
 	status = readl(tsc->tsc_regs + REG_TSC_INT_STATUS);
 
@@ -235,8 +250,8 @@ static irqreturn_t tsc_irq_fn(int irq, void *dev_id)
 		timeout = jiffies + HZ/500;
 		do {
 			if (time_after(jiffies, timeout)) {
-				xnur = 0;
-				goto touch_event;
+				touch = true;
+				goto report_touch;
 			}
 			usleep_range(200, 400);
 			debug_mode2 = readl(tsc->tsc_regs + REG_TSC_DEBUG_MODE2);
@@ -244,14 +259,15 @@ static irqreturn_t tsc_irq_fn(int irq, void *dev_id)
 		} while (state_machine != DETECT_MODE);
 		usleep_range(200, 400);
 
-		xnur = gpio_get_value(tsc->xnur_gpio);
-touch_event:
-		if (xnur == 0) {
+		touch = gpiod_get_value_cansleep(tsc->xnur_gpio);
+report_touch:
+		if (touch) {
 			input_report_key(tsc->input, BTN_TOUCH, 1);
 			input_report_abs(tsc->input, ABS_X, x);
 			input_report_abs(tsc->input, ABS_Y, y);
-		} else
+		} else {
 			input_report_key(tsc->input, BTN_TOUCH, 0);
+		}
 
 		input_sync(tsc->input);
 	}
@@ -261,7 +277,7 @@ touch_event:
 
 static irqreturn_t adc_irq_fn(int irq, void *dev_id)
 {
-	struct imx6ul_tsc *tsc = (struct imx6ul_tsc *)dev_id;
+	struct imx6ul_tsc *tsc = dev_id;
 	int coco;
 	int value;
 
@@ -274,70 +290,113 @@ static irqreturn_t adc_irq_fn(int irq, void *dev_id)
 	return IRQ_HANDLED;
 }
 
-static const struct of_device_id imx6ul_tsc_match[] = {
-	{ .compatible = "fsl,imx6ul-tsc", },
-	{ /* sentinel */ }
-};
-MODULE_DEVICE_TABLE(of, imx6ul_tsc_match);
+static int imx6ul_tsc_open(struct input_dev *input_dev)
+{
+	struct imx6ul_tsc *tsc = input_get_drvdata(input_dev);
+	int err;
+
+	err = clk_prepare_enable(tsc->adc_clk);
+	if (err) {
+		dev_err(tsc->dev,
+			"Could not prepare or enable the adc clock: %d\n",
+			err);
+		return err;
+	}
+
+	err = clk_prepare_enable(tsc->tsc_clk);
+	if (err) {
+		dev_err(tsc->dev,
+			"Could not prepare or enable the tsc clock: %d\n",
+			err);
+		clk_disable_unprepare(tsc->adc_clk);
+		return err;
+	}
+
+	imx6ul_tsc_init(tsc);
+
+	return 0;
+}
+
+static void imx6ul_tsc_close(struct input_dev *input_dev)
+{
+	struct imx6ul_tsc *tsc = input_get_drvdata(input_dev);
+
+	imx6ul_tsc_disable(tsc);
+
+	clk_disable_unprepare(tsc->tsc_clk);
+	clk_disable_unprepare(tsc->adc_clk);
+}
 
 static int imx6ul_tsc_probe(struct platform_device *pdev)
 {
+	struct device_node *np = pdev->dev.of_node;
 	struct imx6ul_tsc *tsc;
+	struct input_dev *input_dev;
 	struct resource *tsc_mem;
 	struct resource *adc_mem;
-	struct input_dev *input_dev;
-	struct device_node *np = pdev->dev.of_node;
 	int err;
 	int tsc_irq;
 	int adc_irq;
 
 	tsc = devm_kzalloc(&pdev->dev, sizeof(struct imx6ul_tsc), GFP_KERNEL);
+	if (!tsc)
+		return -ENOMEM;
+
 	input_dev = devm_input_allocate_device(&pdev->dev);
+	if (!input_dev)
+		return -ENOMEM;
 
-	tsc->dev = &pdev->dev;
+	input_dev->name = "iMX6UL TouchScreen Controller";
+	input_dev->id.bustype = BUS_HOST;
 
-	tsc->input = input_dev;
-	tsc->input->evbit[0] = BIT_MASK(EV_KEY) | BIT_MASK(EV_ABS);
-	tsc->input->keybit[BIT_WORD(BTN_TOUCH)] = BIT_MASK(BTN_TOUCH);
-	input_set_abs_params(tsc->input, ABS_X, 0, 0xFFF, 0, 0);
-	input_set_abs_params(tsc->input, ABS_Y, 0, 0xFFF, 0, 0);
+	input_dev->open = imx6ul_tsc_open;
+	input_dev->close = imx6ul_tsc_close;
 
-	tsc->input->name = "iMX6UL TouchScreen Controller";
+	input_set_capability(input_dev, EV_KEY, BTN_TOUCH);
+	input_set_abs_params(input_dev, ABS_X, 0, 0xFFF, 0, 0);
+	input_set_abs_params(input_dev, ABS_Y, 0, 0xFFF, 0, 0);
 
-	tsc->xnur_gpio = of_get_named_gpio(np, "xnur-gpio", 0);
-	err = gpio_request_one(tsc->xnur_gpio, GPIOF_IN, "tsc_X-");
-	if (err) {
-		dev_err(&pdev->dev, "failed to request GPIO tsc_X-\n");
+	input_set_drvdata(input_dev, tsc);
+
+	tsc->dev = &pdev->dev;
+	tsc->input = input_dev;
+	init_completion(&tsc->completion);
+
+	tsc->xnur_gpio = devm_gpiod_get(&pdev->dev, "xnur-gpio", GPIOD_IN);
+	if (IS_ERR(tsc->xnur_gpio)) {
+		err = PTR_ERR(tsc->xnur_gpio);
+		dev_err(&pdev->dev,
+			"failed to request GPIO tsc_X- (xnur): %d\n", err);
 		return err;
 	}
 
 	tsc_mem = platform_get_resource(pdev, IORESOURCE_MEM, 0);
 	tsc->tsc_regs = devm_ioremap_resource(&pdev->dev, tsc_mem);
 	if (IS_ERR(tsc->tsc_regs)) {
-		dev_err(&pdev->dev, "failed to remap tsc memory\n");
 		err = PTR_ERR(tsc->tsc_regs);
+		dev_err(&pdev->dev, "failed to remap tsc memory: %d\n", err);
 		return err;
 	}
 
 	adc_mem = platform_get_resource(pdev, IORESOURCE_MEM, 1);
 	tsc->adc_regs = devm_ioremap_resource(&pdev->dev, adc_mem);
 	if (IS_ERR(tsc->adc_regs)) {
-		dev_err(&pdev->dev, "failed to remap adc memory\n");
 		err = PTR_ERR(tsc->adc_regs);
+		dev_err(&pdev->dev, "failed to remap adc memory: %d\n", err);
 		return err;
 	}
 
 	tsc->tsc_clk = devm_clk_get(&pdev->dev, "tsc");
 	if (IS_ERR(tsc->tsc_clk)) {
-		dev_err(&pdev->dev, "failed getting tsc clock\n");
 		err = PTR_ERR(tsc->tsc_clk);
+		dev_err(&pdev->dev, "failed getting tsc clock: %d\n", err);
 		return err;
 	}
 
 	tsc->adc_clk = devm_clk_get(&pdev->dev, "adc");
 	if (IS_ERR(tsc->adc_clk)) {
-		dev_err(&pdev->dev, "failed getting adc clock\n");
 		err = PTR_ERR(tsc->adc_clk);
+		dev_err(&pdev->dev, "failed getting adc clock: %d\n", err);
 		return err;
 	}
 
@@ -354,111 +413,61 @@ static int imx6ul_tsc_probe(struct platform_device *pdev)
 	}
 
 	err = devm_request_threaded_irq(tsc->dev, tsc_irq,
-					NULL, tsc_irq_fn,
-					IRQF_TRIGGER_HIGH | IRQF_ONESHOT,
+					NULL, tsc_irq_fn, IRQF_ONESHOT,
 					dev_name(&pdev->dev), tsc);
-	if (err < 0) {
+	if (err) {
 		dev_err(&pdev->dev,
-			"failed requesting tsc irq %d\n",
-					    tsc_irq);
+			"failed requesting tsc irq %di: %d\n",
+			tsc_irq, err);
 		return err;
 	}
 
-	err = devm_request_irq(tsc->dev, adc_irq,
-				adc_irq_fn, 0,
+	err = devm_request_irq(tsc->dev, adc_irq, adc_irq_fn, 0,
 				dev_name(&pdev->dev), tsc);
-	if (err < 0) {
+	if (err) {
 		dev_err(&pdev->dev,
-			"failed requesting adc irq %d\n",
-					    adc_irq);
+			"failed requesting adc irq %d: %d\n",
+			adc_irq, err);
 		return err;
 	}
 
 	err = of_property_read_u32(np, "measure-delay-time",
-				&tsc->measure_delay_time);
+				   &tsc->measure_delay_time);
 	if (err)
 		tsc->measure_delay_time = 0xffff;
 
 	err = of_property_read_u32(np, "pre-charge-time",
-				&tsc->pre_charge_time);
+				   &tsc->pre_charge_time);
 	if (err)
 		tsc->pre_charge_time = 0xfff;
 
-	init_completion(&tsc->completion);
-
-	err = clk_prepare_enable(tsc->adc_clk);
+	err = input_register_device(tsc->input);
 	if (err) {
 		dev_err(&pdev->dev,
-			"Could not prepare or enable the adc clock.\n");
+			"failed to register input device: %d\n", err);
 		return err;
 	}
 
-	err = clk_prepare_enable(tsc->tsc_clk);
-	if (err) {
-		dev_err(&pdev->dev,
-			"Could not prepare or enable the tsc clock.\n");
-		goto error_tsc_clk_enable;
-	}
-
-	err = input_register_device(tsc->input);
-	if (err < 0) {
-		dev_err(&pdev->dev, "failed to register input device\n");
-		err = -EIO;
-		goto err_input_register;
-	}
-
-	imx6ul_tsc_init(tsc);
-
 	platform_set_drvdata(pdev, tsc);
 	return 0;
-
-err_input_register:
-	clk_disable_unprepare(tsc->tsc_clk);
-error_tsc_clk_enable:
-	clk_disable_unprepare(tsc->adc_clk);
-
-	return err;
-}
-
-static void imx6ul_tsc_disable(struct imx6ul_tsc *tsc)
-{
-	int tsc_flow;
-	int adc_cfg;
-
-	/* TSC controller enters to idle status */
-	tsc_flow = readl(tsc->tsc_regs + REG_TSC_FLOW_CONTROL);
-	tsc_flow |= TSC_DISABLE;
-	writel(tsc_flow, tsc->tsc_regs + REG_TSC_FLOW_CONTROL);
-
-	/* ADC controller enters to stop mode */
-	adc_cfg = readl(tsc->adc_regs + REG_ADC_HC0);
-	adc_cfg |= ADC_CONV_DISABLE;
-	writel(adc_cfg, tsc->adc_regs + REG_ADC_HC0);
-}
-
-static int imx6ul_tsc_remove(struct platform_device *pdev)
-{
-	struct imx6ul_tsc *tsc = platform_get_drvdata(pdev);
-
-	imx6ul_tsc_disable(tsc);
-
-	clk_disable_unprepare(tsc->tsc_clk);
-	clk_disable_unprepare(tsc->adc_clk);
-	input_unregister_device(tsc->input);
-	kfree(tsc);
-
-	return 0;
 }
 
 static int __maybe_unused imx6ul_tsc_suspend(struct device *dev)
 {
 	struct platform_device *pdev = to_platform_device(dev);
 	struct imx6ul_tsc *tsc = platform_get_drvdata(pdev);
+	struct input_dev *input_dev = tsc->input;
 
-	imx6ul_tsc_disable(tsc);
+	mutex_lock(&input_dev->mutex);
 
-	clk_disable_unprepare(tsc->tsc_clk);
-	clk_disable_unprepare(tsc->adc_clk);
+	if (input_dev->users) {
+		imx6ul_tsc_disable(tsc);
+
+		clk_disable_unprepare(tsc->tsc_clk);
+		clk_disable_unprepare(tsc->adc_clk);
+	}
+
+	mutex_unlock(&input_dev->mutex);
 
 	return 0;
 }
@@ -467,35 +476,46 @@ static int __maybe_unused imx6ul_tsc_resume(struct device *dev)
 {
 	struct platform_device *pdev = to_platform_device(dev);
 	struct imx6ul_tsc *tsc = platform_get_drvdata(pdev);
-	int err;
+	struct input_dev *input_dev = tsc->input;
+	int retval = 0;
 
-	err = clk_prepare_enable(tsc->adc_clk);
-	if (err)
-		return err;
+	mutex_lock(&input_dev->mutex);
 
-	err = clk_prepare_enable(tsc->tsc_clk);
-	if (err) {
-		clk_disable_unprepare(tsc->adc_clk);
-		return err;
+	if (input_dev->users) {
+		retval = clk_prepare_enable(tsc->adc_clk);
+		if (retval)
+			goto out;
+
+		retval = clk_prepare_enable(tsc->tsc_clk);
+		if (retval) {
+			clk_disable_unprepare(tsc->adc_clk);
+			goto out;
+		}
+
+		imx6ul_tsc_init(tsc);
 	}
 
-	imx6ul_tsc_init(tsc);
-	return 0;
+out:
+	mutex_unlock(&input_dev->mutex);
+	return retval;
 }
 
 static SIMPLE_DEV_PM_OPS(imx6ul_tsc_pm_ops,
-			 imx6ul_tsc_suspend,
-			 imx6ul_tsc_resume);
+			 imx6ul_tsc_suspend, imx6ul_tsc_resume);
+
+static const struct of_device_id imx6ul_tsc_match[] = {
+	{ .compatible = "fsl,imx6ul-tsc", },
+	{ /* sentinel */ }
+};
+MODULE_DEVICE_TABLE(of, imx6ul_tsc_match);
 
 static struct platform_driver imx6ul_tsc_driver = {
 	.driver		= {
 		.name	= "imx6ul-tsc",
-		.owner	= THIS_MODULE,
 		.of_match_table	= imx6ul_tsc_match,
 		.pm	= &imx6ul_tsc_pm_ops,
 	},
 	.probe		= imx6ul_tsc_probe,
-	.remove		= imx6ul_tsc_remove,
 };
 module_platform_driver(imx6ul_tsc_driver);
 


From b38611 at freescale.com  Tue Aug 18 22:33:58 2015
From: b38611 at freescale.com (Fugang Duan)
Date: Wed, 19 Aug 2015 13:33:58 +0800
Subject: [PATCH v1 0/6] Add fec1 and fec2 support for i.MX7d sdb board
Message-ID: <1439962444-27486-1-git-send-email-b38611@freescale.com>

The patch series is to add fec support for i.MX7d sdb board. Since i.MX7d fec ip is
the same as i.MX6SX, so there have no change for driver itself.

Patch#1: add bcm54220 PHY ID entry into brcmphy.h file.
Patch#2: add new iomux-gpr file to define iomux-gpr register and field for i.MX7d.
Patch#3: i.MX7d sdb board install bcm54220 phy, i.MX7d arm2 board install AR8031 phy.
	 For the two phys, there needs extra phy setting, so package the setting to fixup.
Patch#4~6: Add fec dts node and pinmux setting in dts file.


Fugang Duan (6):
  net: phy: broadcom: add bcm54220 phy ID
  ARM: imx7d: add imx7d iomux-gpr field define
  ARM: imx: add enet init for i.MX7D platform
  ARM: dts: imx: pinfunc: add GPIO1 pin define for i.MX7d
  ARM: dts: imx7d: add fec1 and fec2 support for i.MX7d soc
  ARM: dts: imx7d-sdb: add fec1 and fec2 support

 arch/arm/boot/dts/imx7d-pinfunc.h          | 115 +++++++++++++++++++++++++++++
 arch/arm/boot/dts/imx7d-sdb.dts            |  76 ++++++++++++++++++-
 arch/arm/boot/dts/imx7d.dtsi               |  36 +++++++++
 arch/arm/mach-imx/mach-imx7d.c             |  75 ++++++++++++++++++-
 include/linux/brcmphy.h                    |   1 +
 include/linux/mfd/syscon/imx7-iomuxc-gpr.h |  49 ++++++++++++
 6 files changed, 349 insertions(+), 3 deletions(-)
 create mode 100644 include/linux/mfd/syscon/imx7-iomuxc-gpr.h

-- 
1.9.1



From b38611 at freescale.com  Tue Aug 18 22:33:59 2015
From: b38611 at freescale.com (Fugang Duan)
Date: Wed, 19 Aug 2015 13:33:59 +0800
Subject: [PATCH v1 1/6] net: phy: broadcom: add bcm54220 phy ID
In-Reply-To: <1439962444-27486-1-git-send-email-b38611@freescale.com>
References: <1439962444-27486-1-git-send-email-b38611@freescale.com>
Message-ID: <1439962444-27486-2-git-send-email-b38611@freescale.com>

Add bcm54220 phy ID entry.

Signed-off-by: Fugang Duan <B38611 at freescale.com>
---
 include/linux/brcmphy.h | 1 +
 1 file changed, 1 insertion(+)

diff --git a/include/linux/brcmphy.h b/include/linux/brcmphy.h
index 697ca77..20bed15 100644
--- a/include/linux/brcmphy.h
+++ b/include/linux/brcmphy.h
@@ -16,6 +16,7 @@
 #define PHY_ID_BCM5482			0x0143bcb0
 #define PHY_ID_BCM5411			0x00206070
 #define PHY_ID_BCM5421			0x002060e0
+#define PHY_ID_BCM54220			0x600d8589
 #define PHY_ID_BCM5464			0x002060b0
 #define PHY_ID_BCM5461			0x002060c0
 #define PHY_ID_BCM54616S		0x03625d10
-- 
1.9.1



From b38611 at freescale.com  Tue Aug 18 22:34:00 2015
From: b38611 at freescale.com (Fugang Duan)
Date: Wed, 19 Aug 2015 13:34:00 +0800
Subject: [PATCH v1 2/6] ARM: imx7d: add imx7d iomux-gpr field define
In-Reply-To: <1439962444-27486-1-git-send-email-b38611@freescale.com>
References: <1439962444-27486-1-git-send-email-b38611@freescale.com>
Message-ID: <1439962444-27486-3-git-send-email-b38611@freescale.com>

Add imx7d iomux-gpr field define.

Signed-off-by: Fugang Duan <B38611 at freescale.com>
---
 include/linux/mfd/syscon/imx7-iomuxc-gpr.h | 49 ++++++++++++++++++++++++++++++
 1 file changed, 49 insertions(+)

diff --git a/include/linux/mfd/syscon/imx7-iomuxc-gpr.h b/include/linux/mfd/syscon/imx7-iomuxc-gpr.h
new file mode 100644
index 0000000..5cc0553
--- /dev/null
+++ b/include/linux/mfd/syscon/imx7-iomuxc-gpr.h
@@ -0,0 +1,49 @@
+/*
+ * Copyright (C) 2015 Freescale Semiconductor, Inc.
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License version 2 as
+ * published by the Free Software Foundation.
+ */
+
+#ifndef __LINUX_IMX7_IOMUXC_GPR_H
+#define __LINUX_IMX7_IOMUXC_GPR_H
+
+#include <linux/bitops.h>
+
+#define IOMUXC_GPR0	0x00
+#define IOMUXC_GPR1	0x04
+#define IOMUXC_GPR2	0x08
+#define IOMUXC_GPR3	0x0c
+#define IOMUXC_GPR4	0x10
+#define IOMUXC_GPR5	0x14
+#define IOMUXC_GPR6	0x18
+#define IOMUXC_GPR7	0x1c
+#define IOMUXC_GPR8	0x20
+#define IOMUXC_GPR9	0x24
+#define IOMUXC_GPR10	0x28
+#define IOMUXC_GPR11	0x2c
+#define IOMUXC_GPR12	0x30
+#define IOMUXC_GPR13	0x34
+#define IOMUXC_GPR14	0x38
+#define IOMUXC_GPR15	0x3c
+#define IOMUXC_GPR16	0x40
+#define IOMUXC_GPR17	0x44
+#define IOMUXC_GPR18	0x48
+#define IOMUXC_GPR19	0x4c
+#define IOMUXC_GPR20	0x50
+#define IOMUXC_GPR21	0x54
+#define IOMUXC_GPR22	0x58
+
+/* For imx7d iomux gpr register field define */
+#define IMX7D_GPR1_IRQ_MASK			(0x1 << 12)
+#define IMX7D_GPR1_ENET1_TX_CLK_SEL_MASK	(0x1 << 13)
+#define IMX7D_GPR1_ENET2_TX_CLK_SEL_MASK	(0x1 << 14)
+#define IMX7D_GPR1_ENET_TX_CLK_SEL_MASK		(0x3 << 13)
+#define IMX7D_GPR1_ENET1_CLK_DIR_MASK		(0x1 << 17)
+#define IMX7D_GPR1_ENET2_CLK_DIR_MASK		(0x1 << 18)
+#define IMX7D_GPR1_ENET_CLK_DIR_MASK		(0x3 << 17)
+
+#define IMX7D_GPR5_CSI_MUX_CONTROL_MIPI		(0x1 << 4)
+
+#endif /* __LINUX_IMX7_IOMUXC_GPR_H */
-- 
1.9.1



From b38611 at freescale.com  Tue Aug 18 22:34:01 2015
From: b38611 at freescale.com (Fugang Duan)
Date: Wed, 19 Aug 2015 13:34:01 +0800
Subject: [PATCH v1 3/6] ARM: imx: add enet init for i.MX7D platform
In-Reply-To: <1439962444-27486-1-git-send-email-b38611@freescale.com>
References: <1439962444-27486-1-git-send-email-b38611@freescale.com>
Message-ID: <1439962444-27486-4-git-send-email-b38611@freescale.com>

Add enet phy fixup, clock source init for i.MX7D platform.

Signed-off-by: Fugang Duan <B38611 at freescale.com>
---
 arch/arm/mach-imx/mach-imx7d.c | 75 ++++++++++++++++++++++++++++++++++++++++--
 1 file changed, 73 insertions(+), 2 deletions(-)

diff --git a/arch/arm/mach-imx/mach-imx7d.c b/arch/arm/mach-imx/mach-imx7d.c
index 4d4a190..67d7939 100644
--- a/arch/arm/mach-imx/mach-imx7d.c
+++ b/arch/arm/mach-imx/mach-imx7d.c
@@ -5,13 +5,83 @@
  * it under the terms of the GNU General Public License version 2 as
  * published by the Free Software Foundation.
  */
-#include <linux/irqchip.h>
-#include <linux/of_platform.h>
 #include <asm/mach/arch.h>
 #include <asm/mach/map.h>
+#include <linux/brcmphy.h>
+#include <linux/irqchip.h>
+#include <linux/mfd/syscon.h>
+#include <linux/mfd/syscon/imx7-iomuxc-gpr.h>
+#include <linux/of_platform.h>
+#include <linux/regmap.h>
 
 #include "common.h"
 
+static int ar8031_phy_fixup(struct phy_device *dev)
+{
+	u16 val;
+
+	/* Set RGMII IO voltage to 1.8V */
+	phy_write(dev, 0x1d, 0x1f);
+	phy_write(dev, 0x1e, 0x8);
+
+	/* disable phy AR8031 SmartEEE function. */
+	phy_write(dev, 0xd, 0x3);
+	phy_write(dev, 0xe, 0x805d);
+	phy_write(dev, 0xd, 0x4003);
+	val = phy_read(dev, 0xe);
+	val &= ~(0x1 << 8);
+	phy_write(dev, 0xe, val);
+
+	/* introduce tx clock delay */
+	phy_write(dev, 0x1d, 0x5);
+	val = phy_read(dev, 0x1e);
+	val |= 0x0100;
+	phy_write(dev, 0x1e, val);
+
+	return 0;
+}
+
+static int bcm54220_phy_fixup(struct phy_device *dev)
+{
+	/* enable RXC skew select RGMII copper mode */
+	phy_write(dev, 0x1e, 0x21);
+	phy_write(dev, 0x1f, 0x7ea8);
+	phy_write(dev, 0x1e, 0x2f);
+	phy_write(dev, 0x1f, 0x71b7);
+
+	return 0;
+}
+
+#define PHY_ID_AR8031   0x004dd074
+static void __init imx7d_enet_phy_init(void)
+{
+	if (IS_BUILTIN(CONFIG_PHYLIB)) {
+		phy_register_fixup_for_uid(PHY_ID_AR8031, 0xffffffff,
+					   ar8031_phy_fixup);
+		phy_register_fixup_for_uid(PHY_ID_BCM54220, 0xffffffff,
+					   bcm54220_phy_fixup);
+	}
+}
+
+static void __init imx7d_enet_clk_sel(void)
+{
+	struct regmap *gpr;
+
+	gpr = syscon_regmap_lookup_by_compatible("fsl,imx7d-iomuxc-gpr");
+	if (!IS_ERR(gpr)) {
+		regmap_update_bits(gpr, IOMUXC_GPR1, IMX7D_GPR1_ENET_TX_CLK_SEL_MASK, 0);
+		regmap_update_bits(gpr, IOMUXC_GPR1, IMX7D_GPR1_ENET_CLK_DIR_MASK, 0);
+	} else {
+		pr_err("failed to find fsl,imx7d-iomux-gpr regmap\n");
+	}
+}
+
+static inline void imx7d_enet_init(void)
+{
+	imx7d_enet_phy_init();
+	imx7d_enet_clk_sel();
+}
+
 static void __init imx7d_init_machine(void)
 {
 	struct device *parent;
@@ -22,6 +92,7 @@ static void __init imx7d_init_machine(void)
 
 	of_platform_populate(NULL, of_default_bus_match_table, NULL, NULL);
 	imx_anatop_init();
+	imx7d_enet_init();
 }
 
 static void __init imx7d_init_irq(void)
-- 
1.9.1



From b38611 at freescale.com  Tue Aug 18 22:34:03 2015
From: b38611 at freescale.com (Fugang Duan)
Date: Wed, 19 Aug 2015 13:34:03 +0800
Subject: [PATCH v1 5/6] ARM: dts: imx7d: add fec1 and fec2 support for i.MX7d
 soc
In-Reply-To: <1439962444-27486-1-git-send-email-b38611@freescale.com>
References: <1439962444-27486-1-git-send-email-b38611@freescale.com>
Message-ID: <1439962444-27486-6-git-send-email-b38611@freescale.com>

Add fec1 and fec2 nodes for i.MX7d soc.

Signed-off-by: Fugang Duan <B38611 at freescale.com>
---
 arch/arm/boot/dts/imx7d.dtsi | 36 ++++++++++++++++++++++++++++++++++++
 1 file changed, 36 insertions(+)

diff --git a/arch/arm/boot/dts/imx7d.dtsi b/arch/arm/boot/dts/imx7d.dtsi
index b738ce0..7631492 100644
--- a/arch/arm/boot/dts/imx7d.dtsi
+++ b/arch/arm/boot/dts/imx7d.dtsi
@@ -729,6 +729,42 @@
 				bus-width = <4>;
 				status = "disabled";
 			};
+
+			fec1: ethernet at 30be0000 {
+				compatible = "fsl,imx7d-fec", "fsl,imx6sx-fec";
+				reg = <0x30be0000 0x10000>;
+				interrupts = <GIC_SPI 118 IRQ_TYPE_LEVEL_HIGH>,
+					<GIC_SPI 119 IRQ_TYPE_LEVEL_HIGH>,
+					<GIC_SPI 120 IRQ_TYPE_LEVEL_HIGH>;
+				clocks = <&clks IMX7D_ENET_AXI_ROOT_CLK>,
+					<&clks IMX7D_ENET_AXI_ROOT_CLK>,
+					<&clks IMX7D_ENET1_TIME_ROOT_CLK>,
+					<&clks IMX7D_PLL_ENET_MAIN_125M_CLK>,
+					<&clks IMX7D_ENET_PHY_REF_ROOT_CLK>;
+				clock-names = "ipg", "ahb", "ptp",
+					"enet_clk_ref", "enet_out";
+				fsl,num-tx-queues=<3>;
+				fsl,num-rx-queues=<3>;
+				status = "disabled";
+			};
+
+			fec2: ethernet at 30bf0000 {
+				compatible = "fsl,imx7d-fec", "fsl,imx6sx-fec";
+				reg = <0x30bf0000 0x10000>;
+				interrupts = <GIC_SPI 100 IRQ_TYPE_LEVEL_HIGH>,
+					<GIC_SPI 101 IRQ_TYPE_LEVEL_HIGH>,
+					<GIC_SPI 102 IRQ_TYPE_LEVEL_HIGH>;
+				clocks = <&clks IMX7D_ENET_AXI_ROOT_CLK>,
+					<&clks IMX7D_ENET_AXI_ROOT_CLK>,
+					<&clks IMX7D_ENET2_TIME_ROOT_CLK>,
+					<&clks IMX7D_PLL_ENET_MAIN_125M_CLK>,
+					<&clks IMX7D_ENET_PHY_REF_ROOT_CLK>;
+				clock-names = "ipg", "ahb", "ptp",
+					"enet_clk_ref", "enet_out";
+				fsl,num-tx-queues=<3>;
+				fsl,num-rx-queues=<3>;
+				status = "disabled";
+			};
 		};
 	};
 };
-- 
1.9.1



From b38611 at freescale.com  Tue Aug 18 22:34:02 2015
From: b38611 at freescale.com (Fugang Duan)
Date: Wed, 19 Aug 2015 13:34:02 +0800
Subject: [PATCH v1 4/6] ARM: dts: imx: pinfunc: add GPIO1 pin define for i.MX7d
In-Reply-To: <1439962444-27486-1-git-send-email-b38611@freescale.com>
References: <1439962444-27486-1-git-send-email-b38611@freescale.com>
Message-ID: <1439962444-27486-5-git-send-email-b38611@freescale.com>

Add GPIO1 pin define for i.MX7d.

Signed-off-by: Fugang Duan <B38611 at freescale.com>
---
 arch/arm/boot/dts/imx7d-pinfunc.h | 115 ++++++++++++++++++++++++++++++++++++++
 1 file changed, 115 insertions(+)

diff --git a/arch/arm/boot/dts/imx7d-pinfunc.h b/arch/arm/boot/dts/imx7d-pinfunc.h
index a8d8149..8b3cf2bc 100644
--- a/arch/arm/boot/dts/imx7d-pinfunc.h
+++ b/arch/arm/boot/dts/imx7d-pinfunc.h
@@ -15,6 +15,121 @@
  * <mux_reg conf_reg input_reg mux_mode input_val>
  */
 
+#define MX7D_PAD_GPIO1_IO00__GPIO1_IO0				  0x0000 0x0030 0x0000 0x0 0x0
+#define MX7D_PAD_GPIO1_IO00__PWM4_OUT				  0x0000 0x0030 0x0000 0x1 0x0
+#define MX7D_PAD_GPIO1_IO00__WDOD1_WDOG_ANY			  0x0000 0x0030 0x0000 0x2 0x0
+#define MX7D_PAD_GPIO1_IO00__WDOD1_WDOG_B			  0x0000 0x0030 0x0000 0x3 0x0
+#define MX7D_PAD_GPIO1_IO00__WDOD1_WDOG__RST_B_DEB		  0x0000 0x0030 0x0000 0x4 0x0
+#define MX7D_PAD_GPIO1_IO01__GPIO1_IO1				  0x0004 0x0034 0x0000 0x0 0x0
+#define MX7D_PAD_GPIO1_IO01__PWM1_OUT				  0x0004 0x0034 0x0000 0x1 0x0
+#define MX7D_PAD_GPIO1_IO01__CCM_ENET_REF_CLK3			  0x0004 0x0034 0x0000 0x2 0x0
+#define MX7D_PAD_GPIO1_IO01__SAI1_MCLK				  0x0004 0x0034 0x0000 0x3 0x0
+#define MX7D_PAD_GPIO1_IO01__OBSERVE0_OUT			  0x0004 0x0034 0x0000 0x6 0x0
+#define MX7D_PAD_GPIO1_IO02__GPIO1_IO2				  0x0008 0x0038 0x0000 0x0 0x0
+#define MX7D_PAD_GPIO1_IO02__PWM2_OUT				  0x0008 0x0038 0x0000 0x1 0x0
+#define MX7D_PAD_GPIO1_IO02__CCM_ENET_REF_CLK1			  0x0008 0x0038 0x0564 0x2 0x3
+#define MX7D_PAD_GPIO1_IO02__SAI2_MCLK				  0x0008 0x0038 0x0000 0x3 0x0
+#define MX7D_PAD_GPIO1_IO02__CCM_CLKO1				  0x0008 0x0038 0x0000 0x5 0x0
+#define MX7D_PAD_GPIO1_IO02__OBSERVE1_OUT			  0x0008 0x0038 0x0000 0x6 0x0
+#define MX7D_PAD_GPIO1_IO02__USB_OTG1_ID			  0x0008 0x0038 0x0734 0x7 0x3
+#define MX7D_PAD_GPIO1_IO03__GPIO1_IO3				  0x000C 0x003C 0x0000 0x0 0x0
+#define MX7D_PAD_GPIO1_IO03__PWM3_OUT				  0x000C 0x003C 0x0000 0x1 0x0
+#define MX7D_PAD_GPIO1_IO03__CCM_ENET_REF_CLK2			  0x000C 0x003C 0x0570 0x2 0x3
+#define MX7D_PAD_GPIO1_IO03__SAI3_MCLK				  0x000C 0x003C 0x0000 0x3 0x0
+#define MX7D_PAD_GPIO1_IO03__CCM_CLKO2				  0x000C 0x003C 0x0000 0x5 0x0
+#define MX7D_PAD_GPIO1_IO03__OBSERVE2_OUT			  0x000C 0x003C 0x0000 0x6 0x0
+#define MX7D_PAD_GPIO1_IO03__USB_OTG2_ID			  0x000C 0x003C 0x0730 0x7 0x3
+#define MX7D_PAD_GPIO1_IO04__GPIO1_IO4				  0x0010 0x0040 0x0000 0x0 0x0
+#define MX7D_PAD_GPIO1_IO04__USB_OTG1_OC			  0x0010 0x0040 0x072C 0x1 0x1
+#define MX7D_PAD_GPIO1_IO04__FLEXTIMER1_CH4			  0x0010 0x0040 0x0594 0x2 0x1
+#define MX7D_PAD_GPIO1_IO04__UART5_CTS_B			  0x0010 0x0040 0x0710 0x3 0x4
+#define MX7D_PAD_GPIO1_IO04__I2C1_SCL				  0x0010 0x0040 0x05D4 0x4 0x2
+#define MX7D_PAD_GPIO1_IO04__OBSERVE3_OUT			  0x0010 0x0040 0x0000 0x6 0x0
+#define MX7D_PAD_GPIO1_IO05__GPIO1_IO5				  0x0014 0x0044 0x0000 0x0 0x0
+#define MX7D_PAD_GPIO1_IO05__USB_OTG1_PWR			  0x0014 0x0044 0x0000 0x1 0x0
+#define MX7D_PAD_GPIO1_IO05__FLEXTIMER1_CH5			  0x0014 0x0044 0x0598 0x2 0x1
+#define MX7D_PAD_GPIO1_IO05__UART5_RTS_B			  0x0014 0x0044 0x0710 0x3 0x5
+#define MX7D_PAD_GPIO1_IO05__I2C1_SDA				  0x0014 0x0044 0x05D8 0x4 0x2
+#define MX7D_PAD_GPIO1_IO05__OBSERVE4_OUT			  0x0014 0x0044 0x0000 0x6 0x0
+#define MX7D_PAD_GPIO1_IO06__GPIO1_IO6				  0x0018 0x0048 0x0000 0x0 0x0
+#define MX7D_PAD_GPIO1_IO06__USB_OTG2_OC			  0x0018 0x0048 0x0728 0x1 0x1
+#define MX7D_PAD_GPIO1_IO06__FLEXTIMER1_CH6			  0x0018 0x0048 0x059C 0x2 0x1
+#define MX7D_PAD_GPIO1_IO06__UART5_RX_DATA			  0x0018 0x0048 0x0714 0x3 0x4
+#define MX7D_PAD_GPIO1_IO06__I2C2_SCL				  0x0018 0x0048 0x05DC 0x4 0x2
+#define MX7D_PAD_GPIO1_IO06__CCM_WAIT				  0x0018 0x0048 0x0000 0x5 0x0
+#define MX7D_PAD_GPIO1_IO06__KPP_ROW4				  0x0018 0x0048 0x0624 0x6 0x1
+#define MX7D_PAD_GPIO1_IO07__GPIO1_IO7				  0x001C 0x004C 0x0000 0x0 0x0
+#define MX7D_PAD_GPIO1_IO07__USB_OTG2_PWR			  0x001C 0x004C 0x0000 0x1 0x0
+#define MX7D_PAD_GPIO1_IO07__FLEXTIMER1_CH7			  0x001C 0x004C 0x05A0 0x2 0x1
+#define MX7D_PAD_GPIO1_IO07__UART5_TX_DATA			  0x001C 0x004C 0x0714 0x3 0x5
+#define MX7D_PAD_GPIO1_IO07__I2C2_SDA				  0x001C 0x004C 0x05E0 0x4 0x2
+#define MX7D_PAD_GPIO1_IO07__CCM_STOP				  0x001C 0x004C 0x0000 0x5 0x0
+#define MX7D_PAD_GPIO1_IO07__KPP_COL4				  0x001C 0x004C 0x0604 0x6 0x1
+#define MX7D_PAD_GPIO1_IO08__GPIO1_IO8                            0x0014 0x026C 0x0000 0x0 0x0
+#define MX7D_PAD_GPIO1_IO08__SD1_VSELECT                          0x0014 0x026C 0x0000 0x1 0x0
+#define MX7D_PAD_GPIO1_IO08__WDOG1_WDOG_B                         0x0014 0x026C 0x0000 0x2 0x0
+#define MX7D_PAD_GPIO1_IO08__UART3_DCE_RX                         0x0014 0x026C 0x0704 0x3 0x0
+#define MX7D_PAD_GPIO1_IO08__UART3_DTE_TX                         0x0014 0x026C 0x0000 0x3 0x0
+#define MX7D_PAD_GPIO1_IO08__I2C3_SCL                             0x0014 0x026C 0x05E4 0x4 0x0
+#define MX7D_PAD_GPIO1_IO08__KPP_COL5                             0x0014 0x026C 0x0608 0x6 0x0
+#define MX7D_PAD_GPIO1_IO08__PWM1_OUT                             0x0014 0x026C 0x0000 0x7 0x0
+#define MX7D_PAD_GPIO1_IO09__GPIO1_IO9                            0x0018 0x0270 0x0000 0x0 0x0
+#define MX7D_PAD_GPIO1_IO09__SD1_LCTL                             0x0018 0x0270 0x0000 0x1 0x0
+#define MX7D_PAD_GPIO1_IO09__CCM_ENET_REF_CLK3                    0x0018 0x0270 0x0000 0x2 0x0
+#define MX7D_PAD_GPIO1_IO09__UART3_DCE_TX                         0x0018 0x0270 0x0000 0x3 0x0
+#define MX7D_PAD_GPIO1_IO09__UART3_DTE_RX                         0x0018 0x0270 0x0704 0x3 0x1
+#define MX7D_PAD_GPIO1_IO09__I2C3_SDA                             0x0018 0x0270 0x05E8 0x4 0x0
+#define MX7D_PAD_GPIO1_IO09__CCM_PMIC_READY                       0x0018 0x0270 0x04F4 0x5 0x0
+#define MX7D_PAD_GPIO1_IO09__KPP_ROW5                             0x0018 0x0270 0x0628 0x6 0x0
+#define MX7D_PAD_GPIO1_IO09__PWM2_OUT                             0x0018 0x0270 0x0000 0x7 0x0
+#define MX7D_PAD_GPIO1_IO10__GPIO1_IO10                           0x001C 0x0274 0x0000 0x0 0x0
+#define MX7D_PAD_GPIO1_IO10__SD2_LCTL                             0x001C 0x0274 0x0000 0x1 0x0
+#define MX7D_PAD_GPIO1_IO10__ENET1_MDIO                           0x001C 0x0274 0x0568 0x2 0x0
+#define MX7D_PAD_GPIO1_IO10__UART3_DCE_RTS                        0x001C 0x0274 0x0700 0x3 0x0
+#define MX7D_PAD_GPIO1_IO10__UART3_DTE_CTS                        0x001C 0x0274 0x0000 0x3 0x0
+#define MX7D_PAD_GPIO1_IO10__I2C4_SCL                             0x001C 0x0274 0x05EC 0x4 0x0
+#define MX7D_PAD_GPIO1_IO10__FLEXTIMER1_PHA                       0x001C 0x0274 0x05A4 0x5 0x0
+#define MX7D_PAD_GPIO1_IO10__KPP_COL6                             0x001C 0x0274 0x060C 0x6 0x0
+#define MX7D_PAD_GPIO1_IO10__PWM3_OUT                             0x001C 0x0274 0x0000 0x7 0x0
+#define MX7D_PAD_GPIO1_IO11__GPIO1_IO11                           0x0020 0x0278 0x0000 0x0 0x0
+#define MX7D_PAD_GPIO1_IO11__SD3_LCTL                             0x0020 0x0278 0x0000 0x1 0x0
+#define MX7D_PAD_GPIO1_IO11__ENET1_MDC                            0x0020 0x0278 0x0000 0x2 0x0
+#define MX7D_PAD_GPIO1_IO11__UART3_DCE_CTS                        0x0020 0x0278 0x0000 0x3 0x0
+#define MX7D_PAD_GPIO1_IO11__UART3_DTE_RTS                        0x0020 0x0278 0x0700 0x3 0x1
+#define MX7D_PAD_GPIO1_IO11__I2C4_SDA                             0x0020 0x0278 0x05F0 0x4 0x0
+#define MX7D_PAD_GPIO1_IO11__FLEXTIMER1_PHB                       0x0020 0x0278 0x05A8 0x5 0x0
+#define MX7D_PAD_GPIO1_IO11__KPP_ROW6                             0x0020 0x0278 0x062C 0x6 0x0
+#define MX7D_PAD_GPIO1_IO11__PWM4_OUT                             0x0020 0x0278 0x0000 0x7 0x0
+#define MX7D_PAD_GPIO1_IO12__GPIO1_IO12                           0x0024 0x027C 0x0000 0x0 0x0
+#define MX7D_PAD_GPIO1_IO12__SD2_VSELECT                          0x0024 0x027C 0x0000 0x1 0x0
+#define MX7D_PAD_GPIO1_IO12__CCM_ENET_REF_CLK1                    0x0024 0x027C 0x0564 0x2 0x0
+#define MX7D_PAD_GPIO1_IO12__FLEXCAN1_RX                          0x0024 0x027C 0x04DC 0x3 0x0
+#define MX7D_PAD_GPIO1_IO12__CM4_NMI                              0x0024 0x027C 0x0000 0x4 0x0
+#define MX7D_PAD_GPIO1_IO12__CCM_EXT_CLK1                         0x0024 0x027C 0x04E4 0x5 0x0
+#define MX7D_PAD_GPIO1_IO12__SNVS_VIO_5                           0x0024 0x027C 0x0000 0x6 0x0
+#define MX7D_PAD_GPIO1_IO12__USB_OTG1_ID                          0x0024 0x027C 0x0734 0x7 0x0
+#define MX7D_PAD_GPIO1_IO13__GPIO1_IO13                           0x0028 0x0280 0x0000 0x0 0x0
+#define MX7D_PAD_GPIO1_IO13__SD3_VSELECT                          0x0028 0x0280 0x0000 0x1 0x0
+#define MX7D_PAD_GPIO1_IO13__CCM_ENET_REF_CLK2                    0x0028 0x0280 0x0570 0x2 0x0
+#define MX7D_PAD_GPIO1_IO13__FLEXCAN1_TX                          0x0028 0x0280 0x0000 0x3 0x0
+#define MX7D_PAD_GPIO1_IO13__CCM_PMIC_READY                       0x0028 0x0280 0x04F4 0x4 0x1
+#define MX7D_PAD_GPIO1_IO13__CCM_EXT_CLK2                         0x0028 0x0280 0x04E8 0x5 0x0
+#define MX7D_PAD_GPIO1_IO13__SNVS_VIO_5_CTL                       0x0028 0x0280 0x0000 0x6 0x0
+#define MX7D_PAD_GPIO1_IO13__USB_OTG2_ID                          0x0028 0x0280 0x0730 0x7 0x0
+#define MX7D_PAD_GPIO1_IO14__GPIO1_IO14                           0x002C 0x0284 0x0000 0x0 0x0
+#define MX7D_PAD_GPIO1_IO14__SD3_CD_B                             0x002C 0x0284 0x0738 0x1 0x0
+#define MX7D_PAD_GPIO1_IO14__ENET2_MDIO                           0x002C 0x0284 0x0574 0x2 0x0
+#define MX7D_PAD_GPIO1_IO14__FLEXCAN2_RX                          0x002C 0x0284 0x04E0 0x3 0x0
+#define MX7D_PAD_GPIO1_IO14__WDOG3_WDOG_B                         0x002C 0x0284 0x0000 0x4 0x0
+#define MX7D_PAD_GPIO1_IO14__CCM_EXT_CLK3                         0x002C 0x0284 0x04EC 0x5 0x0
+#define MX7D_PAD_GPIO1_IO14__SDMA_EXT_EVENT0                      0x002C 0x0284 0x06D8 0x6 0x0
+#define MX7D_PAD_GPIO1_IO15__GPIO1_IO15                           0x0030 0x0288 0x0000 0x0 0x0
+#define MX7D_PAD_GPIO1_IO15__SD3_WP                               0x0030 0x0288 0x073C 0x1 0x0
+#define MX7D_PAD_GPIO1_IO15__ENET2_MDC                            0x0030 0x0288 0x0000 0x2 0x0
+#define MX7D_PAD_GPIO1_IO15__FLEXCAN2_TX                          0x0030 0x0288 0x0000 0x3 0x0
+#define MX7D_PAD_GPIO1_IO15__WDOG4_WDOG_B                         0x0030 0x0288 0x0000 0x4 0x0
+#define MX7D_PAD_GPIO1_IO15__CCM_EXT_CLK4                         0x0030 0x0288 0x04F0 0x5 0x0
+#define MX7D_PAD_GPIO1_IO15__SDMA_EXT_EVENT1                      0x0030 0x0288 0x06DC 0x6 0x0
 #define MX7D_PAD_EPDC_DATA00__EPDC_DATA0                          0x0034 0x02A4 0x0000 0x0 0x0
 #define MX7D_PAD_EPDC_DATA00__SIM1_PORT2_TRXD                     0x0034 0x02A4 0x0000 0x1 0x0
 #define MX7D_PAD_EPDC_DATA00__QSPI_A_DATA0                        0x0034 0x02A4 0x0000 0x2 0x0
-- 
1.9.1



From viresh.kumar at linaro.org  Tue Aug 18 22:41:20 2015
From: viresh.kumar at linaro.org (Viresh Kumar)
Date: Wed, 19 Aug 2015 11:11:20 +0530
Subject: [PATCH v7 2/3] cpufreq: mediatek: Add MT8173 cpufreq driver
In-Reply-To: <1439949906-22177-1-git-send-email-pi-cheng.chen@linaro.org>
References: <20150818102428.GD31148@linux>
 <1439949906-22177-1-git-send-email-pi-cheng.chen@linaro.org>
Message-ID: <20150819054120.GA3258@linux>

On 19-08-15, 10:05, Pi-Cheng Chen wrote:
> Mediatek MT8173 is an ARMv8 based quad-core (2*Cortex-A53 and
> 2*Cortex-A72) SoC with duall clusters. For each cluster, two voltage
> inputs, Vproc and Vsram are supplied by two regulators. For the big
> cluster, two regulators come from different PMICs. In this case, when
> scaling voltage inputs of the cluster, the voltages of two regulator
> inputs need to be controlled by software explicitly under the SoC
> specific limitation:
> 
> 	100mV < Vsram - Vproc < 200mV
> 
> which is called 'voltage tracking' mechanism. And when scaling the
> frequency of cluster clock input, the input MUX need to be parented to
> another "intermediate" stable PLL first and reparented to the original
> PLL once the original PLL is stable at the target frequency. This patch
> implements those mechanisms to enable CPU DVFS support for Mediatek
> MT8173 SoC.
> 
> Signed-off-by: Pi-Cheng Chen <pi-cheng.chen at linaro.org>
> Acked-by: Viresh Kumar <viresh.kumar at linaro.org>
> ---
> 
> Changes in v7:
> - add of_machine_is_compatible() check to be multiplatform friendly

Looks fine, thanks.

-- 
viresh


From yamada.masahiro at socionext.com  Tue Aug 18 22:45:47 2015
From: yamada.masahiro at socionext.com (Masahiro Yamada)
Date: Wed, 19 Aug 2015 14:45:47 +0900
Subject: [PATCH] ARM: dts: UniPhier: fix PPI interrupt CPU mask of timer nodes
Message-ID: <1439963147-2592-1-git-send-email-yamada.masahiro@socionext.com>

This SoC is integrated with 4 Cortex-A9 cores.  The GIC bindings
says that the bits[15:8] of the 3rd cell of the interrupts property
represents PPI interrupt CPU mask.  Because the timer interrupts are
wired to all of the 4 cores, bits[15:8] should be set to 0xf.

Signed-off-by: Masahiro Yamada <yamada.masahiro at socionext.com>
---

 arch/arm/boot/dts/uniphier-proxstream2.dtsi | 4 ++--
 1 file changed, 2 insertions(+), 2 deletions(-)

diff --git a/arch/arm/boot/dts/uniphier-proxstream2.dtsi b/arch/arm/boot/dts/uniphier-proxstream2.dtsi
index ccf795a..4c7b246 100644
--- a/arch/arm/boot/dts/uniphier-proxstream2.dtsi
+++ b/arch/arm/boot/dts/uniphier-proxstream2.dtsi
@@ -249,14 +249,14 @@
 		timer at 60000200 {
 			compatible = "arm,cortex-a9-global-timer";
 			reg = <0x60000200 0x20>;
-			interrupts = <1 11 0x304>;
+			interrupts = <1 11 0xf04>;
 			clocks = <&arm_timer_clk>;
 		};
 
 		timer at 60000600 {
 			compatible = "arm,cortex-a9-twd-timer";
 			reg = <0x60000600 0x20>;
-			interrupts = <1 13 0x304>;
+			interrupts = <1 13 0xf04>;
 			clocks = <&arm_timer_clk>;
 		};
 
-- 
1.9.1



From yamada.masahiro at socionext.com  Tue Aug 18 22:49:26 2015
From: yamada.masahiro at socionext.com (Masahiro Yamada)
Date: Wed, 19 Aug 2015 14:49:26 +0900
Subject: [PATCH v2] ARM: dts: UniPhier: fix PPI interrupt CPU mask of timer
 nodes
Message-ID: <1439963366-4848-1-git-send-email-yamada.masahiro@socionext.com>

This SoC is integrated with 4 Cortex-A9 cores.  The GIC bindings
document says that the bits[15:8] of the 3rd cell of the interrupts
property represents PPI interrupt CPU mask.  Because the timer
interrupts are wired to all of the 4 cores, bits[15:8] should be set
to 0xf.

Signed-off-by: Masahiro Yamada <yamada.masahiro at socionext.com>
---

Changes in v2:
  - Fix git-description

 arch/arm/boot/dts/uniphier-proxstream2.dtsi | 4 ++--
 1 file changed, 2 insertions(+), 2 deletions(-)

diff --git a/arch/arm/boot/dts/uniphier-proxstream2.dtsi b/arch/arm/boot/dts/uniphier-proxstream2.dtsi
index ccf795a..4c7b246 100644
--- a/arch/arm/boot/dts/uniphier-proxstream2.dtsi
+++ b/arch/arm/boot/dts/uniphier-proxstream2.dtsi
@@ -249,14 +249,14 @@
 		timer at 60000200 {
 			compatible = "arm,cortex-a9-global-timer";
 			reg = <0x60000200 0x20>;
-			interrupts = <1 11 0x304>;
+			interrupts = <1 11 0xf04>;
 			clocks = <&arm_timer_clk>;
 		};
 
 		timer at 60000600 {
 			compatible = "arm,cortex-a9-twd-timer";
 			reg = <0x60000600 0x20>;
-			interrupts = <1 13 0x304>;
+			interrupts = <1 13 0xf04>;
 			clocks = <&arm_timer_clk>;
 		};
 
-- 
1.9.1



From yamada.masahiro at socionext.com  Tue Aug 18 22:50:25 2015
From: yamada.masahiro at socionext.com (Masahiro Yamada)
Date: Wed, 19 Aug 2015 14:50:25 +0900
Subject: [PATCH] ARM: dts: UniPhier: fix PPI interrupt CPU mask of timer
 nodes
In-Reply-To: <1439963147-2592-1-git-send-email-yamada.masahiro@socionext.com>
References: <1439963147-2592-1-git-send-email-yamada.masahiro@socionext.com>
Message-ID: <CAK7LNATCmyO=Ys_cVJ3sox7Dn+qfKAMyxnBAEXVgZN58ApkDEQ@mail.gmail.com>

2015-08-19 14:45 GMT+09:00 Masahiro Yamada <yamada.masahiro at socionext.com>:
> This SoC is integrated with 4 Cortex-A9 cores.  The GIC bindings
> says that the bits[15:8] of the 3rd cell of the interrupts property
> represents PPI interrupt CPU mask.  Because the timer interrupts are
> wired to all of the 4 cores, bits[15:8] should be set to 0xf.
>
> Signed-off-by: Masahiro Yamada <yamada.masahiro at socionext.com>

This has been superseded by v2.

-- 
Best Regards
Masahiro Yamada


From b38611 at freescale.com  Tue Aug 18 22:34:04 2015
From: b38611 at freescale.com (Fugang Duan)
Date: Wed, 19 Aug 2015 13:34:04 +0800
Subject: [PATCH v1 6/6] ARM: dts: imx7d-sdb: add fec1 and fec2 support
In-Reply-To: <1439962444-27486-1-git-send-email-b38611@freescale.com>
References: <1439962444-27486-1-git-send-email-b38611@freescale.com>
Message-ID: <1439962444-27486-7-git-send-email-b38611@freescale.com>

Enable fec1 and fec2 for i.MX7d-sdb board.

Signed-off-by: Fugang Duan <B38611 at freescale.com>
---
 arch/arm/boot/dts/imx7d-sdb.dts | 76 ++++++++++++++++++++++++++++++++++++++++-
 1 file changed, 75 insertions(+), 1 deletion(-)

diff --git a/arch/arm/boot/dts/imx7d-sdb.dts b/arch/arm/boot/dts/imx7d-sdb.dts
index 4d1a4b9..7d3e980 100644
--- a/arch/arm/boot/dts/imx7d-sdb.dts
+++ b/arch/arm/boot/dts/imx7d-sdb.dts
@@ -101,6 +101,45 @@
 	arm-supply = <&sw1a_reg>;
 };
 
+&fec1 {
+	pinctrl-names = "default";
+	pinctrl-0 = <&pinctrl_enet1>;
+	assigned-clocks = <&clks IMX7D_ENET1_TIME_ROOT_SRC>,
+			  <&clks IMX7D_ENET1_TIME_ROOT_CLK>;
+	assigned-clock-parents = <&clks IMX7D_PLL_ENET_MAIN_100M_CLK>;
+	assigned-clock-rates = <0>, <100000000>;
+	phy-mode = "rgmii";
+	phy-handle = <&ethphy0>;
+	fsl,magic-packet;
+	status = "okay";
+
+	mdio {
+		#address-cells = <1>;
+		#size-cells = <0>;
+
+		ethphy0: ethernet-phy at 0 {
+			reg = <0>;
+		};
+
+		ethphy1: ethernet-phy at 1 {
+			reg = <1>;
+		};
+	};
+};
+
+&fec2 {
+	pinctrl-names = "default";
+	pinctrl-0 = <&pinctrl_enet2>;
+	assigned-clocks = <&clks IMX7D_ENET2_TIME_ROOT_SRC>,
+			  <&clks IMX7D_ENET2_TIME_ROOT_CLK>;
+	assigned-clock-parents = <&clks IMX7D_PLL_ENET_MAIN_100M_CLK>;
+	assigned-clock-rates = <0>, <100000000>;
+	phy-mode = "rgmii";
+	phy-handle = <&ethphy1>;
+	fsl,magic-packet;
+	status = "okay";
+};
+
 &i2c1 {
 	pinctrl-names = "default";
 	pinctrl-0 = <&pinctrl_i2c1>;
@@ -246,6 +285,42 @@
 	pinctrl-0 = <&pinctrl_hog>;
 
 	imx7d-sdb {
+		pinctrl_enet1: enet1grp {
+			fsl,pins = <
+				MX7D_PAD_GPIO1_IO10__ENET1_MDIO			0x3
+				MX7D_PAD_GPIO1_IO11__ENET1_MDC			0x3
+				MX7D_PAD_ENET1_RGMII_TXC__ENET1_RGMII_TXC	0x1
+				MX7D_PAD_ENET1_RGMII_TD0__ENET1_RGMII_TD0	0x1
+				MX7D_PAD_ENET1_RGMII_TD1__ENET1_RGMII_TD1	0x1
+				MX7D_PAD_ENET1_RGMII_TD2__ENET1_RGMII_TD2	0x1
+				MX7D_PAD_ENET1_RGMII_TD3__ENET1_RGMII_TD3	0x1
+				MX7D_PAD_ENET1_RGMII_TX_CTL__ENET1_RGMII_TX_CTL	0x1
+				MX7D_PAD_ENET1_RGMII_RXC__ENET1_RGMII_RXC	0x1
+				MX7D_PAD_ENET1_RGMII_RD0__ENET1_RGMII_RD0	0x1
+				MX7D_PAD_ENET1_RGMII_RD1__ENET1_RGMII_RD1	0x1
+				MX7D_PAD_ENET1_RGMII_RD2__ENET1_RGMII_RD2	0x1
+				MX7D_PAD_ENET1_RGMII_RD3__ENET1_RGMII_RD3	0x1
+				MX7D_PAD_ENET1_RGMII_RX_CTL__ENET1_RGMII_RX_CTL	0x1
+			>;
+		};
+
+		pinctrl_enet2: enet2grp {
+			fsl,pins = <
+				MX7D_PAD_EPDC_GDSP__ENET2_RGMII_TXC		0x1
+				MX7D_PAD_EPDC_SDCE2__ENET2_RGMII_TD0		0x1
+				MX7D_PAD_EPDC_SDCE3__ENET2_RGMII_TD1		0x1
+				MX7D_PAD_EPDC_GDCLK__ENET2_RGMII_TD2		0x1
+				MX7D_PAD_EPDC_GDOE__ENET2_RGMII_TD3		0x1
+				MX7D_PAD_EPDC_GDRL__ENET2_RGMII_TX_CTL		0x1
+				MX7D_PAD_EPDC_SDCE1__ENET2_RGMII_RXC		0x1
+				MX7D_PAD_EPDC_SDCLK__ENET2_RGMII_RD0		0x1
+				MX7D_PAD_EPDC_SDLE__ENET2_RGMII_RD1		0x1
+				MX7D_PAD_EPDC_SDOE__ENET2_RGMII_RD2		0x1
+				MX7D_PAD_EPDC_SDSHR__ENET2_RGMII_RD3		0x1
+				MX7D_PAD_EPDC_SDCE0__ENET2_RGMII_RX_CTL		0x1
+			>;
+		};
+
 		pinctrl_hog: hoggrp {
 			fsl,pins = <
 				MX7D_PAD_UART3_CTS_B__GPIO4_IO7		0x14
@@ -281,7 +356,6 @@
 			>;
 		};
 
-
 		pinctrl_uart1: uart1grp {
 			fsl,pins = <
 				MX7D_PAD_UART1_TX_DATA__UART1_DCE_TX	0x79
-- 
1.9.1



From mpa at pengutronix.de  Tue Aug 18 22:54:34 2015
From: mpa at pengutronix.de (Markus Pargmann)
Date: Wed, 19 Aug 2015 07:54:34 +0200
Subject: [PATCH v2 2/5] Documentation: Detail permitted DT properties for
 the imx6ul_tsc
In-Reply-To: <1438077521-12857-3-git-send-email-haibo.chen@freescale.com>
References: <1438077521-12857-1-git-send-email-haibo.chen@freescale.com>
 <1438077521-12857-3-git-send-email-haibo.chen@freescale.com>
Message-ID: <20150819055434.GF11161@pengutronix.de>

Hi,

On Tue, Jul 28, 2015 at 05:58:38PM +0800, Haibo Chen wrote:
> Here we apply required documentation for the imx6ul touch screen
> controller driver which describe available properties and how to
> use them.
> 
> Signed-off-by: Haibo Chen <haibo.chen at freescale.com>
> ---
>  .../bindings/input/touchscreen/imx6ul_tsc.txt      | 36 ++++++++++++++++++++++
>  1 file changed, 36 insertions(+)
>  create mode 100644 Documentation/devicetree/bindings/input/touchscreen/imx6ul_tsc.txt
> 
> diff --git a/Documentation/devicetree/bindings/input/touchscreen/imx6ul_tsc.txt b/Documentation/devicetree/bindings/input/touchscreen/imx6ul_tsc.txt
> new file mode 100644
> index 0000000..ac41c32
> --- /dev/null
> +++ b/Documentation/devicetree/bindings/input/touchscreen/imx6ul_tsc.txt
> @@ -0,0 +1,36 @@
> +* Freescale i.MX6UL Touch Controller
> +
> +Required properties:
> +- compatible: must be "fsl,imx6ul-tsc".
> +- reg: this touch controller address and the ADC2 address.

This suggests that this driver is using a unit ADC2. Which also means
that there are more than one ADC which are probably identical?

Shouldn't these ADCs be properly described by their own device nodes
instead of these two register ranges, two interrupts and two clocks?

Is 'ADC2' usable without tsc? Then ADC1/ADC2 should perhaps get a proper
IIO driver.

Unfortunately I don't have the reference manual to have a look how this
all works.

Best regards,

Markus

> +- interrupts: the interrupt of this touch controller and ADC2.
> +- clocks: the root clock of touch controller and ADC2.
> +- clock-names; must be "tsc" and "adc".
> +- xnur-gpio: the X- gpio this controller connect to.
> +  This xnur-gpio returns to high once the finger leave the touch screen (The
> +  last touch event the touch controller capture).
> +
> +Optional properties:
> +- measure-delay-time: the value of measure delay time.
> +  Before X-axis or Y-axis measurement, the screen need some time before
> +  even potential distribution ready.
> +  This value depends on the touch screen.
> +- pre-charge-time: the touch screen need some time to precharge.
> +  This value depends on the touch screen.
> +
> +Example:
> +	tsc: tsc at 02040000 {
> +		compatible = "fsl,imx6ul-tsc";
> +		reg = <0x02040000 0x4000>, <0x0219c000 0x4000>;
> +		interrupts = <GIC_SPI 3 IRQ_TYPE_LEVEL_HIGH>,
> +			     <GIC_SPI 101 IRQ_TYPE_LEVEL_HIGH>;
> +		clocks = <&clks IMX6UL_CLK_IPG>,
> +			 <&clks IMX6UL_CLK_ADC2>;
> +		clock-names = "tsc", "adc";
> +		pinctrl-names = "default";
> +		pinctrl-0 = <&pinctrl_tsc>;
> +		xnur-gpio = <&gpio1 3 GPIO_ACTIVE_HIGH>;
> +		measure-delay-time = <0xfff>;
> +		pre-charge-time = <0xffff>;
> +		status = "okay";
> +	};
> -- 
> 1.9.1
> 
> 
> 

-- 
Pengutronix e.K.                           |                             |
Industrial Linux Solutions                 | http://www.pengutronix.de/  |
Peiner Str. 6-8, 31137 Hildesheim, Germany | Phone: +49-5121-206917-0    |
Amtsgericht Hildesheim, HRA 2686           | Fax:   +49-5121-206917-5555 |
-------------- next part --------------
A non-text attachment was scrubbed...
Name: signature.asc
Type: application/pgp-signature
Size: 819 bytes
Desc: Digital signature
URL: <http://lists.infradead.org/pipermail/linux-arm-kernel/attachments/20150819/b2431b04/attachment-0001.sig>

From mpa at pengutronix.de  Tue Aug 18 23:12:11 2015
From: mpa at pengutronix.de (Markus Pargmann)
Date: Wed, 19 Aug 2015 08:12:11 +0200
Subject: [PATCH 7/8] pinctrl: freescale: imx: fix flat functions default
 return
In-Reply-To: <1439912939-17535-7-git-send-email-aalonso@freescale.com>
References: <1439912939-17535-1-git-send-email-aalonso@freescale.com>
 <1439912939-17535-7-git-send-email-aalonso@freescale.com>
Message-ID: <20150819061211.GG11161@pengutronix.de>

On Tue, Aug 18, 2015 at 10:48:58AM -0500, Adrian Alonso wrote:
> Fix imx pinctrl dt flat functions default return value.
> If property fsl,pins is not found in function_np and
> pinctrl_np return false to indicate that DT is not using
> flat functions.

The for loop in this function checks the child nodes and the child's
child nodes. Therefore if we exit the for loop we didn't find any nodes
on any level with the 'fsl,pins' property.

So this 'default' return value is never used unless there is no fsl,pins
property anywhere. So this return value is not important but I wrote
true because we want to use the new flat dt option as default. The extra
indention doesn't make sense anymore.

Regards,

Markus

> 
> Signed-off-by: Adrian Alonso <aalonso at freescale.com>
> ---
>  drivers/pinctrl/freescale/pinctrl-imx.c | 2 +-
>  1 file changed, 1 insertion(+), 1 deletion(-)
> 
> diff --git a/drivers/pinctrl/freescale/pinctrl-imx.c b/drivers/pinctrl/freescale/pinctrl-imx.c
> index 1009b52..3e02887 100644
> --- a/drivers/pinctrl/freescale/pinctrl-imx.c
> +++ b/drivers/pinctrl/freescale/pinctrl-imx.c
> @@ -641,7 +641,7 @@ static bool imx_pinctrl_dt_is_flat_functions(struct device_node *np)
>  		}
>  	}
>  
> -	return true;
> +	return false;
>  }
>  
>  static int imx_pinctrl_probe_dt(struct platform_device *pdev,
> -- 
> 2.1.4
> 
> 
> _______________________________________________
> linux-arm-kernel mailing list
> linux-arm-kernel at lists.infradead.org
> http://lists.infradead.org/mailman/listinfo/linux-arm-kernel
> 

-- 
Pengutronix e.K.                           |                             |
Industrial Linux Solutions                 | http://www.pengutronix.de/  |
Peiner Str. 6-8, 31137 Hildesheim, Germany | Phone: +49-5121-206917-0    |
Amtsgericht Hildesheim, HRA 2686           | Fax:   +49-5121-206917-5555 |
-------------- next part --------------
A non-text attachment was scrubbed...
Name: signature.asc
Type: application/pgp-signature
Size: 819 bytes
Desc: Digital signature
URL: <http://lists.infradead.org/pipermail/linux-arm-kernel/attachments/20150819/6a97a423/attachment.sig>

From mpa at pengutronix.de  Tue Aug 18 23:14:58 2015
From: mpa at pengutronix.de (Markus Pargmann)
Date: Wed, 19 Aug 2015 08:14:58 +0200
Subject: [PATCH 8/8] pinctrl: freescale: imx: fix system crash if enable
 two pinctl instances
In-Reply-To: <1439912939-17535-8-git-send-email-aalonso@freescale.com>
References: <1439912939-17535-1-git-send-email-aalonso@freescale.com>
 <1439912939-17535-8-git-send-email-aalonso@freescale.com>
Message-ID: <20150819061458.GH11161@pengutronix.de>

On Tue, Aug 18, 2015 at 10:48:59AM -0500, Adrian Alonso wrote:
> From: Robin Gong <b38343 at freescale.com>
> 
> Remove 'static' for 'grp_index', otherwise, it cause the groups whose number is
> smaller than the number of groups of the last pinctl instance never to be
> intialized, thus cause system crash as below

grp_index is used as array index. If you remove 'static' from this
variable doesn't it always write to array element 0 and overwrite the
last group?

Regards,

Markus

> 
> [    0.661012] [<802a6cb0>] (strcmp) from [<802cc80c>] (imx_dt_node_to_map+0x58/0x208)
> [    0.668879] [<802cc80c>] (imx_dt_node_to_map) from [<802cbe24>] (pinctrl_dt_to_map+0x174/0x2b0)
> [    0.677654] [<802cbe24>] (pinctrl_dt_to_map) from [<802c8f18>] (pinctrl_get+0x100/0x424)
> [    0.685878] [<802c8f18>] (pinctrl_get) from [<802c9510>] (pinctrl_register+0x26c/0x480)
> [    0.694104] [<802c9510>] (pinctrl_register) from [<802ccf3c>] (imx_pinctrl_probe+0x580/0x6e8)
> [    0.702706] [<802ccf3c>] (imx_pinctrl_probe) from [<80351b58>] (platform_drv_probe+0x44/0xa4)
> [    0.711455] [<80351b58>] (platform_drv_probe) from [<803503ec>] (driver_probe_device+0x174/0x2b4)
> [    0.720405] [<803503ec>] (driver_probe_device) from [<803505fc>] (__driver_attach+0x8c/0x90)
> [    0.728982] [<803505fc>] (__driver_attach) from [<8034e930>] (bus_for_each_dev+0x6c/0xa0)
> [    0.737381] [<8034e930>] (bus_for_each_dev) from [<8034fb88>] (bus_add_driver+0x148/0x1f0)
> [    0.745804] [<8034fb88>] (bus_add_driver) from [<80350c00>] (driver_register+0x78/0xf8)
> [    0.753880] [<80350c00>] (driver_register) from [<800097d0>] (do_one_initcall+0x8c/0x1d4)
> [    0.762282] [<800097d0>] (do_one_initcall) from [<80987dac>] (kernel_init_freeable+0x144/0x1e4)
> [    0.771061] [<80987dac>] (kernel_init_freeable) from [<806d9c7c>] (kernel_init+0x8/0xe8)
> [    0.779285] [<806d9c7c>] (kernel_init) from [<8000f628>] (ret_from_fork+0x14/0x2c)
> [    0.786981] Code: e3520000 e5e32001 1afffffb e12fff1e (e4d03001)
> 
> Signed-off-by: Robin Gong <b38343 at freescale.com>
> Signed-off-by: Adrian Alonso <aalonso at freescale.com>
> ---
>  drivers/pinctrl/freescale/pinctrl-imx.c | 2 +-
>  1 file changed, 1 insertion(+), 1 deletion(-)
> 
> diff --git a/drivers/pinctrl/freescale/pinctrl-imx.c b/drivers/pinctrl/freescale/pinctrl-imx.c
> index 3e02887..cdb5463 100644
> --- a/drivers/pinctrl/freescale/pinctrl-imx.c
> +++ b/drivers/pinctrl/freescale/pinctrl-imx.c
> @@ -595,7 +595,7 @@ static int imx_pinctrl_parse_functions(struct device_node *np,
>  	struct device_node *child;
>  	struct imx_pmx_func *func;
>  	struct imx_pin_group *grp;
> -	static u32 grp_index;
> +	u32 grp_index = 0;
>  	u32 i = 0;
>  
>  	dev_dbg(info->dev, "parse function(%d): %s\n", index, np->name);
> -- 
> 2.1.4
> 
> 
> _______________________________________________
> linux-arm-kernel mailing list
> linux-arm-kernel at lists.infradead.org
> http://lists.infradead.org/mailman/listinfo/linux-arm-kernel
> 

-- 
Pengutronix e.K.                           |                             |
Industrial Linux Solutions                 | http://www.pengutronix.de/  |
Peiner Str. 6-8, 31137 Hildesheim, Germany | Phone: +49-5121-206917-0    |
Amtsgericht Hildesheim, HRA 2686           | Fax:   +49-5121-206917-5555 |
-------------- next part --------------
A non-text attachment was scrubbed...
Name: signature.asc
Type: application/pgp-signature
Size: 819 bytes
Desc: Digital signature
URL: <http://lists.infradead.org/pipermail/linux-arm-kernel/attachments/20150819/5590c4f5/attachment.sig>

From mpa at pengutronix.de  Tue Aug 18 23:18:38 2015
From: mpa at pengutronix.de (Markus Pargmann)
Date: Wed, 19 Aug 2015 08:18:38 +0200
Subject: [PATCH 1/8] ARM: imx: imx7d-pinfunc: add gpio1 pad iomux settings
In-Reply-To: <1439912939-17535-1-git-send-email-aalonso@freescale.com>
References: <1439912939-17535-1-git-send-email-aalonso@freescale.com>
Message-ID: <20150819061838.GI11161@pengutronix.de>

On Tue, Aug 18, 2015 at 10:48:52AM -0500, Adrian Alonso wrote:
> - Add imx7 SoC GPIO1 pad iomuxc settings
>   <mux_reg conf_reg input_reg mux_mode input_val>
> - Fix UART input select daisy chain setting values
> 
> Signed-off-by: Adrian Alonso <aalonso at freescale.com>
> ---
>  arch/arm/boot/dts/imx7d-pinfunc.h | 122 +++++++++++++++++++++++++++++++++++++-
>  1 file changed, 119 insertions(+), 3 deletions(-)
> 
> diff --git a/arch/arm/boot/dts/imx7d-pinfunc.h b/arch/arm/boot/dts/imx7d-pinfunc.h
> index a8d8149..22f849c 100644
> --- a/arch/arm/boot/dts/imx7d-pinfunc.h
> +++ b/arch/arm/boot/dts/imx7d-pinfunc.h
> @@ -15,6 +15,122 @@
>   * <mux_reg conf_reg input_reg mux_mode input_val>
>   */
>  
> +#define MX7D_PAD_GPIO1_IO00__GPIO1_IO0				  0x0000 0x0030 0x0000 0x0 0x0
> +#define MX7D_PAD_GPIO1_IO00__PWM4_OUT				  0x0000 0x0030 0x0000 0x1 0x0
> +#define MX7D_PAD_GPIO1_IO00__WDOD1_WDOG_ANY			  0x0000 0x0030 0x0000 0x2 0x0
> +#define MX7D_PAD_GPIO1_IO00__WDOD1_WDOG_B			  0x0000 0x0030 0x0000 0x3 0x0
> +#define MX7D_PAD_GPIO1_IO00__WDOD1_WDOG__RST_B_DEB		  0x0000 0x0030 0x0000 0x4 0x0
> +#define MX7D_PAD_GPIO1_IO01__GPIO1_IO1				  0x0004 0x0034 0x0000 0x0 0x0
> +#define MX7D_PAD_GPIO1_IO01__PWM1_OUT				  0x0004 0x0034 0x0000 0x1 0x0
> +#define MX7D_PAD_GPIO1_IO01__CCM_ENET_REF_CLK3			  0x0004 0x0034 0x0000 0x2 0x0
> +#define MX7D_PAD_GPIO1_IO01__SAI1_MCLK				  0x0004 0x0034 0x0000 0x3 0x0
> +#define MX7D_PAD_GPIO1_IO01__ANATOP_24M_OUT			  0x0004 0x0034 0x0000 0x4 0x0
> +#define MX7D_PAD_GPIO1_IO01__OBSERVE0_OUT			  0x0004 0x0034 0x0000 0x6 0x0
> +#define MX7D_PAD_GPIO1_IO02__GPIO1_IO2				  0x0008 0x0038 0x0000 0x0 0x0
> +#define MX7D_PAD_GPIO1_IO02__PWM2_OUT				  0x0008 0x0038 0x0000 0x1 0x0
> +#define MX7D_PAD_GPIO1_IO02__CCM_ENET_REF_CLK1			  0x0008 0x0038 0x0564 0x2 0x3
> +#define MX7D_PAD_GPIO1_IO02__SAI2_MCLK				  0x0008 0x0038 0x0000 0x3 0x0
> +#define MX7D_PAD_GPIO1_IO02__CCM_CLKO1				  0x0008 0x0038 0x0000 0x5 0x0
> +#define MX7D_PAD_GPIO1_IO02__OBSERVE1_OUT			  0x0008 0x0038 0x0000 0x6 0x0
> +#define MX7D_PAD_GPIO1_IO02__USB_OTG1_ID			  0x0008 0x0038 0x0734 0x7 0x3
> +#define MX7D_PAD_GPIO1_IO03__GPIO1_IO3				  0x000C 0x003C 0x0000 0x0 0x0
> +#define MX7D_PAD_GPIO1_IO03__PWM3_OUT				  0x000C 0x003C 0x0000 0x1 0x0
> +#define MX7D_PAD_GPIO1_IO03__CCM_ENET_REF_CLK2			  0x000C 0x003C 0x0570 0x2 0x3
> +#define MX7D_PAD_GPIO1_IO03__SAI3_MCLK				  0x000C 0x003C 0x0000 0x3 0x0
> +#define MX7D_PAD_GPIO1_IO03__CCM_CLKO2				  0x000C 0x003C 0x0000 0x5 0x0
> +#define MX7D_PAD_GPIO1_IO03__OBSERVE2_OUT			  0x000C 0x003C 0x0000 0x6 0x0
> +#define MX7D_PAD_GPIO1_IO03__USB_OTG2_ID			  0x000C 0x003C 0x0730 0x7 0x3
> +#define MX7D_PAD_GPIO1_IO04__GPIO1_IO4				  0x0010 0x0040 0x0000 0x0 0x0
> +#define MX7D_PAD_GPIO1_IO04__USB_OTG1_OC			  0x0010 0x0040 0x072C 0x1 0x1
> +#define MX7D_PAD_GPIO1_IO04__FLEXTIMER1_CH4			  0x0010 0x0040 0x0594 0x2 0x1
> +#define MX7D_PAD_GPIO1_IO04__UART5_CTS_B			  0x0010 0x0040 0x0710 0x3 0x4
> +#define MX7D_PAD_GPIO1_IO04__I2C1_SCL				  0x0010 0x0040 0x05D4 0x4 0x2
> +#define MX7D_PAD_GPIO1_IO04__OBSERVE3_OUT			  0x0010 0x0040 0x0000 0x6 0x0
> +#define MX7D_PAD_GPIO1_IO05__GPIO1_IO5				  0x0014 0x0044 0x0000 0x0 0x0
> +#define MX7D_PAD_GPIO1_IO05__USB_OTG1_PWR			  0x0014 0x0044 0x0000 0x1 0x0
> +#define MX7D_PAD_GPIO1_IO05__FLEXTIMER1_CH5			  0x0014 0x0044 0x0598 0x2 0x1
> +#define MX7D_PAD_GPIO1_IO05__UART5_RTS_B			  0x0014 0x0044 0x0710 0x3 0x5
> +#define MX7D_PAD_GPIO1_IO05__I2C1_SDA				  0x0014 0x0044 0x05D8 0x4 0x2
> +#define MX7D_PAD_GPIO1_IO05__OBSERVE4_OUT			  0x0014 0x0044 0x0000 0x6 0x0
> +#define MX7D_PAD_GPIO1_IO06__GPIO1_IO6				  0x0018 0x0048 0x0000 0x0 0x0
> +#define MX7D_PAD_GPIO1_IO06__USB_OTG2_OC			  0x0018 0x0048 0x0728 0x1 0x1
> +#define MX7D_PAD_GPIO1_IO06__FLEXTIMER1_CH6			  0x0018 0x0048 0x059C 0x2 0x1
> +#define MX7D_PAD_GPIO1_IO06__UART5_RX_DATA			  0x0018 0x0048 0x0714 0x3 0x4
> +#define MX7D_PAD_GPIO1_IO06__I2C2_SCL				  0x0018 0x0048 0x05DC 0x4 0x2
> +#define MX7D_PAD_GPIO1_IO06__CCM_WAIT				  0x0018 0x0048 0x0000 0x5 0x0
> +#define MX7D_PAD_GPIO1_IO06__KPP_ROW4				  0x0018 0x0048 0x0624 0x6 0x1
> +#define MX7D_PAD_GPIO1_IO07__GPIO1_IO7				  0x001C 0x004C 0x0000 0x0 0x0
> +#define MX7D_PAD_GPIO1_IO07__USB_OTG2_PWR			  0x001C 0x004C 0x0000 0x1 0x0
> +#define MX7D_PAD_GPIO1_IO07__FLEXTIMER1_CH7			  0x001C 0x004C 0x05A0 0x2 0x1
> +#define MX7D_PAD_GPIO1_IO07__UART5_TX_DATA			  0x001C 0x004C 0x0714 0x3 0x5
> +#define MX7D_PAD_GPIO1_IO07__I2C2_SDA				  0x001C 0x004C 0x05E0 0x4 0x2
> +#define MX7D_PAD_GPIO1_IO07__CCM_STOP				  0x001C 0x004C 0x0000 0x5 0x0
> +#define MX7D_PAD_GPIO1_IO07__KPP_COL4				  0x001C 0x004C 0x0604 0x6 0x1
> +#define MX7D_PAD_GPIO1_IO08__GPIO1_IO8                            0x0014 0x026C 0x0000 0x0 0x0

You are going from tab+space indention to space indention here.

Regards,

Markus

> +#define MX7D_PAD_GPIO1_IO08__SD1_VSELECT                          0x0014 0x026C 0x0000 0x1 0x0
> +#define MX7D_PAD_GPIO1_IO08__WDOG1_WDOG_B                         0x0014 0x026C 0x0000 0x2 0x0
> +#define MX7D_PAD_GPIO1_IO08__UART3_DCE_RX                         0x0014 0x026C 0x0704 0x3 0x0
> +#define MX7D_PAD_GPIO1_IO08__UART3_DTE_TX                         0x0014 0x026C 0x0000 0x3 0x0
> +#define MX7D_PAD_GPIO1_IO08__I2C3_SCL                             0x0014 0x026C 0x05E4 0x4 0x0
> +#define MX7D_PAD_GPIO1_IO08__KPP_COL5                             0x0014 0x026C 0x0608 0x6 0x0
> +#define MX7D_PAD_GPIO1_IO08__PWM1_OUT                             0x0014 0x026C 0x0000 0x7 0x0
> +#define MX7D_PAD_GPIO1_IO09__GPIO1_IO9                            0x0018 0x0270 0x0000 0x0 0x0
> +#define MX7D_PAD_GPIO1_IO09__SD1_LCTL                             0x0018 0x0270 0x0000 0x1 0x0
> +#define MX7D_PAD_GPIO1_IO09__CCM_ENET_REF_CLK3                    0x0018 0x0270 0x0000 0x2 0x0
> +#define MX7D_PAD_GPIO1_IO09__UART3_DCE_TX                         0x0018 0x0270 0x0000 0x3 0x0
> +#define MX7D_PAD_GPIO1_IO09__UART3_DTE_RX                         0x0018 0x0270 0x0704 0x3 0x1
> +#define MX7D_PAD_GPIO1_IO09__I2C3_SDA                             0x0018 0x0270 0x05E8 0x4 0x0
> +#define MX7D_PAD_GPIO1_IO09__CCM_PMIC_READY                       0x0018 0x0270 0x04F4 0x5 0x0
> +#define MX7D_PAD_GPIO1_IO09__KPP_ROW5                             0x0018 0x0270 0x0628 0x6 0x0
> +#define MX7D_PAD_GPIO1_IO09__PWM2_OUT                             0x0018 0x0270 0x0000 0x7 0x0
> +#define MX7D_PAD_GPIO1_IO10__GPIO1_IO10                           0x001C 0x0274 0x0000 0x0 0x0
> +#define MX7D_PAD_GPIO1_IO10__SD2_LCTL                             0x001C 0x0274 0x0000 0x1 0x0
> +#define MX7D_PAD_GPIO1_IO10__ENET1_MDIO                           0x001C 0x0274 0x0568 0x2 0x0
> +#define MX7D_PAD_GPIO1_IO10__UART3_DCE_RTS                        0x001C 0x0274 0x0700 0x3 0x0
> +#define MX7D_PAD_GPIO1_IO10__UART3_DTE_CTS                        0x001C 0x0274 0x0000 0x3 0x0
> +#define MX7D_PAD_GPIO1_IO10__I2C4_SCL                             0x001C 0x0274 0x05EC 0x4 0x0
> +#define MX7D_PAD_GPIO1_IO10__FLEXTIMER1_PHA                       0x001C 0x0274 0x05A4 0x5 0x0
> +#define MX7D_PAD_GPIO1_IO10__KPP_COL6                             0x001C 0x0274 0x060C 0x6 0x0
> +#define MX7D_PAD_GPIO1_IO10__PWM3_OUT                             0x001C 0x0274 0x0000 0x7 0x0
> +#define MX7D_PAD_GPIO1_IO11__GPIO1_IO11                           0x0020 0x0278 0x0000 0x0 0x0
> +#define MX7D_PAD_GPIO1_IO11__SD3_LCTL                             0x0020 0x0278 0x0000 0x1 0x0
> +#define MX7D_PAD_GPIO1_IO11__ENET1_MDC                            0x0020 0x0278 0x0000 0x2 0x0
> +#define MX7D_PAD_GPIO1_IO11__UART3_DCE_CTS                        0x0020 0x0278 0x0000 0x3 0x0
> +#define MX7D_PAD_GPIO1_IO11__UART3_DTE_RTS                        0x0020 0x0278 0x0700 0x3 0x1
> +#define MX7D_PAD_GPIO1_IO11__I2C4_SDA                             0x0020 0x0278 0x05F0 0x4 0x0
> +#define MX7D_PAD_GPIO1_IO11__FLEXTIMER1_PHB                       0x0020 0x0278 0x05A8 0x5 0x0
> +#define MX7D_PAD_GPIO1_IO11__KPP_ROW6                             0x0020 0x0278 0x062C 0x6 0x0
> +#define MX7D_PAD_GPIO1_IO11__PWM4_OUT                             0x0020 0x0278 0x0000 0x7 0x0
> +#define MX7D_PAD_GPIO1_IO12__GPIO1_IO12                           0x0024 0x027C 0x0000 0x0 0x0
> +#define MX7D_PAD_GPIO1_IO12__SD2_VSELECT                          0x0024 0x027C 0x0000 0x1 0x0
> +#define MX7D_PAD_GPIO1_IO12__CCM_ENET_REF_CLK1                    0x0024 0x027C 0x0564 0x2 0x0
> +#define MX7D_PAD_GPIO1_IO12__FLEXCAN1_RX                          0x0024 0x027C 0x04DC 0x3 0x0
> +#define MX7D_PAD_GPIO1_IO12__CM4_NMI                              0x0024 0x027C 0x0000 0x4 0x0
> +#define MX7D_PAD_GPIO1_IO12__CCM_EXT_CLK1                         0x0024 0x027C 0x04E4 0x5 0x0
> +#define MX7D_PAD_GPIO1_IO12__SNVS_VIO_5                           0x0024 0x027C 0x0000 0x6 0x0
> +#define MX7D_PAD_GPIO1_IO12__USB_OTG1_ID                          0x0024 0x027C 0x0734 0x7 0x0
> +#define MX7D_PAD_GPIO1_IO13__GPIO1_IO13                           0x0028 0x0280 0x0000 0x0 0x0
> +#define MX7D_PAD_GPIO1_IO13__SD3_VSELECT                          0x0028 0x0280 0x0000 0x1 0x0
> +#define MX7D_PAD_GPIO1_IO13__CCM_ENET_REF_CLK2                    0x0028 0x0280 0x0570 0x2 0x0
> +#define MX7D_PAD_GPIO1_IO13__FLEXCAN1_TX                          0x0028 0x0280 0x0000 0x3 0x0
> +#define MX7D_PAD_GPIO1_IO13__CCM_PMIC_READY                       0x0028 0x0280 0x04F4 0x4 0x1
> +#define MX7D_PAD_GPIO1_IO13__CCM_EXT_CLK2                         0x0028 0x0280 0x04E8 0x5 0x0
> +#define MX7D_PAD_GPIO1_IO13__SNVS_VIO_5_CTL                       0x0028 0x0280 0x0000 0x6 0x0
> +#define MX7D_PAD_GPIO1_IO13__USB_OTG2_ID                          0x0028 0x0280 0x0730 0x7 0x0
> +#define MX7D_PAD_GPIO1_IO14__GPIO1_IO14                           0x002C 0x0284 0x0000 0x0 0x0
> +#define MX7D_PAD_GPIO1_IO14__SD3_CD_B                             0x002C 0x0284 0x0738 0x1 0x0
> +#define MX7D_PAD_GPIO1_IO14__ENET2_MDIO                           0x002C 0x0284 0x0574 0x2 0x0
> +#define MX7D_PAD_GPIO1_IO14__FLEXCAN2_RX                          0x002C 0x0284 0x04E0 0x3 0x0
> +#define MX7D_PAD_GPIO1_IO14__WDOG3_WDOG_B                         0x002C 0x0284 0x0000 0x4 0x0
> +#define MX7D_PAD_GPIO1_IO14__CCM_EXT_CLK3                         0x002C 0x0284 0x04EC 0x5 0x0
> +#define MX7D_PAD_GPIO1_IO14__SDMA_EXT_EVENT0                      0x002C 0x0284 0x06D8 0x6 0x0
> +#define MX7D_PAD_GPIO1_IO15__GPIO1_IO15                           0x0030 0x0288 0x0000 0x0 0x0
> +#define MX7D_PAD_GPIO1_IO15__SD3_WP                               0x0030 0x0288 0x073C 0x1 0x0
> +#define MX7D_PAD_GPIO1_IO15__ENET2_MDC                            0x0030 0x0288 0x0000 0x2 0x0
> +#define MX7D_PAD_GPIO1_IO15__FLEXCAN2_TX                          0x0030 0x0288 0x0000 0x3 0x0
> +#define MX7D_PAD_GPIO1_IO15__WDOG4_WDOG_B                         0x0030 0x0288 0x0000 0x4 0x0
> +#define MX7D_PAD_GPIO1_IO15__CCM_EXT_CLK4                         0x0030 0x0288 0x04F0 0x5 0x0
> +#define MX7D_PAD_GPIO1_IO15__SDMA_EXT_EVENT1                      0x0030 0x0288 0x06DC 0x6 0x0
>  #define MX7D_PAD_EPDC_DATA00__EPDC_DATA0                          0x0034 0x02A4 0x0000 0x0 0x0
>  #define MX7D_PAD_EPDC_DATA00__SIM1_PORT2_TRXD                     0x0034 0x02A4 0x0000 0x1 0x0
>  #define MX7D_PAD_EPDC_DATA00__QSPI_A_DATA0                        0x0034 0x02A4 0x0000 0x2 0x0
> @@ -453,7 +569,7 @@
>  #define MX7D_PAD_LCD_DATA23__EIM_ADDR26                           0x0124 0x0394 0x0000 0x4 0x0
>  #define MX7D_PAD_LCD_DATA23__GPIO3_IO28                           0x0124 0x0394 0x0000 0x5 0x0
>  #define MX7D_PAD_LCD_DATA23__I2C4_SDA                             0x0124 0x0394 0x05F0 0x6 0x1
> -#define MX7D_PAD_UART1_RX_DATA__UART1_DCE_RX                      0x0128 0x0398 0x0000 0x0 0x0
> +#define MX7D_PAD_UART1_RX_DATA__UART1_DCE_RX                      0x0128 0x0398 0x06F4 0x0 0x0
>  #define MX7D_PAD_UART1_RX_DATA__UART1_DTE_TX                      0x0128 0x0398 0x0000 0x0 0x0
>  #define MX7D_PAD_UART1_RX_DATA__I2C1_SCL                          0x0128 0x0398 0x05D4 0x1 0x0
>  #define MX7D_PAD_UART1_RX_DATA__CCM_PMIC_READY                    0x0128 0x0398 0x0000 0x2 0x0
> @@ -469,7 +585,7 @@
>  #define MX7D_PAD_UART1_TX_DATA__ENET2_1588_EVENT0_OUT             0x012C 0x039C 0x0000 0x4 0x0
>  #define MX7D_PAD_UART1_TX_DATA__GPIO4_IO1                         0x012C 0x039C 0x0000 0x5 0x0
>  #define MX7D_PAD_UART1_TX_DATA__ENET1_MDC                         0x012C 0x039C 0x0000 0x6 0x0
> -#define MX7D_PAD_UART2_RX_DATA__UART2_DCE_RX                      0x0130 0x03A0 0x0000 0x0 0x0
> +#define MX7D_PAD_UART2_RX_DATA__UART2_DCE_RX                      0x0130 0x03A0 0x06FC 0x0 0x2
>  #define MX7D_PAD_UART2_RX_DATA__UART2_DTE_TX                      0x0130 0x03A0 0x0000 0x0 0x0
>  #define MX7D_PAD_UART2_RX_DATA__I2C2_SCL                          0x0130 0x03A0 0x05DC 0x1 0x0
>  #define MX7D_PAD_UART2_RX_DATA__SAI3_RX_BCLK                      0x0130 0x03A0 0x0000 0x2 0x0
> @@ -501,7 +617,7 @@
>  #define MX7D_PAD_UART3_TX_DATA__ENET1_1588_EVENT0_OUT             0x013C 0x03AC 0x0000 0x4 0x0
>  #define MX7D_PAD_UART3_TX_DATA__GPIO4_IO5                         0x013C 0x03AC 0x0000 0x5 0x0
>  #define MX7D_PAD_UART3_TX_DATA__SD2_LCTL                          0x013C 0x03AC 0x0000 0x6 0x0
> -#define MX7D_PAD_UART3_RTS_B__UART3_DCE_RTS                       0x0140 0x03B0 0x0000 0x0 0x0
> +#define MX7D_PAD_UART3_RTS_B__UART3_DCE_RTS                       0x0140 0x03B0 0x0700 0x0 0x2
>  #define MX7D_PAD_UART3_RTS_B__UART3_DTE_CTS                       0x0140 0x03B0 0x0000 0x0 0x0
>  #define MX7D_PAD_UART3_RTS_B__USB_OTG2_OC                         0x0140 0x03B0 0x0728 0x1 0x0
>  #define MX7D_PAD_UART3_RTS_B__SAI3_TX_DATA0                       0x0140 0x03B0 0x0000 0x2 0x0
> -- 
> 2.1.4
> 
> --
> To unsubscribe from this list: send the line "unsubscribe devicetree" in
> the body of a message to majordomo at vger.kernel.org
> More majordomo info at  http://vger.kernel.org/majordomo-info.html
> 

-- 
Pengutronix e.K.                           |                             |
Industrial Linux Solutions                 | http://www.pengutronix.de/  |
Peiner Str. 6-8, 31137 Hildesheim, Germany | Phone: +49-5121-206917-0    |
Amtsgericht Hildesheim, HRA 2686           | Fax:   +49-5121-206917-5555 |
-------------- next part --------------
A non-text attachment was scrubbed...
Name: signature.asc
Type: application/pgp-signature
Size: 819 bytes
Desc: Digital signature
URL: <http://lists.infradead.org/pipermail/linux-arm-kernel/attachments/20150819/cf6d5498/attachment-0001.sig>

From heiko at sntech.de  Tue Aug 18 23:19:47 2015
From: heiko at sntech.de (Heiko Stuebner)
Date: Wed, 19 Aug 2015 08:19:47 +0200
Subject: [PATCH 2/2] ARM: dts: rockchip: correct regulator PM properties
In-Reply-To: <20150818232806.GC140911@google.com>
References: <1439923455-109818-1-git-send-email-briannorris@chromium.org>
 <20150818224831.GA140911@google.com> <20150818232806.GC140911@google.com>
Message-ID: <10828643.SSUS2EOuvv@phil>

Am Dienstag, 18. August 2015, 16:28:06 schrieb Brian Norris:
> Now that I'm looking a little closer, it seems like other existing DTS's
> are broken too, then. Jerry looks like it was converted to the
> regulator-state-mem node binding, but the conversion doesn't seem to
> make sense when I compare the chromium DTS sources with the for-next
> source I see in your tree.
> 
> In -next:
> 
>      regulators {
>              mic_vcc: LDO_REG2 {
>                         regulator-name = "mic_vcc";
>                         regulator-always-on;
>                         regulator-boot-on;
>                         regulator-min-microvolt = <1800000>;
>                         regulator-max-microvolt = <1800000>;
>                         regulator-state-mem {
>                                 regulator-on-in-suspend;
>                         };
>                 };
>          };
> 
> But chromium had:
> 
>        regulators {
>                 mic_vcc: LDO_REG2 {
>                         regulator-always-on;
>                         regulator-boot-on;
>                         regulator-min-microvolt = <1800000>;
>                         regulator-max-microvolt = <1800000>;
>                         regulator-name = "mic_vcc";
>                         regulator-suspend-mem-disabled;
>                 };
>        };
> 
> So I guess I'll make the proper conversion for all the veyron variants I
> see.

great, just take into account the deep vs. shallow suspend modes :-)

The original regulator-state changes did happen when we had this suspend 
instability (counter and gpioint stuff) and I did go with the values similar to 
the rk3288-evb, as this was the only one resuming at all at the time. So I 
guess I never looked to closesly what it did, as long as the system came out 
of suspend sucessfully again :-)


Heiko


From mpa at pengutronix.de  Tue Aug 18 23:26:30 2015
From: mpa at pengutronix.de (Markus Pargmann)
Date: Wed, 19 Aug 2015 08:26:30 +0200
Subject: [PATCH 5/8] pinctrl: freescale: imx: add shared input select reg
 support
In-Reply-To: <1439912939-17535-5-git-send-email-aalonso@freescale.com>
References: <1439912939-17535-1-git-send-email-aalonso@freescale.com>
 <1439912939-17535-5-git-send-email-aalonso@freescale.com>
Message-ID: <20150819062630.GJ11161@pengutronix.de>

On Tue, Aug 18, 2015 at 10:48:56AM -0500, Adrian Alonso wrote:
> - Add shared input select register support
> - imx7d has two iomux controllers iomuxc and iomuxc-lpsr
>   which share select_input register for daisy chain settings
> 
> Signed-off-by: Adrian Alonso <aalonso at freescale.com>
> ---
>  drivers/pinctrl/freescale/pinctrl-imx.c | 28 +++++++++++++++++++++++++++-
>  drivers/pinctrl/freescale/pinctrl-imx.h |  1 +
>  2 files changed, 28 insertions(+), 1 deletion(-)
> 
> diff --git a/drivers/pinctrl/freescale/pinctrl-imx.c b/drivers/pinctrl/freescale/pinctrl-imx.c
> index 0440b0b..1009b52 100644
> --- a/drivers/pinctrl/freescale/pinctrl-imx.c
> +++ b/drivers/pinctrl/freescale/pinctrl-imx.c
> @@ -18,6 +18,7 @@
>  #include <linux/module.h>
>  #include <linux/of.h>
>  #include <linux/of_device.h>
> +#include <linux/of_address.h>
>  #include <linux/pinctrl/machine.h>
>  #include <linux/pinctrl/pinconf.h>
>  #include <linux/pinctrl/pinctrl.h>
> @@ -39,6 +40,7 @@ struct imx_pinctrl {
>  	struct device *dev;
>  	struct pinctrl_dev *pctl;
>  	void __iomem *base;
> +	void __iomem *input_sel_base;
>  	const struct imx_pinctrl_soc_info *info;
>  };
>  
> @@ -254,7 +256,12 @@ static int imx_pmx_set(struct pinctrl_dev *pctldev, unsigned selector,
>  			 * Regular select input register can never be at offset
>  			 * 0, and we only print register value for regular case.
>  			 */
> -			writel(pin->input_val, ipctl->base + pin->input_reg);
> +			if (info->flags & SHARE_INPUT_SELECT_REG)
> +				writel(pin->input_val, ipctl->input_sel_base +
> +						pin->input_reg);
> +			else
> +				writel(pin->input_val, ipctl->base +
> +						pin->input_reg);
>  			dev_dbg(ipctl->dev,
>  				"==>select_input: offset 0x%x val 0x%x\n",
>  				pin->input_reg, pin->input_val);
> @@ -691,6 +698,8 @@ static int imx_pinctrl_probe_dt(struct platform_device *pdev,
>  int imx_pinctrl_probe(struct platform_device *pdev,
>  		      struct imx_pinctrl_soc_info *info)
>  {
> +	struct device_node *dev_np = pdev->dev.of_node;
> +	struct device_node *np;
>  	struct imx_pinctrl *ipctl;
>  	struct resource *res;
>  	int ret;
> @@ -716,6 +725,23 @@ int imx_pinctrl_probe(struct platform_device *pdev,
>  	if (IS_ERR(ipctl->base))
>  		return PTR_ERR(ipctl->base);
>  
> +	if (info->flags & SHARE_INPUT_SELECT_REG) {
> +		np = of_get_child_by_name(dev_np->parent, "iomuxc");

Isn't there a better way to get this node than searching through the
childs of the parent which may magically have the right 'iomuxc' node
there and using the register range of that node?

Does the other iomuxc node uses its register space as well?

Regards,

Markus

> +		if (np) {
> +			ipctl->input_sel_base = of_iomap(np, 0);
> +			if (IS_ERR(ipctl->input_sel_base)) {
> +				of_node_put(np);
> +				dev_err(&pdev->dev,
> +				       "iomuxc base address not found\n");
> +				return PTR_ERR(ipctl->input_sel_base);
> +			}
> +		} else {
> +			dev_err(&pdev->dev, "iomuxc device node not foud\n");
> +			return -EINVAL;
> +		}
> +		of_node_put(np);
> +	}
> +
>  	imx_pinctrl_desc.name = dev_name(&pdev->dev);
>  	imx_pinctrl_desc.pins = info->pins;
>  	imx_pinctrl_desc.npins = info->npins;
> diff --git a/drivers/pinctrl/freescale/pinctrl-imx.h b/drivers/pinctrl/freescale/pinctrl-imx.h
> index d22b8f6..85c701b 100644
> --- a/drivers/pinctrl/freescale/pinctrl-imx.h
> +++ b/drivers/pinctrl/freescale/pinctrl-imx.h
> @@ -85,6 +85,7 @@ struct imx_pinctrl_soc_info {
>  
>  #define SHARE_MUX_CONF_REG	0x1
>  #define ZERO_OFFSET_VALID	0x2
> +#define SHARE_INPUT_SELECT_REG	0x4
>  
>  #define NO_MUX		0x0
>  #define NO_PAD		0x0
> -- 
> 2.1.4
> 
> --
> To unsubscribe from this list: send the line "unsubscribe devicetree" in
> the body of a message to majordomo at vger.kernel.org
> More majordomo info at  http://vger.kernel.org/majordomo-info.html
> 

-- 
Pengutronix e.K.                           |                             |
Industrial Linux Solutions                 | http://www.pengutronix.de/  |
Peiner Str. 6-8, 31137 Hildesheim, Germany | Phone: +49-5121-206917-0    |
Amtsgericht Hildesheim, HRA 2686           | Fax:   +49-5121-206917-5555 |
-------------- next part --------------
A non-text attachment was scrubbed...
Name: signature.asc
Type: application/pgp-signature
Size: 819 bytes
Desc: Digital signature
URL: <http://lists.infradead.org/pipermail/linux-arm-kernel/attachments/20150819/618ebc3c/attachment.sig>

From u.kleine-koenig at pengutronix.de  Tue Aug 18 23:44:19 2015
From: u.kleine-koenig at pengutronix.de (Uwe =?iso-8859-1?Q?Kleine-K=F6nig?=)
Date: Wed, 19 Aug 2015 08:44:19 +0200
Subject: [PATCH V3] Watchdog: Fix parent of watchdog_devices
In-Reply-To: <db7db9102158b87a4a7169e84e2272b3ba03f9f7.1439954581.git.panand@redhat.com>
References: <db7db9102158b87a4a7169e84e2272b3ba03f9f7.1439954581.git.panand@redhat.com>
Message-ID: <20150819064419.GC9999@pengutronix.de>

Hello,

On Wed, Aug 19, 2015 at 08:58:24AM +0530, Pratyush Anand wrote:
> /sys/class/watchdog/watchdogn/device/modalias can help to identify the
> driver/module for a given watchdog node. However, many wdt devices does not set

s/es//

> its parent and so, we do not see an entry for device in sysfs for such devices.
> 
> This patch fixes parent of watchdog_device so that
> /sys/class/watchdog/watchdogn/device is populated.
> 
> Exceptions: booke, diag288, mpc8xxx, octeon, softdog and w83627hf -- They do not
> have any parent. Not sure, how we can we identify driver for these devices.

I don't see why you don't use the platform device as parent for mpc8xxx.

Note however that I did several updates to the mpc8xxx driver which
probably conflict with setting the parent. I'll take care of that.

Best regards
Uwe

-- 
Pengutronix e.K.                           | Uwe Kleine-K?nig            |
Industrial Linux Solutions                 | http://www.pengutronix.de/  |


From u.kleine-koenig at pengutronix.de  Tue Aug 18 23:51:36 2015
From: u.kleine-koenig at pengutronix.de (Uwe =?iso-8859-1?Q?Kleine-K=F6nig?=)
Date: Wed, 19 Aug 2015 08:51:36 +0200
Subject: [PATCH 8/8] pinctrl: freescale: imx: fix system crash if enable
 two pinctl instances
In-Reply-To: <1439912939-17535-8-git-send-email-aalonso@freescale.com>
References: <1439912939-17535-1-git-send-email-aalonso@freescale.com>
 <1439912939-17535-8-git-send-email-aalonso@freescale.com>
Message-ID: <20150819065136.GD9999@pengutronix.de>

Hello,

On Tue, Aug 18, 2015 at 10:48:59AM -0500, Adrian Alonso wrote:
> From: Robin Gong <b38343 at freescale.com>
> 
> Remove 'static' for 'grp_index', otherwise, it cause the groups whose number is
> smaller than the number of groups of the last pinctl instance never to be
> intialized, thus cause system crash as below
> 
> [    0.661012] [<802a6cb0>] (strcmp) from [<802cc80c>] (imx_dt_node_to_map+0x58/0x208)
> [    0.668879] [<802cc80c>] (imx_dt_node_to_map) from [<802cbe24>] (pinctrl_dt_to_map+0x174/0x2b0)
> [    0.677654] [<802cbe24>] (pinctrl_dt_to_map) from [<802c8f18>] (pinctrl_get+0x100/0x424)
> [    0.685878] [<802c8f18>] (pinctrl_get) from [<802c9510>] (pinctrl_register+0x26c/0x480)
> [    0.694104] [<802c9510>] (pinctrl_register) from [<802ccf3c>] (imx_pinctrl_probe+0x580/0x6e8)
> [    0.702706] [<802ccf3c>] (imx_pinctrl_probe) from [<80351b58>] (platform_drv_probe+0x44/0xa4)
> [    0.711455] [<80351b58>] (platform_drv_probe) from [<803503ec>] (driver_probe_device+0x174/0x2b4)
> [    0.720405] [<803503ec>] (driver_probe_device) from [<803505fc>] (__driver_attach+0x8c/0x90)
> [    0.728982] [<803505fc>] (__driver_attach) from [<8034e930>] (bus_for_each_dev+0x6c/0xa0)
> [    0.737381] [<8034e930>] (bus_for_each_dev) from [<8034fb88>] (bus_add_driver+0x148/0x1f0)
> [    0.745804] [<8034fb88>] (bus_add_driver) from [<80350c00>] (driver_register+0x78/0xf8)
> [    0.753880] [<80350c00>] (driver_register) from [<800097d0>] (do_one_initcall+0x8c/0x1d4)
> [    0.762282] [<800097d0>] (do_one_initcall) from [<80987dac>] (kernel_init_freeable+0x144/0x1e4)
> [    0.771061] [<80987dac>] (kernel_init_freeable) from [<806d9c7c>] (kernel_init+0x8/0xe8)
> [    0.779285] [<806d9c7c>] (kernel_init) from [<8000f628>] (ret_from_fork+0x14/0x2c)
> [    0.786981] Code: e3520000 e5e32001 1afffffb e12fff1e (e4d03001)

When you add a crash log (which is fine) then please don't remove
relevant parts (here the beginning). I'm sure you have a wrong fix here
(as Markus already pointed out). Which machine did this happen on?

Also as general rule it's nice to have the fixes at the beginning of the
series. This allows the maintainer to take the fixes already now and
postpone the cleanups and new features until the next merge window.

Best regards
Uwe

-- 
Pengutronix e.K.                           | Uwe Kleine-K?nig            |
Industrial Linux Solutions                 | http://www.pengutronix.de/  |


From sjoerd.simons at collabora.co.uk  Tue Aug 18 23:56:48 2015
From: sjoerd.simons at collabora.co.uk (Sjoerd Simons)
Date: Wed, 19 Aug 2015 08:56:48 +0200
Subject: [PATCH v3 2/4] ASoC: rockchip: Add rockchip SPDIF transceiver
 driver
In-Reply-To: <1463451.tH10lfH9Hm@phil>
References: <1438947854-3743-1-git-send-email-sjoerd.simons@collabora.co.uk>
 <1438947854-3743-3-git-send-email-sjoerd.simons@collabora.co.uk>
 <1463451.tH10lfH9Hm@phil>
Message-ID: <1439967408.4135.84.camel@collabora.co.uk>

Hey Heiko,

Thanks for the comments, i'm hoping to address them and Marks comments
in a next patch series next week.

On Tue, 2015-08-18 at 20:25 +0200, Heiko Stuebner wrote:

> > +
> > +     spdif->hclk = devm_clk_get(&pdev->dev, "spdif_hclk");

> I guess this could be named just "hclk" - as it is the identifier 
> local to the spdif-ip. (Of course in the binding too)

I'm entirely happy to change that, just wanted to note that the reason
i used spdif_hclk and spidf_clk is for consistency with the rockchip
-i2s binding which uses i2s_hclk ans i2s_mclk. 

However i guess we could update the i2s binding at some poit as well to
follow similar names (with fallbacks to the old one). In general a lot
of the comments yourself and Mark have given actually apply to the
rockchip-i2s code as well so there is some cleanup to do there :)

-- 
Sjoerd Simons
Collabora Ltd.


From lee.jones at linaro.org  Tue Aug 18 23:58:26 2015
From: lee.jones at linaro.org (Lee Jones)
Date: Wed, 19 Aug 2015 07:58:26 +0100
Subject: [PATCH v2 18/21] mfd: htc-pasic3: Prepare driver for leds-pasic3
In-Reply-To: <55D39D25.7010909@tul.cz>
References: <cover.1439843482.git.petr.cvek@tul.cz> <55D25ABC.1000405@tul.cz>
 <20150818065207.GC6180@x1> <55D39D25.7010909@tul.cz>
Message-ID: <20150819065826.GH6180@x1>

On Tue, 18 Aug 2015, Petr Cvek wrote:

> Dne 18.8.2015 v 08:52 Lee Jones napsal(a):
> > On Tue, 18 Aug 2015, Petr Cvek wrote:
> > 
> >> Fix register definitions and prepare structures for new leds-pasic3
> >> driver.
> >>
> >> Signed-off-by: Petr Cvek <petr.cvek at tul.cz>
> >> ---
> >>  drivers/mfd/htc-pasic3.c       | 54 ++++++++++++++++-----------
> >>  include/linux/mfd/htc-pasic3.h | 85 +++++++++++++++++++++++++++++++-----------
> >>  2 files changed, 97 insertions(+), 42 deletions(-)
> >>
> >> diff --git a/drivers/mfd/htc-pasic3.c b/drivers/mfd/htc-pasic3.c
> >> index e88d4f6..16e156d 100644
> >> --- a/drivers/mfd/htc-pasic3.c
> >> +++ b/drivers/mfd/htc-pasic3.c
> >> @@ -3,6 +3,9 @@
> >>   *
> >>   * Copyright (C) 2006 Philipp Zabel <philipp.zabel at gmail.com>
> >>   *
> >> + * 2015:	Added registers for LED and RESET, see htc-pasic3.h
> >> + *		-- Petr Cvek
> >> + *
> > 
> > This is pretty unconventional.
> > 
> > Please look to see what others have done.
> 
> LED support: Petr Cvek <petr.cvek at tul.cz>

We can see what changes/support you added in the Git log.  No need to
reflect that here at all.  If everyone did that, the headers would be
a complete mess.

Just:
 * Copyright (C) 2015 Petr Cvek <petr.cvek at tul.cz>

... will do fine.

> >> @@ -130,6 +140,7 @@ static int __init pasic3_probe(struct platform_device *pdev)
> >>  	struct device *dev = &pdev->dev;
> >>  	struct pasic3_data *asic;
> >>  	struct resource *r;
> >> +	struct pasic3_leds_pdata *leds_pdata;
> >>  	int ret;
> >>  	int irq = 0;
> >>  
> >> @@ -162,6 +173,8 @@ static int __init pasic3_probe(struct platform_device *pdev)
> >>  	/* calculate bus shift from mem resource */
> >>  	asic->bus_shift = (resource_size(r) - 5) >> 3;
> >>  
> >> +	spin_lock_init(&asic->lock);
> >> +
> >>  	if (pdata && pdata->clock_rate) {
> >>  		ds1wm_pdata.clock_rate = pdata->clock_rate;
> >>  		/* the first 5 PASIC3 registers control the DS1WM */
> >> @@ -172,13 +185,12 @@ static int __init pasic3_probe(struct platform_device *pdev)
> >>  			dev_warn(dev, "failed to register DS1WM\n");
> >>  	}
> >>  
> >> -	if (pdata && pdata->led_pdata) {
> >> -		led_cell.platform_data = pdata->led_pdata;
> >> -		led_cell.pdata_size = sizeof(struct pasic3_leds_machinfo);
> >> -		ret = mfd_add_devices(&pdev->dev, pdev->id, &led_cell, 1, r,
> >> -				      0, NULL);
> >> -		if (ret < 0)
> >> -			dev_warn(dev, "failed to register LED device\n");
> >> +	if (pdata && pdata->pasic3_leds) {
> >> +		leds_pdata = dev_get_platdata(&pdata->pasic3_leds->dev);
> > 
> > Whoa!  You're passing a pointer to a device through pdata?
> > 
> > I don't like that at all.  Please explain.
> 
> > 
> >> +		if (leds_pdata) {
> >> +			leds_pdata->mfd_dev = dev;
> >> +			platform_device_register(pdata->pasic3_leds);
> > 
> > What's the idea here?
> 
> Actually, I don't know how to do this in a clean way as
> pasic3_read_register() and pasic3_write_register() require device
> struct to pass address for accessing the registers. Only way would
> be to rewrite all functions which call pasic3_*_register() (removing
> struct device *dev and change it to struct pasic3_data *asic).

I'm still not entirely sure what the problem is.

Why are you calling platform_device_register() instead of using the
MFD API?

Where does the 'struct device' actually get loaded into pdata?

-- 
Lee Jones
Linaro STMicroelectronics Landing Team Lead
Linaro.org ? Open source software for ARM SoCs
Follow Linaro: Facebook | Twitter | Blog


From maitysanchayan at gmail.com  Wed Aug 19 00:22:42 2015
From: maitysanchayan at gmail.com (maitysanchayan at gmail.com)
Date: Wed, 19 Aug 2015 12:52:42 +0530
Subject: [PATCH v3 3/3] touchscreen: colibri-vf50-ts: Add touchscreen
 support for Colibri VF50
In-Reply-To: <20150814225346.GA9160@dtor-ws>
References: <cover.1438763030.git.maitysanchayan@gmail.com>
 <bb234514d6921c3d184930d78e7822381c481b79.1438763030.git.maitysanchayan@gmail.com>
 <20150814225346.GA9160@dtor-ws>
Message-ID: <20150819072242.GA2166@Sanchayan-Arch.toradex.int>

Hello Dmitry,

Will take care of all points with the next revision.

Thank you for the feedback.

- Sanchayan.

On 15-08-14 15:53:46, Dmitry Torokhov wrote:
> Hi Sanchayan,
> 
> On Wed, Aug 05, 2015 at 02:25:51PM +0530, Sanchayan Maity wrote:
> > The Colibri Vybrid VF50 module supports 4-wire touchscreens using
> > FETs and ADC inputs. This driver uses the IIO consumer interface
> > and relies on the vf610_adc driver based on the IIO framework.
> > 
> > Signed-off-by: Sanchayan Maity <maitysanchayan at gmail.com>
> > ---
> >  drivers/input/touchscreen/Kconfig           |  12 +
> >  drivers/input/touchscreen/Makefile          |   1 +
> >  drivers/input/touchscreen/colibri-vf50-ts.c | 404 ++++++++++++++++++++++++++++
> >  3 files changed, 417 insertions(+)
> >  create mode 100644 drivers/input/touchscreen/colibri-vf50-ts.c
> > 
> > diff --git a/drivers/input/touchscreen/Kconfig b/drivers/input/touchscreen/Kconfig
> > index 80f6386..28948ca 100644
> > --- a/drivers/input/touchscreen/Kconfig
> > +++ b/drivers/input/touchscreen/Kconfig
> > @@ -1027,4 +1027,16 @@ config TOUCHSCREEN_ZFORCE
> >  	  To compile this driver as a module, choose M here: the
> >  	  module will be called zforce_ts.
> >  
> > +config TOUCHSCREEN_COLIBRI_VF50
> > +	tristate "Toradex Colibri on board touchscreen driver"
> > +	depends on GPIOLIB && IIO && VF610_ADC
> > +	help
> > +	  Say Y here if you have a Colibri VF50 and plan to use
> > +	  the on-board provided 4-wire touchscreen driver.
> > +
> > +	  If unsure, say N.
> > +
> > +	  To compile this driver as a module, choose M here: the
> > +	  module will be called colibri_vf50_ts.
> > +
> >  endif
> > diff --git a/drivers/input/touchscreen/Makefile b/drivers/input/touchscreen/Makefile
> > index 44deea7..93746a0 100644
> > --- a/drivers/input/touchscreen/Makefile
> > +++ b/drivers/input/touchscreen/Makefile
> > @@ -84,3 +84,4 @@ obj-$(CONFIG_TOUCHSCREEN_W90X900)	+= w90p910_ts.o
> >  obj-$(CONFIG_TOUCHSCREEN_SX8654)	+= sx8654.o
> >  obj-$(CONFIG_TOUCHSCREEN_TPS6507X)	+= tps6507x-ts.o
> >  obj-$(CONFIG_TOUCHSCREEN_ZFORCE)	+= zforce_ts.o
> > +obj-$(CONFIG_TOUCHSCREEN_COLIBRI_VF50)	+= colibri-vf50-ts.o
> > diff --git a/drivers/input/touchscreen/colibri-vf50-ts.c b/drivers/input/touchscreen/colibri-vf50-ts.c
> > new file mode 100644
> > index 0000000..d7bc91a
> > --- /dev/null
> > +++ b/drivers/input/touchscreen/colibri-vf50-ts.c
> > @@ -0,0 +1,404 @@
> > +/* Copyright 2015 Toradex AG
> > + *
> > + * Toradex Colibri VF50 Touchscreen driver
> > + *
> > + * Originally authored by Stefan Agner for 3.0 kernel
> > + *
> > + * 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.
> > + */
> > +
> > +#include <linux/delay.h>
> > +#include <linux/err.h>
> > +#include <linux/gpio.h>
> > +#include <linux/iio/consumer.h>
> > +#include <linux/iio/types.h>
> > +#include <linux/input.h>
> > +#include <linux/interrupt.h>
> > +#include <linux/kernel.h>
> > +#include <linux/module.h>
> > +#include <linux/pinctrl/consumer.h>
> > +#include <linux/platform_device.h>
> > +#include <linux/slab.h>
> > +#include <linux/types.h>
> > +
> > +#define DRIVER_NAME "colibri-vf50-ts"
> > +#define DRV_VERSION "1.0"
> > +
> > +#define VF_ADC_MAX ((1 << 12) - 1)
> > +
> > +#define COLI_TOUCH_MIN_DELAY_US 1000
> > +#define COLI_TOUCH_MAX_DELAY_US 2000
> > +
> > +static int min_pressure = 200;
> > +
> > +struct vf50_touch_device {
> > +	struct platform_device	*pdev;
> > +	struct input_dev	*ts_input;
> > +	struct iio_channel	*channels;
> > +	struct gpio_desc *gpio_xp;
> > +	struct gpio_desc *gpio_xm;
> > +	struct gpio_desc *gpio_yp;
> > +	struct gpio_desc *gpio_ym;
> > +	struct gpio_desc *gpio_pen_detect;
> > +	int pen_irq;
> > +	bool stop_touchscreen;
> > +};
> > +
> > +/*
> > + * Enables given plates and measures touch parameters using ADC
> > + */
> > +static int adc_ts_measure(struct iio_channel *channel,
> > +		  struct gpio_desc *plate_p, struct gpio_desc *plate_m)
> > +{
> > +	int i, value = 0, val = 0;
> > +	int ret;
> > +
> > +	gpiod_set_value(plate_p, 1);
> > +	gpiod_set_value(plate_m, 1);
> > +
> > +	usleep_range(COLI_TOUCH_MIN_DELAY_US, COLI_TOUCH_MAX_DELAY_US);
> > +
> > +	for (i = 0; i < 5; i++) {
> 
> Can we have a #define for 5?
> 
> > +		ret = iio_read_channel_raw(channel, &val);
> > +		if (ret < 0) {
> > +			value = ret;
> > +			goto error_iio_read;
> > +		}
> > +
> > +		value += val;
> > +	}
> > +
> > +	value /= 5;
> > +
> > +error_iio_read:
> > +	gpiod_set_value(plate_p, 0);
> > +	gpiod_set_value(plate_m, 0);
> > +
> > +	return value;
> > +}
> > +
> > +/*
> > + * Enable touch detection using falling edge detection on XM
> > + */
> > +static void vf50_ts_enable_touch_detection(struct vf50_touch_device *vf50_ts)
> > +{
> > +	/* Enable plate YM (needs to be strong GND, high active) */
> > +	gpiod_set_value(vf50_ts->gpio_ym, 1);
> > +
> > +	/*
> > +	 * Let the platform mux to idle state in order to enable
> > +	 * Pull-Up on GPIO
> > +	 */
> > +	pinctrl_pm_select_idle_state(&vf50_ts->pdev->dev);
> > +}
> > +
> > +/*
> > + * ADC touch screen sampling bottom half irq handler
> > + */
> > +static irqreturn_t vf50_ts_irq_bh(int irq, void *private)
> > +{
> > +	struct vf50_touch_device *vf50_ts = (struct vf50_touch_device *)private;
> > +	struct device *dev = &vf50_ts->pdev->dev;
> > +	int val_x, val_y, val_z1, val_z2, val_p = 0;
> > +	bool discard_val_on_start = true;
> > +
> > +	/* Disable the touch detection plates */
> > +	gpiod_set_value(vf50_ts->gpio_ym, 0);
> > +
> > +	/* Let the platform mux to default state in order to mux as ADC */
> > +	pinctrl_pm_select_default_state(dev);
> > +
> > +	while (!vf50_ts->stop_touchscreen) {
> > +		/* X-Direction */
> > +		val_x = adc_ts_measure(&vf50_ts->channels[0],
> > +				vf50_ts->gpio_xp, vf50_ts->gpio_xm);
> > +		if (val_x < 0)
> > +			break;
> > +
> > +		/* Y-Direction */
> > +		val_y = adc_ts_measure(&vf50_ts->channels[1],
> > +				vf50_ts->gpio_yp, vf50_ts->gpio_ym);
> > +		if (val_y < 0)
> > +			break;
> > +
> > +		/*
> > +		 * Touch pressure
> > +		 * Measure on XP/YM
> > +		 */
> > +		val_z1 = adc_ts_measure(&vf50_ts->channels[2],
> > +				vf50_ts->gpio_yp, vf50_ts->gpio_xm);
> > +		if (val_z1 < 0)
> > +			break;
> > +		val_z2 = adc_ts_measure(&vf50_ts->channels[3],
> > +				vf50_ts->gpio_yp, vf50_ts->gpio_xm);
> > +		if (val_z2 < 0)
> > +			break;
> > +
> > +		/* Validate signal (avoid calculation using noise) */
> > +		if (val_z1 > 64 && val_x > 64) {
> > +			/*
> > +			 * Calculate resistance between the plates
> > +			 * lower resistance means higher pressure
> > +			 */
> > +			int r_x = (1000 * val_x) / VF_ADC_MAX;
> > +
> > +			val_p = (r_x * val_z2) / val_z1 - r_x;
> > +
> > +		} else {
> > +			val_p = 2000;
> > +		}
> > +
> > +		val_p = 2000 - val_p;
> > +		dev_dbg(dev, "Measured values: x: %d, y: %d, z1: %d, z2: %d, "
> > +			"p: %d\n", val_x, val_y, val_z1, val_z2, val_p);
> > +
> > +		/*
> > +		 * If touch pressure is too low, stop measuring and reenable
> > +		 * touch detection
> > +		 */
> > +		if (val_p < min_pressure || val_p > 2000)
> > +			break;
> > +
> > +		/*
> > +		 * The pressure may not be enough for the first x and the
> > +		 * second y measurement, but, the pressure is ok when the
> > +		 * driver is doing the third and fourth measurement. To
> > +		 * take care of this, we drop the first measurement always.
> > +		 */
> > +		if (discard_val_on_start) {
> > +			discard_val_on_start = false;
> > +		} else {
> > +			/*
> > +			 * Report touch position and sleep for
> > +			 * next measurement
> > +			 */
> > +			input_report_abs(vf50_ts->ts_input,
> > +					ABS_X, VF_ADC_MAX - val_x);
> > +			input_report_abs(vf50_ts->ts_input,
> > +					ABS_Y, VF_ADC_MAX - val_y);
> > +			input_report_abs(vf50_ts->ts_input,
> > +					ABS_PRESSURE, val_p);
> > +			input_report_key(vf50_ts->ts_input, BTN_TOUCH, 1);
> > +			input_sync(vf50_ts->ts_input);
> > +		}
> > +
> > +		msleep(10);
> > +	}
> > +
> > +	/* Report no more touch, reenable touch detection */
> > +	input_report_abs(vf50_ts->ts_input, ABS_PRESSURE, 0);
> > +	input_report_key(vf50_ts->ts_input, BTN_TOUCH, 0);
> > +	input_sync(vf50_ts->ts_input);
> > +
> > +	vf50_ts_enable_touch_detection(vf50_ts);
> > +
> > +	/* Wait for the pull-up to be stable on high */
> > +	msleep(10);
> > +
> > +	return IRQ_HANDLED;
> > +}
> > +
> > +static int vf50_ts_open(struct input_dev *dev_input)
> > +{
> > +	int ret;
> > +	struct vf50_touch_device *touchdev = input_get_drvdata(dev_input);
> > +	struct device *dev = &touchdev->pdev->dev;
> > +
> > +	dev_dbg(dev, "Input device %s opened, starting touch detection\n",
> > +			dev_input->name);
> > +
> > +	touchdev->stop_touchscreen = false;
> > +
> > +	ret = gpiod_direction_output(touchdev->gpio_xp, 0);
> > +	if (ret) {
> > +		dev_err(dev, "Could not set gpio xp as output %d\n", ret);
> > +		return ret;
> > +	}
> > +
> > +	ret = gpiod_direction_output(touchdev->gpio_xm, 0);
> > +	if (ret) {
> > +		dev_err(dev, "Could not set gpio xm as output %d\n", ret);
> > +		return ret;
> > +	}
> > +
> > +	ret = gpiod_direction_output(touchdev->gpio_yp, 0);
> > +	if (ret) {
> > +		dev_err(dev, "Could not set gpio yp as output %d\n", ret);
> > +		return ret;
> > +	}
> > +
> > +	ret = gpiod_direction_output(touchdev->gpio_ym, 0);
> > +	if (ret) {
> > +		dev_err(dev, "Could not set gpio ym as output %d\n", ret);
> > +		return ret;
> > +	}
> > +
> > +	ret = gpiod_direction_input(touchdev->gpio_pen_detect);
> > +	if (ret) {
> > +		dev_err(dev,
> > +			"Could not set gpio pen detect as input %d\n", ret);
> > +		return ret;
> > +	}
> 
> Why do we do this on every open? You can configure gpios as you request
> them.
> 
> > +
> > +	/* Mux detection before request IRQ, wait for pull-up to settle */
> > +	vf50_ts_enable_touch_detection(touchdev);
> > +	msleep(10);
> > +
> > +	return 0;
> > +}
> > +
> > +static void vf50_ts_close(struct input_dev *dev_input)
> > +{
> > +	struct vf50_touch_device *touchdev = input_get_drvdata(dev_input);
> > +	struct device *dev = &touchdev->pdev->dev;
> > +
> > +	touchdev->stop_touchscreen = true;
> 
> I think you also need:
> 
> 	mb();
> 	synchronize_irq(touchdev->irq);
> 
> to make sure interrupt routine is not running past close.
> 
> > +
> > +	dev_dbg(dev, "Input device %s closed, disable touch detection\n",
> > +		dev_input->name);
> > +}
> > +
> > +static inline int vf50_ts_get_gpiod(struct device *dev,
> 
> Drop inline, let compiler decide whether it should be inlined or not.
> 
> > +			struct gpio_desc **gpio_d, const char *con_id)
> > +{
> > +	int ret;
> 
> Personal preference: call this variable "error".
> 
> > +
> > +	*gpio_d = devm_gpiod_get(dev, con_id);
> 
> I think you need use GPIOD_OUT_LOW (assuming you do not use the function
> for pen detect gpio, see below).
> 
> > +	if (IS_ERR(*gpio_d)) {
> > +		ret = PTR_ERR(*gpio_d);
> > +		dev_err(dev, "Could not get gpio_%s %d\n", con_id, ret);
> > +		return ret;
> > +	}
> > +
> > +	return 0;
> > +}
> > +
> > +static int vf50_ts_probe(struct platform_device *pdev)
> > +{
> > +	struct input_dev *input;
> > +	struct iio_channel *channels;
> > +	struct device *dev = &pdev->dev;
> > +	struct vf50_touch_device *touchdev;
> > +	int ret;
> 
> Personal preference: call this variable "error".
> 
> 
> > +
> > +	channels = iio_channel_get_all(dev);
> > +	if (IS_ERR(channels))
> > +		return PTR_ERR(channels);
> 
> 
> Please either introduce devm_iio_channel_get_all() or install
> iio_channel_release_all as a custom devm action (devm_add_action).
> 
> > +
> > +	touchdev = devm_kzalloc(dev, sizeof(*touchdev), GFP_KERNEL);
> > +	if (touchdev == NULL) {
> 
> 	if (!touchdev)
> 
> please.
> 
> > +		ret = -ENOMEM;
> > +		goto error_release_channels;
> > +	}
> > +
> > +	input = devm_input_allocate_device(dev);
> > +	if (!input) {
> > +		dev_err(dev, "Failed to allocate TS input device\n");
> > +		ret = -ENOMEM;
> > +		goto error_release_channels;
> > +	}
> > +
> > +	platform_set_drvdata(pdev, touchdev);
> > +
> > +	touchdev->pdev = pdev;
> > +	touchdev->channels = channels;
> > +
> > +	input->name = DRIVER_NAME;
> > +	input->id.bustype = BUS_HOST;
> > +	input->dev.parent = dev;
> > +	input->open = vf50_ts_open;
> > +	input->close = vf50_ts_close;
> > +
> > +	_set_bit(EV_ABS, input->evbit);
> > +	_set_bit(EV_KEY, input->evbit);
> > +	_set_bit(BTN_TOUCH, input->keybit);
> 
> input_set_capability(dev, EV_KEY, BTN_TOUCH);
> 
> and kill _set_bit()s above.
> 
> > +	input_set_abs_params(input, ABS_X, 0, VF_ADC_MAX, 0, 0);
> > +	input_set_abs_params(input, ABS_Y, 0, VF_ADC_MAX, 0, 0);
> > +	input_set_abs_params(input, ABS_PRESSURE, 0, VF_ADC_MAX, 0, 0);
> > +
> > +	touchdev->ts_input = input;
> > +	input_set_drvdata(input, touchdev);
> > +	ret = input_register_device(input);
> > +	if (ret) {
> > +		dev_err(dev, "Failed to register input device\n");
> > +		goto error_release_channels;
> > +	}
> > +
> > +	ret = vf50_ts_get_gpiod(dev, &touchdev->gpio_xp, "xp");
> > +	if (ret)
> > +		goto error_release_channels;
> > +
> > +	ret = vf50_ts_get_gpiod(dev, &touchdev->gpio_xm, "xm");
> > +	if (ret)
> > +		goto error_release_channels;
> > +
> > +	ret = vf50_ts_get_gpiod(dev, &touchdev->gpio_yp, "yp");
> > +	if (ret)
> > +		goto error_release_channels;
> > +
> > +	ret = vf50_ts_get_gpiod(dev, &touchdev->gpio_ym, "ym");
> > +	if (ret)
> > +		goto error_release_channels;
> > +
> > +	ret = vf50_ts_get_gpiod(dev, &touchdev->gpio_pen_detect,
> > +				"pen-detect");
> > +	if (ret)
> > +		goto error_release_channels;
> > +
> > +	touchdev->pen_irq = gpiod_to_irq(touchdev->gpio_pen_detect);
> > +	if (touchdev->pen_irq < 0) {
> > +		ret = touchdev->pen_irq;
> > +		dev_err(dev, "Unable to get IRQ for GPIO\n");
> > +		goto error_release_channels;
> > +	}
> 
> I do not think you need to specify this as gpio, since you are not
> reading it's state. Map it using "interrupts" property instead and do
> 
> 	touchdev->pen_irq = platform_get_irq(pdev, 0);
> 
> > +
> > +	ret = devm_request_threaded_irq(dev, touchdev->pen_irq, NULL,
> > +			vf50_ts_irq_bh, IRQF_TRIGGER_LOW | IRQF_ONESHOT,
> 
> Just use IRQF_ONESHOT here, rely on the platform/OF to read and set up
> the trigger properly (via "interrupts" property).
> 
> > +			"vf50 touch", touchdev);
> > +	if (ret < 0) {
> > +		dev_err(dev, "Unable to request IRQ %d\n", touchdev->pen_irq);
> > +		goto error_release_channels;
> > +	}
> > +
> > +	return 0;
> > +
> > +error_release_channels:
> > +	iio_channel_release_all(channels);
> > +	return ret;
> > +}
> > +
> > +static int vf50_ts_remove(struct platform_device *pdev)
> > +{
> > +	struct vf50_touch_device *touchdev = platform_get_drvdata(pdev);
> > +
> > +	iio_channel_release_all(touchdev->channels);
> 
> This is wrong order, I do not think you want to release channels while
> your interrupt routine still running. With custom devm action you can
> avoid this and also remove whole vf50_ts_remove.
> 
> > +
> > +	return 0;
> > +}
> > +
> > +static const struct of_device_id vf50_touch_of_match[] = {
> > +	{ .compatible = "toradex,vf50-touchscreen", },
> > +	{ }
> > +};
> > +MODULE_DEVICE_TABLE(of, vf50_touch_of_match);
> > +
> > +static struct platform_driver vf50_touch_driver = {
> > +	.driver = {
> > +		.name = "toradex,vf50_touchctrl",
> > +		.of_match_table = vf50_touch_of_match,
> > +	},
> > +	.probe = vf50_ts_probe,
> > +	.remove = vf50_ts_remove,
> > +};
> > +
> > +module_platform_driver(vf50_touch_driver);
> > +
> > +module_param(min_pressure, int, 0600);
> > +MODULE_PARM_DESC(min_pressure, "Minimum pressure for touch detection");
> 
> Since it is my understanding this is not user preference but rather
> property of device, I'd rather this been part of DT binding.
> 
> > +MODULE_AUTHOR("Sanchayan Maity");
> > +MODULE_DESCRIPTION("Colibri VF50 Touchscreen driver");
> > +MODULE_LICENSE("GPL v2");
> > +MODULE_VERSION(DRV_VERSION);
> > -- 
> > 2.5.0
> > 
> 
> Thanks.
> 
> -- 
> Dmitry


From heiko at sntech.de  Wed Aug 19 00:28:06 2015
From: heiko at sntech.de (Heiko Stuebner)
Date: Wed, 19 Aug 2015 09:28:06 +0200
Subject: [PATCH v3 2/4] ASoC: rockchip: Add rockchip SPDIF transceiver
 driver
In-Reply-To: <1439967408.4135.84.camel@collabora.co.uk>
References: <1438947854-3743-1-git-send-email-sjoerd.simons@collabora.co.uk>
 <1463451.tH10lfH9Hm@phil> <1439967408.4135.84.camel@collabora.co.uk>
Message-ID: <2559509.ITzpmR5XN3@phil>

Hi Sjoerd,

Am Mittwoch, 19. August 2015, 08:56:48 schrieb Sjoerd Simons:
> Hey Heiko,
> 
> Thanks for the comments, i'm hoping to address them and Marks comments
> in a next patch series next week.
> 
> On Tue, 2015-08-18 at 20:25 +0200, Heiko Stuebner wrote:
> > > +
> > > +     spdif->hclk = devm_clk_get(&pdev->dev, "spdif_hclk");
> > 
> > I guess this could be named just "hclk" - as it is the identifier
> > local to the spdif-ip. (Of course in the binding too)
> 
> I'm entirely happy to change that, just wanted to note that the reason
> i used spdif_hclk and spidf_clk is for consistency with the rockchip
> -i2s binding which uses i2s_hclk ans i2s_mclk.

I was also just remembering something Thierry Reding said in the edp thread: 
"The names are in a per-driver scope, so "dp-phy" is implied by the device 
tree binding and driver already. You could simply use shorter names such as 
"phy" and "24m" for example."


> However i guess we could update the i2s binding at some poit as well to
> follow similar names (with fallbacks to the old one). In general a lot
> of the comments yourself and Mark have given actually apply to the
> rockchip-i2s code as well so there is some cleanup to do there :)

I'm not sure about updating the binding though, as it we'd need to provide 
backwards-compatibility for the old names as well. So I don't think renaming 
these will bring much benefit, but we can choose better names for followup 
drivers like the spdif.

I haven't looked to much into the i2s stuff yet. But with me getting a grasp on 
the fractional dividers and the hardware drivers making it into the asoc tree 
now, I also plan to give the i2s audio on the Chromebooks a try :-)


Heiko


From philipp.zabel at gmail.com  Wed Aug 19 00:29:42 2015
From: philipp.zabel at gmail.com (Philipp Zabel)
Date: Wed, 19 Aug 2015 09:29:42 +0200
Subject: [PATCH v2 01/21] ARM: pxa: magician: Fix Kconfig for magician
 to always include htc-egpio
In-Reply-To: <55D38F60.7010405@tul.cz>
References: <cover.1439843482.git.petr.cvek@tul.cz>
 <55D25880.3030507@tul.cz> <87zj1o8n3w.fsf@belgarion.home>
 <55D38F60.7010405@tul.cz>
Message-ID: <1439969382.11928.6.camel@gmail.com>

Am Dienstag, den 18.08.2015, 22:02 +0200 schrieb Petr Cvek:
> Dne 18.8.2015 v 20:31 Robert Jarzmik napsal(a):
> > Petr Cvek <petr.cvek at tul.cz> writes:
> > 
> > > The htc-egpio driver should be always included in the kernel as 
> > > it
> > > controls MMC/charging/IrDA power, which is the only way to get
> > > an useful rootfs.
> > > 
> > > Signed-off-by: Petr Cvek <petr.cvek at tul.cz>
> > It's already defined in magician_defconfig, why enforce it in 
> > Kconfig ?
> 
> Good remark, I did not use defconfig at all (as I had to fix from 
> zero configuration + I did not know if defconfig works and will be 
> supported in the future).
> 
> I will check if magician_defconfig needs to be updated (probably for 
> leds).
> 
> > 
> > And if it's enforced and I want to build a kernel for magician 
> > without
> > MMC/charging/IrDA, why should I be forced to build in HTC_EGPIO ?
> > 
> > Or said differently, does a kernel without HTC_EGPIO is proven to 
> > fail 100%
> > without this option ?
> 
> Kernel will probably run OK, but the phone will be unusable (for any 
> practical purposes). The EGPIO chip (CPLD) will stay in the state 
> programmed from the previous environment (bootloader or WinCE/Mobile) 
> and drivers fail to init because of the missing EGPIO (and if they 
> init, they will be without any idea about state of the peripherals 
> (no charger detection/charging current stuck on the previous 
> settings, no LCD backlight control, no IrDA, no rootfs, no GSM, no 
> sound, no LEDs).
> 
> Different PCB revisions probably use EGPIO pin for LCD power (and at 
> least on my phone, LCD power must have very specific order).
> 
> For future (when ROM XIP will work) I would like to be able boot 
> kernel from flash, which itself uses EGPIO for Vpp control (another 
> initial EGPIO configuration). Last possible boot is from JTAG and 
> there will be no previous EGPIO initialization.
> 
> Petr

I agree with Robert, let's drop this patch.

regards
Philipp


From philipp.zabel at gmail.com  Wed Aug 19 00:42:58 2015
From: philipp.zabel at gmail.com (Philipp Zabel)
Date: Wed, 19 Aug 2015 09:42:58 +0200
Subject: [PATCH v2 02/21] ARM: pxa: magician: Fix indentation and
 whitespaces
In-Reply-To: <55D258A6.2040105@tul.cz>
References: <cover.1439843482.git.petr.cvek@tul.cz> <55D258A6.2040105@tul.cz>
Message-ID: <1439970178.11928.15.camel@gmail.com>

Am Montag, den 17.08.2015, 23:56 +0200 schrieb Petr Cvek:
> Fix magician.c: indentation and whitespaces.
> 
> Signed-off-by: Petr Cvek <petr.cvek at tul.cz>
> ---
>  arch/arm/mach-pxa/magician.c | 356 +++++++++++++++++++++------------
> ----------
>  1 file changed, 178 insertions(+), 178 deletions(-)
> 
> diff --git a/arch/arm/mach-pxa/magician.c b/arch/arm/mach
> -pxa/magician.c
> index a9761c2..9e8698a 100644
> --- a/arch/arm/mach-pxa/magician.c
> +++ b/arch/arm/mach-pxa/magician.c
> @@ -52,8 +52,8 @@ static unsigned long magician_pin_config[] 
> __initdata = {
>  	GPIO20_nSDCS_2,
>  	GPIO21_nSDCS_3,
>  	GPIO15_nCS_1,
> -	GPIO78_nCS_2,   /* PASIC3 */
> -	GPIO79_nCS_3,   /* EGPIO CPLD */
> +	GPIO78_nCS_2,	/* PASIC3 */
> +	GPIO79_nCS_3,	/* EGPIO CPLD */
>  	GPIO80_nCS_4,
>  	GPIO33_nCS_5,
>  
> @@ -107,7 +107,7 @@ static unsigned long magician_pin_config[] 


Yay.

> __initdata = {
>  	GPIO85_CIF_LV,
>  
>  	/* Magician specific input GPIOs */
> -	GPIO9_GPIO,	/* unknown */
> +	GPIO9_GPIO,		/* unknown */
>  	GPIO10_GPIO,	/* GSM_IRQ */
>  	GPIO13_GPIO,	/* CPLD_IRQ */
>  	GPIO107_GPIO,	/* DS1WM_IRQ */

Nay. Are you using 8-space tabs?

> @@ -133,46 +133,45 @@ static struct pxaficp_platform_data 
> magician_ficp_info = {
>   */
>  
>  #define INIT_KEY(_code, _gpio, _desc)	\
> -	{				\
> -		.code   = KEY_##_code,	\
> -		.gpio   = _gpio,	\
> -		.desc   = _desc,	\
> -		.type   = EV_KEY,	\
> -		.wakeup = 1,		\
> +	{						\
> +		.code	= KEY_##_code,	\
> +		.gpio	= _gpio,	\
> +		.desc	= _desc,	\
> +		.type	= EV_KEY,	\
> +		.wakeup	= 1,		\
>  	}

Ok.

>  static struct gpio_keys_button magician_button_table[] = {
> -	INIT_KEY(POWER,      GPIO0_MAGICIAN_KEY_POWER,      "Power 
> button"),
> -	INIT_KEY(ESC,        GPIO37_MAGICIAN_KEY_HANGUP,    "Hangup 
> button"),
> -	INIT_KEY(F10,        GPIO38_MAGICIAN_KEY_CONTACTS, 
>  "Contacts button"),
> -	INIT_KEY(CALENDAR,   GPIO90_MAGICIAN_KEY_CALENDAR, 
>  "Calendar button"),
> -	INIT_KEY(CAMERA,     GPIO91_MAGICIAN_KEY_CAMERA,    "Camera 
> button"),
> -	INIT_KEY(UP,         GPIO93_MAGICIAN_KEY_UP,        "Up 
> button"),
> -	INIT_KEY(DOWN,       GPIO94_MAGICIAN_KEY_DOWN,      "Down 
> button"),
> -	INIT_KEY(LEFT,       GPIO95_MAGICIAN_KEY_LEFT,      "Left 
> button"),
> -	INIT_KEY(RIGHT,      GPIO96_MAGICIAN_KEY_RIGHT,     "Right 
> button"),
> -	INIT_KEY(KPENTER,    GPIO97_MAGICIAN_KEY_ENTER,     "Action 
> button"),
> -	INIT_KEY(RECORD,     GPIO98_MAGICIAN_KEY_RECORD,    "Record 
> button"),
> -	INIT_KEY(VOLUMEUP,   GPIO100_MAGICIAN_KEY_VOL_UP,   "Volume 
> up"),
> -	INIT_KEY(VOLUMEDOWN, GPIO101_MAGICIAN_KEY_VOL_DOWN, "Volume 
> down"),
> -	INIT_KEY(PHONE,      GPIO102_MAGICIAN_KEY_PHONE,    "Phone 
> button"),
> -	INIT_KEY(PLAY,       GPIO99_MAGICIAN_HEADPHONE_IN,  "Headset 
> button"),
> +	INIT_KEY(POWER,		GPIO0_MAGICIAN_KEY_POWER,	> "Power 
> button"),
> +	INIT_KEY(ESC,		GPIO37_MAGICIAN_KEY_HANGUP,	"Han
> gup button"),
> +	INIT_KEY(F10,		GPIO38_MAGICIAN_KEY_CONTACTS,	"Con
> tacts button"),
> +	INIT_KEY(CALENDAR,	GPIO90_MAGICIAN_KEY_CALENDAR,	"Cal
> endar button"),
> +	INIT_KEY(CAMERA,	GPIO91_MAGICIAN_KEY_CAMERA,	"Cam
> era button"),
> +	INIT_KEY(UP,		GPIO93_MAGICIAN_KEY_UP,		> "Up 
> button"),
> +	INIT_KEY(DOWN,		GPIO94_MAGICIAN_KEY_DOWN,	"Dow
> n button"),
> +	INIT_KEY(LEFT,		GPIO95_MAGICIAN_KEY_LEFT,	"Lef
> t button"),
> +	INIT_KEY(RIGHT,		GPIO96_MAGICIAN_KEY_RIGHT,	> "Right 
> button"),
> +	INIT_KEY(KPENTER,	GPIO97_MAGICIAN_KEY_ENTER,	"Act
> ion button"),
> +	INIT_KEY(RECORD,	GPIO98_MAGICIAN_KEY_RECORD,	"Rec
> ord button"),
> +	INIT_KEY(VOLUMEUP,	GPIO100_MAGICIAN_KEY_VOL_UP,	"Vol
> ume up"),
> +	INIT_KEY(VOLUMEDOWN,	GPIO101_MAGICIAN_KEY_VOL_DOWN,	"Vol
> ume down"),
> +	INIT_KEY(PHONE,		GPIO102_MAGICIAN_KEY_PHONE,	> "Phone 
> button"),
> +	INIT_KEY(PLAY,		GPIO99_MAGICIAN_HEADPHONE_IN,	"Hea
> dset button"),
>  };

I don't like this. The tabs cause long lines and it's not like we
expect additional keys to appear that would warrant the reformatting.

>   static struct gpio_keys_platform_data gpio_keys_data = {
> -	.buttons  = magician_button_table,
> +	.buttons = magician_button_table,
>  	.nbuttons = ARRAY_SIZE(magician_button_table),
>  };
>  
>  static struct platform_device gpio_keys = {
>  	.name = "gpio-keys",
> -	.dev  = {
> +	.dev = {
>  		.platform_data = &gpio_keys_data,
>  	},
> -	.id   = -1,
> +	.id = -1,
>  };

Hm, so are we aligning at =, or are we not?


>  /*
>   * EGPIO (Xilinx CPLD)
>   *
> @@ -181,14 +180,14 @@ static struct platform_device gpio_keys = {
>  
>  static struct resource egpio_resources[] = {
>  	[0] = {
> -		.start = PXA_CS3_PHYS,
> -		.end   = PXA_CS3_PHYS + 0x20 - 1,
> -		.flags = IORESOURCE_MEM,
> +		.start	= PXA_CS3_PHYS,
> +		.end	= PXA_CS3_PHYS + 0x20 - 1,
> +		.flags	= IORESOURCE_MEM,
>  	},
>  	[1] = {
> -		.start = PXA_GPIO_TO_IRQ(GPIO13_MAGICIAN_CPLD_IRQ),
> -		.end   = PXA_GPIO_TO_IRQ(GPIO13_MAGICIAN_CPLD_IRQ),
> -		.flags = IORESOURCE_IRQ,
> +		.start	= PXA_GPIO_TO_IRQ(GPIO13_MAGICIAN_CPLD_IRQ),
> +		.end	= PXA_GPIO_TO_IRQ(GPIO13_MAGICIAN_CPLD_IRQ),
> +		.flags	= IORESOURCE_IRQ,
>  	},
>  };

I'm not a fan of reformatting unless there's a reason (like the mixture
of space and tab warnings). But as long as this doesn't introduce new
issues like long lines, and as long as it's done consequently, I'm fine
with this.

> @@ -209,20 +208,20 @@ static struct htc_egpio_chip egpio_chips[] = {
>  };
>  
>  static struct htc_egpio_platform_data egpio_info = {
> -	.reg_width    = 8,
> -	.bus_width    = 32,
> -	.irq_base     = IRQ_BOARD_START,
> -	.num_irqs     = 4,
> -	.ack_register = 3,
> -	.chip         = egpio_chips,
> -	.num_chips    = ARRAY_SIZE(egpio_chips),
> +	.reg_width	= 8,
> +	.bus_width	= 32,
> +	.irq_base	= IRQ_BOARD_START,
> +	.num_irqs	= 4,
> +	.ack_register	= 3,
> +	.chip		= egpio_chips,
> +	.num_chips	= ARRAY_SIZE(egpio_chips),
>  };
>  
>  static struct platform_device egpio = {
> -	.name          = "htc-egpio",
> -	.id            = -1,
> -	.resource      = egpio_resources,
> -	.num_resources = ARRAY_SIZE(egpio_resources),
> +	.name		= "htc-egpio",
> +	.id		= -1,
> +	.resource	= egpio_resources,
> +	.num_resources	= ARRAY_SIZE(egpio_resources),
>  	.dev = {
>  		.platform_data = &egpio_info,
>  	},
> @@ -234,33 +233,33 @@ static struct platform_device egpio = {
>  
>  static struct pxafb_mode_info toppoly_modes[] = {
>  	{
> -		.pixclock     = 96153,
> -		.bpp          = 16,
> -		.xres         = 240,
> -		.yres         = 320,
> -		.hsync_len    = 11,
> -		.vsync_len    = 3,
> -		.left_margin  = 19,
> -		.upper_margin = 2,
> -		.right_margin = 10,
> -		.lower_margin = 2,
> -		.sync         = 0,
> +		.pixclock	= 96153,
> +		.bpp		= 16,
> +		.xres		= 240,
> +		.yres		= 320,
> +		.hsync_len	= 11,
> +		.vsync_len	= 3,
> +		.left_margin	= 19,
> +		.upper_margin	= 2,
> +		.right_margin	= 10,
> +		.lower_margin	= 2,
> +		.sync		= 0,
>  	},
>  };
>  
>  static struct pxafb_mode_info samsung_modes[] = {
>  	{
> -		.pixclock     = 96153,
> -		.bpp          = 16,
> -		.xres         = 240,
> -		.yres         = 320,
> -		.hsync_len    = 8,
> -		.vsync_len    = 4,
> -		.left_margin  = 9,
> -		.upper_margin = 4,
> -		.right_margin = 9,
> -		.lower_margin = 4,
> -		.sync         = FB_SYNC_HOR_HIGH_ACT | 
> FB_SYNC_VERT_HIGH_ACT,
> +		.pixclock	= 96153,
> +		.bpp		= 16,
> +		.xres		= 240,
> +		.yres		= 320,
> +		.hsync_len	= 8,
> +		.vsync_len	= 4,
> +		.left_margin	= 9,
> +		.upper_margin	= 4,
> +		.right_margin	= 9,
> +		.lower_margin	= 4,
> +		.sync	= FB_SYNC_HOR_HIGH_ACT | 
> FB_SYNC_VERT_HIGH_ACT,
>  	},
>  };
>  
> @@ -326,19 +325,19 @@ static void samsung_lcd_power(int on, struct 
> fb_var_screeninfo *si)
>  }
>  
>  static struct pxafb_mach_info toppoly_info = {
> -	.modes           = toppoly_modes,
> -	.num_modes       = 1,
> -	.fixed_modes     = 1,
> +	.modes		= toppoly_modes,
> +	.num_modes	= 1,
> +	.fixed_modes	= 1,
>  	.lcd_conn	= LCD_COLOR_TFT_16BPP,
>  	.pxafb_lcd_power = toppoly_lcd_power,
>  };
>  
>  static struct pxafb_mach_info samsung_info = {
> -	.modes           = samsung_modes,
> -	.num_modes       = 1,
> -	.fixed_modes     = 1,
> -	.lcd_conn	 = LCD_COLOR_TFT_16BPP | LCD_PCLK_EDGE_FALL 
> |\
> -			   LCD_ALTERNATE_MAPPING,
> +	.modes		= samsung_modes,
> +	.num_modes	= 1,
> +	.fixed_modes	= 1,
> +	.lcd_conn	= LCD_COLOR_TFT_16BPP | LCD_PCLK_EDGE_FALL |
> +		LCD_ALTERNATE_MAPPING,
>  	.pxafb_lcd_power = samsung_lcd_power,
>  };
>  
> @@ -374,22 +373,22 @@ static void magician_backlight_exit(struct 
> device *dev)
>  }
>  
>  static struct platform_pwm_backlight_data backlight_data = {
> -	.pwm_id         = 0,
> -	.max_brightness = 272,
> -	.dft_brightness = 100,
> -	.pwm_period_ns  = 30923,
> -	.enable_gpio    = -1,
> -	.init           = magician_backlight_init,
> -	.notify         = magician_backlight_notify,
> -	.exit           = magician_backlight_exit,
> +	.pwm_id		= 0,
> +	.max_brightness	= 272,
> +	.dft_brightness	= 100,
> +	.pwm_period_ns	= 30923,
> +	.enable_gpio	= -1,
> +	.init		= magician_backlight_init,
> +	.notify		= magician_backlight_notify,
> +	.exit		= magician_backlight_exit,
>  };
>  
>  static struct platform_device backlight = {
> -	.name = "pwm-backlight",
> -	.id   = -1,
> -	.dev  = {
> -		.parent        = &pxa27x_device_pwm0.dev,
> -		.platform_data = &backlight_data,
> +	.name	= "pwm-backlight",
> +	.id	= -1,
> +	.dev	= {
> +		.parent		= &pxa27x_device_pwm0.dev,
> +		.platform_data	= &backlight_data,
>  	},
>  };

So we are aligning, then. Please pick a style and stick with it.
I'll skip the rest for now.

regards
Philipp


From philipp.zabel at gmail.com  Wed Aug 19 00:57:01 2015
From: philipp.zabel at gmail.com (Philipp Zabel)
Date: Wed, 19 Aug 2015 09:57:01 +0200
Subject: [PATCH v2 03/21] ARM: pxa: magician: Fix comments, debug
 functions and print strings
In-Reply-To: <55D258CD.40101@tul.cz>
References: <cover.1439843482.git.petr.cvek@tul.cz> <55D258CD.40101@tul.cz>
Message-ID: <1439971021.11928.26.camel@gmail.com>

Am Montag, den 17.08.2015, 23:57 +0200 schrieb Petr Cvek:
> Fix comments, debug functions and print strings. Rename backlight
> structures to be more specific.
> 
> Signed-off-by: Petr Cvek <petr.cvek at tul.cz>
> ---
>  arch/arm/mach-pxa/magician.c | 121 +++++++++++++++++++++++++++++++--
> ----------
>  1 file changed, 89 insertions(+), 32 deletions(-)
> 
> diff --git a/arch/arm/mach-pxa/magician.c b/arch/arm/mach
> -pxa/magician.c
> index 9e8698a..57da133 100644
> --- a/arch/arm/mach-pxa/magician.c
> +++ b/arch/arm/mach-pxa/magician.c
> @@ -11,6 +11,46 @@
>   * it under the terms of the GNU General Public License version 2 as
>   * published by the Free Software Foundation.
>   *
> + *
> + * NOTICE MDA Compact (T-mobile XDA) facts:
> + *   On "LCD type = 1, system_rev = 2" (0x3a in CPLD)
> + * Samsung LTP280QV - valid LCD init sequence sequence:
> + *   powerup: Vdigital->Vanalog->gate Voff->gate Von->data enable
> + *   powerdown: data disable->gate Von->gate Voff->Vanalog->Vdigital
> + * Measured on PCB:
> + *   GPIO106
> + *     Affects VOFF, VON and other voltages
> + *     Probably main reset pin for DC-DC converter
> + *   GPIO75
> + *     Must be AF0+OUT (WM leaves it to AF2+OUT), not LCD signal
> + *     GPIO106 works only when GPIO75 is high (DC-DC power enable?)
> + *     After LCD powerup, value is irrelevant
> + *   GPIO104
> + *     LCD VOFF (gate off voltage)
> + *   GPIO105
> + *     LCD VON (gate on voltage)
> + * FFUART (/dev/ttyS0) WM: 38400,8,n,1,crtscts (GSM data?)
> + * BTUART (/dev/ttyS1) WM: 115200,8,n,1,crtscts (GSM AT commands)
> + *   Use a HTC line discipline: 0x02 channel(==0x16) data 0x02
> + * EGPIO(CPLD) should be always present (controls "all" supply 
> power)
> + *   For rootfs on MMC/SD: EGPIO module controls card power (in 
> kernel)
> + * cpu-freq often freeze platform (errata?, use userspace gov)
> + * Do not use YUV420, (erratum E24) causes LCD hang (forever)
> + * Many GSM related pins are unknown
> + * gpio-rc-recv probably require lowpass filter (sw is OK)
> + * TODO EGPIO_MAGICIAN_IR_RECEIVE_SHUTDOWN
> + * FIXME AC charging blocks IrDA
> + * Unimplemented blocking of camera+power+reset, reset and door open 
> reset
> + *   Registers: htc-pasic3.h (but blocks charging too)
> + * Other PXA machines have wait_for_sync for ADS7846 (during LCD 
> refresh)
> + * pda-power has not optimal charging (accu can be bloated)
> + * TODO Current switching works? Is gpio-regulator/bq24022 required?

> + * pdata supports alternative drivers (mutually exclusive modules)
> + *   i2c-pxa vs i2c-gpio (SCCB)
> + *   pwm_bl vs gpio_backlight
> + *   pxa27x_udc vs phy-gpio-vbus-usb
> + *   physmap-flash vs pxa2xx-flash

This infodump is useful to have, but I don't think it belongs in the
code.
Also, please don't include the mutually exclusive alternatives in
mainline. Let's just pick one option.

>  #include <linux/kernel.h>
> @@ -57,31 +97,31 @@ static unsigned long magician_pin_config[] 
> __initdata = {
>  	GPIO80_nCS_4,
>  	GPIO33_nCS_5,
>  
> -	/* I2C */
> +	/* I2C UDA1380 + OV9640 */
>  	GPIO117_I2C_SCL,
>  	GPIO118_I2C_SDA,
>  
> -	/* PWM 0 */
> +	/* PWM 0 - LCD backlight */
>  	GPIO16_PWM0_OUT,
>  
> -	/* I2S */
> +	/* I2S UDA1380 capture */
>  	GPIO28_I2S_BITCLK_OUT,
>  	GPIO29_I2S_SDATA_IN,
>  	GPIO31_I2S_SYNC,
>  	GPIO113_I2S_SYSCLK,
>  
> -	/* SSP 1 */
> +	/* SSP 1 UDA1380 playback */
>  	GPIO23_SSP1_SCLK,
>  	GPIO24_SSP1_SFRM,
>  	GPIO25_SSP1_TXD,
>  
> -	/* SSP 2 */
> +	/* SSP 2 TSC2046 touchscreen */
>  	GPIO19_SSP2_SCLK,
>  	GPIO14_SSP2_SFRM,
>  	GPIO89_SSP2_TXD,
>  	GPIO88_SSP2_RXD,
>  
> -	/* MMC */
> +	/* MMC/SD/SDHC slot */
>  	GPIO32_MMC_CLK,
>  	GPIO92_MMC_DAT_0,
>  	GPIO109_MMC_DAT_1,

These comments are nice to have.

> @@ -92,7 +132,7 @@ static unsigned long magician_pin_config[] 
> __initdata = {
>  	/* LCD */
>  	GPIOxx_LCD_TFT_16BPP,
>  
> -	/* QCI */
> +	/* QCI camera interface */
>  	GPIO12_CIF_DD_7,
>  	GPIO17_CIF_DD_6,
>  	GPIO50_CIF_DD_3,
> @@ -120,11 +160,12 @@ static unsigned long magician_pin_config[] 
> __initdata = {
>  };
>  
>  /*
> - * IRDA
> + * IrDA
>   */
>  
>  static struct pxaficp_platform_data magician_ficp_info = {
>  	.gpio_pwdown		= GPIO83_MAGICIAN_nIR_EN,
> +	/* TODO test with FIR dongle */
>  	.transceiver_cap	= IR_SIRMODE | IR_OFF,
>  };
> @@ -174,8 +215,8 @@ static struct platform_device gpio_keys = {
>   
>  /*
>   * EGPIO (Xilinx CPLD)
> - *
> - * 7 32-bit aligned 8-bit registers: 3x output, 1x irq, 3x input
> + * 32-bit aligned
> + * 7x 8-bit registers: 3x output, 1x irq, 3x input
>   */

Why reorder?

>  static struct resource egpio_resources[] = {
> @@ -197,7 +238,11 @@ static struct htc_egpio_chip egpio_chips[] = {
>  		.gpio_base = MAGICIAN_EGPIO(0, 0),
>  		.num_gpios = 24,
>  		.direction = HTC_EGPIO_OUTPUT,
> -		.initial_values = 0x40, /* EGPIO_MAGICIAN_GSM_RESET 
> */
> +
> +		/*
> +		 * Depends on modules configuration
> +		 */
> +		.initial_values = 0x40,
>  	},
>  	[1] = {
>  		.reg_start = 4,
> @@ -228,7 +273,7 @@ static struct platform_device egpio = {
>  };
>  
>  /*
> - * LCD - Toppoly TD028STEB1 or Samsung LTP280QV
> + * PXAFB LCD - Toppoly TD028STEB1 or Samsung LTP280QV
>   */
>  
>  static struct pxafb_mode_info toppoly_modes[] = {
> @@ -265,10 +310,9 @@ static struct pxafb_mode_info samsung_modes[] = 
> {
>  
>  static void toppoly_lcd_power(int on, struct fb_var_screeninfo *si)
>  {
> -	pr_debug("Toppoly LCD power\n");
> +	pr_debug("Toppoly LCD power: %s\n", on ? "on" : "off");Ok.

Ok.

> 	if (on) {
> -		pr_debug("on\n");
>  		gpio_set_value(EGPIO_MAGICIAN_TOPPOLY_POWER, 1);
>  		gpio_set_value(GPIO106_MAGICIAN_LCD_POWER_3, 1);
>  		udelay(2000);
> @@ -280,8 +324,7 @@ static void toppoly_lcd_power(int on, struct 
> fb_var_screeninfo *si)
>  		udelay(2000);
>  		gpio_set_value(GPIO105_MAGICIAN_LCD_POWER_2, 1);
>  	} else {
> -		pr_debug("off\n");
> -		msleep(15);
> +		mdelay(15);

This is an unrelated change and should be in a separate patch.
Also maybe better use usleep_range?

>  		gpio_set_value(GPIO105_MAGICIAN_LCD_POWER_2, 0);
>  		udelay(500);
>  		gpio_set_value(GPIO104_MAGICIAN_LCD_POWER_1, 0);
> @@ -293,10 +336,9 @@ static void toppoly_lcd_power(int on, struct 
> fb_var_screeninfo *si)
>  
>  static void samsung_lcd_power(int on, struct fb_var_screeninfo *si)
>  {
> -	pr_debug("Samsung LCD power\n");
> +	pr_debug("Samsung LCD power: %s\n", on ? "on" : "off");
>  
>  	if (on) {
> -		pr_debug("on\n");
>  		if (system_rev < 3)
>  			gpio_set_value(GPIO75_MAGICIAN_SAMSUNG_POWER
> , 1);
>  		else
> @@ -309,7 +351,6 @@ static void samsung_lcd_power(int on, struct 
> fb_var_screeninfo *si)
>  		gpio_set_value(GPIO105_MAGICIAN_LCD_POWER_2, 1);
>  		mdelay(10);
>  	} else {
> -		pr_debug("off\n");
>  		mdelay(10);
>  		gpio_set_value(GPIO105_MAGICIAN_LCD_POWER_2, 0);
>  		mdelay(30);
> @@ -346,8 +387,8 @@ static struct pxafb_mach_info samsung_info = {
>   */
>  
[...]
> +/*
> + * pda_power Li-ion charger
> + */
> +
>  static struct pda_power_pdata power_supply_info = {
>  	.init		= power_supply_init,
>  	.is_ac_online	= magician_is_ac_online,
> @@ -575,7 +631,7 @@ static struct platform_device power_supply = {
>  };
>  
>  /*
> - * Battery charger
> + * Charging current switch
>   */

The bq24022 is a battery charger. The switch is one of its input pins
to allow to limit USB charging current to 100 mA in case the host
doesn't support more.
 
regards
Philipp


From philipp.zabel at gmail.com  Wed Aug 19 01:02:30 2015
From: philipp.zabel at gmail.com (Philipp Zabel)
Date: Wed, 19 Aug 2015 10:02:30 +0200
Subject: [PATCH v2 06/21] ARM: pxa: magician: Add normal and power I2C
 definition
In-Reply-To: <55D2593A.5060400@tul.cz>
References: <cover.1439843482.git.petr.cvek@tul.cz> <55D2593A.5060400@tul.cz>
Message-ID: <1439971350.11928.28.camel@gmail.com>

Am Montag, den 17.08.2015, 23:59 +0200 schrieb Petr Cvek:
> Add normal and power I2C definition to HTC Magician.

What do you need i2c-gpio for? As I said before, I don't think this
should be in mainline, rather the pxa-i2c driver should be used.

>  
>  /*
> + * PXA I2C power controller
> + */
> +
> +static struct i2c_pxa_platform_data magician_i2c_power_info = {
> +	.fast_mode = 0,
> +	.use_pio = 0,
> +};
[...]
> @@ -975,7 +1009,7 @@ static void __init magician_init(void)
>  	platform_add_devices(ARRAY_AND_SIZE(devices));
>  
>  	pxa_set_ficp_info(&magician_ficp_info);
> -	pxa27x_set_i2c_power_info(NULL);
> +	pxa27x_set_i2c_power_info(&magician_i2c_power_info);

Does this actually have an effect?

regards
Philipp


From philipp.zabel at gmail.com  Wed Aug 19 01:09:31 2015
From: philipp.zabel at gmail.com (Philipp Zabel)
Date: Wed, 19 Aug 2015 10:09:31 +0200
Subject: [PATCH v2 19/21] leds: leds-pasic3: Add support for PASIC3 LED
 controller
In-Reply-To: <55D3A832.90705@tul.cz>
References: <cover.1439843482.git.petr.cvek@tul.cz> <55D25ADC.10703@tul.cz>
 <55D30875.3090103@samsung.com> <55D3A832.90705@tul.cz>
Message-ID: <1439971771.11928.31.camel@gmail.com>

Am Dienstag, den 18.08.2015, 23:48 +0200 schrieb Petr Cvek:
> Dne 18.8.2015 v 12:27 Jacek Anaszewski napsal(a):
> > Hi Petr,
> > 
> > On 08/18/2015 12:06 AM, Petr Cvek wrote:
> > > +/*
> > > + * AIC3 (or PASIC3) LED driver for HTC Magician/Alpine/.. (not 
> > > Compaq ASIC3)
> > 
> > s/AIC3/ASIC3/
> > 
> > I am a bit confused. What's the relation between ASIC3 and PASIC3?
> 
> Actually both drivers should be renamed to AIC3 (or AIC only, as 
> there is version 2). "HTC_AIC3" is written on the chip and "pasic3" 
> is confusing with compaq asic3 driver, which claims in Kconfig help 
> to be compatible with HTC machines. Compaq ASIC3 has much more 
> functionality and from brief look it seems it has 16 bit registers 
> (HTC_AIC3 has only LEDs, RESET and DS1WM and has 8 bit registers).

I think I've got the PASIC3 name from debug strings present in the HTC
bootloader or WinCE binary. This chip (and its predecessor PASIC2 in
HTC Blueangel) are different from the ASIC3 found in hx4700 iPAQs.

regards
Philipp


From antoine.tenart at free-electrons.com  Wed Aug 19 01:17:57 2015
From: antoine.tenart at free-electrons.com (Antoine Tenart)
Date: Wed, 19 Aug 2015 10:17:57 +0200
Subject: [PATCH v2 0/6] ARM: berlin: add cpufreq support
In-Reply-To: <20150818145925.GF31148@linux>
References: <1439898368-11543-1-git-send-email-antoine.tenart@free-electrons.com>
 <CAOh2x=ke9NWa-GjL=c+RgEWWfsNeKvE2O9CRHmW2dG5mj8ATCg@mail.gmail.com>
 <20150818143911.GB12017@kwain> <20150818145925.GF31148@linux>
Message-ID: <20150819081757.GA1089@kwain>

On Tue, Aug 18, 2015 at 08:29:25PM +0530, Viresh Kumar wrote:
> On 18-08-15, 16:39, Antoine Tenart wrote:
> > However, it seems the OPP-v2 table takes precedence over the old one.
> > When a default OPP-v2 table is supplied in the device tree, if the
> > bootloader supplies an OPP table the old way it won't be taken into
> > account.
> > 
> > So if I understood correctly, this won't work here for the BG2Q.
> 
> Didn't understood it completely. Are you saying that your dtb will
> have two operating-points tables ?

Yes. If the device tree has an OPP-v2 table and the bootloader modify it
to add an old OPP table at boot, the one added by the bootloader won't
be taken into account by the kernel.

> The deal is that for any device, parsing of opp-v2 will be attempted
> first. If its not available, then opp-v1 will be tried. But this is
> per-device. So, one device can have opp-v2 tables and other one can do
> v1 type.

Sure. OPP-v2 tables can be used for devices having an up-to-date
bootloader or if the bootloader do not modify the device tree at boot
time to add an (old) OPP table.

Antoine

-- 
Antoine T?nart, Free Electrons
Embedded Linux, Kernel and Android engineering
http://free-electrons.com


From m.szyprowski at samsung.com  Wed Aug 19 01:19:37 2015
From: m.szyprowski at samsung.com (Marek Szyprowski)
Date: Wed, 19 Aug 2015 10:19:37 +0200
Subject: [PATCH v2] ARM: multi_v7_defconfig: Enable DWC2 USB driver and USB
 ethernet gadget
In-Reply-To: <55D30313.7080107@osg.samsung.com>
References: <55D30313.7080107@osg.samsung.com>
Message-ID: <1439972377-22683-1-git-send-email-m.szyprowski@samsung.com>

DWC2 (s3c-hsotg) hardware module is available on many Exynos based boards,
so enable DWC2 driver as well as the most common USB Ethernet gadget.

Signed-off-by: Marek Szyprowski <m.szyprowski at samsung.com>
Reviewed-by: Javier Martinez Canillas <javier at osg.samsung.com>
---
Changes since v1: build DWC2 and USB gadget as modules
---
 arch/arm/configs/multi_v7_defconfig | 2 ++
 1 file changed, 2 insertions(+)

diff --git a/arch/arm/configs/multi_v7_defconfig b/arch/arm/configs/multi_v7_defconfig
index b2facab..d15f719 100644
--- a/arch/arm/configs/multi_v7_defconfig
+++ b/arch/arm/configs/multi_v7_defconfig
@@ -506,6 +506,7 @@ CONFIG_USB_R8A66597_HCD=m
 CONFIG_USB_RENESAS_USBHS=m
 CONFIG_USB_STORAGE=y
 CONFIG_USB_DWC3=y
+CONFIG_USB_DWC2=m
 CONFIG_USB_CHIPIDEA=y
 CONFIG_USB_CHIPIDEA_HOST=y
 CONFIG_AB8500_USB=y
@@ -517,6 +518,7 @@ CONFIG_USB_MXS_PHY=y
 CONFIG_USB_RCAR_PHY=m
 CONFIG_USB_GADGET=y
 CONFIG_USB_RENESAS_USBHS_UDC=m
+CONFIG_USB_ETH=m
 CONFIG_MMC=y
 CONFIG_MMC_BLOCK_MINORS=16
 CONFIG_MMC_ARMMMCI=y
-- 
1.9.2



From p.zabel at pengutronix.de  Wed Aug 19 01:36:59 2015
From: p.zabel at pengutronix.de (Philipp Zabel)
Date: Wed, 19 Aug 2015 10:36:59 +0200
Subject: [GIT PULL] Reset controller changes for v4.3
Message-ID: <1439973419.3160.6.camel@pengutronix.de>

Hi arm-soc maintainers,

This tag includes reset controller support for LPC18xx, SocFPGA Arria10,
AR71XX/AR9XXX and Zynq and moves all dt-bindings include files into the
same place.

regards
Philipp

The following changes since commit bc0195aad0daa2ad5b0d76cce22b167bc3435590:

  Linux 4.2-rc2 (2015-07-12 15:10:30 -0700)

are available in the git repository at:

  git://git.pengutronix.de/git/pza/linux.git tags/reset-for-4.3

for you to fetch changes up to 5d44595c2627f7edcd8c24a76b13bd115f9fc2da:

  Merge branch 'reset/ath79' into reset/next (2015-08-16 17:11:20 +0200)

----------------------------------------------------------------
Reset controller changes for v4.3

- moved the DT reset binding includes from
  include/dt-bindings/reset-controller to include/dt-bindings/reset
- new driver for LPC18xx Reset Generation Unit (RGU)
- of_device_id array in the STi driver changed to const.
- extend SoCFPGA reset driver to support Arria10
- new ath79 reset controller driver for AR71XX/AR9XXX
- new driver for Xilinx Zynq reset controller

----------------------------------------------------------------
Alban Bedel (3):
      devicetree: Add bindings for the ATH79 reset controller
      reset: Add a driver for the reset controller on the AR71XX/AR9XXX
      MIPS: ath79: Add the reset controller to the AR9132 dtsi

Dinh Nguyen (1):
      reset: socfpga: Update reset-socfpga to read the altr,modrst-offset property

Fabian Frederick (1):
      reset: sti: constify of_device_id array

Joachim Eastwood (2):
      reset: add driver for lpc18xx rgu
      doc: dt: add documentation for lpc1850-rgu reset driver

Moritz Fischer (2):
      docs: dts: Added documentation for Xilinx Zynq Reset Controller bindings.
      reset: reset-zynq: Adding support for Xilinx Zynq reset controller.

Philipp Zabel (3):
      MAINTAINERS: add include/dt-bindings/reset path to reset controller entry
      ARM: STi: DT: Move reset controller constants into common location
      Merge branch 'reset/ath79' into reset/next

 .../devicetree/bindings/reset/ath79-reset.txt      |  20 ++
 .../devicetree/bindings/reset/nxp,lpc1850-rgu.txt  |  84 +++++++
 .../bindings/reset/st,sti-picophyreset.txt         |   2 +-
 .../devicetree/bindings/reset/st,sti-powerdown.txt |   4 +-
 .../devicetree/bindings/reset/st,sti-softreset.txt |   4 +-
 .../devicetree/bindings/reset/zynq-reset.txt       |  68 ++++++
 MAINTAINERS                                        |   1 +
 arch/arm/boot/dts/stih407-family.dtsi              |   2 +-
 arch/arm/boot/dts/stih415.dtsi                     |   2 +-
 arch/arm/boot/dts/stih416.dtsi                     |   2 +-
 arch/mips/Kconfig                                  |   1 +
 arch/mips/boot/dts/qca/ar9132.dtsi                 |   8 +
 drivers/reset/Makefile                             |   3 +
 drivers/reset/reset-ath79.c                        | 128 ++++++++++
 drivers/reset/reset-lpc18xx.c                      | 258 +++++++++++++++++++++
 drivers/reset/reset-socfpga.c                      |  19 +-
 drivers/reset/reset-zynq.c                         | 155 +++++++++++++
 drivers/reset/sti/reset-stih407.c                  |   4 +-
 drivers/reset/sti/reset-stih415.c                  |   4 +-
 drivers/reset/sti/reset-stih416.c                  |   4 +-
 .../{reset-controller => reset}/stih407-resets.h   |   0
 .../{reset-controller => reset}/stih415-resets.h   |   0
 .../{reset-controller => reset}/stih416-resets.h   |   0
 23 files changed, 753 insertions(+), 20 deletions(-)
 create mode 100644 Documentation/devicetree/bindings/reset/ath79-reset.txt
 create mode 100644 Documentation/devicetree/bindings/reset/nxp,lpc1850-rgu.txt
 create mode 100644 Documentation/devicetree/bindings/reset/zynq-reset.txt
 create mode 100644 drivers/reset/reset-ath79.c
 create mode 100644 drivers/reset/reset-lpc18xx.c
 create mode 100644 drivers/reset/reset-zynq.c
 rename include/dt-bindings/{reset-controller => reset}/stih407-resets.h (100%)
 rename include/dt-bindings/{reset-controller => reset}/stih415-resets.h (100%)
 rename include/dt-bindings/{reset-controller => reset}/stih416-resets.h (100%)



From hverkuil at xs4all.nl  Wed Aug 19 01:38:26 2015
From: hverkuil at xs4all.nl (Hans Verkuil)
Date: Wed, 19 Aug 2015 10:38:26 +0200
Subject: [PATCH RFC v5 8/8] [media] media: rename the function that create
 pad links
In-Reply-To: <4b0c0aa7604f5202401997f946297c0b35c1b692.1439927113.git.mchehab@osg.samsung.com>
References: <cover.1439927113.git.mchehab@osg.samsung.com>
 <4b0c0aa7604f5202401997f946297c0b35c1b692.1439927113.git.mchehab@osg.samsung.com>
Message-ID: <55D44082.6000600@xs4all.nl>

On 08/18/2015 10:04 PM, Mauro Carvalho Chehab wrote:
> Now that a link can be either between two different graph
> objects, we'll need to add more functions to create links.
> So, rename the existing one that create links only between
> two pads as media_create_pad_link().
> 
> No functional changes.
> 
> This patch was created via this shell script:
> 	for i in $(find drivers/media -name '*.[ch]' -type f) $(find drivers/staging/media -name '*.[ch]' -type f) $(find include/ -name '*.h' -type f) ; do sed s,media_entity_create_link,media_create_pad_link,g <$i >a && mv a $i; done
> 
> Signed-off-by: Mauro Carvalho Chehab <mchehab at osg.samsung.com>
>

Acked-by: Hans Verkuil <hans.verkuil at cisco.com>

Thanks!

	Hans



From jens.wiklander at linaro.org  Wed Aug 19 01:40:25 2015
From: jens.wiklander at linaro.org (Jens Wiklander)
Date: Wed, 19 Aug 2015 10:40:25 +0200
Subject: [PATCH v5 1/5] arm/arm64: add smccc ARCH32
In-Reply-To: <1439973629-19505-1-git-send-email-jens.wiklander@linaro.org>
References: <1439973629-19505-1-git-send-email-jens.wiklander@linaro.org>
Message-ID: <1439973629-19505-2-git-send-email-jens.wiklander@linaro.org>

Adds helpers to do SMC based on ARM SMC Calling Convention.
CONFIG_HAVE_SMCCC is enabled for architectures that may support
the SMC instruction. It's the responsibility of the caller to
know if the SMC instruction is supported by the platform.

Signed-off-by: Jens Wiklander <jens.wiklander at linaro.org>
---
 arch/arm/Kconfig               |  4 +++
 arch/arm/kernel/Makefile       |  2 ++
 arch/arm/kernel/smccc-call.S   | 26 ++++++++++++++
 arch/arm/kernel/smccc.c        | 17 +++++++++
 arch/arm64/Kconfig             |  4 +++
 arch/arm64/kernel/Makefile     |  1 +
 arch/arm64/kernel/smccc-call.S | 34 ++++++++++++++++++
 arch/arm64/kernel/smccc.c      | 17 +++++++++
 include/linux/arm-smccc.h      | 79 ++++++++++++++++++++++++++++++++++++++++++
 9 files changed, 184 insertions(+)
 create mode 100644 arch/arm/kernel/smccc-call.S
 create mode 100644 arch/arm/kernel/smccc.c
 create mode 100644 arch/arm64/kernel/smccc-call.S
 create mode 100644 arch/arm64/kernel/smccc.c
 create mode 100644 include/linux/arm-smccc.h

diff --git a/arch/arm/Kconfig b/arch/arm/Kconfig
index 45df48b..75e4da3 100644
--- a/arch/arm/Kconfig
+++ b/arch/arm/Kconfig
@@ -221,6 +221,9 @@ config NEED_RET_TO_USER
 config ARCH_MTD_XIP
 	bool
 
+config HAVE_SMCCC
+	bool
+
 config VECTORS_BASE
 	hex
 	default 0xffff0000 if MMU || CPU_HIGH_VECTOR
@@ -324,6 +327,7 @@ config ARCH_MULTIPLATFORM
 	select CLKSRC_OF
 	select COMMON_CLK
 	select GENERIC_CLOCKEVENTS
+	select HAVE_SMCCC if CPU_V7
 	select MIGHT_HAVE_PCI
 	select MULTI_IRQ_HANDLER
 	select SPARSE_IRQ
diff --git a/arch/arm/kernel/Makefile b/arch/arm/kernel/Makefile
index 752725d..8cdd25b 100644
--- a/arch/arm/kernel/Makefile
+++ b/arch/arm/kernel/Makefile
@@ -90,4 +90,6 @@ obj-y				+= psci.o psci-call.o
 obj-$(CONFIG_SMP)		+= psci_smp.o
 endif
 
+obj-$(CONFIG_HAVE_SMCCC)	+= smccc-call.o smccc.o
+
 extra-y := $(head-y) vmlinux.lds
diff --git a/arch/arm/kernel/smccc-call.S b/arch/arm/kernel/smccc-call.S
new file mode 100644
index 0000000..05bc554
--- /dev/null
+++ b/arch/arm/kernel/smccc-call.S
@@ -0,0 +1,26 @@
+/*
+ * Copyright (c) 2015, Linaro Limited
+ *
+ * This software is licensed under the terms of the GNU General Public
+ * License version 2, as published by the Free Software Foundation, and
+ * may be copied, distributed, and modified under those terms.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ * GNU General Public License for more details.
+ *
+ */
+#include <linux/linkage.h>
+
+#include <asm/opcodes-sec.h>
+
+/* void smccc_call32(struct smccc_param32 *param) */
+ENTRY(smccc_call32)
+	push	{r4-r8, lr}
+	mov	r8, r0
+	ldm	r8, {r0-r7}
+	__SMC(0)
+	stm	r8, {r0-r7}
+	pop	{r4-r8, pc}
+ENDPROC(smccc_call32)
diff --git a/arch/arm/kernel/smccc.c b/arch/arm/kernel/smccc.c
new file mode 100644
index 0000000..ba4039e
--- /dev/null
+++ b/arch/arm/kernel/smccc.c
@@ -0,0 +1,17 @@
+/*
+ * Copyright (c) 2015, Linaro Limited
+ *
+ * This software is licensed under the terms of the GNU General Public
+ * License version 2, as published by the Free Software Foundation, and
+ * may be copied, distributed, and modified under those terms.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ * GNU General Public License for more details.
+ *
+ */
+#include <linux/export.h>
+#include <linux/arm-smccc.h>
+
+EXPORT_SYMBOL_GPL(smccc_call32);
diff --git a/arch/arm64/Kconfig b/arch/arm64/Kconfig
index 7796af4..b3ea778 100644
--- a/arch/arm64/Kconfig
+++ b/arch/arm64/Kconfig
@@ -83,6 +83,7 @@ config ARM64
 	select SPARSE_IRQ
 	select SYSCTL_EXCEPTION_TRACE
 	select HAVE_CONTEXT_TRACKING
+	select HAVE_SMCCC
 	help
 	  ARM 64-bit (AArch64) Linux support.
 
@@ -146,6 +147,9 @@ config KERNEL_MODE_NEON
 config FIX_EARLYCON_MEM
 	def_bool y
 
+config HAVE_SMCCC
+	bool
+
 config PGTABLE_LEVELS
 	int
 	default 2 if ARM64_64K_PAGES && ARM64_VA_BITS_42
diff --git a/arch/arm64/kernel/Makefile b/arch/arm64/kernel/Makefile
index 426d076..f7804f7 100644
--- a/arch/arm64/kernel/Makefile
+++ b/arch/arm64/kernel/Makefile
@@ -36,6 +36,7 @@ arm64-obj-$(CONFIG_EFI)			+= efi.o efi-stub.o efi-entry.o
 arm64-obj-$(CONFIG_PCI)			+= pci.o
 arm64-obj-$(CONFIG_ARMV8_DEPRECATED)	+= armv8_deprecated.o
 arm64-obj-$(CONFIG_ACPI)		+= acpi.o
+arm64-obj-$(CONFIG_HAVE_SMCCC)		+= smccc-call.o smccc.o
 
 obj-y					+= $(arm64-obj-y) vdso/
 obj-m					+= $(arm64-obj-m)
diff --git a/arch/arm64/kernel/smccc-call.S b/arch/arm64/kernel/smccc-call.S
new file mode 100644
index 0000000..3ce7fe8
--- /dev/null
+++ b/arch/arm64/kernel/smccc-call.S
@@ -0,0 +1,34 @@
+/*
+ * Copyright (c) 2015, Linaro Limited
+ *
+ * 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/linkage.h>
+
+#define SMC_PARAM_W0_OFFS	0
+#define SMC_PARAM_W2_OFFS	8
+#define SMC_PARAM_W4_OFFS	16
+#define SMC_PARAM_W6_OFFS	24
+
+/* void smccc_call32(struct smccc_param32 *param) */
+ENTRY(smccc_call32)
+	stp	x28, x30, [sp, #-16]!
+	mov	x28, x0
+	ldp	w0, w1, [x28, #SMC_PARAM_W0_OFFS]
+	ldp	w2, w3, [x28, #SMC_PARAM_W2_OFFS]
+	ldp	w4, w5, [x28, #SMC_PARAM_W4_OFFS]
+	ldp	w6, w7, [x28, #SMC_PARAM_W6_OFFS]
+	smc	#0
+	stp	w0, w1, [x28, #SMC_PARAM_W0_OFFS]
+	stp	w2, w3, [x28, #SMC_PARAM_W2_OFFS]
+	ldp	x28, x30, [sp], #16
+	ret
+ENDPROC(smccc_call32)
diff --git a/arch/arm64/kernel/smccc.c b/arch/arm64/kernel/smccc.c
new file mode 100644
index 0000000..ba4039e
--- /dev/null
+++ b/arch/arm64/kernel/smccc.c
@@ -0,0 +1,17 @@
+/*
+ * Copyright (c) 2015, Linaro Limited
+ *
+ * This software is licensed under the terms of the GNU General Public
+ * License version 2, as published by the Free Software Foundation, and
+ * may be copied, distributed, and modified under those terms.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ * GNU General Public License for more details.
+ *
+ */
+#include <linux/export.h>
+#include <linux/arm-smccc.h>
+
+EXPORT_SYMBOL_GPL(smccc_call32);
diff --git a/include/linux/arm-smccc.h b/include/linux/arm-smccc.h
new file mode 100644
index 0000000..9b8d775
--- /dev/null
+++ b/include/linux/arm-smccc.h
@@ -0,0 +1,79 @@
+/*
+ * Copyright (c) 2015, Linaro Limited
+ *
+ * This software is licensed under the terms of the GNU General Public
+ * License version 2, as published by the Free Software Foundation, and
+ * may be copied, distributed, and modified under those terms.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ * GNU General Public License for more details.
+ *
+ */
+#ifndef __LINUX_ARM_SMCCC_H
+#define __LINUX_ARM_SMCCC_H
+
+#include <linux/types.h>
+
+/*
+ * This file provideds defines common defines for ARM SMC Calling
+ * Convention as specified in
+ * http://infocenter.arm.com/help/topic/com.arm.doc.den0028a/index.html
+ */
+
+#define SMCCC_SMC_32			(0 << 30)
+#define SMCCC_SMC_64			(1 << 30)
+#define SMCCC_FAST_CALL			(1 << 31)
+#define SMCCC_STD_CALL			(0 << 31)
+
+#define SMCCC_OWNER_MASK		0x3F
+#define SMCCC_OWNER_SHIFT		24
+
+#define SMCCC_FUNC_MASK			0xFFFF
+
+#define SMCCC_IS_FAST_CALL(smc_val)	((smc_val) & SMCCC_FAST_CALL)
+#define SMCCC_IS_64(smc_val)		((smc_val) & SMCCC_SMC_64)
+#define SMCCC_FUNC_NUM(smc_val)		((smc_val) & SMCCC_FUNC_MASK)
+#define SMCCC_OWNER_NUM(smc_val) \
+	(((smc_val) >> SMCCC_OWNER_SHIFT) & SMCCC_OWNER_MASK)
+
+#define SMCCC_CALL_VAL(type, calling_convention, owner, func_num) \
+			((type) | (calling_convention) | \
+			(((owner) & SMCCC_OWNER_MASK) << SMCCC_OWNER_SHIFT) | \
+			((func_num) & SMCCC_FUNC_MASK))
+
+#define SMCCC_OWNER_ARCH		0
+#define SMCCC_OWNER_CPU			1
+#define SMCCC_OWNER_SIP			2
+#define SMCCC_OWNER_OEM			3
+#define SMCCC_OWNER_STANDARD		4
+#define SMCCC_OWNER_TRUSTED_APP		48
+#define SMCCC_OWNER_TRUSTED_APP_END	49
+#define SMCCC_OWNER_TRUSTED_OS		50
+#define SMCCC_OWNER_TRUSTED_OS_END	63
+
+struct smccc_param32 {
+	u32 a0;
+	u32 a1;
+	u32 a2;
+	u32 a3;
+	u32 a4;
+	u32 a5;
+	u32 a6;
+	u32 a7;
+};
+
+/**
+ * smccc_call32() - make ARCH32 SMC calls
+ * @param: values to pass in registers 0 to 7
+ *
+ * This function is used to make SMC calls following SMC Calling Convention
+ * for ARCH32 calls. The content of the supplied param are copied to
+ * registers 0 to 7 prior to the SMC instruction. Values a0..a3 are updated
+ * with the content from register 0 to 3 on return from the SMC
+ * instruction.
+ */
+void smccc_call32(struct smccc_param32 *param);
+
+#endif /*__LINUX_ARM_SMCCC_H*/
-- 
1.9.1



From jens.wiklander at linaro.org  Wed Aug 19 01:40:26 2015
From: jens.wiklander at linaro.org (Jens Wiklander)
Date: Wed, 19 Aug 2015 10:40:26 +0200
Subject: [PATCH v5 2/5] dt/bindings: add bindings for optee
In-Reply-To: <1439973629-19505-1-git-send-email-jens.wiklander@linaro.org>
References: <1439973629-19505-1-git-send-email-jens.wiklander@linaro.org>
Message-ID: <1439973629-19505-3-git-send-email-jens.wiklander@linaro.org>

Introduces optee prefix and adds bindings for ARM TrustZone based OP-TEE
implementation.

Signed-off-by: Jens Wiklander <jens.wiklander at linaro.org>
---
 Documentation/devicetree/bindings/optee/optee.txt     | 17 +++++++++++++++++
 Documentation/devicetree/bindings/vendor-prefixes.txt |  1 +
 2 files changed, 18 insertions(+)
 create mode 100644 Documentation/devicetree/bindings/optee/optee.txt

diff --git a/Documentation/devicetree/bindings/optee/optee.txt b/Documentation/devicetree/bindings/optee/optee.txt
new file mode 100644
index 0000000..4a6ff10
--- /dev/null
+++ b/Documentation/devicetree/bindings/optee/optee.txt
@@ -0,0 +1,17 @@
+OP-TEE Device Tree Bindings
+
+OP-TEE is a piece of software using hardware features to provide a Trusted
+Execution Environment. The security can be provided with ARM TrustZone, but
+also by virtualization or a separate chip. As there's no single OP-TEE
+vendor we're using "optee" as the first part of compatible property,
+indicating the OP-TEE protocol is used when communicating with the secure
+world.
+
+* OP-TEE based on ARM TrustZone required properties:
+
+- compatible="optee,optee-tz"
+
+Example:
+	optee {
+		compatible="optee,optee-tz";
+	};
diff --git a/Documentation/devicetree/bindings/vendor-prefixes.txt b/Documentation/devicetree/bindings/vendor-prefixes.txt
index 8033919..17c2a7e 100644
--- a/Documentation/devicetree/bindings/vendor-prefixes.txt
+++ b/Documentation/devicetree/bindings/vendor-prefixes.txt
@@ -141,6 +141,7 @@ nvidia	NVIDIA
 nxp	NXP Semiconductors
 onnn	ON Semiconductor Corp.
 opencores	OpenCores.org
+optee	OP-TEE, Open Portable Trusted Execution Environment
 ortustech	Ortus Technology Co., Ltd.
 ovti	OmniVision Technologies
 panasonic	Panasonic Corporation
-- 
1.9.1



From jens.wiklander at linaro.org  Wed Aug 19 01:40:29 2015
From: jens.wiklander at linaro.org (Jens Wiklander)
Date: Wed, 19 Aug 2015 10:40:29 +0200
Subject: [PATCH v5 5/5] Documentation: tee subsystem and op-tee driver
In-Reply-To: <1439973629-19505-1-git-send-email-jens.wiklander@linaro.org>
References: <1439973629-19505-1-git-send-email-jens.wiklander@linaro.org>
Message-ID: <1439973629-19505-6-git-send-email-jens.wiklander@linaro.org>

Signed-off-by: Jens Wiklander <jens.wiklander at linaro.org>
---
 Documentation/00-INDEX |   2 +
 Documentation/tee.txt  | 117 +++++++++++++++++++++++++++++++++++++++++++++++++
 MAINTAINERS            |   1 +
 3 files changed, 120 insertions(+)
 create mode 100644 Documentation/tee.txt

diff --git a/Documentation/00-INDEX b/Documentation/00-INDEX
index cd077ca..bd3f803 100644
--- a/Documentation/00-INDEX
+++ b/Documentation/00-INDEX
@@ -435,6 +435,8 @@ sysrq.txt
 	- info on the magic SysRq key.
 target/
 	- directory with info on generating TCM v4 fabric .ko modules
+tee.txt
+	- info on the TEE subsystem and drivers
 this_cpu_ops.txt
 	- List rationale behind and the way to use this_cpu operations.
 thermal/
diff --git a/Documentation/tee.txt b/Documentation/tee.txt
new file mode 100644
index 0000000..4ac91d2
--- /dev/null
+++ b/Documentation/tee.txt
@@ -0,0 +1,117 @@
+TEE subsystem
+This document describes the TEE subsystem in Linux
+
+A TEE (Trusted Execution Environment) is a trusted OS running in some
+secure environment, for example, TrustZone on ARM CPUs, or a separate
+secure co-processor etc. A TEE driver handles the details needed to
+communicate with the TEE.
+
+This subsystem deals with:
+
+- Registration of TEE drivers
+
+- Managing shared memory between Linux and the TEE
+
+- Providing a generic API to the TEE
+
+The TEE interface
+=================
+
+include/uapi/linux/tee.h defines the generic interface to a TEE.
+
+User space (the client) connects to the driver by opening /dev/tee[0-9]* or
+/dev/teepriv[0-9]*.
+
+- TEE_IOC_SHM_ALLOC allocates shared memory and returns a file descriptor which
+  user space can mmap. When user space doesn't need the file descriptor anymore
+  it should be closed. When shared memory isn't needed any longer it should be
+  unmapped with munmap() to allow the reuse of memory.
+
+- TEE_IOC_VERSION lets user space know which TEE this driver handles and
+  the its capabilities.
+
+- TEE_IOC_OPEN_SESSION opens a new session to a Trusted Application
+
+- TEE_IOC_INVOKE invokes a function in a Trusted Application
+
+- TEE_IOC_CANCEL may cancel an ongoing TEE_IOC_OPEN_SESSION or TEE_IOC_INVOKE
+
+- TEE_IOC_CLOSE_SESSION closes a session to a Trusted Application
+
+There are two classes of clients, normal clients and supplicants. The latter is
+a helper process for the TEE to access resources in Linux, for example file
+system access. A normal client opens /dev/tee[0-9]* and a supplicant opens
+/dev/teepriv[0-9].
+
+Much of the communication between clients and the TEE is opaque to the
+driver. The main job for the driver is to receive requests from the
+clients, forward them to the TEE and send back the results. In the case of
+supplicants the communication goes in the other direction, the TEE sends
+requests to the supplicant which then sends back the result.
+
+OP-TEE driver
+=============
+
+The OP-TEE driver handles OP-TEE [1] based TEEs. Currently it is only the ARM
+TrustZone based OP-TEE solution that is supported.
+
+Lowest level of communication with OP-TEE builds on ARM SMC Calling
+Convention (SMCCC) [2], which is the foundation for OP-TEE's SMC interface
+[3] used internally by the driver. Stacked on top of that is OP-TEE Message
+Protocol [4].
+
+OP-TEE SMC interface provides the basic functions required by SMCCC and some
+additional functions specific for OP-TEE. The most interesting functions are:
+
+- OPTEE_SMC_FUNCID_CALLS_UID (part of SMCCC) returns the version information
+  which is then returned by TEE_IOC_VERSION
+
+- OPTEE_SMC_CALL_GET_OS_UUID returns the particular OP-TEE implementation, used
+  to tell, for instance, a TrustZone OP-TEE apart from an OP-TEE running on a
+  separate secure co-processor.
+
+- OPTEE_SMC_CALL_WITH_ARG drives the OP-TEE message protocol
+
+- OPTEE_SMC_GET_SHM_CONFIG lets the driver and OP-TEE agree on which memory
+  range to used for shared memory between Linux and OP-TEE.
+
+The GlobalPlatform TEE Client API [5] is implemented on top of the generic
+TEE API.
+
+Picture of the relationship between the different components in the
+OP-TEE architecture.
+
+    User space                  Kernel                   Secure world
+    ~~~~~~~~~~                  ~~~~~~                   ~~~~~~~~~~~~
+ +--------+                                             +-------------+
+ | Client |                                             | Trusted     |
+ +--------+                                             | Application |
+    /\                                                  +-------------+
+    || +----------+                                           /\
+    || |tee-      |                                           ||
+    || |supplicant|                                           \/
+    || +----------+                                     +-------------+
+    \/      /\                                          | TEE Internal|
+ +-------+  ||                                          | API         |
+ + TEE   |  ||            +--------+--------+           +-------------+
+ | Client|  ||            | TEE    | OP-TEE |           | OP-TEE      |
+ | API   |  \/            | subsys | driver |           | Trusted OS  |
+ +-------+----------------+----+-------+----+-----------+-------------+
+ |      Generic TEE API        |       |     OP-TEE MSG               |
+ |      IOCTL (TEE_IOC_*)      |       |     SMCCC (OPTEE_SMC_CALL_*) |
+ +-----------------------------+       +------------------------------+
+
+RPC (Remote Procedure Call) are requests from secure world to kernel driver
+or tee-supplicant. An RPC is identified by a special range of SMCCC return
+values from OPTEE_SMC_CALL_WITH_ARG. RPC messages which are intended for the
+kernel are handled by the kernel driver. Other RPC messages will be forwarded to
+tee-supplicant without further involvement of the driver, except switching
+shared memory buffer representation.
+
+References:
+[1] https://github.com/OP-TEE/optee_os
+[2] http://infocenter.arm.com/help/topic/com.arm.doc.den0028a/index.html
+[3] drivers/tee/optee/optee_smc.h
+[4] drivers/tee/optee/optee_msg.h
+[5] http://www.globalplatform.org/specificationsdevice.asp look for
+    "TEE Client API Specification v1.0" and click download.
diff --git a/MAINTAINERS b/MAINTAINERS
index 2df3f03..a48d718 100644
--- a/MAINTAINERS
+++ b/MAINTAINERS
@@ -8646,6 +8646,7 @@ S:	Maintained
 F:	include/linux/tee_drv.h
 F:	include/uapi/linux/tee.h
 F:	drivers/tee/
+F:	Documentation/tee.txt
 
 THUNDERBOLT DRIVER
 M:	Andreas Noever <andreas.noever at gmail.com>
-- 
1.9.1



From jens.wiklander at linaro.org  Wed Aug 19 01:40:27 2015
From: jens.wiklander at linaro.org (Jens Wiklander)
Date: Wed, 19 Aug 2015 10:40:27 +0200
Subject: [PATCH v5 3/5] tee: generic TEE subsystem
In-Reply-To: <1439973629-19505-1-git-send-email-jens.wiklander@linaro.org>
References: <1439973629-19505-1-git-send-email-jens.wiklander@linaro.org>
Message-ID: <1439973629-19505-4-git-send-email-jens.wiklander@linaro.org>

Initial patch for generic TEE subsystem.
This subsystem provides:
* Registration/un-registration of TEE drivers.
* Shared memory between normal world and secure world.
* Ioctl interface for interaction with user space.

A TEE (Trusted Execution Environment) driver is a driver that interfaces
with a trusted OS running in some secure environment, for example,
TrustZone on ARM cpus, or a separate secure co-processor etc.

The TEE subsystem can serve a TEE driver for a Global Platform compliant
TEE, but it's not limited to only Global Platform TEEs.

This patch builds on other similar implementations trying to solve
the same problem:
* "optee_linuxdriver" by among others
  Jean-michel DELORME<jean-michel.delorme at st.com> and
  Emmanuel MICHEL <emmanuel.michel at st.com>
* "Generic TrustZone Driver" by Javier Gonz?lez <javier at javigon.com>

Signed-off-by: Jens Wiklander <jens.wiklander at linaro.org>
---
 Documentation/ioctl/ioctl-number.txt |   1 +
 MAINTAINERS                          |   8 +
 drivers/Kconfig                      |   2 +
 drivers/Makefile                     |   1 +
 drivers/tee/Kconfig                  |   8 +
 drivers/tee/Makefile                 |   3 +
 drivers/tee/tee.c                    | 834 +++++++++++++++++++++++++++++++++++
 drivers/tee/tee_private.h            |  80 ++++
 drivers/tee/tee_shm.c                | 324 ++++++++++++++
 drivers/tee/tee_shm_pool.c           | 133 ++++++
 include/linux/tee_drv.h              | 306 +++++++++++++
 include/uapi/linux/tee.h             | 376 ++++++++++++++++
 12 files changed, 2076 insertions(+)
 create mode 100644 drivers/tee/Kconfig
 create mode 100644 drivers/tee/Makefile
 create mode 100644 drivers/tee/tee.c
 create mode 100644 drivers/tee/tee_private.h
 create mode 100644 drivers/tee/tee_shm.c
 create mode 100644 drivers/tee/tee_shm_pool.c
 create mode 100644 include/linux/tee_drv.h
 create mode 100644 include/uapi/linux/tee.h

diff --git a/Documentation/ioctl/ioctl-number.txt b/Documentation/ioctl/ioctl-number.txt
index 51f4221..f54dfc02 100644
--- a/Documentation/ioctl/ioctl-number.txt
+++ b/Documentation/ioctl/ioctl-number.txt
@@ -301,6 +301,7 @@ Code  Seq#(hex)	Include File		Comments
 0xA3	80-8F	Port ACL		in development:
 					<mailto:tlewis at mindspring.com>
 0xA3	90-9F	linux/dtlk.h
+0xA4	00-1F	uapi/linux/tee.h	Generic TEE subsystem
 0xAB	00-1F	linux/nbd.h
 0xAC	00-1F	linux/raw.h
 0xAD	00	Netfilter device	in development:
diff --git a/MAINTAINERS b/MAINTAINERS
index d8afd29..869635f 100644
--- a/MAINTAINERS
+++ b/MAINTAINERS
@@ -8634,6 +8634,14 @@ S:	Maintained
 F:	include/linux/mmc/dw_mmc.h
 F:	drivers/mmc/host/dw_mmc*
 
+TEE SUBSYSTEM
+M:	Jens Wiklander <jens.wiklander at linaro.org>
+M:	Javier Gonz?lez <javier at javigon.com>
+S:	Maintained
+F:	include/linux/tee_drv.h
+F:	include/uapi/linux/tee.h
+F:	drivers/tee/
+
 THUNDERBOLT DRIVER
 M:	Andreas Noever <andreas.noever at gmail.com>
 S:	Maintained
diff --git a/drivers/Kconfig b/drivers/Kconfig
index c0cc96b..7510f69 100644
--- a/drivers/Kconfig
+++ b/drivers/Kconfig
@@ -182,4 +182,6 @@ source "drivers/thunderbolt/Kconfig"
 
 source "drivers/android/Kconfig"
 
+source "drivers/tee/Kconfig"
+
 endmenu
diff --git a/drivers/Makefile b/drivers/Makefile
index 46d2554..852f0af 100644
--- a/drivers/Makefile
+++ b/drivers/Makefile
@@ -165,3 +165,4 @@ obj-$(CONFIG_RAS)		+= ras/
 obj-$(CONFIG_THUNDERBOLT)	+= thunderbolt/
 obj-$(CONFIG_CORESIGHT)		+= hwtracing/coresight/
 obj-$(CONFIG_ANDROID)		+= android/
+obj-$(CONFIG_TEE)		+= tee/
diff --git a/drivers/tee/Kconfig b/drivers/tee/Kconfig
new file mode 100644
index 0000000..64a8cd7
--- /dev/null
+++ b/drivers/tee/Kconfig
@@ -0,0 +1,8 @@
+# Generic Trusted Execution Environment Configuration
+config TEE
+	bool "Trusted Execution Environment support"
+	default n
+	select DMA_SHARED_BUFFER
+	help
+	  This implements a generic interface towards a Trusted Execution
+	  Environment (TEE).
diff --git a/drivers/tee/Makefile b/drivers/tee/Makefile
new file mode 100644
index 0000000..60d2dab
--- /dev/null
+++ b/drivers/tee/Makefile
@@ -0,0 +1,3 @@
+obj-y += tee.o
+obj-y += tee_shm.o
+obj-y += tee_shm_pool.o
diff --git a/drivers/tee/tee.c b/drivers/tee/tee.c
new file mode 100644
index 0000000..f5942c8
--- /dev/null
+++ b/drivers/tee/tee.c
@@ -0,0 +1,834 @@
+/*
+ * Copyright (c) 2015, Linaro Limited
+ *
+ * This software is licensed under the terms of the GNU General Public
+ * License version 2, as published by the Free Software Foundation, and
+ * may be copied, distributed, and modified under those terms.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ * GNU General Public License for more details.
+ *
+ */
+#include <linux/device.h>
+#include <linux/cdev.h>
+#include <linux/fs.h>
+#include <linux/slab.h>
+#include <linux/uaccess.h>
+#include <linux/tee_drv.h>
+#include "tee_private.h"
+
+#define TEE_NUM_DEVICES	32
+
+#define TEE_IOCTL_PARAM_SIZE(x) (sizeof(struct tee_param) * (x))
+
+/*
+ * Unprivileged devices in the in the lower half range and privileged
+ * devices in the upper half range.
+ */
+static DECLARE_BITMAP(dev_mask, TEE_NUM_DEVICES);
+static DEFINE_SPINLOCK(driver_lock);
+
+static struct class *tee_class;
+static dev_t tee_devt;
+
+static int tee_open(struct inode *inode, struct file *filp)
+{
+	int rc;
+	struct tee_device *teedev;
+	struct tee_context *ctx;
+
+	teedev = container_of(inode->i_cdev, struct tee_device, cdev);
+	if (!tee_device_get(teedev))
+		return -EINVAL;
+
+	ctx = kzalloc(sizeof(*ctx), GFP_KERNEL);
+	if (!ctx)
+		return -ENOMEM;
+
+	ctx->teedev = teedev;
+	filp->private_data = ctx;
+	rc = teedev->desc->ops->open(ctx);
+	if (rc) {
+		kfree(ctx);
+		tee_device_put(teedev);
+	}
+	return rc;
+}
+
+static int tee_release(struct inode *inode, struct file *filp)
+{
+	struct tee_context *ctx = filp->private_data;
+	struct tee_device *teedev = ctx->teedev;
+
+	ctx->teedev->desc->ops->release(ctx);
+	kfree(ctx);
+	tee_device_put(teedev);
+	return 0;
+}
+
+static int tee_ioctl_version(struct tee_context *ctx,
+		struct tee_ioctl_version_data __user *uvers)
+{
+	struct tee_ioctl_version_data vers;
+
+	ctx->teedev->desc->ops->get_version(ctx, &vers);
+	if (copy_to_user(uvers, &vers, sizeof(vers)))
+		return -EFAULT;
+	return 0;
+}
+
+static int tee_ioctl_shm_alloc(struct tee_context *ctx,
+		struct tee_ioctl_shm_alloc_data __user *udata)
+{
+	long ret;
+	struct tee_ioctl_shm_alloc_data data;
+	struct tee_shm *shm;
+
+	if (copy_from_user(&data, udata, sizeof(data)))
+		return -EFAULT;
+
+	/* Currently no input flags are supported */
+	if (data.flags)
+		return -EINVAL;
+
+	data.fd = -1;
+
+	shm = tee_shm_alloc(ctx->teedev, data.size,
+			    TEE_SHM_MAPPED | TEE_SHM_DMA_BUF);
+	if (IS_ERR(shm))
+		return PTR_ERR(shm);
+
+	data.flags = shm->flags;
+	data.size = shm->size;
+	data.fd = tee_shm_get_fd(shm);
+	if (data.fd < 0) {
+		ret = data.fd;
+		goto err;
+	}
+
+	if (copy_to_user(udata, &data, sizeof(data))) {
+		ret = -EFAULT;
+		goto err;
+	}
+	/*
+	 * When user space closes the file descriptor the shared memory
+	 * should be freed
+	 */
+	tee_shm_put(shm);
+	return 0;
+err:
+	if (data.fd >= 0)
+		tee_shm_put_fd(data.fd);
+	tee_shm_free(shm);
+	return ret;
+}
+
+static int params_from_user(struct tee_param *params, size_t num_params,
+		struct tee_ioctl_param __user *uparams)
+{
+	size_t n;
+
+	for (n = 0; n < num_params; n++) {
+		struct tee_shm *shm;
+		struct tee_ioctl_param ip;
+
+		if (copy_from_user(&ip, uparams + n, sizeof(ip)))
+			return -EFAULT;
+
+		/* All unused attribute bits has to be zero */
+		if (ip.attr & ~TEE_IOCTL_PARAM_ATTR_TYPE_MASK)
+			return -EINVAL;
+
+		params[n].attr = ip.attr;
+		switch (ip.attr) {
+		case TEE_IOCTL_PARAM_ATTR_TYPE_NONE:
+		case TEE_IOCTL_PARAM_ATTR_TYPE_VALUE_OUTPUT:
+			break;
+		case TEE_IOCTL_PARAM_ATTR_TYPE_VALUE_INPUT:
+		case TEE_IOCTL_PARAM_ATTR_TYPE_VALUE_INOUT:
+			params[n].u.value.a = ip.u.value.a;
+			params[n].u.value.b = ip.u.value.b;
+			params[n].u.value.c = ip.u.value.c;
+			break;
+		case TEE_IOCTL_PARAM_ATTR_TYPE_MEMREF_INPUT:
+		case TEE_IOCTL_PARAM_ATTR_TYPE_MEMREF_OUTPUT:
+		case TEE_IOCTL_PARAM_ATTR_TYPE_MEMREF_INOUT:
+			/*
+			 * If we fail to get a pointer to a shared memory
+			 * object (and increase the ref count) from a file
+			 * descriptor we return an error. All pointers that
+			 * has been added in params have an increased ref
+			 * count. It's the callers responibility to do
+			 * tee_shm_put() on all resolved pointers.
+			 */
+			shm = tee_shm_get_from_fd(ip.u.memref.shm_fd);
+			if (IS_ERR(shm))
+				return PTR_ERR(shm);
+
+			params[n].u.memref.shm_offs = ip.u.memref.shm_offs;
+			params[n].u.memref.size = ip.u.memref.size;
+			params[n].u.memref.shm = shm;
+			break;
+		default:
+			/* Unknown attribute */
+			return -EINVAL;
+		}
+	}
+	return 0;
+}
+
+static int params_to_user(struct tee_ioctl_param __user *uparams,
+		size_t num_params, struct tee_param *params)
+{
+	size_t n;
+
+	for (n = 0; n < num_params; n++) {
+		struct tee_ioctl_param __user *up = uparams + n;
+		struct tee_param *p = params + n;
+
+		switch (p->attr) {
+		case TEE_IOCTL_PARAM_ATTR_TYPE_VALUE_OUTPUT:
+		case TEE_IOCTL_PARAM_ATTR_TYPE_VALUE_INOUT:
+			if (put_user(p->u.value.a, &up->u.value.a) ||
+			    put_user(p->u.value.b, &up->u.value.b) ||
+			    put_user(p->u.value.c, &up->u.value.c))
+				return -EFAULT;
+			break;
+		case TEE_IOCTL_PARAM_ATTR_TYPE_MEMREF_OUTPUT:
+		case TEE_IOCTL_PARAM_ATTR_TYPE_MEMREF_INOUT:
+			if (put_user((u64)p->u.memref.size, &up->u.memref.size))
+				return -EFAULT;
+		default:
+			break;
+		}
+	}
+	return 0;
+}
+
+static bool param_is_memref(struct tee_param *param)
+{
+	switch (param->attr & TEE_IOCTL_PARAM_ATTR_TYPE_MASK) {
+	case TEE_IOCTL_PARAM_ATTR_TYPE_MEMREF_INPUT:
+	case TEE_IOCTL_PARAM_ATTR_TYPE_MEMREF_OUTPUT:
+	case TEE_IOCTL_PARAM_ATTR_TYPE_MEMREF_INOUT:
+		return true;
+	default:
+		return false;
+	}
+}
+
+static int tee_ioctl_open_session(struct tee_context *ctx,
+		struct tee_ioctl_buf_data __user *ubuf)
+{
+	int rc;
+	size_t n;
+	struct tee_ioctl_buf_data buf;
+	struct tee_ioctl_open_session_arg __user *uarg;
+	struct tee_ioctl_open_session_arg arg;
+	struct tee_ioctl_param __user *uparams = NULL;
+	struct tee_param *params = NULL;
+	bool have_session = false;
+
+	if (!ctx->teedev->desc->ops->open_session)
+		return -EINVAL;
+
+	if (copy_from_user(&buf, ubuf, sizeof(buf)))
+		return -EFAULT;
+
+	if (buf.buf_len > TEE_MAX_ARG_SIZE ||
+	    buf.buf_len < sizeof(struct tee_ioctl_open_session_arg))
+		return -EINVAL;
+
+	uarg = (struct tee_ioctl_open_session_arg __user *)(unsigned long)
+		buf.buf_ptr;
+	rc = copy_from_user(&arg, uarg, sizeof(arg));
+	if (rc)
+		return rc;
+
+	if (sizeof(arg) + TEE_IOCTL_PARAM_SIZE(arg.num_params) != buf.buf_len)
+		return -EINVAL;
+
+	if (arg.num_params) {
+		params = kcalloc(arg.num_params, sizeof(struct tee_param),
+				GFP_KERNEL);
+		if (!params)
+			return -ENOMEM;
+		uparams = (struct tee_ioctl_param __user *)(uarg + 1);
+		rc = params_from_user(params, arg.num_params, uparams);
+		if (rc)
+			goto out;
+	}
+
+	rc = ctx->teedev->desc->ops->open_session(ctx, &arg, params);
+	if (rc)
+		goto out;
+	have_session = true;
+
+	if (put_user(arg.session, &uarg->session) ||
+	    put_user(arg.ret, &uarg->ret) ||
+	    put_user(arg.ret_origin, &uarg->ret_origin)) {
+		rc = -EFAULT;
+		goto out;
+	}
+	rc = params_to_user(uparams, arg.num_params, params);
+out:
+	/*
+	 * If we've succeeded to open the session but failed to communicate
+	 * it back to user space, close the session again to avoid leakage.
+	 */
+	if (rc && have_session && ctx->teedev->desc->ops->close_session)
+		ctx->teedev->desc->ops->close_session(ctx, arg.session);
+
+	if (params) {
+		/* Decrease ref count for all valid shared memory pointers */
+		for (n = 0; n < arg.num_params; n++)
+			if (param_is_memref(params + n) &&
+			    params[n].u.memref.shm)
+				tee_shm_put(params[n].u.memref.shm);
+		kfree(params);
+	}
+
+	return rc;
+}
+
+static int tee_ioctl_invoke(struct tee_context *ctx,
+		struct tee_ioctl_buf_data __user *ubuf)
+{
+	int rc;
+	size_t n;
+	struct tee_ioctl_buf_data buf;
+	struct tee_ioctl_invoke_arg __user *uarg;
+	struct tee_ioctl_invoke_arg arg;
+	struct tee_ioctl_param __user *uparams = NULL;
+	struct tee_param *params = NULL;
+
+	if (!ctx->teedev->desc->ops->invoke_func)
+		return -EINVAL;
+
+	rc = copy_from_user(&buf, ubuf, sizeof(buf));
+	if (rc)
+		return rc;
+
+	if (buf.buf_len > TEE_MAX_ARG_SIZE ||
+	    buf.buf_len < sizeof(struct tee_ioctl_invoke_arg))
+		return -EINVAL;
+
+	uarg = (struct tee_ioctl_invoke_arg __user *)(unsigned long)buf.buf_ptr;
+	if (copy_from_user(&arg, uarg, sizeof(arg)))
+		return -EFAULT;
+
+	if (sizeof(arg) + TEE_IOCTL_PARAM_SIZE(arg.num_params) != buf.buf_len)
+		return -EINVAL;
+
+	if (arg.num_params) {
+		params = kcalloc(arg.num_params, sizeof(struct tee_param),
+				GFP_KERNEL);
+		if (!params)
+			return -ENOMEM;
+		uparams = (struct tee_ioctl_param __user *)(uarg + 1);
+		rc = params_from_user(params, arg.num_params, uparams);
+		if (rc)
+			goto out;
+	}
+
+	rc = ctx->teedev->desc->ops->invoke_func(ctx, &arg, params);
+	if (rc)
+		goto out;
+
+	if (put_user(arg.ret, &uarg->ret) ||
+	    put_user(arg.ret_origin, &uarg->ret_origin)) {
+		rc = -EFAULT;
+		goto out;
+	}
+	rc = params_to_user(uparams, arg.num_params, params);
+out:
+	if (params) {
+		/* Decrease ref count for all valid shared memory pointers */
+		for (n = 0; n < arg.num_params; n++)
+			if (param_is_memref(params + n) &&
+			    params[n].u.memref.shm)
+				tee_shm_put(params[n].u.memref.shm);
+		kfree(params);
+	}
+	return rc;
+}
+
+
+static int tee_ioctl_cancel(struct tee_context *ctx,
+		struct tee_ioctl_cancel_arg __user *uarg)
+{
+	struct tee_ioctl_cancel_arg arg;
+
+	if (!ctx->teedev->desc->ops->cancel_req)
+		return -EINVAL;
+
+	if (copy_from_user(&arg, uarg, sizeof(arg)))
+		return -EFAULT;
+
+	return ctx->teedev->desc->ops->cancel_req(ctx, arg.cancel_id,
+						  arg.session);
+}
+
+static int tee_ioctl_close_session(struct tee_context *ctx,
+		struct tee_ioctl_close_session_arg __user *uarg)
+{
+	struct tee_ioctl_close_session_arg arg;
+
+	if (!ctx->teedev->desc->ops->close_session)
+		return -EINVAL;
+
+	if (copy_from_user(&arg, uarg, sizeof(arg)))
+		return -EFAULT;
+
+	return ctx->teedev->desc->ops->close_session(ctx, arg.session);
+}
+
+static int params_to_supp(struct tee_ioctl_param __user *uparams,
+		size_t num_params, struct tee_param *params)
+{
+	int rc = 0;
+	size_t n;
+	int *fds = kmalloc_array(num_params, sizeof(int), GFP_KERNEL);
+
+	if (!fds)
+		return -ENOMEM;
+	for (n = 0; n < num_params; n++)
+		fds[n] = -1;
+
+	for (n = 0; n < num_params; n++) {
+		struct tee_ioctl_param ip;
+		struct tee_param *p = params + n;
+
+		ip.attr = p->attr & TEE_IOCTL_PARAM_ATTR_TYPE_MASK;
+		switch (p->attr) {
+		case TEE_IOCTL_PARAM_ATTR_TYPE_VALUE_INPUT:
+		case TEE_IOCTL_PARAM_ATTR_TYPE_VALUE_INOUT:
+			ip.u.value.a = p->u.value.a;
+			ip.u.value.b = p->u.value.b;
+			ip.u.value.c = p->u.value.c;
+			break;
+		case TEE_IOCTL_PARAM_ATTR_TYPE_MEMREF_INPUT:
+		case TEE_IOCTL_PARAM_ATTR_TYPE_MEMREF_OUTPUT:
+		case TEE_IOCTL_PARAM_ATTR_TYPE_MEMREF_INOUT:
+			ip.u.memref.size = p->u.memref.size;
+			if (!p->u.memref.shm) {
+				ip.u.memref.shm_offs = 0;
+				ip.u.memref.shm_fd = -1;
+				break;
+			}
+			ip.u.memref.shm_offs = p->u.memref.shm_offs;
+			/*
+			 * This tee_shm_get_fd() is supposed to be matched
+			 * by a close(2) from tee-supplicant.
+			 */
+			fds[n] = tee_shm_get_fd(p->u.memref.shm);
+			if (fds[n] < 0) {
+				rc = fds[n];
+				goto out;
+			}
+			ip.u.memref.shm_fd = fds[n];
+			break;
+		default:
+			memset(&ip.u, 0, sizeof(ip.u));
+			break;
+		}
+
+		if (copy_to_user(uparams + n, &ip, sizeof(ip))) {
+			rc = -EFAULT;
+			goto out;
+		}
+	}
+out:
+	if (rc) {
+		for (n = 0; n < num_params; n++)
+			if (fds[n] >= 0)
+				tee_shm_put_fd(fds[n]);
+	}
+	kfree(fds);
+	return rc;
+}
+
+static int tee_ioctl_supp_recv(struct tee_context *ctx,
+		struct tee_ioctl_buf_data __user *ubuf)
+{
+	int rc;
+	struct tee_ioctl_buf_data buf;
+	struct tee_iocl_supp_recv_arg __user *uarg;
+	struct tee_param *params;
+	struct tee_ioctl_param __user *uparams;
+	u32 num_params;
+	u32 func;
+
+	if (!ctx->teedev->desc->ops->supp_recv)
+		return -EINVAL;
+
+	if (copy_from_user(&buf, ubuf, sizeof(buf)))
+		return -EFAULT;
+
+	if (buf.buf_len > TEE_MAX_ARG_SIZE ||
+	    buf.buf_len < sizeof(struct tee_iocl_supp_recv_arg))
+		return -EINVAL;
+
+	uarg = (struct tee_iocl_supp_recv_arg __user *)(unsigned long)
+		buf.buf_ptr;
+	if (get_user(num_params, &uarg->num_params))
+		return -EFAULT;
+
+	if (sizeof(*uarg) + TEE_IOCTL_PARAM_SIZE(num_params) != buf.buf_len)
+		return -EINVAL;
+
+	params = kcalloc(num_params, sizeof(struct tee_param), GFP_KERNEL);
+	if (!params)
+		return -ENOMEM;
+
+	rc = ctx->teedev->desc->ops->supp_recv(ctx, &func, &num_params, params);
+	if (rc)
+		goto out;
+
+	if (put_user(func, &uarg->func) ||
+	    put_user(num_params, &uarg->num_params)) {
+		rc = -EFAULT;
+		goto out;
+	}
+
+	uparams = (struct tee_ioctl_param __user *)(uarg + 1);
+	rc = params_to_supp(uparams, num_params, params);
+out:
+	kfree(params);
+	return rc;
+}
+
+static int params_from_supp(struct tee_param *params,
+		size_t num_params, struct tee_ioctl_param __user *uparams)
+{
+	size_t n;
+
+	for (n = 0; n < num_params; n++) {
+		struct tee_param *p = params + n;
+		struct tee_ioctl_param ip;
+
+		if (copy_from_user(&ip, uparams + n, sizeof(ip)))
+			return -EFAULT;
+
+		/* All unused attribute bits has to be zero */
+		if (ip.attr & ~TEE_IOCTL_PARAM_ATTR_TYPE_MASK)
+			return -EINVAL;
+
+		p->attr = ip.attr;
+		switch (ip.attr) {
+		case TEE_IOCTL_PARAM_ATTR_TYPE_VALUE_OUTPUT:
+		case TEE_IOCTL_PARAM_ATTR_TYPE_VALUE_INOUT:
+			/* Only out and in/out values can be updated */
+			p->u.value.a = ip.u.value.a;
+			p->u.value.b = ip.u.value.b;
+			p->u.value.c = ip.u.value.c;
+			break;
+		case TEE_IOCTL_PARAM_ATTR_TYPE_MEMREF_OUTPUT:
+		case TEE_IOCTL_PARAM_ATTR_TYPE_MEMREF_INOUT:
+			/*
+			 * Only the size of the memref can be updated.
+			 * Since we don't have access to the original
+			 * parameters here, only store the supplied size.
+			 * The driver will copy the updated size into the
+			 * original parameters.
+			 */
+			p->u.memref.shm = NULL;
+			p->u.memref.shm_offs = 0;
+			p->u.memref.size = ip.u.memref.size;
+			break;
+		default:
+			memset(&p->u, 0, sizeof(p->u));
+			break;
+		}
+	}
+	return 0;
+}
+
+static int tee_ioctl_supp_send(struct tee_context *ctx,
+		struct tee_ioctl_buf_data __user *ubuf)
+{
+	long rc;
+	struct tee_ioctl_buf_data buf;
+	struct tee_iocl_supp_send_arg __user *uarg;
+	struct tee_param *params;
+	struct tee_ioctl_param __user *uparams;
+	u32 num_params;
+	u32 ret;
+
+	/* Not valid for this driver */
+	if (!ctx->teedev->desc->ops->supp_send)
+		return -EINVAL;
+
+	if (copy_from_user(&buf, ubuf, sizeof(buf)))
+		return -EFAULT;
+
+	if (buf.buf_len > TEE_MAX_ARG_SIZE ||
+	    buf.buf_len < sizeof(struct tee_iocl_supp_send_arg))
+		return -EINVAL;
+
+	uarg = (struct tee_iocl_supp_send_arg __user *)(unsigned long)
+		buf.buf_ptr;
+	if (get_user(ret, &uarg->ret) ||
+	    get_user(num_params, &uarg->num_params))
+		return -EFAULT;
+
+	if (sizeof(*uarg) + TEE_IOCTL_PARAM_SIZE(num_params) > buf.buf_len)
+		return -EINVAL;
+
+	params = kcalloc(num_params, sizeof(struct tee_param), GFP_KERNEL);
+	if (!params)
+		return -ENOMEM;
+
+	uparams = (struct tee_ioctl_param __user *)(uarg + 1);
+	rc = params_from_supp(params, num_params, uparams);
+	if (rc)
+		goto out;
+
+	rc = ctx->teedev->desc->ops->supp_send(ctx, ret, num_params, params);
+out:
+	kfree(params);
+	return rc;
+}
+
+
+static long tee_ioctl(struct file *filp, unsigned int cmd, unsigned long arg)
+{
+	struct tee_context *ctx = filp->private_data;
+	void __user *uarg = (void __user *)arg;
+
+	switch (cmd) {
+	case TEE_IOC_VERSION:
+		return tee_ioctl_version(ctx, uarg);
+	case TEE_IOC_SHM_ALLOC:
+		return tee_ioctl_shm_alloc(ctx, uarg);
+	case TEE_IOC_OPEN_SESSION:
+		return tee_ioctl_open_session(ctx, uarg);
+	case TEE_IOC_INVOKE:
+		return tee_ioctl_invoke(ctx, uarg);
+	case TEE_IOC_CANCEL:
+		return tee_ioctl_cancel(ctx, uarg);
+	case TEE_IOC_CLOSE_SESSION:
+		return tee_ioctl_close_session(ctx, uarg);
+	case TEE_IOC_SUPPL_RECV:
+		return tee_ioctl_supp_recv(ctx, uarg);
+	case TEE_IOC_SUPPL_SEND:
+		return tee_ioctl_supp_send(ctx, uarg);
+	default:
+		return -EINVAL;
+	}
+}
+
+static const struct file_operations tee_fops = {
+	.open = tee_open,
+	.release = tee_release,
+	.unlocked_ioctl = tee_ioctl,
+	.compat_ioctl = tee_ioctl,
+};
+
+static void tee_release_device(struct device *dev)
+{
+	struct tee_device *teedev = container_of(dev, struct tee_device, dev);
+
+	spin_lock(&driver_lock);
+	clear_bit(teedev->id, dev_mask);
+	spin_unlock(&driver_lock);
+	mutex_destroy(&teedev->mutex);
+	kfree(teedev);
+}
+
+struct tee_device *tee_device_alloc(const struct tee_desc *teedesc,
+			struct device *dev, struct tee_shm_pool *pool,
+			void *driver_data)
+{
+	struct tee_device *teedev;
+	void *ret;
+	int rc;
+	int offs = 0;
+
+	if (!teedesc || !teedesc->name || !teedesc->ops ||
+	    !teedesc->ops->get_version || !teedesc->ops->open ||
+	    !teedesc->ops->release || !dev || !pool)
+		return ERR_PTR(-EINVAL);
+
+	teedev = kzalloc(sizeof(*teedev), GFP_KERNEL);
+	if (!teedev) {
+		ret = ERR_PTR(-ENOMEM);
+		goto err;
+	}
+
+	if (teedesc->flags & TEE_DESC_PRIVILEGED)
+		offs = TEE_NUM_DEVICES / 2;
+
+	spin_lock(&driver_lock);
+	teedev->id = find_next_zero_bit(dev_mask, TEE_NUM_DEVICES, offs);
+	if (teedev->id < TEE_NUM_DEVICES)
+		set_bit(teedev->id, dev_mask);
+	spin_unlock(&driver_lock);
+
+	if (teedev->id >= TEE_NUM_DEVICES) {
+		ret = ERR_PTR(-ENOMEM);
+		goto err;
+	}
+
+	snprintf(teedev->name, sizeof(teedev->name), "tee%s%d",
+		 teedesc->flags & TEE_DESC_PRIVILEGED ? "priv" : "",
+		 teedev->id - offs);
+
+	teedev->dev.class = tee_class;
+	teedev->dev.release = tee_release_device;
+	teedev->dev.parent = dev;
+	teedev->dev.devt = MKDEV(MAJOR(tee_devt), teedev->id);
+
+	rc = dev_set_name(&teedev->dev, "%s", teedev->name);
+	if (rc) {
+		ret = ERR_PTR(rc);
+		goto err;
+	}
+
+	cdev_init(&teedev->cdev, &tee_fops);
+	teedev->cdev.owner = teedesc->owner;
+	teedev->cdev.kobj.parent = &teedev->dev.kobj;
+
+	dev_set_drvdata(&teedev->dev, driver_data);
+	device_initialize(&teedev->dev);
+
+	/* 1 as tee_device_unregister() does one final tee_device_put() */
+	teedev->num_users = 1;
+	init_completion(&teedev->c_no_users);
+	mutex_init(&teedev->mutex);
+
+	teedev->desc = teedesc;
+	teedev->pool = pool;
+	INIT_LIST_HEAD(&teedev->list_shm);
+
+	return teedev;
+err:
+	dev_err(dev, "could not register %s driver\n",
+		teedesc->flags & TEE_DESC_PRIVILEGED ? "privileged" : "client");
+	if (teedev && teedev->id < TEE_NUM_DEVICES) {
+		spin_lock(&driver_lock);
+		clear_bit(teedev->id, dev_mask);
+		spin_unlock(&driver_lock);
+	}
+	kfree(teedev);
+	return ret;
+}
+EXPORT_SYMBOL_GPL(tee_device_alloc);
+
+
+int tee_device_register(struct tee_device *teedev)
+{
+	int rc;
+
+	/*
+	 * If the teedev already is registered, don't do it again. It's
+	 * obviously an error to try to register twice, but if we return
+	 * an error we'll force the driver to remove the teedev.
+	 */
+	if (teedev->flags & TEE_DEVICE_FLAG_REGISTERED) {
+		dev_err(&teedev->dev, "attempt to register twice\n");
+		return 0;
+	}
+
+	rc = cdev_add(&teedev->cdev, teedev->dev.devt, 1);
+	if (rc) {
+		dev_err(&teedev->dev,
+			"unable to cdev_add() %s, major %d, minor %d, err=%d\n",
+			teedev->name, MAJOR(teedev->dev.devt),
+			MINOR(teedev->dev.devt), rc);
+		return rc;
+	}
+
+	rc = device_add(&teedev->dev);
+	if (rc) {
+		dev_err(&teedev->dev,
+			"unable to device_add() %s, major %d, minor %d, err=%d\n",
+			teedev->name, MAJOR(teedev->dev.devt),
+			MINOR(teedev->dev.devt), rc);
+		cdev_del(&teedev->cdev);
+		return rc;
+	}
+	teedev->flags |= TEE_DEVICE_FLAG_REGISTERED;
+	return 0;
+}
+EXPORT_SYMBOL_GPL(tee_device_register);
+
+void tee_device_put(struct tee_device *teedev)
+{
+	mutex_lock(&teedev->mutex);
+	/* Shouldn't put in this state */
+	if (!WARN_ON(!teedev->desc)) {
+		teedev->num_users--;
+		if (!teedev->num_users) {
+			teedev->desc = NULL;
+			complete(&teedev->c_no_users);
+		}
+	}
+	mutex_unlock(&teedev->mutex);
+}
+
+bool tee_device_get(struct tee_device *teedev)
+{
+	mutex_lock(&teedev->mutex);
+	if (!teedev->desc) {
+		mutex_unlock(&teedev->mutex);
+		return false;
+	}
+	teedev->num_users++;
+	mutex_unlock(&teedev->mutex);
+	return true;
+}
+
+void tee_device_unregister(struct tee_device *teedev)
+{
+	if (!teedev)
+		return;
+
+	if (teedev->flags & TEE_DEVICE_FLAG_REGISTERED) {
+		cdev_del(&teedev->cdev);
+		device_del(&teedev->dev);
+	}
+
+	tee_device_put(teedev);
+	wait_for_completion(&teedev->c_no_users);
+
+	/*
+	 * No need to take a mutex any longer now since teedev->desc was
+	 * set to NULL before teedev->c_no_users was completed.
+	 */
+
+	teedev->pool = NULL;
+
+	put_device(&teedev->dev);
+}
+EXPORT_SYMBOL_GPL(tee_device_unregister);
+
+void *tee_get_drvdata(struct tee_device *teedev)
+{
+	return dev_get_drvdata(&teedev->dev);
+}
+EXPORT_SYMBOL_GPL(tee_get_drvdata);
+
+static int __init tee_init(void)
+{
+	int rc;
+
+	tee_class = class_create(THIS_MODULE, "tee");
+	if (IS_ERR(tee_class)) {
+		pr_err("couldn't create class\n");
+		return PTR_ERR(tee_class);
+	}
+
+	rc = alloc_chrdev_region(&tee_devt, 0, TEE_NUM_DEVICES, "tee");
+	if (rc < 0) {
+		pr_err("failed to allocate char dev region\n");
+		class_destroy(tee_class);
+		tee_class = NULL;
+	}
+
+	return rc;
+}
+
+subsys_initcall(tee_init);
diff --git a/drivers/tee/tee_private.h b/drivers/tee/tee_private.h
new file mode 100644
index 0000000..d32ac54
--- /dev/null
+++ b/drivers/tee/tee_private.h
@@ -0,0 +1,80 @@
+/*
+ * Copyright (c) 2015, Linaro Limited
+ *
+ * This software is licensed under the terms of the GNU General Public
+ * License version 2, as published by the Free Software Foundation, and
+ * may be copied, distributed, and modified under those terms.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ * GNU General Public License for more details.
+ *
+ */
+#ifndef TEE_PRIVATE_H
+#define TEE_PRIVATE_H
+
+#include <linux/types.h>
+#include <linux/device.h>
+#include <linux/cdev.h>
+#include <linux/completion.h>
+#include <linux/mutex.h>
+#include <linux/kref.h>
+
+struct tee_device;
+
+struct tee_shm {
+	struct list_head list_node;
+	struct tee_device *teedev;
+	phys_addr_t paddr;
+	void *kaddr;
+	size_t size;
+	struct dma_buf *dmabuf;
+	u32 flags;
+};
+
+struct tee_shm_pool_mgr;
+struct tee_shm_pool_mgr_ops {
+	int (*alloc)(struct tee_shm_pool_mgr *poolmgr, struct tee_shm *shm,
+		     size_t size);
+	void (*free)(struct tee_shm_pool_mgr *poolmgr, struct tee_shm *shm);
+};
+
+struct tee_shm_pool_mgr {
+	const struct tee_shm_pool_mgr_ops *ops;
+	void *private_data;
+};
+
+struct tee_shm_pool {
+	struct tee_shm_pool_mgr private_mgr;
+	struct tee_shm_pool_mgr dma_buf_mgr;
+	void (*destroy)(struct tee_shm_pool *pool);
+	void *private_data;
+};
+
+#define TEE_DEVICE_FLAG_REGISTERED	0x1
+#define TEE_MAX_DEV_NAME_LEN		32
+
+struct tee_device {
+	char name[TEE_MAX_DEV_NAME_LEN];
+	const struct tee_desc *desc;
+	int id;
+	unsigned flags;
+
+	struct device dev;
+	struct cdev cdev;
+
+	size_t num_users;
+	struct completion c_no_users;
+	struct mutex mutex;
+
+	struct list_head list_shm;
+	struct tee_shm_pool *pool;
+};
+
+int tee_shm_init(void);
+
+bool tee_device_get(struct tee_device *teedev);
+void tee_device_put(struct tee_device *teedev);
+
+#endif /*TEE_PRIVATE_H*/
diff --git a/drivers/tee/tee_shm.c b/drivers/tee/tee_shm.c
new file mode 100644
index 0000000..6732e77
--- /dev/null
+++ b/drivers/tee/tee_shm.c
@@ -0,0 +1,324 @@
+/*
+ * Copyright (c) 2015, Linaro Limited
+ *
+ * This software is licensed under the terms of the GNU General Public
+ * License version 2, as published by the Free Software Foundation, and
+ * may be copied, distributed, and modified under those terms.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ * GNU General Public License for more details.
+ *
+ */
+#include <linux/device.h>
+#include <linux/fdtable.h>
+#include <linux/sched.h>
+#include <linux/dma-buf.h>
+#include <linux/slab.h>
+#include <linux/tee_drv.h>
+#include "tee_private.h"
+
+static void tee_shm_release(struct tee_shm *shm)
+{
+	struct tee_device *teedev = shm->teedev;
+	struct tee_shm_pool_mgr *poolm;
+
+	mutex_lock(&teedev->mutex);
+	list_del(&shm->list_node);
+	mutex_unlock(&teedev->mutex);
+
+	if (shm->flags & TEE_SHM_DMA_BUF)
+		poolm = &teedev->pool->dma_buf_mgr;
+	else
+		poolm = &teedev->pool->private_mgr;
+
+	poolm->ops->free(poolm, shm);
+	kfree(shm);
+
+	tee_device_put(teedev);
+}
+
+static struct sg_table *tee_shm_op_map_dma_buf(struct dma_buf_attachment
+			*attach, enum dma_data_direction dir)
+{
+	return NULL;
+}
+
+static void tee_shm_op_unmap_dma_buf(struct dma_buf_attachment *attach,
+			struct sg_table *table, enum dma_data_direction dir)
+{
+}
+
+static void tee_shm_op_release(struct dma_buf *dmabuf)
+{
+	struct tee_shm *shm = dmabuf->priv;
+
+	tee_shm_release(shm);
+}
+
+static void *tee_shm_op_kmap_atomic(struct dma_buf *dmabuf,
+			unsigned long pgnum)
+{
+	return NULL;
+}
+
+static void *tee_shm_op_kmap(struct dma_buf *dmabuf, unsigned long pgnum)
+{
+	return NULL;
+}
+
+static int tee_shm_op_mmap(struct dma_buf *dmabuf,
+			struct vm_area_struct *vma)
+{
+	struct tee_shm *shm = dmabuf->priv;
+	size_t size = vma->vm_end - vma->vm_start;
+
+	return remap_pfn_range(vma, vma->vm_start, shm->paddr >> PAGE_SHIFT,
+			       size, vma->vm_page_prot);
+}
+
+static struct dma_buf_ops tee_shm_dma_buf_ops = {
+	.map_dma_buf = tee_shm_op_map_dma_buf,
+	.unmap_dma_buf = tee_shm_op_unmap_dma_buf,
+	.release = tee_shm_op_release,
+	.kmap_atomic = tee_shm_op_kmap_atomic,
+	.kmap = tee_shm_op_kmap,
+	.mmap = tee_shm_op_mmap,
+};
+
+struct tee_shm *tee_shm_alloc(struct tee_device *teedev, size_t size,
+			u32 flags)
+{
+	struct tee_shm_pool_mgr *poolm = NULL;
+	struct tee_shm *shm;
+	void *ret;
+	int rc;
+
+	if (!(flags & TEE_SHM_MAPPED)) {
+		dev_err(teedev->dev.parent,
+			"only mapped allocations supported\n");
+		return ERR_PTR(-EINVAL);
+	}
+
+	if ((flags & ~(TEE_SHM_MAPPED|TEE_SHM_DMA_BUF))) {
+		dev_err(teedev->dev.parent, "invalid shm flags 0x%x", flags);
+		return ERR_PTR(-EINVAL);
+	}
+
+	if (!tee_device_get(teedev))
+		return ERR_PTR(-EINVAL);
+
+	if (!teedev->pool) {
+		/* teedev has been detached from driver */
+		ret = ERR_PTR(-EINVAL);
+		goto err;
+	}
+
+	shm = kzalloc(sizeof(struct tee_shm), GFP_KERNEL);
+	if (!shm) {
+		ret = ERR_PTR(-ENOMEM);
+		goto err;
+	}
+
+	shm->flags = flags;
+	shm->teedev = teedev;
+	if (flags & TEE_SHM_DMA_BUF)
+		poolm = &teedev->pool->dma_buf_mgr;
+	else
+		poolm = &teedev->pool->private_mgr;
+
+	rc = poolm->ops->alloc(poolm, shm, size);
+	if (rc) {
+		ret = ERR_PTR(rc);
+		goto err;
+	}
+
+	mutex_lock(&teedev->mutex);
+	list_add_tail(&shm->list_node, &teedev->list_shm);
+	mutex_unlock(&teedev->mutex);
+
+	if (flags & TEE_SHM_DMA_BUF) {
+		DEFINE_DMA_BUF_EXPORT_INFO(exp_info);
+
+		exp_info.ops = &tee_shm_dma_buf_ops;
+		exp_info.size = shm->size;
+		exp_info.flags = O_RDWR;
+		exp_info.priv = shm;
+
+		shm->dmabuf = dma_buf_export(&exp_info);
+		if (IS_ERR(shm->dmabuf)) {
+			ret = ERR_CAST(shm->dmabuf);
+			goto err;
+		}
+	}
+
+	return shm;
+err:
+	if (poolm && shm && shm->kaddr)
+		poolm->ops->free(poolm, shm);
+	kfree(shm);
+	tee_device_put(teedev);
+	return ret;
+}
+EXPORT_SYMBOL_GPL(tee_shm_alloc);
+
+int tee_shm_get_fd(struct tee_shm *shm)
+{
+	u32 req_flags = TEE_SHM_MAPPED | TEE_SHM_DMA_BUF;
+	int fd;
+
+	if ((shm->flags & req_flags) != req_flags)
+		return -EINVAL;
+
+	fd = dma_buf_fd(shm->dmabuf, O_CLOEXEC);
+	if (fd >= 0)
+		get_dma_buf(shm->dmabuf);
+	return fd;
+}
+EXPORT_SYMBOL_GPL(tee_shm_get_fd);
+
+int tee_shm_put_fd(int fd)
+{
+	return __close_fd(current->files, fd);
+}
+EXPORT_SYMBOL_GPL(tee_shm_put_fd);
+
+void tee_shm_free(struct tee_shm *shm)
+{
+
+	/*
+	 * dma_buf_put() decreases the dmabuf reference counter and will
+	 * call tee_shm_release() when the last reference is gone.
+	 *
+	 * In the case of driver private memory we call tee_shm_release
+	 * directly instead as it doesn't have a reference counter.
+	 */
+	if (shm->flags & TEE_SHM_DMA_BUF)
+		dma_buf_put(shm->dmabuf);
+	else
+		tee_shm_release(shm);
+}
+EXPORT_SYMBOL_GPL(tee_shm_free);
+
+static bool cmp_key_va(struct tee_shm *shm, uintptr_t va)
+{
+	uintptr_t shm_va = (uintptr_t)shm->kaddr;
+
+	return (va >= shm_va) && (va < (shm_va + shm->size));
+}
+
+static bool cmp_key_pa(struct tee_shm *shm, uintptr_t pa)
+{
+	return (pa >= shm->paddr) && (pa < (shm->paddr + shm->size));
+}
+
+static struct tee_shm *tee_shm_find_by_key(struct tee_device *teedev, u32 flags,
+			bool (*cmp)(struct tee_shm *shm, uintptr_t key),
+			uintptr_t key)
+{
+	struct tee_shm *ret = NULL;
+	struct tee_shm *shm;
+
+	mutex_lock(&teedev->mutex);
+	list_for_each_entry(shm, &teedev->list_shm, list_node) {
+		if (cmp(shm, key)) {
+			ret = shm;
+			break;
+		}
+	}
+	mutex_unlock(&teedev->mutex);
+
+	return ret;
+}
+
+struct tee_shm *tee_shm_find_by_va(struct tee_device *teedev, u32 flags,
+			void *va)
+{
+	return tee_shm_find_by_key(teedev, flags, cmp_key_va, (uintptr_t)va);
+}
+EXPORT_SYMBOL_GPL(tee_shm_find_by_va);
+
+struct tee_shm *tee_shm_find_by_pa(struct tee_device *teedev, u32 flags,
+			phys_addr_t pa)
+{
+	return tee_shm_find_by_key(teedev, flags, cmp_key_pa, pa);
+}
+EXPORT_SYMBOL_GPL(tee_shm_find_by_pa);
+
+int tee_shm_va2pa(struct tee_shm *shm, void *va, phys_addr_t *pa)
+{
+	/* Check that we're in the range of the shm */
+	if ((char *)va < (char *)shm->kaddr)
+		return -EINVAL;
+	if ((char *)va >= ((char *)shm->kaddr + shm->size))
+		return -EINVAL;
+
+	return tee_shm_get_pa(
+			shm, (unsigned long)va - (unsigned long)shm->kaddr, pa);
+}
+EXPORT_SYMBOL_GPL(tee_shm_va2pa);
+
+int tee_shm_pa2va(struct tee_shm *shm, phys_addr_t pa, void **va)
+{
+	/* Check that we're in the range of the shm */
+	if (pa < shm->paddr)
+		return -EINVAL;
+	if (pa >= (shm->paddr + shm->size))
+		return -EINVAL;
+
+	if (va) {
+		void *v = tee_shm_get_va(shm, pa - shm->paddr);
+
+		if (IS_ERR(v))
+			return PTR_ERR(v);
+		*va = v;
+	}
+	return 0;
+}
+EXPORT_SYMBOL_GPL(tee_shm_pa2va);
+
+void *tee_shm_get_va(struct tee_shm *shm, size_t offs)
+{
+	if (offs >= shm->size)
+		return ERR_PTR(-EINVAL);
+	return (char *)shm->kaddr + offs;
+}
+EXPORT_SYMBOL_GPL(tee_shm_get_va);
+
+int tee_shm_get_pa(struct tee_shm *shm, size_t offs, phys_addr_t *pa)
+{
+	if (offs >= shm->size)
+		return -EINVAL;
+	if (pa)
+		*pa = shm->paddr + offs;
+	return 0;
+}
+EXPORT_SYMBOL_GPL(tee_shm_get_pa);
+
+static bool is_shm_dma_buf(struct dma_buf *dmabuf)
+{
+	return dmabuf->ops == &tee_shm_dma_buf_ops;
+}
+
+struct tee_shm *tee_shm_get_from_fd(int fd)
+{
+	struct dma_buf *dmabuf = dma_buf_get(fd);
+
+	if (IS_ERR(dmabuf))
+		return ERR_CAST(dmabuf);
+
+	if (!is_shm_dma_buf(dmabuf)) {
+		dma_buf_put(dmabuf);
+		return ERR_PTR(-EINVAL);
+	}
+	return dmabuf->priv;
+}
+EXPORT_SYMBOL_GPL(tee_shm_get_from_fd);
+
+void tee_shm_put(struct tee_shm *shm)
+{
+	if (shm->flags & TEE_SHM_DMA_BUF)
+		dma_buf_put(shm->dmabuf);
+}
+EXPORT_SYMBOL_GPL(tee_shm_put);
diff --git a/drivers/tee/tee_shm_pool.c b/drivers/tee/tee_shm_pool.c
new file mode 100644
index 0000000..2ef22bc
--- /dev/null
+++ b/drivers/tee/tee_shm_pool.c
@@ -0,0 +1,133 @@
+/*
+ * Copyright (c) 2015, Linaro Limited
+ *
+ * This software is licensed under the terms of the GNU General Public
+ * License version 2, as published by the Free Software Foundation, and
+ * may be copied, distributed, and modified under those terms.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ * GNU General Public License for more details.
+ *
+ */
+#include <linux/device.h>
+#include <linux/dma-buf.h>
+#include <linux/slab.h>
+#include <linux/genalloc.h>
+#include <linux/tee_drv.h>
+#include "tee_private.h"
+
+static int pool_op_gen_alloc(struct tee_shm_pool_mgr *poolm,
+			struct tee_shm *shm, size_t size)
+{
+	unsigned long va;
+	struct gen_pool *genpool = poolm->private_data;
+	size_t s = roundup(size, 1 << genpool->min_alloc_order);
+
+	va = gen_pool_alloc(genpool, s);
+	if (!va)
+		return -ENOMEM;
+	shm->kaddr = (void *)va;
+	shm->paddr = gen_pool_virt_to_phys(genpool, va);
+	shm->size = s;
+	return 0;
+}
+
+static void pool_op_gen_free(struct tee_shm_pool_mgr *poolm,
+			struct tee_shm *shm)
+{
+	gen_pool_free(poolm->private_data, (unsigned long)shm->kaddr,
+		      shm->size);
+	shm->kaddr = NULL;
+}
+
+static const struct tee_shm_pool_mgr_ops pool_ops_generic = {
+	.alloc = pool_op_gen_alloc,
+	.free = pool_op_gen_free,
+};
+
+static void pool_res_mem_destroy(struct tee_shm_pool *pool)
+{
+	gen_pool_destroy(pool->private_mgr.private_data);
+	gen_pool_destroy(pool->dma_buf_mgr.private_data);
+}
+
+static int pool_res_mem_mgr_init(struct tee_shm_pool_mgr *mgr,
+			struct tee_shm_pool_mem_info *info, int min_alloc_order)
+{
+	size_t page_mask = PAGE_SIZE - 1;
+	struct gen_pool *genpool = NULL;
+	int rc;
+
+	/*
+	 * Start and end must be page aligned
+	 */
+	if ((info->vaddr & page_mask) || (info->paddr & page_mask) ||
+	    (info->size & page_mask))
+		return -EINVAL;
+
+	genpool = gen_pool_create(min_alloc_order, -1);
+	if (!genpool)
+		return -ENOMEM;
+
+	gen_pool_set_algo(genpool, gen_pool_best_fit, NULL);
+	rc = gen_pool_add_virt(genpool, info->vaddr, info->paddr, info->size,
+			       -1);
+	if (rc) {
+		gen_pool_destroy(genpool);
+		return rc;
+	}
+
+	mgr->private_data = genpool;
+	mgr->ops = &pool_ops_generic;
+	return 0;
+}
+
+struct tee_shm_pool *tee_shm_pool_alloc_res_mem(struct device *dev,
+			struct tee_shm_pool_mem_info *priv_info,
+			struct tee_shm_pool_mem_info *dmabuf_info)
+{
+	struct tee_shm_pool *pool = NULL;
+	int ret;
+
+	pool = kzalloc(sizeof(*pool), GFP_KERNEL);
+	if (!pool) {
+		ret = -ENOMEM;
+		goto err;
+	}
+
+	/*
+	 * Create the pool for driver private shared memory
+	 */
+	ret = pool_res_mem_mgr_init(&pool->private_mgr, priv_info,
+				    3 /* 8 byte aligned */);
+	if (ret)
+		goto err;
+
+	/*
+	 * Create the pool for dma_buf shared memory
+	 */
+	ret = pool_res_mem_mgr_init(&pool->dma_buf_mgr, dmabuf_info,
+				    PAGE_SHIFT);
+	if (ret)
+		goto err;
+
+	pool->destroy = pool_res_mem_destroy;
+	return pool;
+err:
+	if (ret == -ENOMEM)
+		dev_err(dev, "can't allocate memory for res_mem shared memory pool\n");
+	if (pool && pool->private_mgr.private_data)
+		gen_pool_destroy(pool->private_mgr.private_data);
+	kfree(pool);
+	return ERR_PTR(ret);
+}
+EXPORT_SYMBOL_GPL(tee_shm_pool_alloc_res_mem);
+
+void tee_shm_pool_free(struct tee_shm_pool *pool)
+{
+	pool->destroy(pool);
+	kfree(pool);
+}
+EXPORT_SYMBOL_GPL(tee_shm_pool_free);
diff --git a/include/linux/tee_drv.h b/include/linux/tee_drv.h
new file mode 100644
index 0000000..1b55f3b
--- /dev/null
+++ b/include/linux/tee_drv.h
@@ -0,0 +1,306 @@
+/*
+ * Copyright (c) 2015, Linaro Limited
+ *
+ * This software is licensed under the terms of the GNU General Public
+ * License version 2, as published by the Free Software Foundation, and
+ * may be copied, distributed, and modified under those terms.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ * GNU General Public License for more details.
+ *
+ */
+
+#ifndef __TEE_DRV_H
+#define __TEE_DRV_H
+
+#include <linux/types.h>
+#include <linux/list.h>
+#include <linux/miscdevice.h>
+#include <linux/tee.h>
+
+/*
+ * The file describes the API provided by the generic TEE driver to the
+ * specific TEE driver.
+ */
+
+#define TEE_SHM_MAPPED		0x1	/* Memory mapped by the kernel */
+#define TEE_SHM_DMA_BUF		0x2	/* Memory with dma-buf handle */
+
+struct tee_device;
+struct tee_shm;
+struct tee_shm_pool;
+
+/**
+ * struct tee_context - driver specific context on file pointer data
+ * @teedev:	pointer to this drivers struct tee_device
+ * @data:	driver specific context data, managed by the driver
+ */
+struct tee_context {
+	struct tee_device *teedev;
+	void *data;
+};
+
+struct tee_param_memref {
+	size_t shm_offs;
+	size_t size;
+	struct tee_shm *shm;
+};
+
+struct tee_param_value {
+	u64 a;
+	u64 b;
+	u64 c;
+};
+
+struct tee_param {
+	u64 attr;
+	union {
+		struct tee_param_memref memref;
+		struct tee_param_value value;
+	} u;
+};
+
+/**
+ * struct tee_driver_ops - driver operations vtable
+ * @get_version:	returns version of driver
+ * @open:		called when the device file is opened
+ * @release:		release this open file
+ */
+struct tee_driver_ops {
+	void (*get_version)(struct tee_context *ctx,
+			struct tee_ioctl_version_data *vers);
+	int (*open)(struct tee_context *ctx);
+	void (*release)(struct tee_context *ctx);
+	int (*open_session)(struct tee_context *ctx,
+			struct tee_ioctl_open_session_arg *arg,
+			struct tee_param *param);
+	int (*close_session)(struct tee_context *ctx, u32 session);
+	int (*invoke_func)(struct tee_context *ctx,
+			struct tee_ioctl_invoke_arg *arg,
+			struct tee_param *param);
+	int (*cancel_req)(struct tee_context *ctx, u32 cancel_id, u32 session);
+	int (*supp_recv)(struct tee_context *ctx, u32 *func, u32 *num_params,
+			struct tee_param *param);
+	int (*supp_send)(struct tee_context *ctx, u32 ret, u32 num_params,
+			struct tee_param *param);
+};
+
+/**
+ * struct tee_desc - Describes the TEE driver to the subsystem
+ * @name:	name of driver
+ * @ops:	driver operations vtable
+ * @owner:	module providing the driver
+ * @flags:	Extra properties of driver, defined by TEE_DESC_* below
+ */
+#define TEE_DESC_PRIVILEGED	0x1
+struct tee_desc {
+	const char *name;
+	const struct tee_driver_ops *ops;
+	struct module *owner;
+	u32 flags;
+};
+
+
+/**
+ * tee_device_alloc() - Allocate a new struct tee_device instance
+ * @teedesc:	Descriptor for this driver
+ * @dev:	Parent device for this device
+ * @pool:	Shared memory pool, NULL if not used
+ * @driver_data: Private driver data for this device
+ *
+ * Allocates a new struct tee_device instance. The device is
+ * removed by tee_device_unregister().
+ *
+ * @returns a pointer to a 'struct tee_device' or an ERR_PTR on failure
+ */
+struct tee_device *tee_device_alloc(const struct tee_desc *teedesc,
+			struct device *dev, struct tee_shm_pool *pool,
+			void *driver_data);
+
+/**
+ * tee_device_register() - Registers a TEE device
+ * @teedev:	Device to register
+ *
+ * tee_device_unregister() need to be called to remove the @teedev if
+ * this function fails.
+ *
+ * @returns < 0 on failure
+ */
+int tee_device_register(struct tee_device *teedev);
+
+/**
+ * tee_device_unregister() - Removes a TEE device
+ * @teedev:	Device to unregister
+ *
+ * This function should be called to remove the @teedev even if
+ * tee_device_register() hasn't been called yet. Does nothing if
+ * @teedev is NULL.
+ */
+void tee_device_unregister(struct tee_device *teedev);
+
+/**
+ * struct tee_shm_pool_mem_info - holds information needed to create a shared memory pool
+ * @vaddr:	Virtual address of start of pool
+ * @paddr:	Physical address of start of pool
+ * @size:	Size in bytes of the pool
+ */
+struct tee_shm_pool_mem_info {
+	unsigned long vaddr;
+	unsigned long paddr;
+	size_t size;
+};
+
+/**
+ * tee_shm_pool_alloc_res_mem() - Create a shared memory pool from reserved memory range
+ * @dev:	Device allocating the pool
+ * @priv_info:	Information for driver private shared memory pool
+ * @dmabuf_info: Information for dma-buf shared memory pool
+ *
+ * Start and end of pools will must be page aligned.
+ *
+ * Allocation with the flag TEE_SHM_DMA_BUF set will use the range supplied
+ * in @dmabuf, others will use the range provided by @priv.
+ *
+ * @returns pointer to a 'struct tee_shm_pool' or an ERR_PTR on failure.
+ */
+struct tee_shm_pool *tee_shm_pool_alloc_res_mem(struct device *dev,
+			struct tee_shm_pool_mem_info *priv_info,
+			struct tee_shm_pool_mem_info *dmabuf_info);
+
+/**
+ * tee_shm_pool_free() - Free a shared memory pool
+ * @pool:	The shared memory pool to free
+ *
+ * The must be no remaining shared memory allocated from this pool when
+ * this function is called.
+ */
+void tee_shm_pool_free(struct tee_shm_pool *pool);
+
+/**
+ * tee_get_drvdata() - Return driver_data pointer
+ * @returns the driver_data pointer supplied to tee_register().
+ */
+void *tee_get_drvdata(struct tee_device *teedev);
+
+/**
+ * tee_shm_alloc() - Allocate shared memory
+ * @teedev:	Driver that allocates the shared memory
+ * @size:	Requested size of shared memory
+ * @flags:	Flags setting properties for the requested shared memory.
+ *
+ * Memory allocated as global shared memory is automatically freed when the
+ * TEE file pointer is closed. The @flags field uses the bits defined by
+ * TEE_SHM_* above. TEE_SHM_MAPPED must currently always be set. If
+ * TEE_SHM_DMA_BUF global shared memory will be allocated and associated
+ * with a dma-buf handle, else driver private memory.
+ *
+ * @returns a pointer to 'struct tee_shm'
+ */
+struct tee_shm *tee_shm_alloc(struct tee_device *teedev, size_t size,
+			u32 flags);
+
+/**
+ * tee_shm_free() - Free shared memory
+ * @shm:	Handle to shared memory to free
+ */
+void tee_shm_free(struct tee_shm *shm);
+
+/**
+ * tee_shm_find_by_va() - Find a shared memory handle by a virtual address
+ * @teedev:	The device that owns the shared memory
+ * @flags:	Select which type of shared memory to locate, if
+ *		TEE_SHM_DMA_BUF global shared memory else driver private
+ *		shared memory.
+ * @va:		Virtual address covered by the shared memory
+ * @returns a Handle to shared memory
+ */
+struct tee_shm *tee_shm_find_by_va(struct tee_device *teedev, u32 flags,
+			void *va);
+/**
+ * tee_shm_find_by_pa() - Find a shared memory handle by a physical address
+ * @teedev:	The device that owns the shared memory
+ * @flags:	Select which type of shared memory to locate, if
+ *		TEE_SHM_DMA_BUF global shared memory else driver private
+ *		shared memory.
+ * @pa:		Physical address covered by the shared memory
+ * @returns a Handle to shared memory
+ */
+struct tee_shm *tee_shm_find_by_pa(struct tee_device *teedev, u32 flags,
+			phys_addr_t pa);
+
+/**
+ * tee_shm_va2pa() - Get physical address of a virtual address
+ * @shm:	Shared memory handle
+ * @va:		Virtual address to tranlsate
+ * @pa:		Returned physical address
+ * @returns 0 on success and < 0 on failure
+ */
+int tee_shm_va2pa(struct tee_shm *shm, void *va, phys_addr_t *pa);
+
+/**
+ * tee_shm_pa2va() - Get virtual address of a physical address
+ * @shm:	Shared memory handle
+ * @pa:		Physical address to tranlsate
+ * @va:		Returned virtual address
+ * @returns 0 on success and < 0 on failure
+ */
+int tee_shm_pa2va(struct tee_shm *shm, phys_addr_t pa, void **va);
+
+/**
+ * tee_shm_get_size() - Get size of a shared memory
+ * @returns the size of the shared memory
+ */
+size_t tee_shm_get_size(struct tee_shm *shm);
+
+/**
+ * tee_shm_get_va() - Get virtual address of a shared memory plus an offset
+ * @shm:	Shared memory handle
+ * @offs:	Offset from start of this shared memory
+ * @returns virtual address of the shared memory + offs if offs is within
+ *	the bounds of this shared memory, else an ERR_PTR
+ */
+void *tee_shm_get_va(struct tee_shm *shm, size_t offs);
+
+/**
+ * tee_shm_get_pa() - Get physical address of a shared memory plus an offset
+ * @shm:	Shared memory handle
+ * @offs:	Offset from start of this shared memory
+ * @pa:		Physical address to return
+ * @returns 0 if offs is within the bounds of this shared memory, else an
+ *	error code.
+ */
+int tee_shm_get_pa(struct tee_shm *shm, size_t offs, phys_addr_t *pa);
+
+/**
+ * tee_shm_get_from_fd() - Get a shared memory handle from a file descriptor
+ * @fd:		A user space file descriptor
+ *
+ * This function increases the reference counter on the shared memory and
+ * returns a handle.
+ * @returns handle to shared memory
+ */
+struct tee_shm *tee_shm_get_from_fd(int fd);
+
+/**
+ * tee_shm_put() - Decrease reference count on a shared memory handle
+ * @shm:	Shared memory handle
+ */
+void tee_shm_put(struct tee_shm *shm);
+
+/**
+ * tee_shm_get_fd() - Increase reference count and return file descriptor
+ * @shm:	Shared memory handle
+ * @returns user space file descriptor to shared memory
+ */
+int tee_shm_get_fd(struct tee_shm *shm);
+
+/**
+ * tee_shm_put_fd() - Decrease reference count and close file descriptor
+ * @fd:		File descriptor to close
+ * @returns < 0 on failure
+ */
+int tee_shm_put_fd(int fd);
+
+#endif /*__TEE_DRV_H*/
diff --git a/include/uapi/linux/tee.h b/include/uapi/linux/tee.h
new file mode 100644
index 0000000..39186c4
--- /dev/null
+++ b/include/uapi/linux/tee.h
@@ -0,0 +1,376 @@
+/*
+ * Copyright (c) 2015, Linaro Limited
+ *
+ * This software is licensed under the terms of the GNU General Public
+ * License version 2, as published by the Free Software Foundation, and
+ * may be copied, distributed, and modified under those terms.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ * GNU General Public License for more details.
+ *
+ */
+
+#ifndef __TEE_H
+#define __TEE_H
+
+#include <linux/ioctl.h>
+#include <linux/types.h>
+
+/*
+ * This file describes the API provided by a TEE driver to user space.
+ *
+ * Each TEE driver defines a TEE specific protocol which is used for the
+ * data passed back and forth using TEE_IOC_CMD.
+ */
+
+
+/* Helpers to make the ioctl defines */
+#define TEE_IOC_MAGIC	0xa4
+#define TEE_IOC_BASE	0
+
+/* Flags relating to shared memory */
+#define TEE_IOCTL_SHM_MAPPED	0x1	/* memory mapped in normal world */
+#define TEE_IOCTL_SHM_DMA_BUF	0x2	/* dma-buf handle on shared memory */
+
+#define TEE_MAX_ARG_SIZE	1024
+
+#define TEE_GEN_CAP_GP		(1 << 0)/* Global Platform compliant TEE */
+
+#define TEE_IMPL_ID_OPTEE	1
+#define TEE_OPTEE_CAP_TZ	(1 << 0)
+
+/**
+ * struct tee_version - TEE version
+ * @impl_id:	[out] TEE implementation id
+ * @impl_caps:	[out] Implementation specific capabilities
+ * @gen_caps:	[out] Generic capabilities, defined by TEE_GEN_CAPS_* above
+ *
+ * Identifies the TEE implementaion, @impl_id is one of TEE_IMPL_ID_* above.
+ * @impl_caps is implementation specific, for example TEE_OPTEE_CAP_*
+ * is valid when @impl_id == TEE_IMPL_ID_OPTEE.
+ */
+struct tee_ioctl_version_data {
+	__u32 impl_id;
+	__u32 impl_caps;
+	__u32 gen_caps;
+};
+/**
+ * TEE_IOC_VERSION - query version of TEE
+ *
+ * Takes a tee_version struct and returns with the TEE version data filled
+ * in.
+ */
+#define TEE_IOC_VERSION		_IOR(TEE_IOC_MAGIC, TEE_IOC_BASE + 0, \
+				     struct tee_ioctl_version_data)
+
+/**
+ * struct tee_shm_alloc_data - Shared memory allocate argument
+ * @size:	[in/out] Size of shared memory to allocate
+ * @flags:	[in/out] Flags to/from allocation.
+ * @fd:		[out] dma_buf file descriptor of the shared memory
+ *
+ * The flags field should currently be zero as input. Updated by the call
+ * with actual flags as defined by TEE_IOCTL_SHM_* above.
+ * This structure is used as argument for TEE_IOC_SHM_ALLOC below.
+ */
+struct tee_ioctl_shm_alloc_data {
+	__u64 size;
+	__u32 flags;
+	__s32 fd;
+};
+/**
+ * TEE_IOC_SHM_ALLOC - allocate shared memory
+ *
+ * Allocates shared memory between the user space process and secure OS.
+ * The returned file descriptor is used to map the shared memory into user
+ * space. The shared memory is freed when the descriptor is closed and the
+ * memory is unmapped.
+ */
+#define TEE_IOC_SHM_ALLOC	_IOWR(TEE_IOC_MAGIC, TEE_IOC_BASE + 1, \
+				     struct tee_ioctl_shm_alloc_data)
+
+/**
+ * struct tee_buf_data - Variable sized buffer
+ * @buf_ptr:	[in] A __user pointer to a buffer
+ * @buf_len:	[in] Length of the buffer above
+ *
+ * Used as argument for TEE_IOC_OPEN_SESSION, TEE_IOC_INVOKE,
+ * TEE_IOC_SUPPL_RECV, and TEE_IOC_SUPPL_SEND below.
+ */
+struct tee_ioctl_buf_data {
+	__u64 buf_ptr;
+	__u64 buf_len;
+};
+
+
+/*
+ * Attributes for struct tee_ioctl_param, selects field in the union
+ */
+#define TEE_IOCTL_PARAM_ATTR_TYPE_NONE		0	/* parameter not used */
+
+/*
+ * These defines value parameters (struct tee_ioctl_param_value)
+ */
+#define TEE_IOCTL_PARAM_ATTR_TYPE_VALUE_INPUT	1
+#define TEE_IOCTL_PARAM_ATTR_TYPE_VALUE_OUTPUT	2
+#define TEE_IOCTL_PARAM_ATTR_TYPE_VALUE_INOUT	3	/* input and output */
+
+/*
+ * These defines shared memory reference parameters (struct
+ * tee_ioctl_param_memref)
+ */
+#define TEE_IOCTL_PARAM_ATTR_TYPE_MEMREF_INPUT	5
+#define TEE_IOCTL_PARAM_ATTR_TYPE_MEMREF_OUTPUT	6
+#define TEE_IOCTL_PARAM_ATTR_TYPE_MEMREF_INOUT	7	/* input and output */
+
+/*
+ * Mask for the type part of the attribute, leaves room for more types
+ */
+#define TEE_IOCTL_PARAM_ATTR_TYPE_MASK		0xff
+
+/*
+ * Matches TEEC_LOGIN_* in GP TEE Client API
+ * Is only defined for GP compliant TEEs
+ */
+#define TEE_IOCTL_LOGIN_PUBLIC			0
+#define TEE_IOCTL_LOGIN_USER			1
+#define TEE_IOCTL_LOGIN_GROUP			2
+#define TEE_IOCTL_LOGIN_APPLICATION		4
+#define TEE_IOCTL_LOGIN_USER_APPLICATION	5
+#define TEE_IOCTL_LOGIN_GROUP_APPLICATION	6
+
+/**
+ * struct tee_ioctl_param_memref - memory reference
+ * @shm_offs:	Offset into the shared memory object
+ * @size:	Size of the buffer
+ * @shm_fd:	Shared memory file descriptor
+ *
+ * Shared memory is allocated with TEE_IOC_SHM_ALLOC which returns a file
+ * descriptor connected to the shared memory object. A memref can reference
+ * a part of a shared memory by specifying an offset (@shm_offs) and @size
+ * of the object. To supply the entire shared memory object set @shm_offs to 0
+ * and @size to the previously returned size of the object.
+ */
+struct tee_ioctl_param_memref {
+	__u64 shm_offs;
+	__u64 size;
+	__s64 shm_fd;
+};
+
+/**
+ * struct tee_ioctl_param_value - values
+ * @a: first value
+ * @b: second value
+ * @c: third value
+ */
+struct tee_ioctl_param_value {
+	__u64 a;
+	__u64 b;
+	__u64 c;
+};
+
+/**
+ * struct tee_ioctl_param - parameter
+ * @attr: attributes
+ * @memref: a memory reference
+ * @value: a value
+ *
+ * @attr & TEE_PARAM_ATTR_TYPE_MASK indicates if memref or value is used in
+ * the union. TEE_PARAM_ATTR_TYPE_VALUE_* indicates value and
+ * TEE_PARAM_ATTR_TYPE_MEMREF_* indicates memref. TEE_PARAM_ATTR_TYPE_NONE
+ * indicates that none of the members are used.
+ */
+struct tee_ioctl_param {
+	__u64 attr;
+	union {
+		struct tee_ioctl_param_memref memref;
+		struct tee_ioctl_param_value value;
+	} u;
+};
+
+#define TEE_IOCTL_UUID_LEN		16
+
+/**
+ * struct tee_open_session_arg - Open session argument
+ * @uuid:	[in] UUID of the Trusted Application
+ * @clnt_uuid:	[in] UUID of client
+ * @clnt_login:	[in] Login class of client, TEE_LOGIN_* above
+ * @cancel_id:	[in] Cancellation id, a unique value to identify this request
+ * @session:	[out] Session id
+ * @ret:	[out] return value
+ * @ret_origin	[out] origin of the return value
+ * @num_params	[in] number of parameters following this struct
+ */
+struct tee_ioctl_open_session_arg {
+	__u8 uuid[TEE_IOCTL_UUID_LEN];
+	__u8 clnt_uuid[TEE_IOCTL_UUID_LEN];
+	__u32 clnt_login;
+	__u32 cancel_id;
+	__u32 session;
+	__u32 ret;
+	__u32 ret_origin;
+	__u32 num_params;
+	/*
+	 * this struct is 8 byte aligned since the 'struct tee_ioctl_param'
+	 * which follows requires 8 byte alignment.
+	 *
+	 * Commented out element used to visualize the layout dynamic part
+	 * of the struct. This field is not available at all if
+	 * num_params == 0.
+	 *
+	 * struct tee_ioctl_param params[num_params];
+	 */
+} __aligned(8);
+
+/**
+ * TEE_IOC_OPEN_SESSION - opens a session to a Trusted Application
+ *
+ * Takes a struct tee_ioctl_buf_data which contains a struct
+ * tee_ioctl_open_session_arg followed by any array of struct
+ * tee_ioctl_param
+ */
+#define TEE_IOC_OPEN_SESSION	_IOR(TEE_IOC_MAGIC, TEE_IOC_BASE + 2, \
+				     struct tee_ioctl_buf_data)
+
+/**
+ * struct tee_invoke_func_arg - Invokes a function in a Trusted Application
+ * @func:	[in] Trusted Application function, specific to the TA
+ * @session:	[in] Session id
+ * @cancel_id:	[in] Cancellation id, a unique value to identify this request
+ * @ret:	[out] return value
+ * @ret_origin	[out] origin of the return value
+ * @num_params	[in] number of parameters following this struct
+ */
+struct tee_ioctl_invoke_arg {
+	__u32 func;
+	__u32 session;
+	__u32 cancel_id;
+	__u32 ret;
+	__u32 ret_origin;
+	__u32 num_params;
+	/*
+	 * this struct is 8 byte aligned since the 'struct tee_ioctl_param'
+	 * which follows requires 8 byte alignment.
+	 *
+	 * Commented out element used to visualize the layout dynamic part
+	 * of the struct. This field is not available at all if
+	 * num_params == 0.
+	 *
+	 * struct tee_ioctl_param params[num_params];
+	 */
+} __aligned(8);
+
+/**
+ * TEE_IOC_INVOKE - Invokes a function in a Trusted Application
+ *
+ * Takes a struct tee_ioctl_buf_data which contains a struct
+ * tee_invoke_func_arg followed by any array of struct tee_param
+ */
+#define TEE_IOC_INVOKE		_IOR(TEE_IOC_MAGIC, TEE_IOC_BASE + 3, \
+				     struct tee_ioctl_buf_data)
+
+/**
+ * struct tee_ioctl_cancel_arg - Cancels an open session or invoke ioctl
+ * @cancel_id:	[in] Cancellation id, a unique value to identify this request
+ * @session:	[in] Session id, if the session is opened, else set to 0
+ */
+struct tee_ioctl_cancel_arg {
+	__u32 cancel_id;
+	__u32 session;
+};
+/**
+ * TEE_IOC_CANCEL - Cancels an open session or invoke
+ */
+#define TEE_IOC_CANCEL		_IOR(TEE_IOC_MAGIC, TEE_IOC_BASE + 4, \
+				     struct tee_ioctl_cancel_arg)
+
+/**
+ * struct tee_ioctl_close_session_arg - Closes an open session
+ * @session:	[in] Session id
+ */
+struct tee_ioctl_close_session_arg {
+	__u32 session;
+};
+/**
+ * TEE_IOC_CLOSE_SESSION - Closes a session
+ */
+#define TEE_IOC_CLOSE_SESSION	_IOR(TEE_IOC_MAGIC, TEE_IOC_BASE + 5, \
+				     struct tee_ioctl_close_session_arg)
+
+/**
+ * struct tee_iocl_supp_recv_arg - Receive a request for a supplicant function
+ * @func:	[in] supplicant function
+ * @num_params	[in/out] number of parameters following this struct
+ *
+ * @num_params is the number of params that tee-supplicant has room to
+ * receive when input, @num_params is the number of actual params
+ * tee-supplicant receives when output.
+ */
+struct tee_iocl_supp_recv_arg {
+	__u32 func;
+	__u32 num_params;
+	/*
+	 * this struct is 8 byte aligned since the 'struct tee_ioctl_param'
+	 * which follows requires 8 byte alignment.
+	 *
+	 * Commented out element used to visualize the layout dynamic part
+	 * of the struct. This field is not available at all if
+	 * num_params == 0.
+	 *
+	 * struct tee_ioctl_param params[num_params];
+	 */
+} __aligned(8);
+/**
+ * TEE_IOC_SUPPL_RECV - Receive a request for a supplicant function
+ *
+ * Takes a struct tee_ioctl_buf_data which contains a struct
+ * tee_iocl_supp_recv_arg followed by any array of struct tee_param
+ */
+#define TEE_IOC_SUPPL_RECV	_IOR(TEE_IOC_MAGIC, TEE_IOC_BASE + 6, \
+				     struct tee_ioctl_buf_data)
+
+
+/**
+ * struct tee_iocl_supp_send_arg - Send a response to a received request
+ * @ret:	[out] return value
+ * @num_params	[in] number of parameters following this struct
+ */
+struct tee_iocl_supp_send_arg {
+	__u32 ret;
+	__u32 num_params;
+	/*
+	 * this struct is 8 byte aligned since the 'struct tee_ioctl_param'
+	 * which follows requires 8 byte alignment.
+	 *
+	 * Commented out element used to visualize the layout dynamic part
+	 * of the struct. This field is not available at all if
+	 * num_params == 0.
+	 *
+	 * struct tee_ioctl_param params[num_params];
+	 */
+} __aligned(8);
+/**
+ * TEE_IOC_SUPPL_SEND - Receive a request for a supplicant function
+ *
+ * Takes a struct tee_ioctl_buf_data which contains a struct
+ * tee_iocl_supp_send_arg followed by any array of struct tee_param
+ */
+#define TEE_IOC_SUPPL_SEND	_IOR(TEE_IOC_MAGIC, TEE_IOC_BASE + 7, \
+				     struct tee_ioctl_buf_data)
+
+
+/*
+ * Five syscalls are used when communicating with the TEE driver.
+ * open(): opens the device associated with the driver
+ * ioctl(): as described above operating on the file descriptor from open()
+ * close(): two cases
+ *   - closes the device file descriptor
+ *   - closes a file descriptor connected to allocated shared memory
+ * mmap(): maps shared memory into user space using information from struct
+ *	   tee_ioctl_shm_alloc_data
+ * munmap(): unmaps previously shared memory
+ */
+
+#endif /*__TEE_H*/
-- 
1.9.1



From jens.wiklander at linaro.org  Wed Aug 19 01:40:28 2015
From: jens.wiklander at linaro.org (Jens Wiklander)
Date: Wed, 19 Aug 2015 10:40:28 +0200
Subject: [PATCH v5 4/5] tee: add OP-TEE driver
In-Reply-To: <1439973629-19505-1-git-send-email-jens.wiklander@linaro.org>
References: <1439973629-19505-1-git-send-email-jens.wiklander@linaro.org>
Message-ID: <1439973629-19505-5-git-send-email-jens.wiklander@linaro.org>

Adds a OP-TEE driver which also can be compiled as a loadable module.

* Targets ARM and ARM64
* Supports using reserved memory from OP-TEE as shared memory
* Probes OP-TEE version using SMCs
* Accepts requests on privileged and unprivileged device
* Uses OPTEE message protocol version 2 to communicate with secure world

Signed-off-by: Jens Wiklander <jens.wiklander at linaro.org>
---
 MAINTAINERS                       |   5 +
 drivers/tee/Kconfig               |  10 +
 drivers/tee/Makefile              |   1 +
 drivers/tee/optee/Kconfig         |   8 +
 drivers/tee/optee/Makefile        |   5 +
 drivers/tee/optee/call.c          | 390 +++++++++++++++++++++++++++++++
 drivers/tee/optee/core.c          | 453 ++++++++++++++++++++++++++++++++++++
 drivers/tee/optee/optee_msg.h     | 334 +++++++++++++++++++++++++++
 drivers/tee/optee/optee_private.h | 129 +++++++++++
 drivers/tee/optee/optee_smc.h     | 466 ++++++++++++++++++++++++++++++++++++++
 drivers/tee/optee/rpc.c           | 248 ++++++++++++++++++++
 drivers/tee/optee/supp.c          | 212 +++++++++++++++++
 12 files changed, 2261 insertions(+)
 create mode 100644 drivers/tee/optee/Kconfig
 create mode 100644 drivers/tee/optee/Makefile
 create mode 100644 drivers/tee/optee/call.c
 create mode 100644 drivers/tee/optee/core.c
 create mode 100644 drivers/tee/optee/optee_msg.h
 create mode 100644 drivers/tee/optee/optee_private.h
 create mode 100644 drivers/tee/optee/optee_smc.h
 create mode 100644 drivers/tee/optee/rpc.c
 create mode 100644 drivers/tee/optee/supp.c

diff --git a/MAINTAINERS b/MAINTAINERS
index 869635f..2df3f03 100644
--- a/MAINTAINERS
+++ b/MAINTAINERS
@@ -7314,6 +7314,11 @@ F:	arch/*/oprofile/
 F:	drivers/oprofile/
 F:	include/linux/oprofile.h
 
+OP-TEE DRIVER
+M:	Jens Wiklander <jens.wiklander at linaro.org>
+S:	Maintained
+F:	drivers/tee/optee/
+
 ORACLE CLUSTER FILESYSTEM 2 (OCFS2)
 M:	Mark Fasheh <mfasheh at suse.com>
 M:	Joel Becker <jlbec at evilplan.org>
diff --git a/drivers/tee/Kconfig b/drivers/tee/Kconfig
index 64a8cd7..b269276 100644
--- a/drivers/tee/Kconfig
+++ b/drivers/tee/Kconfig
@@ -6,3 +6,13 @@ config TEE
 	help
 	  This implements a generic interface towards a Trusted Execution
 	  Environment (TEE).
+
+if TEE
+
+menu "TEE drivers"
+
+source "drivers/tee/optee/Kconfig"
+
+endmenu
+
+endif
diff --git a/drivers/tee/Makefile b/drivers/tee/Makefile
index 60d2dab..53f3c76 100644
--- a/drivers/tee/Makefile
+++ b/drivers/tee/Makefile
@@ -1,3 +1,4 @@
 obj-y += tee.o
 obj-y += tee_shm.o
 obj-y += tee_shm_pool.o
+obj-$(CONFIG_OPTEE) += optee/
diff --git a/drivers/tee/optee/Kconfig b/drivers/tee/optee/Kconfig
new file mode 100644
index 0000000..b550b18
--- /dev/null
+++ b/drivers/tee/optee/Kconfig
@@ -0,0 +1,8 @@
+# OP-TEE Trusted Execution Environment Configuration
+config OPTEE
+	tristate "OP-TEE"
+	default n
+	depends on HAVE_SMCCC
+	help
+	  This implements the OP-TEE Trusted Execution Environment (TEE)
+	  driver.
diff --git a/drivers/tee/optee/Makefile b/drivers/tee/optee/Makefile
new file mode 100644
index 0000000..92fe578
--- /dev/null
+++ b/drivers/tee/optee/Makefile
@@ -0,0 +1,5 @@
+obj-$(CONFIG_OPTEE) += optee.o
+optee-objs += core.o
+optee-objs += call.o
+optee-objs += rpc.o
+optee-objs += supp.o
diff --git a/drivers/tee/optee/call.c b/drivers/tee/optee/call.c
new file mode 100644
index 0000000..ed07b65
--- /dev/null
+++ b/drivers/tee/optee/call.c
@@ -0,0 +1,390 @@
+/*
+ * Copyright (c) 2015, Linaro Limited
+ *
+ * This software is licensed under the terms of the GNU General Public
+ * License version 2, as published by the Free Software Foundation, and
+ * may be copied, distributed, and modified under those terms.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ * GNU General Public License for more details.
+ *
+ */
+#include <linux/types.h>
+#include <linux/err.h>
+#include <linux/errno.h>
+#include <linux/slab.h>
+#include <linux/uaccess.h>
+#include <linux/device.h>
+#include <linux/tee_drv.h>
+#include <linux/arm-smccc.h>
+#include "optee_private.h"
+#include "optee_smc.h"
+
+struct optee_call_waiter {
+	struct list_head list_node;
+	struct completion c;
+	bool completed;
+};
+
+static void optee_cq_wait_init(struct optee_call_queue *cq,
+			struct optee_call_waiter *w)
+{
+	mutex_lock(&cq->mutex);
+	/*
+	 * We add ourselves to the queue, but we don't wait. This
+	 * guarentees that we don't lose a completion if secure world
+	 * returns busy and another thread just exited and try to complete
+	 * someone.
+	 */
+	w->completed = false;
+	init_completion(&w->c);
+	list_add_tail(&w->list_node, &cq->waiters);
+	mutex_unlock(&cq->mutex);
+}
+
+static void optee_cq_wait_for_completion(struct optee_call_queue *cq,
+			struct optee_call_waiter *w)
+{
+	wait_for_completion(&w->c);
+
+	mutex_lock(&cq->mutex);
+
+	/* Move to end of list to get out of the way for other waiters */
+	list_del(&w->list_node);
+	w->completed = false;
+	reinit_completion(&w->c);
+	list_add_tail(&w->list_node, &cq->waiters);
+
+	mutex_unlock(&cq->mutex);
+}
+
+static void optee_cq_complete_one(struct optee_call_queue *cq)
+{
+	struct optee_call_waiter *w;
+
+	list_for_each_entry(w, &cq->waiters, list_node) {
+		if (!w->completed) {
+			complete(&w->c);
+			w->completed = true;
+			break;
+		}
+	}
+}
+
+static void optee_cq_wait_final(struct optee_call_queue *cq,
+			struct optee_call_waiter *w)
+{
+	mutex_lock(&cq->mutex);
+
+	/* Get out of the list */
+	list_del(&w->list_node);
+
+	optee_cq_complete_one(cq);
+	/*
+	 * If we're completed we've got a completion that some other task
+	 * could have used instead.
+	 */
+	if (w->completed)
+		optee_cq_complete_one(cq);
+
+	mutex_unlock(&cq->mutex);
+}
+
+/* Requires the filpstate mutex to be held */
+static struct optee_session *find_session(struct optee_context_data *ctxdata,
+			u32 session_id)
+{
+	struct optee_session *sess;
+
+	list_for_each_entry(sess, &ctxdata->sess_list, list_node)
+		if (sess->session_id == session_id)
+			return sess;
+	return NULL;
+}
+
+u32 optee_do_call_with_arg(struct tee_context *ctx, phys_addr_t parg)
+{
+	struct optee *optee = tee_get_drvdata(ctx->teedev);
+	struct optee_call_waiter w;
+	struct smccc_param32 param = { };
+	u32 ret;
+	u32 cmdid = OPTEE_SMC_CALL_WITH_ARG;
+
+	reg_pair_from_64(&param.a1, &param.a2, parg);
+	/* Initialize waiter */
+	optee_cq_wait_init(&optee->call_queue, &w);
+	while (true) {
+		param.a0 = cmdid;
+
+		smccc_call32(&param);
+		ret = param.a0;
+
+		if (ret == OPTEE_SMC_RETURN_ETHREAD_LIMIT) {
+			/*
+			 * Out of threads in secure world, wait for a thread
+			 * become available.
+			 */
+			optee_cq_wait_for_completion(&optee->call_queue, &w);
+		} else if (OPTEE_SMC_RETURN_IS_RPC(ret))
+			cmdid = optee_handle_rpc(ctx, &param);
+		else
+			break;
+	}
+	/*
+	 * We're done with our thread in secure world, if there's any
+	 * thread waiters wake up one.
+	 */
+	optee_cq_wait_final(&optee->call_queue, &w);
+	return ret;
+}
+
+static struct tee_shm *get_msg_arg(struct tee_context *ctx, size_t num_params,
+			struct optee_msg_arg **msg_arg, phys_addr_t *msg_parg)
+{
+	int rc;
+	struct tee_shm *shm;
+	struct optee_msg_arg *ma;
+
+	shm = tee_shm_alloc(ctx->teedev, OPTEE_MSG_GET_ARG_SIZE(num_params),
+			    TEE_SHM_MAPPED);
+	if (IS_ERR(shm))
+		return shm;
+	ma = tee_shm_get_va(shm, 0);
+	if (IS_ERR(ma)) {
+		rc = PTR_ERR(ma);
+		goto out;
+	}
+	rc = tee_shm_get_pa(shm, 0, msg_parg);
+	if (rc)
+		goto out;
+
+	memset(ma, 0, OPTEE_MSG_GET_ARG_SIZE(num_params));
+	ma->num_params = num_params;
+	*msg_arg = ma;
+out:
+	if (rc) {
+		tee_shm_free(shm);
+		return ERR_PTR(rc);
+	}
+	return shm;
+}
+
+int optee_open_session(struct tee_context *ctx,
+			struct tee_ioctl_open_session_arg *arg,
+			struct tee_param *param)
+{
+	struct optee_context_data *ctxdata = ctx->data;
+	int rc;
+	struct tee_shm *shm;
+	struct optee_msg_arg *msg_arg;
+	phys_addr_t msg_parg;
+	struct optee_msg_param *msg_param;
+	struct optee_session *sess = NULL;
+
+	/* +2 for the meta parameters added below */
+	shm = get_msg_arg(ctx, arg->num_params + 2, &msg_arg, &msg_parg);
+	if (IS_ERR(shm))
+		return PTR_ERR(shm);
+
+	msg_arg->cmd = OPTEE_MSG_CMD_OPEN_SESSION;
+	msg_param = OPTEE_MSG_GET_PARAMS(msg_arg);
+
+	/*
+	 * Initialize and add the meta parameters needed when opening a
+	 * session.
+	 */
+	msg_param[0].attr = OPTEE_MSG_ATTR_TYPE_VALUE_INPUT |
+			    OPTEE_MSG_ATTR_META;
+	msg_param[1].attr = OPTEE_MSG_ATTR_TYPE_VALUE_INPUT |
+			    OPTEE_MSG_ATTR_META;
+	memcpy(&msg_param[0].u.value, arg->uuid, sizeof(arg->uuid));
+	memcpy(&msg_param[1].u.value, arg->uuid, sizeof(arg->clnt_uuid));
+	msg_param[1].u.value.c = arg->clnt_login;
+
+	rc = optee_to_msg_param(msg_param + 2, arg->num_params, param);
+	if (rc)
+		goto out;
+
+	sess = kzalloc(sizeof(struct optee_session), GFP_KERNEL);
+	if (!sess) {
+		rc = -ENOMEM;
+		goto out;
+	}
+
+	if (optee_do_call_with_arg(ctx, msg_parg)) {
+		msg_arg->ret = TEEC_ERROR_COMMUNICATION;
+		msg_arg->ret_origin = TEEC_ORIGIN_COMMS;
+	}
+
+	if (msg_arg->ret == TEEC_SUCCESS) {
+		/* A new session has been created, add it to the list. */
+		sess->session_id = msg_arg->session;
+		mutex_lock(&ctxdata->mutex);
+		list_add(&sess->list_node, &ctxdata->sess_list);
+		mutex_unlock(&ctxdata->mutex);
+		sess = NULL;
+	}
+
+	if (optee_from_msg_param(param, arg->num_params, msg_param + 2)) {
+		arg->ret = TEEC_ERROR_COMMUNICATION;
+		arg->ret_origin = TEEC_ORIGIN_COMMS;
+		/* Close session again to avoid leakage */
+		optee_close_session(ctx, msg_arg->session);
+	} else {
+		arg->session = msg_arg->session;
+		arg->ret = msg_arg->ret;
+		arg->ret_origin = msg_arg->ret_origin;
+	}
+out:
+	kfree(sess);
+	tee_shm_free(shm);
+	return rc;
+}
+
+int optee_close_session(struct tee_context *ctx, u32 session)
+{
+	struct optee_context_data *ctxdata = ctx->data;
+	struct tee_shm *shm;
+	struct optee_msg_arg *msg_arg;
+	phys_addr_t msg_parg;
+	struct optee_session *sess;
+
+	/* Check that the session is valid and remove it from the list */
+	mutex_lock(&ctxdata->mutex);
+	sess = find_session(ctxdata, session);
+	if (sess)
+		list_del(&sess->list_node);
+	mutex_unlock(&ctxdata->mutex);
+	if (!sess)
+		return -EINVAL;
+	kfree(sess);
+
+	shm = get_msg_arg(ctx, 0, &msg_arg, &msg_parg);
+	if (IS_ERR(shm))
+		return PTR_ERR(shm);
+
+	msg_arg->cmd = OPTEE_MSG_CMD_CLOSE_SESSION;
+	msg_arg->session = session;
+	optee_do_call_with_arg(ctx, msg_parg);
+
+	tee_shm_free(shm);
+	return 0;
+}
+
+int optee_invoke_func(struct tee_context *ctx, struct tee_ioctl_invoke_arg *arg,
+			struct tee_param *param)
+{
+	struct optee_context_data *ctxdata = ctx->data;
+	int rc;
+	struct tee_shm *shm;
+	struct optee_msg_arg *msg_arg;
+	phys_addr_t msg_parg;
+	struct optee_msg_param *msg_param;
+	struct optee_session *sess;
+
+	/* Check that the session is valid */
+	mutex_lock(&ctxdata->mutex);
+	sess = find_session(ctxdata, arg->session);
+	mutex_unlock(&ctxdata->mutex);
+	if (!sess)
+		return -EINVAL;
+
+	shm = get_msg_arg(ctx, arg->num_params, &msg_arg, &msg_parg);
+	if (IS_ERR(shm))
+		return PTR_ERR(shm);
+	msg_arg->cmd = OPTEE_MSG_CMD_INVOKE_COMMAND;
+	msg_arg->func = arg->func;
+	msg_arg->session = arg->session;
+	msg_param = OPTEE_MSG_GET_PARAMS(msg_arg);
+
+	rc = optee_to_msg_param(msg_param, arg->num_params, param);
+	if (rc)
+		goto out;
+
+	if (optee_do_call_with_arg(ctx, msg_parg)) {
+		msg_arg->ret = TEEC_ERROR_COMMUNICATION;
+		msg_arg->ret_origin = TEEC_ORIGIN_COMMS;
+	}
+
+	if (optee_from_msg_param(param, arg->num_params, msg_param)) {
+		msg_arg->ret = TEEC_ERROR_COMMUNICATION;
+		msg_arg->ret_origin = TEEC_ORIGIN_COMMS;
+	}
+
+	arg->ret = msg_arg->ret;
+	arg->ret_origin = msg_arg->ret_origin;
+out:
+	tee_shm_free(shm);
+	return rc;
+}
+
+int optee_cancel_req(struct tee_context *ctx, u32 cancel_id, u32 session)
+{
+	struct optee_context_data *ctxdata = ctx->data;
+	struct tee_shm *shm;
+	struct optee_msg_arg *msg_arg;
+	phys_addr_t msg_parg;
+	struct optee_session *sess;
+
+	/* Check that the session is valid */
+	mutex_lock(&ctxdata->mutex);
+	sess = find_session(ctxdata, session);
+	mutex_unlock(&ctxdata->mutex);
+	if (!sess)
+		return -EINVAL;
+
+	shm = get_msg_arg(ctx, 0, &msg_arg, &msg_parg);
+	if (IS_ERR(shm))
+		return PTR_ERR(shm);
+
+	msg_arg->cmd = OPTEE_MSG_CMD_CANCEL;
+	msg_arg->session = session;
+	optee_do_call_with_arg(ctx, msg_parg);
+
+	tee_shm_free(shm);
+	return 0;
+}
+
+void optee_enable_shm_cache(struct optee *optee)
+{
+	struct smccc_param32 param = { };
+	struct optee_call_waiter w;
+
+	/* We need to retry until secure world isn't busy. */
+	optee_cq_wait_init(&optee->call_queue, &w);
+	while (true) {
+		param.a0 = OPTEE_SMC_ENABLE_SHM_CACHE;
+
+		smccc_call32(&param);
+		if (param.a0 == OPTEE_SMC_RETURN_OK)
+			break;
+		optee_cq_wait_for_completion(&optee->call_queue, &w);
+	}
+	optee_cq_wait_final(&optee->call_queue, &w);
+}
+
+void optee_disable_shm_cache(struct optee *optee)
+{
+	struct smccc_param32 param = { };
+	struct optee_call_waiter w;
+
+	/* We need to retry until secure world isn't busy. */
+	optee_cq_wait_init(&optee->call_queue, &w);
+	while (true) {
+		param.a0 = OPTEE_SMC_DISABLE_SHM_CACHE;
+
+		smccc_call32(&param);
+		if (param.a0 == OPTEE_SMC_RETURN_ENOTAVAIL)
+			break; /* All shm's freed */
+		if (param.a0 == OPTEE_SMC_RETURN_OK) {
+			struct tee_shm *shm;
+
+			shm = reg_pair_to_ptr(param.a1, param.a2);
+			tee_shm_free(shm);
+		} else
+			optee_cq_wait_for_completion(&optee->call_queue, &w);
+	}
+	optee_cq_wait_final(&optee->call_queue, &w);
+}
diff --git a/drivers/tee/optee/core.c b/drivers/tee/optee/core.c
new file mode 100644
index 0000000..26b9427
--- /dev/null
+++ b/drivers/tee/optee/core.c
@@ -0,0 +1,453 @@
+/*
+ * Copyright (c) 2015, Linaro Limited
+ *
+ * This software is licensed under the terms of the GNU General Public
+ * License version 2, as published by the Free Software Foundation, and
+ * may be copied, distributed, and modified under those terms.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ * GNU General Public License for more details.
+ *
+ */
+#include <linux/types.h>
+#include <linux/string.h>
+#include <linux/errno.h>
+#include <linux/module.h>
+#include <linux/platform_device.h>
+#include <linux/slab.h>
+#include <linux/uaccess.h>
+#include <linux/io.h>
+#include <linux/tee_drv.h>
+#include "optee_private.h"
+#include "optee_smc.h"
+
+#define DRIVER_NAME "optee"
+
+#define OPTEE_SHM_NUM_PRIV_PAGES	1
+
+int optee_from_msg_param(struct tee_param *params, size_t num_params,
+			const struct optee_msg_param *msg_params)
+{
+	int rc;
+	size_t n;
+	struct tee_shm *shm;
+	phys_addr_t pa;
+
+	for (n = 0; n < num_params; n++) {
+		struct tee_param *p = params + n;
+		const struct optee_msg_param *mp = msg_params + n;
+
+		p->attr = mp->attr;
+		switch (mp->attr & OPTEE_MSG_ATTR_TYPE_MASK) {
+		case OPTEE_MSG_ATTR_TYPE_VALUE_INPUT:
+		case OPTEE_MSG_ATTR_TYPE_VALUE_OUTPUT:
+		case OPTEE_MSG_ATTR_TYPE_VALUE_INOUT:
+			p->u.value.a = mp->u.value.a;
+			p->u.value.b = mp->u.value.b;
+			p->u.value.c = mp->u.value.c;
+			break;
+		case OPTEE_MSG_ATTR_TYPE_MEMREF_INPUT:
+		case OPTEE_MSG_ATTR_TYPE_MEMREF_OUTPUT:
+		case OPTEE_MSG_ATTR_TYPE_MEMREF_INOUT:
+			p->u.memref.size = mp->u.memref.size;
+			shm = (struct tee_shm *)(unsigned long)
+				mp->u.memref.shm_ref;
+			if (!shm) {
+				p->u.memref.shm_offs = 0;
+				p->u.memref.shm = NULL;
+				break;
+			}
+			rc = tee_shm_get_pa(shm, 0, &pa);
+			if (rc)
+				return rc;
+			p->u.memref.shm_offs = pa - mp->u.memref.buf_ptr;
+			p->u.memref.shm = shm;
+
+			/* Check that the memref is covered by the shm object */
+			if (p->u.memref.size) {
+				size_t o = p->u.memref.shm_offs +
+					   p->u.memref.size - 1;
+
+				rc = tee_shm_get_pa(shm, o, NULL);
+				if (rc)
+					return rc;
+			}
+			break;
+		default:
+			memset(&p->u, 0, sizeof(p->u));
+		}
+	}
+	return 0;
+}
+
+int optee_to_msg_param(struct optee_msg_param *msg_params, size_t num_params,
+			const struct tee_param *params)
+{
+	int rc;
+	size_t n;
+	phys_addr_t pa;
+
+	for (n = 0; n < num_params; n++) {
+		const struct tee_param *p = params + n;
+		struct optee_msg_param *mp = msg_params + n;
+
+		mp->attr = p->attr;
+		switch (p->attr & OPTEE_MSG_ATTR_TYPE_MASK) {
+		case OPTEE_MSG_ATTR_TYPE_VALUE_INPUT:
+		case OPTEE_MSG_ATTR_TYPE_VALUE_OUTPUT:
+		case OPTEE_MSG_ATTR_TYPE_VALUE_INOUT:
+			mp->u.value.a = p->u.value.a;
+			mp->u.value.b = p->u.value.b;
+			mp->u.value.c = p->u.value.c;
+			break;
+		case OPTEE_MSG_ATTR_TYPE_MEMREF_INPUT:
+		case OPTEE_MSG_ATTR_TYPE_MEMREF_OUTPUT:
+		case OPTEE_MSG_ATTR_TYPE_MEMREF_INOUT:
+			mp->u.memref.shm_ref = (unsigned long)p->u.memref.shm;
+			mp->u.memref.size = p->u.memref.size;
+			if (!p->u.memref.shm) {
+				mp->u.memref.buf_ptr = 0;
+				break;
+			}
+			rc = tee_shm_get_pa(p->u.memref.shm,
+					    p->u.memref.shm_offs, &pa);
+			if (rc)
+				return rc;
+			mp->u.memref.buf_ptr = pa;
+			mp->attr |= OPTEE_MSG_ATTR_CACHE_PREDEFINED <<
+					OPTEE_MSG_ATTR_CACHE_SHIFT;
+			break;
+		default:
+			memset(&mp->u, 0, sizeof(mp->u));
+		}
+	}
+	return 0;
+}
+
+static void optee_get_version(struct tee_context *ctx,
+			struct tee_ioctl_version_data *vers)
+{
+	struct tee_ioctl_version_data v = {
+		.impl_id = TEE_IMPL_ID_OPTEE,
+		.impl_caps = TEE_OPTEE_CAP_TZ,
+		.gen_caps = TEE_GEN_CAP_GP,
+	};
+	*vers = v;
+}
+
+static int optee_open(struct tee_context *ctx)
+{
+	struct optee_context_data *ctxdata;
+
+	ctxdata = kzalloc(sizeof(*ctxdata), GFP_KERNEL);
+	if (!ctxdata)
+		return -ENOMEM;
+
+	mutex_init(&ctxdata->mutex);
+	INIT_LIST_HEAD(&ctxdata->sess_list);
+
+	ctx->data = ctxdata;
+	return 0;
+}
+
+static void optee_release(struct tee_context *ctx)
+{
+	struct optee_context_data *ctxdata = ctx->data;
+	struct tee_shm *shm;
+	struct optee_msg_arg *arg = NULL;
+	phys_addr_t parg;
+
+	if (!ctxdata)
+		return;
+
+	shm = tee_shm_alloc(ctx->teedev, sizeof(struct optee_msg_arg),
+			    TEE_SHM_MAPPED);
+	if (!IS_ERR(shm)) {
+		arg = tee_shm_get_va(shm, 0);
+		/*
+		 * If va2pa fails for some reason, we can't call
+		 * optee_close_session(), only free the memory. Secure OS
+		 * will leak sessions and finally refuse more session, but
+		 * we will at least let normal world reclaim its memory.
+		 */
+		if (!IS_ERR(arg))
+			tee_shm_va2pa(shm, arg, &parg);
+	}
+
+	while (true) {
+		struct optee_session *sess;
+
+		sess = list_first_entry_or_null(&ctxdata->sess_list,
+						struct optee_session,
+						list_node);
+		if (!sess)
+			break;
+		list_del(&sess->list_node);
+		if (!IS_ERR_OR_NULL(arg)) {
+			memset(arg, 0, sizeof(*arg));
+			arg->cmd = OPTEE_MSG_CMD_CLOSE_SESSION;
+			arg->session = sess->session_id;
+			optee_do_call_with_arg(ctx, parg);
+		}
+		kfree(sess);
+	}
+	kfree(ctxdata);
+
+	if (!IS_ERR(shm))
+		tee_shm_free(shm);
+
+	ctx->data = NULL;
+}
+
+static struct tee_driver_ops optee_ops = {
+	.get_version = optee_get_version,
+	.open = optee_open,
+	.release = optee_release,
+	.open_session = optee_open_session,
+	.close_session = optee_close_session,
+	.invoke_func = optee_invoke_func,
+	.cancel_req = optee_cancel_req,
+};
+
+static struct tee_desc optee_desc = {
+	.name = DRIVER_NAME "-clnt",
+	.ops = &optee_ops,
+	.owner = THIS_MODULE,
+};
+
+static struct tee_driver_ops optee_supp_ops = {
+	.get_version = optee_get_version,
+	.open = optee_open,
+	.release = optee_release,
+	.supp_recv = optee_supp_recv,
+	.supp_send = optee_supp_send,
+};
+
+static struct tee_desc optee_supp_desc = {
+	.name = DRIVER_NAME "-supp",
+	.ops = &optee_supp_ops,
+	.owner = THIS_MODULE,
+	.flags = TEE_DESC_PRIVILEGED,
+};
+
+static bool optee_msg_api_uid_is_optee_api(void)
+{
+	struct smccc_param32 param = { .a0 = OPTEE_SMC_CALLS_UID };
+
+	smccc_call32(&param);
+
+	if (param.a0 == OPTEE_MSG_UID_0 && param.a1 == OPTEE_MSG_UID_1 &&
+	    param.a2 == OPTEE_MSG_UID_2 && param.a3 == OPTEE_MSG_UID_3)
+		return true;
+	return false;
+}
+
+static bool optee_msg_api_revision_is_compatible(void)
+{
+	struct smccc_param32 param = { .a0 = OPTEE_SMC_CALLS_REVISION };
+
+	smccc_call32(&param);
+
+	if (param.a0 == OPTEE_MSG_REVISION_MAJOR &&
+	    (int)param.a1 >= OPTEE_MSG_REVISION_MINOR)
+		return true;
+	return false;
+}
+
+static bool optee_msg_exchange_capabilities(u32 *sec_caps)
+{
+	struct smccc_param32 param = { .a0 = OPTEE_SMC_EXCHANGE_CAPABILITIES };
+
+	/*
+	 * TODO This isn't enough to tell if it's UP system (from kernel
+	 * point of view) or not, is_smp() returns the the information
+	 * needed, but can't be called directly from here.
+	 */
+#ifndef CONFIG_SMP
+	param.a1 |= OPTEE_SMC_NSEC_CAP_UNIPROCESSOR;
+#endif
+
+	smccc_call32(&param);
+
+	if (param.a0 != OPTEE_SMC_RETURN_OK)
+		return false;
+
+	*sec_caps = param.a1;
+	return true;
+}
+
+static struct tee_shm_pool *optee_config_shm_ioremap(struct device *dev,
+			void __iomem **ioremaped_shm)
+{
+	struct smccc_param32 param = { .a0 = OPTEE_SMC_GET_SHM_CONFIG };
+	struct tee_shm_pool *pool;
+	unsigned long vaddr;
+	phys_addr_t paddr;
+	size_t size;
+	phys_addr_t begin;
+	phys_addr_t end;
+	void __iomem *va;
+	struct tee_shm_pool_mem_info priv_info;
+	struct tee_shm_pool_mem_info dmabuf_info;
+
+	smccc_call32(&param);
+	if (param.a0 != OPTEE_SMC_RETURN_OK) {
+		dev_info(dev, "shm service not available\n");
+		return ERR_PTR(-ENOENT);
+	}
+
+	if (param.a3 != OPTEE_SMC_SHM_CACHED) {
+		dev_err(dev, "only normal cached shared memory supported\n");
+		return ERR_PTR(-EINVAL);
+	}
+
+	begin = roundup(param.a1, PAGE_SIZE);
+	end = rounddown(param.a1 + param.a2, PAGE_SIZE);
+	paddr = begin;
+	size = end - begin;
+
+	if (size < 2 * OPTEE_SHM_NUM_PRIV_PAGES * PAGE_SIZE) {
+		dev_err(dev, "too small shared memory area\n");
+		return ERR_PTR(-EINVAL);
+	}
+
+	va = ioremap_cache(paddr, size);
+	if (!va) {
+		dev_err(dev, "shared memory ioremap failed\n");
+		return ERR_PTR(-EINVAL);
+	}
+	vaddr = (unsigned long)va;
+
+	priv_info.vaddr = vaddr;
+	priv_info.paddr = paddr;
+	priv_info.size = OPTEE_SHM_NUM_PRIV_PAGES * PAGE_SIZE;
+	dmabuf_info.vaddr = vaddr + OPTEE_SHM_NUM_PRIV_PAGES * PAGE_SIZE;
+	dmabuf_info.paddr = paddr + OPTEE_SHM_NUM_PRIV_PAGES * PAGE_SIZE;
+	dmabuf_info.size = size - OPTEE_SHM_NUM_PRIV_PAGES * PAGE_SIZE;
+
+	pool = tee_shm_pool_alloc_res_mem(dev, &priv_info, &dmabuf_info);
+	if (IS_ERR(pool))
+		iounmap(va);
+	else
+		*ioremaped_shm = va;
+	return pool;
+}
+
+static int optee_probe(struct platform_device *pdev)
+{
+	struct tee_shm_pool *pool;
+	struct optee *optee = NULL;
+	void __iomem *ioremaped_shm = NULL;
+	struct tee_device *teedev;
+	u32 sec_caps;
+	int rc;
+
+	if (!optee_msg_api_uid_is_optee_api() ||
+	    !optee_msg_api_revision_is_compatible() ||
+	    !optee_msg_exchange_capabilities(&sec_caps))
+		return -EINVAL;
+
+	/*
+	 * We have no other option for shared memory, if secure world
+	 * doesn't have any reserved memory we can use we can't continue.
+	 */
+	if (!(sec_caps & OPTEE_SMC_SEC_CAP_HAVE_RESERVERED_SHM))
+		return -EINVAL;
+
+	pool = optee_config_shm_ioremap(&pdev->dev, &ioremaped_shm);
+	if (IS_ERR(pool))
+		return PTR_ERR(pool);
+
+	optee = devm_kzalloc(&pdev->dev, sizeof(*optee), GFP_KERNEL);
+	if (!optee) {
+		rc = -ENOMEM;
+		goto err;
+	}
+
+	optee->dev = &pdev->dev;
+
+	teedev = tee_device_alloc(&optee_desc, &pdev->dev, pool, optee);
+	if (IS_ERR(teedev)) {
+		rc = PTR_ERR(teedev);
+		goto err;
+	}
+	optee->teedev = teedev;
+
+	teedev = tee_device_alloc(&optee_supp_desc, &pdev->dev, pool, optee);
+	if (IS_ERR(teedev)) {
+		rc = PTR_ERR(teedev);
+		goto err;
+	}
+	optee->supp_teedev = teedev;
+
+	rc = tee_device_register(optee->teedev);
+	if (rc)
+		goto err;
+
+	rc = tee_device_register(optee->supp_teedev);
+	if (rc)
+		goto err;
+
+	mutex_init(&optee->call_queue.mutex);
+	INIT_LIST_HEAD(&optee->call_queue.waiters);
+	optee_wait_queue_init(&optee->wait_queue);
+	optee_supp_init(&optee->supp);
+	optee->ioremaped_shm = ioremaped_shm;
+	optee->pool = pool;
+
+	platform_set_drvdata(pdev, optee);
+
+	optee_enable_shm_cache(optee);
+
+	dev_info(&pdev->dev, "initialized driver\n");
+	return 0;
+err:
+	tee_device_unregister(optee->teedev);
+	tee_device_unregister(optee->supp_teedev);
+	if (pool)
+		tee_shm_pool_free(pool);
+	if (ioremaped_shm)
+		iounmap(optee->ioremaped_shm);
+	return rc;
+}
+
+static int optee_remove(struct platform_device *pdev)
+{
+	struct optee *optee = platform_get_drvdata(pdev);
+
+	optee_disable_shm_cache(optee);
+
+	tee_device_unregister(optee->teedev);
+	tee_device_unregister(optee->supp_teedev);
+	tee_shm_pool_free(optee->pool);
+	if (optee->ioremaped_shm)
+		iounmap(optee->ioremaped_shm);
+	optee_wait_queue_exit(&optee->wait_queue);
+	optee_supp_uninit(&optee->supp);
+	mutex_destroy(&optee->call_queue.mutex);
+	return 0;
+}
+
+static const struct of_device_id optee_match[] = {
+	{ .compatible = "optee,optee-tz" },
+	{},
+};
+
+static struct platform_driver optee_driver = {
+	.driver = {
+		.name = DRIVER_NAME,
+		.of_match_table = optee_match,
+	},
+	.probe = optee_probe,
+	.remove = optee_remove,
+};
+
+module_platform_driver(optee_driver);
+
+MODULE_AUTHOR("Linaro");
+MODULE_DESCRIPTION("OP-TEE driver");
+MODULE_SUPPORTED_DEVICE("");
+MODULE_VERSION("1.0");
+MODULE_LICENSE("GPL v2");
diff --git a/drivers/tee/optee/optee_msg.h b/drivers/tee/optee/optee_msg.h
new file mode 100644
index 0000000..c850ed1
--- /dev/null
+++ b/drivers/tee/optee/optee_msg.h
@@ -0,0 +1,334 @@
+/*
+ * Copyright (c) 2015, Linaro Limited
+ * All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions are met:
+ *
+ * 1. Redistributions of source code must retain the above copyright notice,
+ * this list of conditions and the following disclaimer.
+ *
+ * 2. Redistributions in binary form must reproduce the above copyright notice,
+ * this list of conditions and the following disclaimer in the documentation
+ * and/or other materials provided with the distribution.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
+ * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ * ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE
+ * LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
+ * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
+ * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
+ * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
+ * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
+ * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
+ * POSSIBILITY OF SUCH DAMAGE.
+ */
+#ifndef _OPTEE_MSG_H
+#define _OPTEE_MSG_H
+
+#include <linux/types.h>
+
+/*
+ * This file defines the OP-TEE message protocol used to communicate
+ * with an instance of OP-TEE running in secure world.
+ *
+ * This file is divided into three sections.
+ * 1. Formatting of messages.
+ * 2. Requests from normal world
+ * 3. Requests from secure world, Remote Procedure Call (RPC), handled by
+ *    tee-supplicant.
+ */
+
+/*****************************************************************************
+ * Part 1 - formatting of messages
+ *****************************************************************************/
+
+/*
+ * Same values as TEE_PARAM_* from TEE Internal API
+ */
+#define OPTEE_MSG_ATTR_TYPE_NONE		0
+#define OPTEE_MSG_ATTR_TYPE_VALUE_INPUT		1
+#define OPTEE_MSG_ATTR_TYPE_VALUE_OUTPUT	2
+#define OPTEE_MSG_ATTR_TYPE_VALUE_INOUT		3
+#define OPTEE_MSG_ATTR_TYPE_MEMREF_INPUT	5
+#define OPTEE_MSG_ATTR_TYPE_MEMREF_OUTPUT	6
+#define OPTEE_MSG_ATTR_TYPE_MEMREF_INOUT	7
+
+#define OPTEE_MSG_ATTR_TYPE_MASK		0xff
+
+/*
+ * Meta parameter to be absorbed by the Secure OS and not passed
+ * to the Trusted Application.
+ *
+ * Currently only used with OPTEE_MSG_CMD_OPEN_SESSION.
+ */
+#define OPTEE_MSG_ATTR_META			(1 << 8)
+
+/*
+ * Memory attributes for caching passed with memrefs. The actual value
+ * used is defined outside the message protocol with the exception
+ * of OPTEE_MSG_ATTR_CACHE_PREDEFINED which means the attributes already
+ * defined for the memory range should be used.
+ */
+#define OPTEE_MSG_ATTR_CACHE_SHIFT		4
+#define OPTEE_MSG_ATTR_CACHE_MASK		0x7
+#define OPTEE_MSG_ATTR_CACHE_PREDEFINED		0
+
+/*
+ * Same values as TEE_LOGIN_* from TEE Internal API
+ */
+#define OPTEE_MSG_LOGIN_PUBLIC			0x00000000
+#define OPTEE_MSG_LOGIN_USER			0x00000001
+#define OPTEE_MSG_LOGIN_GROUP			0x00000002
+#define OPTEE_MSG_LOGIN_APPLICATION		0x00000004
+#define OPTEE_MSG_LOGIN_APPLICATION_USER	0x00000005
+#define OPTEE_MSG_LOGIN_APPLICATION_GROUP	0x00000006
+
+/**
+ * struct optee_msg_param_memref - memory reference
+ * @buf_ptr:	Address of the buffer
+ * @size:	Size of the buffer
+ * @shm_ref:	Shared memory reference, pointer to a struct tee_shm
+ *
+ * Secure and normal world communicates pointers as physical address
+ * instead of the virtual address. This is because secure and normal world
+ * have completely independent memory mapping. Normal world can even have a
+ * hypervisor which need to translate the guest physical address (AKA IPA
+ * in ARM documentation) to a real physical address before passing the
+ * structure to secure world.
+ */
+struct optee_msg_param_memref {
+	u64 buf_ptr;
+	u64 size;
+	u64 shm_ref;
+};
+
+/**
+ * struct optee_msg_param_value - values
+ * @a: first value
+ * @b: second value
+ * @c: third value
+ */
+struct optee_msg_param_value {
+	u64 a;
+	u64 b;
+	u64 c;
+};
+
+/**
+ * struct optee_msg_param - parameter
+ * @attr: attributes
+ * @memref: a memory reference
+ * @value: a value
+ *
+ * @attr & OPTEE_MSG_ATTR_TYPE_MASK indicates if memref or value is used in
+ * the union. OPTEE_MSG_ATTR_TYPE_VALUE_* indicates value and
+ * OPTEE_MSG_ATTR_TYPE_MEMREF_* indicates memref. OPTEE_MSG_ATTR_TYPE_NONE
+ * indicates that none of the members are used.
+ */
+struct optee_msg_param {
+	u64 attr;
+	union {
+		struct optee_msg_param_memref memref;
+		struct optee_msg_param_value value;
+	} u;
+};
+
+/**
+ * struct optee_msg_arg - call argument
+ * @cmd: Command, one of OPTEE_MSG_CMD_* or OPTEE_MSG_RPC_CMD_*
+ * @func: Trusted Application function, specific to the Trusted Application,
+ *	     used if cmd == OPTEE_MSG_CMD_INVOKE_COMMAND
+ * @session: In parameter for all OPTEE_MSG_CMD_* except
+ *	     OPTEE_MSG_CMD_OPEN_SESSION where it's an output parameter instead
+ * @ret: return value
+ * @ret_origin: origin of the return value
+ * @num_params: number of parameters supplied to the OS Command
+ * @params: the parameters supplied to the OS Command
+ *
+ * All normal calls to Trusted OS uses this struct. If cmd requires further
+ * information than what these field holds it can be passed as a parameter
+ * tagged as meta (setting the OPTEE_MSG_ATTR_META bit in corresponding
+ * param_attrs). All parameters tagged as meta has to come first.
+ */
+struct optee_msg_arg {
+	u32 cmd;
+	u32 func;
+	u32 session;
+	u32 ret;
+	u32 ret_origin;
+	u32 num_params;
+
+	/*
+	 * this struct is 8 byte aligned since the 'struct optee_msg_param'
+	 * which follows requires 8 byte alignment.
+	 *
+	 * Commented out element used to visualize the layout dynamic part
+	 * of the struct. This field is not available at all if
+	 * num_params == 0.
+	 *
+	 * params is accessed through the macro OPTEE_MSG_GET_PARAMS
+	 *
+	 * struct optee_msg_param params[num_params];
+	 */
+} __aligned(8);
+
+/**
+ * OPTEE_MSG_GET_PARAMS - return pointer to struct optee_msg_param *
+ *
+ * @x: Pointer to a struct optee_msg_arg
+ *
+ * Returns a pointer to the params[] inside a struct optee_msg_arg.
+ */
+#define OPTEE_MSG_GET_PARAMS(x) \
+	(struct optee_msg_param *)(((struct optee_msg_arg *)(x)) + 1)
+
+/**
+ * OPTEE_MSG_GET_ARG_SIZE - return size of struct optee_msg_arg
+ *
+ * @num_params: Number of parameters embedded in the struct optee_msg_arg
+ *
+ * Returns the size of the struct optee_msg_arg together with the number
+ * of embedded parameters.
+ */
+#define OPTEE_MSG_GET_ARG_SIZE(num_params) \
+	(sizeof(struct optee_msg_arg) + \
+	 sizeof(struct optee_msg_param) * (num_params))
+
+/*****************************************************************************
+ * Part 2 - requests from normal world
+ *****************************************************************************/
+
+/*
+ * Return the following UID if using API specified in this file without
+ * further extentions:
+ * 384fb3e0-e7f8-11e3-af63-0002a5d5c51b.
+ * Represented in 4 32-bit words in OPTEE_MSG_UID_0, OPTEE_MSG_UID_1,
+ * OPTEE_MSG_UID_2, OPTEE_MSG_UID_3.
+ */
+#define OPTEE_MSG_UID_0			0x384fb3e0
+#define OPTEE_MSG_UID_1			0xe7f811e3
+#define OPTEE_MSG_UID_2			0xaf630002
+#define OPTEE_MSG_UID_3			0xa5d5c51b
+#define OPTEE_MSG_FUNCID_CALLS_UID	0xFF01
+
+/*
+ * Returns 2.0 if using API specified in this file without further
+ * extentions. Represented in 2 32-bit words in OPTEE_MSG_REVISION_MAJOR
+ * and OPTEE_MSG_REVISION_MINOR
+ */
+#define OPTEE_MSG_REVISION_MAJOR	2
+#define OPTEE_MSG_REVISION_MINOR	0
+#define OPTEE_MSG_FUNCID_CALLS_REVISION	0xFF03
+
+/*
+ * Get UUID of Trusted OS.
+ *
+ * Used by non-secure world to figure out which Trusted OS is installed.
+ * Note that returned UUID is the UUID of the Trusted OS, not of the API.
+ *
+ * Returns UUID in 4 32-bit words in the same way as
+ * OPTEE_MSG_FUNCID_CALLS_UID described above.
+ */
+#define OPTEE_MSG_OS_OPTEE_UUID_0	0x486178e0
+#define OPTEE_MSG_OS_OPTEE_UUID_1	0xe7f811e3
+#define OPTEE_MSG_OS_OPTEE_UUID_2	0xbc5e0002
+#define OPTEE_MSG_OS_OPTEE_UUID_3	0xa5d5c51b
+#define OPTEE_MSG_FUNCID_GET_OS_UUID	0x0000
+
+/*
+ * Get revision of Trusted OS.
+ *
+ * Used by non-secure world to figure out which version of the Trusted OS
+ * is installed. Note that the returned revision is the revision of the
+ * Trusted OS, not of the API.
+ *
+ * Returns revision in 2 32-bit words in the same way as
+ * OPTEE_MSG_CALLS_REVISION described above.
+ */
+#define OPTEE_MSG_OS_OPTEE_REVISION_MAJOR	1
+#define OPTEE_MSG_OS_OPTEE_REVISION_MINOR	0
+#define OPTEE_MSG_FUNCID_GET_OS_REVISION	0x0001
+
+/*
+ * Do a secure call with struct optee_msg_arg as argument
+ * The OPTEE_MSG_CMD_* below defines what goes in struct optee_msg_arg::cmd
+ *
+ * For OPTEE_MSG_CMD_OPEN_SESSION the first two parameters are tagged as meta,
+ * holding two value parameters to pass the following information:
+ * param[0].u.value.a-b uuid of Trusted Application
+ * param[1].u.value.a-b uuid of Client
+ * param[1].u.value.c Login class of client OPTEE_MSG_LOGIN_*
+ *
+ * For OPTEE_MSG_CMD_INVOKE_COMMAND struct optee_msg_arg::func is Trusted
+ * Application function, specific to the Trusted Application.
+ */
+#define OPTEE_MSG_CMD_OPEN_SESSION	0
+#define OPTEE_MSG_CMD_INVOKE_COMMAND	1
+#define OPTEE_MSG_CMD_CLOSE_SESSION	2
+#define OPTEE_MSG_CMD_CANCEL		3
+#define OPTEE_MSG_FUNCID_CALL_WITH_ARG	0x0004
+
+/*****************************************************************************
+ * Part 3 - Requests from secure world, RPC
+ *****************************************************************************/
+
+/*
+ * All RPC is done with a struct optee_msg_arg as bearer of information,
+ * struct optee_msg_arg::arg holds values defined by OPTEE_MSG_RPC_CMD_* below
+ *
+ * RPC communication with tee-supplicant is reversed compared to normal
+ * client communication desribed above. The supplicant receives requests
+ * and sends responses.
+ */
+
+/*
+ * Maximum number of parameters used in RPC communication
+ */
+#define OPTEE_MSG_RPC_MAX_NUM_PARAMS	2
+
+/*
+ * Load a TA into memory, defined in tee-supplicant
+ */
+#define OPTEE_MSG_RPC_CMD_LOAD_TA	0
+
+/*
+ * Reserved
+ */
+#define OPTEE_MSG_RPC_CMD_RPMB		1
+
+/*
+ * File system access, defined in tee-supplicant
+ */
+#define OPTEE_MSG_RPC_CMD_FS		2
+
+/*
+ * Get time, defined in tee-supplicant
+ */
+#define OPTEE_MSG_RPC_CMD_GET_TIME	3
+
+/*
+ * Wait queue primitive, helper for secure world to implement a wait queue
+ *
+ * Waiting on a key
+ * [in] param[0].value	.a OPTEE_MSG_RPC_WAIT_QUEUE_SLEEP
+ *			.b wait key
+ *
+ * Waking up a key
+ * [in] param[0].value	.a OPTEE_MSG_RPC_WAIT_QUEUE_WAKEUP
+ *			.b wakeup key
+ */
+
+#define OPTEE_MSG_RPC_CMD_WAIT_QUEUE	4
+#define OPTEE_MSG_RPC_WAIT_QUEUE_SLEEP	0
+#define OPTEE_MSG_RPC_WAIT_QUEUE_WAKEUP	1
+
+/*
+ * Suspend execution
+ *
+ * [in] param[0].value	.a number of milliseconds to suspend
+ */
+#define OPTEE_MSG_RPC_CMD_SUSPEND	5
+
+#endif /* _OPTEE_MSG_H */
diff --git a/drivers/tee/optee/optee_private.h b/drivers/tee/optee/optee_private.h
new file mode 100644
index 0000000..f765853
--- /dev/null
+++ b/drivers/tee/optee/optee_private.h
@@ -0,0 +1,129 @@
+/*
+ * Copyright (c) 2015, Linaro Limited
+ *
+ * This software is licensed under the terms of the GNU General Public
+ * License version 2, as published by the Free Software Foundation, and
+ * may be copied, distributed, and modified under those terms.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ * GNU General Public License for more details.
+ *
+ */
+
+#ifndef OPTEE_PRIVATE_H
+#define OPTEE_PRIVATE_H
+
+#include <linux/types.h>
+#include <linux/semaphore.h>
+#include <linux/tee_drv.h>
+#include "optee_msg.h"
+#include <linux/arm-smccc.h>
+
+#define OPTEE_MAX_ARG_SIZE	1024
+
+/* Some Global Platform error codes used in this driver */
+#define TEEC_SUCCESS			0x00000000
+#define TEEC_ERROR_BAD_PARAMETERS	0xFFFF0006
+#define TEEC_ERROR_COMMUNICATION	0xFFFF000E
+#define TEEC_ERROR_OUT_OF_MEMORY	0xFFFF000C
+
+#define TEEC_ORIGIN_COMMS		0x00000002
+
+struct optee_call_queue {
+	struct mutex mutex;
+	struct list_head waiters;
+};
+
+struct optee_wait_queue {
+	struct mutex mu;
+	struct list_head db;
+};
+
+struct optee_supp {
+	u32 func;
+	u32 ret;
+	size_t num_params;
+	struct tee_param *param;
+
+	bool req_posted;
+	bool supp_next_send;
+	struct mutex thrd_mutex;
+	struct mutex supp_mutex;
+	struct completion data_to_supp;
+	struct completion data_from_supp;
+};
+
+struct optee {
+	struct tee_device *supp_teedev;
+	struct tee_device *teedev;
+	struct device *dev;
+	struct optee_call_queue call_queue;
+	struct optee_wait_queue wait_queue;
+	struct optee_supp supp;
+	struct tee_shm_pool *pool;
+	void __iomem *ioremaped_shm;
+};
+
+struct optee_session {
+	struct list_head list_node;
+	u32 session_id;
+};
+
+struct optee_context_data {
+	struct mutex mutex;
+	struct list_head sess_list;
+};
+
+u32 optee_handle_rpc(struct tee_context *ctx, struct smccc_param32 *param);
+
+void optee_wait_queue_init(struct optee_wait_queue *wq);
+void optee_wait_queue_exit(struct optee_wait_queue *wq);
+
+u32 optee_supp_thrd_req(struct tee_context *ctx, u32 func, size_t num_params,
+			struct tee_param *param);
+
+int optee_supp_read(struct tee_context *ctx, void __user *buf, size_t len);
+int optee_supp_write(struct tee_context *ctx, void __user *buf, size_t len);
+void optee_supp_init(struct optee_supp *supp);
+void optee_supp_uninit(struct optee_supp *supp);
+
+int optee_supp_recv(struct tee_context *ctx, u32 *func, u32 *num_params,
+			struct tee_param *param);
+int optee_supp_send(struct tee_context *ctx, u32 ret, u32 num_params,
+			struct tee_param *param);
+
+u32 optee_do_call_with_arg(struct tee_context *ctx, phys_addr_t parg);
+int optee_open_session(struct tee_context *ctx,
+			struct tee_ioctl_open_session_arg *arg,
+			struct tee_param *param);
+int optee_close_session(struct tee_context *ctx, u32 session);
+int optee_invoke_func(struct tee_context *ctx, struct tee_ioctl_invoke_arg *arg,
+			struct tee_param *param);
+int optee_cancel_req(struct tee_context *ctx, u32 cancel_id, u32 session);
+
+void optee_enable_shm_cache(struct optee *optee);
+void optee_disable_shm_cache(struct optee *optee);
+
+int optee_from_msg_param(struct tee_param *params, size_t num_params,
+			const struct optee_msg_param *msg_params);
+int optee_to_msg_param(struct optee_msg_param *msg_params, size_t num_params,
+			const struct tee_param *params);
+
+/*
+ * Small helpers
+ */
+
+static inline void *reg_pair_to_ptr(u32 reg0, u32 reg1)
+{
+	return (void *)(unsigned long)(((u64)reg0 << 32) | reg1);
+}
+
+static inline void reg_pair_from_64(u32 *reg0, u32 *reg1, u64 val)
+{
+	*reg0 = val >> 32;
+	*reg1 = val;
+}
+
+#endif /*OPTEE_PRIVATE_H*/
diff --git a/drivers/tee/optee/optee_smc.h b/drivers/tee/optee/optee_smc.h
new file mode 100644
index 0000000..ead6615
--- /dev/null
+++ b/drivers/tee/optee/optee_smc.h
@@ -0,0 +1,466 @@
+/*
+ * Copyright (c) 2015, Linaro Limited
+ * All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions are met:
+ *
+ * 1. Redistributions of source code must retain the above copyright notice,
+ * this list of conditions and the following disclaimer.
+ *
+ * 2. Redistributions in binary form must reproduce the above copyright notice,
+ * this list of conditions and the following disclaimer in the documentation
+ * and/or other materials provided with the distribution.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
+ * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ * ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE
+ * LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
+ * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
+ * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
+ * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
+ * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
+ * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
+ * POSSIBILITY OF SUCH DAMAGE.
+ */
+#ifndef OPTEE_SMC_H
+#define OPTEE_SMC_H
+
+#include <linux/arm-smccc.h>
+
+#define OPTEE_SMC_STD_CALL_VAL(func_num) \
+	SMCCC_CALL_VAL(SMCCC_SMC_32, SMCCC_STD_CALL, \
+			   SMCCC_OWNER_TRUSTED_OS, (func_num))
+#define OPTEE_SMC_FAST_CALL_VAL(func_num) \
+	SMCCC_CALL_VAL(SMCCC_SMC_32, SMCCC_FAST_CALL, \
+			   SMCCC_OWNER_TRUSTED_OS, (func_num))
+
+/*
+ * Function specified by SMC Calling convention.
+ */
+#define OPTEE_SMC_FUNCID_CALLS_COUNT	0xFF00
+#define OPTEE_SMC_CALLS_COUNT \
+	SMCCC_CALL_VAL(SMCCC_SMC_32, OPTEE_SMC_FAST_CALL, \
+			   SMCCC_OWNER_TRUSTED_OS_END, \
+			   OPTEE_SMC_FUNCID_CALLS_COUNT)
+
+/*
+ * Normal cached memory (write-back), shareable for SMP systems and not
+ * shareable for UP systems.
+ */
+#define OPTEE_SMC_SHM_CACHED		1
+
+/*
+ * a0..a7 is used as register names in the descriptions below, on arm32
+ * that translates to r0..r7 and on arm64 to w0..w7. In both cases it's
+ * 32-bit registers.
+ */
+
+/*
+ * Function specified by SMC Calling convention
+ *
+ * Return one of the following UIDs if using API specified in this file
+ * without further extentions:
+ * 65cb6b93-af0c-4617-8ed6-644a8d1140f8
+ * see also OPTEE_SMC_UID_* in optee_msg.h
+ */
+#define OPTEE_SMC_FUNCID_CALLS_UID OPTEE_MSG_FUNCID_CALLS_UID
+#define OPTEE_SMC_CALLS_UID \
+	SMCCC_CALL_VAL(SMCCC_SMC_32, SMCCC_FAST_CALL, \
+		       SMCCC_OWNER_TRUSTED_OS_END, \
+		       OPTEE_SMC_FUNCID_CALLS_UID)
+
+/*
+ * Function specified by SMC Calling convention
+ *
+ * Returns 2.0 if using API specified in this file without further extentions.
+ * see also OPTEE_MSG_REVISION_* in optee_msg.h
+ */
+#define OPTEE_SMC_FUNCID_CALLS_REVISION OPTEE_MSG_FUNCID_CALLS_REVISION
+#define OPTEE_SMC_CALLS_REVISION \
+	SMCCC_CALL_VAL(SMCCC_SMC_32, SMCCC_FAST_CALL, \
+		       SMCCC_OWNER_TRUSTED_OS_END, \
+		       OPTEE_SMC_FUNCID_CALLS_REVISION)
+
+/*
+ * Get UUID of Trusted OS.
+ *
+ * Used by non-secure world to figure out which Trusted OS is installed.
+ * Note that returned UUID is the UUID of the Trusted OS, not of the API.
+ *
+ * Returns UUID in a0-4 in the same way as OPTEE_SMC_CALLS_UID
+ * described above.
+ */
+#define OPTEE_SMC_FUNCID_GET_OS_UUID OPTEE_MSG_FUNCID_GET_OS_UUID
+#define OPTEE_SMC_CALL_GET_OS_UUID \
+	OPTEE_SMC_FAST_CALL_VAL(OPTEE_SMC_FUNCID_GET_OS_UUID)
+
+/*
+ * Get revision of Trusted OS.
+ *
+ * Used by non-secure world to figure out which version of the Trusted OS
+ * is installed. Note that the returned revision is the revision of the
+ * Trusted OS, not of the API.
+ *
+ * Returns revision in a0-1 in the same way as OPTEE_SMC_CALLS_REVISION
+ * described above.
+ */
+#define OPTEE_SMC_FUNCID_GET_OS_REVISION OPTEE_MSG_FUNCID_GET_OS_REVISION
+#define OPTEE_SMC_CALL_GET_OS_REVISION \
+	OPTEE_SMC_FAST_CALL_VAL(OPTEE_SMC_FUNCID_GET_OS_REVISION)
+
+/*
+ * Call with struct optee_msg_arg as argument
+ *
+ * Call register usage:
+ * a0	SMC Function ID, OPTEE_SMC*CALL_WITH_ARG
+ * a1	Upper 32bit of a 64bit physical pointer to a struct optee_msg_arg
+ * a2	Lower 32bit of a 64bit physical pointer to a struct optee_msg_arg
+ * a3-6	Not used
+ * a7	Hypervisor Client ID register
+ *
+ * Normal return register usage:
+ * a0	Return value, OPTEE_SMC_RETURN_*
+ * a1-3	Not used
+ * a4-7	Preserved
+ *
+ * OPTEE_SMC_RETURN_ETHREAD_LIMIT return register usage:
+ * a0	Return value, OPTEE_SMC_RETURN_ETHREAD_LIMIT
+ * a1-3	Preserved
+ * a4-7	Preserved
+ *
+ * RPC return register usage:
+ * a0	Return value, OPTEE_SMC_RETURN_IS_RPC(val)
+ * a1-2	RPC parameters
+ * a3-7	Resume information, must be preserved
+ *
+ * Possible return values:
+ * OPTEE_SMC_RETURN_UNKNOWN_FUNCTION	Trusted OS does not recognize this
+ *					function.
+ * OPTEE_SMC_RETURN_OK			Call completed, result updated in
+ *					the previously supplied struct
+ *					optee_msg_arg.
+ * OPTEE_SMC_RETURN_ETHREAD_LIMIT	Number of Trusted OS threads exceeded,
+ *					try again later.
+ * OPTEE_SMC_RETURN_EBADADDR		Bad physcial pointer to struct
+ *					optee_msg_arg.
+ * OPTEE_SMC_RETURN_EBADCMD		Bad/unknown cmd in struct optee_msg_arg
+ * OPTEE_SMC_RETURN_IS_RPC()		Call suspended by RPC call to normal
+ *					world.
+ */
+#define OPTEE_SMC_FUNCID_CALL_WITH_ARG OPTEE_MSG_FUNCID_CALL_WITH_ARG
+#define OPTEE_SMC_CALL_WITH_ARG \
+	OPTEE_SMC_STD_CALL_VAL(OPTEE_SMC_FUNCID_CALL_WITH_ARG)
+
+/*
+ * Get Shared Memory Config
+ *
+ * Returns the Secure/Non-secure shared memory config.
+ *
+ * Call register usage:
+ * a0	SMC Function ID, OPTEE_SMC_GET_SHM_CONFIG
+ * a1-6	Not used
+ * a7	Hypervisor Client ID register
+ *
+ * Have config return register usage:
+ * a0	OPTEE_SMC_RETURN_OK
+ * a1	Physical address of start of SHM
+ * a2	Size of of SHM
+ * a3	Cache settings of memory, as defined by the
+ *	OPTEE_SMC_SHM_* values above
+ * a4-7	Preserved
+ *
+ * Not available register usage:
+ * a0	OPTEE_SMC_RETURN_ENOTAVAIL
+ * a1-3 Not used
+ * a4-7	Preserved
+ */
+#define OPTEE_SMC_FUNCID_GET_SHM_CONFIG	7
+#define OPTEE_SMC_GET_SHM_CONFIG \
+	OPTEE_SMC_FAST_CALL_VAL(OPTEE_SMC_FUNCID_GET_SHM_CONFIG)
+
+/*
+ * Exchanges capabilities between normal world and secure world
+ *
+ * Call register usage:
+ * a0	SMC Function ID, OPTEE_SMC_EXCHANGE_CAPABILITIES
+ * a1	bitfield of normal world capabilities OPTEE_SMC_NSEC_CAP_*
+ * a2-6	Not used
+ * a7	Hypervisor Client ID register
+ *
+ * Normal return register usage:
+ * a0	OPTEE_SMC_RETURN_OK
+ * a1	bitfield of secure world capabilities OPTEE_SMC_SEC_CAP_*
+ * a2-7	Preserved
+ *
+ * Error return register usage:
+ * a0	OPTEE_SMC_RETURN_ENOTAVAIL, can't use the capabilities from normal world
+ * a1	bitfield of secure world capabilities OPTEE_SMC_SEC_CAP_*
+ * a2-7 Preserved
+ */
+/* Normal world works as a uniprocessor system */
+#define OPTEE_SMC_NSEC_CAP_UNIPROCESSOR		(1 << 0)
+/* Secure world has reserved shared memory for normal world to use */
+#define OPTEE_SMC_SEC_CAP_HAVE_RESERVERED_SHM	(1 << 0)
+#define OPTEE_SMC_FUNCID_EXCHANGE_CAPABILITIES	9
+#define OPTEE_SMC_EXCHANGE_CAPABILITIES \
+	OPTEE_SMC_FAST_CALL_VAL(OPTEE_SMC_FUNCID_EXCHANGE_CAPABILITIES)
+
+/*
+ * Disable and empties cache of shared memory objects
+ *
+ * Secure world can cache frequently used shared memory objects, for
+ * example objects used as RPC arguments. When secure world is idle this
+ * function returns one shared memory reference to free. To disable the
+ * cache and free all cached objects this function has to be called until
+ * it returns OPTEE_SMC_RETURN_ENOTAVAIL.
+ *
+ * Call register usage:
+ * a0	SMC Function ID, OPTEE_SMC_DISABLE_SHM_CACHE
+ * a1-6	Not used
+ * a7	Hypervisor Client ID register
+ *
+ * Normal return register usage:
+ * a0	OPTEE_SMC_RETURN_OK
+ * a1	Upper 32bit of a 64bit Shared memory cookie
+ * a2	Lower 32bit of a 64bit Shared memory cookie
+ * a3-7	Preserved
+ *
+ * Cache empty return register usage:
+ * a0	OPTEE_SMC_RETURN_ENOTAVAIL
+ * a1-7	Preserved
+ *
+ * Not idle return register usage:
+ * a0	OPTEE_SMC_RETURN_EBUSY
+ * a1-7	Preserved
+ */
+#define OPTEE_SMC_FUNCID_DISABLE_SHM_CACHE	10
+#define OPTEE_SMC_DISABLE_SHM_CACHE \
+	OPTEE_SMC_FAST_CALL_VAL(OPTEE_SMC_FUNCID_DISABLE_SHM_CACHE)
+
+
+/*
+ * Enable cache of shared memory objects
+ *
+ * Secure world can cache frequently used shared memory objects, for
+ * example objects used as RPC arguments. When secure world is idle this
+ * function returns OPTEE_SMC_RETURN_OK and the cache is enabled. If
+ * secure world isn't idle OPTEE_SMC_RETURN_EBUSY is returned.
+ *
+ * Call register usage:
+ * a0	SMC Function ID, OPTEE_SMC_ENABLE_SHM_CACHE
+ * a1-6	Not used
+ * a7	Hypervisor Client ID register
+ *
+ * Normal return register usage:
+ * a0	OPTEE_SMC_RETURN_OK
+ * a1-7	Preserved
+ *
+ * Not idle return register usage:
+ * a0	OPTEE_SMC_RETURN_EBUSY
+ * a1-7	Preserved
+ */
+#define OPTEE_SMC_FUNCID_ENABLE_SHM_CACHE	11
+#define OPTEE_SMC_ENABLE_SHM_CACHE \
+	OPTEE_SMC_FAST_CALL_VAL(OPTEE_SMC_FUNCID_ENABLE_SHM_CACHE)
+
+/*
+ * Resume from RPC (for example after processing an IRQ)
+ *
+ * Call register usage:
+ * a0	SMC Function ID, OPTEE_SMC_CALL_RETURN_FROM_RPC
+ * a1-3	Value of a1-3 when OPTEE_SMC_CALL_WITH_ARG returned
+ *	OPTEE_SMC_RETURN_RPC in a0
+ *
+ * Return register usage is the same as for OPTEE_SMC_*CALL_WITH_ARG above.
+ *
+ * Possible return values
+ * OPTEE_SMC_RETURN_UNKNOWN_FUNCTION	Trusted OS does not recognize this
+ *					function.
+ * OPTEE_SMC_RETURN_OK			Original call completed, result
+ *					updated in the previously supplied.
+ *					struct optee_msg_arg
+ * OPTEE_SMC_RETURN_RPC			Call suspended by RPC call to normal
+ *					world.
+ * OPTEE_SMC_RETURN_ERESUME		Resume failed, the opaque resume
+ *					information was corrupt.
+ */
+#define OPTEE_SMC_FUNCID_RETURN_FROM_RPC	3
+#define OPTEE_SMC_CALL_RETURN_FROM_RPC \
+	OPTEE_SMC_STD_CALL_VAL(OPTEE_SMC_FUNCID_RETURN_FROM_RPC)
+
+#define OPTEE_SMC_RETURN_RPC_PREFIX_MASK	0xFFFF0000
+#define OPTEE_SMC_RETURN_RPC_PREFIX		0xFFFF0000
+#define OPTEE_SMC_RETURN_RPC_FUNC_MASK		0x0000FFFF
+
+#define OPTEE_SMC_RETURN_GET_RPC_FUNC(ret) \
+	((ret) & OPTEE_SMC_RETURN_RPC_FUNC_MASK)
+
+#define OPTEE_SMC_RPC_VAL(func)		((func) | OPTEE_SMC_RETURN_RPC_PREFIX)
+
+/*
+ * Allocate argument memory for RPC parameter passing.
+ * Argument memory is used to hold a struct optee_msg_arg.
+ *
+ * "Call" register usage:
+ * a0	This value, OPTEE_SMC_RETURN_RPC_ALLOC_ARG
+ * a1	Size in bytes of required argument memory
+ * a2	Not used
+ * a3	Resume information, must be preserved
+ * a4-5	Not used
+ * a6-7	Resume information, must be preserved
+ *
+ * "Return" register usage:
+ * a0	SMC Function ID, OPTEE_SMC_CALL_RETURN_FROM_RPC.
+ * a1	Upper 32bits of 64bit physical pointer to allocated argument
+ *	memory, (a1 == 0 && a2 == 0) if size was 0 or if memory can't
+ *	be allocated.
+ * a2	Lower 32bits of 64bit physical pointer to allocated argument
+ *	memory, (a1 == 0 && a2 == 0) if size was 0 or if memory can't
+ *	be allocated
+ * a3	Preserved
+ * a4	Upper 32bits of 64bit Shared memory cookie used when freeing
+ *	the memory or doing an RPC
+ * a5	Lower 32bits of 64bit Shared memory cookie used when freeing
+ *	the memory or doing an RPC
+ * a6-7	Preserved
+ */
+#define OPTEE_SMC_RPC_FUNC_ALLOC_ARG	0
+#define OPTEE_SMC_RETURN_RPC_ALLOC_ARG \
+	OPTEE_SMC_RPC_VAL(OPTEE_SMC_RPC_FUNC_ALLOC_ARG)
+
+/*
+ * Allocate payload memory for RPC parameter passing.
+ * Payload memory is used to hold the memory referred to by struct
+ * optee_msg_param_memref.
+ *
+ * "Call" register usage:
+ * a0	This value, OPTEE_SMC_RETURN_RPC_ALLOC_PAYLOAD
+ * a1	Size in bytes of required argument memory
+ * a2	Not used
+ * a3	Resume information, must be preserved
+ * a4-5	Not used
+ * a6-7	Resume information, must be preserved
+ *
+ * "Return" register usage:
+ * a0	SMC Function ID, OPTEE_SMC_CALL_RETURN_FROM_RPC.
+ * a1	Upper 32bits of 64bit physical pointer to allocated argument
+ *	memory, (a1 == 0 && a2 == 0) if size was 0 or if memory can't
+ *	be allocated
+ * a2	Lower 32bits of 64bit physical pointer to allocated argument
+ *	memory, (a1 == 0 && a2 == 0) if size was 0 or if memory can't
+ *	be allocated
+ * a3	Preserved
+ * a4	Upper 32bits of 64bit Shared memory cookie used when freeing
+ *	the memory
+ * a5	Lower 32bits of 64bit Shared memory cookie used when freeing
+ *	the memory
+ * a6-7	Preserved
+ */
+#define OPTEE_SMC_RPC_FUNC_ALLOC_PAYLOAD	1
+#define OPTEE_SMC_RETURN_RPC_ALLOC_PAYLOAD \
+	OPTEE_SMC_RPC_VAL(OPTEE_SMC_RPC_FUNC_ALLOC_PAYLOAD)
+
+/*
+ * Free memory previously allocated by OPTEE_SMC_RETURN_RPC_ALLOC_ARG.
+ *
+ * "Call" register usage:
+ * a0	This value, OPTEE_SMC_RETURN_RPC_FREE_ARG
+ * a1	Upper 32bits of 64bit shared memory cookie belonging to this
+ *	argument memory
+ * a2	Lower 32bits of 64bit shared memory cookie belonging to this
+ *	argument memory
+ * a3-7	Resume information, must be preserved
+ *
+ * "Return" register usage:
+ * a0	SMC Function ID, OPTEE_SMC_CALL_RETURN_FROM_RPC.
+ * a1-2	Not used
+ * a3-7	Preserved
+ */
+#define OPTEE_SMC_RPC_FUNC_FREE_ARG	2
+#define OPTEE_SMC_RETURN_RPC_FREE_ARG \
+	OPTEE_SMC_RPC_VAL(OPTEE_SMC_RPC_FUNC_FREE_ARG)
+
+/*
+ * Free memory previously allocated by OPTEE_SMC_RETURN_RPC_ALLOC_PAYLOAD.
+ *
+ * "Call" register usage:
+ * a0	This value, OPTEE_SMC_RETURN_RPC_FREE_PAYLOAD
+ * a1	Upper 32bit of 64bit shared memory cookie belonging to this
+ *	payload memory
+ * a2	Lower 32bit of 64bit shared memory cookie belonging to this
+ *	payload memory
+ * a3-7	Resume information, must be preserved
+ *
+ * "Return" register usage:
+ * a0	SMC Function ID, OPTEE_SMC_CALL_RETURN_FROM_RPC.
+ * a1-2	Not used
+ * a3-7	Preserved
+ */
+#define OPTEE_SMC_RPC_FUNC_FREE_PAYLOAD	3
+#define OPTEE_SMC_RETURN_RPC_FREE_PAYLOAD \
+	OPTEE_SMC_RPC_VAL(OPTEE_SMC_RPC_FUNC_FREE_PAYLOAD)
+
+/*
+ * Deliver an IRQ in normal world.
+ *
+ * "Call" register usage:
+ * a0	OPTEE_SMC_RETURN_RPC_IRQ
+ * a1-7	Resume information, must be preserved
+ *
+ * "Return" register usage:
+ * a0	SMC Function ID, OPTEE_SMC_CALL_RETURN_FROM_RPC.
+ * a1-7	Preserved
+ */
+#define OPTEE_SMC_RPC_FUNC_IRQ		4
+#define OPTEE_SMC_RETURN_RPC_IRQ \
+	OPTEE_SMC_RPC_VAL(OPTEE_SMC_RPC_FUNC_IRQ)
+
+/*
+ * Do an RPC request. The supplied struct optee_msg_arg tells which
+ * request to do and the parameters for the request. The following fields
+ * are used (the rest are unused):
+ * - cmd		the Request ID
+ * - ret		return value of the request, filled in by normal world
+ * - num_params		number of parameters for the request
+ * - params		the parameters
+ * - param_attrs	attributes of the parameters
+ *
+ * "Call" register usage:
+ * a0	OPTEE_SMC_RETURN_RPC_CMD
+ * a1	Upper 32bit of a 64bit Shared memory cookie holding a
+ *	struct optee_msg_arg, must be preserved, only the data should
+ *	be updated
+ * a2	Lower 32bit of a 64bit Shared memory cookie holding a
+ *	struct optee_msg_arg, must be preserved, only the data should
+ *	be updated
+ * a3-7	Resume information, must be preserved
+ *
+ * "Return" register usage:
+ * a0	SMC Function ID, OPTEE_SMC_CALL_RETURN_FROM_RPC.
+ * a1-2	Not used
+ * a3-7	Preserved
+ */
+#define OPTEE_SMC_RPC_FUNC_CMD		5
+#define OPTEE_SMC_RETURN_RPC_CMD \
+	OPTEE_SMC_RPC_VAL(OPTEE_SMC_RPC_FUNC_CMD)
+
+/* Returned in a0 */
+#define OPTEE_SMC_RETURN_UNKNOWN_FUNCTION 0xFFFFFFFF
+
+/* Returned in a0 only from Trusted OS functions */
+#define OPTEE_SMC_RETURN_OK		0x0
+#define OPTEE_SMC_RETURN_ETHREAD_LIMIT	0x1
+#define OPTEE_SMC_RETURN_EBUSY		0x2
+#define OPTEE_SMC_RETURN_ERESUME	0x3
+#define OPTEE_SMC_RETURN_EBADADDR	0x4
+#define OPTEE_SMC_RETURN_EBADCMD	0x5
+#define OPTEE_SMC_RETURN_ENOMEM		0x6
+#define OPTEE_SMC_RETURN_ENOTAVAIL	0x7
+#define OPTEE_SMC_RETURN_IS_RPC(ret) \
+	(((ret) != OPTEE_SMC_RETURN_UNKNOWN_FUNCTION) && \
+	((((ret) & OPTEE_SMC_RETURN_RPC_PREFIX_MASK) == \
+		OPTEE_SMC_RETURN_RPC_PREFIX)))
+
+#endif /* OPTEE_SMC_H */
diff --git a/drivers/tee/optee/rpc.c b/drivers/tee/optee/rpc.c
new file mode 100644
index 0000000..dd5bb01
--- /dev/null
+++ b/drivers/tee/optee/rpc.c
@@ -0,0 +1,248 @@
+/*
+ * Copyright (c) 2015, Linaro Limited
+ *
+ * This software is licensed under the terms of the GNU General Public
+ * License version 2, as published by the Free Software Foundation, and
+ * may be copied, distributed, and modified under those terms.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ * GNU General Public License for more details.
+ *
+ */
+#include <linux/device.h>
+#include <linux/slab.h>
+#include <linux/sched.h>
+#include <linux/tee_drv.h>
+#include "optee_private.h"
+#include "optee_smc.h"
+
+struct wq_entry {
+	struct list_head link;
+	struct completion c;
+	u32 key;
+};
+
+void optee_wait_queue_init(struct optee_wait_queue *priv)
+{
+	mutex_init(&priv->mu);
+	INIT_LIST_HEAD(&priv->db);
+}
+
+void optee_wait_queue_exit(struct optee_wait_queue *priv)
+{
+	mutex_destroy(&priv->mu);
+}
+
+static struct wq_entry *wq_entry_get(struct optee_wait_queue *wq, u32 key)
+{
+	struct wq_entry *w;
+
+	mutex_lock(&wq->mu);
+
+	list_for_each_entry(w, &wq->db, link)
+		if (w->key == key)
+			goto out;
+
+	w = kmalloc(sizeof(struct wq_entry), GFP_KERNEL);
+	if (w) {
+		init_completion(&w->c);
+		w->key = key;
+		list_add_tail(&w->link, &wq->db);
+	}
+out:
+	mutex_unlock(&wq->mu);
+	return w;
+}
+
+static void wq_sleep(struct optee_wait_queue *wq, u32 key)
+{
+	struct wq_entry *w = wq_entry_get(wq, key);
+
+	if (w) {
+		wait_for_completion(&w->c);
+		mutex_lock(&wq->mu);
+		list_del(&w->link);
+		mutex_unlock(&wq->mu);
+		kfree(w);
+	}
+}
+
+static void wq_wakeup(struct optee_wait_queue *wq, u32 key)
+{
+	struct wq_entry *w = wq_entry_get(wq, key);
+
+	if (w)
+		complete(&w->c);
+}
+
+static void handle_rpc_func_cmd_wq(struct optee *optee,
+			struct optee_msg_arg *arg)
+{
+	struct optee_msg_param *params;
+
+	if (arg->num_params != 1)
+		goto bad;
+
+	params = OPTEE_MSG_GET_PARAMS(arg);
+	if ((params->attr & OPTEE_MSG_ATTR_TYPE_MASK) !=
+			OPTEE_MSG_ATTR_TYPE_VALUE_INPUT)
+		goto bad;
+
+	switch (params->u.value.a) {
+	case OPTEE_MSG_RPC_WAIT_QUEUE_SLEEP:
+		wq_sleep(&optee->wait_queue, params->u.value.b);
+		break;
+	case OPTEE_MSG_RPC_WAIT_QUEUE_WAKEUP:
+		wq_wakeup(&optee->wait_queue, params->u.value.b);
+		break;
+	default:
+		goto bad;
+	}
+
+	arg->ret = TEEC_SUCCESS;
+	return;
+bad:
+	arg->ret = TEEC_ERROR_BAD_PARAMETERS;
+}
+
+static void handle_rpc_func_cmd_wait(struct optee_msg_arg *arg)
+{
+	struct optee_msg_param *params;
+	u32 msec_to_wait;
+
+	if (arg->num_params != 1)
+		goto bad;
+
+	params = OPTEE_MSG_GET_PARAMS(arg);
+	if ((params->attr & OPTEE_MSG_ATTR_TYPE_MASK) !=
+			OPTEE_MSG_ATTR_TYPE_VALUE_INPUT)
+		goto bad;
+
+	msec_to_wait = params->u.value.a;
+
+	/* set task's state to interruptible sleep */
+	set_current_state(TASK_INTERRUPTIBLE);
+
+	/* take a nap */
+	schedule_timeout(msecs_to_jiffies(msec_to_wait));
+
+	arg->ret = TEEC_SUCCESS;
+	return;
+bad:
+	arg->ret = TEEC_ERROR_BAD_PARAMETERS;
+}
+
+static void handle_rpc_supp_cmd(struct tee_context *ctx,
+			struct optee_msg_arg *arg)
+{
+	struct tee_param *params;
+	struct optee_msg_param *msg_params = OPTEE_MSG_GET_PARAMS(arg);
+
+	arg->ret_origin = TEEC_ORIGIN_COMMS;
+
+	params = kmalloc_array(arg->num_params, sizeof(struct tee_param),
+			       GFP_KERNEL);
+	if (!params) {
+		arg->ret = TEEC_ERROR_OUT_OF_MEMORY;
+		return;
+	}
+
+	if (optee_from_msg_param(params, arg->num_params, msg_params)) {
+		arg->ret = TEEC_ERROR_BAD_PARAMETERS;
+		goto out;
+	}
+
+	arg->ret = optee_supp_thrd_req(ctx, arg->cmd, arg->num_params, params);
+
+	if (optee_to_msg_param(msg_params, arg->num_params, params))
+		arg->ret = TEEC_ERROR_BAD_PARAMETERS;
+out:
+	kfree(params);
+}
+
+static void handle_rpc_func_cmd(struct tee_context *ctx, struct optee *optee,
+			struct tee_shm *shm)
+{
+	struct optee_msg_arg *arg;
+
+	arg = tee_shm_get_va(shm, 0);
+	if (IS_ERR(arg)) {
+		dev_err(optee->dev, "%s: tee_shm_get_va %p failed\n",
+			__func__, shm);
+		return;
+	}
+
+	switch (arg->cmd) {
+	case OPTEE_MSG_RPC_CMD_WAIT_QUEUE:
+		handle_rpc_func_cmd_wq(optee, arg);
+		break;
+	case OPTEE_MSG_RPC_CMD_SUSPEND:
+		handle_rpc_func_cmd_wait(arg);
+		break;
+	default:
+		handle_rpc_supp_cmd(ctx, arg);
+	}
+}
+
+u32 optee_handle_rpc(struct tee_context *ctx, struct smccc_param32 *param)
+{
+	struct tee_device *teedev = ctx->teedev;
+	struct optee *optee = tee_get_drvdata(teedev);
+	struct tee_shm *shm;
+	phys_addr_t pa;
+
+	switch (OPTEE_SMC_RETURN_GET_RPC_FUNC(param->a0)) {
+	case OPTEE_SMC_RPC_FUNC_ALLOC_ARG:
+		shm = tee_shm_alloc(teedev, param->a1, TEE_SHM_MAPPED);
+		if (!IS_ERR(shm) && !tee_shm_get_pa(shm, 0, &pa)) {
+			reg_pair_from_64(&param->a1, &param->a2, pa);
+			reg_pair_from_64(&param->a4, &param->a5,
+					 (unsigned long)shm);
+		} else {
+			param->a1 = 0;
+			param->a2 = 0;
+			param->a4 = 0;
+			param->a5 = 0;
+		}
+		break;
+	case OPTEE_SMC_RPC_FUNC_ALLOC_PAYLOAD:
+		shm = tee_shm_alloc(teedev, param->a1,
+				    TEE_SHM_MAPPED | TEE_SHM_DMA_BUF);
+		if (!IS_ERR(shm) && !tee_shm_get_pa(shm, 0, &pa)) {
+			reg_pair_from_64(&param->a1, &param->a2, pa);
+			reg_pair_from_64(&param->a4, &param->a5,
+					 (unsigned long)shm);
+		} else {
+			param->a1 = 0;
+			param->a2 = 0;
+			param->a4 = 0;
+			param->a5 = 0;
+		}
+		break;
+	case OPTEE_SMC_RPC_FUNC_FREE_ARG:
+	case OPTEE_SMC_RPC_FUNC_FREE_PAYLOAD:
+		shm = reg_pair_to_ptr(param->a1, param->a2);
+		tee_shm_free(shm);
+		break;
+	case OPTEE_SMC_RPC_FUNC_IRQ:
+		/*
+		 * An IRQ was raised while secure world was executing,
+		 * since all IRQs a handled in Linux a dummy RPC is
+		 * performed to let Linux take the IRQ through the normal
+		 * vector.
+		 */
+		break;
+	case OPTEE_SMC_RPC_FUNC_CMD:
+		shm = reg_pair_to_ptr(param->a1, param->a2);
+		handle_rpc_func_cmd(ctx, optee, shm);
+		break;
+	default:
+		dev_warn(optee->dev, "Unknown RPC func 0x%x\n",
+			 (u32)OPTEE_SMC_RETURN_GET_RPC_FUNC(param->a0));
+		break;
+	}
+
+	return OPTEE_SMC_CALL_RETURN_FROM_RPC;
+}
diff --git a/drivers/tee/optee/supp.c b/drivers/tee/optee/supp.c
new file mode 100644
index 0000000..b6478b6
--- /dev/null
+++ b/drivers/tee/optee/supp.c
@@ -0,0 +1,212 @@
+/*
+ * Copyright (c) 2015, Linaro Limited
+ *
+ * This software is licensed under the terms of the GNU General Public
+ * License version 2, as published by the Free Software Foundation, and
+ * may be copied, distributed, and modified under those terms.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ * GNU General Public License for more details.
+ *
+ */
+#include <linux/device.h>
+#include <linux/slab.h>
+#include <linux/uaccess.h>
+#include "optee_private.h"
+
+void optee_supp_init(struct optee_supp *supp)
+{
+	memset(supp, 0, sizeof(*supp));
+	mutex_init(&supp->thrd_mutex);
+	mutex_init(&supp->supp_mutex);
+	init_completion(&supp->data_to_supp);
+	init_completion(&supp->data_from_supp);
+}
+
+void optee_supp_uninit(struct optee_supp *supp)
+{
+	mutex_destroy(&supp->thrd_mutex);
+	mutex_destroy(&supp->supp_mutex);
+}
+
+u32 optee_supp_thrd_req(struct tee_context *ctx, u32 func, size_t num_params,
+			struct tee_param *param)
+{
+	struct optee *optee = tee_get_drvdata(ctx->teedev);
+	struct optee_supp *supp = &optee->supp;
+	u32 ret;
+
+	/*
+	 * Other threads blocks here until we've copied our answer from
+	 * supplicant.
+	 */
+	mutex_lock(&supp->thrd_mutex);
+
+	/*
+	 * We have exclusive access now since the supplicant at this
+	 * point is either doing a
+	 * wait_for_completion_interruptible(data_to_supp) or is in
+	 * userspace still about to do the ioctl() to enter
+	 * optee_supp_read() below.
+	 */
+
+	supp->func = func;
+	supp->num_params = num_params;
+	supp->param = param;
+	supp->req_posted = true;
+
+	/* Let supplicant get the data */
+	complete(&supp->data_to_supp);
+
+	/*
+	 * Wait for supplicant to process and return result, once we've
+	 * returned from wait_for_completion(data_from_supp) we have
+	 * exclusive access again.
+	 */
+	wait_for_completion(&supp->data_from_supp);
+
+	ret = supp->ret;
+	supp->param = NULL;
+	supp->req_posted = false;
+
+	/* We're done, let someone else talk to the supplicant now. */
+	mutex_unlock(&supp->thrd_mutex);
+
+	return ret;
+}
+
+int optee_supp_recv(struct tee_context *ctx, u32 *func, u32 *num_params,
+		struct tee_param *param)
+{
+	struct tee_device *teedev = ctx->teedev;
+	struct optee *optee = tee_get_drvdata(teedev);
+	struct optee_supp *supp = &optee->supp;
+	int rc;
+
+	/*
+	 * In case two supplicants or two threads in one supplicant is
+	 * calling this function simultaneously we need to protect the
+	 * data with a mutex which we'll release before returning.
+	 */
+	mutex_lock(&supp->supp_mutex);
+
+	if (supp->supp_next_send) {
+		/*
+		 * optee_supp_recv() has been called again without
+		 * a optee_supp_send() in between. Supplicant has
+		 * probably been restarted before it was able to
+		 * write back last result. Abort last request and
+		 * wait for a new.
+		 */
+		if (supp->req_posted) {
+			supp->ret = TEEC_ERROR_COMMUNICATION;
+			supp->supp_next_send = false;
+			complete(&supp->data_from_supp);
+		}
+	}
+
+	/*
+	 * This is where supplicant will be hanging most of the
+	 * time, let's make this interruptable so we can easily
+	 * restart supplicant if needed.
+	 */
+	if (wait_for_completion_interruptible(&supp->data_to_supp)) {
+		rc = -ERESTARTSYS;
+		goto out;
+	}
+
+	/* We have exlusive access to the data */
+
+	if (*num_params < supp->num_params) {
+		/*
+		 * Not enough room for parameters, tell supplicant
+		 * it failed and abort last request.
+		 */
+		supp->ret = TEEC_ERROR_COMMUNICATION;
+		rc = -EINVAL;
+		complete(&supp->data_from_supp);
+		goto out;
+	}
+
+	*func = supp->func;
+	*num_params = supp->num_params;
+	memcpy(param, supp->param,
+	       sizeof(struct tee_param) * supp->num_params);
+
+	/* Allow optee_supp_send() below to do its work */
+	supp->supp_next_send = true;
+
+	rc = 0;
+out:
+	mutex_unlock(&supp->supp_mutex);
+	return rc;
+}
+
+int optee_supp_send(struct tee_context *ctx, u32 ret, u32 num_params,
+			struct tee_param *param)
+{
+	struct tee_device *teedev = ctx->teedev;
+	struct optee *optee = tee_get_drvdata(teedev);
+	struct optee_supp *supp = &optee->supp;
+	size_t n;
+	int rc = 0;
+
+	/*
+	 * We still have exclusive access to the data since that's how we
+	 * left it when returning from optee_supp_read().
+	 */
+
+	/* See comment on mutex in optee_supp_read() above */
+	mutex_lock(&supp->supp_mutex);
+
+	if (!supp->supp_next_send) {
+		/*
+		 * Something strange is going on, supplicant shouldn't
+		 * enter optee_supp_send() in this state
+		 */
+		rc = -ENOENT;
+		goto out;
+	}
+
+	if (num_params != supp->num_params) {
+		/*
+		 * Something is wrong, let supplicant restart. Next call to
+		 * optee_supp_recv() will give an error to the requesting
+		 * thread and release it.
+		 */
+		rc = -EINVAL;
+		goto out;
+	}
+
+	/* Update out and in/out parameters */
+	for (n = 0; n < num_params; n++) {
+		struct tee_param *p = supp->param + n;
+
+		switch (p->attr) {
+		case TEE_IOCTL_PARAM_ATTR_TYPE_VALUE_OUTPUT:
+		case TEE_IOCTL_PARAM_ATTR_TYPE_VALUE_INOUT:
+			p->u.value.a = param[n].u.value.a;
+			p->u.value.b = param[n].u.value.b;
+			p->u.value.c = param[n].u.value.c;
+			break;
+		case TEE_IOCTL_PARAM_ATTR_TYPE_MEMREF_OUTPUT:
+		case TEE_IOCTL_PARAM_ATTR_TYPE_MEMREF_INOUT:
+			p->u.memref.size = param[n].u.memref.size;
+			break;
+		default:
+			break;
+		}
+	}
+	supp->ret = ret;
+
+	/* Allow optee_supp_recv() above to do its work */
+	supp->supp_next_send = false;
+
+	/* Let the requesting thread continue */
+	complete(&supp->data_from_supp);
+out:
+	mutex_unlock(&supp->supp_mutex);
+	return rc;
+}
-- 
1.9.1



From k.kozlowski at samsung.com  Wed Aug 19 01:44:02 2015
From: k.kozlowski at samsung.com (Krzysztof Kozlowski)
Date: Wed, 19 Aug 2015 17:44:02 +0900
Subject: [PATCH v2] ARM: multi_v7_defconfig: Enable DWC2 USB driver and USB
 ethernet gadget
In-Reply-To: <1439972377-22683-1-git-send-email-m.szyprowski@samsung.com>
References: <55D30313.7080107@osg.samsung.com>
 <1439972377-22683-1-git-send-email-m.szyprowski@samsung.com>
Message-ID: <55D441D2.4070506@samsung.com>

On 19.08.2015 17:19, Marek Szyprowski wrote:
> DWC2 (s3c-hsotg) hardware module is available on many Exynos based boards,
> so enable DWC2 driver as well as the most common USB Ethernet gadget.
> 
> Signed-off-by: Marek Szyprowski <m.szyprowski at samsung.com>
> Reviewed-by: Javier Martinez Canillas <javier at osg.samsung.com>
> ---
> Changes since v1: build DWC2 and USB gadget as modules
> ---
>  arch/arm/configs/multi_v7_defconfig | 2 ++
>  1 file changed, 2 insertions(+)

Thanks Marek for the patch.
Reviewed-by: Krzysztof Kozlowski <k.kozlowski at samsung.com>

Best regards,
Krzysztof


From jens.wiklander at linaro.org  Wed Aug 19 01:40:24 2015
From: jens.wiklander at linaro.org (Jens Wiklander)
Date: Wed, 19 Aug 2015 10:40:24 +0200
Subject: [PATCH v5 0/5] generic TEE subsystem
Message-ID: <1439973629-19505-1-git-send-email-jens.wiklander@linaro.org>

Hi,

This patch set introduces a generic TEE subsystem. The TEE subsystem will
contain drivers for various TEE implementations. A TEE (Trusted Execution
Environment) is a trusted OS running in some secure environment, for
example, TrustZone on ARM CPUs, or a separate secure co-processor etc.

Regarding use cases, TrustZone has traditionally been used for
offloading secure tasks to the secure world. Examples include: 
- Secure key handling where the OS may or may not have direct access to key
  material.
- E-commerce and payment technologies. Credentials, credit card numbers etc
  could be stored in a more secure environment.
- Trusted User Interface (TUI) to ensure that no-one can snoop PIN-codes
  etc.
- Secure boot to ensure that loaded binaries haven?t been tampered with.
  It?s not strictly needed for secure boot, but you could enhance security
  by leveraging a TEE during boot.
- Digital Rights Management (DRM), the studios provides content with
  different resolution depending on the security of the device. Higher
  security means higher resolution.

A TEE could also be used in existing and new technologies. For example IMA
(Integrity Measurement Architecture) which has been in the kernel for quite
a while. Today you can enhance security by using a TPM-chip to sign the IMA
measurement list. This is something that you also could do by leveraging a
TEE.

Another example could be in 2-factor authentication which is becoming
increasingly more important. FIDO (https://fidoalliance.org) for example
are using public key cryptography in their 2-factor authentication standard
(U2F). With FIDO, a private and public key pair will be generated for every
site you visit and the private key should never leave the local device.
This is an example where you could use secure storage in a TEE for the
private key.

Today you will find a quite a few different out of tree implementations of
TEE drivers which tends to fragment the TEE ecosystem and development. We
think it would be a good idea to have a generic TEE driver integrated in
the kernel which would serve as a base for several different TEE solutions,
no matter if they are on-chip like TrustZone or if they are on a separate
crypto co-processor.

To develop this TEE subsystem we have been using the open source TEE called
OP-TEE (https://github.com/OP-TEE/optee_os) and therefore this would be the
first TEE solution supported by this new subsystem. OP-TEE is a
GlobalPlatform compliant TEE, however this TEE subsystem is not limited to
only GlobalPlatform TEEs, instead we have tried to design it so that it
should work with other TEE solutions also.

"tee: generic TEE subsystem" brings in the generic TEE subsystem which
helps when writing a driver for a specific TEE, for example, OP-TEE.

"tee: add OP-TEE driver" is an OP-TEE driver which uses the subsystem to do
its work.

This patch set has been prepared in cooperation with Javier Gonz?lez who
proposed "Generic TrustZone Driver in Linux Kernel" patches 28 Nov 2014,
https://lwn.net/Articles/623380/ . We've since then changed the scope to
TEE instead of TrustZone.

We have discussed the design on tee-dev at lists.linaro.org (archive at
https://lists.linaro.org/pipermail/tee-dev/) with people from other
companies, including Valentin Manea <valentin.manea at huawei.com>,
Emmanuel MICHEL <emmanuel.michel at st.com>,
Jean-michel DELORME <jean-michel.delorme at st.com>,
and Joakim Bech <joakim.bech at linaro.org>. Our main concern has been to
agree on something that is generic enough to support many different
TEEs while still keeping the interface together.

v5:
* Replaced kref reference counting for the device with a size_t instead as
  the counter is always protected by a mutex

v4:
* Rebased on 4.1
* Redesigned the synchronization around entry exit of normal SMC
* Replaced rwsem on the driver instance with kref and completion since
  rwsem wasn't intended to be used in this way
* Expanded the TEE_IOCTL_PARAM_ATTR_TYPE_MASK to make room for
  future additional parameter types
* Documents TEE subsystem and OP-TEE driver
* Replaced TEE_IOC_CMD with TEE_IOC_OPEN_SESSION, TEE_IOC_INVOKE,
  TEE_IOC_CANCEL and TEE_IOC_CLOSE_SESSION
* DT bindings in a separate patch
* Assembly parts moved to arch/arm and arch/arm64 respectively, in a
  separate patch
* Redefined/clarified the meaning of OPTEE_SMC_SHM_CACHED
* Removed CMA usage to limit the scope of the patch set

v3:
* Rebased on 4.1-rc3 (dma_buf_export() API change)
* A couple of small sparse fixes
* Documents bindings for OP-TEE driver
* Updated MAINTAINERS

v2:
* Replaced the stubbed OP-TEE driver with a real OP-TEE driver
* Removed most APIs not needed by OP-TEE in current state
* Update Documentation/ioctl/ioctl-number.txt with correct path to tee.h
* Rename tee_shm_pool_alloc_cma() to tee_shm_pool_alloc()
* Moved tee.h into include/uapi/linux/
* Redefined tee.h IOCTL macros to be directly based on _IOR and friends
* Removed version info on the API to user space, a data blob which
  can contain an UUID is left for user space to be able to tell which
  protocol to use in TEE_IOC_CMD
* Changed user space exposed structures to only have types with __ prefix
* Dropped THIS_MODULE from tee_fops
* Reworked how the driver is registered and ref counted:
  - moved from using an embedded struct miscdevice to an embedded struct
    device.
  - uses an struct rw_semaphore as synchronization for driver detachment
  - uses alloc/register pattern from TPM

Thanks,
Jens

Jens Wiklander (5):
  arm/arm64: add smccc ARCH32
  dt/bindings: add bindings for optee
  tee: generic TEE subsystem
  tee: add OP-TEE driver
  Documentation: tee subsystem and op-tee driver

 Documentation/00-INDEX                             |   2 +
 Documentation/devicetree/bindings/optee/optee.txt  |  17 +
 .../devicetree/bindings/vendor-prefixes.txt        |   1 +
 Documentation/ioctl/ioctl-number.txt               |   1 +
 Documentation/tee.txt                              | 117 +++
 MAINTAINERS                                        |  14 +
 arch/arm/Kconfig                                   |   4 +
 arch/arm/kernel/Makefile                           |   2 +
 arch/arm/kernel/smccc-call.S                       |  26 +
 arch/arm/kernel/smccc.c                            |  17 +
 arch/arm64/Kconfig                                 |   4 +
 arch/arm64/kernel/Makefile                         |   1 +
 arch/arm64/kernel/smccc-call.S                     |  34 +
 arch/arm64/kernel/smccc.c                          |  17 +
 drivers/Kconfig                                    |   2 +
 drivers/Makefile                                   |   1 +
 drivers/tee/Kconfig                                |  18 +
 drivers/tee/Makefile                               |   4 +
 drivers/tee/optee/Kconfig                          |   8 +
 drivers/tee/optee/Makefile                         |   5 +
 drivers/tee/optee/call.c                           | 390 ++++++++++
 drivers/tee/optee/core.c                           | 453 +++++++++++
 drivers/tee/optee/optee_msg.h                      | 334 +++++++++
 drivers/tee/optee/optee_private.h                  | 129 ++++
 drivers/tee/optee/optee_smc.h                      | 466 ++++++++++++
 drivers/tee/optee/rpc.c                            | 248 ++++++
 drivers/tee/optee/supp.c                           | 212 ++++++
 drivers/tee/tee.c                                  | 834 +++++++++++++++++++++
 drivers/tee/tee_private.h                          |  80 ++
 drivers/tee/tee_shm.c                              | 324 ++++++++
 drivers/tee/tee_shm_pool.c                         | 133 ++++
 include/linux/arm-smccc.h                          |  79 ++
 include/linux/tee_drv.h                            | 306 ++++++++
 include/uapi/linux/tee.h                           | 376 ++++++++++
 34 files changed, 4659 insertions(+)
 create mode 100644 Documentation/devicetree/bindings/optee/optee.txt
 create mode 100644 Documentation/tee.txt
 create mode 100644 arch/arm/kernel/smccc-call.S
 create mode 100644 arch/arm/kernel/smccc.c
 create mode 100644 arch/arm64/kernel/smccc-call.S
 create mode 100644 arch/arm64/kernel/smccc.c
 create mode 100644 drivers/tee/Kconfig
 create mode 100644 drivers/tee/Makefile
 create mode 100644 drivers/tee/optee/Kconfig
 create mode 100644 drivers/tee/optee/Makefile
 create mode 100644 drivers/tee/optee/call.c
 create mode 100644 drivers/tee/optee/core.c
 create mode 100644 drivers/tee/optee/optee_msg.h
 create mode 100644 drivers/tee/optee/optee_private.h
 create mode 100644 drivers/tee/optee/optee_smc.h
 create mode 100644 drivers/tee/optee/rpc.c
 create mode 100644 drivers/tee/optee/supp.c
 create mode 100644 drivers/tee/tee.c
 create mode 100644 drivers/tee/tee_private.h
 create mode 100644 drivers/tee/tee_shm.c
 create mode 100644 drivers/tee/tee_shm_pool.c
 create mode 100644 include/linux/arm-smccc.h
 create mode 100644 include/linux/tee_drv.h
 create mode 100644 include/uapi/linux/tee.h

-- 
1.9.1



From gabriel.fernandez at linaro.org  Wed Aug 19 01:48:13 2015
From: gabriel.fernandez at linaro.org (Gabriel Fernandez)
Date: Wed, 19 Aug 2015 10:48:13 +0200
Subject: [PATCH 1/2] dt-bindings: Fix tipo in st,clkgen-pll documentation
In-Reply-To: <1439974094-32322-1-git-send-email-gabriel.fernandez@linaro.org>
References: <1439974094-32322-1-git-send-email-gabriel.fernandez@linaro.org>
Message-ID: <1439974094-32322-2-git-send-email-gabriel.fernandez@linaro.org>

replace "sst,plls-c32-cx_x" by "st,plls-c32-cx_x"

Signed-off-by: Gabriel Fernandez <gabriel.fernandez at linaro.org>
---
 Documentation/devicetree/bindings/clock/st/st,clkgen-pll.txt | 4 ++--
 1 file changed, 2 insertions(+), 2 deletions(-)

diff --git a/Documentation/devicetree/bindings/clock/st/st,clkgen-pll.txt b/Documentation/devicetree/bindings/clock/st/st,clkgen-pll.txt
index d8b168e..e2c6db0 100644
--- a/Documentation/devicetree/bindings/clock/st/st,clkgen-pll.txt
+++ b/Documentation/devicetree/bindings/clock/st/st,clkgen-pll.txt
@@ -21,8 +21,8 @@ Required properties:
 	"st,stih416-plls-c32-ddr",	"st,clkgen-plls-c32"
 	"st,stih407-plls-c32-a0",	"st,clkgen-plls-c32"
 	"st,stih407-plls-c32-a9",	"st,clkgen-plls-c32"
-	"sst,plls-c32-cx_0",		"st,clkgen-plls-c32"
-	"sst,plls-c32-cx_1",		"st,clkgen-plls-c32"
+	"st,plls-c32-cx_0",		"st,clkgen-plls-c32"
+	"st,plls-c32-cx_1",		"st,clkgen-plls-c32"
 
 	"st,stih415-gpu-pll-c32",	"st,clkgengpu-pll-c32"
 	"st,stih416-gpu-pll-c32",	"st,clkgengpu-pll-c32"
-- 
1.9.1



From gabriel.fernandez at linaro.org  Wed Aug 19 01:48:12 2015
From: gabriel.fernandez at linaro.org (Gabriel Fernandez)
Date: Wed, 19 Aug 2015 10:48:12 +0200
Subject: [PATCH 0/2] ST PLL fixes for 4.3
Message-ID: <1439974094-32322-1-git-send-email-gabriel.fernandez@linaro.org>

Should be apply with 
commit 5eb26c605909 ("ARM: STi: DT: Rename st_pll3200c32_407_c0_x into st_pll3200c32_cx_x")
to avoid broken compatibility.

Gabriel Fernandez (2):
  dt-bindings: Fix tipo in st,clkgen-pll documentation
  drivers: clk: st: Rename st_pll3200c32_407_c0_x into
    st_pll3200c32_cx_x

 Documentation/devicetree/bindings/clock/st/st,clkgen-pll.txt |  4 ++--
 drivers/clk/st/clkgen-fsyn.c                                 |  8 ++++----
 drivers/clk/st/clkgen-pll.c                                  | 12 ++++++------
 3 files changed, 12 insertions(+), 12 deletions(-)

-- 
1.9.1



From gabriel.fernandez at linaro.org  Wed Aug 19 01:48:14 2015
From: gabriel.fernandez at linaro.org (Gabriel Fernandez)
Date: Wed, 19 Aug 2015 10:48:14 +0200
Subject: [PATCH 2/2] drivers: clk: st: Rename st_pll3200c32_407_c0_x into
 st_pll3200c32_cx_x
In-Reply-To: <1439974094-32322-1-git-send-email-gabriel.fernandez@linaro.org>
References: <1439974094-32322-1-git-send-email-gabriel.fernandez@linaro.org>
Message-ID: <1439974094-32322-3-git-send-email-gabriel.fernandez@linaro.org>

Use a generic name for this kind of PLL

Correction in dts files are already done here:
commit 5eb26c605909 ("ARM: STi: DT: Rename st_pll3200c32_407_c0_x into st_pll3200c32_cx_x")

Signed-off-by: Gabriel Fernandez <gabriel.fernandez at linaro.org>
---
 drivers/clk/st/clkgen-fsyn.c |  8 ++++----
 drivers/clk/st/clkgen-pll.c  | 12 ++++++------
 2 files changed, 10 insertions(+), 10 deletions(-)

diff --git a/drivers/clk/st/clkgen-fsyn.c b/drivers/clk/st/clkgen-fsyn.c
index 83ccf14..576cd03 100644
--- a/drivers/clk/st/clkgen-fsyn.c
+++ b/drivers/clk/st/clkgen-fsyn.c
@@ -307,7 +307,7 @@ static const struct clkgen_quadfs_data st_fs660c32_F_416 = {
 	.get_rate	= clk_fs660c32_dig_get_rate,
 };
 
-static const struct clkgen_quadfs_data st_fs660c32_C_407 = {
+static const struct clkgen_quadfs_data st_fs660c32_C = {
 	.nrst_present = true,
 	.nrst	= { CLKGEN_FIELD(0x2f0, 0x1, 0),
 		    CLKGEN_FIELD(0x2f0, 0x1, 1),
@@ -350,7 +350,7 @@ static const struct clkgen_quadfs_data st_fs660c32_C_407 = {
 	.get_rate	= clk_fs660c32_dig_get_rate,
 };
 
-static const struct clkgen_quadfs_data st_fs660c32_D_407 = {
+static const struct clkgen_quadfs_data st_fs660c32_D = {
 	.nrst_present = true,
 	.nrst	= { CLKGEN_FIELD(0x2a0, 0x1, 0),
 		    CLKGEN_FIELD(0x2a0, 0x1, 1),
@@ -1077,11 +1077,11 @@ static const struct of_device_id quadfs_of_match[] = {
 	},
 	{
 		.compatible = "st,stih407-quadfs660-C",
-		.data = &st_fs660c32_C_407
+		.data = &st_fs660c32_C
 	},
 	{
 		.compatible = "st,stih407-quadfs660-D",
-		.data = &st_fs660c32_D_407
+		.data = &st_fs660c32_D
 	},
 	{}
 };
diff --git a/drivers/clk/st/clkgen-pll.c b/drivers/clk/st/clkgen-pll.c
index 47a38a9..b2a332c 100644
--- a/drivers/clk/st/clkgen-pll.c
+++ b/drivers/clk/st/clkgen-pll.c
@@ -193,7 +193,7 @@ static const struct clkgen_pll_data st_pll3200c32_407_a0 = {
 	.ops		= &stm_pll3200c32_ops,
 };
 
-static const struct clkgen_pll_data st_pll3200c32_407_c0_0 = {
+static const struct clkgen_pll_data st_pll3200c32_cx_0 = {
 	/* 407 C0 PLL0 */
 	.pdn_status	= CLKGEN_FIELD(0x2a0,	0x1,			8),
 	.locked_status	= CLKGEN_FIELD(0x2a0,	0x1,			24),
@@ -205,7 +205,7 @@ static const struct clkgen_pll_data st_pll3200c32_407_c0_0 = {
 	.ops		= &stm_pll3200c32_ops,
 };
 
-static const struct clkgen_pll_data st_pll3200c32_407_c0_1 = {
+static const struct clkgen_pll_data st_pll3200c32_cx_1 = {
 	/* 407 C0 PLL1 */
 	.pdn_status	= CLKGEN_FIELD(0x2c8,	0x1,			8),
 	.locked_status	= CLKGEN_FIELD(0x2c8,	0x1,			24),
@@ -624,12 +624,12 @@ static const struct of_device_id c32_pll_of_match[] = {
 		.data = &st_pll3200c32_407_a0,
 	},
 	{
-		.compatible = "st,stih407-plls-c32-c0_0",
-		.data = &st_pll3200c32_407_c0_0,
+		.compatible = "st,plls-c32-cx_0",
+		.data = &st_pll3200c32_cx_0,
 	},
 	{
-		.compatible = "st,stih407-plls-c32-c0_1",
-		.data = &st_pll3200c32_407_c0_1,
+		.compatible = "st,plls-c32-cx_1",
+		.data = &st_pll3200c32_cx_1,
 	},
 	{
 		.compatible = "st,stih407-plls-c32-a9",
-- 
1.9.1



From j.anaszewski at samsung.com  Wed Aug 19 01:49:08 2015
From: j.anaszewski at samsung.com (Jacek Anaszewski)
Date: Wed, 19 Aug 2015 10:49:08 +0200
Subject: [PATCH v2 19/21] leds: leds-pasic3: Add support for PASIC3 LED
 controller
In-Reply-To: <55D3A832.90705@tul.cz>
References: <cover.1439843482.git.petr.cvek@tul.cz> <55D25ADC.10703@tul.cz>
 <55D30875.3090103@samsung.com> <55D3A832.90705@tul.cz>
Message-ID: <55D44304.1000503@samsung.com>

On 08/18/2015 11:48 PM, Petr Cvek wrote:
> Dne 18.8.2015 v 12:27 Jacek Anaszewski napsal(a):
>> Hi Petr,
>>
>> On 08/18/2015 12:06 AM, Petr Cvek wrote:
>>> +/*
>>> + * AIC3 (or PASIC3) LED driver for HTC Magician/Alpine/.. (not Compaq ASIC3)
>>
>> s/AIC3/ASIC3/
>>
>> I am a bit confused. What's the relation between ASIC3 and PASIC3?
>
> Actually both drivers should be renamed to AIC3 (or AIC only, as there is version 2). "HTC_AIC3" is written on the chip and "pasic3" is confusing with compaq asic3 driver, which claims in Kconfig help to be compatible with HTC machines. Compaq ASIC3 has much more functionality and from brief look it seems it has 16 bit registers (HTC_AIC3 has only LEDs, RESET and DS1WM and has 8 bit registers).

I see, thanks for the explanation.

>>> +spinlock_t lock;
>>
>> Please move it to the struct pasic3_leds_data.
>
> OK
>
>>
>>> +
>>> +static void brightness_set(struct led_classdev *cdev,
>>> +    enum led_brightness value)
>>> +{
>>> +    struct platform_device *pdev = to_platform_device(cdev->dev->parent);
>>> +    struct pasic3_led *led = dev_get_platdata(cdev->dev);
>>> +    struct pasic3_leds_pdata *pdata = dev_get_platdata(&pdev->dev);
>>> +    unsigned long flags;
>>> +    u8 val;
>>> +
>>> +    spin_lock_irqsave(&lock, flags);
>>> +
>>> +    if (value == LED_OFF) {
>>> +        val = pasic3_read_register(pdata->mfd_dev, PASIC3_CH_CONTROL);
>>> +        pasic3_write_register(pdata->mfd_dev, PASIC3_CH_CONTROL,
>>> +            val & ~(led->bit_blink_en | led->bit_force_on));
>>> +
>>> +        val = pasic3_read_register(pdata->mfd_dev, PASIC3_MASK_A);
>>> +        pasic3_write_register(pdata->mfd_dev, PASIC3_MASK_A,
>>> +            val & ~led->bit_mask);
>>> +
>>> +        if (pdata->power_gpio) {
>>> +            pdata->power_gpio_users--;
>>
>> Now it is possible that power_gpio_users will have negative value.
>> You should check the value before decrementing it.
>
>> Now you are setting power_gpio_users to 1 each time brightness is set,
>> whereas it should be set to 1 only if it was 0.
>>
>> This could be changed to:
>>
>> if (pdata->power_gpio_users == 0)
>>      gpio_set_value(pdata->power_gpio, 1);
>>
>> pdata->power_gpio_users++;
>
>>
>> Shouldn't you check if also power_gpio state doesn't need to be altered
>> here?
>>
>
>
> Can the same brightness_set() function be called multiple times with same value (like LED_ON)?

Yes it can. LED core doesn't check if the value isn't already set.

> I think I will change it to a different code altogether, power_gpio is shared variable and power can be shut off when two of three leds are disabled (green LED does not use power_gpio). Something like:
>
> enabled_leds |= BIT(hw_num);
>
> or
>
> enabled_leds &= ~BIT(hw_num);

OK, we'll discuss that after you'll submit the next version.

>
>>> +        ret = gpio_request(pdata->power_gpio,
>>> +            "Red-Blue LED Power");
>>
>> Please use devm_gpio_request. Then you will not need pasic3_led_remove.
>>
>
> OK
>
>


-- 
Best Regards,
Jacek Anaszewski


From andriy.shevchenko at linux.intel.com  Wed Aug 19 01:51:06 2015
From: andriy.shevchenko at linux.intel.com (Andy Shevchenko)
Date: Wed, 19 Aug 2015 11:51:06 +0300
Subject: [PATCH v3 2/2] spi: dw: Allow interface drivers to limit data
 I/O to word sizes
In-Reply-To: <1439929313-4948-3-git-send-email-michael@smart-africa.com>
References: <1439929313-4948-1-git-send-email-michael@smart-africa.com>
 <1439929313-4948-3-git-send-email-michael@smart-africa.com>
Message-ID: <1439974266.23314.8.camel@linux.intel.com>

On Tue, 2015-08-18 at 22:21 +0200, Michael van der Westhuizen wrote:
> The commit dd11444327ce ("spi: dw-spi: Convert 16bit accesses to 
> 32bit
> accesses") changed all 16bit accesses in the DW_apb_ssi driver to 
> 32bit.
> This, unfortunately, breaks data register access on picoXcell, where 
> the
> DW IP needs data register accesses to be word accesses (all other
> accesses appear to be OK).
> 
> This change introduces a new master variable to allow interface 
> drivers
> to specify that 16bit data transfer I/O is required.  This change 
> also
> introduces the ability to set this variable via device tree bindings 
> in
> the MMIO interface driver.  Both the core and the MMIO interface 
> driver
> default to the current 32bit behaviour.
> 
> Before this change, on a picoXcell pc3x3:
>  spi_master spi32766: interrupt_transfer: fifo overrun/underrun
>  m25p80 spi32766.0: error -5 reading 9f
>  m25p80: probe of spi32766.0 failed with error -5
> 
> After this change:
>  m25p80 spi32766.0: m25p40 (512 Kbytes)

Reviewed-by: Andy Shevchenko <andriy.shevchenko at linux.intel.com>

> 
> Fixes: dd11444327ce ("spi: dw-spi: Convert 16bit accesses to 32bit 
> accesses")
> Signed-off-by: Michael van der Westhuizen <michael at smart-africa.com>
> ---
> Changes in v3:
>   - Rename the DT property as requested by Rob Herring.
> 
> Changes in v2:
>   - Incorporate review feedback from Andy Shevchenko
>     - Rework the DT bindings to accept an I/O register width as a
>       number of bytes rather than using a boolean spefifying the
>       width preference to be 16 bits.
>     - Add data register access wrapper functions and use them when
>       reading and writing the data register.
> 
>  drivers/spi/spi-dw-mmio.c |  3 +++
>  drivers/spi/spi-dw.c      |  4 ++--
>  drivers/spi/spi-dw.h      | 35 +++++++++++++++++++++++++++++++++++
>  3 files changed, 40 insertions(+), 2 deletions(-)
> 
> diff --git a/drivers/spi/spi-dw-mmio.c b/drivers/spi/spi-dw-mmio.c
> index eb03e12..7edede6 100644
> --- a/drivers/spi/spi-dw-mmio.c
> +++ b/drivers/spi/spi-dw-mmio.c
> @@ -74,6 +74,9 @@ static int dw_spi_mmio_probe(struct platform_device 
> *pdev)
>  
>  	dws->max_freq = clk_get_rate(dwsmmio->clk);
>  
> +	of_property_read_u32(pdev->dev.of_node, "reg-io-width",
> +			     &dws->reg_io_width);
> +
>  	num_cs = 4;
>  
>  	if (pdev->dev.of_node)
> diff --git a/drivers/spi/spi-dw.c b/drivers/spi/spi-dw.c
> index 8d67d03..4fbfcdc 100644
> --- a/drivers/spi/spi-dw.c
> +++ b/drivers/spi/spi-dw.c
> @@ -194,7 +194,7 @@ static void dw_writer(struct dw_spi *dws)
>  			else
>  				txw = *(u16 *)(dws->tx);
>  		}
> -		dw_writel(dws, DW_SPI_DR, txw);
> +		dw_write_io_reg(dws, DW_SPI_DR, txw);
>  		dws->tx += dws->n_bytes;
>  	}
>  }
> @@ -205,7 +205,7 @@ static void dw_reader(struct dw_spi *dws)
>  	u16 rxw;
>  
>  	while (max--) {
> -		rxw = dw_readl(dws, DW_SPI_DR);
> +		rxw = dw_read_io_reg(dws, DW_SPI_DR);
>  		/* Care rx only if the transfer's original "rx" is 
> not null */
>  		if (dws->rx_end - dws->len) {
>  			if (dws->n_bytes == 1)
> diff --git a/drivers/spi/spi-dw.h b/drivers/spi/spi-dw.h
> index 6c91391..b75ed32 100644
> --- a/drivers/spi/spi-dw.h
> +++ b/drivers/spi/spi-dw.h
> @@ -109,6 +109,7 @@ struct dw_spi {
>  	u32			fifo_len;	/* depth of the FIFO 
> buffer */
>  	u32			max_freq;	/* max bus freq 
> supported */
>  
> +	u32			reg_io_width;	/* DR I/O width in 
> bytes */
>  	u16			bus_num;
>  	u16			num_cs;		/* supported 
> slave numbers */
>  
> @@ -145,11 +146,45 @@ static inline u32 dw_readl(struct dw_spi *dws, 
> u32 offset)
>  	return __raw_readl(dws->regs + offset);
>  }
>  
> +static inline u16 dw_readw(struct dw_spi *dws, u32 offset)
> +{
> +	return __raw_readw(dws->regs + offset);
> +}
> +
>  static inline void dw_writel(struct dw_spi *dws, u32 offset, u32 
> val)
>  {
>  	__raw_writel(val, dws->regs + offset);
>  }
>  
> +static inline void dw_writew(struct dw_spi *dws, u32 offset, u16 
> val)
> +{
> +	__raw_writew(val, dws->regs + offset);
> +}
> +
> +static inline u32 dw_read_io_reg(struct dw_spi *dws, u32 offset)
> +{
> +	switch (dws->reg_io_width) {
> +	case 2:
> +		return dw_readw(dws, offset);
> +	case 4:
> +	default:
> +		return dw_readl(dws, offset);
> +	}
> +}
> +
> +static inline void dw_write_io_reg(struct dw_spi *dws, u32 offset, 
> u32 val)
> +{
> +	switch (dws->reg_io_width) {
> +	case 2:
> +		dw_writew(dws, offset, val);
> +		break;
> +	case 4:
> +	default:
> +		dw_writel(dws, offset, val);
> +		break;
> +	}
> +}
> +
>  static inline void spi_enable_chip(struct dw_spi *dws, int enable)
>  {
>  	dw_writel(dws, DW_SPI_SSIENR, (enable ? 1 : 0));

-- 
Andy Shevchenko <andriy.shevchenko at linux.intel.com>
Intel Finland Oy


From wens at csie.org  Wed Aug 19 01:57:22 2015
From: wens at csie.org (Chen-Yu Tsai)
Date: Wed, 19 Aug 2015 16:57:22 +0800
Subject: [PATCH] ARM: dts: sun6i: hummingbird: Add missing pinmux setting for
 gmac phy reset
Message-ID: <1439974642-12091-1-git-send-email-wens@csie.org>

Signed-off-by: Chen-Yu Tsai <wens at csie.org>
---
 arch/arm/boot/dts/sun6i-a31-hummingbird.dts | 9 ++++++++-
 1 file changed, 8 insertions(+), 1 deletion(-)

diff --git a/arch/arm/boot/dts/sun6i-a31-hummingbird.dts b/arch/arm/boot/dts/sun6i-a31-hummingbird.dts
index d0cfadac0691..06d9391ca30e 100644
--- a/arch/arm/boot/dts/sun6i-a31-hummingbird.dts
+++ b/arch/arm/boot/dts/sun6i-a31-hummingbird.dts
@@ -73,7 +73,7 @@
 
 &gmac {
 	pinctrl-names = "default";
-	pinctrl-0 = <&gmac_pins_rgmii_a>;
+	pinctrl-0 = <&gmac_pins_rgmii_a>, <&gmac_phy_reset_pin_hummingbird>;
 	phy = <&phy1>;
 	phy-mode = "rgmii";
 	snps,reset-gpio = <&pio 0 21 GPIO_ACTIVE_HIGH>;
@@ -146,6 +146,13 @@
 };
 
 &pio {
+	gmac_phy_reset_pin_hummingbird: gmac_phy_reset_pin at 0 {
+		allwinner,pins = "PA21";
+		allwinner,function = "gpio_out";
+		allwinner,drive = <SUN4I_PINCTRL_10_MA>;
+		allwinner,pull = <SUN4I_PINCTRL_NO_PULL>;
+	};
+
 	mmc0_cd_pin_hummingbird: mmc0_cd_pin at 0 {
 		allwinner,pins = "PA8";
 		allwinner,function = "gpio_in";
-- 
2.5.0



From catalin.marinas at arm.com  Wed Aug 19 02:13:06 2015
From: catalin.marinas at arm.com (Catalin Marinas)
Date: Wed, 19 Aug 2015 10:13:06 +0100
Subject: [PATCH v2] arm64 Kconfig: Move LIST_POISON to a safe value
In-Reply-To: <1439927410-15522-1-git-send-email-jeffv@google.com>
References: <1439927410-15522-1-git-send-email-jeffv@google.com>
Message-ID: <20150819091306.GC21913@e104818-lin.cambridge.arm.com>

On Tue, Aug 18, 2015 at 12:50:10PM -0700, Jeff Vander Stoep wrote:
> Move the poison pointer offset to 0xdead000000000000, a
> recognized value that is not mappable by user-space exploits.
> 
> Signed-off-by: Thierry Strudel <tstrudel at google.com>
> Signed-off-by: Jeff Vander Stoep <jeffv at google.com>
> ---

Acked-by: Catalin Marinas <catalin.marinas at arm.com>


From maxime.ripard at free-electrons.com  Wed Aug 19 02:13:58 2015
From: maxime.ripard at free-electrons.com (Maxime Ripard)
Date: Wed, 19 Aug 2015 11:13:58 +0200
Subject: [PATCH v2 1/7] clk: Add a basic factor clock
In-Reply-To: <20150811213041.31346.58562@quantum>
References: <1432241646-9511-1-git-send-email-maxime.ripard@free-electrons.com>
 <1432241646-9511-2-git-send-email-maxime.ripard@free-electrons.com>
 <CAGb2v64rqRC24wPWz5xYZv=w2QAtsCb-pd76Qynkb5NBCptXhQ@mail.gmail.com>
 <20150523074930.GI8557@lukather> <20150724000001.642.84690@quantum>
 <20150724065017.GJ2373@lukather> <20150724182619.642.11590@quantum>
 <20150725073925.GK2564@lukather>
 <20150811213041.31346.58562@quantum>
Message-ID: <20150819091358.GB30520@lukather>

On Tue, Aug 11, 2015 at 02:30:41PM -0700, Michael Turquette wrote:
> > > The real problem with these basic clock types is that they are an
> > > abstraction layer at the wrong level. Each clock type implements both
> > > the policy of a given clock, as well as the machine-specific details.
> > > For example clk-divider.c has made some assumptions in the past about
> > > rounding the rate, or how to calculate the best divider; this is a
> > > matter of policy and is useful on its own. But additionally that same
> > > policy is glued to a specific implementation: memory-mapped register
> > > controls for a clock divider.
> > > 
> > > The I/O accessor stuff needs to be addressed at some point.  Currently
> > > the basic clock types assume specific patterns of access to
> > > memory-mapped clock registers. There are lots of other clock controls
> > > out there that talk to firmware, or over i2c, or whatever. The amount of
> > > code that has to be copy/pasted for each different type of access is
> > > 100%; i.e. we do not have abstractions at the right level such as
> > > .get_best_div(struct clk_hw *hw, unsigned long rate).
> > > 
> > > What I would like to see in time is a re-usable layer for clock policy
> > > (e.g. common rules for how dividers or multipliers should behave), and
> > > then have that sit on top of the machine-specific callbacks that
> > > directly touch the hardware, such as the .get_best_div callback above.
> > 
> > Can't that be solved by moving to regmap using Matthias' patches, or
> > at least the IO method abstraction?
> 
> I need to look at those patches again, but I do not think they address
> the problem I described above: abstraction at the wrong level (or more
> specifically, combining two abstract layers into one).

Well, maybe I'm missing something, but you end up with this patch with
the clock driver allocating the regmap, and passing it to the generic
part of the clock framework, that will only do regmap calls and not
care anymore about what kind of accesses it is (the point of regmap
being the abstraction).

Isn't it what you were looking for?

> I'll have more bandwidth to look at this problem after the next merge
> window. The clk framework is slowly be rewritten in bits and pieces here
> on the list (shh don't tell anybody) and this is on my radar and
> Stephen's.

Ok, i'll resend it after the merge window then.

Maxime

-- 
Maxime Ripard, Free Electrons
Embedded Linux, Kernel and Android engineering
http://free-electrons.com
-------------- next part --------------
A non-text attachment was scrubbed...
Name: signature.asc
Type: application/pgp-signature
Size: 819 bytes
Desc: Digital signature
URL: <http://lists.infradead.org/pipermail/linux-arm-kernel/attachments/20150819/4a3c9aeb/attachment.sig>

From maxime.ripard at free-electrons.com  Wed Aug 19 02:15:00 2015
From: maxime.ripard at free-electrons.com (Maxime Ripard)
Date: Wed, 19 Aug 2015 11:15:00 +0200
Subject: [PATCH v2 5/7] ARM: sun8i: Add clock indices
In-Reply-To: <CAGb2v64nvA1K=Ya7_99-2G1LtFjcuj+qQbO1GJaqsL+yPF+Xdw@mail.gmail.com>
References: <1438364782-3968-1-git-send-email-maxime.ripard@free-electrons.com>
 <1438364782-3968-6-git-send-email-maxime.ripard@free-electrons.com>
 <CAGb2v64nvA1K=Ya7_99-2G1LtFjcuj+qQbO1GJaqsL+yPF+Xdw@mail.gmail.com>
Message-ID: <20150819091500.GC30520@lukather>

Hi Chen-Yu,

On Sat, Aug 08, 2015 at 12:21:17AM +0800, Chen-Yu Tsai wrote:
> On Sat, Aug 1, 2015 at 1:46 AM, Maxime Ripard
> <maxime.ripard at free-electrons.com> wrote:
> > The A23 and A33 gates have a non continuous set of clock IDs that are
> > valid. Add the clock-indices property to the DT to express this.
> >
> > Signed-off-by: Maxime Ripard <maxime.ripard at free-electrons.com>
> > ---
> >  arch/arm/boot/dts/sun8i-a23-a33.dtsi | 15 +++++++++++++++
> >  1 file changed, 15 insertions(+)
> >
> > diff --git a/arch/arm/boot/dts/sun8i-a23-a33.dtsi b/arch/arm/boot/dts/sun8i-a23-a33.dtsi
> > index 7abd0ae3143d..c318c770b6c1 100644
> > --- a/arch/arm/boot/dts/sun8i-a23-a33.dtsi
> > +++ b/arch/arm/boot/dts/sun8i-a23-a33.dtsi
> > @@ -180,6 +180,15 @@
> >                         compatible = "allwinner,sun8i-a23-ahb1-gates-clk";
> >                         reg = <0x01c20060 0x8>;
> >                         clocks = <&ahb1>;
> > +                       clock-indices = <1>, <6>,
> 
> Turns out the A33 (and I assume the same with the A23) has
> an ahb1 clock gate for the Security System at clock-index <5>.
> 
> This is found in the updated A33 user manual.
> 
> > +                                       <8>, <9>, <10>,
> > +                                       <13>, <14>,
> > +                                       <19>, <20>,
> > +                                       <21>, <24>, <26>,
> > +                                       <29>, <32>, <36>,
> > +                                       <40>, <44>, <46>,
> > +                                       <52>, <54>,
> 
> <53> is ahb1 clock gate for msgbox, again found in A33 manual.
> 
> > +                                       <57>;
> 
> <58> is ahb1 clock gate for SAT, which seems to be part of the
> display pipeline.
> 
> >                         clock-output-names = "ahb1_mipidsi", "ahb1_dma",
> >                                         "ahb1_mmc0", "ahb1_mmc1", "ahb1_mmc2",
> >                                         "ahb1_nand", "ahb1_sdram",
> > @@ -196,6 +205,8 @@
> >                         compatible = "allwinner,sun8i-a23-apb1-gates-clk";
> >                         reg = <0x01c20068 0x4>;
> >                         clocks = <&apb1>;
> > +                       clock-indices = <0>, <5>,
> > +                                       <12>, <13>;
> >                         clock-output-names = "apb1_codec", "apb1_pio",
> >                                         "apb1_daudio0", "apb1_daudio1";
> >                 };
> > @@ -213,6 +224,10 @@
> >                         compatible = "allwinner,sun8i-a23-apb2-gates-clk";
> >                         reg = <0x01c2006c 0x4>;
> >                         clocks = <&apb2>;
> > +                       clock-indices = <0>, <1>,
> > +                                       <2>, <16>,
> > +                                       <17>, <18>,
> > +                                       <19>, <20>;
> >                         clock-output-names = "apb2_i2c0", "apb2_i2c1",
> >                                         "apb2_i2c2", "apb2_uart0",
> >                                         "apb2_uart1", "apb2_uart2",
> > --
> > 2.4.6
> >
> 
> Not sure if you want to add the clocks I mentioned together
> in this patch, or do a separate patch.
> 
> The rest look good.

Thanks for your input, I'll send some new patches to deal with this.

-- 
Maxime Ripard, Free Electrons
Embedded Linux, Kernel and Android engineering
http://free-electrons.com
-------------- next part --------------
A non-text attachment was scrubbed...
Name: signature.asc
Type: application/pgp-signature
Size: 819 bytes
Desc: Digital signature
URL: <http://lists.infradead.org/pipermail/linux-arm-kernel/attachments/20150819/a2f3d6ad/attachment-0001.sig>

From thierry.reding at gmail.com  Wed Aug 19 02:14:00 2015
From: thierry.reding at gmail.com (Thierry Reding)
Date: Wed, 19 Aug 2015 11:14:00 +0200
Subject: [GIT PULL 9/9] ARM: tegra: Default configuration updates for
 v4.3-rc1
In-Reply-To: <CANMBJr7PKy-eCcB3HiBajpApHS_BYPa7xfKjTqV4o8Z1hwY99A@mail.gmail.com>
References: <1439563720-13189-1-git-send-email-thierry.reding@gmail.com>
 <1439563720-13189-10-git-send-email-thierry.reding@gmail.com>
 <CANMBJr7PKy-eCcB3HiBajpApHS_BYPa7xfKjTqV4o8Z1hwY99A@mail.gmail.com>
Message-ID: <20150819091358.GA26627@ulmo>

On Tue, Aug 18, 2015 at 03:30:41PM -0700, Tyler Baker wrote:
> Hi Theirry,
> 
> On 14 August 2015 at 07:48, Thierry Reding <thierry.reding at gmail.com> wrote:
> > Hi ARM SoC maintainers,
> >
> > The following changes since commit d770e558e21961ad6cfdf0ff7df0eb5d7d4f0754:
> >
> >   Linux 4.2-rc1 (2015-07-05 11:01:52 -0700)
> >
> > are available in the git repository at:
> >
> >   git://git.kernel.org/pub/scm/linux/kernel/git/tegra/linux.git tags/tegra-for-4.3-defconfig
> >
> > for you to fetch changes up to 258d9bc5e77fa40e290a0bd480d5349224374480:
> >
> >   ARM: tegra: Update multi_v7_defconfig (2015-08-14 16:26:00 +0200)
> >
> > Thanks,
> > Thierry
> >
> > ----------------------------------------------------------------
> > ARM: tegra: Default configuration updates for v4.3-rc1
> >
> > Enable the GK20A GPU (via the Nouveau driver) and CPU frequency scaling
> > on Tegra124.
> >
> > ----------------------------------------------------------------
> > Thierry Reding (1):
> >       ARM: tegra: Update multi_v7_defconfig
> 
> The kernelci.org bot recently reported jetson-tk1 boot failures[1][2]
> in next-20150818, only when booting the mult_v7_defconfig kernels. I
> bisected[3] these boot failure down to this commit, it didn't cleanly
> revert, so I manually removed that options this patch added, and my
> jetson-tk1 booted again. Digging a bit further, if I apply the patch
> below to next-20150818, my jetson-tk1 boots.

I'm not able to reproduce this here. Building next-20150818 with
multi_v7_config and booting the resulting kernel works just fine.

> diff --git a/arch/arm/configs/multi_v7_defconfig
> b/arch/arm/configs/multi_v7_defconfig
> index b2facab..a285afe 100644
> --- a/arch/arm/configs/multi_v7_defconfig
> +++ b/arch/arm/configs/multi_v7_defconfig
> @@ -468,7 +468,6 @@ CONFIG_FRAMEBUFFER_CONSOLE_ROTATION=y
>  CONFIG_SOUND=m
>  CONFIG_SND=m
>  CONFIG_SND_DYNAMIC_MINORS=y
> -CONFIG_SND_HDA_TEGRA=m
>  CONFIG_SND_HDA_INPUT_BEEP=y
>  CONFIG_SND_HDA_PATCH_LOADER=y
>  CONFIG_SND_HDA_CODEC_REALTEK=m

lsmod output confirms that snd-hda-tegra.ko was loaded:

	# lsmod
	Module                  Size  Used by
	snd_soc_tegra30_i2s     5591  2 
	snd_soc_tegra_pcm       1184  1 snd_soc_tegra30_i2s
	snd_hda_tegra           4771  0 
	snd_soc_rt5640         56972  1 
	snd_soc_tegra_rt5640     3960  0 
	snd_hda_codec          76398  1 snd_hda_tegra
	snd_soc_rl6231          1897  1 snd_soc_rt5640
	snd_soc_tegra_utils     2825  1 snd_soc_tegra_rt5640
	snd_hda_core           26151  2 snd_hda_codec,snd_hda_tegra
	snd_soc_core          119213  4 snd_soc_tegra_pcm,snd_soc_rt5640,snd_soc_tegra_rt5640,snd_soc_tegra30_i2s
	snd_compress            7114  1 snd_soc_core
	snd_pcm_dmaengine       2943  1 snd_soc_core
	snd_pcm                67835  6 snd_soc_rt5640,snd_soc_core,snd_hda_codec,snd_hda_tegra,snd_pcm_dmaengine,snd_hda_core
	snd_timer              16881  1 snd_pcm
	snd                    41480  6 snd_soc_core,snd_timer,snd_pcm,snd_hda_codec,snd_hda_tegra,snd_compress
	soundcore                858  1 snd
	snd_soc_tegra30_ahub     8747  1 snd_soc_tegra30_i2s
	nouveau              1217903  0 
	tegra_devfreq           5389  0 
	ttm                    65073  1 nouveau

> This isn't where the story ends unfortunately. The collabora lab also
> has a jetson-tk1, booted in the same manner, which boots next-20150818
> fine[4]. The only differences I can spot in the two boot logs is that
> the collabora board is using an older version of u-boot, where as my
> board is using a newer version. U-Boot 2015.01-00231-gab77f24-dirty
> (Good) vs U-Boot 2015.07-00130-gb217c89 (Bad).

I don't have either of those commits in any of the U-Boot trees I have.
Perhaps whatever tree this comes from has local patches that cause the
breakage? The version that I use a recent upstream U-Boot with some
local patches, none of which should impact Jetson TK1 in any way. Just
to make sure I tried running latest origin/master, which identifies
thusly:

	U-Boot 2015.10-rc2-00040-g0f9258228e2b

And that boots next-20150818 fine.

If you can point me at the source for the version that you use I may be
able to find something that could cause this.

>                                                I've also noticed some
> angry udev messages after the modules probe in userspace present in
> both boot logs that look suspicious.
> 
> [   70.469914] udevd[108]: worker [113] /devices/soc0/70030000.hda is
> taking a long time
> [   70.479849] udevd[108]: worker [115] /devices/soc0/70300000.ahub is
> taking a long time
> [   70.490769] udevd[108]: worker [117] /devices/soc0/sound is taking
> a long time

These look suspicious indeed. Unfortunately I don't see those in the
boot log on my setup either. Then again, you seem to be using Eudev
2.1.1, whereas I use the one shipped with systemd 219, so this could
also be some sort of weird userspace issue.

From the logs it further seems like you've configured the root to be
on NFS, but the logs never show NFS to be mounted. Perhaps that's
because you're booting into a ramdisk rather than a full root file-
system.

> FWIW, When I went searching for this patch, I couldn't find it on any
> of the mailing lists. The only reference to this patch was from this
> pull request, thus why I'm reporting the issue here. :)

That's because it's merely sync'ing up the multi_v7_defconfig changes
with tegra_defconfig that I forgot to submit for v4.2. I didn't think it
necessary to send out a separate patch for that.

> Anyways, let me know if you can reproduce this issue, and/or can think
> of a reason this might may be causing trouble.

Like I said, if you can point me at the U-Boot sources I can take a look
if anything jumps out. I've also noticed that the initial ramdisks in
both boot logs that you linked to have a slightly different size. But
they use the same Eudev version, so I suspect that that's unrelated.

Thierry
-------------- next part --------------
A non-text attachment was scrubbed...
Name: signature.asc
Type: application/pgp-signature
Size: 819 bytes
Desc: not available
URL: <http://lists.infradead.org/pipermail/linux-arm-kernel/attachments/20150819/908f330e/attachment.sig>

From catalin.marinas at arm.com  Wed Aug 19 02:15:53 2015
From: catalin.marinas at arm.com (Catalin Marinas)
Date: Wed, 19 Aug 2015 10:15:53 +0100
Subject: [PATCH 2/2] arm64: set MAX_MEMBLOCK_ADDR according to linear
 region size
In-Reply-To: <CAKv+Gu8hBCtxUHqBwCjfiati7kbWrq314_mTjRvzf7ZnjWXsuw@mail.gmail.com>
References: <1439890482-20798-1-git-send-email-ard.biesheuvel@linaro.org>
 <1439890482-20798-3-git-send-email-ard.biesheuvel@linaro.org>
 <20150818100018.GA11021@arm.com>
 <CAKv+Gu-YDEKSrkSG2fywgrHBB3Hao+jodknmCAkFCWqG4OpXCA@mail.gmail.com>
 <20150818173938.GH11571@e104818-lin.cambridge.arm.com>
 <CAKv+Gu8hBCtxUHqBwCjfiati7kbWrq314_mTjRvzf7ZnjWXsuw@mail.gmail.com>
Message-ID: <20150819091553.GD21913@e104818-lin.cambridge.arm.com>

On Tue, Aug 18, 2015 at 07:44:59PM +0200, Ard Biesheuvel wrote:
> On 18 August 2015 at 19:39, Catalin Marinas <catalin.marinas at arm.com> wrote:
> > On Tue, Aug 18, 2015 at 12:04:27PM +0200, Ard Biesheuvel wrote:
> >> On 18 August 2015 at 12:00, Will Deacon <will.deacon at arm.com> wrote:
> >> > On Tue, Aug 18, 2015 at 10:34:42AM +0100, Ard Biesheuvel wrote:
> >> >> The linear region size of a 39-bit VA kernel is only 256 GB, which
> >> >> may be insufficient to cover all of system RAM, even on platforms
> >> >> that have much less than 256 GB of memory but which is laid out
> >> >> very sparsely.
> >> >>
> >> >> So make sure we clip the memory we will not be able to map before
> >> >> installing it into the memblock memory table, by setting
> >> >> MAX_MEMBLOCK_ADDR accordingly.
> >> >>
> >> >> Signed-off-by: Ard Biesheuvel <ard.biesheuvel at linaro.org>
> >> >> ---
> >> >>  arch/arm64/include/asm/memory.h | 8 ++++++++
> >> >>  1 file changed, 8 insertions(+)
> >> >>
> >> >> diff --git a/arch/arm64/include/asm/memory.h b/arch/arm64/include/asm/memory.h
> >> >> index f800d45ea226..44a59c20e773 100644
> >> >> --- a/arch/arm64/include/asm/memory.h
> >> >> +++ b/arch/arm64/include/asm/memory.h
> >> >> @@ -114,6 +114,14 @@ extern phys_addr_t               memstart_addr;
> >> >>  #define PHYS_OFFSET          ({ memstart_addr; })
> >> >>
> >> >>  /*
> >> >> + * The maximum physical address that the linear direct mapping
> >> >> + * of system RAM can cover. (PAGE_OFFSET can be interpreted as
> >> >> + * a 2's complement signed quantity and negated to derive the
> >> >> + * maximum size of the linear mapping.)
> >> >> + */
> >> >> +#define MAX_MEMBLOCK_ADDR    ({ memstart_addr - PAGE_OFFSET - 1; })
> >> >
> >> > If we initialised memory_limit to this value and changed early_mem to
> >> > use min (i.e. only restrict the limit further), would that avoid the
> >> > need to change the of code? It looks like PPC uses
> >> > memblock_enforce_memory_limit for similar reasons.
> >>
> >> Yes, that would be yet another way of doing things. But since Catalin
> >> explicitly requested that both checks (i.e., bottom end and top end)
> >> occur in the same place, and indicated his preference not to override
> >> early_init_dt_add_memory_arch() if we can avoid it, the only way is to
> >> hack it in there.
> >
> > Talking to Will, we decided to go for a quick fix with cc stable that
> > does something like:
> >
> >         memblock_enforce_memory_limit(min(memory_limit, ~PAGE_OFFSET));
> 
> ~PAGE_OFFSET + 1 ?

Yes.

-- 
Catalin


From Liviu.Dudau at arm.com  Wed Aug 19 02:28:16 2015
From: Liviu.Dudau at arm.com (Liviu Dudau)
Date: Wed, 19 Aug 2015 10:28:16 +0100
Subject: [PATCH 2/4] drm: Add support for ARM's HDLCD controller.
In-Reply-To: <CACvgo53KWsC1ZeYYF2bW=4=BeuexaEgBHT=+h2U60iS9nYvYpw@mail.gmail.com>
References: <1438784892-27888-1-git-send-email-Liviu.Dudau@arm.com>
 <1438784892-27888-3-git-send-email-Liviu.Dudau@arm.com>
 <CACvgo537C6SRfhMTNoE4cSLJukcXuKLvt1TRykynX--ybEhmaQ@mail.gmail.com>
 <20150817151547.GA1020@e106497-lin.cambridge.arm.com>
 <CACvgo53KWsC1ZeYYF2bW=4=BeuexaEgBHT=+h2U60iS9nYvYpw@mail.gmail.com>
Message-ID: <20150819092816.GF1020@e106497-lin.cambridge.arm.com>

On Tue, Aug 18, 2015 at 05:41:59PM +0100, Emil Velikov wrote:
> On 17 August 2015 at 16:15, Liviu Dudau <Liviu.Dudau at arm.com> wrote:
> > On Sun, Aug 16, 2015 at 09:56:33AM +0100, Emil Velikov wrote:
> >> Hi Liviu,
> >
> > Hi Emil,
> >
> >>
> >> On 5 August 2015 at 15:28, Liviu Dudau <Liviu.Dudau at arm.com> wrote:
> >> > The HDLCD controller is a display controller that supports resolutions
> >> > up to 4096x4096 pixels. It is present on various development boards
> >> > produced by ARM Ltd and emulated by the latest Fast Models from the
> >> > company.
> >> >
> >> I believe there is a unofficial requirement(?) for new drm drivers to
> >> use atomic modesetting. Not 100% sure on this one though. The
> >> following drivers: tegra, msm, rcar-du, i915, and Daniel's blog [1]
> >> [2] cat provide some information on the topic.
> >
> > I am also interested to know if this is a requirement or not.
> > Thanks for the pointers, I will review them again to see if I did miss
> > anything. I remember reading them at the beginning of the year but probably
> > the Christmas haze did not clear enough when I did.
> >
> There was a similar question from the freescale dcu people [1]. I
> believe that the answer still applies.
> 
> [1] http://lists.freedesktop.org/archives/dri-devel/2015-March/078689.html
> 
> >>
> >> The driver seems to has has a bit of dead code guarded by
> >> HDLCD_*_UNDERRUN. Perhaps these macros should become build or runtime
> >> switch(es) ?
> >
> > There is a comment in hdlcd_drv.h explaining what HDLCD_SHOW_UNDERRUN can
> > be used for. As for HDLCD_COUNT_BUFFERUNDERRUNS, you are right, it's dead
> > code from the earlier debugging code that got removed before submission.
> > I will correct that.
> >
> I haven't seen other drm drivers follow the "set a macro that is
> documented in a header and rebuild" approach. Devs either add a CONFIG
> option for it, or expose it as a module parameter. IIRC the nouveau
> driver does even more - it enables the underrun machinery
> unconditionally.

Adding a module parameter probably makes more sense, I will look into that.

> 
> >>
> >> Most DRM drivers do not threat dma, bus_error, vsync and/or underrun
> >> interrupts as debug functionality. They are of limited use in this
> >> driver, presently, yet the CONFIG_DEBUG_FS guard seems a bit strange
> >> imho.
> >
> > The HDLCD device has only 1 interrupt that can fire and there is no other
> > way to show the reason for the interrupt in the driver. It was useful when
> > debugging underruns and/or vsync issues so I thought it might be useful
> > to keep around. Putting it the other way: if you are going to use this device
> > and the image is not completely rendered I would not be able to give you
> > support to figure out what went wrong without this debugging information.
> > With this in place I can tell the difference between a busy system vs one
> > where the interrupt latency is large.
> >
> Out of curiosity - are there any implications/side-effects from having
> these enabled ?

Having the counters counting the interrupts should not affect the latency and
having the default colour red means parts of the screen will flash with that
colour when the data that was supposed to be there could not be fetched in
time (underrun). Yes, probably not something casual users of the ARM boards
will complain about and a highly visible effect when you have bandwidth
starvation issues.

Best regards,
Liviu

> 
> Thanks,
> Emil
> 

-- 
====================
| I would like to |
| fix the world,  |
| but they're not |
| giving me the   |
 \ source code!  /
  ---------------
    ?\_(?)_/?



From leo.yan at linaro.org  Wed Aug 19 02:37:32 2015
From: leo.yan at linaro.org (Leo Yan)
Date: Wed, 19 Aug 2015 17:37:32 +0800
Subject: [PATCH v1 0/3] mailbox: hisilicon: add Hi6220 mailbox driver
Message-ID: <1439977055-1747-1-git-send-email-leo.yan@linaro.org>

Hi6220 mailbox supports up to 32 channels. Each channel is unidirectional
with a maximum message size of 8 words. I/O is performed using register
access (there is no DMA) and the cell raises an interrupt when messages
are received.

This patch series is to implement Hi6220 mailbox driver. It registers
two channels into framework for communication with MCU, one is tx channel
and another is rx channel. Now mailbox driver is used to send message to
MCU to control dynamic voltage and frequency scaling for CPU, GPU and DDR.

Changes from RFC:
* According to Jassi's review, totally remove the abstract common driver
  layer and only commit driver dedicated for Hi6220
* According to Paul Bolle's review, fix typo issue for Kconfig and remove
  unnecessary dependency with OF and fix minor for mailbox driver
* Refine a little for dts nodes

Leo Yan (3):
  dt-bindings: mailbox: Document Hi6220 mailbox driver
  mailbox: Hi6220: add mailbox driver
  arm64: dts: add Hi6220 mailbox node

 .../bindings/mailbox/hisilicon,hi6220-mailbox.txt  |  57 +++
 arch/arm64/boot/dts/hisilicon/hi6220-hikey.dts     |  20 +-
 arch/arm64/boot/dts/hisilicon/hi6220.dtsi          |   8 +
 drivers/mailbox/Kconfig                            |   8 +
 drivers/mailbox/Makefile                           |   2 +
 drivers/mailbox/hi6220-mailbox.c                   | 513 +++++++++++++++++++++
 6 files changed, 605 insertions(+), 3 deletions(-)
 create mode 100644 Documentation/devicetree/bindings/mailbox/hisilicon,hi6220-mailbox.txt
 create mode 100644 drivers/mailbox/hi6220-mailbox.c

-- 
1.9.1



From leo.yan at linaro.org  Wed Aug 19 02:37:33 2015
From: leo.yan at linaro.org (Leo Yan)
Date: Wed, 19 Aug 2015 17:37:33 +0800
Subject: [PATCH v1 1/3] dt-bindings: mailbox: Document Hi6220 mailbox driver
In-Reply-To: <1439977055-1747-1-git-send-email-leo.yan@linaro.org>
References: <1439977055-1747-1-git-send-email-leo.yan@linaro.org>
Message-ID: <1439977055-1747-2-git-send-email-leo.yan@linaro.org>

Document the new compatible for Hisilicon Hi6220 mailbox driver.

Signed-off-by: Leo Yan <leo.yan at linaro.org>
---
 .../bindings/mailbox/hisilicon,hi6220-mailbox.txt  | 57 ++++++++++++++++++++++
 1 file changed, 57 insertions(+)
 create mode 100644 Documentation/devicetree/bindings/mailbox/hisilicon,hi6220-mailbox.txt

diff --git a/Documentation/devicetree/bindings/mailbox/hisilicon,hi6220-mailbox.txt b/Documentation/devicetree/bindings/mailbox/hisilicon,hi6220-mailbox.txt
new file mode 100644
index 0000000..3dfb0b0
--- /dev/null
+++ b/Documentation/devicetree/bindings/mailbox/hisilicon,hi6220-mailbox.txt
@@ -0,0 +1,57 @@
+Hisilicon Hi6220 Mailbox Driver
+===============================
+
+Hisilicon Hi6220 mailbox supports up to 32 channels. Each channel
+is unidirectional with a maximum message size of 8 words. I/O is
+performed using register access (there is no DMA) and the cell
+raises an interrupt when messages are received.
+
+Mailbox Device Node:
+====================
+
+Required properties:
+--------------------
+- compatible:		Shall be "hisilicon,hi6220-mbox"
+- reg:			Contains the mailbox register address range (base
+			address and length); the first item is for IPC
+			registers, the second item is shared buffer for
+			slots.
+- #mbox-cells		Common mailbox binding property to identify the number
+			of cells required for the mailbox specifier. Should be 1.
+- interrupts:		Contains the interrupt information for the mailbox
+			device. The format is dependent on which interrupt
+			controller the SoCs use.
+
+Example:
+--------
+
+	mailbox: mailbox at F7510000 {
+		#mbox-cells = <1>;
+		compatible = "hisilicon,hi6220-mbox";
+		reg = <0x0 0xF7510000 0x0 0x1000>, /* IPC_S */
+		      <0x0 0x06DFF800 0x0 0x0800>; /* Mailbox */
+		interrupt-parent = <&gic>;
+		interrupts = <0 94 4>;
+	};
+
+
+Mailbox client
+===============
+
+"mboxes" and the optional "mbox-names" (please see
+Documentation/devicetree/bindings/mailbox/mailbox.txt for details). Each value
+of the mboxes property should contain a phandle to the mailbox controller
+device node and second argument is the channel index. It must be 0 (hardware
+support only one channel). The equivalent "mbox-names" property value can be
+used to give a name to the communication channel to be used by the client user.
+
+Example:
+--------
+
+	stub_clock: stub_clock {
+		compatible = "hisilicon,hi6220-stub-clk";
+		hisilicon,hi6220-clk-sram = <&sram>;
+		#clock-cells = <1>;
+		mbox-names = "mbox-tx";
+		mboxes = <&mailbox 1>;
+	};
-- 
1.9.1



From leo.yan at linaro.org  Wed Aug 19 02:37:34 2015
From: leo.yan at linaro.org (Leo Yan)
Date: Wed, 19 Aug 2015 17:37:34 +0800
Subject: [PATCH v1 2/3] mailbox: Hi6220: add mailbox driver
In-Reply-To: <1439977055-1747-1-git-send-email-leo.yan@linaro.org>
References: <1439977055-1747-1-git-send-email-leo.yan@linaro.org>
Message-ID: <1439977055-1747-3-git-send-email-leo.yan@linaro.org>

Add driver for Hi6220 mailbox, the mailbox communicates with MCU; for
sending data, it can support two methods for low level implementation:
one is to use interrupt as acknowledge, another is automatic mode which
without any acknowledge. These two methods have been supported in the
driver. For receiving data, it will depend on the interrupt to notify
the channel has incoming message; enhance rx channel's message queue,
which is based on the code in drivers/mailbox/omap-mailbox.c.

Now mailbox driver is used to send message to MCU to control dynamic
voltage and frequency scaling for CPU, GPU and DDR.

Signed-off-by: Leo Yan <leo.yan at linaro.org>
---
 drivers/mailbox/Kconfig          |   8 +
 drivers/mailbox/Makefile         |   2 +
 drivers/mailbox/hi6220-mailbox.c | 513 +++++++++++++++++++++++++++++++++++++++
 3 files changed, 523 insertions(+)
 create mode 100644 drivers/mailbox/hi6220-mailbox.c

diff --git a/drivers/mailbox/Kconfig b/drivers/mailbox/Kconfig
index e269f08..21b71dd 100644
--- a/drivers/mailbox/Kconfig
+++ b/drivers/mailbox/Kconfig
@@ -70,4 +70,12 @@ config BCM2835_MBOX
 	  the services of the Videocore. Say Y here if you want to use the
 	  BCM2835 Mailbox.
 
+config HI6220_MBOX
+	tristate "Hi6220 Mailbox"
+	depends on ARCH_HISI
+	help
+	  An implementation of the hi6220 mailbox. It is used to send message
+	  between application processors and MCU. Say Y here if you want to build
+	  the Hi6220 mailbox controller driver.
+
 endif
diff --git a/drivers/mailbox/Makefile b/drivers/mailbox/Makefile
index 8e6d822..4ba9f5f 100644
--- a/drivers/mailbox/Makefile
+++ b/drivers/mailbox/Makefile
@@ -13,3 +13,5 @@ obj-$(CONFIG_PCC)		+= pcc.o
 obj-$(CONFIG_ALTERA_MBOX)	+= mailbox-altera.o
 
 obj-$(CONFIG_BCM2835_MBOX)	+= bcm2835-mailbox.o
+
+obj-$(CONFIG_HI6220_MBOX)	+= hi6220-mailbox.o
diff --git a/drivers/mailbox/hi6220-mailbox.c b/drivers/mailbox/hi6220-mailbox.c
new file mode 100644
index 0000000..1b2dc5b
--- /dev/null
+++ b/drivers/mailbox/hi6220-mailbox.c
@@ -0,0 +1,513 @@
+/*
+ * Hisilicon's Hi6220 mailbox driver
+ *
+ * RX channel's message queue is based on the code written in
+ * drivers/mailbox/omap-mailbox.c.
+ *
+ * Copyright (c) 2015 Hisilicon Limited.
+ * Copyright (c) 2015 Linaro Limited.
+ *
+ * Author: Leo Yan <leo.yan at linaro.org>
+ *
+ * This program is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation, version 2 of the License.
+ *
+ * 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/device.h>
+#include <linux/err.h>
+#include <linux/interrupt.h>
+#include <linux/io.h>
+#include <linux/kfifo.h>
+#include <linux/mailbox_controller.h>
+#include <linux/module.h>
+#include <linux/platform_device.h>
+#include <linux/spinlock.h>
+#include <linux/slab.h>
+
+#define HI6220_MBOX_CHAN_MAX		32
+#define HI6220_MBOX_CHAN_NUM		2
+#define HI6220_MBOX_CHAN_SLOT_SIZE	64
+
+#define HI6220_MBOX_RX			0x0
+#define HI6220_MBOX_TX			0x1
+
+/* Mailbox message length: 32 bytes */
+#define HI6220_MBOX_MSG_LEN		32
+
+/* Mailbox kfifo size */
+#define HI6220_MBOX_MSG_FIFO_SIZE	512
+
+/* Status & Mode Register */
+#define HI6220_MBOX_MODE_REG		0x0
+
+#define HI6220_MBOX_STATUS_MASK		(0xF << 4)
+#define HI6220_MBOX_STATUS_IDLE		(0x1 << 4)
+#define HI6220_MBOX_STATUS_TX		(0x2 << 4)
+#define HI6220_MBOX_STATUS_RX		(0x4 << 4)
+#define HI6220_MBOX_STATUS_ACK		(0x8 << 4)
+#define HI6220_MBOX_ACK_CONFIG_MASK	(0x1 << 0)
+#define HI6220_MBOX_ACK_AUTOMATIC	(0x1 << 0)
+#define HI6220_MBOX_ACK_IRQ		(0x0 << 0)
+
+/* Data Registers */
+#define HI6220_MBOX_DATA_REG(i)		(0x4 + (i << 2))
+
+/* ACPU Interrupt Register */
+#define HI6220_MBOX_ACPU_INT_RAW_REG	0x400
+#define HI6220_MBOX_ACPU_INT_MSK_REG	0x404
+#define HI6220_MBOX_ACPU_INT_STAT_REG	0x408
+#define HI6220_MBOX_ACPU_INT_CLR_REG	0x40c
+#define HI6220_MBOX_ACPU_INT_ENA_REG	0x500
+#define HI6220_MBOX_ACPU_INT_DIS_REG	0x504
+
+/* MCU Interrupt Register */
+#define HI6220_MBOX_MCU_INT_RAW_REG	0x420
+
+/* Core Id */
+#define HI6220_CORE_ACPU		0x0
+#define HI6220_CORE_MCU			0x2
+
+struct hi6220_mbox_queue {
+	struct kfifo fifo;
+	struct work_struct work;
+	struct mbox_chan *chan;
+	bool full;
+};
+
+struct hi6220_mbox_chan {
+
+	/*
+	 * Description for channel's hardware info:
+	 *  - direction;
+	 *  - peer core id for communication;
+	 *  - local irq vector or number;
+	 *  - remoted irq vector or number for peer core;
+	 */
+	unsigned int dir;
+	unsigned int peer_core;
+	unsigned int remote_irq;
+	unsigned int local_irq;
+
+	/*
+	 * Slot address is cached value derived from index
+	 * within buffer for every channel
+	 */
+	void __iomem *slot;
+
+	/* For rx's fifo operations */
+	struct hi6220_mbox_queue *mq;
+
+	struct hi6220_mbox *parent;
+};
+
+struct hi6220_mbox {
+	struct device *dev;
+
+	spinlock_t lock;
+
+	unsigned int irq;
+
+	/* flag of enabling tx's irq mode */
+	bool tx_irq_mode;
+
+	/* region for ipc event */
+	void __iomem *ipc;
+
+	/* region for share mem */
+	void __iomem *buf;
+
+	unsigned int chan_num;
+	struct hi6220_mbox_chan *mchan;
+
+	void *irq_map_chan[HI6220_MBOX_CHAN_MAX];
+	struct mbox_chan *chan;
+	struct mbox_controller controller;
+};
+
+static void hi6220_mbox_set_status(struct hi6220_mbox_chan *mchan, u32 val)
+{
+	u32 status;
+
+	status = readl(mchan->slot + HI6220_MBOX_MODE_REG);
+	status &= ~HI6220_MBOX_STATUS_MASK;
+	status |= val;
+	writel(status, mchan->slot + HI6220_MBOX_MODE_REG);
+}
+
+static void hi6220_mbox_set_mode(struct hi6220_mbox_chan *mchan, u32 val)
+{
+	u32 mode;
+
+	mode = readl(mchan->slot + HI6220_MBOX_MODE_REG);
+	mode &= ~HI6220_MBOX_ACK_CONFIG_MASK;
+	mode |= val;
+	writel(mode, mchan->slot + HI6220_MBOX_MODE_REG);
+}
+
+static bool hi6220_mbox_last_tx_done(struct mbox_chan *chan)
+{
+	struct hi6220_mbox_chan *mchan = chan->con_priv;
+	struct hi6220_mbox *mbox = mchan->parent;
+	u32 status;
+
+	/* Only set idle state for polling mode */
+	BUG_ON(mbox->tx_irq_mode);
+
+	status = readl(mchan->slot + HI6220_MBOX_MODE_REG);
+	status = status & HI6220_MBOX_STATUS_MASK;
+	return (status == HI6220_MBOX_STATUS_IDLE);
+}
+
+static int hi6220_mbox_send_data(struct mbox_chan *chan, void *msg)
+{
+	struct hi6220_mbox_chan *mchan = chan->con_priv;
+	struct hi6220_mbox *mbox = mchan->parent;
+	int irq = mchan->remote_irq;
+	u32 *buf = msg;
+	unsigned long flags;
+	int i;
+
+	hi6220_mbox_set_status(mchan, HI6220_MBOX_STATUS_TX);
+
+	if (mbox->tx_irq_mode)
+		hi6220_mbox_set_mode(mchan, HI6220_MBOX_ACK_IRQ);
+	else
+		hi6220_mbox_set_mode(mchan, HI6220_MBOX_ACK_AUTOMATIC);
+
+	for (i = 0; i < (HI6220_MBOX_MSG_LEN >> 2); i++)
+		writel(buf[i], mchan->slot + HI6220_MBOX_DATA_REG(i));
+
+	/* trigger remote request */
+	spin_lock_irqsave(&mbox->lock, flags);
+	writel(1 << irq, mbox->ipc + HI6220_MBOX_MCU_INT_RAW_REG);
+	spin_unlock_irqrestore(&mbox->lock, flags);
+	return 0;
+}
+
+static void hi6220_mbox_rx_work(struct work_struct *work)
+{
+	struct hi6220_mbox_queue *mq =
+			container_of(work, struct hi6220_mbox_queue, work);
+	struct mbox_chan *chan = mq->chan;
+	struct hi6220_mbox_chan *mchan = chan->con_priv;
+	struct hi6220_mbox *mbox = mchan->parent;
+	int irq = mchan->local_irq, len;
+	u32 msg[HI6220_MBOX_MSG_LEN >> 2];
+
+	while (kfifo_len(&mq->fifo) >= sizeof(msg)) {
+		len = kfifo_out(&mq->fifo, (unsigned char *)&msg, sizeof(msg));
+		WARN_ON(len != sizeof(msg));
+
+		mbox_chan_received_data(chan, (void *)msg);
+		spin_lock_irq(&mbox->lock);
+		if (mq->full) {
+			mq->full = false;
+			writel(1 << irq,
+				mbox->ipc + HI6220_MBOX_ACPU_INT_ENA_REG);
+		}
+		spin_unlock_irq(&mbox->lock);
+	}
+}
+
+static void hi6220_mbox_tx_interrupt(struct mbox_chan *chan)
+{
+	struct hi6220_mbox_chan *mchan = chan->con_priv;
+	struct hi6220_mbox *mbox = mchan->parent;
+	int irq = mchan->local_irq;
+
+	writel(1 << irq, mbox->ipc + HI6220_MBOX_ACPU_INT_CLR_REG);
+	hi6220_mbox_set_status(mchan, HI6220_MBOX_STATUS_IDLE);
+
+	mbox_chan_txdone(chan, 0);
+}
+
+static void hi6220_mbox_rx_interrupt(struct mbox_chan *chan)
+{
+	struct hi6220_mbox_chan *mchan = chan->con_priv;
+	struct hi6220_mbox_queue *mq = mchan->mq;
+	struct hi6220_mbox *mbox = mchan->parent;
+	int irq = mchan->local_irq;
+	int msg[HI6220_MBOX_MSG_LEN >> 2];
+	int i, len;
+
+	if (unlikely(kfifo_avail(&mq->fifo) < sizeof(msg))) {
+		writel(1 << irq, mbox->ipc + HI6220_MBOX_ACPU_INT_DIS_REG);
+		mq->full = true;
+		goto nomem;
+	}
+
+	for (i = 0; i < (HI6220_MBOX_MSG_LEN >> 2); i++)
+		msg[i] = readl(mchan->slot + HI6220_MBOX_DATA_REG(i));
+
+	/* clear IRQ source */
+	writel(1 << irq, mbox->ipc + HI6220_MBOX_ACPU_INT_CLR_REG);
+
+	hi6220_mbox_set_status(mchan, HI6220_MBOX_STATUS_IDLE);
+
+	len = kfifo_in(&mq->fifo, (unsigned char *)&msg, sizeof(msg));
+	WARN_ON(len != sizeof(msg));
+
+nomem:
+	schedule_work(&mq->work);
+}
+
+static irqreturn_t hi6220_mbox_interrupt(int irq, void *p)
+{
+	struct hi6220_mbox *mbox = p;
+	struct hi6220_mbox_chan *mchan;
+	struct mbox_chan *chan;
+	unsigned int state;
+	unsigned int intr_bit;
+
+	state = readl(mbox->ipc + HI6220_MBOX_ACPU_INT_STAT_REG);
+	if (!state) {
+		dev_warn(mbox->dev, "%s: spurious interrupt\n",
+			 __func__);
+		return IRQ_HANDLED;
+	}
+
+	while (state) {
+		intr_bit = __ffs(state);
+		state &= (state - 1);
+
+		chan = mbox->irq_map_chan[intr_bit];
+		if (!chan) {
+			dev_warn(mbox->dev, "%s: unexpected irq vector %d\n",
+				 __func__, intr_bit);
+			continue;
+		}
+
+		mchan = chan->con_priv;
+		if (mchan->dir == HI6220_MBOX_TX)
+			hi6220_mbox_tx_interrupt(chan);
+		else
+			hi6220_mbox_rx_interrupt(chan);
+	}
+
+	return IRQ_HANDLED;
+}
+
+static struct hi6220_mbox_queue *hi6220_mbox_queue_alloc(
+		struct mbox_chan *chan,
+		void (*work)(struct work_struct *))
+{
+	struct hi6220_mbox_queue *mq;
+
+	mq = kzalloc(sizeof(struct hi6220_mbox_queue), GFP_KERNEL);
+	if (!mq)
+		return NULL;
+
+	if (kfifo_alloc(&mq->fifo, HI6220_MBOX_MSG_FIFO_SIZE, GFP_KERNEL))
+		goto error;
+
+	mq->chan = chan;
+	INIT_WORK(&mq->work, work);
+	return mq;
+
+error:
+	kfree(mq);
+	return NULL;
+}
+
+static void hi6220_mbox_queue_free(struct hi6220_mbox_queue *mq)
+{
+	kfifo_free(&mq->fifo);
+	kfree(mq);
+}
+
+static int hi6220_mbox_startup(struct mbox_chan *chan)
+{
+	struct hi6220_mbox_chan *mchan = chan->con_priv;
+	struct hi6220_mbox *mbox = mchan->parent;
+	unsigned int irq = mchan->local_irq;
+	struct hi6220_mbox_queue *mq;
+	unsigned long flags;
+
+	mq = hi6220_mbox_queue_alloc(chan, hi6220_mbox_rx_work);
+	if (!mq)
+		return -ENOMEM;
+	mchan->mq = mq;
+	mbox->irq_map_chan[irq] = (void *)chan;
+
+	/* enable interrupt */
+	spin_lock_irqsave(&mbox->lock, flags);
+	writel(1 << irq, mbox->ipc + HI6220_MBOX_ACPU_INT_ENA_REG);
+	spin_unlock_irqrestore(&mbox->lock, flags);
+	return 0;
+}
+
+static void hi6220_mbox_shutdown(struct mbox_chan *chan)
+{
+	struct hi6220_mbox_chan *mchan = chan->con_priv;
+	struct hi6220_mbox *mbox = mchan->parent;
+	unsigned int irq = mchan->local_irq;
+	unsigned long flags;
+
+	/* disable interrupt */
+	spin_lock_irqsave(&mbox->lock, flags);
+	writel(1 << irq, mbox->ipc + HI6220_MBOX_ACPU_INT_DIS_REG);
+	spin_unlock_irqrestore(&mbox->lock, flags);
+
+	mbox->irq_map_chan[irq] = NULL;
+	flush_work(&mchan->mq->work);
+	hi6220_mbox_queue_free(mchan->mq);
+}
+
+static struct mbox_chan_ops hi6220_mbox_chan_ops = {
+	.send_data    = hi6220_mbox_send_data,
+	.startup      = hi6220_mbox_startup,
+	.shutdown     = hi6220_mbox_shutdown,
+	.last_tx_done = hi6220_mbox_last_tx_done,
+};
+
+static void hi6220_mbox_init_hw(struct hi6220_mbox *mbox)
+{
+	struct hi6220_mbox_chan init_data[HI6220_MBOX_CHAN_NUM] = {
+		{ HI6220_MBOX_RX, HI6220_CORE_MCU, 1, 10 },
+		{ HI6220_MBOX_TX, HI6220_CORE_MCU, 0, 11 },
+	};
+	struct hi6220_mbox_chan *mchan = mbox->mchan;
+	int i;
+
+	for (i = 0; i < HI6220_MBOX_CHAN_NUM; i++) {
+		memcpy(&mchan[i], &init_data[i], sizeof(*mchan));
+		mchan[i].slot = mbox->buf + HI6220_MBOX_CHAN_SLOT_SIZE * i;
+		mchan[i].parent = mbox;
+	}
+
+	/* mask and clear all interrupt vectors */
+	writel(0x0,  mbox->ipc + HI6220_MBOX_ACPU_INT_MSK_REG);
+	writel(~0x0, mbox->ipc + HI6220_MBOX_ACPU_INT_CLR_REG);
+
+	/* use interrupt for tx's ack */
+	mbox->tx_irq_mode = true;
+}
+
+static const struct of_device_id hi6220_mbox_of_match[] = {
+	{ .compatible = "hisilicon,hi6220-mbox", },
+	{},
+};
+MODULE_DEVICE_TABLE(of, hi6220_mbox_of_match);
+
+static int hi6220_mbox_probe(struct platform_device *pdev)
+{
+	struct device *dev = &pdev->dev;
+	struct hi6220_mbox *mbox;
+	struct resource *res;
+	int i, err;
+
+	mbox = devm_kzalloc(dev, sizeof(*mbox), GFP_KERNEL);
+	if (!mbox)
+		return -ENOMEM;
+
+	mbox->dev = dev;
+	mbox->chan_num = HI6220_MBOX_CHAN_NUM;
+	mbox->mchan = devm_kzalloc(dev,
+		mbox->chan_num * sizeof(*mbox->mchan), GFP_KERNEL);
+	if (!mbox->mchan)
+		return -ENOMEM;
+
+	mbox->chan = devm_kzalloc(dev,
+		mbox->chan_num * sizeof(*mbox->chan), GFP_KERNEL);
+	if (!mbox->chan)
+		return -ENOMEM;
+
+	mbox->irq = platform_get_irq(pdev, 0);
+	if (mbox->irq < 0)
+		return mbox->irq;
+
+	res = platform_get_resource(pdev, IORESOURCE_MEM, 0);
+	mbox->ipc = devm_ioremap_resource(dev, res);
+	if (IS_ERR(mbox->ipc)) {
+		dev_err(dev, "ioremap ipc failed\n");
+		return PTR_ERR(mbox->ipc);
+	}
+
+	res = platform_get_resource(pdev, IORESOURCE_MEM, 1);
+	mbox->buf = devm_ioremap_resource(dev, res);
+	if (IS_ERR(mbox->buf)) {
+		dev_err(dev, "ioremap buffer failed\n");
+		return PTR_ERR(mbox->buf);
+	}
+
+	err = devm_request_irq(dev, mbox->irq, hi6220_mbox_interrupt, 0,
+			dev_name(dev), mbox);
+	if (err) {
+		dev_err(dev, "Failed to register a mailbox IRQ handler: %d\n",
+			err);
+		return -ENODEV;
+	}
+
+	/* init hardware parameters */
+	hi6220_mbox_init_hw(mbox);
+
+	spin_lock_init(&mbox->lock);
+
+	for (i = 0; i < mbox->chan_num; i++) {
+		mbox->chan[i].con_priv = &mbox->mchan[i];
+		mbox->irq_map_chan[i] = NULL;
+	}
+
+	mbox->controller.dev = dev;
+	mbox->controller.chans = &mbox->chan[0];
+	mbox->controller.num_chans = mbox->chan_num;
+	mbox->controller.ops = &hi6220_mbox_chan_ops;
+
+	if (mbox->tx_irq_mode)
+		mbox->controller.txdone_irq = true;
+	else {
+		mbox->controller.txdone_poll = true;
+		mbox->controller.txpoll_period = 5;
+	}
+
+	err = mbox_controller_register(&mbox->controller);
+	if (err) {
+		dev_err(dev, "Failed to register mailbox %d\n", err);
+		return err;
+	}
+
+	platform_set_drvdata(pdev, mbox);
+	dev_info(dev, "Mailbox enabled\n");
+	return 0;
+}
+
+static int hi6220_mbox_remove(struct platform_device *pdev)
+{
+	struct hi6220_mbox *mbox = platform_get_drvdata(pdev);
+
+	mbox_controller_unregister(&mbox->controller);
+	return 0;
+}
+
+static struct platform_driver hi6220_mbox_driver = {
+	.driver = {
+		.name = "hi6220-mbox",
+		.owner = THIS_MODULE,
+		.of_match_table = hi6220_mbox_of_match,
+	},
+	.probe	= hi6220_mbox_probe,
+	.remove	= hi6220_mbox_remove,
+};
+
+static int __init hi6220_mbox_init(void)
+{
+	return platform_driver_register(&hi6220_mbox_driver);
+}
+core_initcall(hi6220_mbox_init);
+
+static void __exit hi6220_mbox_exit(void)
+{
+	platform_driver_unregister(&hi6220_mbox_driver);
+}
+module_exit(hi6220_mbox_exit);
+
+MODULE_AUTHOR("Leo Yan <leo.yan at linaro.org>");
+MODULE_DESCRIPTION("Hi6220 mailbox driver");
+MODULE_LICENSE("GPL v2");
-- 
1.9.1



From leo.yan at linaro.org  Wed Aug 19 02:37:35 2015
From: leo.yan at linaro.org (Leo Yan)
Date: Wed, 19 Aug 2015 17:37:35 +0800
Subject: [PATCH v1 3/3] arm64: dts: add Hi6220 mailbox node
In-Reply-To: <1439977055-1747-1-git-send-email-leo.yan@linaro.org>
References: <1439977055-1747-1-git-send-email-leo.yan@linaro.org>
Message-ID: <1439977055-1747-4-git-send-email-leo.yan@linaro.org>

On Hi6220, below memory regions in DDR have specific purpose:

  0x05e0,0000 - 0x05ef,ffff: For MCU firmware using at runtime;
  0x0740,f000 - 0x0740,ffff: For MCU firmware's section;
  0x06df,f000 - 0x06df,ffff: For mailbox message data.

This patch reserves these memory regions and add device node for
mailbox in dts.

Signed-off-by: Leo Yan <leo.yan at linaro.org>
---
 arch/arm64/boot/dts/hisilicon/hi6220-hikey.dts | 20 +++++++++++++++++---
 arch/arm64/boot/dts/hisilicon/hi6220.dtsi      |  8 ++++++++
 2 files changed, 25 insertions(+), 3 deletions(-)

diff --git a/arch/arm64/boot/dts/hisilicon/hi6220-hikey.dts b/arch/arm64/boot/dts/hisilicon/hi6220-hikey.dts
index e36a539..d5470d3 100644
--- a/arch/arm64/boot/dts/hisilicon/hi6220-hikey.dts
+++ b/arch/arm64/boot/dts/hisilicon/hi6220-hikey.dts
@@ -7,9 +7,6 @@
 
 /dts-v1/;
 
-/*Reserved 1MB memory for MCU*/
-/memreserve/ 0x05e00000 0x00100000;
-
 #include "hi6220.dtsi"
 
 / {
@@ -28,4 +25,21 @@
 		device_type = "memory";
 		reg = <0x0 0x0 0x0 0x40000000>;
 	};
+
+	reserved-memory {
+		#address-cells = <2>;
+		#size-cells = <2>;
+		ranges;
+
+		mcu-buf at 05e00000 {
+			no-map;
+			reg = <0x0 0x05e00000 0x0 0x00100000>,	/* MCU firmware buffer */
+			      <0x0 0x0740f000 0x0 0x00001000>;	/* MCU firmware section */
+		};
+
+		mbox-buf at 06dff000 {
+			no-map;
+			reg = <0x0 0x06dff000 0x0 0x00001000>;	/* Mailbox message buf */
+		};
+	};
 };
diff --git a/arch/arm64/boot/dts/hisilicon/hi6220.dtsi b/arch/arm64/boot/dts/hisilicon/hi6220.dtsi
index 3f03380..9ff25bc 100644
--- a/arch/arm64/boot/dts/hisilicon/hi6220.dtsi
+++ b/arch/arm64/boot/dts/hisilicon/hi6220.dtsi
@@ -167,5 +167,13 @@
 			clocks = <&ao_ctrl 36>, <&ao_ctrl 36>;
 			clock-names = "uartclk", "apb_pclk";
 		};
+
+		mailbox: mailbox at f7510000 {
+			#mbox-cells = <1>;
+			compatible = "hisilicon,hi6220-mbox";
+			reg = <0x0 0xf7510000 0x0 0x1000>, /* IPC_S */
+			      <0x0 0x06dff800 0x0 0x0800>; /* Mailbox buffer */
+			interrupts = <GIC_SPI 94 IRQ_TYPE_LEVEL_HIGH>;
+		};
 	};
 };
-- 
1.9.1



From Liviu.Dudau at arm.com  Wed Aug 19 02:46:26 2015
From: Liviu.Dudau at arm.com (Liviu Dudau)
Date: Wed, 19 Aug 2015 10:46:26 +0100
Subject: [PATCH 2/4] drm: Add support for ARM's HDLCD controller.
In-Reply-To: <1439835473.3341.88.camel@linaro.org>
References: <1438784892-27888-1-git-send-email-Liviu.Dudau@arm.com>
 <1438784892-27888-3-git-send-email-Liviu.Dudau@arm.com>
 <1439835473.3341.88.camel@linaro.org>
Message-ID: <20150819094626.GG1020@e106497-lin.cambridge.arm.com>

On Mon, Aug 17, 2015 at 07:17:53PM +0100, Jon Medhurst (Tixy) wrote:
> I haven't reviewed the code in detail, just had one comment I alluded to
> in a private email the other day...
> 
> On Wed, 2015-08-05 at 15:28 +0100, Liviu Dudau wrote:
> 
> > diff --git a/drivers/gpu/drm/arm/hdlcd_crtc.c b/drivers/gpu/drm/arm/hdlcd_crtc.c
> [...]
> > +void hdlcd_set_scanout(struct hdlcd_drm_private *hdlcd)
> > +{
> > +	struct drm_framebuffer *fb = hdlcd->crtc.primary->fb;
> > +	struct drm_gem_cma_object *gem;
> > +	unsigned int depth, bpp;
> > +	dma_addr_t scanout_start;
> > +
> > +	drm_fb_get_bpp_depth(fb->pixel_format, &depth, &bpp);
> > +	gem = drm_fb_cma_get_gem_obj(fb, 0);
> > +
> > +	scanout_start = gem->paddr + fb->offsets[0] +
> > +		(hdlcd->crtc.y * fb->pitches[0]) + (hdlcd->crtc.x * bpp/8);
> > +
> > +	hdlcd_write(hdlcd, HDLCD_REG_FB_BASE, scanout_start);
> > +}
> > +
> 
> The above function accesses various pointers and values, which
> presumably all need to be valid and consistent. However...
> 
> [...]
> > diff --git a/drivers/gpu/drm/arm/hdlcd_drv.c b/drivers/gpu/drm/arm/hdlcd_drv.c
> [...]
> > +static irqreturn_t hdlcd_irq(int irq, void *arg)
> > +{
> > +	struct drm_device *dev = arg;
> > +	struct hdlcd_drm_private *hdlcd = dev->dev_private;
> > +	unsigned long irq_status;
> > +
> > +	irq_status = hdlcd_read(hdlcd, HDLCD_REG_INT_STATUS);
> > +
> > +#ifdef CONFIG_DEBUG_FS
> > +	if (irq_status & HDLCD_INTERRUPT_UNDERRUN) {
> > +		atomic_inc(&hdlcd->buffer_underrun_count);
> > +	}
> > +	if (irq_status & HDLCD_INTERRUPT_DMA_END) {
> > +		atomic_inc(&hdlcd->dma_end_count);
> > +	}
> > +	if (irq_status & HDLCD_INTERRUPT_BUS_ERROR) {
> > +		atomic_inc(&hdlcd->bus_error_count);
> > +	}
> > +	if (irq_status & HDLCD_INTERRUPT_VSYNC) {
> > +		atomic_inc(&hdlcd->vsync_count);
> > +	}
> > +#endif
> > +	if (irq_status & HDLCD_INTERRUPT_VSYNC) {
> > +		struct drm_pending_vblank_event *event;
> > +		unsigned long flags;
> > +
> > +		hdlcd_set_scanout(hdlcd);
> 
> hdlcd_set_scanout is being called on every vsync interrupt, can we
> guarantee that is safe? What if we're in the middle of a page flip or
> panning operation? Seems to me that there is at least scope for
> incorrect addresses being calculated leading to a nasty glitch on the
> screen for one frame. And in the worst case, possibly invalid pointer
> being dereferenced.

Agree, there is a risk of corruption here. I'm going to look at the atomic
mode setting which should hopefully resolve most of these issues.

> 
> So, if scanout needs to be set on every vsync, would it not be safer
> (and more efficient) to have a single variable storing the value to use
> during interrupts, and recalculate that value outside of interrupts
> whenever things are changed?

hdlcd_set_scanout() function is merely a convenience function to calculate
the scanout_start variable. The interrupt handler probably doesn't need to
call that and it was mostly a shortcut to make sure the HDLCD_REG_FB_BASE
register was up-to-date when the vsync interrupt happened. I hope the
atomic modeset will cleanup things here.

Best regards,
Liviu

> 
> -- 
> Tixy
> 

-- 
====================
| I would like to |
| fix the world,  |
| but they're not |
| giving me the   |
 \ source code!  /
  ---------------
    ?\_(?)_/?



From sjoerd.simons at collabora.co.uk  Wed Aug 19 02:48:44 2015
From: sjoerd.simons at collabora.co.uk (Sjoerd Simons)
Date: Wed, 19 Aug 2015 11:48:44 +0200
Subject: [GIT PULL 9/9] ARM: tegra: Default configuration updates for
 v4.3-rc1
In-Reply-To: <20150819091358.GA26627@ulmo>
References: <1439563720-13189-1-git-send-email-thierry.reding@gmail.com>
 <1439563720-13189-10-git-send-email-thierry.reding@gmail.com>
 <CANMBJr7PKy-eCcB3HiBajpApHS_BYPa7xfKjTqV4o8Z1hwY99A@mail.gmail.com>
 <20150819091358.GA26627@ulmo>
Message-ID: <1439977724.4135.90.camel@collabora.co.uk>

On Wed, 2015-08-19 at 11:14 +0200, Thierry Reding wrote:
> On Tue, Aug 18, 2015 at 03:30:41PM -0700, Tyler Baker wrote:
> > Hi Theirry,
> > 
> > 
> > This isn't where the story ends unfortunately. The collabora lab 
> > also
> > has a jetson-tk1, booted in the same manner, which boots next
> > -20150818
> > fine[4]. The only differences I can spot in the two boot logs is 
> > that
> > the collabora board is using an older version of u-boot, where as 
> > my
> > board is using a newer version. U-Boot 2015.01-00231-gab77f24-dirty
> > (Good) vs U-Boot 2015.07-00130-gb217c89 (Bad).

Our 2015.01-00231-gab77f24-dirty is 2015.01-00231-gab77f24 + changes
which got merged as 053b86e6d8e50359412e626c33bae3f7bafd74dd in
upstream u-boot.

Fwiw:
$ git show 2015.01-00231-gab77f24
commit ab77f24119e80257de4ab017b877f92f96980562
Merge: d928664 fa58b10
Author: Tom Rini <trini at ti.com>
Date:   Thu Jan 15 14:05:31 2015 -0500

    Merge branch 'master' of git://git.denx.de/u-boot-ti

Which is definately a commit you should hae in your upstream u-boot
tree.




> I don't have either of those commits in any of the U-Boot trees I 
> have.
> Perhaps whatever tree this comes from has local patches that cause 
> the
> breakage? The version that I use a recent upstream U-Boot with some
> local patches, none of which should impact Jetson TK1 in any way. 
> Just
> to make sure I tried running latest origin/master, which identifies
> thusly:
> 
> 	U-Boot 2015.10-rc2-00040-g0f9258228e2b
> 
> And that boots next-20150818 fine.

Probably worth for tyler to test that u-boot commit on his jetson to
see if that solves the issue he's having...

-- 
Sjoerd Simons <sjoerd.simons at collabora.co.uk>
Collabora Ltd.


From suneel.garapati at xilinx.com  Wed Aug 19 02:53:21 2015
From: suneel.garapati at xilinx.com (Suneel Garapati)
Date: Wed, 19 Aug 2015 15:23:21 +0530
Subject: [PATCH v3 1/2] devicetree: bindings: rtc: add bindings for xilinx
 zynqmp rtc
Message-ID: <1439978002-12157-1-git-send-email-suneel.garapati@xilinx.com>

adds file for description on device node bindings for RTC
found on Xilinx Zynq Ultrascale+ MPSoC.

Signed-off-by: Suneel Garapati <suneel.garapati at xilinx.com>
---
Changes v3 
- none 
Changes v2 
- add examples for interrupt-names 
- change alm to alarm 
---
 Documentation/devicetree/bindings/rtc/xlnx-rtc.txt | 25 ++++++++++++++++++++++
 1 file changed, 25 insertions(+)
 create mode 100644 Documentation/devicetree/bindings/rtc/xlnx-rtc.txt

diff --git a/Documentation/devicetree/bindings/rtc/xlnx-rtc.txt b/Documentation/devicetree/bindings/rtc/xlnx-rtc.txt
new file mode 100644
index 0000000..0df6f01
--- /dev/null
+++ b/Documentation/devicetree/bindings/rtc/xlnx-rtc.txt
@@ -0,0 +1,25 @@
+* Xilinx Zynq Ultrascale+ MPSoC Real Time Clock
+
+RTC controller for the Xilinx Zynq MPSoC Real Time Clock
+Separate IRQ lines for seconds and alarm
+
+Required properties:
+- compatible: Should be "xlnx,zynqmp-rtc"
+- reg: Physical base address of the controller and length
+       of memory mapped region.
+- interrupts: IRQ lines for the RTC.
+- interrupt-names: interrupt line names eg. "sec" "alarm"
+
+Optional:
+- calibration: calibration value for 1 sec period which will
+		be programmed directly to calibration register
+
+Example:
+rtc: rtc at ffa60000 {
+	compatible = "xlnx,zynqmp-rtc";
+	reg = <0x0 0xffa60000 0x100>;
+	interrupt-parent = <&gic>;
+	interrupts = <0 26 4>, <0 27 4>;
+	interrupt-names = "alarm", "sec";
+	calibration = <0x198233>;
+};
-- 
2.1.2



From suneel.garapati at xilinx.com  Wed Aug 19 02:53:22 2015
From: suneel.garapati at xilinx.com (Suneel Garapati)
Date: Wed, 19 Aug 2015 15:23:22 +0530
Subject: [PATCH v3 2/2] drivers: rtc: add xilinx zynqmp rtc driver
In-Reply-To: <1439978002-12157-1-git-send-email-suneel.garapati@xilinx.com>
References: <1439978002-12157-1-git-send-email-suneel.garapati@xilinx.com>
Message-ID: <1439978002-12157-2-git-send-email-suneel.garapati@xilinx.com>

adds support for RTC controller found on
Xilinx Zynq Ultrascale+ MPSoC platform.

Signed-off-by: Suneel Garapati <suneel.garapati at xilinx.com>
---
Changes v3 
- fix checkpatch errors 
- check time in secs arg against max sec val 
- order header files 
- use ptr_err_or_zero macro 
- use time64 variants 
Changes v2 
- change alm to alarm 
---
 drivers/rtc/Kconfig      |   7 ++
 drivers/rtc/Makefile     |   1 +
 drivers/rtc/rtc-zynqmp.c | 279 +++++++++++++++++++++++++++++++++++++++++++++++
 3 files changed, 287 insertions(+)
 create mode 100644 drivers/rtc/rtc-zynqmp.c

diff --git a/drivers/rtc/Kconfig b/drivers/rtc/Kconfig
index 35ea04c..bc96277 100644
--- a/drivers/rtc/Kconfig
+++ b/drivers/rtc/Kconfig
@@ -1116,6 +1116,13 @@ config RTC_DRV_OPAL
 	  This driver can also be built as a module. If so, the module
 	  will be called rtc-opal.
 
+config RTC_DRV_ZYNQMP
+	tristate "Xilinx Zynq Ultrascale+ MPSoC RTC"
+	depends on OF
+	help
+	  If you say yes here you get support for the RTC controller found on
+	  Xilinx Zynq Ultrascale+ MPSoC.
+
 comment "on-CPU RTC drivers"
 
 config RTC_DRV_DAVINCI
diff --git a/drivers/rtc/Makefile b/drivers/rtc/Makefile
index 2797384..e491eb5 100644
--- a/drivers/rtc/Makefile
+++ b/drivers/rtc/Makefile
@@ -159,3 +159,4 @@ obj-$(CONFIG_RTC_DRV_WM831X)	+= rtc-wm831x.o
 obj-$(CONFIG_RTC_DRV_WM8350)	+= rtc-wm8350.o
 obj-$(CONFIG_RTC_DRV_X1205)	+= rtc-x1205.o
 obj-$(CONFIG_RTC_DRV_XGENE)	+= rtc-xgene.o
+obj-$(CONFIG_RTC_DRV_ZYNQMP)	+= rtc-zynqmp.o
diff --git a/drivers/rtc/rtc-zynqmp.c b/drivers/rtc/rtc-zynqmp.c
new file mode 100644
index 0000000..8b28762
--- /dev/null
+++ b/drivers/rtc/rtc-zynqmp.c
@@ -0,0 +1,279 @@
+/*
+ * Xilinx Zynq Ultrascale+ MPSoC Real Time Clock Driver
+ *
+ * Copyright (C) 2015 Xilinx, Inc.
+ *
+ * This program is free software; you can redistribute it and/or modify it
+ * under the terms and conditions of the GNU General Public License,
+ * version 2, as published by the Free Software Foundation.
+ *
+ * This program is distributed in the hope 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.
+ *
+ * You should have received a copy of the GNU General Public License along with
+ * this program. If not, see <http://www.gnu.org/licenses/>.
+ *
+ */
+
+#include <linux/delay.h>
+#include <linux/init.h>
+#include <linux/io.h>
+#include <linux/module.h>
+#include <linux/of.h>
+#include <linux/platform_device.h>
+#include <linux/rtc.h>
+
+/* RTC Registers */
+#define RTC_SET_TM_WR		0x00
+#define RTC_SET_TM_RD		0x04
+#define RTC_CALIB_WR		0x08
+#define RTC_CALIB_RD		0x0C
+#define RTC_CUR_TM		0x10
+#define RTC_CUR_TICK		0x14
+#define RTC_ALRM		0x18
+#define RTC_INT_STS		0x20
+#define RTC_INT_MASK		0x24
+#define RTC_INT_EN		0x28
+#define RTC_INT_DIS		0x2C
+#define RTC_CTRL		0x40
+
+#define RTC_FR_EN		BIT(20)
+#define RTC_FR_DATSHIFT		16
+#define RTC_TICK_MASK		0xFFFF
+#define RTC_INT_SEC		BIT(0)
+#define RTC_INT_ALRM		BIT(1)
+#define RTC_OSC_EN		BIT(24)
+
+#define RTC_CALIB_DEF		0x198233
+#define RTC_CALIB_MASK		0x1FFFFF
+#define RTC_SEC_MAX_VAL		0xFFFFFFFF
+
+struct xlnx_rtc_dev {
+	struct rtc_device	*rtc;
+	void __iomem		*reg_base;
+	int			alarm_irq;
+	int			sec_irq;
+};
+
+static int xlnx_rtc_set_time(struct device *dev, struct rtc_time *tm)
+{
+	struct xlnx_rtc_dev *xrtcdev = dev_get_drvdata(dev);
+	unsigned long new_time;
+
+	new_time = rtc_tm_to_time64(tm);
+
+	if (new_time > RTC_SEC_MAX_VAL)
+		return -EINVAL;
+
+	writel(new_time, xrtcdev->reg_base + RTC_SET_TM_WR);
+
+	return 0;
+}
+
+static int xlnx_rtc_read_time(struct device *dev, struct rtc_time *tm)
+{
+	struct xlnx_rtc_dev *xrtcdev = dev_get_drvdata(dev);
+
+	rtc_time64_to_tm(readl(xrtcdev->reg_base + RTC_CUR_TM), tm);
+
+	return rtc_valid_tm(tm);
+}
+
+static int xlnx_rtc_read_alarm(struct device *dev, struct rtc_wkalrm *alrm)
+{
+	struct xlnx_rtc_dev *xrtcdev = dev_get_drvdata(dev);
+
+	rtc_time64_to_tm(readl(xrtcdev->reg_base + RTC_ALRM), &alrm->time);
+	alrm->enabled = readl(xrtcdev->reg_base + RTC_INT_MASK) & RTC_INT_ALRM;
+
+	return 0;
+}
+
+static int xlnx_rtc_alarm_irq_enable(struct device *dev, u32 enabled)
+{
+	struct xlnx_rtc_dev *xrtcdev = dev_get_drvdata(dev);
+
+	if (enabled)
+		writel(RTC_INT_ALRM, xrtcdev->reg_base + RTC_INT_EN);
+	else
+		writel(RTC_INT_ALRM, xrtcdev->reg_base + RTC_INT_DIS);
+
+	return 0;
+}
+
+static int xlnx_rtc_set_alarm(struct device *dev, struct rtc_wkalrm *alrm)
+{
+	struct xlnx_rtc_dev *xrtcdev = dev_get_drvdata(dev);
+	unsigned long alarm_time;
+
+	alarm_time = rtc_tm_to_time64(&alrm->time);
+
+	if (alarm_time > RTC_SEC_MAX_VAL)
+		return -EINVAL;
+
+	writel((u32)alarm_time, (xrtcdev->reg_base + RTC_ALRM));
+
+	xlnx_rtc_alarm_irq_enable(dev, alrm->enabled);
+
+	return 0;
+}
+
+static void xlnx_init_rtc(struct xlnx_rtc_dev *xrtcdev, u32 calibval)
+{
+	/*
+	 * Based on crystal freq of 33.330 KHz
+	 * set the seconds counter and enable, set fractions counter
+	 * to default value suggested as per design spec
+	 * to correct RTC delay in frequency over period of time.
+	 */
+	calibval &= RTC_CALIB_MASK;
+	writel(calibval, (xrtcdev->reg_base + RTC_CALIB_WR));
+}
+
+static const struct rtc_class_ops xlnx_rtc_ops = {
+	.set_time	  = xlnx_rtc_set_time,
+	.read_time	  = xlnx_rtc_read_time,
+	.read_alarm	  = xlnx_rtc_read_alarm,
+	.set_alarm	  = xlnx_rtc_set_alarm,
+	.alarm_irq_enable = xlnx_rtc_alarm_irq_enable,
+};
+
+static irqreturn_t xlnx_rtc_interrupt(int irq, void *id)
+{
+	struct xlnx_rtc_dev *xrtcdev = (struct xlnx_rtc_dev *)id;
+	unsigned int status;
+
+	status = readl(xrtcdev->reg_base + RTC_INT_STS);
+	/* Check if interrupt asserted */
+	if (!(status & (RTC_INT_SEC | RTC_INT_ALRM)))
+		return IRQ_NONE;
+
+	/* Clear interrupt */
+	writel(status, xrtcdev->reg_base + RTC_INT_STS);
+
+	if (status & RTC_INT_SEC)
+		rtc_update_irq(xrtcdev->rtc, 1, RTC_IRQF | RTC_UF);
+	if (status & RTC_INT_ALRM)
+		rtc_update_irq(xrtcdev->rtc, 1, RTC_IRQF | RTC_AF);
+
+	return IRQ_HANDLED;
+}
+
+static int xlnx_rtc_probe(struct platform_device *pdev)
+{
+	struct xlnx_rtc_dev *xrtcdev;
+	struct resource *res;
+	int ret;
+	unsigned int calibvalue;
+
+	xrtcdev = devm_kzalloc(&pdev->dev, sizeof(*xrtcdev), GFP_KERNEL);
+	if (!xrtcdev)
+		return -ENOMEM;
+
+	platform_set_drvdata(pdev, xrtcdev);
+
+	res = platform_get_resource(pdev, IORESOURCE_MEM, 0);
+
+	xrtcdev->reg_base = devm_ioremap_resource(&pdev->dev, res);
+	if (IS_ERR(xrtcdev->reg_base))
+		return PTR_ERR(xrtcdev->reg_base);
+
+	xrtcdev->alarm_irq = platform_get_irq_byname(pdev, "alarm");
+	if (xrtcdev->alarm_irq < 0) {
+		dev_err(&pdev->dev, "no irq resource\n");
+		return xrtcdev->alarm_irq;
+	}
+	ret = devm_request_irq(&pdev->dev, xrtcdev->alarm_irq,
+			       xlnx_rtc_interrupt, 0,
+			       dev_name(&pdev->dev), xrtcdev);
+	if (ret) {
+		dev_err(&pdev->dev, "request irq failed\n");
+		return ret;
+	}
+
+	xrtcdev->sec_irq = platform_get_irq_byname(pdev, "sec");
+	if (xrtcdev->sec_irq < 0) {
+		dev_err(&pdev->dev, "no irq resource\n");
+		return xrtcdev->sec_irq;
+	}
+	ret = devm_request_irq(&pdev->dev, xrtcdev->sec_irq,
+			       xlnx_rtc_interrupt, 0,
+			       dev_name(&pdev->dev), xrtcdev);
+	if (ret) {
+		dev_err(&pdev->dev, "request irq failed\n");
+		return ret;
+	}
+
+	ret = of_property_read_u32(pdev->dev.of_node, "calibration",
+				   &calibvalue);
+	if (ret)
+		calibvalue = RTC_CALIB_DEF;
+
+	xlnx_init_rtc(xrtcdev, calibvalue);
+
+	device_init_wakeup(&pdev->dev, 1);
+
+	xrtcdev->rtc = devm_rtc_device_register(&pdev->dev, pdev->name,
+					 &xlnx_rtc_ops, THIS_MODULE);
+	return PTR_ERR_OR_ZERO(xrtcdev->rtc);
+}
+
+static int xlnx_rtc_remove(struct platform_device *pdev)
+{
+	xlnx_rtc_alarm_irq_enable(&pdev->dev, 0);
+	device_init_wakeup(&pdev->dev, 0);
+
+	return 0;
+}
+
+static int __maybe_unused xlnx_rtc_suspend(struct device *dev)
+{
+	struct platform_device *pdev = to_platform_device(dev);
+	struct xlnx_rtc_dev *xrtcdev = platform_get_drvdata(pdev);
+
+	if (device_may_wakeup(&pdev->dev))
+		enable_irq_wake(xrtcdev->alarm_irq);
+	else
+		xlnx_rtc_alarm_irq_enable(dev, 0);
+
+	return 0;
+}
+
+static int __maybe_unused xlnx_rtc_resume(struct device *dev)
+{
+	struct platform_device *pdev = to_platform_device(dev);
+	struct xlnx_rtc_dev *xrtcdev = platform_get_drvdata(pdev);
+
+	if (device_may_wakeup(&pdev->dev))
+		disable_irq_wake(xrtcdev->alarm_irq);
+	else
+		xlnx_rtc_alarm_irq_enable(dev, 1);
+
+	return 0;
+}
+
+static SIMPLE_DEV_PM_OPS(xlnx_rtc_pm_ops, xlnx_rtc_suspend, xlnx_rtc_resume);
+
+static const struct of_device_id xlnx_rtc_of_match[] = {
+	{.compatible = "xlnx,zynqmp-rtc" },
+	{ }
+};
+MODULE_DEVICE_TABLE(of, xlnx_rtc_of_match);
+
+static struct platform_driver xlnx_rtc_driver = {
+	.probe		= xlnx_rtc_probe,
+	.remove		= xlnx_rtc_remove,
+	.driver		= {
+		.name	= KBUILD_MODNAME,
+		.pm	= &xlnx_rtc_pm_ops,
+		.of_match_table	= xlnx_rtc_of_match,
+	},
+};
+
+module_platform_driver(xlnx_rtc_driver);
+
+MODULE_DESCRIPTION("Xilinx Zynq MPSoC RTC driver");
+MODULE_AUTHOR("Xilinx Inc.");
+MODULE_LICENSE("GPL v2");
-- 
2.1.2



From thierry.reding at gmail.com  Wed Aug 19 03:09:38 2015
From: thierry.reding at gmail.com (Thierry Reding)
Date: Wed, 19 Aug 2015 12:09:38 +0200
Subject: [PATCH V3] Watchdog: Fix parent of watchdog_devices
In-Reply-To: <db7db9102158b87a4a7169e84e2272b3ba03f9f7.1439954581.git.panand@redhat.com>
References: <db7db9102158b87a4a7169e84e2272b3ba03f9f7.1439954581.git.panand@redhat.com>
Message-ID: <20150819100937.GD26627@ulmo>

On Wed, Aug 19, 2015 at 08:58:24AM +0530, Pratyush Anand wrote:
[...]
> diff --git a/drivers/watchdog/tegra_wdt.c b/drivers/watchdog/tegra_wdt.c
> index 30451ea46902..7f97cdd53f29 100644
> --- a/drivers/watchdog/tegra_wdt.c
> +++ b/drivers/watchdog/tegra_wdt.c
> @@ -218,6 +218,7 @@ static int tegra_wdt_probe(struct platform_device *pdev)
>  	wdd->ops = &tegra_wdt_ops;
>  	wdd->min_timeout = MIN_WDT_TIMEOUT;
>  	wdd->max_timeout = MAX_WDT_TIMEOUT;
> +	wdd->parent = &pdev->dev;
>  
>  	watchdog_set_drvdata(wdd, wdt);
>  

Acked-by: Thierry Reding <treding at nvidia.com>
-------------- next part --------------
A non-text attachment was scrubbed...
Name: signature.asc
Type: application/pgp-signature
Size: 819 bytes
Desc: not available
URL: <http://lists.infradead.org/pipermail/linux-arm-kernel/attachments/20150819/f971965d/attachment.sig>

From Dave.Martin at arm.com  Wed Aug 19 03:14:27 2015
From: Dave.Martin at arm.com (Dave Martin)
Date: Wed, 19 Aug 2015 11:14:27 +0100
Subject: [PATCH 2/3] [v4] ARM64: TTY: hvc_dcc: Add support for ARM64 dcc
In-Reply-To: <55D3825D.6020105@codeaurora.org>
References: <1438992995-22610-1-git-send-email-timur@codeaurora.org>
 <1438992995-22610-2-git-send-email-timur@codeaurora.org>
 <20150810094008.GD1604@arm.com> <55D2749A.401@codeaurora.org>
 <20150818082141.GA6281@e103592.cambridge.arm.com>
 <55D3825D.6020105@codeaurora.org>
Message-ID: <20150819101426.GB6281@e103592.cambridge.arm.com>

On Tue, Aug 18, 2015 at 02:07:09PM -0500, Timur Tabi wrote:
> On 08/18/2015 03:21 AM, Dave Martin wrote:
> >>Do you think that I need an explicit instruction to clear the upper
> >>>bits?  I tried a few compiler tricks (e.g. "c && 0xff" and the
> >>>like), and they had no effect.
> >The in-register representation of a char permits the upper bits to be
> >nonzero, so you need to convert to a register-sized type if you want
> >to be able to force those bits to zero.
> >
> >Try: (unsigned long)(unsigned char)c or (unsigned long)c & 0xff.
> 
> I tried all those, and more, and I still always get the same thing:
> 
>   28:	38401423 	ldrb	w3, [x1],#1
>   2c:	d5130503 	msr	dbgdtrrx_el0, x3
> 
> I know that ldrb will zero-extend the byte to a 32-bit word.  But I
> don't see any way to zero-extend the word into a 64-bit register.
> 
> I'm not even sure that this is necessary.  The dbgdtrrx_el0 register
> is technically only 32-bit anyway.  It looks to me like the code is
> already correct.

[...]

> >Check the ARM ARM for what operand combinations are allowed.  However,
> >it doesn't really make any difference here because it's a general rule
> >in the architecture that when an instruction's output is in a
> >W-register, the upper 32 bits of the corresponding X-register are
> >always zeroed anyway.
> 
> So does that mean that ldrb will zero-extend the byte to all 64 bits of x3?

Yes.  No extra operation is required.

Cheers
---Dave



From mpa at pengutronix.de  Wed Aug 19 03:18:29 2015
From: mpa at pengutronix.de (Markus Pargmann)
Date: Wed, 19 Aug 2015 12:18:29 +0200
Subject: [PATCH 0/3] gpiolib: Initializing GPIOs using DT property gpio-initval
Message-ID: <1439979512-3894-1-git-send-email-mpa@pengutronix.de>

Hi,

This series adds a gpio-initval property to the devicetree. It provides a way
to initialize GPIOs to a defined value.

The previous patch was '[PATCH v2] gpio: Allow hogged gpios to be requested'
which would have allowed to request hogged GPIOs. Linus suggested a separate DT
property as hogged gpios should not be requested.

There are 3 patches. The first two simplify the function gpiod_hog. The third
reuses the gpiod_hog()_code for a new gpiod_initialize() and adds the parsing
of the DT.

This series is based on the series
"[PATCH v3 0/9] gpiolib: Add GPIO name support".

Best regards,

Markus


Markus Pargmann (3):
  gpio: Use __gpiod_request directly
  gpiolib: gpiod_hog remove separate name argument
  gpiolib: Add GPIO initialization

 Documentation/devicetree/bindings/gpio/gpio.txt | 29 ++++++----
 drivers/gpio/gpiolib-of.c                       | 11 +++-
 drivers/gpio/gpiolib.c                          | 74 +++++++++++++++++--------
 drivers/gpio/gpiolib.h                          |  6 +-
 4 files changed, 83 insertions(+), 37 deletions(-)

-- 
2.4.6



From mpa at pengutronix.de  Wed Aug 19 03:18:32 2015
From: mpa at pengutronix.de (Markus Pargmann)
Date: Wed, 19 Aug 2015 12:18:32 +0200
Subject: [PATCH 3/3] gpiolib: Add GPIO initialization
In-Reply-To: <1439979512-3894-1-git-send-email-mpa@pengutronix.de>
References: <1439979512-3894-1-git-send-email-mpa@pengutronix.de>
Message-ID: <1439979512-3894-4-git-send-email-mpa@pengutronix.de>

From: Markus Pargmann <mpa at devmp.org>

This functions adds a way to initialize a GPIO without hogging it.

Signed-off-by: Markus Pargmann <mpa at devmp.org>
---
 Documentation/devicetree/bindings/gpio/gpio.txt | 29 +++++++------
 drivers/gpio/gpiolib-of.c                       |  9 ++++
 drivers/gpio/gpiolib.c                          | 55 ++++++++++++++++++++-----
 drivers/gpio/gpiolib.h                          |  2 +
 4 files changed, 73 insertions(+), 22 deletions(-)

diff --git a/Documentation/devicetree/bindings/gpio/gpio.txt b/Documentation/devicetree/bindings/gpio/gpio.txt
index 5788d5cf1252..55d58983ba43 100644
--- a/Documentation/devicetree/bindings/gpio/gpio.txt
+++ b/Documentation/devicetree/bindings/gpio/gpio.txt
@@ -116,29 +116,34 @@ Every GPIO controller node must contain both an empty "gpio-controller"
 property, and a #gpio-cells integer property, which indicates the number of
 cells in a gpio-specifier.
 
-The GPIO chip may contain GPIO hog definitions. GPIO hogging is a mechanism
-providing automatic GPIO request and configuration as part of the
-gpio-controller's driver probe function.
+The GPIO chip may contain GPIO definitions. These define properties for single
+GPIOs of this controller.
 
-Each GPIO hog definition is represented as a child node of the GPIO controller.
+GPIO hogging is a mechanism providing automatic GPIO request and configuration
+as part of the gpio-controller's driver probe function.
+
+GPIO initialization provides an automatic initialization to known save values.
+Instead of GPIO hogging the GPIO's value and direction can be modified by other
+users after it was initialized.
+
+Each GPIO definition is represented as a child node of the GPIO controller.
 Required properties:
-- gpio-hog:   A property specifying that this child node represent a GPIO hog.
 - gpios:      Store the GPIO information (id, flags, ...). Shall contain the
 	      number of cells specified in its parent node (GPIO controller
 	      node).
-Only one of the following properties scanned in the order shown below.
-This means that when multiple properties are present they will be searched
-in the order presented below and the first match is taken as the intended
-configuration.
+
+Optional properties:
+- line-name:  The GPIO label name. If not present the node name is used.
+ Only one of gpio-hog and gpio-initval may be specified.
+- gpio-hog:   A property specifying that this child node represent a GPIO hog.
+- gpio-initval: This GPIO should be initialized to the specified configuration.
+ Only one of input, output-low and output-high may be specified:
 - input:      A property specifying to set the GPIO direction as input.
 - output-low  A property specifying to set the GPIO direction as output with
 	      the value low.
 - output-high A property specifying to set the GPIO direction as output with
 	      the value high.
 
-Optional properties:
-- line-name:  The GPIO label name. If not present the node name is used.
-
 Example of two SOC GPIO banks defined as gpio-controller nodes:
 
 	qe_pio_a: gpio-controller at 1400 {
diff --git a/drivers/gpio/gpiolib-of.c b/drivers/gpio/gpiolib-of.c
index f1fe5123da28..ee00c2c63f57 100644
--- a/drivers/gpio/gpiolib-of.c
+++ b/drivers/gpio/gpiolib-of.c
@@ -234,6 +234,15 @@ static void of_gpiochip_scan_gpios(struct gpio_chip *chip)
 
 			if (gpiod_hog(desc, lflags, dflags))
 				continue;
+		} else if (of_property_read_bool(np, "gpio-initval")) {
+			if (!dflags) {
+				dev_warn(chip->dev, "GPIO line %d (%s): no initialization state specified, bailing out\n",
+					 desc_to_gpio(desc), np->name);
+				continue;
+			}
+
+			if (gpiod_initialize(desc, lflags, dflags))
+				continue;
 		}
 	}
 }
diff --git a/drivers/gpio/gpiolib.c b/drivers/gpio/gpiolib.c
index f1559fa72c36..d7aa27a92e82 100644
--- a/drivers/gpio/gpiolib.c
+++ b/drivers/gpio/gpiolib.c
@@ -2178,15 +2178,8 @@ struct gpio_desc *__must_check __gpiod_get_index_optional(struct device *dev,
 }
 EXPORT_SYMBOL_GPL(__gpiod_get_index_optional);
 
-/**
- * gpiod_hog - Hog the specified GPIO desc given the provided flags
- * @desc:	gpio whose value will be assigned
- * @lflags:	gpio_lookup_flags - returned from of_find_gpio() or
- *		of_get_gpio_hog()
- * @dflags:	gpiod_flags - optional GPIO initialization flags
- */
-int gpiod_hog(struct gpio_desc *desc, unsigned long lflags,
-	      enum gpiod_flags dflags)
+static int _gpiod_initialize(struct gpio_desc *desc, unsigned long lflags,
+		      enum gpiod_flags dflags)
 {
 	int status;
 	const char *name = desc->name;
@@ -2202,11 +2195,31 @@ int gpiod_hog(struct gpio_desc *desc, unsigned long lflags,
 	status = gpiod_configure_flags(desc, name, lflags, dflags);
 	if (status < 0) {
 		pr_err("setup of hog GPIO %s (chip %s, offset %d) failed\n",
-		       name, gpiod_to_chip(desc)->label, gpio_chip_hwgpio(desc));
+		       name, gpiod_to_chip(desc)->label,
+		       gpio_chip_hwgpio(desc));
 		gpiochip_free_own_desc(desc);
 		return status;
 	}
 
+	return 0;
+}
+
+/**
+ * gpiod_hog - Hog the specified GPIO desc given the provided flags
+ * @desc:	gpio whose value will be assigned
+ * @lflags:	gpio_lookup_flags - returned from of_find_gpio() or
+ *		of_get_gpio_hog()
+ * @dflags:	gpiod_flags - optional GPIO initialization flags
+ */
+int gpiod_hog(struct gpio_desc *desc, unsigned long lflags,
+	      enum gpiod_flags dflags)
+{
+	int ret;
+
+	ret = _gpiod_initialize(desc, lflags, dflags);
+	if (ret)
+		return ret;
+
 	/* Mark GPIO as hogged so it can be identified and removed later */
 	set_bit(FLAG_IS_HOGGED, &desc->flags);
 
@@ -2236,6 +2249,28 @@ static void gpiochip_free_hogs(struct gpio_chip *chip)
 }
 
 /**
+ * gpiod_initialize - Initialize a GPIO with a given value
+ * @desc:	gpio whose value will be assigned
+ * @lflags:	gpio_lookup_flags - returned from of_find_gpio() or
+ *		of_get_gpio_hog()
+ * @dflags:	gpiod_flags - optional GPIO initialization flags
+ *
+ * This is used to initialize GPIOs that were defined in DT
+ */
+int gpiod_initialize(struct gpio_desc *desc, unsigned long lflags,
+		     enum gpiod_flags dflags)
+{
+	int ret;
+
+	ret = _gpiod_initialize(desc, lflags, dflags);
+	if (ret)
+		return ret;
+
+	__gpiod_free(desc);
+	return ret;
+}
+
+/**
  * gpiod_get_array - obtain multiple GPIOs from a multi-index GPIO function
  * @dev:	GPIO consumer, can be NULL for system-global GPIOs
  * @con_id:	function within the GPIO consumer
diff --git a/drivers/gpio/gpiolib.h b/drivers/gpio/gpiolib.h
index 6c2aeff59f86..b6dfa3526e3a 100644
--- a/drivers/gpio/gpiolib.h
+++ b/drivers/gpio/gpiolib.h
@@ -99,6 +99,8 @@ int gpiod_request(struct gpio_desc *desc, const char *label);
 void gpiod_free(struct gpio_desc *desc);
 int gpiod_hog(struct gpio_desc *desc, unsigned long lflags,
 	      enum gpiod_flags dflags);
+int gpiod_initialize(struct gpio_desc *desc, unsigned long lflags,
+		     enum gpiod_flags dflags);
 
 /*
  * Return the GPIO number of the passed descriptor relative to its chip
-- 
2.4.6



From mpa at pengutronix.de  Wed Aug 19 03:18:31 2015
From: mpa at pengutronix.de (Markus Pargmann)
Date: Wed, 19 Aug 2015 12:18:31 +0200
Subject: [PATCH 2/3] gpiolib: gpiod_hog remove separate name argument
In-Reply-To: <1439979512-3894-1-git-send-email-mpa@pengutronix.de>
References: <1439979512-3894-1-git-send-email-mpa@pengutronix.de>
Message-ID: <1439979512-3894-3-git-send-email-mpa@pengutronix.de>

From: Markus Pargmann <mpa at devmp.org>

The gpio name is now stored in the gpio descriptor, so we can simply use
that instead of an argument to the function.

Signed-off-by: Markus Pargmann <mpa at pengutronix.de>
---
 drivers/gpio/gpiolib-of.c | 2 +-
 drivers/gpio/gpiolib.c    | 8 ++++----
 drivers/gpio/gpiolib.h    | 4 ++--
 3 files changed, 7 insertions(+), 7 deletions(-)

diff --git a/drivers/gpio/gpiolib-of.c b/drivers/gpio/gpiolib-of.c
index 48a7579dd62d..f1fe5123da28 100644
--- a/drivers/gpio/gpiolib-of.c
+++ b/drivers/gpio/gpiolib-of.c
@@ -232,7 +232,7 @@ static void of_gpiochip_scan_gpios(struct gpio_chip *chip)
 				continue;
 			}
 
-			if (gpiod_hog(desc, name, lflags, dflags))
+			if (gpiod_hog(desc, lflags, dflags))
 				continue;
 		}
 	}
diff --git a/drivers/gpio/gpiolib.c b/drivers/gpio/gpiolib.c
index 872fdd3617c1..f1559fa72c36 100644
--- a/drivers/gpio/gpiolib.c
+++ b/drivers/gpio/gpiolib.c
@@ -2181,15 +2181,15 @@ EXPORT_SYMBOL_GPL(__gpiod_get_index_optional);
 /**
  * gpiod_hog - Hog the specified GPIO desc given the provided flags
  * @desc:	gpio whose value will be assigned
- * @name:	gpio line name
  * @lflags:	gpio_lookup_flags - returned from of_find_gpio() or
  *		of_get_gpio_hog()
  * @dflags:	gpiod_flags - optional GPIO initialization flags
  */
-int gpiod_hog(struct gpio_desc *desc, const char *name,
-	      unsigned long lflags, enum gpiod_flags dflags)
+int gpiod_hog(struct gpio_desc *desc, unsigned long lflags,
+	      enum gpiod_flags dflags)
 {
 	int status;
+	const char *name = desc->name;
 
 	status = __gpiod_request(desc, name);
 	if (status) {
@@ -2211,7 +2211,7 @@ int gpiod_hog(struct gpio_desc *desc, const char *name,
 	set_bit(FLAG_IS_HOGGED, &desc->flags);
 
 	pr_info("GPIO line %d (%s) hogged as %s%s\n",
-		desc_to_gpio(desc), name,
+		desc_to_gpio(desc), desc->name,
 		(dflags&GPIOD_FLAGS_BIT_DIR_OUT) ? "output" : "input",
 		(dflags&GPIOD_FLAGS_BIT_DIR_OUT) ?
 		  (dflags&GPIOD_FLAGS_BIT_DIR_VAL) ? "/high" : "/low":"");
diff --git a/drivers/gpio/gpiolib.h b/drivers/gpio/gpiolib.h
index 78e634d1c719..6c2aeff59f86 100644
--- a/drivers/gpio/gpiolib.h
+++ b/drivers/gpio/gpiolib.h
@@ -97,8 +97,8 @@ struct gpio_desc {
 
 int gpiod_request(struct gpio_desc *desc, const char *label);
 void gpiod_free(struct gpio_desc *desc);
-int gpiod_hog(struct gpio_desc *desc, const char *name,
-		unsigned long lflags, enum gpiod_flags dflags);
+int gpiod_hog(struct gpio_desc *desc, unsigned long lflags,
+	      enum gpiod_flags dflags);
 
 /*
  * Return the GPIO number of the passed descriptor relative to its chip
-- 
2.4.6



From mpa at pengutronix.de  Wed Aug 19 03:18:30 2015
From: mpa at pengutronix.de (Markus Pargmann)
Date: Wed, 19 Aug 2015 12:18:30 +0200
Subject: [PATCH 1/3] gpio: Use __gpiod_request directly
In-Reply-To: <1439979512-3894-1-git-send-email-mpa@pengutronix.de>
References: <1439979512-3894-1-git-send-email-mpa@pengutronix.de>
Message-ID: <1439979512-3894-2-git-send-email-mpa@pengutronix.de>

From: Markus Pargmann <mpa at devmp.org>

There is no reason to find out chip and hwnum to use to request a gpio
and get another gpio descriptor. We already have the descriptor we want
to use so we can directly use it.

Signed-off-by: Markus Pargmann <mpa at pengutronix.de>
---
 drivers/gpio/gpiolib.c | 17 ++++++-----------
 1 file changed, 6 insertions(+), 11 deletions(-)

diff --git a/drivers/gpio/gpiolib.c b/drivers/gpio/gpiolib.c
index 79a0b41ce57b..872fdd3617c1 100644
--- a/drivers/gpio/gpiolib.c
+++ b/drivers/gpio/gpiolib.c
@@ -2189,25 +2189,20 @@ EXPORT_SYMBOL_GPL(__gpiod_get_index_optional);
 int gpiod_hog(struct gpio_desc *desc, const char *name,
 	      unsigned long lflags, enum gpiod_flags dflags)
 {
-	struct gpio_chip *chip;
-	struct gpio_desc *local_desc;
-	int hwnum;
 	int status;
 
-	chip = gpiod_to_chip(desc);
-	hwnum = gpio_chip_hwgpio(desc);
-
-	local_desc = gpiochip_request_own_desc(chip, hwnum, name);
-	if (IS_ERR(local_desc)) {
+	status = __gpiod_request(desc, name);
+	if (status) {
 		pr_err("requesting hog GPIO %s (chip %s, offset %d) failed\n",
-		       name, chip->label, hwnum);
-		return PTR_ERR(local_desc);
+		       name, gpiod_to_chip(desc)->label,
+		       gpio_chip_hwgpio(desc));
+		return status;
 	}
 
 	status = gpiod_configure_flags(desc, name, lflags, dflags);
 	if (status < 0) {
 		pr_err("setup of hog GPIO %s (chip %s, offset %d) failed\n",
-		       name, chip->label, hwnum);
+		       name, gpiod_to_chip(desc)->label, gpio_chip_hwgpio(desc));
 		gpiochip_free_own_desc(desc);
 		return status;
 	}
-- 
2.4.6



From thierry.reding at gmail.com  Wed Aug 19 03:33:06 2015
From: thierry.reding at gmail.com (Thierry Reding)
Date: Wed, 19 Aug 2015 12:33:06 +0200
Subject: [GIT PULL 9/9] ARM: tegra: Default configuration updates for
 v4.3-rc1
In-Reply-To: <1439977724.4135.90.camel@collabora.co.uk>
References: <1439563720-13189-1-git-send-email-thierry.reding@gmail.com>
 <1439563720-13189-10-git-send-email-thierry.reding@gmail.com>
 <CANMBJr7PKy-eCcB3HiBajpApHS_BYPa7xfKjTqV4o8Z1hwY99A@mail.gmail.com>
 <20150819091358.GA26627@ulmo>
 <1439977724.4135.90.camel@collabora.co.uk>
Message-ID: <20150819103305.GF26627@ulmo>

On Wed, Aug 19, 2015 at 11:48:44AM +0200, Sjoerd Simons wrote:
> On Wed, 2015-08-19 at 11:14 +0200, Thierry Reding wrote:
> > On Tue, Aug 18, 2015 at 03:30:41PM -0700, Tyler Baker wrote:
> > > Hi Theirry,
> > > 
> > > 
> > > This isn't where the story ends unfortunately. The collabora lab 
> > > also
> > > has a jetson-tk1, booted in the same manner, which boots next
> > > -20150818
> > > fine[4]. The only differences I can spot in the two boot logs is 
> > > that
> > > the collabora board is using an older version of u-boot, where as 
> > > my
> > > board is using a newer version. U-Boot 2015.01-00231-gab77f24-dirty
> > > (Good) vs U-Boot 2015.07-00130-gb217c89 (Bad).
> 
> Our 2015.01-00231-gab77f24-dirty is 2015.01-00231-gab77f24 + changes
> which got merged as 053b86e6d8e50359412e626c33bae3f7bafd74dd in
> upstream u-boot.
> 
> Fwiw:
> $ git show 2015.01-00231-gab77f24
> commit ab77f24119e80257de4ab017b877f92f96980562
> Merge: d928664 fa58b10
> Author: Tom Rini <trini at ti.com>
> Date:   Thu Jan 15 14:05:31 2015 -0500
> 
>     Merge branch 'master' of git://git.denx.de/u-boot-ti
> 
> Which is definately a commit you should hae in your upstream u-boot
> tree.

Yeah, I suck. I was running:

	$ git show gab77f24

I didn't know git could parse the full output from git describe.

> > I don't have either of those commits in any of the U-Boot trees I 
> > have.
> > Perhaps whatever tree this comes from has local patches that cause 
> > the
> > breakage? The version that I use a recent upstream U-Boot with some
> > local patches, none of which should impact Jetson TK1 in any way. 
> > Just
> > to make sure I tried running latest origin/master, which identifies
> > thusly:
> > 
> > 	U-Boot 2015.10-rc2-00040-g0f9258228e2b
> > 
> > And that boots next-20150818 fine.
> 
> Probably worth for tyler to test that u-boot commit on his jetson to
> see if that solves the issue he's having...

I've tried reconstructing the version that Tyler is running by checking
out 2015.01-00231-gab77f24 and applying 053b86e6d8e5 ("pci: tegra: Fix
port information parsing") on top, but that also leaves me with a
bootable system, so no way of reproducing. I agree that upgrading to a
more recent U-Boot version sounds like the best way forward because it
has already proven to work on at least two setups.

Thierry
-------------- next part --------------
A non-text attachment was scrubbed...
Name: signature.asc
Type: application/pgp-signature
Size: 819 bytes
Desc: not available
URL: <http://lists.infradead.org/pipermail/linux-arm-kernel/attachments/20150819/63181835/attachment.sig>

From mpa at pengutronix.de  Wed Aug 19 03:35:58 2015
From: mpa at pengutronix.de (Markus Pargmann)
Date: Wed, 19 Aug 2015 12:35:58 +0200
Subject: [PATCH 0/3] gpiolib: Initializing GPIOs using DT property
 gpio-initval
In-Reply-To: <1439979512-3894-1-git-send-email-mpa@pengutronix.de>
References: <1439979512-3894-1-git-send-email-mpa@pengutronix.de>
Message-ID: <20150819103558.GP11161@pengutronix.de>

On Wed, Aug 19, 2015 at 12:18:29PM +0200, Markus Pargmann wrote:
> Hi,
> 
> This series adds a gpio-initval property to the devicetree. It provides a way
> to initialize GPIOs to a defined value.
> 
> The previous patch was '[PATCH v2] gpio: Allow hogged gpios to be requested'
> which would have allowed to request hogged GPIOs. Linus suggested a separate DT
> property as hogged gpios should not be requested.
> 
> There are 3 patches. The first two simplify the function gpiod_hog. The third
> reuses the gpiod_hog()_code for a new gpiod_initialize() and adds the parsing
> of the DT.
> 
> This series is based on the series
> "[PATCH v3 0/9] gpiolib: Add GPIO name support".

Messed up all the author/signed-off-bys. I will fix it in v2 but will
wait for some feedback first.

Best regards,

Markus

> 
> Best regards,
> 
> Markus
> 
> 
> Markus Pargmann (3):
>   gpio: Use __gpiod_request directly
>   gpiolib: gpiod_hog remove separate name argument
>   gpiolib: Add GPIO initialization
> 
>  Documentation/devicetree/bindings/gpio/gpio.txt | 29 ++++++----
>  drivers/gpio/gpiolib-of.c                       | 11 +++-
>  drivers/gpio/gpiolib.c                          | 74 +++++++++++++++++--------
>  drivers/gpio/gpiolib.h                          |  6 +-
>  4 files changed, 83 insertions(+), 37 deletions(-)
> 
> -- 
> 2.4.6
> 
> 
> 

-- 
Pengutronix e.K.                           |                             |
Industrial Linux Solutions                 | http://www.pengutronix.de/  |
Peiner Str. 6-8, 31137 Hildesheim, Germany | Phone: +49-5121-206917-0    |
Amtsgericht Hildesheim, HRA 2686           | Fax:   +49-5121-206917-5555 |
-------------- next part --------------
A non-text attachment was scrubbed...
Name: signature.asc
Type: application/pgp-signature
Size: 819 bytes
Desc: Digital signature
URL: <http://lists.infradead.org/pipermail/linux-arm-kernel/attachments/20150819/bbf71c15/attachment.sig>

From maxime.coquelin at st.com  Wed Aug 19 03:55:05 2015
From: maxime.coquelin at st.com (Maxime Coquelin)
Date: Wed, 19 Aug 2015 12:55:05 +0200
Subject: [PATCH V3] Watchdog: Fix parent of watchdog_devices
In-Reply-To: <db7db9102158b87a4a7169e84e2272b3ba03f9f7.1439954581.git.panand@redhat.com>
References: <db7db9102158b87a4a7169e84e2272b3ba03f9f7.1439954581.git.panand@redhat.com>
Message-ID: <55D46089.8030801@st.com>

Hi Pratyush,

On 08/19/2015 05:28 AM, Pratyush Anand wrote:
> diff --git a/drivers/watchdog/st_lpc_wdt.c b/drivers/watchdog/st_lpc_wdt.c
> index 6785afdc0fca..14e9badf2bfa 100644
> --- a/drivers/watchdog/st_lpc_wdt.c
> +++ b/drivers/watchdog/st_lpc_wdt.c
> @@ -241,6 +241,7 @@ static int st_wdog_probe(struct platform_device *pdev)
>   		return -EINVAL;
>   	}
>   	st_wdog_dev.max_timeout = 0xFFFFFFFF / st_wdog->clkrate;
> +	st_wdog_dev.parent = &pdev->dev;
>   
>   	ret = clk_prepare_enable(clk);
>   	if (ret) {

Acked-by: Maxime Coquelin <maxime.coquelin at st.com>

Thanks!
Maxime


From yury.norov at gmail.com  Wed Aug 19 03:56:39 2015
From: yury.norov at gmail.com (Yury)
Date: Wed, 19 Aug 2015 13:56:39 +0300
Subject: [PATCH v5 1/5] arm/arm64: add smccc ARCH32
In-Reply-To: <1439973629-19505-2-git-send-email-jens.wiklander@linaro.org>
References: <1439973629-19505-1-git-send-email-jens.wiklander@linaro.org>
 <1439973629-19505-2-git-send-email-jens.wiklander@linaro.org>
Message-ID: <55D460E7.9070104@gmail.com>

On 19.08.2015 11:40, Jens Wiklander wrote:
 >
 > Adds helpers to do SMC based on ARM SMC Calling Convention.
 > CONFIG_HAVE_SMCCC is enabled for architectures that may support
 > the SMC instruction. It's the responsibility of the caller to
 > know if the SMC instruction is supported by the platform.
 >
 > Signed-off-by: Jens Wiklander <jens.wiklander at linaro.org>
 > ---
 >  arch/arm/Kconfig               |  4 +++
 >  arch/arm/kernel/Makefile       |  2 ++
 >  arch/arm/kernel/smccc-call.S   | 26 ++++++++++++++
 >  arch/arm/kernel/smccc.c        | 17 +++++++++
 >  arch/arm64/Kconfig             |  4 +++
 >  arch/arm64/kernel/Makefile     |  1 +
 >  arch/arm64/kernel/smccc-call.S | 34 ++++++++++++++++++
 >  arch/arm64/kernel/smccc.c      | 17 +++++++++
 >  include/linux/arm-smccc.h      | 79 
++++++++++++++++++++++++++++++++++++++++++
 >  9 files changed, 184 insertions(+)
 >  create mode 100644 arch/arm/kernel/smccc-call.S
 >  create mode 100644 arch/arm/kernel/smccc.c
 >  create mode 100644 arch/arm64/kernel/smccc-call.S
 >  create mode 100644 arch/arm64/kernel/smccc.c
 >  create mode 100644 include/linux/arm-smccc.h
 >
 > diff --git a/arch/arm/Kconfig b/arch/arm/Kconfig
 > index 45df48b..75e4da3 100644
 > --- a/arch/arm/Kconfig
 > +++ b/arch/arm/Kconfig
 > @@ -221,6 +221,9 @@ config NEED_RET_TO_USER
 >  config ARCH_MTD_XIP
 >  	bool
 >
 > +config HAVE_SMCCC
 > +	bool
 > +
 >  config VECTORS_BASE
 >  	hex
 >  	default 0xffff0000 if MMU || CPU_HIGH_VECTOR
 > @@ -324,6 +327,7 @@ config ARCH_MULTIPLATFORM
 >  	select CLKSRC_OF
 >  	select COMMON_CLK
 >  	select GENERIC_CLOCKEVENTS
 > +	select HAVE_SMCCC if CPU_V7
 >  	select MIGHT_HAVE_PCI
 >  	select MULTI_IRQ_HANDLER
 >  	select SPARSE_IRQ
 > diff --git a/arch/arm/kernel/Makefile b/arch/arm/kernel/Makefile
 > index 752725d..8cdd25b 100644
 > --- a/arch/arm/kernel/Makefile
 > +++ b/arch/arm/kernel/Makefile
 > @@ -90,4 +90,6 @@ obj-y				+= psci.o psci-call.o
 >  obj-$(CONFIG_SMP)		+= psci_smp.o
 >  endif
 >
 > +obj-$(CONFIG_HAVE_SMCCC)	+= smccc-call.o smccc.o
 > +
 >  extra-y := $(head-y) vmlinux.lds
 > diff --git a/arch/arm/kernel/smccc-call.S b/arch/arm/kernel/smccc-call.S
 > new file mode 100644
 > index 0000000..05bc554
 > --- /dev/null
 > +++ b/arch/arm/kernel/smccc-call.S
 > @@ -0,0 +1,26 @@
 > +/*
 > + * Copyright (c) 2015, Linaro Limited
 > + *
 > + * This software is licensed under the terms of the GNU General Public
 > + * License version 2, as published by the Free Software Foundation, and
 > + * may be copied, distributed, and modified under those terms.
 > + *
 > + * This program is distributed in the hope that it will be useful,
 > + * but WITHOUT ANY WARRANTY; without even the implied warranty of
 > + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
 > + * GNU General Public License for more details.
 > + *
 > + */
 > +#include <linux/linkage.h>
 > +
 > +#include <asm/opcodes-sec.h>
 > +
 > +/* void smccc_call32(struct smccc_param32 *param) */
 > +ENTRY(smccc_call32)
 > +	push	{r4-r8, lr}
 > +	mov	r8, r0
 > +	ldm	r8, {r0-r7}
 > +	__SMC(0)
 > +	stm	r8, {r0-r7}
 > +	pop	{r4-r8, pc}
 > +ENDPROC(smccc_call32)
 > diff --git a/arch/arm/kernel/smccc.c b/arch/arm/kernel/smccc.c
 > new file mode 100644
 > index 0000000..ba4039e
 > --- /dev/null
 > +++ b/arch/arm/kernel/smccc.c
 > @@ -0,0 +1,17 @@
 > +/*
 > + * Copyright (c) 2015, Linaro Limited
 > + *
 > + * This software is licensed under the terms of the GNU General Public
 > + * License version 2, as published by the Free Software Foundation, and
 > + * may be copied, distributed, and modified under those terms.
 > + *
 > + * This program is distributed in the hope that it will be useful,
 > + * but WITHOUT ANY WARRANTY; without even the implied warranty of
 > + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
 > + * GNU General Public License for more details.
 > + *
 > + */
 > +#include <linux/export.h>
 > +#include <linux/arm-smccc.h>
 > +
 > +EXPORT_SYMBOL_GPL(smccc_call32);
 > diff --git a/arch/arm64/Kconfig b/arch/arm64/Kconfig
 > index 7796af4..b3ea778 100644
 > --- a/arch/arm64/Kconfig
 > +++ b/arch/arm64/Kconfig
 > @@ -83,6 +83,7 @@ config ARM64
 >  	select SPARSE_IRQ
 >  	select SYSCTL_EXCEPTION_TRACE
 >  	select HAVE_CONTEXT_TRACKING
 > +	select HAVE_SMCCC
 >  	help
 >  	  ARM 64-bit (AArch64) Linux support.
 >
 > @@ -146,6 +147,9 @@ config KERNEL_MODE_NEON
 >  config FIX_EARLYCON_MEM
 >  	def_bool y
 >
 > +config HAVE_SMCCC
 > +	bool
 > +
 >  config PGTABLE_LEVELS
 >  	int
 >  	default 2 if ARM64_64K_PAGES && ARM64_VA_BITS_42
 > diff --git a/arch/arm64/kernel/Makefile b/arch/arm64/kernel/Makefile
 > index 426d076..f7804f7 100644
 > --- a/arch/arm64/kernel/Makefile
 > +++ b/arch/arm64/kernel/Makefile
 > @@ -36,6 +36,7 @@ arm64-obj-$(CONFIG_EFI)			+= efi.o efi-stub.o 
efi-entry.o
 >  arm64-obj-$(CONFIG_PCI)			+= pci.o
 >  arm64-obj-$(CONFIG_ARMV8_DEPRECATED)	+= armv8_deprecated.o
 >  arm64-obj-$(CONFIG_ACPI)		+= acpi.o
 > +arm64-obj-$(CONFIG_HAVE_SMCCC)		+= smccc-call.o smccc.o
 >
 >  obj-y					+= $(arm64-obj-y) vdso/
 >  obj-m					+= $(arm64-obj-m)
 > diff --git a/arch/arm64/kernel/smccc-call.S 
b/arch/arm64/kernel/smccc-call.S
 > new file mode 100644
 > index 0000000..3ce7fe8
 > --- /dev/null
 > +++ b/arch/arm64/kernel/smccc-call.S
 > @@ -0,0 +1,34 @@
 > +/*
 > + * Copyright (c) 2015, Linaro Limited
 > + *
 > + * 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/linkage.h>
 > +
 > +#define SMC_PARAM_W0_OFFS	0
 > +#define SMC_PARAM_W2_OFFS	8
 > +#define SMC_PARAM_W4_OFFS	16
 > +#define SMC_PARAM_W6_OFFS	24
 > +
 > +/* void smccc_call32(struct smccc_param32 *param) */
 > +ENTRY(smccc_call32)
 > +	stp	x28, x30, [sp, #-16]!
 > +	mov	x28, x0
 > +	ldp	w0, w1, [x28, #SMC_PARAM_W0_OFFS]
 > +	ldp	w2, w3, [x28, #SMC_PARAM_W2_OFFS]
 > +	ldp	w4, w5, [x28, #SMC_PARAM_W4_OFFS]
 > +	ldp	w6, w7, [x28, #SMC_PARAM_W6_OFFS]
 > +	smc	#0
 > +	stp	w0, w1, [x28, #SMC_PARAM_W0_OFFS]
 > +	stp	w2, w3, [x28, #SMC_PARAM_W2_OFFS]
 > +	ldp	x28, x30, [sp], #16
 > +	ret
 > +ENDPROC(smccc_call32)
 > diff --git a/arch/arm64/kernel/smccc.c b/arch/arm64/kernel/smccc.c
 > new file mode 100644
 > index 0000000..ba4039e
 > --- /dev/null
 > +++ b/arch/arm64/kernel/smccc.c
 > @@ -0,0 +1,17 @@
 > +/*
 > + * Copyright (c) 2015, Linaro Limited
 > + *
 > + * This software is licensed under the terms of the GNU General Public
 > + * License version 2, as published by the Free Software Foundation, and
 > + * may be copied, distributed, and modified under those terms.
 > + *
 > + * This program is distributed in the hope that it will be useful,
 > + * but WITHOUT ANY WARRANTY; without even the implied warranty of
 > + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
 > + * GNU General Public License for more details.
 > + *
 > + */
 > +#include <linux/export.h>
 > +#include <linux/arm-smccc.h>
 > +
 > +EXPORT_SYMBOL_GPL(smccc_call32);
 > diff --git a/include/linux/arm-smccc.h b/include/linux/arm-smccc.h
 > new file mode 100644
 > index 0000000..9b8d775
 > --- /dev/null
 > +++ b/include/linux/arm-smccc.h
 > @@ -0,0 +1,79 @@
 > +/*
 > + * Copyright (c) 2015, Linaro Limited
 > + *
 > + * This software is licensed under the terms of the GNU General Public
 > + * License version 2, as published by the Free Software Foundation, and
 > + * may be copied, distributed, and modified under those terms.
 > + *
 > + * This program is distributed in the hope that it will be useful,
 > + * but WITHOUT ANY WARRANTY; without even the implied warranty of
 > + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
 > + * GNU General Public License for more details.
 > + *
 > + */
 > +#ifndef __LINUX_ARM_SMCCC_H
 > +#define __LINUX_ARM_SMCCC_H
 > +
 > +#include <linux/types.h>
 > +
 > +/*
 > + * This file provideds defines common defines for ARM SMC Calling

typos here?

 > + * Convention as specified in
 > + * http://infocenter.arm.com/help/topic/com.arm.doc.den0028a/index.html
 > + */
 > +
 > +#define SMCCC_SMC_32			(0 << 30)

0 << 30 is just 0, and so meaningless.
It's better to introduce SMCCC_IS_32() macro instead.

 > +#define SMCCC_SMC_64			(1 << 30)
 > +#define SMCCC_FAST_CALL			(1 << 31)
 > +#define SMCCC_STD_CALL			(0 << 31)

The same

 > +
 > +#define SMCCC_OWNER_MASK		0x3F
 > +#define SMCCC_OWNER_SHIFT		24
 > +
 > +#define SMCCC_FUNC_MASK			0xFFFF
 > +
 > +#define SMCCC_IS_FAST_CALL(smc_val)	((smc_val) & SMCCC_FAST_CALL)
 > +#define SMCCC_IS_64(smc_val)		((smc_val) & SMCCC_SMC_64)
 > +#define SMCCC_FUNC_NUM(smc_val)		((smc_val) & SMCCC_FUNC_MASK)
 > +#define SMCCC_OWNER_NUM(smc_val) \
 > +	(((smc_val) >> SMCCC_OWNER_SHIFT) & SMCCC_OWNER_MASK)
 > +
 > +#define SMCCC_CALL_VAL(type, calling_convention, owner, func_num) \
 > +			((type) | (calling_convention) | \
 > +			(((owner) & SMCCC_OWNER_MASK) << SMCCC_OWNER_SHIFT) | \
 > +			((func_num) & SMCCC_FUNC_MASK))
 > +
 > +#define SMCCC_OWNER_ARCH		0
 > +#define SMCCC_OWNER_CPU			1
 > +#define SMCCC_OWNER_SIP			2
 > +#define SMCCC_OWNER_OEM			3
 > +#define SMCCC_OWNER_STANDARD		4
 > +#define SMCCC_OWNER_TRUSTED_APP		48
 > +#define SMCCC_OWNER_TRUSTED_APP_END	49
 > +#define SMCCC_OWNER_TRUSTED_OS		50
 > +#define SMCCC_OWNER_TRUSTED_OS_END	63
 > +
 > +struct smccc_param32 {
 > +	u32 a0;
 > +	u32 a1;
 > +	u32 a2;
 > +	u32 a3;
 > +	u32 a4;
 > +	u32 a5;
 > +	u32 a6;
 > +	u32 a7;
 > +};
 > +
 > +/**
 > + * smccc_call32() - make ARCH32 SMC calls
 > + * @param: values to pass in registers 0 to 7
 > + *
 > + * This function is used to make SMC calls following SMC Calling 
Convention
 > + * for ARCH32 calls. The content of the supplied param are copied to
 > + * registers 0 to 7 prior to the SMC instruction. Values a0..a3 are 
updated
 > + * with the content from register 0 to 3 on return from the SMC
 > + * instruction.
 > + */
 > +void smccc_call32(struct smccc_param32 *param);
 > +
 > +#endif /*__LINUX_ARM_SMCCC_H*/
 > --
 > 1.9.1
 >
 >
 > _______________________________________________
 > linux-arm-kernel mailing list
 > linux-arm-kernel at lists.infradead.org
 > http://lists.infradead.org/mailman/listinfo/linux-arm-kernel


From mchehab at osg.samsung.com  Wed Aug 19 04:01:55 2015
From: mchehab at osg.samsung.com (Mauro Carvalho Chehab)
Date: Wed, 19 Aug 2015 08:01:55 -0300
Subject: [PATCH v6 8/8] [media] media: rename the function that create pad
 links
In-Reply-To: <cover.1439981515.git.mchehab@osg.samsung.com>
References: <cover.1439981515.git.mchehab@osg.samsung.com>
Message-ID: <457d0f95f932b0f8e035d0500788fe4046ff95ca.1439981515.git.mchehab@osg.samsung.com>

Now that a link can be either between two different graph
objects, we'll need to add more functions to create links.
So, rename the existing one that create links only between
two pads as media_create_pad_link().

No functional changes.

This patch was created via this shell script:
	for i in $(find drivers/media -name '*.[ch]' -type f) $(find drivers/staging/media -name '*.[ch]' -type f) $(find include/ -name '*.h' -type f) ; do sed s,media_entity_create_link,media_create_pad_link,g <$i >a && mv a $i; done

Signed-off-by: Mauro Carvalho Chehab <mchehab at osg.samsung.com>
Acked-by: Hans Verkuil <hans.verkuil at cisco.com>

diff --git a/Documentation/media-framework.txt b/Documentation/media-framework.txt
index 6903b2503577..b424de6c3bb3 100644
--- a/Documentation/media-framework.txt
+++ b/Documentation/media-framework.txt
@@ -199,7 +199,7 @@ pre-allocated and grows dynamically as needed.
 
 Drivers create links by calling
 
-	media_entity_create_link(struct media_entity *source, u16 source_pad,
+	media_create_pad_link(struct media_entity *source, u16 source_pad,
 				 struct media_entity *sink,   u16 sink_pad,
 				 u32 flags);
 
diff --git a/drivers/media/dvb-core/dvbdev.c b/drivers/media/dvb-core/dvbdev.c
index 2fdcbb5f000a..65f59f2124b4 100644
--- a/drivers/media/dvb-core/dvbdev.c
+++ b/drivers/media/dvb-core/dvbdev.c
@@ -412,16 +412,16 @@ void dvb_create_media_graph(struct dvb_adapter *adap)
 	}
 
 	if (tuner && fe)
-		media_entity_create_link(tuner, 0, fe, 0, 0);
+		media_create_pad_link(tuner, 0, fe, 0, 0);
 
 	if (fe && demux)
-		media_entity_create_link(fe, 1, demux, 0, MEDIA_LNK_FL_ENABLED);
+		media_create_pad_link(fe, 1, demux, 0, MEDIA_LNK_FL_ENABLED);
 
 	if (demux && dvr)
-		media_entity_create_link(demux, 1, dvr, 0, MEDIA_LNK_FL_ENABLED);
+		media_create_pad_link(demux, 1, dvr, 0, MEDIA_LNK_FL_ENABLED);
 
 	if (demux && ca)
-		media_entity_create_link(demux, 1, ca, 0, MEDIA_LNK_FL_ENABLED);
+		media_create_pad_link(demux, 1, ca, 0, MEDIA_LNK_FL_ENABLED);
 }
 EXPORT_SYMBOL_GPL(dvb_create_media_graph);
 #endif
diff --git a/drivers/media/i2c/s5c73m3/s5c73m3-core.c b/drivers/media/i2c/s5c73m3/s5c73m3-core.c
index 6d167428727d..c81bfbfea32f 100644
--- a/drivers/media/i2c/s5c73m3/s5c73m3-core.c
+++ b/drivers/media/i2c/s5c73m3/s5c73m3-core.c
@@ -1482,11 +1482,11 @@ static int s5c73m3_oif_registered(struct v4l2_subdev *sd)
 		return ret;
 	}
 
-	ret = media_entity_create_link(&state->sensor_sd.entity,
+	ret = media_create_pad_link(&state->sensor_sd.entity,
 			S5C73M3_ISP_PAD, &state->oif_sd.entity, OIF_ISP_PAD,
 			MEDIA_LNK_FL_IMMUTABLE | MEDIA_LNK_FL_ENABLED);
 
-	ret = media_entity_create_link(&state->sensor_sd.entity,
+	ret = media_create_pad_link(&state->sensor_sd.entity,
 			S5C73M3_JPEG_PAD, &state->oif_sd.entity, OIF_JPEG_PAD,
 			MEDIA_LNK_FL_IMMUTABLE | MEDIA_LNK_FL_ENABLED);
 
diff --git a/drivers/media/i2c/s5k5baf.c b/drivers/media/i2c/s5k5baf.c
index 30a9ca62e034..d3bff30bcb6f 100644
--- a/drivers/media/i2c/s5k5baf.c
+++ b/drivers/media/i2c/s5k5baf.c
@@ -1756,7 +1756,7 @@ static int s5k5baf_registered(struct v4l2_subdev *sd)
 		v4l2_err(sd, "failed to register subdev %s\n",
 			 state->cis_sd.name);
 	else
-		ret = media_entity_create_link(&state->cis_sd.entity, PAD_CIS,
+		ret = media_create_pad_link(&state->cis_sd.entity, PAD_CIS,
 					       &state->sd.entity, PAD_CIS,
 					       MEDIA_LNK_FL_IMMUTABLE |
 					       MEDIA_LNK_FL_ENABLED);
diff --git a/drivers/media/i2c/smiapp/smiapp-core.c b/drivers/media/i2c/smiapp/smiapp-core.c
index 308613ea0aed..5aa49eb393a9 100644
--- a/drivers/media/i2c/smiapp/smiapp-core.c
+++ b/drivers/media/i2c/smiapp/smiapp-core.c
@@ -2495,7 +2495,7 @@ static int smiapp_register_subdevs(struct smiapp_sensor *sensor)
 			return rval;
 		}
 
-		rval = media_entity_create_link(&this->sd.entity,
+		rval = media_create_pad_link(&this->sd.entity,
 						this->source_pad,
 						&last->sd.entity,
 						last->sink_pad,
@@ -2503,7 +2503,7 @@ static int smiapp_register_subdevs(struct smiapp_sensor *sensor)
 						MEDIA_LNK_FL_IMMUTABLE);
 		if (rval) {
 			dev_err(&client->dev,
-				"media_entity_create_link failed\n");
+				"media_create_pad_link failed\n");
 			return rval;
 		}
 
diff --git a/drivers/media/media-entity.c b/drivers/media/media-entity.c
index 6d515e149d7f..35e52cd1fc5a 100644
--- a/drivers/media/media-entity.c
+++ b/drivers/media/media-entity.c
@@ -542,7 +542,7 @@ static struct media_link *media_entity_add_link(struct media_entity *entity)
 }
 
 int
-media_entity_create_link(struct media_entity *source, u16 source_pad,
+media_create_pad_link(struct media_entity *source, u16 source_pad,
 			 struct media_entity *sink, u16 sink_pad, u32 flags)
 {
 	struct media_link *link;
@@ -586,7 +586,7 @@ media_entity_create_link(struct media_entity *source, u16 source_pad,
 
 	return 0;
 }
-EXPORT_SYMBOL_GPL(media_entity_create_link);
+EXPORT_SYMBOL_GPL(media_create_pad_link);
 
 void __media_entity_remove_links(struct media_entity *entity)
 {
diff --git a/drivers/media/platform/exynos4-is/media-dev.c b/drivers/media/platform/exynos4-is/media-dev.c
index 4f5586a4cbff..3ba76940eef5 100644
--- a/drivers/media/platform/exynos4-is/media-dev.c
+++ b/drivers/media/platform/exynos4-is/media-dev.c
@@ -729,7 +729,7 @@ static int __fimc_md_create_fimc_sink_links(struct fimc_md *fmd,
 		flags = ((1 << i) & link_mask) ? MEDIA_LNK_FL_ENABLED : 0;
 
 		sink = &fmd->fimc[i]->vid_cap.subdev.entity;
-		ret = media_entity_create_link(source, pad, sink,
+		ret = media_create_pad_link(source, pad, sink,
 					      FIMC_SD_PAD_SINK_CAM, flags);
 		if (ret)
 			return ret;
@@ -749,7 +749,7 @@ static int __fimc_md_create_fimc_sink_links(struct fimc_md *fmd,
 			continue;
 
 		sink = &fmd->fimc_lite[i]->subdev.entity;
-		ret = media_entity_create_link(source, pad, sink,
+		ret = media_create_pad_link(source, pad, sink,
 					       FLITE_SD_PAD_SINK, 0);
 		if (ret)
 			return ret;
@@ -781,13 +781,13 @@ static int __fimc_md_create_flite_source_links(struct fimc_md *fmd)
 		source = &fimc->subdev.entity;
 		sink = &fimc->ve.vdev.entity;
 		/* FIMC-LITE's subdev and video node */
-		ret = media_entity_create_link(source, FLITE_SD_PAD_SOURCE_DMA,
+		ret = media_create_pad_link(source, FLITE_SD_PAD_SOURCE_DMA,
 					       sink, 0, 0);
 		if (ret)
 			break;
 		/* Link from FIMC-LITE to IS-ISP subdev */
 		sink = &fmd->fimc_is->isp.subdev.entity;
-		ret = media_entity_create_link(source, FLITE_SD_PAD_SOURCE_ISP,
+		ret = media_create_pad_link(source, FLITE_SD_PAD_SOURCE_ISP,
 					       sink, 0, 0);
 		if (ret)
 			break;
@@ -811,7 +811,7 @@ static int __fimc_md_create_fimc_is_links(struct fimc_md *fmd)
 
 		/* Link from FIMC-IS-ISP subdev to FIMC */
 		sink = &fmd->fimc[i]->vid_cap.subdev.entity;
-		ret = media_entity_create_link(source, FIMC_ISP_SD_PAD_SRC_FIFO,
+		ret = media_create_pad_link(source, FIMC_ISP_SD_PAD_SRC_FIFO,
 					       sink, FIMC_SD_PAD_SINK_FIFO, 0);
 		if (ret)
 			return ret;
@@ -824,7 +824,7 @@ static int __fimc_md_create_fimc_is_links(struct fimc_md *fmd)
 	if (sink->num_pads == 0)
 		return 0;
 
-	return media_entity_create_link(source, FIMC_ISP_SD_PAD_SRC_DMA,
+	return media_create_pad_link(source, FIMC_ISP_SD_PAD_SRC_DMA,
 					sink, 0, 0);
 }
 
@@ -873,7 +873,7 @@ static int fimc_md_create_links(struct fimc_md *fmd)
 				return -EINVAL;
 
 			pad = sensor->entity.num_pads - 1;
-			ret = media_entity_create_link(&sensor->entity, pad,
+			ret = media_create_pad_link(&sensor->entity, pad,
 					      &csis->entity, CSIS_PAD_SINK,
 					      MEDIA_LNK_FL_IMMUTABLE |
 					      MEDIA_LNK_FL_ENABLED);
@@ -927,7 +927,7 @@ static int fimc_md_create_links(struct fimc_md *fmd)
 		source = &fmd->fimc[i]->vid_cap.subdev.entity;
 		sink = &fmd->fimc[i]->vid_cap.ve.vdev.entity;
 
-		ret = media_entity_create_link(source, FIMC_SD_PAD_SOURCE,
+		ret = media_create_pad_link(source, FIMC_SD_PAD_SOURCE,
 					      sink, 0, flags);
 		if (ret)
 			break;
diff --git a/drivers/media/platform/omap3isp/isp.c b/drivers/media/platform/omap3isp/isp.c
index 56e683b19a73..d6b2922ed55c 100644
--- a/drivers/media/platform/omap3isp/isp.c
+++ b/drivers/media/platform/omap3isp/isp.c
@@ -1862,7 +1862,7 @@ static int isp_link_entity(
 		return -EINVAL;
 	}
 
-	return media_entity_create_link(entity, i, input, pad, flags);
+	return media_create_pad_link(entity, i, input, pad, flags);
 }
 
 static int isp_register_entities(struct isp_device *isp)
@@ -2001,51 +2001,51 @@ static int isp_initialize_modules(struct isp_device *isp)
 	}
 
 	/* Connect the submodules. */
-	ret = media_entity_create_link(
+	ret = media_create_pad_link(
 			&isp->isp_csi2a.subdev.entity, CSI2_PAD_SOURCE,
 			&isp->isp_ccdc.subdev.entity, CCDC_PAD_SINK, 0);
 	if (ret < 0)
 		goto error_link;
 
-	ret = media_entity_create_link(
+	ret = media_create_pad_link(
 			&isp->isp_ccp2.subdev.entity, CCP2_PAD_SOURCE,
 			&isp->isp_ccdc.subdev.entity, CCDC_PAD_SINK, 0);
 	if (ret < 0)
 		goto error_link;
 
-	ret = media_entity_create_link(
+	ret = media_create_pad_link(
 			&isp->isp_ccdc.subdev.entity, CCDC_PAD_SOURCE_VP,
 			&isp->isp_prev.subdev.entity, PREV_PAD_SINK, 0);
 	if (ret < 0)
 		goto error_link;
 
-	ret = media_entity_create_link(
+	ret = media_create_pad_link(
 			&isp->isp_ccdc.subdev.entity, CCDC_PAD_SOURCE_OF,
 			&isp->isp_res.subdev.entity, RESZ_PAD_SINK, 0);
 	if (ret < 0)
 		goto error_link;
 
-	ret = media_entity_create_link(
+	ret = media_create_pad_link(
 			&isp->isp_prev.subdev.entity, PREV_PAD_SOURCE,
 			&isp->isp_res.subdev.entity, RESZ_PAD_SINK, 0);
 	if (ret < 0)
 		goto error_link;
 
-	ret = media_entity_create_link(
+	ret = media_create_pad_link(
 			&isp->isp_ccdc.subdev.entity, CCDC_PAD_SOURCE_VP,
 			&isp->isp_aewb.subdev.entity, 0,
 			MEDIA_LNK_FL_ENABLED | MEDIA_LNK_FL_IMMUTABLE);
 	if (ret < 0)
 		goto error_link;
 
-	ret = media_entity_create_link(
+	ret = media_create_pad_link(
 			&isp->isp_ccdc.subdev.entity, CCDC_PAD_SOURCE_VP,
 			&isp->isp_af.subdev.entity, 0,
 			MEDIA_LNK_FL_ENABLED | MEDIA_LNK_FL_IMMUTABLE);
 	if (ret < 0)
 		goto error_link;
 
-	ret = media_entity_create_link(
+	ret = media_create_pad_link(
 			&isp->isp_ccdc.subdev.entity, CCDC_PAD_SOURCE_VP,
 			&isp->isp_hist.subdev.entity, 0,
 			MEDIA_LNK_FL_ENABLED | MEDIA_LNK_FL_IMMUTABLE);
diff --git a/drivers/media/platform/omap3isp/ispccdc.c b/drivers/media/platform/omap3isp/ispccdc.c
index 3b10304b580b..3fe425f254bb 100644
--- a/drivers/media/platform/omap3isp/ispccdc.c
+++ b/drivers/media/platform/omap3isp/ispccdc.c
@@ -2667,7 +2667,7 @@ static int ccdc_init_entities(struct isp_ccdc_device *ccdc)
 		goto error_video;
 
 	/* Connect the CCDC subdev to the video node. */
-	ret = media_entity_create_link(&ccdc->subdev.entity, CCDC_PAD_SOURCE_OF,
+	ret = media_create_pad_link(&ccdc->subdev.entity, CCDC_PAD_SOURCE_OF,
 			&ccdc->video_out.video.entity, 0, 0);
 	if (ret < 0)
 		goto error_link;
diff --git a/drivers/media/platform/omap3isp/ispccp2.c b/drivers/media/platform/omap3isp/ispccp2.c
index e1b5f5bea541..b215eb5049d6 100644
--- a/drivers/media/platform/omap3isp/ispccp2.c
+++ b/drivers/media/platform/omap3isp/ispccp2.c
@@ -1100,7 +1100,7 @@ static int ccp2_init_entities(struct isp_ccp2_device *ccp2)
 		goto error_video;
 
 	/* Connect the video node to the ccp2 subdev. */
-	ret = media_entity_create_link(&ccp2->video_in.video.entity, 0,
+	ret = media_create_pad_link(&ccp2->video_in.video.entity, 0,
 				       &ccp2->subdev.entity, CCP2_PAD_SINK, 0);
 	if (ret < 0)
 		goto error_link;
diff --git a/drivers/media/platform/omap3isp/ispcsi2.c b/drivers/media/platform/omap3isp/ispcsi2.c
index 6fff92f0813a..fcefc1e74881 100644
--- a/drivers/media/platform/omap3isp/ispcsi2.c
+++ b/drivers/media/platform/omap3isp/ispcsi2.c
@@ -1265,7 +1265,7 @@ static int csi2_init_entities(struct isp_csi2_device *csi2)
 		goto error_video;
 
 	/* Connect the CSI2 subdev to the video node. */
-	ret = media_entity_create_link(&csi2->subdev.entity, CSI2_PAD_SOURCE,
+	ret = media_create_pad_link(&csi2->subdev.entity, CSI2_PAD_SOURCE,
 				       &csi2->video_out.video.entity, 0, 0);
 	if (ret < 0)
 		goto error_link;
diff --git a/drivers/media/platform/omap3isp/isppreview.c b/drivers/media/platform/omap3isp/isppreview.c
index b440c6342ca4..ad38d20c7770 100644
--- a/drivers/media/platform/omap3isp/isppreview.c
+++ b/drivers/media/platform/omap3isp/isppreview.c
@@ -2312,12 +2312,12 @@ static int preview_init_entities(struct isp_prev_device *prev)
 		goto error_video_out;
 
 	/* Connect the video nodes to the previewer subdev. */
-	ret = media_entity_create_link(&prev->video_in.video.entity, 0,
+	ret = media_create_pad_link(&prev->video_in.video.entity, 0,
 			&prev->subdev.entity, PREV_PAD_SINK, 0);
 	if (ret < 0)
 		goto error_link;
 
-	ret = media_entity_create_link(&prev->subdev.entity, PREV_PAD_SOURCE,
+	ret = media_create_pad_link(&prev->subdev.entity, PREV_PAD_SOURCE,
 			&prev->video_out.video.entity, 0, 0);
 	if (ret < 0)
 		goto error_link;
diff --git a/drivers/media/platform/omap3isp/ispresizer.c b/drivers/media/platform/omap3isp/ispresizer.c
index 3deb1ec4a973..b48ad4d4b834 100644
--- a/drivers/media/platform/omap3isp/ispresizer.c
+++ b/drivers/media/platform/omap3isp/ispresizer.c
@@ -1756,12 +1756,12 @@ static int resizer_init_entities(struct isp_res_device *res)
 	res->video_out.video.entity.flags |= MEDIA_ENT_FL_DEFAULT;
 
 	/* Connect the video nodes to the resizer subdev. */
-	ret = media_entity_create_link(&res->video_in.video.entity, 0,
+	ret = media_create_pad_link(&res->video_in.video.entity, 0,
 			&res->subdev.entity, RESZ_PAD_SINK, 0);
 	if (ret < 0)
 		goto error_link;
 
-	ret = media_entity_create_link(&res->subdev.entity, RESZ_PAD_SOURCE,
+	ret = media_create_pad_link(&res->subdev.entity, RESZ_PAD_SOURCE,
 			&res->video_out.video.entity, 0, 0);
 	if (ret < 0)
 		goto error_link;
diff --git a/drivers/media/platform/s3c-camif/camif-core.c b/drivers/media/platform/s3c-camif/camif-core.c
index f47b332f0418..3e33c60be004 100644
--- a/drivers/media/platform/s3c-camif/camif-core.c
+++ b/drivers/media/platform/s3c-camif/camif-core.c
@@ -263,7 +263,7 @@ static int camif_create_media_links(struct camif_dev *camif)
 {
 	int i, ret;
 
-	ret = media_entity_create_link(&camif->sensor.sd->entity, 0,
+	ret = media_create_pad_link(&camif->sensor.sd->entity, 0,
 				&camif->subdev.entity, CAMIF_SD_PAD_SINK,
 				MEDIA_LNK_FL_IMMUTABLE |
 				MEDIA_LNK_FL_ENABLED);
@@ -271,7 +271,7 @@ static int camif_create_media_links(struct camif_dev *camif)
 		return ret;
 
 	for (i = 1; i < CAMIF_SD_PADS_NUM && !ret; i++) {
-		ret = media_entity_create_link(&camif->subdev.entity, i,
+		ret = media_create_pad_link(&camif->subdev.entity, i,
 				&camif->vp[i - 1].vdev.entity, 0,
 				MEDIA_LNK_FL_IMMUTABLE |
 				MEDIA_LNK_FL_ENABLED);
diff --git a/drivers/media/platform/vsp1/vsp1_drv.c b/drivers/media/platform/vsp1/vsp1_drv.c
index 4e61886384e3..9cd94a76a9ed 100644
--- a/drivers/media/platform/vsp1/vsp1_drv.c
+++ b/drivers/media/platform/vsp1/vsp1_drv.c
@@ -101,7 +101,7 @@ static int vsp1_create_links(struct vsp1_device *vsp1, struct vsp1_entity *sink)
 			if (!(entity->pads[pad].flags & MEDIA_PAD_FL_SINK))
 				continue;
 
-			ret = media_entity_create_link(&source->subdev.entity,
+			ret = media_create_pad_link(&source->subdev.entity,
 						       source->source_pad,
 						       entity, pad, flags);
 			if (ret < 0)
@@ -262,7 +262,7 @@ static int vsp1_create_entities(struct vsp1_device *vsp1)
 	}
 
 	if (vsp1->pdata.features & VSP1_HAS_LIF) {
-		ret = media_entity_create_link(
+		ret = media_create_pad_link(
 			&vsp1->wpf[0]->entity.subdev.entity, RWPF_PAD_SOURCE,
 			&vsp1->lif->entity.subdev.entity, LIF_PAD_SINK, 0);
 		if (ret < 0)
diff --git a/drivers/media/platform/vsp1/vsp1_rpf.c b/drivers/media/platform/vsp1/vsp1_rpf.c
index 3294529a3108..b60a528a8fe8 100644
--- a/drivers/media/platform/vsp1/vsp1_rpf.c
+++ b/drivers/media/platform/vsp1/vsp1_rpf.c
@@ -278,7 +278,7 @@ struct vsp1_rwpf *vsp1_rpf_create(struct vsp1_device *vsp1, unsigned int index)
 	rpf->entity.video = video;
 
 	/* Connect the video device to the RPF. */
-	ret = media_entity_create_link(&rpf->video.video.entity, 0,
+	ret = media_create_pad_link(&rpf->video.video.entity, 0,
 				       &rpf->entity.subdev.entity,
 				       RWPF_PAD_SINK,
 				       MEDIA_LNK_FL_ENABLED |
diff --git a/drivers/media/platform/vsp1/vsp1_wpf.c b/drivers/media/platform/vsp1/vsp1_wpf.c
index 1d2b3a2f1573..d39aa4b8aea1 100644
--- a/drivers/media/platform/vsp1/vsp1_wpf.c
+++ b/drivers/media/platform/vsp1/vsp1_wpf.c
@@ -284,7 +284,7 @@ struct vsp1_rwpf *vsp1_wpf_create(struct vsp1_device *vsp1, unsigned int index)
 	if (!(vsp1->pdata.features & VSP1_HAS_LIF) || index != 0)
 		flags |= MEDIA_LNK_FL_IMMUTABLE;
 
-	ret = media_entity_create_link(&wpf->entity.subdev.entity,
+	ret = media_create_pad_link(&wpf->entity.subdev.entity,
 				       RWPF_PAD_SOURCE,
 				       &wpf->video.video.entity, 0, flags);
 	if (ret < 0)
diff --git a/drivers/media/platform/xilinx/xilinx-vipp.c b/drivers/media/platform/xilinx/xilinx-vipp.c
index 7b7cb9c28d2c..79d4be7ce9a5 100644
--- a/drivers/media/platform/xilinx/xilinx-vipp.c
+++ b/drivers/media/platform/xilinx/xilinx-vipp.c
@@ -156,7 +156,7 @@ static int xvip_graph_build_one(struct xvip_composite_device *xdev,
 			local->name, local_pad->index,
 			remote->name, remote_pad->index);
 
-		ret = media_entity_create_link(local, local_pad->index,
+		ret = media_create_pad_link(local, local_pad->index,
 					       remote, remote_pad->index,
 					       link_flags);
 		if (ret < 0) {
@@ -270,7 +270,7 @@ static int xvip_graph_build_dma(struct xvip_composite_device *xdev)
 			source->name, source_pad->index,
 			sink->name, sink_pad->index);
 
-		ret = media_entity_create_link(source, source_pad->index,
+		ret = media_create_pad_link(source, source_pad->index,
 					       sink, sink_pad->index,
 					       link_flags);
 		if (ret < 0) {
diff --git a/drivers/media/usb/au0828/au0828-core.c b/drivers/media/usb/au0828/au0828-core.c
index 0378a2c99ebb..a55eb524ea21 100644
--- a/drivers/media/usb/au0828/au0828-core.c
+++ b/drivers/media/usb/au0828/au0828-core.c
@@ -260,13 +260,13 @@ static void au0828_create_media_graph(struct au0828_dev *dev)
 		return;
 
 	if (tuner)
-		media_entity_create_link(tuner, 0, decoder, 0,
+		media_create_pad_link(tuner, 0, decoder, 0,
 					 MEDIA_LNK_FL_ENABLED);
 	if (dev->vdev.entity.links)
-		media_entity_create_link(decoder, 1, &dev->vdev.entity, 0,
+		media_create_pad_link(decoder, 1, &dev->vdev.entity, 0,
 				 MEDIA_LNK_FL_ENABLED);
 	if (dev->vbi_dev.entity.links)
-		media_entity_create_link(decoder, 2, &dev->vbi_dev.entity, 0,
+		media_create_pad_link(decoder, 2, &dev->vbi_dev.entity, 0,
 				 MEDIA_LNK_FL_ENABLED);
 #endif
 }
diff --git a/drivers/media/usb/cx231xx/cx231xx-cards.c b/drivers/media/usb/cx231xx/cx231xx-cards.c
index 4a117a58c39a..3b5c9ae39ad3 100644
--- a/drivers/media/usb/cx231xx/cx231xx-cards.c
+++ b/drivers/media/usb/cx231xx/cx231xx-cards.c
@@ -1264,11 +1264,11 @@ static void cx231xx_create_media_graph(struct cx231xx *dev)
 		return;
 
 	if (tuner)
-		media_entity_create_link(tuner, 0, decoder, 0,
+		media_create_pad_link(tuner, 0, decoder, 0,
 					 MEDIA_LNK_FL_ENABLED);
-	media_entity_create_link(decoder, 1, &dev->vdev.entity, 0,
+	media_create_pad_link(decoder, 1, &dev->vdev.entity, 0,
 				 MEDIA_LNK_FL_ENABLED);
-	media_entity_create_link(decoder, 2, &dev->vbi_dev.entity, 0,
+	media_create_pad_link(decoder, 2, &dev->vbi_dev.entity, 0,
 				 MEDIA_LNK_FL_ENABLED);
 #endif
 }
diff --git a/drivers/media/usb/uvc/uvc_entity.c b/drivers/media/usb/uvc/uvc_entity.c
index 245445491516..429e428ccd93 100644
--- a/drivers/media/usb/uvc/uvc_entity.c
+++ b/drivers/media/usb/uvc/uvc_entity.c
@@ -56,7 +56,7 @@ static int uvc_mc_register_entity(struct uvc_video_chain *chain,
 			continue;
 
 		remote_pad = remote->num_pads - 1;
-		ret = media_entity_create_link(source, remote_pad,
+		ret = media_create_pad_link(source, remote_pad,
 					       sink, i, flags);
 		if (ret < 0)
 			return ret;
diff --git a/drivers/staging/media/davinci_vpfe/dm365_ipipeif.c b/drivers/staging/media/davinci_vpfe/dm365_ipipeif.c
index 8fb676186898..d96bdaaae50e 100644
--- a/drivers/staging/media/davinci_vpfe/dm365_ipipeif.c
+++ b/drivers/staging/media/davinci_vpfe/dm365_ipipeif.c
@@ -971,7 +971,7 @@ vpfe_ipipeif_register_entities(struct vpfe_ipipeif_device *ipipeif,
 	ipipeif->video_in.vpfe_dev = vpfe_dev;
 
 	flags = 0;
-	ret = media_entity_create_link(&ipipeif->video_in.video_dev.entity, 0,
+	ret = media_create_pad_link(&ipipeif->video_in.video_dev.entity, 0,
 					&ipipeif->subdev.entity, 0, flags);
 	if (ret < 0)
 		goto fail;
diff --git a/drivers/staging/media/davinci_vpfe/dm365_isif.c b/drivers/staging/media/davinci_vpfe/dm365_isif.c
index b1f01adfa7c8..df77288b0ec0 100644
--- a/drivers/staging/media/davinci_vpfe/dm365_isif.c
+++ b/drivers/staging/media/davinci_vpfe/dm365_isif.c
@@ -1817,7 +1817,7 @@ int vpfe_isif_register_entities(struct vpfe_isif_device *isif,
 	isif->video_out.vpfe_dev = vpfe_dev;
 	flags = 0;
 	/* connect isif to video node */
-	ret = media_entity_create_link(&isif->subdev.entity, 1,
+	ret = media_create_pad_link(&isif->subdev.entity, 1,
 				       &isif->video_out.video_dev.entity,
 				       0, flags);
 	if (ret < 0)
diff --git a/drivers/staging/media/davinci_vpfe/dm365_resizer.c b/drivers/staging/media/davinci_vpfe/dm365_resizer.c
index 692789aa22f4..ae942de3a23d 100644
--- a/drivers/staging/media/davinci_vpfe/dm365_resizer.c
+++ b/drivers/staging/media/davinci_vpfe/dm365_resizer.c
@@ -1831,27 +1831,27 @@ int vpfe_resizer_register_entities(struct vpfe_resizer_device *resizer,
 	resizer->resizer_b.video_out.vpfe_dev = vpfe_dev;
 
 	/* create link between Resizer Crop----> Resizer A*/
-	ret = media_entity_create_link(&resizer->crop_resizer.subdev.entity, 1,
+	ret = media_create_pad_link(&resizer->crop_resizer.subdev.entity, 1,
 				&resizer->resizer_a.subdev.entity,
 				0, flags);
 	if (ret < 0)
 		goto out_create_link;
 
 	/* create link between Resizer Crop----> Resizer B*/
-	ret = media_entity_create_link(&resizer->crop_resizer.subdev.entity, 2,
+	ret = media_create_pad_link(&resizer->crop_resizer.subdev.entity, 2,
 				&resizer->resizer_b.subdev.entity,
 				0, flags);
 	if (ret < 0)
 		goto out_create_link;
 
 	/* create link between Resizer A ----> video out */
-	ret = media_entity_create_link(&resizer->resizer_a.subdev.entity, 1,
+	ret = media_create_pad_link(&resizer->resizer_a.subdev.entity, 1,
 		&resizer->resizer_a.video_out.video_dev.entity, 0, flags);
 	if (ret < 0)
 		goto out_create_link;
 
 	/* create link between Resizer B ----> video out */
-	ret = media_entity_create_link(&resizer->resizer_b.subdev.entity, 1,
+	ret = media_create_pad_link(&resizer->resizer_b.subdev.entity, 1,
 		&resizer->resizer_b.video_out.video_dev.entity, 0, flags);
 	if (ret < 0)
 		goto out_create_link;
diff --git a/drivers/staging/media/davinci_vpfe/vpfe_mc_capture.c b/drivers/staging/media/davinci_vpfe/vpfe_mc_capture.c
index 57426199ad7a..08c8a5f967d3 100644
--- a/drivers/staging/media/davinci_vpfe/vpfe_mc_capture.c
+++ b/drivers/staging/media/davinci_vpfe/vpfe_mc_capture.c
@@ -445,32 +445,32 @@ static int vpfe_register_entities(struct vpfe_device *vpfe_dev)
 		/* if entity has no pads (ex: amplifier),
 		   cant establish link */
 		if (vpfe_dev->sd[i]->entity.num_pads) {
-			ret = media_entity_create_link(&vpfe_dev->sd[i]->entity,
+			ret = media_create_pad_link(&vpfe_dev->sd[i]->entity,
 				0, &vpfe_dev->vpfe_isif.subdev.entity,
 				0, flags);
 			if (ret < 0)
 				goto out_resizer_register;
 		}
 
-	ret = media_entity_create_link(&vpfe_dev->vpfe_isif.subdev.entity, 1,
+	ret = media_create_pad_link(&vpfe_dev->vpfe_isif.subdev.entity, 1,
 				       &vpfe_dev->vpfe_ipipeif.subdev.entity,
 				       0, flags);
 	if (ret < 0)
 		goto out_resizer_register;
 
-	ret = media_entity_create_link(&vpfe_dev->vpfe_ipipeif.subdev.entity, 1,
+	ret = media_create_pad_link(&vpfe_dev->vpfe_ipipeif.subdev.entity, 1,
 				       &vpfe_dev->vpfe_ipipe.subdev.entity,
 				       0, flags);
 	if (ret < 0)
 		goto out_resizer_register;
 
-	ret = media_entity_create_link(&vpfe_dev->vpfe_ipipe.subdev.entity,
+	ret = media_create_pad_link(&vpfe_dev->vpfe_ipipe.subdev.entity,
 			1, &vpfe_dev->vpfe_resizer.crop_resizer.subdev.entity,
 			0, flags);
 	if (ret < 0)
 		goto out_resizer_register;
 
-	ret = media_entity_create_link(&vpfe_dev->vpfe_ipipeif.subdev.entity, 1,
+	ret = media_create_pad_link(&vpfe_dev->vpfe_ipipeif.subdev.entity, 1,
 			&vpfe_dev->vpfe_resizer.crop_resizer.subdev.entity,
 			0, flags);
 	if (ret < 0)
diff --git a/drivers/staging/media/omap4iss/iss.c b/drivers/staging/media/omap4iss/iss.c
index 9bfb725b9986..f32ab7b98ae2 100644
--- a/drivers/staging/media/omap4iss/iss.c
+++ b/drivers/staging/media/omap4iss/iss.c
@@ -1259,7 +1259,7 @@ static int iss_register_entities(struct iss_device *iss)
 			goto done;
 		}
 
-		ret = media_entity_create_link(&sensor->entity, 0, input, pad,
+		ret = media_create_pad_link(&sensor->entity, 0, input, pad,
 					       flags);
 		if (ret < 0)
 			goto done;
@@ -1317,31 +1317,31 @@ static int iss_initialize_modules(struct iss_device *iss)
 	}
 
 	/* Connect the submodules. */
-	ret = media_entity_create_link(
+	ret = media_create_pad_link(
 			&iss->csi2a.subdev.entity, CSI2_PAD_SOURCE,
 			&iss->ipipeif.subdev.entity, IPIPEIF_PAD_SINK, 0);
 	if (ret < 0)
 		goto error_link;
 
-	ret = media_entity_create_link(
+	ret = media_create_pad_link(
 			&iss->csi2b.subdev.entity, CSI2_PAD_SOURCE,
 			&iss->ipipeif.subdev.entity, IPIPEIF_PAD_SINK, 0);
 	if (ret < 0)
 		goto error_link;
 
-	ret = media_entity_create_link(
+	ret = media_create_pad_link(
 			&iss->ipipeif.subdev.entity, IPIPEIF_PAD_SOURCE_VP,
 			&iss->resizer.subdev.entity, RESIZER_PAD_SINK, 0);
 	if (ret < 0)
 		goto error_link;
 
-	ret = media_entity_create_link(
+	ret = media_create_pad_link(
 			&iss->ipipeif.subdev.entity, IPIPEIF_PAD_SOURCE_VP,
 			&iss->ipipe.subdev.entity, IPIPE_PAD_SINK, 0);
 	if (ret < 0)
 		goto error_link;
 
-	ret = media_entity_create_link(
+	ret = media_create_pad_link(
 			&iss->ipipe.subdev.entity, IPIPE_PAD_SOURCE_VP,
 			&iss->resizer.subdev.entity, RESIZER_PAD_SINK, 0);
 	if (ret < 0)
diff --git a/drivers/staging/media/omap4iss/iss_csi2.c b/drivers/staging/media/omap4iss/iss_csi2.c
index e936cfc218cb..6b4dcbfa9425 100644
--- a/drivers/staging/media/omap4iss/iss_csi2.c
+++ b/drivers/staging/media/omap4iss/iss_csi2.c
@@ -1291,7 +1291,7 @@ static int csi2_init_entities(struct iss_csi2_device *csi2, const char *subname)
 		goto error_video;
 
 	/* Connect the CSI2 subdev to the video node. */
-	ret = media_entity_create_link(&csi2->subdev.entity, CSI2_PAD_SOURCE,
+	ret = media_create_pad_link(&csi2->subdev.entity, CSI2_PAD_SOURCE,
 				       &csi2->video_out.video.entity, 0, 0);
 	if (ret < 0)
 		goto error_link;
diff --git a/drivers/staging/media/omap4iss/iss_ipipeif.c b/drivers/staging/media/omap4iss/iss_ipipeif.c
index be5f80d7b5dc..44c432ef2ac5 100644
--- a/drivers/staging/media/omap4iss/iss_ipipeif.c
+++ b/drivers/staging/media/omap4iss/iss_ipipeif.c
@@ -762,7 +762,7 @@ static int ipipeif_init_entities(struct iss_ipipeif_device *ipipeif)
 		return ret;
 
 	/* Connect the IPIPEIF subdev to the video node. */
-	ret = media_entity_create_link(&ipipeif->subdev.entity,
+	ret = media_create_pad_link(&ipipeif->subdev.entity,
 				       IPIPEIF_PAD_SOURCE_ISIF_SF,
 				       &ipipeif->video_out.video.entity, 0, 0);
 	if (ret < 0)
diff --git a/drivers/staging/media/omap4iss/iss_resizer.c b/drivers/staging/media/omap4iss/iss_resizer.c
index 91e724085dba..b659e465cb56 100644
--- a/drivers/staging/media/omap4iss/iss_resizer.c
+++ b/drivers/staging/media/omap4iss/iss_resizer.c
@@ -806,7 +806,7 @@ static int resizer_init_entities(struct iss_resizer_device *resizer)
 		return ret;
 
 	/* Connect the RESIZER subdev to the video node. */
-	ret = media_entity_create_link(&resizer->subdev.entity,
+	ret = media_create_pad_link(&resizer->subdev.entity,
 				       RESIZER_PAD_SOURCE_MEM,
 				       &resizer->video_out.video.entity, 0, 0);
 	if (ret < 0)
diff --git a/include/media/media-entity.h b/include/media/media-entity.h
index bdd5e565ae76..3b653e9321f2 100644
--- a/include/media/media-entity.h
+++ b/include/media/media-entity.h
@@ -208,7 +208,7 @@ int media_entity_init(struct media_entity *entity, u16 num_pads,
 		struct media_pad *pads);
 void media_entity_cleanup(struct media_entity *entity);
 
-int media_entity_create_link(struct media_entity *source, u16 source_pad,
+int media_create_pad_link(struct media_entity *source, u16 source_pad,
 		struct media_entity *sink, u16 sink_pad, u32 flags);
 void __media_entity_remove_links(struct media_entity *entity);
 void media_entity_remove_links(struct media_entity *entity);
-- 
2.4.3



From monstr at monstr.eu  Wed Aug 19 04:11:43 2015
From: monstr at monstr.eu (Michal Simek)
Date: Wed, 19 Aug 2015 13:11:43 +0200
Subject: [GIT PULL] Xilinx Zynq DT changes for v4.3 v2
Message-ID: <55D4646F.7010404@monstr.eu>

Hi guys,

Philipp just sent his PR to you with adding reset controller for Zynq
(http://www.spinics.net/lists/arm-kernel/msg440136.html).
Can you please consider to add this one more patch to your tree?
It is one more patch on the top of existing zynq/dt branch which you
already have in arm-soc git repo.

Thanks,
Michal

The following changes since commit b76da4d8758995437a831748dfca6f64a0e31c95:

  ARM: zynq: DT: Add zc702 pushbuttons to DT as gpio-keys (2015-07-31
10:50:06 +0200)

are available in the git repository at:

  https://github.com/Xilinx/linux-xlnx.git tags/zynq-dt-for-4.3-v2

for you to fetch changes up to d8ae96c948ccb6c4274f007eb2ffd27ed656783a:

  dts: zynq: Add devicetree entry for Xilinx Zynq reset controller.
(2015-08-19 13:03:23 +0200)

----------------------------------------------------------------
arm: Xilinx Zynq dt patches for v4.3 v2

- Enable reset driver for Zynq

----------------------------------------------------------------
Moritz Fischer (1):
      dts: zynq: Add devicetree entry for Xilinx Zynq reset controller.

 arch/arm/boot/dts/zynq-7000.dtsi | 7 +++++++
 1 file changed, 7 insertions(+)

-- 
Michal Simek, Ing. (M.Eng), OpenPGP -> KeyID: FE3D1F91
w: www.monstr.eu p: +42-0-721842854
Maintainer of Linux kernel - Microblaze cpu - http://www.monstr.eu/fdt/
Maintainer of Linux kernel - Xilinx Zynq ARM architecture
Microblaze U-BOOT custodian and responsible for u-boot arm zynq platform


-------------- next part --------------
A non-text attachment was scrubbed...
Name: signature.asc
Type: application/pgp-signature
Size: 198 bytes
Desc: OpenPGP digital signature
URL: <http://lists.infradead.org/pipermail/linux-arm-kernel/attachments/20150819/e76aabb6/attachment.sig>

From mikko.perttunen at kapsi.fi  Wed Aug 19 04:15:28 2015
From: mikko.perttunen at kapsi.fi (Mikko Perttunen)
Date: Wed, 19 Aug 2015 14:15:28 +0300
Subject: [GIT PULL 9/9] ARM: tegra: Default configuration updates for
 v4.3-rc1
In-Reply-To: <CANMBJr7PKy-eCcB3HiBajpApHS_BYPa7xfKjTqV4o8Z1hwY99A@mail.gmail.com>
References: <1439563720-13189-1-git-send-email-thierry.reding@gmail.com>	<1439563720-13189-10-git-send-email-thierry.reding@gmail.com>
 <CANMBJr7PKy-eCcB3HiBajpApHS_BYPa7xfKjTqV4o8Z1hwY99A@mail.gmail.com>
Message-ID: <55D46550.7090203@kapsi.fi>

Please try disabling TEGRA124_EMC and seeing if that makes any difference.

Mikko

On 08/19/2015 01:30 AM, Tyler Baker wrote:
> Hi Theirry,
> 
> On 14 August 2015 at 07:48, Thierry Reding <thierry.reding at gmail.com> wrote:
>> Hi ARM SoC maintainers,
>>
>> The following changes since commit d770e558e21961ad6cfdf0ff7df0eb5d7d4f0754:
>>
>>   Linux 4.2-rc1 (2015-07-05 11:01:52 -0700)
>>
>> are available in the git repository at:
>>
>>   git://git.kernel.org/pub/scm/linux/kernel/git/tegra/linux.git tags/tegra-for-4.3-defconfig
>>
>> for you to fetch changes up to 258d9bc5e77fa40e290a0bd480d5349224374480:
>>
>>   ARM: tegra: Update multi_v7_defconfig (2015-08-14 16:26:00 +0200)
>>
>> Thanks,
>> Thierry
>>
>> ----------------------------------------------------------------
>> ARM: tegra: Default configuration updates for v4.3-rc1
>>
>> Enable the GK20A GPU (via the Nouveau driver) and CPU frequency scaling
>> on Tegra124.
>>
>> ----------------------------------------------------------------
>> Thierry Reding (1):
>>       ARM: tegra: Update multi_v7_defconfig
> 
> The kernelci.org bot recently reported jetson-tk1 boot failures[1][2]
> in next-20150818, only when booting the mult_v7_defconfig kernels. I
> bisected[3] these boot failure down to this commit, it didn't cleanly
> revert, so I manually removed that options this patch added, and my
> jetson-tk1 booted again. Digging a bit further, if I apply the patch
> below to next-20150818, my jetson-tk1 boots.
> 
> diff --git a/arch/arm/configs/multi_v7_defconfig
> b/arch/arm/configs/multi_v7_defconfig
> index b2facab..a285afe 100644
> --- a/arch/arm/configs/multi_v7_defconfig
> +++ b/arch/arm/configs/multi_v7_defconfig
> @@ -468,7 +468,6 @@ CONFIG_FRAMEBUFFER_CONSOLE_ROTATION=y
>  CONFIG_SOUND=m
>  CONFIG_SND=m
>  CONFIG_SND_DYNAMIC_MINORS=y
> -CONFIG_SND_HDA_TEGRA=m
>  CONFIG_SND_HDA_INPUT_BEEP=y
>  CONFIG_SND_HDA_PATCH_LOADER=y
>  CONFIG_SND_HDA_CODEC_REALTEK=m
> 
> This isn't where the story ends unfortunately. The collabora lab also
> has a jetson-tk1, booted in the same manner, which boots next-20150818
> fine[4]. The only differences I can spot in the two boot logs is that
> the collabora board is using an older version of u-boot, where as my
> board is using a newer version. U-Boot 2015.01-00231-gab77f24-dirty
> (Good) vs U-Boot 2015.07-00130-gb217c89 (Bad). I've also noticed some
> angry udev messages after the modules probe in userspace present in
> both boot logs that look suspicious.
> 
> [   70.469914] udevd[108]: worker [113] /devices/soc0/70030000.hda is
> taking a long time
> [   70.479849] udevd[108]: worker [115] /devices/soc0/70300000.ahub is
> taking a long time
> [   70.490769] udevd[108]: worker [117] /devices/soc0/sound is taking
> a long time
> 
> FWIW, When I went searching for this patch, I couldn't find it on any
> of the mailing lists. The only reference to this patch was from this
> pull request, thus why I'm reporting the issue here. :)
> 
> Anyways, let me know if you can reproduce this issue, and/or can think
> of a reason this might may be causing trouble.
> 
> Cheers,
> 
> Tyler
> 
> [1] http://kernelci.org/boot/all/job/next/kernel/next-20150818/
> [2] http://storage.kernelci.org/next/next-20150818/arm-multi_v7_defconfig/lab-tbaker/boot-tegra124-jetson-tk1.html
> [3] http://hastebin.com/bixofozaji.vhdl
> [4] http://storage.kernelci.org/next/next-20150818/arm-multi_v7_defconfig/lab-collabora/boot-tegra124-jetson-tk1.html
> --
> To unsubscribe from this list: send the line "unsubscribe linux-tegra" in
> the body of a message to majordomo at vger.kernel.org
> More majordomo info at  http://vger.kernel.org/majordomo-info.html
> 


From aisheng.dong at freescale.com  Wed Aug 19 04:07:04 2015
From: aisheng.dong at freescale.com (Dong Aisheng)
Date: Wed, 19 Aug 2015 19:07:04 +0800
Subject: [PATCH V3 4/5] clk: core: add CLK_OPS_PARENT_ON flags to
 support clocks require parent on
In-Reply-To: <20150817124514.GA30536@shlinux1.ap.freescale.net>
References: <1438089585-30103-1-git-send-email-aisheng.dong@freescale.com>
 <1438089585-30103-5-git-send-email-aisheng.dong@freescale.com>
 <20150814010109.GW26614@codeaurora.org>
 <20150817124514.GA30536@shlinux1.ap.freescale.net>
Message-ID: <20150819110703.GB30536@shlinux1.ap.freescale.net>

On Mon, Aug 17, 2015 at 08:45:18PM +0800, Dong Aisheng wrote:
> On Thu, Aug 13, 2015 at 06:01:09PM -0700, Stephen Boyd wrote:
> > On 07/28, Dong Aisheng wrote:
> > > On Freescale i.MX7D platform, all clocks operations, including
> > > enable/disable, rate change and re-parent, requires its parent
> > > clock on. Current clock core can not support it well.
> > > This patch introduce a new flag CLK_OPS_PARENT_ON to handle this
> > > special case in clock core that enable its parent clock firstly for
> > > each operation and disable it later after operation complete.
> > > 
> > > This patch fixes disaling clocks while its parent is off.
> > > This is a special case that is caused by a state mis-align between
> > > HW and SW in clock tree during booting.
> > > Usually in uboot, we may enable all clocks in HW by default.
> > > And during kernel booting time, the parent clock could be disabled in its
> > > driver probe due to calling clk_prepare_enable and clk_disable_unprepare.
> > > Because it's child clock is only enabled in HW while its SW usecount
> > > in clock tree is still 0, so clk_disable of parent clock will gate
> > > the parent clock in both HW and SW usecount ultimately.
> > > Then there will be a clock is on in HW while its parent is disabled.
> > > 
> > > Later when clock core does clk_disable_unused, this clock disable
> > > will cause system hang due to the limitation of operation requiring
> > > its parent clock on.
> > > 
> > > Cc: Mike Turquette <mturquette at linaro.org>
> > > Cc: Stephen Boyd <sboyd at codeaurora.org>
> > > Signed-off-by: Dong Aisheng <aisheng.dong at freescale.com>
> > > ---
> > 
> > Sorry, I still don't agree with this patch. There's no reason we
> > should be turning on clocks during late init so that we can turn
> > off clocks.
> 
> Can't the reason be that it's fairly possible one clock is enabled
> in HW while it's parent is disabled in initial clock tree state
> and to enable parent clocks to disable itself is required by its special
> HW characteristic?
> 
> Dosen't it quite clear from HW point of view?
> 
> > If there's some sort of problem in doing that we
> > should figure it out and make it so that during late init we turn
> > off clocks from the leaves of the tree to the root.
> > 
> 
> Turning off clocks from the leaves to root probably may require clock core
> to provide a way to keep the parent clock enabled once finding its child
> is still on in HW (clk_core_is_enabled() returns true) but enable_count
> is zero before late init.
> 
> One possible solution may be leaving parent clocks on in HW during disable
> once finding its child is on in HW and only decrease the parent's refcount,
> and then replying on the later clk_disable_unused() to disable both child
> and parent from leave to root.
> e.g. clock A: parent, clock B: child of A
> Initial state: clock B is enabled in HW while refcount is zero
> Step1: Driver A enable clock A during probe
>  A: refcount becomes 1 HW state: enabled
> Step2: Driver A disable clock A after probe
>  A: refcount becomes 0 HW state: enabled (only decrease refcount)
> 
> Then Clock A will be the same state as B, HW enabled while refcount is zero(
> means no users), the later clk_disable_unusersd() will disable them all
> from leave to root.
> 
> This is a workable solution but seems much more complicated than the exist
> one in this patch which is only 5 lines of code changes.
> 
> And the question is:
> since we already have the support of CLK_OPS_PARENT_ON (required by
> clock set_rate/re-parent), why we still need invent another complicated
> mechanism to support avoiding enable parent clock only for clk_disable_unused()?
> Is that really worthy?
> And it's also less power efficiency than the one in the patch.
> 
> > I agree that there's a problem here where we don't properly
> > handle keeping children clocks on if a driver comes in and turns
> > off a clock in the middle of the tree before late init. That's a
> > real bug, and we should fix it.
> 
> Sorry, i still can't understand it's a bug.
> Can you help explain more?
> 
> It looks to me like reasonable.
> Enable/disable clock in driver is just one case, the initial clock tree may
> also have such cases.
> (Here i took the 'children clocks' you said as the one who's child clock is on
> in HW while refcount is zero, fix me if wrong)
> 
> And it seems not so quite make sense to not physically disable the clock
> when there's already no child users(refcount becomes zero) and i don't
> think the child clock's default enablement state in HW means a valid user
> since it's just caused by misalignment between HW and SW clock tree during
> kernel booting phase which is meaningless.
> And that seems is why the clk_disable_unused() function exist for fixing
> this state misalignment issue.
> 
> > Mike Turquette has been doing
> > some work to have a way to indicate that certain clocks should be
> > kept on until client drivers grab them. 
> 
> Sorry i can't see how this help on my issue.
> 
> > I think it will also make
> > sure to up refcounts on parent clocks in the middle of the tree
> > when it figures out that a child clock is enabled. Would that be
> > all that we need to do to fix this problem?
> > 
> 
> Then when will we down the refcounts on parent clocks and when to disable it?
> The current clk_disable_unused() only handle HW clk enable/disable, no
> refcount operations.
> Not sure how this is going to fix my issues.
> 
> And again, as i said above, i don't think it makes much sense to not disable
> parent only if child is enabled in HW, unless there's more strong reasons.
> 
> > Also, the subject of this patch and patch 5 are the same. Why?
> > 
> 
> Sorry, mainly because the full feature of CLK_OPS_PARENT_ON is divided into
> two patches for better review, their commit message is different.
> patch 4 is adding support for clk_disable_unused() while patch 5 is for
> clk_setrate/clk_reparent.
> I could reform the subject if needed.
> 
> Regards
> Dong Aisheng
> 

Hi Mike & Stephen,

Any comments about this?

Regards
Dong Aisheng

> > -- 
> > Qualcomm Innovation Center, Inc. is a member of Code Aurora Forum,
> > a Linux Foundation Collaborative Project


From chunfeng.yun at mediatek.com  Wed Aug 19 04:21:13 2015
From: chunfeng.yun at mediatek.com (chunfeng yun)
Date: Wed, 19 Aug 2015 19:21:13 +0800
Subject: [PATCH v5 4/5] xhci: mediatek: support MTK xHCI host controller
In-Reply-To: <55D1F8B7.9060306@linux.intel.com>
References: <1438950644-27290-1-git-send-email-chunfeng.yun@mediatek.com>
 <1438950644-27290-5-git-send-email-chunfeng.yun@mediatek.com>
 <55D1F8B7.9060306@linux.intel.com>
Message-ID: <1439983273.11157.1.camel@mhfsdcap03>

Hi
On Mon, 2015-08-17 at 18:07 +0300, Mathias Nyman wrote:
> Hi
> 
> On 07.08.2015 15:30, Chunfeng Yun wrote:
> > MTK xhci host controller defines some extra SW scheduling
> > parameters for HW to minimize the scheduling effort for
> > synchronous and interrupt endpoints. The parameters are
> > put into reseved DWs of slot context and endpoint context
> >
> >
> 
> ...
> 
> > + * The TD size is the number of max packet sized packets remaining in the TD
> > + * (including this TRB), right shifted by 10.
> > + * It must fit in bits 21:17, so it can't be bigger than 31.
> > + */
> > +u32 xhci_mtk_td_remainder_quirk(unsigned int td_running_total,
> > +	unsigned trb_buffer_length, struct urb *urb)
> > +{
> > +	u32 max = 31;
> > +	int remainder, td_packet_count, packet_transferred;
> > +	unsigned int td_transfer_size = urb->transfer_buffer_length;
> > +	unsigned int maxp;
> > +
> > +	maxp = GET_MAX_PACKET(usb_endpoint_maxp(&urb->ep->desc));
> > +
> > +	/* 0 for the last TRB */
> > +	if (td_running_total + trb_buffer_length == td_transfer_size)
> > +		return 0;
> > +
> > +	packet_transferred = td_running_total / maxp;
> > +	td_packet_count = DIV_ROUND_UP(td_transfer_size, maxp);
> > +	remainder = td_packet_count - packet_transferred;
> > +
> > +	if (remainder > max)
> > +		return max << 17;
> > +	else
> > +		return remainder << 17;
> > +}
> 
> I started looking at this xhci_mtk_td_remainder() function, one
> of the places this patch touches the existing xhci code.
> 
> The remainder functions in xhci are already bit too messy, and
> adding one more function which does almost the same thing makes
> it even messier.
> 
> For example queuing a bulk transfer will end up like this:
> 
> >   		/* Set the TRB length, TD size, and interrupter fields. */
> >   		if (xhci->hci_version < 0x100) {
> > -			remainder = xhci_td_remainder(
> > +			if (xhci->quirks & XHCI_MTK_HOST) {
> > +				remainder = xhci_mtk_td_remainder_quirk(
> > +					running_total, trb_buff_len, urb);
> > +			} else {
> > +				remainder = xhci_td_remainder(
> >   					urb->transfer_buffer_length -
> >   					running_total);
> > +			}
> >   		} else {
> >   			remainder = xhci_v1_0_td_remainder(running_total,
> >   					trb_buff_len, total_packet_count, urb,
> 
> and similar for isoc and control transfers.
> 
> I'll see if I can simplify the existing remainder calculations into one function, then it should
> be enough to just add something like this into it:
> 
> if (xhci->quirks & XHCI_MTK_HOST)
> 	trb_buff_len = 0;
>   	
> This way we can skip all the extra hassle that comes with a new exported quirk function
> 
> Is the Mediatek xhci really a xHCI 0.96 or older controller? (hci_version < 0x100)
> Not a xHCI 1.0 or 1.1 ?
> 
It is xHCI 0.96, but add some feature of xHCI 1.0

Thanks a lot

> -Mathias




From chunfeng.yun at mediatek.com  Wed Aug 19 04:29:21 2015
From: chunfeng.yun at mediatek.com (chunfeng yun)
Date: Wed, 19 Aug 2015 19:29:21 +0800
Subject: [PATCH v5 3/5] usb: phy: add usb3.0 phy driver for mt65xx SoCs
In-Reply-To: <55D1713D.9070107@ti.com>
References: <1438950644-27290-1-git-send-email-chunfeng.yun@mediatek.com>
 <1438950644-27290-4-git-send-email-chunfeng.yun@mediatek.com>
 <55D1713D.9070107@ti.com>
Message-ID: <1439983761.11157.5.camel@mhfsdcap03>

Hi
On Mon, 2015-08-17 at 10:59 +0530, Kishon Vijay Abraham I wrote:
> Hi,
> 
> On Friday 07 August 2015 06:00 PM, Chunfeng Yun wrote:
> > support usb3.0 phy of mt65xx SoCs
> > 
> > Signed-off-by: Chunfeng Yun <chunfeng.yun at mediatek.com>
> 
> change $subject to phy:
> > ---
> >  drivers/phy/Kconfig           |   9 +
> >  drivers/phy/Makefile          |   1 +
> >  drivers/phy/phy-mt65xx-usb3.c | 467 ++++++++++++++++++++++++++++++++++++++++++
> >  3 files changed, 477 insertions(+)
> >  create mode 100644 drivers/phy/phy-mt65xx-usb3.c
> > 
> > diff --git a/drivers/phy/Kconfig b/drivers/phy/Kconfig
> > index c0e6ede..019cf8b 100644
> > --- a/drivers/phy/Kconfig
> > +++ b/drivers/phy/Kconfig
> > @@ -193,6 +193,15 @@ config PHY_HIX5HD2_SATA
> >  	help
> >  	  Support for SATA PHY on Hisilicon hix5hd2 Soc.
> >  
> > +config PHY_MT65XX_USB3
> > +	tristate "Mediatek USB3.0 PHY Driver"
> > +	depends on ARCH_MEDIATEK && OF
> > +	select GENERIC_PHY
> > +	help
> > +	  Say 'Y' here to add support for Mediatek USB3.0 PHY driver
> > +	  for mt65xx SoCs. it supports two usb2.0 ports and
> > +	  one usb3.0 port.
> > +
> >  config PHY_SUN4I_USB
> >  	tristate "Allwinner sunxi SoC USB PHY driver"
> >  	depends on ARCH_SUNXI && HAS_IOMEM && OF
> > diff --git a/drivers/phy/Makefile b/drivers/phy/Makefile
> > index f344e1b..3ceff2a 100644
> > --- a/drivers/phy/Makefile
> > +++ b/drivers/phy/Makefile
> > @@ -22,6 +22,7 @@ obj-$(CONFIG_TI_PIPE3)			+= phy-ti-pipe3.o
> >  obj-$(CONFIG_TWL4030_USB)		+= phy-twl4030-usb.o
> >  obj-$(CONFIG_PHY_EXYNOS5250_SATA)	+= phy-exynos5250-sata.o
> >  obj-$(CONFIG_PHY_HIX5HD2_SATA)		+= phy-hix5hd2-sata.o
> > +obj-$(CONFIG_PHY_MT65XX_USB3)		+= phy-mt65xx-usb3.o
> >  obj-$(CONFIG_PHY_SUN4I_USB)		+= phy-sun4i-usb.o
> >  obj-$(CONFIG_PHY_SUN9I_USB)		+= phy-sun9i-usb.o
> >  obj-$(CONFIG_PHY_SAMSUNG_USB2)		+= phy-exynos-usb2.o
> > diff --git a/drivers/phy/phy-mt65xx-usb3.c b/drivers/phy/phy-mt65xx-usb3.c
> > new file mode 100644
> > index 0000000..6835bff
> > --- /dev/null
> > +++ b/drivers/phy/phy-mt65xx-usb3.c
> .
> .
> <snip>
> .
> .
> > +static struct phy *mt65xx_phy_xlate(struct device *dev,
> > +					struct of_phandle_args *args)
> > +{
> > +	struct mt65xx_u3phy *u3phy = dev_get_drvdata(dev);
> > +	struct mt65xx_phy_instance *instance = NULL;
> > +	struct device_node *phy_np = args->np;
> > +	struct resource res;
> > +	int index;
> > +	int ret;
> > +
> > +	if (args->args_count != 1) {
> > +		dev_err(dev, "invalid number of cells in 'phy' property\n");
> > +		return ERR_PTR(-EINVAL);
> > +	}
> > +
> > +	for (index = 0; index < u3phy->nphys; index++)
> > +		if (phy_np == u3phy->phys[index]->phy->dev.of_node) {
> > +			instance = u3phy->phys[index];
> > +			break;
> > +		}
> > +
> > +	if (!instance) {
> > +		dev_err(dev, "failed to find appropriate phy\n");
> > +		return ERR_PTR(-EINVAL);
> > +	}
> > +
> > +	instance->type = args->args[0];
> > +
> > +	if (!(instance->type == PHY_TYPE_USB2 ||
> > +	      instance->type == PHY_TYPE_USB3)) {
> > +		dev_err(dev, "unsupported device type: %d\n", instance->type);
> > +		return ERR_PTR(-EINVAL);
> > +	}
> > +
> > +	ret = of_address_to_resource(phy_np, 0, &res);
> > +	if (ret) {
> > +		dev_err(dev, "failed to get address resource, err-%d (index-%d)\n",
> > +			ret, instance->index);
> > +		return ERR_PTR(-EINVAL);
> > +	}
> 
> This should be done in probe itself.
> > +
> > +	instance->port_base = devm_ioremap_resource(&instance->phy->dev, &res);
> > +	if (IS_ERR(instance->port_base)) {
> > +		dev_err(dev, "failed to remap sif regs\n");
> > +		return instance->port_base;
> > +	}
> 
> This too should be done in probe.
Ok, I'll revise it later.

> > +
> > +	return instance->phy;
> > +}
> > +
> > +static struct phy_ops mt65xx_u3phy_ops = {
> > +	.init		= mt65xx_phy_init,
> > +	.power_on	= mt65xx_phy_power_on,
> > +	.power_off	= mt65xx_phy_power_off,
> > +	.owner		= THIS_MODULE,
> > +};
> > +
> > +static int mt65xx_u3phy_probe(struct platform_device *pdev)
> > +{
> > +	struct device *dev = &pdev->dev;
> > +	struct device_node *np = dev->of_node;
> > +	struct device_node *child_np;
> > +	struct phy_provider *phy_provider;
> > +	struct resource *sif_res;
> > +	struct mt65xx_u3phy *u3phy;
> > +	int port;
> > +
> > +	u3phy = devm_kzalloc(dev, sizeof(*u3phy), GFP_KERNEL);
> > +	if (!u3phy)
> > +		return -ENOMEM;
> > +
> > +	u3phy->nphys = of_get_child_count(np);
> > +	u3phy->phys = devm_kcalloc(dev, u3phy->nphys,
> > +				       sizeof(*u3phy->phys), GFP_KERNEL);
> > +	if (!u3phy->phys)
> > +		return -ENOMEM;
> > +
> > +	u3phy->dev = dev;
> > +	platform_set_drvdata(pdev, u3phy);
> > +
> > +	sif_res = platform_get_resource(pdev, IORESOURCE_MEM, 0);
> > +	u3phy->sif_base = devm_ioremap_resource(dev, sif_res);
> > +	if (IS_ERR(u3phy->sif_base)) {
> > +		dev_err(dev, "failed to remap sif regs\n");
> > +		return PTR_ERR(u3phy->sif_base);
> > +	}
> > +
> > +	u3phy->u3phya_ref = devm_clk_get(dev, "u3phya_ref");
> > +	if (IS_ERR(u3phy->u3phya_ref)) {
> > +		dev_err(dev, "error to get u3phya_ref\n");
> > +		return PTR_ERR(u3phy->u3phya_ref);
> > +	}
> > +
> > +	port = 0;
> > +	for_each_child_of_node(np, child_np) {
> > +		struct mt65xx_phy_instance *instance;
> > +		struct phy *phy;
> > +
> > +		instance = devm_kzalloc(dev, sizeof(*instance), GFP_KERNEL);
> > +		if (!instance)
> > +			return -ENOMEM;
> > +
> > +		u3phy->phys[port] = instance;
> > +
> > +		phy = devm_phy_create(dev, child_np, &mt65xx_u3phy_ops);
> > +		if (IS_ERR(phy)) {
> > +			dev_err(dev, "failed to create phy\n");
> > +			return PTR_ERR(phy);
> > +		}
> > +		instance->phy = phy;
> > +		instance->index = port;
> 
> 'index' here is not used anywhere.
It's used by phy_instance_xx() functions

> > +		phy_set_drvdata(phy, instance);
> > +		port++;
> > +	}
> > +
> > +	phy_provider = devm_of_phy_provider_register(dev, mt65xx_phy_xlate);
> > +	if (IS_ERR(phy_provider)) {
> > +		dev_err(dev, "Failed to register phy provider\n");
> > +		return PTR_ERR(phy_provider);
> > +	}
> > +
> > +	return u3phy_clk_enable(u3phy);
> 
> Can't we clk enable in phy_init or phy-power_on where it is actually needed.
Yes, I'll test it.

Thanks a lot.
> 
> Thanks
> Kishon




From linus.walleij at linaro.org  Wed Aug 19 05:14:53 2015
From: linus.walleij at linaro.org (Linus Walleij)
Date: Wed, 19 Aug 2015 14:14:53 +0200
Subject: [PATCH v2 5/5] arm64: add KASan support
In-Reply-To: <55AFD8D0.9020308@samsung.com>
References: <1431698344-28054-1-git-send-email-a.ryabinin@samsung.com>
 <1431698344-28054-6-git-send-email-a.ryabinin@samsung.com>
 <CACRpkdaRJJjCXR=vK1M2YhR26JZfGoBB+jcqz8r2MhERfxRzqA@mail.gmail.com>
 <CAPAsAGy-r8Z2N09wKV+e0kLfbwxd-eWK6N5Xajsnqq9jfyWqcQ@mail.gmail.com>
 <CACRpkdZmHLMxosLXjyOPdkavo=UNzmTcHOLF5vV4cS1ULfbq6A@mail.gmail.com>
 <CAPAsAGw-iawTpjJh66rQN5fqBFT6UBZCcv2eKx7JTqCXzhzpsw@mail.gmail.com>
 <CACRpkdY2i2M27gP_fXawkFrC_GFgWaKr5rEn6d47refNPiEk=g@mail.gmail.com>
 <55AE56DB.4040607@samsung.com>
 <CACRpkdYaqK8upK-3b01JbO_y+sHnk4-Hm1MfvjSy0tKUkFREtQ@mail.gmail.com>
 <55AFD8D0.9020308@samsung.com>
Message-ID: <CACRpkdaJVRuLTCh585rLEjua2TpnLsALhLdu0ma56TBA=C+EiQ@mail.gmail.com>

On Wed, Jul 22, 2015 at 7:54 PM, Andrey Ryabinin <a.ryabinin at samsung.com> wrote:

> So here is updated version:
>         git://github.com/aryabinin/linux.git kasan/arm_v0_1
>
> The code is still ugly in some places and it probably have some bugs.
> Lightly tested on exynos 5410/5420.

I compiled this for various ARM platforms and tested to boot.
I used GCC version 4.9.3 20150113 (prerelease) (Linaro).

I get these compilation warnings no matter what I compile,
I chose to ignore them:

WARNING: vmlinux.o(.meminit.text+0x2c):
Section mismatch in reference from the function kasan_pte_populate()
to the function
.init.text:kasan_alloc_block.constprop.7()
The function __meminit kasan_pte_populate() references
a function __init kasan_alloc_block.constprop.7().
If kasan_alloc_block.constprop.7 is only used by kasan_pte_populate then
annotate kasan_alloc_block.constprop.7 with a matching annotation.

WARNING: vmlinux.o(.meminit.text+0x98):
Section mismatch in reference from the function kasan_pmd_populate()
to the function
.init.text:kasan_alloc_block.constprop.7()
The function __meminit kasan_pmd_populate() references
a function __init kasan_alloc_block.constprop.7().
If kasan_alloc_block.constprop.7 is only used by kasan_pmd_populate then
annotate kasan_alloc_block.constprop.7 with a matching annotation.

These KASan outline tests run fine:

kasan test: kmalloc_oob_right out-of-bounds to right
kasan test: kmalloc_oob_left out-of-bounds to left
kasan test: kmalloc_node_oob_right kmalloc_node(): out-of-bounds to right
kasan test: kmalloc_large_oob_rigth kmalloc large allocation:
out-of-bounds to right
kasan test: kmalloc_oob_krealloc_more out-of-bounds after krealloc more
kasan test: kmalloc_oob_krealloc_less out-of-bounds after krealloc less
kasan test: kmalloc_oob_16 kmalloc out-of-bounds for 16-bytes access
kasan test: kmalloc_oob_in_memset out-of-bounds in memset
kasan test: kmalloc_uaf use-after-free
kasan test: kmalloc_uaf_memset use-after-free in memset
kasan test: kmalloc_uaf2 use-after-free after another kmalloc
kasan test: kmem_cache_oob out-of-bounds in kmem_cache_alloc

These two tests seems to not trigger KASan BUG()s, and seemse to
be like so on all hardware, so I guess it is this kind of test
that requires GCC 5.0:

kasan test: kasan_stack_oob out-of-bounds on stack
kasan test: kasan_global_oob out-of-bounds global variable


Hardware test targets:

Ux500 (ARMv7):

On Ux500 I get a real slow boot (as exepected) and after
enabling the test cases produce KASan warnings
expectedly.

MSM APQ8060 (ARMv7):

Also a real slow boot and the expected KASan warnings when
running the tests.

Integrator/AP (ARMv5):

This one mounted with an ARMv5 ARM926 tile. It boots nicely
(but takes forever) with KASan and run all test cases (!) just like
for the other platforms but before reaching userspace this happens:

Unable to handle kernel paging request at virtual address 00021144
pgd = c5a74000
[00021144] *pgd=00000000
Internal error: Oops: 5 [#1] PREEMPT ARM
Modules linked in:
CPU: 0 PID: 24 Comm: modprobe Tainted: G    B
4.2.0-rc2-77613-g11c2df68e4a8 #1
Hardware name: ARM Integrator/AP (Device Tree)
task: c69f8cc0 ti: c5a68000 task.ti: c5a68000
PC is at v4wbi_flush_user_tlb_range+0x10/0x4c
LR is at move_page_tables+0x320/0x46c
pc : [<c00182d0>]    lr : [<c00ce9d0>]    psr: 60000013
sp : c5a6bd78  ip : c5a70000  fp : 9f000000
r10: 9eaab000  r9 : ffaab000  r8 : 0093d34f
r7 : c5a782ac  r6 : c5a68000  r5 : 9effe000  r4 : c0900044
r3 : 00021000  r2 : c5a4c000  r1 : 9f000000  r0 : 9effe000
Flags: nZCv  IRQs on  FIQs on  Mode SVC_32  ISA ARM  Segment user
Control: 0005317f  Table: 05a74000  DAC: 00000015
Process modprobe (pid: 24, stack limit = 0xc5a68190)
Stack: (0xc5a6bd78 to 0xc5a6c000)
bd60:                                                       9f000000 00002000
bd80: 00000000 9f000000 c5a4c000 00000000 00000000 c5a4c020 c5a68000 c5a68004
bda0: c5a4c000 9effe000 00000000 c5a4c000 c59a6540 c5a4c004 c5a70034 c59a65cc
bdc0: 9effe000 00000000 00002000 c00f4558 00002000 00000000 00000000 9f000000
bde0: 9eaa9000 c5a70000 9eaab000 c5a4c04c 00000000 c5a4c000 00000000 00000000
be00: 00000000 00000000 00000000 0f4a4438 b0a5485b 8881364f c0910aec 00000000
be20: 00000000 00000000 c69f8cc0 0f4a4438 c0910aec 00000018 9f000000 c59a68c0
be40: c69f8cc0 c592db40 c59a6540 c592db50 9f000000 c59a68c0 c69f8cc0 00c00000
be60: c5a6be68 c015694c c59a6540 00000080 c5a4aa80 c59a65d8 c5e9bc00 c592db6c
be80: c6a0da00 c592db40 00000001 00000000 c59a6540 c00f4f10 00000000 00002000
bea0: 9f000000 c5a4c000 c69f8cc0 c00f5008 00000017 c5a6bec4 00000000 00000008
bec0: 9efff000 c00b5160 c7e937a0 c00a4684 00000000 c7e937a0 9efff000 c09089a8
bee0: c09089b0 c59a6540 c0908590 fffffff8 c59a65d4 c5a68000 c5a68004 c00f4b28
bf00: c59a65c8 00000001 00000018 c69f8cc0 c5a4ab60 00000018 c6a38000 c59a6540
bf20: 00000001 c59a65e8 c59a65cc c00f6fec c090476c 00000000 c59a65c8 0000038f
bf40: c5a4c028 c59a65c0 c59a65f0 c5a4c004 00000000 c69f8ec0 00000000 c6a38000
bf60: c5a11a00 c5a4ab60 00000000 00000000 ffffffff 00000000 00000000 c00f71a4
bf80: 00000000 ffffffff 00000000 c00361fc c5a11a00 c0036044 00000000 00000000
bfa0: 00000000 00000000 00000000 c000aa60 00000000 00000000 00000000 00000000
bfc0: 00000000 00000000 00000000 00000000 00000000 00000000 00000000 00000000
bfe0: 00000000 00000000 00000000 00000000 00000013 00000000 00002000 41000001
[<c00182d0>] (v4wbi_flush_user_tlb_range) from [<9f000000>] (0x9f000000)
Code: e592c020 e3cd3d7f e3c3303f e593300c (e5933144)
---[ end trace 7fa2f634c630ab6d ]---


Compaq iPAQ H3600 (ARMv4):

This is an ARMv4 machine, SA1100-based. It boots nicely
with KASan and run all test cases (!) just like for the other platforms
but before reaching userspace this happens:

Unable to handle kernel paging request at virtual address e3e57b43
pgd = c08e8000
[e3e57b43] *pgd=00000000
Internal error: Oops: 408eb003 [#1] PREEMPT ARM
Modules linked in:
CPU: 0 PID: 944 Comm: modprobe Tainted: G    B
4.2.0-rc2-77612-g66bb8b6c242c #1
Hardware name: Compaq iPAQ H3600
task: c14d4880 ti: c08dc000 task.ti: c08dc000
PC is at v4wb_flush_user_tlb_range+0x10/0x48
LR is at change_protection_range+0x3c8/0x464
pc : [<c001cb10>]    lr : [<c00c9d58>]    psr: 20000013
sp : c08dfd20  ip : c08e6000  fp : 00000000
r10: c08dc000  r9 : c08ea7c8  r8 : 00000001
r7 : 9f000000  r6 : 9f000000  r5 : c08ed800  r4 : c1ff834f
r3 : e3e579ff  r2 : c08ec000  r1 : 9f000000  r0 : 9effe000
Flags: nzCv  IRQs on  FIQs on  Mode SVC_32  ISA ARM  Segment user
Control: c08eb17f  Table: c08eb17f  DAC: 00000015
Process modprobe (pid: 944, stack limit = 0xc08dc190)
Stack: (0xc08dfd20 to 0xc08e0000)
fd20: 00000001 9f000000 9effffff c08ec000 00000181 c08dc004 c14bc050 c08ea7c0
fd40: c08dc000 c08e6000 9effe000 c08e6170 c0800d90 00000000 c08ec000 00118177
fd60: 9effe000 00000000 00118173 9f000000 c08e6000 c00c9f50 00000000 00000000
fd80: 00000000 0009effe 00000000 c00e9868 00000000 00000002 c08ef000 00000000
fda0: 00000000 c08ec000 c12d4000 c08ec004 c08e6034 c12d408c 00118177 9effe000
fdc0: 001b8000 c00f0a24 00118177 ffffa1d9 00000000 00100177 00000000 00000000
fde0: 00000000 00000000 00000000 c08ec000 00000000 00000000 00000000 00000000
fe00: 00000000 673bd3e6 80a09842 cd271319 c08087f8 00000000 00000000 00000000
fe20: c14d4880 673bd3e6 c08087f8 000003b0 9f000000 c08f0000 c14d4880 c0ace8c0
fe40: c12d4000 c0ace8d0 9f000000 c08f0000 c14d4880 00c00000 c08dfe60 c015474c
fe60: c12d4000 00000080 c08e5d20 c12d4098 c08f0d80 c0ace8ec c14bc000 c0ace8c0
fe80: 00000002 00000000 9f000000 00000000 c12d4000 c00f14dc 00000000 00002000
fea0: 9f000000 c08ec000 c14d4880 c00f15d4 00000017 c08dfec4 00000000 9efff000
fec0: 00000000 c00b0eb4 c1f38f00 c00a3590 00000000 c0801f28 c12d4000 c08dc000
fee0: c08dc004 fffffff8 c0801b10 c12d4094 00000000 c00f118c c12d4098 c12d4088
ff00: 00000001 c12d4001 000003b0 c14d4880 c08e5e00 000003b0 c1494300 c12d4000
ff20: 00000001 c12d40a8 c12d408c c00f35e8 c07fdd8c 00000000 c12d4088 0000038f
ff40: c08ec028 c12d4080 c12d40b0 c08ec004 00000000 c14d4a80 00000000 c1494300
ff60: c08db300 c08e5e00 00000000 00000000 ffffffff 00000000 00000000 c00f3778
ff80: 00000000 ffffffff 00000000 c0038f3c c08db300 c0038d40 00000000 00000000
ffa0: 00000000 00000000 00000000 c00108a0 00000000 00000000 00000000 00000000
ffc0: 00000000 00000000 00000000 00000000 00000000 00000000 00000000 00000000
ffe0: 00000000 00000000 00000000 00000000 00000013 00000000 e85b38dd 6e46c80d
[<c001cb10>] (v4wb_flush_user_tlb_range) from [<c08ec000>] (0xc08ec000)
Code: e592c020 e3cd3d7f e3c3303f e593300c (e5933144)
---[ end trace 66be5d28dde42c9f ]---
random: nonblocking pool is initialized

So it seems v4wb_flush_user_tlb_range+0x10/0x48 is the culprit
on these two systems. It is in arch/arm/mm/tlb-v4wb.S.

Uninstrumenting these files with ASAN_SANITIZE_tlb-v4wb.o := n does
not help.

I then tested on the Footbridge, another ARMv4 system, the oldest I have
SA110-based. This passes decompression and then you may *think* it hangs.
But it doesn't. It just takes a few minutes to boot with KASan
instrumentation, then all tests run fine also on this hardware.
The crash logs scroll by on the physical console.

They keep scrolling forever however, and are still scrolling as I
write this. I suspect some real memory usage bugs to be causing it,
as it is exercising some ages old code that didn't see much scrutiny
in recent years.


Yours,
Linus Walleij


From wangzhou1 at hisilicon.com  Wed Aug 19 05:20:51 2015
From: wangzhou1 at hisilicon.com (Zhou Wang)
Date: Wed, 19 Aug 2015 20:20:51 +0800
Subject: [PATCH v7 3/6] PCI: designware: Add ARM64 support
In-Reply-To: <1439812554-180426-4-git-send-email-wangzhou1@hisilicon.com>
References: <1439812554-180426-1-git-send-email-wangzhou1@hisilicon.com>
 <1439812554-180426-4-git-send-email-wangzhou1@hisilicon.com>
Message-ID: <55D474A3.8090201@hisilicon.com>

Hi Pratyush and Jingoo,

what is your opinion about this patch? It will be very appreciated if you
could take a look at it.

Thanks,
Zhou

On 2015/8/17 19:55, Zhou Wang wrote:
> This patch tries to unify ARM32 and ARM64 PCIe in designware driver. Delete
> function dw_pcie_setup, dw_pcie_scan_bus, dw_pcie_map_irq and struct hw_pci,
> move related operations to dw_pcie_host_init.
> 
> In past, we use:
> pci_common_init_dev
> 	-> pcibios_init_hw
> 		-> hw->scan (dw_pcie_scan_bus)
> to pass 0 to root_bus_nr in struct pcie_port. This patch set pp->root_bus_nr = 0
> in each PCIe host driver which is based on pcie-designware.
> 
> This patch also try to use of_pci_get_host_bridge_resources for ARM32 and ARM64
> according to the suggestion for Gabriele[1]
> 
> Finally this patch reverts commit f4c55c5a3f7f "PCI: designware: Program ATU
> with untranslated address" based on 1/6 in this series. we delete *_mod_base in
> pcie-designware. This was discussed in [2]
> 
> I have compiled the driver with multi_v7_defconfig. However, I don't have
> ARM32 PCIe related board to do test. It will be appreciated if someone could
> help to test it.
> 
> Signed-off-by: Zhou Wang <wangzhou1 at hisilicon.com>
> Signed-off-by: Gabriele Paoloni <gabriele.paoloni at huawei.com>
> Signed-off-by: Arnd Bergmann <arnd at arndb.de>
> Tested-By: James Morse <james.morse at arm.com>
> 
> [1] http://www.spinics.net/lists/linux-pci/msg42194.html
> [2] http://www.spinics.net/lists/arm-kernel/msg436779.html
> ---
>  drivers/pci/host/pci-dra7xx.c      |  15 +--
>  drivers/pci/host/pci-exynos.c      |   2 +-
>  drivers/pci/host/pci-imx6.c        |   2 +-
>  drivers/pci/host/pci-keystone-dw.c |   2 +-
>  drivers/pci/host/pci-keystone.c    |   2 +-
>  drivers/pci/host/pci-layerscape.c  |   2 +-
>  drivers/pci/host/pcie-designware.c | 229 ++++++++++++-------------------------
>  drivers/pci/host/pcie-designware.h |  14 +--
>  drivers/pci/host/pcie-spear13xx.c  |   2 +-
>  9 files changed, 95 insertions(+), 175 deletions(-)
> 
> diff --git a/drivers/pci/host/pci-dra7xx.c b/drivers/pci/host/pci-dra7xx.c
> index 18ae7ff..1268c69 100644
> --- a/drivers/pci/host/pci-dra7xx.c
> +++ b/drivers/pci/host/pci-dra7xx.c
> @@ -141,15 +141,15 @@ static void dra7xx_pcie_host_init(struct pcie_port *pp)
>  {
>  	dw_pcie_setup_rc(pp);
>  
> -	if (pp->io_mod_base)
> -		pp->io_mod_base &= CPU_TO_BUS_ADDR;
> +	if (pp->io_base)
> +		pp->io_base &= CPU_TO_BUS_ADDR;
>  
> -	if (pp->mem_mod_base)
> -		pp->mem_mod_base &= CPU_TO_BUS_ADDR;
> +	if (pp->mem_base)
> +		pp->mem_base &= CPU_TO_BUS_ADDR;
>  
> -	if (pp->cfg0_mod_base) {
> -		pp->cfg0_mod_base &= CPU_TO_BUS_ADDR;
> -		pp->cfg1_mod_base &= CPU_TO_BUS_ADDR;
> +	if (pp->cfg0_base) {
> +		pp->cfg0_base &= CPU_TO_BUS_ADDR;
> +		pp->cfg1_base &= CPU_TO_BUS_ADDR;
>  	}
>  
>  	dra7xx_pcie_establish_link(pp);
> @@ -288,6 +288,7 @@ static int __init dra7xx_add_pcie_port(struct dra7xx_pcie *dra7xx,
>  
>  	pp = &dra7xx->pp;
>  	pp->dev = dev;
> +	pp->root_bus_nr = 0;
>  	pp->ops = &dra7xx_pcie_host_ops;
>  
>  	pp->irq = platform_get_irq(pdev, 1);
> diff --git a/drivers/pci/host/pci-exynos.c b/drivers/pci/host/pci-exynos.c
> index f9f468d..9771bb0 100644
> --- a/drivers/pci/host/pci-exynos.c
> +++ b/drivers/pci/host/pci-exynos.c
> @@ -530,7 +530,7 @@ static int __init exynos_add_pcie_port(struct pcie_port *pp,
>  		}
>  	}
>  
> -	pp->root_bus_nr = -1;
> +	pp->root_bus_nr = 0;
>  	pp->ops = &exynos_pcie_host_ops;
>  
>  	ret = dw_pcie_host_init(pp);
> diff --git a/drivers/pci/host/pci-imx6.c b/drivers/pci/host/pci-imx6.c
> index 233a196..bec256c 100644
> --- a/drivers/pci/host/pci-imx6.c
> +++ b/drivers/pci/host/pci-imx6.c
> @@ -551,7 +551,7 @@ static int __init imx6_add_pcie_port(struct pcie_port *pp,
>  		}
>  	}
>  
> -	pp->root_bus_nr = -1;
> +	pp->root_bus_nr = 0;
>  	pp->ops = &imx6_pcie_host_ops;
>  
>  	ret = dw_pcie_host_init(pp);
> diff --git a/drivers/pci/host/pci-keystone-dw.c b/drivers/pci/host/pci-keystone-dw.c
> index f34892e..b1e4135 100644
> --- a/drivers/pci/host/pci-keystone-dw.c
> +++ b/drivers/pci/host/pci-keystone-dw.c
> @@ -327,7 +327,7 @@ static void ks_dw_pcie_clear_dbi_mode(void __iomem *reg_virt)
>  void ks_dw_pcie_setup_rc_app_regs(struct keystone_pcie *ks_pcie)
>  {
>  	struct pcie_port *pp = &ks_pcie->pp;
> -	u32 start = pp->mem.start, end = pp->mem.end;
> +	u32 start = pp->mem->start, end = pp->mem->end;
>  	int i, tr_size;
>  
>  	/* Disable BARs for inbound access */
> diff --git a/drivers/pci/host/pci-keystone.c b/drivers/pci/host/pci-keystone.c
> index 734da58..8113832 100644
> --- a/drivers/pci/host/pci-keystone.c
> +++ b/drivers/pci/host/pci-keystone.c
> @@ -309,7 +309,7 @@ static int __init ks_add_pcie_port(struct keystone_pcie *ks_pcie,
>  			return ret;
>  	}
>  
> -	pp->root_bus_nr = -1;
> +	pp->root_bus_nr = 0;
>  	pp->ops = &keystone_pcie_host_ops;
>  	ret = ks_dw_pcie_host_init(ks_pcie, ks_pcie->msi_intc_np);
>  	if (ret) {
> diff --git a/drivers/pci/host/pci-layerscape.c b/drivers/pci/host/pci-layerscape.c
> index b2328ea1..79ff08c 100644
> --- a/drivers/pci/host/pci-layerscape.c
> +++ b/drivers/pci/host/pci-layerscape.c
> @@ -106,7 +106,7 @@ static int ls_add_pcie_port(struct ls_pcie *pcie)
>  	pp = &pcie->pp;
>  	pp->dev = pcie->dev;
>  	pp->dbi_base = pcie->dbi;
> -	pp->root_bus_nr = -1;
> +	pp->root_bus_nr = 0;
>  	pp->ops = &ls_pcie_host_ops;
>  
>  	ret = dw_pcie_host_init(pp);
> diff --git a/drivers/pci/host/pcie-designware.c b/drivers/pci/host/pcie-designware.c
> index c5d407c..e71a88e 100644
> --- a/drivers/pci/host/pcie-designware.c
> +++ b/drivers/pci/host/pcie-designware.c
> @@ -11,6 +11,7 @@
>   * published by the Free Software Foundation.
>   */
>  
> +#include <linux/hardirq.h>
>  #include <linux/irq.h>
>  #include <linux/irqdomain.h>
>  #include <linux/kernel.h>
> @@ -69,16 +70,7 @@
>  #define PCIE_ATU_FUNC(x)		(((x) & 0x7) << 16)
>  #define PCIE_ATU_UPPER_TARGET		0x91C
>  
> -static struct hw_pci dw_pci;
> -
> -static unsigned long global_io_offset;
> -
> -static inline struct pcie_port *sys_to_pcie(struct pci_sys_data *sys)
> -{
> -	BUG_ON(!sys->private_data);
> -
> -	return sys->private_data;
> -}
> +static struct pci_ops dw_pcie_ops;
>  
>  int dw_pcie_cfg_read(void __iomem *addr, int where, int size, u32 *val)
>  {
> @@ -255,7 +247,7 @@ static void dw_pcie_msi_set_irq(struct pcie_port *pp, int irq)
>  static int assign_irq(int no_irqs, struct msi_desc *desc, int *pos)
>  {
>  	int irq, pos0, i;
> -	struct pcie_port *pp = sys_to_pcie(desc->dev->bus->sysdata);
> +	struct pcie_port *pp = desc->dev->bus->sysdata;
>  
>  	pos0 = bitmap_find_free_region(pp->msi_irq_in_use, MAX_MSI_IRQS,
>  				       order_base_2(no_irqs));
> @@ -298,7 +290,7 @@ static int dw_msi_setup_irq(struct msi_controller *chip, struct pci_dev *pdev,
>  {
>  	int irq, pos;
>  	struct msi_msg msg;
> -	struct pcie_port *pp = sys_to_pcie(pdev->bus->sysdata);
> +	struct pcie_port *pp = pdev->bus->sysdata;
>  
>  	if (desc->msi_attrib.is_msix)
>  		return -EINVAL;
> @@ -327,7 +319,7 @@ static void dw_msi_teardown_irq(struct msi_controller *chip, unsigned int irq)
>  {
>  	struct irq_data *data = irq_get_irq_data(irq);
>  	struct msi_desc *msi = irq_data_get_msi(data);
> -	struct pcie_port *pp = sys_to_pcie(msi->dev->bus->sysdata);
> +	struct pcie_port *pp = msi->dev->bus->sysdata;
>  
>  	clear_irq_range(pp, irq, 1, data->hwirq);
>  }
> @@ -363,14 +355,12 @@ int dw_pcie_host_init(struct pcie_port *pp)
>  {
>  	struct device_node *np = pp->dev->of_node;
>  	struct platform_device *pdev = to_platform_device(pp->dev);
> -	struct of_pci_range range;
> -	struct of_pci_range_parser parser;
> +	struct pci_bus *bus;
>  	struct resource *cfg_res;
> -	u32 val, ns;
> -	const __be32 *addrp;
> -	int i, index, ret;
> -
> -	ns = of_n_size_cells(np);
> +	LIST_HEAD(res);
> +	u32 val;
> +	int i, ret;
> +	struct resource_entry *win;
>  
>  	cfg_res = platform_get_resource_byname(pdev, IORESOURCE_MEM, "config");
>  	if (cfg_res) {
> @@ -378,85 +368,60 @@ int dw_pcie_host_init(struct pcie_port *pp)
>  		pp->cfg1_size = resource_size(cfg_res)/2;
>  		pp->cfg0_base = cfg_res->start;
>  		pp->cfg1_base = cfg_res->start + pp->cfg0_size;
> -
> -		/* Find the untranslated configuration space address */
> -		index = of_property_match_string(np, "reg-names", "config");
> -		addrp = of_get_address(np, index, NULL, NULL);
> -		pp->cfg0_mod_base = of_read_number(addrp, ns);
> -		pp->cfg1_mod_base = pp->cfg0_mod_base + pp->cfg0_size;
>  	} else {
>  		dev_err(pp->dev, "missing *config* reg space\n");
>  	}
>  
> -	if (of_pci_range_parser_init(&parser, np)) {
> -		dev_err(pp->dev, "missing ranges property\n");
> -		return -EINVAL;
> -	}
> +	ret = of_pci_get_host_bridge_resources(np, 0, 0xff, &res, &pp->io_base);
> +	if (ret)
> +		return ret;
>  
>  	/* Get the I/O and memory ranges from DT */
> -	for_each_of_pci_range(&parser, &range) {
> -		unsigned long restype = range.flags & IORESOURCE_TYPE_BITS;
> -
> -		if (restype == IORESOURCE_IO) {
> -			of_pci_range_to_resource(&range, np, &pp->io);
> -			pp->io.name = "I/O";
> -			pp->io.start = max_t(resource_size_t,
> -					     PCIBIOS_MIN_IO,
> -					     range.pci_addr + global_io_offset);
> -			pp->io.end = min_t(resource_size_t,
> -					   IO_SPACE_LIMIT,
> -					   range.pci_addr + range.size
> -					   + global_io_offset - 1);
> -			pp->io_size = resource_size(&pp->io);
> -			pp->io_bus_addr = range.pci_addr;
> -			pp->io_base = range.cpu_addr;
> -
> -			/* Find the untranslated IO space address */
> -			pp->io_mod_base = range.cpu_addr;
> -		}
> -		if (restype == IORESOURCE_MEM) {
> -			of_pci_range_to_resource(&range, np, &pp->mem);
> -			pp->mem.name = "MEM";
> -			pp->mem_size = resource_size(&pp->mem);
> -			pp->mem_bus_addr = range.pci_addr;
> -
> -			/* Find the untranslated MEM space address */
> -			pp->mem_mod_base = range.cpu_addr;
> -		}
> -		if (restype == 0) {
> -			of_pci_range_to_resource(&range, np, &pp->cfg);
> -			pp->cfg0_size = resource_size(&pp->cfg)/2;
> -			pp->cfg1_size = resource_size(&pp->cfg)/2;
> -			pp->cfg0_base = pp->cfg.start;
> -			pp->cfg1_base = pp->cfg.start + pp->cfg0_size;
> -
> -			/* Find the untranslated configuration space address */
> -			pp->cfg0_mod_base = range.cpu_addr;
> -			pp->cfg1_mod_base = pp->cfg0_mod_base +
> -					    pp->cfg0_size;
> +	resource_list_for_each_entry(win, &res) {
> +		switch (resource_type(win->res)) {
> +		case IORESOURCE_IO:
> +			pp->io = win->res;
> +			pp->io->name = "I/O";
> +			pp->io_size = resource_size(pp->io);
> +			pp->io_bus_addr = pp->io->start - win->offset;
> +			ret = pci_remap_iospace(pp->io, pp->io_base);
> +			if (ret) {
> +				dev_warn(pp->dev, "error %d: failed to map resource %pR\n",
> +					 ret, pp->io);
> +				continue;
> +			}
> +			break;
> +		case IORESOURCE_MEM:
> +			pp->mem = win->res;
> +			pp->mem->name = "MEM";
> +			pp->mem_size = resource_size(pp->mem);
> +			pp->mem_bus_addr = pp->mem->start - win->offset;
> +			break;
> +		case 0:
> +			pp->cfg = win->res;
> +			pp->cfg0_size = resource_size(pp->cfg)/2;
> +			pp->cfg1_size = resource_size(pp->cfg)/2;
> +			pp->cfg0_base = pp->cfg->start;
> +			pp->cfg1_base = pp->cfg->start + pp->cfg0_size;
> +			break;
> +		case IORESOURCE_BUS:
> +			pp->busn = win->res;
> +			break;
> +		default:
> +			continue;
>  		}
>  	}
>  
> -	ret = of_pci_parse_bus_range(np, &pp->busn);
> -	if (ret < 0) {
> -		pp->busn.name = np->name;
> -		pp->busn.start = 0;
> -		pp->busn.end = 0xff;
> -		pp->busn.flags = IORESOURCE_BUS;
> -		dev_dbg(pp->dev, "failed to parse bus-range property: %d, using default %pR\n",
> -			ret, &pp->busn);
> -	}
> -
>  	if (!pp->dbi_base) {
> -		pp->dbi_base = devm_ioremap(pp->dev, pp->cfg.start,
> -					resource_size(&pp->cfg));
> +		pp->dbi_base = devm_ioremap(pp->dev, pp->cfg->start,
> +					resource_size(pp->cfg));
>  		if (!pp->dbi_base) {
>  			dev_err(pp->dev, "error with ioremap\n");
>  			return -ENOMEM;
>  		}
>  	}
>  
> -	pp->mem_base = pp->mem.start;
> +	pp->mem_base = pp->mem->start;
>  
>  	if (!pp->va_cfg0_base) {
>  		pp->va_cfg0_base = devm_ioremap(pp->dev, pp->cfg0_base,
> @@ -505,7 +470,7 @@ int dw_pcie_host_init(struct pcie_port *pp)
>  
>  	if (!pp->ops->rd_other_conf)
>  		dw_pcie_prog_outbound_atu(pp, PCIE_ATU_REGION_INDEX1,
> -					  PCIE_ATU_TYPE_MEM, pp->mem_mod_base,
> +					  PCIE_ATU_TYPE_MEM, pp->mem_base,
>  					  pp->mem_bus_addr, pp->mem_size);
>  
>  	dw_pcie_wr_own_conf(pp, PCI_BASE_ADDRESS_0, 4, 0);
> @@ -517,15 +482,29 @@ int dw_pcie_host_init(struct pcie_port *pp)
>  	val |= PORT_LOGIC_SPEED_CHANGE;
>  	dw_pcie_wr_own_conf(pp, PCIE_LINK_WIDTH_SPEED_CONTROL, 4, val);
>  
> -#ifdef CONFIG_PCI_MSI
> +	bus = pci_create_root_bus(pp->dev, pp->root_bus_nr, &dw_pcie_ops,
> +				  pp, &res);
> +	if (!bus)
> +		return -ENOMEM;
> +
> +#ifdef CONFIG_GENERIC_MSI_IRQ_DOMAIN
> +	bus->msi = container_of(&pp->irq_domain, struct msi_controller, domain);
> +#else
>  	dw_pcie_msi_chip.dev = pp->dev;
> -	dw_pci.msi_ctrl = &dw_pcie_msi_chip;
> +	bus->msi = &dw_pcie_msi_chip;
>  #endif
>  
> -	dw_pci.nr_controllers = 1;
> -	dw_pci.private_data = (void **)&pp;
> +	pci_scan_child_bus(bus);
> +	if (pp->ops->scan_bus)
> +		pp->ops->scan_bus(pp);
> +
> +#ifdef CONFIG_ARM
> +	/* support old dtbs that incorrectly describe IRQs */
> +	pci_fixup_irqs(pci_common_swizzle, of_irq_parse_and_map_pci);
> +#endif
>  
> -	pci_common_init_dev(pp->dev, &dw_pci);
> +	pci_assign_unassigned_bus_resources(bus);
> +	pci_bus_add_devices(bus);
>  
>  	return 0;
>  }
> @@ -544,12 +523,12 @@ static int dw_pcie_rd_other_conf(struct pcie_port *pp, struct pci_bus *bus,
>  
>  	if (bus->parent->number == pp->root_bus_nr) {
>  		type = PCIE_ATU_TYPE_CFG0;
> -		cpu_addr = pp->cfg0_mod_base;
> +		cpu_addr = pp->cfg0_base;
>  		cfg_size = pp->cfg0_size;
>  		va_cfg_base = pp->va_cfg0_base;
>  	} else {
>  		type = PCIE_ATU_TYPE_CFG1;
> -		cpu_addr = pp->cfg1_mod_base;
> +		cpu_addr = pp->cfg1_base;
>  		cfg_size = pp->cfg1_size;
>  		va_cfg_base = pp->va_cfg1_base;
>  	}
> @@ -559,7 +538,7 @@ static int dw_pcie_rd_other_conf(struct pcie_port *pp, struct pci_bus *bus,
>  				  busdev, cfg_size);
>  	ret = dw_pcie_cfg_read(va_cfg_base + address, where, size, val);
>  	dw_pcie_prog_outbound_atu(pp, PCIE_ATU_REGION_INDEX0,
> -				  PCIE_ATU_TYPE_IO, pp->io_mod_base,
> +				  PCIE_ATU_TYPE_IO, pp->io_base,
>  				  pp->io_bus_addr, pp->io_size);
>  
>  	return ret;
> @@ -579,12 +558,12 @@ static int dw_pcie_wr_other_conf(struct pcie_port *pp, struct pci_bus *bus,
>  
>  	if (bus->parent->number == pp->root_bus_nr) {
>  		type = PCIE_ATU_TYPE_CFG0;
> -		cpu_addr = pp->cfg0_mod_base;
> +		cpu_addr = pp->cfg0_base;
>  		cfg_size = pp->cfg0_size;
>  		va_cfg_base = pp->va_cfg0_base;
>  	} else {
>  		type = PCIE_ATU_TYPE_CFG1;
> -		cpu_addr = pp->cfg1_mod_base;
> +		cpu_addr = pp->cfg1_base;
>  		cfg_size = pp->cfg1_size;
>  		va_cfg_base = pp->va_cfg1_base;
>  	}
> @@ -594,7 +573,7 @@ static int dw_pcie_wr_other_conf(struct pcie_port *pp, struct pci_bus *bus,
>  				  busdev, cfg_size);
>  	ret = dw_pcie_cfg_write(va_cfg_base + address, where, size, val);
>  	dw_pcie_prog_outbound_atu(pp, PCIE_ATU_REGION_INDEX0,
> -				  PCIE_ATU_TYPE_IO, pp->io_mod_base,
> +				  PCIE_ATU_TYPE_IO, pp->io_base,
>  				  pp->io_bus_addr, pp->io_size);
>  
>  	return ret;
> @@ -626,7 +605,7 @@ static int dw_pcie_valid_config(struct pcie_port *pp,
>  static int dw_pcie_rd_conf(struct pci_bus *bus, u32 devfn, int where,
>  			int size, u32 *val)
>  {
> -	struct pcie_port *pp = sys_to_pcie(bus->sysdata);
> +	struct pcie_port *pp = bus->sysdata;
>  	int ret;
>  
>  	if (dw_pcie_valid_config(pp, bus, PCI_SLOT(devfn)) == 0) {
> @@ -650,7 +629,7 @@ static int dw_pcie_rd_conf(struct pci_bus *bus, u32 devfn, int where,
>  static int dw_pcie_wr_conf(struct pci_bus *bus, u32 devfn,
>  			int where, int size, u32 val)
>  {
> -	struct pcie_port *pp = sys_to_pcie(bus->sysdata);
> +	struct pcie_port *pp = bus->sysdata;
>  	int ret;
>  
>  	if (dw_pcie_valid_config(pp, bus, PCI_SLOT(devfn)) == 0)
> @@ -674,62 +653,6 @@ static struct pci_ops dw_pcie_ops = {
>  	.write = dw_pcie_wr_conf,
>  };
>  
> -static int dw_pcie_setup(int nr, struct pci_sys_data *sys)
> -{
> -	struct pcie_port *pp;
> -
> -	pp = sys_to_pcie(sys);
> -
> -	if (global_io_offset < SZ_1M && pp->io_size > 0) {
> -		sys->io_offset = global_io_offset - pp->io_bus_addr;
> -		pci_ioremap_io(global_io_offset, pp->io_base);
> -		global_io_offset += SZ_64K;
> -		pci_add_resource_offset(&sys->resources, &pp->io,
> -					sys->io_offset);
> -	}
> -
> -	sys->mem_offset = pp->mem.start - pp->mem_bus_addr;
> -	pci_add_resource_offset(&sys->resources, &pp->mem, sys->mem_offset);
> -	pci_add_resource(&sys->resources, &pp->busn);
> -
> -	return 1;
> -}
> -
> -static struct pci_bus *dw_pcie_scan_bus(int nr, struct pci_sys_data *sys)
> -{
> -	struct pci_bus *bus;
> -	struct pcie_port *pp = sys_to_pcie(sys);
> -
> -	pp->root_bus_nr = sys->busnr;
> -	bus = pci_scan_root_bus(pp->dev, sys->busnr,
> -				  &dw_pcie_ops, sys, &sys->resources);
> -	if (!bus)
> -		return NULL;
> -
> -	if (bus && pp->ops->scan_bus)
> -		pp->ops->scan_bus(pp);
> -
> -	return bus;
> -}
> -
> -static int dw_pcie_map_irq(const struct pci_dev *dev, u8 slot, u8 pin)
> -{
> -	struct pcie_port *pp = sys_to_pcie(dev->bus->sysdata);
> -	int irq;
> -
> -	irq = of_irq_parse_and_map_pci(dev, slot, pin);
> -	if (!irq)
> -		irq = pp->irq;
> -
> -	return irq;
> -}
> -
> -static struct hw_pci dw_pci = {
> -	.setup		= dw_pcie_setup,
> -	.scan		= dw_pcie_scan_bus,
> -	.map_irq	= dw_pcie_map_irq,
> -};
> -
>  void dw_pcie_setup_rc(struct pcie_port *pp)
>  {
>  	u32 val;
> diff --git a/drivers/pci/host/pcie-designware.h b/drivers/pci/host/pcie-designware.h
> index d0bbd27..264c969 100644
> --- a/drivers/pci/host/pcie-designware.h
> +++ b/drivers/pci/host/pcie-designware.h
> @@ -27,25 +27,21 @@ struct pcie_port {
>  	u8			root_bus_nr;
>  	void __iomem		*dbi_base;
>  	u64			cfg0_base;
> -	u64			cfg0_mod_base;
>  	void __iomem		*va_cfg0_base;
>  	u32			cfg0_size;
>  	u64			cfg1_base;
> -	u64			cfg1_mod_base;
>  	void __iomem		*va_cfg1_base;
>  	u32			cfg1_size;
> -	u64			io_base;
> -	u64			io_mod_base;
> +	resource_size_t		io_base;
>  	phys_addr_t		io_bus_addr;
>  	u32			io_size;
>  	u64			mem_base;
> -	u64			mem_mod_base;
>  	phys_addr_t		mem_bus_addr;
>  	u32			mem_size;
> -	struct resource		cfg;
> -	struct resource		io;
> -	struct resource		mem;
> -	struct resource		busn;
> +	struct resource		*cfg;
> +	struct resource		*io;
> +	struct resource		*mem;
> +	struct resource		*busn;
>  	int			irq;
>  	u32			lanes;
>  	struct pcie_host_ops	*ops;
> diff --git a/drivers/pci/host/pcie-spear13xx.c b/drivers/pci/host/pcie-spear13xx.c
> index c49fbdc..03eb204 100644
> --- a/drivers/pci/host/pcie-spear13xx.c
> +++ b/drivers/pci/host/pcie-spear13xx.c
> @@ -286,7 +286,7 @@ static int spear13xx_add_pcie_port(struct pcie_port *pp,
>  		return ret;
>  	}
>  
> -	pp->root_bus_nr = -1;
> +	pp->root_bus_nr = 0;
>  	pp->ops = &spear13xx_pcie_host_ops;
>  
>  	ret = dw_pcie_host_init(pp);
> 




From l.stach at pengutronix.de  Wed Aug 19 05:54:12 2015
From: l.stach at pengutronix.de (Lucas Stach)
Date: Wed, 19 Aug 2015 14:54:12 +0200
Subject: [PATCH v7 3/6] PCI: designware: Add ARM64 support
In-Reply-To: <1439812554-180426-4-git-send-email-wangzhou1@hisilicon.com>
References: <1439812554-180426-1-git-send-email-wangzhou1@hisilicon.com>
 <1439812554-180426-4-git-send-email-wangzhou1@hisilicon.com>
Message-ID: <1439988852.31432.15.camel@pengutronix.de>

Am Montag, den 17.08.2015, 19:55 +0800 schrieb Zhou Wang:
> This patch tries to unify ARM32 and ARM64 PCIe in designware driver. Delete
> function dw_pcie_setup, dw_pcie_scan_bus, dw_pcie_map_irq and struct hw_pci,
> move related operations to dw_pcie_host_init.
> 
> In past, we use:
> pci_common_init_dev
> 	-> pcibios_init_hw
> 		-> hw->scan (dw_pcie_scan_bus)
> to pass 0 to root_bus_nr in struct pcie_port. This patch set pp->root_bus_nr = 0
> in each PCIe host driver which is based on pcie-designware.
> 
This is incorrect at least if there are 2 instances of DW PCIe host in
the same SoC without using PCI domains. In that the case the bus range
determines the range of valid bus numbers per instance and the first
number is the root bus. Please look at the "bus-range" DT property in
the DW PCIe bindings.

Also we should finally remove this root-bus setup from the glue drivers
altogether. It's something that entirely belongs into the DW core code.

Regards,
Lucas

> This patch also try to use of_pci_get_host_bridge_resources for ARM32 and ARM64
> according to the suggestion for Gabriele[1]
> 
> Finally this patch reverts commit f4c55c5a3f7f "PCI: designware: Program ATU
> with untranslated address" based on 1/6 in this series. we delete *_mod_base in
> pcie-designware. This was discussed in [2]
> 
> I have compiled the driver with multi_v7_defconfig. However, I don't have
> ARM32 PCIe related board to do test. It will be appreciated if someone could
> help to test it.
> 
> Signed-off-by: Zhou Wang <wangzhou1 at hisilicon.com>
> Signed-off-by: Gabriele Paoloni <gabriele.paoloni at huawei.com>
> Signed-off-by: Arnd Bergmann <arnd at arndb.de>
> Tested-By: James Morse <james.morse at arm.com>
> 
> [1] http://www.spinics.net/lists/linux-pci/msg42194.html
> [2] http://www.spinics.net/lists/arm-kernel/msg436779.html
> ---
>  drivers/pci/host/pci-dra7xx.c      |  15 +--
>  drivers/pci/host/pci-exynos.c      |   2 +-
>  drivers/pci/host/pci-imx6.c        |   2 +-
>  drivers/pci/host/pci-keystone-dw.c |   2 +-
>  drivers/pci/host/pci-keystone.c    |   2 +-
>  drivers/pci/host/pci-layerscape.c  |   2 +-
>  drivers/pci/host/pcie-designware.c | 229 ++++++++++++-------------------------
>  drivers/pci/host/pcie-designware.h |  14 +--
>  drivers/pci/host/pcie-spear13xx.c  |   2 +-
>  9 files changed, 95 insertions(+), 175 deletions(-)
> 
> diff --git a/drivers/pci/host/pci-dra7xx.c b/drivers/pci/host/pci-dra7xx.c
> index 18ae7ff..1268c69 100644
> --- a/drivers/pci/host/pci-dra7xx.c
> +++ b/drivers/pci/host/pci-dra7xx.c
> @@ -141,15 +141,15 @@ static void dra7xx_pcie_host_init(struct pcie_port *pp)
>  {
>  	dw_pcie_setup_rc(pp);
>  
> -	if (pp->io_mod_base)
> -		pp->io_mod_base &= CPU_TO_BUS_ADDR;
> +	if (pp->io_base)
> +		pp->io_base &= CPU_TO_BUS_ADDR;
>  
> -	if (pp->mem_mod_base)
> -		pp->mem_mod_base &= CPU_TO_BUS_ADDR;
> +	if (pp->mem_base)
> +		pp->mem_base &= CPU_TO_BUS_ADDR;
>  
> -	if (pp->cfg0_mod_base) {
> -		pp->cfg0_mod_base &= CPU_TO_BUS_ADDR;
> -		pp->cfg1_mod_base &= CPU_TO_BUS_ADDR;
> +	if (pp->cfg0_base) {
> +		pp->cfg0_base &= CPU_TO_BUS_ADDR;
> +		pp->cfg1_base &= CPU_TO_BUS_ADDR;
>  	}
>  
>  	dra7xx_pcie_establish_link(pp);
> @@ -288,6 +288,7 @@ static int __init dra7xx_add_pcie_port(struct dra7xx_pcie *dra7xx,
>  
>  	pp = &dra7xx->pp;
>  	pp->dev = dev;
> +	pp->root_bus_nr = 0;
>  	pp->ops = &dra7xx_pcie_host_ops;
>  
>  	pp->irq = platform_get_irq(pdev, 1);
> diff --git a/drivers/pci/host/pci-exynos.c b/drivers/pci/host/pci-exynos.c
> index f9f468d..9771bb0 100644
> --- a/drivers/pci/host/pci-exynos.c
> +++ b/drivers/pci/host/pci-exynos.c
> @@ -530,7 +530,7 @@ static int __init exynos_add_pcie_port(struct pcie_port *pp,
>  		}
>  	}
>  
> -	pp->root_bus_nr = -1;
> +	pp->root_bus_nr = 0;
>  	pp->ops = &exynos_pcie_host_ops;
>  
>  	ret = dw_pcie_host_init(pp);
> diff --git a/drivers/pci/host/pci-imx6.c b/drivers/pci/host/pci-imx6.c
> index 233a196..bec256c 100644
> --- a/drivers/pci/host/pci-imx6.c
> +++ b/drivers/pci/host/pci-imx6.c
> @@ -551,7 +551,7 @@ static int __init imx6_add_pcie_port(struct pcie_port *pp,
>  		}
>  	}
>  
> -	pp->root_bus_nr = -1;
> +	pp->root_bus_nr = 0;
>  	pp->ops = &imx6_pcie_host_ops;
>  
>  	ret = dw_pcie_host_init(pp);
> diff --git a/drivers/pci/host/pci-keystone-dw.c b/drivers/pci/host/pci-keystone-dw.c
> index f34892e..b1e4135 100644
> --- a/drivers/pci/host/pci-keystone-dw.c
> +++ b/drivers/pci/host/pci-keystone-dw.c
> @@ -327,7 +327,7 @@ static void ks_dw_pcie_clear_dbi_mode(void __iomem *reg_virt)
>  void ks_dw_pcie_setup_rc_app_regs(struct keystone_pcie *ks_pcie)
>  {
>  	struct pcie_port *pp = &ks_pcie->pp;
> -	u32 start = pp->mem.start, end = pp->mem.end;
> +	u32 start = pp->mem->start, end = pp->mem->end;
>  	int i, tr_size;
>  
>  	/* Disable BARs for inbound access */
> diff --git a/drivers/pci/host/pci-keystone.c b/drivers/pci/host/pci-keystone.c
> index 734da58..8113832 100644
> --- a/drivers/pci/host/pci-keystone.c
> +++ b/drivers/pci/host/pci-keystone.c
> @@ -309,7 +309,7 @@ static int __init ks_add_pcie_port(struct keystone_pcie *ks_pcie,
>  			return ret;
>  	}
>  
> -	pp->root_bus_nr = -1;
> +	pp->root_bus_nr = 0;
>  	pp->ops = &keystone_pcie_host_ops;
>  	ret = ks_dw_pcie_host_init(ks_pcie, ks_pcie->msi_intc_np);
>  	if (ret) {
> diff --git a/drivers/pci/host/pci-layerscape.c b/drivers/pci/host/pci-layerscape.c
> index b2328ea1..79ff08c 100644
> --- a/drivers/pci/host/pci-layerscape.c
> +++ b/drivers/pci/host/pci-layerscape.c
> @@ -106,7 +106,7 @@ static int ls_add_pcie_port(struct ls_pcie *pcie)
>  	pp = &pcie->pp;
>  	pp->dev = pcie->dev;
>  	pp->dbi_base = pcie->dbi;
> -	pp->root_bus_nr = -1;
> +	pp->root_bus_nr = 0;
>  	pp->ops = &ls_pcie_host_ops;
>  
>  	ret = dw_pcie_host_init(pp);
> diff --git a/drivers/pci/host/pcie-designware.c b/drivers/pci/host/pcie-designware.c
> index c5d407c..e71a88e 100644
> --- a/drivers/pci/host/pcie-designware.c
> +++ b/drivers/pci/host/pcie-designware.c
> @@ -11,6 +11,7 @@
>   * published by the Free Software Foundation.
>   */
>  
> +#include <linux/hardirq.h>
>  #include <linux/irq.h>
>  #include <linux/irqdomain.h>
>  #include <linux/kernel.h>
> @@ -69,16 +70,7 @@
>  #define PCIE_ATU_FUNC(x)		(((x) & 0x7) << 16)
>  #define PCIE_ATU_UPPER_TARGET		0x91C
>  
> -static struct hw_pci dw_pci;
> -
> -static unsigned long global_io_offset;
> -
> -static inline struct pcie_port *sys_to_pcie(struct pci_sys_data *sys)
> -{
> -	BUG_ON(!sys->private_data);
> -
> -	return sys->private_data;
> -}
> +static struct pci_ops dw_pcie_ops;
>  
>  int dw_pcie_cfg_read(void __iomem *addr, int where, int size, u32 *val)
>  {
> @@ -255,7 +247,7 @@ static void dw_pcie_msi_set_irq(struct pcie_port *pp, int irq)
>  static int assign_irq(int no_irqs, struct msi_desc *desc, int *pos)
>  {
>  	int irq, pos0, i;
> -	struct pcie_port *pp = sys_to_pcie(desc->dev->bus->sysdata);
> +	struct pcie_port *pp = desc->dev->bus->sysdata;
>  
>  	pos0 = bitmap_find_free_region(pp->msi_irq_in_use, MAX_MSI_IRQS,
>  				       order_base_2(no_irqs));
> @@ -298,7 +290,7 @@ static int dw_msi_setup_irq(struct msi_controller *chip, struct pci_dev *pdev,
>  {
>  	int irq, pos;
>  	struct msi_msg msg;
> -	struct pcie_port *pp = sys_to_pcie(pdev->bus->sysdata);
> +	struct pcie_port *pp = pdev->bus->sysdata;
>  
>  	if (desc->msi_attrib.is_msix)
>  		return -EINVAL;
> @@ -327,7 +319,7 @@ static void dw_msi_teardown_irq(struct msi_controller *chip, unsigned int irq)
>  {
>  	struct irq_data *data = irq_get_irq_data(irq);
>  	struct msi_desc *msi = irq_data_get_msi(data);
> -	struct pcie_port *pp = sys_to_pcie(msi->dev->bus->sysdata);
> +	struct pcie_port *pp = msi->dev->bus->sysdata;
>  
>  	clear_irq_range(pp, irq, 1, data->hwirq);
>  }
> @@ -363,14 +355,12 @@ int dw_pcie_host_init(struct pcie_port *pp)
>  {
>  	struct device_node *np = pp->dev->of_node;
>  	struct platform_device *pdev = to_platform_device(pp->dev);
> -	struct of_pci_range range;
> -	struct of_pci_range_parser parser;
> +	struct pci_bus *bus;
>  	struct resource *cfg_res;
> -	u32 val, ns;
> -	const __be32 *addrp;
> -	int i, index, ret;
> -
> -	ns = of_n_size_cells(np);
> +	LIST_HEAD(res);
> +	u32 val;
> +	int i, ret;
> +	struct resource_entry *win;
>  
>  	cfg_res = platform_get_resource_byname(pdev, IORESOURCE_MEM, "config");
>  	if (cfg_res) {
> @@ -378,85 +368,60 @@ int dw_pcie_host_init(struct pcie_port *pp)
>  		pp->cfg1_size = resource_size(cfg_res)/2;
>  		pp->cfg0_base = cfg_res->start;
>  		pp->cfg1_base = cfg_res->start + pp->cfg0_size;
> -
> -		/* Find the untranslated configuration space address */
> -		index = of_property_match_string(np, "reg-names", "config");
> -		addrp = of_get_address(np, index, NULL, NULL);
> -		pp->cfg0_mod_base = of_read_number(addrp, ns);
> -		pp->cfg1_mod_base = pp->cfg0_mod_base + pp->cfg0_size;
>  	} else {
>  		dev_err(pp->dev, "missing *config* reg space\n");
>  	}
>  
> -	if (of_pci_range_parser_init(&parser, np)) {
> -		dev_err(pp->dev, "missing ranges property\n");
> -		return -EINVAL;
> -	}
> +	ret = of_pci_get_host_bridge_resources(np, 0, 0xff, &res, &pp->io_base);
> +	if (ret)
> +		return ret;
>  
>  	/* Get the I/O and memory ranges from DT */
> -	for_each_of_pci_range(&parser, &range) {
> -		unsigned long restype = range.flags & IORESOURCE_TYPE_BITS;
> -
> -		if (restype == IORESOURCE_IO) {
> -			of_pci_range_to_resource(&range, np, &pp->io);
> -			pp->io.name = "I/O";
> -			pp->io.start = max_t(resource_size_t,
> -					     PCIBIOS_MIN_IO,
> -					     range.pci_addr + global_io_offset);
> -			pp->io.end = min_t(resource_size_t,
> -					   IO_SPACE_LIMIT,
> -					   range.pci_addr + range.size
> -					   + global_io_offset - 1);
> -			pp->io_size = resource_size(&pp->io);
> -			pp->io_bus_addr = range.pci_addr;
> -			pp->io_base = range.cpu_addr;
> -
> -			/* Find the untranslated IO space address */
> -			pp->io_mod_base = range.cpu_addr;
> -		}
> -		if (restype == IORESOURCE_MEM) {
> -			of_pci_range_to_resource(&range, np, &pp->mem);
> -			pp->mem.name = "MEM";
> -			pp->mem_size = resource_size(&pp->mem);
> -			pp->mem_bus_addr = range.pci_addr;
> -
> -			/* Find the untranslated MEM space address */
> -			pp->mem_mod_base = range.cpu_addr;
> -		}
> -		if (restype == 0) {
> -			of_pci_range_to_resource(&range, np, &pp->cfg);
> -			pp->cfg0_size = resource_size(&pp->cfg)/2;
> -			pp->cfg1_size = resource_size(&pp->cfg)/2;
> -			pp->cfg0_base = pp->cfg.start;
> -			pp->cfg1_base = pp->cfg.start + pp->cfg0_size;
> -
> -			/* Find the untranslated configuration space address */
> -			pp->cfg0_mod_base = range.cpu_addr;
> -			pp->cfg1_mod_base = pp->cfg0_mod_base +
> -					    pp->cfg0_size;
> +	resource_list_for_each_entry(win, &res) {
> +		switch (resource_type(win->res)) {
> +		case IORESOURCE_IO:
> +			pp->io = win->res;
> +			pp->io->name = "I/O";
> +			pp->io_size = resource_size(pp->io);
> +			pp->io_bus_addr = pp->io->start - win->offset;
> +			ret = pci_remap_iospace(pp->io, pp->io_base);
> +			if (ret) {
> +				dev_warn(pp->dev, "error %d: failed to map resource %pR\n",
> +					 ret, pp->io);
> +				continue;
> +			}
> +			break;
> +		case IORESOURCE_MEM:
> +			pp->mem = win->res;
> +			pp->mem->name = "MEM";
> +			pp->mem_size = resource_size(pp->mem);
> +			pp->mem_bus_addr = pp->mem->start - win->offset;
> +			break;
> +		case 0:
> +			pp->cfg = win->res;
> +			pp->cfg0_size = resource_size(pp->cfg)/2;
> +			pp->cfg1_size = resource_size(pp->cfg)/2;
> +			pp->cfg0_base = pp->cfg->start;
> +			pp->cfg1_base = pp->cfg->start + pp->cfg0_size;
> +			break;
> +		case IORESOURCE_BUS:
> +			pp->busn = win->res;
> +			break;
> +		default:
> +			continue;
>  		}
>  	}
>  
> -	ret = of_pci_parse_bus_range(np, &pp->busn);
> -	if (ret < 0) {
> -		pp->busn.name = np->name;
> -		pp->busn.start = 0;
> -		pp->busn.end = 0xff;
> -		pp->busn.flags = IORESOURCE_BUS;
> -		dev_dbg(pp->dev, "failed to parse bus-range property: %d, using default %pR\n",
> -			ret, &pp->busn);
> -	}
> -
>  	if (!pp->dbi_base) {
> -		pp->dbi_base = devm_ioremap(pp->dev, pp->cfg.start,
> -					resource_size(&pp->cfg));
> +		pp->dbi_base = devm_ioremap(pp->dev, pp->cfg->start,
> +					resource_size(pp->cfg));
>  		if (!pp->dbi_base) {
>  			dev_err(pp->dev, "error with ioremap\n");
>  			return -ENOMEM;
>  		}
>  	}
>  
> -	pp->mem_base = pp->mem.start;
> +	pp->mem_base = pp->mem->start;
>  
>  	if (!pp->va_cfg0_base) {
>  		pp->va_cfg0_base = devm_ioremap(pp->dev, pp->cfg0_base,
> @@ -505,7 +470,7 @@ int dw_pcie_host_init(struct pcie_port *pp)
>  
>  	if (!pp->ops->rd_other_conf)
>  		dw_pcie_prog_outbound_atu(pp, PCIE_ATU_REGION_INDEX1,
> -					  PCIE_ATU_TYPE_MEM, pp->mem_mod_base,
> +					  PCIE_ATU_TYPE_MEM, pp->mem_base,
>  					  pp->mem_bus_addr, pp->mem_size);
>  
>  	dw_pcie_wr_own_conf(pp, PCI_BASE_ADDRESS_0, 4, 0);
> @@ -517,15 +482,29 @@ int dw_pcie_host_init(struct pcie_port *pp)
>  	val |= PORT_LOGIC_SPEED_CHANGE;
>  	dw_pcie_wr_own_conf(pp, PCIE_LINK_WIDTH_SPEED_CONTROL, 4, val);
>  
> -#ifdef CONFIG_PCI_MSI
> +	bus = pci_create_root_bus(pp->dev, pp->root_bus_nr, &dw_pcie_ops,
> +				  pp, &res);
> +	if (!bus)
> +		return -ENOMEM;
> +
> +#ifdef CONFIG_GENERIC_MSI_IRQ_DOMAIN
> +	bus->msi = container_of(&pp->irq_domain, struct msi_controller, domain);
> +#else
>  	dw_pcie_msi_chip.dev = pp->dev;
> -	dw_pci.msi_ctrl = &dw_pcie_msi_chip;
> +	bus->msi = &dw_pcie_msi_chip;
>  #endif
>  
> -	dw_pci.nr_controllers = 1;
> -	dw_pci.private_data = (void **)&pp;
> +	pci_scan_child_bus(bus);
> +	if (pp->ops->scan_bus)
> +		pp->ops->scan_bus(pp);
> +
> +#ifdef CONFIG_ARM
> +	/* support old dtbs that incorrectly describe IRQs */
> +	pci_fixup_irqs(pci_common_swizzle, of_irq_parse_and_map_pci);
> +#endif
>  
> -	pci_common_init_dev(pp->dev, &dw_pci);
> +	pci_assign_unassigned_bus_resources(bus);
> +	pci_bus_add_devices(bus);
>  
>  	return 0;
>  }
> @@ -544,12 +523,12 @@ static int dw_pcie_rd_other_conf(struct pcie_port *pp, struct pci_bus *bus,
>  
>  	if (bus->parent->number == pp->root_bus_nr) {
>  		type = PCIE_ATU_TYPE_CFG0;
> -		cpu_addr = pp->cfg0_mod_base;
> +		cpu_addr = pp->cfg0_base;
>  		cfg_size = pp->cfg0_size;
>  		va_cfg_base = pp->va_cfg0_base;
>  	} else {
>  		type = PCIE_ATU_TYPE_CFG1;
> -		cpu_addr = pp->cfg1_mod_base;
> +		cpu_addr = pp->cfg1_base;
>  		cfg_size = pp->cfg1_size;
>  		va_cfg_base = pp->va_cfg1_base;
>  	}
> @@ -559,7 +538,7 @@ static int dw_pcie_rd_other_conf(struct pcie_port *pp, struct pci_bus *bus,
>  				  busdev, cfg_size);
>  	ret = dw_pcie_cfg_read(va_cfg_base + address, where, size, val);
>  	dw_pcie_prog_outbound_atu(pp, PCIE_ATU_REGION_INDEX0,
> -				  PCIE_ATU_TYPE_IO, pp->io_mod_base,
> +				  PCIE_ATU_TYPE_IO, pp->io_base,
>  				  pp->io_bus_addr, pp->io_size);
>  
>  	return ret;
> @@ -579,12 +558,12 @@ static int dw_pcie_wr_other_conf(struct pcie_port *pp, struct pci_bus *bus,
>  
>  	if (bus->parent->number == pp->root_bus_nr) {
>  		type = PCIE_ATU_TYPE_CFG0;
> -		cpu_addr = pp->cfg0_mod_base;
> +		cpu_addr = pp->cfg0_base;
>  		cfg_size = pp->cfg0_size;
>  		va_cfg_base = pp->va_cfg0_base;
>  	} else {
>  		type = PCIE_ATU_TYPE_CFG1;
> -		cpu_addr = pp->cfg1_mod_base;
> +		cpu_addr = pp->cfg1_base;
>  		cfg_size = pp->cfg1_size;
>  		va_cfg_base = pp->va_cfg1_base;
>  	}
> @@ -594,7 +573,7 @@ static int dw_pcie_wr_other_conf(struct pcie_port *pp, struct pci_bus *bus,
>  				  busdev, cfg_size);
>  	ret = dw_pcie_cfg_write(va_cfg_base + address, where, size, val);
>  	dw_pcie_prog_outbound_atu(pp, PCIE_ATU_REGION_INDEX0,
> -				  PCIE_ATU_TYPE_IO, pp->io_mod_base,
> +				  PCIE_ATU_TYPE_IO, pp->io_base,
>  				  pp->io_bus_addr, pp->io_size);
>  
>  	return ret;
> @@ -626,7 +605,7 @@ static int dw_pcie_valid_config(struct pcie_port *pp,
>  static int dw_pcie_rd_conf(struct pci_bus *bus, u32 devfn, int where,
>  			int size, u32 *val)
>  {
> -	struct pcie_port *pp = sys_to_pcie(bus->sysdata);
> +	struct pcie_port *pp = bus->sysdata;
>  	int ret;
>  
>  	if (dw_pcie_valid_config(pp, bus, PCI_SLOT(devfn)) == 0) {
> @@ -650,7 +629,7 @@ static int dw_pcie_rd_conf(struct pci_bus *bus, u32 devfn, int where,
>  static int dw_pcie_wr_conf(struct pci_bus *bus, u32 devfn,
>  			int where, int size, u32 val)
>  {
> -	struct pcie_port *pp = sys_to_pcie(bus->sysdata);
> +	struct pcie_port *pp = bus->sysdata;
>  	int ret;
>  
>  	if (dw_pcie_valid_config(pp, bus, PCI_SLOT(devfn)) == 0)
> @@ -674,62 +653,6 @@ static struct pci_ops dw_pcie_ops = {
>  	.write = dw_pcie_wr_conf,
>  };
>  
> -static int dw_pcie_setup(int nr, struct pci_sys_data *sys)
> -{
> -	struct pcie_port *pp;
> -
> -	pp = sys_to_pcie(sys);
> -
> -	if (global_io_offset < SZ_1M && pp->io_size > 0) {
> -		sys->io_offset = global_io_offset - pp->io_bus_addr;
> -		pci_ioremap_io(global_io_offset, pp->io_base);
> -		global_io_offset += SZ_64K;
> -		pci_add_resource_offset(&sys->resources, &pp->io,
> -					sys->io_offset);
> -	}
> -
> -	sys->mem_offset = pp->mem.start - pp->mem_bus_addr;
> -	pci_add_resource_offset(&sys->resources, &pp->mem, sys->mem_offset);
> -	pci_add_resource(&sys->resources, &pp->busn);
> -
> -	return 1;
> -}
> -
> -static struct pci_bus *dw_pcie_scan_bus(int nr, struct pci_sys_data *sys)
> -{
> -	struct pci_bus *bus;
> -	struct pcie_port *pp = sys_to_pcie(sys);
> -
> -	pp->root_bus_nr = sys->busnr;
> -	bus = pci_scan_root_bus(pp->dev, sys->busnr,
> -				  &dw_pcie_ops, sys, &sys->resources);
> -	if (!bus)
> -		return NULL;
> -
> -	if (bus && pp->ops->scan_bus)
> -		pp->ops->scan_bus(pp);
> -
> -	return bus;
> -}
> -
> -static int dw_pcie_map_irq(const struct pci_dev *dev, u8 slot, u8 pin)
> -{
> -	struct pcie_port *pp = sys_to_pcie(dev->bus->sysdata);
> -	int irq;
> -
> -	irq = of_irq_parse_and_map_pci(dev, slot, pin);
> -	if (!irq)
> -		irq = pp->irq;
> -
> -	return irq;
> -}
> -
> -static struct hw_pci dw_pci = {
> -	.setup		= dw_pcie_setup,
> -	.scan		= dw_pcie_scan_bus,
> -	.map_irq	= dw_pcie_map_irq,
> -};
> -
>  void dw_pcie_setup_rc(struct pcie_port *pp)
>  {
>  	u32 val;
> diff --git a/drivers/pci/host/pcie-designware.h b/drivers/pci/host/pcie-designware.h
> index d0bbd27..264c969 100644
> --- a/drivers/pci/host/pcie-designware.h
> +++ b/drivers/pci/host/pcie-designware.h
> @@ -27,25 +27,21 @@ struct pcie_port {
>  	u8			root_bus_nr;
>  	void __iomem		*dbi_base;
>  	u64			cfg0_base;
> -	u64			cfg0_mod_base;
>  	void __iomem		*va_cfg0_base;
>  	u32			cfg0_size;
>  	u64			cfg1_base;
> -	u64			cfg1_mod_base;
>  	void __iomem		*va_cfg1_base;
>  	u32			cfg1_size;
> -	u64			io_base;
> -	u64			io_mod_base;
> +	resource_size_t		io_base;
>  	phys_addr_t		io_bus_addr;
>  	u32			io_size;
>  	u64			mem_base;
> -	u64			mem_mod_base;
>  	phys_addr_t		mem_bus_addr;
>  	u32			mem_size;
> -	struct resource		cfg;
> -	struct resource		io;
> -	struct resource		mem;
> -	struct resource		busn;
> +	struct resource		*cfg;
> +	struct resource		*io;
> +	struct resource		*mem;
> +	struct resource		*busn;
>  	int			irq;
>  	u32			lanes;
>  	struct pcie_host_ops	*ops;
> diff --git a/drivers/pci/host/pcie-spear13xx.c b/drivers/pci/host/pcie-spear13xx.c
> index c49fbdc..03eb204 100644
> --- a/drivers/pci/host/pcie-spear13xx.c
> +++ b/drivers/pci/host/pcie-spear13xx.c
> @@ -286,7 +286,7 @@ static int spear13xx_add_pcie_port(struct pcie_port *pp,
>  		return ret;
>  	}
>  
> -	pp->root_bus_nr = -1;
> +	pp->root_bus_nr = 0;
>  	pp->ops = &spear13xx_pcie_host_ops;
>  
>  	ret = dw_pcie_host_init(pp);

-- 
Pengutronix e.K.             | Lucas Stach                 |
Industrial Linux Solutions   | http://www.pengutronix.de/  |



From heiko at sntech.de  Wed Aug 19 06:06:55 2015
From: heiko at sntech.de (Heiko Stuebner)
Date: Wed, 19 Aug 2015 15:06:55 +0200
Subject: [PATCH] clk: rockchip: register pll mux before pll itself
Message-ID: <7060610.CC2Q1RMG2L@phil>

The structure is xin24m -> pll -> pll-mux (xin24m,pll,xin32k). The pll
does have an init callback to make sure the boot-selected frequency is
using the expected pll settings and resets the same frequency using
the values provided in the driver if necessary.

The setting itself also involves remuxing the pll-mux temporarily to
the xin24m source to let the new pll rate settle. Until now this worked
flawlessly, even when it had the flaw of accessing the mux settings
before the mux actually got registered.

With the recent clock-core conversions this flaw became apparent in
null pointer dereference in
[<c03fc400>] (clk_hw_get_num_parents) from [<c0400df0>] (clk_mux_get_parent+0x14/0xc8)
[<c0400ddc>] (clk_mux_get_parent) from [<c040246c>] (rockchip_rk3066_pll_set_rate+0xd8/0x320)

So to fix that, simply register the pll-mux before the pll, so that
it will be fully initialized when the pll clock executes its init-
callback and possibly touches the pll-mux clock.

Signed-off-by: Heiko Stuebner <heiko at sntech.de>
---
This only surfaced with the clk_core changes for 4.3, so should
probably just go on top.

 drivers/clk/rockchip/clk-pll.c | 63 +++++++++++++++++++++---------------------
 1 file changed, 32 insertions(+), 31 deletions(-)

diff --git a/drivers/clk/rockchip/clk-pll.c b/drivers/clk/rockchip/clk-pll.c
index eab4304..7737a1d 100644
--- a/drivers/clk/rockchip/clk-pll.c
+++ b/drivers/clk/rockchip/clk-pll.c
@@ -353,6 +353,35 @@ struct clk *rockchip_clk_register_pll(enum rockchip_pll_type pll_type,
 	if (!pll)
 		return ERR_PTR(-ENOMEM);
 
+	/* create the mux on top of the real pll */
+	pll->pll_mux_ops = &clk_mux_ops;
+	pll_mux = &pll->pll_mux;
+	pll_mux->reg = base + mode_offset;
+	pll_mux->shift = mode_shift;
+	pll_mux->mask = PLL_MODE_MASK;
+	pll_mux->flags = 0;
+	pll_mux->lock = lock;
+	pll_mux->hw.init = &init;
+
+	if (pll_type == pll_rk3066)
+		pll_mux->flags |= CLK_MUX_HIWORD_MASK;
+
+	/* the actual muxing is xin24m, pll-output, xin32k */
+	pll_parents[0] = parent_names[0];
+	pll_parents[1] = pll_name;
+	pll_parents[2] = parent_names[1];
+
+	init.name = name;
+	init.flags = CLK_SET_RATE_PARENT;
+	init.ops = pll->pll_mux_ops;
+	init.parent_names = pll_parents;
+	init.num_parents = ARRAY_SIZE(pll_parents);
+
+	mux_clk = clk_register(NULL, &pll_mux->hw);
+	if (IS_ERR(mux_clk))
+		goto err_mux;
+
+	/* now create the actual pll */
 	init.name = pll_name;
 
 	/* keep all plls untouched for now */
@@ -398,47 +427,19 @@ struct clk *rockchip_clk_register_pll(enum rockchip_pll_type pll_type,
 	pll->flags = clk_pll_flags;
 	pll->lock = lock;
 
-	/* create the mux on top of the real pll */
-	pll->pll_mux_ops = &clk_mux_ops;
-	pll_mux = &pll->pll_mux;
-	pll_mux->reg = base + mode_offset;
-	pll_mux->shift = mode_shift;
-	pll_mux->mask = PLL_MODE_MASK;
-	pll_mux->flags = 0;
-	pll_mux->lock = lock;
-	pll_mux->hw.init = &init;
-
-	if (pll_type == pll_rk3066)
-		pll_mux->flags |= CLK_MUX_HIWORD_MASK;
-
 	pll_clk = clk_register(NULL, &pll->hw);
 	if (IS_ERR(pll_clk)) {
 		pr_err("%s: failed to register pll clock %s : %ld\n",
 			__func__, name, PTR_ERR(pll_clk));
-		mux_clk = pll_clk;
 		goto err_pll;
 	}
 
-	/* the actual muxing is xin24m, pll-output, xin32k */
-	pll_parents[0] = parent_names[0];
-	pll_parents[1] = pll_name;
-	pll_parents[2] = parent_names[1];
-
-	init.name = name;
-	init.flags = CLK_SET_RATE_PARENT;
-	init.ops = pll->pll_mux_ops;
-	init.parent_names = pll_parents;
-	init.num_parents = ARRAY_SIZE(pll_parents);
-
-	mux_clk = clk_register(NULL, &pll_mux->hw);
-	if (IS_ERR(mux_clk))
-		goto err_mux;
-
 	return mux_clk;
 
-err_mux:
-	clk_unregister(pll_clk);
 err_pll:
+	clk_unregister(mux_clk);
+	mux_clk = pll_clk;
+err_mux:
 	kfree(pll);
 	return mux_clk;
 }
-- 
2.1.4




From l.stach at pengutronix.de  Wed Aug 19 06:19:46 2015
From: l.stach at pengutronix.de (Lucas Stach)
Date: Wed, 19 Aug 2015 15:19:46 +0200
Subject: [PATCH 1/2] ARM: imx53: include IRQ dt-bindings header
Message-ID: <1439990387-8602-1-git-send-email-l.stach@pengutronix.de>

Allows to use the more meaningful IRQ flag defines instead of
the raw values.

Signed-off-by: Lucas Stach <l.stach at pengutronix.de>
---
 arch/arm/boot/dts/imx53.dtsi | 1 +
 1 file changed, 1 insertion(+)

diff --git a/arch/arm/boot/dts/imx53.dtsi b/arch/arm/boot/dts/imx53.dtsi
index c3e3ca9362fb..cd170376eaca 100644
--- a/arch/arm/boot/dts/imx53.dtsi
+++ b/arch/arm/boot/dts/imx53.dtsi
@@ -15,6 +15,7 @@
 #include <dt-bindings/clock/imx5-clock.h>
 #include <dt-bindings/gpio/gpio.h>
 #include <dt-bindings/input/input.h>
+#include <dt-bindings/interrupt-controller/irq.h>
 
 / {
 	aliases {
-- 
2.4.6



From l.stach at pengutronix.de  Wed Aug 19 06:19:47 2015
From: l.stach at pengutronix.de (Lucas Stach)
Date: Wed, 19 Aug 2015 15:19:47 +0200
Subject: [PATCH 2/2] ARM: imx53: qsrb: fix PMIC interrupt level
In-Reply-To: <1439990387-8602-1-git-send-email-l.stach@pengutronix.de>
References: <1439990387-8602-1-git-send-email-l.stach@pengutronix.de>
Message-ID: <1439990387-8602-2-git-send-email-l.stach@pengutronix.de>

The MC34708 PMIC interrupt level is active high, but was set to
active low in the devicetree, probably as a result of a copy and
paste error from the QSB board.

This caused IRQ storms and led to the kernel disabling the PMIC
interrupt.

Signed-off-by: Lucas Stach <l.stach at pengutronix.de>
---
 arch/arm/boot/dts/imx53-qsrb.dts | 2 +-
 1 file changed, 1 insertion(+), 1 deletion(-)

diff --git a/arch/arm/boot/dts/imx53-qsrb.dts b/arch/arm/boot/dts/imx53-qsrb.dts
index 82d623d05915..bbb3f4b7a7fe 100644
--- a/arch/arm/boot/dts/imx53-qsrb.dts
+++ b/arch/arm/boot/dts/imx53-qsrb.dts
@@ -48,7 +48,7 @@
 		pinctrl-0 = <&pinctrl_pmic>;
 		reg = <0x08>;
 		interrupt-parent = <&gpio5>;
-		interrupts = <23 0x8>;
+		interrupts = <23 IRQ_TYPE_LEVEL_HIGH>;
 		regulators {
 			sw1_reg: sw1a {
 				regulator-name = "SW1";
-- 
2.4.6



From rabin.vincent at axis.com  Wed Aug 19 06:43:38 2015
From: rabin.vincent at axis.com (Rabin Vincent)
Date: Wed, 19 Aug 2015 15:43:38 +0200
Subject: [PATCH] clocksource: arm_global_timer: register delay timer
Message-ID: <1439991818-31989-1-git-send-email-rabin.vincent@axis.com>

Provide a delay timer using the lower 32-bits of the global timer so
that we can use that instead of having to calibrating delays.

Signed-off-by: Rabin Vincent <rabin.vincent at axis.com>
---
 drivers/clocksource/arm_global_timer.c |   17 +++++++++++++++++
 1 file changed, 17 insertions(+)

diff --git a/drivers/clocksource/arm_global_timer.c b/drivers/clocksource/arm_global_timer.c
index e683377..f92a77d 100644
--- a/drivers/clocksource/arm_global_timer.c
+++ b/drivers/clocksource/arm_global_timer.c
@@ -16,6 +16,7 @@
 #include <linux/clockchips.h>
 #include <linux/cpu.h>
 #include <linux/clk.h>
+#include <linux/delay.h>
 #include <linux/err.h>
 #include <linux/io.h>
 #include <linux/of.h>
@@ -208,6 +209,21 @@ static u64 notrace gt_sched_clock_read(void)
 }
 #endif
 
+static unsigned long gt_read_long(void)
+{
+	return readl_relaxed(gt_base + GT_COUNTER0);
+}
+
+static struct delay_timer gt_delay_timer = {
+	.read_current_timer = gt_read_long,
+};
+
+static void __init gt_delay_timer_init(void)
+{
+	gt_delay_timer.freq = gt_clk_rate;
+	register_current_timer_delay(&gt_delay_timer);
+}
+
 static void __init gt_clocksource_init(void)
 {
 	writel(0, gt_base + GT_CONTROL);
@@ -304,6 +320,7 @@ static void __init global_timer_of_register(struct device_node *np)
 	/* Immediately configure the timer on the boot CPU */
 	gt_clocksource_init();
 	gt_clockevents_init(this_cpu_ptr(gt_evt));
+	gt_delay_timer_init();
 
 	return;
 
-- 
1.7.10.4



From lee.jones at linaro.org  Wed Aug 19 07:22:50 2015
From: lee.jones at linaro.org (Lee Jones)
Date: Wed, 19 Aug 2015 15:22:50 +0100
Subject: [PATCH v3 0/5] Mailbox: Provide support STi based platforms
Message-ID: <1439994175-13360-1-git-send-email-lee.jones@linaro.org>

ST's platforms currently support a maximum of 5 Mailboxes, one for
each of the supported co-processors situated on the platform.  Each
Mailbox is divided up into 4 instances which consist of 32 channels.
Messages are passed between the application and co-processors using
shared memory areas.

Also included in the set is an example Client which should be generic
enough to use as a testing environment for all Mailbox IPs which use
shared memory or the API to pass messages.  With small changes, it
should also be able to test more extravagant implementations.

v2 => v3:
 - Controller
   - Shared (DT <=> Device Driver) defines removed
   - Return actual error codes instead of NULL in xlate()
   - Not passing 'direction' configuration via DT anymore
     - Removed all accompanying configuration checking code
 - Test F/W
   - Allow Rx-only and Tx-only controllers to be tested
   - Cater for controllers requiring pre-Tx 'signal' to be sent
   - Supply 'wr-' message debugfs file
     - When written to, will Tx message through Mailbox Framework
     - When read from, will print out a hexdump of Rx'ed message
 
v1 => v2:
 - New MACRO() to obtain base address for a given instance
 - Move locking into the structure it protects
 - Stop checking for 'ready' state when sending data
 - Don't clear channel data (that belongs to the API)
 - #define register offsets instead of providing via pdata
 - Register driver with module_platform_driver()

Lee Jones (5):
  mailbox: dt: Supply bindings for ST's Mailbox IP
  mailbox: Add support for ST's Mailbox IP
  ARM: STi: stih407-family: Add nodes for Mailbox
  mailbox: Add generic mechanism for testing Mailbox Controllers
  ARM: STi: DT: STiH407: Enable Mailbox testing facility

 .../devicetree/bindings/mailbox/sti-mailbox.txt    |  52 +++
 arch/arm/boot/dts/stih407-family.dtsi              |  42 ++
 drivers/mailbox/Kconfig                            |  14 +
 drivers/mailbox/Makefile                           |   4 +
 drivers/mailbox/mailbox-sti.c                      | 516 +++++++++++++++++++++
 drivers/mailbox/mailbox-test.c                     | 361 ++++++++++++++
 6 files changed, 989 insertions(+)
 create mode 100644 Documentation/devicetree/bindings/mailbox/sti-mailbox.txt
 create mode 100644 drivers/mailbox/mailbox-sti.c
 create mode 100644 drivers/mailbox/mailbox-test.c

-- 
1.9.1



From lee.jones at linaro.org  Wed Aug 19 07:22:51 2015
From: lee.jones at linaro.org (Lee Jones)
Date: Wed, 19 Aug 2015 15:22:51 +0100
Subject: [PATCH v3 1/5] mailbox: dt: Supply bindings for ST's Mailbox IP
In-Reply-To: <1439994175-13360-1-git-send-email-lee.jones@linaro.org>
References: <1439994175-13360-1-git-send-email-lee.jones@linaro.org>
Message-ID: <1439994175-13360-2-git-send-email-lee.jones@linaro.org>

Signed-off-by: Lee Jones <lee.jones at linaro.org>
---
 .../devicetree/bindings/mailbox/sti-mailbox.txt    | 52 ++++++++++++++++++++++
 1 file changed, 52 insertions(+)
 create mode 100644 Documentation/devicetree/bindings/mailbox/sti-mailbox.txt

diff --git a/Documentation/devicetree/bindings/mailbox/sti-mailbox.txt b/Documentation/devicetree/bindings/mailbox/sti-mailbox.txt
new file mode 100644
index 0000000..9fb4400
--- /dev/null
+++ b/Documentation/devicetree/bindings/mailbox/sti-mailbox.txt
@@ -0,0 +1,52 @@
+ST Microelectronics Mailbox Driver
+
+Each ST Mailbox IP currently consists of 4 instances of 32 channels.  Messages
+are passed between Application and Remote processors using shared memory.
+
+Controller
+----------
+
+Required properties:
+- compatible		: Should be "st,stih407-mailbox"
+- reg			: Offset and length of the device's register set
+- mbox-name		: Name of the mailbox
+- #mbox-cells:		: Must be 2
+			  <&phandle instance channel direction>
+			    phandle   : Label name of controller
+			    instance  : Instance number
+			    channel   : Channel number
+
+Optional properties
+- interrupts		: Contains the IRQ line for a Rx mailbox
+- tx-only		: Denotes Mailbox cannot receive messages
+
+Example:
+
+mailbox0: mailbox at 0  {
+	compatible	= "st,stih407-mailbox";
+	reg		= <0x08f00000 0x1000>;
+	interrupts	= <GIC_SPI 1 IRQ_TYPE_NONE>;
+	#mbox-cells	= <2>;
+	mbox-name	= "a9";
+};
+
+Client
+------
+
+Required properties:
+- compatible		: Many (See the client docs)
+- reg			: Shared (between Application and Remote) memory address
+- mboxes		: Standard property to specify a Mailbox (See ./mailbox.txt)
+			  Cells must match 'mbox-cells' (See Controller docs above)
+
+Optional properties
+- mbox-names		: Name given to channels seen in the 'mboxes' property.
+
+Example:
+
+mailbox_test {
+	compatible	= "mailbox_test";
+	reg		= <0x[shared_memory_address], [shared_memory_size]>;
+	mboxes		= <&mailbox2 0 1>, <&mailbox0 2 1>;
+	mbox-names	= "tx",	"rx";
+};
-- 
1.9.1



From lee.jones at linaro.org  Wed Aug 19 07:22:52 2015
From: lee.jones at linaro.org (Lee Jones)
Date: Wed, 19 Aug 2015 15:22:52 +0100
Subject: [PATCH v3 2/5] mailbox: Add support for ST's Mailbox IP
In-Reply-To: <1439994175-13360-1-git-send-email-lee.jones@linaro.org>
References: <1439994175-13360-1-git-send-email-lee.jones@linaro.org>
Message-ID: <1439994175-13360-3-git-send-email-lee.jones@linaro.org>

ST's platforms currently support a maximum of 5 Mailboxes, one for
each of the supported co-processors situated on the platform.  Each
Mailbox is divided up into 4 instances which consist of 32 channels.
Messages are passed between the application and co-processors using
shared memory areas.  It is the Client's responsibility to manage
these areas.

Signed-off-by: Lee Jones <lee.jones at linaro.org>
---
 drivers/mailbox/Kconfig       |   7 +
 drivers/mailbox/Makefile      |   2 +
 drivers/mailbox/mailbox-sti.c | 516 ++++++++++++++++++++++++++++++++++++++++++
 3 files changed, 525 insertions(+)
 create mode 100644 drivers/mailbox/mailbox-sti.c

diff --git a/drivers/mailbox/Kconfig b/drivers/mailbox/Kconfig
index e269f08..2cc4c39 100644
--- a/drivers/mailbox/Kconfig
+++ b/drivers/mailbox/Kconfig
@@ -70,4 +70,11 @@ config BCM2835_MBOX
 	  the services of the Videocore. Say Y here if you want to use the
 	  BCM2835 Mailbox.
 
+config STI_MBOX
+	tristate "STI Mailbox framework support"
+	depends on ARCH_STI && OF
+	help
+	  Mailbox implementation for STMicroelectonics family chips with
+	  hardware for interprocessor communication.
+
 endif
diff --git a/drivers/mailbox/Makefile b/drivers/mailbox/Makefile
index 8e6d822..7cb4766 100644
--- a/drivers/mailbox/Makefile
+++ b/drivers/mailbox/Makefile
@@ -13,3 +13,5 @@ obj-$(CONFIG_PCC)		+= pcc.o
 obj-$(CONFIG_ALTERA_MBOX)	+= mailbox-altera.o
 
 obj-$(CONFIG_BCM2835_MBOX)	+= bcm2835-mailbox.o
+
+obj-$(CONFIG_STI_MBOX)		+= mailbox-sti.o
diff --git a/drivers/mailbox/mailbox-sti.c b/drivers/mailbox/mailbox-sti.c
new file mode 100644
index 0000000..b1618d2
--- /dev/null
+++ b/drivers/mailbox/mailbox-sti.c
@@ -0,0 +1,516 @@
+/*
+ * STi Mailbox
+ *
+ * Copyright (C) 2015 ST Microelectronics
+ *
+ * Author: Lee Jones <lee.jones at linaro.org> for ST Microelectronics
+ *
+ * Based on the original driver written by;
+ *   Alexandre Torgue, Olivier Lebreton and Loic Pallardy
+ *
+ * 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.
+ */
+
+#include <linux/err.h>
+#include <linux/interrupt.h>
+#include <linux/io.h>
+#include <linux/kernel.h>
+#include <linux/mailbox_controller.h>
+#include <linux/module.h>
+#include <linux/of.h>
+#include <linux/of_device.h>
+#include <linux/platform_device.h>
+#include <linux/slab.h>
+
+#include "mailbox.h"
+
+#define STI_MBOX_INST_MAX	4      /* RAM saving: Max supported instances */
+#define STI_MBOX_CHAN_MAX	20     /* RAM saving: Max supported channels  */
+
+#define STI_IRQ_VAL_OFFSET	0x04   /* Read interrupt status	              */
+#define STI_IRQ_SET_OFFSET	0x24   /* Generate a Tx channel interrupt     */
+#define STI_IRQ_CLR_OFFSET	0x44   /* Clear pending Rx interrupts	      */
+#define STI_ENA_VAL_OFFSET	0x64   /* Read enable status		      */
+#define STI_ENA_SET_OFFSET	0x84   /* Enable a channel		      */
+#define STI_ENA_CLR_OFFSET	0xa4   /* Disable a channel		      */
+
+#define MBOX_BASE(mdev, inst)   ((mdev)->base + (inst * 4))
+
+/**
+ * STi Mailbox device data
+ *
+ * An IP Mailbox is currently composed of 4 instances
+ * Each instance is currently composed of 32 channels
+ * This means that we have 128 channels per Mailbox
+ * A channel an be used for TX or RX
+ *
+ * @dev:	Device to which it is attached
+ * @mbox:	Representation of a communication channel controller
+ * @base:	Base address of the register mapping region
+ * @name:	Name of the mailbox
+ * @enabled:	Local copy of enabled channels
+ * @lock:	Mutex protecting enabled status
+ */
+struct sti_mbox_device {
+	struct device		*dev;
+	struct mbox_controller	*mbox;
+	void __iomem		*base;
+	const char		*name;
+	u32			enabled[STI_MBOX_INST_MAX];
+	spinlock_t		lock;
+	bool			txonly;
+};
+
+/**
+ * STi Mailbox platform specfic configuration
+ *
+ * @num_inst:	Maximum number of instances in one HW Mailbox
+ * @num_chan:	Maximum number of channel per instance
+ */
+struct sti_mbox_pdata {
+	unsigned int		num_inst;
+	unsigned int		num_chan;
+};
+
+/**
+ * STi Mailbox allocated channel information
+ *
+ * @mdev:	Pointer to parent Mailbox device
+ * @instance:	Instance number channel resides in
+ * @channel:	Channel number pertaining to this container
+ */
+struct sti_channel {
+	struct sti_mbox_device	*mdev;
+	unsigned int		instance;
+	unsigned int		channel;
+};
+
+static inline bool sti_mbox_channel_is_enabled(struct mbox_chan *chan)
+{
+	struct sti_channel *chan_info = chan->con_priv;
+	struct sti_mbox_device *mdev = chan_info->mdev;
+	unsigned int instance = chan_info->instance;
+	unsigned int channel = chan_info->channel;
+
+	return mdev->enabled[instance] & BIT(channel);
+}
+
+static inline
+struct mbox_chan *sti_mbox_to_channel(struct mbox_controller *mbox,
+				      unsigned int instance,
+				      unsigned int channel)
+{
+	struct sti_channel *chan_info;
+	int i;
+
+	for (i = 0; i < mbox->num_chans; i++) {
+		chan_info = mbox->chans[i].con_priv;
+		if (chan_info &&
+		    chan_info->instance == instance &&
+		    chan_info->channel == channel)
+			return &mbox->chans[i];
+	}
+
+	dev_err(mbox->dev,
+		"Channel not registered: instance: %d channel: %d\n",
+		instance, channel);
+
+	return NULL;
+}
+
+static void sti_mbox_enable_channel(struct mbox_chan *chan)
+{
+	struct sti_channel *chan_info = chan->con_priv;
+	struct sti_mbox_device *mdev = chan_info->mdev;
+	unsigned int instance = chan_info->instance;
+	unsigned int channel = chan_info->channel;
+	unsigned long flags;
+	void __iomem *base = MBOX_BASE(mdev, instance);
+
+	spin_lock_irqsave(&mdev->lock, flags);
+	mdev->enabled[instance] |= BIT(channel);
+	writel_relaxed(BIT(channel), base + STI_ENA_SET_OFFSET);
+	spin_unlock_irqrestore(&mdev->lock, flags);
+}
+
+static void sti_mbox_disable_channel(struct mbox_chan *chan)
+{
+	struct sti_channel *chan_info = chan->con_priv;
+	struct sti_mbox_device *mdev = chan_info->mdev;
+	unsigned int instance = chan_info->instance;
+	unsigned int channel = chan_info->channel;
+	unsigned long flags;
+	void __iomem *base = MBOX_BASE(mdev, instance);
+
+	spin_lock_irqsave(&mdev->lock, flags);
+	mdev->enabled[instance] &= ~BIT(channel);
+	writel_relaxed(BIT(channel), base + STI_ENA_CLR_OFFSET);
+	spin_unlock_irqrestore(&mdev->lock, flags);
+}
+
+static void sti_mbox_clear_irq(struct mbox_chan *chan)
+{
+	struct sti_channel *chan_info = chan->con_priv;
+	struct sti_mbox_device *mdev = chan_info->mdev;
+	unsigned int instance = chan_info->instance;
+	unsigned int channel = chan_info->channel;
+	void __iomem *base = MBOX_BASE(mdev, instance);
+
+	writel_relaxed(BIT(channel), base + STI_IRQ_CLR_OFFSET);
+}
+
+static struct mbox_chan *sti_mbox_irq_to_channel(struct sti_mbox_device *mdev,
+						 unsigned int instance)
+{
+	struct mbox_controller *mbox = mdev->mbox;
+	struct mbox_chan *chan = NULL;
+	unsigned int channel;
+	unsigned long bits;
+	void __iomem *base = MBOX_BASE(mdev, instance);
+
+	bits = readl_relaxed(base + STI_IRQ_VAL_OFFSET);
+	if (!bits)
+		/* No IRQs fired in specified instance */
+		return NULL;
+
+	/* An IRQ has fired, find the associated channel */
+	for (channel = 0; bits; channel++) {
+		if (!test_and_clear_bit(channel, &bits))
+			continue;
+
+		chan = sti_mbox_to_channel(mbox, instance, channel);
+		if (chan) {
+			dev_dbg(mbox->dev,
+				"IRQ fired on instance: %d channel: %d\n",
+				instance, channel);
+			break;
+		}
+	}
+
+	return chan;
+}
+
+static irqreturn_t sti_mbox_thread_handler(int irq, void *data)
+{
+	struct sti_mbox_device *mdev = data;
+	struct sti_mbox_pdata *pdata = dev_get_platdata(mdev->dev);
+	struct mbox_chan *chan;
+	unsigned int instance;
+
+	for (instance = 0; instance < pdata->num_inst; instance++) {
+keep_looking:
+		chan = sti_mbox_irq_to_channel(mdev, instance);
+		if (!chan)
+			continue;
+
+		mbox_chan_received_data(chan, NULL);
+		sti_mbox_clear_irq(chan);
+		sti_mbox_enable_channel(chan);
+		goto keep_looking;
+	}
+
+	return IRQ_HANDLED;
+}
+
+static irqreturn_t sti_mbox_irq_handler(int irq, void *data)
+{
+	struct sti_mbox_device *mdev = data;
+	struct sti_mbox_pdata *pdata = dev_get_platdata(mdev->dev);
+	struct sti_channel *chan_info;
+	struct mbox_chan *chan;
+	unsigned int instance;
+	int ret = IRQ_NONE;
+
+	for (instance = 0; instance < pdata->num_inst; instance++) {
+		chan = sti_mbox_irq_to_channel(mdev, instance);
+		if (!chan)
+			continue;
+		chan_info = chan->con_priv;
+
+		if (!sti_mbox_channel_is_enabled(chan)) {
+			dev_warn(mdev->dev,
+				 "Unexpected IRQ: %s\n"
+				 "  instance: %d: channel: %d [enabled: %x]\n",
+				 mdev->name, chan_info->instance,
+				 chan_info->channel, mdev->enabled[instance]);
+
+			/* Only handle IRQ if no other valid IRQs were found */
+			if (ret == IRQ_NONE)
+				ret = IRQ_HANDLED;
+			continue;
+		}
+
+		sti_mbox_disable_channel(chan);
+		ret = IRQ_WAKE_THREAD;
+	}
+
+	if (ret == IRQ_NONE)
+		dev_err(mdev->dev, "Spurious IRQ - was a channel requested?\n");
+
+	return ret;
+}
+
+static bool sti_mbox_tx_is_ready(struct mbox_chan *chan)
+{
+	struct sti_channel *chan_info = chan->con_priv;
+	struct sti_mbox_device *mdev = chan_info->mdev;
+	unsigned int instance = chan_info->instance;
+	unsigned int channel = chan_info->channel;
+	void __iomem *base = MBOX_BASE(mdev, instance);
+
+	if (!(readl_relaxed(base + STI_ENA_VAL_OFFSET) & BIT(channel))) {
+		dev_dbg(mdev->dev, "Mbox: %s: inst: %d, chan: %d disabled\n",
+			mdev->name, instance, channel);
+		return false;
+	}
+
+	if (readl_relaxed(base + STI_IRQ_VAL_OFFSET) & BIT(channel)) {
+		dev_dbg(mdev->dev, "Mbox: %s: inst: %d, chan: %d not ready\n",
+			mdev->name, instance, channel);
+		return false;
+	}
+
+	return true;
+}
+
+static int sti_mbox_send_data(struct mbox_chan *chan, void *data)
+{
+	struct sti_channel *chan_info = chan->con_priv;
+	struct sti_mbox_device *mdev = chan_info->mdev;
+	unsigned int instance = chan_info->instance;
+	unsigned int channel = chan_info->channel;
+	void __iomem *base = MBOX_BASE(mdev, instance);
+
+	/* Send event to co-processor */
+	writel_relaxed(BIT(channel), base + STI_IRQ_SET_OFFSET);
+
+	dev_dbg(mdev->dev,
+		"Sent via Mailbox %s: instance: %d channel: %d\n",
+		mdev->name, instance, channel);
+
+	return 0;
+}
+
+static int sti_mbox_startup_chan(struct mbox_chan *chan)
+{
+	sti_mbox_clear_irq(chan);
+	sti_mbox_enable_channel(chan);
+
+	return 0;
+}
+
+static void sti_mbox_shutdown_chan(struct mbox_chan *chan)
+{
+	struct sti_channel *chan_info = chan->con_priv;
+	struct mbox_controller *mbox = chan_info->mdev->mbox;
+	int i;
+
+	for (i = 0; i < mbox->num_chans; i++)
+		if (chan == &mbox->chans[i])
+			break;
+
+	if (mbox->num_chans == i) {
+		dev_warn(mbox->dev, "Request to free non-existent channel\n");
+		return;
+	}
+
+	/* Reset channel */
+	sti_mbox_disable_channel(chan);
+	sti_mbox_clear_irq(chan);
+	chan->con_priv = NULL;
+}
+
+static struct mbox_chan *sti_mbox_xlate(struct mbox_controller *mbox,
+					const struct of_phandle_args *spec)
+{
+	struct sti_mbox_device *mdev = dev_get_drvdata(mbox->dev);
+	struct sti_mbox_pdata *pdata = dev_get_platdata(mdev->dev);
+	struct sti_channel *chan_info;
+	struct mbox_chan *chan = NULL;
+	unsigned int instance  = spec->args[0];
+	unsigned int channel   = spec->args[1];
+	int i;
+
+	/* Bounds checking */
+	if (instance >= pdata->num_inst || channel  >= pdata->num_chan) {
+		dev_err(mbox->dev,
+			"Invalid channel requested instance: %d channel: %d\n",
+			instance, channel);
+		return ERR_PTR(-EINVAL);
+	}
+
+	for (i = 0; i < mbox->num_chans; i++) {
+		chan_info = mbox->chans[i].con_priv;
+
+		/* Is requested channel free? */
+		if (chan_info &&
+		    mbox->dev == chan_info->mdev->dev &&
+		    instance == chan_info->instance &&
+		    channel == chan_info->channel) {
+
+			dev_err(mbox->dev, "Channel in use\n");
+			return ERR_PTR(-EBUSY);
+		}
+
+		/*
+		 * Find the first free slot, then continue checking
+		 * to see if requested channel is in use
+		 */
+		if (!chan && !chan_info)
+			chan = &mbox->chans[i];
+	}
+
+	if (!chan) {
+		dev_err(mbox->dev, "No free channels left\n");
+		return ERR_PTR(-EBUSY);
+	}
+
+	chan_info = devm_kzalloc(mbox->dev, sizeof(*chan_info), GFP_KERNEL);
+	if (!chan_info)
+		return ERR_PTR(-ENOMEM);
+
+	chan_info->mdev		= mdev;
+	chan_info->instance	= instance;
+	chan_info->channel	= channel;
+
+	chan->con_priv = chan_info;
+
+	dev_info(mbox->dev,
+		 "Mbox: %s: Created channel: instance: %d channel: %d\n",
+		 mdev->name, instance, channel);
+
+	return chan;
+}
+
+static struct mbox_chan_ops sti_mbox_ops = {
+	.startup	= sti_mbox_startup_chan,
+	.shutdown	= sti_mbox_shutdown_chan,
+	.send_data	= sti_mbox_send_data,
+	.last_tx_done	= sti_mbox_tx_is_ready,
+};
+
+static const struct sti_mbox_pdata mbox_stih407_pdata = {
+	.num_inst	= 4,
+	.num_chan	= 32,
+};
+
+static const struct of_device_id sti_mailbox_match[] = {
+	{
+		.compatible = "st,stih407-mailbox",
+		.data = (void *)&mbox_stih407_pdata
+	},
+	{ }
+};
+
+static int sti_mbox_probe(struct platform_device *pdev)
+{
+	const struct of_device_id *match;
+	struct mbox_controller *mbox;
+	struct sti_mbox_device *mdev;
+	struct device_node *np = pdev->dev.of_node;
+	struct mbox_chan *chans;
+	struct resource *res;
+	int irq;
+	int ret;
+
+	match = of_match_device(sti_mailbox_match, &pdev->dev);
+	if (!match) {
+		dev_err(&pdev->dev, "No configuration found\n");
+		return -ENODEV;
+	}
+	pdev->dev.platform_data = (struct sti_mbox_pdata *) match->data;
+
+	mdev = devm_kzalloc(&pdev->dev, sizeof(*mdev), GFP_KERNEL);
+	if (!mdev)
+		return -ENOMEM;
+
+	platform_set_drvdata(pdev, mdev);
+
+	res = platform_get_resource(pdev, IORESOURCE_MEM, 0);
+	mdev->base = devm_ioremap_resource(&pdev->dev, res);
+	if (!mdev->base)
+		return -ENOMEM;
+
+	ret = of_property_read_string(np, "mbox-name", &mdev->name);
+	if (ret)
+		mdev->name = np->full_name;
+
+	mdev->txonly = of_property_read_bool(np, "tx-only");
+
+	mbox = devm_kzalloc(&pdev->dev, sizeof(*mbox), GFP_KERNEL);
+	if (!mbox)
+		return -ENOMEM;
+
+	chans = devm_kzalloc(&pdev->dev,
+			     sizeof(*chans) * STI_MBOX_CHAN_MAX, GFP_KERNEL);
+	if (!chans)
+		return -ENOMEM;
+
+	mdev->dev		= &pdev->dev;
+	mdev->mbox		= mbox;
+
+	spin_lock_init(&mdev->lock);
+
+	/* STi Mailbox does not have a Tx-Done or Tx-Ready IRQ */
+	mbox->txdone_irq	= false;
+	mbox->txdone_poll	= true;
+	mbox->txpoll_period	= 100;
+	mbox->ops		= &sti_mbox_ops;
+	mbox->dev		= mdev->dev;
+	mbox->of_xlate		= sti_mbox_xlate;
+	mbox->chans		= chans;
+	mbox->num_chans		= STI_MBOX_CHAN_MAX;
+
+	ret = mbox_controller_register(mbox);
+	if (ret)
+		return ret;
+
+	/* It's okay for Tx Mailboxes to not supply IRQs */
+	irq = platform_get_irq(pdev, 0);
+	if (irq < 0) {
+		dev_info(&pdev->dev,
+			 "%s: Registered Tx only Mailbox\n", mdev->name);
+		return 0;
+	}
+
+	ret = devm_request_threaded_irq(&pdev->dev, irq,
+					sti_mbox_irq_handler,
+					sti_mbox_thread_handler,
+					IRQF_ONESHOT, mdev->name, mdev);
+	if (ret) {
+		dev_err(&pdev->dev, "Can't claim IRQ %d\n", irq);
+		mbox_controller_unregister(mbox);
+		return -EINVAL;
+	}
+
+	dev_info(&pdev->dev, "%s: Registered Tx/Rx Mailbox\n", mdev->name);
+
+	return 0;
+}
+
+static int sti_mbox_remove(struct platform_device *pdev)
+{
+	struct sti_mbox_device *mdev = platform_get_drvdata(pdev);
+
+	mbox_controller_unregister(mdev->mbox);
+
+	return 0;
+}
+
+static struct platform_driver sti_mbox_driver = {
+	.probe = sti_mbox_probe,
+	.remove = sti_mbox_remove,
+	.driver = {
+		.name = "sti-mailbox",
+		.of_match_table = sti_mailbox_match,
+	},
+};
+module_platform_driver(sti_mbox_driver);
+
+MODULE_LICENSE("GPL");
+MODULE_DESCRIPTION("STMicroelectronics Mailbox Controller");
+MODULE_AUTHOR("Lee Jones <lee.jones at linaro.org");
+MODULE_ALIAS("platform:mailbox-sti");
-- 
1.9.1



From lee.jones at linaro.org  Wed Aug 19 07:22:53 2015
From: lee.jones at linaro.org (Lee Jones)
Date: Wed, 19 Aug 2015 15:22:53 +0100
Subject: [PATCH v3 3/5] ARM: STi: stih407-family: Add nodes for Mailbox
In-Reply-To: <1439994175-13360-1-git-send-email-lee.jones@linaro.org>
References: <1439994175-13360-1-git-send-email-lee.jones@linaro.org>
Message-ID: <1439994175-13360-4-git-send-email-lee.jones@linaro.org>

This patch supplies the Mailbox Controller nodes.  In order to
request channels, these nodes will be referenced by Mailbox
Client nodes.

Signed-off-by: Lee Jones <lee.jones at linaro.org>
---
 arch/arm/boot/dts/stih407-family.dtsi | 36 +++++++++++++++++++++++++++++++++++
 1 file changed, 36 insertions(+)

diff --git a/arch/arm/boot/dts/stih407-family.dtsi b/arch/arm/boot/dts/stih407-family.dtsi
index 838b812..32da3f8 100644
--- a/arch/arm/boot/dts/stih407-family.dtsi
+++ b/arch/arm/boot/dts/stih407-family.dtsi
@@ -565,5 +565,41 @@
 						  <&phy_port2 PHY_TYPE_USB3>;
 			};
 		};
+
+		mailbox0: mailbox at 0  {
+			compatible	= "st,stih407-mailbox";
+			reg		= <0x8f00000 0x1000>;
+			interrupts	= <GIC_SPI 1 IRQ_TYPE_NONE>;
+			#mbox-cells	= <2>;
+			mbox-name	= "a9";
+			status		= "okay";
+		};
+
+		mailbox1: mailbox at 1 {
+			compatible	= "st,stih407-mailbox";
+			reg		= <0x8f01000 0x1000>;
+			#mbox-cells	= <2>;
+			mbox-name	= "st231_gp_1";
+			status		= "okay";
+			tx-only;
+		};
+
+		mailbox2: mailbox at 2 {
+			compatible	= "st,stih407-mailbox";
+			reg		= <0x8f02000 0x1000>;
+			#mbox-cells	= <2>;
+			mbox-name	= "st231_gp_0";
+			status		= "okay";
+			tx-only;
+		};
+
+		mailbox3: mailbox at 3 {
+			compatible	= "st,stih407-mailbox";
+			reg		= <0x8f03000 0x1000>;
+			#mbox-cells	= <2>;
+			mbox-name	= "st231_audio_video";
+			status		= "okay";
+			tx-only;
+		};
 	};
 };
-- 
1.9.1



From lee.jones at linaro.org  Wed Aug 19 07:22:54 2015
From: lee.jones at linaro.org (Lee Jones)
Date: Wed, 19 Aug 2015 15:22:54 +0100
Subject: [PATCH v3 4/5] mailbox: Add generic mechanism for testing Mailbox
 Controllers
In-Reply-To: <1439994175-13360-1-git-send-email-lee.jones@linaro.org>
References: <1439994175-13360-1-git-send-email-lee.jones@linaro.org>
Message-ID: <1439994175-13360-5-git-send-email-lee.jones@linaro.org>

This particular Client implementation uses shared memory in order
to pass messages between Mailbox users; however, it can be easily
hacked to support any type of Controller.

Signed-off-by: Lee Jones <lee.jones at linaro.org>
---
 drivers/mailbox/Kconfig        |   7 +
 drivers/mailbox/Makefile       |   2 +
 drivers/mailbox/mailbox-test.c | 361 +++++++++++++++++++++++++++++++++++++++++
 3 files changed, 370 insertions(+)
 create mode 100644 drivers/mailbox/mailbox-test.c

diff --git a/drivers/mailbox/Kconfig b/drivers/mailbox/Kconfig
index 2cc4c39..7720bde 100644
--- a/drivers/mailbox/Kconfig
+++ b/drivers/mailbox/Kconfig
@@ -77,4 +77,11 @@ config STI_MBOX
 	  Mailbox implementation for STMicroelectonics family chips with
 	  hardware for interprocessor communication.
 
+config MAILBOX_TEST
+	tristate "Mailbox Test Client"
+	depends on OF
+	help
+	  Test client to help with testing new Controller driver
+	  implementations.
+
 endif
diff --git a/drivers/mailbox/Makefile b/drivers/mailbox/Makefile
index 7cb4766..92435ef 100644
--- a/drivers/mailbox/Makefile
+++ b/drivers/mailbox/Makefile
@@ -2,6 +2,8 @@
 
 obj-$(CONFIG_MAILBOX)		+= mailbox.o
 
+obj-$(CONFIG_MAILBOX_TEST)	+= mailbox-test.o
+
 obj-$(CONFIG_ARM_MHU)	+= arm_mhu.o
 
 obj-$(CONFIG_PL320_MBOX)	+= pl320-ipc.o
diff --git a/drivers/mailbox/mailbox-test.c b/drivers/mailbox/mailbox-test.c
new file mode 100644
index 0000000..cac1ba2
--- /dev/null
+++ b/drivers/mailbox/mailbox-test.c
@@ -0,0 +1,361 @@
+/*
+ * Copyright (C) 2015 ST Microelectronics
+ *
+ * Author: Lee Jones <lee.jones at linaro.org>
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2 of the License, or
+ * (at your option) any later version.
+ */
+
+#include <linux/debugfs.h>
+#include <linux/err.h>
+#include <linux/kernel.h>
+#include <linux/mailbox_client.h>
+#include <linux/module.h>
+#include <linux/of.h>
+#include <linux/platform_device.h>
+#include <linux/slab.h>
+#include <linux/uaccess.h>
+
+#define MBOX_MAX_SIG_LEN	8
+#define MBOX_MAX_MSG_LEN	128
+#define MBOX_BYTES_PER_LINE	16
+#define MBOX_HEXDUMP_LINE_LEN 	((MBOX_BYTES_PER_LINE * 4) + 2)
+#define MBOX_HEXDUMP_MAX_LEN	(MBOX_HEXDUMP_LINE_LEN *		\
+				 (MBOX_MAX_MSG_LEN / MBOX_BYTES_PER_LINE))
+
+static struct dentry *root_debugfs_dir;
+
+struct mbox_test_device {
+	struct device		*dev;
+	void __iomem		*mmio;
+	struct mbox_chan	*tx_channel;
+	struct mbox_chan	*rx_channel;
+	char			*rx_buffer;
+	char			*signal;
+	char			*message;
+	spinlock_t		lock;
+};
+
+static ssize_t mbox_test_signal_write(struct file *filp,
+				       const char __user *userbuf,
+				       size_t count, loff_t *ppos)
+{
+	struct mbox_test_device *tdev = filp->private_data;
+	int ret;
+
+	if (!tdev->tx_channel) {
+		dev_err(tdev->dev, "Channel cannot do Tx\n");
+		return -EINVAL;
+	}
+
+	if (count > MBOX_MAX_SIG_LEN) {
+		dev_err(tdev->dev,
+			"Signal length %d greater than max allowed %d\n",
+			count, MBOX_MAX_SIG_LEN);
+		return -EINVAL;
+	}
+
+	tdev->signal = kzalloc(MBOX_MAX_SIG_LEN, GFP_KERNEL);
+	if (!tdev->signal)
+		return -ENOMEM;
+
+	ret = copy_from_user(tdev->signal, userbuf, count);
+	if (ret) {
+		kfree(tdev->signal);
+		return -EFAULT;
+	}
+
+	return ret < 0 ? ret : count;
+}
+
+static const struct file_operations mbox_test_signal_ops = {
+	.write	= mbox_test_signal_write,
+	.open	= simple_open,
+	.llseek	= generic_file_llseek,
+};
+
+static ssize_t mbox_test_message_write(struct file *filp,
+				       const char __user *userbuf,
+				       size_t count, loff_t *ppos)
+{
+	struct mbox_test_device *tdev = filp->private_data;
+	void *data;
+	int ret;
+
+	if (!tdev->tx_channel) {
+		dev_err(tdev->dev, "Channel cannot do Tx\n");
+		return -EINVAL;
+	}
+
+	if (count > MBOX_MAX_MSG_LEN) {
+		dev_err(tdev->dev,
+			"Message length %d greater than max allowed %d\n",
+			count, MBOX_MAX_MSG_LEN);
+		return -EINVAL;
+	}
+
+	tdev->message = kzalloc(MBOX_MAX_MSG_LEN, GFP_KERNEL);
+	if (!tdev->message)
+		return -ENOMEM;
+
+	ret = copy_from_user(tdev->message, userbuf, count);
+	if (ret) {
+		ret = -EFAULT;
+		goto out;
+	}
+
+	/*
+	 * A separate signal is only of use if there is
+	 * MMIO to subsequently pass the message through
+	 */
+	if (tdev->mmio && tdev->signal) {
+		print_hex_dump(KERN_INFO, "Client: Sending: Signal: ", DUMP_PREFIX_ADDRESS,
+			       MBOX_BYTES_PER_LINE, 1, tdev->signal, MBOX_MAX_SIG_LEN, true);
+
+		data = tdev->signal;
+	} else
+		data = tdev->message;
+
+	print_hex_dump(KERN_INFO, "Client: Sending: Message: ", DUMP_PREFIX_ADDRESS,
+		       MBOX_BYTES_PER_LINE, 1, tdev->message, MBOX_MAX_MSG_LEN, true);
+
+	ret = mbox_send_message(tdev->tx_channel, data);
+	if (ret < 0)
+		dev_err(tdev->dev, "Failed to send message via mailbox\n");
+
+out:
+	kfree(tdev->signal);
+	kfree(tdev->message);
+
+	return ret < 0 ? ret : count;
+}
+
+static ssize_t mbox_test_message_read(struct file *filp, char __user *userbuf,
+				      size_t count, loff_t *ppos)
+{
+	struct mbox_test_device *tdev = filp->private_data;
+	unsigned long flags;
+	char *touser, *ptr;
+	int l = 0;
+	int ret;
+
+	touser = kzalloc(MBOX_HEXDUMP_MAX_LEN, GFP_KERNEL);
+	if (!touser)
+		return -ENOMEM;
+
+	if (!tdev->rx_channel) {
+		ret = snprintf(touser, 20, "<NO RX CAPABILITY>\n");
+		ret = simple_read_from_buffer(userbuf, count, ppos,
+					      touser, ret);
+		goto out;
+	}
+
+	if (tdev->rx_buffer[0] == '\0') {
+		ret = snprintf(touser, 9, "<EMPTY>\n");
+		ret = simple_read_from_buffer(userbuf, count, ppos,
+					      touser, ret);
+		goto out;
+	}
+
+	spin_lock_irqsave(&tdev->lock, flags);
+
+	ptr = tdev->rx_buffer;
+	while (l < MBOX_HEXDUMP_MAX_LEN) {
+		hex_dump_to_buffer(ptr,
+				   MBOX_BYTES_PER_LINE,
+				   MBOX_BYTES_PER_LINE, 1, touser + l,
+				   MBOX_HEXDUMP_LINE_LEN, true);
+
+		ptr += MBOX_BYTES_PER_LINE;
+		l += MBOX_HEXDUMP_LINE_LEN;
+		*(touser + (l - 1)) = '\n';
+	}
+	*(touser + l) = '\0';
+
+	memset(tdev->rx_buffer, 0, MBOX_MAX_MSG_LEN);
+
+	spin_unlock_irqrestore(&tdev->lock, flags);
+
+	ret = simple_read_from_buffer(userbuf, count, ppos, touser, MBOX_HEXDUMP_MAX_LEN);
+out:
+	kfree(touser);
+	return ret;
+}
+
+static const struct file_operations mbox_test_message_ops = {
+	.write	= mbox_test_message_write,
+	.read	= mbox_test_message_read,
+	.open	= simple_open,
+	.llseek	= generic_file_llseek,
+};
+
+static int mbox_test_add_debugfs(struct platform_device *pdev,
+				 struct mbox_test_device *tdev)
+{
+	if (!debugfs_initialized())
+		return 0;
+
+	root_debugfs_dir = debugfs_create_dir("mailbox", NULL);
+	if (!root_debugfs_dir) {
+		dev_err(&pdev->dev, "Failed to create Mailbox debugfs\n");
+		return -EINVAL;
+	}
+
+	debugfs_create_file("message", 0600, root_debugfs_dir,
+			    tdev, &mbox_test_message_ops);
+
+	debugfs_create_file("signal", 0200, root_debugfs_dir,
+			    tdev, &mbox_test_signal_ops);
+
+	return 0;
+}
+
+static void mbox_test_receive_message(struct mbox_client *client, void *message)
+{
+	struct mbox_test_device *tdev = dev_get_drvdata(client->dev);
+	unsigned long flags;
+
+	spin_lock_irqsave(&tdev->lock, flags);
+	if (tdev->mmio) {
+		print_hex_dump(KERN_INFO, "Client: Received [MMIO]: ",
+			       DUMP_PREFIX_ADDRESS, MBOX_BYTES_PER_LINE, 1,
+			       tdev->mmio, MBOX_MAX_MSG_LEN, true);
+		memcpy(tdev->rx_buffer, tdev->mmio, MBOX_MAX_MSG_LEN);
+
+	} else if (message) {
+		print_hex_dump(KERN_INFO, "Client: Received [API]: ",
+			       DUMP_PREFIX_ADDRESS, MBOX_BYTES_PER_LINE, 1,
+			       message, MBOX_MAX_MSG_LEN, true);
+		memcpy(tdev->rx_buffer, message, MBOX_MAX_MSG_LEN);
+	}
+	spin_unlock_irqrestore(&tdev->lock, flags);
+}
+
+static void mbox_test_prepare_message(struct mbox_client *client, void *message)
+{
+	struct mbox_test_device *tdev = dev_get_drvdata(client->dev);
+
+	if (tdev->mmio) {
+		if (tdev->signal)
+			memcpy(tdev->mmio, tdev->message, MBOX_MAX_MSG_LEN);
+		else
+			memcpy(tdev->mmio, message, MBOX_MAX_MSG_LEN);
+	}
+}
+
+static void mbox_test_message_sent(struct mbox_client *client,
+				   void *message, int r)
+{
+	if (r)
+		dev_warn(client->dev,
+			 "Client: Message could not be sent: %d\n", r);
+	else
+		dev_info(client->dev,
+			 "Client: Message sent\n");
+}
+
+static struct mbox_chan *
+mbox_test_request_channel(struct platform_device *pdev, const char *name)
+{
+	struct mbox_client *client;
+	struct mbox_chan *channel;
+
+	client = devm_kzalloc(&pdev->dev, sizeof(*client), GFP_KERNEL);
+	if (!client)
+		return ERR_PTR(-ENOMEM);
+
+	client->dev		= &pdev->dev;
+	client->rx_callback	= mbox_test_receive_message;
+	client->tx_prepare	= mbox_test_prepare_message;
+	client->tx_done		= mbox_test_message_sent;
+	client->tx_block	= true;
+	client->knows_txdone	= false;
+	client->tx_tout		= 500;
+
+	channel = mbox_request_channel_byname(client, name);
+	if (IS_ERR(channel)) {
+		dev_warn(&pdev->dev, "Failed to request %s channel\n", name);
+		return NULL;
+	}
+
+	return channel;
+}
+
+static int mbox_test_probe(struct platform_device *pdev)
+{
+	struct mbox_test_device *tdev;
+	struct resource *res;
+	int ret;
+
+	tdev = devm_kzalloc(&pdev->dev, sizeof(*tdev), GFP_KERNEL);
+	if (!tdev)
+		return -ENOMEM;
+
+	/* It's okay for MMIO to be NULL */
+	res = platform_get_resource(pdev, IORESOURCE_MEM, 0);
+	tdev->mmio = devm_ioremap_resource(&pdev->dev, res);
+	if (IS_ERR(tdev->mmio))
+		tdev->mmio = NULL;
+
+	tdev->tx_channel = mbox_test_request_channel(pdev, "tx");
+	tdev->rx_channel = mbox_test_request_channel(pdev, "rx");
+
+	if (!tdev->tx_channel && !tdev->tx_channel)
+		return -EPROBE_DEFER;
+
+	tdev->dev = &pdev->dev;
+	platform_set_drvdata(pdev, tdev);
+
+	spin_lock_init(&tdev->lock);
+
+	if (tdev->rx_channel) {
+		tdev->rx_buffer = devm_kzalloc(&pdev->dev,
+					       MBOX_MAX_MSG_LEN, GFP_KERNEL);
+		if (!tdev->rx_buffer)
+			return -ENOMEM;
+	}
+
+	ret = mbox_test_add_debugfs(pdev, tdev);
+	if (ret)
+		return ret;
+
+	dev_info(&pdev->dev, "Successfully registered\n");
+
+	return 0;
+}
+
+static int mbox_test_remove(struct platform_device *pdev)
+{
+	struct mbox_test_device *tdev = platform_get_drvdata(pdev);
+
+	debugfs_remove_recursive(root_debugfs_dir);
+
+	if (tdev->tx_channel)
+		mbox_free_channel(tdev->tx_channel);
+	if (tdev->rx_channel)
+		mbox_free_channel(tdev->rx_channel);
+
+	return 0;
+}
+
+static const struct of_device_id mbox_test_match[] = {
+	{ .compatible = "mailbox_test" },
+	{},
+};
+
+static struct platform_driver mbox_test_driver = {
+	.driver = {
+		.name = "mailbox_sti_test",
+		.of_match_table = mbox_test_match,
+	},
+	.probe  = mbox_test_probe,
+	.remove = mbox_test_remove,
+};
+module_platform_driver(mbox_test_driver);
+
+MODULE_DESCRIPTION("Generic Mailbox Testing Facility");
+MODULE_AUTHOR("Lee Jones <lee.jones at linaro.org");
+MODULE_LICENSE("GPL v2");
-- 
1.9.1



From lee.jones at linaro.org  Wed Aug 19 07:22:55 2015
From: lee.jones at linaro.org (Lee Jones)
Date: Wed, 19 Aug 2015 15:22:55 +0100
Subject: [PATCH v3 5/5] ARM: STi: DT: STiH407: Enable Mailbox testing facility
In-Reply-To: <1439994175-13360-1-git-send-email-lee.jones@linaro.org>
References: <1439994175-13360-1-git-send-email-lee.jones@linaro.org>
Message-ID: <1439994175-13360-6-git-send-email-lee.jones@linaro.org>

This patch supplies a Client node to enable the Mailbox testing
facility.  It will be used to send and receive messages from any
given co-processor in order to test the STi Mailbox Controller
driver.

Signed-off-by: Lee Jones <lee.jones at linaro.org>
---
 arch/arm/boot/dts/stih407-family.dtsi | 6 ++++++
 1 file changed, 6 insertions(+)

diff --git a/arch/arm/boot/dts/stih407-family.dtsi b/arch/arm/boot/dts/stih407-family.dtsi
index 32da3f8..ac1d1ee 100644
--- a/arch/arm/boot/dts/stih407-family.dtsi
+++ b/arch/arm/boot/dts/stih407-family.dtsi
@@ -566,6 +566,12 @@
 			};
 		};
 
+		mailbox_test {
+			compatible = "mailbox_test";
+			mboxes = <&mailbox2 1 31>, <&mailbox0 1 31>;
+			mbox-names = "tx", "rx";
+		};
+
 		mailbox0: mailbox at 0  {
 			compatible	= "st,stih407-mailbox";
 			reg		= <0x8f00000 0x1000>;
-- 
1.9.1



From hramrach at gmail.com  Wed Aug 19 07:35:36 2015
From: hramrach at gmail.com (Michal Suchanek)
Date: Wed, 19 Aug 2015 16:35:36 +0200
Subject: un4i-ss-cipher.c warning
Message-ID: <CAOMqctShdb9xEkBmuaQKfB1cwGupbfH5TS5ZB_P85Hwpn+4zAA@mail.gmail.com>

Hello,

when building a kernel with sunxi crypto driver as merged into the
sinxi-wip branch I get a compiler warning.

I am not sure this is the latest version of the driver. It does not
seem to be in mainline yet.

Thanks

Michal

In file included from /scratch/build/linux/include/linux/printk.h:277:0,
                 from /scratch/build/linux/include/linux/kernel.h:13,
                 from /scratch/build/linux/include/linux/clk.h:16,
                 from
/scratch/build/linux/drivers/crypto/sunxi-ss/sun4i-ss.h:15,
                 from
/scratch/build/linux/drivers/crypto/sunxi-ss/sun4i-ss-cipher.c:17:
/scratch/build/linux/drivers/crypto/sunxi-ss/sun4i-ss-cipher.c: In
function ?sun4i_ss_cipher_poll?:
/scratch/build/linux/include/linux/dynamic_debug.h:86:3: warning:
?todo? may be used uninitialized in this function
[-Wmaybe-uninitialized]
   __dynamic_dev_dbg(&descriptor, dev, fmt, \
   ^
/scratch/build/linux/drivers/crypto/sunxi-ss/sun4i-ss-cipher.c:144:15:
note: ?todo? was declared here
  unsigned int todo;


From ykk at rock-chips.com  Wed Aug 19 07:48:48 2015
From: ykk at rock-chips.com (Yakir Yang)
Date: Wed, 19 Aug 2015 09:48:48 -0500
Subject: [PATCH v3 0/14] Add Analogix Core Display Port Driver
Message-ID: <1439995728-18046-1-git-send-email-ykk@rock-chips.com>


Hi all,
   The Samsung Exynos eDP controller and Rockchip RK3288 eDP controller
share the same IP, so a lot of parts can be re-used. I split the common
code into bridge directory, then rk3288 and exynos only need to keep
some platform code. Cause I can't find the exact IP name of exynos dp
controller, so I decide to name dp core driver with "analogix" which I
find in rk3288 eDP TRM ;)

Beyond that, there are three light registers setting differents bewteen
exynos and rk3288.
1. RK3288 have five special pll resigters which not indicata in exynos
   dp controller.
2. The address of DP_PHY_PD(dp phy power manager register) are different
   between rk3288 and exynos.
3. Rk3288 and exynos have different setting with AUX_HW_RETRY_CTL(dp debug
   register).

I have verified this series on two kinds of rockchip platform board, one
is rk3288 sdk board which connect with a 2K display port monitor, the other
is google jerry chromebook which connect with a eDP screen "cnm,n116bgeea2",
both of them works rightlly.

I haven't verified the dp function on samsung platform, cause I haven't got
exynos boards. I can only ensure that there are no build error on samsung
platform, wish some samsung guys help to test. ;)

Thanks,
- Yakir

Changes in v3:
- Take Thierry Reding suggest, move exynos's video_timing code
  to analogix_dp-exynos platform driver, add get_modes method
  to struct analogix_dp_plat_data.
- Take Heiko suggest, rename some "samsung*" dts propery to "analogix*".
- Take Thierry Reding suggest, dynamic parse video timing info from
  struct drm_display_mode and struct drm_display_info.
- Take Thierry Reding suggest, link_rate and lane_count shouldn't config to
  the DT property value directly, but we can take those as hardware limite.
  For example, RK3288 only support 4 physical lanes of 2.7/1.62 Gbps/lane,
  so DT property would like "link-rate = 0x0a" "lane-count = 4".
- Take Heiko suggest, add devicetree binding documents.
- Take Thierry Reding suggest, remove sync pol & colorimetry properies
  from the new analogix dp driver devicetree binding.
- Update the exist exynos dtsi file with the latest DP DT properies.
- Take Thierry Reding and Heiko suggest, leave "sclk_edp_24m" to rockchip
  dp phy driver which name to "24m", and leave "sclk_edp" to analogix dp
  core driver which name to "dp", and leave "pclk_edp" to rockchip dp platform
  driver which name to "pclk".
- Take Heiko suggest, add devicetree binding document.
- Take Heiko suggest, remove "rockchip,panel" DT property, take use of remote
  point to get panel node.
- Add the new function point analogix_dp_platdata.get_modes init.
- Take Heiko suggest, add rockchip dp phy driver,
  collect the phy clocks and power control.
- Add "analogix,need-force-hpd" to indicate whether driver need foce
  hpd when hpd detect failed.
- move dp hpd detect to connector detect function.
- Add edid modes parse support

Changes in v2:
- Take Joe Preches advise, improved commit message more readable, and
  avoid using some uncommon style like bellow:
  -  retval = exynos_dp_read_bytes_from_i2c(...
				...)
  +  retval =
  +  exynos_dp_read_bytes_from_i2c(......);
- Take Jingoo Han suggest, just remove my name from author list.
- Take Jingoo Han suggest, remove new copyright
- Fix compiled failed dut to analogix_dp_device misspell
- Take Heiko suggest, get panel node with remote-endpoint method,
  and create devicetree binding for driver.
- Remove the clock enable/disbale with "sclk_edp" & "sclk_edp_24m",
  leave those clock to rockchip dp phy driver.
- Add GNU license v2 declared and samsung copyright
- Fix compile failed dut to phy_pd_addr variable misspell error

Yakir Yang (14):
  drm: exynos/dp: fix code style
  drm: exynos/dp: convert to drm bridge mode
  drm: bridge: analogix_dp: split exynos dp driver to bridge dir
  drm: bridge/analogix_dp: dynamic parse sync_pol & interlace &
    colorimetry
  drm: bridge/analogix_dp: fix link_rate & lane_count bug
  Documentation: drm/bridge: add document for analogix_dp
  drm: rockchip/dp: add rockchip platform dp driver
  phy: Add driver for rockchip Display Port PHY
  drm: bridge/analogix_dp: add platform device type support
  drm: bridge: analogix_dp: add some rk3288 special registers setting
  drm: bridge: analogix_dp: try force hpd after plug in lookup failed
  drm: bridge/analogix_dp: expand the delay time for hpd detect
  drm: bridge/analogix_dp: move hpd detect to connector detect function
  drm: bridge/analogix_dp: add edid modes parse in get_modes method

 .../devicetree/bindings/drm/bridge/analogix_dp.txt |   73 +
 .../devicetree/bindings/phy/rockchip-dp-phy.txt    |   26 +
 .../bindings/video/analogix_dp-rockchip.txt        |   83 ++
 .../devicetree/bindings/video/exynos_dp.txt        |   51 +-
 arch/arm/boot/dts/exynos5250-arndale.dts           |   10 +-
 arch/arm/boot/dts/exynos5250-smdk5250.dts          |   10 +-
 arch/arm/boot/dts/exynos5250-snow.dts              |   12 +-
 arch/arm/boot/dts/exynos5250-spring.dts            |   12 +-
 arch/arm/boot/dts/exynos5420-peach-pit.dts         |   12 +-
 arch/arm/boot/dts/exynos5420-smdk5420.dts          |   10 +-
 arch/arm/boot/dts/exynos5800-peach-pi.dts          |   12 +-
 drivers/gpu/drm/bridge/Kconfig                     |    5 +
 drivers/gpu/drm/bridge/Makefile                    |    1 +
 drivers/gpu/drm/bridge/analogix_dp_core.c          | 1382 +++++++++++++++++++
 drivers/gpu/drm/bridge/analogix_dp_core.h          |  286 ++++
 drivers/gpu/drm/bridge/analogix_dp_reg.c           | 1294 ++++++++++++++++++
 .../exynos_dp_reg.h => bridge/analogix_dp_reg.h}   |  270 ++--
 drivers/gpu/drm/exynos/Kconfig                     |    5 +-
 drivers/gpu/drm/exynos/Makefile                    |    2 +-
 drivers/gpu/drm/exynos/analogix_dp-exynos.c        |  347 +++++
 drivers/gpu/drm/exynos/exynos_dp_core.c            | 1416 --------------------
 drivers/gpu/drm/exynos/exynos_dp_core.h            |  282 ----
 drivers/gpu/drm/exynos/exynos_dp_reg.c             | 1263 -----------------
 drivers/gpu/drm/rockchip/Kconfig                   |    9 +
 drivers/gpu/drm/rockchip/Makefile                  |    1 +
 drivers/gpu/drm/rockchip/analogix_dp-rockchip.c    |  390 ++++++
 drivers/phy/Kconfig                                |    7 +
 drivers/phy/Makefile                               |    1 +
 drivers/phy/phy-rockchip-dp.c                      |  185 +++
 include/drm/bridge/analogix_dp.h                   |   40 +
 30 files changed, 4325 insertions(+), 3172 deletions(-)
 create mode 100644 Documentation/devicetree/bindings/drm/bridge/analogix_dp.txt
 create mode 100644 Documentation/devicetree/bindings/phy/rockchip-dp-phy.txt
 create mode 100644 Documentation/devicetree/bindings/video/analogix_dp-rockchip.txt
 create mode 100644 drivers/gpu/drm/bridge/analogix_dp_core.c
 create mode 100644 drivers/gpu/drm/bridge/analogix_dp_core.h
 create mode 100644 drivers/gpu/drm/bridge/analogix_dp_reg.c
 rename drivers/gpu/drm/{exynos/exynos_dp_reg.h => bridge/analogix_dp_reg.h} (62%)
 create mode 100644 drivers/gpu/drm/exynos/analogix_dp-exynos.c
 delete mode 100644 drivers/gpu/drm/exynos/exynos_dp_core.c
 delete mode 100644 drivers/gpu/drm/exynos/exynos_dp_core.h
 delete mode 100644 drivers/gpu/drm/exynos/exynos_dp_reg.c
 create mode 100644 drivers/gpu/drm/rockchip/analogix_dp-rockchip.c
 create mode 100644 drivers/phy/phy-rockchip-dp.c
 create mode 100644 include/drm/bridge/analogix_dp.h

-- 
1.9.1




From ykk at rock-chips.com  Wed Aug 19 07:49:19 2015
From: ykk at rock-chips.com (Yakir Yang)
Date: Wed, 19 Aug 2015 09:49:19 -0500
Subject: [PATCH v3 01/14] drm: exynos/dp: fix code style
In-Reply-To: <1439995728-18046-1-git-send-email-ykk@rock-chips.com>
References: <1439995728-18046-1-git-send-email-ykk@rock-chips.com>
Message-ID: <1439995760-18102-1-git-send-email-ykk@rock-chips.com>

After run "checkpatch.pl -f --subjective" command, I see there
are lots of alignment problem in exynos_dp driver, so let just
fix them.

Signed-off-by: Yakir Yang <ykk at rock-chips.com>
---
Changes in v3: None
Changes in v2:
- Take Joe Preches advise, improved commit message more readable, and
  avoid using some uncommon style like bellow:
  -  retval = exynos_dp_read_bytes_from_i2c(...
				...)
  +  retval =
  +  exynos_dp_read_bytes_from_i2c(......);

 drivers/gpu/drm/exynos/exynos_dp_core.c | 219 ++++++++++++++++----------------
 drivers/gpu/drm/exynos/exynos_dp_core.h |  53 ++++----
 drivers/gpu/drm/exynos/exynos_dp_reg.c  | 100 +++++++--------
 3 files changed, 182 insertions(+), 190 deletions(-)

diff --git a/drivers/gpu/drm/exynos/exynos_dp_core.c b/drivers/gpu/drm/exynos/exynos_dp_core.c
index 172b800..562f4a8 100644
--- a/drivers/gpu/drm/exynos/exynos_dp_core.c
+++ b/drivers/gpu/drm/exynos/exynos_dp_core.c
@@ -114,8 +114,8 @@ static int exynos_dp_read_edid(struct exynos_dp_device *dp)
 
 	/* Read Extension Flag, Number of 128-byte EDID extension blocks */
 	retval = exynos_dp_read_byte_from_i2c(dp, I2C_EDID_DEVICE_ADDR,
-				EDID_EXTENSION_FLAG,
-				&extend_block);
+					      EDID_EXTENSION_FLAG,
+					      &extend_block);
 	if (retval)
 		return retval;
 
@@ -123,10 +123,11 @@ static int exynos_dp_read_edid(struct exynos_dp_device *dp)
 		dev_dbg(dp->dev, "EDID data includes a single extension!\n");
 
 		/* Read EDID data */
-		retval = exynos_dp_read_bytes_from_i2c(dp, I2C_EDID_DEVICE_ADDR,
-						EDID_HEADER_PATTERN,
-						EDID_BLOCK_LENGTH,
-						&edid[EDID_HEADER_PATTERN]);
+		retval = exynos_dp_read_bytes_from_i2c(
+					dp, I2C_EDID_DEVICE_ADDR,
+					EDID_HEADER_PATTERN,
+					EDID_BLOCK_LENGTH,
+					&edid[EDID_HEADER_PATTERN]);
 		if (retval != 0) {
 			dev_err(dp->dev, "EDID Read failed!\n");
 			return -EIO;
@@ -138,11 +139,11 @@ static int exynos_dp_read_edid(struct exynos_dp_device *dp)
 		}
 
 		/* Read additional EDID data */
-		retval = exynos_dp_read_bytes_from_i2c(dp,
-				I2C_EDID_DEVICE_ADDR,
-				EDID_BLOCK_LENGTH,
-				EDID_BLOCK_LENGTH,
-				&edid[EDID_BLOCK_LENGTH]);
+		retval = exynos_dp_read_bytes_from_i2c(
+					dp, I2C_EDID_DEVICE_ADDR,
+					EDID_BLOCK_LENGTH,
+					EDID_BLOCK_LENGTH,
+					&edid[EDID_BLOCK_LENGTH]);
 		if (retval != 0) {
 			dev_err(dp->dev, "EDID Read failed!\n");
 			return -EIO;
@@ -154,24 +155,22 @@ static int exynos_dp_read_edid(struct exynos_dp_device *dp)
 		}
 
 		exynos_dp_read_byte_from_dpcd(dp, DP_TEST_REQUEST,
-					&test_vector);
+					      &test_vector);
 		if (test_vector & DP_TEST_LINK_EDID_READ) {
-			exynos_dp_write_byte_to_dpcd(dp,
-				DP_TEST_EDID_CHECKSUM,
+			exynos_dp_write_byte_to_dpcd(
+				dp, DP_TEST_EDID_CHECKSUM,
 				edid[EDID_BLOCK_LENGTH + EDID_CHECKSUM]);
-			exynos_dp_write_byte_to_dpcd(dp,
-				DP_TEST_RESPONSE,
+			exynos_dp_write_byte_to_dpcd(
+				dp, DP_TEST_RESPONSE,
 				DP_TEST_EDID_CHECKSUM_WRITE);
 		}
 	} else {
 		dev_info(dp->dev, "EDID data does not include any extensions.\n");
 
 		/* Read EDID data */
-		retval = exynos_dp_read_bytes_from_i2c(dp,
-				I2C_EDID_DEVICE_ADDR,
-				EDID_HEADER_PATTERN,
-				EDID_BLOCK_LENGTH,
-				&edid[EDID_HEADER_PATTERN]);
+		retval = exynos_dp_read_bytes_from_i2c(
+				dp, I2C_EDID_DEVICE_ADDR, EDID_HEADER_PATTERN,
+				EDID_BLOCK_LENGTH, &edid[EDID_HEADER_PATTERN]);
 		if (retval != 0) {
 			dev_err(dp->dev, "EDID Read failed!\n");
 			return -EIO;
@@ -182,16 +181,15 @@ static int exynos_dp_read_edid(struct exynos_dp_device *dp)
 			return -EIO;
 		}
 
-		exynos_dp_read_byte_from_dpcd(dp,
-			DP_TEST_REQUEST,
-			&test_vector);
+		exynos_dp_read_byte_from_dpcd(dp, DP_TEST_REQUEST,
+					      &test_vector);
 		if (test_vector & DP_TEST_LINK_EDID_READ) {
-			exynos_dp_write_byte_to_dpcd(dp,
-				DP_TEST_EDID_CHECKSUM,
-				edid[EDID_CHECKSUM]);
-			exynos_dp_write_byte_to_dpcd(dp,
-				DP_TEST_RESPONSE,
-				DP_TEST_EDID_CHECKSUM_WRITE);
+			exynos_dp_write_byte_to_dpcd(
+					dp, DP_TEST_EDID_CHECKSUM,
+					edid[EDID_CHECKSUM]);
+			exynos_dp_write_byte_to_dpcd(
+					dp, DP_TEST_RESPONSE,
+					DP_TEST_EDID_CHECKSUM_WRITE);
 		}
 	}
 
@@ -206,8 +204,7 @@ static int exynos_dp_handle_edid(struct exynos_dp_device *dp)
 	int retval;
 
 	/* Read DPCD DP_DPCD_REV~RECEIVE_PORT1_CAP_1 */
-	retval = exynos_dp_read_bytes_from_dpcd(dp, DP_DPCD_REV,
-				12, buf);
+	retval = exynos_dp_read_bytes_from_dpcd(dp, DP_DPCD_REV, 12, buf);
 	if (retval)
 		return retval;
 
@@ -222,19 +219,21 @@ static int exynos_dp_handle_edid(struct exynos_dp_device *dp)
 }
 
 static void exynos_dp_enable_rx_to_enhanced_mode(struct exynos_dp_device *dp,
-						bool enable)
+						 bool enable)
 {
 	u8 data;
 
 	exynos_dp_read_byte_from_dpcd(dp, DP_LANE_COUNT_SET, &data);
 
 	if (enable)
-		exynos_dp_write_byte_to_dpcd(dp, DP_LANE_COUNT_SET,
-			DP_LANE_COUNT_ENHANCED_FRAME_EN |
-			DPCD_LANE_COUNT_SET(data));
+		exynos_dp_write_byte_to_dpcd(
+					dp, DP_LANE_COUNT_SET,
+					DP_LANE_COUNT_ENHANCED_FRAME_EN |
+					DPCD_LANE_COUNT_SET(data));
 	else
-		exynos_dp_write_byte_to_dpcd(dp, DP_LANE_COUNT_SET,
-			DPCD_LANE_COUNT_SET(data));
+		exynos_dp_write_byte_to_dpcd(
+					dp, DP_LANE_COUNT_SET,
+					DPCD_LANE_COUNT_SET(data));
 }
 
 static int exynos_dp_is_enhanced_mode_available(struct exynos_dp_device *dp)
@@ -261,13 +260,12 @@ static void exynos_dp_training_pattern_dis(struct exynos_dp_device *dp)
 {
 	exynos_dp_set_training_pattern(dp, DP_NONE);
 
-	exynos_dp_write_byte_to_dpcd(dp,
-		DP_TRAINING_PATTERN_SET,
-		DP_TRAINING_PATTERN_DISABLE);
+	exynos_dp_write_byte_to_dpcd(dp, DP_TRAINING_PATTERN_SET,
+				     DP_TRAINING_PATTERN_DISABLE);
 }
 
 static void exynos_dp_set_lane_lane_pre_emphasis(struct exynos_dp_device *dp,
-					int pre_emphasis, int lane)
+						 int pre_emphasis, int lane)
 {
 	switch (lane) {
 	case 0:
@@ -307,15 +305,14 @@ static int exynos_dp_link_start(struct exynos_dp_device *dp)
 	/* Setup RX configuration */
 	buf[0] = dp->link_train.link_rate;
 	buf[1] = dp->link_train.lane_count;
-	retval = exynos_dp_write_bytes_to_dpcd(dp, DP_LINK_BW_SET,
-				2, buf);
+	retval = exynos_dp_write_bytes_to_dpcd(dp, DP_LINK_BW_SET, 2, buf);
 	if (retval)
 		return retval;
 
 	/* Set TX pre-emphasis to minimum */
 	for (lane = 0; lane < lane_count; lane++)
-		exynos_dp_set_lane_lane_pre_emphasis(dp,
-			PRE_EMPHASIS_LEVEL_0, lane);
+		exynos_dp_set_lane_lane_pre_emphasis(dp, PRE_EMPHASIS_LEVEL_0,
+						     lane);
 
 	/* Wait for PLL lock */
 	pll_tries = 0;
@@ -333,9 +330,9 @@ static int exynos_dp_link_start(struct exynos_dp_device *dp)
 	exynos_dp_set_training_pattern(dp, TRAINING_PTN1);
 
 	/* Set RX training pattern */
-	retval = exynos_dp_write_byte_to_dpcd(dp,
-			DP_TRAINING_PATTERN_SET,
-			DP_LINK_SCRAMBLING_DISABLE | DP_TRAINING_PATTERN_1);
+	retval = exynos_dp_write_byte_to_dpcd(dp, DP_TRAINING_PATTERN_SET,
+					      DP_LINK_SCRAMBLING_DISABLE |
+					      DP_TRAINING_PATTERN_1);
 	if (retval)
 		return retval;
 
@@ -344,7 +341,7 @@ static int exynos_dp_link_start(struct exynos_dp_device *dp)
 			    DP_TRAIN_VOLTAGE_SWING_LEVEL_0;
 
 	retval = exynos_dp_write_bytes_to_dpcd(dp, DP_TRAINING_LANE0_SET,
-			lane_count, buf);
+					       lane_count, buf);
 
 	return retval;
 }
@@ -352,7 +349,7 @@ static int exynos_dp_link_start(struct exynos_dp_device *dp)
 static unsigned char exynos_dp_get_lane_status(u8 link_status[2], int lane)
 {
 	int shift = (lane & 1) * 4;
-	u8 link_value = link_status[lane>>1];
+	u8 link_value = link_status[lane >> 1];
 
 	return (link_value >> shift) & 0xf;
 }
@@ -371,7 +368,7 @@ static int exynos_dp_clock_recovery_ok(u8 link_status[2], int lane_count)
 }
 
 static int exynos_dp_channel_eq_ok(u8 link_status[2], u8 link_align,
-				int lane_count)
+				   int lane_count)
 {
 	int lane;
 	u8 lane_status;
@@ -390,10 +387,10 @@ static int exynos_dp_channel_eq_ok(u8 link_status[2], u8 link_align,
 }
 
 static unsigned char exynos_dp_get_adjust_request_voltage(u8 adjust_request[2],
-							int lane)
+							  int lane)
 {
 	int shift = (lane & 1) * 4;
-	u8 link_value = adjust_request[lane>>1];
+	u8 link_value = adjust_request[lane >> 1];
 
 	return (link_value >> shift) & 0x3;
 }
@@ -403,13 +400,13 @@ static unsigned char exynos_dp_get_adjust_request_pre_emphasis(
 					int lane)
 {
 	int shift = (lane & 1) * 4;
-	u8 link_value = adjust_request[lane>>1];
+	u8 link_value = adjust_request[lane >> 1];
 
 	return ((link_value >> shift) & 0xc) >> 2;
 }
 
 static void exynos_dp_set_lane_link_training(struct exynos_dp_device *dp,
-					u8 training_lane_set, int lane)
+					     u8 training_lane_set, int lane)
 {
 	switch (lane) {
 	case 0:
@@ -465,7 +462,7 @@ static void exynos_dp_reduce_link_rate(struct exynos_dp_device *dp)
 }
 
 static void exynos_dp_get_adjust_training_lane(struct exynos_dp_device *dp,
-					u8 adjust_request[2])
+					       u8 adjust_request[2])
 {
 	int lane, lane_count;
 	u8 voltage_swing, pre_emphasis, training_lane;
@@ -498,13 +495,13 @@ static int exynos_dp_process_clock_recovery(struct exynos_dp_device *dp)
 
 	lane_count = dp->link_train.lane_count;
 
-	retval =  exynos_dp_read_bytes_from_dpcd(dp,
-			DP_LANE0_1_STATUS, 2, link_status);
+	retval = exynos_dp_read_bytes_from_dpcd(dp, DP_LANE0_1_STATUS,
+						2, link_status);
 	if (retval)
 		return retval;
 
-	retval =  exynos_dp_read_bytes_from_dpcd(dp,
-			DP_ADJUST_REQUEST_LANE0_1, 2, adjust_request);
+	retval = exynos_dp_read_bytes_from_dpcd(dp, DP_ADJUST_REQUEST_LANE0_1,
+						2, adjust_request);
 	if (retval)
 		return retval;
 
@@ -512,8 +509,8 @@ static int exynos_dp_process_clock_recovery(struct exynos_dp_device *dp)
 		/* set training pattern 2 for EQ */
 		exynos_dp_set_training_pattern(dp, TRAINING_PTN2);
 
-		retval = exynos_dp_write_byte_to_dpcd(dp,
-				DP_TRAINING_PATTERN_SET,
+		retval = exynos_dp_write_byte_to_dpcd(
+				dp, DP_TRAINING_PATTERN_SET,
 				DP_LINK_SCRAMBLING_DISABLE |
 				DP_TRAINING_PATTERN_2);
 		if (retval)
@@ -551,11 +548,11 @@ static int exynos_dp_process_clock_recovery(struct exynos_dp_device *dp)
 	exynos_dp_get_adjust_training_lane(dp, adjust_request);
 
 	for (lane = 0; lane < lane_count; lane++)
-		exynos_dp_set_lane_link_training(dp,
-			dp->link_train.training_lane[lane], lane);
+		exynos_dp_set_lane_link_training(
+				dp, dp->link_train.training_lane[lane], lane);
 
-	retval = exynos_dp_write_bytes_to_dpcd(dp,
-			DP_TRAINING_LANE0_SET, lane_count,
+	retval = exynos_dp_write_bytes_to_dpcd(
+			dp, DP_TRAINING_LANE0_SET, lane_count,
 			dp->link_train.training_lane);
 	if (retval)
 		return retval;
@@ -573,8 +570,8 @@ static int exynos_dp_process_equalizer_training(struct exynos_dp_device *dp)
 
 	lane_count = dp->link_train.lane_count;
 
-	retval = exynos_dp_read_bytes_from_dpcd(dp,
-			DP_LANE0_1_STATUS, 2, link_status);
+	retval = exynos_dp_read_bytes_from_dpcd(dp, DP_LANE0_1_STATUS,
+						2, link_status);
 	if (retval)
 		return retval;
 
@@ -583,13 +580,13 @@ static int exynos_dp_process_equalizer_training(struct exynos_dp_device *dp)
 		return -EIO;
 	}
 
-	retval = exynos_dp_read_bytes_from_dpcd(dp,
-			DP_ADJUST_REQUEST_LANE0_1, 2, adjust_request);
+	retval = exynos_dp_read_bytes_from_dpcd(dp, DP_ADJUST_REQUEST_LANE0_1,
+						2, adjust_request);
 	if (retval)
 		return retval;
 
-	retval = exynos_dp_read_byte_from_dpcd(dp,
-			DP_LANE_ALIGN_STATUS_UPDATED, &link_align);
+	retval = exynos_dp_read_byte_from_dpcd(
+			dp, DP_LANE_ALIGN_STATUS_UPDATED, &link_align);
 	if (retval)
 		return retval;
 
@@ -628,17 +625,18 @@ static int exynos_dp_process_equalizer_training(struct exynos_dp_device *dp)
 	}
 
 	for (lane = 0; lane < lane_count; lane++)
-		exynos_dp_set_lane_link_training(dp,
-			dp->link_train.training_lane[lane], lane);
+		exynos_dp_set_lane_link_training(
+				dp, dp->link_train.training_lane[lane], lane);
 
 	retval = exynos_dp_write_bytes_to_dpcd(dp, DP_TRAINING_LANE0_SET,
-			lane_count, dp->link_train.training_lane);
+					       lane_count,
+					       dp->link_train.training_lane);
 
 	return retval;
 }
 
 static void exynos_dp_get_max_rx_bandwidth(struct exynos_dp_device *dp,
-					u8 *bandwidth)
+					   u8 *bandwidth)
 {
 	u8 data;
 
@@ -651,7 +649,7 @@ static void exynos_dp_get_max_rx_bandwidth(struct exynos_dp_device *dp,
 }
 
 static void exynos_dp_get_max_rx_lane_count(struct exynos_dp_device *dp,
-					u8 *lane_count)
+					    u8 *lane_count)
 {
 	u8 data;
 
@@ -664,8 +662,8 @@ static void exynos_dp_get_max_rx_lane_count(struct exynos_dp_device *dp,
 }
 
 static void exynos_dp_init_training(struct exynos_dp_device *dp,
-			enum link_lane_count_type max_lane,
-			enum link_rate_type max_rate)
+				    enum link_lane_count_type max_lane,
+				    enum link_rate_type max_rate)
 {
 	/*
 	 * MACRO_RST must be applied after the PLL_LOCK to avoid
@@ -678,7 +676,7 @@ static void exynos_dp_init_training(struct exynos_dp_device *dp,
 	exynos_dp_get_max_rx_lane_count(dp, &dp->link_train.lane_count);
 
 	if ((dp->link_train.link_rate != LINK_RATE_1_62GBPS) &&
-	   (dp->link_train.link_rate != LINK_RATE_2_70GBPS)) {
+	    (dp->link_train.link_rate != LINK_RATE_2_70GBPS)) {
 		dev_err(dp->dev, "Rx Max Link Rate is abnormal :%x !\n",
 			dp->link_train.link_rate);
 		dp->link_train.link_rate = LINK_RATE_1_62GBPS;
@@ -738,8 +736,7 @@ static int exynos_dp_sw_link_training(struct exynos_dp_device *dp)
 }
 
 static int exynos_dp_set_link_train(struct exynos_dp_device *dp,
-				u32 count,
-				u32 bwtype)
+				    u32 count, u32 bwtype)
 {
 	int i;
 	int retval;
@@ -830,21 +827,19 @@ static void exynos_dp_enable_scramble(struct exynos_dp_device *dp, bool enable)
 	if (enable) {
 		exynos_dp_enable_scrambling(dp);
 
-		exynos_dp_read_byte_from_dpcd(dp,
-			DP_TRAINING_PATTERN_SET,
-			&data);
-		exynos_dp_write_byte_to_dpcd(dp,
-			DP_TRAINING_PATTERN_SET,
+		exynos_dp_read_byte_from_dpcd(dp, DP_TRAINING_PATTERN_SET,
+					      &data);
+		exynos_dp_write_byte_to_dpcd(
+			dp, DP_TRAINING_PATTERN_SET,
 			(u8)(data & ~DP_LINK_SCRAMBLING_DISABLE));
 	} else {
 		exynos_dp_disable_scrambling(dp);
 
-		exynos_dp_read_byte_from_dpcd(dp,
-			DP_TRAINING_PATTERN_SET,
-			&data);
-		exynos_dp_write_byte_to_dpcd(dp,
-			DP_TRAINING_PATTERN_SET,
-			(u8)(data | DP_LINK_SCRAMBLING_DISABLE));
+		exynos_dp_read_byte_from_dpcd(dp, DP_TRAINING_PATTERN_SET,
+					      &data);
+		exynos_dp_write_byte_to_dpcd(
+				dp, DP_TRAINING_PATTERN_SET,
+				(u8)(data | DP_LINK_SCRAMBLING_DISABLE));
 	}
 }
 
@@ -915,7 +910,7 @@ static void exynos_dp_commit(struct exynos_drm_display *display)
 	}
 
 	ret = exynos_dp_set_link_train(dp, dp->video_info->lane_count,
-					dp->video_info->link_rate);
+				       dp->video_info->link_rate);
 	if (ret) {
 		dev_err(dp->dev, "unable to do link train\n");
 		return;
@@ -1004,7 +999,7 @@ static struct drm_connector_helper_funcs exynos_dp_connector_helper_funcs = {
 
 /* returns the number of bridges attached */
 static int exynos_drm_attach_lcd_bridge(struct exynos_dp_device *dp,
-		struct drm_encoder *encoder)
+					struct drm_encoder *encoder)
 {
 	int ret;
 
@@ -1020,7 +1015,7 @@ static int exynos_drm_attach_lcd_bridge(struct exynos_dp_device *dp,
 }
 
 static int exynos_dp_create_connector(struct exynos_drm_display *display,
-				struct drm_encoder *encoder)
+				      struct drm_encoder *encoder)
 {
 	struct exynos_dp_device *dp = display_to_dp(display);
 	struct drm_connector *connector = &dp->connector;
@@ -1038,7 +1033,8 @@ static int exynos_dp_create_connector(struct exynos_drm_display *display,
 	connector->polled = DRM_CONNECTOR_POLL_HPD;
 
 	ret = drm_connector_init(dp->drm_dev, connector,
-			&exynos_dp_connector_funcs, DRM_MODE_CONNECTOR_eDP);
+				 &exynos_dp_connector_funcs,
+				 DRM_MODE_CONNECTOR_eDP);
 	if (ret) {
 		DRM_ERROR("Failed to initialize connector with drm\n");
 		return ret;
@@ -1148,8 +1144,8 @@ static struct video_info *exynos_dp_dt_parse_pdata(struct device *dev)
 	struct device_node *dp_node = dev->of_node;
 	struct video_info *dp_video_config;
 
-	dp_video_config = devm_kzalloc(dev,
-				sizeof(*dp_video_config), GFP_KERNEL);
+	dp_video_config = devm_kzalloc(dev, sizeof(*dp_video_config),
+				       GFP_KERNEL);
 	if (!dp_video_config)
 		return ERR_PTR(-ENOMEM);
 
@@ -1163,37 +1159,37 @@ static struct video_info *exynos_dp_dt_parse_pdata(struct device *dev)
 		of_property_read_bool(dp_node, "interlaced");
 
 	if (of_property_read_u32(dp_node, "samsung,color-space",
-				&dp_video_config->color_space)) {
+				 &dp_video_config->color_space)) {
 		dev_err(dev, "failed to get color-space\n");
 		return ERR_PTR(-EINVAL);
 	}
 
 	if (of_property_read_u32(dp_node, "samsung,dynamic-range",
-				&dp_video_config->dynamic_range)) {
+				 &dp_video_config->dynamic_range)) {
 		dev_err(dev, "failed to get dynamic-range\n");
 		return ERR_PTR(-EINVAL);
 	}
 
 	if (of_property_read_u32(dp_node, "samsung,ycbcr-coeff",
-				&dp_video_config->ycbcr_coeff)) {
+				 &dp_video_config->ycbcr_coeff)) {
 		dev_err(dev, "failed to get ycbcr-coeff\n");
 		return ERR_PTR(-EINVAL);
 	}
 
 	if (of_property_read_u32(dp_node, "samsung,color-depth",
-				&dp_video_config->color_depth)) {
+				 &dp_video_config->color_depth)) {
 		dev_err(dev, "failed to get color-depth\n");
 		return ERR_PTR(-EINVAL);
 	}
 
 	if (of_property_read_u32(dp_node, "samsung,link-rate",
-				&dp_video_config->link_rate)) {
+				 &dp_video_config->link_rate)) {
 		dev_err(dev, "failed to get link-rate\n");
 		return ERR_PTR(-EINVAL);
 	}
 
 	if (of_property_read_u32(dp_node, "samsung,lane-count",
-				&dp_video_config->lane_count)) {
+				 &dp_video_config->lane_count)) {
 		dev_err(dev, "failed to get lane-count\n");
 		return ERR_PTR(-EINVAL);
 	}
@@ -1206,7 +1202,7 @@ static int exynos_dp_dt_parse_panel(struct exynos_dp_device *dp)
 	int ret;
 
 	ret = of_get_videomode(dp->dev->of_node, &dp->priv.vm,
-			OF_USE_NATIVE_MODE);
+			       OF_USE_NATIVE_MODE);
 	if (ret) {
 		DRM_ERROR("failed: of_get_videomode() : %d\n", ret);
 		return ret;
@@ -1302,7 +1298,7 @@ static int exynos_dp_bind(struct device *dev, struct device *master, void *data)
 	exynos_dp_init_dp(dp);
 
 	ret = devm_request_irq(&pdev->dev, dp->irq, exynos_dp_irq_handler,
-			irq_flags, "exynos-dp", dp);
+			       irq_flags, "exynos-dp", dp);
 	if (ret) {
 		dev_err(&pdev->dev, "failed to request irq\n");
 		return ret;
@@ -1315,7 +1311,7 @@ static int exynos_dp_bind(struct device *dev, struct device *master, void *data)
 }
 
 static void exynos_dp_unbind(struct device *dev, struct device *master,
-				void *data)
+			     void *data)
 {
 	struct exynos_dp_device *dp = dev_get_drvdata(dev);
 
@@ -1334,7 +1330,7 @@ static int exynos_dp_probe(struct platform_device *pdev)
 	struct exynos_dp_device *dp;
 
 	dp = devm_kzalloc(&pdev->dev, sizeof(struct exynos_dp_device),
-				GFP_KERNEL);
+			  GFP_KERNEL);
 	if (!dp)
 		return -ENOMEM;
 
@@ -1358,8 +1354,9 @@ static int exynos_dp_probe(struct platform_device *pdev)
 			of_node_put(bridge_node);
 			if (!dp->bridge)
 				return -EPROBE_DEFER;
-		} else
+		} else {
 			return -EPROBE_DEFER;
+		}
 	}
 
 	return component_add(&pdev->dev, &exynos_dp_ops);
diff --git a/drivers/gpu/drm/exynos/exynos_dp_core.h b/drivers/gpu/drm/exynos/exynos_dp_core.h
index a4e7996..c321ad5 100644
--- a/drivers/gpu/drm/exynos/exynos_dp_core.h
+++ b/drivers/gpu/drm/exynos/exynos_dp_core.h
@@ -180,8 +180,8 @@ void exynos_dp_config_interrupt(struct exynos_dp_device *dp);
 enum pll_status exynos_dp_get_pll_lock_status(struct exynos_dp_device *dp);
 void exynos_dp_set_pll_power_down(struct exynos_dp_device *dp, bool enable);
 void exynos_dp_set_analog_power_down(struct exynos_dp_device *dp,
-				enum analog_power_block block,
-				bool enable);
+				     enum analog_power_block block,
+				     bool enable);
 void exynos_dp_init_analog_func(struct exynos_dp_device *dp);
 void exynos_dp_init_hpd(struct exynos_dp_device *dp);
 enum dp_irq_type exynos_dp_get_irq_type(struct exynos_dp_device *dp);
@@ -192,50 +192,50 @@ int exynos_dp_get_plug_in_status(struct exynos_dp_device *dp);
 void exynos_dp_enable_sw_function(struct exynos_dp_device *dp);
 int exynos_dp_start_aux_transaction(struct exynos_dp_device *dp);
 int exynos_dp_write_byte_to_dpcd(struct exynos_dp_device *dp,
-				unsigned int reg_addr,
-				unsigned char data);
+				 unsigned int reg_addr,
+				 unsigned char data);
 int exynos_dp_read_byte_from_dpcd(struct exynos_dp_device *dp,
-				unsigned int reg_addr,
-				unsigned char *data);
+				  unsigned int reg_addr,
+				  unsigned char *data);
 int exynos_dp_write_bytes_to_dpcd(struct exynos_dp_device *dp,
-				unsigned int reg_addr,
-				unsigned int count,
-				unsigned char data[]);
+				  unsigned int reg_addr,
+				  unsigned int count,
+				  unsigned char data[]);
 int exynos_dp_read_bytes_from_dpcd(struct exynos_dp_device *dp,
-				unsigned int reg_addr,
-				unsigned int count,
-				unsigned char data[]);
+				   unsigned int reg_addr,
+				   unsigned int count,
+				   unsigned char data[]);
 int exynos_dp_select_i2c_device(struct exynos_dp_device *dp,
 				unsigned int device_addr,
 				unsigned int reg_addr);
 int exynos_dp_read_byte_from_i2c(struct exynos_dp_device *dp,
-				unsigned int device_addr,
-				unsigned int reg_addr,
-				unsigned int *data);
+				 unsigned int device_addr,
+				 unsigned int reg_addr,
+				 unsigned int *data);
 int exynos_dp_read_bytes_from_i2c(struct exynos_dp_device *dp,
-				unsigned int device_addr,
-				unsigned int reg_addr,
-				unsigned int count,
-				unsigned char edid[]);
+				  unsigned int device_addr,
+				  unsigned int reg_addr,
+				  unsigned int count,
+				  unsigned char edid[]);
 void exynos_dp_set_link_bandwidth(struct exynos_dp_device *dp, u32 bwtype);
 void exynos_dp_get_link_bandwidth(struct exynos_dp_device *dp, u32 *bwtype);
 void exynos_dp_set_lane_count(struct exynos_dp_device *dp, u32 count);
 void exynos_dp_get_lane_count(struct exynos_dp_device *dp, u32 *count);
 void exynos_dp_enable_enhanced_mode(struct exynos_dp_device *dp, bool enable);
 void exynos_dp_set_training_pattern(struct exynos_dp_device *dp,
-				 enum pattern_set pattern);
+				    enum pattern_set pattern);
 void exynos_dp_set_lane0_pre_emphasis(struct exynos_dp_device *dp, u32 level);
 void exynos_dp_set_lane1_pre_emphasis(struct exynos_dp_device *dp, u32 level);
 void exynos_dp_set_lane2_pre_emphasis(struct exynos_dp_device *dp, u32 level);
 void exynos_dp_set_lane3_pre_emphasis(struct exynos_dp_device *dp, u32 level);
 void exynos_dp_set_lane0_link_training(struct exynos_dp_device *dp,
-				u32 training_lane);
+				       u32 training_lane);
 void exynos_dp_set_lane1_link_training(struct exynos_dp_device *dp,
-				u32 training_lane);
+				       u32 training_lane);
 void exynos_dp_set_lane2_link_training(struct exynos_dp_device *dp,
-				u32 training_lane);
+				       u32 training_lane);
 void exynos_dp_set_lane3_link_training(struct exynos_dp_device *dp,
-				u32 training_lane);
+				       u32 training_lane);
 u32 exynos_dp_get_lane0_link_training(struct exynos_dp_device *dp);
 u32 exynos_dp_get_lane1_link_training(struct exynos_dp_device *dp);
 u32 exynos_dp_get_lane2_link_training(struct exynos_dp_device *dp);
@@ -246,9 +246,8 @@ void exynos_dp_init_video(struct exynos_dp_device *dp);
 void exynos_dp_set_video_color_format(struct exynos_dp_device *dp);
 int exynos_dp_is_slave_video_stream_clock_on(struct exynos_dp_device *dp);
 void exynos_dp_set_video_cr_mn(struct exynos_dp_device *dp,
-			enum clock_recovery_m_value_type type,
-			u32 m_value,
-			u32 n_value);
+			       enum clock_recovery_m_value_type type,
+			       u32 m_value, u32 n_value);
 void exynos_dp_set_video_timing_mode(struct exynos_dp_device *dp, u32 type);
 void exynos_dp_enable_video_master(struct exynos_dp_device *dp, bool enable);
 void exynos_dp_start_video(struct exynos_dp_device *dp);
diff --git a/drivers/gpu/drm/exynos/exynos_dp_reg.c b/drivers/gpu/drm/exynos/exynos_dp_reg.c
index c1f87a2..9aa483d 100644
--- a/drivers/gpu/drm/exynos/exynos_dp_reg.c
+++ b/drivers/gpu/drm/exynos/exynos_dp_reg.c
@@ -202,8 +202,8 @@ void exynos_dp_set_pll_power_down(struct exynos_dp_device *dp, bool enable)
 }
 
 void exynos_dp_set_analog_power_down(struct exynos_dp_device *dp,
-				enum analog_power_block block,
-				bool enable)
+				     enum analog_power_block block,
+				     bool enable)
 {
 	u32 reg;
 
@@ -399,8 +399,8 @@ void exynos_dp_init_aux(struct exynos_dp_device *dp)
 	exynos_dp_reset_aux(dp);
 
 	/* Disable AUX transaction H/W retry */
-	reg = AUX_BIT_PERIOD_EXPECTED_DELAY(3) | AUX_HW_RETRY_COUNT_SEL(0)|
-		AUX_HW_RETRY_INTERVAL_600_MICROSECONDS;
+	reg = AUX_BIT_PERIOD_EXPECTED_DELAY(3) | AUX_HW_RETRY_COUNT_SEL(0) |
+	      AUX_HW_RETRY_INTERVAL_600_MICROSECONDS;
 	writel(reg, dp->reg_base + EXYNOS_DP_AUX_HW_RETRY_CTL);
 
 	/* Receive AUX Channel DEFER commands equal to DEFFER_COUNT*64 */
@@ -483,8 +483,8 @@ int exynos_dp_start_aux_transaction(struct exynos_dp_device *dp)
 }
 
 int exynos_dp_write_byte_to_dpcd(struct exynos_dp_device *dp,
-				unsigned int reg_addr,
-				unsigned char data)
+				 unsigned int reg_addr,
+				 unsigned char data)
 {
 	u32 reg;
 	int i;
@@ -519,17 +519,16 @@ int exynos_dp_write_byte_to_dpcd(struct exynos_dp_device *dp,
 		retval = exynos_dp_start_aux_transaction(dp);
 		if (retval == 0)
 			break;
-		else
-			dev_dbg(dp->dev, "%s: Aux Transaction fail!\n",
-				__func__);
+
+		dev_dbg(dp->dev, "%s: Aux Transaction fail!\n", __func__);
 	}
 
 	return retval;
 }
 
 int exynos_dp_read_byte_from_dpcd(struct exynos_dp_device *dp,
-				unsigned int reg_addr,
-				unsigned char *data)
+				  unsigned int reg_addr,
+				  unsigned char *data)
 {
 	u32 reg;
 	int i;
@@ -560,9 +559,8 @@ int exynos_dp_read_byte_from_dpcd(struct exynos_dp_device *dp,
 		retval = exynos_dp_start_aux_transaction(dp);
 		if (retval == 0)
 			break;
-		else
-			dev_dbg(dp->dev, "%s: Aux Transaction fail!\n",
-				__func__);
+
+		dev_dbg(dp->dev, "%s: Aux Transaction fail!\n", __func__);
 	}
 
 	/* Read data buffer */
@@ -573,9 +571,9 @@ int exynos_dp_read_byte_from_dpcd(struct exynos_dp_device *dp,
 }
 
 int exynos_dp_write_bytes_to_dpcd(struct exynos_dp_device *dp,
-				unsigned int reg_addr,
-				unsigned int count,
-				unsigned char data[])
+				  unsigned int reg_addr,
+				  unsigned int count,
+				  unsigned char data[])
 {
 	u32 reg;
 	unsigned int start_offset;
@@ -625,9 +623,9 @@ int exynos_dp_write_bytes_to_dpcd(struct exynos_dp_device *dp,
 			retval = exynos_dp_start_aux_transaction(dp);
 			if (retval == 0)
 				break;
-			else
-				dev_dbg(dp->dev, "%s: Aux Transaction fail!\n",
-					__func__);
+
+			dev_dbg(dp->dev, "%s: Aux Transaction fail!\n",
+				__func__);
 		}
 
 		start_offset += cur_data_count;
@@ -637,9 +635,9 @@ int exynos_dp_write_bytes_to_dpcd(struct exynos_dp_device *dp,
 }
 
 int exynos_dp_read_bytes_from_dpcd(struct exynos_dp_device *dp,
-				unsigned int reg_addr,
-				unsigned int count,
-				unsigned char data[])
+				   unsigned int reg_addr,
+				   unsigned int count,
+				   unsigned char data[])
 {
 	u32 reg;
 	unsigned int start_offset;
@@ -683,9 +681,9 @@ int exynos_dp_read_bytes_from_dpcd(struct exynos_dp_device *dp,
 			retval = exynos_dp_start_aux_transaction(dp);
 			if (retval == 0)
 				break;
-			else
-				dev_dbg(dp->dev, "%s: Aux Transaction fail!\n",
-					__func__);
+
+			dev_dbg(dp->dev, "%s: Aux Transaction fail!\n",
+				__func__);
 		}
 
 		for (cur_data_idx = 0; cur_data_idx < cur_data_count;
@@ -736,9 +734,9 @@ int exynos_dp_select_i2c_device(struct exynos_dp_device *dp,
 }
 
 int exynos_dp_read_byte_from_i2c(struct exynos_dp_device *dp,
-				unsigned int device_addr,
-				unsigned int reg_addr,
-				unsigned int *data)
+				 unsigned int device_addr,
+				 unsigned int reg_addr,
+				 unsigned int *data)
 {
 	u32 reg;
 	int i;
@@ -767,9 +765,8 @@ int exynos_dp_read_byte_from_i2c(struct exynos_dp_device *dp,
 		retval = exynos_dp_start_aux_transaction(dp);
 		if (retval == 0)
 			break;
-		else
-			dev_dbg(dp->dev, "%s: Aux Transaction fail!\n",
-				__func__);
+
+		dev_dbg(dp->dev, "%s: Aux Transaction fail!\n", __func__);
 	}
 
 	/* Read data */
@@ -780,10 +777,10 @@ int exynos_dp_read_byte_from_i2c(struct exynos_dp_device *dp,
 }
 
 int exynos_dp_read_bytes_from_i2c(struct exynos_dp_device *dp,
-				unsigned int device_addr,
-				unsigned int reg_addr,
-				unsigned int count,
-				unsigned char edid[])
+				  unsigned int device_addr,
+				  unsigned int reg_addr,
+				  unsigned int count,
+				  unsigned char edid[])
 {
 	u32 reg;
 	unsigned int i, j;
@@ -807,8 +804,8 @@ int exynos_dp_read_bytes_from_i2c(struct exynos_dp_device *dp,
 			 * request without sending address
 			 */
 			if (!defer)
-				retval = exynos_dp_select_i2c_device(dp,
-						device_addr, reg_addr + i);
+				retval = exynos_dp_select_i2c_device(
+						dp, device_addr, reg_addr + i);
 			else
 				defer = 0;
 
@@ -828,15 +825,14 @@ int exynos_dp_read_bytes_from_i2c(struct exynos_dp_device *dp,
 				retval = exynos_dp_start_aux_transaction(dp);
 				if (retval == 0)
 					break;
-				else
-					dev_dbg(dp->dev,
-						"%s: Aux Transaction fail!\n",
-						__func__);
+
+				dev_dbg(dp->dev, "%s: Aux Transaction fail!\n",
+					__func__);
 			}
 			/* Check if Rx sends defer */
 			reg = readl(dp->reg_base + EXYNOS_DP_AUX_RX_COMM);
 			if (reg == AUX_RX_COMM_AUX_DEFER ||
-				reg == AUX_RX_COMM_I2C_DEFER) {
+			    reg == AUX_RX_COMM_I2C_DEFER) {
 				dev_err(dp->dev, "Defer: %d\n\n", reg);
 				defer = 1;
 			}
@@ -901,7 +897,7 @@ void exynos_dp_enable_enhanced_mode(struct exynos_dp_device *dp, bool enable)
 }
 
 void exynos_dp_set_training_pattern(struct exynos_dp_device *dp,
-				 enum pattern_set pattern)
+				    enum pattern_set pattern)
 {
 	u32 reg;
 
@@ -974,7 +970,7 @@ void exynos_dp_set_lane3_pre_emphasis(struct exynos_dp_device *dp, u32 level)
 }
 
 void exynos_dp_set_lane0_link_training(struct exynos_dp_device *dp,
-					u32 training_lane)
+				       u32 training_lane)
 {
 	u32 reg;
 
@@ -983,7 +979,7 @@ void exynos_dp_set_lane0_link_training(struct exynos_dp_device *dp,
 }
 
 void exynos_dp_set_lane1_link_training(struct exynos_dp_device *dp,
-					u32 training_lane)
+				       u32 training_lane)
 {
 	u32 reg;
 
@@ -992,7 +988,7 @@ void exynos_dp_set_lane1_link_training(struct exynos_dp_device *dp,
 }
 
 void exynos_dp_set_lane2_link_training(struct exynos_dp_device *dp,
-					u32 training_lane)
+				       u32 training_lane)
 {
 	u32 reg;
 
@@ -1001,7 +997,7 @@ void exynos_dp_set_lane2_link_training(struct exynos_dp_device *dp,
 }
 
 void exynos_dp_set_lane3_link_training(struct exynos_dp_device *dp,
-					u32 training_lane)
+				       u32 training_lane)
 {
 	u32 reg;
 
@@ -1125,9 +1121,9 @@ int exynos_dp_is_slave_video_stream_clock_on(struct exynos_dp_device *dp)
 }
 
 void exynos_dp_set_video_cr_mn(struct exynos_dp_device *dp,
-		enum clock_recovery_m_value_type type,
-		u32 m_value,
-		u32 n_value)
+			       enum clock_recovery_m_value_type type,
+			       u32 m_value,
+			       u32 n_value)
 {
 	u32 reg;
 
@@ -1221,7 +1217,7 @@ void exynos_dp_config_video_slave_mode(struct exynos_dp_device *dp)
 	u32 reg;
 
 	reg = readl(dp->reg_base + EXYNOS_DP_FUNC_EN_1);
-	reg &= ~(MASTER_VID_FUNC_EN_N|SLAVE_VID_FUNC_EN_N);
+	reg &= ~(MASTER_VID_FUNC_EN_N | SLAVE_VID_FUNC_EN_N);
 	reg |= MASTER_VID_FUNC_EN_N;
 	writel(reg, dp->reg_base + EXYNOS_DP_FUNC_EN_1);
 
-- 
1.9.1




From ykk at rock-chips.com  Wed Aug 19 07:49:50 2015
From: ykk at rock-chips.com (Yakir Yang)
Date: Wed, 19 Aug 2015 09:49:50 -0500
Subject: [PATCH v3 02/14] drm: exynos/dp: convert to drm bridge mode
In-Reply-To: <1439995728-18046-1-git-send-email-ykk@rock-chips.com>
References: <1439995728-18046-1-git-send-email-ykk@rock-chips.com>
Message-ID: <1439995790-18155-1-git-send-email-ykk@rock-chips.com>

In order to move exynos dp code to bridge directory,
we need to convert driver drm bridge mode first. As
dp driver already have a ptn3460 bridge, so we need
to move ptn bridge to the next bridge of dp bridge.

Signed-off-by: Yakir Yang <ykk at rock-chips.com>
---
Changes in v3: None
Changes in v2:
- Take Jingoo Han suggest, just remove my name from author list.

 drivers/gpu/drm/exynos/exynos_dp_core.c | 194 ++++++++++++++++++++------------
 drivers/gpu/drm/exynos/exynos_dp_core.h |   1 +
 2 files changed, 123 insertions(+), 72 deletions(-)

diff --git a/drivers/gpu/drm/exynos/exynos_dp_core.c b/drivers/gpu/drm/exynos/exynos_dp_core.c
index 562f4a8..2b87406 100644
--- a/drivers/gpu/drm/exynos/exynos_dp_core.c
+++ b/drivers/gpu/drm/exynos/exynos_dp_core.c
@@ -997,59 +997,6 @@ static struct drm_connector_helper_funcs exynos_dp_connector_helper_funcs = {
 	.best_encoder = exynos_dp_best_encoder,
 };
 
-/* returns the number of bridges attached */
-static int exynos_drm_attach_lcd_bridge(struct exynos_dp_device *dp,
-					struct drm_encoder *encoder)
-{
-	int ret;
-
-	encoder->bridge = dp->bridge;
-	dp->bridge->encoder = encoder;
-	ret = drm_bridge_attach(encoder->dev, dp->bridge);
-	if (ret) {
-		DRM_ERROR("Failed to attach bridge to drm\n");
-		return ret;
-	}
-
-	return 0;
-}
-
-static int exynos_dp_create_connector(struct exynos_drm_display *display,
-				      struct drm_encoder *encoder)
-{
-	struct exynos_dp_device *dp = display_to_dp(display);
-	struct drm_connector *connector = &dp->connector;
-	int ret;
-
-	dp->encoder = encoder;
-
-	/* Pre-empt DP connector creation if there's a bridge */
-	if (dp->bridge) {
-		ret = exynos_drm_attach_lcd_bridge(dp, encoder);
-		if (!ret)
-			return 0;
-	}
-
-	connector->polled = DRM_CONNECTOR_POLL_HPD;
-
-	ret = drm_connector_init(dp->drm_dev, connector,
-				 &exynos_dp_connector_funcs,
-				 DRM_MODE_CONNECTOR_eDP);
-	if (ret) {
-		DRM_ERROR("Failed to initialize connector with drm\n");
-		return ret;
-	}
-
-	drm_connector_helper_add(connector, &exynos_dp_connector_helper_funcs);
-	drm_connector_register(connector);
-	drm_mode_connector_attach_encoder(connector, encoder);
-
-	if (dp->panel)
-		ret = drm_panel_attach(dp->panel, &dp->connector);
-
-	return ret;
-}
-
 static void exynos_dp_phy_init(struct exynos_dp_device *dp)
 {
 	if (dp->phy)
@@ -1114,23 +1061,126 @@ static void exynos_dp_poweroff(struct exynos_dp_device *dp)
 	}
 }
 
-static void exynos_dp_dpms(struct exynos_drm_display *display, int mode)
+/* returns the number of bridges attached */
+static int exynos_drm_attach_lcd_bridge(struct exynos_dp_device *dp,
+		struct drm_encoder *encoder)
+{
+	int ret;
+
+	dp->bridge->next = dp->ptn_bridge;
+	dp->bridge->encoder = encoder;
+	ret = drm_bridge_attach(encoder->dev, dp->bridge);
+	if (ret) {
+		DRM_ERROR("Failed to attach ptn bridge to drm\n");
+		return ret;
+	}
+
+	return 0;
+}
+
+static int exynos_dp_bridge_attach(struct drm_bridge *bridge)
+{
+
+	struct exynos_dp_device *dp = bridge->driver_private;
+	struct drm_encoder *encoder = dp->encoder;
+	struct drm_connector *connector = &dp->connector;
+	int ret;
+
+	if (!bridge->encoder) {
+		DRM_ERROR("Parent encoder object not found");
+		return -ENODEV;
+	}
+
+	encoder->bridge = bridge;
+
+	/* Pre-empt DP connector creation if there's a bridge */
+	if (dp->ptn_bridge) {
+		ret = exynos_drm_attach_lcd_bridge(dp, encoder);
+		if (ret)
+			return -ENODEV;
+	}
+
+	connector->polled = DRM_CONNECTOR_POLL_HPD;
+
+	ret = drm_connector_init(dp->drm_dev, connector,
+			&exynos_dp_connector_funcs, DRM_MODE_CONNECTOR_eDP);
+	if (ret) {
+		DRM_ERROR("Failed to initialize connector with drm\n");
+		return ret;
+	}
+
+	drm_connector_helper_add(connector, &exynos_dp_connector_helper_funcs);
+	drm_connector_register(connector);
+	drm_mode_connector_attach_encoder(connector, encoder);
+
+	if (dp->panel)
+		ret = drm_panel_attach(dp->panel, &dp->connector);
+
+	return ret;
+}
+
+static void exynos_dp_bridge_nop(struct drm_bridge *bridge)
+{
+	/* do nothing */
+}
+
+static void exynos_dp_bridge_enable(struct drm_bridge *bridge)
+{
+	struct exynos_dp_device *dp = bridge->driver_private;
+
+	exynos_dp_poweron(dp);
+	dp->dpms_mode = DRM_MODE_DPMS_ON;
+}
+
+static void exynos_dp_bridge_disable(struct drm_bridge *bridge)
+{
+	struct exynos_dp_device *dp = bridge->driver_private;
+
+	exynos_dp_poweroff(dp);
+	dp->dpms_mode = DRM_MODE_DPMS_OFF;
+}
+
+static const struct drm_bridge_funcs exynos_dp_bridge_funcs = {
+	.enable = exynos_dp_bridge_enable,
+	.disable = exynos_dp_bridge_disable,
+	.pre_enable = exynos_dp_bridge_nop,
+	.post_disable = exynos_dp_bridge_nop,
+	.attach = exynos_dp_bridge_attach,
+};
+
+static int exynos_dp_create_connector(struct exynos_drm_display *display,
+				struct drm_encoder *encoder)
 {
 	struct exynos_dp_device *dp = display_to_dp(display);
+	struct drm_device *drm_dev = dp->drm_dev;
+	struct drm_bridge *bridge;
+	int ret;
 
-	switch (mode) {
-	case DRM_MODE_DPMS_ON:
-		exynos_dp_poweron(dp);
-		break;
-	case DRM_MODE_DPMS_STANDBY:
-	case DRM_MODE_DPMS_SUSPEND:
-	case DRM_MODE_DPMS_OFF:
-		exynos_dp_poweroff(dp);
-		break;
-	default:
-		break;
+	bridge = devm_kzalloc(drm_dev->dev, sizeof(*bridge), GFP_KERNEL);
+	if (!bridge) {
+		DRM_ERROR("failed to allocate for drm bridge\n");
+		return -ENOMEM;
 	}
-	dp->dpms_mode = mode;
+
+	dp->bridge = bridge;
+	dp->encoder = encoder;
+
+	bridge->driver_private = dp;
+	bridge->encoder = dp->encoder;
+	bridge->funcs = &exynos_dp_bridge_funcs;
+
+	ret = drm_bridge_attach(drm_dev, bridge);
+	if (ret) {
+		DRM_ERROR("failed to attach drm bridge\n");
+		return -EINVAL;
+	}
+
+	return 0;
+}
+
+static void exynos_dp_dpms(struct exynos_drm_display *display, int mode)
+{
+	/* do nothing */
 }
 
 static struct exynos_drm_display_ops exynos_dp_display_ops = {
@@ -1242,7 +1292,7 @@ static int exynos_dp_bind(struct device *dev, struct device *master, void *data)
 		}
 	}
 
-	if (!dp->panel && !dp->bridge) {
+	if (!dp->panel && !dp->ptn_bridge) {
 		ret = exynos_dp_dt_parse_panel(dp);
 		if (ret)
 			return ret;
@@ -1315,7 +1365,7 @@ static void exynos_dp_unbind(struct device *dev, struct device *master,
 {
 	struct exynos_dp_device *dp = dev_get_drvdata(dev);
 
-	exynos_dp_dpms(&dp->display, DRM_MODE_DPMS_OFF);
+	exynos_dp_bridge_disable(dp->bridge);
 }
 
 static const struct component_ops exynos_dp_ops = {
@@ -1350,9 +1400,9 @@ static int exynos_dp_probe(struct platform_device *pdev)
 	if (endpoint) {
 		bridge_node = of_graph_get_remote_port_parent(endpoint);
 		if (bridge_node) {
-			dp->bridge = of_drm_find_bridge(bridge_node);
+			dp->ptn_bridge = of_drm_find_bridge(bridge_node);
 			of_node_put(bridge_node);
-			if (!dp->bridge)
+			if (!dp->ptn_bridge)
 				return -EPROBE_DEFER;
 		} else {
 			return -EPROBE_DEFER;
@@ -1374,7 +1424,7 @@ static int exynos_dp_suspend(struct device *dev)
 {
 	struct exynos_dp_device *dp = dev_get_drvdata(dev);
 
-	exynos_dp_dpms(&dp->display, DRM_MODE_DPMS_OFF);
+	exynos_dp_bridge_disable(dp->bridge);
 	return 0;
 }
 
@@ -1382,7 +1432,7 @@ static int exynos_dp_resume(struct device *dev)
 {
 	struct exynos_dp_device *dp = dev_get_drvdata(dev);
 
-	exynos_dp_dpms(&dp->display, DRM_MODE_DPMS_ON);
+	exynos_dp_bridge_enable(dp->bridge);
 	return 0;
 }
 #endif
diff --git a/drivers/gpu/drm/exynos/exynos_dp_core.h b/drivers/gpu/drm/exynos/exynos_dp_core.h
index c321ad5..29bd56e 100644
--- a/drivers/gpu/drm/exynos/exynos_dp_core.h
+++ b/drivers/gpu/drm/exynos/exynos_dp_core.h
@@ -154,6 +154,7 @@ struct exynos_dp_device {
 	struct drm_encoder	*encoder;
 	struct drm_panel	*panel;
 	struct drm_bridge	*bridge;
+	struct drm_bridge	*ptn_bridge;
 	struct clk		*clock;
 	unsigned int		irq;
 	void __iomem		*reg_base;
-- 
1.9.1




From ykk at rock-chips.com  Wed Aug 19 07:50:24 2015
From: ykk at rock-chips.com (Yakir Yang)
Date: Wed, 19 Aug 2015 09:50:24 -0500
Subject: [PATCH v3 05/14] drm: bridge/analogix_dp: fix link_rate & lane_count
 bug
In-Reply-To: <1439995728-18046-1-git-send-email-ykk@rock-chips.com>
References: <1439995728-18046-1-git-send-email-ykk@rock-chips.com>
Message-ID: <1439995824-18312-1-git-send-email-ykk@rock-chips.com>

link_rate and lane_count already configed in analogix_dp_set_link_train(),
so we don't need to config those repeatly after training finished, just
remove them out.

Beside Display Port 1.2 already support 5.4Gbps link rate, the maximum sets
would change from {1.62Gbps, 2.7Gbps} to {1.62Gbps, 2.7Gbps, 5.4Gbps}.

Signed-off-by: Yakir Yang <ykk at rock-chips.com>
---
Changes in v3:
- Take Thierry Reding suggest, link_rate and lane_count shouldn't config to
  the DT property value directly, but we can take those as hardware limite.
  For example, RK3288 only support 4 physical lanes of 2.7/1.62 Gbps/lane,
  so DT property would like "link-rate = 0x0a" "lane-count = 4".

Changes in v2: None

 drivers/gpu/drm/bridge/analogix_dp_core.c | 16 ++++++++--------
 drivers/gpu/drm/bridge/analogix_dp_core.h |  9 +++++----
 2 files changed, 13 insertions(+), 12 deletions(-)

diff --git a/drivers/gpu/drm/bridge/analogix_dp_core.c b/drivers/gpu/drm/bridge/analogix_dp_core.c
index 480cc13..1778e0a 100644
--- a/drivers/gpu/drm/bridge/analogix_dp_core.c
+++ b/drivers/gpu/drm/bridge/analogix_dp_core.c
@@ -635,6 +635,8 @@ static void analogix_dp_get_max_rx_bandwidth(struct analogix_dp_device *dp,
 	/*
 	 * For DP rev.1.1, Maximum link rate of Main Link lanes
 	 * 0x06 = 1.62 Gbps, 0x0a = 2.7 Gbps
+	 * For DP rev.1.2, Maximum link rate of Main Link lanes
+	 * 0x06 = 1.62 Gbps, 0x0a = 2.7 Gbps, 0x14 = 5.4Gbps
 	 */
 	analogix_dp_read_byte_from_dpcd(dp, DP_MAX_LINK_RATE, &data);
 	*bandwidth = data;
@@ -668,7 +670,8 @@ static void analogix_dp_init_training(struct analogix_dp_device *dp,
 	analogix_dp_get_max_rx_lane_count(dp, &dp->link_train.lane_count);
 
 	if ((dp->link_train.link_rate != LINK_RATE_1_62GBPS) &&
-	    (dp->link_train.link_rate != LINK_RATE_2_70GBPS)) {
+	    (dp->link_train.link_rate != LINK_RATE_2_70GBPS) &&
+	    (dp->link_train.link_rate != LINK_RATE_5_40GBPS)) {
 		dev_err(dp->dev, "Rx Max Link Rate is abnormal :%x !\n",
 			dp->link_train.link_rate);
 		dp->link_train.link_rate = LINK_RATE_1_62GBPS;
@@ -901,8 +904,8 @@ static void analogix_dp_commit(struct analogix_dp_device *dp)
 		return;
 	}
 
-	ret = analogix_dp_set_link_train(dp, dp->video_info->lane_count,
-					 dp->video_info->link_rate);
+	ret = analogix_dp_set_link_train(dp, dp->video_info->max_lane_count,
+					 dp->video_info->max_link_rate);
 	if (ret) {
 		dev_err(dp->dev, "unable to do link train\n");
 		return;
@@ -912,9 +915,6 @@ static void analogix_dp_commit(struct analogix_dp_device *dp)
 	analogix_dp_enable_rx_to_enhanced_mode(dp, 1);
 	analogix_dp_enable_enhanced_mode(dp, 1);
 
-	analogix_dp_set_lane_count(dp, dp->video_info->lane_count);
-	analogix_dp_set_link_bandwidth(dp, dp->video_info->link_rate);
-
 	analogix_dp_init_video(dp);
 	ret = analogix_dp_config_video(dp);
 	if (ret)
@@ -1198,13 +1198,13 @@ static struct video_info *analogix_dp_dt_parse_pdata(struct device *dev)
 	}
 
 	if (of_property_read_u32(dp_node, "analogix,link-rate",
-				 &dp_video_config->link_rate)) {
+				 &dp_video_config->max_link_rate)) {
 		dev_err(dev, "failed to get link-rate\n");
 		return ERR_PTR(-EINVAL);
 	}
 
 	if (of_property_read_u32(dp_node, "analogix,lane-count",
-				 &dp_video_config->lane_count)) {
+				 &dp_video_config->max_lane_count)) {
 		dev_err(dev, "failed to get lane-count\n");
 		return ERR_PTR(-EINVAL);
 	}
diff --git a/drivers/gpu/drm/bridge/analogix_dp_core.h b/drivers/gpu/drm/bridge/analogix_dp_core.h
index 2cefde9..941b34f 100644
--- a/drivers/gpu/drm/bridge/analogix_dp_core.h
+++ b/drivers/gpu/drm/bridge/analogix_dp_core.h
@@ -21,8 +21,9 @@
 #define MAX_EQ_LOOP 5
 
 enum link_rate_type {
-	LINK_RATE_1_62GBPS = 0x06,
-	LINK_RATE_2_70GBPS = 0x0a
+	LINK_RATE_1_62GBPS = DP_LINK_BW_1_62,
+	LINK_RATE_2_70GBPS = DP_LINK_BW_2_7,
+	LINK_RATE_5_40GBPS = DP_LINK_BW_5_4,
 };
 
 enum link_lane_count_type {
@@ -128,8 +129,8 @@ struct video_info {
 	enum color_coefficient ycbcr_coeff;
 	enum color_depth color_depth;
 
-	enum link_rate_type link_rate;
-	enum link_lane_count_type lane_count;
+	enum link_rate_type       max_link_rate;
+	enum link_lane_count_type max_lane_count;
 };
 
 struct link_train {
-- 
1.9.1




From ykk at rock-chips.com  Wed Aug 19 07:50:13 2015
From: ykk at rock-chips.com (Yakir Yang)
Date: Wed, 19 Aug 2015 09:50:13 -0500
Subject: [PATCH v3 04/14] drm: bridge/analogix_dp: dynamic parse sync_pol &
 interlace & colorimetry
In-Reply-To: <1439995728-18046-1-git-send-email-ykk@rock-chips.com>
References: <1439995728-18046-1-git-send-email-ykk@rock-chips.com>
Message-ID: <1439995813-18261-1-git-send-email-ykk@rock-chips.com>

Both hsync/vsync polarity and interlace mode can be parsed from
drm display mode, and dynamic_range and ycbcr_coeff can be judge
by the video code.

But presumably Exynos still relaies on the DT properties, so take
good use of mode_fixup() in to achieve the compatibility hacks.

Signed-off-by: Yakir Yang <ykk at rock-chips.com>
---
Changes in v3:
- Take Thierry Reding suggest, dynamic parse video timing info from
  struct drm_display_mode and struct drm_display_info.

Changes in v2: None

 drivers/gpu/drm/bridge/analogix_dp_core.c   | 50 ++++++++++++----------
 drivers/gpu/drm/exynos/analogix_dp-exynos.c | 65 ++++++++++++++++++++++++++---
 2 files changed, 89 insertions(+), 26 deletions(-)

diff --git a/drivers/gpu/drm/bridge/analogix_dp_core.c b/drivers/gpu/drm/bridge/analogix_dp_core.c
index 6c15e20..480cc13 100644
--- a/drivers/gpu/drm/bridge/analogix_dp_core.c
+++ b/drivers/gpu/drm/bridge/analogix_dp_core.c
@@ -1110,11 +1110,40 @@ static void analogix_dp_bridge_disable(struct drm_bridge *bridge)
 	dp->dpms_mode = DRM_MODE_DPMS_OFF;
 }
 
+static void analogix_dp_bridge_mode_set(struct drm_bridge *bridge,
+					struct drm_display_mode *orig_mode,
+					struct drm_display_mode *mode)
+{
+	struct analogix_dp_device *dp = bridge->driver_private;
+	struct video_info *video_info = dp->video_info;
+	int vic;
+
+	/* interlaces & hsync pol & vsync pol */
+	video_info->interlaced = !!(mode->flags & DRM_MODE_FLAG_INTERLACE);
+	video_info->v_sync_polarity = !!(mode->flags & DRM_MODE_FLAG_NVSYNC);
+	video_info->h_sync_polarity = !!(mode->flags & DRM_MODE_FLAG_NHSYNC);
+
+	/* dynamic_range & colorimetry */
+	vic = drm_match_cea_mode(mode);
+	if ((vic == 6) || (vic == 7) || (vic == 21) || (vic == 22) ||
+	    (vic == 2) || (vic == 3) || (vic == 17) || (vic == 18)) {
+		video_info->dynamic_range = CEA;
+		video_info->ycbcr_coeff = COLOR_YCBCR601;
+	} else if (vic) {
+		video_info->dynamic_range = CEA;
+		video_info->ycbcr_coeff = COLOR_YCBCR709;
+	} else {
+		video_info->dynamic_range = VESA;
+		video_info->ycbcr_coeff = COLOR_YCBCR709;
+	}
+}
+
 static const struct drm_bridge_funcs analogix_dp_bridge_funcs = {
 	.enable = analogix_dp_bridge_enable,
 	.disable = analogix_dp_bridge_disable,
 	.pre_enable = analogix_dp_bridge_nop,
 	.post_disable = analogix_dp_bridge_nop,
+	.mode_set = analogix_dp_bridge_mode_set,
 	.attach = analogix_dp_bridge_attach,
 };
 
@@ -1156,33 +1185,12 @@ static struct video_info *analogix_dp_dt_parse_pdata(struct device *dev)
 	if (!dp_video_config)
 		return ERR_PTR(-ENOMEM);
 
-	dp_video_config->h_sync_polarity =
-		of_property_read_bool(dp_node, "hsync-active-high");
-
-	dp_video_config->v_sync_polarity =
-		of_property_read_bool(dp_node, "vsync-active-high");
-
-	dp_video_config->interlaced =
-		of_property_read_bool(dp_node, "interlaced");
-
 	if (of_property_read_u32(dp_node, "analogix,color-space",
 				 &dp_video_config->color_space)) {
 		dev_err(dev, "failed to get color-space\n");
 		return ERR_PTR(-EINVAL);
 	}
 
-	if (of_property_read_u32(dp_node, "analogix,dynamic-range",
-				 &dp_video_config->dynamic_range)) {
-		dev_err(dev, "failed to get dynamic-range\n");
-		return ERR_PTR(-EINVAL);
-	}
-
-	if (of_property_read_u32(dp_node, "analogix,ycbcr-coeff",
-				 &dp_video_config->ycbcr_coeff)) {
-		dev_err(dev, "failed to get ycbcr-coeff\n");
-		return ERR_PTR(-EINVAL);
-	}
-
 	if (of_property_read_u32(dp_node, "analogix,color-depth",
 				 &dp_video_config->color_depth)) {
 		dev_err(dev, "failed to get color-depth\n");
diff --git a/drivers/gpu/drm/exynos/analogix_dp-exynos.c b/drivers/gpu/drm/exynos/analogix_dp-exynos.c
index d5631c2..17da2c8 100644
--- a/drivers/gpu/drm/exynos/analogix_dp-exynos.c
+++ b/drivers/gpu/drm/exynos/analogix_dp-exynos.c
@@ -26,11 +26,17 @@
 #include <drm/exynos_drm.h>
 #include "exynos_drm_drv.h"
 
-#define plat_data_to_dp(pd) \
-		container_of(pd, struct exynos_dp_device, plat_data)
+#define to_dp(nm)	container_of(nm, struct exynos_dp_device, nm)
+
+struct video_info {
+	bool h_sync_polarity;
+	bool v_sync_polarity;
+	bool interlaced;
+};
 
 struct exynos_dp_device {
 	struct exynos_drm_display  display;
+	struct video_info          video_info;
 	struct drm_bridge          *ptn_bridge;
 	struct drm_device          *drm_dev;
 	struct device              *dev;
@@ -42,7 +48,7 @@ struct exynos_dp_device {
 int exynos_dp_crtc_clock_enable(struct analogix_dp_plat_data *plat_data,
 				bool enable)
 {
-	struct exynos_dp_device *dp = plat_data_to_dp(plat_data);
+	struct exynos_dp_device *dp = to_dp(plat_data);
 	struct drm_encoder *encoder = dp->display.encoder;
 	struct exynos_drm_crtc *crtc;
 
@@ -69,7 +75,7 @@ static int exynos_dp_poweroff(struct analogix_dp_plat_data *plat_data)
 static int exynos_dp_get_modes(struct analogix_dp_plat_data *plat_data,
 			       struct drm_connector *connector)
 {
-	struct exynos_dp_device *dp = plat_data_to_dp(plat_data);
+	struct exynos_dp_device *dp = to_dp(plat_data);
 	struct drm_display_mode *mode;
 
 	if (dp->plat_data.panel)
@@ -97,7 +103,7 @@ static int exynos_dp_get_modes(struct analogix_dp_plat_data *plat_data,
 static int exynos_dp_bridge_attach(struct analogix_dp_plat_data *plat_data,
 				   struct drm_bridge *bridge)
 {
-	struct exynos_dp_device *dp = plat_data_to_dp(plat_data);
+	struct exynos_dp_device *dp = to_dp(plat_data);
 	struct drm_encoder *encoder = dp->display.encoder;
 	int ret;
 
@@ -116,6 +122,34 @@ static int exynos_dp_bridge_attach(struct analogix_dp_plat_data *plat_data,
 	return 0;
 }
 
+static void exynos_dp_mode_fixup(struct exynos_drm_display *display,
+				 struct drm_connector *connector,
+				 const struct drm_display_mode *mode,
+				 struct drm_display_mode *adjusted_mode)
+{
+	struct exynos_dp_device *dp = to_dp(display);
+	int flags = adjusted_mode->flags;
+
+	flags &= ~(DRM_MODE_FLAG_PHSYNC | DRM_MODE_FLAG_NHSYNC |
+		   DRM_MODE_FLAG_PVSYNC | DRM_MODE_FLAG_NVSYNC |
+		   DRM_MODE_FLAG_INTERLACE);
+
+	if (dp->video_info.h_sync_polarity)
+		flags |= DRM_MODE_FLAG_PHSYNC;
+	else
+		flags |= DRM_MODE_FLAG_NHSYNC;
+
+	if (dp->video_info.v_sync_polarity)
+		flags |= DRM_MODE_FLAG_PVSYNC;
+	else
+		flags |= DRM_MODE_FLAG_NVSYNC;
+
+	if (dp->video_info.interlaced)
+		flags |= DRM_MODE_FLAG_INTERLACE;
+
+	adjusted_mode->flags = flags;
+}
+
 static void exynos_dp_dpms(struct exynos_drm_display *display, int mode)
 {
 	/* do nothing */
@@ -137,6 +171,7 @@ static struct exynos_drm_display_ops exynos_dp_display_ops = {
 	.create_connector = exynos_dp_create_connector,
 	.dpms = exynos_dp_dpms,
 	.commit = exynos_dp_commit,
+	.mode_fixup = exynos_dp_mode_fixup,
 };
 
 static int exynos_dp_dt_parse_panel(struct exynos_dp_device *dp)
@@ -153,6 +188,22 @@ static int exynos_dp_dt_parse_panel(struct exynos_dp_device *dp)
 	return 0;
 }
 
+static int exynos_dp_dt_parse_video_info(struct exynos_dp_device *dp)
+{
+	struct device_node *dp_node = dp->dev->of_node;
+
+	dp->video_info.h_sync_polarity =
+		of_property_read_bool(dp_node, "hsync-active-high");
+
+	dp->video_info.v_sync_polarity =
+		of_property_read_bool(dp_node, "vsync-active-high");
+
+	dp->video_info.interlaced =
+		of_property_read_bool(dp_node, "interlaced");
+
+	return 0;
+}
+
 static int exynos_dp_bind(struct device *dev, struct device *master, void *data)
 {
 	struct exynos_dp_device *dp = dev_get_drvdata(dev);
@@ -180,6 +231,10 @@ static int exynos_dp_bind(struct device *dev, struct device *master, void *data)
 			return ret;
 	}
 
+	ret = exynos_dp_dt_parse_video_info(dp);
+	if (ret)
+		return ret;
+
 	ret = exynos_drm_create_enc_conn(dp->drm_dev, &dp->display);
 	if (ret) {
 		DRM_ERROR("exynos dp create enc_conn failed\n");
-- 
1.9.1




From ykk at rock-chips.com  Wed Aug 19 07:50:34 2015
From: ykk at rock-chips.com (Yakir Yang)
Date: Wed, 19 Aug 2015 09:50:34 -0500
Subject: [PATCH v3 06/14] Documentation: drm/bridge: add document for
 analogix_dp
In-Reply-To: <1439995728-18046-1-git-send-email-ykk@rock-chips.com>
References: <1439995728-18046-1-git-send-email-ykk@rock-chips.com>
Message-ID: <1439995834-18363-1-git-send-email-ykk@rock-chips.com>

Analogix dp driver is split from exynos dp driver, so we just
make an copy of exynos_dp.txt, and then simplify exynos_dp.txt

Beside update some exynos dtsi file with the latest change
according to the devicetree binding documents.

Signed-off-by: Yakir Yang <ykk at rock-chips.com>
---
Changes in v3:
- Take Heiko suggest, add devicetree binding documents.
- Take Thierry Reding suggest, remove sync pol & colorimetry properies
  from the new analogix dp driver devicetree binding.
- Update the exist exynos dtsi file with the latest DP DT properies.

Changes in v2: None

 .../devicetree/bindings/drm/bridge/analogix_dp.txt | 70 ++++++++++++++++++++++
 .../devicetree/bindings/video/exynos_dp.txt        | 50 ++++++----------
 arch/arm/boot/dts/exynos5250-arndale.dts           | 10 ++--
 arch/arm/boot/dts/exynos5250-smdk5250.dts          | 10 ++--
 arch/arm/boot/dts/exynos5250-snow.dts              | 12 ++--
 arch/arm/boot/dts/exynos5250-spring.dts            | 12 ++--
 arch/arm/boot/dts/exynos5420-peach-pit.dts         | 12 ++--
 arch/arm/boot/dts/exynos5420-smdk5420.dts          | 10 ++--
 arch/arm/boot/dts/exynos5800-peach-pi.dts          | 12 ++--
 9 files changed, 119 insertions(+), 79 deletions(-)
 create mode 100644 Documentation/devicetree/bindings/drm/bridge/analogix_dp.txt

diff --git a/Documentation/devicetree/bindings/drm/bridge/analogix_dp.txt b/Documentation/devicetree/bindings/drm/bridge/analogix_dp.txt
new file mode 100644
index 0000000..6127018
--- /dev/null
+++ b/Documentation/devicetree/bindings/drm/bridge/analogix_dp.txt
@@ -0,0 +1,70 @@
+Analogix Display Port bridge bindings
+
+Required properties for dp-controller:
+	-compatible:
+		platform specific such as:
+		 * "samsung,exynos5-dp"
+		 * "rockchip,rk3288-dp"
+	-reg:
+		physical base address of the controller and length
+		of memory mapped region.
+	-interrupts:
+		interrupt combiner values.
+	-clocks:
+		from common clock binding: handle to dp clock.
+	-clock-names:
+		from common clock binding: Shall be "dp".
+	-interrupt-parent:
+		phandle to Interrupt combiner node.
+	-phys:
+		from general PHY binding: the phandle for the PHY device.
+	-phy-names:
+		from general PHY binding: Should be "dp".
+	-analogix,color-space:
+		input video data format.
+			COLOR_RGB = 0, COLOR_YCBCR422 = 1, COLOR_YCBCR444 = 2
+	-analogix,color-depth:
+		number of bits per colour component.
+			COLOR_6 = 0, COLOR_8 = 1, COLOR_10 = 2, COLOR_12 = 3
+	-analogix,link-rate:
+		max link rate supported by the eDP controller.
+			LINK_RATE_1_62GBPS = 0x6, LINK_RATE_2_70GBPS = 0x0A,
+			LINK_RATE_5_40GBPS = 0x14
+	-analogix,lane-count:
+		max number of lanes supported by the eDP contoller.
+			LANE_COUNT1 = 1, LANE_COUNT2 = 2, LANE_COUNT4 = 4
+	-port@[X]: SoC specific port nodes with endpoint definitions as defined
+		in Documentation/devicetree/bindings/media/video-interfaces.txt,
+		please refer to the SoC specific binding document:
+		* Documentation/devicetree/bindings/video/exynos_dp.txt
+		* Documentation/devicetree/bindings/video/analogix_dp-rockchip.txt
+
+Optional properties for dp-controller:
+	-analogix,hpd-gpio:
+		Hotplug detect GPIO.
+			Indicates which GPIO should be used for hotplug
+			detection
+	-video interfaces: Device node can contain video interface port
+			    nodes according to [1].
+
+[1]: Documentation/devicetree/bindings/media/video-interfaces.txt
+-------------------------------------------------------------------------------
+
+Example:
+
+	dp-controller {
+		compatible = "samsung,exynos5-dp";
+		reg = <0x145b0000 0x10000>;
+		interrupts = <10 3>;
+		interrupt-parent = <&combiner>;
+		clocks = <&clock 342>;
+		clock-names = "dp";
+
+		phys = <&dp_phy>;
+		phy-names = "dp";
+
+		analogix,color-space = <0>;
+		analogix,color-depth = <1>;
+		analogix,link-rate = <0x0a>;
+		analogix,lane-count = <4>;
+	};
diff --git a/Documentation/devicetree/bindings/video/exynos_dp.txt b/Documentation/devicetree/bindings/video/exynos_dp.txt
index 7a3a9cd..177506f 100644
--- a/Documentation/devicetree/bindings/video/exynos_dp.txt
+++ b/Documentation/devicetree/bindings/video/exynos_dp.txt
@@ -31,28 +31,10 @@ Required properties for dp-controller:
 		from general PHY binding: the phandle for the PHY device.
 	-phy-names:
 		from general PHY binding: Should be "dp".
-	-samsung,color-space:
-		input video data format.
-			COLOR_RGB = 0, COLOR_YCBCR422 = 1, COLOR_YCBCR444 = 2
-	-samsung,dynamic-range:
-		dynamic range for input video data.
-			VESA = 0, CEA = 1
-	-samsung,ycbcr-coeff:
-		YCbCr co-efficients for input video.
-			COLOR_YCBCR601 = 0, COLOR_YCBCR709 = 1
-	-samsung,color-depth:
-		number of bits per colour component.
-			COLOR_6 = 0, COLOR_8 = 1, COLOR_10 = 2, COLOR_12 = 3
-	-samsung,link-rate:
-		link rate supported by the panel.
-			LINK_RATE_1_62GBPS = 0x6, LINK_RATE_2_70GBPS = 0x0A
-	-samsung,lane-count:
-		number of lanes supported by the panel.
-			LANE_COUNT1 = 1, LANE_COUNT2 = 2, LANE_COUNT4 = 4
-	- display-timings: timings for the connected panel as described by
-		Documentation/devicetree/bindings/video/display-timing.txt
 
 Optional properties for dp-controller:
+	- display-timings: timings for the connected panel as described by
+		Documentation/devicetree/bindings/video/display-timing.txt
 	-interlaced:
 		interlace scan mode.
 			Progressive if defined, Interlaced if not defined
@@ -62,14 +44,18 @@ Optional properties for dp-controller:
 	-hsync-active-high:
 		HSYNC polarity configuration.
 			High if defined, Low if not defined
-	-samsung,hpd-gpio:
-		Hotplug detect GPIO.
-			Indicates which GPIO should be used for hotplug
-			detection
-	-video interfaces: Device node can contain video interface port
-			    nodes according to [1].
 
-[1]: Documentation/devicetree/bindings/media/video-interfaces.txt
+For the below properties, please refer to Analogix DP binding document:
+ * Documentation/devicetree/bindings/drm/bridge/analogix_dp.txt
+	-phys (required)
+	-phy-names (required)
+	-analogix,color-space (required)
+	-analogix,color-depth (required)
+	-analogix,link-rate (required)
+	-analogix,lane-count (required)
+	-analogix,hpd-gpio (optional)
+	-video interfaces (optional)
+-------------------------------------------------------------------------------
 
 Example:
 
@@ -88,12 +74,10 @@ SOC specific portion:
 
 Board Specific portion:
 	dp-controller {
-		samsung,color-space = <0>;
-		samsung,dynamic-range = <0>;
-		samsung,ycbcr-coeff = <0>;
-		samsung,color-depth = <1>;
-		samsung,link-rate = <0x0a>;
-		samsung,lane-count = <4>;
+		analogix,color-space = <0>;
+		analogix,color-depth = <1>;
+		analogix,link-rate = <0x0a>;
+		analogix,lane-count = <4>;
 
 		display-timings {
 			native-mode = <&lcd_timing>;
diff --git a/arch/arm/boot/dts/exynos5250-arndale.dts b/arch/arm/boot/dts/exynos5250-arndale.dts
index 7e728a1..e48798d 100644
--- a/arch/arm/boot/dts/exynos5250-arndale.dts
+++ b/arch/arm/boot/dts/exynos5250-arndale.dts
@@ -119,12 +119,10 @@
 
 &dp {
 	status = "okay";
-	samsung,color-space = <0>;
-	samsung,dynamic-range = <0>;
-	samsung,ycbcr-coeff = <0>;
-	samsung,color-depth = <1>;
-	samsung,link-rate = <0x0a>;
-	samsung,lane-count = <4>;
+	analogix,color-space = <0>;
+	analogix,color-depth = <1>;
+	analogix,link-rate = <0x0a>;
+	analogix,lane-count = <4>;
 };
 
 &fimd {
diff --git a/arch/arm/boot/dts/exynos5250-smdk5250.dts b/arch/arm/boot/dts/exynos5250-smdk5250.dts
index 4fe186d..b8c6b8b 100644
--- a/arch/arm/boot/dts/exynos5250-smdk5250.dts
+++ b/arch/arm/boot/dts/exynos5250-smdk5250.dts
@@ -75,12 +75,10 @@
 };
 
 &dp {
-	samsung,color-space = <0>;
-	samsung,dynamic-range = <0>;
-	samsung,ycbcr-coeff = <0>;
-	samsung,color-depth = <1>;
-	samsung,link-rate = <0x0a>;
-	samsung,lane-count = <4>;
+	analogix,color-space = <0>;
+	analogix,color-depth = <1>;
+	analogix,link-rate = <0x0a>;
+	analogix,lane-count = <4>;
 
 	pinctrl-names = "default";
 	pinctrl-0 = <&dp_hpd>;
diff --git a/arch/arm/boot/dts/exynos5250-snow.dts b/arch/arm/boot/dts/exynos5250-snow.dts
index b7f4122..9ce2b89 100644
--- a/arch/arm/boot/dts/exynos5250-snow.dts
+++ b/arch/arm/boot/dts/exynos5250-snow.dts
@@ -239,13 +239,11 @@
 	status = "okay";
 	pinctrl-names = "default";
 	pinctrl-0 = <&dp_hpd>;
-	samsung,color-space = <0>;
-	samsung,dynamic-range = <0>;
-	samsung,ycbcr-coeff = <0>;
-	samsung,color-depth = <1>;
-	samsung,link-rate = <0x0a>;
-	samsung,lane-count = <2>;
-	samsung,hpd-gpio = <&gpx0 7 GPIO_ACTIVE_HIGH>;
+	analogix,color-space = <0>;
+	analogix,color-depth = <1>;
+	analogix,link-rate = <0x0a>;
+	analogix,lane-count = <2>;
+	analogix,hpd-gpio = <&gpx0 7 GPIO_ACTIVE_HIGH>;
 
 	ports {
 		port at 0 {
diff --git a/arch/arm/boot/dts/exynos5250-spring.dts b/arch/arm/boot/dts/exynos5250-spring.dts
index d03f9b8..9288ae6 100644
--- a/arch/arm/boot/dts/exynos5250-spring.dts
+++ b/arch/arm/boot/dts/exynos5250-spring.dts
@@ -69,13 +69,11 @@
 	status = "okay";
 	pinctrl-names = "default";
 	pinctrl-0 = <&dp_hpd_gpio>;
-	samsung,color-space = <0>;
-	samsung,dynamic-range = <0>;
-	samsung,ycbcr-coeff = <0>;
-	samsung,color-depth = <1>;
-	samsung,link-rate = <0x0a>;
-	samsung,lane-count = <1>;
-	samsung,hpd-gpio = <&gpc3 0 GPIO_ACTIVE_HIGH>;
+	analogix,color-space = <0>;
+	analogix,color-depth = <1>;
+	analogix,link-rate = <0x0a>;
+	analogix,lane-count = <1>;
+	analogix,hpd-gpio = <&gpc3 0 GPIO_ACTIVE_HIGH>;
 };
 
 &ehci {
diff --git a/arch/arm/boot/dts/exynos5420-peach-pit.dts b/arch/arm/boot/dts/exynos5420-peach-pit.dts
index 8f4d76c..695a380 100644
--- a/arch/arm/boot/dts/exynos5420-peach-pit.dts
+++ b/arch/arm/boot/dts/exynos5420-peach-pit.dts
@@ -147,13 +147,11 @@
 	status = "okay";
 	pinctrl-names = "default";
 	pinctrl-0 = <&dp_hpd_gpio>;
-	samsung,color-space = <0>;
-	samsung,dynamic-range = <0>;
-	samsung,ycbcr-coeff = <0>;
-	samsung,color-depth = <1>;
-	samsung,link-rate = <0x06>;
-	samsung,lane-count = <2>;
-	samsung,hpd-gpio = <&gpx2 6 0>;
+	analogix,color-space = <0>;
+	analogix,color-depth = <1>;
+	analogix,link-rate = <0x06>;
+	analogix,lane-count = <2>;
+	analogix,hpd-gpio = <&gpx2 6 0>;
 
 	ports {
 		port at 0 {
diff --git a/arch/arm/boot/dts/exynos5420-smdk5420.dts b/arch/arm/boot/dts/exynos5420-smdk5420.dts
index 98871f9..fd46714 100644
--- a/arch/arm/boot/dts/exynos5420-smdk5420.dts
+++ b/arch/arm/boot/dts/exynos5420-smdk5420.dts
@@ -91,12 +91,10 @@
 &dp {
 	pinctrl-names = "default";
 	pinctrl-0 = <&dp_hpd>;
-	samsung,color-space = <0>;
-	samsung,dynamic-range = <0>;
-	samsung,ycbcr-coeff = <0>;
-	samsung,color-depth = <1>;
-	samsung,link-rate = <0x0a>;
-	samsung,lane-count = <4>;
+	analogix,color-space = <0>;
+	analogix,color-depth = <1>;
+	analogix,link-rate = <0x0a>;
+	analogix,lane-count = <4>;
 	status = "okay";
 };
 
diff --git a/arch/arm/boot/dts/exynos5800-peach-pi.dts b/arch/arm/boot/dts/exynos5800-peach-pi.dts
index 7d5b386..54b4c63 100644
--- a/arch/arm/boot/dts/exynos5800-peach-pi.dts
+++ b/arch/arm/boot/dts/exynos5800-peach-pi.dts
@@ -141,13 +141,11 @@
 	status = "okay";
 	pinctrl-names = "default";
 	pinctrl-0 = <&dp_hpd_gpio>;
-	samsung,color-space = <0>;
-	samsung,dynamic-range = <0>;
-	samsung,ycbcr-coeff = <0>;
-	samsung,color-depth = <1>;
-	samsung,link-rate = <0x0a>;
-	samsung,lane-count = <2>;
-	samsung,hpd-gpio = <&gpx2 6 0>;
+	analogix,color-space = <0>;
+	analogix,color-depth = <1>;
+	analogix,link-rate = <0x0a>;
+	analogix,lane-count = <2>;
+	analogix,hpd-gpio = <&gpx2 6 0>;
 	panel = <&panel>;
 };
 
-- 
1.9.1




From s.hauer at pengutronix.de  Wed Aug 19 07:50:35 2015
From: s.hauer at pengutronix.de (Sascha Hauer)
Date: Wed, 19 Aug 2015 16:50:35 +0200
Subject: [PATCH v7 0/9] Fixes and new clocks support for Mediatek MT8173
In-Reply-To: <CAGS+omAj=BZXYXChJwC2Heq+2KVEV2EoRrhiQhtXZRHGaZ9tEw@mail.gmail.com>
References: <1439200228-318-1-git-send-email-jamesjj.liao@mediatek.com>
 <CAGS+omCya_0djzoVGhJchmaTtzo2z+JdnJHDjLipNMsZKV=MLQ@mail.gmail.com>
 <CAGS+omAj=BZXYXChJwC2Heq+2KVEV2EoRrhiQhtXZRHGaZ9tEw@mail.gmail.com>
Message-ID: <20150819145035.GN18700@pengutronix.de>

Hi Dan,

On Fri, Aug 14, 2015 at 12:01:06PM +0800, Daniel Kurtz wrote:
> On Tue, Aug 11, 2015 at 12:43 PM, Daniel Kurtz <djkurtz at chromium.org> wrote:
> > Hi James,
> >
> > On Mon, Aug 10, 2015 at 5:50 PM, James Liao <jamesjj.liao at mediatek.com> wrote:
> >> This patchset is based on 4.2-rc2 and [1], and contains minor fixes and
> >> subsystem clocks support for Mediatek MT8173.
> >>
> >> The previous reviews can be found in [2].
> >>
> >> changes since v6:
> >> - Use DUMMY_RATE (0) instead of typical rate for clocks that we don't care
> >>   and not controlled in CCF.
> >
> > For the whole series:
> > Reviewed-by: Daniel Kurtz <djkurtz at chromium.org>
> 
> Hi Sascha,
> 
> Are you happy with these patches now?

Yes.

Acked-by: Sascha Hauer <s.hauer at pengutronix.de>

Sascha

-- 
Pengutronix e.K.                           |                             |
Industrial Linux Solutions                 | http://www.pengutronix.de/  |
Peiner Str. 6-8, 31137 Hildesheim, Germany | Phone: +49-5121-206917-0    |
Amtsgericht Hildesheim, HRA 2686           | Fax:   +49-5121-206917-5555 |


From ykk at rock-chips.com  Wed Aug 19 07:50:44 2015
From: ykk at rock-chips.com (Yakir Yang)
Date: Wed, 19 Aug 2015 09:50:44 -0500
Subject: [PATCH v3 07/14] drm: rockchip/dp: add rockchip platform dp driver
In-Reply-To: <1439995728-18046-1-git-send-email-ykk@rock-chips.com>
References: <1439995728-18046-1-git-send-email-ykk@rock-chips.com>
Message-ID: <1439995844-18419-1-git-send-email-ykk@rock-chips.com>

Rockchip have three clocks for dp controller, we leave pclk_edp
to analogix_dp driver control, and keep the sclk_edp_24m and
sclk_edp in platform driver.

Signed-off-by: Yakir Yang <ykk at rock-chips.com>
---
Changes in v3:
- Take Thierry Reding and Heiko suggest, leave "sclk_edp_24m" to rockchip
  dp phy driver which name to "24m", and leave "sclk_edp" to analogix dp
  core driver which name to "dp", and leave "pclk_edp" to rockchip dp platform
  driver which name to "pclk".
- Take Heiko suggest, add devicetree binding document.
- Take Heiko suggest, remove "rockchip,panel" DT property, take use of remote
  point to get panel node.
- Add the new function point analogix_dp_platdata.get_modes init.

Changes in v2:
- Take Heiko suggest, get panel node with remote-endpoint method,
  and create devicetree binding for driver.
- Remove the clock enable/disbale with "sclk_edp" & "sclk_edp_24m",
  leave those clock to rockchip dp phy driver.

 .../bindings/video/analogix_dp-rockchip.txt        |  82 +++++
 drivers/gpu/drm/rockchip/Kconfig                   |   9 +
 drivers/gpu/drm/rockchip/Makefile                  |   1 +
 drivers/gpu/drm/rockchip/analogix_dp-rockchip.c    | 389 +++++++++++++++++++++
 4 files changed, 481 insertions(+)
 create mode 100644 Documentation/devicetree/bindings/video/analogix_dp-rockchip.txt
 create mode 100644 drivers/gpu/drm/rockchip/analogix_dp-rockchip.c

diff --git a/Documentation/devicetree/bindings/video/analogix_dp-rockchip.txt b/Documentation/devicetree/bindings/video/analogix_dp-rockchip.txt
new file mode 100644
index 0000000..99fd421
--- /dev/null
+++ b/Documentation/devicetree/bindings/video/analogix_dp-rockchip.txt
@@ -0,0 +1,82 @@
+Rockchip RK3288 specific extensions to the Analogix Display Port
+================================
+
+Required properties:
+- compatible: "rockchip,rk3288-edp";
+
+- reg: physical base address of the controller and length
+- clocks: from common clock binding: handle to dp clock.
+	of memory mapped region.
+- clock-names: from common clock binding:
+	Required elements: "dp" "pclk"
+- resets: Must contain an entry for each entry in reset-names.
+	See ../reset/reset.txt for details.
+- reset-names: Must include the name "dp"
+
+- rockchip,grf: this soc should set GRF regs, so need get grf here.
+
+- ports: contain a port node with endpoint definitions as defined in
+  Documentation/devicetree/bindings/media/video-interfaces.txt.
+
+
+For the below properties, please refer to Analogix DP binding document:
+ * Documentation/devicetree/bindings/drm/bridge/analogix_dp.txt
+- phys (required)
+- phy-names (required)
+- analogix,color-space (required)
+- analogix,color-depth (required)
+- analogix,link-rate (required)
+- analogix,lane-count (required)
+- analogix,hpd-gpio (optional)
+- video interfaces (optional)
+-------------------------------------------------------------------------------
+
+Example:
+	dp-controller: dp at ff970000 {
+		compatible = "rockchip,rk3288-dp";
+		reg = <0xff970000 0x4000>;
+		interrupts = <GIC_SPI 98 IRQ_TYPE_LEVEL_HIGH>;
+		clocks = <&cru SCLK_EDP>, <&cru PCLK_EDP_CTRL>;
+		clock-names = "dp", "pclk";
+		phys = <&dp_phy>;
+		phy-names = "dp";
+
+		rockchip,grf = <&grf>;
+		resets = <&cru 111>;
+		reset-names = "dp";
+
+		hsync-active-high = <0>;
+		vsync-active-high = <0>;
+		interlaced = <0>;
+		analogix,color-space = <0>;
+		analogix,color-depth = <1>;
+		analogix,link-rate = <0x0a>;
+		analogix,lane-count = <4>;
+		status = "disabled";
+
+		ports {
+			edp_in: port {
+				#address-cells = <1>;
+				#size-cells = <0>;
+				edp_in_vopb: endpoint at 0 {
+					reg = <0>;
+					remote-endpoint = <&vopb_out_edp>;
+				};
+				edp_in_vopl: endpoint at 1 {
+					reg = <1>;
+					remote-endpoint = <&vopl_out_edp>;
+				};
+			};
+
+			edp_out: port at 1 {
+				reg = <1>;
+				#address-cells = <1>;
+				#size-cells = <0>;
+				edp_out_panel: endpoint {
+					reg = <0>;
+					remote-endpoint = <&panel_in_edp>
+				};
+			};
+		};
+	};
+
diff --git a/drivers/gpu/drm/rockchip/Kconfig b/drivers/gpu/drm/rockchip/Kconfig
index 35215f6..c2ba945 100644
--- a/drivers/gpu/drm/rockchip/Kconfig
+++ b/drivers/gpu/drm/rockchip/Kconfig
@@ -25,3 +25,12 @@ config ROCKCHIP_DW_HDMI
 	  for the Synopsys DesignWare HDMI driver. If you want to
 	  enable HDMI on RK3288 based SoC, you should selet this
 	  option.
+
+config ROCKCHIP_ANALOGIX_DP
+        tristate "Rockchip specific extensions for Analogix DP driver"
+        depends on DRM_ROCKCHIP
+        select DRM_ANALOGIX_DP
+        help
+	  This selects support for Rockchip SoC specific extensions
+	  for the Analogix Core DP driver. If you want to enable DP
+	  on RK3288 based SoC, you should selet this option.
diff --git a/drivers/gpu/drm/rockchip/Makefile b/drivers/gpu/drm/rockchip/Makefile
index f3d8a19..8ad01fb 100644
--- a/drivers/gpu/drm/rockchip/Makefile
+++ b/drivers/gpu/drm/rockchip/Makefile
@@ -6,5 +6,6 @@ rockchipdrm-y := rockchip_drm_drv.o rockchip_drm_fb.o rockchip_drm_fbdev.o \
 		rockchip_drm_gem.o
 
 obj-$(CONFIG_ROCKCHIP_DW_HDMI) += dw_hdmi-rockchip.o
+obj-$(CONFIG_ROCKCHIP_ANALOGIX_DP) += analogix_dp-rockchip.o
 
 obj-$(CONFIG_DRM_ROCKCHIP) += rockchipdrm.o rockchip_drm_vop.o
diff --git a/drivers/gpu/drm/rockchip/analogix_dp-rockchip.c b/drivers/gpu/drm/rockchip/analogix_dp-rockchip.c
new file mode 100644
index 0000000..cebff9e
--- /dev/null
+++ b/drivers/gpu/drm/rockchip/analogix_dp-rockchip.c
@@ -0,0 +1,389 @@
+/*
+ * Rockchip SoC DP (Display Port) interface driver.
+ *
+ * Copyright (C) Fuzhou Rockchip Electronics Co., Ltd.
+ * Author: Andy Yan <andy.yan at rock-chips.com>
+ *         Yakir Yang <ykk at rock-chips.com>
+ *         Jeff Chen <jeff.chen at 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.
+ */
+#include <drm/drmP.h>
+#include <drm/drm_crtc_helper.h>
+#include <drm/drm_panel.h>
+#include <drm/drm_of.h>
+#include <drm/drm_dp_helper.h>
+
+#include <linux/component.h>
+#include <linux/mfd/syscon.h>
+#include <linux/of_graph.h>
+#include <linux/regmap.h>
+#include <linux/reset.h>
+#include <linux/clk.h>
+
+#include <video/of_videomode.h>
+#include <video/videomode.h>
+
+#include <drm/bridge/analogix_dp.h>
+
+#include "rockchip_drm_drv.h"
+#include "rockchip_drm_vop.h"
+
+#define encoder_to_dp(c) \
+		container_of(c, struct rockchip_dp_device, encoder)
+
+#define plat_data_to_dp(pd) \
+		container_of(pd, struct rockchip_dp_device, plat_data)
+
+/* dp grf register offset */
+#define GRF_GPIO7B_IOMUX                        0x0070
+#define GPIO7B3_SEL_MASK                        (0x03 << 6)
+#define GPIO7B3_SEL_EDP_HOTPLUG                 BIT(7)
+
+#define GRF_SOC_CON6                            0x025c
+#define GRF_EDP_LCD_SEL_MASK                    BIT(5)
+#define GRF_EDP_SEL_VOP_LIT                     BIT(5)
+#define GRF_EDP_SEL_VOP_BIG                     0
+
+struct rockchip_dp_device {
+	struct drm_device        *drm_dev;
+	struct device            *dev;
+	struct drm_encoder       encoder;
+	struct drm_display_mode  mode;
+
+	struct clk               *pclk;
+	struct regmap            *grf;
+	struct reset_control     *rst;
+
+	struct analogix_dp_plat_data plat_data;
+};
+
+static int rockchip_dp_pre_init(struct rockchip_dp_device *dp)
+{
+	u32 val;
+	int ret;
+
+	val = GPIO7B3_SEL_EDP_HOTPLUG | (GPIO7B3_SEL_MASK << 16);
+	ret = regmap_write(dp->grf, GRF_GPIO7B_IOMUX, val);
+	if (ret != 0) {
+		dev_err(dp->dev, "Could not config GRF edp hpd: %d\n", ret);
+		return ret;
+	}
+
+	reset_control_assert(dp->rst);
+	usleep_range(10, 20);
+	reset_control_deassert(dp->rst);
+
+	return 0;
+}
+
+static int rockchip_dp_poweron(struct analogix_dp_plat_data *plat_data)
+{
+	struct rockchip_dp_device *dp = plat_data_to_dp(plat_data);
+	int ret;
+
+	ret = clk_prepare_enable(dp->pclk);
+	if (ret < 0) {
+		dev_err(dp->dev, "failed to enable pclk %d\n", ret);
+		return ret;
+	}
+
+	ret = rockchip_dp_pre_init(dp);
+	if (ret < 0) {
+		dev_err(dp->dev, "failed to dp pre init %d\n", ret);
+		return ret;
+	}
+
+	return 0;
+}
+
+static int rockchip_dp_powerdown(struct analogix_dp_plat_data *plat_data)
+{
+	struct rockchip_dp_device *dp = plat_data_to_dp(plat_data);
+
+	clk_disable_unprepare(dp->pclk);
+
+	return 0;
+}
+
+static bool
+rockchip_dp_drm_encoder_mode_fixup(struct drm_encoder *encoder,
+				   const struct drm_display_mode *mode,
+				   struct drm_display_mode *adjusted_mode)
+{
+	/* do nothing */
+	return true;
+}
+
+static void rockchip_dp_drm_encoder_mode_set(struct drm_encoder *encoder,
+					     struct drm_display_mode *mode,
+					     struct drm_display_mode *adjusted)
+{
+	/* do nothing */
+}
+
+static void rockchip_dp_drm_encoder_prepare(struct drm_encoder *encoder)
+{
+	struct rockchip_dp_device *dp = encoder_to_dp(encoder);
+	u32 val;
+	int ret;
+
+	ret = rockchip_drm_crtc_mode_config(encoder->crtc,
+					    DRM_MODE_CONNECTOR_eDP,
+					    ROCKCHIP_OUT_MODE_AAAA);
+	if (ret < 0) {
+		dev_err(dp->dev, "Could not set crtc mode config: %d.\n", ret);
+		return;
+	}
+
+	ret = rockchip_drm_encoder_get_mux_id(dp->dev->of_node, encoder);
+	if (ret < 0)
+		return;
+
+	if (ret)
+		val = GRF_EDP_SEL_VOP_LIT | (GRF_EDP_LCD_SEL_MASK << 16);
+	else
+		val = GRF_EDP_SEL_VOP_BIG | (GRF_EDP_LCD_SEL_MASK << 16);
+
+	dev_dbg(dp->dev, "vop %s output to dp\n", (ret) ? "LIT" : "BIG");
+
+	ret = regmap_write(dp->grf, GRF_SOC_CON6, val);
+	if (ret != 0) {
+		dev_err(dp->dev, "Could not write to GRF: %d\n", ret);
+		return;
+	}
+}
+
+static void rockchip_dp_drm_encoder_nop(struct drm_encoder *encoder)
+{
+	/* do nothing */
+}
+
+static struct drm_encoder_helper_funcs rockchip_dp_encoder_helper_funcs = {
+	.mode_fixup = rockchip_dp_drm_encoder_mode_fixup,
+	.mode_set = rockchip_dp_drm_encoder_mode_set,
+	.prepare = rockchip_dp_drm_encoder_prepare,
+	.commit = rockchip_dp_drm_encoder_nop,
+	.disable = rockchip_dp_drm_encoder_nop,
+};
+
+static void rockchip_dp_drm_encoder_destroy(struct drm_encoder *encoder)
+{
+	drm_encoder_cleanup(encoder);
+}
+
+static struct drm_encoder_funcs rockchip_dp_encoder_funcs = {
+	.destroy = rockchip_dp_drm_encoder_destroy,
+};
+
+static int rockchip_dp_init(struct rockchip_dp_device *dp)
+{
+	struct device *dev = dp->dev;
+	struct device_node *np = dev->of_node;
+	int ret;
+
+	dp->grf = syscon_regmap_lookup_by_phandle(np, "rockchip,grf");
+	if (IS_ERR(dp->grf)) {
+		dev_err(dev, "failed to get rockchip,grf property\n");
+		return PTR_ERR(dp->grf);
+	}
+
+	dp->pclk = devm_clk_get(dev, "pclk");
+	if (IS_ERR(dp->pclk)) {
+		dev_err(dev, "failed to get pclk property\n");
+		return PTR_ERR(dp->pclk);
+	}
+
+	dp->rst = devm_reset_control_get(dev, "dp");
+	if (IS_ERR(dp->rst)) {
+		dev_err(dev, "failed to get dp reset control\n");
+		return PTR_ERR(dp->rst);
+	}
+
+	ret = clk_prepare_enable(dp->pclk);
+	if (ret < 0) {
+		dev_err(dp->dev, "failed to enable pclk %d\n", ret);
+		return ret;
+	}
+
+	ret = rockchip_dp_pre_init(dp);
+	if (ret < 0) {
+		dev_err(dp->dev, "failed to pre init %d\n", ret);
+		return ret;
+	}
+
+	return 0;
+}
+
+static int rockchip_dp_drm_create_encoder(struct rockchip_dp_device *dp)
+{
+	struct drm_encoder *encoder = &dp->encoder;
+	struct drm_device *drm_dev = dp->drm_dev;
+	struct device *dev = dp->dev;
+	int ret;
+
+	encoder->possible_crtcs = drm_of_find_possible_crtcs(drm_dev,
+							     dev->of_node);
+	DRM_DEBUG_KMS("possible_crtcs = 0x%x\n", encoder->possible_crtcs);
+
+	ret = drm_encoder_init(drm_dev, encoder, &rockchip_dp_encoder_funcs,
+			       DRM_MODE_ENCODER_TMDS);
+	if (ret) {
+		DRM_ERROR("failed to initialize encoder with drm\n");
+		return ret;
+	}
+
+	drm_encoder_helper_add(encoder, &rockchip_dp_encoder_helper_funcs);
+
+	return 0;
+}
+
+static int rockchip_dp_bind(struct device *dev, struct device *master,
+			    void *data)
+{
+	struct rockchip_dp_device *dp = dev_get_drvdata(dev);
+	struct drm_device *drm_dev = data;
+	int ret;
+
+	/*
+	 * Just like the probe function said, we don't need the
+	 * device drvrate anymore, we should leave the charge to
+	 * analogix dp driver, set the device drvdata to NULL.
+	 */
+	dev_set_drvdata(dev, NULL);
+
+	ret = rockchip_dp_init(dp);
+	if (ret < 0)
+		return ret;
+
+	dp->drm_dev = drm_dev;
+
+	ret = rockchip_dp_drm_create_encoder(dp);
+	if (ret) {
+		DRM_ERROR("failed to create drm encoder\n");
+		return ret;
+	}
+
+	dp->plat_data.attach = NULL;
+	dp->plat_data.get_modes = NULL;
+	dp->plat_data.power_on = rockchip_dp_poweron;
+	dp->plat_data.power_off = rockchip_dp_powerdown;
+
+	return analogix_dp_bind(dev, dp->drm_dev, &dp->encoder,
+				&dp->plat_data);
+}
+
+static void rockchip_dp_unbind(struct device *dev, struct device *master,
+			       void *data)
+{
+	return analogix_dp_unbind(dev, master, data);
+}
+
+static const struct component_ops rockchip_dp_component_ops = {
+	.bind = rockchip_dp_bind,
+	.unbind = rockchip_dp_unbind,
+};
+
+static int rockchip_dp_probe(struct platform_device *pdev)
+{
+	struct device *dev = &pdev->dev;
+	struct device_node *panel_node, *port, *endpoint;
+	struct rockchip_dp_device *dp;
+	struct drm_panel *panel;
+
+	port = of_graph_get_port_by_id(dev->of_node, 1);
+	if (!port) {
+		dev_err(dev, "can't find output port\n");
+		return -EINVAL;
+	}
+
+	endpoint = of_get_child_by_name(port, "endpoint");
+	of_node_put(port);
+	if (!endpoint) {
+		dev_err(dev, "no output endpoint found\n");
+		return -EINVAL;
+	}
+
+	panel_node = of_graph_get_remote_port_parent(endpoint);
+	of_node_put(endpoint);
+	if (!panel_node) {
+		dev_err(dev, "no output node found\n");
+		return -EINVAL;
+	}
+
+	panel = of_drm_find_panel(panel_node);
+	if (!panel) {
+		DRM_ERROR("failed to find panel\n");
+		of_node_put(panel_node);
+		return -EPROBE_DEFER;
+	}
+
+	of_node_put(panel_node);
+
+	dp = devm_kzalloc(dev, sizeof(*dp), GFP_KERNEL);
+	if (!dp)
+		return -ENOMEM;
+
+	dp->dev = dev;
+
+	dp->plat_data.panel = panel;
+
+	/*
+	 * We just use the drvdata until driver run into component
+	 * add function, and then we would set drvdata to null, so
+	 * that analogix dp driver could take charge of the drvdata.
+	 */
+	platform_set_drvdata(pdev, dp);
+
+	return component_add(dev, &rockchip_dp_component_ops);
+}
+
+static int rockchip_dp_remove(struct platform_device *pdev)
+{
+	component_del(&pdev->dev, &rockchip_dp_component_ops);
+
+	return 0;
+}
+
+#ifdef CONFIG_PM_SLEEP
+static int rockchip_dp_suspend(struct device *dev)
+{
+	return analogix_dp_suspend(dev);
+}
+
+static int rockchip_dp_resume(struct device *dev)
+{
+	return analogix_dp_resume(dev);
+}
+#endif
+
+static const struct dev_pm_ops rockchip_dp_pm_ops = {
+	SET_SYSTEM_SLEEP_PM_OPS(rockchip_dp_suspend, rockchip_dp_resume)
+};
+
+static const struct of_device_id rockchip_dp_dt_ids[] = {
+	{.compatible = "rockchip,rk3288-dp",},
+	{}
+};
+MODULE_DEVICE_TABLE(of, rockchip_dp_dt_ids);
+
+static struct platform_driver rockchip_dp_driver = {
+	.probe = rockchip_dp_probe,
+	.remove = rockchip_dp_remove,
+	.driver = {
+		   .name = "rockchip-dp",
+		   .owner = THIS_MODULE,
+		   .pm = &rockchip_dp_pm_ops,
+		   .of_match_table = of_match_ptr(rockchip_dp_dt_ids),
+	},
+};
+
+module_platform_driver(rockchip_dp_driver);
+
+MODULE_AUTHOR("Yakir Yang <ykk at rock-chips.com>");
+MODULE_AUTHOR("Jeff chen <jeff.chen at rock-chips.com>");
+MODULE_DESCRIPTION("Rockchip Specific Analogix-DP Driver Extension");
+MODULE_LICENSE("GPL v2");
-- 
1.9.1




From ykk at rock-chips.com  Wed Aug 19 07:51:17 2015
From: ykk at rock-chips.com (Yakir Yang)
Date: Wed, 19 Aug 2015 09:51:17 -0500
Subject: [PATCH v3 08/14] phy: Add driver for rockchip Display Port PHY
In-Reply-To: <1439995728-18046-1-git-send-email-ykk@rock-chips.com>
References: <1439995728-18046-1-git-send-email-ykk@rock-chips.com>
Message-ID: <1439995877-18496-1-git-send-email-ykk@rock-chips.com>

Signed-off-by: Yakir Yang <ykk at rock-chips.com>
---
Changes in v3:
- Take Heiko suggest, add rockchip dp phy driver,
  collect the phy clocks and power control.

Changes in v2: None

 .../devicetree/bindings/phy/rockchip-dp-phy.txt    |  26 +++
 drivers/phy/Kconfig                                |   7 +
 drivers/phy/Makefile                               |   1 +
 drivers/phy/phy-rockchip-dp.c                      | 185 +++++++++++++++++++++
 4 files changed, 219 insertions(+)
 create mode 100644 Documentation/devicetree/bindings/phy/rockchip-dp-phy.txt
 create mode 100644 drivers/phy/phy-rockchip-dp.c

diff --git a/Documentation/devicetree/bindings/phy/rockchip-dp-phy.txt b/Documentation/devicetree/bindings/phy/rockchip-dp-phy.txt
new file mode 100644
index 0000000..5de1088
--- /dev/null
+++ b/Documentation/devicetree/bindings/phy/rockchip-dp-phy.txt
@@ -0,0 +1,26 @@
+Rockchip Soc Seroes Display Port PHY
+------------------------------------
+
+Required properties:
+- compatible : should be one of the following supported values:
+	 - "rockchip.rk3288-dp-phy"
+
+- reg : a list of registers used by phy driver
+- clocks: from common clock binding: handle to dp clock.
+	of memory mapped region.
+- clock-names: from common clock binding:
+	Required elements: "sclk_dp" "sclk_dp_24m"
+
+- rockchip,grf: this soc should set GRF regs, so need get grf here.
+- #phy-cells : from the generic PHY bindings, must be 0;
+
+Example:
+
+edp_phy: phy at ff770274 {
+	compatilble = "rockchip,rk3288-dp-phy";
+	reg = <0xff770274 4>;
+	rockchip,grf = <&grf>;
+	clocks = <&cru SCLK_EDP_24M>;
+	clock-names = "24m";
+	#phy-cells = <0>;
+}
diff --git a/drivers/phy/Kconfig b/drivers/phy/Kconfig
index 6b8dd16..da00440 100644
--- a/drivers/phy/Kconfig
+++ b/drivers/phy/Kconfig
@@ -297,6 +297,13 @@ config PHY_ROCKCHIP_USB
 	help
 	  Enable this to support the Rockchip USB 2.0 PHY.
 
+config PHY_ROCKCHIP_DP
+	tristate "Rockchip Display Port PHY Driver"
+	depends on ARCH_ROCKCHIP && OF
+	select GENERIC_PHY
+	help
+	  Enable this to support the Rockchip Display Port PHY.
+
 config PHY_ST_SPEAR1310_MIPHY
 	tristate "ST SPEAR1310-MIPHY driver"
 	select GENERIC_PHY
diff --git a/drivers/phy/Makefile b/drivers/phy/Makefile
index f344e1b..35e3ce6 100644
--- a/drivers/phy/Makefile
+++ b/drivers/phy/Makefile
@@ -33,6 +33,7 @@ phy-exynos-usb2-$(CONFIG_PHY_S5PV210_USB2)	+= phy-s5pv210-usb2.o
 obj-$(CONFIG_PHY_EXYNOS5_USBDRD)	+= phy-exynos5-usbdrd.o
 obj-$(CONFIG_PHY_QCOM_APQ8064_SATA)	+= phy-qcom-apq8064-sata.o
 obj-$(CONFIG_PHY_ROCKCHIP_USB) += phy-rockchip-usb.o
+obj-$(CONFIG_PHY_ROCKCHIP_DP)		+= phy-rockchip-dp.o
 obj-$(CONFIG_PHY_QCOM_IPQ806X_SATA)	+= phy-qcom-ipq806x-sata.o
 obj-$(CONFIG_PHY_ST_SPEAR1310_MIPHY)	+= phy-spear1310-miphy.o
 obj-$(CONFIG_PHY_ST_SPEAR1340_MIPHY)	+= phy-spear1340-miphy.o
diff --git a/drivers/phy/phy-rockchip-dp.c b/drivers/phy/phy-rockchip-dp.c
new file mode 100644
index 0000000..4759111
--- /dev/null
+++ b/drivers/phy/phy-rockchip-dp.c
@@ -0,0 +1,185 @@
+/*
+ * Rockchip DP PHY driver
+ *
+ * Copyright (C) 2015 FuZhou Rockchip Co., Ltd.
+ * Author: Yakir Yang <ykk@@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.
+ */
+
+#include <linux/io.h>
+#include <linux/kernel.h>
+#include <linux/module.h>
+#include <linux/of.h>
+#include <linux/of_address.h>
+#include <linux/clk.h>
+#include <linux/phy/phy.h>
+#include <linux/regmap.h>
+#include <linux/mfd/syscon.h>
+#include <linux/platform_device.h>
+
+#define GRF_SOC_CON12                   0x0274
+#define GRF_EDP_REF_CLK_SEL_INTER       BIT(4)
+
+#define DP_PHY_SIDDQ_WRITE_EN           BIT(21)
+#define DP_PHY_SIDDQ_ON                 0
+#define DP_PHY_SIDDQ_OFF                BIT(5)
+
+struct rockchip_dp_phy {
+	struct device  *dev;
+	struct regmap  *grf;
+	void __iomem   *regs;
+	struct clk     *phy_24m;
+};
+
+static int rockchip_dp_phy_clk_enable(struct rockchip_dp_phy *dp)
+{
+	int ret = 0;
+
+	ret = clk_set_rate(dp->phy_24m, 24000000);
+	if (ret < 0) {
+		dev_err(dp->dev, "cannot set clock phy_24m %d\n", ret);
+		return ret;
+	}
+
+	ret = clk_prepare_enable(dp->phy_24m);
+	if (ret < 0) {
+		dev_err(dp->dev, "cannot enable clock phy_24m %d\n", ret);
+		return ret;
+	}
+
+	return 0;
+}
+
+static int rockchip_dp_phy_clk_disable(struct rockchip_dp_phy *dp)
+{
+	clk_disable_unprepare(dp->phy_24m);
+
+	return 0;
+}
+
+static int rockchip_set_phy_state(struct phy *phy, bool enable)
+{
+	struct rockchip_dp_phy *dp = phy_get_drvdata(phy);
+
+	if (enable) {
+		rockchip_dp_phy_clk_enable(dp);
+		writel(DP_PHY_SIDDQ_WRITE_EN | DP_PHY_SIDDQ_ON, dp->regs);
+	} else {
+		rockchip_dp_phy_clk_disable(dp);
+		writel(DP_PHY_SIDDQ_WRITE_EN | DP_PHY_SIDDQ_OFF, dp->regs);
+	}
+
+	return 0;
+}
+
+static int rockchip_dp_phy_power_on(struct phy *phy)
+{
+	return rockchip_set_phy_state(phy, true);
+}
+
+static int rockchip_dp_phy_power_off(struct phy *phy)
+{
+	return rockchip_set_phy_state(phy, false);
+}
+
+static struct phy_ops rockchip_dp_phy_ops = {
+	.power_on	= rockchip_dp_phy_power_on,
+	.power_off	= rockchip_dp_phy_power_off,
+	.owner		= THIS_MODULE,
+};
+
+static int rockchip_dp_phy_init(struct rockchip_dp_phy *dp)
+{
+	struct device *dev = dp->dev;
+	struct device_node *np = dev->of_node;
+	int ret;
+
+	dp->phy_24m = devm_clk_get(dev, "24m");
+	if (IS_ERR(dp->phy_24m)) {
+		dev_err(dev, "cannot get clock 24m\n");
+		return PTR_ERR(dp->phy_24m);
+	}
+
+	ret = rockchip_dp_phy_clk_enable(dp);
+	if (ret < 0) {
+		dev_err(dp->dev, "cannot enable dp phy clk %d\n", ret);
+		return ret;
+	}
+
+	dp->grf = syscon_regmap_lookup_by_phandle(np, "rockchip,grf");
+	if (IS_ERR(dp->grf)) {
+		dev_err(dev, "rk3288-dp needs rockchip,grf property\n");
+		return PTR_ERR(dp->grf);
+	}
+
+	ret = regmap_write(dp->grf, GRF_SOC_CON12,
+			   GRF_EDP_REF_CLK_SEL_INTER |
+			   (GRF_EDP_REF_CLK_SEL_INTER << 16));
+	if (ret != 0) {
+		dev_err(dp->dev, "Could not config GRF edp ref clk: %d\n", ret);
+		return ret;
+	}
+
+	return 0;
+}
+
+static int rockchip_dp_phy_probe(struct platform_device *pdev)
+{
+	struct device *dev = &pdev->dev;
+	struct phy_provider *phy_provider;
+	struct rockchip_dp_phy *dp;
+	struct resource *res;
+	struct phy *phy;
+	int ret;
+
+	dp = devm_kzalloc(dev, sizeof(*dp), GFP_KERNEL);
+	if (IS_ERR(dp))
+		return -ENOMEM;
+
+	dp->dev = dev;
+
+	res = platform_get_resource(pdev, IORESOURCE_MEM, 0);
+	dp->regs = devm_ioremap_resource(dev, res);
+	if (IS_ERR(dp->regs))
+		return PTR_ERR(dp->regs);
+
+	ret = rockchip_dp_phy_init(dp);
+	if (ret)
+		return ret;
+
+	phy = devm_phy_create(dev, NULL, &rockchip_dp_phy_ops, NULL);
+	if (IS_ERR(phy)) {
+		dev_err(dev, "failed to create phy\n");
+		return PTR_ERR(phy);
+	}
+	phy_set_drvdata(phy, dp);
+
+	phy_provider = devm_of_phy_provider_register(dev, of_phy_simple_xlate);
+
+	return PTR_ERR_OR_ZERO(phy_provider);
+}
+
+static const struct of_device_id rockchip_dp_phy_dt_ids[] = {
+	{ .compatible = "rockchip,rk3288-dp-phy" },
+	{}
+};
+
+MODULE_DEVICE_TABLE(of, rockchip_dp_phy_dt_ids);
+
+static struct platform_driver rockchip_dp_phy_driver = {
+	.probe		= rockchip_dp_phy_probe,
+	.driver		= {
+		.name	= "rockchip-dp-phy",
+		.owner	= THIS_MODULE,
+		.of_match_table = rockchip_dp_phy_dt_ids,
+	},
+};
+
+module_platform_driver(rockchip_dp_phy_driver);
+
+MODULE_AUTHOR("Yakir Yang <ykk at rock-chips.com>");
+MODULE_DESCRIPTION("Rockchip DP PHY driver");
+MODULE_LICENSE("GPL v2");
-- 
1.9.1




From ykk at rock-chips.com  Wed Aug 19 07:51:28 2015
From: ykk at rock-chips.com (Yakir Yang)
Date: Wed, 19 Aug 2015 09:51:28 -0500
Subject: [PATCH v3 09/14] drm: bridge/analogix_dp: add platform device type
 support
In-Reply-To: <1439995728-18046-1-git-send-email-ykk@rock-chips.com>
References: <1439995728-18046-1-git-send-email-ykk@rock-chips.com>
Message-ID: <1439995888-18548-1-git-send-email-ykk@rock-chips.com>

Signed-off-by: Yakir Yang <ykk at rock-chips.com>
---
Changes in v3: None
Changes in v2:
- Add GNU license v2 declared and samsung copyright

 drivers/gpu/drm/exynos/analogix_dp-exynos.c     |  1 +
 drivers/gpu/drm/rockchip/analogix_dp-rockchip.c |  1 +
 include/drm/bridge/analogix_dp.h                | 16 ++++++++++++++++
 3 files changed, 18 insertions(+)

diff --git a/drivers/gpu/drm/exynos/analogix_dp-exynos.c b/drivers/gpu/drm/exynos/analogix_dp-exynos.c
index 17da2c8..b160159 100644
--- a/drivers/gpu/drm/exynos/analogix_dp-exynos.c
+++ b/drivers/gpu/drm/exynos/analogix_dp-exynos.c
@@ -220,6 +220,7 @@ static int exynos_dp_bind(struct device *dev, struct device *master, void *data)
 	dp->dev = dev;
 	dp->drm_dev = drm_dev;
 
+	dp->plat_data.dev_type = EXYNOS_DP;
 	dp->plat_data.power_on = exynos_dp_poweron;
 	dp->plat_data.power_off = exynos_dp_poweroff;
 	dp->plat_data.get_modes = exynos_dp_get_modes;
diff --git a/drivers/gpu/drm/rockchip/analogix_dp-rockchip.c b/drivers/gpu/drm/rockchip/analogix_dp-rockchip.c
index cebff9e..f2c5c26 100644
--- a/drivers/gpu/drm/rockchip/analogix_dp-rockchip.c
+++ b/drivers/gpu/drm/rockchip/analogix_dp-rockchip.c
@@ -267,6 +267,7 @@ static int rockchip_dp_bind(struct device *dev, struct device *master,
 		return ret;
 	}
 
+	dp->plat_data.dev_type = RK3288_DP;
 	dp->plat_data.attach = NULL;
 	dp->plat_data.get_modes = NULL;
 	dp->plat_data.power_on = rockchip_dp_poweron;
diff --git a/include/drm/bridge/analogix_dp.h b/include/drm/bridge/analogix_dp.h
index 8b4ffad..7209a64 100644
--- a/include/drm/bridge/analogix_dp.h
+++ b/include/drm/bridge/analogix_dp.h
@@ -1,9 +1,25 @@
+/*
+ * Analogix Core DP (Display Port) interface driver.
+ *
+ * Copyright (C) 2012 Samsung Electronics Co., Ltd.
+ *
+ * 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.
+ */
 #ifndef _ANALOGIX_DP_H_
 #define _ANALOGIX_DP_H_
 
 #include <drm/drm_crtc.h>
 
+enum analogix_dp_devtype {
+	EXYNOS_DP,
+	RK3288_DP,
+};
+
 struct analogix_dp_plat_data {
+	enum analogix_dp_devtype dev_type;
 	struct drm_panel *panel;
 
 	int (*power_on)(struct analogix_dp_plat_data *);
-- 
1.9.1




From ryabinin.a.a at gmail.com  Wed Aug 19 07:51:40 2015
From: ryabinin.a.a at gmail.com (Andrey Ryabinin)
Date: Wed, 19 Aug 2015 17:51:40 +0300
Subject: [PATCH v2 5/5] arm64: add KASan support
In-Reply-To: <CACRpkdaJVRuLTCh585rLEjua2TpnLsALhLdu0ma56TBA=C+EiQ@mail.gmail.com>
References: <1431698344-28054-1-git-send-email-a.ryabinin@samsung.com>
 <1431698344-28054-6-git-send-email-a.ryabinin@samsung.com>
 <CACRpkdaRJJjCXR=vK1M2YhR26JZfGoBB+jcqz8r2MhERfxRzqA@mail.gmail.com>
 <CAPAsAGy-r8Z2N09wKV+e0kLfbwxd-eWK6N5Xajsnqq9jfyWqcQ@mail.gmail.com>
 <CACRpkdZmHLMxosLXjyOPdkavo=UNzmTcHOLF5vV4cS1ULfbq6A@mail.gmail.com>
 <CAPAsAGw-iawTpjJh66rQN5fqBFT6UBZCcv2eKx7JTqCXzhzpsw@mail.gmail.com>
 <CACRpkdY2i2M27gP_fXawkFrC_GFgWaKr5rEn6d47refNPiEk=g@mail.gmail.com>
 <55AE56DB.4040607@samsung.com>
 <CACRpkdYaqK8upK-3b01JbO_y+sHnk4-Hm1MfvjSy0tKUkFREtQ@mail.gmail.com>
 <55AFD8D0.9020308@samsung.com>
 <CACRpkdaJVRuLTCh585rLEjua2TpnLsALhLdu0ma56TBA=C+EiQ@mail.gmail.com>
Message-ID: <55D497FC.9060506@gmail.com>

On 08/19/2015 03:14 PM, Linus Walleij wrote:
> On Wed, Jul 22, 2015 at 7:54 PM, Andrey Ryabinin <a.ryabinin at samsung.com> wrote:
> 
>> So here is updated version:
>>         git://github.com/aryabinin/linux.git kasan/arm_v0_1
>>
>> The code is still ugly in some places and it probably have some bugs.
>> Lightly tested on exynos 5410/5420.
> 
> I compiled this for various ARM platforms and tested to boot.
> I used GCC version 4.9.3 20150113 (prerelease) (Linaro).
> 
> I get these compilation warnings no matter what I compile,
> I chose to ignore them:
> 
> WARNING: vmlinux.o(.meminit.text+0x2c):
> Section mismatch in reference from the function kasan_pte_populate()
> to the function
> .init.text:kasan_alloc_block.constprop.7()
> The function __meminit kasan_pte_populate() references
> a function __init kasan_alloc_block.constprop.7().
> If kasan_alloc_block.constprop.7 is only used by kasan_pte_populate then
> annotate kasan_alloc_block.constprop.7 with a matching annotation.
> 
> WARNING: vmlinux.o(.meminit.text+0x98):
> Section mismatch in reference from the function kasan_pmd_populate()
> to the function
> .init.text:kasan_alloc_block.constprop.7()
> The function __meminit kasan_pmd_populate() references
> a function __init kasan_alloc_block.constprop.7().
> If kasan_alloc_block.constprop.7 is only used by kasan_pmd_populate then
> annotate kasan_alloc_block.constprop.7 with a matching annotation.
> 
> These KASan outline tests run fine:
> 
> kasan test: kmalloc_oob_right out-of-bounds to right
> kasan test: kmalloc_oob_left out-of-bounds to left
> kasan test: kmalloc_node_oob_right kmalloc_node(): out-of-bounds to right
> kasan test: kmalloc_large_oob_rigth kmalloc large allocation:
> out-of-bounds to right
> kasan test: kmalloc_oob_krealloc_more out-of-bounds after krealloc more
> kasan test: kmalloc_oob_krealloc_less out-of-bounds after krealloc less
> kasan test: kmalloc_oob_16 kmalloc out-of-bounds for 16-bytes access
> kasan test: kmalloc_oob_in_memset out-of-bounds in memset
> kasan test: kmalloc_uaf use-after-free
> kasan test: kmalloc_uaf_memset use-after-free in memset
> kasan test: kmalloc_uaf2 use-after-free after another kmalloc
> kasan test: kmem_cache_oob out-of-bounds in kmem_cache_alloc
> 
> These two tests seems to not trigger KASan BUG()s, and seemse to
> be like so on all hardware, so I guess it is this kind of test
> that requires GCC 5.0:
> 
> kasan test: kasan_stack_oob out-of-bounds on stack
> kasan test: kasan_global_oob out-of-bounds global variable
> 
> 
> Hardware test targets:
> 
> Ux500 (ARMv7):
> 
> On Ux500 I get a real slow boot (as exepected) and after
> enabling the test cases produce KASan warnings
> expectedly.
> 
> MSM APQ8060 (ARMv7):
> 
> Also a real slow boot and the expected KASan warnings when
> running the tests.
> 
> Integrator/AP (ARMv5):
> 
> This one mounted with an ARMv5 ARM926 tile. It boots nicely
> (but takes forever) with KASan and run all test cases (!) just like
> for the other platforms but before reaching userspace this happens:
> 

THREAD_SIZE hardcoded in act_mm macro.

This hack should help:

diff --git a/arch/arm/mm/proc-macros.S b/arch/arm/mm/proc-macros.S
index c671f34..b1765f2 100644
--- a/arch/arm/mm/proc-macros.S
+++ b/arch/arm/mm/proc-macros.S
@@ -32,6 +32,9 @@
 	.macro	act_mm, rd
 	bic	\rd, sp, #8128
 	bic	\rd, \rd, #63
+#ifdef CONFIG_KASAN
+	bic	\rd, \rd, #8192
+#endif
 	ldr	\rd, [\rd, #TI_TASK]
 	ldr	\rd, [\rd, #TSK_ACTIVE_MM]
 	.endm
---




> 
> I then tested on the Footbridge, another ARMv4 system, the oldest I have
> SA110-based. This passes decompression and then you may *think* it hangs.
> But it doesn't. It just takes a few minutes to boot with KASan
> instrumentation, then all tests run fine also on this hardware.
> The crash logs scroll by on the physical console.
> 
> They keep scrolling forever however, and are still scrolling as I
> write this. I suspect some real memory usage bugs to be causing it,
> as it is exercising some ages old code that didn't see much scrutiny
> in recent years.
> 

I would suspect some kasan bug here.

BTW, we probably need to introduce one-shot mode in kasan to prevent such report spam.
I mean print only the first report and ignore the rest. The first report is the most important usually,
next reports usually just noise.


> 
> Yours,
> Linus Walleij
> 


From ykk at rock-chips.com  Wed Aug 19 07:51:44 2015
From: ykk at rock-chips.com (Yakir Yang)
Date: Wed, 19 Aug 2015 09:51:44 -0500
Subject: [PATCH v3 10/14] drm: bridge: analogix_dp: add some rk3288 special
 registers setting
In-Reply-To: <1439995728-18046-1-git-send-email-ykk@rock-chips.com>
References: <1439995728-18046-1-git-send-email-ykk@rock-chips.com>
Message-ID: <1439995904-18608-1-git-send-email-ykk@rock-chips.com>

RK3288 need some special registers setting, we can separate
them out by the dev_type of plat_data.

Signed-off-by: Yakir Yang <ykk at rock-chips.com>
---
Changes in v3: None
Changes in v2:
- Fix compile failed dut to phy_pd_addr variable misspell error

 drivers/gpu/drm/bridge/analogix_dp_reg.c | 76 ++++++++++++++++++++------------
 drivers/gpu/drm/bridge/analogix_dp_reg.h | 12 +++++
 2 files changed, 60 insertions(+), 28 deletions(-)

diff --git a/drivers/gpu/drm/bridge/analogix_dp_reg.c b/drivers/gpu/drm/bridge/analogix_dp_reg.c
index cc5cdbf..a0fc1fb 100644
--- a/drivers/gpu/drm/bridge/analogix_dp_reg.c
+++ b/drivers/gpu/drm/bridge/analogix_dp_reg.c
@@ -15,6 +15,8 @@
 #include <linux/delay.h>
 #include <linux/gpio.h>
 
+#include <drm/bridge/analogix_dp.h>
+
 #include "analogix_dp_core.h"
 #include "analogix_dp_reg.h"
 
@@ -72,6 +74,14 @@ void analogix_dp_init_analog_param(struct analogix_dp_device *dp)
 	reg = SEL_24M | TX_DVDD_BIT_1_0625V;
 	writel(reg, dp->reg_base + ANALOGIX_DP_ANALOG_CTL_2);
 
+	if (dp->plat_data && (dp->plat_data->dev_type == RK3288_DP)) {
+		writel(REF_CLK_24M, dp->reg_base + ANALOGIX_DP_PLL_REG_1);
+		writel(0x95, dp->reg_base + ANALOGIX_DP_PLL_REG_2);
+		writel(0x40, dp->reg_base + ANALOGIX_DP_PLL_REG_3);
+		writel(0x58, dp->reg_base + ANALOGIX_DP_PLL_REG_4);
+		writel(0x22, dp->reg_base + ANALOGIX_DP_PLL_REG_5);
+	}
+
 	reg = DRIVE_DVDD_BIT_1_0625V | VCO_BIT_600_MICRO;
 	writel(reg, dp->reg_base + ANALOGIX_DP_ANALOG_CTL_3);
 
@@ -206,81 +216,85 @@ void analogix_dp_set_analog_power_down(struct analogix_dp_device *dp,
 				       bool enable)
 {
 	u32 reg;
+	u32 phy_pd_addr = ANALOGIX_DP_PHY_PD;
+
+	if (dp->plat_data && (dp->plat_data->dev_type == RK3288_DP))
+		phy_pd_addr = ANALOGIX_DP_PD;
 
 	switch (block) {
 	case AUX_BLOCK:
 		if (enable) {
-			reg = readl(dp->reg_base + ANALOGIX_DP_PHY_PD);
+			reg = readl(dp->reg_base + phy_pd_addr);
 			reg |= AUX_PD;
-			writel(reg, dp->reg_base + ANALOGIX_DP_PHY_PD);
+			writel(reg, dp->reg_base + phy_pd_addr);
 		} else {
-			reg = readl(dp->reg_base + ANALOGIX_DP_PHY_PD);
+			reg = readl(dp->reg_base + phy_pd_addr);
 			reg &= ~AUX_PD;
-			writel(reg, dp->reg_base + ANALOGIX_DP_PHY_PD);
+			writel(reg, dp->reg_base + phy_pd_addr);
 		}
 		break;
 	case CH0_BLOCK:
 		if (enable) {
-			reg = readl(dp->reg_base + ANALOGIX_DP_PHY_PD);
+			reg = readl(dp->reg_base + phy_pd_addr);
 			reg |= CH0_PD;
-			writel(reg, dp->reg_base + ANALOGIX_DP_PHY_PD);
+			writel(reg, dp->reg_base + phy_pd_addr);
 		} else {
-			reg = readl(dp->reg_base + ANALOGIX_DP_PHY_PD);
+			reg = readl(dp->reg_base + phy_pd_addr);
 			reg &= ~CH0_PD;
-			writel(reg, dp->reg_base + ANALOGIX_DP_PHY_PD);
+			writel(reg, dp->reg_base + phy_pd_addr);
 		}
 		break;
 	case CH1_BLOCK:
 		if (enable) {
-			reg = readl(dp->reg_base + ANALOGIX_DP_PHY_PD);
+			reg = readl(dp->reg_base + phy_pd_addr);
 			reg |= CH1_PD;
-			writel(reg, dp->reg_base + ANALOGIX_DP_PHY_PD);
+			writel(reg, dp->reg_base + phy_pd_addr);
 		} else {
-			reg = readl(dp->reg_base + ANALOGIX_DP_PHY_PD);
+			reg = readl(dp->reg_base + phy_pd_addr);
 			reg &= ~CH1_PD;
-			writel(reg, dp->reg_base + ANALOGIX_DP_PHY_PD);
+			writel(reg, dp->reg_base + phy_pd_addr);
 		}
 		break;
 	case CH2_BLOCK:
 		if (enable) {
-			reg = readl(dp->reg_base + ANALOGIX_DP_PHY_PD);
+			reg = readl(dp->reg_base + phy_pd_addr);
 			reg |= CH2_PD;
-			writel(reg, dp->reg_base + ANALOGIX_DP_PHY_PD);
+			writel(reg, dp->reg_base + phy_pd_addr);
 		} else {
-			reg = readl(dp->reg_base + ANALOGIX_DP_PHY_PD);
+			reg = readl(dp->reg_base + phy_pd_addr);
 			reg &= ~CH2_PD;
-			writel(reg, dp->reg_base + ANALOGIX_DP_PHY_PD);
+			writel(reg, dp->reg_base + phy_pd_addr);
 		}
 		break;
 	case CH3_BLOCK:
 		if (enable) {
-			reg = readl(dp->reg_base + ANALOGIX_DP_PHY_PD);
+			reg = readl(dp->reg_base + phy_pd_addr);
 			reg |= CH3_PD;
-			writel(reg, dp->reg_base + ANALOGIX_DP_PHY_PD);
+			writel(reg, dp->reg_base + phy_pd_addr);
 		} else {
-			reg = readl(dp->reg_base + ANALOGIX_DP_PHY_PD);
+			reg = readl(dp->reg_base + phy_pd_addr);
 			reg &= ~CH3_PD;
-			writel(reg, dp->reg_base + ANALOGIX_DP_PHY_PD);
+			writel(reg, dp->reg_base + phy_pd_addr);
 		}
 		break;
 	case ANALOG_TOTAL:
 		if (enable) {
-			reg = readl(dp->reg_base + ANALOGIX_DP_PHY_PD);
+			reg = readl(dp->reg_base + phy_pd_addr);
 			reg |= DP_PHY_PD;
-			writel(reg, dp->reg_base + ANALOGIX_DP_PHY_PD);
+			writel(reg, dp->reg_base + phy_pd_addr);
 		} else {
-			reg = readl(dp->reg_base + ANALOGIX_DP_PHY_PD);
+			reg = readl(dp->reg_base + phy_pd_addr);
 			reg &= ~DP_PHY_PD;
-			writel(reg, dp->reg_base + ANALOGIX_DP_PHY_PD);
+			writel(reg, dp->reg_base + phy_pd_addr);
 		}
 		break;
 	case POWER_ALL:
 		if (enable) {
 			reg = DP_PHY_PD | AUX_PD | CH3_PD | CH2_PD |
 				CH1_PD | CH0_PD;
-			writel(reg, dp->reg_base + ANALOGIX_DP_PHY_PD);
+			writel(reg, dp->reg_base + phy_pd_addr);
 		} else {
-			writel(0x00, dp->reg_base + ANALOGIX_DP_PHY_PD);
+			writel(0x00, dp->reg_base + phy_pd_addr);
 		}
 		break;
 	default:
@@ -399,8 +413,14 @@ void analogix_dp_init_aux(struct analogix_dp_device *dp)
 	analogix_dp_reset_aux(dp);
 
 	/* Disable AUX transaction H/W retry */
-	reg = AUX_BIT_PERIOD_EXPECTED_DELAY(3) | AUX_HW_RETRY_COUNT_SEL(0) |
-	      AUX_HW_RETRY_INTERVAL_600_MICROSECONDS;
+	if (dp->plat_data && (dp->plat_data->dev_type == RK3288_DP))
+		reg = AUX_BIT_PERIOD_EXPECTED_DELAY(0) |
+		      AUX_HW_RETRY_COUNT_SEL(3) |
+		      AUX_HW_RETRY_INTERVAL_600_MICROSECONDS;
+	else
+		reg = AUX_BIT_PERIOD_EXPECTED_DELAY(3) |
+		      AUX_HW_RETRY_COUNT_SEL(0) |
+		      AUX_HW_RETRY_INTERVAL_600_MICROSECONDS;
 	writel(reg, dp->reg_base + ANALOGIX_DP_AUX_HW_RETRY_CTL);
 
 	/* Receive AUX Channel DEFER commands equal to DEFFER_COUNT*64 */
diff --git a/drivers/gpu/drm/bridge/analogix_dp_reg.h b/drivers/gpu/drm/bridge/analogix_dp_reg.h
index bed226f..e38af21 100644
--- a/drivers/gpu/drm/bridge/analogix_dp_reg.h
+++ b/drivers/gpu/drm/bridge/analogix_dp_reg.h
@@ -22,6 +22,14 @@
 #define ANALOGIX_DP_VIDEO_CTL_8			0x3C
 #define ANALOGIX_DP_VIDEO_CTL_10			0x44
 
+#define ANALOGIX_DP_PLL_REG_1			0xfc
+#define ANALOGIX_DP_PLL_REG_2			0x9e4
+#define ANALOGIX_DP_PLL_REG_3			0x9e8
+#define ANALOGIX_DP_PLL_REG_4			0x9ec
+#define ANALOGIX_DP_PLL_REG_5			0xa00
+
+#define ANALOGIX_DP_PD                          0x12c
+
 #define ANALOGIX_DP_LANE_MAP			0x35C
 
 #define ANALOGIX_DP_ANALOG_CTL_1			0x370
@@ -154,6 +162,10 @@
 #define VSYNC_POLARITY_CFG			(0x1 << 1)
 #define HSYNC_POLARITY_CFG			(0x1 << 0)
 
+/* ANALOGIX_DP_PLL_REG_1 */
+#define REF_CLK_24M				(0x1 << 1)
+#define REF_CLK_27M				(0x0 << 1)
+
 /* ANALOGIX_DP_LANE_MAP */
 #define LANE3_MAP_LOGIC_LANE_0			(0x0 << 6)
 #define LANE3_MAP_LOGIC_LANE_1			(0x1 << 6)
-- 
1.9.1




From ykk at rock-chips.com  Wed Aug 19 07:51:59 2015
From: ykk at rock-chips.com (Yakir Yang)
Date: Wed, 19 Aug 2015 09:51:59 -0500
Subject: [PATCH v3 11/14] drm: bridge: analogix_dp: try force hpd after plug
 in lookup failed
In-Reply-To: <1439995728-18046-1-git-send-email-ykk@rock-chips.com>
References: <1439995728-18046-1-git-send-email-ykk@rock-chips.com>
Message-ID: <1439995919-18668-1-git-send-email-ykk@rock-chips.com>

Some edp screen do not have hpd signal, so we can't just return
failed when hpd plug in detect failed.

This is an hardware property, so we need add a devicetree property
"analogix,need-force-hpd" to indicate this sutiation.

Signed-off-by: Yakir Yang <ykk at rock-chips.com>
---
Changes in v3:
- Add "analogix,need-force-hpd" to indicate whether driver need foce
  hpd when hpd detect failed.

Changes in v2: None

 .../devicetree/bindings/drm/bridge/analogix_dp.txt |  3 ++
 .../bindings/video/analogix_dp-rockchip.txt        |  1 +
 .../devicetree/bindings/video/exynos_dp.txt        |  1 +
 drivers/gpu/drm/bridge/analogix_dp_core.c          | 36 +++++++++++++++++++---
 drivers/gpu/drm/bridge/analogix_dp_core.h          |  2 ++
 drivers/gpu/drm/bridge/analogix_dp_reg.c           |  9 ++++++
 6 files changed, 47 insertions(+), 5 deletions(-)

diff --git a/Documentation/devicetree/bindings/drm/bridge/analogix_dp.txt b/Documentation/devicetree/bindings/drm/bridge/analogix_dp.txt
index 6127018..b043200 100644
--- a/Documentation/devicetree/bindings/drm/bridge/analogix_dp.txt
+++ b/Documentation/devicetree/bindings/drm/bridge/analogix_dp.txt
@@ -40,6 +40,9 @@ Required properties for dp-controller:
 		* Documentation/devicetree/bindings/video/analogix_dp-rockchip.txt
 
 Optional properties for dp-controller:
+	-analogix,need-force-hpd:
+		Indicate driver need force hpd when hpd detect failed, this
+		is used for some eDP screen which don't have hpd signal.
 	-analogix,hpd-gpio:
 		Hotplug detect GPIO.
 			Indicates which GPIO should be used for hotplug
diff --git a/Documentation/devicetree/bindings/video/analogix_dp-rockchip.txt b/Documentation/devicetree/bindings/video/analogix_dp-rockchip.txt
index 99fd421..752005e 100644
--- a/Documentation/devicetree/bindings/video/analogix_dp-rockchip.txt
+++ b/Documentation/devicetree/bindings/video/analogix_dp-rockchip.txt
@@ -27,6 +27,7 @@ For the below properties, please refer to Analogix DP binding document:
 - analogix,color-depth (required)
 - analogix,link-rate (required)
 - analogix,lane-count (required)
+- analogix,need-force-hpd (optional)
 - analogix,hpd-gpio (optional)
 - video interfaces (optional)
 -------------------------------------------------------------------------------
diff --git a/Documentation/devicetree/bindings/video/exynos_dp.txt b/Documentation/devicetree/bindings/video/exynos_dp.txt
index 177506f..ba20416 100644
--- a/Documentation/devicetree/bindings/video/exynos_dp.txt
+++ b/Documentation/devicetree/bindings/video/exynos_dp.txt
@@ -53,6 +53,7 @@ For the below properties, please refer to Analogix DP binding document:
 	-analogix,color-depth (required)
 	-analogix,link-rate (required)
 	-analogix,lane-count (required)
+	-analogix,need-force-hpd (optional)
 	-analogix,hpd-gpio (optional)
 	-video interfaces (optional)
 -------------------------------------------------------------------------------
diff --git a/drivers/gpu/drm/bridge/analogix_dp_core.c b/drivers/gpu/drm/bridge/analogix_dp_core.c
index 1778e0a..99870f7 100644
--- a/drivers/gpu/drm/bridge/analogix_dp_core.c
+++ b/drivers/gpu/drm/bridge/analogix_dp_core.c
@@ -63,15 +63,38 @@ static int analogix_dp_detect_hpd(struct analogix_dp_device *dp)
 {
 	int timeout_loop = 0;
 
-	while (analogix_dp_get_plug_in_status(dp) != 0) {
+	while (timeout_loop < DP_TIMEOUT_LOOP_COUNT) {
+		if (analogix_dp_get_plug_in_status(dp) == 0)
+			return 0;
+
 		timeout_loop++;
-		if (DP_TIMEOUT_LOOP_COUNT < timeout_loop) {
-			dev_err(dp->dev, "failed to get hpd plug status\n");
-			return -ETIMEDOUT;
-		}
 		usleep_range(10, 11);
 	}
 
+	/*
+	 * Some edp screen do not have hpd signal, so we can't just
+	 * return failed when hpd plug in detect failed, DT property
+	 * "need-force-hpd" would indicate whether driver need this.
+	 */
+	if (!dp->need_force_hpd)
+		return -ETIMEDOUT;
+
+	/*
+	 * The eDP TRM indicate that if HPD_STATUS(RO) is 0, AUX CH
+	 * will not work, so we need to give a force hpd action to
+	 * set HPD_STATUS manually.
+	 */
+	dev_dbg(dp->dev, "failed to get hpd plug status, try to force hpd\n");
+
+	analogix_dp_force_hpd(dp);
+
+	if (analogix_dp_get_plug_in_status(dp) != 0) {
+		dev_err(dp->dev, "failed to get hpd plug in status\n");
+		return -EINVAL;
+	}
+
+	dev_dbg(dp->dev, "success to get plug in status after force hpd\n");
+
 	return 0;
 }
 
@@ -1272,6 +1295,9 @@ int analogix_dp_bind(struct device *dev, struct drm_device *drm_dev,
 	if (IS_ERR(dp->reg_base))
 		return PTR_ERR(dp->reg_base);
 
+	dp->need_force_hpd =
+		of_property_read_bool(dev->of_node, "analogix,need-force-hpd");
+
 	dp->hpd_gpio = of_get_named_gpio(dev->of_node, "analogix,hpd-gpio", 0);
 
 	if (gpio_is_valid(dp->hpd_gpio)) {
diff --git a/drivers/gpu/drm/bridge/analogix_dp_core.h b/drivers/gpu/drm/bridge/analogix_dp_core.h
index 941b34f..2405155 100644
--- a/drivers/gpu/drm/bridge/analogix_dp_core.h
+++ b/drivers/gpu/drm/bridge/analogix_dp_core.h
@@ -160,6 +160,7 @@ struct analogix_dp_device {
 	struct phy		*phy;
 	int			dpms_mode;
 	int			hpd_gpio;
+	bool                    need_force_hpd;
 
 	struct analogix_dp_plat_data *plat_data;
 };
@@ -180,6 +181,7 @@ void analogix_dp_set_analog_power_down(struct analogix_dp_device *dp,
 				       bool enable);
 void analogix_dp_init_analog_func(struct analogix_dp_device *dp);
 void analogix_dp_init_hpd(struct analogix_dp_device *dp);
+void analogix_dp_force_hpd(struct analogix_dp_device *dp);
 enum dp_irq_type analogix_dp_get_irq_type(struct analogix_dp_device *dp);
 void analogix_dp_clear_hotplug_interrupts(struct analogix_dp_device *dp);
 void analogix_dp_reset_aux(struct analogix_dp_device *dp);
diff --git a/drivers/gpu/drm/bridge/analogix_dp_reg.c b/drivers/gpu/drm/bridge/analogix_dp_reg.c
index a0fc1fb..bf7cee1 100644
--- a/drivers/gpu/drm/bridge/analogix_dp_reg.c
+++ b/drivers/gpu/drm/bridge/analogix_dp_reg.c
@@ -365,6 +365,15 @@ void analogix_dp_init_hpd(struct analogix_dp_device *dp)
 	writel(reg, dp->reg_base + ANALOGIX_DP_SYS_CTL_3);
 }
 
+void analogix_dp_force_hpd(struct analogix_dp_device *dp)
+{
+	u32 reg;
+
+	reg = readl(dp->reg_base + ANALOGIX_DP_SYS_CTL_3);
+	reg = (F_HPD | HPD_CTRL);
+	writel(reg, dp->reg_base + ANALOGIX_DP_SYS_CTL_3);
+}
+
 enum dp_irq_type analogix_dp_get_irq_type(struct analogix_dp_device *dp)
 {
 	u32 reg;
-- 
1.9.1




From ykk at rock-chips.com  Wed Aug 19 07:52:09 2015
From: ykk at rock-chips.com (Yakir Yang)
Date: Wed, 19 Aug 2015 09:52:09 -0500
Subject: [PATCH v3 12/14] drm: bridge/analogix_dp: expand the delay time for
 hpd detect
In-Reply-To: <1439995728-18046-1-git-send-email-ykk@rock-chips.com>
References: <1439995728-18046-1-git-send-email-ykk@rock-chips.com>
Message-ID: <1439995929-18719-1-git-send-email-ykk@rock-chips.com>

Some edp screen with no hpd signal would need some delay time
to ensure that screen would be ready for work, so we can expand
the delay time in hpd detect function, it works prefectly on my
rk3288 sdk board.

Signed-off-by: Yakir Yang <ykk at rock-chips.com>
---
Changes in v3: None
Changes in v2: None

 drivers/gpu/drm/bridge/analogix_dp_core.c | 2 +-
 1 file changed, 1 insertion(+), 1 deletion(-)

diff --git a/drivers/gpu/drm/bridge/analogix_dp_core.c b/drivers/gpu/drm/bridge/analogix_dp_core.c
index 99870f7..75dd44a 100644
--- a/drivers/gpu/drm/bridge/analogix_dp_core.c
+++ b/drivers/gpu/drm/bridge/analogix_dp_core.c
@@ -68,7 +68,7 @@ static int analogix_dp_detect_hpd(struct analogix_dp_device *dp)
 			return 0;
 
 		timeout_loop++;
-		usleep_range(10, 11);
+		usleep_range(100, 110);
 	}
 
 	/*
-- 
1.9.1




From ykk at rock-chips.com  Wed Aug 19 07:52:19 2015
From: ykk at rock-chips.com (Yakir Yang)
Date: Wed, 19 Aug 2015 09:52:19 -0500
Subject: [PATCH v3 13/14] drm: bridge/analogix_dp: move hpd detect to
 connector detect function
In-Reply-To: <1439995728-18046-1-git-send-email-ykk@rock-chips.com>
References: <1439995728-18046-1-git-send-email-ykk@rock-chips.com>
Message-ID: <1439995939-18770-1-git-send-email-ykk@rock-chips.com>

Signed-off-by: Yakir Yang <ykk at rock-chips.com>
---
Changes in v3:
- move dp hpd detect to connector detect function.

Changes in v2: None

 drivers/gpu/drm/bridge/analogix_dp_core.c | 12 ++++++------
 1 file changed, 6 insertions(+), 6 deletions(-)

diff --git a/drivers/gpu/drm/bridge/analogix_dp_core.c b/drivers/gpu/drm/bridge/analogix_dp_core.c
index 75dd44a..052b9b3 100644
--- a/drivers/gpu/drm/bridge/analogix_dp_core.c
+++ b/drivers/gpu/drm/bridge/analogix_dp_core.c
@@ -915,12 +915,6 @@ static void analogix_dp_commit(struct analogix_dp_device *dp)
 			DRM_ERROR("failed to disable the panel\n");
 	}
 
-	ret = analogix_dp_detect_hpd(dp);
-	if (ret) {
-		/* Cable has been disconnected, we're done */
-		return;
-	}
-
 	ret = analogix_dp_handle_edid(dp);
 	if (ret) {
 		dev_err(dp->dev, "unable to handle edid\n");
@@ -953,6 +947,12 @@ static void analogix_dp_commit(struct analogix_dp_device *dp)
 static enum drm_connector_status analogix_dp_detect(
 				struct drm_connector *connector, bool force)
 {
+	struct analogix_dp_device *dp = connector_to_dp(connector);
+
+	if (analogix_dp_detect_hpd(dp))
+		/* Cable has been disconnected, we're done */
+		return connector_status_disconnected;
+
 	return connector_status_connected;
 }
 
-- 
1.9.1




From ykk at rock-chips.com  Wed Aug 19 07:52:29 2015
From: ykk at rock-chips.com (Yakir Yang)
Date: Wed, 19 Aug 2015 09:52:29 -0500
Subject: [PATCH v3 14/14] drm: bridge/analogix_dp: add edid modes parse in
 get_modes method
In-Reply-To: <1439995728-18046-1-git-send-email-ykk@rock-chips.com>
References: <1439995728-18046-1-git-send-email-ykk@rock-chips.com>
Message-ID: <1439995949-18821-1-git-send-email-ykk@rock-chips.com>

Display Port monitor could support kinds of mode which indicate
in monitor edid, not just one single display resolution which
defined in panel or devivetree property display timing.

Signed-off-by: Yakir Yang <ykk at rock-chips.com>
---
Changes in v3:
- Add edid modes parse support

Changes in v2: None

 drivers/gpu/drm/bridge/analogix_dp_core.c | 17 +++++++-----
 drivers/gpu/drm/bridge/analogix_dp_core.h | 45 ++++++++++++++++---------------
 2 files changed, 33 insertions(+), 29 deletions(-)

diff --git a/drivers/gpu/drm/bridge/analogix_dp_core.c b/drivers/gpu/drm/bridge/analogix_dp_core.c
index 052b9b3..83698c6 100644
--- a/drivers/gpu/drm/bridge/analogix_dp_core.c
+++ b/drivers/gpu/drm/bridge/analogix_dp_core.c
@@ -111,7 +111,7 @@ static unsigned char analogix_dp_calc_edid_check_sum(unsigned char *edid_data)
 
 static int analogix_dp_read_edid(struct analogix_dp_device *dp)
 {
-	unsigned char edid[EDID_BLOCK_LENGTH * 2];
+	unsigned char *edid = dp->edid;
 	unsigned int extend_block = 0;
 	unsigned char sum;
 	unsigned char test_vector;
@@ -915,12 +915,6 @@ static void analogix_dp_commit(struct analogix_dp_device *dp)
 			DRM_ERROR("failed to disable the panel\n");
 	}
 
-	ret = analogix_dp_handle_edid(dp);
-	if (ret) {
-		dev_err(dp->dev, "unable to handle edid\n");
-		return;
-	}
-
 	ret = analogix_dp_set_link_train(dp, dp->video_info->max_lane_count,
 					 dp->video_info->max_link_rate);
 	if (ret) {
@@ -976,8 +970,17 @@ static int analogix_dp_get_modes(struct drm_connector *connector)
 {
 	struct analogix_dp_device *dp = connector_to_dp(connector);
 	struct analogix_dp_plat_data *plat_data = dp->plat_data;
+	struct edid *edid = (struct edid *)dp->edid;
 	int num_modes = 0;
 
+	if (analogix_dp_handle_edid(dp)) {
+		dev_err(dp->dev, "unable to handle edid\n");
+		return -EINVAL;
+	}
+
+	drm_mode_connector_update_edid_property(connector, edid);
+	num_modes += drm_add_edid_modes(connector, edid);
+
 	if (plat_data && plat_data->panel)
 		num_modes += drm_panel_get_modes(plat_data->panel);
 
diff --git a/drivers/gpu/drm/bridge/analogix_dp_core.h b/drivers/gpu/drm/bridge/analogix_dp_core.h
index 2405155..950b6ca 100644
--- a/drivers/gpu/drm/bridge/analogix_dp_core.h
+++ b/drivers/gpu/drm/bridge/analogix_dp_core.h
@@ -20,6 +20,28 @@
 #define MAX_CR_LOOP 5
 #define MAX_EQ_LOOP 5
 
+/* I2C EDID Chip ID, Slave Address */
+#define I2C_EDID_DEVICE_ADDR			0x50
+#define I2C_E_EDID_DEVICE_ADDR			0x30
+
+#define EDID_BLOCK_LENGTH			0x80
+#define EDID_HEADER_PATTERN			0x00
+#define EDID_EXTENSION_FLAG			0x7e
+#define EDID_CHECKSUM				0x7f
+
+/* DP_MAX_LANE_COUNT */
+#define DPCD_ENHANCED_FRAME_CAP(x)		(((x) >> 7) & 0x1)
+#define DPCD_MAX_LANE_COUNT(x)			((x) & 0x1f)
+
+/* DP_LANE_COUNT_SET */
+#define DPCD_LANE_COUNT_SET(x)			((x) & 0x1f)
+
+/* DP_TRAINING_LANE0_SET */
+#define DPCD_PRE_EMPHASIS_SET(x)		(((x) & 0x3) << 3)
+#define DPCD_PRE_EMPHASIS_GET(x)		(((x) >> 3) & 0x3)
+#define DPCD_VOLTAGE_SWING_SET(x)		(((x) & 0x3) << 0)
+#define DPCD_VOLTAGE_SWING_GET(x)		(((x) >> 0) & 0x3)
+
 enum link_rate_type {
 	LINK_RATE_1_62GBPS = DP_LINK_BW_1_62,
 	LINK_RATE_2_70GBPS = DP_LINK_BW_2_7,
@@ -161,6 +183,7 @@ struct analogix_dp_device {
 	int			dpms_mode;
 	int			hpd_gpio;
 	bool                    need_force_hpd;
+	unsigned char           edid[EDID_BLOCK_LENGTH * 2];
 
 	struct analogix_dp_plat_data *plat_data;
 };
@@ -260,26 +283,4 @@ void analogix_dp_config_video_slave_mode(struct analogix_dp_device *dp);
 void analogix_dp_enable_scrambling(struct analogix_dp_device *dp);
 void analogix_dp_disable_scrambling(struct analogix_dp_device *dp);
 
-/* I2C EDID Chip ID, Slave Address */
-#define I2C_EDID_DEVICE_ADDR			0x50
-#define I2C_E_EDID_DEVICE_ADDR			0x30
-
-#define EDID_BLOCK_LENGTH			0x80
-#define EDID_HEADER_PATTERN			0x00
-#define EDID_EXTENSION_FLAG			0x7e
-#define EDID_CHECKSUM				0x7f
-
-/* DP_MAX_LANE_COUNT */
-#define DPCD_ENHANCED_FRAME_CAP(x)		(((x) >> 7) & 0x1)
-#define DPCD_MAX_LANE_COUNT(x)			((x) & 0x1f)
-
-/* DP_LANE_COUNT_SET */
-#define DPCD_LANE_COUNT_SET(x)			((x) & 0x1f)
-
-/* DP_TRAINING_LANE0_SET */
-#define DPCD_PRE_EMPHASIS_SET(x)		(((x) & 0x3) << 3)
-#define DPCD_PRE_EMPHASIS_GET(x)		(((x) >> 3) & 0x3)
-#define DPCD_VOLTAGE_SWING_SET(x)		(((x) & 0x3) << 0)
-#define DPCD_VOLTAGE_SWING_GET(x)		(((x) >> 0) & 0x3)
-
 #endif /* _ANALOGIX_DP_CORE_H */
-- 
1.9.1




From vinod.koul at intel.com  Wed Aug 19 08:06:05 2015
From: vinod.koul at intel.com (Vinod Koul)
Date: Wed, 19 Aug 2015 20:36:05 +0530
Subject: [PATCH 1/7] dmaengine: st_fdma: Add STMicroelectronics FDMA DT
 binding documentation
In-Reply-To: <1436371888-27863-2-git-send-email-peter.griffin@linaro.org>
References: <1436371888-27863-1-git-send-email-peter.griffin@linaro.org>
 <1436371888-27863-2-git-send-email-peter.griffin@linaro.org>
Message-ID: <20150819150605.GA13546@localhost>

On Wed, Jul 08, 2015 at 05:11:22PM +0100, Peter Griffin wrote:
> This patch adds the DT binding documentation for the FDMA constroller
> found on STi based chipsets from STMicroelectronics.
> 
> Signed-off-by: Ludovic Barre <ludovic.barre at st.com>
> Signed-off-by: Peter Griffin <peter.griffin at linaro.org>
> ---
>  Documentation/devicetree/bindings/dma/st_fdma.txt | 76 +++++++++++++++++++++++
>  1 file changed, 76 insertions(+)
>  create mode 100644 Documentation/devicetree/bindings/dma/st_fdma.txt
> 
> diff --git a/Documentation/devicetree/bindings/dma/st_fdma.txt b/Documentation/devicetree/bindings/dma/st_fdma.txt
> new file mode 100644
> index 0000000..1ec7470
> --- /dev/null
> +++ b/Documentation/devicetree/bindings/dma/st_fdma.txt
> @@ -0,0 +1,76 @@
> +* STMicroelectronics Flexible Direct Memory Access Device Tree bindings
> +
> +The FDMA is a general-purpose direct memory access controller capable of
> +supporting 16 independent DMA channels. It accepts up to 32 DMA requests.
> +The FDMA is based on a Slim processor which require a firmware.
> +
> +* FDMA Controller
> +
> +Required properties:
> +- compatible	: Should be "st,fdma_mpe31"
> +- reg		: Should contain DMA registers location and length
> +- interrupts	: Should contain one interrupt shared by all channel

s/channel/channels

> +- dma-channels	: Number of channels supported by the controller
> +- #dma-cells	: Must be <3>.

any reason three?

-- 
~Vinod



From will.deacon at arm.com  Wed Aug 19 08:09:49 2015
From: will.deacon at arm.com (Will Deacon)
Date: Wed, 19 Aug 2015 16:09:49 +0100
Subject: [PATCH] arm64: entry: always restore x0 from the stack on syscall
 return
Message-ID: <1439996989-5772-1-git-send-email-will.deacon@arm.com>

We have a micro-optimisation on the fast syscall return path where we
take care to keep x0 live with the return value from the syscall so that
we can avoid restoring it from the stack. The benefit of doing this is
fairly suspect, since we will be restoring x1 from the stack anyway
(which lives adjacent in the pt_regs structure) and the only additional
cost is saving x0 back to pt_regs after the syscall handler, which could
be seen as a poor man's prefetch.

More importantly, this causes issues with the context tracking code.

The ct_user_enter macro ends up branching into C code, which is free to
use x0 as a scratch register and consequently leads to us returning junk
back to userspace as the syscall return value. Rather than special case
the context-tracking code, this patch removes the questionable
optimisation entirely.

Cc: <stable at vger.kernel.org>
Cc: Larry Bassel <larry.bassel at linaro.org>
Cc: Kevin Hilman <khilman at linaro.org>
Cc: Catalin Marinas <catalin.marinas at arm.com>
Reported-by: Hanjun Guo <hanjun.guo at linaro.org>
Signed-off-by: Will Deacon <will.deacon at arm.com>
---
 arch/arm64/kernel/entry.S | 15 +++++----------
 1 file changed, 5 insertions(+), 10 deletions(-)

diff --git a/arch/arm64/kernel/entry.S b/arch/arm64/kernel/entry.S
index 301c37207c64..2a5e64ccc991 100644
--- a/arch/arm64/kernel/entry.S
+++ b/arch/arm64/kernel/entry.S
@@ -116,7 +116,7 @@
 	*/
 	.endm
 
-	.macro	kernel_exit, el, ret = 0
+	.macro	kernel_exit, el
 	ldp	x21, x22, [sp, #S_PC]		// load ELR, SPSR
 	.if	\el == 0
 	ct_user_enter
@@ -146,11 +146,7 @@
 	.endif
 	msr	elr_el1, x21			// set up the return data
 	msr	spsr_el1, x22
-	.if	\ret
-	ldr	x1, [sp, #S_X1]			// preserve x0 (syscall return)
-	.else
 	ldp	x0, x1, [sp, #16 * 0]
-	.endif
 	ldp	x2, x3, [sp, #16 * 1]
 	ldp	x4, x5, [sp, #16 * 2]
 	ldp	x6, x7, [sp, #16 * 3]
@@ -613,13 +609,14 @@ ENDPROC(cpu_switch_to)
  */
 ret_fast_syscall:
 	disable_irq				// disable interrupts
+	str	x0, [sp, #S_X0]			// returned x0
 	ldr	x1, [tsk, #TI_FLAGS]		// re-check for syscall tracing
 	and	x2, x1, #_TIF_SYSCALL_WORK
 	cbnz	x2, ret_fast_syscall_trace
 	and	x2, x1, #_TIF_WORK_MASK
-	cbnz	x2, fast_work_pending
+	cbnz	x2, work_pending
 	enable_step_tsk x1, x2
-	kernel_exit 0, ret = 1
+	kernel_exit 0
 ret_fast_syscall_trace:
 	enable_irq				// enable interrupts
 	b	__sys_trace_return
@@ -627,8 +624,6 @@ ret_fast_syscall_trace:
 /*
  * Ok, we need to do extra processing, enter the slow path.
  */
-fast_work_pending:
-	str	x0, [sp, #S_X0]			// returned x0
 work_pending:
 	tbnz	x1, #TIF_NEED_RESCHED, work_resched
 	/* TIF_SIGPENDING, TIF_NOTIFY_RESUME or TIF_FOREIGN_FPSTATE case */
@@ -652,7 +647,7 @@ ret_to_user:
 	cbnz	x2, work_pending
 	enable_step_tsk x1, x2
 no_work_pending:
-	kernel_exit 0, ret = 0
+	kernel_exit 0
 ENDPROC(ret_to_user)
 
 /*
-- 
2.1.4



From maxime.ripard at free-electrons.com  Wed Aug 19 08:10:03 2015
From: maxime.ripard at free-electrons.com (Maxime Ripard)
Date: Wed, 19 Aug 2015 17:10:03 +0200
Subject: [PATCH 3/3] ARM: dts: sun6i: Columbus: Add i2c controller for
 communicating with the LCD
In-Reply-To: <1438960955-6551-3-git-send-email-hdegoede@redhat.com>
References: <1438960955-6551-1-git-send-email-hdegoede@redhat.com>
 <1438960955-6551-3-git-send-email-hdegoede@redhat.com>
Message-ID: <20150819151003.GG30520@lukather>

On Fri, Aug 07, 2015 at 05:22:35PM +0200, Hans de Goede wrote:
> The Colombus development kit uses an optional 2048x1536 edp panel using
> an anx9804 parallel lcd to edp convertor. The anx9804 chip is controlled
> via an i2c bus which is connected to 2 regular gpio pins.
> 
> Signed-off-by: Hans de Goede <hdegoede at redhat.com>

Fixed the checkpatch warning (convertor vs converter) and queued,
thanks!

Maxime

-- 
Maxime Ripard, Free Electrons
Embedded Linux, Kernel and Android engineering
http://free-electrons.com
-------------- next part --------------
A non-text attachment was scrubbed...
Name: signature.asc
Type: application/pgp-signature
Size: 819 bytes
Desc: Digital signature
URL: <http://lists.infradead.org/pipermail/linux-arm-kernel/attachments/20150819/67817c7d/attachment.sig>

From maxime.ripard at free-electrons.com  Wed Aug 19 08:17:54 2015
From: maxime.ripard at free-electrons.com (Maxime Ripard)
Date: Wed, 19 Aug 2015 17:17:54 +0200
Subject: [PATCH 2/3] ARM: dts: sun6i: Turn on gmac on Colombus
In-Reply-To: <1438960955-6551-2-git-send-email-hdegoede@redhat.com>
References: <1438960955-6551-1-git-send-email-hdegoede@redhat.com>
 <1438960955-6551-2-git-send-email-hdegoede@redhat.com>
Message-ID: <20150819151754.GH30520@lukather>

On Fri, Aug 07, 2015 at 05:22:34PM +0200, Hans de Goede wrote:
> We've everything we need to support the gmac on Colombus, turn it on.
> 
> Signed-off-by: Hans de Goede <hdegoede at redhat.com>

I recall that the phy was powered by one of the AXP221 regulators,
does it require some additional stuff (like a recent u-boot), or does
it just work and my memory is bad :) ?

-- 
Maxime Ripard, Free Electrons
Embedded Linux, Kernel and Android engineering
http://free-electrons.com
-------------- next part --------------
A non-text attachment was scrubbed...
Name: signature.asc
Type: application/pgp-signature
Size: 819 bytes
Desc: Digital signature
URL: <http://lists.infradead.org/pipermail/linux-arm-kernel/attachments/20150819/03e65392/attachment.sig>

From gabriele.paoloni at huawei.com  Wed Aug 19 08:16:20 2015
From: gabriele.paoloni at huawei.com (Gabriele Paoloni)
Date: Wed, 19 Aug 2015 15:16:20 +0000
Subject: [PATCH v7 3/6] PCI: designware: Add ARM64 support
In-Reply-To: <1439988852.31432.15.camel@pengutronix.de>
References: <1439812554-180426-1-git-send-email-wangzhou1@hisilicon.com>
 <1439812554-180426-4-git-send-email-wangzhou1@hisilicon.com>
 <1439988852.31432.15.camel@pengutronix.de>
Message-ID: <EE11001F9E5DDD47B7634E2F8A612F2E01D81315@lhreml503-mbs>

Hi Lucas

I have rewritten the patch to take into account multiple controllers.

As you can see now there is a static var in dw_pcie_host_init() that tracks
the bus numbers used.
Drivers that do not specify the bus range in the DTB set pp->root_bus_nr = DW_ROOT_NR_UNDEFINED.
Designware will check if the flag is set and will use the automatic bus range
assignment.
Instead if the driver assigns pp->root_bus_nr according to the dtb, designwware
will use the value passed in by the driver.
Below the relevant section:


+	static int root_bus_nr = 0;
...
+	mutex_lock(&root_bus_nr_mux);
+
+	if (pp->root_bus_nr != DW_ROOT_NR_UNDEFINED)
+		root_bus_nr = pp->root_bus_nr;
+
+	bus = pci_create_root_bus(pp->dev, root_bus_nr, &dw_pcie_ops,
+			      pp, &res);
+	if (!bus) {
+		mutex_unlock(&root_bus_nr_mux);
+		return -ENOMEM;
+	}
+
+	root_bus_nr += bus->busn_res.end + 1;
+	mutex_unlock(&root_bus_nr_mux);

Please let me know what you think...

Many Thanks

Gab
----------

From: gabriele paoloni <gabriele.paoloni at huawei.com>

This patch tries to unify ARM32 and ARM64 PCIe in designware driver. Delete
function dw_pcie_setup, dw_pcie_scan_bus, dw_pcie_map_irq and struct hw_pci,
move related operations to dw_pcie_host_init.
Also set pp->root_bus_nr = DW_ROOT_NR_UNDEFINED in all the drivers that
are based on designware to flag that the drivers do not read the bus
ranges from DT.
This patch also adds handling of multiple PCI domains in designware.
if the PCI host bridge driver does not specify a root bus number, in case
of multiple domains, designware will automatillay set the next domain root
bus number to the last bus number used in the last domain + 1.

This patch also try to use of_pci_get_host_bridge_resources for ARM32 and
ARM64 according to the suggestion for Gabriele[1]

This patch is based on Gabriele's patch about of_pci_range fix[2]

Finally this patch reverts commit f4c55c5a3f7f "PCI: designware:
Program ATU with untranslated address". This was discussed in [3]

I have compiled the driver with multi_v7_defconfig. However, I don't have
ARM32 PCIe related board to do test. It will be appreciated if someone could
help to test it.

Signed-off-by: Zhou Wang <wangzhou1 at hisilicon.com>
Signed-off-by: Arnd Bergmann <arnd at arndb.de>
Signed-off-by: Gabriele Paoloni <gabriele.paoloni at huawei.com>

[1] http://www.spinics.net/lists/linux-pci/msg42194.html
[2] https://patchwork.ozlabs.org/patch/495018/
[3] http://www.spinics.net/lists/arm-kernel/msg436779.html
---
 drivers/pci/host/pci-dra7xx.c      |  15 +--
 drivers/pci/host/pci-exynos.c      |   2 +-
 drivers/pci/host/pci-imx6.c        |   2 +-
 drivers/pci/host/pci-keystone-dw.c |   2 +-
 drivers/pci/host/pci-keystone.c    |   2 +-
 drivers/pci/host/pci-layerscape.c  |   2 +-
 drivers/pci/host/pcie-designware.c | 247 ++++++++++++++-----------------------
 drivers/pci/host/pcie-designware.h |  15 +--
 drivers/pci/host/pcie-spear13xx.c  |   2 +-
 9 files changed, 110 insertions(+), 179 deletions(-)

diff --git a/drivers/pci/host/pci-dra7xx.c b/drivers/pci/host/pci-dra7xx.c
index 5678b57..8d598fb 100644
--- a/drivers/pci/host/pci-dra7xx.c
+++ b/drivers/pci/host/pci-dra7xx.c
@@ -141,15 +141,15 @@ static void dra7xx_pcie_host_init(struct pcie_port *pp)
 {
 	dw_pcie_setup_rc(pp);
 
-	if (pp->io_mod_base)
-		pp->io_mod_base &= CPU_TO_BUS_ADDR;
+	if (pp->io_base)
+		pp->io_base &= CPU_TO_BUS_ADDR;
 
-	if (pp->mem_mod_base)
-		pp->mem_mod_base &= CPU_TO_BUS_ADDR;
+	if (pp->mem_base)
+		pp->mem_base &= CPU_TO_BUS_ADDR;
 
-	if (pp->cfg0_mod_base) {
-		pp->cfg0_mod_base &= CPU_TO_BUS_ADDR;
-		pp->cfg1_mod_base &= CPU_TO_BUS_ADDR;
+	if (pp->cfg0_base) {
+		pp->cfg0_base &= CPU_TO_BUS_ADDR;
+		pp->cfg1_base &= CPU_TO_BUS_ADDR;
 	}
 
 	dra7xx_pcie_establish_link(pp);
@@ -288,6 +288,7 @@ static int __init dra7xx_add_pcie_port(struct dra7xx_pcie *dra7xx,
 
 	pp = &dra7xx->pp;
 	pp->dev = dev;
+	pp->root_bus_nr = DW_ROOT_NR_UNDEFINED;
 	pp->ops = &dra7xx_pcie_host_ops;
 
 	pp->irq = platform_get_irq(pdev, 1);
diff --git a/drivers/pci/host/pci-exynos.c b/drivers/pci/host/pci-exynos.c
index f9f468d..ed03a8f 100644
--- a/drivers/pci/host/pci-exynos.c
+++ b/drivers/pci/host/pci-exynos.c
@@ -530,7 +530,7 @@ static int __init exynos_add_pcie_port(struct pcie_port *pp,
 		}
 	}
 
-	pp->root_bus_nr = -1;
+	pp->root_bus_nr = DW_ROOT_NR_UNDEFINED;
 	pp->ops = &exynos_pcie_host_ops;
 
 	ret = dw_pcie_host_init(pp);
diff --git a/drivers/pci/host/pci-imx6.c b/drivers/pci/host/pci-imx6.c
index 233a196..0efac85 100644
--- a/drivers/pci/host/pci-imx6.c
+++ b/drivers/pci/host/pci-imx6.c
@@ -551,7 +551,7 @@ static int __init imx6_add_pcie_port(struct pcie_port *pp,
 		}
 	}
 
-	pp->root_bus_nr = -1;
+	pp->root_bus_nr = DW_ROOT_NR_UNDEFINED;
 	pp->ops = &imx6_pcie_host_ops;
 
 	ret = dw_pcie_host_init(pp);
diff --git a/drivers/pci/host/pci-keystone-dw.c b/drivers/pci/host/pci-keystone-dw.c
index f34892e..b1e4135 100644
--- a/drivers/pci/host/pci-keystone-dw.c
+++ b/drivers/pci/host/pci-keystone-dw.c
@@ -327,7 +327,7 @@ static void ks_dw_pcie_clear_dbi_mode(void __iomem *reg_virt)
 void ks_dw_pcie_setup_rc_app_regs(struct keystone_pcie *ks_pcie)
 {
 	struct pcie_port *pp = &ks_pcie->pp;
-	u32 start = pp->mem.start, end = pp->mem.end;
+	u32 start = pp->mem->start, end = pp->mem->end;
 	int i, tr_size;
 
 	/* Disable BARs for inbound access */
diff --git a/drivers/pci/host/pci-keystone.c b/drivers/pci/host/pci-keystone.c
index 734da58..b522956 100644
--- a/drivers/pci/host/pci-keystone.c
+++ b/drivers/pci/host/pci-keystone.c
@@ -309,7 +309,7 @@ static int __init ks_add_pcie_port(struct keystone_pcie *ks_pcie,
 			return ret;
 	}
 
-	pp->root_bus_nr = -1;
+	pp->root_bus_nr = DW_ROOT_NR_UNDEFINED;
 	pp->ops = &keystone_pcie_host_ops;
 	ret = ks_dw_pcie_host_init(ks_pcie, ks_pcie->msi_intc_np);
 	if (ret) {
diff --git a/drivers/pci/host/pci-layerscape.c b/drivers/pci/host/pci-layerscape.c
index b2328ea1..dd92ffa 100644
--- a/drivers/pci/host/pci-layerscape.c
+++ b/drivers/pci/host/pci-layerscape.c
@@ -106,7 +106,7 @@ static int ls_add_pcie_port(struct ls_pcie *pcie)
 	pp = &pcie->pp;
 	pp->dev = pcie->dev;
 	pp->dbi_base = pcie->dbi;
-	pp->root_bus_nr = -1;
+	pp->root_bus_nr = DW_ROOT_NR_UNDEFINED;
 	pp->ops = &ls_pcie_host_ops;
 
 	ret = dw_pcie_host_init(pp);
diff --git a/drivers/pci/host/pcie-designware.c b/drivers/pci/host/pcie-designware.c
index 5307b35..bd2606b 100644
--- a/drivers/pci/host/pcie-designware.c
+++ b/drivers/pci/host/pcie-designware.c
@@ -11,6 +11,7 @@
  * published by the Free Software Foundation.
  */
 
+#include <linux/hardirq.h>
 #include <linux/irq.h>
 #include <linux/irqdomain.h>
 #include <linux/kernel.h>
@@ -69,16 +70,9 @@
 #define PCIE_ATU_FUNC(x)		(((x) & 0x7) << 16)
 #define PCIE_ATU_UPPER_TARGET		0x91C
 
-static struct hw_pci dw_pci;
+static struct pci_ops dw_pcie_ops;
 
-static unsigned long global_io_offset;
-
-static inline struct pcie_port *sys_to_pcie(struct pci_sys_data *sys)
-{
-	BUG_ON(!sys->private_data);
-
-	return sys->private_data;
-}
+DEFINE_MUTEX(root_bus_nr_mux);
 
 int dw_pcie_cfg_read(void __iomem *addr, int where, int size, u32 *val)
 {
@@ -255,7 +249,7 @@ static void dw_pcie_msi_set_irq(struct pcie_port *pp, int irq)
 static int assign_irq(int no_irqs, struct msi_desc *desc, int *pos)
 {
 	int irq, pos0, i;
-	struct pcie_port *pp = sys_to_pcie(desc->dev->bus->sysdata);
+	struct pcie_port *pp = desc->dev->bus->sysdata;
 
 	pos0 = bitmap_find_free_region(pp->msi_irq_in_use, MAX_MSI_IRQS,
 				       order_base_2(no_irqs));
@@ -298,7 +292,7 @@ static int dw_msi_setup_irq(struct msi_controller *chip, struct pci_dev *pdev,
 {
 	int irq, pos;
 	struct msi_msg msg;
-	struct pcie_port *pp = sys_to_pcie(pdev->bus->sysdata);
+	struct pcie_port *pp = pdev->bus->sysdata;
 
 	if (desc->msi_attrib.is_msix)
 		return -EINVAL;
@@ -327,7 +321,7 @@ static void dw_msi_teardown_irq(struct msi_controller *chip, unsigned int irq)
 {
 	struct irq_data *data = irq_get_irq_data(irq);
 	struct msi_desc *msi = irq_data_get_msi(data);
-	struct pcie_port *pp = sys_to_pcie(msi->dev->bus->sysdata);
+	struct pcie_port *pp = msi->dev->bus->sysdata;
 
 	clear_irq_range(pp, irq, 1, data->hwirq);
 }
@@ -359,22 +353,17 @@ static const struct irq_domain_ops msi_domain_ops = {
 	.map = dw_pcie_msi_map,
 };
 
-int dw_pcie_host_init(struct pcie_port *pp)
+int __init dw_pcie_host_init(struct pcie_port *pp)
 {
 	struct device_node *np = pp->dev->of_node;
 	struct platform_device *pdev = to_platform_device(pp->dev);
-	struct of_pci_range range;
-	struct of_pci_range_parser parser;
+	struct pci_bus *bus;
 	struct resource *cfg_res;
-	u32 val, na, ns;
-	const __be32 *addrp;
-	int i, index, ret;
-
-	/* Find the address cell size and the number of cells in order to get
-	 * the untranslated address.
-	 */
-	of_property_read_u32(np, "#address-cells", &na);
-	ns = of_n_size_cells(np);
+	LIST_HEAD(res);
+	u32 val;
+	int i, ret;
+	struct resource_entry *win;
+	static int root_bus_nr = 0;
 
 	cfg_res = platform_get_resource_byname(pdev, IORESOURCE_MEM, "config");
 	if (cfg_res) {
@@ -382,85 +371,60 @@ int dw_pcie_host_init(struct pcie_port *pp)
 		pp->cfg1_size = resource_size(cfg_res)/2;
 		pp->cfg0_base = cfg_res->start;
 		pp->cfg1_base = cfg_res->start + pp->cfg0_size;
-
-		/* Find the untranslated configuration space address */
-		index = of_property_match_string(np, "reg-names", "config");
-		addrp = of_get_address(np, index, NULL, NULL);
-		pp->cfg0_mod_base = of_read_number(addrp, ns);
-		pp->cfg1_mod_base = pp->cfg0_mod_base + pp->cfg0_size;
 	} else {
 		dev_err(pp->dev, "missing *config* reg space\n");
 	}
 
-	if (of_pci_range_parser_init(&parser, np)) {
-		dev_err(pp->dev, "missing ranges property\n");
-		return -EINVAL;
-	}
+	ret = of_pci_get_host_bridge_resources(np, 0, 0xff, &res, &pp->io_base);
+	if (ret)
+		return ret;
 
 	/* Get the I/O and memory ranges from DT */
-	for_each_of_pci_range(&parser, &range) {
-		unsigned long restype = range.flags & IORESOURCE_TYPE_BITS;
-
-		if (restype == IORESOURCE_IO) {
-			of_pci_range_to_resource(&range, np, &pp->io);
-			pp->io.name = "I/O";
-			pp->io.start = max_t(resource_size_t,
-					     PCIBIOS_MIN_IO,
-					     range.pci_addr + global_io_offset);
-			pp->io.end = min_t(resource_size_t,
-					   IO_SPACE_LIMIT,
-					   range.pci_addr + range.size
-					   + global_io_offset - 1);
-			pp->io_size = resource_size(&pp->io);
-			pp->io_bus_addr = range.pci_addr;
-			pp->io_base = range.cpu_addr;
-
-			/* Find the untranslated IO space address */
-			pp->io_mod_base = range.cpu_addr;
-		}
-		if (restype == IORESOURCE_MEM) {
-			of_pci_range_to_resource(&range, np, &pp->mem);
-			pp->mem.name = "MEM";
-			pp->mem_size = resource_size(&pp->mem);
-			pp->mem_bus_addr = range.pci_addr;
-
-			/* Find the untranslated MEM space address */
-			pp->mem_mod_base = range.cpu_addr;
-		}
-		if (restype == 0) {
-			of_pci_range_to_resource(&range, np, &pp->cfg);
-			pp->cfg0_size = resource_size(&pp->cfg)/2;
-			pp->cfg1_size = resource_size(&pp->cfg)/2;
-			pp->cfg0_base = pp->cfg.start;
-			pp->cfg1_base = pp->cfg.start + pp->cfg0_size;
-
-			/* Find the untranslated configuration space address */
-			pp->cfg0_mod_base = range.cpu_addr;
-			pp->cfg1_mod_base = pp->cfg0_mod_base +
-					    pp->cfg0_size;
+	resource_list_for_each_entry(win, &res) {
+		switch (resource_type(win->res)) {
+		case IORESOURCE_IO:
+			pp->io = win->res;
+			pp->io->name = "I/O";
+			pp->io_size = resource_size(pp->io);
+			pp->io_bus_addr = pp->io->start - win->offset;
+			ret = pci_remap_iospace(pp->io, pp->io_base);
+			if (ret) {
+				dev_warn(pp->dev, "error %d: failed to map resource %pR\n",
+					 ret, pp->io);
+				continue;
+			}
+			break;
+		case IORESOURCE_MEM:
+			pp->mem = win->res;
+			pp->mem->name = "MEM";
+			pp->mem_size = resource_size(pp->mem);
+			pp->mem_bus_addr = pp->mem->start - win->offset;
+			break;
+		case 0:
+			pp->cfg = win->res;
+			pp->cfg0_size = resource_size(pp->cfg)/2;
+			pp->cfg1_size = resource_size(pp->cfg)/2;
+			pp->cfg0_base = pp->cfg->start;
+			pp->cfg1_base = pp->cfg->start + pp->cfg0_size;
+			break;
+		case IORESOURCE_BUS:
+			pp->busn = win->res;
+			break;
+		default:
+			continue;
 		}
 	}
 
-	ret = of_pci_parse_bus_range(np, &pp->busn);
-	if (ret < 0) {
-		pp->busn.name = np->name;
-		pp->busn.start = 0;
-		pp->busn.end = 0xff;
-		pp->busn.flags = IORESOURCE_BUS;
-		dev_dbg(pp->dev, "failed to parse bus-range property: %d, using default %pR\n",
-			ret, &pp->busn);
-	}
-
 	if (!pp->dbi_base) {
-		pp->dbi_base = devm_ioremap(pp->dev, pp->cfg.start,
-					resource_size(&pp->cfg));
+		pp->dbi_base = devm_ioremap(pp->dev, pp->cfg->start,
+					resource_size(pp->cfg));
 		if (!pp->dbi_base) {
 			dev_err(pp->dev, "error with ioremap\n");
 			return -ENOMEM;
 		}
 	}
 
-	pp->mem_base = pp->mem.start;
+	pp->mem_base = pp->mem->start;
 
 	if (!pp->va_cfg0_base) {
 		pp->va_cfg0_base = devm_ioremap(pp->dev, pp->cfg0_base,
@@ -509,7 +473,7 @@ int dw_pcie_host_init(struct pcie_port *pp)
 
 	if (!pp->ops->rd_other_conf)
 		dw_pcie_prog_outbound_atu(pp, PCIE_ATU_REGION_INDEX1,
-					  PCIE_ATU_TYPE_MEM, pp->mem_mod_base,
+					  PCIE_ATU_TYPE_MEM, pp->mem_base,
 					  pp->mem_bus_addr, pp->mem_size);
 
 	dw_pcie_wr_own_conf(pp, PCI_BASE_ADDRESS_0, 4, 0);
@@ -521,15 +485,40 @@ int dw_pcie_host_init(struct pcie_port *pp)
 	val |= PORT_LOGIC_SPEED_CHANGE;
 	dw_pcie_wr_own_conf(pp, PCIE_LINK_WIDTH_SPEED_CONTROL, 4, val);
 
-#ifdef CONFIG_PCI_MSI
 	dw_pcie_msi_chip.dev = pp->dev;
-	dw_pci.msi_ctrl = &dw_pcie_msi_chip;
+
+	mutex_lock(&root_bus_nr_mux);
+
+	if (pp->root_bus_nr != DW_ROOT_NR_UNDEFINED)
+		root_bus_nr = pp->root_bus_nr;
+
+	bus = pci_create_root_bus(pp->dev, root_bus_nr, &dw_pcie_ops,
+			      pp, &res);
+	if (!bus) {
+		mutex_unlock(&root_bus_nr_mux);
+		return -ENOMEM;
+	}
+
+	root_bus_nr += bus->busn_res.end + 1;
+	mutex_unlock(&root_bus_nr_mux);
+
+#ifdef CONFIG_GENERIC_MSI_IRQ_DOMAIN
+	bus->msi = container_of(&pp->irq_domain, struct msi_controller, domain);
+#else
+	bus->msi = &dw_pcie_msi_chip;
 #endif
 
-	dw_pci.nr_controllers = 1;
-	dw_pci.private_data = (void **)&pp;
+	pci_scan_child_bus(bus);
+	if (pp->ops->scan_bus)
+		pp->ops->scan_bus(pp);
+
+#ifdef CONFIG_ARM
+	/* support old dtbs that incorrectly describe IRQs */
+	pci_fixup_irqs(pci_common_swizzle, of_irq_parse_and_map_pci);
+#endif
 
-	pci_common_init_dev(pp->dev, &dw_pci);
+	pci_assign_unassigned_bus_resources(bus);
+	pci_bus_add_devices(bus);
 
 	return 0;
 }
@@ -548,12 +537,12 @@ static int dw_pcie_rd_other_conf(struct pcie_port *pp, struct pci_bus *bus,
 
 	if (bus->parent->number == pp->root_bus_nr) {
 		type = PCIE_ATU_TYPE_CFG0;
-		cpu_addr = pp->cfg0_mod_base;
+		cpu_addr = pp->cfg0_base;
 		cfg_size = pp->cfg0_size;
 		va_cfg_base = pp->va_cfg0_base;
 	} else {
 		type = PCIE_ATU_TYPE_CFG1;
-		cpu_addr = pp->cfg1_mod_base;
+		cpu_addr = pp->cfg1_base;
 		cfg_size = pp->cfg1_size;
 		va_cfg_base = pp->va_cfg1_base;
 	}
@@ -563,7 +552,7 @@ static int dw_pcie_rd_other_conf(struct pcie_port *pp, struct pci_bus *bus,
 				  busdev, cfg_size);
 	ret = dw_pcie_cfg_read(va_cfg_base + address, where, size, val);
 	dw_pcie_prog_outbound_atu(pp, PCIE_ATU_REGION_INDEX0,
-				  PCIE_ATU_TYPE_IO, pp->io_mod_base,
+				  PCIE_ATU_TYPE_IO, pp->io_base,
 				  pp->io_bus_addr, pp->io_size);
 
 	return ret;
@@ -583,12 +572,12 @@ static int dw_pcie_wr_other_conf(struct pcie_port *pp, struct pci_bus *bus,
 
 	if (bus->parent->number == pp->root_bus_nr) {
 		type = PCIE_ATU_TYPE_CFG0;
-		cpu_addr = pp->cfg0_mod_base;
+		cpu_addr = pp->cfg0_base;
 		cfg_size = pp->cfg0_size;
 		va_cfg_base = pp->va_cfg0_base;
 	} else {
 		type = PCIE_ATU_TYPE_CFG1;
-		cpu_addr = pp->cfg1_mod_base;
+		cpu_addr = pp->cfg1_base;
 		cfg_size = pp->cfg1_size;
 		va_cfg_base = pp->va_cfg1_base;
 	}
@@ -598,7 +587,7 @@ static int dw_pcie_wr_other_conf(struct pcie_port *pp, struct pci_bus *bus,
 				  busdev, cfg_size);
 	ret = dw_pcie_cfg_write(va_cfg_base + address, where, size, val);
 	dw_pcie_prog_outbound_atu(pp, PCIE_ATU_REGION_INDEX0,
-				  PCIE_ATU_TYPE_IO, pp->io_mod_base,
+				  PCIE_ATU_TYPE_IO, pp->io_base,
 				  pp->io_bus_addr, pp->io_size);
 
 	return ret;
@@ -630,7 +619,7 @@ static int dw_pcie_valid_config(struct pcie_port *pp,
 static int dw_pcie_rd_conf(struct pci_bus *bus, u32 devfn, int where,
 			int size, u32 *val)
 {
-	struct pcie_port *pp = sys_to_pcie(bus->sysdata);
+	struct pcie_port *pp = bus->sysdata;
 	int ret;
 
 	if (dw_pcie_valid_config(pp, bus, PCI_SLOT(devfn)) == 0) {
@@ -654,7 +643,7 @@ static int dw_pcie_rd_conf(struct pci_bus *bus, u32 devfn, int where,
 static int dw_pcie_wr_conf(struct pci_bus *bus, u32 devfn,
 			int where, int size, u32 val)
 {
-	struct pcie_port *pp = sys_to_pcie(bus->sysdata);
+	struct pcie_port *pp = bus->sysdata;
 	int ret;
 
 	if (dw_pcie_valid_config(pp, bus, PCI_SLOT(devfn)) == 0)
@@ -678,62 +667,6 @@ static struct pci_ops dw_pcie_ops = {
 	.write = dw_pcie_wr_conf,
 };
 
-static int dw_pcie_setup(int nr, struct pci_sys_data *sys)
-{
-	struct pcie_port *pp;
-
-	pp = sys_to_pcie(sys);
-
-	if (global_io_offset < SZ_1M && pp->io_size > 0) {
-		sys->io_offset = global_io_offset - pp->io_bus_addr;
-		pci_ioremap_io(global_io_offset, pp->io_base);
-		global_io_offset += SZ_64K;
-		pci_add_resource_offset(&sys->resources, &pp->io,
-					sys->io_offset);
-	}
-
-	sys->mem_offset = pp->mem.start - pp->mem_bus_addr;
-	pci_add_resource_offset(&sys->resources, &pp->mem, sys->mem_offset);
-	pci_add_resource(&sys->resources, &pp->busn);
-
-	return 1;
-}
-
-static struct pci_bus *dw_pcie_scan_bus(int nr, struct pci_sys_data *sys)
-{
-	struct pci_bus *bus;
-	struct pcie_port *pp = sys_to_pcie(sys);
-
-	pp->root_bus_nr = sys->busnr;
-	bus = pci_scan_root_bus(pp->dev, sys->busnr,
-				  &dw_pcie_ops, sys, &sys->resources);
-	if (!bus)
-		return NULL;
-
-	if (bus && pp->ops->scan_bus)
-		pp->ops->scan_bus(pp);
-
-	return bus;
-}
-
-static int dw_pcie_map_irq(const struct pci_dev *dev, u8 slot, u8 pin)
-{
-	struct pcie_port *pp = sys_to_pcie(dev->bus->sysdata);
-	int irq;
-
-	irq = of_irq_parse_and_map_pci(dev, slot, pin);
-	if (!irq)
-		irq = pp->irq;
-
-	return irq;
-}
-
-static struct hw_pci dw_pci = {
-	.setup		= dw_pcie_setup,
-	.scan		= dw_pcie_scan_bus,
-	.map_irq	= dw_pcie_map_irq,
-};
-
 void dw_pcie_setup_rc(struct pcie_port *pp)
 {
 	u32 val;
diff --git a/drivers/pci/host/pcie-designware.h b/drivers/pci/host/pcie-designware.h
index d0bbd27..0c2a7eb 100644
--- a/drivers/pci/host/pcie-designware.h
+++ b/drivers/pci/host/pcie-designware.h
@@ -21,31 +21,28 @@
  */
 #define MAX_MSI_IRQS			32
 #define MAX_MSI_CTRLS			(MAX_MSI_IRQS / 32)
+#define DW_ROOT_NR_UNDEFINED	-1
 
 struct pcie_port {
 	struct device		*dev;
 	u8			root_bus_nr;
 	void __iomem		*dbi_base;
 	u64			cfg0_base;
-	u64			cfg0_mod_base;
 	void __iomem		*va_cfg0_base;
 	u32			cfg0_size;
 	u64			cfg1_base;
-	u64			cfg1_mod_base;
 	void __iomem		*va_cfg1_base;
 	u32			cfg1_size;
-	u64			io_base;
-	u64			io_mod_base;
+	resource_size_t		io_base;
 	phys_addr_t		io_bus_addr;
 	u32			io_size;
 	u64			mem_base;
-	u64			mem_mod_base;
 	phys_addr_t		mem_bus_addr;
 	u32			mem_size;
-	struct resource		cfg;
-	struct resource		io;
-	struct resource		mem;
-	struct resource		busn;
+	struct resource		*cfg;
+	struct resource		*io;
+	struct resource		*mem;
+	struct resource		*busn;
 	int			irq;
 	u32			lanes;
 	struct pcie_host_ops	*ops;
diff --git a/drivers/pci/host/pcie-spear13xx.c b/drivers/pci/host/pcie-spear13xx.c
index c49fbdc..b2c59b9 100644
--- a/drivers/pci/host/pcie-spear13xx.c
+++ b/drivers/pci/host/pcie-spear13xx.c
@@ -286,7 +286,7 @@ static int spear13xx_add_pcie_port(struct pcie_port *pp,
 		return ret;
 	}
 
-	pp->root_bus_nr = -1;
+	pp->root_bus_nr = DW_ROOT_NR_UNDEFINED;
 	pp->ops = &spear13xx_pcie_host_ops;
 
 	ret = dw_pcie_host_init(pp);
-- 
1.9.1


> -----Original Message-----
> From: Lucas Stach [mailto:l.stach at pengutronix.de]
> Sent: Wednesday, August 19, 2015 1:54 PM
> To: Wangzhou (B)
> Cc: Bjorn Helgaas; jingoohan1 at gmail.com; Pratyush Anand; Arnd Bergmann;
> linux at arm.linux.org.uk; thomas.petazzoni at free-electrons.com; Gabriele
> Paoloni; lorenzo.pieralisi at arm.com; james.morse at arm.com;
> Liviu.Dudau at arm.com; jason at lakedaemon.net; robh at kernel.org; linux-
> pci at vger.kernel.org; linux-arm-kernel at lists.infradead.org;
> devicetree at vger.kernel.org; Yuanzhichang; Zhudacai; zhangjukuo;
> qiuzhenfa; liudongdong (C); qiujiang; xuwei (O); Liguozhu (Kenneth)
> Subject: Re: [PATCH v7 3/6] PCI: designware: Add ARM64 support
> 
> Am Montag, den 17.08.2015, 19:55 +0800 schrieb Zhou Wang:
> > This patch tries to unify ARM32 and ARM64 PCIe in designware driver.
> Delete
> > function dw_pcie_setup, dw_pcie_scan_bus, dw_pcie_map_irq and struct
> hw_pci,
> > move related operations to dw_pcie_host_init.
> >
> > In past, we use:
> > pci_common_init_dev
> > 	-> pcibios_init_hw
> > 		-> hw->scan (dw_pcie_scan_bus)
> > to pass 0 to root_bus_nr in struct pcie_port. This patch set pp-
> >root_bus_nr = 0
> > in each PCIe host driver which is based on pcie-designware.
> >
> This is incorrect at least if there are 2 instances of DW PCIe host in
> the same SoC without using PCI domains. In that the case the bus range
> determines the range of valid bus numbers per instance and the first
> number is the root bus. Please look at the "bus-range" DT property in
> the DW PCIe bindings.
> 
> Also we should finally remove this root-bus setup from the glue drivers
> altogether. It's something that entirely belongs into the DW core code.
> 
> Regards,
> Lucas
> 
> > This patch also try to use of_pci_get_host_bridge_resources for ARM32
> and ARM64
> > according to the suggestion for Gabriele[1]
> >
> > Finally this patch reverts commit f4c55c5a3f7f "PCI: designware:
> Program ATU
> > with untranslated address" based on 1/6 in this series. we delete
> *_mod_base in
> > pcie-designware. This was discussed in [2]
> >
> > I have compiled the driver with multi_v7_defconfig. However, I don't
> have
> > ARM32 PCIe related board to do test. It will be appreciated if
> someone could
> > help to test it.
> >
> > Signed-off-by: Zhou Wang <wangzhou1 at hisilicon.com>
> > Signed-off-by: Gabriele Paoloni <gabriele.paoloni at huawei.com>
> > Signed-off-by: Arnd Bergmann <arnd at arndb.de>
> > Tested-By: James Morse <james.morse at arm.com>
> >
> > [1] http://www.spinics.net/lists/linux-pci/msg42194.html
> > [2] http://www.spinics.net/lists/arm-kernel/msg436779.html
> > ---
> >  drivers/pci/host/pci-dra7xx.c      |  15 +--
> >  drivers/pci/host/pci-exynos.c      |   2 +-
> >  drivers/pci/host/pci-imx6.c        |   2 +-
> >  drivers/pci/host/pci-keystone-dw.c |   2 +-
> >  drivers/pci/host/pci-keystone.c    |   2 +-
> >  drivers/pci/host/pci-layerscape.c  |   2 +-
> >  drivers/pci/host/pcie-designware.c | 229 ++++++++++++---------------
> ----------
> >  drivers/pci/host/pcie-designware.h |  14 +--
> >  drivers/pci/host/pcie-spear13xx.c  |   2 +-
> >  9 files changed, 95 insertions(+), 175 deletions(-)
> >
> > diff --git a/drivers/pci/host/pci-dra7xx.c b/drivers/pci/host/pci-
> dra7xx.c
> > index 18ae7ff..1268c69 100644
> > --- a/drivers/pci/host/pci-dra7xx.c
> > +++ b/drivers/pci/host/pci-dra7xx.c
> > @@ -141,15 +141,15 @@ static void dra7xx_pcie_host_init(struct
> pcie_port *pp)
> >  {
> >  	dw_pcie_setup_rc(pp);
> >
> > -	if (pp->io_mod_base)
> > -		pp->io_mod_base &= CPU_TO_BUS_ADDR;
> > +	if (pp->io_base)
> > +		pp->io_base &= CPU_TO_BUS_ADDR;
> >
> > -	if (pp->mem_mod_base)
> > -		pp->mem_mod_base &= CPU_TO_BUS_ADDR;
> > +	if (pp->mem_base)
> > +		pp->mem_base &= CPU_TO_BUS_ADDR;
> >
> > -	if (pp->cfg0_mod_base) {
> > -		pp->cfg0_mod_base &= CPU_TO_BUS_ADDR;
> > -		pp->cfg1_mod_base &= CPU_TO_BUS_ADDR;
> > +	if (pp->cfg0_base) {
> > +		pp->cfg0_base &= CPU_TO_BUS_ADDR;
> > +		pp->cfg1_base &= CPU_TO_BUS_ADDR;
> >  	}
> >
> >  	dra7xx_pcie_establish_link(pp);
> > @@ -288,6 +288,7 @@ static int __init dra7xx_add_pcie_port(struct
> dra7xx_pcie *dra7xx,
> >
> >  	pp = &dra7xx->pp;
> >  	pp->dev = dev;
> > +	pp->root_bus_nr = 0;
> >  	pp->ops = &dra7xx_pcie_host_ops;
> >
> >  	pp->irq = platform_get_irq(pdev, 1);
> > diff --git a/drivers/pci/host/pci-exynos.c b/drivers/pci/host/pci-
> exynos.c
> > index f9f468d..9771bb0 100644
> > --- a/drivers/pci/host/pci-exynos.c
> > +++ b/drivers/pci/host/pci-exynos.c
> > @@ -530,7 +530,7 @@ static int __init exynos_add_pcie_port(struct
> pcie_port *pp,
> >  		}
> >  	}
> >
> > -	pp->root_bus_nr = -1;
> > +	pp->root_bus_nr = 0;
> >  	pp->ops = &exynos_pcie_host_ops;
> >
> >  	ret = dw_pcie_host_init(pp);
> > diff --git a/drivers/pci/host/pci-imx6.c b/drivers/pci/host/pci-
> imx6.c
> > index 233a196..bec256c 100644
> > --- a/drivers/pci/host/pci-imx6.c
> > +++ b/drivers/pci/host/pci-imx6.c
> > @@ -551,7 +551,7 @@ static int __init imx6_add_pcie_port(struct
> pcie_port *pp,
> >  		}
> >  	}
> >
> > -	pp->root_bus_nr = -1;
> > +	pp->root_bus_nr = 0;
> >  	pp->ops = &imx6_pcie_host_ops;
> >
> >  	ret = dw_pcie_host_init(pp);
> > diff --git a/drivers/pci/host/pci-keystone-dw.c
> b/drivers/pci/host/pci-keystone-dw.c
> > index f34892e..b1e4135 100644
> > --- a/drivers/pci/host/pci-keystone-dw.c
> > +++ b/drivers/pci/host/pci-keystone-dw.c
> > @@ -327,7 +327,7 @@ static void ks_dw_pcie_clear_dbi_mode(void
> __iomem *reg_virt)
> >  void ks_dw_pcie_setup_rc_app_regs(struct keystone_pcie *ks_pcie)
> >  {
> >  	struct pcie_port *pp = &ks_pcie->pp;
> > -	u32 start = pp->mem.start, end = pp->mem.end;
> > +	u32 start = pp->mem->start, end = pp->mem->end;
> >  	int i, tr_size;
> >
> >  	/* Disable BARs for inbound access */
> > diff --git a/drivers/pci/host/pci-keystone.c b/drivers/pci/host/pci-
> keystone.c
> > index 734da58..8113832 100644
> > --- a/drivers/pci/host/pci-keystone.c
> > +++ b/drivers/pci/host/pci-keystone.c
> > @@ -309,7 +309,7 @@ static int __init ks_add_pcie_port(struct
> keystone_pcie *ks_pcie,
> >  			return ret;
> >  	}
> >
> > -	pp->root_bus_nr = -1;
> > +	pp->root_bus_nr = 0;
> >  	pp->ops = &keystone_pcie_host_ops;
> >  	ret = ks_dw_pcie_host_init(ks_pcie, ks_pcie->msi_intc_np);
> >  	if (ret) {
> > diff --git a/drivers/pci/host/pci-layerscape.c
> b/drivers/pci/host/pci-layerscape.c
> > index b2328ea1..79ff08c 100644
> > --- a/drivers/pci/host/pci-layerscape.c
> > +++ b/drivers/pci/host/pci-layerscape.c
> > @@ -106,7 +106,7 @@ static int ls_add_pcie_port(struct ls_pcie *pcie)
> >  	pp = &pcie->pp;
> >  	pp->dev = pcie->dev;
> >  	pp->dbi_base = pcie->dbi;
> > -	pp->root_bus_nr = -1;
> > +	pp->root_bus_nr = 0;
> >  	pp->ops = &ls_pcie_host_ops;
> >
> >  	ret = dw_pcie_host_init(pp);
> > diff --git a/drivers/pci/host/pcie-designware.c
> b/drivers/pci/host/pcie-designware.c
> > index c5d407c..e71a88e 100644
> > --- a/drivers/pci/host/pcie-designware.c
> > +++ b/drivers/pci/host/pcie-designware.c
> > @@ -11,6 +11,7 @@
> >   * published by the Free Software Foundation.
> >   */
> >
> > +#include <linux/hardirq.h>
> >  #include <linux/irq.h>
> >  #include <linux/irqdomain.h>
> >  #include <linux/kernel.h>
> > @@ -69,16 +70,7 @@
> >  #define PCIE_ATU_FUNC(x)		(((x) & 0x7) << 16)
> >  #define PCIE_ATU_UPPER_TARGET		0x91C
> >
> > -static struct hw_pci dw_pci;
> > -
> > -static unsigned long global_io_offset;
> > -
> > -static inline struct pcie_port *sys_to_pcie(struct pci_sys_data *sys)
> > -{
> > -	BUG_ON(!sys->private_data);
> > -
> > -	return sys->private_data;
> > -}
> > +static struct pci_ops dw_pcie_ops;
> >
> >  int dw_pcie_cfg_read(void __iomem *addr, int where, int size, u32
> *val)
> >  {
> > @@ -255,7 +247,7 @@ static void dw_pcie_msi_set_irq(struct pcie_port
> *pp, int irq)
> >  static int assign_irq(int no_irqs, struct msi_desc *desc, int *pos)
> >  {
> >  	int irq, pos0, i;
> > -	struct pcie_port *pp = sys_to_pcie(desc->dev->bus->sysdata);
> > +	struct pcie_port *pp = desc->dev->bus->sysdata;
> >
> >  	pos0 = bitmap_find_free_region(pp->msi_irq_in_use, MAX_MSI_IRQS,
> >  				       order_base_2(no_irqs));
> > @@ -298,7 +290,7 @@ static int dw_msi_setup_irq(struct msi_controller
> *chip, struct pci_dev *pdev,
> >  {
> >  	int irq, pos;
> >  	struct msi_msg msg;
> > -	struct pcie_port *pp = sys_to_pcie(pdev->bus->sysdata);
> > +	struct pcie_port *pp = pdev->bus->sysdata;
> >
> >  	if (desc->msi_attrib.is_msix)
> >  		return -EINVAL;
> > @@ -327,7 +319,7 @@ static void dw_msi_teardown_irq(struct
> msi_controller *chip, unsigned int irq)
> >  {
> >  	struct irq_data *data = irq_get_irq_data(irq);
> >  	struct msi_desc *msi = irq_data_get_msi(data);
> > -	struct pcie_port *pp = sys_to_pcie(msi->dev->bus->sysdata);
> > +	struct pcie_port *pp = msi->dev->bus->sysdata;
> >
> >  	clear_irq_range(pp, irq, 1, data->hwirq);
> >  }
> > @@ -363,14 +355,12 @@ int dw_pcie_host_init(struct pcie_port *pp)
> >  {
> >  	struct device_node *np = pp->dev->of_node;
> >  	struct platform_device *pdev = to_platform_device(pp->dev);
> > -	struct of_pci_range range;
> > -	struct of_pci_range_parser parser;
> > +	struct pci_bus *bus;
> >  	struct resource *cfg_res;
> > -	u32 val, ns;
> > -	const __be32 *addrp;
> > -	int i, index, ret;
> > -
> > -	ns = of_n_size_cells(np);
> > +	LIST_HEAD(res);
> > +	u32 val;
> > +	int i, ret;
> > +	struct resource_entry *win;
> >
> >  	cfg_res = platform_get_resource_byname(pdev, IORESOURCE_MEM,
> "config");
> >  	if (cfg_res) {
> > @@ -378,85 +368,60 @@ int dw_pcie_host_init(struct pcie_port *pp)
> >  		pp->cfg1_size = resource_size(cfg_res)/2;
> >  		pp->cfg0_base = cfg_res->start;
> >  		pp->cfg1_base = cfg_res->start + pp->cfg0_size;
> > -
> > -		/* Find the untranslated configuration space address */
> > -		index = of_property_match_string(np, "reg-names", "config");
> > -		addrp = of_get_address(np, index, NULL, NULL);
> > -		pp->cfg0_mod_base = of_read_number(addrp, ns);
> > -		pp->cfg1_mod_base = pp->cfg0_mod_base + pp->cfg0_size;
> >  	} else {
> >  		dev_err(pp->dev, "missing *config* reg space\n");
> >  	}
> >
> > -	if (of_pci_range_parser_init(&parser, np)) {
> > -		dev_err(pp->dev, "missing ranges property\n");
> > -		return -EINVAL;
> > -	}
> > +	ret = of_pci_get_host_bridge_resources(np, 0, 0xff, &res, &pp-
> >io_base);
> > +	if (ret)
> > +		return ret;
> >
> >  	/* Get the I/O and memory ranges from DT */
> > -	for_each_of_pci_range(&parser, &range) {
> > -		unsigned long restype = range.flags & IORESOURCE_TYPE_BITS;
> > -
> > -		if (restype == IORESOURCE_IO) {
> > -			of_pci_range_to_resource(&range, np, &pp->io);
> > -			pp->io.name = "I/O";
> > -			pp->io.start = max_t(resource_size_t,
> > -					     PCIBIOS_MIN_IO,
> > -					     range.pci_addr + global_io_offset);
> > -			pp->io.end = min_t(resource_size_t,
> > -					   IO_SPACE_LIMIT,
> > -					   range.pci_addr + range.size
> > -					   + global_io_offset - 1);
> > -			pp->io_size = resource_size(&pp->io);
> > -			pp->io_bus_addr = range.pci_addr;
> > -			pp->io_base = range.cpu_addr;
> > -
> > -			/* Find the untranslated IO space address */
> > -			pp->io_mod_base = range.cpu_addr;
> > -		}
> > -		if (restype == IORESOURCE_MEM) {
> > -			of_pci_range_to_resource(&range, np, &pp->mem);
> > -			pp->mem.name = "MEM";
> > -			pp->mem_size = resource_size(&pp->mem);
> > -			pp->mem_bus_addr = range.pci_addr;
> > -
> > -			/* Find the untranslated MEM space address */
> > -			pp->mem_mod_base = range.cpu_addr;
> > -		}
> > -		if (restype == 0) {
> > -			of_pci_range_to_resource(&range, np, &pp->cfg);
> > -			pp->cfg0_size = resource_size(&pp->cfg)/2;
> > -			pp->cfg1_size = resource_size(&pp->cfg)/2;
> > -			pp->cfg0_base = pp->cfg.start;
> > -			pp->cfg1_base = pp->cfg.start + pp->cfg0_size;
> > -
> > -			/* Find the untranslated configuration space address
> */
> > -			pp->cfg0_mod_base = range.cpu_addr;
> > -			pp->cfg1_mod_base = pp->cfg0_mod_base +
> > -					    pp->cfg0_size;
> > +	resource_list_for_each_entry(win, &res) {
> > +		switch (resource_type(win->res)) {
> > +		case IORESOURCE_IO:
> > +			pp->io = win->res;
> > +			pp->io->name = "I/O";
> > +			pp->io_size = resource_size(pp->io);
> > +			pp->io_bus_addr = pp->io->start - win->offset;
> > +			ret = pci_remap_iospace(pp->io, pp->io_base);
> > +			if (ret) {
> > +				dev_warn(pp->dev, "error %d: failed to map
> resource %pR\n",
> > +					 ret, pp->io);
> > +				continue;
> > +			}
> > +			break;
> > +		case IORESOURCE_MEM:
> > +			pp->mem = win->res;
> > +			pp->mem->name = "MEM";
> > +			pp->mem_size = resource_size(pp->mem);
> > +			pp->mem_bus_addr = pp->mem->start - win->offset;
> > +			break;
> > +		case 0:
> > +			pp->cfg = win->res;
> > +			pp->cfg0_size = resource_size(pp->cfg)/2;
> > +			pp->cfg1_size = resource_size(pp->cfg)/2;
> > +			pp->cfg0_base = pp->cfg->start;
> > +			pp->cfg1_base = pp->cfg->start + pp->cfg0_size;
> > +			break;
> > +		case IORESOURCE_BUS:
> > +			pp->busn = win->res;
> > +			break;
> > +		default:
> > +			continue;
> >  		}
> >  	}
> >
> > -	ret = of_pci_parse_bus_range(np, &pp->busn);
> > -	if (ret < 0) {
> > -		pp->busn.name = np->name;
> > -		pp->busn.start = 0;
> > -		pp->busn.end = 0xff;
> > -		pp->busn.flags = IORESOURCE_BUS;
> > -		dev_dbg(pp->dev, "failed to parse bus-range property: %d,
> using default %pR\n",
> > -			ret, &pp->busn);
> > -	}
> > -
> >  	if (!pp->dbi_base) {
> > -		pp->dbi_base = devm_ioremap(pp->dev, pp->cfg.start,
> > -					resource_size(&pp->cfg));
> > +		pp->dbi_base = devm_ioremap(pp->dev, pp->cfg->start,
> > +					resource_size(pp->cfg));
> >  		if (!pp->dbi_base) {
> >  			dev_err(pp->dev, "error with ioremap\n");
> >  			return -ENOMEM;
> >  		}
> >  	}
> >
> > -	pp->mem_base = pp->mem.start;
> > +	pp->mem_base = pp->mem->start;
> >
> >  	if (!pp->va_cfg0_base) {
> >  		pp->va_cfg0_base = devm_ioremap(pp->dev, pp->cfg0_base,
> > @@ -505,7 +470,7 @@ int dw_pcie_host_init(struct pcie_port *pp)
> >
> >  	if (!pp->ops->rd_other_conf)
> >  		dw_pcie_prog_outbound_atu(pp, PCIE_ATU_REGION_INDEX1,
> > -					  PCIE_ATU_TYPE_MEM, pp->mem_mod_base,
> > +					  PCIE_ATU_TYPE_MEM, pp->mem_base,
> >  					  pp->mem_bus_addr, pp->mem_size);
> >
> >  	dw_pcie_wr_own_conf(pp, PCI_BASE_ADDRESS_0, 4, 0);
> > @@ -517,15 +482,29 @@ int dw_pcie_host_init(struct pcie_port *pp)
> >  	val |= PORT_LOGIC_SPEED_CHANGE;
> >  	dw_pcie_wr_own_conf(pp, PCIE_LINK_WIDTH_SPEED_CONTROL, 4, val);
> >
> > -#ifdef CONFIG_PCI_MSI
> > +	bus = pci_create_root_bus(pp->dev, pp->root_bus_nr, &dw_pcie_ops,
> > +				  pp, &res);
> > +	if (!bus)
> > +		return -ENOMEM;
> > +
> > +#ifdef CONFIG_GENERIC_MSI_IRQ_DOMAIN
> > +	bus->msi = container_of(&pp->irq_domain, struct msi_controller,
> domain);
> > +#else
> >  	dw_pcie_msi_chip.dev = pp->dev;
> > -	dw_pci.msi_ctrl = &dw_pcie_msi_chip;
> > +	bus->msi = &dw_pcie_msi_chip;
> >  #endif
> >
> > -	dw_pci.nr_controllers = 1;
> > -	dw_pci.private_data = (void **)&pp;
> > +	pci_scan_child_bus(bus);
> > +	if (pp->ops->scan_bus)
> > +		pp->ops->scan_bus(pp);
> > +
> > +#ifdef CONFIG_ARM
> > +	/* support old dtbs that incorrectly describe IRQs */
> > +	pci_fixup_irqs(pci_common_swizzle, of_irq_parse_and_map_pci);
> > +#endif
> >
> > -	pci_common_init_dev(pp->dev, &dw_pci);
> > +	pci_assign_unassigned_bus_resources(bus);
> > +	pci_bus_add_devices(bus);
> >
> >  	return 0;
> >  }
> > @@ -544,12 +523,12 @@ static int dw_pcie_rd_other_conf(struct
> pcie_port *pp, struct pci_bus *bus,
> >
> >  	if (bus->parent->number == pp->root_bus_nr) {
> >  		type = PCIE_ATU_TYPE_CFG0;
> > -		cpu_addr = pp->cfg0_mod_base;
> > +		cpu_addr = pp->cfg0_base;
> >  		cfg_size = pp->cfg0_size;
> >  		va_cfg_base = pp->va_cfg0_base;
> >  	} else {
> >  		type = PCIE_ATU_TYPE_CFG1;
> > -		cpu_addr = pp->cfg1_mod_base;
> > +		cpu_addr = pp->cfg1_base;
> >  		cfg_size = pp->cfg1_size;
> >  		va_cfg_base = pp->va_cfg1_base;
> >  	}
> > @@ -559,7 +538,7 @@ static int dw_pcie_rd_other_conf(struct pcie_port
> *pp, struct pci_bus *bus,
> >  				  busdev, cfg_size);
> >  	ret = dw_pcie_cfg_read(va_cfg_base + address, where, size, val);
> >  	dw_pcie_prog_outbound_atu(pp, PCIE_ATU_REGION_INDEX0,
> > -				  PCIE_ATU_TYPE_IO, pp->io_mod_base,
> > +				  PCIE_ATU_TYPE_IO, pp->io_base,
> >  				  pp->io_bus_addr, pp->io_size);
> >
> >  	return ret;
> > @@ -579,12 +558,12 @@ static int dw_pcie_wr_other_conf(struct
> pcie_port *pp, struct pci_bus *bus,
> >
> >  	if (bus->parent->number == pp->root_bus_nr) {
> >  		type = PCIE_ATU_TYPE_CFG0;
> > -		cpu_addr = pp->cfg0_mod_base;
> > +		cpu_addr = pp->cfg0_base;
> >  		cfg_size = pp->cfg0_size;
> >  		va_cfg_base = pp->va_cfg0_base;
> >  	} else {
> >  		type = PCIE_ATU_TYPE_CFG1;
> > -		cpu_addr = pp->cfg1_mod_base;
> > +		cpu_addr = pp->cfg1_base;
> >  		cfg_size = pp->cfg1_size;
> >  		va_cfg_base = pp->va_cfg1_base;
> >  	}
> > @@ -594,7 +573,7 @@ static int dw_pcie_wr_other_conf(struct pcie_port
> *pp, struct pci_bus *bus,
> >  				  busdev, cfg_size);
> >  	ret = dw_pcie_cfg_write(va_cfg_base + address, where, size, val);
> >  	dw_pcie_prog_outbound_atu(pp, PCIE_ATU_REGION_INDEX0,
> > -				  PCIE_ATU_TYPE_IO, pp->io_mod_base,
> > +				  PCIE_ATU_TYPE_IO, pp->io_base,
> >  				  pp->io_bus_addr, pp->io_size);
> >
> >  	return ret;
> > @@ -626,7 +605,7 @@ static int dw_pcie_valid_config(struct pcie_port
> *pp,
> >  static int dw_pcie_rd_conf(struct pci_bus *bus, u32 devfn, int where,
> >  			int size, u32 *val)
> >  {
> > -	struct pcie_port *pp = sys_to_pcie(bus->sysdata);
> > +	struct pcie_port *pp = bus->sysdata;
> >  	int ret;
> >
> >  	if (dw_pcie_valid_config(pp, bus, PCI_SLOT(devfn)) == 0) {
> > @@ -650,7 +629,7 @@ static int dw_pcie_rd_conf(struct pci_bus *bus,
> u32 devfn, int where,
> >  static int dw_pcie_wr_conf(struct pci_bus *bus, u32 devfn,
> >  			int where, int size, u32 val)
> >  {
> > -	struct pcie_port *pp = sys_to_pcie(bus->sysdata);
> > +	struct pcie_port *pp = bus->sysdata;
> >  	int ret;
> >
> >  	if (dw_pcie_valid_config(pp, bus, PCI_SLOT(devfn)) == 0)
> > @@ -674,62 +653,6 @@ static struct pci_ops dw_pcie_ops = {
> >  	.write = dw_pcie_wr_conf,
> >  };
> >
> > -static int dw_pcie_setup(int nr, struct pci_sys_data *sys)
> > -{
> > -	struct pcie_port *pp;
> > -
> > -	pp = sys_to_pcie(sys);
> > -
> > -	if (global_io_offset < SZ_1M && pp->io_size > 0) {
> > -		sys->io_offset = global_io_offset - pp->io_bus_addr;
> > -		pci_ioremap_io(global_io_offset, pp->io_base);
> > -		global_io_offset += SZ_64K;
> > -		pci_add_resource_offset(&sys->resources, &pp->io,
> > -					sys->io_offset);
> > -	}
> > -
> > -	sys->mem_offset = pp->mem.start - pp->mem_bus_addr;
> > -	pci_add_resource_offset(&sys->resources, &pp->mem, sys-
> >mem_offset);
> > -	pci_add_resource(&sys->resources, &pp->busn);
> > -
> > -	return 1;
> > -}
> > -
> > -static struct pci_bus *dw_pcie_scan_bus(int nr, struct pci_sys_data
> *sys)
> > -{
> > -	struct pci_bus *bus;
> > -	struct pcie_port *pp = sys_to_pcie(sys);
> > -
> > -	pp->root_bus_nr = sys->busnr;
> > -	bus = pci_scan_root_bus(pp->dev, sys->busnr,
> > -				  &dw_pcie_ops, sys, &sys->resources);
> > -	if (!bus)
> > -		return NULL;
> > -
> > -	if (bus && pp->ops->scan_bus)
> > -		pp->ops->scan_bus(pp);
> > -
> > -	return bus;
> > -}
> > -
> > -static int dw_pcie_map_irq(const struct pci_dev *dev, u8 slot, u8
> pin)
> > -{
> > -	struct pcie_port *pp = sys_to_pcie(dev->bus->sysdata);
> > -	int irq;
> > -
> > -	irq = of_irq_parse_and_map_pci(dev, slot, pin);
> > -	if (!irq)
> > -		irq = pp->irq;
> > -
> > -	return irq;
> > -}
> > -
> > -static struct hw_pci dw_pci = {
> > -	.setup		= dw_pcie_setup,
> > -	.scan		= dw_pcie_scan_bus,
> > -	.map_irq	= dw_pcie_map_irq,
> > -};
> > -
> >  void dw_pcie_setup_rc(struct pcie_port *pp)
> >  {
> >  	u32 val;
> > diff --git a/drivers/pci/host/pcie-designware.h
> b/drivers/pci/host/pcie-designware.h
> > index d0bbd27..264c969 100644
> > --- a/drivers/pci/host/pcie-designware.h
> > +++ b/drivers/pci/host/pcie-designware.h
> > @@ -27,25 +27,21 @@ struct pcie_port {
> >  	u8			root_bus_nr;
> >  	void __iomem		*dbi_base;
> >  	u64			cfg0_base;
> > -	u64			cfg0_mod_base;
> >  	void __iomem		*va_cfg0_base;
> >  	u32			cfg0_size;
> >  	u64			cfg1_base;
> > -	u64			cfg1_mod_base;
> >  	void __iomem		*va_cfg1_base;
> >  	u32			cfg1_size;
> > -	u64			io_base;
> > -	u64			io_mod_base;
> > +	resource_size_t		io_base;
> >  	phys_addr_t		io_bus_addr;
> >  	u32			io_size;
> >  	u64			mem_base;
> > -	u64			mem_mod_base;
> >  	phys_addr_t		mem_bus_addr;
> >  	u32			mem_size;
> > -	struct resource		cfg;
> > -	struct resource		io;
> > -	struct resource		mem;
> > -	struct resource		busn;
> > +	struct resource		*cfg;
> > +	struct resource		*io;
> > +	struct resource		*mem;
> > +	struct resource		*busn;
> >  	int			irq;
> >  	u32			lanes;
> >  	struct pcie_host_ops	*ops;
> > diff --git a/drivers/pci/host/pcie-spear13xx.c
> b/drivers/pci/host/pcie-spear13xx.c
> > index c49fbdc..03eb204 100644
> > --- a/drivers/pci/host/pcie-spear13xx.c
> > +++ b/drivers/pci/host/pcie-spear13xx.c
> > @@ -286,7 +286,7 @@ static int spear13xx_add_pcie_port(struct
> pcie_port *pp,
> >  		return ret;
> >  	}
> >
> > -	pp->root_bus_nr = -1;
> > +	pp->root_bus_nr = 0;
> >  	pp->ops = &spear13xx_pcie_host_ops;
> >
> >  	ret = dw_pcie_host_init(pp);
> 
> --
> Pengutronix e.K.             | Lucas Stach                 |
> Industrial Linux Solutions   | http://www.pengutronix.de/  |


From wsa at the-dreams.de  Wed Aug 19 08:18:40 2015
From: wsa at the-dreams.de (Wolfram Sang)
Date: Wed, 19 Aug 2015 17:18:40 +0200
Subject: [PATCH v2 0/2] I2C support for NXP LPC18xx family
In-Reply-To: <1439748617-7683-1-git-send-email-manabian@gmail.com>
References: <1439748617-7683-1-git-send-email-manabian@gmail.com>
Message-ID: <20150819151838.GC1634@katana>

On Sun, Aug 16, 2015 at 08:10:15PM +0200, Joachim Eastwood wrote:
> This patch set adds a I2C driver and documentation for the I2C
> peripheral found on many NXP LPC MCUs.
> 
> The driver is a rework of an old driver by Kevin Wells. It has been
> modified to support modern resource allocation, device tree and
> generally cleaned up. Driver was originally written to support the
> LPC2xxx platforms.
> 
> Patches based on i2c/for-next and tested on Embedded Artists' LPC4357
> Dev Kit and Hitex LPC4350 Eval board with several I2C devices.
> 
> This version address comments from Wolfram Sang.
> 
> Changes since v1:
>  - remove dev_dbg() leftovers from development/debugging
>  - use i2c_add_adapter
>  - change return value on NACK and arb lost
>    (I think all the others should be okay as they are)
>  - fix 80 char warnings (involved s/reg_base/base)
>  - rebase on i2c/for-next
> 
> Joachim Eastwood (2):
>   i2c: add i2c-lpc2k driver
>   doc: dt: add documentation for nxp,lpc1788-i2c

Applied to for-next, thanks!

Changes regarding readl_poll_timeout() can be sent incrementally.



From wens at csie.org  Wed Aug 19 08:29:22 2015
From: wens at csie.org (Chen-Yu Tsai)
Date: Wed, 19 Aug 2015 23:29:22 +0800
Subject: [linux-sunxi] Re: [PATCH 2/3] ARM: dts: sun6i: Turn on gmac on
 Colombus
In-Reply-To: <20150819151754.GH30520@lukather>
References: <1438960955-6551-1-git-send-email-hdegoede@redhat.com>
 <1438960955-6551-2-git-send-email-hdegoede@redhat.com>
 <20150819151754.GH30520@lukather>
Message-ID: <CAGb2v64gqDfV_s2Q1CmSD51m+LC1krgJMtSxT4a1rvTmTUncaw@mail.gmail.com>

On Wed, Aug 19, 2015 at 11:17 PM, Maxime Ripard
<maxime.ripard at free-electrons.com> wrote:
> On Fri, Aug 07, 2015 at 05:22:34PM +0200, Hans de Goede wrote:
>> We've everything we need to support the gmac on Colombus, turn it on.
>>
>> Signed-off-by: Hans de Goede <hdegoede at redhat.com>
>
> I recall that the phy was powered by one of the AXP221 regulators,
> does it require some additional stuff (like a recent u-boot), or does
> it just work and my memory is bad :) ?

I sort of remember that as well.

FYI i have a patch to add axp221.dtsi, though I haven't converted
the hummingbird dts yet.

ChenYu


From manabian at gmail.com  Wed Aug 19 08:30:24 2015
From: manabian at gmail.com (Joachim Eastwood)
Date: Wed, 19 Aug 2015 17:30:24 +0200
Subject: [PATCH v2 0/2] I2C support for NXP LPC18xx family
In-Reply-To: <20150819151838.GC1634@katana>
References: <1439748617-7683-1-git-send-email-manabian@gmail.com>
 <20150819151838.GC1634@katana>
Message-ID: <CAGhQ9VxEOMg7hG=L4A9QZLQOfZQgtBhgs2PH1zajxqbrZpi3Wg@mail.gmail.com>

On 19 August 2015 at 17:18, Wolfram Sang <wsa at the-dreams.de> wrote:
> On Sun, Aug 16, 2015 at 08:10:15PM +0200, Joachim Eastwood wrote:
>> This patch set adds a I2C driver and documentation for the I2C
>> peripheral found on many NXP LPC MCUs.
>>
>> The driver is a rework of an old driver by Kevin Wells. It has been
>> modified to support modern resource allocation, device tree and
>> generally cleaned up. Driver was originally written to support the
>> LPC2xxx platforms.
>>
>> Patches based on i2c/for-next and tested on Embedded Artists' LPC4357
>> Dev Kit and Hitex LPC4350 Eval board with several I2C devices.
>>
>> This version address comments from Wolfram Sang.
>>
>> Changes since v1:
>>  - remove dev_dbg() leftovers from development/debugging
>>  - use i2c_add_adapter
>>  - change return value on NACK and arb lost
>>    (I think all the others should be okay as they are)
>>  - fix 80 char warnings (involved s/reg_base/base)
>>  - rebase on i2c/for-next
>>
>> Joachim Eastwood (2):
>>   i2c: add i2c-lpc2k driver
>>   doc: dt: add documentation for nxp,lpc1788-i2c
>
> Applied to for-next, thanks!

Thanks, Wolfram.

> Changes regarding readl_poll_timeout() can be sent incrementally.

Got it. I'll see if I can figure out a way to test the code path properly.

regards,
Joachim Eastwood


From javier at osg.samsung.com  Wed Aug 19 08:35:18 2015
From: javier at osg.samsung.com (Javier Martinez Canillas)
Date: Wed, 19 Aug 2015 17:35:18 +0200
Subject: [PATCH 0/4] [media] Media entity cleanups and build fixes
Message-ID: <1439998526-12832-1-git-send-email-javier@osg.samsung.com>

Hello,

This series contains a couple of build fixes and cleanups for the
Media Controller framework. The goal of the series is to get rid of
the struct media_entity .parent member since now that a media_gobj is
embedded into entities, the media_gobj .mdev member can be used to
store a pointer to the parent struct media_device.

So the .parent field becomes redundant and can be removed after all
the users are converted to use entity .graph_obj.mdev instead.

Patches 1/4 and 2/4 are build fixes I found while build testing if no
regressions were introduced by the conversion. Patch 3/4 converts
all the drivers and the MC core to use .mdev instead of .parent and
finally patch 4/4 removes the .parent field since now is unused.

The series depend on Mauro's "[PATCH v6 0/8] MC preparation patches
series" [0].

The transformation were automated using a coccinelle semantic patch
and the drivers were build tested using allyesconfig and x-building
the ARM Exynos and OMAP defconfigs + the needed media config options.

Best regards,
Javier

[0]: http://www.mail-archive.com/linux-media at vger.kernel.org/msg91330.html


Javier Martinez Canillas (4):
  [media] staging: omap4iss: get entity ID using media_entity_id()
  [media] omap3isp: get entity ID using media_entity_id()
  [media] media: use entity.graph_obj.mdev instead of .parent
  [media] media: remove media entity .parent field

 drivers/media/media-device.c                       |  8 ++---
 drivers/media/media-entity.c                       | 34 ++++++++++++----------
 drivers/media/platform/exynos4-is/fimc-isp-video.c |  6 ++--
 drivers/media/platform/exynos4-is/fimc-lite.c      |  8 ++---
 drivers/media/platform/exynos4-is/media-dev.c      |  2 +-
 drivers/media/platform/exynos4-is/media-dev.h      |  8 ++---
 drivers/media/platform/omap3isp/isp.c              | 11 ++++---
 drivers/media/platform/omap3isp/ispccdc.c          |  2 +-
 drivers/media/platform/omap3isp/ispvideo.c         | 10 ++++---
 drivers/media/platform/vsp1/vsp1_video.c           |  2 +-
 drivers/media/platform/xilinx/xilinx-dma.c         |  2 +-
 drivers/staging/media/davinci_vpfe/vpfe_video.c    |  6 ++--
 drivers/staging/media/omap4iss/iss.c               |  6 ++--
 drivers/staging/media/omap4iss/iss_video.c         |  4 +--
 include/media/media-entity.h                       |  1 -
 15 files changed, 58 insertions(+), 52 deletions(-)

-- 
2.4.3



From javier at osg.samsung.com  Wed Aug 19 08:35:21 2015
From: javier at osg.samsung.com (Javier Martinez Canillas)
Date: Wed, 19 Aug 2015 17:35:21 +0200
Subject: [PATCH 3/4] [media] media: use entity.graph_obj.mdev instead of
 .parent
In-Reply-To: <1439998526-12832-1-git-send-email-javier@osg.samsung.com>
References: <1439998526-12832-1-git-send-email-javier@osg.samsung.com>
Message-ID: <1439998526-12832-4-git-send-email-javier@osg.samsung.com>

The struct media_entity has a .parent field that stores a pointer
to the parent struct media_device. But recently a media_gobj was
embedded into the entities and since struct media_gojb already has
a pointer to a struct media_device in the .mdev field, the .parent
field becomes redundant and can be removed.

This patch replaces all the usage of .parent by .graph_obj.mdev so
that field will become unused and can be removed on a later patch.

No functional changes.

The transformation was made using the following coccinelle spatch:

@@
struct media_entity *me;
@@

- me->parent
+ me->graph_obj.mdev

@@
struct media_entity *link;
@@

- link->source->entity->parent
+ link->source->entity->graph_obj.mdev

@@
struct exynos_video_entity *ve;
@@

- ve->vdev.entity.parent
+ ve->vdev.entity.graph_obj.mdev

Suggested-by: Mauro Carvalho Chehab <mchehab at osg.samsung.com>
Signed-off-by: Javier Martinez Canillas <javier at osg.samsung.com>
---

 drivers/media/media-device.c                       |  8 ++---
 drivers/media/media-entity.c                       | 34 ++++++++++++----------
 drivers/media/platform/exynos4-is/fimc-isp-video.c |  6 ++--
 drivers/media/platform/exynos4-is/fimc-lite.c      |  8 ++---
 drivers/media/platform/exynos4-is/media-dev.c      |  2 +-
 drivers/media/platform/exynos4-is/media-dev.h      |  8 ++---
 drivers/media/platform/omap3isp/isp.c              |  4 +--
 drivers/media/platform/omap3isp/ispvideo.c         |  2 +-
 drivers/media/platform/vsp1/vsp1_video.c           |  2 +-
 drivers/media/platform/xilinx/xilinx-dma.c         |  2 +-
 drivers/staging/media/davinci_vpfe/vpfe_video.c    |  6 ++--
 drivers/staging/media/omap4iss/iss.c               |  4 +--
 drivers/staging/media/omap4iss/iss_video.c         |  2 +-
 13 files changed, 45 insertions(+), 43 deletions(-)

diff --git a/drivers/media/media-device.c b/drivers/media/media-device.c
index 0f3844470147..138b18416460 100644
--- a/drivers/media/media-device.c
+++ b/drivers/media/media-device.c
@@ -435,8 +435,8 @@ int __must_check media_device_register_entity(struct media_device *mdev,
 	int i;
 
 	/* Warn if we apparently re-register an entity */
-	WARN_ON(entity->parent != NULL);
-	entity->parent = mdev;
+	WARN_ON(entity->graph_obj.mdev != NULL);
+	entity->graph_obj.mdev = mdev;
 
 	spin_lock(&mdev->lock);
 	/* Initialize media_gobj embedded at the entity */
@@ -471,7 +471,7 @@ EXPORT_SYMBOL_GPL(media_device_register_entity);
 void media_device_unregister_entity(struct media_entity *entity)
 {
 	int i;
-	struct media_device *mdev = entity->parent;
+	struct media_device *mdev = entity->graph_obj.mdev;
 
 	if (mdev == NULL)
 		return;
@@ -484,7 +484,7 @@ void media_device_unregister_entity(struct media_entity *entity)
 	media_gobj_remove(&entity->graph_obj);
 	list_del(&entity->list);
 	spin_unlock(&mdev->lock);
-	entity->parent = NULL;
+	entity->graph_obj.mdev = NULL;
 }
 EXPORT_SYMBOL_GPL(media_device_unregister_entity);
 
diff --git a/drivers/media/media-entity.c b/drivers/media/media-entity.c
index 35e52cd1fc5a..a23c93369a04 100644
--- a/drivers/media/media-entity.c
+++ b/drivers/media/media-entity.c
@@ -332,7 +332,7 @@ EXPORT_SYMBOL_GPL(media_entity_graph_walk_next);
 __must_check int media_entity_pipeline_start(struct media_entity *entity,
 					     struct media_pipeline *pipe)
 {
-	struct media_device *mdev = entity->parent;
+	struct media_device *mdev = entity->graph_obj.mdev;
 	struct media_entity_graph graph;
 	struct media_entity *entity_err = entity;
 	int ret;
@@ -387,7 +387,7 @@ __must_check int media_entity_pipeline_start(struct media_entity *entity,
 
 			ret = entity->ops->link_validate(link);
 			if (ret < 0 && ret != -ENOIOCTLCMD) {
-				dev_dbg(entity->parent->dev,
+				dev_dbg(entity->graph_obj.mdev->dev,
 					"link validation failed for \"%s\":%u -> \"%s\":%u, error %d\n",
 					link->source->entity->name,
 					link->source->index,
@@ -401,7 +401,7 @@ __must_check int media_entity_pipeline_start(struct media_entity *entity,
 
 		if (!bitmap_full(active, entity->num_pads)) {
 			ret = -EPIPE;
-			dev_dbg(entity->parent->dev,
+			dev_dbg(entity->graph_obj.mdev->dev,
 				"\"%s\":%u must be connected by an enabled link\n",
 				entity->name,
 				(unsigned)find_first_zero_bit(
@@ -454,7 +454,7 @@ EXPORT_SYMBOL_GPL(media_entity_pipeline_start);
  */
 void media_entity_pipeline_stop(struct media_entity *entity)
 {
-	struct media_device *mdev = entity->parent;
+	struct media_device *mdev = entity->graph_obj.mdev;
 	struct media_entity_graph graph;
 
 	mutex_lock(&mdev->graph_mutex);
@@ -490,8 +490,8 @@ struct media_entity *media_entity_get(struct media_entity *entity)
 	if (entity == NULL)
 		return NULL;
 
-	if (entity->parent->dev &&
-	    !try_module_get(entity->parent->dev->driver->owner))
+	if (entity->graph_obj.mdev->dev &&
+	    !try_module_get(entity->graph_obj.mdev->dev->driver->owner))
 		return NULL;
 
 	return entity;
@@ -511,8 +511,8 @@ void media_entity_put(struct media_entity *entity)
 	if (entity == NULL)
 		return;
 
-	if (entity->parent->dev)
-		module_put(entity->parent->dev->driver->owner);
+	if (entity->graph_obj.mdev->dev)
+		module_put(entity->graph_obj.mdev->dev->driver->owner);
 }
 EXPORT_SYMBOL_GPL(media_entity_put);
 
@@ -561,7 +561,8 @@ media_create_pad_link(struct media_entity *source, u16 source_pad,
 	link->flags = flags;
 
 	/* Initialize graph object embedded at the new link */
-	media_gobj_init(source->parent, MEDIA_GRAPH_LINK, &link->graph_obj);
+	media_gobj_init(source->graph_obj.mdev, MEDIA_GRAPH_LINK,
+			&link->graph_obj);
 
 	/* Create the backlink. Backlinks are used to help graph traversal and
 	 * are not reported to userspace.
@@ -577,7 +578,8 @@ media_create_pad_link(struct media_entity *source, u16 source_pad,
 	backlink->flags = flags;
 
 	/* Initialize graph object embedded at the new link */
-	media_gobj_init(sink->parent, MEDIA_GRAPH_LINK, &backlink->graph_obj);
+	media_gobj_init(sink->graph_obj.mdev, MEDIA_GRAPH_LINK,
+			&backlink->graph_obj);
 
 	link->reverse = backlink;
 	backlink->reverse = link;
@@ -629,12 +631,12 @@ EXPORT_SYMBOL_GPL(__media_entity_remove_links);
 void media_entity_remove_links(struct media_entity *entity)
 {
 	/* Do nothing if the entity is not registered. */
-	if (entity->parent == NULL)
+	if (entity->graph_obj.mdev == NULL)
 		return;
 
-	mutex_lock(&entity->parent->graph_mutex);
+	mutex_lock(&entity->graph_obj.mdev->graph_mutex);
 	__media_entity_remove_links(entity);
-	mutex_unlock(&entity->parent->graph_mutex);
+	mutex_unlock(&entity->graph_obj.mdev->graph_mutex);
 }
 EXPORT_SYMBOL_GPL(media_entity_remove_links);
 
@@ -703,7 +705,7 @@ int __media_entity_setup_link(struct media_link *link, u32 flags)
 	    (source->stream_count || sink->stream_count))
 		return -EBUSY;
 
-	mdev = source->parent;
+	mdev = source->graph_obj.mdev;
 
 	if (mdev->link_notify) {
 		ret = mdev->link_notify(link, flags,
@@ -724,9 +726,9 @@ int media_entity_setup_link(struct media_link *link, u32 flags)
 {
 	int ret;
 
-	mutex_lock(&link->source->entity->parent->graph_mutex);
+	mutex_lock(&link->source->entity->graph_obj.mdev->graph_mutex);
 	ret = __media_entity_setup_link(link, flags);
-	mutex_unlock(&link->source->entity->parent->graph_mutex);
+	mutex_unlock(&link->source->entity->graph_obj.mdev->graph_mutex);
 
 	return ret;
 }
diff --git a/drivers/media/platform/exynos4-is/fimc-isp-video.c b/drivers/media/platform/exynos4-is/fimc-isp-video.c
index b7dc5ac66e36..3d9ccbf5f10f 100644
--- a/drivers/media/platform/exynos4-is/fimc-isp-video.c
+++ b/drivers/media/platform/exynos4-is/fimc-isp-video.c
@@ -288,7 +288,7 @@ static int isp_video_open(struct file *file)
 		goto rel_fh;
 
 	if (v4l2_fh_is_singular_file(file)) {
-		mutex_lock(&me->parent->graph_mutex);
+		mutex_lock(&me->graph_obj.mdev->graph_mutex);
 
 		ret = fimc_pipeline_call(ve, open, me, true);
 
@@ -296,7 +296,7 @@ static int isp_video_open(struct file *file)
 		if (ret == 0)
 			me->use_count++;
 
-		mutex_unlock(&me->parent->graph_mutex);
+		mutex_unlock(&me->graph_obj.mdev->graph_mutex);
 	}
 	if (!ret)
 		goto unlock;
@@ -312,7 +312,7 @@ static int isp_video_release(struct file *file)
 	struct fimc_isp *isp = video_drvdata(file);
 	struct fimc_is_video *ivc = &isp->video_capture;
 	struct media_entity *entity = &ivc->ve.vdev.entity;
-	struct media_device *mdev = entity->parent;
+	struct media_device *mdev = entity->graph_obj.mdev;
 
 	mutex_lock(&isp->video_lock);
 
diff --git a/drivers/media/platform/exynos4-is/fimc-lite.c b/drivers/media/platform/exynos4-is/fimc-lite.c
index e8f707d1729b..b2607da4ad14 100644
--- a/drivers/media/platform/exynos4-is/fimc-lite.c
+++ b/drivers/media/platform/exynos4-is/fimc-lite.c
@@ -500,7 +500,7 @@ static int fimc_lite_open(struct file *file)
 	    atomic_read(&fimc->out_path) != FIMC_IO_DMA)
 		goto unlock;
 
-	mutex_lock(&me->parent->graph_mutex);
+	mutex_lock(&me->graph_obj.mdev->graph_mutex);
 
 	ret = fimc_pipeline_call(&fimc->ve, open, me, true);
 
@@ -508,7 +508,7 @@ static int fimc_lite_open(struct file *file)
 	if (ret == 0)
 		me->use_count++;
 
-	mutex_unlock(&me->parent->graph_mutex);
+	mutex_unlock(&me->graph_obj.mdev->graph_mutex);
 
 	if (!ret) {
 		fimc_lite_clear_event_counters(fimc);
@@ -541,9 +541,9 @@ static int fimc_lite_release(struct file *file)
 		fimc_pipeline_call(&fimc->ve, close);
 		clear_bit(ST_FLITE_IN_USE, &fimc->state);
 
-		mutex_lock(&entity->parent->graph_mutex);
+		mutex_lock(&entity->graph_obj.mdev->graph_mutex);
 		entity->use_count--;
-		mutex_unlock(&entity->parent->graph_mutex);
+		mutex_unlock(&entity->graph_obj.mdev->graph_mutex);
 	}
 
 	_vb2_fop_release(file, NULL);
diff --git a/drivers/media/platform/exynos4-is/media-dev.c b/drivers/media/platform/exynos4-is/media-dev.c
index 3ba76940eef5..92dbade2fffc 100644
--- a/drivers/media/platform/exynos4-is/media-dev.c
+++ b/drivers/media/platform/exynos4-is/media-dev.c
@@ -1046,7 +1046,7 @@ static int __fimc_md_modify_pipeline(struct media_entity *entity, bool enable)
 	return ret;
 }
 
-/* Locking: called with entity->parent->graph_mutex mutex held. */
+/* Locking: called with entity->graph_obj.mdev->graph_mutex mutex held. */
 static int __fimc_md_modify_pipelines(struct media_entity *entity, bool enable)
 {
 	struct media_entity *entity_err = entity;
diff --git a/drivers/media/platform/exynos4-is/media-dev.h b/drivers/media/platform/exynos4-is/media-dev.h
index 03214541f149..9a69913b31cb 100644
--- a/drivers/media/platform/exynos4-is/media-dev.h
+++ b/drivers/media/platform/exynos4-is/media-dev.h
@@ -164,8 +164,8 @@ struct fimc_sensor_info *source_to_sensor_info(struct fimc_source_info *si)
 
 static inline struct fimc_md *entity_to_fimc_mdev(struct media_entity *me)
 {
-	return me->parent == NULL ? NULL :
-		container_of(me->parent, struct fimc_md, media_dev);
+	return me->graph_obj.mdev == NULL ? NULL :
+		container_of(me->graph_obj.mdev, struct fimc_md, media_dev);
 }
 
 static inline struct fimc_md *notifier_to_fimc_md(struct v4l2_async_notifier *n)
@@ -175,12 +175,12 @@ static inline struct fimc_md *notifier_to_fimc_md(struct v4l2_async_notifier *n)
 
 static inline void fimc_md_graph_lock(struct exynos_video_entity *ve)
 {
-	mutex_lock(&ve->vdev.entity.parent->graph_mutex);
+	mutex_lock(&ve->vdev.entity.graph_obj.mdev->graph_mutex);
 }
 
 static inline void fimc_md_graph_unlock(struct exynos_video_entity *ve)
 {
-	mutex_unlock(&ve->vdev.entity.parent->graph_mutex);
+	mutex_unlock(&ve->vdev.entity.graph_obj.mdev->graph_mutex);
 }
 
 int fimc_md_set_camclk(struct v4l2_subdev *sd, bool on);
diff --git a/drivers/media/platform/omap3isp/isp.c b/drivers/media/platform/omap3isp/isp.c
index 6351f35b0a65..aa13b17d19a0 100644
--- a/drivers/media/platform/omap3isp/isp.c
+++ b/drivers/media/platform/omap3isp/isp.c
@@ -787,7 +787,7 @@ int omap3isp_pipeline_pm_use(struct media_entity *entity, int use)
 	int change = use ? 1 : -1;
 	int ret;
 
-	mutex_lock(&entity->parent->graph_mutex);
+	mutex_lock(&entity->graph_obj.mdev->graph_mutex);
 
 	/* Apply use count to node. */
 	entity->use_count += change;
@@ -798,7 +798,7 @@ int omap3isp_pipeline_pm_use(struct media_entity *entity, int use)
 	if (ret < 0)
 		entity->use_count -= change;
 
-	mutex_unlock(&entity->parent->graph_mutex);
+	mutex_unlock(&entity->graph_obj.mdev->graph_mutex);
 
 	return ret;
 }
diff --git a/drivers/media/platform/omap3isp/ispvideo.c b/drivers/media/platform/omap3isp/ispvideo.c
index 6c89dc40df85..4c367352b1f7 100644
--- a/drivers/media/platform/omap3isp/ispvideo.c
+++ b/drivers/media/platform/omap3isp/ispvideo.c
@@ -226,7 +226,7 @@ static int isp_video_get_graph_data(struct isp_video *video,
 {
 	struct media_entity_graph graph;
 	struct media_entity *entity = &video->video.entity;
-	struct media_device *mdev = entity->parent;
+	struct media_device *mdev = entity->graph_obj.mdev;
 	struct isp_video *far_end = NULL;
 
 	mutex_lock(&mdev->graph_mutex);
diff --git a/drivers/media/platform/vsp1/vsp1_video.c b/drivers/media/platform/vsp1/vsp1_video.c
index debe4e539df6..1f94c1a54e00 100644
--- a/drivers/media/platform/vsp1/vsp1_video.c
+++ b/drivers/media/platform/vsp1/vsp1_video.c
@@ -409,7 +409,7 @@ static int vsp1_pipeline_validate(struct vsp1_pipeline *pipe,
 {
 	struct media_entity_graph graph;
 	struct media_entity *entity = &video->video.entity;
-	struct media_device *mdev = entity->parent;
+	struct media_device *mdev = entity->graph_obj.mdev;
 	unsigned int i;
 	int ret;
 
diff --git a/drivers/media/platform/xilinx/xilinx-dma.c b/drivers/media/platform/xilinx/xilinx-dma.c
index f7f9aa353a55..92e8116dc28f 100644
--- a/drivers/media/platform/xilinx/xilinx-dma.c
+++ b/drivers/media/platform/xilinx/xilinx-dma.c
@@ -181,7 +181,7 @@ static int xvip_pipeline_validate(struct xvip_pipeline *pipe,
 {
 	struct media_entity_graph graph;
 	struct media_entity *entity = &start->video.entity;
-	struct media_device *mdev = entity->parent;
+	struct media_device *mdev = entity->graph_obj.mdev;
 	unsigned int num_inputs = 0;
 	unsigned int num_outputs = 0;
 
diff --git a/drivers/staging/media/davinci_vpfe/vpfe_video.c b/drivers/staging/media/davinci_vpfe/vpfe_video.c
index 61a8d5beff58..92573fa852a9 100644
--- a/drivers/staging/media/davinci_vpfe/vpfe_video.c
+++ b/drivers/staging/media/davinci_vpfe/vpfe_video.c
@@ -130,7 +130,7 @@ __vpfe_video_get_format(struct vpfe_video_device *video,
 static void vpfe_prepare_pipeline(struct vpfe_video_device *video)
 {
 	struct media_entity *entity = &video->video_dev.entity;
-	struct media_device *mdev = entity->parent;
+	struct media_device *mdev = entity->graph_obj.mdev;
 	struct vpfe_pipeline *pipe = &video->pipe;
 	struct vpfe_video_device *far_end = NULL;
 	struct media_entity_graph graph;
@@ -288,7 +288,7 @@ static int vpfe_pipeline_enable(struct vpfe_pipeline *pipe)
 	else
 		entity = &pipe->inputs[0]->video_dev.entity;
 
-	mdev = entity->parent;
+	mdev = entity->graph_obj.mdev;
 	mutex_lock(&mdev->graph_mutex);
 	media_entity_graph_walk_start(&graph, entity);
 	while ((entity = media_entity_graph_walk_next(&graph))) {
@@ -328,7 +328,7 @@ static int vpfe_pipeline_disable(struct vpfe_pipeline *pipe)
 	else
 		entity = &pipe->inputs[0]->video_dev.entity;
 
-	mdev = entity->parent;
+	mdev = entity->graph_obj.mdev;
 	mutex_lock(&mdev->graph_mutex);
 	media_entity_graph_walk_start(&graph, entity);
 
diff --git a/drivers/staging/media/omap4iss/iss.c b/drivers/staging/media/omap4iss/iss.c
index 7226553ceb2f..40591963b42b 100644
--- a/drivers/staging/media/omap4iss/iss.c
+++ b/drivers/staging/media/omap4iss/iss.c
@@ -494,7 +494,7 @@ int omap4iss_pipeline_pm_use(struct media_entity *entity, int use)
 	int change = use ? 1 : -1;
 	int ret;
 
-	mutex_lock(&entity->parent->graph_mutex);
+	mutex_lock(&entity->graph_obj.mdev->graph_mutex);
 
 	/* Apply use count to node. */
 	entity->use_count += change;
@@ -505,7 +505,7 @@ int omap4iss_pipeline_pm_use(struct media_entity *entity, int use)
 	if (ret < 0)
 		entity->use_count -= change;
 
-	mutex_unlock(&entity->parent->graph_mutex);
+	mutex_unlock(&entity->graph_obj.mdev->graph_mutex);
 
 	return ret;
 }
diff --git a/drivers/staging/media/omap4iss/iss_video.c b/drivers/staging/media/omap4iss/iss_video.c
index 25e9e7a6b99d..45a3f2d778fc 100644
--- a/drivers/staging/media/omap4iss/iss_video.c
+++ b/drivers/staging/media/omap4iss/iss_video.c
@@ -207,7 +207,7 @@ iss_video_far_end(struct iss_video *video)
 {
 	struct media_entity_graph graph;
 	struct media_entity *entity = &video->video.entity;
-	struct media_device *mdev = entity->parent;
+	struct media_device *mdev = entity->graph_obj.mdev;
 	struct iss_video *far_end = NULL;
 
 	mutex_lock(&mdev->graph_mutex);
-- 
2.4.3



From l.stach at pengutronix.de  Wed Aug 19 08:37:02 2015
From: l.stach at pengutronix.de (Lucas Stach)
Date: Wed, 19 Aug 2015 17:37:02 +0200
Subject: [PATCH v7 3/6] PCI: designware: Add ARM64 support
In-Reply-To: <EE11001F9E5DDD47B7634E2F8A612F2E01D81315@lhreml503-mbs>
References: <1439812554-180426-1-git-send-email-wangzhou1@hisilicon.com>
 <1439812554-180426-4-git-send-email-wangzhou1@hisilicon.com>
 <1439988852.31432.15.camel@pengutronix.de>
 <EE11001F9E5DDD47B7634E2F8A612F2E01D81315@lhreml503-mbs>
Message-ID: <1439998622.31432.44.camel@pengutronix.de>

Hi Gab,

Am Mittwoch, den 19.08.2015, 15:16 +0000 schrieb Gabriele Paoloni:
> Hi Lucas
> 
> I have rewritten the patch to take into account multiple controllers.
> 
> As you can see now there is a static var in dw_pcie_host_init() that tracks
> the bus numbers used.

This is wrong. The DT specifies the valid bus number range. You can not
just assign the next free bus number to the root bus.

It is perfectly valid to have a bus range of 0x00-0x10 assigned to one
instance and 0x50-0xff to the next instance. Additional with PCIe
hotplug you may not use the full range of the bus numbers on one
instance at the first scan, but only later populate more buses when more
bridges are added to the tree.

> Drivers that do not specify the bus range in the DTB set pp->root_bus_nr = DW_ROOT_NR_UNDEFINED.
> Designware will check if the flag is set and will use the automatic bus range
> assignment.

No, please lets get rid of this assignment altogether. The glue drivers
have no business in assigning the bus range. Please remove the
pp->root_bus_nr assignment from all the glue drivers.

"bus range" is a generic DW PCIe property, so just parse the root bus
number from the DT, it is handled the same way for all the DW based PCIe
drivers. The bindings specifies that if the bus range property is
missing the range is 0x00-0xff, so you can default to 0 as the root bus
number in that case.

Also I would think this conversion warrants a patch on its own and
should not be mixed in the ARM64 support patch.

Regards,
Lucas

> Instead if the driver assigns pp->root_bus_nr according to the dtb, designwware
> will use the value passed in by the driver.
> Below the relevant section:
> 
> 
> +	static int root_bus_nr = 0;
> ...
> +	mutex_lock(&root_bus_nr_mux);
> +
> +	if (pp->root_bus_nr != DW_ROOT_NR_UNDEFINED)
> +		root_bus_nr = pp->root_bus_nr;
> +
> +	bus = pci_create_root_bus(pp->dev, root_bus_nr, &dw_pcie_ops,
> +			      pp, &res);
> +	if (!bus) {
> +		mutex_unlock(&root_bus_nr_mux);
> +		return -ENOMEM;
> +	}
> +
> +	root_bus_nr += bus->busn_res.end + 1;
> +	mutex_unlock(&root_bus_nr_mux);
> 
> Please let me know what you think...
> 
> Many Thanks
> 
> Gab
> ----------
> 
> From: gabriele paoloni <gabriele.paoloni at huawei.com>
> 
> This patch tries to unify ARM32 and ARM64 PCIe in designware driver. Delete
> function dw_pcie_setup, dw_pcie_scan_bus, dw_pcie_map_irq and struct hw_pci,
> move related operations to dw_pcie_host_init.
> Also set pp->root_bus_nr = DW_ROOT_NR_UNDEFINED in all the drivers that
> are based on designware to flag that the drivers do not read the bus
> ranges from DT.
> This patch also adds handling of multiple PCI domains in designware.
> if the PCI host bridge driver does not specify a root bus number, in case
> of multiple domains, designware will automatillay set the next domain root
> bus number to the last bus number used in the last domain + 1.
> 
> This patch also try to use of_pci_get_host_bridge_resources for ARM32 and
> ARM64 according to the suggestion for Gabriele[1]
> 
> This patch is based on Gabriele's patch about of_pci_range fix[2]
> 
> Finally this patch reverts commit f4c55c5a3f7f "PCI: designware:
> Program ATU with untranslated address". This was discussed in [3]
> 
> I have compiled the driver with multi_v7_defconfig. However, I don't have
> ARM32 PCIe related board to do test. It will be appreciated if someone could
> help to test it.
> 
> Signed-off-by: Zhou Wang <wangzhou1 at hisilicon.com>
> Signed-off-by: Arnd Bergmann <arnd at arndb.de>
> Signed-off-by: Gabriele Paoloni <gabriele.paoloni at huawei.com>
> 
> [1] http://www.spinics.net/lists/linux-pci/msg42194.html
> [2] https://patchwork.ozlabs.org/patch/495018/
> [3] http://www.spinics.net/lists/arm-kernel/msg436779.html
> ---
>  drivers/pci/host/pci-dra7xx.c      |  15 +--
>  drivers/pci/host/pci-exynos.c      |   2 +-
>  drivers/pci/host/pci-imx6.c        |   2 +-
>  drivers/pci/host/pci-keystone-dw.c |   2 +-
>  drivers/pci/host/pci-keystone.c    |   2 +-
>  drivers/pci/host/pci-layerscape.c  |   2 +-
>  drivers/pci/host/pcie-designware.c | 247 ++++++++++++++-----------------------
>  drivers/pci/host/pcie-designware.h |  15 +--
>  drivers/pci/host/pcie-spear13xx.c  |   2 +-
>  9 files changed, 110 insertions(+), 179 deletions(-)
> 
> diff --git a/drivers/pci/host/pci-dra7xx.c b/drivers/pci/host/pci-dra7xx.c
> index 5678b57..8d598fb 100644
> --- a/drivers/pci/host/pci-dra7xx.c
> +++ b/drivers/pci/host/pci-dra7xx.c
> @@ -141,15 +141,15 @@ static void dra7xx_pcie_host_init(struct pcie_port *pp)
>  {
>  	dw_pcie_setup_rc(pp);
>  
> -	if (pp->io_mod_base)
> -		pp->io_mod_base &= CPU_TO_BUS_ADDR;
> +	if (pp->io_base)
> +		pp->io_base &= CPU_TO_BUS_ADDR;
>  
> -	if (pp->mem_mod_base)
> -		pp->mem_mod_base &= CPU_TO_BUS_ADDR;
> +	if (pp->mem_base)
> +		pp->mem_base &= CPU_TO_BUS_ADDR;
>  
> -	if (pp->cfg0_mod_base) {
> -		pp->cfg0_mod_base &= CPU_TO_BUS_ADDR;
> -		pp->cfg1_mod_base &= CPU_TO_BUS_ADDR;
> +	if (pp->cfg0_base) {
> +		pp->cfg0_base &= CPU_TO_BUS_ADDR;
> +		pp->cfg1_base &= CPU_TO_BUS_ADDR;
>  	}
>  
>  	dra7xx_pcie_establish_link(pp);
> @@ -288,6 +288,7 @@ static int __init dra7xx_add_pcie_port(struct dra7xx_pcie *dra7xx,
>  
>  	pp = &dra7xx->pp;
>  	pp->dev = dev;
> +	pp->root_bus_nr = DW_ROOT_NR_UNDEFINED;
>  	pp->ops = &dra7xx_pcie_host_ops;
>  
>  	pp->irq = platform_get_irq(pdev, 1);
> diff --git a/drivers/pci/host/pci-exynos.c b/drivers/pci/host/pci-exynos.c
> index f9f468d..ed03a8f 100644
> --- a/drivers/pci/host/pci-exynos.c
> +++ b/drivers/pci/host/pci-exynos.c
> @@ -530,7 +530,7 @@ static int __init exynos_add_pcie_port(struct pcie_port *pp,
>  		}
>  	}
>  
> -	pp->root_bus_nr = -1;
> +	pp->root_bus_nr = DW_ROOT_NR_UNDEFINED;
>  	pp->ops = &exynos_pcie_host_ops;
>  
>  	ret = dw_pcie_host_init(pp);
> diff --git a/drivers/pci/host/pci-imx6.c b/drivers/pci/host/pci-imx6.c
> index 233a196..0efac85 100644
> --- a/drivers/pci/host/pci-imx6.c
> +++ b/drivers/pci/host/pci-imx6.c
> @@ -551,7 +551,7 @@ static int __init imx6_add_pcie_port(struct pcie_port *pp,
>  		}
>  	}
>  
> -	pp->root_bus_nr = -1;
> +	pp->root_bus_nr = DW_ROOT_NR_UNDEFINED;
>  	pp->ops = &imx6_pcie_host_ops;
>  
>  	ret = dw_pcie_host_init(pp);
> diff --git a/drivers/pci/host/pci-keystone-dw.c b/drivers/pci/host/pci-keystone-dw.c
> index f34892e..b1e4135 100644
> --- a/drivers/pci/host/pci-keystone-dw.c
> +++ b/drivers/pci/host/pci-keystone-dw.c
> @@ -327,7 +327,7 @@ static void ks_dw_pcie_clear_dbi_mode(void __iomem *reg_virt)
>  void ks_dw_pcie_setup_rc_app_regs(struct keystone_pcie *ks_pcie)
>  {
>  	struct pcie_port *pp = &ks_pcie->pp;
> -	u32 start = pp->mem.start, end = pp->mem.end;
> +	u32 start = pp->mem->start, end = pp->mem->end;
>  	int i, tr_size;
>  
>  	/* Disable BARs for inbound access */
> diff --git a/drivers/pci/host/pci-keystone.c b/drivers/pci/host/pci-keystone.c
> index 734da58..b522956 100644
> --- a/drivers/pci/host/pci-keystone.c
> +++ b/drivers/pci/host/pci-keystone.c
> @@ -309,7 +309,7 @@ static int __init ks_add_pcie_port(struct keystone_pcie *ks_pcie,
>  			return ret;
>  	}
>  
> -	pp->root_bus_nr = -1;
> +	pp->root_bus_nr = DW_ROOT_NR_UNDEFINED;
>  	pp->ops = &keystone_pcie_host_ops;
>  	ret = ks_dw_pcie_host_init(ks_pcie, ks_pcie->msi_intc_np);
>  	if (ret) {
> diff --git a/drivers/pci/host/pci-layerscape.c b/drivers/pci/host/pci-layerscape.c
> index b2328ea1..dd92ffa 100644
> --- a/drivers/pci/host/pci-layerscape.c
> +++ b/drivers/pci/host/pci-layerscape.c
> @@ -106,7 +106,7 @@ static int ls_add_pcie_port(struct ls_pcie *pcie)
>  	pp = &pcie->pp;
>  	pp->dev = pcie->dev;
>  	pp->dbi_base = pcie->dbi;
> -	pp->root_bus_nr = -1;
> +	pp->root_bus_nr = DW_ROOT_NR_UNDEFINED;
>  	pp->ops = &ls_pcie_host_ops;
>  
>  	ret = dw_pcie_host_init(pp);
> diff --git a/drivers/pci/host/pcie-designware.c b/drivers/pci/host/pcie-designware.c
> index 5307b35..bd2606b 100644
> --- a/drivers/pci/host/pcie-designware.c
> +++ b/drivers/pci/host/pcie-designware.c
> @@ -11,6 +11,7 @@
>   * published by the Free Software Foundation.
>   */
>  
> +#include <linux/hardirq.h>
>  #include <linux/irq.h>
>  #include <linux/irqdomain.h>
>  #include <linux/kernel.h>
> @@ -69,16 +70,9 @@
>  #define PCIE_ATU_FUNC(x)		(((x) & 0x7) << 16)
>  #define PCIE_ATU_UPPER_TARGET		0x91C
>  
> -static struct hw_pci dw_pci;
> +static struct pci_ops dw_pcie_ops;
>  
> -static unsigned long global_io_offset;
> -
> -static inline struct pcie_port *sys_to_pcie(struct pci_sys_data *sys)
> -{
> -	BUG_ON(!sys->private_data);
> -
> -	return sys->private_data;
> -}
> +DEFINE_MUTEX(root_bus_nr_mux);
>  
>  int dw_pcie_cfg_read(void __iomem *addr, int where, int size, u32 *val)
>  {
> @@ -255,7 +249,7 @@ static void dw_pcie_msi_set_irq(struct pcie_port *pp, int irq)
>  static int assign_irq(int no_irqs, struct msi_desc *desc, int *pos)
>  {
>  	int irq, pos0, i;
> -	struct pcie_port *pp = sys_to_pcie(desc->dev->bus->sysdata);
> +	struct pcie_port *pp = desc->dev->bus->sysdata;
>  
>  	pos0 = bitmap_find_free_region(pp->msi_irq_in_use, MAX_MSI_IRQS,
>  				       order_base_2(no_irqs));
> @@ -298,7 +292,7 @@ static int dw_msi_setup_irq(struct msi_controller *chip, struct pci_dev *pdev,
>  {
>  	int irq, pos;
>  	struct msi_msg msg;
> -	struct pcie_port *pp = sys_to_pcie(pdev->bus->sysdata);
> +	struct pcie_port *pp = pdev->bus->sysdata;
>  
>  	if (desc->msi_attrib.is_msix)
>  		return -EINVAL;
> @@ -327,7 +321,7 @@ static void dw_msi_teardown_irq(struct msi_controller *chip, unsigned int irq)
>  {
>  	struct irq_data *data = irq_get_irq_data(irq);
>  	struct msi_desc *msi = irq_data_get_msi(data);
> -	struct pcie_port *pp = sys_to_pcie(msi->dev->bus->sysdata);
> +	struct pcie_port *pp = msi->dev->bus->sysdata;
>  
>  	clear_irq_range(pp, irq, 1, data->hwirq);
>  }
> @@ -359,22 +353,17 @@ static const struct irq_domain_ops msi_domain_ops = {
>  	.map = dw_pcie_msi_map,
>  };
>  
> -int dw_pcie_host_init(struct pcie_port *pp)
> +int __init dw_pcie_host_init(struct pcie_port *pp)
>  {
>  	struct device_node *np = pp->dev->of_node;
>  	struct platform_device *pdev = to_platform_device(pp->dev);
> -	struct of_pci_range range;
> -	struct of_pci_range_parser parser;
> +	struct pci_bus *bus;
>  	struct resource *cfg_res;
> -	u32 val, na, ns;
> -	const __be32 *addrp;
> -	int i, index, ret;
> -
> -	/* Find the address cell size and the number of cells in order to get
> -	 * the untranslated address.
> -	 */
> -	of_property_read_u32(np, "#address-cells", &na);
> -	ns = of_n_size_cells(np);
> +	LIST_HEAD(res);
> +	u32 val;
> +	int i, ret;
> +	struct resource_entry *win;
> +	static int root_bus_nr = 0;
>  
>  	cfg_res = platform_get_resource_byname(pdev, IORESOURCE_MEM, "config");
>  	if (cfg_res) {
> @@ -382,85 +371,60 @@ int dw_pcie_host_init(struct pcie_port *pp)
>  		pp->cfg1_size = resource_size(cfg_res)/2;
>  		pp->cfg0_base = cfg_res->start;
>  		pp->cfg1_base = cfg_res->start + pp->cfg0_size;
> -
> -		/* Find the untranslated configuration space address */
> -		index = of_property_match_string(np, "reg-names", "config");
> -		addrp = of_get_address(np, index, NULL, NULL);
> -		pp->cfg0_mod_base = of_read_number(addrp, ns);
> -		pp->cfg1_mod_base = pp->cfg0_mod_base + pp->cfg0_size;
>  	} else {
>  		dev_err(pp->dev, "missing *config* reg space\n");
>  	}
>  
> -	if (of_pci_range_parser_init(&parser, np)) {
> -		dev_err(pp->dev, "missing ranges property\n");
> -		return -EINVAL;
> -	}
> +	ret = of_pci_get_host_bridge_resources(np, 0, 0xff, &res, &pp->io_base);
> +	if (ret)
> +		return ret;
>  
>  	/* Get the I/O and memory ranges from DT */
> -	for_each_of_pci_range(&parser, &range) {
> -		unsigned long restype = range.flags & IORESOURCE_TYPE_BITS;
> -
> -		if (restype == IORESOURCE_IO) {
> -			of_pci_range_to_resource(&range, np, &pp->io);
> -			pp->io.name = "I/O";
> -			pp->io.start = max_t(resource_size_t,
> -					     PCIBIOS_MIN_IO,
> -					     range.pci_addr + global_io_offset);
> -			pp->io.end = min_t(resource_size_t,
> -					   IO_SPACE_LIMIT,
> -					   range.pci_addr + range.size
> -					   + global_io_offset - 1);
> -			pp->io_size = resource_size(&pp->io);
> -			pp->io_bus_addr = range.pci_addr;
> -			pp->io_base = range.cpu_addr;
> -
> -			/* Find the untranslated IO space address */
> -			pp->io_mod_base = range.cpu_addr;
> -		}
> -		if (restype == IORESOURCE_MEM) {
> -			of_pci_range_to_resource(&range, np, &pp->mem);
> -			pp->mem.name = "MEM";
> -			pp->mem_size = resource_size(&pp->mem);
> -			pp->mem_bus_addr = range.pci_addr;
> -
> -			/* Find the untranslated MEM space address */
> -			pp->mem_mod_base = range.cpu_addr;
> -		}
> -		if (restype == 0) {
> -			of_pci_range_to_resource(&range, np, &pp->cfg);
> -			pp->cfg0_size = resource_size(&pp->cfg)/2;
> -			pp->cfg1_size = resource_size(&pp->cfg)/2;
> -			pp->cfg0_base = pp->cfg.start;
> -			pp->cfg1_base = pp->cfg.start + pp->cfg0_size;
> -
> -			/* Find the untranslated configuration space address */
> -			pp->cfg0_mod_base = range.cpu_addr;
> -			pp->cfg1_mod_base = pp->cfg0_mod_base +
> -					    pp->cfg0_size;
> +	resource_list_for_each_entry(win, &res) {
> +		switch (resource_type(win->res)) {
> +		case IORESOURCE_IO:
> +			pp->io = win->res;
> +			pp->io->name = "I/O";
> +			pp->io_size = resource_size(pp->io);
> +			pp->io_bus_addr = pp->io->start - win->offset;
> +			ret = pci_remap_iospace(pp->io, pp->io_base);
> +			if (ret) {
> +				dev_warn(pp->dev, "error %d: failed to map resource %pR\n",
> +					 ret, pp->io);
> +				continue;
> +			}
> +			break;
> +		case IORESOURCE_MEM:
> +			pp->mem = win->res;
> +			pp->mem->name = "MEM";
> +			pp->mem_size = resource_size(pp->mem);
> +			pp->mem_bus_addr = pp->mem->start - win->offset;
> +			break;
> +		case 0:
> +			pp->cfg = win->res;
> +			pp->cfg0_size = resource_size(pp->cfg)/2;
> +			pp->cfg1_size = resource_size(pp->cfg)/2;
> +			pp->cfg0_base = pp->cfg->start;
> +			pp->cfg1_base = pp->cfg->start + pp->cfg0_size;
> +			break;
> +		case IORESOURCE_BUS:
> +			pp->busn = win->res;
> +			break;
> +		default:
> +			continue;
>  		}
>  	}
>  
> -	ret = of_pci_parse_bus_range(np, &pp->busn);
> -	if (ret < 0) {
> -		pp->busn.name = np->name;
> -		pp->busn.start = 0;
> -		pp->busn.end = 0xff;
> -		pp->busn.flags = IORESOURCE_BUS;
> -		dev_dbg(pp->dev, "failed to parse bus-range property: %d, using default %pR\n",
> -			ret, &pp->busn);
> -	}
> -
>  	if (!pp->dbi_base) {
> -		pp->dbi_base = devm_ioremap(pp->dev, pp->cfg.start,
> -					resource_size(&pp->cfg));
> +		pp->dbi_base = devm_ioremap(pp->dev, pp->cfg->start,
> +					resource_size(pp->cfg));
>  		if (!pp->dbi_base) {
>  			dev_err(pp->dev, "error with ioremap\n");
>  			return -ENOMEM;
>  		}
>  	}
>  
> -	pp->mem_base = pp->mem.start;
> +	pp->mem_base = pp->mem->start;
>  
>  	if (!pp->va_cfg0_base) {
>  		pp->va_cfg0_base = devm_ioremap(pp->dev, pp->cfg0_base,
> @@ -509,7 +473,7 @@ int dw_pcie_host_init(struct pcie_port *pp)
>  
>  	if (!pp->ops->rd_other_conf)
>  		dw_pcie_prog_outbound_atu(pp, PCIE_ATU_REGION_INDEX1,
> -					  PCIE_ATU_TYPE_MEM, pp->mem_mod_base,
> +					  PCIE_ATU_TYPE_MEM, pp->mem_base,
>  					  pp->mem_bus_addr, pp->mem_size);
>  
>  	dw_pcie_wr_own_conf(pp, PCI_BASE_ADDRESS_0, 4, 0);
> @@ -521,15 +485,40 @@ int dw_pcie_host_init(struct pcie_port *pp)
>  	val |= PORT_LOGIC_SPEED_CHANGE;
>  	dw_pcie_wr_own_conf(pp, PCIE_LINK_WIDTH_SPEED_CONTROL, 4, val);
>  
> -#ifdef CONFIG_PCI_MSI
>  	dw_pcie_msi_chip.dev = pp->dev;
> -	dw_pci.msi_ctrl = &dw_pcie_msi_chip;
> +
> +	mutex_lock(&root_bus_nr_mux);
> +
> +	if (pp->root_bus_nr != DW_ROOT_NR_UNDEFINED)
> +		root_bus_nr = pp->root_bus_nr;
> +
> +	bus = pci_create_root_bus(pp->dev, root_bus_nr, &dw_pcie_ops,
> +			      pp, &res);
> +	if (!bus) {
> +		mutex_unlock(&root_bus_nr_mux);
> +		return -ENOMEM;
> +	}
> +
> +	root_bus_nr += bus->busn_res.end + 1;
> +	mutex_unlock(&root_bus_nr_mux);
> +
> +#ifdef CONFIG_GENERIC_MSI_IRQ_DOMAIN
> +	bus->msi = container_of(&pp->irq_domain, struct msi_controller, domain);
> +#else
> +	bus->msi = &dw_pcie_msi_chip;
>  #endif
>  
> -	dw_pci.nr_controllers = 1;
> -	dw_pci.private_data = (void **)&pp;
> +	pci_scan_child_bus(bus);
> +	if (pp->ops->scan_bus)
> +		pp->ops->scan_bus(pp);
> +
> +#ifdef CONFIG_ARM
> +	/* support old dtbs that incorrectly describe IRQs */
> +	pci_fixup_irqs(pci_common_swizzle, of_irq_parse_and_map_pci);
> +#endif
>  
> -	pci_common_init_dev(pp->dev, &dw_pci);
> +	pci_assign_unassigned_bus_resources(bus);
> +	pci_bus_add_devices(bus);
>  
>  	return 0;
>  }
> @@ -548,12 +537,12 @@ static int dw_pcie_rd_other_conf(struct pcie_port *pp, struct pci_bus *bus,
>  
>  	if (bus->parent->number == pp->root_bus_nr) {
>  		type = PCIE_ATU_TYPE_CFG0;
> -		cpu_addr = pp->cfg0_mod_base;
> +		cpu_addr = pp->cfg0_base;
>  		cfg_size = pp->cfg0_size;
>  		va_cfg_base = pp->va_cfg0_base;
>  	} else {
>  		type = PCIE_ATU_TYPE_CFG1;
> -		cpu_addr = pp->cfg1_mod_base;
> +		cpu_addr = pp->cfg1_base;
>  		cfg_size = pp->cfg1_size;
>  		va_cfg_base = pp->va_cfg1_base;
>  	}
> @@ -563,7 +552,7 @@ static int dw_pcie_rd_other_conf(struct pcie_port *pp, struct pci_bus *bus,
>  				  busdev, cfg_size);
>  	ret = dw_pcie_cfg_read(va_cfg_base + address, where, size, val);
>  	dw_pcie_prog_outbound_atu(pp, PCIE_ATU_REGION_INDEX0,
> -				  PCIE_ATU_TYPE_IO, pp->io_mod_base,
> +				  PCIE_ATU_TYPE_IO, pp->io_base,
>  				  pp->io_bus_addr, pp->io_size);
>  
>  	return ret;
> @@ -583,12 +572,12 @@ static int dw_pcie_wr_other_conf(struct pcie_port *pp, struct pci_bus *bus,
>  
>  	if (bus->parent->number == pp->root_bus_nr) {
>  		type = PCIE_ATU_TYPE_CFG0;
> -		cpu_addr = pp->cfg0_mod_base;
> +		cpu_addr = pp->cfg0_base;
>  		cfg_size = pp->cfg0_size;
>  		va_cfg_base = pp->va_cfg0_base;
>  	} else {
>  		type = PCIE_ATU_TYPE_CFG1;
> -		cpu_addr = pp->cfg1_mod_base;
> +		cpu_addr = pp->cfg1_base;
>  		cfg_size = pp->cfg1_size;
>  		va_cfg_base = pp->va_cfg1_base;
>  	}
> @@ -598,7 +587,7 @@ static int dw_pcie_wr_other_conf(struct pcie_port *pp, struct pci_bus *bus,
>  				  busdev, cfg_size);
>  	ret = dw_pcie_cfg_write(va_cfg_base + address, where, size, val);
>  	dw_pcie_prog_outbound_atu(pp, PCIE_ATU_REGION_INDEX0,
> -				  PCIE_ATU_TYPE_IO, pp->io_mod_base,
> +				  PCIE_ATU_TYPE_IO, pp->io_base,
>  				  pp->io_bus_addr, pp->io_size);
>  
>  	return ret;
> @@ -630,7 +619,7 @@ static int dw_pcie_valid_config(struct pcie_port *pp,
>  static int dw_pcie_rd_conf(struct pci_bus *bus, u32 devfn, int where,
>  			int size, u32 *val)
>  {
> -	struct pcie_port *pp = sys_to_pcie(bus->sysdata);
> +	struct pcie_port *pp = bus->sysdata;
>  	int ret;
>  
>  	if (dw_pcie_valid_config(pp, bus, PCI_SLOT(devfn)) == 0) {
> @@ -654,7 +643,7 @@ static int dw_pcie_rd_conf(struct pci_bus *bus, u32 devfn, int where,
>  static int dw_pcie_wr_conf(struct pci_bus *bus, u32 devfn,
>  			int where, int size, u32 val)
>  {
> -	struct pcie_port *pp = sys_to_pcie(bus->sysdata);
> +	struct pcie_port *pp = bus->sysdata;
>  	int ret;
>  
>  	if (dw_pcie_valid_config(pp, bus, PCI_SLOT(devfn)) == 0)
> @@ -678,62 +667,6 @@ static struct pci_ops dw_pcie_ops = {
>  	.write = dw_pcie_wr_conf,
>  };
>  
> -static int dw_pcie_setup(int nr, struct pci_sys_data *sys)
> -{
> -	struct pcie_port *pp;
> -
> -	pp = sys_to_pcie(sys);
> -
> -	if (global_io_offset < SZ_1M && pp->io_size > 0) {
> -		sys->io_offset = global_io_offset - pp->io_bus_addr;
> -		pci_ioremap_io(global_io_offset, pp->io_base);
> -		global_io_offset += SZ_64K;
> -		pci_add_resource_offset(&sys->resources, &pp->io,
> -					sys->io_offset);
> -	}
> -
> -	sys->mem_offset = pp->mem.start - pp->mem_bus_addr;
> -	pci_add_resource_offset(&sys->resources, &pp->mem, sys->mem_offset);
> -	pci_add_resource(&sys->resources, &pp->busn);
> -
> -	return 1;
> -}
> -
> -static struct pci_bus *dw_pcie_scan_bus(int nr, struct pci_sys_data *sys)
> -{
> -	struct pci_bus *bus;
> -	struct pcie_port *pp = sys_to_pcie(sys);
> -
> -	pp->root_bus_nr = sys->busnr;
> -	bus = pci_scan_root_bus(pp->dev, sys->busnr,
> -				  &dw_pcie_ops, sys, &sys->resources);
> -	if (!bus)
> -		return NULL;
> -
> -	if (bus && pp->ops->scan_bus)
> -		pp->ops->scan_bus(pp);
> -
> -	return bus;
> -}
> -
> -static int dw_pcie_map_irq(const struct pci_dev *dev, u8 slot, u8 pin)
> -{
> -	struct pcie_port *pp = sys_to_pcie(dev->bus->sysdata);
> -	int irq;
> -
> -	irq = of_irq_parse_and_map_pci(dev, slot, pin);
> -	if (!irq)
> -		irq = pp->irq;
> -
> -	return irq;
> -}
> -
> -static struct hw_pci dw_pci = {
> -	.setup		= dw_pcie_setup,
> -	.scan		= dw_pcie_scan_bus,
> -	.map_irq	= dw_pcie_map_irq,
> -};
> -
>  void dw_pcie_setup_rc(struct pcie_port *pp)
>  {
>  	u32 val;
> diff --git a/drivers/pci/host/pcie-designware.h b/drivers/pci/host/pcie-designware.h
> index d0bbd27..0c2a7eb 100644
> --- a/drivers/pci/host/pcie-designware.h
> +++ b/drivers/pci/host/pcie-designware.h
> @@ -21,31 +21,28 @@
>   */
>  #define MAX_MSI_IRQS			32
>  #define MAX_MSI_CTRLS			(MAX_MSI_IRQS / 32)
> +#define DW_ROOT_NR_UNDEFINED	-1
>  
>  struct pcie_port {
>  	struct device		*dev;
>  	u8			root_bus_nr;
>  	void __iomem		*dbi_base;
>  	u64			cfg0_base;
> -	u64			cfg0_mod_base;
>  	void __iomem		*va_cfg0_base;
>  	u32			cfg0_size;
>  	u64			cfg1_base;
> -	u64			cfg1_mod_base;
>  	void __iomem		*va_cfg1_base;
>  	u32			cfg1_size;
> -	u64			io_base;
> -	u64			io_mod_base;
> +	resource_size_t		io_base;
>  	phys_addr_t		io_bus_addr;
>  	u32			io_size;
>  	u64			mem_base;
> -	u64			mem_mod_base;
>  	phys_addr_t		mem_bus_addr;
>  	u32			mem_size;
> -	struct resource		cfg;
> -	struct resource		io;
> -	struct resource		mem;
> -	struct resource		busn;
> +	struct resource		*cfg;
> +	struct resource		*io;
> +	struct resource		*mem;
> +	struct resource		*busn;
>  	int			irq;
>  	u32			lanes;
>  	struct pcie_host_ops	*ops;
> diff --git a/drivers/pci/host/pcie-spear13xx.c b/drivers/pci/host/pcie-spear13xx.c
> index c49fbdc..b2c59b9 100644
> --- a/drivers/pci/host/pcie-spear13xx.c
> +++ b/drivers/pci/host/pcie-spear13xx.c
> @@ -286,7 +286,7 @@ static int spear13xx_add_pcie_port(struct pcie_port *pp,
>  		return ret;
>  	}
>  
> -	pp->root_bus_nr = -1;
> +	pp->root_bus_nr = DW_ROOT_NR_UNDEFINED;
>  	pp->ops = &spear13xx_pcie_host_ops;
>  
>  	ret = dw_pcie_host_init(pp);
> -- 
> 1.9.1
> 
> 
> > -----Original Message-----
> > From: Lucas Stach [mailto:l.stach at pengutronix.de]
> > Sent: Wednesday, August 19, 2015 1:54 PM
> > To: Wangzhou (B)
> > Cc: Bjorn Helgaas; jingoohan1 at gmail.com; Pratyush Anand; Arnd Bergmann;
> > linux at arm.linux.org.uk; thomas.petazzoni at free-electrons.com; Gabriele
> > Paoloni; lorenzo.pieralisi at arm.com; james.morse at arm.com;
> > Liviu.Dudau at arm.com; jason at lakedaemon.net; robh at kernel.org; linux-
> > pci at vger.kernel.org; linux-arm-kernel at lists.infradead.org;
> > devicetree at vger.kernel.org; Yuanzhichang; Zhudacai; zhangjukuo;
> > qiuzhenfa; liudongdong (C); qiujiang; xuwei (O); Liguozhu (Kenneth)
> > Subject: Re: [PATCH v7 3/6] PCI: designware: Add ARM64 support
> > 
> > Am Montag, den 17.08.2015, 19:55 +0800 schrieb Zhou Wang:
> > > This patch tries to unify ARM32 and ARM64 PCIe in designware driver.
> > Delete
> > > function dw_pcie_setup, dw_pcie_scan_bus, dw_pcie_map_irq and struct
> > hw_pci,
> > > move related operations to dw_pcie_host_init.
> > >
> > > In past, we use:
> > > pci_common_init_dev
> > > 	-> pcibios_init_hw
> > > 		-> hw->scan (dw_pcie_scan_bus)
> > > to pass 0 to root_bus_nr in struct pcie_port. This patch set pp-
> > >root_bus_nr = 0
> > > in each PCIe host driver which is based on pcie-designware.
> > >
> > This is incorrect at least if there are 2 instances of DW PCIe host in
> > the same SoC without using PCI domains. In that the case the bus range
> > determines the range of valid bus numbers per instance and the first
> > number is the root bus. Please look at the "bus-range" DT property in
> > the DW PCIe bindings.
> > 
> > Also we should finally remove this root-bus setup from the glue drivers
> > altogether. It's something that entirely belongs into the DW core code.
> > 
> > Regards,
> > Lucas
> > 
> > > This patch also try to use of_pci_get_host_bridge_resources for ARM32
> > and ARM64
> > > according to the suggestion for Gabriele[1]
> > >
> > > Finally this patch reverts commit f4c55c5a3f7f "PCI: designware:
> > Program ATU
> > > with untranslated address" based on 1/6 in this series. we delete
> > *_mod_base in
> > > pcie-designware. This was discussed in [2]
> > >
> > > I have compiled the driver with multi_v7_defconfig. However, I don't
> > have
> > > ARM32 PCIe related board to do test. It will be appreciated if
> > someone could
> > > help to test it.
> > >
> > > Signed-off-by: Zhou Wang <wangzhou1 at hisilicon.com>
> > > Signed-off-by: Gabriele Paoloni <gabriele.paoloni at huawei.com>
> > > Signed-off-by: Arnd Bergmann <arnd at arndb.de>
> > > Tested-By: James Morse <james.morse at arm.com>
> > >
> > > [1] http://www.spinics.net/lists/linux-pci/msg42194.html
> > > [2] http://www.spinics.net/lists/arm-kernel/msg436779.html
> > > ---
> > >  drivers/pci/host/pci-dra7xx.c      |  15 +--
> > >  drivers/pci/host/pci-exynos.c      |   2 +-
> > >  drivers/pci/host/pci-imx6.c        |   2 +-
> > >  drivers/pci/host/pci-keystone-dw.c |   2 +-
> > >  drivers/pci/host/pci-keystone.c    |   2 +-
> > >  drivers/pci/host/pci-layerscape.c  |   2 +-
> > >  drivers/pci/host/pcie-designware.c | 229 ++++++++++++---------------
> > ----------
> > >  drivers/pci/host/pcie-designware.h |  14 +--
> > >  drivers/pci/host/pcie-spear13xx.c  |   2 +-
> > >  9 files changed, 95 insertions(+), 175 deletions(-)
> > >
> > > diff --git a/drivers/pci/host/pci-dra7xx.c b/drivers/pci/host/pci-
> > dra7xx.c
> > > index 18ae7ff..1268c69 100644
> > > --- a/drivers/pci/host/pci-dra7xx.c
> > > +++ b/drivers/pci/host/pci-dra7xx.c
> > > @@ -141,15 +141,15 @@ static void dra7xx_pcie_host_init(struct
> > pcie_port *pp)
> > >  {
> > >  	dw_pcie_setup_rc(pp);
> > >
> > > -	if (pp->io_mod_base)
> > > -		pp->io_mod_base &= CPU_TO_BUS_ADDR;
> > > +	if (pp->io_base)
> > > +		pp->io_base &= CPU_TO_BUS_ADDR;
> > >
> > > -	if (pp->mem_mod_base)
> > > -		pp->mem_mod_base &= CPU_TO_BUS_ADDR;
> > > +	if (pp->mem_base)
> > > +		pp->mem_base &= CPU_TO_BUS_ADDR;
> > >
> > > -	if (pp->cfg0_mod_base) {
> > > -		pp->cfg0_mod_base &= CPU_TO_BUS_ADDR;
> > > -		pp->cfg1_mod_base &= CPU_TO_BUS_ADDR;
> > > +	if (pp->cfg0_base) {
> > > +		pp->cfg0_base &= CPU_TO_BUS_ADDR;
> > > +		pp->cfg1_base &= CPU_TO_BUS_ADDR;
> > >  	}
> > >
> > >  	dra7xx_pcie_establish_link(pp);
> > > @@ -288,6 +288,7 @@ static int __init dra7xx_add_pcie_port(struct
> > dra7xx_pcie *dra7xx,
> > >
> > >  	pp = &dra7xx->pp;
> > >  	pp->dev = dev;
> > > +	pp->root_bus_nr = 0;
> > >  	pp->ops = &dra7xx_pcie_host_ops;
> > >
> > >  	pp->irq = platform_get_irq(pdev, 1);
> > > diff --git a/drivers/pci/host/pci-exynos.c b/drivers/pci/host/pci-
> > exynos.c
> > > index f9f468d..9771bb0 100644
> > > --- a/drivers/pci/host/pci-exynos.c
> > > +++ b/drivers/pci/host/pci-exynos.c
> > > @@ -530,7 +530,7 @@ static int __init exynos_add_pcie_port(struct
> > pcie_port *pp,
> > >  		}
> > >  	}
> > >
> > > -	pp->root_bus_nr = -1;
> > > +	pp->root_bus_nr = 0;
> > >  	pp->ops = &exynos_pcie_host_ops;
> > >
> > >  	ret = dw_pcie_host_init(pp);
> > > diff --git a/drivers/pci/host/pci-imx6.c b/drivers/pci/host/pci-
> > imx6.c
> > > index 233a196..bec256c 100644
> > > --- a/drivers/pci/host/pci-imx6.c
> > > +++ b/drivers/pci/host/pci-imx6.c
> > > @@ -551,7 +551,7 @@ static int __init imx6_add_pcie_port(struct
> > pcie_port *pp,
> > >  		}
> > >  	}
> > >
> > > -	pp->root_bus_nr = -1;
> > > +	pp->root_bus_nr = 0;
> > >  	pp->ops = &imx6_pcie_host_ops;
> > >
> > >  	ret = dw_pcie_host_init(pp);
> > > diff --git a/drivers/pci/host/pci-keystone-dw.c
> > b/drivers/pci/host/pci-keystone-dw.c
> > > index f34892e..b1e4135 100644
> > > --- a/drivers/pci/host/pci-keystone-dw.c
> > > +++ b/drivers/pci/host/pci-keystone-dw.c
> > > @@ -327,7 +327,7 @@ static void ks_dw_pcie_clear_dbi_mode(void
> > __iomem *reg_virt)
> > >  void ks_dw_pcie_setup_rc_app_regs(struct keystone_pcie *ks_pcie)
> > >  {
> > >  	struct pcie_port *pp = &ks_pcie->pp;
> > > -	u32 start = pp->mem.start, end = pp->mem.end;
> > > +	u32 start = pp->mem->start, end = pp->mem->end;
> > >  	int i, tr_size;
> > >
> > >  	/* Disable BARs for inbound access */
> > > diff --git a/drivers/pci/host/pci-keystone.c b/drivers/pci/host/pci-
> > keystone.c
> > > index 734da58..8113832 100644
> > > --- a/drivers/pci/host/pci-keystone.c
> > > +++ b/drivers/pci/host/pci-keystone.c
> > > @@ -309,7 +309,7 @@ static int __init ks_add_pcie_port(struct
> > keystone_pcie *ks_pcie,
> > >  			return ret;
> > >  	}
> > >
> > > -	pp->root_bus_nr = -1;
> > > +	pp->root_bus_nr = 0;
> > >  	pp->ops = &keystone_pcie_host_ops;
> > >  	ret = ks_dw_pcie_host_init(ks_pcie, ks_pcie->msi_intc_np);
> > >  	if (ret) {
> > > diff --git a/drivers/pci/host/pci-layerscape.c
> > b/drivers/pci/host/pci-layerscape.c
> > > index b2328ea1..79ff08c 100644
> > > --- a/drivers/pci/host/pci-layerscape.c
> > > +++ b/drivers/pci/host/pci-layerscape.c
> > > @@ -106,7 +106,7 @@ static int ls_add_pcie_port(struct ls_pcie *pcie)
> > >  	pp = &pcie->pp;
> > >  	pp->dev = pcie->dev;
> > >  	pp->dbi_base = pcie->dbi;
> > > -	pp->root_bus_nr = -1;
> > > +	pp->root_bus_nr = 0;
> > >  	pp->ops = &ls_pcie_host_ops;
> > >
> > >  	ret = dw_pcie_host_init(pp);
> > > diff --git a/drivers/pci/host/pcie-designware.c
> > b/drivers/pci/host/pcie-designware.c
> > > index c5d407c..e71a88e 100644
> > > --- a/drivers/pci/host/pcie-designware.c
> > > +++ b/drivers/pci/host/pcie-designware.c
> > > @@ -11,6 +11,7 @@
> > >   * published by the Free Software Foundation.
> > >   */
> > >
> > > +#include <linux/hardirq.h>
> > >  #include <linux/irq.h>
> > >  #include <linux/irqdomain.h>
> > >  #include <linux/kernel.h>
> > > @@ -69,16 +70,7 @@
> > >  #define PCIE_ATU_FUNC(x)		(((x) & 0x7) << 16)
> > >  #define PCIE_ATU_UPPER_TARGET		0x91C
> > >
> > > -static struct hw_pci dw_pci;
> > > -
> > > -static unsigned long global_io_offset;
> > > -
> > > -static inline struct pcie_port *sys_to_pcie(struct pci_sys_data *sys)
> > > -{
> > > -	BUG_ON(!sys->private_data);
> > > -
> > > -	return sys->private_data;
> > > -}
> > > +static struct pci_ops dw_pcie_ops;
> > >
> > >  int dw_pcie_cfg_read(void __iomem *addr, int where, int size, u32
> > *val)
> > >  {
> > > @@ -255,7 +247,7 @@ static void dw_pcie_msi_set_irq(struct pcie_port
> > *pp, int irq)
> > >  static int assign_irq(int no_irqs, struct msi_desc *desc, int *pos)
> > >  {
> > >  	int irq, pos0, i;
> > > -	struct pcie_port *pp = sys_to_pcie(desc->dev->bus->sysdata);
> > > +	struct pcie_port *pp = desc->dev->bus->sysdata;
> > >
> > >  	pos0 = bitmap_find_free_region(pp->msi_irq_in_use, MAX_MSI_IRQS,
> > >  				       order_base_2(no_irqs));
> > > @@ -298,7 +290,7 @@ static int dw_msi_setup_irq(struct msi_controller
> > *chip, struct pci_dev *pdev,
> > >  {
> > >  	int irq, pos;
> > >  	struct msi_msg msg;
> > > -	struct pcie_port *pp = sys_to_pcie(pdev->bus->sysdata);
> > > +	struct pcie_port *pp = pdev->bus->sysdata;
> > >
> > >  	if (desc->msi_attrib.is_msix)
> > >  		return -EINVAL;
> > > @@ -327,7 +319,7 @@ static void dw_msi_teardown_irq(struct
> > msi_controller *chip, unsigned int irq)
> > >  {
> > >  	struct irq_data *data = irq_get_irq_data(irq);
> > >  	struct msi_desc *msi = irq_data_get_msi(data);
> > > -	struct pcie_port *pp = sys_to_pcie(msi->dev->bus->sysdata);
> > > +	struct pcie_port *pp = msi->dev->bus->sysdata;
> > >
> > >  	clear_irq_range(pp, irq, 1, data->hwirq);
> > >  }
> > > @@ -363,14 +355,12 @@ int dw_pcie_host_init(struct pcie_port *pp)
> > >  {
> > >  	struct device_node *np = pp->dev->of_node;
> > >  	struct platform_device *pdev = to_platform_device(pp->dev);
> > > -	struct of_pci_range range;
> > > -	struct of_pci_range_parser parser;
> > > +	struct pci_bus *bus;
> > >  	struct resource *cfg_res;
> > > -	u32 val, ns;
> > > -	const __be32 *addrp;
> > > -	int i, index, ret;
> > > -
> > > -	ns = of_n_size_cells(np);
> > > +	LIST_HEAD(res);
> > > +	u32 val;
> > > +	int i, ret;
> > > +	struct resource_entry *win;
> > >
> > >  	cfg_res = platform_get_resource_byname(pdev, IORESOURCE_MEM,
> > "config");
> > >  	if (cfg_res) {
> > > @@ -378,85 +368,60 @@ int dw_pcie_host_init(struct pcie_port *pp)
> > >  		pp->cfg1_size = resource_size(cfg_res)/2;
> > >  		pp->cfg0_base = cfg_res->start;
> > >  		pp->cfg1_base = cfg_res->start + pp->cfg0_size;
> > > -
> > > -		/* Find the untranslated configuration space address */
> > > -		index = of_property_match_string(np, "reg-names", "config");
> > > -		addrp = of_get_address(np, index, NULL, NULL);
> > > -		pp->cfg0_mod_base = of_read_number(addrp, ns);
> > > -		pp->cfg1_mod_base = pp->cfg0_mod_base + pp->cfg0_size;
> > >  	} else {
> > >  		dev_err(pp->dev, "missing *config* reg space\n");
> > >  	}
> > >
> > > -	if (of_pci_range_parser_init(&parser, np)) {
> > > -		dev_err(pp->dev, "missing ranges property\n");
> > > -		return -EINVAL;
> > > -	}
> > > +	ret = of_pci_get_host_bridge_resources(np, 0, 0xff, &res, &pp-
> > >io_base);
> > > +	if (ret)
> > > +		return ret;
> > >
> > >  	/* Get the I/O and memory ranges from DT */
> > > -	for_each_of_pci_range(&parser, &range) {
> > > -		unsigned long restype = range.flags & IORESOURCE_TYPE_BITS;
> > > -
> > > -		if (restype == IORESOURCE_IO) {
> > > -			of_pci_range_to_resource(&range, np, &pp->io);
> > > -			pp->io.name = "I/O";
> > > -			pp->io.start = max_t(resource_size_t,
> > > -					     PCIBIOS_MIN_IO,
> > > -					     range.pci_addr + global_io_offset);
> > > -			pp->io.end = min_t(resource_size_t,
> > > -					   IO_SPACE_LIMIT,
> > > -					   range.pci_addr + range.size
> > > -					   + global_io_offset - 1);
> > > -			pp->io_size = resource_size(&pp->io);
> > > -			pp->io_bus_addr = range.pci_addr;
> > > -			pp->io_base = range.cpu_addr;
> > > -
> > > -			/* Find the untranslated IO space address */
> > > -			pp->io_mod_base = range.cpu_addr;
> > > -		}
> > > -		if (restype == IORESOURCE_MEM) {
> > > -			of_pci_range_to_resource(&range, np, &pp->mem);
> > > -			pp->mem.name = "MEM";
> > > -			pp->mem_size = resource_size(&pp->mem);
> > > -			pp->mem_bus_addr = range.pci_addr;
> > > -
> > > -			/* Find the untranslated MEM space address */
> > > -			pp->mem_mod_base = range.cpu_addr;
> > > -		}
> > > -		if (restype == 0) {
> > > -			of_pci_range_to_resource(&range, np, &pp->cfg);
> > > -			pp->cfg0_size = resource_size(&pp->cfg)/2;
> > > -			pp->cfg1_size = resource_size(&pp->cfg)/2;
> > > -			pp->cfg0_base = pp->cfg.start;
> > > -			pp->cfg1_base = pp->cfg.start + pp->cfg0_size;
> > > -
> > > -			/* Find the untranslated configuration space address
> > */
> > > -			pp->cfg0_mod_base = range.cpu_addr;
> > > -			pp->cfg1_mod_base = pp->cfg0_mod_base +
> > > -					    pp->cfg0_size;
> > > +	resource_list_for_each_entry(win, &res) {
> > > +		switch (resource_type(win->res)) {
> > > +		case IORESOURCE_IO:
> > > +			pp->io = win->res;
> > > +			pp->io->name = "I/O";
> > > +			pp->io_size = resource_size(pp->io);
> > > +			pp->io_bus_addr = pp->io->start - win->offset;
> > > +			ret = pci_remap_iospace(pp->io, pp->io_base);
> > > +			if (ret) {
> > > +				dev_warn(pp->dev, "error %d: failed to map
> > resource %pR\n",
> > > +					 ret, pp->io);
> > > +				continue;
> > > +			}
> > > +			break;
> > > +		case IORESOURCE_MEM:
> > > +			pp->mem = win->res;
> > > +			pp->mem->name = "MEM";
> > > +			pp->mem_size = resource_size(pp->mem);
> > > +			pp->mem_bus_addr = pp->mem->start - win->offset;
> > > +			break;
> > > +		case 0:
> > > +			pp->cfg = win->res;
> > > +			pp->cfg0_size = resource_size(pp->cfg)/2;
> > > +			pp->cfg1_size = resource_size(pp->cfg)/2;
> > > +			pp->cfg0_base = pp->cfg->start;
> > > +			pp->cfg1_base = pp->cfg->start + pp->cfg0_size;
> > > +			break;
> > > +		case IORESOURCE_BUS:
> > > +			pp->busn = win->res;
> > > +			break;
> > > +		default:
> > > +			continue;
> > >  		}
> > >  	}
> > >
> > > -	ret = of_pci_parse_bus_range(np, &pp->busn);
> > > -	if (ret < 0) {
> > > -		pp->busn.name = np->name;
> > > -		pp->busn.start = 0;
> > > -		pp->busn.end = 0xff;
> > > -		pp->busn.flags = IORESOURCE_BUS;
> > > -		dev_dbg(pp->dev, "failed to parse bus-range property: %d,
> > using default %pR\n",
> > > -			ret, &pp->busn);
> > > -	}
> > > -
> > >  	if (!pp->dbi_base) {
> > > -		pp->dbi_base = devm_ioremap(pp->dev, pp->cfg.start,
> > > -					resource_size(&pp->cfg));
> > > +		pp->dbi_base = devm_ioremap(pp->dev, pp->cfg->start,
> > > +					resource_size(pp->cfg));
> > >  		if (!pp->dbi_base) {
> > >  			dev_err(pp->dev, "error with ioremap\n");
> > >  			return -ENOMEM;
> > >  		}
> > >  	}
> > >
> > > -	pp->mem_base = pp->mem.start;
> > > +	pp->mem_base = pp->mem->start;
> > >
> > >  	if (!pp->va_cfg0_base) {
> > >  		pp->va_cfg0_base = devm_ioremap(pp->dev, pp->cfg0_base,
> > > @@ -505,7 +470,7 @@ int dw_pcie_host_init(struct pcie_port *pp)
> > >
> > >  	if (!pp->ops->rd_other_conf)
> > >  		dw_pcie_prog_outbound_atu(pp, PCIE_ATU_REGION_INDEX1,
> > > -					  PCIE_ATU_TYPE_MEM, pp->mem_mod_base,
> > > +					  PCIE_ATU_TYPE_MEM, pp->mem_base,
> > >  					  pp->mem_bus_addr, pp->mem_size);
> > >
> > >  	dw_pcie_wr_own_conf(pp, PCI_BASE_ADDRESS_0, 4, 0);
> > > @@ -517,15 +482,29 @@ int dw_pcie_host_init(struct pcie_port *pp)
> > >  	val |= PORT_LOGIC_SPEED_CHANGE;
> > >  	dw_pcie_wr_own_conf(pp, PCIE_LINK_WIDTH_SPEED_CONTROL, 4, val);
> > >
> > > -#ifdef CONFIG_PCI_MSI
> > > +	bus = pci_create_root_bus(pp->dev, pp->root_bus_nr, &dw_pcie_ops,
> > > +				  pp, &res);
> > > +	if (!bus)
> > > +		return -ENOMEM;
> > > +
> > > +#ifdef CONFIG_GENERIC_MSI_IRQ_DOMAIN
> > > +	bus->msi = container_of(&pp->irq_domain, struct msi_controller,
> > domain);
> > > +#else
> > >  	dw_pcie_msi_chip.dev = pp->dev;
> > > -	dw_pci.msi_ctrl = &dw_pcie_msi_chip;
> > > +	bus->msi = &dw_pcie_msi_chip;
> > >  #endif
> > >
> > > -	dw_pci.nr_controllers = 1;
> > > -	dw_pci.private_data = (void **)&pp;
> > > +	pci_scan_child_bus(bus);
> > > +	if (pp->ops->scan_bus)
> > > +		pp->ops->scan_bus(pp);
> > > +
> > > +#ifdef CONFIG_ARM
> > > +	/* support old dtbs that incorrectly describe IRQs */
> > > +	pci_fixup_irqs(pci_common_swizzle, of_irq_parse_and_map_pci);
> > > +#endif
> > >
> > > -	pci_common_init_dev(pp->dev, &dw_pci);
> > > +	pci_assign_unassigned_bus_resources(bus);
> > > +	pci_bus_add_devices(bus);
> > >
> > >  	return 0;
> > >  }
> > > @@ -544,12 +523,12 @@ static int dw_pcie_rd_other_conf(struct
> > pcie_port *pp, struct pci_bus *bus,
> > >
> > >  	if (bus->parent->number == pp->root_bus_nr) {
> > >  		type = PCIE_ATU_TYPE_CFG0;
> > > -		cpu_addr = pp->cfg0_mod_base;
> > > +		cpu_addr = pp->cfg0_base;
> > >  		cfg_size = pp->cfg0_size;
> > >  		va_cfg_base = pp->va_cfg0_base;
> > >  	} else {
> > >  		type = PCIE_ATU_TYPE_CFG1;
> > > -		cpu_addr = pp->cfg1_mod_base;
> > > +		cpu_addr = pp->cfg1_base;
> > >  		cfg_size = pp->cfg1_size;
> > >  		va_cfg_base = pp->va_cfg1_base;
> > >  	}
> > > @@ -559,7 +538,7 @@ static int dw_pcie_rd_other_conf(struct pcie_port
> > *pp, struct pci_bus *bus,
> > >  				  busdev, cfg_size);
> > >  	ret = dw_pcie_cfg_read(va_cfg_base + address, where, size, val);
> > >  	dw_pcie_prog_outbound_atu(pp, PCIE_ATU_REGION_INDEX0,
> > > -				  PCIE_ATU_TYPE_IO, pp->io_mod_base,
> > > +				  PCIE_ATU_TYPE_IO, pp->io_base,
> > >  				  pp->io_bus_addr, pp->io_size);
> > >
> > >  	return ret;
> > > @@ -579,12 +558,12 @@ static int dw_pcie_wr_other_conf(struct
> > pcie_port *pp, struct pci_bus *bus,
> > >
> > >  	if (bus->parent->number == pp->root_bus_nr) {
> > >  		type = PCIE_ATU_TYPE_CFG0;
> > > -		cpu_addr = pp->cfg0_mod_base;
> > > +		cpu_addr = pp->cfg0_base;
> > >  		cfg_size = pp->cfg0_size;
> > >  		va_cfg_base = pp->va_cfg0_base;
> > >  	} else {
> > >  		type = PCIE_ATU_TYPE_CFG1;
> > > -		cpu_addr = pp->cfg1_mod_base;
> > > +		cpu_addr = pp->cfg1_base;
> > >  		cfg_size = pp->cfg1_size;
> > >  		va_cfg_base = pp->va_cfg1_base;
> > >  	}
> > > @@ -594,7 +573,7 @@ static int dw_pcie_wr_other_conf(struct pcie_port
> > *pp, struct pci_bus *bus,
> > >  				  busdev, cfg_size);
> > >  	ret = dw_pcie_cfg_write(va_cfg_base + address, where, size, val);
> > >  	dw_pcie_prog_outbound_atu(pp, PCIE_ATU_REGION_INDEX0,
> > > -				  PCIE_ATU_TYPE_IO, pp->io_mod_base,
> > > +				  PCIE_ATU_TYPE_IO, pp->io_base,
> > >  				  pp->io_bus_addr, pp->io_size);
> > >
> > >  	return ret;
> > > @@ -626,7 +605,7 @@ static int dw_pcie_valid_config(struct pcie_port
> > *pp,
> > >  static int dw_pcie_rd_conf(struct pci_bus *bus, u32 devfn, int where,
> > >  			int size, u32 *val)
> > >  {
> > > -	struct pcie_port *pp = sys_to_pcie(bus->sysdata);
> > > +	struct pcie_port *pp = bus->sysdata;
> > >  	int ret;
> > >
> > >  	if (dw_pcie_valid_config(pp, bus, PCI_SLOT(devfn)) == 0) {
> > > @@ -650,7 +629,7 @@ static int dw_pcie_rd_conf(struct pci_bus *bus,
> > u32 devfn, int where,
> > >  static int dw_pcie_wr_conf(struct pci_bus *bus, u32 devfn,
> > >  			int where, int size, u32 val)
> > >  {
> > > -	struct pcie_port *pp = sys_to_pcie(bus->sysdata);
> > > +	struct pcie_port *pp = bus->sysdata;
> > >  	int ret;
> > >
> > >  	if (dw_pcie_valid_config(pp, bus, PCI_SLOT(devfn)) == 0)
> > > @@ -674,62 +653,6 @@ static struct pci_ops dw_pcie_ops = {
> > >  	.write = dw_pcie_wr_conf,
> > >  };
> > >
> > > -static int dw_pcie_setup(int nr, struct pci_sys_data *sys)
> > > -{
> > > -	struct pcie_port *pp;
> > > -
> > > -	pp = sys_to_pcie(sys);
> > > -
> > > -	if (global_io_offset < SZ_1M && pp->io_size > 0) {
> > > -		sys->io_offset = global_io_offset - pp->io_bus_addr;
> > > -		pci_ioremap_io(global_io_offset, pp->io_base);
> > > -		global_io_offset += SZ_64K;
> > > -		pci_add_resource_offset(&sys->resources, &pp->io,
> > > -					sys->io_offset);
> > > -	}
> > > -
> > > -	sys->mem_offset = pp->mem.start - pp->mem_bus_addr;
> > > -	pci_add_resource_offset(&sys->resources, &pp->mem, sys-
> > >mem_offset);
> > > -	pci_add_resource(&sys->resources, &pp->busn);
> > > -
> > > -	return 1;
> > > -}
> > > -
> > > -static struct pci_bus *dw_pcie_scan_bus(int nr, struct pci_sys_data
> > *sys)
> > > -{
> > > -	struct pci_bus *bus;
> > > -	struct pcie_port *pp = sys_to_pcie(sys);
> > > -
> > > -	pp->root_bus_nr = sys->busnr;
> > > -	bus = pci_scan_root_bus(pp->dev, sys->busnr,
> > > -				  &dw_pcie_ops, sys, &sys->resources);
> > > -	if (!bus)
> > > -		return NULL;
> > > -
> > > -	if (bus && pp->ops->scan_bus)
> > > -		pp->ops->scan_bus(pp);
> > > -
> > > -	return bus;
> > > -}
> > > -
> > > -static int dw_pcie_map_irq(const struct pci_dev *dev, u8 slot, u8
> > pin)
> > > -{
> > > -	struct pcie_port *pp = sys_to_pcie(dev->bus->sysdata);
> > > -	int irq;
> > > -
> > > -	irq = of_irq_parse_and_map_pci(dev, slot, pin);
> > > -	if (!irq)
> > > -		irq = pp->irq;
> > > -
> > > -	return irq;
> > > -}
> > > -
> > > -static struct hw_pci dw_pci = {
> > > -	.setup		= dw_pcie_setup,
> > > -	.scan		= dw_pcie_scan_bus,
> > > -	.map_irq	= dw_pcie_map_irq,
> > > -};
> > > -
> > >  void dw_pcie_setup_rc(struct pcie_port *pp)
> > >  {
> > >  	u32 val;
> > > diff --git a/drivers/pci/host/pcie-designware.h
> > b/drivers/pci/host/pcie-designware.h
> > > index d0bbd27..264c969 100644
> > > --- a/drivers/pci/host/pcie-designware.h
> > > +++ b/drivers/pci/host/pcie-designware.h
> > > @@ -27,25 +27,21 @@ struct pcie_port {
> > >  	u8			root_bus_nr;
> > >  	void __iomem		*dbi_base;
> > >  	u64			cfg0_base;
> > > -	u64			cfg0_mod_base;
> > >  	void __iomem		*va_cfg0_base;
> > >  	u32			cfg0_size;
> > >  	u64			cfg1_base;
> > > -	u64			cfg1_mod_base;
> > >  	void __iomem		*va_cfg1_base;
> > >  	u32			cfg1_size;
> > > -	u64			io_base;
> > > -	u64			io_mod_base;
> > > +	resource_size_t		io_base;
> > >  	phys_addr_t		io_bus_addr;
> > >  	u32			io_size;
> > >  	u64			mem_base;
> > > -	u64			mem_mod_base;
> > >  	phys_addr_t		mem_bus_addr;
> > >  	u32			mem_size;
> > > -	struct resource		cfg;
> > > -	struct resource		io;
> > > -	struct resource		mem;
> > > -	struct resource		busn;
> > > +	struct resource		*cfg;
> > > +	struct resource		*io;
> > > +	struct resource		*mem;
> > > +	struct resource		*busn;
> > >  	int			irq;
> > >  	u32			lanes;
> > >  	struct pcie_host_ops	*ops;
> > > diff --git a/drivers/pci/host/pcie-spear13xx.c
> > b/drivers/pci/host/pcie-spear13xx.c
> > > index c49fbdc..03eb204 100644
> > > --- a/drivers/pci/host/pcie-spear13xx.c
> > > +++ b/drivers/pci/host/pcie-spear13xx.c
> > > @@ -286,7 +286,7 @@ static int spear13xx_add_pcie_port(struct
> > pcie_port *pp,
> > >  		return ret;
> > >  	}
> > >
> > > -	pp->root_bus_nr = -1;
> > > +	pp->root_bus_nr = 0;
> > >  	pp->ops = &spear13xx_pcie_host_ops;
> > >
> > >  	ret = dw_pcie_host_init(pp);
> > 
> > --
> > Pengutronix e.K.             | Lucas Stach                 |
> > Industrial Linux Solutions   | http://www.pengutronix.de/  |
> 

-- 
Pengutronix e.K.             | Lucas Stach                 |
Industrial Linux Solutions   | http://www.pengutronix.de/  |



From vinod.koul at intel.com  Wed Aug 19 08:40:07 2015
From: vinod.koul at intel.com (Vinod Koul)
Date: Wed, 19 Aug 2015 21:10:07 +0530
Subject: [PATCH 3/7] dmaengine: st_fdma: Add STMicroelectronics FDMA
 engine driver support
In-Reply-To: <1436371888-27863-4-git-send-email-peter.griffin@linaro.org>
References: <1436371888-27863-1-git-send-email-peter.griffin@linaro.org>
 <1436371888-27863-4-git-send-email-peter.griffin@linaro.org>
Message-ID: <20150819154007.GB13546@localhost>

On Wed, Jul 08, 2015 at 05:11:24PM +0100, Peter Griffin wrote:
> +static int
> +st_fdma_elf_sanity_check(struct st_fdma_dev *fdev, const struct firmware *fw)
> +{
> +	const char *fw_name = fdev->pdata->fw_name;
> +	struct elf32_hdr *ehdr;
> +	char class;
> +
> +	if (!fw) {
> +		dev_err(fdev->dev, "failed to load %s\n", fw_name);
> +		return -EINVAL;
> +	}
> +
> +	if (fw->size < sizeof(struct elf32_hdr)) {
sizeof(*ehdr) ?

> +		dev_err(fdev->dev, "Image is too small\n");
> +		return -EINVAL;
> +	}
> +
> +	ehdr = (struct elf32_hdr *)fw->data;
> +
> +	/* We only support ELF32 at this point */
> +	class = ehdr->e_ident[EI_CLASS];
> +	if (class != ELFCLASS32) {
> +		dev_err(fdev->dev, "Unsupported class: %d\n", class);
> +		return -EINVAL;
> +	}
> +
> +	if (ehdr->e_ident[EI_DATA] != ELFDATA2LSB) {
> +		dev_err(fdev->dev, "Unsupported firmware endianness\n");
would be worth printing the value for debug

> +		return -EINVAL;
> +	}
> +
> +	if (fw->size < ehdr->e_shoff + sizeof(struct elf32_shdr)) {
> +		dev_err(fdev->dev, "Image is too small\n");
Again printing size helps when you get a log trace and have no idea why size
was small. Similar one other places


> +		dst = st_fdma_seg_to_mem(fdev, da, memsz);
> +		if (!dst) {
> +			dev_err(dev, "bad phdr da 0x%x mem 0x%x\n", da, memsz);
> +			break;
> +		}
> +
> +		if (phdr->p_filesz)
> +			memcpy(dst, elf_data + phdr->p_offset, filesz);
> +
> +		if (memsz > filesz)
> +			memset(dst + filesz, 0, memsz - filesz);
> +
> +		mem_loaded++;
> +	}
> +
> +	return (mem_loaded != fdev->drvdata->num_mem) ? -EINVAL : 0;
so you are not expecting any segment with PT_LOAD otherwise this check will
fail as num_mem is assigned from e_phnum.
Also perhaps EIO will be better return?

> +}
> +
> +static void st_fdma_enable(struct st_fdma_dev *fdev)
> +{
> +	unsigned long hw_id, hw_ver, fw_rev;
> +	u32 val;
> +
> +	/* disable CPU pipeline clock & reset cpu pipeline */
> +	val = FDMA_CLK_GATE_DIS | FDMA_CLK_GATE_RESET;
> +	fdma_write(fdev, val, CLK_GATE);

empty line here

> +	/* disable SLIM core STBus sync */
> +	fdma_write(fdev, FDMA_STBUS_SYNC_DIS, STBUS_SYNC);
> +	/* enable cpu pipeline clock */
> +	fdma_write(fdev, !FDMA_CLK_GATE_DIS, CLK_GATE);
> +
> +	/* clear int & cmd mailbox */
> +	fdma_write(fdev, ~0UL, INT_CLR);
> +	fdma_write(fdev, ~0UL, CMD_CLR);

here too

> +static int st_fdma_get_fw(struct st_fdma_dev *fdev)
> +{
> +	int ret;
> +
> +	init_completion(&fdev->fw_ack);
> +	atomic_set(&fdev->fw_loaded, 0);
> +
> +	ret = request_firmware_nowait(THIS_MODULE, FW_ACTION_HOTPLUG,
> +				      fdev->pdata->fw_name, fdev->dev,
> +				      GFP_KERNEL, fdev, st_fdma_fw_cb);

Isn't doing this in device probe too stringent and holding up load...

> +	fdesc = st_fdma_alloc_desc(fchan, sg_len);
> +	if (!fdesc) {
> +		dev_err(fchan->fdev->dev, "no memory for desc\n");
> +		return NULL;
> +	}
> +
> +	fdesc->iscyclic = false;
> +
> +	for_each_sg(sgl, sg, sg_len, i) {
> +		hw_node = fdesc->node[i].desc;
> +
> +		hw_node->next = fdesc->node[(i + 1) % sg_len].pdesc;
> +		hw_node->control = NODE_CTRL_REQ_MAP_DREQ(fchan->dreq_line);
> +
> +		if (direction == DMA_MEM_TO_DEV) {
> +			hw_node->control |= NODE_CTRL_SRC_INCR;
> +			hw_node->control |= NODE_CTRL_DST_STATIC;
> +			hw_node->saddr = sg_dma_address(sg);
> +			hw_node->daddr = fchan->cfg.dev_addr;
> +		} else {
> +			hw_node->control |= NODE_CTRL_SRC_STATIC;
> +			hw_node->control |= NODE_CTRL_DST_INCR;
> +			hw_node->saddr = fchan->cfg.dev_addr;
> +			hw_node->daddr = sg_dma_address(sg);
> +		}
> +
> +		hw_node->nbytes = sg_dma_len(sg);
> +		hw_node->generic.length = sg_dma_len(sg);
> +		hw_node->generic.sstride = 0;
> +		hw_node->generic.dstride = 0;

This looks quite similar to previous one, I think some bits can be reused

> +static int st_fdma_slave_config(struct dma_chan *chan,
> +				struct dma_slave_config *slave_cfg)
> +{
> +	u32 maxburst = 0, addr = 0;
> +	enum dma_slave_buswidth width;
> +	struct st_fdma_chan *fchan = to_st_fdma_chan(chan);
> +	int ch_id = fchan->vchan.chan.chan_id;
> +	struct st_fdma_dev *fdev = fchan->fdev;
> +
> +	if (slave_cfg->direction == DMA_DEV_TO_MEM) {

This is depreciated, you can't use direction here. Please save the fields and
then use them in prep_ call

Also this is quite big patch, consider splitting it up for faster review

-- 
~Vinod


From linux at roeck-us.net  Wed Aug 19 08:38:17 2015
From: linux at roeck-us.net (Guenter Roeck)
Date: Wed, 19 Aug 2015 08:38:17 -0700
Subject: [PATCH V3] Watchdog: Fix parent of watchdog_devices
In-Reply-To: <db7db9102158b87a4a7169e84e2272b3ba03f9f7.1439954581.git.panand@redhat.com>
References: <db7db9102158b87a4a7169e84e2272b3ba03f9f7.1439954581.git.panand@redhat.com>
Message-ID: <20150819153817.GA27186@roeck-us.net>

On Wed, Aug 19, 2015 at 08:58:24AM +0530, Pratyush Anand wrote:
> /sys/class/watchdog/watchdogn/device/modalias can help to identify the
> driver/module for a given watchdog node. However, many wdt devices does not set
> its parent and so, we do not see an entry for device in sysfs for such devices.
> 
> This patch fixes parent of watchdog_device so that
> /sys/class/watchdog/watchdogn/device is populated.
> 
> Exceptions: booke, diag288, mpc8xxx, octeon, softdog and w83627hf -- They do not
> have any parent. Not sure, how we can we identify driver for these devices.
> 
If you happen to send out another revision, please reduce the number of columns
in the description to 75 or less to avoid the checkpatch warning.
Also, it would help if you can add all the Reviewed-by: and Acked-by: tags.

> Signed-off-by: Pratyush Anand <panand at redhat.com>

Passes my build and qemu tests, and the kbuild test robot is happy this time.

Acked-by: Guenter Roeck <linux at roeck-us.net>

Guenter

> ---
> Changes since v2:
> Fixed drivers/watchdog/txx9wdt.c:134:20: error: 'pdev' undeclared
> Reported-by: kbuild test robot <fengguang.wu at intel.com>
> Changes since v1:
> Squash all commits of V1 into a single patch.
> V1 was here:
> http://www.spinics.net/lists/linux-watchdog/msg07220.html
> 
>  drivers/misc/mei/wd.c               | 1 +
>  drivers/watchdog/bcm2835_wdt.c      | 1 +
>  drivers/watchdog/bcm47xx_wdt.c      | 1 +
>  drivers/watchdog/bcm_kona_wdt.c     | 1 +
>  drivers/watchdog/coh901327_wdt.c    | 1 +
>  drivers/watchdog/da9052_wdt.c       | 1 +
>  drivers/watchdog/da9055_wdt.c       | 1 +
>  drivers/watchdog/da9062_wdt.c       | 1 +
>  drivers/watchdog/da9063_wdt.c       | 1 +
>  drivers/watchdog/davinci_wdt.c      | 1 +
>  drivers/watchdog/digicolor_wdt.c    | 1 +
>  drivers/watchdog/ep93xx_wdt.c       | 1 +
>  drivers/watchdog/gpio_wdt.c         | 1 +
>  drivers/watchdog/ie6xx_wdt.c        | 1 +
>  drivers/watchdog/intel-mid_wdt.c    | 1 +
>  drivers/watchdog/jz4740_wdt.c       | 1 +
>  drivers/watchdog/mena21_wdt.c       | 1 +
>  drivers/watchdog/menf21bmc_wdt.c    | 1 +
>  drivers/watchdog/omap_wdt.c         | 1 +
>  drivers/watchdog/orion_wdt.c        | 1 +
>  drivers/watchdog/pnx4008_wdt.c      | 1 +
>  drivers/watchdog/qcom-wdt.c         | 1 +
>  drivers/watchdog/retu_wdt.c         | 1 +
>  drivers/watchdog/rt2880_wdt.c       | 1 +
>  drivers/watchdog/s3c2410_wdt.c      | 1 +
>  drivers/watchdog/shwdt.c            | 1 +
>  drivers/watchdog/sirfsoc_wdt.c      | 1 +
>  drivers/watchdog/sp805_wdt.c        | 1 +
>  drivers/watchdog/st_lpc_wdt.c       | 1 +
>  drivers/watchdog/stmp3xxx_rtc_wdt.c | 1 +
>  drivers/watchdog/tegra_wdt.c        | 1 +
>  drivers/watchdog/twl4030_wdt.c      | 1 +
>  drivers/watchdog/txx9wdt.c          | 1 +
>  drivers/watchdog/ux500_wdt.c        | 1 +
>  drivers/watchdog/via_wdt.c          | 1 +
>  drivers/watchdog/wm831x_wdt.c       | 1 +
>  drivers/watchdog/wm8350_wdt.c       | 1 +
>  37 files changed, 37 insertions(+)
> 
> diff --git a/drivers/misc/mei/wd.c b/drivers/misc/mei/wd.c
> index 2bc0f5089f82..b346638833b0 100644
> --- a/drivers/misc/mei/wd.c
> +++ b/drivers/misc/mei/wd.c
> @@ -364,6 +364,7 @@ int mei_watchdog_register(struct mei_device *dev)
>  
>  	int ret;
>  
> +	amt_wd_dev.parent = dev->dev;
>  	/* unlock to perserve correct locking order */
>  	mutex_unlock(&dev->device_lock);
>  	ret = watchdog_register_device(&amt_wd_dev);
> diff --git a/drivers/watchdog/bcm2835_wdt.c b/drivers/watchdog/bcm2835_wdt.c
> index 7116968dee12..66c3e656a616 100644
> --- a/drivers/watchdog/bcm2835_wdt.c
> +++ b/drivers/watchdog/bcm2835_wdt.c
> @@ -182,6 +182,7 @@ static int bcm2835_wdt_probe(struct platform_device *pdev)
>  	watchdog_set_drvdata(&bcm2835_wdt_wdd, wdt);
>  	watchdog_init_timeout(&bcm2835_wdt_wdd, heartbeat, dev);
>  	watchdog_set_nowayout(&bcm2835_wdt_wdd, nowayout);
> +	bcm2835_wdt_wdd.parent = &pdev->dev;
>  	err = watchdog_register_device(&bcm2835_wdt_wdd);
>  	if (err) {
>  		dev_err(dev, "Failed to register watchdog device");
> diff --git a/drivers/watchdog/bcm47xx_wdt.c b/drivers/watchdog/bcm47xx_wdt.c
> index b28a072abf78..4064a43f1360 100644
> --- a/drivers/watchdog/bcm47xx_wdt.c
> +++ b/drivers/watchdog/bcm47xx_wdt.c
> @@ -209,6 +209,7 @@ static int bcm47xx_wdt_probe(struct platform_device *pdev)
>  
>  	wdt->wdd.info = &bcm47xx_wdt_info;
>  	wdt->wdd.timeout = WDT_DEFAULT_TIME;
> +	wdt->wdd.parent = &pdev->dev;
>  	ret = wdt->wdd.ops->set_timeout(&wdt->wdd, timeout);
>  	if (ret)
>  		goto err_timer;
> diff --git a/drivers/watchdog/bcm_kona_wdt.c b/drivers/watchdog/bcm_kona_wdt.c
> index 22d8ae65772a..e0c98423f2c9 100644
> --- a/drivers/watchdog/bcm_kona_wdt.c
> +++ b/drivers/watchdog/bcm_kona_wdt.c
> @@ -319,6 +319,7 @@ static int bcm_kona_wdt_probe(struct platform_device *pdev)
>  	spin_lock_init(&wdt->lock);
>  	platform_set_drvdata(pdev, wdt);
>  	watchdog_set_drvdata(&bcm_kona_wdt_wdd, wdt);
> +	bcm_kona_wdt_wdd.parent = &pdev->dev;
>  
>  	ret = bcm_kona_wdt_set_timeout_reg(&bcm_kona_wdt_wdd, 0);
>  	if (ret) {
> diff --git a/drivers/watchdog/coh901327_wdt.c b/drivers/watchdog/coh901327_wdt.c
> index ce12f437f195..a099b77fc0b9 100644
> --- a/drivers/watchdog/coh901327_wdt.c
> +++ b/drivers/watchdog/coh901327_wdt.c
> @@ -358,6 +358,7 @@ static int __init coh901327_probe(struct platform_device *pdev)
>  	if (ret < 0)
>  		coh901327_wdt.timeout = 60;
>  
> +	coh901327_wdt.parent = &pdev->dev;
>  	ret = watchdog_register_device(&coh901327_wdt);
>  	if (ret == 0)
>  		dev_info(&pdev->dev,
> diff --git a/drivers/watchdog/da9052_wdt.c b/drivers/watchdog/da9052_wdt.c
> index 2e9589652e1e..67e67977bd29 100644
> --- a/drivers/watchdog/da9052_wdt.c
> +++ b/drivers/watchdog/da9052_wdt.c
> @@ -195,6 +195,7 @@ static int da9052_wdt_probe(struct platform_device *pdev)
>  	da9052_wdt->timeout = DA9052_DEF_TIMEOUT;
>  	da9052_wdt->info = &da9052_wdt_info;
>  	da9052_wdt->ops = &da9052_wdt_ops;
> +	da9052_wdt->parent = &pdev->dev;
>  	watchdog_set_drvdata(da9052_wdt, driver_data);
>  
>  	kref_init(&driver_data->kref);
> diff --git a/drivers/watchdog/da9055_wdt.c b/drivers/watchdog/da9055_wdt.c
> index 495089d8dbfe..04d1430d93d2 100644
> --- a/drivers/watchdog/da9055_wdt.c
> +++ b/drivers/watchdog/da9055_wdt.c
> @@ -161,6 +161,7 @@ static int da9055_wdt_probe(struct platform_device *pdev)
>  	da9055_wdt->timeout = DA9055_DEF_TIMEOUT;
>  	da9055_wdt->info = &da9055_wdt_info;
>  	da9055_wdt->ops = &da9055_wdt_ops;
> +	da9055_wdt->parent = &pdev->dev;
>  	watchdog_set_nowayout(da9055_wdt, nowayout);
>  	watchdog_set_drvdata(da9055_wdt, driver_data);
>  
> diff --git a/drivers/watchdog/da9062_wdt.c b/drivers/watchdog/da9062_wdt.c
> index b3a870ce85be..7386111220d5 100644
> --- a/drivers/watchdog/da9062_wdt.c
> +++ b/drivers/watchdog/da9062_wdt.c
> @@ -210,6 +210,7 @@ static int da9062_wdt_probe(struct platform_device *pdev)
>  	wdt->wdtdev.max_timeout = DA9062_WDT_MAX_TIMEOUT;
>  	wdt->wdtdev.timeout = DA9062_WDG_DEFAULT_TIMEOUT;
>  	wdt->wdtdev.status = WATCHDOG_NOWAYOUT_INIT_STATUS;
> +	wdt->wdtdev.parent = &pdev->dev;
>  
>  	watchdog_set_drvdata(&wdt->wdtdev, wdt);
>  	dev_set_drvdata(&pdev->dev, wdt);
> diff --git a/drivers/watchdog/da9063_wdt.c b/drivers/watchdog/da9063_wdt.c
> index e2fe2ebdebd4..6bf130bd863d 100644
> --- a/drivers/watchdog/da9063_wdt.c
> +++ b/drivers/watchdog/da9063_wdt.c
> @@ -175,6 +175,7 @@ static int da9063_wdt_probe(struct platform_device *pdev)
>  	wdt->wdtdev.min_timeout = DA9063_WDT_MIN_TIMEOUT;
>  	wdt->wdtdev.max_timeout = DA9063_WDT_MAX_TIMEOUT;
>  	wdt->wdtdev.timeout = DA9063_WDG_TIMEOUT;
> +	wdt->wdtdev.parent = &pdev->dev;
>  
>  	wdt->wdtdev.status = WATCHDOG_NOWAYOUT_INIT_STATUS;
>  
> diff --git a/drivers/watchdog/davinci_wdt.c b/drivers/watchdog/davinci_wdt.c
> index cfdf8a408aea..17454ca653f4 100644
> --- a/drivers/watchdog/davinci_wdt.c
> +++ b/drivers/watchdog/davinci_wdt.c
> @@ -179,6 +179,7 @@ static int davinci_wdt_probe(struct platform_device *pdev)
>  	wdd->min_timeout	= 1;
>  	wdd->max_timeout	= MAX_HEARTBEAT;
>  	wdd->timeout		= DEFAULT_HEARTBEAT;
> +	wdd->parent		= &pdev->dev;
>  
>  	watchdog_init_timeout(wdd, heartbeat, dev);
>  
> diff --git a/drivers/watchdog/digicolor_wdt.c b/drivers/watchdog/digicolor_wdt.c
> index 31d8e4936611..50abe1bf62a5 100644
> --- a/drivers/watchdog/digicolor_wdt.c
> +++ b/drivers/watchdog/digicolor_wdt.c
> @@ -143,6 +143,7 @@ static int dc_wdt_probe(struct platform_device *pdev)
>  	}
>  	dc_wdt_wdd.max_timeout = U32_MAX / clk_get_rate(wdt->clk);
>  	dc_wdt_wdd.timeout = dc_wdt_wdd.max_timeout;
> +	dc_wdt_wdd.parent = &pdev->dev;
>  
>  	spin_lock_init(&wdt->lock);
>  
> diff --git a/drivers/watchdog/ep93xx_wdt.c b/drivers/watchdog/ep93xx_wdt.c
> index 7a2cc7191c58..0a4d7cc05d54 100644
> --- a/drivers/watchdog/ep93xx_wdt.c
> +++ b/drivers/watchdog/ep93xx_wdt.c
> @@ -132,6 +132,7 @@ static int ep93xx_wdt_probe(struct platform_device *pdev)
>  	val = readl(mmio_base + EP93XX_WATCHDOG);
>  	ep93xx_wdt_wdd.bootstatus = (val & 0x01) ? WDIOF_CARDRESET : 0;
>  	ep93xx_wdt_wdd.timeout = timeout;
> +	ep93xx_wdt_wdd.parent = &pdev->dev;
>  
>  	watchdog_set_nowayout(&ep93xx_wdt_wdd, nowayout);
>  
> diff --git a/drivers/watchdog/gpio_wdt.c b/drivers/watchdog/gpio_wdt.c
> index 1687cc2d7122..336bddd84809 100644
> --- a/drivers/watchdog/gpio_wdt.c
> +++ b/drivers/watchdog/gpio_wdt.c
> @@ -217,6 +217,7 @@ static int gpio_wdt_probe(struct platform_device *pdev)
>  	priv->wdd.ops		= &gpio_wdt_ops;
>  	priv->wdd.min_timeout	= SOFT_TIMEOUT_MIN;
>  	priv->wdd.max_timeout	= SOFT_TIMEOUT_MAX;
> +	priv->wdd.parent	= &pdev->dev;
>  
>  	if (watchdog_init_timeout(&priv->wdd, 0, &pdev->dev) < 0)
>  		priv->wdd.timeout = SOFT_TIMEOUT_DEF;
> diff --git a/drivers/watchdog/ie6xx_wdt.c b/drivers/watchdog/ie6xx_wdt.c
> index 9bc39ae51624..78c2541f5d52 100644
> --- a/drivers/watchdog/ie6xx_wdt.c
> +++ b/drivers/watchdog/ie6xx_wdt.c
> @@ -267,6 +267,7 @@ static int ie6xx_wdt_probe(struct platform_device *pdev)
>  
>  	ie6xx_wdt_dev.timeout = timeout;
>  	watchdog_set_nowayout(&ie6xx_wdt_dev, nowayout);
> +	ie6xx_wdt_dev.parent = &pdev->dev;
>  
>  	spin_lock_init(&ie6xx_wdt_data.unlock_sequence);
>  
> diff --git a/drivers/watchdog/intel-mid_wdt.c b/drivers/watchdog/intel-mid_wdt.c
> index 84f6701c391f..0a436b5d1e84 100644
> --- a/drivers/watchdog/intel-mid_wdt.c
> +++ b/drivers/watchdog/intel-mid_wdt.c
> @@ -137,6 +137,7 @@ static int mid_wdt_probe(struct platform_device *pdev)
>  	wdt_dev->min_timeout = MID_WDT_TIMEOUT_MIN;
>  	wdt_dev->max_timeout = MID_WDT_TIMEOUT_MAX;
>  	wdt_dev->timeout = MID_WDT_DEFAULT_TIMEOUT;
> +	wdt_dev->parent = &pdev->dev;
>  
>  	watchdog_set_drvdata(wdt_dev, &pdev->dev);
>  	platform_set_drvdata(pdev, wdt_dev);
> diff --git a/drivers/watchdog/jz4740_wdt.c b/drivers/watchdog/jz4740_wdt.c
> index 4c2cc09c0c57..6a7d5c365438 100644
> --- a/drivers/watchdog/jz4740_wdt.c
> +++ b/drivers/watchdog/jz4740_wdt.c
> @@ -174,6 +174,7 @@ static int jz4740_wdt_probe(struct platform_device *pdev)
>  	jz4740_wdt->timeout = heartbeat;
>  	jz4740_wdt->min_timeout = 1;
>  	jz4740_wdt->max_timeout = MAX_HEARTBEAT;
> +	jz4740_wdt->parent = &pdev->dev;
>  	watchdog_set_nowayout(jz4740_wdt, nowayout);
>  	watchdog_set_drvdata(jz4740_wdt, drvdata);
>  
> diff --git a/drivers/watchdog/mena21_wdt.c b/drivers/watchdog/mena21_wdt.c
> index d193a5e79c38..69013007dc47 100644
> --- a/drivers/watchdog/mena21_wdt.c
> +++ b/drivers/watchdog/mena21_wdt.c
> @@ -197,6 +197,7 @@ static int a21_wdt_probe(struct platform_device *pdev)
>  	watchdog_init_timeout(&a21_wdt, 30, &pdev->dev);
>  	watchdog_set_nowayout(&a21_wdt, nowayout);
>  	watchdog_set_drvdata(&a21_wdt, drv);
> +	a21_wdt.parent = &pdev->dev;
>  
>  	reset = a21_wdt_get_bootstatus(drv);
>  	if (reset == 2)
> diff --git a/drivers/watchdog/menf21bmc_wdt.c b/drivers/watchdog/menf21bmc_wdt.c
> index 59f0913c7341..3aefddebb386 100644
> --- a/drivers/watchdog/menf21bmc_wdt.c
> +++ b/drivers/watchdog/menf21bmc_wdt.c
> @@ -130,6 +130,7 @@ static int menf21bmc_wdt_probe(struct platform_device *pdev)
>  	drv_data->wdt.info = &menf21bmc_wdt_info;
>  	drv_data->wdt.min_timeout = BMC_WD_TIMEOUT_MIN;
>  	drv_data->wdt.max_timeout = BMC_WD_TIMEOUT_MAX;
> +	drv_data->wdt.parent = &pdev->dev;
>  	drv_data->i2c_client = i2c_client;
>  
>  	/*
> diff --git a/drivers/watchdog/omap_wdt.c b/drivers/watchdog/omap_wdt.c
> index de911c7e477c..d96bee017fd3 100644
> --- a/drivers/watchdog/omap_wdt.c
> +++ b/drivers/watchdog/omap_wdt.c
> @@ -253,6 +253,7 @@ static int omap_wdt_probe(struct platform_device *pdev)
>  	wdev->wdog.ops = &omap_wdt_ops;
>  	wdev->wdog.min_timeout = TIMER_MARGIN_MIN;
>  	wdev->wdog.max_timeout = TIMER_MARGIN_MAX;
> +	wdev->wdog.parent = &pdev->dev;
>  
>  	if (watchdog_init_timeout(&wdev->wdog, timer_margin, &pdev->dev) < 0)
>  		wdev->wdog.timeout = TIMER_MARGIN_DEFAULT;
> diff --git a/drivers/watchdog/orion_wdt.c b/drivers/watchdog/orion_wdt.c
> index ef0c628d5037..c6b8f4a43bde 100644
> --- a/drivers/watchdog/orion_wdt.c
> +++ b/drivers/watchdog/orion_wdt.c
> @@ -567,6 +567,7 @@ static int orion_wdt_probe(struct platform_device *pdev)
>  
>  	dev->wdt.timeout = wdt_max_duration;
>  	dev->wdt.max_timeout = wdt_max_duration;
> +	dev->wdt.parent = &pdev->dev;
>  	watchdog_init_timeout(&dev->wdt, heartbeat, &pdev->dev);
>  
>  	platform_set_drvdata(pdev, &dev->wdt);
> diff --git a/drivers/watchdog/pnx4008_wdt.c b/drivers/watchdog/pnx4008_wdt.c
> index b9c6049c3e78..4224b3ec83a5 100644
> --- a/drivers/watchdog/pnx4008_wdt.c
> +++ b/drivers/watchdog/pnx4008_wdt.c
> @@ -167,6 +167,7 @@ static int pnx4008_wdt_probe(struct platform_device *pdev)
>  
>  	pnx4008_wdd.bootstatus = (readl(WDTIM_RES(wdt_base)) & WDOG_RESET) ?
>  			WDIOF_CARDRESET : 0;
> +	pnx4008_wdd.parent = &pdev->dev;
>  	watchdog_set_nowayout(&pnx4008_wdd, nowayout);
>  
>  	pnx4008_wdt_stop(&pnx4008_wdd);	/* disable for now */
> diff --git a/drivers/watchdog/qcom-wdt.c b/drivers/watchdog/qcom-wdt.c
> index aa03ca8f2d9b..773dcfaee7b2 100644
> --- a/drivers/watchdog/qcom-wdt.c
> +++ b/drivers/watchdog/qcom-wdt.c
> @@ -171,6 +171,7 @@ static int qcom_wdt_probe(struct platform_device *pdev)
>  	wdt->wdd.ops = &qcom_wdt_ops;
>  	wdt->wdd.min_timeout = 1;
>  	wdt->wdd.max_timeout = 0x10000000U / wdt->rate;
> +	wdt->wdd.parent = &pdev->dev;
>  
>  	/*
>  	 * If 'timeout-sec' unspecified in devicetree, assume a 30 second
> diff --git a/drivers/watchdog/retu_wdt.c b/drivers/watchdog/retu_wdt.c
> index b7c68e275aeb..39cd51df2ffc 100644
> --- a/drivers/watchdog/retu_wdt.c
> +++ b/drivers/watchdog/retu_wdt.c
> @@ -127,6 +127,7 @@ static int retu_wdt_probe(struct platform_device *pdev)
>  	retu_wdt->timeout	= RETU_WDT_MAX_TIMER;
>  	retu_wdt->min_timeout	= 0;
>  	retu_wdt->max_timeout	= RETU_WDT_MAX_TIMER;
> +	retu_wdt->parent	= &pdev->dev;
>  
>  	watchdog_set_drvdata(retu_wdt, wdev);
>  	watchdog_set_nowayout(retu_wdt, nowayout);
> diff --git a/drivers/watchdog/rt2880_wdt.c b/drivers/watchdog/rt2880_wdt.c
> index a6f7e2e29beb..1967919ae743 100644
> --- a/drivers/watchdog/rt2880_wdt.c
> +++ b/drivers/watchdog/rt2880_wdt.c
> @@ -161,6 +161,7 @@ static int rt288x_wdt_probe(struct platform_device *pdev)
>  	rt288x_wdt_dev.dev = &pdev->dev;
>  	rt288x_wdt_dev.bootstatus = rt288x_wdt_bootcause();
>  	rt288x_wdt_dev.max_timeout = (0xfffful / rt288x_wdt_freq);
> +	rt288x_wdt_dev.parent = &pdev->dev;
>  
>  	watchdog_init_timeout(&rt288x_wdt_dev, rt288x_wdt_dev.max_timeout,
>  			      &pdev->dev);
> diff --git a/drivers/watchdog/s3c2410_wdt.c b/drivers/watchdog/s3c2410_wdt.c
> index e89ae027c91d..d781000c7825 100644
> --- a/drivers/watchdog/s3c2410_wdt.c
> +++ b/drivers/watchdog/s3c2410_wdt.c
> @@ -607,6 +607,7 @@ static int s3c2410wdt_probe(struct platform_device *pdev)
>  	watchdog_set_nowayout(&wdt->wdt_device, nowayout);
>  
>  	wdt->wdt_device.bootstatus = s3c2410wdt_get_bootstatus(wdt);
> +	wdt->wdt_device.parent = &pdev->dev;
>  
>  	ret = watchdog_register_device(&wdt->wdt_device);
>  	if (ret) {
> diff --git a/drivers/watchdog/shwdt.c b/drivers/watchdog/shwdt.c
> index 567458b137a6..f90812170657 100644
> --- a/drivers/watchdog/shwdt.c
> +++ b/drivers/watchdog/shwdt.c
> @@ -252,6 +252,7 @@ static int sh_wdt_probe(struct platform_device *pdev)
>  
>  	watchdog_set_nowayout(&sh_wdt_dev, nowayout);
>  	watchdog_set_drvdata(&sh_wdt_dev, wdt);
> +	sh_wdt_dev.parent = &pdev->dev;
>  
>  	spin_lock_init(&wdt->lock);
>  
> diff --git a/drivers/watchdog/sirfsoc_wdt.c b/drivers/watchdog/sirfsoc_wdt.c
> index 42fa5c0c518a..d0578ab2e636 100644
> --- a/drivers/watchdog/sirfsoc_wdt.c
> +++ b/drivers/watchdog/sirfsoc_wdt.c
> @@ -154,6 +154,7 @@ static int sirfsoc_wdt_probe(struct platform_device *pdev)
>  
>  	watchdog_init_timeout(&sirfsoc_wdd, timeout, &pdev->dev);
>  	watchdog_set_nowayout(&sirfsoc_wdd, nowayout);
> +	sirfsoc_wdd.parent = &pdev->dev;
>  
>  	ret = watchdog_register_device(&sirfsoc_wdd);
>  	if (ret)
> diff --git a/drivers/watchdog/sp805_wdt.c b/drivers/watchdog/sp805_wdt.c
> index 4e7fec36f5c3..01d816251302 100644
> --- a/drivers/watchdog/sp805_wdt.c
> +++ b/drivers/watchdog/sp805_wdt.c
> @@ -226,6 +226,7 @@ sp805_wdt_probe(struct amba_device *adev, const struct amba_id *id)
>  	wdt->adev = adev;
>  	wdt->wdd.info = &wdt_info;
>  	wdt->wdd.ops = &wdt_ops;
> +	wdt->wdd.parent = &adev->dev;
>  
>  	spin_lock_init(&wdt->lock);
>  	watchdog_set_nowayout(&wdt->wdd, nowayout);
> diff --git a/drivers/watchdog/st_lpc_wdt.c b/drivers/watchdog/st_lpc_wdt.c
> index 6785afdc0fca..14e9badf2bfa 100644
> --- a/drivers/watchdog/st_lpc_wdt.c
> +++ b/drivers/watchdog/st_lpc_wdt.c
> @@ -241,6 +241,7 @@ static int st_wdog_probe(struct platform_device *pdev)
>  		return -EINVAL;
>  	}
>  	st_wdog_dev.max_timeout = 0xFFFFFFFF / st_wdog->clkrate;
> +	st_wdog_dev.parent = &pdev->dev;
>  
>  	ret = clk_prepare_enable(clk);
>  	if (ret) {
> diff --git a/drivers/watchdog/stmp3xxx_rtc_wdt.c b/drivers/watchdog/stmp3xxx_rtc_wdt.c
> index e7f0d5b60d3d..3ee6128a540e 100644
> --- a/drivers/watchdog/stmp3xxx_rtc_wdt.c
> +++ b/drivers/watchdog/stmp3xxx_rtc_wdt.c
> @@ -76,6 +76,7 @@ static int stmp3xxx_wdt_probe(struct platform_device *pdev)
>  	watchdog_set_drvdata(&stmp3xxx_wdd, &pdev->dev);
>  
>  	stmp3xxx_wdd.timeout = clamp_t(unsigned, heartbeat, 1, STMP3XXX_MAX_TIMEOUT);
> +	stmp3xxx_wdd.parent = &pdev->dev;
>  
>  	ret = watchdog_register_device(&stmp3xxx_wdd);
>  	if (ret < 0) {
> diff --git a/drivers/watchdog/tegra_wdt.c b/drivers/watchdog/tegra_wdt.c
> index 30451ea46902..7f97cdd53f29 100644
> --- a/drivers/watchdog/tegra_wdt.c
> +++ b/drivers/watchdog/tegra_wdt.c
> @@ -218,6 +218,7 @@ static int tegra_wdt_probe(struct platform_device *pdev)
>  	wdd->ops = &tegra_wdt_ops;
>  	wdd->min_timeout = MIN_WDT_TIMEOUT;
>  	wdd->max_timeout = MAX_WDT_TIMEOUT;
> +	wdd->parent = &pdev->dev;
>  
>  	watchdog_set_drvdata(wdd, wdt);
>  
> diff --git a/drivers/watchdog/twl4030_wdt.c b/drivers/watchdog/twl4030_wdt.c
> index 2c1db6fa9a27..9bf3cc0f3961 100644
> --- a/drivers/watchdog/twl4030_wdt.c
> +++ b/drivers/watchdog/twl4030_wdt.c
> @@ -83,6 +83,7 @@ static int twl4030_wdt_probe(struct platform_device *pdev)
>  	wdt->timeout		= 30;
>  	wdt->min_timeout	= 1;
>  	wdt->max_timeout	= 30;
> +	wdt->parent = &pdev->dev;
>  
>  	watchdog_set_nowayout(wdt, nowayout);
>  	platform_set_drvdata(pdev, wdt);
> diff --git a/drivers/watchdog/txx9wdt.c b/drivers/watchdog/txx9wdt.c
> index 7f615933d31a..c2da880292bc 100644
> --- a/drivers/watchdog/txx9wdt.c
> +++ b/drivers/watchdog/txx9wdt.c
> @@ -131,6 +131,7 @@ static int __init txx9wdt_probe(struct platform_device *dev)
>  	txx9wdt.timeout = timeout;
>  	txx9wdt.min_timeout = 1;
>  	txx9wdt.max_timeout = WD_MAX_TIMEOUT;
> +	txx9wdt.parent = &dev->dev;
>  	watchdog_set_nowayout(&txx9wdt, nowayout);
>  
>  	ret = watchdog_register_device(&txx9wdt);
> diff --git a/drivers/watchdog/ux500_wdt.c b/drivers/watchdog/ux500_wdt.c
> index 9de09ab00838..37c084353cce 100644
> --- a/drivers/watchdog/ux500_wdt.c
> +++ b/drivers/watchdog/ux500_wdt.c
> @@ -96,6 +96,7 @@ static int ux500_wdt_probe(struct platform_device *pdev)
>  			ux500_wdt.max_timeout = WATCHDOG_MAX28;
>  	}
>  
> +	ux500_wdt.parent = &pdev->dev;
>  	watchdog_set_nowayout(&ux500_wdt, nowayout);
>  
>  	/* disable auto off on sleep */
> diff --git a/drivers/watchdog/via_wdt.c b/drivers/watchdog/via_wdt.c
> index 56369c4f1961..5f9cbc37520d 100644
> --- a/drivers/watchdog/via_wdt.c
> +++ b/drivers/watchdog/via_wdt.c
> @@ -206,6 +206,7 @@ static int wdt_probe(struct pci_dev *pdev,
>  		timeout = WDT_TIMEOUT;
>  
>  	wdt_dev.timeout = timeout;
> +	wdt_dev.parent = &pdev->dev;
>  	watchdog_set_nowayout(&wdt_dev, nowayout);
>  	if (readl(wdt_mem) & VIA_WDT_FIRED)
>  		wdt_dev.bootstatus |= WDIOF_CARDRESET;
> diff --git a/drivers/watchdog/wm831x_wdt.c b/drivers/watchdog/wm831x_wdt.c
> index 2fa17e746ff6..8d1184aee932 100644
> --- a/drivers/watchdog/wm831x_wdt.c
> +++ b/drivers/watchdog/wm831x_wdt.c
> @@ -215,6 +215,7 @@ static int wm831x_wdt_probe(struct platform_device *pdev)
>  
>  	wm831x_wdt->info = &wm831x_wdt_info;
>  	wm831x_wdt->ops = &wm831x_wdt_ops;
> +	wm831x_wdt->parent = &pdev->dev;
>  	watchdog_set_nowayout(wm831x_wdt, nowayout);
>  	watchdog_set_drvdata(wm831x_wdt, driver_data);
>  
> diff --git a/drivers/watchdog/wm8350_wdt.c b/drivers/watchdog/wm8350_wdt.c
> index 34d272ada23d..4ab4b8347d45 100644
> --- a/drivers/watchdog/wm8350_wdt.c
> +++ b/drivers/watchdog/wm8350_wdt.c
> @@ -151,6 +151,7 @@ static int wm8350_wdt_probe(struct platform_device *pdev)
>  
>  	watchdog_set_nowayout(&wm8350_wdt, nowayout);
>  	watchdog_set_drvdata(&wm8350_wdt, wm8350);
> +	wm8350_wdt.parent = &pdev->dev;
>  
>  	/* Default to 4s timeout */
>  	wm8350_wdt_set_timeout(&wm8350_wdt, 4);
> -- 
> 2.4.3
> 
> --
> To unsubscribe from this list: send the line "unsubscribe linux-watchdog" in
> the body of a message to majordomo at vger.kernel.org
> More majordomo info at  http://vger.kernel.org/majordomo-info.html


From robert.richter at caviumnetworks.com  Wed Aug 19 08:43:46 2015
From: robert.richter at caviumnetworks.com (Robert Richter)
Date: Wed, 19 Aug 2015 17:43:46 +0200
Subject: [PATCH v4 2/5] irqchip, gicv3: Workaround for Cavium ThunderX
 erratum 23154
In-Reply-To: <20150817164003.GB2906@e104818-lin.cambridge.arm.com>
References: <1439576885-15621-1-git-send-email-rric@kernel.org>
 <1439576885-15621-3-git-send-email-rric@kernel.org>
 <20150817164003.GB2906@e104818-lin.cambridge.arm.com>
Message-ID: <20150819154346.GX1820@rric.localhost>

On 17.08.15 17:40:03, Catalin Marinas wrote:
> On Fri, Aug 14, 2015 at 08:28:02PM +0200, Robert Richter wrote:
> > +struct static_key is_cavium_thunderx = STATIC_KEY_INIT_FALSE;

Will add the static ...

> This could also be "static struct ...". BTW, the use of static_key
> directly is deprecated, so just do:
> 
> static DEFINE_STATIC_KEY_FALSE(is_cavium_thunderx);

... and for simplicity a patch with this after the jump laber bits are
merged upstream.

-Robert


From vinod.koul at intel.com  Wed Aug 19 08:51:54 2015
From: vinod.koul at intel.com (Vinod Koul)
Date: Wed, 19 Aug 2015 21:21:54 +0530
Subject: [PATCH] dmaengine: at_xdmac: fix bug in prep_dma_cyclic
In-Reply-To: <1437574349-13816-1-git-send-email-ludovic.desroches@atmel.com>
References: <1437574349-13816-1-git-send-email-ludovic.desroches@atmel.com>
Message-ID: <20150819155154.GC13546@localhost>

On Wed, Jul 22, 2015 at 04:12:29PM +0200, Ludovic Desroches wrote:
> In cyclic mode, the round chaining has been broken by the introduction
> of at_xdmac_queue_desc(): AT_XDMAC_MBR_UBC_NDE is set for all descriptors
> excepted for the last one. at_xdmac_queue_desc() has to be called one
> more time to chain the last and the first descriptors.

Applied, thanks

-- 
~Vinod



From catalin.marinas at arm.com  Wed Aug 19 09:03:20 2015
From: catalin.marinas at arm.com (Catalin Marinas)
Date: Wed, 19 Aug 2015 17:03:20 +0100
Subject: [PATCH] arm64: entry: always restore x0 from the stack on
 syscall return
In-Reply-To: <1439996989-5772-1-git-send-email-will.deacon@arm.com>
References: <1439996989-5772-1-git-send-email-will.deacon@arm.com>
Message-ID: <20150819160320.GI24062@e104818-lin.cambridge.arm.com>

On Wed, Aug 19, 2015 at 04:09:49PM +0100, Will Deacon wrote:
> @@ -613,13 +609,14 @@ ENDPROC(cpu_switch_to)
>   */
>  ret_fast_syscall:
>  	disable_irq				// disable interrupts
> +	str	x0, [sp, #S_X0]			// returned x0
>  	ldr	x1, [tsk, #TI_FLAGS]		// re-check for syscall tracing
>  	and	x2, x1, #_TIF_SYSCALL_WORK
>  	cbnz	x2, ret_fast_syscall_trace
>  	and	x2, x1, #_TIF_WORK_MASK
> -	cbnz	x2, fast_work_pending
> +	cbnz	x2, work_pending
>  	enable_step_tsk x1, x2
> -	kernel_exit 0, ret = 1
> +	kernel_exit 0
>  ret_fast_syscall_trace:
>  	enable_irq				// enable interrupts
>  	b	__sys_trace_return

There is another str x0 in __sys_trace_return which I think we could
remove.

-- 
Catalin


From robert.richter at caviumnetworks.com  Wed Aug 19 09:05:58 2015
From: robert.richter at caviumnetworks.com (Robert Richter)
Date: Wed, 19 Aug 2015 18:05:58 +0200
Subject: [PATCH v4 2/5] irqchip, gicv3: Workaround for Cavium ThunderX
 erratum 23154
In-Reply-To: <55D21345.3040903@caviumnetworks.com>
References: <1439576885-15621-1-git-send-email-rric@kernel.org>
 <1439576885-15621-3-git-send-email-rric@kernel.org>
 <55D21345.3040903@caviumnetworks.com>
Message-ID: <20150819160558.GY1820@rric.localhost>

On 17.08.15 10:00:53, David Daney wrote:
> On 08/14/2015 11:28 AM, Robert Richter wrote:
> >+config CAVIUM_ERRATUM_23154
> >+	bool "Cavium erratum 23154: Access to ICC_IAR1_EL1 is not sync'ed"
> >+	depends on ARCH_THUNDER
> 
> None of the other errata depend on a specific ARCH_*.  I think we should
> remove this 'depends on', so that a generic kernel can be configured to work
> on Thunder without having to first select ARCH_THUNDER.

Right, will remove the dependency. Same as for the other errata then.

Thanks,

-Robert

> >+	default y
> >+	help
> >+	  The gicv3 of ThunderX requires a modified version for
> >+	  reading the IAR status to ensure data synchronization
> >+	  (access to icc_iar1_el1 is not sync'ed before and after).
> >+
> >+	  If unsure, say Y.


From timur at codeaurora.org  Wed Aug 19 09:16:52 2015
From: timur at codeaurora.org (Timur Tabi)
Date: Wed, 19 Aug 2015 11:16:52 -0500
Subject: [PATCH 2/3] [v4] ARM64: TTY: hvc_dcc: Add support for ARM64 dcc
In-Reply-To: <20150819101426.GB6281@e103592.cambridge.arm.com>
References: <1438992995-22610-1-git-send-email-timur@codeaurora.org>
 <1438992995-22610-2-git-send-email-timur@codeaurora.org>
 <20150810094008.GD1604@arm.com> <55D2749A.401@codeaurora.org>
 <20150818082141.GA6281@e103592.cambridge.arm.com>
 <55D3825D.6020105@codeaurora.org>
 <20150819101426.GB6281@e103592.cambridge.arm.com>
Message-ID: <55D4ABF4.5020600@codeaurora.org>

On 08/19/2015 05:14 AM, Dave Martin wrote:
>> >So does that mean that ldrb will zero-extend the byte to all 64 bits of x3?
> Yes.  No extra operation is required.

So my patch is actually correct as-is?

-- 
Qualcomm Innovation Center, Inc.
The Qualcomm Innovation Center, Inc. is a member of the
Code Aurora Forum, a Linux Foundation Collaborative Project.


From will.deacon at arm.com  Wed Aug 19 09:23:59 2015
From: will.deacon at arm.com (Will Deacon)
Date: Wed, 19 Aug 2015 17:23:59 +0100
Subject: [PATCH] arm64: entry: always restore x0 from the stack on
 syscall return
In-Reply-To: <20150819160320.GI24062@e104818-lin.cambridge.arm.com>
References: <1439996989-5772-1-git-send-email-will.deacon@arm.com>
 <20150819160320.GI24062@e104818-lin.cambridge.arm.com>
Message-ID: <20150819162359.GA10297@arm.com>

On Wed, Aug 19, 2015 at 05:03:20PM +0100, Catalin Marinas wrote:
> On Wed, Aug 19, 2015 at 04:09:49PM +0100, Will Deacon wrote:
> > @@ -613,13 +609,14 @@ ENDPROC(cpu_switch_to)
> >   */
> >  ret_fast_syscall:
> >  	disable_irq				// disable interrupts
> > +	str	x0, [sp, #S_X0]			// returned x0
> >  	ldr	x1, [tsk, #TI_FLAGS]		// re-check for syscall tracing
> >  	and	x2, x1, #_TIF_SYSCALL_WORK
> >  	cbnz	x2, ret_fast_syscall_trace
> >  	and	x2, x1, #_TIF_WORK_MASK
> > -	cbnz	x2, fast_work_pending
> > +	cbnz	x2, work_pending
> >  	enable_step_tsk x1, x2
> > -	kernel_exit 0, ret = 1
> > +	kernel_exit 0
> >  ret_fast_syscall_trace:
> >  	enable_irq				// enable interrupts
> >  	b	__sys_trace_return
> 
> There is another str x0 in __sys_trace_return which I think we could
> remove.

Hmm, I don't think we can remove that. It's needed on the slowpath to
update the pt_regs with either -ENOSYS (for __ni_sys_trace) or the
syscall return value from the blr in __sys_trace.

What we can do instead is change the branch above to branch to
__sys_trace_return_skipped. Patch below.

Will

--->8

diff --git a/arch/arm64/kernel/entry.S b/arch/arm64/kernel/entry.S
index 2a5e64ccc991..088322ff1ba0 100644
--- a/arch/arm64/kernel/entry.S
+++ b/arch/arm64/kernel/entry.S
@@ -619,7 +619,7 @@ ret_fast_syscall:
        kernel_exit 0
 ret_fast_syscall_trace:
        enable_irq                              // enable interrupts
-       b       __sys_trace_return
+       b       __sys_trace_return_skipped      // we already saved x0
 
 /*
  * Ok, we need to do extra processing, enter the slow path.



From catalin.marinas at arm.com  Wed Aug 19 09:35:05 2015
From: catalin.marinas at arm.com (Catalin Marinas)
Date: Wed, 19 Aug 2015 17:35:05 +0100
Subject: [PATCH] arm64: entry: always restore x0 from the stack on
 syscall return
In-Reply-To: <20150819162359.GA10297@arm.com>
References: <1439996989-5772-1-git-send-email-will.deacon@arm.com>
 <20150819160320.GI24062@e104818-lin.cambridge.arm.com>
 <20150819162359.GA10297@arm.com>
Message-ID: <20150819163504.GL24062@e104818-lin.cambridge.arm.com>

On Wed, Aug 19, 2015 at 05:23:59PM +0100, Will Deacon wrote:
> On Wed, Aug 19, 2015 at 05:03:20PM +0100, Catalin Marinas wrote:
> > On Wed, Aug 19, 2015 at 04:09:49PM +0100, Will Deacon wrote:
> > > @@ -613,13 +609,14 @@ ENDPROC(cpu_switch_to)
> > >   */
> > >  ret_fast_syscall:
> > >  	disable_irq				// disable interrupts
> > > +	str	x0, [sp, #S_X0]			// returned x0
> > >  	ldr	x1, [tsk, #TI_FLAGS]		// re-check for syscall tracing
> > >  	and	x2, x1, #_TIF_SYSCALL_WORK
> > >  	cbnz	x2, ret_fast_syscall_trace
> > >  	and	x2, x1, #_TIF_WORK_MASK
> > > -	cbnz	x2, fast_work_pending
> > > +	cbnz	x2, work_pending
> > >  	enable_step_tsk x1, x2
> > > -	kernel_exit 0, ret = 1
> > > +	kernel_exit 0
> > >  ret_fast_syscall_trace:
> > >  	enable_irq				// enable interrupts
> > >  	b	__sys_trace_return
> > 
> > There is another str x0 in __sys_trace_return which I think we could
> > remove.
> 
> Hmm, I don't think we can remove that. It's needed on the slowpath to
> update the pt_regs with either -ENOSYS (for __ni_sys_trace) or the
> syscall return value from the blr in __sys_trace.
> 
> What we can do instead is change the branch above to branch to
> __sys_trace_return_skipped. Patch below.
> 
> Will
> 
> --->8
> 
> diff --git a/arch/arm64/kernel/entry.S b/arch/arm64/kernel/entry.S
> index 2a5e64ccc991..088322ff1ba0 100644
> --- a/arch/arm64/kernel/entry.S
> +++ b/arch/arm64/kernel/entry.S
> @@ -619,7 +619,7 @@ ret_fast_syscall:
>         kernel_exit 0
>  ret_fast_syscall_trace:
>         enable_irq                              // enable interrupts
> -       b       __sys_trace_return
> +       b       __sys_trace_return_skipped      // we already saved x0

That would do. With this added:

Reviewed-by: Catalin Marinas <catalin.marinas at arm.com>

(or I can take it for 4.2 but I'd like more testing like LTP)


From gabriele.paoloni at huawei.com  Wed Aug 19 09:34:47 2015
From: gabriele.paoloni at huawei.com (Gabriele Paoloni)
Date: Wed, 19 Aug 2015 16:34:47 +0000
Subject: [PATCH v7 3/6] PCI: designware: Add ARM64 support
In-Reply-To: <1439998622.31432.44.camel@pengutronix.de>
References: <1439812554-180426-1-git-send-email-wangzhou1@hisilicon.com>
 <1439812554-180426-4-git-send-email-wangzhou1@hisilicon.com>
 <1439988852.31432.15.camel@pengutronix.de>
 <EE11001F9E5DDD47B7634E2F8A612F2E01D81315@lhreml503-mbs>
 <1439998622.31432.44.camel@pengutronix.de>
Message-ID: <EE11001F9E5DDD47B7634E2F8A612F2E01D8139B@lhreml503-mbs>

Hi Lucas

First of all many thanks for the quick reply, really appreciated

> -----Original Message-----
> From: Lucas Stach [mailto:l.stach at pengutronix.de]
> Sent: Wednesday, August 19, 2015 4:37 PM
> To: Gabriele Paoloni
> Cc: Wangzhou (B); Bjorn Helgaas; jingoohan1 at gmail.com; Pratyush Anand;
> Arnd Bergmann; linux at arm.linux.org.uk; thomas.petazzoni at free-
> electrons.com; lorenzo.pieralisi at arm.com; james.morse at arm.com;
> Liviu.Dudau at arm.com; jason at lakedaemon.net; robh at kernel.org; linux-
> pci at vger.kernel.org; linux-arm-kernel at lists.infradead.org;
> devicetree at vger.kernel.org; Yuanzhichang; Zhudacai; zhangjukuo;
> qiuzhenfa; liudongdong (C); qiujiang; xuwei (O); Liguozhu (Kenneth)
> Subject: Re: [PATCH v7 3/6] PCI: designware: Add ARM64 support
> 
> Hi Gab,
> 
> Am Mittwoch, den 19.08.2015, 15:16 +0000 schrieb Gabriele Paoloni:
> > Hi Lucas
> >
> > I have rewritten the patch to take into account multiple controllers.
> >
> > As you can see now there is a static var in dw_pcie_host_init() that
> tracks
> > the bus numbers used.
> 
> This is wrong. The DT specifies the valid bus number range. You can not
> just assign the next free bus number to the root bus.

I think this is what is being done in
http://lxr.free-electrons.com/source/arch/arm/kernel/bios32.c#L495
and currently designware assigns the root bus number in
http://lxr.free-electrons.com/source/drivers/pci/host/pcie-designware.c#L730


In general I agree with you but if you look at all the current drivers 
based on designware none of them define the "bus-range" dtb property.
Therefore doing as you say would break the current driver when we have
multiple controllers...am I right?

If that is the case in order to fix this in the way you say I would need
to assign "bus-range" for all the PCIe drivers with multiple controllers:
in this case I would split the default range evenly (that is, if we have 
two controllers I would define "bus-range"  0-127 and 128-255)

If you think this solution is ok I can go for it. My only doubt was about
touching other vendors DTBs....


> 
> It is perfectly valid to have a bus range of 0x00-0x10 assigned to one
> instance and 0x50-0xff to the next instance. Additional with PCIe
> hotplug you may not use the full range of the bus numbers on one
> instance at the first scan, but only later populate more buses when
> more
> bridges are added to the tree.
> 
> > Drivers that do not specify the bus range in the DTB set pp-
> >root_bus_nr = DW_ROOT_NR_UNDEFINED.
> > Designware will check if the flag is set and will use the automatic
> bus range
> > assignment.
> 
> No, please lets get rid of this assignment altogether. The glue drivers
> have no business in assigning the bus range. Please remove the
> pp->root_bus_nr assignment from all the glue drivers.
> 
> "bus range" is a generic DW PCIe property, so just parse the root bus
> number from the DT, it is handled the same way for all the DW based
> PCIe
> drivers. The bindings specifies that if the bus range property is
> missing the range is 0x00-0xff, so you can default to 0 as the root bus
> number in that case.
> 
> Also I would think this conversion warrants a patch on its own and
> should not be mixed in the ARM64 support patch.
> 
> Regards,
> Lucas
> 
> > Instead if the driver assigns pp->root_bus_nr according to the dtb,
> designwware
> > will use the value passed in by the driver.
> > Below the relevant section:
> >
> >
> > +	static int root_bus_nr = 0;
> > ...
> > +	mutex_lock(&root_bus_nr_mux);
> > +
> > +	if (pp->root_bus_nr != DW_ROOT_NR_UNDEFINED)
> > +		root_bus_nr = pp->root_bus_nr;
> > +
> > +	bus = pci_create_root_bus(pp->dev, root_bus_nr, &dw_pcie_ops,
> > +			      pp, &res);
> > +	if (!bus) {
> > +		mutex_unlock(&root_bus_nr_mux);
> > +		return -ENOMEM;
> > +	}
> > +
> > +	root_bus_nr += bus->busn_res.end + 1;
> > +	mutex_unlock(&root_bus_nr_mux);
> >
> > Please let me know what you think...
> >
> > Many Thanks
> >
> > Gab
> > ----------
> >
> > From: gabriele paoloni <gabriele.paoloni at huawei.com>
> >
> > This patch tries to unify ARM32 and ARM64 PCIe in designware driver.
> Delete
> > function dw_pcie_setup, dw_pcie_scan_bus, dw_pcie_map_irq and struct
> hw_pci,
> > move related operations to dw_pcie_host_init.
> > Also set pp->root_bus_nr = DW_ROOT_NR_UNDEFINED in all the drivers
> that
> > are based on designware to flag that the drivers do not read the bus
> > ranges from DT.
> > This patch also adds handling of multiple PCI domains in designware.
> > if the PCI host bridge driver does not specify a root bus number, in
> case
> > of multiple domains, designware will automatillay set the next domain
> root
> > bus number to the last bus number used in the last domain + 1.
> >
> > This patch also try to use of_pci_get_host_bridge_resources for ARM32
> and
> > ARM64 according to the suggestion for Gabriele[1]
> >
> > This patch is based on Gabriele's patch about of_pci_range fix[2]
> >
> > Finally this patch reverts commit f4c55c5a3f7f "PCI: designware:
> > Program ATU with untranslated address". This was discussed in [3]
> >
> > I have compiled the driver with multi_v7_defconfig. However, I don't
> have
> > ARM32 PCIe related board to do test. It will be appreciated if
> someone could
> > help to test it.
> >
> > Signed-off-by: Zhou Wang <wangzhou1 at hisilicon.com>
> > Signed-off-by: Arnd Bergmann <arnd at arndb.de>
> > Signed-off-by: Gabriele Paoloni <gabriele.paoloni at huawei.com>
> >
> > [1] http://www.spinics.net/lists/linux-pci/msg42194.html
> > [2] https://patchwork.ozlabs.org/patch/495018/
> > [3] http://www.spinics.net/lists/arm-kernel/msg436779.html
> > ---
> >  drivers/pci/host/pci-dra7xx.c      |  15 +--
> >  drivers/pci/host/pci-exynos.c      |   2 +-
> >  drivers/pci/host/pci-imx6.c        |   2 +-
> >  drivers/pci/host/pci-keystone-dw.c |   2 +-
> >  drivers/pci/host/pci-keystone.c    |   2 +-
> >  drivers/pci/host/pci-layerscape.c  |   2 +-
> >  drivers/pci/host/pcie-designware.c | 247 ++++++++++++++-------------
> ----------
> >  drivers/pci/host/pcie-designware.h |  15 +--
> >  drivers/pci/host/pcie-spear13xx.c  |   2 +-
> >  9 files changed, 110 insertions(+), 179 deletions(-)
> >
> > diff --git a/drivers/pci/host/pci-dra7xx.c b/drivers/pci/host/pci-
> dra7xx.c
> > index 5678b57..8d598fb 100644
> > --- a/drivers/pci/host/pci-dra7xx.c
> > +++ b/drivers/pci/host/pci-dra7xx.c
> > @@ -141,15 +141,15 @@ static void dra7xx_pcie_host_init(struct
> pcie_port *pp)
> >  {
> >  	dw_pcie_setup_rc(pp);
> >
> > -	if (pp->io_mod_base)
> > -		pp->io_mod_base &= CPU_TO_BUS_ADDR;
> > +	if (pp->io_base)
> > +		pp->io_base &= CPU_TO_BUS_ADDR;
> >
> > -	if (pp->mem_mod_base)
> > -		pp->mem_mod_base &= CPU_TO_BUS_ADDR;
> > +	if (pp->mem_base)
> > +		pp->mem_base &= CPU_TO_BUS_ADDR;
> >
> > -	if (pp->cfg0_mod_base) {
> > -		pp->cfg0_mod_base &= CPU_TO_BUS_ADDR;
> > -		pp->cfg1_mod_base &= CPU_TO_BUS_ADDR;
> > +	if (pp->cfg0_base) {
> > +		pp->cfg0_base &= CPU_TO_BUS_ADDR;
> > +		pp->cfg1_base &= CPU_TO_BUS_ADDR;
> >  	}
> >
> >  	dra7xx_pcie_establish_link(pp);
> > @@ -288,6 +288,7 @@ static int __init dra7xx_add_pcie_port(struct
> dra7xx_pcie *dra7xx,
> >
> >  	pp = &dra7xx->pp;
> >  	pp->dev = dev;
> > +	pp->root_bus_nr = DW_ROOT_NR_UNDEFINED;
> >  	pp->ops = &dra7xx_pcie_host_ops;
> >
> >  	pp->irq = platform_get_irq(pdev, 1);
> > diff --git a/drivers/pci/host/pci-exynos.c b/drivers/pci/host/pci-
> exynos.c
> > index f9f468d..ed03a8f 100644
> > --- a/drivers/pci/host/pci-exynos.c
> > +++ b/drivers/pci/host/pci-exynos.c
> > @@ -530,7 +530,7 @@ static int __init exynos_add_pcie_port(struct
> pcie_port *pp,
> >  		}
> >  	}
> >
> > -	pp->root_bus_nr = -1;
> > +	pp->root_bus_nr = DW_ROOT_NR_UNDEFINED;
> >  	pp->ops = &exynos_pcie_host_ops;
> >
> >  	ret = dw_pcie_host_init(pp);
> > diff --git a/drivers/pci/host/pci-imx6.c b/drivers/pci/host/pci-
> imx6.c
> > index 233a196..0efac85 100644
> > --- a/drivers/pci/host/pci-imx6.c
> > +++ b/drivers/pci/host/pci-imx6.c
> > @@ -551,7 +551,7 @@ static int __init imx6_add_pcie_port(struct
> pcie_port *pp,
> >  		}
> >  	}
> >
> > -	pp->root_bus_nr = -1;
> > +	pp->root_bus_nr = DW_ROOT_NR_UNDEFINED;
> >  	pp->ops = &imx6_pcie_host_ops;
> >
> >  	ret = dw_pcie_host_init(pp);
> > diff --git a/drivers/pci/host/pci-keystone-dw.c
> b/drivers/pci/host/pci-keystone-dw.c
> > index f34892e..b1e4135 100644
> > --- a/drivers/pci/host/pci-keystone-dw.c
> > +++ b/drivers/pci/host/pci-keystone-dw.c
> > @@ -327,7 +327,7 @@ static void ks_dw_pcie_clear_dbi_mode(void
> __iomem *reg_virt)
> >  void ks_dw_pcie_setup_rc_app_regs(struct keystone_pcie *ks_pcie)
> >  {
> >  	struct pcie_port *pp = &ks_pcie->pp;
> > -	u32 start = pp->mem.start, end = pp->mem.end;
> > +	u32 start = pp->mem->start, end = pp->mem->end;
> >  	int i, tr_size;
> >
> >  	/* Disable BARs for inbound access */
> > diff --git a/drivers/pci/host/pci-keystone.c b/drivers/pci/host/pci-
> keystone.c
> > index 734da58..b522956 100644
> > --- a/drivers/pci/host/pci-keystone.c
> > +++ b/drivers/pci/host/pci-keystone.c
> > @@ -309,7 +309,7 @@ static int __init ks_add_pcie_port(struct
> keystone_pcie *ks_pcie,
> >  			return ret;
> >  	}
> >
> > -	pp->root_bus_nr = -1;
> > +	pp->root_bus_nr = DW_ROOT_NR_UNDEFINED;
> >  	pp->ops = &keystone_pcie_host_ops;
> >  	ret = ks_dw_pcie_host_init(ks_pcie, ks_pcie->msi_intc_np);
> >  	if (ret) {
> > diff --git a/drivers/pci/host/pci-layerscape.c
> b/drivers/pci/host/pci-layerscape.c
> > index b2328ea1..dd92ffa 100644
> > --- a/drivers/pci/host/pci-layerscape.c
> > +++ b/drivers/pci/host/pci-layerscape.c
> > @@ -106,7 +106,7 @@ static int ls_add_pcie_port(struct ls_pcie *pcie)
> >  	pp = &pcie->pp;
> >  	pp->dev = pcie->dev;
> >  	pp->dbi_base = pcie->dbi;
> > -	pp->root_bus_nr = -1;
> > +	pp->root_bus_nr = DW_ROOT_NR_UNDEFINED;
> >  	pp->ops = &ls_pcie_host_ops;
> >
> >  	ret = dw_pcie_host_init(pp);
> > diff --git a/drivers/pci/host/pcie-designware.c
> b/drivers/pci/host/pcie-designware.c
> > index 5307b35..bd2606b 100644
> > --- a/drivers/pci/host/pcie-designware.c
> > +++ b/drivers/pci/host/pcie-designware.c
> > @@ -11,6 +11,7 @@
> >   * published by the Free Software Foundation.
> >   */
> >
> > +#include <linux/hardirq.h>
> >  #include <linux/irq.h>
> >  #include <linux/irqdomain.h>
> >  #include <linux/kernel.h>
> > @@ -69,16 +70,9 @@
> >  #define PCIE_ATU_FUNC(x)		(((x) & 0x7) << 16)
> >  #define PCIE_ATU_UPPER_TARGET		0x91C
> >
> > -static struct hw_pci dw_pci;
> > +static struct pci_ops dw_pcie_ops;
> >
> > -static unsigned long global_io_offset;
> > -
> > -static inline struct pcie_port *sys_to_pcie(struct pci_sys_data *sys)
> > -{
> > -	BUG_ON(!sys->private_data);
> > -
> > -	return sys->private_data;
> > -}
> > +DEFINE_MUTEX(root_bus_nr_mux);
> >
> >  int dw_pcie_cfg_read(void __iomem *addr, int where, int size, u32
> *val)
> >  {
> > @@ -255,7 +249,7 @@ static void dw_pcie_msi_set_irq(struct pcie_port
> *pp, int irq)
> >  static int assign_irq(int no_irqs, struct msi_desc *desc, int *pos)
> >  {
> >  	int irq, pos0, i;
> > -	struct pcie_port *pp = sys_to_pcie(desc->dev->bus->sysdata);
> > +	struct pcie_port *pp = desc->dev->bus->sysdata;
> >
> >  	pos0 = bitmap_find_free_region(pp->msi_irq_in_use, MAX_MSI_IRQS,
> >  				       order_base_2(no_irqs));
> > @@ -298,7 +292,7 @@ static int dw_msi_setup_irq(struct msi_controller
> *chip, struct pci_dev *pdev,
> >  {
> >  	int irq, pos;
> >  	struct msi_msg msg;
> > -	struct pcie_port *pp = sys_to_pcie(pdev->bus->sysdata);
> > +	struct pcie_port *pp = pdev->bus->sysdata;
> >
> >  	if (desc->msi_attrib.is_msix)
> >  		return -EINVAL;
> > @@ -327,7 +321,7 @@ static void dw_msi_teardown_irq(struct
> msi_controller *chip, unsigned int irq)
> >  {
> >  	struct irq_data *data = irq_get_irq_data(irq);
> >  	struct msi_desc *msi = irq_data_get_msi(data);
> > -	struct pcie_port *pp = sys_to_pcie(msi->dev->bus->sysdata);
> > +	struct pcie_port *pp = msi->dev->bus->sysdata;
> >
> >  	clear_irq_range(pp, irq, 1, data->hwirq);
> >  }
> > @@ -359,22 +353,17 @@ static const struct irq_domain_ops
> msi_domain_ops = {
> >  	.map = dw_pcie_msi_map,
> >  };
> >
> > -int dw_pcie_host_init(struct pcie_port *pp)
> > +int __init dw_pcie_host_init(struct pcie_port *pp)
> >  {
> >  	struct device_node *np = pp->dev->of_node;
> >  	struct platform_device *pdev = to_platform_device(pp->dev);
> > -	struct of_pci_range range;
> > -	struct of_pci_range_parser parser;
> > +	struct pci_bus *bus;
> >  	struct resource *cfg_res;
> > -	u32 val, na, ns;
> > -	const __be32 *addrp;
> > -	int i, index, ret;
> > -
> > -	/* Find the address cell size and the number of cells in order to
> get
> > -	 * the untranslated address.
> > -	 */
> > -	of_property_read_u32(np, "#address-cells", &na);
> > -	ns = of_n_size_cells(np);
> > +	LIST_HEAD(res);
> > +	u32 val;
> > +	int i, ret;
> > +	struct resource_entry *win;
> > +	static int root_bus_nr = 0;
> >
> >  	cfg_res = platform_get_resource_byname(pdev, IORESOURCE_MEM,
> "config");
> >  	if (cfg_res) {
> > @@ -382,85 +371,60 @@ int dw_pcie_host_init(struct pcie_port *pp)
> >  		pp->cfg1_size = resource_size(cfg_res)/2;
> >  		pp->cfg0_base = cfg_res->start;
> >  		pp->cfg1_base = cfg_res->start + pp->cfg0_size;
> > -
> > -		/* Find the untranslated configuration space address */
> > -		index = of_property_match_string(np, "reg-names", "config");
> > -		addrp = of_get_address(np, index, NULL, NULL);
> > -		pp->cfg0_mod_base = of_read_number(addrp, ns);
> > -		pp->cfg1_mod_base = pp->cfg0_mod_base + pp->cfg0_size;
> >  	} else {
> >  		dev_err(pp->dev, "missing *config* reg space\n");
> >  	}
> >
> > -	if (of_pci_range_parser_init(&parser, np)) {
> > -		dev_err(pp->dev, "missing ranges property\n");
> > -		return -EINVAL;
> > -	}
> > +	ret = of_pci_get_host_bridge_resources(np, 0, 0xff, &res, &pp-
> >io_base);
> > +	if (ret)
> > +		return ret;
> >
> >  	/* Get the I/O and memory ranges from DT */
> > -	for_each_of_pci_range(&parser, &range) {
> > -		unsigned long restype = range.flags & IORESOURCE_TYPE_BITS;
> > -
> > -		if (restype == IORESOURCE_IO) {
> > -			of_pci_range_to_resource(&range, np, &pp->io);
> > -			pp->io.name = "I/O";
> > -			pp->io.start = max_t(resource_size_t,
> > -					     PCIBIOS_MIN_IO,
> > -					     range.pci_addr + global_io_offset);
> > -			pp->io.end = min_t(resource_size_t,
> > -					   IO_SPACE_LIMIT,
> > -					   range.pci_addr + range.size
> > -					   + global_io_offset - 1);
> > -			pp->io_size = resource_size(&pp->io);
> > -			pp->io_bus_addr = range.pci_addr;
> > -			pp->io_base = range.cpu_addr;
> > -
> > -			/* Find the untranslated IO space address */
> > -			pp->io_mod_base = range.cpu_addr;
> > -		}
> > -		if (restype == IORESOURCE_MEM) {
> > -			of_pci_range_to_resource(&range, np, &pp->mem);
> > -			pp->mem.name = "MEM";
> > -			pp->mem_size = resource_size(&pp->mem);
> > -			pp->mem_bus_addr = range.pci_addr;
> > -
> > -			/* Find the untranslated MEM space address */
> > -			pp->mem_mod_base = range.cpu_addr;
> > -		}
> > -		if (restype == 0) {
> > -			of_pci_range_to_resource(&range, np, &pp->cfg);
> > -			pp->cfg0_size = resource_size(&pp->cfg)/2;
> > -			pp->cfg1_size = resource_size(&pp->cfg)/2;
> > -			pp->cfg0_base = pp->cfg.start;
> > -			pp->cfg1_base = pp->cfg.start + pp->cfg0_size;
> > -
> > -			/* Find the untranslated configuration space address
> */
> > -			pp->cfg0_mod_base = range.cpu_addr;
> > -			pp->cfg1_mod_base = pp->cfg0_mod_base +
> > -					    pp->cfg0_size;
> > +	resource_list_for_each_entry(win, &res) {
> > +		switch (resource_type(win->res)) {
> > +		case IORESOURCE_IO:
> > +			pp->io = win->res;
> > +			pp->io->name = "I/O";
> > +			pp->io_size = resource_size(pp->io);
> > +			pp->io_bus_addr = pp->io->start - win->offset;
> > +			ret = pci_remap_iospace(pp->io, pp->io_base);
> > +			if (ret) {
> > +				dev_warn(pp->dev, "error %d: failed to map
> resource %pR\n",
> > +					 ret, pp->io);
> > +				continue;
> > +			}
> > +			break;
> > +		case IORESOURCE_MEM:
> > +			pp->mem = win->res;
> > +			pp->mem->name = "MEM";
> > +			pp->mem_size = resource_size(pp->mem);
> > +			pp->mem_bus_addr = pp->mem->start - win->offset;
> > +			break;
> > +		case 0:
> > +			pp->cfg = win->res;
> > +			pp->cfg0_size = resource_size(pp->cfg)/2;
> > +			pp->cfg1_size = resource_size(pp->cfg)/2;
> > +			pp->cfg0_base = pp->cfg->start;
> > +			pp->cfg1_base = pp->cfg->start + pp->cfg0_size;
> > +			break;
> > +		case IORESOURCE_BUS:
> > +			pp->busn = win->res;
> > +			break;
> > +		default:
> > +			continue;
> >  		}
> >  	}
> >
> > -	ret = of_pci_parse_bus_range(np, &pp->busn);
> > -	if (ret < 0) {
> > -		pp->busn.name = np->name;
> > -		pp->busn.start = 0;
> > -		pp->busn.end = 0xff;
> > -		pp->busn.flags = IORESOURCE_BUS;
> > -		dev_dbg(pp->dev, "failed to parse bus-range property: %d,
> using default %pR\n",
> > -			ret, &pp->busn);
> > -	}
> > -
> >  	if (!pp->dbi_base) {
> > -		pp->dbi_base = devm_ioremap(pp->dev, pp->cfg.start,
> > -					resource_size(&pp->cfg));
> > +		pp->dbi_base = devm_ioremap(pp->dev, pp->cfg->start,
> > +					resource_size(pp->cfg));
> >  		if (!pp->dbi_base) {
> >  			dev_err(pp->dev, "error with ioremap\n");
> >  			return -ENOMEM;
> >  		}
> >  	}
> >
> > -	pp->mem_base = pp->mem.start;
> > +	pp->mem_base = pp->mem->start;
> >
> >  	if (!pp->va_cfg0_base) {
> >  		pp->va_cfg0_base = devm_ioremap(pp->dev, pp->cfg0_base,
> > @@ -509,7 +473,7 @@ int dw_pcie_host_init(struct pcie_port *pp)
> >
> >  	if (!pp->ops->rd_other_conf)
> >  		dw_pcie_prog_outbound_atu(pp, PCIE_ATU_REGION_INDEX1,
> > -					  PCIE_ATU_TYPE_MEM, pp->mem_mod_base,
> > +					  PCIE_ATU_TYPE_MEM, pp->mem_base,
> >  					  pp->mem_bus_addr, pp->mem_size);
> >
> >  	dw_pcie_wr_own_conf(pp, PCI_BASE_ADDRESS_0, 4, 0);
> > @@ -521,15 +485,40 @@ int dw_pcie_host_init(struct pcie_port *pp)
> >  	val |= PORT_LOGIC_SPEED_CHANGE;
> >  	dw_pcie_wr_own_conf(pp, PCIE_LINK_WIDTH_SPEED_CONTROL, 4, val);
> >
> > -#ifdef CONFIG_PCI_MSI
> >  	dw_pcie_msi_chip.dev = pp->dev;
> > -	dw_pci.msi_ctrl = &dw_pcie_msi_chip;
> > +
> > +	mutex_lock(&root_bus_nr_mux);
> > +
> > +	if (pp->root_bus_nr != DW_ROOT_NR_UNDEFINED)
> > +		root_bus_nr = pp->root_bus_nr;
> > +
> > +	bus = pci_create_root_bus(pp->dev, root_bus_nr, &dw_pcie_ops,
> > +			      pp, &res);
> > +	if (!bus) {
> > +		mutex_unlock(&root_bus_nr_mux);
> > +		return -ENOMEM;
> > +	}
> > +
> > +	root_bus_nr += bus->busn_res.end + 1;
> > +	mutex_unlock(&root_bus_nr_mux);
> > +
> > +#ifdef CONFIG_GENERIC_MSI_IRQ_DOMAIN
> > +	bus->msi = container_of(&pp->irq_domain, struct msi_controller,
> domain);
> > +#else
> > +	bus->msi = &dw_pcie_msi_chip;
> >  #endif
> >
> > -	dw_pci.nr_controllers = 1;
> > -	dw_pci.private_data = (void **)&pp;
> > +	pci_scan_child_bus(bus);
> > +	if (pp->ops->scan_bus)
> > +		pp->ops->scan_bus(pp);
> > +
> > +#ifdef CONFIG_ARM
> > +	/* support old dtbs that incorrectly describe IRQs */
> > +	pci_fixup_irqs(pci_common_swizzle, of_irq_parse_and_map_pci);
> > +#endif
> >
> > -	pci_common_init_dev(pp->dev, &dw_pci);
> > +	pci_assign_unassigned_bus_resources(bus);
> > +	pci_bus_add_devices(bus);
> >
> >  	return 0;
> >  }
> > @@ -548,12 +537,12 @@ static int dw_pcie_rd_other_conf(struct
> pcie_port *pp, struct pci_bus *bus,
> >
> >  	if (bus->parent->number == pp->root_bus_nr) {
> >  		type = PCIE_ATU_TYPE_CFG0;
> > -		cpu_addr = pp->cfg0_mod_base;
> > +		cpu_addr = pp->cfg0_base;
> >  		cfg_size = pp->cfg0_size;
> >  		va_cfg_base = pp->va_cfg0_base;
> >  	} else {
> >  		type = PCIE_ATU_TYPE_CFG1;
> > -		cpu_addr = pp->cfg1_mod_base;
> > +		cpu_addr = pp->cfg1_base;
> >  		cfg_size = pp->cfg1_size;
> >  		va_cfg_base = pp->va_cfg1_base;
> >  	}
> > @@ -563,7 +552,7 @@ static int dw_pcie_rd_other_conf(struct pcie_port
> *pp, struct pci_bus *bus,
> >  				  busdev, cfg_size);
> >  	ret = dw_pcie_cfg_read(va_cfg_base + address, where, size, val);
> >  	dw_pcie_prog_outbound_atu(pp, PCIE_ATU_REGION_INDEX0,
> > -				  PCIE_ATU_TYPE_IO, pp->io_mod_base,
> > +				  PCIE_ATU_TYPE_IO, pp->io_base,
> >  				  pp->io_bus_addr, pp->io_size);
> >
> >  	return ret;
> > @@ -583,12 +572,12 @@ static int dw_pcie_wr_other_conf(struct
> pcie_port *pp, struct pci_bus *bus,
> >
> >  	if (bus->parent->number == pp->root_bus_nr) {
> >  		type = PCIE_ATU_TYPE_CFG0;
> > -		cpu_addr = pp->cfg0_mod_base;
> > +		cpu_addr = pp->cfg0_base;
> >  		cfg_size = pp->cfg0_size;
> >  		va_cfg_base = pp->va_cfg0_base;
> >  	} else {
> >  		type = PCIE_ATU_TYPE_CFG1;
> > -		cpu_addr = pp->cfg1_mod_base;
> > +		cpu_addr = pp->cfg1_base;
> >  		cfg_size = pp->cfg1_size;
> >  		va_cfg_base = pp->va_cfg1_base;
> >  	}
> > @@ -598,7 +587,7 @@ static int dw_pcie_wr_other_conf(struct pcie_port
> *pp, struct pci_bus *bus,
> >  				  busdev, cfg_size);
> >  	ret = dw_pcie_cfg_write(va_cfg_base + address, where, size, val);
> >  	dw_pcie_prog_outbound_atu(pp, PCIE_ATU_REGION_INDEX0,
> > -				  PCIE_ATU_TYPE_IO, pp->io_mod_base,
> > +				  PCIE_ATU_TYPE_IO, pp->io_base,
> >  				  pp->io_bus_addr, pp->io_size);
> >
> >  	return ret;
> > @@ -630,7 +619,7 @@ static int dw_pcie_valid_config(struct pcie_port
> *pp,
> >  static int dw_pcie_rd_conf(struct pci_bus *bus, u32 devfn, int where,
> >  			int size, u32 *val)
> >  {
> > -	struct pcie_port *pp = sys_to_pcie(bus->sysdata);
> > +	struct pcie_port *pp = bus->sysdata;
> >  	int ret;
> >
> >  	if (dw_pcie_valid_config(pp, bus, PCI_SLOT(devfn)) == 0) {
> > @@ -654,7 +643,7 @@ static int dw_pcie_rd_conf(struct pci_bus *bus,
> u32 devfn, int where,
> >  static int dw_pcie_wr_conf(struct pci_bus *bus, u32 devfn,
> >  			int where, int size, u32 val)
> >  {
> > -	struct pcie_port *pp = sys_to_pcie(bus->sysdata);
> > +	struct pcie_port *pp = bus->sysdata;
> >  	int ret;
> >
> >  	if (dw_pcie_valid_config(pp, bus, PCI_SLOT(devfn)) == 0)
> > @@ -678,62 +667,6 @@ static struct pci_ops dw_pcie_ops = {
> >  	.write = dw_pcie_wr_conf,
> >  };
> >
> > -static int dw_pcie_setup(int nr, struct pci_sys_data *sys)
> > -{
> > -	struct pcie_port *pp;
> > -
> > -	pp = sys_to_pcie(sys);
> > -
> > -	if (global_io_offset < SZ_1M && pp->io_size > 0) {
> > -		sys->io_offset = global_io_offset - pp->io_bus_addr;
> > -		pci_ioremap_io(global_io_offset, pp->io_base);
> > -		global_io_offset += SZ_64K;
> > -		pci_add_resource_offset(&sys->resources, &pp->io,
> > -					sys->io_offset);
> > -	}
> > -
> > -	sys->mem_offset = pp->mem.start - pp->mem_bus_addr;
> > -	pci_add_resource_offset(&sys->resources, &pp->mem, sys-
> >mem_offset);
> > -	pci_add_resource(&sys->resources, &pp->busn);
> > -
> > -	return 1;
> > -}
> > -
> > -static struct pci_bus *dw_pcie_scan_bus(int nr, struct pci_sys_data
> *sys)
> > -{
> > -	struct pci_bus *bus;
> > -	struct pcie_port *pp = sys_to_pcie(sys);
> > -
> > -	pp->root_bus_nr = sys->busnr;
> > -	bus = pci_scan_root_bus(pp->dev, sys->busnr,
> > -				  &dw_pcie_ops, sys, &sys->resources);
> > -	if (!bus)
> > -		return NULL;
> > -
> > -	if (bus && pp->ops->scan_bus)
> > -		pp->ops->scan_bus(pp);
> > -
> > -	return bus;
> > -}
> > -
> > -static int dw_pcie_map_irq(const struct pci_dev *dev, u8 slot, u8
> pin)
> > -{
> > -	struct pcie_port *pp = sys_to_pcie(dev->bus->sysdata);
> > -	int irq;
> > -
> > -	irq = of_irq_parse_and_map_pci(dev, slot, pin);
> > -	if (!irq)
> > -		irq = pp->irq;
> > -
> > -	return irq;
> > -}
> > -
> > -static struct hw_pci dw_pci = {
> > -	.setup		= dw_pcie_setup,
> > -	.scan		= dw_pcie_scan_bus,
> > -	.map_irq	= dw_pcie_map_irq,
> > -};
> > -
> >  void dw_pcie_setup_rc(struct pcie_port *pp)
> >  {
> >  	u32 val;
> > diff --git a/drivers/pci/host/pcie-designware.h
> b/drivers/pci/host/pcie-designware.h
> > index d0bbd27..0c2a7eb 100644
> > --- a/drivers/pci/host/pcie-designware.h
> > +++ b/drivers/pci/host/pcie-designware.h
> > @@ -21,31 +21,28 @@
> >   */
> >  #define MAX_MSI_IRQS			32
> >  #define MAX_MSI_CTRLS			(MAX_MSI_IRQS / 32)
> > +#define DW_ROOT_NR_UNDEFINED	-1
> >
> >  struct pcie_port {
> >  	struct device		*dev;
> >  	u8			root_bus_nr;
> >  	void __iomem		*dbi_base;
> >  	u64			cfg0_base;
> > -	u64			cfg0_mod_base;
> >  	void __iomem		*va_cfg0_base;
> >  	u32			cfg0_size;
> >  	u64			cfg1_base;
> > -	u64			cfg1_mod_base;
> >  	void __iomem		*va_cfg1_base;
> >  	u32			cfg1_size;
> > -	u64			io_base;
> > -	u64			io_mod_base;
> > +	resource_size_t		io_base;
> >  	phys_addr_t		io_bus_addr;
> >  	u32			io_size;
> >  	u64			mem_base;
> > -	u64			mem_mod_base;
> >  	phys_addr_t		mem_bus_addr;
> >  	u32			mem_size;
> > -	struct resource		cfg;
> > -	struct resource		io;
> > -	struct resource		mem;
> > -	struct resource		busn;
> > +	struct resource		*cfg;
> > +	struct resource		*io;
> > +	struct resource		*mem;
> > +	struct resource		*busn;
> >  	int			irq;
> >  	u32			lanes;
> >  	struct pcie_host_ops	*ops;
> > diff --git a/drivers/pci/host/pcie-spear13xx.c
> b/drivers/pci/host/pcie-spear13xx.c
> > index c49fbdc..b2c59b9 100644
> > --- a/drivers/pci/host/pcie-spear13xx.c
> > +++ b/drivers/pci/host/pcie-spear13xx.c
> > @@ -286,7 +286,7 @@ static int spear13xx_add_pcie_port(struct
> pcie_port *pp,
> >  		return ret;
> >  	}
> >
> > -	pp->root_bus_nr = -1;
> > +	pp->root_bus_nr = DW_ROOT_NR_UNDEFINED;
> >  	pp->ops = &spear13xx_pcie_host_ops;
> >
> >  	ret = dw_pcie_host_init(pp);
> > --
> > 1.9.1
> >
> >
> > > -----Original Message-----
> > > From: Lucas Stach [mailto:l.stach at pengutronix.de]
> > > Sent: Wednesday, August 19, 2015 1:54 PM
> > > To: Wangzhou (B)
> > > Cc: Bjorn Helgaas; jingoohan1 at gmail.com; Pratyush Anand; Arnd
> Bergmann;
> > > linux at arm.linux.org.uk; thomas.petazzoni at free-electrons.com;
> Gabriele
> > > Paoloni; lorenzo.pieralisi at arm.com; james.morse at arm.com;
> > > Liviu.Dudau at arm.com; jason at lakedaemon.net; robh at kernel.org; linux-
> > > pci at vger.kernel.org; linux-arm-kernel at lists.infradead.org;
> > > devicetree at vger.kernel.org; Yuanzhichang; Zhudacai; zhangjukuo;
> > > qiuzhenfa; liudongdong (C); qiujiang; xuwei (O); Liguozhu (Kenneth)
> > > Subject: Re: [PATCH v7 3/6] PCI: designware: Add ARM64 support
> > >
> > > Am Montag, den 17.08.2015, 19:55 +0800 schrieb Zhou Wang:
> > > > This patch tries to unify ARM32 and ARM64 PCIe in designware
> driver.
> > > Delete
> > > > function dw_pcie_setup, dw_pcie_scan_bus, dw_pcie_map_irq and
> struct
> > > hw_pci,
> > > > move related operations to dw_pcie_host_init.
> > > >
> > > > In past, we use:
> > > > pci_common_init_dev
> > > > 	-> pcibios_init_hw
> > > > 		-> hw->scan (dw_pcie_scan_bus)
> > > > to pass 0 to root_bus_nr in struct pcie_port. This patch set pp-
> > > >root_bus_nr = 0
> > > > in each PCIe host driver which is based on pcie-designware.
> > > >
> > > This is incorrect at least if there are 2 instances of DW PCIe host
> in
> > > the same SoC without using PCI domains. In that the case the bus
> range
> > > determines the range of valid bus numbers per instance and the
> first
> > > number is the root bus. Please look at the "bus-range" DT property
> in
> > > the DW PCIe bindings.
> > >
> > > Also we should finally remove this root-bus setup from the glue
> drivers
> > > altogether. It's something that entirely belongs into the DW core
> code.
> > >
> > > Regards,
> > > Lucas
> > >
> > > > This patch also try to use of_pci_get_host_bridge_resources for
> ARM32
> > > and ARM64
> > > > according to the suggestion for Gabriele[1]
> > > >
> > > > Finally this patch reverts commit f4c55c5a3f7f "PCI: designware:
> > > Program ATU
> > > > with untranslated address" based on 1/6 in this series. we delete
> > > *_mod_base in
> > > > pcie-designware. This was discussed in [2]
> > > >
> > > > I have compiled the driver with multi_v7_defconfig. However, I
> don't
> > > have
> > > > ARM32 PCIe related board to do test. It will be appreciated if
> > > someone could
> > > > help to test it.
> > > >
> > > > Signed-off-by: Zhou Wang <wangzhou1 at hisilicon.com>
> > > > Signed-off-by: Gabriele Paoloni <gabriele.paoloni at huawei.com>
> > > > Signed-off-by: Arnd Bergmann <arnd at arndb.de>
> > > > Tested-By: James Morse <james.morse at arm.com>
> > > >
> > > > [1] http://www.spinics.net/lists/linux-pci/msg42194.html
> > > > [2] http://www.spinics.net/lists/arm-kernel/msg436779.html
> > > > ---
> > > >  drivers/pci/host/pci-dra7xx.c      |  15 +--
> > > >  drivers/pci/host/pci-exynos.c      |   2 +-
> > > >  drivers/pci/host/pci-imx6.c        |   2 +-
> > > >  drivers/pci/host/pci-keystone-dw.c |   2 +-
> > > >  drivers/pci/host/pci-keystone.c    |   2 +-
> > > >  drivers/pci/host/pci-layerscape.c  |   2 +-
> > > >  drivers/pci/host/pcie-designware.c | 229 ++++++++++++-----------
> ----
> > > ----------
> > > >  drivers/pci/host/pcie-designware.h |  14 +--
> > > >  drivers/pci/host/pcie-spear13xx.c  |   2 +-
> > > >  9 files changed, 95 insertions(+), 175 deletions(-)
> > > >
> > > > diff --git a/drivers/pci/host/pci-dra7xx.c
> b/drivers/pci/host/pci-
> > > dra7xx.c
> > > > index 18ae7ff..1268c69 100644
> > > > --- a/drivers/pci/host/pci-dra7xx.c
> > > > +++ b/drivers/pci/host/pci-dra7xx.c
> > > > @@ -141,15 +141,15 @@ static void dra7xx_pcie_host_init(struct
> > > pcie_port *pp)
> > > >  {
> > > >  	dw_pcie_setup_rc(pp);
> > > >
> > > > -	if (pp->io_mod_base)
> > > > -		pp->io_mod_base &= CPU_TO_BUS_ADDR;
> > > > +	if (pp->io_base)
> > > > +		pp->io_base &= CPU_TO_BUS_ADDR;
> > > >
> > > > -	if (pp->mem_mod_base)
> > > > -		pp->mem_mod_base &= CPU_TO_BUS_ADDR;
> > > > +	if (pp->mem_base)
> > > > +		pp->mem_base &= CPU_TO_BUS_ADDR;
> > > >
> > > > -	if (pp->cfg0_mod_base) {
> > > > -		pp->cfg0_mod_base &= CPU_TO_BUS_ADDR;
> > > > -		pp->cfg1_mod_base &= CPU_TO_BUS_ADDR;
> > > > +	if (pp->cfg0_base) {
> > > > +		pp->cfg0_base &= CPU_TO_BUS_ADDR;
> > > > +		pp->cfg1_base &= CPU_TO_BUS_ADDR;
> > > >  	}
> > > >
> > > >  	dra7xx_pcie_establish_link(pp);
> > > > @@ -288,6 +288,7 @@ static int __init dra7xx_add_pcie_port(struct
> > > dra7xx_pcie *dra7xx,
> > > >
> > > >  	pp = &dra7xx->pp;
> > > >  	pp->dev = dev;
> > > > +	pp->root_bus_nr = 0;
> > > >  	pp->ops = &dra7xx_pcie_host_ops;
> > > >
> > > >  	pp->irq = platform_get_irq(pdev, 1);
> > > > diff --git a/drivers/pci/host/pci-exynos.c
> b/drivers/pci/host/pci-
> > > exynos.c
> > > > index f9f468d..9771bb0 100644
> > > > --- a/drivers/pci/host/pci-exynos.c
> > > > +++ b/drivers/pci/host/pci-exynos.c
> > > > @@ -530,7 +530,7 @@ static int __init exynos_add_pcie_port(struct
> > > pcie_port *pp,
> > > >  		}
> > > >  	}
> > > >
> > > > -	pp->root_bus_nr = -1;
> > > > +	pp->root_bus_nr = 0;
> > > >  	pp->ops = &exynos_pcie_host_ops;
> > > >
> > > >  	ret = dw_pcie_host_init(pp);
> > > > diff --git a/drivers/pci/host/pci-imx6.c b/drivers/pci/host/pci-
> > > imx6.c
> > > > index 233a196..bec256c 100644
> > > > --- a/drivers/pci/host/pci-imx6.c
> > > > +++ b/drivers/pci/host/pci-imx6.c
> > > > @@ -551,7 +551,7 @@ static int __init imx6_add_pcie_port(struct
> > > pcie_port *pp,
> > > >  		}
> > > >  	}
> > > >
> > > > -	pp->root_bus_nr = -1;
> > > > +	pp->root_bus_nr = 0;
> > > >  	pp->ops = &imx6_pcie_host_ops;
> > > >
> > > >  	ret = dw_pcie_host_init(pp);
> > > > diff --git a/drivers/pci/host/pci-keystone-dw.c
> > > b/drivers/pci/host/pci-keystone-dw.c
> > > > index f34892e..b1e4135 100644
> > > > --- a/drivers/pci/host/pci-keystone-dw.c
> > > > +++ b/drivers/pci/host/pci-keystone-dw.c
> > > > @@ -327,7 +327,7 @@ static void ks_dw_pcie_clear_dbi_mode(void
> > > __iomem *reg_virt)
> > > >  void ks_dw_pcie_setup_rc_app_regs(struct keystone_pcie *ks_pcie)
> > > >  {
> > > >  	struct pcie_port *pp = &ks_pcie->pp;
> > > > -	u32 start = pp->mem.start, end = pp->mem.end;
> > > > +	u32 start = pp->mem->start, end = pp->mem->end;
> > > >  	int i, tr_size;
> > > >
> > > >  	/* Disable BARs for inbound access */
> > > > diff --git a/drivers/pci/host/pci-keystone.c
> b/drivers/pci/host/pci-
> > > keystone.c
> > > > index 734da58..8113832 100644
> > > > --- a/drivers/pci/host/pci-keystone.c
> > > > +++ b/drivers/pci/host/pci-keystone.c
> > > > @@ -309,7 +309,7 @@ static int __init ks_add_pcie_port(struct
> > > keystone_pcie *ks_pcie,
> > > >  			return ret;
> > > >  	}
> > > >
> > > > -	pp->root_bus_nr = -1;
> > > > +	pp->root_bus_nr = 0;
> > > >  	pp->ops = &keystone_pcie_host_ops;
> > > >  	ret = ks_dw_pcie_host_init(ks_pcie, ks_pcie->msi_intc_np);
> > > >  	if (ret) {
> > > > diff --git a/drivers/pci/host/pci-layerscape.c
> > > b/drivers/pci/host/pci-layerscape.c
> > > > index b2328ea1..79ff08c 100644
> > > > --- a/drivers/pci/host/pci-layerscape.c
> > > > +++ b/drivers/pci/host/pci-layerscape.c
> > > > @@ -106,7 +106,7 @@ static int ls_add_pcie_port(struct ls_pcie
> *pcie)
> > > >  	pp = &pcie->pp;
> > > >  	pp->dev = pcie->dev;
> > > >  	pp->dbi_base = pcie->dbi;
> > > > -	pp->root_bus_nr = -1;
> > > > +	pp->root_bus_nr = 0;
> > > >  	pp->ops = &ls_pcie_host_ops;
> > > >
> > > >  	ret = dw_pcie_host_init(pp);
> > > > diff --git a/drivers/pci/host/pcie-designware.c
> > > b/drivers/pci/host/pcie-designware.c
> > > > index c5d407c..e71a88e 100644
> > > > --- a/drivers/pci/host/pcie-designware.c
> > > > +++ b/drivers/pci/host/pcie-designware.c
> > > > @@ -11,6 +11,7 @@
> > > >   * published by the Free Software Foundation.
> > > >   */
> > > >
> > > > +#include <linux/hardirq.h>
> > > >  #include <linux/irq.h>
> > > >  #include <linux/irqdomain.h>
> > > >  #include <linux/kernel.h>
> > > > @@ -69,16 +70,7 @@
> > > >  #define PCIE_ATU_FUNC(x)		(((x) & 0x7) << 16)
> > > >  #define PCIE_ATU_UPPER_TARGET		0x91C
> > > >
> > > > -static struct hw_pci dw_pci;
> > > > -
> > > > -static unsigned long global_io_offset;
> > > > -
> > > > -static inline struct pcie_port *sys_to_pcie(struct pci_sys_data
> *sys)
> > > > -{
> > > > -	BUG_ON(!sys->private_data);
> > > > -
> > > > -	return sys->private_data;
> > > > -}
> > > > +static struct pci_ops dw_pcie_ops;
> > > >
> > > >  int dw_pcie_cfg_read(void __iomem *addr, int where, int size,
> u32
> > > *val)
> > > >  {
> > > > @@ -255,7 +247,7 @@ static void dw_pcie_msi_set_irq(struct
> pcie_port
> > > *pp, int irq)
> > > >  static int assign_irq(int no_irqs, struct msi_desc *desc, int
> *pos)
> > > >  {
> > > >  	int irq, pos0, i;
> > > > -	struct pcie_port *pp = sys_to_pcie(desc->dev->bus->sysdata);
> > > > +	struct pcie_port *pp = desc->dev->bus->sysdata;
> > > >
> > > >  	pos0 = bitmap_find_free_region(pp->msi_irq_in_use,
> MAX_MSI_IRQS,
> > > >  				       order_base_2(no_irqs));
> > > > @@ -298,7 +290,7 @@ static int dw_msi_setup_irq(struct
> msi_controller
> > > *chip, struct pci_dev *pdev,
> > > >  {
> > > >  	int irq, pos;
> > > >  	struct msi_msg msg;
> > > > -	struct pcie_port *pp = sys_to_pcie(pdev->bus->sysdata);
> > > > +	struct pcie_port *pp = pdev->bus->sysdata;
> > > >
> > > >  	if (desc->msi_attrib.is_msix)
> > > >  		return -EINVAL;
> > > > @@ -327,7 +319,7 @@ static void dw_msi_teardown_irq(struct
> > > msi_controller *chip, unsigned int irq)
> > > >  {
> > > >  	struct irq_data *data = irq_get_irq_data(irq);
> > > >  	struct msi_desc *msi = irq_data_get_msi(data);
> > > > -	struct pcie_port *pp = sys_to_pcie(msi->dev->bus->sysdata);
> > > > +	struct pcie_port *pp = msi->dev->bus->sysdata;
> > > >
> > > >  	clear_irq_range(pp, irq, 1, data->hwirq);
> > > >  }
> > > > @@ -363,14 +355,12 @@ int dw_pcie_host_init(struct pcie_port *pp)
> > > >  {
> > > >  	struct device_node *np = pp->dev->of_node;
> > > >  	struct platform_device *pdev = to_platform_device(pp->dev);
> > > > -	struct of_pci_range range;
> > > > -	struct of_pci_range_parser parser;
> > > > +	struct pci_bus *bus;
> > > >  	struct resource *cfg_res;
> > > > -	u32 val, ns;
> > > > -	const __be32 *addrp;
> > > > -	int i, index, ret;
> > > > -
> > > > -	ns = of_n_size_cells(np);
> > > > +	LIST_HEAD(res);
> > > > +	u32 val;
> > > > +	int i, ret;
> > > > +	struct resource_entry *win;
> > > >
> > > >  	cfg_res = platform_get_resource_byname(pdev, IORESOURCE_MEM,
> > > "config");
> > > >  	if (cfg_res) {
> > > > @@ -378,85 +368,60 @@ int dw_pcie_host_init(struct pcie_port *pp)
> > > >  		pp->cfg1_size = resource_size(cfg_res)/2;
> > > >  		pp->cfg0_base = cfg_res->start;
> > > >  		pp->cfg1_base = cfg_res->start + pp->cfg0_size;
> > > > -
> > > > -		/* Find the untranslated configuration space address
> */
> > > > -		index = of_property_match_string(np, "reg-names",
> "config");
> > > > -		addrp = of_get_address(np, index, NULL, NULL);
> > > > -		pp->cfg0_mod_base = of_read_number(addrp, ns);
> > > > -		pp->cfg1_mod_base = pp->cfg0_mod_base + pp->cfg0_size;
> > > >  	} else {
> > > >  		dev_err(pp->dev, "missing *config* reg space\n");
> > > >  	}
> > > >
> > > > -	if (of_pci_range_parser_init(&parser, np)) {
> > > > -		dev_err(pp->dev, "missing ranges property\n");
> > > > -		return -EINVAL;
> > > > -	}
> > > > +	ret = of_pci_get_host_bridge_resources(np, 0, 0xff, &res,
> &pp-
> > > >io_base);
> > > > +	if (ret)
> > > > +		return ret;
> > > >
> > > >  	/* Get the I/O and memory ranges from DT */
> > > > -	for_each_of_pci_range(&parser, &range) {
> > > > -		unsigned long restype = range.flags &
> IORESOURCE_TYPE_BITS;
> > > > -
> > > > -		if (restype == IORESOURCE_IO) {
> > > > -			of_pci_range_to_resource(&range, np, &pp->io);
> > > > -			pp->io.name = "I/O";
> > > > -			pp->io.start = max_t(resource_size_t,
> > > > -					     PCIBIOS_MIN_IO,
> > > > -					     range.pci_addr +
> global_io_offset);
> > > > -			pp->io.end = min_t(resource_size_t,
> > > > -					   IO_SPACE_LIMIT,
> > > > -					   range.pci_addr + range.size
> > > > -					   + global_io_offset - 1);
> > > > -			pp->io_size = resource_size(&pp->io);
> > > > -			pp->io_bus_addr = range.pci_addr;
> > > > -			pp->io_base = range.cpu_addr;
> > > > -
> > > > -			/* Find the untranslated IO space address */
> > > > -			pp->io_mod_base = range.cpu_addr;
> > > > -		}
> > > > -		if (restype == IORESOURCE_MEM) {
> > > > -			of_pci_range_to_resource(&range, np, &pp->mem);
> > > > -			pp->mem.name = "MEM";
> > > > -			pp->mem_size = resource_size(&pp->mem);
> > > > -			pp->mem_bus_addr = range.pci_addr;
> > > > -
> > > > -			/* Find the untranslated MEM space address */
> > > > -			pp->mem_mod_base = range.cpu_addr;
> > > > -		}
> > > > -		if (restype == 0) {
> > > > -			of_pci_range_to_resource(&range, np, &pp->cfg);
> > > > -			pp->cfg0_size = resource_size(&pp->cfg)/2;
> > > > -			pp->cfg1_size = resource_size(&pp->cfg)/2;
> > > > -			pp->cfg0_base = pp->cfg.start;
> > > > -			pp->cfg1_base = pp->cfg.start + pp->cfg0_size;
> > > > -
> > > > -			/* Find the untranslated configuration space
> address
> > > */
> > > > -			pp->cfg0_mod_base = range.cpu_addr;
> > > > -			pp->cfg1_mod_base = pp->cfg0_mod_base +
> > > > -					    pp->cfg0_size;
> > > > +	resource_list_for_each_entry(win, &res) {
> > > > +		switch (resource_type(win->res)) {
> > > > +		case IORESOURCE_IO:
> > > > +			pp->io = win->res;
> > > > +			pp->io->name = "I/O";
> > > > +			pp->io_size = resource_size(pp->io);
> > > > +			pp->io_bus_addr = pp->io->start - win->offset;
> > > > +			ret = pci_remap_iospace(pp->io, pp->io_base);
> > > > +			if (ret) {
> > > > +				dev_warn(pp->dev, "error %d: failed to
> map
> > > resource %pR\n",
> > > > +					 ret, pp->io);
> > > > +				continue;
> > > > +			}
> > > > +			break;
> > > > +		case IORESOURCE_MEM:
> > > > +			pp->mem = win->res;
> > > > +			pp->mem->name = "MEM";
> > > > +			pp->mem_size = resource_size(pp->mem);
> > > > +			pp->mem_bus_addr = pp->mem->start - win->offset;
> > > > +			break;
> > > > +		case 0:
> > > > +			pp->cfg = win->res;
> > > > +			pp->cfg0_size = resource_size(pp->cfg)/2;
> > > > +			pp->cfg1_size = resource_size(pp->cfg)/2;
> > > > +			pp->cfg0_base = pp->cfg->start;
> > > > +			pp->cfg1_base = pp->cfg->start + pp->cfg0_size;
> > > > +			break;
> > > > +		case IORESOURCE_BUS:
> > > > +			pp->busn = win->res;
> > > > +			break;
> > > > +		default:
> > > > +			continue;
> > > >  		}
> > > >  	}
> > > >
> > > > -	ret = of_pci_parse_bus_range(np, &pp->busn);
> > > > -	if (ret < 0) {
> > > > -		pp->busn.name = np->name;
> > > > -		pp->busn.start = 0;
> > > > -		pp->busn.end = 0xff;
> > > > -		pp->busn.flags = IORESOURCE_BUS;
> > > > -		dev_dbg(pp->dev, "failed to parse bus-range
> property: %d,
> > > using default %pR\n",
> > > > -			ret, &pp->busn);
> > > > -	}
> > > > -
> > > >  	if (!pp->dbi_base) {
> > > > -		pp->dbi_base = devm_ioremap(pp->dev, pp->cfg.start,
> > > > -					resource_size(&pp->cfg));
> > > > +		pp->dbi_base = devm_ioremap(pp->dev, pp->cfg->start,
> > > > +					resource_size(pp->cfg));
> > > >  		if (!pp->dbi_base) {
> > > >  			dev_err(pp->dev, "error with ioremap\n");
> > > >  			return -ENOMEM;
> > > >  		}
> > > >  	}
> > > >
> > > > -	pp->mem_base = pp->mem.start;
> > > > +	pp->mem_base = pp->mem->start;
> > > >
> > > >  	if (!pp->va_cfg0_base) {
> > > >  		pp->va_cfg0_base = devm_ioremap(pp->dev, pp-
> >cfg0_base,
> > > > @@ -505,7 +470,7 @@ int dw_pcie_host_init(struct pcie_port *pp)
> > > >
> > > >  	if (!pp->ops->rd_other_conf)
> > > >  		dw_pcie_prog_outbound_atu(pp, PCIE_ATU_REGION_INDEX1,
> > > > -					  PCIE_ATU_TYPE_MEM, pp-
> >mem_mod_base,
> > > > +					  PCIE_ATU_TYPE_MEM, pp->mem_base,
> > > >  					  pp->mem_bus_addr, pp->mem_size);
> > > >
> > > >  	dw_pcie_wr_own_conf(pp, PCI_BASE_ADDRESS_0, 4, 0);
> > > > @@ -517,15 +482,29 @@ int dw_pcie_host_init(struct pcie_port *pp)
> > > >  	val |= PORT_LOGIC_SPEED_CHANGE;
> > > >  	dw_pcie_wr_own_conf(pp, PCIE_LINK_WIDTH_SPEED_CONTROL, 4,
> val);
> > > >
> > > > -#ifdef CONFIG_PCI_MSI
> > > > +	bus = pci_create_root_bus(pp->dev, pp->root_bus_nr,
> &dw_pcie_ops,
> > > > +				  pp, &res);
> > > > +	if (!bus)
> > > > +		return -ENOMEM;
> > > > +
> > > > +#ifdef CONFIG_GENERIC_MSI_IRQ_DOMAIN
> > > > +	bus->msi = container_of(&pp->irq_domain, struct
> msi_controller,
> > > domain);
> > > > +#else
> > > >  	dw_pcie_msi_chip.dev = pp->dev;
> > > > -	dw_pci.msi_ctrl = &dw_pcie_msi_chip;
> > > > +	bus->msi = &dw_pcie_msi_chip;
> > > >  #endif
> > > >
> > > > -	dw_pci.nr_controllers = 1;
> > > > -	dw_pci.private_data = (void **)&pp;
> > > > +	pci_scan_child_bus(bus);
> > > > +	if (pp->ops->scan_bus)
> > > > +		pp->ops->scan_bus(pp);
> > > > +
> > > > +#ifdef CONFIG_ARM
> > > > +	/* support old dtbs that incorrectly describe IRQs */
> > > > +	pci_fixup_irqs(pci_common_swizzle,
> of_irq_parse_and_map_pci);
> > > > +#endif
> > > >
> > > > -	pci_common_init_dev(pp->dev, &dw_pci);
> > > > +	pci_assign_unassigned_bus_resources(bus);
> > > > +	pci_bus_add_devices(bus);
> > > >
> > > >  	return 0;
> > > >  }
> > > > @@ -544,12 +523,12 @@ static int dw_pcie_rd_other_conf(struct
> > > pcie_port *pp, struct pci_bus *bus,
> > > >
> > > >  	if (bus->parent->number == pp->root_bus_nr) {
> > > >  		type = PCIE_ATU_TYPE_CFG0;
> > > > -		cpu_addr = pp->cfg0_mod_base;
> > > > +		cpu_addr = pp->cfg0_base;
> > > >  		cfg_size = pp->cfg0_size;
> > > >  		va_cfg_base = pp->va_cfg0_base;
> > > >  	} else {
> > > >  		type = PCIE_ATU_TYPE_CFG1;
> > > > -		cpu_addr = pp->cfg1_mod_base;
> > > > +		cpu_addr = pp->cfg1_base;
> > > >  		cfg_size = pp->cfg1_size;
> > > >  		va_cfg_base = pp->va_cfg1_base;
> > > >  	}
> > > > @@ -559,7 +538,7 @@ static int dw_pcie_rd_other_conf(struct
> pcie_port
> > > *pp, struct pci_bus *bus,
> > > >  				  busdev, cfg_size);
> > > >  	ret = dw_pcie_cfg_read(va_cfg_base + address, where, size,
> val);
> > > >  	dw_pcie_prog_outbound_atu(pp, PCIE_ATU_REGION_INDEX0,
> > > > -				  PCIE_ATU_TYPE_IO, pp->io_mod_base,
> > > > +				  PCIE_ATU_TYPE_IO, pp->io_base,
> > > >  				  pp->io_bus_addr, pp->io_size);
> > > >
> > > >  	return ret;
> > > > @@ -579,12 +558,12 @@ static int dw_pcie_wr_other_conf(struct
> > > pcie_port *pp, struct pci_bus *bus,
> > > >
> > > >  	if (bus->parent->number == pp->root_bus_nr) {
> > > >  		type = PCIE_ATU_TYPE_CFG0;
> > > > -		cpu_addr = pp->cfg0_mod_base;
> > > > +		cpu_addr = pp->cfg0_base;
> > > >  		cfg_size = pp->cfg0_size;
> > > >  		va_cfg_base = pp->va_cfg0_base;
> > > >  	} else {
> > > >  		type = PCIE_ATU_TYPE_CFG1;
> > > > -		cpu_addr = pp->cfg1_mod_base;
> > > > +		cpu_addr = pp->cfg1_base;
> > > >  		cfg_size = pp->cfg1_size;
> > > >  		va_cfg_base = pp->va_cfg1_base;
> > > >  	}
> > > > @@ -594,7 +573,7 @@ static int dw_pcie_wr_other_conf(struct
> pcie_port
> > > *pp, struct pci_bus *bus,
> > > >  				  busdev, cfg_size);
> > > >  	ret = dw_pcie_cfg_write(va_cfg_base + address, where, size,
> val);
> > > >  	dw_pcie_prog_outbound_atu(pp, PCIE_ATU_REGION_INDEX0,
> > > > -				  PCIE_ATU_TYPE_IO, pp->io_mod_base,
> > > > +				  PCIE_ATU_TYPE_IO, pp->io_base,
> > > >  				  pp->io_bus_addr, pp->io_size);
> > > >
> > > >  	return ret;
> > > > @@ -626,7 +605,7 @@ static int dw_pcie_valid_config(struct
> pcie_port
> > > *pp,
> > > >  static int dw_pcie_rd_conf(struct pci_bus *bus, u32 devfn, int
> where,
> > > >  			int size, u32 *val)
> > > >  {
> > > > -	struct pcie_port *pp = sys_to_pcie(bus->sysdata);
> > > > +	struct pcie_port *pp = bus->sysdata;
> > > >  	int ret;
> > > >
> > > >  	if (dw_pcie_valid_config(pp, bus, PCI_SLOT(devfn)) == 0) {
> > > > @@ -650,7 +629,7 @@ static int dw_pcie_rd_conf(struct pci_bus
> *bus,
> > > u32 devfn, int where,
> > > >  static int dw_pcie_wr_conf(struct pci_bus *bus, u32 devfn,
> > > >  			int where, int size, u32 val)
> > > >  {
> > > > -	struct pcie_port *pp = sys_to_pcie(bus->sysdata);
> > > > +	struct pcie_port *pp = bus->sysdata;
> > > >  	int ret;
> > > >
> > > >  	if (dw_pcie_valid_config(pp, bus, PCI_SLOT(devfn)) == 0)
> > > > @@ -674,62 +653,6 @@ static struct pci_ops dw_pcie_ops = {
> > > >  	.write = dw_pcie_wr_conf,
> > > >  };
> > > >
> > > > -static int dw_pcie_setup(int nr, struct pci_sys_data *sys)
> > > > -{
> > > > -	struct pcie_port *pp;
> > > > -
> > > > -	pp = sys_to_pcie(sys);
> > > > -
> > > > -	if (global_io_offset < SZ_1M && pp->io_size > 0) {
> > > > -		sys->io_offset = global_io_offset - pp->io_bus_addr;
> > > > -		pci_ioremap_io(global_io_offset, pp->io_base);
> > > > -		global_io_offset += SZ_64K;
> > > > -		pci_add_resource_offset(&sys->resources, &pp->io,
> > > > -					sys->io_offset);
> > > > -	}
> > > > -
> > > > -	sys->mem_offset = pp->mem.start - pp->mem_bus_addr;
> > > > -	pci_add_resource_offset(&sys->resources, &pp->mem, sys-
> > > >mem_offset);
> > > > -	pci_add_resource(&sys->resources, &pp->busn);
> > > > -
> > > > -	return 1;
> > > > -}
> > > > -
> > > > -static struct pci_bus *dw_pcie_scan_bus(int nr, struct
> pci_sys_data
> > > *sys)
> > > > -{
> > > > -	struct pci_bus *bus;
> > > > -	struct pcie_port *pp = sys_to_pcie(sys);
> > > > -
> > > > -	pp->root_bus_nr = sys->busnr;
> > > > -	bus = pci_scan_root_bus(pp->dev, sys->busnr,
> > > > -				  &dw_pcie_ops, sys, &sys->resources);
> > > > -	if (!bus)
> > > > -		return NULL;
> > > > -
> > > > -	if (bus && pp->ops->scan_bus)
> > > > -		pp->ops->scan_bus(pp);
> > > > -
> > > > -	return bus;
> > > > -}
> > > > -
> > > > -static int dw_pcie_map_irq(const struct pci_dev *dev, u8 slot,
> u8
> > > pin)
> > > > -{
> > > > -	struct pcie_port *pp = sys_to_pcie(dev->bus->sysdata);
> > > > -	int irq;
> > > > -
> > > > -	irq = of_irq_parse_and_map_pci(dev, slot, pin);
> > > > -	if (!irq)
> > > > -		irq = pp->irq;
> > > > -
> > > > -	return irq;
> > > > -}
> > > > -
> > > > -static struct hw_pci dw_pci = {
> > > > -	.setup		= dw_pcie_setup,
> > > > -	.scan		= dw_pcie_scan_bus,
> > > > -	.map_irq	= dw_pcie_map_irq,
> > > > -};
> > > > -
> > > >  void dw_pcie_setup_rc(struct pcie_port *pp)
> > > >  {
> > > >  	u32 val;
> > > > diff --git a/drivers/pci/host/pcie-designware.h
> > > b/drivers/pci/host/pcie-designware.h
> > > > index d0bbd27..264c969 100644
> > > > --- a/drivers/pci/host/pcie-designware.h
> > > > +++ b/drivers/pci/host/pcie-designware.h
> > > > @@ -27,25 +27,21 @@ struct pcie_port {
> > > >  	u8			root_bus_nr;
> > > >  	void __iomem		*dbi_base;
> > > >  	u64			cfg0_base;
> > > > -	u64			cfg0_mod_base;
> > > >  	void __iomem		*va_cfg0_base;
> > > >  	u32			cfg0_size;
> > > >  	u64			cfg1_base;
> > > > -	u64			cfg1_mod_base;
> > > >  	void __iomem		*va_cfg1_base;
> > > >  	u32			cfg1_size;
> > > > -	u64			io_base;
> > > > -	u64			io_mod_base;
> > > > +	resource_size_t		io_base;
> > > >  	phys_addr_t		io_bus_addr;
> > > >  	u32			io_size;
> > > >  	u64			mem_base;
> > > > -	u64			mem_mod_base;
> > > >  	phys_addr_t		mem_bus_addr;
> > > >  	u32			mem_size;
> > > > -	struct resource		cfg;
> > > > -	struct resource		io;
> > > > -	struct resource		mem;
> > > > -	struct resource		busn;
> > > > +	struct resource		*cfg;
> > > > +	struct resource		*io;
> > > > +	struct resource		*mem;
> > > > +	struct resource		*busn;
> > > >  	int			irq;
> > > >  	u32			lanes;
> > > >  	struct pcie_host_ops	*ops;
> > > > diff --git a/drivers/pci/host/pcie-spear13xx.c
> > > b/drivers/pci/host/pcie-spear13xx.c
> > > > index c49fbdc..03eb204 100644
> > > > --- a/drivers/pci/host/pcie-spear13xx.c
> > > > +++ b/drivers/pci/host/pcie-spear13xx.c
> > > > @@ -286,7 +286,7 @@ static int spear13xx_add_pcie_port(struct
> > > pcie_port *pp,
> > > >  		return ret;
> > > >  	}
> > > >
> > > > -	pp->root_bus_nr = -1;
> > > > +	pp->root_bus_nr = 0;
> > > >  	pp->ops = &spear13xx_pcie_host_ops;
> > > >
> > > >  	ret = dw_pcie_host_init(pp);
> > >
> > > --
> > > Pengutronix e.K.             | Lucas Stach                 |
> > > Industrial Linux Solutions   | http://www.pengutronix.de/  |
> >
> 
> --
> Pengutronix e.K.             | Lucas Stach                 |
> Industrial Linux Solutions   | http://www.pengutronix.de/  |


From bjorn.andersson at sonymobile.com  Wed Aug 19 09:35:48 2015
From: bjorn.andersson at sonymobile.com (Bjorn Andersson)
Date: Wed, 19 Aug 2015 09:35:48 -0700
Subject: [PATCH v4 1/3] ARM: qcom: add SFPB nodes to IPQ806x dts
In-Reply-To: <1439931860-7473-2-git-send-email-mathieu@codeaurora.org>
References: <1439931860-7473-1-git-send-email-mathieu@codeaurora.org>
 <1439931860-7473-2-git-send-email-mathieu@codeaurora.org>
Message-ID: <20150819163548.GX13472@usrtlx11787.corpusers.net>

On Tue 18 Aug 14:04 PDT 2015, Mathieu Olivari wrote:

> Add one new node to the ipq806x.dtsi file to declare & register the
> hardware spinlock devices. This mechanism is required to be used by
> other drivers such as SMEM.
> 

Still looks good, but you should have added:

Reviewed-by: Bjorn Andersson <bjorn.andersson at sonymobile.com>
> Signed-off-by: Mathieu Olivari <mathieu at codeaurora.org>
> ---
>  arch/arm/boot/dts/qcom-ipq8064.dtsi | 11 +++++++++++
>  1 file changed, 11 insertions(+)
> 
> diff --git a/arch/arm/boot/dts/qcom-ipq8064.dtsi b/arch/arm/boot/dts/qcom-ipq8064.dtsi
> index 9f727d8..8d366ae 100644
> --- a/arch/arm/boot/dts/qcom-ipq8064.dtsi
> +++ b/arch/arm/boot/dts/qcom-ipq8064.dtsi
> @@ -329,5 +329,16 @@
>  			#reset-cells = <1>;
>  		};
>  
> +		sfpb_mutex_block: syscon at 1200600 {
> +			compatible = "syscon";
> +			reg = <0x01200600 0x100>;
> +		};
> +	};
> +
> +	sfpb_mutex: sfpb-mutex {
> +		compatible = "qcom,sfpb-mutex";
> +		syscon = <&sfpb_mutex_block 4 4>;
> +
> +		#hwlock-cells = <1>;
>  	};
>  };
> -- 
> 2.1.4
> 


From bjorn.andersson at sonymobile.com  Wed Aug 19 09:36:28 2015
From: bjorn.andersson at sonymobile.com (Bjorn Andersson)
Date: Wed, 19 Aug 2015 09:36:28 -0700
Subject: [PATCH v4 2/3] ARM: qcom: add SMEM device node to IPQ806x dts
In-Reply-To: <1439931860-7473-3-git-send-email-mathieu@codeaurora.org>
References: <1439931860-7473-1-git-send-email-mathieu@codeaurora.org>
 <1439931860-7473-3-git-send-email-mathieu@codeaurora.org>
Message-ID: <20150819163628.GY13472@usrtlx11787.corpusers.net>

On Tue 18 Aug 14:04 PDT 2015, Mathieu Olivari wrote:

> SMEM is used on IPQ806x to store various board related information such
> as boot device and flash partition layout. We'll declare it as a device
> so we can make use of it thanks to the new SMEM soc driver.
> 

Reviewed-by: Bjorn Andersson <bjorn.andersson at sonymobile.com>

> Signed-off-by: Mathieu Olivari <mathieu at codeaurora.org>
> ---
> 
> Notes:
>     v2:
>     *Rename "smem" tag into "smem_region"
> 
>  arch/arm/boot/dts/qcom-ipq8064.dtsi | 8 +++++++-
>  1 file changed, 7 insertions(+), 1 deletion(-)
> 
> diff --git a/arch/arm/boot/dts/qcom-ipq8064.dtsi b/arch/arm/boot/dts/qcom-ipq8064.dtsi
> index 8d366ae..9834c94 100644
> --- a/arch/arm/boot/dts/qcom-ipq8064.dtsi
> +++ b/arch/arm/boot/dts/qcom-ipq8064.dtsi
> @@ -55,7 +55,7 @@
>  			no-map;
>  		};
>  
> -		smem at 41000000 {
> +		smem_region: smem at 41000000 {
>  			reg = <0x41000000 0x200000>;
>  			no-map;
>  		};
> @@ -341,4 +341,10 @@
>  
>  		#hwlock-cells = <1>;
>  	};
> +
> +	smem {
> +		compatible = "qcom,smem";
> +		memory-region = <&smem_region>;
> +		hwlocks = <&sfpb_mutex 3>;
> +	};
>  };
> -- 
> 2.1.4
> 


From Dave.Martin at arm.com  Wed Aug 19 09:37:36 2015
From: Dave.Martin at arm.com (Dave Martin)
Date: Wed, 19 Aug 2015 17:37:36 +0100
Subject: [PATCH 2/3] [v4] ARM64: TTY: hvc_dcc: Add support for ARM64 dcc
In-Reply-To: <55D4ABF4.5020600@codeaurora.org>
References: <1438992995-22610-1-git-send-email-timur@codeaurora.org>
 <1438992995-22610-2-git-send-email-timur@codeaurora.org>
 <20150810094008.GD1604@arm.com> <55D2749A.401@codeaurora.org>
 <20150818082141.GA6281@e103592.cambridge.arm.com>
 <55D3825D.6020105@codeaurora.org>
 <20150819101426.GB6281@e103592.cambridge.arm.com>
 <55D4ABF4.5020600@codeaurora.org>
Message-ID: <20150819163736.GC6281@e103592.cambridge.arm.com>

On Wed, Aug 19, 2015 at 11:16:52AM -0500, Timur Tabi wrote:
> On 08/19/2015 05:14 AM, Dave Martin wrote:
> >>>So does that mean that ldrb will zero-extend the byte to all 64 bits of x3?
> >Yes.  No extra operation is required.
> 
> So my patch is actually correct as-is?

+static inline void __dcc_putchar(char c)
+{
+	asm volatile("msr dbgdtrtx_el0, %0"
+			: /* No output register */
+			: "r" (c));

For safety, you still need to make sure that c is appropriately masked
before passing it to the asm.  Something like this should definitely be
safe:

			: "r" ((unsigned long)(unsigned char)c)

GCC can then emit uxtb or not, depending on whether it's needed in each
context where the asm is inlined.

Cheers
---Dave



From broonie at kernel.org  Wed Aug 19 09:32:32 2015
From: broonie at kernel.org (Mark Brown)
Date: Wed, 19 Aug 2015 09:32:32 -0700
Subject: [PATCH v3 0/8] ARM: sunxi: Add Reduced Serial Bus support
In-Reply-To: <1439958009-14056-1-git-send-email-wens@csie.org>
References: <1439958009-14056-1-git-send-email-wens@csie.org>
Message-ID: <20150819163232.GS10748@sirena.org.uk>

On Wed, Aug 19, 2015 at 12:20:01PM +0800, Chen-Yu Tsai wrote:
> Hi everyone,
> 
> This is my third attempt at adding support for Allwinner's Reduced
> Serial Bus (RSB), which is used to communicate with PMICs and other
> peripherals on their newer SoCs, such as the A23/A33/A80.

This is flagged as something that is specific to the Allwinner SoCs.
Why add generic regmap support rather than just implement the regmap
reg_read() and reg_write() in a regmap in the controller driver?  Are
there expected to be other controller drivers from other vendors?
-------------- next part --------------
A non-text attachment was scrubbed...
Name: signature.asc
Type: application/pgp-signature
Size: 473 bytes
Desc: Digital signature
URL: <http://lists.infradead.org/pipermail/linux-arm-kernel/attachments/20150819/63d78ebe/attachment.sig>

From bjorn.andersson at sonymobile.com  Wed Aug 19 09:37:52 2015
From: bjorn.andersson at sonymobile.com (Bjorn Andersson)
Date: Wed, 19 Aug 2015 09:37:52 -0700
Subject: [PATCH v4 3/3] mtd: add SMEM parser for QCOM platforms
In-Reply-To: <1439931860-7473-4-git-send-email-mathieu@codeaurora.org>
References: <1439931860-7473-1-git-send-email-mathieu@codeaurora.org>
 <1439931860-7473-4-git-send-email-mathieu@codeaurora.org>
Message-ID: <20150819163752.GZ13472@usrtlx11787.corpusers.net>

On Tue 18 Aug 14:04 PDT 2015, Mathieu Olivari wrote:

> On QCOM platforms using MTD devices storage (such as IPQ806x), SMEM is
> used to store partition layout. This new parser can now be used to read
> SMEM and use it to register an MTD layout according to its content.
> 

Still looks good, but you should have added:

Acked-by: Bjorn Andersson <bjorn.andersson at sonymobile.com>

> Signed-off-by: Mathieu Olivari <mathieu at codeaurora.org>
> ---
> 
> Notes:
>     v2:
>     *Release the SPI device reference after looking it up (put_device())
>     *Represent SMEM data as __le32 rather than u32
>     *Move new DT nodes in their proper respective location
>     *Address readability concerns in MTD parser
>     
>     v3:
>     *Redefine SMEM functions prototypes for better readability
>     *Duplicate MTD name instead of pointing to SMEM string location in case
>      mtd layer tries to free it
>     *Rework some of the comments
>     
>     v4:
>     *Fix case in the license string
> 
>  drivers/mtd/Kconfig          |   7 ++
>  drivers/mtd/Makefile         |   1 +
>  drivers/mtd/qcom_smem_part.c | 246 +++++++++++++++++++++++++++++++++++++++++++
>  3 files changed, 254 insertions(+)
>  create mode 100644 drivers/mtd/qcom_smem_part.c
> 
> diff --git a/drivers/mtd/Kconfig b/drivers/mtd/Kconfig
> index a03ad29..debc887 100644
> --- a/drivers/mtd/Kconfig
> +++ b/drivers/mtd/Kconfig
> @@ -155,6 +155,13 @@ config MTD_BCM47XX_PARTS
>  	  This provides partitions parser for devices based on BCM47xx
>  	  boards.
>  
> +config MTD_QCOM_SMEM_PARTS
> +	tristate "QCOM SMEM partitioning support"
> +	depends on QCOM_SMEM
> +	help
> +	  This provides partitions parser for QCOM devices using SMEM
> +	  such as IPQ806x.
> +
>  comment "User Modules And Translation Layers"
>  
>  #
> diff --git a/drivers/mtd/Makefile b/drivers/mtd/Makefile
> index 99bb9a1..b3c7de4 100644
> --- a/drivers/mtd/Makefile
> +++ b/drivers/mtd/Makefile
> @@ -13,6 +13,7 @@ obj-$(CONFIG_MTD_AFS_PARTS)	+= afs.o
>  obj-$(CONFIG_MTD_AR7_PARTS)	+= ar7part.o
>  obj-$(CONFIG_MTD_BCM63XX_PARTS)	+= bcm63xxpart.o
>  obj-$(CONFIG_MTD_BCM47XX_PARTS)	+= bcm47xxpart.o
> +obj-$(CONFIG_MTD_QCOM_SMEM_PARTS) += qcom_smem_part.o
>  
>  # 'Users' - code which presents functionality to userspace.
>  obj-$(CONFIG_MTD_BLKDEVS)	+= mtd_blkdevs.o
> diff --git a/drivers/mtd/qcom_smem_part.c b/drivers/mtd/qcom_smem_part.c
> new file mode 100644
> index 0000000..b4f8acc
> --- /dev/null
> +++ b/drivers/mtd/qcom_smem_part.c
> @@ -0,0 +1,246 @@
> +/*
> + * Copyright (c) 2015, The Linux Foundation. All rights reserved.
> + *
> + * This program is free software; you can redistribute it and/or modify
> + * it under the terms of the GNU General Public License version 2 and
> + * only 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/kernel.h>
> +#include <linux/device.h>
> +#include <linux/slab.h>
> +
> +#include <linux/mtd/mtd.h>
> +#include <linux/mtd/partitions.h>
> +#include <linux/spi/spi.h>
> +#include <linux/module.h>
> +
> +#include <linux/soc/qcom/smem.h>
> +
> +/* Processor/host identifier for the application processor */
> +#define QCOM_SMEM_GLOBAL		0
> +
> +/* SMEM items index */
> +#define SMEM_AARM_PARTITION_TABLE	9
> +#define SMEM_BOOT_FLASH_TYPE		421
> +#define SMEM_BOOT_FLASH_BLOCK_SIZE	424
> +
> +/* SMEM Flash types */
> +#define SMEM_FLASH_NAND			2
> +#define SMEM_FLASH_SPI			6
> +
> +#define SMEM_PART_NAME_SZ		16
> +#define SMEM_PARTS_MAX			32
> +
> +struct smem_partition {
> +	char name[SMEM_PART_NAME_SZ];
> +	__le32 start;
> +	__le32 size;
> +	__le32 attr;
> +};
> +
> +struct smem_partition_table {
> +	u8 magic[8];
> +	__le32 version;
> +	__le32 len;
> +	struct smem_partition parts[SMEM_PARTS_MAX];
> +};
> +
> +/* SMEM Magic values in partition table */
> +static const u8 SMEM_PTABLE_MAGIC[] = {
> +	0xaa, 0x73, 0xee, 0x55,
> +	0xdb, 0xbd, 0x5e, 0xe3,
> +};
> +
> +static int qcom_smem_get_flash_blksz(void)
> +{
> +	int ret;
> +	size_t size;
> +	u64 *smem_blksz;
> +
> +	ret = qcom_smem_get(QCOM_SMEM_GLOBAL, SMEM_BOOT_FLASH_BLOCK_SIZE,
> +			    (void **) &smem_blksz, &size);
> +
> +	if (ret < 0) {
> +		pr_err("Unable to read flash blksz from SMEM\n");
> +		return -ENOENT;
> +	}
> +
> +	if (size != sizeof(*smem_blksz)) {
> +		pr_err("Invalid flash blksz size in SMEM\n");
> +		return -EINVAL;
> +	}
> +
> +	/* Sanity check block size value before casting it */
> +	if (*smem_blksz > INT_MAX) {
> +		pr_err("Invalid flash block size in SMEM\n");
> +		return -EINVAL;
> +	}
> +
> +	return (int) *smem_blksz;
> +}
> +
> +static int qcom_smem_get_flash_type(void)
> +{
> +	int ret;
> +	size_t size;
> +	u64 *smem_flash_type;
> +
> +	ret = qcom_smem_get(QCOM_SMEM_GLOBAL, SMEM_BOOT_FLASH_TYPE,
> +			    (void **) &smem_flash_type, &size);
> +
> +	if (ret < 0) {
> +		pr_err("Unable to read flash type from SMEM\n");
> +		return -ENOENT;
> +	}
> +
> +	if (size != sizeof(*smem_flash_type)) {
> +		pr_err("Invalid flash type size in SMEM\n");
> +		return -EINVAL;
> +	}
> +
> +	/* Sanity check flash type value before casting it */
> +	if (*smem_flash_type > INT_MAX) {
> +		pr_err("Invalid flash type in SMEM\n");
> +		return -EINVAL;
> +	}
> +
> +	return (int) *smem_flash_type;
> +}
> +
> +static struct smem_partition *qcom_smem_get_flash_partitions(size_t *count)
> +{
> +	struct smem_partition_table *smem_parts;
> +	int ret;
> +
> +	ret = qcom_smem_get(QCOM_SMEM_GLOBAL, SMEM_AARM_PARTITION_TABLE,
> +			    (void **) &smem_parts, NULL);
> +
> +	if (ret < 0) {
> +		pr_err("Unable to read partition table from SMEM\n");
> +		return ERR_PTR(-ENOENT);
> +	}
> +
> +	if (memcmp(SMEM_PTABLE_MAGIC, smem_parts->magic,
> +		   sizeof(SMEM_PTABLE_MAGIC))) {
> +		pr_err("SMEM partition magic invalid\n");
> +		return ERR_PTR(-EINVAL);
> +	}
> +
> +	if (le32_to_cpu(smem_parts->version) != 3) {
> +		pr_err("SMEM version unsupported\n");
> +		return ERR_PTR(-EINVAL);
> +	}
> +
> +	*count = le32_to_cpu(smem_parts->len);
> +
> +	return smem_parts->parts;
> +}
> +
> +static int of_dev_node_match(struct device *dev, void *data)
> +{
> +	return dev->of_node == data;
> +}
> +
> +static bool is_spi_device(struct device_node *np)
> +{
> +	struct device *dev;
> +
> +	dev = bus_find_device(&spi_bus_type, NULL, np, of_dev_node_match);
> +	if (!dev)
> +		return false;
> +
> +	put_device(dev);
> +	return true;
> +}
> +
> +static int parse_qcom_smem_partitions(struct mtd_info *master,
> +				      struct mtd_partition **pparts,
> +				      struct mtd_part_parser_data *data)
> +{
> +	struct smem_partition *smem_part;
> +	int smem_flash_type, smem_blksz;
> +	size_t nbparts = 0, len;
> +	struct mtd_partition *mtd_parts;
> +	struct device_node *of_node = data->of_node;
> +
> +	/* Only parse partitions on the specified memory type */
> +	smem_flash_type = qcom_smem_get_flash_type();
> +	if (smem_flash_type < 0)
> +		return smem_flash_type;
> +
> +	if ((smem_flash_type == SMEM_FLASH_NAND && !mtd_type_is_nand(master))
> +	    || (smem_flash_type == SMEM_FLASH_SPI && !is_spi_device(of_node)))
> +		return 0;
> +
> +	/* Make sure the block size in SMEM matches the block size in MTD */
> +	smem_blksz = qcom_smem_get_flash_blksz();
> +	if (smem_blksz < 0)
> +		return smem_blksz;
> +
> +	if (smem_blksz != master->erasesize) {
> +		pr_err("SMEM block size differs from MTD block size\n");
> +		return -EINVAL;
> +	}
> +
> +	/* Get partition pointer from SMEM */
> +	smem_part = qcom_smem_get_flash_partitions(&nbparts);
> +	if (IS_ERR_OR_NULL(smem_part))
> +		return -EINVAL;
> +
> +	/* Allocate and populate the mtd structures */
> +	mtd_parts = kcalloc(nbparts, sizeof(*mtd_parts), GFP_KERNEL);
> +	if (!mtd_parts)
> +		return -ENOMEM;
> +
> +	*pparts = mtd_parts;
> +	len = nbparts;
> +
> +	while (len--) {
> +		mtd_parts->name = kstrdup(smem_part->name, GFP_KERNEL);
> +		mtd_parts->size = le32_to_cpu(smem_part->size) * smem_blksz;
> +		mtd_parts->offset = le32_to_cpu(smem_part->start) * smem_blksz;
> +
> +		/*
> +		 * The last SMEM partition may have its size marked as
> +		 * something like 0xffffffff, which means "until the end of the
> +		 * flash device". In this case, truncate it.
> +		 */
> +		if (mtd_parts->offset + mtd_parts->size > master->size)
> +			mtd_parts->size = master->size - mtd_parts->offset;
> +
> +		smem_part++;
> +		mtd_parts++;
> +	}
> +
> +	return nbparts;
> +}
> +
> +static struct mtd_part_parser qcom_smem_parser = {
> +	.owner = THIS_MODULE,
> +	.parse_fn = parse_qcom_smem_partitions,
> +	.name = "qcom-smem",
> +};
> +
> +static int __init qcom_smem_parser_init(void)
> +{
> +	register_mtd_parser(&qcom_smem_parser);
> +	return 0;
> +}
> +
> +static void __exit qcom_smem_parser_exit(void)
> +{
> +	deregister_mtd_parser(&qcom_smem_parser);
> +}
> +
> +module_init(qcom_smem_parser_init);
> +module_exit(qcom_smem_parser_exit);
> +
> +MODULE_LICENSE("GPL v2");
> +MODULE_AUTHOR("Mathieu Olivari <mathieu at codeaurora.org>");
> +MODULE_DESCRIPTION("Parsing code for SMEM based partition tables");
> -- 
> 2.1.4
> 


From codekipper at gmail.com  Wed Aug 19 09:43:16 2015
From: codekipper at gmail.com (codekipper at gmail.com)
Date: Wed, 19 Aug 2015 18:43:16 +0200
Subject: [linux-sunxi][PATCH] ARM: sun7i: dt: Add new Olimex A20 EVB device
Message-ID: <1440002596-2611-1-git-send-email-codekipper@gmail.com>

From: Marcus Cooper <codekipper at gmail.com>

The A20-SOM-EVB is a reference design of a 2-layer board for the
A20-SOM.
It expands the features of A20-SOM by adding VGA connector, HDMI
connector, audio In/Out, LCD connector, 2 Mpix camera, gigabit
Ethernet, SATA, USB-OTG and 2 USB hosts.

This patch adds basic support for the device
https://www.olimex.com/Products/SOM/A20/A20-SOM-EVB/

More information on the SOM can be found here
http://linux-sunxi.org/Olimex_A20-SOM.

Signed-off-by: Marcus Cooper <codekipper at gmail.com>
---
 arch/arm/boot/dts/Makefile                    |   1 +
 arch/arm/boot/dts/sun7i-a20-olinuxino-evb.dts | 233 ++++++++++++++++++++++++++
 2 files changed, 234 insertions(+)
 create mode 100644 arch/arm/boot/dts/sun7i-a20-olinuxino-evb.dts

diff --git a/arch/arm/boot/dts/Makefile b/arch/arm/boot/dts/Makefile
index 6d7cec1..fdbda9b 100644
--- a/arch/arm/boot/dts/Makefile
+++ b/arch/arm/boot/dts/Makefile
@@ -613,6 +613,7 @@ dtb-$(CONFIG_MACH_SUN7I) += \
 	sun7i-a20-olinuxino-lime.dtb \
 	sun7i-a20-olinuxino-lime2.dtb \
 	sun7i-a20-olinuxino-micro.dtb \
+	sun7i-a20-olinuxino-evb.dtb \
 	sun7i-a20-orangepi.dtb \
 	sun7i-a20-orangepi-mini.dtb \
 	sun7i-a20-pcduino3.dtb \
diff --git a/arch/arm/boot/dts/sun7i-a20-olinuxino-evb.dts b/arch/arm/boot/dts/sun7i-a20-olinuxino-evb.dts
new file mode 100644
index 0000000..a0071fa
--- /dev/null
+++ b/arch/arm/boot/dts/sun7i-a20-olinuxino-evb.dts
@@ -0,0 +1,233 @@
+/*
+ * Copyright 2015 - Marcus Cooper <codekipper at gmail.com>
+ *
+ * This file is dual-licensed: you can use it either under the terms
+ * of the GPL or the X11 license, at your option. Note that this dual
+ * licensing only applies to this file, and not this project as a
+ * whole.
+ *
+ *  a) This file is free software; you can redistribute it and/or
+ *     modify it under the terms of the GNU General Public License as
+ *     published by the Free Software Foundation; either version 2 of the
+ *     License, or (at your option) any later version.
+ *
+ *     This file is distributed in the hope that it will be useful,
+ *     but WITHOUT ANY WARRANTY; without even the implied warranty of
+ *     MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ *     GNU General Public License for more details.
+ *
+ * Or, alternatively,
+ *
+ *  b) Permission is hereby granted, free of charge, to any person
+ *     obtaining a copy of this software and associated documentation
+ *     files (the "Software"), to deal in the Software without
+ *     restriction, including without limitation the rights to use,
+ *     copy, modify, merge, publish, distribute, sublicense, and/or
+ *     sell copies of the Software, and to permit persons to whom the
+ *     Software is furnished to do so, subject to the following
+ *     conditions:
+ *
+ *     The above copyright notice and this permission notice shall be
+ *     included in all copies or substantial portions of the Software.
+ *
+ *     THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
+ *     EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES
+ *     OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
+ *     NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT
+ *     HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY,
+ *     WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
+ *     FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR
+ *     OTHER DEALINGS IN THE SOFTWARE.
+ */
+
+/dts-v1/;
+#include "sun7i-a20.dtsi"
+#include "sunxi-common-regulators.dtsi"
+
+#include <dt-bindings/gpio/gpio.h>
+#include <dt-bindings/interrupt-controller/irq.h>
+#include <dt-bindings/pinctrl/sun4i-a10.h>
+
+/ {
+	model = "Olimex A20-OLinuXino-EVB";
+	compatible = "olimex,a20-olinuxino-evb", "allwinner,sun7i-a20";
+
+	aliases {
+		serial0 = &uart0;
+	};
+
+	chosen {
+		stdout-path = "serial0:115200n8";
+	};
+
+	leds {
+		compatible = "gpio-leds";
+		pinctrl-names = "default";
+		pinctrl-0 = <&led_pins_olinuxinoevb>;
+
+		green {
+			label = "a20-olinuxino-evb:green:usr";
+			gpios = <&pio 7 2 GPIO_ACTIVE_HIGH>;
+			default-state = "on";
+		};
+	};
+
+	reg_axp_ipsout: axp_ipsout {
+		compatible = "regulator-fixed";
+		regulator-name = "axp-ipsout";
+		regulator-min-microvolt = <5000000>;
+		regulator-max-microvolt = <5000000>;
+		regulator-always-on;
+	};
+};
+
+&ahci {
+	target-supply = <&reg_ahci_5v>;
+	status = "okay";
+};
+
+&ehci0 {
+	status = "okay";
+};
+
+&ehci1 {
+	status = "okay";
+};
+
+&gmac {
+	pinctrl-names = "default";
+	pinctrl-0 = <&gmac_pins_rgmii_a>;
+	phy = <&phy1>;
+	phy-mode = "rgmii";
+	status = "okay";
+
+	phy1: ethernet-phy at 1 {
+		reg = <1>;
+	};
+};
+
+&i2c0 {
+	pinctrl-names = "default";
+	pinctrl-0 = <&i2c0_pins_a>;
+	status = "okay";
+
+	axp209: pmic at 34 {
+		compatible = "x-powers,axp209";
+		reg = <0x34>;
+		interrupt-parent = <&nmi_intc>;
+		interrupts = <0 IRQ_TYPE_LEVEL_LOW>;
+
+		interrupt-controller;
+		#interrupt-cells = <1>;
+
+		acin-supply = <&reg_axp_ipsout>;
+		vin2-supply = <&reg_axp_ipsout>;
+		vin3-supply = <&reg_axp_ipsout>;
+		ldo24in-supply = <&reg_axp_ipsout>;
+		ldo3in-supply = <&reg_axp_ipsout>;
+
+		regulators {
+			vdd_rtc: ldo1 {
+				regulator-min-microvolt = <1300000>;
+				regulator-max-microvolt = <1300000>;
+				regulator-always-on;
+			};
+
+			avcc: ldo2 {
+				regulator-min-microvolt = <1800000>;
+				regulator-max-microvolt = <3300000>;
+				regulator-always-on;
+			};
+
+			vcc_csi0: ldo3 {
+				regulator-min-microvolt = <700000>;
+				regulator-max-microvolt = <3500000>;
+				regulator-always-on;
+			};
+
+			vcc_csi1: ldo4 {
+				regulator-min-microvolt = <1250000>;
+				regulator-max-microvolt = <3300000>;
+				regulator-always-on;
+			};
+
+			vdd_cpu: dcdc2 {
+				regulator-min-microvolt = <700000>;
+				regulator-max-microvolt = <2275000>;
+				regulator-always-on;
+			};
+
+			vdd_int: dcdc3 {
+				regulator-min-microvolt = <700000>;
+				regulator-max-microvolt = <3500000>;
+				regulator-always-on;
+			};
+		};
+	};
+};
+
+&i2c1 {
+	pinctrl-names = "default";
+	pinctrl-0 = <&i2c1_pins_a>;
+	status = "okay";
+};
+
+&mmc0 {
+	pinctrl-names = "default";
+	pinctrl-0 = <&mmc0_pins_a>, <&mmc0_cd_pin_reference_design>;
+	vmmc-supply = <&reg_vcc3v3>;
+	bus-width = <4>;
+	cd-gpios = <&pio 7 1 GPIO_ACTIVE_HIGH>; /* PH1 */
+	cd-inverted;
+	status = "okay";
+};
+
+&ohci0 {
+	status = "okay";
+};
+
+&ohci1 {
+	status = "okay";
+};
+
+&pio {
+	ahci_pwr_pin_olinuxinoevb: ahci_pwr_pin at 1 {
+		allwinner,pins = "PC3";
+		allwinner,function = "gpio_out";
+		allwinner,drive = <SUN4I_PINCTRL_10_MA>;
+		allwinner,pull = <SUN4I_PINCTRL_NO_PULL>;
+	};
+
+	led_pins_olinuxinoevb: led_pins at 0 {
+		allwinner,pins = "PH2";
+		allwinner,function = "gpio_out";
+		allwinner,drive = <SUN4I_PINCTRL_20_MA>;
+		allwinner,pull = <SUN4I_PINCTRL_NO_PULL>;
+	};
+};
+
+&reg_ahci_5v {
+	pinctrl-0 = <&ahci_pwr_pin_olinuxinoevb>;
+	gpio = <&pio 2 3 GPIO_ACTIVE_HIGH>;
+	status = "okay";
+};
+
+&reg_usb1_vbus {
+	status = "okay";
+};
+
+&reg_usb2_vbus {
+	status = "okay";
+};
+
+&uart0 {
+	pinctrl-names = "default";
+	pinctrl-0 = <&uart0_pins_a>;
+	status = "okay";
+};
+
+&usbphy {
+	usb1_vbus-supply = <&reg_usb1_vbus>;
+	usb2_vbus-supply = <&reg_usb2_vbus>;
+	status = "okay";
+};
-- 
2.5.0



From tyler.baker at linaro.org  Wed Aug 19 09:48:43 2015
From: tyler.baker at linaro.org (Tyler Baker)
Date: Wed, 19 Aug 2015 09:48:43 -0700
Subject: [GIT PULL 9/9] ARM: tegra: Default configuration updates for
 v4.3-rc1
In-Reply-To: <20150819103305.GF26627@ulmo>
References: <1439563720-13189-1-git-send-email-thierry.reding@gmail.com>
 <1439563720-13189-10-git-send-email-thierry.reding@gmail.com>
 <CANMBJr7PKy-eCcB3HiBajpApHS_BYPa7xfKjTqV4o8Z1hwY99A@mail.gmail.com>
 <20150819091358.GA26627@ulmo>
 <1439977724.4135.90.camel@collabora.co.uk>
 <20150819103305.GF26627@ulmo>
Message-ID: <CANMBJr4Peshs09H9gHZymE7bcJT2Ujp15_JhK2nuhb1FtEhJCA@mail.gmail.com>

On 19 August 2015 at 03:33, Thierry Reding <thierry.reding at gmail.com> wrote:
> On Wed, Aug 19, 2015 at 11:48:44AM +0200, Sjoerd Simons wrote:
>> On Wed, 2015-08-19 at 11:14 +0200, Thierry Reding wrote:
>> > On Tue, Aug 18, 2015 at 03:30:41PM -0700, Tyler Baker wrote:
>> > > Hi Theirry,
>> > >
>> > >
>> > > This isn't where the story ends unfortunately. The collabora lab
>> > > also
>> > > has a jetson-tk1, booted in the same manner, which boots next
>> > > -20150818
>> > > fine[4]. The only differences I can spot in the two boot logs is
>> > > that
>> > > the collabora board is using an older version of u-boot, where as
>> > > my
>> > > board is using a newer version. U-Boot 2015.01-00231-gab77f24-dirty
>> > > (Good) vs U-Boot 2015.07-00130-gb217c89 (Bad).
>>
>> Our 2015.01-00231-gab77f24-dirty is 2015.01-00231-gab77f24 + changes
>> which got merged as 053b86e6d8e50359412e626c33bae3f7bafd74dd in
>> upstream u-boot.
>>
>> Fwiw:
>> $ git show 2015.01-00231-gab77f24
>> commit ab77f24119e80257de4ab017b877f92f96980562
>> Merge: d928664 fa58b10
>> Author: Tom Rini <trini at ti.com>
>> Date:   Thu Jan 15 14:05:31 2015 -0500
>>
>>     Merge branch 'master' of git://git.denx.de/u-boot-ti
>>
>> Which is definately a commit you should hae in your upstream u-boot
>> tree.
>
> Yeah, I suck. I was running:
>
>         $ git show gab77f24
>
> I didn't know git could parse the full output from git describe.
>
>> > I don't have either of those commits in any of the U-Boot trees I
>> > have.
>> > Perhaps whatever tree this comes from has local patches that cause
>> > the
>> > breakage? The version that I use a recent upstream U-Boot with some
>> > local patches, none of which should impact Jetson TK1 in any way.
>> > Just
>> > to make sure I tried running latest origin/master, which identifies
>> > thusly:
>> >
>> >     U-Boot 2015.10-rc2-00040-g0f9258228e2b
>> >
>> > And that boots next-20150818 fine.
>>
>> Probably worth for tyler to test that u-boot commit on his jetson to
>> see if that solves the issue he's having...
>
> I've tried reconstructing the version that Tyler is running by checking
> out 2015.01-00231-gab77f24 and applying 053b86e6d8e5 ("pci: tegra: Fix
> port information parsing") on top, but that also leaves me with a
> bootable system, so no way of reproducing. I agree that upgrading to a
> more recent U-Boot version sounds like the best way forward because it
> has already proven to work on at least two setups.

Thanks for looking into this issue guys. I'll upgrade u-boot when I
return from Plumbers this week and report back.

Cheers,

Tyler


From tyler.baker at linaro.org  Wed Aug 19 09:50:13 2015
From: tyler.baker at linaro.org (Tyler Baker)
Date: Wed, 19 Aug 2015 09:50:13 -0700
Subject: [GIT PULL 9/9] ARM: tegra: Default configuration updates for
 v4.3-rc1
In-Reply-To: <55D46550.7090203@kapsi.fi>
References: <1439563720-13189-1-git-send-email-thierry.reding@gmail.com>
 <1439563720-13189-10-git-send-email-thierry.reding@gmail.com>
 <CANMBJr7PKy-eCcB3HiBajpApHS_BYPa7xfKjTqV4o8Z1hwY99A@mail.gmail.com>
 <55D46550.7090203@kapsi.fi>
Message-ID: <CANMBJr7y3Nz+wXQqxmOVsWVgdu+ZOk0Vvzamd4e+S9JJx2iBQw@mail.gmail.com>

Hi Mikko,

On 19 August 2015 at 04:15, Mikko Perttunen <mikko.perttunen at kapsi.fi> wrote:
> Please try disabling TEGRA124_EMC and seeing if that makes any difference.

I disabled CONFIG_TEGRA124_EMC and the problem on my end still exists.
Thanks for the suggestion.

Cheers,

Tyler


From will.deacon at arm.com  Wed Aug 19 09:50:09 2015
From: will.deacon at arm.com (Will Deacon)
Date: Wed, 19 Aug 2015 17:50:09 +0100
Subject: [PATCH v5 1/5] arm/arm64: add smccc ARCH32
In-Reply-To: <1439973629-19505-2-git-send-email-jens.wiklander@linaro.org>
References: <1439973629-19505-1-git-send-email-jens.wiklander@linaro.org>
 <1439973629-19505-2-git-send-email-jens.wiklander@linaro.org>
Message-ID: <20150819165009.GC10297@arm.com>

On Wed, Aug 19, 2015 at 09:40:25AM +0100, Jens Wiklander wrote:
> Adds helpers to do SMC based on ARM SMC Calling Convention.
> CONFIG_HAVE_SMCCC is enabled for architectures that may support
> the SMC instruction. It's the responsibility of the caller to
> know if the SMC instruction is supported by the platform.

[...]
> diff --git a/arch/arm64/kernel/smccc-call.S b/arch/arm64/kernel/smccc-call.S
> new file mode 100644
> index 0000000..3ce7fe8
> --- /dev/null
> +++ b/arch/arm64/kernel/smccc-call.S
> @@ -0,0 +1,34 @@
> +/*
> + * Copyright (c) 2015, Linaro Limited
> + *
> + * 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/linkage.h>
> +
> +#define SMC_PARAM_W0_OFFS      0
> +#define SMC_PARAM_W2_OFFS      8
> +#define SMC_PARAM_W4_OFFS      16
> +#define SMC_PARAM_W6_OFFS      24
> +
> +/* void smccc_call32(struct smccc_param32 *param) */
> +ENTRY(smccc_call32)
> +       stp     x28, x30, [sp, #-16]!

Why are you saving lr?

> +       mov     x28, x0
> +       ldp     w0, w1, [x28, #SMC_PARAM_W0_OFFS]
> +       ldp     w2, w3, [x28, #SMC_PARAM_W2_OFFS]
> +       ldp     w4, w5, [x28, #SMC_PARAM_W4_OFFS]
> +       ldp     w6, w7, [x28, #SMC_PARAM_W6_OFFS]
> +       smc     #0
> +       stp     w0, w1, [x28, #SMC_PARAM_W0_OFFS]
> +       stp     w2, w3, [x28, #SMC_PARAM_W2_OFFS]
> +       ldp     x28, x30, [sp], #16
> +       ret
> +ENDPROC(smccc_call32)

Could we deal with this like we do for PSCI instead? (see
__invoke_psci_fn_smc). We could also then rename psci-call.S to fw-call.S
and stick this in there too.

Will


From vinod.koul at intel.com  Wed Aug 19 09:53:49 2015
From: vinod.koul at intel.com (Vinod Koul)
Date: Wed, 19 Aug 2015 22:23:49 +0530
Subject: [PATCHv4 2/6] dmaengine: mv_xor: add suspend/resume support
In-Reply-To: <20150729113405.2b337ae0@free-electrons.com>
References: <1436365699-6862-1-git-send-email-thomas.petazzoni@free-electrons.com>
 <1436365699-6862-3-git-send-email-thomas.petazzoni@free-electrons.com>
 <20150722051011.GQ23525@localhost>
 <20150729113405.2b337ae0@free-electrons.com>
Message-ID: <20150819165349.GJ13546@localhost>

On Wed, Jul 29, 2015 at 11:34:05AM +0200, Thomas Petazzoni wrote:
> Vinod,
> 
> On Wed, 22 Jul 2015 10:40:11 +0530, Vinod Koul wrote:
> 
> > > +static int mv_xor_suspend(struct platform_device *pdev, pm_message_t state)
> > > +{
> > > +	struct mv_xor_device *xordev = platform_get_drvdata(pdev);
> > > +	int i;
> > > +
> > > +	for (i = 0; i < MV_XOR_MAX_CHANNELS; i++) {
> > > +		struct mv_xor_chan *mv_chan = xordev->channels[i];
> > > +
> > > +		if (!mv_chan)
> > > +			continue;
> > > +
> > > +		mv_chan->saved_config_reg =
> > > +			readl_relaxed(XOR_CONFIG(mv_chan));
> > > +		mv_chan->saved_int_mask_reg =
> > > +			readl_relaxed(XOR_INTR_MASK(mv_chan));
> > this sound fine, but I am missing the suspension of the channel. If a
> > transfer was active while suspend was invoked then how would this work?
> 
> There are indeed no provisions to handle this problem. Does the
> dmaengine framework provide any helpers to ease with this? I have
> quickly looked at other dmaengine drivers, and I haven't seen any of
> them taking care of this problem. Do you have a pointer to a driver
> handling this problem?

Sorry for delay...

Should this be solved at framework level? We should rather suspend the
channels, save the cfg and then restore that on resume.

-- 
~Vinod



From will.deacon at arm.com  Wed Aug 19 09:56:43 2015
From: will.deacon at arm.com (Will Deacon)
Date: Wed, 19 Aug 2015 17:56:43 +0100
Subject: [PATCH] arm64: entry: always restore x0 from the stack on
 syscall return
In-Reply-To: <20150819163504.GL24062@e104818-lin.cambridge.arm.com>
References: <1439996989-5772-1-git-send-email-will.deacon@arm.com>
 <20150819160320.GI24062@e104818-lin.cambridge.arm.com>
 <20150819162359.GA10297@arm.com>
 <20150819163504.GL24062@e104818-lin.cambridge.arm.com>
Message-ID: <20150819165643.GD10297@arm.com>

On Wed, Aug 19, 2015 at 05:35:05PM +0100, Catalin Marinas wrote:
> On Wed, Aug 19, 2015 at 05:23:59PM +0100, Will Deacon wrote:
> > On Wed, Aug 19, 2015 at 05:03:20PM +0100, Catalin Marinas wrote:
> > > There is another str x0 in __sys_trace_return which I think we could
> > > remove.
> > 
> > Hmm, I don't think we can remove that. It's needed on the slowpath to
> > update the pt_regs with either -ENOSYS (for __ni_sys_trace) or the
> > syscall return value from the blr in __sys_trace.
> > 
> > What we can do instead is change the branch above to branch to
> > __sys_trace_return_skipped. Patch below.
> > 
> > Will
> > 
> > --->8
> > 
> > diff --git a/arch/arm64/kernel/entry.S b/arch/arm64/kernel/entry.S
> > index 2a5e64ccc991..088322ff1ba0 100644
> > --- a/arch/arm64/kernel/entry.S
> > +++ b/arch/arm64/kernel/entry.S
> > @@ -619,7 +619,7 @@ ret_fast_syscall:
> >         kernel_exit 0
> >  ret_fast_syscall_trace:
> >         enable_irq                              // enable interrupts
> > -       b       __sys_trace_return
> > +       b       __sys_trace_return_skipped      // we already saved x0
> 
> That would do. With this added:
> 
> Reviewed-by: Catalin Marinas <catalin.marinas at arm.com>
> 
> (or I can take it for 4.2 but I'd like more testing like LTP)

Yeah, I'll run some tests overnight and see how it holds up.

Will


From vinod.koul at intel.com  Wed Aug 19 10:00:45 2015
From: vinod.koul at intel.com (Vinod Koul)
Date: Wed, 19 Aug 2015 22:30:45 +0530
Subject: [PATCHv4 3/6] dmaengine: mv_xor: remove support for dmacap,* DT
 properties
In-Reply-To: <20150727124405.53752fe2@free-electrons.com>
References: <1436365699-6862-1-git-send-email-thomas.petazzoni@free-electrons.com>
 <1436365699-6862-4-git-send-email-thomas.petazzoni@free-electrons.com>
 <20150722051653.GR23525@localhost>
 <20150727124405.53752fe2@free-electrons.com>
Message-ID: <20150819170045.GK13546@localhost>

On Mon, Jul 27, 2015 at 12:44:05PM +0200, Thomas Petazzoni wrote:
> Vinod,
> 
> On Wed, 22 Jul 2015 10:46:53 +0530, Vinod Koul wrote:
> 
> > >  	xor01 {
> > >  	      interrupts = <52>;
> > > -	      dmacap,memcpy;
> > > -	      dmacap,xor;
> > > -	      dmacap,memset;
> > I maybe wrong but there was an assumption that DT properties, even if bad
> > are always there as they need to be treated as kernel ABI.
> > 
> > How will it work if someone has older DT implementation or older driver?
> 
> Supporting a new DT with an old kernel has never been part of the
> requirements of the DT ABI stability.
> 
> Supporting an old DT with a new kernel is the actual requirement. And
> the patch I'm proposing does not break this at all: a new kernel will
> simply ignore those dmacap,* properties from an old DT, and the driver
> automatically knows by itself what are the capabilities of the
> different XOR engines.
> 
> Therefore, there is no backward compatibility issue introduced by this
> patch.

Yes tht is correct

-- 
~Vinod



From vinod.koul at intel.com  Wed Aug 19 10:02:48 2015
From: vinod.koul at intel.com (Vinod Koul)
Date: Wed, 19 Aug 2015 22:32:48 +0530
Subject: [PATCHv4 3/6] dmaengine: mv_xor: remove support for dmacap,* DT
 properties
In-Reply-To: <1436365699-6862-4-git-send-email-thomas.petazzoni@free-electrons.com>
References: <1436365699-6862-1-git-send-email-thomas.petazzoni@free-electrons.com>
 <1436365699-6862-4-git-send-email-thomas.petazzoni@free-electrons.com>
Message-ID: <20150819170248.GL13546@localhost>

On Wed, Jul 08, 2015 at 04:28:16PM +0200, Thomas Petazzoni wrote:
> The only reason why we had dmacap,* properties is because back when
> DMA_MEMSET was supported, only one out of the two channels per engine
> could do a memset operation. But this is something that the driver
> already knows anyway, and since then, the DMA_MEMSET support has been
> removed.
> 
> The driver is already well aware of what each channel supports and the
> one to one mapping between Linux specific implementation details (such
> as dmacap,interrupt enabling DMA_INTERRUPT) and DT properties is a
> good indication that these DT properties are wrong.
> 
> Therefore, this commit simply gets rid of these dmacap,* properties,
> they are now ignored, and the driver is responsible for knowing the
> capabilities of the hardware with regard to the dmaengine subsystem
> expectations.

Applied, thanks

-- 
~Vinod



From vinod.koul at intel.com  Wed Aug 19 10:04:20 2015
From: vinod.koul at intel.com (Vinod Koul)
Date: Wed, 19 Aug 2015 22:34:20 +0530
Subject: [PATCHv4 4/6] dmaengine: mv_xor: remove
 mv_xor_chan->current_type field
In-Reply-To: <1436365699-6862-5-git-send-email-thomas.petazzoni@free-electrons.com>
References: <1436365699-6862-1-git-send-email-thomas.petazzoni@free-electrons.com>
 <1436365699-6862-5-git-send-email-thomas.petazzoni@free-electrons.com>
Message-ID: <20150819170420.GM13546@localhost>

On Wed, Jul 08, 2015 at 04:28:17PM +0200, Thomas Petazzoni wrote:
> Since commit 3e4f52e2da9f6 ("dma: mv_xor: Simplify the DMA_MEMCPY
> operation"), this field is no longer used, so get rid of it.

This one fails to apply, can you pls rebase

-- 
~Vinod



From vinod.koul at intel.com  Wed Aug 19 10:05:04 2015
From: vinod.koul at intel.com (Vinod Koul)
Date: Wed, 19 Aug 2015 22:35:04 +0530
Subject: [PATCHv4 5/6] dmaengine: mv_xor: de-duplicate mv_chan_set_mode*()
In-Reply-To: <1436365699-6862-6-git-send-email-thomas.petazzoni@free-electrons.com>
References: <1436365699-6862-1-git-send-email-thomas.petazzoni@free-electrons.com>
 <1436365699-6862-6-git-send-email-thomas.petazzoni@free-electrons.com>
Message-ID: <20150819170504.GN13546@localhost>

On Wed, Jul 08, 2015 at 04:28:18PM +0200, Thomas Petazzoni wrote:
> When commit 6f166312c6ea2 ("dmaengine: mv_xor: add support for a38x
> command in descriptor mode") added support for the descriptor mode
> available in Marvell Armada 38x and later SoCs, it added a new
> function mv_chan_set_mode_to_desc() which allows to configure a XOR
> channel to get the specific operation to be done from each individual
> DMA descriptor.
> 
> However, this function was mainly a duplicate of the existing
> mv_chan_set_mode(), with just the operation being different.
> 
> This commit re-organizes the code into a single mv_chan_set_mode()
> function, which takes the operation mode as argument, and the
> mv_xor_channel_add() function decides whether to use
> XOR_OPERATION_MODE_IN_DESC or XOR_OPERATION_MODE_XOR.

This one as well

-- 
~Vinod



From vinod.koul at intel.com  Wed Aug 19 10:05:26 2015
From: vinod.koul at intel.com (Vinod Koul)
Date: Wed, 19 Aug 2015 22:35:26 +0530
Subject: [PATCHv4 6/6] dmaengine: mv_xor: optimize performance by using a
 subset of the XOR channels
In-Reply-To: <1436365699-6862-7-git-send-email-thomas.petazzoni@free-electrons.com>
References: <1436365699-6862-1-git-send-email-thomas.petazzoni@free-electrons.com>
 <1436365699-6862-7-git-send-email-thomas.petazzoni@free-electrons.com>
Message-ID: <20150819170526.GO13546@localhost>

On Wed, Jul 08, 2015 at 04:28:19PM +0200, Thomas Petazzoni wrote:
> Due to how async_tx behaves internally, having more XOR channels than
> CPUs is actually hurting performance more than it improves it, because
> memcpy requests get scheduled on a different channel than the XOR
> requests, but async_tx will still wait for the completion of the
> memcpy requests before scheduling the XOR requests.
> 
> It is in fact more efficient to have at most one channel per CPU,
> which this patch implements by limiting the number of channels per
> engine, and the number of engines registered depending on the number
> of availables CPUs.
> 
> Marvell platforms are currently available in one CPU, two CPUs and
> four CPUs configurations:
> 
>  - in the configurations with one CPU, only one channel from one
>    engine is used.
> 
>  - in the configurations with two CPUs, only one channel from each
>    engine is used (they are two XOR engines)
> 
>  - in the configurations with four CPUs, both channels of both engines
>    are used.

Applied, thanks

-- 
~Vinod



From broonie at kernel.org  Wed Aug 19 10:26:26 2015
From: broonie at kernel.org (Mark Brown)
Date: Wed, 19 Aug 2015 10:26:26 -0700
Subject: [PATCH 3/3] spi: mediatek: fix spi incorrect endian usage
In-Reply-To: <1439955478-2733-4-git-send-email-leilk.liu@mediatek.com>
References: <1439955478-2733-1-git-send-email-leilk.liu@mediatek.com>
 <1439955478-2733-4-git-send-email-leilk.liu@mediatek.com>
Message-ID: <20150819172626.GV10748@sirena.org.uk>

On Wed, Aug 19, 2015 at 11:37:58AM +0800, Leilk Liu wrote:
> TX_ENDIAN/RX_ENDIAN bits define whether to reverse the endian
> order of the data DMA from/to memory. The endian order should
> keep the same with cpu endian.

This doesn't apply, probably because it depends on your stylistic
changes patch - this is an example of the issues I was mentioning with
stylistic changes getting in the waty of fixes :(
-------------- next part --------------
A non-text attachment was scrubbed...
Name: signature.asc
Type: application/pgp-signature
Size: 473 bytes
Desc: Digital signature
URL: <http://lists.infradead.org/pipermail/linux-arm-kernel/attachments/20150819/a89cb2d0/attachment.sig>

From christoffer.dall at linaro.org  Wed Aug 19 10:49:58 2015
From: christoffer.dall at linaro.org (Christoffer Dall)
Date: Wed, 19 Aug 2015 19:49:58 +0200
Subject: [PATCH v4 1/2] arm64: KVM: Optimize arm64 skip 30-50% vfp/simd
 save/restore on exits
In-Reply-To: <55C235B9.3000800@arm.com>
References: <1437082178-11039-1-git-send-email-m.smarduch@samsung.com>
 <1437082178-11039-2-git-send-email-m.smarduch@samsung.com>
 <55C235B9.3000800@arm.com>
Message-ID: <20150819174958.GA11518@cbox>

Hi Mario,

On Wed, Aug 05, 2015 at 05:11:37PM +0100, Marc Zyngier wrote:
> On 16/07/15 22:29, Mario Smarduch wrote:
> > This patch only saves and restores FP/SIMD registers on Guest access. To do
> > this cptr_el2 FP/SIMD trap is set on Guest entry and later checked on exit.
> > lmbench, hackbench show significant improvements, for 30-50% exits FP/SIMD
> > context is not saved/restored
> > 
> > Signed-off-by: Mario Smarduch <m.smarduch at samsung.com>
> 
> So this patch seems to break 32bit guests on arm64.  I've had a look,
> squashed a few bugs that I dangerously overlooked during the review, but
> it still doesn't work (it doesn't crash anymore, but I get random
> illegal VFP instructions in 32bit guests).
> 
> I'd be glad if someone could eyeball the following patch and tell me
> what's going wrong. If we don't find the root cause quickly enough, I'll
> have to drop the series from -next, and that'd be a real shame.
> 
> Thanks,
> 
> 	M.
> 
> commit 5777dc55fbc170426a85e00c26002dd5a795cfa5
> Author: Marc Zyngier <marc.zyngier at arm.com>
> Date:   Wed Aug 5 16:53:01 2015 +0100
> 
>     KVM: arm64: NOTAFIX: Prevent crash when 32bit guest uses VFP
> 
>     Since we switch FPSIMD in a lazy way, access to FPEXC32_EL2
>     must be guarded by skip_fpsimd_state. Otherwise, all hell
>     break loose.
> 
>     Also, FPEXC32_EL2 must be restored when we trap to EL2 to
>     enable floating point.
> 
>     Note that while it prevents the host from catching fire, the
>     guest still doesn't work properly, and I don't understand why just
>     yet.
> 
>     Not-really-signed-off-by: Marc Zyngier <marc.zyngier at arm.com>
> 
> diff --git a/arch/arm64/kvm/hyp.S b/arch/arm64/kvm/hyp.S
> index c8e0c70..b53ec5d 100644
> --- a/arch/arm64/kvm/hyp.S
> +++ b/arch/arm64/kvm/hyp.S
> @@ -431,10 +431,12 @@
>  	add	x3, x2, #CPU_SYSREG_OFFSET(DACR32_EL2)
>  	mrs	x4, dacr32_el2
>  	mrs	x5, ifsr32_el2
> -	mrs	x6, fpexc32_el2
>  	stp	x4, x5, [x3]
> -	str	x6, [x3, #16]
> 
> +	skip_fpsimd_state x8, 3f
> +	mrs	x6, fpexc32_el2
> +	str	x6, [x3, #16]
> +3:
>  	skip_debug_state x8, 2f
>  	mrs	x7, dbgvcr32_el2
>  	str	x7, [x3, #24]
> @@ -461,10 +463,8 @@
> 
>  	add	x3, x2, #CPU_SYSREG_OFFSET(DACR32_EL2)
>  	ldp	x4, x5, [x3]
> -	ldr	x6, [x3, #16]
>  	msr	dacr32_el2, x4
>  	msr	ifsr32_el2, x5
> -	msr	fpexc32_el2, x6
> 
>  	skip_debug_state x8, 2f
>  	ldr	x7, [x3, #24]
> @@ -669,12 +669,14 @@ __restore_debug:
>  	ret
> 
>  __save_fpsimd:
> +	skip_fpsimd_state x3, 1f
>  	save_fpsimd
> -	ret
> +1:	ret
> 
>  __restore_fpsimd:
> +	skip_fpsimd_state x3, 1f
>  	restore_fpsimd
> -	ret
> +1:	ret
> 
>  switch_to_guest_fpsimd:
>  	push	x4, lr
> @@ -682,6 +684,7 @@ switch_to_guest_fpsimd:
>  	mrs	x2, cptr_el2
>  	bic	x2, x2, #CPTR_EL2_TFP
>  	msr	cptr_el2, x2
> +	isb
> 
>  	mrs	x0, tpidr_el2
> 
> @@ -692,6 +695,10 @@ switch_to_guest_fpsimd:
>  	add	x2, x0, #VCPU_CONTEXT
>  	bl __restore_fpsimd
> 
> +	skip_32bit_state x3, 1f
> +	ldr	x4, [x2, #CPU_SYSREG_OFFSET(FPEXC32_EL2)]
> +	msr	fpexc32_el2, x4
> +1:
>  	pop	x4, lr
>  	pop	x2, x3
>  	pop	x0, x1
> @@ -754,9 +761,7 @@ __kvm_vcpu_return:
>  	add	x2, x0, #VCPU_CONTEXT
> 
>  	save_guest_regs
> -	skip_fpsimd_state x3, 1f
>  	bl __save_fpsimd
> -1:
>  	bl __save_sysregs
> 
>  	skip_debug_state x3, 1f
> @@ -777,9 +782,7 @@ __kvm_vcpu_return:
>  	kern_hyp_va x2
> 
>  	bl __restore_sysregs
> -	skip_fpsimd_state x3, 1f
>  	bl __restore_fpsimd
> -1:
>  	/* Clear FPSIMD and Trace trapping */
>  	msr     cptr_el2, xzr
> 
> 

Marc and I have hunted down the issue at KVM Forum and we believe we've
found the issue.  Please have a look at the following follow-up patch to
Marc's patch above:

diff --git a/arch/arm64/kvm/hyp.S b/arch/arm64/kvm/hyp.S
index 8b2a73b4..842e727 100644
--- a/arch/arm64/kvm/hyp.S
+++ b/arch/arm64/kvm/hyp.S
@@ -769,11 +769,26 @@
 
 .macro activate_traps
 	ldr     x2, [x0, #VCPU_HCR_EL2]
+
+	/*
+	 * We are about to set CPTR_EL2.TFP to trap all floating point
+	 * register accesses to EL2, however, the ARM ARM clearly states that
+	 * traps are only taken to EL2 if the operation would not otherwise
+	 * trap to EL1.  Therefore, always make sure that for 32-bit guests,
+	 * we set FPEXC.EN to prevent traps to EL1, when setting the TFP bit.
+	 */
+	tbnz	x2, #HCR_RW_SHIFT, 99f // open code skip_32bit_state
+	mov	x3, #(1 << 30)
+	msr	fpexc32_el2, x3
+	isb
+99:
+
 	msr     hcr_el2, x2
 	mov	x2, #CPTR_EL2_TTA
 	orr     x2, x2, #CPTR_EL2_TFP
 	msr	cptr_el2, x2
 
+
 	mov	x2, #(1 << 15)	// Trap CP15 Cr=15
 	msr	hstr_el2, x2
 


Thanks,
-Christoffer


From broonie at kernel.org  Wed Aug 19 09:53:16 2015
From: broonie at kernel.org (Mark Brown)
Date: Wed, 19 Aug 2015 09:53:16 -0700
Subject: [PATCH 1/3] spi: mediatek: revise coding style
In-Reply-To: <1439955478-2733-2-git-send-email-leilk.liu@mediatek.com>
References: <1439955478-2733-1-git-send-email-leilk.liu@mediatek.com>
 <1439955478-2733-2-git-send-email-leilk.liu@mediatek.com>
Message-ID: <20150819165316.GU10748@sirena.org.uk>

On Wed, Aug 19, 2015 at 11:37:56AM +0800, Leilk Liu wrote:
> This patch revises mediatek spi driver coding styles.

Two problems here.  One is that it's best practice to make purely
stylistic changes after any substantial ones, that way people can pick
up bug fixes without needing the stylistic changes.  The other is that
this just isn't an adequate changelog - what are the revisions that are
being made to the coding style and why are they being made?  This is a
very large change and there seem to be many different and unrelated
changes being made here.
-------------- next part --------------
A non-text attachment was scrubbed...
Name: signature.asc
Type: application/pgp-signature
Size: 473 bytes
Desc: Digital signature
URL: <http://lists.infradead.org/pipermail/linux-arm-kernel/attachments/20150819/946a63f0/attachment-0001.sig>

From mathieu at codeaurora.org  Wed Aug 19 10:53:21 2015
From: mathieu at codeaurora.org (Mathieu Olivari)
Date: Wed, 19 Aug 2015 10:53:21 -0700
Subject: [PATCH 1/2] ARM: qcom: add mdio bus on IPQ806x/AP148
Message-ID: <1440006802-2415-1-git-send-email-mathieu@codeaurora.org>

Ethernet switch on AP148 is connected through MDIO using GPIO 0 and 1.
We'll add the new node using the bitbang driver on these two pins.

Signed-off-by: Mathieu Olivari <mathieu at codeaurora.org>
---
 arch/arm/boot/dts/qcom-ipq8064-ap148.dts | 31 ++++++++++++++++++++++++++++++-
 1 file changed, 30 insertions(+), 1 deletion(-)

diff --git a/arch/arm/boot/dts/qcom-ipq8064-ap148.dts b/arch/arm/boot/dts/qcom-ipq8064-ap148.dts
index 6886d09..d73df24 100644
--- a/arch/arm/boot/dts/qcom-ipq8064-ap148.dts
+++ b/arch/arm/boot/dts/qcom-ipq8064-ap148.dts
@@ -19,8 +19,9 @@
 		};
 	};
 
-	alias {
+	aliases {
 		serial0 = &uart4;
+		mdio-gpio0 = &mdio0;
 	};
 
 	chosen {
@@ -84,6 +85,15 @@
 					};
 				};
 			};
+
+			mdio0_pins: mdio0_pins {
+				mux {
+					pins = "gpio0", "gpio1";
+					function = "gpio";
+					drive-strength = <8>;
+					bias-disable;
+				};
+			};
 		};
 
 		sata-phy at 1b400000 {
@@ -93,5 +103,24 @@
 		sata at 29000000 {
 			status = "ok";
 		};
+
+		mdio0: mdio {
+			compatible = "virtual,mdio-gpio";
+			#address-cells = <1>;
+			#size-cells = <0>;
+			gpios = <&qcom_pinmux 1 0 &qcom_pinmux 0 0>;
+			pinctrl-0 = <&mdio0_pins>;
+			pinctrl-names = "default";
+
+			phy0: ethernet-phy at 0 {
+				device_type = "ethernet-phy";
+				reg = <0>;
+			};
+
+			phy4: ethernet-phy at 4 {
+				device_type = "ethernet-phy";
+				reg = <4>;
+			};
+		};
 	};
 };
-- 
2.1.4



From mathieu at codeaurora.org  Wed Aug 19 10:53:22 2015
From: mathieu at codeaurora.org (Mathieu Olivari)
Date: Wed, 19 Aug 2015 10:53:22 -0700
Subject: [PATCH 2/2] ARM: qcom: add GMAC nodes to IPQ806x platforms
In-Reply-To: <1440006802-2415-1-git-send-email-mathieu@codeaurora.org>
References: <1440006802-2415-1-git-send-email-mathieu@codeaurora.org>
Message-ID: <1440006802-2415-2-git-send-email-mathieu@codeaurora.org>

This change adds GMAC nodes to IPQ806x platforms, both to the dtsi and
to the AP148 dts. This will provide ethernet connectivity to the device.

Signed-off-by: Mathieu Olivari <mathieu at codeaurora.org>
---
 arch/arm/boot/dts/qcom-ipq8064-ap148.dts | 33 ++++++++++++
 arch/arm/boot/dts/qcom-ipq8064.dtsi      | 86 ++++++++++++++++++++++++++++++++
 2 files changed, 119 insertions(+)

diff --git a/arch/arm/boot/dts/qcom-ipq8064-ap148.dts b/arch/arm/boot/dts/qcom-ipq8064-ap148.dts
index d73df24..0958fa3 100644
--- a/arch/arm/boot/dts/qcom-ipq8064-ap148.dts
+++ b/arch/arm/boot/dts/qcom-ipq8064-ap148.dts
@@ -94,6 +94,18 @@
 					bias-disable;
 				};
 			};
+
+			rgmii2_pins: rgmii2_pins {
+				mux {
+					pins = "gpio27", "gpio28", "gpio29",
+					       "gpio30", "gpio31", "gpio32",
+					       "gpio51", "gpio52", "gpio59",
+					       "gpio60", "gpio61", "gpio62";
+					function = "rgmii2";
+					drive-strength = <8>;
+					bias-disable;
+				};
+			};
 		};
 
 		sata-phy at 1b400000 {
@@ -122,5 +134,26 @@
 				reg = <4>;
 			};
 		};
+
+		gmac1: ethernet at 37200000 {
+			status = "ok";
+			phy-mode = "rgmii";
+			phy-handle = <&phy4>;
+			qcom,id = <1>;
+
+			pinctrl-0 = <&rgmii2_pins>;
+			pinctrl-names = "default";
+		};
+
+		gmac2: ethernet at 37400000 {
+			status = "ok";
+			phy-mode = "sgmii";
+			qcom,id = <2>;
+
+			fixed-link {
+				speed = <1000>;
+				full-duplex;
+			};
+		};
 	};
 };
diff --git a/arch/arm/boot/dts/qcom-ipq8064.dtsi b/arch/arm/boot/dts/qcom-ipq8064.dtsi
index 2f270d7..6706a56 100644
--- a/arch/arm/boot/dts/qcom-ipq8064.dtsi
+++ b/arch/arm/boot/dts/qcom-ipq8064.dtsi
@@ -336,6 +336,92 @@
 			compatible = "syscon";
 			reg = <0x01200600 0x100>;
 		};
+
+		nss_common: syscon at 03000000 {
+			compatible = "syscon";
+			reg = <0x03000000 0x0000FFFF>;
+		};
+
+		qsgmii_csr: syscon at 1bb00000 {
+			compatible = "syscon";
+			reg = <0x1bb00000 0x000001FF>;
+		};
+
+		gmac0: ethernet at 37000000 {
+			device_type = "network";
+			compatible = "qcom,ipq806x-gmac";
+			reg = <0x37000000 0x200000>;
+			interrupts = <GIC_SPI 220 IRQ_TYPE_LEVEL_HIGH>;
+			interrupt-names = "macirq";
+
+			qcom,nss-common = <&nss_common>;
+			qcom,qsgmii-csr = <&qsgmii_csr>;
+
+			clocks = <&gcc GMAC_CORE1_CLK>;
+			clock-names = "stmmaceth";
+
+			resets = <&gcc GMAC_CORE1_RESET>;
+			reset-names = "stmmaceth";
+
+			status = "disabled";
+		};
+
+		gmac1: ethernet at 37200000 {
+			device_type = "network";
+			compatible = "qcom,ipq806x-gmac";
+			reg = <0x37200000 0x200000>;
+			interrupts = <GIC_SPI 223 IRQ_TYPE_LEVEL_HIGH>;
+			interrupt-names = "macirq";
+
+			qcom,nss-common = <&nss_common>;
+			qcom,qsgmii-csr = <&qsgmii_csr>;
+
+			clocks = <&gcc GMAC_CORE2_CLK>;
+			clock-names = "stmmaceth";
+
+			resets = <&gcc GMAC_CORE2_RESET>;
+			reset-names = "stmmaceth";
+
+			status = "disabled";
+		};
+
+		gmac2: ethernet at 37400000 {
+			device_type = "network";
+			compatible = "qcom,ipq806x-gmac";
+			reg = <0x37400000 0x200000>;
+			interrupts = <GIC_SPI 226 IRQ_TYPE_LEVEL_HIGH>;
+			interrupt-names = "macirq";
+
+			qcom,nss-common = <&nss_common>;
+			qcom,qsgmii-csr = <&qsgmii_csr>;
+
+			clocks = <&gcc GMAC_CORE3_CLK>;
+			clock-names = "stmmaceth";
+
+			resets = <&gcc GMAC_CORE3_RESET>;
+			reset-names = "stmmaceth";
+
+			status = "disabled";
+		};
+
+		gmac3: ethernet at 37600000 {
+			device_type = "network";
+			compatible = "qcom,ipq806x-gmac";
+			reg = <0x37600000 0x200000>;
+			interrupts = <GIC_SPI 229 IRQ_TYPE_LEVEL_HIGH>;
+			interrupt-names = "macirq";
+
+			qcom,nss-common = <&nss_common>;
+			qcom,qsgmii-csr = <&qsgmii_csr>;
+
+			clocks = <&gcc GMAC_CORE4_CLK>;
+			clock-names = "stmmaceth";
+
+			resets = <&gcc GMAC_CORE4_RESET>;
+			reset-names = "stmmaceth";
+
+			status = "disabled";
+		};
 	};
 
 	sfpb_mutex: sfpb-mutex {
-- 
2.1.4



From olof at lixom.net  Wed Aug 19 10:55:37 2015
From: olof at lixom.net (Olof Johansson)
Date: Wed, 19 Aug 2015 10:55:37 -0700
Subject: [GIT PULL 1/3] ARM: imx: soc updates for 4.3
In-Reply-To: <20150818201416.GA4732@localhost>
References: <1439311351-5268-1-git-send-email-shawnguo@kernel.org>
 <20150818201416.GA4732@localhost>
Message-ID: <CAOesGMg_TocMprCDQK69CTLtnyiyf4hn_hEzWoEhdKsXH3OuBw@mail.gmail.com>

Hi Shawn,

On Tue, Aug 18, 2015 at 1:14 PM, Olof Johansson <olof at lixom.net> wrote:
> Hi,
>
> On Wed, Aug 12, 2015 at 12:42:29AM +0800, Shawn Guo wrote:
>> Hi arm-soc maintainers,
>>
>> This is the i.MX SoC changes for 4.3.  There are some input and rtc
>> changes, because they are applied as a series.  Subsystem maintainers
>> have ACKed these changes, so it should be fine to send them via arm-soc
>> tree.
>
> In some of these cases, may I ask why? For example, the RTC changes look
> like they could just go in through the driver tree -- adding DT support to
> a driver can definitely do so (and the DT changes to plumb up the device can go
> through your DT branch).
>
>> The following changes since commit d770e558e21961ad6cfdf0ff7df0eb5d7d4f0754:
>>
>>   Linux 4.2-rc1 (2015-07-05 11:01:52 -0700)
>>
>> are available in the git repository at:
>>
>>   git://git.kernel.org/pub/scm/linux/kernel/git/shawnguo/linux.git tags/imx-soc-4.3
>>
>> for you to fetch changes up to 8a0fa1843638c5078e6606114ed8bdf9ea56fab1:
>>
>>   rtc: snvs: select option REGMAP_MMIO (2015-08-11 23:04:47 +0800)
>
> I've merged this, and we can merge acked drivers in the future too if needed,
> but ideally only where it's needed.

It looks like these changes broke ARM allmodconfig:

arch/arm/mach-imx/built-in.o: In function `ksz8081_phy_fixup':
:(.text+0x8bcc): undefined reference to `mdiobus_write'
:(.text+0x8bf0): undefined reference to `mdiobus_write'
:(.text+0x8c28): undefined reference to `mdiobus_write'
:(.text+0x8c4c): undefined reference to `mdiobus_write'
arch/arm/mach-imx/built-in.o: In function `imx6ul_init_machine':
:(.init.text+0xa714): undefined reference to `phy_register_fixup_for_uid'

Whole output is at:

http://arm-soc.lixom.net/buildlogs/arm-soc/v4.2-rc2-861-gdb5c5fd/buildall.arm.allmodconfig.log.failed

Please send an incremental fix (or I can drop this branch if you need
more time).

Thanks!


-Olof


From festevam at gmail.com  Wed Aug 19 11:17:27 2015
From: festevam at gmail.com (Fabio Estevam)
Date: Wed, 19 Aug 2015 15:17:27 -0300
Subject: [GIT PULL 1/3] ARM: imx: soc updates for 4.3
In-Reply-To: <CAOesGMg_TocMprCDQK69CTLtnyiyf4hn_hEzWoEhdKsXH3OuBw@mail.gmail.com>
References: <1439311351-5268-1-git-send-email-shawnguo@kernel.org>
 <20150818201416.GA4732@localhost>
 <CAOesGMg_TocMprCDQK69CTLtnyiyf4hn_hEzWoEhdKsXH3OuBw@mail.gmail.com>
Message-ID: <CAOMZO5AL2iFJSpSukcV44Y=JZecRrm0sCRZQgyTM6w8_R6OHqw@mail.gmail.com>

Hi Olof,

On Wed, Aug 19, 2015 at 2:55 PM, Olof Johansson <olof at lixom.net> wrote:

> It looks like these changes broke ARM allmodconfig:
>
> arch/arm/mach-imx/built-in.o: In function `ksz8081_phy_fixup':
> :(.text+0x8bcc): undefined reference to `mdiobus_write'
> :(.text+0x8bf0): undefined reference to `mdiobus_write'
> :(.text+0x8c28): undefined reference to `mdiobus_write'
> :(.text+0x8c4c): undefined reference to `mdiobus_write'
> arch/arm/mach-imx/built-in.o: In function `imx6ul_init_machine':
> :(.init.text+0xa714): undefined reference to `phy_register_fixup_for_uid'
>
> Whole output is at:
>
> http://arm-soc.lixom.net/buildlogs/arm-soc/v4.2-rc2-861-gdb5c5fd/buildall.arm.allmodconfig.log.failed
>
> Please send an incremental fix (or I can drop this branch if you need
> more time).

Does this fix it?

--- a/arch/arm/mach-imx/mach-imx6ul.c
+++ b/arch/arm/mach-imx/mach-imx6ul.c
@@ -45,7 +45,9 @@ static int ksz8081_phy_fixup(struct phy_device *dev)

 static void __init imx6ul_enet_phy_init(void)
 {
-       phy_register_fixup_for_uid(PHY_ID_KSZ8081, 0xffffffff,
ksz8081_phy_fixup);
+       if (IS_BUILTIN(CONFIG_PHYLIB))
+               phy_register_fixup_for_uid(PHY_ID_KSZ8081, 0xffffffff,
+                                          ksz8081_phy_fixup);
 }


From moritz.fischer at ettus.com  Wed Aug 19 11:19:48 2015
From: moritz.fischer at ettus.com (Moritz Fischer)
Date: Wed, 19 Aug 2015 11:19:48 -0700
Subject: [PATCH v3 2/2] drivers: rtc: add xilinx zynqmp rtc driver
In-Reply-To: <1439978002-12157-2-git-send-email-suneel.garapati@xilinx.com>
References: <1439978002-12157-1-git-send-email-suneel.garapati@xilinx.com>
 <1439978002-12157-2-git-send-email-suneel.garapati@xilinx.com>
Message-ID: <CAAtXAHf7Vngo8gz6cCRauxUSnrQgs4+UNGWpQ6wy0fvBPMQO_A@mail.gmail.com>

Hi Suneel,

looks good, minor nit below.

On Wed, Aug 19, 2015 at 2:53 AM, Suneel Garapati
<suneel.garapati at xilinx.com> wrote:
> adds support for RTC controller found on
> Xilinx Zynq Ultrascale+ MPSoC platform.
>
> Signed-off-by: Suneel Garapati <suneel.garapati at xilinx.com>
> ---
> Changes v3
> - fix checkpatch errors
> - check time in secs arg against max sec val
> - order header files
> - use ptr_err_or_zero macro
> - use time64 variants
> Changes v2
> - change alm to alarm
> ---
>  drivers/rtc/Kconfig      |   7 ++
>  drivers/rtc/Makefile     |   1 +
>  drivers/rtc/rtc-zynqmp.c | 279 +++++++++++++++++++++++++++++++++++++++++++++++
>  3 files changed, 287 insertions(+)
>  create mode 100644 drivers/rtc/rtc-zynqmp.c
>
> diff --git a/drivers/rtc/Kconfig b/drivers/rtc/Kconfig
> index 35ea04c..bc96277 100644
> --- a/drivers/rtc/Kconfig
> +++ b/drivers/rtc/Kconfig
> @@ -1116,6 +1116,13 @@ config RTC_DRV_OPAL
>           This driver can also be built as a module. If so, the module
>           will be called rtc-opal.
>
> +config RTC_DRV_ZYNQMP
> +       tristate "Xilinx Zynq Ultrascale+ MPSoC RTC"
> +       depends on OF
> +       help
> +         If you say yes here you get support for the RTC controller found on
> +         Xilinx Zynq Ultrascale+ MPSoC.
> +
>  comment "on-CPU RTC drivers"
>
>  config RTC_DRV_DAVINCI
> diff --git a/drivers/rtc/Makefile b/drivers/rtc/Makefile
> index 2797384..e491eb5 100644
> --- a/drivers/rtc/Makefile
> +++ b/drivers/rtc/Makefile
> @@ -159,3 +159,4 @@ obj-$(CONFIG_RTC_DRV_WM831X)        += rtc-wm831x.o
>  obj-$(CONFIG_RTC_DRV_WM8350)   += rtc-wm8350.o
>  obj-$(CONFIG_RTC_DRV_X1205)    += rtc-x1205.o
>  obj-$(CONFIG_RTC_DRV_XGENE)    += rtc-xgene.o
> +obj-$(CONFIG_RTC_DRV_ZYNQMP)   += rtc-zynqmp.o
> diff --git a/drivers/rtc/rtc-zynqmp.c b/drivers/rtc/rtc-zynqmp.c
> new file mode 100644
> index 0000000..8b28762
> --- /dev/null
> +++ b/drivers/rtc/rtc-zynqmp.c
> @@ -0,0 +1,279 @@
> +/*
> + * Xilinx Zynq Ultrascale+ MPSoC Real Time Clock Driver
> + *
> + * Copyright (C) 2015 Xilinx, Inc.
> + *
> + * This program is free software; you can redistribute it and/or modify it
> + * under the terms and conditions of the GNU General Public License,
> + * version 2, as published by the Free Software Foundation.
> + *
> + * This program is distributed in the hope 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.
> + *
> + * You should have received a copy of the GNU General Public License along with
> + * this program. If not, see <http://www.gnu.org/licenses/>.
> + *
> + */
> +
> +#include <linux/delay.h>
> +#include <linux/init.h>
> +#include <linux/io.h>
> +#include <linux/module.h>
> +#include <linux/of.h>
> +#include <linux/platform_device.h>
> +#include <linux/rtc.h>
> +
> +/* RTC Registers */
> +#define RTC_SET_TM_WR          0x00
> +#define RTC_SET_TM_RD          0x04
> +#define RTC_CALIB_WR           0x08
> +#define RTC_CALIB_RD           0x0C
> +#define RTC_CUR_TM             0x10
> +#define RTC_CUR_TICK           0x14
> +#define RTC_ALRM               0x18
> +#define RTC_INT_STS            0x20
> +#define RTC_INT_MASK           0x24
> +#define RTC_INT_EN             0x28
> +#define RTC_INT_DIS            0x2C
> +#define RTC_CTRL               0x40
> +
> +#define RTC_FR_EN              BIT(20)
> +#define RTC_FR_DATSHIFT                16
> +#define RTC_TICK_MASK          0xFFFF
> +#define RTC_INT_SEC            BIT(0)
> +#define RTC_INT_ALRM           BIT(1)
> +#define RTC_OSC_EN             BIT(24)
> +
> +#define RTC_CALIB_DEF          0x198233
> +#define RTC_CALIB_MASK         0x1FFFFF
> +#define RTC_SEC_MAX_VAL                0xFFFFFFFF
> +
> +struct xlnx_rtc_dev {
> +       struct rtc_device       *rtc;
> +       void __iomem            *reg_base;
> +       int                     alarm_irq;
> +       int                     sec_irq;
> +};
> +
> +static int xlnx_rtc_set_time(struct device *dev, struct rtc_time *tm)
> +{
> +       struct xlnx_rtc_dev *xrtcdev = dev_get_drvdata(dev);
> +       unsigned long new_time;
> +
> +       new_time = rtc_tm_to_time64(tm);
> +
> +       if (new_time > RTC_SEC_MAX_VAL)
> +               return -EINVAL;
> +
> +       writel(new_time, xrtcdev->reg_base + RTC_SET_TM_WR);
> +
> +       return 0;
> +}
> +
> +static int xlnx_rtc_read_time(struct device *dev, struct rtc_time *tm)
> +{
> +       struct xlnx_rtc_dev *xrtcdev = dev_get_drvdata(dev);
> +
> +       rtc_time64_to_tm(readl(xrtcdev->reg_base + RTC_CUR_TM), tm);
> +
> +       return rtc_valid_tm(tm);
> +}
> +
> +static int xlnx_rtc_read_alarm(struct device *dev, struct rtc_wkalrm *alrm)
> +{
> +       struct xlnx_rtc_dev *xrtcdev = dev_get_drvdata(dev);
> +
> +       rtc_time64_to_tm(readl(xrtcdev->reg_base + RTC_ALRM), &alrm->time);
> +       alrm->enabled = readl(xrtcdev->reg_base + RTC_INT_MASK) & RTC_INT_ALRM;
> +
> +       return 0;
> +}
> +
> +static int xlnx_rtc_alarm_irq_enable(struct device *dev, u32 enabled)
> +{
> +       struct xlnx_rtc_dev *xrtcdev = dev_get_drvdata(dev);
> +
> +       if (enabled)
> +               writel(RTC_INT_ALRM, xrtcdev->reg_base + RTC_INT_EN);
> +       else
> +               writel(RTC_INT_ALRM, xrtcdev->reg_base + RTC_INT_DIS);
> +
> +       return 0;
> +}
> +
> +static int xlnx_rtc_set_alarm(struct device *dev, struct rtc_wkalrm *alrm)
> +{
> +       struct xlnx_rtc_dev *xrtcdev = dev_get_drvdata(dev);
> +       unsigned long alarm_time;
> +
> +       alarm_time = rtc_tm_to_time64(&alrm->time);
> +
> +       if (alarm_time > RTC_SEC_MAX_VAL)
> +               return -EINVAL;
> +
> +       writel((u32)alarm_time, (xrtcdev->reg_base + RTC_ALRM));
> +
> +       xlnx_rtc_alarm_irq_enable(dev, alrm->enabled);
> +
> +       return 0;
> +}
> +
> +static void xlnx_init_rtc(struct xlnx_rtc_dev *xrtcdev, u32 calibval)
> +{
> +       /*
> +        * Based on crystal freq of 33.330 KHz
> +        * set the seconds counter and enable, set fractions counter
> +        * to default value suggested as per design spec
> +        * to correct RTC delay in frequency over period of time.
> +        */
> +       calibval &= RTC_CALIB_MASK;
> +       writel(calibval, (xrtcdev->reg_base + RTC_CALIB_WR));
> +}
> +
> +static const struct rtc_class_ops xlnx_rtc_ops = {
> +       .set_time         = xlnx_rtc_set_time,
> +       .read_time        = xlnx_rtc_read_time,
> +       .read_alarm       = xlnx_rtc_read_alarm,
> +       .set_alarm        = xlnx_rtc_set_alarm,
> +       .alarm_irq_enable = xlnx_rtc_alarm_irq_enable,
> +};
> +
> +static irqreturn_t xlnx_rtc_interrupt(int irq, void *id)
> +{
> +       struct xlnx_rtc_dev *xrtcdev = (struct xlnx_rtc_dev *)id;
> +       unsigned int status;
> +
> +       status = readl(xrtcdev->reg_base + RTC_INT_STS);
> +       /* Check if interrupt asserted */
> +       if (!(status & (RTC_INT_SEC | RTC_INT_ALRM)))
> +               return IRQ_NONE;
> +
> +       /* Clear interrupt */
> +       writel(status, xrtcdev->reg_base + RTC_INT_STS);
> +
> +       if (status & RTC_INT_SEC)
> +               rtc_update_irq(xrtcdev->rtc, 1, RTC_IRQF | RTC_UF);
> +       if (status & RTC_INT_ALRM)
> +               rtc_update_irq(xrtcdev->rtc, 1, RTC_IRQF | RTC_AF);
> +
> +       return IRQ_HANDLED;
> +}
> +
> +static int xlnx_rtc_probe(struct platform_device *pdev)
> +{
> +       struct xlnx_rtc_dev *xrtcdev;
> +       struct resource *res;
> +       int ret;
> +       unsigned int calibvalue;
> +
> +       xrtcdev = devm_kzalloc(&pdev->dev, sizeof(*xrtcdev), GFP_KERNEL);
> +       if (!xrtcdev)
> +               return -ENOMEM;
> +
> +       platform_set_drvdata(pdev, xrtcdev);
> +
> +       res = platform_get_resource(pdev, IORESOURCE_MEM, 0);
Do you want to check for return value here?
> +
> +       xrtcdev->reg_base = devm_ioremap_resource(&pdev->dev, res);
> +       if (IS_ERR(xrtcdev->reg_base))
> +               return PTR_ERR(xrtcdev->reg_base);
> +
> +       xrtcdev->alarm_irq = platform_get_irq_byname(pdev, "alarm");
> +       if (xrtcdev->alarm_irq < 0) {
> +               dev_err(&pdev->dev, "no irq resource\n");
> +               return xrtcdev->alarm_irq;
> +       }
> +       ret = devm_request_irq(&pdev->dev, xrtcdev->alarm_irq,
> +                              xlnx_rtc_interrupt, 0,
> +                              dev_name(&pdev->dev), xrtcdev);
> +       if (ret) {
> +               dev_err(&pdev->dev, "request irq failed\n");
> +               return ret;
> +       }
> +
> +       xrtcdev->sec_irq = platform_get_irq_byname(pdev, "sec");
> +       if (xrtcdev->sec_irq < 0) {
> +               dev_err(&pdev->dev, "no irq resource\n");
> +               return xrtcdev->sec_irq;
> +       }
> +       ret = devm_request_irq(&pdev->dev, xrtcdev->sec_irq,
> +                              xlnx_rtc_interrupt, 0,
> +                              dev_name(&pdev->dev), xrtcdev);
> +       if (ret) {
> +               dev_err(&pdev->dev, "request irq failed\n");
> +               return ret;
> +       }
> +
> +       ret = of_property_read_u32(pdev->dev.of_node, "calibration",
> +                                  &calibvalue);
> +       if (ret)
> +               calibvalue = RTC_CALIB_DEF;
> +
> +       xlnx_init_rtc(xrtcdev, calibvalue);
> +
> +       device_init_wakeup(&pdev->dev, 1);
> +
> +       xrtcdev->rtc = devm_rtc_device_register(&pdev->dev, pdev->name,
> +                                        &xlnx_rtc_ops, THIS_MODULE);
> +       return PTR_ERR_OR_ZERO(xrtcdev->rtc);
> +}
> +
> +static int xlnx_rtc_remove(struct platform_device *pdev)
> +{
> +       xlnx_rtc_alarm_irq_enable(&pdev->dev, 0);
> +       device_init_wakeup(&pdev->dev, 0);
> +
> +       return 0;
> +}
> +
> +static int __maybe_unused xlnx_rtc_suspend(struct device *dev)
> +{
> +       struct platform_device *pdev = to_platform_device(dev);
> +       struct xlnx_rtc_dev *xrtcdev = platform_get_drvdata(pdev);
> +
> +       if (device_may_wakeup(&pdev->dev))
> +               enable_irq_wake(xrtcdev->alarm_irq);
> +       else
> +               xlnx_rtc_alarm_irq_enable(dev, 0);
> +
> +       return 0;
> +}
> +
> +static int __maybe_unused xlnx_rtc_resume(struct device *dev)
> +{
> +       struct platform_device *pdev = to_platform_device(dev);
> +       struct xlnx_rtc_dev *xrtcdev = platform_get_drvdata(pdev);
> +
> +       if (device_may_wakeup(&pdev->dev))
> +               disable_irq_wake(xrtcdev->alarm_irq);
> +       else
> +               xlnx_rtc_alarm_irq_enable(dev, 1);
> +
> +       return 0;
> +}
> +
> +static SIMPLE_DEV_PM_OPS(xlnx_rtc_pm_ops, xlnx_rtc_suspend, xlnx_rtc_resume);
> +
> +static const struct of_device_id xlnx_rtc_of_match[] = {
> +       {.compatible = "xlnx,zynqmp-rtc" },
> +       { }
> +};
> +MODULE_DEVICE_TABLE(of, xlnx_rtc_of_match);
> +
> +static struct platform_driver xlnx_rtc_driver = {
> +       .probe          = xlnx_rtc_probe,
> +       .remove         = xlnx_rtc_remove,
> +       .driver         = {
> +               .name   = KBUILD_MODNAME,
> +               .pm     = &xlnx_rtc_pm_ops,
> +               .of_match_table = xlnx_rtc_of_match,
> +       },
> +};
> +
> +module_platform_driver(xlnx_rtc_driver);
> +
> +MODULE_DESCRIPTION("Xilinx Zynq MPSoC RTC driver");
> +MODULE_AUTHOR("Xilinx Inc.");
> +MODULE_LICENSE("GPL v2");
> --
> 2.1.2
>
>
> _______________________________________________
> linux-arm-kernel mailing list
> linux-arm-kernel at lists.infradead.org
> http://lists.infradead.org/mailman/listinfo/linux-arm-kernel

Cheers,

Moritz


From festevam at gmail.com  Wed Aug 19 11:31:30 2015
From: festevam at gmail.com (Fabio Estevam)
Date: Wed, 19 Aug 2015 15:31:30 -0300
Subject: [PATCH] ARM: imx: mach-imx6ul: Fix allmodconfig build
Message-ID: <1440009090-25799-1-git-send-email-festevam@gmail.com>

From: Fabio Estevam <fabio.estevam at freescale.com>

We should call phy_register_fixup_for_uid() only when CONFIG_PHYLIB
is built-in, otherwise we get the following link error when building
allmodconfig:

arch/arm/mach-imx/built-in.o: In function `imx6ul_init_machine':
:(.init.text+0xa714): undefined reference to `phy_register_fixup_for_uid'

This is the same approach done in mach-imx6q.c and mach-imx6sx.c.

Reported-by: Olof Johansson <olof at lixom.net>
Signed-off-by: Fabio Estevam <fabio.estevam at freescale.com>
---
 arch/arm/mach-imx/mach-imx6ul.c | 4 +++-
 1 file changed, 3 insertions(+), 1 deletion(-)

diff --git a/arch/arm/mach-imx/mach-imx6ul.c b/arch/arm/mach-imx/mach-imx6ul.c
index db74da5..1b97fe1 100644
--- a/arch/arm/mach-imx/mach-imx6ul.c
+++ b/arch/arm/mach-imx/mach-imx6ul.c
@@ -45,7 +45,9 @@ static int ksz8081_phy_fixup(struct phy_device *dev)
 
 static void __init imx6ul_enet_phy_init(void)
 {
-	phy_register_fixup_for_uid(PHY_ID_KSZ8081, 0xffffffff, ksz8081_phy_fixup);
+	if (IS_BUILTIN(CONFIG_PHYLIB))
+		phy_register_fixup_for_uid(PHY_ID_KSZ8081, 0xffffffff,
+					   ksz8081_phy_fixup);
 }
 
 static inline void imx6ul_enet_init(void)
-- 
1.9.1



From nicolas.pitre at linaro.org  Wed Aug 19 11:40:47 2015
From: nicolas.pitre at linaro.org (Nicolas Pitre)
Date: Wed, 19 Aug 2015 14:40:47 -0400 (EDT)
Subject: [PATCH] drivers/clk: appropriate __init annotation for const data
In-Reply-To: <20150811231416.31346.83289@quantum>
References: <alpine.LFD.2.20.1507281430130.26147@knanqh.ubzr>
 <20150811231416.31346.83289@quantum>
Message-ID: <alpine.LFD.2.20.1508191437410.25645@knanqh.ubzr>

On Tue, 11 Aug 2015, Michael Turquette wrote:

> Quoting Nicolas Pitre (2015-07-28 16:43:20)
> > 
> > Init data marked const should be annotated with __initconst for
> > correctness and not __initdata.  This also fixes LTO builds that
> > otherwise fail with section mismatch errors.
> > 
> > Signed-off-by: Nicolas Pitre <nico at linaro.org>
> 
> Thanks for the patch Nico. Applied.


Is it possible for you to amend that patch with the following?

diff --git a/drivers/clk/clk-stm32f4.c b/drivers/clk/clk-stm32f4.c
index 5404a001c3..3f6f7ad394 100644
--- a/drivers/clk/clk-stm32f4.c
+++ b/drivers/clk/clk-stm32f4.c
@@ -293,7 +293,7 @@ stm32f4_rcc_lookup_clk(struct of_phandle_args *clkspec, void *data)
 	return clks[i];
 }
 
-static const char *const sys_parents[] __initconst =   { "hsi", NULL, "pll" };
+static const char *sys_parents[] __initdata =   { "hsi", NULL, "pll" };
 
 static const struct clk_div_table ahb_div_table[] = {
 	{ 0x0,   1 }, { 0x1,   1 }, { 0x2,   1 }, { 0x3,   1 },

Turns out that sys_parents[] is actually written to.


Nicolas


From robert.jarzmik at free.fr  Wed Aug 19 11:41:29 2015
From: robert.jarzmik at free.fr (Robert Jarzmik)
Date: Wed, 19 Aug 2015 20:41:29 +0200
Subject: [PATCH v2 05/21] ARM: pxa: magician: Add support for ADS7846
 touchscreen
In-Reply-To: <55D2591F.10509@tul.cz> (Petr Cvek's message of "Mon, 17 Aug 2015
 23:58:55 +0200")
References: <cover.1439843482.git.petr.cvek@tul.cz> <55D2591F.10509@tul.cz>
Message-ID: <87twrv6rza.fsf@belgarion.home>

Petr Cvek <petr.cvek at tul.cz> writes:

> Add support for ADS7846 touchscreen.
> +
> +static struct pxa2xx_spi_master magician_spi_info = {
> +	.num_chipselect = 1,
> +/*	.enable_dma = 1, */ /* FIXME probably unnecessary */
That's up to you. If almost nothing transits on SPI then a DMA is not necessary.

I'll leave that one for a week for others to further comment.

Cheers.

--
Robert


From robert.jarzmik at free.fr  Wed Aug 19 11:41:43 2015
From: robert.jarzmik at free.fr (Robert Jarzmik)
Date: Wed, 19 Aug 2015 20:41:43 +0200
Subject: [PATCH v2 06/21] ARM: pxa: magician: Add normal and power I2C
 definition
References: <cover.1439843482.git.petr.cvek@tul.cz> <55D2593A.5060400@tul.cz>
Message-ID: <87mvxn6ryw.fsf@belgarion.home>

Petr Cvek <petr.cvek at tul.cz> writes:

> @@ -873,10 +875,39 @@ static struct platform_device strataflash = {
>   */
>  
>  static struct i2c_pxa_platform_data i2c_info = {
> -	.fast_mode = 1,
> +	.fast_mode = 0,	/* fast mode seems to be have bit errors */
> +	.use_pio = 0, /* no polling */
This deserves a better commit message : why the switch out of fast_mode, what
was not working, etc ...

> +/*
> + * GPIO I2C normal controller (alternative)
> + */
> +
> +static struct i2c_gpio_platform_data rtc_device_data = {
> +	.sda_pin = GPIO118_MAGICIAN_I2C_SDA,
> +	.scl_pin = GPIO117_MAGICIAN_I2C_SCL,
> +	.udelay = 100
> +};
> +
> +static struct platform_device i2c_gpio_bus_alt = {
> +	.name = "i2c-gpio",
> +	.id = 0,
> +	.dev = {
> +		.platform_data = &rtc_device_data,
rtc_device_data, really ?
Can you add __initdata, I think i2c-gpio copies the data and doesn't use it
anymore after ?

Cheers.

-- 
Robert


From robert.jarzmik at free.fr  Wed Aug 19 11:41:51 2015
From: robert.jarzmik at free.fr (Robert Jarzmik)
Date: Wed, 19 Aug 2015 20:41:51 +0200
Subject: [PATCH v2 07/21] ARM: pxa: magician: Fix IrDA pdata and redundant
 GPIO request
References: <cover.1439843482.git.petr.cvek@tul.cz> <55D25950.6010601@tul.cz>
Message-ID: <87fv3f6ryo.fsf@belgarion.home>

Petr Cvek <petr.cvek at tul.cz> writes:

> Fix PXA FICP (IrDA) pdata and redundant GPIO request.
Fix what ? What is broken, what is not working before the patch and what will be
working after ? Could I have a better explanation in the commit message please ?

Cheers.

--
Robert


From javier at osg.samsung.com  Wed Aug 19 12:28:36 2015
From: javier at osg.samsung.com (Javier Martinez Canillas)
Date: Wed, 19 Aug 2015 21:28:36 +0200
Subject: [PATCH] ARM: exynos_defconfig: Enable CROS_EC_PROTO for ChromeOS
 EC mfd driver
In-Reply-To: <1439881281-22054-1-git-send-email-javier@osg.samsung.com>
References: <1439881281-22054-1-git-send-email-javier@osg.samsung.com>
Message-ID: <55D4D8E4.2090003@osg.samsung.com>

Hello,

On 08/18/2015 09:01 AM, Javier Martinez Canillas wrote:
> The ChromeOS mfd driver (MFD_CROS_EC) select the CROS_EC_PROTO config
> symbol because the driver uses some communication helper functions in
> drivers/platform/chrome/cros_ec_proto.c but other drivers depends on
> CROS_EC_PROTO instead. Mixing select and depends can lead to circular
> Kconfig dependencies so the MFD_CROS_EC select should be changed to a
> depends on CROS_EC_PROTO instead.
> 
> But doing so will break git bisect-ability since MFD_CROS_EC will not
> be enabled anymore unless the default configs first explicitly enable
> the CROS_EC_PROTO dependency.
> 
> Signed-off-by: Javier Martinez Canillas <javier at osg.samsung.com>

This patch has been superseded by the "[PATCH 0/6] ChromeOS EC
Kconfig cleanups" series: https://lkml.org/lkml/2015/8/19/194

Please just ignore it.

Best regards,
-- 
Javier Martinez Canillas
Open Source Group
Samsung Research America


From javier at osg.samsung.com  Wed Aug 19 12:29:46 2015
From: javier at osg.samsung.com (Javier Martinez Canillas)
Date: Wed, 19 Aug 2015 21:29:46 +0200
Subject: [PATCH] ARM: tegra: Enable CROS_EC_PROTO for ChromeOS EC mfd
 driver
In-Reply-To: <1439881599-22348-1-git-send-email-javier@osg.samsung.com>
References: <1439881599-22348-1-git-send-email-javier@osg.samsung.com>
Message-ID: <55D4D92A.7010107@osg.samsung.com>

Hello,

On 08/18/2015 09:06 AM, Javier Martinez Canillas wrote:
> The ChromeOS mfd driver (MFD_CROS_EC) select the CROS_EC_PROTO config
> symbol because the driver uses some communication helper functions in
> drivers/platform/chrome/cros_ec_proto.c but other drivers depends on
> CROS_EC_PROTO instead. Mixing select and depends can lead to circular
> Kconfig dependencies so the MFD_CROS_EC select should be changed to a
> depends on CROS_EC_PROTO instead.
> 
> But doing so will break git bisect-ability since MFD_CROS_EC will not
> be enabled anymore unless the default configs first explicitly enable
> the CROS_EC_PROTO dependency.
> 
> Also enable CHROME_PLATFORMS since the CROS_EC_PROTO symbol is inside
> that submenu.
> 
> Signed-off-by: Javier Martinez Canillas <javier at osg.samsung.com>
> ---

This patch has been superseded by the "[PATCH 0/6] ChromeOS EC
Kconfig cleanups" series: https://lkml.org/lkml/2015/8/19/194

Please just ignore it.

Best regards,
--
Javier Martinez Canillas
Open Source Group
Samsung Research America


From festevam at gmail.com  Wed Aug 19 13:36:12 2015
From: festevam at gmail.com (Fabio Estevam)
Date: Wed, 19 Aug 2015 17:36:12 -0300
Subject: [GIT PULL 1/3] ARM: imx: soc updates for 4.3
In-Reply-To: <CAOMZO5AL2iFJSpSukcV44Y=JZecRrm0sCRZQgyTM6w8_R6OHqw@mail.gmail.com>
References: <1439311351-5268-1-git-send-email-shawnguo@kernel.org>
 <20150818201416.GA4732@localhost>
 <CAOesGMg_TocMprCDQK69CTLtnyiyf4hn_hEzWoEhdKsXH3OuBw@mail.gmail.com>
 <CAOMZO5AL2iFJSpSukcV44Y=JZecRrm0sCRZQgyTM6w8_R6OHqw@mail.gmail.com>
Message-ID: <CAOMZO5AtmWPLeGDQP+VRLDuxMq6AXXHXjOQxHje1W5sz2bMvYQ@mail.gmail.com>

On Wed, Aug 19, 2015 at 3:17 PM, Fabio Estevam <festevam at gmail.com> wrote:

>> Please send an incremental fix (or I can drop this branch if you need
>> more time).
>
> Does this fix it?
>
> --- a/arch/arm/mach-imx/mach-imx6ul.c
> +++ b/arch/arm/mach-imx/mach-imx6ul.c
> @@ -45,7 +45,9 @@ static int ksz8081_phy_fixup(struct phy_device *dev)
>
>  static void __init imx6ul_enet_phy_init(void)
>  {
> -       phy_register_fixup_for_uid(PHY_ID_KSZ8081, 0xffffffff,
> ksz8081_phy_fixup);
> +       if (IS_BUILTIN(CONFIG_PHYLIB))
> +               phy_register_fixup_for_uid(PHY_ID_KSZ8081, 0xffffffff,
> +                                          ksz8081_phy_fixup);
>  }

Yes, just confirmed that this fixes the issue and sent a formal patch.


From olof at lixom.net  Wed Aug 19 13:36:26 2015
From: olof at lixom.net (Olof Johansson)
Date: Wed, 19 Aug 2015 13:36:26 -0700
Subject: [GIT PULL 9/9] ARM: tegra: Default configuration updates for
 v4.3-rc1
In-Reply-To: <20150819091358.GA26627@ulmo>
References: <1439563720-13189-1-git-send-email-thierry.reding@gmail.com>
 <1439563720-13189-10-git-send-email-thierry.reding@gmail.com>
 <CANMBJr7PKy-eCcB3HiBajpApHS_BYPa7xfKjTqV4o8Z1hwY99A@mail.gmail.com>
 <20150819091358.GA26627@ulmo>
Message-ID: <CAOesGMh8cRhQ-bdO+1CamurDYtokOhPnZdAQsmh_43_L-44ekg@mail.gmail.com>

On Wed, Aug 19, 2015 at 2:14 AM, Thierry Reding
<thierry.reding at gmail.com> wrote:
> On Tue, Aug 18, 2015 at 03:30:41PM -0700, Tyler Baker wrote:
>> Hi Theirry,
>>
>> On 14 August 2015 at 07:48, Thierry Reding <thierry.reding at gmail.com> wrote:
>> > Hi ARM SoC maintainers,
>> >
>> > The following changes since commit d770e558e21961ad6cfdf0ff7df0eb5d7d4f0754:
>> >
>> >   Linux 4.2-rc1 (2015-07-05 11:01:52 -0700)
>> >
>> > are available in the git repository at:
>> >
>> >   git://git.kernel.org/pub/scm/linux/kernel/git/tegra/linux.git tags/tegra-for-4.3-defconfig
>> >
>> > for you to fetch changes up to 258d9bc5e77fa40e290a0bd480d5349224374480:
>> >
>> >   ARM: tegra: Update multi_v7_defconfig (2015-08-14 16:26:00 +0200)
>> >
>> > Thanks,
>> > Thierry
>> >
>> > ----------------------------------------------------------------
>> > ARM: tegra: Default configuration updates for v4.3-rc1
>> >
>> > Enable the GK20A GPU (via the Nouveau driver) and CPU frequency scaling
>> > on Tegra124.
>> >
>> > ----------------------------------------------------------------
>> > Thierry Reding (1):
>> >       ARM: tegra: Update multi_v7_defconfig
>>
>> The kernelci.org bot recently reported jetson-tk1 boot failures[1][2]
>> in next-20150818, only when booting the mult_v7_defconfig kernels. I
>> bisected[3] these boot failure down to this commit, it didn't cleanly
>> revert, so I manually removed that options this patch added, and my
>> jetson-tk1 booted again. Digging a bit further, if I apply the patch
>> below to next-20150818, my jetson-tk1 boots.
>
> I'm not able to reproduce this here. Building next-20150818 with
> multi_v7_config and booting the resulting kernel works just fine.
>
>> diff --git a/arch/arm/configs/multi_v7_defconfig
>> b/arch/arm/configs/multi_v7_defconfig
>> index b2facab..a285afe 100644
>> --- a/arch/arm/configs/multi_v7_defconfig
>> +++ b/arch/arm/configs/multi_v7_defconfig
>> @@ -468,7 +468,6 @@ CONFIG_FRAMEBUFFER_CONSOLE_ROTATION=y
>>  CONFIG_SOUND=m
>>  CONFIG_SND=m
>>  CONFIG_SND_DYNAMIC_MINORS=y
>> -CONFIG_SND_HDA_TEGRA=m
>>  CONFIG_SND_HDA_INPUT_BEEP=y
>>  CONFIG_SND_HDA_PATCH_LOADER=y
>>  CONFIG_SND_HDA_CODEC_REALTEK=m
>
> lsmod output confirms that snd-hda-tegra.ko was loaded:
>
>         # lsmod
>         Module                  Size  Used by
>         snd_soc_tegra30_i2s     5591  2
>         snd_soc_tegra_pcm       1184  1 snd_soc_tegra30_i2s
>         snd_hda_tegra           4771  0
>         snd_soc_rt5640         56972  1
>         snd_soc_tegra_rt5640     3960  0
>         snd_hda_codec          76398  1 snd_hda_tegra
>         snd_soc_rl6231          1897  1 snd_soc_rt5640
>         snd_soc_tegra_utils     2825  1 snd_soc_tegra_rt5640
>         snd_hda_core           26151  2 snd_hda_codec,snd_hda_tegra
>         snd_soc_core          119213  4 snd_soc_tegra_pcm,snd_soc_rt5640,snd_soc_tegra_rt5640,snd_soc_tegra30_i2s
>         snd_compress            7114  1 snd_soc_core
>         snd_pcm_dmaengine       2943  1 snd_soc_core
>         snd_pcm                67835  6 snd_soc_rt5640,snd_soc_core,snd_hda_codec,snd_hda_tegra,snd_pcm_dmaengine,snd_hda_core
>         snd_timer              16881  1 snd_pcm
>         snd                    41480  6 snd_soc_core,snd_timer,snd_pcm,snd_hda_codec,snd_hda_tegra,snd_compress
>         soundcore                858  1 snd
>         snd_soc_tegra30_ahub     8747  1 snd_soc_tegra30_i2s
>         nouveau              1217903  0
>         tegra_devfreq           5389  0
>         ttm                    65073  1 nouveau
>
>> This isn't where the story ends unfortunately. The collabora lab also
>> has a jetson-tk1, booted in the same manner, which boots next-20150818
>> fine[4]. The only differences I can spot in the two boot logs is that
>> the collabora board is using an older version of u-boot, where as my
>> board is using a newer version. U-Boot 2015.01-00231-gab77f24-dirty
>> (Good) vs U-Boot 2015.07-00130-gb217c89 (Bad).
>
> I don't have either of those commits in any of the U-Boot trees I have.
> Perhaps whatever tree this comes from has local patches that cause the
> breakage? The version that I use a recent upstream U-Boot with some
> local patches, none of which should impact Jetson TK1 in any way. Just
> to make sure I tried running latest origin/master, which identifies
> thusly:
>
>         U-Boot 2015.10-rc2-00040-g0f9258228e2b
>
> And that boots next-20150818 fine.
>
> If you can point me at the source for the version that you use I may be
> able to find something that could cause this.


FWIW, my jetson has been booting fine as well, with U-Boot
2014.07-rc1-00095-gd7782d0 and Debian userspace.

(Glad to confirm that it's a good thing we've got variety in how
systems are configured and setup so we get more coverage).


-Olof


From info at lategoodbye.de  Wed Aug 19 13:38:35 2015
From: info at lategoodbye.de (Stefan Wahren)
Date: Wed, 19 Aug 2015 22:38:35 +0200
Subject: [PATCH v2 1/7] drm/vc4: Add devicetree bindings for VC4.
In-Reply-To: <1439934848-7196-2-git-send-email-eric@anholt.net>
References: <1439934848-7196-1-git-send-email-eric@anholt.net>
 <1439934848-7196-2-git-send-email-eric@anholt.net>
Message-ID: <55D4E94B.8080103@lategoodbye.de>

Hi Eric,

Am 18.08.2015 um 23:54 schrieb Eric Anholt:
> VC4 is the GPU (display and 3D) subsystem present on the 2835 and some
> other Broadcom SoCs.
>
> This binding follows the model of msm, imx, sti, and others, where
> there is a subsystem node for the whole GPU, with nodes for the
> individual HW components within it.
>
> Signed-off-by: Eric Anholt <eric at anholt.net>
> ---
>
> v2: Extend the commit message, fix several nits from Stephen Warren.
>
>   .../devicetree/bindings/gpu/brcm,bcm-vc4.txt       | 79 ++++++++++++++++++++++
>   1 file changed, 79 insertions(+)
>   create mode 100644 Documentation/devicetree/bindings/gpu/brcm,bcm-vc4.txt
>
> diff --git a/Documentation/devicetree/bindings/gpu/brcm,bcm-vc4.txt b/Documentation/devicetree/bindings/gpu/brcm,bcm-vc4.txt
> new file mode 100644
> index 0000000..1b9fedc
> --- /dev/null
> +++ b/Documentation/devicetree/bindings/gpu/brcm,bcm-vc4.txt
> @@ -0,0 +1,79 @@
> +Broadcom VC4 GPU
> +
> +The VC4 device present on the Raspberry Pi includes a display system
> +with HDMI output and the HVS scaler for compositing display planes.
> +
> +Required properties for VC4:
> +- compatible:	Should be "brcm,vc4"
> +- crtcs:	List of phandles of pixelvalve scanout engines
> +- hvss:		List of phandles of HVS video scalers
> +- encoders:	List of phandles of output encoders (HDMI, SDTV)
> +
> +Required properties for Pixel Valve:
> +- compatible:	Should be "brcm,vc4-pixelvalve"
> +- reg:		Physical base address and length of the PV's registers
> +- interrupts:	The interrupt number
> +		  See bindings/interrupt-controller/brcm,bcm2835-armctrl-ic.txt
> +
> +Required properties for HVS:
> +- compatible:	Should be "brcm,vc4-hvs"
> +- reg:		Physical base address and length of the HVS's registers
> +- interrupts:	The interrupt number
> +		  See bindings/interrupt-controller/brcm,bcm2835-armctrl-ic.txt
> +
> +Required properties for HDMI
> +- compatible:	Should be "brcm,vc4-hdmi"
> +- reg:		Physical base address and length of the two register ranges
> +		  ("HDMI" and "HD", in that order)
> +- interrupts:	The interrupt numbers
> +		  See bindings/interrupt-controller/brcm,bcm2835-armctrl-ic.txt
> +- ddc:		phandle of the I2C controller used for DDC EDID probing
> +- crtc:		phandle to the pixelvalve CRTC the HDMI encoder is attached to
> +
> +Optional properties for HDMI:
> +- hpd-gpio:	The GPIO pin for HDMI hotplug detect (if it doesn't appear
> +		  as an interrupt/status bit in the HDMI controller
> +		  itself).  See bindings/pinctrl/brcm,bcm2835-gpio.txt
> +
> +Example:
> +pv0: brcm,vc4-pixelvalve at 7e206000 {

AFAIK the DT node name should describe the function and usually don't 
have a vendor prefix. Here some possible suggestions without deeper 
knowledge of the hardware function:

pv0: pixelvalve

> +	compatible = "brcm,vc4-pixelvalve";
> +	reg = <0x7e206000 0x100>;
> +	interrupts = <2 13>; /* pwa2 */
> +};
> +
> +pv1: brcm,vc4-pixelvalve at 7e207000 {

pv1: pixelvalve

> +	compatible = "brcm,vc4-pixelvalve";
> +	reg = <0x7e207000 0x100>;
> +	interrupts = <2 14>; /* pwa1 */
> +};
> +
> +pv2: brcm,vc4-pixelvalve at 7e807000 {

pv2: pixelvalve

> +	compatible = "brcm,vc4-pixelvalve";
> +	reg = <0x7e807000 0x100>;
> +	interrupts = <2 10>; /* pixelvalve */
> +};
> +
> +hvs: brcm,hvs at 7e400000 {

hvs: hvs

> +	compatible = "brcm,vc4-hvs";
> +	reg = <0x7e400000 0x6000>;
> +	interrupts = <2 1>;
> +};
> +
> +hdmi: brcm,vc4-hdmi at 7e902000 {

hdmi: hdmi

> +	compatible = "brcm,vc4-hdmi";
> +	reg = <0x7e902000 0x600>,
> +	      <0x7e808000 0x100>;
> +	interrupts = <2 8>, <2 9>;
> +	ddc = <&i2c2>;
> +	hpd-gpio = <&gpio 46 GPIO_ACTIVE_HIGH>;
> +	crtc = <&pv2>;
> +};
> +
> +vc4: vc4 at 0x7e4c0000 {

vc4: gpu

Regards
Stefan

> +	compatible = "brcm,vc4";
> +
> +	crtcs = <&pv0>, <&pv1>, <&pv2>;
> +	encoders = <&hdmi>;
> +	hvss = <&hvs>;
> +};
>



From daniel.lezcano at linaro.org  Wed Aug 19 14:24:44 2015
From: daniel.lezcano at linaro.org (Daniel Lezcano)
Date: Wed, 19 Aug 2015 23:24:44 +0200
Subject: [PATCH v4 4/4] misc: atmel_tclib: get and use slow clock
In-Reply-To: <1439717026-30634-5-git-send-email-alexandre.belloni@free-electrons.com>
References: <1439717026-30634-1-git-send-email-alexandre.belloni@free-electrons.com>
 <1439717026-30634-5-git-send-email-alexandre.belloni@free-electrons.com>
Message-ID: <55D4F41C.6010109@linaro.org>

On 08/16/2015 11:23 AM, Alexandre Belloni wrote:
> From: Boris Brezillon <boris.brezillon at free-electrons.com>
>
> Commit dca1a4b5ff6e ("clk: at91: keep slow clk enabled to prevent system
> hang") added a workaround for the slow clock as it is not properly handled
> by its users.
>
> Get and use the slow clock as it is necessary for the timer counters.
>
> Signed-off-by: Boris Brezillon <boris.brezillon at free-electrons.com>
> Signed-off-by: Alexandre Belloni <alexandre.belloni at free-electrons.com>
> Acked-by: Greg Kroah-Hartman <gregkh at linuxfoundation.org>
> ---

Acked-by: Daniel Lezcano <daniel.lezcano at linaro.org>


-- 
  <http://www.linaro.org/> Linaro.org ? Open source software for ARM SoCs

Follow Linaro:  <http://www.facebook.com/pages/Linaro> Facebook |
<http://twitter.com/#!/linaroorg> Twitter |
<http://www.linaro.org/linaro-blog/> Blog



From dhdang at apm.com  Wed Aug 19 14:28:33 2015
From: dhdang at apm.com (Duc Dang)
Date: Wed, 19 Aug 2015 14:28:33 -0700
Subject: [PATCH v5 1/2] usb: make xhci platform driver use 64 bit or 32
 bit DMA
In-Reply-To: <1643536.i8Q5EFEN01@wuerfel>
References: <CADaLNDkU14GCPZE_zNt_9kMSsUdywyNp1QCiWpokXQgbfRS0qw@mail.gmail.com>
 <20150808092252.GJ7557@n2100.arm.linux.org.uk>
 <CADaLNDn4SvW3hvi7H0c_z2xgVSgRHLOK06xMyTYJd+ddFqc7Nw@mail.gmail.com>
 <1643536.i8Q5EFEN01@wuerfel>
Message-ID: <CADaLNDmYt+k6Sw6q+t2-FA7muk=x6h_hfYV321B03qBPMD_=AA@mail.gmail.com>

On Sat, Aug 15, 2015 at 1:05 PM, Arnd Bergmann <arnd at arndb.de> wrote:
>
> On Saturday 08 August 2015 13:31:02 Duc Dang wrote:
> > >
> > > If we know that pdev->dev.dma_mask will always be initialised at this
> > > point, then the above change is fine.  If not, it's introducing a
> > > regression - dma_set_mask_and_coherent() will fail if pdev->dev.dma_mask
> > > is NULL (depending on the architectures implementation of dma_set_mask()).
> > >
> > > Prefixing the above change with the two lines I mention above would
> > > ensure equivalent behaviour.  Even if we do want to get rid of this,
> > > I'd advise to do it as a separate patch after this change, which can
> > > be independently reverted if there's problems with its removal.
> > >
> > Hi Russell,
> >
> > I will add the 2 lines you mentioned back to next version of the
> > patch. It is safer to do it that way as I do not see
> > pdev->dev.dma_mask gets initialized before the call
> > dma_set_mask_and_coherent  inside this xhci_plat.c file.
>
> It would be good to add a WARN_ON() to the case where dma_mask
> is a NULL pointer at the least. That way, we will at least
> find out if there are some broken platforms that do not correctly
> initialize the mask pointer.

Hi Arnd,

So the check will look like this, please let me know what do you think:
        if (!pdev->dev.dma_mask) {
                WARN_ON(1);
                /* Initialize dma_mask if the broken platform code has
not done so */
                pdev->dev.dma_mask = &pdev->dev.coherent_dma_mask;
        }

>
>         Arnd




-- 
Regards,
Duc Dang.


From f.fainelli at gmail.com  Wed Aug 19 14:28:54 2015
From: f.fainelli at gmail.com (Florian Fainelli)
Date: Wed, 19 Aug 2015 14:28:54 -0700
Subject: [PATCH v1 1/6] net: phy: broadcom: add bcm54220 phy ID
In-Reply-To: <1439962444-27486-2-git-send-email-b38611@freescale.com>
References: <1439962444-27486-1-git-send-email-b38611@freescale.com>
 <1439962444-27486-2-git-send-email-b38611@freescale.com>
Message-ID: <CAGVrzcak2u_kBg1o061OO0UK8sdrXaKF+-7eREwByD-dQ1r1XQ@mail.gmail.com>

2015-08-18 22:33 GMT-07:00 Fugang Duan <b38611 at freescale.com>:
> Add bcm54220 phy ID entry.

This change itself is fine, but looking at the rest of your changes,
we are not adding an entry for this PHY in drivers/net/phy/broadcom.c,
which means that we will bind to the Generic PHY driver, and so this
looks sufficient, even with your fixup done in the subsequent patch.

>
> Signed-off-by: Fugang Duan <B38611 at freescale.com>
> ---
>  include/linux/brcmphy.h | 1 +
>  1 file changed, 1 insertion(+)
>
> diff --git a/include/linux/brcmphy.h b/include/linux/brcmphy.h
> index 697ca77..20bed15 100644
> --- a/include/linux/brcmphy.h
> +++ b/include/linux/brcmphy.h
> @@ -16,6 +16,7 @@
>  #define PHY_ID_BCM5482                 0x0143bcb0
>  #define PHY_ID_BCM5411                 0x00206070
>  #define PHY_ID_BCM5421                 0x002060e0
> +#define PHY_ID_BCM54220                        0x600d8589
>  #define PHY_ID_BCM5464                 0x002060b0
>  #define PHY_ID_BCM5461                 0x002060c0
>  #define PHY_ID_BCM54616S               0x03625d10
> --
> 1.9.1
>
>
> _______________________________________________
> linux-arm-kernel mailing list
> linux-arm-kernel at lists.infradead.org
> http://lists.infradead.org/mailman/listinfo/linux-arm-kernel



-- 
Florian


From jeremy.linton at arm.com  Wed Aug 19 14:36:30 2015
From: jeremy.linton at arm.com (Jeremy Linton)
Date: Wed, 19 Aug 2015 16:36:30 -0500
Subject: [PATCHv2 0/2] USB: Enable EHCI-platform driver for use with ACPI
Message-ID: <1440020192-23754-1-git-send-email-jeremy.linton@arm.com>

This patch set enables USB on the ARM Juno development platform when
using an ACPI kernel.

First it adds an error message if the device cannot be configured with
the current DMA settings (missing/unsupported CCA attribute). It then
adds the ACPI PNP id to the acpi_match_table entry.

Tested-by: Huang Shijie <shijie.huang at arm.com>
Reviewed-by: Graeme Gregory <graeme.gregory at linaro.org>
Reviewed-by: Hanjun Guo <hanjun.guo at linaro.org>
Acked-by: Alan Stern <stern at rowland.harvard.edu>
Signed-off-by: Jeremy Linton <jeremy.linton at arm.com>

Jeremy Linton (2):
  USB: ehci-platform: Display a DMA configuration error message
  USB: ehci-platform: Add ACPI bindings for the EHCI platform driver.

 drivers/usb/host/ehci-platform.c | 12 +++++++++++-
 1 file changed, 11 insertions(+), 1 deletion(-)

-- 
2.4.3




From jeremy.linton at arm.com  Wed Aug 19 14:36:32 2015
From: jeremy.linton at arm.com (Jeremy Linton)
Date: Wed, 19 Aug 2015 16:36:32 -0500
Subject: [PATCH 2/2] USB: ehci-platform: Add ACPI bindings for the EHCI
 platform driver.
In-Reply-To: <1440020192-23754-1-git-send-email-jeremy.linton@arm.com>
References: <1440020192-23754-1-git-send-email-jeremy.linton@arm.com>
Message-ID: <1440020192-23754-3-git-send-email-jeremy.linton@arm.com>

This enables USB on the ARM juno board when booted with
an ACPI kernel. The PNP id comes from the PNP/ACPI registry
and describes an EHCI controller without debug.

Tested-by: Huang Shijie <shijie.huang at arm.com>
Reviewed-by: Graeme Gregory <graeme.gregory at linaro.org>
Reviewed-by: Hanjun Guo <hanjun.guo at linaro.org>
Acked-by: Alan Stern <stern at rowland.harvard.edu>
Signed-off-by: Jeremy Linton <jeremy.linton at arm.com>
---
 drivers/usb/host/ehci-platform.c | 8 ++++++++
 1 file changed, 8 insertions(+)

diff --git a/drivers/usb/host/ehci-platform.c b/drivers/usb/host/ehci-platform.c
index 3ce38c3..9680a5d 100644
--- a/drivers/usb/host/ehci-platform.c
+++ b/drivers/usb/host/ehci-platform.c
@@ -19,6 +19,7 @@
  *
  * Licensed under the GNU/GPL. See COPYING for details.
  */
+#include <linux/acpi.h>
 #include <linux/clk.h>
 #include <linux/dma-mapping.h>
 #include <linux/err.h>
@@ -382,6 +383,12 @@ static const struct of_device_id vt8500_ehci_ids[] = {
 };
 MODULE_DEVICE_TABLE(of, vt8500_ehci_ids);
 
+static const struct acpi_device_id ehci_acpi_match[] = {
+	{ "PNP0D20", 0 }, /* EHCI controller without debug */
+	{ }
+};
+MODULE_DEVICE_TABLE(acpi, ehci_acpi_match);
+
 static const struct platform_device_id ehci_platform_table[] = {
 	{ "ehci-platform", 0 },
 	{ }
@@ -400,6 +407,7 @@ static struct platform_driver ehci_platform_driver = {
 		.name	= "ehci-platform",
 		.pm	= &ehci_platform_pm_ops,
 		.of_match_table = vt8500_ehci_ids,
+		.acpi_match_table = ACPI_PTR(ehci_acpi_match),
 	}
 };
 
-- 
2.4.3




From jeremy.linton at arm.com  Wed Aug 19 14:36:31 2015
From: jeremy.linton at arm.com (Jeremy Linton)
Date: Wed, 19 Aug 2015 16:36:31 -0500
Subject: [PATCH 1/2] USB: ehci-platform: Display a DMA configuration error
 message
In-Reply-To: <1440020192-23754-1-git-send-email-jeremy.linton@arm.com>
References: <1440020192-23754-1-git-send-email-jeremy.linton@arm.com>
Message-ID: <1440020192-23754-2-git-send-email-jeremy.linton@arm.com>

If the ehci driver fails to configure the dma settings then display
a dev error instead of simply failing. This is triggered in an
ACPI world if the user fails to set the _CCA on the device.

Tested-by: Huang Shijie <shijie.huang at arm.com>
Reviewed-by: Graeme Gregory <graeme.gregory at linaro.org>
Reviewed-by: Hanjun Guo <hanjun.guo at linaro.org>
Acked-by: Alan Stern <stern at rowland.harvard.edu>
Signed-off-by: Jeremy Linton <jeremy.linton at arm.com>
---
 drivers/usb/host/ehci-platform.c | 4 +++-
 1 file changed, 3 insertions(+), 1 deletion(-)

diff --git a/drivers/usb/host/ehci-platform.c b/drivers/usb/host/ehci-platform.c
index 2593def..3ce38c3 100644
--- a/drivers/usb/host/ehci-platform.c
+++ b/drivers/usb/host/ehci-platform.c
@@ -162,8 +162,10 @@ static int ehci_platform_probe(struct platform_device *dev)
 
 	err = dma_coerce_mask_and_coherent(&dev->dev,
 		pdata->dma_mask_64 ? DMA_BIT_MASK(64) : DMA_BIT_MASK(32));
-	if (err)
+	if (err) {
+		dev_err(&dev->dev, "Error: DMA mask configuration failed\n");
 		return err;
+	}
 
 	irq = platform_get_irq(dev, 0);
 	if (irq < 0) {
-- 
2.4.3




From info at lategoodbye.de  Wed Aug 19 14:37:14 2015
From: info at lategoodbye.de (Stefan Wahren)
Date: Wed, 19 Aug 2015 23:37:14 +0200
Subject: [PATCH v2 3/7] drm/vc4: Add KMS support for Raspberry Pi.
In-Reply-To: <1439934848-7196-4-git-send-email-eric@anholt.net>
References: <1439934848-7196-1-git-send-email-eric@anholt.net>
 <1439934848-7196-4-git-send-email-eric@anholt.net>
Message-ID: <55D4F70A.30508@lategoodbye.de>

Hi Eric,

only a few nits.

Am 18.08.2015 um 23:54 schrieb Eric Anholt:
> This is the start of a full VC4 driver.  Right now this just supports
> configuring the display using a pre-existing video mode (because
> changing the pixel clock isn't available yet, and doesn't work when it
> is).  However, this is enough for fbcon and bringing up X using
> xf86-video-modesetting.
>
> Signed-off-by: Eric Anholt <eric at anholt.net>
> ---
>
> v2: Drop FB_HELPER select thanks to Archit's patches.  Do manual init
>      ordering instead of using the .load hook.  Structure registration
>      more like tegra's, but still using the typical "component" code.
>      Drop no-op hooks for atomic_begin and mode_fixup() now that
>      they're optional.  Drop sentinel in Makefile.  Fix minor style
>      nits I noticed on another reread.
>
>   drivers/gpu/drm/Kconfig           |   2 +
>   drivers/gpu/drm/Makefile          |   1 +
>   drivers/gpu/drm/vc4/Kconfig       |  13 +
>   drivers/gpu/drm/vc4/Makefile      |  17 +
>   drivers/gpu/drm/vc4/vc4_bo.c      |  52 ++++
>   drivers/gpu/drm/vc4/vc4_crtc.c    | 565 ++++++++++++++++++++++++++++++++++
>   drivers/gpu/drm/vc4/vc4_debugfs.c |  38 +++
>   drivers/gpu/drm/vc4/vc4_drv.c     | 271 ++++++++++++++++
>   drivers/gpu/drm/vc4/vc4_drv.h     | 120 ++++++++
>   drivers/gpu/drm/vc4/vc4_hdmi.c    | 633 ++++++++++++++++++++++++++++++++++++++
>   drivers/gpu/drm/vc4/vc4_hvs.c     | 161 ++++++++++
>   drivers/gpu/drm/vc4/vc4_kms.c     |  84 +++++
>   drivers/gpu/drm/vc4/vc4_plane.c   | 320 +++++++++++++++++++
>   drivers/gpu/drm/vc4/vc4_regs.h    | 562 +++++++++++++++++++++++++++++++++
>   14 files changed, 2839 insertions(+)
>   create mode 100644 drivers/gpu/drm/vc4/Kconfig
>   create mode 100644 drivers/gpu/drm/vc4/Makefile
>   create mode 100644 drivers/gpu/drm/vc4/vc4_bo.c
>   create mode 100644 drivers/gpu/drm/vc4/vc4_crtc.c
>   create mode 100644 drivers/gpu/drm/vc4/vc4_debugfs.c
>   create mode 100644 drivers/gpu/drm/vc4/vc4_drv.c
>   create mode 100644 drivers/gpu/drm/vc4/vc4_drv.h
>   create mode 100644 drivers/gpu/drm/vc4/vc4_hdmi.c
>   create mode 100644 drivers/gpu/drm/vc4/vc4_hvs.c
>   create mode 100644 drivers/gpu/drm/vc4/vc4_kms.c
>   create mode 100644 drivers/gpu/drm/vc4/vc4_plane.c
>   create mode 100644 drivers/gpu/drm/vc4/vc4_regs.h
>
> [...]
> +static void vc4_crtc_mode_set_nofb(struct drm_crtc *crtc)
> +{
> +	struct vc4_crtc *vc4_crtc = to_vc4_crtc(crtc);
> +	struct drm_crtc_state *state = crtc->state;
> +	struct drm_display_mode *mode = &state->adjusted_mode;
> +	u32 vactive = (mode->vdisplay >>
> +		       ((mode->flags & DRM_MODE_FLAG_INTERLACE) ? 1 : 0));
> +	u32 format = PV_CONTROL_FORMAT_24;
> +	bool debug_dump_regs = false;
> +
> +	if (debug_dump_regs) {
> +		DRM_INFO("CRTC %d regs before:\n", drm_crtc_index(crtc));
> +		vc4_crtc_dump_regs(vc4_crtc);
> +	}
> +
> +	/* This is where we would set the pixel clock. */
> +
> +	/* Reset the PV fifo. */
> +	CRTC_WRITE(PV_CONTROL, 0);
> +	CRTC_WRITE(PV_CONTROL, PV_CONTROL_FIFO_CLR | PV_CONTROL_EN);
> +	CRTC_WRITE(PV_CONTROL, 0);
> +
> +	CRTC_WRITE(PV_HORZA,
> +		   VC4_SET_FIELD(mode->htotal - mode->hsync_end,
> +				 PV_HORZA_HBP) |
> +		   VC4_SET_FIELD(mode->hsync_end - mode->hsync_start,
> +				 PV_HORZA_HSYNC));
> +	CRTC_WRITE(PV_HORZB,
> +		   VC4_SET_FIELD(mode->hsync_start - mode->hdisplay,
> +				 PV_HORZB_HFP) |
> +		   VC4_SET_FIELD(mode->hdisplay, PV_HORZB_HACTIVE));
> +
> +	CRTC_WRITE(PV_VERTA,
> +		   VC4_SET_FIELD(mode->vtotal - mode->vsync_end,
> +				 PV_VERTA_VBP) |
> +		   VC4_SET_FIELD(mode->vsync_end - mode->vsync_start,
> +				 PV_VERTA_VSYNC));
> +	CRTC_WRITE(PV_VERTB,
> +		   VC4_SET_FIELD(mode->vsync_start - mode->vdisplay,
> +				 PV_VERTB_VFP) |
> +		   VC4_SET_FIELD(vactive, PV_VERTB_VACTIVE));
> +	if (mode->flags & DRM_MODE_FLAG_INTERLACE) {
> +		/* Write PV_VERTA_EVEN/VERTB_EVEN */
> +	}

checkpatch complains here. Is this intended to have only a comment? Is 
it a TODO?

> [...]
> --- /dev/null
> +++ b/drivers/gpu/drm/vc4/vc4_drv.h
> @@ -0,0 +1,120 @@
> +/*
> + * Copyright (C) 2015 Broadcom
> + *
> + * This program is free software; you can redistribute it and/or modify
> + * it under the terms of the GNU General Public License version 2 as
> + * published by the Free Software Foundation.
> + */
> +
> +#include "drmP.h"
> +#include "drm_gem_cma_helper.h"
> +
> +struct vc4_dev {
> +	struct drm_device *dev;
> +
> +	struct vc4_hdmi *hdmi;
> +	struct vc4_hvs *hvs;
> +	struct vc4_crtc *crtc[3];
> +};
> +
> +static inline struct vc4_dev *
> +to_vc4_dev(struct drm_device *dev)
> +{
> +	return (struct vc4_dev *)dev->dev_private;
> +}
> +
> +struct vc4_bo {
> +	struct drm_gem_cma_object base;
> +};
> +
> +static inline struct vc4_bo *
> +to_vc4_bo(struct drm_gem_object *bo)
> +{
> +	return (struct vc4_bo *)bo;
> +}
> +
> +struct vc4_hvs {
> +	struct platform_device *pdev;
> +	void __iomem *regs;
> +	void __iomem *dlist;
> +};
> +
> +struct vc4_crtc {
> +	struct drm_crtc base;
> +	void __iomem *regs;
> +
> +	/* Which HVS channel we're using for our CRTC. */
> +	int channel;
> +
> +	/* Pointer to the actual hardware display list memory for the
> +	 * crtc.
> +	 */
> +	u32 __iomem *dlist;
> +
> +	u32 dlist_size; /* in dwords */
> +
> +	struct drm_pending_vblank_event *event;
> +};
> +
> +static inline struct vc4_crtc *
> +to_vc4_crtc(struct drm_crtc *crtc)
> +{
> +	return (struct vc4_crtc *)crtc;
> +}
> +
> +struct vc4_plane {
> +	struct drm_plane base;
> +};
> +
> +static inline struct vc4_plane *
> +to_vc4_plane(struct drm_plane *plane)
> +{
> +	return (struct vc4_plane *)plane;
> +}
> +
> +#define HVS_READ(offset) readl(vc4->hvs->regs + offset)
> +#define HVS_WRITE(offset, val) writel(val, vc4->hvs->regs + offset)
> +
> +/* vc4_bo.c */

I'm not sure about these filename references.

> +void vc4_free_object(struct drm_gem_object *gem_obj);
> +struct vc4_bo *vc4_bo_create(struct drm_device *dev, size_t size);
> +int vc4_dumb_create(struct drm_file *file_priv,
> +		    struct drm_device *dev,
> +		    struct drm_mode_create_dumb *args);
> +struct dma_buf *vc4_prime_export(struct drm_device *dev,
> +				 struct drm_gem_object *obj, int flags);
> +
> +/* vc4_crtc.c */
> +extern struct platform_driver vc4_crtc_driver;
> +int vc4_enable_vblank(struct drm_device *dev, int crtc_id);
> +void vc4_disable_vblank(struct drm_device *dev, int crtc_id);
> +void vc4_cancel_page_flip(struct drm_crtc *crtc, struct drm_file *file);
> +int vc4_crtc_debugfs_regs(struct seq_file *m, void *arg);
> +
> +/* vc4_debugfs.c */
> +int vc4_debugfs_init(struct drm_minor *minor);
> +void vc4_debugfs_cleanup(struct drm_minor *minor);
> +
> +/* vc4_drv.c */
> +void __iomem *vc4_ioremap_regs(struct platform_device *dev, int index);
> +
> +/* vc4_hdmi.c */
> +extern struct platform_driver vc4_hdmi_driver;
> +struct drm_encoder *vc4_hdmi_encoder_init(struct drm_device *dev);
> +struct drm_connector *vc4_hdmi_connector_init(struct drm_device *dev,
> +					      struct drm_encoder *encoder);
> +int vc4_hdmi_debugfs_regs(struct seq_file *m, void *unused);
> +
> +/* vc4_hvs.c */
> +extern struct platform_driver vc4_hvs_driver;
> +void vc4_hvs_dump_state(struct drm_device *dev);
> +int vc4_hvs_debugfs_regs(struct seq_file *m, void *unused);
> +
> +/* vc4_kms.c */
> +int vc4_kms_load(struct drm_device *dev);
> +
> +/* vc4_plane.c */
> +struct drm_plane *vc4_plane_init(struct drm_device *dev,
> +				 enum drm_plane_type type);
> +u32 vc4_plane_write_dlist(struct drm_plane *plane, u32 __iomem *dlist);
> +u32 vc4_plane_dlist_size(struct drm_plane_state *state);
>
> [...]
> diff --git a/drivers/gpu/drm/vc4/vc4_regs.h b/drivers/gpu/drm/vc4/vc4_regs.h
> new file mode 100644
> index 0000000..0eff631
> --- /dev/null
> +++ b/drivers/gpu/drm/vc4/vc4_regs.h
> @@ -0,0 +1,562 @@
> +/*
> + *  Copyright ? 2014-2015 Broadcom
> + *
> + * 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.
> + */
> +
> +#define VC4_MASK(high, low) (((1 << ((high) - (low) + 1)) - 1) << (low))
> +/* Using the GNU statement expression extension */
> +#define VC4_SET_FIELD(value, field)					\
> +	({								\
> +		uint32_t fieldval = (value) << field##_SHIFT;		\
> +		WARN_ON((fieldval & ~field##_MASK) != 0);		\
> +		fieldval & field##_MASK;				\
> +	 })
> +
> +#define VC4_GET_FIELD(word, field) (((word) & field##_MASK) >>		\
> +				    field##_SHIFT)
> +
> +#define V3D_IDENT0   0x00000
> +# define V3D_EXPECTED_IDENT0 \
> +	((2 << 24) | \
> +	('V' << 0) | \
> +	('3' << 8) | \
> +	 ('D' << 16))
> +
> +#define V3D_IDENT1   0x00004
> +/* Multiples of 1kb */
> +# define V3D_IDENT1_VPM_SIZE_MASK                      VC4_MASK(31, 28)
> +# define V3D_IDENT1_VPM_SIZE_SHIFT                     28
> +# define V3D_IDENT1_NSEM_MASK                          VC4_MASK(23, 16)
> +# define V3D_IDENT1_NSEM_SHIFT                         16
> +# define V3D_IDENT1_TUPS_MASK                          VC4_MASK(15, 12)
> +# define V3D_IDENT1_TUPS_SHIFT                         12
> +# define V3D_IDENT1_QUPS_MASK                          VC4_MASK(11, 8)
> +# define V3D_IDENT1_QUPS_SHIFT                         8
> +# define V3D_IDENT1_NSLC_MASK                          VC4_MASK(7, 4)
> +# define V3D_IDENT1_NSLC_SHIFT                         4
> +# define V3D_IDENT1_REV_MASK                           VC4_MASK(3, 0)
> +# define V3D_IDENT1_REV_SHIFT                          0
> +
> +#define V3D_IDENT2   0x00008
> +#define V3D_SCRATCH  0x00010
> +#define V3D_L2CACTL  0x00020
> +# define V3D_L2CACTL_L2CCLR                            (1 << 2)

Maybe you could use the BIT macro?

Thanks Stefan




From paul.gortmaker at windriver.com  Wed Aug 19 14:48:04 2015
From: paul.gortmaker at windriver.com (Paul Gortmaker)
Date: Wed, 19 Aug 2015 17:48:04 -0400
Subject: [PATCH v2 0/5] drivers/tty: make more bool drivers explicitly
 non-modular
Message-ID: <1440020889-12120-1-git-send-email-paul.gortmaker@windriver.com>

[v2: drop dead module code removal from 8250_lpc18xx.c ; instead convert it
 from bool to tristate ; also add ack to hvc_console commit.]

This second set of patches to drivers/tty steps outside of the serial
dir, and an improved auditing finds two more serial drivers pretending
to be modular that really are not.

The reasoning for doing this is the same as the first set[1] of patches
and is largely copied below:

  In the previous merge window, we made changes to allow better
  delineation between modular and non-modular code in commit
  0fd972a7d91d6e15393c449492a04d94c0b89351 ("module: relocate module_init
  from init.h to module.h").  This allows us to now ensure module code
  looks modular and non-modular code does not accidentally look modular
  without suffering build breakage.
  
  Here we target code that is, by nature of their Kconfig settings, only
  available to be built-in, but implicitly presenting itself as being
  possibly modular by way of using modular headers, macros, and functions.
  
  The goal here is to remove that illusion of modularity from these
  drivers, but in a way that leaves the actual runtime unchanged.
  In doing so, we remove code that has never been tested and adds
  no value to the tree.  And we begin the process of expecting a
  level of consistency between the Kconfig of a driver and the code
  that the driver uses.
  
Build tested for allyesconfig on x86_64, and ARM for lpc81xx, and powerpc
for hvc_console and mpsc, layered onto tty/tty-next as a baseline.

Paul.

[1] https://lkml.kernel.org/r/1437530538-5078-1-git-send-email-paul.gortmaker at windriver.com
--

Cc: Greg Kroah-Hartman <gregkh at linuxfoundation.org>
Cc: Jiri Slaby <jslaby at suse.com>
Cc: Joachim Eastwood <manabian at gmail.com>
Cc: linux-arm-kernel at lists.infradead.org
Cc: linuxppc-dev at lists.ozlabs.org
Cc: linux-serial at vger.kernel.org

Paul Gortmaker (5):
  drivers/tty: make pty.c slightly more explicitly non-modular
  drivers/tty: make sysrq.c slightly more explicitly non-modular
  drivers/tty: make hvc_console.c explicitly non-modular
  drivers/tty: make serial/mpsc.c driver explicitly non-modular
  drivers/tty: make serial 8250_lpc18xx.c Kconfig a tristate

 drivers/tty/hvc/hvc_console.c   | 18 +-----------------
 drivers/tty/pty.c               |  7 +++++--
 drivers/tty/serial/8250/Kconfig |  2 +-
 drivers/tty/serial/mpsc.c       | 36 +++---------------------------------
 drivers/tty/sysrq.c             |  6 +++++-
 5 files changed, 15 insertions(+), 54 deletions(-)

-- 
2.5.0



From paul.gortmaker at windriver.com  Wed Aug 19 14:48:09 2015
From: paul.gortmaker at windriver.com (Paul Gortmaker)
Date: Wed, 19 Aug 2015 17:48:09 -0400
Subject: [PATCH 5/5] drivers/tty: make serial 8250_lpc18xx.c Kconfig a tristate
In-Reply-To: <1440020889-12120-1-git-send-email-paul.gortmaker@windriver.com>
References: <1440020889-12120-1-git-send-email-paul.gortmaker@windriver.com>
Message-ID: <1440020889-12120-6-git-send-email-paul.gortmaker@windriver.com>

The Kconfig currently controlling compilation of this code is:

8250/Kconfig:config SERIAL_8250_LPC18XX
8250/Kconfig:        bool "NXP LPC18xx/43xx serial port support"

...meaning that it currently is not being built as a module by anyone.

When targetting orphaned modular code in non-modular drivers, this
came up.  Joachim indicated that the driver was actually meant to
be tristate but ended up bool by accident.  So here we make it
tristate instead of removing the modular code that was essentially
orphaned.

Suggested-by: Joachim Eastwood <manabian at gmail.com>
Cc: Greg Kroah-Hartman <gregkh at linuxfoundation.org>
Cc: Jiri Slaby <jslaby at suse.com>
Cc: Joachim Eastwood <manabian at gmail.com>
Cc: linux-serial at vger.kernel.org
Cc: linux-arm-kernel at lists.infradead.org
Signed-off-by: Paul Gortmaker <paul.gortmaker at windriver.com>
---
 drivers/tty/serial/8250/Kconfig | 2 +-
 1 file changed, 1 insertion(+), 1 deletion(-)

diff --git a/drivers/tty/serial/8250/Kconfig b/drivers/tty/serial/8250/Kconfig
index e1de1181b322..f5c4b01f6f1d 100644
--- a/drivers/tty/serial/8250/Kconfig
+++ b/drivers/tty/serial/8250/Kconfig
@@ -337,7 +337,7 @@ config SERIAL_8250_FINTEK
 	  through the PNP driver. If unsure, say N.
 
 config SERIAL_8250_LPC18XX
-	bool "NXP LPC18xx/43xx serial port support"
+	tristate "NXP LPC18xx/43xx serial port support"
 	depends on SERIAL_8250 && OF && (ARCH_LPC18XX || COMPILE_TEST)
 	default ARCH_LPC18XX
 	help
-- 
2.5.0



From moritz.fischer at ettus.com  Wed Aug 19 14:51:28 2015
From: moritz.fischer at ettus.com (Moritz Fischer)
Date: Wed, 19 Aug 2015 14:51:28 -0700
Subject: [RESEND PATCH] dmaengine: Add Xilinx AXI Direct Memory Access
 Engine driver support
In-Reply-To: <1439825512-16444-1-git-send-email-appanad@xilinx.com>
References: <1439825512-16444-1-git-send-email-appanad@xilinx.com>
Message-ID: <CAAtXAHf9S662okN1gchbD246=e4_bMFoyBMrbt5q48xm1uo_CA@mail.gmail.com>

Hi there,

see comment below. I just did a quick compile test. Will take another
look once I synthesized an image.

On Mon, Aug 17, 2015 at 8:31 AM, Kedareswara rao Appana
<appana.durga.rao at xilinx.com> wrote:
> This is the driver for the AXI Direct Memory Access (AXI DMA)
> core, which is a soft Xilinx IP core that provides high-
> bandwidth direct memory access between memory and AXI4-Stream
> type target peripherals.
>
> Signed-off-by: Srikanth Thokala <sthokal at xilinx.com>
> Signed-off-by: Kedareswara rao Appana <appanad at xilinx.com>
> ---
> The deivce tree doc got applied in the slave-dmaengine.git.
>
> Forgot to include dmaengine at vger.kernel.org in the cc list
> resending the patch.
>
> Changes in v8:
> - Updated the SG handling as suggested by Nicolae Rosia.
> - Removed the unnecessary xilinx_dma_channel_set_config API the properties
>   in this API is not being used by the driver.
> Changes in v7:
> - Updated license in the driver as suggested by Paul.
> - Corrected return value in is_idle funtion.
> Changes in v6:
> - Fixed Odd indention in the Kconfig.
> - used GFP_NOWAIT instead of GFP_KERNEL during the desc allocation
> - Calculated residue in the tx_status instead of complete_descriptor.
> - Update copy right to 2015.
> - Modified spin_lock handling moved the spin_lock to the appropriate functions
> (instead of xilinx_dma_start_transfer doing it xilinx_dma_issue_pending api).
> - device_control and declare slave caps updated as per newer APi's.
> Changes in v5:
> - Modified the xilinx_dma.h header file location to the
>   include/linux/dma/xilinx_dma.h
> Changes in v4:
> - Add direction field to DMA descriptor structure and removed from
>   channel structure to avoid duplication.
> - Check for DMA idle condition before changing the configuration.
> - Residue is being calculated in complete_descriptor() and is reported
>   to slave driver.
> Changes in v3:
> - Rebased on 3.16-rc7
> Changes in v2:
> - Simplified the logic to set SOP and APP words in prep_slave_sg().
> - Corrected function description comments to match the return type.
> - Fixed some minor comments as suggested by Andy.
>
>  drivers/dma/Kconfig             |   13 +
>  drivers/dma/xilinx/Makefile     |    1 +
>  drivers/dma/xilinx/xilinx_dma.c | 1179 +++++++++++++++++++++++++++++++++++++++
>  3 files changed, 1193 insertions(+)
>  create mode 100644 drivers/dma/xilinx/xilinx_dma.c
>
> diff --git a/drivers/dma/Kconfig b/drivers/dma/Kconfig
> index 88d474b..5e95f07 100644
> --- a/drivers/dma/Kconfig
> +++ b/drivers/dma/Kconfig
> @@ -507,4 +507,17 @@ config QCOM_BAM_DMA
>           Enable support for the QCOM BAM DMA controller.  This controller
>           provides DMA capabilities for a variety of on-chip devices.
>
> +config XILINX_DMA
> +        tristate "Xilinx AXI DMA Engine"
> +        depends on (ARCH_ZYNQ || MICROBLAZE)
> +        select DMA_ENGINE
> +        help
> +          Enable support for Xilinx AXI DMA Soft IP.
> +
> +          This engine provides high-bandwidth direct memory access
> +          between memory and AXI4-Stream type target peripherals.
> +          It has two stream interfaces/channels, Memory Mapped to
> +          Stream (MM2S) and Stream to Memory Mapped (S2MM) for the
> +          data transfers.
> +
>  endif
> diff --git a/drivers/dma/xilinx/Makefile b/drivers/dma/xilinx/Makefile
> index 3c4e9f2..6224a49 100644
> --- a/drivers/dma/xilinx/Makefile
> +++ b/drivers/dma/xilinx/Makefile
> @@ -1 +1,2 @@
>  obj-$(CONFIG_XILINX_VDMA) += xilinx_vdma.o
> +obj-$(CONFIG_XILINX_DMA) += xilinx_dma.o
> diff --git a/drivers/dma/xilinx/xilinx_dma.c b/drivers/dma/xilinx/xilinx_dma.c
> new file mode 100644
> index 0000000..a9be197
> --- /dev/null
> +++ b/drivers/dma/xilinx/xilinx_dma.c
> @@ -0,0 +1,1179 @@
> +/*
> + * DMA driver for Xilinx DMA Engine
> + *
> + * Copyright (C) 2010 - 2015 Xilinx, Inc. All rights reserved.
> + *
> + * Based on the Freescale DMA driver.
> + *
> + * Description:
> + *  The AXI DMA, is a soft IP, which provides high-bandwidth Direct Memory
> + *  Access between memory and AXI4-Stream-type target peripherals. It can be
> + *  configured to have one channel or two channels and if configured as two
> + *  channels, one is to transmit data from memory to a device and another is
> + *  to receive from a device.
> + *
> + * This 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.
> + */
> +
> +#include <linux/bitops.h>
> +#include <linux/dma/xilinx_dma.h>
> +#include <linux/init.h>
> +#include <linux/interrupt.h>
> +#include <linux/io.h>
> +#include <linux/module.h>
> +#include <linux/of_address.h>
> +#include <linux/of_dma.h>
> +#include <linux/of_irq.h>
> +#include <linux/of_platform.h>
> +#include <linux/slab.h>
> +
> +#include "../dmaengine.h"
> +
> +/* Register Offsets */
> +#define XILINX_DMA_REG_CONTROL         0x00
> +#define XILINX_DMA_REG_STATUS          0x04
> +#define XILINX_DMA_REG_CURDESC         0x08
> +#define XILINX_DMA_REG_TAILDESC                0x10
> +#define XILINX_DMA_REG_SRCADDR         0x18
> +#define XILINX_DMA_REG_DSTADDR         0x20
> +#define XILINX_DMA_REG_BTT             0x28
> +
> +/* Channel/Descriptor Offsets */
> +#define XILINX_DMA_MM2S_CTRL_OFFSET    0x00
> +#define XILINX_DMA_S2MM_CTRL_OFFSET    0x30
> +
> +/* General register bits definitions */
> +#define XILINX_DMA_CR_RUNSTOP_MASK     BIT(0)
> +#define XILINX_DMA_CR_RESET_MASK       BIT(2)
> +
> +#define XILINX_DMA_CR_DELAY_SHIFT      24
> +#define XILINX_DMA_CR_COALESCE_SHIFT   16
> +
> +#define XILINX_DMA_CR_DELAY_MAX                GENMASK(7, 0)
> +#define XILINX_DMA_CR_COALESCE_MAX     GENMASK(7, 0)
> +
> +#define XILINX_DMA_SR_HALTED_MASK      BIT(0)
> +#define XILINX_DMA_SR_IDLE_MASK                BIT(1)
> +
> +#define XILINX_DMA_XR_IRQ_IOC_MASK     BIT(12)
> +#define XILINX_DMA_XR_IRQ_DELAY_MASK   BIT(13)
> +#define XILINX_DMA_XR_IRQ_ERROR_MASK   BIT(14)
> +#define XILINX_DMA_XR_IRQ_ALL_MASK     GENMASK(14, 12)
> +
> +/* BD definitions */
> +#define XILINX_DMA_BD_STS_ALL_MASK     GENMASK(31, 28)
> +#define XILINX_DMA_BD_SOP              BIT(27)
> +#define XILINX_DMA_BD_EOP              BIT(26)
> +
> +/* Hw specific definitions */
> +#define XILINX_DMA_MAX_CHANS_PER_DEVICE        0x2
> +#define XILINX_DMA_MAX_TRANS_LEN       GENMASK(22, 0)
> +
> +/* Delay loop counter to prevent hardware failure */
> +#define XILINX_DMA_LOOP_COUNT          1000000
> +
> +/* Maximum number of Descriptors */
> +#define XILINX_DMA_NUM_DESCS           255
> +#define XILINX_DMA_COALESCE_MAX                255
> +#define XILINX_DMA_NUM_APP_WORDS       5
> +
> +/**
> + * struct xilinx_dma_desc_hw - Hardware Descriptor
> + * @next_desc: Next Descriptor Pointer @0x00
> + * @pad1: Reserved @0x04
> + * @buf_addr: Buffer address @0x08
> + * @pad2: Reserved @0x0C
> + * @pad3: Reserved @0x10
> + * @pad4: Reserved @0x14
> + * @control: Control field @0x18
> + * @status: Status field @0x1C
> + * @app: APP Fields @0x20 - 0x30
> + */
> +struct xilinx_dma_desc_hw {
> +       u32 next_desc;
> +       u32 pad1;
> +       u32 buf_addr;
> +       u32 pad2;
> +       u32 pad3;
> +       u32 pad4;
> +       u32 control;
> +       u32 status;
> +       u32 app[XILINX_DMA_NUM_APP_WORDS];
> +} __aligned(64);
> +
> +/**
> + * struct xilinx_dma_tx_segment - Descriptor segment
> + * @hw: Hardware descriptor
> + * @node: Node in the descriptor segments list
> + * @phys: Physical address of segment
> + */
> +struct xilinx_dma_tx_segment {
> +       struct xilinx_dma_desc_hw hw;
> +       struct list_head node;
> +       dma_addr_t phys;
> +} __aligned(64);
> +
> +/**
> + * struct xilinx_dma_tx_descriptor - Per Transaction structure
> + * @async_tx: Async transaction descriptor
> + * @segments: TX segments list
> + * @node: Node in the channel descriptors list
> + * @direction: Transfer direction
> + */
> +struct xilinx_dma_tx_descriptor {
> +       struct dma_async_tx_descriptor async_tx;
> +       struct list_head segments;
> +       struct list_head node;
> +       enum dma_transfer_direction direction;
> +};
> +
> +/**
> + * struct xilinx_dma_chan - Driver specific DMA channel structure
> + * @xdev: Driver specific device structure
> + * @ctrl_offset: Control registers offset
> + * @ctrl_reg: Control register value
> + * @lock: Descriptor operation lock
> + * @pending_list: Descriptors waiting
> + * @active_list: Descriptors ready to submit
> + * @done_list: Complete descriptors
> + * @free_seg_list: Free descriptors
> + * @common: DMA common channel
> + * @seg_v: Statically allocated segments base
> + * @seg_p: Physical allocated segments base
> + * @dev: The dma device
> + * @irq: Channel IRQ
> + * @id: Channel ID
> + * @has_sg: Support scatter transfers
> + * @idle: Check for channel idle
> + * @err: Channel has errors
> + * @tasklet: Cleanup work after irq
> + * @residue: Residue
> + * @desc_pendingcount: Descriptor pending count
> + */
> +struct xilinx_dma_chan {
> +       struct xilinx_dma_device *xdev;
> +       u32 ctrl_offset;
> +       u32 ctrl_reg;
> +       spinlock_t lock;
> +       struct list_head pending_list;
> +       struct list_head done_list;
> +       struct list_head active_list;
> +       struct list_head free_seg_list;
> +       struct dma_chan common;
> +       struct xilinx_dma_tx_segment *seg_v;
> +       dma_addr_t seg_p;
> +       struct device *dev;
> +       int irq;
> +       int id;
> +       bool has_sg;
> +       bool idle;
> +       int err;
> +       struct tasklet_struct tasklet;
> +       u32 residue;
> +       u32 desc_pendingcount;
> +};
> +
> +/**
> + * struct xilinx_dma_device - DMA device structure
> + * @regs: I/O mapped base address
> + * @dev: Device Structure
> + * @common: DMA device structure
> + * @chan: Driver specific DMA channel
> + * @has_sg: Specifies whether Scatter-Gather is present or not
> + */
> +struct xilinx_dma_device {
> +       void __iomem *regs;
> +       struct device *dev;
> +       struct dma_device common;
> +       struct xilinx_dma_chan *chan[XILINX_DMA_MAX_CHANS_PER_DEVICE];
> +       bool has_sg;
> +};
> +
> +/* Macros */
> +#define to_xilinx_chan(chan) \
> +       container_of(chan, struct xilinx_dma_chan, common)
> +#define to_dma_tx_descriptor(tx) \
> +       container_of(tx, struct xilinx_dma_tx_descriptor, async_tx)
> +
> +/* IO accessors */
> +static inline void dma_write(struct xilinx_dma_chan *chan, u32 reg, u32 value)
> +{
> +       iowrite32(value, chan->xdev->regs + reg);
Any reason to not use write here?
> +}
> +
> +static inline u32 dma_read(struct xilinx_dma_chan *chan, u32 reg)
> +{
> +       return ioread32(chan->xdev->regs + reg);
Any reason to not use readl here?
> +}
> +
> +static inline u32 dma_ctrl_read(struct xilinx_dma_chan *chan, u32 reg)
> +{
> +       return dma_read(chan, chan->ctrl_offset + reg);
> +}
> +
> +static inline void dma_ctrl_write(struct xilinx_dma_chan *chan, u32 reg,
> +                                 u32 value)
> +{
> +       dma_write(chan, chan->ctrl_offset + reg, value);
> +}
> +
> +/* -----------------------------------------------------------------------------
> + * Descriptors and segments alloc and free
> + */
> +
> +/**
> + * xilinx_dma_alloc_tx_segment - Allocate transaction segment
> + * @chan: Driver specific dma channel
> + *
> + * Return: The allocated segment on success and NULL on failure.
> + */
> +static struct xilinx_dma_tx_segment *
> +xilinx_dma_alloc_tx_segment(struct xilinx_dma_chan *chan)
> +{
> +       struct xilinx_dma_tx_segment *segment = NULL;
> +       unsigned long flags;
> +
> +       spin_lock_irqsave(&chan->lock, flags);
> +       if (!list_empty(&chan->free_seg_list)) {
> +               segment = list_first_entry(&chan->free_seg_list,
> +                                          struct xilinx_dma_tx_segment,
> +                                          node);
> +               list_del(&segment->node);
> +       }
> +       spin_unlock_irqrestore(&chan->lock, flags);
> +
> +       return segment;
> +}
> +
> +/**
> + * xilinx_dma_clean_hw_desc - Clean hardware descriptor
> + * @hw: HW descriptor to clean
> + */
> +static void xilinx_dma_clean_hw_desc(struct xilinx_dma_desc_hw *hw)
> +{
> +       u32 next_desc = hw->next_desc;
> +
> +       memset(hw, 0, sizeof(struct xilinx_dma_desc_hw));
> +
> +       hw->next_desc = next_desc;
> +}
> +
> +/**
> + * xilinx_dma_free_tx_segment - Free transaction segment
> + * @chan: Driver specific dma channel
> + * @segment: dma transaction segment
> + */
> +static void xilinx_dma_free_tx_segment(struct xilinx_dma_chan *chan,
> +                                      struct xilinx_dma_tx_segment *segment)
> +{
> +       xilinx_dma_clean_hw_desc(&segment->hw);
> +
> +       list_add_tail(&segment->node, &chan->free_seg_list);
> +}
> +
> +/**
> + * xilinx_dma_tx_descriptor - Allocate transaction descriptor
> + * @chan: Driver specific dma channel
> + *
> + * Return: The allocated descriptor on success and NULL on failure.
> + */
> +static struct xilinx_dma_tx_descriptor *
> +xilinx_dma_alloc_tx_descriptor(struct xilinx_dma_chan *chan)
> +{
> +       struct xilinx_dma_tx_descriptor *desc;
> +
> +       desc = kzalloc(sizeof(*desc), GFP_NOWAIT);
> +       if (!desc)
> +               return NULL;
> +
> +       INIT_LIST_HEAD(&desc->segments);
> +
> +       return desc;
> +}
> +
> +/**
> + * xilinx_dma_free_tx_descriptor - Free transaction descriptor
> + * @chan: Driver specific dma channel
> + * @desc: dma transaction descriptor
> + */
> +static void
> +xilinx_dma_free_tx_descriptor(struct xilinx_dma_chan *chan,
> +                             struct xilinx_dma_tx_descriptor *desc)
> +{
> +       struct xilinx_dma_tx_segment *segment, *next;
> +
> +       if (!desc)
> +               return;
> +
> +       list_for_each_entry_safe(segment, next, &desc->segments, node) {
> +               list_del(&segment->node);
> +               xilinx_dma_free_tx_segment(chan, segment);
> +       }
> +
> +       kfree(desc);
> +}
> +
> +/**
> + * xilinx_dma_alloc_chan_resources - Allocate channel resources
> + * @dchan: DMA channel
> + *
> + * Return: '0' on success and failure value on error
> + */
> +static int xilinx_dma_alloc_chan_resources(struct dma_chan *dchan)
> +{
> +       struct xilinx_dma_chan *chan = to_xilinx_chan(dchan);
> +       int i;
> +
> +       /* Allocate the buffer descriptors. */
> +       chan->seg_v = dma_zalloc_coherent(chan->dev,
> +                                         sizeof(*chan->seg_v) *
> +                                         XILINX_DMA_NUM_DESCS,
> +                                         &chan->seg_p, GFP_KERNEL);
> +       if (!chan->seg_v) {
> +               dev_err(chan->dev,
> +                       "unable to allocate channel %d descriptors\n",
> +                       chan->id);
> +               return -ENOMEM;
> +       }
> +
> +       for (i = 0; i < XILINX_DMA_NUM_DESCS; i++) {
> +               chan->seg_v[i].hw.next_desc =
> +                               chan->seg_p + sizeof(*chan->seg_v) *
> +                               ((i + 1) % XILINX_DMA_NUM_DESCS);
> +               chan->seg_v[i].phys =
> +                               chan->seg_p + sizeof(*chan->seg_v) * i;
> +               list_add_tail(&chan->seg_v[i].node, &chan->free_seg_list);
> +       }
> +
> +       dma_cookie_init(dchan);
> +
> +       /* Enable interrupts */
> +       chan->ctrl_reg |= XILINX_DMA_XR_IRQ_ALL_MASK;
> +       dma_ctrl_write(chan, XILINX_DMA_REG_CONTROL, chan->ctrl_reg);
> +
> +       return 0;
> +}
> +
> +/**
> + * xilinx_dma_free_desc_list - Free descriptors list
> + * @chan: Driver specific dma channel
> + * @list: List to parse and delete the descriptor
> + */
> +static void xilinx_dma_free_desc_list(struct xilinx_dma_chan *chan,
> +                                     struct list_head *list)
> +{
> +       struct xilinx_dma_tx_descriptor *desc, *next;
> +
> +       list_for_each_entry_safe(desc, next, list, node) {
> +               list_del(&desc->node);
> +               xilinx_dma_free_tx_descriptor(chan, desc);
> +       }
> +}
> +
> +/**
> + * xilinx_dma_free_descriptors - Free channel descriptors
> + * @chan: Driver specific dma channel
> + */
> +static void xilinx_dma_free_descriptors(struct xilinx_dma_chan *chan)
> +{
> +       unsigned long flags;
> +
> +       spin_lock_irqsave(&chan->lock, flags);
> +
> +       xilinx_dma_free_desc_list(chan, &chan->pending_list);
> +       xilinx_dma_free_desc_list(chan, &chan->done_list);
> +       xilinx_dma_free_desc_list(chan, &chan->active_list);
> +
> +       spin_unlock_irqrestore(&chan->lock, flags);
> +}
> +
> +/**
> + * xilinx_dma_free_chan_resources - Free channel resources
> + * @dchan: DMA channel
> + */
> +static void xilinx_dma_free_chan_resources(struct dma_chan *dchan)
> +{
> +       struct xilinx_dma_chan *chan = to_xilinx_chan(dchan);
> +
> +       xilinx_dma_free_descriptors(chan);
> +
> +       dma_free_coherent(chan->dev,
> +                         sizeof(*chan->seg_v) * XILINX_DMA_NUM_DESCS,
> +                         chan->seg_v, chan->seg_p);
> +}
> +
> +/**
> + * xilinx_dma_chan_desc_cleanup - Clean channel descriptors
> + * @chan: Driver specific dma channel
> + */
> +static void xilinx_dma_chan_desc_cleanup(struct xilinx_dma_chan *chan)
> +{
> +       struct xilinx_dma_tx_descriptor *desc;
> +       unsigned long flags;
> +
> +       spin_lock_irqsave(&chan->lock, flags);
> +
> +       while (!list_empty(&chan->done_list)) {
> +               dma_async_tx_callback callback;
> +               void *callback_param;
> +
> +               desc = list_first_entry(&chan->done_list,
> +                       struct xilinx_dma_tx_descriptor, node);
> +
> +               /* Remove from the list of running transactions */
> +               list_del(&desc->node);
> +
> +               /* Run the link descriptor callback function */
> +               callback = desc->async_tx.callback;
> +               callback_param = desc->async_tx.callback_param;
> +               if (callback) {
> +                       spin_unlock_irqrestore(&chan->lock, flags);
> +                       callback(callback_param);
> +                       spin_lock_irqsave(&chan->lock, flags);
> +               }
> +
> +               /* Run any dependencies, then free the descriptor */
> +               dma_run_dependencies(&desc->async_tx);
> +               xilinx_dma_free_tx_descriptor(chan, desc);
> +       }
> +
> +       spin_unlock_irqrestore(&chan->lock, flags);
> +}
> +
> +/**
> + * xilinx_dma_tx_status - Get dma transaction status
> + * @dchan: DMA channel
> + * @cookie: Transaction identifier
> + * @txstate: Transaction state
> + *
> + * Return: DMA transaction status
> + */
> +static enum dma_status xilinx_dma_tx_status(struct dma_chan *dchan,
> +                                           dma_cookie_t cookie,
> +                                           struct dma_tx_state *txstate)
> +{
> +       struct xilinx_dma_chan *chan = to_xilinx_chan(dchan);
> +       struct xilinx_dma_tx_descriptor *desc;
> +       struct xilinx_dma_tx_segment *segment;
> +       struct xilinx_dma_desc_hw *hw;
> +       enum dma_status ret;
> +       unsigned long flags;
> +       u32 residue;

While compiling this threw a residue may be used uninitialized warning,
I suppose 0 would be a sensible default value?
> +
> +       ret = dma_cookie_status(dchan, cookie, txstate);
> +       if (ret == DMA_COMPLETE || !txstate)
> +               return ret;
> +
> +       desc = list_last_entry(&chan->active_list,
> +                              struct xilinx_dma_tx_descriptor, node);
> +
> +       spin_lock_irqsave(&chan->lock, flags);
> +       if (chan->has_sg) {
> +               while (!list_empty(&desc->segments)) {
> +                       segment = list_first_entry(&desc->segments,
> +                                       struct xilinx_dma_tx_segment, node);
> +                       hw = &segment->hw;
> +                       residue += (hw->control - hw->status) &
> +                                  XILINX_DMA_MAX_TRANS_LEN;
> +               }
> +       }
> +
> +       chan->residue = residue;
> +       dma_set_residue(txstate, chan->residue);
> +       spin_unlock_irqrestore(&chan->lock, flags);
> +
> +       return ret;
> +}
> +
> +/**
> + * xilinx_dma_halt - Halt DMA channel
> + * @chan: Driver specific DMA channel
> + */
> +static void xilinx_dma_halt(struct xilinx_dma_chan *chan)
> +{
> +       int loop = XILINX_DMA_LOOP_COUNT;
> +
> +       chan->ctrl_reg &= ~XILINX_DMA_CR_RUNSTOP_MASK;
> +       dma_ctrl_write(chan, XILINX_DMA_REG_CONTROL, chan->ctrl_reg);
> +
> +       /* Wait for the hardware to halt */
> +       do {
> +               if (dma_ctrl_read(chan, XILINX_DMA_REG_STATUS) &
> +                       XILINX_DMA_SR_HALTED_MASK)
> +                       break;
> +       } while (loop--);
> +
> +       if (!loop) {
> +               dev_err(chan->dev, "Cannot stop channel %p: %x\n",
> +                       chan, dma_ctrl_read(chan, XILINX_DMA_REG_STATUS));
> +               chan->err = true;
> +       }
> +}
> +
> +/**
> + * xilinx_dma_start - Start DMA channel
> + * @chan: Driver specific DMA channel
> + */
> +static void xilinx_dma_start(struct xilinx_dma_chan *chan)
> +{
> +       int loop = XILINX_DMA_LOOP_COUNT;
> +
> +       chan->ctrl_reg |= XILINX_DMA_CR_RUNSTOP_MASK;
> +       dma_ctrl_write(chan, XILINX_DMA_REG_CONTROL, chan->ctrl_reg);
> +
> +       /* Wait for the hardware to start */
> +       do {
> +               if (!dma_ctrl_read(chan, XILINX_DMA_REG_STATUS) &
> +                       XILINX_DMA_SR_HALTED_MASK)
> +                       break;
> +       } while (loop--);
Maybe use one of the readx_poll_timeout functions?
> +
> +       if (!loop) {
> +               dev_err(chan->dev, "Cannot start channel %p: %x\n",
> +                        chan, dma_ctrl_read(chan, XILINX_DMA_REG_STATUS));
> +               chan->err = true;
> +       }
> +}
> +
> +/**
> + * xilinx_dma_start_transfer - Starts DMA transfer
> + * @chan: Driver specific channel struct pointer
> + */
> +static void xilinx_dma_start_transfer(struct xilinx_dma_chan *chan)
> +{
> +       struct xilinx_dma_tx_descriptor *head_desc, *tail_desc;
> +       struct xilinx_dma_tx_segment *tail_segment;
> +
> +       if (chan->err)
> +               return;
> +
> +       if (list_empty(&chan->pending_list))
> +               return;
> +
> +       if (!chan->idle)
> +               return;
> +
> +       head_desc = list_first_entry(&chan->pending_list,
> +                                    struct xilinx_dma_tx_descriptor, node);
> +       tail_desc = list_last_entry(&chan->pending_list,
> +                                   struct xilinx_dma_tx_descriptor, node);
> +       tail_segment = list_last_entry(&tail_desc->segments,
> +                                      struct xilinx_dma_tx_segment, node);
> +
> +       if (chan->desc_pendingcount <= XILINX_DMA_COALESCE_MAX) {
> +               chan->ctrl_reg &= ~XILINX_DMA_CR_COALESCE_MAX;
> +               chan->ctrl_reg |= chan->desc_pendingcount <<
> +                                 XILINX_DMA_CR_COALESCE_SHIFT;
> +               dma_ctrl_write(chan, XILINX_DMA_REG_CONTROL, chan->ctrl_reg);
> +       }
> +
> +       if (chan->has_sg)
> +               dma_ctrl_write(chan, XILINX_DMA_REG_CURDESC,
> +                              head_desc->async_tx.phys);
> +
> +       xilinx_dma_start(chan);
> +
> +       if (chan->err)
> +               return;
> +
> +       /* Start the transfer */
> +       if (chan->has_sg) {
> +               dma_ctrl_write(chan, XILINX_DMA_REG_TAILDESC,
> +                              tail_segment->phys);
> +       } else {
> +               struct xilinx_dma_tx_segment *segment;
> +               struct xilinx_dma_desc_hw *hw;
> +
> +               segment = list_first_entry(&head_desc->segments,
> +                                          struct xilinx_dma_tx_segment, node);
> +               hw = &segment->hw;
> +
> +               if (head_desc->direction == DMA_MEM_TO_DEV)
> +                       dma_ctrl_write(chan, XILINX_DMA_REG_SRCADDR,
> +                                      hw->buf_addr);
> +               else
> +                       dma_ctrl_write(chan, XILINX_DMA_REG_DSTADDR,
> +                                      hw->buf_addr);
> +
> +               /* Start the transfer */
> +               dma_ctrl_write(chan, XILINX_DMA_REG_BTT,
> +                              hw->control & XILINX_DMA_MAX_TRANS_LEN);
> +       }
> +
> +       list_splice_tail_init(&chan->pending_list, &chan->active_list);
> +       chan->desc_pendingcount = 0;
> +       chan->idle = false;
> +}
> +
> +/**
> + * xilinx_dma_issue_pending - Issue pending transactions
> + * @dchan: DMA channel
> + */
> +static void xilinx_dma_issue_pending(struct dma_chan *dchan)
> +{
> +       struct xilinx_dma_chan *chan = to_xilinx_chan(dchan);
> +       unsigned long flags;
> +
> +       spin_lock_irqsave(&chan->lock, flags);
> +       xilinx_dma_start_transfer(chan);
> +       spin_unlock_irqrestore(&chan->lock, flags);
> +}
> +
> +/**
> + * xilinx_dma_complete_descriptor - Mark the active descriptor as complete
> + * @chan : xilinx DMA channel
> + */
> +static void xilinx_dma_complete_descriptor(struct xilinx_dma_chan *chan)
> +{
> +       struct xilinx_dma_tx_descriptor *desc, *next;
> +
> +       if (list_empty(&chan->active_list))
> +               return;
> +
> +       list_for_each_entry_safe(desc, next, &chan->active_list, node) {
> +               list_del(&desc->node);
> +               dma_cookie_complete(&desc->async_tx);
> +               list_add_tail(&desc->node, &chan->done_list);
> +       }
> +}
> +
> +/**
> + * xilinx_dma_reset - Reset DMA channel
> + * @chan: Driver specific DMA channel
> + *
> + * Return: '0' on success and failure value on error
> + */
> +static int xilinx_dma_chan_reset(struct xilinx_dma_chan *chan)
> +{
> +       int loop = XILINX_DMA_LOOP_COUNT;
> +       u32 tmp;
> +
> +       chan->ctrl_reg = dma_ctrl_read(chan, XILINX_DMA_REG_CONTROL);
> +       dma_ctrl_write(chan, XILINX_DMA_REG_CONTROL, chan->ctrl_reg |
> +                      XILINX_DMA_CR_RESET_MASK);
> +
> +       tmp = dma_ctrl_read(chan, XILINX_DMA_REG_CONTROL) &
> +             XILINX_DMA_CR_RESET_MASK;
> +
> +       /* Wait for the hardware to finish reset */
> +       do {
> +               tmp = dma_ctrl_read(chan, XILINX_DMA_REG_CONTROL) &
> +                     XILINX_DMA_CR_RESET_MASK;
> +       } while (loop-- && tmp);
See above
> +
> +       if (!loop) {
> +               dev_err(chan->dev, "reset timeout, cr %x, sr %x\n",
> +                       dma_ctrl_read(chan, XILINX_DMA_REG_CONTROL),
> +                       dma_ctrl_read(chan, XILINX_DMA_REG_STATUS));
> +               return -EBUSY;
> +       }
> +
> +       chan->err = false;
> +
> +       return 0;
> +}
> +
> +/**
> + * xilinx_dma_irq_handler - DMA Interrupt handler
> + * @irq: IRQ number
> + * @data: Pointer to the Xilinx DMA channel structure
> + *
> + * Return: IRQ_HANDLED/IRQ_NONE
> + */
> +static irqreturn_t xilinx_dma_irq_handler(int irq, void *data)
> +{
> +       struct xilinx_dma_chan *chan = data;
> +       u32 status;
> +
> +       /* Read the status and ack the interrupts. */
> +       status = dma_ctrl_read(chan, XILINX_DMA_REG_STATUS);
> +       if (!(status & XILINX_DMA_XR_IRQ_ALL_MASK))
> +               return IRQ_NONE;
> +
> +       dma_ctrl_write(chan, XILINX_DMA_REG_STATUS,
> +                      status & XILINX_DMA_XR_IRQ_ALL_MASK);
> +
> +       if (status & XILINX_DMA_XR_IRQ_ERROR_MASK) {
> +               dev_err(chan->dev,
> +                       "Channel %p has errors %x, cdr %x tdr %x\n",
> +                       chan, dma_ctrl_read(chan, XILINX_DMA_REG_STATUS),
> +                       dma_ctrl_read(chan, XILINX_DMA_REG_CURDESC),
> +                       dma_ctrl_read(chan, XILINX_DMA_REG_TAILDESC));
> +               chan->err = true;
> +       }
> +
> +       /*
> +        * Device takes too long to do the transfer when user requires
> +        * responsiveness
> +        */
> +       if (status & XILINX_DMA_XR_IRQ_DELAY_MASK)
> +               dev_dbg(chan->dev, "Inter-packet latency too long\n");
> +
> +       if (status & XILINX_DMA_XR_IRQ_IOC_MASK) {
> +               spin_lock(&chan->lock);
> +               xilinx_dma_complete_descriptor(chan);
> +               chan->idle = true;
> +               xilinx_dma_start_transfer(chan);
> +               spin_unlock(&chan->lock);
> +       }
> +
> +       tasklet_schedule(&chan->tasklet);
> +       return IRQ_HANDLED;
> +}
> +
> +/**
> + * xilinx_dma_do_tasklet - Schedule completion tasklet
> + * @data: Pointer to the Xilinx dma channel structure
> + */
> +static void xilinx_dma_do_tasklet(unsigned long data)
> +{
> +       struct xilinx_dma_chan *chan = (struct xilinx_dma_chan *)data;
> +
> +       xilinx_dma_chan_desc_cleanup(chan);
> +}
> +
> +/**
> + * append_desc_queue - Queuing descriptor
> + * @chan: Driver specific dma channel
> + * @desc: dma transaction descriptor
> + */
> +static void append_desc_queue(struct xilinx_dma_chan *chan,
> +                             struct xilinx_dma_tx_descriptor *desc)
> +{
> +       struct xilinx_dma_tx_segment *tail_segment;
> +       struct xilinx_dma_tx_descriptor *tail_desc;
> +
> +       if (list_empty(&chan->pending_list))
> +               goto append;
> +
> +       /*
> +        * Add the hardware descriptor to the chain of hardware descriptors
> +        * that already exists in memory.
> +        */
> +       tail_desc = list_last_entry(&chan->pending_list,
> +                                   struct xilinx_dma_tx_descriptor, node);
> +       tail_segment = list_last_entry(&tail_desc->segments,
> +                                      struct xilinx_dma_tx_segment, node);
> +       tail_segment->hw.next_desc = (u32)desc->async_tx.phys;
> +
> +       /*
> +        * Add the software descriptor and all children to the list
> +        * of pending transactions
> +        */
> +append:
> +       list_add_tail(&desc->node, &chan->pending_list);
> +       chan->desc_pendingcount++;
> +
> +       if (unlikely(chan->desc_pendingcount > XILINX_DMA_COALESCE_MAX)) {
> +               dev_dbg(chan->dev, "desc pendingcount is too high\n");
> +               chan->desc_pendingcount = XILINX_DMA_COALESCE_MAX;
> +               BUG();
> +       }
> +}
> +
> +/**
> + * xilinx_dma_tx_submit - Submit DMA transaction
> + * @tx: Async transaction descriptor
> + *
> + * Return: cookie value on success and failure value on error
> + */
> +static dma_cookie_t xilinx_dma_tx_submit(struct dma_async_tx_descriptor *tx)
> +{
> +       struct xilinx_dma_tx_descriptor *desc = to_dma_tx_descriptor(tx);
> +       struct xilinx_dma_chan *chan = to_xilinx_chan(tx->chan);
> +       dma_cookie_t cookie;
> +       unsigned long flags;
> +       int err;
> +
> +       if (chan->err) {
> +               /*
> +                * If reset fails, need to hard reset the system.
> +                * Channel is no longer functional
> +                */
> +               err = xilinx_dma_chan_reset(chan);
> +               if (err < 0)
> +                       return err;
> +       }
> +
> +       spin_lock_irqsave(&chan->lock, flags);
> +
> +       cookie = dma_cookie_assign(tx);
> +
> +       /* Put this transaction onto the tail of the pending queue */
> +       append_desc_queue(chan, desc);
> +
> +       spin_unlock_irqrestore(&chan->lock, flags);
> +
> +       return cookie;
> +}
> +
> +/**
> + * xilinx_dma_prep_slave_sg - prepare descriptors for a DMA_SLAVE transaction
> + * @dchan: DMA channel
> + * @sgl: scatterlist to transfer to/from
> + * @sg_len: number of entries in @scatterlist
> + * @direction: DMA direction
> + * @flags: transfer ack flags
> + * @context: APP words of the descriptor
> + *
> + * Return: Async transaction descriptor on success and NULL on failure
> + */
> +static struct dma_async_tx_descriptor *xilinx_dma_prep_slave_sg(
> +       struct dma_chan *dchan, struct scatterlist *sgl, unsigned int sg_len,
> +       enum dma_transfer_direction direction, unsigned long flags,
> +       void *context)
> +{
> +       struct xilinx_dma_chan *chan = to_xilinx_chan(dchan);
> +       struct xilinx_dma_tx_descriptor *desc;
> +       struct xilinx_dma_tx_segment *segment;
> +       u32 *app_w = (u32 *)context;
> +       struct scatterlist *sg;
> +       size_t copy, sg_used;
> +       int i;
> +
> +       if (!is_slave_direction(direction))
> +               return NULL;
> +
> +       /* Allocate a transaction descriptor. */
> +       desc = xilinx_dma_alloc_tx_descriptor(chan);
> +       if (!desc)
> +               return NULL;
> +
> +       desc->direction = direction;
> +       dma_async_tx_descriptor_init(&desc->async_tx, &chan->common);
> +       desc->async_tx.tx_submit = xilinx_dma_tx_submit;
> +
> +       /* Build transactions using information in the scatter gather list */
> +       for_each_sg(sgl, sg, sg_len, i) {
> +               sg_used = 0;
> +
> +               /* Loop until the entire scatterlist entry is used */
> +               while (sg_used < sg_dma_len(sg)) {
> +                       struct xilinx_dma_desc_hw *hw;
> +
> +                       /* Get a free segment */
> +                       segment = xilinx_dma_alloc_tx_segment(chan);
> +                       if (!segment)
> +                               goto error;
> +
> +                       /*
> +                        * Calculate the maximum number of bytes to transfer,
> +                        * making sure it is less than the hw limit
> +                        */
> +                       copy = min_t(size_t, sg_dma_len(sg) - sg_used,
> +                                    XILINX_DMA_MAX_TRANS_LEN);
> +                       hw = &segment->hw;
> +
> +                       /* Fill in the descriptor */
> +                       hw->buf_addr = sg_dma_address(sg) + sg_used;
> +
> +                       hw->control = copy;
> +
> +                       if (direction == DMA_MEM_TO_DEV) {
> +                               if (app_w)
> +                                       memcpy(hw->app, app_w, sizeof(u32) *
> +                                              XILINX_DMA_NUM_APP_WORDS);
> +                       }
> +
> +                       sg_used += copy;
> +
> +                       /*
> +                        * Insert the segment into the descriptor segments
> +                        * list.
> +                        */
> +                       list_add_tail(&segment->node, &desc->segments);
> +               }
> +       }
> +
> +       segment = list_first_entry(&desc->segments,
> +                                  struct xilinx_dma_tx_segment, node);
> +       desc->async_tx.phys = segment->phys;
> +
> +       /* For the last DMA_MEM_TO_DEV transfer, set EOP */
> +       if (direction == DMA_MEM_TO_DEV) {
> +               segment->hw.control |= XILINX_DMA_BD_SOP;
> +               segment = list_last_entry(&desc->segments,
> +                                         struct xilinx_dma_tx_segment,
> +                                         node);
> +               segment->hw.control |= XILINX_DMA_BD_EOP;
> +       }
> +
> +       return &desc->async_tx;
> +
> +error:
> +       xilinx_dma_free_tx_descriptor(chan, desc);
> +       return NULL;
> +}
> +
> +/**
> + * xilinx_dma_terminate_all - Halt the channel and free descriptors
> + * @dchan: DMA Channel pointer
> + *
> + * Return: '0' always
> + */
> +static int xilinx_dma_terminate_all(struct dma_chan *dchan)
> +{
> +       struct xilinx_dma_chan *chan = to_xilinx_chan(dchan);
> +
> +       /* Halt the DMA engine */
> +       xilinx_dma_halt(chan);
> +
> +       /* Remove and free all of the descriptors in the lists */
> +       xilinx_dma_free_descriptors(chan);
> +
> +       return 0;
> +}
> +
> +/**
> + * xilinx_dma_chan_remove - Per Channel remove function
> + * @chan: Driver specific DMA channel
> + */
> +static void xilinx_dma_chan_remove(struct xilinx_dma_chan *chan)
> +{
> +       /* Disable interrupts */
> +       chan->ctrl_reg &= ~XILINX_DMA_XR_IRQ_ALL_MASK;
> +       dma_ctrl_write(chan, XILINX_DMA_REG_CONTROL, chan->ctrl_reg);
> +
> +       if (chan->irq > 0)
> +               free_irq(chan->irq, chan);
> +
> +       tasklet_kill(&chan->tasklet);
> +
> +       list_del(&chan->common.device_node);
> +}
> +
> +/**
> + * xilinx_dma_chan_probe - Per Channel Probing
> + * It get channel features from the device tree entry and
> + * initialize special channel handling routines
> + *
> + * @xdev: Driver specific device structure
> + * @node: Device node
> + *
> + * Return: '0' on success and failure value on error
> + */
> +static int xilinx_dma_chan_probe(struct xilinx_dma_device *xdev,
> +                                struct device_node *node)
> +{
> +       struct xilinx_dma_chan *chan;
> +       int err;
> +       bool has_dre;
> +       u32 value, width = 0;
> +
> +       /* alloc channel */
> +       chan = devm_kzalloc(xdev->dev, sizeof(*chan), GFP_KERNEL);
> +       if (!chan)
> +               return -ENOMEM;
> +
> +       chan->dev = xdev->dev;
> +       chan->xdev = xdev;
> +       chan->has_sg = xdev->has_sg;
> +       chan->desc_pendingcount = 0x0;
> +
> +       has_dre = of_property_read_bool(node, "xlnx,include-dre");
> +
> +       err = of_property_read_u32(node, "xlnx,datawidth", &value);
> +       if (err) {
> +               dev_err(xdev->dev, "unable to read datawidth property");
> +               return err;
> +       }
> +
> +       width = value >> 3; /* Convert bits to bytes */
> +
> +       /* If data width is greater than 8 bytes, DRE is not in hw */
> +       if (width > 8)
> +               has_dre = false;
> +
> +       if (!has_dre)
> +               xdev->common.copy_align = fls(width - 1);
> +
> +       if (of_device_is_compatible(node, "xlnx,axi-dma-mm2s-channel")) {
> +               chan->id = 0;
> +               chan->ctrl_offset = XILINX_DMA_MM2S_CTRL_OFFSET;
> +       } else if (of_device_is_compatible(node, "xlnx,axi-dma-s2mm-channel")) {
> +               chan->id = 1;
> +               chan->ctrl_offset = XILINX_DMA_S2MM_CTRL_OFFSET;
> +       } else {
> +               dev_err(xdev->dev, "Invalid channel compatible node\n");
> +               return -EINVAL;
> +       }
> +
> +       xdev->chan[chan->id] = chan;
> +
> +       /* Initialize the channel */
> +       err = xilinx_dma_chan_reset(chan);
> +       if (err) {
> +               dev_err(xdev->dev, "Reset channel failed\n");
> +               return err;
> +       }
> +
> +       spin_lock_init(&chan->lock);
> +       INIT_LIST_HEAD(&chan->pending_list);
> +       INIT_LIST_HEAD(&chan->done_list);
> +       INIT_LIST_HEAD(&chan->active_list);
> +       INIT_LIST_HEAD(&chan->free_seg_list);
> +
> +       chan->common.device = &xdev->common;
> +
> +       /* find the IRQ line, if it exists in the device tree */
> +       chan->irq = irq_of_parse_and_map(node, 0);
> +       err = request_irq(chan->irq, xilinx_dma_irq_handler,
> +                         IRQF_SHARED,
> +                         "xilinx-dma-controller", chan);
> +       if (err) {
> +               dev_err(xdev->dev, "unable to request IRQ %d\n", chan->irq);
> +               return err;
> +       }
> +
> +       /* Initialize the tasklet */
> +       tasklet_init(&chan->tasklet, xilinx_dma_do_tasklet,
> +                    (unsigned long)chan);
> +
> +       /* Add the channel to DMA device channel list */
> +       list_add_tail(&chan->common.device_node, &xdev->common.channels);
> +
> +       chan->idle = true;
> +
> +       return 0;
> +}
> +
> +/**
> + * of_dma_xilinx_xlate - Translation function
> + * @dma_spec: Pointer to DMA specifier as found in the device tree
> + * @ofdma: Pointer to DMA controller data
> + *
> + * Return: DMA channel pointer on success and NULL on error
> + */
> +static struct dma_chan *of_dma_xilinx_xlate(struct of_phandle_args *dma_spec,
> +                                           struct of_dma *ofdma)
> +{
> +       struct xilinx_dma_device *xdev = ofdma->of_dma_data;
> +       int chan_id = dma_spec->args[0];
> +
> +       if (chan_id >= XILINX_DMA_MAX_CHANS_PER_DEVICE)
> +               return NULL;
> +
> +       return dma_get_slave_channel(&xdev->chan[chan_id]->common);
> +}
> +
> +/**
> + * xilinx_dma_probe - Driver probe function
> + * @pdev: Pointer to the platform_device structure
> + *
> + * Return: '0' on success and failure value on error
> + */
> +static int xilinx_dma_probe(struct platform_device *pdev)
> +{
> +       struct xilinx_dma_device *xdev;
> +       struct device_node *child, *node;
> +       struct resource *res;
> +       int i, ret;
> +
> +       xdev = devm_kzalloc(&pdev->dev, sizeof(*xdev), GFP_KERNEL);
> +       if (!xdev)
> +               return -ENOMEM;
> +
> +       xdev->dev = &(pdev->dev);
> +       INIT_LIST_HEAD(&xdev->common.channels);
> +
> +       node = pdev->dev.of_node;
> +
> +       /* Map the registers */
> +       res = platform_get_resource(pdev, IORESOURCE_MEM, 0);
> +       xdev->regs = devm_ioremap_resource(&pdev->dev, res);
> +       if (IS_ERR(xdev->regs))
> +               return PTR_ERR(xdev->regs);
> +
> +       /* Check if SG is enabled */
> +       xdev->has_sg = of_property_read_bool(node, "xlnx,include-sg");
> +
> +       /* Axi DMA only do slave transfers */
> +       dma_cap_set(DMA_SLAVE, xdev->common.cap_mask);
> +       dma_cap_set(DMA_PRIVATE, xdev->common.cap_mask);
> +       xdev->common.device_prep_slave_sg = xilinx_dma_prep_slave_sg;
> +       xdev->common.device_terminate_all = xilinx_dma_terminate_all;
> +       xdev->common.device_issue_pending = xilinx_dma_issue_pending;
> +       xdev->common.device_alloc_chan_resources =
> +               xilinx_dma_alloc_chan_resources;
> +       xdev->common.device_free_chan_resources =
> +               xilinx_dma_free_chan_resources;
> +       xdev->common.device_tx_status = xilinx_dma_tx_status;
> +       xdev->common.directions = BIT(DMA_DEV_TO_MEM) | BIT(DMA_MEM_TO_DEV);
> +       xdev->common.residue_granularity = DMA_RESIDUE_GRANULARITY_SEGMENT;
> +       xdev->common.dev = &pdev->dev;
> +
> +       platform_set_drvdata(pdev, xdev);
> +
> +       for_each_child_of_node(node, child) {
> +               ret = xilinx_dma_chan_probe(xdev, child);
> +               if (ret) {
> +                       dev_err(&pdev->dev, "Probing channels failed\n");
> +                       goto free_chan_resources;
> +               }
> +       }
> +
> +       dma_async_device_register(&xdev->common);
> +
> +       ret = of_dma_controller_register(node, of_dma_xilinx_xlate, xdev);
> +       if (ret) {
> +               dev_err(&pdev->dev, "Unable to register DMA to DT\n");
> +               dma_async_device_unregister(&xdev->common);
> +               goto free_chan_resources;
> +       }
> +
> +       dev_info(&pdev->dev, "Xilinx AXI DMA Engine driver Probed!!\n");
> +
> +       return 0;
> +
> +free_chan_resources:
> +       for (i = 0; i < XILINX_DMA_MAX_CHANS_PER_DEVICE; i++)
> +               if (xdev->chan[i])
> +                       xilinx_dma_chan_remove(xdev->chan[i]);
> +
> +       return ret;
> +}
> +
> +/**
> + * xilinx_dma_remove - Driver remove function
> + * @pdev: Pointer to the platform_device structure
> + *
> + * Return: Always '0'
> + */
> +static int xilinx_dma_remove(struct platform_device *pdev)
> +{
> +       struct xilinx_dma_device *xdev = platform_get_drvdata(pdev);
> +       int i;
> +
> +       of_dma_controller_free(pdev->dev.of_node);
> +       dma_async_device_unregister(&xdev->common);
> +
> +       for (i = 0; i < XILINX_DMA_MAX_CHANS_PER_DEVICE; i++)
> +               if (xdev->chan[i])
> +                       xilinx_dma_chan_remove(xdev->chan[i]);
> +
> +       return 0;
> +}
> +
> +static const struct of_device_id xilinx_dma_of_match[] = {
> +       { .compatible = "xlnx,axi-dma-1.00.a",},
> +       {}
> +};
> +MODULE_DEVICE_TABLE(of, xilinx_dma_of_match);
> +
> +static struct platform_driver xilinx_dma_driver = {
> +       .driver = {
> +               .name = "xilinx-dma",
> +               .of_match_table = xilinx_dma_of_match,
> +       },
> +       .probe = xilinx_dma_probe,
> +       .remove = xilinx_dma_remove,
> +};
> +
> +module_platform_driver(xilinx_dma_driver);
> +
> +MODULE_AUTHOR("Xilinx, Inc.");
> +MODULE_DESCRIPTION("Xilinx DMA driver");
> +MODULE_LICENSE("GPL");
> --
> 2.1.2
>
>
> _______________________________________________
> linux-arm-kernel mailing list
> linux-arm-kernel at lists.infradead.org
> http://lists.infradead.org/mailman/listinfo/linux-arm-kernel

Cheers,

Moritz


From m.smarduch at samsung.com  Wed Aug 19 14:52:08 2015
From: m.smarduch at samsung.com (Mario Smarduch)
Date: Wed, 19 Aug 2015 14:52:08 -0700
Subject: [PATCH v4 1/2] arm64: KVM: Optimize arm64 skip 30-50% vfp/simd
 save/restore on exits
In-Reply-To: <20150819174958.GA11518@cbox>
References: <1437082178-11039-1-git-send-email-m.smarduch@samsung.com>
 <1437082178-11039-2-git-send-email-m.smarduch@samsung.com>
 <55C235B9.3000800@arm.com> <20150819174958.GA11518@cbox>
Message-ID: <55D4FA88.5060305@samsung.com>

Hi Christoffer,
   I'll test it and work with it.

Thanks,
  Mario

On 8/19/2015 10:49 AM, Christoffer Dall wrote:
> Hi Mario,
> 
> On Wed, Aug 05, 2015 at 05:11:37PM +0100, Marc Zyngier wrote:
>> On 16/07/15 22:29, Mario Smarduch wrote:
>>> This patch only saves and restores FP/SIMD registers on Guest access. To do
>>> this cptr_el2 FP/SIMD trap is set on Guest entry and later checked on exit.
>>> lmbench, hackbench show significant improvements, for 30-50% exits FP/SIMD
>>> context is not saved/restored
>>>
>>> Signed-off-by: Mario Smarduch <m.smarduch at samsung.com>
>>
>> So this patch seems to break 32bit guests on arm64.  I've had a look,
>> squashed a few bugs that I dangerously overlooked during the review, but
>> it still doesn't work (it doesn't crash anymore, but I get random
>> illegal VFP instructions in 32bit guests).
>>
>> I'd be glad if someone could eyeball the following patch and tell me
>> what's going wrong. If we don't find the root cause quickly enough, I'll
>> have to drop the series from -next, and that'd be a real shame.
>>
>> Thanks,
>>
>> 	M.
>>
>> commit 5777dc55fbc170426a85e00c26002dd5a795cfa5
>> Author: Marc Zyngier <marc.zyngier at arm.com>
>> Date:   Wed Aug 5 16:53:01 2015 +0100
>>
>>     KVM: arm64: NOTAFIX: Prevent crash when 32bit guest uses VFP
>>
>>     Since we switch FPSIMD in a lazy way, access to FPEXC32_EL2
>>     must be guarded by skip_fpsimd_state. Otherwise, all hell
>>     break loose.
>>
>>     Also, FPEXC32_EL2 must be restored when we trap to EL2 to
>>     enable floating point.
>>
>>     Note that while it prevents the host from catching fire, the
>>     guest still doesn't work properly, and I don't understand why just
>>     yet.
>>
>>     Not-really-signed-off-by: Marc Zyngier <marc.zyngier at arm.com>
>>
>> diff --git a/arch/arm64/kvm/hyp.S b/arch/arm64/kvm/hyp.S
>> index c8e0c70..b53ec5d 100644
>> --- a/arch/arm64/kvm/hyp.S
>> +++ b/arch/arm64/kvm/hyp.S
>> @@ -431,10 +431,12 @@
>>  	add	x3, x2, #CPU_SYSREG_OFFSET(DACR32_EL2)
>>  	mrs	x4, dacr32_el2
>>  	mrs	x5, ifsr32_el2
>> -	mrs	x6, fpexc32_el2
>>  	stp	x4, x5, [x3]
>> -	str	x6, [x3, #16]
>>
>> +	skip_fpsimd_state x8, 3f
>> +	mrs	x6, fpexc32_el2
>> +	str	x6, [x3, #16]
>> +3:
>>  	skip_debug_state x8, 2f
>>  	mrs	x7, dbgvcr32_el2
>>  	str	x7, [x3, #24]
>> @@ -461,10 +463,8 @@
>>
>>  	add	x3, x2, #CPU_SYSREG_OFFSET(DACR32_EL2)
>>  	ldp	x4, x5, [x3]
>> -	ldr	x6, [x3, #16]
>>  	msr	dacr32_el2, x4
>>  	msr	ifsr32_el2, x5
>> -	msr	fpexc32_el2, x6
>>
>>  	skip_debug_state x8, 2f
>>  	ldr	x7, [x3, #24]
>> @@ -669,12 +669,14 @@ __restore_debug:
>>  	ret
>>
>>  __save_fpsimd:
>> +	skip_fpsimd_state x3, 1f
>>  	save_fpsimd
>> -	ret
>> +1:	ret
>>
>>  __restore_fpsimd:
>> +	skip_fpsimd_state x3, 1f
>>  	restore_fpsimd
>> -	ret
>> +1:	ret
>>
>>  switch_to_guest_fpsimd:
>>  	push	x4, lr
>> @@ -682,6 +684,7 @@ switch_to_guest_fpsimd:
>>  	mrs	x2, cptr_el2
>>  	bic	x2, x2, #CPTR_EL2_TFP
>>  	msr	cptr_el2, x2
>> +	isb
>>
>>  	mrs	x0, tpidr_el2
>>
>> @@ -692,6 +695,10 @@ switch_to_guest_fpsimd:
>>  	add	x2, x0, #VCPU_CONTEXT
>>  	bl __restore_fpsimd
>>
>> +	skip_32bit_state x3, 1f
>> +	ldr	x4, [x2, #CPU_SYSREG_OFFSET(FPEXC32_EL2)]
>> +	msr	fpexc32_el2, x4
>> +1:
>>  	pop	x4, lr
>>  	pop	x2, x3
>>  	pop	x0, x1
>> @@ -754,9 +761,7 @@ __kvm_vcpu_return:
>>  	add	x2, x0, #VCPU_CONTEXT
>>
>>  	save_guest_regs
>> -	skip_fpsimd_state x3, 1f
>>  	bl __save_fpsimd
>> -1:
>>  	bl __save_sysregs
>>
>>  	skip_debug_state x3, 1f
>> @@ -777,9 +782,7 @@ __kvm_vcpu_return:
>>  	kern_hyp_va x2
>>
>>  	bl __restore_sysregs
>> -	skip_fpsimd_state x3, 1f
>>  	bl __restore_fpsimd
>> -1:
>>  	/* Clear FPSIMD and Trace trapping */
>>  	msr     cptr_el2, xzr
>>
>>
> 
> Marc and I have hunted down the issue at KVM Forum and we believe we've
> found the issue.  Please have a look at the following follow-up patch to
> Marc's patch above:
> 
> diff --git a/arch/arm64/kvm/hyp.S b/arch/arm64/kvm/hyp.S
> index 8b2a73b4..842e727 100644
> --- a/arch/arm64/kvm/hyp.S
> +++ b/arch/arm64/kvm/hyp.S
> @@ -769,11 +769,26 @@
>  
>  .macro activate_traps
>  	ldr     x2, [x0, #VCPU_HCR_EL2]
> +
> +	/*
> +	 * We are about to set CPTR_EL2.TFP to trap all floating point
> +	 * register accesses to EL2, however, the ARM ARM clearly states that
> +	 * traps are only taken to EL2 if the operation would not otherwise
> +	 * trap to EL1.  Therefore, always make sure that for 32-bit guests,
> +	 * we set FPEXC.EN to prevent traps to EL1, when setting the TFP bit.
> +	 */
> +	tbnz	x2, #HCR_RW_SHIFT, 99f // open code skip_32bit_state
> +	mov	x3, #(1 << 30)
> +	msr	fpexc32_el2, x3
> +	isb
> +99:
> +
>  	msr     hcr_el2, x2
>  	mov	x2, #CPTR_EL2_TTA
>  	orr     x2, x2, #CPTR_EL2_TFP
>  	msr	cptr_el2, x2
>  
> +
>  	mov	x2, #(1 << 15)	// Trap CP15 Cr=15
>  	msr	hstr_el2, x2
>  
> 
> 
> Thanks,
> -Christoffer
> 


From sergei.shtylyov at cogentembedded.com  Wed Aug 19 14:57:57 2015
From: sergei.shtylyov at cogentembedded.com (Sergei Shtylyov)
Date: Thu, 20 Aug 2015 00:57:57 +0300
Subject: [PATCH 0/2] Add R8A7794/SILK I2C device tree support
Message-ID: <2390854.nqPs17CVpc@wasted.cogentembedded.com>

Hello.

   Here's the set of 2 patches against Simon Horman's 'renesas.git' repo's
'renesas-devel-20150819-v4.2-rc7' tag. Here we add the I2C device tree support
for the R8A7794/SILK board.

[1/2] ARM: shmobile: r8a7794: add I2C DT support
[2/2] ARM: shmobile: silk: add I2C1 DT support

WBR, Sergei



From sergei.shtylyov at cogentembedded.com  Wed Aug 19 15:00:09 2015
From: sergei.shtylyov at cogentembedded.com (Sergei Shtylyov)
Date: Thu, 20 Aug 2015 01:00:09 +0300
Subject: [PATCH 1/2] ARM: shmobile: r8a7794: add I2C DT support
In-Reply-To: <2390854.nqPs17CVpc@wasted.cogentembedded.com>
References: <2390854.nqPs17CVpc@wasted.cogentembedded.com>
Message-ID: <1683106.jUSrvORJGA@wasted.cogentembedded.com>

Define the generic R8A7794 parts of the I2C[0-5] device nodes.

Based on the original patch by Koji Matsuoka <koji.matsuoka.xm at renesas.com>.

Signed-off-by: Sergei Shtylyov <sergei.shtylyov at cogentembedded.com>

---
 arch/arm/boot/dts/r8a7794.dtsi |   73 +++++++++++++++++++++++++++++++++++++++++
 1 file changed, 73 insertions(+)

Index: renesas/arch/arm/boot/dts/r8a7794.dtsi
===================================================================
--- renesas.orig/arch/arm/boot/dts/r8a7794.dtsi
+++ renesas/arch/arm/boot/dts/r8a7794.dtsi
@@ -20,6 +20,12 @@
 	#size-cells = <2>;
 
 	aliases {
+		i2c0 = &i2c0;
+		i2c1 = &i2c1;
+		i2c2 = &i2c2;
+		i2c3 = &i2c3;
+		i2c4 = &i2c4;
+		i2c5 = &i2c5;
 		spi0 = &qspi;
 	};
 
@@ -500,6 +506,73 @@
 		#address-cells = <1>;
 		#size-cells = <0>;
 		status = "disabled";
+	};
+
+	/* The memory map in the User's Manual maps the cores to bus numbers */
+	i2c0: i2c at e6508000 {
+		compatible = "renesas,i2c-r8a7794";
+		reg = <0 0xe6508000 0 0x40>;
+		interrupts = <0 287 IRQ_TYPE_LEVEL_HIGH>;
+		clocks = <&mstp9_clks R8A7794_CLK_I2C0>;
+		power-domains = <&cpg_clocks>;
+		#address-cells = <1>;
+		#size-cells = <0>;
+		status = "disabled";
+	};
+
+	i2c1: i2c at e6518000 {
+		compatible = "renesas,i2c-r8a7794";
+		reg = <0 0xe6518000 0 0x40>;
+		interrupts = <0 288 IRQ_TYPE_LEVEL_HIGH>;
+		clocks = <&mstp9_clks R8A7794_CLK_I2C1>;
+		power-domains = <&cpg_clocks>;
+		#address-cells = <1>;
+		#size-cells = <0>;
+		status = "disabled";
+	};
+
+	i2c2: i2c at e6530000 {
+		compatible = "renesas,i2c-r8a7794";
+		reg = <0 0xe6530000 0 0x40>;
+		interrupts = <0 286 IRQ_TYPE_LEVEL_HIGH>;
+		clocks = <&mstp9_clks R8A7794_CLK_I2C2>;
+		power-domains = <&cpg_clocks>;
+		#address-cells = <1>;
+		#size-cells = <0>;
+		status = "disabled";
+	};
+
+	i2c3: i2c at e6540000 {
+		compatible = "renesas,i2c-r8a7794";
+		reg = <0 0xe6540000 0 0x40>;
+		interrupts = <0 290 IRQ_TYPE_LEVEL_HIGH>;
+		clocks = <&mstp9_clks R8A7794_CLK_I2C3>;
+		power-domains = <&cpg_clocks>;
+		#address-cells = <1>;
+		#size-cells = <0>;
+		status = "disabled";
+	};
+
+	i2c4: i2c at e6520000 {
+		compatible = "renesas,i2c-r8a7794";
+		reg = <0 0xe6520000 0 0x40>;
+		interrupts = <0 19 IRQ_TYPE_LEVEL_HIGH>;
+		clocks = <&mstp9_clks R8A7794_CLK_I2C4>;
+		power-domains = <&cpg_clocks>;
+		#address-cells = <1>;
+		#size-cells = <0>;
+		status = "disabled";
+	};
+
+	i2c5: i2c at e6528000 {
+		compatible = "renesas,i2c-r8a7794";
+		reg = <0 0xe6528000 0 0x40>;
+		interrupts = <0 20 IRQ_TYPE_LEVEL_HIGH>;
+		clocks = <&mstp9_clks R8A7794_CLK_I2C5>;
+		power-domains = <&cpg_clocks>;
+		#address-cells = <1>;
+		#size-cells = <0>;
+		status = "disabled";
 	};
 
 	mmcif0: mmc at ee200000 {



From sergei.shtylyov at cogentembedded.com  Wed Aug 19 15:05:02 2015
From: sergei.shtylyov at cogentembedded.com (Sergei Shtylyov)
Date: Thu, 20 Aug 2015 01:05:02 +0300
Subject: [PATCH 2/2] ARM: shmobile: silk: add I2C1 DT support
In-Reply-To: <2390854.nqPs17CVpc@wasted.cogentembedded.com>
References: <2390854.nqPs17CVpc@wasted.cogentembedded.com>
Message-ID: <1624715.8TpWL8Dlnf@wasted.cogentembedded.com>

Define the SILK board dependent part of the I2C1 device node.

Signed-off-by: Sergei Shtylyov <sergei.shtylyov at cogentembedded.com>

---
 arch/arm/boot/dts/r8a7794-silk.dts |   13 +++++++++++++
 1 file changed, 13 insertions(+)

Index: renesas/arch/arm/boot/dts/r8a7794-silk.dts
===================================================================
--- renesas.orig/arch/arm/boot/dts/r8a7794-silk.dts
+++ renesas/arch/arm/boot/dts/r8a7794-silk.dts
@@ -85,6 +85,11 @@
 		renesas,function = "intc";
 	};
 
+	i2c1_pins: i2c1 {
+		renesas,groups = "i2c1";
+		renesas,function = "i2c1";
+	};
+
 	mmcif0_pins: mmcif0 {
 		renesas,groups = "mmc_data8", "mmc_ctrl";
 		renesas,function = "mmc";
@@ -124,6 +129,14 @@
 	};
 };
 
+&i2c1 {
+	pinctrl-0 = <&i2c1_pins>;
+	pinctrl-names = "default";
+
+	status = "okay";
+	clock-frequency = <400000>;
+};
+
 &mmcif0 {
 	pinctrl-0 = <&mmcif0_pins>;
 	pinctrl-names = "default";



From al.stone at linaro.org  Wed Aug 19 15:07:25 2015
From: al.stone at linaro.org (Al Stone)
Date: Wed, 19 Aug 2015 16:07:25 -0600
Subject: [PATCH v2 2/5] ACPI / ARM64: remove usage of
 BAD_MADT_ENTRY/BAD_MADT_GICC_ENTRY
In-Reply-To: <1440022048-6285-1-git-send-email-al.stone@linaro.org>
References: <1440022048-6285-1-git-send-email-al.stone@linaro.org>
Message-ID: <1440022048-6285-3-git-send-email-al.stone@linaro.org>

Now that we have introduced the bad_madt_entry() function, and that
function is being invoked in acpi_table_parse_madt() for us, there
is no longer any need to use the BAD_MADT_ENTRY macro, or in the case
of arm64, the BAD_MADT_GICC_ENTRY, too.

Signed-off-by: Al Stone <al.stone at linaro.org>
Acked-by: Catalin Marinas <catalin.marinas at arm.com>
Acked-by: Marc Zyngier <marc.zyngier at arm.com>
Cc: Will Deacon <will.deacon at arm.com>
Cc: Thomas Gleixner <tglx at linutronix.de>
Cc: Jason Cooper <jason at lakedaemon.net>
---
 arch/arm64/include/asm/acpi.h | 8 --------
 arch/arm64/kernel/smp.c       | 2 --
 drivers/irqchip/irq-gic.c     | 6 ------
 3 files changed, 16 deletions(-)

diff --git a/arch/arm64/include/asm/acpi.h b/arch/arm64/include/asm/acpi.h
index 208cec0..ed7e212 100644
--- a/arch/arm64/include/asm/acpi.h
+++ b/arch/arm64/include/asm/acpi.h
@@ -19,14 +19,6 @@
 #include <asm/cputype.h>
 #include <asm/smp_plat.h>
 
-/* Macros for consistency checks of the GICC subtable of MADT */
-#define ACPI_MADT_GICC_LENGTH	\
-	(acpi_gbl_FADT.header.revision < 6 ? 76 : 80)
-
-#define BAD_MADT_GICC_ENTRY(entry, end)						\
-	(!(entry) || (unsigned long)(entry) + sizeof(*(entry)) > (end) ||	\
-	 (entry)->header.length != ACPI_MADT_GICC_LENGTH)
-
 /* Basic configuration for ACPI */
 #ifdef	CONFIG_ACPI
 /* ACPI table mapping after acpi_gbl_permanent_mmap is set */
diff --git a/arch/arm64/kernel/smp.c b/arch/arm64/kernel/smp.c
index dbdaacd..66cc8c4 100644
--- a/arch/arm64/kernel/smp.c
+++ b/arch/arm64/kernel/smp.c
@@ -451,8 +451,6 @@ acpi_parse_gic_cpu_interface(struct acpi_subtable_header *header,
 	struct acpi_madt_generic_interrupt *processor;
 
 	processor = (struct acpi_madt_generic_interrupt *)header;
-	if (BAD_MADT_GICC_ENTRY(processor, end))
-		return -EINVAL;
 
 	acpi_table_print_madt_entry(header);
 
diff --git a/drivers/irqchip/irq-gic.c b/drivers/irqchip/irq-gic.c
index aa3e7b8..848c44c 100644
--- a/drivers/irqchip/irq-gic.c
+++ b/drivers/irqchip/irq-gic.c
@@ -1064,9 +1064,6 @@ gic_acpi_parse_madt_cpu(struct acpi_subtable_header *header,
 
 	processor = (struct acpi_madt_generic_interrupt *)header;
 
-	if (BAD_MADT_GICC_ENTRY(processor, end))
-		return -EINVAL;
-
 	/*
 	 * There is no support for non-banked GICv1/2 register in ACPI spec.
 	 * All CPU interface addresses have to be the same.
@@ -1088,9 +1085,6 @@ gic_acpi_parse_madt_distributor(struct acpi_subtable_header *header,
 
 	dist = (struct acpi_madt_generic_distributor *)header;
 
-	if (BAD_MADT_ENTRY(dist, end))
-		return -EINVAL;
-
 	dist_phy_base = dist->base_address;
 	return 0;
 }
-- 
2.4.3



From al.stone at linaro.org  Wed Aug 19 15:07:23 2015
From: al.stone at linaro.org (Al Stone)
Date: Wed, 19 Aug 2015 16:07:23 -0600
Subject: [PATCH v2 0/5] ACPI: Provide better MADT subtable sanity checks
Message-ID: <1440022048-6285-1-git-send-email-al.stone@linaro.org>

Currently, the BAD_MADT_ENTRY macro is used to do a very simple sanity
check on the various subtables that are defined for the MADT.  The check
compares the size of the subtable data structure as defined by ACPICA to
the length entry in the subtable.  If they are not the same, the assumption
is that the subtable is incorrect.

Over time, the ACPI spec has allowed for MADT subtables where this can
never be true (the local SAPIC subtable, for example).  Or, more recently,
the spec has accumulated some minor flaws where there are three possible 
sizes for a subtable, all of which are valid, but only for specific versions
of the spec (the GICC subtable).  In both cases, BAD_MADT_ENTRY reports these
subtables as bad when they are not.  In order to retain some sanity check
on the MADT subtables, we now have to special case these subtables.  Of
necessity, these special cases have ended up in arch-dependent code (arm64)
or an arch has simply decided to forgo the check (ia64).

This patch set replaces the BAD_MADT_ENTRY macro with a function called
bad_madt_entry().  This function uses a data set of details about the
subtables to provide more sanity checking than before:

	-- is the subtable legal for the version given in the FADT?

	-- is the subtable legal for the revision of the MADT in use?

	-- is the subtable of the proper length (including checking
	   on the one variable length subtable that is currently ignored),
	   given the FADT version and the MADT revision?

Further, this patch set adds in the call to bad_madt_entry() from the 
acpi_table_parse_madt() function, allowing it to be used consistently
by all architectures, for all subtables, and removing the need for each
of the subtable traversal callback functions to use BAD_MADT_ENTRY.

In theory, as the ACPI specification changes, we would only have to add
additional information to the data set describing the MADT subtables in
order to continue providing sanity checks, even when new subtables are
added.

These patches have been tested on an APM Mustang (arm64) and are known to
work there.  They have also been cross-compiled for x86 and ia64 with no
known failures.

Changes for v2:
   -- Acked-by on 2/5 from Marc Zyngier and Catalin Marinas for ARM
   -- Correct faulty end of loop test found by Timur Tabi

Al Stone (5):
  ACPI: add in a bad_madt_entry() function to eventually replace the
    macro
  ACPI / ARM64: remove usage of BAD_MADT_ENTRY/BAD_MADT_GICC_ENTRY
  ACPI / IA64: remove usage of BAD_MADT_ENTRY
  ACPI / X86: remove usage of BAD_MADT_ENTRY
  ACPI: remove definition of BAD_MADT_ENTRY macro

 arch/arm64/include/asm/acpi.h  |   8 --
 arch/arm64/kernel/perf_event.c |   3 -
 arch/arm64/kernel/smp.c        |   2 -
 arch/ia64/kernel/acpi.c        |  20 ----
 arch/x86/kernel/acpi/boot.c    |  27 -----
 drivers/acpi/tables.c          | 241 +++++++++++++++++++++++++++++++++++++++++
 drivers/irqchip/irq-gic-v2m.c  |   2 -
 drivers/irqchip/irq-gic.c      |   6 -
 include/linux/acpi.h           |   4 -
 9 files changed, 241 insertions(+), 72 deletions(-)

-- 
2.4.3



From al.stone at linaro.org  Wed Aug 19 15:07:24 2015
From: al.stone at linaro.org (Al Stone)
Date: Wed, 19 Aug 2015 16:07:24 -0600
Subject: [PATCH v2 1/5] ACPI: add in a bad_madt_entry() function to eventually
 replace the macro
In-Reply-To: <1440022048-6285-1-git-send-email-al.stone@linaro.org>
References: <1440022048-6285-1-git-send-email-al.stone@linaro.org>
Message-ID: <1440022048-6285-2-git-send-email-al.stone@linaro.org>

The existing BAD_MADT_ENTRY macro only checks that the size of the data
structure for an MADT subtable matches the length entry in the subtable.
This is, unfortunately, not reliable.  Nor, as it turns out, does it have
anything to do with what the length should be in any particular table.

We introduce the bad_madt_entry() function that uses a data set to
do some basic sanity checks on any given MADT subtable.  Over time, as
the spec changes, we should just be able to add entries to the data set
to reflect the changes.

What the data set captures is the allowed MADT subtable length for each
type of subtable, for each revision of the specification.  While there
is a revision number in the MADT that we should be able to use to figure
out the proper subtable length, it was not changed when subtables did.
And, while there is a major and minor revision in the FADT that could
also help, it was not always changed as the subtables changed either.
So, the data set captures for each published version of the ACPI spec
what the FADT revisions numbers should be, the corresponding MADT
revision number, and the subtable types and lengths that were defined
at that time.

The sanity checks done are:
	-- is the length non-zero?
	-- is the subtable type defined/allowed for the revision of
	   the FADT we're using?
	-- is the subtable type defined/allowed for the revision of
	   the MADT we're using?
	-- is the length entry what it should be for this revision
	   of the MADT and FADT?

These checks are more thorough than the previous macro provided, and
are now insulated from data structure size changes by ACPICA, which
have been the source of other patches in the past.

Now that the bad_madt_entry() function is available, we add code to
also invoke it before any subtable handlers are called to use the
info in the subtable.  Subsequent patches will remove the use of the
BAD_MADT_ENTRY macro which is now redundant as a result.  Any ACPI
functions that use acpi_parse_madt_entries() will always have all of
the MADT subtables checked from now on.

Signed-off-by: Al Stone <al.stone at linaro.org>
Cc: Rafael J. Wysocki <rjw at rjwysocki.net>
Cc: Len Brown <lenb at kernel.org>
---
 drivers/acpi/tables.c | 241 ++++++++++++++++++++++++++++++++++++++++++++++++++
 1 file changed, 241 insertions(+)

diff --git a/drivers/acpi/tables.c b/drivers/acpi/tables.c
index 17a6fa0..d1c0efc 100644
--- a/drivers/acpi/tables.c
+++ b/drivers/acpi/tables.c
@@ -210,6 +210,245 @@ void acpi_table_print_madt_entry(struct acpi_subtable_header *header)
 	}
 }
 
+/*
+ * The Long, Sad, True Story of the MADT
+ *    or
+ * What does bad_madt_entry() actually do?
+ *
+ * Once upon a time in ACPI 1.0, there was the MADT.  It was a nice table,
+ * and it had two subtables all of its own.  But, it was also a pretty
+ * busy table, too, so over time the MADT gathered up other nice little
+ * subtables.  By the time ACPI 6.0 came around, the MADT had 16 of the
+ * little guys.
+ *
+ * Now, the MADT kept a little counter around for the subtables.  In fact,
+ * it kept two counters: one was the revision level, which was supposed to
+ * change when new subtables came to be, or as the ones already around grew
+ * up. The second counter was a type number, because the MADT needed a unique
+ * type for each subtable so he could tell them apart.  But, sometimes the
+ * MADT got so busy, he forgot to increment the revision level when he needed
+ * to.  Fortunately, the type counter kept increasing since that's the only
+ * way the MADT could find each little subtable.  It just wouldn't do to have
+ * every subtable called Number 6.
+ *
+ * In the next valley over, a castle full of wizards was watching the MADT
+ * and made a pact to keep their own counter.  Every time the MADT found a
+ * new subtable, or a subtable grew up, the wizards promised they would
+ * increment their counter.  Well, wizards being the forgetful sort, they
+ * didn't alway do that.  And, since there quite a lot of them, they
+ * couldn't always remember who was supposed to keep track of the MADT,
+ * especially if dinner was coming up soon.  Their counter was called the
+ * spec version.
+ *
+ * Every now and then, the MADT would gather up all its little subtables
+ * and take them in to the cobbler to get new boots.  This was a very, very
+ * meticulous cobbler, so every time they came, he wrote down all the boot
+ * sizes for all of the little subtables.  The cobbler would ask each subtable
+ * for its length, check that against his careful notes, and then go get the
+ * right boots.  Sometimes, a little subtable would change a bit, and their
+ * length did not match what the cobbler had written down.  If the wizards
+ * or the MADT had incremented their counters, the cobbler would breath a
+ * sigh of relief and write down the new length as the right one.  But, if
+ * none of the counters had changed, this would make the cobbler very, very
+ * mad.  He couldn't tell if he had the right size boots or not for the
+ * little subtable.  He would have to *guess* and this really bugged him.
+ *
+ * Well, when the cobbler got mad like this, he would go into hiding.  He
+ * would not make or sell any boots.  He would not go out at all.  Pretty
+ * soon, the coffee shop would have to close because the cobbler wasn't
+ * coming by twice a day any more.  Then the grocery store would have to
+ * close because he wouldn't eat much.  After a while, everyone would panic
+ * and have to move from the village and go live with all their relatives
+ * (usually the ones they didn't like very much).
+ *
+ * Eventually, the cobbler would work his way out of his bad mood, and
+ * open up his boot business again.  Then, everyone else could move back
+ * to the village and restart their lives, too.
+ *
+ * Fortunately, we have been able to collect up all the cobbler's careful
+ * notes (and we wrote them down below).  We'll have to keep checking these
+ * notes over time, too, just as the cobbler does.  But, in the meantime,
+ * we can avoid the panic and the reboot since we can make sure that each
+ * subtable is doing okay.  And that's what bad_madt_entry() does.
+ *
+ *
+ * FADT Major Version ->       1    3    4     4     5     5     6
+ * FADT Minor Version ->       x    x    x     x     x     1     0
+ * MADT revision ->            1    1    2     3     3     3     3
+ * Spec Version ->            1.0  2.0  3.0b  4.0a  5.0b  5.1a  6.0
+ * Subtable Name	Type  Expected Length ->
+ * Processor Local APIC  0x0    8    8    8     8     8     8     8
+ * IO APIC               0x1   12   12   12    12    12    12    12
+ * Int Src Override      0x2        10   10    10    10    10    10
+ * NMI Src               0x3         8    8     8     8     8     8
+ * Local APIC NMI Struct 0x4         6    6     6     6     6     6
+ * Local APIC Addr Ovrrd 0x5        16   12    12    12    12    12
+ * IO SAPIC              0x6        20   16    16    16    16    16
+ * Local SAPIC           0x7         8  >16   >16   >16   >16   >16
+ * Platform Int Src      0x8        16   16    16    16    16    16
+ * Proc Local x2APIC     0x9                   16    16    16    16
+ * Local x2APIC NMI      0xa                   12    12    12    12
+ * GICC CPU I/F          0xb                         40    76    80
+ * GICD                  0xc                         24    24    24
+ * GICv2m MSI            0xd                               24    24
+ * GICR                  0xe                               16    16
+ * GIC ITS               0xf                                     16
+ *
+ * In the table, each length entry is what should be in the length
+ * field of the subtable, and -- in general -- it should match the
+ * size of the struct for the subtable.  Any value that is not set
+ * (i.e., is zero) indicates that the subtable is not defined for
+ * that version of the ACPI spec.
+ *
+ */
+#define SUBTABLE_UNDEFINED	0x00
+#define SUBTABLE_VARIABLE	0xff
+#define NUM_SUBTABLE_TYPES	16
+
+struct acpi_madt_subtable_lengths {
+	unsigned short major_version;	/* from revision in FADT header */
+	unsigned short minor_version;	/* FADT field starting with 5.1 */
+	unsigned short madt_version;	/* MADT revision */
+	unsigned short num_types;	/* types possible for this version */
+	unsigned short lengths[NUM_SUBTABLE_TYPES];
+					/* subtable lengths, indexed by type */
+};
+
+static struct acpi_madt_subtable_lengths spec_info[] = {
+	{ /* for ACPI 1.0 */
+		.major_version = 1,
+		.minor_version = 0,
+		.madt_version = 1,
+		.num_types = 2,
+		.lengths = { 8, 12 }
+	},
+	{ /* for ACPI 2.0 */
+		.major_version = 3,
+		.minor_version = 0,
+		.madt_version = 1,
+		.num_types = 9,
+		.lengths = { 8, 12, 10, 8, 6, 16, 20, 8, 16 }
+	},
+	{ /* for ACPI 3.0b */
+		.major_version = 4,
+		.minor_version = 0,
+		.madt_version = 2,
+		.num_types = 9,
+		.lengths = { 8, 12, 10, 8, 6, 12, 16, SUBTABLE_VARIABLE, 16 }
+	},
+	{ /* for ACPI 4.0a */
+		.major_version = 4,
+		.minor_version = 0,
+		.madt_version = 3,
+		.num_types = 11,
+		.lengths = { 8, 12, 10, 8, 6, 12, 16, SUBTABLE_VARIABLE,
+			     16, 16, 12 }
+	},
+	{ /* for ACPI 5.0b */
+		.major_version = 5,
+		.minor_version = 0,
+		.madt_version = 3,
+		.num_types = 13,
+		.lengths = { 8, 12, 10, 8, 6, 12, 16, SUBTABLE_VARIABLE,
+			     16, 16, 12, 40, 24 }
+	},
+	{ /* for ACPI 5.1a */
+		.major_version = 5,
+		.minor_version = 1,
+		.madt_version = 3,
+		.num_types = 15,
+		.lengths = { 8, 12, 10, 8, 6, 12, 16, SUBTABLE_VARIABLE,
+			     16, 16, 12, 76, 24, 24, 16 }
+	},
+	{ /* for ACPI 6.0 */
+		.major_version = 6,
+		.minor_version = 0,
+		.madt_version = 3,
+		.num_types = 16,
+		.lengths = { 8, 12, 10, 8, 6, 12, 16, SUBTABLE_VARIABLE,
+			     16, 16, 12, 80, 24, 24, 16, 16 }
+	},
+	{ /* terminator */
+		.major_version = 0,
+		.minor_version = 0,
+		.madt_version = 0,
+		.num_types = 0,
+		.lengths = { 0 }
+	}
+};
+
+int __init bad_madt_entry(struct acpi_table_header *table,
+			  struct acpi_subtable_header *entry)
+{
+	struct acpi_madt_subtable_lengths *ms;
+	struct acpi_table_madt *madt;
+	unsigned short major;
+	unsigned short minor;
+	unsigned short len;
+
+	/* simple sanity checking on MADT subtable entries */
+	if (!entry || !table)
+		return 1;
+
+	/* FADT minor numbers were not introduced until ACPI 5.1 */
+	major = acpi_gbl_FADT.header.revision;
+	if (major >= 5 && acpi_gbl_FADT.header.length >= 268)
+		minor = acpi_gbl_FADT.minor_revision;
+	else
+		minor = 0;
+
+	madt = (struct acpi_table_madt *)table;
+	ms = spec_info;
+	while (ms->num_types != 0) {
+		if (ms->major_version == major &&
+		    ms->minor_version == minor &&
+		    ms->madt_version == madt->header.revision)
+			break;
+		ms++;
+	}
+	if (!ms->num_types) {
+		pr_err("undefined FADT version: %d.%d\n", major, minor);
+		return 1;
+	}
+
+	if (entry->type >= ms->num_types) {
+		pr_err("undefined MADT subtable type for FADT %d.%d: %d (length %d)\n",
+		       major, minor, entry->type, entry->length);
+		return 1;
+	}
+
+	/* verify that the table is allowed for this version of the spec */
+	len = ms->lengths[entry->type];
+	if (!len) {
+		pr_err("MADT subtable %d not defined for FADT %d.%d\n",
+			 entry->type, major, minor);
+		return 1;
+	}
+
+	/* verify that the length is what we expect */
+	if (len == SUBTABLE_VARIABLE) {
+		if (entry->type == ACPI_MADT_TYPE_LOCAL_SAPIC) {
+			struct acpi_madt_local_sapic *lsapic =
+				(struct acpi_madt_local_sapic *)entry;
+
+			if (sizeof(struct acpi_madt_local_sapic) +
+			    strlen(lsapic->uid_string) + 1 != entry->length) {
+				pr_err("Variable length MADT subtable %d is wrong size: %d\n",
+				       entry->type, entry->length);
+				return 1;
+			}
+		}
+	} else {
+		if (entry->length != len) {
+			pr_err("MADT subtable %d is wrong size: %d\n",
+			       len, entry->type);
+			return 1;
+		}
+	}
+
+	return 0;
+}
+
 int __init
 acpi_parse_entries(char *id, unsigned long table_size,
 		acpi_tbl_entry_handler handler,
@@ -245,6 +484,8 @@ acpi_parse_entries(char *id, unsigned long table_size,
 	       table_end) {
 		if (entry->type == entry_id
 		    && (!max_entries || count < max_entries)) {
+			if (bad_madt_entry(table_header, entry))
+				return -EINVAL;
 			if (handler(entry, table_end))
 				return -EINVAL;
 
-- 
2.4.3



From al.stone at linaro.org  Wed Aug 19 15:07:26 2015
From: al.stone at linaro.org (Al Stone)
Date: Wed, 19 Aug 2015 16:07:26 -0600
Subject: [PATCH v2 3/5] ACPI / IA64: remove usage of BAD_MADT_ENTRY
In-Reply-To: <1440022048-6285-1-git-send-email-al.stone@linaro.org>
References: <1440022048-6285-1-git-send-email-al.stone@linaro.org>
Message-ID: <1440022048-6285-4-git-send-email-al.stone@linaro.org>

Now that we have introduced the bad_madt_entry() function, and that
function is being invoked in acpi_table_parse_madt() for us, there
is no longer any need to use the BAD_MADT_ENTRY macro.

Signed-off-by: Al Stone <al.stone at linaro.org>
Cc: Tony Luck <tony.luck at intel.com>
Cc: Fenghua Yu <fenghua.yu at intel.com>
---
 arch/ia64/kernel/acpi.c | 20 --------------------
 1 file changed, 20 deletions(-)

diff --git a/arch/ia64/kernel/acpi.c b/arch/ia64/kernel/acpi.c
index b1698bc..efa3f0a 100644
--- a/arch/ia64/kernel/acpi.c
+++ b/arch/ia64/kernel/acpi.c
@@ -184,9 +184,6 @@ acpi_parse_lapic_addr_ovr(struct acpi_subtable_header * header,
 
 	lapic = (struct acpi_madt_local_apic_override *)header;
 
-	if (BAD_MADT_ENTRY(lapic, end))
-		return -EINVAL;
-
 	if (lapic->address) {
 		iounmap(ipi_base_addr);
 		ipi_base_addr = ioremap(lapic->address, 0);
@@ -201,8 +198,6 @@ acpi_parse_lsapic(struct acpi_subtable_header * header, const unsigned long end)
 
 	lsapic = (struct acpi_madt_local_sapic *)header;
 
-	/*Skip BAD_MADT_ENTRY check, as lsapic size could vary */
-
 	if (lsapic->lapic_flags & ACPI_MADT_ENABLED) {
 #ifdef CONFIG_SMP
 		smp_boot_data.cpu_phys_id[available_cpus] =
@@ -222,9 +217,6 @@ acpi_parse_lapic_nmi(struct acpi_subtable_header * header, const unsigned long e
 
 	lacpi_nmi = (struct acpi_madt_local_apic_nmi *)header;
 
-	if (BAD_MADT_ENTRY(lacpi_nmi, end))
-		return -EINVAL;
-
 	/* TBD: Support lapic_nmi entries */
 	return 0;
 }
@@ -236,9 +228,6 @@ acpi_parse_iosapic(struct acpi_subtable_header * header, const unsigned long end
 
 	iosapic = (struct acpi_madt_io_sapic *)header;
 
-	if (BAD_MADT_ENTRY(iosapic, end))
-		return -EINVAL;
-
 	return iosapic_init(iosapic->address, iosapic->global_irq_base);
 }
 
@@ -253,9 +242,6 @@ acpi_parse_plat_int_src(struct acpi_subtable_header * header,
 
 	plintsrc = (struct acpi_madt_interrupt_source *)header;
 
-	if (BAD_MADT_ENTRY(plintsrc, end))
-		return -EINVAL;
-
 	/*
 	 * Get vector assignment for this interrupt, set attributes,
 	 * and program the IOSAPIC routing table.
@@ -336,9 +322,6 @@ acpi_parse_int_src_ovr(struct acpi_subtable_header * header,
 
 	p = (struct acpi_madt_interrupt_override *)header;
 
-	if (BAD_MADT_ENTRY(p, end))
-		return -EINVAL;
-
 	iosapic_override_isa_irq(p->source_irq, p->global_irq,
 				 ((p->inti_flags & ACPI_MADT_POLARITY_MASK) ==
 				  ACPI_MADT_POLARITY_ACTIVE_LOW) ?
@@ -356,9 +339,6 @@ acpi_parse_nmi_src(struct acpi_subtable_header * header, const unsigned long end
 
 	nmi_src = (struct acpi_madt_nmi_source *)header;
 
-	if (BAD_MADT_ENTRY(nmi_src, end))
-		return -EINVAL;
-
 	/* TBD: Support nimsrc entries */
 	return 0;
 }
-- 
2.4.3



From al.stone at linaro.org  Wed Aug 19 15:07:27 2015
From: al.stone at linaro.org (Al Stone)
Date: Wed, 19 Aug 2015 16:07:27 -0600
Subject: [PATCH v2 4/5] ACPI / X86: remove usage of BAD_MADT_ENTRY
In-Reply-To: <1440022048-6285-1-git-send-email-al.stone@linaro.org>
References: <1440022048-6285-1-git-send-email-al.stone@linaro.org>
Message-ID: <1440022048-6285-5-git-send-email-al.stone@linaro.org>

Now that we have introduced the bad_madt_entry() function, and that
function is being invoked in acpi_table_parse_madt() for us, there
is no longer any need to use the BAD_MADT_ENTRY macro.

Signed-off-by: Al Stone <al.stone at linaro.org>
Cc: Rafael J. Wysocki <rjw at rjwysocki.net>
Cc: Len Brown <len.brown at intel.com>
Cc: Pavel Machek <pavel at ucw.cz>
Cc: Thomas Gleixner <tglx at linutronix.de>
Cc: Ingo Molnar <mingo at redhat.com>
Cc: H. Peter Anvin <hpa at zytor.com>
Cc: x86 at kernel.org
---
 arch/x86/kernel/acpi/boot.c | 27 ---------------------------
 1 file changed, 27 deletions(-)

diff --git a/arch/x86/kernel/acpi/boot.c b/arch/x86/kernel/acpi/boot.c
index 75e8bad..f2a70b2 100644
--- a/arch/x86/kernel/acpi/boot.c
+++ b/arch/x86/kernel/acpi/boot.c
@@ -194,9 +194,6 @@ acpi_parse_x2apic(struct acpi_subtable_header *header, const unsigned long end)
 
 	processor = (struct acpi_madt_local_x2apic *)header;
 
-	if (BAD_MADT_ENTRY(processor, end))
-		return -EINVAL;
-
 	acpi_table_print_madt_entry(header);
 
 	apic_id = processor->local_apic_id;
@@ -227,9 +224,6 @@ acpi_parse_lapic(struct acpi_subtable_header * header, const unsigned long end)
 
 	processor = (struct acpi_madt_local_apic *)header;
 
-	if (BAD_MADT_ENTRY(processor, end))
-		return -EINVAL;
-
 	acpi_table_print_madt_entry(header);
 
 	/*
@@ -252,9 +246,6 @@ acpi_parse_sapic(struct acpi_subtable_header *header, const unsigned long end)
 
 	processor = (struct acpi_madt_local_sapic *)header;
 
-	if (BAD_MADT_ENTRY(processor, end))
-		return -EINVAL;
-
 	acpi_table_print_madt_entry(header);
 
 	acpi_register_lapic((processor->id << 8) | processor->eid,/* APIC ID */
@@ -271,9 +262,6 @@ acpi_parse_lapic_addr_ovr(struct acpi_subtable_header * header,
 
 	lapic_addr_ovr = (struct acpi_madt_local_apic_override *)header;
 
-	if (BAD_MADT_ENTRY(lapic_addr_ovr, end))
-		return -EINVAL;
-
 	acpi_lapic_addr = lapic_addr_ovr->address;
 
 	return 0;
@@ -287,9 +275,6 @@ acpi_parse_x2apic_nmi(struct acpi_subtable_header *header,
 
 	x2apic_nmi = (struct acpi_madt_local_x2apic_nmi *)header;
 
-	if (BAD_MADT_ENTRY(x2apic_nmi, end))
-		return -EINVAL;
-
 	acpi_table_print_madt_entry(header);
 
 	if (x2apic_nmi->lint != 1)
@@ -305,9 +290,6 @@ acpi_parse_lapic_nmi(struct acpi_subtable_header * header, const unsigned long e
 
 	lapic_nmi = (struct acpi_madt_local_apic_nmi *)header;
 
-	if (BAD_MADT_ENTRY(lapic_nmi, end))
-		return -EINVAL;
-
 	acpi_table_print_madt_entry(header);
 
 	if (lapic_nmi->lint != 1)
@@ -411,9 +393,6 @@ acpi_parse_ioapic(struct acpi_subtable_header * header, const unsigned long end)
 
 	ioapic = (struct acpi_madt_io_apic *)header;
 
-	if (BAD_MADT_ENTRY(ioapic, end))
-		return -EINVAL;
-
 	acpi_table_print_madt_entry(header);
 
 	/* Statically assign IRQ numbers for IOAPICs hosting legacy IRQs */
@@ -462,9 +441,6 @@ acpi_parse_int_src_ovr(struct acpi_subtable_header * header,
 
 	intsrc = (struct acpi_madt_interrupt_override *)header;
 
-	if (BAD_MADT_ENTRY(intsrc, end))
-		return -EINVAL;
-
 	acpi_table_print_madt_entry(header);
 
 	if (intsrc->source_irq == acpi_gbl_FADT.sci_interrupt) {
@@ -503,9 +479,6 @@ acpi_parse_nmi_src(struct acpi_subtable_header * header, const unsigned long end
 
 	nmi_src = (struct acpi_madt_nmi_source *)header;
 
-	if (BAD_MADT_ENTRY(nmi_src, end))
-		return -EINVAL;
-
 	acpi_table_print_madt_entry(header);
 
 	/* TBD: Support nimsrc entries? */
-- 
2.4.3



From al.stone at linaro.org  Wed Aug 19 15:07:28 2015
From: al.stone at linaro.org (Al Stone)
Date: Wed, 19 Aug 2015 16:07:28 -0600
Subject: [PATCH v2 5/5] ACPI: remove definition of BAD_MADT_ENTRY macro
In-Reply-To: <1440022048-6285-1-git-send-email-al.stone@linaro.org>
References: <1440022048-6285-1-git-send-email-al.stone@linaro.org>
Message-ID: <1440022048-6285-6-git-send-email-al.stone@linaro.org>

Now that we have introduced to bad_madt_entry(), and we have removed
all the usages of the BAD_MADT_ENTRY macro from all of the various
architectures that use it (arm64, ia64, x86), we can remove the macro
definition since it is no longer used.

Signed-off-by: Al Stone <al.stone at linaro.org>
Cc: Rafael J. Wysocki <rjw at rjwysocki.net>
Cc: Len Brown <lenb at kernel.org>
---
 include/linux/acpi.h | 4 ----
 1 file changed, 4 deletions(-)

diff --git a/include/linux/acpi.h b/include/linux/acpi.h
index 01e6770..96729d3 100644
--- a/include/linux/acpi.h
+++ b/include/linux/acpi.h
@@ -127,10 +127,6 @@ static inline void acpi_initrd_override(void *data, size_t size)
 }
 #endif
 
-#define BAD_MADT_ENTRY(entry, end) (					    \
-		(!entry) || (unsigned long)entry + sizeof(*entry) > end ||  \
-		((struct acpi_subtable_header *)entry)->length < sizeof(*entry))
-
 char * __acpi_map_table (unsigned long phys_addr, unsigned long size);
 void __acpi_unmap_table(char *map, unsigned long size);
 int early_acpi_boot_init(void);
-- 
2.4.3



From sergei.shtylyov at cogentembedded.com  Wed Aug 19 15:08:33 2015
From: sergei.shtylyov at cogentembedded.com (Sergei Shtylyov)
Date: Thu, 20 Aug 2015 01:08:33 +0300
Subject: [PATCH 0/2] Add R8A7794/SILK I2C device tree support
In-Reply-To: <2390854.nqPs17CVpc@wasted.cogentembedded.com>
References: <2390854.nqPs17CVpc@wasted.cogentembedded.com>
Message-ID: <55D4FE61.5010800@cogentembedded.com>

On 08/20/2015 12:57 AM, Sergei Shtylyov wrote:

>     Here's the set of 2 patches against Simon Horman's 'renesas.git' repo's
> 'renesas-devel-20150819-v4.2-rc7' tag. Here we add the I2C device tree support
> for the R8A7794/SILK board.
>
> [1/2] ARM: shmobile: r8a7794: add I2C DT support
> [2/2] ARM: shmobile: silk: add I2C1 DT support

    Simon, actually the above patch is atop of my SILK SDHI1 patch but should 
apply with offsets atop of your tag.

MBR, Sergei



From briannorris at chromium.org  Wed Aug 19 15:18:39 2015
From: briannorris at chromium.org (Brian Norris)
Date: Wed, 19 Aug 2015 15:18:39 -0700
Subject: [PATCH v2 1/3] ARM: dts: rockchip: add veyron-jaq board
Message-ID: <1440022721-73712-1-git-send-email-briannorris@chromium.org>

a.k.a. Haier Chromebook 11

Signed-off-by: Brian Norris <briannorris at chromium.org>
Cc: Alexandru M Stan <amstan at chromium.org>
Cc: Douglas Anderson <dianders at chromium.org>
---
v1 -> v2:
 - add overlooked DT binding doc
 - fixup regulator suspend state for LDO_REG2

 Documentation/devicetree/bindings/arm/rockchip.txt |   7 +
 arch/arm/boot/dts/Makefile                         |   1 +
 arch/arm/boot/dts/rk3288-veyron-jaq.dts            | 176 +++++++++++++++++++++
 3 files changed, 184 insertions(+)
 create mode 100644 arch/arm/boot/dts/rk3288-veyron-jaq.dts

diff --git a/Documentation/devicetree/bindings/arm/rockchip.txt b/Documentation/devicetree/bindings/arm/rockchip.txt
index af58cd74aeff..7fc7cf5c79d2 100644
--- a/Documentation/devicetree/bindings/arm/rockchip.txt
+++ b/Documentation/devicetree/bindings/arm/rockchip.txt
@@ -31,6 +31,13 @@ Rockchip platforms device tree bindings
     Required root node properties:
       - compatible = "netxeon,r89", "rockchip,rk3288";
 
+- Google Jaq (Haier Chromebook 11):
+    Required root node properties:
+      - compatible = "google,veyron-jaq-rev5", "google,veyron-jaq-rev4",
+		     "google,veyron-jaq-rev3", "google,veyron-jaq-rev2",
+		     "google,veyron-jaq-rev1", "google,veyron-jaq",
+		     "google,veyron", "rockchip,rk3288";
+
 - Google Jerry (Hisense Chromebook C11 and more):
     Required root node properties:
       - compatible = "google,veyron-jerry-rev7", "google,veyron-jerry-rev6",
diff --git a/arch/arm/boot/dts/Makefile b/arch/arm/boot/dts/Makefile
index 7805a6541a38..a08ca6c3d76e 100644
--- a/arch/arm/boot/dts/Makefile
+++ b/arch/arm/boot/dts/Makefile
@@ -490,6 +490,7 @@ dtb-$(CONFIG_ARCH_ROCKCHIP) += \
 	rk3288-firefly-beta.dtb \
 	rk3288-firefly.dtb \
 	rk3288-r89.dtb \
+	rk3288-veyron-jaq.dtb \
 	rk3288-veyron-jerry.dtb \
 	rk3288-veyron-minnie.dtb \
 	rk3288-veyron-pinky.dtb \
diff --git a/arch/arm/boot/dts/rk3288-veyron-jaq.dts b/arch/arm/boot/dts/rk3288-veyron-jaq.dts
new file mode 100644
index 000000000000..c2f52cfb4d06
--- /dev/null
+++ b/arch/arm/boot/dts/rk3288-veyron-jaq.dts
@@ -0,0 +1,176 @@
+/*
+ * Google Veyron Jaq Rev 1+ board device tree source
+ *
+ * Copyright 2015 Google, Inc
+ *
+ * This file is dual-licensed: you can use it either under the terms
+ * of the GPL or the X11 license, at your option. Note that this dual
+ * licensing only applies to this file, and not this project as a
+ * whole.
+ *
+ *  a) This file is free software; you can redistribute it and/or
+ *     modify it under the terms of the GNU General Public License as
+ *     published by the Free Software Foundation; either version 2 of the
+ *     License, or (at your option) any later version.
+ *
+ *     This file is distributed in the hope that it will be useful,
+ *     but WITHOUT ANY WARRANTY; without even the implied warranty of
+ *     MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ *     GNU General Public License for more details.
+ *
+ *  Or, alternatively,
+ *
+ *  b) Permission is hereby granted, free of charge, to any person
+ *     obtaining a copy of this software and associated documentation
+ *     files (the "Software"), to deal in the Software without
+ *     restriction, including without limitation the rights to use,
+ *     copy, modify, merge, publish, distribute, sublicense, and/or
+ *     sell copies of the Software, and to permit persons to whom the
+ *     Software is furnished to do so, subject to the following
+ *     conditions:
+ *
+ *     The above copyright notice and this permission notice shall be
+ *     included in all copies or substantial portions of the Software.
+ *
+ *     THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
+ *     EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES
+ *     OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
+ *     NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT
+ *     HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY,
+ *     WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
+ *     FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR
+ *     OTHER DEALINGS IN THE SOFTWARE.
+ */
+
+/dts-v1/;
+
+#include "rk3288-veyron-chromebook.dtsi"
+#include "cros-ec-sbs.dtsi"
+
+/ {
+	model = "Google Jaq";
+	compatible = "google,veyron-jaq-rev5", "google,veyron-jaq-rev4",
+		     "google,veyron-jaq-rev3", "google,veyron-jaq-rev2",
+		     "google,veyron-jaq-rev1", "google,veyron-jaq",
+		     "google,veyron", "rockchip,rk3288";
+
+	panel_regulator: panel-regulator {
+		compatible = "regulator-fixed";
+		enable-active-high;
+		gpio = <&gpio7 14 GPIO_ACTIVE_HIGH>;
+		pinctrl-names = "default";
+		pinctrl-0 = <&lcd_enable_h>;
+		regulator-name = "panel_regulator";
+		vin-supply = <&vcc33_sys>;
+	};
+
+	vcc18_lcd: vcc18-lcd {
+		compatible = "regulator-fixed";
+		enable-active-high;
+		gpio = <&gpio2 13 GPIO_ACTIVE_HIGH>;
+		pinctrl-names = "default";
+		pinctrl-0 = <&avdd_1v8_disp_en>;
+		regulator-name = "vcc18_lcd";
+		regulator-always-on;
+		regulator-boot-on;
+		vin-supply = <&vcc18_wl>;
+	};
+
+	backlight_regulator: backlight-regulator {
+		compatible = "regulator-fixed";
+		enable-active-high;
+		gpio = <&gpio2 12 GPIO_ACTIVE_HIGH>;
+		pinctrl-names = "default";
+		pinctrl-0 = <&bl_pwr_en>;
+		regulator-name = "backlight_regulator";
+		vin-supply = <&vcc33_sys>;
+		startup-delay-us = <15000>;
+	};
+};
+
+&rk808 {
+	pinctrl-names = "default";
+	pinctrl-0 = <&pmic_int_l &dvs_1 &dvs_2>;
+	dvs-gpios = <&gpio7 12 GPIO_ACTIVE_HIGH>,
+		    <&gpio7 15 GPIO_ACTIVE_HIGH>;
+
+	regulators {
+		mic_vcc: LDO_REG2 {
+			regulator-name = "mic_vcc";
+			regulator-always-on;
+			regulator-boot-on;
+			regulator-min-microvolt = <1800000>;
+			regulator-max-microvolt = <1800000>;
+			regulator-state-mem {
+				regulator-off-in-suspend;
+			};
+		};
+	};
+};
+
+&sdmmc {
+	disable-wp;
+	pinctrl-names = "default";
+	pinctrl-0 = <&sdmmc_clk &sdmmc_cmd &sdmmc_cd_disabled &sdmmc_cd_gpio
+			&sdmmc_bus4>;
+};
+
+&vcc_5v {
+	enable-active-high;
+	gpio = <&gpio7 21 GPIO_ACTIVE_HIGH>;
+	pinctrl-names = "default";
+	pinctrl-0 = <&drv_5v>;
+};
+
+&vcc50_hdmi {
+	enable-active-high;
+	gpio = <&gpio5 19 GPIO_ACTIVE_HIGH>;
+	pinctrl-names = "default";
+	pinctrl-0 = <&vcc50_hdmi_en>;
+};
+
+&pinctrl {
+	backlight {
+		bl_pwr_en: bl_pwr_en {
+			rockchip,pins = <2 12 RK_FUNC_GPIO &pcfg_pull_none>;
+		};
+	};
+
+	buck-5v {
+		drv_5v: drv-5v {
+			rockchip,pins = <7 21 RK_FUNC_GPIO &pcfg_pull_none>;
+		};
+	};
+
+	edp {
+		edp_hpd: edp_hpd {
+			rockchip,pins = <7 11 RK_FUNC_2 &pcfg_pull_down>;
+		};
+	};
+
+	hdmi {
+		vcc50_hdmi_en: vcc50-hdmi-en {
+			rockchip,pins = <5 19 RK_FUNC_GPIO &pcfg_pull_none>;
+		};
+	};
+
+	lcd {
+		lcd_enable_h: lcd-en {
+			rockchip,pins = <7 14 RK_FUNC_GPIO &pcfg_pull_none>;
+		};
+
+		avdd_1v8_disp_en: avdd-1v8-disp-en {
+			rockchip,pins = <2 13 RK_FUNC_GPIO &pcfg_pull_none>;
+		};
+	};
+
+	pmic {
+		dvs_1: dvs-1 {
+			rockchip,pins = <7 12 RK_FUNC_GPIO &pcfg_pull_down>;
+		};
+
+		dvs_2: dvs-2 {
+			rockchip,pins = <7 15 RK_FUNC_GPIO &pcfg_pull_down>;
+		};
+	};
+};
-- 
2.5.0.276.gf5e568e



From briannorris at chromium.org  Wed Aug 19 15:18:40 2015
From: briannorris at chromium.org (Brian Norris)
Date: Wed, 19 Aug 2015 15:18:40 -0700
Subject: [PATCH v2 2/3] ARM: dts: rockchip: correct regulator PM properties
In-Reply-To: <1440022721-73712-1-git-send-email-briannorris@chromium.org>
References: <1440022721-73712-1-git-send-email-briannorris@chromium.org>
Message-ID: <1440022721-73712-2-git-send-email-briannorris@chromium.org>

This DTS file was submitted with non-upstream bindings. I happened
across this while reviewing the jaq DTS.

Signed-off-by: Brian Norris <briannorris at chromium.org>
Cc: Alexandru M Stan <amstan at chromium.org>
Cc: Douglas Anderson <dianders at chromium.org>
---
Did not test minnie

v1 -> v2:
 - use "off-in-suspend", as that's the equivalent to the downstream
   'regulator-suspend-mem-disabled'

 arch/arm/boot/dts/rk3288-veyron-minnie.dts | 8 ++++++--
 1 file changed, 6 insertions(+), 2 deletions(-)

diff --git a/arch/arm/boot/dts/rk3288-veyron-minnie.dts b/arch/arm/boot/dts/rk3288-veyron-minnie.dts
index 0e30bd6bf92b..8fd8ef2c72da 100644
--- a/arch/arm/boot/dts/rk3288-veyron-minnie.dts
+++ b/arch/arm/boot/dts/rk3288-veyron-minnie.dts
@@ -128,12 +128,16 @@
 			regulator-min-microvolt = <3300000>;
 			regulator-max-microvolt = <3300000>;
 			regulator-name = "vcc33_touch";
-			regulator-suspend-mem-disabled;
+			regulator-state-mem {
+				regulator-off-in-suspend;
+			};
 		};
 
 		vcc5v_touch: SWITCH_REG2 {
 			regulator-name = "vcc5v_touch";
-			regulator-suspend-mem-disabled;
+			regulator-state-mem {
+				regulator-off-in-suspend;
+			};
 		};
 	};
 };
-- 
2.5.0.276.gf5e568e



From briannorris at chromium.org  Wed Aug 19 15:18:41 2015
From: briannorris at chromium.org (Brian Norris)
Date: Wed, 19 Aug 2015 15:18:41 -0700
Subject: [PATCH v2 3/3] ARM: dts: rockchip: correct regulator power states for
 suspend
In-Reply-To: <1440022721-73712-1-git-send-email-briannorris@chromium.org>
References: <1440022721-73712-1-git-send-email-briannorris@chromium.org>
Message-ID: <1440022721-73712-3-git-send-email-briannorris@chromium.org>

When getting translated from a downstream device tree that used slightly
different DT bindings, these regulators got labeled with the
"on-in-suspend" state, when they were actually supposed to be turned off
for S3 suspend. This was harmless, but not intentional, AFAICT.

Let's turn them off to get the optimal power state.

Signed-off-by: Brian Norris <briannorris at chromium.org>
Cc: Alexandru M Stan <amstan at chromium.org>
Cc: Douglas Anderson <dianders at chromium.org>
---
New in v2. Tested jaq.

 arch/arm/boot/dts/rk3288-veyron-jerry.dts  | 2 +-
 arch/arm/boot/dts/rk3288-veyron-pinky.dts  | 2 +-
 arch/arm/boot/dts/rk3288-veyron-sdmmc.dtsi | 4 ++--
 3 files changed, 4 insertions(+), 4 deletions(-)

diff --git a/arch/arm/boot/dts/rk3288-veyron-jerry.dts b/arch/arm/boot/dts/rk3288-veyron-jerry.dts
index 42d724559915..60bd6e91e308 100644
--- a/arch/arm/boot/dts/rk3288-veyron-jerry.dts
+++ b/arch/arm/boot/dts/rk3288-veyron-jerry.dts
@@ -99,7 +99,7 @@
 			regulator-min-microvolt = <1800000>;
 			regulator-max-microvolt = <1800000>;
 			regulator-state-mem {
-				regulator-on-in-suspend;
+				regulator-off-in-suspend;
 			};
 		};
 	};
diff --git a/arch/arm/boot/dts/rk3288-veyron-pinky.dts b/arch/arm/boot/dts/rk3288-veyron-pinky.dts
index 25eb4b0c1330..94b56e33d947 100644
--- a/arch/arm/boot/dts/rk3288-veyron-pinky.dts
+++ b/arch/arm/boot/dts/rk3288-veyron-pinky.dts
@@ -109,7 +109,7 @@
 			regulator-boot-on;
 			regulator-name = "vcc18_lcd";
 			regulator-state-mem {
-				regulator-on-in-suspend;
+				regulator-off-in-suspend;
 			};
 		};
 	};
diff --git a/arch/arm/boot/dts/rk3288-veyron-sdmmc.dtsi b/arch/arm/boot/dts/rk3288-veyron-sdmmc.dtsi
index 788468a48163..b5334ecff13c 100644
--- a/arch/arm/boot/dts/rk3288-veyron-sdmmc.dtsi
+++ b/arch/arm/boot/dts/rk3288-veyron-sdmmc.dtsi
@@ -93,7 +93,7 @@
 			regulator-min-microvolt = <3300000>;
 			regulator-max-microvolt = <3300000>;
 			regulator-state-mem {
-				regulator-on-in-suspend;
+				regulator-off-in-suspend;
 			};
 		};
 
@@ -102,7 +102,7 @@
 			regulator-min-microvolt = <3300000>;
 			regulator-max-microvolt = <3300000>;
 			regulator-state-mem {
-				regulator-on-in-suspend;
+				regulator-off-in-suspend;
 			};
 		};
 	};
-- 
2.5.0.276.gf5e568e



From sergei.shtylyov at cogentembedded.com  Wed Aug 19 15:20:42 2015
From: sergei.shtylyov at cogentembedded.com (Sergei Shtylyov)
Date: Thu, 20 Aug 2015 01:20:42 +0300
Subject: [PATCH 0/2] Add VIN and ADV7180 device tree support for R8A7794/SILK
 board
Message-ID: <1750082.WpWf34HsI6@wasted.cogentembedded.com>

Hello.

   Here's the set of 2 patches against Simon Horman's 'renesas.git' repo's
'renesas-devel-20150819-v4.2-rc7' tag. Here we add the VIN and ADV7180
video decoder device tree support on the R8A7794/SILK board. The patchset
requires previously posted SILK SDHI1 support patch in order to apply and 
R8A7794/SILK I2C1 support in order to apply and build.

[1/2] ARM: shmobile: r8a7794: add VIN DT support
[2/2] ARM: shmobile: silk: add VIN0/ADV7180 DT support

MBR, Sergei



From sergei.shtylyov at cogentembedded.com  Wed Aug 19 15:22:24 2015
From: sergei.shtylyov at cogentembedded.com (Sergei Shtylyov)
Date: Thu, 20 Aug 2015 01:22:24 +0300
Subject: [PATCH 1/2] ARM: shmobile: r8a7794: add VIN DT support
In-Reply-To: <1750082.WpWf34HsI6@wasted.cogentembedded.com>
References: <1750082.WpWf34HsI6@wasted.cogentembedded.com>
Message-ID: <6082759.38ZG7ZtnPq@wasted.cogentembedded.com>

Define the generic R8A7794 part of the VIN[01] device nodes. Add aliases for
the VIN[01] device nodes. 

Signed-off-by: Sergei Shtylyov <sergei.shtylyov at cogentembedded.com>

---
 arch/arm/boot/dts/r8a7794.dtsi |   20 ++++++++++++++++++++
 1 file changed, 20 insertions(+)

Index: renesas/arch/arm/boot/dts/r8a7794.dtsi
===================================================================
--- renesas.orig/arch/arm/boot/dts/r8a7794.dtsi
+++ renesas/arch/arm/boot/dts/r8a7794.dtsi
@@ -27,6 +27,8 @@
 		i2c4 = &i2c4;
 		i2c5 = &i2c5;
 		spi0 = &qspi;
+		vin0 = &vin0;
+		vin1 = &vin1;
 	};
 
 	cpus {
@@ -628,6 +630,24 @@
 		status = "disabled";
 	};
 
+	vin0: video at e6ef0000 {
+		compatible = "renesas,vin-r8a7794";
+		reg = <0 0xe6ef0000 0 0x1000>;
+		interrupts = <0 188 IRQ_TYPE_LEVEL_HIGH>;
+		clocks = <&mstp8_clks R8A7794_CLK_VIN0>;
+		power-domains = <&cpg_clocks>;
+		status = "disabled";
+	};
+
+	vin1: video at e6ef1000 {
+		compatible = "renesas,vin-r8a7794";
+		reg = <0 0xe6ef1000 0 0x1000>;
+		interrupts = <0 189 IRQ_TYPE_LEVEL_HIGH>;
+		clocks = <&mstp8_clks R8A7794_CLK_VIN1>;
+		power-domains = <&cpg_clocks>;
+		status = "disabled";
+	};
+
 	clocks {
 		#address-cells = <2>;
 		#size-cells = <2>;



From sergei.shtylyov at cogentembedded.com  Wed Aug 19 15:24:47 2015
From: sergei.shtylyov at cogentembedded.com (Sergei Shtylyov)
Date: Thu, 20 Aug 2015 01:24:47 +0300
Subject: [PATCH 2/2] ARM: shmobile: silk: add VIN0/ADV7180 DT support
In-Reply-To: <1750082.WpWf34HsI6@wasted.cogentembedded.com>
References: <1750082.WpWf34HsI6@wasted.cogentembedded.com>
Message-ID: <4017919.utiMzpz6ED@wasted.cogentembedded.com>

Define  the  SILK board dependent part of the  VIN0  device  node.
Add the device node for Analog Devices ADV7180 video decoder to I2C1 bus.
Add the necessary subnodes to interconnect VIN0 and ADV7180 devices.

Based on the Henninger VIN0/ADV8170 device tree patch by myself.

Signed-off-by: Sergei Shtylyov <sergei.shtylyov at cogentembedded.com>

---
 arch/arm/boot/dts/r8a7794-silk.dts |   35 +++++++++++++++++++++++++++++++++++
 1 file changed, 35 insertions(+)

Index: renesas/arch/arm/boot/dts/r8a7794-silk.dts
===================================================================
--- renesas.orig/arch/arm/boot/dts/r8a7794-silk.dts
+++ renesas/arch/arm/boot/dts/r8a7794-silk.dts
@@ -104,6 +104,11 @@
 		renesas,groups = "qspi_ctrl", "qspi_data4";
 		renesas,function = "qspi";
 	};
+
+	vin0_pins: vin0 {
+		renesas,groups = "vin0_data8", "vin0_clk";
+		renesas,function = "vin0";
+	};
 };
 
 &scif2 {
@@ -135,6 +140,19 @@
 
 	status = "okay";
 	clock-frequency = <400000>;
+
+	composite-in at 20 {
+		compatible = "adi,adv7180";
+		reg = <0x20>;
+		remote = <&vin0>;
+
+		port {
+			adv7180: endpoint {
+				bus-width = <8>;
+				remote-endpoint = <&vin0ep>;
+			};
+		};
+	};
 };
 
 &mmcif0 {
@@ -193,3 +211,20 @@
 		};
 	};
 };
+
+/* composite video input */
+&vin0 {
+	status = "okay";
+	pinctrl-0 = <&vin0_pins>;
+	pinctrl-names = "default";
+
+	port {
+		#address-cells = <1>;
+		#size-cells = <0>;
+
+		vin0ep: endpoint {
+			remote-endpoint = <&adv7180>;
+			bus-width = <8>;
+		};
+	};
+};



From marc.zyngier at arm.com  Wed Aug 19 15:28:39 2015
From: marc.zyngier at arm.com (Marc Zyngier)
Date: Wed, 19 Aug 2015 23:28:39 +0100
Subject: [PATCH v4 1/2] arm64: KVM: Optimize arm64 skip 30-50% vfp/simd
 save/restore on exits
In-Reply-To: <55D4FA88.5060305@samsung.com>
References: <1437082178-11039-1-git-send-email-m.smarduch@samsung.com>
 <1437082178-11039-2-git-send-email-m.smarduch@samsung.com>
 <55C235B9.3000800@arm.com> <20150819174958.GA11518@cbox>
 <55D4FA88.5060305@samsung.com>
Message-ID: <20150819232839.69531eca@arm.com>

On Wed, 19 Aug 2015 14:52:08 -0700
Mario Smarduch <m.smarduch at samsung.com> wrote:

> Hi Christoffer,
>    I'll test it and work with it.

FWIW, I've added these patches to both -queue and -next, and from the
tests Christoffer has run, it looks pretty good.

Thanks,

	M.
-- 
Jazz is not dead. It just smells funny.


From timur at codeaurora.org  Wed Aug 19 15:51:23 2015
From: timur at codeaurora.org (Timur Tabi)
Date: Wed, 19 Aug 2015 17:51:23 -0500
Subject: [PATCH 1/3] [v2] hvc_dcc: don't ignore errors during
 initialization
In-Reply-To: <20150810094859.GF1604@arm.com>
References: <1438992995-22610-1-git-send-email-timur@codeaurora.org>
 <20150810094859.GF1604@arm.com>
Message-ID: <55D5086B.7050907@codeaurora.org>

On 08/10/2015 04:48 AM, Will Deacon wrote:
>> >
>> >  static int __init hvc_dcc_console_init(void)
>> >  {
>> >+	int ret;
>> >+
>> >+	/* This always runs on boot core */
> Does this really "always run on the boot core"? I couldn't find anything
> suggesting that console_init is limited in that regard.

So this is a left-over comment from some other code that actually cared 
what code this function runs on.  I've removed the comment.

-- 
Qualcomm Innovation Center, Inc.
The Qualcomm Innovation Center, Inc. is a member of the
Code Aurora Forum, a Linux Foundation Collaborative Project.


From briannorris at chromium.org  Wed Aug 19 15:59:38 2015
From: briannorris at chromium.org (Brian Norris)
Date: Wed, 19 Aug 2015 15:59:38 -0700
Subject: [PATCH v2 1/3] ARM: dts: rockchip: add veyron-jaq board
In-Reply-To: <CAHNYxRzWHvy=mv+G6wwO29=9smOCwKh6gBPLbT-TNq0PmP2Xiw@mail.gmail.com>
References: <1440022721-73712-1-git-send-email-briannorris@chromium.org>
 <CAHNYxRzWHvy=mv+G6wwO29=9smOCwKh6gBPLbT-TNq0PmP2Xiw@mail.gmail.com>
Message-ID: <20150819225938.GA68578@google.com>

On Wed, Aug 19, 2015 at 03:38:43PM -0700, Alexandru Stan wrote:
> On Wed, Aug 19, 2015 at 3:18 PM, Brian Norris <briannorris at chromium.org>
> wrote:
> 
> > +++ b/Documentation/devicetree/bindings/arm/rockchip.txt
> 
> ...
> 
> > +- Google Jaq (Haier Chromebook 11):
> 
> 
> Could you add s/)/ and more)/ similar to what Jerry has? This is jaq too:
> http://sasthamarket.com/wp-content/uploads/2015/06/34.jpg

Sure. I'll wait for any other comments on v2 before sending the next
(and final?) version.

Thanks,
Brian


From timur at codeaurora.org  Wed Aug 19 16:02:48 2015
From: timur at codeaurora.org (Timur Tabi)
Date: Wed, 19 Aug 2015 18:02:48 -0500
Subject: [PATCH 1/3] [v3] hvc_dcc: don't ignore errors during initialization
Message-ID: <1440025370-9519-1-git-send-email-timur@codeaurora.org>

hvc_instantiate() and hvc_alloc() return errors if they fail, so don't
ignore them.

Signed-off-by: Timur Tabi <timur at codeaurora.org>
---
 drivers/tty/hvc/hvc_dcc.c | 15 +++++++++++----
 1 file changed, 11 insertions(+), 4 deletions(-)

diff --git a/drivers/tty/hvc/hvc_dcc.c b/drivers/tty/hvc/hvc_dcc.c
index 809920d..82f240f 100644
--- a/drivers/tty/hvc/hvc_dcc.c
+++ b/drivers/tty/hvc/hvc_dcc.c
@@ -70,20 +70,27 @@ static const struct hv_ops hvc_dcc_get_put_ops = {
 
 static int __init hvc_dcc_console_init(void)
 {
+	int ret;
+
 	if (!hvc_dcc_check())
 		return -ENODEV;
 
-	hvc_instantiate(0, 0, &hvc_dcc_get_put_ops);
-	return 0;
+	/* Returns -1 if error */
+	ret = hvc_instantiate(0, 0, &hvc_dcc_get_put_ops);
+
+	return ret < 0 ? -ENODEV : 0;
 }
 console_initcall(hvc_dcc_console_init);
 
 static int __init hvc_dcc_init(void)
 {
+	struct hvc_struct *p;
+
 	if (!hvc_dcc_check())
 		return -ENODEV;
 
-	hvc_alloc(0, 0, &hvc_dcc_get_put_ops, 128);
-	return 0;
+	p = hvc_alloc(0, 0, &hvc_dcc_get_put_ops, 128);
+
+	return PTR_ERR_OR_ZERO(p);
 }
 device_initcall(hvc_dcc_init);
-- 
Qualcomm Innovation Center, Inc.
The Qualcomm Innovation Center, Inc. is a member of the Code Aurora Forum,
a Linux Foundation Collaborative Project.



From timur at codeaurora.org  Wed Aug 19 16:02:50 2015
From: timur at codeaurora.org (Timur Tabi)
Date: Wed, 19 Aug 2015 18:02:50 -0500
Subject: [PATCH 3/3] [v2] hvc_dcc: disable user-space access to DCC
In-Reply-To: <1440025370-9519-1-git-send-email-timur@codeaurora.org>
References: <1440025370-9519-1-git-send-email-timur@codeaurora.org>
Message-ID: <1440025370-9519-3-git-send-email-timur@codeaurora.org>

If the DCC driver loads, then disable user-space access to the DCC so that
we don't have two entities trying to access the DCC at the same time.

Signed-off-by: Timur Tabi <timur at codeaurora.org>
---
 arch/arm/include/asm/dcc.h   | 15 +++++++++++++++
 arch/arm64/include/asm/dcc.h | 11 +++++++++++
 drivers/tty/hvc/hvc_dcc.c    |  2 ++
 3 files changed, 28 insertions(+)

diff --git a/arch/arm/include/asm/dcc.h b/arch/arm/include/asm/dcc.h
index b74899d..c50056b 100644
--- a/arch/arm/include/asm/dcc.h
+++ b/arch/arm/include/asm/dcc.h
@@ -9,8 +9,11 @@
  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
  * GNU General Public License for more details.
  */
+#ifndef __ASM_DCC_H
+#define __ASM_DCC_H
 
 #include <asm/barrier.h>
+#include <asm/hardware/cp14.h>
 
 static inline u32 __dcc_getstatus(void)
 {
@@ -39,3 +42,15 @@ static inline void __dcc_putchar(char c)
 		: "r" (c));
 	isb();
 }
+
+static inline void __dcc_initialize(void)
+{
+	u32 val;
+
+	/* Disable user-space access to DCC */
+	val = MRC14(0, c0, c1, 0);
+	val |= 1 << 12; /* DSCR[Comms] */
+	MCR14(val, 0, c0, c1, 0);
+}
+
+#endif
diff --git a/arch/arm64/include/asm/dcc.h b/arch/arm64/include/asm/dcc.h
index 65e0190..cff9512 100644
--- a/arch/arm64/include/asm/dcc.h
+++ b/arch/arm64/include/asm/dcc.h
@@ -52,4 +52,15 @@ static inline void __dcc_putchar(char c)
 	isb();
 }
 
+static inline void __dcc_initialize(void)
+{
+	u32 val;
+
+	/* Disable user-space access to DCC */
+	asm volatile ("mrs %0, mdscr_el1\n"
+		"	orr %0, %0, #4096\n" /* Set the TDCC bit */
+		"	msr mdscr_el1, %0\n"
+		: "=r" (val));
+}
+
 #endif
diff --git a/drivers/tty/hvc/hvc_dcc.c b/drivers/tty/hvc/hvc_dcc.c
index 82f240f..14d4a473 100644
--- a/drivers/tty/hvc/hvc_dcc.c
+++ b/drivers/tty/hvc/hvc_dcc.c
@@ -75,6 +75,8 @@ static int __init hvc_dcc_console_init(void)
 	if (!hvc_dcc_check())
 		return -ENODEV;
 
+	__dcc_initialize();
+
 	/* Returns -1 if error */
 	ret = hvc_instantiate(0, 0, &hvc_dcc_get_put_ops);
 
-- 
Qualcomm Innovation Center, Inc.
The Qualcomm Innovation Center, Inc. is a member of the Code Aurora Forum,
a Linux Foundation Collaborative Project.



From timur at codeaurora.org  Wed Aug 19 16:02:49 2015
From: timur at codeaurora.org (Timur Tabi)
Date: Wed, 19 Aug 2015 18:02:49 -0500
Subject: [PATCH 2/3] [v5] ARM64: TTY: hvc_dcc: Add support for ARM64 dcc
In-Reply-To: <1440025370-9519-1-git-send-email-timur@codeaurora.org>
References: <1440025370-9519-1-git-send-email-timur@codeaurora.org>
Message-ID: <1440025370-9519-2-git-send-email-timur@codeaurora.org>

From: Abhimanyu Kapur <abhimany at codeaurora.org>

Add support for debug communications channel based
hvc console for arm64 cpus.

Signed-off-by: Abhimanyu Kapur <abhimany at codeaurora.org>
Signed-off-by: Timur Tabi <timur at codeaurora.org>
---
 arch/arm64/include/asm/dcc.h | 55 ++++++++++++++++++++++++++++++++++++++++++++
 drivers/tty/hvc/Kconfig      |  2 +-
 2 files changed, 56 insertions(+), 1 deletion(-)
 create mode 100644 arch/arm64/include/asm/dcc.h

diff --git a/arch/arm64/include/asm/dcc.h b/arch/arm64/include/asm/dcc.h
new file mode 100644
index 0000000..65e0190
--- /dev/null
+++ b/arch/arm64/include/asm/dcc.h
@@ -0,0 +1,55 @@
+/* Copyright (c) 2014-2015 The Linux Foundation. All rights reserved.
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License version 2 and
+ * only 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.
+ *
+ * A call to __dcc_getchar() or __dcc_putchar() is typically followed by
+ * a call to __dcc_getstatus().  We want to make sure that the CPU does
+ * not speculative read the DCC status before executing the read or write
+ * instruction.  That's what the ISBs are for.
+ *
+ * The 'volatile' ensures that the compiler does not cache the status bits,
+ * and instead reads the DCC register every time.
+ */
+#ifndef __ASM_DCC_H
+#define __ASM_DCC_H
+
+#include <asm/barrier.h>
+
+static inline u32 __dcc_getstatus(void)
+{
+	u32 ret;
+
+	asm volatile("mrs %0, mdccsr_el0" : "=r" (ret));
+
+	return ret;
+}
+
+static inline char __dcc_getchar(void)
+{
+	char c;
+
+	asm volatile("mrs %0, dbgdtrrx_el0" : "=r" (c));
+	isb();
+
+	return c;
+}
+
+static inline void __dcc_putchar(char c)
+{
+	/*
+	 * The typecast is to make absolutely certain that 'c' is
+	 * zero-extended.
+	 */
+	asm volatile("msr dbgdtrtx_el0, %0"
+			: : "r" ((unsigned long)(unsigned char)c));
+	isb();
+}
+
+#endif
diff --git a/drivers/tty/hvc/Kconfig b/drivers/tty/hvc/Kconfig
index 2509d05..574da15 100644
--- a/drivers/tty/hvc/Kconfig
+++ b/drivers/tty/hvc/Kconfig
@@ -81,7 +81,7 @@ config HVC_UDBG
 
 config HVC_DCC
        bool "ARM JTAG DCC console"
-       depends on ARM
+       depends on ARM || ARM64
        select HVC_DRIVER
        help
          This console uses the JTAG DCC on ARM to create a console under the HVC
-- 
Qualcomm Innovation Center, Inc.
The Qualcomm Innovation Center, Inc. is a member of the Code Aurora Forum,
a Linux Foundation Collaborative Project.



From m.smarduch at samsung.com  Wed Aug 19 16:21:14 2015
From: m.smarduch at samsung.com (Mario Smarduch)
Date: Wed, 19 Aug 2015 16:21:14 -0700
Subject: [PATCH v4 1/2] arm64: KVM: Optimize arm64 skip 30-50% vfp/simd
 save/restore on exits
In-Reply-To: <20150819232839.69531eca@arm.com>
References: <1437082178-11039-1-git-send-email-m.smarduch@samsung.com>
 <1437082178-11039-2-git-send-email-m.smarduch@samsung.com>
 <55C235B9.3000800@arm.com> <20150819174958.GA11518@cbox>
 <55D4FA88.5060305@samsung.com> <20150819232839.69531eca@arm.com>
Message-ID: <55D50F6A.9020604@samsung.com>

Great that's even better.

On 8/19/2015 3:28 PM, Marc Zyngier wrote:
> On Wed, 19 Aug 2015 14:52:08 -0700
> Mario Smarduch <m.smarduch at samsung.com> wrote:
> 
>> Hi Christoffer,
>>    I'll test it and work with it.
> 
> FWIW, I've added these patches to both -queue and -next, and from the
> tests Christoffer has run, it looks pretty good.
> 
> Thanks,
> 
> 	M.
> 


From javier at dowhile0.org  Wed Aug 19 16:35:41 2015
From: javier at dowhile0.org (Javier Martinez Canillas)
Date: Thu, 20 Aug 2015 01:35:41 +0200
Subject: [PATCH v2 2/3] ARM: dts: rockchip: correct regulator PM properties
In-Reply-To: <1440022721-73712-2-git-send-email-briannorris@chromium.org>
References: <1440022721-73712-1-git-send-email-briannorris@chromium.org>
 <1440022721-73712-2-git-send-email-briannorris@chromium.org>
Message-ID: <CABxcv=kV2YW7gTmvaLTQiQUbmfVcqttV8prRfm0zxV=hvsRe9w@mail.gmail.com>

Hello Brian,

On Thu, Aug 20, 2015 at 12:18 AM, Brian Norris <briannorris at chromium.org> wrote:
> This DTS file was submitted with non-upstream bindings. I happened
> across this while reviewing the jaq DTS.
>
> Signed-off-by: Brian Norris <briannorris at chromium.org>
> Cc: Alexandru M Stan <amstan at chromium.org>
> Cc: Douglas Anderson <dianders at chromium.org>
> ---
> Did not test minnie
>
> v1 -> v2:
>  - use "off-in-suspend", as that's the equivalent to the downstream
>    'regulator-suspend-mem-disabled'
>
>  arch/arm/boot/dts/rk3288-veyron-minnie.dts | 8 ++++++--
>  1 file changed, 6 insertions(+), 2 deletions(-)
>

Patch looks good to me.

Reviewed-by: Javier Martinez Canillas <javier at osg.samsung.com>

Best regards,
Javier


From javier at dowhile0.org  Wed Aug 19 16:36:46 2015
From: javier at dowhile0.org (Javier Martinez Canillas)
Date: Thu, 20 Aug 2015 01:36:46 +0200
Subject: [PATCH v2 3/3] ARM: dts: rockchip: correct regulator power states
 for suspend
In-Reply-To: <1440022721-73712-3-git-send-email-briannorris@chromium.org>
References: <1440022721-73712-1-git-send-email-briannorris@chromium.org>
 <1440022721-73712-3-git-send-email-briannorris@chromium.org>
Message-ID: <CABxcv=mpz7yJFiR=1NQxsbmbVCVGYpgZYS1rEWi58aSUQaELcw@mail.gmail.com>

Hello Brian,

On Thu, Aug 20, 2015 at 12:18 AM, Brian Norris <briannorris at chromium.org> wrote:
> When getting translated from a downstream device tree that used slightly
> different DT bindings, these regulators got labeled with the
> "on-in-suspend" state, when they were actually supposed to be turned off
> for S3 suspend. This was harmless, but not intentional, AFAICT.
>
> Let's turn them off to get the optimal power state.
>
> Signed-off-by: Brian Norris <briannorris at chromium.org>
> Cc: Alexandru M Stan <amstan at chromium.org>
> Cc: Douglas Anderson <dianders at chromium.org>
> ---
> New in v2. Tested jaq.
>
>  arch/arm/boot/dts/rk3288-veyron-jerry.dts  | 2 +-
>  arch/arm/boot/dts/rk3288-veyron-pinky.dts  | 2 +-
>  arch/arm/boot/dts/rk3288-veyron-sdmmc.dtsi | 4 ++--
>  3 files changed, 4 insertions(+), 4 deletions(-)
>

Reviewed-by: Javier Martinez Canillas <javier at osg.samsung.com>

Best regards,
Javier


From javier at dowhile0.org  Wed Aug 19 16:29:40 2015
From: javier at dowhile0.org (Javier Martinez Canillas)
Date: Thu, 20 Aug 2015 01:29:40 +0200
Subject: [PATCH v2 1/3] ARM: dts: rockchip: add veyron-jaq board
In-Reply-To: <1440022721-73712-1-git-send-email-briannorris@chromium.org>
References: <1440022721-73712-1-git-send-email-briannorris@chromium.org>
Message-ID: <CABxcv=nQAfCzj_bQ9N-XYEPCNuihyrkUOz7=ogetKzye4KKNng@mail.gmail.com>

Hello Brian,

[...]

> +
> +&rk808 {
> +       pinctrl-names = "default";
> +       pinctrl-0 = <&pmic_int_l &dvs_1 &dvs_2>;
> +       dvs-gpios = <&gpio7 12 GPIO_ACTIVE_HIGH>,
> +                   <&gpio7 15 GPIO_ACTIVE_HIGH>;

I see the dvs-gpios DT property is documented in the downstream
ChromiumOS 3.18 tree [0] but I don't see it neither mentioned in
Documentation/devicetree/bindings/mfd/rk808.txt in mainline nor code
that parses it in the drivers/regulator/rk808-regulator.c driver.

So I think this should be removed and also the dvs_{1,2} pinctrl
lines. The rest of the patch looks good to me though so with these
removed feel free to add:

Reviewed-by: Javier Martinez Canillas <javier at osg.samsung.com>

[0]: https://chromium.googlesource.com/chromiumos/third_party/kernel/+/chromeos-3.14/Documentation/devicetree/bindings/mfd/rk808.txt

Best regards,
Javier


From airlied at gmail.com  Wed Aug 19 16:54:04 2015
From: airlied at gmail.com (Dave Airlie)
Date: Thu, 20 Aug 2015 09:54:04 +1000
Subject: [PATCH v3 0/14] Add Analogix Core Display Port Driver
In-Reply-To: <1439995728-18046-1-git-send-email-ykk@rock-chips.com>
References: <1439995728-18046-1-git-send-email-ykk@rock-chips.com>
Message-ID: <CAPM=9tx6qMnHEfYpi5_+Ay9P5fy=JqthMp6-t0fxFPfm8E4k7Q@mail.gmail.com>

On 20 August 2015 at 00:48, Yakir Yang <ykk at rock-chips.com> wrote:
>
> Hi all,
>    The Samsung Exynos eDP controller and Rockchip RK3288 eDP controller
> share the same IP, so a lot of parts can be re-used. I split the common
> code into bridge directory, then rk3288 and exynos only need to keep
> some platform code. Cause I can't find the exact IP name of exynos dp
> controller, so I decide to name dp core driver with "analogix" which I
> find in rk3288 eDP TRM ;)
>
> Beyond that, there are three light registers setting differents bewteen
> exynos and rk3288.
> 1. RK3288 have five special pll resigters which not indicata in exynos
>    dp controller.
> 2. The address of DP_PHY_PD(dp phy power manager register) are different
>    between rk3288 and exynos.
> 3. Rk3288 and exynos have different setting with AUX_HW_RETRY_CTL(dp debug
>    register).
>
> I have verified this series on two kinds of rockchip platform board, one
> is rk3288 sdk board which connect with a 2K display port monitor, the other
> is google jerry chromebook which connect with a eDP screen "cnm,n116bgeea2",
> both of them works rightlly.
>
> I haven't verified the dp function on samsung platform, cause I haven't got
> exynos boards. I can only ensure that there are no build error on samsung
> platform, wish some samsung guys help to test. ;)

I'd like to pull this in, but it probably needs an ack from Samsung,

Inki can you guys find some time to test this?

Dave.


From 21cnbao at gmail.com  Wed Aug 19 17:16:42 2015
From: 21cnbao at gmail.com (Barry Song)
Date: Thu, 20 Aug 2015 08:16:42 +0800
Subject: [PATCH 1/2] mmc: core: enable CMD19 tuning for DDR50 mode
In-Reply-To: <CAPDyKFpXZD28NwNAhKQyxmWasVhk_7AeyOW6oXaBPHKuSTmGUA@mail.gmail.com>
References: <1439282492-6274-1-git-send-email-21cnbao@gmail.com>
 <CAPDyKFpXZD28NwNAhKQyxmWasVhk_7AeyOW6oXaBPHKuSTmGUA@mail.gmail.com>
Message-ID: <CAGsJ_4wvvQdyjFi=JmWfASm-LbJMybrhC=Wxxn7jHZEP5dUfEw@mail.gmail.com>

2015-08-18 1:11 GMT+08:00 Ulf Hansson <ulf.hansson at linaro.org>:
> On 11 August 2015 at 10:41, Barry Song <21cnbao at gmail.com> wrote:
>> From: Weijun Yang <york.yang at csr.com>
>>
>> As SD Specifications Part1 Physical Layer Specification Version
>> 3.01 says, CMD19 tuning is available for unlocked cards in transfer
>> state of 1.8V signaling mode. The small difference between v3.00
>> and 3.01 spec means that CMD19 tuning is also available for DDR50
>> mode.
>
> So what happens with cards following the 3.0 spec version, those
> doesn't need to support the tuning CMD right? Perhaps that needs to be
> addressed in this patch well!?

from HW registers of the card, we cann't know whether the HW needs
tuning. it is said 3.0.x need tuning, but 3.0 doesn't need.  @weijun,
pls fix me if i am wrong.
if so, it seems we need a static flag somewhere to indicate whether
the tuning is needed. we can't detect to find the tuning requirement.

>
> Kind regards
> Uffe
>
>>
>> Signed-off-by: Weijun Yang <york.yang at csr.com>
>> Signed-off-by: Barry Song <Baohua.Song at csr.com>
>> ---
>>  drivers/mmc/core/sd.c    | 1 +
>>  drivers/mmc/host/sdhci.c | 1 +
>>  2 files changed, 2 insertions(+)
>>
>> diff --git a/drivers/mmc/core/sd.c b/drivers/mmc/core/sd.c
>> index 4e7366a..a1ed24d 100644
>> --- a/drivers/mmc/core/sd.c
>> +++ b/drivers/mmc/core/sd.c
>> @@ -629,6 +629,7 @@ static int mmc_sd_init_uhs_card(struct mmc_card *card)
>>          */
>>         if (!mmc_host_is_spi(card->host) &&
>>             (card->sd_bus_speed == UHS_SDR50_BUS_SPEED ||
>> +            card->sd_bus_speed == UHS_DDR50_BUS_SPEED ||
>>              card->sd_bus_speed == UHS_SDR104_BUS_SPEED))
>>                 err = mmc_execute_tuning(card);
>>  out:
>> diff --git a/drivers/mmc/host/sdhci.c b/drivers/mmc/host/sdhci.c
>> index 1dbe932..812c19b 100644
>> --- a/drivers/mmc/host/sdhci.c
>> +++ b/drivers/mmc/host/sdhci.c
>> @@ -1891,6 +1891,7 @@ static int sdhci_execute_tuning(struct mmc_host *mmc, u32 opcode)
>>                 break;
>>
>>         case MMC_TIMING_UHS_SDR104:
>> +       case MMC_TIMING_UHS_DDR50:
>>                 break;
>>
>>         case MMC_TIMING_UHS_SDR50:
>> --
>> 1.9.1
>>

-barry


From julien.grall at citrix.com  Wed Aug 19 17:40:18 2015
From: julien.grall at citrix.com (Julien Grall)
Date: Wed, 19 Aug 2015 17:40:18 -0700
Subject: [Xen-devel] [PATCH v3 00/20] xen/arm64: Add support for 64KB page
In-Reply-To: <1438966019-19322-1-git-send-email-julien.grall@citrix.com>
References: <1438966019-19322-1-git-send-email-julien.grall@citrix.com>
Message-ID: <55D521F2.5080504@citrix.com>

Hi,

Ping? I'm missing some reviews on block and netfront code.

We'd like to see this series going in Linux 4.3. Some distributions 
plans to use this version for aarch64 support. If we miss it, we won't 
have any Xen guests support, even it's minimal, for Linux using 64KB 
page granularity.

Regards,

On 07/08/2015 09:46, Julien Grall wrote:
> Hi all,
>
> ARM64 Linux is supporting both 4KB and 64KB page granularity. Although, Xen
> hypercall interface and PV protocol are always based on 4KB page granularity.
>
> Any attempt to boot a Linux guest with 64KB pages enabled will result to a
> guest crash.
>
> This series is a first attempt to allow those Linux running with the current
> hypercall interface and PV protocol.
>
> This solution has been chosen because we want to run Linux 64KB in released
> Xen ARM version or/and platform using an old version of Linux DOM0.
>
> There is room for improvement, such as support of 64KB grant, modification
> of PV protocol to support different page size... They will be explored in a
> separate patch series later.
>
> TODO list:
>      - Convert swiotlb to 64KB
>      - Convert xenfb to 64KB
>      - Check if backend in QEMU works with DOM0 64KB
>      - It may be possible to move some common define between
>      netback/netfront and blkfront/blkback in an header
>
> All patches has been built tested for ARM32, ARM64, x86. But I haven't tested
> to run it on x86 as I don't have a box with Xen x86 running. I would be
> happy if someone give a try and see possible regression for x86.
>
> A branch based on the latest linux/master can be found here:
>
> git://xenbits.xen.org/people/julieng/linux-arm.git branch xen-64k-v3
>
> Comments, suggestions are welcomed.
>
> Sincerely yours,
>
> Cc: david.vrabel at citrix.com
> Cc: konrad.wilk at oracle.com
> Cc: boris.ostrovsky at oracle.com
> Cc: wei.liu2 at citrix.com
> Cc: roger.pau at citrix.com
>
> Julien Grall (20):
>    net/xen-netback: xenvif_gop_frag_copy: move GSO check out of the loop
>    arm/xen: Drop pte_mfn and mfn_pte
>    xen: Add Xen specific page definition
>    xen/grant: Introduce helpers to split a page into grant
>    xen/grant: Add helper gnttab_page_grant_foreign_access_ref_one
>    block/xen-blkfront: Split blkif_queue_request in 2
>    block/xen-blkfront: Store a page rather a pfn in the grant structure
>    block/xen-blkfront: split get_grant in 2
>    xen/biomerge: Don't allow biovec to be merge when Linux is not using
>      4KB page
>    xen/xenbus: Use Xen page definition
>    tty/hvc: xen: Use xen page definition
>    xen/balloon: Don't rely on the page granularity is the same for Xen
>      and Linux
>    xen/events: fifo: Make it running on 64KB granularity
>    xen/grant-table: Make it running on 64KB granularity
>    block/xen-blkfront: Make it running on 64KB page granularity
>    block/xen-blkback: Make it running on 64KB page granularity
>    net/xen-netfront: Make it running on 64KB page granularity
>    net/xen-netback: Make it running on 64KB page granularity
>    xen/privcmd: Add support for Linux 64KB page granularity
>    arm/xen: Add support for 64KB page granularity
>
>   arch/arm/include/asm/xen/page.h     |  18 +-
>   arch/arm/xen/enlighten.c            |   6 +-
>   arch/arm/xen/p2m.c                  |   6 +-
>   arch/x86/include/asm/xen/page.h     |   2 +-
>   drivers/block/xen-blkback/blkback.c |   5 +-
>   drivers/block/xen-blkback/common.h  |  17 +-
>   drivers/block/xen-blkback/xenbus.c  |   9 +-
>   drivers/block/xen-blkfront.c        | 552 +++++++++++++++++++++++-------------
>   drivers/net/xen-netback/common.h    |  15 +-
>   drivers/net/xen-netback/netback.c   | 163 +++++++----
>   drivers/net/xen-netfront.c          | 122 +++++---
>   drivers/tty/hvc/hvc_xen.c           |   4 +-
>   drivers/xen/balloon.c               |  47 ++-
>   drivers/xen/biomerge.c              |   8 +
>   drivers/xen/events/events_base.c    |   2 +-
>   drivers/xen/events/events_fifo.c    |   2 +-
>   drivers/xen/grant-table.c           |  32 ++-
>   drivers/xen/privcmd.c               |   8 +-
>   drivers/xen/xenbus/xenbus_client.c  |   6 +-
>   drivers/xen/xenbus/xenbus_probe.c   |   3 +-
>   drivers/xen/xlate_mmu.c             | 124 +++++---
>   include/xen/grant_table.h           |  51 ++++
>   include/xen/page.h                  |  27 +-
>   23 files changed, 844 insertions(+), 385 deletions(-)
>

-- 
Julien Grall


From ykk at rock-chips.com  Wed Aug 19 18:02:57 2015
From: ykk at rock-chips.com (Yakir Yang)
Date: Wed, 19 Aug 2015 20:02:57 -0500
Subject: [PATCH v3 0/14] Add Analogix Core Display Port Driver
In-Reply-To: <CAPM=9tx6qMnHEfYpi5_+Ay9P5fy=JqthMp6-t0fxFPfm8E4k7Q@mail.gmail.com>
References: <1439995728-18046-1-git-send-email-ykk@rock-chips.com>
 <CAPM=9tx6qMnHEfYpi5_+Ay9P5fy=JqthMp6-t0fxFPfm8E4k7Q@mail.gmail.com>
Message-ID: <55D52741.3080709@rock-chips.com>

Hi Dave,

On 08/19/2015 06:54 PM, Dave Airlie wrote:
> On 20 August 2015 at 00:48, Yakir Yang <ykk at rock-chips.com> wrote:
>> Hi all,
>>     The Samsung Exynos eDP controller and Rockchip RK3288 eDP controller
>> share the same IP, so a lot of parts can be re-used. I split the common
>> code into bridge directory, then rk3288 and exynos only need to keep
>> some platform code. Cause I can't find the exact IP name of exynos dp
>> controller, so I decide to name dp core driver with "analogix" which I
>> find in rk3288 eDP TRM ;)
>>
>> Beyond that, there are three light registers setting differents bewteen
>> exynos and rk3288.
>> 1. RK3288 have five special pll resigters which not indicata in exynos
>>     dp controller.
>> 2. The address of DP_PHY_PD(dp phy power manager register) are different
>>     between rk3288 and exynos.
>> 3. Rk3288 and exynos have different setting with AUX_HW_RETRY_CTL(dp debug
>>     register).
>>
>> I have verified this series on two kinds of rockchip platform board, one
>> is rk3288 sdk board which connect with a 2K display port monitor, the other
>> is google jerry chromebook which connect with a eDP screen "cnm,n116bgeea2",
>> both of them works rightlly.
>>
>> I haven't verified the dp function on samsung platform, cause I haven't got
>> exynos boards. I can only ensure that there are no build error on samsung
>> platform, wish some samsung guys help to test. ;)
> I'd like to pull this in, but it probably needs an ack from Samsung,
>
> Inki can you guys find some time to test this?
>
> Dave.

Wow, thanks a lots  :-)

Still waiting for some reviews and acks.

Best regards,
- Yakir
>
>




From fugang.duan at freescale.com  Wed Aug 19 18:16:40 2015
From: fugang.duan at freescale.com (Duan Andy)
Date: Thu, 20 Aug 2015 01:16:40 +0000
Subject: [PATCH v1 1/6] net: phy: broadcom: add bcm54220 phy ID
In-Reply-To: <CAGVrzcak2u_kBg1o061OO0UK8sdrXaKF+-7eREwByD-dQ1r1XQ@mail.gmail.com>
References: <1439962444-27486-1-git-send-email-b38611@freescale.com>
 <1439962444-27486-2-git-send-email-b38611@freescale.com>
 <CAGVrzcak2u_kBg1o061OO0UK8sdrXaKF+-7eREwByD-dQ1r1XQ@mail.gmail.com>
Message-ID: <BN3PR0301MB12198F2E8A1D508EE4FB0419F5660@BN3PR0301MB1219.namprd03.prod.outlook.com>

From: Florian Fainelli <f.fainelli at gmail.com> Sent: Thursday, August 20, 2015 5:29 AM
> To: Duan Fugang-B38611
> Cc: shawnguo at kernel.org; David Miller; netdev; linux-arm-
> kernel at lists.infradead.org
> Subject: Re: [PATCH v1 1/6] net: phy: broadcom: add bcm54220 phy ID
> 
> 2015-08-18 22:33 GMT-07:00 Fugang Duan <b38611 at freescale.com>:
> > Add bcm54220 phy ID entry.
> 
> This change itself is fine, but looking at the rest of your changes, we
> are not adding an entry for this PHY in drivers/net/phy/broadcom.c, which
> means that we will bind to the Generic PHY driver, and so this looks
> sufficient, even with your fixup done in the subsequent patch.
> 

Thanks for your comment.

Yes, for the phy, the driver use generic phy driver. 
I see all Broadcom phy ID are defined in this file, we shouldn't define new phy id in other place.
When the phy is used more popular, I think the patch is very reasonable.

> >
> > Signed-off-by: Fugang Duan <B38611 at freescale.com>
> > ---
> >  include/linux/brcmphy.h | 1 +
> >  1 file changed, 1 insertion(+)
> >
> > diff --git a/include/linux/brcmphy.h b/include/linux/brcmphy.h index
> > 697ca77..20bed15 100644
> > --- a/include/linux/brcmphy.h
> > +++ b/include/linux/brcmphy.h
> > @@ -16,6 +16,7 @@
> >  #define PHY_ID_BCM5482                 0x0143bcb0
> >  #define PHY_ID_BCM5411                 0x00206070
> >  #define PHY_ID_BCM5421                 0x002060e0
> > +#define PHY_ID_BCM54220                        0x600d8589
> >  #define PHY_ID_BCM5464                 0x002060b0
> >  #define PHY_ID_BCM5461                 0x002060c0
> >  #define PHY_ID_BCM54616S               0x03625d10
> > --
> > 1.9.1
> >
> >
> > _______________________________________________
> > linux-arm-kernel mailing list
> > linux-arm-kernel at lists.infradead.org
> > http://lists.infradead.org/mailman/listinfo/linux-arm-kernel
> 
> 
> 
> --
> Florian

From wens at csie.org  Wed Aug 19 18:59:27 2015
From: wens at csie.org (Chen-Yu Tsai)
Date: Thu, 20 Aug 2015 09:59:27 +0800
Subject: [PATCH v3 0/8] ARM: sunxi: Add Reduced Serial Bus support
In-Reply-To: <20150819163232.GS10748@sirena.org.uk>
References: <1439958009-14056-1-git-send-email-wens@csie.org>
 <20150819163232.GS10748@sirena.org.uk>
Message-ID: <CAGb2v66X-CMQiS1dNqhwamTsVbnf+7siSTV3xGwn-C91Zhw3uA@mail.gmail.com>

On Thu, Aug 20, 2015 at 12:32 AM, Mark Brown <broonie at kernel.org> wrote:
> On Wed, Aug 19, 2015 at 12:20:01PM +0800, Chen-Yu Tsai wrote:
>> Hi everyone,
>>
>> This is my third attempt at adding support for Allwinner's Reduced
>> Serial Bus (RSB), which is used to communicate with PMICs and other
>> peripherals on their newer SoCs, such as the A23/A33/A80.
>
> This is flagged as something that is specific to the Allwinner SoCs.
> Why add generic regmap support rather than just implement the regmap
> reg_read() and reg_write() in a regmap in the controller driver?  Are
> there expected to be other controller drivers from other vendors?

I don't expect there to be any other controller drivers. And it seems
at least some of the devices are dual interface (I2C/RSB). Though I
don't see how its connected to the generic regmap support. Regmap
is for device drivers connected to the RSB bus, not the bus controller
itself.

That said, there are a few RSB mfd slave devices that need support,
those being the later AXP series PMICs, and AC100/AC200 audio-codec/RTC
chips. The current axp20x driver already uses i2c regmaps.

I could throw all the RSB-related stuff together, presumably under
drivers/soc/sunxi/rsb, though that doesn't help the fact that common
regmap code would be  better than scattering regmap_* in various mfd
drivers.


Regards
ChenYu


From kgene at kernel.org  Wed Aug 19 19:25:44 2015
From: kgene at kernel.org (Kukjin Kim)
Date: Thu, 20 Aug 2015 11:25:44 +0900
Subject: [GIT PULL v2 0/5] Samsung updates for v4.3
In-Reply-To: <55CCE517.2070003@kernel.org>
References: <55CCE517.2070003@kernel.org>
Message-ID: <023501d0daef$86d21c20$94765460$@kernel.org>

Kukjin Kim wrote:
> 
> Hello Arnd, Olof, Kevin
> 
Hi,

Please pull and if any comments, please kindly let me know.

Thanks,
Kukjin

> Here is re-spin of pull request for Samsung stuff for v4.3 as per Olof's
> suggestion.
> 
> Most of this pull-requests are to switch to support generic cpufreq
> driver for exynos3250, 4210, 4412 and 5250 and several exynos dt updates.
> 
> Note as I commented in each tag, each pull-request(signed tag) has a
> dependency with each other, so please keep the ordering in this time.
> 
> 1) tags/samsung-clk-driver
> 2) tags/samsung-late-dt
> 3) tags/samsung-soc
> 4) tags/samsung-late-cpufreq-driver
> 5) tags/samsung-defconfig-new
> 
> If any problems, please kindly let me know.
> 
> Thanks,
> Kukjin
> 
> Alexis Ballier (1):
>       ARM: dts: enable SPI1 for exynos4412-odroidu3
> 
> Anand Moon (1):
>       ARM: exynos_defconfig: Enable CONFIG_SND_SOC_ODROIDX2 for Odroid-XU3
> 
> Bartlomiej Zolnierkiewicz (5):
>       cpufreq: exynos: remove exynos5250 specific cpufreq driver support
>       clk: exynos4x12: add cpu clock configuration data and instantiate
> cpu clock
>       cpufreq: exynos: remove Exynos4x12 specific cpufreq driver support
>       ARM: dts: add CPU OPP and regulator supply property for exynos4x12
>       ARM: EXYNOS: switch to using generic cpufreq driver for exynos4x12
> 
> Chanho Park (1):
>       ARM: dts: add exynos5422-cpus.dtsi to correct cpu order
> 
> Chanwoo Choi (4):
>       clk: exynos3250: Add cpu clock configuration data and instaniate
> cpu clock
>       ARM: EXYNOS: Add exynos3250 compatible to use generic cpufreq driver
>       ARM: dts: Add CPU OPP and regulator supply property for exynos3250
>       ARM: dts: Add CPU cooling binding for exynos3250 boards
> 
> Javier Martinez Canillas (4):
>       ARM: multi_v7_defconfig: Remove old Samsung USB PHY configs
>       ARM: multi_v7_defconfig: Enable NTC Thermistors support
>       ARM: exynos_defconfig: Enable NTC Thermistors support
>       ARM: multi_v7_defconfig: Enable max77802 regulator
> 
> Jonas Rabenstein (1):
>       cpufreq: exynos: Remove unselectable rule for arm-exynos-cpufreq.o
> 
> Krzysztof Kozlowski (1):
>       ARM: exynos_defconfig: Enable cpufreq-dt driver
> 
> Marek Szyprowski (1):
>       ARM: dts: add iommu property to JPEG device for exynos4
> 
> Michal Suchanek (1):
>       ARM: dts: Add SPI CS on exynos5250-snow
> 
> Thomas Abraham (3):
>       clk: exynos5250: add cpu clock configuration data and instantiate
> cpu clock
>       ARM: EXYNOS: switch to using generic cpufreq driver for exynos5250
>       ARM: dts: add CPU OPP and regulator supply property for exynos5250
> 
>  arch/arm/boot/dts/exynos3250-monk.dts              |  19 ++
>  arch/arm/boot/dts/exynos3250-rinato.dts            |  19 ++
>  arch/arm/boot/dts/exynos3250.dtsi                  |  16 ++
>  arch/arm/boot/dts/exynos4.dtsi                     |   1 +
>  arch/arm/boot/dts/exynos4212.dtsi                  |  81 +++++++
>  arch/arm/boot/dts/exynos4412-odroid-common.dtsi    |   4 +
>  arch/arm/boot/dts/exynos4412-odroidu3.dts          |   8 +
>  arch/arm/boot/dts/exynos4412-origen.dts            |   4 +
>  arch/arm/boot/dts/exynos4412-trats2.dts            |   4 +
>  arch/arm/boot/dts/exynos4412.dtsi                  |  83 ++++++++
>  arch/arm/boot/dts/exynos5250-arndale.dts           |   4 +
>  arch/arm/boot/dts/exynos5250-smdk5250.dts          |   4 +
>  arch/arm/boot/dts/exynos5250-snow.dts              |   5 +
>  arch/arm/boot/dts/exynos5250-spring.dts            |   4 +
>  arch/arm/boot/dts/exynos5250.dtsi                  |  22 ++
>  arch/arm/boot/dts/exynos5422-cpus.dtsi             |  81 +++++++
>  arch/arm/boot/dts/exynos5422-odroidxu3-common.dtsi |   1 +
>  arch/arm/configs/exynos_defconfig                  |   5 +
>  arch/arm/configs/multi_v7_defconfig                |   5 +-
>  arch/arm/mach-exynos/Kconfig                       |   2 +
>  arch/arm/mach-exynos/exynos.c                      |   4 +
>  drivers/clk/samsung/clk-exynos3250.c               |  32 ++-
>  drivers/clk/samsung/clk-exynos4.c                  |  50 +++++
>  drivers/clk/samsung/clk-exynos5250.c               |  31 +++
>  drivers/cpufreq/Kconfig.arm                        |  49 -----
>  drivers/cpufreq/Makefile                           |   4 -
>  drivers/cpufreq/exynos-cpufreq.c                   | 237
> ---------------------
>  drivers/cpufreq/exynos-cpufreq.h                   |  89 --------
>  drivers/cpufreq/exynos4x12-cpufreq.c               | 236
> --------------------
>  drivers/cpufreq/exynos5250-cpufreq.c               | 210 ------------------
>  include/dt-bindings/clock/exynos3250.h             |   1 +
>  include/dt-bindings/clock/exynos5250.h             |   1 +
>  32 files changed, 487 insertions(+), 829 deletions(-)



From leo.yan at linaro.org  Wed Aug 19 19:53:56 2015
From: leo.yan at linaro.org (Leo Yan)
Date: Thu, 20 Aug 2015 10:53:56 +0800
Subject: [PATCH v2 0/3] mailbox: hisilicon: add Hi6220 mailbox driver
Message-ID: <1440039239-8772-1-git-send-email-leo.yan@linaro.org>

Hi6220 mailbox supports up to 32 channels. Each channel is unidirectional
with a maximum message size of 8 words. I/O is performed using register
access (there is no DMA) and the cell raises an interrupt when messages
are received.

This patch series is to implement Hi6220 mailbox driver. It registers
two channels into framework for communication with MCU, one is tx channel
and another is rx channel. Now mailbox driver is used to send message to
MCU to control dynamic voltage and frequency scaling for CPU, GPU and DDR.

Changes from v1:
* Correct lock usage for SMP scenario

Changes from RFC:
* According to Jassi's review, totally remove the abstract common driver
  layer and only commit driver dedicated for Hi6220
* According to Paul Bolle's review, fix typo issue for Kconfig and remove
  unnecessary dependency with OF and fix minor for mailbox driver
* Refine a little for dts nodes


Leo Yan (3):
  dt-bindings: mailbox: Document Hi6220 mailbox driver
  mailbox: Hi6220: add mailbox driver
  arm64: dts: add Hi6220 mailbox node

 .../bindings/mailbox/hisilicon,hi6220-mailbox.txt  |  57 +++
 arch/arm64/boot/dts/hisilicon/hi6220-hikey.dts     |  20 +-
 arch/arm64/boot/dts/hisilicon/hi6220.dtsi          |   8 +
 drivers/mailbox/Kconfig                            |   8 +
 drivers/mailbox/Makefile                           |   2 +
 drivers/mailbox/hi6220-mailbox.c                   | 519 +++++++++++++++++++++
 6 files changed, 611 insertions(+), 3 deletions(-)
 create mode 100644 Documentation/devicetree/bindings/mailbox/hisilicon,hi6220-mailbox.txt
 create mode 100644 drivers/mailbox/hi6220-mailbox.c

-- 
1.9.1



From leo.yan at linaro.org  Wed Aug 19 19:53:57 2015
From: leo.yan at linaro.org (Leo Yan)
Date: Thu, 20 Aug 2015 10:53:57 +0800
Subject: [PATCH v2 1/3] dt-bindings: mailbox: Document Hi6220 mailbox driver
In-Reply-To: <1440039239-8772-1-git-send-email-leo.yan@linaro.org>
References: <1440039239-8772-1-git-send-email-leo.yan@linaro.org>
Message-ID: <1440039239-8772-2-git-send-email-leo.yan@linaro.org>

Document the new compatible for Hisilicon Hi6220 mailbox driver.

Signed-off-by: Leo Yan <leo.yan at linaro.org>
---
 .../bindings/mailbox/hisilicon,hi6220-mailbox.txt  | 57 ++++++++++++++++++++++
 1 file changed, 57 insertions(+)
 create mode 100644 Documentation/devicetree/bindings/mailbox/hisilicon,hi6220-mailbox.txt

diff --git a/Documentation/devicetree/bindings/mailbox/hisilicon,hi6220-mailbox.txt b/Documentation/devicetree/bindings/mailbox/hisilicon,hi6220-mailbox.txt
new file mode 100644
index 0000000..3dfb0b0
--- /dev/null
+++ b/Documentation/devicetree/bindings/mailbox/hisilicon,hi6220-mailbox.txt
@@ -0,0 +1,57 @@
+Hisilicon Hi6220 Mailbox Driver
+===============================
+
+Hisilicon Hi6220 mailbox supports up to 32 channels. Each channel
+is unidirectional with a maximum message size of 8 words. I/O is
+performed using register access (there is no DMA) and the cell
+raises an interrupt when messages are received.
+
+Mailbox Device Node:
+====================
+
+Required properties:
+--------------------
+- compatible:		Shall be "hisilicon,hi6220-mbox"
+- reg:			Contains the mailbox register address range (base
+			address and length); the first item is for IPC
+			registers, the second item is shared buffer for
+			slots.
+- #mbox-cells		Common mailbox binding property to identify the number
+			of cells required for the mailbox specifier. Should be 1.
+- interrupts:		Contains the interrupt information for the mailbox
+			device. The format is dependent on which interrupt
+			controller the SoCs use.
+
+Example:
+--------
+
+	mailbox: mailbox at F7510000 {
+		#mbox-cells = <1>;
+		compatible = "hisilicon,hi6220-mbox";
+		reg = <0x0 0xF7510000 0x0 0x1000>, /* IPC_S */
+		      <0x0 0x06DFF800 0x0 0x0800>; /* Mailbox */
+		interrupt-parent = <&gic>;
+		interrupts = <0 94 4>;
+	};
+
+
+Mailbox client
+===============
+
+"mboxes" and the optional "mbox-names" (please see
+Documentation/devicetree/bindings/mailbox/mailbox.txt for details). Each value
+of the mboxes property should contain a phandle to the mailbox controller
+device node and second argument is the channel index. It must be 0 (hardware
+support only one channel). The equivalent "mbox-names" property value can be
+used to give a name to the communication channel to be used by the client user.
+
+Example:
+--------
+
+	stub_clock: stub_clock {
+		compatible = "hisilicon,hi6220-stub-clk";
+		hisilicon,hi6220-clk-sram = <&sram>;
+		#clock-cells = <1>;
+		mbox-names = "mbox-tx";
+		mboxes = <&mailbox 1>;
+	};
-- 
1.9.1



From leo.yan at linaro.org  Wed Aug 19 19:53:58 2015
From: leo.yan at linaro.org (Leo Yan)
Date: Thu, 20 Aug 2015 10:53:58 +0800
Subject: [PATCH v2 2/3] mailbox: Hi6220: add mailbox driver
In-Reply-To: <1440039239-8772-1-git-send-email-leo.yan@linaro.org>
References: <1440039239-8772-1-git-send-email-leo.yan@linaro.org>
Message-ID: <1440039239-8772-3-git-send-email-leo.yan@linaro.org>

Add driver for Hi6220 mailbox, the mailbox communicates with MCU; for
sending data, it can support two methods for low level implementation:
one is to use interrupt as acknowledge, another is automatic mode which
without any acknowledge. These two methods have been supported in the
driver. For receiving data, it will depend on the interrupt to notify
the channel has incoming message; enhance rx channel's message queue,
which is based on the code in drivers/mailbox/omap-mailbox.c.

Now mailbox driver is used to send message to MCU to control dynamic
voltage and frequency scaling for CPU, GPU and DDR.

Signed-off-by: Leo Yan <leo.yan at linaro.org>
---
 drivers/mailbox/Kconfig          |   8 +
 drivers/mailbox/Makefile         |   2 +
 drivers/mailbox/hi6220-mailbox.c | 519 +++++++++++++++++++++++++++++++++++++++
 3 files changed, 529 insertions(+)
 create mode 100644 drivers/mailbox/hi6220-mailbox.c

diff --git a/drivers/mailbox/Kconfig b/drivers/mailbox/Kconfig
index e269f08..21b71dd 100644
--- a/drivers/mailbox/Kconfig
+++ b/drivers/mailbox/Kconfig
@@ -70,4 +70,12 @@ config BCM2835_MBOX
 	  the services of the Videocore. Say Y here if you want to use the
 	  BCM2835 Mailbox.
 
+config HI6220_MBOX
+	tristate "Hi6220 Mailbox"
+	depends on ARCH_HISI
+	help
+	  An implementation of the hi6220 mailbox. It is used to send message
+	  between application processors and MCU. Say Y here if you want to build
+	  the Hi6220 mailbox controller driver.
+
 endif
diff --git a/drivers/mailbox/Makefile b/drivers/mailbox/Makefile
index 8e6d822..4ba9f5f 100644
--- a/drivers/mailbox/Makefile
+++ b/drivers/mailbox/Makefile
@@ -13,3 +13,5 @@ obj-$(CONFIG_PCC)		+= pcc.o
 obj-$(CONFIG_ALTERA_MBOX)	+= mailbox-altera.o
 
 obj-$(CONFIG_BCM2835_MBOX)	+= bcm2835-mailbox.o
+
+obj-$(CONFIG_HI6220_MBOX)	+= hi6220-mailbox.o
diff --git a/drivers/mailbox/hi6220-mailbox.c b/drivers/mailbox/hi6220-mailbox.c
new file mode 100644
index 0000000..8f63d0d
--- /dev/null
+++ b/drivers/mailbox/hi6220-mailbox.c
@@ -0,0 +1,519 @@
+/*
+ * Hisilicon's Hi6220 mailbox driver
+ *
+ * RX channel's message queue is based on the code written in
+ * drivers/mailbox/omap-mailbox.c.
+ *
+ * Copyright (c) 2015 Hisilicon Limited.
+ * Copyright (c) 2015 Linaro Limited.
+ *
+ * Author: Leo Yan <leo.yan at linaro.org>
+ *
+ * This program is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation, version 2 of the License.
+ *
+ * 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/device.h>
+#include <linux/err.h>
+#include <linux/interrupt.h>
+#include <linux/io.h>
+#include <linux/kfifo.h>
+#include <linux/mailbox_controller.h>
+#include <linux/module.h>
+#include <linux/platform_device.h>
+#include <linux/spinlock.h>
+#include <linux/slab.h>
+
+#define HI6220_MBOX_CHAN_MAX		32
+#define HI6220_MBOX_CHAN_NUM		2
+#define HI6220_MBOX_CHAN_SLOT_SIZE	64
+
+#define HI6220_MBOX_RX			0x0
+#define HI6220_MBOX_TX			0x1
+
+/* Mailbox message length: 32 bytes */
+#define HI6220_MBOX_MSG_LEN		32
+
+/* Mailbox kfifo size */
+#define HI6220_MBOX_MSG_FIFO_SIZE	512
+
+/* Status & Mode Register */
+#define HI6220_MBOX_MODE_REG		0x0
+
+#define HI6220_MBOX_STATUS_MASK		(0xF << 4)
+#define HI6220_MBOX_STATUS_IDLE		(0x1 << 4)
+#define HI6220_MBOX_STATUS_TX		(0x2 << 4)
+#define HI6220_MBOX_STATUS_RX		(0x4 << 4)
+#define HI6220_MBOX_STATUS_ACK		(0x8 << 4)
+#define HI6220_MBOX_ACK_CONFIG_MASK	(0x1 << 0)
+#define HI6220_MBOX_ACK_AUTOMATIC	(0x1 << 0)
+#define HI6220_MBOX_ACK_IRQ		(0x0 << 0)
+
+/* Data Registers */
+#define HI6220_MBOX_DATA_REG(i)		(0x4 + (i << 2))
+
+/* ACPU Interrupt Register */
+#define HI6220_MBOX_ACPU_INT_RAW_REG	0x400
+#define HI6220_MBOX_ACPU_INT_MSK_REG	0x404
+#define HI6220_MBOX_ACPU_INT_STAT_REG	0x408
+#define HI6220_MBOX_ACPU_INT_CLR_REG	0x40c
+#define HI6220_MBOX_ACPU_INT_ENA_REG	0x500
+#define HI6220_MBOX_ACPU_INT_DIS_REG	0x504
+
+/* MCU Interrupt Register */
+#define HI6220_MBOX_MCU_INT_RAW_REG	0x420
+
+/* Core Id */
+#define HI6220_CORE_ACPU		0x0
+#define HI6220_CORE_MCU			0x2
+
+struct hi6220_mbox_queue {
+	struct kfifo fifo;
+	struct work_struct work;
+	struct mbox_chan *chan;
+	bool full;
+};
+
+struct hi6220_mbox_chan {
+
+	/*
+	 * Description for channel's hardware info:
+	 *  - direction;
+	 *  - peer core id for communication;
+	 *  - local irq vector or number;
+	 *  - remoted irq vector or number for peer core;
+	 */
+	unsigned int dir;
+	unsigned int peer_core;
+	unsigned int remote_irq;
+	unsigned int local_irq;
+
+	/*
+	 * Slot address is cached value derived from index
+	 * within buffer for every channel
+	 */
+	void __iomem *slot;
+
+	/* For rx's fifo operations */
+	struct hi6220_mbox_queue *mq;
+
+	struct hi6220_mbox *parent;
+};
+
+struct hi6220_mbox {
+	struct device *dev;
+
+	spinlock_t lock;
+
+	int irq;
+
+	/* flag of enabling tx's irq mode */
+	bool tx_irq_mode;
+
+	/* region for ipc event */
+	void __iomem *ipc;
+
+	/* region for share mem */
+	void __iomem *buf;
+
+	unsigned int chan_num;
+	struct hi6220_mbox_chan *mchan;
+
+	void *irq_map_chan[HI6220_MBOX_CHAN_MAX];
+	struct mbox_chan *chan;
+	struct mbox_controller controller;
+};
+
+static void hi6220_mbox_set_status(struct hi6220_mbox_chan *mchan, u32 val)
+{
+	u32 status;
+
+	status = readl(mchan->slot + HI6220_MBOX_MODE_REG);
+	status &= ~HI6220_MBOX_STATUS_MASK;
+	status |= val;
+	writel(status, mchan->slot + HI6220_MBOX_MODE_REG);
+}
+
+static void hi6220_mbox_set_mode(struct hi6220_mbox_chan *mchan, u32 val)
+{
+	u32 mode;
+
+	mode = readl(mchan->slot + HI6220_MBOX_MODE_REG);
+	mode &= ~HI6220_MBOX_ACK_CONFIG_MASK;
+	mode |= val;
+	writel(mode, mchan->slot + HI6220_MBOX_MODE_REG);
+}
+
+static bool hi6220_mbox_last_tx_done(struct mbox_chan *chan)
+{
+	struct hi6220_mbox_chan *mchan = chan->con_priv;
+	struct hi6220_mbox *mbox = mchan->parent;
+	u32 status;
+
+	/* Only set idle state for polling mode */
+	BUG_ON(mbox->tx_irq_mode);
+
+	status = readl(mchan->slot + HI6220_MBOX_MODE_REG);
+	status = status & HI6220_MBOX_STATUS_MASK;
+	return (status == HI6220_MBOX_STATUS_IDLE);
+}
+
+static int hi6220_mbox_send_data(struct mbox_chan *chan, void *msg)
+{
+	struct hi6220_mbox_chan *mchan = chan->con_priv;
+	struct hi6220_mbox *mbox = mchan->parent;
+	int irq = mchan->remote_irq;
+	u32 *buf = msg;
+	unsigned long flags;
+	int i;
+
+	hi6220_mbox_set_status(mchan, HI6220_MBOX_STATUS_TX);
+
+	if (mbox->tx_irq_mode)
+		hi6220_mbox_set_mode(mchan, HI6220_MBOX_ACK_IRQ);
+	else
+		hi6220_mbox_set_mode(mchan, HI6220_MBOX_ACK_AUTOMATIC);
+
+	for (i = 0; i < (HI6220_MBOX_MSG_LEN >> 2); i++)
+		writel(buf[i], mchan->slot + HI6220_MBOX_DATA_REG(i));
+
+	/* trigger remote request */
+	spin_lock_irqsave(&mbox->lock, flags);
+	writel(1 << irq, mbox->ipc + HI6220_MBOX_MCU_INT_RAW_REG);
+	spin_unlock_irqrestore(&mbox->lock, flags);
+	return 0;
+}
+
+static void hi6220_mbox_rx_work(struct work_struct *work)
+{
+	struct hi6220_mbox_queue *mq =
+			container_of(work, struct hi6220_mbox_queue, work);
+	struct mbox_chan *chan = mq->chan;
+	struct hi6220_mbox_chan *mchan = chan->con_priv;
+	struct hi6220_mbox *mbox = mchan->parent;
+	int irq = mchan->local_irq, len;
+	u32 msg[HI6220_MBOX_MSG_LEN >> 2];
+
+	while (kfifo_len(&mq->fifo) >= sizeof(msg)) {
+		len = kfifo_out(&mq->fifo, (unsigned char *)&msg, sizeof(msg));
+		WARN_ON(len != sizeof(msg));
+
+		mbox_chan_received_data(chan, (void *)msg);
+		spin_lock_irq(&mbox->lock);
+		if (mq->full) {
+			mq->full = false;
+			writel(1 << irq,
+				mbox->ipc + HI6220_MBOX_ACPU_INT_ENA_REG);
+		}
+		spin_unlock_irq(&mbox->lock);
+	}
+}
+
+static void hi6220_mbox_tx_interrupt(struct mbox_chan *chan)
+{
+	struct hi6220_mbox_chan *mchan = chan->con_priv;
+	struct hi6220_mbox *mbox = mchan->parent;
+	int irq = mchan->local_irq;
+
+	spin_lock(&mbox->lock);
+	writel(1 << irq, mbox->ipc + HI6220_MBOX_ACPU_INT_CLR_REG);
+	spin_unlock(&mbox->lock);
+
+	hi6220_mbox_set_status(mchan, HI6220_MBOX_STATUS_IDLE);
+	mbox_chan_txdone(chan, 0);
+}
+
+static void hi6220_mbox_rx_interrupt(struct mbox_chan *chan)
+{
+	struct hi6220_mbox_chan *mchan = chan->con_priv;
+	struct hi6220_mbox_queue *mq = mchan->mq;
+	struct hi6220_mbox *mbox = mchan->parent;
+	int irq = mchan->local_irq;
+	int msg[HI6220_MBOX_MSG_LEN >> 2];
+	int i, len;
+
+	if (unlikely(kfifo_avail(&mq->fifo) < sizeof(msg))) {
+		spin_lock(&mbox->lock);
+		writel(1 << irq, mbox->ipc + HI6220_MBOX_ACPU_INT_DIS_REG);
+		mq->full = true;
+		spin_unlock(&mbox->lock);
+		goto nomem;
+	}
+
+	for (i = 0; i < (HI6220_MBOX_MSG_LEN >> 2); i++)
+		msg[i] = readl(mchan->slot + HI6220_MBOX_DATA_REG(i));
+
+	/* clear IRQ source */
+	spin_lock(&mbox->lock);
+	writel(1 << irq, mbox->ipc + HI6220_MBOX_ACPU_INT_CLR_REG);
+	spin_unlock(&mbox->lock);
+
+	hi6220_mbox_set_status(mchan, HI6220_MBOX_STATUS_IDLE);
+
+	len = kfifo_in(&mq->fifo, (unsigned char *)&msg, sizeof(msg));
+	WARN_ON(len != sizeof(msg));
+
+nomem:
+	schedule_work(&mq->work);
+}
+
+static irqreturn_t hi6220_mbox_interrupt(int irq, void *p)
+{
+	struct hi6220_mbox *mbox = p;
+	struct hi6220_mbox_chan *mchan;
+	struct mbox_chan *chan;
+	unsigned int state;
+	unsigned int intr_bit;
+
+	state = readl(mbox->ipc + HI6220_MBOX_ACPU_INT_STAT_REG);
+	if (!state) {
+		dev_warn(mbox->dev, "%s: spurious interrupt\n",
+			 __func__);
+		return IRQ_HANDLED;
+	}
+
+	while (state) {
+		intr_bit = __ffs(state);
+		state &= (state - 1);
+
+		chan = mbox->irq_map_chan[intr_bit];
+		if (!chan) {
+			dev_warn(mbox->dev, "%s: unexpected irq vector %d\n",
+				 __func__, intr_bit);
+			continue;
+		}
+
+		mchan = chan->con_priv;
+		if (mchan->dir == HI6220_MBOX_TX)
+			hi6220_mbox_tx_interrupt(chan);
+		else
+			hi6220_mbox_rx_interrupt(chan);
+	}
+
+	return IRQ_HANDLED;
+}
+
+static struct hi6220_mbox_queue *hi6220_mbox_queue_alloc(
+		struct mbox_chan *chan,
+		void (*work)(struct work_struct *))
+{
+	struct hi6220_mbox_queue *mq;
+
+	mq = kzalloc(sizeof(struct hi6220_mbox_queue), GFP_KERNEL);
+	if (!mq)
+		return NULL;
+
+	if (kfifo_alloc(&mq->fifo, HI6220_MBOX_MSG_FIFO_SIZE, GFP_KERNEL))
+		goto error;
+
+	mq->chan = chan;
+	INIT_WORK(&mq->work, work);
+	return mq;
+
+error:
+	kfree(mq);
+	return NULL;
+}
+
+static void hi6220_mbox_queue_free(struct hi6220_mbox_queue *mq)
+{
+	kfifo_free(&mq->fifo);
+	kfree(mq);
+}
+
+static int hi6220_mbox_startup(struct mbox_chan *chan)
+{
+	struct hi6220_mbox_chan *mchan = chan->con_priv;
+	struct hi6220_mbox *mbox = mchan->parent;
+	unsigned int irq = mchan->local_irq;
+	struct hi6220_mbox_queue *mq;
+	unsigned long flags;
+
+	mq = hi6220_mbox_queue_alloc(chan, hi6220_mbox_rx_work);
+	if (!mq)
+		return -ENOMEM;
+	mchan->mq = mq;
+	mbox->irq_map_chan[irq] = (void *)chan;
+
+	/* enable interrupt */
+	spin_lock_irqsave(&mbox->lock, flags);
+	writel(1 << irq, mbox->ipc + HI6220_MBOX_ACPU_INT_ENA_REG);
+	spin_unlock_irqrestore(&mbox->lock, flags);
+	return 0;
+}
+
+static void hi6220_mbox_shutdown(struct mbox_chan *chan)
+{
+	struct hi6220_mbox_chan *mchan = chan->con_priv;
+	struct hi6220_mbox *mbox = mchan->parent;
+	unsigned int irq = mchan->local_irq;
+	unsigned long flags;
+
+	/* disable interrupt */
+	spin_lock_irqsave(&mbox->lock, flags);
+	writel(1 << irq, mbox->ipc + HI6220_MBOX_ACPU_INT_DIS_REG);
+	spin_unlock_irqrestore(&mbox->lock, flags);
+
+	mbox->irq_map_chan[irq] = NULL;
+	flush_work(&mchan->mq->work);
+	hi6220_mbox_queue_free(mchan->mq);
+}
+
+static struct mbox_chan_ops hi6220_mbox_chan_ops = {
+	.send_data    = hi6220_mbox_send_data,
+	.startup      = hi6220_mbox_startup,
+	.shutdown     = hi6220_mbox_shutdown,
+	.last_tx_done = hi6220_mbox_last_tx_done,
+};
+
+static void hi6220_mbox_init_hw(struct hi6220_mbox *mbox)
+{
+	struct hi6220_mbox_chan init_data[HI6220_MBOX_CHAN_NUM] = {
+		{ HI6220_MBOX_RX, HI6220_CORE_MCU, 1, 10 },
+		{ HI6220_MBOX_TX, HI6220_CORE_MCU, 0, 11 },
+	};
+	struct hi6220_mbox_chan *mchan = mbox->mchan;
+	int i;
+
+	for (i = 0; i < HI6220_MBOX_CHAN_NUM; i++) {
+		memcpy(&mchan[i], &init_data[i], sizeof(*mchan));
+		mchan[i].slot = mbox->buf + HI6220_MBOX_CHAN_SLOT_SIZE * i;
+		mchan[i].parent = mbox;
+	}
+
+	/* mask and clear all interrupt vectors */
+	writel(0x0,  mbox->ipc + HI6220_MBOX_ACPU_INT_MSK_REG);
+	writel(~0x0, mbox->ipc + HI6220_MBOX_ACPU_INT_CLR_REG);
+
+	/* use interrupt for tx's ack */
+	mbox->tx_irq_mode = true;
+}
+
+static const struct of_device_id hi6220_mbox_of_match[] = {
+	{ .compatible = "hisilicon,hi6220-mbox", },
+	{},
+};
+MODULE_DEVICE_TABLE(of, hi6220_mbox_of_match);
+
+static int hi6220_mbox_probe(struct platform_device *pdev)
+{
+	struct device *dev = &pdev->dev;
+	struct hi6220_mbox *mbox;
+	struct resource *res;
+	int i, err;
+
+	mbox = devm_kzalloc(dev, sizeof(*mbox), GFP_KERNEL);
+	if (!mbox)
+		return -ENOMEM;
+
+	mbox->dev = dev;
+	mbox->chan_num = HI6220_MBOX_CHAN_NUM;
+	mbox->mchan = devm_kzalloc(dev,
+		mbox->chan_num * sizeof(*mbox->mchan), GFP_KERNEL);
+	if (!mbox->mchan)
+		return -ENOMEM;
+
+	mbox->chan = devm_kzalloc(dev,
+		mbox->chan_num * sizeof(*mbox->chan), GFP_KERNEL);
+	if (!mbox->chan)
+		return -ENOMEM;
+
+	mbox->irq = platform_get_irq(pdev, 0);
+	if (mbox->irq < 0)
+		return mbox->irq;
+
+	res = platform_get_resource(pdev, IORESOURCE_MEM, 0);
+	mbox->ipc = devm_ioremap_resource(dev, res);
+	if (IS_ERR(mbox->ipc)) {
+		dev_err(dev, "ioremap ipc failed\n");
+		return PTR_ERR(mbox->ipc);
+	}
+
+	res = platform_get_resource(pdev, IORESOURCE_MEM, 1);
+	mbox->buf = devm_ioremap_resource(dev, res);
+	if (IS_ERR(mbox->buf)) {
+		dev_err(dev, "ioremap buffer failed\n");
+		return PTR_ERR(mbox->buf);
+	}
+
+	err = devm_request_irq(dev, mbox->irq, hi6220_mbox_interrupt, 0,
+			dev_name(dev), mbox);
+	if (err) {
+		dev_err(dev, "Failed to register a mailbox IRQ handler: %d\n",
+			err);
+		return -ENODEV;
+	}
+
+	/* init hardware parameters */
+	hi6220_mbox_init_hw(mbox);
+
+	spin_lock_init(&mbox->lock);
+
+	for (i = 0; i < mbox->chan_num; i++) {
+		mbox->chan[i].con_priv = &mbox->mchan[i];
+		mbox->irq_map_chan[i] = NULL;
+	}
+
+	mbox->controller.dev = dev;
+	mbox->controller.chans = &mbox->chan[0];
+	mbox->controller.num_chans = mbox->chan_num;
+	mbox->controller.ops = &hi6220_mbox_chan_ops;
+
+	if (mbox->tx_irq_mode)
+		mbox->controller.txdone_irq = true;
+	else {
+		mbox->controller.txdone_poll = true;
+		mbox->controller.txpoll_period = 5;
+	}
+
+	err = mbox_controller_register(&mbox->controller);
+	if (err) {
+		dev_err(dev, "Failed to register mailbox %d\n", err);
+		return err;
+	}
+
+	platform_set_drvdata(pdev, mbox);
+	dev_info(dev, "Mailbox enabled\n");
+	return 0;
+}
+
+static int hi6220_mbox_remove(struct platform_device *pdev)
+{
+	struct hi6220_mbox *mbox = platform_get_drvdata(pdev);
+
+	mbox_controller_unregister(&mbox->controller);
+	return 0;
+}
+
+static struct platform_driver hi6220_mbox_driver = {
+	.driver = {
+		.name = "hi6220-mbox",
+		.owner = THIS_MODULE,
+		.of_match_table = hi6220_mbox_of_match,
+	},
+	.probe	= hi6220_mbox_probe,
+	.remove	= hi6220_mbox_remove,
+};
+
+static int __init hi6220_mbox_init(void)
+{
+	return platform_driver_register(&hi6220_mbox_driver);
+}
+core_initcall(hi6220_mbox_init);
+
+static void __exit hi6220_mbox_exit(void)
+{
+	platform_driver_unregister(&hi6220_mbox_driver);
+}
+module_exit(hi6220_mbox_exit);
+
+MODULE_AUTHOR("Leo Yan <leo.yan at linaro.org>");
+MODULE_DESCRIPTION("Hi6220 mailbox driver");
+MODULE_LICENSE("GPL v2");
-- 
1.9.1



From leo.yan at linaro.org  Wed Aug 19 19:53:59 2015
From: leo.yan at linaro.org (Leo Yan)
Date: Thu, 20 Aug 2015 10:53:59 +0800
Subject: [PATCH v2 3/3] arm64: dts: add Hi6220 mailbox node
In-Reply-To: <1440039239-8772-1-git-send-email-leo.yan@linaro.org>
References: <1440039239-8772-1-git-send-email-leo.yan@linaro.org>
Message-ID: <1440039239-8772-4-git-send-email-leo.yan@linaro.org>

On Hi6220, below memory regions in DDR have specific purpose:

  0x05e0,0000 - 0x05ef,ffff: For MCU firmware using at runtime;
  0x0740,f000 - 0x0740,ffff: For MCU firmware's section;
  0x06df,f000 - 0x06df,ffff: For mailbox message data.

This patch reserves these memory regions and add device node for
mailbox in dts.

Signed-off-by: Leo Yan <leo.yan at linaro.org>
---
 arch/arm64/boot/dts/hisilicon/hi6220-hikey.dts | 20 +++++++++++++++++---
 arch/arm64/boot/dts/hisilicon/hi6220.dtsi      |  8 ++++++++
 2 files changed, 25 insertions(+), 3 deletions(-)

diff --git a/arch/arm64/boot/dts/hisilicon/hi6220-hikey.dts b/arch/arm64/boot/dts/hisilicon/hi6220-hikey.dts
index e36a539..d5470d3 100644
--- a/arch/arm64/boot/dts/hisilicon/hi6220-hikey.dts
+++ b/arch/arm64/boot/dts/hisilicon/hi6220-hikey.dts
@@ -7,9 +7,6 @@
 
 /dts-v1/;
 
-/*Reserved 1MB memory for MCU*/
-/memreserve/ 0x05e00000 0x00100000;
-
 #include "hi6220.dtsi"
 
 / {
@@ -28,4 +25,21 @@
 		device_type = "memory";
 		reg = <0x0 0x0 0x0 0x40000000>;
 	};
+
+	reserved-memory {
+		#address-cells = <2>;
+		#size-cells = <2>;
+		ranges;
+
+		mcu-buf at 05e00000 {
+			no-map;
+			reg = <0x0 0x05e00000 0x0 0x00100000>,	/* MCU firmware buffer */
+			      <0x0 0x0740f000 0x0 0x00001000>;	/* MCU firmware section */
+		};
+
+		mbox-buf at 06dff000 {
+			no-map;
+			reg = <0x0 0x06dff000 0x0 0x00001000>;	/* Mailbox message buf */
+		};
+	};
 };
diff --git a/arch/arm64/boot/dts/hisilicon/hi6220.dtsi b/arch/arm64/boot/dts/hisilicon/hi6220.dtsi
index 3f03380..9ff25bc 100644
--- a/arch/arm64/boot/dts/hisilicon/hi6220.dtsi
+++ b/arch/arm64/boot/dts/hisilicon/hi6220.dtsi
@@ -167,5 +167,13 @@
 			clocks = <&ao_ctrl 36>, <&ao_ctrl 36>;
 			clock-names = "uartclk", "apb_pclk";
 		};
+
+		mailbox: mailbox at f7510000 {
+			#mbox-cells = <1>;
+			compatible = "hisilicon,hi6220-mbox";
+			reg = <0x0 0xf7510000 0x0 0x1000>, /* IPC_S */
+			      <0x0 0x06dff800 0x0 0x0800>; /* Mailbox buffer */
+			interrupts = <GIC_SPI 94 IRQ_TYPE_LEVEL_HIGH>;
+		};
 	};
 };
-- 
1.9.1



From hongzhou.yang at mediatek.com  Wed Aug 19 20:38:51 2015
From: hongzhou.yang at mediatek.com (Hongzhou Yang)
Date: Wed, 19 Aug 2015 20:38:51 -0700
Subject: [PATCH v2] pinctrl: mediatek: Fix multiple registration issue.
Message-ID: <1440041931-38278-1-git-send-email-hongzhou.yang@mediatek.com>

Since our common driver need support main chip and PMU
at the same time, that means it will register two
pinctrl device, and the pinctrl_desc structure should
be used two times.

But pinctrl_desc use global static definition, then
the latest registered pinctrl device will overwrite
the old one's, all members in pinctrl_desc will set to
the new one's, such as name, pins and pins numbers, etc.
This is a bug. Changing to use devm_kzalloc to fix it.

Cc: stable at vger.kernel.org # v4.1+
Signed-off-by: Hongzhou Yang <hongzhou.yang at mediatek.com>
---
 Use dynamic allocation to fix multiple registration issue.

 drivers/pinctrl/mediatek/pinctrl-mtk-common.c |   26 ++++++++++++++-----------
 drivers/pinctrl/mediatek/pinctrl-mtk-common.h |    1 +
 2 files changed, 16 insertions(+), 11 deletions(-)

diff --git a/drivers/pinctrl/mediatek/pinctrl-mtk-common.c b/drivers/pinctrl/mediatek/pinctrl-mtk-common.c
index ad1ea16..911c736 100644
--- a/drivers/pinctrl/mediatek/pinctrl-mtk-common.c
+++ b/drivers/pinctrl/mediatek/pinctrl-mtk-common.c
@@ -1202,12 +1202,6 @@ static int mtk_pctrl_build_state(struct platform_device *pdev)
 	return 0;
 }
 
-static struct pinctrl_desc mtk_pctrl_desc = {
-	.confops	= &mtk_pconf_ops,
-	.pctlops	= &mtk_pctrl_ops,
-	.pmxops		= &mtk_pmx_ops,
-};
-
 int mtk_pctrl_init(struct platform_device *pdev,
 		const struct mtk_pinctrl_devdata *data,
 		struct regmap *regmap)
@@ -1265,12 +1259,22 @@ int mtk_pctrl_init(struct platform_device *pdev,
 
 	for (i = 0; i < pctl->devdata->npins; i++)
 		pins[i] = pctl->devdata->pins[i].pin;
-	mtk_pctrl_desc.name = dev_name(&pdev->dev);
-	mtk_pctrl_desc.owner = THIS_MODULE;
-	mtk_pctrl_desc.pins = pins;
-	mtk_pctrl_desc.npins = pctl->devdata->npins;
+
+	pctl->pctl_desc = devm_kzalloc(&pdev->dev, sizeof(*pctl->pctl_desc),
+				GFP_KERNEL);
+	if (!pctl->pctl_desc)
+		return -ENOMEM;
+
+	pctl->pctl_desc->name = dev_name(&pdev->dev);
+	pctl->pctl_desc->owner = THIS_MODULE;
+	pctl->pctl_desc->pins = pins;
+	pctl->pctl_desc->npins = pctl->devdata->npins;
+	pctl->pctl_desc->confops = &mtk_pconf_ops;
+	pctl->pctl_desc->pctlops = &mtk_pctrl_ops;
+	pctl->pctl_desc->pmxops = &mtk_pmx_ops;
 	pctl->dev = &pdev->dev;
-	pctl->pctl_dev = pinctrl_register(&mtk_pctrl_desc, &pdev->dev, pctl);
+
+	pctl->pctl_dev = pinctrl_register(pctl->pctl_desc, &pdev->dev, pctl);
 	if (IS_ERR(pctl->pctl_dev)) {
 		dev_err(&pdev->dev, "couldn't register pinctrl driver\n");
 		return PTR_ERR(pctl->pctl_dev);
diff --git a/drivers/pinctrl/mediatek/pinctrl-mtk-common.h b/drivers/pinctrl/mediatek/pinctrl-mtk-common.h
index 30213e5..93d6f5b 100644
--- a/drivers/pinctrl/mediatek/pinctrl-mtk-common.h
+++ b/drivers/pinctrl/mediatek/pinctrl-mtk-common.h
@@ -256,6 +256,7 @@ struct mtk_pinctrl_devdata {
 struct mtk_pinctrl {
 	struct regmap	*regmap1;
 	struct regmap	*regmap2;
+	struct pinctrl_desc *pctl_desc;
 	struct device           *dev;
 	struct gpio_chip	*chip;
 	struct mtk_pinctrl_group	*groups;
-- 
1.7.9.5



From axel.lin at ingics.com  Wed Aug 19 20:49:35 2015
From: axel.lin at ingics.com (Axel Lin)
Date: Thu, 20 Aug 2015 11:49:35 +0800
Subject: [PATCH v2] pinctrl: mediatek: Fix multiple registration issue.
In-Reply-To: <1440041931-38278-1-git-send-email-hongzhou.yang@mediatek.com>
References: <1440041931-38278-1-git-send-email-hongzhou.yang@mediatek.com>
Message-ID: <CAFRkauDE4QRnZP4q61JyX+t8rn3zOtokiESJTV4uak71zM0kTg@mail.gmail.com>

2015-08-20 11:38 GMT+08:00 Hongzhou Yang <hongzhou.yang at mediatek.com>:
> Since our common driver need support main chip and PMU
> at the same time, that means it will register two
> pinctrl device, and the pinctrl_desc structure should
> be used two times.
>
> But pinctrl_desc use global static definition, then
> the latest registered pinctrl device will overwrite
> the old one's, all members in pinctrl_desc will set to
> the new one's, such as name, pins and pins numbers, etc.
> This is a bug. Changing to use devm_kzalloc to fix it.
>
> Cc: stable at vger.kernel.org # v4.1+
> Signed-off-by: Hongzhou Yang <hongzhou.yang at mediatek.com>
> ---
>  Use dynamic allocation to fix multiple registration issue.
>
>  drivers/pinctrl/mediatek/pinctrl-mtk-common.c |   26 ++++++++++++++-----------
>  drivers/pinctrl/mediatek/pinctrl-mtk-common.h |    1 +
>  2 files changed, 16 insertions(+), 11 deletions(-)
>
> diff --git a/drivers/pinctrl/mediatek/pinctrl-mtk-common.c b/drivers/pinctrl/mediatek/pinctrl-mtk-common.c
> index ad1ea16..911c736 100644
> --- a/drivers/pinctrl/mediatek/pinctrl-mtk-common.c
> +++ b/drivers/pinctrl/mediatek/pinctrl-mtk-common.c
> @@ -1202,12 +1202,6 @@ static int mtk_pctrl_build_state(struct platform_device *pdev)
>         return 0;
>  }
>
> -static struct pinctrl_desc mtk_pctrl_desc = {
> -       .confops        = &mtk_pconf_ops,
> -       .pctlops        = &mtk_pctrl_ops,
> -       .pmxops         = &mtk_pmx_ops,
> -};
> -
>  int mtk_pctrl_init(struct platform_device *pdev,
>                 const struct mtk_pinctrl_devdata *data,
>                 struct regmap *regmap)
> @@ -1265,12 +1259,22 @@ int mtk_pctrl_init(struct platform_device *pdev,
>
>         for (i = 0; i < pctl->devdata->npins; i++)
>                 pins[i] = pctl->devdata->pins[i].pin;
> -       mtk_pctrl_desc.name = dev_name(&pdev->dev);
> -       mtk_pctrl_desc.owner = THIS_MODULE;
> -       mtk_pctrl_desc.pins = pins;
> -       mtk_pctrl_desc.npins = pctl->devdata->npins;
> +
> +       pctl->pctl_desc = devm_kzalloc(&pdev->dev, sizeof(*pctl->pctl_desc),
> +                               GFP_KERNEL);
> +       if (!pctl->pctl_desc)
> +               return -ENOMEM;
> +
> +       pctl->pctl_desc->name = dev_name(&pdev->dev);
> +       pctl->pctl_desc->owner = THIS_MODULE;
> +       pctl->pctl_desc->pins = pins;
> +       pctl->pctl_desc->npins = pctl->devdata->npins;
> +       pctl->pctl_desc->confops = &mtk_pconf_ops;
> +       pctl->pctl_desc->pctlops = &mtk_pctrl_ops;
> +       pctl->pctl_desc->pmxops = &mtk_pmx_ops;
>         pctl->dev = &pdev->dev;
> -       pctl->pctl_dev = pinctrl_register(&mtk_pctrl_desc, &pdev->dev, pctl);
> +
> +       pctl->pctl_dev = pinctrl_register(pctl->pctl_desc, &pdev->dev, pctl);
>         if (IS_ERR(pctl->pctl_dev)) {
>                 dev_err(&pdev->dev, "couldn't register pinctrl driver\n");
>                 return PTR_ERR(pctl->pctl_dev);
> diff --git a/drivers/pinctrl/mediatek/pinctrl-mtk-common.h b/drivers/pinctrl/mediatek/pinctrl-mtk-common.h
> index 30213e5..93d6f5b 100644
> --- a/drivers/pinctrl/mediatek/pinctrl-mtk-common.h
> +++ b/drivers/pinctrl/mediatek/pinctrl-mtk-common.h
> @@ -256,6 +256,7 @@ struct mtk_pinctrl_devdata {
>  struct mtk_pinctrl {
>         struct regmap   *regmap1;
>         struct regmap   *regmap2;
> +       struct pinctrl_desc *pctl_desc;
Use
struct pinctrl_desc pctl_desc;

Then you can remove the devm_kzalloc.


From architt at codeaurora.org  Wed Aug 19 21:29:49 2015
From: architt at codeaurora.org (Archit Taneja)
Date: Thu, 20 Aug 2015 09:59:49 +0530
Subject: [PATCH v3 0/14] Add Analogix Core Display Port Driver
In-Reply-To: <1439995728-18046-1-git-send-email-ykk@rock-chips.com>
References: <1439995728-18046-1-git-send-email-ykk@rock-chips.com>
Message-ID: <55D557BD.8070004@codeaurora.org>

Hi,

On 08/19/2015 08:18 PM, Yakir Yang wrote:
>
> Hi all,
>     The Samsung Exynos eDP controller and Rockchip RK3288 eDP controller
> share the same IP, so a lot of parts can be re-used. I split the common
> code into bridge directory, then rk3288 and exynos only need to keep
> some platform code. Cause I can't find the exact IP name of exynos dp
> controller, so I decide to name dp core driver with "analogix" which I
> find in rk3288 eDP TRM ;)
>
> Beyond that, there are three light registers setting differents bewteen
> exynos and rk3288.
> 1. RK3288 have five special pll resigters which not indicata in exynos
>     dp controller.
> 2. The address of DP_PHY_PD(dp phy power manager register) are different
>     between rk3288 and exynos.
> 3. Rk3288 and exynos have different setting with AUX_HW_RETRY_CTL(dp debug
>     register).
>
> I have verified this series on two kinds of rockchip platform board, one
> is rk3288 sdk board which connect with a 2K display port monitor, the other
> is google jerry chromebook which connect with a eDP screen "cnm,n116bgeea2",
> both of them works rightlly.
>
> I haven't verified the dp function on samsung platform, cause I haven't got
> exynos boards. I can only ensure that there are no build error on samsung
> platform, wish some samsung guys help to test. ;)
>
> Thanks,
> - Yakir
>
> Changes in v3:
> - Take Thierry Reding suggest, move exynos's video_timing code
>    to analogix_dp-exynos platform driver, add get_modes method
>    to struct analogix_dp_plat_data.
> - Take Heiko suggest, rename some "samsung*" dts propery to "analogix*".
> - Take Thierry Reding suggest, dynamic parse video timing info from
>    struct drm_display_mode and struct drm_display_info.
> - Take Thierry Reding suggest, link_rate and lane_count shouldn't config to
>    the DT property value directly, but we can take those as hardware limite.
>    For example, RK3288 only support 4 physical lanes of 2.7/1.62 Gbps/lane,
>    so DT property would like "link-rate = 0x0a" "lane-count = 4".
> - Take Heiko suggest, add devicetree binding documents.
> - Take Thierry Reding suggest, remove sync pol & colorimetry properies
>    from the new analogix dp driver devicetree binding.
> - Update the exist exynos dtsi file with the latest DP DT properies.
> - Take Thierry Reding and Heiko suggest, leave "sclk_edp_24m" to rockchip
>    dp phy driver which name to "24m", and leave "sclk_edp" to analogix dp
>    core driver which name to "dp", and leave "pclk_edp" to rockchip dp platform
>    driver which name to "pclk".
> - Take Heiko suggest, add devicetree binding document.
> - Take Heiko suggest, remove "rockchip,panel" DT property, take use of remote
>    point to get panel node.
> - Add the new function point analogix_dp_platdata.get_modes init.
> - Take Heiko suggest, add rockchip dp phy driver,
>    collect the phy clocks and power control.
> - Add "analogix,need-force-hpd" to indicate whether driver need foce
>    hpd when hpd detect failed.
> - move dp hpd detect to connector detect function.
> - Add edid modes parse support
>
> Changes in v2:
> - Take Joe Preches advise, improved commit message more readable, and
>    avoid using some uncommon style like bellow:
>    -  retval = exynos_dp_read_bytes_from_i2c(...
> 				...)
>    +  retval =
>    +  exynos_dp_read_bytes_from_i2c(......);
> - Take Jingoo Han suggest, just remove my name from author list.
> - Take Jingoo Han suggest, remove new copyright
> - Fix compiled failed dut to analogix_dp_device misspell
> - Take Heiko suggest, get panel node with remote-endpoint method,
>    and create devicetree binding for driver.
> - Remove the clock enable/disbale with "sclk_edp" & "sclk_edp_24m",
>    leave those clock to rockchip dp phy driver.
> - Add GNU license v2 declared and samsung copyright
> - Fix compile failed dut to phy_pd_addr variable misspell error
>
> Yakir Yang (14):
>    drm: exynos/dp: fix code style
>    drm: exynos/dp: convert to drm bridge mode
>    drm: bridge: analogix_dp: split exynos dp driver to bridge dir
>    drm: bridge/analogix_dp: dynamic parse sync_pol & interlace &
>      colorimetry
>    drm: bridge/analogix_dp: fix link_rate & lane_count bug
>    Documentation: drm/bridge: add document for analogix_dp
>    drm: rockchip/dp: add rockchip platform dp driver
>    phy: Add driver for rockchip Display Port PHY
>    drm: bridge/analogix_dp: add platform device type support
>    drm: bridge: analogix_dp: add some rk3288 special registers setting
>    drm: bridge: analogix_dp: try force hpd after plug in lookup failed
>    drm: bridge/analogix_dp: expand the delay time for hpd detect
>    drm: bridge/analogix_dp: move hpd detect to connector detect function
>    drm: bridge/analogix_dp: add edid modes parse in get_modes method
>
>   .../devicetree/bindings/drm/bridge/analogix_dp.txt |   73 +
>   .../devicetree/bindings/phy/rockchip-dp-phy.txt    |   26 +
>   .../bindings/video/analogix_dp-rockchip.txt        |   83 ++
>   .../devicetree/bindings/video/exynos_dp.txt        |   51 +-
>   arch/arm/boot/dts/exynos5250-arndale.dts           |   10 +-
>   arch/arm/boot/dts/exynos5250-smdk5250.dts          |   10 +-
>   arch/arm/boot/dts/exynos5250-snow.dts              |   12 +-
>   arch/arm/boot/dts/exynos5250-spring.dts            |   12 +-
>   arch/arm/boot/dts/exynos5420-peach-pit.dts         |   12 +-
>   arch/arm/boot/dts/exynos5420-smdk5420.dts          |   10 +-
>   arch/arm/boot/dts/exynos5800-peach-pi.dts          |   12 +-
>   drivers/gpu/drm/bridge/Kconfig                     |    5 +
>   drivers/gpu/drm/bridge/Makefile                    |    1 +
>   drivers/gpu/drm/bridge/analogix_dp_core.c          | 1382 +++++++++++++++++++
>   drivers/gpu/drm/bridge/analogix_dp_core.h          |  286 ++++
>   drivers/gpu/drm/bridge/analogix_dp_reg.c           | 1294 ++++++++++++++++++
>   .../exynos_dp_reg.h => bridge/analogix_dp_reg.h}   |  270 ++--
>   drivers/gpu/drm/exynos/Kconfig                     |    5 +-
>   drivers/gpu/drm/exynos/Makefile                    |    2 +-
>   drivers/gpu/drm/exynos/analogix_dp-exynos.c        |  347 +++++
>   drivers/gpu/drm/exynos/exynos_dp_core.c            | 1416 --------------------
>   drivers/gpu/drm/exynos/exynos_dp_core.h            |  282 ----
>   drivers/gpu/drm/exynos/exynos_dp_reg.c             | 1263 -----------------
>   drivers/gpu/drm/rockchip/Kconfig                   |    9 +
>   drivers/gpu/drm/rockchip/Makefile                  |    1 +
>   drivers/gpu/drm/rockchip/analogix_dp-rockchip.c    |  390 ++++++
>   drivers/phy/Kconfig                                |    7 +
>   drivers/phy/Makefile                               |    1 +
>   drivers/phy/phy-rockchip-dp.c                      |  185 +++
>   include/drm/bridge/analogix_dp.h                   |   40 +
>   30 files changed, 4325 insertions(+), 3172 deletions(-)
>   create mode 100644 Documentation/devicetree/bindings/drm/bridge/analogix_dp.txt
>   create mode 100644 Documentation/devicetree/bindings/phy/rockchip-dp-phy.txt
>   create mode 100644 Documentation/devicetree/bindings/video/analogix_dp-rockchip.txt
>   create mode 100644 drivers/gpu/drm/bridge/analogix_dp_core.c
>   create mode 100644 drivers/gpu/drm/bridge/analogix_dp_core.h
>   create mode 100644 drivers/gpu/drm/bridge/analogix_dp_reg.c

Minor comment: Since there are a few files required for the driver,
could you create a separate folder within drivers/gpu/drm/bridge?

Thanks,
Archit

-- 
Qualcomm Innovation Center, Inc. is a member of Code Aurora Forum,
a Linux Foundation Collaborative Project


From kishon at ti.com  Wed Aug 19 21:40:30 2015
From: kishon at ti.com (Kishon Vijay Abraham I)
Date: Thu, 20 Aug 2015 10:10:30 +0530
Subject: [PATCH v3 08/14] phy: Add driver for rockchip Display Port PHY
In-Reply-To: <1439995877-18496-1-git-send-email-ykk@rock-chips.com>
References: <1439995728-18046-1-git-send-email-ykk@rock-chips.com>
 <1439995877-18496-1-git-send-email-ykk@rock-chips.com>
Message-ID: <55D55A3E.8090905@ti.com>

Hi,

On Wednesday 19 August 2015 08:21 PM, Yakir Yang wrote:
> Signed-off-by: Yakir Yang <ykk at rock-chips.com>

where's the commit message?
> ---
> Changes in v3:
> - Take Heiko suggest, add rockchip dp phy driver,
>   collect the phy clocks and power control.
> 
> Changes in v2: None
> 
>  .../devicetree/bindings/phy/rockchip-dp-phy.txt    |  26 +++
>  drivers/phy/Kconfig                                |   7 +
>  drivers/phy/Makefile                               |   1 +
>  drivers/phy/phy-rockchip-dp.c                      | 185 +++++++++++++++++++++
>  4 files changed, 219 insertions(+)
>  create mode 100644 Documentation/devicetree/bindings/phy/rockchip-dp-phy.txt
>  create mode 100644 drivers/phy/phy-rockchip-dp.c
> 
> diff --git a/Documentation/devicetree/bindings/phy/rockchip-dp-phy.txt b/Documentation/devicetree/bindings/phy/rockchip-dp-phy.txt
> new file mode 100644
> index 0000000..5de1088
> --- /dev/null
> +++ b/Documentation/devicetree/bindings/phy/rockchip-dp-phy.txt
> @@ -0,0 +1,26 @@
> +Rockchip Soc Seroes Display Port PHY
> +------------------------------------
> +
> +Required properties:
> +- compatible : should be one of the following supported values:
> +	 - "rockchip.rk3288-dp-phy"
> +
> +- reg : a list of registers used by phy driver
> +- clocks: from common clock binding: handle to dp clock.
> +	of memory mapped region.
> +- clock-names: from common clock binding:
> +	Required elements: "sclk_dp" "sclk_dp_24m"
> +
> +- rockchip,grf: this soc should set GRF regs, so need get grf here.
> +- #phy-cells : from the generic PHY bindings, must be 0;
> +
> +Example:
> +
> +edp_phy: phy at ff770274 {
> +	compatilble = "rockchip,rk3288-dp-phy";
> +	reg = <0xff770274 4>;
> +	rockchip,grf = <&grf>;
> +	clocks = <&cru SCLK_EDP_24M>;
> +	clock-names = "24m";
> +	#phy-cells = <0>;
> +}
> diff --git a/drivers/phy/Kconfig b/drivers/phy/Kconfig
> index 6b8dd16..da00440 100644
> --- a/drivers/phy/Kconfig
> +++ b/drivers/phy/Kconfig
> @@ -297,6 +297,13 @@ config PHY_ROCKCHIP_USB
>  	help
>  	  Enable this to support the Rockchip USB 2.0 PHY.
>  
> +config PHY_ROCKCHIP_DP
> +	tristate "Rockchip Display Port PHY Driver"
> +	depends on ARCH_ROCKCHIP && OF
> +	select GENERIC_PHY
> +	help
> +	  Enable this to support the Rockchip Display Port PHY.
> +
>  config PHY_ST_SPEAR1310_MIPHY
>  	tristate "ST SPEAR1310-MIPHY driver"
>  	select GENERIC_PHY
> diff --git a/drivers/phy/Makefile b/drivers/phy/Makefile
> index f344e1b..35e3ce6 100644
> --- a/drivers/phy/Makefile
> +++ b/drivers/phy/Makefile
> @@ -33,6 +33,7 @@ phy-exynos-usb2-$(CONFIG_PHY_S5PV210_USB2)	+= phy-s5pv210-usb2.o
>  obj-$(CONFIG_PHY_EXYNOS5_USBDRD)	+= phy-exynos5-usbdrd.o
>  obj-$(CONFIG_PHY_QCOM_APQ8064_SATA)	+= phy-qcom-apq8064-sata.o
>  obj-$(CONFIG_PHY_ROCKCHIP_USB) += phy-rockchip-usb.o
> +obj-$(CONFIG_PHY_ROCKCHIP_DP)		+= phy-rockchip-dp.o
>  obj-$(CONFIG_PHY_QCOM_IPQ806X_SATA)	+= phy-qcom-ipq806x-sata.o
>  obj-$(CONFIG_PHY_ST_SPEAR1310_MIPHY)	+= phy-spear1310-miphy.o
>  obj-$(CONFIG_PHY_ST_SPEAR1340_MIPHY)	+= phy-spear1340-miphy.o
> diff --git a/drivers/phy/phy-rockchip-dp.c b/drivers/phy/phy-rockchip-dp.c
> new file mode 100644
> index 0000000..4759111
> --- /dev/null
> +++ b/drivers/phy/phy-rockchip-dp.c
> @@ -0,0 +1,185 @@
> +/*
> + * Rockchip DP PHY driver
> + *
> + * Copyright (C) 2015 FuZhou Rockchip Co., Ltd.
> + * Author: Yakir Yang <ykk@@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.
> + */
> +
> +#include <linux/io.h>
> +#include <linux/kernel.h>
> +#include <linux/module.h>
> +#include <linux/of.h>
> +#include <linux/of_address.h>
> +#include <linux/clk.h>
> +#include <linux/phy/phy.h>
> +#include <linux/regmap.h>
> +#include <linux/mfd/syscon.h>
> +#include <linux/platform_device.h>
> +
> +#define GRF_SOC_CON12                   0x0274
> +#define GRF_EDP_REF_CLK_SEL_INTER       BIT(4)
> +
> +#define DP_PHY_SIDDQ_WRITE_EN           BIT(21)
> +#define DP_PHY_SIDDQ_ON                 0
> +#define DP_PHY_SIDDQ_OFF                BIT(5)
> +
> +struct rockchip_dp_phy {
> +	struct device  *dev;
> +	struct regmap  *grf;
> +	void __iomem   *regs;
> +	struct clk     *phy_24m;
> +};
> +
> +static int rockchip_dp_phy_clk_enable(struct rockchip_dp_phy *dp)
> +{
> +	int ret = 0;
> +
> +	ret = clk_set_rate(dp->phy_24m, 24000000);
> +	if (ret < 0) {
> +		dev_err(dp->dev, "cannot set clock phy_24m %d\n", ret);
> +		return ret;
> +	}
> +
> +	ret = clk_prepare_enable(dp->phy_24m);
> +	if (ret < 0) {
> +		dev_err(dp->dev, "cannot enable clock phy_24m %d\n", ret);
> +		return ret;
> +	}
> +
> +	return 0;
> +}
> +
> +static int rockchip_dp_phy_clk_disable(struct rockchip_dp_phy *dp)
> +{
> +	clk_disable_unprepare(dp->phy_24m);
> +
> +	return 0;
> +}
> +
> +static int rockchip_set_phy_state(struct phy *phy, bool enable)
> +{
> +	struct rockchip_dp_phy *dp = phy_get_drvdata(phy);
> +
> +	if (enable) {
> +		rockchip_dp_phy_clk_enable(dp);
> +		writel(DP_PHY_SIDDQ_WRITE_EN | DP_PHY_SIDDQ_ON, dp->regs);
> +	} else {
> +		rockchip_dp_phy_clk_disable(dp);
> +		writel(DP_PHY_SIDDQ_WRITE_EN | DP_PHY_SIDDQ_OFF, dp->regs);
> +	}
> +
> +	return 0;
> +}
> +
> +static int rockchip_dp_phy_power_on(struct phy *phy)
> +{
> +	return rockchip_set_phy_state(phy, true);
> +}
> +
> +static int rockchip_dp_phy_power_off(struct phy *phy)
> +{
> +	return rockchip_set_phy_state(phy, false);
> +}
> +
> +static struct phy_ops rockchip_dp_phy_ops = {
> +	.power_on	= rockchip_dp_phy_power_on,
> +	.power_off	= rockchip_dp_phy_power_off,
> +	.owner		= THIS_MODULE,
> +};
> +
> +static int rockchip_dp_phy_init(struct rockchip_dp_phy *dp)
> +{
> +	struct device *dev = dp->dev;
> +	struct device_node *np = dev->of_node;
> +	int ret;
> +
> +	dp->phy_24m = devm_clk_get(dev, "24m");
> +	if (IS_ERR(dp->phy_24m)) {
> +		dev_err(dev, "cannot get clock 24m\n");
> +		return PTR_ERR(dp->phy_24m);
> +	}
> +
> +	ret = rockchip_dp_phy_clk_enable(dp);
> +	if (ret < 0) {
> +		dev_err(dp->dev, "cannot enable dp phy clk %d\n", ret);
> +		return ret;
> +	}
> +
> +	dp->grf = syscon_regmap_lookup_by_phandle(np, "rockchip,grf");
> +	if (IS_ERR(dp->grf)) {
> +		dev_err(dev, "rk3288-dp needs rockchip,grf property\n");
> +		return PTR_ERR(dp->grf);
> +	}
> +
> +	ret = regmap_write(dp->grf, GRF_SOC_CON12,
> +			   GRF_EDP_REF_CLK_SEL_INTER |
> +			   (GRF_EDP_REF_CLK_SEL_INTER << 16));
> +	if (ret != 0) {
> +		dev_err(dp->dev, "Could not config GRF edp ref clk: %d\n", ret);
> +		return ret;
> +	}

This function can be split to do only clk_get and syscon_regmap_lookup in
probe, clk_enable and regmap_write in phy_init?
> +
> +	return 0;
> +}
> +
> +static int rockchip_dp_phy_probe(struct platform_device *pdev)
> +{
> +	struct device *dev = &pdev->dev;
> +	struct phy_provider *phy_provider;
> +	struct rockchip_dp_phy *dp;
> +	struct resource *res;
> +	struct phy *phy;
> +	int ret;
> +
> +	dp = devm_kzalloc(dev, sizeof(*dp), GFP_KERNEL);
> +	if (IS_ERR(dp))
> +		return -ENOMEM;
> +
> +	dp->dev = dev;
> +
> +	res = platform_get_resource(pdev, IORESOURCE_MEM, 0);
> +	dp->regs = devm_ioremap_resource(dev, res);
> +	if (IS_ERR(dp->regs))
> +		return PTR_ERR(dp->regs);
> +
> +	ret = rockchip_dp_phy_init(dp);
> +	if (ret)
> +		return ret;
> +
> +	phy = devm_phy_create(dev, NULL, &rockchip_dp_phy_ops, NULL);
> +	if (IS_ERR(phy)) {
> +		dev_err(dev, "failed to create phy\n");
> +		return PTR_ERR(phy);
> +	}
> +	phy_set_drvdata(phy, dp);
> +
> +	phy_provider = devm_of_phy_provider_register(dev, of_phy_simple_xlate);
> +
> +	return PTR_ERR_OR_ZERO(phy_provider);
> +}
> +
> +static const struct of_device_id rockchip_dp_phy_dt_ids[] = {
> +	{ .compatible = "rockchip,rk3288-dp-phy" },
> +	{}
> +};
> +
> +MODULE_DEVICE_TABLE(of, rockchip_dp_phy_dt_ids);
> +
> +static struct platform_driver rockchip_dp_phy_driver = {
> +	.probe		= rockchip_dp_phy_probe,
> +	.driver		= {
> +		.name	= "rockchip-dp-phy",
> +		.owner	= THIS_MODULE,

owner is not required here.

Thanks
Kishon


From vinod.koul at intel.com  Wed Aug 19 21:08:01 2015
From: vinod.koul at intel.com (Vinod Koul)
Date: Thu, 20 Aug 2015 09:38:01 +0530
Subject: [PATCH v2] dmaengine: fsl-edma: add PM suspend/resume support
In-Reply-To: <CADRPPNRaDaUBD1JG_QHrEQ5pKP9Ap1hV+bBdUnC-V32Nzr2qQw@mail.gmail.com>
References: <1437469005-3162-1-git-send-email-yao.yuan@freescale.com>
 <CADRPPNQJi_x+mdQV=DEVuhCL_p6VOWcPiV3jzioeRdWgSW2w3g@mail.gmail.com>
 <CY1PR0301MB15628DD5CFCE2B65BF4FECB2837C0@CY1PR0301MB1562.namprd03.prod.outlook.com>
 <CADRPPNS_wzX+mwT0L-H=ZP9w8gH9W4O9KUqnGYiAc39S5v4qLA@mail.gmail.com>
 <CY1PR0301MB1562103588FB0C6BEFDDBF3C83790@CY1PR0301MB1562.namprd03.prod.outlook.com>
 <55D183D1.9020401@nigelcunningham.com.au>
 <CY1PR0301MB1562FBE9818C1973651D2B7183790@CY1PR0301MB1562.namprd03.prod.outlook.com>
 <CADRPPNRaDaUBD1JG_QHrEQ5pKP9Ap1hV+bBdUnC-V32Nzr2qQw@mail.gmail.com>
Message-ID: <20150820040801.GS13546@localhost>

On Mon, Aug 17, 2015 at 02:10:46PM -0500, Li Yang wrote:
> >> Think of it from the end user perspective. Would you like your laptop (or
> >> whatever) to refuse to suspend because of this condition? The user may well
> >> expect that closing the lid on their laptop will reliably lead to it suspending to
> >> ram. Returning a failure here could result in a loss of data if the condition is not
> >> detected and the machine subsequently runs out of power.
> >>
> >
> > Yes, the user may well expect that closing the lid on their laptop will reliably lead to it suspending to ram.
> > So the client(the user of the DMA) must  to PAUSE or terminate the DMA transmission.
> >
> > We need to rely on client doing the right thing here.
> > The DMA should not make a decision instead of client.
> > If the DMA is not idle in DMA suspend, it should be the client's issue.
> > We don't know what the client really want to do, so just return the non-success value.
> 
> The problem here is that neither the client nor the DMA controller
> driver should easily decide to stop the suspend entrance and rollback.
> I don't think the non-idle situation is serious enough to cause a
> rollback.  You should do whatever can be done with the DMA
> controller(such as stop the controller and leave whatever to be done
> to the wake up) and continue with the suspend.

Ideally yes client should suspend first and dmaengine driver then being idle
when suspend is invoked. But we know we are in idle world!
So, driver should ensure it suspends the active channels and then goes to
suspend and restores that on resume

-- 
~Vinod



From ard.biesheuvel at linaro.org  Wed Aug 19 22:09:25 2015
From: ard.biesheuvel at linaro.org (Ard Biesheuvel)
Date: Thu, 20 Aug 2015 07:09:25 +0200
Subject: [PATCH 2/2] arm64: set MAX_MEMBLOCK_ADDR according to linear
 region size
In-Reply-To: <20150818173938.GH11571@e104818-lin.cambridge.arm.com>
References: <1439890482-20798-1-git-send-email-ard.biesheuvel@linaro.org>
 <1439890482-20798-3-git-send-email-ard.biesheuvel@linaro.org>
 <20150818100018.GA11021@arm.com>
 <CAKv+Gu-YDEKSrkSG2fywgrHBB3Hao+jodknmCAkFCWqG4OpXCA@mail.gmail.com>
 <20150818173938.GH11571@e104818-lin.cambridge.arm.com>
Message-ID: <CAKv+Gu8BVJF9MEsRRonprEkyhvrbTsWdUnz0wQyi2zUNAd_bpg@mail.gmail.com>

On 18 August 2015 at 19:39, Catalin Marinas <catalin.marinas at arm.com> wrote:
> On Tue, Aug 18, 2015 at 12:04:27PM +0200, Ard Biesheuvel wrote:
>> On 18 August 2015 at 12:00, Will Deacon <will.deacon at arm.com> wrote:
>> > On Tue, Aug 18, 2015 at 10:34:42AM +0100, Ard Biesheuvel wrote:
>> >> The linear region size of a 39-bit VA kernel is only 256 GB, which
>> >> may be insufficient to cover all of system RAM, even on platforms
>> >> that have much less than 256 GB of memory but which is laid out
>> >> very sparsely.
>> >>
>> >> So make sure we clip the memory we will not be able to map before
>> >> installing it into the memblock memory table, by setting
>> >> MAX_MEMBLOCK_ADDR accordingly.
>> >>
>> >> Signed-off-by: Ard Biesheuvel <ard.biesheuvel at linaro.org>
>> >> ---
>> >>  arch/arm64/include/asm/memory.h | 8 ++++++++
>> >>  1 file changed, 8 insertions(+)
>> >>
>> >> diff --git a/arch/arm64/include/asm/memory.h b/arch/arm64/include/asm/memory.h
>> >> index f800d45ea226..44a59c20e773 100644
>> >> --- a/arch/arm64/include/asm/memory.h
>> >> +++ b/arch/arm64/include/asm/memory.h
>> >> @@ -114,6 +114,14 @@ extern phys_addr_t               memstart_addr;
>> >>  #define PHYS_OFFSET          ({ memstart_addr; })
>> >>
>> >>  /*
>> >> + * The maximum physical address that the linear direct mapping
>> >> + * of system RAM can cover. (PAGE_OFFSET can be interpreted as
>> >> + * a 2's complement signed quantity and negated to derive the
>> >> + * maximum size of the linear mapping.)
>> >> + */
>> >> +#define MAX_MEMBLOCK_ADDR    ({ memstart_addr - PAGE_OFFSET - 1; })
>> >
>> > If we initialised memory_limit to this value and changed early_mem to
>> > use min (i.e. only restrict the limit further), would that avoid the
>> > need to change the of code? It looks like PPC uses
>> > memblock_enforce_memory_limit for similar reasons.
>>
>> Yes, that would be yet another way of doing things. But since Catalin
>> explicitly requested that both checks (i.e., bottom end and top end)
>> occur in the same place, and indicated his preference not to override
>> early_init_dt_add_memory_arch() if we can avoid it, the only way is to
>> hack it in there.
>
> Talking to Will, we decided to go for a quick fix with cc stable that
> does something like:
>
>         memblock_enforce_memory_limit(min(memory_limit, ~PAGE_OFFSET));
>

Actually, this won't work. The function limits the /amount/ of memory,
and disregards holes when doing so.

> Afterwards, we should still sort early_init_dt_add_memory_arch() to get
> the nicer printing since, as it stands, checking that a u64 is bigger
> than ULONG_MAX is pointless on 64-bit.
>
> Thanks.
>
> --
> Catalin


From vinod.koul at intel.com  Wed Aug 19 22:15:56 2015
From: vinod.koul at intel.com (Vinod Koul)
Date: Thu, 20 Aug 2015 10:45:56 +0530
Subject: [PATCH v8] dma: sun4i: Add support for the DMA engine on
 sun[457]i SoCs
In-Reply-To: <1437943855-29055-1-git-send-email-maxime.ripard@free-electrons.com>
References: <1437943855-29055-1-git-send-email-maxime.ripard@free-electrons.com>
Message-ID: <20150820051556.GT13546@localhost>

On Sun, Jul 26, 2015 at 10:50:55PM +0200, Maxime Ripard wrote:
> From: Emilio L?pez <emilio at elopez.com.ar>
> 
> This patch adds support for the DMA engine present on Allwinner A10,
> A13, A10S and A20 SoCs. This engine has two kinds of channels: normal
> and dedicated. The main difference is in the mode of operation;
> while a single normal channel may be operating at any given time,
> dedicated channels may operate simultaneously provided there is no
> overlap of source or destination.
> 
> Hardware documentation can be found on A10 User Manual (section 12), A13
> User Manual (section 14) and A20 User Manual (section 1.12)

Applied with subsystem name fixed

-- 
~Vinod



From vinod.koul at intel.com  Wed Aug 19 22:26:31 2015
From: vinod.koul at intel.com (Vinod Koul)
Date: Thu, 20 Aug 2015 10:56:31 +0530
Subject: [PATCH v1 1/4] dmaengine: Add support for new feature CRC32C
In-Reply-To: <1438258268-3099-2-git-send-email-rsahu@apm.com>
References: <1438258268-3099-1-git-send-email-rsahu@apm.com>
 <1438258268-3099-2-git-send-email-rsahu@apm.com>
Message-ID: <20150820052631.GW13546@localhost>

On Thu, Jul 30, 2015 at 05:41:05PM +0530, Rameshwar Prasad Sahu wrote:
> This patch adds support for new feature CRC32C calculation in
> dmaengine framework.

Looks okay can you please update Documentation also

-- 
~Vinod



From herbert at gondor.apana.org.au  Wed Aug 19 22:29:03 2015
From: herbert at gondor.apana.org.au (Herbert Xu)
Date: Thu, 20 Aug 2015 13:29:03 +0800
Subject: un4i-ss-cipher.c warning
In-Reply-To: <CAOMqctShdb9xEkBmuaQKfB1cwGupbfH5TS5ZB_P85Hwpn+4zAA@mail.gmail.com>
References: <CAOMqctShdb9xEkBmuaQKfB1cwGupbfH5TS5ZB_P85Hwpn+4zAA@mail.gmail.com>
Message-ID: <20150820052903.GA26031@gondor.apana.org.au>

On Wed, Aug 19, 2015 at 04:35:36PM +0200, Michal Suchanek wrote:
> Hello,
> 
> when building a kernel with sunxi crypto driver as merged into the
> sinxi-wip branch I get a compiler warning.
> 
> I am not sure this is the latest version of the driver. It does not
> seem to be in mainline yet.

The warning appears to be spurious as the code always ends up
initialising todo before using it.

Cheers,
-- 
Email: Herbert Xu <herbert at gondor.apana.org.au>
Home Page: http://gondor.apana.org.au/~herbert/
PGP Key: http://gondor.apana.org.au/~herbert/pubkey.txt


From appana.durga.rao at xilinx.com  Wed Aug 19 22:31:16 2015
From: appana.durga.rao at xilinx.com (Appana Durga Kedareswara Rao)
Date: Thu, 20 Aug 2015 05:31:16 +0000
Subject: [RESEND PATCH] dmaengine: Add Xilinx AXI Direct Memory Access
 Engine driver support
In-Reply-To: <CAAtXAHf9S662okN1gchbD246=e4_bMFoyBMrbt5q48xm1uo_CA@mail.gmail.com>
References: <1439825512-16444-1-git-send-email-appanad@xilinx.com>
 <CAAtXAHf9S662okN1gchbD246=e4_bMFoyBMrbt5q48xm1uo_CA@mail.gmail.com>
Message-ID: <C246CAC1457055469EF09E3A7AC4E11A4A4B2B8A@XAP-PVEXMBX01.xlnx.xilinx.com>

Hi Moritz Fischer,

        Thanks for reviewing the patch.

> -----Original Message-----
> From: Moritz Fischer [mailto:moritz.fischer at ettus.com]
> Sent: Thursday, August 20, 2015 3:21 AM
> To: Appana Durga Kedareswara Rao
> Cc: vinod.koul at intel.com; dan.j.williams at intel.com; Michal Simek; Soren
> Brinkmann; Appana Durga Kedareswara Rao; anirudha at xilinx.com;
> dmaengine at vger.kernel.org; linux-kernel at vger.kernel.org; linux-arm-kernel;
> Srikanth Thokala
> Subject: Re: [RESEND PATCH] dmaengine: Add Xilinx AXI Direct Memory Access
> Engine driver support
>
> Hi there,
>
> see comment below. I just did a quick compile test. Will take another look once I
> synthesized an image.
>
> On Mon, Aug 17, 2015 at 8:31 AM, Kedareswara rao Appana
> <appana.durga.rao at xilinx.com> wrote:
> > This is the driver for the AXI Direct Memory Access (AXI DMA) core,
> > which is a soft Xilinx IP core that provides high- bandwidth direct
> > memory access between memory and AXI4-Stream type target peripherals.
> >
> > Signed-off-by: Srikanth Thokala <sthokal at xilinx.com>
> > Signed-off-by: Kedareswara rao Appana <appanad at xilinx.com>
> > ---
> > The deivce tree doc got applied in the slave-dmaengine.git.
> >
> > Forgot to include dmaengine at vger.kernel.org in the cc list resending
> > the patch.
> >
> > Changes in v8:
> > - Updated the SG handling as suggested by Nicolae Rosia.
> > - Removed the unnecessary xilinx_dma_channel_set_config API the properties
> >   in this API is not being used by the driver.
> > Changes in v7:
> > - Updated license in the driver as suggested by Paul.
> > - Corrected return value in is_idle funtion.
> > Changes in v6:
> > - Fixed Odd indention in the Kconfig.
> > - used GFP_NOWAIT instead of GFP_KERNEL during the desc allocation
> > - Calculated residue in the tx_status instead of complete_descriptor.
> > - Update copy right to 2015.
> > - Modified spin_lock handling moved the spin_lock to the appropriate
> > functions (instead of xilinx_dma_start_transfer doing it
> xilinx_dma_issue_pending api).
> > - device_control and declare slave caps updated as per newer APi's.
> > Changes in v5:
> > - Modified the xilinx_dma.h header file location to the
> >   include/linux/dma/xilinx_dma.h
> > Changes in v4:
> > - Add direction field to DMA descriptor structure and removed from
> >   channel structure to avoid duplication.
> > - Check for DMA idle condition before changing the configuration.
> > - Residue is being calculated in complete_descriptor() and is reported
> >   to slave driver.
> > Changes in v3:
> > - Rebased on 3.16-rc7
> > Changes in v2:
> > - Simplified the logic to set SOP and APP words in prep_slave_sg().
> > - Corrected function description comments to match the return type.
> > - Fixed some minor comments as suggested by Andy.
> >
> >  drivers/dma/Kconfig             |   13 +
> >  drivers/dma/xilinx/Makefile     |    1 +
> >  drivers/dma/xilinx/xilinx_dma.c | 1179
> > +++++++++++++++++++++++++++++++++++++++
> >  3 files changed, 1193 insertions(+)
> >  create mode 100644 drivers/dma/xilinx/xilinx_dma.c
> >
> > diff --git a/drivers/dma/Kconfig b/drivers/dma/Kconfig index
> > 88d474b..5e95f07 100644
> > --- a/drivers/dma/Kconfig
> > +++ b/drivers/dma/Kconfig
> > @@ -507,4 +507,17 @@ config QCOM_BAM_DMA
> >           Enable support for the QCOM BAM DMA controller.  This controller
> >           provides DMA capabilities for a variety of on-chip devices.
> >
> > +config XILINX_DMA
> > +        tristate "Xilinx AXI DMA Engine"
> > +        depends on (ARCH_ZYNQ || MICROBLAZE)
> > +        select DMA_ENGINE
> > +        help
> > +          Enable support for Xilinx AXI DMA Soft IP.
> > +
> > +          This engine provides high-bandwidth direct memory access
> > +          between memory and AXI4-Stream type target peripherals.
> > +          It has two stream interfaces/channels, Memory Mapped to
> > +          Stream (MM2S) and Stream to Memory Mapped (S2MM) for the
> > +          data transfers.
> > +
> >  endif
> > diff --git a/drivers/dma/xilinx/Makefile b/drivers/dma/xilinx/Makefile
> > index 3c4e9f2..6224a49 100644
> > --- a/drivers/dma/xilinx/Makefile
> > +++ b/drivers/dma/xilinx/Makefile
> > @@ -1 +1,2 @@
> >  obj-$(CONFIG_XILINX_VDMA) += xilinx_vdma.o
> > +obj-$(CONFIG_XILINX_DMA) += xilinx_dma.o
> > diff --git a/drivers/dma/xilinx/xilinx_dma.c
> > b/drivers/dma/xilinx/xilinx_dma.c new file mode 100644 index
> > 0000000..a9be197
> > --- /dev/null
> > +++ b/drivers/dma/xilinx/xilinx_dma.c
> > @@ -0,0 +1,1179 @@
> > +/*
> > + * DMA driver for Xilinx DMA Engine
> > + *
> > + * Copyright (C) 2010 - 2015 Xilinx, Inc. All rights reserved.
> > + *
> > + * Based on the Freescale DMA driver.
> > + *
> > + * Description:
> > + *  The AXI DMA, is a soft IP, which provides high-bandwidth Direct
> > +Memory
> > + *  Access between memory and AXI4-Stream-type target peripherals. It
> > +can be
> > + *  configured to have one channel or two channels and if configured
> > +as two
> > + *  channels, one is to transmit data from memory to a device and
> > +another is
> > + *  to receive from a device.
> > + *
> > + * This 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.
> > + */
> > +
> > +#include <linux/bitops.h>
> > +#include <linux/dma/xilinx_dma.h>
> > +#include <linux/init.h>
> > +#include <linux/interrupt.h>
> > +#include <linux/io.h>
> > +#include <linux/module.h>
> > +#include <linux/of_address.h>
> > +#include <linux/of_dma.h>
> > +#include <linux/of_irq.h>
> > +#include <linux/of_platform.h>
> > +#include <linux/slab.h>
> > +
> > +#include "../dmaengine.h"
> > +
> > +/* Register Offsets */
> > +#define XILINX_DMA_REG_CONTROL         0x00
> > +#define XILINX_DMA_REG_STATUS          0x04
> > +#define XILINX_DMA_REG_CURDESC         0x08
> > +#define XILINX_DMA_REG_TAILDESC                0x10
> > +#define XILINX_DMA_REG_SRCADDR         0x18
> > +#define XILINX_DMA_REG_DSTADDR         0x20
> > +#define XILINX_DMA_REG_BTT             0x28
> > +
> > +/* Channel/Descriptor Offsets */
> > +#define XILINX_DMA_MM2S_CTRL_OFFSET    0x00
> > +#define XILINX_DMA_S2MM_CTRL_OFFSET    0x30
> > +
> > +/* General register bits definitions */
> > +#define XILINX_DMA_CR_RUNSTOP_MASK     BIT(0)
> > +#define XILINX_DMA_CR_RESET_MASK       BIT(2)
> > +
> > +#define XILINX_DMA_CR_DELAY_SHIFT      24
> > +#define XILINX_DMA_CR_COALESCE_SHIFT   16
> > +
> > +#define XILINX_DMA_CR_DELAY_MAX                GENMASK(7, 0)
> > +#define XILINX_DMA_CR_COALESCE_MAX     GENMASK(7, 0)
> > +
> > +#define XILINX_DMA_SR_HALTED_MASK      BIT(0)
> > +#define XILINX_DMA_SR_IDLE_MASK                BIT(1)
> > +
> > +#define XILINX_DMA_XR_IRQ_IOC_MASK     BIT(12)
> > +#define XILINX_DMA_XR_IRQ_DELAY_MASK   BIT(13)
> > +#define XILINX_DMA_XR_IRQ_ERROR_MASK   BIT(14)
> > +#define XILINX_DMA_XR_IRQ_ALL_MASK     GENMASK(14, 12)
> > +
> > +/* BD definitions */
> > +#define XILINX_DMA_BD_STS_ALL_MASK     GENMASK(31, 28)
> > +#define XILINX_DMA_BD_SOP              BIT(27)
> > +#define XILINX_DMA_BD_EOP              BIT(26)
> > +
> > +/* Hw specific definitions */
> > +#define XILINX_DMA_MAX_CHANS_PER_DEVICE        0x2
> > +#define XILINX_DMA_MAX_TRANS_LEN       GENMASK(22, 0)
> > +
> > +/* Delay loop counter to prevent hardware failure */
> > +#define XILINX_DMA_LOOP_COUNT          1000000
> > +
> > +/* Maximum number of Descriptors */
> > +#define XILINX_DMA_NUM_DESCS           255
> > +#define XILINX_DMA_COALESCE_MAX                255
> > +#define XILINX_DMA_NUM_APP_WORDS       5
> > +
> > +/**
> > + * struct xilinx_dma_desc_hw - Hardware Descriptor
> > + * @next_desc: Next Descriptor Pointer @0x00
> > + * @pad1: Reserved @0x04
> > + * @buf_addr: Buffer address @0x08
> > + * @pad2: Reserved @0x0C
> > + * @pad3: Reserved @0x10
> > + * @pad4: Reserved @0x14
> > + * @control: Control field @0x18
> > + * @status: Status field @0x1C
> > + * @app: APP Fields @0x20 - 0x30
> > + */
> > +struct xilinx_dma_desc_hw {
> > +       u32 next_desc;
> > +       u32 pad1;
> > +       u32 buf_addr;
> > +       u32 pad2;
> > +       u32 pad3;
> > +       u32 pad4;
> > +       u32 control;
> > +       u32 status;
> > +       u32 app[XILINX_DMA_NUM_APP_WORDS]; } __aligned(64);
> > +
> > +/**
> > + * struct xilinx_dma_tx_segment - Descriptor segment
> > + * @hw: Hardware descriptor
> > + * @node: Node in the descriptor segments list
> > + * @phys: Physical address of segment  */ struct
> > +xilinx_dma_tx_segment {
> > +       struct xilinx_dma_desc_hw hw;
> > +       struct list_head node;
> > +       dma_addr_t phys;
> > +} __aligned(64);
> > +
> > +/**
> > + * struct xilinx_dma_tx_descriptor - Per Transaction structure
> > + * @async_tx: Async transaction descriptor
> > + * @segments: TX segments list
> > + * @node: Node in the channel descriptors list
> > + * @direction: Transfer direction
> > + */
> > +struct xilinx_dma_tx_descriptor {
> > +       struct dma_async_tx_descriptor async_tx;
> > +       struct list_head segments;
> > +       struct list_head node;
> > +       enum dma_transfer_direction direction; };
> > +
> > +/**
> > + * struct xilinx_dma_chan - Driver specific DMA channel structure
> > + * @xdev: Driver specific device structure
> > + * @ctrl_offset: Control registers offset
> > + * @ctrl_reg: Control register value
> > + * @lock: Descriptor operation lock
> > + * @pending_list: Descriptors waiting
> > + * @active_list: Descriptors ready to submit
> > + * @done_list: Complete descriptors
> > + * @free_seg_list: Free descriptors
> > + * @common: DMA common channel
> > + * @seg_v: Statically allocated segments base
> > + * @seg_p: Physical allocated segments base
> > + * @dev: The dma device
> > + * @irq: Channel IRQ
> > + * @id: Channel ID
> > + * @has_sg: Support scatter transfers
> > + * @idle: Check for channel idle
> > + * @err: Channel has errors
> > + * @tasklet: Cleanup work after irq
> > + * @residue: Residue
> > + * @desc_pendingcount: Descriptor pending count  */ struct
> > +xilinx_dma_chan {
> > +       struct xilinx_dma_device *xdev;
> > +       u32 ctrl_offset;
> > +       u32 ctrl_reg;
> > +       spinlock_t lock;
> > +       struct list_head pending_list;
> > +       struct list_head done_list;
> > +       struct list_head active_list;
> > +       struct list_head free_seg_list;
> > +       struct dma_chan common;
> > +       struct xilinx_dma_tx_segment *seg_v;
> > +       dma_addr_t seg_p;
> > +       struct device *dev;
> > +       int irq;
> > +       int id;
> > +       bool has_sg;
> > +       bool idle;
> > +       int err;
> > +       struct tasklet_struct tasklet;
> > +       u32 residue;
> > +       u32 desc_pendingcount;
> > +};
> > +
> > +/**
> > + * struct xilinx_dma_device - DMA device structure
> > + * @regs: I/O mapped base address
> > + * @dev: Device Structure
> > + * @common: DMA device structure
> > + * @chan: Driver specific DMA channel
> > + * @has_sg: Specifies whether Scatter-Gather is present or not  */
> > +struct xilinx_dma_device {
> > +       void __iomem *regs;
> > +       struct device *dev;
> > +       struct dma_device common;
> > +       struct xilinx_dma_chan *chan[XILINX_DMA_MAX_CHANS_PER_DEVICE];
> > +       bool has_sg;
> > +};
> > +
> > +/* Macros */
> > +#define to_xilinx_chan(chan) \
> > +       container_of(chan, struct xilinx_dma_chan, common) #define
> > +to_dma_tx_descriptor(tx) \
> > +       container_of(tx, struct xilinx_dma_tx_descriptor, async_tx)
> > +
> > +/* IO accessors */
> > +static inline void dma_write(struct xilinx_dma_chan *chan, u32 reg,
> > +u32 value) {
> > +       iowrite32(value, chan->xdev->regs + reg);
> Any reason to not use write here?

Most of the Xilinx drivers and the VDMA driver that got up streamed
Use iowrite to make consistency b/w the drivers I used the same API's.

What is the advantage we will gain by using writel instead of iowrite32?


> > +}
> > +
> > +static inline u32 dma_read(struct xilinx_dma_chan *chan, u32 reg) {
> > +       return ioread32(chan->xdev->regs + reg);
> Any reason to not use readl here?
> > +}
> > +
> > +static inline u32 dma_ctrl_read(struct xilinx_dma_chan *chan, u32
> > +reg) {
> > +       return dma_read(chan, chan->ctrl_offset + reg); }
> > +
> > +static inline void dma_ctrl_write(struct xilinx_dma_chan *chan, u32 reg,
> > +                                 u32 value) {
> > +       dma_write(chan, chan->ctrl_offset + reg, value); }
> > +
> > +/*
> > +---------------------------------------------------------------------
> > +--------
> > + * Descriptors and segments alloc and free  */
> > +
> > +/**
> > + * xilinx_dma_alloc_tx_segment - Allocate transaction segment
> > + * @chan: Driver specific dma channel
> > + *
> > + * Return: The allocated segment on success and NULL on failure.
> > + */
> > +static struct xilinx_dma_tx_segment *
> > +xilinx_dma_alloc_tx_segment(struct xilinx_dma_chan *chan) {
> > +       struct xilinx_dma_tx_segment *segment = NULL;
> > +       unsigned long flags;
> > +
> > +       spin_lock_irqsave(&chan->lock, flags);
> > +       if (!list_empty(&chan->free_seg_list)) {
> > +               segment = list_first_entry(&chan->free_seg_list,
> > +                                          struct xilinx_dma_tx_segment,
> > +                                          node);
> > +               list_del(&segment->node);
> > +       }
> > +       spin_unlock_irqrestore(&chan->lock, flags);
> > +
> > +       return segment;
> > +}
> > +
> > +/**
> > + * xilinx_dma_clean_hw_desc - Clean hardware descriptor
> > + * @hw: HW descriptor to clean
> > + */
> > +static void xilinx_dma_clean_hw_desc(struct xilinx_dma_desc_hw *hw) {
> > +       u32 next_desc = hw->next_desc;
> > +
> > +       memset(hw, 0, sizeof(struct xilinx_dma_desc_hw));
> > +
> > +       hw->next_desc = next_desc;
> > +}
> > +
> > +/**
> > + * xilinx_dma_free_tx_segment - Free transaction segment
> > + * @chan: Driver specific dma channel
> > + * @segment: dma transaction segment
> > + */
> > +static void xilinx_dma_free_tx_segment(struct xilinx_dma_chan *chan,
> > +                                      struct xilinx_dma_tx_segment
> > +*segment) {
> > +       xilinx_dma_clean_hw_desc(&segment->hw);
> > +
> > +       list_add_tail(&segment->node, &chan->free_seg_list); }
> > +
> > +/**
> > + * xilinx_dma_tx_descriptor - Allocate transaction descriptor
> > + * @chan: Driver specific dma channel
> > + *
> > + * Return: The allocated descriptor on success and NULL on failure.
> > + */
> > +static struct xilinx_dma_tx_descriptor *
> > +xilinx_dma_alloc_tx_descriptor(struct xilinx_dma_chan *chan) {
> > +       struct xilinx_dma_tx_descriptor *desc;
> > +
> > +       desc = kzalloc(sizeof(*desc), GFP_NOWAIT);
> > +       if (!desc)
> > +               return NULL;
> > +
> > +       INIT_LIST_HEAD(&desc->segments);
> > +
> > +       return desc;
> > +}
> > +
> > +/**
> > + * xilinx_dma_free_tx_descriptor - Free transaction descriptor
> > + * @chan: Driver specific dma channel
> > + * @desc: dma transaction descriptor
> > + */
> > +static void
> > +xilinx_dma_free_tx_descriptor(struct xilinx_dma_chan *chan,
> > +                             struct xilinx_dma_tx_descriptor *desc) {
> > +       struct xilinx_dma_tx_segment *segment, *next;
> > +
> > +       if (!desc)
> > +               return;
> > +
> > +       list_for_each_entry_safe(segment, next, &desc->segments, node) {
> > +               list_del(&segment->node);
> > +               xilinx_dma_free_tx_segment(chan, segment);
> > +       }
> > +
> > +       kfree(desc);
> > +}
> > +
> > +/**
> > + * xilinx_dma_alloc_chan_resources - Allocate channel resources
> > + * @dchan: DMA channel
> > + *
> > + * Return: '0' on success and failure value on error  */ static int
> > +xilinx_dma_alloc_chan_resources(struct dma_chan *dchan) {
> > +       struct xilinx_dma_chan *chan = to_xilinx_chan(dchan);
> > +       int i;
> > +
> > +       /* Allocate the buffer descriptors. */
> > +       chan->seg_v = dma_zalloc_coherent(chan->dev,
> > +                                         sizeof(*chan->seg_v) *
> > +                                         XILINX_DMA_NUM_DESCS,
> > +                                         &chan->seg_p, GFP_KERNEL);
> > +       if (!chan->seg_v) {
> > +               dev_err(chan->dev,
> > +                       "unable to allocate channel %d descriptors\n",
> > +                       chan->id);
> > +               return -ENOMEM;
> > +       }
> > +
> > +       for (i = 0; i < XILINX_DMA_NUM_DESCS; i++) {
> > +               chan->seg_v[i].hw.next_desc =
> > +                               chan->seg_p + sizeof(*chan->seg_v) *
> > +                               ((i + 1) % XILINX_DMA_NUM_DESCS);
> > +               chan->seg_v[i].phys =
> > +                               chan->seg_p + sizeof(*chan->seg_v) * i;
> > +               list_add_tail(&chan->seg_v[i].node, &chan->free_seg_list);
> > +       }
> > +
> > +       dma_cookie_init(dchan);
> > +
> > +       /* Enable interrupts */
> > +       chan->ctrl_reg |= XILINX_DMA_XR_IRQ_ALL_MASK;
> > +       dma_ctrl_write(chan, XILINX_DMA_REG_CONTROL, chan->ctrl_reg);
> > +
> > +       return 0;
> > +}
> > +
> > +/**
> > + * xilinx_dma_free_desc_list - Free descriptors list
> > + * @chan: Driver specific dma channel
> > + * @list: List to parse and delete the descriptor  */ static void
> > +xilinx_dma_free_desc_list(struct xilinx_dma_chan *chan,
> > +                                     struct list_head *list) {
> > +       struct xilinx_dma_tx_descriptor *desc, *next;
> > +
> > +       list_for_each_entry_safe(desc, next, list, node) {
> > +               list_del(&desc->node);
> > +               xilinx_dma_free_tx_descriptor(chan, desc);
> > +       }
> > +}
> > +
> > +/**
> > + * xilinx_dma_free_descriptors - Free channel descriptors
> > + * @chan: Driver specific dma channel  */ static void
> > +xilinx_dma_free_descriptors(struct xilinx_dma_chan *chan) {
> > +       unsigned long flags;
> > +
> > +       spin_lock_irqsave(&chan->lock, flags);
> > +
> > +       xilinx_dma_free_desc_list(chan, &chan->pending_list);
> > +       xilinx_dma_free_desc_list(chan, &chan->done_list);
> > +       xilinx_dma_free_desc_list(chan, &chan->active_list);
> > +
> > +       spin_unlock_irqrestore(&chan->lock, flags); }
> > +
> > +/**
> > + * xilinx_dma_free_chan_resources - Free channel resources
> > + * @dchan: DMA channel
> > + */
> > +static void xilinx_dma_free_chan_resources(struct dma_chan *dchan) {
> > +       struct xilinx_dma_chan *chan = to_xilinx_chan(dchan);
> > +
> > +       xilinx_dma_free_descriptors(chan);
> > +
> > +       dma_free_coherent(chan->dev,
> > +                         sizeof(*chan->seg_v) * XILINX_DMA_NUM_DESCS,
> > +                         chan->seg_v, chan->seg_p); }
> > +
> > +/**
> > + * xilinx_dma_chan_desc_cleanup - Clean channel descriptors
> > + * @chan: Driver specific dma channel  */ static void
> > +xilinx_dma_chan_desc_cleanup(struct xilinx_dma_chan *chan) {
> > +       struct xilinx_dma_tx_descriptor *desc;
> > +       unsigned long flags;
> > +
> > +       spin_lock_irqsave(&chan->lock, flags);
> > +
> > +       while (!list_empty(&chan->done_list)) {
> > +               dma_async_tx_callback callback;
> > +               void *callback_param;
> > +
> > +               desc = list_first_entry(&chan->done_list,
> > +                       struct xilinx_dma_tx_descriptor, node);
> > +
> > +               /* Remove from the list of running transactions */
> > +               list_del(&desc->node);
> > +
> > +               /* Run the link descriptor callback function */
> > +               callback = desc->async_tx.callback;
> > +               callback_param = desc->async_tx.callback_param;
> > +               if (callback) {
> > +                       spin_unlock_irqrestore(&chan->lock, flags);
> > +                       callback(callback_param);
> > +                       spin_lock_irqsave(&chan->lock, flags);
> > +               }
> > +
> > +               /* Run any dependencies, then free the descriptor */
> > +               dma_run_dependencies(&desc->async_tx);
> > +               xilinx_dma_free_tx_descriptor(chan, desc);
> > +       }
> > +
> > +       spin_unlock_irqrestore(&chan->lock, flags); }
> > +
> > +/**
> > + * xilinx_dma_tx_status - Get dma transaction status
> > + * @dchan: DMA channel
> > + * @cookie: Transaction identifier
> > + * @txstate: Transaction state
> > + *
> > + * Return: DMA transaction status
> > + */
> > +static enum dma_status xilinx_dma_tx_status(struct dma_chan *dchan,
> > +                                           dma_cookie_t cookie,
> > +                                           struct dma_tx_state
> > +*txstate) {
> > +       struct xilinx_dma_chan *chan = to_xilinx_chan(dchan);
> > +       struct xilinx_dma_tx_descriptor *desc;
> > +       struct xilinx_dma_tx_segment *segment;
> > +       struct xilinx_dma_desc_hw *hw;
> > +       enum dma_status ret;
> > +       unsigned long flags;
> > +       u32 residue;
>
> While compiling this threw a residue may be used uninitialized warning, I
> suppose 0 would be a sensible default value?

Ok will fix it.

> > +
> > +       ret = dma_cookie_status(dchan, cookie, txstate);
> > +       if (ret == DMA_COMPLETE || !txstate)
> > +               return ret;
> > +
> > +       desc = list_last_entry(&chan->active_list,
> > +                              struct xilinx_dma_tx_descriptor, node);
> > +
> > +       spin_lock_irqsave(&chan->lock, flags);
> > +       if (chan->has_sg) {
> > +               while (!list_empty(&desc->segments)) {
> > +                       segment = list_first_entry(&desc->segments,
> > +                                       struct xilinx_dma_tx_segment, node);
> > +                       hw = &segment->hw;
> > +                       residue += (hw->control - hw->status) &
> > +                                  XILINX_DMA_MAX_TRANS_LEN;
> > +               }
> > +       }
> > +
> > +       chan->residue = residue;
> > +       dma_set_residue(txstate, chan->residue);
> > +       spin_unlock_irqrestore(&chan->lock, flags);
> > +
> > +       return ret;
> > +}
> > +
> > +/**
> > + * xilinx_dma_halt - Halt DMA channel
> > + * @chan: Driver specific DMA channel  */ static void
> > +xilinx_dma_halt(struct xilinx_dma_chan *chan) {
> > +       int loop = XILINX_DMA_LOOP_COUNT;
> > +
> > +       chan->ctrl_reg &= ~XILINX_DMA_CR_RUNSTOP_MASK;
> > +       dma_ctrl_write(chan, XILINX_DMA_REG_CONTROL, chan->ctrl_reg);
> > +
> > +       /* Wait for the hardware to halt */
> > +       do {
> > +               if (dma_ctrl_read(chan, XILINX_DMA_REG_STATUS) &
> > +                       XILINX_DMA_SR_HALTED_MASK)
> > +                       break;
> > +       } while (loop--);
> > +
> > +       if (!loop) {
> > +               dev_err(chan->dev, "Cannot stop channel %p: %x\n",
> > +                       chan, dma_ctrl_read(chan, XILINX_DMA_REG_STATUS));
> > +               chan->err = true;
> > +       }
> > +}
> > +
> > +/**
> > + * xilinx_dma_start - Start DMA channel
> > + * @chan: Driver specific DMA channel  */ static void
> > +xilinx_dma_start(struct xilinx_dma_chan *chan) {
> > +       int loop = XILINX_DMA_LOOP_COUNT;
> > +
> > +       chan->ctrl_reg |= XILINX_DMA_CR_RUNSTOP_MASK;
> > +       dma_ctrl_write(chan, XILINX_DMA_REG_CONTROL, chan->ctrl_reg);
> > +
> > +       /* Wait for the hardware to start */
> > +       do {
> > +               if (!dma_ctrl_read(chan, XILINX_DMA_REG_STATUS) &
> > +                       XILINX_DMA_SR_HALTED_MASK)
> > +                       break;
> > +       } while (loop--);
> Maybe use one of the readx_poll_timeout functions?

Ok will use

> > +
> > +       if (!loop) {
> > +               dev_err(chan->dev, "Cannot start channel %p: %x\n",
> > +                        chan, dma_ctrl_read(chan, XILINX_DMA_REG_STATUS));
> > +               chan->err = true;
> > +       }
> > +}
> > +
> > +/**
> > + * xilinx_dma_start_transfer - Starts DMA transfer
> > + * @chan: Driver specific channel struct pointer  */ static void
> > +xilinx_dma_start_transfer(struct xilinx_dma_chan *chan) {
> > +       struct xilinx_dma_tx_descriptor *head_desc, *tail_desc;
> > +       struct xilinx_dma_tx_segment *tail_segment;
> > +
> > +       if (chan->err)
> > +               return;
> > +
> > +       if (list_empty(&chan->pending_list))
> > +               return;
> > +
> > +       if (!chan->idle)
> > +               return;
> > +
> > +       head_desc = list_first_entry(&chan->pending_list,
> > +                                    struct xilinx_dma_tx_descriptor, node);
> > +       tail_desc = list_last_entry(&chan->pending_list,
> > +                                   struct xilinx_dma_tx_descriptor, node);
> > +       tail_segment = list_last_entry(&tail_desc->segments,
> > +                                      struct xilinx_dma_tx_segment,
> > + node);
> > +
> > +       if (chan->desc_pendingcount <= XILINX_DMA_COALESCE_MAX) {
> > +               chan->ctrl_reg &= ~XILINX_DMA_CR_COALESCE_MAX;
> > +               chan->ctrl_reg |= chan->desc_pendingcount <<
> > +                                 XILINX_DMA_CR_COALESCE_SHIFT;
> > +               dma_ctrl_write(chan, XILINX_DMA_REG_CONTROL, chan->ctrl_reg);
> > +       }
> > +
> > +       if (chan->has_sg)
> > +               dma_ctrl_write(chan, XILINX_DMA_REG_CURDESC,
> > +                              head_desc->async_tx.phys);
> > +
> > +       xilinx_dma_start(chan);
> > +
> > +       if (chan->err)
> > +               return;
> > +
> > +       /* Start the transfer */
> > +       if (chan->has_sg) {
> > +               dma_ctrl_write(chan, XILINX_DMA_REG_TAILDESC,
> > +                              tail_segment->phys);
> > +       } else {
> > +               struct xilinx_dma_tx_segment *segment;
> > +               struct xilinx_dma_desc_hw *hw;
> > +
> > +               segment = list_first_entry(&head_desc->segments,
> > +                                          struct xilinx_dma_tx_segment, node);
> > +               hw = &segment->hw;
> > +
> > +               if (head_desc->direction == DMA_MEM_TO_DEV)
> > +                       dma_ctrl_write(chan, XILINX_DMA_REG_SRCADDR,
> > +                                      hw->buf_addr);
> > +               else
> > +                       dma_ctrl_write(chan, XILINX_DMA_REG_DSTADDR,
> > +                                      hw->buf_addr);
> > +
> > +               /* Start the transfer */
> > +               dma_ctrl_write(chan, XILINX_DMA_REG_BTT,
> > +                              hw->control & XILINX_DMA_MAX_TRANS_LEN);
> > +       }
> > +
> > +       list_splice_tail_init(&chan->pending_list, &chan->active_list);
> > +       chan->desc_pendingcount = 0;
> > +       chan->idle = false;
> > +}
> > +
> > +/**
> > + * xilinx_dma_issue_pending - Issue pending transactions
> > + * @dchan: DMA channel
> > + */
> > +static void xilinx_dma_issue_pending(struct dma_chan *dchan) {
> > +       struct xilinx_dma_chan *chan = to_xilinx_chan(dchan);
> > +       unsigned long flags;
> > +
> > +       spin_lock_irqsave(&chan->lock, flags);
> > +       xilinx_dma_start_transfer(chan);
> > +       spin_unlock_irqrestore(&chan->lock, flags); }
> > +
> > +/**
> > + * xilinx_dma_complete_descriptor - Mark the active descriptor as
> > +complete
> > + * @chan : xilinx DMA channel
> > + */
> > +static void xilinx_dma_complete_descriptor(struct xilinx_dma_chan
> > +*chan) {
> > +       struct xilinx_dma_tx_descriptor *desc, *next;
> > +
> > +       if (list_empty(&chan->active_list))
> > +               return;
> > +
> > +       list_for_each_entry_safe(desc, next, &chan->active_list, node) {
> > +               list_del(&desc->node);
> > +               dma_cookie_complete(&desc->async_tx);
> > +               list_add_tail(&desc->node, &chan->done_list);
> > +       }
> > +}
> > +
> > +/**
> > + * xilinx_dma_reset - Reset DMA channel
> > + * @chan: Driver specific DMA channel
> > + *
> > + * Return: '0' on success and failure value on error  */ static int
> > +xilinx_dma_chan_reset(struct xilinx_dma_chan *chan) {
> > +       int loop = XILINX_DMA_LOOP_COUNT;
> > +       u32 tmp;
> > +
> > +       chan->ctrl_reg = dma_ctrl_read(chan, XILINX_DMA_REG_CONTROL);
> > +       dma_ctrl_write(chan, XILINX_DMA_REG_CONTROL, chan->ctrl_reg |
> > +                      XILINX_DMA_CR_RESET_MASK);
> > +
> > +       tmp = dma_ctrl_read(chan, XILINX_DMA_REG_CONTROL) &
> > +             XILINX_DMA_CR_RESET_MASK;
> > +
> > +       /* Wait for the hardware to finish reset */
> > +       do {
> > +               tmp = dma_ctrl_read(chan, XILINX_DMA_REG_CONTROL) &
> > +                     XILINX_DMA_CR_RESET_MASK;
> > +       } while (loop-- && tmp);
> See above

Ok will fix it

Regards,
Kedar.

> > +
> > +       if (!loop) {
> > +               dev_err(chan->dev, "reset timeout, cr %x, sr %x\n",
> > +                       dma_ctrl_read(chan, XILINX_DMA_REG_CONTROL),
> > +                       dma_ctrl_read(chan, XILINX_DMA_REG_STATUS));
> > +               return -EBUSY;
> > +       }
> > +
> > +       chan->err = false;
> > +
> > +       return 0;
> > +}
> > +
> > +/**
> > + * xilinx_dma_irq_handler - DMA Interrupt handler
> > + * @irq: IRQ number
> > + * @data: Pointer to the Xilinx DMA channel structure
> > + *
> > + * Return: IRQ_HANDLED/IRQ_NONE
> > + */
> > +static irqreturn_t xilinx_dma_irq_handler(int irq, void *data) {
> > +       struct xilinx_dma_chan *chan = data;
> > +       u32 status;
> > +
> > +       /* Read the status and ack the interrupts. */
> > +       status = dma_ctrl_read(chan, XILINX_DMA_REG_STATUS);
> > +       if (!(status & XILINX_DMA_XR_IRQ_ALL_MASK))
> > +               return IRQ_NONE;
> > +
> > +       dma_ctrl_write(chan, XILINX_DMA_REG_STATUS,
> > +                      status & XILINX_DMA_XR_IRQ_ALL_MASK);
> > +
> > +       if (status & XILINX_DMA_XR_IRQ_ERROR_MASK) {
> > +               dev_err(chan->dev,
> > +                       "Channel %p has errors %x, cdr %x tdr %x\n",
> > +                       chan, dma_ctrl_read(chan, XILINX_DMA_REG_STATUS),
> > +                       dma_ctrl_read(chan, XILINX_DMA_REG_CURDESC),
> > +                       dma_ctrl_read(chan, XILINX_DMA_REG_TAILDESC));
> > +               chan->err = true;
> > +       }
> > +
> > +       /*
> > +        * Device takes too long to do the transfer when user requires
> > +        * responsiveness
> > +        */
> > +       if (status & XILINX_DMA_XR_IRQ_DELAY_MASK)
> > +               dev_dbg(chan->dev, "Inter-packet latency too long\n");
> > +
> > +       if (status & XILINX_DMA_XR_IRQ_IOC_MASK) {
> > +               spin_lock(&chan->lock);
> > +               xilinx_dma_complete_descriptor(chan);
> > +               chan->idle = true;
> > +               xilinx_dma_start_transfer(chan);
> > +               spin_unlock(&chan->lock);
> > +       }
> > +
> > +       tasklet_schedule(&chan->tasklet);
> > +       return IRQ_HANDLED;
> > +}
> > +
> > +/**
> > + * xilinx_dma_do_tasklet - Schedule completion tasklet
> > + * @data: Pointer to the Xilinx dma channel structure  */ static void
> > +xilinx_dma_do_tasklet(unsigned long data) {
> > +       struct xilinx_dma_chan *chan = (struct xilinx_dma_chan *)data;
> > +
> > +       xilinx_dma_chan_desc_cleanup(chan);
> > +}
> > +
> > +/**
> > + * append_desc_queue - Queuing descriptor
> > + * @chan: Driver specific dma channel
> > + * @desc: dma transaction descriptor
> > + */
> > +static void append_desc_queue(struct xilinx_dma_chan *chan,
> > +                             struct xilinx_dma_tx_descriptor *desc) {
> > +       struct xilinx_dma_tx_segment *tail_segment;
> > +       struct xilinx_dma_tx_descriptor *tail_desc;
> > +
> > +       if (list_empty(&chan->pending_list))
> > +               goto append;
> > +
> > +       /*
> > +        * Add the hardware descriptor to the chain of hardware descriptors
> > +        * that already exists in memory.
> > +        */
> > +       tail_desc = list_last_entry(&chan->pending_list,
> > +                                   struct xilinx_dma_tx_descriptor, node);
> > +       tail_segment = list_last_entry(&tail_desc->segments,
> > +                                      struct xilinx_dma_tx_segment, node);
> > +       tail_segment->hw.next_desc = (u32)desc->async_tx.phys;
> > +
> > +       /*
> > +        * Add the software descriptor and all children to the list
> > +        * of pending transactions
> > +        */
> > +append:
> > +       list_add_tail(&desc->node, &chan->pending_list);
> > +       chan->desc_pendingcount++;
> > +
> > +       if (unlikely(chan->desc_pendingcount > XILINX_DMA_COALESCE_MAX)) {
> > +               dev_dbg(chan->dev, "desc pendingcount is too high\n");
> > +               chan->desc_pendingcount = XILINX_DMA_COALESCE_MAX;
> > +               BUG();
> > +       }
> > +}
> > +
> > +/**
> > + * xilinx_dma_tx_submit - Submit DMA transaction
> > + * @tx: Async transaction descriptor
> > + *
> > + * Return: cookie value on success and failure value on error  */
> > +static dma_cookie_t xilinx_dma_tx_submit(struct
> > +dma_async_tx_descriptor *tx) {
> > +       struct xilinx_dma_tx_descriptor *desc = to_dma_tx_descriptor(tx);
> > +       struct xilinx_dma_chan *chan = to_xilinx_chan(tx->chan);
> > +       dma_cookie_t cookie;
> > +       unsigned long flags;
> > +       int err;
> > +
> > +       if (chan->err) {
> > +               /*
> > +                * If reset fails, need to hard reset the system.
> > +                * Channel is no longer functional
> > +                */
> > +               err = xilinx_dma_chan_reset(chan);
> > +               if (err < 0)
> > +                       return err;
> > +       }
> > +
> > +       spin_lock_irqsave(&chan->lock, flags);
> > +
> > +       cookie = dma_cookie_assign(tx);
> > +
> > +       /* Put this transaction onto the tail of the pending queue */
> > +       append_desc_queue(chan, desc);
> > +
> > +       spin_unlock_irqrestore(&chan->lock, flags);
> > +
> > +       return cookie;
> > +}
> > +
> > +/**
> > + * xilinx_dma_prep_slave_sg - prepare descriptors for a DMA_SLAVE
> > +transaction
> > + * @dchan: DMA channel
> > + * @sgl: scatterlist to transfer to/from
> > + * @sg_len: number of entries in @scatterlist
> > + * @direction: DMA direction
> > + * @flags: transfer ack flags
> > + * @context: APP words of the descriptor
> > + *
> > + * Return: Async transaction descriptor on success and NULL on
> > +failure  */ static struct dma_async_tx_descriptor
> > +*xilinx_dma_prep_slave_sg(
> > +       struct dma_chan *dchan, struct scatterlist *sgl, unsigned int sg_len,
> > +       enum dma_transfer_direction direction, unsigned long flags,
> > +       void *context)
> > +{
> > +       struct xilinx_dma_chan *chan = to_xilinx_chan(dchan);
> > +       struct xilinx_dma_tx_descriptor *desc;
> > +       struct xilinx_dma_tx_segment *segment;
> > +       u32 *app_w = (u32 *)context;
> > +       struct scatterlist *sg;
> > +       size_t copy, sg_used;
> > +       int i;
> > +
> > +       if (!is_slave_direction(direction))
> > +               return NULL;
> > +
> > +       /* Allocate a transaction descriptor. */
> > +       desc = xilinx_dma_alloc_tx_descriptor(chan);
> > +       if (!desc)
> > +               return NULL;
> > +
> > +       desc->direction = direction;
> > +       dma_async_tx_descriptor_init(&desc->async_tx, &chan->common);
> > +       desc->async_tx.tx_submit = xilinx_dma_tx_submit;
> > +
> > +       /* Build transactions using information in the scatter gather list */
> > +       for_each_sg(sgl, sg, sg_len, i) {
> > +               sg_used = 0;
> > +
> > +               /* Loop until the entire scatterlist entry is used */
> > +               while (sg_used < sg_dma_len(sg)) {
> > +                       struct xilinx_dma_desc_hw *hw;
> > +
> > +                       /* Get a free segment */
> > +                       segment = xilinx_dma_alloc_tx_segment(chan);
> > +                       if (!segment)
> > +                               goto error;
> > +
> > +                       /*
> > +                        * Calculate the maximum number of bytes to transfer,
> > +                        * making sure it is less than the hw limit
> > +                        */
> > +                       copy = min_t(size_t, sg_dma_len(sg) - sg_used,
> > +                                    XILINX_DMA_MAX_TRANS_LEN);
> > +                       hw = &segment->hw;
> > +
> > +                       /* Fill in the descriptor */
> > +                       hw->buf_addr = sg_dma_address(sg) + sg_used;
> > +
> > +                       hw->control = copy;
> > +
> > +                       if (direction == DMA_MEM_TO_DEV) {
> > +                               if (app_w)
> > +                                       memcpy(hw->app, app_w, sizeof(u32) *
> > +                                              XILINX_DMA_NUM_APP_WORDS);
> > +                       }
> > +
> > +                       sg_used += copy;
> > +
> > +                       /*
> > +                        * Insert the segment into the descriptor segments
> > +                        * list.
> > +                        */
> > +                       list_add_tail(&segment->node, &desc->segments);
> > +               }
> > +       }
> > +
> > +       segment = list_first_entry(&desc->segments,
> > +                                  struct xilinx_dma_tx_segment, node);
> > +       desc->async_tx.phys = segment->phys;
> > +
> > +       /* For the last DMA_MEM_TO_DEV transfer, set EOP */
> > +       if (direction == DMA_MEM_TO_DEV) {
> > +               segment->hw.control |= XILINX_DMA_BD_SOP;
> > +               segment = list_last_entry(&desc->segments,
> > +                                         struct xilinx_dma_tx_segment,
> > +                                         node);
> > +               segment->hw.control |= XILINX_DMA_BD_EOP;
> > +       }
> > +
> > +       return &desc->async_tx;
> > +
> > +error:
> > +       xilinx_dma_free_tx_descriptor(chan, desc);
> > +       return NULL;
> > +}
> > +
> > +/**
> > + * xilinx_dma_terminate_all - Halt the channel and free descriptors
> > + * @dchan: DMA Channel pointer
> > + *
> > + * Return: '0' always
> > + */
> > +static int xilinx_dma_terminate_all(struct dma_chan *dchan) {
> > +       struct xilinx_dma_chan *chan = to_xilinx_chan(dchan);
> > +
> > +       /* Halt the DMA engine */
> > +       xilinx_dma_halt(chan);
> > +
> > +       /* Remove and free all of the descriptors in the lists */
> > +       xilinx_dma_free_descriptors(chan);
> > +
> > +       return 0;
> > +}
> > +
> > +/**
> > + * xilinx_dma_chan_remove - Per Channel remove function
> > + * @chan: Driver specific DMA channel  */ static void
> > +xilinx_dma_chan_remove(struct xilinx_dma_chan *chan) {
> > +       /* Disable interrupts */
> > +       chan->ctrl_reg &= ~XILINX_DMA_XR_IRQ_ALL_MASK;
> > +       dma_ctrl_write(chan, XILINX_DMA_REG_CONTROL, chan->ctrl_reg);
> > +
> > +       if (chan->irq > 0)
> > +               free_irq(chan->irq, chan);
> > +
> > +       tasklet_kill(&chan->tasklet);
> > +
> > +       list_del(&chan->common.device_node);
> > +}
> > +
> > +/**
> > + * xilinx_dma_chan_probe - Per Channel Probing
> > + * It get channel features from the device tree entry and
> > + * initialize special channel handling routines
> > + *
> > + * @xdev: Driver specific device structure
> > + * @node: Device node
> > + *
> > + * Return: '0' on success and failure value on error  */ static int
> > +xilinx_dma_chan_probe(struct xilinx_dma_device *xdev,
> > +                                struct device_node *node) {
> > +       struct xilinx_dma_chan *chan;
> > +       int err;
> > +       bool has_dre;
> > +       u32 value, width = 0;
> > +
> > +       /* alloc channel */
> > +       chan = devm_kzalloc(xdev->dev, sizeof(*chan), GFP_KERNEL);
> > +       if (!chan)
> > +               return -ENOMEM;
> > +
> > +       chan->dev = xdev->dev;
> > +       chan->xdev = xdev;
> > +       chan->has_sg = xdev->has_sg;
> > +       chan->desc_pendingcount = 0x0;
> > +
> > +       has_dre = of_property_read_bool(node, "xlnx,include-dre");
> > +
> > +       err = of_property_read_u32(node, "xlnx,datawidth", &value);
> > +       if (err) {
> > +               dev_err(xdev->dev, "unable to read datawidth property");
> > +               return err;
> > +       }
> > +
> > +       width = value >> 3; /* Convert bits to bytes */
> > +
> > +       /* If data width is greater than 8 bytes, DRE is not in hw */
> > +       if (width > 8)
> > +               has_dre = false;
> > +
> > +       if (!has_dre)
> > +               xdev->common.copy_align = fls(width - 1);
> > +
> > +       if (of_device_is_compatible(node, "xlnx,axi-dma-mm2s-channel")) {
> > +               chan->id = 0;
> > +               chan->ctrl_offset = XILINX_DMA_MM2S_CTRL_OFFSET;
> > +       } else if (of_device_is_compatible(node, "xlnx,axi-dma-s2mm-channel")) {
> > +               chan->id = 1;
> > +               chan->ctrl_offset = XILINX_DMA_S2MM_CTRL_OFFSET;
> > +       } else {
> > +               dev_err(xdev->dev, "Invalid channel compatible node\n");
> > +               return -EINVAL;
> > +       }
> > +
> > +       xdev->chan[chan->id] = chan;
> > +
> > +       /* Initialize the channel */
> > +       err = xilinx_dma_chan_reset(chan);
> > +       if (err) {
> > +               dev_err(xdev->dev, "Reset channel failed\n");
> > +               return err;
> > +       }
> > +
> > +       spin_lock_init(&chan->lock);
> > +       INIT_LIST_HEAD(&chan->pending_list);
> > +       INIT_LIST_HEAD(&chan->done_list);
> > +       INIT_LIST_HEAD(&chan->active_list);
> > +       INIT_LIST_HEAD(&chan->free_seg_list);
> > +
> > +       chan->common.device = &xdev->common;
> > +
> > +       /* find the IRQ line, if it exists in the device tree */
> > +       chan->irq = irq_of_parse_and_map(node, 0);
> > +       err = request_irq(chan->irq, xilinx_dma_irq_handler,
> > +                         IRQF_SHARED,
> > +                         "xilinx-dma-controller", chan);
> > +       if (err) {
> > +               dev_err(xdev->dev, "unable to request IRQ %d\n", chan->irq);
> > +               return err;
> > +       }
> > +
> > +       /* Initialize the tasklet */
> > +       tasklet_init(&chan->tasklet, xilinx_dma_do_tasklet,
> > +                    (unsigned long)chan);
> > +
> > +       /* Add the channel to DMA device channel list */
> > +       list_add_tail(&chan->common.device_node,
> > + &xdev->common.channels);
> > +
> > +       chan->idle = true;
> > +
> > +       return 0;
> > +}
> > +
> > +/**
> > + * of_dma_xilinx_xlate - Translation function
> > + * @dma_spec: Pointer to DMA specifier as found in the device tree
> > + * @ofdma: Pointer to DMA controller data
> > + *
> > + * Return: DMA channel pointer on success and NULL on error  */
> > +static struct dma_chan *of_dma_xilinx_xlate(struct of_phandle_args
> *dma_spec,
> > +                                           struct of_dma *ofdma) {
> > +       struct xilinx_dma_device *xdev = ofdma->of_dma_data;
> > +       int chan_id = dma_spec->args[0];
> > +
> > +       if (chan_id >= XILINX_DMA_MAX_CHANS_PER_DEVICE)
> > +               return NULL;
> > +
> > +       return dma_get_slave_channel(&xdev->chan[chan_id]->common);
> > +}
> > +
> > +/**
> > + * xilinx_dma_probe - Driver probe function
> > + * @pdev: Pointer to the platform_device structure
> > + *
> > + * Return: '0' on success and failure value on error  */ static int
> > +xilinx_dma_probe(struct platform_device *pdev) {
> > +       struct xilinx_dma_device *xdev;
> > +       struct device_node *child, *node;
> > +       struct resource *res;
> > +       int i, ret;
> > +
> > +       xdev = devm_kzalloc(&pdev->dev, sizeof(*xdev), GFP_KERNEL);
> > +       if (!xdev)
> > +               return -ENOMEM;
> > +
> > +       xdev->dev = &(pdev->dev);
> > +       INIT_LIST_HEAD(&xdev->common.channels);
> > +
> > +       node = pdev->dev.of_node;
> > +
> > +       /* Map the registers */
> > +       res = platform_get_resource(pdev, IORESOURCE_MEM, 0);
> > +       xdev->regs = devm_ioremap_resource(&pdev->dev, res);
> > +       if (IS_ERR(xdev->regs))
> > +               return PTR_ERR(xdev->regs);
> > +
> > +       /* Check if SG is enabled */
> > +       xdev->has_sg = of_property_read_bool(node, "xlnx,include-sg");
> > +
> > +       /* Axi DMA only do slave transfers */
> > +       dma_cap_set(DMA_SLAVE, xdev->common.cap_mask);
> > +       dma_cap_set(DMA_PRIVATE, xdev->common.cap_mask);
> > +       xdev->common.device_prep_slave_sg = xilinx_dma_prep_slave_sg;
> > +       xdev->common.device_terminate_all = xilinx_dma_terminate_all;
> > +       xdev->common.device_issue_pending = xilinx_dma_issue_pending;
> > +       xdev->common.device_alloc_chan_resources =
> > +               xilinx_dma_alloc_chan_resources;
> > +       xdev->common.device_free_chan_resources =
> > +               xilinx_dma_free_chan_resources;
> > +       xdev->common.device_tx_status = xilinx_dma_tx_status;
> > +       xdev->common.directions = BIT(DMA_DEV_TO_MEM) |
> BIT(DMA_MEM_TO_DEV);
> > +       xdev->common.residue_granularity =
> DMA_RESIDUE_GRANULARITY_SEGMENT;
> > +       xdev->common.dev = &pdev->dev;
> > +
> > +       platform_set_drvdata(pdev, xdev);
> > +
> > +       for_each_child_of_node(node, child) {
> > +               ret = xilinx_dma_chan_probe(xdev, child);
> > +               if (ret) {
> > +                       dev_err(&pdev->dev, "Probing channels failed\n");
> > +                       goto free_chan_resources;
> > +               }
> > +       }
> > +
> > +       dma_async_device_register(&xdev->common);
> > +
> > +       ret = of_dma_controller_register(node, of_dma_xilinx_xlate, xdev);
> > +       if (ret) {
> > +               dev_err(&pdev->dev, "Unable to register DMA to DT\n");
> > +               dma_async_device_unregister(&xdev->common);
> > +               goto free_chan_resources;
> > +       }
> > +
> > +       dev_info(&pdev->dev, "Xilinx AXI DMA Engine driver
> > + Probed!!\n");
> > +
> > +       return 0;
> > +
> > +free_chan_resources:
> > +       for (i = 0; i < XILINX_DMA_MAX_CHANS_PER_DEVICE; i++)
> > +               if (xdev->chan[i])
> > +                       xilinx_dma_chan_remove(xdev->chan[i]);
> > +
> > +       return ret;
> > +}
> > +
> > +/**
> > + * xilinx_dma_remove - Driver remove function
> > + * @pdev: Pointer to the platform_device structure
> > + *
> > + * Return: Always '0'
> > + */
> > +static int xilinx_dma_remove(struct platform_device *pdev) {
> > +       struct xilinx_dma_device *xdev = platform_get_drvdata(pdev);
> > +       int i;
> > +
> > +       of_dma_controller_free(pdev->dev.of_node);
> > +       dma_async_device_unregister(&xdev->common);
> > +
> > +       for (i = 0; i < XILINX_DMA_MAX_CHANS_PER_DEVICE; i++)
> > +               if (xdev->chan[i])
> > +                       xilinx_dma_chan_remove(xdev->chan[i]);
> > +
> > +       return 0;
> > +}
> > +
> > +static const struct of_device_id xilinx_dma_of_match[] = {
> > +       { .compatible = "xlnx,axi-dma-1.00.a",},
> > +       {}
> > +};
> > +MODULE_DEVICE_TABLE(of, xilinx_dma_of_match);
> > +
> > +static struct platform_driver xilinx_dma_driver = {
> > +       .driver = {
> > +               .name = "xilinx-dma",
> > +               .of_match_table = xilinx_dma_of_match,
> > +       },
> > +       .probe = xilinx_dma_probe,
> > +       .remove = xilinx_dma_remove,
> > +};
> > +
> > +module_platform_driver(xilinx_dma_driver);
> > +
> > +MODULE_AUTHOR("Xilinx, Inc.");
> > +MODULE_DESCRIPTION("Xilinx DMA driver"); MODULE_LICENSE("GPL");
> > --
> > 2.1.2
> >
> >
> > _______________________________________________
> > linux-arm-kernel mailing list
> > linux-arm-kernel at lists.infradead.org
> > http://lists.infradead.org/mailman/listinfo/linux-arm-kernel
>
> Cheers,
>
> Moritz


This email and any attachments are intended for the sole use of the named recipient(s) and contain(s) confidential information that may be proprietary, privileged or copyrighted under applicable law. If you are not the intended recipient, do not read, copy, or forward this email message or any attachments. Delete this email message and any attachments immediately.


From vinod.koul at intel.com  Wed Aug 19 22:40:34 2015
From: vinod.koul at intel.com (Vinod Koul)
Date: Thu, 20 Aug 2015 11:10:34 +0530
Subject: [PATCH v1 2/4] dmaengine: xgene-dma: Add support for CRC32C
 calculation via DMA engine
In-Reply-To: <1438258268-3099-3-git-send-email-rsahu@apm.com>
References: <1438258268-3099-1-git-send-email-rsahu@apm.com>
 <1438258268-3099-3-git-send-email-rsahu@apm.com>
Message-ID: <20150820054034.GX13546@localhost>

On Thu, Jul 30, 2015 at 05:41:06PM +0530, Rameshwar Prasad Sahu wrote:
> +	/* Invalidate unused source address field */
> +	for (; i < 4; i++)
> +		xgene_dma_invalidate_buffer(xgene_dma_lookup_ext8(desc2, i));
> +
> +	/* Check whether requested buffer processed */
> +	if (nbytes) {
> +		chan_err(chan, "Src count crossed maximum limit\n");
> +		return -EINVAL;
no cleanup ?

> +struct dma_async_tx_descriptor *xgene_dma_prep_flyby(
> +	struct xgene_dma_chan *chan, struct scatterlist *src_sg,
> +	size_t len, u32 seed, u8 *result, unsigned long flags, u8 opcode)
please fix style here

> +struct dma_async_tx_descriptor *xgene_dma_prep_crc32c(
> +	struct dma_chan *dchan, struct scatterlist *src_sg,
> +	size_t len, u32 seed, u8 *result, unsigned long flags)
here too

> @@ -1309,8 +1512,13 @@ static void xgene_dma_setup_ring(struct xgene_dma_ring *ring)
>  		  ring->pdma->csr_ring + XGENE_DMA_RING_ID);
> 
>  	/* Set DMA ring buffer */
> -	iowrite32(XGENE_DMA_RING_ID_BUF_SETUP(ring->num),
> -		  ring->pdma->csr_ring + XGENE_DMA_RING_ID_BUF);
> +	ring_id_buf = XGENE_DMA_RING_ID_BUF_SETUP(ring->num);
> +
> +	if (ring->is_bufpool)
> +		ring_id_buf |= XGENE_DMA_RING_IS_BUFPOOL;
> +
> +	iowrite32(ring_id_buf, ring->pdma->csr_ring +
> +		  XGENE_DMA_RING_ID_BUF);
pls fix style here

-- 
~Vinod


From appana.durga.rao at xilinx.com  Wed Aug 19 22:41:23 2015
From: appana.durga.rao at xilinx.com (Appana Durga Kedareswara Rao)
Date: Thu, 20 Aug 2015 05:41:23 +0000
Subject: [RESEND PATCH] dmaengine: Add Xilinx AXI Direct Memory Access
 Engine driver support
In-Reply-To: <CAAtXAHf9S662okN1gchbD246=e4_bMFoyBMrbt5q48xm1uo_CA@mail.gmail.com>
References: <1439825512-16444-1-git-send-email-appanad@xilinx.com>
 <CAAtXAHf9S662okN1gchbD246=e4_bMFoyBMrbt5q48xm1uo_CA@mail.gmail.com>
Message-ID: <C246CAC1457055469EF09E3A7AC4E11A4A4B2BBC@XAP-PVEXMBX01.xlnx.xilinx.com>

Hi Moritz Fischer,

	Thanks for reviewing the patch.

> -----Original Message-----
> From: Moritz Fischer [mailto:moritz.fischer at ettus.com]
> Sent: Thursday, August 20, 2015 3:21 AM
> To: Appana Durga Kedareswara Rao
> Cc: vinod.koul at intel.com; dan.j.williams at intel.com; Michal Simek; Soren
> Brinkmann; Appana Durga Kedareswara Rao; anirudha at xilinx.com;
> dmaengine at vger.kernel.org; linux-kernel at vger.kernel.org; linux-arm-kernel;
> Srikanth Thokala
> Subject: Re: [RESEND PATCH] dmaengine: Add Xilinx AXI Direct Memory Access
> Engine driver support
> 
> Hi there,
> 
> see comment below. I just did a quick compile test. Will take another look once I
> synthesized an image.
> 
> On Mon, Aug 17, 2015 at 8:31 AM, Kedareswara rao Appana
> <appana.durga.rao at xilinx.com> wrote:
> > This is the driver for the AXI Direct Memory Access (AXI DMA) core,
> > which is a soft Xilinx IP core that provides high- bandwidth direct
> > memory access between memory and AXI4-Stream type target peripherals.
> >
> > Signed-off-by: Srikanth Thokala <sthokal at xilinx.com>
> > Signed-off-by: Kedareswara rao Appana <appanad at xilinx.com>
> > ---
> > The deivce tree doc got applied in the slave-dmaengine.git.
> >
> > Forgot to include dmaengine at vger.kernel.org in the cc list resending
> > the patch.
> >
> > Changes in v8:
> > - Updated the SG handling as suggested by Nicolae Rosia.
> > - Removed the unnecessary xilinx_dma_channel_set_config API the properties
> >   in this API is not being used by the driver.
> > Changes in v7:
> > - Updated license in the driver as suggested by Paul.
> > - Corrected return value in is_idle funtion.
> > Changes in v6:
> > - Fixed Odd indention in the Kconfig.
> > - used GFP_NOWAIT instead of GFP_KERNEL during the desc allocation
> > - Calculated residue in the tx_status instead of complete_descriptor.
> > - Update copy right to 2015.
> > - Modified spin_lock handling moved the spin_lock to the appropriate
> > functions (instead of xilinx_dma_start_transfer doing it
> xilinx_dma_issue_pending api).
> > - device_control and declare slave caps updated as per newer APi's.
> > Changes in v5:
> > - Modified the xilinx_dma.h header file location to the
> >   include/linux/dma/xilinx_dma.h
> > Changes in v4:
> > - Add direction field to DMA descriptor structure and removed from
> >   channel structure to avoid duplication.
> > - Check for DMA idle condition before changing the configuration.
> > - Residue is being calculated in complete_descriptor() and is reported
> >   to slave driver.
> > Changes in v3:
> > - Rebased on 3.16-rc7
> > Changes in v2:
> > - Simplified the logic to set SOP and APP words in prep_slave_sg().
> > - Corrected function description comments to match the return type.
> > - Fixed some minor comments as suggested by Andy.
> >
> >  drivers/dma/Kconfig             |   13 +
> >  drivers/dma/xilinx/Makefile     |    1 +
> >  drivers/dma/xilinx/xilinx_dma.c | 1179
> > +++++++++++++++++++++++++++++++++++++++
> >  3 files changed, 1193 insertions(+)
> >  create mode 100644 drivers/dma/xilinx/xilinx_dma.c
> >
> > diff --git a/drivers/dma/Kconfig b/drivers/dma/Kconfig index
> > 88d474b..5e95f07 100644
> > --- a/drivers/dma/Kconfig
> > +++ b/drivers/dma/Kconfig
> > @@ -507,4 +507,17 @@ config QCOM_BAM_DMA
> >           Enable support for the QCOM BAM DMA controller.  This controller
> >           provides DMA capabilities for a variety of on-chip devices.
> >
> > +config XILINX_DMA
> > +        tristate "Xilinx AXI DMA Engine"
> > +        depends on (ARCH_ZYNQ || MICROBLAZE)
> > +        select DMA_ENGINE
> > +        help
> > +          Enable support for Xilinx AXI DMA Soft IP.
> > +
> > +          This engine provides high-bandwidth direct memory access
> > +          between memory and AXI4-Stream type target peripherals.
> > +          It has two stream interfaces/channels, Memory Mapped to
> > +          Stream (MM2S) and Stream to Memory Mapped (S2MM) for the
> > +          data transfers.
> > +
> >  endif
> > diff --git a/drivers/dma/xilinx/Makefile b/drivers/dma/xilinx/Makefile
> > index 3c4e9f2..6224a49 100644
> > --- a/drivers/dma/xilinx/Makefile
> > +++ b/drivers/dma/xilinx/Makefile
> > @@ -1 +1,2 @@
> >  obj-$(CONFIG_XILINX_VDMA) += xilinx_vdma.o
> > +obj-$(CONFIG_XILINX_DMA) += xilinx_dma.o
> > diff --git a/drivers/dma/xilinx/xilinx_dma.c
> > b/drivers/dma/xilinx/xilinx_dma.c new file mode 100644 index
> > 0000000..a9be197
> > --- /dev/null
> > +++ b/drivers/dma/xilinx/xilinx_dma.c
> > @@ -0,0 +1,1179 @@
> > +/*
> > + * DMA driver for Xilinx DMA Engine
> > + *
> > + * Copyright (C) 2010 - 2015 Xilinx, Inc. All rights reserved.
> > + *
> > + * Based on the Freescale DMA driver.
> > + *
> > + * Description:
> > + *  The AXI DMA, is a soft IP, which provides high-bandwidth Direct
> > +Memory
> > + *  Access between memory and AXI4-Stream-type target peripherals. It
> > +can be
> > + *  configured to have one channel or two channels and if configured
> > +as two
> > + *  channels, one is to transmit data from memory to a device and
> > +another is
> > + *  to receive from a device.
> > + *
> > + * This 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.
> > + */
> > +
> > +#include <linux/bitops.h>
> > +#include <linux/dma/xilinx_dma.h>
> > +#include <linux/init.h>
> > +#include <linux/interrupt.h>
> > +#include <linux/io.h>
> > +#include <linux/module.h>
> > +#include <linux/of_address.h>
> > +#include <linux/of_dma.h>
> > +#include <linux/of_irq.h>
> > +#include <linux/of_platform.h>
> > +#include <linux/slab.h>
> > +
> > +#include "../dmaengine.h"
> > +
> > +/* Register Offsets */
> > +#define XILINX_DMA_REG_CONTROL         0x00
> > +#define XILINX_DMA_REG_STATUS          0x04
> > +#define XILINX_DMA_REG_CURDESC         0x08
> > +#define XILINX_DMA_REG_TAILDESC                0x10
> > +#define XILINX_DMA_REG_SRCADDR         0x18
> > +#define XILINX_DMA_REG_DSTADDR         0x20
> > +#define XILINX_DMA_REG_BTT             0x28
> > +
> > +/* Channel/Descriptor Offsets */
> > +#define XILINX_DMA_MM2S_CTRL_OFFSET    0x00
> > +#define XILINX_DMA_S2MM_CTRL_OFFSET    0x30
> > +
> > +/* General register bits definitions */
> > +#define XILINX_DMA_CR_RUNSTOP_MASK     BIT(0)
> > +#define XILINX_DMA_CR_RESET_MASK       BIT(2)
> > +
> > +#define XILINX_DMA_CR_DELAY_SHIFT      24
> > +#define XILINX_DMA_CR_COALESCE_SHIFT   16
> > +
> > +#define XILINX_DMA_CR_DELAY_MAX                GENMASK(7, 0)
> > +#define XILINX_DMA_CR_COALESCE_MAX     GENMASK(7, 0)
> > +
> > +#define XILINX_DMA_SR_HALTED_MASK      BIT(0)
> > +#define XILINX_DMA_SR_IDLE_MASK                BIT(1)
> > +
> > +#define XILINX_DMA_XR_IRQ_IOC_MASK     BIT(12)
> > +#define XILINX_DMA_XR_IRQ_DELAY_MASK   BIT(13)
> > +#define XILINX_DMA_XR_IRQ_ERROR_MASK   BIT(14)
> > +#define XILINX_DMA_XR_IRQ_ALL_MASK     GENMASK(14, 12)
> > +
> > +/* BD definitions */
> > +#define XILINX_DMA_BD_STS_ALL_MASK     GENMASK(31, 28)
> > +#define XILINX_DMA_BD_SOP              BIT(27)
> > +#define XILINX_DMA_BD_EOP              BIT(26)
> > +
> > +/* Hw specific definitions */
> > +#define XILINX_DMA_MAX_CHANS_PER_DEVICE        0x2
> > +#define XILINX_DMA_MAX_TRANS_LEN       GENMASK(22, 0)
> > +
> > +/* Delay loop counter to prevent hardware failure */
> > +#define XILINX_DMA_LOOP_COUNT          1000000
> > +
> > +/* Maximum number of Descriptors */
> > +#define XILINX_DMA_NUM_DESCS           255
> > +#define XILINX_DMA_COALESCE_MAX                255
> > +#define XILINX_DMA_NUM_APP_WORDS       5
> > +
> > +/**
> > + * struct xilinx_dma_desc_hw - Hardware Descriptor
> > + * @next_desc: Next Descriptor Pointer @0x00
> > + * @pad1: Reserved @0x04
> > + * @buf_addr: Buffer address @0x08
> > + * @pad2: Reserved @0x0C
> > + * @pad3: Reserved @0x10
> > + * @pad4: Reserved @0x14
> > + * @control: Control field @0x18
> > + * @status: Status field @0x1C
> > + * @app: APP Fields @0x20 - 0x30
> > + */
> > +struct xilinx_dma_desc_hw {
> > +       u32 next_desc;
> > +       u32 pad1;
> > +       u32 buf_addr;
> > +       u32 pad2;
> > +       u32 pad3;
> > +       u32 pad4;
> > +       u32 control;
> > +       u32 status;
> > +       u32 app[XILINX_DMA_NUM_APP_WORDS]; } __aligned(64);
> > +
> > +/**
> > + * struct xilinx_dma_tx_segment - Descriptor segment
> > + * @hw: Hardware descriptor
> > + * @node: Node in the descriptor segments list
> > + * @phys: Physical address of segment  */ struct
> > +xilinx_dma_tx_segment {
> > +       struct xilinx_dma_desc_hw hw;
> > +       struct list_head node;
> > +       dma_addr_t phys;
> > +} __aligned(64);
> > +
> > +/**
> > + * struct xilinx_dma_tx_descriptor - Per Transaction structure
> > + * @async_tx: Async transaction descriptor
> > + * @segments: TX segments list
> > + * @node: Node in the channel descriptors list
> > + * @direction: Transfer direction
> > + */
> > +struct xilinx_dma_tx_descriptor {
> > +       struct dma_async_tx_descriptor async_tx;
> > +       struct list_head segments;
> > +       struct list_head node;
> > +       enum dma_transfer_direction direction; };
> > +
> > +/**
> > + * struct xilinx_dma_chan - Driver specific DMA channel structure
> > + * @xdev: Driver specific device structure
> > + * @ctrl_offset: Control registers offset
> > + * @ctrl_reg: Control register value
> > + * @lock: Descriptor operation lock
> > + * @pending_list: Descriptors waiting
> > + * @active_list: Descriptors ready to submit
> > + * @done_list: Complete descriptors
> > + * @free_seg_list: Free descriptors
> > + * @common: DMA common channel
> > + * @seg_v: Statically allocated segments base
> > + * @seg_p: Physical allocated segments base
> > + * @dev: The dma device
> > + * @irq: Channel IRQ
> > + * @id: Channel ID
> > + * @has_sg: Support scatter transfers
> > + * @idle: Check for channel idle
> > + * @err: Channel has errors
> > + * @tasklet: Cleanup work after irq
> > + * @residue: Residue
> > + * @desc_pendingcount: Descriptor pending count  */ struct
> > +xilinx_dma_chan {
> > +       struct xilinx_dma_device *xdev;
> > +       u32 ctrl_offset;
> > +       u32 ctrl_reg;
> > +       spinlock_t lock;
> > +       struct list_head pending_list;
> > +       struct list_head done_list;
> > +       struct list_head active_list;
> > +       struct list_head free_seg_list;
> > +       struct dma_chan common;
> > +       struct xilinx_dma_tx_segment *seg_v;
> > +       dma_addr_t seg_p;
> > +       struct device *dev;
> > +       int irq;
> > +       int id;
> > +       bool has_sg;
> > +       bool idle;
> > +       int err;
> > +       struct tasklet_struct tasklet;
> > +       u32 residue;
> > +       u32 desc_pendingcount;
> > +};
> > +
> > +/**
> > + * struct xilinx_dma_device - DMA device structure
> > + * @regs: I/O mapped base address
> > + * @dev: Device Structure
> > + * @common: DMA device structure
> > + * @chan: Driver specific DMA channel
> > + * @has_sg: Specifies whether Scatter-Gather is present or not  */
> > +struct xilinx_dma_device {
> > +       void __iomem *regs;
> > +       struct device *dev;
> > +       struct dma_device common;
> > +       struct xilinx_dma_chan *chan[XILINX_DMA_MAX_CHANS_PER_DEVICE];
> > +       bool has_sg;
> > +};
> > +
> > +/* Macros */
> > +#define to_xilinx_chan(chan) \
> > +       container_of(chan, struct xilinx_dma_chan, common) #define
> > +to_dma_tx_descriptor(tx) \
> > +       container_of(tx, struct xilinx_dma_tx_descriptor, async_tx)
> > +
> > +/* IO accessors */
> > +static inline void dma_write(struct xilinx_dma_chan *chan, u32 reg,
> > +u32 value) {
> > +       iowrite32(value, chan->xdev->regs + reg);
> Any reason to not use write here?
Most of the Xilinx drivers and the VDMA driver that got up streamed Use iowrite to make consistency b/w the drivers I used the same API's.

What is the advantage we will gain by using writel instead of iowrite32?

> > +}
> > +
> > +static inline u32 dma_read(struct xilinx_dma_chan *chan, u32 reg) {
> > +       return ioread32(chan->xdev->regs + reg);
> Any reason to not use readl here?
> > +}
> > +
> > +static inline u32 dma_ctrl_read(struct xilinx_dma_chan *chan, u32
> > +reg) {
> > +       return dma_read(chan, chan->ctrl_offset + reg); }
> > +
> > +static inline void dma_ctrl_write(struct xilinx_dma_chan *chan, u32 reg,
> > +                                 u32 value) {
> > +       dma_write(chan, chan->ctrl_offset + reg, value); }
> > +
> > +/*
> > +---------------------------------------------------------------------
> > +--------
> > + * Descriptors and segments alloc and free  */
> > +
> > +/**
> > + * xilinx_dma_alloc_tx_segment - Allocate transaction segment
> > + * @chan: Driver specific dma channel
> > + *
> > + * Return: The allocated segment on success and NULL on failure.
> > + */
> > +static struct xilinx_dma_tx_segment *
> > +xilinx_dma_alloc_tx_segment(struct xilinx_dma_chan *chan) {
> > +       struct xilinx_dma_tx_segment *segment = NULL;
> > +       unsigned long flags;
> > +
> > +       spin_lock_irqsave(&chan->lock, flags);
> > +       if (!list_empty(&chan->free_seg_list)) {
> > +               segment = list_first_entry(&chan->free_seg_list,
> > +                                          struct xilinx_dma_tx_segment,
> > +                                          node);
> > +               list_del(&segment->node);
> > +       }
> > +       spin_unlock_irqrestore(&chan->lock, flags);
> > +
> > +       return segment;
> > +}
> > +
> > +/**
> > + * xilinx_dma_clean_hw_desc - Clean hardware descriptor
> > + * @hw: HW descriptor to clean
> > + */
> > +static void xilinx_dma_clean_hw_desc(struct xilinx_dma_desc_hw *hw) {
> > +       u32 next_desc = hw->next_desc;
> > +
> > +       memset(hw, 0, sizeof(struct xilinx_dma_desc_hw));
> > +
> > +       hw->next_desc = next_desc;
> > +}
> > +
> > +/**
> > + * xilinx_dma_free_tx_segment - Free transaction segment
> > + * @chan: Driver specific dma channel
> > + * @segment: dma transaction segment
> > + */
> > +static void xilinx_dma_free_tx_segment(struct xilinx_dma_chan *chan,
> > +                                      struct xilinx_dma_tx_segment
> > +*segment) {
> > +       xilinx_dma_clean_hw_desc(&segment->hw);
> > +
> > +       list_add_tail(&segment->node, &chan->free_seg_list); }
> > +
> > +/**
> > + * xilinx_dma_tx_descriptor - Allocate transaction descriptor
> > + * @chan: Driver specific dma channel
> > + *
> > + * Return: The allocated descriptor on success and NULL on failure.
> > + */
> > +static struct xilinx_dma_tx_descriptor *
> > +xilinx_dma_alloc_tx_descriptor(struct xilinx_dma_chan *chan) {
> > +       struct xilinx_dma_tx_descriptor *desc;
> > +
> > +       desc = kzalloc(sizeof(*desc), GFP_NOWAIT);
> > +       if (!desc)
> > +               return NULL;
> > +
> > +       INIT_LIST_HEAD(&desc->segments);
> > +
> > +       return desc;
> > +}
> > +
> > +/**
> > + * xilinx_dma_free_tx_descriptor - Free transaction descriptor
> > + * @chan: Driver specific dma channel
> > + * @desc: dma transaction descriptor
> > + */
> > +static void
> > +xilinx_dma_free_tx_descriptor(struct xilinx_dma_chan *chan,
> > +                             struct xilinx_dma_tx_descriptor *desc) {
> > +       struct xilinx_dma_tx_segment *segment, *next;
> > +
> > +       if (!desc)
> > +               return;
> > +
> > +       list_for_each_entry_safe(segment, next, &desc->segments, node) {
> > +               list_del(&segment->node);
> > +               xilinx_dma_free_tx_segment(chan, segment);
> > +       }
> > +
> > +       kfree(desc);
> > +}
> > +
> > +/**
> > + * xilinx_dma_alloc_chan_resources - Allocate channel resources
> > + * @dchan: DMA channel
> > + *
> > + * Return: '0' on success and failure value on error  */ static int
> > +xilinx_dma_alloc_chan_resources(struct dma_chan *dchan) {
> > +       struct xilinx_dma_chan *chan = to_xilinx_chan(dchan);
> > +       int i;
> > +
> > +       /* Allocate the buffer descriptors. */
> > +       chan->seg_v = dma_zalloc_coherent(chan->dev,
> > +                                         sizeof(*chan->seg_v) *
> > +                                         XILINX_DMA_NUM_DESCS,
> > +                                         &chan->seg_p, GFP_KERNEL);
> > +       if (!chan->seg_v) {
> > +               dev_err(chan->dev,
> > +                       "unable to allocate channel %d descriptors\n",
> > +                       chan->id);
> > +               return -ENOMEM;
> > +       }
> > +
> > +       for (i = 0; i < XILINX_DMA_NUM_DESCS; i++) {
> > +               chan->seg_v[i].hw.next_desc =
> > +                               chan->seg_p + sizeof(*chan->seg_v) *
> > +                               ((i + 1) % XILINX_DMA_NUM_DESCS);
> > +               chan->seg_v[i].phys =
> > +                               chan->seg_p + sizeof(*chan->seg_v) * i;
> > +               list_add_tail(&chan->seg_v[i].node, &chan->free_seg_list);
> > +       }
> > +
> > +       dma_cookie_init(dchan);
> > +
> > +       /* Enable interrupts */
> > +       chan->ctrl_reg |= XILINX_DMA_XR_IRQ_ALL_MASK;
> > +       dma_ctrl_write(chan, XILINX_DMA_REG_CONTROL, chan->ctrl_reg);
> > +
> > +       return 0;
> > +}
> > +
> > +/**
> > + * xilinx_dma_free_desc_list - Free descriptors list
> > + * @chan: Driver specific dma channel
> > + * @list: List to parse and delete the descriptor  */ static void
> > +xilinx_dma_free_desc_list(struct xilinx_dma_chan *chan,
> > +                                     struct list_head *list) {
> > +       struct xilinx_dma_tx_descriptor *desc, *next;
> > +
> > +       list_for_each_entry_safe(desc, next, list, node) {
> > +               list_del(&desc->node);
> > +               xilinx_dma_free_tx_descriptor(chan, desc);
> > +       }
> > +}
> > +
> > +/**
> > + * xilinx_dma_free_descriptors - Free channel descriptors
> > + * @chan: Driver specific dma channel  */ static void
> > +xilinx_dma_free_descriptors(struct xilinx_dma_chan *chan) {
> > +       unsigned long flags;
> > +
> > +       spin_lock_irqsave(&chan->lock, flags);
> > +
> > +       xilinx_dma_free_desc_list(chan, &chan->pending_list);
> > +       xilinx_dma_free_desc_list(chan, &chan->done_list);
> > +       xilinx_dma_free_desc_list(chan, &chan->active_list);
> > +
> > +       spin_unlock_irqrestore(&chan->lock, flags); }
> > +
> > +/**
> > + * xilinx_dma_free_chan_resources - Free channel resources
> > + * @dchan: DMA channel
> > + */
> > +static void xilinx_dma_free_chan_resources(struct dma_chan *dchan) {
> > +       struct xilinx_dma_chan *chan = to_xilinx_chan(dchan);
> > +
> > +       xilinx_dma_free_descriptors(chan);
> > +
> > +       dma_free_coherent(chan->dev,
> > +                         sizeof(*chan->seg_v) * XILINX_DMA_NUM_DESCS,
> > +                         chan->seg_v, chan->seg_p); }
> > +
> > +/**
> > + * xilinx_dma_chan_desc_cleanup - Clean channel descriptors
> > + * @chan: Driver specific dma channel  */ static void
> > +xilinx_dma_chan_desc_cleanup(struct xilinx_dma_chan *chan) {
> > +       struct xilinx_dma_tx_descriptor *desc;
> > +       unsigned long flags;
> > +
> > +       spin_lock_irqsave(&chan->lock, flags);
> > +
> > +       while (!list_empty(&chan->done_list)) {
> > +               dma_async_tx_callback callback;
> > +               void *callback_param;
> > +
> > +               desc = list_first_entry(&chan->done_list,
> > +                       struct xilinx_dma_tx_descriptor, node);
> > +
> > +               /* Remove from the list of running transactions */
> > +               list_del(&desc->node);
> > +
> > +               /* Run the link descriptor callback function */
> > +               callback = desc->async_tx.callback;
> > +               callback_param = desc->async_tx.callback_param;
> > +               if (callback) {
> > +                       spin_unlock_irqrestore(&chan->lock, flags);
> > +                       callback(callback_param);
> > +                       spin_lock_irqsave(&chan->lock, flags);
> > +               }
> > +
> > +               /* Run any dependencies, then free the descriptor */
> > +               dma_run_dependencies(&desc->async_tx);
> > +               xilinx_dma_free_tx_descriptor(chan, desc);
> > +       }
> > +
> > +       spin_unlock_irqrestore(&chan->lock, flags); }
> > +
> > +/**
> > + * xilinx_dma_tx_status - Get dma transaction status
> > + * @dchan: DMA channel
> > + * @cookie: Transaction identifier
> > + * @txstate: Transaction state
> > + *
> > + * Return: DMA transaction status
> > + */
> > +static enum dma_status xilinx_dma_tx_status(struct dma_chan *dchan,
> > +                                           dma_cookie_t cookie,
> > +                                           struct dma_tx_state
> > +*txstate) {
> > +       struct xilinx_dma_chan *chan = to_xilinx_chan(dchan);
> > +       struct xilinx_dma_tx_descriptor *desc;
> > +       struct xilinx_dma_tx_segment *segment;
> > +       struct xilinx_dma_desc_hw *hw;
> > +       enum dma_status ret;
> > +       unsigned long flags;
> > +       u32 residue;
> 
> While compiling this threw a residue may be used uninitialized warning, I
> suppose 0 would be a sensible default value?

Ok will fix it.

> > +
> > +       ret = dma_cookie_status(dchan, cookie, txstate);
> > +       if (ret == DMA_COMPLETE || !txstate)
> > +               return ret;
> > +
> > +       desc = list_last_entry(&chan->active_list,
> > +                              struct xilinx_dma_tx_descriptor, node);
> > +
> > +       spin_lock_irqsave(&chan->lock, flags);
> > +       if (chan->has_sg) {
> > +               while (!list_empty(&desc->segments)) {
> > +                       segment = list_first_entry(&desc->segments,
> > +                                       struct xilinx_dma_tx_segment, node);
> > +                       hw = &segment->hw;
> > +                       residue += (hw->control - hw->status) &
> > +                                  XILINX_DMA_MAX_TRANS_LEN;
> > +               }
> > +       }
> > +
> > +       chan->residue = residue;
> > +       dma_set_residue(txstate, chan->residue);
> > +       spin_unlock_irqrestore(&chan->lock, flags);
> > +
> > +       return ret;
> > +}
> > +
> > +/**
> > + * xilinx_dma_halt - Halt DMA channel
> > + * @chan: Driver specific DMA channel  */ static void
> > +xilinx_dma_halt(struct xilinx_dma_chan *chan) {
> > +       int loop = XILINX_DMA_LOOP_COUNT;
> > +
> > +       chan->ctrl_reg &= ~XILINX_DMA_CR_RUNSTOP_MASK;
> > +       dma_ctrl_write(chan, XILINX_DMA_REG_CONTROL, chan->ctrl_reg);
> > +
> > +       /* Wait for the hardware to halt */
> > +       do {
> > +               if (dma_ctrl_read(chan, XILINX_DMA_REG_STATUS) &
> > +                       XILINX_DMA_SR_HALTED_MASK)
> > +                       break;
> > +       } while (loop--);
> > +
> > +       if (!loop) {
> > +               dev_err(chan->dev, "Cannot stop channel %p: %x\n",
> > +                       chan, dma_ctrl_read(chan, XILINX_DMA_REG_STATUS));
> > +               chan->err = true;
> > +       }
> > +}
> > +
> > +/**
> > + * xilinx_dma_start - Start DMA channel
> > + * @chan: Driver specific DMA channel  */ static void
> > +xilinx_dma_start(struct xilinx_dma_chan *chan) {
> > +       int loop = XILINX_DMA_LOOP_COUNT;
> > +
> > +       chan->ctrl_reg |= XILINX_DMA_CR_RUNSTOP_MASK;
> > +       dma_ctrl_write(chan, XILINX_DMA_REG_CONTROL, chan->ctrl_reg);
> > +
> > +       /* Wait for the hardware to start */
> > +       do {
> > +               if (!dma_ctrl_read(chan, XILINX_DMA_REG_STATUS) &
> > +                       XILINX_DMA_SR_HALTED_MASK)
> > +                       break;
> > +       } while (loop--);
> Maybe use one of the readx_poll_timeout functions?

Ok will fix it.

> > +
> > +       if (!loop) {
> > +               dev_err(chan->dev, "Cannot start channel %p: %x\n",
> > +                        chan, dma_ctrl_read(chan, XILINX_DMA_REG_STATUS));
> > +               chan->err = true;
> > +       }
> > +}
> > +
> > +/**
> > + * xilinx_dma_start_transfer - Starts DMA transfer
> > + * @chan: Driver specific channel struct pointer  */ static void
> > +xilinx_dma_start_transfer(struct xilinx_dma_chan *chan) {
> > +       struct xilinx_dma_tx_descriptor *head_desc, *tail_desc;
> > +       struct xilinx_dma_tx_segment *tail_segment;
> > +
> > +       if (chan->err)
> > +               return;
> > +
> > +       if (list_empty(&chan->pending_list))
> > +               return;
> > +
> > +       if (!chan->idle)
> > +               return;
> > +
> > +       head_desc = list_first_entry(&chan->pending_list,
> > +                                    struct xilinx_dma_tx_descriptor, node);
> > +       tail_desc = list_last_entry(&chan->pending_list,
> > +                                   struct xilinx_dma_tx_descriptor, node);
> > +       tail_segment = list_last_entry(&tail_desc->segments,
> > +                                      struct xilinx_dma_tx_segment,
> > + node);
> > +
> > +       if (chan->desc_pendingcount <= XILINX_DMA_COALESCE_MAX) {
> > +               chan->ctrl_reg &= ~XILINX_DMA_CR_COALESCE_MAX;
> > +               chan->ctrl_reg |= chan->desc_pendingcount <<
> > +                                 XILINX_DMA_CR_COALESCE_SHIFT;
> > +               dma_ctrl_write(chan, XILINX_DMA_REG_CONTROL, chan->ctrl_reg);
> > +       }
> > +
> > +       if (chan->has_sg)
> > +               dma_ctrl_write(chan, XILINX_DMA_REG_CURDESC,
> > +                              head_desc->async_tx.phys);
> > +
> > +       xilinx_dma_start(chan);
> > +
> > +       if (chan->err)
> > +               return;
> > +
> > +       /* Start the transfer */
> > +       if (chan->has_sg) {
> > +               dma_ctrl_write(chan, XILINX_DMA_REG_TAILDESC,
> > +                              tail_segment->phys);
> > +       } else {
> > +               struct xilinx_dma_tx_segment *segment;
> > +               struct xilinx_dma_desc_hw *hw;
> > +
> > +               segment = list_first_entry(&head_desc->segments,
> > +                                          struct xilinx_dma_tx_segment, node);
> > +               hw = &segment->hw;
> > +
> > +               if (head_desc->direction == DMA_MEM_TO_DEV)
> > +                       dma_ctrl_write(chan, XILINX_DMA_REG_SRCADDR,
> > +                                      hw->buf_addr);
> > +               else
> > +                       dma_ctrl_write(chan, XILINX_DMA_REG_DSTADDR,
> > +                                      hw->buf_addr);
> > +
> > +               /* Start the transfer */
> > +               dma_ctrl_write(chan, XILINX_DMA_REG_BTT,
> > +                              hw->control & XILINX_DMA_MAX_TRANS_LEN);
> > +       }
> > +
> > +       list_splice_tail_init(&chan->pending_list, &chan->active_list);
> > +       chan->desc_pendingcount = 0;
> > +       chan->idle = false;
> > +}
> > +
> > +/**
> > + * xilinx_dma_issue_pending - Issue pending transactions
> > + * @dchan: DMA channel
> > + */
> > +static void xilinx_dma_issue_pending(struct dma_chan *dchan) {
> > +       struct xilinx_dma_chan *chan = to_xilinx_chan(dchan);
> > +       unsigned long flags;
> > +
> > +       spin_lock_irqsave(&chan->lock, flags);
> > +       xilinx_dma_start_transfer(chan);
> > +       spin_unlock_irqrestore(&chan->lock, flags); }
> > +
> > +/**
> > + * xilinx_dma_complete_descriptor - Mark the active descriptor as
> > +complete
> > + * @chan : xilinx DMA channel
> > + */
> > +static void xilinx_dma_complete_descriptor(struct xilinx_dma_chan
> > +*chan) {
> > +       struct xilinx_dma_tx_descriptor *desc, *next;
> > +
> > +       if (list_empty(&chan->active_list))
> > +               return;
> > +
> > +       list_for_each_entry_safe(desc, next, &chan->active_list, node) {
> > +               list_del(&desc->node);
> > +               dma_cookie_complete(&desc->async_tx);
> > +               list_add_tail(&desc->node, &chan->done_list);
> > +       }
> > +}
> > +
> > +/**
> > + * xilinx_dma_reset - Reset DMA channel
> > + * @chan: Driver specific DMA channel
> > + *
> > + * Return: '0' on success and failure value on error  */ static int
> > +xilinx_dma_chan_reset(struct xilinx_dma_chan *chan) {
> > +       int loop = XILINX_DMA_LOOP_COUNT;
> > +       u32 tmp;
> > +
> > +       chan->ctrl_reg = dma_ctrl_read(chan, XILINX_DMA_REG_CONTROL);
> > +       dma_ctrl_write(chan, XILINX_DMA_REG_CONTROL, chan->ctrl_reg |
> > +                      XILINX_DMA_CR_RESET_MASK);
> > +
> > +       tmp = dma_ctrl_read(chan, XILINX_DMA_REG_CONTROL) &
> > +             XILINX_DMA_CR_RESET_MASK;
> > +
> > +       /* Wait for the hardware to finish reset */
> > +       do {
> > +               tmp = dma_ctrl_read(chan, XILINX_DMA_REG_CONTROL) &
> > +                     XILINX_DMA_CR_RESET_MASK;
> > +       } while (loop-- && tmp);
> See above

Ok will fix it.

Regards,
Kedar.

> > +
> > +       if (!loop) {
> > +               dev_err(chan->dev, "reset timeout, cr %x, sr %x\n",
> > +                       dma_ctrl_read(chan, XILINX_DMA_REG_CONTROL),
> > +                       dma_ctrl_read(chan, XILINX_DMA_REG_STATUS));
> > +               return -EBUSY;
> > +       }
> > +
> > +       chan->err = false;
> > +
> > +       return 0;
> > +}
> > +
> > +/**
> > + * xilinx_dma_irq_handler - DMA Interrupt handler
> > + * @irq: IRQ number
> > + * @data: Pointer to the Xilinx DMA channel structure
> > + *
> > + * Return: IRQ_HANDLED/IRQ_NONE
> > + */
> > +static irqreturn_t xilinx_dma_irq_handler(int irq, void *data) {
> > +       struct xilinx_dma_chan *chan = data;
> > +       u32 status;
> > +
> > +       /* Read the status and ack the interrupts. */
> > +       status = dma_ctrl_read(chan, XILINX_DMA_REG_STATUS);
> > +       if (!(status & XILINX_DMA_XR_IRQ_ALL_MASK))
> > +               return IRQ_NONE;
> > +
> > +       dma_ctrl_write(chan, XILINX_DMA_REG_STATUS,
> > +                      status & XILINX_DMA_XR_IRQ_ALL_MASK);
> > +
> > +       if (status & XILINX_DMA_XR_IRQ_ERROR_MASK) {
> > +               dev_err(chan->dev,
> > +                       "Channel %p has errors %x, cdr %x tdr %x\n",
> > +                       chan, dma_ctrl_read(chan, XILINX_DMA_REG_STATUS),
> > +                       dma_ctrl_read(chan, XILINX_DMA_REG_CURDESC),
> > +                       dma_ctrl_read(chan, XILINX_DMA_REG_TAILDESC));
> > +               chan->err = true;
> > +       }
> > +
> > +       /*
> > +        * Device takes too long to do the transfer when user requires
> > +        * responsiveness
> > +        */
> > +       if (status & XILINX_DMA_XR_IRQ_DELAY_MASK)
> > +               dev_dbg(chan->dev, "Inter-packet latency too long\n");
> > +
> > +       if (status & XILINX_DMA_XR_IRQ_IOC_MASK) {
> > +               spin_lock(&chan->lock);
> > +               xilinx_dma_complete_descriptor(chan);
> > +               chan->idle = true;
> > +               xilinx_dma_start_transfer(chan);
> > +               spin_unlock(&chan->lock);
> > +       }
> > +
> > +       tasklet_schedule(&chan->tasklet);
> > +       return IRQ_HANDLED;
> > +}
> > +
> > +/**
> > + * xilinx_dma_do_tasklet - Schedule completion tasklet
> > + * @data: Pointer to the Xilinx dma channel structure  */ static void
> > +xilinx_dma_do_tasklet(unsigned long data) {
> > +       struct xilinx_dma_chan *chan = (struct xilinx_dma_chan *)data;
> > +
> > +       xilinx_dma_chan_desc_cleanup(chan);
> > +}
> > +
> > +/**
> > + * append_desc_queue - Queuing descriptor
> > + * @chan: Driver specific dma channel
> > + * @desc: dma transaction descriptor
> > + */
> > +static void append_desc_queue(struct xilinx_dma_chan *chan,
> > +                             struct xilinx_dma_tx_descriptor *desc) {
> > +       struct xilinx_dma_tx_segment *tail_segment;
> > +       struct xilinx_dma_tx_descriptor *tail_desc;
> > +
> > +       if (list_empty(&chan->pending_list))
> > +               goto append;
> > +
> > +       /*
> > +        * Add the hardware descriptor to the chain of hardware descriptors
> > +        * that already exists in memory.
> > +        */
> > +       tail_desc = list_last_entry(&chan->pending_list,
> > +                                   struct xilinx_dma_tx_descriptor, node);
> > +       tail_segment = list_last_entry(&tail_desc->segments,
> > +                                      struct xilinx_dma_tx_segment, node);
> > +       tail_segment->hw.next_desc = (u32)desc->async_tx.phys;
> > +
> > +       /*
> > +        * Add the software descriptor and all children to the list
> > +        * of pending transactions
> > +        */
> > +append:
> > +       list_add_tail(&desc->node, &chan->pending_list);
> > +       chan->desc_pendingcount++;
> > +
> > +       if (unlikely(chan->desc_pendingcount > XILINX_DMA_COALESCE_MAX)) {
> > +               dev_dbg(chan->dev, "desc pendingcount is too high\n");
> > +               chan->desc_pendingcount = XILINX_DMA_COALESCE_MAX;
> > +               BUG();
> > +       }
> > +}
> > +
> > +/**
> > + * xilinx_dma_tx_submit - Submit DMA transaction
> > + * @tx: Async transaction descriptor
> > + *
> > + * Return: cookie value on success and failure value on error  */
> > +static dma_cookie_t xilinx_dma_tx_submit(struct
> > +dma_async_tx_descriptor *tx) {
> > +       struct xilinx_dma_tx_descriptor *desc = to_dma_tx_descriptor(tx);
> > +       struct xilinx_dma_chan *chan = to_xilinx_chan(tx->chan);
> > +       dma_cookie_t cookie;
> > +       unsigned long flags;
> > +       int err;
> > +
> > +       if (chan->err) {
> > +               /*
> > +                * If reset fails, need to hard reset the system.
> > +                * Channel is no longer functional
> > +                */
> > +               err = xilinx_dma_chan_reset(chan);
> > +               if (err < 0)
> > +                       return err;
> > +       }
> > +
> > +       spin_lock_irqsave(&chan->lock, flags);
> > +
> > +       cookie = dma_cookie_assign(tx);
> > +
> > +       /* Put this transaction onto the tail of the pending queue */
> > +       append_desc_queue(chan, desc);
> > +
> > +       spin_unlock_irqrestore(&chan->lock, flags);
> > +
> > +       return cookie;
> > +}
> > +
> > +/**
> > + * xilinx_dma_prep_slave_sg - prepare descriptors for a DMA_SLAVE
> > +transaction
> > + * @dchan: DMA channel
> > + * @sgl: scatterlist to transfer to/from
> > + * @sg_len: number of entries in @scatterlist
> > + * @direction: DMA direction
> > + * @flags: transfer ack flags
> > + * @context: APP words of the descriptor
> > + *
> > + * Return: Async transaction descriptor on success and NULL on
> > +failure  */ static struct dma_async_tx_descriptor
> > +*xilinx_dma_prep_slave_sg(
> > +       struct dma_chan *dchan, struct scatterlist *sgl, unsigned int sg_len,
> > +       enum dma_transfer_direction direction, unsigned long flags,
> > +       void *context)
> > +{
> > +       struct xilinx_dma_chan *chan = to_xilinx_chan(dchan);
> > +       struct xilinx_dma_tx_descriptor *desc;
> > +       struct xilinx_dma_tx_segment *segment;
> > +       u32 *app_w = (u32 *)context;
> > +       struct scatterlist *sg;
> > +       size_t copy, sg_used;
> > +       int i;
> > +
> > +       if (!is_slave_direction(direction))
> > +               return NULL;
> > +
> > +       /* Allocate a transaction descriptor. */
> > +       desc = xilinx_dma_alloc_tx_descriptor(chan);
> > +       if (!desc)
> > +               return NULL;
> > +
> > +       desc->direction = direction;
> > +       dma_async_tx_descriptor_init(&desc->async_tx, &chan->common);
> > +       desc->async_tx.tx_submit = xilinx_dma_tx_submit;
> > +
> > +       /* Build transactions using information in the scatter gather list */
> > +       for_each_sg(sgl, sg, sg_len, i) {
> > +               sg_used = 0;
> > +
> > +               /* Loop until the entire scatterlist entry is used */
> > +               while (sg_used < sg_dma_len(sg)) {
> > +                       struct xilinx_dma_desc_hw *hw;
> > +
> > +                       /* Get a free segment */
> > +                       segment = xilinx_dma_alloc_tx_segment(chan);
> > +                       if (!segment)
> > +                               goto error;
> > +
> > +                       /*
> > +                        * Calculate the maximum number of bytes to transfer,
> > +                        * making sure it is less than the hw limit
> > +                        */
> > +                       copy = min_t(size_t, sg_dma_len(sg) - sg_used,
> > +                                    XILINX_DMA_MAX_TRANS_LEN);
> > +                       hw = &segment->hw;
> > +
> > +                       /* Fill in the descriptor */
> > +                       hw->buf_addr = sg_dma_address(sg) + sg_used;
> > +
> > +                       hw->control = copy;
> > +
> > +                       if (direction == DMA_MEM_TO_DEV) {
> > +                               if (app_w)
> > +                                       memcpy(hw->app, app_w, sizeof(u32) *
> > +                                              XILINX_DMA_NUM_APP_WORDS);
> > +                       }
> > +
> > +                       sg_used += copy;
> > +
> > +                       /*
> > +                        * Insert the segment into the descriptor segments
> > +                        * list.
> > +                        */
> > +                       list_add_tail(&segment->node, &desc->segments);
> > +               }
> > +       }
> > +
> > +       segment = list_first_entry(&desc->segments,
> > +                                  struct xilinx_dma_tx_segment, node);
> > +       desc->async_tx.phys = segment->phys;
> > +
> > +       /* For the last DMA_MEM_TO_DEV transfer, set EOP */
> > +       if (direction == DMA_MEM_TO_DEV) {
> > +               segment->hw.control |= XILINX_DMA_BD_SOP;
> > +               segment = list_last_entry(&desc->segments,
> > +                                         struct xilinx_dma_tx_segment,
> > +                                         node);
> > +               segment->hw.control |= XILINX_DMA_BD_EOP;
> > +       }
> > +
> > +       return &desc->async_tx;
> > +
> > +error:
> > +       xilinx_dma_free_tx_descriptor(chan, desc);
> > +       return NULL;
> > +}
> > +
> > +/**
> > + * xilinx_dma_terminate_all - Halt the channel and free descriptors
> > + * @dchan: DMA Channel pointer
> > + *
> > + * Return: '0' always
> > + */
> > +static int xilinx_dma_terminate_all(struct dma_chan *dchan) {
> > +       struct xilinx_dma_chan *chan = to_xilinx_chan(dchan);
> > +
> > +       /* Halt the DMA engine */
> > +       xilinx_dma_halt(chan);
> > +
> > +       /* Remove and free all of the descriptors in the lists */
> > +       xilinx_dma_free_descriptors(chan);
> > +
> > +       return 0;
> > +}
> > +
> > +/**
> > + * xilinx_dma_chan_remove - Per Channel remove function
> > + * @chan: Driver specific DMA channel  */ static void
> > +xilinx_dma_chan_remove(struct xilinx_dma_chan *chan) {
> > +       /* Disable interrupts */
> > +       chan->ctrl_reg &= ~XILINX_DMA_XR_IRQ_ALL_MASK;
> > +       dma_ctrl_write(chan, XILINX_DMA_REG_CONTROL, chan->ctrl_reg);
> > +
> > +       if (chan->irq > 0)
> > +               free_irq(chan->irq, chan);
> > +
> > +       tasklet_kill(&chan->tasklet);
> > +
> > +       list_del(&chan->common.device_node);
> > +}
> > +
> > +/**
> > + * xilinx_dma_chan_probe - Per Channel Probing
> > + * It get channel features from the device tree entry and
> > + * initialize special channel handling routines
> > + *
> > + * @xdev: Driver specific device structure
> > + * @node: Device node
> > + *
> > + * Return: '0' on success and failure value on error  */ static int
> > +xilinx_dma_chan_probe(struct xilinx_dma_device *xdev,
> > +                                struct device_node *node) {
> > +       struct xilinx_dma_chan *chan;
> > +       int err;
> > +       bool has_dre;
> > +       u32 value, width = 0;
> > +
> > +       /* alloc channel */
> > +       chan = devm_kzalloc(xdev->dev, sizeof(*chan), GFP_KERNEL);
> > +       if (!chan)
> > +               return -ENOMEM;
> > +
> > +       chan->dev = xdev->dev;
> > +       chan->xdev = xdev;
> > +       chan->has_sg = xdev->has_sg;
> > +       chan->desc_pendingcount = 0x0;
> > +
> > +       has_dre = of_property_read_bool(node, "xlnx,include-dre");
> > +
> > +       err = of_property_read_u32(node, "xlnx,datawidth", &value);
> > +       if (err) {
> > +               dev_err(xdev->dev, "unable to read datawidth property");
> > +               return err;
> > +       }
> > +
> > +       width = value >> 3; /* Convert bits to bytes */
> > +
> > +       /* If data width is greater than 8 bytes, DRE is not in hw */
> > +       if (width > 8)
> > +               has_dre = false;
> > +
> > +       if (!has_dre)
> > +               xdev->common.copy_align = fls(width - 1);
> > +
> > +       if (of_device_is_compatible(node, "xlnx,axi-dma-mm2s-channel")) {
> > +               chan->id = 0;
> > +               chan->ctrl_offset = XILINX_DMA_MM2S_CTRL_OFFSET;
> > +       } else if (of_device_is_compatible(node, "xlnx,axi-dma-s2mm-channel")) {
> > +               chan->id = 1;
> > +               chan->ctrl_offset = XILINX_DMA_S2MM_CTRL_OFFSET;
> > +       } else {
> > +               dev_err(xdev->dev, "Invalid channel compatible node\n");
> > +               return -EINVAL;
> > +       }
> > +
> > +       xdev->chan[chan->id] = chan;
> > +
> > +       /* Initialize the channel */
> > +       err = xilinx_dma_chan_reset(chan);
> > +       if (err) {
> > +               dev_err(xdev->dev, "Reset channel failed\n");
> > +               return err;
> > +       }
> > +
> > +       spin_lock_init(&chan->lock);
> > +       INIT_LIST_HEAD(&chan->pending_list);
> > +       INIT_LIST_HEAD(&chan->done_list);
> > +       INIT_LIST_HEAD(&chan->active_list);
> > +       INIT_LIST_HEAD(&chan->free_seg_list);
> > +
> > +       chan->common.device = &xdev->common;
> > +
> > +       /* find the IRQ line, if it exists in the device tree */
> > +       chan->irq = irq_of_parse_and_map(node, 0);
> > +       err = request_irq(chan->irq, xilinx_dma_irq_handler,
> > +                         IRQF_SHARED,
> > +                         "xilinx-dma-controller", chan);
> > +       if (err) {
> > +               dev_err(xdev->dev, "unable to request IRQ %d\n", chan->irq);
> > +               return err;
> > +       }
> > +
> > +       /* Initialize the tasklet */
> > +       tasklet_init(&chan->tasklet, xilinx_dma_do_tasklet,
> > +                    (unsigned long)chan);
> > +
> > +       /* Add the channel to DMA device channel list */
> > +       list_add_tail(&chan->common.device_node,
> > + &xdev->common.channels);
> > +
> > +       chan->idle = true;
> > +
> > +       return 0;
> > +}
> > +
> > +/**
> > + * of_dma_xilinx_xlate - Translation function
> > + * @dma_spec: Pointer to DMA specifier as found in the device tree
> > + * @ofdma: Pointer to DMA controller data
> > + *
> > + * Return: DMA channel pointer on success and NULL on error  */
> > +static struct dma_chan *of_dma_xilinx_xlate(struct of_phandle_args
> *dma_spec,
> > +                                           struct of_dma *ofdma) {
> > +       struct xilinx_dma_device *xdev = ofdma->of_dma_data;
> > +       int chan_id = dma_spec->args[0];
> > +
> > +       if (chan_id >= XILINX_DMA_MAX_CHANS_PER_DEVICE)
> > +               return NULL;
> > +
> > +       return dma_get_slave_channel(&xdev->chan[chan_id]->common);
> > +}
> > +
> > +/**
> > + * xilinx_dma_probe - Driver probe function
> > + * @pdev: Pointer to the platform_device structure
> > + *
> > + * Return: '0' on success and failure value on error  */ static int
> > +xilinx_dma_probe(struct platform_device *pdev) {
> > +       struct xilinx_dma_device *xdev;
> > +       struct device_node *child, *node;
> > +       struct resource *res;
> > +       int i, ret;
> > +
> > +       xdev = devm_kzalloc(&pdev->dev, sizeof(*xdev), GFP_KERNEL);
> > +       if (!xdev)
> > +               return -ENOMEM;
> > +
> > +       xdev->dev = &(pdev->dev);
> > +       INIT_LIST_HEAD(&xdev->common.channels);
> > +
> > +       node = pdev->dev.of_node;
> > +
> > +       /* Map the registers */
> > +       res = platform_get_resource(pdev, IORESOURCE_MEM, 0);
> > +       xdev->regs = devm_ioremap_resource(&pdev->dev, res);
> > +       if (IS_ERR(xdev->regs))
> > +               return PTR_ERR(xdev->regs);
> > +
> > +       /* Check if SG is enabled */
> > +       xdev->has_sg = of_property_read_bool(node, "xlnx,include-sg");
> > +
> > +       /* Axi DMA only do slave transfers */
> > +       dma_cap_set(DMA_SLAVE, xdev->common.cap_mask);
> > +       dma_cap_set(DMA_PRIVATE, xdev->common.cap_mask);
> > +       xdev->common.device_prep_slave_sg = xilinx_dma_prep_slave_sg;
> > +       xdev->common.device_terminate_all = xilinx_dma_terminate_all;
> > +       xdev->common.device_issue_pending = xilinx_dma_issue_pending;
> > +       xdev->common.device_alloc_chan_resources =
> > +               xilinx_dma_alloc_chan_resources;
> > +       xdev->common.device_free_chan_resources =
> > +               xilinx_dma_free_chan_resources;
> > +       xdev->common.device_tx_status = xilinx_dma_tx_status;
> > +       xdev->common.directions = BIT(DMA_DEV_TO_MEM) |
> BIT(DMA_MEM_TO_DEV);
> > +       xdev->common.residue_granularity =
> DMA_RESIDUE_GRANULARITY_SEGMENT;
> > +       xdev->common.dev = &pdev->dev;
> > +
> > +       platform_set_drvdata(pdev, xdev);
> > +
> > +       for_each_child_of_node(node, child) {
> > +               ret = xilinx_dma_chan_probe(xdev, child);
> > +               if (ret) {
> > +                       dev_err(&pdev->dev, "Probing channels failed\n");
> > +                       goto free_chan_resources;
> > +               }
> > +       }
> > +
> > +       dma_async_device_register(&xdev->common);
> > +
> > +       ret = of_dma_controller_register(node, of_dma_xilinx_xlate, xdev);
> > +       if (ret) {
> > +               dev_err(&pdev->dev, "Unable to register DMA to DT\n");
> > +               dma_async_device_unregister(&xdev->common);
> > +               goto free_chan_resources;
> > +       }
> > +
> > +       dev_info(&pdev->dev, "Xilinx AXI DMA Engine driver
> > + Probed!!\n");
> > +
> > +       return 0;
> > +
> > +free_chan_resources:
> > +       for (i = 0; i < XILINX_DMA_MAX_CHANS_PER_DEVICE; i++)
> > +               if (xdev->chan[i])
> > +                       xilinx_dma_chan_remove(xdev->chan[i]);
> > +
> > +       return ret;
> > +}
> > +
> > +/**
> > + * xilinx_dma_remove - Driver remove function
> > + * @pdev: Pointer to the platform_device structure
> > + *
> > + * Return: Always '0'
> > + */
> > +static int xilinx_dma_remove(struct platform_device *pdev) {
> > +       struct xilinx_dma_device *xdev = platform_get_drvdata(pdev);
> > +       int i;
> > +
> > +       of_dma_controller_free(pdev->dev.of_node);
> > +       dma_async_device_unregister(&xdev->common);
> > +
> > +       for (i = 0; i < XILINX_DMA_MAX_CHANS_PER_DEVICE; i++)
> > +               if (xdev->chan[i])
> > +                       xilinx_dma_chan_remove(xdev->chan[i]);
> > +
> > +       return 0;
> > +}
> > +
> > +static const struct of_device_id xilinx_dma_of_match[] = {
> > +       { .compatible = "xlnx,axi-dma-1.00.a",},
> > +       {}
> > +};
> > +MODULE_DEVICE_TABLE(of, xilinx_dma_of_match);
> > +
> > +static struct platform_driver xilinx_dma_driver = {
> > +       .driver = {
> > +               .name = "xilinx-dma",
> > +               .of_match_table = xilinx_dma_of_match,
> > +       },
> > +       .probe = xilinx_dma_probe,
> > +       .remove = xilinx_dma_remove,
> > +};
> > +
> > +module_platform_driver(xilinx_dma_driver);
> > +
> > +MODULE_AUTHOR("Xilinx, Inc.");
> > +MODULE_DESCRIPTION("Xilinx DMA driver"); MODULE_LICENSE("GPL");
> > --
> > 2.1.2
> >
> >
> > _______________________________________________
> > linux-arm-kernel mailing list
> > linux-arm-kernel at lists.infradead.org
> > http://lists.infradead.org/mailman/listinfo/linux-arm-kernel
> 
> Cheers,
> 
> Moritz

From vinod.koul at intel.com  Wed Aug 19 22:48:28 2015
From: vinod.koul at intel.com (Vinod Koul)
Date: Thu, 20 Aug 2015 11:18:28 +0530
Subject: [PATCH v1 3/4] Crypto: Add support for APM X-Gene SoC CRC32C h/w
 accelerator driver
In-Reply-To: <1438258268-3099-4-git-send-email-rsahu@apm.com>
References: <1438258268-3099-1-git-send-email-rsahu@apm.com>
 <1438258268-3099-4-git-send-email-rsahu@apm.com>
Message-ID: <20150820054828.GY13546@localhost>

On Thu, Jul 30, 2015 at 05:41:07PM +0530, Rameshwar Prasad Sahu wrote:
> +	nents = sg_nents(req->src);
> +	sg_count = dma_map_sg(dev, req->src, nents, DMA_TO_DEVICE);
> +	if (!sg_count) {
> +		dev_err(dev, "Failed to map src sg");
> +		return -ENOMEM;
mapping error shouldn't be no mem error

> +	}
> +
> +	if (sg_count > XGENE_DMA_MAX_FLYBY_SRC_CNT) {
> +		dev_err(dev, "Unsupported src sg len\n");
would be worth printing length

> +		goto err;
> +	}
> +
> +	flags = DMA_CTRL_ACK;
why ACK?

> +
> +	tx = dchan->device->device_prep_dma_crc32c(dchan, req->src,
> +						   req->nbytes,
> +						   reqctx->seed,
> +						   req->result,
> +						   flags);
We should add helper for this

-- 
~Vinod



From xuyiping at hisilicon.com  Wed Aug 19 22:42:58 2015
From: xuyiping at hisilicon.com (YiPing Xu)
Date: Thu, 20 Aug 2015 13:42:58 +0800
Subject: [PATCH v2 2/3] mailbox: Hi6220: add mailbox driver
In-Reply-To: <1440039239-8772-3-git-send-email-leo.yan@linaro.org>
References: <1440039239-8772-1-git-send-email-leo.yan@linaro.org>
 <1440039239-8772-3-git-send-email-leo.yan@linaro.org>
Message-ID: <55D568E2.9060505@hisilicon.com>

On 2015/8/20 10:53, Leo Yan wrote:
> Add driver for Hi6220 mailbox, the mailbox communicates with MCU; for
> sending data, it can support two methods for low level implementation:
> one is to use interrupt as acknowledge, another is automatic mode which
> without any acknowledge. These two methods have been supported in the
> driver. For receiving data, it will depend on the interrupt to notify
> the channel has incoming message; enhance rx channel's message queue,
> which is based on the code in drivers/mailbox/omap-mailbox.c.
>
> Now mailbox driver is used to send message to MCU to control dynamic
> voltage and frequency scaling for CPU, GPU and DDR.
>
> Signed-off-by: Leo Yan <leo.yan at linaro.org>
> ---
>   drivers/mailbox/Kconfig          |   8 +
>   drivers/mailbox/Makefile         |   2 +
>   drivers/mailbox/hi6220-mailbox.c | 519 +++++++++++++++++++++++++++++++++++++++
>   3 files changed, 529 insertions(+)
>   create mode 100644 drivers/mailbox/hi6220-mailbox.c
>
> diff --git a/drivers/mailbox/Kconfig b/drivers/mailbox/Kconfig
> index e269f08..21b71dd 100644
> --- a/drivers/mailbox/Kconfig
> +++ b/drivers/mailbox/Kconfig
> @@ -70,4 +70,12 @@ config BCM2835_MBOX
>   	  the services of the Videocore. Say Y here if you want to use the
>   	  BCM2835 Mailbox.
>
> +config HI6220_MBOX
> +	tristate "Hi6220 Mailbox"
> +	depends on ARCH_HISI
> +	help
> +	  An implementation of the hi6220 mailbox. It is used to send message
> +	  between application processors and MCU. Say Y here if you want to build
> +	  the Hi6220 mailbox controller driver.
> +
>   endif
> diff --git a/drivers/mailbox/Makefile b/drivers/mailbox/Makefile
> index 8e6d822..4ba9f5f 100644
> --- a/drivers/mailbox/Makefile
> +++ b/drivers/mailbox/Makefile
> @@ -13,3 +13,5 @@ obj-$(CONFIG_PCC)		+= pcc.o
>   obj-$(CONFIG_ALTERA_MBOX)	+= mailbox-altera.o
>
>   obj-$(CONFIG_BCM2835_MBOX)	+= bcm2835-mailbox.o
> +
> +obj-$(CONFIG_HI6220_MBOX)	+= hi6220-mailbox.o
> diff --git a/drivers/mailbox/hi6220-mailbox.c b/drivers/mailbox/hi6220-mailbox.c
> new file mode 100644
> index 0000000..8f63d0d
> --- /dev/null
> +++ b/drivers/mailbox/hi6220-mailbox.c
> @@ -0,0 +1,519 @@
> +/*
> + * Hisilicon's Hi6220 mailbox driver
> + *
> + * RX channel's message queue is based on the code written in
> + * drivers/mailbox/omap-mailbox.c.
> + *
> + * Copyright (c) 2015 Hisilicon Limited.
> + * Copyright (c) 2015 Linaro Limited.
> + *
> + * Author: Leo Yan <leo.yan at linaro.org>
> + *
> + * This program is free software: you can redistribute it and/or modify
> + * it under the terms of the GNU General Public License as published by
> + * the Free Software Foundation, version 2 of the License.
> + *
> + * 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/device.h>
> +#include <linux/err.h>
> +#include <linux/interrupt.h>
> +#include <linux/io.h>
> +#include <linux/kfifo.h>
> +#include <linux/mailbox_controller.h>
> +#include <linux/module.h>
> +#include <linux/platform_device.h>
> +#include <linux/spinlock.h>
> +#include <linux/slab.h>
> +
> +#define HI6220_MBOX_CHAN_MAX		32
> +#define HI6220_MBOX_CHAN_NUM		2
> +#define HI6220_MBOX_CHAN_SLOT_SIZE	64
> +
> +#define HI6220_MBOX_RX			0x0
> +#define HI6220_MBOX_TX			0x1
> +
> +/* Mailbox message length: 32 bytes */
> +#define HI6220_MBOX_MSG_LEN		32
> +
> +/* Mailbox kfifo size */
> +#define HI6220_MBOX_MSG_FIFO_SIZE	512
> +
> +/* Status & Mode Register */
> +#define HI6220_MBOX_MODE_REG		0x0
> +
> +#define HI6220_MBOX_STATUS_MASK		(0xF << 4)
> +#define HI6220_MBOX_STATUS_IDLE		(0x1 << 4)
> +#define HI6220_MBOX_STATUS_TX		(0x2 << 4)
> +#define HI6220_MBOX_STATUS_RX		(0x4 << 4)
> +#define HI6220_MBOX_STATUS_ACK		(0x8 << 4)
> +#define HI6220_MBOX_ACK_CONFIG_MASK	(0x1 << 0)
> +#define HI6220_MBOX_ACK_AUTOMATIC	(0x1 << 0)
> +#define HI6220_MBOX_ACK_IRQ		(0x0 << 0)
> +
> +/* Data Registers */
> +#define HI6220_MBOX_DATA_REG(i)		(0x4 + (i << 2))
> +
> +/* ACPU Interrupt Register */
> +#define HI6220_MBOX_ACPU_INT_RAW_REG	0x400
> +#define HI6220_MBOX_ACPU_INT_MSK_REG	0x404
> +#define HI6220_MBOX_ACPU_INT_STAT_REG	0x408
> +#define HI6220_MBOX_ACPU_INT_CLR_REG	0x40c
> +#define HI6220_MBOX_ACPU_INT_ENA_REG	0x500
> +#define HI6220_MBOX_ACPU_INT_DIS_REG	0x504
> +
> +/* MCU Interrupt Register */
> +#define HI6220_MBOX_MCU_INT_RAW_REG	0x420
> +
> +/* Core Id */
> +#define HI6220_CORE_ACPU		0x0
> +#define HI6220_CORE_MCU			0x2
> +
> +struct hi6220_mbox_queue {
> +	struct kfifo fifo;
> +	struct work_struct work;
> +	struct mbox_chan *chan;
> +	bool full;
> +};
> +
> +struct hi6220_mbox_chan {
> +
> +	/*
> +	 * Description for channel's hardware info:
> +	 *  - direction;
> +	 *  - peer core id for communication;
> +	 *  - local irq vector or number;
> +	 *  - remoted irq vector or number for peer core;
> +	 */
> +	unsigned int dir;
> +	unsigned int peer_core;
> +	unsigned int remote_irq;
> +	unsigned int local_irq;
> +
> +	/*
> +	 * Slot address is cached value derived from index
> +	 * within buffer for every channel
> +	 */
> +	void __iomem *slot;
> +
> +	/* For rx's fifo operations */
> +	struct hi6220_mbox_queue *mq;
> +
> +	struct hi6220_mbox *parent;
> +};
> +
> +struct hi6220_mbox {
> +	struct device *dev;
> +
> +	spinlock_t lock;
> +
> +	int irq;
> +
> +	/* flag of enabling tx's irq mode */
> +	bool tx_irq_mode;
> +
> +	/* region for ipc event */
> +	void __iomem *ipc;
> +
> +	/* region for share mem */
> +	void __iomem *buf;
> +
> +	unsigned int chan_num;
> +	struct hi6220_mbox_chan *mchan;
> +
> +	void *irq_map_chan[HI6220_MBOX_CHAN_MAX];
> +	struct mbox_chan *chan;
> +	struct mbox_controller controller;
> +};
> +
> +static void hi6220_mbox_set_status(struct hi6220_mbox_chan *mchan, u32 val)
> +{
> +	u32 status;
> +
> +	status = readl(mchan->slot + HI6220_MBOX_MODE_REG);
> +	status &= ~HI6220_MBOX_STATUS_MASK;
> +	status |= val;
> +	writel(status, mchan->slot + HI6220_MBOX_MODE_REG);
> +}
> +
> +static void hi6220_mbox_set_mode(struct hi6220_mbox_chan *mchan, u32 val)
> +{
> +	u32 mode;
> +
> +	mode = readl(mchan->slot + HI6220_MBOX_MODE_REG);
> +	mode &= ~HI6220_MBOX_ACK_CONFIG_MASK;
> +	mode |= val;
> +	writel(mode, mchan->slot + HI6220_MBOX_MODE_REG);
> +}
> +
> +static bool hi6220_mbox_last_tx_done(struct mbox_chan *chan)
> +{
> +	struct hi6220_mbox_chan *mchan = chan->con_priv;
> +	struct hi6220_mbox *mbox = mchan->parent;
> +	u32 status;
> +
> +	/* Only set idle state for polling mode */
> +	BUG_ON(mbox->tx_irq_mode);
> +
> +	status = readl(mchan->slot + HI6220_MBOX_MODE_REG);
> +	status = status & HI6220_MBOX_STATUS_MASK;
> +	return (status == HI6220_MBOX_STATUS_IDLE);
> +}
> +
> +static int hi6220_mbox_send_data(struct mbox_chan *chan, void *msg)
> +{
> +	struct hi6220_mbox_chan *mchan = chan->con_priv;
> +	struct hi6220_mbox *mbox = mchan->parent;
> +	int irq = mchan->remote_irq;
> +	u32 *buf = msg;
> +	unsigned long flags;
> +	int i;
> +
> +	hi6220_mbox_set_status(mchan, HI6220_MBOX_STATUS_TX);

	hi6220_mbox_set_status is called in send_data context, and it is also 
called in hi6220_mbox_rx_interrupt and hi6220_mbox_tx_interrupt.

	no race condition here?

> +	if (mbox->tx_irq_mode)
> +		hi6220_mbox_set_mode(mchan, HI6220_MBOX_ACK_IRQ);
> +	else
> +		hi6220_mbox_set_mode(mchan, HI6220_MBOX_ACK_AUTOMATIC);
> +
> +	for (i = 0; i < (HI6220_MBOX_MSG_LEN >> 2); i++)
> +		writel(buf[i], mchan->slot + HI6220_MBOX_DATA_REG(i));
> +
> +	/* trigger remote request */
> +	spin_lock_irqsave(&mbox->lock, flags);
> +	writel(1 << irq, mbox->ipc + HI6220_MBOX_MCU_INT_RAW_REG);
> +	spin_unlock_irqrestore(&mbox->lock, flags);
> +	return 0;
> +}
> +
> +static void hi6220_mbox_rx_work(struct work_struct *work)
> +{
> +	struct hi6220_mbox_queue *mq =
> +			container_of(work, struct hi6220_mbox_queue, work);
> +	struct mbox_chan *chan = mq->chan;
> +	struct hi6220_mbox_chan *mchan = chan->con_priv;
> +	struct hi6220_mbox *mbox = mchan->parent;
> +	int irq = mchan->local_irq, len;
> +	u32 msg[HI6220_MBOX_MSG_LEN >> 2];
> +
> +	while (kfifo_len(&mq->fifo) >= sizeof(msg)) {
> +		len = kfifo_out(&mq->fifo, (unsigned char *)&msg, sizeof(msg));
> +		WARN_ON(len != sizeof(msg));
> +
> +		mbox_chan_received_data(chan, (void *)msg);
> +		spin_lock_irq(&mbox->lock);
> +		if (mq->full) {
> +			mq->full = false;
> +			writel(1 << irq,
> +				mbox->ipc + HI6220_MBOX_ACPU_INT_ENA_REG);
> +		}
> +		spin_unlock_irq(&mbox->lock);
> +	}
> +}
> +
> +static void hi6220_mbox_tx_interrupt(struct mbox_chan *chan)
> +{
> +	struct hi6220_mbox_chan *mchan = chan->con_priv;
> +	struct hi6220_mbox *mbox = mchan->parent;
> +	int irq = mchan->local_irq;
> +
> +	spin_lock(&mbox->lock);
> +	writel(1 << irq, mbox->ipc + HI6220_MBOX_ACPU_INT_CLR_REG);
> +	spin_unlock(&mbox->lock);
> +
> +	hi6220_mbox_set_status(mchan, HI6220_MBOX_STATUS_IDLE);
> +	mbox_chan_txdone(chan, 0);
> +}
> +
> +static void hi6220_mbox_rx_interrupt(struct mbox_chan *chan)
> +{
> +	struct hi6220_mbox_chan *mchan = chan->con_priv;
> +	struct hi6220_mbox_queue *mq = mchan->mq;
> +	struct hi6220_mbox *mbox = mchan->parent;
> +	int irq = mchan->local_irq;
> +	int msg[HI6220_MBOX_MSG_LEN >> 2];
> +	int i, len;
> +
> +	if (unlikely(kfifo_avail(&mq->fifo) < sizeof(msg))) {
> +		spin_lock(&mbox->lock);
> +		writel(1 << irq, mbox->ipc + HI6220_MBOX_ACPU_INT_DIS_REG);
> +		mq->full = true;
> +		spin_unlock(&mbox->lock);
> +		goto nomem;
> +	}
> +
> +	for (i = 0; i < (HI6220_MBOX_MSG_LEN >> 2); i++)
> +		msg[i] = readl(mchan->slot + HI6220_MBOX_DATA_REG(i));
> +
> +	/* clear IRQ source */
> +	spin_lock(&mbox->lock);
> +	writel(1 << irq, mbox->ipc + HI6220_MBOX_ACPU_INT_CLR_REG);
> +	spin_unlock(&mbox->lock);
> +
> +	hi6220_mbox_set_status(mchan, HI6220_MBOX_STATUS_IDLE);
> +
> +	len = kfifo_in(&mq->fifo, (unsigned char *)&msg, sizeof(msg));
> +	WARN_ON(len != sizeof(msg));
> +
> +nomem:
> +	schedule_work(&mq->work);
> +}
> +
> +static irqreturn_t hi6220_mbox_interrupt(int irq, void *p)
> +{
> +	struct hi6220_mbox *mbox = p;
> +	struct hi6220_mbox_chan *mchan;
> +	struct mbox_chan *chan;
> +	unsigned int state;
> +	unsigned int intr_bit;
> +
> +	state = readl(mbox->ipc + HI6220_MBOX_ACPU_INT_STAT_REG);
> +	if (!state) {
> +		dev_warn(mbox->dev, "%s: spurious interrupt\n",
> +			 __func__);
> +		return IRQ_HANDLED;
> +	}
> +
> +	while (state) {
> +		intr_bit = __ffs(state);
> +		state &= (state - 1);
> +
> +		chan = mbox->irq_map_chan[intr_bit];
> +		if (!chan) {
> +			dev_warn(mbox->dev, "%s: unexpected irq vector %d\n",
> +				 __func__, intr_bit);
> +			continue;
> +		}
> +
> +		mchan = chan->con_priv;
> +		if (mchan->dir == HI6220_MBOX_TX)
> +			hi6220_mbox_tx_interrupt(chan);
> +		else
> +			hi6220_mbox_rx_interrupt(chan);
> +	}
> +
> +	return IRQ_HANDLED;
> +}
> +
> +static struct hi6220_mbox_queue *hi6220_mbox_queue_alloc(
> +		struct mbox_chan *chan,
> +		void (*work)(struct work_struct *))
> +{
> +	struct hi6220_mbox_queue *mq;
> +
> +	mq = kzalloc(sizeof(struct hi6220_mbox_queue), GFP_KERNEL);
> +	if (!mq)
> +		return NULL;
> +
> +	if (kfifo_alloc(&mq->fifo, HI6220_MBOX_MSG_FIFO_SIZE, GFP_KERNEL))
> +		goto error;
> +
> +	mq->chan = chan;
> +	INIT_WORK(&mq->work, work);
> +	return mq;
> +
> +error:
> +	kfree(mq);
> +	return NULL;
> +}
> +
> +static void hi6220_mbox_queue_free(struct hi6220_mbox_queue *mq)
> +{
> +	kfifo_free(&mq->fifo);
> +	kfree(mq);
> +}
> +
> +static int hi6220_mbox_startup(struct mbox_chan *chan)
> +{
> +	struct hi6220_mbox_chan *mchan = chan->con_priv;
> +	struct hi6220_mbox *mbox = mchan->parent;
> +	unsigned int irq = mchan->local_irq;
> +	struct hi6220_mbox_queue *mq;
> +	unsigned long flags;
> +
> +	mq = hi6220_mbox_queue_alloc(chan, hi6220_mbox_rx_work);
> +	if (!mq)
> +		return -ENOMEM;
> +	mchan->mq = mq;
> +	mbox->irq_map_chan[irq] = (void *)chan;
> +
> +	/* enable interrupt */
> +	spin_lock_irqsave(&mbox->lock, flags);
> +	writel(1 << irq, mbox->ipc + HI6220_MBOX_ACPU_INT_ENA_REG);
> +	spin_unlock_irqrestore(&mbox->lock, flags);
> +	return 0;
> +}
> +
> +static void hi6220_mbox_shutdown(struct mbox_chan *chan)
> +{
> +	struct hi6220_mbox_chan *mchan = chan->con_priv;
> +	struct hi6220_mbox *mbox = mchan->parent;
> +	unsigned int irq = mchan->local_irq;
> +	unsigned long flags;
> +
> +	/* disable interrupt */
> +	spin_lock_irqsave(&mbox->lock, flags);
> +	writel(1 << irq, mbox->ipc + HI6220_MBOX_ACPU_INT_DIS_REG);
> +	spin_unlock_irqrestore(&mbox->lock, flags);
> +
> +	mbox->irq_map_chan[irq] = NULL;
> +	flush_work(&mchan->mq->work);
> +	hi6220_mbox_queue_free(mchan->mq);
> +}
> +
> +static struct mbox_chan_ops hi6220_mbox_chan_ops = {
> +	.send_data    = hi6220_mbox_send_data,
> +	.startup      = hi6220_mbox_startup,
> +	.shutdown     = hi6220_mbox_shutdown,
> +	.last_tx_done = hi6220_mbox_last_tx_done,
> +};
> +
> +static void hi6220_mbox_init_hw(struct hi6220_mbox *mbox)
> +{
> +	struct hi6220_mbox_chan init_data[HI6220_MBOX_CHAN_NUM] = {
> +		{ HI6220_MBOX_RX, HI6220_CORE_MCU, 1, 10 },
> +		{ HI6220_MBOX_TX, HI6220_CORE_MCU, 0, 11 },
> +	};
> +	struct hi6220_mbox_chan *mchan = mbox->mchan;
> +	int i;
> +
> +	for (i = 0; i < HI6220_MBOX_CHAN_NUM; i++) {
> +		memcpy(&mchan[i], &init_data[i], sizeof(*mchan));
> +		mchan[i].slot = mbox->buf + HI6220_MBOX_CHAN_SLOT_SIZE * i;
> +		mchan[i].parent = mbox;
> +	}
> +
> +	/* mask and clear all interrupt vectors */
> +	writel(0x0,  mbox->ipc + HI6220_MBOX_ACPU_INT_MSK_REG);
> +	writel(~0x0, mbox->ipc + HI6220_MBOX_ACPU_INT_CLR_REG);
> +
> +	/* use interrupt for tx's ack */
> +	mbox->tx_irq_mode = true;
> +}
> +
> +static const struct of_device_id hi6220_mbox_of_match[] = {
> +	{ .compatible = "hisilicon,hi6220-mbox", },
> +	{},
> +};
> +MODULE_DEVICE_TABLE(of, hi6220_mbox_of_match);
> +
> +static int hi6220_mbox_probe(struct platform_device *pdev)
> +{
> +	struct device *dev = &pdev->dev;
> +	struct hi6220_mbox *mbox;
> +	struct resource *res;
> +	int i, err;
> +
> +	mbox = devm_kzalloc(dev, sizeof(*mbox), GFP_KERNEL);
> +	if (!mbox)
> +		return -ENOMEM;
> +
> +	mbox->dev = dev;
> +	mbox->chan_num = HI6220_MBOX_CHAN_NUM;
> +	mbox->mchan = devm_kzalloc(dev,
> +		mbox->chan_num * sizeof(*mbox->mchan), GFP_KERNEL);
> +	if (!mbox->mchan)
> +		return -ENOMEM;
> +
> +	mbox->chan = devm_kzalloc(dev,
> +		mbox->chan_num * sizeof(*mbox->chan), GFP_KERNEL);
> +	if (!mbox->chan)
> +		return -ENOMEM;
> +
> +	mbox->irq = platform_get_irq(pdev, 0);
> +	if (mbox->irq < 0)
> +		return mbox->irq;
> +
> +	res = platform_get_resource(pdev, IORESOURCE_MEM, 0);
> +	mbox->ipc = devm_ioremap_resource(dev, res);
> +	if (IS_ERR(mbox->ipc)) {
> +		dev_err(dev, "ioremap ipc failed\n");
> +		return PTR_ERR(mbox->ipc);
> +	}
> +
> +	res = platform_get_resource(pdev, IORESOURCE_MEM, 1);
> +	mbox->buf = devm_ioremap_resource(dev, res);
> +	if (IS_ERR(mbox->buf)) {
> +		dev_err(dev, "ioremap buffer failed\n");
> +		return PTR_ERR(mbox->buf);
> +	}
> +
> +	err = devm_request_irq(dev, mbox->irq, hi6220_mbox_interrupt, 0,
> +			dev_name(dev), mbox);
> +	if (err) {
> +		dev_err(dev, "Failed to register a mailbox IRQ handler: %d\n",
> +			err);
> +		return -ENODEV;
> +	}
> +
> +	/* init hardware parameters */
> +	hi6220_mbox_init_hw(mbox);
> +
> +	spin_lock_init(&mbox->lock);
> +
> +	for (i = 0; i < mbox->chan_num; i++) {
> +		mbox->chan[i].con_priv = &mbox->mchan[i];
> +		mbox->irq_map_chan[i] = NULL;
> +	}
> +
> +	mbox->controller.dev = dev;
> +	mbox->controller.chans = &mbox->chan[0];
> +	mbox->controller.num_chans = mbox->chan_num;
> +	mbox->controller.ops = &hi6220_mbox_chan_ops;
> +
> +	if (mbox->tx_irq_mode)
> +		mbox->controller.txdone_irq = true;
> +	else {
> +		mbox->controller.txdone_poll = true;
> +		mbox->controller.txpoll_period = 5;
> +	}
> +
> +	err = mbox_controller_register(&mbox->controller);
> +	if (err) {
> +		dev_err(dev, "Failed to register mailbox %d\n", err);
> +		return err;
> +	}
> +
> +	platform_set_drvdata(pdev, mbox);
> +	dev_info(dev, "Mailbox enabled\n");
> +	return 0;
> +}
> +
> +static int hi6220_mbox_remove(struct platform_device *pdev)
> +{
> +	struct hi6220_mbox *mbox = platform_get_drvdata(pdev);
> +
> +	mbox_controller_unregister(&mbox->controller);
> +	return 0;
> +}
> +
> +static struct platform_driver hi6220_mbox_driver = {
> +	.driver = {
> +		.name = "hi6220-mbox",
> +		.owner = THIS_MODULE,
> +		.of_match_table = hi6220_mbox_of_match,
> +	},
> +	.probe	= hi6220_mbox_probe,
> +	.remove	= hi6220_mbox_remove,
> +};
> +
> +static int __init hi6220_mbox_init(void)
> +{
> +	return platform_driver_register(&hi6220_mbox_driver);
> +}
> +core_initcall(hi6220_mbox_init);
> +
> +static void __exit hi6220_mbox_exit(void)
> +{
> +	platform_driver_unregister(&hi6220_mbox_driver);
> +}
> +module_exit(hi6220_mbox_exit);
> +
> +MODULE_AUTHOR("Leo Yan <leo.yan at linaro.org>");
> +MODULE_DESCRIPTION("Hi6220 mailbox driver");
> +MODULE_LICENSE("GPL v2");
>




From vinod.koul at intel.com  Wed Aug 19 22:52:55 2015
From: vinod.koul at intel.com (Vinod Koul)
Date: Thu, 20 Aug 2015 11:22:55 +0530
Subject: [PATCH v4 1/2] Documentation: dt: Add Xilinx zynqmp dma device
 tree binding documentation
In-Reply-To: <1438831173-8761-1-git-send-email-punnaia@xilinx.com>
References: <1438831173-8761-1-git-send-email-punnaia@xilinx.com>
Message-ID: <20150820055255.GZ13546@localhost>

On Thu, Aug 06, 2015 at 08:49:32AM +0530, Punnaiah Choudary Kalluri wrote:
> Device-tree binding documentation for Xilinx zynqmp dma engine used in
> Zynq UltraScale+ MPSoC.
> 
> Signed-off-by: Punnaiah Choudary Kalluri <punnaia at xilinx.com>
> ---
> Changes in v4:
> - None
> Changes in v3:
> - None
> Changes in v2:
> - None
> ---
>  .../devicetree/bindings/dma/xilinx/zynqmp_dma.txt  |   61 ++++++++++++++++++++
>  1 files changed, 61 insertions(+), 0 deletions(-)
>  create mode 100644 Documentation/devicetree/bindings/dma/xilinx/zynqmp_dma.txt
> 
> diff --git a/Documentation/devicetree/bindings/dma/xilinx/zynqmp_dma.txt b/Documentation/devicetree/bindings/dma/xilinx/zynqmp_dma.txt
> new file mode 100644
> index 0000000..e4f92b9
> --- /dev/null
> +++ b/Documentation/devicetree/bindings/dma/xilinx/zynqmp_dma.txt
> @@ -0,0 +1,61 @@
> +Xilinx ZynqMP DMA engine, it does support memory to memory transfers,
> +memory to device and device to memory transfers. It also has flow
> +control and rate control support for slave/peripheral dma access.
> +
> +Required properties:
> +- compatible: Should be "xlnx,zynqmp-dma-1.0"
> +- #dma-cells: Should be <1>, a single cell holding a line request number
> +- reg: Memory map for module access
> +- interrupt-parent: Interrupt controller the interrupt is routed through
> +- interrupts: Should contain DMA channel interrupt
channel interrupt or interrupts, former says it is plural

-- 
~Vinod



From jingoohan1 at gmail.com  Wed Aug 19 22:54:22 2015
From: jingoohan1 at gmail.com (Jingoo Han)
Date: Thu, 20 Aug 2015 14:54:22 +0900
Subject: [PATCH v3 0/14] Add Analogix Core Display Port Driver
In-Reply-To: <55D557BD.8070004@codeaurora.org>
References: <1439995728-18046-1-git-send-email-ykk@rock-chips.com>
 <55D557BD.8070004@codeaurora.org>
Message-ID: <58DB3289-29F0-4C2D-97F6-EB0555392DF2@gmail.com>

On 2015. 8. 20., at PM 1:29, Archit Taneja <architt at codeaurora.org> wrote:
> 
> Hi,
> 
>> On 08/19/2015 08:18 PM, Yakir Yang wrote:
>> 
>> Hi all,
>>    The Samsung Exynos eDP controller and Rockchip RK3288 eDP controller
>> share the same IP, so a lot of parts can be re-used. I split the common
>> code into bridge directory, then rk3288 and exynos only need to keep
>> some platform code. Cause I can't find the exact IP name of exynos dp
>> controller, so I decide to name dp core driver with "analogix" which I
>> find in rk3288 eDP TRM ;)
>> 
>> Beyond that, there are three light registers setting differents bewteen
>> exynos and rk3288.
>> 1. RK3288 have five special pll resigters which not indicata in exynos
>>    dp controller.
>> 2. The address of DP_PHY_PD(dp phy power manager register) are different
>>    between rk3288 and exynos.
>> 3. Rk3288 and exynos have different setting with AUX_HW_RETRY_CTL(dp debug
>>    register).
>> 
>> I have verified this series on two kinds of rockchip platform board, one
>> is rk3288 sdk board which connect with a 2K display port monitor, the other
>> is google jerry chromebook which connect with a eDP screen "cnm,n116bgeea2",
>> both of them works rightlly.
>> 
>> I haven't verified the dp function on samsung platform, cause I haven't got
>> exynos boards. I can only ensure that there are no build error on samsung
>> platform, wish some samsung guys help to test. ;)
>> 
>> Thanks,
>> - Yakir
>> 
>> Changes in v3:
>> - Take Thierry Reding suggest, move exynos's video_timing code
>>   to analogix_dp-exynos platform driver, add get_modes method
>>   to struct analogix_dp_plat_data.
>> - Take Heiko suggest, rename some "samsung*" dts propery to "analogix*".
>> - Take Thierry Reding suggest, dynamic parse video timing info from
>>   struct drm_display_mode and struct drm_display_info.
>> - Take Thierry Reding suggest, link_rate and lane_count shouldn't config to
>>   the DT property value directly, but we can take those as hardware limite.
>>   For example, RK3288 only support 4 physical lanes of 2.7/1.62 Gbps/lane,
>>   so DT property would like "link-rate = 0x0a" "lane-count = 4".
>> - Take Heiko suggest, add devicetree binding documents.
>> - Take Thierry Reding suggest, remove sync pol & colorimetry properies
>>   from the new analogix dp driver devicetree binding.
>> - Update the exist exynos dtsi file with the latest DP DT properies.
>> - Take Thierry Reding and Heiko suggest, leave "sclk_edp_24m" to rockchip
>>   dp phy driver which name to "24m", and leave "sclk_edp" to analogix dp
>>   core driver which name to "dp", and leave "pclk_edp" to rockchip dp platform
>>   driver which name to "pclk".
>> - Take Heiko suggest, add devicetree binding document.
>> - Take Heiko suggest, remove "rockchip,panel" DT property, take use of remote
>>   point to get panel node.
>> - Add the new function point analogix_dp_platdata.get_modes init.
>> - Take Heiko suggest, add rockchip dp phy driver,
>>   collect the phy clocks and power control.
>> - Add "analogix,need-force-hpd" to indicate whether driver need foce
>>   hpd when hpd detect failed.
>> - move dp hpd detect to connector detect function.
>> - Add edid modes parse support
>> 
>> Changes in v2:
>> - Take Joe Preches advise, improved commit message more readable, and
>>   avoid using some uncommon style like bellow:
>>   -  retval = exynos_dp_read_bytes_from_i2c(...
>>                ...)
>>   +  retval =
>>   +  exynos_dp_read_bytes_from_i2c(......);
>> - Take Jingoo Han suggest, just remove my name from author list.
>> - Take Jingoo Han suggest, remove new copyright
>> - Fix compiled failed dut to analogix_dp_device misspell
>> - Take Heiko suggest, get panel node with remote-endpoint method,
>>   and create devicetree binding for driver.
>> - Remove the clock enable/disbale with "sclk_edp" & "sclk_edp_24m",
>>   leave those clock to rockchip dp phy driver.
>> - Add GNU license v2 declared and samsung copyright
>> - Fix compile failed dut to phy_pd_addr variable misspell error
>> 
>> Yakir Yang (14):
>>   drm: exynos/dp: fix code style
>>   drm: exynos/dp: convert to drm bridge mode
>>   drm: bridge: analogix_dp: split exynos dp driver to bridge dir
>>   drm: bridge/analogix_dp: dynamic parse sync_pol & interlace &
>>     colorimetry
>>   drm: bridge/analogix_dp: fix link_rate & lane_count bug
>>   Documentation: drm/bridge: add document for analogix_dp
>>   drm: rockchip/dp: add rockchip platform dp driver
>>   phy: Add driver for rockchip Display Port PHY
>>   drm: bridge/analogix_dp: add platform device type support
>>   drm: bridge: analogix_dp: add some rk3288 special registers setting
>>   drm: bridge: analogix_dp: try force hpd after plug in lookup failed
>>   drm: bridge/analogix_dp: expand the delay time for hpd detect
>>   drm: bridge/analogix_dp: move hpd detect to connector detect function
>>   drm: bridge/analogix_dp: add edid modes parse in get_modes method
>> 
>>  .../devicetree/bindings/drm/bridge/analogix_dp.txt |   73 +
>>  .../devicetree/bindings/phy/rockchip-dp-phy.txt    |   26 +
>>  .../bindings/video/analogix_dp-rockchip.txt        |   83 ++
>>  .../devicetree/bindings/video/exynos_dp.txt        |   51 +-
>>  arch/arm/boot/dts/exynos5250-arndale.dts           |   10 +-
>>  arch/arm/boot/dts/exynos5250-smdk5250.dts          |   10 +-
>>  arch/arm/boot/dts/exynos5250-snow.dts              |   12 +-
>>  arch/arm/boot/dts/exynos5250-spring.dts            |   12 +-
>>  arch/arm/boot/dts/exynos5420-peach-pit.dts         |   12 +-
>>  arch/arm/boot/dts/exynos5420-smdk5420.dts          |   10 +-
>>  arch/arm/boot/dts/exynos5800-peach-pi.dts          |   12 +-
>>  drivers/gpu/drm/bridge/Kconfig                     |    5 +
>>  drivers/gpu/drm/bridge/Makefile                    |    1 +
>>  drivers/gpu/drm/bridge/analogix_dp_core.c          | 1382 +++++++++++++++++++
>>  drivers/gpu/drm/bridge/analogix_dp_core.h          |  286 ++++
>>  drivers/gpu/drm/bridge/analogix_dp_reg.c           | 1294 ++++++++++++++++++
>>  .../exynos_dp_reg.h => bridge/analogix_dp_reg.h}   |  270 ++--
>>  drivers/gpu/drm/exynos/Kconfig                     |    5 +-
>>  drivers/gpu/drm/exynos/Makefile                    |    2 +-
>>  drivers/gpu/drm/exynos/analogix_dp-exynos.c        |  347 +++++
>>  drivers/gpu/drm/exynos/exynos_dp_core.c            | 1416 --------------------
>>  drivers/gpu/drm/exynos/exynos_dp_core.h            |  282 ----
>>  drivers/gpu/drm/exynos/exynos_dp_reg.c             | 1263 -----------------
>>  drivers/gpu/drm/rockchip/Kconfig |    9 +
>>  drivers/gpu/drm/rockchip/Makefile                  |    1 +
>>  drivers/gpu/drm/rockchip/analogix_dp-rockchip.c    |  390 ++++++
>>  drivers/phy/Kconfig                                |    7 +
>>  drivers/phy/Makefile                               |    1 +
>>  drivers/phy/phy-rockchip-dp.c                      |  185 +++
>>  include/drm/bridge/analogix_dp.h |   40 +
>>  30 files changed, 4325 insertions(+), 3172 deletions(-)
>>  create mode 100644 Documentation/devicetree/bindings/drm/bridge/analogix_dp.txt
>>  create mode 100644 Documentation/devicetree/bindings/phy/rockchip-dp-phy.txt
>>  create mode 100644 Documentation/devicetree/bindings/video/analogix_dp-rockchip.txt
>>  create mode 100644 drivers/gpu/drm/bridge/analogix_dp_core.c
>>  create mode 100644 drivers/gpu/drm/bridge/analogix_dp_core.h
>>  create mode 100644 drivers/gpu/drm/bridge/analogix_dp_reg.c
> 
> Minor comment: Since there are a few files required for the driver,
> could you create a separate folder within drivers/gpu/drm/bridge?

I agree on this opinion.
Thank you. 

Best regards,
Jingoo Han

> Thanks,
> Archit
> 
> -- 
> Qualcomm Innovation Center, Inc. is a member of Code Aurora Forum,
> a Linux Foundation Collaborative Project


From vinod.koul at intel.com  Wed Aug 19 23:13:12 2015
From: vinod.koul at intel.com (Vinod Koul)
Date: Thu, 20 Aug 2015 11:43:12 +0530
Subject: [PATCH v4 2/2] dma: Add Xilinx zynqmp dma engine driver support
In-Reply-To: <1438831173-8761-2-git-send-email-punnaia@xilinx.com>
References: <1438831173-8761-1-git-send-email-punnaia@xilinx.com>
 <1438831173-8761-2-git-send-email-punnaia@xilinx.com>
Message-ID: <20150820061312.GA13546@localhost>

On Thu, Aug 06, 2015 at 08:49:33AM +0530, Punnaiah Choudary Kalluri wrote:

> +	list_for_each_entry_safe(desc, next, &chan->done_list, node) {
> +		dma_async_tx_callback callback;
> +		void *callback_param;
> +
> +		list_del(&desc->node);
> +
> +		callback = desc->async_tx.callback;
> +		callback_param = desc->async_tx.callback_param;
> +		if (callback) {
> +			if (in_interrupt())
> +				spin_unlock_bh(&chan->lock);
> +			else
> +				spin_unlock(&chan->lock);

This looks bad!
Why would callback be called from different context. It should only be
invoked from your tasklet

> +static int zynqmp_dma_device_terminate_all(struct dma_chan *dchan)
> +{
> +	struct zynqmp_dma_chan *chan = to_chan(dchan);
> +
> +	spin_lock_bh(&chan->lock);
> +	zynqmp_dma_reset(chan);
> +	spin_unlock_bh(&chan->lock);

No descriptor cleanup

> +static void zynqmp_dma_chan_remove(struct zynqmp_dma_chan *chan)
> +{
> +	if (!chan)
> +		return;
> +
> +	devm_free_irq(chan->zdev->dev, chan->irq, chan);
> +	tasklet_kill(&chan->tasklet);
> +	list_del(&chan->common.device_node);

not deregistering with dmaengine?

> +	zdev->chan = chan;
> +	tasklet_init(&chan->tasklet, zynqmp_dma_do_tasklet, (ulong)chan);
> +	spin_lock_init(&chan->lock);
> +	INIT_LIST_HEAD(&chan->active_list);
> +	INIT_LIST_HEAD(&chan->pending_list);
> +	INIT_LIST_HEAD(&chan->done_list);
> +	INIT_LIST_HEAD(&chan->free_list);

You can simmplify this by using vchan framework!

> +MODULE_AUTHOR("Xilinx, Inc.");
> +MODULE_DESCRIPTION("Xilinx ZynqMP DMA driver");
> +MODULE_LICENSE("GPL");
No alias, how did it get loaded?

-- 
~Vinod



From punnaia at xilinx.com  Wed Aug 19 23:11:33 2015
From: punnaia at xilinx.com (punnaiah choudary kalluri)
Date: Thu, 20 Aug 2015 11:41:33 +0530
Subject: [PATCH v4 1/2] Documentation: dt: Add Xilinx zynqmp dma device
 tree binding documentation
In-Reply-To: <20150820055255.GZ13546@localhost>
References: <1438831173-8761-1-git-send-email-punnaia@xilinx.com>
 <20150820055255.GZ13546@localhost>
Message-ID: <CAGnW=BbjdAUf5SgRXvNNoamhuVjKC4miBUGSiV_s4+Byb0nzog@mail.gmail.com>

On Thu, Aug 20, 2015 at 11:22 AM, Vinod Koul <vinod.koul at intel.com> wrote:
> On Thu, Aug 06, 2015 at 08:49:32AM +0530, Punnaiah Choudary Kalluri wrote:
>> Device-tree binding documentation for Xilinx zynqmp dma engine used in
>> Zynq UltraScale+ MPSoC.
>>
>> Signed-off-by: Punnaiah Choudary Kalluri <punnaia at xilinx.com>
>> ---
>> Changes in v4:
>> - None
>> Changes in v3:
>> - None
>> Changes in v2:
>> - None
>> ---
>>  .../devicetree/bindings/dma/xilinx/zynqmp_dma.txt  |   61 ++++++++++++++++++++
>>  1 files changed, 61 insertions(+), 0 deletions(-)
>>  create mode 100644 Documentation/devicetree/bindings/dma/xilinx/zynqmp_dma.txt
>>
>> diff --git a/Documentation/devicetree/bindings/dma/xilinx/zynqmp_dma.txt b/Documentation/devicetree/bindings/dma/xilinx/zynqmp_dma.txt
>> new file mode 100644
>> index 0000000..e4f92b9
>> --- /dev/null
>> +++ b/Documentation/devicetree/bindings/dma/xilinx/zynqmp_dma.txt
>> @@ -0,0 +1,61 @@
>> +Xilinx ZynqMP DMA engine, it does support memory to memory transfers,
>> +memory to device and device to memory transfers. It also has flow
>> +control and rate control support for slave/peripheral dma access.
>> +
>> +Required properties:
>> +- compatible: Should be "xlnx,zynqmp-dma-1.0"
>> +- #dma-cells: Should be <1>, a single cell holding a line request number
>> +- reg: Memory map for module access
>> +- interrupt-parent: Interrupt controller the interrupt is routed through
>> +- interrupts: Should contain DMA channel interrupt
> channel interrupt or interrupts, former says it is plural

ZynqMP DMA has single interrupt for each channel So, that is the reason
i have explicitly mentioned it as interrupt ( not interrupts).

Please let me know if you still want it to be plural.

Regards,
Punnaiah
>
> --
> ~Vinod
>


From jingoohan1 at gmail.com  Wed Aug 19 23:11:29 2015
From: jingoohan1 at gmail.com (Jingoo Han)
Date: Thu, 20 Aug 2015 15:11:29 +0900
Subject: [PATCH v3 12/14] drm: bridge/analogix_dp: expand the delay time
 for hpd detect
In-Reply-To: <1439995929-18719-1-git-send-email-ykk@rock-chips.com>
References: <1439995728-18046-1-git-send-email-ykk@rock-chips.com>
 <1439995929-18719-1-git-send-email-ykk@rock-chips.com>
Message-ID: <A474A3AB-86A8-4967-B90F-31920A5E7BA3@gmail.com>

On 2015. 8. 19., at PM 11:52, Yakir Yang <ykk at rock-chips.com> wrote:
> 
> Some edp screen with no hpd signal would need some delay time
> to ensure that screen would be ready for work, so we can expand
> the delay time in hpd detect function, it works prefectly on my
> rk3288 sdk board.

Then, this delay has a dependency on the "rk3288 sdk" board.
Also, if the delay time is expanded, the booting time of some Exybos boards will be increased unnecessarily. :-(

So, please add new DT property such as 'hpd-delay' that can be added to board DT files.

If there is not that DT property in DT files, the default value '10' will written to a variable such as 'unsigned int hpd_delay'.
If there is the DT property in DT files, the delay value will written to the variable when parsing DT values
and will be used in analogix_dp_detect_hpd().

What I want to say is that there should not be harmful effect on the existing Exynos boards, due to unrelated reasons.

Best regards,
Jingoo Han

> Signed-off-by: Yakir Yang <ykk at rock-chips.com>
> ---
> Changes in v3: None
> Changes in v2: None
> 
> drivers/gpu/drm/bridge/analogix_dp_core.c | 2 +-
> 1 file changed, 1 insertion(+), 1 deletion(-)
> 
> diff --git a/drivers/gpu/drm/bridge/analogix_dp_core.c b/drivers/gpu/drm/bridge/analogix_dp_core.c
> index 99870f7..75dd44a 100644
> --- a/drivers/gpu/drm/bridge/analogix_dp_core.c
> +++ b/drivers/gpu/drm/bridge/analogix_dp_core.c
> @@ -68,7 +68,7 @@ static int analogix_dp_detect_hpd(struct analogix_dp_device *dp)
>            return 0;
> 
>        timeout_loop++;
> -        usleep_range(10, 11);
> +        usleep_range(100, 110);
>    }
> 
>    /*
> -- 
> 1.9.1
> 
> 


From vinod.koul at intel.com  Wed Aug 19 23:18:31 2015
From: vinod.koul at intel.com (Vinod Koul)
Date: Thu, 20 Aug 2015 11:48:31 +0530
Subject: [PATCH v4 1/2] Documentation: dt: Add Xilinx zynqmp dma device
 tree binding documentation
In-Reply-To: <CAGnW=BbjdAUf5SgRXvNNoamhuVjKC4miBUGSiV_s4+Byb0nzog@mail.gmail.com>
References: <1438831173-8761-1-git-send-email-punnaia@xilinx.com>
 <20150820055255.GZ13546@localhost>
 <CAGnW=BbjdAUf5SgRXvNNoamhuVjKC4miBUGSiV_s4+Byb0nzog@mail.gmail.com>
Message-ID: <20150820061831.GB13546@localhost>

On Thu, Aug 20, 2015 at 11:41:33AM +0530, punnaiah choudary kalluri wrote:
> >> +- interrupts: Should contain DMA channel interrupt
> > channel interrupt or interrupts, former says it is plural
> 
> ZynqMP DMA has single interrupt for each channel So, that is the reason
> i have explicitly mentioned it as interrupt ( not interrupts).
> 
> Please let me know if you still want it to be plural.

The example had multiple values so plural sounds right

-- 
~Vinod



From michal.simek at xilinx.com  Wed Aug 19 23:20:26 2015
From: michal.simek at xilinx.com (Michal Simek)
Date: Thu, 20 Aug 2015 08:20:26 +0200
Subject: [PATCH v4 1/2] Documentation: dt: Add Xilinx zynqmp dma device
 tree binding documentation
In-Reply-To: <20150820061831.GB13546@localhost>
References: <1438831173-8761-1-git-send-email-punnaia@xilinx.com>
 <20150820055255.GZ13546@localhost>
 <CAGnW=BbjdAUf5SgRXvNNoamhuVjKC4miBUGSiV_s4+Byb0nzog@mail.gmail.com>
 <20150820061831.GB13546@localhost>
Message-ID: <55D571AA.1090102@xilinx.com>

On 08/20/2015 08:18 AM, Vinod Koul wrote:
> On Thu, Aug 20, 2015 at 11:41:33AM +0530, punnaiah choudary kalluri wrote:
>>>> +- interrupts: Should contain DMA channel interrupt
>>> channel interrupt or interrupts, former says it is plural
>>
>> ZynqMP DMA has single interrupt for each channel So, that is the reason
>> i have explicitly mentioned it as interrupt ( not interrupts).
>>
>> Please let me know if you still want it to be plural.
> 
> The example had multiple values so plural sounds right
> 

I expect you are talking about this "interrupts = <0 117 4>;"

It is 3 cells format used on ARM based on gic spec which is on SPI
interrupt 117 active high level-sensitive

Documentation/devicetree/bindings/arm/gic.txt

Thanks,
Michal



From hdegoede at redhat.com  Wed Aug 19 23:23:27 2015
From: hdegoede at redhat.com (Hans de Goede)
Date: Thu, 20 Aug 2015 08:23:27 +0200
Subject: [PATCH 2/3] ARM: dts: sun6i: Turn on gmac on Colombus
In-Reply-To: <20150819151754.GH30520@lukather>
References: <1438960955-6551-1-git-send-email-hdegoede@redhat.com>
 <1438960955-6551-2-git-send-email-hdegoede@redhat.com>
 <20150819151754.GH30520@lukather>
Message-ID: <55D5725F.6000106@redhat.com>

Hi,

On 08/19/2015 05:17 PM, Maxime Ripard wrote:
> On Fri, Aug 07, 2015 at 05:22:34PM +0200, Hans de Goede wrote:
>> We've everything we need to support the gmac on Colombus, turn it on.
>>
>> Signed-off-by: Hans de Goede <hdegoede at redhat.com>
>
> I recall that the phy was powered by one of the AXP221 regulators,
> does it require some additional stuff (like a recent u-boot), or does
> it just work and my memory is bad :) ?

I think it just works, it MAY be connected to aldo1 but according to
the git history for the u-boot defconfig that one is used for wifi not
for the gmac, and we do not enable any other "spare" regulators in the
u-boot config.

I do not have any schematics, so no way to say for sure.

I can confirm that the GMAC work fine with the latest u-boot
master. Looking in the history we've always enabled ALDO1
on the Colombus in upstream u-boot, so this should all just work.

Regards,

Hans


From ykk at rock-chips.com  Wed Aug 19 23:23:56 2015
From: ykk at rock-chips.com (Yakir Yang)
Date: Thu, 20 Aug 2015 01:23:56 -0500
Subject: [PATCH v3 0/14] Add Analogix Core Display Port Driver
In-Reply-To: <58DB3289-29F0-4C2D-97F6-EB0555392DF2@gmail.com>
References: <1439995728-18046-1-git-send-email-ykk@rock-chips.com>
 <55D557BD.8070004@codeaurora.org>
 <58DB3289-29F0-4C2D-97F6-EB0555392DF2@gmail.com>
Message-ID: <55D5727C.8000109@rock-chips.com>

Hi Jingoo & Archit,


On 08/20/2015 12:54 AM, Jingoo Han wrote:
> On 2015. 8. 20., at PM 1:29, Archit Taneja <architt at codeaurora.org> wrote:
>> Hi,
>>
>>> On 08/19/2015 08:18 PM, Yakir Yang wrote:
>>>
>>> Hi all,
>>>     The Samsung Exynos eDP controller and Rockchip RK3288 eDP controller
>>> share the same IP, so a lot of parts can be re-used. I split the common
>>> code into bridge directory, then rk3288 and exynos only need to keep
>>> some platform code. Cause I can't find the exact IP name of exynos dp
>>> controller, so I decide to name dp core driver with "analogix" which I
>>> find in rk3288 eDP TRM ;)
>>>
>>> Beyond that, there are three light registers setting differents bewteen
>>> exynos and rk3288.
>>> 1. RK3288 have five special pll resigters which not indicata in exynos
>>>     dp controller.
>>> 2. The address of DP_PHY_PD(dp phy power manager register) are different
>>>     between rk3288 and exynos.
>>> 3. Rk3288 and exynos have different setting with AUX_HW_RETRY_CTL(dp debug
>>>     register).
>>>
>>> I have verified this series on two kinds of rockchip platform board, one
>>> is rk3288 sdk board which connect with a 2K display port monitor, the other
>>> is google jerry chromebook which connect with a eDP screen "cnm,n116bgeea2",
>>> both of them works rightlly.
>>>
>>> I haven't verified the dp function on samsung platform, cause I haven't got
>>> exynos boards. I can only ensure that there are no build error on samsung
>>> platform, wish some samsung guys help to test. ;)
>>>
>>> Thanks,
>>> - Yakir
>>>
>>> Changes in v3:
>>> - Take Thierry Reding suggest, move exynos's video_timing code
>>>    to analogix_dp-exynos platform driver, add get_modes method
>>>    to struct analogix_dp_plat_data.
>>> - Take Heiko suggest, rename some "samsung*" dts propery to "analogix*".
>>> - Take Thierry Reding suggest, dynamic parse video timing info from
>>>    struct drm_display_mode and struct drm_display_info.
>>> - Take Thierry Reding suggest, link_rate and lane_count shouldn't config to
>>>    the DT property value directly, but we can take those as hardware limite.
>>>    For example, RK3288 only support 4 physical lanes of 2.7/1.62 Gbps/lane,
>>>    so DT property would like "link-rate = 0x0a" "lane-count = 4".
>>> - Take Heiko suggest, add devicetree binding documents.
>>> - Take Thierry Reding suggest, remove sync pol & colorimetry properies
>>>    from the new analogix dp driver devicetree binding.
>>> - Update the exist exynos dtsi file with the latest DP DT properies.
>>> - Take Thierry Reding and Heiko suggest, leave "sclk_edp_24m" to rockchip
>>>    dp phy driver which name to "24m", and leave "sclk_edp" to analogix dp
>>>    core driver which name to "dp", and leave "pclk_edp" to rockchip dp platform
>>>    driver which name to "pclk".
>>> - Take Heiko suggest, add devicetree binding document.
>>> - Take Heiko suggest, remove "rockchip,panel" DT property, take use of remote
>>>    point to get panel node.
>>> - Add the new function point analogix_dp_platdata.get_modes init.
>>> - Take Heiko suggest, add rockchip dp phy driver,
>>>    collect the phy clocks and power control.
>>> - Add "analogix,need-force-hpd" to indicate whether driver need foce
>>>    hpd when hpd detect failed.
>>> - move dp hpd detect to connector detect function.
>>> - Add edid modes parse support
>>>
>>> Changes in v2:
>>> - Take Joe Preches advise, improved commit message more readable, and
>>>    avoid using some uncommon style like bellow:
>>>    -  retval = exynos_dp_read_bytes_from_i2c(...
>>>                 ...)
>>>    +  retval =
>>>    +  exynos_dp_read_bytes_from_i2c(......);
>>> - Take Jingoo Han suggest, just remove my name from author list.
>>> - Take Jingoo Han suggest, remove new copyright
>>> - Fix compiled failed dut to analogix_dp_device misspell
>>> - Take Heiko suggest, get panel node with remote-endpoint method,
>>>    and create devicetree binding for driver.
>>> - Remove the clock enable/disbale with "sclk_edp" & "sclk_edp_24m",
>>>    leave those clock to rockchip dp phy driver.
>>> - Add GNU license v2 declared and samsung copyright
>>> - Fix compile failed dut to phy_pd_addr variable misspell error
>>>
>>> Yakir Yang (14):
>>>    drm: exynos/dp: fix code style
>>>    drm: exynos/dp: convert to drm bridge mode
>>>    drm: bridge: analogix_dp: split exynos dp driver to bridge dir
>>>    drm: bridge/analogix_dp: dynamic parse sync_pol & interlace &
>>>      colorimetry
>>>    drm: bridge/analogix_dp: fix link_rate & lane_count bug
>>>    Documentation: drm/bridge: add document for analogix_dp
>>>    drm: rockchip/dp: add rockchip platform dp driver
>>>    phy: Add driver for rockchip Display Port PHY
>>>    drm: bridge/analogix_dp: add platform device type support
>>>    drm: bridge: analogix_dp: add some rk3288 special registers setting
>>>    drm: bridge: analogix_dp: try force hpd after plug in lookup failed
>>>    drm: bridge/analogix_dp: expand the delay time for hpd detect
>>>    drm: bridge/analogix_dp: move hpd detect to connector detect function
>>>    drm: bridge/analogix_dp: add edid modes parse in get_modes method
>>>
>>>   .../devicetree/bindings/drm/bridge/analogix_dp.txt |   73 +
>>>   .../devicetree/bindings/phy/rockchip-dp-phy.txt    |   26 +
>>>   .../bindings/video/analogix_dp-rockchip.txt        |   83 ++
>>>   .../devicetree/bindings/video/exynos_dp.txt        |   51 +-
>>>   arch/arm/boot/dts/exynos5250-arndale.dts           |   10 +-
>>>   arch/arm/boot/dts/exynos5250-smdk5250.dts          |   10 +-
>>>   arch/arm/boot/dts/exynos5250-snow.dts              |   12 +-
>>>   arch/arm/boot/dts/exynos5250-spring.dts            |   12 +-
>>>   arch/arm/boot/dts/exynos5420-peach-pit.dts         |   12 +-
>>>   arch/arm/boot/dts/exynos5420-smdk5420.dts          |   10 +-
>>>   arch/arm/boot/dts/exynos5800-peach-pi.dts          |   12 +-
>>>   drivers/gpu/drm/bridge/Kconfig                     |    5 +
>>>   drivers/gpu/drm/bridge/Makefile                    |    1 +
>>>   drivers/gpu/drm/bridge/analogix_dp_core.c          | 1382 +++++++++++++++++++
>>>   drivers/gpu/drm/bridge/analogix_dp_core.h          |  286 ++++
>>>   drivers/gpu/drm/bridge/analogix_dp_reg.c           | 1294 ++++++++++++++++++
>>>   .../exynos_dp_reg.h => bridge/analogix_dp_reg.h}   |  270 ++--
>>>   drivers/gpu/drm/exynos/Kconfig                     |    5 +-
>>>   drivers/gpu/drm/exynos/Makefile                    |    2 +-
>>>   drivers/gpu/drm/exynos/analogix_dp-exynos.c        |  347 +++++
>>>   drivers/gpu/drm/exynos/exynos_dp_core.c            | 1416 --------------------
>>>   drivers/gpu/drm/exynos/exynos_dp_core.h            |  282 ----
>>>   drivers/gpu/drm/exynos/exynos_dp_reg.c             | 1263 -----------------
>>>   drivers/gpu/drm/rockchip/Kconfig |    9 +
>>>   drivers/gpu/drm/rockchip/Makefile                  |    1 +
>>>   drivers/gpu/drm/rockchip/analogix_dp-rockchip.c    |  390 ++++++
>>>   drivers/phy/Kconfig                                |    7 +
>>>   drivers/phy/Makefile                               |    1 +
>>>   drivers/phy/phy-rockchip-dp.c                      |  185 +++
>>>   include/drm/bridge/analogix_dp.h |   40 +
>>>   30 files changed, 4325 insertions(+), 3172 deletions(-)
>>>   create mode 100644 Documentation/devicetree/bindings/drm/bridge/analogix_dp.txt
>>>   create mode 100644 Documentation/devicetree/bindings/phy/rockchip-dp-phy.txt
>>>   create mode 100644 Documentation/devicetree/bindings/video/analogix_dp-rockchip.txt
>>>   create mode 100644 drivers/gpu/drm/bridge/analogix_dp_core.c
>>>   create mode 100644 drivers/gpu/drm/bridge/analogix_dp_core.h
>>>   create mode 100644 drivers/gpu/drm/bridge/analogix_dp_reg.c
>> Minor comment: Since there are a few files required for the driver,
>> could you create a separate folder within drivers/gpu/drm/bridge?
> I agree on this opinion.
> Thank you.

Thanks for your comment ;)

Yeah, bridge/ have been add four new files for this driver, it would be 
better to
collect into a separate folder.

I'm wondering should I just name the folder with "analogix_dp/", or we 
can make
it more common (like "analogix/")? (personally I do like the last one)

Thanks,
- Yakir
> Best regards,
> Jingoo Han
>
>> Thanks,
>> Archit
>>
>> -- 
>> Qualcomm Innovation Center, Inc. is a member of Code Aurora Forum,
>> a Linux Foundation Collaborative Project
>
>




From vinod.koul at intel.com  Wed Aug 19 23:27:35 2015
From: vinod.koul at intel.com (Vinod Koul)
Date: Thu, 20 Aug 2015 11:57:35 +0530
Subject: [PATCH] dmaengine: xgene-dma: Add ACPI support for X-Gene DMA
 engine driver
In-Reply-To: <1437484479-2822-1-git-send-email-rsahu@apm.com>
References: <1437484479-2822-1-git-send-email-rsahu@apm.com>
Message-ID: <20150820062735.GC13546@localhost>

On Tue, Jul 21, 2015 at 06:44:39PM +0530, Rameshwar Prasad Sahu wrote:
> This patch adds ACPI support for the APM X-Gene DMA engine driver.

Applied, thanks

-- 
~Vinod



From rsahu at apm.com  Wed Aug 19 23:29:07 2015
From: rsahu at apm.com (Rameshwar Sahu)
Date: Thu, 20 Aug 2015 11:59:07 +0530
Subject: [PATCH v1 1/4] dmaengine: Add support for new feature CRC32C
In-Reply-To: <20150820052631.GW13546@localhost>
References: <1438258268-3099-1-git-send-email-rsahu@apm.com>
 <1438258268-3099-2-git-send-email-rsahu@apm.com>
 <20150820052631.GW13546@localhost>
Message-ID: <CAFd313x+MD5C2stJ-YdKrt6Ywzt4_2GmK3pJTFjfwrhPnCdopQ@mail.gmail.com>

Hi Vinod,

On Thu, Aug 20, 2015 at 10:56 AM, Vinod Koul <vinod.koul at intel.com> wrote:
> On Thu, Jul 30, 2015 at 05:41:05PM +0530, Rameshwar Prasad Sahu wrote:
>> This patch adds support for new feature CRC32C calculation in
>> dmaengine framework.
>
> Looks okay can you please update Documentation also

Thanks, I will update Documentation.
>
> --
> ~Vinod
>


From punnaia at xilinx.com  Wed Aug 19 23:31:27 2015
From: punnaia at xilinx.com (punnaiah choudary kalluri)
Date: Thu, 20 Aug 2015 12:01:27 +0530
Subject: [PATCH v4 2/2] dma: Add Xilinx zynqmp dma engine driver support
In-Reply-To: <20150820061312.GA13546@localhost>
References: <1438831173-8761-1-git-send-email-punnaia@xilinx.com>
 <1438831173-8761-2-git-send-email-punnaia@xilinx.com>
 <20150820061312.GA13546@localhost>
Message-ID: <CAGnW=BaU__+B2uAK=qpV3QP60SqSUxx-kgJVs0t42K0fqTxL0g@mail.gmail.com>

On Thu, Aug 20, 2015 at 11:43 AM, Vinod Koul <vinod.koul at intel.com> wrote:
> On Thu, Aug 06, 2015 at 08:49:33AM +0530, Punnaiah Choudary Kalluri wrote:
>
>> +     list_for_each_entry_safe(desc, next, &chan->done_list, node) {
>> +             dma_async_tx_callback callback;
>> +             void *callback_param;
>> +
>> +             list_del(&desc->node);
>> +
>> +             callback = desc->async_tx.callback;
>> +             callback_param = desc->async_tx.callback_param;
>> +             if (callback) {
>> +                     if (in_interrupt())
>> +                             spin_unlock_bh(&chan->lock);
>> +                     else
>> +                             spin_unlock(&chan->lock);
>
> This looks bad!
> Why would callback be called from different context. It should only be
> invoked from your tasklet

During the terminate call, driver need to clean up the existing BDs so that time
this function will be called from the thread or process context in
addition to the
tasklet context.

DO you have any suggestion here ?


>
>> +static int zynqmp_dma_device_terminate_all(struct dma_chan *dchan)
>> +{
>> +     struct zynqmp_dma_chan *chan = to_chan(dchan);
>> +
>> +     spin_lock_bh(&chan->lock);
>> +     zynqmp_dma_reset(chan);
>> +     spin_unlock_bh(&chan->lock);
>
> No descriptor cleanup

zynqmp_dma_reset will do the descriptor cleanup.

>
>> +static void zynqmp_dma_chan_remove(struct zynqmp_dma_chan *chan)
>> +{
>> +     if (!chan)
>> +             return;
>> +
>> +     devm_free_irq(chan->zdev->dev, chan->irq, chan);
>> +     tasklet_kill(&chan->tasklet);
>> +     list_del(&chan->common.device_node);
>
> not deregistering with dmaengine?

This i am doing it in zynqmp_dma_remove function. Each channel will be
a standalone dma device for ZynqMP DMA case

>
>> +     zdev->chan = chan;
>> +     tasklet_init(&chan->tasklet, zynqmp_dma_do_tasklet, (ulong)chan);
>> +     spin_lock_init(&chan->lock);
>> +     INIT_LIST_HEAD(&chan->active_list);
>> +     INIT_LIST_HEAD(&chan->pending_list);
>> +     INIT_LIST_HEAD(&chan->done_list);
>> +     INIT_LIST_HEAD(&chan->free_list);
>
> You can simmplify this by using vchan framework!

I got your point . but i have already said my reasons why i am
reluctant to use vchan framework in v3 review.

>
>> +MODULE_AUTHOR("Xilinx, Inc.");
>> +MODULE_DESCRIPTION("Xilinx ZynqMP DMA driver");
>> +MODULE_LICENSE("GPL");
> No alias, how did it get loaded?

I will fix this. thanks.

Regards,
Punnaiah
>
> --
> ~Vinod
>


From maxime.ripard at free-electrons.com  Wed Aug 19 23:39:00 2015
From: maxime.ripard at free-electrons.com (Maxime Ripard)
Date: Thu, 20 Aug 2015 08:39:00 +0200
Subject: un4i-ss-cipher.c warning
In-Reply-To: <20150820052903.GA26031@gondor.apana.org.au>
References: <CAOMqctShdb9xEkBmuaQKfB1cwGupbfH5TS5ZB_P85Hwpn+4zAA@mail.gmail.com>
 <20150820052903.GA26031@gondor.apana.org.au>
Message-ID: <20150820063900.GJ30520@lukather>

On Thu, Aug 20, 2015 at 01:29:03PM +0800, Herbert Xu wrote:
> On Wed, Aug 19, 2015 at 04:35:36PM +0200, Michal Suchanek wrote:
> > Hello,
> > 
> > when building a kernel with sunxi crypto driver as merged into the
> > sinxi-wip branch I get a compiler warning.
> > 
> > I am not sure this is the latest version of the driver. It does not
> > seem to be in mainline yet.
> 
> The warning appears to be spurious as the code always ends up
> initialising todo before using it.

Not in the dev_dbg call line 258. If ileft was negative or null, todo
isn't assigned to anything.

I'm not sure whether initializing todo to 0 is the right thing to do
though. Corentin?

Maxime

-- 
Maxime Ripard, Free Electrons
Embedded Linux, Kernel and Android engineering
http://free-electrons.com
-------------- next part --------------
A non-text attachment was scrubbed...
Name: signature.asc
Type: application/pgp-signature
Size: 819 bytes
Desc: Digital signature
URL: <http://lists.infradead.org/pipermail/linux-arm-kernel/attachments/20150820/7e407bbd/attachment.sig>

From maitysanchayan at gmail.com  Wed Aug 19 23:38:07 2015
From: maitysanchayan at gmail.com (maitysanchayan at gmail.com)
Date: Thu, 20 Aug 2015 12:08:07 +0530
Subject: [PATCH v4] iio: adc: vf610: Add IIO buffer support for Vybrid ADC
In-Reply-To: <9be567ec7d6f6370dd42a41438d64cf7aaa47635.1439826018.git.maitysanchayan@gmail.com>
References: <d556443a26070be505f9a5f5f0999253b73d9b71.1439283162.git.maitysanchayan@gmail.com>
 <9be567ec7d6f6370dd42a41438d64cf7aaa47635.1439826018.git.maitysanchayan@gmail.com>
Message-ID: <20150820063807.GA3708@Sanchayan-Arch.toradex.int>

Hello Fugang Duan,

Can I have your ACK if you are ok with the changes made by the
patch?

Thanks & Regards,
Sanchayan Maity.

On 15-08-17 21:21:40, Sanchayan Maity wrote:
> This patch adds support for IIO buffer to the Vybrid ADC driver.
> IIO triggered buffer infrastructure along with iio sysfs trigger
> is used to leverage continuous sampling support provided by the
> ADC block.
> 
> Signed-off-by: Sanchayan Maity <maitysanchayan at gmail.com>
> ---
> 
> Changes since v3:
> Fix iio_buffer_setup_ops for postenable and predisable functions
> to match pairwise. Before this the predisable work was being done
> in postdisable.
> 
> Changes since v2:
> 1. Fix the wrong buffer size for statically allocated buffer
> 2. Drop the use of .address field from the iio_chan_spec
> 3. Use iio_buffer_enabled call inside the lock
> 4. Drop wrapper function around iio_trigered_* function calls
> 5. Drop Kconfig select of sysfs trigger
> 6. Drop Kconfig select IIO_TRIGGER as it is already selected by
> IIO_TRIGGERED_BUFFER
> 
> Changes since v1:
> 1. Use a fixed size buffer instead of kmalloc allocated during update
> scan mode
> 2. Remove a write to read only register ADC_HS (COCO bit)
> 
>  drivers/iio/adc/Kconfig     |   2 +
>  drivers/iio/adc/vf610_adc.c | 105 +++++++++++++++++++++++++++++++++++++++++---
>  2 files changed, 100 insertions(+), 7 deletions(-)
> 
> diff --git a/drivers/iio/adc/Kconfig b/drivers/iio/adc/Kconfig
> index 7c55658..660f790 100644
> --- a/drivers/iio/adc/Kconfig
> +++ b/drivers/iio/adc/Kconfig
> @@ -337,6 +337,8 @@ config TWL6030_GPADC
>  config VF610_ADC
>  	tristate "Freescale vf610 ADC driver"
>  	depends on OF
> +	select IIO_BUFFER
> +	select IIO_TRIGGERED_BUFFER
>  	help
>  	  Say yes here to support for Vybrid board analog-to-digital converter.
>  	  Since the IP is used for i.MX6SLX, the driver also support i.MX6SLX.
> diff --git a/drivers/iio/adc/vf610_adc.c b/drivers/iio/adc/vf610_adc.c
> index 23b8fb9..887a7ba 100644
> --- a/drivers/iio/adc/vf610_adc.c
> +++ b/drivers/iio/adc/vf610_adc.c
> @@ -34,8 +34,11 @@
>  #include <linux/err.h>
>  
>  #include <linux/iio/iio.h>
> +#include <linux/iio/buffer.h>
>  #include <linux/iio/sysfs.h>
> -#include <linux/iio/driver.h>
> +#include <linux/iio/trigger.h>
> +#include <linux/iio/trigger_consumer.h>
> +#include <linux/iio/triggered_buffer.h>
>  
>  /* This will be the driver name the kernel reports */
>  #define DRIVER_NAME "vf610-adc"
> @@ -170,6 +173,7 @@ struct vf610_adc {
>  	u32 sample_freq_avail[5];
>  
>  	struct completion completion;
> +	u16 buffer[8];
>  };
>  
>  static const u32 vf610_hw_avgs[] = { 1, 4, 8, 16, 32 };
> @@ -505,12 +509,24 @@ static const struct iio_chan_spec_ext_info vf610_ext_info[] = {
>  	.info_mask_shared_by_type = BIT(IIO_CHAN_INFO_SCALE) |	\
>  				BIT(IIO_CHAN_INFO_SAMP_FREQ),	\
>  	.ext_info = vf610_ext_info,				\
> +	.scan_index = (_idx),			\
> +	.scan_type = {					\
> +		.sign = 'u',				\
> +		.realbits = 12,				\
> +		.storagebits = 16,			\
> +	},						\
>  }
>  
>  #define VF610_ADC_TEMPERATURE_CHAN(_idx, _chan_type) {	\
>  	.type = (_chan_type),	\
>  	.channel = (_idx),		\
>  	.info_mask_separate = BIT(IIO_CHAN_INFO_PROCESSED),	\
> +	.scan_index = (_idx),					\
> +	.scan_type = {						\
> +		.sign = 'u',					\
> +		.realbits = 12,					\
> +		.storagebits = 16,				\
> +	},							\
>  }
>  
>  static const struct iio_chan_spec vf610_adc_iio_channels[] = {
> @@ -531,6 +547,7 @@ static const struct iio_chan_spec vf610_adc_iio_channels[] = {
>  	VF610_ADC_CHAN(14, IIO_VOLTAGE),
>  	VF610_ADC_CHAN(15, IIO_VOLTAGE),
>  	VF610_ADC_TEMPERATURE_CHAN(26, IIO_TEMP),
> +	IIO_CHAN_SOFT_TIMESTAMP(32),
>  	/* sentinel */
>  };
>  
> @@ -559,13 +576,20 @@ static int vf610_adc_read_data(struct vf610_adc *info)
>  
>  static irqreturn_t vf610_adc_isr(int irq, void *dev_id)
>  {
> -	struct vf610_adc *info = (struct vf610_adc *)dev_id;
> +	struct iio_dev *indio_dev = (struct iio_dev *)dev_id;
> +	struct vf610_adc *info = iio_priv(indio_dev);
>  	int coco;
>  
>  	coco = readl(info->regs + VF610_REG_ADC_HS);
>  	if (coco & VF610_ADC_HS_COCO0) {
>  		info->value = vf610_adc_read_data(info);
> -		complete(&info->completion);
> +		if (iio_buffer_enabled(indio_dev)) {
> +			info->buffer[0] = info->value;
> +			iio_push_to_buffers_with_timestamp(indio_dev,
> +					info->buffer, iio_get_time_ns());
> +			iio_trigger_notify_done(indio_dev->trig);
> +		} else
> +			complete(&info->completion);
>  	}
>  
>  	return IRQ_HANDLED;
> @@ -613,8 +637,12 @@ static int vf610_read_raw(struct iio_dev *indio_dev,
>  	case IIO_CHAN_INFO_RAW:
>  	case IIO_CHAN_INFO_PROCESSED:
>  		mutex_lock(&indio_dev->mlock);
> -		reinit_completion(&info->completion);
> +		if (iio_buffer_enabled(indio_dev)) {
> +			mutex_unlock(&indio_dev->mlock);
> +			return -EBUSY;
> +		}
>  
> +		reinit_completion(&info->completion);
>  		hc_cfg = VF610_ADC_ADCHC(chan->channel);
>  		hc_cfg |= VF610_ADC_AIEN;
>  		writel(hc_cfg, info->regs + VF610_REG_ADC_HC0);
> @@ -694,6 +722,60 @@ static int vf610_write_raw(struct iio_dev *indio_dev,
>  	return -EINVAL;
>  }
>  
> +static int vf610_adc_buffer_postenable(struct iio_dev *indio_dev)
> +{
> +	struct vf610_adc *info = iio_priv(indio_dev);
> +	unsigned int channel;
> +	int ret;
> +	int val;
> +
> +	ret = iio_triggered_buffer_postenable(indio_dev);
> +	if (ret)
> +		return ret;
> +
> +	val = readl(info->regs + VF610_REG_ADC_GC);
> +	val |= VF610_ADC_ADCON;
> +	writel(val, info->regs + VF610_REG_ADC_GC);
> +
> +	channel = find_first_bit(indio_dev->active_scan_mask,
> +						indio_dev->masklength);
> +
> +	val = VF610_ADC_ADCHC(channel);
> +	val |= VF610_ADC_AIEN;
> +
> +	writel(val, info->regs + VF610_REG_ADC_HC0);
> +
> +	return 0;
> +}
> +
> +static int vf610_adc_buffer_predisable(struct iio_dev *indio_dev)
> +{
> +	struct vf610_adc *info = iio_priv(indio_dev);
> +	unsigned int hc_cfg = 0;
> +	int val, ret;
> +
> +	val = readl(info->regs + VF610_REG_ADC_GC);
> +	val &= ~VF610_ADC_ADCON;
> +	writel(val, info->regs + VF610_REG_ADC_GC);
> +
> +	hc_cfg |= VF610_ADC_CONV_DISABLE;
> +	hc_cfg &= ~VF610_ADC_AIEN;
> +
> +	writel(hc_cfg, info->regs + VF610_REG_ADC_HC0);
> +
> +	ret = iio_triggered_buffer_predisable(indio_dev);
> +	if (ret)
> +		return ret;
> +
> +	return 0;
> +}
> +
> +static const struct iio_buffer_setup_ops iio_triggered_buffer_setup_ops = {
> +	.postenable = &vf610_adc_buffer_postenable,
> +	.predisable = &vf610_adc_buffer_predisable,
> +	.validate_scan_mask = &iio_validate_scan_mask_onehot,
> +};
> +
>  static int vf610_adc_reg_access(struct iio_dev *indio_dev,
>  			unsigned reg, unsigned writeval,
>  			unsigned *readval)
> @@ -753,7 +835,7 @@ static int vf610_adc_probe(struct platform_device *pdev)
>  
>  	ret = devm_request_irq(info->dev, irq,
>  				vf610_adc_isr, 0,
> -				dev_name(&pdev->dev), info);
> +				dev_name(&pdev->dev), indio_dev);
>  	if (ret < 0) {
>  		dev_err(&pdev->dev, "failed requesting irq, irq = %d\n", irq);
>  		return ret;
> @@ -806,15 +888,23 @@ static int vf610_adc_probe(struct platform_device *pdev)
>  	vf610_adc_cfg_init(info);
>  	vf610_adc_hw_init(info);
>  
> +	ret = iio_triggered_buffer_setup(indio_dev, &iio_pollfunc_store_time,
> +					NULL, &iio_triggered_buffer_setup_ops);
> +	if (ret < 0) {
> +		dev_err(&pdev->dev, "Couldn't initialise the buffer\n");
> +		goto error_iio_device_register;
> +	}
> +
>  	ret = iio_device_register(indio_dev);
>  	if (ret) {
>  		dev_err(&pdev->dev, "Couldn't register the device.\n");
> -		goto error_iio_device_register;
> +		goto error_adc_buffer_init;
>  	}
>  
>  	return 0;
>  
> -
> +error_adc_buffer_init:
> +	iio_triggered_buffer_cleanup(indio_dev);
>  error_iio_device_register:
>  	clk_disable_unprepare(info->clk);
>  error_adc_clk_enable:
> @@ -829,6 +919,7 @@ static int vf610_adc_remove(struct platform_device *pdev)
>  	struct vf610_adc *info = iio_priv(indio_dev);
>  
>  	iio_device_unregister(indio_dev);
> +	iio_triggered_buffer_cleanup(indio_dev);
>  	regulator_disable(info->vref);
>  	clk_disable_unprepare(info->clk);
>  
> -- 
> 2.5.0
> 


From maxime.ripard at free-electrons.com  Wed Aug 19 23:43:05 2015
From: maxime.ripard at free-electrons.com (Maxime Ripard)
Date: Thu, 20 Aug 2015 08:43:05 +0200
Subject: [PATCH 1/6] ARM: dts: sun5i: Add simplefb node for tvencoder
 output
In-Reply-To: <1439563477-12295-2-git-send-email-hdegoede@redhat.com>
References: <1439563477-12295-1-git-send-email-hdegoede@redhat.com>
 <1439563477-12295-2-git-send-email-hdegoede@redhat.com>
Message-ID: <20150820064305.GK30520@lukather>

Hi, 

On Fri, Aug 14, 2015 at 04:44:32PM +0200, Hans de Goede wrote:
> Add a simplefb node for tvencoder / composite-video output, such as found
> on the Auxtek-T003 and the CHIP.
> 
> Signed-off-by: Hans de Goede <hdegoede at redhat.com>

Queued, thanks!

I guess the CHIP will have to have the same change for the A13 DTSI.

Maxime

-- 
Maxime Ripard, Free Electrons
Embedded Linux, Kernel and Android engineering
http://free-electrons.com
-------------- next part --------------
A non-text attachment was scrubbed...
Name: signature.asc
Type: application/pgp-signature
Size: 819 bytes
Desc: Digital signature
URL: <http://lists.infradead.org/pipermail/linux-arm-kernel/attachments/20150820/e5078225/attachment.sig>

From maxime.ripard at free-electrons.com  Wed Aug 19 23:44:07 2015
From: maxime.ripard at free-electrons.com (Maxime Ripard)
Date: Thu, 20 Aug 2015 08:44:07 +0200
Subject: [PATCH 3/6] ARM: dts: sun7i: Add regulator configuration to the
 pcduino3 dts file
In-Reply-To: <1439563477-12295-4-git-send-email-hdegoede@redhat.com>
References: <1439563477-12295-1-git-send-email-hdegoede@redhat.com>
 <1439563477-12295-4-git-send-email-hdegoede@redhat.com>
Message-ID: <20150820064407.GL30520@lukather>

On Fri, Aug 14, 2015 at 04:44:34PM +0200, Hans de Goede wrote:
> From: Jelle van der Waa <jelle at vdwaa.nl>
> 
> Add regulator configuration to the pcduino3 dts file.
> 
> Signed-off-by: Jelle van der Waa <jelle at vdwaa.nl>
> Signed-off-by: Hans de Goede <hdegoede at redhat.com>

Queued, thanks!

Maxime

-- 
Maxime Ripard, Free Electrons
Embedded Linux, Kernel and Android engineering
http://free-electrons.com
-------------- next part --------------
A non-text attachment was scrubbed...
Name: signature.asc
Type: application/pgp-signature
Size: 819 bytes
Desc: Digital signature
URL: <http://lists.infradead.org/pipermail/linux-arm-kernel/attachments/20150820/53c09db3/attachment.sig>

From herbert at gondor.apana.org.au  Wed Aug 19 23:44:26 2015
From: herbert at gondor.apana.org.au (Herbert Xu)
Date: Thu, 20 Aug 2015 14:44:26 +0800
Subject: un4i-ss-cipher.c warning
In-Reply-To: <20150820063900.GJ30520@lukather>
References: <CAOMqctShdb9xEkBmuaQKfB1cwGupbfH5TS5ZB_P85Hwpn+4zAA@mail.gmail.com>
 <20150820052903.GA26031@gondor.apana.org.au>
 <20150820063900.GJ30520@lukather>
Message-ID: <20150820064426.GA26787@gondor.apana.org.au>

On Thu, Aug 20, 2015 at 08:39:00AM +0200, Maxime Ripard wrote:
>
> Not in the dev_dbg call line 258. If ileft was negative or null, todo
> isn't assigned to anything.

If ileft starts out being <= 0, then oleft == ileft will also be
<= 0, in which case the loop never executes.

Cheers,
-- 
Email: Herbert Xu <herbert at gondor.apana.org.au>
Home Page: http://gondor.apana.org.au/~herbert/
PGP Key: http://gondor.apana.org.au/~herbert/pubkey.txt


From maxime.ripard at free-electrons.com  Wed Aug 19 23:45:45 2015
From: maxime.ripard at free-electrons.com (Maxime Ripard)
Date: Thu, 20 Aug 2015 08:45:45 +0200
Subject: [PATCH 4/6] ARM: dts: sun7i: Enable USB DRC on pcDuino 3
In-Reply-To: <1439563477-12295-5-git-send-email-hdegoede@redhat.com>
References: <1439563477-12295-1-git-send-email-hdegoede@redhat.com>
 <1439563477-12295-5-git-send-email-hdegoede@redhat.com>
Message-ID: <20150820064545.GM30520@lukather>

On Fri, Aug 14, 2015 at 04:44:35PM +0200, Hans de Goede wrote:
> From: Jelle van der Waa <jelle at vdwaa.nl>
> 
> Enable the otg/drc usb controller on the pcDuino 3.
> 
> Note this board has the otg-vbus connected directly to the 5v-dcc of
> the board, so there is no vbus0 regulator, nor vbus0-det.

Can it do OTG then? If VBUS is tied to the 5v, there's no way for the
board to shut it down when acting as peripheral, right?

Maxime

-- 
Maxime Ripard, Free Electrons
Embedded Linux, Kernel and Android engineering
http://free-electrons.com
-------------- next part --------------
A non-text attachment was scrubbed...
Name: signature.asc
Type: application/pgp-signature
Size: 819 bytes
Desc: Digital signature
URL: <http://lists.infradead.org/pipermail/linux-arm-kernel/attachments/20150820/b32cc8e0/attachment-0001.sig>

From maxime.ripard at free-electrons.com  Wed Aug 19 23:47:12 2015
From: maxime.ripard at free-electrons.com (Maxime Ripard)
Date: Thu, 20 Aug 2015 08:47:12 +0200
Subject: [PATCH 6/6] ARM: dts: sun8i: Add support for qt90h-v4 tablets
In-Reply-To: <1439563477-12295-7-git-send-email-hdegoede@redhat.com>
References: <1439563477-12295-1-git-send-email-hdegoede@redhat.com>
 <1439563477-12295-7-git-send-email-hdegoede@redhat.com>
Message-ID: <20150820064712.GN30520@lukather>

On Fri, Aug 14, 2015 at 04:44:37PM +0200, Hans de Goede wrote:
> The gt90h is a pcb found in generic 9" tablets with an A23 soc, 1G RAM
> and 8G nand, rtl8723as usb wifi, 1 micro usb port and 1 micro sd slot.
> 
> This commit adds a dts for v4 of the gt90h pcb.
> 
> Signed-off-by: Hans de Goede <hdegoede at redhat.com>

Applied, thanks!

Maxime

-- 
Maxime Ripard, Free Electrons
Embedded Linux, Kernel and Android engineering
http://free-electrons.com
-------------- next part --------------
A non-text attachment was scrubbed...
Name: signature.asc
Type: application/pgp-signature
Size: 819 bytes
Desc: Digital signature
URL: <http://lists.infradead.org/pipermail/linux-arm-kernel/attachments/20150820/2ff0c2cc/attachment.sig>

From gpkulkarni at gmail.com  Wed Aug 19 23:50:29 2015
From: gpkulkarni at gmail.com (Ganapatrao Kulkarni)
Date: Thu, 20 Aug 2015 12:20:29 +0530
Subject: [PATCH v5 0/8] arm64, numa: Add numa support for arm64 platforms.
In-Reply-To: <CAFpQJXXXFmWE5rk9=KW_Vg0B9aA+Cd_6YQOeiCZ21Q61cSQ+ew@mail.gmail.com>
References: <1439570374-4079-1-git-send-email-gkulkarni@caviumnetworks.com>
 <CAFpQJXXXFmWE5rk9=KW_Vg0B9aA+Cd_6YQOeiCZ21Q61cSQ+ew@mail.gmail.com>
Message-ID: <CAFpQJXVtAq9SG5qoRHYE-18tS+LaU7Fid1yBvx=-UFRjdnVrfQ@mail.gmail.com>

Hi Maintainers,


On Fri, Aug 14, 2015 at 10:14 PM, Ganapatrao Kulkarni
<gpkulkarni at gmail.com> wrote:
> On Fri, Aug 14, 2015 at 10:09 PM, Ganapatrao Kulkarni
> <gkulkarni at caviumnetworks.com> wrote:
>> v5:
>>         - created base verion of numa.c which creates dummy numa without using dt
>>           on single socket platforms. Then added patches for dt support.
>>         - Incorporated review comments from Hanjun Guo.
>>
>> v4:
>> done changes as per Arnd review comments.
>>
>> v3:
>> Added changes to support numa on arm64 based platforms.
>> Tested these patches on cavium's multinode(2 node topology) platform.
>> In this patchset, defined and implemented dt bindings for numa mapping
>> for core and memory using device node property arm,associativity.
>>
>> v2:
>> Defined and implemented numa map for memory, cores to node and
>> proximity distance matrix of nodes.
>>
>> v1:
>> Initial patchset to support numa on arm64 platforms.
>>
>> Note:
>>         1. This patchset is tested for numa with dt on
>>            thunderx single socket and dual socket boards.
>>         2. Numa DT booting needs the dt memory nodes, which are deleted in current efi-stub,
>>         hence to try numa with dt, you need to rebase with ard's patchset.
>>         http://git.linaro.org/people/ard.biesheuvel/linux-arm.git/shortlog/refs/heads/arm64-uefi-early-fdt-handling
>>
>>
>> Ganapatrao Kulkarni (4):
>>   arm64, numa: adding numa support for arm64 platforms.
>>   Documentation: arm64/arm: dt bindings for numa.
>>   arm64, numa: adding numa support for arm64 platforms.
>>   arm64, dt, thunderx: Add initial dts for Cavium Thunder SoC in 2 Node
>>     topology.
>>
>>  Documentation/devicetree/bindings/arm/numa.txt  | 212 +++++++
>>  arch/arm64/Kconfig                              |  32 +
>>  arch/arm64/boot/dts/cavium/Makefile             |   2 +-
>>  arch/arm64/boot/dts/cavium/thunder-88xx-2n.dts  |  78 +++
>>  arch/arm64/boot/dts/cavium/thunder-88xx-2n.dtsi | 790 ++++++++++++++++++++++++
>>  arch/arm64/include/asm/mmzone.h                 |  32 +
>>  arch/arm64/include/asm/numa.h                   |  49 ++
>>  arch/arm64/kernel/Makefile                      |   1 +
>>  arch/arm64/kernel/dt_numa.c                     | 316 ++++++++++
>>  arch/arm64/kernel/setup.c                       |   9 +
>>  arch/arm64/kernel/smp.c                         |   3 +
>>  arch/arm64/mm/Makefile                          |   1 +
>>  arch/arm64/mm/init.c                            |  34 +-
>>  arch/arm64/mm/numa.c                            | 563 +++++++++++++++++
>>  14 files changed, 2115 insertions(+), 7 deletions(-)
>>  create mode 100644 Documentation/devicetree/bindings/arm/numa.txt
>>  create mode 100644 arch/arm64/boot/dts/cavium/thunder-88xx-2n.dts
>>  create mode 100644 arch/arm64/boot/dts/cavium/thunder-88xx-2n.dtsi
>>  create mode 100644 arch/arm64/include/asm/mmzone.h
>>  create mode 100644 arch/arm64/include/asm/numa.h
>>  create mode 100644 arch/arm64/kernel/dt_numa.c
>>  create mode 100644 arch/arm64/mm/numa.c
>>
>> --
>> 1.8.1.4
>>
> sorry, minor correction, this patchset has 4 patches.
>
> PATCH v5 0/8 => PATCH v5 0/4

please review this patchset.

thanks
Ganapat


From fugang.duan at freescale.com  Wed Aug 19 23:50:53 2015
From: fugang.duan at freescale.com (Duan Andy)
Date: Thu, 20 Aug 2015 06:50:53 +0000
Subject: [PATCH v4] iio: adc: vf610: Add IIO buffer support for Vybrid ADC
In-Reply-To: <9be567ec7d6f6370dd42a41438d64cf7aaa47635.1439826018.git.maitysanchayan@gmail.com>
References: <d556443a26070be505f9a5f5f0999253b73d9b71.1439283162.git.maitysanchayan@gmail.com>
 <9be567ec7d6f6370dd42a41438d64cf7aaa47635.1439826018.git.maitysanchayan@gmail.com>
Message-ID: <BN3PR0301MB121977040608F337E69ADADEF5660@BN3PR0301MB1219.namprd03.prod.outlook.com>

From: Sanchayan Maity <maitysanchayan at gmail.com> Sent: Monday, August 17, 2015 11:52 PM
> To: jic23 at kernel.org; linux-iio at vger.kernel.org
> Cc: stefan at agner.ch; Duan Fugang-B38611; pmeerw at pmeerw.net; linux-
> kernel at vger.kernel.org; linux-arm-kernel at lists.infradead.org; Sanchayan
> Maity
> Subject: [PATCH v4] iio: adc: vf610: Add IIO buffer support for Vybrid
> ADC
> 
> This patch adds support for IIO buffer to the Vybrid ADC driver.
> IIO triggered buffer infrastructure along with iio sysfs trigger is used
> to leverage continuous sampling support provided by the ADC block.
> 
> Signed-off-by: Sanchayan Maity <maitysanchayan at gmail.com>
> ---
> 
> Changes since v3:
> Fix iio_buffer_setup_ops for postenable and predisable functions to match
> pairwise. Before this the predisable work was being done in postdisable.
> 
> Changes since v2:
> 1. Fix the wrong buffer size for statically allocated buffer 2. Drop the
> use of .address field from the iio_chan_spec 3. Use iio_buffer_enabled
> call inside the lock 4. Drop wrapper function around iio_trigered_*
> function calls 5. Drop Kconfig select of sysfs trigger 6. Drop Kconfig
> select IIO_TRIGGER as it is already selected by IIO_TRIGGERED_BUFFER
> 
> Changes since v1:
> 1. Use a fixed size buffer instead of kmalloc allocated during update
> scan mode 2. Remove a write to read only register ADC_HS (COCO bit)
> 
>  drivers/iio/adc/Kconfig     |   2 +
>  drivers/iio/adc/vf610_adc.c | 105
> +++++++++++++++++++++++++++++++++++++++++---
>  2 files changed, 100 insertions(+), 7 deletions(-)
> 

The version is fine for me. Thanks for your effort.

Acked-by: Fugang Duan <B38611 at freescale.com>


From rsahu at apm.com  Wed Aug 19 23:53:50 2015
From: rsahu at apm.com (Rameshwar Sahu)
Date: Thu, 20 Aug 2015 12:23:50 +0530
Subject: [PATCH v1 2/4] dmaengine: xgene-dma: Add support for CRC32C
 calculation via DMA engine
In-Reply-To: <20150820054034.GX13546@localhost>
References: <1438258268-3099-1-git-send-email-rsahu@apm.com>
 <1438258268-3099-3-git-send-email-rsahu@apm.com>
 <20150820054034.GX13546@localhost>
Message-ID: <CAFd313y3vTCzaGKY7ZVyFGDiSx+KuxQHyBwqKyB+xWfR5dtVSA@mail.gmail.com>

Hi Vinod,

On Thu, Aug 20, 2015 at 11:10 AM, Vinod Koul <vinod.koul at intel.com> wrote:
> On Thu, Jul 30, 2015 at 05:41:06PM +0530, Rameshwar Prasad Sahu wrote:
>> +     /* Invalidate unused source address field */
>> +     for (; i < 4; i++)
>> +             xgene_dma_invalidate_buffer(xgene_dma_lookup_ext8(desc2, i));
>> +
>> +     /* Check whether requested buffer processed */
>> +     if (nbytes) {
>> +             chan_err(chan, "Src count crossed maximum limit\n");
>> +             return -EINVAL;
> no cleanup ?
Here not required, cleanup I am doing in parent function from where
this function is getting called in case of failure.
>
>> +struct dma_async_tx_descriptor *xgene_dma_prep_flyby(
>> +     struct xgene_dma_chan *chan, struct scatterlist *src_sg,
>> +     size_t len, u32 seed, u8 *result, unsigned long flags, u8 opcode)
> please fix style here

Could you explain me What kind of coding style you would like here ??
>
>> +struct dma_async_tx_descriptor *xgene_dma_prep_crc32c(
>> +     struct dma_chan *dchan, struct scatterlist *src_sg,
>> +     size_t len, u32 seed, u8 *result, unsigned long flags)
> here too
>
>> @@ -1309,8 +1512,13 @@ static void xgene_dma_setup_ring(struct xgene_dma_ring *ring)
>>                 ring->pdma->csr_ring + XGENE_DMA_RING_ID);
>>
>>       /* Set DMA ring buffer */
>> -     iowrite32(XGENE_DMA_RING_ID_BUF_SETUP(ring->num),
>> -               ring->pdma->csr_ring + XGENE_DMA_RING_ID_BUF);
>> +     ring_id_buf = XGENE_DMA_RING_ID_BUF_SETUP(ring->num);
>> +
>> +     if (ring->is_bufpool)
>> +             ring_id_buf |= XGENE_DMA_RING_IS_BUFPOOL;
>> +
>> +     iowrite32(ring_id_buf, ring->pdma->csr_ring +
>> +               XGENE_DMA_RING_ID_BUF);
> pls fix style here
I didn't see any alignment issue here, just follow checkpatch that
argument should start just after "function(" in next line also.
>
> --
> ~Vinod


From jingoohan1 at gmail.com  Wed Aug 19 23:55:13 2015
From: jingoohan1 at gmail.com (Jingoo Han)
Date: Thu, 20 Aug 2015 15:55:13 +0900
Subject: [PATCH v3 0/14] Add Analogix Core Display Port Driver
In-Reply-To: <55D5727C.8000109@rock-chips.com>
References: <1439995728-18046-1-git-send-email-ykk@rock-chips.com>
 <55D557BD.8070004@codeaurora.org>
 <58DB3289-29F0-4C2D-97F6-EB0555392DF2@gmail.com>
 <55D5727C.8000109@rock-chips.com>
Message-ID: <4EDBEF7E-31F4-45EF-960C-A7C47C650E49@gmail.com>

On 2015. 8. 20., at PM 3:23, Yakir Yang <ykk at rock-chips.com> wrote:
> 
> Hi Jingoo & Archit,
> 
> 
>> On 08/20/2015 12:54 AM, Jingoo Han wrote:
>>> On 2015. 8. 20., at PM 1:29, Archit Taneja <architt at codeaurora.org> wrote:
>>> Hi,
>>> 
>>>> On 08/19/2015 08:18 PM, Yakir Yang wrote:
>>>> 
>>>> Hi all,
>>>>    The Samsung Exynos eDP controller and Rockchip RK3288 eDP controller
>>>> share the same IP, so a lot of parts can be re-used. I split the common
>>>> code into bridge directory, then rk3288 and exynos only need to keep
>>>> some platform code. Cause I can't find the exact IP name of exynos dp
>>>> controller, so I decide to name dp core driver with "analogix" which I
>>>> find in rk3288 eDP TRM ;)
>>>> 
>>>> Beyond that, there are three light registers setting differents bewteen
>>>> exynos and rk3288.
>>>> 1. RK3288 have five special pll resigters which not indicata in exynos
>>>>    dp controller.
>>>> 2. The address of DP_PHY_PD(dp phy power manager register) are different
>>>>    between rk3288 and exynos.
>>>> 3. Rk3288 and exynos have different setting with AUX_HW_RETRY_CTL(dp debug
>>>>    register).
>>>> 
>>>> I have verified this series on two kinds of rockchip platform board, one
>>>> is rk3288 sdk board which connect with a 2K display port monitor, the other
>>>> is google jerry chromebook which connect with a eDP screen "cnm,n116bgeea2",
>>>> both of them works rightlly.
>>>> 
>>>> I haven't verified the dp function on samsung platform, cause I haven't got
>>>> exynos boards. I can only ensure that there are no build error on samsung
>>>> platform, wish some samsung guys help to test. ;)
>>>> 
>>>> Thanks,
>>>> - Yakir
>>>> 
>>>> Changes in v3:
>>>> - Take Thierry Reding suggest, move exynos's video_timing code
>>>>   to analogix_dp-exynos platform driver, add get_modes method
>>>>   to struct analogix_dp_plat_data.
>>>> - Take Heiko suggest, rename some "samsung*" dts propery to "analogix*".
>>>> - Take Thierry Reding suggest, dynamic parse video timing info from
>>>>   struct drm_display_mode and struct drm_display_info.
>>>> - Take Thierry Reding suggest, link_rate and lane_count shouldn't config to
>>>>   the DT property value directly, but we can take those as hardware limite.
>>>>   For example, RK3288 only support 4 physical lanes of 2.7/1.62 Gbps/lane,
>>>>   so DT property would like "link-rate = 0x0a" "lane-count = 4".
>>>> - Take Heiko suggest, add devicetree binding documents.
>>>> - Take Thierry Reding suggest, remove sync pol & colorimetry properies
>>>>   from the new analogix dp driver devicetree binding.
>>>> - Update the exist exynos dtsi file with the latest DP DT properies.
>>>> - Take Thierry Reding and Heiko suggest, leave "sclk_edp_24m" to rockchip
>>>>   dp phy driver which name to "24m", and leave "sclk_edp" to analogix dp
>>>>   core driver which name to "dp", and leave "pclk_edp" to rockchip dp platform
>>>>   driver which name to "pclk".
>>>> - Take Heiko suggest, add devicetree binding document.
>>>> - Take Heiko suggest, remove "rockchip,panel" DT property, take use of remote
>>>>   point to get panel node.
>>>> - Add the new function point analogix_dp_platdata.get_modes init.
>>>> - Take Heiko suggest, add rockchip dp phy driver,
>>>>   collect the phy clocks and power control.
>>>> - Add "analogix,need-force-hpd" to indicate whether driver need foce
>>>>   hpd when hpd detect failed.
>>>> - move dp hpd detect to connector detect function.
>>>> - Add edid modes parse support
>>>> 
>>>> Changes in v2:
>>>> - Take Joe Preches advise, improved commit message more readable, and
>>>>   avoid using some uncommon style like bellow:
>>>>   -  retval = exynos_dp_read_bytes_from_i2c(...
>>>>                ...)
>>>>   +  retval =
>>>>   +  exynos_dp_read_bytes_from_i2c(......);
>>>> - Take Jingoo Han suggest, just remove my name from author list.
>>>> - Take Jingoo Han suggest, remove new copyright
>>>> - Fix compiled failed dut to analogix_dp_device misspell
>>>> - Take Heiko suggest, get panel node with remote-endpoint method,
>>>>   and create devicetree binding for driver.
>>>> - Remove the clock enable/disbale with "sclk_edp" & "sclk_edp_24m",
>>>>   leave those clock to rockchip dp phy driver.
>>>> - Add GNU license v2 declared and samsung copyright
>>>> - Fix compile failed dut to phy_pd_addr variable misspell error
>>>> 
>>>> Yakir Yang (14):
>>>>   drm: exynos/dp: fix code style
>>>>   drm: exynos/dp: convert to drm bridge mode
>>>>   drm: bridge: analogix_dp: split exynos dp driver to bridge dir
>>>>   drm: bridge/analogix_dp: dynamic parse sync_pol & interlace &
>>>>     colorimetry
>>>>   drm: bridge/analogix_dp: fix link_rate & lane_count bug
>>>>   Documentation: drm/bridge: add document for analogix_dp
>>>>   drm: rockchip/dp: add rockchip platform dp driver
>>>>   phy: Add driver for rockchip Display Port PHY
>>>>   drm: bridge/analogix_dp: add platform device type support
>>>>   drm: bridge: analogix_dp: add some rk3288 special registers setting
>>>>   drm: bridge: analogix_dp: try force hpd after plug in lookup failed
>>>>   drm: bridge/analogix_dp: expand the delay time for hpd detect
>>>>   drm: bridge/analogix_dp: move hpd detect to connector detect function
>>>>   drm: bridge/analogix_dp: add edid modes parse in get_modes method
>>>> 
>>>>  .../devicetree/bindings/drm/bridge/analogix_dp.txt |   73 +
>>>>  .../devicetree/bindings/phy/rockchip-dp-phy.txt    |   26 +
>>>>  .../bindings/video/analogix_dp-rockchip.txt        |   83 ++
>>>>  .../devicetree/bindings/video/exynos_dp.txt        |   51 +-
>>>>  arch/arm/boot/dts/exynos5250-arndale.dts           |   10 +-
>>>>  arch/arm/boot/dts/exynos5250-smdk5250.dts          |   10 +-
>>>>  arch/arm/boot/dts/exynos5250-snow.dts              |   12 +-
>>>>  arch/arm/boot/dts/exynos5250-spring.dts            |   12 +-
>>>>  arch/arm/boot/dts/exynos5420-peach-pit.dts         |   12 +-
>>>>  arch/arm/boot/dts/exynos5420-smdk5420.dts          |   10 +-
>>>>  arch/arm/boot/dts/exynos5800-peach-pi.dts          |   12 +-
>>>>  drivers/gpu/drm/bridge/Kconfig                     |    5 +
>>>>  drivers/gpu/drm/bridge/Makefile                    |    1 +
>>>>  drivers/gpu/drm/bridge/analogix_dp_core.c          | 1382 +++++++++++++++++++
>>>>  drivers/gpu/drm/bridge/analogix_dp_core.h          |  286 ++++
>>>>  drivers/gpu/drm/bridge/analogix_dp_reg.c           | 1294 ++++++++++++++++++
>>>>  .../exynos_dp_reg.h => bridge/analogix_dp_reg.h}   |  270 ++--
>>>>  drivers/gpu/drm/exynos/Kconfig                     |    5 +-
>>>>  drivers/gpu/drm/exynos/Makefile                    |    2 +-
>>>>  drivers/gpu/drm/exynos/analogix_dp-exynos.c        |  347 +++++
>>>>  drivers/gpu/drm/exynos/exynos_dp_core.c            | 1416 --------------------
>>>>  drivers/gpu/drm/exynos/exynos_dp_core.h            |  282 ----
>>>>  drivers/gpu/drm/exynos/exynos_dp_reg.c             | 1263 -----------------
>>>>  drivers/gpu/drm/rockchip/Kconfig |    9 +
>>>>  drivers/gpu/drm/rockchip/Makefile                  |    1 +
>>>>  drivers/gpu/drm/rockchip/analogix_dp-rockchip.c    |  390 ++++++
>>>>  drivers/phy/Kconfig                                |    7 +
>>>>  drivers/phy/Makefile                               |    1 +
>>>>  drivers/phy/phy-rockchip-dp.c                      |  185 +++
>>>>  include/drm/bridge/analogix_dp.h |   40 +
>>>>  30 files changed, 4325 insertions(+), 3172 deletions(-)
>>>>  create mode 100644 Documentation/devicetree/bindings/drm/bridge/analogix_dp.txt
>>>>  create mode 100644 Documentation/devicetree/bindings/phy/rockchip-dp-phy.txt
>>>>  create mode 100644 Documentation/devicetree/bindings/video/analogix_dp-rockchip.txt
>>>>  create mode 100644 drivers/gpu/drm/bridge/analogix_dp_core.c
>>>>  create mode 100644 drivers/gpu/drm/bridge/analogix_dp_core.h
>>>>  create mode 100644 drivers/gpu/drm/bridge/analogix_dp_reg.c
>>> Minor comment: Since there are a few files required for the driver,
>>> could you create a separate folder within drivers/gpu/drm/bridge?
>> I agree on this opinion.
>> Thank you.
> 
> Thanks for your comment ;)
> 
> Yeah, bridge/ have been add four new files for this driver, it would be better to
> collect into a separate folder.
> 
> I'm wondering should I just name the folder with "analogix_dp/", or we can make
> it more common (like "analogix/")? (personally I do like the last one)

I prefer "analogix".

Best regards,
Jingoo Han

> Thanks,
> - Yakir
>> Best regards,
>> Jingoo Han
>> 
>>> Thanks,
>>> Archit
>>> 
>>> -- 
>>> Qualcomm Innovation Center, Inc. is a member of Code Aurora Forum,
>>> a Linux Foundation Collaborative Project
> 
> 


From manabian at gmail.com  Wed Aug 19 23:58:37 2015
From: manabian at gmail.com (Joachim Eastwood)
Date: Thu, 20 Aug 2015 08:58:37 +0200
Subject: [PATCH 5/5] drivers/tty: make serial 8250_lpc18xx.c Kconfig a
 tristate
In-Reply-To: <1440020889-12120-6-git-send-email-paul.gortmaker@windriver.com>
References: <1440020889-12120-1-git-send-email-paul.gortmaker@windriver.com>
 <1440020889-12120-6-git-send-email-paul.gortmaker@windriver.com>
Message-ID: <CAGhQ9VzWBq=gqHhkhfm+2MwaOHDzLKDLo8v1CJX3N-xiZnCv=g@mail.gmail.com>

On 19 August 2015 at 23:48, Paul Gortmaker <paul.gortmaker at windriver.com> wrote:
> The Kconfig currently controlling compilation of this code is:
>
> 8250/Kconfig:config SERIAL_8250_LPC18XX
> 8250/Kconfig:        bool "NXP LPC18xx/43xx serial port support"
>
> ...meaning that it currently is not being built as a module by anyone.
>
> When targetting orphaned modular code in non-modular drivers, this
> came up.  Joachim indicated that the driver was actually meant to
> be tristate but ended up bool by accident.  So here we make it
> tristate instead of removing the modular code that was essentially
> orphaned.
>
> Suggested-by: Joachim Eastwood <manabian at gmail.com>
> Cc: Greg Kroah-Hartman <gregkh at linuxfoundation.org>
> Cc: Jiri Slaby <jslaby at suse.com>
> Cc: Joachim Eastwood <manabian at gmail.com>
> Cc: linux-serial at vger.kernel.org
> Cc: linux-arm-kernel at lists.infradead.org
> Signed-off-by: Paul Gortmaker <paul.gortmaker at windriver.com>

Acked-by: Joachim Eastwood <manabian at gmail.com>

Build tested as a module on lpc18xx.

Thanks for fixing it Paul.


regards,
Joachim Eastwood


From rsahu at apm.com  Thu Aug 20 00:01:44 2015
From: rsahu at apm.com (Rameshwar Sahu)
Date: Thu, 20 Aug 2015 12:31:44 +0530
Subject: [PATCH v1 3/4] Crypto: Add support for APM X-Gene SoC CRC32C h/w
 accelerator driver
In-Reply-To: <20150820054828.GY13546@localhost>
References: <1438258268-3099-1-git-send-email-rsahu@apm.com>
 <1438258268-3099-4-git-send-email-rsahu@apm.com>
 <20150820054828.GY13546@localhost>
Message-ID: <CAFd313xG2_4NGHspuJwThY=jUSPiBm3egvXVvhv8XxKctgMv1A@mail.gmail.com>

Hi Vinod,

On Thu, Aug 20, 2015 at 11:18 AM, Vinod Koul <vinod.koul at intel.com> wrote:
> On Thu, Jul 30, 2015 at 05:41:07PM +0530, Rameshwar Prasad Sahu wrote:
>> +     nents = sg_nents(req->src);
>> +     sg_count = dma_map_sg(dev, req->src, nents, DMA_TO_DEVICE);
>> +     if (!sg_count) {
>> +             dev_err(dev, "Failed to map src sg");
>> +             return -ENOMEM;
> mapping error shouldn't be no mem error
Okay, I guess then -EIO will be fine here??
>
>> +     }
>> +
>> +     if (sg_count > XGENE_DMA_MAX_FLYBY_SRC_CNT) {
>> +             dev_err(dev, "Unsupported src sg len\n");
> would be worth printing length
Okay,
>
>> +             goto err;
>> +     }
>> +
>> +     flags = DMA_CTRL_ACK;
> why ACK?
My understanding about DMA_CTRL_ACK is dma engine driver can
re-use/free this descriptor once operation completed in cleanup path.
Am I correct ??
But yes, I need to look on this because recently you have added one
more descriptor flag.

>
>> +
>> +     tx = dchan->device->device_prep_dma_crc32c(dchan, req->src,
>> +                                                req->nbytes,
>> +                                                reqctx->seed,
>> +                                                req->result,
>> +                                                flags);
> We should add helper for this
Okay
>
> --
> ~Vinod
>


From appana.durga.rao at xilinx.com  Thu Aug 20 00:01:52 2015
From: appana.durga.rao at xilinx.com (Appana Durga Kedareswara Rao)
Date: Thu, 20 Aug 2015 07:01:52 +0000
Subject: [RESEND PATCH] dmaengine: Add Xilinx AXI Direct Memory Access
 Engine driver support
In-Reply-To: <C246CAC1457055469EF09E3A7AC4E11A4A4B2BBC@XAP-PVEXMBX01.xlnx.xilinx.com>
References: <1439825512-16444-1-git-send-email-appanad@xilinx.com>
 <CAAtXAHf9S662okN1gchbD246=e4_bMFoyBMrbt5q48xm1uo_CA@mail.gmail.com>
 <C246CAC1457055469EF09E3A7AC4E11A4A4B2BBC@XAP-PVEXMBX01.xlnx.xilinx.com>
Message-ID: <C246CAC1457055469EF09E3A7AC4E11A4A4B2C48@XAP-PVEXMBX01.xlnx.xilinx.com>

Hi ,

> -----Original Message-----
> From: dmaengine-owner at vger.kernel.org [mailto:dmaengine-
> owner at vger.kernel.org] On Behalf Of Appana Durga Kedareswara Rao
> Sent: Thursday, August 20, 2015 11:11 AM
> To: Moritz Fischer
> Cc: vinod.koul at intel.com; dan.j.williams at intel.com; Michal Simek; Soren
> Brinkmann; anirudha at xilinx.com; dmaengine at vger.kernel.org; linux-
> kernel at vger.kernel.org; linux-arm-kernel
> Subject: RE: [RESEND PATCH] dmaengine: Add Xilinx AXI Direct Memory Access
> Engine driver support
> 
> Hi Moritz Fischer,
> 
> 	Thanks for reviewing the patch.
> 
> > -----Original Message-----
> > From: Moritz Fischer [mailto:moritz.fischer at ettus.com]
> > Sent: Thursday, August 20, 2015 3:21 AM
> > To: Appana Durga Kedareswara Rao
> > Cc: vinod.koul at intel.com; dan.j.williams at intel.com; Michal Simek;
> > Soren Brinkmann; Appana Durga Kedareswara Rao; anirudha at xilinx.com;
> > dmaengine at vger.kernel.org; linux-kernel at vger.kernel.org;
> > linux-arm-kernel; Srikanth Thokala
> > Subject: Re: [RESEND PATCH] dmaengine: Add Xilinx AXI Direct Memory
> > Access Engine driver support
> >
> > Hi there,
> >
> > see comment below. I just did a quick compile test. Will take another
> > look once I synthesized an image.
> >
> > On Mon, Aug 17, 2015 at 8:31 AM, Kedareswara rao Appana
> > <appana.durga.rao at xilinx.com> wrote:
> > > This is the driver for the AXI Direct Memory Access (AXI DMA) core,
> > > which is a soft Xilinx IP core that provides high- bandwidth direct
> > > memory access between memory and AXI4-Stream type target peripherals.
> > >
> > > Signed-off-by: Srikanth Thokala <sthokal at xilinx.com>
> > > Signed-off-by: Kedareswara rao Appana <appanad at xilinx.com>
> > > ---
> > > The deivce tree doc got applied in the slave-dmaengine.git.
> > >
> > > Forgot to include dmaengine at vger.kernel.org in the cc list resending
> > > the patch.
> > >
> > > Changes in v8:
> > > - Updated the SG handling as suggested by Nicolae Rosia.
> > > - Removed the unnecessary xilinx_dma_channel_set_config API the
> properties
> > >   in this API is not being used by the driver.
> > > Changes in v7:
> > > - Updated license in the driver as suggested by Paul.
> > > - Corrected return value in is_idle funtion.
> > > Changes in v6:
> > > - Fixed Odd indention in the Kconfig.
> > > - used GFP_NOWAIT instead of GFP_KERNEL during the desc allocation
> > > - Calculated residue in the tx_status instead of complete_descriptor.
> > > - Update copy right to 2015.
> > > - Modified spin_lock handling moved the spin_lock to the appropriate
> > > functions (instead of xilinx_dma_start_transfer doing it
> > xilinx_dma_issue_pending api).
> > > - device_control and declare slave caps updated as per newer APi's.
> > > Changes in v5:
> > > - Modified the xilinx_dma.h header file location to the
> > >   include/linux/dma/xilinx_dma.h
> > > Changes in v4:
> > > - Add direction field to DMA descriptor structure and removed from
> > >   channel structure to avoid duplication.
> > > - Check for DMA idle condition before changing the configuration.
> > > - Residue is being calculated in complete_descriptor() and is reported
> > >   to slave driver.
> > > Changes in v3:
> > > - Rebased on 3.16-rc7
> > > Changes in v2:
> > > - Simplified the logic to set SOP and APP words in prep_slave_sg().
> > > - Corrected function description comments to match the return type.
> > > - Fixed some minor comments as suggested by Andy.
> > >
> > >  drivers/dma/Kconfig             |   13 +
> > >  drivers/dma/xilinx/Makefile     |    1 +
> > >  drivers/dma/xilinx/xilinx_dma.c | 1179
> > > +++++++++++++++++++++++++++++++++++++++
> > >  3 files changed, 1193 insertions(+)  create mode 100644
> > > drivers/dma/xilinx/xilinx_dma.c
> > >
> > > diff --git a/drivers/dma/Kconfig b/drivers/dma/Kconfig index
> > > 88d474b..5e95f07 100644
> > > --- a/drivers/dma/Kconfig
> > > +++ b/drivers/dma/Kconfig
> > > @@ -507,4 +507,17 @@ config QCOM_BAM_DMA
> > >           Enable support for the QCOM BAM DMA controller.  This controller
> > >           provides DMA capabilities for a variety of on-chip devices.
> > >
> > > +config XILINX_DMA
> > > +        tristate "Xilinx AXI DMA Engine"
> > > +        depends on (ARCH_ZYNQ || MICROBLAZE)
> > > +        select DMA_ENGINE
> > > +        help
> > > +          Enable support for Xilinx AXI DMA Soft IP.
> > > +
> > > +          This engine provides high-bandwidth direct memory access
> > > +          between memory and AXI4-Stream type target peripherals.
> > > +          It has two stream interfaces/channels, Memory Mapped to
> > > +          Stream (MM2S) and Stream to Memory Mapped (S2MM) for the
> > > +          data transfers.
> > > +
> > >  endif
> > > diff --git a/drivers/dma/xilinx/Makefile
> > > b/drivers/dma/xilinx/Makefile index 3c4e9f2..6224a49 100644
> > > --- a/drivers/dma/xilinx/Makefile
> > > +++ b/drivers/dma/xilinx/Makefile
> > > @@ -1 +1,2 @@
> > >  obj-$(CONFIG_XILINX_VDMA) += xilinx_vdma.o
> > > +obj-$(CONFIG_XILINX_DMA) += xilinx_dma.o
> > > diff --git a/drivers/dma/xilinx/xilinx_dma.c
> > > b/drivers/dma/xilinx/xilinx_dma.c new file mode 100644 index
> > > 0000000..a9be197
> > > --- /dev/null
> > > +++ b/drivers/dma/xilinx/xilinx_dma.c
> > > @@ -0,0 +1,1179 @@
> > > +/*
> > > + * DMA driver for Xilinx DMA Engine
> > > + *
> > > + * Copyright (C) 2010 - 2015 Xilinx, Inc. All rights reserved.
> > > + *
> > > + * Based on the Freescale DMA driver.
> > > + *
> > > + * Description:
> > > + *  The AXI DMA, is a soft IP, which provides high-bandwidth Direct
> > > +Memory
> > > + *  Access between memory and AXI4-Stream-type target peripherals.
> > > +It can be
> > > + *  configured to have one channel or two channels and if
> > > +configured as two
> > > + *  channels, one is to transmit data from memory to a device and
> > > +another is
> > > + *  to receive from a device.
> > > + *
> > > + * This 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.
> > > + */
> > > +
> > > +#include <linux/bitops.h>
> > > +#include <linux/dma/xilinx_dma.h>
> > > +#include <linux/init.h>
> > > +#include <linux/interrupt.h>
> > > +#include <linux/io.h>
> > > +#include <linux/module.h>
> > > +#include <linux/of_address.h>
> > > +#include <linux/of_dma.h>
> > > +#include <linux/of_irq.h>
> > > +#include <linux/of_platform.h>
> > > +#include <linux/slab.h>
> > > +
> > > +#include "../dmaengine.h"
> > > +
> > > +/* Register Offsets */
> > > +#define XILINX_DMA_REG_CONTROL         0x00
> > > +#define XILINX_DMA_REG_STATUS          0x04
> > > +#define XILINX_DMA_REG_CURDESC         0x08
> > > +#define XILINX_DMA_REG_TAILDESC                0x10
> > > +#define XILINX_DMA_REG_SRCADDR         0x18
> > > +#define XILINX_DMA_REG_DSTADDR         0x20
> > > +#define XILINX_DMA_REG_BTT             0x28
> > > +
> > > +/* Channel/Descriptor Offsets */
> > > +#define XILINX_DMA_MM2S_CTRL_OFFSET    0x00
> > > +#define XILINX_DMA_S2MM_CTRL_OFFSET    0x30
> > > +
> > > +/* General register bits definitions */
> > > +#define XILINX_DMA_CR_RUNSTOP_MASK     BIT(0)
> > > +#define XILINX_DMA_CR_RESET_MASK       BIT(2)
> > > +
> > > +#define XILINX_DMA_CR_DELAY_SHIFT      24
> > > +#define XILINX_DMA_CR_COALESCE_SHIFT   16
> > > +
> > > +#define XILINX_DMA_CR_DELAY_MAX                GENMASK(7, 0)
> > > +#define XILINX_DMA_CR_COALESCE_MAX     GENMASK(7, 0)
> > > +
> > > +#define XILINX_DMA_SR_HALTED_MASK      BIT(0)
> > > +#define XILINX_DMA_SR_IDLE_MASK                BIT(1)
> > > +
> > > +#define XILINX_DMA_XR_IRQ_IOC_MASK     BIT(12)
> > > +#define XILINX_DMA_XR_IRQ_DELAY_MASK   BIT(13)
> > > +#define XILINX_DMA_XR_IRQ_ERROR_MASK   BIT(14)
> > > +#define XILINX_DMA_XR_IRQ_ALL_MASK     GENMASK(14, 12)
> > > +
> > > +/* BD definitions */
> > > +#define XILINX_DMA_BD_STS_ALL_MASK     GENMASK(31, 28)
> > > +#define XILINX_DMA_BD_SOP              BIT(27)
> > > +#define XILINX_DMA_BD_EOP              BIT(26)
> > > +
> > > +/* Hw specific definitions */
> > > +#define XILINX_DMA_MAX_CHANS_PER_DEVICE        0x2
> > > +#define XILINX_DMA_MAX_TRANS_LEN       GENMASK(22, 0)
> > > +
> > > +/* Delay loop counter to prevent hardware failure */
> > > +#define XILINX_DMA_LOOP_COUNT          1000000
> > > +
> > > +/* Maximum number of Descriptors */
> > > +#define XILINX_DMA_NUM_DESCS           255
> > > +#define XILINX_DMA_COALESCE_MAX                255
> > > +#define XILINX_DMA_NUM_APP_WORDS       5
> > > +
> > > +/**
> > > + * struct xilinx_dma_desc_hw - Hardware Descriptor
> > > + * @next_desc: Next Descriptor Pointer @0x00
> > > + * @pad1: Reserved @0x04
> > > + * @buf_addr: Buffer address @0x08
> > > + * @pad2: Reserved @0x0C
> > > + * @pad3: Reserved @0x10
> > > + * @pad4: Reserved @0x14
> > > + * @control: Control field @0x18
> > > + * @status: Status field @0x1C
> > > + * @app: APP Fields @0x20 - 0x30
> > > + */
> > > +struct xilinx_dma_desc_hw {
> > > +       u32 next_desc;
> > > +       u32 pad1;
> > > +       u32 buf_addr;
> > > +       u32 pad2;
> > > +       u32 pad3;
> > > +       u32 pad4;
> > > +       u32 control;
> > > +       u32 status;
> > > +       u32 app[XILINX_DMA_NUM_APP_WORDS]; } __aligned(64);
> > > +
> > > +/**
> > > + * struct xilinx_dma_tx_segment - Descriptor segment
> > > + * @hw: Hardware descriptor
> > > + * @node: Node in the descriptor segments list
> > > + * @phys: Physical address of segment  */ struct
> > > +xilinx_dma_tx_segment {
> > > +       struct xilinx_dma_desc_hw hw;
> > > +       struct list_head node;
> > > +       dma_addr_t phys;
> > > +} __aligned(64);
> > > +
> > > +/**
> > > + * struct xilinx_dma_tx_descriptor - Per Transaction structure
> > > + * @async_tx: Async transaction descriptor
> > > + * @segments: TX segments list
> > > + * @node: Node in the channel descriptors list
> > > + * @direction: Transfer direction
> > > + */
> > > +struct xilinx_dma_tx_descriptor {
> > > +       struct dma_async_tx_descriptor async_tx;
> > > +       struct list_head segments;
> > > +       struct list_head node;
> > > +       enum dma_transfer_direction direction; };
> > > +
> > > +/**
> > > + * struct xilinx_dma_chan - Driver specific DMA channel structure
> > > + * @xdev: Driver specific device structure
> > > + * @ctrl_offset: Control registers offset
> > > + * @ctrl_reg: Control register value
> > > + * @lock: Descriptor operation lock
> > > + * @pending_list: Descriptors waiting
> > > + * @active_list: Descriptors ready to submit
> > > + * @done_list: Complete descriptors
> > > + * @free_seg_list: Free descriptors
> > > + * @common: DMA common channel
> > > + * @seg_v: Statically allocated segments base
> > > + * @seg_p: Physical allocated segments base
> > > + * @dev: The dma device
> > > + * @irq: Channel IRQ
> > > + * @id: Channel ID
> > > + * @has_sg: Support scatter transfers
> > > + * @idle: Check for channel idle
> > > + * @err: Channel has errors
> > > + * @tasklet: Cleanup work after irq
> > > + * @residue: Residue
> > > + * @desc_pendingcount: Descriptor pending count  */ struct
> > > +xilinx_dma_chan {
> > > +       struct xilinx_dma_device *xdev;
> > > +       u32 ctrl_offset;
> > > +       u32 ctrl_reg;
> > > +       spinlock_t lock;
> > > +       struct list_head pending_list;
> > > +       struct list_head done_list;
> > > +       struct list_head active_list;
> > > +       struct list_head free_seg_list;
> > > +       struct dma_chan common;
> > > +       struct xilinx_dma_tx_segment *seg_v;
> > > +       dma_addr_t seg_p;
> > > +       struct device *dev;
> > > +       int irq;
> > > +       int id;
> > > +       bool has_sg;
> > > +       bool idle;
> > > +       int err;
> > > +       struct tasklet_struct tasklet;
> > > +       u32 residue;
> > > +       u32 desc_pendingcount;
> > > +};
> > > +
> > > +/**
> > > + * struct xilinx_dma_device - DMA device structure
> > > + * @regs: I/O mapped base address
> > > + * @dev: Device Structure
> > > + * @common: DMA device structure
> > > + * @chan: Driver specific DMA channel
> > > + * @has_sg: Specifies whether Scatter-Gather is present or not  */
> > > +struct xilinx_dma_device {
> > > +       void __iomem *regs;
> > > +       struct device *dev;
> > > +       struct dma_device common;
> > > +       struct xilinx_dma_chan
> *chan[XILINX_DMA_MAX_CHANS_PER_DEVICE];
> > > +       bool has_sg;
> > > +};
> > > +
> > > +/* Macros */
> > > +#define to_xilinx_chan(chan) \
> > > +       container_of(chan, struct xilinx_dma_chan, common) #define
> > > +to_dma_tx_descriptor(tx) \
> > > +       container_of(tx, struct xilinx_dma_tx_descriptor, async_tx)
> > > +
> > > +/* IO accessors */
> > > +static inline void dma_write(struct xilinx_dma_chan *chan, u32 reg,
> > > +u32 value) {
> > > +       iowrite32(value, chan->xdev->regs + reg);
> > Any reason to not use write here?
> Most of the Xilinx drivers and the VDMA driver that got up streamed Use iowrite
> to make consistency b/w the drivers I used the same API's.
> 
> What is the advantage we will gain by using writel instead of iowrite32?
> 
> > > +}
> > > +
> > > +static inline u32 dma_read(struct xilinx_dma_chan *chan, u32 reg) {
> > > +       return ioread32(chan->xdev->regs + reg);
> > Any reason to not use readl here?
> > > +}
> > > +
> > > +static inline u32 dma_ctrl_read(struct xilinx_dma_chan *chan, u32
> > > +reg) {
> > > +       return dma_read(chan, chan->ctrl_offset + reg); }
> > > +
> > > +static inline void dma_ctrl_write(struct xilinx_dma_chan *chan, u32 reg,
> > > +                                 u32 value) {
> > > +       dma_write(chan, chan->ctrl_offset + reg, value); }
> > > +
> > > +/*
> > > +-------------------------------------------------------------------
> > > +--
> > > +--------
> > > + * Descriptors and segments alloc and free  */
> > > +
> > > +/**
> > > + * xilinx_dma_alloc_tx_segment - Allocate transaction segment
> > > + * @chan: Driver specific dma channel
> > > + *
> > > + * Return: The allocated segment on success and NULL on failure.
> > > + */
> > > +static struct xilinx_dma_tx_segment *
> > > +xilinx_dma_alloc_tx_segment(struct xilinx_dma_chan *chan) {
> > > +       struct xilinx_dma_tx_segment *segment = NULL;
> > > +       unsigned long flags;
> > > +
> > > +       spin_lock_irqsave(&chan->lock, flags);
> > > +       if (!list_empty(&chan->free_seg_list)) {
> > > +               segment = list_first_entry(&chan->free_seg_list,
> > > +                                          struct xilinx_dma_tx_segment,
> > > +                                          node);
> > > +               list_del(&segment->node);
> > > +       }
> > > +       spin_unlock_irqrestore(&chan->lock, flags);
> > > +
> > > +       return segment;
> > > +}
> > > +
> > > +/**
> > > + * xilinx_dma_clean_hw_desc - Clean hardware descriptor
> > > + * @hw: HW descriptor to clean
> > > + */
> > > +static void xilinx_dma_clean_hw_desc(struct xilinx_dma_desc_hw *hw) {
> > > +       u32 next_desc = hw->next_desc;
> > > +
> > > +       memset(hw, 0, sizeof(struct xilinx_dma_desc_hw));
> > > +
> > > +       hw->next_desc = next_desc;
> > > +}
> > > +
> > > +/**
> > > + * xilinx_dma_free_tx_segment - Free transaction segment
> > > + * @chan: Driver specific dma channel
> > > + * @segment: dma transaction segment  */ static void
> > > +xilinx_dma_free_tx_segment(struct xilinx_dma_chan *chan,
> > > +                                      struct xilinx_dma_tx_segment
> > > +*segment) {
> > > +       xilinx_dma_clean_hw_desc(&segment->hw);
> > > +
> > > +       list_add_tail(&segment->node, &chan->free_seg_list); }
> > > +
> > > +/**
> > > + * xilinx_dma_tx_descriptor - Allocate transaction descriptor
> > > + * @chan: Driver specific dma channel
> > > + *
> > > + * Return: The allocated descriptor on success and NULL on failure.
> > > + */
> > > +static struct xilinx_dma_tx_descriptor *
> > > +xilinx_dma_alloc_tx_descriptor(struct xilinx_dma_chan *chan) {
> > > +       struct xilinx_dma_tx_descriptor *desc;
> > > +
> > > +       desc = kzalloc(sizeof(*desc), GFP_NOWAIT);
> > > +       if (!desc)
> > > +               return NULL;
> > > +
> > > +       INIT_LIST_HEAD(&desc->segments);
> > > +
> > > +       return desc;
> > > +}
> > > +
> > > +/**
> > > + * xilinx_dma_free_tx_descriptor - Free transaction descriptor
> > > + * @chan: Driver specific dma channel
> > > + * @desc: dma transaction descriptor  */ static void
> > > +xilinx_dma_free_tx_descriptor(struct xilinx_dma_chan *chan,
> > > +                             struct xilinx_dma_tx_descriptor *desc) {
> > > +       struct xilinx_dma_tx_segment *segment, *next;
> > > +
> > > +       if (!desc)
> > > +               return;
> > > +
> > > +       list_for_each_entry_safe(segment, next, &desc->segments, node) {
> > > +               list_del(&segment->node);
> > > +               xilinx_dma_free_tx_segment(chan, segment);
> > > +       }
> > > +
> > > +       kfree(desc);
> > > +}
> > > +
> > > +/**
> > > + * xilinx_dma_alloc_chan_resources - Allocate channel resources
> > > + * @dchan: DMA channel
> > > + *
> > > + * Return: '0' on success and failure value on error  */ static int
> > > +xilinx_dma_alloc_chan_resources(struct dma_chan *dchan) {
> > > +       struct xilinx_dma_chan *chan = to_xilinx_chan(dchan);
> > > +       int i;
> > > +
> > > +       /* Allocate the buffer descriptors. */
> > > +       chan->seg_v = dma_zalloc_coherent(chan->dev,
> > > +                                         sizeof(*chan->seg_v) *
> > > +                                         XILINX_DMA_NUM_DESCS,
> > > +                                         &chan->seg_p, GFP_KERNEL);
> > > +       if (!chan->seg_v) {
> > > +               dev_err(chan->dev,
> > > +                       "unable to allocate channel %d descriptors\n",
> > > +                       chan->id);
> > > +               return -ENOMEM;
> > > +       }
> > > +
> > > +       for (i = 0; i < XILINX_DMA_NUM_DESCS; i++) {
> > > +               chan->seg_v[i].hw.next_desc =
> > > +                               chan->seg_p + sizeof(*chan->seg_v) *
> > > +                               ((i + 1) % XILINX_DMA_NUM_DESCS);
> > > +               chan->seg_v[i].phys =
> > > +                               chan->seg_p + sizeof(*chan->seg_v) * i;
> > > +               list_add_tail(&chan->seg_v[i].node, &chan->free_seg_list);
> > > +       }
> > > +
> > > +       dma_cookie_init(dchan);
> > > +
> > > +       /* Enable interrupts */
> > > +       chan->ctrl_reg |= XILINX_DMA_XR_IRQ_ALL_MASK;
> > > +       dma_ctrl_write(chan, XILINX_DMA_REG_CONTROL,
> > > + chan->ctrl_reg);
> > > +
> > > +       return 0;
> > > +}
> > > +
> > > +/**
> > > + * xilinx_dma_free_desc_list - Free descriptors list
> > > + * @chan: Driver specific dma channel
> > > + * @list: List to parse and delete the descriptor  */ static void
> > > +xilinx_dma_free_desc_list(struct xilinx_dma_chan *chan,
> > > +                                     struct list_head *list) {
> > > +       struct xilinx_dma_tx_descriptor *desc, *next;
> > > +
> > > +       list_for_each_entry_safe(desc, next, list, node) {
> > > +               list_del(&desc->node);
> > > +               xilinx_dma_free_tx_descriptor(chan, desc);
> > > +       }
> > > +}
> > > +
> > > +/**
> > > + * xilinx_dma_free_descriptors - Free channel descriptors
> > > + * @chan: Driver specific dma channel  */ static void
> > > +xilinx_dma_free_descriptors(struct xilinx_dma_chan *chan) {
> > > +       unsigned long flags;
> > > +
> > > +       spin_lock_irqsave(&chan->lock, flags);
> > > +
> > > +       xilinx_dma_free_desc_list(chan, &chan->pending_list);
> > > +       xilinx_dma_free_desc_list(chan, &chan->done_list);
> > > +       xilinx_dma_free_desc_list(chan, &chan->active_list);
> > > +
> > > +       spin_unlock_irqrestore(&chan->lock, flags); }
> > > +
> > > +/**
> > > + * xilinx_dma_free_chan_resources - Free channel resources
> > > + * @dchan: DMA channel
> > > + */
> > > +static void xilinx_dma_free_chan_resources(struct dma_chan *dchan) {
> > > +       struct xilinx_dma_chan *chan = to_xilinx_chan(dchan);
> > > +
> > > +       xilinx_dma_free_descriptors(chan);
> > > +
> > > +       dma_free_coherent(chan->dev,
> > > +                         sizeof(*chan->seg_v) * XILINX_DMA_NUM_DESCS,
> > > +                         chan->seg_v, chan->seg_p); }
> > > +
> > > +/**
> > > + * xilinx_dma_chan_desc_cleanup - Clean channel descriptors
> > > + * @chan: Driver specific dma channel  */ static void
> > > +xilinx_dma_chan_desc_cleanup(struct xilinx_dma_chan *chan) {
> > > +       struct xilinx_dma_tx_descriptor *desc;
> > > +       unsigned long flags;
> > > +
> > > +       spin_lock_irqsave(&chan->lock, flags);
> > > +
> > > +       while (!list_empty(&chan->done_list)) {
> > > +               dma_async_tx_callback callback;
> > > +               void *callback_param;
> > > +
> > > +               desc = list_first_entry(&chan->done_list,
> > > +                       struct xilinx_dma_tx_descriptor, node);
> > > +
> > > +               /* Remove from the list of running transactions */
> > > +               list_del(&desc->node);
> > > +
> > > +               /* Run the link descriptor callback function */
> > > +               callback = desc->async_tx.callback;
> > > +               callback_param = desc->async_tx.callback_param;
> > > +               if (callback) {
> > > +                       spin_unlock_irqrestore(&chan->lock, flags);
> > > +                       callback(callback_param);
> > > +                       spin_lock_irqsave(&chan->lock, flags);
> > > +               }
> > > +
> > > +               /* Run any dependencies, then free the descriptor */
> > > +               dma_run_dependencies(&desc->async_tx);
> > > +               xilinx_dma_free_tx_descriptor(chan, desc);
> > > +       }
> > > +
> > > +       spin_unlock_irqrestore(&chan->lock, flags); }
> > > +
> > > +/**
> > > + * xilinx_dma_tx_status - Get dma transaction status
> > > + * @dchan: DMA channel
> > > + * @cookie: Transaction identifier
> > > + * @txstate: Transaction state
> > > + *
> > > + * Return: DMA transaction status
> > > + */
> > > +static enum dma_status xilinx_dma_tx_status(struct dma_chan *dchan,
> > > +                                           dma_cookie_t cookie,
> > > +                                           struct dma_tx_state
> > > +*txstate) {
> > > +       struct xilinx_dma_chan *chan = to_xilinx_chan(dchan);
> > > +       struct xilinx_dma_tx_descriptor *desc;
> > > +       struct xilinx_dma_tx_segment *segment;
> > > +       struct xilinx_dma_desc_hw *hw;
> > > +       enum dma_status ret;
> > > +       unsigned long flags;
> > > +       u32 residue;
> >
> > While compiling this threw a residue may be used uninitialized
> > warning, I suppose 0 would be a sensible default value?
> 
> Ok will fix it.
> 
> > > +
> > > +       ret = dma_cookie_status(dchan, cookie, txstate);
> > > +       if (ret == DMA_COMPLETE || !txstate)
> > > +               return ret;
> > > +
> > > +       desc = list_last_entry(&chan->active_list,
> > > +                              struct xilinx_dma_tx_descriptor,
> > > + node);
> > > +
> > > +       spin_lock_irqsave(&chan->lock, flags);
> > > +       if (chan->has_sg) {
> > > +               while (!list_empty(&desc->segments)) {
> > > +                       segment = list_first_entry(&desc->segments,
> > > +                                       struct xilinx_dma_tx_segment, node);
> > > +                       hw = &segment->hw;
> > > +                       residue += (hw->control - hw->status) &
> > > +                                  XILINX_DMA_MAX_TRANS_LEN;
> > > +               }
> > > +       }
> > > +
> > > +       chan->residue = residue;
> > > +       dma_set_residue(txstate, chan->residue);
> > > +       spin_unlock_irqrestore(&chan->lock, flags);
> > > +
> > > +       return ret;
> > > +}
> > > +
> > > +/**
> > > + * xilinx_dma_halt - Halt DMA channel
> > > + * @chan: Driver specific DMA channel  */ static void
> > > +xilinx_dma_halt(struct xilinx_dma_chan *chan) {
> > > +       int loop = XILINX_DMA_LOOP_COUNT;
> > > +
> > > +       chan->ctrl_reg &= ~XILINX_DMA_CR_RUNSTOP_MASK;
> > > +       dma_ctrl_write(chan, XILINX_DMA_REG_CONTROL,
> > > + chan->ctrl_reg);
> > > +
> > > +       /* Wait for the hardware to halt */
> > > +       do {
> > > +               if (dma_ctrl_read(chan, XILINX_DMA_REG_STATUS) &
> > > +                       XILINX_DMA_SR_HALTED_MASK)
> > > +                       break;
> > > +       } while (loop--);
> > > +
> > > +       if (!loop) {
> > > +               dev_err(chan->dev, "Cannot stop channel %p: %x\n",
> > > +                       chan, dma_ctrl_read(chan, XILINX_DMA_REG_STATUS));
> > > +               chan->err = true;
> > > +       }
> > > +}
> > > +
> > > +/**
> > > + * xilinx_dma_start - Start DMA channel
> > > + * @chan: Driver specific DMA channel  */ static void
> > > +xilinx_dma_start(struct xilinx_dma_chan *chan) {
> > > +       int loop = XILINX_DMA_LOOP_COUNT;
> > > +
> > > +       chan->ctrl_reg |= XILINX_DMA_CR_RUNSTOP_MASK;
> > > +       dma_ctrl_write(chan, XILINX_DMA_REG_CONTROL,
> > > + chan->ctrl_reg);
> > > +
> > > +       /* Wait for the hardware to start */
> > > +       do {
> > > +               if (!dma_ctrl_read(chan, XILINX_DMA_REG_STATUS) &
> > > +                       XILINX_DMA_SR_HALTED_MASK)
> > > +                       break;
> > > +       } while (loop--);
> > Maybe use one of the readx_poll_timeout functions?
> 
> Ok will fix it.

Seems to be the readx_poll_timeout api is not suits for my driver requirement.
The API has some limitations when I try to use this API the code looks ugly.

The issue that I am facing is:
The readx_poll_timeout API 1st argument is expecting only the address (https://lwn.net/Articles/626525/).
But in my case I need to pass the channel info and a particular offset in the channel.
If I pass all these info in the API's where I am using readx_poll_timeout the code looks ugly.

Do you have any other suggestions?

Regards,
Kedar.

> 
> > > +
> > > +       if (!loop) {
> > > +               dev_err(chan->dev, "Cannot start channel %p: %x\n",
> > > +                        chan, dma_ctrl_read(chan, XILINX_DMA_REG_STATUS));
> > > +               chan->err = true;
> > > +       }
> > > +}
> > > +
> > > +/**
> > > + * xilinx_dma_start_transfer - Starts DMA transfer
> > > + * @chan: Driver specific channel struct pointer  */ static void
> > > +xilinx_dma_start_transfer(struct xilinx_dma_chan *chan) {
> > > +       struct xilinx_dma_tx_descriptor *head_desc, *tail_desc;
> > > +       struct xilinx_dma_tx_segment *tail_segment;
> > > +
> > > +       if (chan->err)
> > > +               return;
> > > +
> > > +       if (list_empty(&chan->pending_list))
> > > +               return;
> > > +
> > > +       if (!chan->idle)
> > > +               return;
> > > +
> > > +       head_desc = list_first_entry(&chan->pending_list,
> > > +                                    struct xilinx_dma_tx_descriptor, node);
> > > +       tail_desc = list_last_entry(&chan->pending_list,
> > > +                                   struct xilinx_dma_tx_descriptor, node);
> > > +       tail_segment = list_last_entry(&tail_desc->segments,
> > > +                                      struct xilinx_dma_tx_segment,
> > > + node);
> > > +
> > > +       if (chan->desc_pendingcount <= XILINX_DMA_COALESCE_MAX) {
> > > +               chan->ctrl_reg &= ~XILINX_DMA_CR_COALESCE_MAX;
> > > +               chan->ctrl_reg |= chan->desc_pendingcount <<
> > > +                                 XILINX_DMA_CR_COALESCE_SHIFT;
> > > +               dma_ctrl_write(chan, XILINX_DMA_REG_CONTROL, chan-
> >ctrl_reg);
> > > +       }
> > > +
> > > +       if (chan->has_sg)
> > > +               dma_ctrl_write(chan, XILINX_DMA_REG_CURDESC,
> > > +                              head_desc->async_tx.phys);
> > > +
> > > +       xilinx_dma_start(chan);
> > > +
> > > +       if (chan->err)
> > > +               return;
> > > +
> > > +       /* Start the transfer */
> > > +       if (chan->has_sg) {
> > > +               dma_ctrl_write(chan, XILINX_DMA_REG_TAILDESC,
> > > +                              tail_segment->phys);
> > > +       } else {
> > > +               struct xilinx_dma_tx_segment *segment;
> > > +               struct xilinx_dma_desc_hw *hw;
> > > +
> > > +               segment = list_first_entry(&head_desc->segments,
> > > +                                          struct xilinx_dma_tx_segment, node);
> > > +               hw = &segment->hw;
> > > +
> > > +               if (head_desc->direction == DMA_MEM_TO_DEV)
> > > +                       dma_ctrl_write(chan, XILINX_DMA_REG_SRCADDR,
> > > +                                      hw->buf_addr);
> > > +               else
> > > +                       dma_ctrl_write(chan, XILINX_DMA_REG_DSTADDR,
> > > +                                      hw->buf_addr);
> > > +
> > > +               /* Start the transfer */
> > > +               dma_ctrl_write(chan, XILINX_DMA_REG_BTT,
> > > +                              hw->control & XILINX_DMA_MAX_TRANS_LEN);
> > > +       }
> > > +
> > > +       list_splice_tail_init(&chan->pending_list, &chan->active_list);
> > > +       chan->desc_pendingcount = 0;
> > > +       chan->idle = false;
> > > +}
> > > +
> > > +/**
> > > + * xilinx_dma_issue_pending - Issue pending transactions
> > > + * @dchan: DMA channel
> > > + */
> > > +static void xilinx_dma_issue_pending(struct dma_chan *dchan) {
> > > +       struct xilinx_dma_chan *chan = to_xilinx_chan(dchan);
> > > +       unsigned long flags;
> > > +
> > > +       spin_lock_irqsave(&chan->lock, flags);
> > > +       xilinx_dma_start_transfer(chan);
> > > +       spin_unlock_irqrestore(&chan->lock, flags); }
> > > +
> > > +/**
> > > + * xilinx_dma_complete_descriptor - Mark the active descriptor as
> > > +complete
> > > + * @chan : xilinx DMA channel
> > > + */
> > > +static void xilinx_dma_complete_descriptor(struct xilinx_dma_chan
> > > +*chan) {
> > > +       struct xilinx_dma_tx_descriptor *desc, *next;
> > > +
> > > +       if (list_empty(&chan->active_list))
> > > +               return;
> > > +
> > > +       list_for_each_entry_safe(desc, next, &chan->active_list, node) {
> > > +               list_del(&desc->node);
> > > +               dma_cookie_complete(&desc->async_tx);
> > > +               list_add_tail(&desc->node, &chan->done_list);
> > > +       }
> > > +}
> > > +
> > > +/**
> > > + * xilinx_dma_reset - Reset DMA channel
> > > + * @chan: Driver specific DMA channel
> > > + *
> > > + * Return: '0' on success and failure value on error  */ static int
> > > +xilinx_dma_chan_reset(struct xilinx_dma_chan *chan) {
> > > +       int loop = XILINX_DMA_LOOP_COUNT;
> > > +       u32 tmp;
> > > +
> > > +       chan->ctrl_reg = dma_ctrl_read(chan, XILINX_DMA_REG_CONTROL);
> > > +       dma_ctrl_write(chan, XILINX_DMA_REG_CONTROL, chan->ctrl_reg |
> > > +                      XILINX_DMA_CR_RESET_MASK);
> > > +
> > > +       tmp = dma_ctrl_read(chan, XILINX_DMA_REG_CONTROL) &
> > > +             XILINX_DMA_CR_RESET_MASK;
> > > +
> > > +       /* Wait for the hardware to finish reset */
> > > +       do {
> > > +               tmp = dma_ctrl_read(chan, XILINX_DMA_REG_CONTROL) &
> > > +                     XILINX_DMA_CR_RESET_MASK;
> > > +       } while (loop-- && tmp);
> > See above
> 
> Ok will fix it.
> 
> Regards,
> Kedar.
> 
> > > +
> > > +       if (!loop) {
> > > +               dev_err(chan->dev, "reset timeout, cr %x, sr %x\n",
> > > +                       dma_ctrl_read(chan, XILINX_DMA_REG_CONTROL),
> > > +                       dma_ctrl_read(chan, XILINX_DMA_REG_STATUS));
> > > +               return -EBUSY;
> > > +       }
> > > +
> > > +       chan->err = false;
> > > +
> > > +       return 0;
> > > +}
> > > +
> > > +/**
> > > + * xilinx_dma_irq_handler - DMA Interrupt handler
> > > + * @irq: IRQ number
> > > + * @data: Pointer to the Xilinx DMA channel structure
> > > + *
> > > + * Return: IRQ_HANDLED/IRQ_NONE
> > > + */
> > > +static irqreturn_t xilinx_dma_irq_handler(int irq, void *data) {
> > > +       struct xilinx_dma_chan *chan = data;
> > > +       u32 status;
> > > +
> > > +       /* Read the status and ack the interrupts. */
> > > +       status = dma_ctrl_read(chan, XILINX_DMA_REG_STATUS);
> > > +       if (!(status & XILINX_DMA_XR_IRQ_ALL_MASK))
> > > +               return IRQ_NONE;
> > > +
> > > +       dma_ctrl_write(chan, XILINX_DMA_REG_STATUS,
> > > +                      status & XILINX_DMA_XR_IRQ_ALL_MASK);
> > > +
> > > +       if (status & XILINX_DMA_XR_IRQ_ERROR_MASK) {
> > > +               dev_err(chan->dev,
> > > +                       "Channel %p has errors %x, cdr %x tdr %x\n",
> > > +                       chan, dma_ctrl_read(chan, XILINX_DMA_REG_STATUS),
> > > +                       dma_ctrl_read(chan, XILINX_DMA_REG_CURDESC),
> > > +                       dma_ctrl_read(chan, XILINX_DMA_REG_TAILDESC));
> > > +               chan->err = true;
> > > +       }
> > > +
> > > +       /*
> > > +        * Device takes too long to do the transfer when user requires
> > > +        * responsiveness
> > > +        */
> > > +       if (status & XILINX_DMA_XR_IRQ_DELAY_MASK)
> > > +               dev_dbg(chan->dev, "Inter-packet latency too
> > > + long\n");
> > > +
> > > +       if (status & XILINX_DMA_XR_IRQ_IOC_MASK) {
> > > +               spin_lock(&chan->lock);
> > > +               xilinx_dma_complete_descriptor(chan);
> > > +               chan->idle = true;
> > > +               xilinx_dma_start_transfer(chan);
> > > +               spin_unlock(&chan->lock);
> > > +       }
> > > +
> > > +       tasklet_schedule(&chan->tasklet);
> > > +       return IRQ_HANDLED;
> > > +}
> > > +
> > > +/**
> > > + * xilinx_dma_do_tasklet - Schedule completion tasklet
> > > + * @data: Pointer to the Xilinx dma channel structure  */ static
> > > +void xilinx_dma_do_tasklet(unsigned long data) {
> > > +       struct xilinx_dma_chan *chan = (struct xilinx_dma_chan
> > > +*)data;
> > > +
> > > +       xilinx_dma_chan_desc_cleanup(chan);
> > > +}
> > > +
> > > +/**
> > > + * append_desc_queue - Queuing descriptor
> > > + * @chan: Driver specific dma channel
> > > + * @desc: dma transaction descriptor  */ static void
> > > +append_desc_queue(struct xilinx_dma_chan *chan,
> > > +                             struct xilinx_dma_tx_descriptor *desc) {
> > > +       struct xilinx_dma_tx_segment *tail_segment;
> > > +       struct xilinx_dma_tx_descriptor *tail_desc;
> > > +
> > > +       if (list_empty(&chan->pending_list))
> > > +               goto append;
> > > +
> > > +       /*
> > > +        * Add the hardware descriptor to the chain of hardware descriptors
> > > +        * that already exists in memory.
> > > +        */
> > > +       tail_desc = list_last_entry(&chan->pending_list,
> > > +                                   struct xilinx_dma_tx_descriptor, node);
> > > +       tail_segment = list_last_entry(&tail_desc->segments,
> > > +                                      struct xilinx_dma_tx_segment, node);
> > > +       tail_segment->hw.next_desc = (u32)desc->async_tx.phys;
> > > +
> > > +       /*
> > > +        * Add the software descriptor and all children to the list
> > > +        * of pending transactions
> > > +        */
> > > +append:
> > > +       list_add_tail(&desc->node, &chan->pending_list);
> > > +       chan->desc_pendingcount++;
> > > +
> > > +       if (unlikely(chan->desc_pendingcount > XILINX_DMA_COALESCE_MAX))
> {
> > > +               dev_dbg(chan->dev, "desc pendingcount is too high\n");
> > > +               chan->desc_pendingcount = XILINX_DMA_COALESCE_MAX;
> > > +               BUG();
> > > +       }
> > > +}
> > > +
> > > +/**
> > > + * xilinx_dma_tx_submit - Submit DMA transaction
> > > + * @tx: Async transaction descriptor
> > > + *
> > > + * Return: cookie value on success and failure value on error  */
> > > +static dma_cookie_t xilinx_dma_tx_submit(struct
> > > +dma_async_tx_descriptor *tx) {
> > > +       struct xilinx_dma_tx_descriptor *desc = to_dma_tx_descriptor(tx);
> > > +       struct xilinx_dma_chan *chan = to_xilinx_chan(tx->chan);
> > > +       dma_cookie_t cookie;
> > > +       unsigned long flags;
> > > +       int err;
> > > +
> > > +       if (chan->err) {
> > > +               /*
> > > +                * If reset fails, need to hard reset the system.
> > > +                * Channel is no longer functional
> > > +                */
> > > +               err = xilinx_dma_chan_reset(chan);
> > > +               if (err < 0)
> > > +                       return err;
> > > +       }
> > > +
> > > +       spin_lock_irqsave(&chan->lock, flags);
> > > +
> > > +       cookie = dma_cookie_assign(tx);
> > > +
> > > +       /* Put this transaction onto the tail of the pending queue */
> > > +       append_desc_queue(chan, desc);
> > > +
> > > +       spin_unlock_irqrestore(&chan->lock, flags);
> > > +
> > > +       return cookie;
> > > +}
> > > +
> > > +/**
> > > + * xilinx_dma_prep_slave_sg - prepare descriptors for a DMA_SLAVE
> > > +transaction
> > > + * @dchan: DMA channel
> > > + * @sgl: scatterlist to transfer to/from
> > > + * @sg_len: number of entries in @scatterlist
> > > + * @direction: DMA direction
> > > + * @flags: transfer ack flags
> > > + * @context: APP words of the descriptor
> > > + *
> > > + * Return: Async transaction descriptor on success and NULL on
> > > +failure  */ static struct dma_async_tx_descriptor
> > > +*xilinx_dma_prep_slave_sg(
> > > +       struct dma_chan *dchan, struct scatterlist *sgl, unsigned int sg_len,
> > > +       enum dma_transfer_direction direction, unsigned long flags,
> > > +       void *context)
> > > +{
> > > +       struct xilinx_dma_chan *chan = to_xilinx_chan(dchan);
> > > +       struct xilinx_dma_tx_descriptor *desc;
> > > +       struct xilinx_dma_tx_segment *segment;
> > > +       u32 *app_w = (u32 *)context;
> > > +       struct scatterlist *sg;
> > > +       size_t copy, sg_used;
> > > +       int i;
> > > +
> > > +       if (!is_slave_direction(direction))
> > > +               return NULL;
> > > +
> > > +       /* Allocate a transaction descriptor. */
> > > +       desc = xilinx_dma_alloc_tx_descriptor(chan);
> > > +       if (!desc)
> > > +               return NULL;
> > > +
> > > +       desc->direction = direction;
> > > +       dma_async_tx_descriptor_init(&desc->async_tx, &chan->common);
> > > +       desc->async_tx.tx_submit = xilinx_dma_tx_submit;
> > > +
> > > +       /* Build transactions using information in the scatter gather list */
> > > +       for_each_sg(sgl, sg, sg_len, i) {
> > > +               sg_used = 0;
> > > +
> > > +               /* Loop until the entire scatterlist entry is used */
> > > +               while (sg_used < sg_dma_len(sg)) {
> > > +                       struct xilinx_dma_desc_hw *hw;
> > > +
> > > +                       /* Get a free segment */
> > > +                       segment = xilinx_dma_alloc_tx_segment(chan);
> > > +                       if (!segment)
> > > +                               goto error;
> > > +
> > > +                       /*
> > > +                        * Calculate the maximum number of bytes to transfer,
> > > +                        * making sure it is less than the hw limit
> > > +                        */
> > > +                       copy = min_t(size_t, sg_dma_len(sg) - sg_used,
> > > +                                    XILINX_DMA_MAX_TRANS_LEN);
> > > +                       hw = &segment->hw;
> > > +
> > > +                       /* Fill in the descriptor */
> > > +                       hw->buf_addr = sg_dma_address(sg) + sg_used;
> > > +
> > > +                       hw->control = copy;
> > > +
> > > +                       if (direction == DMA_MEM_TO_DEV) {
> > > +                               if (app_w)
> > > +                                       memcpy(hw->app, app_w, sizeof(u32) *
> > > +                                              XILINX_DMA_NUM_APP_WORDS);
> > > +                       }
> > > +
> > > +                       sg_used += copy;
> > > +
> > > +                       /*
> > > +                        * Insert the segment into the descriptor segments
> > > +                        * list.
> > > +                        */
> > > +                       list_add_tail(&segment->node, &desc->segments);
> > > +               }
> > > +       }
> > > +
> > > +       segment = list_first_entry(&desc->segments,
> > > +                                  struct xilinx_dma_tx_segment, node);
> > > +       desc->async_tx.phys = segment->phys;
> > > +
> > > +       /* For the last DMA_MEM_TO_DEV transfer, set EOP */
> > > +       if (direction == DMA_MEM_TO_DEV) {
> > > +               segment->hw.control |= XILINX_DMA_BD_SOP;
> > > +               segment = list_last_entry(&desc->segments,
> > > +                                         struct xilinx_dma_tx_segment,
> > > +                                         node);
> > > +               segment->hw.control |= XILINX_DMA_BD_EOP;
> > > +       }
> > > +
> > > +       return &desc->async_tx;
> > > +
> > > +error:
> > > +       xilinx_dma_free_tx_descriptor(chan, desc);
> > > +       return NULL;
> > > +}
> > > +
> > > +/**
> > > + * xilinx_dma_terminate_all - Halt the channel and free descriptors
> > > + * @dchan: DMA Channel pointer
> > > + *
> > > + * Return: '0' always
> > > + */
> > > +static int xilinx_dma_terminate_all(struct dma_chan *dchan) {
> > > +       struct xilinx_dma_chan *chan = to_xilinx_chan(dchan);
> > > +
> > > +       /* Halt the DMA engine */
> > > +       xilinx_dma_halt(chan);
> > > +
> > > +       /* Remove and free all of the descriptors in the lists */
> > > +       xilinx_dma_free_descriptors(chan);
> > > +
> > > +       return 0;
> > > +}
> > > +
> > > +/**
> > > + * xilinx_dma_chan_remove - Per Channel remove function
> > > + * @chan: Driver specific DMA channel  */ static void
> > > +xilinx_dma_chan_remove(struct xilinx_dma_chan *chan) {
> > > +       /* Disable interrupts */
> > > +       chan->ctrl_reg &= ~XILINX_DMA_XR_IRQ_ALL_MASK;
> > > +       dma_ctrl_write(chan, XILINX_DMA_REG_CONTROL,
> > > +chan->ctrl_reg);
> > > +
> > > +       if (chan->irq > 0)
> > > +               free_irq(chan->irq, chan);
> > > +
> > > +       tasklet_kill(&chan->tasklet);
> > > +
> > > +       list_del(&chan->common.device_node);
> > > +}
> > > +
> > > +/**
> > > + * xilinx_dma_chan_probe - Per Channel Probing
> > > + * It get channel features from the device tree entry and
> > > + * initialize special channel handling routines
> > > + *
> > > + * @xdev: Driver specific device structure
> > > + * @node: Device node
> > > + *
> > > + * Return: '0' on success and failure value on error  */ static int
> > > +xilinx_dma_chan_probe(struct xilinx_dma_device *xdev,
> > > +                                struct device_node *node) {
> > > +       struct xilinx_dma_chan *chan;
> > > +       int err;
> > > +       bool has_dre;
> > > +       u32 value, width = 0;
> > > +
> > > +       /* alloc channel */
> > > +       chan = devm_kzalloc(xdev->dev, sizeof(*chan), GFP_KERNEL);
> > > +       if (!chan)
> > > +               return -ENOMEM;
> > > +
> > > +       chan->dev = xdev->dev;
> > > +       chan->xdev = xdev;
> > > +       chan->has_sg = xdev->has_sg;
> > > +       chan->desc_pendingcount = 0x0;
> > > +
> > > +       has_dre = of_property_read_bool(node, "xlnx,include-dre");
> > > +
> > > +       err = of_property_read_u32(node, "xlnx,datawidth", &value);
> > > +       if (err) {
> > > +               dev_err(xdev->dev, "unable to read datawidth property");
> > > +               return err;
> > > +       }
> > > +
> > > +       width = value >> 3; /* Convert bits to bytes */
> > > +
> > > +       /* If data width is greater than 8 bytes, DRE is not in hw */
> > > +       if (width > 8)
> > > +               has_dre = false;
> > > +
> > > +       if (!has_dre)
> > > +               xdev->common.copy_align = fls(width - 1);
> > > +
> > > +       if (of_device_is_compatible(node, "xlnx,axi-dma-mm2s-channel")) {
> > > +               chan->id = 0;
> > > +               chan->ctrl_offset = XILINX_DMA_MM2S_CTRL_OFFSET;
> > > +       } else if (of_device_is_compatible(node, "xlnx,axi-dma-s2mm-
> channel")) {
> > > +               chan->id = 1;
> > > +               chan->ctrl_offset = XILINX_DMA_S2MM_CTRL_OFFSET;
> > > +       } else {
> > > +               dev_err(xdev->dev, "Invalid channel compatible node\n");
> > > +               return -EINVAL;
> > > +       }
> > > +
> > > +       xdev->chan[chan->id] = chan;
> > > +
> > > +       /* Initialize the channel */
> > > +       err = xilinx_dma_chan_reset(chan);
> > > +       if (err) {
> > > +               dev_err(xdev->dev, "Reset channel failed\n");
> > > +               return err;
> > > +       }
> > > +
> > > +       spin_lock_init(&chan->lock);
> > > +       INIT_LIST_HEAD(&chan->pending_list);
> > > +       INIT_LIST_HEAD(&chan->done_list);
> > > +       INIT_LIST_HEAD(&chan->active_list);
> > > +       INIT_LIST_HEAD(&chan->free_seg_list);
> > > +
> > > +       chan->common.device = &xdev->common;
> > > +
> > > +       /* find the IRQ line, if it exists in the device tree */
> > > +       chan->irq = irq_of_parse_and_map(node, 0);
> > > +       err = request_irq(chan->irq, xilinx_dma_irq_handler,
> > > +                         IRQF_SHARED,
> > > +                         "xilinx-dma-controller", chan);
> > > +       if (err) {
> > > +               dev_err(xdev->dev, "unable to request IRQ %d\n", chan->irq);
> > > +               return err;
> > > +       }
> > > +
> > > +       /* Initialize the tasklet */
> > > +       tasklet_init(&chan->tasklet, xilinx_dma_do_tasklet,
> > > +                    (unsigned long)chan);
> > > +
> > > +       /* Add the channel to DMA device channel list */
> > > +       list_add_tail(&chan->common.device_node,
> > > + &xdev->common.channels);
> > > +
> > > +       chan->idle = true;
> > > +
> > > +       return 0;
> > > +}
> > > +
> > > +/**
> > > + * of_dma_xilinx_xlate - Translation function
> > > + * @dma_spec: Pointer to DMA specifier as found in the device tree
> > > + * @ofdma: Pointer to DMA controller data
> > > + *
> > > + * Return: DMA channel pointer on success and NULL on error  */
> > > +static struct dma_chan *of_dma_xilinx_xlate(struct of_phandle_args
> > *dma_spec,
> > > +                                           struct of_dma *ofdma) {
> > > +       struct xilinx_dma_device *xdev = ofdma->of_dma_data;
> > > +       int chan_id = dma_spec->args[0];
> > > +
> > > +       if (chan_id >= XILINX_DMA_MAX_CHANS_PER_DEVICE)
> > > +               return NULL;
> > > +
> > > +       return dma_get_slave_channel(&xdev->chan[chan_id]->common);
> > > +}
> > > +
> > > +/**
> > > + * xilinx_dma_probe - Driver probe function
> > > + * @pdev: Pointer to the platform_device structure
> > > + *
> > > + * Return: '0' on success and failure value on error  */ static int
> > > +xilinx_dma_probe(struct platform_device *pdev) {
> > > +       struct xilinx_dma_device *xdev;
> > > +       struct device_node *child, *node;
> > > +       struct resource *res;
> > > +       int i, ret;
> > > +
> > > +       xdev = devm_kzalloc(&pdev->dev, sizeof(*xdev), GFP_KERNEL);
> > > +       if (!xdev)
> > > +               return -ENOMEM;
> > > +
> > > +       xdev->dev = &(pdev->dev);
> > > +       INIT_LIST_HEAD(&xdev->common.channels);
> > > +
> > > +       node = pdev->dev.of_node;
> > > +
> > > +       /* Map the registers */
> > > +       res = platform_get_resource(pdev, IORESOURCE_MEM, 0);
> > > +       xdev->regs = devm_ioremap_resource(&pdev->dev, res);
> > > +       if (IS_ERR(xdev->regs))
> > > +               return PTR_ERR(xdev->regs);
> > > +
> > > +       /* Check if SG is enabled */
> > > +       xdev->has_sg = of_property_read_bool(node,
> > > + "xlnx,include-sg");
> > > +
> > > +       /* Axi DMA only do slave transfers */
> > > +       dma_cap_set(DMA_SLAVE, xdev->common.cap_mask);
> > > +       dma_cap_set(DMA_PRIVATE, xdev->common.cap_mask);
> > > +       xdev->common.device_prep_slave_sg = xilinx_dma_prep_slave_sg;
> > > +       xdev->common.device_terminate_all = xilinx_dma_terminate_all;
> > > +       xdev->common.device_issue_pending = xilinx_dma_issue_pending;
> > > +       xdev->common.device_alloc_chan_resources =
> > > +               xilinx_dma_alloc_chan_resources;
> > > +       xdev->common.device_free_chan_resources =
> > > +               xilinx_dma_free_chan_resources;
> > > +       xdev->common.device_tx_status = xilinx_dma_tx_status;
> > > +       xdev->common.directions = BIT(DMA_DEV_TO_MEM) |
> > BIT(DMA_MEM_TO_DEV);
> > > +       xdev->common.residue_granularity =
> > DMA_RESIDUE_GRANULARITY_SEGMENT;
> > > +       xdev->common.dev = &pdev->dev;
> > > +
> > > +       platform_set_drvdata(pdev, xdev);
> > > +
> > > +       for_each_child_of_node(node, child) {
> > > +               ret = xilinx_dma_chan_probe(xdev, child);
> > > +               if (ret) {
> > > +                       dev_err(&pdev->dev, "Probing channels failed\n");
> > > +                       goto free_chan_resources;
> > > +               }
> > > +       }
> > > +
> > > +       dma_async_device_register(&xdev->common);
> > > +
> > > +       ret = of_dma_controller_register(node, of_dma_xilinx_xlate, xdev);
> > > +       if (ret) {
> > > +               dev_err(&pdev->dev, "Unable to register DMA to DT\n");
> > > +               dma_async_device_unregister(&xdev->common);
> > > +               goto free_chan_resources;
> > > +       }
> > > +
> > > +       dev_info(&pdev->dev, "Xilinx AXI DMA Engine driver
> > > + Probed!!\n");
> > > +
> > > +       return 0;
> > > +
> > > +free_chan_resources:
> > > +       for (i = 0; i < XILINX_DMA_MAX_CHANS_PER_DEVICE; i++)
> > > +               if (xdev->chan[i])
> > > +                       xilinx_dma_chan_remove(xdev->chan[i]);
> > > +
> > > +       return ret;
> > > +}
> > > +
> > > +/**
> > > + * xilinx_dma_remove - Driver remove function
> > > + * @pdev: Pointer to the platform_device structure
> > > + *
> > > + * Return: Always '0'
> > > + */
> > > +static int xilinx_dma_remove(struct platform_device *pdev) {
> > > +       struct xilinx_dma_device *xdev = platform_get_drvdata(pdev);
> > > +       int i;
> > > +
> > > +       of_dma_controller_free(pdev->dev.of_node);
> > > +       dma_async_device_unregister(&xdev->common);
> > > +
> > > +       for (i = 0; i < XILINX_DMA_MAX_CHANS_PER_DEVICE; i++)
> > > +               if (xdev->chan[i])
> > > +                       xilinx_dma_chan_remove(xdev->chan[i]);
> > > +
> > > +       return 0;
> > > +}
> > > +
> > > +static const struct of_device_id xilinx_dma_of_match[] = {
> > > +       { .compatible = "xlnx,axi-dma-1.00.a",},
> > > +       {}
> > > +};
> > > +MODULE_DEVICE_TABLE(of, xilinx_dma_of_match);
> > > +
> > > +static struct platform_driver xilinx_dma_driver = {
> > > +       .driver = {
> > > +               .name = "xilinx-dma",
> > > +               .of_match_table = xilinx_dma_of_match,
> > > +       },
> > > +       .probe = xilinx_dma_probe,
> > > +       .remove = xilinx_dma_remove, };
> > > +
> > > +module_platform_driver(xilinx_dma_driver);
> > > +
> > > +MODULE_AUTHOR("Xilinx, Inc.");
> > > +MODULE_DESCRIPTION("Xilinx DMA driver"); MODULE_LICENSE("GPL");
> > > --
> > > 2.1.2
> > >
> > >
> > > _______________________________________________
> > > linux-arm-kernel mailing list
> > > linux-arm-kernel at lists.infradead.org
> > > http://lists.infradead.org/mailman/listinfo/linux-arm-kernel
> >
> > Cheers,
> >
> > Moritz

From s.hauer at pengutronix.de  Thu Aug 20 00:05:07 2015
From: s.hauer at pengutronix.de (Sascha Hauer)
Date: Thu, 20 Aug 2015 09:05:07 +0200
Subject: [RFC PATCH 0/3] New Atmel PIO4 pinctrl/gpio driver
In-Reply-To: <20150810065334.GC2635@odux.rfo.atmel.com>
References: <1438355290-28255-1-git-send-email-ludovic.desroches@atmel.com>
 <20150805073117.GP5161@pengutronix.de>
 <20150810065334.GC2635@odux.rfo.atmel.com>
Message-ID: <20150820070507.GS5161@pengutronix.de>

On Mon, Aug 10, 2015 at 08:53:34AM +0200, Ludovic Desroches wrote:
> Hi Sascha,
> 
> On Wed, Aug 05, 2015 at 09:31:17AM +0200, Sascha Hauer wrote:
> > On Fri, Jul 31, 2015 at 05:08:07PM +0200, Ludovic Desroches wrote:
> > > Hi,
> > > 
> > > Following our discussion, I send an RFC version of my driver. RFC because it is
> > > not totally achieved, some cleanup and feature addition is needed.
> > > 
> > > At least, we could discuss about the 'core' part. I have used the pinmux
> > > property as Mediatek driver. Patch 3 is the internal dt files we are using.
> > 
> > As you can imagine I am fine with the binding, so I can add my acked-by
> > once you send a non-RFC version.
> >
> 
> Great, I'm glad to hear that.
>  
> > The only thing I never understood is what's so special about GPIOs that
> > they have to bypass the pinctrl framework and instead a gpio_request
> > magically translates a gpio into a pin.
> 
> Not sure to really understand your concern here... Do you mean I could
> get rid of gpio_request_enable()?

I would expect a gpio to be a pin like every other pin, hence configured
via the pinctrl framework and not implicitly via gpio_request().

> 
> > Wouldn't it make sense to at
> > least add the pins in their GPIO mode to
> > arch/arm/boot/dts/sama5d2-pinfunc.h?
> 
> It is done, PIN_PA0 could be used for this purpose.

I would expect a define like:

#define PIN_PA3__GPIO                   PINMUX_PIN(PIN_PA3, 0, 2)

PIN_PAx only contains the pin number, but not the function.

Sascha

-- 
Pengutronix e.K.                           |                             |
Industrial Linux Solutions                 | http://www.pengutronix.de/  |
Peiner Str. 6-8, 31137 Hildesheim, Germany | Phone: +49-5121-206917-0    |
Amtsgericht Hildesheim, HRA 2686           | Fax:   +49-5121-206917-5555 |


From vinod.koul at intel.com  Thu Aug 20 00:08:49 2015
From: vinod.koul at intel.com (Vinod Koul)
Date: Thu, 20 Aug 2015 12:38:49 +0530
Subject: [PATCH v1 1/4] dmaengine: Add support for new feature CRC32C
In-Reply-To: <CAFd313x+MD5C2stJ-YdKrt6Ywzt4_2GmK3pJTFjfwrhPnCdopQ@mail.gmail.com>
References: <1438258268-3099-1-git-send-email-rsahu@apm.com>
 <1438258268-3099-2-git-send-email-rsahu@apm.com>
 <20150820052631.GW13546@localhost>
 <CAFd313x+MD5C2stJ-YdKrt6Ywzt4_2GmK3pJTFjfwrhPnCdopQ@mail.gmail.com>
Message-ID: <20150820070849.GF13546@localhost>

On Thu, Aug 20, 2015 at 11:59:07AM +0530, Rameshwar Sahu wrote:
> Hi Vinod,
> 
> On Thu, Aug 20, 2015 at 10:56 AM, Vinod Koul <vinod.koul at intel.com> wrote:
> > On Thu, Jul 30, 2015 at 05:41:05PM +0530, Rameshwar Prasad Sahu wrote:
> >> This patch adds support for new feature CRC32C calculation in
> >> dmaengine framework.
> >
> > Looks okay can you please update Documentation also
> 
> Thanks, I will update Documentation.

Also add a wrapper for new API

-- 
~Vinod



From vinod.koul at intel.com  Thu Aug 20 00:09:57 2015
From: vinod.koul at intel.com (Vinod Koul)
Date: Thu, 20 Aug 2015 12:39:57 +0530
Subject: [PATCH v1 2/4] dmaengine: xgene-dma: Add support for CRC32C
 calculation via DMA engine
In-Reply-To: <CAFd313y3vTCzaGKY7ZVyFGDiSx+KuxQHyBwqKyB+xWfR5dtVSA@mail.gmail.com>
References: <1438258268-3099-1-git-send-email-rsahu@apm.com>
 <1438258268-3099-3-git-send-email-rsahu@apm.com>
 <20150820054034.GX13546@localhost>
 <CAFd313y3vTCzaGKY7ZVyFGDiSx+KuxQHyBwqKyB+xWfR5dtVSA@mail.gmail.com>
Message-ID: <20150820070957.GG13546@localhost>

On Thu, Aug 20, 2015 at 12:23:50PM +0530, Rameshwar Sahu wrote:
> Hi Vinod,
> 
> On Thu, Aug 20, 2015 at 11:10 AM, Vinod Koul <vinod.koul at intel.com> wrote:
> > On Thu, Jul 30, 2015 at 05:41:06PM +0530, Rameshwar Prasad Sahu wrote:
> >> +     /* Invalidate unused source address field */
> >> +     for (; i < 4; i++)
> >> +             xgene_dma_invalidate_buffer(xgene_dma_lookup_ext8(desc2, i));
> >> +
> >> +     /* Check whether requested buffer processed */
> >> +     if (nbytes) {
> >> +             chan_err(chan, "Src count crossed maximum limit\n");
> >> +             return -EINVAL;
> > no cleanup ?
> Here not required, cleanup I am doing in parent function from where
> this function is getting called in case of failure.
> >
> >> +struct dma_async_tx_descriptor *xgene_dma_prep_flyby(
> >> +     struct xgene_dma_chan *chan, struct scatterlist *src_sg,
> >> +     size_t len, u32 seed, u8 *result, unsigned long flags, u8 opcode)
> > please fix style here
> 
> Could you explain me What kind of coding style you would like here ??

See CodingStyle Chapter 2

-- 
~Vinod



From vinod.koul at intel.com  Thu Aug 20 00:10:28 2015
From: vinod.koul at intel.com (Vinod Koul)
Date: Thu, 20 Aug 2015 12:40:28 +0530
Subject: [PATCH v1 3/4] Crypto: Add support for APM X-Gene SoC CRC32C h/w
 accelerator driver
In-Reply-To: <CAFd313xG2_4NGHspuJwThY=jUSPiBm3egvXVvhv8XxKctgMv1A@mail.gmail.com>
References: <1438258268-3099-1-git-send-email-rsahu@apm.com>
 <1438258268-3099-4-git-send-email-rsahu@apm.com>
 <20150820054828.GY13546@localhost>
 <CAFd313xG2_4NGHspuJwThY=jUSPiBm3egvXVvhv8XxKctgMv1A@mail.gmail.com>
Message-ID: <20150820071028.GH13546@localhost>

On Thu, Aug 20, 2015 at 12:31:44PM +0530, Rameshwar Sahu wrote:
> Hi Vinod,
> 
> On Thu, Aug 20, 2015 at 11:18 AM, Vinod Koul <vinod.koul at intel.com> wrote:
> > On Thu, Jul 30, 2015 at 05:41:07PM +0530, Rameshwar Prasad Sahu wrote:
> >> +     nents = sg_nents(req->src);
> >> +     sg_count = dma_map_sg(dev, req->src, nents, DMA_TO_DEVICE);
> >> +     if (!sg_count) {
> >> +             dev_err(dev, "Failed to map src sg");
> >> +             return -ENOMEM;
> > mapping error shouldn't be no mem error
> Okay, I guess then -EIO will be fine here??

yes better

-- 
~Vinod


From jingoohan1 at gmail.com  Thu Aug 20 00:22:43 2015
From: jingoohan1 at gmail.com (Jingoo Han)
Date: Thu, 20 Aug 2015 16:22:43 +0900
Subject: [PATCH v3 05/14] drm: bridge/analogix_dp: fix link_rate &
 lane_count bug
In-Reply-To: <1439995824-18312-1-git-send-email-ykk@rock-chips.com>
References: <1439995728-18046-1-git-send-email-ykk@rock-chips.com>
 <1439995824-18312-1-git-send-email-ykk@rock-chips.com>
Message-ID: <6480369A-D108-4FBD-9041-ED925D8FD922@gmail.com>

On 2015. 8. 19., at PM 11:50, Yakir Yang <ykk at rock-chips.com> wrote:
> 
> link_rate and lane_count already configed in analogix_dp_set_link_train(),

s/configed/configured

Also, the commit name such as "fix ... bug" is not good.
How about following?

drm: bridge/analogix_dp: remove duplicate configuration of link rate and link count

Best regards,
Jingoo Han

> so we don't need to config those repeatly after training finished, just
> remove them out.
> 
> Beside Display Port 1.2 already support 5.4Gbps link rate, the maximum sets
> would change from {1.62Gbps, 2.7Gbps} to {1.62Gbps, 2.7Gbps, 5.4Gbps}.
> 
> Signed-off-by: Yakir Yang <ykk at rock-chips.com>
> ---
> Changes in v3:
> - Take Thierry Reding suggest, link_rate and lane_count shouldn't config to
>  the DT property value directly, but we can take those as hardware limite.
>  For example, RK3288 only support 4 physical lanes of 2.7/1.62 Gbps/lane,
>  so DT property would like "link-rate = 0x0a" "lane-count = 4".
> 
> Changes in v2: None
> 
> drivers/gpu/drm/bridge/analogix_dp_core.c | 16 ++++++++--------
> drivers/gpu/drm/bridge/analogix_dp_core.h |  9 +++++----
> 2 files changed, 13 insertions(+), 12 deletions(-)
> 
> diff --git a/drivers/gpu/drm/bridge/analogix_dp_core.c b/drivers/gpu/drm/bridge/analogix_dp_core.c
> index 480cc13..1778e0a 100644
> --- a/drivers/gpu/drm/bridge/analogix_dp_core.c
> +++ b/drivers/gpu/drm/bridge/analogix_dp_core.c
> @@ -635,6 +635,8 @@ static void analogix_dp_get_max_rx_bandwidth(struct analogix_dp_device *dp,
>    /*
>     * For DP rev.1.1, Maximum link rate of Main Link lanes
>     * 0x06 = 1.62 Gbps, 0x0a = 2.7 Gbps
> +     * For DP rev.1.2, Maximum link rate of Main Link lanes
> +     * 0x06 = 1.62 Gbps, 0x0a = 2.7 Gbps, 0x14 = 5.4Gbps
>     */
>    analogix_dp_read_byte_from_dpcd(dp, DP_MAX_LINK_RATE, &data);
>    *bandwidth = data;
> @@ -668,7 +670,8 @@ static void analogix_dp_init_training(struct analogix_dp_device *dp,
>    analogix_dp_get_max_rx_lane_count(dp, &dp->link_train.lane_count);
> 
>    if ((dp->link_train.link_rate != LINK_RATE_1_62GBPS) &&
> -        (dp->link_train.link_rate != LINK_RATE_2_70GBPS)) {
> +        (dp->link_train.link_rate != LINK_RATE_2_70GBPS) &&
> +        (dp->link_train.link_rate != LINK_RATE_5_40GBPS)) {
>        dev_err(dp->dev, "Rx Max Link Rate is abnormal :%x !\n",
>            dp->link_train.link_rate);
>        dp->link_train.link_rate = LINK_RATE_1_62GBPS;
> @@ -901,8 +904,8 @@ static void analogix_dp_commit(struct analogix_dp_device *dp)
>        return;
>    }
> 
> -    ret = analogix_dp_set_link_train(dp, dp->video_info->lane_count,
> -                     dp->video_info->link_rate);
> +    ret = analogix_dp_set_link_train(dp, dp->video_info->max_lane_count,
> +                     dp->video_info->max_link_rate);
>    if (ret) {
>        dev_err(dp->dev, "unable to do link train\n");
>        return;
> @@ -912,9 +915,6 @@ static void analogix_dp_commit(struct analogix_dp_device *dp)
>    analogix_dp_enable_rx_to_enhanced_mode(dp, 1);
>    analogix_dp_enable_enhanced_mode(dp, 1);
> 
> -    analogix_dp_set_lane_count(dp, dp->video_info->lane_count);
> -    analogix_dp_set_link_bandwidth(dp, dp->video_info->link_rate);
> -
>    analogix_dp_init_video(dp);
>    ret = analogix_dp_config_video(dp);
>    if (ret)
> @@ -1198,13 +1198,13 @@ static struct video_info *analogix_dp_dt_parse_pdata(struct device *dev)
>    }
> 
>    if (of_property_read_u32(dp_node, "analogix,link-rate",
> -                 &dp_video_config->link_rate)) {
> +                 &dp_video_config->max_link_rate)) {
>        dev_err(dev, "failed to get link-rate\n");
>        return ERR_PTR(-EINVAL);
>    }
> 
>    if (of_property_read_u32(dp_node, "analogix,lane-count",
> -                 &dp_video_config->lane_count)) {
> +                 &dp_video_config->max_lane_count)) {
>        dev_err(dev, "failed to get lane-count\n");
>        return ERR_PTR(-EINVAL);
>    }
> diff --git a/drivers/gpu/drm/bridge/analogix_dp_core.h b/drivers/gpu/drm/bridge/analogix_dp_core.h
> index 2cefde9..941b34f 100644
> --- a/drivers/gpu/drm/bridge/analogix_dp_core.h
> +++ b/drivers/gpu/drm/bridge/analogix_dp_core.h
> @@ -21,8 +21,9 @@
> #define MAX_EQ_LOOP 5
> 
> enum link_rate_type {
> -    LINK_RATE_1_62GBPS = 0x06,
> -    LINK_RATE_2_70GBPS = 0x0a
> +    LINK_RATE_1_62GBPS = DP_LINK_BW_1_62,
> +    LINK_RATE_2_70GBPS = DP_LINK_BW_2_7,
> +    LINK_RATE_5_40GBPS = DP_LINK_BW_5_4,
> };
> 
> enum link_lane_count_type {
> @@ -128,8 +129,8 @@ struct video_info {
>    enum color_coefficient ycbcr_coeff;
>    enum color_depth color_depth;
> 
> -    enum link_rate_type link_rate;
> -    enum link_lane_count_type lane_count;
> +    enum link_rate_type       max_link_rate;
> +    enum link_lane_count_type max_lane_count;
> };
> 
> struct link_train {
> -- 
> 1.9.1
> 
> 


From jens.wiklander at linaro.org  Thu Aug 20 00:23:29 2015
From: jens.wiklander at linaro.org (Jens Wiklander)
Date: Thu, 20 Aug 2015 09:23:29 +0200
Subject: [PATCH v5 1/5] arm/arm64: add smccc ARCH32
In-Reply-To: <55D460E7.9070104@gmail.com>
References: <1439973629-19505-1-git-send-email-jens.wiklander@linaro.org>
 <1439973629-19505-2-git-send-email-jens.wiklander@linaro.org>
 <55D460E7.9070104@gmail.com>
Message-ID: <20150820072329.GA24984@ermac>

On Wed, Aug 19, 2015 at 01:56:39PM +0300, Yury wrote:
[...]
> > +++ b/include/linux/arm-smccc.h
> > @@ -0,0 +1,79 @@
> > +/*
> > + * Copyright (c) 2015, Linaro Limited
> > + *
> > + * This software is licensed under the terms of the GNU General Public
> > + * License version 2, as published by the Free Software Foundation, and
> > + * may be copied, distributed, and modified under those terms.
> > + *
> > + * This program is distributed in the hope that it will be useful,
> > + * but WITHOUT ANY WARRANTY; without even the implied warranty of
> > + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
> > + * GNU General Public License for more details.
> > + *
> > + */
> > +#ifndef __LINUX_ARM_SMCCC_H
> > +#define __LINUX_ARM_SMCCC_H
> > +
> > +#include <linux/types.h>
> > +
> > +/*
> > + * This file provideds defines common defines for ARM SMC Calling
> 
> typos here?

Thanks

> 
> > + * Convention as specified in
> > + * http://infocenter.arm.com/help/topic/com.arm.doc.den0028a/index.html
> > + */
> > +
> > +#define SMCCC_SMC_32			(0 << 30)
> 
> 0 << 30 is just 0, and so meaningless.
> It's better to introduce SMCCC_IS_32() macro instead.

SMCCC_SMC_32 is used as an argument for SMCCC_CALL_VAL (example in
"[PATCH v5 4/5] tee: add OP-TEE driver" drivers/tee/optee/optee_smc.h).
Shifting 0 here is still 0 as you point out, but it connects it with the
other define SMCCC_SMC_64.

> 
> > +#define SMCCC_SMC_64			(1 << 30)
> > +#define SMCCC_FAST_CALL			(1 << 31)
> > +#define SMCCC_STD_CALL			(0 << 31)
> 
> The same
> 
> > +
> > +#define SMCCC_OWNER_MASK		0x3F
> > +#define SMCCC_OWNER_SHIFT		24
> > +
> > +#define SMCCC_FUNC_MASK			0xFFFF
> > +
> > +#define SMCCC_IS_FAST_CALL(smc_val)	((smc_val) & SMCCC_FAST_CALL)
> > +#define SMCCC_IS_64(smc_val)		((smc_val) & SMCCC_SMC_64)
> > +#define SMCCC_FUNC_NUM(smc_val)		((smc_val) & SMCCC_FUNC_MASK)
> > +#define SMCCC_OWNER_NUM(smc_val) \
> > +	(((smc_val) >> SMCCC_OWNER_SHIFT) & SMCCC_OWNER_MASK)
> > +
> > +#define SMCCC_CALL_VAL(type, calling_convention, owner, func_num) \
> > +			((type) | (calling_convention) | \
> > +			(((owner) & SMCCC_OWNER_MASK) << SMCCC_OWNER_SHIFT) | \
> > +			((func_num) & SMCCC_FUNC_MASK))
> > +
> > +#define SMCCC_OWNER_ARCH		0
> > +#define SMCCC_OWNER_CPU			1
> > +#define SMCCC_OWNER_SIP			2
> > +#define SMCCC_OWNER_OEM			3
> > +#define SMCCC_OWNER_STANDARD		4
> > +#define SMCCC_OWNER_TRUSTED_APP		48
> > +#define SMCCC_OWNER_TRUSTED_APP_END	49
> > +#define SMCCC_OWNER_TRUSTED_OS		50
> > +#define SMCCC_OWNER_TRUSTED_OS_END	63
> > +
> > +struct smccc_param32 {
> > +	u32 a0;
> > +	u32 a1;
> > +	u32 a2;
> > +	u32 a3;
> > +	u32 a4;
> > +	u32 a5;
> > +	u32 a6;
> > +	u32 a7;
> > +};
> > +
> > +/**
> > + * smccc_call32() - make ARCH32 SMC calls
> > + * @param: values to pass in registers 0 to 7
> > + *
> > + * This function is used to make SMC calls following SMC Calling
> Convention
> > + * for ARCH32 calls. The content of the supplied param are copied to
> > + * registers 0 to 7 prior to the SMC instruction. Values a0..a3
> are updated
> > + * with the content from register 0 to 3 on return from the SMC
> > + * instruction.
> > + */
> > +void smccc_call32(struct smccc_param32 *param);
> > +
> > +#endif /*__LINUX_ARM_SMCCC_H*/
> > --
> > 1.9.1
> >
> >
> > _______________________________________________
> > linux-arm-kernel mailing list
> > linux-arm-kernel at lists.infradead.org
> > http://lists.infradead.org/mailman/listinfo/linux-arm-kernel

--
Thanks,
Jens


From roger.pau at citrix.com  Thu Aug 20 00:33:12 2015
From: roger.pau at citrix.com (=?UTF-8?B?Um9nZXIgUGF1IE1vbm7DqQ==?=)
Date: Thu, 20 Aug 2015 09:33:12 +0200
Subject: [PATCH v3 08/20] block/xen-blkfront: split get_grant in 2
In-Reply-To: <1438966019-19322-9-git-send-email-julien.grall@citrix.com>
References: <1438966019-19322-1-git-send-email-julien.grall@citrix.com>
 <1438966019-19322-9-git-send-email-julien.grall@citrix.com>
Message-ID: <55D582B8.5030602@citrix.com>

El 07/08/15 a les 18.46, Julien Grall ha escrit:
> Prepare the code to support 64KB page granularity. The first
> implementation will use a full Linux page per indirect and persistent
> grant. When non-persistent grant is used, each page of a bio request
> may be split in multiple grant.
> 
> Furthermore, the field page of the grant structure is only used to copy
> data from persistent grant or indirect grant. Avoid to set it for other
> use case as it will have no meaning given the page will be split in
> multiple grant.
> 
> Provide 2 functions, to setup indirect grant, the other for bio page.
> 
> Signed-off-by: Julien Grall <julien.grall at citrix.com>

Thanks, this looks fine:

Acked-by: Roger Pau Monn? <roger.pau at citrix.com>

Roger.


From hdegoede at redhat.com  Thu Aug 20 00:36:33 2015
From: hdegoede at redhat.com (Hans de Goede)
Date: Thu, 20 Aug 2015 09:36:33 +0200
Subject: [linux-sunxi] Re: [PATCH 4/6] ARM: dts: sun7i: Enable USB DRC on
 pcDuino 3
In-Reply-To: <20150820064545.GM30520@lukather>
References: <1439563477-12295-1-git-send-email-hdegoede@redhat.com>
 <1439563477-12295-5-git-send-email-hdegoede@redhat.com>
 <20150820064545.GM30520@lukather>
Message-ID: <55D58381.7040801@redhat.com>

Hi,

On 08/20/2015 08:45 AM, Maxime Ripard wrote:
> On Fri, Aug 14, 2015 at 04:44:35PM +0200, Hans de Goede wrote:
>> From: Jelle van der Waa <jelle at vdwaa.nl>
>>
>> Enable the otg/drc usb controller on the pcDuino 3.
>>
>> Note this board has the otg-vbus connected directly to the 5v-dcc of
>> the board, so there is no vbus0 regulator, nor vbus0-det.
>
> Can it do OTG then?

Yes.

> If VBUS is tied to the 5v, there's no way for the
> board to shut it down when acting as peripheral, right?

Correct, the idea is to power it over otg when using it
as a peripheral, or at least power it from a usb port of
the machine for which it is a peripheral. Note that the
original cubieboard (both A10 and A20 versions) have the
same issue.

Regards,

Hans


From rsahu at apm.com  Thu Aug 20 00:48:18 2015
From: rsahu at apm.com (Rameshwar Sahu)
Date: Thu, 20 Aug 2015 13:18:18 +0530
Subject: [PATCH v1 1/4] dmaengine: Add support for new feature CRC32C
In-Reply-To: <20150820070849.GF13546@localhost>
References: <1438258268-3099-1-git-send-email-rsahu@apm.com>
 <1438258268-3099-2-git-send-email-rsahu@apm.com>
 <20150820052631.GW13546@localhost>
 <CAFd313x+MD5C2stJ-YdKrt6Ywzt4_2GmK3pJTFjfwrhPnCdopQ@mail.gmail.com>
 <20150820070849.GF13546@localhost>
Message-ID: <CAFd313wjAayC9++YdfDwO8tCYsTxBvAGNvPNeEVtBjhskY82eg@mail.gmail.com>

On Thu, Aug 20, 2015 at 12:38 PM, Vinod Koul <vinod.koul at intel.com> wrote:
> On Thu, Aug 20, 2015 at 11:59:07AM +0530, Rameshwar Sahu wrote:
>> Hi Vinod,
>>
>> On Thu, Aug 20, 2015 at 10:56 AM, Vinod Koul <vinod.koul at intel.com> wrote:
>> > On Thu, Jul 30, 2015 at 05:41:05PM +0530, Rameshwar Prasad Sahu wrote:
>> >> This patch adds support for new feature CRC32C calculation in
>> >> dmaengine framework.
>> >
>> > Looks okay can you please update Documentation also
>>
>> Thanks, I will update Documentation.
>
> Also add a wrapper for new API
Okay
>
> --
> ~Vinod
>


From jingoohan1 at gmail.com  Thu Aug 20 00:49:00 2015
From: jingoohan1 at gmail.com (Jingoo Han)
Date: Thu, 20 Aug 2015 16:49:00 +0900
Subject: [PATCH v3 13/14] drm: bridge/analogix_dp: move hpd detect to
 connector detect function
In-Reply-To: <1439995939-18770-1-git-send-email-ykk@rock-chips.com>
References: <1439995728-18046-1-git-send-email-ykk@rock-chips.com>
 <1439995939-18770-1-git-send-email-ykk@rock-chips.com>
Message-ID: <6E5CEF9B-19D4-4AC4-B5B1-BC667979302D@gmail.com>

On 2015. 8. 19., at PM 11:52, Yakir Yang <ykk at rock-chips.com> wrote:
> 


What is the reason to make this patch?

Please make commit message including the reason.

Best regards,
Jingoo Han

> Signed-off-by: Yakir Yang <ykk at rock-chips.com>
> ---
> Changes in v3:
> - move dp hpd detect to connector detect function.
> 
> Changes in v2: None
> 
> drivers/gpu/drm/bridge/analogix_dp_core.c | 12 ++++++------
> 1 file changed, 6 insertions(+), 6 deletions(-)
> 
> diff --git a/drivers/gpu/drm/bridge/analogix_dp_core.c b/drivers/gpu/drm/bridge/analogix_dp_core.c
> index 75dd44a..052b9b3 100644
> --- a/drivers/gpu/drm/bridge/analogix_dp_core.c
> +++ b/drivers/gpu/drm/bridge/analogix_dp_core.c
> @@ -915,12 +915,6 @@ static void analogix_dp_commit(struct analogix_dp_device *dp)
>            DRM_ERROR("failed to disable the panel\n");
>    }
> 
> -    ret = analogix_dp_detect_hpd(dp);
> -    if (ret) {
> -        /* Cable has been disconnected, we're done */
> -        return;
> -    }
> -
>    ret = analogix_dp_handle_edid(dp);
>    if (ret) {
>        dev_err(dp->dev, "unable to handle edid\n");
> @@ -953,6 +947,12 @@ static void analogix_dp_commit(struct analogix_dp_device *dp)
> static enum drm_connector_status analogix_dp_detect(
>                struct drm_connector *connector, bool force)
> {
> +    struct analogix_dp_device *dp = connector_to_dp(connector);
> +
> +    if (analogix_dp_detect_hpd(dp))
> +        /* Cable has been disconnected, we're done */
> +        return connector_status_disconnected;
> +
>    return connector_status_connected;
> }
> 
> -- 
> 1.9.1
> 
> 


From ykk at rock-chips.com  Thu Aug 20 01:02:27 2015
From: ykk at rock-chips.com (Yakir Yang)
Date: Thu, 20 Aug 2015 03:02:27 -0500
Subject: [PATCH v3 12/14] drm: bridge/analogix_dp: expand the delay time
 for hpd detect
In-Reply-To: <A474A3AB-86A8-4967-B90F-31920A5E7BA3@gmail.com>
References: <1439995728-18046-1-git-send-email-ykk@rock-chips.com>
 <1439995929-18719-1-git-send-email-ykk@rock-chips.com>
 <A474A3AB-86A8-4967-B90F-31920A5E7BA3@gmail.com>
Message-ID: <55D58993.4060502@rock-chips.com>

Hi Jingoo,

On 08/20/2015 01:11 AM, Jingoo Han wrote:
> On 2015. 8. 19., at PM 11:52, Yakir Yang <ykk at rock-chips.com> wrote:
>> Some edp screen with no hpd signal would need some delay time
>> to ensure that screen would be ready for work, so we can expand
>> the delay time in hpd detect function, it works prefectly on my
>> rk3288 sdk board.
> Then, this delay has a dependency on the "rk3288 sdk" board.
> Also, if the delay time is expanded, the booting time of some Exybos boards will be increased unnecessarily. :-(
>
> So, please add new DT property such as 'hpd-delay' that can be added to board DT files.
>
> If there is not that DT property in DT files, the default value '10' will written to a variable such as 'unsigned int hpd_delay'.
> If there is the DT property in DT files, the delay value will written to the variable when parsing DT values
> and will be used in analogix_dp_detect_hpd().
>
> What I want to say is that there should not be harmful effect on the existing Exynos boards, due to unrelated reasons.

Yeah, you are right, I made an mistake here.

And I want to put this delay to "need-force-hpd" code, cause
this property is for the no-hpd-signal eDP screen.

But strangely, with my this series, I don't need the expand delay
any more, I am not sure which change improved this, I guess
those delay time should come from drm core ?

Whatever seems we don't need this delay for now, and if I can
find the exact reason and realize I still need this delay, I prefer
to add those delay in "need-force-hpd" code.

Thanks,
- Yakir
> Best regards,
> Jingoo Han
>
>> Signed-off-by: Yakir Yang <ykk at rock-chips.com>
>> ---
>> Changes in v3: None
>> Changes in v2: None
>>
>> drivers/gpu/drm/bridge/analogix_dp_core.c | 2 +-
>> 1 file changed, 1 insertion(+), 1 deletion(-)
>>
>> diff --git a/drivers/gpu/drm/bridge/analogix_dp_core.c b/drivers/gpu/drm/bridge/analogix_dp_core.c
>> index 99870f7..75dd44a 100644
>> --- a/drivers/gpu/drm/bridge/analogix_dp_core.c
>> +++ b/drivers/gpu/drm/bridge/analogix_dp_core.c
>> @@ -68,7 +68,7 @@ static int analogix_dp_detect_hpd(struct analogix_dp_device *dp)
>>             return 0;
>>
>>         timeout_loop++;
>> -        usleep_range(10, 11);
>> +        usleep_range(100, 110);
>>     }
>>
>>     /*
>> -- 
>> 1.9.1
>>
>>
>
>




From ykk at rock-chips.com  Thu Aug 20 01:03:30 2015
From: ykk at rock-chips.com (Yakir Yang)
Date: Thu, 20 Aug 2015 03:03:30 -0500
Subject: [PATCH v3 0/14] Add Analogix Core Display Port Driver
In-Reply-To: <4EDBEF7E-31F4-45EF-960C-A7C47C650E49@gmail.com>
References: <1439995728-18046-1-git-send-email-ykk@rock-chips.com>
 <55D557BD.8070004@codeaurora.org>
 <58DB3289-29F0-4C2D-97F6-EB0555392DF2@gmail.com>
 <55D5727C.8000109@rock-chips.com>
 <4EDBEF7E-31F4-45EF-960C-A7C47C650E49@gmail.com>
Message-ID: <55D589D2.8080006@rock-chips.com>

Hi Jingoo,

On 08/20/2015 01:55 AM, Jingoo Han wrote:
> On 2015. 8. 20., at PM 3:23, Yakir Yang <ykk at rock-chips.com> wrote:
>> Hi Jingoo & Archit,
>>
>>
>>> On 08/20/2015 12:54 AM, Jingoo Han wrote:
>>>> On 2015. 8. 20., at PM 1:29, Archit Taneja <architt at codeaurora.org> wrote:
>>>> Hi,
>>>>
>>>>> On 08/19/2015 08:18 PM, Yakir Yang wrote:
>>>>>
>>>>> Hi all,
>>>>>     The Samsung Exynos eDP controller and Rockchip RK3288 eDP controller
>>>>> share the same IP, so a lot of parts can be re-used. I split the common
>>>>> code into bridge directory, then rk3288 and exynos only need to keep
>>>>> some platform code. Cause I can't find the exact IP name of exynos dp
>>>>> controller, so I decide to name dp core driver with "analogix" which I
>>>>> find in rk3288 eDP TRM ;)
>>>>>
>>>>> Beyond that, there are three light registers setting differents bewteen
>>>>> exynos and rk3288.
>>>>> 1. RK3288 have five special pll resigters which not indicata in exynos
>>>>>     dp controller.
>>>>> 2. The address of DP_PHY_PD(dp phy power manager register) are different
>>>>>     between rk3288 and exynos.
>>>>> 3. Rk3288 and exynos have different setting with AUX_HW_RETRY_CTL(dp debug
>>>>>     register).
>>>>>
>>>>> I have verified this series on two kinds of rockchip platform board, one
>>>>> is rk3288 sdk board which connect with a 2K display port monitor, the other
>>>>> is google jerry chromebook which connect with a eDP screen "cnm,n116bgeea2",
>>>>> both of them works rightlly.
>>>>>
>>>>> I haven't verified the dp function on samsung platform, cause I haven't got
>>>>> exynos boards. I can only ensure that there are no build error on samsung
>>>>> platform, wish some samsung guys help to test. ;)
>>>>>
>>>>> Thanks,
>>>>> - Yakir
>>>>>
>>>>> Changes in v3:
>>>>> - Take Thierry Reding suggest, move exynos's video_timing code
>>>>>    to analogix_dp-exynos platform driver, add get_modes method
>>>>>    to struct analogix_dp_plat_data.
>>>>> - Take Heiko suggest, rename some "samsung*" dts propery to "analogix*".
>>>>> - Take Thierry Reding suggest, dynamic parse video timing info from
>>>>>    struct drm_display_mode and struct drm_display_info.
>>>>> - Take Thierry Reding suggest, link_rate and lane_count shouldn't config to
>>>>>    the DT property value directly, but we can take those as hardware limite.
>>>>>    For example, RK3288 only support 4 physical lanes of 2.7/1.62 Gbps/lane,
>>>>>    so DT property would like "link-rate = 0x0a" "lane-count = 4".
>>>>> - Take Heiko suggest, add devicetree binding documents.
>>>>> - Take Thierry Reding suggest, remove sync pol & colorimetry properies
>>>>>    from the new analogix dp driver devicetree binding.
>>>>> - Update the exist exynos dtsi file with the latest DP DT properies.
>>>>> - Take Thierry Reding and Heiko suggest, leave "sclk_edp_24m" to rockchip
>>>>>    dp phy driver which name to "24m", and leave "sclk_edp" to analogix dp
>>>>>    core driver which name to "dp", and leave "pclk_edp" to rockchip dp platform
>>>>>    driver which name to "pclk".
>>>>> - Take Heiko suggest, add devicetree binding document.
>>>>> - Take Heiko suggest, remove "rockchip,panel" DT property, take use of remote
>>>>>    point to get panel node.
>>>>> - Add the new function point analogix_dp_platdata.get_modes init.
>>>>> - Take Heiko suggest, add rockchip dp phy driver,
>>>>>    collect the phy clocks and power control.
>>>>> - Add "analogix,need-force-hpd" to indicate whether driver need foce
>>>>>    hpd when hpd detect failed.
>>>>> - move dp hpd detect to connector detect function.
>>>>> - Add edid modes parse support
>>>>>
>>>>> Changes in v2:
>>>>> - Take Joe Preches advise, improved commit message more readable, and
>>>>>    avoid using some uncommon style like bellow:
>>>>>    -  retval = exynos_dp_read_bytes_from_i2c(...
>>>>>                 ...)
>>>>>    +  retval =
>>>>>    +  exynos_dp_read_bytes_from_i2c(......);
>>>>> - Take Jingoo Han suggest, just remove my name from author list.
>>>>> - Take Jingoo Han suggest, remove new copyright
>>>>> - Fix compiled failed dut to analogix_dp_device misspell
>>>>> - Take Heiko suggest, get panel node with remote-endpoint method,
>>>>>    and create devicetree binding for driver.
>>>>> - Remove the clock enable/disbale with "sclk_edp" & "sclk_edp_24m",
>>>>>    leave those clock to rockchip dp phy driver.
>>>>> - Add GNU license v2 declared and samsung copyright
>>>>> - Fix compile failed dut to phy_pd_addr variable misspell error
>>>>>
>>>>> Yakir Yang (14):
>>>>>    drm: exynos/dp: fix code style
>>>>>    drm: exynos/dp: convert to drm bridge mode
>>>>>    drm: bridge: analogix_dp: split exynos dp driver to bridge dir
>>>>>    drm: bridge/analogix_dp: dynamic parse sync_pol & interlace &
>>>>>      colorimetry
>>>>>    drm: bridge/analogix_dp: fix link_rate & lane_count bug
>>>>>    Documentation: drm/bridge: add document for analogix_dp
>>>>>    drm: rockchip/dp: add rockchip platform dp driver
>>>>>    phy: Add driver for rockchip Display Port PHY
>>>>>    drm: bridge/analogix_dp: add platform device type support
>>>>>    drm: bridge: analogix_dp: add some rk3288 special registers setting
>>>>>    drm: bridge: analogix_dp: try force hpd after plug in lookup failed
>>>>>    drm: bridge/analogix_dp: expand the delay time for hpd detect
>>>>>    drm: bridge/analogix_dp: move hpd detect to connector detect function
>>>>>    drm: bridge/analogix_dp: add edid modes parse in get_modes method
>>>>>
>>>>>   .../devicetree/bindings/drm/bridge/analogix_dp.txt |   73 +
>>>>>   .../devicetree/bindings/phy/rockchip-dp-phy.txt    |   26 +
>>>>>   .../bindings/video/analogix_dp-rockchip.txt        |   83 ++
>>>>>   .../devicetree/bindings/video/exynos_dp.txt        |   51 +-
>>>>>   arch/arm/boot/dts/exynos5250-arndale.dts           |   10 +-
>>>>>   arch/arm/boot/dts/exynos5250-smdk5250.dts          |   10 +-
>>>>>   arch/arm/boot/dts/exynos5250-snow.dts              |   12 +-
>>>>>   arch/arm/boot/dts/exynos5250-spring.dts            |   12 +-
>>>>>   arch/arm/boot/dts/exynos5420-peach-pit.dts         |   12 +-
>>>>>   arch/arm/boot/dts/exynos5420-smdk5420.dts          |   10 +-
>>>>>   arch/arm/boot/dts/exynos5800-peach-pi.dts          |   12 +-
>>>>>   drivers/gpu/drm/bridge/Kconfig                     |    5 +
>>>>>   drivers/gpu/drm/bridge/Makefile                    |    1 +
>>>>>   drivers/gpu/drm/bridge/analogix_dp_core.c          | 1382 +++++++++++++++++++
>>>>>   drivers/gpu/drm/bridge/analogix_dp_core.h          |  286 ++++
>>>>>   drivers/gpu/drm/bridge/analogix_dp_reg.c           | 1294 ++++++++++++++++++
>>>>>   .../exynos_dp_reg.h => bridge/analogix_dp_reg.h}   |  270 ++--
>>>>>   drivers/gpu/drm/exynos/Kconfig                     |    5 +-
>>>>>   drivers/gpu/drm/exynos/Makefile                    |    2 +-
>>>>>   drivers/gpu/drm/exynos/analogix_dp-exynos.c        |  347 +++++
>>>>>   drivers/gpu/drm/exynos/exynos_dp_core.c            | 1416 --------------------
>>>>>   drivers/gpu/drm/exynos/exynos_dp_core.h            |  282 ----
>>>>>   drivers/gpu/drm/exynos/exynos_dp_reg.c             | 1263 -----------------
>>>>>   drivers/gpu/drm/rockchip/Kconfig |    9 +
>>>>>   drivers/gpu/drm/rockchip/Makefile                  |    1 +
>>>>>   drivers/gpu/drm/rockchip/analogix_dp-rockchip.c    |  390 ++++++
>>>>>   drivers/phy/Kconfig                                |    7 +
>>>>>   drivers/phy/Makefile                               |    1 +
>>>>>   drivers/phy/phy-rockchip-dp.c                      |  185 +++
>>>>>   include/drm/bridge/analogix_dp.h |   40 +
>>>>>   30 files changed, 4325 insertions(+), 3172 deletions(-)
>>>>>   create mode 100644 Documentation/devicetree/bindings/drm/bridge/analogix_dp.txt
>>>>>   create mode 100644 Documentation/devicetree/bindings/phy/rockchip-dp-phy.txt
>>>>>   create mode 100644 Documentation/devicetree/bindings/video/analogix_dp-rockchip.txt
>>>>>   create mode 100644 drivers/gpu/drm/bridge/analogix_dp_core.c
>>>>>   create mode 100644 drivers/gpu/drm/bridge/analogix_dp_core.h
>>>>>   create mode 100644 drivers/gpu/drm/bridge/analogix_dp_reg.c
>>>> Minor comment: Since there are a few files required for the driver,
>>>> could you create a separate folder within drivers/gpu/drm/bridge?
>>> I agree on this opinion.
>>> Thank you.
>> Thanks for your comment ;)
>>
>> Yeah, bridge/ have been add four new files for this driver, it would be better to
>> collect into a separate folder.
>>
>> I'm wondering should I just name the folder with "analogix_dp/", or we can make
>> it more common (like "analogix/")? (personally I do like the last one)
> I prefer "analogix".

Okay :)

- Yakir

> Best regards,
> Jingoo Han
>
>> Thanks,
>> - Yakir
>>> Best regards,
>>> Jingoo Han
>>>
>>>> Thanks,
>>>> Archit
>>>>
>>>> -- 
>>>> Qualcomm Innovation Center, Inc. is a member of Code Aurora Forum,
>>>> a Linux Foundation Collaborative Project
>>
>
>




From ykk at rock-chips.com  Thu Aug 20 01:04:30 2015
From: ykk at rock-chips.com (Yakir Yang)
Date: Thu, 20 Aug 2015 03:04:30 -0500
Subject: [PATCH v3 05/14] drm: bridge/analogix_dp: fix link_rate &
 lane_count bug
In-Reply-To: <6480369A-D108-4FBD-9041-ED925D8FD922@gmail.com>
References: <1439995728-18046-1-git-send-email-ykk@rock-chips.com>
 <1439995824-18312-1-git-send-email-ykk@rock-chips.com>
 <6480369A-D108-4FBD-9041-ED925D8FD922@gmail.com>
Message-ID: <55D58A0E.4080905@rock-chips.com>

Hi Jingoo,

On 08/20/2015 02:22 AM, Jingoo Han wrote:
> On 2015. 8. 19., at PM 11:50, Yakir Yang <ykk at rock-chips.com> wrote:
>> link_rate and lane_count already configed in analogix_dp_set_link_train(),
> s/configed/configured
>
> Also, the commit name such as "fix ... bug" is not good.
> How about following?
>
> drm: bridge/analogix_dp: remove duplicate configuration of link rate and link count

Thanks, done, it's more readable.

- Yakir
> Best regards,
> Jingoo Han
>
>> so we don't need to config those repeatly after training finished, just
>> remove them out.
>>
>> Beside Display Port 1.2 already support 5.4Gbps link rate, the maximum sets
>> would change from {1.62Gbps, 2.7Gbps} to {1.62Gbps, 2.7Gbps, 5.4Gbps}.
>>
>> Signed-off-by: Yakir Yang <ykk at rock-chips.com>
>> ---
>> Changes in v3:
>> - Take Thierry Reding suggest, link_rate and lane_count shouldn't config to
>>   the DT property value directly, but we can take those as hardware limite.
>>   For example, RK3288 only support 4 physical lanes of 2.7/1.62 Gbps/lane,
>>   so DT property would like "link-rate = 0x0a" "lane-count = 4".
>>
>> Changes in v2: None
>>
>> drivers/gpu/drm/bridge/analogix_dp_core.c | 16 ++++++++--------
>> drivers/gpu/drm/bridge/analogix_dp_core.h |  9 +++++----
>> 2 files changed, 13 insertions(+), 12 deletions(-)
>>
>> diff --git a/drivers/gpu/drm/bridge/analogix_dp_core.c b/drivers/gpu/drm/bridge/analogix_dp_core.c
>> index 480cc13..1778e0a 100644
>> --- a/drivers/gpu/drm/bridge/analogix_dp_core.c
>> +++ b/drivers/gpu/drm/bridge/analogix_dp_core.c
>> @@ -635,6 +635,8 @@ static void analogix_dp_get_max_rx_bandwidth(struct analogix_dp_device *dp,
>>     /*
>>      * For DP rev.1.1, Maximum link rate of Main Link lanes
>>      * 0x06 = 1.62 Gbps, 0x0a = 2.7 Gbps
>> +     * For DP rev.1.2, Maximum link rate of Main Link lanes
>> +     * 0x06 = 1.62 Gbps, 0x0a = 2.7 Gbps, 0x14 = 5.4Gbps
>>      */
>>     analogix_dp_read_byte_from_dpcd(dp, DP_MAX_LINK_RATE, &data);
>>     *bandwidth = data;
>> @@ -668,7 +670,8 @@ static void analogix_dp_init_training(struct analogix_dp_device *dp,
>>     analogix_dp_get_max_rx_lane_count(dp, &dp->link_train.lane_count);
>>
>>     if ((dp->link_train.link_rate != LINK_RATE_1_62GBPS) &&
>> -        (dp->link_train.link_rate != LINK_RATE_2_70GBPS)) {
>> +        (dp->link_train.link_rate != LINK_RATE_2_70GBPS) &&
>> +        (dp->link_train.link_rate != LINK_RATE_5_40GBPS)) {
>>         dev_err(dp->dev, "Rx Max Link Rate is abnormal :%x !\n",
>>             dp->link_train.link_rate);
>>         dp->link_train.link_rate = LINK_RATE_1_62GBPS;
>> @@ -901,8 +904,8 @@ static void analogix_dp_commit(struct analogix_dp_device *dp)
>>         return;
>>     }
>>
>> -    ret = analogix_dp_set_link_train(dp, dp->video_info->lane_count,
>> -                     dp->video_info->link_rate);
>> +    ret = analogix_dp_set_link_train(dp, dp->video_info->max_lane_count,
>> +                     dp->video_info->max_link_rate);
>>     if (ret) {
>>         dev_err(dp->dev, "unable to do link train\n");
>>         return;
>> @@ -912,9 +915,6 @@ static void analogix_dp_commit(struct analogix_dp_device *dp)
>>     analogix_dp_enable_rx_to_enhanced_mode(dp, 1);
>>     analogix_dp_enable_enhanced_mode(dp, 1);
>>
>> -    analogix_dp_set_lane_count(dp, dp->video_info->lane_count);
>> -    analogix_dp_set_link_bandwidth(dp, dp->video_info->link_rate);
>> -
>>     analogix_dp_init_video(dp);
>>     ret = analogix_dp_config_video(dp);
>>     if (ret)
>> @@ -1198,13 +1198,13 @@ static struct video_info *analogix_dp_dt_parse_pdata(struct device *dev)
>>     }
>>
>>     if (of_property_read_u32(dp_node, "analogix,link-rate",
>> -                 &dp_video_config->link_rate)) {
>> +                 &dp_video_config->max_link_rate)) {
>>         dev_err(dev, "failed to get link-rate\n");
>>         return ERR_PTR(-EINVAL);
>>     }
>>
>>     if (of_property_read_u32(dp_node, "analogix,lane-count",
>> -                 &dp_video_config->lane_count)) {
>> +                 &dp_video_config->max_lane_count)) {
>>         dev_err(dev, "failed to get lane-count\n");
>>         return ERR_PTR(-EINVAL);
>>     }
>> diff --git a/drivers/gpu/drm/bridge/analogix_dp_core.h b/drivers/gpu/drm/bridge/analogix_dp_core.h
>> index 2cefde9..941b34f 100644
>> --- a/drivers/gpu/drm/bridge/analogix_dp_core.h
>> +++ b/drivers/gpu/drm/bridge/analogix_dp_core.h
>> @@ -21,8 +21,9 @@
>> #define MAX_EQ_LOOP 5
>>
>> enum link_rate_type {
>> -    LINK_RATE_1_62GBPS = 0x06,
>> -    LINK_RATE_2_70GBPS = 0x0a
>> +    LINK_RATE_1_62GBPS = DP_LINK_BW_1_62,
>> +    LINK_RATE_2_70GBPS = DP_LINK_BW_2_7,
>> +    LINK_RATE_5_40GBPS = DP_LINK_BW_5_4,
>> };
>>
>> enum link_lane_count_type {
>> @@ -128,8 +129,8 @@ struct video_info {
>>     enum color_coefficient ycbcr_coeff;
>>     enum color_depth color_depth;
>>
>> -    enum link_rate_type link_rate;
>> -    enum link_lane_count_type lane_count;
>> +    enum link_rate_type       max_link_rate;
>> +    enum link_lane_count_type max_lane_count;
>> };
>>
>> struct link_train {
>> -- 
>> 1.9.1
>>
>>
>
>




From roger.pau at citrix.com  Thu Aug 20 01:10:23 2015
From: roger.pau at citrix.com (=?UTF-8?B?Um9nZXIgUGF1IE1vbm7DqQ==?=)
Date: Thu, 20 Aug 2015 10:10:23 +0200
Subject: [PATCH v3 15/20] block/xen-blkfront: Make it running on 64KB
 page granularity
In-Reply-To: <1438966019-19322-16-git-send-email-julien.grall@citrix.com>
References: <1438966019-19322-1-git-send-email-julien.grall@citrix.com>
 <1438966019-19322-16-git-send-email-julien.grall@citrix.com>
Message-ID: <55D58B6F.8010904@citrix.com>

Hello,

I have some comments regarding the commit message, IMHO it would be good
that a native English speaker reviews it too.

El 07/08/15 a les 18.46, Julien Grall ha escrit:
> The PV block protocol is using 4KB page granularity. The goal of this
> patch is to allow a Linux using 64KB page granularity using block
> device on a non-modified Xen.
> 
> The block API is using segment which should at least be the size of a
> Linux page. Therefore, the driver will have to break the page in chunk
> of 4K before giving the page to the backend.
> 
> Breaking a 64KB segment in 4KB chunk will result to have some chunk with
> no data.

I would rewrite the above line as:

When breaking a 64KB segment into 4KB chunks it is possible that some
chunks are empty.

> As the PV protocol always require to have data in the chunk, we
> have to count the number of Xen page which will be in use and avoid to
                                  ^pages
> sent empty chunk.
  ^and avoid sending empty chunks.
> 
> Note that, a pre-defined number of grant is reserved before preparing
                                     ^grants are
> the request. This pre-defined number is based on the number and the
> maximum size of the segments. If each segment contain a very small
                                                ^contains
> amount of data, the driver may reserve too much grant (16 grant is
                                             ^many grants   ^grants are
> reserved per segment with 64KB page granularity).
> 
> Futhermore, in the case of persistent grant we allocate one Linux page
                                        ^grants
> per grant although only the 4KB of the page will be effectively use.
                             ^first                              ^in
> This could be improved by share the page with multiple grants.
                            ^sharing
> 
> Signed-off-by: Julien Grall <julien.grall at citrix.com>

LGTM:

Acked-by: Roger Pau Monn? <roger.pau at citrix.com>

Just one question.

[...]
> @@ -559,73 +669,30 @@ static int blkif_queue_rw_req(struct request *req)
>  				ring_req->operation = 0;
>  			}
>  		}
> -		ring_req->u.rw.nr_segments = nseg;
> -	}
> -	for_each_sg(info->shadow[id].sg, sg, nseg, i) {
> -		fsect = sg->offset >> 9;
> -		lsect = fsect + (sg->length >> 9) - 1;
> -
> -		if ((ring_req->operation == BLKIF_OP_INDIRECT) &&
> -		    (i % SEGS_PER_INDIRECT_FRAME == 0)) {
> -			if (segments)
> -				kunmap_atomic(segments);
> -
> -			n = i / SEGS_PER_INDIRECT_FRAME;
> -			gnt_list_entry = get_indirect_grant(&gref_head, info);
> -			info->shadow[id].indirect_grants[n] = gnt_list_entry;
> -			segments = kmap_atomic(gnt_list_entry->page);
> -			ring_req->u.indirect.indirect_grefs[n] = gnt_list_entry->gref;
> -		}
> -
> -		gnt_list_entry = get_grant(&gref_head,
> -					   xen_page_to_gfn(sg_page(sg)),
> -					   info);
> -		ref = gnt_list_entry->gref;
> -
> -		info->shadow[id].grants_used[i] = gnt_list_entry;
> -
> -		if (rq_data_dir(req) && info->feature_persistent) {
> -			char *bvec_data;
> -			void *shared_data;
> +		ring_req->u.rw.nr_segments = num_grant;
> +	}
>  
> -			BUG_ON(sg->offset + sg->length > PAGE_SIZE);
> +	setup.ring_req = ring_req;
> +	setup.id = id;
> +	for_each_sg(info->shadow[id].sg, sg, num_sg, i) {
> +		BUG_ON(sg->offset + sg->length > PAGE_SIZE);
>  
> -			shared_data = kmap_atomic(gnt_list_entry->page);
> -			bvec_data = kmap_atomic(sg_page(sg));
> +		if (setup.need_copy) {
> +			setup.bvec_off = sg->offset;
> +			setup.bvec_data = kmap_atomic(sg_page(sg));
> +		}
>  
> -			/*
> -			 * this does not wipe data stored outside the
> -			 * range sg->offset..sg->offset+sg->length.
> -			 * Therefore, blkback *could* see data from
> -			 * previous requests. This is OK as long as
> -			 * persistent grants are shared with just one
> -			 * domain. It may need refactoring if this
> -			 * changes
> -			 */
> -			memcpy(shared_data + sg->offset,
> -			       bvec_data   + sg->offset,
> -			       sg->length);
> +		gnttab_foreach_grant_in_range(sg_page(sg),
> +					      sg->offset,
> +					      sg->length,
> +					      blkif_setup_rw_req_grant,
> +					      &setup);

If I'm understanding this right, on x86 gnttab_foreach_grant_in_range is
only going to perform one iteration, since XEN_PAGE_SIZE == PAGE_SIZE.

Roger.


From roger.pau at citrix.com  Thu Aug 20 01:14:11 2015
From: roger.pau at citrix.com (=?UTF-8?B?Um9nZXIgUGF1IE1vbm7DqQ==?=)
Date: Thu, 20 Aug 2015 10:14:11 +0200
Subject: [PATCH v3 16/20] block/xen-blkback: Make it running on 64KB page
 granularity
In-Reply-To: <1438966019-19322-17-git-send-email-julien.grall@citrix.com>
References: <1438966019-19322-1-git-send-email-julien.grall@citrix.com>
 <1438966019-19322-17-git-send-email-julien.grall@citrix.com>
Message-ID: <55D58C53.1020601@citrix.com>

El 07/08/15 a les 18.46, Julien Grall ha escrit:
> The PV block protocol is using 4KB page granularity. The goal of this
> patch is to allow a Linux using 64KB page granularity behaving as a
> block backend on a non-modified Xen.
> 
> It's only necessary to adapt the ring size and the number of request per
> indirect frames. The rest of the code is relying on the grant table
> code.
> 
> Note that the grant table code is allocating a Linux page per grant
> which will result to waste 6OKB for every grant when Linux is using 64KB
> page granularity. This could be improved by sharing the page between
> multiple grants.
> 
> Signed-off-by: Julien Grall <julien.grall at citrix.com>

LGTM:

Acked-by: Roger Pau Monn? <roger.pau at citrix.com>

> ---
> 
> Cc: Konrad Rzeszutek Wilk <konrad.wilk at oracle.com>
> Cc: "Roger Pau Monn?" <roger.pau at citrix.com>
> Cc: Boris Ostrovsky <boris.ostrovsky at oracle.com>
> Cc: David Vrabel <david.vrabel at citrix.com>
> 
> Improvement such as support of 64KB grant is not taken into
> consideration in this patch because we have the requirement to run a
> Linux using 64KB pages on a non-modified Xen.
> 
> This has been tested only with a loop device. I plan to test passing
> hard drive partition but I didn't yet convert the swiotlb code.
> 
>     Changes in v3:
>         - Use DIV_ROUND_UP in INDIRECT_PAGES to avoid a line over 80
>         characters
> ---
>  drivers/block/xen-blkback/blkback.c |  5 +++--
>  drivers/block/xen-blkback/common.h  | 17 +++++++++++++----
>  drivers/block/xen-blkback/xenbus.c  |  9 ++++++---
>  3 files changed, 22 insertions(+), 9 deletions(-)
> 
> diff --git a/drivers/block/xen-blkback/blkback.c b/drivers/block/xen-blkback/blkback.c
> index ced9677..d5cce8c 100644
> --- a/drivers/block/xen-blkback/blkback.c
> +++ b/drivers/block/xen-blkback/blkback.c
> @@ -961,7 +961,7 @@ static int xen_blkbk_parse_indirect(struct blkif_request *req,
>  		seg[n].nsec = segments[i].last_sect -
>  			segments[i].first_sect + 1;
>  		seg[n].offset = (segments[i].first_sect << 9);
> -		if ((segments[i].last_sect >= (PAGE_SIZE >> 9)) ||
> +		if ((segments[i].last_sect >= (XEN_PAGE_SIZE >> 9)) ||
>  		    (segments[i].last_sect < segments[i].first_sect)) {
>  			rc = -EINVAL;
>  			goto unmap;
> @@ -1210,6 +1210,7 @@ static int dispatch_rw_block_io(struct xen_blkif *blkif,
>  
>  	req_operation = req->operation == BLKIF_OP_INDIRECT ?
>  			req->u.indirect.indirect_op : req->operation;
> +
>  	if ((req->operation == BLKIF_OP_INDIRECT) &&
>  	    (req_operation != BLKIF_OP_READ) &&
>  	    (req_operation != BLKIF_OP_WRITE)) {
> @@ -1268,7 +1269,7 @@ static int dispatch_rw_block_io(struct xen_blkif *blkif,
>  			seg[i].nsec = req->u.rw.seg[i].last_sect -
>  				req->u.rw.seg[i].first_sect + 1;
>  			seg[i].offset = (req->u.rw.seg[i].first_sect << 9);
> -			if ((req->u.rw.seg[i].last_sect >= (PAGE_SIZE >> 9)) ||
> +			if ((req->u.rw.seg[i].last_sect >= (XEN_PAGE_SIZE >> 9)) ||
>  			    (req->u.rw.seg[i].last_sect <
>  			     req->u.rw.seg[i].first_sect))
>  				goto fail_response;
> diff --git a/drivers/block/xen-blkback/common.h b/drivers/block/xen-blkback/common.h
> index 45a044a..68e87a0 100644
> --- a/drivers/block/xen-blkback/common.h
> +++ b/drivers/block/xen-blkback/common.h
> @@ -39,6 +39,7 @@
>  #include <asm/pgalloc.h>
>  #include <asm/hypervisor.h>
>  #include <xen/grant_table.h>
> +#include <xen/page.h>
>  #include <xen/xenbus.h>
>  #include <xen/interface/io/ring.h>
>  #include <xen/interface/io/blkif.h>
> @@ -51,12 +52,20 @@ extern unsigned int xen_blkif_max_ring_order;
>   */
>  #define MAX_INDIRECT_SEGMENTS 256
>  
> -#define SEGS_PER_INDIRECT_FRAME \
> -	(PAGE_SIZE/sizeof(struct blkif_request_segment))
> +/*
> + * Xen use 4K pages. The guest may use different page size (4K or 64K)

Please expand this comment to mention that it only applies to ARM, for
now on x86 the backend and the frontend always use the same page size.

Roger.


From roger.pau at citrix.com  Thu Aug 20 01:15:10 2015
From: roger.pau at citrix.com (=?windows-1252?Q?Roger_Pau_Monn=E9?=)
Date: Thu, 20 Aug 2015 10:15:10 +0200
Subject: [Xen-devel] [PATCH v3 00/20] xen/arm64: Add support for 64KB page
In-Reply-To: <55D521F2.5080504@citrix.com>
References: <1438966019-19322-1-git-send-email-julien.grall@citrix.com>
 <55D521F2.5080504@citrix.com>
Message-ID: <55D58C8E.9000200@citrix.com>

El 20/08/15 a les 2.40, Julien Grall ha escrit:
> Hi,
> 
> Ping? I'm missing some reviews on block and netfront code.

Sorry, I didn't realize some of the patches were changed and the Ack
dropped. I think I've reviewed everything related to block.

Roger.



From ykk at rock-chips.com  Thu Aug 20 01:18:30 2015
From: ykk at rock-chips.com (Yakir Yang)
Date: Thu, 20 Aug 2015 03:18:30 -0500
Subject: [PATCH v3 13/14] drm: bridge/analogix_dp: move hpd detect to
 connector detect function
In-Reply-To: <6E5CEF9B-19D4-4AC4-B5B1-BC667979302D@gmail.com>
References: <1439995728-18046-1-git-send-email-ykk@rock-chips.com>
 <1439995939-18770-1-git-send-email-ykk@rock-chips.com>
 <6E5CEF9B-19D4-4AC4-B5B1-BC667979302D@gmail.com>
Message-ID: <55D58D56.5070505@rock-chips.com>

Hi Jingoo,

On 08/20/2015 02:49 AM, Jingoo Han wrote:
> On 2015. 8. 19., at PM 11:52, Yakir Yang <ykk at rock-chips.com> wrote:
>
> What is the reason to make this patch?
>
> Please make commit message including the reason.

Okay, I think the below words would be okay :)

"This change just make a little clean to make code more like
drm core expect, move hdp detect code from bridge->enable(),
and place them into connector->detect()."

Thanks,
- Yakir

> Best regards,
> Jingoo Han
>
>> Signed-off-by: Yakir Yang <ykk at rock-chips.com>
>> ---
>> Changes in v3:
>> - move dp hpd detect to connector detect function.
>>
>> Changes in v2: None
>>
>> drivers/gpu/drm/bridge/analogix_dp_core.c | 12 ++++++------
>> 1 file changed, 6 insertions(+), 6 deletions(-)
>>
>> diff --git a/drivers/gpu/drm/bridge/analogix_dp_core.c b/drivers/gpu/drm/bridge/analogix_dp_core.c
>> index 75dd44a..052b9b3 100644
>> --- a/drivers/gpu/drm/bridge/analogix_dp_core.c
>> +++ b/drivers/gpu/drm/bridge/analogix_dp_core.c
>> @@ -915,12 +915,6 @@ static void analogix_dp_commit(struct analogix_dp_device *dp)
>>             DRM_ERROR("failed to disable the panel\n");
>>     }
>>
>> -    ret = analogix_dp_detect_hpd(dp);
>> -    if (ret) {
>> -        /* Cable has been disconnected, we're done */
>> -        return;
>> -    }
>> -
>>     ret = analogix_dp_handle_edid(dp);
>>     if (ret) {
>>         dev_err(dp->dev, "unable to handle edid\n");
>> @@ -953,6 +947,12 @@ static void analogix_dp_commit(struct analogix_dp_device *dp)
>> static enum drm_connector_status analogix_dp_detect(
>>                 struct drm_connector *connector, bool force)
>> {
>> +    struct analogix_dp_device *dp = connector_to_dp(connector);
>> +
>> +    if (analogix_dp_detect_hpd(dp))
>> +        /* Cable has been disconnected, we're done */
>> +        return connector_status_disconnected;
>> +
>>     return connector_status_connected;
>> }
>>
>> -- 
>> 1.9.1
>>
>>
>
>




From l.stach at pengutronix.de  Thu Aug 20 01:27:23 2015
From: l.stach at pengutronix.de (Lucas Stach)
Date: Thu, 20 Aug 2015 10:27:23 +0200
Subject: [PATCH v7 3/6] PCI: designware: Add ARM64 support
In-Reply-To: <EE11001F9E5DDD47B7634E2F8A612F2E01D8139B@lhreml503-mbs>
References: <1439812554-180426-1-git-send-email-wangzhou1@hisilicon.com>
 <1439812554-180426-4-git-send-email-wangzhou1@hisilicon.com>
 <1439988852.31432.15.camel@pengutronix.de>
 <EE11001F9E5DDD47B7634E2F8A612F2E01D81315@lhreml503-mbs>
 <1439998622.31432.44.camel@pengutronix.de>
 <EE11001F9E5DDD47B7634E2F8A612F2E01D8139B@lhreml503-mbs>
Message-ID: <1440059243.31432.59.camel@pengutronix.de>

Hi Gab,

Am Mittwoch, den 19.08.2015, 16:34 +0000 schrieb Gabriele Paoloni:
> Hi Lucas
> 
> First of all many thanks for the quick reply, really appreciated
> 
> > -----Original Message-----
> > From: Lucas Stach [mailto:l.stach at pengutronix.de]
> > Sent: Wednesday, August 19, 2015 4:37 PM
> > To: Gabriele Paoloni
> > Cc: Wangzhou (B); Bjorn Helgaas; jingoohan1 at gmail.com; Pratyush Anand;
> > Arnd Bergmann; linux at arm.linux.org.uk; thomas.petazzoni at free-
> > electrons.com; lorenzo.pieralisi at arm.com; james.morse at arm.com;
> > Liviu.Dudau at arm.com; jason at lakedaemon.net; robh at kernel.org; linux-
> > pci at vger.kernel.org; linux-arm-kernel at lists.infradead.org;
> > devicetree at vger.kernel.org; Yuanzhichang; Zhudacai; zhangjukuo;
> > qiuzhenfa; liudongdong (C); qiujiang; xuwei (O); Liguozhu (Kenneth)
> > Subject: Re: [PATCH v7 3/6] PCI: designware: Add ARM64 support
> > 
> > Hi Gab,
> > 
> > Am Mittwoch, den 19.08.2015, 15:16 +0000 schrieb Gabriele Paoloni:
> > > Hi Lucas
> > >
> > > I have rewritten the patch to take into account multiple controllers.
> > >
> > > As you can see now there is a static var in dw_pcie_host_init() that
> > tracks
> > > the bus numbers used.
> > 
> > This is wrong. The DT specifies the valid bus number range. You can not
> > just assign the next free bus number to the root bus.
> 
> I think this is what is being done in
> http://lxr.free-electrons.com/source/arch/arm/kernel/bios32.c#L495
> and currently designware assigns the root bus number in
> http://lxr.free-electrons.com/source/drivers/pci/host/pcie-designware.c#L730
> 
You found the right spot. It works a bit different than I remember, but
is less broken than your current code. :)

It actually assigns the next instance a root bus number behind the
current instances bus range. Please note the difference to your code
which assigns the next free bus number, which may still lay within the
current instances bus range.

> 
> In general I agree with you but if you look at all the current drivers 
> based on designware none of them define the "bus-range" dtb property.
> Therefore doing as you say would break the current driver when we have
> multiple controllers...am I right?
> 
The current _code_ works fine for multiple controllers. It's just that
you must define the bus range property in the DTB if you want to enable
multiple instances of one controller and support a kernel without PCI
domains support. As all current implementations have only a single
instance of the controller per SoC, or depend on PCI domain support,
it's totally fine for them to not define the bus ranges property, as
it's an optional property and it is well defined how things behave if it
is absent. We absolutely need to keep that specified behavior.

> If that is the case in order to fix this in the way you say I would need
> to assign "bus-range" for all the PCIe drivers with multiple controllers:
> in this case I would split the default range evenly (that is, if we have 
> two controllers I would define "bus-range"  0-127 and 128-255)
> 
> If you think this solution is ok I can go for it. My only doubt was about
> touching other vendors DTBs....
> 
You don't need to touch any of the current DTBs, as they are fine with
the default bus range behavior. You need to keep the specified behavior
of the bus range property with the new code.

Regards,
Lucas
> 
> > 
> > It is perfectly valid to have a bus range of 0x00-0x10 assigned to one
> > instance and 0x50-0xff to the next instance. Additional with PCIe
> > hotplug you may not use the full range of the bus numbers on one
> > instance at the first scan, but only later populate more buses when
> > more
> > bridges are added to the tree.
> > 
> > > Drivers that do not specify the bus range in the DTB set pp-
> > >root_bus_nr = DW_ROOT_NR_UNDEFINED.
> > > Designware will check if the flag is set and will use the automatic
> > bus range
> > > assignment.
> > 
> > No, please lets get rid of this assignment altogether. The glue drivers
> > have no business in assigning the bus range. Please remove the
> > pp->root_bus_nr assignment from all the glue drivers.
> > 
> > "bus range" is a generic DW PCIe property, so just parse the root bus
> > number from the DT, it is handled the same way for all the DW based
> > PCIe
> > drivers. The bindings specifies that if the bus range property is
> > missing the range is 0x00-0xff, so you can default to 0 as the root bus
> > number in that case.
> > 
> > Also I would think this conversion warrants a patch on its own and
> > should not be mixed in the ARM64 support patch.
> > 
> > Regards,
> > Lucas
> > 

-- 
Pengutronix e.K.             | Lucas Stach                 |
Industrial Linux Solutions   | http://www.pengutronix.de/  |



From Adam.Thomson.Opensource at diasemi.com  Thu Aug 20 01:30:35 2015
From: Adam.Thomson.Opensource at diasemi.com (Opensource [Adam Thomson])
Date: Thu, 20 Aug 2015 08:30:35 +0000
Subject: [PATCH V3] Watchdog: Fix parent of watchdog_devices
In-Reply-To: <db7db9102158b87a4a7169e84e2272b3ba03f9f7.1439954581.git.panand@redhat.com>
References: <db7db9102158b87a4a7169e84e2272b3ba03f9f7.1439954581.git.panand@redhat.com>
Message-ID: <2E89032DDAA8B9408CB92943514A0337AB56C694@SW-EX-MBX01.diasemi.com>

On August 19, 2015 04:28, Pratyush Anand wrote:

> diff --git a/drivers/watchdog/da9052_wdt.c b/drivers/watchdog/da9052_wdt.c
> index 2e9589652e1e..67e67977bd29 100644
> --- a/drivers/watchdog/da9052_wdt.c
> +++ b/drivers/watchdog/da9052_wdt.c
> @@ -195,6 +195,7 @@ static int da9052_wdt_probe(struct platform_device *pdev)
>  	da9052_wdt->timeout = DA9052_DEF_TIMEOUT;
>  	da9052_wdt->info = &da9052_wdt_info;
>  	da9052_wdt->ops = &da9052_wdt_ops;
> +	da9052_wdt->parent = &pdev->dev;
>  	watchdog_set_drvdata(da9052_wdt, driver_data);
> 
>  	kref_init(&driver_data->kref);
> diff --git a/drivers/watchdog/da9055_wdt.c b/drivers/watchdog/da9055_wdt.c
> index 495089d8dbfe..04d1430d93d2 100644
> --- a/drivers/watchdog/da9055_wdt.c
> +++ b/drivers/watchdog/da9055_wdt.c
> @@ -161,6 +161,7 @@ static int da9055_wdt_probe(struct platform_device *pdev)
>  	da9055_wdt->timeout = DA9055_DEF_TIMEOUT;
>  	da9055_wdt->info = &da9055_wdt_info;
>  	da9055_wdt->ops = &da9055_wdt_ops;
> +	da9055_wdt->parent = &pdev->dev;
>  	watchdog_set_nowayout(da9055_wdt, nowayout);
>  	watchdog_set_drvdata(da9055_wdt, driver_data);
> 
> diff --git a/drivers/watchdog/da9062_wdt.c b/drivers/watchdog/da9062_wdt.c
> index b3a870ce85be..7386111220d5 100644
> --- a/drivers/watchdog/da9062_wdt.c
> +++ b/drivers/watchdog/da9062_wdt.c
> @@ -210,6 +210,7 @@ static int da9062_wdt_probe(struct platform_device *pdev)
>  	wdt->wdtdev.max_timeout = DA9062_WDT_MAX_TIMEOUT;
>  	wdt->wdtdev.timeout = DA9062_WDG_DEFAULT_TIMEOUT;
>  	wdt->wdtdev.status = WATCHDOG_NOWAYOUT_INIT_STATUS;
> +	wdt->wdtdev.parent = &pdev->dev;
> 
>  	watchdog_set_drvdata(&wdt->wdtdev, wdt);
>  	dev_set_drvdata(&pdev->dev, wdt);
> diff --git a/drivers/watchdog/da9063_wdt.c b/drivers/watchdog/da9063_wdt.c
> index e2fe2ebdebd4..6bf130bd863d 100644
> --- a/drivers/watchdog/da9063_wdt.c
> +++ b/drivers/watchdog/da9063_wdt.c
> @@ -175,6 +175,7 @@ static int da9063_wdt_probe(struct platform_device *pdev)
>  	wdt->wdtdev.min_timeout = DA9063_WDT_MIN_TIMEOUT;
>  	wdt->wdtdev.max_timeout = DA9063_WDT_MAX_TIMEOUT;
>  	wdt->wdtdev.timeout = DA9063_WDG_TIMEOUT;
> +	wdt->wdtdev.parent = &pdev->dev;
> 
>  	wdt->wdtdev.status = WATCHDOG_NOWAYOUT_INIT_STATUS;
> 

Acked-by: Adam Thomson <Adam.Thomson.Opensource at diasemi.com>

From tomas.winkler at intel.com  Thu Aug 20 01:35:22 2015
From: tomas.winkler at intel.com (Winkler, Tomas)
Date: Thu, 20 Aug 2015 08:35:22 +0000
Subject: [PATCH V3] Watchdog: Fix parent of watchdog_devices
In-Reply-To: <db7db9102158b87a4a7169e84e2272b3ba03f9f7.1439954581.git.panand@redhat.com>
References: <db7db9102158b87a4a7169e84e2272b3ba03f9f7.1439954581.git.panand@redhat.com>
Message-ID: <5B8DA87D05A7694D9FA63FD143655C1B3D42A60A@hasmsx108.ger.corp.intel.com>

> diff --git a/drivers/misc/mei/wd.c b/drivers/misc/mei/wd.c
> index 2bc0f5089f82..b346638833b0 100644
> --- a/drivers/misc/mei/wd.c
> +++ b/drivers/misc/mei/wd.c
> @@ -364,6 +364,7 @@ int mei_watchdog_register(struct mei_device *dev)
> 
>  	int ret;
> 
> +	amt_wd_dev.parent = dev->dev;
>  	/* unlock to perserve correct locking order */
>  	mutex_unlock(&dev->device_lock);
>  	ret = watchdog_register_device(&amt_wd_dev);

Acked-by: Tomas Winkler <tomas.winkler at intel.com>

Should this be got to stable as well?



From panand at redhat.com  Thu Aug 20 01:35:01 2015
From: panand at redhat.com (Pratyush Anand)
Date: Thu, 20 Aug 2015 14:05:01 +0530
Subject: [PATCH V4] Watchdog: Fix parent of watchdog_devices
Message-ID: <d035c08984bb06bd81e49fa587fab1da44533bcc.1440059435.git.panand@redhat.com>

/sys/class/watchdog/watchdogn/device/modalias can help to identify the
driver/module for a given watchdog node. However, many wdt devices do not
set their parent and so, we do not see an entry for device in sysfs for
such devices.

This patch fixes parent of watchdog_device so that
/sys/class/watchdog/watchdogn/device is populated.

Exceptions: booke, diag288, octeon, softdog and w83627hf -- They do not
have any parent. Not sure, how we can identify driver for these devices.

Signed-off-by: Pratyush Anand <panand at redhat.com>
Reviewed-by: Johannes Thumshirn <jthumshirn at suse.de>
Acked-by: Guenter Roeck <linux at roeck-us.net>
Acked-by: H Hartley Sweeten <hsweeten at visionengravers.com>
Acked-by: Lee Jones <lee.jones at linaro.org>
Acked-by: Lubomir Rintel <lkundrak at v3.sk>
Acked-by: Maxime Coquelin <maxime.coquelin at st.com>
Acked-by: Thierry Reding <treding at nvidia.com>
Acked-by: Viresh Kumar <viresh.kumar at linaro.org>
---
* Changes since v3:
- Fixed max no number of columns in the description to 75 
- Fixed grammatical mistake in patch description reported by Uwe
Kleine-K?nig.
- Fixed for mpc8xxx as well.
* Changes since v2:
- Fixed drivers/watchdog/txx9wdt.c:134:20: error: 'pdev' undeclared
Reported-by: kbuild test robot <fengguang.wu at intel.com>
* Changes since v1:
- Squash all commits of V1 into a single patch.
- V1 was here:
	http://www.spinics.net/lists/linux-watchdog/msg07220.html

 drivers/misc/mei/wd.c               | 1 +
 drivers/watchdog/bcm2835_wdt.c      | 1 +
 drivers/watchdog/bcm47xx_wdt.c      | 1 +
 drivers/watchdog/bcm_kona_wdt.c     | 1 +
 drivers/watchdog/coh901327_wdt.c    | 1 +
 drivers/watchdog/da9052_wdt.c       | 1 +
 drivers/watchdog/da9055_wdt.c       | 1 +
 drivers/watchdog/da9062_wdt.c       | 1 +
 drivers/watchdog/da9063_wdt.c       | 1 +
 drivers/watchdog/davinci_wdt.c      | 1 +
 drivers/watchdog/digicolor_wdt.c    | 1 +
 drivers/watchdog/ep93xx_wdt.c       | 1 +
 drivers/watchdog/gpio_wdt.c         | 1 +
 drivers/watchdog/ie6xx_wdt.c        | 1 +
 drivers/watchdog/intel-mid_wdt.c    | 1 +
 drivers/watchdog/jz4740_wdt.c       | 1 +
 drivers/watchdog/mena21_wdt.c       | 1 +
 drivers/watchdog/menf21bmc_wdt.c    | 1 +
 drivers/watchdog/mpc8xxx_wdt.c      | 1 +
 drivers/watchdog/omap_wdt.c         | 1 +
 drivers/watchdog/orion_wdt.c        | 1 +
 drivers/watchdog/pnx4008_wdt.c      | 1 +
 drivers/watchdog/qcom-wdt.c         | 1 +
 drivers/watchdog/retu_wdt.c         | 1 +
 drivers/watchdog/rt2880_wdt.c       | 1 +
 drivers/watchdog/s3c2410_wdt.c      | 1 +
 drivers/watchdog/shwdt.c            | 1 +
 drivers/watchdog/sirfsoc_wdt.c      | 1 +
 drivers/watchdog/sp805_wdt.c        | 1 +
 drivers/watchdog/st_lpc_wdt.c       | 1 +
 drivers/watchdog/stmp3xxx_rtc_wdt.c | 1 +
 drivers/watchdog/tegra_wdt.c        | 1 +
 drivers/watchdog/twl4030_wdt.c      | 1 +
 drivers/watchdog/txx9wdt.c          | 1 +
 drivers/watchdog/ux500_wdt.c        | 1 +
 drivers/watchdog/via_wdt.c          | 1 +
 drivers/watchdog/wm831x_wdt.c       | 1 +
 drivers/watchdog/wm8350_wdt.c       | 1 +
 38 files changed, 38 insertions(+)

diff --git a/drivers/misc/mei/wd.c b/drivers/misc/mei/wd.c
index 2bc0f5089f82..b346638833b0 100644
--- a/drivers/misc/mei/wd.c
+++ b/drivers/misc/mei/wd.c
@@ -364,6 +364,7 @@ int mei_watchdog_register(struct mei_device *dev)
 
 	int ret;
 
+	amt_wd_dev.parent = dev->dev;
 	/* unlock to perserve correct locking order */
 	mutex_unlock(&dev->device_lock);
 	ret = watchdog_register_device(&amt_wd_dev);
diff --git a/drivers/watchdog/bcm2835_wdt.c b/drivers/watchdog/bcm2835_wdt.c
index 7116968dee12..66c3e656a616 100644
--- a/drivers/watchdog/bcm2835_wdt.c
+++ b/drivers/watchdog/bcm2835_wdt.c
@@ -182,6 +182,7 @@ static int bcm2835_wdt_probe(struct platform_device *pdev)
 	watchdog_set_drvdata(&bcm2835_wdt_wdd, wdt);
 	watchdog_init_timeout(&bcm2835_wdt_wdd, heartbeat, dev);
 	watchdog_set_nowayout(&bcm2835_wdt_wdd, nowayout);
+	bcm2835_wdt_wdd.parent = &pdev->dev;
 	err = watchdog_register_device(&bcm2835_wdt_wdd);
 	if (err) {
 		dev_err(dev, "Failed to register watchdog device");
diff --git a/drivers/watchdog/bcm47xx_wdt.c b/drivers/watchdog/bcm47xx_wdt.c
index b28a072abf78..4064a43f1360 100644
--- a/drivers/watchdog/bcm47xx_wdt.c
+++ b/drivers/watchdog/bcm47xx_wdt.c
@@ -209,6 +209,7 @@ static int bcm47xx_wdt_probe(struct platform_device *pdev)
 
 	wdt->wdd.info = &bcm47xx_wdt_info;
 	wdt->wdd.timeout = WDT_DEFAULT_TIME;
+	wdt->wdd.parent = &pdev->dev;
 	ret = wdt->wdd.ops->set_timeout(&wdt->wdd, timeout);
 	if (ret)
 		goto err_timer;
diff --git a/drivers/watchdog/bcm_kona_wdt.c b/drivers/watchdog/bcm_kona_wdt.c
index 22d8ae65772a..e0c98423f2c9 100644
--- a/drivers/watchdog/bcm_kona_wdt.c
+++ b/drivers/watchdog/bcm_kona_wdt.c
@@ -319,6 +319,7 @@ static int bcm_kona_wdt_probe(struct platform_device *pdev)
 	spin_lock_init(&wdt->lock);
 	platform_set_drvdata(pdev, wdt);
 	watchdog_set_drvdata(&bcm_kona_wdt_wdd, wdt);
+	bcm_kona_wdt_wdd.parent = &pdev->dev;
 
 	ret = bcm_kona_wdt_set_timeout_reg(&bcm_kona_wdt_wdd, 0);
 	if (ret) {
diff --git a/drivers/watchdog/coh901327_wdt.c b/drivers/watchdog/coh901327_wdt.c
index ce12f437f195..a099b77fc0b9 100644
--- a/drivers/watchdog/coh901327_wdt.c
+++ b/drivers/watchdog/coh901327_wdt.c
@@ -358,6 +358,7 @@ static int __init coh901327_probe(struct platform_device *pdev)
 	if (ret < 0)
 		coh901327_wdt.timeout = 60;
 
+	coh901327_wdt.parent = &pdev->dev;
 	ret = watchdog_register_device(&coh901327_wdt);
 	if (ret == 0)
 		dev_info(&pdev->dev,
diff --git a/drivers/watchdog/da9052_wdt.c b/drivers/watchdog/da9052_wdt.c
index 2e9589652e1e..67e67977bd29 100644
--- a/drivers/watchdog/da9052_wdt.c
+++ b/drivers/watchdog/da9052_wdt.c
@@ -195,6 +195,7 @@ static int da9052_wdt_probe(struct platform_device *pdev)
 	da9052_wdt->timeout = DA9052_DEF_TIMEOUT;
 	da9052_wdt->info = &da9052_wdt_info;
 	da9052_wdt->ops = &da9052_wdt_ops;
+	da9052_wdt->parent = &pdev->dev;
 	watchdog_set_drvdata(da9052_wdt, driver_data);
 
 	kref_init(&driver_data->kref);
diff --git a/drivers/watchdog/da9055_wdt.c b/drivers/watchdog/da9055_wdt.c
index 495089d8dbfe..04d1430d93d2 100644
--- a/drivers/watchdog/da9055_wdt.c
+++ b/drivers/watchdog/da9055_wdt.c
@@ -161,6 +161,7 @@ static int da9055_wdt_probe(struct platform_device *pdev)
 	da9055_wdt->timeout = DA9055_DEF_TIMEOUT;
 	da9055_wdt->info = &da9055_wdt_info;
 	da9055_wdt->ops = &da9055_wdt_ops;
+	da9055_wdt->parent = &pdev->dev;
 	watchdog_set_nowayout(da9055_wdt, nowayout);
 	watchdog_set_drvdata(da9055_wdt, driver_data);
 
diff --git a/drivers/watchdog/da9062_wdt.c b/drivers/watchdog/da9062_wdt.c
index b3a870ce85be..7386111220d5 100644
--- a/drivers/watchdog/da9062_wdt.c
+++ b/drivers/watchdog/da9062_wdt.c
@@ -210,6 +210,7 @@ static int da9062_wdt_probe(struct platform_device *pdev)
 	wdt->wdtdev.max_timeout = DA9062_WDT_MAX_TIMEOUT;
 	wdt->wdtdev.timeout = DA9062_WDG_DEFAULT_TIMEOUT;
 	wdt->wdtdev.status = WATCHDOG_NOWAYOUT_INIT_STATUS;
+	wdt->wdtdev.parent = &pdev->dev;
 
 	watchdog_set_drvdata(&wdt->wdtdev, wdt);
 	dev_set_drvdata(&pdev->dev, wdt);
diff --git a/drivers/watchdog/da9063_wdt.c b/drivers/watchdog/da9063_wdt.c
index e2fe2ebdebd4..6bf130bd863d 100644
--- a/drivers/watchdog/da9063_wdt.c
+++ b/drivers/watchdog/da9063_wdt.c
@@ -175,6 +175,7 @@ static int da9063_wdt_probe(struct platform_device *pdev)
 	wdt->wdtdev.min_timeout = DA9063_WDT_MIN_TIMEOUT;
 	wdt->wdtdev.max_timeout = DA9063_WDT_MAX_TIMEOUT;
 	wdt->wdtdev.timeout = DA9063_WDG_TIMEOUT;
+	wdt->wdtdev.parent = &pdev->dev;
 
 	wdt->wdtdev.status = WATCHDOG_NOWAYOUT_INIT_STATUS;
 
diff --git a/drivers/watchdog/davinci_wdt.c b/drivers/watchdog/davinci_wdt.c
index cfdf8a408aea..17454ca653f4 100644
--- a/drivers/watchdog/davinci_wdt.c
+++ b/drivers/watchdog/davinci_wdt.c
@@ -179,6 +179,7 @@ static int davinci_wdt_probe(struct platform_device *pdev)
 	wdd->min_timeout	= 1;
 	wdd->max_timeout	= MAX_HEARTBEAT;
 	wdd->timeout		= DEFAULT_HEARTBEAT;
+	wdd->parent		= &pdev->dev;
 
 	watchdog_init_timeout(wdd, heartbeat, dev);
 
diff --git a/drivers/watchdog/digicolor_wdt.c b/drivers/watchdog/digicolor_wdt.c
index 31d8e4936611..50abe1bf62a5 100644
--- a/drivers/watchdog/digicolor_wdt.c
+++ b/drivers/watchdog/digicolor_wdt.c
@@ -143,6 +143,7 @@ static int dc_wdt_probe(struct platform_device *pdev)
 	}
 	dc_wdt_wdd.max_timeout = U32_MAX / clk_get_rate(wdt->clk);
 	dc_wdt_wdd.timeout = dc_wdt_wdd.max_timeout;
+	dc_wdt_wdd.parent = &pdev->dev;
 
 	spin_lock_init(&wdt->lock);
 
diff --git a/drivers/watchdog/ep93xx_wdt.c b/drivers/watchdog/ep93xx_wdt.c
index 7a2cc7191c58..0a4d7cc05d54 100644
--- a/drivers/watchdog/ep93xx_wdt.c
+++ b/drivers/watchdog/ep93xx_wdt.c
@@ -132,6 +132,7 @@ static int ep93xx_wdt_probe(struct platform_device *pdev)
 	val = readl(mmio_base + EP93XX_WATCHDOG);
 	ep93xx_wdt_wdd.bootstatus = (val & 0x01) ? WDIOF_CARDRESET : 0;
 	ep93xx_wdt_wdd.timeout = timeout;
+	ep93xx_wdt_wdd.parent = &pdev->dev;
 
 	watchdog_set_nowayout(&ep93xx_wdt_wdd, nowayout);
 
diff --git a/drivers/watchdog/gpio_wdt.c b/drivers/watchdog/gpio_wdt.c
index 1687cc2d7122..336bddd84809 100644
--- a/drivers/watchdog/gpio_wdt.c
+++ b/drivers/watchdog/gpio_wdt.c
@@ -217,6 +217,7 @@ static int gpio_wdt_probe(struct platform_device *pdev)
 	priv->wdd.ops		= &gpio_wdt_ops;
 	priv->wdd.min_timeout	= SOFT_TIMEOUT_MIN;
 	priv->wdd.max_timeout	= SOFT_TIMEOUT_MAX;
+	priv->wdd.parent	= &pdev->dev;
 
 	if (watchdog_init_timeout(&priv->wdd, 0, &pdev->dev) < 0)
 		priv->wdd.timeout = SOFT_TIMEOUT_DEF;
diff --git a/drivers/watchdog/ie6xx_wdt.c b/drivers/watchdog/ie6xx_wdt.c
index 9bc39ae51624..78c2541f5d52 100644
--- a/drivers/watchdog/ie6xx_wdt.c
+++ b/drivers/watchdog/ie6xx_wdt.c
@@ -267,6 +267,7 @@ static int ie6xx_wdt_probe(struct platform_device *pdev)
 
 	ie6xx_wdt_dev.timeout = timeout;
 	watchdog_set_nowayout(&ie6xx_wdt_dev, nowayout);
+	ie6xx_wdt_dev.parent = &pdev->dev;
 
 	spin_lock_init(&ie6xx_wdt_data.unlock_sequence);
 
diff --git a/drivers/watchdog/intel-mid_wdt.c b/drivers/watchdog/intel-mid_wdt.c
index 84f6701c391f..0a436b5d1e84 100644
--- a/drivers/watchdog/intel-mid_wdt.c
+++ b/drivers/watchdog/intel-mid_wdt.c
@@ -137,6 +137,7 @@ static int mid_wdt_probe(struct platform_device *pdev)
 	wdt_dev->min_timeout = MID_WDT_TIMEOUT_MIN;
 	wdt_dev->max_timeout = MID_WDT_TIMEOUT_MAX;
 	wdt_dev->timeout = MID_WDT_DEFAULT_TIMEOUT;
+	wdt_dev->parent = &pdev->dev;
 
 	watchdog_set_drvdata(wdt_dev, &pdev->dev);
 	platform_set_drvdata(pdev, wdt_dev);
diff --git a/drivers/watchdog/jz4740_wdt.c b/drivers/watchdog/jz4740_wdt.c
index 4c2cc09c0c57..6a7d5c365438 100644
--- a/drivers/watchdog/jz4740_wdt.c
+++ b/drivers/watchdog/jz4740_wdt.c
@@ -174,6 +174,7 @@ static int jz4740_wdt_probe(struct platform_device *pdev)
 	jz4740_wdt->timeout = heartbeat;
 	jz4740_wdt->min_timeout = 1;
 	jz4740_wdt->max_timeout = MAX_HEARTBEAT;
+	jz4740_wdt->parent = &pdev->dev;
 	watchdog_set_nowayout(jz4740_wdt, nowayout);
 	watchdog_set_drvdata(jz4740_wdt, drvdata);
 
diff --git a/drivers/watchdog/mena21_wdt.c b/drivers/watchdog/mena21_wdt.c
index d193a5e79c38..69013007dc47 100644
--- a/drivers/watchdog/mena21_wdt.c
+++ b/drivers/watchdog/mena21_wdt.c
@@ -197,6 +197,7 @@ static int a21_wdt_probe(struct platform_device *pdev)
 	watchdog_init_timeout(&a21_wdt, 30, &pdev->dev);
 	watchdog_set_nowayout(&a21_wdt, nowayout);
 	watchdog_set_drvdata(&a21_wdt, drv);
+	a21_wdt.parent = &pdev->dev;
 
 	reset = a21_wdt_get_bootstatus(drv);
 	if (reset == 2)
diff --git a/drivers/watchdog/menf21bmc_wdt.c b/drivers/watchdog/menf21bmc_wdt.c
index 59f0913c7341..3aefddebb386 100644
--- a/drivers/watchdog/menf21bmc_wdt.c
+++ b/drivers/watchdog/menf21bmc_wdt.c
@@ -130,6 +130,7 @@ static int menf21bmc_wdt_probe(struct platform_device *pdev)
 	drv_data->wdt.info = &menf21bmc_wdt_info;
 	drv_data->wdt.min_timeout = BMC_WD_TIMEOUT_MIN;
 	drv_data->wdt.max_timeout = BMC_WD_TIMEOUT_MAX;
+	drv_data->wdt.parent = &pdev->dev;
 	drv_data->i2c_client = i2c_client;
 
 	/*
diff --git a/drivers/watchdog/mpc8xxx_wdt.c b/drivers/watchdog/mpc8xxx_wdt.c
index 689381a24887..21eda27686c5 100644
--- a/drivers/watchdog/mpc8xxx_wdt.c
+++ b/drivers/watchdog/mpc8xxx_wdt.c
@@ -185,6 +185,7 @@ static int mpc8xxx_wdt_probe(struct platform_device *ofdev)
 		timeout_sec = timeout / freq;
 
 	mpc8xxx_wdt_dev.timeout = timeout_sec;
+	mpc8xxx_wdt_dev.parent = &ofdev->dev;
 #ifdef MODULE
 	ret = mpc8xxx_wdt_init_late();
 	if (ret)
diff --git a/drivers/watchdog/omap_wdt.c b/drivers/watchdog/omap_wdt.c
index de911c7e477c..d96bee017fd3 100644
--- a/drivers/watchdog/omap_wdt.c
+++ b/drivers/watchdog/omap_wdt.c
@@ -253,6 +253,7 @@ static int omap_wdt_probe(struct platform_device *pdev)
 	wdev->wdog.ops = &omap_wdt_ops;
 	wdev->wdog.min_timeout = TIMER_MARGIN_MIN;
 	wdev->wdog.max_timeout = TIMER_MARGIN_MAX;
+	wdev->wdog.parent = &pdev->dev;
 
 	if (watchdog_init_timeout(&wdev->wdog, timer_margin, &pdev->dev) < 0)
 		wdev->wdog.timeout = TIMER_MARGIN_DEFAULT;
diff --git a/drivers/watchdog/orion_wdt.c b/drivers/watchdog/orion_wdt.c
index ef0c628d5037..c6b8f4a43bde 100644
--- a/drivers/watchdog/orion_wdt.c
+++ b/drivers/watchdog/orion_wdt.c
@@ -567,6 +567,7 @@ static int orion_wdt_probe(struct platform_device *pdev)
 
 	dev->wdt.timeout = wdt_max_duration;
 	dev->wdt.max_timeout = wdt_max_duration;
+	dev->wdt.parent = &pdev->dev;
 	watchdog_init_timeout(&dev->wdt, heartbeat, &pdev->dev);
 
 	platform_set_drvdata(pdev, &dev->wdt);
diff --git a/drivers/watchdog/pnx4008_wdt.c b/drivers/watchdog/pnx4008_wdt.c
index b9c6049c3e78..4224b3ec83a5 100644
--- a/drivers/watchdog/pnx4008_wdt.c
+++ b/drivers/watchdog/pnx4008_wdt.c
@@ -167,6 +167,7 @@ static int pnx4008_wdt_probe(struct platform_device *pdev)
 
 	pnx4008_wdd.bootstatus = (readl(WDTIM_RES(wdt_base)) & WDOG_RESET) ?
 			WDIOF_CARDRESET : 0;
+	pnx4008_wdd.parent = &pdev->dev;
 	watchdog_set_nowayout(&pnx4008_wdd, nowayout);
 
 	pnx4008_wdt_stop(&pnx4008_wdd);	/* disable for now */
diff --git a/drivers/watchdog/qcom-wdt.c b/drivers/watchdog/qcom-wdt.c
index aa03ca8f2d9b..773dcfaee7b2 100644
--- a/drivers/watchdog/qcom-wdt.c
+++ b/drivers/watchdog/qcom-wdt.c
@@ -171,6 +171,7 @@ static int qcom_wdt_probe(struct platform_device *pdev)
 	wdt->wdd.ops = &qcom_wdt_ops;
 	wdt->wdd.min_timeout = 1;
 	wdt->wdd.max_timeout = 0x10000000U / wdt->rate;
+	wdt->wdd.parent = &pdev->dev;
 
 	/*
 	 * If 'timeout-sec' unspecified in devicetree, assume a 30 second
diff --git a/drivers/watchdog/retu_wdt.c b/drivers/watchdog/retu_wdt.c
index b7c68e275aeb..39cd51df2ffc 100644
--- a/drivers/watchdog/retu_wdt.c
+++ b/drivers/watchdog/retu_wdt.c
@@ -127,6 +127,7 @@ static int retu_wdt_probe(struct platform_device *pdev)
 	retu_wdt->timeout	= RETU_WDT_MAX_TIMER;
 	retu_wdt->min_timeout	= 0;
 	retu_wdt->max_timeout	= RETU_WDT_MAX_TIMER;
+	retu_wdt->parent	= &pdev->dev;
 
 	watchdog_set_drvdata(retu_wdt, wdev);
 	watchdog_set_nowayout(retu_wdt, nowayout);
diff --git a/drivers/watchdog/rt2880_wdt.c b/drivers/watchdog/rt2880_wdt.c
index a6f7e2e29beb..1967919ae743 100644
--- a/drivers/watchdog/rt2880_wdt.c
+++ b/drivers/watchdog/rt2880_wdt.c
@@ -161,6 +161,7 @@ static int rt288x_wdt_probe(struct platform_device *pdev)
 	rt288x_wdt_dev.dev = &pdev->dev;
 	rt288x_wdt_dev.bootstatus = rt288x_wdt_bootcause();
 	rt288x_wdt_dev.max_timeout = (0xfffful / rt288x_wdt_freq);
+	rt288x_wdt_dev.parent = &pdev->dev;
 
 	watchdog_init_timeout(&rt288x_wdt_dev, rt288x_wdt_dev.max_timeout,
 			      &pdev->dev);
diff --git a/drivers/watchdog/s3c2410_wdt.c b/drivers/watchdog/s3c2410_wdt.c
index e89ae027c91d..d781000c7825 100644
--- a/drivers/watchdog/s3c2410_wdt.c
+++ b/drivers/watchdog/s3c2410_wdt.c
@@ -607,6 +607,7 @@ static int s3c2410wdt_probe(struct platform_device *pdev)
 	watchdog_set_nowayout(&wdt->wdt_device, nowayout);
 
 	wdt->wdt_device.bootstatus = s3c2410wdt_get_bootstatus(wdt);
+	wdt->wdt_device.parent = &pdev->dev;
 
 	ret = watchdog_register_device(&wdt->wdt_device);
 	if (ret) {
diff --git a/drivers/watchdog/shwdt.c b/drivers/watchdog/shwdt.c
index 567458b137a6..f90812170657 100644
--- a/drivers/watchdog/shwdt.c
+++ b/drivers/watchdog/shwdt.c
@@ -252,6 +252,7 @@ static int sh_wdt_probe(struct platform_device *pdev)
 
 	watchdog_set_nowayout(&sh_wdt_dev, nowayout);
 	watchdog_set_drvdata(&sh_wdt_dev, wdt);
+	sh_wdt_dev.parent = &pdev->dev;
 
 	spin_lock_init(&wdt->lock);
 
diff --git a/drivers/watchdog/sirfsoc_wdt.c b/drivers/watchdog/sirfsoc_wdt.c
index 42fa5c0c518a..d0578ab2e636 100644
--- a/drivers/watchdog/sirfsoc_wdt.c
+++ b/drivers/watchdog/sirfsoc_wdt.c
@@ -154,6 +154,7 @@ static int sirfsoc_wdt_probe(struct platform_device *pdev)
 
 	watchdog_init_timeout(&sirfsoc_wdd, timeout, &pdev->dev);
 	watchdog_set_nowayout(&sirfsoc_wdd, nowayout);
+	sirfsoc_wdd.parent = &pdev->dev;
 
 	ret = watchdog_register_device(&sirfsoc_wdd);
 	if (ret)
diff --git a/drivers/watchdog/sp805_wdt.c b/drivers/watchdog/sp805_wdt.c
index 4e7fec36f5c3..01d816251302 100644
--- a/drivers/watchdog/sp805_wdt.c
+++ b/drivers/watchdog/sp805_wdt.c
@@ -226,6 +226,7 @@ sp805_wdt_probe(struct amba_device *adev, const struct amba_id *id)
 	wdt->adev = adev;
 	wdt->wdd.info = &wdt_info;
 	wdt->wdd.ops = &wdt_ops;
+	wdt->wdd.parent = &adev->dev;
 
 	spin_lock_init(&wdt->lock);
 	watchdog_set_nowayout(&wdt->wdd, nowayout);
diff --git a/drivers/watchdog/st_lpc_wdt.c b/drivers/watchdog/st_lpc_wdt.c
index 6785afdc0fca..14e9badf2bfa 100644
--- a/drivers/watchdog/st_lpc_wdt.c
+++ b/drivers/watchdog/st_lpc_wdt.c
@@ -241,6 +241,7 @@ static int st_wdog_probe(struct platform_device *pdev)
 		return -EINVAL;
 	}
 	st_wdog_dev.max_timeout = 0xFFFFFFFF / st_wdog->clkrate;
+	st_wdog_dev.parent = &pdev->dev;
 
 	ret = clk_prepare_enable(clk);
 	if (ret) {
diff --git a/drivers/watchdog/stmp3xxx_rtc_wdt.c b/drivers/watchdog/stmp3xxx_rtc_wdt.c
index e7f0d5b60d3d..3ee6128a540e 100644
--- a/drivers/watchdog/stmp3xxx_rtc_wdt.c
+++ b/drivers/watchdog/stmp3xxx_rtc_wdt.c
@@ -76,6 +76,7 @@ static int stmp3xxx_wdt_probe(struct platform_device *pdev)
 	watchdog_set_drvdata(&stmp3xxx_wdd, &pdev->dev);
 
 	stmp3xxx_wdd.timeout = clamp_t(unsigned, heartbeat, 1, STMP3XXX_MAX_TIMEOUT);
+	stmp3xxx_wdd.parent = &pdev->dev;
 
 	ret = watchdog_register_device(&stmp3xxx_wdd);
 	if (ret < 0) {
diff --git a/drivers/watchdog/tegra_wdt.c b/drivers/watchdog/tegra_wdt.c
index 30451ea46902..7f97cdd53f29 100644
--- a/drivers/watchdog/tegra_wdt.c
+++ b/drivers/watchdog/tegra_wdt.c
@@ -218,6 +218,7 @@ static int tegra_wdt_probe(struct platform_device *pdev)
 	wdd->ops = &tegra_wdt_ops;
 	wdd->min_timeout = MIN_WDT_TIMEOUT;
 	wdd->max_timeout = MAX_WDT_TIMEOUT;
+	wdd->parent = &pdev->dev;
 
 	watchdog_set_drvdata(wdd, wdt);
 
diff --git a/drivers/watchdog/twl4030_wdt.c b/drivers/watchdog/twl4030_wdt.c
index 2c1db6fa9a27..9bf3cc0f3961 100644
--- a/drivers/watchdog/twl4030_wdt.c
+++ b/drivers/watchdog/twl4030_wdt.c
@@ -83,6 +83,7 @@ static int twl4030_wdt_probe(struct platform_device *pdev)
 	wdt->timeout		= 30;
 	wdt->min_timeout	= 1;
 	wdt->max_timeout	= 30;
+	wdt->parent = &pdev->dev;
 
 	watchdog_set_nowayout(wdt, nowayout);
 	platform_set_drvdata(pdev, wdt);
diff --git a/drivers/watchdog/txx9wdt.c b/drivers/watchdog/txx9wdt.c
index 7f615933d31a..c2da880292bc 100644
--- a/drivers/watchdog/txx9wdt.c
+++ b/drivers/watchdog/txx9wdt.c
@@ -131,6 +131,7 @@ static int __init txx9wdt_probe(struct platform_device *dev)
 	txx9wdt.timeout = timeout;
 	txx9wdt.min_timeout = 1;
 	txx9wdt.max_timeout = WD_MAX_TIMEOUT;
+	txx9wdt.parent = &dev->dev;
 	watchdog_set_nowayout(&txx9wdt, nowayout);
 
 	ret = watchdog_register_device(&txx9wdt);
diff --git a/drivers/watchdog/ux500_wdt.c b/drivers/watchdog/ux500_wdt.c
index 9de09ab00838..37c084353cce 100644
--- a/drivers/watchdog/ux500_wdt.c
+++ b/drivers/watchdog/ux500_wdt.c
@@ -96,6 +96,7 @@ static int ux500_wdt_probe(struct platform_device *pdev)
 			ux500_wdt.max_timeout = WATCHDOG_MAX28;
 	}
 
+	ux500_wdt.parent = &pdev->dev;
 	watchdog_set_nowayout(&ux500_wdt, nowayout);
 
 	/* disable auto off on sleep */
diff --git a/drivers/watchdog/via_wdt.c b/drivers/watchdog/via_wdt.c
index 56369c4f1961..5f9cbc37520d 100644
--- a/drivers/watchdog/via_wdt.c
+++ b/drivers/watchdog/via_wdt.c
@@ -206,6 +206,7 @@ static int wdt_probe(struct pci_dev *pdev,
 		timeout = WDT_TIMEOUT;
 
 	wdt_dev.timeout = timeout;
+	wdt_dev.parent = &pdev->dev;
 	watchdog_set_nowayout(&wdt_dev, nowayout);
 	if (readl(wdt_mem) & VIA_WDT_FIRED)
 		wdt_dev.bootstatus |= WDIOF_CARDRESET;
diff --git a/drivers/watchdog/wm831x_wdt.c b/drivers/watchdog/wm831x_wdt.c
index 2fa17e746ff6..8d1184aee932 100644
--- a/drivers/watchdog/wm831x_wdt.c
+++ b/drivers/watchdog/wm831x_wdt.c
@@ -215,6 +215,7 @@ static int wm831x_wdt_probe(struct platform_device *pdev)
 
 	wm831x_wdt->info = &wm831x_wdt_info;
 	wm831x_wdt->ops = &wm831x_wdt_ops;
+	wm831x_wdt->parent = &pdev->dev;
 	watchdog_set_nowayout(wm831x_wdt, nowayout);
 	watchdog_set_drvdata(wm831x_wdt, driver_data);
 
diff --git a/drivers/watchdog/wm8350_wdt.c b/drivers/watchdog/wm8350_wdt.c
index 34d272ada23d..4ab4b8347d45 100644
--- a/drivers/watchdog/wm8350_wdt.c
+++ b/drivers/watchdog/wm8350_wdt.c
@@ -151,6 +151,7 @@ static int wm8350_wdt_probe(struct platform_device *pdev)
 
 	watchdog_set_nowayout(&wm8350_wdt, nowayout);
 	watchdog_set_drvdata(&wm8350_wdt, wm8350);
+	wm8350_wdt.parent = &pdev->dev;
 
 	/* Default to 4s timeout */
 	wm8350_wdt_set_timeout(&wm8350_wdt, 4);
-- 
2.4.3



From hanjun.guo at linaro.org  Thu Aug 20 01:42:12 2015
From: hanjun.guo at linaro.org (Hanjun Guo)
Date: Thu, 20 Aug 2015 16:42:12 +0800
Subject: [PATCH] arm64: entry: always restore x0 from the stack on syscall
 return
In-Reply-To: <20150819165643.GD10297@arm.com>
References: <1439996989-5772-1-git-send-email-will.deacon@arm.com>
 <20150819160320.GI24062@e104818-lin.cambridge.arm.com>
 <20150819162359.GA10297@arm.com>
 <20150819163504.GL24062@e104818-lin.cambridge.arm.com>
 <20150819165643.GD10297@arm.com>
Message-ID: <55D592E4.50609@linaro.org>

On 08/20/2015 12:56 AM, Will Deacon wrote:
> On Wed, Aug 19, 2015 at 05:35:05PM +0100, Catalin Marinas wrote:
>> On Wed, Aug 19, 2015 at 05:23:59PM +0100, Will Deacon wrote:
>>> On Wed, Aug 19, 2015 at 05:03:20PM +0100, Catalin Marinas wrote:
>>>> There is another str x0 in __sys_trace_return which I think we could
>>>> remove.
>>>
>>> Hmm, I don't think we can remove that. It's needed on the slowpath to
>>> update the pt_regs with either -ENOSYS (for __ni_sys_trace) or the
>>> syscall return value from the blr in __sys_trace.
>>>
>>> What we can do instead is change the branch above to branch to
>>> __sys_trace_return_skipped. Patch below.
>>>
>>> Will
>>>
>>> --->8
>>>
>>> diff --git a/arch/arm64/kernel/entry.S b/arch/arm64/kernel/entry.S
>>> index 2a5e64ccc991..088322ff1ba0 100644
>>> --- a/arch/arm64/kernel/entry.S
>>> +++ b/arch/arm64/kernel/entry.S
>>> @@ -619,7 +619,7 @@ ret_fast_syscall:
>>>          kernel_exit 0
>>>   ret_fast_syscall_trace:
>>>          enable_irq                              // enable interrupts
>>> -       b       __sys_trace_return
>>> +       b       __sys_trace_return_skipped      // we already saved x0
>>
>> That would do. With this added:
>>
>> Reviewed-by: Catalin Marinas <catalin.marinas at arm.com>
>>
>> (or I can take it for 4.2 but I'd like more testing like LTP)
>
> Yeah, I'll run some tests overnight and see how it holds up.

How is the stress test going on? I didn't do some stress test but
when I applied this patch (along with above additions), the problem
I reported is gone,

Tested-by: Hanjun Guo <hanjun.guo at linaro.org>

Thanks
Hanjun


From shawnguo at kernel.org  Thu Aug 20 01:57:08 2015
From: shawnguo at kernel.org (Shawn Guo)
Date: Thu, 20 Aug 2015 16:57:08 +0800
Subject: [PATCH] ARM: imx: mach-imx6ul: Fix allmodconfig build
In-Reply-To: <1440009090-25799-1-git-send-email-festevam@gmail.com>
References: <1440009090-25799-1-git-send-email-festevam@gmail.com>
Message-ID: <20150820085707.GA9137@tiger>

On Wed, Aug 19, 2015 at 03:31:30PM -0300, Fabio Estevam wrote:
> From: Fabio Estevam <fabio.estevam at freescale.com>
> 
> We should call phy_register_fixup_for_uid() only when CONFIG_PHYLIB
> is built-in, otherwise we get the following link error when building
> allmodconfig:
> 
> arch/arm/mach-imx/built-in.o: In function `imx6ul_init_machine':
> :(.init.text+0xa714): undefined reference to `phy_register_fixup_for_uid'
> 
> This is the same approach done in mach-imx6q.c and mach-imx6sx.c.
> 
> Reported-by: Olof Johansson <olof at lixom.net>
> Signed-off-by: Fabio Estevam <fabio.estevam at freescale.com>

Thanks, Fabio.

Acked-by: Shawn Guo <shawnguo at kernel.org>

Olof,

I suppose that you will pick up the fix directly.  Let me know if you
think differently.  Thanks.

Shawn


From shawnguo at kernel.org  Thu Aug 20 02:06:46 2015
From: shawnguo at kernel.org (Shawn Guo)
Date: Thu, 20 Aug 2015 17:06:46 +0800
Subject: [GIT PULL 1/3] ARM: imx: soc updates for 4.3
In-Reply-To: <20150818201416.GA4732@localhost>
References: <1439311351-5268-1-git-send-email-shawnguo@kernel.org>
 <20150818201416.GA4732@localhost>
Message-ID: <20150820090646.GB9137@tiger>

On Tue, Aug 18, 2015 at 01:14:16PM -0700, Olof Johansson wrote:
> Hi,
> 
> On Wed, Aug 12, 2015 at 12:42:29AM +0800, Shawn Guo wrote:
> > Hi arm-soc maintainers,
> > 
> > This is the i.MX SoC changes for 4.3.  There are some input and rtc
> > changes, because they are applied as a series.  Subsystem maintainers
> > have ACKed these changes, so it should be fine to send them via arm-soc
> > tree.
> 
> In some of these cases, may I ask why? For example, the RTC changes look
> like they could just go in through the driver tree -- adding DT support to
> a driver can definitely do so (and the DT changes to plumb up the device can go
> through your DT branch).

It's primarily because that subsystem maintainers gave their ACKs and
asked me to apply the series as a whole.  I will pick up subsystem
patches only when it's necessary in the future.

Shawn


From stripathi at apm.com  Thu Aug 20 02:07:13 2015
From: stripathi at apm.com (Suman Tripathi)
Date: Thu, 20 Aug 2015 14:37:13 +0530
Subject: arch/arm/kernel/setup.c does not compile at -O0
In-Reply-To: <20150730155048.GS7557@n2100.arm.linux.org.uk>
References: <55BA1E62.9080103@free.fr>
 <CAOHikRBW+OnYvduFMVnssYAxDP4u+E+Q9NJ+5iDhnc21OvFRpg@mail.gmail.com>
 <20150730155048.GS7557@n2100.arm.linux.org.uk>
Message-ID: <CAOHikRASXDj2DWubjrQsy-BvAM7oGW06ddUcuRSGbM__gMYwPg@mail.gmail.com>

Hi Russell,

On Thu, Jul 30, 2015 at 9:20 PM, Russell King - ARM Linux
<linux at arm.linux.org.uk> wrote:
> On Thu, Jul 30, 2015 at 08:53:45PM +0530, Suman Tripathi wrote:
>> Hi,
>>
>> On Thu, Jul 30, 2015 at 6:23 PM, Mason <slash.tmp at free.fr> wrote:
>> >
>> > Hello everyone,
>> >
>> > I'm trying to debug a live kernel (v3.14) using a DS-5 JTAG probe.
>> >
>> > In order to make the control flow easier to follow, I disabled
>> > optimizations by adding
>> >
>> >   subdir-ccflags-y := -O0
>> >
>> > to arch/arm/kernel/Makefile
>> >
>> > With that change, linking fails:
>> >
>> > arch/arm/kernel/setup.c:924: undefined reference to `psci_smp_ops'
>> >
>> >       if (psci_smp_available())
>> >         smp_set_ops(&psci_smp_ops);
>> >
>> > #ifdef CONFIG_ARM_PSCI
>> > void psci_init(void);
>> > bool psci_smp_available(void);
>> > #else
>> > static inline void psci_init(void) { }
>> > static inline bool psci_smp_available(void) { return false; }
>> > #endif
>> >
>> > The optimizer is able to remove the entire block, but this
>> > does not happen when optimizations are disabled.
>> >
>> > Is compiling at -O0 not supported?
>>
>> If you have inline functions, it won't compile at -O0
>
> That's incorrect.
>
> If you have static inline functions, there isn't a problem irrespective
> of optimisation level - they'll become merely static functions which
> won't be inlined, and you'll end up with a copy of the function per
> compilation unit.
>
> If you have extern inline functions, they also won't be inlined, but
> unlike static inline, the compiler won't emit a static function.
> Instead, the compiler expects the function to be provided via another
> compilation unit or library (which won't happen in the Linux kernel.)
> However, Linux kernel coding style does not allow the use of extern
> inline functions.
>
> The problem which the Linux kernel has is that we rely on the compiler
> performing optimisations in multiple places - such as eliminating code
> which can't be reached.  Disabling the optimiser prevents such
> eliminations from happening, and ends up leaving symbols behind which
> are purposely not-defined (which are so in order to detect errors for
> accessors like get_user(), etc. which are only defined to operate on
> 1, 2, 4 and maybe 8 byte values.)
>
> For example:
>
> #define __put_user_check(x, p)                                          \
>         ({                                                              \
>                 unsigned long __limit = current_thread_info()->addr_limit - 1; \                const typeof(*(p)) __user *__tmp_p = (p);               \
>                 register const typeof(*(p)) __r2 asm("r2") = (x);       \
>                 register const typeof(*(p)) __user *__p asm("r0") = __tmp_p; \
>                 register unsigned long __l asm("r1") = __limit;         \
>                 register int __e asm("r0");                             \
>                 switch (sizeof(*(__p))) {                               \
>                 case 1:                                                 \
>                         __put_user_x(__r2, __p, __e, __l, 1);           \
>                         break;                                          \
>                 case 2:                                                 \
>                         __put_user_x(__r2, __p, __e, __l, 2);           \
>                         break;                                          \
>                 case 4:                                                 \
>                         __put_user_x(__r2, __p, __e, __l, 4);           \
>                         break;                                          \
>                 case 8:                                                 \
>                         __put_user_x(__r2, __p, __e, __l, 8);           \
>                         break;                                          \
>                 default: __e = __put_user_bad(); break;                 \
>                 }                                                       \
>                 __e;                                                    \
>         })
>
> which relies on the optimiser removing all the cases which don't apply to
> the access size.  Disabling optimisation prevents that happening, so you
> end up with the entire switch() statement coded in the output assembly
> for every invocation of this macro - which includes a call to
> __put_user_bad() just in case sizeof(*__p) changes unexpectedly.
>
> Building the kernel with optimisation disabled is not supported.

After some analysis found that :

1. with -O0 compiletime assertion's kick off and results in build failures

2. with -O1 or more it's doesn't kick off.

why this is so ?

For example below , the smp_store_release kicks calls
compiletime_assert_atomic_type  and build fails at O0 but passes at O1
.Point is this happens at preprocessing stage and cases for size of *p
afterwards which can be optimized when optimiser is enabled.

Snippet of smp_store_release :

#define smp_store_release(p, v) \
do { \
compiletime_assert_atomic_type(*p); \
switch (sizeof(*p)) { \
case 1: \
asm volatile ("stlrb %w1, %0" \
: "=Q" (*p) : "r" (v) : "memory"); \
break; \
case 2: \
asm volatile ("stlrh %w1, %0" \
: "=Q" (*p) : "r" (v) : "memory"); \
break; \
case 4: \
asm volatile ("stlr %w1, %0" \
: "=Q" (*p) : "r" (v) : "memory"); \
break; \
case 8: \
asm volatile ("stlr %1, %0" \
: "=Q" (*p) : "r" (v) : "memory"); \
break; \
} \
} while (0)

build output :

/projects/pnq/P4sbSW/stripath/open_source_sata/processor/shadowcat/linux/arch/arm64/kvm/../../../virt/kvm/kvm_main.c:
In function \u2018kvm_io_bus_register_dev\u2019:
/projects/pnq/P4sbSW/stripath/open_source_sata/processor/shadowcat/linux/include/linux/compiler.h:429:38:
error: call to \u2018__compiletime_assert_3113\u2019 declared with
attribute error: Need native word sized stores/loads for atomicity.
  _compiletime_assert(condition, msg, __compiletime_assert_, __LINE__)
                                      ^
/projects/pnq/P4sbSW/stripath/open_source_sata/processor/shadowcat/linux/include/linux/compiler.h:412:4:
note: in definition of macro \u2018__compiletime_assert\u2019
    prefix ## suffix();    \
    ^
/projects/pnq/P4sbSW/stripath/open_source_sata/processor/shadowcat/linux/include/linux/compiler.h:429:2:
note: in expansion of macro \u2018_compiletime_assert\u2019
  _compiletime_assert(condition, msg, __compiletime_assert_, __LINE__)
  ^
/projects/pnq/P4sbSW/stripath/open_source_sata/processor/shadowcat/linux/include/linux/compiler.h:432:2:
note: in expansion of macro \u2018compiletime_assert\u2019
  compiletime_assert(__native_word(t),    \
  ^
/projects/pnq/P4sbSW/stripath/open_source_sata/processor/shadowcat/linux/arch/arm64/include/asm/barrier.h:66:2:
note: in expansion of macro \u2018compiletime_assert_atomic_type\u2019
  compiletime_assert_atomic_type(*p);    \
  ^
/projects/pnq/P4sbSW/stripath/open_source_sata/processor/shadowcat/linux/include/linux/rcupdate.h:698:34:
note: in expansion of macro \u2018smp_store_release\u2019
 #define rcu_assign_pointer(p, v) smp_store_release(&p, RCU_INITIALIZER(v))
                                  ^
/projects/pnq/P4sbSW/stripath/open_source_sata/processor/shadowcat/linux/arch/arm64/kvm/../../../virt/kvm/kvm_main.c:3113:2:
note: in expansion of macro \u2018rcu_assign_pointer\u2019
  rcu_assign_pointer(kvm->buses[bus_idx], new_bus);
  ^
/projects/pnq/P4sbSW/stripath/open_source_sata/processor/shadowcat/linux/arch/arm64/kvm/../../../virt/kvm/kvm_main.c:
In function \u2018kvm_io_bus_unregister_dev\u2019:
/projects/pnq/P4sbSW/stripath/open_source_sata/processor/shadowcat/linux/include/linux/compiler.h:429:38:
error: call to \u2018__compiletime_assert_3148\u2019 declared with
attribute error: Need native word sized stores/loads for atomicity.
  _compiletime_assert(condition, msg, __compiletime_assert_, __LINE__)
                                      ^


>
> --
> FTTC broadband for 0.8mile line: currently at 10.5Mbps down 400kbps up
> according to speedtest.net.



-- 
Thanks,
with regards,
Suman Tripathi


From mpa at pengutronix.de  Thu Aug 20 02:12:36 2015
From: mpa at pengutronix.de (Markus Pargmann)
Date: Thu, 20 Aug 2015 11:12:36 +0200
Subject: [PATCH v2 5/5] regmap: No multi_write support if bus->write does not
 exist
In-Reply-To: <1440061956-29064-1-git-send-email-mpa@pengutronix.de>
References: <1440061956-29064-1-git-send-email-mpa@pengutronix.de>
Message-ID: <1440061956-29064-6-git-send-email-mpa@pengutronix.de>

There is no multi_write support available if we cannot use raw_write.
This is the case if bus->write is not implemented.

This patch adds a condition that we need bus and bus->write so that
can_multi_write is true.

Signed-off-by: Markus Pargmann <mpa at pengutronix.de>
---
 drivers/base/regmap/regmap.c | 2 +-
 1 file changed, 1 insertion(+), 1 deletion(-)

diff --git a/drivers/base/regmap/regmap.c b/drivers/base/regmap/regmap.c
index 66efe25d64c9..d43723bb3257 100644
--- a/drivers/base/regmap/regmap.c
+++ b/drivers/base/regmap/regmap.c
@@ -575,7 +575,7 @@ struct regmap *regmap_init(struct device *dev,
 		map->reg_stride = 1;
 	map->use_single_read = config->use_single_rw || !bus || !bus->read;
 	map->use_single_write = config->use_single_rw || !bus || !bus->write;
-	map->can_multi_write = config->can_multi_write;
+	map->can_multi_write = config->can_multi_write && bus && bus->write;
 	map->dev = dev;
 	map->bus = bus;
 	map->bus_context = bus_context;
-- 
2.4.6



From mpa at pengutronix.de  Thu Aug 20 02:12:33 2015
From: mpa at pengutronix.de (Markus Pargmann)
Date: Thu, 20 Aug 2015 11:12:33 +0200
Subject: [PATCH v2 2/5] regmap: Fix regmap_bulk_write for bus writes
In-Reply-To: <1440061956-29064-1-git-send-email-mpa@pengutronix.de>
References: <1440061956-29064-1-git-send-email-mpa@pengutronix.de>
Message-ID: <1440061956-29064-3-git-send-email-mpa@pengutronix.de>

The regmap config does not prohibit val_bytes that are not powers of
two. But the current code of regmap_bulk_write for use_single_rw does
limit the possible val_bytes to 1, 2 and 4.

This patch fixes the behaviour to allow bus writes with non-standard
val_bytes sizes.

Cc: Stephen Boyd <sboyd at codeaurora.org>
Signed-off-by: Markus Pargmann <mpa at pengutronix.de>
---
 drivers/base/regmap/regmap.c | 17 ++++++++++++++++-
 1 file changed, 16 insertions(+), 1 deletion(-)

diff --git a/drivers/base/regmap/regmap.c b/drivers/base/regmap/regmap.c
index a778cf943628..66a2fd42d77f 100644
--- a/drivers/base/regmap/regmap.c
+++ b/drivers/base/regmap/regmap.c
@@ -1680,7 +1680,7 @@ int regmap_bulk_write(struct regmap *map, unsigned int reg, const void *val,
 	 * Some devices don't support bulk write, for
 	 * them we have a series of single write operations.
 	 */
-	if (!map->bus || map->use_single_rw) {
+	if (!map->bus) {
 		map->lock(map->lock_arg);
 		for (i = 0; i < val_count; i++) {
 			unsigned int ival;
@@ -1712,6 +1712,21 @@ int regmap_bulk_write(struct regmap *map, unsigned int reg, const void *val,
 		}
 out:
 		map->unlock(map->lock_arg);
+	} else if (map->use_single_rw) {
+		/*
+		 * We need to handle bus writes separate to support val_bytes
+		 * that are not powers of 2.
+		 */
+		map->lock(map->lock_arg);
+		for (i = 0; i < val_count; i++) {
+			ret = _regmap_raw_write(map,
+						reg + (i * map->reg_stride),
+						val + (i * val_bytes),
+						val_bytes);
+			if (ret)
+				break;
+		}
+		map->unlock(map->lock_arg);
 	} else {
 		void *wval;
 
-- 
2.4.6



From mpa at pengutronix.de  Thu Aug 20 02:12:34 2015
From: mpa at pengutronix.de (Markus Pargmann)
Date: Thu, 20 Aug 2015 11:12:34 +0200
Subject: [PATCH v2 3/5] regmap: Split use_single_rw internally into
 use_single_read/write
In-Reply-To: <1440061956-29064-1-git-send-email-mpa@pengutronix.de>
References: <1440061956-29064-1-git-send-email-mpa@pengutronix.de>
Message-ID: <1440061956-29064-4-git-send-email-mpa@pengutronix.de>

use_single_rw currently reflects the capabilities of the connected
device. The capabilities of the bus are currently missing for this
variable.

As there are read only and write only buses we need seperate values for
use_single_rw to also reflect tha capabilities of the bus.

This patch splits use_single_rw into use_single_read and
use_single_write. The initialization is changed to check the
configuration for use_single_rw and to check the capabilities of the
used bus.

Signed-off-by: Markus Pargmann <mpa at pengutronix.de>
---
 drivers/base/regmap/internal.h   | 6 ++++--
 drivers/base/regmap/regcache.c   | 2 +-
 drivers/base/regmap/regmap-irq.c | 4 ++--
 drivers/base/regmap/regmap.c     | 9 +++++----
 4 files changed, 12 insertions(+), 9 deletions(-)

diff --git a/drivers/base/regmap/internal.h b/drivers/base/regmap/internal.h
index b2b2849fc6d3..d744ae3926dd 100644
--- a/drivers/base/regmap/internal.h
+++ b/drivers/base/regmap/internal.h
@@ -139,8 +139,10 @@ struct regmap {
 	struct reg_default *patch;
 	int patch_regs;
 
-	/* if set, converts bulk rw to single rw */
-	bool use_single_rw;
+	/* if set, converts bulk read to single read */
+	bool use_single_read;
+	/* if set, converts bulk read to single read */
+	bool use_single_write;
 	/* if set, the device supports multi write mode */
 	bool can_multi_write;
 
diff --git a/drivers/base/regmap/regcache.c b/drivers/base/regmap/regcache.c
index b9862d741a56..6f8a13ec32a4 100644
--- a/drivers/base/regmap/regcache.c
+++ b/drivers/base/regmap/regcache.c
@@ -729,7 +729,7 @@ int regcache_sync_block(struct regmap *map, void *block,
 			unsigned int block_base, unsigned int start,
 			unsigned int end)
 {
-	if (regmap_can_raw_write(map) && !map->use_single_rw)
+	if (regmap_can_raw_write(map) && !map->use_single_write)
 		return regcache_sync_block_raw(map, block, cache_present,
 					       block_base, start, end);
 	else
diff --git a/drivers/base/regmap/regmap-irq.c b/drivers/base/regmap/regmap-irq.c
index 2597600a5d26..38d1f72d869c 100644
--- a/drivers/base/regmap/regmap-irq.c
+++ b/drivers/base/regmap/regmap-irq.c
@@ -209,7 +209,7 @@ static irqreturn_t regmap_irq_thread(int irq, void *d)
 	 * Read in the statuses, using a single bulk read if possible
 	 * in order to reduce the I/O overheads.
 	 */
-	if (!map->use_single_rw && map->reg_stride == 1 &&
+	if (!map->use_single_read && map->reg_stride == 1 &&
 	    data->irq_reg_stride == 1) {
 		u8 *buf8 = data->status_reg_buf;
 		u16 *buf16 = data->status_reg_buf;
@@ -398,7 +398,7 @@ int regmap_add_irq_chip(struct regmap *map, int irq, int irq_flags,
 	else
 		d->irq_reg_stride = 1;
 
-	if (!map->use_single_rw && map->reg_stride == 1 &&
+	if (!map->use_single_read && map->reg_stride == 1 &&
 	    d->irq_reg_stride == 1) {
 		d->status_reg_buf = kmalloc(map->format.val_bytes *
 					    chip->num_regs, GFP_KERNEL);
diff --git a/drivers/base/regmap/regmap.c b/drivers/base/regmap/regmap.c
index 66a2fd42d77f..bb4e65e7a950 100644
--- a/drivers/base/regmap/regmap.c
+++ b/drivers/base/regmap/regmap.c
@@ -573,7 +573,8 @@ struct regmap *regmap_init(struct device *dev,
 		map->reg_stride = config->reg_stride;
 	else
 		map->reg_stride = 1;
-	map->use_single_rw = config->use_single_rw;
+	map->use_single_read = config->use_single_rw || !bus || !bus->read;
+	map->use_single_write = config->use_single_rw || !bus || !bus->write;
 	map->can_multi_write = config->can_multi_write;
 	map->dev = dev;
 	map->bus = bus;
@@ -763,7 +764,7 @@ struct regmap *regmap_init(struct device *dev,
 		if ((reg_endian != REGMAP_ENDIAN_BIG) ||
 		    (val_endian != REGMAP_ENDIAN_BIG))
 			goto err_map;
-		map->use_single_rw = true;
+		map->use_single_write = true;
 	}
 
 	if (!map->format.format_write &&
@@ -1712,7 +1713,7 @@ int regmap_bulk_write(struct regmap *map, unsigned int reg, const void *val,
 		}
 out:
 		map->unlock(map->lock_arg);
-	} else if (map->use_single_rw) {
+	} else if (map->use_single_write) {
 		/*
 		 * We need to handle bus writes separate to support val_bytes
 		 * that are not powers of 2.
@@ -2308,7 +2309,7 @@ int regmap_bulk_read(struct regmap *map, unsigned int reg, void *val,
 		 * Some devices does not support bulk read, for
 		 * them we have a series of single read operations.
 		 */
-		if (map->use_single_rw) {
+		if (map->use_single_read) {
 			for (i = 0; i < val_count; i++) {
 				ret = regmap_raw_read(map,
 						reg + (i * map->reg_stride),
-- 
2.4.6



From mpa at pengutronix.de  Thu Aug 20 02:12:35 2015
From: mpa at pengutronix.de (Markus Pargmann)
Date: Thu, 20 Aug 2015 11:12:35 +0200
Subject: [PATCH v2 4/5] regmap: regmap_raw_read return error on !bus->read
In-Reply-To: <1440061956-29064-1-git-send-email-mpa@pengutronix.de>
References: <1440061956-29064-1-git-send-email-mpa@pengutronix.de>
Message-ID: <1440061956-29064-5-git-send-email-mpa@pengutronix.de>

Return -ENOTSUPP if map->bus->read is not implemented and we do not use
the cache. This code path would directly use bus->read would run into an
NULL pointer for the read function.

Signed-off-by: Markus Pargmann <mpa at pengutronix.de>
---
 drivers/base/regmap/regmap.c | 5 +++++
 1 file changed, 5 insertions(+)

diff --git a/drivers/base/regmap/regmap.c b/drivers/base/regmap/regmap.c
index bb4e65e7a950..66efe25d64c9 100644
--- a/drivers/base/regmap/regmap.c
+++ b/drivers/base/regmap/regmap.c
@@ -2201,6 +2201,11 @@ int regmap_raw_read(struct regmap *map, unsigned int reg, void *val,
 
 	if (regmap_volatile_range(map, reg, val_count) || map->cache_bypass ||
 	    map->cache_type == REGCACHE_NONE) {
+		if (!map->bus->read) {
+			ret = -ENOTSUPP;
+			goto out;
+		}
+
 		/* Physical block read if there's no cache involved */
 		ret = _regmap_raw_read(map, reg, val, val_len);
 
-- 
2.4.6



From mpa at pengutronix.de  Thu Aug 20 02:12:31 2015
From: mpa at pengutronix.de (Markus Pargmann)
Date: Thu, 20 Aug 2015 11:12:31 +0200
Subject: [PATCH v2 0/5] regmap: fixes
Message-ID: <1440061956-29064-1-git-send-email-mpa@pengutronix.de>

Hi,

These are some regmap fixes from the previous series
"Regmap max_raw_io and bmc150 SPI support". They are now splitted from the
other patches.

Changes in v2:
- Fixed free_context typo
- use_single_rw is now internally split into use_single_read/write
- Removed patches that wrongly tried to fix things
- Added simpler patches which check for the existence of bus->read/write to
  avoid null dereferences

Best Regards,

Markus


Markus Pargmann (5):
  regmap: Add missing comments about struct regmap_bus
  regmap: Fix regmap_bulk_write for bus writes
  regmap: Split use_single_rw internally into use_single_read/write
  regmap: regmap_raw_read return error on !bus->read
  regmap: No multi_write support if bus->write does not exist

 drivers/base/regmap/internal.h   |  6 ++++--
 drivers/base/regmap/regcache.c   |  2 +-
 drivers/base/regmap/regmap-irq.c |  4 ++--
 drivers/base/regmap/regmap.c     | 31 ++++++++++++++++++++++++++-----
 include/linux/regmap.h           |  4 +++-
 5 files changed, 36 insertions(+), 11 deletions(-)

-- 
2.4.6



From mpa at pengutronix.de  Thu Aug 20 02:12:32 2015
From: mpa at pengutronix.de (Markus Pargmann)
Date: Thu, 20 Aug 2015 11:12:32 +0200
Subject: [PATCH v2 1/5] regmap: Add missing comments about struct regmap_bus
In-Reply-To: <1440061956-29064-1-git-send-email-mpa@pengutronix.de>
References: <1440061956-29064-1-git-send-email-mpa@pengutronix.de>
Message-ID: <1440061956-29064-2-git-send-email-mpa@pengutronix.de>

There are some fields of this struct undocumented or old. This patch
updates the missing comments.

Signed-off-by: Markus Pargmann <mpa at pengutronix.de>
---
 include/linux/regmap.h | 4 +++-
 1 file changed, 3 insertions(+), 1 deletion(-)

diff --git a/include/linux/regmap.h b/include/linux/regmap.h
index 59c55ea0f0b5..915454a1b54e 100644
--- a/include/linux/regmap.h
+++ b/include/linux/regmap.h
@@ -296,8 +296,11 @@ typedef void (*regmap_hw_free_context)(void *context);
  *                if not implemented  on a given device.
  * @async_write: Write operation which completes asynchronously, optional and
  *               must serialise with respect to non-async I/O.
+ * @reg_write: Write operation for a register. Writes value to register.
  * @read: Read operation.  Data is returned in the buffer used to transmit
  *         data.
+ * @reg_read: Read operation for a register. Reads a value from a register.
+ * @free_context: Free context.
  * @async_alloc: Allocate a regmap_async() structure.
  * @read_flag_mask: Mask to be set in the top byte of the register when doing
  *                  a read.
@@ -307,7 +310,6 @@ typedef void (*regmap_hw_free_context)(void *context);
  * @val_format_endian_default: Default endianness for formatted register
  *     values. Used when the regmap_config specifies DEFAULT. If this is
  *     DEFAULT, BIG is assumed.
- * @async_size: Size of struct used for async work.
  */
 struct regmap_bus {
 	bool fast_io;
-- 
2.4.6



From catalin.marinas at arm.com  Thu Aug 20 02:17:45 2015
From: catalin.marinas at arm.com (Catalin Marinas)
Date: Thu, 20 Aug 2015 10:17:45 +0100
Subject: [PATCH 2/2] arm64: set MAX_MEMBLOCK_ADDR according to linear
 region size
In-Reply-To: <CAKv+Gu8BVJF9MEsRRonprEkyhvrbTsWdUnz0wQyi2zUNAd_bpg@mail.gmail.com>
References: <1439890482-20798-1-git-send-email-ard.biesheuvel@linaro.org>
 <1439890482-20798-3-git-send-email-ard.biesheuvel@linaro.org>
 <20150818100018.GA11021@arm.com>
 <CAKv+Gu-YDEKSrkSG2fywgrHBB3Hao+jodknmCAkFCWqG4OpXCA@mail.gmail.com>
 <20150818173938.GH11571@e104818-lin.cambridge.arm.com>
 <CAKv+Gu8BVJF9MEsRRonprEkyhvrbTsWdUnz0wQyi2zUNAd_bpg@mail.gmail.com>
Message-ID: <20150820091745.GA2972@e104818-lin.cambridge.arm.com>

On Thu, Aug 20, 2015 at 07:09:25AM +0200, Ard Biesheuvel wrote:
> On 18 August 2015 at 19:39, Catalin Marinas <catalin.marinas at arm.com> wrote:
> > On Tue, Aug 18, 2015 at 12:04:27PM +0200, Ard Biesheuvel wrote:
> >> On 18 August 2015 at 12:00, Will Deacon <will.deacon at arm.com> wrote:
> >> > On Tue, Aug 18, 2015 at 10:34:42AM +0100, Ard Biesheuvel wrote:
> >> >> The linear region size of a 39-bit VA kernel is only 256 GB, which
> >> >> may be insufficient to cover all of system RAM, even on platforms
> >> >> that have much less than 256 GB of memory but which is laid out
> >> >> very sparsely.
> >> >>
> >> >> So make sure we clip the memory we will not be able to map before
> >> >> installing it into the memblock memory table, by setting
> >> >> MAX_MEMBLOCK_ADDR accordingly.
> >> >>
> >> >> Signed-off-by: Ard Biesheuvel <ard.biesheuvel at linaro.org>
> >> >> ---
> >> >>  arch/arm64/include/asm/memory.h | 8 ++++++++
> >> >>  1 file changed, 8 insertions(+)
> >> >>
> >> >> diff --git a/arch/arm64/include/asm/memory.h b/arch/arm64/include/asm/memory.h
> >> >> index f800d45ea226..44a59c20e773 100644
> >> >> --- a/arch/arm64/include/asm/memory.h
> >> >> +++ b/arch/arm64/include/asm/memory.h
> >> >> @@ -114,6 +114,14 @@ extern phys_addr_t               memstart_addr;
> >> >>  #define PHYS_OFFSET          ({ memstart_addr; })
> >> >>
> >> >>  /*
> >> >> + * The maximum physical address that the linear direct mapping
> >> >> + * of system RAM can cover. (PAGE_OFFSET can be interpreted as
> >> >> + * a 2's complement signed quantity and negated to derive the
> >> >> + * maximum size of the linear mapping.)
> >> >> + */
> >> >> +#define MAX_MEMBLOCK_ADDR    ({ memstart_addr - PAGE_OFFSET - 1; })
> >> >
> >> > If we initialised memory_limit to this value and changed early_mem to
> >> > use min (i.e. only restrict the limit further), would that avoid the
> >> > need to change the of code? It looks like PPC uses
> >> > memblock_enforce_memory_limit for similar reasons.
> >>
> >> Yes, that would be yet another way of doing things. But since Catalin
> >> explicitly requested that both checks (i.e., bottom end and top end)
> >> occur in the same place, and indicated his preference not to override
> >> early_init_dt_add_memory_arch() if we can avoid it, the only way is to
> >> hack it in there.
> >
> > Talking to Will, we decided to go for a quick fix with cc stable that
> > does something like:
> >
> >         memblock_enforce_memory_limit(min(memory_limit, ~PAGE_OFFSET));
> 
> Actually, this won't work. The function limits the /amount/ of memory,
> and disregards holes when doing so.

Ah, we missed this (but its behaviour makes sense, it's meant for mem=
arguments).

-- 
Catalin


From catalin.marinas at arm.com  Thu Aug 20 02:18:05 2015
From: catalin.marinas at arm.com (Catalin Marinas)
Date: Thu, 20 Aug 2015 10:18:05 +0100
Subject: [PATCH 1/2] of/fdt: make memblock maximum physical address arch
 configurable
In-Reply-To: <1439890482-20798-2-git-send-email-ard.biesheuvel@linaro.org>
References: <1439890482-20798-1-git-send-email-ard.biesheuvel@linaro.org>
 <1439890482-20798-2-git-send-email-ard.biesheuvel@linaro.org>
Message-ID: <20150820091805.GB2972@e104818-lin.cambridge.arm.com>

On Tue, Aug 18, 2015 at 11:34:41AM +0200, Ard Biesheuvel wrote:
> When parsing the memory nodes to populate the memblock memory
> table, we check against high and low limits and clip any memory
> that exceeds either one of them.
> 
> However, for arm64, the high limit of (phys_addr_t)~0 is not very
> meaningful, since phys_addr_t is 64 bits (i.e., no limit) but there
> may be other constraints that limit the memory ranges that we can
> support.
> 
> So rename MAX_PHYS_ADDR to MAX_MEMBLOCK_ADDR (for clarity) and only
> define it if the arch does not supply a definition of its own.
> 
> Signed-off-by: Ard Biesheuvel <ard.biesheuvel at linaro.org>

Reviewed-by: Catalin Marinas <catalin.marinas at arm.com>


From catalin.marinas at arm.com  Thu Aug 20 02:19:15 2015
From: catalin.marinas at arm.com (Catalin Marinas)
Date: Thu, 20 Aug 2015 10:19:15 +0100
Subject: [PATCH 2/2] arm64: set MAX_MEMBLOCK_ADDR according to linear
 region size
In-Reply-To: <1439890482-20798-3-git-send-email-ard.biesheuvel@linaro.org>
References: <1439890482-20798-1-git-send-email-ard.biesheuvel@linaro.org>
 <1439890482-20798-3-git-send-email-ard.biesheuvel@linaro.org>
Message-ID: <20150820091915.GC2972@e104818-lin.cambridge.arm.com>

On Tue, Aug 18, 2015 at 11:34:42AM +0200, Ard Biesheuvel wrote:
> The linear region size of a 39-bit VA kernel is only 256 GB, which
> may be insufficient to cover all of system RAM, even on platforms
> that have much less than 256 GB of memory but which is laid out
> very sparsely.
> 
> So make sure we clip the memory we will not be able to map before
> installing it into the memblock memory table, by setting
> MAX_MEMBLOCK_ADDR accordingly.
> 
> Signed-off-by: Ard Biesheuvel <ard.biesheuvel at linaro.org>
> ---
>  arch/arm64/include/asm/memory.h | 8 ++++++++
>  1 file changed, 8 insertions(+)
> 
> diff --git a/arch/arm64/include/asm/memory.h b/arch/arm64/include/asm/memory.h
> index f800d45ea226..44a59c20e773 100644
> --- a/arch/arm64/include/asm/memory.h
> +++ b/arch/arm64/include/asm/memory.h
> @@ -114,6 +114,14 @@ extern phys_addr_t		memstart_addr;
>  #define PHYS_OFFSET		({ memstart_addr; })
>  
>  /*
> + * The maximum physical address that the linear direct mapping
> + * of system RAM can cover. (PAGE_OFFSET can be interpreted as
> + * a 2's complement signed quantity and negated to derive the
> + * maximum size of the linear mapping.)
> + */
> +#define MAX_MEMBLOCK_ADDR	({ memstart_addr - PAGE_OFFSET - 1; })

Would it be easier to understand as just memstart_addr + ~PAGE_OFFSET?

Otherwise:

Reviewed-by: Catalin Marinas <catalin.marinas at arm.com>


From leilk.liu at mediatek.com  Thu Aug 20 02:19:05 2015
From: leilk.liu at mediatek.com (Leilk Liu)
Date: Thu, 20 Aug 2015 17:19:05 +0800
Subject: [PATCH v2 0/4] Fixup mediatek spi driver 
Message-ID: <1440062349-25513-1-git-send-email-leilk.liu@mediatek.com>

This series are based on 4.2-rc1 and provide four patches to fix mediatek spi driver.

Change in v2:
1. The patch "spi: mediatek: remove redundant clock in prepare_hardware/unprepare_hardware" 
   is applied, so remove it from series.
2. fix incorrect endian usage to support little-endian and big-endian system.
3. revise quirks style to bool.
4. use BIT() to instead of SPI_CMD_*_OFFSET.
5. revise coding style, such as time name, and variable type. 



From leilk.liu at mediatek.com  Thu Aug 20 02:19:06 2015
From: leilk.liu at mediatek.com (Leilk Liu)
Date: Thu, 20 Aug 2015 17:19:06 +0800
Subject: [PATCH v2 1/4] spi: mediatek: fix spi incorrect endian usage
In-Reply-To: <1440062349-25513-1-git-send-email-leilk.liu@mediatek.com>
References: <1440062349-25513-1-git-send-email-leilk.liu@mediatek.com>
Message-ID: <1440062349-25513-2-git-send-email-leilk.liu@mediatek.com>

TX_ENDIAN/RX_ENDIAN bits define whether to reverse the endian
order of the data DMA from/to memory. The endian order should
keep the same with cpu endian.

Signed-off-by: Leilk Liu <leilk.liu at mediatek.com>
---
 drivers/spi/spi-mt65xx.c                 | 38 ++++++++++++++------------------
 include/linux/platform_data/spi-mt65xx.h |  2 --
 2 files changed, 16 insertions(+), 24 deletions(-)

diff --git a/drivers/spi/spi-mt65xx.c b/drivers/spi/spi-mt65xx.c
index 321b820..79286c8 100644
--- a/drivers/spi/spi-mt65xx.c
+++ b/drivers/spi/spi-mt65xx.c
@@ -122,8 +122,6 @@ static const struct mtk_spi_compatible mt8173_compat = {
 static const struct mtk_chip_config mtk_default_chip_info = {
 	.rx_mlsb = 1,
 	.tx_mlsb = 1,
-	.tx_endian = 0,
-	.rx_endian = 0,
 };
 
 static const struct of_device_id mtk_spi_of_match[] = {
@@ -161,9 +159,13 @@ static void mtk_spi_config(struct mtk_spi *mdata,
 	reg_val |= (chip_config->rx_mlsb << SPI_CMD_RXMSBF_OFFSET);
 
 	/* set the tx/rx endian */
-	reg_val &= ~(SPI_CMD_TX_ENDIAN | SPI_CMD_RX_ENDIAN);
-	reg_val |= (chip_config->tx_endian << SPI_CMD_TX_ENDIAN_OFFSET);
-	reg_val |= (chip_config->rx_endian << SPI_CMD_RX_ENDIAN_OFFSET);
+#ifdef __LITTLE_ENDIAN
+	reg_val &= ~SPI_CMD_TX_ENDIAN;
+	reg_val &= ~SPI_CMD_RX_ENDIAN;
+#else
+	reg_val |= SPI_CMD_TX_ENDIAN;
+	reg_val |= SPI_CMD_RX_ENDIAN;
+#endif
 
 	/* set finish and pause interrupt always enable */
 	reg_val |= SPI_CMD_FINISH_IE | SPI_CMD_PAUSE_EN;
@@ -352,7 +354,7 @@ static int mtk_spi_fifo_transfer(struct spi_master *master,
 				 struct spi_device *spi,
 				 struct spi_transfer *xfer)
 {
-	int cnt, i;
+	int cnt;
 	struct mtk_spi *mdata = spi_master_get_devdata(master);
 
 	mdata->cur_transfer = xfer;
@@ -364,10 +366,7 @@ static int mtk_spi_fifo_transfer(struct spi_master *master,
 		cnt = xfer->len / 4 + 1;
 	else
 		cnt = xfer->len / 4;
-
-	for (i = 0; i < cnt; i++)
-		writel(*((u32 *)xfer->tx_buf + i),
-		       mdata->base + SPI_TX_DATA_REG);
+	iowrite32_rep(mdata->base + SPI_TX_DATA_REG, xfer->tx_buf, cnt);
 
 	mtk_spi_enable_transfer(master);
 
@@ -437,7 +436,7 @@ static bool mtk_spi_can_dma(struct spi_master *master,
 
 static irqreturn_t mtk_spi_interrupt(int irq, void *dev_id)
 {
-	u32 cmd, reg_val, i;
+	u32 cmd, reg_val, cnt;
 	struct spi_master *master = dev_id;
 	struct mtk_spi *mdata = spi_master_get_devdata(master);
 	struct spi_transfer *trans = mdata->cur_transfer;
@@ -449,18 +448,13 @@ static irqreturn_t mtk_spi_interrupt(int irq, void *dev_id)
 		mdata->state = MTK_SPI_IDLE;
 
 	if (!master->can_dma(master, master->cur_msg->spi, trans)) {
-		/* xfer len is not N*4 bytes every time in a transfer,
-		 * but SPI_RX_DATA_REG must reads 4 bytes once,
-		 * so rx buffer byte by byte.
-		 */
 		if (trans->rx_buf) {
-			for (i = 0; i < mdata->xfer_len; i++) {
-				if (i % 4 == 0)
-					reg_val =
-					readl(mdata->base + SPI_RX_DATA_REG);
-				*((u8 *)(trans->rx_buf + i)) =
-					(reg_val >> ((i % 4) * 8)) & 0xff;
-			}
+			if (mdata->xfer_len % 4)
+				cnt = mdata->xfer_len / 4 + 1;
+			else
+				cnt = mdata->xfer_len / 4;
+			ioread32_rep(mdata->base + SPI_RX_DATA_REG,
+				     trans->rx_buf, cnt);
 		}
 		spi_finalize_current_transfer(master);
 		return IRQ_HANDLED;
diff --git a/include/linux/platform_data/spi-mt65xx.h b/include/linux/platform_data/spi-mt65xx.h
index 7512255..54b0448 100644
--- a/include/linux/platform_data/spi-mt65xx.h
+++ b/include/linux/platform_data/spi-mt65xx.h
@@ -16,7 +16,5 @@
 struct mtk_chip_config {
 	u32 tx_mlsb;
 	u32 rx_mlsb;
-	u32 tx_endian;
-	u32 rx_endian;
 };
 #endif
-- 
1.8.1.1.dirty



From leilk.liu at mediatek.com  Thu Aug 20 02:19:07 2015
From: leilk.liu at mediatek.com (Leilk Liu)
Date: Thu, 20 Aug 2015 17:19:07 +0800
Subject: [PATCH v2 2/4] spi: medaitek: revise quirks compatibility style
In-Reply-To: <1440062349-25513-1-git-send-email-leilk.liu@mediatek.com>
References: <1440062349-25513-1-git-send-email-leilk.liu@mediatek.com>
Message-ID: <1440062349-25513-3-git-send-email-leilk.liu@mediatek.com>

The quirks are true/false, so define these as bool.

Signed-off-by: Leilk Liu <leilk.liu at mediatek.com>
---
 drivers/spi/spi-mt65xx.c | 25 +++++++------------------
 1 file changed, 7 insertions(+), 18 deletions(-)

diff --git a/drivers/spi/spi-mt65xx.c b/drivers/spi/spi-mt65xx.c
index 79286c8..4fa4332 100644
--- a/drivers/spi/spi-mt65xx.c
+++ b/drivers/spi/spi-mt65xx.c
@@ -71,10 +71,6 @@
 #define SPI_CMD_FINISH_IE            BIT(16)
 #define SPI_CMD_PAUSE_IE             BIT(17)
 
-#define MTK_SPI_QUIRK_PAD_SELECT 1
-/* Must explicitly send dummy Tx bytes to do Rx only transfer */
-#define MTK_SPI_QUIRK_MUST_TX 1
-
 #define MT8173_SPI_MAX_PAD_SEL 3
 
 #define MTK_SPI_IDLE 0
@@ -84,8 +80,9 @@
 #define MTK_SPI_PACKET_SIZE 1024
 
 struct mtk_spi_compatible {
-	u32 need_pad_sel;
-	u32 must_tx;
+	bool need_pad_sel;
+	/* Must explicitly send dummy Tx bytes to do Rx only transfer */
+	bool must_tx;
 };
 
 struct mtk_spi {
@@ -100,19 +97,11 @@ struct mtk_spi {
 	const struct mtk_spi_compatible *dev_comp;
 };
 
-static const struct mtk_spi_compatible mt6589_compat = {
-	.need_pad_sel = 0,
-	.must_tx = 0,
-};
-
-static const struct mtk_spi_compatible mt8135_compat = {
-	.need_pad_sel = 0,
-	.must_tx = 0,
-};
-
+static const struct mtk_spi_compatible mt6589_compat;
+static const struct mtk_spi_compatible mt8135_compat;
 static const struct mtk_spi_compatible mt8173_compat = {
-	.need_pad_sel = MTK_SPI_QUIRK_PAD_SELECT,
-	.must_tx = MTK_SPI_QUIRK_MUST_TX,
+	.need_pad_sel = true,
+	.must_tx = true,
 };
 
 /*
-- 
1.8.1.1.dirty



From leilk.liu at mediatek.com  Thu Aug 20 02:19:08 2015
From: leilk.liu at mediatek.com (Leilk Liu)
Date: Thu, 20 Aug 2015 17:19:08 +0800
Subject: [PATCH v2 3/4] spi: mediatek: use BIT() to instead of SPI_CMD_*_OFFSET
In-Reply-To: <1440062349-25513-1-git-send-email-leilk.liu@mediatek.com>
References: <1440062349-25513-1-git-send-email-leilk.liu@mediatek.com>
Message-ID: <1440062349-25513-4-git-send-email-leilk.liu@mediatek.com>

This patch removes SPI_CMD_*_OFFSET defines, and uses the BIT(x)
defines instead.

Signed-off-by: Leilk Liu <leilk.liu at mediatek.com>
---
 drivers/spi/spi-mt65xx.c | 37 ++++++++++++++++++++-----------------
 1 file changed, 20 insertions(+), 17 deletions(-)

diff --git a/drivers/spi/spi-mt65xx.c b/drivers/spi/spi-mt65xx.c
index 4fa4332..43c1dd5 100644
--- a/drivers/spi/spi-mt65xx.c
+++ b/drivers/spi/spi-mt65xx.c
@@ -48,15 +48,8 @@
 #define SPI_CFG1_PACKET_LOOP_MASK         0xff00
 #define SPI_CFG1_PACKET_LENGTH_MASK       0x3ff0000
 
-#define SPI_CMD_ACT_OFFSET                0
-#define SPI_CMD_RESUME_OFFSET             1
-#define SPI_CMD_CPHA_OFFSET               8
-#define SPI_CMD_CPOL_OFFSET               9
-#define SPI_CMD_TXMSBF_OFFSET             12
-#define SPI_CMD_RXMSBF_OFFSET             13
-#define SPI_CMD_RX_ENDIAN_OFFSET          14
-#define SPI_CMD_TX_ENDIAN_OFFSET          15
-
+#define SPI_CMD_ACT                  BIT(0)
+#define SPI_CMD_RESUME               BIT(1)
 #define SPI_CMD_RST                  BIT(2)
 #define SPI_CMD_PAUSE_EN             BIT(4)
 #define SPI_CMD_DEASSERT             BIT(5)
@@ -143,9 +136,14 @@ static void mtk_spi_config(struct mtk_spi *mdata,
 	reg_val = readl(mdata->base + SPI_CMD_REG);
 
 	/* set the mlsbx and mlsbtx */
-	reg_val &= ~(SPI_CMD_TXMSBF | SPI_CMD_RXMSBF);
-	reg_val |= (chip_config->tx_mlsb << SPI_CMD_TXMSBF_OFFSET);
-	reg_val |= (chip_config->rx_mlsb << SPI_CMD_RXMSBF_OFFSET);
+	if (chip_config->tx_mlsb)
+		reg_val |= SPI_CMD_TXMSBF;
+	else
+		reg_val &= ~SPI_CMD_TXMSBF;
+	if (chip_config->rx_mlsb)
+		reg_val |= SPI_CMD_RXMSBF;
+	else
+		reg_val &= ~SPI_CMD_RXMSBF;
 
 	/* set the tx/rx endian */
 #ifdef __LITTLE_ENDIAN
@@ -201,9 +199,14 @@ static int mtk_spi_prepare_message(struct spi_master *master,
 	cpol = spi->mode & SPI_CPOL ? 1 : 0;
 
 	reg_val = readl(mdata->base + SPI_CMD_REG);
-	reg_val &= ~(SPI_CMD_CPHA | SPI_CMD_CPOL);
-	reg_val |= (cpha << SPI_CMD_CPHA_OFFSET);
-	reg_val |= (cpol << SPI_CMD_CPOL_OFFSET);
+	if (cpha)
+		reg_val |= SPI_CMD_CPHA;
+	else
+		reg_val &= ~SPI_CMD_CPHA;
+	if (cpol)
+		reg_val |= SPI_CMD_CPOL;
+	else
+		reg_val &= ~SPI_CMD_CPOL;
 	writel(reg_val, mdata->base + SPI_CMD_REG);
 
 	chip_config = spi->controller_data;
@@ -282,9 +285,9 @@ static void mtk_spi_enable_transfer(struct spi_master *master)
 
 	cmd = readl(mdata->base + SPI_CMD_REG);
 	if (mdata->state == MTK_SPI_IDLE)
-		cmd |= 1 << SPI_CMD_ACT_OFFSET;
+		cmd |= SPI_CMD_ACT;
 	else
-		cmd |= 1 << SPI_CMD_RESUME_OFFSET;
+		cmd |= SPI_CMD_RESUME;
 	writel(cmd, mdata->base + SPI_CMD_REG);
 }
 
-- 
1.8.1.1.dirty



From leilk.liu at mediatek.com  Thu Aug 20 02:19:09 2015
From: leilk.liu at mediatek.com (Leilk Liu)
Date: Thu, 20 Aug 2015 17:19:09 +0800
Subject: [PATCH v2 4/4] spi: mediatek: revise coding style
In-Reply-To: <1440062349-25513-1-git-send-email-leilk.liu@mediatek.com>
References: <1440062349-25513-1-git-send-email-leilk.liu@mediatek.com>
Message-ID: <1440062349-25513-5-git-send-email-leilk.liu@mediatek.com>

This patch revises littery coding style according to comments.

Signed-off-by: Leilk Liu <leilk.liu at mediatek.com>
---
 drivers/spi/spi-mt65xx.c | 52 ++++++++++++++++++++++++++++--------------------
 1 file changed, 30 insertions(+), 22 deletions(-)

diff --git a/drivers/spi/spi-mt65xx.c b/drivers/spi/spi-mt65xx.c
index 43c1dd5..eaadc7e 100644
--- a/drivers/spi/spi-mt65xx.c
+++ b/drivers/spi/spi-mt65xx.c
@@ -16,6 +16,7 @@
 #include <linux/device.h>
 #include <linux/err.h>
 #include <linux/interrupt.h>
+#include <linux/io.h>
 #include <linux/ioport.h>
 #include <linux/module.h>
 #include <linux/of.h>
@@ -66,6 +67,8 @@
 
 #define MT8173_SPI_MAX_PAD_SEL 3
 
+#define MTK_SPI_PAUSE_INT_STATUS 0x2
+
 #define MTK_SPI_IDLE 0
 #define MTK_SPI_PAUSED 1
 
@@ -178,7 +181,7 @@ static int mtk_spi_prepare_hardware(struct spi_master *master)
 
 	trans = list_first_entry(&msg->transfers, struct spi_transfer,
 				 transfer_list);
-	if (trans->cs_change == 0) {
+	if (!trans->cs_change) {
 		mdata->state = MTK_SPI_IDLE;
 		mtk_spi_reset(mdata);
 	}
@@ -235,8 +238,7 @@ static void mtk_spi_set_cs(struct spi_device *spi, bool enable)
 static void mtk_spi_prepare_transfer(struct spi_master *master,
 				     struct spi_transfer *xfer)
 {
-	u32 spi_clk_hz, div, high_time, low_time, holdtime,
-	    setuptime, cs_idletime, reg_val = 0;
+	u32 spi_clk_hz, div, sck_time, cs_time, reg_val = 0;
 	struct mtk_spi *mdata = spi_master_get_devdata(master);
 
 	spi_clk_hz = clk_get_rate(mdata->spi_clk);
@@ -245,21 +247,18 @@ static void mtk_spi_prepare_transfer(struct spi_master *master,
 	else
 		div = 1;
 
-	high_time = (div + 1) / 2;
-	low_time = (div + 1) / 2;
-	holdtime = (div + 1) / 2 * 2;
-	setuptime = (div + 1) / 2 * 2;
-	cs_idletime = (div + 1) / 2 * 2;
+	sck_time = (div + 1) / 2;
+	cs_time = sck_time * 2;
 
-	reg_val |= (((high_time - 1) & 0xff) << SPI_CFG0_SCK_HIGH_OFFSET);
-	reg_val |= (((low_time - 1) & 0xff) << SPI_CFG0_SCK_LOW_OFFSET);
-	reg_val |= (((holdtime - 1) & 0xff) << SPI_CFG0_CS_HOLD_OFFSET);
-	reg_val |= (((setuptime - 1) & 0xff) << SPI_CFG0_CS_SETUP_OFFSET);
+	reg_val |= (((sck_time - 1) & 0xff) << SPI_CFG0_SCK_HIGH_OFFSET);
+	reg_val |= (((sck_time - 1) & 0xff) << SPI_CFG0_SCK_LOW_OFFSET);
+	reg_val |= (((cs_time - 1) & 0xff) << SPI_CFG0_CS_HOLD_OFFSET);
+	reg_val |= (((cs_time - 1) & 0xff) << SPI_CFG0_CS_SETUP_OFFSET);
 	writel(reg_val, mdata->base + SPI_CFG0_REG);
 
 	reg_val = readl(mdata->base + SPI_CFG1_REG);
 	reg_val &= ~SPI_CFG1_CS_IDLE_MASK;
-	reg_val |= (((cs_idletime - 1) & 0xff) << SPI_CFG1_CS_IDLE_OFFSET);
+	reg_val |= (((cs_time - 1) & 0xff) << SPI_CFG1_CS_IDLE_OFFSET);
 	writel(reg_val, mdata->base + SPI_CFG1_REG);
 }
 
@@ -268,11 +267,11 @@ static void mtk_spi_setup_packet(struct spi_master *master)
 	u32 packet_size, packet_loop, reg_val;
 	struct mtk_spi *mdata = spi_master_get_devdata(master);
 
-	packet_size = min_t(unsigned, mdata->xfer_len, MTK_SPI_PACKET_SIZE);
+	packet_size = min_t(u32, mdata->xfer_len, MTK_SPI_PACKET_SIZE);
 	packet_loop = mdata->xfer_len / packet_size;
 
 	reg_val = readl(mdata->base + SPI_CFG1_REG);
-	reg_val &= ~(SPI_CFG1_PACKET_LENGTH_MASK + SPI_CFG1_PACKET_LOOP_MASK);
+	reg_val &= ~(SPI_CFG1_PACKET_LENGTH_MASK | SPI_CFG1_PACKET_LOOP_MASK);
 	reg_val |= (packet_size - 1) << SPI_CFG1_PACKET_LENGTH_OFFSET;
 	reg_val |= (packet_loop - 1) << SPI_CFG1_PACKET_LOOP_OFFSET;
 	writel(reg_val, mdata->base + SPI_CFG1_REG);
@@ -280,7 +279,7 @@ static void mtk_spi_setup_packet(struct spi_master *master)
 
 static void mtk_spi_enable_transfer(struct spi_master *master)
 {
-	int cmd;
+	u32 cmd;
 	struct mtk_spi *mdata = spi_master_get_devdata(master);
 
 	cmd = readl(mdata->base + SPI_CMD_REG);
@@ -291,9 +290,9 @@ static void mtk_spi_enable_transfer(struct spi_master *master)
 	writel(cmd, mdata->base + SPI_CMD_REG);
 }
 
-static int mtk_spi_get_mult_delta(int xfer_len)
+static int mtk_spi_get_mult_delta(u32 xfer_len)
 {
-	int mult_delta;
+	u32 mult_delta;
 
 	if (xfer_len > MTK_SPI_PACKET_SIZE)
 		mult_delta = xfer_len % MTK_SPI_PACKET_SIZE;
@@ -434,7 +433,7 @@ static irqreturn_t mtk_spi_interrupt(int irq, void *dev_id)
 	struct spi_transfer *trans = mdata->cur_transfer;
 
 	reg_val = readl(mdata->base + SPI_STATUS0_REG);
-	if (reg_val & 0x2)
+	if (reg_val & MTK_SPI_PAUSE_INT_STATUS)
 		mdata->state = MTK_SPI_PAUSED;
 	else
 		mdata->state = MTK_SPI_IDLE;
@@ -497,7 +496,7 @@ static int mtk_spi_probe(struct platform_device *pdev)
 	struct mtk_spi *mdata;
 	const struct of_device_id *of_id;
 	struct resource *res;
-	int	irq, ret;
+	int irq, ret;
 
 	master = spi_alloc_master(&pdev->dev, sizeof(*mdata));
 	if (!master) {
@@ -662,8 +661,10 @@ static int mtk_spi_resume(struct device *dev)
 
 	if (!pm_runtime_suspended(dev)) {
 		ret = clk_prepare_enable(mdata->spi_clk);
-		if (ret < 0)
+		if (ret < 0) {
+			dev_err(dev, "failed to enable spi_clk (%d)\n", ret);
 			return ret;
+		}
 	}
 
 	ret = spi_master_resume(master);
@@ -689,8 +690,15 @@ static int mtk_spi_runtime_resume(struct device *dev)
 {
 	struct spi_master *master = dev_get_drvdata(dev);
 	struct mtk_spi *mdata = spi_master_get_devdata(master);
+	int ret;
 
-	return clk_prepare_enable(mdata->spi_clk);
+	ret = clk_prepare_enable(mdata->spi_clk);
+	if (ret < 0) {
+		dev_err(dev, "failed to enable spi_clk (%d)\n", ret);
+		return ret;
+	}
+
+	return 0;
 }
 #endif /* CONFIG_PM */
 
-- 
1.8.1.1.dirty



From david.vrabel at citrix.com  Thu Aug 20 02:49:43 2015
From: david.vrabel at citrix.com (David Vrabel)
Date: Thu, 20 Aug 2015 10:49:43 +0100
Subject: [Xen-devel] [PATCH v3 03/20] xen: Add Xen specific page definition
In-Reply-To: <1438966019-19322-4-git-send-email-julien.grall@citrix.com>
References: <1438966019-19322-1-git-send-email-julien.grall@citrix.com>
 <1438966019-19322-4-git-send-email-julien.grall@citrix.com>
Message-ID: <55D5A2B7.5000106@citrix.com>

On 07/08/15 17:46, Julien Grall wrote:
> The Xen hypercall interface is always using 4K page granularity on ARM
> and x86 architecture.
> 
> With the incoming support of 64K page granularity for ARM64 guest, it
> won't be possible to re-use the Linux page definition in Xen drivers.
> 
> Introduce Xen page definition helpers based on the Linux page
> definition. They have exactly the same name but prefixed with
> XEN_/xen_ prefix.
> 
> Also modify xen_page_to_gfn to use new Xen page definition.
[...]
> +#define xen_page_to_pfn(page)	\
> +	(((page_to_pfn(page)) << PAGE_SHIFT) >> XEN_PAGE_SHIFT)

Rename this to page_to_xen_pfn()

David



From david.vrabel at citrix.com  Thu Aug 20 02:51:51 2015
From: david.vrabel at citrix.com (David Vrabel)
Date: Thu, 20 Aug 2015 10:51:51 +0100
Subject: [Xen-devel] [PATCH v3 04/20] xen/grant: Introduce helpers to
 split a page into grant
In-Reply-To: <1438966019-19322-5-git-send-email-julien.grall@citrix.com>
References: <1438966019-19322-1-git-send-email-julien.grall@citrix.com>
 <1438966019-19322-5-git-send-email-julien.grall@citrix.com>
Message-ID: <55D5A337.7090704@citrix.com>

On 07/08/15 17:46, Julien Grall wrote:
> Currently, a grant is always based on the Xen page granularity (i.e
> 4KB). When Linux is using a different page granularity, a single page
> will be split between multiple grants.
> 
> The new helpers will be in charge to split the Linux page into grants and
> call a function given by the caller on each grant.
> 
> Also provide an helper to count the number of grants within a given
> contiguous region.
> 
> Note that the x86/include/asm/xen/page.h is now including
> xen/interface/grant_table.h rather than xen/grant_table.h. It's
> necessary because xen/grant_table.h depends on asm/xen/page.h and will
> break the compilation. Furthermore, only definition in
> interface/grant_table.h was required.

Reviewed-by: David Vrabel <david.vrabel at citrix.com>

But...

> +/* Helper to get to call fn only on the first "grant chunk" */
> +static inline void gnttab_one_grant(struct page *page, unsigned int offset,
> +				    unsigned len, xen_grant_fn_t fn,
> +				    void *data)

...call this gnttab_for_one_grant().

David


From david.vrabel at citrix.com  Thu Aug 20 02:55:58 2015
From: david.vrabel at citrix.com (David Vrabel)
Date: Thu, 20 Aug 2015 10:55:58 +0100
Subject: [Xen-devel] [PATCH v3 11/20] tty/hvc: xen: Use xen page definition
In-Reply-To: <1438966019-19322-12-git-send-email-julien.grall@citrix.com>
References: <1438966019-19322-1-git-send-email-julien.grall@citrix.com>
 <1438966019-19322-12-git-send-email-julien.grall@citrix.com>
Message-ID: <55D5A42E.7070800@citrix.com>

On 07/08/15 17:46, Julien Grall wrote:
> The console ring is always based on the page granularity of Xen.
[...]
> --- a/drivers/tty/hvc/hvc_xen.c
> +++ b/drivers/tty/hvc/hvc_xen.c
> @@ -230,7 +230,7 @@ static int xen_hvm_console_init(void)
>  	if (r < 0 || v == 0)
>  		goto err;
>  	gfn = v;
> -	info->intf = xen_remap(gfn << PAGE_SHIFT, PAGE_SIZE);
> +	info->intf = xen_remap(gfn << XEN_PAGE_SHIFT, PAGE_SIZE);

You need XEN_PAGE_SIZE here I think...

>  	if (info->intf == NULL)
>  		goto err;
>  	info->vtermno = HVC_COOKIE;
> @@ -472,7 +472,7 @@ static int xencons_resume(struct xenbus_device *dev)
>  	struct xencons_info *info = dev_get_drvdata(&dev->dev);
>  
>  	xencons_disconnect_backend(info);
> -	memset(info->intf, 0, PAGE_SIZE);
> +	memset(info->intf, 0, XEN_PAGE_SIZE);

...particularly since you use it here.

David


From david.vrabel at citrix.com  Thu Aug 20 02:59:57 2015
From: david.vrabel at citrix.com (David Vrabel)
Date: Thu, 20 Aug 2015 10:59:57 +0100
Subject: [Xen-devel] [PATCH v3 12/20] xen/balloon: Don't rely on the page
 granularity is the same for Xen and Linux
In-Reply-To: <1438966019-19322-13-git-send-email-julien.grall@citrix.com>
References: <1438966019-19322-1-git-send-email-julien.grall@citrix.com>
 <1438966019-19322-13-git-send-email-julien.grall@citrix.com>
Message-ID: <55D5A51D.2060106@citrix.com>

On 07/08/15 17:46, Julien Grall wrote:
> For ARM64 guests, Linux is able to support either 64K or 4K page
> granularity. Although, the hypercall interface is always based on 4K
> page granularity.
> 
> With 64K page granularity, a single page will be spread over multiple
> Xen frame.
> 
> To avoid splitting the page into 4K frame, take advantage of the
> extent_order field to directly allocate/free chunk of the Linux page
> size.
> 
> Note that PVMMU is only used for PV guest (which is x86) and the page
> granularity is always 4KB. Some BUILD_BUG_ON has been added to ensure
> that because the code has not been modified.
[...]
>  #ifdef CONFIG_XEN_HAVE_PVMMU
> +		/* We don't support PV MMU when Linux and Xen is using
> +		 * different page granularity.
> +		 */
> +		BUILD_BUG_ON(XEN_PAGE_SIZE != PAGE_SIZE);

You don't need this BUILD_BUG_ON() twice.

Otherwise,

Reviewed-by: David Vrabel <david.vrabel at citrix.com>

David


From mpa at pengutronix.de  Thu Aug 20 03:00:03 2015
From: mpa at pengutronix.de (Markus Pargmann)
Date: Thu, 20 Aug 2015 12:00:03 +0200
Subject: [PATCH v2 0/4] regmap: i2c block support
Message-ID: <1440064807-26346-1-git-send-email-mpa@pengutronix.de>

Hi,

This series adds support for i2c block read/writes. To support the maximum 32
byte read/write operations, the regmap core is extended by max_raw_read and
max_raw_write. bulk operations are splitted depending of the size of
max_raw_read/write.

These patches were included in the previous series "Regmap max_raw_io and
bmc150 SPI support". The patches are based on "regmap: fixes".

I am not able to perform any tests for the last patch of this series as I don't
have hardware to test this on.

Changes in v2:
- max_raw_io splitted into max_raw_read/write
- Use E2BIG as error value in the block read/write functions

Best Regards,

Markus


Markus Pargmann (4):
  regmap: Introduce max_raw_read/write for regmap_bulk_read/write
  regmap: regmap max_raw_read/write getter functions
  regmap: Add raw_write/read checks for max_raw_write/read sizes
  regmap-i2c: Add smbus i2c block support

 drivers/base/regmap/internal.h   |   4 ++
 drivers/base/regmap/regmap-i2c.c |  49 +++++++++++++++++
 drivers/base/regmap/regmap.c     | 113 +++++++++++++++++++++++++++++++++------
 include/linux/regmap.h           |   6 +++
 4 files changed, 157 insertions(+), 15 deletions(-)

-- 
2.4.6



From mpa at pengutronix.de  Thu Aug 20 03:00:07 2015
From: mpa at pengutronix.de (Markus Pargmann)
Date: Thu, 20 Aug 2015 12:00:07 +0200
Subject: [PATCH v2 4/4] regmap-i2c: Add smbus i2c block support
In-Reply-To: <1440064807-26346-1-git-send-email-mpa@pengutronix.de>
References: <1440064807-26346-1-git-send-email-mpa@pengutronix.de>
Message-ID: <1440064807-26346-5-git-send-email-mpa@pengutronix.de>

This allows to read/write up to 32 bytes of data and is to be prefered
if supported before the register read/write smbus support.

Signed-off-by: Markus Pargmann <mpa at pengutronix.de>
---
 drivers/base/regmap/regmap-i2c.c | 49 ++++++++++++++++++++++++++++++++++++++++
 1 file changed, 49 insertions(+)

diff --git a/drivers/base/regmap/regmap-i2c.c b/drivers/base/regmap/regmap-i2c.c
index 4b76e33110a2..ddb9b0efb724 100644
--- a/drivers/base/regmap/regmap-i2c.c
+++ b/drivers/base/regmap/regmap-i2c.c
@@ -209,11 +209,60 @@ static struct regmap_bus regmap_i2c = {
 	.val_format_endian_default = REGMAP_ENDIAN_BIG,
 };
 
+static int regmap_i2c_smbus_i2c_write(void *context, const void *data,
+				      size_t count)
+{
+	struct device *dev = context;
+	struct i2c_client *i2c = to_i2c_client(dev);
+
+	if (count < 1)
+		return -EINVAL;
+	if (count >= I2C_SMBUS_BLOCK_MAX)
+		return -E2BIG;
+
+	--count;
+	return i2c_smbus_write_i2c_block_data(i2c, ((u8 *)data)[0], count,
+					      ((u8 *)data + 1));
+}
+
+static int regmap_i2c_smbus_i2c_read(void *context, const void *reg,
+				     size_t reg_size, void *val,
+				     size_t val_size)
+{
+	struct device *dev = context;
+	struct i2c_client *i2c = to_i2c_client(dev);
+	int ret;
+
+	if (reg_size != 1 || val_size < 1)
+		return -EINVAL;
+	if (val_size >= I2C_SMBUS_BLOCK_MAX)
+		return -E2BIG;
+
+	ret = i2c_smbus_read_i2c_block_data(i2c, ((u8 *)reg)[0], val_size, val);
+	if (ret == val_size)
+		return 0;
+	else if (ret < 0)
+		return ret;
+	else
+		return -EIO;
+}
+
+static struct regmap_bus regmap_i2c_smbus_i2c_block = {
+	.write = regmap_i2c_smbus_i2c_write,
+	.read = regmap_i2c_smbus_i2c_read,
+	.max_raw_read = I2C_SMBUS_BLOCK_MAX,
+	.max_raw_write = I2C_SMBUS_BLOCK_MAX,
+};
+
 static const struct regmap_bus *regmap_get_i2c_bus(struct i2c_client *i2c,
 					const struct regmap_config *config)
 {
 	if (i2c_check_functionality(i2c->adapter, I2C_FUNC_I2C))
 		return &regmap_i2c;
+	else if (config->reg_bits == 8 &&
+		 i2c_check_functionality(i2c->adapter,
+					 I2C_FUNC_SMBUS_I2C_BLOCK))
+		return &regmap_i2c_smbus_i2c_block;
 	else if (config->val_bits == 16 && config->reg_bits == 8 &&
 		 i2c_check_functionality(i2c->adapter,
 					 I2C_FUNC_SMBUS_WORD_DATA))
-- 
2.4.6



From mpa at pengutronix.de  Thu Aug 20 03:00:06 2015
From: mpa at pengutronix.de (Markus Pargmann)
Date: Thu, 20 Aug 2015 12:00:06 +0200
Subject: [PATCH v2 3/4] regmap: Add raw_write/read checks for
 max_raw_write/read sizes
In-Reply-To: <1440064807-26346-1-git-send-email-mpa@pengutronix.de>
References: <1440064807-26346-1-git-send-email-mpa@pengutronix.de>
Message-ID: <1440064807-26346-4-git-send-email-mpa@pengutronix.de>

Check in regmap_raw_read() and regmap_raw_write() for correct maximum
sizes of the operations. Return -E2BIG if this size is not supported
because it is too big.

Also this patch causes an uninitialized variable warning so it
initializes ret (although not necessary).

Signed-off-by: Markus Pargmann <mpa at pengutronix.de>
---
 drivers/base/regmap/regmap.c | 6 ++++++
 1 file changed, 6 insertions(+)

diff --git a/drivers/base/regmap/regmap.c b/drivers/base/regmap/regmap.c
index 99f5f1165b60..77c9f235bf3d 100644
--- a/drivers/base/regmap/regmap.c
+++ b/drivers/base/regmap/regmap.c
@@ -1581,6 +1581,8 @@ int regmap_raw_write(struct regmap *map, unsigned int reg,
 		return -EINVAL;
 	if (val_len % map->format.val_bytes)
 		return -EINVAL;
+	if (map->max_raw_write && map->max_raw_write > val_len)
+		return -E2BIG;
 
 	map->lock(map->lock_arg);
 
@@ -2251,6 +2253,10 @@ int regmap_raw_read(struct regmap *map, unsigned int reg, void *val,
 			ret = -ENOTSUPP;
 			goto out;
 		}
+		if (map->max_raw_read && map->max_raw_read < val_len) {
+			ret = -E2BIG;
+			goto out;
+		}
 
 		/* Physical block read if there's no cache involved */
 		ret = _regmap_raw_read(map, reg, val, val_len);
-- 
2.4.6



From mpa at pengutronix.de  Thu Aug 20 03:00:04 2015
From: mpa at pengutronix.de (Markus Pargmann)
Date: Thu, 20 Aug 2015 12:00:04 +0200
Subject: [PATCH v2 1/4] regmap: Introduce max_raw_read/write for
 regmap_bulk_read/write
In-Reply-To: <1440064807-26346-1-git-send-email-mpa@pengutronix.de>
References: <1440064807-26346-1-git-send-email-mpa@pengutronix.de>
Message-ID: <1440064807-26346-2-git-send-email-mpa@pengutronix.de>

There are some buses which have a limit on the maximum number of bytes
that can be send/received. An example for this is
I2C_FUNC_SMBUS_I2C_BLOCK which does not support any reads/writes of more
than 32 bytes. The regmap_bulk operations should still be able to
utilize the full 32 bytes in this case.

Signed-off-by: Markus Pargmann <mpa at pengutronix.de>
---
 drivers/base/regmap/internal.h |  4 ++
 drivers/base/regmap/regmap.c   | 85 ++++++++++++++++++++++++++++++++++--------
 include/linux/regmap.h         |  4 ++
 3 files changed, 78 insertions(+), 15 deletions(-)

diff --git a/drivers/base/regmap/internal.h b/drivers/base/regmap/internal.h
index d744ae3926dd..fc554e357c5d 100644
--- a/drivers/base/regmap/internal.h
+++ b/drivers/base/regmap/internal.h
@@ -146,6 +146,10 @@ struct regmap {
 	/* if set, the device supports multi write mode */
 	bool can_multi_write;
 
+	/* if set, raw reads/writes are limited to this size */
+	size_t max_raw_read;
+	size_t max_raw_write;
+
 	struct rb_root range_tree;
 	void *selector_work_buf;	/* Scratch buffer used for selector */
 };
diff --git a/drivers/base/regmap/regmap.c b/drivers/base/regmap/regmap.c
index d43723bb3257..bb2bfadfb4a3 100644
--- a/drivers/base/regmap/regmap.c
+++ b/drivers/base/regmap/regmap.c
@@ -576,6 +576,8 @@ struct regmap *regmap_init(struct device *dev,
 	map->use_single_read = config->use_single_rw || !bus || !bus->read;
 	map->use_single_write = config->use_single_rw || !bus || !bus->write;
 	map->can_multi_write = config->can_multi_write && bus && bus->write;
+	map->max_raw_read = bus->max_raw_read;
+	map->max_raw_write = bus->max_raw_write;
 	map->dev = dev;
 	map->bus = bus;
 	map->bus_context = bus_context;
@@ -1671,6 +1673,7 @@ int regmap_bulk_write(struct regmap *map, unsigned int reg, const void *val,
 {
 	int ret = 0, i;
 	size_t val_bytes = map->format.val_bytes;
+	size_t total_size = val_bytes * val_count;
 
 	if (map->bus && !map->format.parse_inplace)
 		return -EINVAL;
@@ -1713,20 +1716,41 @@ int regmap_bulk_write(struct regmap *map, unsigned int reg, const void *val,
 		}
 out:
 		map->unlock(map->lock_arg);
-	} else if (map->use_single_write) {
+	} else if (map->use_single_write ||
+		   (map->max_raw_write && map->max_raw_write < total_size)) {
 		/*
 		 * We need to handle bus writes separate to support val_bytes
 		 * that are not powers of 2.
 		 */
+		int chunk_stride = map->reg_stride;
+		size_t chunk_size = val_bytes;
+		size_t chunk_count = val_count;
+
+		if (!map->use_single_write) {
+			chunk_size = map->max_raw_write;
+			if (chunk_size % val_bytes)
+				chunk_size -= chunk_size % val_bytes;
+			chunk_count = total_size / chunk_size;
+			chunk_stride *= chunk_size / val_bytes;
+		}
+
 		map->lock(map->lock_arg);
-		for (i = 0; i < val_count; i++) {
+		/* Write as many bytes as possible with chunk_size */
+		for (i = 0; i < chunk_count; i++) {
 			ret = _regmap_raw_write(map,
-						reg + (i * map->reg_stride),
-						val + (i * val_bytes),
-						val_bytes);
+						reg + (i * chunk_stride),
+						val + (i * chunk_size),
+						chunk_size);
 			if (ret)
 				break;
 		}
+
+		/* Write remaining bytes */
+		if (!ret && chunk_size * i < total_size) {
+			ret = _regmap_raw_write(map, reg + (i * chunk_stride),
+						val + (i * chunk_size),
+						total_size - i * chunk_size);
+		}
 		map->unlock(map->lock_arg);
 	} else {
 		void *wval;
@@ -2314,20 +2338,51 @@ int regmap_bulk_read(struct regmap *map, unsigned int reg, void *val,
 		 * Some devices does not support bulk read, for
 		 * them we have a series of single read operations.
 		 */
-		if (map->use_single_read) {
-			for (i = 0; i < val_count; i++) {
-				ret = regmap_raw_read(map,
-						reg + (i * map->reg_stride),
-						val + (i * val_bytes),
-						val_bytes);
-				if (ret != 0)
-					return ret;
-			}
-		} else {
+		size_t total_size = val_bytes * val_count;
+
+		if (!map->use_single_read &&
+		    (!map->max_raw_read || map->max_raw_read > total_size)) {
 			ret = regmap_raw_read(map, reg, val,
 					      val_bytes * val_count);
 			if (ret != 0)
 				return ret;
+		} else {
+			/*
+			 * Some devices do not support bulk read or do not
+			 * support large bulk reads, for them we have a series
+			 * of read operations.
+			 */
+			int chunk_stride = map->reg_stride;
+			size_t chunk_size = val_bytes;
+			size_t chunk_count = val_count;
+
+			if (!map->use_single_read) {
+				chunk_size = map->max_raw_read;
+				if (chunk_size % val_bytes)
+					chunk_size -= chunk_size % val_bytes;
+				chunk_count = total_size / chunk_size;
+				chunk_stride *= chunk_size / val_bytes;
+			}
+
+			/* Read bytes that fit into a multiple of chunk_size */
+			for (i = 0; i < chunk_count; i++) {
+				ret = regmap_raw_read(map,
+						      reg + (i * chunk_stride),
+						      val + (i * chunk_size),
+						      chunk_size);
+				if (ret != 0)
+					return ret;
+			}
+
+			/* Read remaining bytes */
+			if (chunk_size * i < total_size) {
+				ret = regmap_raw_read(map,
+						      reg + (i * chunk_stride),
+						      val + (i * chunk_size),
+						      total_size - i * chunk_size);
+				if (ret != 0)
+					return ret;
+			}
 		}
 
 		for (i = 0; i < val_count * val_bytes; i += val_bytes)
diff --git a/include/linux/regmap.h b/include/linux/regmap.h
index 915454a1b54e..6c9de3e8dd6e 100644
--- a/include/linux/regmap.h
+++ b/include/linux/regmap.h
@@ -310,6 +310,8 @@ typedef void (*regmap_hw_free_context)(void *context);
  * @val_format_endian_default: Default endianness for formatted register
  *     values. Used when the regmap_config specifies DEFAULT. If this is
  *     DEFAULT, BIG is assumed.
+ * @max_raw_read: Max raw read size that can be used on the bus.
+ * @max_raw_write: Max raw write size that can be used on the bus.
  */
 struct regmap_bus {
 	bool fast_io;
@@ -324,6 +326,8 @@ struct regmap_bus {
 	u8 read_flag_mask;
 	enum regmap_endian reg_format_endian_default;
 	enum regmap_endian val_format_endian_default;
+	size_t max_raw_read;
+	size_t max_raw_write;
 };
 
 struct regmap *regmap_init(struct device *dev,
-- 
2.4.6



From mpa at pengutronix.de  Thu Aug 20 03:00:05 2015
From: mpa at pengutronix.de (Markus Pargmann)
Date: Thu, 20 Aug 2015 12:00:05 +0200
Subject: [PATCH v2 2/4] regmap: regmap max_raw_read/write getter functions
In-Reply-To: <1440064807-26346-1-git-send-email-mpa@pengutronix.de>
References: <1440064807-26346-1-git-send-email-mpa@pengutronix.de>
Message-ID: <1440064807-26346-3-git-send-email-mpa@pengutronix.de>

Add functions to access the maximum size we can read/write using
regmap_raw_read/write().

This helps drivers that need to know how much they can write with the
raw functions without problems. There are some devices (e.g. bmc150)
that have fifos as registers which need to be read in specific chunks
otherwise samples are dropped.

Signed-off-by: Markus Pargmann <mpa at pengutronix.de>
---
 drivers/base/regmap/regmap.c | 22 ++++++++++++++++++++++
 include/linux/regmap.h       |  2 ++
 2 files changed, 24 insertions(+)

diff --git a/drivers/base/regmap/regmap.c b/drivers/base/regmap/regmap.c
index bb2bfadfb4a3..99f5f1165b60 100644
--- a/drivers/base/regmap/regmap.c
+++ b/drivers/base/regmap/regmap.c
@@ -1390,6 +1390,28 @@ bool regmap_can_raw_write(struct regmap *map)
 }
 EXPORT_SYMBOL_GPL(regmap_can_raw_write);
 
+/**
+ * regmap_get_raw_read_max - Get the maximum size we can read
+ *
+ * @map: Map to check.
+ */
+size_t regmap_get_raw_read_max(struct regmap *map)
+{
+	return map->max_raw_read;
+}
+EXPORT_SYMBOL_GPL(regmap_get_raw_read_max);
+
+/**
+ * regmap_get_raw_write_max - Get the maximum size we can read
+ *
+ * @map: Map to check.
+ */
+size_t regmap_get_raw_write_max(struct regmap *map)
+{
+	return map->max_raw_write;
+}
+EXPORT_SYMBOL_GPL(regmap_get_raw_write_max);
+
 static int _regmap_bus_formatted_write(void *context, unsigned int reg,
 				       unsigned int val)
 {
diff --git a/include/linux/regmap.h b/include/linux/regmap.h
index 6c9de3e8dd6e..9a49a2e22cc0 100644
--- a/include/linux/regmap.h
+++ b/include/linux/regmap.h
@@ -443,6 +443,8 @@ int regmap_get_max_register(struct regmap *map);
 int regmap_get_reg_stride(struct regmap *map);
 int regmap_async_complete(struct regmap *map);
 bool regmap_can_raw_write(struct regmap *map);
+size_t regmap_get_raw_read_max(struct regmap *map);
+size_t regmap_get_raw_write_max(struct regmap *map);
 
 int regcache_sync(struct regmap *map);
 int regcache_sync_region(struct regmap *map, unsigned int min,
-- 
2.4.6



From david.vrabel at citrix.com  Thu Aug 20 03:03:50 2015
From: david.vrabel at citrix.com (David Vrabel)
Date: Thu, 20 Aug 2015 11:03:50 +0100
Subject: [Xen-devel] [PATCH v3 17/20] net/xen-netfront: Make it running
 on 64KB page granularity
In-Reply-To: <1438966019-19322-18-git-send-email-julien.grall@citrix.com>
References: <1438966019-19322-1-git-send-email-julien.grall@citrix.com>
 <1438966019-19322-18-git-send-email-julien.grall@citrix.com>
Message-ID: <55D5A606.7020701@citrix.com>

On 07/08/15 17:46, Julien Grall wrote:
> The PV network protocol is using 4KB page granularity. The goal of this
> patch is to allow a Linux using 64KB page granularity using network
> device on a non-modified Xen.
> 
> It's only necessary to adapt the ring size and break skb data in small
> chunk of 4KB. The rest of the code is relying on the grant table code.
> 
> Note that we allocate a Linux page for each rx skb but only the first
> 4KB is used. We may improve the memory usage by extending the size of
> the rx skb.

Reviewed-by: David Vrabel <david.vrabel at citrix.com>

David


From david.vrabel at citrix.com  Thu Aug 20 03:08:56 2015
From: david.vrabel at citrix.com (David Vrabel)
Date: Thu, 20 Aug 2015 11:08:56 +0100
Subject: [Xen-devel] [PATCH v3 19/20] xen/privcmd: Add support for Linux
 64KB page granularity
In-Reply-To: <1438966019-19322-20-git-send-email-julien.grall@citrix.com>
References: <1438966019-19322-1-git-send-email-julien.grall@citrix.com>
 <1438966019-19322-20-git-send-email-julien.grall@citrix.com>
Message-ID: <55D5A738.9020403@citrix.com>

On 07/08/15 17:46, Julien Grall wrote:
> The hypercall interface (as well as the toolstack) is always using 4KB
> page granularity. When the toolstack is asking for mapping a series of
> guest PFN in a batch, it expects to have the page map contiguously in
> its virtual memory.
> 
> When Linux is using 64KB page granularity, the privcmd driver will have
> to map multiple Xen PFN in a single Linux page.
> 
> Note that this solution works on page granularity which is a multiple of
> 4KB.

Reviewed-by: David Vrabel <david.vrabel at citrix.com>

David


From david.vrabel at citrix.com  Thu Aug 20 03:11:23 2015
From: david.vrabel at citrix.com (David Vrabel)
Date: Thu, 20 Aug 2015 11:11:23 +0100
Subject: [Xen-devel] [PATCH v3 00/20] xen/arm64: Add support for 64KB page
In-Reply-To: <55D521F2.5080504@citrix.com>
References: <1438966019-19322-1-git-send-email-julien.grall@citrix.com>
 <55D521F2.5080504@citrix.com>
Message-ID: <55D5A7CB.3070207@citrix.com>

On 20/08/15 01:40, Julien Grall wrote:
> Hi,
> 
> Ping? I'm missing some reviews on block and netfront code.
> 
> We'd like to see this series going in Linux 4.3. Some distributions
> plans to use this version for aarch64 support. If we miss it, we won't
> have any Xen guests support, even it's minimal, for Linux using 64KB
> page granularity.

This is too late for Linux 4.3.

David


From will.deacon at arm.com  Thu Aug 20 03:13:22 2015
From: will.deacon at arm.com (Will Deacon)
Date: Thu, 20 Aug 2015 11:13:22 +0100
Subject: [PATCH v2 2/5] ACPI / ARM64: remove usage of
 BAD_MADT_ENTRY/BAD_MADT_GICC_ENTRY
In-Reply-To: <1440022048-6285-3-git-send-email-al.stone@linaro.org>
References: <1440022048-6285-1-git-send-email-al.stone@linaro.org>
 <1440022048-6285-3-git-send-email-al.stone@linaro.org>
Message-ID: <20150820101322.GA19328@arm.com>

Hi Al,

On Wed, Aug 19, 2015 at 11:07:25PM +0100, Al Stone wrote:
> Now that we have introduced the bad_madt_entry() function, and that
> function is being invoked in acpi_table_parse_madt() for us, there
> is no longer any need to use the BAD_MADT_ENTRY macro, or in the case
> of arm64, the BAD_MADT_GICC_ENTRY, too.
> 
> Signed-off-by: Al Stone <al.stone at linaro.org>
> Acked-by: Catalin Marinas <catalin.marinas at arm.com>
> Acked-by: Marc Zyngier <marc.zyngier at arm.com>
> Cc: Will Deacon <will.deacon at arm.com>
> Cc: Thomas Gleixner <tglx at linutronix.de>
> Cc: Jason Cooper <jason at lakedaemon.net>
> ---
>  arch/arm64/include/asm/acpi.h | 8 --------
>  arch/arm64/kernel/smp.c       | 2 --
>  drivers/irqchip/irq-gic.c     | 6 ------
>  3 files changed, 16 deletions(-)

How are you planning to merge this (and which kernel are you targetting?)
You've got Acks for both arm64 and irqchip, so I guess either of those
trees could take it.

Will


From rsahu at apm.com  Thu Aug 20 03:30:56 2015
From: rsahu at apm.com (Rameshwar Prasad Sahu)
Date: Thu, 20 Aug 2015 16:00:56 +0530
Subject: [PATCH] dmaengine: xgene-dma: Fix holding lock while calling tx
 callback in cleanup path
Message-ID: <1440066656-15516-1-git-send-email-rsahu@apm.com>

This patch fixes the an locking issue where client callback performs
further submission.

Signed-off-by: Rameshwar Prasad Sahu <rsahu at apm.com>
---
 drivers/dma/xgene-dma.c | 33 ++++++++++++++++++++++-----------
 1 file changed, 22 insertions(+), 11 deletions(-)

diff --git a/drivers/dma/xgene-dma.c b/drivers/dma/xgene-dma.c
index d1c8809..0b82bc0 100644
--- a/drivers/dma/xgene-dma.c
+++ b/drivers/dma/xgene-dma.c
@@ -763,12 +763,17 @@ static void xgene_dma_cleanup_descriptors(struct xgene_dma_chan *chan)
 	struct xgene_dma_ring *ring = &chan->rx_ring;
 	struct xgene_dma_desc_sw *desc_sw, *_desc_sw;
 	struct xgene_dma_desc_hw *desc_hw;
+	struct list_head ld_completed;
 	u8 status;

+	INIT_LIST_HEAD(&ld_completed);
+
+	spin_lock_bh(&chan->lock);
+
 	/* Clean already completed and acked descriptors */
 	xgene_dma_clean_completed_descriptor(chan);

-	/* Run the callback for each descriptor, in order */
+	/* Move all completed descriptors to ld completed queue, in order */
 	list_for_each_entry_safe(desc_sw, _desc_sw, &chan->ld_running, node) {
 		/* Get subsequent hw descriptor from DMA rx ring */
 		desc_hw = &ring->desc_hw[ring->head];
@@ -811,15 +816,17 @@ static void xgene_dma_cleanup_descriptors(struct xgene_dma_chan *chan)
 		/* Mark this hw descriptor as processed */
 		desc_hw->m0 = cpu_to_le64(XGENE_DMA_DESC_EMPTY_SIGNATURE);

-		xgene_dma_run_tx_complete_actions(chan, desc_sw);
-
-		xgene_dma_clean_running_descriptor(chan, desc_sw);
-
 		/*
 		 * Decrement the pending transaction count
 		 * as we have processed one
 		 */
 		chan->pending--;
+
+		/*
+		 * Delete this node from ld running queue and append it to
+		 * ld completed queue for further processing
+		 */
+		list_move_tail(&desc_sw->node, &ld_completed);
 	}

 	/*
@@ -828,6 +835,14 @@ static void xgene_dma_cleanup_descriptors(struct xgene_dma_chan *chan)
 	 * ahead and free the descriptors below.
 	 */
 	xgene_chan_xfer_ld_pending(chan);
+
+	spin_unlock_bh(&chan->lock);
+
+	/* Run the callback for each descriptor, in order */
+	list_for_each_entry_safe(desc_sw, _desc_sw, &ld_completed, node) {
+		xgene_dma_run_tx_complete_actions(chan, desc_sw);
+		xgene_dma_clean_running_descriptor(chan, desc_sw);
+	}
 }

 static int xgene_dma_alloc_chan_resources(struct dma_chan *dchan)
@@ -876,11 +891,11 @@ static void xgene_dma_free_chan_resources(struct dma_chan *dchan)
 	if (!chan->desc_pool)
 		return;

-	spin_lock_bh(&chan->lock);
-
 	/* Process all running descriptor */
 	xgene_dma_cleanup_descriptors(chan);

+	spin_lock_bh(&chan->lock);
+
 	/* Clean all link descriptor queues */
 	xgene_dma_free_desc_list(chan, &chan->ld_pending);
 	xgene_dma_free_desc_list(chan, &chan->ld_running);
@@ -1200,15 +1215,11 @@ static void xgene_dma_tasklet_cb(unsigned long data)
 {
 	struct xgene_dma_chan *chan = (struct xgene_dma_chan *)data;

-	spin_lock_bh(&chan->lock);
-
 	/* Run all cleanup for descriptors which have been completed */
 	xgene_dma_cleanup_descriptors(chan);

 	/* Re-enable DMA channel IRQ */
 	enable_irq(chan->rx_irq);
-
-	spin_unlock_bh(&chan->lock);
 }

 static irqreturn_t xgene_dma_chan_ring_isr(int irq, void *id)
--
1.8.2.1



From will.deacon at arm.com  Thu Aug 20 03:38:11 2015
From: will.deacon at arm.com (Will Deacon)
Date: Thu, 20 Aug 2015 11:38:11 +0100
Subject: [PATCH] arm: Adding support for atomic half word exchange
In-Reply-To: <1707387422.329291440052843653.JavaMail.weblogic@ep2mlwas04c>
References: <1707387422.329291440052843653.JavaMail.weblogic@ep2mlwas04c>
Message-ID: <20150820103810.GC19328@arm.com>

On Thu, Aug 20, 2015 at 07:40:44AM +0100, Sarbojit Ganguly wrote:
> My apologies, the e-mail editor was not configured properly.
> CC'ed to relevant maintainers and reposting once again with proper formatting.
> 
> Since 16 bit half word exchange was not there and MCS based qspinlock
> by Waiman's xchg_tail() requires an atomic exchange on a half word, 
> here is a small modification to __xchg() code to support the exchange.
> ARMv6 and lower does not have support for LDREXH, so we need to make sure things
> do not break when we're compiling on ARMv6.
> 
> Signed-off-by: Sarbojit Ganguly <ganguly.s at samsung.com>
> ---
>  arch/arm/include/asm/cmpxchg.h | 18 ++++++++++++++++++
>  1 file changed, 18 insertions(+)
> 
> diff --git a/arch/arm/include/asm/cmpxchg.h b/arch/arm/include/asm/cmpxchg.h
> index 1692a05..547101d 100644
> --- a/arch/arm/include/asm/cmpxchg.h
> +++ b/arch/arm/include/asm/cmpxchg.h
> @@ -50,6 +50,24 @@ static inline unsigned long __xchg(unsigned long x, volatile void *ptr, int size
>                         : "r" (x), "r" (ptr)
>                         : "memory", "cc");
>                 break;
> +#if !defined (CONFIG_CPU_V6)
> +               /*
> +                * Halfword exclusive exchange
> +                * This is new implementation as qspinlock
> +                * wants 16 bit atomic CAS.
> +                * This is not supported on ARMv6.
> +                */

I don't think you need this comment. We don't use qspinlock on arch/arm/.

> +       case 2:
> +               asm volatile("@ __xchg2\n"
> +               "1:     ldrexh  %0, [%3]\n"
> +               "       strexh  %1, %2, [%3]\n"
> +               "       teq     %1, #0\n"
> +               "       bne     1b"
> +               : "=&r" (ret), "=&r" (tmp)
> +               : "r" (x), "r" (ptr)
> +               : "memory", "cc");
> +               break;
> +#endif
>         case 4:
>                 asm volatile("@ __xchg4\n"
>                 "1:     ldrex   %0, [%3]\n"

We have the same issue with the byte exclusives, so I think you need
to extend the guard you're adding to cover that case too (which is a bug
in current mainline).

Will


From will.deacon at arm.com  Thu Aug 20 03:46:45 2015
From: will.deacon at arm.com (Will Deacon)
Date: Thu, 20 Aug 2015 11:46:45 +0100
Subject: [PATCH 3/3] [v2] hvc_dcc: disable user-space access to DCC
In-Reply-To: <1440025370-9519-3-git-send-email-timur@codeaurora.org>
References: <1440025370-9519-1-git-send-email-timur@codeaurora.org>
 <1440025370-9519-3-git-send-email-timur@codeaurora.org>
Message-ID: <20150820104645.GD19328@arm.com>

On Thu, Aug 20, 2015 at 12:02:50AM +0100, Timur Tabi wrote:
> If the DCC driver loads, then disable user-space access to the DCC so that
> we don't have two entities trying to access the DCC at the same time.

In the interests of making some headway with this, just drop this patch
and I'll queue the diff below via the arm64 tree.

Will

--->8

diff --git a/arch/arm64/mm/proc.S b/arch/arm64/mm/proc.S
index 39139a3aa16d..4c922ecce600 100644
--- a/arch/arm64/mm/proc.S
+++ b/arch/arm64/mm/proc.S
@@ -156,7 +156,7 @@ ENTRY(__cpu_setup)
 
 	mov	x0, #3 << 20
 	msr	cpacr_el1, x0			// Enable FP/ASIMD
-	msr	mdscr_el1, xzr			// Reset mdscr_el1
+	msr	mdscr_el1, #1 << 12		// Reset mdscr_el1
 	/*
 	 * Memory region attributes for LPAE:
 	 *


From anurag.kumar.vulisha at xilinx.com  Thu Aug 20 03:47:48 2015
From: anurag.kumar.vulisha at xilinx.com (Anurag Kumar Vulisha)
Date: Thu, 20 Aug 2015 10:47:48 +0000
Subject: [PATCH] dmaengine: vdma: Add 64 bit addressing support to the
 driver
In-Reply-To: <2214014.FVHbR3JRBK@avalon>
References: <1438775257-3511-1-git-send-email-anuragku@xilinx.com>
 <2214014.FVHbR3JRBK@avalon>
Message-ID: <3802E9A6666DF54886E2B9CBF743BA9801BF8264@XAP-PVEXMBX01.xlnx.xilinx.com>

Hi Laurent,

> -----Original Message-----
> From: Anurag Kumar Vulisha
> Sent: Thursday, August 20, 2015 2:41 PM
> To: Anurag Kumar Vulisha
> Subject: RE:[PATCH] dmaengine: vdma: Add 64 bit addressing support to the
> driver
> 
> 
> Hi Anurag,
> 
> Thank you for the patch.
> 
> On Wednesday 05 August 2015 17:17:37 Anurag Kumar Vulisha wrote:
> > This patch adds the 64 bit addressing support to the vdma driver.
> >
> > Signed-off-by: Anurag Kumar Vulisha <anuragku at xilinx.com>
> > ---
> >  drivers/dma/Kconfig              |    2 +-
> >  drivers/dma/xilinx/xilinx_vdma.c |   36
> ++++++++++++++++++++++++++++------
> >  2 files changed, 31 insertions(+), 7 deletions(-)
> >
> > diff --git a/drivers/dma/Kconfig b/drivers/dma/Kconfig index
> > bda2cb0..a7cd0a8 100644
> > --- a/drivers/dma/Kconfig
> > +++ b/drivers/dma/Kconfig
> > @@ -398,7 +398,7 @@ config FSL_EDMA
> >
> >  config XILINX_VDMA
> >  	tristate "Xilinx AXI VDMA Engine"
> > -	depends on (ARCH_ZYNQ || MICROBLAZE)
> > +	depends on (ARCH_ZYNQ || MICROBLAZE || ARM64)
> >  	select DMA_ENGINE
> >  	help
> >  	  Enable support for Xilinx AXI VDMA Soft IP.
> > diff --git a/drivers/dma/xilinx/xilinx_vdma.c
> > b/drivers/dma/xilinx/xilinx_vdma.c index d8434d4..3dcbd29 100644
> > --- a/drivers/dma/xilinx/xilinx_vdma.c
> > +++ b/drivers/dma/xilinx/xilinx_vdma.c
> > @@ -98,7 +98,11 @@
> >  #define XILINX_VDMA_FRMDLY_STRIDE_FRMDLY_SHIFT	24
> >  #define XILINX_VDMA_FRMDLY_STRIDE_STRIDE_SHIFT	0
> >
> > +#if defined(CONFIG_PHYS_ADDR_T_64BIT)
> 
> Strictly speaking that should be CONFIG_ARCH_DMA_ADDR_T_64BIT.
> 

Will change this in v2

> > +#define XILINX_VDMA_REG_START_ADDRESS(n)	(0x000c + 8 * (n))
> > +#else
> >  #define XILINX_VDMA_REG_START_ADDRESS(n)	(0x000c + 4 * (n))
> > +#endif
> >
> >  /* HW specific definitions */
> >  #define XILINX_VDMA_MAX_CHANS_PER_DEVICE	0x2
> > @@ -143,16 +147,16 @@
> >   * @next_desc: Next Descriptor Pointer @0x00
> >   * @pad1: Reserved @0x04
> >   * @buf_addr: Buffer address @0x08
> > - * @pad2: Reserved @0x0C
> > - * @vsize: Vertical Size @0x10
> > - * @hsize: Horizontal Size @0x14
> > + * @pad2: Reserved @0x10
> > + * @vsize: Vertical Size @0x14
> > + * @hsize: Horizontal Size @0x18
> >   * @stride: Number of bytes between the first
> > - *	    pixels of each horizontal line @0x18
> > + *	    pixels of each horizontal line @0x1C
> >   */
> >  struct xilinx_vdma_desc_hw {
> >  	u32 next_desc;
> >  	u32 pad1;
> > -	u32 buf_addr;
> > +	u64 buf_addr;
> 
> This will change the descriptor layout for 32-bit VDMA, I don't think that's
> right.
> 

Will change this in v2

> >  	u32 pad2;
> >  	u32 vsize;
> >  	u32 hsize;
> > @@ -272,6 +276,20 @@ static inline void vdma_desc_write(struct
> > xilinx_vdma_chan *chan, u32 reg, vdma_write(chan, chan->desc_offset +
> > reg, value);  }
> >
> > +#if defined(CONFIG_PHYS_ADDR_T_64BIT) static inline void
> > +vdma_desc_write_64(struct xilinx_vdma_chan *chan, u32
> > reg,
> > +				 u64 value)
> > +{
> > +	/* Write the lsb 32 bits*/
> > +	writel(lower_32_bits(value),
> > +			chan->xdev->regs + chan->desc_offset + reg);
> > +
> > +	/* Write the msb 32 bits */
> > +	writel(upper_32_bits(value),
> > +			chan->xdev->regs + chan->desc_offset + reg + 4);
> 
> So the CPU can't perform 64-bit register access ?
>

We are trying to write at a register address(0x5c) which is not aligned on
8 bytes boundary.So if I try to use 64 bit write on it, unalignment fault will
be generated. Because of this we are using two separate 32  bit writes. 
 
> How is 64 bit DMA addressing implemented ? Can you use a 64-bit VDMA on
> a 32- bit platform with LPAE ? Can you use a 32-bit VDMA on a 64-bit platform
> ?
> Given that VDMA is an IP core you can instantiate in the programmable logic I
> expect some level of flexibility to be possible, but this patch doesn't seem to
> support it. Please provide more context to allow a proper review (and please
> include it in the commit message of v2).
>

The VDMA core is a soft ip, which can be programmed to support both 32 bit and
64 bit addressing.When the VDMA core is configured for 32 bit address space ,
transfer start address is specified by a single register.

When the  VDMA core is configured for an address space greater than 32, each
start address is specified by a combination of two registers.The first register
specifies the LSB 32 bits of address, while the next register specifies the MSB
32 bits of address.For example,5Ch will specify the LSB bits while 60h will
specify the MSB bits of the first start address. So we need to program two
registers at a time.

Yes,64 bit vdma can be used on 32 bit platform and 32 bit vdma can also be used
on 64 bit platform.As far as i know , there is no use case where 64 bit dma can
be used on 32 bit platform.Please correct me if i am wrong.

> > +}
> > +#endif
> > +
> >  static inline u32 vdma_ctrl_read(struct xilinx_vdma_chan *chan, u32
> > reg)  {
> >  	return vdma_read(chan, chan->ctrl_offset + reg); @@ -700,9 +718,15
> > @@ static void xilinx_vdma_start_transfer(struct xilinx_vdma_chan
> > *chan) int i = 0;
> >
> >  		list_for_each_entry(segment, &desc->segments, node) {
> > -			vdma_desc_write(chan,
> > +#if defined(CONFIG_PHYS_ADDR_T_64BIT)
> > +			vdma_desc_write_64(chan,
> >
> 	XILINX_VDMA_REG_START_ADDRESS(i++),
> >  					segment->hw.buf_addr);
> > +#else
> > +			vdma_desc_write(chan,
> > +
> 	XILINX_VDMA_REG_START_ADDRESS(i++),
> > +					(u32)segment->hw.buf_addr);
> > +#endif
> >  			last = segment;
> >  		}
> 
> --

Thanks,
Anurag Kumar V



From will.deacon at arm.com  Thu Aug 20 03:51:27 2015
From: will.deacon at arm.com (Will Deacon)
Date: Thu, 20 Aug 2015 11:51:27 +0100
Subject: [PATCH] arm64: entry: always restore x0 from the stack on
 syscall return
In-Reply-To: <55D592E4.50609@linaro.org>
References: <1439996989-5772-1-git-send-email-will.deacon@arm.com>
 <20150819160320.GI24062@e104818-lin.cambridge.arm.com>
 <20150819162359.GA10297@arm.com>
 <20150819163504.GL24062@e104818-lin.cambridge.arm.com>
 <20150819165643.GD10297@arm.com> <55D592E4.50609@linaro.org>
Message-ID: <20150820105127.GE19328@arm.com>

On Thu, Aug 20, 2015 at 09:42:12AM +0100, Hanjun Guo wrote:
> On 08/20/2015 12:56 AM, Will Deacon wrote:
> > On Wed, Aug 19, 2015 at 05:35:05PM +0100, Catalin Marinas wrote:
> >> On Wed, Aug 19, 2015 at 05:23:59PM +0100, Will Deacon wrote:
> >>> On Wed, Aug 19, 2015 at 05:03:20PM +0100, Catalin Marinas wrote:
> >>>> There is another str x0 in __sys_trace_return which I think we could
> >>>> remove.
> >>>
> >>> Hmm, I don't think we can remove that. It's needed on the slowpath to
> >>> update the pt_regs with either -ENOSYS (for __ni_sys_trace) or the
> >>> syscall return value from the blr in __sys_trace.
> >>>
> >>> What we can do instead is change the branch above to branch to
> >>> __sys_trace_return_skipped. Patch below.
> >>>
> >>> Will
> >>>
> >>> --->8
> >>>
> >>> diff --git a/arch/arm64/kernel/entry.S b/arch/arm64/kernel/entry.S
> >>> index 2a5e64ccc991..088322ff1ba0 100644
> >>> --- a/arch/arm64/kernel/entry.S
> >>> +++ b/arch/arm64/kernel/entry.S
> >>> @@ -619,7 +619,7 @@ ret_fast_syscall:
> >>>          kernel_exit 0
> >>>   ret_fast_syscall_trace:
> >>>          enable_irq                              // enable interrupts
> >>> -       b       __sys_trace_return
> >>> +       b       __sys_trace_return_skipped      // we already saved x0
> >>
> >> That would do. With this added:
> >>
> >> Reviewed-by: Catalin Marinas <catalin.marinas at arm.com>
> >>
> >> (or I can take it for 4.2 but I'd like more testing like LTP)
> >
> > Yeah, I'll run some tests overnight and see how it holds up.
> 
> How is the stress test going on? I didn't do some stress test but
> when I applied this patch (along with above additions), the problem
> I reported is gone,
> 
> Tested-by: Hanjun Guo <hanjun.guo at linaro.org>

Thanks, Hanjun. LTP passed successfully, so I think the patch is ok but
there's no need to rush it in for 4.2.

Will


From tomi.valkeinen at ti.com  Thu Aug 20 03:55:46 2015
From: tomi.valkeinen at ti.com (Tomi Valkeinen)
Date: Thu, 20 Aug 2015 13:55:46 +0300
Subject: [PATCH v1, TRIVIAL] Fix pxafb nonstd field documentation and
 add errata info
In-Reply-To: <55C64864.6070405@tul.cz>
References: <55C64864.6070405@tul.cz>
Message-ID: <55D5B232.9090006@ti.com>



On 08/08/15 21:20, Petr Cvek wrote:

> diff --git a/drivers/video/fbdev/Kconfig b/drivers/video/fbdev/Kconfig
> index 2d98de5..8f485ec 100644
> --- a/drivers/video/fbdev/Kconfig
> +++ b/drivers/video/fbdev/Kconfig
> @@ -1893,6 +1893,11 @@ config FB_PXA_OVERLAY
>  	bool "Support PXA27x/PXA3xx Overlay(s) as framebuffer"
>  	default n
>  	depends on FB_PXA && (PXA27x || PXA3xx)
> +	---help---
> +	  Using the overlay 2 and YUV420 mode on a PXA27x C0 chip revision will
> +	  hang the LCD until the next SoC restart (errata E24).

Shouldn't the driver handle this? It should not allow the combination to
be used.

 Tomi

-------------- next part --------------
A non-text attachment was scrubbed...
Name: signature.asc
Type: application/pgp-signature
Size: 819 bytes
Desc: OpenPGP digital signature
URL: <http://lists.infradead.org/pipermail/linux-arm-kernel/attachments/20150820/042b80a1/attachment.sig>

From gabriele.paoloni at huawei.com  Thu Aug 20 04:10:24 2015
From: gabriele.paoloni at huawei.com (Gabriele Paoloni)
Date: Thu, 20 Aug 2015 11:10:24 +0000
Subject: [PATCH v7 3/6] PCI: designware: Add ARM64 support
In-Reply-To: <1440059243.31432.59.camel@pengutronix.de>
References: <1439812554-180426-1-git-send-email-wangzhou1@hisilicon.com>
 <1439812554-180426-4-git-send-email-wangzhou1@hisilicon.com>
 <1439988852.31432.15.camel@pengutronix.de>
 <EE11001F9E5DDD47B7634E2F8A612F2E01D81315@lhreml503-mbs>
 <1439998622.31432.44.camel@pengutronix.de>
 <EE11001F9E5DDD47B7634E2F8A612F2E01D8139B@lhreml503-mbs>
 <1440059243.31432.59.camel@pengutronix.de>
Message-ID: <EE11001F9E5DDD47B7634E2F8A612F2E01D81BAC@lhreml503-mbs>

Hi Lucas

Again many thanks for explaining and for your time.

I got your point now and I have dug a bit better in the PCI_DOMAINS code.

However I have a question...see inline below

> -----Original Message-----
> From: Lucas Stach [mailto:l.stach at pengutronix.de]
> Sent: Thursday, August 20, 2015 9:27 AM
> To: Gabriele Paoloni
> Cc: Wangzhou (B); Bjorn Helgaas; jingoohan1 at gmail.com; Pratyush Anand;
> Arnd Bergmann; linux at arm.linux.org.uk; thomas.petazzoni at free-
> electrons.com; lorenzo.pieralisi at arm.com; james.morse at arm.com;
> Liviu.Dudau at arm.com; jason at lakedaemon.net; robh at kernel.org; linux-
> pci at vger.kernel.org; linux-arm-kernel at lists.infradead.org;
> devicetree at vger.kernel.org; Yuanzhichang; Zhudacai; zhangjukuo;
> qiuzhenfa; liudongdong (C); qiujiang; xuwei (O); Liguozhu (Kenneth)
> Subject: Re: [PATCH v7 3/6] PCI: designware: Add ARM64 support
> 
> Hi Gab,
> 
> Am Mittwoch, den 19.08.2015, 16:34 +0000 schrieb Gabriele Paoloni:
> > Hi Lucas
> >
> > First of all many thanks for the quick reply, really appreciated
> >
> > > -----Original Message-----
> > > From: Lucas Stach [mailto:l.stach at pengutronix.de]
> > > Sent: Wednesday, August 19, 2015 4:37 PM
> > > To: Gabriele Paoloni
> > > Cc: Wangzhou (B); Bjorn Helgaas; jingoohan1 at gmail.com; Pratyush
> Anand;
> > > Arnd Bergmann; linux at arm.linux.org.uk; thomas.petazzoni at free-
> > > electrons.com; lorenzo.pieralisi at arm.com; james.morse at arm.com;
> > > Liviu.Dudau at arm.com; jason at lakedaemon.net; robh at kernel.org; linux-
> > > pci at vger.kernel.org; linux-arm-kernel at lists.infradead.org;
> > > devicetree at vger.kernel.org; Yuanzhichang; Zhudacai; zhangjukuo;
> > > qiuzhenfa; liudongdong (C); qiujiang; xuwei (O); Liguozhu (Kenneth)
> > > Subject: Re: [PATCH v7 3/6] PCI: designware: Add ARM64 support
> > >
> > > Hi Gab,
> > >
> > > Am Mittwoch, den 19.08.2015, 15:16 +0000 schrieb Gabriele Paoloni:
> > > > Hi Lucas
> > > >
> > > > I have rewritten the patch to take into account multiple
> controllers.
> > > >
> > > > As you can see now there is a static var in dw_pcie_host_init()
> that
> > > tracks
> > > > the bus numbers used.
> > >
> > > This is wrong. The DT specifies the valid bus number range. You can
> not
> > > just assign the next free bus number to the root bus.
> >
> > I think this is what is being done in
> > http://lxr.free-electrons.com/source/arch/arm/kernel/bios32.c#L495
> > and currently designware assigns the root bus number in
> > http://lxr.free-electrons.com/source/drivers/pci/host/pcie-
> designware.c#L730
> >
> You found the right spot. It works a bit different than I remember, but
> is less broken than your current code. :)
> 
> It actually assigns the next instance a root bus number behind the
> current instances bus range. Please note the difference to your code
> which assigns the next free bus number, which may still lay within the
> current instances bus range.

Mmmm here I have done a mistake: in the current designware the number of hw
controllers is always 1
http://lxr.free-electrons.com/source/drivers/pci/host/pcie-designware.c#L510
So the loop in bios32.c does not work on multiple PCIe ports...
However your comment about PCI_DOMAINS enlightened my mind and now I see
that when CONFIG_PCI_DOMAINS is defined we have the domains numbers
(tracked by __domain_nr).
So (correct me if I am wrong) if we have 2 PCIe ports that do not specify
the "bus-range" property, both root ports will enumerate starting from 
root_bus_nr = 0 and everything will still work ok.

So if my assumption is correct, I do not see why the orginal patch from Wang 
Zhou is wrong. 
The only point can be that assigning pp->root_bus_nr = 0 is not required 
as pp memory is kzalloc'ed (an therefore init to zero).


> 
> >
> > In general I agree with you but if you look at all the current
> drivers
> > based on designware none of them define the "bus-range" dtb property.
> > Therefore doing as you say would break the current driver when we
> have
> > multiple controllers...am I right?
> >
> The current _code_ works fine for multiple controllers. It's just that
> you must define the bus range property in the DTB if you want to enable
> multiple instances of one controller and support a kernel without PCI
> domains support. As all current implementations have only a single
> instance of the controller per SoC, or depend on PCI domain support,
> it's totally fine for them to not define the bus ranges property, as
> it's an optional property and it is well defined how things behave if
> it
> is absent. We absolutely need to keep that specified behavior.
> 
> > If that is the case in order to fix this in the way you say I would
> need
> > to assign "bus-range" for all the PCIe drivers with multiple
> controllers:
> > in this case I would split the default range evenly (that is, if we
> have
> > two controllers I would define "bus-range"  0-127 and 128-255)
> >
> > If you think this solution is ok I can go for it. My only doubt was
> about
> > touching other vendors DTBs....
> >
> You don't need to touch any of the current DTBs, as they are fine with
> the default bus range behavior. You need to keep the specified behavior
> of the bus range property with the new code.
> 
> Regards,
> Lucas
> >
> > >
> > > It is perfectly valid to have a bus range of 0x00-0x10 assigned to
> one
> > > instance and 0x50-0xff to the next instance. Additional with PCIe
> > > hotplug you may not use the full range of the bus numbers on one
> > > instance at the first scan, but only later populate more buses when
> > > more
> > > bridges are added to the tree.
> > >
> > > > Drivers that do not specify the bus range in the DTB set pp-
> > > >root_bus_nr = DW_ROOT_NR_UNDEFINED.
> > > > Designware will check if the flag is set and will use the
> automatic
> > > bus range
> > > > assignment.
> > >
> > > No, please lets get rid of this assignment altogether. The glue
> drivers
> > > have no business in assigning the bus range. Please remove the
> > > pp->root_bus_nr assignment from all the glue drivers.
> > >
> > > "bus range" is a generic DW PCIe property, so just parse the root
> bus
> > > number from the DT, it is handled the same way for all the DW based
> > > PCIe
> > > drivers. The bindings specifies that if the bus range property is
> > > missing the range is 0x00-0xff, so you can default to 0 as the root
> bus
> > > number in that case.
> > >
> > > Also I would think this conversion warrants a patch on its own and
> > > should not be mixed in the ARM64 support patch.
> > >
> > > Regards,
> > > Lucas
> > >
> 
> --
> Pengutronix e.K.             | Lucas Stach                 |
> Industrial Linux Solutions   | http://www.pengutronix.de/  |


From festevam at gmail.com  Thu Aug 20 04:13:30 2015
From: festevam at gmail.com (Fabio Estevam)
Date: Thu, 20 Aug 2015 08:13:30 -0300
Subject: [PATCH] Revert "serial: imx: remove unbalanced clk_prepare"
In-Reply-To: <20150818233356.GA4494@localhost.localdomain>
References: <1439912592-14779-1-git-send-email-fabio.estevam@freescale.com>
 <20150818233356.GA4494@localhost.localdomain>
Message-ID: <CAOMZO5Czxr5TTtsrbRyD6N1a89AkeVSyam9Wo5tFxWkyE2iMfQ@mail.gmail.com>

On Tue, Aug 18, 2015 at 8:33 PM, Eduardo Valentin <edubezval at gmail.com> wrote:

> hmmm.. I really did not see this one. Looking at the code looks like we
> could be atomic in some of the uart console callbacks.
>
> For this one:
>
> Reviewed-by: Eduardo Valentin <edubezval at gmail.com>
>
> Did you try the runtime pm patch on your end?

I have only tested linux-next.


From pankaj.dubey at samsung.com  Thu Aug 20 04:34:46 2015
From: pankaj.dubey at samsung.com (Pankaj Dubey)
Date: Thu, 20 Aug 2015 17:04:46 +0530
Subject: [PATCH 1/5] drivers: soc: add support for exynos SROM driver
In-Reply-To: <5565AFE6.5030106@samsung.com>
References: <1430296712-10287-1-git-send-email-pankaj.dubey@samsung.com>
 <1430296712-10287-2-git-send-email-pankaj.dubey@samsung.com>
 <5565AFE6.5030106@samsung.com>
Message-ID: <55D5BB56.1030405@samsung.com>

Hi Krzysztof,

Sorry for delay in reply, as I got busy in some other official 
assignments and could not take this series further at that time.

On Wednesday 27 May 2015 05:22 PM, Krzysztof Kozlowski wrote:
> W dniu 29.04.2015 o 17:38, Pankaj Dubey pisze:
>> This patch adds Exynos SROM controller driver which will handle
>> save restore of SROM registers during S2R.
>>
>> Change-Id: Iaddaaebc1d7090c9889e948e68e886519562c43c
>
> Please remove it.

Will do it.

>
>> Signed-off-by: Pankaj Dubey <pankaj.dubey at samsung.com>
>> ---
>>   drivers/soc/Kconfig               |   1 +
>>   drivers/soc/Makefile              |   1 +
>>   drivers/soc/samsung/Kconfig       |  14 ++++
>>   drivers/soc/samsung/Makefile      |   1 +
>>   drivers/soc/samsung/exynos-srom.c | 142 ++++++++++++++++++++++++++++++++++++++
>>   drivers/soc/samsung/exynos-srom.h |  51 ++++++++++++++
>>   6 files changed, 210 insertions(+)
>>   create mode 100644 drivers/soc/samsung/Kconfig
>>   create mode 100644 drivers/soc/samsung/Makefile
>>   create mode 100644 drivers/soc/samsung/exynos-srom.c
>>   create mode 100644 drivers/soc/samsung/exynos-srom.h
>>
>> diff --git a/drivers/soc/Kconfig b/drivers/soc/Kconfig
>> index 76d6bd4..c3abfbe 100644
>> --- a/drivers/soc/Kconfig
>> +++ b/drivers/soc/Kconfig
>> @@ -1,6 +1,7 @@
>>   menu "SOC (System On Chip) specific Drivers"
>>
>>   source "drivers/soc/qcom/Kconfig"
>> +source "drivers/soc/samsung/Kconfig"
>>   source "drivers/soc/ti/Kconfig"
>>   source "drivers/soc/versatile/Kconfig"
>>
>> diff --git a/drivers/soc/Makefile b/drivers/soc/Makefile
>> index 063113d..620366f 100644
>> --- a/drivers/soc/Makefile
>> +++ b/drivers/soc/Makefile
>> @@ -3,6 +3,7 @@
>>   #
>>
>>   obj-$(CONFIG_ARCH_QCOM)		+= qcom/
>> +obj-$(CONFIG_SOC_SAMSUNG)	+= samsung/
>>   obj-$(CONFIG_ARCH_TEGRA)	+= tegra/
>>   obj-$(CONFIG_SOC_TI)		+= ti/
>>   obj-$(CONFIG_PLAT_VERSATILE)	+= versatile/
>> diff --git a/drivers/soc/samsung/Kconfig b/drivers/soc/samsung/Kconfig
>> new file mode 100644
>> index 0000000..b6fa4e6
>> --- /dev/null
>> +++ b/drivers/soc/samsung/Kconfig
>> @@ -0,0 +1,14 @@
>> +#
>> +# SAMSUNG SoC drivers
>> +#
>> +menu "Samsung SOC driver support"
>> +
>> +config SOC_SAMSUNG
>> +	bool
>
> Any reason for not using menuconfig?
>

For one of my Exynos PMU patchset [1] this suggestion came from Russel 
King, not to use user-visible sysmbol if not required.
[1]: 
http://lists.infradead.org/pipermail/linux-arm-kernel/2014-November/304451.html

>> +
>> +config EXYNOS_SROM
>> +	bool
>> +	depends on ARM && ARCH_EXYNOS
>> +	select SOC_BUS
>
> Why we need to select SOC_BUS?
>

We do not need it, will modify.

>> +
>> +endmenu
>> diff --git a/drivers/soc/samsung/Makefile b/drivers/soc/samsung/Makefile
>> new file mode 100644
>> index 0000000..9c554d5
>> --- /dev/null
>> +++ b/drivers/soc/samsung/Makefile
>> @@ -0,0 +1 @@
>> +obj-$(CONFIG_EXYNOS_SROM)	+= exynos-srom.o
>> diff --git a/drivers/soc/samsung/exynos-srom.c b/drivers/soc/samsung/exynos-srom.c
>> new file mode 100644
>> index 0000000..8aae762
>> --- /dev/null
>> +++ b/drivers/soc/samsung/exynos-srom.c
>> @@ -0,0 +1,142 @@
>> +/*
>> + * Copyright (c) 2015 Samsung Electronics Co., Ltd.
>> + *	      http://www.samsung.com/
>> + *
>> + * EXYNOS - SROM Controller support
>> + * Author: Pankaj Dubey <pankaj.dubey at samsung.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.
>> + */
>> +
>> +#include <linux/io.h>
>> +#include <linux/of.h>
>> +#include <linux/of_address.h>
>> +#include <linux/of_platform.h>
>> +#include <linux/platform_device.h>
>> +#include <linux/slab.h>
>> +#include "exynos-srom.h"
>> +
>> +static void __iomem *exynos_srom_base;
>> +
>> +static unsigned long exynos_srom_offsets[] = {
>
> static const
>
>> +	/* SROM side */
>> +	S5P_SROM_BW,
>> +	S5P_SROM_BC0,
>> +	S5P_SROM_BC1,
>> +	S5P_SROM_BC2,
>> +	S5P_SROM_BC3,
>> +};
>> +
>> +/**
>> + * struct exynos_srom_reg_dump: register dump of SROM Controller registers.
>> + * @offset: srom register offset from the controller base address.
>> + * @value: the value to be register at offset.
>
> Maybe:
> @value: the value of register under the offset
>

OK.

>> + */
>> +struct exynos_srom_reg_dump {
>> +	u32     offset;
>> +	u32     value;
>> +};
>> +
>> +static struct exynos_srom_reg_dump *exynos_srom_regs;
>> +
>> +static struct exynos_srom_reg_dump *exynos_srom_alloc_reg_dump(
>> +		const unsigned long *rdump,
>> +		unsigned long nr_rdump)
>> +{
>> +	struct exynos_srom_reg_dump *rd;
>> +	unsigned int i;
>> +
>> +	rd = kcalloc(nr_rdump, sizeof(*rd), GFP_KERNEL);
>> +	if (!rd)
>> +		return NULL;
>> +
>> +	for (i = 0; i < nr_rdump; ++i)
>> +		rd[i].offset = rdump[i];
>> +
>> +	return rd;
>> +}
>> +
>> +static void exynos_srom_save(void __iomem *base,
>> +				    struct exynos_srom_reg_dump *rd,
>> +				    unsigned int num_regs)
>> +{
>> +	for (; num_regs > 0; --num_regs, ++rd)
>> +		rd->value = readl(base + rd->offset);
>> +
>> +}
>> +
>> +static void exynos_srom_restore(void __iomem *base,
>> +				      const struct exynos_srom_reg_dump *rd,
>> +				      unsigned int num_regs)
>> +{
>> +	for (; num_regs > 0; --num_regs, ++rd)
>> +		writel(rd->value, base + rd->offset);
>> +
>> +}
>> +
>> +static const struct of_device_id of_exynos_srom_ids[] = {
>> +	{
>> +		.compatible	= "samsung,exynos-srom",
>> +	},
>> +	{},
>> +};
>> +
>> +static int exynos_srom_probe(struct platform_device *pdev)
>> +{
>> +	struct device_node *np;
>> +	struct device *dev = &pdev->dev;
>> +
>> +	np = dev->of_node;
>> +	exynos_srom_base = of_iomap(np, 0);
>> +
>> +	if (!exynos_srom_base)
>> +		return PTR_ERR(exynos_srom_base);
>
> This looks wrong. If this is NULL, do not convert it to ERR. What will
> be the value of PTR_ERR(NULL)?
>

Ok will handle it properly.

>> +
>> +	exynos_srom_regs = exynos_srom_alloc_reg_dump(exynos_srom_offsets,
>> +			sizeof(exynos_srom_offsets));
>
> if (NULL) then what? Have you tested the error paths in the probe?
>

I have not tested this for error path, will take care.

>> +
>> +	return 0;
>> +}
>> +
>> +#ifdef CONFIG_PM_SLEEP
>> +static int exynos_srom_suspend(struct device *dev)
>> +{
>> +	exynos_srom_save(exynos_srom_base, exynos_srom_regs,
>> +				ARRAY_SIZE(exynos_srom_offsets));
>> +
>> +	return 0;
>> +}
>> +
>> +static int exynos_srom_resume(struct device *dev)
>> +{
>> +	exynos_srom_restore(exynos_srom_base, exynos_srom_regs,
>> +				ARRAY_SIZE(exynos_srom_offsets));
>> +
>> +	return 0;
>> +}
>> +
>> +static const struct dev_pm_ops exynos_srom_dev_pm_ops = {
>> +	SET_SYSTEM_SLEEP_PM_OPS(exynos_srom_suspend, exynos_srom_resume)
>> +};
>> +
>> +#define DEV_PM_OPS	(&exynos_srom_dev_pm_ops)
>> +#else
>> +#define DEV_PM_OPS	NULL
>> +#endif /* CONFIG_PM_SLEEP */
>
> That look like an old code. Please use SIMPLE_DEV_PM_OPS unless there is
> a reason not to.
>

Thanks for suggestion, will update accordingly.

>> +
>> +static struct platform_driver exynos_srom_driver = {
>> +	.probe = exynos_srom_probe,
>> +	.driver = {
>> +		.name = "exynos-srom",
>> +		.of_match_table = of_exynos_srom_ids,
>> +		.pm = DEV_PM_OPS,
>> +	},
>> +};
>> +
>> +static int __init exynos_srom_init(void)
>> +{
>> +	return platform_driver_register(&exynos_srom_driver);
>> +}
>> +device_initcall(exynos_srom_init);
>> diff --git a/drivers/soc/samsung/exynos-srom.h b/drivers/soc/samsung/exynos-srom.h
>> new file mode 100644
>> index 0000000..e6ee438
>> --- /dev/null
>> +++ b/drivers/soc/samsung/exynos-srom.h
>> @@ -0,0 +1,51 @@
>> +/*
>> + * Copyright (c) 2015 Samsung Electronics Co., Ltd.
>> + *		http://www.samsung.com
>> + *
>> + * Exynos SROMC register definitions
>> + *
>> + * 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.
>> +*/
>> +
>> +#ifndef __SAMSUNG_REGS_SROM_H
>> +#define __SAMSUNG_REGS_SROM_H __FILE__
>
> The double-inclusion protection looks different than file path and name.
> Please make it similar.
>

OK.

>> +#define S5P_SROMREG(x)		(x)
>> +
>> +#define S5P_SROM_BW		S5P_SROMREG(0x0)
>> +#define S5P_SROM_BC0		S5P_SROMREG(0x4)
>> +#define S5P_SROM_BC1		S5P_SROMREG(0x8)
>> +#define S5P_SROM_BC2		S5P_SROMREG(0xc)
>> +#define S5P_SROM_BC3		S5P_SROMREG(0x10)
>> +#define S5P_SROM_BC4		S5P_SROMREG(0x14)
>> +#define S5P_SROM_BC5		S5P_SROMREG(0x18)
>> +
>> +/* one register BW holds 4 x 4-bit packed settings for NCS0 - NCS3 */
>> +
>> +#define S5P_SROM_BW__DATAWIDTH__SHIFT		0
>> +#define S5P_SROM_BW__ADDRMODE__SHIFT		1
>> +#define S5P_SROM_BW__WAITENABLE__SHIFT		2
>> +#define S5P_SROM_BW__BYTEENABLE__SHIFT		3
>> +
>> +#define S5P_SROM_BW__CS_MASK			0xf
>> +
>> +#define S5P_SROM_BW__NCS0__SHIFT		0
>> +#define S5P_SROM_BW__NCS1__SHIFT		4
>> +#define S5P_SROM_BW__NCS2__SHIFT		8
>> +#define S5P_SROM_BW__NCS3__SHIFT		12
>> +#define S5P_SROM_BW__NCS4__SHIFT		16
>> +#define S5P_SROM_BW__NCS5__SHIFT		20
>> +
>> +/* applies to same to BCS0 - BCS3 */
>> +
>> +#define S5P_SROM_BCX__PMC__SHIFT		0
>> +#define S5P_SROM_BCX__TACP__SHIFT		4
>> +#define S5P_SROM_BCX__TCAH__SHIFT		8
>> +#define S5P_SROM_BCX__TCOH__SHIFT		12
>> +#define S5P_SROM_BCX__TACC__SHIFT		16
>> +#define S5P_SROM_BCX__TCOS__SHIFT		24
>> +#define S5P_SROM_BCX__TACS__SHIFT		28
>
> s/S5P/EXYNOS/
>
OK.

Thanks,
Pankaj Dubey

>> +
>> +#endif /* __SAMSUNG_REGS_SROM_H */
>>
>
>


From michal.simek at xilinx.com  Thu Aug 20 04:35:58 2015
From: michal.simek at xilinx.com (Michal Simek)
Date: Thu, 20 Aug 2015 13:35:58 +0200
Subject: [PATCH v5 1/5] arm/arm64: add smccc ARCH32
In-Reply-To: <20150819165009.GC10297@arm.com>
References: <1439973629-19505-1-git-send-email-jens.wiklander@linaro.org>
 <1439973629-19505-2-git-send-email-jens.wiklander@linaro.org>
 <20150819165009.GC10297@arm.com>
Message-ID: <55D5BB9E.3020304@xilinx.com>

On 08/19/2015 06:50 PM, Will Deacon wrote:
> On Wed, Aug 19, 2015 at 09:40:25AM +0100, Jens Wiklander wrote:
>> Adds helpers to do SMC based on ARM SMC Calling Convention.
>> CONFIG_HAVE_SMCCC is enabled for architectures that may support
>> the SMC instruction. It's the responsibility of the caller to
>> know if the SMC instruction is supported by the platform.
> 
> [...]
>> diff --git a/arch/arm64/kernel/smccc-call.S b/arch/arm64/kernel/smccc-call.S
>> new file mode 100644
>> index 0000000..3ce7fe8
>> --- /dev/null
>> +++ b/arch/arm64/kernel/smccc-call.S
>> @@ -0,0 +1,34 @@
>> +/*
>> + * Copyright (c) 2015, Linaro Limited
>> + *
>> + * 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/linkage.h>
>> +
>> +#define SMC_PARAM_W0_OFFS      0
>> +#define SMC_PARAM_W2_OFFS      8
>> +#define SMC_PARAM_W4_OFFS      16
>> +#define SMC_PARAM_W6_OFFS      24
>> +
>> +/* void smccc_call32(struct smccc_param32 *param) */
>> +ENTRY(smccc_call32)
>> +       stp     x28, x30, [sp, #-16]!
> 
> Why are you saving lr?
> 
>> +       mov     x28, x0
>> +       ldp     w0, w1, [x28, #SMC_PARAM_W0_OFFS]
>> +       ldp     w2, w3, [x28, #SMC_PARAM_W2_OFFS]
>> +       ldp     w4, w5, [x28, #SMC_PARAM_W4_OFFS]
>> +       ldp     w6, w7, [x28, #SMC_PARAM_W6_OFFS]
>> +       smc     #0
>> +       stp     w0, w1, [x28, #SMC_PARAM_W0_OFFS]
>> +       stp     w2, w3, [x28, #SMC_PARAM_W2_OFFS]
>> +       ldp     x28, x30, [sp], #16
>> +       ret
>> +ENDPROC(smccc_call32)
> 
> Could we deal with this like we do for PSCI instead? (see
> __invoke_psci_fn_smc). We could also then rename psci-call.S to fw-call.S
> and stick this in there too.

I think that make sense to make smc, hvc calling more generic. Remove
psci name from __invoke_psci_fn_smc and just use it in other drivers.

Thanks,
Michal



From pankaj.dubey at samsung.com  Thu Aug 20 04:36:49 2015
From: pankaj.dubey at samsung.com (Pankaj Dubey)
Date: Thu, 20 Aug 2015 17:06:49 +0530
Subject: [PATCH 2/5] ARM: EXYNOS: Remove SROM related register settings
 from mach-exynos
In-Reply-To: <5565B0D1.80004@samsung.com>
References: <1430296712-10287-1-git-send-email-pankaj.dubey@samsung.com>
 <1430296712-10287-3-git-send-email-pankaj.dubey@samsung.com>
 <5565B0D1.80004@samsung.com>
Message-ID: <55D5BBD1.1030905@samsung.com>

Hi Krzysztof,

On Wednesday 27 May 2015 05:26 PM, Krzysztof Kozlowski wrote:
> W dniu 29.04.2015 o 17:38, Pankaj Dubey pisze:
>> As now we have dedicated driver for SROM controller, it will take care
>> of saving register banks during S2R so we can safely remove these
>> settings from mach-exynos.
>>
>> Signed-off-by: Pankaj Dubey <pankaj.dubey at samsung.com>
>> ---
>>   arch/arm/mach-exynos/Kconfig                   |  2 +
>>   arch/arm/mach-exynos/exynos.c                  | 10 -----
>>   arch/arm/mach-exynos/include/mach/map.h        |  3 --
>>   arch/arm/mach-exynos/suspend.c                 | 20 +---------
>>   arch/arm/plat-samsung/include/plat/map-s5p.h   |  1 -
>>   arch/arm/plat-samsung/include/plat/regs-srom.h | 54 --------------------------
>>   6 files changed, 4 insertions(+), 86 deletions(-)
>>   delete mode 100644 arch/arm/plat-samsung/include/plat/regs-srom.h
>>
>> diff --git a/arch/arm/mach-exynos/Kconfig b/arch/arm/mach-exynos/Kconfig
>> index 603820e..e842b23 100644
>> --- a/arch/arm/mach-exynos/Kconfig
>> +++ b/arch/arm/mach-exynos/Kconfig
>> @@ -25,6 +25,8 @@ menuconfig ARCH_EXYNOS
>>   	select S5P_DEV_MFC
>>   	select SRAM
>>   	select MFD_SYSCON
>> +	select SOC_SAMSUNG
>> +	select EXYNOS_SROM
>
> What about the difference of execution time? The suspend/resume of
> device may not be called in the same time as previous syscore ops. Does
> this have any impact?
>


I had tested it for S2R at that time on SMDK5250 board and it was fine. 
I do not noticed any issue in S2R, so I feel timing should not have any 
impact.

Thanks,
Pankaj Dubey

> Best regards,
> Krzysztof
>
>


From jens.wiklander at linaro.org  Thu Aug 20 04:37:29 2015
From: jens.wiklander at linaro.org (Jens Wiklander)
Date: Thu, 20 Aug 2015 13:37:29 +0200
Subject: [PATCH v5 1/5] arm/arm64: add smccc ARCH32
In-Reply-To: <20150819165009.GC10297@arm.com>
References: <1439973629-19505-1-git-send-email-jens.wiklander@linaro.org>
 <1439973629-19505-2-git-send-email-jens.wiklander@linaro.org>
 <20150819165009.GC10297@arm.com>
Message-ID: <20150820113729.GA25962@ermac>

On Wed, Aug 19, 2015 at 05:50:09PM +0100, Will Deacon wrote:
> On Wed, Aug 19, 2015 at 09:40:25AM +0100, Jens Wiklander wrote:
> > Adds helpers to do SMC based on ARM SMC Calling Convention.
> > CONFIG_HAVE_SMCCC is enabled for architectures that may support
> > the SMC instruction. It's the responsibility of the caller to
> > know if the SMC instruction is supported by the platform.
> 
> [...]
> > diff --git a/arch/arm64/kernel/smccc-call.S b/arch/arm64/kernel/smccc-call.S
> > new file mode 100644
> > index 0000000..3ce7fe8
> > --- /dev/null
> > +++ b/arch/arm64/kernel/smccc-call.S
> > @@ -0,0 +1,34 @@
> > +/*
> > + * Copyright (c) 2015, Linaro Limited
> > + *
> > + * 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/linkage.h>
> > +
> > +#define SMC_PARAM_W0_OFFS      0
> > +#define SMC_PARAM_W2_OFFS      8
> > +#define SMC_PARAM_W4_OFFS      16
> > +#define SMC_PARAM_W6_OFFS      24
> > +
> > +/* void smccc_call32(struct smccc_param32 *param) */
> > +ENTRY(smccc_call32)
> > +       stp     x28, x30, [sp, #-16]!
> 
> Why are you saving lr?

Agree, no point in saving lr, but I still need to decrease sp with 16 to
maintain correct alignment. I'll do it with an str instruction instead.

> 
> > +       mov     x28, x0
> > +       ldp     w0, w1, [x28, #SMC_PARAM_W0_OFFS]
> > +       ldp     w2, w3, [x28, #SMC_PARAM_W2_OFFS]
> > +       ldp     w4, w5, [x28, #SMC_PARAM_W4_OFFS]
> > +       ldp     w6, w7, [x28, #SMC_PARAM_W6_OFFS]
> > +       smc     #0
> > +       stp     w0, w1, [x28, #SMC_PARAM_W0_OFFS]
> > +       stp     w2, w3, [x28, #SMC_PARAM_W2_OFFS]
> > +       ldp     x28, x30, [sp], #16
> > +       ret
> > +ENDPROC(smccc_call32)
> 
> Could we deal with this like we do for PSCI instead? (see
> __invoke_psci_fn_smc). We could also then rename psci-call.S to fw-call.S
> and stick this in there too.

I assume you're referring to when to use "hvc" and "smc".

I would rather consider smccc_call32() a primitive function that a
driver may use if it's configured to do so, for instance via DT. When an
"hvc" should be used instead of an "smc" up to the driver to decide
based how it's configured.

When merging psci-call.S and smccc-call.S into fw-call.S, what should I
do about smccc.c? I need to export the smccc_call32 function somewhere
as it could be used from a loadable module.

--
Thanks,
Jens


From pankaj.dubey at samsung.com  Thu Aug 20 04:37:47 2015
From: pankaj.dubey at samsung.com (Pankaj Dubey)
Date: Thu, 20 Aug 2015 17:07:47 +0530
Subject: [PATCH 3/5] ARM: EXYNOS: DTS: add SROM device node for exynos4
In-Reply-To: <5565B24F.9060601@samsung.com>
References: <1430296712-10287-1-git-send-email-pankaj.dubey@samsung.com>
 <1430296712-10287-4-git-send-email-pankaj.dubey@samsung.com>
 <5565B24F.9060601@samsung.com>
Message-ID: <55D5BC0B.2010203@samsung.com>

Hi,


On Wednesday 27 May 2015 05:32 PM, Krzysztof Kozlowski wrote:
> W dniu 29.04.2015 o 17:38, Pankaj Dubey pisze:
>> Add SROM device node for exynos4.
>
> Subject prefix: "ARM: dts:"
>
Ok.
>>
>> CC: Rob Herring <robh+dt at kernel.org>
>> CC: Mark Rutland <mark.rutland at arm.com>
>> CC: Ian Campbell <ijc+devicetree at hellion.org.uk>
>> Signed-off-by: Pankaj Dubey <pankaj.dubey at 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 77ea547..48490ea 100644
>> --- a/arch/arm/boot/dts/exynos4.dtsi
>> +++ b/arch/arm/boot/dts/exynos4.dtsi
>> @@ -76,6 +76,11 @@
>>   		reg = <0x10000000 0x100>;
>>   	};
>>
>> +	sromc at 12570000 {
>> +		compatible = "samsung,exynos-srom";
>> +		reg = <0x12570000 0x100>;
>
> There are 5 registers, so size of 0x100 seems to be bigger than needed.
> Maybe limit it to actual length?
>
Yes, we do not need size of 0x100. Will take care in next version.

Thanks,
Pankaj Dubey

> Best regards,
> Krzysztof
>


From pankaj.dubey at samsung.com  Thu Aug 20 04:39:45 2015
From: pankaj.dubey at samsung.com (Pankaj Dubey)
Date: Thu, 20 Aug 2015 17:09:45 +0530
Subject: [PATCH 5/5] Documentation: dt-bindings: add exynos-srom binding
 information
In-Reply-To: <CAJKOXPfpu+k-3u3kFzeKL4b9bkh+iwWHak2ea+9QLtGUEZGWdA@mail.gmail.com>
References: <1430296712-10287-1-git-send-email-pankaj.dubey@samsung.com>
 <1430296712-10287-6-git-send-email-pankaj.dubey@samsung.com>
 <CAJKOXPfpu+k-3u3kFzeKL4b9bkh+iwWHak2ea+9QLtGUEZGWdA@mail.gmail.com>
Message-ID: <55D5BC81.9050304@samsung.com>

Hi Krzysztof,

On Wednesday 27 May 2015 04:51 PM, Krzysztof Kozlowski wrote:
> 2015-04-29 17:38 GMT+09:00 Pankaj Dubey <pankaj.dubey at samsung.com>:
>> This patch adds exynos-srom binding information for SROM Controller
>> driver on Exynos SoCs.
>>
>> CC: Rob Herring <robh+dt at kernel.org>
>> CC: Mark Rutland <mark.rutland at arm.com>
>> CC: Ian Campbell <ijc+devicetree at hellion.org.uk>
>> Signed-off-by: Pankaj Dubey <pankaj.dubey at samsung.com>
>> ---
>>   .../devicetree/bindings/arm/samsung/exynos-srom.txt          | 12 ++++++++++++
>>   1 file changed, 12 insertions(+)
>>   create mode 100644 Documentation/devicetree/bindings/arm/samsung/exynos-srom.txt
>>
>> diff --git a/Documentation/devicetree/bindings/arm/samsung/exynos-srom.txt b/Documentation/devicetree/bindings/arm/samsung/exynos-srom.txt
>> new file mode 100644
>> index 0000000..482d1cd
>> --- /dev/null
>> +++ b/Documentation/devicetree/bindings/arm/samsung/exynos-srom.txt
>> @@ -0,0 +1,12 @@
>> +SAMSUNG Exynos SoCs SROM Controller driver.
>> +
>> +Required properties:
>> +- compatible : Should at least contain "samsung,exynos-srom".
>
> "At least" - do you already expect other compatibles?
>

Nope, as of now I do not expect any other compatible, so I will change 
this to "Should contain "samsung,exynos-srom"."

Thanks,
Pankaj Dubey
> Best regards,
> Krzysztof
>


From ard.biesheuvel at linaro.org  Thu Aug 20 04:54:40 2015
From: ard.biesheuvel at linaro.org (Ard Biesheuvel)
Date: Thu, 20 Aug 2015 13:54:40 +0200
Subject: [PATCH 2/2] arm64: set MAX_MEMBLOCK_ADDR according to linear
 region size
In-Reply-To: <20150820091915.GC2972@e104818-lin.cambridge.arm.com>
References: <1439890482-20798-1-git-send-email-ard.biesheuvel@linaro.org>
 <1439890482-20798-3-git-send-email-ard.biesheuvel@linaro.org>
 <20150820091915.GC2972@e104818-lin.cambridge.arm.com>
Message-ID: <E830F411-141C-40C4-A608-7709304395C5@linaro.org>



> On 20 aug. 2015, at 11:19, Catalin Marinas <catalin.marinas at arm.com> wrote:
> 
>> On Tue, Aug 18, 2015 at 11:34:42AM +0200, Ard Biesheuvel wrote:
>> The linear region size of a 39-bit VA kernel is only 256 GB, which
>> may be insufficient to cover all of system RAM, even on platforms
>> that have much less than 256 GB of memory but which is laid out
>> very sparsely.
>> 
>> So make sure we clip the memory we will not be able to map before
>> installing it into the memblock memory table, by setting
>> MAX_MEMBLOCK_ADDR accordingly.
>> 
>> Signed-off-by: Ard Biesheuvel <ard.biesheuvel at linaro.org>
>> ---
>> arch/arm64/include/asm/memory.h | 8 ++++++++
>> 1 file changed, 8 insertions(+)
>> 
>> diff --git a/arch/arm64/include/asm/memory.h b/arch/arm64/include/asm/memory.h
>> index f800d45ea226..44a59c20e773 100644
>> --- a/arch/arm64/include/asm/memory.h
>> +++ b/arch/arm64/include/asm/memory.h
>> @@ -114,6 +114,14 @@ extern phys_addr_t        memstart_addr;
>> #define PHYS_OFFSET        ({ memstart_addr; })
>> 
>> /*
>> + * The maximum physical address that the linear direct mapping
>> + * of system RAM can cover. (PAGE_OFFSET can be interpreted as
>> + * a 2's complement signed quantity and negated to derive the
>> + * maximum size of the linear mapping.)
>> + */
>> +#define MAX_MEMBLOCK_ADDR    ({ memstart_addr - PAGE_OFFSET - 1; })
> 
> Would it be easier to understand as just memstart_addr + ~PAGE_OFFSET?
> 

Whichever you prefer

> Otherwise:
> 
> Reviewed-by: Catalin Marinas <catalin.marinas at arm.com>

Thanks

From danindrey at mail.ru  Thu Aug 20 05:14:34 2015
From: danindrey at mail.ru (Andrey Danin)
Date: Thu, 20 Aug 2015 15:14:34 +0300
Subject: [PATCH v3 1/4] i2c: tegra: implement slave mode
In-Reply-To: <20150724105251.GA22787@katana>
References: <1437424546-30405-1-git-send-email-danindrey@mail.ru>
 <1437424546-30405-2-git-send-email-danindrey@mail.ru>
 <20150724092720.GA1597@katana> <55B210F4.6030700@mail.ru>
 <20150724105251.GA22787@katana>
Message-ID: <55D5C4AA.2000307@mail.ru>

On 24.07.2015 13:52, Wolfram Sang wrote:
>
>> At the begin of my work on this patchset I even denied clock disable call if
>> slave is registered (to minimize code that can affect transfer).
>
> I hacked something like this, but it seems it was not enough.
>
>> If only slave mode is used, then this logic is not needed.
>
> This is not sufficent. We shouldn't break being a master only because we
> also listen to a slave address (as long as the HW supports that of
> course).
>
>> tegra_i2c_init is called on probe and resume. Also it is called in case of
>> xfer fail. If xfer is ok, then I think slave addr must be kept unchanged.
>
> This is fragile. Try scanning the bus with i2cdetect and slave setup
> will be gone.
>
>> As far as I understand it is a loopback mode. Probably it will not work
>> (Stephen Warren already mentioned this).
>
> Just to make clear: I am not saying we should support talking to our own
> slave address. But it should still be possible to communicate with other
> remote devices on the bus.

Sorry for the long delay. I tried to analyze the issue. Attached patch 
works on AC100 (Misha Komarovsky helped me with testing).

Wolfram could you please try the patch with your environment?


Thanks.

-------------- next part --------------
>From 0927b4007786b19e51415c4900863dd4e74fa034 Mon Sep 17 00:00:00 2001
From: Andrey Danin <danindrey at mail.ru>
Date: Thu, 20 Aug 2015 00:41:39 +0300
Subject: [PATCH] i2c: tegra: don't reset I2C slave address on init

Init function is called multuple times. If I2C controller works
in slave mode, then driver must keep slave registers otherwise
slave configuration will be reseted.

Signed-off-by: Andrey Danin <danindrey at mail.ru>
---
 drivers/i2c/busses/i2c-tegra.c |   42 +++++++++++++++++++++++++--------------
 1 files changed, 27 insertions(+), 15 deletions(-)

diff --git a/drivers/i2c/busses/i2c-tegra.c b/drivers/i2c/busses/i2c-tegra.c
index 6467ce0..50250a1 100644
--- a/drivers/i2c/busses/i2c-tegra.c
+++ b/drivers/i2c/busses/i2c-tegra.c
@@ -402,6 +402,22 @@ static void tegra_dvc_init(struct tegra_i2c_dev *i2c_dev)
 	dvc_writel(i2c_dev, val, DVC_CTRL_REG1);
 }
 
+static int tegra_i2c_init_slave(struct tegra_i2c_dev *i2c_dev, u32 addr, u32 flags)
+{
+	int addr2 = 0;
+
+	i2c_writel(i2c_dev, I2C_SL_CNFG_NEWSL, I2C_SL_CNFG);
+	i2c_writel(i2c_dev, I2C_SL_DELAY_COUNT_DEFAULT, I2C_SL_DELAY_COUNT);
+
+	if (flags & I2C_CLIENT_TEN)
+		addr2 = (addr >> 7) | I2C_SL_ADDR2_TEN_BIT_MODE;
+
+	i2c_writel(i2c_dev, addr, I2C_SL_ADDR1);
+	i2c_writel(i2c_dev, addr2, I2C_SL_ADDR2);
+
+	return 0;
+}
+
 static inline int tegra_i2c_clock_enable(struct tegra_i2c_dev *i2c_dev)
 {
 	int ret;
@@ -461,12 +477,16 @@ static int tegra_i2c_init(struct tegra_i2c_dev *i2c_dev)
 	i2c_writel(i2c_dev, clk_divisor, I2C_CLK_DIVISOR);
 
 	if (!i2c_dev->is_dvc) {
-		u32 sl_cfg = i2c_readl(i2c_dev, I2C_SL_CNFG);
-		sl_cfg |= I2C_SL_CNFG_NACK | I2C_SL_CNFG_NEWSL;
-		i2c_writel(i2c_dev, sl_cfg, I2C_SL_CNFG);
-		i2c_writel(i2c_dev, 0xfc, I2C_SL_ADDR1);
-		i2c_writel(i2c_dev, 0x00, I2C_SL_ADDR2);
-
+		if (i2c_dev->slave) {
+			tegra_i2c_init_slave(i2c_dev, i2c_dev->slave->addr,
+					i2c_dev->slave->flags);
+		} else {
+			u32 sl_cfg = i2c_readl(i2c_dev, I2C_SL_CNFG);
+			sl_cfg |= I2C_SL_CNFG_NACK | I2C_SL_CNFG_NEWSL;
+			i2c_writel(i2c_dev, sl_cfg, I2C_SL_CNFG);
+			i2c_writel(i2c_dev, 0xfc, I2C_SL_ADDR1);
+			i2c_writel(i2c_dev, 0x00, I2C_SL_ADDR2);
+		}
 	}
 
 	val = 7 << I2C_FIFO_CONTROL_TX_TRIG_SHIFT |
@@ -767,7 +787,6 @@ static u32 tegra_i2c_func(struct i2c_adapter *adap)
 static int tegra_reg_slave(struct i2c_client *slave)
 {
 	struct tegra_i2c_dev *i2c_dev = i2c_get_adapdata(slave->adapter);
-	int addr2 = 0;
 
 	if (i2c_dev->slave)
 		return -EBUSY;
@@ -776,14 +795,7 @@ static int tegra_reg_slave(struct i2c_client *slave)
 
 	tegra_i2c_clock_enable(i2c_dev);
 
-	i2c_writel(i2c_dev, I2C_SL_CNFG_NEWSL, I2C_SL_CNFG);
-	i2c_writel(i2c_dev, I2C_SL_DELAY_COUNT_DEFAULT, I2C_SL_DELAY_COUNT);
-
-	if (slave->flags & I2C_CLIENT_TEN)
-		addr2 = (slave->addr >> 7) | I2C_SL_ADDR2_TEN_BIT_MODE;
-
-	i2c_writel(i2c_dev, slave->addr, I2C_SL_ADDR1);
-	i2c_writel(i2c_dev, addr2, I2C_SL_ADDR2);
+	tegra_i2c_init_slave(i2c_dev, slave->addr, slave->flags);
 
 	return 0;
 }
-- 
1.7.1


From varada at codeaurora.org  Thu Aug 20 05:15:41 2015
From: varada at codeaurora.org (Varadarajan Narayanan)
Date: Thu, 20 Aug 2015 17:45:41 +0530
Subject: [PATCH] ARM: Set proper TEXT_OFFSET for IPQ806x
Message-ID: <20150820121541.GA14664@codeaurora.org>

RAM starts at 0x40000000 for IPQ. The lower 21MB of RAM is used
for Shared Memory and the kernel can start from 0x41500000. However,
this cannot be accomodated within the current AUTO_ZRELADDR framework.
If textofs-y is set to 0x01508000, compilation breaks with

	arch/arm/kernel/head.S:181:
		Error: invalid constant (1508000) after fixup

Hence, cannot use Linux's self extractor. Instead, create a compressed
image that will be de-compressed from U-Boot.

Signed-off-by: Varadarajan Narayanan <varada at codeaurora.org>

diff --git a/arch/arm/Makefile b/arch/arm/Makefile
index 07ab3d2..cce8ea6 100644
--- a/arch/arm/Makefile
+++ b/arch/arm/Makefile
@@ -142,6 +142,8 @@ textofs-$(CONFIG_SA1111) := 0x00208000
 endif
 textofs-$(CONFIG_ARCH_MSM8X60) := 0x00208000
 textofs-$(CONFIG_ARCH_MSM8960) := 0x00208000
+textofs-$(CONFIG_ARCH_IPQ8064) := 0x00008000
+
 textofs-$(CONFIG_ARCH_AXXIA) := 0x00308000
 
 # Machine directory name.  This list is sorted alphanumerically
diff --git a/arch/arm/configs/ipq_defconfig b/arch/arm/configs/ipq_defconfig
new file mode 100644
index 0000000..8562a2f
--- /dev/null
+++ b/arch/arm/configs/ipq_defconfig
@@ -0,0 +1,175 @@
+CONFIG_SYSVIPC=y
+CONFIG_NO_HZ=y
+CONFIG_HIGH_RES_TIMERS=y
+CONFIG_IKCONFIG=y
+CONFIG_IKCONFIG_PROC=y
+CONFIG_BLK_DEV_INITRD=y
+CONFIG_SYSCTL_SYSCALL=y
+CONFIG_KALLSYMS_ALL=y
+CONFIG_EMBEDDED=y
+# CONFIG_SLUB_DEBUG is not set
+# CONFIG_COMPAT_BRK is not set
+CONFIG_PROFILING=y
+CONFIG_OPROFILE=y
+CONFIG_KPROBES=y
+CONFIG_MODULES=y
+CONFIG_MODULE_UNLOAD=y
+CONFIG_MODULE_FORCE_UNLOAD=y
+CONFIG_MODVERSIONS=y
+CONFIG_PARTITION_ADVANCED=y
+CONFIG_ARCH_QCOM=y
+CONFIG_ARCH_MSM8X60=y
+CONFIG_ARCH_MSM8960=y
+CONFIG_ARCH_MSM8974=y
+CONFIG_ARCH_IPQ8064=y
+CONFIG_SMP=y
+CONFIG_PREEMPT=y
+CONFIG_AEABI=y
+CONFIG_HIGHMEM=y
+CONFIG_HIGHPTE=y
+CONFIG_CLEANCACHE=y
+CONFIG_ARM_APPENDED_DTB=y
+CONFIG_ARM_ATAG_DTB_COMPAT=y
+CONFIG_CPU_IDLE=y
+CONFIG_ARM_CPUIDLE=y
+CONFIG_VFP=y
+CONFIG_NEON=y
+# CONFIG_CORE_DUMP_DEFAULT_ELF_HEADERS is not set
+CONFIG_NET=y
+CONFIG_PACKET=y
+CONFIG_UNIX=y
+CONFIG_INET=y
+CONFIG_IP_ADVANCED_ROUTER=y
+CONFIG_IP_MULTIPLE_TABLES=y
+CONFIG_IP_ROUTE_VERBOSE=y
+CONFIG_IP_PNP=y
+CONFIG_IP_PNP_DHCP=y
+# CONFIG_INET_XFRM_MODE_TRANSPORT is not set
+# CONFIG_INET_XFRM_MODE_TUNNEL is not set
+# CONFIG_INET_XFRM_MODE_BEET is not set
+# CONFIG_INET_LRO is not set
+# CONFIG_IPV6 is not set
+CONFIG_CFG80211=y
+CONFIG_RFKILL=y
+CONFIG_DEVTMPFS=y
+CONFIG_DEVTMPFS_MOUNT=y
+CONFIG_MTD=y
+CONFIG_MTD_BLOCK=y
+CONFIG_MTD_M25P80=y
+CONFIG_MTD_SPI_NOR=y
+CONFIG_BLK_DEV_LOOP=y
+CONFIG_BLK_DEV_RAM=y
+CONFIG_SCSI=y
+CONFIG_BLK_DEV_SD=y
+CONFIG_CHR_DEV_SG=y
+CONFIG_CHR_DEV_SCH=y
+CONFIG_SCSI_CONSTANTS=y
+CONFIG_SCSI_LOGGING=y
+CONFIG_SCSI_SCAN_ASYNC=y
+CONFIG_NETDEVICES=y
+CONFIG_DUMMY=y
+CONFIG_MDIO_BITBANG=y
+CONFIG_MDIO_GPIO=y
+CONFIG_SLIP=y
+CONFIG_SLIP_COMPRESSED=y
+CONFIG_SLIP_MODE_SLIP6=y
+CONFIG_USB_USBNET=y
+# CONFIG_USB_NET_AX8817X is not set
+# CONFIG_USB_NET_ZAURUS is not set
+CONFIG_INPUT_EVDEV=y
+# CONFIG_KEYBOARD_ATKBD is not set
+# CONFIG_MOUSE_PS2 is not set
+CONFIG_INPUT_JOYSTICK=y
+CONFIG_INPUT_TOUCHSCREEN=y
+CONFIG_INPUT_MISC=y
+CONFIG_INPUT_UINPUT=y
+CONFIG_SERIO_LIBPS2=y
+# CONFIG_LEGACY_PTYS is not set
+CONFIG_SERIAL_MSM=y
+CONFIG_SERIAL_MSM_CONSOLE=y
+CONFIG_HW_RANDOM=y
+CONFIG_I2C=y
+CONFIG_I2C_CHARDEV=y
+CONFIG_I2C_QUP=y
+CONFIG_SPI=y
+CONFIG_SPI_QUP=y
+CONFIG_SPMI=y
+CONFIG_PINCTRL_APQ8064=y
+CONFIG_PINCTRL_APQ8084=y
+CONFIG_PINCTRL_IPQ8064=y
+CONFIG_PINCTRL_MSM8960=y
+CONFIG_PINCTRL_MSM8X74=y
+CONFIG_GPIOLIB=y
+CONFIG_DEBUG_GPIO=y
+CONFIG_GPIO_SYSFS=y
+CONFIG_POWER_RESET=y
+CONFIG_POWER_RESET_MSM=y
+CONFIG_THERMAL=y
+CONFIG_REGULATOR=y
+CONFIG_REGULATOR_FIXED_VOLTAGE=y
+CONFIG_MEDIA_SUPPORT=y
+CONFIG_FB=y
+CONFIG_SOUND=y
+CONFIG_SND=y
+CONFIG_SND_DYNAMIC_MINORS=y
+# CONFIG_SND_ARM is not set
+# CONFIG_SND_SPI is not set
+# CONFIG_SND_USB is not set
+CONFIG_SND_SOC=y
+CONFIG_HID_BATTERY_STRENGTH=y
+CONFIG_USB=y
+CONFIG_USB_ANNOUNCE_NEW_DEVICES=y
+CONFIG_USB_MON=y
+CONFIG_USB_EHCI_HCD=y
+CONFIG_USB_ACM=y
+CONFIG_USB_SERIAL=y
+CONFIG_USB_GADGET=y
+CONFIG_USB_GADGET_DEBUG_FILES=y
+CONFIG_USB_GADGET_VBUS_DRAW=500
+CONFIG_MMC=y
+CONFIG_MMC_BLOCK_MINORS=32
+CONFIG_MMC_ARMMMCI=y
+CONFIG_MMC_SDHCI=y
+CONFIG_MMC_SDHCI_PLTFM=y
+CONFIG_MMC_SDHCI_MSM=y
+CONFIG_RTC_CLASS=y
+CONFIG_DMADEVICES=y
+CONFIG_QCOM_BAM_DMA=y
+CONFIG_STAGING=y
+CONFIG_COMMON_CLK_QCOM=y
+CONFIG_APQ_MMCC_8084=y
+CONFIG_IPQ_LCC_806X=y
+CONFIG_MSM_GCC_8660=y
+CONFIG_MSM_LCC_8960=y
+CONFIG_MSM_MMCC_8960=y
+CONFIG_MSM_MMCC_8974=y
+CONFIG_MSM_IOMMU=y
+CONFIG_QCOM_GSBI=y
+CONFIG_QCOM_PM=y
+CONFIG_PHY_QCOM_APQ8064_SATA=y
+CONFIG_PHY_QCOM_IPQ806X_SATA=y
+CONFIG_EXT2_FS=y
+CONFIG_EXT2_FS_XATTR=y
+CONFIG_EXT3_FS=y
+# CONFIG_EXT3_DEFAULTS_TO_ORDERED is not set
+CONFIG_EXT4_FS=y
+CONFIG_FUSE_FS=y
+CONFIG_VFAT_FS=y
+CONFIG_TMPFS=y
+CONFIG_JFFS2_FS=y
+CONFIG_NFS_FS=y
+CONFIG_NFS_V3_ACL=y
+CONFIG_NFS_V4=y
+CONFIG_CIFS=y
+CONFIG_NLS_CODEPAGE_437=y
+CONFIG_NLS_ASCII=y
+CONFIG_NLS_ISO8859_1=y
+CONFIG_NLS_UTF8=y
+CONFIG_PRINTK_TIME=y
+CONFIG_DYNAMIC_DEBUG=y
+CONFIG_DEBUG_INFO=y
+CONFIG_MAGIC_SYSRQ=y
+CONFIG_LOCKUP_DETECTOR=y
+# CONFIG_DETECT_HUNG_TASK is not set
+# CONFIG_SCHED_DEBUG is not set
+CONFIG_TIMER_STATS=y
diff --git a/arch/arm/mach-qcom/Kconfig b/arch/arm/mach-qcom/Kconfig
index 2256cd1..fab49a2 100644
--- a/arch/arm/mach-qcom/Kconfig
+++ b/arch/arm/mach-qcom/Kconfig
@@ -22,4 +22,8 @@ config ARCH_MSM8974
 	bool "Enable support for MSM8974"
 	select HAVE_ARM_ARCH_TIMER
 
+config ARCH_IPQ8064
+	bool "Enable support for IPQ806x"
+	select CLKSRC_QCOM
+
 endif


From hverkuil at xs4all.nl  Thu Aug 20 05:41:40 2015
From: hverkuil at xs4all.nl (Hans Verkuil)
Date: Thu, 20 Aug 2015 14:41:40 +0200
Subject: [PATCH 0/4] [media] Media entity cleanups and build fixes
In-Reply-To: <1439998526-12832-1-git-send-email-javier@osg.samsung.com>
References: <1439998526-12832-1-git-send-email-javier@osg.samsung.com>
Message-ID: <55D5CB04.50508@xs4all.nl>

On 08/19/15 17:35, Javier Martinez Canillas wrote:
> Hello,
> 
> This series contains a couple of build fixes and cleanups for the
> Media Controller framework. The goal of the series is to get rid of
> the struct media_entity .parent member since now that a media_gobj is
> embedded into entities, the media_gobj .mdev member can be used to
> store a pointer to the parent struct media_device.
> 
> So the .parent field becomes redundant and can be removed after all
> the users are converted to use entity .graph_obj.mdev instead.
> 
> Patches 1/4 and 2/4 are build fixes I found while build testing if no
> regressions were introduced by the conversion. Patch 3/4 converts
> all the drivers and the MC core to use .mdev instead of .parent and
> finally patch 4/4 removes the .parent field since now is unused.

Regarding patches 1 and 2: these should of course be merged with Mauro's
patches that make this particular change (patch 3/8), otherwise it would
break git bisect.

Anyway,

Acked-by: Hans Verkuil <hans.verkuil at cisco.com> for the changes in patch
1 and 2, as long as they are added to Mauro's patch 3/8.

Regards,

	Hans

> 
> The series depend on Mauro's "[PATCH v6 0/8] MC preparation patches
> series" [0].
> 
> The transformation were automated using a coccinelle semantic patch
> and the drivers were build tested using allyesconfig and x-building
> the ARM Exynos and OMAP defconfigs + the needed media config options.
> 
> Best regards,
> Javier
> 
> [0]: http://www.mail-archive.com/linux-media at vger.kernel.org/msg91330.html
> 
> 
> Javier Martinez Canillas (4):
>   [media] staging: omap4iss: get entity ID using media_entity_id()
>   [media] omap3isp: get entity ID using media_entity_id()
>   [media] media: use entity.graph_obj.mdev instead of .parent
>   [media] media: remove media entity .parent field
> 
>  drivers/media/media-device.c                       |  8 ++---
>  drivers/media/media-entity.c                       | 34 ++++++++++++----------
>  drivers/media/platform/exynos4-is/fimc-isp-video.c |  6 ++--
>  drivers/media/platform/exynos4-is/fimc-lite.c      |  8 ++---
>  drivers/media/platform/exynos4-is/media-dev.c      |  2 +-
>  drivers/media/platform/exynos4-is/media-dev.h      |  8 ++---
>  drivers/media/platform/omap3isp/isp.c              | 11 ++++---
>  drivers/media/platform/omap3isp/ispccdc.c          |  2 +-
>  drivers/media/platform/omap3isp/ispvideo.c         | 10 ++++---
>  drivers/media/platform/vsp1/vsp1_video.c           |  2 +-
>  drivers/media/platform/xilinx/xilinx-dma.c         |  2 +-
>  drivers/staging/media/davinci_vpfe/vpfe_video.c    |  6 ++--
>  drivers/staging/media/omap4iss/iss.c               |  6 ++--
>  drivers/staging/media/omap4iss/iss_video.c         |  4 +--
>  include/media/media-entity.h                       |  1 -
>  15 files changed, 58 insertions(+), 52 deletions(-)
> 


From hverkuil at xs4all.nl  Thu Aug 20 05:43:11 2015
From: hverkuil at xs4all.nl (Hans Verkuil)
Date: Thu, 20 Aug 2015 14:43:11 +0200
Subject: [PATCH 3/4] [media] media: use entity.graph_obj.mdev instead
 of .parent
In-Reply-To: <1439998526-12832-4-git-send-email-javier@osg.samsung.com>
References: <1439998526-12832-1-git-send-email-javier@osg.samsung.com>
 <1439998526-12832-4-git-send-email-javier@osg.samsung.com>
Message-ID: <55D5CB5F.2010106@xs4all.nl>

On 08/19/15 17:35, Javier Martinez Canillas wrote:
> The struct media_entity has a .parent field that stores a pointer
> to the parent struct media_device. But recently a media_gobj was
> embedded into the entities and since struct media_gojb already has
> a pointer to a struct media_device in the .mdev field, the .parent
> field becomes redundant and can be removed.
> 
> This patch replaces all the usage of .parent by .graph_obj.mdev so
> that field will become unused and can be removed on a later patch.
> 
> No functional changes.
> 
> The transformation was made using the following coccinelle spatch:
> 
> @@
> struct media_entity *me;
> @@
> 
> - me->parent
> + me->graph_obj.mdev
> 
> @@
> struct media_entity *link;
> @@
> 
> - link->source->entity->parent
> + link->source->entity->graph_obj.mdev
> 
> @@
> struct exynos_video_entity *ve;
> @@
> 
> - ve->vdev.entity.parent
> + ve->vdev.entity.graph_obj.mdev
> 
> Suggested-by: Mauro Carvalho Chehab <mchehab at osg.samsung.com>
> Signed-off-by: Javier Martinez Canillas <javier at osg.samsung.com>

Acked-by: Hans Verkuil <hans.verkuil at cisco.com>

Regards,

	Hans


From ludovic.desroches at atmel.com  Thu Aug 20 05:44:49 2015
From: ludovic.desroches at atmel.com (Ludovic Desroches)
Date: Thu, 20 Aug 2015 14:44:49 +0200
Subject: [RFC PATCH 0/3] New Atmel PIO4 pinctrl/gpio driver
In-Reply-To: <20150820070507.GS5161@pengutronix.de>
References: <1438355290-28255-1-git-send-email-ludovic.desroches@atmel.com>
 <20150805073117.GP5161@pengutronix.de>
 <20150810065334.GC2635@odux.rfo.atmel.com>
 <20150820070507.GS5161@pengutronix.de>
Message-ID: <20150820124449.GB23434@odux.rfo.atmel.com>

On Thu, Aug 20, 2015 at 09:05:07AM +0200, Sascha Hauer wrote:
> On Mon, Aug 10, 2015 at 08:53:34AM +0200, Ludovic Desroches wrote:
> > Hi Sascha,
> > 
> > On Wed, Aug 05, 2015 at 09:31:17AM +0200, Sascha Hauer wrote:
> > > On Fri, Jul 31, 2015 at 05:08:07PM +0200, Ludovic Desroches wrote:
> > > > Hi,
> > > > 
> > > > Following our discussion, I send an RFC version of my driver. RFC because it is
> > > > not totally achieved, some cleanup and feature addition is needed.
> > > > 
> > > > At least, we could discuss about the 'core' part. I have used the pinmux
> > > > property as Mediatek driver. Patch 3 is the internal dt files we are using.
> > > 
> > > As you can imagine I am fine with the binding, so I can add my acked-by
> > > once you send a non-RFC version.
> > >
> > 
> > Great, I'm glad to hear that.
> >  
> > > The only thing I never understood is what's so special about GPIOs that
> > > they have to bypass the pinctrl framework and instead a gpio_request
> > > magically translates a gpio into a pin.
> > 
> > Not sure to really understand your concern here... Do you mean I could
> > get rid of gpio_request_enable()?
> 
> I would expect a gpio to be a pin like every other pin, hence configured
> via the pinctrl framework and not implicitly via gpio_request().
> 

It is not an issue to get rid of gpio_request_*(). I was thinking it was
a bonus to provide it.

> > 
> > > Wouldn't it make sense to at
> > > least add the pins in their GPIO mode to
> > > arch/arm/boot/dts/sama5d2-pinfunc.h?
> > 
> > It is done, PIN_PA0 could be used for this purpose.
> 
> I would expect a define like:
> 
> #define PIN_PA3__GPIO                   PINMUX_PIN(PIN_PA3, 0, 2)
> 
> PIN_PAx only contains the pin number, but not the function.

Ok I can do this change for v2.


Ludovic


From catalin.marinas at arm.com  Thu Aug 20 05:50:35 2015
From: catalin.marinas at arm.com (Catalin Marinas)
Date: Thu, 20 Aug 2015 13:50:35 +0100
Subject: [PATCH 2/2] arm64: set MAX_MEMBLOCK_ADDR according to linear
 region size
In-Reply-To: <E830F411-141C-40C4-A608-7709304395C5@linaro.org>
References: <1439890482-20798-1-git-send-email-ard.biesheuvel@linaro.org>
 <1439890482-20798-3-git-send-email-ard.biesheuvel@linaro.org>
 <20150820091915.GC2972@e104818-lin.cambridge.arm.com>
 <E830F411-141C-40C4-A608-7709304395C5@linaro.org>
Message-ID: <20150820125035.GD2972@e104818-lin.cambridge.arm.com>

On Thu, Aug 20, 2015 at 01:54:40PM +0200, Ard Biesheuvel wrote:
> 
> 
> > On 20 aug. 2015, at 11:19, Catalin Marinas <catalin.marinas at arm.com> wrote:
> > 
> >> On Tue, Aug 18, 2015 at 11:34:42AM +0200, Ard Biesheuvel wrote:
> >> The linear region size of a 39-bit VA kernel is only 256 GB, which
> >> may be insufficient to cover all of system RAM, even on platforms
> >> that have much less than 256 GB of memory but which is laid out
> >> very sparsely.
> >> 
> >> So make sure we clip the memory we will not be able to map before
> >> installing it into the memblock memory table, by setting
> >> MAX_MEMBLOCK_ADDR accordingly.
> >> 
> >> Signed-off-by: Ard Biesheuvel <ard.biesheuvel at linaro.org>
> >> ---
> >> arch/arm64/include/asm/memory.h | 8 ++++++++
> >> 1 file changed, 8 insertions(+)
> >> 
> >> diff --git a/arch/arm64/include/asm/memory.h b/arch/arm64/include/asm/memory.h
> >> index f800d45ea226..44a59c20e773 100644
> >> --- a/arch/arm64/include/asm/memory.h
> >> +++ b/arch/arm64/include/asm/memory.h
> >> @@ -114,6 +114,14 @@ extern phys_addr_t        memstart_addr;
> >> #define PHYS_OFFSET        ({ memstart_addr; })
> >> 
> >> /*
> >> + * The maximum physical address that the linear direct mapping
> >> + * of system RAM can cover. (PAGE_OFFSET can be interpreted as
> >> + * a 2's complement signed quantity and negated to derive the
> >> + * maximum size of the linear mapping.)
> >> + */
> >> +#define MAX_MEMBLOCK_ADDR    ({ memstart_addr - PAGE_OFFSET - 1; })
> > 
> > Would it be easier to understand as just memstart_addr + ~PAGE_OFFSET?
> 
> Whichever you prefer

Just leave it as it is, not sure it's any clearer. Basically the maximum
size we can map is (0 - PAGE_OFFSET), so if we make the range inclusive,
we get to memstart_addr - PAGE_OFFSET - 1.

-- 
Catalin


From javier at osg.samsung.com  Thu Aug 20 05:50:53 2015
From: javier at osg.samsung.com (Javier Martinez Canillas)
Date: Thu, 20 Aug 2015 14:50:53 +0200
Subject: [PATCH 0/4] [media] Media entity cleanups and build fixes
In-Reply-To: <55D5CB04.50508@xs4all.nl>
References: <1439998526-12832-1-git-send-email-javier@osg.samsung.com>
 <55D5CB04.50508@xs4all.nl>
Message-ID: <55D5CD2D.2010607@osg.samsung.com>

Hello Hans,

On 08/20/2015 02:41 PM, Hans Verkuil wrote:
> On 08/19/15 17:35, Javier Martinez Canillas wrote:
>> Hello,
>>
>> This series contains a couple of build fixes and cleanups for the
>> Media Controller framework. The goal of the series is to get rid of
>> the struct media_entity .parent member since now that a media_gobj is
>> embedded into entities, the media_gobj .mdev member can be used to
>> store a pointer to the parent struct media_device.
>>
>> So the .parent field becomes redundant and can be removed after all
>> the users are converted to use entity .graph_obj.mdev instead.
>>
>> Patches 1/4 and 2/4 are build fixes I found while build testing if no
>> regressions were introduced by the conversion. Patch 3/4 converts
>> all the drivers and the MC core to use .mdev instead of .parent and
>> finally patch 4/4 removes the .parent field since now is unused.
> 
> Regarding patches 1 and 2: these should of course be merged with Mauro's
> patches that make this particular change (patch 3/8), otherwise it would
> break git bisect.
> 
> Anyway,
> 
> Acked-by: Hans Verkuil <hans.verkuil at cisco.com> for the changes in patch

Thanks a lot for the acks.

> 1 and 2, as long as they are added to Mauro's patch 3/8.
>

Indeed, I completely agree that these should be squashed with
Mauro's patch to maintain git bisect-ability.
 
> Regards,
> 
> 	Hans
> 

Best regards,
-- 
Javier Martinez Canillas
Open Source Group
Samsung Research America


From catalin.marinas at arm.com  Thu Aug 20 06:02:00 2015
From: catalin.marinas at arm.com (Catalin Marinas)
Date: Thu, 20 Aug 2015 14:02:00 +0100
Subject: [PATCH 3/3] [v2] hvc_dcc: disable user-space access to DCC
In-Reply-To: <20150820104645.GD19328@arm.com>
References: <1440025370-9519-1-git-send-email-timur@codeaurora.org>
 <1440025370-9519-3-git-send-email-timur@codeaurora.org>
 <20150820104645.GD19328@arm.com>
Message-ID: <20150820130200.GE2972@e104818-lin.cambridge.arm.com>

On Thu, Aug 20, 2015 at 11:46:45AM +0100, Will Deacon wrote:
> On Thu, Aug 20, 2015 at 12:02:50AM +0100, Timur Tabi wrote:
> > If the DCC driver loads, then disable user-space access to the DCC so that
> > we don't have two entities trying to access the DCC at the same time.
> 
> In the interests of making some headway with this, just drop this patch
> and I'll queue the diff below via the arm64 tree.
> 
> Will
> 
> --->8
> 
> diff --git a/arch/arm64/mm/proc.S b/arch/arm64/mm/proc.S
> index 39139a3aa16d..4c922ecce600 100644
> --- a/arch/arm64/mm/proc.S
> +++ b/arch/arm64/mm/proc.S
> @@ -156,7 +156,7 @@ ENTRY(__cpu_setup)
>  
>  	mov	x0, #3 << 20
>  	msr	cpacr_el1, x0			// Enable FP/ASIMD
> -	msr	mdscr_el1, xzr			// Reset mdscr_el1
> +	msr	mdscr_el1, #1 << 12		// Reset mdscr_el1

Nitpick: expand the "Reset..." comment to include some text about this
bit.

-- 
Catalin


From linux at arm.linux.org.uk  Thu Aug 20 06:00:06 2015
From: linux at arm.linux.org.uk (Russell King - ARM Linux)
Date: Thu, 20 Aug 2015 14:00:06 +0100
Subject: [PATCH] ARM: Set proper TEXT_OFFSET for IPQ806x
In-Reply-To: <20150820121541.GA14664@codeaurora.org>
References: <20150820121541.GA14664@codeaurora.org>
Message-ID: <20150820130005.GS7557@n2100.arm.linux.org.uk>

On Thu, Aug 20, 2015 at 05:45:41PM +0530, Varadarajan Narayanan wrote:
> RAM starts at 0x40000000 for IPQ. The lower 21MB of RAM is used
> for Shared Memory and the kernel can start from 0x41500000.

Why do people keep creating crap like this?  Each time something like
this is created, it means that you _need_ to have a special kernel for
your platform and you can't be part of the single zImage.

Please, rather than creating crap like this, find a better way.

-- 
FTTC broadband for 0.8mile line: currently at 10.5Mbps down 400kbps up
according to speedtest.net.


From arnd at arndb.de  Thu Aug 20 06:09:11 2015
From: arnd at arndb.de (Arnd Bergmann)
Date: Thu, 20 Aug 2015 15:09:11 +0200
Subject: [PATCH v5 1/2] usb: make xhci platform driver use 64 bit or 32
 bit DMA
In-Reply-To: <CADaLNDmYt+k6Sw6q+t2-FA7muk=x6h_hfYV321B03qBPMD_=AA@mail.gmail.com>
References: <CADaLNDkU14GCPZE_zNt_9kMSsUdywyNp1QCiWpokXQgbfRS0qw@mail.gmail.com>
 <1643536.i8Q5EFEN01@wuerfel>
 <CADaLNDmYt+k6Sw6q+t2-FA7muk=x6h_hfYV321B03qBPMD_=AA@mail.gmail.com>
Message-ID: <1522889.9kdnRk8vHo@wuerfel>

On Wednesday 19 August 2015 14:28:33 Duc Dang wrote:
> 
> Hi Arnd,
> 
> So the check will look like this, please let me know what do you think:
>         if (!pdev->dev.dma_mask) {
>                 WARN_ON(1);
>                 /* Initialize dma_mask if the broken platform code has
> not done so */
>                 pdev->dev.dma_mask = &pdev->dev.coherent_dma_mask;
>         }

The condition can be written as 

	if (WARN_ON(!pdev->dev.dma_mask))

and I'd use dma_coerce_mask_and_coherent() instead of manually setting the
pointer, as an annotation for the fact that we are knowingly violating the
API here.

Those two points are just cosmetic though, aside from them, your code
above is what I had in mind.

Thanks,

	Arnd


From monnier at iro.umontreal.ca  Thu Aug 20 06:15:38 2015
From: monnier at iro.umontreal.ca (Stefan Monnier)
Date: Thu, 20 Aug 2015 09:15:38 -0400
Subject: [PATCH v8] dma: sun4i: Add support for the DMA engine on
 sun[457]i SoCs
References: <1437943855-29055-1-git-send-email-maxime.ripard@free-electrons.com>
 <20150820051556.GT13546@localhost>
Message-ID: <jwvzj1mm782.fsf-monnier+gmane.comp.hardware.netbook.arm.sunxi@gnu.org>

> Applied with subsystem name fixed

Yay!


        Stefan



From 21cnbao at gmail.com  Thu Aug 20 06:23:02 2015
From: 21cnbao at gmail.com (Barry Song)
Date: Thu, 20 Aug 2015 21:23:02 +0800
Subject: [PATCH v7 4/5] clk: Provide critical clock support
In-Reply-To: <20150817074244.GA3239@x1>
References: <1437570255-21049-1-git-send-email-lee.jones@linaro.org>
 <1437570255-21049-5-git-send-email-lee.jones@linaro.org>
 <CAGsJ_4zKn-o4ZxZ0-xzCStvuTkdC5xqD9FneWna-0dNVgp=1DQ@mail.gmail.com>
 <20150817074244.GA3239@x1>
Message-ID: <CAGsJ_4xZOktOy=SMft+VA9JOLBauk-_vchVY=Cs62PzrZ+socQ@mail.gmail.com>

2015-08-17 15:42 GMT+08:00 Lee Jones <lee.jones at linaro.org>:
> On Mon, 17 Aug 2015, Barry Song wrote:
>
>> 2015-07-22 21:04 GMT+08:00 Lee Jones <lee.jones at linaro.org>:
>> > Lots of platforms contain clocks which if turned off would prove fatal.
>> > The only way to recover from these catastrophic failures is to restart
>> > the board(s).  Now, when a clock provider is registered with the
>> > framework it is possible for a list of critical clocks to be supplied
>> > which must be kept ungated.  Each clock mentioned in the newly
>> > introduced 'critical-clock' property will be clk_prepare_enable()d
>> > where the normal references will be taken.  This will prevent the
>> > common clk framework from attempting to gate them during the normal
>> > clk_disable_unused() and disable_clock() procedures.
>> >
>> > Note that it will still be possible for knowledgeable drivers to turn
>> > these clocks off using clk_{enable,disable}_critical() calls.
>> >
>> > Signed-off-by: Lee Jones <lee.jones at linaro.org>
>>
>> hi Lee,
>> i have another email about this. i am wondering whether
>> CLK_IGNORE_UNUSE is still useful after your patch. another solution
>> for your patch might be extending the current CLK_IGNORE_UNUSE to
>> runtime?
>>
>>
>> copy the mail here:
>> currently we can set a CLK_IGNORE_UNUSE flag to  a clock to stop
>> clk_disable_unused()  from disabling it at the boot stage:
>>
>> static void clk_disable_unused_subtree(struct clk_core *core)
>> {
>> ...
>>
>> if (core->flags & CLK_IGNORE_UNUSED)
>> goto unlock_out;
>> }
>>
>> static int clk_disable_unused(void)
>> {
>> ...
>>
>> clk_unprepare_unused_subtree(core);
>> ...
>>  return 0;
>> }
>>
>> late_initcall_sync(clk_disable_unused);
>>
>> so if there are two clocks A and B, A is the parent of B, and A is
>> marked as CLK_IGNORE_UNUSED.
>>
>> in boot stage if there is nobody using A and B, Linux will disable B
>> due to clk_disable_unused() , but keep A being enabled since A has
>> CLK_IGNORE_UNUSED.
>>
>> but in Linux runtime, we might frequently disable /enable B in runtime
>> power management, this will cause A disabled since Linux will not
>> check CLK_IGNORE_UNUSED for runtime disabling clk .
>>
>>  so this makes CLK_IGNORE_UNUSE only work if we don't disable its
>> sub-clock at runtime. this looks making no sense.
>>
>>  i am thinking whether we should do some changes to make it have side
>> affect for runtime clk disable. otherwise, why do we want to stop it
>> from being disabled during boot stage?
>
> This is one of this problems, along with some others that this set
> aims to solve.
>
> Extending CLK_IGNORE_UNUSED is not a good idea.  In fact, if we can
> phase it out completely, that will be a good thing.

i would agree it is better we can drop CLK_IGNORE_UNUSED since it is
confusing...


>
> Since this set Mike has submitted an alternitive solution.
>
> Please see: https://groups.google.com/forum/#!msg/linux.kernel/kX_nWSsWRxU/IZSjhG5Ed4oJ
>
>>  I am not sure whether i missed something in clk core level support.
>>
>> -barry
>>
>> > ---
>> >  drivers/clk/clk-conf.c | 45 ++++++++++++++++++++++++++++++++++++++++++++-
>> >  1 file changed, 44 insertions(+), 1 deletion(-)
>> >
>> > diff --git a/drivers/clk/clk-conf.c b/drivers/clk/clk-conf.c
>> > index aad4796..f83c1c2 100644
>> > --- a/drivers/clk/clk-conf.c
>> > +++ b/drivers/clk/clk-conf.c
>> > @@ -116,6 +116,45 @@ static int __set_clk_rates(struct device_node *node, bool clk_supplier)
>> >         return 0;
>> >  }
>> >
>> > +static int __set_critical_clocks(struct device_node *node, bool clk_supplier)
>> > +{
>> > +       struct of_phandle_args clkspec;
>> > +       struct clk *clk;
>> > +       struct property *prop;
>> > +       const __be32 *cur;
>> > +       uint32_t index;
>> > +       int ret;
>> > +
>> > +       if (!clk_supplier)
>> > +               return 0;
>> > +
>> > +       of_property_for_each_u32(node, "critical-clock", prop, cur, index) {
>> > +               clkspec.np = node;
>> > +               clkspec.args_count = 1;
>> > +               clkspec.args[0] = index;
>> > +
>> > +               clk = of_clk_get_from_provider(&clkspec);
>> > +               if (IS_ERR(clk)) {
>> > +                       pr_err("clk: couldn't get clock %u for %s\n",
>> > +                               index, node->full_name);
>> > +                       return PTR_ERR(clk);
>> > +               }
>> > +
>> > +               clk_init_critical(clk);
>> > +
>> > +               ret = clk_prepare_enable(clk);
>> > +               if (ret) {
>> > +                       pr_err("Failed to enable clock %u for %s: %d\n",
>> > +                              index, node->full_name, ret);
>> > +                       return ret;
>> > +               }
>> > +
>> > +               pr_debug("Setting clock as critical %pC\n", clk);
>> > +       }
>> > +
>> > +       return 0;
>> > +}
>> > +
>> >  /**
>> >   * of_clk_set_defaults() - parse and set assigned clocks configuration
>> >   * @node: device node to apply clock settings for
>> > @@ -139,6 +178,10 @@ int of_clk_set_defaults(struct device_node *node, bool clk_supplier)
>> >         if (rc < 0)
>> >                 return rc;
>> >
>> > -       return __set_clk_rates(node, clk_supplier);
>> > +       rc = __set_clk_rates(node, clk_supplier);
>> > +       if (rc < 0)
>> > +               return rc;
>> > +
>> > +       return __set_critical_clocks(node, clk_supplier);
>> >  }
>> >  EXPORT_SYMBOL_GPL(of_clk_set_defaults);
>
> --

-barry


From leo.yan at linaro.org  Thu Aug 20 06:44:38 2015
From: leo.yan at linaro.org (Leo Yan)
Date: Thu, 20 Aug 2015 21:44:38 +0800
Subject: [PATCH v2 2/3] mailbox: Hi6220: add mailbox driver
In-Reply-To: <55D568E2.9060505@hisilicon.com>
References: <1440039239-8772-1-git-send-email-leo.yan@linaro.org>
 <1440039239-8772-3-git-send-email-leo.yan@linaro.org>
 <55D568E2.9060505@hisilicon.com>
Message-ID: <20150820134438.GA18629@leoy-linaro>

Hi Yiping,

Thanks for review, please see below comments.

On Thu, Aug 20, 2015 at 01:42:58PM +0800, YiPing Xu wrote:
> On 2015/8/20 10:53, Leo Yan wrote:
> >Add driver for Hi6220 mailbox, the mailbox communicates with MCU; for
> >sending data, it can support two methods for low level implementation:
> >one is to use interrupt as acknowledge, another is automatic mode which
> >without any acknowledge. These two methods have been supported in the
> >driver. For receiving data, it will depend on the interrupt to notify
> >the channel has incoming message; enhance rx channel's message queue,
> >which is based on the code in drivers/mailbox/omap-mailbox.c.
> >
> >Now mailbox driver is used to send message to MCU to control dynamic
> >voltage and frequency scaling for CPU, GPU and DDR.
> >
> >Signed-off-by: Leo Yan <leo.yan at linaro.org>

[...]

> >+static int hi6220_mbox_send_data(struct mbox_chan *chan, void *msg)
> >+{
> >+	struct hi6220_mbox_chan *mchan = chan->con_priv;
> >+	struct hi6220_mbox *mbox = mchan->parent;
> >+	int irq = mchan->remote_irq;
> >+	u32 *buf = msg;
> >+	unsigned long flags;
> >+	int i;
> >+
> >+	hi6220_mbox_set_status(mchan, HI6220_MBOX_STATUS_TX);
> 
> 	hi6220_mbox_set_status is called in send_data context, and it is
> also called in hi6220_mbox_rx_interrupt and
> hi6220_mbox_tx_interrupt.
> 
> 	no race condition here?

Have thought this question yet when writing code; it will _NOT_
introduce race condition according to below implementation details:

- Every channel have its own slot, so there have no race condition
  between channels;
- The channel is unidirectional; so it will be only for tx or rx at
  the same time;
- The channel operation is sequential, so it have the sequence as:
  For tx: startup -> send_data -> tx_irq (for ack);
  For rx: startup -> rx_irq -> recv_data;

Thanks,
Leo Yan


From clabbe.montjoie at gmail.com  Thu Aug 20 06:56:39 2015
From: clabbe.montjoie at gmail.com (Corentin LABBE)
Date: Thu, 20 Aug 2015 15:56:39 +0200
Subject: un4i-ss-cipher.c warning
In-Reply-To: <CAOMqctShdb9xEkBmuaQKfB1cwGupbfH5TS5ZB_P85Hwpn+4zAA@mail.gmail.com>
References: <CAOMqctShdb9xEkBmuaQKfB1cwGupbfH5TS5ZB_P85Hwpn+4zAA@mail.gmail.com>
Message-ID: <55D5DC97.1040209@gmail.com>

On 19/08/2015 16:35, Michal Suchanek wrote:
> Hello,
>
> when building a kernel with sunxi crypto driver as merged into the
> sinxi-wip branch I get a compiler warning.
>
> I am not sure this is the latest version of the driver. It does not
> seem to be in mainline yet.
>
> Thanks
>
> Michal
>
> In file included from /scratch/build/linux/include/linux/printk.h:277:0,
>                   from /scratch/build/linux/include/linux/kernel.h:13,
>                   from /scratch/build/linux/include/linux/clk.h:16,
>                   from
> /scratch/build/linux/drivers/crypto/sunxi-ss/sun4i-ss.h:15,
>                   from
> /scratch/build/linux/drivers/crypto/sunxi-ss/sun4i-ss-cipher.c:17:
> /scratch/build/linux/drivers/crypto/sunxi-ss/sun4i-ss-cipher.c: In
> function ?sun4i_ss_cipher_poll?:
> /scratch/build/linux/include/linux/dynamic_debug.h:86:3: warning:
> ?todo? may be used uninitialized in this function
> [-Wmaybe-uninitialized]
>     __dynamic_dev_dbg(&descriptor, dev, fmt, \
>     ^
> /scratch/build/linux/drivers/crypto/sunxi-ss/sun4i-ss-cipher.c:144:15:
> note: ?todo? was declared here
>    unsigned int todo;
>

Hello

Thanks for the report, strange that I do not have that warning.
todo is always initialized, since oleft and ileft are always > 0 at start.
But setting todo to 0 is a simple fix.
The following patch will suppress the warning.

Regards

-- >8 --
 From 67f2d0749041b08c4c4ad671ab710b3b83f6dfd3 Mon Sep 17 00:00:00 2001
From: LABBE Corentin <clabbe.montjoie at gmail.com>
Date: Thu, 20 Aug 2015 12:18:46 +0200
Subject: [PATCH] crypto: sun4i-ss: suppress the todo uninitialized warning

Signed-off-by: LABBE Corentin <clabbe.montjoie at gmail.com>
---
  drivers/crypto/sunxi-ss/sun4i-ss-cipher.c | 4 ++--
  1 file changed, 2 insertions(+), 2 deletions(-)

diff --git a/drivers/crypto/sunxi-ss/sun4i-ss-cipher.c b/drivers/crypto/sunxi-ss/sun4i-ss-cipher.c
index e070c31..9299914 100644
--- a/drivers/crypto/sunxi-ss/sun4i-ss-cipher.c
+++ b/drivers/crypto/sunxi-ss/sun4i-ss-cipher.c
@@ -32,7 +32,7 @@ static int sun4i_ss_opti_poll(struct ablkcipher_request *areq)
  	int i, err = 0;
  	unsigned int ileft = areq->nbytes;
  	unsigned int oleft = areq->nbytes;
-	unsigned int todo;
+	unsigned int todo = 0;
  	struct sg_mapping_iter mi, mo;
  	unsigned int oi, oo; /* offset for in and out */

@@ -141,7 +141,7 @@ static int sun4i_ss_cipher_poll(struct ablkcipher_request *areq)
  	int i, err = 0;
  	unsigned int ileft = areq->nbytes;
  	unsigned int oleft = areq->nbytes;
-	unsigned int todo;
+	unsigned int todo = 0;
  	struct sg_mapping_iter mi, mo;
  	unsigned int oi, oo;	/* offset for in and out */
  	char buf[4 * SS_RX_MAX];/* buffer for linearize SG src */
-- 
2.4.6



From p.fedin at samsung.com  Thu Aug 20 07:11:57 2015
From: p.fedin at samsung.com (Pavel Fedin)
Date: Thu, 20 Aug 2015 17:11:57 +0300
Subject: [PATCH 2/5] gic-its: Allow pci_requester_id to be overridden.
In-Reply-To: <1436979285-8177-3-git-send-email-ddaney.cavm@gmail.com>
References: <1436979285-8177-1-git-send-email-ddaney.cavm@gmail.com>
 <1436979285-8177-3-git-send-email-ddaney.cavm@gmail.com>
Message-ID: <01a101d0db52$2d23b360$876b1a20$@samsung.com>

 Hello!

> -----Original Message-----
> From: linux-pci-owner at vger.kernel.org [mailto:linux-pci-owner at vger.kernel.org] On Behalf Of David
> Daney
> Sent: Wednesday, July 15, 2015 7:55 PM
> To: linux-arm-kernel at lists.infradead.org; Catalin Marinas; Will Deacon; Bjorn Helgaas; linux-
> pci at vger.kernel.org; Thomas Gleixner; Jason Cooper
> Cc: linux-kernel at vger.kernel.org; Robert Richter; David Daney
> Subject: [PATCH 2/5] gic-its: Allow pci_requester_id to be overridden.
> 
> From: David Daney <david.daney at cavium.com>
> 
> Signed-off-by: David Daney <david.daney at cavium.com>
> ---
>  drivers/irqchip/irq-gic-v3-its.c   | 14 +++++++++++++-
>  include/linux/irqchip/arm-gic-v3.h |  2 ++
>  2 files changed, 15 insertions(+), 1 deletion(-)
> 
> diff --git a/drivers/irqchip/irq-gic-v3-its.c b/drivers/irqchip/irq-gic-v3-its.c
> index 1b7e155..4580970 100644
> --- a/drivers/irqchip/irq-gic-v3-its.c
> +++ b/drivers/irqchip/irq-gic-v3-its.c
> @@ -1189,11 +1189,23 @@ static int its_pci_msi_vec_count(struct pci_dev *pdev)
>  	return max(msi, msix);
>  }
> 
> +static u32 its_dflt_pci_requester_id(struct pci_dev *pdev, u16 alias)
> +{
> +	return alias;
> +}
> +
> +static its_pci_requester_id_t its_pci_requester_id = its_dflt_pci_requester_id;
> +void set_its_pci_requester_id(its_pci_requester_id_t fn)
> +{
> +	its_pci_requester_id = fn;
> +}
> +EXPORT_SYMBOL(set_its_pci_requester_id);

 IMHO having a globally defined function is a horrible approach. What if some HW has two different
PCI host controllers, each of them wants to provide different form of IDs? I know, this is just
imaginary, but still...
 What if instead of this function we simply add a field to a struct pci_bus ? Then bus driver would
fill in HW-specific ID bits for every bus.
 I can send a patch if interested.

> +
>  static int its_get_pci_alias(struct pci_dev *pdev, u16 alias, void *data)
>  {
>  	struct its_pci_alias *dev_alias = data;
> 
> -	dev_alias->dev_id = alias;
> +	dev_alias->dev_id = its_pci_requester_id(pdev, alias);
>  	if (pdev != dev_alias->pdev)
>  		dev_alias->count += its_pci_msi_vec_count(dev_alias->pdev);
> 
> diff --git a/include/linux/irqchip/arm-gic-v3.h b/include/linux/irqchip/arm-gic-v3.h
> index ffbc034..18e3757 100644
> --- a/include/linux/irqchip/arm-gic-v3.h
> +++ b/include/linux/irqchip/arm-gic-v3.h
> @@ -389,6 +389,8 @@ int its_cpu_init(void);
>  int its_init(struct device_node *node, struct rdists *rdists,
>  	     struct irq_domain *domain);
> 
> +typedef u32 (*its_pci_requester_id_t)(struct pci_dev *, u16);
> +void set_its_pci_requester_id(its_pci_requester_id_t fn);
>  #endif
> 
>  #endif
> --

Kind regards,
Pavel Fedin
Expert Engineer
Samsung Electronics Research center Russia





From hramrach at gmail.com  Thu Aug 20 07:19:45 2015
From: hramrach at gmail.com (Michal Suchanek)
Date: 20 Aug 2015 14:19:45 -0000
Subject: [PATCH 1/9] spi: sunxi: fix transfer timeout
In-Reply-To: <cover.1440080122.git.hramrach@gmail.com>
References: <cover.1440080122.git.hramrach@gmail.com>
Message-ID: <0e0b52774a48ddb71dc8095b66942451cd31ff7d.1440080122.git.hramrach@gmail.com>

The trasfer timeout is fixed at 1000 ms. Reading a 4Mbyte flash over
1MHz SPI bus takes way longer than that. Calculate the timeout from the
actual time the transfer is supposed to take and multiply by 2 for good
measure.

Signed-off-by: Michal Suchanek <hramrach at gmail.com>
---
 drivers/spi/spi-sun4i.c | 10 +++++++++-
 drivers/spi/spi-sun6i.c | 10 +++++++++-
 2 files changed, 18 insertions(+), 2 deletions(-)

diff --git a/drivers/spi/spi-sun4i.c b/drivers/spi/spi-sun4i.c
index fbb0a4d..48532ec 100644
--- a/drivers/spi/spi-sun4i.c
+++ b/drivers/spi/spi-sun4i.c
@@ -170,6 +170,7 @@ static int sun4i_spi_transfer_one(struct spi_master *master,
 {
 	struct sun4i_spi *sspi = spi_master_get_devdata(master);
 	unsigned int mclk_rate, div, timeout;
+	unsigned int start, end, tx_time;
 	unsigned int tx_len = 0;
 	int ret = 0;
 	u32 reg;
@@ -279,9 +280,16 @@ static int sun4i_spi_transfer_one(struct spi_master *master,
 	reg = sun4i_spi_read(sspi, SUN4I_CTL_REG);
 	sun4i_spi_write(sspi, SUN4I_CTL_REG, reg | SUN4I_CTL_XCH);
 
+	tx_time = max_t(int, tfr->len * 8 * 2 / (speed / 1000), 100);
+	start = jiffies;
 	timeout = wait_for_completion_timeout(&sspi->done,
-					      msecs_to_jiffies(1000));
+					      msecs_to_jiffies(tx_time));
+	end = jiffies;
 	if (!timeout) {
+		dev_warn(&master->dev,
+			 "%s: timeout transferring %u bytes@%iHz for %i(%i)ms",
+			 dev_name(&spi->dev), tfr->len, speed,
+			 jiffies_to_msecs(end - start), tx_time);
 		ret = -ETIMEDOUT;
 		goto out;
 	}
diff --git a/drivers/spi/spi-sun6i.c b/drivers/spi/spi-sun6i.c
index ac48f59..3d0f66c 100644
--- a/drivers/spi/spi-sun6i.c
+++ b/drivers/spi/spi-sun6i.c
@@ -162,6 +162,7 @@ static int sun6i_spi_transfer_one(struct spi_master *master,
 	unsigned int mclk_rate, div, timeout;
 	unsigned int tx_len = 0;
 	int ret = 0;
+	unsigned int start, end, tx_time;
 	u32 reg;
 
 	/* We don't support transfer larger than the FIFO */
@@ -269,9 +270,16 @@ static int sun6i_spi_transfer_one(struct spi_master *master,
 	reg = sun6i_spi_read(sspi, SUN6I_TFR_CTL_REG);
 	sun6i_spi_write(sspi, SUN6I_TFR_CTL_REG, reg | SUN6I_TFR_CTL_XCH);
 
+	tx_time = max_t(int, tfr->len * 8 * 2 / (speed / 1000), 100);
+	start = jiffies;
 	timeout = wait_for_completion_timeout(&sspi->done,
-					      msecs_to_jiffies(1000));
+					      msecs_to_jiffies(tx_time));
+	end = jiffies;
 	if (!timeout) {
+		dev_warn(&master->dev,
+			 "%s: timeout transferring %u bytes@%iHz for %i(%i)ms",
+			 dev_name(&spi->dev), tfr->len, speed,
+			 jiffies_to_msecs(end - start), tx_time);
 		ret = -ETIMEDOUT;
 		goto out;
 	}
-- 
2.1.4



From emilio at elopez.com.ar  Thu Aug 20 07:19:46 2015
From: emilio at elopez.com.ar (=?UTF-8?q?Emilio=20L=C3=B3pez?=)
Date: 20 Aug 2015 14:19:46 -0000
Subject: [PATCH 4/9] spi: sun4i: add DMA support
In-Reply-To: <cover.1440080122.git.hramrach@gmail.com>
References: <cover.1440080122.git.hramrach@gmail.com>
Message-ID: <ccf776869b0d7fe2c78bcc41d6cd1896bf732296.1440080122.git.hramrach@gmail.com>

From: Emilio L?pez <emilio at elopez.com.ar>

This patch adds support for 64 byte or bigger transfers on the
sun4i SPI controller. Said transfers will be performed via DMA.

Signed-off-by: Emilio L?pez <emilio at elopez.com.ar>
Tested-by: Michal Suchanek <hramrach at gmail.com>
---
 drivers/spi/spi-sun4i.c | 145 +++++++++++++++++++++++++++++++++++++++++++-----
 1 file changed, 130 insertions(+), 15 deletions(-)

diff --git a/drivers/spi/spi-sun4i.c b/drivers/spi/spi-sun4i.c
index 4dda366..63242a7 100644
--- a/drivers/spi/spi-sun4i.c
+++ b/drivers/spi/spi-sun4i.c
@@ -14,6 +14,8 @@
 #include <linux/clk.h>
 #include <linux/delay.h>
 #include <linux/device.h>
+#include <linux/dmaengine.h>
+#include <linux/dma-mapping.h>
 #include <linux/interrupt.h>
 #include <linux/io.h>
 #include <linux/module.h>
@@ -34,6 +36,7 @@
 #define SUN4I_CTL_CPHA				BIT(2)
 #define SUN4I_CTL_CPOL				BIT(3)
 #define SUN4I_CTL_CS_ACTIVE_LOW			BIT(4)
+#define SUN4I_CTL_DMAMC_DEDICATED		BIT(5)
 #define SUN4I_CTL_LMTF				BIT(6)
 #define SUN4I_CTL_TF_RST			BIT(8)
 #define SUN4I_CTL_RF_RST			BIT(9)
@@ -51,6 +54,8 @@
 #define SUN4I_INT_STA_REG		0x10
 
 #define SUN4I_DMA_CTL_REG		0x14
+#define SUN4I_DMA_CTL_RF_READY			BIT(0)
+#define SUN4I_DMA_CTL_TF_NOT_FULL		BIT(10)
 
 #define SUN4I_WAIT_REG			0x18
 
@@ -130,6 +135,13 @@ static inline void sun4i_spi_fill_fifo(struct sun4i_spi *sspi, int len)
 	}
 }
 
+static bool sun4i_spi_can_dma(struct spi_master *master,
+			      struct spi_device *spi,
+			      struct spi_transfer *tfr)
+{
+	return tfr->len >= SUN4I_FIFO_DEPTH;
+}
+
 static void sun4i_spi_set_cs(struct spi_device *spi, bool enable)
 {
 	struct sun4i_spi *sspi = spi_master_get_devdata(spi->master);
@@ -169,17 +181,12 @@ static int sun4i_spi_transfer_one(struct spi_master *master,
 				  struct spi_transfer *tfr)
 {
 	struct sun4i_spi *sspi = spi_master_get_devdata(master);
+	struct dma_async_tx_descriptor *desc_tx = NULL, *desc_rx = NULL;
 	unsigned int speed, mclk_rate, div, timeout;
 	unsigned int start, end, tx_time;
 	unsigned int tx_len = 0;
+	u32 reg, trigger = 0;
 	int ret = 0;
-	u32 reg;
-
-	/* We don't support transfer larger than the FIFO */
-	if (tfr->len > SUN4I_FIFO_DEPTH)
-		return -EINVAL;
-	if (tfr->tx_buf && tfr->len => SUN4I_FIFO_DEPTH)
-		return -EINVAL;
 
 	reinit_completion(&sspi->done);
 	sspi->tx_buf = tfr->tx_buf;
@@ -277,14 +284,67 @@ static int sun4i_spi_transfer_one(struct spi_master *master,
 	sun4i_spi_write(sspi, SUN4I_BURST_CNT_REG, SUN4I_BURST_CNT(tfr->len));
 	sun4i_spi_write(sspi, SUN4I_XMIT_CNT_REG, SUN4I_XMIT_CNT(tx_len));
 
-	/* Fill the TX FIFO */
-	/* Filling the fifo fully causes timeout for some reason
-	 * at least on spi2 on a10s */
-	sun4i_spi_fill_fifo(sspi, SUN4I_FIFO_DEPTH - 1);
-
 	/* Enable the interrupts */
 	sun4i_spi_write(sspi, SUN4I_INT_CTL_REG, SUN4I_INT_CTL_TC);
 
+	if (sun4i_spi_can_dma(master, spi, tfr)) {
+		dev_dbg(&sspi->master->dev, "Using DMA mode for transfer\n");
+
+		if (sspi->tx_buf) {
+			desc_tx = dmaengine_prep_slave_sg(master->dma_tx,
+					tfr->tx_sg.sgl, tfr->tx_sg.nents,
+					DMA_TO_DEVICE,
+					DMA_PREP_INTERRUPT | DMA_CTRL_ACK);
+			if (!desc_tx) {
+				dev_err(&sspi->master->dev,
+					"Couldn't prepare dma slave\n");
+				return -EIO;
+			}
+
+			trigger |= SUN4I_DMA_CTL_TF_NOT_FULL;
+
+			dmaengine_submit(desc_tx);
+			dma_async_issue_pending(master->dma_tx);
+
+		}
+
+		if (sspi->rx_buf) {
+			desc_rx = dmaengine_prep_slave_sg(master->dma_rx,
+					tfr->rx_sg.sgl, tfr->rx_sg.nents,
+					DMA_FROM_DEVICE,
+					DMA_PREP_INTERRUPT | DMA_CTRL_ACK);
+			if (!desc_rx) {
+				dev_err(&sspi->master->dev,
+					"Couldn't prepare dma slave\n");
+				return -EIO;
+			}
+
+			trigger |= SUN4I_DMA_CTL_RF_READY;
+
+			dmaengine_submit(desc_rx);
+			dma_async_issue_pending(master->dma_rx);
+		}
+
+		/* Enable Dedicated DMA requests */
+		reg = sun4i_spi_read(sspi, SUN4I_CTL_REG);
+		reg |= SUN4I_CTL_DMAMC_DEDICATED;
+		sun4i_spi_write(sspi, SUN4I_CTL_REG, reg);
+		sun4i_spi_write(sspi, SUN4I_DMA_CTL_REG, trigger);
+	} else {
+		dev_dbg(&sspi->master->dev, "Using PIO mode for transfer\n");
+
+		/* Disable DMA requests */
+		reg = sun4i_spi_read(sspi, SUN4I_CTL_REG);
+		sun4i_spi_write(sspi, SUN4I_CTL_REG,
+				reg & ~SUN4I_CTL_DMAMC_DEDICATED);
+		sun4i_spi_write(sspi, SUN4I_DMA_CTL_REG, 0);
+
+		/* Fill the TX FIFO */
+		/* Filling the fifo fully causes timeout for some reason
+		 * at least on spi2 on a10s */
+		sun4i_spi_fill_fifo(sspi, SUN4I_FIFO_DEPTH - 1);
+	}
+
 	/* Start the transfer */
 	reg = sun4i_spi_read(sspi, SUN4I_CTL_REG);
 	sun4i_spi_write(sspi, SUN4I_CTL_REG, reg | SUN4I_CTL_XCH);
@@ -303,7 +363,12 @@ static int sun4i_spi_transfer_one(struct spi_master *master,
 		goto out;
 	}
 
-	sun4i_spi_drain_fifo(sspi, SUN4I_FIFO_DEPTH);
+	if (sun4i_spi_can_dma(master, spi, tfr) && desc_rx) {
+		/* The receive transfer should be the last one to finish */
+		dma_wait_for_async_tx(desc_rx);
+	} else {
+		sun4i_spi_drain_fifo(sspi, SUN4I_FIFO_DEPTH);
+	}
 
 out:
 	sun4i_spi_write(sspi, SUN4I_INT_CTL_REG, 0);
@@ -368,6 +433,7 @@ static int sun4i_spi_runtime_suspend(struct device *dev)
 
 static int sun4i_spi_probe(struct platform_device *pdev)
 {
+	struct dma_slave_config dma_sconfig;
 	struct spi_master *master;
 	struct sun4i_spi *sspi;
 	struct resource	*res;
@@ -403,7 +469,9 @@ static int sun4i_spi_probe(struct platform_device *pdev)
 		goto err_free_master;
 	}
 
+	init_completion(&sspi->done);
 	sspi->master = master;
+	master->can_dma = sun4i_spi_can_dma;
 	master->set_cs = sun4i_spi_set_cs;
 	master->transfer_one = sun4i_spi_transfer_one;
 	master->num_chipselect = 4;
@@ -426,7 +494,45 @@ static int sun4i_spi_probe(struct platform_device *pdev)
 		goto err_free_master;
 	}
 
-	init_completion(&sspi->done);
+	master->dma_tx = dma_request_slave_channel_reason(&pdev->dev, "tx");
+	if (IS_ERR(master->dma_tx)) {
+		dev_err(&pdev->dev, "Unable to acquire DMA channel TX\n");
+		ret = PTR_ERR(master->dma_tx);
+		goto err_free_master;
+	}
+
+	dma_sconfig.direction = DMA_MEM_TO_DEV;
+	dma_sconfig.src_addr_width = DMA_SLAVE_BUSWIDTH_1_BYTE;
+	dma_sconfig.dst_addr_width = DMA_SLAVE_BUSWIDTH_1_BYTE;
+	dma_sconfig.dst_addr = res->start + SUN4I_TXDATA_REG;
+	dma_sconfig.src_maxburst = 1;
+	dma_sconfig.dst_maxburst = 1;
+
+	ret = dmaengine_slave_config(master->dma_tx, &dma_sconfig);
+	if (ret) {
+		dev_err(&pdev->dev, "Unable to configure TX DMA slave\n");
+		goto err_tx_dma_release;
+	}
+
+	master->dma_rx = dma_request_slave_channel_reason(&pdev->dev, "rx");
+	if (IS_ERR(master->dma_rx)) {
+		dev_err(&pdev->dev, "Unable to acquire DMA channel RX\n");
+		ret = PTR_ERR(master->dma_rx);
+		goto err_tx_dma_release;
+	}
+
+	dma_sconfig.direction = DMA_DEV_TO_MEM;
+	dma_sconfig.src_addr_width = DMA_SLAVE_BUSWIDTH_1_BYTE;
+	dma_sconfig.dst_addr_width = DMA_SLAVE_BUSWIDTH_1_BYTE;
+	dma_sconfig.src_addr = res->start + SUN4I_RXDATA_REG;
+	dma_sconfig.src_maxburst = 1;
+	dma_sconfig.dst_maxburst = 1;
+
+	ret = dmaengine_slave_config(master->dma_rx, &dma_sconfig);
+	if (ret) {
+		dev_err(&pdev->dev, "Unable to configure RX DMA slave\n");
+		goto err_rx_dma_release;
+	}
 
 	/*
 	 * This wake-up/shutdown pattern is to be able to have the
@@ -435,7 +541,7 @@ static int sun4i_spi_probe(struct platform_device *pdev)
 	ret = sun4i_spi_runtime_resume(&pdev->dev);
 	if (ret) {
 		dev_err(&pdev->dev, "Couldn't resume the device\n");
-		goto err_free_master;
+		goto err_rx_dma_release;
 	}
 
 	pm_runtime_set_active(&pdev->dev);
@@ -453,6 +559,10 @@ static int sun4i_spi_probe(struct platform_device *pdev)
 err_pm_disable:
 	pm_runtime_disable(&pdev->dev);
 	sun4i_spi_runtime_suspend(&pdev->dev);
+err_rx_dma_release:
+	dma_release_channel(master->dma_rx);
+err_tx_dma_release:
+	dma_release_channel(master->dma_tx);
 err_free_master:
 	spi_master_put(master);
 	return ret;
@@ -460,8 +570,13 @@ err_free_master:
 
 static int sun4i_spi_remove(struct platform_device *pdev)
 {
+	struct spi_master *master = platform_get_drvdata(pdev);
+
 	pm_runtime_disable(&pdev->dev);
 
+	dma_release_channel(master->dma_rx);
+	dma_release_channel(master->dma_tx);
+
 	return 0;
 }
 
-- 
2.1.4



From hramrach at gmail.com  Thu Aug 20 07:19:46 2015
From: hramrach at gmail.com (Michal Suchanek)
Date: 20 Aug 2015 14:19:46 -0000
Subject: [PATCH 5/9] ARM: dts: sun7i: cubieboard2: Enable SPI0
In-Reply-To: <cover.1440080122.git.hramrach@gmail.com>
References: <cover.1440080122.git.hramrach@gmail.com>
Message-ID: <a5a061d98b7ff851866cc668cd8bf8f6fc99d002.1440080122.git.hramrach@gmail.com>

Only SPI0 is enabled. The schematic denotes it as the only SPI bus.
Other SPI pins are reserved for different peripherals.

Signed-off-by: Michal Suchanek <hramrach at gmail.com>
---
 arch/arm/boot/dts/sun7i-a20-cubieboard2.dts | 7 +++++++
 1 file changed, 7 insertions(+)

diff --git a/arch/arm/boot/dts/sun7i-a20-cubieboard2.dts b/arch/arm/boot/dts/sun7i-a20-cubieboard2.dts
index 39a51d5..9861304 100644
--- a/arch/arm/boot/dts/sun7i-a20-cubieboard2.dts
+++ b/arch/arm/boot/dts/sun7i-a20-cubieboard2.dts
@@ -198,6 +198,13 @@
 	status = "okay";
 };
 
+&spi0 {
+	pinctrl-names = "default";
+	pinctrl-0 = <&spi0_pins_a>,
+		    <&spi0_cs0_pins_a>;
+	status = "okay";
+};
+
 &uart0 {
 	pinctrl-names = "default";
 	pinctrl-0 = <&uart0_pins_a>;
-- 
2.1.4



From hramrach at gmail.com  Thu Aug 20 07:19:47 2015
From: hramrach at gmail.com (Michal Suchanek)
Date: 20 Aug 2015 14:19:47 -0000
Subject: [PATCH 6/9] ARM: dts: sunxi: add spi aliases on cubieboards
In-Reply-To: <cover.1440080122.git.hramrach@gmail.com>
References: <cover.1440080122.git.hramrach@gmail.com>
Message-ID: <b2d2cea6f06d54fe1c160fcdcaab7c53585d52d9.1440080122.git.hramrach@gmail.com>

Aliases give nicer device node names.

Signed-off-by: Michal Suchanek <hramrach at gmail.com>
---
 arch/arm/boot/dts/sun4i-a10-cubieboard.dts  | 1 +
 arch/arm/boot/dts/sun7i-a20-cubieboard2.dts | 1 +
 2 files changed, 2 insertions(+)

diff --git a/arch/arm/boot/dts/sun4i-a10-cubieboard.dts b/arch/arm/boot/dts/sun4i-a10-cubieboard.dts
index 9afb4e0..ba02f3b 100644
--- a/arch/arm/boot/dts/sun4i-a10-cubieboard.dts
+++ b/arch/arm/boot/dts/sun4i-a10-cubieboard.dts
@@ -54,6 +54,7 @@
 
 	aliases {
 		serial0 = &uart0;
+		spi0 = &spi0;
 	};
 
 	chosen {
diff --git a/arch/arm/boot/dts/sun7i-a20-cubieboard2.dts b/arch/arm/boot/dts/sun7i-a20-cubieboard2.dts
index 9861304..4c952a2 100644
--- a/arch/arm/boot/dts/sun7i-a20-cubieboard2.dts
+++ b/arch/arm/boot/dts/sun7i-a20-cubieboard2.dts
@@ -56,6 +56,7 @@
 
 	aliases {
 		serial0 = &uart0;
+		spi0 = &spi0;
 	};
 
 	chosen {
-- 
2.1.4



From hramrach at gmail.com  Thu Aug 20 07:19:46 2015
From: hramrach at gmail.com (Michal Suchanek)
Date: 20 Aug 2015 14:19:46 -0000
Subject: [PATCH 2/9] spi: sun4i: fix FIFO limit
In-Reply-To: <cover.1440080122.git.hramrach@gmail.com>
References: <cover.1440080122.git.hramrach@gmail.com>
Message-ID: <a40fbf7ca8bd36f08f5e9d3fb6f6de2454066af7.1440080122.git.hramrach@gmail.com>

When testing SPI without DMA I noticed that filling the FIFO on the
spi controller causes timeout.

Always leave room for one byte in the FIFO.

Signed-off-by: Michal Suchanek <hramrach at gmail.com>
---
 drivers/spi/spi-sun4i.c | 6 +++++-
 1 file changed, 5 insertions(+), 1 deletion(-)

diff --git a/drivers/spi/spi-sun4i.c b/drivers/spi/spi-sun4i.c
index 48532ec..707f61b 100644
--- a/drivers/spi/spi-sun4i.c
+++ b/drivers/spi/spi-sun4i.c
@@ -178,6 +178,8 @@ static int sun4i_spi_transfer_one(struct spi_master *master,
 	/* We don't support transfer larger than the FIFO */
 	if (tfr->len > SUN4I_FIFO_DEPTH)
 		return -EINVAL;
+	if (tfr->tx_buf && tfr->len => SUN4I_FIFO_DEPTH)
+		return -EINVAL;
 
 	reinit_completion(&sspi->done);
 	sspi->tx_buf = tfr->tx_buf;
@@ -271,7 +273,9 @@ static int sun4i_spi_transfer_one(struct spi_master *master,
 	sun4i_spi_write(sspi, SUN4I_XMIT_CNT_REG, SUN4I_XMIT_CNT(tx_len));
 
 	/* Fill the TX FIFO */
-	sun4i_spi_fill_fifo(sspi, SUN4I_FIFO_DEPTH);
+	/* Filling the fifo fully causes timeout for some reason
+	 * at least on spi2 on a10s */
+	sun4i_spi_fill_fifo(sspi, SUN4I_FIFO_DEPTH - 1);
 
 	/* Enable the interrupts */
 	sun4i_spi_write(sspi, SUN4I_INT_CTL_REG, SUN4I_INT_CTL_TC);
-- 
2.1.4



From hramrach at gmail.com  Thu Aug 20 07:15:22 2015
From: hramrach at gmail.com (Michal Suchanek)
Date: Thu, 20 Aug 2015 16:15:22 +0200
Subject: [PATCH 0/9] spi/sunxi patches
Message-ID: <cover.1440080122.git.hramrach@gmail.com>

Hello,

Since the sun4i dmaengine and DT label conversion patches are in this should be
now workable.

 - fix some minor issues with the spi driver
 - add spi dt nodes on some boards
 - include the DMA patch which depends on the dmaengine

Thanks

Michal

Emilio L?pez (1):
  spi: sun4i: add DMA support

Michal Suchanek (8):
  spi: sunxi: fix transfer timeout
  spi: sun4i: fix FIFO limit
  spi: sunxi: check that transfer speed is non-zero
  ARM: dts: sun7i: cubieboard2: Enable SPI0
  ARM: dts: sunxi: add spi aliases on cubieboards
  ARM: dts: sun5i: add SPI pins on A13 and A10s
  ARM: dts: sunxi: A10s Olinuxino Micro: add spi2.
  ARM: dts: sunxi: Add SPI aliases on A10s Olinuxino.

 arch/arm/boot/dts/sun4i-a10-cubieboard.dts       |   1 +
 arch/arm/boot/dts/sun5i-a10s-olinuxino-micro.dts |  10 ++
 arch/arm/boot/dts/sun5i-a10s.dtsi                |  21 +++
 arch/arm/boot/dts/sun5i.dtsi                     |  49 +++++++
 arch/arm/boot/dts/sun7i-a20-cubieboard2.dts      |   8 ++
 drivers/spi/spi-sun4i.c                          | 166 ++++++++++++++++++++---
 drivers/spi/spi-sun6i.c                          |  25 +++-
 7 files changed, 257 insertions(+), 23 deletions(-)

-- 
2.1.4



From hramrach at gmail.com  Thu Aug 20 07:19:46 2015
From: hramrach at gmail.com (Michal Suchanek)
Date: 20 Aug 2015 14:19:46 -0000
Subject: [PATCH 3/9] spi: sunxi: check that transfer speed is non-zero
In-Reply-To: <cover.1440080122.git.hramrach@gmail.com>
References: <cover.1440080122.git.hramrach@gmail.com>
Message-ID: <3688fab67e7cdc7bcbff73dfd6b0fcdcc4e79eb6.1440080122.git.hramrach@gmail.com>

When the maximum transfer speed is not set for a SPI slave the value
remains 0 and the code in sunxi SPI divides by it. Use an arbitrary
speed instead in that case.

Signed-off-by: Michal Suchanek <hramrach at gmail.com>
---
 drivers/spi/spi-sun4i.c | 15 ++++++++++-----
 drivers/spi/spi-sun6i.c | 15 ++++++++++-----
 2 files changed, 20 insertions(+), 10 deletions(-)

diff --git a/drivers/spi/spi-sun4i.c b/drivers/spi/spi-sun4i.c
index 707f61b..4dda366 100644
--- a/drivers/spi/spi-sun4i.c
+++ b/drivers/spi/spi-sun4i.c
@@ -169,7 +169,7 @@ static int sun4i_spi_transfer_one(struct spi_master *master,
 				  struct spi_transfer *tfr)
 {
 	struct sun4i_spi *sspi = spi_master_get_devdata(master);
-	unsigned int mclk_rate, div, timeout;
+	unsigned int speed, mclk_rate, div, timeout;
 	unsigned int start, end, tx_time;
 	unsigned int tx_len = 0;
 	int ret = 0;
@@ -230,10 +230,15 @@ static int sun4i_spi_transfer_one(struct spi_master *master,
 
 	sun4i_spi_write(sspi, SUN4I_CTL_REG, reg);
 
+	speed = spi->max_speed_hz;
+	if (!speed) {
+		speed = 100000;
+		dev_warn(&spi->dev, "SPI speed not set. Using %uHz.", speed);
+	}
 	/* Ensure that we have a parent clock fast enough */
 	mclk_rate = clk_get_rate(sspi->mclk);
-	if (mclk_rate < (2 * spi->max_speed_hz)) {
-		clk_set_rate(sspi->mclk, 2 * spi->max_speed_hz);
+	if (mclk_rate < (2 * speed)) {
+		clk_set_rate(sspi->mclk, 2 * speed);
 		mclk_rate = clk_get_rate(sspi->mclk);
 	}
 
@@ -251,14 +256,14 @@ static int sun4i_spi_transfer_one(struct spi_master *master,
 	 * First try CDR2, and if we can't reach the expected
 	 * frequency, fall back to CDR1.
 	 */
-	div = mclk_rate / (2 * spi->max_speed_hz);
+	div = mclk_rate / (2 * speed);
 	if (div <= (SUN4I_CLK_CTL_CDR2_MASK + 1)) {
 		if (div > 0)
 			div--;
 
 		reg = SUN4I_CLK_CTL_CDR2(div) | SUN4I_CLK_CTL_DRS;
 	} else {
-		div = ilog2(mclk_rate) - ilog2(spi->max_speed_hz);
+		div = ilog2(mclk_rate) - ilog2(speed);
 		reg = SUN4I_CLK_CTL_CDR1(div);
 	}
 
diff --git a/drivers/spi/spi-sun6i.c b/drivers/spi/spi-sun6i.c
index 3d0f66c..cf6a33e 100644
--- a/drivers/spi/spi-sun6i.c
+++ b/drivers/spi/spi-sun6i.c
@@ -159,7 +159,7 @@ static int sun6i_spi_transfer_one(struct spi_master *master,
 				  struct spi_transfer *tfr)
 {
 	struct sun6i_spi *sspi = spi_master_get_devdata(master);
-	unsigned int mclk_rate, div, timeout;
+	unsigned int speed, mclk_rate, div, timeout;
 	unsigned int tx_len = 0;
 	int ret = 0;
 	unsigned int start, end, tx_time;
@@ -216,10 +216,15 @@ static int sun6i_spi_transfer_one(struct spi_master *master,
 
 	sun6i_spi_write(sspi, SUN6I_TFR_CTL_REG, reg);
 
+	speed = spi->max_speed_hz;
+	if(!speed) {
+		speed = 100000;
+		dev_warn(&spi->dev, "SPI speed not set. Using %uHz.", speed);
+	}
 	/* Ensure that we have a parent clock fast enough */
 	mclk_rate = clk_get_rate(sspi->mclk);
-	if (mclk_rate < (2 * spi->max_speed_hz)) {
-		clk_set_rate(sspi->mclk, 2 * spi->max_speed_hz);
+	if (mclk_rate < (2 * speed)) {
+		clk_set_rate(sspi->mclk, 2 * speed);
 		mclk_rate = clk_get_rate(sspi->mclk);
 	}
 
@@ -237,14 +242,14 @@ static int sun6i_spi_transfer_one(struct spi_master *master,
 	 * First try CDR2, and if we can't reach the expected
 	 * frequency, fall back to CDR1.
 	 */
-	div = mclk_rate / (2 * spi->max_speed_hz);
+	div = mclk_rate / (2 * speed);
 	if (div <= (SUN6I_CLK_CTL_CDR2_MASK + 1)) {
 		if (div > 0)
 			div--;
 
 		reg = SUN6I_CLK_CTL_CDR2(div) | SUN6I_CLK_CTL_DRS;
 	} else {
-		div = ilog2(mclk_rate) - ilog2(spi->max_speed_hz);
+		div = ilog2(mclk_rate) - ilog2(speed);
 		reg = SUN6I_CLK_CTL_CDR1(div);
 	}
 
-- 
2.1.4



From hramrach at gmail.com  Thu Aug 20 07:19:48 2015
From: hramrach at gmail.com (Michal Suchanek)
Date: 20 Aug 2015 14:19:48 -0000
Subject: [PATCH 8/9] ARM: dts: sunxi: A10s Olinuxino Micro: add spi2.
In-Reply-To: <cover.1440080122.git.hramrach@gmail.com>
References: <cover.1440080122.git.hramrach@gmail.com>
Message-ID: <c479a62f6d28bbda65c23fc00a0a8499cf639b76.1440080122.git.hramrach@gmail.com>

spi2 is exposed on the UEXT connector.

Signed-off-by: Michal Suchanek <hramrach at gmail.com>
---
 arch/arm/boot/dts/sun5i-a10s-olinuxino-micro.dts | 7 +++++++
 1 file changed, 7 insertions(+)

diff --git a/arch/arm/boot/dts/sun5i-a10s-olinuxino-micro.dts b/arch/arm/boot/dts/sun5i-a10s-olinuxino-micro.dts
index a7e19e4..b546fc2 100644
--- a/arch/arm/boot/dts/sun5i-a10s-olinuxino-micro.dts
+++ b/arch/arm/boot/dts/sun5i-a10s-olinuxino-micro.dts
@@ -185,6 +185,13 @@
 	status = "okay";
 };
 
+&spi2 {
+	pinctrl-names = "default";
+	pinctrl-0 = <&spi2_pins_a>,
+		    <&spi2_cs0_pins_a>;
+	status = "okay";
+};
+
 &ohci0 {
 	status = "okay";
 };
-- 
2.1.4



From hramrach at gmail.com  Thu Aug 20 07:19:47 2015
From: hramrach at gmail.com (Michal Suchanek)
Date: 20 Aug 2015 14:19:47 -0000
Subject: [PATCH 7/9] ARM: dts: sun5i: add SPI pins on A13 and A10s
In-Reply-To: <cover.1440080122.git.hramrach@gmail.com>
References: <cover.1440080122.git.hramrach@gmail.com>
Message-ID: <90730047894f6ec84cd70062a27b7085c2016260.1440080122.git.hramrach@gmail.com>

According to datasheet some pins are available on A10s only while others
are shared with A13.

Signed-off-by: Michal Suchanek <hramrach at gmail.com>
---
This time add all spi pins and make the CS pins separate as is seen with
current sun4i DTs
---
 arch/arm/boot/dts/sun5i-a10s.dtsi | 21 +++++++++++++++++
 arch/arm/boot/dts/sun5i.dtsi      | 49 +++++++++++++++++++++++++++++++++++++++
 2 files changed, 70 insertions(+)

diff --git a/arch/arm/boot/dts/sun5i-a10s.dtsi b/arch/arm/boot/dts/sun5i-a10s.dtsi
index f11efb7..d9610fa 100644
--- a/arch/arm/boot/dts/sun5i-a10s.dtsi
+++ b/arch/arm/boot/dts/sun5i-a10s.dtsi
@@ -201,6 +201,27 @@
 		allwinner,drive = <SUN4I_PINCTRL_30_MA>;
 		allwinner,pull = <SUN4I_PINCTRL_NO_PULL>;
 	};
+
+	spi1_cs1_pins_a: spi1_cs1 at 0 {
+		allwinner,pins = "PG13";
+		allwinner,function = "spi1";
+		allwinner,drive = <SUN4I_PINCTRL_10_MA>;
+		allwinner,pull = <SUN4I_PINCTRL_NO_PULL>;
+	};
+
+	spi2_pins_a: spi2 at 0 {
+		allwinner,pins = "PB12", "PB13", "PB14";
+		allwinner,function = "spi1";
+		allwinner,drive = <SUN4I_PINCTRL_10_MA>;
+		allwinner,pull = <SUN4I_PINCTRL_NO_PULL>;
+	};
+
+	spi2_cs0_pins_a: spi2_cs0 at 0 {
+		allwinner,pins = "PB11";
+		allwinner,function = "spi1";
+		allwinner,drive = <SUN4I_PINCTRL_10_MA>;
+		allwinner,pull = <SUN4I_PINCTRL_NO_PULL>;
+	};
 };
 
 &sram_a {
diff --git a/arch/arm/boot/dts/sun5i.dtsi b/arch/arm/boot/dts/sun5i.dtsi
index 54b0978..7d32d49 100644
--- a/arch/arm/boot/dts/sun5i.dtsi
+++ b/arch/arm/boot/dts/sun5i.dtsi
@@ -516,6 +516,55 @@
 				allwinner,drive = <SUN4I_PINCTRL_30_MA>;
 				allwinner,pull = <SUN4I_PINCTRL_PULL_UP>;
 			};
+
+			spi0_pins_a: spi0 at 0 {
+				allwinner,pins = "PC00", "PC01", "PC02";
+				allwinner,function = "spi0";
+				allwinner,drive = <SUN4I_PINCTRL_10_MA>;
+				allwinner,pull = <SUN4I_PINCTRL_NO_PULL>;
+			};
+
+			spi0_cs0_pins_a: spi0_cs0 at 0 {
+				allwinner,pins = "PC03";
+				allwinner,function = "spi0";
+				allwinner,drive = <SUN4I_PINCTRL_10_MA>;
+				allwinner,pull = <SUN4I_PINCTRL_NO_PULL>;
+			};
+
+			spi1_pins_a: spi1 at 0 {
+				allwinner,pins = "PG10", "PG11", "PG12";
+				allwinner,function = "spi1";
+				allwinner,drive = <SUN4I_PINCTRL_10_MA>;
+				allwinner,pull = <SUN4I_PINCTRL_NO_PULL>;
+			};
+
+			spi1_cs0_pins_a: spi1_cs0 at 0 {
+				allwinner,pins = "PG09";
+				allwinner,function = "spi1";
+				allwinner,drive = <SUN4I_PINCTRL_10_MA>;
+				allwinner,pull = <SUN4I_PINCTRL_NO_PULL>;
+			};
+
+			spi2_pins_b: spi2 at 1 {
+				allwinner,pins = "PE01", "PE02", "PE03";
+				allwinner,function = "spi2";
+				allwinner,drive = <SUN4I_PINCTRL_10_MA>;
+				allwinner,pull = <SUN4I_PINCTRL_NO_PULL>;
+			};
+
+			spi2_cs0_pins_b: spi2_cs1 at 1 {
+				allwinner,pins = "PE00";
+				allwinner,function = "spi2";
+				allwinner,drive = <SUN4I_PINCTRL_10_MA>;
+				allwinner,pull = <SUN4I_PINCTRL_NO_PULL>;
+			};
+
+			spi2_cs1_pins_a: spi2_cs1 at 0 {
+				allwinner,pins = "PB10";
+				allwinner,function = "spi2";
+				allwinner,drive = <SUN4I_PINCTRL_10_MA>;
+				allwinner,pull = <SUN4I_PINCTRL_NO_PULL>;
+			};
 		};
 
 		timer at 01c20c00 {
-- 
2.1.4



From hramrach at gmail.com  Thu Aug 20 07:24:02 2015
From: hramrach at gmail.com (Michal Suchanek)
Date: Thu, 20 Aug 2015 16:24:02 +0200
Subject: [linux-sunxi] [PATCH 4/9] spi: sun4i: add DMA support
In-Reply-To: <ccf776869b0d7fe2c78bcc41d6cd1896bf732296.1440080122.git.hramrach@gmail.com>
References: <cover.1440080122.git.hramrach@gmail.com>
 <ccf776869b0d7fe2c78bcc41d6cd1896bf732296.1440080122.git.hramrach@gmail.com>
Message-ID: <CAOMqctSj0evKAbUvG08N1f24BmSM1mZrRyjDas3UCZnsy1CCpQ@mail.gmail.com>

On 20 August 2015 at 16:19, Emilio L?pez <emilio at elopez.com.ar> wrote:
> From: Emilio L?pez <emilio at elopez.com.ar>

Something went wrong with overriding the headers

Sorry

Michal


From daniel.lezcano at linaro.org  Thu Aug 20 07:28:26 2015
From: daniel.lezcano at linaro.org (Daniel Lezcano)
Date: Thu, 20 Aug 2015 16:28:26 +0200
Subject: [PATCH v2 1/5] clocksource: mediatek: do not enable GPT_CLK_EVT
 when setup
In-Reply-To: <1439820602.3414.12.camel@mtksdaap41>
References: <CAGS+omD8k_Cfxv3bYyjmjtLbiavo-WmJPn0Z-CBhN_nnv65Tag@mail.gmail.com>	
 <1437552878-3684-1-git-send-email-yingjoe.chen@mediatek.com>	
 <55CC56C4.8080201@linaro.org> <1439820602.3414.12.camel@mtksdaap41>
Message-ID: <55D5E40A.6080904@linaro.org>

On 08/17/2015 04:10 PM, Yingjoe Chen wrote:
> On Thu, 2015-08-13 at 10:35 +0200, Daniel Lezcano wrote:
>> On 07/22/2015 10:14 AM, Yingjoe Chen wrote:
>>> Spurious mtk timer interrupt is noticed at boot and cause kernel
>>> crash. It seems if GPT is enabled, it will latch irq status even
>>> when its IRQ is disabled.

It "seems" ?

>>> When irq is enabled afterward, we see
>>> spurious interrupt.

Doesn't have the firmware something to do with that ?

I have a mtk 8173 board I can use next week. How do you reproduce the 
issue ?

>>> Change init flow to only enable GPT_CLK_SRC at mtk_timer_init.
>>>
>>> Acked-by: Matthias Brugger <matthias.bgg at gmail.com>
>>> Reviewed-by: Daniel Kurtz <djkurtz at chromium.org>
>>> Signed-off-by: Yingjoe Chen <yingjoe.chen at mediatek.com>
>>> ---
>>>
>>> Update to my patch [1], added __init as Daniel suggest. This is the
>>> only patch that need to change in that series, so I only sent this one.
>>>
>>> http://lists.infradead.org/pipermail/linux-mediatek/2015-July/001545.html
>>>
>>>    drivers/clocksource/mtk_timer.c | 16 ++++++++++------
>>>    1 file changed, 10 insertions(+), 6 deletions(-)
>>>
>>> diff --git a/drivers/clocksource/mtk_timer.c b/drivers/clocksource/mtk_timer.c
>>> index 68ab423..2ba5b66 100644
>>> --- a/drivers/clocksource/mtk_timer.c
>>> +++ b/drivers/clocksource/mtk_timer.c
>>> @@ -156,9 +156,11 @@ static void mtk_timer_global_reset(struct mtk_clock_event_device *evt)
>>>    	writel(0x3f, evt->gpt_base + GPT_IRQ_ACK_REG);
>>>    }
>>>
>>> -static void
>>> -mtk_timer_setup(struct mtk_clock_event_device *evt, u8 timer, u8 option)
>>> +static void __init mtk_timer_setup(struct mtk_clock_event_device *evt,
>>> +				   u8 timer, u8 option, bool enable)
>>>    {
>>> +	u32 val;
>>> +
>>>    	writel(TIMER_CTRL_CLEAR | TIMER_CTRL_DISABLE,
>>>    		evt->gpt_base + TIMER_CTRL_REG(timer));
>>>
>>> @@ -167,8 +169,10 @@ mtk_timer_setup(struct mtk_clock_event_device *evt, u8 timer, u8 option)
>>>
>>>    	writel(0x0, evt->gpt_base + TIMER_CMP_REG(timer));
>>>
>>> -	writel(TIMER_CTRL_OP(option) | TIMER_CTRL_ENABLE,
>>> -			evt->gpt_base + TIMER_CTRL_REG(timer));
>>> +	val = TIMER_CTRL_OP(option);
>>> +	if (enable)
>>> +		val |= TIMER_CTRL_ENABLE;
>>> +	writel(val, evt->gpt_base + TIMER_CTRL_REG(timer));
>>
>> Instead of the 'enable' new option, I prefer a test with 'timer' with a
>> comment:
>>
>> 	/*
>> 	 * the timer hw is broken in that way ... bla bla, so we only
>> 	 * enable the clocksource ...
>> 	 */
>> 	if (timer == GPT_CLK_SRC)
>> 		val |= TIMER_CTRL_ENABLE;
>
> Hi Daniel,
>
> Thanks for your review.
> Since this bug happens to anyone using interrupt,

Can you elaborate ? I don't get the point.

> I'm not sure checking
> timer and only enable it for GPT_CLK_SRC is easier to read. Anyway, I'll
> change to this in next version.
>> That said, can you have a look at commit 1096be08 ?
>> "clockevents: sun5i: Fix setup_irq init sequence"
>>
>> first and check if moving the interrupt request after the
>> clockevents_config_and_register could fix your issue.
>
> I've tested this before, see:
>
> http://lists.infradead.org/pipermail/linux-mediatek/2015-May/000539.html
> http://lists.infradead.org/pipermail/linux-mediatek/2015-May/000551.html

I could take or ack this patch trusting it fixes the issue but there are 
some points that need clarifications.

  - Does the spurious interrupt occurs *every* time ? at each boot ?

The previous patches were supposed to fix the issue but they actually 
didn't. So how is tested the patch ?

Regarding the different fixes for this problem, it sounds like you are 
proceeding by trial and error.

Please give a more detailed analysis of the problem and especially check 
the timer is not altered by the firmware leaving it in a transient state 
or whatever.

   -- Daniel

-- 
  <http://www.linaro.org/> Linaro.org ? Open source software for ARM SoCs

Follow Linaro:  <http://www.facebook.com/pages/Linaro> Facebook |
<http://twitter.com/#!/linaroorg> Twitter |
<http://www.linaro.org/linaro-blog/> Blog



From hramrach at gmail.com  Thu Aug 20 07:19:48 2015
From: hramrach at gmail.com (Michal Suchanek)
Date: 20 Aug 2015 14:19:48 -0000
Subject: [PATCH 9/9] ARM: dts: sunxi: Add SPI aliases on A10s Olinuxino.
In-Reply-To: <cover.1440080122.git.hramrach@gmail.com>
References: <cover.1440080122.git.hramrach@gmail.com>
Message-ID: <de1151651088bd3acfd279785412ed9537023472.1440080122.git.hramrach@gmail.com>

SPI aliases give nicer spidev device node names.

Signed-off-by: Michal Suchanek <hramrach at gmail.com>
---
 arch/arm/boot/dts/sun5i-a10s-olinuxino-micro.dts | 3 +++
 1 file changed, 3 insertions(+)

diff --git a/arch/arm/boot/dts/sun5i-a10s-olinuxino-micro.dts b/arch/arm/boot/dts/sun5i-a10s-olinuxino-micro.dts
index b546fc2..1a0e0c0 100644
--- a/arch/arm/boot/dts/sun5i-a10s-olinuxino-micro.dts
+++ b/arch/arm/boot/dts/sun5i-a10s-olinuxino-micro.dts
@@ -58,6 +58,9 @@
 		serial0 = &uart0;
 		serial1 = &uart2;
 		serial2 = &uart3;
+		spi0 = &spi0;
+		spi1 = &spi1;
+		spi2 = &spi2;
 	};
 
 	chosen {
-- 
2.1.4



From maxime.ripard at free-electrons.com  Thu Aug 20 07:43:07 2015
From: maxime.ripard at free-electrons.com (Maxime Ripard)
Date: Thu, 20 Aug 2015 16:43:07 +0200
Subject: [PATCH 1/9] spi: sunxi: fix transfer timeout
In-Reply-To: <0e0b52774a48ddb71dc8095b66942451cd31ff7d.1440080122.git.hramrach@gmail.com>
References: <cover.1440080122.git.hramrach@gmail.com>
 <0e0b52774a48ddb71dc8095b66942451cd31ff7d.1440080122.git.hramrach@gmail.com>
Message-ID: <20150820144307.GT30520@lukather>

On Thu, Aug 20, 2015 at 02:19:45PM -0000, Michal Suchanek wrote:
> The trasfer timeout is fixed at 1000 ms. Reading a 4Mbyte flash over
> 1MHz SPI bus takes way longer than that. Calculate the timeout from the
> actual time the transfer is supposed to take and multiply by 2 for good
> measure.
> 
> Signed-off-by: Michal Suchanek <hramrach at gmail.com>
> ---
>  drivers/spi/spi-sun4i.c | 10 +++++++++-
>  drivers/spi/spi-sun6i.c | 10 +++++++++-
>  2 files changed, 18 insertions(+), 2 deletions(-)
> 
> diff --git a/drivers/spi/spi-sun4i.c b/drivers/spi/spi-sun4i.c
> index fbb0a4d..48532ec 100644
> --- a/drivers/spi/spi-sun4i.c
> +++ b/drivers/spi/spi-sun4i.c
> @@ -170,6 +170,7 @@ static int sun4i_spi_transfer_one(struct spi_master *master,
>  {
>  	struct sun4i_spi *sspi = spi_master_get_devdata(master);
>  	unsigned int mclk_rate, div, timeout;
> +	unsigned int start, end, tx_time;
>  	unsigned int tx_len = 0;
>  	int ret = 0;
>  	u32 reg;
> @@ -279,9 +280,16 @@ static int sun4i_spi_transfer_one(struct spi_master *master,
>  	reg = sun4i_spi_read(sspi, SUN4I_CTL_REG);
>  	sun4i_spi_write(sspi, SUN4I_CTL_REG, reg | SUN4I_CTL_XCH);
>  
> +	tx_time = max_t(int, tfr->len * 8 * 2 / (speed / 1000), 100);
> +	start = jiffies;
>  	timeout = wait_for_completion_timeout(&sspi->done,
> -					      msecs_to_jiffies(1000));
> +					      msecs_to_jiffies(tx_time));
> +	end = jiffies;
>  	if (!timeout) {
> +		dev_warn(&master->dev,
> +			 "%s: timeout transferring %u bytes@%iHz for %i(%i)ms",
> +			 dev_name(&spi->dev), tfr->len, speed,
> +			 jiffies_to_msecs(end - start), tx_time);

Timeout already contains the number of jiffies elapsed (and I'm not
sure anyone reading that message would get that the last number is
actually the maximum timeout).

Maxime

-- 
Maxime Ripard, Free Electrons
Embedded Linux, Kernel and Android engineering
http://free-electrons.com
-------------- next part --------------
A non-text attachment was scrubbed...
Name: signature.asc
Type: application/pgp-signature
Size: 819 bytes
Desc: Digital signature
URL: <http://lists.infradead.org/pipermail/linux-arm-kernel/attachments/20150820/ca920d73/attachment.sig>

From maxime.ripard at free-electrons.com  Thu Aug 20 07:45:52 2015
From: maxime.ripard at free-electrons.com (Maxime Ripard)
Date: Thu, 20 Aug 2015 16:45:52 +0200
Subject: [PATCH 2/9] spi: sun4i: fix FIFO limit
In-Reply-To: <a40fbf7ca8bd36f08f5e9d3fb6f6de2454066af7.1440080122.git.hramrach@gmail.com>
References: <cover.1440080122.git.hramrach@gmail.com>
 <a40fbf7ca8bd36f08f5e9d3fb6f6de2454066af7.1440080122.git.hramrach@gmail.com>
Message-ID: <20150820144552.GU30520@lukather>

On Thu, Aug 20, 2015 at 02:19:46PM -0000, Michal Suchanek wrote:
> When testing SPI without DMA I noticed that filling the FIFO on the
> spi controller causes timeout.
> 
> Always leave room for one byte in the FIFO.
> 
> Signed-off-by: Michal Suchanek <hramrach at gmail.com>
> ---
>  drivers/spi/spi-sun4i.c | 6 +++++-
>  1 file changed, 5 insertions(+), 1 deletion(-)
> 
> diff --git a/drivers/spi/spi-sun4i.c b/drivers/spi/spi-sun4i.c
> index 48532ec..707f61b 100644
> --- a/drivers/spi/spi-sun4i.c
> +++ b/drivers/spi/spi-sun4i.c
> @@ -178,6 +178,8 @@ static int sun4i_spi_transfer_one(struct spi_master *master,
>  	/* We don't support transfer larger than the FIFO */
>  	if (tfr->len > SUN4I_FIFO_DEPTH)
>  		return -EINVAL;
> +	if (tfr->tx_buf && tfr->len => SUN4I_FIFO_DEPTH)
> +		return -EINVAL;

Shouldn't you fix the condition just above instead?

>  
>  	reinit_completion(&sspi->done);
>  	sspi->tx_buf = tfr->tx_buf;
> @@ -271,7 +273,9 @@ static int sun4i_spi_transfer_one(struct spi_master *master,
>  	sun4i_spi_write(sspi, SUN4I_XMIT_CNT_REG, SUN4I_XMIT_CNT(tx_len));
>  
>  	/* Fill the TX FIFO */
> -	sun4i_spi_fill_fifo(sspi, SUN4I_FIFO_DEPTH);
> +	/* Filling the fifo fully causes timeout for some reason
> +	 * at least on spi2 on a10s */

Please use the proper comment style. And it only happens on that
particular SPI controller and SoC combination?

> +	sun4i_spi_fill_fifo(sspi, SUN4I_FIFO_DEPTH - 1);
>  
>  	/* Enable the interrupts */
>  	sun4i_spi_write(sspi, SUN4I_INT_CTL_REG, SUN4I_INT_CTL_TC);
> -- 
> 2.1.4
> 

-- 
Maxime Ripard, Free Electrons
Embedded Linux, Kernel and Android engineering
http://free-electrons.com
-------------- next part --------------
A non-text attachment was scrubbed...
Name: signature.asc
Type: application/pgp-signature
Size: 819 bytes
Desc: Digital signature
URL: <http://lists.infradead.org/pipermail/linux-arm-kernel/attachments/20150820/b3e270e9/attachment.sig>

From maxime.ripard at free-electrons.com  Thu Aug 20 07:48:36 2015
From: maxime.ripard at free-electrons.com (Maxime Ripard)
Date: Thu, 20 Aug 2015 16:48:36 +0200
Subject: [PATCH 3/9] spi: sunxi: check that transfer speed is non-zero
In-Reply-To: <3688fab67e7cdc7bcbff73dfd6b0fcdcc4e79eb6.1440080122.git.hramrach@gmail.com>
References: <cover.1440080122.git.hramrach@gmail.com>
 <3688fab67e7cdc7bcbff73dfd6b0fcdcc4e79eb6.1440080122.git.hramrach@gmail.com>
Message-ID: <20150820144836.GV30520@lukather>

On Thu, Aug 20, 2015 at 02:19:46PM -0000, Michal Suchanek wrote:
> When the maximum transfer speed is not set for a SPI slave the value
> remains 0 and the code in sunxi SPI divides by it. Use an arbitrary
> speed instead in that case.
> 
> Signed-off-by: Michal Suchanek <hramrach at gmail.com>

spi->max_speed_hz is set using the spi-max-frequency property, and
spi->will error out if that property isn't set. What am I missing?

Maxime

-- 
Maxime Ripard, Free Electrons
Embedded Linux, Kernel and Android engineering
http://free-electrons.com
-------------- next part --------------
A non-text attachment was scrubbed...
Name: signature.asc
Type: application/pgp-signature
Size: 819 bytes
Desc: Digital signature
URL: <http://lists.infradead.org/pipermail/linux-arm-kernel/attachments/20150820/45a045ea/attachment-0001.sig>

From Shenwei.Wang at freescale.com  Thu Aug 20 07:48:43 2015
From: Shenwei.Wang at freescale.com (Shenwei Wang)
Date: Thu, 20 Aug 2015 14:48:43 +0000
Subject: [PATCH v3 1/1] misc: sram: add dev_pm_ops to support module power
 gate
In-Reply-To: <CY1PR0301MB08436DD71E719BC9622879B3837E0@CY1PR0301MB0843.namprd03.prod.outlook.com>
References: <1438272681-29338-1-git-send-email-shenwei.wang@freescale.com>
 <CY1PR0301MB08436DD71E719BC9622879B3837E0@CY1PR0301MB0843.namprd03.prod.outlook.com>
Message-ID: <CY1PR0301MB08436F2AB0D5D78043CCE2A083660@CY1PR0301MB0843.namprd03.prod.outlook.com>

3rd Ping.

Shenwei

> -----Original Message-----
> From: linux-arm-kernel [mailto:linux-arm-kernel-bounces at lists.infradead.org] On
> Behalf Of Shenwei Wang
> Sent: 2015?8?12? 10:47
> To: gregkh at linuxfoundation.org; arnd at arndb.de
> Cc: Huang Yongcai-B20788; linux-arm-kernel at lists.infradead.org
> Subject: RE: [PATCH v3 1/1] misc: sram: add dev_pm_ops to support module
> power gate
> 
> 2nd Ping.
> 
> Regards,
> Shenwei
> 
> > -----Original Message-----
> > From: linux-arm-kernel
> > [mailto:linux-arm-kernel-bounces at lists.infradead.org] On Behalf Of
> > Shenwei Wang
> > Sent: 2015?7?30? 11:11
> > To: gregkh at linuxfoundation.org; arnd at arndb.de
> > Cc: Huang Yongcai-B20788; linux-arm-kernel at lists.infradead.org
> > Subject: [PATCH v3 1/1] misc: sram: add dev_pm_ops to support module
> > power gate
> >
> > When system goes into low power states like SUSPEND_MEM and
> > HIBERNATION, the hardware IP block may be powered off to reduce the power
> consumption.
> > This power down will lost all the data inside the ram. This patch
> > added the dev_pm_ops and implemented two callbacks: suspend_noirq and
> > resume_noirq, which will save the data in the on-chip-ram right before
> > power down and restore it after system resumes.
> >
> > A new property string named "can-power-gate" is added to the
> > devicetree bindings too.
> >
> > Signed-off-by: Shenwei Wang <shenwei.wang at freescale.com>
> > Signed-off-by: Anson Huang <b20788 at freescale.com>
> > ---
> > Change log:
> >
> > PATCH v3
> > 	Removed the unnecessary clk_enable/clk_disable.
> >
> > PATCH v2
> > 	Use vmalloc to allocate the SRAM backup memory.
> > 	Code clean up.
> >
> >  Documentation/devicetree/bindings/misc/sram.txt |  2 ++
> >  drivers/misc/sram.c                             | 42
> > +++++++++++++++++++++++++
> >  2 files changed, 44 insertions(+)
> >
> > diff --git a/Documentation/devicetree/bindings/misc/sram.txt
> > b/Documentation/devicetree/bindings/misc/sram.txt
> > index 36cbe5a..1170086 100644
> > --- a/Documentation/devicetree/bindings/misc/sram.txt
> > +++ b/Documentation/devicetree/bindings/misc/sram.txt
> > @@ -33,6 +33,8 @@ Optional properties in the area nodes:
> >
> >  - compatible : standard definition, should contain a vendor specific string
> >                 in the form <vendor>,[<device>-]<usage>
> > +- can-power-gate: a property to tell the driver that the sram can support
> > +		power gate
> >
> >  Example:
> >
> > diff --git a/drivers/misc/sram.c b/drivers/misc/sram.c index
> > 15c33cc..db9f1fa
> > 100644
> > --- a/drivers/misc/sram.c
> > +++ b/drivers/misc/sram.c
> > @@ -30,7 +30,9 @@
> >
> >  struct sram_dev {
> >  	struct device *dev;
> > +	void *power_off_save;
> >  	void __iomem *virt_base;
> > +	u32 size;
> >
> >  	struct gen_pool *pool;
> >  	struct clk *clk;
> > @@ -156,6 +158,33 @@ static int sram_reserve_regions(struct sram_dev
> > *sram, struct resource *res)
> >  	return ret;
> >  }
> >
> > +static int sram_suspend_noirq(struct device *dev) {
> > +	struct platform_device *pdev = to_platform_device(dev);
> > +	struct sram_dev *sram = platform_get_drvdata(pdev);
> > +
> > +	if (!sram->power_off_save)
> > +		return 0;
> > +
> > +	/* Save necessary regs */
> > +	memcpy(sram->power_off_save, sram->virt_base, sram->size);
> > +
> > +	return 0;
> > +}
> > +
> > +static int sram_resume_noirq(struct device *dev) {
> > +	struct platform_device *pdev = to_platform_device(dev);
> > +	struct sram_dev *sram = platform_get_drvdata(pdev);
> > +
> > +	if (!sram->power_off_save)
> > +		return 0;
> > +
> > +	memcpy(sram->virt_base, sram->power_off_save, sram->size);
> > +
> > +	return 0;
> > +}
> > +
> >  static int sram_probe(struct platform_device *pdev)  {
> >  	struct sram_dev *sram;
> > @@ -176,6 +205,7 @@ static int sram_probe(struct platform_device *pdev)
> >  	}
> >
> >  	size = resource_size(res);
> > +	sram->size = size;
> >
> >  	if (!devm_request_mem_region(sram->dev, res->start, size, pdev->name)) {
> >  		dev_err(sram->dev, "could not request region for resource\n"); @@
> > -203,6 +233,9 @@ static int sram_probe(struct platform_device *pdev)
> >
> >  	platform_set_drvdata(pdev, sram);
> >
> > +	if (of_property_read_bool(pdev->dev.of_node, "can-power-gate"))
> > +		sram->power_off_save = vmalloc(size);
> > +
> >  	dev_dbg(sram->dev, "SRAM pool: %zu KiB @ 0x%p\n",
> >  		gen_pool_size(sram->pool) / 1024, sram->virt_base);
> >
> > @@ -219,6 +252,9 @@ static int sram_remove(struct platform_device *pdev)
> >  	if (sram->clk)
> >  		clk_disable_unprepare(sram->clk);
> >
> > +	if (sram->power_off_save)
> > +		vfree(sram->power_off_save);
> > +
> >  	return 0;
> >  }
> >
> > @@ -229,10 +265,16 @@ static const struct of_device_id sram_dt_ids[] =
> > {  }; #endif
> >
> > +static const struct dev_pm_ops sram_pm_ops = {
> > +	.suspend_noirq = sram_suspend_noirq,
> > +	.resume_noirq = sram_resume_noirq,
> > +};
> > +
> >  static struct platform_driver sram_driver = {
> >  	.driver = {
> >  		.name = "sram",
> >  		.of_match_table = of_match_ptr(sram_dt_ids),
> > +		.pm	= &sram_pm_ops,
> >  	},
> >  	.probe = sram_probe,
> >  	.remove = sram_remove,
> > --
> > 2.5.0.rc2
> >
> >
> >
> > _______________________________________________
> > linux-arm-kernel mailing list
> > linux-arm-kernel at lists.infradead.org
> > http://lists.infradead.org/mailman/listinfo/linux-arm-kernel
> _______________________________________________
> linux-arm-kernel mailing list
> linux-arm-kernel at lists.infradead.org
> http://lists.infradead.org/mailman/listinfo/linux-arm-kernel

From wens at csie.org  Thu Aug 20 07:54:51 2015
From: wens at csie.org (Chen-Yu Tsai)
Date: Thu, 20 Aug 2015 22:54:51 +0800
Subject: [linux-sunxi] Re: [PATCH 2/3] ARM: dts: sun6i: Turn on gmac on
 Colombus
In-Reply-To: <55D5725F.6000106@redhat.com>
References: <1438960955-6551-1-git-send-email-hdegoede@redhat.com>
 <1438960955-6551-2-git-send-email-hdegoede@redhat.com>
 <20150819151754.GH30520@lukather> <55D5725F.6000106@redhat.com>
Message-ID: <CAGb2v64YBmkmRbHz=XFmQG-Newvxm_R2MS2Jg0v-XO_qYgZQxg@mail.gmail.com>

On Thu, Aug 20, 2015 at 2:23 PM, Hans de Goede <hdegoede at redhat.com> wrote:
> Hi,
>
> On 08/19/2015 05:17 PM, Maxime Ripard wrote:
>>
>> On Fri, Aug 07, 2015 at 05:22:34PM +0200, Hans de Goede wrote:
>>>
>>> We've everything we need to support the gmac on Colombus, turn it on.
>>>
>>> Signed-off-by: Hans de Goede <hdegoede at redhat.com>
>>
>>
>> I recall that the phy was powered by one of the AXP221 regulators,
>> does it require some additional stuff (like a recent u-boot), or does
>> it just work and my memory is bad :) ?
>
>
> I think it just works, it MAY be connected to aldo1 but according to
> the git history for the u-boot defconfig that one is used for wifi not
> for the gmac, and we do not enable any other "spare" regulators in the
> u-boot config.
>
> I do not have any schematics, so no way to say for sure.
>
> I can confirm that the GMAC work fine with the latest u-boot
> master. Looking in the history we've always enabled ALDO1
> on the Colombus in upstream u-boot, so this should all just work.

Could you test it with ALDO1 disabled in U-boot? That should give us
an answer.

ChenYu


From maxime.ripard at free-electrons.com  Thu Aug 20 07:56:56 2015
From: maxime.ripard at free-electrons.com (Maxime Ripard)
Date: Thu, 20 Aug 2015 16:56:56 +0200
Subject: [PATCH 4/9] spi: sun4i: add DMA support
In-Reply-To: <ccf776869b0d7fe2c78bcc41d6cd1896bf732296.1440080122.git.hramrach@gmail.com>
References: <cover.1440080122.git.hramrach@gmail.com>
 <ccf776869b0d7fe2c78bcc41d6cd1896bf732296.1440080122.git.hramrach@gmail.com>
Message-ID: <20150820145656.GW30520@lukather>

On Thu, Aug 20, 2015 at 02:19:46PM -0000, Emilio L?pez wrote:
> From: Emilio L?pez <emilio at elopez.com.ar>
> 
> This patch adds support for 64 byte or bigger transfers on the
> sun4i SPI controller. Said transfers will be performed via DMA.
> 
> Signed-off-by: Emilio L?pez <emilio at elopez.com.ar>
> Tested-by: Michal Suchanek <hramrach at gmail.com>

This should have your SoB.

> ---
>  drivers/spi/spi-sun4i.c | 145 +++++++++++++++++++++++++++++++++++++++++++-----
>  1 file changed, 130 insertions(+), 15 deletions(-)
> 
> diff --git a/drivers/spi/spi-sun4i.c b/drivers/spi/spi-sun4i.c
> index 4dda366..63242a7 100644
> --- a/drivers/spi/spi-sun4i.c
> +++ b/drivers/spi/spi-sun4i.c
> @@ -14,6 +14,8 @@
>  #include <linux/clk.h>
>  #include <linux/delay.h>
>  #include <linux/device.h>
> +#include <linux/dmaengine.h>
> +#include <linux/dma-mapping.h>
>  #include <linux/interrupt.h>
>  #include <linux/io.h>
>  #include <linux/module.h>
> @@ -34,6 +36,7 @@
>  #define SUN4I_CTL_CPHA				BIT(2)
>  #define SUN4I_CTL_CPOL				BIT(3)
>  #define SUN4I_CTL_CS_ACTIVE_LOW			BIT(4)
> +#define SUN4I_CTL_DMAMC_DEDICATED		BIT(5)
>  #define SUN4I_CTL_LMTF				BIT(6)
>  #define SUN4I_CTL_TF_RST			BIT(8)
>  #define SUN4I_CTL_RF_RST			BIT(9)
> @@ -51,6 +54,8 @@
>  #define SUN4I_INT_STA_REG		0x10
>  
>  #define SUN4I_DMA_CTL_REG		0x14
> +#define SUN4I_DMA_CTL_RF_READY			BIT(0)
> +#define SUN4I_DMA_CTL_TF_NOT_FULL		BIT(10)
>  
>  #define SUN4I_WAIT_REG			0x18
>  
> @@ -130,6 +135,13 @@ static inline void sun4i_spi_fill_fifo(struct sun4i_spi *sspi, int len)
>  	}
>  }
>  
> +static bool sun4i_spi_can_dma(struct spi_master *master,
> +			      struct spi_device *spi,
> +			      struct spi_transfer *tfr)
> +{
> +	return tfr->len >= SUN4I_FIFO_DEPTH;
> +}
> +
>  static void sun4i_spi_set_cs(struct spi_device *spi, bool enable)
>  {
>  	struct sun4i_spi *sspi = spi_master_get_devdata(spi->master);
> @@ -169,17 +181,12 @@ static int sun4i_spi_transfer_one(struct spi_master *master,
>  				  struct spi_transfer *tfr)
>  {
>  	struct sun4i_spi *sspi = spi_master_get_devdata(master);
> +	struct dma_async_tx_descriptor *desc_tx = NULL, *desc_rx = NULL;
>  	unsigned int speed, mclk_rate, div, timeout;
>  	unsigned int start, end, tx_time;
>  	unsigned int tx_len = 0;
> +	u32 reg, trigger = 0;
>  	int ret = 0;
> -	u32 reg;
> -
> -	/* We don't support transfer larger than the FIFO */
> -	if (tfr->len > SUN4I_FIFO_DEPTH)
> -		return -EINVAL;
> -	if (tfr->tx_buf && tfr->len => SUN4I_FIFO_DEPTH)
> -		return -EINVAL;
>  
>  	reinit_completion(&sspi->done);
>  	sspi->tx_buf = tfr->tx_buf;
> @@ -277,14 +284,67 @@ static int sun4i_spi_transfer_one(struct spi_master *master,
>  	sun4i_spi_write(sspi, SUN4I_BURST_CNT_REG, SUN4I_BURST_CNT(tfr->len));
>  	sun4i_spi_write(sspi, SUN4I_XMIT_CNT_REG, SUN4I_XMIT_CNT(tx_len));
>  
> -	/* Fill the TX FIFO */
> -	/* Filling the fifo fully causes timeout for some reason
> -	 * at least on spi2 on a10s */
> -	sun4i_spi_fill_fifo(sspi, SUN4I_FIFO_DEPTH - 1);
> -
>  	/* Enable the interrupts */
>  	sun4i_spi_write(sspi, SUN4I_INT_CTL_REG, SUN4I_INT_CTL_TC);
>  
> +	if (sun4i_spi_can_dma(master, spi, tfr)) {
> +		dev_dbg(&sspi->master->dev, "Using DMA mode for transfer\n");
> +
> +		if (sspi->tx_buf) {
> +			desc_tx = dmaengine_prep_slave_sg(master->dma_tx,
> +					tfr->tx_sg.sgl, tfr->tx_sg.nents,
> +					DMA_TO_DEVICE,
> +					DMA_PREP_INTERRUPT | DMA_CTRL_ACK);
> +			if (!desc_tx) {
> +				dev_err(&sspi->master->dev,
> +					"Couldn't prepare dma slave\n");
> +				return -EIO;
> +			}
> +
> +			trigger |= SUN4I_DMA_CTL_TF_NOT_FULL;
> +
> +			dmaengine_submit(desc_tx);
> +			dma_async_issue_pending(master->dma_tx);
> +
> +		}
> +
> +		if (sspi->rx_buf) {
> +			desc_rx = dmaengine_prep_slave_sg(master->dma_rx,
> +					tfr->rx_sg.sgl, tfr->rx_sg.nents,
> +					DMA_FROM_DEVICE,
> +					DMA_PREP_INTERRUPT | DMA_CTRL_ACK);
> +			if (!desc_rx) {
> +				dev_err(&sspi->master->dev,
> +					"Couldn't prepare dma slave\n");
> +				return -EIO;
> +			}
> +
> +			trigger |= SUN4I_DMA_CTL_RF_READY;
> +
> +			dmaengine_submit(desc_rx);
> +			dma_async_issue_pending(master->dma_rx);
> +		}

What happens if the dma driver controller isn't present in your
system? Or that it doesn't have any channels available anymore?

> +		/* Enable Dedicated DMA requests */
> +		reg = sun4i_spi_read(sspi, SUN4I_CTL_REG);
> +		reg |= SUN4I_CTL_DMAMC_DEDICATED;
> +		sun4i_spi_write(sspi, SUN4I_CTL_REG, reg);
> +		sun4i_spi_write(sspi, SUN4I_DMA_CTL_REG, trigger);
> +	} else {
> +		dev_dbg(&sspi->master->dev, "Using PIO mode for transfer\n");
> +
> +		/* Disable DMA requests */
> +		reg = sun4i_spi_read(sspi, SUN4I_CTL_REG);
> +		sun4i_spi_write(sspi, SUN4I_CTL_REG,
> +				reg & ~SUN4I_CTL_DMAMC_DEDICATED);
> +		sun4i_spi_write(sspi, SUN4I_DMA_CTL_REG, 0);
> +
> +		/* Fill the TX FIFO */
> +		/* Filling the fifo fully causes timeout for some reason
> +		 * at least on spi2 on a10s */
> +		sun4i_spi_fill_fifo(sspi, SUN4I_FIFO_DEPTH - 1);
> +	}
> +
>  	/* Start the transfer */
>  	reg = sun4i_spi_read(sspi, SUN4I_CTL_REG);
>  	sun4i_spi_write(sspi, SUN4I_CTL_REG, reg | SUN4I_CTL_XCH);
> @@ -303,7 +363,12 @@ static int sun4i_spi_transfer_one(struct spi_master *master,
>  		goto out;
>  	}
>  
> -	sun4i_spi_drain_fifo(sspi, SUN4I_FIFO_DEPTH);
> +	if (sun4i_spi_can_dma(master, spi, tfr) && desc_rx) {
> +		/* The receive transfer should be the last one to finish */
> +		dma_wait_for_async_tx(desc_rx);

Nope, this is only meant for async_tx. You should register a callback
in your transfer that will mark the completion structure as completed,
and then drain the FIFO only if not using DMA.

> +	} else {
> +		sun4i_spi_drain_fifo(sspi, SUN4I_FIFO_DEPTH);
> +	}
>  
>  out:
>  	sun4i_spi_write(sspi, SUN4I_INT_CTL_REG, 0);
> @@ -368,6 +433,7 @@ static int sun4i_spi_runtime_suspend(struct device *dev)
>  
>  static int sun4i_spi_probe(struct platform_device *pdev)
>  {
> +	struct dma_slave_config dma_sconfig;
>  	struct spi_master *master;
>  	struct sun4i_spi *sspi;
>  	struct resource	*res;
> @@ -403,7 +469,9 @@ static int sun4i_spi_probe(struct platform_device *pdev)
>  		goto err_free_master;
>  	}
>  
> +	init_completion(&sspi->done);
>  	sspi->master = master;
> +	master->can_dma = sun4i_spi_can_dma;
>  	master->set_cs = sun4i_spi_set_cs;
>  	master->transfer_one = sun4i_spi_transfer_one;
>  	master->num_chipselect = 4;
> @@ -426,7 +494,45 @@ static int sun4i_spi_probe(struct platform_device *pdev)
>  		goto err_free_master;
>  	}
>  
> -	init_completion(&sspi->done);
> +	master->dma_tx = dma_request_slave_channel_reason(&pdev->dev, "tx");
> +	if (IS_ERR(master->dma_tx)) {
> +		dev_err(&pdev->dev, "Unable to acquire DMA channel TX\n");
> +		ret = PTR_ERR(master->dma_tx);
> +		goto err_free_master;
> +	}
> +
> +	dma_sconfig.direction = DMA_MEM_TO_DEV;
> +	dma_sconfig.src_addr_width = DMA_SLAVE_BUSWIDTH_1_BYTE;
> +	dma_sconfig.dst_addr_width = DMA_SLAVE_BUSWIDTH_1_BYTE;
> +	dma_sconfig.dst_addr = res->start + SUN4I_TXDATA_REG;
> +	dma_sconfig.src_maxburst = 1;
> +	dma_sconfig.dst_maxburst = 1;
> +
> +	ret = dmaengine_slave_config(master->dma_tx, &dma_sconfig);
> +	if (ret) {
> +		dev_err(&pdev->dev, "Unable to configure TX DMA slave\n");
> +		goto err_tx_dma_release;
> +	}
> +
> +	master->dma_rx = dma_request_slave_channel_reason(&pdev->dev, "rx");
> +	if (IS_ERR(master->dma_rx)) {
> +		dev_err(&pdev->dev, "Unable to acquire DMA channel RX\n");
> +		ret = PTR_ERR(master->dma_rx);
> +		goto err_tx_dma_release;
> +	}
> +
> +	dma_sconfig.direction = DMA_DEV_TO_MEM;
> +	dma_sconfig.src_addr_width = DMA_SLAVE_BUSWIDTH_1_BYTE;
> +	dma_sconfig.dst_addr_width = DMA_SLAVE_BUSWIDTH_1_BYTE;
> +	dma_sconfig.src_addr = res->start + SUN4I_RXDATA_REG;
> +	dma_sconfig.src_maxburst = 1;
> +	dma_sconfig.dst_maxburst = 1;

We can't use a higher bust size?

Maxime

-- 
Maxime Ripard, Free Electrons
Embedded Linux, Kernel and Android engineering
http://free-electrons.com
-------------- next part --------------
A non-text attachment was scrubbed...
Name: signature.asc
Type: application/pgp-signature
Size: 819 bytes
Desc: Digital signature
URL: <http://lists.infradead.org/pipermail/linux-arm-kernel/attachments/20150820/707bfe7e/attachment.sig>

From maxime.ripard at free-electrons.com  Thu Aug 20 07:58:58 2015
From: maxime.ripard at free-electrons.com (Maxime Ripard)
Date: Thu, 20 Aug 2015 16:58:58 +0200
Subject: [PATCH 5/9] ARM: dts: sun7i: cubieboard2: Enable SPI0
In-Reply-To: <a5a061d98b7ff851866cc668cd8bf8f6fc99d002.1440080122.git.hramrach@gmail.com>
References: <cover.1440080122.git.hramrach@gmail.com>
 <a5a061d98b7ff851866cc668cd8bf8f6fc99d002.1440080122.git.hramrach@gmail.com>
Message-ID: <20150820145858.GX30520@lukather>

On Thu, Aug 20, 2015 at 02:19:46PM -0000, Michal Suchanek wrote:
> Only SPI0 is enabled. The schematic denotes it as the only SPI bus.
> Other SPI pins are reserved for different peripherals.
> 
> Signed-off-by: Michal Suchanek <hramrach at gmail.com>

What device is connected to the other end?

> ---
>  arch/arm/boot/dts/sun7i-a20-cubieboard2.dts | 7 +++++++
>  1 file changed, 7 insertions(+)
> 
> diff --git a/arch/arm/boot/dts/sun7i-a20-cubieboard2.dts b/arch/arm/boot/dts/sun7i-a20-cubieboard2.dts
> index 39a51d5..9861304 100644
> --- a/arch/arm/boot/dts/sun7i-a20-cubieboard2.dts
> +++ b/arch/arm/boot/dts/sun7i-a20-cubieboard2.dts
> @@ -198,6 +198,13 @@
>  	status = "okay";
>  };
>  
> +&spi0 {
> +	pinctrl-names = "default";
> +	pinctrl-0 = <&spi0_pins_a>,
> +		    <&spi0_cs0_pins_a>;
> +	status = "okay";
> +};
> +

You should probably add an alias to that bus too.

Maxime

-- 
Maxime Ripard, Free Electrons
Embedded Linux, Kernel and Android engineering
http://free-electrons.com
-------------- next part --------------
A non-text attachment was scrubbed...
Name: signature.asc
Type: application/pgp-signature
Size: 819 bytes
Desc: Digital signature
URL: <http://lists.infradead.org/pipermail/linux-arm-kernel/attachments/20150820/5f89b1a8/attachment-0001.sig>

From maxime.ripard at free-electrons.com  Thu Aug 20 08:00:57 2015
From: maxime.ripard at free-electrons.com (Maxime Ripard)
Date: Thu, 20 Aug 2015 17:00:57 +0200
Subject: [PATCH 7/9] ARM: dts: sun5i: add SPI pins on A13 and A10s
In-Reply-To: <90730047894f6ec84cd70062a27b7085c2016260.1440080122.git.hramrach@gmail.com>
References: <cover.1440080122.git.hramrach@gmail.com>
 <90730047894f6ec84cd70062a27b7085c2016260.1440080122.git.hramrach@gmail.com>
Message-ID: <20150820150057.GY30520@lukather>

On Thu, Aug 20, 2015 at 02:19:47PM -0000, Michal Suchanek wrote:
> According to datasheet some pins are available on A10s only while others
> are shared with A13.
> 
> Signed-off-by: Michal Suchanek <hramrach at gmail.com>
> ---
> This time add all spi pins and make the CS pins separate as is seen with
> current sun4i DTs
> ---
>  arch/arm/boot/dts/sun5i-a10s.dtsi | 21 +++++++++++++++++
>  arch/arm/boot/dts/sun5i.dtsi      | 49 +++++++++++++++++++++++++++++++++++++++
>  2 files changed, 70 insertions(+)
> 
> diff --git a/arch/arm/boot/dts/sun5i-a10s.dtsi b/arch/arm/boot/dts/sun5i-a10s.dtsi
> index f11efb7..d9610fa 100644
> --- a/arch/arm/boot/dts/sun5i-a10s.dtsi
> +++ b/arch/arm/boot/dts/sun5i-a10s.dtsi
> @@ -201,6 +201,27 @@
>  		allwinner,drive = <SUN4I_PINCTRL_30_MA>;
>  		allwinner,pull = <SUN4I_PINCTRL_NO_PULL>;
>  	};
> +
> +	spi1_cs1_pins_a: spi1_cs1 at 0 {
> +		allwinner,pins = "PG13";
> +		allwinner,function = "spi1";
> +		allwinner,drive = <SUN4I_PINCTRL_10_MA>;
> +		allwinner,pull = <SUN4I_PINCTRL_NO_PULL>;
> +	};
> +
> +	spi2_pins_a: spi2 at 0 {
> +		allwinner,pins = "PB12", "PB13", "PB14";
> +		allwinner,function = "spi1";
> +		allwinner,drive = <SUN4I_PINCTRL_10_MA>;
> +		allwinner,pull = <SUN4I_PINCTRL_NO_PULL>;
> +	};
> +
> +	spi2_cs0_pins_a: spi2_cs0 at 0 {
> +		allwinner,pins = "PB11";
> +		allwinner,function = "spi1";
> +		allwinner,drive = <SUN4I_PINCTRL_10_MA>;
> +		allwinner,pull = <SUN4I_PINCTRL_NO_PULL>;
> +	};

spi2 nodes with spi1 function ??? How can that even work?

>  };
>  
>  &sram_a {
> diff --git a/arch/arm/boot/dts/sun5i.dtsi b/arch/arm/boot/dts/sun5i.dtsi
> index 54b0978..7d32d49 100644
> --- a/arch/arm/boot/dts/sun5i.dtsi
> +++ b/arch/arm/boot/dts/sun5i.dtsi
> @@ -516,6 +516,55 @@
>  				allwinner,drive = <SUN4I_PINCTRL_30_MA>;
>  				allwinner,pull = <SUN4I_PINCTRL_PULL_UP>;
>  			};
> +
> +			spi0_pins_a: spi0 at 0 {
> +				allwinner,pins = "PC00", "PC01", "PC02";
> +				allwinner,function = "spi0";
> +				allwinner,drive = <SUN4I_PINCTRL_10_MA>;
> +				allwinner,pull = <SUN4I_PINCTRL_NO_PULL>;
> +			};
> +
> +			spi0_cs0_pins_a: spi0_cs0 at 0 {
> +				allwinner,pins = "PC03";
> +				allwinner,function = "spi0";
> +				allwinner,drive = <SUN4I_PINCTRL_10_MA>;
> +				allwinner,pull = <SUN4I_PINCTRL_NO_PULL>;
> +			};
> +
> +			spi1_pins_a: spi1 at 0 {
> +				allwinner,pins = "PG10", "PG11", "PG12";
> +				allwinner,function = "spi1";
> +				allwinner,drive = <SUN4I_PINCTRL_10_MA>;
> +				allwinner,pull = <SUN4I_PINCTRL_NO_PULL>;
> +			};
> +
> +			spi1_cs0_pins_a: spi1_cs0 at 0 {
> +				allwinner,pins = "PG09";
> +				allwinner,function = "spi1";
> +				allwinner,drive = <SUN4I_PINCTRL_10_MA>;
> +				allwinner,pull = <SUN4I_PINCTRL_NO_PULL>;
> +			};
> +
> +			spi2_pins_b: spi2 at 1 {
> +				allwinner,pins = "PE01", "PE02", "PE03";
> +				allwinner,function = "spi2";
> +				allwinner,drive = <SUN4I_PINCTRL_10_MA>;
> +				allwinner,pull = <SUN4I_PINCTRL_NO_PULL>;
> +			};
> +
> +			spi2_cs0_pins_b: spi2_cs1 at 1 {
> +				allwinner,pins = "PE00";
> +				allwinner,function = "spi2";
> +				allwinner,drive = <SUN4I_PINCTRL_10_MA>;
> +				allwinner,pull = <SUN4I_PINCTRL_NO_PULL>;
> +			};
> +
> +			spi2_cs1_pins_a: spi2_cs1 at 0 {
> +				allwinner,pins = "PB10";
> +				allwinner,function = "spi2";
> +				allwinner,drive = <SUN4I_PINCTRL_10_MA>;
> +				allwinner,pull = <SUN4I_PINCTRL_NO_PULL>;
> +			};

Please only add the pins you intend to use.

Maxime

-- 
Maxime Ripard, Free Electrons
Embedded Linux, Kernel and Android engineering
http://free-electrons.com
-------------- next part --------------
A non-text attachment was scrubbed...
Name: signature.asc
Type: application/pgp-signature
Size: 819 bytes
Desc: Digital signature
URL: <http://lists.infradead.org/pipermail/linux-arm-kernel/attachments/20150820/04bcd02f/attachment.sig>

From maxime.ripard at free-electrons.com  Thu Aug 20 08:03:58 2015
From: maxime.ripard at free-electrons.com (Maxime Ripard)
Date: Thu, 20 Aug 2015 17:03:58 +0200
Subject: [linux-sunxi] Re: [PATCH 4/6] ARM: dts: sun7i: Enable USB DRC on
 pcDuino 3
In-Reply-To: <55D58381.7040801@redhat.com>
References: <1439563477-12295-1-git-send-email-hdegoede@redhat.com>
 <1439563477-12295-5-git-send-email-hdegoede@redhat.com>
 <20150820064545.GM30520@lukather> <55D58381.7040801@redhat.com>
Message-ID: <20150820150358.GZ30520@lukather>

On Thu, Aug 20, 2015 at 09:36:33AM +0200, Hans de Goede wrote:
> Hi,
> 
> On 08/20/2015 08:45 AM, Maxime Ripard wrote:
> >On Fri, Aug 14, 2015 at 04:44:35PM +0200, Hans de Goede wrote:
> >>From: Jelle van der Waa <jelle at vdwaa.nl>
> >>
> >>Enable the otg/drc usb controller on the pcDuino 3.
> >>
> >>Note this board has the otg-vbus connected directly to the 5v-dcc of
> >>the board, so there is no vbus0 regulator, nor vbus0-det.
> >
> >Can it do OTG then?
> 
> Yes.
> 
> >If VBUS is tied to the 5v, there's no way for the
> >board to shut it down when acting as peripheral, right?
> 
> Correct, the idea is to power it over otg when using it
> as a peripheral, or at least power it from a usb port of
> the machine for which it is a peripheral. Note that the
> original cubieboard (both A10 and A20 versions) have the
> same issue.

Hmmm, I see. I'll queue your patch then.

Thanks!
Maxime

-- 
Maxime Ripard, Free Electrons
Embedded Linux, Kernel and Android engineering
http://free-electrons.com
-------------- next part --------------
A non-text attachment was scrubbed...
Name: signature.asc
Type: application/pgp-signature
Size: 819 bytes
Desc: Digital signature
URL: <http://lists.infradead.org/pipermail/linux-arm-kernel/attachments/20150820/ecf37948/attachment.sig>

From maxime.ripard at free-electrons.com  Thu Aug 20 08:04:24 2015
From: maxime.ripard at free-electrons.com (Maxime Ripard)
Date: Thu, 20 Aug 2015 17:04:24 +0200
Subject: [PATCH 5/6] ARM: dts: sun7i: Enable USB DRC on cubieboard2
In-Reply-To: <1439563477-12295-6-git-send-email-hdegoede@redhat.com>
References: <1439563477-12295-1-git-send-email-hdegoede@redhat.com>
 <1439563477-12295-6-git-send-email-hdegoede@redhat.com>
Message-ID: <20150820150424.GA30520@lukather>

On Fri, Aug 14, 2015 at 04:44:36PM +0200, Hans de Goede wrote:
> From: Ralph Benadski <benadski at gmail.com>
> 
> Enable the otg/drc usb controller on the cubieboard2.
> 
> Note this board has the otg-vbus connected directly to the 5v-dcc of
> the board, so there is no vbus0 regulator, nor vbus0-det.
> 
> Signed-off-by: Ralph Benadski <benadski at gmail.com>
> Signed-off-by: Hans de Goede <hdegoede at redhat.com>

Queued, thanks!

Maxime

-- 
Maxime Ripard, Free Electrons
Embedded Linux, Kernel and Android engineering
http://free-electrons.com
-------------- next part --------------
A non-text attachment was scrubbed...
Name: signature.asc
Type: application/pgp-signature
Size: 819 bytes
Desc: Digital signature
URL: <http://lists.infradead.org/pipermail/linux-arm-kernel/attachments/20150820/342e3c86/attachment.sig>

From julien.grall at citrix.com  Thu Aug 20 08:03:33 2015
From: julien.grall at citrix.com (Julien Grall)
Date: Thu, 20 Aug 2015 08:03:33 -0700
Subject: [Xen-devel] [PATCH v3 00/20] xen/arm64: Add support for 64KB page
In-Reply-To: <55D5A7CB.3070207@citrix.com>
References: <1438966019-19322-1-git-send-email-julien.grall@citrix.com>
 <55D521F2.5080504@citrix.com> <55D5A7CB.3070207@citrix.com>
Message-ID: <55D5EC45.5010306@citrix.com>



On 20/08/2015 03:11, David Vrabel wrote:
> On 20/08/15 01:40, Julien Grall wrote:
>> Hi,
>>
>> Ping? I'm missing some reviews on block and netfront code.
>>
>> We'd like to see this series going in Linux 4.3. Some distributions
>> plans to use this version for aarch64 support. If we miss it, we won't
>> have any Xen guests support, even it's minimal, for Linux using 64KB
>> page granularity.
>
> This is too late for Linux 4.3.

May I know why it's too late for Linux 4.3? AFAICT, Linux 4.2 is not yet 
out and therefore the merge window for Linux 4.3 is not yet opened.

Regards,

-- 
Julien Grall


From maxime.ripard at free-electrons.com  Thu Aug 20 08:08:45 2015
From: maxime.ripard at free-electrons.com (Maxime Ripard)
Date: Thu, 20 Aug 2015 17:08:45 +0200
Subject: [PATCH v3 1/8] rsb: Add generic Reduced Serial Bus (RSB)
 controller binding documentation
In-Reply-To: <1439958009-14056-2-git-send-email-wens@csie.org>
References: <1439958009-14056-1-git-send-email-wens@csie.org>
 <1439958009-14056-2-git-send-email-wens@csie.org>
Message-ID: <20150820150845.GB30520@lukather>

Hi,

Thanks a lot for working on this.

On Wed, Aug 19, 2015 at 12:20:02PM +0800, Chen-Yu Tsai wrote:
> Reduced Serial Bus is a proprietary 2-line push-pull serial bus
> supporting multiple slave devices.
> 
> It was developed by Allwinner, Inc. and used by Allwinner and X-Powers,
> Inc. for their line of PMICs and other peripheral ICs.
> 
> Signed-off-by: Chen-Yu Tsai <wens at csie.org>
> ---
>  Documentation/devicetree/bindings/rsb/rsb.txt | 50 +++++++++++++++++++++++++++
>  1 file changed, 50 insertions(+)
>  create mode 100644 Documentation/devicetree/bindings/rsb/rsb.txt
> 
> diff --git a/Documentation/devicetree/bindings/rsb/rsb.txt b/Documentation/devicetree/bindings/rsb/rsb.txt
> new file mode 100644
> index 000000000000..0b027948ca9c
> --- /dev/null
> +++ b/Documentation/devicetree/bindings/rsb/rsb.txt
> @@ -0,0 +1,50 @@
> +Reduced Serial Bus (RSB) Controller
> +
> +This document defines a generic set of bindings for use by RSB controllers.
> +A controller is modelled in device tree as a node with zero or more child
> +nodes, each representing a unique slave device on the bus.
> +
> +Required properties:
> +
> + - #address-cells : must be 2
> + - #size-cells : must be 0
> +
> +Optional properties:
> +
> + - clock-frequency : Desired bus clock frequency in Hz. Maximum is 20 MHz.

What is the default if not set?

> +
> +Child nodes:
> +
> +An RSB controller node can contain zero or more child nodes representing
> +slave devices on the bus.  Child 'reg' properties are specified as a
> +runtime address, hardware address pair. The hardware address is hardwired
> +in the device, which can normally be found in the datasheet. The runtime
> +address is set by software. No 2 devices on the same bus shall have the
> +same runtime address.
> +
> +Valid runtime addresses - There are only 15 valid runtime addresses:
> +
> +    0x17, 0x2d, 0x3a, 0x4e, 0x59, 0x63, 0x74, 0x8b,
> +    0x9c, 0xa6, 0xb1, 0xc5, 0xd2, 0xe8, 0xff
> +
> +It is highly recommended that one choose the same runtime addresses as
> +vendor BSPs use so that a) the addresses remain the same across different
> +software systems, and b) addresses of supported and listed slave devices
> +don't conflict with unsupported or not yet listed devices.

I'd expect to have the hardware address first, but maybe it's just me
:)


> +Example:
> +
> +	rsb at ... {
> +		compatible = "...";
> +		reg = <...>;
> +		/* ... */
> +		#address-cells = <2>;
> +		#size-cells = <0>;
> +
> +		pmic at 2d {

The unit-address should be 2d,3e3.

> +			compatible = "...";
> +			reg = <0x2d 0x3e3>;
> +
> +			/* ... */
> +		};
> +	};
> -- 
> 2.5.0
> 

-- 
Maxime Ripard, Free Electrons
Embedded Linux, Kernel and Android engineering
http://free-electrons.com
-------------- next part --------------
A non-text attachment was scrubbed...
Name: signature.asc
Type: application/pgp-signature
Size: 819 bytes
Desc: Digital signature
URL: <http://lists.infradead.org/pipermail/linux-arm-kernel/attachments/20150820/8efe28ec/attachment.sig>

From david.vrabel at citrix.com  Thu Aug 20 08:15:05 2015
From: david.vrabel at citrix.com (David Vrabel)
Date: Thu, 20 Aug 2015 16:15:05 +0100
Subject: [Xen-devel] [PATCH v3 00/20] xen/arm64: Add support for 64KB page
In-Reply-To: <55D5EC45.5010306@citrix.com>
References: <1438966019-19322-1-git-send-email-julien.grall@citrix.com>
 <55D521F2.5080504@citrix.com> <55D5A7CB.3070207@citrix.com>
 <55D5EC45.5010306@citrix.com>
Message-ID: <55D5EEF9.7080904@citrix.com>

On 20/08/15 16:03, Julien Grall wrote:
> 
> 
> On 20/08/2015 03:11, David Vrabel wrote:
>> On 20/08/15 01:40, Julien Grall wrote:
>>> Hi,
>>>
>>> Ping? I'm missing some reviews on block and netfront code.
>>>
>>> We'd like to see this series going in Linux 4.3. Some distributions
>>> plans to use this version for aarch64 support. If we miss it, we won't
>>> have any Xen guests support, even it's minimal, for Linux using 64KB
>>> page granularity.
>>
>> This is too late for Linux 4.3.
> 
> May I know why it's too late for Linux 4.3? AFAICT, Linux 4.2 is not yet
> out and therefore the merge window for Linux 4.3 is not yet opened.

Because:

a) There's nothing suitable to apply yet (need a v4 series)
b) The merge window opens this weekend (probably).
c) What's currently queued for 4.3 has been tested and no further tests
can be run until next week (when Boris or Konrad get back).

FWIW, "mm, xen/balloon: memory hotplug improvements" has also not been
queued for 4.3 for similar reasons (despite this series being ready 4
days ago and it having been more extensively tested inside XenServer).

David


From timur at codeaurora.org  Thu Aug 20 08:22:36 2015
From: timur at codeaurora.org (Timur Tabi)
Date: Thu, 20 Aug 2015 10:22:36 -0500
Subject: [PATCH 3/3] [v2] hvc_dcc: disable user-space access to DCC
In-Reply-To: <20150820104645.GD19328@arm.com>
References: <1440025370-9519-1-git-send-email-timur@codeaurora.org>
 <1440025370-9519-3-git-send-email-timur@codeaurora.org>
 <20150820104645.GD19328@arm.com>
Message-ID: <55D5F0BC.4010304@codeaurora.org>

On 08/20/2015 05:46 AM, Will Deacon wrote:
>> If the DCC driver loads, then disable user-space access to the DCC so that
>> >we don't have two entities trying to access the DCC at the same time.

> In the interests of making some headway with this, just drop this patch
> and I'll queue the diff below via the arm64 tree.

Yes, that would be great.  Thank you.

-- 
Qualcomm Innovation Center, Inc.
The Qualcomm Innovation Center, Inc. is a member of the
Code Aurora Forum, a Linux Foundation Collaborative Project.


From ddaney at caviumnetworks.com  Thu Aug 20 08:23:13 2015
From: ddaney at caviumnetworks.com (David Daney)
Date: Thu, 20 Aug 2015 08:23:13 -0700
Subject: [PATCH 2/5] gic-its: Allow pci_requester_id to be overridden.
In-Reply-To: <01a101d0db52$2d23b360$876b1a20$@samsung.com>
References: <1436979285-8177-1-git-send-email-ddaney.cavm@gmail.com>
 <1436979285-8177-3-git-send-email-ddaney.cavm@gmail.com>
 <01a101d0db52$2d23b360$876b1a20$@samsung.com>
Message-ID: <55D5F0E1.30702@caviumnetworks.com>

On 08/20/2015 07:11 AM, Pavel Fedin wrote:
>
>   Hello!
>
>> -----Original Message-----
>> From: linux-pci-owner at vger.kernel.org [mailto:linux-pci-owner at vger.kernel.org] On Behalf Of David
>> Daney
>> Sent: Wednesday, July 15, 2015 7:55 PM
>> To: linux-arm-kernel at lists.infradead.org; Catalin Marinas; Will Deacon; Bjorn Helgaas; linux-
>> pci at vger.kernel.org; Thomas Gleixner; Jason Cooper
>> Cc: linux-kernel at vger.kernel.org; Robert Richter; David Daney
>> Subject: [PATCH 2/5] gic-its: Allow pci_requester_id to be overridden.
>>
>> From: David Daney <david.daney at cavium.com>
>>
>> Signed-off-by: David Daney <david.daney at cavium.com>
>> ---
>>   drivers/irqchip/irq-gic-v3-its.c   | 14 +++++++++++++-
>>   include/linux/irqchip/arm-gic-v3.h |  2 ++
>>   2 files changed, 15 insertions(+), 1 deletion(-)
>>
>> diff --git a/drivers/irqchip/irq-gic-v3-its.c b/drivers/irqchip/irq-gic-v3-its.c
>> index 1b7e155..4580970 100644
>> --- a/drivers/irqchip/irq-gic-v3-its.c
>> +++ b/drivers/irqchip/irq-gic-v3-its.c
>> @@ -1189,11 +1189,23 @@ static int its_pci_msi_vec_count(struct pci_dev *pdev)
>>   	return max(msi, msix);
>>   }
>>
>> +static u32 its_dflt_pci_requester_id(struct pci_dev *pdev, u16 alias)
>> +{
>> +	return alias;
>> +}
>> +
>> +static its_pci_requester_id_t its_pci_requester_id = its_dflt_pci_requester_id;
>> +void set_its_pci_requester_id(its_pci_requester_id_t fn)
>> +{
>> +	its_pci_requester_id = fn;
>> +}
>> +EXPORT_SYMBOL(set_its_pci_requester_id);
>
>   IMHO having a globally defined function is a horrible approach. What if some HW has two different
> PCI host controllers, each of them wants to provide different form of IDs? I know, this is just
> imaginary, but still...

It is not imaginary, such systems exist.

>   What if instead of this function we simply add a field to a struct pci_bus ? Then bus driver would
> fill in HW-specific ID bits for every bus.
>   I can send a patch if interested.

There is a lot of work being done in the upstream to extract the proper 
information from the device tree.  We are going to piggyback on that for 
the next versions of the patch.

ACPI will have to be made to work as well.

David Daney




>
>> +
>>   static int its_get_pci_alias(struct pci_dev *pdev, u16 alias, void *data)
>>   {
>>   	struct its_pci_alias *dev_alias = data;
>>
>> -	dev_alias->dev_id = alias;
>> +	dev_alias->dev_id = its_pci_requester_id(pdev, alias);
>>   	if (pdev != dev_alias->pdev)
>>   		dev_alias->count += its_pci_msi_vec_count(dev_alias->pdev);
>>
>> diff --git a/include/linux/irqchip/arm-gic-v3.h b/include/linux/irqchip/arm-gic-v3.h
>> index ffbc034..18e3757 100644
>> --- a/include/linux/irqchip/arm-gic-v3.h
>> +++ b/include/linux/irqchip/arm-gic-v3.h
>> @@ -389,6 +389,8 @@ int its_cpu_init(void);
>>   int its_init(struct device_node *node, struct rdists *rdists,
>>   	     struct irq_domain *domain);
>>
>> +typedef u32 (*its_pci_requester_id_t)(struct pci_dev *, u16);
>> +void set_its_pci_requester_id(its_pci_requester_id_t fn);
>>   #endif
>>
>>   #endif
>> --
>
> Kind regards,
> Pavel Fedin
> Expert Engineer
> Samsung Electronics Research center Russia
>
>
>


From balbi at ti.com  Thu Aug 20 08:35:53 2015
From: balbi at ti.com (Felipe Balbi)
Date: Thu, 20 Aug 2015 10:35:53 -0500
Subject: [PATCH v5 01/46] usb: gadget: encapsulate endpoint claiming
 mechanism
In-Reply-To: <1438351258-31578-2-git-send-email-r.baldyga@samsung.com>
References: <1438351258-31578-1-git-send-email-r.baldyga@samsung.com>
 <1438351258-31578-2-git-send-email-r.baldyga@samsung.com>
Message-ID: <20150820153553.GD1639@saruman.tx.rr.com>

Hi,

On Fri, Jul 31, 2015 at 04:00:13PM +0200, Robert Baldyga wrote:
> So far it was necessary for usb functions to set ep->driver_data in
> endpoint obtained from autoconfig to non-null value, to indicate that
> endpoint is claimed by function (in autoconfig it was checked if endpoint
> has set this field to non-null value, and if it has, it was assumed that
> it is claimed). It could cause bugs because if some function doesn't
> set this field autoconfig could return the same endpoint more than one
> time.
> 
> To help to avoid such bugs this patch adds claimed flag to struct usb_ep,
> and  encapsulates endpoint claiming mechanism inside usb_ep_autoconfig_ss()
> and usb_ep_autoconfig_reset(), so now usb functions don't need to perform
> any additional actions to mark endpoint obtained from autoconfig as claimed.
> 
> Signed-off-by: Robert Baldyga <r.baldyga at samsung.com>

just letting you know that this regresses all gadget drivers making them
try to disable previously disabled endpoints and enable previously
enabled endpoints.

I have a possible fix (see below) but then it shows a problem on the
host side when using with g_zero (see further below):

commit 3b8932100aacb6cfbffe288ca93025d8b8430c00
Author: Felipe Balbi <balbi at ti.com>
Date:   Wed Aug 19 18:05:27 2015 -0500

    usb: gadget: fix ep->claimed lifetime
    
    In order to fix a regression introduced by commit
    cc476b42a39d ("usb: gadget: encapsulate endpoint
    claiming mechanism") we have to introduce a simple
    helper to check if a particular is enabled or not.
    
    After that, we need to move ep->claimed lifetime to
    usb_ep_enable() and usb_ep_disable() since those
    are the only functions which actually enable and
    disable endpoints.
    
    A follow-up patch will come to drop all driver_data
    checks from function drivers, since those are, now,
    pointless.
    
    Fixes: cc476b42a39d ("usb: gadget: encapsulate endpoint
    	claiming mechanism")
    Cc: Robert Baldyga <r.baldyga at samsung.com>
    Signed-off-by: Felipe Balbi <balbi at ti.com>

diff --git a/drivers/usb/gadget/epautoconf.c b/drivers/usb/gadget/epautoconf.c
index 978435a51038..ad45070cd76f 100644
--- a/drivers/usb/gadget/epautoconf.c
+++ b/drivers/usb/gadget/epautoconf.c
@@ -126,7 +126,6 @@ found_ep:
 	ep->address = desc->bEndpointAddress;
 	ep->desc = NULL;
 	ep->comp_desc = NULL;
-	ep->claimed = true;
 	return ep;
 }
 EXPORT_SYMBOL_GPL(usb_ep_autoconfig_ss);
@@ -182,11 +181,6 @@ EXPORT_SYMBOL_GPL(usb_ep_autoconfig);
  */
 void usb_ep_autoconfig_reset (struct usb_gadget *gadget)
 {
-	struct usb_ep	*ep;
-
-	list_for_each_entry (ep, &gadget->ep_list, ep_list) {
-		ep->claimed = false;
-	}
 	gadget->in_epnum = 0;
 	gadget->out_epnum = 0;
 }
diff --git a/include/linux/usb/gadget.h b/include/linux/usb/gadget.h
index c14a69b36d27..9b3d60c1cf9f 100644
--- a/include/linux/usb/gadget.h
+++ b/include/linux/usb/gadget.h
@@ -243,6 +243,22 @@ static inline void usb_ep_set_maxpacket_limit(struct usb_ep *ep,
 }
 
 /**
+ * usb_ep_enabled - is endpoint enabled ?
+ * @ep: the endpoint being checked. may not be the endpoint named "ep0".
+ *
+ * Whenever a function driver wants to check if a particular endpoint is
+ * enabled or not, it must check using this helper function. This will
+ * encapsulate details about how the endpoint is checked, saving the function
+ * driver from using private methods for doing so.
+ *
+ * return true if endpoint is enabled, false otherwise.
+ */
+static inline bool usb_ep_enabled(struct usb_ep *ep)
+{
+	return ep->claimed;
+}
+
+/**
  * usb_ep_enable - configure endpoint, making it usable
  * @ep:the endpoint being configured.  may not be the endpoint named "ep0".
  *	drivers discover endpoints through the ep_list of a usb_gadget.
@@ -264,7 +280,18 @@ static inline void usb_ep_set_maxpacket_limit(struct usb_ep *ep,
  */
 static inline int usb_ep_enable(struct usb_ep *ep)
 {
-	return ep->ops->enable(ep, ep->desc);
+	int ret;
+
+	if (usb_ep_enabled(ep))
+		return 0;
+
+	ret = ep->ops->enable(ep, ep->desc);
+	if (ret)
+		return ret;
+
+	ep->claimed = true;
+
+	return 0;
 }
 
 /**
@@ -281,7 +308,18 @@ static inline int usb_ep_enable(struct usb_ep *ep)
  */
 static inline int usb_ep_disable(struct usb_ep *ep)
 {
-	return ep->ops->disable(ep);
+	int ret;
+
+	if (!usb_ep_enabled(ep))
+		return 0;
+
+	ret = ep->ops->disable(ep);
+	if (ret)
+		return ret;
+
+	ep->claimed = false;
+
+	return 0;
 }
 
 /**



[   73.290345] WARNING: CPU: 0 PID: 300 at lib/kobject.c:240 kobject_add_internal+0x25c/0x2d8()
[   73.299172] kobject_add_internal failed for ep_81 with -EEXIST, don't try to register things with the same name in the same directory.
[   73.311825] Modules linked in: usbtest usb_f_ss_lb g_zero libcomposite xhci_plat_hcd xhci_hcd usbcore joydev dwc3 udc_core usb_common m25p80 evdev spi_nor omapfb cpufreq_dt cfbfillrect snd_soc_simple_card cfbimgblt thermal_sys cfbcopyarea hwmon leds_gpio matrix_keypad led_class matrix_keymap panel_dpi pwm_bl snd_soc_tlv320aic3x snd_soc_davinci_mcasp snd_soc_edma snd_soc_omap snd_soc_core omapdss snd_compress snd_pcm_dmaengine snd_pcm dwc3_omap extcon snd_timer pwm_tiecap snd lis3lv02d_i2c lis3lv02d soundcore  input_polldev spi_ti_qspi tps65218_pwrbutton rtc_omap omap_wdt phy_omap_usb2 autofs4
 [   73.367114] CPU: 0 PID: 300 Comm: testusb Tainted: G        W  4.2.0-rc7-next-20150819-00002-g3ccb6c8b6305 #1080
 [   73.378236] Hardware name: Generic AM43 (Flattened Device Tree)
 [   73.384439] [<c0016f14>] (unwind_backtrace) from [<c001339c>] (show_stack+0x10/0x14)
 [   73.392566] [<c001339c>] (show_stack) from [<c0636cec>] (dump_stack+0x84/0x9c)
 [   73.400164] [<c0636cec>] (dump_stack) from [<c003db48>] (warn_slowpath_common+0x78/0xb4)
 [   73.408649] [<c003db48>] (warn_slowpath_common) from [<c003dbb4>] (warn_slowpath_fmt+0x30/0x40)
 [   73.417783] [<c003dbb4>] (warn_slowpath_fmt) from [<c03473e4>] (kobject_add_internal+0x25c/0x2d8)
 [   73.427063] [<c03473e4>] (kobject_add_internal) from [<c03474ac>] (kobject_add+0x4c/0x98)
 [   73.435641] [<c03474ac>] (kobject_add) from [<c03d8a58>] (device_add+0xd4/0x56c)
 [   73.443466] [<c03d8a58>] (device_add) from [<bf2c17b0>] (usb_create_ep_devs+0x60/0xac [usbcore])
 [   73.452788] [<bf2c17b0>] (usb_create_ep_devs [usbcore]) from [<bf2bb210>] (create_intf_ep_devs+0x48/0x70 [usbcore])
 [   73.463801] [<bf2bb210>] (create_intf_ep_devs [usbcore]) from [<bf2bbae0>] (usb_set_interface+0x1c4/0x2f4 [usbcore])
 [   73.474891] [<bf2bbae0>] (usb_set_interface [usbcore]) from [<bf33d370>] (usbtest_ioctl+0x840/0x14c8 [usbtest])
 [   73.485659] [<bf33d370>] (usbtest_ioctl [usbtest]) from [<bf2c569c>] (usbdev_ioctl+0x1728/0x17fc [usbcore])
 [   73.495947] [<bf2c569c>] (usbdev_ioctl [usbcore]) from [<c0185764>] (do_vfs_ioctl+0x3f4/0x6c4)
 [   73.504989] [<c0185764>] (do_vfs_ioctl) from [<c0185aa0>] (SyS_ioctl+0x6c/0x7c)
 [   73.512662] [<c0185aa0>] (SyS_ioctl) from [<c000f540>] (ret_fast_syscall+0x0/0x54)
 [   73.520605] ---[ end trace 4576b2ea698fb13f ]---


-- 
balbi
-------------- next part --------------
A non-text attachment was scrubbed...
Name: signature.asc
Type: application/pgp-signature
Size: 819 bytes
Desc: Digital signature
URL: <http://lists.infradead.org/pipermail/linux-arm-kernel/attachments/20150820/a85def20/attachment.sig>

From maxime.ripard at free-electrons.com  Thu Aug 20 08:45:45 2015
From: maxime.ripard at free-electrons.com (Maxime Ripard)
Date: Thu, 20 Aug 2015 17:45:45 +0200
Subject: [linux-sunxi][PATCH] ARM: sun7i: dt: Add new Olimex A20 EVB device
In-Reply-To: <1440002596-2611-1-git-send-email-codekipper@gmail.com>
References: <1440002596-2611-1-git-send-email-codekipper@gmail.com>
Message-ID: <20150820154545.GF30520@lukather>

Hi,

On Wed, Aug 19, 2015 at 06:43:16PM +0200, codekipper at gmail.com wrote:
> From: Marcus Cooper <codekipper at gmail.com>
> 
> The A20-SOM-EVB is a reference design of a 2-layer board for the
> A20-SOM.
> It expands the features of A20-SOM by adding VGA connector, HDMI
> connector, audio In/Out, LCD connector, 2 Mpix camera, gigabit
> Ethernet, SATA, USB-OTG and 2 USB hosts.
> 
> This patch adds basic support for the device
> https://www.olimex.com/Products/SOM/A20/A20-SOM-EVB/
> 
> More information on the SOM can be found here
> http://linux-sunxi.org/Olimex_A20-SOM.
> 
> Signed-off-by: Marcus Cooper <codekipper at gmail.com>

Is there any other SOM planned that could work with that baseboard? Or
any other baseboard for that SOM?

> ---
>  arch/arm/boot/dts/Makefile                    |   1 +
>  arch/arm/boot/dts/sun7i-a20-olinuxino-evb.dts | 233 ++++++++++++++++++++++++++
>  2 files changed, 234 insertions(+)
>  create mode 100644 arch/arm/boot/dts/sun7i-a20-olinuxino-evb.dts
> 
> diff --git a/arch/arm/boot/dts/Makefile b/arch/arm/boot/dts/Makefile
> index 6d7cec1..fdbda9b 100644
> --- a/arch/arm/boot/dts/Makefile
> +++ b/arch/arm/boot/dts/Makefile
> @@ -613,6 +613,7 @@ dtb-$(CONFIG_MACH_SUN7I) += \
>  	sun7i-a20-olinuxino-lime.dtb \
>  	sun7i-a20-olinuxino-lime2.dtb \
>  	sun7i-a20-olinuxino-micro.dtb \
> +	sun7i-a20-olinuxino-evb.dtb \
>  	sun7i-a20-orangepi.dtb \
>  	sun7i-a20-orangepi-mini.dtb \
>  	sun7i-a20-pcduino3.dtb \
> diff --git a/arch/arm/boot/dts/sun7i-a20-olinuxino-evb.dts b/arch/arm/boot/dts/sun7i-a20-olinuxino-evb.dts
> new file mode 100644
> index 0000000..a0071fa
> --- /dev/null
> +++ b/arch/arm/boot/dts/sun7i-a20-olinuxino-evb.dts
> @@ -0,0 +1,233 @@
> +/*
> + * Copyright 2015 - Marcus Cooper <codekipper at gmail.com>
> + *
> + * This file is dual-licensed: you can use it either under the terms
> + * of the GPL or the X11 license, at your option. Note that this dual
> + * licensing only applies to this file, and not this project as a
> + * whole.
> + *
> + *  a) This file is free software; you can redistribute it and/or
> + *     modify it under the terms of the GNU General Public License as
> + *     published by the Free Software Foundation; either version 2 of the
> + *     License, or (at your option) any later version.
> + *
> + *     This file is distributed in the hope that it will be useful,
> + *     but WITHOUT ANY WARRANTY; without even the implied warranty of
> + *     MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
> + *     GNU General Public License for more details.
> + *
> + * Or, alternatively,
> + *
> + *  b) Permission is hereby granted, free of charge, to any person
> + *     obtaining a copy of this software and associated documentation
> + *     files (the "Software"), to deal in the Software without
> + *     restriction, including without limitation the rights to use,
> + *     copy, modify, merge, publish, distribute, sublicense, and/or
> + *     sell copies of the Software, and to permit persons to whom the
> + *     Software is furnished to do so, subject to the following
> + *     conditions:
> + *
> + *     The above copyright notice and this permission notice shall be
> + *     included in all copies or substantial portions of the Software.
> + *
> + *     THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
> + *     EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES
> + *     OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
> + *     NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT
> + *     HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY,
> + *     WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
> + *     FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR
> + *     OTHER DEALINGS IN THE SOFTWARE.
> + */
> +
> +/dts-v1/;
> +#include "sun7i-a20.dtsi"
> +#include "sunxi-common-regulators.dtsi"
> +
> +#include <dt-bindings/gpio/gpio.h>
> +#include <dt-bindings/interrupt-controller/irq.h>
> +#include <dt-bindings/pinctrl/sun4i-a10.h>
> +
> +/ {
> +	model = "Olimex A20-OLinuXino-EVB";
> +	compatible = "olimex,a20-olinuxino-evb", "allwinner,sun7i-a20";
> +
> +	aliases {
> +		serial0 = &uart0;
> +	};
> +
> +	chosen {
> +		stdout-path = "serial0:115200n8";
> +	};
> +
> +	leds {
> +		compatible = "gpio-leds";
> +		pinctrl-names = "default";
> +		pinctrl-0 = <&led_pins_olinuxinoevb>;
> +
> +		green {
> +			label = "a20-olinuxino-evb:green:usr";
> +			gpios = <&pio 7 2 GPIO_ACTIVE_HIGH>;
> +			default-state = "on";
> +		};
> +	};
> +
> +	reg_axp_ipsout: axp_ipsout {
> +		compatible = "regulator-fixed";
> +		regulator-name = "axp-ipsout";
> +		regulator-min-microvolt = <5000000>;
> +		regulator-max-microvolt = <5000000>;
> +		regulator-always-on;
> +	};
> +};
> +
> +&ahci {
> +	target-supply = <&reg_ahci_5v>;
> +	status = "okay";
> +};
> +
> +&ehci0 {
> +	status = "okay";
> +};
> +
> +&ehci1 {
> +	status = "okay";
> +};
> +
> +&gmac {
> +	pinctrl-names = "default";
> +	pinctrl-0 = <&gmac_pins_rgmii_a>;
> +	phy = <&phy1>;
> +	phy-mode = "rgmii";
> +	status = "okay";
> +
> +	phy1: ethernet-phy at 1 {
> +		reg = <1>;
> +	};
> +};
> +
> +&i2c0 {
> +	pinctrl-names = "default";
> +	pinctrl-0 = <&i2c0_pins_a>;
> +	status = "okay";
> +
> +	axp209: pmic at 34 {
> +		compatible = "x-powers,axp209";
> +		reg = <0x34>;
> +		interrupt-parent = <&nmi_intc>;
> +		interrupts = <0 IRQ_TYPE_LEVEL_LOW>;
> +
> +		interrupt-controller;
> +		#interrupt-cells = <1>;
> +
> +		acin-supply = <&reg_axp_ipsout>;
> +		vin2-supply = <&reg_axp_ipsout>;
> +		vin3-supply = <&reg_axp_ipsout>;
> +		ldo24in-supply = <&reg_axp_ipsout>;
> +		ldo3in-supply = <&reg_axp_ipsout>;

Please use the axp209 dtsi.

> +
> +		regulators {
> +			vdd_rtc: ldo1 {
> +				regulator-min-microvolt = <1300000>;
> +				regulator-max-microvolt = <1300000>;
> +				regulator-always-on;
> +			};
> +
> +			avcc: ldo2 {
> +				regulator-min-microvolt = <1800000>;
> +				regulator-max-microvolt = <3300000>;
> +				regulator-always-on;
> +			};
> +
> +			vcc_csi0: ldo3 {
> +				regulator-min-microvolt = <700000>;
> +				regulator-max-microvolt = <3500000>;
> +				regulator-always-on;
> +			};
> +
> +			vcc_csi1: ldo4 {
> +				regulator-min-microvolt = <1250000>;
> +				regulator-max-microvolt = <3300000>;
> +				regulator-always-on;
> +			};

the csi regulators are always-on too? What function do they provide?

> +			vdd_cpu: dcdc2 {
> +				regulator-min-microvolt = <700000>;
> +				regulator-max-microvolt = <2275000>;

This is way outside of the CPU operating range. Are you sure of your
constraints?

> +				regulator-always-on;
> +			};
> +
> +			vdd_int: dcdc3 {
> +				regulator-min-microvolt = <700000>;
> +				regulator-max-microvolt = <3500000>;
> +				regulator-always-on;
> +			};
> +		};
> +	};
> +};
> +
> +&i2c1 {
> +	pinctrl-names = "default";
> +	pinctrl-0 = <&i2c1_pins_a>;
> +	status = "okay";
> +};
> +
> +&mmc0 {
> +	pinctrl-names = "default";
> +	pinctrl-0 = <&mmc0_pins_a>, <&mmc0_cd_pin_reference_design>;
> +	vmmc-supply = <&reg_vcc3v3>;
> +	bus-width = <4>;
> +	cd-gpios = <&pio 7 1 GPIO_ACTIVE_HIGH>; /* PH1 */
> +	cd-inverted;
> +	status = "okay";
> +};
> +
> +&ohci0 {
> +	status = "okay";
> +};
> +
> +&ohci1 {
> +	status = "okay";
> +};
> +
> +&pio {
> +	ahci_pwr_pin_olinuxinoevb: ahci_pwr_pin at 1 {
> +		allwinner,pins = "PC3";
> +		allwinner,function = "gpio_out";
> +		allwinner,drive = <SUN4I_PINCTRL_10_MA>;
> +		allwinner,pull = <SUN4I_PINCTRL_NO_PULL>;
> +	};
> +
> +	led_pins_olinuxinoevb: led_pins at 0 {
> +		allwinner,pins = "PH2";
> +		allwinner,function = "gpio_out";
> +		allwinner,drive = <SUN4I_PINCTRL_20_MA>;
> +		allwinner,pull = <SUN4I_PINCTRL_NO_PULL>;
> +	};
> +};
> +
> +&reg_ahci_5v {
> +	pinctrl-0 = <&ahci_pwr_pin_olinuxinoevb>;
> +	gpio = <&pio 2 3 GPIO_ACTIVE_HIGH>;
> +	status = "okay";
> +};
> +
> +&reg_usb1_vbus {
> +	status = "okay";
> +};
> +
> +&reg_usb2_vbus {
> +	status = "okay";
> +};
> +
> +&uart0 {
> +	pinctrl-names = "default";
> +	pinctrl-0 = <&uart0_pins_a>;
> +	status = "okay";
> +};
> +
> +&usbphy {
> +	usb1_vbus-supply = <&reg_usb1_vbus>;
> +	usb2_vbus-supply = <&reg_usb2_vbus>;
> +	status = "okay";
> +};
> -- 
> 2.5.0
> 

Thanks,
Maxime

-- 
Maxime Ripard, Free Electrons
Embedded Linux, Kernel and Android engineering
http://free-electrons.com
-------------- next part --------------
A non-text attachment was scrubbed...
Name: signature.asc
Type: application/pgp-signature
Size: 819 bytes
Desc: Digital signature
URL: <http://lists.infradead.org/pipermail/linux-arm-kernel/attachments/20150820/5daa9a37/attachment-0001.sig>

From wens at csie.org  Thu Aug 20 08:58:39 2015
From: wens at csie.org (Chen-Yu Tsai)
Date: Thu, 20 Aug 2015 23:58:39 +0800
Subject: [PATCH v3 1/8] rsb: Add generic Reduced Serial Bus (RSB)
 controller binding documentation
In-Reply-To: <20150820150845.GB30520@lukather>
References: <1439958009-14056-1-git-send-email-wens@csie.org>
 <1439958009-14056-2-git-send-email-wens@csie.org>
 <20150820150845.GB30520@lukather>
Message-ID: <CAGb2v65jnU859gQG0orb9M9pR6nKcth9EPcgmmR5fckdHxngrQ@mail.gmail.com>

On Thu, Aug 20, 2015 at 11:08 PM, Maxime Ripard
<maxime.ripard at free-electrons.com> wrote:
> Hi,
>
> Thanks a lot for working on this.
>
> On Wed, Aug 19, 2015 at 12:20:02PM +0800, Chen-Yu Tsai wrote:
>> Reduced Serial Bus is a proprietary 2-line push-pull serial bus
>> supporting multiple slave devices.
>>
>> It was developed by Allwinner, Inc. and used by Allwinner and X-Powers,
>> Inc. for their line of PMICs and other peripheral ICs.
>>
>> Signed-off-by: Chen-Yu Tsai <wens at csie.org>
>> ---
>>  Documentation/devicetree/bindings/rsb/rsb.txt | 50 +++++++++++++++++++++++++++
>>  1 file changed, 50 insertions(+)
>>  create mode 100644 Documentation/devicetree/bindings/rsb/rsb.txt
>>
>> diff --git a/Documentation/devicetree/bindings/rsb/rsb.txt b/Documentation/devicetree/bindings/rsb/rsb.txt
>> new file mode 100644
>> index 000000000000..0b027948ca9c
>> --- /dev/null
>> +++ b/Documentation/devicetree/bindings/rsb/rsb.txt
>> @@ -0,0 +1,50 @@
>> +Reduced Serial Bus (RSB) Controller
>> +
>> +This document defines a generic set of bindings for use by RSB controllers.
>> +A controller is modelled in device tree as a node with zero or more child
>> +nodes, each representing a unique slave device on the bus.
>> +
>> +Required properties:
>> +
>> + - #address-cells : must be 2
>> + - #size-cells : must be 0
>> +
>> +Optional properties:
>> +
>> + - clock-frequency : Desired bus clock frequency in Hz. Maximum is 20 MHz.
>
> What is the default if not set?

Presently the driver would have it default to 1 MHz, Which doesn't match
the driver binding. Will fix this.

>> +
>> +Child nodes:
>> +
>> +An RSB controller node can contain zero or more child nodes representing
>> +slave devices on the bus.  Child 'reg' properties are specified as a
>> +runtime address, hardware address pair. The hardware address is hardwired
>> +in the device, which can normally be found in the datasheet. The runtime
>> +address is set by software. No 2 devices on the same bus shall have the
>> +same runtime address.
>> +
>> +Valid runtime addresses - There are only 15 valid runtime addresses:
>> +
>> +    0x17, 0x2d, 0x3a, 0x4e, 0x59, 0x63, 0x74, 0x8b,
>> +    0x9c, 0xa6, 0xb1, 0xc5, 0xd2, 0xe8, 0xff
>> +
>> +It is highly recommended that one choose the same runtime addresses as
>> +vendor BSPs use so that a) the addresses remain the same across different
>> +software systems, and b) addresses of supported and listed slave devices
>> +don't conflict with unsupported or not yet listed devices.
>
> I'd expect to have the hardware address first, but maybe it's just me
> :)

I don't know. It's only used at init time.

And in my latest experience, once the runtime address is set by the
bootloader, it can't be changed. My earlier experience was the opposite,
though I haven't figured out why.

>
>> +Example:
>> +
>> +     rsb at ... {
>> +             compatible = "...";
>> +             reg = <...>;
>> +             /* ... */
>> +             #address-cells = <2>;
>> +             #size-cells = <0>;
>> +
>> +             pmic at 2d {
>
> The unit-address should be 2d,3e3.

Hmm... I didn't know this was legal.

>> +                     compatible = "...";
>> +                     reg = <0x2d 0x3e3>;
>> +
>> +                     /* ... */
>> +             };
>> +     };
>> --
>> 2.5.0
>>
>
> --
> Maxime Ripard, Free Electrons
> Embedded Linux, Kernel and Android engineering
> http://free-electrons.com


From gregory.clement at free-electrons.com  Thu Aug 20 09:12:33 2015
From: gregory.clement at free-electrons.com (Gregory CLEMENT)
Date: Thu, 20 Aug 2015 18:12:33 +0200
Subject: [PATCH] usb: musb: dsps: handle the otg_state_a_wait_vrise_timeout
 case
Message-ID: <1440087153-31084-1-git-send-email-gregory.clement@free-electrons.com>

According to the OTG specification after a timeout of
OTG_TIME_A_WAIT_VRISE (the maximum value is 100ms) the driver must
move from the state a_wait_vrise to the state a_wait_bcon. However,
the dsps version of musb does not handle this case.

Without it, the driver could remain stuck in the a_wait_vrise. It can
be reproduce with the following steps:

1) Boot a board with no USB adapter inserted
2) Insert an empty OTG adapter
3) Wait 2 seconds then remove the OTG adapter
4) The unit is now stuck in host mode, the VBUS switch is latched on
and the ID pin is no longer polled.

The only way to exit this state was to insert a OTG adapter with an
USB device connected. Until this, the usb device mode was not
available.

It was tested on a AM35x based board.

CC: <stable at vger.kernel.org>
Signed-off-by: Gregory CLEMENT <gregory.clement at free-electrons.com>
---
 drivers/usb/musb/musb_dsps.c | 14 +++++++++++++-
 1 file changed, 13 insertions(+), 1 deletion(-)

diff --git a/drivers/usb/musb/musb_dsps.c b/drivers/usb/musb/musb_dsps.c
index 65d931a..2d22683 100644
--- a/drivers/usb/musb/musb_dsps.c
+++ b/drivers/usb/musb/musb_dsps.c
@@ -145,6 +145,7 @@ struct dsps_glue {
 	struct timer_list timer;	/* otg_workaround timer */
 	unsigned long last_timer;    /* last timer data for each instance */
 	bool sw_babble_enabled;
+	int otg_state_a_wait_vrise_timeout;
 
 	struct dsps_context context;
 	struct debugfs_regset32 regset;
@@ -268,9 +269,18 @@ static void otg_timer(unsigned long _musb)
 
 	spin_lock_irqsave(&musb->lock, flags);
 	switch (musb->xceiv->otg->state) {
+	case OTG_STATE_A_WAIT_VRISE:
+		if ((glue->otg_state_a_wait_vrise_timeout)) {
+				musb->xceiv->otg->state = OTG_STATE_A_WAIT_BCON;
+				musb->is_active = 0;
+			}
+		mod_timer(&glue->timer, jiffies +
+			  msecs_to_jiffies(OTG_TIME_A_WAIT_VRISE));
+		break;
 	case OTG_STATE_A_WAIT_BCON:
 		dsps_writeb(musb->mregs, MUSB_DEVCTL, 0);
 		skip_session = 1;
+		glue->otg_state_a_wait_vrise_timeout = 0;
 		/* fall */
 
 	case OTG_STATE_A_IDLE:
@@ -359,7 +369,9 @@ static irqreturn_t dsps_interrupt(int irq, void *hci)
 			MUSB_HST_MODE(musb);
 			musb->xceiv->otg->default_a = 1;
 			musb->xceiv->otg->state = OTG_STATE_A_WAIT_VRISE;
-			del_timer(&glue->timer);
+			glue->otg_state_a_wait_vrise_timeout = 1;
+			mod_timer(&glue->timer, jiffies +
+				  msecs_to_jiffies(OTG_TIME_A_WAIT_VRISE));
 		} else {
 			musb->is_active = 0;
 			MUSB_DEV_MODE(musb);
-- 
2.1.0



From moritz.fischer at ettus.com  Thu Aug 20 09:27:57 2015
From: moritz.fischer at ettus.com (Moritz Fischer)
Date: Thu, 20 Aug 2015 09:27:57 -0700
Subject: [PATCH v3 2/2] drivers: rtc: add xilinx zynqmp rtc driver
In-Reply-To: <c713c202-1d5e-4656-9e4f-1e15bc4dac14@googlegroups.com>
References: <1439978002-12157-1-git-send-email-suneel.garapati@xilinx.com>
 <1439978002-12157-2-git-send-email-suneel.garapati@xilinx.com>
 <CAAtXAHf7Vngo8gz6cCRauxUSnrQgs4+UNGWpQ6wy0fvBPMQO_A@mail.gmail.com>
 <c713c202-1d5e-4656-9e4f-1e15bc4dac14@googlegroups.com>
Message-ID: <CAAtXAHfaUbS8a=7YkAxcdYMaQWhPVJhU_fMv9zTyh1eFSsOk_A@mail.gmail.com>

Hi Suneel

On Wed, Aug 19, 2015 at 9:37 PM,  <suneelgarapati at gmail.com> wrote:
> Hi Moritz,
>
> devm_ioremap_resource validates the argument pointer of struct resource.
> Hence no explicit validation of return value of platform_get_resource
> function.
> It seems to be common practice with all other drivers in drivers/rtc.

Fair enough.

Acked-by: Moritz Fischer <moritz.fischer at ettus.com>
>
> Regards,
> Suneel
>
> On Wednesday, August 19, 2015 at 11:49:49 PM UTC+5:30, Moritz Fischer wrote:
>>
>> Hi Suneel,
>>
>> looks good, minor nit below.
>>
>> On Wed, Aug 19, 2015 at 2:53 AM, Suneel Garapati
>> <suneel.... at xilinx.com> wrote:
>> > adds support for RTC controller found on
>> > Xilinx Zynq Ultrascale+ MPSoC platform.
>> >
>> > Signed-off-by: Suneel Garapati <suneel.... at xilinx.com>
>> > ---
>> > Changes v3
>> > - fix checkpatch errors
>> > - check time in secs arg against max sec val
>> > - order header files
>> > - use ptr_err_or_zero macro
>> > - use time64 variants
>> > Changes v2
>> > - change alm to alarm
>> > ---
>> >  drivers/rtc/Kconfig      |   7 ++
>> >  drivers/rtc/Makefile     |   1 +
>> >  drivers/rtc/rtc-zynqmp.c | 279
>> > +++++++++++++++++++++++++++++++++++++++++++++++
>> >  3 files changed, 287 insertions(+)
>> >  create mode 100644 drivers/rtc/rtc-zynqmp.c
>> >
>> > diff --git a/drivers/rtc/Kconfig b/drivers/rtc/Kconfig
>> > index 35ea04c..bc96277 100644
>> > --- a/drivers/rtc/Kconfig
>> > +++ b/drivers/rtc/Kconfig
>> > @@ -1116,6 +1116,13 @@ config RTC_DRV_OPAL
>> >           This driver can also be built as a module. If so, the module
>> >           will be called rtc-opal.
>> >
>> > +config RTC_DRV_ZYNQMP
>> > +       tristate "Xilinx Zynq Ultrascale+ MPSoC RTC"
>> > +       depends on OF
>> > +       help
>> > +         If you say yes here you get support for the RTC controller
>> > found on
>> > +         Xilinx Zynq Ultrascale+ MPSoC.
>> > +
>> >  comment "on-CPU RTC drivers"
>> >
>> >  config RTC_DRV_DAVINCI
>> > diff --git a/drivers/rtc/Makefile b/drivers/rtc/Makefile
>> > index 2797384..e491eb5 100644
>> > --- a/drivers/rtc/Makefile
>> > +++ b/drivers/rtc/Makefile
>> > @@ -159,3 +159,4 @@ obj-$(CONFIG_RTC_DRV_WM831X)        += rtc-wm831x.o
>> >  obj-$(CONFIG_RTC_DRV_WM8350)   += rtc-wm8350.o
>> >  obj-$(CONFIG_RTC_DRV_X1205)    += rtc-x1205.o
>> >  obj-$(CONFIG_RTC_DRV_XGENE)    += rtc-xgene.o
>> > +obj-$(CONFIG_RTC_DRV_ZYNQMP)   += rtc-zynqmp.o
>> > diff --git a/drivers/rtc/rtc-zynqmp.c b/drivers/rtc/rtc-zynqmp.c
>> > new file mode 100644
>> > index 0000000..8b28762
>> > --- /dev/null
>> > +++ b/drivers/rtc/rtc-zynqmp.c
>> > @@ -0,0 +1,279 @@
>> > +/*
>> > + * Xilinx Zynq Ultrascale+ MPSoC Real Time Clock Driver
>> > + *
>> > + * Copyright (C) 2015 Xilinx, Inc.
>> > + *
>> > + * This program is free software; you can redistribute it and/or modify
>> > it
>> > + * under the terms and conditions of the GNU General Public License,
>> > + * version 2, as published by the Free Software Foundation.
>> > + *
>> > + * This program is distributed in the hope 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.
>> > + *
>> > + * You should have received a copy of the GNU General Public License
>> > along with
>> > + * this program. If not, see <http://www.gnu.org/licenses/>.
>> > + *
>> > + */
>> > +
>> > +#include <linux/delay.h>
>> > +#include <linux/init.h>
>> > +#include <linux/io.h>
>> > +#include <linux/module.h>
>> > +#include <linux/of.h>
>> > +#include <linux/platform_device.h>
>> > +#include <linux/rtc.h>
>> > +
>> > +/* RTC Registers */
>> > +#define RTC_SET_TM_WR          0x00
>> > +#define RTC_SET_TM_RD          0x04
>> > +#define RTC_CALIB_WR           0x08
>> > +#define RTC_CALIB_RD           0x0C
>> > +#define RTC_CUR_TM             0x10
>> > +#define RTC_CUR_TICK           0x14
>> > +#define RTC_ALRM               0x18
>> > +#define RTC_INT_STS            0x20
>> > +#define RTC_INT_MASK           0x24
>> > +#define RTC_INT_EN             0x28
>> > +#define RTC_INT_DIS            0x2C
>> > +#define RTC_CTRL               0x40
>> > +
>> > +#define RTC_FR_EN              BIT(20)
>> > +#define RTC_FR_DATSHIFT                16
>> > +#define RTC_TICK_MASK          0xFFFF
>> > +#define RTC_INT_SEC            BIT(0)
>> > +#define RTC_INT_ALRM           BIT(1)
>> > +#define RTC_OSC_EN             BIT(24)
>> > +
>> > +#define RTC_CALIB_DEF          0x198233
>> > +#define RTC_CALIB_MASK         0x1FFFFF
>> > +#define RTC_SEC_MAX_VAL                0xFFFFFFFF
>> > +
>> > +struct xlnx_rtc_dev {
>> > +       struct rtc_device       *rtc;
>> > +       void __iomem            *reg_base;
>> > +       int                     alarm_irq;
>> > +       int                     sec_irq;
>> > +};
>> > +
>> > +static int xlnx_rtc_set_time(struct device *dev, struct rtc_time *tm)
>> > +{
>> > +       struct xlnx_rtc_dev *xrtcdev = dev_get_drvdata(dev);
>> > +       unsigned long new_time;
>> > +
>> > +       new_time = rtc_tm_to_time64(tm);
>> > +
>> > +       if (new_time > RTC_SEC_MAX_VAL)
>> > +               return -EINVAL;
>> > +
>> > +       writel(new_time, xrtcdev->reg_base + RTC_SET_TM_WR);
>> > +
>> > +       return 0;
>> > +}
>> > +
>> > +static int xlnx_rtc_read_time(struct device *dev, struct rtc_time *tm)
>> > +{
>> > +       struct xlnx_rtc_dev *xrtcdev = dev_get_drvdata(dev);
>> > +
>> > +       rtc_time64_to_tm(readl(xrtcdev->reg_base + RTC_CUR_TM), tm);
>> > +
>> > +       return rtc_valid_tm(tm);
>> > +}
>> > +
>> > +static int xlnx_rtc_read_alarm(struct device *dev, struct rtc_wkalrm
>> > *alrm)
>> > +{
>> > +       struct xlnx_rtc_dev *xrtcdev = dev_get_drvdata(dev);
>> > +
>> > +       rtc_time64_to_tm(readl(xrtcdev->reg_base + RTC_ALRM),
>> > &alrm->time);
>> > +       alrm->enabled = readl(xrtcdev->reg_base + RTC_INT_MASK) &
>> > RTC_INT_ALRM;
>> > +
>> > +       return 0;
>> > +}
>> > +
>> > +static int xlnx_rtc_alarm_irq_enable(struct device *dev, u32 enabled)
>> > +{
>> > +       struct xlnx_rtc_dev *xrtcdev = dev_get_drvdata(dev);
>> > +
>> > +       if (enabled)
>> > +               writel(RTC_INT_ALRM, xrtcdev->reg_base + RTC_INT_EN);
>> > +       else
>> > +               writel(RTC_INT_ALRM, xrtcdev->reg_base + RTC_INT_DIS);
>> > +
>> > +       return 0;
>> > +}
>> > +
>> > +static int xlnx_rtc_set_alarm(struct device *dev, struct rtc_wkalrm
>> > *alrm)
>> > +{
>> > +       struct xlnx_rtc_dev *xrtcdev = dev_get_drvdata(dev);
>> > +       unsigned long alarm_time;
>> > +
>> > +       alarm_time = rtc_tm_to_time64(&alrm->time);
>> > +
>> > +       if (alarm_time > RTC_SEC_MAX_VAL)
>> > +               return -EINVAL;
>> > +
>> > +       writel((u32)alarm_time, (xrtcdev->reg_base + RTC_ALRM));
>> > +
>> > +       xlnx_rtc_alarm_irq_enable(dev, alrm->enabled);
>> > +
>> > +       return 0;
>> > +}
>> > +
>> > +static void xlnx_init_rtc(struct xlnx_rtc_dev *xrtcdev, u32 calibval)
>> > +{
>> > +       /*
>> > +        * Based on crystal freq of 33.330 KHz
>> > +        * set the seconds counter and enable, set fractions counter
>> > +        * to default value suggested as per design spec
>> > +        * to correct RTC delay in frequency over period of time.
>> > +        */
>> > +       calibval &= RTC_CALIB_MASK;
>> > +       writel(calibval, (xrtcdev->reg_base + RTC_CALIB_WR));
>> > +}
>> > +
>> > +static const struct rtc_class_ops xlnx_rtc_ops = {
>> > +       .set_time         = xlnx_rtc_set_time,
>> > +       .read_time        = xlnx_rtc_read_time,
>> > +       .read_alarm       = xlnx_rtc_read_alarm,
>> > +       .set_alarm        = xlnx_rtc_set_alarm,
>> > +       .alarm_irq_enable = xlnx_rtc_alarm_irq_enable,
>> > +};
>> > +
>> > +static irqreturn_t xlnx_rtc_interrupt(int irq, void *id)
>> > +{
>> > +       struct xlnx_rtc_dev *xrtcdev = (struct xlnx_rtc_dev *)id;
>> > +       unsigned int status;
>> > +
>> > +       status = readl(xrtcdev->reg_base + RTC_INT_STS);
>> > +       /* Check if interrupt asserted */
>> > +       if (!(status & (RTC_INT_SEC | RTC_INT_ALRM)))
>> > +               return IRQ_NONE;
>> > +
>> > +       /* Clear interrupt */
>> > +       writel(status, xrtcdev->reg_base + RTC_INT_STS);
>> > +
>> > +       if (status & RTC_INT_SEC)
>> > +               rtc_update_irq(xrtcdev->rtc, 1, RTC_IRQF | RTC_UF);
>> > +       if (status & RTC_INT_ALRM)
>> > +               rtc_update_irq(xrtcdev->rtc, 1, RTC_IRQF | RTC_AF);
>> > +
>> > +       return IRQ_HANDLED;
>> > +}
>> > +
>> > +static int xlnx_rtc_probe(struct platform_device *pdev)
>> > +{
>> > +       struct xlnx_rtc_dev *xrtcdev;
>> > +       struct resource *res;
>> > +       int ret;
>> > +       unsigned int calibvalue;
>> > +
>> > +       xrtcdev = devm_kzalloc(&pdev->dev, sizeof(*xrtcdev),
>> > GFP_KERNEL);
>> > +       if (!xrtcdev)
>> > +               return -ENOMEM;
>> > +
>> > +       platform_set_drvdata(pdev, xrtcdev);
>> > +
>> > +       res = platform_get_resource(pdev, IORESOURCE_MEM, 0);
>> Do you want to check for return value here?
>> > +
>> > +       xrtcdev->reg_base = devm_ioremap_resource(&pdev->dev, res);
>> > +       if (IS_ERR(xrtcdev->reg_base))
>> > +               return PTR_ERR(xrtcdev->reg_base);
>> > +
>> > +       xrtcdev->alarm_irq = platform_get_irq_byname(pdev, "alarm");
>> > +       if (xrtcdev->alarm_irq < 0) {
>> > +               dev_err(&pdev->dev, "no irq resource\n");
>> > +               return xrtcdev->alarm_irq;
>> > +       }
>> > +       ret = devm_request_irq(&pdev->dev, xrtcdev->alarm_irq,
>> > +                              xlnx_rtc_interrupt, 0,
>> > +                              dev_name(&pdev->dev), xrtcdev);
>> > +       if (ret) {
>> > +               dev_err(&pdev->dev, "request irq failed\n");
>> > +               return ret;
>> > +       }
>> > +
>> > +       xrtcdev->sec_irq = platform_get_irq_byname(pdev, "sec");
>> > +       if (xrtcdev->sec_irq < 0) {
>> > +               dev_err(&pdev->dev, "no irq resource\n");
>> > +               return xrtcdev->sec_irq;
>> > +       }
>> > +       ret = devm_request_irq(&pdev->dev, xrtcdev->sec_irq,
>> > +                              xlnx_rtc_interrupt, 0,
>> > +                              dev_name(&pdev->dev), xrtcdev);
>> > +       if (ret) {
>> > +               dev_err(&pdev->dev, "request irq failed\n");
>> > +               return ret;
>> > +       }
>> > +
>> > +       ret = of_property_read_u32(pdev->dev.of_node, "calibration",
>> > +                                  &calibvalue);
>> > +       if (ret)
>> > +               calibvalue = RTC_CALIB_DEF;
>> > +
>> > +       xlnx_init_rtc(xrtcdev, calibvalue);
>> > +
>> > +       device_init_wakeup(&pdev->dev, 1);
>> > +
>> > +       xrtcdev->rtc = devm_rtc_device_register(&pdev->dev, pdev->name,
>> > +                                        &xlnx_rtc_ops, THIS_MODULE);
>> > +       return PTR_ERR_OR_ZERO(xrtcdev->rtc);
>> > +}
>> > +
>> > +static int xlnx_rtc_remove(struct platform_device *pdev)
>> > +{
>> > +       xlnx_rtc_alarm_irq_enable(&pdev->dev, 0);
>> > +       device_init_wakeup(&pdev->dev, 0);
>> > +
>> > +       return 0;
>> > +}
>> > +
>> > +static int __maybe_unused xlnx_rtc_suspend(struct device *dev)
>> > +{
>> > +       struct platform_device *pdev = to_platform_device(dev);
>> > +       struct xlnx_rtc_dev *xrtcdev = platform_get_drvdata(pdev);
>> > +
>> > +       if (device_may_wakeup(&pdev->dev))
>> > +               enable_irq_wake(xrtcdev->alarm_irq);
>> > +       else
>> > +               xlnx_rtc_alarm_irq_enable(dev, 0);
>> > +
>> > +       return 0;
>> > +}
>> > +
>> > +static int __maybe_unused xlnx_rtc_resume(struct device *dev)
>> > +{
>> > +       struct platform_device *pdev = to_platform_device(dev);
>> > +       struct xlnx_rtc_dev *xrtcdev = platform_get_drvdata(pdev);
>> > +
>> > +       if (device_may_wakeup(&pdev->dev))
>> > +               disable_irq_wake(xrtcdev->alarm_irq);
>> > +       else
>> > +               xlnx_rtc_alarm_irq_enable(dev, 1);
>> > +
>> > +       return 0;
>> > +}
>> > +
>> > +static SIMPLE_DEV_PM_OPS(xlnx_rtc_pm_ops, xlnx_rtc_suspend,
>> > xlnx_rtc_resume);
>> > +
>> > +static const struct of_device_id xlnx_rtc_of_match[] = {
>> > +       {.compatible = "xlnx,zynqmp-rtc" },
>> > +       { }
>> > +};
>> > +MODULE_DEVICE_TABLE(of, xlnx_rtc_of_match);
>> > +
>> > +static struct platform_driver xlnx_rtc_driver = {
>> > +       .probe          = xlnx_rtc_probe,
>> > +       .remove         = xlnx_rtc_remove,
>> > +       .driver         = {
>> > +               .name   = KBUILD_MODNAME,
>> > +               .pm     = &xlnx_rtc_pm_ops,
>> > +               .of_match_table = xlnx_rtc_of_match,
>> > +       },
>> > +};
>> > +
>> > +module_platform_driver(xlnx_rtc_driver);
>> > +
>> > +MODULE_DESCRIPTION("Xilinx Zynq MPSoC RTC driver");
>> > +MODULE_AUTHOR("Xilinx Inc.");
>> > +MODULE_LICENSE("GPL v2");
>> > --
>> > 2.1.2
>> >
>> >
>> > _______________________________________________
>> > linux-arm-kernel mailing list
>> > linux-ar... at lists.infradead.org
>> > http://lists.infradead.org/mailman/listinfo/linux-arm-kernel
>>
>> Cheers,
>>
>> Moritz

Cheers,

Moritz


From r.baldyga at hackerion.com  Thu Aug 20 09:28:14 2015
From: r.baldyga at hackerion.com (Robert Baldyga)
Date: Thu, 20 Aug 2015 18:28:14 +0200
Subject: [PATCH v5 01/46] usb: gadget: encapsulate endpoint claiming
 mechanism
In-Reply-To: <20150820153553.GD1639@saruman.tx.rr.com>
References: <1438351258-31578-1-git-send-email-r.baldyga@samsung.com>
 <1438351258-31578-2-git-send-email-r.baldyga@samsung.com>
 <20150820153553.GD1639@saruman.tx.rr.com>
Message-ID: <55D6001E.3000504@hackerion.com>

Hi Felipe,

On 08/20/2015 05:35 PM, Felipe Balbi wrote:
[...]
> just letting you know that this regresses all gadget drivers making them
> try to disable previously disabled endpoints and enable previously
> enabled endpoints.
>
> I have a possible fix (see below) but then it shows a problem on the
> host side when using with g_zero (see further below):
>
> commit 3b8932100aacb6cfbffe288ca93025d8b8430c00
> Author: Felipe Balbi <balbi at ti.com>
> Date:   Wed Aug 19 18:05:27 2015 -0500
>
>      usb: gadget: fix ep->claimed lifetime
>
>      In order to fix a regression introduced by commit
>      cc476b42a39d ("usb: gadget: encapsulate endpoint
>      claiming mechanism") we have to introduce a simple
>      helper to check if a particular is enabled or not.
>
>      After that, we need to move ep->claimed lifetime to
>      usb_ep_enable() and usb_ep_disable() since those
>      are the only functions which actually enable and
>      disable endpoints.
>
>      A follow-up patch will come to drop all driver_data
>      checks from function drivers, since those are, now,
>      pointless.
>
>      Fixes: cc476b42a39d ("usb: gadget: encapsulate endpoint
>      	claiming mechanism")
>      Cc: Robert Baldyga <r.baldyga at samsung.com>
>      Signed-off-by: Felipe Balbi <balbi at ti.com>
>
> diff --git a/drivers/usb/gadget/epautoconf.c b/drivers/usb/gadget/epautoconf.c
> index 978435a51038..ad45070cd76f 100644
> --- a/drivers/usb/gadget/epautoconf.c
> +++ b/drivers/usb/gadget/epautoconf.c
> @@ -126,7 +126,6 @@ found_ep:
>   	ep->address = desc->bEndpointAddress;
>   	ep->desc = NULL;
>   	ep->comp_desc = NULL;
> -	ep->claimed = true;

Removing this line causes autoconfig can return the same endpoint many 
times. This probably causes problems with g_zero.

I will try to fix it ASAP.

Thanks,
Robert



From marc.zyngier at arm.com  Thu Aug 20 09:28:38 2015
From: marc.zyngier at arm.com (Marc Zyngier)
Date: Thu, 20 Aug 2015 17:28:38 +0100
Subject: [GIT PULL] KVM/ARM pull request for 4.3
Message-ID: <1440088143-4722-1-git-send-email-marc.zyngier@arm.com>

Hi Paolo,

This is the KVM/ARM pull request for Linux 4.3. Some rather major
things this time around (guest debug, management of interrupt active
state, lazy FP save/restore).

Thanks!

	M.

The following changes since commit bc0195aad0daa2ad5b0d76cce22b167bc3435590:

  Linux 4.2-rc2 (2015-07-12 15:10:30 -0700)

are available in the git repository at:

  git://git.kernel.org/pub/scm/linux/kernel/git/kvmarm/kvmarm.git tags/kvm-arm-for-4.3

for you to fetch changes up to 054167b3d55127feb64978eddf3f9f3a84fe493b:

  arm: KVM: keep arm vfp/simd exit handling consistent with arm64 (2015-08-19 22:27:58 +0100)

----------------------------------------------------------------
KVM/ARM changes for 4.3

- Full debug support for arm64
- Active state switching for timer interrupts
- Lazy FP/SIMD save/restore for arm64
- Generic ARMv8 target

----------------------------------------------------------------
Alex Benn?e (11):
      KVM: add comments for kvm_debug_exit_arch struct
      KVM: arm64: guest debug, define API headers
      KVM: arm: guest debug, add stub KVM_SET_GUEST_DEBUG ioctl
      KVM: arm: introduce kvm_arm_init/setup/clear_debug
      KVM: arm64: guest debug, add SW break point support
      KVM: arm64: guest debug, add support for single-step
      KVM: arm64: re-factor hyp.S debug register code
      KVM: arm64: introduce vcpu->arch.debug_ptr
      KVM: arm64: guest debug, HW assisted debug support
      KVM: arm64: enable KVM_CAP_SET_GUEST_DEBUG
      KVM: arm64: add trace points for guest_debug debug

Marc Zyngier (10):
      arm/arm64: KVM: Fix ordering of timer/GIC on guest entry
      arm/arm64: KVM: Move vgic handling to a non-preemptible section
      KVM: arm/arm64: vgic: Convert struct vgic_lr to use bitfields
      KVM: arm/arm64: vgic: Allow HW irq to be encoded in LR
      KVM: arm/arm64: vgic: Relax vgic_can_sample_irq for edge IRQs
      KVM: arm/arm64: vgic: Allow dynamic mapping of physical/virtual interrupts
      KVM: arm/arm64: vgic: Allow HW interrupts to be queued to a guest
      KVM: arm/arm64: vgic: Add vgic_{get,set}_phys_irq_active
      KVM: arm/arm64: vgic: Prevent userspace injection of a mapped interrupt
      KVM: arm/arm64: timer: Allow the timer to control the active state

Mario Smarduch (2):
      arm64: KVM: Optimize arm64 skip 30-50% vfp/simd save/restore on exits
      arm: KVM: keep arm vfp/simd exit handling consistent with arm64

Suzuki K. Poulose (1):
      arm64/kvm: Add generic v8 KVM target

Vladimir Murzin (1):
      arm64: KVM: remove remaining reference to vgic_sr_vectors

 Documentation/virtual/kvm/api.txt      |  15 +-
 arch/arm/include/asm/kvm_host.h        |   5 +
 arch/arm/kvm/arm.c                     |  36 +-
 arch/arm/kvm/guest.c                   |   6 +
 arch/arm/kvm/interrupts.S              |  14 +-
 arch/arm/kvm/reset.c                   |   4 +-
 arch/arm64/include/asm/hw_breakpoint.h |  14 +
 arch/arm64/include/asm/kvm_arm.h       |   5 +-
 arch/arm64/include/asm/kvm_asm.h       |  26 +-
 arch/arm64/include/asm/kvm_host.h      |  42 ++-
 arch/arm64/include/uapi/asm/kvm.h      |  37 +-
 arch/arm64/kernel/asm-offsets.c        |   9 +-
 arch/arm64/kernel/hw_breakpoint.c      |  12 -
 arch/arm64/kvm/Makefile                |   2 +-
 arch/arm64/kvm/debug.c                 | 217 ++++++++++++
 arch/arm64/kvm/guest.c                 |  43 ++-
 arch/arm64/kvm/handle_exit.c           |  44 +++
 arch/arm64/kvm/hyp.S                   | 617 ++++++++++++---------------------
 arch/arm64/kvm/reset.c                 |  20 +-
 arch/arm64/kvm/sys_regs.c              | 291 ++++++++++++++--
 arch/arm64/kvm/sys_regs.h              |   6 +
 arch/arm64/kvm/sys_regs_generic_v8.c   |   2 +
 arch/arm64/kvm/trace.h                 | 123 +++++++
 include/kvm/arm_arch_timer.h           |   7 +-
 include/kvm/arm_vgic.h                 |  39 ++-
 include/linux/irqchip/arm-gic-v3.h     |   3 +
 include/linux/irqchip/arm-gic.h        |   3 +-
 include/uapi/linux/kvm.h               |   5 +
 virt/kvm/arm/arch_timer.c              |  29 +-
 virt/kvm/arm/vgic-v2.c                 |  16 +-
 virt/kvm/arm/vgic-v3.c                 |  21 +-
 virt/kvm/arm/vgic.c                    | 427 +++++++++++++++++++++--
 32 files changed, 1596 insertions(+), 544 deletions(-)
 create mode 100644 arch/arm64/kvm/debug.c


From marc.zyngier at arm.com  Thu Aug 20 09:28:40 2015
From: marc.zyngier at arm.com (Marc Zyngier)
Date: Thu, 20 Aug 2015 17:28:40 +0100
Subject: [PATCH 02/25] KVM: arm64: guest debug, define API headers
In-Reply-To: <1440088143-4722-1-git-send-email-marc.zyngier@arm.com>
References: <1440088143-4722-1-git-send-email-marc.zyngier@arm.com>
Message-ID: <1440088143-4722-3-git-send-email-marc.zyngier@arm.com>

From: Alex Benn?e <alex.bennee at linaro.org>

This commit defines the API headers for guest debugging. There are two
architecture specific debug structures:

  - kvm_guest_debug_arch, allows us to pass in HW debug registers
  - kvm_debug_exit_arch, signals exception and possible faulting address

The type of debugging being used is controlled by the architecture
specific control bits of the kvm_guest_debug->control flags in the ioctl
structure.

Signed-off-by: Alex Benn?e <alex.bennee at linaro.org>
Reviewed-by: David Hildenbrand <dahi at linux.vnet.ibm.com>
Reviewed-by: Andrew Jones <drjones at redhat.com>
Acked-by: Christoffer Dall <christoffer.dall at linaro.org>
Signed-off-by: Marc Zyngier <marc.zyngier at arm.com>
---
 arch/arm64/include/uapi/asm/kvm.h | 27 +++++++++++++++++++++++++++
 1 file changed, 27 insertions(+)

diff --git a/arch/arm64/include/uapi/asm/kvm.h b/arch/arm64/include/uapi/asm/kvm.h
index d268320..d82f3f3 100644
--- a/arch/arm64/include/uapi/asm/kvm.h
+++ b/arch/arm64/include/uapi/asm/kvm.h
@@ -100,12 +100,39 @@ struct kvm_sregs {
 struct kvm_fpu {
 };
 
+/*
+ * See v8 ARM ARM D7.3: Debug Registers
+ *
+ * The architectural limit is 16 debug registers of each type although
+ * in practice there are usually less (see ID_AA64DFR0_EL1).
+ *
+ * Although the control registers are architecturally defined as 32
+ * bits wide we use a 64 bit structure here to keep parity with
+ * KVM_GET/SET_ONE_REG behaviour which treats all system registers as
+ * 64 bit values. It also allows for the possibility of the
+ * architecture expanding the control registers without having to
+ * change the userspace ABI.
+ */
+#define KVM_ARM_MAX_DBG_REGS 16
 struct kvm_guest_debug_arch {
+	__u64 dbg_bcr[KVM_ARM_MAX_DBG_REGS];
+	__u64 dbg_bvr[KVM_ARM_MAX_DBG_REGS];
+	__u64 dbg_wcr[KVM_ARM_MAX_DBG_REGS];
+	__u64 dbg_wvr[KVM_ARM_MAX_DBG_REGS];
 };
 
 struct kvm_debug_exit_arch {
+	__u32 hsr;
+	__u64 far;	/* used for watchpoints */
 };
 
+/*
+ * Architecture specific defines for kvm_guest_debug->control
+ */
+
+#define KVM_GUESTDBG_USE_SW_BP		(1 << 16)
+#define KVM_GUESTDBG_USE_HW		(1 << 17)
+
 struct kvm_sync_regs {
 };
 
-- 
2.1.4



From marc.zyngier at arm.com  Thu Aug 20 09:28:41 2015
From: marc.zyngier at arm.com (Marc Zyngier)
Date: Thu, 20 Aug 2015 17:28:41 +0100
Subject: [PATCH 03/25] KVM: arm: guest debug,
 add stub KVM_SET_GUEST_DEBUG ioctl
In-Reply-To: <1440088143-4722-1-git-send-email-marc.zyngier@arm.com>
References: <1440088143-4722-1-git-send-email-marc.zyngier@arm.com>
Message-ID: <1440088143-4722-4-git-send-email-marc.zyngier@arm.com>

From: Alex Benn?e <alex.bennee at linaro.org>

This commit adds a stub function to support the KVM_SET_GUEST_DEBUG
ioctl. Any unsupported flag will return -EINVAL. For now, only
KVM_GUESTDBG_ENABLE is supported, although it won't have any effects.

Signed-off-by: Alex Benn?e <alex.bennee at linaro.org>.
Reviewed-by: Christoffer Dall <christoffer.dall at linaro.org>
Signed-off-by: Marc Zyngier <marc.zyngier at arm.com>
---
 Documentation/virtual/kvm/api.txt |  2 +-
 arch/arm/kvm/arm.c                |  7 -------
 arch/arm/kvm/guest.c              |  6 ++++++
 arch/arm64/kvm/guest.c            | 27 +++++++++++++++++++++++++++
 4 files changed, 34 insertions(+), 8 deletions(-)

diff --git a/Documentation/virtual/kvm/api.txt b/Documentation/virtual/kvm/api.txt
index 9f746ea..19adfd3 100644
--- a/Documentation/virtual/kvm/api.txt
+++ b/Documentation/virtual/kvm/api.txt
@@ -2671,7 +2671,7 @@ handled.
 4.87 KVM_SET_GUEST_DEBUG
 
 Capability: KVM_CAP_SET_GUEST_DEBUG
-Architectures: x86, s390, ppc
+Architectures: x86, s390, ppc, arm64
 Type: vcpu ioctl
 Parameters: struct kvm_guest_debug (in)
 Returns: 0 on success; -1 on error
diff --git a/arch/arm/kvm/arm.c b/arch/arm/kvm/arm.c
index bc738d2..1b693cb 100644
--- a/arch/arm/kvm/arm.c
+++ b/arch/arm/kvm/arm.c
@@ -301,13 +301,6 @@ void kvm_arch_vcpu_put(struct kvm_vcpu *vcpu)
 	kvm_arm_set_running_vcpu(NULL);
 }
 
-int kvm_arch_vcpu_ioctl_set_guest_debug(struct kvm_vcpu *vcpu,
-					struct kvm_guest_debug *dbg)
-{
-	return -EINVAL;
-}
-
-
 int kvm_arch_vcpu_ioctl_get_mpstate(struct kvm_vcpu *vcpu,
 				    struct kvm_mp_state *mp_state)
 {
diff --git a/arch/arm/kvm/guest.c b/arch/arm/kvm/guest.c
index d503fbb..96e935b 100644
--- a/arch/arm/kvm/guest.c
+++ b/arch/arm/kvm/guest.c
@@ -290,3 +290,9 @@ int kvm_arch_vcpu_ioctl_translate(struct kvm_vcpu *vcpu,
 {
 	return -EINVAL;
 }
+
+int kvm_arch_vcpu_ioctl_set_guest_debug(struct kvm_vcpu *vcpu,
+					struct kvm_guest_debug *dbg)
+{
+	return -EINVAL;
+}
diff --git a/arch/arm64/kvm/guest.c b/arch/arm64/kvm/guest.c
index 9535bd5..0ba8677 100644
--- a/arch/arm64/kvm/guest.c
+++ b/arch/arm64/kvm/guest.c
@@ -331,3 +331,30 @@ int kvm_arch_vcpu_ioctl_translate(struct kvm_vcpu *vcpu,
 {
 	return -EINVAL;
 }
+
+#define KVM_GUESTDBG_VALID_MASK (KVM_GUESTDBG_ENABLE)
+
+/**
+ * kvm_arch_vcpu_ioctl_set_guest_debug - set up guest debugging
+ * @kvm:	pointer to the KVM struct
+ * @kvm_guest_debug: the ioctl data buffer
+ *
+ * This sets up and enables the VM for guest debugging. Userspace
+ * passes in a control flag to enable different debug types and
+ * potentially other architecture specific information in the rest of
+ * the structure.
+ */
+int kvm_arch_vcpu_ioctl_set_guest_debug(struct kvm_vcpu *vcpu,
+					struct kvm_guest_debug *dbg)
+{
+	if (dbg->control & ~KVM_GUESTDBG_VALID_MASK)
+		return -EINVAL;
+
+	if (dbg->control & KVM_GUESTDBG_ENABLE) {
+		vcpu->guest_debug = dbg->control;
+	} else {
+		/* If not enabled clear all flags */
+		vcpu->guest_debug = 0;
+	}
+	return 0;
+}
-- 
2.1.4



From marc.zyngier at arm.com  Thu Aug 20 09:28:39 2015
From: marc.zyngier at arm.com (Marc Zyngier)
Date: Thu, 20 Aug 2015 17:28:39 +0100
Subject: [PATCH 01/25] KVM: add comments for kvm_debug_exit_arch struct
In-Reply-To: <1440088143-4722-1-git-send-email-marc.zyngier@arm.com>
References: <1440088143-4722-1-git-send-email-marc.zyngier@arm.com>
Message-ID: <1440088143-4722-2-git-send-email-marc.zyngier@arm.com>

From: Alex Benn?e <alex.bennee at linaro.org>

Bring into line with the comments for the other structures and their
KVM_EXIT_* cases. Also update api.txt to reflect use in kvm_run
documentation.

Signed-off-by: Alex Benn?e <alex.bennee at linaro.org>
Reviewed-by: David Hildenbrand <dahi at linux.vnet.ibm.com>
Reviewed-by: Andrew Jones <drjones at redhat.com>
Acked-by: Christoffer Dall <christoffer.dall at linaro.org>
Signed-off-by: Marc Zyngier <marc.zyngier at arm.com>
---
 Documentation/virtual/kvm/api.txt | 4 +++-
 include/uapi/linux/kvm.h          | 3 +++
 2 files changed, 6 insertions(+), 1 deletion(-)

diff --git a/Documentation/virtual/kvm/api.txt b/Documentation/virtual/kvm/api.txt
index a7926a9..9f746ea 100644
--- a/Documentation/virtual/kvm/api.txt
+++ b/Documentation/virtual/kvm/api.txt
@@ -3111,11 +3111,13 @@ data_offset describes where the data is located (KVM_EXIT_IO_OUT) or
 where kvm expects application code to place the data for the next
 KVM_RUN invocation (KVM_EXIT_IO_IN).  Data format is a packed array.
 
+		/* KVM_EXIT_DEBUG */
 		struct {
 			struct kvm_debug_exit_arch arch;
 		} debug;
 
-Unused.
+If the exit_reason is KVM_EXIT_DEBUG, then a vcpu is processing a debug event
+for which architecture specific information is returned.
 
 		/* KVM_EXIT_MMIO */
 		struct {
diff --git a/include/uapi/linux/kvm.h b/include/uapi/linux/kvm.h
index 716ad4a..4ab3c6a 100644
--- a/include/uapi/linux/kvm.h
+++ b/include/uapi/linux/kvm.h
@@ -237,6 +237,7 @@ struct kvm_run {
 			__u32 count;
 			__u64 data_offset; /* relative to kvm_run start */
 		} io;
+		/* KVM_EXIT_DEBUG */
 		struct {
 			struct kvm_debug_exit_arch arch;
 		} debug;
@@ -285,6 +286,7 @@ struct kvm_run {
 			__u32 data;
 			__u8  is_write;
 		} dcr;
+		/* KVM_EXIT_INTERNAL_ERROR */
 		struct {
 			__u32 suberror;
 			/* Available with KVM_CAP_INTERNAL_ERROR_DATA: */
@@ -295,6 +297,7 @@ struct kvm_run {
 		struct {
 			__u64 gprs[32];
 		} osi;
+		/* KVM_EXIT_PAPR_HCALL */
 		struct {
 			__u64 nr;
 			__u64 ret;
-- 
2.1.4



From marc.zyngier at arm.com  Thu Aug 20 09:28:42 2015
From: marc.zyngier at arm.com (Marc Zyngier)
Date: Thu, 20 Aug 2015 17:28:42 +0100
Subject: [PATCH 04/25] KVM: arm: introduce kvm_arm_init/setup/clear_debug
In-Reply-To: <1440088143-4722-1-git-send-email-marc.zyngier@arm.com>
References: <1440088143-4722-1-git-send-email-marc.zyngier@arm.com>
Message-ID: <1440088143-4722-5-git-send-email-marc.zyngier@arm.com>

From: Alex Benn?e <alex.bennee at linaro.org>

This is a precursor for later patches which will need to do more to
setup debug state before entering the hyp.S switch code. The existing
functionality for setting mdcr_el2 has been moved out of hyp.S and now
uses the value kept in vcpu->arch.mdcr_el2.

As the assembler used to previously mask and preserve MDCR_EL2.HPMN I've
had to add a mechanism to save the value of mdcr_el2 as a per-cpu
variable during the initialisation code. The kernel never sets this
number so we are assuming the bootcode has set up the correct value
here.

This also moves the conditional setting of the TDA bit from the hyp code
into the C code which is currently used for the lazy debug register
context switch code.

Signed-off-by: Alex Benn?e <alex.bennee at linaro.org>
Reviewed-by: Christoffer Dall <christoffer.dall at linaro.org>
Signed-off-by: Marc Zyngier <marc.zyngier at arm.com>
---
 arch/arm/include/asm/kvm_host.h   |  4 ++
 arch/arm/kvm/arm.c                |  6 +++
 arch/arm64/include/asm/kvm_asm.h  |  2 +
 arch/arm64/include/asm/kvm_host.h |  5 +++
 arch/arm64/kernel/asm-offsets.c   |  1 +
 arch/arm64/kvm/Makefile           |  2 +-
 arch/arm64/kvm/debug.c            | 81 +++++++++++++++++++++++++++++++++++++++
 arch/arm64/kvm/hyp.S              | 19 ++++-----
 8 files changed, 108 insertions(+), 12 deletions(-)
 create mode 100644 arch/arm64/kvm/debug.c

diff --git a/arch/arm/include/asm/kvm_host.h b/arch/arm/include/asm/kvm_host.h
index e896d2c..2b0bc8c 100644
--- a/arch/arm/include/asm/kvm_host.h
+++ b/arch/arm/include/asm/kvm_host.h
@@ -231,4 +231,8 @@ static inline void kvm_arch_sync_events(struct kvm *kvm) {}
 static inline void kvm_arch_vcpu_uninit(struct kvm_vcpu *vcpu) {}
 static inline void kvm_arch_sched_in(struct kvm_vcpu *vcpu, int cpu) {}
 
+static inline void kvm_arm_init_debug(void) {}
+static inline void kvm_arm_setup_debug(struct kvm_vcpu *vcpu) {}
+static inline void kvm_arm_clear_debug(struct kvm_vcpu *vcpu) {}
+
 #endif /* __ARM_KVM_HOST_H__ */
diff --git a/arch/arm/kvm/arm.c b/arch/arm/kvm/arm.c
index 1b693cb..77151b1 100644
--- a/arch/arm/kvm/arm.c
+++ b/arch/arm/kvm/arm.c
@@ -543,6 +543,8 @@ int kvm_arch_vcpu_ioctl_run(struct kvm_vcpu *vcpu, struct kvm_run *run)
 			continue;
 		}
 
+		kvm_arm_setup_debug(vcpu);
+
 		/**************************************************************
 		 * Enter the guest
 		 */
@@ -557,6 +559,8 @@ int kvm_arch_vcpu_ioctl_run(struct kvm_vcpu *vcpu, struct kvm_run *run)
 		 * Back from guest
 		 *************************************************************/
 
+		kvm_arm_clear_debug(vcpu);
+
 		/*
 		 * We may have taken a host interrupt in HYP mode (ie
 		 * while executing the guest). This interrupt is still
@@ -914,6 +918,8 @@ static void cpu_init_hyp_mode(void *dummy)
 	vector_ptr = (unsigned long)__kvm_hyp_vector;
 
 	__cpu_init_hyp_mode(boot_pgd_ptr, pgd_ptr, hyp_stack_ptr, vector_ptr);
+
+	kvm_arm_init_debug();
 }
 
 static int hyp_init_cpu_notify(struct notifier_block *self,
diff --git a/arch/arm64/include/asm/kvm_asm.h b/arch/arm64/include/asm/kvm_asm.h
index 3c5fe68..f5e40da 100644
--- a/arch/arm64/include/asm/kvm_asm.h
+++ b/arch/arm64/include/asm/kvm_asm.h
@@ -132,6 +132,8 @@ extern int __kvm_vcpu_run(struct kvm_vcpu *vcpu);
 
 extern u64 __vgic_v3_get_ich_vtr_el2(void);
 
+extern u32 __kvm_get_mdcr_el2(void);
+
 #endif
 
 #endif /* __ARM_KVM_ASM_H__ */
diff --git a/arch/arm64/include/asm/kvm_host.h b/arch/arm64/include/asm/kvm_host.h
index 2709db2..c90c6a4 100644
--- a/arch/arm64/include/asm/kvm_host.h
+++ b/arch/arm64/include/asm/kvm_host.h
@@ -103,6 +103,7 @@ struct kvm_vcpu_arch {
 
 	/* HYP configuration */
 	u64 hcr_el2;
+	u32 mdcr_el2;
 
 	/* Exception Information */
 	struct kvm_vcpu_fault_info fault;
@@ -227,4 +228,8 @@ static inline void kvm_arch_sync_events(struct kvm *kvm) {}
 static inline void kvm_arch_vcpu_uninit(struct kvm_vcpu *vcpu) {}
 static inline void kvm_arch_sched_in(struct kvm_vcpu *vcpu, int cpu) {}
 
+void kvm_arm_init_debug(void);
+void kvm_arm_setup_debug(struct kvm_vcpu *vcpu);
+void kvm_arm_clear_debug(struct kvm_vcpu *vcpu);
+
 #endif /* __ARM64_KVM_HOST_H__ */
diff --git a/arch/arm64/kernel/asm-offsets.c b/arch/arm64/kernel/asm-offsets.c
index c99701a..5c900d4 100644
--- a/arch/arm64/kernel/asm-offsets.c
+++ b/arch/arm64/kernel/asm-offsets.c
@@ -117,6 +117,7 @@ int main(void)
   DEFINE(VCPU_HPFAR_EL2,	offsetof(struct kvm_vcpu, arch.fault.hpfar_el2));
   DEFINE(VCPU_DEBUG_FLAGS,	offsetof(struct kvm_vcpu, arch.debug_flags));
   DEFINE(VCPU_HCR_EL2,		offsetof(struct kvm_vcpu, arch.hcr_el2));
+  DEFINE(VCPU_MDCR_EL2,	offsetof(struct kvm_vcpu, arch.mdcr_el2));
   DEFINE(VCPU_IRQ_LINES,	offsetof(struct kvm_vcpu, arch.irq_lines));
   DEFINE(VCPU_HOST_CONTEXT,	offsetof(struct kvm_vcpu, arch.host_cpu_context));
   DEFINE(VCPU_TIMER_CNTV_CTL,	offsetof(struct kvm_vcpu, arch.timer_cpu.cntv_ctl));
diff --git a/arch/arm64/kvm/Makefile b/arch/arm64/kvm/Makefile
index f90f4aa..1949fe5 100644
--- a/arch/arm64/kvm/Makefile
+++ b/arch/arm64/kvm/Makefile
@@ -17,7 +17,7 @@ kvm-$(CONFIG_KVM_ARM_HOST) += $(ARM)/psci.o $(ARM)/perf.o
 
 kvm-$(CONFIG_KVM_ARM_HOST) += emulate.o inject_fault.o regmap.o
 kvm-$(CONFIG_KVM_ARM_HOST) += hyp.o hyp-init.o handle_exit.o
-kvm-$(CONFIG_KVM_ARM_HOST) += guest.o reset.o sys_regs.o sys_regs_generic_v8.o
+kvm-$(CONFIG_KVM_ARM_HOST) += guest.o debug.o reset.o sys_regs.o sys_regs_generic_v8.o
 
 kvm-$(CONFIG_KVM_ARM_HOST) += $(KVM)/arm/vgic.o
 kvm-$(CONFIG_KVM_ARM_HOST) += $(KVM)/arm/vgic-v2.o
diff --git a/arch/arm64/kvm/debug.c b/arch/arm64/kvm/debug.c
new file mode 100644
index 0000000..faf0e1f
--- /dev/null
+++ b/arch/arm64/kvm/debug.c
@@ -0,0 +1,81 @@
+/*
+ * Debug and Guest Debug support
+ *
+ * Copyright (C) 2015 - Linaro Ltd
+ * Author: Alex Benn?e <alex.bennee at linaro.org>
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License version 2 as
+ * published by the Free Software Foundation.
+ *
+ * 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.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program.  If not, see <http://www.gnu.org/licenses/>.
+ */
+
+#include <linux/kvm_host.h>
+
+#include <asm/kvm_arm.h>
+
+static DEFINE_PER_CPU(u32, mdcr_el2);
+
+/**
+ * kvm_arm_init_debug - grab what we need for debug
+ *
+ * Currently the sole task of this function is to retrieve the initial
+ * value of mdcr_el2 so we can preserve MDCR_EL2.HPMN which has
+ * presumably been set-up by some knowledgeable bootcode.
+ *
+ * It is called once per-cpu during CPU hyp initialisation.
+ */
+
+void kvm_arm_init_debug(void)
+{
+	__this_cpu_write(mdcr_el2, kvm_call_hyp(__kvm_get_mdcr_el2));
+}
+
+
+/**
+ * kvm_arm_setup_debug - set up debug related stuff
+ *
+ * @vcpu:	the vcpu pointer
+ *
+ * This is called before each entry into the hypervisor to setup any
+ * debug related registers. Currently this just ensures we will trap
+ * access to:
+ *  - Performance monitors (MDCR_EL2_TPM/MDCR_EL2_TPMCR)
+ *  - Debug ROM Address (MDCR_EL2_TDRA)
+ *  - OS related registers (MDCR_EL2_TDOSA)
+ *
+ * Additionally, KVM only traps guest accesses to the debug registers if
+ * the guest is not actively using them (see the KVM_ARM64_DEBUG_DIRTY
+ * flag on vcpu->arch.debug_flags).  Since the guest must not interfere
+ * with the hardware state when debugging the guest, we must ensure that
+ * trapping is enabled whenever we are debugging the guest using the
+ * debug registers.
+ */
+
+void kvm_arm_setup_debug(struct kvm_vcpu *vcpu)
+{
+	bool trap_debug = !(vcpu->arch.debug_flags & KVM_ARM64_DEBUG_DIRTY);
+
+	vcpu->arch.mdcr_el2 = __this_cpu_read(mdcr_el2) & MDCR_EL2_HPMN_MASK;
+	vcpu->arch.mdcr_el2 |= (MDCR_EL2_TPM |
+				MDCR_EL2_TPMCR |
+				MDCR_EL2_TDRA |
+				MDCR_EL2_TDOSA);
+
+	/* Trap on access to debug registers? */
+	if (trap_debug)
+		vcpu->arch.mdcr_el2 |= MDCR_EL2_TDA;
+
+}
+
+void kvm_arm_clear_debug(struct kvm_vcpu *vcpu)
+{
+	/* Nothing to do yet */
+}
diff --git a/arch/arm64/kvm/hyp.S b/arch/arm64/kvm/hyp.S
index 17a8fb1..b3176e6 100644
--- a/arch/arm64/kvm/hyp.S
+++ b/arch/arm64/kvm/hyp.S
@@ -770,17 +770,8 @@
 	mov	x2, #(1 << 15)	// Trap CP15 Cr=15
 	msr	hstr_el2, x2
 
-	mrs	x2, mdcr_el2
-	and	x2, x2, #MDCR_EL2_HPMN_MASK
-	orr	x2, x2, #(MDCR_EL2_TPM | MDCR_EL2_TPMCR)
-	orr	x2, x2, #(MDCR_EL2_TDRA | MDCR_EL2_TDOSA)
-
-	// Check for KVM_ARM64_DEBUG_DIRTY, and set debug to trap
-	// if not dirty.
-	ldr	x3, [x0, #VCPU_DEBUG_FLAGS]
-	tbnz	x3, #KVM_ARM64_DEBUG_DIRTY_SHIFT, 1f
-	orr	x2, x2,  #MDCR_EL2_TDA
-1:
+	// Monitor Debug Config - see kvm_arm_setup_debug()
+	ldr	x2, [x0, #VCPU_MDCR_EL2]
 	msr	mdcr_el2, x2
 .endm
 
@@ -1285,4 +1276,10 @@ ENTRY(__kvm_hyp_vector)
 	ventry	el1_error_invalid		// Error 32-bit EL1
 ENDPROC(__kvm_hyp_vector)
 
+
+ENTRY(__kvm_get_mdcr_el2)
+	mrs	x0, mdcr_el2
+	ret
+ENDPROC(__kvm_get_mdcr_el2)
+
 	.popsection
-- 
2.1.4



From marc.zyngier at arm.com  Thu Aug 20 09:28:52 2015
From: marc.zyngier at arm.com (Marc Zyngier)
Date: Thu, 20 Aug 2015 17:28:52 +0100
Subject: [PATCH 14/25] arm/arm64: KVM: Fix ordering of timer/GIC on guest entry
In-Reply-To: <1440088143-4722-1-git-send-email-marc.zyngier@arm.com>
References: <1440088143-4722-1-git-send-email-marc.zyngier@arm.com>
Message-ID: <1440088143-4722-15-git-send-email-marc.zyngier@arm.com>

As we now inject the timer interrupt when we're about to enter
the guest, it makes a lot more sense to make sure this happens
before the vgic code queues the pending interrupts.

Otherwise, we get the interrupt on the following exit, which is
not great for latency (and leads to all kind of bizarre issues
when using with active interrupts at the HW level).

Signed-off-by: Marc Zyngier <marc.zyngier at arm.com>
Reviewed-by: Alex Benn?e <alex.bennee at linaro.org>
Reviewed-by: Christoffer Dall <christoffer.dall at linaro.org>
---
 arch/arm/kvm/arm.c | 7 +++----
 1 file changed, 3 insertions(+), 4 deletions(-)

diff --git a/arch/arm/kvm/arm.c b/arch/arm/kvm/arm.c
index 9ce5cf0..1141d21 100644
--- a/arch/arm/kvm/arm.c
+++ b/arch/arm/kvm/arm.c
@@ -523,8 +523,8 @@ int kvm_arch_vcpu_ioctl_run(struct kvm_vcpu *vcpu, struct kvm_run *run)
 		if (vcpu->arch.pause)
 			vcpu_pause(vcpu);
 
-		kvm_vgic_flush_hwstate(vcpu);
 		kvm_timer_flush_hwstate(vcpu);
+		kvm_vgic_flush_hwstate(vcpu);
 
 		preempt_disable();
 		local_irq_disable();
@@ -540,8 +540,8 @@ int kvm_arch_vcpu_ioctl_run(struct kvm_vcpu *vcpu, struct kvm_run *run)
 		if (ret <= 0 || need_new_vmid_gen(vcpu->kvm)) {
 			local_irq_enable();
 			preempt_enable();
-			kvm_timer_sync_hwstate(vcpu);
 			kvm_vgic_sync_hwstate(vcpu);
+			kvm_timer_sync_hwstate(vcpu);
 			continue;
 		}
 
@@ -587,9 +587,8 @@ int kvm_arch_vcpu_ioctl_run(struct kvm_vcpu *vcpu, struct kvm_run *run)
 		trace_kvm_exit(kvm_vcpu_trap_get_class(vcpu), *vcpu_pc(vcpu));
 		preempt_enable();
 
-
-		kvm_timer_sync_hwstate(vcpu);
 		kvm_vgic_sync_hwstate(vcpu);
+		kvm_timer_sync_hwstate(vcpu);
 
 		ret = handle_exit(vcpu, run, ret);
 	}
-- 
2.1.4



From marc.zyngier at arm.com  Thu Aug 20 09:28:44 2015
From: marc.zyngier at arm.com (Marc Zyngier)
Date: Thu, 20 Aug 2015 17:28:44 +0100
Subject: [PATCH 06/25] KVM: arm64: guest debug, add support for single-step
In-Reply-To: <1440088143-4722-1-git-send-email-marc.zyngier@arm.com>
References: <1440088143-4722-1-git-send-email-marc.zyngier@arm.com>
Message-ID: <1440088143-4722-7-git-send-email-marc.zyngier@arm.com>

From: Alex Benn?e <alex.bennee at linaro.org>

This adds support for single-stepping the guest. To do this we need to
manipulate the guests PSTATE.SS and MDSCR_EL1.SS bits to trigger
stepping. We take care to preserve MDSCR_EL1 and trap access to it to
ensure we don't affect the apparent state of the guest.

As we have to enable trapping of all software debug exceptions we
suppress the ability of the guest to single-step itself. If we didn't we
would have to deal with the exception arriving while the guest was in
kernelspace when the guest is expecting to single-step userspace. This
is something we don't want to unwind in the kernel. Once the host is no
longer debugging the guest its ability to single-step userspace is
restored.

Signed-off-by: Alex Benn?e <alex.bennee at linaro.org>
Reviewed-by: Christoffer Dall <christoffer.dall at linaro.org>
Signed-off-by: Marc Zyngier <marc.zyngier at arm.com>
---
 arch/arm64/include/asm/kvm_host.h | 11 +++++++
 arch/arm64/kvm/debug.c            | 68 ++++++++++++++++++++++++++++++++++++---
 arch/arm64/kvm/guest.c            |  4 ++-
 arch/arm64/kvm/handle_exit.c      |  2 ++
 4 files changed, 80 insertions(+), 5 deletions(-)

diff --git a/arch/arm64/include/asm/kvm_host.h b/arch/arm64/include/asm/kvm_host.h
index c90c6a4..cfb6754 100644
--- a/arch/arm64/include/asm/kvm_host.h
+++ b/arch/arm64/include/asm/kvm_host.h
@@ -123,6 +123,17 @@ struct kvm_vcpu_arch {
 	 * here.
 	 */
 
+	/*
+	 * Guest registers we preserve during guest debugging.
+	 *
+	 * These shadow registers are updated by the kvm_handle_sys_reg
+	 * trap handler if the guest accesses or updates them while we
+	 * are using guest debug.
+	 */
+	struct {
+		u32	mdscr_el1;
+	} guest_debug_preserved;
+
 	/* Don't run the guest */
 	bool pause;
 
diff --git a/arch/arm64/kvm/debug.c b/arch/arm64/kvm/debug.c
index 8d1bfa4..d439eb8 100644
--- a/arch/arm64/kvm/debug.c
+++ b/arch/arm64/kvm/debug.c
@@ -19,11 +19,39 @@
 
 #include <linux/kvm_host.h>
 
+#include <asm/debug-monitors.h>
+#include <asm/kvm_asm.h>
 #include <asm/kvm_arm.h>
+#include <asm/kvm_emulate.h>
+
+/* These are the bits of MDSCR_EL1 we may manipulate */
+#define MDSCR_EL1_DEBUG_MASK	(DBG_MDSCR_SS | \
+				DBG_MDSCR_KDE | \
+				DBG_MDSCR_MDE)
 
 static DEFINE_PER_CPU(u32, mdcr_el2);
 
 /**
+ * save/restore_guest_debug_regs
+ *
+ * For some debug operations we need to tweak some guest registers. As
+ * a result we need to save the state of those registers before we
+ * make those modifications.
+ *
+ * Guest access to MDSCR_EL1 is trapped by the hypervisor and handled
+ * after we have restored the preserved value to the main context.
+ */
+static void save_guest_debug_regs(struct kvm_vcpu *vcpu)
+{
+	vcpu->arch.guest_debug_preserved.mdscr_el1 = vcpu_sys_reg(vcpu, MDSCR_EL1);
+}
+
+static void restore_guest_debug_regs(struct kvm_vcpu *vcpu)
+{
+	vcpu_sys_reg(vcpu, MDSCR_EL1) = vcpu->arch.guest_debug_preserved.mdscr_el1;
+}
+
+/**
  * kvm_arm_init_debug - grab what we need for debug
  *
  * Currently the sole task of this function is to retrieve the initial
@@ -38,7 +66,6 @@ void kvm_arm_init_debug(void)
 	__this_cpu_write(mdcr_el2, kvm_call_hyp(__kvm_get_mdcr_el2));
 }
 
-
 /**
  * kvm_arm_setup_debug - set up debug related stuff
  *
@@ -73,12 +100,45 @@ void kvm_arm_setup_debug(struct kvm_vcpu *vcpu)
 	if (trap_debug)
 		vcpu->arch.mdcr_el2 |= MDCR_EL2_TDA;
 
-	/* Trap breakpoints? */
-	if (vcpu->guest_debug & KVM_GUESTDBG_USE_SW_BP)
+	/* Is Guest debugging in effect? */
+	if (vcpu->guest_debug) {
+		/* Route all software debug exceptions to EL2 */
 		vcpu->arch.mdcr_el2 |= MDCR_EL2_TDE;
+
+		/* Save guest debug state */
+		save_guest_debug_regs(vcpu);
+
+		/*
+		 * Single Step (ARM ARM D2.12.3 The software step state
+		 * machine)
+		 *
+		 * If we are doing Single Step we need to manipulate
+		 * the guest's MDSCR_EL1.SS and PSTATE.SS. Once the
+		 * step has occurred the hypervisor will trap the
+		 * debug exception and we return to userspace.
+		 *
+		 * If the guest attempts to single step its userspace
+		 * we would have to deal with a trapped exception
+		 * while in the guest kernel. Because this would be
+		 * hard to unwind we suppress the guest's ability to
+		 * do so by masking MDSCR_EL.SS.
+		 *
+		 * This confuses guest debuggers which use
+		 * single-step behind the scenes but everything
+		 * returns to normal once the host is no longer
+		 * debugging the system.
+		 */
+		if (vcpu->guest_debug & KVM_GUESTDBG_SINGLESTEP) {
+			*vcpu_cpsr(vcpu) |=  DBG_SPSR_SS;
+			vcpu_sys_reg(vcpu, MDSCR_EL1) |= DBG_MDSCR_SS;
+		} else {
+			vcpu_sys_reg(vcpu, MDSCR_EL1) &= ~DBG_MDSCR_SS;
+		}
+	}
 }
 
 void kvm_arm_clear_debug(struct kvm_vcpu *vcpu)
 {
-	/* Nothing to do yet */
+	if (vcpu->guest_debug)
+		restore_guest_debug_regs(vcpu);
 }
diff --git a/arch/arm64/kvm/guest.c b/arch/arm64/kvm/guest.c
index 22d22c5..48de4f4 100644
--- a/arch/arm64/kvm/guest.c
+++ b/arch/arm64/kvm/guest.c
@@ -332,7 +332,9 @@ int kvm_arch_vcpu_ioctl_translate(struct kvm_vcpu *vcpu,
 	return -EINVAL;
 }
 
-#define KVM_GUESTDBG_VALID_MASK (KVM_GUESTDBG_ENABLE | KVM_GUESTDBG_USE_SW_BP)
+#define KVM_GUESTDBG_VALID_MASK (KVM_GUESTDBG_ENABLE |    \
+			    KVM_GUESTDBG_USE_SW_BP | \
+			    KVM_GUESTDBG_SINGLESTEP)
 
 /**
  * kvm_arch_vcpu_ioctl_set_guest_debug - set up guest debugging
diff --git a/arch/arm64/kvm/handle_exit.c b/arch/arm64/kvm/handle_exit.c
index 27f38a9..e9de13e 100644
--- a/arch/arm64/kvm/handle_exit.c
+++ b/arch/arm64/kvm/handle_exit.c
@@ -103,6 +103,7 @@ static int kvm_handle_guest_debug(struct kvm_vcpu *vcpu, struct kvm_run *run)
 	run->debug.arch.hsr = hsr;
 
 	switch (hsr >> ESR_ELx_EC_SHIFT) {
+	case ESR_ELx_EC_SOFTSTP_LOW:
 	case ESR_ELx_EC_BKPT32:
 	case ESR_ELx_EC_BRK64:
 		break;
@@ -130,6 +131,7 @@ static exit_handle_fn arm_exit_handlers[] = {
 	[ESR_ELx_EC_SYS64]	= kvm_handle_sys_reg,
 	[ESR_ELx_EC_IABT_LOW]	= kvm_handle_guest_abort,
 	[ESR_ELx_EC_DABT_LOW]	= kvm_handle_guest_abort,
+	[ESR_ELx_EC_SOFTSTP_LOW]= kvm_handle_guest_debug,
 	[ESR_ELx_EC_BKPT32]	= kvm_handle_guest_debug,
 	[ESR_ELx_EC_BRK64]	= kvm_handle_guest_debug,
 };
-- 
2.1.4



From marc.zyngier at arm.com  Thu Aug 20 09:28:47 2015
From: marc.zyngier at arm.com (Marc Zyngier)
Date: Thu, 20 Aug 2015 17:28:47 +0100
Subject: [PATCH 09/25] KVM: arm64: guest debug, HW assisted debug support
In-Reply-To: <1440088143-4722-1-git-send-email-marc.zyngier@arm.com>
References: <1440088143-4722-1-git-send-email-marc.zyngier@arm.com>
Message-ID: <1440088143-4722-10-git-send-email-marc.zyngier@arm.com>

From: Alex Benn?e <alex.bennee at linaro.org>

This adds support for userspace to control the HW debug registers for
guest debug. In the debug ioctl we copy an IMPDEF registers into a new
register set called host_debug_state.

We use the recently introduced vcpu parameter debug_ptr to select which
register set is copied into the real registers when world switch occurs.

I've made some helper functions from hw_breakpoint.c more widely
available for re-use.

As with single step we need to tweak the guest registers to enable the
exceptions so we need to save and restore those bits.

Two new capabilities have been added to the KVM_EXTENSION ioctl to allow
userspace to query the number of hardware break and watch points
available on the host hardware.

Signed-off-by: Alex Benn?e <alex.bennee at linaro.org>
Reviewed-by: Christoffer Dall <christoffer.dall at linaro.org>
Signed-off-by: Marc Zyngier <marc.zyngier at arm.com>
---
 include/uapi/linux/kvm.h | 2 ++
 1 file changed, 2 insertions(+)

diff --git a/include/uapi/linux/kvm.h b/include/uapi/linux/kvm.h
index 4ab3c6a..a1e08e7 100644
--- a/include/uapi/linux/kvm.h
+++ b/include/uapi/linux/kvm.h
@@ -820,6 +820,8 @@ struct kvm_ppc_smmu_info {
 #define KVM_CAP_DISABLE_QUIRKS 116
 #define KVM_CAP_X86_SMM 117
 #define KVM_CAP_MULTI_ADDRESS_SPACE 118
+#define KVM_CAP_GUEST_DEBUG_HW_BPS 119
+#define KVM_CAP_GUEST_DEBUG_HW_WPS 120
 
 #ifdef KVM_CAP_IRQ_ROUTING
 
-- 
2.1.4



From marc.zyngier at arm.com  Thu Aug 20 09:28:43 2015
From: marc.zyngier at arm.com (Marc Zyngier)
Date: Thu, 20 Aug 2015 17:28:43 +0100
Subject: [PATCH 05/25] KVM: arm64: guest debug, add SW break point support
In-Reply-To: <1440088143-4722-1-git-send-email-marc.zyngier@arm.com>
References: <1440088143-4722-1-git-send-email-marc.zyngier@arm.com>
Message-ID: <1440088143-4722-6-git-send-email-marc.zyngier@arm.com>

From: Alex Benn?e <alex.bennee at linaro.org>

This adds support for SW breakpoints inserted by userspace.

We do this by trapping all guest software debug exceptions to the
hypervisor (MDCR_EL2.TDE). The exit handler sets an exit reason of
KVM_EXIT_DEBUG with the kvm_debug_exit_arch structure holding the
exception syndrome information.

It will be up to userspace to extract the PC (via GET_ONE_REG) and
determine if the debug event was for a breakpoint it inserted. If not
userspace will need to re-inject the correct exception restart the
hypervisor to deliver the debug exception to the guest.

Any other guest software debug exception (e.g. single step or HW
assisted breakpoints) will cause an error and the VM to be killed. This
is addressed by later patches which add support for the other debug
types.

Signed-off-by: Alex Benn?e <alex.bennee at linaro.org>
Reviewed-by: Christoffer Dall <christoffer.dall at linaro.org>
Signed-off-by: Marc Zyngier <marc.zyngier at arm.com>
---
 Documentation/virtual/kvm/api.txt |  2 +-
 arch/arm64/kvm/debug.c            |  3 +++
 arch/arm64/kvm/guest.c            |  2 +-
 arch/arm64/kvm/handle_exit.c      | 36 ++++++++++++++++++++++++++++++++++++
 4 files changed, 41 insertions(+), 2 deletions(-)

diff --git a/Documentation/virtual/kvm/api.txt b/Documentation/virtual/kvm/api.txt
index 19adfd3..0f498da 100644
--- a/Documentation/virtual/kvm/api.txt
+++ b/Documentation/virtual/kvm/api.txt
@@ -2693,7 +2693,7 @@ when running. Common control bits are:
 The top 16 bits of the control field are architecture specific control
 flags which can include the following:
 
-  - KVM_GUESTDBG_USE_SW_BP:     using software breakpoints [x86]
+  - KVM_GUESTDBG_USE_SW_BP:     using software breakpoints [x86, arm64]
   - KVM_GUESTDBG_USE_HW_BP:     using hardware breakpoints [x86, s390]
   - KVM_GUESTDBG_INJECT_DB:     inject DB type exception [x86]
   - KVM_GUESTDBG_INJECT_BP:     inject BP type exception [x86]
diff --git a/arch/arm64/kvm/debug.c b/arch/arm64/kvm/debug.c
index faf0e1f..8d1bfa4 100644
--- a/arch/arm64/kvm/debug.c
+++ b/arch/arm64/kvm/debug.c
@@ -73,6 +73,9 @@ void kvm_arm_setup_debug(struct kvm_vcpu *vcpu)
 	if (trap_debug)
 		vcpu->arch.mdcr_el2 |= MDCR_EL2_TDA;
 
+	/* Trap breakpoints? */
+	if (vcpu->guest_debug & KVM_GUESTDBG_USE_SW_BP)
+		vcpu->arch.mdcr_el2 |= MDCR_EL2_TDE;
 }
 
 void kvm_arm_clear_debug(struct kvm_vcpu *vcpu)
diff --git a/arch/arm64/kvm/guest.c b/arch/arm64/kvm/guest.c
index 0ba8677..22d22c5 100644
--- a/arch/arm64/kvm/guest.c
+++ b/arch/arm64/kvm/guest.c
@@ -332,7 +332,7 @@ int kvm_arch_vcpu_ioctl_translate(struct kvm_vcpu *vcpu,
 	return -EINVAL;
 }
 
-#define KVM_GUESTDBG_VALID_MASK (KVM_GUESTDBG_ENABLE)
+#define KVM_GUESTDBG_VALID_MASK (KVM_GUESTDBG_ENABLE | KVM_GUESTDBG_USE_SW_BP)
 
 /**
  * kvm_arch_vcpu_ioctl_set_guest_debug - set up guest debugging
diff --git a/arch/arm64/kvm/handle_exit.c b/arch/arm64/kvm/handle_exit.c
index 524fa25..27f38a9 100644
--- a/arch/arm64/kvm/handle_exit.c
+++ b/arch/arm64/kvm/handle_exit.c
@@ -82,6 +82,40 @@ static int kvm_handle_wfx(struct kvm_vcpu *vcpu, struct kvm_run *run)
 	return 1;
 }
 
+/**
+ * kvm_handle_guest_debug - handle a debug exception instruction
+ *
+ * @vcpu:	the vcpu pointer
+ * @run:	access to the kvm_run structure for results
+ *
+ * We route all debug exceptions through the same handler. If both the
+ * guest and host are using the same debug facilities it will be up to
+ * userspace to re-inject the correct exception for guest delivery.
+ *
+ * @return: 0 (while setting run->exit_reason), -1 for error
+ */
+static int kvm_handle_guest_debug(struct kvm_vcpu *vcpu, struct kvm_run *run)
+{
+	u32 hsr = kvm_vcpu_get_hsr(vcpu);
+	int ret = 0;
+
+	run->exit_reason = KVM_EXIT_DEBUG;
+	run->debug.arch.hsr = hsr;
+
+	switch (hsr >> ESR_ELx_EC_SHIFT) {
+	case ESR_ELx_EC_BKPT32:
+	case ESR_ELx_EC_BRK64:
+		break;
+	default:
+		kvm_err("%s: un-handled case hsr: %#08x\n",
+			__func__, (unsigned int) hsr);
+		ret = -1;
+		break;
+	}
+
+	return ret;
+}
+
 static exit_handle_fn arm_exit_handlers[] = {
 	[ESR_ELx_EC_WFx]	= kvm_handle_wfx,
 	[ESR_ELx_EC_CP15_32]	= kvm_handle_cp15_32,
@@ -96,6 +130,8 @@ static exit_handle_fn arm_exit_handlers[] = {
 	[ESR_ELx_EC_SYS64]	= kvm_handle_sys_reg,
 	[ESR_ELx_EC_IABT_LOW]	= kvm_handle_guest_abort,
 	[ESR_ELx_EC_DABT_LOW]	= kvm_handle_guest_abort,
+	[ESR_ELx_EC_BKPT32]	= kvm_handle_guest_debug,
+	[ESR_ELx_EC_BRK64]	= kvm_handle_guest_debug,
 };
 
 static exit_handle_fn kvm_get_exit_handler(struct kvm_vcpu *vcpu)
-- 
2.1.4



From marc.zyngier at arm.com  Thu Aug 20 09:28:49 2015
From: marc.zyngier at arm.com (Marc Zyngier)
Date: Thu, 20 Aug 2015 17:28:49 +0100
Subject: [PATCH 11/25] KVM: arm64: add trace points for guest_debug debug
In-Reply-To: <1440088143-4722-1-git-send-email-marc.zyngier@arm.com>
References: <1440088143-4722-1-git-send-email-marc.zyngier@arm.com>
Message-ID: <1440088143-4722-12-git-send-email-marc.zyngier@arm.com>

From: Alex Benn?e <alex.bennee at linaro.org>

This includes trace points for:
  kvm_arch_setup_guest_debug
  kvm_arch_clear_guest_debug

I've also added some generic register setting trace events and also a
trace point to dump the array of hardware registers.

Acked-by: Christoffer Dall <christoffer.dall at linaro.org>
Signed-off-by: Alex Benn?e <alex.bennee at linaro.org>
Signed-off-by: Marc Zyngier <marc.zyngier at arm.com>
---
 arch/arm64/kvm/debug.c    |  36 +++++++++++++-
 arch/arm64/kvm/guest.c    |   4 ++
 arch/arm64/kvm/sys_regs.c |  17 +++++++
 arch/arm64/kvm/trace.h    | 123 ++++++++++++++++++++++++++++++++++++++++++++++
 4 files changed, 179 insertions(+), 1 deletion(-)

diff --git a/arch/arm64/kvm/debug.c b/arch/arm64/kvm/debug.c
index 4a99e54..47e5f0f 100644
--- a/arch/arm64/kvm/debug.c
+++ b/arch/arm64/kvm/debug.c
@@ -18,12 +18,15 @@
  */
 
 #include <linux/kvm_host.h>
+#include <linux/hw_breakpoint.h>
 
 #include <asm/debug-monitors.h>
 #include <asm/kvm_asm.h>
 #include <asm/kvm_arm.h>
 #include <asm/kvm_emulate.h>
 
+#include "trace.h"
+
 /* These are the bits of MDSCR_EL1 we may manipulate */
 #define MDSCR_EL1_DEBUG_MASK	(DBG_MDSCR_SS | \
 				DBG_MDSCR_KDE | \
@@ -44,11 +47,17 @@ static DEFINE_PER_CPU(u32, mdcr_el2);
 static void save_guest_debug_regs(struct kvm_vcpu *vcpu)
 {
 	vcpu->arch.guest_debug_preserved.mdscr_el1 = vcpu_sys_reg(vcpu, MDSCR_EL1);
+
+	trace_kvm_arm_set_dreg32("Saved MDSCR_EL1",
+				vcpu->arch.guest_debug_preserved.mdscr_el1);
 }
 
 static void restore_guest_debug_regs(struct kvm_vcpu *vcpu)
 {
 	vcpu_sys_reg(vcpu, MDSCR_EL1) = vcpu->arch.guest_debug_preserved.mdscr_el1;
+
+	trace_kvm_arm_set_dreg32("Restored MDSCR_EL1",
+				vcpu_sys_reg(vcpu, MDSCR_EL1));
 }
 
 /**
@@ -99,6 +108,8 @@ void kvm_arm_setup_debug(struct kvm_vcpu *vcpu)
 {
 	bool trap_debug = !(vcpu->arch.debug_flags & KVM_ARM64_DEBUG_DIRTY);
 
+	trace_kvm_arm_setup_debug(vcpu, vcpu->guest_debug);
+
 	vcpu->arch.mdcr_el2 = __this_cpu_read(mdcr_el2) & MDCR_EL2_HPMN_MASK;
 	vcpu->arch.mdcr_el2 |= (MDCR_EL2_TPM |
 				MDCR_EL2_TPMCR |
@@ -140,6 +151,8 @@ void kvm_arm_setup_debug(struct kvm_vcpu *vcpu)
 			vcpu_sys_reg(vcpu, MDSCR_EL1) &= ~DBG_MDSCR_SS;
 		}
 
+		trace_kvm_arm_set_dreg32("SPSR_EL2", *vcpu_cpsr(vcpu));
+
 		/*
 		 * HW Breakpoints and watchpoints
 		 *
@@ -156,6 +169,14 @@ void kvm_arm_setup_debug(struct kvm_vcpu *vcpu)
 			vcpu->arch.debug_ptr = &vcpu->arch.external_debug_state;
 			vcpu->arch.debug_flags |= KVM_ARM64_DEBUG_DIRTY;
 			trap_debug = true;
+
+			trace_kvm_arm_set_regset("BKPTS", get_num_brps(),
+						&vcpu->arch.debug_ptr->dbg_bcr[0],
+						&vcpu->arch.debug_ptr->dbg_bvr[0]);
+
+			trace_kvm_arm_set_regset("WAPTS", get_num_wrps(),
+						&vcpu->arch.debug_ptr->dbg_wcr[0],
+						&vcpu->arch.debug_ptr->dbg_wvr[0]);
 		}
 	}
 
@@ -165,10 +186,15 @@ void kvm_arm_setup_debug(struct kvm_vcpu *vcpu)
 	/* Trap debug register access */
 	if (trap_debug)
 		vcpu->arch.mdcr_el2 |= MDCR_EL2_TDA;
+
+	trace_kvm_arm_set_dreg32("MDCR_EL2", vcpu->arch.mdcr_el2);
+	trace_kvm_arm_set_dreg32("MDSCR_EL1", vcpu_sys_reg(vcpu, MDSCR_EL1));
 }
 
 void kvm_arm_clear_debug(struct kvm_vcpu *vcpu)
 {
+	trace_kvm_arm_clear_debug(vcpu->guest_debug);
+
 	if (vcpu->guest_debug) {
 		restore_guest_debug_regs(vcpu);
 
@@ -176,8 +202,16 @@ void kvm_arm_clear_debug(struct kvm_vcpu *vcpu)
 		 * If we were using HW debug we need to restore the
 		 * debug_ptr to the guest debug state.
 		 */
-		if (vcpu->guest_debug & KVM_GUESTDBG_USE_HW)
+		if (vcpu->guest_debug & KVM_GUESTDBG_USE_HW) {
 			kvm_arm_reset_debug_ptr(vcpu);
 
+			trace_kvm_arm_set_regset("BKPTS", get_num_brps(),
+						&vcpu->arch.debug_ptr->dbg_bcr[0],
+						&vcpu->arch.debug_ptr->dbg_bvr[0]);
+
+			trace_kvm_arm_set_regset("WAPTS", get_num_wrps(),
+						&vcpu->arch.debug_ptr->dbg_wcr[0],
+						&vcpu->arch.debug_ptr->dbg_wvr[0]);
+		}
 	}
 }
diff --git a/arch/arm64/kvm/guest.c b/arch/arm64/kvm/guest.c
index 6f1b249..48868d8 100644
--- a/arch/arm64/kvm/guest.c
+++ b/arch/arm64/kvm/guest.c
@@ -32,6 +32,8 @@
 #include <asm/kvm_emulate.h>
 #include <asm/kvm_coproc.h>
 
+#include "trace.h"
+
 struct kvm_stats_debugfs_item debugfs_entries[] = {
 	{ NULL }
 };
@@ -350,6 +352,8 @@ int kvm_arch_vcpu_ioctl_translate(struct kvm_vcpu *vcpu,
 int kvm_arch_vcpu_ioctl_set_guest_debug(struct kvm_vcpu *vcpu,
 					struct kvm_guest_debug *dbg)
 {
+	trace_kvm_set_guest_debug(vcpu, dbg->control);
+
 	if (dbg->control & ~KVM_GUESTDBG_VALID_MASK)
 		return -EINVAL;
 
diff --git a/arch/arm64/kvm/sys_regs.c b/arch/arm64/kvm/sys_regs.c
index 158bae7..b41607d 100644
--- a/arch/arm64/kvm/sys_regs.c
+++ b/arch/arm64/kvm/sys_regs.c
@@ -38,6 +38,8 @@
 
 #include "sys_regs.h"
 
+#include "trace.h"
+
 /*
  * All of this file is extremly similar to the ARM coproc.c, but the
  * types are different. My gut feeling is that it should be pretty
@@ -208,6 +210,8 @@ static bool trap_debug_regs(struct kvm_vcpu *vcpu,
 		*vcpu_reg(vcpu, p->Rt) = vcpu_sys_reg(vcpu, r->reg);
 	}
 
+	trace_trap_reg(__func__, r->reg, p->is_write, *vcpu_reg(vcpu, p->Rt));
+
 	return true;
 }
 
@@ -258,6 +262,8 @@ static inline bool trap_bvr(struct kvm_vcpu *vcpu,
 	else
 		dbg_to_reg(vcpu, p, dbg_reg);
 
+	trace_trap_reg(__func__, rd->reg, p->is_write, *dbg_reg);
+
 	return true;
 }
 
@@ -298,6 +304,8 @@ static inline bool trap_bcr(struct kvm_vcpu *vcpu,
 	else
 		dbg_to_reg(vcpu, p, dbg_reg);
 
+	trace_trap_reg(__func__, rd->reg, p->is_write, *dbg_reg);
+
 	return true;
 }
 
@@ -339,6 +347,9 @@ static inline bool trap_wvr(struct kvm_vcpu *vcpu,
 	else
 		dbg_to_reg(vcpu, p, dbg_reg);
 
+	trace_trap_reg(__func__, rd->reg, p->is_write,
+		vcpu->arch.vcpu_debug_state.dbg_wvr[rd->reg]);
+
 	return true;
 }
 
@@ -379,6 +390,8 @@ static inline bool trap_wcr(struct kvm_vcpu *vcpu,
 	else
 		dbg_to_reg(vcpu, p, dbg_reg);
 
+	trace_trap_reg(__func__, rd->reg, p->is_write, *dbg_reg);
+
 	return true;
 }
 
@@ -742,6 +755,8 @@ static inline bool trap_xvr(struct kvm_vcpu *vcpu,
 		*vcpu_reg(vcpu, p->Rt) = *dbg_reg >> 32;
 	}
 
+	trace_trap_reg(__func__, rd->reg, p->is_write, *dbg_reg);
+
 	return true;
 }
 
@@ -1223,6 +1238,8 @@ int kvm_handle_sys_reg(struct kvm_vcpu *vcpu, struct kvm_run *run)
 	struct sys_reg_params params;
 	unsigned long esr = kvm_vcpu_get_hsr(vcpu);
 
+	trace_kvm_handle_sys_reg(esr);
+
 	params.is_aarch32 = false;
 	params.is_32bit = false;
 	params.Op0 = (esr >> 20) & 3;
diff --git a/arch/arm64/kvm/trace.h b/arch/arm64/kvm/trace.h
index 157416e9..7fb0008 100644
--- a/arch/arm64/kvm/trace.h
+++ b/arch/arm64/kvm/trace.h
@@ -44,6 +44,129 @@ TRACE_EVENT(kvm_hvc_arm64,
 		  __entry->vcpu_pc, __entry->r0, __entry->imm)
 );
 
+TRACE_EVENT(kvm_arm_setup_debug,
+	TP_PROTO(struct kvm_vcpu *vcpu, __u32 guest_debug),
+	TP_ARGS(vcpu, guest_debug),
+
+	TP_STRUCT__entry(
+		__field(struct kvm_vcpu *, vcpu)
+		__field(__u32, guest_debug)
+	),
+
+	TP_fast_assign(
+		__entry->vcpu = vcpu;
+		__entry->guest_debug = guest_debug;
+	),
+
+	TP_printk("vcpu: %p, flags: 0x%08x", __entry->vcpu, __entry->guest_debug)
+);
+
+TRACE_EVENT(kvm_arm_clear_debug,
+	TP_PROTO(__u32 guest_debug),
+	TP_ARGS(guest_debug),
+
+	TP_STRUCT__entry(
+		__field(__u32, guest_debug)
+	),
+
+	TP_fast_assign(
+		__entry->guest_debug = guest_debug;
+	),
+
+	TP_printk("flags: 0x%08x", __entry->guest_debug)
+);
+
+TRACE_EVENT(kvm_arm_set_dreg32,
+	TP_PROTO(const char *name, __u32 value),
+	TP_ARGS(name, value),
+
+	TP_STRUCT__entry(
+		__field(const char *, name)
+		__field(__u32, value)
+	),
+
+	TP_fast_assign(
+		__entry->name = name;
+		__entry->value = value;
+	),
+
+	TP_printk("%s: 0x%08x", __entry->name, __entry->value)
+);
+
+TRACE_EVENT(kvm_arm_set_regset,
+	TP_PROTO(const char *type, int len, __u64 *control, __u64 *value),
+	TP_ARGS(type, len, control, value),
+	TP_STRUCT__entry(
+		__field(const char *, name)
+		__field(int, len)
+		__array(u64, ctrls, 16)
+		__array(u64, values, 16)
+	),
+	TP_fast_assign(
+		__entry->name = type;
+		__entry->len = len;
+		memcpy(__entry->ctrls, control, len << 3);
+		memcpy(__entry->values, value, len << 3);
+	),
+	TP_printk("%d %s CTRL:%s VALUE:%s", __entry->len, __entry->name,
+		__print_array(__entry->ctrls, __entry->len, sizeof(__u64)),
+		__print_array(__entry->values, __entry->len, sizeof(__u64)))
+);
+
+TRACE_EVENT(trap_reg,
+	TP_PROTO(const char *fn, int reg, bool is_write, u64 write_value),
+	TP_ARGS(fn, reg, is_write, write_value),
+
+	TP_STRUCT__entry(
+		__field(const char *, fn)
+		__field(int, reg)
+		__field(bool, is_write)
+		__field(u64, write_value)
+	),
+
+	TP_fast_assign(
+		__entry->fn = fn;
+		__entry->reg = reg;
+		__entry->is_write = is_write;
+		__entry->write_value = write_value;
+	),
+
+	TP_printk("%s %s reg %d (0x%08llx)", __entry->fn,  __entry->is_write?"write to":"read from", __entry->reg, __entry->write_value)
+);
+
+TRACE_EVENT(kvm_handle_sys_reg,
+	TP_PROTO(unsigned long hsr),
+	TP_ARGS(hsr),
+
+	TP_STRUCT__entry(
+		__field(unsigned long,	hsr)
+	),
+
+	TP_fast_assign(
+		__entry->hsr = hsr;
+	),
+
+	TP_printk("HSR 0x%08lx", __entry->hsr)
+);
+
+TRACE_EVENT(kvm_set_guest_debug,
+	TP_PROTO(struct kvm_vcpu *vcpu, __u32 guest_debug),
+	TP_ARGS(vcpu, guest_debug),
+
+	TP_STRUCT__entry(
+		__field(struct kvm_vcpu *, vcpu)
+		__field(__u32, guest_debug)
+	),
+
+	TP_fast_assign(
+		__entry->vcpu = vcpu;
+		__entry->guest_debug = guest_debug;
+	),
+
+	TP_printk("vcpu: %p, flags: 0x%08x", __entry->vcpu, __entry->guest_debug)
+);
+
+
 #endif /* _TRACE_ARM64_KVM_H */
 
 #undef TRACE_INCLUDE_PATH
-- 
2.1.4



From marc.zyngier at arm.com  Thu Aug 20 09:28:48 2015
From: marc.zyngier at arm.com (Marc Zyngier)
Date: Thu, 20 Aug 2015 17:28:48 +0100
Subject: [PATCH 10/25] KVM: arm64: enable KVM_CAP_SET_GUEST_DEBUG
In-Reply-To: <1440088143-4722-1-git-send-email-marc.zyngier@arm.com>
References: <1440088143-4722-1-git-send-email-marc.zyngier@arm.com>
Message-ID: <1440088143-4722-11-git-send-email-marc.zyngier@arm.com>

From: Alex Benn?e <alex.bennee at linaro.org>

Finally advertise the KVM capability for SET_GUEST_DEBUG. Once arm
support is added this check can be moved to the common
kvm_vm_ioctl_check_extension() code.

Signed-off-by: Alex Benn?e <alex.bennee at linaro.org>
Acked-by: Christoffer Dall <christoffer.dall at linaro.org>
Signed-off-by: Marc Zyngier <marc.zyngier at arm.com>
---
 Documentation/virtual/kvm/api.txt      |  7 +++++-
 arch/arm64/include/asm/hw_breakpoint.h | 14 ++++++++++++
 arch/arm64/include/asm/kvm_host.h      |  6 ++++-
 arch/arm64/kernel/hw_breakpoint.c      | 12 ----------
 arch/arm64/kvm/debug.c                 | 40 +++++++++++++++++++++++++++++-----
 arch/arm64/kvm/guest.c                 |  7 ++++++
 arch/arm64/kvm/handle_exit.c           |  6 +++++
 arch/arm64/kvm/reset.c                 | 16 ++++++++++++++
 8 files changed, 89 insertions(+), 19 deletions(-)

diff --git a/Documentation/virtual/kvm/api.txt b/Documentation/virtual/kvm/api.txt
index 0f498da..35affb5 100644
--- a/Documentation/virtual/kvm/api.txt
+++ b/Documentation/virtual/kvm/api.txt
@@ -2694,7 +2694,7 @@ The top 16 bits of the control field are architecture specific control
 flags which can include the following:
 
   - KVM_GUESTDBG_USE_SW_BP:     using software breakpoints [x86, arm64]
-  - KVM_GUESTDBG_USE_HW_BP:     using hardware breakpoints [x86, s390]
+  - KVM_GUESTDBG_USE_HW_BP:     using hardware breakpoints [x86, s390, arm64]
   - KVM_GUESTDBG_INJECT_DB:     inject DB type exception [x86]
   - KVM_GUESTDBG_INJECT_BP:     inject BP type exception [x86]
   - KVM_GUESTDBG_EXIT_PENDING:  trigger an immediate guest exit [s390]
@@ -2709,6 +2709,11 @@ updated to the correct (supplied) values.
 The second part of the structure is architecture specific and
 typically contains a set of debug registers.
 
+For arm64 the number of debug registers is implementation defined and
+can be determined by querying the KVM_CAP_GUEST_DEBUG_HW_BPS and
+KVM_CAP_GUEST_DEBUG_HW_WPS capabilities which return a positive number
+indicating the number of supported registers.
+
 When debug events exit the main run loop with the reason
 KVM_EXIT_DEBUG with the kvm_debug_exit_arch part of the kvm_run
 structure containing architecture specific debug information.
diff --git a/arch/arm64/include/asm/hw_breakpoint.h b/arch/arm64/include/asm/hw_breakpoint.h
index 52b484b..4c47cb2 100644
--- a/arch/arm64/include/asm/hw_breakpoint.h
+++ b/arch/arm64/include/asm/hw_breakpoint.h
@@ -16,6 +16,8 @@
 #ifndef __ASM_HW_BREAKPOINT_H
 #define __ASM_HW_BREAKPOINT_H
 
+#include <asm/cputype.h>
+
 #ifdef __KERNEL__
 
 struct arch_hw_breakpoint_ctrl {
@@ -132,5 +134,17 @@ static inline void ptrace_hw_copy_thread(struct task_struct *task)
 
 extern struct pmu perf_ops_bp;
 
+/* Determine number of BRP registers available. */
+static inline int get_num_brps(void)
+{
+	return ((read_cpuid(ID_AA64DFR0_EL1) >> 12) & 0xf) + 1;
+}
+
+/* Determine number of WRP registers available. */
+static inline int get_num_wrps(void)
+{
+	return ((read_cpuid(ID_AA64DFR0_EL1) >> 20) & 0xf) + 1;
+}
+
 #endif	/* __KERNEL__ */
 #endif	/* __ASM_BREAKPOINT_H */
diff --git a/arch/arm64/include/asm/kvm_host.h b/arch/arm64/include/asm/kvm_host.h
index 9b99402..409217f 100644
--- a/arch/arm64/include/asm/kvm_host.h
+++ b/arch/arm64/include/asm/kvm_host.h
@@ -116,13 +116,17 @@ struct kvm_vcpu_arch {
 	 * debugging the guest from the host and to maintain separate host and
 	 * guest state during world switches. vcpu_debug_state are the debug
 	 * registers of the vcpu as the guest sees them.  host_debug_state are
-	 * the host registers which are saved and restored during world switches.
+	 * the host registers which are saved and restored during
+	 * world switches. external_debug_state contains the debug
+	 * values we want to debug the guest. This is set via the
+	 * KVM_SET_GUEST_DEBUG ioctl.
 	 *
 	 * debug_ptr points to the set of debug registers that should be loaded
 	 * onto the hardware when running the guest.
 	 */
 	struct kvm_guest_debug_arch *debug_ptr;
 	struct kvm_guest_debug_arch vcpu_debug_state;
+	struct kvm_guest_debug_arch external_debug_state;
 
 	/* Pointer to host CPU context */
 	kvm_cpu_context_t *host_cpu_context;
diff --git a/arch/arm64/kernel/hw_breakpoint.c b/arch/arm64/kernel/hw_breakpoint.c
index 7a1a5da..77bee00 100644
--- a/arch/arm64/kernel/hw_breakpoint.c
+++ b/arch/arm64/kernel/hw_breakpoint.c
@@ -48,18 +48,6 @@ static DEFINE_PER_CPU(int, stepping_kernel_bp);
 static int core_num_brps;
 static int core_num_wrps;
 
-/* Determine number of BRP registers available. */
-static int get_num_brps(void)
-{
-	return ((read_cpuid(ID_AA64DFR0_EL1) >> 12) & 0xf) + 1;
-}
-
-/* Determine number of WRP registers available. */
-static int get_num_wrps(void)
-{
-	return ((read_cpuid(ID_AA64DFR0_EL1) >> 20) & 0xf) + 1;
-}
-
 int hw_breakpoint_slots(int type)
 {
 	/*
diff --git a/arch/arm64/kvm/debug.c b/arch/arm64/kvm/debug.c
index e0947b7..4a99e54 100644
--- a/arch/arm64/kvm/debug.c
+++ b/arch/arm64/kvm/debug.c
@@ -105,10 +105,6 @@ void kvm_arm_setup_debug(struct kvm_vcpu *vcpu)
 				MDCR_EL2_TDRA |
 				MDCR_EL2_TDOSA);
 
-	/* Trap on access to debug registers? */
-	if (trap_debug)
-		vcpu->arch.mdcr_el2 |= MDCR_EL2_TDA;
-
 	/* Is Guest debugging in effect? */
 	if (vcpu->guest_debug) {
 		/* Route all software debug exceptions to EL2 */
@@ -143,11 +139,45 @@ void kvm_arm_setup_debug(struct kvm_vcpu *vcpu)
 		} else {
 			vcpu_sys_reg(vcpu, MDSCR_EL1) &= ~DBG_MDSCR_SS;
 		}
+
+		/*
+		 * HW Breakpoints and watchpoints
+		 *
+		 * We simply switch the debug_ptr to point to our new
+		 * external_debug_state which has been populated by the
+		 * debug ioctl. The existing KVM_ARM64_DEBUG_DIRTY
+		 * mechanism ensures the registers are updated on the
+		 * world switch.
+		 */
+		if (vcpu->guest_debug & KVM_GUESTDBG_USE_HW) {
+			/* Enable breakpoints/watchpoints */
+			vcpu_sys_reg(vcpu, MDSCR_EL1) |= DBG_MDSCR_MDE;
+
+			vcpu->arch.debug_ptr = &vcpu->arch.external_debug_state;
+			vcpu->arch.debug_flags |= KVM_ARM64_DEBUG_DIRTY;
+			trap_debug = true;
+		}
 	}
+
+	BUG_ON(!vcpu->guest_debug &&
+		vcpu->arch.debug_ptr != &vcpu->arch.vcpu_debug_state);
+
+	/* Trap debug register access */
+	if (trap_debug)
+		vcpu->arch.mdcr_el2 |= MDCR_EL2_TDA;
 }
 
 void kvm_arm_clear_debug(struct kvm_vcpu *vcpu)
 {
-	if (vcpu->guest_debug)
+	if (vcpu->guest_debug) {
 		restore_guest_debug_regs(vcpu);
+
+		/*
+		 * If we were using HW debug we need to restore the
+		 * debug_ptr to the guest debug state.
+		 */
+		if (vcpu->guest_debug & KVM_GUESTDBG_USE_HW)
+			kvm_arm_reset_debug_ptr(vcpu);
+
+	}
 }
diff --git a/arch/arm64/kvm/guest.c b/arch/arm64/kvm/guest.c
index 48de4f4..6f1b249 100644
--- a/arch/arm64/kvm/guest.c
+++ b/arch/arm64/kvm/guest.c
@@ -334,6 +334,7 @@ int kvm_arch_vcpu_ioctl_translate(struct kvm_vcpu *vcpu,
 
 #define KVM_GUESTDBG_VALID_MASK (KVM_GUESTDBG_ENABLE |    \
 			    KVM_GUESTDBG_USE_SW_BP | \
+			    KVM_GUESTDBG_USE_HW | \
 			    KVM_GUESTDBG_SINGLESTEP)
 
 /**
@@ -354,6 +355,12 @@ int kvm_arch_vcpu_ioctl_set_guest_debug(struct kvm_vcpu *vcpu,
 
 	if (dbg->control & KVM_GUESTDBG_ENABLE) {
 		vcpu->guest_debug = dbg->control;
+
+		/* Hardware assisted Break and Watch points */
+		if (vcpu->guest_debug & KVM_GUESTDBG_USE_HW) {
+			vcpu->arch.external_debug_state = dbg->arch;
+		}
+
 	} else {
 		/* If not enabled clear all flags */
 		vcpu->guest_debug = 0;
diff --git a/arch/arm64/kvm/handle_exit.c b/arch/arm64/kvm/handle_exit.c
index e9de13e..68a0759 100644
--- a/arch/arm64/kvm/handle_exit.c
+++ b/arch/arm64/kvm/handle_exit.c
@@ -103,7 +103,11 @@ static int kvm_handle_guest_debug(struct kvm_vcpu *vcpu, struct kvm_run *run)
 	run->debug.arch.hsr = hsr;
 
 	switch (hsr >> ESR_ELx_EC_SHIFT) {
+	case ESR_ELx_EC_WATCHPT_LOW:
+		run->debug.arch.far = vcpu->arch.fault.far_el2;
+		/* fall through */
 	case ESR_ELx_EC_SOFTSTP_LOW:
+	case ESR_ELx_EC_BREAKPT_LOW:
 	case ESR_ELx_EC_BKPT32:
 	case ESR_ELx_EC_BRK64:
 		break;
@@ -132,6 +136,8 @@ static exit_handle_fn arm_exit_handlers[] = {
 	[ESR_ELx_EC_IABT_LOW]	= kvm_handle_guest_abort,
 	[ESR_ELx_EC_DABT_LOW]	= kvm_handle_guest_abort,
 	[ESR_ELx_EC_SOFTSTP_LOW]= kvm_handle_guest_debug,
+	[ESR_ELx_EC_WATCHPT_LOW]= kvm_handle_guest_debug,
+	[ESR_ELx_EC_BREAKPT_LOW]= kvm_handle_guest_debug,
 	[ESR_ELx_EC_BKPT32]	= kvm_handle_guest_debug,
 	[ESR_ELx_EC_BRK64]	= kvm_handle_guest_debug,
 };
diff --git a/arch/arm64/kvm/reset.c b/arch/arm64/kvm/reset.c
index 0b43265..b4af618 100644
--- a/arch/arm64/kvm/reset.c
+++ b/arch/arm64/kvm/reset.c
@@ -22,6 +22,7 @@
 #include <linux/errno.h>
 #include <linux/kvm_host.h>
 #include <linux/kvm.h>
+#include <linux/hw_breakpoint.h>
 
 #include <kvm/arm_arch_timer.h>
 
@@ -56,6 +57,12 @@ static bool cpu_has_32bit_el1(void)
 	return !!(pfr0 & 0x20);
 }
 
+/**
+ * kvm_arch_dev_ioctl_check_extension
+ *
+ * We currently assume that the number of HW registers is uniform
+ * across all CPUs (see cpuinfo_sanity_check).
+ */
 int kvm_arch_dev_ioctl_check_extension(long ext)
 {
 	int r;
@@ -64,6 +71,15 @@ int kvm_arch_dev_ioctl_check_extension(long ext)
 	case KVM_CAP_ARM_EL1_32BIT:
 		r = cpu_has_32bit_el1();
 		break;
+	case KVM_CAP_GUEST_DEBUG_HW_BPS:
+		r = get_num_brps();
+		break;
+	case KVM_CAP_GUEST_DEBUG_HW_WPS:
+		r = get_num_wrps();
+		break;
+	case KVM_CAP_SET_GUEST_DEBUG:
+		r = 1;
+		break;
 	default:
 		r = 0;
 	}
-- 
2.1.4



From marc.zyngier at arm.com  Thu Aug 20 09:28:53 2015
From: marc.zyngier at arm.com (Marc Zyngier)
Date: Thu, 20 Aug 2015 17:28:53 +0100
Subject: [PATCH 15/25] arm/arm64: KVM: Move vgic handling to a non-preemptible
 section
In-Reply-To: <1440088143-4722-1-git-send-email-marc.zyngier@arm.com>
References: <1440088143-4722-1-git-send-email-marc.zyngier@arm.com>
Message-ID: <1440088143-4722-16-git-send-email-marc.zyngier@arm.com>

As we're about to introduce some serious GIC-poking to the vgic code,
it is important to make sure that we're going to poke the part of
the GIC that belongs to the CPU we're about to run on (otherwise,
we'd end up with some unexpected interrupts firing)...

Introducing a non-preemptible section in kvm_arch_vcpu_ioctl_run
prevents the problem from occuring.

Reviewed-by: Alex Benn?e <alex.bennee at linaro.org>
Reviewed-by: Christoffer Dall <christoffer.dall at linaro.org>
Signed-off-by: Marc Zyngier <marc.zyngier at arm.com>
---
 arch/arm/kvm/arm.c | 18 +++++++++++++++---
 1 file changed, 15 insertions(+), 3 deletions(-)

diff --git a/arch/arm/kvm/arm.c b/arch/arm/kvm/arm.c
index 1141d21..f1bf418 100644
--- a/arch/arm/kvm/arm.c
+++ b/arch/arm/kvm/arm.c
@@ -523,10 +523,20 @@ int kvm_arch_vcpu_ioctl_run(struct kvm_vcpu *vcpu, struct kvm_run *run)
 		if (vcpu->arch.pause)
 			vcpu_pause(vcpu);
 
+		/*
+		 * Disarming the background timer must be done in a
+		 * preemptible context, as this call may sleep.
+		 */
 		kvm_timer_flush_hwstate(vcpu);
-		kvm_vgic_flush_hwstate(vcpu);
 
+		/*
+		 * Preparing the interrupts to be injected also
+		 * involves poking the GIC, which must be done in a
+		 * non-preemptible context.
+		 */
 		preempt_disable();
+		kvm_vgic_flush_hwstate(vcpu);
+
 		local_irq_disable();
 
 		/*
@@ -539,8 +549,8 @@ int kvm_arch_vcpu_ioctl_run(struct kvm_vcpu *vcpu, struct kvm_run *run)
 
 		if (ret <= 0 || need_new_vmid_gen(vcpu->kvm)) {
 			local_irq_enable();
-			preempt_enable();
 			kvm_vgic_sync_hwstate(vcpu);
+			preempt_enable();
 			kvm_timer_sync_hwstate(vcpu);
 			continue;
 		}
@@ -585,9 +595,11 @@ int kvm_arch_vcpu_ioctl_run(struct kvm_vcpu *vcpu, struct kvm_run *run)
 		 */
 		kvm_guest_exit();
 		trace_kvm_exit(kvm_vcpu_trap_get_class(vcpu), *vcpu_pc(vcpu));
-		preempt_enable();
 
 		kvm_vgic_sync_hwstate(vcpu);
+
+		preempt_enable();
+
 		kvm_timer_sync_hwstate(vcpu);
 
 		ret = handle_exit(vcpu, run, ret);
-- 
2.1.4



From marc.zyngier at arm.com  Thu Aug 20 09:28:46 2015
From: marc.zyngier at arm.com (Marc Zyngier)
Date: Thu, 20 Aug 2015 17:28:46 +0100
Subject: [PATCH 08/25] KVM: arm64: introduce vcpu->arch.debug_ptr
In-Reply-To: <1440088143-4722-1-git-send-email-marc.zyngier@arm.com>
References: <1440088143-4722-1-git-send-email-marc.zyngier@arm.com>
Message-ID: <1440088143-4722-9-git-send-email-marc.zyngier@arm.com>

From: Alex Benn?e <alex.bennee at linaro.org>

This introduces a level of indirection for the debug registers. Instead
of using the sys_regs[] directly we store registers in a structure in
the vcpu. The new kvm_arm_reset_debug_ptr() sets the debug ptr to the
guest context.

Because we no longer give the sys_regs offset for the sys_reg_desc->reg
field, but instead the index into a debug-specific struct we need to
add a number of additional trap functions for each register. Also as the
generic generic user-space access code no longer works we have
introduced a new pair of function pointers to the sys_reg_desc structure
to override the generic code when needed.

Reviewed-by: Christoffer Dall <christoffer.dall at linaro.org>
Signed-off-by: Alex Benn?e <alex.bennee at linaro.org>
Signed-off-by: Marc Zyngier <marc.zyngier at arm.com>
---
 arch/arm/include/asm/kvm_host.h   |   1 +
 arch/arm/kvm/arm.c                |   2 +
 arch/arm64/include/asm/kvm_asm.h  |  24 ++--
 arch/arm64/include/asm/kvm_host.h |  17 ++-
 arch/arm64/kernel/asm-offsets.c   |   6 +
 arch/arm64/kvm/debug.c            |   9 ++
 arch/arm64/kvm/hyp.S              |  24 ++--
 arch/arm64/kvm/sys_regs.c         | 274 +++++++++++++++++++++++++++++++++++---
 arch/arm64/kvm/sys_regs.h         |   6 +
 9 files changed, 316 insertions(+), 47 deletions(-)

diff --git a/arch/arm/include/asm/kvm_host.h b/arch/arm/include/asm/kvm_host.h
index 2b0bc8c..dcba0fa 100644
--- a/arch/arm/include/asm/kvm_host.h
+++ b/arch/arm/include/asm/kvm_host.h
@@ -234,5 +234,6 @@ static inline void kvm_arch_sched_in(struct kvm_vcpu *vcpu, int cpu) {}
 static inline void kvm_arm_init_debug(void) {}
 static inline void kvm_arm_setup_debug(struct kvm_vcpu *vcpu) {}
 static inline void kvm_arm_clear_debug(struct kvm_vcpu *vcpu) {}
+static inline void kvm_arm_reset_debug_ptr(struct kvm_vcpu *vcpu) {}
 
 #endif /* __ARM_KVM_HOST_H__ */
diff --git a/arch/arm/kvm/arm.c b/arch/arm/kvm/arm.c
index 77151b1..9ce5cf0 100644
--- a/arch/arm/kvm/arm.c
+++ b/arch/arm/kvm/arm.c
@@ -278,6 +278,8 @@ int kvm_arch_vcpu_init(struct kvm_vcpu *vcpu)
 	/* Set up the timer */
 	kvm_timer_vcpu_init(vcpu);
 
+	kvm_arm_reset_debug_ptr(vcpu);
+
 	return 0;
 }
 
diff --git a/arch/arm64/include/asm/kvm_asm.h b/arch/arm64/include/asm/kvm_asm.h
index f5e40da..67fa0de 100644
--- a/arch/arm64/include/asm/kvm_asm.h
+++ b/arch/arm64/include/asm/kvm_asm.h
@@ -46,24 +46,16 @@
 #define	CNTKCTL_EL1	20	/* Timer Control Register (EL1) */
 #define	PAR_EL1		21	/* Physical Address Register */
 #define MDSCR_EL1	22	/* Monitor Debug System Control Register */
-#define DBGBCR0_EL1	23	/* Debug Breakpoint Control Registers (0-15) */
-#define DBGBCR15_EL1	38
-#define DBGBVR0_EL1	39	/* Debug Breakpoint Value Registers (0-15) */
-#define DBGBVR15_EL1	54
-#define DBGWCR0_EL1	55	/* Debug Watchpoint Control Registers (0-15) */
-#define DBGWCR15_EL1	70
-#define DBGWVR0_EL1	71	/* Debug Watchpoint Value Registers (0-15) */
-#define DBGWVR15_EL1	86
-#define MDCCINT_EL1	87	/* Monitor Debug Comms Channel Interrupt Enable Reg */
+#define MDCCINT_EL1	23	/* Monitor Debug Comms Channel Interrupt Enable Reg */
 
 /* 32bit specific registers. Keep them at the end of the range */
-#define	DACR32_EL2	88	/* Domain Access Control Register */
-#define	IFSR32_EL2	89	/* Instruction Fault Status Register */
-#define	FPEXC32_EL2	90	/* Floating-Point Exception Control Register */
-#define	DBGVCR32_EL2	91	/* Debug Vector Catch Register */
-#define	TEECR32_EL1	92	/* ThumbEE Configuration Register */
-#define	TEEHBR32_EL1	93	/* ThumbEE Handler Base Register */
-#define	NR_SYS_REGS	94
+#define	DACR32_EL2	24	/* Domain Access Control Register */
+#define	IFSR32_EL2	25	/* Instruction Fault Status Register */
+#define	FPEXC32_EL2	26	/* Floating-Point Exception Control Register */
+#define	DBGVCR32_EL2	27	/* Debug Vector Catch Register */
+#define	TEECR32_EL1	28	/* ThumbEE Configuration Register */
+#define	TEEHBR32_EL1	29	/* ThumbEE Handler Base Register */
+#define	NR_SYS_REGS	30
 
 /* 32bit mapping */
 #define c0_MPIDR	(MPIDR_EL1 * 2)	/* MultiProcessor ID Register */
diff --git a/arch/arm64/include/asm/kvm_host.h b/arch/arm64/include/asm/kvm_host.h
index cfb6754..9b99402 100644
--- a/arch/arm64/include/asm/kvm_host.h
+++ b/arch/arm64/include/asm/kvm_host.h
@@ -108,11 +108,25 @@ struct kvm_vcpu_arch {
 	/* Exception Information */
 	struct kvm_vcpu_fault_info fault;
 
-	/* Debug state */
+	/* Guest debug state */
 	u64 debug_flags;
 
+	/*
+	 * We maintain more than a single set of debug registers to support
+	 * debugging the guest from the host and to maintain separate host and
+	 * guest state during world switches. vcpu_debug_state are the debug
+	 * registers of the vcpu as the guest sees them.  host_debug_state are
+	 * the host registers which are saved and restored during world switches.
+	 *
+	 * debug_ptr points to the set of debug registers that should be loaded
+	 * onto the hardware when running the guest.
+	 */
+	struct kvm_guest_debug_arch *debug_ptr;
+	struct kvm_guest_debug_arch vcpu_debug_state;
+
 	/* Pointer to host CPU context */
 	kvm_cpu_context_t *host_cpu_context;
+	struct kvm_guest_debug_arch host_debug_state;
 
 	/* VGIC state */
 	struct vgic_cpu vgic_cpu;
@@ -242,5 +256,6 @@ static inline void kvm_arch_sched_in(struct kvm_vcpu *vcpu, int cpu) {}
 void kvm_arm_init_debug(void);
 void kvm_arm_setup_debug(struct kvm_vcpu *vcpu);
 void kvm_arm_clear_debug(struct kvm_vcpu *vcpu);
+void kvm_arm_reset_debug_ptr(struct kvm_vcpu *vcpu);
 
 #endif /* __ARM64_KVM_HOST_H__ */
diff --git a/arch/arm64/kernel/asm-offsets.c b/arch/arm64/kernel/asm-offsets.c
index 5c900d4..d886308 100644
--- a/arch/arm64/kernel/asm-offsets.c
+++ b/arch/arm64/kernel/asm-offsets.c
@@ -116,10 +116,16 @@ int main(void)
   DEFINE(VCPU_FAR_EL2,		offsetof(struct kvm_vcpu, arch.fault.far_el2));
   DEFINE(VCPU_HPFAR_EL2,	offsetof(struct kvm_vcpu, arch.fault.hpfar_el2));
   DEFINE(VCPU_DEBUG_FLAGS,	offsetof(struct kvm_vcpu, arch.debug_flags));
+  DEFINE(VCPU_DEBUG_PTR,	offsetof(struct kvm_vcpu, arch.debug_ptr));
+  DEFINE(DEBUG_BCR, 		offsetof(struct kvm_guest_debug_arch, dbg_bcr));
+  DEFINE(DEBUG_BVR, 		offsetof(struct kvm_guest_debug_arch, dbg_bvr));
+  DEFINE(DEBUG_WCR, 		offsetof(struct kvm_guest_debug_arch, dbg_wcr));
+  DEFINE(DEBUG_WVR, 		offsetof(struct kvm_guest_debug_arch, dbg_wvr));
   DEFINE(VCPU_HCR_EL2,		offsetof(struct kvm_vcpu, arch.hcr_el2));
   DEFINE(VCPU_MDCR_EL2,	offsetof(struct kvm_vcpu, arch.mdcr_el2));
   DEFINE(VCPU_IRQ_LINES,	offsetof(struct kvm_vcpu, arch.irq_lines));
   DEFINE(VCPU_HOST_CONTEXT,	offsetof(struct kvm_vcpu, arch.host_cpu_context));
+  DEFINE(VCPU_HOST_DEBUG_STATE, offsetof(struct kvm_vcpu, arch.host_debug_state));
   DEFINE(VCPU_TIMER_CNTV_CTL,	offsetof(struct kvm_vcpu, arch.timer_cpu.cntv_ctl));
   DEFINE(VCPU_TIMER_CNTV_CVAL,	offsetof(struct kvm_vcpu, arch.timer_cpu.cntv_cval));
   DEFINE(KVM_TIMER_CNTVOFF,	offsetof(struct kvm, arch.timer.cntvoff));
diff --git a/arch/arm64/kvm/debug.c b/arch/arm64/kvm/debug.c
index d439eb8..e0947b7 100644
--- a/arch/arm64/kvm/debug.c
+++ b/arch/arm64/kvm/debug.c
@@ -67,6 +67,15 @@ void kvm_arm_init_debug(void)
 }
 
 /**
+ * kvm_arm_reset_debug_ptr - reset the debug ptr to point to the vcpu state
+ */
+
+void kvm_arm_reset_debug_ptr(struct kvm_vcpu *vcpu)
+{
+	vcpu->arch.debug_ptr = &vcpu->arch.vcpu_debug_state;
+}
+
+/**
  * kvm_arm_setup_debug - set up debug related stuff
  *
  * @vcpu:	the vcpu pointer
diff --git a/arch/arm64/kvm/hyp.S b/arch/arm64/kvm/hyp.S
index 8264f5b..d93c0a2 100644
--- a/arch/arm64/kvm/hyp.S
+++ b/arch/arm64/kvm/hyp.S
@@ -596,6 +596,7 @@ __restore_sysregs:
 /* Save debug state */
 __save_debug:
 	// x2: ptr to CPU context
+	// x3: ptr to debug reg struct
 	// x4/x5/x6-22/x24-26: trashed
 
 	mrs	x26, id_aa64dfr0_el1
@@ -606,15 +607,15 @@ __save_debug:
 	sub	w25, w26, w25		// How many WPs to skip
 
 	mov	x5, x24
-	add	x4, x2, #CPU_SYSREG_OFFSET(DBGBCR0_EL1)
+	add	x4, x3, #DEBUG_BCR
 	save_debug dbgbcr
-	add	x4, x2, #CPU_SYSREG_OFFSET(DBGBVR0_EL1)
+	add	x4, x3, #DEBUG_BVR
 	save_debug dbgbvr
 
 	mov	x5, x25
-	add	x4, x2, #CPU_SYSREG_OFFSET(DBGWCR0_EL1)
+	add	x4, x3, #DEBUG_WCR
 	save_debug dbgwcr
-	add	x4, x2, #CPU_SYSREG_OFFSET(DBGWVR0_EL1)
+	add	x4, x3, #DEBUG_WVR
 	save_debug dbgwvr
 
 	mrs	x21, mdccint_el1
@@ -624,6 +625,7 @@ __save_debug:
 /* Restore debug state */
 __restore_debug:
 	// x2: ptr to CPU context
+	// x3: ptr to debug reg struct
 	// x4/x5/x6-22/x24-26: trashed
 
 	mrs	x26, id_aa64dfr0_el1
@@ -634,15 +636,15 @@ __restore_debug:
 	sub	w25, w26, w25		// How many WPs to skip
 
 	mov	x5, x24
-	add	x4, x2, #CPU_SYSREG_OFFSET(DBGBCR0_EL1)
+	add	x4, x3, #DEBUG_BCR
 	restore_debug dbgbcr
-	add	x4, x2, #CPU_SYSREG_OFFSET(DBGBVR0_EL1)
+	add	x4, x3, #DEBUG_BVR
 	restore_debug dbgbvr
 
 	mov	x5, x25
-	add	x4, x2, #CPU_SYSREG_OFFSET(DBGWCR0_EL1)
+	add	x4, x3, #DEBUG_WCR
 	restore_debug dbgwcr
-	add	x4, x2, #CPU_SYSREG_OFFSET(DBGWVR0_EL1)
+	add	x4, x3, #DEBUG_WVR
 	restore_debug dbgwvr
 
 	ldr	x21, [x2, #CPU_SYSREG_OFFSET(MDCCINT_EL1)]
@@ -682,6 +684,7 @@ ENTRY(__kvm_vcpu_run)
 	bl __save_sysregs
 
 	compute_debug_state 1f
+	add	x3, x0, #VCPU_HOST_DEBUG_STATE
 	bl	__save_debug
 1:
 	activate_traps
@@ -697,6 +700,8 @@ ENTRY(__kvm_vcpu_run)
 	bl __restore_fpsimd
 
 	skip_debug_state x3, 1f
+	ldr	x3, [x0, #VCPU_DEBUG_PTR]
+	kern_hyp_va x3
 	bl	__restore_debug
 1:
 	restore_guest_32bit_state
@@ -717,6 +722,8 @@ __kvm_vcpu_return:
 	bl __save_sysregs
 
 	skip_debug_state x3, 1f
+	ldr	x3, [x0, #VCPU_DEBUG_PTR]
+	kern_hyp_va x3
 	bl	__save_debug
 1:
 	save_guest_32bit_state
@@ -739,6 +746,7 @@ __kvm_vcpu_return:
 	// already been saved. Note that we nuke the whole 64bit word.
 	// If we ever add more flags, we'll have to be more careful...
 	str	xzr, [x0, #VCPU_DEBUG_FLAGS]
+	add	x3, x0, #VCPU_HOST_DEBUG_STATE
 	bl	__restore_debug
 1:
 	restore_host_regs
diff --git a/arch/arm64/kvm/sys_regs.c b/arch/arm64/kvm/sys_regs.c
index c370b40..158bae7 100644
--- a/arch/arm64/kvm/sys_regs.c
+++ b/arch/arm64/kvm/sys_regs.c
@@ -211,6 +211,203 @@ static bool trap_debug_regs(struct kvm_vcpu *vcpu,
 	return true;
 }
 
+/*
+ * reg_to_dbg/dbg_to_reg
+ *
+ * A 32 bit write to a debug register leave top bits alone
+ * A 32 bit read from a debug register only returns the bottom bits
+ *
+ * All writes will set the KVM_ARM64_DEBUG_DIRTY flag to ensure the
+ * hyp.S code switches between host and guest values in future.
+ */
+static inline void reg_to_dbg(struct kvm_vcpu *vcpu,
+			      const struct sys_reg_params *p,
+			      u64 *dbg_reg)
+{
+	u64 val = *vcpu_reg(vcpu, p->Rt);
+
+	if (p->is_32bit) {
+		val &= 0xffffffffUL;
+		val |= ((*dbg_reg >> 32) << 32);
+	}
+
+	*dbg_reg = val;
+	vcpu->arch.debug_flags |= KVM_ARM64_DEBUG_DIRTY;
+}
+
+static inline void dbg_to_reg(struct kvm_vcpu *vcpu,
+			      const struct sys_reg_params *p,
+			      u64 *dbg_reg)
+{
+	u64 val = *dbg_reg;
+
+	if (p->is_32bit)
+		val &= 0xffffffffUL;
+
+	*vcpu_reg(vcpu, p->Rt) = val;
+}
+
+static inline bool trap_bvr(struct kvm_vcpu *vcpu,
+			    const struct sys_reg_params *p,
+			    const struct sys_reg_desc *rd)
+{
+	u64 *dbg_reg = &vcpu->arch.vcpu_debug_state.dbg_bvr[rd->reg];
+
+	if (p->is_write)
+		reg_to_dbg(vcpu, p, dbg_reg);
+	else
+		dbg_to_reg(vcpu, p, dbg_reg);
+
+	return true;
+}
+
+static int set_bvr(struct kvm_vcpu *vcpu, const struct sys_reg_desc *rd,
+		const struct kvm_one_reg *reg, void __user *uaddr)
+{
+	__u64 *r = &vcpu->arch.vcpu_debug_state.dbg_bvr[rd->reg];
+
+	if (copy_from_user(uaddr, r, KVM_REG_SIZE(reg->id)) != 0)
+		return -EFAULT;
+	return 0;
+}
+
+static int get_bvr(struct kvm_vcpu *vcpu, const struct sys_reg_desc *rd,
+	const struct kvm_one_reg *reg, void __user *uaddr)
+{
+	__u64 *r = &vcpu->arch.vcpu_debug_state.dbg_bvr[rd->reg];
+
+	if (copy_to_user(uaddr, r, KVM_REG_SIZE(reg->id)) != 0)
+		return -EFAULT;
+	return 0;
+}
+
+static inline void reset_bvr(struct kvm_vcpu *vcpu,
+			     const struct sys_reg_desc *rd)
+{
+	vcpu->arch.vcpu_debug_state.dbg_bvr[rd->reg] = rd->val;
+}
+
+static inline bool trap_bcr(struct kvm_vcpu *vcpu,
+			    const struct sys_reg_params *p,
+			    const struct sys_reg_desc *rd)
+{
+	u64 *dbg_reg = &vcpu->arch.vcpu_debug_state.dbg_bcr[rd->reg];
+
+	if (p->is_write)
+		reg_to_dbg(vcpu, p, dbg_reg);
+	else
+		dbg_to_reg(vcpu, p, dbg_reg);
+
+	return true;
+}
+
+static int set_bcr(struct kvm_vcpu *vcpu, const struct sys_reg_desc *rd,
+		const struct kvm_one_reg *reg, void __user *uaddr)
+{
+	__u64 *r = &vcpu->arch.vcpu_debug_state.dbg_bcr[rd->reg];
+
+	if (copy_from_user(uaddr, r, KVM_REG_SIZE(reg->id)) != 0)
+		return -EFAULT;
+
+	return 0;
+}
+
+static int get_bcr(struct kvm_vcpu *vcpu, const struct sys_reg_desc *rd,
+	const struct kvm_one_reg *reg, void __user *uaddr)
+{
+	__u64 *r = &vcpu->arch.vcpu_debug_state.dbg_bcr[rd->reg];
+
+	if (copy_to_user(uaddr, r, KVM_REG_SIZE(reg->id)) != 0)
+		return -EFAULT;
+	return 0;
+}
+
+static inline void reset_bcr(struct kvm_vcpu *vcpu,
+			     const struct sys_reg_desc *rd)
+{
+	vcpu->arch.vcpu_debug_state.dbg_bcr[rd->reg] = rd->val;
+}
+
+static inline bool trap_wvr(struct kvm_vcpu *vcpu,
+			    const struct sys_reg_params *p,
+			    const struct sys_reg_desc *rd)
+{
+	u64 *dbg_reg = &vcpu->arch.vcpu_debug_state.dbg_wvr[rd->reg];
+
+	if (p->is_write)
+		reg_to_dbg(vcpu, p, dbg_reg);
+	else
+		dbg_to_reg(vcpu, p, dbg_reg);
+
+	return true;
+}
+
+static int set_wvr(struct kvm_vcpu *vcpu, const struct sys_reg_desc *rd,
+		const struct kvm_one_reg *reg, void __user *uaddr)
+{
+	__u64 *r = &vcpu->arch.vcpu_debug_state.dbg_wvr[rd->reg];
+
+	if (copy_from_user(uaddr, r, KVM_REG_SIZE(reg->id)) != 0)
+		return -EFAULT;
+	return 0;
+}
+
+static int get_wvr(struct kvm_vcpu *vcpu, const struct sys_reg_desc *rd,
+	const struct kvm_one_reg *reg, void __user *uaddr)
+{
+	__u64 *r = &vcpu->arch.vcpu_debug_state.dbg_wvr[rd->reg];
+
+	if (copy_to_user(uaddr, r, KVM_REG_SIZE(reg->id)) != 0)
+		return -EFAULT;
+	return 0;
+}
+
+static inline void reset_wvr(struct kvm_vcpu *vcpu,
+			     const struct sys_reg_desc *rd)
+{
+	vcpu->arch.vcpu_debug_state.dbg_wvr[rd->reg] = rd->val;
+}
+
+static inline bool trap_wcr(struct kvm_vcpu *vcpu,
+			    const struct sys_reg_params *p,
+			    const struct sys_reg_desc *rd)
+{
+	u64 *dbg_reg = &vcpu->arch.vcpu_debug_state.dbg_wcr[rd->reg];
+
+	if (p->is_write)
+		reg_to_dbg(vcpu, p, dbg_reg);
+	else
+		dbg_to_reg(vcpu, p, dbg_reg);
+
+	return true;
+}
+
+static int set_wcr(struct kvm_vcpu *vcpu, const struct sys_reg_desc *rd,
+		const struct kvm_one_reg *reg, void __user *uaddr)
+{
+	__u64 *r = &vcpu->arch.vcpu_debug_state.dbg_wcr[rd->reg];
+
+	if (copy_from_user(uaddr, r, KVM_REG_SIZE(reg->id)) != 0)
+		return -EFAULT;
+	return 0;
+}
+
+static int get_wcr(struct kvm_vcpu *vcpu, const struct sys_reg_desc *rd,
+	const struct kvm_one_reg *reg, void __user *uaddr)
+{
+	__u64 *r = &vcpu->arch.vcpu_debug_state.dbg_wcr[rd->reg];
+
+	if (copy_to_user(uaddr, r, KVM_REG_SIZE(reg->id)) != 0)
+		return -EFAULT;
+	return 0;
+}
+
+static inline void reset_wcr(struct kvm_vcpu *vcpu,
+			     const struct sys_reg_desc *rd)
+{
+	vcpu->arch.vcpu_debug_state.dbg_wcr[rd->reg] = rd->val;
+}
+
 static void reset_amair_el1(struct kvm_vcpu *vcpu, const struct sys_reg_desc *r)
 {
 	u64 amair;
@@ -240,16 +437,16 @@ static void reset_mpidr(struct kvm_vcpu *vcpu, const struct sys_reg_desc *r)
 #define DBG_BCR_BVR_WCR_WVR_EL1(n)					\
 	/* DBGBVRn_EL1 */						\
 	{ Op0(0b10), Op1(0b000), CRn(0b0000), CRm((n)), Op2(0b100),	\
-	  trap_debug_regs, reset_val, (DBGBVR0_EL1 + (n)), 0 },		\
+	  trap_bvr, reset_bvr, n, 0, get_bvr, set_bvr },		\
 	/* DBGBCRn_EL1 */						\
 	{ Op0(0b10), Op1(0b000), CRn(0b0000), CRm((n)), Op2(0b101),	\
-	  trap_debug_regs, reset_val, (DBGBCR0_EL1 + (n)), 0 },		\
+	  trap_bcr, reset_bcr, n, 0, get_bcr, set_bcr },		\
 	/* DBGWVRn_EL1 */						\
 	{ Op0(0b10), Op1(0b000), CRn(0b0000), CRm((n)), Op2(0b110),	\
-	  trap_debug_regs, reset_val, (DBGWVR0_EL1 + (n)), 0 },		\
+	  trap_wvr, reset_wvr, n, 0,  get_wvr, set_wvr },		\
 	/* DBGWCRn_EL1 */						\
 	{ Op0(0b10), Op1(0b000), CRn(0b0000), CRm((n)), Op2(0b111),	\
-	  trap_debug_regs, reset_val, (DBGWCR0_EL1 + (n)), 0 }
+	  trap_wcr, reset_wcr, n, 0,  get_wcr, set_wcr }
 
 /*
  * Architected system registers.
@@ -516,28 +713,55 @@ static bool trap_debug32(struct kvm_vcpu *vcpu,
 	return true;
 }
 
-#define DBG_BCR_BVR_WCR_WVR(n)					\
-	/* DBGBVRn */						\
-	{ Op1( 0), CRn( 0), CRm((n)), Op2( 4), trap_debug32,	\
-	  NULL, (cp14_DBGBVR0 + (n) * 2) },			\
-	/* DBGBCRn */						\
-	{ Op1( 0), CRn( 0), CRm((n)), Op2( 5), trap_debug32,	\
-	  NULL, (cp14_DBGBCR0 + (n) * 2) },			\
-	/* DBGWVRn */						\
-	{ Op1( 0), CRn( 0), CRm((n)), Op2( 6), trap_debug32,	\
-	  NULL, (cp14_DBGWVR0 + (n) * 2) },			\
-	/* DBGWCRn */						\
-	{ Op1( 0), CRn( 0), CRm((n)), Op2( 7), trap_debug32,	\
-	  NULL, (cp14_DBGWCR0 + (n) * 2) }
-
-#define DBGBXVR(n)						\
-	{ Op1( 0), CRn( 1), CRm((n)), Op2( 1), trap_debug32,	\
-	  NULL, cp14_DBGBXVR0 + n * 2 }
+/* AArch32 debug register mappings
+ *
+ * AArch32 DBGBVRn is mapped to DBGBVRn_EL1[31:0]
+ * AArch32 DBGBXVRn is mapped to DBGBVRn_EL1[63:32]
+ *
+ * All control registers and watchpoint value registers are mapped to
+ * the lower 32 bits of their AArch64 equivalents. We share the trap
+ * handlers with the above AArch64 code which checks what mode the
+ * system is in.
+ */
+
+static inline bool trap_xvr(struct kvm_vcpu *vcpu,
+			    const struct sys_reg_params *p,
+			    const struct sys_reg_desc *rd)
+{
+	u64 *dbg_reg = &vcpu->arch.vcpu_debug_state.dbg_bvr[rd->reg];
+
+	if (p->is_write) {
+		u64 val = *dbg_reg;
+
+		val &= 0xffffffffUL;
+		val |= *vcpu_reg(vcpu, p->Rt) << 32;
+		*dbg_reg = val;
+
+		vcpu->arch.debug_flags |= KVM_ARM64_DEBUG_DIRTY;
+	} else {
+		*vcpu_reg(vcpu, p->Rt) = *dbg_reg >> 32;
+	}
+
+	return true;
+}
+
+#define DBG_BCR_BVR_WCR_WVR(n)						\
+	/* DBGBVRn */							\
+	{ Op1( 0), CRn( 0), CRm((n)), Op2( 4), trap_bvr, NULL, n }, 	\
+	/* DBGBCRn */							\
+	{ Op1( 0), CRn( 0), CRm((n)), Op2( 5), trap_bcr, NULL, n },	\
+	/* DBGWVRn */							\
+	{ Op1( 0), CRn( 0), CRm((n)), Op2( 6), trap_wvr, NULL, n },	\
+	/* DBGWCRn */							\
+	{ Op1( 0), CRn( 0), CRm((n)), Op2( 7), trap_wcr, NULL, n }
+
+#define DBGBXVR(n)							\
+	{ Op1( 0), CRn( 1), CRm((n)), Op2( 1), trap_xvr, NULL, n }
 
 /*
  * Trapped cp14 registers. We generally ignore most of the external
  * debug, on the principle that they don't really make sense to a
- * guest. Revisit this one day, whould this principle change.
+ * guest. Revisit this one day, would this principle change.
  */
 static const struct sys_reg_desc cp14_regs[] = {
 	/* DBGIDR */
@@ -1303,6 +1527,9 @@ int kvm_arm_sys_reg_get_reg(struct kvm_vcpu *vcpu, const struct kvm_one_reg *reg
 	if (!r)
 		return get_invariant_sys_reg(reg->id, uaddr);
 
+	if (r->get_user)
+		return (r->get_user)(vcpu, r, reg, uaddr);
+
 	return reg_to_user(uaddr, &vcpu_sys_reg(vcpu, r->reg), reg->id);
 }
 
@@ -1321,6 +1548,9 @@ int kvm_arm_sys_reg_set_reg(struct kvm_vcpu *vcpu, const struct kvm_one_reg *reg
 	if (!r)
 		return set_invariant_sys_reg(reg->id, uaddr);
 
+	if (r->set_user)
+		return (r->set_user)(vcpu, r, reg, uaddr);
+
 	return reg_from_user(&vcpu_sys_reg(vcpu, r->reg), uaddr, reg->id);
 }
 
diff --git a/arch/arm64/kvm/sys_regs.h b/arch/arm64/kvm/sys_regs.h
index d411e25..eaa324e 100644
--- a/arch/arm64/kvm/sys_regs.h
+++ b/arch/arm64/kvm/sys_regs.h
@@ -55,6 +55,12 @@ struct sys_reg_desc {
 
 	/* Value (usually reset value) */
 	u64 val;
+
+	/* Custom get/set_user functions, fallback to generic if NULL */
+	int (*get_user)(struct kvm_vcpu *vcpu, const struct sys_reg_desc *rd,
+			const struct kvm_one_reg *reg, void __user *uaddr);
+	int (*set_user)(struct kvm_vcpu *vcpu, const struct sys_reg_desc *rd,
+			const struct kvm_one_reg *reg, void __user *uaddr);
 };
 
 static inline void print_sys_reg_instr(const struct sys_reg_params *p)
-- 
2.1.4



From marc.zyngier at arm.com  Thu Aug 20 09:28:59 2015
From: marc.zyngier at arm.com (Marc Zyngier)
Date: Thu, 20 Aug 2015 17:28:59 +0100
Subject: [PATCH 21/25] KVM: arm/arm64: vgic: Add vgic_{get,
 set}_phys_irq_active
In-Reply-To: <1440088143-4722-1-git-send-email-marc.zyngier@arm.com>
References: <1440088143-4722-1-git-send-email-marc.zyngier@arm.com>
Message-ID: <1440088143-4722-22-git-send-email-marc.zyngier@arm.com>

In order to control the active state of an interrupt, introduce
a pair of accessors allowing the state to be set/queried.

This only affects the logical state, and the HW state will only be
applied at world-switch time.

Acked-by: Christoffer Dall <christoffer.dall at linaro.org>
Signed-off-by: Marc Zyngier <marc.zyngier at arm.com>
---
 include/kvm/arm_vgic.h |  2 ++
 virt/kvm/arm/vgic.c    | 24 ++++++++++++++++++++++++
 2 files changed, 26 insertions(+)

diff --git a/include/kvm/arm_vgic.h b/include/kvm/arm_vgic.h
index c0e6354..e789e47 100644
--- a/include/kvm/arm_vgic.h
+++ b/include/kvm/arm_vgic.h
@@ -356,6 +356,8 @@ int kvm_vgic_vcpu_active_irq(struct kvm_vcpu *vcpu);
 struct irq_phys_map *kvm_vgic_map_phys_irq(struct kvm_vcpu *vcpu,
 					   int virt_irq, int irq);
 int kvm_vgic_unmap_phys_irq(struct kvm_vcpu *vcpu, struct irq_phys_map *map);
+bool kvm_vgic_get_phys_irq_active(struct irq_phys_map *map);
+void kvm_vgic_set_phys_irq_active(struct irq_phys_map *map, bool active);
 
 #define irqchip_in_kernel(k)	(!!((k)->arch.vgic.in_kernel))
 #define vgic_initialized(k)	(!!((k)->arch.vgic.nr_cpus))
diff --git a/virt/kvm/arm/vgic.c b/virt/kvm/arm/vgic.c
index 9d009d2..b553a8f 100644
--- a/virt/kvm/arm/vgic.c
+++ b/virt/kvm/arm/vgic.c
@@ -1802,6 +1802,30 @@ static void vgic_free_phys_irq_map_rcu(struct rcu_head *rcu)
 }
 
 /**
+ * kvm_vgic_get_phys_irq_active - Return the active state of a mapped IRQ
+ *
+ * Return the logical active state of a mapped interrupt. This doesn't
+ * necessarily reflects the current HW state.
+ */
+bool kvm_vgic_get_phys_irq_active(struct irq_phys_map *map)
+{
+	BUG_ON(!map);
+	return map->active;
+}
+
+/**
+ * kvm_vgic_set_phys_irq_active - Set the active state of a mapped IRQ
+ *
+ * Set the logical active state of a mapped interrupt. This doesn't
+ * immediately affects the HW state.
+ */
+void kvm_vgic_set_phys_irq_active(struct irq_phys_map *map, bool active)
+{
+	BUG_ON(!map);
+	map->active = active;
+}
+
+/**
  * kvm_vgic_unmap_phys_irq - Remove a virtual to physical IRQ mapping
  * @vcpu: The VCPU pointer
  * @map: The pointer to a mapping obtained through kvm_vgic_map_phys_irq
-- 
2.1.4



From marc.zyngier at arm.com  Thu Aug 20 09:28:58 2015
From: marc.zyngier at arm.com (Marc Zyngier)
Date: Thu, 20 Aug 2015 17:28:58 +0100
Subject: [PATCH 20/25] KVM: arm/arm64: vgic: Allow HW interrupts to be queued
 to a guest
In-Reply-To: <1440088143-4722-1-git-send-email-marc.zyngier@arm.com>
References: <1440088143-4722-1-git-send-email-marc.zyngier@arm.com>
Message-ID: <1440088143-4722-21-git-send-email-marc.zyngier@arm.com>

To allow a HW interrupt to be injected into a guest, we lookup the
guest virtual interrupt in the irq_phys_map list, and if we have
a match, encode both interrupts in the LR.

We also mark the interrupt as "active" at the host distributor level.

On guest EOI on the virtual interrupt, the host interrupt will be
deactivated.

Reviewed-by: Christoffer Dall <christoffer.dall at linaro.org>
Signed-off-by: Marc Zyngier <marc.zyngier at arm.com>
---
 virt/kvm/arm/vgic.c | 89 +++++++++++++++++++++++++++++++++++++++++++++++++++--
 1 file changed, 86 insertions(+), 3 deletions(-)

diff --git a/virt/kvm/arm/vgic.c b/virt/kvm/arm/vgic.c
index 51c9900..9d009d2 100644
--- a/virt/kvm/arm/vgic.c
+++ b/virt/kvm/arm/vgic.c
@@ -1140,6 +1140,39 @@ static void vgic_queue_irq_to_lr(struct kvm_vcpu *vcpu, int irq,
 	if (!vgic_irq_is_edge(vcpu, irq))
 		vlr.state |= LR_EOI_INT;
 
+	if (vlr.irq >= VGIC_NR_SGIS) {
+		struct irq_phys_map *map;
+		map = vgic_irq_map_search(vcpu, irq);
+
+		/*
+		 * If we have a mapping, and the virtual interrupt is
+		 * being injected, then we must set the state to
+		 * active in the physical world. Otherwise the
+		 * physical interrupt will fire and the guest will
+		 * exit before processing the virtual interrupt.
+		 */
+		if (map) {
+			int ret;
+
+			BUG_ON(!map->active);
+			vlr.hwirq = map->phys_irq;
+			vlr.state |= LR_HW;
+			vlr.state &= ~LR_EOI_INT;
+
+			ret = irq_set_irqchip_state(map->irq,
+						    IRQCHIP_STATE_ACTIVE,
+						    true);
+			WARN_ON(ret);
+
+			/*
+			 * Make sure we're not going to sample this
+			 * again, as a HW-backed interrupt cannot be
+			 * in the PENDING_ACTIVE stage.
+			 */
+			vgic_irq_set_queued(vcpu, irq);
+		}
+	}
+
 	vgic_set_lr(vcpu, lr_nr, vlr);
 	vgic_sync_lr_elrsr(vcpu, lr_nr, vlr);
 }
@@ -1364,6 +1397,39 @@ static bool vgic_process_maintenance(struct kvm_vcpu *vcpu)
 	return level_pending;
 }
 
+/*
+ * Save the physical active state, and reset it to inactive.
+ *
+ * Return 1 if HW interrupt went from active to inactive, and 0 otherwise.
+ */
+static int vgic_sync_hwirq(struct kvm_vcpu *vcpu, struct vgic_lr vlr)
+{
+	struct irq_phys_map *map;
+	int ret;
+
+	if (!(vlr.state & LR_HW))
+		return 0;
+
+	map = vgic_irq_map_search(vcpu, vlr.irq);
+	BUG_ON(!map || !map->active);
+
+	ret = irq_get_irqchip_state(map->irq,
+				    IRQCHIP_STATE_ACTIVE,
+				    &map->active);
+
+	WARN_ON(ret);
+
+	if (map->active) {
+		ret = irq_set_irqchip_state(map->irq,
+					    IRQCHIP_STATE_ACTIVE,
+					    false);
+		WARN_ON(ret);
+		return 0;
+	}
+
+	return 1;
+}
+
 /* Sync back the VGIC state after a guest run */
 static void __kvm_vgic_sync_hwstate(struct kvm_vcpu *vcpu)
 {
@@ -1378,14 +1444,31 @@ static void __kvm_vgic_sync_hwstate(struct kvm_vcpu *vcpu)
 	elrsr = vgic_get_elrsr(vcpu);
 	elrsr_ptr = u64_to_bitmask(&elrsr);
 
-	/* Clear mappings for empty LRs */
-	for_each_set_bit(lr, elrsr_ptr, vgic->nr_lr) {
+	/* Deal with HW interrupts, and clear mappings for empty LRs */
+	for (lr = 0; lr < vgic->nr_lr; lr++) {
 		struct vgic_lr vlr;
 
-		if (!test_and_clear_bit(lr, vgic_cpu->lr_used))
+		if (!test_bit(lr, vgic_cpu->lr_used))
 			continue;
 
 		vlr = vgic_get_lr(vcpu, lr);
+		if (vgic_sync_hwirq(vcpu, vlr)) {
+			/*
+			 * So this is a HW interrupt that the guest
+			 * EOI-ed. Clean the LR state and allow the
+			 * interrupt to be sampled again.
+			 */
+			vlr.state = 0;
+			vlr.hwirq = 0;
+			vgic_set_lr(vcpu, lr, vlr);
+			vgic_irq_clear_queued(vcpu, vlr.irq);
+			set_bit(lr, elrsr_ptr);
+		}
+
+		if (!test_bit(lr, elrsr_ptr))
+			continue;
+
+		clear_bit(lr, vgic_cpu->lr_used);
 
 		BUG_ON(vlr.irq >= dist->nr_irqs);
 		vgic_cpu->vgic_irq_lr_map[vlr.irq] = LR_EMPTY;
-- 
2.1.4



From marc.zyngier at arm.com  Thu Aug 20 09:28:55 2015
From: marc.zyngier at arm.com (Marc Zyngier)
Date: Thu, 20 Aug 2015 17:28:55 +0100
Subject: [PATCH 17/25] KVM: arm/arm64: vgic: Allow HW irq to be encoded in LR
In-Reply-To: <1440088143-4722-1-git-send-email-marc.zyngier@arm.com>
References: <1440088143-4722-1-git-send-email-marc.zyngier@arm.com>
Message-ID: <1440088143-4722-18-git-send-email-marc.zyngier@arm.com>

Now that struct vgic_lr supports the LR_HW bit and carries a hwirq
field, we can encode that information into the list registers.

This patch provides implementations for both GICv2 and GICv3.

Reviewed-by: Christoffer Dall <christoffer.dall at linaro.org>
Signed-off-by: Marc Zyngier <marc.zyngier at arm.com>
---
 include/linux/irqchip/arm-gic-v3.h |  3 +++
 include/linux/irqchip/arm-gic.h    |  3 ++-
 virt/kvm/arm/vgic-v2.c             | 16 +++++++++++++++-
 virt/kvm/arm/vgic-v3.c             | 21 ++++++++++++++++++---
 4 files changed, 38 insertions(+), 5 deletions(-)

diff --git a/include/linux/irqchip/arm-gic-v3.h b/include/linux/irqchip/arm-gic-v3.h
index ffbc034..cf637d6 100644
--- a/include/linux/irqchip/arm-gic-v3.h
+++ b/include/linux/irqchip/arm-gic-v3.h
@@ -268,9 +268,12 @@
 
 #define ICH_LR_EOI			(1UL << 41)
 #define ICH_LR_GROUP			(1UL << 60)
+#define ICH_LR_HW			(1UL << 61)
 #define ICH_LR_STATE			(3UL << 62)
 #define ICH_LR_PENDING_BIT		(1UL << 62)
 #define ICH_LR_ACTIVE_BIT		(1UL << 63)
+#define ICH_LR_PHYS_ID_SHIFT		32
+#define ICH_LR_PHYS_ID_MASK		(0x3ffUL << ICH_LR_PHYS_ID_SHIFT)
 
 #define ICH_MISR_EOI			(1 << 0)
 #define ICH_MISR_U			(1 << 1)
diff --git a/include/linux/irqchip/arm-gic.h b/include/linux/irqchip/arm-gic.h
index 9de976b..ca88dad 100644
--- a/include/linux/irqchip/arm-gic.h
+++ b/include/linux/irqchip/arm-gic.h
@@ -71,11 +71,12 @@
 
 #define GICH_LR_VIRTUALID		(0x3ff << 0)
 #define GICH_LR_PHYSID_CPUID_SHIFT	(10)
-#define GICH_LR_PHYSID_CPUID		(7 << GICH_LR_PHYSID_CPUID_SHIFT)
+#define GICH_LR_PHYSID_CPUID		(0x3ff << GICH_LR_PHYSID_CPUID_SHIFT)
 #define GICH_LR_STATE			(3 << 28)
 #define GICH_LR_PENDING_BIT		(1 << 28)
 #define GICH_LR_ACTIVE_BIT		(1 << 29)
 #define GICH_LR_EOI			(1 << 19)
+#define GICH_LR_HW			(1 << 31)
 
 #define GICH_VMCR_CTRL_SHIFT		0
 #define GICH_VMCR_CTRL_MASK		(0x21f << GICH_VMCR_CTRL_SHIFT)
diff --git a/virt/kvm/arm/vgic-v2.c b/virt/kvm/arm/vgic-v2.c
index f9b9c7c..8d7b04d 100644
--- a/virt/kvm/arm/vgic-v2.c
+++ b/virt/kvm/arm/vgic-v2.c
@@ -48,6 +48,10 @@ static struct vgic_lr vgic_v2_get_lr(const struct kvm_vcpu *vcpu, int lr)
 		lr_desc.state |= LR_STATE_ACTIVE;
 	if (val & GICH_LR_EOI)
 		lr_desc.state |= LR_EOI_INT;
+	if (val & GICH_LR_HW) {
+		lr_desc.state |= LR_HW;
+		lr_desc.hwirq = (val & GICH_LR_PHYSID_CPUID) >> GICH_LR_PHYSID_CPUID_SHIFT;
+	}
 
 	return lr_desc;
 }
@@ -55,7 +59,9 @@ static struct vgic_lr vgic_v2_get_lr(const struct kvm_vcpu *vcpu, int lr)
 static void vgic_v2_set_lr(struct kvm_vcpu *vcpu, int lr,
 			   struct vgic_lr lr_desc)
 {
-	u32 lr_val = (lr_desc.source << GICH_LR_PHYSID_CPUID_SHIFT) | lr_desc.irq;
+	u32 lr_val;
+
+	lr_val = lr_desc.irq;
 
 	if (lr_desc.state & LR_STATE_PENDING)
 		lr_val |= GICH_LR_PENDING_BIT;
@@ -64,6 +70,14 @@ static void vgic_v2_set_lr(struct kvm_vcpu *vcpu, int lr,
 	if (lr_desc.state & LR_EOI_INT)
 		lr_val |= GICH_LR_EOI;
 
+	if (lr_desc.state & LR_HW) {
+		lr_val |= GICH_LR_HW;
+		lr_val |= (u32)lr_desc.hwirq << GICH_LR_PHYSID_CPUID_SHIFT;
+	}
+
+	if (lr_desc.irq < VGIC_NR_SGIS)
+		lr_val |= (lr_desc.source << GICH_LR_PHYSID_CPUID_SHIFT);
+
 	vcpu->arch.vgic_cpu.vgic_v2.vgic_lr[lr] = lr_val;
 }
 
diff --git a/virt/kvm/arm/vgic-v3.c b/virt/kvm/arm/vgic-v3.c
index dff0602..afbf925 100644
--- a/virt/kvm/arm/vgic-v3.c
+++ b/virt/kvm/arm/vgic-v3.c
@@ -67,6 +67,10 @@ static struct vgic_lr vgic_v3_get_lr(const struct kvm_vcpu *vcpu, int lr)
 		lr_desc.state |= LR_STATE_ACTIVE;
 	if (val & ICH_LR_EOI)
 		lr_desc.state |= LR_EOI_INT;
+	if (val & ICH_LR_HW) {
+		lr_desc.state |= LR_HW;
+		lr_desc.hwirq = (val >> ICH_LR_PHYS_ID_SHIFT) & GENMASK(9, 0);
+	}
 
 	return lr_desc;
 }
@@ -84,10 +88,17 @@ static void vgic_v3_set_lr(struct kvm_vcpu *vcpu, int lr,
 	 * Eventually we want to make this configurable, so we may revisit
 	 * this in the future.
 	 */
-	if (vcpu->kvm->arch.vgic.vgic_model == KVM_DEV_TYPE_ARM_VGIC_V3)
+	switch (vcpu->kvm->arch.vgic.vgic_model) {
+	case KVM_DEV_TYPE_ARM_VGIC_V3:
 		lr_val |= ICH_LR_GROUP;
-	else
-		lr_val |= (u32)lr_desc.source << GICH_LR_PHYSID_CPUID_SHIFT;
+		break;
+	case  KVM_DEV_TYPE_ARM_VGIC_V2:
+		if (lr_desc.irq < VGIC_NR_SGIS)
+			lr_val |= (u32)lr_desc.source << GICH_LR_PHYSID_CPUID_SHIFT;
+		break;
+	default:
+		BUG();
+	}
 
 	if (lr_desc.state & LR_STATE_PENDING)
 		lr_val |= ICH_LR_PENDING_BIT;
@@ -95,6 +106,10 @@ static void vgic_v3_set_lr(struct kvm_vcpu *vcpu, int lr,
 		lr_val |= ICH_LR_ACTIVE_BIT;
 	if (lr_desc.state & LR_EOI_INT)
 		lr_val |= ICH_LR_EOI;
+	if (lr_desc.state & LR_HW) {
+		lr_val |= ICH_LR_HW;
+		lr_val |= ((u64)lr_desc.hwirq) << ICH_LR_PHYS_ID_SHIFT;
+	}
 
 	vcpu->arch.vgic_cpu.vgic_v3.vgic_lr[LR_INDEX(lr)] = lr_val;
 }
-- 
2.1.4



From marc.zyngier at arm.com  Thu Aug 20 09:29:03 2015
From: marc.zyngier at arm.com (Marc Zyngier)
Date: Thu, 20 Aug 2015 17:29:03 +0100
Subject: [PATCH 25/25] arm: KVM: keep arm vfp/simd exit handling consistent
 with arm64
In-Reply-To: <1440088143-4722-1-git-send-email-marc.zyngier@arm.com>
References: <1440088143-4722-1-git-send-email-marc.zyngier@arm.com>
Message-ID: <1440088143-4722-26-git-send-email-marc.zyngier@arm.com>

From: Mario Smarduch <m.smarduch at samsung.com>

After enhancing arm64 FP/SIMD exit handling, ARMv7 VFP exit branch is moved
to guest trap handling. This allows us to keep exit handling flow between both
architectures consistent.

Signed-off-by: Mario Smarduch <m.smarduch at samsung.com>
Signed-off-by: Marc Zyngier <marc.zyngier at arm.com>
---
 arch/arm/kvm/interrupts.S | 14 ++++++++------
 1 file changed, 8 insertions(+), 6 deletions(-)

diff --git a/arch/arm/kvm/interrupts.S b/arch/arm/kvm/interrupts.S
index 568494d..900ef6d 100644
--- a/arch/arm/kvm/interrupts.S
+++ b/arch/arm/kvm/interrupts.S
@@ -361,10 +361,6 @@ hyp_hvc:
 	@ Check syndrome register
 	mrc	p15, 4, r1, c5, c2, 0	@ HSR
 	lsr	r0, r1, #HSR_EC_SHIFT
-#ifdef CONFIG_VFPv3
-	cmp	r0, #HSR_EC_CP_0_13
-	beq	switch_to_guest_vfp
-#endif
 	cmp	r0, #HSR_EC_HVC
 	bne	guest_trap		@ Not HVC instr.
 
@@ -378,7 +374,10 @@ hyp_hvc:
 	cmp     r2, #0
 	bne	guest_trap		@ Guest called HVC
 
-host_switch_to_hyp:
+	/*
+	 * Getting here means host called HVC, we shift parameters and branch
+	 * to Hyp function.
+	 */
 	pop	{r0, r1, r2}
 
 	/* Check for __hyp_get_vectors */
@@ -409,6 +408,10 @@ guest_trap:
 
 	@ Check if we need the fault information
 	lsr	r1, r1, #HSR_EC_SHIFT
+#ifdef CONFIG_VFPv3
+	cmp	r1, #HSR_EC_CP_0_13
+	beq	switch_to_guest_vfp
+#endif
 	cmp	r1, #HSR_EC_IABT
 	mrceq	p15, 4, r2, c6, c0, 2	@ HIFAR
 	beq	2f
@@ -477,7 +480,6 @@ guest_trap:
  */
 #ifdef CONFIG_VFPv3
 switch_to_guest_vfp:
-	load_vcpu			@ Load VCPU pointer to r0
 	push	{r3-r7}
 
 	@ NEON/VFP used.  Turn on VFP access.
-- 
2.1.4



From marc.zyngier at arm.com  Thu Aug 20 09:29:02 2015
From: marc.zyngier at arm.com (Marc Zyngier)
Date: Thu, 20 Aug 2015 17:29:02 +0100
Subject: [PATCH 24/25] arm64: KVM: Optimize arm64 skip 30-50% vfp/simd
 save/restore on exits
In-Reply-To: <1440088143-4722-1-git-send-email-marc.zyngier@arm.com>
References: <1440088143-4722-1-git-send-email-marc.zyngier@arm.com>
Message-ID: <1440088143-4722-25-git-send-email-marc.zyngier@arm.com>

From: Mario Smarduch <m.smarduch at samsung.com>

This patch only saves and restores FP/SIMD registers on Guest access. To do
this cptr_el2 FP/SIMD trap is set on Guest entry and later checked on exit.
lmbench, hackbench show significant improvements, for 30-50% exits FP/SIMD
context is not saved/restored

[chazy/maz: fixed save/restore logic for 32bit guests]

Signed-off-by: Mario Smarduch <m.smarduch at samsung.com>
Signed-off-by: Christoffer Dall <christoffer.dall at linaro.org>
Signed-off-by: Marc Zyngier <marc.zyngier at arm.com>
---
 arch/arm64/include/asm/kvm_arm.h |  5 ++-
 arch/arm64/kvm/hyp.S             | 73 +++++++++++++++++++++++++++++++++++-----
 2 files changed, 68 insertions(+), 10 deletions(-)

diff --git a/arch/arm64/include/asm/kvm_arm.h b/arch/arm64/include/asm/kvm_arm.h
index ac6fafb..7605e09 100644
--- a/arch/arm64/include/asm/kvm_arm.h
+++ b/arch/arm64/include/asm/kvm_arm.h
@@ -171,10 +171,13 @@
 #define HSTR_EL2_TTEE	(1 << 16)
 #define HSTR_EL2_T(x)	(1 << x)
 
+/* Hyp Coproccessor Trap Register Shifts */
+#define CPTR_EL2_TFP_SHIFT 10
+
 /* Hyp Coprocessor Trap Register */
 #define CPTR_EL2_TCPAC	(1 << 31)
 #define CPTR_EL2_TTA	(1 << 20)
-#define CPTR_EL2_TFP	(1 << 10)
+#define CPTR_EL2_TFP	(1 << CPTR_EL2_TFP_SHIFT)
 
 /* Hyp Debug Configuration Register bits */
 #define MDCR_EL2_TDRA		(1 << 11)
diff --git a/arch/arm64/kvm/hyp.S b/arch/arm64/kvm/hyp.S
index d93c0a2..8188f6a 100644
--- a/arch/arm64/kvm/hyp.S
+++ b/arch/arm64/kvm/hyp.S
@@ -385,6 +385,14 @@
 	tbz	\tmp, #KVM_ARM64_DEBUG_DIRTY_SHIFT, \target
 .endm
 
+/*
+ * Branch to target if CPTR_EL2.TFP bit is set (VFP/SIMD trapping enabled)
+ */
+.macro skip_fpsimd_state tmp, target
+	mrs	\tmp, cptr_el2
+	tbnz	\tmp, #CPTR_EL2_TFP_SHIFT, \target
+.endm
+
 .macro compute_debug_state target
 	// Compute debug state: If any of KDE, MDE or KVM_ARM64_DEBUG_DIRTY
 	// is set, we do a full save/restore cycle and disable trapping.
@@ -423,10 +431,12 @@
 	add	x3, x2, #CPU_SYSREG_OFFSET(DACR32_EL2)
 	mrs	x4, dacr32_el2
 	mrs	x5, ifsr32_el2
-	mrs	x6, fpexc32_el2
 	stp	x4, x5, [x3]
-	str	x6, [x3, #16]
 
+	skip_fpsimd_state x8, 3f
+	mrs	x6, fpexc32_el2
+	str	x6, [x3, #16]
+3:
 	skip_debug_state x8, 2f
 	mrs	x7, dbgvcr32_el2
 	str	x7, [x3, #24]
@@ -453,10 +463,8 @@
 
 	add	x3, x2, #CPU_SYSREG_OFFSET(DACR32_EL2)
 	ldp	x4, x5, [x3]
-	ldr	x6, [x3, #16]
 	msr	dacr32_el2, x4
 	msr	ifsr32_el2, x5
-	msr	fpexc32_el2, x6
 
 	skip_debug_state x8, 2f
 	ldr	x7, [x3, #24]
@@ -473,8 +481,22 @@
 
 .macro activate_traps
 	ldr     x2, [x0, #VCPU_HCR_EL2]
+
+	/*
+	 * We are about to set CPTR_EL2.TFP to trap all floating point
+	 * register accesses to EL2, however, the ARM ARM clearly states that
+	 * traps are only taken to EL2 if the operation would not otherwise
+	 * trap to EL1.  Therefore, always make sure that for 32-bit guests,
+	 * we set FPEXC.EN to prevent traps to EL1, when setting the TFP bit.
+	 */
+	tbnz	x2, #HCR_RW_SHIFT, 99f // open code skip_32bit_state
+	mov	x3, #(1 << 30)
+	msr	fpexc32_el2, x3
+	isb
+99:
 	msr     hcr_el2, x2
 	mov	x2, #CPTR_EL2_TTA
+	orr     x2, x2, #CPTR_EL2_TFP
 	msr	cptr_el2, x2
 
 	mov	x2, #(1 << 15)	// Trap CP15 Cr=15
@@ -488,7 +510,6 @@
 .macro deactivate_traps
 	mov	x2, #HCR_RW
 	msr	hcr_el2, x2
-	msr	cptr_el2, xzr
 	msr	hstr_el2, xzr
 
 	mrs	x2, mdcr_el2
@@ -653,12 +674,41 @@ __restore_debug:
 	ret
 
 __save_fpsimd:
+	skip_fpsimd_state x3, 1f
 	save_fpsimd
-	ret
+1:	ret
 
 __restore_fpsimd:
+	skip_fpsimd_state x3, 1f
 	restore_fpsimd
-	ret
+1:	ret
+
+switch_to_guest_fpsimd:
+	push	x4, lr
+
+	mrs	x2, cptr_el2
+	bic	x2, x2, #CPTR_EL2_TFP
+	msr	cptr_el2, x2
+	isb
+
+	mrs	x0, tpidr_el2
+
+	ldr	x2, [x0, #VCPU_HOST_CONTEXT]
+	kern_hyp_va x2
+	bl __save_fpsimd
+
+	add	x2, x0, #VCPU_CONTEXT
+	bl __restore_fpsimd
+
+	skip_32bit_state x3, 1f
+	ldr	x4, [x2, #CPU_SYSREG_OFFSET(FPEXC32_EL2)]
+	msr	fpexc32_el2, x4
+1:
+	pop	x4, lr
+	pop	x2, x3
+	pop	x0, x1
+
+	eret
 
 /*
  * u64 __kvm_vcpu_run(struct kvm_vcpu *vcpu);
@@ -680,7 +730,6 @@ ENTRY(__kvm_vcpu_run)
 	kern_hyp_va x2
 
 	save_host_regs
-	bl __save_fpsimd
 	bl __save_sysregs
 
 	compute_debug_state 1f
@@ -697,7 +746,6 @@ ENTRY(__kvm_vcpu_run)
 	add	x2, x0, #VCPU_CONTEXT
 
 	bl __restore_sysregs
-	bl __restore_fpsimd
 
 	skip_debug_state x3, 1f
 	ldr	x3, [x0, #VCPU_DEBUG_PTR]
@@ -740,6 +788,8 @@ __kvm_vcpu_return:
 
 	bl __restore_sysregs
 	bl __restore_fpsimd
+	/* Clear FPSIMD and Trace trapping */
+	msr     cptr_el2, xzr
 
 	skip_debug_state x3, 1f
 	// Clear the dirty flag for the next run, as all the state has
@@ -949,6 +999,11 @@ el1_trap:
 	 * x1: ESR
 	 * x2: ESR_EC
 	 */
+
+	/* Guest accessed VFP/SIMD registers, save host, restore Guest */
+	cmp	x2, #ESR_ELx_EC_FP_ASIMD
+	b.eq	switch_to_guest_fpsimd
+
 	cmp	x2, #ESR_ELx_EC_DABT_LOW
 	mov	x0, #ESR_ELx_EC_IABT_LOW
 	ccmp	x2, x0, #4, ne
-- 
2.1.4



From marc.zyngier at arm.com  Thu Aug 20 09:28:50 2015
From: marc.zyngier at arm.com (Marc Zyngier)
Date: Thu, 20 Aug 2015 17:28:50 +0100
Subject: [PATCH 12/25] arm64/kvm: Add generic v8 KVM target
In-Reply-To: <1440088143-4722-1-git-send-email-marc.zyngier@arm.com>
References: <1440088143-4722-1-git-send-email-marc.zyngier@arm.com>
Message-ID: <1440088143-4722-13-git-send-email-marc.zyngier@arm.com>

From: "Suzuki K. Poulose" <suzuki.poulose at arm.com>

This patch adds a generic ARM v8 KVM target cpu type for use
by the new CPUs which eventualy ends up using the common sys_reg
table. For backward compatibility the existing targets have been
preserved. Any new target CPU that can be covered by generic v8
sys_reg tables should make use of the new generic target.

Signed-off-by: Suzuki K. Poulose <suzuki.poulose at arm.com>
Acked-by: Marc Zyngier <Marc.Zyngier at arm.com>
Signed-off-by: Marc Zyngier <marc.zyngier at arm.com>
---
 arch/arm64/include/uapi/asm/kvm.h    | 10 ++++++++--
 arch/arm64/kvm/guest.c               |  3 ++-
 arch/arm64/kvm/sys_regs_generic_v8.c |  2 ++
 3 files changed, 12 insertions(+), 3 deletions(-)

diff --git a/arch/arm64/include/uapi/asm/kvm.h b/arch/arm64/include/uapi/asm/kvm.h
index d82f3f3..0cd7b59 100644
--- a/arch/arm64/include/uapi/asm/kvm.h
+++ b/arch/arm64/include/uapi/asm/kvm.h
@@ -53,14 +53,20 @@ struct kvm_regs {
 	struct user_fpsimd_state fp_regs;
 };
 
-/* Supported Processor Types */
+/*
+ * Supported CPU Targets - Adding a new target type is not recommended,
+ * unless there are some special registers not supported by the
+ * genericv8 syreg table.
+ */
 #define KVM_ARM_TARGET_AEM_V8		0
 #define KVM_ARM_TARGET_FOUNDATION_V8	1
 #define KVM_ARM_TARGET_CORTEX_A57	2
 #define KVM_ARM_TARGET_XGENE_POTENZA	3
 #define KVM_ARM_TARGET_CORTEX_A53	4
+/* Generic ARM v8 target */
+#define KVM_ARM_TARGET_GENERIC_V8	5
 
-#define KVM_ARM_NUM_TARGETS		5
+#define KVM_ARM_NUM_TARGETS		6
 
 /* KVM_ARM_SET_DEVICE_ADDR ioctl id encoding */
 #define KVM_ARM_DEVICE_TYPE_SHIFT	0
diff --git a/arch/arm64/kvm/guest.c b/arch/arm64/kvm/guest.c
index 48868d8..d250160 100644
--- a/arch/arm64/kvm/guest.c
+++ b/arch/arm64/kvm/guest.c
@@ -295,7 +295,8 @@ int __attribute_const__ kvm_target_cpu(void)
 		break;
 	};
 
-	return -EINVAL;
+	/* Return a default generic target */
+	return KVM_ARM_TARGET_GENERIC_V8;
 }
 
 int kvm_vcpu_preferred_target(struct kvm_vcpu_init *init)
diff --git a/arch/arm64/kvm/sys_regs_generic_v8.c b/arch/arm64/kvm/sys_regs_generic_v8.c
index 475fd29..1e45768 100644
--- a/arch/arm64/kvm/sys_regs_generic_v8.c
+++ b/arch/arm64/kvm/sys_regs_generic_v8.c
@@ -94,6 +94,8 @@ static int __init sys_reg_genericv8_init(void)
 					  &genericv8_target_table);
 	kvm_register_target_sys_reg_table(KVM_ARM_TARGET_XGENE_POTENZA,
 					  &genericv8_target_table);
+	kvm_register_target_sys_reg_table(KVM_ARM_TARGET_GENERIC_V8,
+					  &genericv8_target_table);
 
 	return 0;
 }
-- 
2.1.4



From marc.zyngier at arm.com  Thu Aug 20 09:28:45 2015
From: marc.zyngier at arm.com (Marc Zyngier)
Date: Thu, 20 Aug 2015 17:28:45 +0100
Subject: [PATCH 07/25] KVM: arm64: re-factor hyp.S debug register code
In-Reply-To: <1440088143-4722-1-git-send-email-marc.zyngier@arm.com>
References: <1440088143-4722-1-git-send-email-marc.zyngier@arm.com>
Message-ID: <1440088143-4722-8-git-send-email-marc.zyngier@arm.com>

From: Alex Benn?e <alex.bennee at linaro.org>

This is a pre-cursor to sharing the code with the guest debug support.
This replaces the big macro that fishes data out of a fixed location
with a more general helper macro to restore a set of debug registers. It
uses macro substitution so it can be re-used for debug control and value
registers. It does however rely on the debug registers being 64 bit
aligned (as they happen to be in the hyp ABI).

Signed-off-by: Alex Benn?e <alex.bennee at linaro.org>
Reviewed-by: Christoffer Dall <christoffer.dall at linaro.org>
Signed-off-by: Marc Zyngier <marc.zyngier at arm.com>
---
 arch/arm64/kvm/hyp.S | 517 ++++++++++++++-------------------------------------
 1 file changed, 138 insertions(+), 379 deletions(-)

diff --git a/arch/arm64/kvm/hyp.S b/arch/arm64/kvm/hyp.S
index b3176e6..8264f5b 100644
--- a/arch/arm64/kvm/hyp.S
+++ b/arch/arm64/kvm/hyp.S
@@ -230,199 +230,52 @@
 	stp	x24, x25, [x3, #160]
 .endm
 
-.macro save_debug
-	// x2: base address for cpu context
-	// x3: tmp register
-
-	mrs	x26, id_aa64dfr0_el1
-	ubfx	x24, x26, #12, #4	// Extract BRPs
-	ubfx	x25, x26, #20, #4	// Extract WRPs
-	mov	w26, #15
-	sub	w24, w26, w24		// How many BPs to skip
-	sub	w25, w26, w25		// How many WPs to skip
-
-	add	x3, x2, #CPU_SYSREG_OFFSET(DBGBCR0_EL1)
-
-	adr	x26, 1f
-	add	x26, x26, x24, lsl #2
-	br	x26
-1:
-	mrs	x20, dbgbcr15_el1
-	mrs	x19, dbgbcr14_el1
-	mrs	x18, dbgbcr13_el1
-	mrs	x17, dbgbcr12_el1
-	mrs	x16, dbgbcr11_el1
-	mrs	x15, dbgbcr10_el1
-	mrs	x14, dbgbcr9_el1
-	mrs	x13, dbgbcr8_el1
-	mrs	x12, dbgbcr7_el1
-	mrs	x11, dbgbcr6_el1
-	mrs	x10, dbgbcr5_el1
-	mrs	x9, dbgbcr4_el1
-	mrs	x8, dbgbcr3_el1
-	mrs	x7, dbgbcr2_el1
-	mrs	x6, dbgbcr1_el1
-	mrs	x5, dbgbcr0_el1
-
-	adr	x26, 1f
-	add	x26, x26, x24, lsl #2
-	br	x26
-
-1:
-	str	x20, [x3, #(15 * 8)]
-	str	x19, [x3, #(14 * 8)]
-	str	x18, [x3, #(13 * 8)]
-	str	x17, [x3, #(12 * 8)]
-	str	x16, [x3, #(11 * 8)]
-	str	x15, [x3, #(10 * 8)]
-	str	x14, [x3, #(9 * 8)]
-	str	x13, [x3, #(8 * 8)]
-	str	x12, [x3, #(7 * 8)]
-	str	x11, [x3, #(6 * 8)]
-	str	x10, [x3, #(5 * 8)]
-	str	x9, [x3, #(4 * 8)]
-	str	x8, [x3, #(3 * 8)]
-	str	x7, [x3, #(2 * 8)]
-	str	x6, [x3, #(1 * 8)]
-	str	x5, [x3, #(0 * 8)]
-
-	add	x3, x2, #CPU_SYSREG_OFFSET(DBGBVR0_EL1)
-
-	adr	x26, 1f
-	add	x26, x26, x24, lsl #2
-	br	x26
-1:
-	mrs	x20, dbgbvr15_el1
-	mrs	x19, dbgbvr14_el1
-	mrs	x18, dbgbvr13_el1
-	mrs	x17, dbgbvr12_el1
-	mrs	x16, dbgbvr11_el1
-	mrs	x15, dbgbvr10_el1
-	mrs	x14, dbgbvr9_el1
-	mrs	x13, dbgbvr8_el1
-	mrs	x12, dbgbvr7_el1
-	mrs	x11, dbgbvr6_el1
-	mrs	x10, dbgbvr5_el1
-	mrs	x9, dbgbvr4_el1
-	mrs	x8, dbgbvr3_el1
-	mrs	x7, dbgbvr2_el1
-	mrs	x6, dbgbvr1_el1
-	mrs	x5, dbgbvr0_el1
-
-	adr	x26, 1f
-	add	x26, x26, x24, lsl #2
-	br	x26
-
-1:
-	str	x20, [x3, #(15 * 8)]
-	str	x19, [x3, #(14 * 8)]
-	str	x18, [x3, #(13 * 8)]
-	str	x17, [x3, #(12 * 8)]
-	str	x16, [x3, #(11 * 8)]
-	str	x15, [x3, #(10 * 8)]
-	str	x14, [x3, #(9 * 8)]
-	str	x13, [x3, #(8 * 8)]
-	str	x12, [x3, #(7 * 8)]
-	str	x11, [x3, #(6 * 8)]
-	str	x10, [x3, #(5 * 8)]
-	str	x9, [x3, #(4 * 8)]
-	str	x8, [x3, #(3 * 8)]
-	str	x7, [x3, #(2 * 8)]
-	str	x6, [x3, #(1 * 8)]
-	str	x5, [x3, #(0 * 8)]
-
-	add	x3, x2, #CPU_SYSREG_OFFSET(DBGWCR0_EL1)
-
-	adr	x26, 1f
-	add	x26, x26, x25, lsl #2
-	br	x26
+.macro save_debug type
+	// x4: pointer to register set
+	// x5: number of registers to skip
+	// x6..x22 trashed
+
+	adr	x22, 1f
+	add	x22, x22, x5, lsl #2
+	br	x22
 1:
-	mrs	x20, dbgwcr15_el1
-	mrs	x19, dbgwcr14_el1
-	mrs	x18, dbgwcr13_el1
-	mrs	x17, dbgwcr12_el1
-	mrs	x16, dbgwcr11_el1
-	mrs	x15, dbgwcr10_el1
-	mrs	x14, dbgwcr9_el1
-	mrs	x13, dbgwcr8_el1
-	mrs	x12, dbgwcr7_el1
-	mrs	x11, dbgwcr6_el1
-	mrs	x10, dbgwcr5_el1
-	mrs	x9, dbgwcr4_el1
-	mrs	x8, dbgwcr3_el1
-	mrs	x7, dbgwcr2_el1
-	mrs	x6, dbgwcr1_el1
-	mrs	x5, dbgwcr0_el1
-
-	adr	x26, 1f
-	add	x26, x26, x25, lsl #2
-	br	x26
-
-1:
-	str	x20, [x3, #(15 * 8)]
-	str	x19, [x3, #(14 * 8)]
-	str	x18, [x3, #(13 * 8)]
-	str	x17, [x3, #(12 * 8)]
-	str	x16, [x3, #(11 * 8)]
-	str	x15, [x3, #(10 * 8)]
-	str	x14, [x3, #(9 * 8)]
-	str	x13, [x3, #(8 * 8)]
-	str	x12, [x3, #(7 * 8)]
-	str	x11, [x3, #(6 * 8)]
-	str	x10, [x3, #(5 * 8)]
-	str	x9, [x3, #(4 * 8)]
-	str	x8, [x3, #(3 * 8)]
-	str	x7, [x3, #(2 * 8)]
-	str	x6, [x3, #(1 * 8)]
-	str	x5, [x3, #(0 * 8)]
-
-	add	x3, x2, #CPU_SYSREG_OFFSET(DBGWVR0_EL1)
-
-	adr	x26, 1f
-	add	x26, x26, x25, lsl #2
-	br	x26
+	mrs	x21, \type\()15_el1
+	mrs	x20, \type\()14_el1
+	mrs	x19, \type\()13_el1
+	mrs	x18, \type\()12_el1
+	mrs	x17, \type\()11_el1
+	mrs	x16, \type\()10_el1
+	mrs	x15, \type\()9_el1
+	mrs	x14, \type\()8_el1
+	mrs	x13, \type\()7_el1
+	mrs	x12, \type\()6_el1
+	mrs	x11, \type\()5_el1
+	mrs	x10, \type\()4_el1
+	mrs	x9, \type\()3_el1
+	mrs	x8, \type\()2_el1
+	mrs	x7, \type\()1_el1
+	mrs	x6, \type\()0_el1
+
+	adr	x22, 1f
+	add	x22, x22, x5, lsl #2
+	br	x22
 1:
-	mrs	x20, dbgwvr15_el1
-	mrs	x19, dbgwvr14_el1
-	mrs	x18, dbgwvr13_el1
-	mrs	x17, dbgwvr12_el1
-	mrs	x16, dbgwvr11_el1
-	mrs	x15, dbgwvr10_el1
-	mrs	x14, dbgwvr9_el1
-	mrs	x13, dbgwvr8_el1
-	mrs	x12, dbgwvr7_el1
-	mrs	x11, dbgwvr6_el1
-	mrs	x10, dbgwvr5_el1
-	mrs	x9, dbgwvr4_el1
-	mrs	x8, dbgwvr3_el1
-	mrs	x7, dbgwvr2_el1
-	mrs	x6, dbgwvr1_el1
-	mrs	x5, dbgwvr0_el1
-
-	adr	x26, 1f
-	add	x26, x26, x25, lsl #2
-	br	x26
-
-1:
-	str	x20, [x3, #(15 * 8)]
-	str	x19, [x3, #(14 * 8)]
-	str	x18, [x3, #(13 * 8)]
-	str	x17, [x3, #(12 * 8)]
-	str	x16, [x3, #(11 * 8)]
-	str	x15, [x3, #(10 * 8)]
-	str	x14, [x3, #(9 * 8)]
-	str	x13, [x3, #(8 * 8)]
-	str	x12, [x3, #(7 * 8)]
-	str	x11, [x3, #(6 * 8)]
-	str	x10, [x3, #(5 * 8)]
-	str	x9, [x3, #(4 * 8)]
-	str	x8, [x3, #(3 * 8)]
-	str	x7, [x3, #(2 * 8)]
-	str	x6, [x3, #(1 * 8)]
-	str	x5, [x3, #(0 * 8)]
-
-	mrs	x21, mdccint_el1
-	str	x21, [x2, #CPU_SYSREG_OFFSET(MDCCINT_EL1)]
+	str	x21, [x4, #(15 * 8)]
+	str	x20, [x4, #(14 * 8)]
+	str	x19, [x4, #(13 * 8)]
+	str	x18, [x4, #(12 * 8)]
+	str	x17, [x4, #(11 * 8)]
+	str	x16, [x4, #(10 * 8)]
+	str	x15, [x4, #(9 * 8)]
+	str	x14, [x4, #(8 * 8)]
+	str	x13, [x4, #(7 * 8)]
+	str	x12, [x4, #(6 * 8)]
+	str	x11, [x4, #(5 * 8)]
+	str	x10, [x4, #(4 * 8)]
+	str	x9, [x4, #(3 * 8)]
+	str	x8, [x4, #(2 * 8)]
+	str	x7, [x4, #(1 * 8)]
+	str	x6, [x4, #(0 * 8)]
 .endm
 
 .macro restore_sysregs
@@ -467,195 +320,52 @@
 	msr	mdscr_el1,	x25
 .endm
 
-.macro restore_debug
-	// x2: base address for cpu context
-	// x3: tmp register
-
-	mrs	x26, id_aa64dfr0_el1
-	ubfx	x24, x26, #12, #4	// Extract BRPs
-	ubfx	x25, x26, #20, #4	// Extract WRPs
-	mov	w26, #15
-	sub	w24, w26, w24		// How many BPs to skip
-	sub	w25, w26, w25		// How many WPs to skip
-
-	add	x3, x2, #CPU_SYSREG_OFFSET(DBGBCR0_EL1)
+.macro restore_debug type
+	// x4: pointer to register set
+	// x5: number of registers to skip
+	// x6..x22 trashed
 
-	adr	x26, 1f
-	add	x26, x26, x24, lsl #2
-	br	x26
+	adr	x22, 1f
+	add	x22, x22, x5, lsl #2
+	br	x22
 1:
-	ldr	x20, [x3, #(15 * 8)]
-	ldr	x19, [x3, #(14 * 8)]
-	ldr	x18, [x3, #(13 * 8)]
-	ldr	x17, [x3, #(12 * 8)]
-	ldr	x16, [x3, #(11 * 8)]
-	ldr	x15, [x3, #(10 * 8)]
-	ldr	x14, [x3, #(9 * 8)]
-	ldr	x13, [x3, #(8 * 8)]
-	ldr	x12, [x3, #(7 * 8)]
-	ldr	x11, [x3, #(6 * 8)]
-	ldr	x10, [x3, #(5 * 8)]
-	ldr	x9, [x3, #(4 * 8)]
-	ldr	x8, [x3, #(3 * 8)]
-	ldr	x7, [x3, #(2 * 8)]
-	ldr	x6, [x3, #(1 * 8)]
-	ldr	x5, [x3, #(0 * 8)]
-
-	adr	x26, 1f
-	add	x26, x26, x24, lsl #2
-	br	x26
+	ldr	x21, [x4, #(15 * 8)]
+	ldr	x20, [x4, #(14 * 8)]
+	ldr	x19, [x4, #(13 * 8)]
+	ldr	x18, [x4, #(12 * 8)]
+	ldr	x17, [x4, #(11 * 8)]
+	ldr	x16, [x4, #(10 * 8)]
+	ldr	x15, [x4, #(9 * 8)]
+	ldr	x14, [x4, #(8 * 8)]
+	ldr	x13, [x4, #(7 * 8)]
+	ldr	x12, [x4, #(6 * 8)]
+	ldr	x11, [x4, #(5 * 8)]
+	ldr	x10, [x4, #(4 * 8)]
+	ldr	x9, [x4, #(3 * 8)]
+	ldr	x8, [x4, #(2 * 8)]
+	ldr	x7, [x4, #(1 * 8)]
+	ldr	x6, [x4, #(0 * 8)]
+
+	adr	x22, 1f
+	add	x22, x22, x5, lsl #2
+	br	x22
 1:
-	msr	dbgbcr15_el1, x20
-	msr	dbgbcr14_el1, x19
-	msr	dbgbcr13_el1, x18
-	msr	dbgbcr12_el1, x17
-	msr	dbgbcr11_el1, x16
-	msr	dbgbcr10_el1, x15
-	msr	dbgbcr9_el1, x14
-	msr	dbgbcr8_el1, x13
-	msr	dbgbcr7_el1, x12
-	msr	dbgbcr6_el1, x11
-	msr	dbgbcr5_el1, x10
-	msr	dbgbcr4_el1, x9
-	msr	dbgbcr3_el1, x8
-	msr	dbgbcr2_el1, x7
-	msr	dbgbcr1_el1, x6
-	msr	dbgbcr0_el1, x5
-
-	add	x3, x2, #CPU_SYSREG_OFFSET(DBGBVR0_EL1)
-
-	adr	x26, 1f
-	add	x26, x26, x24, lsl #2
-	br	x26
-1:
-	ldr	x20, [x3, #(15 * 8)]
-	ldr	x19, [x3, #(14 * 8)]
-	ldr	x18, [x3, #(13 * 8)]
-	ldr	x17, [x3, #(12 * 8)]
-	ldr	x16, [x3, #(11 * 8)]
-	ldr	x15, [x3, #(10 * 8)]
-	ldr	x14, [x3, #(9 * 8)]
-	ldr	x13, [x3, #(8 * 8)]
-	ldr	x12, [x3, #(7 * 8)]
-	ldr	x11, [x3, #(6 * 8)]
-	ldr	x10, [x3, #(5 * 8)]
-	ldr	x9, [x3, #(4 * 8)]
-	ldr	x8, [x3, #(3 * 8)]
-	ldr	x7, [x3, #(2 * 8)]
-	ldr	x6, [x3, #(1 * 8)]
-	ldr	x5, [x3, #(0 * 8)]
-
-	adr	x26, 1f
-	add	x26, x26, x24, lsl #2
-	br	x26
-1:
-	msr	dbgbvr15_el1, x20
-	msr	dbgbvr14_el1, x19
-	msr	dbgbvr13_el1, x18
-	msr	dbgbvr12_el1, x17
-	msr	dbgbvr11_el1, x16
-	msr	dbgbvr10_el1, x15
-	msr	dbgbvr9_el1, x14
-	msr	dbgbvr8_el1, x13
-	msr	dbgbvr7_el1, x12
-	msr	dbgbvr6_el1, x11
-	msr	dbgbvr5_el1, x10
-	msr	dbgbvr4_el1, x9
-	msr	dbgbvr3_el1, x8
-	msr	dbgbvr2_el1, x7
-	msr	dbgbvr1_el1, x6
-	msr	dbgbvr0_el1, x5
-
-	add	x3, x2, #CPU_SYSREG_OFFSET(DBGWCR0_EL1)
-
-	adr	x26, 1f
-	add	x26, x26, x25, lsl #2
-	br	x26
-1:
-	ldr	x20, [x3, #(15 * 8)]
-	ldr	x19, [x3, #(14 * 8)]
-	ldr	x18, [x3, #(13 * 8)]
-	ldr	x17, [x3, #(12 * 8)]
-	ldr	x16, [x3, #(11 * 8)]
-	ldr	x15, [x3, #(10 * 8)]
-	ldr	x14, [x3, #(9 * 8)]
-	ldr	x13, [x3, #(8 * 8)]
-	ldr	x12, [x3, #(7 * 8)]
-	ldr	x11, [x3, #(6 * 8)]
-	ldr	x10, [x3, #(5 * 8)]
-	ldr	x9, [x3, #(4 * 8)]
-	ldr	x8, [x3, #(3 * 8)]
-	ldr	x7, [x3, #(2 * 8)]
-	ldr	x6, [x3, #(1 * 8)]
-	ldr	x5, [x3, #(0 * 8)]
-
-	adr	x26, 1f
-	add	x26, x26, x25, lsl #2
-	br	x26
-1:
-	msr	dbgwcr15_el1, x20
-	msr	dbgwcr14_el1, x19
-	msr	dbgwcr13_el1, x18
-	msr	dbgwcr12_el1, x17
-	msr	dbgwcr11_el1, x16
-	msr	dbgwcr10_el1, x15
-	msr	dbgwcr9_el1, x14
-	msr	dbgwcr8_el1, x13
-	msr	dbgwcr7_el1, x12
-	msr	dbgwcr6_el1, x11
-	msr	dbgwcr5_el1, x10
-	msr	dbgwcr4_el1, x9
-	msr	dbgwcr3_el1, x8
-	msr	dbgwcr2_el1, x7
-	msr	dbgwcr1_el1, x6
-	msr	dbgwcr0_el1, x5
-
-	add	x3, x2, #CPU_SYSREG_OFFSET(DBGWVR0_EL1)
-
-	adr	x26, 1f
-	add	x26, x26, x25, lsl #2
-	br	x26
-1:
-	ldr	x20, [x3, #(15 * 8)]
-	ldr	x19, [x3, #(14 * 8)]
-	ldr	x18, [x3, #(13 * 8)]
-	ldr	x17, [x3, #(12 * 8)]
-	ldr	x16, [x3, #(11 * 8)]
-	ldr	x15, [x3, #(10 * 8)]
-	ldr	x14, [x3, #(9 * 8)]
-	ldr	x13, [x3, #(8 * 8)]
-	ldr	x12, [x3, #(7 * 8)]
-	ldr	x11, [x3, #(6 * 8)]
-	ldr	x10, [x3, #(5 * 8)]
-	ldr	x9, [x3, #(4 * 8)]
-	ldr	x8, [x3, #(3 * 8)]
-	ldr	x7, [x3, #(2 * 8)]
-	ldr	x6, [x3, #(1 * 8)]
-	ldr	x5, [x3, #(0 * 8)]
-
-	adr	x26, 1f
-	add	x26, x26, x25, lsl #2
-	br	x26
-1:
-	msr	dbgwvr15_el1, x20
-	msr	dbgwvr14_el1, x19
-	msr	dbgwvr13_el1, x18
-	msr	dbgwvr12_el1, x17
-	msr	dbgwvr11_el1, x16
-	msr	dbgwvr10_el1, x15
-	msr	dbgwvr9_el1, x14
-	msr	dbgwvr8_el1, x13
-	msr	dbgwvr7_el1, x12
-	msr	dbgwvr6_el1, x11
-	msr	dbgwvr5_el1, x10
-	msr	dbgwvr4_el1, x9
-	msr	dbgwvr3_el1, x8
-	msr	dbgwvr2_el1, x7
-	msr	dbgwvr1_el1, x6
-	msr	dbgwvr0_el1, x5
-
-	ldr	x21, [x2, #CPU_SYSREG_OFFSET(MDCCINT_EL1)]
-	msr	mdccint_el1, x21
+	msr	\type\()15_el1, x21
+	msr	\type\()14_el1, x20
+	msr	\type\()13_el1, x19
+	msr	\type\()12_el1, x18
+	msr	\type\()11_el1, x17
+	msr	\type\()10_el1, x16
+	msr	\type\()9_el1, x15
+	msr	\type\()8_el1, x14
+	msr	\type\()7_el1, x13
+	msr	\type\()6_el1, x12
+	msr	\type\()5_el1, x11
+	msr	\type\()4_el1, x10
+	msr	\type\()3_el1, x9
+	msr	\type\()2_el1, x8
+	msr	\type\()1_el1, x7
+	msr	\type\()0_el1, x6
 .endm
 
 .macro skip_32bit_state tmp, target
@@ -883,12 +593,61 @@ __restore_sysregs:
 	restore_sysregs
 	ret
 
+/* Save debug state */
 __save_debug:
-	save_debug
+	// x2: ptr to CPU context
+	// x4/x5/x6-22/x24-26: trashed
+
+	mrs	x26, id_aa64dfr0_el1
+	ubfx	x24, x26, #12, #4	// Extract BRPs
+	ubfx	x25, x26, #20, #4	// Extract WRPs
+	mov	w26, #15
+	sub	w24, w26, w24		// How many BPs to skip
+	sub	w25, w26, w25		// How many WPs to skip
+
+	mov	x5, x24
+	add	x4, x2, #CPU_SYSREG_OFFSET(DBGBCR0_EL1)
+	save_debug dbgbcr
+	add	x4, x2, #CPU_SYSREG_OFFSET(DBGBVR0_EL1)
+	save_debug dbgbvr
+
+	mov	x5, x25
+	add	x4, x2, #CPU_SYSREG_OFFSET(DBGWCR0_EL1)
+	save_debug dbgwcr
+	add	x4, x2, #CPU_SYSREG_OFFSET(DBGWVR0_EL1)
+	save_debug dbgwvr
+
+	mrs	x21, mdccint_el1
+	str	x21, [x2, #CPU_SYSREG_OFFSET(MDCCINT_EL1)]
 	ret
 
+/* Restore debug state */
 __restore_debug:
-	restore_debug
+	// x2: ptr to CPU context
+	// x4/x5/x6-22/x24-26: trashed
+
+	mrs	x26, id_aa64dfr0_el1
+	ubfx	x24, x26, #12, #4	// Extract BRPs
+	ubfx	x25, x26, #20, #4	// Extract WRPs
+	mov	w26, #15
+	sub	w24, w26, w24		// How many BPs to skip
+	sub	w25, w26, w25		// How many WPs to skip
+
+	mov	x5, x24
+	add	x4, x2, #CPU_SYSREG_OFFSET(DBGBCR0_EL1)
+	restore_debug dbgbcr
+	add	x4, x2, #CPU_SYSREG_OFFSET(DBGBVR0_EL1)
+	restore_debug dbgbvr
+
+	mov	x5, x25
+	add	x4, x2, #CPU_SYSREG_OFFSET(DBGWCR0_EL1)
+	restore_debug dbgwcr
+	add	x4, x2, #CPU_SYSREG_OFFSET(DBGWVR0_EL1)
+	restore_debug dbgwvr
+
+	ldr	x21, [x2, #CPU_SYSREG_OFFSET(MDCCINT_EL1)]
+	msr	mdccint_el1, x21
+
 	ret
 
 __save_fpsimd:
-- 
2.1.4



From marc.zyngier at arm.com  Thu Aug 20 09:28:56 2015
From: marc.zyngier at arm.com (Marc Zyngier)
Date: Thu, 20 Aug 2015 17:28:56 +0100
Subject: [PATCH 18/25] KVM: arm/arm64: vgic: Relax vgic_can_sample_irq for
 edge IRQs
In-Reply-To: <1440088143-4722-1-git-send-email-marc.zyngier@arm.com>
References: <1440088143-4722-1-git-send-email-marc.zyngier@arm.com>
Message-ID: <1440088143-4722-19-git-send-email-marc.zyngier@arm.com>

We only set the irq_queued flag for level interrupts, meaning
that "!vgic_irq_is_queued(vcpu, irq)" is a good enough predicate
for all interrupts.

This will allow us to inject edge HW interrupts, for which the
state ACTIVE+PENDING is not allowed.

Reviewed-by: Christoffer Dall <christoffer.dall at linaro.org>
Signed-off-by: Marc Zyngier <marc.zyngier at arm.com>
---
 virt/kvm/arm/vgic.c | 2 +-
 1 file changed, 1 insertion(+), 1 deletion(-)

diff --git a/virt/kvm/arm/vgic.c b/virt/kvm/arm/vgic.c
index bc40137..5bd1695 100644
--- a/virt/kvm/arm/vgic.c
+++ b/virt/kvm/arm/vgic.c
@@ -375,7 +375,7 @@ void vgic_cpu_irq_clear(struct kvm_vcpu *vcpu, int irq)
 
 static bool vgic_can_sample_irq(struct kvm_vcpu *vcpu, int irq)
 {
-	return vgic_irq_is_edge(vcpu, irq) || !vgic_irq_is_queued(vcpu, irq);
+	return !vgic_irq_is_queued(vcpu, irq);
 }
 
 /**
-- 
2.1.4



From marc.zyngier at arm.com  Thu Aug 20 09:28:54 2015
From: marc.zyngier at arm.com (Marc Zyngier)
Date: Thu, 20 Aug 2015 17:28:54 +0100
Subject: [PATCH 16/25] KVM: arm/arm64: vgic: Convert struct vgic_lr to use
 bitfields
In-Reply-To: <1440088143-4722-1-git-send-email-marc.zyngier@arm.com>
References: <1440088143-4722-1-git-send-email-marc.zyngier@arm.com>
Message-ID: <1440088143-4722-17-git-send-email-marc.zyngier@arm.com>

As we're about to cram more information in the vgic_lr structure
(HW interrupt number and additional state information), we switch
to a layout similar to the HW's:

- use bitfields to save space (we don't need more than 10 bits
  to represent the irq numbers)
- source CPU and HW interrupt can share the same field, as
  a SGI doesn't have a physical line.

Reviewed-by: Alex Benn?e <alex.bennee at linaro.org>
Reviewed-by: Christoffer Dall <christoffer.dall at linaro.org>
Signed-off-by: Marc Zyngier <marc.zyngier at arm.com>
---
 include/kvm/arm_vgic.h | 10 +++++++---
 1 file changed, 7 insertions(+), 3 deletions(-)

diff --git a/include/kvm/arm_vgic.h b/include/kvm/arm_vgic.h
index 133ea00..a881e39 100644
--- a/include/kvm/arm_vgic.h
+++ b/include/kvm/arm_vgic.h
@@ -95,11 +95,15 @@ enum vgic_type {
 #define LR_STATE_ACTIVE		(1 << 1)
 #define LR_STATE_MASK		(3 << 0)
 #define LR_EOI_INT		(1 << 2)
+#define LR_HW			(1 << 3)
 
 struct vgic_lr {
-	u16	irq;
-	u8	source;
-	u8	state;
+	unsigned irq:10;
+	union {
+		unsigned hwirq:10;
+		unsigned source:3;
+	};
+	unsigned state:4;
 };
 
 struct vgic_vmcr {
-- 
2.1.4



From marc.zyngier at arm.com  Thu Aug 20 09:29:01 2015
From: marc.zyngier at arm.com (Marc Zyngier)
Date: Thu, 20 Aug 2015 17:29:01 +0100
Subject: [PATCH 23/25] KVM: arm/arm64: timer: Allow the timer to control the
 active state
In-Reply-To: <1440088143-4722-1-git-send-email-marc.zyngier@arm.com>
References: <1440088143-4722-1-git-send-email-marc.zyngier@arm.com>
Message-ID: <1440088143-4722-24-git-send-email-marc.zyngier@arm.com>

In order to remove the crude hack where we sneak the masked bit
into the timer's control register, make use of the phys_irq_map
API control the active state of the interrupt.

This causes some limited changes to allow for potential error
propagation.

Reviewed-by: Christoffer Dall <christoffer.dall at linaro.org>
Signed-off-by: Marc Zyngier <marc.zyngier at arm.com>
---
 arch/arm/kvm/reset.c         |  4 +---
 arch/arm64/kvm/reset.c       |  4 +---
 include/kvm/arm_arch_timer.h |  7 +++++--
 virt/kvm/arm/arch_timer.c    | 29 ++++++++++++++++++++++-------
 4 files changed, 29 insertions(+), 15 deletions(-)

diff --git a/arch/arm/kvm/reset.c b/arch/arm/kvm/reset.c
index f558c07..eeb8585 100644
--- a/arch/arm/kvm/reset.c
+++ b/arch/arm/kvm/reset.c
@@ -77,7 +77,5 @@ int kvm_reset_vcpu(struct kvm_vcpu *vcpu)
 	kvm_reset_coprocs(vcpu);
 
 	/* Reset arch_timer context */
-	kvm_timer_vcpu_reset(vcpu, cpu_vtimer_irq);
-
-	return 0;
+	return kvm_timer_vcpu_reset(vcpu, cpu_vtimer_irq);
 }
diff --git a/arch/arm64/kvm/reset.c b/arch/arm64/kvm/reset.c
index b4af618..91cf535 100644
--- a/arch/arm64/kvm/reset.c
+++ b/arch/arm64/kvm/reset.c
@@ -121,7 +121,5 @@ int kvm_reset_vcpu(struct kvm_vcpu *vcpu)
 	kvm_reset_sys_regs(vcpu);
 
 	/* Reset timer */
-	kvm_timer_vcpu_reset(vcpu, cpu_vtimer_irq);
-
-	return 0;
+	return kvm_timer_vcpu_reset(vcpu, cpu_vtimer_irq);
 }
diff --git a/include/kvm/arm_arch_timer.h b/include/kvm/arm_arch_timer.h
index e596675..e1e4d7c 100644
--- a/include/kvm/arm_arch_timer.h
+++ b/include/kvm/arm_arch_timer.h
@@ -52,13 +52,16 @@ struct arch_timer_cpu {
 
 	/* Timer IRQ */
 	const struct kvm_irq_level	*irq;
+
+	/* VGIC mapping */
+	struct irq_phys_map		*map;
 };
 
 int kvm_timer_hyp_init(void);
 void kvm_timer_enable(struct kvm *kvm);
 void kvm_timer_init(struct kvm *kvm);
-void kvm_timer_vcpu_reset(struct kvm_vcpu *vcpu,
-			  const struct kvm_irq_level *irq);
+int kvm_timer_vcpu_reset(struct kvm_vcpu *vcpu,
+			 const struct kvm_irq_level *irq);
 void kvm_timer_vcpu_init(struct kvm_vcpu *vcpu);
 void kvm_timer_flush_hwstate(struct kvm_vcpu *vcpu);
 void kvm_timer_sync_hwstate(struct kvm_vcpu *vcpu);
diff --git a/virt/kvm/arm/arch_timer.c b/virt/kvm/arm/arch_timer.c
index 98c95f2..76e38d2 100644
--- a/virt/kvm/arm/arch_timer.c
+++ b/virt/kvm/arm/arch_timer.c
@@ -64,10 +64,10 @@ static void kvm_timer_inject_irq(struct kvm_vcpu *vcpu)
 	int ret;
 	struct arch_timer_cpu *timer = &vcpu->arch.timer_cpu;
 
-	timer->cntv_ctl |= ARCH_TIMER_CTRL_IT_MASK;
-	ret = kvm_vgic_inject_irq(vcpu->kvm, vcpu->vcpu_id,
-				  timer->irq->irq,
-				  timer->irq->level);
+	kvm_vgic_set_phys_irq_active(timer->map, true);
+	ret = kvm_vgic_inject_mapped_irq(vcpu->kvm, vcpu->vcpu_id,
+					 timer->map,
+					 timer->irq->level);
 	WARN_ON(ret);
 }
 
@@ -117,7 +117,8 @@ bool kvm_timer_should_fire(struct kvm_vcpu *vcpu)
 	cycle_t cval, now;
 
 	if ((timer->cntv_ctl & ARCH_TIMER_CTRL_IT_MASK) ||
-		!(timer->cntv_ctl & ARCH_TIMER_CTRL_ENABLE))
+	    !(timer->cntv_ctl & ARCH_TIMER_CTRL_ENABLE) ||
+	    kvm_vgic_get_phys_irq_active(timer->map))
 		return false;
 
 	cval = timer->cntv_cval;
@@ -184,10 +185,11 @@ void kvm_timer_sync_hwstate(struct kvm_vcpu *vcpu)
 	timer_arm(timer, ns);
 }
 
-void kvm_timer_vcpu_reset(struct kvm_vcpu *vcpu,
-			  const struct kvm_irq_level *irq)
+int kvm_timer_vcpu_reset(struct kvm_vcpu *vcpu,
+			 const struct kvm_irq_level *irq)
 {
 	struct arch_timer_cpu *timer = &vcpu->arch.timer_cpu;
+	struct irq_phys_map *map;
 
 	/*
 	 * The vcpu timer irq number cannot be determined in
@@ -196,6 +198,17 @@ void kvm_timer_vcpu_reset(struct kvm_vcpu *vcpu,
 	 * vcpu timer irq number when the vcpu is reset.
 	 */
 	timer->irq = irq;
+
+	/*
+	 * Tell the VGIC that the virtual interrupt is tied to a
+	 * physical interrupt. We do that once per VCPU.
+	 */
+	map = kvm_vgic_map_phys_irq(vcpu, irq->irq, host_vtimer_irq);
+	if (WARN_ON(IS_ERR(map)))
+		return PTR_ERR(map);
+
+	timer->map = map;
+	return 0;
 }
 
 void kvm_timer_vcpu_init(struct kvm_vcpu *vcpu)
@@ -335,6 +348,8 @@ void kvm_timer_vcpu_terminate(struct kvm_vcpu *vcpu)
 	struct arch_timer_cpu *timer = &vcpu->arch.timer_cpu;
 
 	timer_disarm(timer);
+	if (timer->map)
+		kvm_vgic_unmap_phys_irq(vcpu, timer->map);
 }
 
 void kvm_timer_enable(struct kvm *kvm)
-- 
2.1.4



From marc.zyngier at arm.com  Thu Aug 20 09:28:57 2015
From: marc.zyngier at arm.com (Marc Zyngier)
Date: Thu, 20 Aug 2015 17:28:57 +0100
Subject: [PATCH 19/25] KVM: arm/arm64: vgic: Allow dynamic mapping of
 physical/virtual interrupts
In-Reply-To: <1440088143-4722-1-git-send-email-marc.zyngier@arm.com>
References: <1440088143-4722-1-git-send-email-marc.zyngier@arm.com>
Message-ID: <1440088143-4722-20-git-send-email-marc.zyngier@arm.com>

In order to be able to feed physical interrupts to a guest, we need
to be able to establish the virtual-physical mapping between the two
worlds.

The mappings are kept in a set of RCU lists, indexed by virtual interrupts.

Reviewed-by: Christoffer Dall <christoffer.dall at linaro.org>
Signed-off-by: Marc Zyngier <marc.zyngier at arm.com>
---
 arch/arm/kvm/arm.c     |   2 +
 include/kvm/arm_vgic.h |  25 ++++++
 virt/kvm/arm/vgic.c    | 209 ++++++++++++++++++++++++++++++++++++++++++++++++-
 3 files changed, 235 insertions(+), 1 deletion(-)

diff --git a/arch/arm/kvm/arm.c b/arch/arm/kvm/arm.c
index f1bf418..ce404a5 100644
--- a/arch/arm/kvm/arm.c
+++ b/arch/arm/kvm/arm.c
@@ -125,6 +125,7 @@ int kvm_arch_init_vm(struct kvm *kvm, unsigned long type)
 	if (ret)
 		goto out_free_stage2_pgd;
 
+	kvm_vgic_early_init(kvm);
 	kvm_timer_init(kvm);
 
 	/* Mark the initial VMID generation invalid */
@@ -249,6 +250,7 @@ out:
 
 void kvm_arch_vcpu_postcreate(struct kvm_vcpu *vcpu)
 {
+	kvm_vgic_vcpu_early_init(vcpu);
 }
 
 void kvm_arch_vcpu_free(struct kvm_vcpu *vcpu)
diff --git a/include/kvm/arm_vgic.h b/include/kvm/arm_vgic.h
index a881e39..c0e6354 100644
--- a/include/kvm/arm_vgic.h
+++ b/include/kvm/arm_vgic.h
@@ -159,6 +159,19 @@ struct vgic_io_device {
 	struct kvm_io_device dev;
 };
 
+struct irq_phys_map {
+	u32			virt_irq;
+	u32			phys_irq;
+	u32			irq;
+	bool			active;
+};
+
+struct irq_phys_map_entry {
+	struct list_head	entry;
+	struct rcu_head		rcu;
+	struct irq_phys_map	map;
+};
+
 struct vgic_dist {
 	spinlock_t		lock;
 	bool			in_kernel;
@@ -256,6 +269,10 @@ struct vgic_dist {
 	struct vgic_vm_ops	vm_ops;
 	struct vgic_io_device	dist_iodev;
 	struct vgic_io_device	*redist_iodevs;
+
+	/* Virtual irq to hwirq mapping */
+	spinlock_t		irq_phys_map_lock;
+	struct list_head	irq_phys_map_list;
 };
 
 struct vgic_v2_cpu_if {
@@ -307,6 +324,9 @@ struct vgic_cpu {
 		struct vgic_v2_cpu_if	vgic_v2;
 		struct vgic_v3_cpu_if	vgic_v3;
 	};
+
+	/* Protected by the distributor's irq_phys_map_lock */
+	struct list_head	irq_phys_map_list;
 };
 
 #define LR_EMPTY	0xff
@@ -321,8 +341,10 @@ int kvm_vgic_addr(struct kvm *kvm, unsigned long type, u64 *addr, bool write);
 int kvm_vgic_hyp_init(void);
 int kvm_vgic_map_resources(struct kvm *kvm);
 int kvm_vgic_get_max_vcpus(void);
+void kvm_vgic_early_init(struct kvm *kvm);
 int kvm_vgic_create(struct kvm *kvm, u32 type);
 void kvm_vgic_destroy(struct kvm *kvm);
+void kvm_vgic_vcpu_early_init(struct kvm_vcpu *vcpu);
 void kvm_vgic_vcpu_destroy(struct kvm_vcpu *vcpu);
 void kvm_vgic_flush_hwstate(struct kvm_vcpu *vcpu);
 void kvm_vgic_sync_hwstate(struct kvm_vcpu *vcpu);
@@ -331,6 +353,9 @@ int kvm_vgic_inject_irq(struct kvm *kvm, int cpuid, unsigned int irq_num,
 void vgic_v3_dispatch_sgi(struct kvm_vcpu *vcpu, u64 reg);
 int kvm_vgic_vcpu_pending_irq(struct kvm_vcpu *vcpu);
 int kvm_vgic_vcpu_active_irq(struct kvm_vcpu *vcpu);
+struct irq_phys_map *kvm_vgic_map_phys_irq(struct kvm_vcpu *vcpu,
+					   int virt_irq, int irq);
+int kvm_vgic_unmap_phys_irq(struct kvm_vcpu *vcpu, struct irq_phys_map *map);
 
 #define irqchip_in_kernel(k)	(!!((k)->arch.vgic.in_kernel))
 #define vgic_initialized(k)	(!!((k)->arch.vgic.nr_cpus))
diff --git a/virt/kvm/arm/vgic.c b/virt/kvm/arm/vgic.c
index 5bd1695..51c9900 100644
--- a/virt/kvm/arm/vgic.c
+++ b/virt/kvm/arm/vgic.c
@@ -24,6 +24,7 @@
 #include <linux/of.h>
 #include <linux/of_address.h>
 #include <linux/of_irq.h>
+#include <linux/rculist.h>
 #include <linux/uaccess.h>
 
 #include <asm/kvm_emulate.h>
@@ -74,6 +75,28 @@
  *   cause the interrupt to become inactive in such a situation.
  *   Conversely, writes to GICD_ICPENDRn do not cause the interrupt to become
  *   inactive as long as the external input line is held high.
+ *
+ *
+ * Initialization rules: there are multiple stages to the vgic
+ * initialization, both for the distributor and the CPU interfaces.
+ *
+ * Distributor:
+ *
+ * - kvm_vgic_early_init(): initialization of static data that doesn't
+ *   depend on any sizing information or emulation type. No allocation
+ *   is allowed there.
+ *
+ * - vgic_init(): allocation and initialization of the generic data
+ *   structures that depend on sizing information (number of CPUs,
+ *   number of interrupts). Also initializes the vcpu specific data
+ *   structures. Can be executed lazily for GICv2.
+ *   [to be renamed to kvm_vgic_init??]
+ *
+ * CPU Interface:
+ *
+ * - kvm_vgic_cpu_early_init(): initialization of static data that
+ *   doesn't depend on any sizing information or emulation type. No
+ *   allocation is allowed there.
  */
 
 #include "vgic.h"
@@ -82,6 +105,8 @@ static void vgic_retire_disabled_irqs(struct kvm_vcpu *vcpu);
 static void vgic_retire_lr(int lr_nr, int irq, struct kvm_vcpu *vcpu);
 static struct vgic_lr vgic_get_lr(const struct kvm_vcpu *vcpu, int lr);
 static void vgic_set_lr(struct kvm_vcpu *vcpu, int lr, struct vgic_lr lr_desc);
+static struct irq_phys_map *vgic_irq_map_search(struct kvm_vcpu *vcpu,
+						int virt_irq);
 
 static const struct vgic_ops *vgic_ops;
 static const struct vgic_params *vgic;
@@ -1583,6 +1608,164 @@ static irqreturn_t vgic_maintenance_handler(int irq, void *data)
 	return IRQ_HANDLED;
 }
 
+static struct list_head *vgic_get_irq_phys_map_list(struct kvm_vcpu *vcpu,
+						    int virt_irq)
+{
+	if (virt_irq < VGIC_NR_PRIVATE_IRQS)
+		return &vcpu->arch.vgic_cpu.irq_phys_map_list;
+	else
+		return &vcpu->kvm->arch.vgic.irq_phys_map_list;
+}
+
+/**
+ * kvm_vgic_map_phys_irq - map a virtual IRQ to a physical IRQ
+ * @vcpu: The VCPU pointer
+ * @virt_irq: The virtual irq number
+ * @irq: The Linux IRQ number
+ *
+ * Establish a mapping between a guest visible irq (@virt_irq) and a
+ * Linux irq (@irq). On injection, @virt_irq will be associated with
+ * the physical interrupt represented by @irq. This mapping can be
+ * established multiple times as long as the parameters are the same.
+ *
+ * Returns a valid pointer on success, and an error pointer otherwise
+ */
+struct irq_phys_map *kvm_vgic_map_phys_irq(struct kvm_vcpu *vcpu,
+					   int virt_irq, int irq)
+{
+	struct vgic_dist *dist = &vcpu->kvm->arch.vgic;
+	struct list_head *root = vgic_get_irq_phys_map_list(vcpu, virt_irq);
+	struct irq_phys_map *map;
+	struct irq_phys_map_entry *entry;
+	struct irq_desc *desc;
+	struct irq_data *data;
+	int phys_irq;
+
+	desc = irq_to_desc(irq);
+	if (!desc) {
+		kvm_err("%s: no interrupt descriptor\n", __func__);
+		return ERR_PTR(-EINVAL);
+	}
+
+	data = irq_desc_get_irq_data(desc);
+	while (data->parent_data)
+		data = data->parent_data;
+
+	phys_irq = data->hwirq;
+
+	/* Create a new mapping */
+	entry = kzalloc(sizeof(*entry), GFP_KERNEL);
+	if (!entry)
+		return ERR_PTR(-ENOMEM);
+
+	spin_lock(&dist->irq_phys_map_lock);
+
+	/* Try to match an existing mapping */
+	map = vgic_irq_map_search(vcpu, virt_irq);
+	if (map) {
+		/* Make sure this mapping matches */
+		if (map->phys_irq != phys_irq	||
+		    map->irq      != irq)
+			map = ERR_PTR(-EINVAL);
+
+		/* Found an existing, valid mapping */
+		goto out;
+	}
+
+	map           = &entry->map;
+	map->virt_irq = virt_irq;
+	map->phys_irq = phys_irq;
+	map->irq      = irq;
+
+	list_add_tail_rcu(&entry->entry, root);
+
+out:
+	spin_unlock(&dist->irq_phys_map_lock);
+	/* If we've found a hit in the existing list, free the useless
+	 * entry */
+	if (IS_ERR(map) || map != &entry->map)
+		kfree(entry);
+	return map;
+}
+
+static struct irq_phys_map *vgic_irq_map_search(struct kvm_vcpu *vcpu,
+						int virt_irq)
+{
+	struct list_head *root = vgic_get_irq_phys_map_list(vcpu, virt_irq);
+	struct irq_phys_map_entry *entry;
+	struct irq_phys_map *map;
+
+	rcu_read_lock();
+
+	list_for_each_entry_rcu(entry, root, entry) {
+		map = &entry->map;
+		if (map->virt_irq == virt_irq) {
+			rcu_read_unlock();
+			return map;
+		}
+	}
+
+	rcu_read_unlock();
+
+	return NULL;
+}
+
+static void vgic_free_phys_irq_map_rcu(struct rcu_head *rcu)
+{
+	struct irq_phys_map_entry *entry;
+
+	entry = container_of(rcu, struct irq_phys_map_entry, rcu);
+	kfree(entry);
+}
+
+/**
+ * kvm_vgic_unmap_phys_irq - Remove a virtual to physical IRQ mapping
+ * @vcpu: The VCPU pointer
+ * @map: The pointer to a mapping obtained through kvm_vgic_map_phys_irq
+ *
+ * Remove an existing mapping between virtual and physical interrupts.
+ */
+int kvm_vgic_unmap_phys_irq(struct kvm_vcpu *vcpu, struct irq_phys_map *map)
+{
+	struct vgic_dist *dist = &vcpu->kvm->arch.vgic;
+	struct irq_phys_map_entry *entry;
+	struct list_head *root;
+
+	if (!map)
+		return -EINVAL;
+
+	root = vgic_get_irq_phys_map_list(vcpu, map->virt_irq);
+
+	spin_lock(&dist->irq_phys_map_lock);
+
+	list_for_each_entry(entry, root, entry) {
+		if (&entry->map == map) {
+			list_del_rcu(&entry->entry);
+			call_rcu(&entry->rcu, vgic_free_phys_irq_map_rcu);
+			break;
+		}
+	}
+
+	spin_unlock(&dist->irq_phys_map_lock);
+
+	return 0;
+}
+
+static void vgic_destroy_irq_phys_map(struct kvm *kvm, struct list_head *root)
+{
+	struct vgic_dist *dist = &kvm->arch.vgic;
+	struct irq_phys_map_entry *entry;
+
+	spin_lock(&dist->irq_phys_map_lock);
+
+	list_for_each_entry(entry, root, entry) {
+		list_del_rcu(&entry->entry);
+		call_rcu(&entry->rcu, vgic_free_phys_irq_map_rcu);
+	}
+
+	spin_unlock(&dist->irq_phys_map_lock);
+}
+
 void kvm_vgic_vcpu_destroy(struct kvm_vcpu *vcpu)
 {
 	struct vgic_cpu *vgic_cpu = &vcpu->arch.vgic_cpu;
@@ -1591,6 +1774,7 @@ void kvm_vgic_vcpu_destroy(struct kvm_vcpu *vcpu)
 	kfree(vgic_cpu->active_shared);
 	kfree(vgic_cpu->pend_act_shared);
 	kfree(vgic_cpu->vgic_irq_lr_map);
+	vgic_destroy_irq_phys_map(vcpu->kvm, &vgic_cpu->irq_phys_map_list);
 	vgic_cpu->pending_shared = NULL;
 	vgic_cpu->active_shared = NULL;
 	vgic_cpu->pend_act_shared = NULL;
@@ -1628,6 +1812,17 @@ static int vgic_vcpu_init_maps(struct kvm_vcpu *vcpu, int nr_irqs)
 }
 
 /**
+ * kvm_vgic_vcpu_early_init - Earliest possible per-vcpu vgic init stage
+ *
+ * No memory allocation should be performed here, only static init.
+ */
+void kvm_vgic_vcpu_early_init(struct kvm_vcpu *vcpu)
+{
+	struct vgic_cpu *vgic_cpu = &vcpu->arch.vgic_cpu;
+	INIT_LIST_HEAD(&vgic_cpu->irq_phys_map_list);
+}
+
+/**
  * kvm_vgic_get_max_vcpus - Get the maximum number of VCPUs allowed by HW
  *
  * The host's GIC naturally limits the maximum amount of VCPUs a guest
@@ -1664,6 +1859,7 @@ void kvm_vgic_destroy(struct kvm *kvm)
 	kfree(dist->irq_spi_target);
 	kfree(dist->irq_pending_on_cpu);
 	kfree(dist->irq_active_on_cpu);
+	vgic_destroy_irq_phys_map(kvm, &dist->irq_phys_map_list);
 	dist->irq_sgi_sources = NULL;
 	dist->irq_spi_cpu = NULL;
 	dist->irq_spi_target = NULL;
@@ -1787,6 +1983,18 @@ static int init_vgic_model(struct kvm *kvm, int type)
 	return 0;
 }
 
+/**
+ * kvm_vgic_early_init - Earliest possible vgic initialization stage
+ *
+ * No memory allocation should be performed here, only static init.
+ */
+void kvm_vgic_early_init(struct kvm *kvm)
+{
+	spin_lock_init(&kvm->arch.vgic.lock);
+	spin_lock_init(&kvm->arch.vgic.irq_phys_map_lock);
+	INIT_LIST_HEAD(&kvm->arch.vgic.irq_phys_map_list);
+}
+
 int kvm_vgic_create(struct kvm *kvm, u32 type)
 {
 	int i, vcpu_lock_idx = -1, ret;
@@ -1832,7 +2040,6 @@ int kvm_vgic_create(struct kvm *kvm, u32 type)
 	if (ret)
 		goto out_unlock;
 
-	spin_lock_init(&kvm->arch.vgic.lock);
 	kvm->arch.vgic.in_kernel = true;
 	kvm->arch.vgic.vgic_model = type;
 	kvm->arch.vgic.vctrl_base = vgic->vctrl_base;
-- 
2.1.4



From marc.zyngier at arm.com  Thu Aug 20 09:28:51 2015
From: marc.zyngier at arm.com (Marc Zyngier)
Date: Thu, 20 Aug 2015 17:28:51 +0100
Subject: [PATCH 13/25] arm64: KVM: remove remaining reference to
 vgic_sr_vectors
In-Reply-To: <1440088143-4722-1-git-send-email-marc.zyngier@arm.com>
References: <1440088143-4722-1-git-send-email-marc.zyngier@arm.com>
Message-ID: <1440088143-4722-14-git-send-email-marc.zyngier@arm.com>

From: Vladimir Murzin <Vladimir.Murzin at arm.com>

Since commit 8a14849 (arm64: KVM: Switch vgic save/restore to
alternative_insn) vgic_sr_vectors is not used anymore, so remove
remaining leftovers and kill the structure.

Signed-off-by: Vladimir Murzin <vladimir.murzin at arm.com>
Signed-off-by: Marc Zyngier <marc.zyngier at arm.com>
---
 arch/arm64/include/asm/kvm_host.h | 5 -----
 arch/arm64/kernel/asm-offsets.c   | 2 --
 2 files changed, 7 deletions(-)

diff --git a/arch/arm64/include/asm/kvm_host.h b/arch/arm64/include/asm/kvm_host.h
index 409217f..415938d 100644
--- a/arch/arm64/include/asm/kvm_host.h
+++ b/arch/arm64/include/asm/kvm_host.h
@@ -246,11 +246,6 @@ static inline void __cpu_init_hyp_mode(phys_addr_t boot_pgd_ptr,
 		     hyp_stack_ptr, vector_ptr);
 }
 
-struct vgic_sr_vectors {
-	void	*save_vgic;
-	void	*restore_vgic;
-};
-
 static inline void kvm_arch_hardware_disable(void) {}
 static inline void kvm_arch_hardware_unsetup(void) {}
 static inline void kvm_arch_sync_events(struct kvm *kvm) {}
diff --git a/arch/arm64/kernel/asm-offsets.c b/arch/arm64/kernel/asm-offsets.c
index d886308..8d89cf8 100644
--- a/arch/arm64/kernel/asm-offsets.c
+++ b/arch/arm64/kernel/asm-offsets.c
@@ -132,8 +132,6 @@ int main(void)
   DEFINE(KVM_TIMER_ENABLED,	offsetof(struct kvm, arch.timer.enabled));
   DEFINE(VCPU_KVM,		offsetof(struct kvm_vcpu, kvm));
   DEFINE(VCPU_VGIC_CPU,		offsetof(struct kvm_vcpu, arch.vgic_cpu));
-  DEFINE(VGIC_SAVE_FN,		offsetof(struct vgic_sr_vectors, save_vgic));
-  DEFINE(VGIC_RESTORE_FN,	offsetof(struct vgic_sr_vectors, restore_vgic));
   DEFINE(VGIC_V2_CPU_HCR,	offsetof(struct vgic_cpu, vgic_v2.vgic_hcr));
   DEFINE(VGIC_V2_CPU_VMCR,	offsetof(struct vgic_cpu, vgic_v2.vgic_vmcr));
   DEFINE(VGIC_V2_CPU_MISR,	offsetof(struct vgic_cpu, vgic_v2.vgic_misr));
-- 
2.1.4



From marc.zyngier at arm.com  Thu Aug 20 09:29:00 2015
From: marc.zyngier at arm.com (Marc Zyngier)
Date: Thu, 20 Aug 2015 17:29:00 +0100
Subject: [PATCH 22/25] KVM: arm/arm64: vgic: Prevent userspace injection of a
 mapped interrupt
In-Reply-To: <1440088143-4722-1-git-send-email-marc.zyngier@arm.com>
References: <1440088143-4722-1-git-send-email-marc.zyngier@arm.com>
Message-ID: <1440088143-4722-23-git-send-email-marc.zyngier@arm.com>

Virtual interrupts mapped to a HW interrupt should only be triggered
from inside the kernel. Otherwise, you could end up confusing the
kernel (and the GIC's) state machine.

Rearrange the injection path so that kvm_vgic_inject_irq is
used for non-mapped interrupts, and kvm_vgic_inject_mapped_irq is
used for mapped interrupts. The latter should only be called from
inside the kernel (timer, irqfd).

Reviewed-by: Christoffer Dall <christoffer.dall at linaro.org>
Signed-off-by: Marc Zyngier <marc.zyngier at arm.com>
---
 include/kvm/arm_vgic.h |   2 +
 virt/kvm/arm/vgic.c    | 103 +++++++++++++++++++++++++++++++++----------------
 2 files changed, 72 insertions(+), 33 deletions(-)

diff --git a/include/kvm/arm_vgic.h b/include/kvm/arm_vgic.h
index e789e47..d901f1a 100644
--- a/include/kvm/arm_vgic.h
+++ b/include/kvm/arm_vgic.h
@@ -350,6 +350,8 @@ void kvm_vgic_flush_hwstate(struct kvm_vcpu *vcpu);
 void kvm_vgic_sync_hwstate(struct kvm_vcpu *vcpu);
 int kvm_vgic_inject_irq(struct kvm *kvm, int cpuid, unsigned int irq_num,
 			bool level);
+int kvm_vgic_inject_mapped_irq(struct kvm *kvm, int cpuid,
+			       struct irq_phys_map *map, bool level);
 void vgic_v3_dispatch_sgi(struct kvm_vcpu *vcpu, u64 reg);
 int kvm_vgic_vcpu_pending_irq(struct kvm_vcpu *vcpu);
 int kvm_vgic_vcpu_active_irq(struct kvm_vcpu *vcpu);
diff --git a/virt/kvm/arm/vgic.c b/virt/kvm/arm/vgic.c
index b553a8f..9eb489a 100644
--- a/virt/kvm/arm/vgic.c
+++ b/virt/kvm/arm/vgic.c
@@ -1555,7 +1555,8 @@ static int vgic_validate_injection(struct kvm_vcpu *vcpu, int irq, int level)
 }
 
 static int vgic_update_irq_pending(struct kvm *kvm, int cpuid,
-				  unsigned int irq_num, bool level)
+				   struct irq_phys_map *map,
+				   unsigned int irq_num, bool level)
 {
 	struct vgic_dist *dist = &kvm->arch.vgic;
 	struct kvm_vcpu *vcpu;
@@ -1563,6 +1564,9 @@ static int vgic_update_irq_pending(struct kvm *kvm, int cpuid,
 	int enabled;
 	bool ret = true, can_inject = true;
 
+	if (irq_num >= min(kvm->arch.vgic.nr_irqs, 1020))
+		return -EINVAL;
+
 	spin_lock(&dist->lock);
 
 	vcpu = kvm_get_vcpu(kvm, cpuid);
@@ -1625,18 +1629,46 @@ static int vgic_update_irq_pending(struct kvm *kvm, int cpuid,
 out:
 	spin_unlock(&dist->lock);
 
-	return ret ? cpuid : -EINVAL;
+	if (ret) {
+		/* kick the specified vcpu */
+		kvm_vcpu_kick(kvm_get_vcpu(kvm, cpuid));
+	}
+
+	return 0;
+}
+
+static int vgic_lazy_init(struct kvm *kvm)
+{
+	int ret = 0;
+
+	if (unlikely(!vgic_initialized(kvm))) {
+		/*
+		 * We only provide the automatic initialization of the VGIC
+		 * for the legacy case of a GICv2. Any other type must
+		 * be explicitly initialized once setup with the respective
+		 * KVM device call.
+		 */
+		if (kvm->arch.vgic.vgic_model != KVM_DEV_TYPE_ARM_VGIC_V2)
+			return -EBUSY;
+
+		mutex_lock(&kvm->lock);
+		ret = vgic_init(kvm);
+		mutex_unlock(&kvm->lock);
+	}
+
+	return ret;
 }
 
 /**
  * kvm_vgic_inject_irq - Inject an IRQ from a device to the vgic
  * @kvm:     The VM structure pointer
  * @cpuid:   The CPU for PPIs
- * @irq_num: The IRQ number that is assigned to the device
+ * @irq_num: The IRQ number that is assigned to the device. This IRQ
+ *           must not be mapped to a HW interrupt.
  * @level:   Edge-triggered:  true:  to trigger the interrupt
  *			      false: to ignore the call
- *	     Level-sensitive  true:  activates an interrupt
- *			      false: deactivates an interrupt
+ *	     Level-sensitive  true:  raise the input signal
+ *			      false: lower the input signal
  *
  * The GIC is not concerned with devices being active-LOW or active-HIGH for
  * level-sensitive interrupts.  You can think of the level parameter as 1
@@ -1645,39 +1677,44 @@ out:
 int kvm_vgic_inject_irq(struct kvm *kvm, int cpuid, unsigned int irq_num,
 			bool level)
 {
-	int ret = 0;
-	int vcpu_id;
-
-	if (unlikely(!vgic_initialized(kvm))) {
-		/*
-		 * We only provide the automatic initialization of the VGIC
-		 * for the legacy case of a GICv2. Any other type must
-		 * be explicitly initialized once setup with the respective
-		 * KVM device call.
-		 */
-		if (kvm->arch.vgic.vgic_model != KVM_DEV_TYPE_ARM_VGIC_V2) {
-			ret = -EBUSY;
-			goto out;
-		}
-		mutex_lock(&kvm->lock);
-		ret = vgic_init(kvm);
-		mutex_unlock(&kvm->lock);
+	struct irq_phys_map *map;
+	int ret;
 
-		if (ret)
-			goto out;
-	}
+	ret = vgic_lazy_init(kvm);
+	if (ret)
+		return ret;
 
-	if (irq_num >= min(kvm->arch.vgic.nr_irqs, 1020))
+	map = vgic_irq_map_search(kvm_get_vcpu(kvm, cpuid), irq_num);
+	if (map)
 		return -EINVAL;
 
-	vcpu_id = vgic_update_irq_pending(kvm, cpuid, irq_num, level);
-	if (vcpu_id >= 0) {
-		/* kick the specified vcpu */
-		kvm_vcpu_kick(kvm_get_vcpu(kvm, vcpu_id));
-	}
+	return vgic_update_irq_pending(kvm, cpuid, NULL, irq_num, level);
+}
 
-out:
-	return ret;
+/**
+ * kvm_vgic_inject_mapped_irq - Inject a physically mapped IRQ to the vgic
+ * @kvm:     The VM structure pointer
+ * @cpuid:   The CPU for PPIs
+ * @map:     Pointer to a irq_phys_map structure describing the mapping
+ * @level:   Edge-triggered:  true:  to trigger the interrupt
+ *			      false: to ignore the call
+ *	     Level-sensitive  true:  raise the input signal
+ *			      false: lower the input signal
+ *
+ * The GIC is not concerned with devices being active-LOW or active-HIGH for
+ * level-sensitive interrupts.  You can think of the level parameter as 1
+ * being HIGH and 0 being LOW and all devices being active-HIGH.
+ */
+int kvm_vgic_inject_mapped_irq(struct kvm *kvm, int cpuid,
+			       struct irq_phys_map *map, bool level)
+{
+	int ret;
+
+	ret = vgic_lazy_init(kvm);
+	if (ret)
+		return ret;
+
+	return vgic_update_irq_pending(kvm, cpuid, map, map->virt_irq, level);
 }
 
 static irqreturn_t vgic_maintenance_handler(int irq, void *data)
-- 
2.1.4



From gregory.clement at free-electrons.com  Thu Aug 20 09:35:17 2015
From: gregory.clement at free-electrons.com (Gregory CLEMENT)
Date: Thu, 20 Aug 2015 18:35:17 +0200
Subject: MUSB dual-role on AM335x behaving weirdly
In-Reply-To: <20150818141334.GC9143@saruman.tx.rr.com>
References: <20150514212653.GC3338@piout.net>
 <CADYTM3baVqoEBdWoQb5JFyGR2_GKm1FHMYWST1YkZV=m=ZdycQ@mail.gmail.com>
 <20150526145118.GD26599@saruman.tx.rr.com> <20150527094205.GO3199@piout.net>
 <5594E56B.3040200@free-electrons.com>
 <CADYTM3ZF5m++N1NqmOJoH5agbYrzpvSbLnuLVgttxwzdzwmGwQ@mail.gmail.com>
 <55C0B954.3020106@free-electrons.com> <55C0CAC6.3020603@free-electrons.com>
 <20150804193257.GF9623@saruman.tx.rr.com>
 <55D326BD.2030706@free-electrons.com>
 <20150818141334.GC9143@saruman.tx.rr.com>
Message-ID: <55D601C5.40608@free-electrons.com>

Hi Felipe,

On 18/08/2015 16:13, Felipe Balbi wrote:
> Hi,
> 
> On Tue, Aug 18, 2015 at 02:36:13PM +0200, Gregory CLEMENT wrote:
>> Hi again Felipe,
>>
>> I sent this email again without the capture because it prevented to be delivered
>> to the mailing lists.
>>
>> On 04/08/2015 21:32, Felipe Balbi wrote:
>>> On Tue, Aug 04, 2015 at 04:23:02PM +0200, Gregory CLEMENT wrote:
>>>> Hi again,
>>>> On 04/08/2015 15:08, Gregory CLEMENT wrote:
>>>>> Hi Bin,
>>>>>
>>>>> On 02/07/2015 19:05, Bin Liu wrote:
>>>>>> Hi,
>>>>>>
>>>>>> On Thu, Jul 2, 2015 at 2:16 AM, Gregory CLEMENT
>>>>>> <gregory.clement at free-electrons.com> wrote:
>>>>>>> Hi Felipe,
>>>>>>>
>>>>>>> On 27/05/2015 11:42, Alexandre Belloni wrote:
>>>>>>>> Hi,
>>>>>>>>
>>>>>>>> On 26/05/2015 at 09:51:18 -0500, Felipe Balbi wrote :
>>>>>>>>> On Thu, May 14, 2015 at 04:36:33PM -0500, Bin Liu wrote:
>>>>>>>>>> Alexandre,
>>>>>>>>>>
>>>>>>>>>> On Thu, May 14, 2015 at 4:26 PM, Alexandre Belloni
>>>>>>>>>> <alexandre.belloni at free-electrons.com> wrote:
>>>>>>>>>>> On 14/05/2015 at 16:16:12 -0500, Bin Liu wrote :
>>>>>>>>>>>> I think I found the root cause of the problem: board design issue - I
>>>>>>>>>>>> bet the custom board has too much cap on VBUS line. It should be <
>>>>>>>>>>>> 10uF.
>>>>>>>>>>>>
>>>>>>>>>>>
>>>>>>>>>>> We have a custom board that exhibits the issue but it only has a 100nF
>>>>>>>>>>> cap on VBUS.
>>>>>>>>>>
>>>>>>>>>> Have you measured the VBUS discharging? Is there any way to share your
>>>>>>>>>> schematics?
>>>>>>>>>
>>>>>>>>> Alexandre, any further comments ?
>>>>>>>>>
>>>>>>>>
>>>>>>>> Yeah, I have just got more info.
>>>>>>>>
>>>>>>>> This is the relevant part of the schematic:
>>>>>>>> http://free-electrons.com/~alexandre/usb.png
>>>>>>>>
>>>>>>>> The total VBUS capacitance is 200nF and the USB0 pins are connected
>>>>>>>> directly to the AM3358 pins. U1 is actually not fitted.
>>>>>>>>
>>>>>>>> We didn't measure VBUS discharging but we observe the OTG pin sensing
>>>>>>>> stops when plugging an OTG cable without any device.
>>>>>>>
>>>>>>> Do you have any news about this topic?
>>>>>>>
>>>>>>>
>>>>>>> Is there something else that we can do to help solving this issue?
>>>>>>
>>>>>> In the case of CONFIG_USB_MUSB_DUAL_ROLE=y and dr_mode=otg, how is the
>>>>>> gadget driver configured? It has to be a module not built-in.
>>>>>
>>>>> Indeed when I configured CONFIG_USB_MUSB_HDRC=m and CONFIG_USB_MUSB_DSPS=m
>>>>> it worked seamless.
>>>>>
>>>>
>>>> Actually it didn't worked. And now sometimes I even received continuously
>>>> the following message:
>>>>
>>>>  musb_bus_suspend 2484: trying to suspend as a_wait_vfall while active
>>>
>>> this is likely because your VBUS hasn't dropped below 0.8V fast enough.
>>>
>>> I could only trigger this message in that situation. Use a scope to poke
>>> at VBUS and see how long is takes to reach 0.8V, this could all be cause
>>> by too much capacitance on VBUS line.
>>
>> We got some news:
>> "The capacitance on VBUS due to components is 200nF and the additional parasitic
>> capacitance will be much smaller than this"
>>
>> The rail discharge time is ~36ms when an USB drive is removed from the OTG adapter.
>> I attached a capture of this.
>>
>> What do you think about these values?
>>
>>
>> However, "there appears to be a considerable delay between the removal of a usb
>> drive and the initiation of the VBUS discharge (maybe ~1 second, I wasn't able
>> to measure this time)."
> 
> yeah, this is really weird. I can't think of anything that would make
> VBUS discharge slower from a SW point of view. Once you remove the
> cable, VBUS is physically removed and there's nothing else charging it.

I have more feedback about it: "When I look at it on the oscilloscope
this isn't a 'slow discharge' like a slowly draining capacitor, it is
a delay between the removal of a device and the initiation of the
discharge.  The discharge itself is quite fast once it begins, it just
seems as if the SOC/driver is taking a long time to notice the cable
is disconnected. At this stage, this isn't actually a problem, just
odd."

While working on this issue we found that the
tg_state_a_wait_vrise_timeout case seemed not managed by musb_dsps
driver. I've just submitted a patch for it:
https://lkml.org/lkml/2015/8/20/507

I made most of my test on a 3.17 kernel and today by using a 4.1
kernel with the patch I have submitted I didn't manage to reproduce
the issue. I saw that since 3.17, there were some patches related to
the babble interrupts; so maybe it was enough to fix the issue we saw.
It is still weird because one month ago I also tested with a 4.1
kernel and I had issues...

It needs more testing to see if it is really fixed because the issue
comes only time to time. I will keep you inform about our last tests.


Thanks,

Gregory


-- 
Gregory Clement, Free Electrons
Kernel, drivers, real-time and embedded Linux
development, consulting, training and support.
http://free-electrons.com


From vthakkar1994 at gmail.com  Thu Aug 20 09:41:15 2015
From: vthakkar1994 at gmail.com (Vaishali Thakkar)
Date: Thu, 20 Aug 2015 22:11:15 +0530
Subject: [PATCH] ASoC: Samsung: Remove redundant arndale_audio_remove
Message-ID: <20150820164115.GA19191@localhost>

There is no use of snd_soc_unregister_card in remove function
as devm_snd_soc_register_card in probe function automatically
handles it. So, remove use of snd_soc_unregister_card and with
this change remove arndale_audio_remove as it is now redundant.

Signed-off-by: Vaishali Thakkar <vthakkar1994 at gmail.com>
---
 sound/soc/samsung/arndale_rt5631.c | 10 ----------
 1 file changed, 10 deletions(-)

diff --git a/sound/soc/samsung/arndale_rt5631.c b/sound/soc/samsung/arndale_rt5631.c
index 8bf2e2c..9e371eb 100644
--- a/sound/soc/samsung/arndale_rt5631.c
+++ b/sound/soc/samsung/arndale_rt5631.c
@@ -116,15 +116,6 @@ static int arndale_audio_probe(struct platform_device *pdev)
 	return ret;
 }
 
-static int arndale_audio_remove(struct platform_device *pdev)
-{
-	struct snd_soc_card *card = platform_get_drvdata(pdev);
-
-	snd_soc_unregister_card(card);
-
-	return 0;
-}
-
 static const struct of_device_id samsung_arndale_rt5631_of_match[] __maybe_unused = {
 	{ .compatible = "samsung,arndale-rt5631", },
 	{ .compatible = "samsung,arndale-alc5631", },
@@ -139,7 +130,6 @@ static struct platform_driver arndale_audio_driver = {
 		.of_match_table = of_match_ptr(samsung_arndale_rt5631_of_match),
 	},
 	.probe = arndale_audio_probe,
-	.remove = arndale_audio_remove,
 };
 
 module_platform_driver(arndale_audio_driver);
-- 
1.9.1



From balbi at ti.com  Thu Aug 20 09:46:56 2015
From: balbi at ti.com (Felipe Balbi)
Date: Thu, 20 Aug 2015 11:46:56 -0500
Subject: MUSB dual-role on AM335x behaving weirdly
In-Reply-To: <55D601C5.40608@free-electrons.com>
References: <20150526145118.GD26599@saruman.tx.rr.com>
 <20150527094205.GO3199@piout.net>
 <5594E56B.3040200@free-electrons.com>
 <CADYTM3ZF5m++N1NqmOJoH5agbYrzpvSbLnuLVgttxwzdzwmGwQ@mail.gmail.com>
 <55C0B954.3020106@free-electrons.com>
 <55C0CAC6.3020603@free-electrons.com>
 <20150804193257.GF9623@saruman.tx.rr.com>
 <55D326BD.2030706@free-electrons.com>
 <20150818141334.GC9143@saruman.tx.rr.com>
 <55D601C5.40608@free-electrons.com>
Message-ID: <20150820164656.GA4938@saruman.tx.rr.com>

On Thu, Aug 20, 2015 at 06:35:17PM +0200, Gregory CLEMENT wrote:
> Hi Felipe,
> 
> On 18/08/2015 16:13, Felipe Balbi wrote:
> > Hi,
> > 
> > On Tue, Aug 18, 2015 at 02:36:13PM +0200, Gregory CLEMENT wrote:
> >> Hi again Felipe,
> >>
> >> I sent this email again without the capture because it prevented to be delivered
> >> to the mailing lists.
> >>
> >> On 04/08/2015 21:32, Felipe Balbi wrote:
> >>> On Tue, Aug 04, 2015 at 04:23:02PM +0200, Gregory CLEMENT wrote:
> >>>> Hi again,
> >>>> On 04/08/2015 15:08, Gregory CLEMENT wrote:
> >>>>> Hi Bin,
> >>>>>
> >>>>> On 02/07/2015 19:05, Bin Liu wrote:
> >>>>>> Hi,
> >>>>>>
> >>>>>> On Thu, Jul 2, 2015 at 2:16 AM, Gregory CLEMENT
> >>>>>> <gregory.clement at free-electrons.com> wrote:
> >>>>>>> Hi Felipe,
> >>>>>>>
> >>>>>>> On 27/05/2015 11:42, Alexandre Belloni wrote:
> >>>>>>>> Hi,
> >>>>>>>>
> >>>>>>>> On 26/05/2015 at 09:51:18 -0500, Felipe Balbi wrote :
> >>>>>>>>> On Thu, May 14, 2015 at 04:36:33PM -0500, Bin Liu wrote:
> >>>>>>>>>> Alexandre,
> >>>>>>>>>>
> >>>>>>>>>> On Thu, May 14, 2015 at 4:26 PM, Alexandre Belloni
> >>>>>>>>>> <alexandre.belloni at free-electrons.com> wrote:
> >>>>>>>>>>> On 14/05/2015 at 16:16:12 -0500, Bin Liu wrote :
> >>>>>>>>>>>> I think I found the root cause of the problem: board design issue - I
> >>>>>>>>>>>> bet the custom board has too much cap on VBUS line. It should be <
> >>>>>>>>>>>> 10uF.
> >>>>>>>>>>>>
> >>>>>>>>>>>
> >>>>>>>>>>> We have a custom board that exhibits the issue but it only has a 100nF
> >>>>>>>>>>> cap on VBUS.
> >>>>>>>>>>
> >>>>>>>>>> Have you measured the VBUS discharging? Is there any way to share your
> >>>>>>>>>> schematics?
> >>>>>>>>>
> >>>>>>>>> Alexandre, any further comments ?
> >>>>>>>>>
> >>>>>>>>
> >>>>>>>> Yeah, I have just got more info.
> >>>>>>>>
> >>>>>>>> This is the relevant part of the schematic:
> >>>>>>>> http://free-electrons.com/~alexandre/usb.png
> >>>>>>>>
> >>>>>>>> The total VBUS capacitance is 200nF and the USB0 pins are connected
> >>>>>>>> directly to the AM3358 pins. U1 is actually not fitted.
> >>>>>>>>
> >>>>>>>> We didn't measure VBUS discharging but we observe the OTG pin sensing
> >>>>>>>> stops when plugging an OTG cable without any device.
> >>>>>>>
> >>>>>>> Do you have any news about this topic?
> >>>>>>>
> >>>>>>>
> >>>>>>> Is there something else that we can do to help solving this issue?
> >>>>>>
> >>>>>> In the case of CONFIG_USB_MUSB_DUAL_ROLE=y and dr_mode=otg, how is the
> >>>>>> gadget driver configured? It has to be a module not built-in.
> >>>>>
> >>>>> Indeed when I configured CONFIG_USB_MUSB_HDRC=m and CONFIG_USB_MUSB_DSPS=m
> >>>>> it worked seamless.
> >>>>>
> >>>>
> >>>> Actually it didn't worked. And now sometimes I even received continuously
> >>>> the following message:
> >>>>
> >>>>  musb_bus_suspend 2484: trying to suspend as a_wait_vfall while active
> >>>
> >>> this is likely because your VBUS hasn't dropped below 0.8V fast enough.
> >>>
> >>> I could only trigger this message in that situation. Use a scope to poke
> >>> at VBUS and see how long is takes to reach 0.8V, this could all be cause
> >>> by too much capacitance on VBUS line.
> >>
> >> We got some news:
> >> "The capacitance on VBUS due to components is 200nF and the additional parasitic
> >> capacitance will be much smaller than this"
> >>
> >> The rail discharge time is ~36ms when an USB drive is removed from the OTG adapter.
> >> I attached a capture of this.
> >>
> >> What do you think about these values?
> >>
> >>
> >> However, "there appears to be a considerable delay between the removal of a usb
> >> drive and the initiation of the VBUS discharge (maybe ~1 second, I wasn't able
> >> to measure this time)."
> > 
> > yeah, this is really weird. I can't think of anything that would make
> > VBUS discharge slower from a SW point of view. Once you remove the
> > cable, VBUS is physically removed and there's nothing else charging it.
> 
> I have more feedback about it: "When I look at it on the oscilloscope
> this isn't a 'slow discharge' like a slowly draining capacitor, it is
> a delay between the removal of a device and the initiation of the
> discharge.  The discharge itself is quite fast once it begins, it just
> seems as if the SOC/driver is taking a long time to notice the cable
> is disconnected. At this stage, this isn't actually a problem, just
> odd."
> 
> While working on this issue we found that the
> tg_state_a_wait_vrise_timeout case seemed not managed by musb_dsps
> driver. I've just submitted a patch for it:
> https://lkml.org/lkml/2015/8/20/507

cool, I'll test it next week. Good finding btw.

> I made most of my test on a 3.17 kernel and today by using a 4.1
> kernel with the patch I have submitted I didn't manage to reproduce
> the issue. I saw that since 3.17, there were some patches related to
> the babble interrupts; so maybe it was enough to fix the issue we saw.
> It is still weird because one month ago I also tested with a 4.1
> kernel and I had issues...
> 
> It needs more testing to see if it is really fixed because the issue
> comes only time to time. I will keep you inform about our last tests.

all right. Seems like we really need to turn some of those states
handling into a reusable (musb-specific) library.

-- 
balbi
-------------- next part --------------
A non-text attachment was scrubbed...
Name: signature.asc
Type: application/pgp-signature
Size: 819 bytes
Desc: Digital signature
URL: <http://lists.infradead.org/pipermail/linux-arm-kernel/attachments/20150820/dcebba1f/attachment.sig>

From balbi at ti.com  Thu Aug 20 09:48:08 2015
From: balbi at ti.com (Felipe Balbi)
Date: Thu, 20 Aug 2015 11:48:08 -0500
Subject: [PATCH v5 01/46] usb: gadget: encapsulate endpoint claiming
 mechanism
In-Reply-To: <55D6001E.3000504@hackerion.com>
References: <1438351258-31578-1-git-send-email-r.baldyga@samsung.com>
 <1438351258-31578-2-git-send-email-r.baldyga@samsung.com>
 <20150820153553.GD1639@saruman.tx.rr.com>
 <55D6001E.3000504@hackerion.com>
Message-ID: <20150820164808.GB4938@saruman.tx.rr.com>

On Thu, Aug 20, 2015 at 06:28:14PM +0200, Robert Baldyga wrote:
> Hi Felipe,
> 
> On 08/20/2015 05:35 PM, Felipe Balbi wrote:
> [...]
> >just letting you know that this regresses all gadget drivers making them
> >try to disable previously disabled endpoints and enable previously
> >enabled endpoints.
> >
> >I have a possible fix (see below) but then it shows a problem on the
> >host side when using with g_zero (see further below):
> >
> >commit 3b8932100aacb6cfbffe288ca93025d8b8430c00
> >Author: Felipe Balbi <balbi at ti.com>
> >Date:   Wed Aug 19 18:05:27 2015 -0500
> >
> >     usb: gadget: fix ep->claimed lifetime
> >
> >     In order to fix a regression introduced by commit
> >     cc476b42a39d ("usb: gadget: encapsulate endpoint
> >     claiming mechanism") we have to introduce a simple
> >     helper to check if a particular is enabled or not.
> >
> >     After that, we need to move ep->claimed lifetime to
> >     usb_ep_enable() and usb_ep_disable() since those
> >     are the only functions which actually enable and
> >     disable endpoints.
> >
> >     A follow-up patch will come to drop all driver_data
> >     checks from function drivers, since those are, now,
> >     pointless.
> >
> >     Fixes: cc476b42a39d ("usb: gadget: encapsulate endpoint
> >     	claiming mechanism")
> >     Cc: Robert Baldyga <r.baldyga at samsung.com>
> >     Signed-off-by: Felipe Balbi <balbi at ti.com>
> >
> >diff --git a/drivers/usb/gadget/epautoconf.c b/drivers/usb/gadget/epautoconf.c
> >index 978435a51038..ad45070cd76f 100644
> >--- a/drivers/usb/gadget/epautoconf.c
> >+++ b/drivers/usb/gadget/epautoconf.c
> >@@ -126,7 +126,6 @@ found_ep:
> >  	ep->address = desc->bEndpointAddress;
> >  	ep->desc = NULL;
> >  	ep->comp_desc = NULL;
> >-	ep->claimed = true;
> 
> Removing this line causes autoconfig can return the same endpoint many
> times. This probably causes problems with g_zero.
> 
> I will try to fix it ASAP.

I was considering the same thing, but the lifetime of ->claimed doesn't
look correct to me either way. Note that once the flag is enabled, it
won't get disabled by most gadget drivers.

-- 
balbi
-------------- next part --------------
A non-text attachment was scrubbed...
Name: signature.asc
Type: application/pgp-signature
Size: 819 bytes
Desc: Digital signature
URL: <http://lists.infradead.org/pipermail/linux-arm-kernel/attachments/20150820/e52d8009/attachment-0001.sig>

From ahs3 at redhat.com  Thu Aug 20 09:57:05 2015
From: ahs3 at redhat.com (Al Stone)
Date: Thu, 20 Aug 2015 10:57:05 -0600
Subject: [PATCH v2 2/5] ACPI / ARM64: remove usage of
 BAD_MADT_ENTRY/BAD_MADT_GICC_ENTRY
In-Reply-To: <20150820101322.GA19328@arm.com>
References: <1440022048-6285-1-git-send-email-al.stone@linaro.org>
 <1440022048-6285-3-git-send-email-al.stone@linaro.org>
 <20150820101322.GA19328@arm.com>
Message-ID: <55D606E1.4040804@redhat.com>

On 08/20/2015 04:13 AM, Will Deacon wrote:
> Hi Al,
> 
> On Wed, Aug 19, 2015 at 11:07:25PM +0100, Al Stone wrote:
>> Now that we have introduced the bad_madt_entry() function, and that
>> function is being invoked in acpi_table_parse_madt() for us, there
>> is no longer any need to use the BAD_MADT_ENTRY macro, or in the case
>> of arm64, the BAD_MADT_GICC_ENTRY, too.
>>
>> Signed-off-by: Al Stone <al.stone at linaro.org>
>> Acked-by: Catalin Marinas <catalin.marinas at arm.com>
>> Acked-by: Marc Zyngier <marc.zyngier at arm.com>
>> Cc: Will Deacon <will.deacon at arm.com>
>> Cc: Thomas Gleixner <tglx at linutronix.de>
>> Cc: Jason Cooper <jason at lakedaemon.net>
>> ---
>>  arch/arm64/include/asm/acpi.h | 8 --------
>>  arch/arm64/kernel/smp.c       | 2 --
>>  drivers/irqchip/irq-gic.c     | 6 ------
>>  3 files changed, 16 deletions(-)
> 
> How are you planning to merge this (and which kernel are you targetting?)
> You've got Acks for both arm64 and irqchip, so I guess either of those
> trees could take it.

Yeah, this is a little messy.  If I can get into 4.2, that would be nice,
but not required -- arm64 already has a usable patch for now, and that's
the only arch affected.  So, 4.3 was my primary target (which is why I
worked with linux-next for these).

Which tree?  Yeesh.  1/5 and 5/5 are ACPI only and required for the rest
to work properly; 2/5 is arm64, 3/5 is ia64, and 4/5 is x86.  ARM folks are
the only ones to have provided acks or reviews, however.  I guess I was
assuming this would have to go in via Rafael's ACPI tree since those are
the key parts -- the arch-specific patches would remove safety checks on
MADT subtables without replacing them, if they went in before the ACPI
patches.

Does that make sense?  What do you think?

-- 
ciao,
al
-----------------------------------
Al Stone
Software Engineer
Red Hat, Inc.
ahs3 at redhat.com
-----------------------------------


From horia.geanta at freescale.com  Thu Aug 20 09:58:36 2015
From: horia.geanta at freescale.com (=?UTF-8?Q?Horia_Geant=c4=83?=)
Date: Thu, 20 Aug 2015 19:58:36 +0300
Subject: [PATCH v3] ARM: configs: Add Freescale LS1021A defconfig
In-Reply-To: <BN3PR0301MB08672520CA978383BBF2CF6CFE790@BN3PR0301MB0867.namprd03.prod.outlook.com>
References: <1438941784-38403-1-git-send-email-b18965@freescale.com>
 <55CB4829.40204@freescale.com> <55CE1FFE.2080200@freescale.com>
 <CAOMZO5By_15OCsb7z2pbywPi3n9vKGj=393hWYHVEQ32=jDNaA@mail.gmail.com>
 <BN3PR0301MB08672520CA978383BBF2CF6CFE790@BN3PR0301MB0867.namprd03.prod.outlook.com>
Message-ID: <55D6073C.1020000@freescale.com>

On 8/17/2015 6:42 AM, Wang Huan-B18965 wrote:
> Hi, Fabio,

Please don't top post.

> 
> 	Based on the analysis and discussion, we prefer to use ls1021a_defconfig and remove LS1021A from imx_v6_v7_defconfig.

Alison, when you submit v4 for this patch (adding
CONFIG_ARCH_DMA_ADDR_T_64BIT=y as suggested), could you also send a
patch removing CONFIG_SOC_LS1021A from imx_v6_v7_config?

> 
> 	Thanks.
> 
> Best Regards,
> Alison Wang
> 
>> On Fri, Aug 14, 2015 at 2:06 PM, Horia Geant?
>> <horia.geanta at freescale.com> wrote:
>>
>>> Another thing:
>>> Commit 385c0fb0e2c4 ("ARM: imx_v6_v7_defconfig: Select LS1021A")
>> added
>>> CONFIG_SOC_LS1021A in imx_v6_v7_defconfig.
>>>
>>> Besides this, booting a LS1021 AQDS board (Rev2) using
>>> imx_v6_v7_defconfig did not work (stuck at "Starting kernel").
>>
>> What would be the recommended approach?
>>
>> - Fix imx_v6_v7_defconfig so that it can make LS1021A to boot
>>
>> or
>>
>> - Use this proposed ls1021a_defconfig and remove LS1021A from
>> imx_v6_v7_defconfig?
>>
>> Regards,
>>
>> Fabio Estevam




From broonie at kernel.org  Thu Aug 20 10:02:11 2015
From: broonie at kernel.org (Mark Brown)
Date: Thu, 20 Aug 2015 10:02:11 -0700
Subject: [PATCH v3 0/8] ARM: sunxi: Add Reduced Serial Bus support
In-Reply-To: <CAGb2v66X-CMQiS1dNqhwamTsVbnf+7siSTV3xGwn-C91Zhw3uA@mail.gmail.com>
References: <1439958009-14056-1-git-send-email-wens@csie.org>
 <20150819163232.GS10748@sirena.org.uk>
 <CAGb2v66X-CMQiS1dNqhwamTsVbnf+7siSTV3xGwn-C91Zhw3uA@mail.gmail.com>
Message-ID: <20150820170211.GB12027@sirena.org.uk>

On Thu, Aug 20, 2015 at 09:59:27AM +0800, Chen-Yu Tsai wrote:
> On Thu, Aug 20, 2015 at 12:32 AM, Mark Brown <broonie at kernel.org> wrote:

> > This is flagged as something that is specific to the Allwinner SoCs.
> > Why add generic regmap support rather than just implement the regmap
> > reg_read() and reg_write() in a regmap in the controller driver?  Are
> > there expected to be other controller drivers from other vendors?

> I don't expect there to be any other controller drivers. And it seems
> at least some of the devices are dual interface (I2C/RSB). Though I
> don't see how its connected to the generic regmap support. Regmap
> is for device drivers connected to the RSB bus, not the bus controller
> itself.

The point here is that you can use regmap for a custom controller
without having to implement a bus, to repeat what I said:

| > Why add generic regmap support rather than just implement the regmap
| > reg_read() and reg_write() in a regmap in the controller driver?  Are

> I could throw all the RSB-related stuff together, presumably under
> drivers/soc/sunxi/rsb, though that doesn't help the fact that common
> regmap code would be  better than scattering regmap_* in various mfd
> drivers.

If there is only one controller driver you just have a single call into
that driver in the client device which gives you the same level of
shared code, having a wrapper layer in regmap that puts regmap_
functions around the equivalent controller specific functions isn't
really adding a huge amount.

It's a similar thing to the way we just reuse the platform bus for basic
buses rather than copying it to make new bus types, we don't need to
create lots of new boilerplate regmap types that are just really basic
wrappers.  There are a lot of these custom buses that people have.
-------------- next part --------------
A non-text attachment was scrubbed...
Name: signature.asc
Type: application/pgp-signature
Size: 473 bytes
Desc: Digital signature
URL: <http://lists.infradead.org/pipermail/linux-arm-kernel/attachments/20150820/7be80764/attachment.sig>

From broonie at kernel.org  Thu Aug 20 10:05:35 2015
From: broonie at kernel.org (Mark Brown)
Date: Thu, 20 Aug 2015 10:05:35 -0700
Subject: [PATCH v3 3/8] rsb: Linux driver framework for Reduced Serial
 Bus (RSB)
In-Reply-To: <1439958009-14056-4-git-send-email-wens@csie.org>
References: <1439958009-14056-1-git-send-email-wens@csie.org>
 <1439958009-14056-4-git-send-email-wens@csie.org>
Message-ID: <20150820170535.GC12027@sirena.org.uk>

On Wed, Aug 19, 2015 at 12:20:04PM +0800, Chen-Yu Tsai wrote:

> Reduced Serial Bus (RSB) is an Allwinner proprietery interface
> used to communicate with PMICs and other peripheral ICs.

>  drivers/rsb/Kconfig    |  11 ++
>  drivers/rsb/Makefile   |   4 +
>  drivers/rsb/rsb-core.c | 511 +++++++++++++++++++++++++++++++++++++++++++++++++

Based on the changelog and what you were saying in your other mail about
this being very Allwinner specific I think the current trend would be to
put this into drivers/soc rather than making a new top level directory
in drivers.
-------------- next part --------------
A non-text attachment was scrubbed...
Name: signature.asc
Type: application/pgp-signature
Size: 473 bytes
Desc: Digital signature
URL: <http://lists.infradead.org/pipermail/linux-arm-kernel/attachments/20150820/1133c6fa/attachment.sig>

From vichy.kuo at gmail.com  Thu Aug 20 10:09:23 2015
From: vichy.kuo at gmail.com (vichy)
Date: Fri, 21 Aug 2015 01:09:23 +0800
Subject: is it possible to liimit the softirq re entrance times
Message-ID: <CAOVJa8FfHWGVf=ccXFCyTUD5YHrMAAeQ9Tkg1ipHA=J_CyVAHQ@mail.gmail.com>

After I tracing softirq flow in ARM platform, I have some colusion like below:
1. softirq is running at the end of any irq context, when irq is eabled.
2. as long as any Hard irq happen, softirq can be interrupt and reentrant

My question are:
1. in __do_sofiq, there is a jiffies setting to make sure the whole
softirq will not took to long.
But in my case is there any many hard irq happen like below

                        trace_softirq_entry(vec_nr);    ------a
                        h->action(h);
                        trace_softirq_exit(vec_nr);      ---------b

from lttng, I see there 100 interrupt happen from entry to exit.

is there kernel config or module parameter to let me down grade the
hard irq count from 100  --> 80 or 90 and event can controlled me.
I don't mean I control the count of hard irq, but I found this softirq
is interrupt by 80 times.
then I will not enable_irq until I finished the job.

if no, isn't it possible to make starvation in above a and b?

really appreciate ur kind help,


From r.baldyga at hackerion.com  Thu Aug 20 10:16:48 2015
From: r.baldyga at hackerion.com (Robert Baldyga)
Date: Thu, 20 Aug 2015 19:16:48 +0200
Subject: [PATCH v5 01/46] usb: gadget: encapsulate endpoint claiming
 mechanism
In-Reply-To: <20150820164808.GB4938@saruman.tx.rr.com>
References: <1438351258-31578-1-git-send-email-r.baldyga@samsung.com>
 <1438351258-31578-2-git-send-email-r.baldyga@samsung.com>
 <20150820153553.GD1639@saruman.tx.rr.com> <55D6001E.3000504@hackerion.com>
 <20150820164808.GB4938@saruman.tx.rr.com>
Message-ID: <55D60B80.7040800@hackerion.com>

On 08/20/2015 06:48 PM, Felipe Balbi wrote:
> On Thu, Aug 20, 2015 at 06:28:14PM +0200, Robert Baldyga wrote:
>> Hi Felipe,
>>
>> On 08/20/2015 05:35 PM, Felipe Balbi wrote:
>> [...]
>>> just letting you know that this regresses all gadget drivers making them
>>> try to disable previously disabled endpoints and enable previously
>>> enabled endpoints.
>>>
>>> I have a possible fix (see below) but then it shows a problem on the
>>> host side when using with g_zero (see further below):
>>>
>>> commit 3b8932100aacb6cfbffe288ca93025d8b8430c00
>>> Author: Felipe Balbi <balbi at ti.com>
>>> Date:   Wed Aug 19 18:05:27 2015 -0500
>>>
>>>      usb: gadget: fix ep->claimed lifetime
>>>
>>>      In order to fix a regression introduced by commit
>>>      cc476b42a39d ("usb: gadget: encapsulate endpoint
>>>      claiming mechanism") we have to introduce a simple
>>>      helper to check if a particular is enabled or not.
>>>
>>>      After that, we need to move ep->claimed lifetime to
>>>      usb_ep_enable() and usb_ep_disable() since those
>>>      are the only functions which actually enable and
>>>      disable endpoints.
>>>
>>>      A follow-up patch will come to drop all driver_data
>>>      checks from function drivers, since those are, now,
>>>      pointless.
>>>
>>>      Fixes: cc476b42a39d ("usb: gadget: encapsulate endpoint
>>>      	claiming mechanism")
>>>      Cc: Robert Baldyga <r.baldyga at samsung.com>
>>>      Signed-off-by: Felipe Balbi <balbi at ti.com>
>>>
>>> diff --git a/drivers/usb/gadget/epautoconf.c b/drivers/usb/gadget/epautoconf.c
>>> index 978435a51038..ad45070cd76f 100644
>>> --- a/drivers/usb/gadget/epautoconf.c
>>> +++ b/drivers/usb/gadget/epautoconf.c
>>> @@ -126,7 +126,6 @@ found_ep:
>>>   	ep->address = desc->bEndpointAddress;
>>>   	ep->desc = NULL;
>>>   	ep->comp_desc = NULL;
>>> -	ep->claimed = true;
>>
>> Removing this line causes autoconfig can return the same endpoint many
>> times. This probably causes problems with g_zero.
>>
>> I will try to fix it ASAP.
>
> I was considering the same thing, but the lifetime of ->claimed doesn't
> look correct to me either way. Note that once the flag is enabled, it
> won't get disabled by most gadget drivers.

And it should not be. This flag is indicator, that endpoint is used by 
some function. It should be set once by usb_ep_autoconfig() and cleared 
by usb_ep_autoconfig_reset().

I wonder what is reason of this enable/disable regression. Maybe the 
problem is that we don't set ep->driver_data to NULL in 
usb_ep_autoconfig_reset() (so far it was done). Does this problem occur 
while gadget is binded to UDC for the first time, or at any next time? 
Unfortunately at this moment I don't have access to my hardware, so it 
will take a moment before I will setup some testing environment.

Thanks,
Robert



From agross at codeaurora.org  Thu Aug 20 10:20:10 2015
From: agross at codeaurora.org (Andy Gross)
Date: Thu, 20 Aug 2015 12:20:10 -0500
Subject: [PATCH] ARM: Set proper TEXT_OFFSET for IPQ806x
In-Reply-To: <20150820130005.GS7557@n2100.arm.linux.org.uk>
References: <20150820121541.GA14664@codeaurora.org>
 <20150820130005.GS7557@n2100.arm.linux.org.uk>
Message-ID: <20150820172010.GB10796@qualcomm.com>

On Thu, Aug 20, 2015 at 02:00:06PM +0100, Russell King - ARM Linux wrote:
> On Thu, Aug 20, 2015 at 05:45:41PM +0530, Varadarajan Narayanan wrote:
> > RAM starts at 0x40000000 for IPQ. The lower 21MB of RAM is used
> > for Shared Memory and the kernel can start from 0x41500000.
> 
> Why do people keep creating crap like this?  Each time something like
> this is created, it means that you _need_ to have a special kernel for
> your platform and you can't be part of the single zImage.
> 
> Please, rather than creating crap like this, find a better way.

In the case of the IPQ, we don't use the zImage because the decompress requires
a larger jump than we can do on that platform.  Having this change at least gets
us back 2MB of memory.

-- 
Qualcomm Innovation Center, Inc.
The Qualcomm Innovation Center, Inc. is a member of the Code Aurora Forum,
a Linux Foundation Collaborative Project



From mark.rutland at arm.com  Thu Aug 20 10:23:08 2015
From: mark.rutland at arm.com (Mark Rutland)
Date: Thu, 20 Aug 2015 18:23:08 +0100
Subject: [PATCHv2] arm64: dts: Add base stratix 10 dtsi
In-Reply-To: <1439308127-7412-1-git-send-email-dinguyen@opensource.altera.com>
References: <1439308127-7412-1-git-send-email-dinguyen@opensource.altera.com>
Message-ID: <20150820172308.GA2711@svinekod>

Hi,

> +/ {
> +	compatible = "altr,socfpga-stratix10";
> +	#address-cells = <1>;
> +	#size-cells = <1>;

I would recommend that you make your root #address-cells and #size-cells equal
to 2, as that will simplify matters later if/when you need to add anything
beyond the first 4GB for some particular board.

If everything in the SoC falls within the first 4GB you can have a ranges
property on your /soc node and have only one cell below that.

[...]

> +	intc: intc at ffff8000 {

The unit-address doesn't match the first address in the reg entry.

> +		compatible = "arm,gic-400", "arm,cortex-a15-gic";
> +		#interrupt-cells = <3>;
> +		interrupt-controller;
> +		reg = <0x0 0xffff9000 0x1000>,
> +		      <0x0 0xffffa000 0x2000>,
> +		      <0x0 0xffffc000 0x1000>,
> +		      <0x0 0xffffd000 0x1000>;
> +	};

Shouldn't the virtual CPU interface also be 0x2000 long?

Mark.


From robert.jarzmik at free.fr  Thu Aug 20 10:23:50 2015
From: robert.jarzmik at free.fr (Robert Jarzmik)
Date: Thu, 20 Aug 2015 19:23:50 +0200
Subject: [PATCH v2 12/21] ARM: pxa: magician: Add PXA27x UDC support
References: <cover.1439843482.git.petr.cvek@tul.cz> <55D25A06.9030507@tul.cz>
Message-ID: <87twrt6fh5.fsf@belgarion.home>

Petr Cvek <petr.cvek at tul.cz> writes:

> Add support for PXA27x UDC to HTC Magician.
>
> Signed-off-by: Petr Cvek <petr.cvek at tul.cz>
> ---
>  arch/arm/mach-pxa/magician.c | 40 +++++++++++++++++++++++++++++++++++++++-
>  1 file changed, 39 insertions(+), 1 deletion(-)
>
> diff --git a/arch/arm/mach-pxa/magician.c b/arch/arm/mach-pxa/magician.c
> index 8ca0b67..23b59a0 100644
> --- a/arch/arm/mach-pxa/magician.c
> +++ b/arch/arm/mach-pxa/magician.c
> @@ -98,6 +98,10 @@
>  
>  #include <linux/regulator/max1586.h>
>  
> +#include <linux/platform_data/pxa2xx_udc.h>
> +#include <mach/udc.h>
> +#include <mach/pxa27x-udc.h>
> +
>  #include "devices.h"
>  #include "generic.h"
>  
> @@ -698,6 +702,34 @@ static struct platform_device magician_camera = {
>   * USB "Transceiver"
>   */
>  
> +#if IS_ENABLED(CONFIG_USB_PXA27X)
No #if please, just let it out of #ifdefery, no need to.

> +static void magician_udc_command(int cmd)
> +{
> +	if (cmd == PXA2XX_UDC_CMD_CONNECT)
> +		UP2OCR |= UP2OCR_DPPUE | UP2OCR_DPPUBE;
> +	else if (cmd == PXA2XX_UDC_CMD_DISCONNECT)
> +		UP2OCR &= ~(UP2OCR_DPPUE | UP2OCR_DPPUBE);
> +}
> +
> +/* HACK, shared USB connected state with pda-power */
> +int my_usb_online = 1;
Definitely not, a global (ie. non static variable) is not something I'll let
in. Besides, can't a "gpio_get_value()" give the same level of information ?

> +static int magician_udc_is_connected(void)
> +{
> +	/* Shared with pda_power or gpio-vbus */
> +	return my_usb_online;
gpio_get_value() something ?

> +}
> +
> +static struct pxa2xx_udc_mach_info magician_udc_info __initdata = {
> +	.udc_command		= magician_udc_command,
> +	.udc_is_connected	= magician_udc_is_connected,
I don't think udc_is_connected is a field used by pxa27x_udc.c, it it ? The VBus
connection information comes from a transciever, usually from gpio_vbus driver
nowadays.

> @@ -1175,6 +1207,11 @@ static struct platform_device *devices[] __initdata = {
>  
>  	/* NOTICE mutually exclusive with PXA I2C */
>  	&i2c_gpio_bus_alt,
> +
> +	/* NOTICE mutually exclusive with UDC*/
Euh why so ?
In arch/arm/mach-pxa/mioa701.c they cooperate, why can't they for magician ?

Cheers.

-- 
Robert


From balbi at ti.com  Thu Aug 20 10:44:09 2015
From: balbi at ti.com (Felipe Balbi)
Date: Thu, 20 Aug 2015 12:44:09 -0500
Subject: [PATCH v5 01/46] usb: gadget: encapsulate endpoint claiming
 mechanism
In-Reply-To: <55D60B80.7040800@hackerion.com>
References: <1438351258-31578-1-git-send-email-r.baldyga@samsung.com>
 <1438351258-31578-2-git-send-email-r.baldyga@samsung.com>
 <20150820153553.GD1639@saruman.tx.rr.com>
 <55D6001E.3000504@hackerion.com>
 <20150820164808.GB4938@saruman.tx.rr.com>
 <55D60B80.7040800@hackerion.com>
Message-ID: <20150820174409.GB7270@saruman.tx.rr.com>

Hi,

On Thu, Aug 20, 2015 at 07:16:48PM +0200, Robert Baldyga wrote:
> On 08/20/2015 06:48 PM, Felipe Balbi wrote:
> >On Thu, Aug 20, 2015 at 06:28:14PM +0200, Robert Baldyga wrote:
> >>Hi Felipe,
> >>
> >>On 08/20/2015 05:35 PM, Felipe Balbi wrote:
> >>[...]
> >>>just letting you know that this regresses all gadget drivers making them
> >>>try to disable previously disabled endpoints and enable previously
> >>>enabled endpoints.
> >>>
> >>>I have a possible fix (see below) but then it shows a problem on the
> >>>host side when using with g_zero (see further below):
> >>>
> >>>commit 3b8932100aacb6cfbffe288ca93025d8b8430c00
> >>>Author: Felipe Balbi <balbi at ti.com>
> >>>Date:   Wed Aug 19 18:05:27 2015 -0500
> >>>
> >>>     usb: gadget: fix ep->claimed lifetime
> >>>
> >>>     In order to fix a regression introduced by commit
> >>>     cc476b42a39d ("usb: gadget: encapsulate endpoint
> >>>     claiming mechanism") we have to introduce a simple
> >>>     helper to check if a particular is enabled or not.
> >>>
> >>>     After that, we need to move ep->claimed lifetime to
> >>>     usb_ep_enable() and usb_ep_disable() since those
> >>>     are the only functions which actually enable and
> >>>     disable endpoints.
> >>>
> >>>     A follow-up patch will come to drop all driver_data
> >>>     checks from function drivers, since those are, now,
> >>>     pointless.
> >>>
> >>>     Fixes: cc476b42a39d ("usb: gadget: encapsulate endpoint
> >>>     	claiming mechanism")
> >>>     Cc: Robert Baldyga <r.baldyga at samsung.com>
> >>>     Signed-off-by: Felipe Balbi <balbi at ti.com>
> >>>
> >>>diff --git a/drivers/usb/gadget/epautoconf.c b/drivers/usb/gadget/epautoconf.c
> >>>index 978435a51038..ad45070cd76f 100644
> >>>--- a/drivers/usb/gadget/epautoconf.c
> >>>+++ b/drivers/usb/gadget/epautoconf.c
> >>>@@ -126,7 +126,6 @@ found_ep:
> >>>  	ep->address = desc->bEndpointAddress;
> >>>  	ep->desc = NULL;
> >>>  	ep->comp_desc = NULL;
> >>>-	ep->claimed = true;
> >>
> >>Removing this line causes autoconfig can return the same endpoint many
> >>times. This probably causes problems with g_zero.
> >>
> >>I will try to fix it ASAP.
> >
> >I was considering the same thing, but the lifetime of ->claimed doesn't
> >look correct to me either way. Note that once the flag is enabled, it
> >won't get disabled by most gadget drivers.
> 
> And it should not be. This flag is indicator, that endpoint is used by some
> function. It should be set once by usb_ep_autoconfig() and cleared by
> usb_ep_autoconfig_reset().

have you considered switching interfaces and/or alternate settings ?

> I wonder what is reason of this enable/disable regression. Maybe the problem
> is that we don't set ep->driver_data to NULL in usb_ep_autoconfig_reset()
> (so far it was done). Does this problem occur while gadget is binded to UDC
> for the first time, or at any next time? Unfortunately at this moment I
> don't have access to my hardware, so it will take a moment before I will
> setup some testing environment.

yeah, that's okay. We've got time.

-- 
balbi
-------------- next part --------------
A non-text attachment was scrubbed...
Name: signature.asc
Type: application/pgp-signature
Size: 819 bytes
Desc: Digital signature
URL: <http://lists.infradead.org/pipermail/linux-arm-kernel/attachments/20150820/ed6f1b11/attachment.sig>

From jonmason at broadcom.com  Thu Aug 20 10:46:07 2015
From: jonmason at broadcom.com (Jon Mason)
Date: Thu, 20 Aug 2015 13:46:07 -0400
Subject: [PATCH 0/5] Add Broadcom Northstar Plus Support
Message-ID: <1440092767-25660-1-git-send-email-jonmason@broadcom.com>

This patch series adds support for the Broadcom Northstar Plus family of
SoCs.  NSP is a Cortex A9 based SoC under the Broadcom iProc family.

Jon Mason (5):
  dt-bindings: Create Documentation for NSP DT bindings
  ARM: NSP: add minimal Northstar Plus device tree
  ARM: NSP: Add basic support for Broadcom Northstar Plus SoC
  ARM: multi_v7_defconfig: Add NSP to defconfig
  MAINTAINERS: add entry for the Broadcom Northstar Plus SoCs

 .../devicetree/bindings/arm/bcm/brcm,nsp.txt       |  34 +++++++
 MAINTAINERS                                        |  12 ++-
 arch/arm/boot/dts/Makefile                         |   2 +
 arch/arm/boot/dts/bcm-nsp.dtsi                     | 105 +++++++++++++++++++++
 arch/arm/boot/dts/bcm958625k.dts                   |  57 +++++++++++
 arch/arm/configs/multi_v7_defconfig                |   1 +
 arch/arm/mach-bcm/Kconfig                          |  14 +++
 arch/arm/mach-bcm/Makefile                         |   5 +-
 arch/arm/mach-bcm/bcm_nsp.c                        |  25 +++++
 9 files changed, 252 insertions(+), 3 deletions(-)
 create mode 100644 Documentation/devicetree/bindings/arm/bcm/brcm,nsp.txt
 create mode 100644 arch/arm/boot/dts/bcm-nsp.dtsi
 create mode 100644 arch/arm/boot/dts/bcm958625k.dts
 create mode 100644 arch/arm/mach-bcm/bcm_nsp.c

-- 
1.9.1



From jonmason at broadcom.com  Thu Aug 20 10:46:29 2015
From: jonmason at broadcom.com (Jon Mason)
Date: Thu, 20 Aug 2015 13:46:29 -0400
Subject: [PATCH 1/5] dt-bindings: Create Documentation for NSP DT bindings
Message-ID: <1440092789-25693-1-git-send-email-jonmason@broadcom.com>

Add the documentation for the Broadcom Northstar Plus device tree
bindings.

Signed-off-by: Jon Mason <jonmason at broadcom.com>
Reviewed-by: Ray Jui <rjui at broadcom.com>
Reviewed-by: Scott Branden <sbranden at broadcom.com>
---
 .../devicetree/bindings/arm/bcm/brcm,nsp.txt       | 34 ++++++++++++++++++++++
 1 file changed, 34 insertions(+)
 create mode 100644 Documentation/devicetree/bindings/arm/bcm/brcm,nsp.txt

diff --git a/Documentation/devicetree/bindings/arm/bcm/brcm,nsp.txt b/Documentation/devicetree/bindings/arm/bcm/brcm,nsp.txt
new file mode 100644
index 0000000..eae53e4
--- /dev/null
+++ b/Documentation/devicetree/bindings/arm/bcm/brcm,nsp.txt
@@ -0,0 +1,34 @@
+Broadcom Northstar Plus device tree bindings
+--------------------------------------------
+
+Broadcom Northstar Plus family of SoCs are used for switching control
+and management applications as well as residential router/gateway
+applications. The SoC features dual core Cortex A9 ARM CPUs, integrating
+several peripheral interfaces including multiple Gigabit Ethernet PHYs,
+DDR3 memory, PCIE Gen-2, USB 2.0 and USB 3.0, serial and NAND flash,
+SATA and several other IO controllers.
+
+Boards with Northstar Plus SoCs shall have the following properties:
+
+Required root node property:
+
+BCM58522
+compatible = "brcm,bcm58522", "brcm,nsp";
+
+BCM58525
+compatible = "brcm,bcm58525", "brcm,nsp";
+
+BCM58535
+compatible = "brcm,bcm58535", "brcm,nsp";
+
+BCM58622
+compatible = "brcm,bcm58622", "brcm,nsp";
+
+BCM58623
+compatible = "brcm,bcm58623", "brcm,nsp";
+
+BCM58625
+compatible = "brcm,bcm58625", "brcm,nsp";
+
+BCM88312
+compatible = "brcm,bcm88312", "brcm,nsp";
-- 
1.9.1



From jonmason at broadcom.com  Thu Aug 20 10:46:44 2015
From: jonmason at broadcom.com (Jon Mason)
Date: Thu, 20 Aug 2015 13:46:44 -0400
Subject: [PATCH 2/5] ARM: NSP: add minimal Northstar Plus device tree
Message-ID: <1440092804-25726-1-git-send-email-jonmason@broadcom.com>

Add a very minimalistic set of Northstar Plus Device Tree files which
describes the SoC and the BCM958625 implementation.  The perpherials
described are:

ARM Cortex A9 CPU
2 8250 UARTs
ARM GIC
PL310 L2 Cache
ARM A9 Global timer

Signed-off-by: Jon Mason <jonmason at broadcom.com>
Signed-off-by: Kapil Hali <kapilh at broadcom.com>
Reviewed-by: Ray Jui <rjui at broadcom.com>
Reviewed-by: Scott Branden <sbranden at broadcom.com>
---
 arch/arm/boot/dts/Makefile       |   2 +
 arch/arm/boot/dts/bcm-nsp.dtsi   | 105 +++++++++++++++++++++++++++++++++++++++
 arch/arm/boot/dts/bcm958625k.dts |  57 +++++++++++++++++++++
 3 files changed, 164 insertions(+)
 create mode 100644 arch/arm/boot/dts/bcm-nsp.dtsi
 create mode 100644 arch/arm/boot/dts/bcm958625k.dts

diff --git a/arch/arm/boot/dts/Makefile b/arch/arm/boot/dts/Makefile
index 246473a..adb5732 100644
--- a/arch/arm/boot/dts/Makefile
+++ b/arch/arm/boot/dts/Makefile
@@ -82,6 +82,8 @@ dtb-$(CONFIG_ARCH_BCM_CYGNUS) += \
 dtb-$(CONFIG_ARCH_BCM_MOBILE) += \
 	bcm28155-ap.dtb \
 	bcm21664-garnet.dtb
+dtb-$(CONFIG_ARCH_BCM_NSP) += \
+	bcm958625k.dtb
 dtb-$(CONFIG_ARCH_BERLIN) += \
 	berlin2-sony-nsz-gs7.dtb \
 	berlin2cd-google-chromecast.dtb \
diff --git a/arch/arm/boot/dts/bcm-nsp.dtsi b/arch/arm/boot/dts/bcm-nsp.dtsi
new file mode 100644
index 0000000..77f9bfc
--- /dev/null
+++ b/arch/arm/boot/dts/bcm-nsp.dtsi
@@ -0,0 +1,105 @@
+/*
+ *  BSD LICENSE
+ *
+ *  Copyright(c) 2015 Broadcom Corporation.  All rights reserved.
+ *
+ *  Redistribution and use in source and binary forms, with or without
+ *  modification, are permitted provided that the following conditions
+ *  are met:
+ *
+ *    * Redistributions of source code must retain the above copyright
+ *      notice, this list of conditions and the following disclaimer.
+ *    * Redistributions in binary form must reproduce the above copyright
+ *      notice, this list of conditions and the following disclaimer in
+ *      the documentation and/or other materials provided with the
+ *      distribution.
+ *    * Neither the name of Broadcom Corporation nor the names of its
+ *      contributors may be used to endorse or promote products derived
+ *      from this software without specific prior written permission.
+ *
+ *  THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+ *  "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+ *  LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
+ *  A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
+ *  OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
+ *  SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
+ *  LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
+ *  DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
+ *  THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+ *  (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
+ *  OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ */
+
+#include <dt-bindings/interrupt-controller/arm-gic.h>
+#include <dt-bindings/interrupt-controller/irq.h>
+
+#include "skeleton.dtsi"
+
+/ {
+	compatible = "brcm,nsp";
+	model = "Broadcom Northstar Plus SoC";
+	interrupt-parent = <&gic>;
+
+	cpus {
+		#address-cells = <1>;
+		#size-cells = <0>;
+
+		cpu at 0 {
+			device_type = "cpu";
+			compatible = "arm,cortex-a9";
+			next-level-cache = <&L2>;
+			reg = <0x0>;
+		};
+	};
+
+	clocks {
+		#address-cells = <1>;
+		#size-cells = <1>;
+		ranges;
+
+		periph_clk: periph_clk {
+			compatible = "fixed-clock";
+			#clock-cells = <0>;
+			clock-frequency = <500000000>;
+		};
+	};
+
+	uart0: serial at 18000300 {
+		compatible = "ns16550a";
+		reg = <0x18000300 0x100>;
+		interrupts = <GIC_SPI 85 IRQ_TYPE_LEVEL_HIGH>;
+		clock-frequency = <62499840>;
+		status = "disabled";
+	};
+
+	uart1: serial at 18000400 {
+		compatible = "ns16550a";
+		reg = <0x18000400 0x100>;
+		interrupts = <GIC_SPI 85 IRQ_TYPE_LEVEL_HIGH>;
+		clock-frequency = <62499840>;
+		status = "disabled";
+	};
+
+	gic: interrupt-controller at 19021000 {
+		compatible = "arm,cortex-a9-gic";
+		#interrupt-cells = <3>;
+		#address-cells = <0>;
+		interrupt-controller;
+		reg = <0x19021000 0x1000>,
+		      <0x19020100 0x100>;
+	};
+
+	L2: l2-cache {
+		compatible = "arm,pl310-cache";
+		reg = <0x19022000 0x1000>;
+		cache-unified;
+		cache-level = <2>;
+	};
+
+	timer at 19020200 {
+		compatible = "arm,cortex-a9-global-timer";
+		reg = <0x19020200 0x100>;
+		interrupts = <GIC_PPI 11 IRQ_TYPE_LEVEL_HIGH>;
+		clocks = <&periph_clk>;
+	};
+};
diff --git a/arch/arm/boot/dts/bcm958625k.dts b/arch/arm/boot/dts/bcm958625k.dts
new file mode 100644
index 0000000..a1bc151
--- /dev/null
+++ b/arch/arm/boot/dts/bcm958625k.dts
@@ -0,0 +1,57 @@
+/*
+ *  BSD LICENSE
+ *
+ *  Copyright(c) 2015 Broadcom Corporation.  All rights reserved.
+ *
+ *  Redistribution and use in source and binary forms, with or without
+ *  modification, are permitted provided that the following conditions
+ *  are met:
+ *
+ *    * Redistributions of source code must retain the above copyright
+ *      notice, this list of conditions and the following disclaimer.
+ *    * Redistributions in binary form must reproduce the above copyright
+ *      notice, this list of conditions and the following disclaimer in
+ *      the documentation and/or other materials provided with the
+ *      distribution.
+ *    * Neither the name of Broadcom Corporation nor the names of its
+ *      contributors may be used to endorse or promote products derived
+ *      from this software without specific prior written permission.
+ *
+ *  THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+ *  "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+ *  LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
+ *  A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
+ *  OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
+ *  SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
+ *  LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
+ *  DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
+ *  THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+ *  (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
+ *  OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ */
+
+/dts-v1/;
+
+#include "bcm-nsp.dtsi"
+
+/ {
+	model = "NorthStar Plus SVK (BCM958625K)";
+	compatible = "brcm,bcm58625", "brcm,nsp";
+
+	aliases {
+		serial0 = &uart0;
+		serial1 = &uart1;
+	};
+
+	chosen {
+		stdout-path = "serial0:115200n8";
+	};
+
+	uart0: serial at 18000300 {
+		status = "okay";
+	};
+
+	uart1: serial at 18000400 {
+		status = "okay";
+	};
+};
-- 
1.9.1



From jonmason at broadcom.com  Thu Aug 20 10:47:05 2015
From: jonmason at broadcom.com (Jon Mason)
Date: Thu, 20 Aug 2015 13:47:05 -0400
Subject: [PATCH 3/5] ARM: NSP: Add basic support for Broadcom Northstar Plus
 SoC
Message-ID: <1440092825-25759-1-git-send-email-jonmason@broadcom.com>

Broadcom Northstar Plus family of SoCs are used for switching
control and management applications as well as residential
router/gateway applications. The SoC features dual core Cortex
A9 ARM CPUs, integrating several peripheral interfaces including
multiple Gigabit Ethernet PHYs, DDR3 memory, PCIE Gen-2, USB 2.0
and USB 3.0, serial and NAND flash, SATA and several other IO
controllers.

Signed-off-by: Jon Mason <jonmason at broadcom.com>
Signed-off-by: Kapil Hali <kapilh at broadcom.com>
Reviewed-by: Ray Jui <rjui at broadcom.com>
Reviewed-by: Scott Branden <sbranden at broadcom.com>
---
 arch/arm/mach-bcm/Kconfig   | 14 ++++++++++++++
 arch/arm/mach-bcm/Makefile  |  5 ++++-
 arch/arm/mach-bcm/bcm_nsp.c | 25 +++++++++++++++++++++++++
 3 files changed, 43 insertions(+), 1 deletion(-)
 create mode 100644 arch/arm/mach-bcm/bcm_nsp.c

diff --git a/arch/arm/mach-bcm/Kconfig b/arch/arm/mach-bcm/Kconfig
index 0ac9e4b3..22c85b1 100644
--- a/arch/arm/mach-bcm/Kconfig
+++ b/arch/arm/mach-bcm/Kconfig
@@ -35,6 +35,20 @@ config ARCH_BCM_CYGNUS
 	  BCM11300, BCM11320, BCM11350, BCM11360,
 	  BCM58300, BCM58302, BCM58303, BCM58305.
 
+config ARCH_BCM_NSP
+	bool "Broadcom Northstar Plus SoC Support" if ARCH_MULTI_V7
+	select ARCH_BCM_IPROC
+	select ARM_ERRATA_754322
+	select ARM_ERRATA_775420
+	help
+	  Support for Broadcom Northstar Plus SoC.
+	  Broadcom Northstar Plus family of SoCs are used for switching control
+	  and management applications as well as residential router/gateway
+	  applications. The SoC features dual core Cortex A9 ARM CPUs,
+	  integrating several peripheral interfaces including multiple Gigabit
+	  Ethernet PHYs, DDR3 memory, PCIE Gen-2, USB 2.0 and USB 3.0, serial and
+	  NAND flash, SATA and several other IO controllers.
+
 config ARCH_BCM_5301X
 	bool "Broadcom BCM470X / BCM5301X ARM SoC" if ARCH_MULTI_V7
 	select ARCH_BCM_IPROC
diff --git a/arch/arm/mach-bcm/Makefile b/arch/arm/mach-bcm/Makefile
index 4fb0da4..786d720 100644
--- a/arch/arm/mach-bcm/Makefile
+++ b/arch/arm/mach-bcm/Makefile
@@ -1,5 +1,5 @@
 #
-# Copyright (C) 2012-2014 Broadcom Corporation
+# Copyright (C) 2012-2015 Broadcom Corporation
 #
 # This program is free software; you can redistribute it and/or
 # modify it under the terms of the GNU General Public License as
@@ -13,6 +13,9 @@
 # Cygnus
 obj-$(CONFIG_ARCH_BCM_CYGNUS) +=  bcm_cygnus.o
 
+# Northstar Plus
+obj-$(CONFIG_ARCH_BCM_NSP) += bcm_nsp.o
+
 # BCM281XX
 obj-$(CONFIG_ARCH_BCM_281XX)	+= board_bcm281xx.o
 
diff --git a/arch/arm/mach-bcm/bcm_nsp.c b/arch/arm/mach-bcm/bcm_nsp.c
new file mode 100644
index 0000000..a1101a3
--- /dev/null
+++ b/arch/arm/mach-bcm/bcm_nsp.c
@@ -0,0 +1,25 @@
+/*
+ * Copyright (C) 2015 Broadcom Corporation
+ *
+ * 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 version 2.
+ *
+ * This program is distributed "as is" WITHOUT ANY WARRANTY of any
+ * kind, whether express or implied; without even the implied warranty
+ * of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ * GNU General Public License for more details.
+ */
+
+#include <asm/mach/arch.h>
+
+static const char *const bcm_nsp_dt_compat[] __initconst = {
+	"brcm,nsp",
+	NULL,
+};
+
+DT_MACHINE_START(NSP_DT, "Broadcom Northstar Plus SoC")
+	.l2c_aux_val	= 0,
+	.l2c_aux_mask	= ~0,
+	.dt_compat = bcm_nsp_dt_compat,
+MACHINE_END
-- 
1.9.1



From jonmason at broadcom.com  Thu Aug 20 10:47:22 2015
From: jonmason at broadcom.com (Jon Mason)
Date: Thu, 20 Aug 2015 13:47:22 -0400
Subject: [PATCH 4/5] ARM: multi_v7_defconfig: Add NSP to defconfig
Message-ID: <1440092842-25792-1-git-send-email-jonmason@broadcom.com>

Add the Broadcom Northstar Plus SoC to the multi_v7_defconfig

Signed-off-by: Jon Mason <jonmason at broadcom.com>
Reviewed-by: Ray Jui <rjui at broadcom.com>
Reviewed-by: Scott Branden <sbranden at broadcom.com>
---
 arch/arm/configs/multi_v7_defconfig | 1 +
 1 file changed, 1 insertion(+)

diff --git a/arch/arm/configs/multi_v7_defconfig b/arch/arm/configs/multi_v7_defconfig
index 5fd8df6..3fd46f7 100644
--- a/arch/arm/configs/multi_v7_defconfig
+++ b/arch/arm/configs/multi_v7_defconfig
@@ -25,6 +25,7 @@ CONFIG_SOC_SAMA5D3=y
 CONFIG_SOC_SAMA5D4=y
 CONFIG_ARCH_BCM=y
 CONFIG_ARCH_BCM_CYGNUS=y
+CONFIG_ARCH_BCM_NSP=y
 CONFIG_ARCH_BCM_21664=y
 CONFIG_ARCH_BCM_281XX=y
 CONFIG_ARCH_BCM_5301X=y
-- 
1.9.1



From jonmason at broadcom.com  Thu Aug 20 10:47:41 2015
From: jonmason at broadcom.com (Jon Mason)
Date: Thu, 20 Aug 2015 13:47:41 -0400
Subject: [PATCH 5/5] MAINTAINERS: add entry for the Broadcom Northstar Plus
 SoCs
Message-ID: <1440092861-25825-1-git-send-email-jonmason@broadcom.com>

Modify the iProc MAINTAINER to cover the Nortstar Plus SoCs, and add me
to the list of people responsible for it.

Signed-off-by: Jon Mason <jonmason at broadcom.com>
Reviewed-by: Scott Branden <sbranden at broadcom.com>
---
 MAINTAINERS | 12 ++++++++++--
 1 file changed, 10 insertions(+), 2 deletions(-)

diff --git a/MAINTAINERS b/MAINTAINERS
index a9ae6c1..4b851f5 100644
--- a/MAINTAINERS
+++ b/MAINTAINERS
@@ -2315,19 +2315,27 @@ L:	linux-scsi at vger.kernel.org
 S:	Supported
 F:	drivers/scsi/bnx2i/
 
-BROADCOM CYGNUS/IPROC ARM ARCHITECTURE
+BROADCOM IPROC ARM ARCHITECTURE
 M:	Ray Jui <rjui at broadcom.com>
 M:	Scott Branden <sbranden at broadcom.com>
+M:	Jon Mason <jonmason at broadcom.com>
 L:	linux-arm-kernel at lists.infradead.org (moderated for non-subscribers)
 L:	bcm-kernel-feedback-list at broadcom.com
 T:	git git://github.com/broadcom/cygnus-linux.git
 S:	Maintained
 N:	iproc
 N:	cygnus
+N:	nsp
 N:	bcm9113*
 N:	bcm9583*
-N:	bcm583*
+N:	bcm9585*
+N:	bcm9586*
+N:	bcm988312
 N:	bcm113*
+N:	bcm583*
+N:	bcm585*
+N:	bcm586*
+N:	bcm88312
 
 BROADCOM BRCMSTB GPIO DRIVER
 M:	Gregory Fong <gregory.0xf0 at gmail.com>
-- 
1.9.1



From broonie at kernel.org  Thu Aug 20 11:17:52 2015
From: broonie at kernel.org (Mark Brown)
Date: Thu, 20 Aug 2015 11:17:52 -0700
Subject: [PATCH v2 4/4] spi: mediatek: revise coding style
In-Reply-To: <1440062349-25513-5-git-send-email-leilk.liu@mediatek.com>
References: <1440062349-25513-1-git-send-email-leilk.liu@mediatek.com>
 <1440062349-25513-5-git-send-email-leilk.liu@mediatek.com>
Message-ID: <20150820181752.GH12027@sirena.org.uk>

On Thu, Aug 20, 2015 at 05:19:09PM +0800, Leilk Liu wrote:
> This patch revises littery coding style according to comments.

I can't understand this commit log, sorry - what are the comments that
are being addressed?

> -	reg_val |= (((high_time - 1) & 0xff) << SPI_CFG0_SCK_HIGH_OFFSET);
> -	reg_val |= (((low_time - 1) & 0xff) << SPI_CFG0_SCK_LOW_OFFSET);
> -	reg_val |= (((holdtime - 1) & 0xff) << SPI_CFG0_CS_HOLD_OFFSET);
> -	reg_val |= (((setuptime - 1) & 0xff) << SPI_CFG0_CS_SETUP_OFFSET);
> +	reg_val |= (((sck_time - 1) & 0xff) << SPI_CFG0_SCK_HIGH_OFFSET);
> +	reg_val |= (((sck_time - 1) & 0xff) << SPI_CFG0_SCK_LOW_OFFSET);
> +	reg_val |= (((cs_time - 1) & 0xff) << SPI_CFG0_CS_HOLD_OFFSET);
> +	reg_val |= (((cs_time - 1) & 0xff) << SPI_CFG0_CS_SETUP_OFFSET);

This isn't a coding style change this is (I think) renaming a bunch of
variables for some reason.
-------------- next part --------------
A non-text attachment was scrubbed...
Name: signature.asc
Type: application/pgp-signature
Size: 473 bytes
Desc: Digital signature
URL: <http://lists.infradead.org/pipermail/linux-arm-kernel/attachments/20150820/52c592c0/attachment-0001.sig>

From broonie at kernel.org  Thu Aug 20 11:20:00 2015
From: broonie at kernel.org (Mark Brown)
Date: Thu, 20 Aug 2015 11:20:00 -0700
Subject: [PATCH v2 1/5] regmap: Add missing comments about struct
 regmap_bus
In-Reply-To: <1440061956-29064-2-git-send-email-mpa@pengutronix.de>
References: <1440061956-29064-1-git-send-email-mpa@pengutronix.de>
 <1440061956-29064-2-git-send-email-mpa@pengutronix.de>
Message-ID: <20150820182000.GI12027@sirena.org.uk>

On Thu, Aug 20, 2015 at 11:12:32AM +0200, Markus Pargmann wrote:

>   * @async_write: Write operation which completes asynchronously, optional and
>   *               must serialise with respect to non-async I/O.
> + * @reg_write: Write operation for a register. Writes value to register.

This seems like documenation for the sake of filling in the blank :(  At
least distinguish it from async_write() please.
-------------- next part --------------
A non-text attachment was scrubbed...
Name: signature.asc
Type: application/pgp-signature
Size: 473 bytes
Desc: Digital signature
URL: <http://lists.infradead.org/pipermail/linux-arm-kernel/attachments/20150820/dcc2ce53/attachment.sig>

From broonie at kernel.org  Thu Aug 20 11:27:25 2015
From: broonie at kernel.org (Mark Brown)
Date: Thu, 20 Aug 2015 11:27:25 -0700
Subject: [PATCH v2 2/5] regmap: Fix regmap_bulk_write for bus writes
In-Reply-To: <1440061956-29064-3-git-send-email-mpa@pengutronix.de>
References: <1440061956-29064-1-git-send-email-mpa@pengutronix.de>
 <1440061956-29064-3-git-send-email-mpa@pengutronix.de>
Message-ID: <20150820182725.GJ12027@sirena.org.uk>

On Thu, Aug 20, 2015 at 11:12:33AM +0200, Markus Pargmann wrote:

> +	} else if (map->use_single_rw) {
> +		/*
> +		 * We need to handle bus writes separate to support val_bytes
> +		 * that are not powers of 2.
> +		 */

This comment is really hard to understand - the condition block we're in
is nothing to do with the number of val_bytes and the comment is just
making a statement, there's no why in there.
-------------- next part --------------
A non-text attachment was scrubbed...
Name: signature.asc
Type: application/pgp-signature
Size: 473 bytes
Desc: Digital signature
URL: <http://lists.infradead.org/pipermail/linux-arm-kernel/attachments/20150820/01c16aa5/attachment.sig>

From broonie at kernel.org  Thu Aug 20 11:28:27 2015
From: broonie at kernel.org (Mark Brown)
Date: Thu, 20 Aug 2015 11:28:27 -0700
Subject: [PATCH v2 3/5] regmap: Split use_single_rw internally into
 use_single_read/write
In-Reply-To: <1440061956-29064-4-git-send-email-mpa@pengutronix.de>
References: <1440061956-29064-1-git-send-email-mpa@pengutronix.de>
 <1440061956-29064-4-git-send-email-mpa@pengutronix.de>
Message-ID: <20150820182827.GK12027@sirena.org.uk>

On Thu, Aug 20, 2015 at 11:12:34AM +0200, Markus Pargmann wrote:
> use_single_rw currently reflects the capabilities of the connected
> device. The capabilities of the bus are currently missing for this
> variable.

This is fine but depends on the previous patch.
-------------- next part --------------
A non-text attachment was scrubbed...
Name: signature.asc
Type: application/pgp-signature
Size: 473 bytes
Desc: Digital signature
URL: <http://lists.infradead.org/pipermail/linux-arm-kernel/attachments/20150820/506dc5fa/attachment.sig>

From broonie at kernel.org  Thu Aug 20 11:30:03 2015
From: broonie at kernel.org (Mark Brown)
Date: Thu, 20 Aug 2015 11:30:03 -0700
Subject: [PATCH v2 4/5] regmap: regmap_raw_read return error on !bus->read
In-Reply-To: <1440061956-29064-5-git-send-email-mpa@pengutronix.de>
References: <1440061956-29064-1-git-send-email-mpa@pengutronix.de>
 <1440061956-29064-5-git-send-email-mpa@pengutronix.de>
Message-ID: <20150820183003.GL12027@sirena.org.uk>

On Thu, Aug 20, 2015 at 11:12:35AM +0200, Markus Pargmann wrote:
> Return -ENOTSUPP if map->bus->read is not implemented and we do not use
> the cache. This code path would directly use bus->read would run into an
> NULL pointer for the read function.

Please put fixes like this before coding style changes like patch 3.
-------------- next part --------------
A non-text attachment was scrubbed...
Name: signature.asc
Type: application/pgp-signature
Size: 473 bytes
Desc: Digital signature
URL: <http://lists.infradead.org/pipermail/linux-arm-kernel/attachments/20150820/e1056c60/attachment.sig>

From broonie at kernel.org  Thu Aug 20 11:32:13 2015
From: broonie at kernel.org (Mark Brown)
Date: Thu, 20 Aug 2015 11:32:13 -0700
Subject: [PATCH v2 5/5] regmap: No multi_write support if bus->write does
 not exist
In-Reply-To: <1440061956-29064-6-git-send-email-mpa@pengutronix.de>
References: <1440061956-29064-1-git-send-email-mpa@pengutronix.de>
 <1440061956-29064-6-git-send-email-mpa@pengutronix.de>
Message-ID: <20150820183213.GM12027@sirena.org.uk>

On Thu, Aug 20, 2015 at 11:12:36AM +0200, Markus Pargmann wrote:
> There is no multi_write support available if we cannot use raw_write.
> This is the case if bus->write is not implemented.
> 
> This patch adds a condition that we need bus and bus->write so that
> can_multi_write is true.

This is fine but doesn't apply (I guess it has a depedency on one of the
earlier patches).
-------------- next part --------------
A non-text attachment was scrubbed...
Name: signature.asc
Type: application/pgp-signature
Size: 473 bytes
Desc: Digital signature
URL: <http://lists.infradead.org/pipermail/linux-arm-kernel/attachments/20150820/773feef8/attachment.sig>

From broonie at kernel.org  Thu Aug 20 11:41:32 2015
From: broonie at kernel.org (Mark Brown)
Date: Thu, 20 Aug 2015 11:41:32 -0700
Subject: [PATCH 1/9] spi: sunxi: fix transfer timeout
In-Reply-To: <0e0b52774a48ddb71dc8095b66942451cd31ff7d.1440080122.git.hramrach@gmail.com>
References: <cover.1440080122.git.hramrach@gmail.com>
 <0e0b52774a48ddb71dc8095b66942451cd31ff7d.1440080122.git.hramrach@gmail.com>
Message-ID: <20150820184132.GO12027@sirena.org.uk>

On Thu, Aug 20, 2015 at 02:19:45PM -0000, Michal Suchanek wrote:

>  drivers/spi/spi-sun4i.c | 10 +++++++++-
>  drivers/spi/spi-sun6i.c | 10 +++++++++-

Are we *sure* we can't work on merging these drivers :(
-------------- next part --------------
A non-text attachment was scrubbed...
Name: signature.asc
Type: application/pgp-signature
Size: 473 bytes
Desc: Digital signature
URL: <http://lists.infradead.org/pipermail/linux-arm-kernel/attachments/20150820/ffc08de4/attachment.sig>

From dinguyen at opensource.altera.com  Thu Aug 20 11:37:48 2015
From: dinguyen at opensource.altera.com (Dinh Nguyen)
Date: Thu, 20 Aug 2015 13:37:48 -0500
Subject: [PATCHv2] arm64: dts: Add base stratix 10 dtsi
In-Reply-To: <20150820172308.GA2711@svinekod>
References: <1439308127-7412-1-git-send-email-dinguyen@opensource.altera.com>
 <20150820172308.GA2711@svinekod>
Message-ID: <55D61E7C.40609@opensource.altera.com>

On 08/20/2015 12:23 PM, Mark Rutland wrote:
> Hi,
> 
>> +/ {
>> +	compatible = "altr,socfpga-stratix10";
>> +	#address-cells = <1>;
>> +	#size-cells = <1>;
> 
> I would recommend that you make your root #address-cells and #size-cells equal
> to 2, as that will simplify matters later if/when you need to add anything
> beyond the first 4GB for some particular board.
> 
> If everything in the SoC falls within the first 4GB you can have a ranges
> property on your /soc node and have only one cell below that.
> 

Ok, will update.

> [...]
> 
>> +	intc: intc at ffff8000 {
> 
> The unit-address doesn't match the first address in the reg entry.
> 

Right, according to the GIC-400 r0p1 TRM, section 3.2 register map,
shows that

0x0000 - 0x0fff		Reserved
0x1000 - 0x1fff		Distibutor
...

So even though the GIC address starts at 0xffff8000, the first usable
register is at 0xffff9000. I'll have to ask the hw folks if the
0xffff8000 represents the distributor or the reserved block.

>> +		compatible = "arm,gic-400", "arm,cortex-a15-gic";
>> +		#interrupt-cells = <3>;
>> +		interrupt-controller;
>> +		reg = <0x0 0xffff9000 0x1000>,
>> +		      <0x0 0xffffa000 0x2000>,
>> +		      <0x0 0xffffc000 0x1000>,
>> +		      <0x0 0xffffd000 0x1000>;
>> +	};
> 
> Shouldn't the virtual CPU interface also be 0x2000 long?
> 

Yes, it is. Will update

Thanks for reviewing.

Dinh



From broonie at kernel.org  Thu Aug 20 11:45:04 2015
From: broonie at kernel.org (Mark Brown)
Date: Thu, 20 Aug 2015 11:45:04 -0700
Subject: [PATCH 3/9] spi: sunxi: check that transfer speed is non-zero
In-Reply-To: <3688fab67e7cdc7bcbff73dfd6b0fcdcc4e79eb6.1440080122.git.hramrach@gmail.com>
References: <cover.1440080122.git.hramrach@gmail.com>
 <3688fab67e7cdc7bcbff73dfd6b0fcdcc4e79eb6.1440080122.git.hramrach@gmail.com>
Message-ID: <20150820184504.GP12027@sirena.org.uk>

On Thu, Aug 20, 2015 at 02:19:46PM -0000, Michal Suchanek wrote:
> When the maximum transfer speed is not set for a SPI slave the value
> remains 0 and the code in sunxi SPI divides by it. Use an arbitrary
> speed instead in that case.

You should always be using the transfer speed that is defined per
transfer, the core will ensure that this is always set.
-------------- next part --------------
A non-text attachment was scrubbed...
Name: signature.asc
Type: application/pgp-signature
Size: 473 bytes
Desc: Digital signature
URL: <http://lists.infradead.org/pipermail/linux-arm-kernel/attachments/20150820/db73391e/attachment.sig>

From horms at verge.net.au  Thu Aug 20 11:54:29 2015
From: horms at verge.net.au (Simon Horman)
Date: Thu, 20 Aug 2015 11:54:29 -0700
Subject: [PATCH 0/2] Add R8A7794/SILK I2C device tree support
In-Reply-To: <55D4FE61.5010800@cogentembedded.com>
References: <2390854.nqPs17CVpc@wasted.cogentembedded.com>
 <55D4FE61.5010800@cogentembedded.com>
Message-ID: <20150820185429.GD18990@verge.net.au>

On Thu, Aug 20, 2015 at 01:08:33AM +0300, Sergei Shtylyov wrote:
> On 08/20/2015 12:57 AM, Sergei Shtylyov wrote:
> 
> >    Here's the set of 2 patches against Simon Horman's 'renesas.git' repo's
> >'renesas-devel-20150819-v4.2-rc7' tag. Here we add the I2C device tree support
> >for the R8A7794/SILK board.
> >
> >[1/2] ARM: shmobile: r8a7794: add I2C DT support
> >[2/2] ARM: shmobile: silk: add I2C1 DT support
> 
>    Simon, actually the above patch is atop of my SILK SDHI1 patch but should
> apply with offsets atop of your tag.

Thanks for following up.

I have queued up this series for v4.4.


From horms at verge.net.au  Thu Aug 20 11:54:35 2015
From: horms at verge.net.au (Simon Horman)
Date: Thu, 20 Aug 2015 11:54:35 -0700
Subject: [PATCH 0/2] Add VIN and ADV7180 device tree support for
 R8A7794/SILK board
In-Reply-To: <1750082.WpWf34HsI6@wasted.cogentembedded.com>
References: <1750082.WpWf34HsI6@wasted.cogentembedded.com>
Message-ID: <20150820185435.GE18990@verge.net.au>

On Thu, Aug 20, 2015 at 01:20:42AM +0300, Sergei Shtylyov wrote:
> Hello.
> 
>    Here's the set of 2 patches against Simon Horman's 'renesas.git' repo's
> 'renesas-devel-20150819-v4.2-rc7' tag. Here we add the VIN and ADV7180
> video decoder device tree support on the R8A7794/SILK board. The patchset
> requires previously posted SILK SDHI1 support patch in order to apply and 
> R8A7794/SILK I2C1 support in order to apply and build.
> 
> [1/2] ARM: shmobile: r8a7794: add VIN DT support
> [2/2] ARM: shmobile: silk: add VIN0/ADV7180 DT support

Thanks, I have queued these up for v4.4.


From broonie at kernel.org  Thu Aug 20 11:58:50 2015
From: broonie at kernel.org (Mark Brown)
Date: Thu, 20 Aug 2015 11:58:50 -0700
Subject: [PATCH 4/9] spi: sun4i: add DMA support
In-Reply-To: <ccf776869b0d7fe2c78bcc41d6cd1896bf732296.1440080122.git.hramrach@gmail.com>
References: <cover.1440080122.git.hramrach@gmail.com>
 <ccf776869b0d7fe2c78bcc41d6cd1896bf732296.1440080122.git.hramrach@gmail.com>
Message-ID: <20150820185850.GQ12027@sirena.org.uk>

On Thu, Aug 20, 2015 at 02:19:46PM -0000, Emilio L?pez wrote:

> -	sun4i_spi_drain_fifo(sspi, SUN4I_FIFO_DEPTH);
> +	if (sun4i_spi_can_dma(master, spi, tfr) && desc_rx) {
> +		/* The receive transfer should be the last one to finish */
> +		dma_wait_for_async_tx(desc_rx);

What if it's a transmit only transfer?  We'll fall over to this...

> +	} else {
> +		sun4i_spi_drain_fifo(sspi, SUN4I_FIFO_DEPTH);
> +	}

...which manually reads data from the FIFO which doesn't seem like what
we want, won't it conflict with the DMA?
-------------- next part --------------
A non-text attachment was scrubbed...
Name: signature.asc
Type: application/pgp-signature
Size: 473 bytes
Desc: Digital signature
URL: <http://lists.infradead.org/pipermail/linux-arm-kernel/attachments/20150820/5d89ea8e/attachment.sig>

From broonie at kernel.org  Thu Aug 20 12:00:03 2015
From: broonie at kernel.org (Mark Brown)
Date: Thu, 20 Aug 2015 12:00:03 -0700
Subject: [PATCH 4/9] spi: sun4i: add DMA support
In-Reply-To: <ccf776869b0d7fe2c78bcc41d6cd1896bf732296.1440080122.git.hramrach@gmail.com>
References: <cover.1440080122.git.hramrach@gmail.com>
 <ccf776869b0d7fe2c78bcc41d6cd1896bf732296.1440080122.git.hramrach@gmail.com>
Message-ID: <20150820190003.GR12027@sirena.org.uk>

On Thu, Aug 20, 2015 at 02:19:46PM -0000, Emilio L?pez wrote:

> Signed-off-by: Emilio L?pez <emilio at elopez.com.ar>
> Tested-by: Michal Suchanek <hramrach at gmail.com>

Also, if you're sending on a patch from someone else you must add a
Signed-off-by, see SubmittingPatches.
-------------- next part --------------
A non-text attachment was scrubbed...
Name: signature.asc
Type: application/pgp-signature
Size: 473 bytes
Desc: Digital signature
URL: <http://lists.infradead.org/pipermail/linux-arm-kernel/attachments/20150820/d0884ad1/attachment.sig>

From daniel.lezcano at linaro.org  Thu Aug 20 12:03:04 2015
From: daniel.lezcano at linaro.org (Daniel Lezcano)
Date: Thu, 20 Aug 2015 21:03:04 +0200
Subject: [PATCH] clocksource: arm_global_timer: register delay timer
In-Reply-To: <1439991818-31989-1-git-send-email-rabin.vincent@axis.com>
References: <1439991818-31989-1-git-send-email-rabin.vincent@axis.com>
Message-ID: <55D62468.4050404@linaro.org>

On 08/19/2015 03:43 PM, Rabin Vincent wrote:
> Provide a delay timer using the lower 32-bits of the global timer so
> that we can use that instead of having to calibrating delays.
>
> Signed-off-by: Rabin Vincent <rabin.vincent at axis.com>

Applied to my tree for 4.4

Thanks !

   -- Daniel

-- 
  <http://www.linaro.org/> Linaro.org ? Open source software for ARM SoCs

Follow Linaro:  <http://www.facebook.com/pages/Linaro> Facebook |
<http://twitter.com/#!/linaroorg> Twitter |
<http://www.linaro.org/linaro-blog/> Blog



From sergei.shtylyov at cogentembedded.com  Thu Aug 20 12:04:13 2015
From: sergei.shtylyov at cogentembedded.com (Sergei Shtylyov)
Date: Thu, 20 Aug 2015 22:04:13 +0300
Subject: [PATCH 0/2] Add VIN and ADV7180 device tree support for
 R8A7794/SILK board
In-Reply-To: <20150820185435.GE18990@verge.net.au>
References: <1750082.WpWf34HsI6@wasted.cogentembedded.com>
 <20150820185435.GE18990@verge.net.au>
Message-ID: <55D624AD.7060801@cogentembedded.com>

On 08/20/2015 09:54 PM, Simon Horman wrote:

>>     Here's the set of 2 patches against Simon Horman's 'renesas.git' repo's
>> 'renesas-devel-20150819-v4.2-rc7' tag. Here we add the VIN and ADV7180
>> video decoder device tree support on the R8A7794/SILK board. The patchset
>> requires previously posted SILK SDHI1 support patch in order to apply and
>> R8A7794/SILK I2C1 support in order to apply and build.
>>
>> [1/2] ARM: shmobile: r8a7794: add VIN DT support
>> [2/2] ARM: shmobile: silk: add VIN0/ADV7180 DT support
>
> Thanks, I have queued these up for v4.4.

    Perhaps a bit too early: the PFC VIN patch hasn't been merged yet. Sorry 
for not specifying the PFC dependency...

MBR, Sergei



From maxime.ripard at free-electrons.com  Thu Aug 20 12:34:33 2015
From: maxime.ripard at free-electrons.com (Maxime Ripard)
Date: Thu, 20 Aug 2015 21:34:33 +0200
Subject: [PATCH 1/9] spi: sunxi: fix transfer timeout
In-Reply-To: <20150820184132.GO12027@sirena.org.uk>
References: <cover.1440080122.git.hramrach@gmail.com>
 <0e0b52774a48ddb71dc8095b66942451cd31ff7d.1440080122.git.hramrach@gmail.com>
 <20150820184132.GO12027@sirena.org.uk>
Message-ID: <20150820193433.GH30520@lukather>

On Thu, Aug 20, 2015 at 11:41:32AM -0700, Mark Brown wrote:
> On Thu, Aug 20, 2015 at 02:19:45PM -0000, Michal Suchanek wrote:
> 
> >  drivers/spi/spi-sun4i.c | 10 +++++++++-
> >  drivers/spi/spi-sun6i.c | 10 +++++++++-
> 
> Are we *sure* we can't work on merging these drivers :(

Those are two different IPs, that don't really share anything but
their author...

Maxime

-- 
Maxime Ripard, Free Electrons
Embedded Linux, Kernel and Android engineering
http://free-electrons.com
-------------- next part --------------
A non-text attachment was scrubbed...
Name: signature.asc
Type: application/pgp-signature
Size: 819 bytes
Desc: Digital signature
URL: <http://lists.infradead.org/pipermail/linux-arm-kernel/attachments/20150820/3fafe925/attachment.sig>

From robert.jarzmik at free.fr  Thu Aug 20 12:32:21 2015
From: robert.jarzmik at free.fr (Robert Jarzmik)
Date: Thu, 20 Aug 2015 21:32:21 +0200
Subject: [PATCH v2 11/21] ARM: pxa: magician: Add MAX1586 Vcore regulator
 support
In-Reply-To: <55D259CC.6040307@tul.cz> (Petr Cvek's message of "Tue, 18 Aug
 2015 00:01:48 +0200")
References: <cover.1439843482.git.petr.cvek@tul.cz> <55D259CC.6040307@tul.cz>
Message-ID: <87pp2h69iy.fsf@belgarion.home>

Petr Cvek <petr.cvek at tul.cz> writes:

> Add support for MAX1586 Vcore regulator.
>
> Signed-off-by: Petr Cvek <petr.cvek at tul.cz>
I'll leave that for a week and if no objections queue it.

I would have expected a better commit message : for example, from your patch I
deduce magician has a 1587 regulator, not a 1586 one : that deserves a small
mention in the commit message. Moreover, the Maxim has 2 outputs : one is
connected to VCC_Core of the SoC, what about the other output ?  Is it unknown,
or do you know but don't use it ?

Cheers.

--
Robert


From dhdang at apm.com  Thu Aug 20 12:38:53 2015
From: dhdang at apm.com (Duc Dang)
Date: Thu, 20 Aug 2015 12:38:53 -0700
Subject: [PATCH v7 1/2] usb: make xhci platform driver use 64 bit or 32 bit DMA
In-Reply-To: <1522889.9kdnRk8vHo@wuerfel>
References: <1522889.9kdnRk8vHo@wuerfel>
Message-ID: <69e6f5bf693d02fba001d02047453bed0519499d.1440098398.git.dhdang@apm.com>

The xhci platform driver needs to work on systems that
either only support 64-bit DMA or only support 32-bit DMA.
Attempt to set a coherent dma mask for 64-bit DMA, and
attempt again with 32-bit DMA if that fails.

[dhdang: regenerate the patch over 4.2-rc5 and address new comments]
Signed-off-by: Mark Langsdorf <mlangsdo at redhat.com>
Tested-by: Mark Salter <msalter at redhat.com>
Signed-off-by: Duc Dang <dhdang at apm.com>

---
Changes from v6:
	-Add WARN_ON if dma_mask is NULL
	-Use dma_coerce_mask_and_coherent to assign
	dma_mask and coherent_dma_mask

Changes from v5:
        -Change comment
        -Assign dma_mask to coherent_dma_mask if dma_mask is NULL
        to make sure dma_set_mask_and_coherent does not fail prematurely.

Changes from v4:
        -None

Changes from v3:
        -Re-generate the patch over 4.2-rc5
        -No code change.

Changes from v2:
        -None

Changes from v1:
        -Consolidated to use dma_set_mask_and_coherent
        -Got rid of the check against sizeof(dma_addr_t)

 drivers/usb/host/xhci-plat.c | 21 +++++++++++++--------
 1 file changed, 13 insertions(+), 8 deletions(-)

diff --git a/drivers/usb/host/xhci-plat.c b/drivers/usb/host/xhci-plat.c
index 890ad9d..e4c7f9d 100644
--- a/drivers/usb/host/xhci-plat.c
+++ b/drivers/usb/host/xhci-plat.c
@@ -93,14 +93,19 @@ static int xhci_plat_probe(struct platform_device *pdev)
 	if (irq < 0)
 		return -ENODEV;
 
-	/* Initialize dma_mask and coherent_dma_mask to 32-bits */
-	ret = dma_set_coherent_mask(&pdev->dev, DMA_BIT_MASK(32));
-	if (ret)
-		return ret;
-	if (!pdev->dev.dma_mask)
-		pdev->dev.dma_mask = &pdev->dev.coherent_dma_mask;
-	else
-		dma_set_mask(&pdev->dev, DMA_BIT_MASK(32));
+	/* Throw a waring if broken platform code didn't initialize dma_mask */
+	WARN_ON(!pdev->dev.dma_mask);
+	/*
+	 * Try setting dma_mask and coherent_dma_mask to 64 bits,
+	 * then try 32 bits
+	 */
+	ret = dma_coerce_mask_and_coherent(&pdev->dev, DMA_BIT_MASK(64));
+	if (ret) {
+		ret = dma_coerce_mask_and_coherent(&pdev->dev,
+						   DMA_BIT_MASK(32));
+		if (ret)
+			return ret;
+	}
 
 	hcd = usb_create_hcd(driver, &pdev->dev, dev_name(&pdev->dev));
 	if (!hcd)
-- 
1.9.1



From dhdang at apm.com  Thu Aug 20 12:38:54 2015
From: dhdang at apm.com (Duc Dang)
Date: Thu, 20 Aug 2015 12:38:54 -0700
Subject: [PATCH v7 2/2] usb: Add support for ACPI identification to
 xhci-platform
In-Reply-To: <69e6f5bf693d02fba001d02047453bed0519499d.1440098398.git.dhdang@apm.com>
References: <69e6f5bf693d02fba001d02047453bed0519499d.1440098398.git.dhdang@apm.com>
Message-ID: <4535734cb286b1fcf2964838cb8f432899280db8.1440098398.git.dhdang@apm.com>

Provide the methods to let ACPI identify the need to use
xhci-platform. Change the Kconfig files so the
xhci-plat.o file is selectable during kernel config.

This has been tested on an ARM64 machine with platform XHCI, an
x86_64 machine with XHCI, and an x86_64 machine without XHCI.
There were no regressions or error messages on the machines
without platform XHCI.

[dhdang: regenerate the patch over 4.2-rc5 and address new comments]
Signed-off-by: Mark Langsdorf <mlangsdo at redhat.com>
Signed-off-by: Duc Dang <dhdang at apm.com>

---
Changes from v6:
	-None

Change from v5:
        -Change comment to "XHCI-compliant USB Controller" as
        "PNP0D10" ID is not X-Gene specific

Changes from v4:
        -Remove #ifdef CONFIG_ACPI

Changes from v3:
        -Regenerate the patch over 4.2-rc5
        -No code change

Changes from v2
        -Replaced tristate with a boolean as the driver doesn't
                compile as a module
        -Correct --help-- to ---help---

Changes from v1
        -Renamed from "add support for APM X-Gene to xhci-platform"
        -Removed changes to arm64/Kconfig
        -Made CONFIG_USB_XHCI_PLATFORM a user selectable config option

 drivers/usb/host/Kconfig     | 7 ++++++-
 drivers/usb/host/xhci-plat.c | 9 +++++++++
 2 files changed, 15 insertions(+), 1 deletion(-)

diff --git a/drivers/usb/host/Kconfig b/drivers/usb/host/Kconfig
index 8afc3c1..96231ee 100644
--- a/drivers/usb/host/Kconfig
+++ b/drivers/usb/host/Kconfig
@@ -32,7 +32,12 @@ config USB_XHCI_PCI
        default y
 
 config USB_XHCI_PLATFORM
-	tristate
+	tristate "xHCI platform driver support"
+	---help---
+	  Say 'Y' to enable the support for the xHCI host controller
+	  as a platform device. Many ARM SoCs provide USB this way.
+
+	  If unsure, say 'Y'.
 
 config USB_XHCI_MVEBU
 	tristate "xHCI support for Marvell Armada 375/38x"
diff --git a/drivers/usb/host/xhci-plat.c b/drivers/usb/host/xhci-plat.c
index e4c7f9d..6c03e1c 100644
--- a/drivers/usb/host/xhci-plat.c
+++ b/drivers/usb/host/xhci-plat.c
@@ -19,6 +19,7 @@
 #include <linux/usb/phy.h>
 #include <linux/slab.h>
 #include <linux/usb/xhci_pdriver.h>
+#include <linux/acpi.h>
 
 #include "xhci.h"
 #include "xhci-mvebu.h"
@@ -267,6 +268,13 @@ static const struct of_device_id usb_xhci_of_match[] = {
 MODULE_DEVICE_TABLE(of, usb_xhci_of_match);
 #endif
 
+static const struct acpi_device_id usb_xhci_acpi_match[] = {
+	/* XHCI-compliant USB Controller */
+	{ "PNP0D10", },
+	{ }
+};
+MODULE_DEVICE_TABLE(acpi, usb_xhci_acpi_match);
+
 static struct platform_driver usb_xhci_driver = {
 	.probe	= xhci_plat_probe,
 	.remove	= xhci_plat_remove,
@@ -274,6 +282,7 @@ static struct platform_driver usb_xhci_driver = {
 		.name = "xhci-hcd",
 		.pm = DEV_PM_OPS,
 		.of_match_table = of_match_ptr(usb_xhci_of_match),
+		.acpi_match_table = ACPI_PTR(usb_xhci_acpi_match),
 	},
 };
 MODULE_ALIAS("platform:xhci-hcd");
-- 
1.9.1



From hramrach at gmail.com  Thu Aug 20 12:45:07 2015
From: hramrach at gmail.com (Michal Suchanek)
Date: Thu, 20 Aug 2015 21:45:07 +0200
Subject: [PATCH 3/9] spi: sunxi: check that transfer speed is non-zero
In-Reply-To: <20150820144836.GV30520@lukather>
References: <cover.1440080122.git.hramrach@gmail.com>
 <3688fab67e7cdc7bcbff73dfd6b0fcdcc4e79eb6.1440080122.git.hramrach@gmail.com>
 <20150820144836.GV30520@lukather>
Message-ID: <CAOMqctSfdxWeWDogzHxONE+Qxf7vp6rJnBmxECV89PQO0hXARg@mail.gmail.com>

On 20 August 2015 at 16:48, Maxime Ripard
<maxime.ripard at free-electrons.com> wrote:
> On Thu, Aug 20, 2015 at 02:19:46PM -0000, Michal Suchanek wrote:
>> When the maximum transfer speed is not set for a SPI slave the value
>> remains 0 and the code in sunxi SPI divides by it. Use an arbitrary
>> speed instead in that case.
>>
>> Signed-off-by: Michal Suchanek <hramrach at gmail.com>
>
> spi->max_speed_hz is set using the spi-max-frequency property, and
> spi->will error out if that property isn't set. What am I missing?
>

Spidev I guess.

You can set the speed to arbitrary value from userspace at any time
using the spidev ioctls.

Thanks

Michal


From ezequiel at vanguardiasur.com.ar  Thu Aug 20 12:51:36 2015
From: ezequiel at vanguardiasur.com.ar (Ezequiel Garcia)
Date: Thu, 20 Aug 2015 16:51:36 -0300
Subject: [PATCH v2 0/2] Add support for NXP LPC18xx PWM/SCT
In-Reply-To: <1438828307-14641-1-git-send-email-ariel@vanguardiasur.com.ar>
References: <1438828307-14641-1-git-send-email-ariel@vanguardiasur.com.ar>
Message-ID: <CAAEAJfCyZUNadthZ_3-scqv0f8Rjf4dd=fg8Rhqt0xfdoDF9XQ@mail.gmail.com>

Thierry,

On 5 August 2015 at 23:31, Ariel D'Alessandro
<ariel at vanguardiasur.com.ar> wrote:
> This patch series adds support for NXP LPC18xx PWM/SCT.
>
> NXP LPC SoCs family, which includes LPC18xx/LPC43xx, provides a State
> Configurable Timer (SCT) which can be configured as a Pulse Width Modulator.
> Other SoCs in that family may share the same hardware.
>
> Patchset is based on tag next-20150723 of the linux-next repository.
> It has been successfully tested on a Hitex LPC4350 Evaluation Board.
>
> Changes since v1:
> * Added "sct" in DT compatible string and driver's name.
> * Allowed period changes when there's only one channel requested.
>
> Ariel D'Alessandro (2):
>   pwm: NXP LPC18xx PWM/SCT driver
>   DT: pwm: Add NXP LPC18xx PWM/SCT binding documentation
>
>  .../devicetree/bindings/pwm/lpc1850-sct-pwm.txt    |  20 +
>  drivers/pwm/Kconfig                                |  12 +
>  drivers/pwm/Makefile                               |   1 +
>  drivers/pwm/pwm-lpc18xx-sct.c                      | 465 +++++++++++++++++++++
>  4 files changed, 498 insertions(+)
>  create mode 100644 Documentation/devicetree/bindings/pwm/lpc1850-sct-pwm.txt
>  create mode 100644 drivers/pwm/pwm-lpc18xx-sct.c
>
> --
> 1.9.1
>

Any news about this driver?

-- 
Ezequiel Garc?a, VanguardiaSur
www.vanguardiasur.com.ar


From robert.jarzmik at free.fr  Thu Aug 20 12:48:20 2015
From: robert.jarzmik at free.fr (Robert Jarzmik)
Date: Thu, 20 Aug 2015 21:48:20 +0200
Subject: [PATCH v2 09/21] ARM: pxa: magician: Add OV9640 camera support
In-Reply-To: <55D259A1.6090102@tul.cz> (Petr Cvek's message of "Tue, 18 Aug
 2015 00:01:05 +0200")
References: <cover.1439843482.git.petr.cvek@tul.cz> <55D259A1.6090102@tul.cz>
Message-ID: <87lhd568sb.fsf@belgarion.home>

Petr Cvek <petr.cvek at tul.cz> writes:

> +	mdelay(3);
Okay, there are several mdelay(3) in this file.

Could you please test if removing these mdelays prevents the camera from working
? If not, I'd like to have them removed.

Cheers.

--
Robert


From ezequiel at vanguardiasur.com.ar  Thu Aug 20 12:54:57 2015
From: ezequiel at vanguardiasur.com.ar (Ezequiel Garcia)
Date: Thu, 20 Aug 2015 16:54:57 -0300
Subject: [PATCH v5 1/2] watchdog: NXP LPC18xx Watchdog Timer Driver
In-Reply-To: <55BD1550.708@roeck-us.net>
References: <1438454237-22043-1-git-send-email-ariel@vanguardiasur.com.ar>
 <1438454237-22043-2-git-send-email-ariel@vanguardiasur.com.ar>
 <55BD1550.708@roeck-us.net>
Message-ID: <CAAEAJfB2aHpaoQpZWCrnhajNjQRCu6zWfFkyZ=Ad9hPnnVx0gw@mail.gmail.com>

On 1 August 2015 at 15:52, Guenter Roeck <linux at roeck-us.net> wrote:
> On 08/01/2015 11:37 AM, Ariel D'Alessandro wrote:
>>
>> This commit adds support for the watchdog timer found in NXP LPC SoCs
>> family, which includes LPC18xx/LPC43xx. Other SoCs in that family may
>> share the same watchdog hardware.
>>
>> Watchdog driver registers a restart handler that will restart the system
>> by performing an incorrect feed after ensuring the watchdog is enabled in
>> reset mode.
>>
>> As watchdog cannot be disabled in hardware, driver's stop routine will
>> regularly send a keepalive ping using a timer.
>>
>> Signed-off-by: Ariel D'Alessandro <ariel at vanguardiasur.com.ar>
>
>
> Reviewed-by: Guenter Roeck <linux at roeck-us.net>
>

Wim,

Any chances you pick this in time for the next merge window?

-- 
Ezequiel Garc?a, VanguardiaSur
www.vanguardiasur.com.ar


From linux at arm.linux.org.uk  Thu Aug 20 12:54:55 2015
From: linux at arm.linux.org.uk (Russell King - ARM Linux)
Date: Thu, 20 Aug 2015 20:54:55 +0100
Subject: [PATCH] ARM: Set proper TEXT_OFFSET for IPQ806x
In-Reply-To: <20150820172010.GB10796@qualcomm.com>
References: <20150820121541.GA14664@codeaurora.org>
 <20150820130005.GS7557@n2100.arm.linux.org.uk>
 <20150820172010.GB10796@qualcomm.com>
Message-ID: <20150820195455.GT7557@n2100.arm.linux.org.uk>

On Thu, Aug 20, 2015 at 12:20:10PM -0500, Andy Gross wrote:
> On Thu, Aug 20, 2015 at 02:00:06PM +0100, Russell King - ARM Linux wrote:
> > On Thu, Aug 20, 2015 at 05:45:41PM +0530, Varadarajan Narayanan wrote:
> > > RAM starts at 0x40000000 for IPQ. The lower 21MB of RAM is used
> > > for Shared Memory and the kernel can start from 0x41500000.
> > 
> > Why do people keep creating crap like this?  Each time something like
> > this is created, it means that you _need_ to have a special kernel for
> > your platform and you can't be part of the single zImage.
> > 
> > Please, rather than creating crap like this, find a better way.
> 
> In the case of the IPQ, we don't use the zImage because the decompress
> requires a larger jump than we can do on that platform.  Having this
> change at least gets us back 2MB of memory.

Your argument about "a larger jump" makes no sense what so ever.  The
branches between the decompressor and the main kernel are all done
using a mov, which can jump to any 32-bit address.

Even if you load the compressed kernel image at 0x41500000, the
decompressor will mask that with 0xf8000000, and decide that RAM
starts at 0x40000000.  It will then want to place the decompressed
kernel image at 0x40008000.  Nothing there has anything to do with
jump ranges.

The only restriction that the ARM has as far as jump ranges are
concerned is the 'b' or 'bl' instruction, which in ARM mode is
limited to +/- 32MB.  That doesn't apply here since we don't use
that to jump between the decompressor and the decompressed kernel
image.

So...

Why is it necessary to have this 21MB block of shared memory at
the start of RAM?  Why can't it be reserved by other means higher
up in system memory?

It's up to the submitter to justify why any change is required, and
in this case, part of that justification is why the shared memory is
placed at the start of RAM, and why you need to be different from
almost everyone else, and why you need to be a special case.  The
justification also must make sense.

-- 
FTTC broadband for 0.8mile line: currently at 10.5Mbps down 400kbps up
according to speedtest.net.


From robert.jarzmik at free.fr  Thu Aug 20 12:51:45 2015
From: robert.jarzmik at free.fr (Robert Jarzmik)
Date: Thu, 20 Aug 2015 21:51:45 +0200
Subject: [PATCH v2 10/21] ARM: pxa: magician: Add UDA1380 sound support
In-Reply-To: <55D259B7.90703@tul.cz> (Petr Cvek's message of "Tue, 18 Aug 2015
 00:01:27 +0200")
References: <cover.1439843482.git.petr.cvek@tul.cz> <55D259B7.90703@tul.cz>
Message-ID: <87h9nt68mm.fsf@belgarion.home>

Petr Cvek <petr.cvek at tul.cz> writes:

> +/*
> + * Magician Audio controller
> + */
> +
> +static struct platform_device magician_audio_device = {
> +	.name = "magician-audio",
Is this already upstream or is it a submission in progress ? Other than that
detail, I'll queue it in a week probably.

Cheers.

--
Robert


From robert.jarzmik at free.fr  Thu Aug 20 12:58:25 2015
From: robert.jarzmik at free.fr (Robert Jarzmik)
Date: Thu, 20 Aug 2015 21:58:25 +0200
Subject: [PATCH v2 15/21] ARM: pxa: magician: Fix PWM backlight regulator
In-Reply-To: <55D25A4A.4070409@tul.cz> (Petr Cvek's message of "Tue, 18 Aug
 2015 00:03:54 +0200")
References: <cover.1439843482.git.petr.cvek@tul.cz> <55D25A4A.4070409@tul.cz>
Message-ID: <87d1yh68bi.fsf@belgarion.home>

Petr Cvek <petr.cvek at tul.cz> writes:

> Fix PWM backlight regulator. It is requested from pwm_backlight_probe().
Even if I know why you have to fix it, somebody else reading your commit message
should understand why this fix is need. You need to explain why it is needed,
ie. what happens without it, and therefore what justifies this patch.

Cheers.

--
Robert

PS: For inspiration, look at Thierry's commit 902e6a0c7eba.


From petr.cvek at tul.cz  Thu Aug 20 13:07:45 2015
From: petr.cvek at tul.cz (Petr Cvek)
Date: Thu, 20 Aug 2015 22:07:45 +0200
Subject: [PATCH v1, TRIVIAL] Fix pxafb nonstd field documentation and add
 errata info
In-Reply-To: <55D5B232.9090006@ti.com>
References: <55C64864.6070405@tul.cz> <55D5B232.9090006@ti.com>
Message-ID: <55D63391.3080403@tul.cz>

Dne 20.8.2015 v 12:55 Tomi Valkeinen napsal(a):
> 
> 
> On 08/08/15 21:20, Petr Cvek wrote:
> 
>> diff --git a/drivers/video/fbdev/Kconfig b/drivers/video/fbdev/Kconfig
>> index 2d98de5..8f485ec 100644
>> --- a/drivers/video/fbdev/Kconfig
>> +++ b/drivers/video/fbdev/Kconfig
>> @@ -1893,6 +1893,11 @@ config FB_PXA_OVERLAY
>>  	bool "Support PXA27x/PXA3xx Overlay(s) as framebuffer"
>>  	default n
>>  	depends on FB_PXA && (PXA27x || PXA3xx)
>> +	---help---
>> +	  Using the overlay 2 and YUV420 mode on a PXA27x C0 chip revision will
>> +	  hang the LCD until the next SoC restart (errata E24).
> 
> Shouldn't the driver handle this? It should not allow the combination to
> be used.
> 
>  Tomi
> 

Probably, but I don't know which revisions are OK and which are not. Errata document:

	Marvell? PXA270M Processor Specification Update
	MV-S900957-00

has only 3 revisions, but PXA Manual lists 6 (2.2.5.1 Processor ID Register) and one revision from errata is not shown in my PXA Manual. I can exclude mine revision (from "system_rev" variable), but there should be some warning somewhere in configuration.


BTW There is software workaround, but I was not able to set registers right (it requires to send some data through FIFO in different mode).

Petr


From linux at arm.linux.org.uk  Thu Aug 20 13:05:34 2015
From: linux at arm.linux.org.uk (Russell King - ARM Linux)
Date: Thu, 20 Aug 2015 21:05:34 +0100
Subject: is it possible to liimit the softirq re entrance times
In-Reply-To: <CAOVJa8FfHWGVf=ccXFCyTUD5YHrMAAeQ9Tkg1ipHA=J_CyVAHQ@mail.gmail.com>
References: <CAOVJa8FfHWGVf=ccXFCyTUD5YHrMAAeQ9Tkg1ipHA=J_CyVAHQ@mail.gmail.com>
Message-ID: <20150820200534.GU7557@n2100.arm.linux.org.uk>

On Fri, Aug 21, 2015 at 01:09:23AM +0800, vichy wrote:
> My question are:
> 1. in __do_sofiq, there is a jiffies setting to make sure the whole
> softirq will not took to long.
> But in my case is there any many hard irq happen like below
> 
>                         trace_softirq_entry(vec_nr);    ------a
>                         h->action(h);
>                         trace_softirq_exit(vec_nr);      ---------b
> 
> from lttng, I see there 100 interrupt happen from entry to exit.

Firstly, I don't trust the trace infrastructure all that much for
performance measurements: it has a non-zero overhead (especially if
you turn on stack tracing), and if you want to do these kinds of
measurements, you first need to ascertain what that overhead is, so
you can subtract the effect of having trace enabled from the
observations.  It's quite possible that a number of those 100
interrupts are happening in the trace code recording the softirq
entry and exit events.

Secondly, you seem to be saying that 100 interrupts happen in
h->action().  You don't specify the frequency of those interrupts.
You also don't mention (which is more important) how long h->action()
takes to run.  You also don't say which softirq it is.

>From the sounds of it, whatever soft irq handler is running, it's the
handler itself which is the cause of your problem, but not knowing any
of the details in my second point above, it's impossible to tell.

-- 
FTTC broadband for 0.8mile line: currently at 10.5Mbps down 400kbps up
according to speedtest.net.


From robert.jarzmik at free.fr  Thu Aug 20 13:01:50 2015
From: robert.jarzmik at free.fr (Robert Jarzmik)
Date: Thu, 20 Aug 2015 22:01:50 +0200
Subject: [PATCH v2 16/21] ARM: pxa: magician: Add support for alternative
 LCD backlight
In-Reply-To: <55D25A60.7000900@tul.cz> (Petr Cvek's message of "Tue, 18 Aug
 2015 00:04:16 +0200")
References: <cover.1439843482.git.petr.cvek@tul.cz> <55D25A60.7000900@tul.cz>
Message-ID: <878u95685t.fsf@belgarion.home>

Petr Cvek <petr.cvek at tul.cz> writes:

> Add support for alternative LCD backlight with GPIO (no brightness).
Here, I don't understand, the commit message is too short.

Are there 2 brightness controls on magician, or are these 2 different magicians
(hardware wise), each having a different backlight control ? Or is it there is a
GPIO to light up the screen and a PWM backlight ?

I have to understand first.

Cheers.

--
Robert


From John.Youn at synopsys.com  Thu Aug 20 13:07:35 2015
From: John.Youn at synopsys.com (John Youn)
Date: Thu, 20 Aug 2015 20:07:35 +0000
Subject: [PATCH v5 01/46] usb: gadget: encapsulate endpoint claiming
 mechanism
References: <1438351258-31578-1-git-send-email-r.baldyga@samsung.com>
 <1438351258-31578-2-git-send-email-r.baldyga@samsung.com>
 <20150820153553.GD1639@saruman.tx.rr.com> <55D6001E.3000504@hackerion.com>
 <20150820164808.GB4938@saruman.tx.rr.com> <55D60B80.7040800@hackerion.com>
 <20150820174409.GB7270@saruman.tx.rr.com>
Message-ID: <2B3535C5ECE8B5419E3ECBE30077290901DC3380D9@us01wembx1.internal.synopsys.com>

On 8/20/2015 10:45 AM, Felipe Balbi wrote:
> Hi,
> 
> On Thu, Aug 20, 2015 at 07:16:48PM +0200, Robert Baldyga wrote:
>> On 08/20/2015 06:48 PM, Felipe Balbi wrote:
>>> On Thu, Aug 20, 2015 at 06:28:14PM +0200, Robert Baldyga wrote:
>>>> Hi Felipe,
>>>>
>>>> On 08/20/2015 05:35 PM, Felipe Balbi wrote:
>>>> [...]
>>>>> just letting you know that this regresses all gadget drivers making them
>>>>> try to disable previously disabled endpoints and enable previously
>>>>> enabled endpoints.
>>>>>
>>>>> I have a possible fix (see below) but then it shows a problem on the
>>>>> host side when using with g_zero (see further below):
>>>>>
>>>>> commit 3b8932100aacb6cfbffe288ca93025d8b8430c00
>>>>> Author: Felipe Balbi <balbi at ti.com>
>>>>> Date:   Wed Aug 19 18:05:27 2015 -0500
>>>>>
>>>>>     usb: gadget: fix ep->claimed lifetime
>>>>>
>>>>>     In order to fix a regression introduced by commit
>>>>>     cc476b42a39d ("usb: gadget: encapsulate endpoint
>>>>>     claiming mechanism") we have to introduce a simple
>>>>>     helper to check if a particular is enabled or not.
>>>>>
>>>>>     After that, we need to move ep->claimed lifetime to
>>>>>     usb_ep_enable() and usb_ep_disable() since those
>>>>>     are the only functions which actually enable and
>>>>>     disable endpoints.
>>>>>
>>>>>     A follow-up patch will come to drop all driver_data
>>>>>     checks from function drivers, since those are, now,
>>>>>     pointless.
>>>>>
>>>>>     Fixes: cc476b42a39d ("usb: gadget: encapsulate endpoint
>>>>>     	claiming mechanism")
>>>>>     Cc: Robert Baldyga <r.baldyga at samsung.com>
>>>>>     Signed-off-by: Felipe Balbi <balbi at ti.com>
>>>>>
>>>>> diff --git a/drivers/usb/gadget/epautoconf.c b/drivers/usb/gadget/epautoconf.c
>>>>> index 978435a51038..ad45070cd76f 100644
>>>>> --- a/drivers/usb/gadget/epautoconf.c
>>>>> +++ b/drivers/usb/gadget/epautoconf.c
>>>>> @@ -126,7 +126,6 @@ found_ep:
>>>>>  	ep->address = desc->bEndpointAddress;
>>>>>  	ep->desc = NULL;
>>>>>  	ep->comp_desc = NULL;
>>>>> -	ep->claimed = true;
>>>>
>>>> Removing this line causes autoconfig can return the same endpoint many
>>>> times. This probably causes problems with g_zero.
>>>>
>>>> I will try to fix it ASAP.
>>>
>>> I was considering the same thing, but the lifetime of ->claimed doesn't
>>> look correct to me either way. Note that once the flag is enabled, it
>>> won't get disabled by most gadget drivers.
>>
>> And it should not be. This flag is indicator, that endpoint is used by some
>> function. It should be set once by usb_ep_autoconfig() and cleared by
>> usb_ep_autoconfig_reset().

And the 'claimed' flag should be used for the ep autoconfig
mechanism alone. We may want to reset it during the autoconfig
phase for multiple configs and alt-interfaces. So there should be
separate 'claimed' and 'enabled' flags.


> 
> have you considered switching interfaces and/or alternate settings ?

We ran into similar issues before with this very scenario. Handling
of set_config(0 or N), in both addressed and configured states, and
set_interface requests.


John



From sergei.shtylyov at cogentembedded.com  Thu Aug 20 13:19:11 2015
From: sergei.shtylyov at cogentembedded.com (Sergei Shtylyov)
Date: Thu, 20 Aug 2015 23:19:11 +0300
Subject: [PATCH 0/2] Add VIN and ADV7180 device tree support for
 R8A7794/SILK board
In-Reply-To: <55D624AD.7060801@cogentembedded.com>
References: <1750082.WpWf34HsI6@wasted.cogentembedded.com>
 <20150820185435.GE18990@verge.net.au> <55D624AD.7060801@cogentembedded.com>
Message-ID: <55D6363F.4050207@cogentembedded.com>

On 08/20/2015 10:04 PM, Sergei Shtylyov wrote:

>>>     Here's the set of 2 patches against Simon Horman's 'renesas.git' repo's
>>> 'renesas-devel-20150819-v4.2-rc7' tag. Here we add the VIN and ADV7180
>>> video decoder device tree support on the R8A7794/SILK board. The patchset
>>> requires previously posted SILK SDHI1 support patch in order to apply and
>>> R8A7794/SILK I2C1 support in order to apply and build.
>>>
>>> [1/2] ARM: shmobile: r8a7794: add VIN DT support
>>> [2/2] ARM: shmobile: silk: add VIN0/ADV7180 DT support
>>
>> Thanks, I have queued these up for v4.4.
>
>     Perhaps a bit too early: the PFC VIN patch hasn't been merged yet. Sorry
> for not specifying the PFC dependency...

    OTOH, the frames get captured somehow even without the PFC patch, so might 
as well leave these patches applied. Your choice...

MBR, Sergei



From arnd at arndb.de  Thu Aug 20 13:26:39 2015
From: arnd at arndb.de (Arnd Bergmann)
Date: Thu, 20 Aug 2015 22:26:39 +0200
Subject: [PATCH v2 09/21] ARM: pxa: magician: Add OV9640 camera support
In-Reply-To: <87lhd568sb.fsf@belgarion.home>
References: <cover.1439843482.git.petr.cvek@tul.cz> <55D259A1.6090102@tul.cz>
 <87lhd568sb.fsf@belgarion.home>
Message-ID: <2889798.x6xcIzdYMU@wuerfel>

On Thursday 20 August 2015 21:48:20 Robert Jarzmik wrote:
> Petr Cvek <petr.cvek at tul.cz> writes:
> 
> > +     mdelay(3);
> Okay, there are several mdelay(3) in this file.
> 
> Could you please test if removing these mdelays prevents the camera from working
> ? If not, I'd like to have them removed.
> 
> 

FWIW, it might be possible to replace some of them with msleep() calls,
potentially after replacing spinlocks with mutexes where necessary.

	Arnd


From davem at davemloft.net  Thu Aug 20 14:05:31 2015
From: davem at davemloft.net (David Miller)
Date: Thu, 20 Aug 2015 14:05:31 -0700 (PDT)
Subject: [PATCH v1 0/6] Add fec1 and fec2 support for i.MX7d sdb board
In-Reply-To: <1439962444-27486-1-git-send-email-b38611@freescale.com>
References: <1439962444-27486-1-git-send-email-b38611@freescale.com>
Message-ID: <20150820.140531.1320709021949935376.davem@davemloft.net>

From: Fugang Duan <b38611 at freescale.com>
Date: Wed, 19 Aug 2015 13:33:58 +0800

> The patch series is to add fec support for i.MX7d sdb board. Since i.MX7d fec ip is
> the same as i.MX6SX, so there have no change for driver itself.
> 
> Patch#1: add bcm54220 PHY ID entry into brcmphy.h file.

This is completely, and utterly, pointless.

The only reason a PHY ID should be defined in brcmphy.h is so that it can
be used in the broadcom.c PHY driver or similar.

If there is no user in the tree, there is no reason to add it to the
header file.


From broonie at kernel.org  Thu Aug 20 14:08:30 2015
From: broonie at kernel.org (Mark Brown)
Date: Thu, 20 Aug 2015 14:08:30 -0700
Subject: [PATCH 1/9] spi: sunxi: fix transfer timeout
In-Reply-To: <20150820193433.GH30520@lukather>
References: <cover.1440080122.git.hramrach@gmail.com>
 <0e0b52774a48ddb71dc8095b66942451cd31ff7d.1440080122.git.hramrach@gmail.com>
 <20150820184132.GO12027@sirena.org.uk>
 <20150820193433.GH30520@lukather>
Message-ID: <20150820210830.GS12027@sirena.org.uk>

On Thu, Aug 20, 2015 at 09:34:33PM +0200, Maxime Ripard wrote:
> On Thu, Aug 20, 2015 at 11:41:32AM -0700, Mark Brown wrote:
> > On Thu, Aug 20, 2015 at 02:19:45PM -0000, Michal Suchanek wrote:

> > >  drivers/spi/spi-sun4i.c | 10 +++++++++-
> > >  drivers/spi/spi-sun6i.c | 10 +++++++++-

> > Are we *sure* we can't work on merging these drivers :(

> Those are two different IPs, that don't really share anything but
> their author...

I seem to be seeing a number of changes like this one which make
apparently very similar modifications to both.  Perhaps there is more
core usage that should be happening instead?
-------------- next part --------------
A non-text attachment was scrubbed...
Name: signature.asc
Type: application/pgp-signature
Size: 473 bytes
Desc: Digital signature
URL: <http://lists.infradead.org/pipermail/linux-arm-kernel/attachments/20150820/c5c0c589/attachment-0001.sig>

From f.fainelli at gmail.com  Thu Aug 20 14:14:24 2015
From: f.fainelli at gmail.com (Florian Fainelli)
Date: Thu, 20 Aug 2015 14:14:24 -0700
Subject: [PATCH v1 0/6] Add fec1 and fec2 support for i.MX7d sdb board
In-Reply-To: <20150820.140531.1320709021949935376.davem@davemloft.net>
References: <1439962444-27486-1-git-send-email-b38611@freescale.com>
 <20150820.140531.1320709021949935376.davem@davemloft.net>
Message-ID: <55D64330.4020503@gmail.com>

On 20/08/15 14:05, David Miller wrote:
> From: Fugang Duan <b38611 at freescale.com>
> Date: Wed, 19 Aug 2015 13:33:58 +0800
> 
>> The patch series is to add fec support for i.MX7d sdb board. Since i.MX7d fec ip is
>> the same as i.MX6SX, so there have no change for driver itself.
>>
>> Patch#1: add bcm54220 PHY ID entry into brcmphy.h file.
> 
> This is completely, and utterly, pointless.
> 
> The only reason a PHY ID should be defined in brcmphy.h is so that it can
> be used in the broadcom.c PHY driver or similar.
> 
> If there is no user in the tree, there is no reason to add it to the
> header file.

There is a valid reason for which you may have a PHY id, which is
defining a PHY fixup in your platform code like Andy is doing, however,
this should not be used in conjunction with the Generic PHY driver,
because this driver has absolutely no clue about your PHY fixup, and
this could create at best inconsistencies in how the fixup is managed
later on.

At the very least, I would like to see a change to
drivers/net/phy/broadcom.c which identifies this PHY id, and eventually
just invokes the genphy_* functions where relevant.
-- 
Florian


From maxime.ripard at free-electrons.com  Thu Aug 20 14:18:50 2015
From: maxime.ripard at free-electrons.com (Maxime Ripard)
Date: Thu, 20 Aug 2015 23:18:50 +0200
Subject: [PATCH 1/9] spi: sunxi: fix transfer timeout
In-Reply-To: <20150820210830.GS12027@sirena.org.uk>
References: <cover.1440080122.git.hramrach@gmail.com>
 <0e0b52774a48ddb71dc8095b66942451cd31ff7d.1440080122.git.hramrach@gmail.com>
 <20150820184132.GO12027@sirena.org.uk>
 <20150820193433.GH30520@lukather>
 <20150820210830.GS12027@sirena.org.uk>
Message-ID: <20150820211850.GI30520@lukather>

On Thu, Aug 20, 2015 at 02:08:30PM -0700, Mark Brown wrote:
> On Thu, Aug 20, 2015 at 09:34:33PM +0200, Maxime Ripard wrote:
> > On Thu, Aug 20, 2015 at 11:41:32AM -0700, Mark Brown wrote:
> > > On Thu, Aug 20, 2015 at 02:19:45PM -0000, Michal Suchanek wrote:
> 
> > > >  drivers/spi/spi-sun4i.c | 10 +++++++++-
> > > >  drivers/spi/spi-sun6i.c | 10 +++++++++-
> 
> > > Are we *sure* we can't work on merging these drivers :(
> 
> > Those are two different IPs, that don't really share anything but
> > their author...
> 
> I seem to be seeing a number of changes like this one which make
> apparently very similar modifications to both.  Perhaps there is more
> core usage that should be happening instead?

Yeah, because I wrote the two at the same time, and they share the
same flaws. But that doesn't really mean that you can share anything
at the driver level. And I'm not really sure that we can do much more
at the framework level either, except maybe handling the timeout
directly (but then the drivers would have to handle the recovering
after a timeout too).

Maxime

-- 
Maxime Ripard, Free Electrons
Embedded Linux, Kernel and Android engineering
http://free-electrons.com
-------------- next part --------------
A non-text attachment was scrubbed...
Name: signature.asc
Type: application/pgp-signature
Size: 819 bytes
Desc: Digital signature
URL: <http://lists.infradead.org/pipermail/linux-arm-kernel/attachments/20150820/6f6ae098/attachment.sig>

From maxime.ripard at free-electrons.com  Thu Aug 20 14:23:36 2015
From: maxime.ripard at free-electrons.com (Maxime Ripard)
Date: Thu, 20 Aug 2015 23:23:36 +0200
Subject: [PATCH 3/9] spi: sunxi: check that transfer speed is non-zero
In-Reply-To: <CAOMqctSfdxWeWDogzHxONE+Qxf7vp6rJnBmxECV89PQO0hXARg@mail.gmail.com>
References: <cover.1440080122.git.hramrach@gmail.com>
 <3688fab67e7cdc7bcbff73dfd6b0fcdcc4e79eb6.1440080122.git.hramrach@gmail.com>
 <20150820144836.GV30520@lukather>
 <CAOMqctSfdxWeWDogzHxONE+Qxf7vp6rJnBmxECV89PQO0hXARg@mail.gmail.com>
Message-ID: <20150820212336.GJ30520@lukather>

On Thu, Aug 20, 2015 at 09:45:07PM +0200, Michal Suchanek wrote:
> On 20 August 2015 at 16:48, Maxime Ripard
> <maxime.ripard at free-electrons.com> wrote:
> > On Thu, Aug 20, 2015 at 02:19:46PM -0000, Michal Suchanek wrote:
> >> When the maximum transfer speed is not set for a SPI slave the value
> >> remains 0 and the code in sunxi SPI divides by it. Use an arbitrary
> >> speed instead in that case.
> >>
> >> Signed-off-by: Michal Suchanek <hramrach at gmail.com>
> >
> > spi->max_speed_hz is set using the spi-max-frequency property, and
> > spi->will error out if that property isn't set. What am I missing?
> >
> 
> Spidev I guess.
> 
> You can set the speed to arbitrary value from userspace at any time
> using the spidev ioctls.

Then why should it be fixed at the controller driver level? It looks
more like an issue that impacts everyone and should be fixed either in
spidev directly or in the framework.

-- 
Maxime Ripard, Free Electrons
Embedded Linux, Kernel and Android engineering
http://free-electrons.com
-------------- next part --------------
A non-text attachment was scrubbed...
Name: signature.asc
Type: application/pgp-signature
Size: 819 bytes
Desc: Digital signature
URL: <http://lists.infradead.org/pipermail/linux-arm-kernel/attachments/20150820/579970a2/attachment.sig>

From maxime.ripard at free-electrons.com  Thu Aug 20 14:24:46 2015
From: maxime.ripard at free-electrons.com (Maxime Ripard)
Date: Thu, 20 Aug 2015 23:24:46 +0200
Subject: [PATCH v3 1/8] rsb: Add generic Reduced Serial Bus (RSB)
 controller binding documentation
In-Reply-To: <CAGb2v65jnU859gQG0orb9M9pR6nKcth9EPcgmmR5fckdHxngrQ@mail.gmail.com>
References: <1439958009-14056-1-git-send-email-wens@csie.org>
 <1439958009-14056-2-git-send-email-wens@csie.org>
 <20150820150845.GB30520@lukather>
 <CAGb2v65jnU859gQG0orb9M9pR6nKcth9EPcgmmR5fckdHxngrQ@mail.gmail.com>
Message-ID: <20150820212446.GK30520@lukather>

On Thu, Aug 20, 2015 at 11:58:39PM +0800, Chen-Yu Tsai wrote:
> >> +Child nodes:
> >> +
> >> +An RSB controller node can contain zero or more child nodes representing
> >> +slave devices on the bus.  Child 'reg' properties are specified as a
> >> +runtime address, hardware address pair. The hardware address is hardwired
> >> +in the device, which can normally be found in the datasheet. The runtime
> >> +address is set by software. No 2 devices on the same bus shall have the
> >> +same runtime address.
> >> +
> >> +Valid runtime addresses - There are only 15 valid runtime addresses:
> >> +
> >> +    0x17, 0x2d, 0x3a, 0x4e, 0x59, 0x63, 0x74, 0x8b,
> >> +    0x9c, 0xa6, 0xb1, 0xc5, 0xd2, 0xe8, 0xff
> >> +
> >> +It is highly recommended that one choose the same runtime addresses as
> >> +vendor BSPs use so that a) the addresses remain the same across different
> >> +software systems, and b) addresses of supported and listed slave devices
> >> +don't conflict with unsupported or not yet listed devices.
> >
> > I'd expect to have the hardware address first, but maybe it's just me
> > :)
> 
> I don't know. It's only used at init time.
> 
> And in my latest experience, once the runtime address is set by the
> bootloader, it can't be changed. My earlier experience was the opposite,
> though I haven't figured out why.

Note that I'm only talking about the order of runtime and hardware
addresses in the reg property, having both is fine.

Maxime

-- 
Maxime Ripard, Free Electrons
Embedded Linux, Kernel and Android engineering
http://free-electrons.com
-------------- next part --------------
A non-text attachment was scrubbed...
Name: signature.asc
Type: application/pgp-signature
Size: 819 bytes
Desc: Digital signature
URL: <http://lists.infradead.org/pipermail/linux-arm-kernel/attachments/20150820/298034df/attachment.sig>

From broonie at kernel.org  Thu Aug 20 14:29:07 2015
From: broonie at kernel.org (Mark Brown)
Date: Thu, 20 Aug 2015 14:29:07 -0700
Subject: [PATCH 1/9] spi: sunxi: fix transfer timeout
In-Reply-To: <20150820211850.GI30520@lukather>
References: <cover.1440080122.git.hramrach@gmail.com>
 <0e0b52774a48ddb71dc8095b66942451cd31ff7d.1440080122.git.hramrach@gmail.com>
 <20150820184132.GO12027@sirena.org.uk>
 <20150820193433.GH30520@lukather>
 <20150820210830.GS12027@sirena.org.uk>
 <20150820211850.GI30520@lukather>
Message-ID: <20150820212907.GV12027@sirena.org.uk>

On Thu, Aug 20, 2015 at 11:18:50PM +0200, Maxime Ripard wrote:

> at the driver level. And I'm not really sure that we can do much more
> at the framework level either, except maybe handling the timeout
> directly (but then the drivers would have to handle the recovering
> after a timeout too).

We have handle_err() for that sort of cleanup.
-------------- next part --------------
A non-text attachment was scrubbed...
Name: signature.asc
Type: application/pgp-signature
Size: 473 bytes
Desc: Digital signature
URL: <http://lists.infradead.org/pipermail/linux-arm-kernel/attachments/20150820/aa6e52ea/attachment.sig>

From mark.rutland at arm.com  Thu Aug 20 14:30:29 2015
From: mark.rutland at arm.com (Mark Rutland)
Date: Thu, 20 Aug 2015 22:30:29 +0100
Subject: [PATCH v5 1/5] arm/arm64: add smccc ARCH32
In-Reply-To: <20150820113729.GA25962@ermac>
References: <1439973629-19505-1-git-send-email-jens.wiklander@linaro.org>
 <1439973629-19505-2-git-send-email-jens.wiklander@linaro.org>
 <20150819165009.GC10297@arm.com> <20150820113729.GA25962@ermac>
Message-ID: <20150820213029.GA1426@svinekod>

On Thu, Aug 20, 2015 at 12:37:29PM +0100, Jens Wiklander wrote:
> On Wed, Aug 19, 2015 at 05:50:09PM +0100, Will Deacon wrote:
> > On Wed, Aug 19, 2015 at 09:40:25AM +0100, Jens Wiklander wrote:
> > > Adds helpers to do SMC based on ARM SMC Calling Convention.
> > > CONFIG_HAVE_SMCCC is enabled for architectures that may support
> > > the SMC instruction. It's the responsibility of the caller to
> > > know if the SMC instruction is supported by the platform.

[...]

> > > +       mov     x28, x0
> > > +       ldp     w0, w1, [x28, #SMC_PARAM_W0_OFFS]
> > > +       ldp     w2, w3, [x28, #SMC_PARAM_W2_OFFS]
> > > +       ldp     w4, w5, [x28, #SMC_PARAM_W4_OFFS]
> > > +       ldp     w6, w7, [x28, #SMC_PARAM_W6_OFFS]
> > > +       smc     #0
> > > +       stp     w0, w1, [x28, #SMC_PARAM_W0_OFFS]
> > > +       stp     w2, w3, [x28, #SMC_PARAM_W2_OFFS]
> > > +       ldp     x28, x30, [sp], #16
> > > +       ret
> > > +ENDPROC(smccc_call32)
> > 
> > Could we deal with this like we do for PSCI instead? (see
> > __invoke_psci_fn_smc). We could also then rename psci-call.S to fw-call.S
> > and stick this in there too.
> 
> I assume you're referring to when to use "hvc" and "smc".

I assume he's on about passing the values in registers rather than a struct.

>From the looks of the SMC Calling Convention documentation, it's valid to have
return values in registers r0-r3, which necessitates the use of a struct (at
least for the return values).

Thanks,
Mark.



From herbert at gondor.apana.org.au  Thu Aug 20 15:08:18 2015
From: herbert at gondor.apana.org.au (Herbert Xu)
Date: Fri, 21 Aug 2015 06:08:18 +0800
Subject: un4i-ss-cipher.c warning
In-Reply-To: <55D5DC97.1040209@gmail.com>
References: <CAOMqctShdb9xEkBmuaQKfB1cwGupbfH5TS5ZB_P85Hwpn+4zAA@mail.gmail.com>
 <55D5DC97.1040209@gmail.com>
Message-ID: <20150820220818.GA2850@gondor.apana.org.au>

On Thu, Aug 20, 2015 at 03:56:39PM +0200, Corentin LABBE wrote:
> 
> Thanks for the report, strange that I do not have that warning.
> todo is always initialized, since oleft and ileft are always > 0 at start.
> But setting todo to 0 is a simple fix.
> The following patch will suppress the warning.

Nack.  Please do not fix spurious uninitialised warnings in this
way.  Not only is this pointless but if someone introduced a real
uninitialised bug later on we'd never catch it because of this.

Cheers,
-- 
Email: Herbert Xu <herbert at gondor.apana.org.au>
Home Page: http://gondor.apana.org.au/~herbert/
PGP Key: http://gondor.apana.org.au/~herbert/pubkey.txt


From maxime.ripard at free-electrons.com  Thu Aug 20 15:12:59 2015
From: maxime.ripard at free-electrons.com (Maxime Ripard)
Date: Fri, 21 Aug 2015 00:12:59 +0200
Subject: [PATCH 2/3] ARM: dts: sun6i: Turn on gmac on Colombus
In-Reply-To: <55D5725F.6000106@redhat.com>
References: <1438960955-6551-1-git-send-email-hdegoede@redhat.com>
 <1438960955-6551-2-git-send-email-hdegoede@redhat.com>
 <20150819151754.GH30520@lukather> <55D5725F.6000106@redhat.com>
Message-ID: <20150820221259.GM30520@lukather>

On Thu, Aug 20, 2015 at 08:23:27AM +0200, Hans de Goede wrote:
> Hi,
> 
> On 08/19/2015 05:17 PM, Maxime Ripard wrote:
> >On Fri, Aug 07, 2015 at 05:22:34PM +0200, Hans de Goede wrote:
> >>We've everything we need to support the gmac on Colombus, turn it on.
> >>
> >>Signed-off-by: Hans de Goede <hdegoede at redhat.com>
> >
> >I recall that the phy was powered by one of the AXP221 regulators,
> >does it require some additional stuff (like a recent u-boot), or does
> >it just work and my memory is bad :) ?
> 
> I think it just works, it MAY be connected to aldo1 but according to
> the git history for the u-boot defconfig that one is used for wifi not
> for the gmac, and we do not enable any other "spare" regulators in the
> u-boot config.
> 
> I do not have any schematics, so no way to say for sure.
> 
> I can confirm that the GMAC work fine with the latest u-boot
> master. Looking in the history we've always enabled ALDO1
> on the Colombus in upstream u-boot, so this should all just work.

Except that if it is the case, the DT was working fine with the stock
bootloader, and it doesn't anymore, while we have no way to upgrade
it.

Maxime

-- 
Maxime Ripard, Free Electrons
Embedded Linux, Kernel and Android engineering
http://free-electrons.com
-------------- next part --------------
A non-text attachment was scrubbed...
Name: signature.asc
Type: application/pgp-signature
Size: 819 bytes
Desc: Digital signature
URL: <http://lists.infradead.org/pipermail/linux-arm-kernel/attachments/20150821/844b98f9/attachment.sig>

From maxime.ripard at free-electrons.com  Thu Aug 20 15:14:57 2015
From: maxime.ripard at free-electrons.com (Maxime Ripard)
Date: Fri, 21 Aug 2015 00:14:57 +0200
Subject: [PATCH] ARM: dts: sun6i: hummingbird: Add missing pinmux setting
 for gmac phy reset
In-Reply-To: <1439974642-12091-1-git-send-email-wens@csie.org>
References: <1439974642-12091-1-git-send-email-wens@csie.org>
Message-ID: <20150820221457.GN30520@lukather>

On Wed, Aug 19, 2015 at 04:57:22PM +0800, Chen-Yu Tsai wrote:
> Signed-off-by: Chen-Yu Tsai <wens at csie.org>

Queued, thanks!

Maxime

-- 
Maxime Ripard, Free Electrons
Embedded Linux, Kernel and Android engineering
http://free-electrons.com
-------------- next part --------------
A non-text attachment was scrubbed...
Name: signature.asc
Type: application/pgp-signature
Size: 819 bytes
Desc: Digital signature
URL: <http://lists.infradead.org/pipermail/linux-arm-kernel/attachments/20150821/4f82bc9a/attachment.sig>

From petr.cvek at tul.cz  Thu Aug 20 15:21:04 2015
From: petr.cvek at tul.cz (Petr Cvek)
Date: Fri, 21 Aug 2015 00:21:04 +0200
Subject: [PATCH v2 12/21] ARM: pxa: magician: Add PXA27x UDC support
In-Reply-To: <87twrt6fh5.fsf@belgarion.home>
References: <cover.1439843482.git.petr.cvek@tul.cz> <55D25A06.9030507@tul.cz>
 <87twrt6fh5.fsf@belgarion.home>
Message-ID: <55D652D0.90903@tul.cz>

Dne 20.8.2015 v 19:23 Robert Jarzmik napsal(a):
> Petr Cvek <petr.cvek at tul.cz> writes:
> 
>> Add support for PXA27x UDC to HTC Magician.
>>
>> Signed-off-by: Petr Cvek <petr.cvek at tul.cz>
>> ---
>>  arch/arm/mach-pxa/magician.c | 40 +++++++++++++++++++++++++++++++++++++++-
>>  1 file changed, 39 insertions(+), 1 deletion(-)
>>
>> diff --git a/arch/arm/mach-pxa/magician.c b/arch/arm/mach-pxa/magician.c
>> index 8ca0b67..23b59a0 100644
>> --- a/arch/arm/mach-pxa/magician.c
>> +++ b/arch/arm/mach-pxa/magician.c
>> @@ -98,6 +98,10 @@
>>  
>>  #include <linux/regulator/max1586.h>
>>  
>> +#include <linux/platform_data/pxa2xx_udc.h>
>> +#include <mach/udc.h>
>> +#include <mach/pxa27x-udc.h>
>> +
>>  #include "devices.h"
>>  #include "generic.h"
>>  
>> @@ -698,6 +702,34 @@ static struct platform_device magician_camera = {
>>   * USB "Transceiver"
>>   */
>>  
>> +#if IS_ENABLED(CONFIG_USB_PXA27X)
> No #if please, just let it out of #ifdefery, no need to.
> 
>> +static void magician_udc_command(int cmd)
>> +{
>> +	if (cmd == PXA2XX_UDC_CMD_CONNECT)
>> +		UP2OCR |= UP2OCR_DPPUE | UP2OCR_DPPUBE;
>> +	else if (cmd == PXA2XX_UDC_CMD_DISCONNECT)
>> +		UP2OCR &= ~(UP2OCR_DPPUE | UP2OCR_DPPUBE);
>> +}
>> +
>> +/* HACK, shared USB connected state with pda-power */
>> +int my_usb_online = 1;
> Definitely not, a global (ie. non static variable) is not something I'll let
> in. Besides, can't a "gpio_get_value()" give the same level of information ?

I will gladly remove it, but I want my phone to be able to charge and work as USB device (and maybe as USB host).

> 
>> +static int magician_udc_is_connected(void)
>> +{
>> +	/* Shared with pda_power or gpio-vbus */
>> +	return my_usb_online;
> gpio_get_value() something ?
> 

I need to use EGPIO_MAGICIAN_CABLE_INSERT1 GPIO in pda_power to be able to detect source for charging.

>> +}
>> +
>> +static struct pxa2xx_udc_mach_info magician_udc_info __initdata = {
>> +	.udc_command		= magician_udc_command,
>> +	.udc_is_connected	= magician_udc_is_connected,
> I don't think udc_is_connected is a field used by pxa27x_udc.c, it it ? The VBus
> connection information comes from a transciever, usually from gpio_vbus driver
> nowadays.

Really? Well I guess I took a bad route :-D (when I tried to learn how to add an udc support). As there are two ways to define udc_is_connected, would it be possible to remove this field altogether (only mioa701 and lubbock have relevant use, but if this function is never called, then it is dead code)?

Do you know which code / source is responsible for gpio_vbus -> pxa27x_udc communication about inserted cable? I will need to put some assert for testing.

> 
>> @@ -1175,6 +1207,11 @@ static struct platform_device *devices[] __initdata = {
>>  
>>  	/* NOTICE mutually exclusive with PXA I2C */
>>  	&i2c_gpio_bus_alt,
>> +
>> +	/* NOTICE mutually exclusive with UDC*/
> Euh why so ?
> In arch/arm/mach-pxa/mioa701.c they cooperate, why can't they for magician ?

In mioa701 the GPIO13_nUSB_DETECT GPIO is requested by gpio_vbus driver, used in pda_power (without request) and "used" in PXA UDC driver without request. It is basically similar solution as my (ugly) global variable.

Solution: I will try to use that second new GPIO (EGPIO_MAGICIAN_CABLE_INSERT2) for that, so there is no GPIO request dependency. I may create new names for them (magician.h).

> 
> Cheers.
> 
Best regards,
Petr


From petr.cvek at tul.cz  Thu Aug 20 15:33:41 2015
From: petr.cvek at tul.cz (Petr Cvek)
Date: Fri, 21 Aug 2015 00:33:41 +0200
Subject: [PATCH v2 11/21] ARM: pxa: magician: Add MAX1586 Vcore regulator
 support
In-Reply-To: <87pp2h69iy.fsf@belgarion.home>
References: <cover.1439843482.git.petr.cvek@tul.cz> <55D259CC.6040307@tul.cz>
 <87pp2h69iy.fsf@belgarion.home>
Message-ID: <55D655C5.40506@tul.cz>

Dne 20.8.2015 v 21:32 Robert Jarzmik napsal(a):
> Petr Cvek <petr.cvek at tul.cz> writes:
> 
>> Add support for MAX1586 Vcore regulator.
>>
>> Signed-off-by: Petr Cvek <petr.cvek at tul.cz>
> I'll leave that for a week and if no objections queue it.
> 
> I would have expected a better commit message : for example, from your patch I
> deduce magician has a 1587 regulator, not a 1586 one : that deserves a small
> mention in the commit message. Moreover, the Maxim has 2 outputs : one is
> connected to VCC_Core of the SoC, what about the other output ?  Is it unknown,
> or do you know but don't use it ?
> 
You mean V6 - Usim? MAX1587 does not have this pin implemented. I will note it in commit message.


> Cheers.
> 
> --
> Robert
> 



From clemens.gruber at pqgruber.com  Thu Aug 20 15:30:50 2015
From: clemens.gruber at pqgruber.com (Clemens Gruber)
Date: Fri, 21 Aug 2015 00:30:50 +0200
Subject: RX packet loss on i.MX6Q running 4.2-rc7
Message-ID: <20150820223049.GA20710@pqgruber.com>

Hi,

I am experiencing massive RX packet loss on my i.MX6Q (Chip rev 1.3) on Linux
4.2-rc7 with a Marvell 88E1510 Gigabit Ethernet PHY connected over RGMII.
I noticed it when doing an UDP benchmark with iperf3. When sending UDP packets
from a Debian PC to the i.MX6 with a rate of 100 Mbit/s, 99% of the packets are
lost. With a rate of 10 Mbit/s, we are still losing 93% of all packets. TCP RX
does suffer from packet loss too, but still achieves about 211 Mbit/s.
TX is not affected.

Steps to reproduce:
On the i.MX6: iperf3 -s
On a desktop PC:  iperf3 -b 10M -u -c MX6IP

The iperf3 results:
[ ID] Interval           Transfer     Bandwidth       Jitter    Lost/Total
[  4]   0.00-10.00  sec  11.8 MBytes  9.90 Mbits/sec  0.687 ms  1397/1497 (93%)

During the 10 Mbit UDP test, the IEEE_rx_macerr counter increased to 5371.
ifconfig eth0 shows:
 RX packets:9216 errors:5248 dropped:170 overruns:5248 frame:5248
 TX packets:83 errors:0 dropped:0 overruns:0 carrier:0
 collisions:0

Here are the TCP results with iperf3 -c MX6IP:
[ ID] Interval           Transfer     Bandwidth       Retr
[  4]   0.00-10.00  sec   252 MBytes   211 Mbits/sec  4343             sender
[  4]   0.00-10.00  sec   251 MBytes   211 Mbits/sec                  receiver

During the TCP test, IEEE_rx_macerr increased to 4059.
ifconfig eth0 shows:
RX packets:186368 errors:4206 dropped:50 overruns:4206 frame:4206
TX packets:41861 errors:0 dropped:0 overruns:0 carrier:0
collisions:0

Freescale errata entry ERR004512 did mention a RX FIFO overrun. Is this related?

Forcing pause frames via ethtool -A eth0 rx on tx on, does not improve it:
Same amount of UDP packet loss with reduced TCP throughput of 190 Mbit/s.
IEEE_rx_macerr increased up to 5232 during UDP 10Mbit and up to 4270 for TCP.

I am already using the MX6QDL_PAD_GPIO_6__ENET_IRQ workaround, which solved the
ping latency issues from ERR006687 but not the packet loss problem.

I read through the mailing list archives and found a discussion between Russell
King, Marek Vasut, Eric Nelson, Fugang Duan and others about a similar problem.
I therefore added you and contributors to fec_main.c to the CC.

One suggestion I found, was adding udelay(210); to fec_enet_rx():
https://lkml.org/lkml/2014/8/22/88
But this also did not reduce the packet loss. (I added it to the fec_enet_rx
function just before return pkt_received; but I still got 93% packet loss)

Does anyone have the equipment/setup to trace an i.MX6Q during UDP RX traffic
from iperf3 to find the root cause of this packet loss problem?

What else could we do to fix this?

Thanks,
Clemens


From petr.cvek at tul.cz  Thu Aug 20 15:39:30 2015
From: petr.cvek at tul.cz (Petr Cvek)
Date: Fri, 21 Aug 2015 00:39:30 +0200
Subject: [PATCH v2 09/21] ARM: pxa: magician: Add OV9640 camera support
In-Reply-To: <2889798.x6xcIzdYMU@wuerfel>
References: <cover.1439843482.git.petr.cvek@tul.cz> <55D259A1.6090102@tul.cz>
 <87lhd568sb.fsf@belgarion.home> <2889798.x6xcIzdYMU@wuerfel>
Message-ID: <55D65722.9030508@tul.cz>

Dne 20.8.2015 v 22:26 Arnd Bergmann napsal(a):
> On Thursday 20 August 2015 21:48:20 Robert Jarzmik wrote:
>> Petr Cvek <petr.cvek at tul.cz> writes:
>>
>>> +     mdelay(3);
>> Okay, there are several mdelay(3) in this file.
>>
>> Could you please test if removing these mdelays prevents the camera from working
>> ? If not, I'd like to have them removed.
>>
>>
> 
> FWIW, it might be possible to replace some of them with msleep() calls,
> potentially after replacing spinlocks with mutexes where necessary.
> 
> 	Arnd
> 

Datasheet says:

	tS:RESET	Setting time after software/hardware reset	1 ms

So at least one ~1 ms should be left there. Are msleep less than 20ms valid? 

(checkpatch: msleep < 20ms  can sleep for up to 20ms)

Petr



From petr.cvek at tul.cz  Thu Aug 20 16:01:06 2015
From: petr.cvek at tul.cz (Petr Cvek)
Date: Fri, 21 Aug 2015 01:01:06 +0200
Subject: [PATCH v2 10/21] ARM: pxa: magician: Add UDA1380 sound support
In-Reply-To: <87h9nt68mm.fsf@belgarion.home>
References: <cover.1439843482.git.petr.cvek@tul.cz> <55D259B7.90703@tul.cz>
 <87h9nt68mm.fsf@belgarion.home>
Message-ID: <55D65C32.6080503@tul.cz>

Dne 20.8.2015 v 21:51 Robert Jarzmik napsal(a):
> Petr Cvek <petr.cvek at tul.cz> writes:
> 
>> +/*
>> + * Magician Audio controller
>> + */
>> +
>> +static struct platform_device magician_audio_device = {
>> +	.name = "magician-audio",
> Is this already upstream or is it a submission in progress ? Other than that
> detail, I'll queue it in a week probably.

This one is problematic. Vanilla version did not work from at least 3.4 (where I started, but probably even more in past). Somewhere between 3.13 and ~4.1 there is a change which causes it to fail after driver reload (bad pointers I think). UDA codec routes are not constructed completely and in ~4.1 they are refused, there are some swapped control registers and bad DMA definitions. Oh and recording stopped to work too (maybe it is caused by that routes).

I tried to send initial separate patches (for DMA and registers), but it got stuck somewhere (at least it is not in 4.2rcX and I sent them around start of this year).

I can add some of these patches to this patchset (but I didn't started yet on failing reload, record and fixing the routes).

> 
> Cheers.
> 
> --
> Robert
> 



From laurent.pinchart at ideasonboard.com  Thu Aug 20 16:01:59 2015
From: laurent.pinchart at ideasonboard.com (Laurent Pinchart)
Date: Fri, 21 Aug 2015 02:01:59 +0300
Subject: [PATCH] dmaengine: vdma: Add 64 bit addressing support to the
 driver
In-Reply-To: <3802E9A6666DF54886E2B9CBF743BA9801BF8264@XAP-PVEXMBX01.xlnx.xilinx.com>
References: <1438775257-3511-1-git-send-email-anuragku@xilinx.com>
 <2214014.FVHbR3JRBK@avalon>
 <3802E9A6666DF54886E2B9CBF743BA9801BF8264@XAP-PVEXMBX01.xlnx.xilinx.com>
Message-ID: <2348343.VuhoH7scrX@avalon>

Hi Anurag,

On Thursday 20 August 2015 10:47:48 Anurag Kumar Vulisha wrote:
> On Thursday, August 20, 2015 2:41 PM Anurag Kumar Vulisha wrote:
> > On Wednesday 05 August 2015 17:17:37 Anurag Kumar Vulisha wrote:
> >> This patch adds the 64 bit addressing support to the vdma driver.
> >> 
> >> Signed-off-by: Anurag Kumar Vulisha <anuragku at xilinx.com>
> >> ---
> >> 
> >> drivers/dma/Kconfig              |    2 +-
> >> drivers/dma/xilinx/xilinx_vdma.c |   36 +++++++++++++++++++++++++------
> >>
> >> 2 files changed, 31 insertions(+), 7 deletions(-)

[snip]

> >> diff --git a/drivers/dma/xilinx/xilinx_vdma.c
> >> b/drivers/dma/xilinx/xilinx_vdma.c index d8434d4..3dcbd29 100644
> >> --- a/drivers/dma/xilinx/xilinx_vdma.c
> >> +++ b/drivers/dma/xilinx/xilinx_vdma.c

[snip]

> >> @@ -272,6 +276,20 @@ static inline void vdma_desc_write(struct
> >> xilinx_vdma_chan *chan, u32 reg, vdma_write(chan, chan->desc_offset +
> >> reg, value);  }
> >> 
> >> +#if defined(CONFIG_PHYS_ADDR_T_64BIT) static inline void
> >> +vdma_desc_write_64(struct xilinx_vdma_chan *chan, u32
> >> reg,
> >> +				 u64 value)
> >> +{
> >> +	/* Write the lsb 32 bits*/
> >> +	writel(lower_32_bits(value),
> >> +			chan->xdev->regs + chan->desc_offset + reg);
> >> +
> >> +	/* Write the msb 32 bits */
> >> +	writel(upper_32_bits(value),
> >> +			chan->xdev->regs + chan->desc_offset + reg + 4);
> > 
> > So the CPU can't perform 64-bit register access ?
> 
> We are trying to write at a register address(0x5c) which is not aligned on
> 8 bytes boundary.So if I try to use 64 bit write on it, unalignment fault
> will be generated. Because of this we are using two separate 32  bit
> writes.

Broken hardware design. Fair enough :-)

> > How is 64 bit DMA addressing implemented ? Can you use a 64-bit VDMA on
> > a 32- bit platform with LPAE ? Can you use a 32-bit VDMA on a 64-bit
> > platform ? Given that VDMA is an IP core you can instantiate in the
> > programmable logic I expect some level of flexibility to be possible, but
> > this patch doesn't seem to support it. Please provide more context to
> > allow a proper review (and please include it in the commit message of v2).
> 
> The VDMA core is a soft ip, which can be programmed to support both 32 bit
> and 64 bit addressing.When the VDMA core is configured for 32 bit address
> space , transfer start address is specified by a single register.
> 
> When the  VDMA core is configured for an address space greater than 32, each
> start address is specified by a combination of two registers.The first
> register specifies the LSB 32 bits of address, while the next register
> specifies the MSB 32 bits of address.For example,5Ch will specify the LSB
> bits while 60h will specify the MSB bits of the first start address. So we
> need to program two registers at a time.
> 
> Yes,64 bit vdma can be used on 32 bit platform and 32 bit vdma can also be
> used on 64 bit platform.As far as i know , there is no use case where 64
> bit dma can be used on 32 bit platform.Please correct me if i am wrong.

I'm not sure what the use cases would be, but it makes me feel uncomfortable 
to decide on whether the VDMA is 32 or 64 bits based on the type of CPU.

As the VDMA flavour is selected at synthesis time, how about specifying it in 
DT instead ? You could just add an address-width property.

-- 
Regards,

Laurent Pinchart



From horms at verge.net.au  Thu Aug 20 16:11:14 2015
From: horms at verge.net.au (Simon Horman)
Date: Thu, 20 Aug 2015 16:11:14 -0700
Subject: [PATCH 0/2] Add VIN and ADV7180 device tree support for
 R8A7794/SILK board
In-Reply-To: <55D6363F.4050207@cogentembedded.com>
References: <1750082.WpWf34HsI6@wasted.cogentembedded.com>
 <20150820185435.GE18990@verge.net.au>
 <55D624AD.7060801@cogentembedded.com>
 <55D6363F.4050207@cogentembedded.com>
Message-ID: <20150820231114.GN18990@verge.net.au>

On Thu, Aug 20, 2015 at 11:19:11PM +0300, Sergei Shtylyov wrote:
> On 08/20/2015 10:04 PM, Sergei Shtylyov wrote:
> 
> >>>    Here's the set of 2 patches against Simon Horman's 'renesas.git' repo's
> >>>'renesas-devel-20150819-v4.2-rc7' tag. Here we add the VIN and ADV7180
> >>>video decoder device tree support on the R8A7794/SILK board. The patchset
> >>>requires previously posted SILK SDHI1 support patch in order to apply and
> >>>R8A7794/SILK I2C1 support in order to apply and build.
> >>>
> >>>[1/2] ARM: shmobile: r8a7794: add VIN DT support
> >>>[2/2] ARM: shmobile: silk: add VIN0/ADV7180 DT support
> >>
> >>Thanks, I have queued these up for v4.4.
> >
> >    Perhaps a bit too early: the PFC VIN patch hasn't been merged yet. Sorry
> >for not specifying the PFC dependency...
> 
>    OTOH, the frames get captured somehow even without the PFC patch, so
> might as well leave these patches applied. Your choice...

Thanks. I will defer these patches for now.


From horms+renesas at verge.net.au  Thu Aug 20 16:27:44 2015
From: horms+renesas at verge.net.au (Simon Horman)
Date: Thu, 20 Aug 2015 16:27:44 -0700
Subject: [PATCH] ARM: shmobile: remove Makefile.boot
Message-ID: <1440113264-30359-1-git-send-email-horms+renesas@verge.net.au>

Now that the only multiplatform boot is supported for all
shmobile platforms Makefile.boot may be removed.

This seems correct to me given:
* Setting MACHINE to no value in arch/arm/Makefile
  if CONFIG_ARCH_MULTIPLATFORM is set
* Not including Makefile.boot in arch/arm/boot/Makefile
  if MACHINE has no value

Signed-off-by: Simon Horman <horms+renesas at verge.net.au>
---
 arch/arm/mach-shmobile/Makefile.boot | 0
 1 file changed, 0 insertions(+), 0 deletions(-)
 delete mode 100644 arch/arm/mach-shmobile/Makefile.boot

---

Based on renesas-devel-20150820v2-v4.2-rc7

diff --git a/arch/arm/mach-shmobile/Makefile.boot b/arch/arm/mach-shmobile/Makefile.boot
deleted file mode 100644
index e69de29bb2d1..000000000000
-- 
2.1.4



From broonie at kernel.org  Thu Aug 20 16:46:29 2015
From: broonie at kernel.org (Mark Brown)
Date: Thu, 20 Aug 2015 16:46:29 -0700
Subject: [PATCH v2 0/4] regmap: i2c block support
In-Reply-To: <1440064807-26346-1-git-send-email-mpa@pengutronix.de>
References: <1440064807-26346-1-git-send-email-mpa@pengutronix.de>
Message-ID: <20150820234629.GB12027@sirena.org.uk>

On Thu, Aug 20, 2015 at 12:00:03PM +0200, Markus Pargmann wrote:
> Hi,
> 
> This series adds support for i2c block read/writes. To support the maximum 32
> byte read/write operations, the regmap core is extended by max_raw_read and
> max_raw_write. bulk operations are splitted depending of the size of
> max_raw_read/write.

This looks basically fine but depends on the previous fixes series
AFAICT.
-------------- next part --------------
A non-text attachment was scrubbed...
Name: signature.asc
Type: application/pgp-signature
Size: 473 bytes
Desc: Digital signature
URL: <http://lists.infradead.org/pipermail/linux-arm-kernel/attachments/20150820/152cc54d/attachment.sig>

From alexandre.belloni at free-electrons.com  Thu Aug 20 16:58:19 2015
From: alexandre.belloni at free-electrons.com (Alexandre Belloni)
Date: Fri, 21 Aug 2015 01:58:19 +0200
Subject: [GIT PULL] at91: defconfig for 4.3 #2
In-Reply-To: <CAOesGMhwAYUAMLyT6TH38-0VmZNLEpcd_=Tq=EF1KJ=eywBmUw@mail.gmail.com>
References: <20150807162754.GA20169@piout.net>
 <20150813100938.GN30160@localhost>
 <20150813112118.GA22269@piout.net>
 <20150813122643.GA23581@localhost>
 <20150814092237.3551c03e@canb.auug.org.au>
 <CAOesGMhwAYUAMLyT6TH38-0VmZNLEpcd_=Tq=EF1KJ=eywBmUw@mail.gmail.com>
Message-ID: <20150820235819.GH3769@piout.net>

Hi,

On 18/08/2015 at 23:49:30 +0200, Olof Johansson wrote :
> > The only thing now is that since the at91 tree is in linux-next as well
> > as the arm-soc tree, those patches appear twice there and there is a
> > conflict (easy to fix, but a pain).  The solution here is to update the
> > at91 tree to be somewhere in the arm-soc tree (probably just reset to
> > the point where the two trees match in patches but not commits).  This
> > has the downside that the at91 tree will be rebased which will affect
> > any development work that is based on that.
> >
> > If there was just one patch in common, it maybe have been better to
> > just merge the at91 tree and fix the conflict in the merge.
> 
> Yeah, this is a somewhat frustrating situation for us. I wonder if we
> should essentially tag the downstream ARM platform trees in -next such
> that if they conflict with arm-soc, you can drop them for a day if
> needed.
> 
> It's really useful for us to be able to occasionally adjust a pull
> request instead of always merging them exactly as they're presented to
> us. It saves a roundtrip to the maintainer for trivial stuff, we can
> take care of it and not have to look at it again. We often do send it
> back to the maintainers to respin, but in this particular case it
> seemed appropriate to just deal with it locally for us.
> 
> The downstream users vs rebasing git trees is of course another
> aspect. Here I'm mostly relying on subplatform maintainers to know
> well how many people actually develop on top of their trees. I think
> for most platforms it's a fairly limited use. Interesting enough, I
> can't remember last time someone told me they couldn't respin a pull
> request to fix something up due to downstream developers (not that we
> have _all_ that many of those requests).
> 

I think there is no issue to rebase at91-next apart from Nicolas being
on holiday and the fact that I don't have access to it.

> The other way to handle this would be to only apply patches directly
> and not do merges. Most other high-volume maintainers have exactly
> this workflow. We've been able to avoid reverting to that, thankfully
> (since we can delegate most of the reviews and patch applications this
> way).
> 

On an other topic but not completely unrelated, I see that you are
adding your SoB only on merge commits so basically, when the merge is a
fast forward, your SoB doesn't appear at all.
For now, I've chosen to apply PRs as patches to add my SoB, is that
something I can avoid?

-- 
Alexandre Belloni, Free Electrons
Embedded Linux, Kernel and Android engineering
http://free-electrons.com


From olof at lixom.net  Thu Aug 20 17:02:39 2015
From: olof at lixom.net (Olof Johansson)
Date: Thu, 20 Aug 2015 17:02:39 -0700
Subject: [GIT PULL] at91: defconfig for 4.3 #2
In-Reply-To: <20150820235819.GH3769@piout.net>
References: <20150807162754.GA20169@piout.net>
 <20150813100938.GN30160@localhost>
 <20150813112118.GA22269@piout.net>
 <20150813122643.GA23581@localhost>
 <20150814092237.3551c03e@canb.auug.org.au>
 <CAOesGMhwAYUAMLyT6TH38-0VmZNLEpcd_=Tq=EF1KJ=eywBmUw@mail.gmail.com>
 <20150820235819.GH3769@piout.net>
Message-ID: <CAOesGMhtBYXFN8i45t7CjDXec7MLexmHRwfC2fuZHH2rJzEvpw@mail.gmail.com>

On Thu, Aug 20, 2015 at 4:58 PM, Alexandre Belloni
<alexandre.belloni at free-electrons.com> wrote:
> Hi,
>
> On 18/08/2015 at 23:49:30 +0200, Olof Johansson wrote :
>> > The only thing now is that since the at91 tree is in linux-next as well
>> > as the arm-soc tree, those patches appear twice there and there is a
>> > conflict (easy to fix, but a pain).  The solution here is to update the
>> > at91 tree to be somewhere in the arm-soc tree (probably just reset to
>> > the point where the two trees match in patches but not commits).  This
>> > has the downside that the at91 tree will be rebased which will affect
>> > any development work that is based on that.
>> >
>> > If there was just one patch in common, it maybe have been better to
>> > just merge the at91 tree and fix the conflict in the merge.
>>
>> Yeah, this is a somewhat frustrating situation for us. I wonder if we
>> should essentially tag the downstream ARM platform trees in -next such
>> that if they conflict with arm-soc, you can drop them for a day if
>> needed.
>>
>> It's really useful for us to be able to occasionally adjust a pull
>> request instead of always merging them exactly as they're presented to
>> us. It saves a roundtrip to the maintainer for trivial stuff, we can
>> take care of it and not have to look at it again. We often do send it
>> back to the maintainers to respin, but in this particular case it
>> seemed appropriate to just deal with it locally for us.
>>
>> The downstream users vs rebasing git trees is of course another
>> aspect. Here I'm mostly relying on subplatform maintainers to know
>> well how many people actually develop on top of their trees. I think
>> for most platforms it's a fairly limited use. Interesting enough, I
>> can't remember last time someone told me they couldn't respin a pull
>> request to fix something up due to downstream developers (not that we
>> have _all_ that many of those requests).
>>
>
> I think there is no issue to rebase at91-next apart from Nicolas being
> on holiday and the fact that I don't have access to it.
>
>> The other way to handle this would be to only apply patches directly
>> and not do merges. Most other high-volume maintainers have exactly
>> this workflow. We've been able to avoid reverting to that, thankfully
>> (since we can delegate most of the reviews and patch applications this
>> way).
>>
>
> On an other topic but not completely unrelated, I see that you are
> adding your SoB only on merge commits so basically, when the merge is a
> fast forward, your SoB doesn't appear at all.
> For now, I've chosen to apply PRs as patches to add my SoB, is that
> something I can avoid?

Right, we can't add a S-o-b on non-merge commits since that would in
effect be a rebase.

Also, we never do ff merges in our tree, since it hides the merge path
and we want to make it possible to determine who merged the code.

The fact that we add S-o-b on the merge commit is sort of nonstandard,
but it shows which one of us did the merge (the commit author would
too, but it does happen that we rebase).


-Olof


From k.kozlowski at samsung.com  Thu Aug 20 17:48:22 2015
From: k.kozlowski at samsung.com (Krzysztof Kozlowski)
Date: Fri, 21 Aug 2015 09:48:22 +0900
Subject: [PATCH] ASoC: Samsung: Remove redundant arndale_audio_remove
In-Reply-To: <20150820164115.GA19191@localhost>
References: <20150820164115.GA19191@localhost>
Message-ID: <55D67556.4040500@samsung.com>

On 21.08.2015 01:41, Vaishali Thakkar wrote:
> There is no use of snd_soc_unregister_card in remove function
> as devm_snd_soc_register_card in probe function automatically
> handles it. So, remove use of snd_soc_unregister_card and with
> this change remove arndale_audio_remove as it is now redundant.
> 
> Signed-off-by: Vaishali Thakkar <vthakkar1994 at gmail.com>z
> ---
>  sound/soc/samsung/arndale_rt5631.c | 10 ----------
>  1 file changed, 10 deletions(-)

Reviewed-by: Krzysztof Kozlowski <k.kozlowski at samsung.com>

Best regards,
Krzysztof




From moritz.fischer at ettus.com  Thu Aug 20 18:16:37 2015
From: moritz.fischer at ettus.com (Moritz Fischer)
Date: Thu, 20 Aug 2015 18:16:37 -0700
Subject: [RESEND PATCH] dmaengine: Add Xilinx AXI Direct Memory Access
 Engine driver support
In-Reply-To: <C246CAC1457055469EF09E3A7AC4E11A4A4B2C48@XAP-PVEXMBX01.xlnx.xilinx.com>
References: <1439825512-16444-1-git-send-email-appanad@xilinx.com>
 <CAAtXAHf9S662okN1gchbD246=e4_bMFoyBMrbt5q48xm1uo_CA@mail.gmail.com>
 <C246CAC1457055469EF09E3A7AC4E11A4A4B2BBC@XAP-PVEXMBX01.xlnx.xilinx.com>
 <C246CAC1457055469EF09E3A7AC4E11A4A4B2C48@XAP-PVEXMBX01.xlnx.xilinx.com>
Message-ID: <CAAtXAHe3QjBo4_5unB32ixnOriO8Xt-1nLeddjgRgYvj5Kn_EA@mail.gmail.com>

Hi,

your MUA produces funny messages somehow ...
The driver did not probe for me in it's current form as the bindings
were missing interrupt parents for the interrupts...

On Thu, Aug 20, 2015 at 12:01 AM, Appana Durga Kedareswara Rao
<appana.durga.rao at xilinx.com> wrote:
> Hi ,
>
>> -----Original Message-----
>> From: dmaengine-owner at vger.kernel.org [mailto:dmaengine-
>> owner at vger.kernel.org] On Behalf Of Appana Durga Kedareswara Rao
>> Sent: Thursday, August 20, 2015 11:11 AM
>> To: Moritz Fischer
>> Cc: vinod.koul at intel.com; dan.j.williams at intel.com; Michal Simek; Soren
>> Brinkmann; anirudha at xilinx.com; dmaengine at vger.kernel.org; linux-
>> kernel at vger.kernel.org; linux-arm-kernel
>> Subject: RE: [RESEND PATCH] dmaengine: Add Xilinx AXI Direct Memory Access
>> Engine driver support
>>
>> Hi Moritz Fischer,
>>
>>       Thanks for reviewing the patch.
>>
>> > -----Original Message-----
>> > From: Moritz Fischer [mailto:moritz.fischer at ettus.com]
>> > Sent: Thursday, August 20, 2015 3:21 AM
>> > To: Appana Durga Kedareswara Rao
>> > Cc: vinod.koul at intel.com; dan.j.williams at intel.com; Michal Simek;
>> > Soren Brinkmann; Appana Durga Kedareswara Rao; anirudha at xilinx.com;
>> > dmaengine at vger.kernel.org; linux-kernel at vger.kernel.org;
>> > linux-arm-kernel; Srikanth Thokala
>> > Subject: Re: [RESEND PATCH] dmaengine: Add Xilinx AXI Direct Memory
>> > Access Engine driver support
>> >
>> > Hi there,
>> >
>> > see comment below. I just did a quick compile test. Will take another
>> > look once I synthesized an image.
>> >
>> > On Mon, Aug 17, 2015 at 8:31 AM, Kedareswara rao Appana
>> > <appana.durga.rao at xilinx.com> wrote:
>> > > This is the driver for the AXI Direct Memory Access (AXI DMA) core,
>> > > which is a soft Xilinx IP core that provides high- bandwidth direct
>> > > memory access between memory and AXI4-Stream type target peripherals.
>> > >
>> > > Signed-off-by: Srikanth Thokala <sthokal at xilinx.com>
>> > > Signed-off-by: Kedareswara rao Appana <appanad at xilinx.com>
>> > > ---
>> > > The deivce tree doc got applied in the slave-dmaengine.git.
>> > >
>> > > Forgot to include dmaengine at vger.kernel.org in the cc list resending
>> > > the patch.
>> > >
>> > > Changes in v8:
>> > > - Updated the SG handling as suggested by Nicolae Rosia.
>> > > - Removed the unnecessary xilinx_dma_channel_set_config API the
>> properties
>> > >   in this API is not being used by the driver.
>> > > Changes in v7:
>> > > - Updated license in the driver as suggested by Paul.
>> > > - Corrected return value in is_idle funtion.
>> > > Changes in v6:
>> > > - Fixed Odd indention in the Kconfig.
>> > > - used GFP_NOWAIT instead of GFP_KERNEL during the desc allocation
>> > > - Calculated residue in the tx_status instead of complete_descriptor.
>> > > - Update copy right to 2015.
>> > > - Modified spin_lock handling moved the spin_lock to the appropriate
>> > > functions (instead of xilinx_dma_start_transfer doing it
>> > xilinx_dma_issue_pending api).
>> > > - device_control and declare slave caps updated as per newer APi's.
>> > > Changes in v5:
>> > > - Modified the xilinx_dma.h header file location to the
>> > >   include/linux/dma/xilinx_dma.h
>> > > Changes in v4:
>> > > - Add direction field to DMA descriptor structure and removed from
>> > >   channel structure to avoid duplication.
>> > > - Check for DMA idle condition before changing the configuration.
>> > > - Residue is being calculated in complete_descriptor() and is reported
>> > >   to slave driver.
>> > > Changes in v3:
>> > > - Rebased on 3.16-rc7
>> > > Changes in v2:
>> > > - Simplified the logic to set SOP and APP words in prep_slave_sg().
>> > > - Corrected function description comments to match the return type.
>> > > - Fixed some minor comments as suggested by Andy.
>> > >
>> > >  drivers/dma/Kconfig             |   13 +
>> > >  drivers/dma/xilinx/Makefile     |    1 +
>> > >  drivers/dma/xilinx/xilinx_dma.c | 1179
>> > > +++++++++++++++++++++++++++++++++++++++
>> > >  3 files changed, 1193 insertions(+)  create mode 100644
>> > > drivers/dma/xilinx/xilinx_dma.c
>> > >
>> > > diff --git a/drivers/dma/Kconfig b/drivers/dma/Kconfig index
>> > > 88d474b..5e95f07 100644
>> > > --- a/drivers/dma/Kconfig
>> > > +++ b/drivers/dma/Kconfig
>> > > @@ -507,4 +507,17 @@ config QCOM_BAM_DMA
>> > >           Enable support for the QCOM BAM DMA controller.  This controller
>> > >           provides DMA capabilities for a variety of on-chip devices.
>> > >
>> > > +config XILINX_DMA
>> > > +        tristate "Xilinx AXI DMA Engine"
>> > > +        depends on (ARCH_ZYNQ || MICROBLAZE)
>> > > +        select DMA_ENGINE
>> > > +        help
>> > > +          Enable support for Xilinx AXI DMA Soft IP.
>> > > +
>> > > +          This engine provides high-bandwidth direct memory access
>> > > +          between memory and AXI4-Stream type target peripherals.
>> > > +          It has two stream interfaces/channels, Memory Mapped to
>> > > +          Stream (MM2S) and Stream to Memory Mapped (S2MM) for the
>> > > +          data transfers.
>> > > +
>> > >  endif
>> > > diff --git a/drivers/dma/xilinx/Makefile
>> > > b/drivers/dma/xilinx/Makefile index 3c4e9f2..6224a49 100644
>> > > --- a/drivers/dma/xilinx/Makefile
>> > > +++ b/drivers/dma/xilinx/Makefile
>> > > @@ -1 +1,2 @@
>> > >  obj-$(CONFIG_XILINX_VDMA) += xilinx_vdma.o
>> > > +obj-$(CONFIG_XILINX_DMA) += xilinx_dma.o
>> > > diff --git a/drivers/dma/xilinx/xilinx_dma.c
>> > > b/drivers/dma/xilinx/xilinx_dma.c new file mode 100644 index
>> > > 0000000..a9be197
>> > > --- /dev/null
>> > > +++ b/drivers/dma/xilinx/xilinx_dma.c
>> > > @@ -0,0 +1,1179 @@
>> > > +/*
>> > > + * DMA driver for Xilinx DMA Engine
>> > > + *
>> > > + * Copyright (C) 2010 - 2015 Xilinx, Inc. All rights reserved.
>> > > + *
>> > > + * Based on the Freescale DMA driver.
>> > > + *
>> > > + * Description:
>> > > + *  The AXI DMA, is a soft IP, which provides high-bandwidth Direct
>> > > +Memory
>> > > + *  Access between memory and AXI4-Stream-type target peripherals.
>> > > +It can be
>> > > + *  configured to have one channel or two channels and if
>> > > +configured as two
>> > > + *  channels, one is to transmit data from memory to a device and
>> > > +another is
>> > > + *  to receive from a device.
>> > > + *
>> > > + * This 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.
>> > > + */
>> > > +
>> > > +#include <linux/bitops.h>
>> > > +#include <linux/dma/xilinx_dma.h>
>> > > +#include <linux/init.h>
>> > > +#include <linux/interrupt.h>
>> > > +#include <linux/io.h>
>> > > +#include <linux/module.h>
>> > > +#include <linux/of_address.h>
>> > > +#include <linux/of_dma.h>
>> > > +#include <linux/of_irq.h>
>> > > +#include <linux/of_platform.h>
>> > > +#include <linux/slab.h>
>> > > +
>> > > +#include "../dmaengine.h"
>> > > +
>> > > +/* Register Offsets */
>> > > +#define XILINX_DMA_REG_CONTROL         0x00
>> > > +#define XILINX_DMA_REG_STATUS          0x04
>> > > +#define XILINX_DMA_REG_CURDESC         0x08
>> > > +#define XILINX_DMA_REG_TAILDESC                0x10
>> > > +#define XILINX_DMA_REG_SRCADDR         0x18
>> > > +#define XILINX_DMA_REG_DSTADDR         0x20
>> > > +#define XILINX_DMA_REG_BTT             0x28
>> > > +
>> > > +/* Channel/Descriptor Offsets */
>> > > +#define XILINX_DMA_MM2S_CTRL_OFFSET    0x00
>> > > +#define XILINX_DMA_S2MM_CTRL_OFFSET    0x30
>> > > +
>> > > +/* General register bits definitions */
>> > > +#define XILINX_DMA_CR_RUNSTOP_MASK     BIT(0)
>> > > +#define XILINX_DMA_CR_RESET_MASK       BIT(2)
>> > > +
>> > > +#define XILINX_DMA_CR_DELAY_SHIFT      24
>> > > +#define XILINX_DMA_CR_COALESCE_SHIFT   16
>> > > +
>> > > +#define XILINX_DMA_CR_DELAY_MAX                GENMASK(7, 0)
>> > > +#define XILINX_DMA_CR_COALESCE_MAX     GENMASK(7, 0)
>> > > +
>> > > +#define XILINX_DMA_SR_HALTED_MASK      BIT(0)
>> > > +#define XILINX_DMA_SR_IDLE_MASK                BIT(1)
>> > > +
>> > > +#define XILINX_DMA_XR_IRQ_IOC_MASK     BIT(12)
>> > > +#define XILINX_DMA_XR_IRQ_DELAY_MASK   BIT(13)
>> > > +#define XILINX_DMA_XR_IRQ_ERROR_MASK   BIT(14)
>> > > +#define XILINX_DMA_XR_IRQ_ALL_MASK     GENMASK(14, 12)
>> > > +
>> > > +/* BD definitions */
>> > > +#define XILINX_DMA_BD_STS_ALL_MASK     GENMASK(31, 28)
>> > > +#define XILINX_DMA_BD_SOP              BIT(27)
>> > > +#define XILINX_DMA_BD_EOP              BIT(26)
>> > > +
>> > > +/* Hw specific definitions */
>> > > +#define XILINX_DMA_MAX_CHANS_PER_DEVICE        0x2
>> > > +#define XILINX_DMA_MAX_TRANS_LEN       GENMASK(22, 0)
>> > > +
>> > > +/* Delay loop counter to prevent hardware failure */
>> > > +#define XILINX_DMA_LOOP_COUNT          1000000
>> > > +
>> > > +/* Maximum number of Descriptors */
>> > > +#define XILINX_DMA_NUM_DESCS           255
>> > > +#define XILINX_DMA_COALESCE_MAX                255
>> > > +#define XILINX_DMA_NUM_APP_WORDS       5
>> > > +
>> > > +/**
>> > > + * struct xilinx_dma_desc_hw - Hardware Descriptor
>> > > + * @next_desc: Next Descriptor Pointer @0x00
>> > > + * @pad1: Reserved @0x04
>> > > + * @buf_addr: Buffer address @0x08
>> > > + * @pad2: Reserved @0x0C
>> > > + * @pad3: Reserved @0x10
>> > > + * @pad4: Reserved @0x14
>> > > + * @control: Control field @0x18
>> > > + * @status: Status field @0x1C
>> > > + * @app: APP Fields @0x20 - 0x30
>> > > + */
>> > > +struct xilinx_dma_desc_hw {
>> > > +       u32 next_desc;
>> > > +       u32 pad1;
>> > > +       u32 buf_addr;
>> > > +       u32 pad2;
>> > > +       u32 pad3;
>> > > +       u32 pad4;
>> > > +       u32 control;
>> > > +       u32 status;
>> > > +       u32 app[XILINX_DMA_NUM_APP_WORDS]; } __aligned(64);
>> > > +
>> > > +/**
>> > > + * struct xilinx_dma_tx_segment - Descriptor segment
>> > > + * @hw: Hardware descriptor
>> > > + * @node: Node in the descriptor segments list
>> > > + * @phys: Physical address of segment  */ struct
>> > > +xilinx_dma_tx_segment {
>> > > +       struct xilinx_dma_desc_hw hw;
>> > > +       struct list_head node;
>> > > +       dma_addr_t phys;
>> > > +} __aligned(64);
>> > > +
>> > > +/**
>> > > + * struct xilinx_dma_tx_descriptor - Per Transaction structure
>> > > + * @async_tx: Async transaction descriptor
>> > > + * @segments: TX segments list
>> > > + * @node: Node in the channel descriptors list
>> > > + * @direction: Transfer direction
>> > > + */
>> > > +struct xilinx_dma_tx_descriptor {
>> > > +       struct dma_async_tx_descriptor async_tx;
>> > > +       struct list_head segments;
>> > > +       struct list_head node;
>> > > +       enum dma_transfer_direction direction; };
>> > > +
>> > > +/**
>> > > + * struct xilinx_dma_chan - Driver specific DMA channel structure
>> > > + * @xdev: Driver specific device structure
>> > > + * @ctrl_offset: Control registers offset
>> > > + * @ctrl_reg: Control register value
>> > > + * @lock: Descriptor operation lock
>> > > + * @pending_list: Descriptors waiting
>> > > + * @active_list: Descriptors ready to submit
>> > > + * @done_list: Complete descriptors
>> > > + * @free_seg_list: Free descriptors
>> > > + * @common: DMA common channel
>> > > + * @seg_v: Statically allocated segments base
>> > > + * @seg_p: Physical allocated segments base
>> > > + * @dev: The dma device
>> > > + * @irq: Channel IRQ
>> > > + * @id: Channel ID
>> > > + * @has_sg: Support scatter transfers
>> > > + * @idle: Check for channel idle
>> > > + * @err: Channel has errors
>> > > + * @tasklet: Cleanup work after irq
>> > > + * @residue: Residue
>> > > + * @desc_pendingcount: Descriptor pending count  */ struct
>> > > +xilinx_dma_chan {
>> > > +       struct xilinx_dma_device *xdev;
>> > > +       u32 ctrl_offset;
>> > > +       u32 ctrl_reg;
>> > > +       spinlock_t lock;
>> > > +       struct list_head pending_list;
>> > > +       struct list_head done_list;
>> > > +       struct list_head active_list;
>> > > +       struct list_head free_seg_list;
>> > > +       struct dma_chan common;
>> > > +       struct xilinx_dma_tx_segment *seg_v;
>> > > +       dma_addr_t seg_p;
>> > > +       struct device *dev;
>> > > +       int irq;
>> > > +       int id;
>> > > +       bool has_sg;
>> > > +       bool idle;
>> > > +       int err;
>> > > +       struct tasklet_struct tasklet;
>> > > +       u32 residue;
>> > > +       u32 desc_pendingcount;
>> > > +};
>> > > +
>> > > +/**
>> > > + * struct xilinx_dma_device - DMA device structure
>> > > + * @regs: I/O mapped base address
>> > > + * @dev: Device Structure
>> > > + * @common: DMA device structure
>> > > + * @chan: Driver specific DMA channel
>> > > + * @has_sg: Specifies whether Scatter-Gather is present or not  */
>> > > +struct xilinx_dma_device {
>> > > +       void __iomem *regs;
>> > > +       struct device *dev;
>> > > +       struct dma_device common;
>> > > +       struct xilinx_dma_chan
>> *chan[XILINX_DMA_MAX_CHANS_PER_DEVICE];
>> > > +       bool has_sg;
>> > > +};
>> > > +
>> > > +/* Macros */
>> > > +#define to_xilinx_chan(chan) \
>> > > +       container_of(chan, struct xilinx_dma_chan, common) #define
>> > > +to_dma_tx_descriptor(tx) \
>> > > +       container_of(tx, struct xilinx_dma_tx_descriptor, async_tx)
>> > > +
>> > > +/* IO accessors */
>> > > +static inline void dma_write(struct xilinx_dma_chan *chan, u32 reg,
>> > > +u32 value) {
>> > > +       iowrite32(value, chan->xdev->regs + reg);
>> > Any reason to not use write here?
>> Most of the Xilinx drivers and the VDMA driver that got up streamed Use iowrite
>> to make consistency b/w the drivers I used the same API's.
>>
>> What is the advantage we will gain by using writel instead of iowrite32?

https://lkml.org/lkml/2011/1/19/158
>>
>> > > +}
>> > > +
>> > > +static inline u32 dma_read(struct xilinx_dma_chan *chan, u32 reg) {
>> > > +       return ioread32(chan->xdev->regs + reg);
>> > Any reason to not use readl here?
>> > > +}
>> > > +
>> > > +static inline u32 dma_ctrl_read(struct xilinx_dma_chan *chan, u32
>> > > +reg) {
>> > > +       return dma_read(chan, chan->ctrl_offset + reg); }
>> > > +
>> > > +static inline void dma_ctrl_write(struct xilinx_dma_chan *chan, u32 reg,
>> > > +                                 u32 value) {
>> > > +       dma_write(chan, chan->ctrl_offset + reg, value); }
>> > > +
>> > > +/*
>> > > +-------------------------------------------------------------------
>> > > +--
>> > > +--------
>> > > + * Descriptors and segments alloc and free  */
>> > > +
>> > > +/**
>> > > + * xilinx_dma_alloc_tx_segment - Allocate transaction segment
>> > > + * @chan: Driver specific dma channel
>> > > + *
>> > > + * Return: The allocated segment on success and NULL on failure.
>> > > + */
>> > > +static struct xilinx_dma_tx_segment *
>> > > +xilinx_dma_alloc_tx_segment(struct xilinx_dma_chan *chan) {
>> > > +       struct xilinx_dma_tx_segment *segment = NULL;
>> > > +       unsigned long flags;
>> > > +
>> > > +       spin_lock_irqsave(&chan->lock, flags);
>> > > +       if (!list_empty(&chan->free_seg_list)) {
>> > > +               segment = list_first_entry(&chan->free_seg_list,
>> > > +                                          struct xilinx_dma_tx_segment,
>> > > +                                          node);
>> > > +               list_del(&segment->node);
>> > > +       }
>> > > +       spin_unlock_irqrestore(&chan->lock, flags);
>> > > +
>> > > +       return segment;
>> > > +}
>> > > +
>> > > +/**
>> > > + * xilinx_dma_clean_hw_desc - Clean hardware descriptor
>> > > + * @hw: HW descriptor to clean
>> > > + */
>> > > +static void xilinx_dma_clean_hw_desc(struct xilinx_dma_desc_hw *hw) {
>> > > +       u32 next_desc = hw->next_desc;
>> > > +
>> > > +       memset(hw, 0, sizeof(struct xilinx_dma_desc_hw));
>> > > +
>> > > +       hw->next_desc = next_desc;
>> > > +}
>> > > +
>> > > +/**
>> > > + * xilinx_dma_free_tx_segment - Free transaction segment
>> > > + * @chan: Driver specific dma channel
>> > > + * @segment: dma transaction segment  */ static void
>> > > +xilinx_dma_free_tx_segment(struct xilinx_dma_chan *chan,
>> > > +                                      struct xilinx_dma_tx_segment
>> > > +*segment) {
>> > > +       xilinx_dma_clean_hw_desc(&segment->hw);
>> > > +
>> > > +       list_add_tail(&segment->node, &chan->free_seg_list); }
>> > > +
>> > > +/**
>> > > + * xilinx_dma_tx_descriptor - Allocate transaction descriptor
>> > > + * @chan: Driver specific dma channel
>> > > + *
>> > > + * Return: The allocated descriptor on success and NULL on failure.
>> > > + */
>> > > +static struct xilinx_dma_tx_descriptor *
>> > > +xilinx_dma_alloc_tx_descriptor(struct xilinx_dma_chan *chan) {
>> > > +       struct xilinx_dma_tx_descriptor *desc;
>> > > +
>> > > +       desc = kzalloc(sizeof(*desc), GFP_NOWAIT);
>> > > +       if (!desc)
>> > > +               return NULL;
>> > > +
>> > > +       INIT_LIST_HEAD(&desc->segments);
>> > > +
>> > > +       return desc;
>> > > +}
>> > > +
>> > > +/**
>> > > + * xilinx_dma_free_tx_descriptor - Free transaction descriptor
>> > > + * @chan: Driver specific dma channel
>> > > + * @desc: dma transaction descriptor  */ static void
>> > > +xilinx_dma_free_tx_descriptor(struct xilinx_dma_chan *chan,
>> > > +                             struct xilinx_dma_tx_descriptor *desc) {
>> > > +       struct xilinx_dma_tx_segment *segment, *next;
>> > > +
>> > > +       if (!desc)
>> > > +               return;
>> > > +
>> > > +       list_for_each_entry_safe(segment, next, &desc->segments, node) {
>> > > +               list_del(&segment->node);
>> > > +               xilinx_dma_free_tx_segment(chan, segment);
>> > > +       }
>> > > +
>> > > +       kfree(desc);
>> > > +}
>> > > +
>> > > +/**
>> > > + * xilinx_dma_alloc_chan_resources - Allocate channel resources
>> > > + * @dchan: DMA channel
>> > > + *
>> > > + * Return: '0' on success and failure value on error  */ static int
>> > > +xilinx_dma_alloc_chan_resources(struct dma_chan *dchan) {
>> > > +       struct xilinx_dma_chan *chan = to_xilinx_chan(dchan);
>> > > +       int i;
>> > > +
>> > > +       /* Allocate the buffer descriptors. */
>> > > +       chan->seg_v = dma_zalloc_coherent(chan->dev,
>> > > +                                         sizeof(*chan->seg_v) *
>> > > +                                         XILINX_DMA_NUM_DESCS,
>> > > +                                         &chan->seg_p, GFP_KERNEL);
>> > > +       if (!chan->seg_v) {
>> > > +               dev_err(chan->dev,
>> > > +                       "unable to allocate channel %d descriptors\n",
>> > > +                       chan->id);
>> > > +               return -ENOMEM;
>> > > +       }
>> > > +
>> > > +       for (i = 0; i < XILINX_DMA_NUM_DESCS; i++) {
>> > > +               chan->seg_v[i].hw.next_desc =
>> > > +                               chan->seg_p + sizeof(*chan->seg_v) *
>> > > +                               ((i + 1) % XILINX_DMA_NUM_DESCS);
>> > > +               chan->seg_v[i].phys =
>> > > +                               chan->seg_p + sizeof(*chan->seg_v) * i;
>> > > +               list_add_tail(&chan->seg_v[i].node, &chan->free_seg_list);
>> > > +       }
>> > > +
>> > > +       dma_cookie_init(dchan);
>> > > +
>> > > +       /* Enable interrupts */
>> > > +       chan->ctrl_reg |= XILINX_DMA_XR_IRQ_ALL_MASK;
>> > > +       dma_ctrl_write(chan, XILINX_DMA_REG_CONTROL,
>> > > + chan->ctrl_reg);
>> > > +
>> > > +       return 0;
>> > > +}
>> > > +
>> > > +/**
>> > > + * xilinx_dma_free_desc_list - Free descriptors list
>> > > + * @chan: Driver specific dma channel
>> > > + * @list: List to parse and delete the descriptor  */ static void
>> > > +xilinx_dma_free_desc_list(struct xilinx_dma_chan *chan,
>> > > +                                     struct list_head *list) {
>> > > +       struct xilinx_dma_tx_descriptor *desc, *next;
>> > > +
>> > > +       list_for_each_entry_safe(desc, next, list, node) {
>> > > +               list_del(&desc->node);
>> > > +               xilinx_dma_free_tx_descriptor(chan, desc);
>> > > +       }
>> > > +}
>> > > +
>> > > +/**
>> > > + * xilinx_dma_free_descriptors - Free channel descriptors
>> > > + * @chan: Driver specific dma channel  */ static void
>> > > +xilinx_dma_free_descriptors(struct xilinx_dma_chan *chan) {
>> > > +       unsigned long flags;
>> > > +
>> > > +       spin_lock_irqsave(&chan->lock, flags);
>> > > +
>> > > +       xilinx_dma_free_desc_list(chan, &chan->pending_list);
>> > > +       xilinx_dma_free_desc_list(chan, &chan->done_list);
>> > > +       xilinx_dma_free_desc_list(chan, &chan->active_list);
>> > > +
>> > > +       spin_unlock_irqrestore(&chan->lock, flags); }
>> > > +
>> > > +/**
>> > > + * xilinx_dma_free_chan_resources - Free channel resources
>> > > + * @dchan: DMA channel
>> > > + */
>> > > +static void xilinx_dma_free_chan_resources(struct dma_chan *dchan) {
>> > > +       struct xilinx_dma_chan *chan = to_xilinx_chan(dchan);
>> > > +
>> > > +       xilinx_dma_free_descriptors(chan);
>> > > +
>> > > +       dma_free_coherent(chan->dev,
>> > > +                         sizeof(*chan->seg_v) * XILINX_DMA_NUM_DESCS,
>> > > +                         chan->seg_v, chan->seg_p); }
>> > > +
>> > > +/**
>> > > + * xilinx_dma_chan_desc_cleanup - Clean channel descriptors
>> > > + * @chan: Driver specific dma channel  */ static void
>> > > +xilinx_dma_chan_desc_cleanup(struct xilinx_dma_chan *chan) {
>> > > +       struct xilinx_dma_tx_descriptor *desc;
>> > > +       unsigned long flags;
>> > > +
>> > > +       spin_lock_irqsave(&chan->lock, flags);
>> > > +
>> > > +       while (!list_empty(&chan->done_list)) {
>> > > +               dma_async_tx_callback callback;
>> > > +               void *callback_param;
>> > > +
>> > > +               desc = list_first_entry(&chan->done_list,
>> > > +                       struct xilinx_dma_tx_descriptor, node);
>> > > +
>> > > +               /* Remove from the list of running transactions */
>> > > +               list_del(&desc->node);
>> > > +
>> > > +               /* Run the link descriptor callback function */
>> > > +               callback = desc->async_tx.callback;
>> > > +               callback_param = desc->async_tx.callback_param;
>> > > +               if (callback) {
>> > > +                       spin_unlock_irqrestore(&chan->lock, flags);
>> > > +                       callback(callback_param);
>> > > +                       spin_lock_irqsave(&chan->lock, flags);
>> > > +               }
>> > > +
>> > > +               /* Run any dependencies, then free the descriptor */
>> > > +               dma_run_dependencies(&desc->async_tx);
>> > > +               xilinx_dma_free_tx_descriptor(chan, desc);
>> > > +       }
>> > > +
>> > > +       spin_unlock_irqrestore(&chan->lock, flags); }
>> > > +
>> > > +/**
>> > > + * xilinx_dma_tx_status - Get dma transaction status
>> > > + * @dchan: DMA channel
>> > > + * @cookie: Transaction identifier
>> > > + * @txstate: Transaction state
>> > > + *
>> > > + * Return: DMA transaction status
>> > > + */
>> > > +static enum dma_status xilinx_dma_tx_status(struct dma_chan *dchan,
>> > > +                                           dma_cookie_t cookie,
>> > > +                                           struct dma_tx_state
>> > > +*txstate) {
>> > > +       struct xilinx_dma_chan *chan = to_xilinx_chan(dchan);
>> > > +       struct xilinx_dma_tx_descriptor *desc;
>> > > +       struct xilinx_dma_tx_segment *segment;
>> > > +       struct xilinx_dma_desc_hw *hw;
>> > > +       enum dma_status ret;
>> > > +       unsigned long flags;
>> > > +       u32 residue;
>> >
>> > While compiling this threw a residue may be used uninitialized
>> > warning, I suppose 0 would be a sensible default value?
>>
>> Ok will fix it.
>>
>> > > +
>> > > +       ret = dma_cookie_status(dchan, cookie, txstate);
>> > > +       if (ret == DMA_COMPLETE || !txstate)
>> > > +               return ret;
>> > > +
>> > > +       desc = list_last_entry(&chan->active_list,
>> > > +                              struct xilinx_dma_tx_descriptor,
>> > > + node);
>> > > +
>> > > +       spin_lock_irqsave(&chan->lock, flags);
>> > > +       if (chan->has_sg) {
>> > > +               while (!list_empty(&desc->segments)) {
>> > > +                       segment = list_first_entry(&desc->segments,
>> > > +                                       struct xilinx_dma_tx_segment, node);
>> > > +                       hw = &segment->hw;
>> > > +                       residue += (hw->control - hw->status) &
>> > > +                                  XILINX_DMA_MAX_TRANS_LEN;
>> > > +               }
>> > > +       }
>> > > +
>> > > +       chan->residue = residue;
>> > > +       dma_set_residue(txstate, chan->residue);
>> > > +       spin_unlock_irqrestore(&chan->lock, flags);
>> > > +
>> > > +       return ret;
>> > > +}
>> > > +
>> > > +/**
>> > > + * xilinx_dma_halt - Halt DMA channel
>> > > + * @chan: Driver specific DMA channel  */ static void
>> > > +xilinx_dma_halt(struct xilinx_dma_chan *chan) {
>> > > +       int loop = XILINX_DMA_LOOP_COUNT;
>> > > +
>> > > +       chan->ctrl_reg &= ~XILINX_DMA_CR_RUNSTOP_MASK;
>> > > +       dma_ctrl_write(chan, XILINX_DMA_REG_CONTROL,
>> > > + chan->ctrl_reg);
>> > > +
>> > > +       /* Wait for the hardware to halt */
>> > > +       do {
>> > > +               if (dma_ctrl_read(chan, XILINX_DMA_REG_STATUS) &
>> > > +                       XILINX_DMA_SR_HALTED_MASK)
>> > > +                       break;
>> > > +       } while (loop--);
>> > > +
>> > > +       if (!loop) {
>> > > +               dev_err(chan->dev, "Cannot stop channel %p: %x\n",
>> > > +                       chan, dma_ctrl_read(chan, XILINX_DMA_REG_STATUS));
>> > > +               chan->err = true;
>> > > +       }
>> > > +}
>> > > +
>> > > +/**
>> > > + * xilinx_dma_start - Start DMA channel
>> > > + * @chan: Driver specific DMA channel  */ static void
>> > > +xilinx_dma_start(struct xilinx_dma_chan *chan) {
>> > > +       int loop = XILINX_DMA_LOOP_COUNT;
>> > > +
>> > > +       chan->ctrl_reg |= XILINX_DMA_CR_RUNSTOP_MASK;
>> > > +       dma_ctrl_write(chan, XILINX_DMA_REG_CONTROL,
>> > > + chan->ctrl_reg);
>> > > +
>> > > +       /* Wait for the hardware to start */
>> > > +       do {
>> > > +               if (!dma_ctrl_read(chan, XILINX_DMA_REG_STATUS) &
>> > > +                       XILINX_DMA_SR_HALTED_MASK)
>> > > +                       break;
>> > > +       } while (loop--);
>> > Maybe use one of the readx_poll_timeout functions?
>>
>> Ok will fix it.
>
> Seems to be the readx_poll_timeout api is not suits for my driver requirement.
> The API has some limitations when I try to use this API the code looks ugly.
>
> The issue that I am facing is:
> The readx_poll_timeout API 1st argument is expecting only the address (https://lwn.net/Articles/626525/).
> But in my case I need to pass the channel info and a particular offset in the channel.
> If I pass all these info in the API's where I am using readx_poll_timeout the code looks ugly.
>
> Do you have any other suggestions?

How about:
#define xilinx_dma_poll_timeout(chan, reg, val, cond, delay_us, timeout_us) \
    readl_poll_timeout(chan->xdev->regs + reg, val, cond, delay_us, timeout_us)
>
> Regards,
> Kedar.
>
>>
>> > > +
>> > > +       if (!loop) {
>> > > +               dev_err(chan->dev, "Cannot start channel %p: %x\n",
>> > > +                        chan, dma_ctrl_read(chan, XILINX_DMA_REG_STATUS));
>> > > +               chan->err = true;
>> > > +       }
>> > > +}
>> > > +
>> > > +/**
>> > > + * xilinx_dma_start_transfer - Starts DMA transfer
>> > > + * @chan: Driver specific channel struct pointer  */ static void
>> > > +xilinx_dma_start_transfer(struct xilinx_dma_chan *chan) {
>> > > +       struct xilinx_dma_tx_descriptor *head_desc, *tail_desc;
>> > > +       struct xilinx_dma_tx_segment *tail_segment;
>> > > +
>> > > +       if (chan->err)
>> > > +               return;
>> > > +
>> > > +       if (list_empty(&chan->pending_list))
>> > > +               return;
>> > > +
>> > > +       if (!chan->idle)
>> > > +               return;
>> > > +
>> > > +       head_desc = list_first_entry(&chan->pending_list,
>> > > +                                    struct xilinx_dma_tx_descriptor, node);
>> > > +       tail_desc = list_last_entry(&chan->pending_list,
>> > > +                                   struct xilinx_dma_tx_descriptor, node);
>> > > +       tail_segment = list_last_entry(&tail_desc->segments,
>> > > +                                      struct xilinx_dma_tx_segment,
>> > > + node);
>> > > +
>> > > +       if (chan->desc_pendingcount <= XILINX_DMA_COALESCE_MAX) {
>> > > +               chan->ctrl_reg &= ~XILINX_DMA_CR_COALESCE_MAX;
>> > > +               chan->ctrl_reg |= chan->desc_pendingcount <<
>> > > +                                 XILINX_DMA_CR_COALESCE_SHIFT;
>> > > +               dma_ctrl_write(chan, XILINX_DMA_REG_CONTROL, chan-
>> >ctrl_reg);
>> > > +       }
>> > > +
>> > > +       if (chan->has_sg)
>> > > +               dma_ctrl_write(chan, XILINX_DMA_REG_CURDESC,
>> > > +                              head_desc->async_tx.phys);
>> > > +
>> > > +       xilinx_dma_start(chan);
>> > > +
>> > > +       if (chan->err)
>> > > +               return;
>> > > +
>> > > +       /* Start the transfer */
>> > > +       if (chan->has_sg) {
>> > > +               dma_ctrl_write(chan, XILINX_DMA_REG_TAILDESC,
>> > > +                              tail_segment->phys);
>> > > +       } else {
>> > > +               struct xilinx_dma_tx_segment *segment;
>> > > +               struct xilinx_dma_desc_hw *hw;
>> > > +
>> > > +               segment = list_first_entry(&head_desc->segments,
>> > > +                                          struct xilinx_dma_tx_segment, node);
>> > > +               hw = &segment->hw;
>> > > +
>> > > +               if (head_desc->direction == DMA_MEM_TO_DEV)
>> > > +                       dma_ctrl_write(chan, XILINX_DMA_REG_SRCADDR,
>> > > +                                      hw->buf_addr);
>> > > +               else
>> > > +                       dma_ctrl_write(chan, XILINX_DMA_REG_DSTADDR,
>> > > +                                      hw->buf_addr);
>> > > +
>> > > +               /* Start the transfer */
>> > > +               dma_ctrl_write(chan, XILINX_DMA_REG_BTT,
>> > > +                              hw->control & XILINX_DMA_MAX_TRANS_LEN);
>> > > +       }
>> > > +
>> > > +       list_splice_tail_init(&chan->pending_list, &chan->active_list);
>> > > +       chan->desc_pendingcount = 0;
>> > > +       chan->idle = false;
>> > > +}
>> > > +
>> > > +/**
>> > > + * xilinx_dma_issue_pending - Issue pending transactions
>> > > + * @dchan: DMA channel
>> > > + */
>> > > +static void xilinx_dma_issue_pending(struct dma_chan *dchan) {
>> > > +       struct xilinx_dma_chan *chan = to_xilinx_chan(dchan);
>> > > +       unsigned long flags;
>> > > +
>> > > +       spin_lock_irqsave(&chan->lock, flags);
>> > > +       xilinx_dma_start_transfer(chan);
>> > > +       spin_unlock_irqrestore(&chan->lock, flags); }
>> > > +
>> > > +/**
>> > > + * xilinx_dma_complete_descriptor - Mark the active descriptor as
>> > > +complete
>> > > + * @chan : xilinx DMA channel
>> > > + */
>> > > +static void xilinx_dma_complete_descriptor(struct xilinx_dma_chan
>> > > +*chan) {
>> > > +       struct xilinx_dma_tx_descriptor *desc, *next;
>> > > +
>> > > +       if (list_empty(&chan->active_list))
>> > > +               return;
>> > > +
>> > > +       list_for_each_entry_safe(desc, next, &chan->active_list, node) {
>> > > +               list_del(&desc->node);
>> > > +               dma_cookie_complete(&desc->async_tx);
>> > > +               list_add_tail(&desc->node, &chan->done_list);
>> > > +       }
>> > > +}
>> > > +
>> > > +/**
>> > > + * xilinx_dma_reset - Reset DMA channel
>> > > + * @chan: Driver specific DMA channel
>> > > + *
>> > > + * Return: '0' on success and failure value on error  */ static int
>> > > +xilinx_dma_chan_reset(struct xilinx_dma_chan *chan) {
>> > > +       int loop = XILINX_DMA_LOOP_COUNT;
>> > > +       u32 tmp;
>> > > +
>> > > +       chan->ctrl_reg = dma_ctrl_read(chan, XILINX_DMA_REG_CONTROL);
>> > > +       dma_ctrl_write(chan, XILINX_DMA_REG_CONTROL, chan->ctrl_reg |
>> > > +                      XILINX_DMA_CR_RESET_MASK);
>> > > +
>> > > +       tmp = dma_ctrl_read(chan, XILINX_DMA_REG_CONTROL) &
>> > > +             XILINX_DMA_CR_RESET_MASK;
>> > > +
>> > > +       /* Wait for the hardware to finish reset */
>> > > +       do {
>> > > +               tmp = dma_ctrl_read(chan, XILINX_DMA_REG_CONTROL) &
>> > > +                     XILINX_DMA_CR_RESET_MASK;
>> > > +       } while (loop-- && tmp);
>> > See above
>>
>> Ok will fix it.
>>
>> Regards,
>> Kedar.
>>
>> > > +
>> > > +       if (!loop) {
>> > > +               dev_err(chan->dev, "reset timeout, cr %x, sr %x\n",
>> > > +                       dma_ctrl_read(chan, XILINX_DMA_REG_CONTROL),
>> > > +                       dma_ctrl_read(chan, XILINX_DMA_REG_STATUS));
>> > > +               return -EBUSY;
>> > > +       }
>> > > +
>> > > +       chan->err = false;
>> > > +
>> > > +       return 0;
>> > > +}
>> > > +
>> > > +/**
>> > > + * xilinx_dma_irq_handler - DMA Interrupt handler
>> > > + * @irq: IRQ number
>> > > + * @data: Pointer to the Xilinx DMA channel structure
>> > > + *
>> > > + * Return: IRQ_HANDLED/IRQ_NONE
>> > > + */
>> > > +static irqreturn_t xilinx_dma_irq_handler(int irq, void *data) {
>> > > +       struct xilinx_dma_chan *chan = data;
>> > > +       u32 status;
>> > > +
>> > > +       /* Read the status and ack the interrupts. */
>> > > +       status = dma_ctrl_read(chan, XILINX_DMA_REG_STATUS);
>> > > +       if (!(status & XILINX_DMA_XR_IRQ_ALL_MASK))
>> > > +               return IRQ_NONE;
>> > > +
>> > > +       dma_ctrl_write(chan, XILINX_DMA_REG_STATUS,
>> > > +                      status & XILINX_DMA_XR_IRQ_ALL_MASK);
>> > > +
>> > > +       if (status & XILINX_DMA_XR_IRQ_ERROR_MASK) {
>> > > +               dev_err(chan->dev,
>> > > +                       "Channel %p has errors %x, cdr %x tdr %x\n",
>> > > +                       chan, dma_ctrl_read(chan, XILINX_DMA_REG_STATUS),
>> > > +                       dma_ctrl_read(chan, XILINX_DMA_REG_CURDESC),
>> > > +                       dma_ctrl_read(chan, XILINX_DMA_REG_TAILDESC));
>> > > +               chan->err = true;
>> > > +       }
>> > > +
>> > > +       /*
>> > > +        * Device takes too long to do the transfer when user requires
>> > > +        * responsiveness
>> > > +        */
>> > > +       if (status & XILINX_DMA_XR_IRQ_DELAY_MASK)
>> > > +               dev_dbg(chan->dev, "Inter-packet latency too
>> > > + long\n");
>> > > +
>> > > +       if (status & XILINX_DMA_XR_IRQ_IOC_MASK) {
>> > > +               spin_lock(&chan->lock);
>> > > +               xilinx_dma_complete_descriptor(chan);
>> > > +               chan->idle = true;
>> > > +               xilinx_dma_start_transfer(chan);
>> > > +               spin_unlock(&chan->lock);
>> > > +       }
>> > > +
>> > > +       tasklet_schedule(&chan->tasklet);
>> > > +       return IRQ_HANDLED;
>> > > +}
>> > > +
>> > > +/**
>> > > + * xilinx_dma_do_tasklet - Schedule completion tasklet
>> > > + * @data: Pointer to the Xilinx dma channel structure  */ static
>> > > +void xilinx_dma_do_tasklet(unsigned long data) {
>> > > +       struct xilinx_dma_chan *chan = (struct xilinx_dma_chan
>> > > +*)data;
>> > > +
>> > > +       xilinx_dma_chan_desc_cleanup(chan);
>> > > +}
>> > > +
>> > > +/**
>> > > + * append_desc_queue - Queuing descriptor
>> > > + * @chan: Driver specific dma channel
>> > > + * @desc: dma transaction descriptor  */ static void
>> > > +append_desc_queue(struct xilinx_dma_chan *chan,
>> > > +                             struct xilinx_dma_tx_descriptor *desc) {
>> > > +       struct xilinx_dma_tx_segment *tail_segment;
>> > > +       struct xilinx_dma_tx_descriptor *tail_desc;
>> > > +
>> > > +       if (list_empty(&chan->pending_list))
>> > > +               goto append;
>> > > +
>> > > +       /*
>> > > +        * Add the hardware descriptor to the chain of hardware descriptors
>> > > +        * that already exists in memory.
>> > > +        */
>> > > +       tail_desc = list_last_entry(&chan->pending_list,
>> > > +                                   struct xilinx_dma_tx_descriptor, node);
>> > > +       tail_segment = list_last_entry(&tail_desc->segments,
>> > > +                                      struct xilinx_dma_tx_segment, node);
>> > > +       tail_segment->hw.next_desc = (u32)desc->async_tx.phys;
>> > > +
>> > > +       /*
>> > > +        * Add the software descriptor and all children to the list
>> > > +        * of pending transactions
>> > > +        */
>> > > +append:
>> > > +       list_add_tail(&desc->node, &chan->pending_list);
>> > > +       chan->desc_pendingcount++;
>> > > +
>> > > +       if (unlikely(chan->desc_pendingcount > XILINX_DMA_COALESCE_MAX))
>> {
>> > > +               dev_dbg(chan->dev, "desc pendingcount is too high\n");
>> > > +               chan->desc_pendingcount = XILINX_DMA_COALESCE_MAX;
>> > > +               BUG();
>> > > +       }
>> > > +}
>> > > +
>> > > +/**
>> > > + * xilinx_dma_tx_submit - Submit DMA transaction
>> > > + * @tx: Async transaction descriptor
>> > > + *
>> > > + * Return: cookie value on success and failure value on error  */
>> > > +static dma_cookie_t xilinx_dma_tx_submit(struct
>> > > +dma_async_tx_descriptor *tx) {
>> > > +       struct xilinx_dma_tx_descriptor *desc = to_dma_tx_descriptor(tx);
>> > > +       struct xilinx_dma_chan *chan = to_xilinx_chan(tx->chan);
>> > > +       dma_cookie_t cookie;
>> > > +       unsigned long flags;
>> > > +       int err;
>> > > +
>> > > +       if (chan->err) {
>> > > +               /*
>> > > +                * If reset fails, need to hard reset the system.
>> > > +                * Channel is no longer functional
>> > > +                */
>> > > +               err = xilinx_dma_chan_reset(chan);
>> > > +               if (err < 0)
>> > > +                       return err;
>> > > +       }
>> > > +
>> > > +       spin_lock_irqsave(&chan->lock, flags);
>> > > +
>> > > +       cookie = dma_cookie_assign(tx);
>> > > +
>> > > +       /* Put this transaction onto the tail of the pending queue */
>> > > +       append_desc_queue(chan, desc);
>> > > +
>> > > +       spin_unlock_irqrestore(&chan->lock, flags);
>> > > +
>> > > +       return cookie;
>> > > +}
>> > > +
>> > > +/**
>> > > + * xilinx_dma_prep_slave_sg - prepare descriptors for a DMA_SLAVE
>> > > +transaction
>> > > + * @dchan: DMA channel
>> > > + * @sgl: scatterlist to transfer to/from
>> > > + * @sg_len: number of entries in @scatterlist
>> > > + * @direction: DMA direction
>> > > + * @flags: transfer ack flags
>> > > + * @context: APP words of the descriptor
>> > > + *
>> > > + * Return: Async transaction descriptor on success and NULL on
>> > > +failure  */ static struct dma_async_tx_descriptor
>> > > +*xilinx_dma_prep_slave_sg(
>> > > +       struct dma_chan *dchan, struct scatterlist *sgl, unsigned int sg_len,
>> > > +       enum dma_transfer_direction direction, unsigned long flags,
>> > > +       void *context)
>> > > +{
>> > > +       struct xilinx_dma_chan *chan = to_xilinx_chan(dchan);
>> > > +       struct xilinx_dma_tx_descriptor *desc;
>> > > +       struct xilinx_dma_tx_segment *segment;
>> > > +       u32 *app_w = (u32 *)context;
>> > > +       struct scatterlist *sg;
>> > > +       size_t copy, sg_used;
>> > > +       int i;
>> > > +
>> > > +       if (!is_slave_direction(direction))
>> > > +               return NULL;
>> > > +
>> > > +       /* Allocate a transaction descriptor. */
>> > > +       desc = xilinx_dma_alloc_tx_descriptor(chan);
>> > > +       if (!desc)
>> > > +               return NULL;
>> > > +
>> > > +       desc->direction = direction;
>> > > +       dma_async_tx_descriptor_init(&desc->async_tx, &chan->common);
>> > > +       desc->async_tx.tx_submit = xilinx_dma_tx_submit;
>> > > +
>> > > +       /* Build transactions using information in the scatter gather list */
>> > > +       for_each_sg(sgl, sg, sg_len, i) {
>> > > +               sg_used = 0;
>> > > +
>> > > +               /* Loop until the entire scatterlist entry is used */
>> > > +               while (sg_used < sg_dma_len(sg)) {
>> > > +                       struct xilinx_dma_desc_hw *hw;
>> > > +
>> > > +                       /* Get a free segment */
>> > > +                       segment = xilinx_dma_alloc_tx_segment(chan);
>> > > +                       if (!segment)
>> > > +                               goto error;
>> > > +
>> > > +                       /*
>> > > +                        * Calculate the maximum number of bytes to transfer,
>> > > +                        * making sure it is less than the hw limit
>> > > +                        */
>> > > +                       copy = min_t(size_t, sg_dma_len(sg) - sg_used,
>> > > +                                    XILINX_DMA_MAX_TRANS_LEN);
>> > > +                       hw = &segment->hw;
>> > > +
>> > > +                       /* Fill in the descriptor */
>> > > +                       hw->buf_addr = sg_dma_address(sg) + sg_used;
>> > > +
>> > > +                       hw->control = copy;
>> > > +
>> > > +                       if (direction == DMA_MEM_TO_DEV) {
>> > > +                               if (app_w)
>> > > +                                       memcpy(hw->app, app_w, sizeof(u32) *
>> > > +                                              XILINX_DMA_NUM_APP_WORDS);
>> > > +                       }
>> > > +
>> > > +                       sg_used += copy;
>> > > +
>> > > +                       /*
>> > > +                        * Insert the segment into the descriptor segments
>> > > +                        * list.
>> > > +                        */
>> > > +                       list_add_tail(&segment->node, &desc->segments);
>> > > +               }
>> > > +       }
>> > > +
>> > > +       segment = list_first_entry(&desc->segments,
>> > > +                                  struct xilinx_dma_tx_segment, node);
>> > > +       desc->async_tx.phys = segment->phys;
>> > > +
>> > > +       /* For the last DMA_MEM_TO_DEV transfer, set EOP */
>> > > +       if (direction == DMA_MEM_TO_DEV) {
>> > > +               segment->hw.control |= XILINX_DMA_BD_SOP;
>> > > +               segment = list_last_entry(&desc->segments,
>> > > +                                         struct xilinx_dma_tx_segment,
>> > > +                                         node);
>> > > +               segment->hw.control |= XILINX_DMA_BD_EOP;
>> > > +       }
>> > > +
>> > > +       return &desc->async_tx;
>> > > +
>> > > +error:
>> > > +       xilinx_dma_free_tx_descriptor(chan, desc);
>> > > +       return NULL;
>> > > +}
>> > > +
>> > > +/**
>> > > + * xilinx_dma_terminate_all - Halt the channel and free descriptors
>> > > + * @dchan: DMA Channel pointer
>> > > + *
>> > > + * Return: '0' always
>> > > + */
>> > > +static int xilinx_dma_terminate_all(struct dma_chan *dchan) {
>> > > +       struct xilinx_dma_chan *chan = to_xilinx_chan(dchan);
>> > > +
>> > > +       /* Halt the DMA engine */
>> > > +       xilinx_dma_halt(chan);
>> > > +
>> > > +       /* Remove and free all of the descriptors in the lists */
>> > > +       xilinx_dma_free_descriptors(chan);
>> > > +
>> > > +       return 0;
>> > > +}
>> > > +
>> > > +/**
>> > > + * xilinx_dma_chan_remove - Per Channel remove function
>> > > + * @chan: Driver specific DMA channel  */ static void
>> > > +xilinx_dma_chan_remove(struct xilinx_dma_chan *chan) {
>> > > +       /* Disable interrupts */
>> > > +       chan->ctrl_reg &= ~XILINX_DMA_XR_IRQ_ALL_MASK;
>> > > +       dma_ctrl_write(chan, XILINX_DMA_REG_CONTROL,
>> > > +chan->ctrl_reg);
>> > > +
>> > > +       if (chan->irq > 0)
>> > > +               free_irq(chan->irq, chan);
>> > > +
>> > > +       tasklet_kill(&chan->tasklet);
>> > > +
>> > > +       list_del(&chan->common.device_node);
>> > > +}
>> > > +
>> > > +/**
>> > > + * xilinx_dma_chan_probe - Per Channel Probing
>> > > + * It get channel features from the device tree entry and
>> > > + * initialize special channel handling routines
>> > > + *
>> > > + * @xdev: Driver specific device structure
>> > > + * @node: Device node
>> > > + *
>> > > + * Return: '0' on success and failure value on error  */ static int
>> > > +xilinx_dma_chan_probe(struct xilinx_dma_device *xdev,
>> > > +                                struct device_node *node) {
>> > > +       struct xilinx_dma_chan *chan;
>> > > +       int err;
>> > > +       bool has_dre;
>> > > +       u32 value, width = 0;
>> > > +
>> > > +       /* alloc channel */
>> > > +       chan = devm_kzalloc(xdev->dev, sizeof(*chan), GFP_KERNEL);
>> > > +       if (!chan)
>> > > +               return -ENOMEM;
>> > > +
>> > > +       chan->dev = xdev->dev;
>> > > +       chan->xdev = xdev;
>> > > +       chan->has_sg = xdev->has_sg;
>> > > +       chan->desc_pendingcount = 0x0;
>> > > +
>> > > +       has_dre = of_property_read_bool(node, "xlnx,include-dre");
>> > > +
>> > > +       err = of_property_read_u32(node, "xlnx,datawidth", &value);
>> > > +       if (err) {
>> > > +               dev_err(xdev->dev, "unable to read datawidth property");
>> > > +               return err;
>> > > +       }
>> > > +
>> > > +       width = value >> 3; /* Convert bits to bytes */
>> > > +
>> > > +       /* If data width is greater than 8 bytes, DRE is not in hw */
>> > > +       if (width > 8)
>> > > +               has_dre = false;
>> > > +
>> > > +       if (!has_dre)
>> > > +               xdev->common.copy_align = fls(width - 1);
>> > > +
>> > > +       if (of_device_is_compatible(node, "xlnx,axi-dma-mm2s-channel")) {
>> > > +               chan->id = 0;
>> > > +               chan->ctrl_offset = XILINX_DMA_MM2S_CTRL_OFFSET;
>> > > +       } else if (of_device_is_compatible(node, "xlnx,axi-dma-s2mm-
>> channel")) {
>> > > +               chan->id = 1;
>> > > +               chan->ctrl_offset = XILINX_DMA_S2MM_CTRL_OFFSET;
>> > > +       } else {
>> > > +               dev_err(xdev->dev, "Invalid channel compatible node\n");
>> > > +               return -EINVAL;
>> > > +       }
>> > > +
>> > > +       xdev->chan[chan->id] = chan;
>> > > +
>> > > +       /* Initialize the channel */
>> > > +       err = xilinx_dma_chan_reset(chan);
>> > > +       if (err) {
>> > > +               dev_err(xdev->dev, "Reset channel failed\n");
>> > > +               return err;
>> > > +       }
>> > > +
>> > > +       spin_lock_init(&chan->lock);
>> > > +       INIT_LIST_HEAD(&chan->pending_list);
>> > > +       INIT_LIST_HEAD(&chan->done_list);
>> > > +       INIT_LIST_HEAD(&chan->active_list);
>> > > +       INIT_LIST_HEAD(&chan->free_seg_list);
>> > > +
>> > > +       chan->common.device = &xdev->common;
>> > > +
>> > > +       /* find the IRQ line, if it exists in the device tree */
>> > > +       chan->irq = irq_of_parse_and_map(node, 0);
>> > > +       err = request_irq(chan->irq, xilinx_dma_irq_handler,
>> > > +                         IRQF_SHARED,
>> > > +                         "xilinx-dma-controller", chan);
>> > > +       if (err) {
>> > > +               dev_err(xdev->dev, "unable to request IRQ %d\n", chan->irq);
>> > > +               return err;
>> > > +       }
>> > > +
>> > > +       /* Initialize the tasklet */
>> > > +       tasklet_init(&chan->tasklet, xilinx_dma_do_tasklet,
>> > > +                    (unsigned long)chan);
>> > > +
>> > > +       /* Add the channel to DMA device channel list */
>> > > +       list_add_tail(&chan->common.device_node,
>> > > + &xdev->common.channels);
>> > > +
>> > > +       chan->idle = true;
>> > > +
>> > > +       return 0;
>> > > +}
>> > > +
>> > > +/**
>> > > + * of_dma_xilinx_xlate - Translation function
>> > > + * @dma_spec: Pointer to DMA specifier as found in the device tree
>> > > + * @ofdma: Pointer to DMA controller data
>> > > + *
>> > > + * Return: DMA channel pointer on success and NULL on error  */
>> > > +static struct dma_chan *of_dma_xilinx_xlate(struct of_phandle_args
>> > *dma_spec,
>> > > +                                           struct of_dma *ofdma) {
>> > > +       struct xilinx_dma_device *xdev = ofdma->of_dma_data;
>> > > +       int chan_id = dma_spec->args[0];
>> > > +
>> > > +       if (chan_id >= XILINX_DMA_MAX_CHANS_PER_DEVICE)
>> > > +               return NULL;
>> > > +
>> > > +       return dma_get_slave_channel(&xdev->chan[chan_id]->common);
>> > > +}
>> > > +
>> > > +/**
>> > > + * xilinx_dma_probe - Driver probe function
>> > > + * @pdev: Pointer to the platform_device structure
>> > > + *
>> > > + * Return: '0' on success and failure value on error  */ static int
>> > > +xilinx_dma_probe(struct platform_device *pdev) {
>> > > +       struct xilinx_dma_device *xdev;
>> > > +       struct device_node *child, *node;
>> > > +       struct resource *res;
>> > > +       int i, ret;
>> > > +
>> > > +       xdev = devm_kzalloc(&pdev->dev, sizeof(*xdev), GFP_KERNEL);
>> > > +       if (!xdev)
>> > > +               return -ENOMEM;
>> > > +
>> > > +       xdev->dev = &(pdev->dev);
>> > > +       INIT_LIST_HEAD(&xdev->common.channels);
>> > > +
>> > > +       node = pdev->dev.of_node;
>> > > +
>> > > +       /* Map the registers */
>> > > +       res = platform_get_resource(pdev, IORESOURCE_MEM, 0);
>> > > +       xdev->regs = devm_ioremap_resource(&pdev->dev, res);
>> > > +       if (IS_ERR(xdev->regs))
>> > > +               return PTR_ERR(xdev->regs);
>> > > +
>> > > +       /* Check if SG is enabled */
>> > > +       xdev->has_sg = of_property_read_bool(node,
>> > > + "xlnx,include-sg");
>> > > +
>> > > +       /* Axi DMA only do slave transfers */
>> > > +       dma_cap_set(DMA_SLAVE, xdev->common.cap_mask);
>> > > +       dma_cap_set(DMA_PRIVATE, xdev->common.cap_mask);
>> > > +       xdev->common.device_prep_slave_sg = xilinx_dma_prep_slave_sg;
>> > > +       xdev->common.device_terminate_all = xilinx_dma_terminate_all;
>> > > +       xdev->common.device_issue_pending = xilinx_dma_issue_pending;
>> > > +       xdev->common.device_alloc_chan_resources =
>> > > +               xilinx_dma_alloc_chan_resources;
>> > > +       xdev->common.device_free_chan_resources =
>> > > +               xilinx_dma_free_chan_resources;
>> > > +       xdev->common.device_tx_status = xilinx_dma_tx_status;
>> > > +       xdev->common.directions = BIT(DMA_DEV_TO_MEM) |
>> > BIT(DMA_MEM_TO_DEV);
>> > > +       xdev->common.residue_granularity =
>> > DMA_RESIDUE_GRANULARITY_SEGMENT;
>> > > +       xdev->common.dev = &pdev->dev;
>> > > +
>> > > +       platform_set_drvdata(pdev, xdev);
>> > > +
>> > > +       for_each_child_of_node(node, child) {
>> > > +               ret = xilinx_dma_chan_probe(xdev, child);
>> > > +               if (ret) {
>> > > +                       dev_err(&pdev->dev, "Probing channels failed\n");
>> > > +                       goto free_chan_resources;
>> > > +               }
>> > > +       }
>> > > +
>> > > +       dma_async_device_register(&xdev->common);
>> > > +
>> > > +       ret = of_dma_controller_register(node, of_dma_xilinx_xlate, xdev);
>> > > +       if (ret) {
>> > > +               dev_err(&pdev->dev, "Unable to register DMA to DT\n");
>> > > +               dma_async_device_unregister(&xdev->common);
>> > > +               goto free_chan_resources;
>> > > +       }
>> > > +
>> > > +       dev_info(&pdev->dev, "Xilinx AXI DMA Engine driver
>> > > + Probed!!\n");
>> > > +
>> > > +       return 0;
>> > > +
>> > > +free_chan_resources:
>> > > +       for (i = 0; i < XILINX_DMA_MAX_CHANS_PER_DEVICE; i++)
>> > > +               if (xdev->chan[i])
>> > > +                       xilinx_dma_chan_remove(xdev->chan[i]);
>> > > +
>> > > +       return ret;
>> > > +}
>> > > +
>> > > +/**
>> > > + * xilinx_dma_remove - Driver remove function
>> > > + * @pdev: Pointer to the platform_device structure
>> > > + *
>> > > + * Return: Always '0'
>> > > + */
>> > > +static int xilinx_dma_remove(struct platform_device *pdev) {
>> > > +       struct xilinx_dma_device *xdev = platform_get_drvdata(pdev);
>> > > +       int i;
>> > > +
>> > > +       of_dma_controller_free(pdev->dev.of_node);
>> > > +       dma_async_device_unregister(&xdev->common);
>> > > +
>> > > +       for (i = 0; i < XILINX_DMA_MAX_CHANS_PER_DEVICE; i++)
>> > > +               if (xdev->chan[i])
>> > > +                       xilinx_dma_chan_remove(xdev->chan[i]);
>> > > +
>> > > +       return 0;
>> > > +}
>> > > +
>> > > +static const struct of_device_id xilinx_dma_of_match[] = {
>> > > +       { .compatible = "xlnx,axi-dma-1.00.a",},
>> > > +       {}
>> > > +};
>> > > +MODULE_DEVICE_TABLE(of, xilinx_dma_of_match);
>> > > +
>> > > +static struct platform_driver xilinx_dma_driver = {
>> > > +       .driver = {
>> > > +               .name = "xilinx-dma",
>> > > +               .of_match_table = xilinx_dma_of_match,
>> > > +       },
>> > > +       .probe = xilinx_dma_probe,
>> > > +       .remove = xilinx_dma_remove, };
>> > > +
>> > > +module_platform_driver(xilinx_dma_driver);
>> > > +
>> > > +MODULE_AUTHOR("Xilinx, Inc.");
>> > > +MODULE_DESCRIPTION("Xilinx DMA driver"); MODULE_LICENSE("GPL");
>> > > --
>> > > 2.1.2
>> > >
>> > >
>> > > _______________________________________________
>> > > linux-arm-kernel mailing list
>> > > linux-arm-kernel at lists.infradead.org
>> > > http://lists.infradead.org/mailman/listinfo/linux-arm-kernel
>> >
>> > Cheers,
>> >
>> > Moritz

Thanks,
Moritz


From k.kozlowski at samsung.com  Thu Aug 20 18:27:53 2015
From: k.kozlowski at samsung.com (Krzysztof Kozlowski)
Date: Fri, 21 Aug 2015 10:27:53 +0900
Subject: [PATCH 1/5] drivers: soc: add support for exynos SROM driver
In-Reply-To: <55D5BB56.1030405@samsung.com>
References: <1430296712-10287-1-git-send-email-pankaj.dubey@samsung.com>
 <1430296712-10287-2-git-send-email-pankaj.dubey@samsung.com>
 <5565AFE6.5030106@samsung.com> <55D5BB56.1030405@samsung.com>
Message-ID: <55D67E99.60505@samsung.com>

On 20.08.2015 20:34, Pankaj Dubey wrote:
> Hi Krzysztof,
> 
> Sorry for delay in reply, as I got busy in some other official
> assignments and could not take this series further at that time.
> 
> On Wednesday 27 May 2015 05:22 PM, Krzysztof Kozlowski wrote:
>> W dniu 29.04.2015 o 17:38, Pankaj Dubey pisze:
>>> This patch adds Exynos SROM controller driver which will handle
>>> save restore of SROM registers during S2R.
>>>
>>> Change-Id: Iaddaaebc1d7090c9889e948e68e886519562c43c
>>
>> Please remove it.
> 
> Will do it.
> 
>>
>>> Signed-off-by: Pankaj Dubey <pankaj.dubey at samsung.com>
>>> ---
>>>   drivers/soc/Kconfig               |   1 +
>>>   drivers/soc/Makefile              |   1 +
>>>   drivers/soc/samsung/Kconfig       |  14 ++++
>>>   drivers/soc/samsung/Makefile      |   1 +
>>>   drivers/soc/samsung/exynos-srom.c | 142
>>> ++++++++++++++++++++++++++++++++++++++
>>>   drivers/soc/samsung/exynos-srom.h |  51 ++++++++++++++
>>>   6 files changed, 210 insertions(+)
>>>   create mode 100644 drivers/soc/samsung/Kconfig
>>>   create mode 100644 drivers/soc/samsung/Makefile
>>>   create mode 100644 drivers/soc/samsung/exynos-srom.c
>>>   create mode 100644 drivers/soc/samsung/exynos-srom.h
>>>
>>> diff --git a/drivers/soc/Kconfig b/drivers/soc/Kconfig
>>> index 76d6bd4..c3abfbe 100644
>>> --- a/drivers/soc/Kconfig
>>> +++ b/drivers/soc/Kconfig
>>> @@ -1,6 +1,7 @@
>>>   menu "SOC (System On Chip) specific Drivers"
>>>
>>>   source "drivers/soc/qcom/Kconfig"
>>> +source "drivers/soc/samsung/Kconfig"
>>>   source "drivers/soc/ti/Kconfig"
>>>   source "drivers/soc/versatile/Kconfig"
>>>
>>> diff --git a/drivers/soc/Makefile b/drivers/soc/Makefile
>>> index 063113d..620366f 100644
>>> --- a/drivers/soc/Makefile
>>> +++ b/drivers/soc/Makefile
>>> @@ -3,6 +3,7 @@
>>>   #
>>>
>>>   obj-$(CONFIG_ARCH_QCOM)        += qcom/
>>> +obj-$(CONFIG_SOC_SAMSUNG)    += samsung/
>>>   obj-$(CONFIG_ARCH_TEGRA)    += tegra/
>>>   obj-$(CONFIG_SOC_TI)        += ti/
>>>   obj-$(CONFIG_PLAT_VERSATILE)    += versatile/
>>> diff --git a/drivers/soc/samsung/Kconfig b/drivers/soc/samsung/Kconfig
>>> new file mode 100644
>>> index 0000000..b6fa4e6
>>> --- /dev/null
>>> +++ b/drivers/soc/samsung/Kconfig
>>> @@ -0,0 +1,14 @@
>>> +#
>>> +# SAMSUNG SoC drivers
>>> +#
>>> +menu "Samsung SOC driver support"
>>> +
>>> +config SOC_SAMSUNG
>>> +    bool
>>
>> Any reason for not using menuconfig?
>>
> 
> For one of my Exynos PMU patchset [1] this suggestion came from Russel
> King, not to use user-visible sysmbol if not required.
> [1]:
> http://lists.infradead.org/pipermail/linux-arm-kernel/2014-November/304451.html

Okay, thanks. I'm fine with that.

Best regards,
Krzysztof


From olof at lixom.net  Wed Aug 19 09:18:34 2015
From: olof at lixom.net (Olof Johansson)
Date: Wed, 19 Aug 2015 09:18:34 -0700
Subject: [PATCH] ARM: multi_v7_defconfig: Enable CROS_EC_PROTO for
 ChromeOS EC mfd driver
In-Reply-To: <55D3B195.6030608@osg.samsung.com>
References: <1439881827-22613-1-git-send-email-javier@osg.samsung.com>
 <20150818214608.GA21855@localhost>
 <55D3B195.6030608@osg.samsung.com>
Message-ID: <20150819161834.GB21855@localhost>

On Wed, Aug 19, 2015 at 12:28:37AM +0200, Javier Martinez Canillas wrote:
> Hello Olof,
> 
> On 08/18/2015 11:46 PM, Olof Johansson wrote:
> > On Tue, Aug 18, 2015 at 09:10:27AM +0200, Javier Martinez Canillas wrote:
> >> The ChromeOS mfd driver (MFD_CROS_EC) select the CROS_EC_PROTO config
> >> symbol because the driver uses some communication helper functions in
> >> drivers/platform/chrome/cros_ec_proto.c but other drivers depends on
> >> CROS_EC_PROTO instead. Mixing select and depends can lead to circular
> >> Kconfig dependencies so the MFD_CROS_EC select should be changed to a
> >> depends on CROS_EC_PROTO instead.
> >>
> >> But doing so will break git bisect-ability since MFD_CROS_EC will not
> >> be enabled anymore unless the default configs first explicitly enable
> >> the CROS_EC_PROTO dependency.
> >>
> >> Signed-off-by: Javier Martinez Canillas <javier at osg.samsung.com>
> > 
> > Applied to cros/ec-config in arm-soc, which will stay stable in case others
> > need to bring in as a prereq.
> >
> 
> Thanks but Bartolomiej's feedback [0] on my patch that made CROS_EC_PROTO
> a user selectable option was to leave it as a non-visible option and instead
> change the other Kconfig symbols to select CROS_EC_PROTO consistently.
> 
> So tomorrow I'll post a new patch series along those lines that will make
> this patch obsolete since no defconfig changes will be needed.
> 
> IOW, please drop this patch and sorry for the inconvenience.

Done.


-Olof


From olof at lixom.net  Thu Aug 20 18:28:48 2015
From: olof at lixom.net (Olof Johansson)
Date: Thu, 20 Aug 2015 18:28:48 -0700
Subject: [PATCH v2] ARM: dts: UniPhier: fix PPI interrupt CPU mask of
 timer nodes
In-Reply-To: <1439963366-4848-1-git-send-email-yamada.masahiro@socionext.com>
References: <1439963366-4848-1-git-send-email-yamada.masahiro@socionext.com>
Message-ID: <20150821012848.GA4865@localhost>

On Wed, Aug 19, 2015 at 02:49:26PM +0900, Masahiro Yamada wrote:
> This SoC is integrated with 4 Cortex-A9 cores.  The GIC bindings
> document says that the bits[15:8] of the 3rd cell of the interrupts
> property represents PPI interrupt CPU mask.  Because the timer
> interrupts are wired to all of the 4 cores, bits[15:8] should be set
> to 0xf.
> 
> Signed-off-by: Masahiro Yamada <yamada.masahiro at socionext.com>
> ---
> 
> Changes in v2:
>   - Fix git-description

Thanks, applied.


-Olof



From olof at lixom.net  Thu Aug 20 18:30:44 2015
From: olof at lixom.net (Olof Johansson)
Date: Thu, 20 Aug 2015 18:30:44 -0700
Subject: [GIT PULL] Reset controller changes for v4.3
In-Reply-To: <1439973419.3160.6.camel@pengutronix.de>
References: <1439973419.3160.6.camel@pengutronix.de>
Message-ID: <20150821013044.GB4865@localhost>

On Wed, Aug 19, 2015 at 10:36:59AM +0200, Philipp Zabel wrote:
> Hi arm-soc maintainers,
> 
> This tag includes reset controller support for LPC18xx, SocFPGA Arria10,
> AR71XX/AR9XXX and Zynq and moves all dt-bindings include files into the
> same place.
> 
> regards
> Philipp
> 
> The following changes since commit bc0195aad0daa2ad5b0d76cce22b167bc3435590:
> 
>   Linux 4.2-rc2 (2015-07-12 15:10:30 -0700)
> 
> are available in the git repository at:
> 
>   git://git.pengutronix.de/git/pza/linux.git tags/reset-for-4.3
> 
> for you to fetch changes up to 5d44595c2627f7edcd8c24a76b13bd115f9fc2da:
> 
>   Merge branch 'reset/ath79' into reset/next (2015-08-16 17:11:20 +0200)

Thanks, merged into next/drivers.


-Olof


From olof at lixom.net  Thu Aug 20 18:34:19 2015
From: olof at lixom.net (Olof Johansson)
Date: Thu, 20 Aug 2015 18:34:19 -0700
Subject: [GIT PULL v2 0/5] Samsung updates for v4.3
In-Reply-To: <55CCE517.2070003@kernel.org>
References: <55CCE517.2070003@kernel.org>
Message-ID: <20150821013419.GC4865@localhost>

On Fri, Aug 14, 2015 at 03:42:31AM +0900, Kukjin Kim wrote:
> Hello Arnd, Olof, Kevin
> 
> Here is re-spin of pull request for Samsung stuff for v4.3 as per Olof's
> suggestion.
> 
> Most of this pull-requests are to switch to support generic cpufreq
> driver for exynos3250, 4210, 4412 and 5250 and several exynos dt updates.
> 
> Note as I commented in each tag, each pull-request(signed tag) has a
> dependency with each other, so please keep the ordering in this time.
> 
> 1) tags/samsung-clk-driver
> 2) tags/samsung-late-dt
> 3) tags/samsung-soc
> 4) tags/samsung-late-cpufreq-driver
> 5) tags/samsung-defconfig-new
> 
> If any problems, please kindly let me know.

That ordering is awkward for us. driver->dt->soc->driver->defconfig is
not the way we do it.

I'll merge them into a next/late branch together, and we might or might not
send it in this merge window depending on how it goes.

The lesson to learn here (for us and you) is that if there is complex
contents, getting it sent in very early is important: rc2/rc3 is
ideal. We're likely to be less tolerant of messy dependencies as we start
to approach -rc6 and already have a lot of things merged up. We might
also have locked into ordering between branches by then that doesn't
match what you've used.


-Olof



From olof at lixom.net  Thu Aug 20 18:35:53 2015
From: olof at lixom.net (Olof Johansson)
Date: Thu, 20 Aug 2015 18:35:53 -0700
Subject: [GIT PULL v2 1/5] Samsung clk driver updates for v4.3
In-Reply-To: <55CCE685.40501@kernel.org>
References: <55CCE517.2070003@kernel.org>
 <55CCE685.40501@kernel.org>
Message-ID: <20150821013553.GD4865@localhost>

On Fri, Aug 14, 2015 at 03:48:37AM +0900, Kukjin Kim wrote:
> The following changes since commit d770e558e21961ad6cfdf0ff7df0eb5d7d4f0754:
> 
>   Linux 4.2-rc1 (2015-07-05 11:01:52 -0700)
> 
> are available in the git repository at:
> 
>   git://git.kernel.org/pub/scm/linux/kernel/git/kgene/linux-samsung.git
> tags/samsung-clk-driver
> 
> for you to fetch changes up to cd6aceef028afc3fa216e3e7bc94cc31632cad43:
> 
>   clk: exynos4x12: add cpu clock configuration data and instantiate cpu
> clock (2015-08-14 02:00:43 +0900)
> 
> ----------------------------------------------------------------
> Samsung clk driver updates for v4.3
> 
> - add cpu clock configuration data and instantiate cpu clock
>   for exynos3250, 4210, 4412 and 5250 SoCs to support Samsung
>   specific cpu-clock type
> 
> * Note this branch has been provided to clk tree as a topic branch

Merged into next/late.


-Olof



From olof at lixom.net  Thu Aug 20 18:37:26 2015
From: olof at lixom.net (Olof Johansson)
Date: Thu, 20 Aug 2015 18:37:26 -0700
Subject: [GIT PULL v2 2/5] Samsung 2nd DT updates for v4.3
In-Reply-To: <55CCE6F6.1090001@kernel.org>
References: <55CCE517.2070003@kernel.org>
 <55CCE6F6.1090001@kernel.org>
Message-ID: <20150821013726.GE4865@localhost>

On Fri, Aug 14, 2015 at 03:50:30AM +0900, Kukjin Kim wrote:
> The following changes since commit 5e080b078fa1f929d9aa5586985d5e7c0739d207:
> 
>   ARM: dts: Extend exynos5420-pinctrl nodes using labels instead of
> paths (2015-07-21 13:01:23 +0900)
> 
> are available in the git repository at:
> 
>   git://git.kernel.org/pub/scm/linux/kernel/git/kgene/linux-samsung.git
> tags/samsung-late-dt
> 
> for you to fetch changes up to ba032795463bfc461937dbde7a345103a47f969b:
> 
>   ARM: dts: add iommu property to JPEG device for exynos4 (2015-08-14
> 02:30:58 +0900)
> 
> ----------------------------------------------------------------
> Samsung 2nd DT updates for v4.3
> 
> - for exynos3250, 4212, 4412 and 5250
>   : add CPU OPP and regulator supply property
> 
> - for exynos3250
>   : add CPU cooling binding for exynos3250 boards
> 
> - for exynos4 SoCs
>   : add iommu property to JPEG device
> 
> - for exynos4412-odroidu3
>   : enable SPI1
> 
> - for exynos5250-snow
>   : add SPI CS
> 
> - for exynos5422
>   : add exynos5422-cpus.dtsi to correct cpu order
> 
> * Note this branch is depending on tags/samsung-clk-driver

It's not depending on it, it contains it -- which is what's required here or
bisectability would be broken.

Merged into next/late.


-Olof



From olof at lixom.net  Thu Aug 20 18:39:03 2015
From: olof at lixom.net (Olof Johansson)
Date: Thu, 20 Aug 2015 18:39:03 -0700
Subject: [GIT PULL v2 4/5] Samsung cpufreq driver updates for v4.3
In-Reply-To: <55CCE781.1090007@kernel.org>
References: <55CCE517.2070003@kernel.org>
 <55CCE781.1090007@kernel.org>
Message-ID: <20150821013903.GG4865@localhost>

On Fri, Aug 14, 2015 at 03:52:49AM +0900, Kukjin Kim wrote:
> The following changes since commit d770e558e21961ad6cfdf0ff7df0eb5d7d4f0754:
> 
>   Linux 4.2-rc1 (2015-07-05 11:01:52 -0700)
> 
> are available in the git repository at:
> 
>   git://git.kernel.org/pub/scm/linux/kernel/git/kgene/linux-samsung.git
> tags/samsung-late-cpufreq-driver
> 
> for you to fetch changes up to 5e3863a74fb70d6a432504ba2fa16a998cd3736b:
> 
>   cpufreq: exynos: Remove unselectable rule for arm-exynos-cpufreq.o
> (2015-08-14 02:36:33 +0900)

Merged into next/late.


-Olof



From olof at lixom.net  Thu Aug 20 18:38:13 2015
From: olof at lixom.net (Olof Johansson)
Date: Thu, 20 Aug 2015 18:38:13 -0700
Subject: [GIT PULL v2 3/5] Samsung SoC updates for v4.3
In-Reply-To: <55CCE73C.3080404@kernel.org>
References: <55CCE517.2070003@kernel.org>
 <55CCE73C.3080404@kernel.org>
Message-ID: <20150821013813.GF4865@localhost>

On Fri, Aug 14, 2015 at 03:51:40AM +0900, Kukjin Kim wrote:
> The following changes since commit d770e558e21961ad6cfdf0ff7df0eb5d7d4f0754:
> 
>   Linux 4.2-rc1 (2015-07-05 11:01:52 -0700)
> 
> are available in the git repository at:
> 
>   git://git.kernel.org/pub/scm/linux/kernel/git/kgene/linux-samsung.git
> tags/samsung-soc
> 
> for you to fetch changes up to bdd2648e50508cbb2eb6d1c303e4d2d6d7505400:
> 
>   ARM: EXYNOS: switch to using generic cpufreq driver for exynos4x12
> (2015-08-14 03:07:10 +0900)
> 

Merged into next/late.


-Olof



From olof at lixom.net  Thu Aug 20 18:40:36 2015
From: olof at lixom.net (Olof Johansson)
Date: Thu, 20 Aug 2015 18:40:36 -0700
Subject: [GIT PULL v2 5/5] Samsung defconfig updates for v4.3
In-Reply-To: <55CCE7BF.2070407@kernel.org>
References: <55CCE517.2070003@kernel.org>
 <55CCE7BF.2070407@kernel.org>
Message-ID: <20150821014036.GH4865@localhost>

On Fri, Aug 14, 2015 at 03:53:51AM +0900, Kukjin Kim wrote:
> The following changes since commit d770e558e21961ad6cfdf0ff7df0eb5d7d4f0754:
> 
>   Linux 4.2-rc1 (2015-07-05 11:01:52 -0700)
> 
> are available in the git repository at:
> 
>   git://git.kernel.org/pub/scm/linux/kernel/git/kgene/linux-samsung.git
> tags/samsung-defconfig-new
> 
> for you to fetch changes up to 2b347c6494cbc6bfdc81b5201b8aa34afb2c3500:
> 
>   ARM: exynos_defconfig: Enable cpufreq-dt driver (2015-08-12 08:17:31
> +0900)

Merged into next/late.


-Olof



From olof at lixom.net  Thu Aug 20 18:42:31 2015
From: olof at lixom.net (Olof Johansson)
Date: Thu, 20 Aug 2015 18:42:31 -0700
Subject: [GIT PULL 3/9] ARM: tegra: Cleanup patches for v4.3-rc1
In-Reply-To: <1439563720-13189-4-git-send-email-thierry.reding@gmail.com>
References: <1439563720-13189-1-git-send-email-thierry.reding@gmail.com>
 <1439563720-13189-4-git-send-email-thierry.reding@gmail.com>
Message-ID: <20150821014231.GI4865@localhost>

On Fri, Aug 14, 2015 at 04:48:34PM +0200, Thierry Reding wrote:
> Hi ARM SoC maintainers,
> 
> The following changes since commit d770e558e21961ad6cfdf0ff7df0eb5d7d4f0754:
> 
>   Linux 4.2-rc1 (2015-07-05 11:01:52 -0700)
> 
> are available in the git repository at:
> 
>   git://git.kernel.org/pub/scm/linux/kernel/git/tegra/linux.git tags/tegra-for-4.3-cleanup
> 
> for you to fetch changes up to 5cf4af3bebb718b72a23b7e80fddfe8b4e8b0620:
> 
>   ALSA: hda/tegra: Order clock and reset names consistently (2015-07-16 09:42:05 +0200)

Merged, thanks!


-Olof



From olof at lixom.net  Thu Aug 20 18:45:14 2015
From: olof at lixom.net (Olof Johansson)
Date: Thu, 20 Aug 2015 18:45:14 -0700
Subject: [GIT PULL 4/9] ARM: tegra: Core SoC changes for v4.3-rc1
In-Reply-To: <1439563720-13189-5-git-send-email-thierry.reding@gmail.com>
References: <1439563720-13189-1-git-send-email-thierry.reding@gmail.com>
 <1439563720-13189-5-git-send-email-thierry.reding@gmail.com>
Message-ID: <20150821014514.GJ4865@localhost>

On Fri, Aug 14, 2015 at 04:48:35PM +0200, Thierry Reding wrote:
> Hi ARM SoC maintainers,
> 
> The following changes since commit d770e558e21961ad6cfdf0ff7df0eb5d7d4f0754:
> 
>   Linux 4.2-rc1 (2015-07-05 11:01:52 -0700)
> 
> are available in the git repository at:
> 
>   git://git.kernel.org/pub/scm/linux/kernel/git/tegra/linux.git tags/tegra-for-4.3-soc
> 
> for you to fetch changes up to 1ec0e115f8604940491861d207cc1e1478db97b3:
> 
>   ARM: tegra: cpuidle: implement cpuidle_state.enter_freeze() (2015-08-13 16:53:38 +0200)
> 
> Thanks,
> Thierry
> 
> ----------------------------------------------------------------
> ARM: tegra: Core SoC changes for v4.3-rc1
> 
> This contains a bit more of Tegra210 support, which is shaping up pretty
> nicely. Other than that there are a couple of cleanup patches here, too.

Merged into next/drivers. Thanks.


-Olof



From olof at lixom.net  Thu Aug 20 18:47:33 2015
From: olof at lixom.net (Olof Johansson)
Date: Thu, 20 Aug 2015 18:47:33 -0700
Subject: [GIT PULL 5/9] ARM: tegra: CPU frequency scaling for v4.3-rc1
In-Reply-To: <1439563720-13189-6-git-send-email-thierry.reding@gmail.com>
References: <1439563720-13189-1-git-send-email-thierry.reding@gmail.com>
 <1439563720-13189-6-git-send-email-thierry.reding@gmail.com>
Message-ID: <20150821014733.GK4865@localhost>

On Fri, Aug 14, 2015 at 04:48:36PM +0200, Thierry Reding wrote:
> Hi ARM SoC maintainers,
> 
> The following changes since commit d770e558e21961ad6cfdf0ff7df0eb5d7d4f0754:
> 
>   Linux 4.2-rc1 (2015-07-05 11:01:52 -0700)
> 
> are available in the git repository at:
> 
>   git://git.kernel.org/pub/scm/linux/kernel/git/tegra/linux.git tags/tegra-for-4.3-cpufreq
> 
> for you to fetch changes up to 9eb15dbbfa1a23b5e65efaf1d5d6c47798e7264b:
> 
>   cpufreq: Add cpufreq driver for Tegra124 (2015-07-16 09:34:09 +0200)
> 
> Thanks,
> Thierry
> 
> ----------------------------------------------------------------
> ARM: tegra: CPU frequency scaling for v4.3-rc1
> 
> This adds CPU frequency scaling support for Tegra124.

Merged, thanks.

-Olof


From olof at lixom.net  Thu Aug 20 18:58:48 2015
From: olof at lixom.net (Olof Johansson)
Date: Thu, 20 Aug 2015 18:58:48 -0700
Subject: [GIT PULL 8/9] ARM: tegra: Devicetree changes for v4.3-rc1
In-Reply-To: <1439563720-13189-9-git-send-email-thierry.reding@gmail.com>
References: <1439563720-13189-1-git-send-email-thierry.reding@gmail.com>
 <1439563720-13189-9-git-send-email-thierry.reding@gmail.com>
Message-ID: <20150821015848.GM4865@localhost>

On Fri, Aug 14, 2015 at 04:48:39PM +0200, Thierry Reding wrote:
> Hi ARM SoC maintainers,
> 
> The following changes since commit d770e558e21961ad6cfdf0ff7df0eb5d7d4f0754:
> 
>   Linux 4.2-rc1 (2015-07-05 11:01:52 -0700)
> 
> are available in the git repository at:
> 
>   git://git.kernel.org/pub/scm/linux/kernel/git/tegra/linux.git tags/tegra-for-4.3-dt
> 
> for you to fetch changes up to 6909c6632fdbea441b5077b4f882c0bf4b71997e:
> 
>   ARM: tegra: Add gpio-ranges property (2015-08-13 16:31:53 +0200)
> 
> Thanks,
> Thierry
> 
> ----------------------------------------------------------------
> ARM: tegra: Devicetree changes for v4.3-rc1
> 
> Enables CPU frequency scaling on Jetson TK1 and enables the GK20A GPU on
> Venice2 and Jetson TK1. This also enables support for the PMU hardware
> found on Tegra124, which among other things, can be used for performance
> measurements.

Merged, thanks.


-Olof


From olof at lixom.net  Thu Aug 20 18:57:50 2015
From: olof at lixom.net (Olof Johansson)
Date: Thu, 20 Aug 2015 18:57:50 -0700
Subject: [GIT PULL 7/9] ARM: tegra: Memory controller updates for v4.3-rc1
In-Reply-To: <1439563720-13189-8-git-send-email-thierry.reding@gmail.com>
References: <1439563720-13189-1-git-send-email-thierry.reding@gmail.com>
 <1439563720-13189-8-git-send-email-thierry.reding@gmail.com>
Message-ID: <20150821015750.GL4865@localhost>

On Fri, Aug 14, 2015 at 04:48:38PM +0200, Thierry Reding wrote:
> Hi ARM SoC maintainers,
> 
> The following changes since commit d770e558e21961ad6cfdf0ff7df0eb5d7d4f0754:
> 
>   Linux 4.2-rc1 (2015-07-05 11:01:52 -0700)
> 
> are available in the git repository at:
> 
>   git://git.kernel.org/pub/scm/linux/kernel/git/tegra/linux.git tags/tegra-for-4.3-memory
> 
> for you to fetch changes up to 588c43a7bd5a53ae523b318e1db16bdd59963a3c:
> 
>   memory: tegra: Add Tegra210 support (2015-08-13 16:07:52 +0200)
> 
> Thanks,
> Thierry
> 
> ----------------------------------------------------------------
> ARM: tegra: Memory controller updates for v4.3-rc1
> 
> Adds support for Tegra210, which allows the SMMU to be used on this new
> SoC generation.

Merged, thanks.


-Olof


From olof at lixom.net  Thu Aug 20 19:03:22 2015
From: olof at lixom.net (Olof Johansson)
Date: Thu, 20 Aug 2015 19:03:22 -0700
Subject: [GIT PULL] Xilinx Zynq DT changes for v4.3 v2
In-Reply-To: <55D4646F.7010404@monstr.eu>
References: <55D4646F.7010404@monstr.eu>
Message-ID: <20150821020322.GO4865@localhost>

On Wed, Aug 19, 2015 at 01:11:43PM +0200, Michal Simek wrote:
> Hi guys,
> 
> Philipp just sent his PR to you with adding reset controller for Zynq
> (http://www.spinics.net/lists/arm-kernel/msg440136.html).
> Can you please consider to add this one more patch to your tree?
> It is one more patch on the top of existing zynq/dt branch which you
> already have in arm-soc git repo.

The change is small enough, so yes we can merge it with the below fixed:

> Moritz Fischer (1):
>       dts: zynq: Add devicetree entry for Xilinx Zynq reset controller.

ARM: dts: <....> is the format we want here -- that's what most other platforms
use as well. I.e. please add ARM as a prefix.

I can do it here and just apply as a patch too instead of merging, just let me
know.


Thanks,


-Olof



From olof at lixom.net  Thu Aug 20 19:00:42 2015
From: olof at lixom.net (Olof Johansson)
Date: Thu, 20 Aug 2015 19:00:42 -0700
Subject: [GIT PULL 9/9] ARM: tegra: Default configuration updates for
 v4.3-rc1
In-Reply-To: <1439563720-13189-10-git-send-email-thierry.reding@gmail.com>
References: <1439563720-13189-1-git-send-email-thierry.reding@gmail.com>
 <1439563720-13189-10-git-send-email-thierry.reding@gmail.com>
Message-ID: <20150821020042.GN4865@localhost>

On Fri, Aug 14, 2015 at 04:48:40PM +0200, Thierry Reding wrote:
> Hi ARM SoC maintainers,
> 
> The following changes since commit d770e558e21961ad6cfdf0ff7df0eb5d7d4f0754:
> 
>   Linux 4.2-rc1 (2015-07-05 11:01:52 -0700)
> 
> are available in the git repository at:
> 
>   git://git.kernel.org/pub/scm/linux/kernel/git/tegra/linux.git tags/tegra-for-4.3-defconfig
> 
> for you to fetch changes up to 258d9bc5e77fa40e290a0bd480d5349224374480:
> 
>   ARM: tegra: Update multi_v7_defconfig (2015-08-14 16:26:00 +0200)
> 
> Thanks,
> Thierry
> 
> ----------------------------------------------------------------
> ARM: tegra: Default configuration updates for v4.3-rc1
> 
> Enable the GK20A GPU (via the Nouveau driver) and CPU frequency scaling
> on Tegra124.

I know there are issues surfaced by these changes, but the bug is unrelated to
the defconfig update per se.

I've chosen to merge this, with the hope that the root cause will be found and
fixed quickly. If needed, we can revert the options that are causing problems.


-Olof


From tyler.baker at linaro.org  Thu Aug 20 19:39:10 2015
From: tyler.baker at linaro.org (Tyler Baker)
Date: Thu, 20 Aug 2015 19:39:10 -0700
Subject: [GIT PULL 9/9] ARM: tegra: Default configuration updates for
 v4.3-rc1
In-Reply-To: <20150821020042.GN4865@localhost>
References: <1439563720-13189-1-git-send-email-thierry.reding@gmail.com>
 <1439563720-13189-10-git-send-email-thierry.reding@gmail.com>
 <20150821020042.GN4865@localhost>
Message-ID: <CANMBJr46__yBZjUhWkxvFz8RAODcbk=wzy2bq1ak-J_WAprH-A@mail.gmail.com>

On 20 August 2015 at 19:00, Olof Johansson <olof at lixom.net> wrote:
> On Fri, Aug 14, 2015 at 04:48:40PM +0200, Thierry Reding wrote:
>> Hi ARM SoC maintainers,
>>
>> The following changes since commit d770e558e21961ad6cfdf0ff7df0eb5d7d4f0754:
>>
>>   Linux 4.2-rc1 (2015-07-05 11:01:52 -0700)
>>
>> are available in the git repository at:
>>
>>   git://git.kernel.org/pub/scm/linux/kernel/git/tegra/linux.git tags/tegra-for-4.3-defconfig
>>
>> for you to fetch changes up to 258d9bc5e77fa40e290a0bd480d5349224374480:
>>
>>   ARM: tegra: Update multi_v7_defconfig (2015-08-14 16:26:00 +0200)
>>
>> Thanks,
>> Thierry
>>
>> ----------------------------------------------------------------
>> ARM: tegra: Default configuration updates for v4.3-rc1
>>
>> Enable the GK20A GPU (via the Nouveau driver) and CPU frequency scaling
>> on Tegra124.
>
> I know there are issues surfaced by these changes, but the bug is unrelated to
> the defconfig update per se.
>
> I've chosen to merge this, with the hope that the root cause will be found and
> fixed quickly. If needed, we can revert the options that are causing problems.

Fine with me, as the issue seem to be local to my board.


From Dongsheng.Wang at freescale.com  Thu Aug 20 20:07:46 2015
From: Dongsheng.Wang at freescale.com (Wang Dongsheng)
Date: Fri, 21 Aug 2015 03:07:46 +0000
Subject: [PATCH 2/2] soc/fsl: add ftm alarm driver for ls1021a platform
In-Reply-To: <CACRpkdYB23PbECUb2FP=_ck8PJe42wdifEcMSdKWrKnJLNp=pg@mail.gmail.com>
References: <1439358807-9024-1-git-send-email-dongsheng.wang@freescale.com>
 <1439358807-9024-2-git-send-email-dongsheng.wang@freescale.com>
 <CACRpkdbninKuGzhEc5mN+85j-=w_wYQgra-Ark_Du6gWKN2=tg@mail.gmail.com>
 <SN1PR0301MB161682A7FC5200580BED09119D7C0@SN1PR0301MB1616.namprd03.prod.outlook.com>
 <CACRpkdYB23PbECUb2FP=_ck8PJe42wdifEcMSdKWrKnJLNp=pg@mail.gmail.com>
Message-ID: <SN1PR0301MB1616A184ADD450D95B29E8A19D650@SN1PR0301MB1616.namprd03.prod.outlook.com>

Hi Walleij and Russell,

I will drop this patch. Thanks for your review.

[PATCH v2 1/2] soc/fsl: add freescale dir for SOC specific drivers

But the 1/2 of the patches also need, because there has another patch(Freescale FPGA driver) need 1/2 patch.
Need I push the 1/2 patch with another patches(Freescale FPGA driver) or push 1/2 standalone without another
patch? 

Regards,
-Dongsheng

> -----Original Message-----
> From: Linus Walleij [mailto:linus.walleij at linaro.org]
> Sent: Friday, August 14, 2015 6:07 PM
> To: Wang Dongsheng-B40534; John Stultz
> Cc: Alessandro Zummo; Alexandre Belloni; Shawn Guo; Nair, Sandeep; Hans de Goede;
> Wang Huan-B18965; linux-arm-kernel at lists.infradead.org; linux-
> kernel at vger.kernel.org; rtc-linux at googlegroups.com
> Subject: Re: [PATCH 2/2] soc/fsl: add ftm alarm driver for ls1021a platform
> 
> On Fri, Aug 14, 2015 at 5:12 AM, Wang Dongsheng
> <Dongsheng.Wang at freescale.com> wrote:
> >> On Wed, Aug 12, 2015 at 7:53 AM, Dongsheng Wang
> >> <dongsheng.wang at freescale.com> wrote:
> >>
> >> > From: Wang Dongsheng <dongsheng.wang at freescale.com>
> >> >
> >> > Only Ftm0 can be used when system going to deep sleep. So this driver
> >> > to support ftm0 as a wakeup source.
> >> >
> >> > Signed-off-by: Wang Dongsheng <dongsheng.wang at freescale.com>
> >> > ---
> >> > *V2*
> >> > Change Copyright 2014 to 2015.
> >> (...)
> >> > +config FTM_ALARM
> >> > +       bool "FTM alarm driver"
> >> > +       depends on SOC_LS1021A
> >> > +       default n
> >> > +       help
> >> > +         Say y here to enable FTM alarm support.  The FTM alarm provides
> >> > +         alarm functions for wakeup system from deep sleep.  There is only
> >> > +         one FTM can be used in ALARM(FTM 0).
> >> (...)
> >> > +static u32 time_to_cycle(unsigned long time)
> >> > +static u32 cycle_to_time(u32 cycle)
> >> > +static int ftm_set_alarm(u64 cycle)
> >> > +static irqreturn_t ftm_alarm_interrupt(int irq, void *dev_id)
> >> > +static ssize_t ftm_alarm_show(struct device *dev,
> >> > +                             struct device_attribute *attr,
> >> > +                             char *buf)
> >> > +static ssize_t ftm_alarm_store(struct device *dev,
> >> > +                              struct device_attribute *attr,
> >> > +                              const char *buf, size_t count)
> >> (...)
> >> > +static struct device_attribute ftm_alarm_attributes = __ATTR(ftm_alarm,
> 0644,
> >> > +                       ftm_alarm_show, ftm_alarm_store);
> >>
> >> If you're gonna invent ABIs, document then in Documentation/ABI/testing/*.
> >>
> >> But I don't get it. Why is this driver not in drivers/rtc?
> >>
> >> It does a subset of what an RTC does. The ioctl()'s of an RTC
> >> can do what you want to do. And much much more.
> >>
> >> If it can't do all an RTC can do, surely the RTC subsystem
> >> can be augmented to host it anyway. It's way to close to
> >> an RTC to have it's own random sysfs driver like this.
> >>
> >> Unless I'm totally off, rewrite this to an RTC driver and post
> >> it to the RTC maintainers.
> >
> > FlexTimer is not a RTC device and not have any rtc deivce function. They
> belong to
> > different devices, why we need to register this to RTC framework? I am
> confused about this.
> >
> > Now in freescale layerscape platform this driver is only for FlexTimer0, and
> not
> > fit for each flextimer. Because only FlexTimer0 still turn-on when system in
> the Deep Sleep.
> >
> > If the "alarm" make you feel confused or mislead you think this is a RTC
> devices. I think
> > I need to change the "alarm" to "timer".
> 
> I think it is an RTC, it is just that the hardware engineer
> designed it with a wakeup usecase in mind and did not call
> it an RTC. Wakeup is one of the things RTCs do.
> 
> If you inspect a few drivers in drivers/rtc such as drivers/rtc/rtc-pl030.c
> you will find that they are just as crude as this "alarm" thing.
> 
> It has a counter that counts cycles, it has a comparator
> and an alarm function. It is an on-chip RTC, just like PL030
> no matter what the datasheet or hardware engineer thinks it
> should be called, the Linux kernel calls this an RTC, and it
> has a subsystem for handling it, so we should use it and
> not invent random new stuff.
> 
> If the hardware is really so strange that the counter can only
> be started if you also put an alarm at the same time (I doubt
> it, but OK if you say so) it is a subset of an RTC that can
> only be used for alarms but not timekeeping, but it should
> *still* live in drivers/rtc.
> 
> Think for a moment on the huge effort that John Stultz put into
> integrating Android alarm timers with POSIX and the RTC
> subsystem and fixing it all from the smallest handset to
> the largest S360 supercomputer. The approach of a custom
> device just throws all of that out the window and reinvents the
> mechanism in userspace, forcing all standardized userspace to
> have special code to handle this special alarm with its
> special sysfs ABI.
> 
> Check
> commit ff3ead96d17f47ee70c294a5cc2cce9b61e82f0f
> "timers: Introduce in-kernel alarm-timer interface"
> for example.
> 
> Even if you persist on keeping it in its own magic driver
> like this, it should implement the alarm timer interface
> from <linux/alarmtimer.h> and I bet after that you don't
> need the sysfs files anymore, as the system will sleep
> and wake up from the regular syscalls instead of using
> magic poking in sysfs from userspace. AFAICT this hardware
> is designed for exactly this usecase.
> 
> tools/testing/selftests/timers/alarmtimer-suspend.c
> is there for you to test your driver with alarmtimer
> support.
> 
> Needless to say: if you implement it as an RTC you get the
> alarmtimer interaction for free. That is why we have the
> subsystem after all: to be helpful.
> 
> Yours,
> Linus Walleij

From leo.yan at linaro.org  Thu Aug 20 20:40:22 2015
From: leo.yan at linaro.org (Leo Yan)
Date: Fri, 21 Aug 2015 11:40:22 +0800
Subject: [PATCH] arm64: enable generic idle loop
Message-ID: <1440128422-4170-1-git-send-email-leo.yan@linaro.org>

Enable generic idle loop for ARM64, so can support for hlt/nohlt
command line options to override default idle loop behavior.

Signed-off-by: Leo Yan <leo.yan at linaro.org>
---
 arch/arm64/Kconfig | 1 +
 1 file changed, 1 insertion(+)

diff --git a/arch/arm64/Kconfig b/arch/arm64/Kconfig
index 0f6edb1..c404e74 100644
--- a/arch/arm64/Kconfig
+++ b/arch/arm64/Kconfig
@@ -31,6 +31,7 @@ config ARM64
 	select GENERIC_CLOCKEVENTS_BROADCAST if SMP
 	select GENERIC_CPU_AUTOPROBE
 	select GENERIC_EARLY_IOREMAP
+	select GENERIC_IDLE_POLL_SETUP
 	select GENERIC_IRQ_PROBE
 	select GENERIC_IRQ_SHOW
 	select GENERIC_IRQ_SHOW_LEVEL
-- 
1.9.1



From hongzhou.yang at mediatek.com  Thu Aug 20 21:46:44 2015
From: hongzhou.yang at mediatek.com (Hongzhou Yang)
Date: Thu, 20 Aug 2015 21:46:44 -0700
Subject: [PATCH v3] pinctrl: mediatek: Fix multiple registration issue.
Message-ID: <1440132404-27749-1-git-send-email-hongzhou.yang@mediatek.com>

Since our common driver need support main chip and PMU
at the same time, that means it will register two
pinctrl device, and the pinctrl_desc structure should
be used two times.

But pinctrl_desc use global static definition, then
the latest registered pinctrl device will overwrite
the old one's, all members in pinctrl_desc will set to
the new one's, such as name, pins and pins numbers, etc.
This is a bug. Changing to use devm_kzalloc to fix it.

Cc: stable at vger.kernel.org # v4.1+
Signed-off-by: Hongzhou Yang <hongzhou.yang at mediatek.com>
---
 Use dynamic allocation to fix multiple registration issue.

 drivers/pinctrl/mediatek/pinctrl-mtk-common.c |   21 ++++++++++-----------
 drivers/pinctrl/mediatek/pinctrl-mtk-common.h |    1 +
 2 files changed, 11 insertions(+), 11 deletions(-)

diff --git a/drivers/pinctrl/mediatek/pinctrl-mtk-common.c b/drivers/pinctrl/mediatek/pinctrl-mtk-common.c
index ad1ea16..4a52072 100644
--- a/drivers/pinctrl/mediatek/pinctrl-mtk-common.c
+++ b/drivers/pinctrl/mediatek/pinctrl-mtk-common.c
@@ -1202,12 +1202,6 @@ static int mtk_pctrl_build_state(struct platform_device *pdev)
 	return 0;
 }
 
-static struct pinctrl_desc mtk_pctrl_desc = {
-	.confops	= &mtk_pconf_ops,
-	.pctlops	= &mtk_pctrl_ops,
-	.pmxops		= &mtk_pmx_ops,
-};
-
 int mtk_pctrl_init(struct platform_device *pdev,
 		const struct mtk_pinctrl_devdata *data,
 		struct regmap *regmap)
@@ -1265,12 +1259,17 @@ int mtk_pctrl_init(struct platform_device *pdev,
 
 	for (i = 0; i < pctl->devdata->npins; i++)
 		pins[i] = pctl->devdata->pins[i].pin;
-	mtk_pctrl_desc.name = dev_name(&pdev->dev);
-	mtk_pctrl_desc.owner = THIS_MODULE;
-	mtk_pctrl_desc.pins = pins;
-	mtk_pctrl_desc.npins = pctl->devdata->npins;
+
+	pctl->pctl_desc.name = dev_name(&pdev->dev);
+	pctl->pctl_desc.owner = THIS_MODULE;
+	pctl->pctl_desc.pins = pins;
+	pctl->pctl_desc.npins = pctl->devdata->npins;
+	pctl->pctl_desc.confops = &mtk_pconf_ops;
+	pctl->pctl_desc.pctlops = &mtk_pctrl_ops;
+	pctl->pctl_desc.pmxops = &mtk_pmx_ops;
 	pctl->dev = &pdev->dev;
-	pctl->pctl_dev = pinctrl_register(&mtk_pctrl_desc, &pdev->dev, pctl);
+
+	pctl->pctl_dev = pinctrl_register(&pctl->pctl_desc, &pdev->dev, pctl);
 	if (IS_ERR(pctl->pctl_dev)) {
 		dev_err(&pdev->dev, "couldn't register pinctrl driver\n");
 		return PTR_ERR(pctl->pctl_dev);
diff --git a/drivers/pinctrl/mediatek/pinctrl-mtk-common.h b/drivers/pinctrl/mediatek/pinctrl-mtk-common.h
index 30213e5..c532c23 100644
--- a/drivers/pinctrl/mediatek/pinctrl-mtk-common.h
+++ b/drivers/pinctrl/mediatek/pinctrl-mtk-common.h
@@ -256,6 +256,7 @@ struct mtk_pinctrl_devdata {
 struct mtk_pinctrl {
 	struct regmap	*regmap1;
 	struct regmap	*regmap2;
+	struct pinctrl_desc pctl_desc;
 	struct device           *dev;
 	struct gpio_chip	*chip;
 	struct mtk_pinctrl_group	*groups;
-- 
1.7.9.5



From jon.nettleton at gmail.com  Thu Aug 20 21:49:20 2015
From: jon.nettleton at gmail.com (Jon Nettleton)
Date: Fri, 21 Aug 2015 06:49:20 +0200
Subject: RX packet loss on i.MX6Q running 4.2-rc7
In-Reply-To: <20150820223049.GA20710@pqgruber.com>
References: <20150820223049.GA20710@pqgruber.com>
Message-ID: <CALHpu37TYT8bL3BmaNhYCukiJQrMPMgmwXFToGH6Y7xRRrPJ-Q@mail.gmail.com>

On Fri, Aug 21, 2015 at 12:30 AM, Clemens Gruber
<clemens.gruber at pqgruber.com> wrote:
> Hi,
>
> I am experiencing massive RX packet loss on my i.MX6Q (Chip rev 1.3) on Linux
> 4.2-rc7 with a Marvell 88E1510 Gigabit Ethernet PHY connected over RGMII.
> I noticed it when doing an UDP benchmark with iperf3. When sending UDP packets
> from a Debian PC to the i.MX6 with a rate of 100 Mbit/s, 99% of the packets are
> lost. With a rate of 10 Mbit/s, we are still losing 93% of all packets. TCP RX
> does suffer from packet loss too, but still achieves about 211 Mbit/s.
> TX is not affected.
>
> Steps to reproduce:
> On the i.MX6: iperf3 -s
> On a desktop PC:  iperf3 -b 10M -u -c MX6IP
>
> The iperf3 results:
> [ ID] Interval           Transfer     Bandwidth       Jitter    Lost/Total
> [  4]   0.00-10.00  sec  11.8 MBytes  9.90 Mbits/sec  0.687 ms  1397/1497 (93%)
>
> During the 10 Mbit UDP test, the IEEE_rx_macerr counter increased to 5371.
> ifconfig eth0 shows:
>  RX packets:9216 errors:5248 dropped:170 overruns:5248 frame:5248
>  TX packets:83 errors:0 dropped:0 overruns:0 carrier:0
>  collisions:0
>
> Here are the TCP results with iperf3 -c MX6IP:
> [ ID] Interval           Transfer     Bandwidth       Retr
> [  4]   0.00-10.00  sec   252 MBytes   211 Mbits/sec  4343             sender
> [  4]   0.00-10.00  sec   251 MBytes   211 Mbits/sec                  receiver
>
> During the TCP test, IEEE_rx_macerr increased to 4059.
> ifconfig eth0 shows:
> RX packets:186368 errors:4206 dropped:50 overruns:4206 frame:4206
> TX packets:41861 errors:0 dropped:0 overruns:0 carrier:0
> collisions:0
>
> Freescale errata entry ERR004512 did mention a RX FIFO overrun. Is this related?
>
> Forcing pause frames via ethtool -A eth0 rx on tx on, does not improve it:
> Same amount of UDP packet loss with reduced TCP throughput of 190 Mbit/s.
> IEEE_rx_macerr increased up to 5232 during UDP 10Mbit and up to 4270 for TCP.
>
> I am already using the MX6QDL_PAD_GPIO_6__ENET_IRQ workaround, which solved the
> ping latency issues from ERR006687 but not the packet loss problem.
>
> I read through the mailing list archives and found a discussion between Russell
> King, Marek Vasut, Eric Nelson, Fugang Duan and others about a similar problem.
> I therefore added you and contributors to fec_main.c to the CC.
>
> One suggestion I found, was adding udelay(210); to fec_enet_rx():
> https://lkml.org/lkml/2014/8/22/88
> But this also did not reduce the packet loss. (I added it to the fec_enet_rx
> function just before return pkt_received; but I still got 93% packet loss)
>
> Does anyone have the equipment/setup to trace an i.MX6Q during UDP RX traffic
> from iperf3 to find the root cause of this packet loss problem?
>
> What else could we do to fix this?
>

This is a bug in iperf3's UDP tests.  Do the same test with iperf2 and
you will see expected performance.  I believe there is a bug open in
github about it.

-Jon


From varada at codeaurora.org  Thu Aug 20 21:59:18 2015
From: varada at codeaurora.org (Varadarajan Narayanan)
Date: Fri, 21 Aug 2015 10:29:18 +0530
Subject: [PATCH] ARM: Set proper TEXT_OFFSET for IPQ806x
In-Reply-To: <20150820195455.GT7557@n2100.arm.linux.org.uk>
References: <20150820121541.GA14664@codeaurora.org>
 <20150820130005.GS7557@n2100.arm.linux.org.uk>
 <20150820172010.GB10796@qualcomm.com>
 <20150820195455.GT7557@n2100.arm.linux.org.uk>
Message-ID: <20150821045918.GB26963@codeaurora.org>

On Thu, Aug 20, 2015 at 08:54:55PM +0100, Russell King - ARM Linux wrote:
> On Thu, Aug 20, 2015 at 12:20:10PM -0500, Andy Gross wrote:
> > On Thu, Aug 20, 2015 at 02:00:06PM +0100, Russell King - ARM Linux wrote:
> > > On Thu, Aug 20, 2015 at 05:45:41PM +0530, Varadarajan Narayanan wrote:
> > > > RAM starts at 0x40000000 for IPQ. The lower 21MB of RAM is used
> > > > for Shared Memory and the kernel can start from 0x41500000.
> > >
> > > Why do people keep creating crap like this?  Each time something like
> > > this is created, it means that you _need_ to have a special kernel for
> > > your platform and you can't be part of the single zImage.
> > >
> > > Please, rather than creating crap like this, find a better way.
> >
> > In the case of the IPQ, we don't use the zImage because the decompress
> > requires a larger jump than we can do on that platform.  Having this
> > change at least gets us back 2MB of memory.
>
> Your argument about "a larger jump" makes no sense what so ever.  The
> branches between the decompressor and the main kernel are all done
> using a mov, which can jump to any 32-bit address.
>
> Even if you load the compressed kernel image at 0x41500000, the
> decompressor will mask that with 0xf8000000, and decide that RAM
> starts at 0x40000000.  It will then want to place the decompressed
> kernel image at 0x40008000.  Nothing there has anything to do with
> jump ranges.

With the qcom_defconfig, the kernel gets loaded at
0x40008000. This region is reserved for NSS.

> The only restriction that the ARM has as far as jump ranges are
> concerned is the 'b' or 'bl' instruction, which in ARM mode is
> limited to +/- 32MB.  That doesn't apply here since we don't use
> that to jump between the decompressor and the decompressed kernel
> image.
>
> So...
>
> Why is it necessary to have this 21MB block of shared memory at
> the start of RAM?  Why can't it be reserved by other means higher
> up in system memory?

The NSS subsystem needs memory to be reserved at 0x40000000.
The Ubi32 cores (part of NSS) need low address memory close
to the Ubi32 address space to do short calls from what is
called Ubi32 On Chip Memory to DDR and back again.  Since
there isn't a way to circumvent this restriction had to
reserve at 0x40000000.

-Varada

> It's up to the submitter to justify why any change is required, and
> in this case, part of that justification is why the shared memory is
> placed at the start of RAM, and why you need to be different from
> almost everyone else, and why you need to be a special case.  The
> justification also must make sense.
>
> --
> FTTC broadband for 0.8mile line: currently at 10.5Mbps down 400kbps up
> according to speedtest.net.
>
> _______________________________________________
> linux-arm-kernel mailing list
> linux-arm-kernel at lists.infradead.org
> http://lists.infradead.org/mailman/listinfo/linux-arm-kernel


From axel.lin at ingics.com  Thu Aug 20 22:08:24 2015
From: axel.lin at ingics.com (Axel Lin)
Date: Fri, 21 Aug 2015 13:08:24 +0800
Subject: [PATCH v3] pinctrl: mediatek: Fix multiple registration issue.
In-Reply-To: <1440132404-27749-1-git-send-email-hongzhou.yang@mediatek.com>
References: <1440132404-27749-1-git-send-email-hongzhou.yang@mediatek.com>
Message-ID: <CAFRkauDR_XuMrihptQu1=Oq4nzOqcmne89LwsOHPzQrWCQQgMA@mail.gmail.com>

2015-08-21 12:46 GMT+08:00 Hongzhou Yang <hongzhou.yang at mediatek.com>:
> Since our common driver need support main chip and PMU
> at the same time, that means it will register two
> pinctrl device, and the pinctrl_desc structure should
> be used two times.
>
> But pinctrl_desc use global static definition, then
> the latest registered pinctrl device will overwrite
> the old one's, all members in pinctrl_desc will set to
> the new one's, such as name, pins and pins numbers, etc.
> This is a bug. Changing to use devm_kzalloc to fix it.
>
> Cc: stable at vger.kernel.org # v4.1+
> Signed-off-by: Hongzhou Yang <hongzhou.yang at mediatek.com>
> ---
>  Use dynamic allocation to fix multiple registration issue.

The code looks good to me but the commit log needs fix.
You don't use devm_kzalloc now.
Just embedded struct pinctrl_desc pctl_desc to struct mtk_pinctrl.

Reviewed-by: Axel Lin <axel.lin at ingics.com>


From vichy.kuo at gmail.com  Thu Aug 20 22:27:30 2015
From: vichy.kuo at gmail.com (vichy)
Date: Fri, 21 Aug 2015 13:27:30 +0800
Subject: is it possible to liimit the softirq re entrance times
In-Reply-To: <20150820200534.GU7557@n2100.arm.linux.org.uk>
References: <CAOVJa8FfHWGVf=ccXFCyTUD5YHrMAAeQ9Tkg1ipHA=J_CyVAHQ@mail.gmail.com>
 <20150820200534.GU7557@n2100.arm.linux.org.uk>
Message-ID: <CAOVJa8EPpncsR1ThfTKsczsc33QXqAxKtGVAfg-PD++6vwxsvg@mail.gmail.com>

hi Russel:

2015-08-21 4:05 GMT+08:00 Russell King - ARM Linux <linux at arm.linux.org.uk>:
> On Fri, Aug 21, 2015 at 01:09:23AM +0800, vichy wrote:
>> My question are:
>> 1. in __do_sofiq, there is a jiffies setting to make sure the whole
>> softirq will not took to long.
>> But in my case is there any many hard irq happen like below
>>
>>                         trace_softirq_entry(vec_nr);    ------a
>>                         h->action(h);
>>                         trace_softirq_exit(vec_nr);      ---------b
>>
>> from lttng, I see there 100 interrupt happen from entry to exit.
>
> Firstly, I don't trust the trace infrastructure all that much for
> performance measurements: it has a non-zero overhead (especially if
> you turn on stack tracing), and if you want to do these kinds of
> measurements, you first need to ascertain what that overhead is, so
> you can subtract the effect of having trace enabled from the
> observations.  It's quite possible that a number of those 100
> interrupts are happening in the trace code recording the softirq
> entry and exit events.
>
> Secondly, you seem to be saying that 100 interrupts happen in
> h->action().  You don't specify the frequency of those interrupts.
> You also don't mention (which is more important) how long h->action()
> takes to run.  You also don't say which softirq it is.
I pasted some part of trace I captured as below.

>
> From the sounds of it, whatever soft irq handler is running, it's the
> handler itself which is the cause of your problem, but not knowing any
> of the details in my second point above, it's impossible to tell.

I paste the log I got from trace
>You don't specify the frequency of those interrupts.
those are ramdomly happen because usb devices is receiving/sending data.
> You also don't mention (which is more important) how long h->action()
it is about 12.915016ms
> takes to run.  You also don't say which softirq it is.
the sofirq vec =1, from the kernel define, it should be TIMER_SOFTIRQ

Isn't there any upward bound for softirq interruptted by HW irq?

Sincerely appreciate your kind explaination,


enum
{
        HI_SOFTIRQ=0,
        TIMER_SOFTIRQ,
        NET_TX_SOFTIRQ,
        NET_RX_SOFTIRQ,
        BLOCK_SOFTIRQ,
        BLOCK_IOPOLL_SOFTIRQ,
        TASKLET_SOFTIRQ,
        SCHED_SOFTIRQ,
        HRTIMER_SOFTIRQ,
        RCU_SOFTIRQ,    /* Preferable RCU should always be the last softirq */

        NR_SOFTIRQS
};

43:08.755 688 556        bla_0        0        softirq_entry
vec=1        3        20
43:08.755 895 172        bla_0        0        irq_handler_entry
 irq=87, name=ehci_hcd:usb3        3        20
43:08.755 993 380        bla_0        0        mm_page_alloc
page=0xeb124c00, order=3, gfp_flags=16928, migratetype=0        3
  20
43:08.756 178 924        bla_0        0        irq_handler_exit
irq=87, ret=1        3        20
43:08.756 190 100        bla_0        0        irq_handler_entry
 irq=87, name=ehci_hcd:usb3        3        20
43:08.756 244 276        bla_0        0        irq_handler_exit
irq=87, ret=1        3        20
43:08.756 396 860        bla_0        0        irq_handler_entry
 irq=87, name=ehci_hcd:usb3        3        20
43:08.757 002 436        bla_0        0        irq_handler_entry
 irq=29, name=twd        3        20
43:08.757 040 244        bla_0        0        irq_handler_exit
irq=29, ret=1        3        20
43:08.757 046 268        bla_0        0        irq_handler_entry
 irq=87, name=ehci_hcd:usb3        3        20
43:08.757 785 772        bla_0        0        irq_handler_exit
irq=87, ret=1        3        20
43:08.757 800 220        bla_0        0        irq_handler_entry
 irq=87, name=ehci_hcd:usb3        3        20
43:08.758 586 644        bla_0        0        irq_handler_exit
irq=87, ret=1        3        20
43:08.758 598 196        bla_0        0        irq_handler_entry
 irq=87, name=ehci_hcd:usb3        3        20
43:08.759 040 900        bla_0        0        irq_handler_exit
irq=87, ret=1        3        20
43:08.759 113 724        bla_0        0        irq_handler_entry
 irq=87, name=ehci_hcd:usb3        3        20
43:08.759 480 276        bla_0        0        mm_page_alloc
page=0xeb11ff00, order=3, gfp_flags=16928, migratetype=0        3
  20
43:08.759 663 100        bla_0        0        irq_handler_exit
irq=87, ret=1        3        20
43:08.759 675 884        bla_0        0        irq_handler_entry
 irq=87, name=ehci_hcd:usb3        3        20
43:08.760 020 468        bla_0        0        irq_handler_exit
irq=87, ret=1        3        20
43:08.760 030 604        bla_0        0        irq_handler_entry
 irq=87, name=ehci_hcd:usb3        3        20
43:08.760 388 452        bla_0        0        irq_handler_exit
irq=87, ret=1        3        20
43:08.760 398 484        bla_0        0        irq_handler_entry
 irq=87, name=ehci_hcd:usb3        3        20
43:08.760 980 348        bla_0        0        irq_handler_exit
irq=87, ret=1        3        20
43:08.760 989 820        bla_0        0        irq_handler_entry
 irq=29, name=twd        3        20
43:08.761 029 324        bla_0        0        irq_handler_exit
irq=29, ret=1        3        20
43:08.761 035 908        bla_0        0        irq_handler_entry
 irq=87, name=ehci_hcd:usb3        3        20
43:08.761 753 780        bla_0        0        irq_handler_exit
irq=87, ret=1        3        20
43:08.761 767 956        bla_0        0        irq_handler_entry
 irq=87, name=ehci_hcd:usb3        3        20
43:08.762 125 924        bla_0        0        irq_handler_exit
irq=87, ret=1        3        20
43:08.762 135 964        bla_0        0        irq_handler_entry
 irq=87, name=ehci_hcd:usb3        3        20
43:08.762 190 300        bla_0        0        irq_handler_exit
irq=87, ret=1        3        20
43:08.762 276 580        bla_0        0        irq_handler_entry
 irq=87, name=ehci_hcd:usb3        3        20
43:08.762 733 724        bla_0        0        mm_page_alloc
page=0xeb12be00, order=3, gfp_flags=16928, migratetype=0        3
  20
43:08.762 943 404        bla_0        0        irq_handler_exit
irq=87, ret=1        3        20
43:08.762 963 852        bla_0        0        irq_handler_entry
 irq=87, name=ehci_hcd:usb3        3        20
43:08.763 678 020        bla_0        0        irq_handler_exit
irq=87, ret=1        3        20
43:08.763 689 796        bla_0        0        irq_handler_entry
 irq=87, name=ehci_hcd:usb3        3        20
43:08.764 390 884        bla_0        0        irq_handler_exit
irq=87, ret=1        3        20
43:08.764 402 372        bla_0        0        irq_handler_entry
 irq=29, name=twd        3        20
43:08.765 204 812        bla_0        0        irq_handler_exit
irq=29, ret=1        3        20
43:08.765 216 436        bla_0        0        irq_handler_entry
 irq=41, name=irq        3        20
43:08.765 242 924        bla_0        0        irq_handler_exit
irq=41, ret=1        3        20
43:08.765 264 092        bla_0        0        irq_handler_entry
 irq=53, name=irq        3        20
43:08.765 269 276        bla_0        0        irq_handler_exit
irq=53, ret=1        3        20
43:08.765 274 644        bla_0        0        irq_handler_entry
 irq=54, name=irq        3        20
43:08.765 290 572        bla_0        0        irq_handler_exit
irq=54, ret=1        3        20
43:08.765 298 316        bla_0        0        irq_handler_entry
 irq=55, name=irq        3        20
43:08.765 423 564        bla_0        0        irq_handler_exit
irq=55, ret=1        3        20
43:08.765 433 724        bla_0        0        irq_handler_entry
 irq=80, name=irq        3        20
43:08.765 450 188        bla_0        0        irq_handler_exit
irq=80, ret=1        3        20
43:08.765 456 628        bla_0        0        irq_handler_entry
 irq=87, name=ehci_hcd:usb3        3        20
43:08.765 711 252        bla_0        0        mm_page_alloc
page=0xeb123f40, order=1, gfp_flags=2118176, migratetype=0        3
    20
43:08.766 252 228        bla_0        0        irq_handler_exit
irq=87, ret=1        3        20
43:08.766 266 716        bla_0        0        irq_handler_entry
 irq=54, name=irq        3        20
43:08.766 282 220        bla_0        0        irq_handler_exit
irq=54, ret=1        3        20
43:08.766 288 460        bla_0        0        irq_handler_entry
 irq=87, name=ehci_hcd:usb3        3        20
43:08.766 550 108        bla_0        0        mm_page_alloc
page=0xeb12b600, order=3, gfp_flags=16928, migratetype=0        3
  20
43:08.767 185 100        bla_0        0        irq_handler_exit
irq=87, ret=1        3        20
43:08.767 203 156        bla_0        0        irq_handler_entry
 irq=87, name=ehci_hcd:usb3        3        20
43:08.767 949 260        bla_0        0        irq_handler_exit
irq=87, ret=1        3        20
43:08.767 960 020        bla_0        0        irq_handler_entry
 irq=87, name=ehci_hcd:usb3        3        20
43:08.768 395 340        bla_0        0        irq_handler_exit
irq=87, ret=1        3        20
43:08.768 496 332        bla_0        0        irq_handler_entry
 irq=29, name=twd        3        20
43:08.768 537 452        bla_0        0        irq_handler_exit
irq=29, ret=1        3        20
43:08.768 603 572        bla_0        0        softirq_exit
vec=1        3        20


From jh80.chung at samsung.com  Thu Aug 20 23:27:32 2015
From: jh80.chung at samsung.com (Jaehoon Chung)
Date: Fri, 21 Aug 2015 15:27:32 +0900
Subject: [RFC PATCH v6 1/9] mmc: dw_mmc: Add external dma interface support
In-Reply-To: <1440060233-26244-1-git-send-email-shawn.lin@rock-chips.com>
References: <1440060204-26203-1-git-send-email-shawn.lin@rock-chips.com>
 <1440060233-26244-1-git-send-email-shawn.lin@rock-chips.com>
Message-ID: <55D6C4D4.8010005@samsung.com>

Hi, Shawn.

Is this based on Ulf's repository?

On 08/20/2015 05:43 PM, Shawn Lin wrote:
> DesignWare MMC Controller can supports two types of DMA
> mode: external dma and internal dma. We get a RK312x platform
> integrated dw_mmc and ARM pl330 dma controller. This patch add
> edmac ops to support these platforms. I've tested it on RK31xx
> platform with edmac mode and RK3288 platform with idmac mode.
> 
> Signed-off-by: Shawn Lin <shawn.lin at rock-chips.com>
> 
> ---
> 
> Changes in v6:
> - add trans_mode condition for IDMAC initialization
>   suggested by Heiko
> - re-test my patch on rk3188 platform and update commit msg
> - update performance of pio vs edmac in cover letter
> 
> Changes in v5:
> - add the title of cover letter
> - fix typo of comment
> - add macro for reading HCON register
> - add "Acked-by: Krzysztof Kozlowski <k.kozlowski at samsung.com>" for exynos_defconfig patch
> - add "Acked-by: Vineet Gupta <vgupta at synopsys.com>" for axs10x_defconfig patch
> - add "Acked-by: Govindraj Raja <govindraj.raja at imgtec.com>" and
>   "Acked-by: Ralf Baechle <ralf at linux-mips.org>" for pistachio_defconfig patch
> - add "Acked-by: Joachim Eastwood <manabian at gmail.com>" for lpc18xx_defconfig patch
> - add "Acked-by: Wei Xu <xuwei5 at hisilicon.com>" for hisi_defconfig patch
> - rebase on "https://github.com/jh80chung/dw-mmc.git tags/dw-mmc-for-ulf-v4.2" for merging easily
> 
> Changes in v4:
> - remove "host->trans_mode" and use "host->use_dma" to indicate
>   transfer mode.
> - remove all bt-bindings' changes since we don't need new properities.
> - check transfer mode at runtime by reading HCON reg
> - spilt defconfig changes for each sub-architecture
> - fix the title of cover letter
> - reuse some code for reducing code size
> 
> Changes in v3:
> - choose transfer mode at runtime
> - remove all CONFIG_MMC_DW_IDMAC config option
> - add supports-idmac property for some platforms
> 
> Changes in v2:
> - Fix typo of dev_info msg
> - remove unused dmach from declaration of dw_mci_dma_slave
> 
>  drivers/mmc/host/Kconfig        |  11 +-
>  drivers/mmc/host/dw_mmc-pltfm.c |   2 +
>  drivers/mmc/host/dw_mmc.c       | 264 ++++++++++++++++++++++++++++++++--------
>  drivers/mmc/host/dw_mmc.h       |   5 +
>  include/linux/mmc/dw_mmc.h      |  27 +++-
>  5 files changed, 242 insertions(+), 67 deletions(-)
> 
> diff --git a/drivers/mmc/host/Kconfig b/drivers/mmc/host/Kconfig
> index 6a0f9c7..a86c0eb 100644
> --- a/drivers/mmc/host/Kconfig
> +++ b/drivers/mmc/host/Kconfig
> @@ -607,15 +607,7 @@ config MMC_DW
>  	help
>  	  This selects support for the Synopsys DesignWare Mobile Storage IP
>  	  block, this provides host support for SD and MMC interfaces, in both
> -	  PIO and external DMA modes.
> -
> -config MMC_DW_IDMAC
> -	bool "Internal DMAC interface"
> -	depends on MMC_DW
> -	help
> -	  This selects support for the internal DMAC block within the Synopsys
> -	  Designware Mobile Storage IP block. This disables the external DMA
> -	  interface.
> +	  PIO, internal DMA mode and external DMA modes.
>  
>  config MMC_DW_PLTFM
>  	tristate "Synopsys Designware MCI Support as platform device"
> @@ -644,7 +636,6 @@ config MMC_DW_K3
>  	tristate "K3 specific extensions for Synopsys DW Memory Card Interface"
>  	depends on MMC_DW
>  	select MMC_DW_PLTFM
> -	select MMC_DW_IDMAC
>  	help
>  	  This selects support for Hisilicon K3 SoC specific extensions to the
>  	  Synopsys DesignWare Memory Card Interface driver. Select this option
> diff --git a/drivers/mmc/host/dw_mmc-pltfm.c b/drivers/mmc/host/dw_mmc-pltfm.c
> index ec6dbcd..7e1d13b 100644
> --- a/drivers/mmc/host/dw_mmc-pltfm.c
> +++ b/drivers/mmc/host/dw_mmc-pltfm.c
> @@ -59,6 +59,8 @@ int dw_mci_pltfm_register(struct platform_device *pdev,
>  	host->pdata = pdev->dev.platform_data;
>  
>  	regs = platform_get_resource(pdev, IORESOURCE_MEM, 0);
> +	/* Get registers' physical base address */
> +	host->phy_regs = (void *)(regs->start);
>  	host->regs = devm_ioremap_resource(&pdev->dev, regs);
>  	if (IS_ERR(host->regs))
>  		return PTR_ERR(host->regs);

Is this board specific code? If so, separate the patch.

> diff --git a/drivers/mmc/host/dw_mmc.c b/drivers/mmc/host/dw_mmc.c
> index fcbf552..f943619 100644
> --- a/drivers/mmc/host/dw_mmc.c
> +++ b/drivers/mmc/host/dw_mmc.c
> @@ -56,7 +56,6 @@
>  #define DW_MCI_FREQ_MAX	200000000	/* unit: HZ */
>  #define DW_MCI_FREQ_MIN	400000		/* unit: HZ */
>  
> -#ifdef CONFIG_MMC_DW_IDMAC
>  #define IDMAC_INT_CLR		(SDMMC_IDMAC_INT_AI | SDMMC_IDMAC_INT_NI | \
>  				 SDMMC_IDMAC_INT_CES | SDMMC_IDMAC_INT_DU | \
>  				 SDMMC_IDMAC_INT_FBE | SDMMC_IDMAC_INT_RI | \
> @@ -102,7 +101,6 @@ struct idmac_desc {
>  
>  /* Each descriptor can transfer up to 4KB of data in chained mode */
>  #define DW_MCI_DESC_DATA_LENGTH	0x1000
> -#endif /* CONFIG_MMC_DW_IDMAC */
>  
>  static bool dw_mci_reset(struct dw_mci *host);
>  static bool dw_mci_ctrl_reset(struct dw_mci *host, u32 reset);
> @@ -407,7 +405,6 @@ static int dw_mci_get_dma_dir(struct mmc_data *data)
>  		return DMA_FROM_DEVICE;
>  }
>  
> -#ifdef CONFIG_MMC_DW_IDMAC
>  static void dw_mci_dma_cleanup(struct dw_mci *host)
>  {
>  	struct mmc_data *data = host->data;
> @@ -445,12 +442,21 @@ static void dw_mci_idmac_stop_dma(struct dw_mci *host)
>  	mci_writel(host, BMOD, temp);
>  }
>  
> -static void dw_mci_idmac_complete_dma(struct dw_mci *host)
> +static void dw_mci_dmac_complete_dma(void *arg)
>  {
> +	struct dw_mci *host = arg;
>  	struct mmc_data *data = host->data;
>  
>  	dev_vdbg(host->dev, "DMA complete\n");
>  
> +	if (host->use_dma == TRANS_MODE_EDMAC)
> +		if (data && (data->flags & MMC_DATA_READ))

Combine one condition.

> +			/* Invalidate cache after read */
> +			dma_sync_sg_for_cpu(mmc_dev(host->cur_slot->mmc),
> +					    data->sg,
> +					    data->sg_len,
> +					    DMA_FROM_DEVICE);
> +
>  	host->dma_ops->cleanup(host);
>  
>  	/*
> @@ -564,7 +570,7 @@ static void dw_mci_translate_sglist(struct dw_mci *host, struct mmc_data *data,
>  	wmb(); /* drain writebuffer */
>  }
>  
> -static void dw_mci_idmac_start_dma(struct dw_mci *host, unsigned int sg_len)
> +static int dw_mci_idmac_start_dma(struct dw_mci *host, unsigned int sg_len)
>  {
>  	u32 temp;
>  
> @@ -589,6 +595,8 @@ static void dw_mci_idmac_start_dma(struct dw_mci *host, unsigned int sg_len)
>  
>  	/* Start it running */
>  	mci_writel(host, PLDMND, 1);
> +
> +	return 0;
>  }
>  
>  static int dw_mci_idmac_init(struct dw_mci *host)
> @@ -669,10 +677,112 @@ static const struct dw_mci_dma_ops dw_mci_idmac_ops = {
>  	.init = dw_mci_idmac_init,
>  	.start = dw_mci_idmac_start_dma,
>  	.stop = dw_mci_idmac_stop_dma,
> -	.complete = dw_mci_idmac_complete_dma,
> +	.complete = dw_mci_dmac_complete_dma,
> +	.cleanup = dw_mci_dma_cleanup,
> +};
> +
> +static void dw_mci_edmac_stop_dma(struct dw_mci *host)
> +{
> +	dmaengine_terminate_all(host->dms->ch);
> +}
> +
> +static int dw_mci_edmac_start_dma(struct dw_mci *host,
> +					    unsigned int sg_len)
> +{
> +	struct dma_slave_config cfg;
> +	struct dma_async_tx_descriptor *desc = NULL;
> +	struct scatterlist *sgl = host->data->sg;
> +	const u32 mszs[] = {1, 4, 8, 16, 32, 64, 128, 256};
> +	u32 sg_elems = host->data->sg_len;
> +	u32 fifoth_val;
> +	u32 fifo_offset = host->fifo_reg - host->regs;
> +	int ret = 0;
> +
> +	/* Set external dma config: burst size, burst width */
> +	cfg.dst_addr = (dma_addr_t)(host->phy_regs + fifo_offset);

host->phy_regs is not assigned?

> +	cfg.src_addr = cfg.dst_addr;
> +	cfg.dst_addr_width = DMA_SLAVE_BUSWIDTH_4_BYTES;
> +	cfg.src_addr_width = DMA_SLAVE_BUSWIDTH_4_BYTES;
> +
> +	/* Match burst msize with external dma config */
> +	fifoth_val = mci_readl(host, FIFOTH);
> +	cfg.dst_maxburst = mszs[(fifoth_val >> 28) & 0x7];
> +	cfg.src_maxburst = cfg.dst_maxburst;
> +
> +	if (host->data->flags & MMC_DATA_WRITE)
> +		cfg.direction = DMA_MEM_TO_DEV;
> +	else /* MMC_DATA_READ */
> +		cfg.direction = DMA_DEV_TO_MEM;
> +
> +	ret = dmaengine_slave_config(host->dms->ch, &cfg);
> +	if (ret) {
> +		dev_err(host->dev, "Failed to config edmac.\n");
> +		return -EBUSY;
> +	}
> +
> +	desc = dmaengine_prep_slave_sg(host->dms->ch, sgl,
> +				       sg_len, cfg.direction,
> +				       DMA_PREP_INTERRUPT | DMA_CTRL_ACK);
> +	if (!desc) {
> +		dev_err(host->dev, "Can't prepare slave sg.\n");
> +		return -EBUSY;
> +	}
> +
> +	/* Set dw_mci_dmac_complete_dma as callback */
> +	desc->callback = dw_mci_dmac_complete_dma;
> +	desc->callback_param = (void *)host;
> +	dmaengine_submit(desc);
> +
> +	/* Flush cache before write */
> +	if (host->data->flags & MMC_DATA_WRITE)
> +		dma_sync_sg_for_device(mmc_dev(host->cur_slot->mmc), sgl,
> +				       sg_elems, DMA_TO_DEVICE);
> +
> +	dma_async_issue_pending(host->dms->ch);
> +
> +	return 0;
> +}
> +
> +static int dw_mci_edmac_init(struct dw_mci *host)
> +{
> +	/* Request external dma channel */
> +	host->dms = kzalloc(sizeof(struct dw_mci_dma_slave), GFP_KERNEL);
> +	if (!host->dms)
> +		return -ENOMEM;
> +
> +	host->dms->ch = dma_request_slave_channel(host->dev, "rx-tx");
> +	if (!host->dms->ch) {
> +		dev_err(host->dev,
> +			"Failed to get external DMA channel %d\n",
> +			host->dms->ch->chan_id);
> +		kfree(host->dms);
> +		host->dms = NULL;
> +		return -ENXIO;
> +	}
> +
> +	return 0;
> +}
> +
> +static void dw_mci_edmac_exit(struct dw_mci *host)
> +{
> +	if (host->dms) {
> +		if (host->dms->ch) {
> +			dma_release_channel(host->dms->ch);
> +			host->dms->ch = NULL;
> +		}
> +		kfree(host->dms);
> +		host->dms = NULL;
> +	}
> +}
> +
> +static const struct dw_mci_dma_ops dw_mci_edmac_ops = {
> +	.init = dw_mci_edmac_init,
> +	.exit = dw_mci_edmac_exit,
> +	.start = dw_mci_edmac_start_dma,
> +	.stop = dw_mci_edmac_stop_dma,
> +	.complete = dw_mci_dmac_complete_dma,
>  	.cleanup = dw_mci_dma_cleanup,
>  };
> -#endif /* CONFIG_MMC_DW_IDMAC */
>  
>  static int dw_mci_pre_dma_transfer(struct dw_mci *host,
>  				   struct mmc_data *data,
> @@ -752,7 +862,6 @@ static void dw_mci_post_req(struct mmc_host *mmc,
>  
>  static void dw_mci_adjust_fifoth(struct dw_mci *host, struct mmc_data *data)
>  {
> -#ifdef CONFIG_MMC_DW_IDMAC
>  	unsigned int blksz = data->blksz;
>  	const u32 mszs[] = {1, 4, 8, 16, 32, 64, 128, 256};
>  	u32 fifo_width = 1 << host->data_shift;
> @@ -760,6 +869,10 @@ static void dw_mci_adjust_fifoth(struct dw_mci *host, struct mmc_data *data)
>  	u32 msize = 0, rx_wmark = 1, tx_wmark, tx_wmark_invers;
>  	int idx = ARRAY_SIZE(mszs) - 1;
>  
> +	/* pio should ship this scenario */
> +	if (!host->use_dma)
> +		return;
> +
>  	tx_wmark = (host->fifo_depth) / 2;
>  	tx_wmark_invers = host->fifo_depth - tx_wmark;
>  
> @@ -788,7 +901,6 @@ static void dw_mci_adjust_fifoth(struct dw_mci *host, struct mmc_data *data)
>  done:
>  	fifoth_val = SDMMC_SET_FIFOTH(msize, rx_wmark, tx_wmark);
>  	mci_writel(host, FIFOTH, fifoth_val);
> -#endif
>  }
>  
>  static void dw_mci_ctrl_rd_thld(struct dw_mci *host, struct mmc_data *data)
> @@ -850,10 +962,12 @@ static int dw_mci_submit_data_dma(struct dw_mci *host, struct mmc_data *data)
>  
>  	host->using_dma = 1;
>  
> -	dev_vdbg(host->dev,
> -		 "sd sg_cpu: %#lx sg_dma: %#lx sg_len: %d\n",
> -		 (unsigned long)host->sg_cpu, (unsigned long)host->sg_dma,
> -		 sg_len);
> +	if (host->use_dma == TRANS_MODE_IDMAC)
> +		dev_vdbg(host->dev,
> +			 "sd sg_cpu: %#lx sg_dma: %#lx sg_len: %d\n",
> +			 (unsigned long)host->sg_cpu,
> +			 (unsigned long)host->sg_dma,
> +			 sg_len);
>  
>  	/*
>  	 * Decide the MSIZE and RX/TX Watermark.
> @@ -875,7 +989,11 @@ static int dw_mci_submit_data_dma(struct dw_mci *host, struct mmc_data *data)
>  	mci_writel(host, INTMASK, temp);
>  	spin_unlock_irqrestore(&host->irq_lock, irqflags);
>  
> -	host->dma_ops->start(host, sg_len);
> +	if (host->dma_ops->start(host, sg_len)) {
> +		/* We can't do DMA */
> +		dev_err(host->dev, "%s: failed to start DMA.\n", __func__);
> +		return -ENODEV;
> +	}
>  
>  	return 0;
>  }
> @@ -2343,15 +2461,17 @@ static irqreturn_t dw_mci_interrupt(int irq, void *dev_id)
>  
>  	}
>  
> -#ifdef CONFIG_MMC_DW_IDMAC
> -	/* Handle DMA interrupts */
> +	if (host->use_dma != TRANS_MODE_IDMAC)
> +		return IRQ_HANDLED;
> +
> +	/* Handle IDMA interrupts */
>  	if (host->dma_64bit_address == 1) {
>  		pending = mci_readl(host, IDSTS64);
>  		if (pending & (SDMMC_IDMAC_INT_TI | SDMMC_IDMAC_INT_RI)) {
>  			mci_writel(host, IDSTS64, SDMMC_IDMAC_INT_TI |
>  							SDMMC_IDMAC_INT_RI);
>  			mci_writel(host, IDSTS64, SDMMC_IDMAC_INT_NI);
> -			host->dma_ops->complete(host);
> +			host->dma_ops->complete((void *)host);
>  		}
>  	} else {
>  		pending = mci_readl(host, IDSTS);
> @@ -2359,10 +2479,9 @@ static irqreturn_t dw_mci_interrupt(int irq, void *dev_id)
>  			mci_writel(host, IDSTS, SDMMC_IDMAC_INT_TI |
>  							SDMMC_IDMAC_INT_RI);
>  			mci_writel(host, IDSTS, SDMMC_IDMAC_INT_NI);
> -			host->dma_ops->complete(host);
> +			host->dma_ops->complete((void *)host);
>  		}
>  	}
> -#endif
>  
>  	return IRQ_HANDLED;
>  }
> @@ -2471,13 +2590,21 @@ static int dw_mci_init_slot(struct dw_mci *host, unsigned int id)
>  		goto err_host_allocated;
>  
>  	/* Useful defaults if platform data is unset. */
> -	if (host->use_dma) {
> +	if (host->use_dma == TRANS_MODE_IDMAC) {
>  		mmc->max_segs = host->ring_size;
>  		mmc->max_blk_size = 65536;
>  		mmc->max_seg_size = 0x1000;
>  		mmc->max_req_size = mmc->max_seg_size * host->ring_size;
>  		mmc->max_blk_count = mmc->max_req_size / 512;
> +	} else if (host->use_dma == TRANS_MODE_EDMAC) {
> +			mmc->max_segs = 64;
> +			mmc->max_blk_size = 65536;
> +			mmc->max_blk_count = 65535;
> +			mmc->max_req_size =
> +					mmc->max_blk_size * mmc->max_blk_count;
> +			mmc->max_seg_size = mmc->max_req_size;

Fix the indention

>  	} else {
> +		/* TRANS_MODE_PIO */
>  		mmc->max_segs = 64;
>  		mmc->max_blk_size = 65536; /* BLKSIZ is 16 bits */
>  		mmc->max_blk_count = 512;
> @@ -2517,35 +2644,66 @@ static void dw_mci_cleanup_slot(struct dw_mci_slot *slot, unsigned int id)
>  static void dw_mci_init_dma(struct dw_mci *host)
>  {
>  	int addr_config;
> -	/* Check ADDR_CONFIG bit in HCON to find IDMAC address bus width */
> -	addr_config = (mci_readl(host, HCON) >> 27) & 0x01;
> -
> -	if (addr_config == 1) {
> -		/* host supports IDMAC in 64-bit address mode */
> -		host->dma_64bit_address = 1;
> -		dev_info(host->dev, "IDMAC supports 64-bit address mode.\n");
> -		if (!dma_set_mask(host->dev, DMA_BIT_MASK(64)))
> -			dma_set_coherent_mask(host->dev, DMA_BIT_MASK(64));
> -	} else {
> -		/* host supports IDMAC in 32-bit address mode */
> -		host->dma_64bit_address = 0;
> -		dev_info(host->dev, "IDMAC supports 32-bit address mode.\n");
> -	}
> +	int trans_mode;
> +	struct device *dev = host->dev;
> +	struct device_node *np = dev->of_node;
>  
> -	/* Alloc memory for sg translation */
> -	host->sg_cpu = dmam_alloc_coherent(host->dev, PAGE_SIZE,
> -					  &host->sg_dma, GFP_KERNEL);
> -	if (!host->sg_cpu) {
> -		dev_err(host->dev, "%s: could not alloc DMA memory\n",
> -			__func__);
> +	/* Check tansfer mode */
> +	trans_mode = SDMMC_GET_TRANS_MODE(mci_readl(host, HCON));
> +	if (trans_mode == 0) {
> +		trans_mode = TRANS_MODE_IDMAC;
> +	} else if (trans_mode == 1 || trans_mode == 2) {
> +		trans_mode = TRANS_MODE_EDMAC;
> +	} else {
> +		trans_mode = TRANS_MODE_PIO;

what are trans_mode "0, 1, 2"?
(00 - none) is NO-DMA interface, isn't? is it IDMAC mode?

>  		goto no_dma;
>  	}
>  
>  	/* Determine which DMA interface to use */
> -#ifdef CONFIG_MMC_DW_IDMAC
> -	host->dma_ops = &dw_mci_idmac_ops;
> -	dev_info(host->dev, "Using internal DMA controller.\n");
> -#endif
> +	if (trans_mode == TRANS_MODE_IDMAC) {
> +		/*
> +		* Check ADDR_CONFIG bit in HCON to find
> +		* IDMAC address bus width
> +		*/
> +		addr_config = SDMMC_GET_ADDR_CONFIG(mci_readl(host, HCON));
> +
> +		if (addr_config == 1) {
> +			/* host supports IDMAC in 64-bit address mode */
> +			host->dma_64bit_address = 1;
> +			dev_info(host->dev,
> +				 "IDMAC supports 64-bit address mode.\n");
> +			if (!dma_set_mask(host->dev, DMA_BIT_MASK(64)))
> +				dma_set_coherent_mask(host->dev,
> +						      DMA_BIT_MASK(64));
> +		} else {
> +			/* host supports IDMAC in 32-bit address mode */
> +			host->dma_64bit_address = 0;
> +			dev_info(host->dev,
> +				 "IDMAC supports 32-bit address mode.\n");
> +		}
> +
> +		/* Alloc memory for sg translation */
> +		host->sg_cpu = dmam_alloc_coherent(host->dev, PAGE_SIZE,
> +						   &host->sg_dma, GFP_KERNEL);
> +		if (!host->sg_cpu) {
> +			dev_err(host->dev,
> +				"%s: could not alloc DMA memory\n",
> +				__func__);
> +			goto no_dma;
> +		}
> +
> +		host->dma_ops = &dw_mci_idmac_ops;
> +		dev_info(host->dev, "Using internal DMA controller.\n");
> +	} else {
> +		/* TRANS_MODE_EDMAC: check dma bindings again */
> +		if ((of_property_count_strings(np, "dma-names") < 0) ||
> +		    (!of_find_property(np, "dmas", NULL))) {
> +			trans_mode = TRANS_MODE_PIO;
> +			goto no_dma;
> +		}
> +		host->dma_ops = &dw_mci_edmac_ops;
> +		dev_info(host->dev, "Using external DMA controller.\n");
> +	}
>  
>  	if (!host->dma_ops)
>  		goto no_dma;
> @@ -2562,12 +2720,12 @@ static void dw_mci_init_dma(struct dw_mci *host)
>  		goto no_dma;
>  	}
>  
> -	host->use_dma = 1;
> +	host->use_dma = trans_mode;

Also confuse, if trans_mode is assigned host->use_dma, can mode value be directly assigned to host->use_dma?

trans_mode = TRAMS_MODE_PIO;
host->use_dma = trans_mode;

-> host->use_dma = TRAMS_MODE_PIO;

Then trans_mode can be removed.

>  	return;
>  
>  no_dma:
>  	dev_info(host->dev, "Using PIO mode.\n");
> -	host->use_dma = 0;
> +	host->use_dma = trans_mode;
>  }
>  
>  static bool dw_mci_ctrl_reset(struct dw_mci *host, u32 reset)
> @@ -2650,10 +2808,9 @@ static bool dw_mci_reset(struct dw_mci *host)
>  		}
>  	}
>  
> -#if IS_ENABLED(CONFIG_MMC_DW_IDMAC)
> -	/* It is also recommended that we reset and reprogram idmac */
> -	dw_mci_idmac_reset(host);
> -#endif
> +	if (host->use_dma == TRANS_MODE_IDMAC)
> +		/* It is also recommended that we reset and reprogram idmac */
> +		dw_mci_idmac_reset(host);
>  
>  	ret = true;
>  
> @@ -2890,7 +3047,7 @@ int dw_mci_probe(struct dw_mci *host)
>  	 * Get the host data width - this assumes that HCON has been set with
>  	 * the correct values.
>  	 */
> -	i = (mci_readl(host, HCON) >> 7) & 0x7;
> +	i = SDMMC_GET_HDATA_WIDTH(mci_readl(host, HCON));

This is not related with supporting external dma interface.
Separate this.

>  	if (!i) {
>  		host->push_data = dw_mci_push_data16;
>  		host->pull_data = dw_mci_pull_data16;
> @@ -2972,7 +3129,7 @@ int dw_mci_probe(struct dw_mci *host)
>  	if (host->pdata->num_slots)
>  		host->num_slots = host->pdata->num_slots;
>  	else
> -		host->num_slots = ((mci_readl(host, HCON) >> 1) & 0x1F) + 1;
> +		host->num_slots = SDMMC_GET_SLOT_NUM(mci_readl(host, HCON));

Ditto. (with above.)

>  
>  	/*
>  	 * Enable interrupts for command done, data over, data empty,
> @@ -3067,6 +3224,9 @@ EXPORT_SYMBOL(dw_mci_remove);
>   */
>  int dw_mci_suspend(struct dw_mci *host)
>  {
> +	if (host->use_dma && host->dma_ops->exit)
> +		host->dma_ops->exit(host);
> +
>  	return 0;
>  }
>  EXPORT_SYMBOL(dw_mci_suspend);
> diff --git a/drivers/mmc/host/dw_mmc.h b/drivers/mmc/host/dw_mmc.h
> index 8ce4674..c453e94 100644
> --- a/drivers/mmc/host/dw_mmc.h
> +++ b/drivers/mmc/host/dw_mmc.h
> @@ -148,6 +148,11 @@
>  #define SDMMC_SET_FIFOTH(m, r, t)	(((m) & 0x7) << 28 | \
>  					 ((r) & 0xFFF) << 16 | \
>  					 ((t) & 0xFFF))
> +/* HCON register defines */
> +#define SDMMC_GET_SLOT_NUM(x)		((((x)>>1) & 0x1F) + 1)
> +#define SDMMC_GET_HDATA_WIDTH(x)	(((x)>>7) & 0x7)
> +#define SDMMC_GET_TRANS_MODE(x)		(((x)>>16) & 0x3)
> +#define SDMMC_GET_ADDR_CONFIG(x)	(((x)>>27) & 0x1)
>  /* Internal DMAC interrupt defines */
>  #define SDMMC_IDMAC_INT_AI		BIT(9)
>  #define SDMMC_IDMAC_INT_NI		BIT(8)
> diff --git a/include/linux/mmc/dw_mmc.h b/include/linux/mmc/dw_mmc.h
> index c846f42..6a2b83c 100644
> --- a/include/linux/mmc/dw_mmc.h
> +++ b/include/linux/mmc/dw_mmc.h
> @@ -16,6 +16,7 @@
>  
>  #include <linux/scatterlist.h>
>  #include <linux/mmc/core.h>
> +#include <linux/dmaengine.h>
>  
>  #define MAX_MCI_SLOTS	2
>  
> @@ -40,6 +41,17 @@ enum {
>  
>  struct mmc_data;
>  
> +enum {
> +	TRANS_MODE_PIO = 0,
> +	TRANS_MODE_IDMAC,
> +	TRANS_MODE_EDMAC
> +};
> +
> +struct dw_mci_dma_slave {
> +	struct dma_chan *ch;
> +	enum dma_transfer_direction direction;
> +};
> +
>  /**
>   * struct dw_mci - MMC controller state shared between all slots
>   * @lock: Spinlock protecting the queue and associated data.
> @@ -154,11 +166,16 @@ struct dw_mci {
>  	dma_addr_t		sg_dma;
>  	void			*sg_cpu;
>  	const struct dw_mci_dma_ops	*dma_ops;
> -#ifdef CONFIG_MMC_DW_IDMAC
> +	/* For idmac */
>  	unsigned int		ring_size;
> -#else
> +
> +	/* For edmac */
> +	struct dw_mci_dma_slave *dms;
> +	/* Registers's physical base address */
> +	void                    *phy_regs;
> +
>  	struct dw_mci_dma_data	*dma_data;
> -#endif
> +

On ulf's repository, this point should be conflicted.

Best Regards,
Jaehoon Chung

>  	u32			cmd_status;
>  	u32			data_status;
>  	u32			stop_cmdr;
> @@ -212,8 +229,8 @@ struct dw_mci {
>  struct dw_mci_dma_ops {
>  	/* DMA Ops */
>  	int (*init)(struct dw_mci *host);
> -	void (*start)(struct dw_mci *host, unsigned int sg_len);
> -	void (*complete)(struct dw_mci *host);
> +	int (*start)(struct dw_mci *host, unsigned int sg_len);
> +	void (*complete)(void *host);
>  	void (*stop)(struct dw_mci *host);
>  	void (*cleanup)(struct dw_mci *host);
>  	void (*exit)(struct dw_mci *host);
> 



From shawn.lin at rock-chips.com  Thu Aug 20 23:30:21 2015
From: shawn.lin at rock-chips.com (Shawn Lin)
Date: Fri, 21 Aug 2015 14:30:21 +0800
Subject: [RFC PATCH v6 1/9] mmc: dw_mmc: Add external dma interface support
In-Reply-To: <55D6C4D4.8010005@samsung.com>
References: <1440060204-26203-1-git-send-email-shawn.lin@rock-chips.com>
 <1440060233-26244-1-git-send-email-shawn.lin@rock-chips.com>
 <55D6C4D4.8010005@samsung.com>
Message-ID: <55D6C57D.4070402@rock-chips.com>

On 2015/8/21 14:27, Jaehoon Chung wrote:
> Hi, Shawn.
>
> Is this based on Ulf's repository?


no, it's based on "https://github.com/jh80chung/dw-mmc.git 
tags/dw-mmc-for-ulf-v4.2" ??

>
> On 08/20/2015 05:43 PM, Shawn Lin wrote:
>> DesignWare MMC Controller can supports two types of DMA
>> mode: external dma and internal dma. We get a RK312x platform
>> integrated dw_mmc and ARM pl330 dma controller. This patch add
>> edmac ops to support these platforms. I've tested it on RK31xx
>> platform with edmac mode and RK3288 platform with idmac mode.
>>
>> Signed-off-by: Shawn Lin <shawn.lin at rock-chips.com>
>>
>> ---
>>
>> Changes in v6:
>> - add trans_mode condition for IDMAC initialization
>>    suggested by Heiko
>> - re-test my patch on rk3188 platform and update commit msg
>> - update performance of pio vs edmac in cover letter
>>
>> Changes in v5:
>> - add the title of cover letter
>> - fix typo of comment
>> - add macro for reading HCON register
>> - add "Acked-by: Krzysztof Kozlowski <k.kozlowski at samsung.com>" for exynos_defconfig patch
>> - add "Acked-by: Vineet Gupta <vgupta at synopsys.com>" for axs10x_defconfig patch
>> - add "Acked-by: Govindraj Raja <govindraj.raja at imgtec.com>" and
>>    "Acked-by: Ralf Baechle <ralf at linux-mips.org>" for pistachio_defconfig patch
>> - add "Acked-by: Joachim Eastwood <manabian at gmail.com>" for lpc18xx_defconfig patch
>> - add "Acked-by: Wei Xu <xuwei5 at hisilicon.com>" for hisi_defconfig patch
>> - rebase on "https://github.com/jh80chung/dw-mmc.git tags/dw-mmc-for-ulf-v4.2" for merging easily
>>
>> Changes in v4:
>> - remove "host->trans_mode" and use "host->use_dma" to indicate
>>    transfer mode.
>> - remove all bt-bindings' changes since we don't need new properities.
>> - check transfer mode at runtime by reading HCON reg
>> - spilt defconfig changes for each sub-architecture
>> - fix the title of cover letter
>> - reuse some code for reducing code size
>>
>> Changes in v3:
>> - choose transfer mode at runtime
>> - remove all CONFIG_MMC_DW_IDMAC config option
>> - add supports-idmac property for some platforms
>>
>> Changes in v2:
>> - Fix typo of dev_info msg
>> - remove unused dmach from declaration of dw_mci_dma_slave
>>
>>   drivers/mmc/host/Kconfig        |  11 +-
>>   drivers/mmc/host/dw_mmc-pltfm.c |   2 +
>>   drivers/mmc/host/dw_mmc.c       | 264 ++++++++++++++++++++++++++++++++--------
>>   drivers/mmc/host/dw_mmc.h       |   5 +
>>   include/linux/mmc/dw_mmc.h      |  27 +++-
>>   5 files changed, 242 insertions(+), 67 deletions(-)
>>
>> diff --git a/drivers/mmc/host/Kconfig b/drivers/mmc/host/Kconfig
>> index 6a0f9c7..a86c0eb 100644
>> --- a/drivers/mmc/host/Kconfig
>> +++ b/drivers/mmc/host/Kconfig
>> @@ -607,15 +607,7 @@ config MMC_DW
>>   	help
>>   	  This selects support for the Synopsys DesignWare Mobile Storage IP
>>   	  block, this provides host support for SD and MMC interfaces, in both
>> -	  PIO and external DMA modes.
>> -
>> -config MMC_DW_IDMAC
>> -	bool "Internal DMAC interface"
>> -	depends on MMC_DW
>> -	help
>> -	  This selects support for the internal DMAC block within the Synopsys
>> -	  Designware Mobile Storage IP block. This disables the external DMA
>> -	  interface.
>> +	  PIO, internal DMA mode and external DMA modes.
>>
>>   config MMC_DW_PLTFM
>>   	tristate "Synopsys Designware MCI Support as platform device"
>> @@ -644,7 +636,6 @@ config MMC_DW_K3
>>   	tristate "K3 specific extensions for Synopsys DW Memory Card Interface"
>>   	depends on MMC_DW
>>   	select MMC_DW_PLTFM
>> -	select MMC_DW_IDMAC
>>   	help
>>   	  This selects support for Hisilicon K3 SoC specific extensions to the
>>   	  Synopsys DesignWare Memory Card Interface driver. Select this option
>> diff --git a/drivers/mmc/host/dw_mmc-pltfm.c b/drivers/mmc/host/dw_mmc-pltfm.c
>> index ec6dbcd..7e1d13b 100644
>> --- a/drivers/mmc/host/dw_mmc-pltfm.c
>> +++ b/drivers/mmc/host/dw_mmc-pltfm.c
>> @@ -59,6 +59,8 @@ int dw_mci_pltfm_register(struct platform_device *pdev,
>>   	host->pdata = pdev->dev.platform_data;
>>
>>   	regs = platform_get_resource(pdev, IORESOURCE_MEM, 0);
>> +	/* Get registers' physical base address */
>> +	host->phy_regs = (void *)(regs->start);
>>   	host->regs = devm_ioremap_resource(&pdev->dev, regs);
>>   	if (IS_ERR(host->regs))
>>   		return PTR_ERR(host->regs);
>
> Is this board specific code? If so, separate the patch.
>
>> diff --git a/drivers/mmc/host/dw_mmc.c b/drivers/mmc/host/dw_mmc.c
>> index fcbf552..f943619 100644
>> --- a/drivers/mmc/host/dw_mmc.c
>> +++ b/drivers/mmc/host/dw_mmc.c
>> @@ -56,7 +56,6 @@
>>   #define DW_MCI_FREQ_MAX	200000000	/* unit: HZ */
>>   #define DW_MCI_FREQ_MIN	400000		/* unit: HZ */
>>
>> -#ifdef CONFIG_MMC_DW_IDMAC
>>   #define IDMAC_INT_CLR		(SDMMC_IDMAC_INT_AI | SDMMC_IDMAC_INT_NI | \
>>   				 SDMMC_IDMAC_INT_CES | SDMMC_IDMAC_INT_DU | \
>>   				 SDMMC_IDMAC_INT_FBE | SDMMC_IDMAC_INT_RI | \
>> @@ -102,7 +101,6 @@ struct idmac_desc {
>>
>>   /* Each descriptor can transfer up to 4KB of data in chained mode */
>>   #define DW_MCI_DESC_DATA_LENGTH	0x1000
>> -#endif /* CONFIG_MMC_DW_IDMAC */
>>
>>   static bool dw_mci_reset(struct dw_mci *host);
>>   static bool dw_mci_ctrl_reset(struct dw_mci *host, u32 reset);
>> @@ -407,7 +405,6 @@ static int dw_mci_get_dma_dir(struct mmc_data *data)
>>   		return DMA_FROM_DEVICE;
>>   }
>>
>> -#ifdef CONFIG_MMC_DW_IDMAC
>>   static void dw_mci_dma_cleanup(struct dw_mci *host)
>>   {
>>   	struct mmc_data *data = host->data;
>> @@ -445,12 +442,21 @@ static void dw_mci_idmac_stop_dma(struct dw_mci *host)
>>   	mci_writel(host, BMOD, temp);
>>   }
>>
>> -static void dw_mci_idmac_complete_dma(struct dw_mci *host)
>> +static void dw_mci_dmac_complete_dma(void *arg)
>>   {
>> +	struct dw_mci *host = arg;
>>   	struct mmc_data *data = host->data;
>>
>>   	dev_vdbg(host->dev, "DMA complete\n");
>>
>> +	if (host->use_dma == TRANS_MODE_EDMAC)
>> +		if (data && (data->flags & MMC_DATA_READ))
>
> Combine one condition.
>
>> +			/* Invalidate cache after read */
>> +			dma_sync_sg_for_cpu(mmc_dev(host->cur_slot->mmc),
>> +					    data->sg,
>> +					    data->sg_len,
>> +					    DMA_FROM_DEVICE);
>> +
>>   	host->dma_ops->cleanup(host);
>>
>>   	/*
>> @@ -564,7 +570,7 @@ static void dw_mci_translate_sglist(struct dw_mci *host, struct mmc_data *data,
>>   	wmb(); /* drain writebuffer */
>>   }
>>
>> -static void dw_mci_idmac_start_dma(struct dw_mci *host, unsigned int sg_len)
>> +static int dw_mci_idmac_start_dma(struct dw_mci *host, unsigned int sg_len)
>>   {
>>   	u32 temp;
>>
>> @@ -589,6 +595,8 @@ static void dw_mci_idmac_start_dma(struct dw_mci *host, unsigned int sg_len)
>>
>>   	/* Start it running */
>>   	mci_writel(host, PLDMND, 1);
>> +
>> +	return 0;
>>   }
>>
>>   static int dw_mci_idmac_init(struct dw_mci *host)
>> @@ -669,10 +677,112 @@ static const struct dw_mci_dma_ops dw_mci_idmac_ops = {
>>   	.init = dw_mci_idmac_init,
>>   	.start = dw_mci_idmac_start_dma,
>>   	.stop = dw_mci_idmac_stop_dma,
>> -	.complete = dw_mci_idmac_complete_dma,
>> +	.complete = dw_mci_dmac_complete_dma,
>> +	.cleanup = dw_mci_dma_cleanup,
>> +};
>> +
>> +static void dw_mci_edmac_stop_dma(struct dw_mci *host)
>> +{
>> +	dmaengine_terminate_all(host->dms->ch);
>> +}
>> +
>> +static int dw_mci_edmac_start_dma(struct dw_mci *host,
>> +					    unsigned int sg_len)
>> +{
>> +	struct dma_slave_config cfg;
>> +	struct dma_async_tx_descriptor *desc = NULL;
>> +	struct scatterlist *sgl = host->data->sg;
>> +	const u32 mszs[] = {1, 4, 8, 16, 32, 64, 128, 256};
>> +	u32 sg_elems = host->data->sg_len;
>> +	u32 fifoth_val;
>> +	u32 fifo_offset = host->fifo_reg - host->regs;
>> +	int ret = 0;
>> +
>> +	/* Set external dma config: burst size, burst width */
>> +	cfg.dst_addr = (dma_addr_t)(host->phy_regs + fifo_offset);
>
> host->phy_regs is not assigned?
>
>> +	cfg.src_addr = cfg.dst_addr;
>> +	cfg.dst_addr_width = DMA_SLAVE_BUSWIDTH_4_BYTES;
>> +	cfg.src_addr_width = DMA_SLAVE_BUSWIDTH_4_BYTES;
>> +
>> +	/* Match burst msize with external dma config */
>> +	fifoth_val = mci_readl(host, FIFOTH);
>> +	cfg.dst_maxburst = mszs[(fifoth_val >> 28) & 0x7];
>> +	cfg.src_maxburst = cfg.dst_maxburst;
>> +
>> +	if (host->data->flags & MMC_DATA_WRITE)
>> +		cfg.direction = DMA_MEM_TO_DEV;
>> +	else /* MMC_DATA_READ */
>> +		cfg.direction = DMA_DEV_TO_MEM;
>> +
>> +	ret = dmaengine_slave_config(host->dms->ch, &cfg);
>> +	if (ret) {
>> +		dev_err(host->dev, "Failed to config edmac.\n");
>> +		return -EBUSY;
>> +	}
>> +
>> +	desc = dmaengine_prep_slave_sg(host->dms->ch, sgl,
>> +				       sg_len, cfg.direction,
>> +				       DMA_PREP_INTERRUPT | DMA_CTRL_ACK);
>> +	if (!desc) {
>> +		dev_err(host->dev, "Can't prepare slave sg.\n");
>> +		return -EBUSY;
>> +	}
>> +
>> +	/* Set dw_mci_dmac_complete_dma as callback */
>> +	desc->callback = dw_mci_dmac_complete_dma;
>> +	desc->callback_param = (void *)host;
>> +	dmaengine_submit(desc);
>> +
>> +	/* Flush cache before write */
>> +	if (host->data->flags & MMC_DATA_WRITE)
>> +		dma_sync_sg_for_device(mmc_dev(host->cur_slot->mmc), sgl,
>> +				       sg_elems, DMA_TO_DEVICE);
>> +
>> +	dma_async_issue_pending(host->dms->ch);
>> +
>> +	return 0;
>> +}
>> +
>> +static int dw_mci_edmac_init(struct dw_mci *host)
>> +{
>> +	/* Request external dma channel */
>> +	host->dms = kzalloc(sizeof(struct dw_mci_dma_slave), GFP_KERNEL);
>> +	if (!host->dms)
>> +		return -ENOMEM;
>> +
>> +	host->dms->ch = dma_request_slave_channel(host->dev, "rx-tx");
>> +	if (!host->dms->ch) {
>> +		dev_err(host->dev,
>> +			"Failed to get external DMA channel %d\n",
>> +			host->dms->ch->chan_id);
>> +		kfree(host->dms);
>> +		host->dms = NULL;
>> +		return -ENXIO;
>> +	}
>> +
>> +	return 0;
>> +}
>> +
>> +static void dw_mci_edmac_exit(struct dw_mci *host)
>> +{
>> +	if (host->dms) {
>> +		if (host->dms->ch) {
>> +			dma_release_channel(host->dms->ch);
>> +			host->dms->ch = NULL;
>> +		}
>> +		kfree(host->dms);
>> +		host->dms = NULL;
>> +	}
>> +}
>> +
>> +static const struct dw_mci_dma_ops dw_mci_edmac_ops = {
>> +	.init = dw_mci_edmac_init,
>> +	.exit = dw_mci_edmac_exit,
>> +	.start = dw_mci_edmac_start_dma,
>> +	.stop = dw_mci_edmac_stop_dma,
>> +	.complete = dw_mci_dmac_complete_dma,
>>   	.cleanup = dw_mci_dma_cleanup,
>>   };
>> -#endif /* CONFIG_MMC_DW_IDMAC */
>>
>>   static int dw_mci_pre_dma_transfer(struct dw_mci *host,
>>   				   struct mmc_data *data,
>> @@ -752,7 +862,6 @@ static void dw_mci_post_req(struct mmc_host *mmc,
>>
>>   static void dw_mci_adjust_fifoth(struct dw_mci *host, struct mmc_data *data)
>>   {
>> -#ifdef CONFIG_MMC_DW_IDMAC
>>   	unsigned int blksz = data->blksz;
>>   	const u32 mszs[] = {1, 4, 8, 16, 32, 64, 128, 256};
>>   	u32 fifo_width = 1 << host->data_shift;
>> @@ -760,6 +869,10 @@ static void dw_mci_adjust_fifoth(struct dw_mci *host, struct mmc_data *data)
>>   	u32 msize = 0, rx_wmark = 1, tx_wmark, tx_wmark_invers;
>>   	int idx = ARRAY_SIZE(mszs) - 1;
>>
>> +	/* pio should ship this scenario */
>> +	if (!host->use_dma)
>> +		return;
>> +
>>   	tx_wmark = (host->fifo_depth) / 2;
>>   	tx_wmark_invers = host->fifo_depth - tx_wmark;
>>
>> @@ -788,7 +901,6 @@ static void dw_mci_adjust_fifoth(struct dw_mci *host, struct mmc_data *data)
>>   done:
>>   	fifoth_val = SDMMC_SET_FIFOTH(msize, rx_wmark, tx_wmark);
>>   	mci_writel(host, FIFOTH, fifoth_val);
>> -#endif
>>   }
>>
>>   static void dw_mci_ctrl_rd_thld(struct dw_mci *host, struct mmc_data *data)
>> @@ -850,10 +962,12 @@ static int dw_mci_submit_data_dma(struct dw_mci *host, struct mmc_data *data)
>>
>>   	host->using_dma = 1;
>>
>> -	dev_vdbg(host->dev,
>> -		 "sd sg_cpu: %#lx sg_dma: %#lx sg_len: %d\n",
>> -		 (unsigned long)host->sg_cpu, (unsigned long)host->sg_dma,
>> -		 sg_len);
>> +	if (host->use_dma == TRANS_MODE_IDMAC)
>> +		dev_vdbg(host->dev,
>> +			 "sd sg_cpu: %#lx sg_dma: %#lx sg_len: %d\n",
>> +			 (unsigned long)host->sg_cpu,
>> +			 (unsigned long)host->sg_dma,
>> +			 sg_len);
>>
>>   	/*
>>   	 * Decide the MSIZE and RX/TX Watermark.
>> @@ -875,7 +989,11 @@ static int dw_mci_submit_data_dma(struct dw_mci *host, struct mmc_data *data)
>>   	mci_writel(host, INTMASK, temp);
>>   	spin_unlock_irqrestore(&host->irq_lock, irqflags);
>>
>> -	host->dma_ops->start(host, sg_len);
>> +	if (host->dma_ops->start(host, sg_len)) {
>> +		/* We can't do DMA */
>> +		dev_err(host->dev, "%s: failed to start DMA.\n", __func__);
>> +		return -ENODEV;
>> +	}
>>
>>   	return 0;
>>   }
>> @@ -2343,15 +2461,17 @@ static irqreturn_t dw_mci_interrupt(int irq, void *dev_id)
>>
>>   	}
>>
>> -#ifdef CONFIG_MMC_DW_IDMAC
>> -	/* Handle DMA interrupts */
>> +	if (host->use_dma != TRANS_MODE_IDMAC)
>> +		return IRQ_HANDLED;
>> +
>> +	/* Handle IDMA interrupts */
>>   	if (host->dma_64bit_address == 1) {
>>   		pending = mci_readl(host, IDSTS64);
>>   		if (pending & (SDMMC_IDMAC_INT_TI | SDMMC_IDMAC_INT_RI)) {
>>   			mci_writel(host, IDSTS64, SDMMC_IDMAC_INT_TI |
>>   							SDMMC_IDMAC_INT_RI);
>>   			mci_writel(host, IDSTS64, SDMMC_IDMAC_INT_NI);
>> -			host->dma_ops->complete(host);
>> +			host->dma_ops->complete((void *)host);
>>   		}
>>   	} else {
>>   		pending = mci_readl(host, IDSTS);
>> @@ -2359,10 +2479,9 @@ static irqreturn_t dw_mci_interrupt(int irq, void *dev_id)
>>   			mci_writel(host, IDSTS, SDMMC_IDMAC_INT_TI |
>>   							SDMMC_IDMAC_INT_RI);
>>   			mci_writel(host, IDSTS, SDMMC_IDMAC_INT_NI);
>> -			host->dma_ops->complete(host);
>> +			host->dma_ops->complete((void *)host);
>>   		}
>>   	}
>> -#endif
>>
>>   	return IRQ_HANDLED;
>>   }
>> @@ -2471,13 +2590,21 @@ static int dw_mci_init_slot(struct dw_mci *host, unsigned int id)
>>   		goto err_host_allocated;
>>
>>   	/* Useful defaults if platform data is unset. */
>> -	if (host->use_dma) {
>> +	if (host->use_dma == TRANS_MODE_IDMAC) {
>>   		mmc->max_segs = host->ring_size;
>>   		mmc->max_blk_size = 65536;
>>   		mmc->max_seg_size = 0x1000;
>>   		mmc->max_req_size = mmc->max_seg_size * host->ring_size;
>>   		mmc->max_blk_count = mmc->max_req_size / 512;
>> +	} else if (host->use_dma == TRANS_MODE_EDMAC) {
>> +			mmc->max_segs = 64;
>> +			mmc->max_blk_size = 65536;
>> +			mmc->max_blk_count = 65535;
>> +			mmc->max_req_size =
>> +					mmc->max_blk_size * mmc->max_blk_count;
>> +			mmc->max_seg_size = mmc->max_req_size;
>
> Fix the indention
>
>>   	} else {
>> +		/* TRANS_MODE_PIO */
>>   		mmc->max_segs = 64;
>>   		mmc->max_blk_size = 65536; /* BLKSIZ is 16 bits */
>>   		mmc->max_blk_count = 512;
>> @@ -2517,35 +2644,66 @@ static void dw_mci_cleanup_slot(struct dw_mci_slot *slot, unsigned int id)
>>   static void dw_mci_init_dma(struct dw_mci *host)
>>   {
>>   	int addr_config;
>> -	/* Check ADDR_CONFIG bit in HCON to find IDMAC address bus width */
>> -	addr_config = (mci_readl(host, HCON) >> 27) & 0x01;
>> -
>> -	if (addr_config == 1) {
>> -		/* host supports IDMAC in 64-bit address mode */
>> -		host->dma_64bit_address = 1;
>> -		dev_info(host->dev, "IDMAC supports 64-bit address mode.\n");
>> -		if (!dma_set_mask(host->dev, DMA_BIT_MASK(64)))
>> -			dma_set_coherent_mask(host->dev, DMA_BIT_MASK(64));
>> -	} else {
>> -		/* host supports IDMAC in 32-bit address mode */
>> -		host->dma_64bit_address = 0;
>> -		dev_info(host->dev, "IDMAC supports 32-bit address mode.\n");
>> -	}
>> +	int trans_mode;
>> +	struct device *dev = host->dev;
>> +	struct device_node *np = dev->of_node;
>>
>> -	/* Alloc memory for sg translation */
>> -	host->sg_cpu = dmam_alloc_coherent(host->dev, PAGE_SIZE,
>> -					  &host->sg_dma, GFP_KERNEL);
>> -	if (!host->sg_cpu) {
>> -		dev_err(host->dev, "%s: could not alloc DMA memory\n",
>> -			__func__);
>> +	/* Check tansfer mode */
>> +	trans_mode = SDMMC_GET_TRANS_MODE(mci_readl(host, HCON));
>> +	if (trans_mode == 0) {
>> +		trans_mode = TRANS_MODE_IDMAC;
>> +	} else if (trans_mode == 1 || trans_mode == 2) {
>> +		trans_mode = TRANS_MODE_EDMAC;
>> +	} else {
>> +		trans_mode = TRANS_MODE_PIO;
>
> what are trans_mode "0, 1, 2"?
> (00 - none) is NO-DMA interface, isn't? is it IDMAC mode?
>
>>   		goto no_dma;
>>   	}
>>
>>   	/* Determine which DMA interface to use */
>> -#ifdef CONFIG_MMC_DW_IDMAC
>> -	host->dma_ops = &dw_mci_idmac_ops;
>> -	dev_info(host->dev, "Using internal DMA controller.\n");
>> -#endif
>> +	if (trans_mode == TRANS_MODE_IDMAC) {
>> +		/*
>> +		* Check ADDR_CONFIG bit in HCON to find
>> +		* IDMAC address bus width
>> +		*/
>> +		addr_config = SDMMC_GET_ADDR_CONFIG(mci_readl(host, HCON));
>> +
>> +		if (addr_config == 1) {
>> +			/* host supports IDMAC in 64-bit address mode */
>> +			host->dma_64bit_address = 1;
>> +			dev_info(host->dev,
>> +				 "IDMAC supports 64-bit address mode.\n");
>> +			if (!dma_set_mask(host->dev, DMA_BIT_MASK(64)))
>> +				dma_set_coherent_mask(host->dev,
>> +						      DMA_BIT_MASK(64));
>> +		} else {
>> +			/* host supports IDMAC in 32-bit address mode */
>> +			host->dma_64bit_address = 0;
>> +			dev_info(host->dev,
>> +				 "IDMAC supports 32-bit address mode.\n");
>> +		}
>> +
>> +		/* Alloc memory for sg translation */
>> +		host->sg_cpu = dmam_alloc_coherent(host->dev, PAGE_SIZE,
>> +						   &host->sg_dma, GFP_KERNEL);
>> +		if (!host->sg_cpu) {
>> +			dev_err(host->dev,
>> +				"%s: could not alloc DMA memory\n",
>> +				__func__);
>> +			goto no_dma;
>> +		}
>> +
>> +		host->dma_ops = &dw_mci_idmac_ops;
>> +		dev_info(host->dev, "Using internal DMA controller.\n");
>> +	} else {
>> +		/* TRANS_MODE_EDMAC: check dma bindings again */
>> +		if ((of_property_count_strings(np, "dma-names") < 0) ||
>> +		    (!of_find_property(np, "dmas", NULL))) {
>> +			trans_mode = TRANS_MODE_PIO;
>> +			goto no_dma;
>> +		}
>> +		host->dma_ops = &dw_mci_edmac_ops;
>> +		dev_info(host->dev, "Using external DMA controller.\n");
>> +	}
>>
>>   	if (!host->dma_ops)
>>   		goto no_dma;
>> @@ -2562,12 +2720,12 @@ static void dw_mci_init_dma(struct dw_mci *host)
>>   		goto no_dma;
>>   	}
>>
>> -	host->use_dma = 1;
>> +	host->use_dma = trans_mode;
>
> Also confuse, if trans_mode is assigned host->use_dma, can mode value be directly assigned to host->use_dma?
>
> trans_mode = TRAMS_MODE_PIO;
> host->use_dma = trans_mode;
>
> -> host->use_dma = TRAMS_MODE_PIO;
>
> Then trans_mode can be removed.
>
>>   	return;
>>
>>   no_dma:
>>   	dev_info(host->dev, "Using PIO mode.\n");
>> -	host->use_dma = 0;
>> +	host->use_dma = trans_mode;
>>   }
>>
>>   static bool dw_mci_ctrl_reset(struct dw_mci *host, u32 reset)
>> @@ -2650,10 +2808,9 @@ static bool dw_mci_reset(struct dw_mci *host)
>>   		}
>>   	}
>>
>> -#if IS_ENABLED(CONFIG_MMC_DW_IDMAC)
>> -	/* It is also recommended that we reset and reprogram idmac */
>> -	dw_mci_idmac_reset(host);
>> -#endif
>> +	if (host->use_dma == TRANS_MODE_IDMAC)
>> +		/* It is also recommended that we reset and reprogram idmac */
>> +		dw_mci_idmac_reset(host);
>>
>>   	ret = true;
>>
>> @@ -2890,7 +3047,7 @@ int dw_mci_probe(struct dw_mci *host)
>>   	 * Get the host data width - this assumes that HCON has been set with
>>   	 * the correct values.
>>   	 */
>> -	i = (mci_readl(host, HCON) >> 7) & 0x7;
>> +	i = SDMMC_GET_HDATA_WIDTH(mci_readl(host, HCON));
>
> This is not related with supporting external dma interface.
> Separate this.
>
>>   	if (!i) {
>>   		host->push_data = dw_mci_push_data16;
>>   		host->pull_data = dw_mci_pull_data16;
>> @@ -2972,7 +3129,7 @@ int dw_mci_probe(struct dw_mci *host)
>>   	if (host->pdata->num_slots)
>>   		host->num_slots = host->pdata->num_slots;
>>   	else
>> -		host->num_slots = ((mci_readl(host, HCON) >> 1) & 0x1F) + 1;
>> +		host->num_slots = SDMMC_GET_SLOT_NUM(mci_readl(host, HCON));
>
> Ditto. (with above.)
>
>>
>>   	/*
>>   	 * Enable interrupts for command done, data over, data empty,
>> @@ -3067,6 +3224,9 @@ EXPORT_SYMBOL(dw_mci_remove);
>>    */
>>   int dw_mci_suspend(struct dw_mci *host)
>>   {
>> +	if (host->use_dma && host->dma_ops->exit)
>> +		host->dma_ops->exit(host);
>> +
>>   	return 0;
>>   }
>>   EXPORT_SYMBOL(dw_mci_suspend);
>> diff --git a/drivers/mmc/host/dw_mmc.h b/drivers/mmc/host/dw_mmc.h
>> index 8ce4674..c453e94 100644
>> --- a/drivers/mmc/host/dw_mmc.h
>> +++ b/drivers/mmc/host/dw_mmc.h
>> @@ -148,6 +148,11 @@
>>   #define SDMMC_SET_FIFOTH(m, r, t)	(((m) & 0x7) << 28 | \
>>   					 ((r) & 0xFFF) << 16 | \
>>   					 ((t) & 0xFFF))
>> +/* HCON register defines */
>> +#define SDMMC_GET_SLOT_NUM(x)		((((x)>>1) & 0x1F) + 1)
>> +#define SDMMC_GET_HDATA_WIDTH(x)	(((x)>>7) & 0x7)
>> +#define SDMMC_GET_TRANS_MODE(x)		(((x)>>16) & 0x3)
>> +#define SDMMC_GET_ADDR_CONFIG(x)	(((x)>>27) & 0x1)
>>   /* Internal DMAC interrupt defines */
>>   #define SDMMC_IDMAC_INT_AI		BIT(9)
>>   #define SDMMC_IDMAC_INT_NI		BIT(8)
>> diff --git a/include/linux/mmc/dw_mmc.h b/include/linux/mmc/dw_mmc.h
>> index c846f42..6a2b83c 100644
>> --- a/include/linux/mmc/dw_mmc.h
>> +++ b/include/linux/mmc/dw_mmc.h
>> @@ -16,6 +16,7 @@
>>
>>   #include <linux/scatterlist.h>
>>   #include <linux/mmc/core.h>
>> +#include <linux/dmaengine.h>
>>
>>   #define MAX_MCI_SLOTS	2
>>
>> @@ -40,6 +41,17 @@ enum {
>>
>>   struct mmc_data;
>>
>> +enum {
>> +	TRANS_MODE_PIO = 0,
>> +	TRANS_MODE_IDMAC,
>> +	TRANS_MODE_EDMAC
>> +};
>> +
>> +struct dw_mci_dma_slave {
>> +	struct dma_chan *ch;
>> +	enum dma_transfer_direction direction;
>> +};
>> +
>>   /**
>>    * struct dw_mci - MMC controller state shared between all slots
>>    * @lock: Spinlock protecting the queue and associated data.
>> @@ -154,11 +166,16 @@ struct dw_mci {
>>   	dma_addr_t		sg_dma;
>>   	void			*sg_cpu;
>>   	const struct dw_mci_dma_ops	*dma_ops;
>> -#ifdef CONFIG_MMC_DW_IDMAC
>> +	/* For idmac */
>>   	unsigned int		ring_size;
>> -#else
>> +
>> +	/* For edmac */
>> +	struct dw_mci_dma_slave *dms;
>> +	/* Registers's physical base address */
>> +	void                    *phy_regs;
>> +
>>   	struct dw_mci_dma_data	*dma_data;
>> -#endif
>> +
>
> On ulf's repository, this point should be conflicted.
>
> Best Regards,
> Jaehoon Chung
>
>>   	u32			cmd_status;
>>   	u32			data_status;
>>   	u32			stop_cmdr;
>> @@ -212,8 +229,8 @@ struct dw_mci {
>>   struct dw_mci_dma_ops {
>>   	/* DMA Ops */
>>   	int (*init)(struct dw_mci *host);
>> -	void (*start)(struct dw_mci *host, unsigned int sg_len);
>> -	void (*complete)(struct dw_mci *host);
>> +	int (*start)(struct dw_mci *host, unsigned int sg_len);
>> +	void (*complete)(void *host);
>>   	void (*stop)(struct dw_mci *host);
>>   	void (*cleanup)(struct dw_mci *host);
>>   	void (*exit)(struct dw_mci *host);
>>
>
>
>
>


-- 
Best Regards
Shawn Lin



From monstr at monstr.eu  Thu Aug 20 23:36:09 2015
From: monstr at monstr.eu (Michal Simek)
Date: Fri, 21 Aug 2015 08:36:09 +0200
Subject: [GIT PULL] Xilinx Zynq DT changes for v4.3 v2
In-Reply-To: <20150821020322.GO4865@localhost>
References: <55D4646F.7010404@monstr.eu> <20150821020322.GO4865@localhost>
Message-ID: <55D6C6D9.3070401@monstr.eu>

On 08/21/2015 04:03 AM, Olof Johansson wrote:
> On Wed, Aug 19, 2015 at 01:11:43PM +0200, Michal Simek wrote:
>> Hi guys,
>>
>> Philipp just sent his PR to you with adding reset controller for Zynq
>> (http://www.spinics.net/lists/arm-kernel/msg440136.html).
>> Can you please consider to add this one more patch to your tree?
>> It is one more patch on the top of existing zynq/dt branch which you
>> already have in arm-soc git repo.
> 
> The change is small enough, so yes we can merge it with the below fixed:
> 
>> Moritz Fischer (1):
>>       dts: zynq: Add devicetree entry for Xilinx Zynq reset controller.
> 
> ARM: dts: <....> is the format we want here -- that's what most other platforms
> use as well. I.e. please add ARM as a prefix.

ok. Will keep my eye on it.

> 
> I can do it here and just apply as a patch too instead of merging, just let me
> know.

Yes that will be great if you can do that change on your side.

Thanks,
Michal


-- 
Michal Simek, Ing. (M.Eng), OpenPGP -> KeyID: FE3D1F91
w: www.monstr.eu p: +42-0-721842854
Maintainer of Linux kernel - Microblaze cpu - http://www.monstr.eu/fdt/
Maintainer of Linux kernel - Xilinx Zynq ARM architecture
Microblaze U-BOOT custodian and responsible for u-boot arm zynq platform


-------------- next part --------------
A non-text attachment was scrubbed...
Name: signature.asc
Type: application/pgp-signature
Size: 198 bytes
Desc: OpenPGP digital signature
URL: <http://lists.infradead.org/pipermail/linux-arm-kernel/attachments/20150821/9673bbc0/attachment.sig>

From liguozhu at hisilicon.com  Thu Aug 20 23:36:15 2015
From: liguozhu at hisilicon.com (Kenneth Lee)
Date: Fri, 21 Aug 2015 14:36:15 +0800
Subject: [PATCH 2/5] net: add Hisilicon Network Subsystem hnae framework
 support
In-Reply-To: <CALW4P+J8LkLshu5TuRT+8c__KRwJ8XAdMV4yA0KEnrfUg=mNow@mail.gmail.com>
References: <1439548222-231611-1-git-send-email-liguozhu@hisilicon.com>
 <1439548222-231611-3-git-send-email-liguozhu@hisilicon.com>
 <CALW4P+J8LkLshu5TuRT+8c__KRwJ8XAdMV4yA0KEnrfUg=mNow@mail.gmail.com>
Message-ID: <20150821063614.GA80122@Turing-Arch-b>

Thanks, Klimov,

You are right. I will fix it in next patches.

On Tue, Aug 18, 2015 at 03:12:02AM +0300, Alexey Klimov wrote:
> Date: Tue, 18 Aug 2015 03:12:02 +0300
> From: Alexey Klimov <klimov.linux at gmail.com>
> To: Kenneth Lee <liguozhu at hisilicon.com>
> CC: robh+dt at kernel.org, pawel.moll at arm.com, Mark Rutland
>  <mark.rutland at arm.com>, ijc+devicetree at hellion.org.uk, Kumar Gala
>  <galak at codeaurora.org>, Catalin Marinas <catalin.marinas at arm.com>, Will
>  Deacon <will.deacon at arm.com>, Yisen.Zhuang at huawei.com, "David S. Miller"
>  <davem at davemloft.net>, paul.gortmaker at windriver.com,
>  dingtianhong at huawei.com, zhangfei.gao at linaro.org,
>  devicetree at vger.kernel.org, Linux Kernel Mailing List
>  <linux-kernel at vger.kernel.org>, linux-arm-kernel at lists.infradead.org,
>  netdev at vger.kernel.org, linuxarm at huawei.com, salil.mehta at huawei.com,
>  huangdaode at hisilicon.com, Kenneth Lee <liguozhu at huawei.com>, Yury Norov
>  <yury.norov at gmail.com>
> Subject: Re: [PATCH 2/5] net: add Hisilicon Network Subsystem hnae
>  framework support
> Message-ID: <CALW4P+J8LkLshu5TuRT+8c__KRwJ8XAdMV4yA0KEnrfUg=mNow at mail.gmail.com>
> 
> Hi Kenneth,
> 
> just small minor question.
> 
> On Fri, Aug 14, 2015 at 1:30 PM, Kenneth Lee <liguozhu at hisilicon.com> wrote:
> > HNAE (Hisilicon Network Acceleration Engine) is a framework to provide a
> > unified ring buffer interface for Hisilicon Network Acceleration Engines.
> >
> > With the interface, upper layer can work as ethernet driver, ODP driver or
> > other service driver on purpose.
> >
> > Signed-off-by: Kenneth Lee <liguozhu at huawei.com>
> > Signed-off-by: Yisen Zhuang <Yisen.Zhuang at huawei.com>
> > ---
> >  drivers/net/ethernet/hisilicon/Kconfig      |  33 +-
> >  drivers/net/ethernet/hisilicon/Makefile     |   1 +
> >  drivers/net/ethernet/hisilicon/hns/Makefile |  15 +
> >  drivers/net/ethernet/hisilicon/hns/hnae.c   | 494 +++++++++++++++++++++++
> >  drivers/net/ethernet/hisilicon/hns/hnae.h   | 582 ++++++++++++++++++++++++++++
> >  5 files changed, 1124 insertions(+), 1 deletion(-)
> >  create mode 100644 drivers/net/ethernet/hisilicon/hns/Makefile
> >  create mode 100644 drivers/net/ethernet/hisilicon/hns/hnae.c
> >  create mode 100644 drivers/net/ethernet/hisilicon/hns/hnae.h
> >
> > diff --git a/drivers/net/ethernet/hisilicon/Kconfig b/drivers/net/ethernet/hisilicon/Kconfig
> > index dead17b..1e4f5a7 100644
> > --- a/drivers/net/ethernet/hisilicon/Kconfig
> > +++ b/drivers/net/ethernet/hisilicon/Kconfig
> > @@ -5,7 +5,7 @@
> >  config NET_VENDOR_HISILICON
> >         bool "Hisilicon devices"
> >         default y
> > -       depends on ARM
> > +       depends on ARM || ARM64
> >         ---help---
> >           If you have a network (Ethernet) card belonging to this class, say Y.
> >
> > @@ -31,4 +31,35 @@ config HIP04_ETH
> >           If you wish to compile a kernel for a hardware with hisilicon p04 SoC and
> >           want to use the internal ethernet then you should answer Y to this.
> >
> > +config HNS
> > +       tristate "Hisilicon Network Subsystem Support (Framework)"
> > +       ---help---
> > +         This selects the framework support for Hisilicon Network Subsystem. It
> > +         is needed by any driver which provides HNS acceleration engine or make
> > +         use of the engine
> > +
> > +config HNS_DSAF
> > +       tristate "Hisilicon HNS DSAF device Support"
> > +       select HNS
> > +       select HNS_MDIO
> > +       ---help---
> > +         This selects the DSAF (Distributed System Area Frabric) network
> > +         acceleration engine support. The engine is used in Hisilicon P660,
> > +         Hi1610 and further ICT SoC
> > +
> > +config HNS_MDIO
> > +       tristate "Hisilicon HNS MDIO device Support"
> > +       select MDIO
> > +       ---help---
> > +         This selects the HNS MDIO support. It is needed by HNS_DSAF to access
> > +         the PHY
> > +
> > +config HNS_ENET
> > +       tristate "Hisilicon HNS Ethernet Device Support"
> > +       select PHYLIB
> > +       select HNS
> > +       ---help---
> > +         This selects the general ethernet driver for HNS.  This module make
> > +         use of any HNS AE driver, such as HNS_DSAF
> > +
> >  endif # NET_VENDOR_HISILICON
> > diff --git a/drivers/net/ethernet/hisilicon/Makefile b/drivers/net/ethernet/hisilicon/Makefile
> > index 6c14540..2503a9b 100644
> > --- a/drivers/net/ethernet/hisilicon/Makefile
> > +++ b/drivers/net/ethernet/hisilicon/Makefile
> > @@ -4,3 +4,4 @@
> >
> >  obj-$(CONFIG_HIX5HD2_GMAC) += hix5hd2_gmac.o
> >  obj-$(CONFIG_HIP04_ETH) += hip04_mdio.o hip04_eth.o
> > +obj-$(CONFIG_HNS) += hns/
> > diff --git a/drivers/net/ethernet/hisilicon/hns/Makefile b/drivers/net/ethernet/hisilicon/hns/Makefile
> > new file mode 100644
> > index 0000000..6680602
> > --- /dev/null
> > +++ b/drivers/net/ethernet/hisilicon/hns/Makefile
> > @@ -0,0 +1,15 @@
> > +#
> > +# Makefile for the HISILICON network device drivers.
> > +#
> > +
> > +obj-$(CONFIG_HNS) += hnae.o
> > +
> > +obj-$(CONFIG_HNS_DSAF) += hns_dsaf.o
> > +hns_dsaf-objs = hns_ae_adapt.o hns_dsaf_gmac.o hns_dsaf_mac.o hns_dsaf_misc.o \
> > +       hns_dsaf_main.o hns_dsaf_ppe.o hns_dsaf_rcb.o hns_dsaf_xgmac.o
> > +
> > +obj-$(CONFIG_HNS_MDIO) += hns_mdio.o
> > +hns_mdio-objs = hns_mdio_main.o
> > +
> > +obj-$(CONFIG_HNS_ENET) += hns_enet_drv.o
> > +hns_enet_drv-objs = hns_enet.o hns_ethtool.o
> > diff --git a/drivers/net/ethernet/hisilicon/hns/hnae.c b/drivers/net/ethernet/hisilicon/hns/hnae.c
> > new file mode 100644
> > index 0000000..fd09768
> > --- /dev/null
> > +++ b/drivers/net/ethernet/hisilicon/hns/hnae.c
> > @@ -0,0 +1,494 @@
> > +/*
> > + * Copyright (c) 2014-2015 Hisilicon Limited.
> > + *
> > + * 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.
> > + */
> > +
> > +#include <linux/dma-mapping.h>
> > +#include <linux/interrupt.h>
> > +#include <linux/skbuff.h>
> > +#include <linux/slab.h>
> > +
> > +#include "hnae.h"
> > +
> > +#define cls_to_ae_dev(dev) container_of(dev, struct hnae_ae_dev, cls_dev)
> > +
> > +static struct class *hnae_class;
> > +
> > +static inline void hnae_list_add(spinlock_t *lock, struct list_head *node,
> > +                                struct list_head *head)
> > +{
> > +       unsigned long flags;
> > +
> > +       spin_lock_irqsave(lock, flags);
> > +       list_add_tail_rcu(node, head);
> > +       spin_unlock_irqrestore(lock, flags);
> > +}
> > +
> > +static inline void hnae_list_del(spinlock_t *lock, struct list_head *node)
> > +{
> > +       unsigned long flags;
> > +
> > +       spin_lock_irqsave(lock, flags);
> > +       list_del_rcu(node);
> > +       spin_unlock_irqrestore(lock, flags);
> > +}
> > +
> > +static int hnae_alloc_buffer(struct hnae_ring *ring, struct hnae_desc_cb *cb)
> > +{
> > +       unsigned int order = hnae_page_order(ring);
> > +       struct page *p = dev_alloc_pages(order);
> > +
> > +       if (!p)
> > +               return -ENOMEM;
> > +
> > +       cb->priv = p;
> > +       cb->page_offset = 0;
> > +       cb->reuse_flag = 0;
> > +       cb->buf  = page_address(p);
> > +       cb->length = hnae_page_size(ring);
> > +       cb->type = DESC_TYPE_PAGE;
> > +
> > +       return 0;
> > +}
> > +
> > +static void hnae_free_buffer(struct hnae_ring *ring, struct hnae_desc_cb *cb)
> > +{
> > +       if (cb->type == DESC_TYPE_SKB)
> > +               dev_kfree_skb_any((struct sk_buff *)cb->priv);
> > +       else if (unlikely(is_rx_ring(ring)))
> > +               put_page((struct page *)cb->priv);
> > +       memset(cb, 0, sizeof(*cb));
> > +}
> > +
> > +static int hnae_map_buffer(struct hnae_ring *ring, struct hnae_desc_cb *cb)
> > +{
> > +       cb->dma = dma_map_page(ring_to_dev(ring), cb->priv, 0,
> > +                              cb->length, ring_to_dma_dir(ring));
> > +
> > +       if (dma_mapping_error(ring_to_dev(ring), cb->dma))
> > +               return -EIO;
> > +
> > +       return 0;
> > +}
> > +
> > +static void hnae_unmap_buffer(struct hnae_ring *ring, struct hnae_desc_cb *cb)
> > +{
> > +       if (cb->type == DESC_TYPE_SKB)
> > +               dma_unmap_single(ring_to_dev(ring), cb->dma, cb->length,
> > +                                ring_to_dma_dir(ring));
> > +       else
> > +               dma_unmap_page(ring_to_dev(ring), cb->dma, cb->length,
> > +                              ring_to_dma_dir(ring));
> > +}
> > +
> > +static struct hnae_buf_ops hnae_bops = {
> > +       .alloc_buffer = hnae_alloc_buffer,
> > +       .free_buffer = hnae_free_buffer,
> > +       .map_buffer = hnae_map_buffer,
> > +       .unmap_buffer = hnae_unmap_buffer,
> > +};
> > +
> > +static int __ae_match(struct device *dev, const void *data)
> > +{
> > +       struct hnae_ae_dev *hdev = cls_to_ae_dev(dev);
> > +       const char *ae_id = data;
> > +
> > +       if (!strncmp(ae_id, hdev->name, AE_NAME_SIZE))
> > +               return 1;
> > +
> > +       return 0;
> > +}
> > +
> > +static struct hnae_ae_dev *find_ae(const char *ae_id)
> > +{
> > +       struct device *dev;
> > +
> > +       BUG_ON(!ae_id);
> > +
> > +       dev = class_find_device(hnae_class, NULL, ae_id, __ae_match);
> > +
> > +       return cls_to_ae_dev(dev);
> > +}
> 
> Most entries of class_find_device() in kernel that i see perform
> if-check for NULL on return value.
> What do you think about such option for example:
> return dev ? cls_to_ae_dev(dev) : NULL;
> ?
> 
> Is it possible that, someday, your dev will be NULL and creep in
> container_of() that doesn't protected from ptr = NULL
> and .... (let's go down a little in another function)
> 
> > +
> > +static void hnae_free_buffers(struct hnae_ring *ring)
> > +{
> > +       int i;
> > +
> > +       for (i = 0; i < ring->desc_num; i++)
> > +               hnae_free_buffer_detach(ring, i);
> > +}
> > +
> > +/* Allocate memory for raw pkg, and map with dma */
> > +static int hnae_alloc_buffers(struct hnae_ring *ring)
> > +{
> > +       int i, j, ret;
> > +
> > +       for (i = 0; i < ring->desc_num; i++) {
> > +               ret = hnae_alloc_buffer_attach(ring, i);
> > +               if (ret)
> > +                       goto out_buffer_fail;
> > +       }
> > +
> > +       return 0;
> > +
> > +out_buffer_fail:
> > +       for (j = i - 1; j >= 0; j--)
> > +               hnae_free_buffer_detach(ring, j);
> > +       return ret;
> > +}
> > +
> > +/* free desc along with its attached buffer */
> > +static inline void hnae_free_desc(struct hnae_ring *ring)
> > +{
> > +       hnae_free_buffers(ring);
> > +       dma_unmap_single(ring_to_dev(ring), ring->desc_dma_addr,
> > +                        ring->desc_num * sizeof(ring->desc[0]),
> > +                        ring_to_dma_dir(ring));
> > +       ring->desc_dma_addr = 0;
> > +       kfree(ring->desc);
> > +       ring->desc = NULL;
> > +}
> > +
> > +/* alloc desc, without buffer attached */
> > +static inline int hnae_alloc_desc(struct hnae_ring *ring)
> > +{
> > +       int size = ring->desc_num * sizeof(ring->desc[0]);
> > +
> > +       ring->desc = kzalloc(size, GFP_KERNEL);
> > +       if (!ring->desc)
> > +               return -ENOMEM;
> > +
> > +       ring->desc_dma_addr = dma_map_single(ring_to_dev(ring),
> > +               ring->desc, size, ring_to_dma_dir(ring));
> > +       if (dma_mapping_error(ring_to_dev(ring), ring->desc_dma_addr)) {
> > +               ring->desc_dma_addr = 0;
> > +               kfree(ring->desc);
> > +               ring->desc = NULL;
> > +               return -ENOMEM;
> > +       }
> > +
> > +       return 0;
> > +}
> > +
> > +/* fini ring, also free the buffer for the ring */
> > +static inline void hnae_fini_ring(struct hnae_ring *ring)
> > +{
> > +       hnae_free_desc(ring);
> > +       kfree(ring->desc_cb);
> > +       ring->desc_cb = NULL;
> > +       ring->next_to_clean = 0;
> > +       ring->next_to_use = 0;
> > +}
> > +
> > +/* init ring, and with buffer for rx ring */
> > +static inline int hnae_init_ring(struct hnae_queue *q, struct hnae_ring *ring,
> > +                                int flags)
> > +{
> > +       int ret;
> > +
> > +       if (ring->desc_num <= 0 || ring->buf_size <= 0)
> > +               return -EINVAL;
> > +
> > +       ring->q = q;
> > +       ring->flags = flags;
> > +       assert(!ring->desc && !ring->desc_cb && !ring->desc_dma_addr);
> > +
> > +       /* not matter for tx or rx ring, the ntc and ntc start from 0 */
> > +       assert(ring->next_to_use == 0);
> > +       assert(ring->next_to_clean == 0);
> > +
> > +       ring->desc_cb = kcalloc(ring->desc_num, sizeof(ring->desc_cb[0]),
> > +                       GFP_KERNEL);
> > +       if (!ring->desc_cb) {
> > +               ret = -ENOMEM;
> > +               goto out;
> > +       }
> > +
> > +       ret = hnae_alloc_desc(ring);
> > +       if (ret)
> > +               goto out_with_desc_cb;
> > +
> > +       if (is_rx_ring(ring)) {
> > +               ret = hnae_alloc_buffers(ring);
> > +               if (ret)
> > +                       goto out_with_desc;
> > +       }
> > +
> > +       return 0;
> > +
> > +out_with_desc:
> > +       hnae_free_desc(ring);
> > +out_with_desc_cb:
> > +       kfree(ring->desc_cb);
> > +       ring->desc_cb = NULL;
> > +out:
> > +       return ret;
> > +}
> > +
> > +static inline int hnae_init_queue(struct hnae_handle *h, struct hnae_queue *q,
> > +                                 struct hnae_ae_dev *dev)
> > +{
> > +       int ret;
> > +
> > +       q->dev = dev;
> > +       q->handle = h;
> > +
> > +       ret = hnae_init_ring(q, &q->tx_ring, q->tx_ring.flags | RINGF_DIR);
> > +       if (ret)
> > +               goto out;
> > +
> > +       ret = hnae_init_ring(q, &q->rx_ring, q->rx_ring.flags & ~RINGF_DIR);
> > +       if (ret)
> > +               goto out_with_tx_ring;
> > +
> > +       if (dev->ops->init_queue)
> > +               dev->ops->init_queue(q);
> > +
> > +       return 0;
> > +
> > +out_with_tx_ring:
> > +       hnae_fini_ring(&q->tx_ring);
> > +out:
> > +       return ret;
> > +}
> > +
> > +static inline void hnae_fini_queue(struct hnae_queue *q)
> > +{
> > +       if (q->dev->ops->fini_queue)
> > +               q->dev->ops->fini_queue(q);
> > +
> > +       hnae_fini_ring(&q->tx_ring);
> > +       hnae_fini_ring(&q->rx_ring);
> > +}
> > +
> > +/**
> > + * ae_chain - define ae chain head
> > + */
> > +static RAW_NOTIFIER_HEAD(ae_chain);
> > +
> > +int hnae_register_notifier(struct notifier_block *nb)
> > +{
> > +       return raw_notifier_chain_register(&ae_chain, nb);
> > +}
> > +EXPORT_SYMBOL(hnae_register_notifier);
> > +
> > +void hnae_unregister_notifier(struct notifier_block *nb)
> > +{
> > +       if (raw_notifier_chain_unregister(&ae_chain, nb))
> > +               dev_err(NULL, "notifier chain unregister fail\n");
> > +}
> > +EXPORT_SYMBOL(hnae_unregister_notifier);
> > +
> > +int hnae_reinit_handle(struct hnae_handle *handle)
> > +{
> > +       int i, j;
> > +       int ret;
> > +
> > +       for (i = 0; i < handle->q_num; i++) /* free ring*/
> > +               hnae_fini_queue(handle->qs[i]);
> > +
> > +       for (i = 0; i < handle->q_num; i++) {/* reinit ring*/
> > +               ret = hnae_init_queue(handle, handle->qs[i], handle->dev);
> > +               if (ret)
> > +                       goto out_when_init_queue;
> > +       }
> > +       return 0;
> > +out_when_init_queue:
> > +       for (j = i - 1; j >= 0; j--)
> > +               hnae_fini_queue(handle->qs[j]);
> > +       return ret;
> > +}
> > +EXPORT_SYMBOL(hnae_reinit_handle);
> > +
> > +/* hnae_get_handle - get a handle from the AE
> > + * @owner_dev: the dev use this handle
> > + * @ae_id: the id of the ae to be used
> > + * @ae_opts: the options set for the handle
> > + * @bops: the callbacks for buffer management
> > + *
> > + * return handle ptr or ERR_PTR
> > + */
> > +struct hnae_handle *hnae_get_handle(struct device *owner_dev,
> > +                                   const char *ae_id, const char *ae_opts,
> > +                                   struct hnae_buf_ops *bops)
> > +{
> > +       struct hnae_ae_dev *dev;
> > +       struct hnae_handle *handle;
> > +       int i, j;
> > +       int ret;
> > +
> > +       dev = find_ae(ae_id);
> > +       if (!dev)
> > +               return ERR_PTR(-ENODEV);
> 
> .. and here you might not receive NULL after container_of() works on
> that returned NULL after class_find_device().
> I guess that might happen after someone change order of fields in
> struct hnae_ae_dev.
> 
> I understand that it's unlikely to happen but could you please check or comment?
> 
> 
> > +
> > +       handle = dev->ops->get_handle(dev, ae_opts);
> > +       if (IS_ERR(handle))
> > +               return handle;
> > +
> > +       handle->dev = dev;
> > +       handle->owner_dev = owner_dev;
> > +       handle->bops = bops ? bops : &hnae_bops;
> > +       handle->ae_opts = ae_opts;
> > +
> > +       for (i = 0; i < handle->q_num; i++) {
> > +               ret = hnae_init_queue(handle, handle->qs[i], dev);
> > +               if (ret)
> > +                       goto out_when_init_queue;
> > +       }
> > +
> > +       __module_get(dev->owner);
> > +
> > +       hnae_list_add(&dev->lock, &handle->node, &dev->handle_list);
> > +
> > +       return handle;
> > +
> > +out_when_init_queue:
> > +       for (j = i - 1; j >= 0; j--)
> > +               hnae_fini_queue(handle->qs[j]);
> > +
> > +       return ERR_PTR(-ENOMEM);
> > +}
> > +EXPORT_SYMBOL(hnae_get_handle);
> > +
> > +void hnae_put_handle(struct hnae_handle *h)
> > +{
> > +       struct hnae_ae_dev *dev = h->dev;
> > +       int i;
> > +
> > +       for (i = 0; i < h->q_num; i++)
> > +               hnae_fini_queue(h->qs[i]);
> > +
> > +       hnae_list_del(&dev->lock, &h->node);
> > +
> > +       if (dev->ops->put_handle)
> > +               dev->ops->put_handle(h);
> > +
> > +       module_put(dev->owner);
> > +}
> > +EXPORT_SYMBOL(hnae_put_handle);
> > +
> > +static void __hnae_release(struct device *dev)
> > +{
> > +}
> > +
> > +/**
> > + * hnae_ae_register - register a AE engine to hnae framework
> > + * @hdev: the hnae ae engine device
> > + * @owner:  the module who provides this dev
> > + * NOTE: the duplicated name will not be checked
> > + */
> > +int hnae_ae_register(struct hnae_ae_dev *hdev, struct module *owner)
> > +{
> > +       static atomic_t id = ATOMIC_INIT(-1);
> > +       int ret;
> > +
> > +       if (!hdev->dev)
> > +               return -ENODEV;
> > +
> > +       if (!hdev->ops || !hdev->ops->get_handle ||
> > +           !hdev->ops->toggle_ring_irq ||
> > +           !hdev->ops->toggle_queue_status ||
> > +           !hdev->ops->get_status || !hdev->ops->adjust_link)
> > +               return -EINVAL;
> > +
> > +       hdev->owner = owner;
> > +       hdev->id = (int)atomic_inc_return(&id);
> > +       hdev->cls_dev.parent = hdev->dev;
> > +       hdev->cls_dev.class = hnae_class;
> > +       hdev->cls_dev.release = __hnae_release;
> > +       dev_set_name(&hdev->cls_dev, "hnae%d", hdev->id);
> > +       ret = device_register(&hdev->cls_dev);
> > +       if (ret)
> > +               return ret;
> > +
> > +       __module_get(THIS_MODULE);
> > +
> > +       INIT_LIST_HEAD(&hdev->handle_list);
> > +       spin_lock_init(&hdev->lock);
> > +
> > +       ret = raw_notifier_call_chain(&ae_chain, HNAE_AE_REGISTER, NULL);
> > +       if (ret)
> > +               dev_dbg(hdev->dev,
> > +                       "has not notifier for AE: %s\n", hdev->name);
> > +
> > +       return 0;
> > +}
> > +EXPORT_SYMBOL(hnae_ae_register);
> > +
> > +/**
> > + * hnae_ae_unregister - unregisters a HNAE AE engine
> > + * @cdev: the device to unregister
> > + */
> > +void hnae_ae_unregister(struct hnae_ae_dev *hdev)
> > +{
> > +       device_unregister(&hdev->cls_dev);
> > +       module_put(THIS_MODULE);
> > +}
> > +EXPORT_SYMBOL(hnae_ae_unregister);
> > +
> > +static ssize_t handles_show(struct device *dev,
> > +                           struct device_attribute *attr, char *buf)
> > +{
> > +       ssize_t s = 0;
> > +       struct hnae_ae_dev *hdev = cls_to_ae_dev(dev);
> > +       struct hnae_handle *h;
> > +       int i = 0, j;
> > +
> > +       list_for_each_entry_rcu(h, &hdev->handle_list, node) {
> > +               s += sprintf(buf + s, "%s(%s): ", dev_name(h->owner_dev),
> > +                            h->ae_opts);
> > +               for (j = 0; j < h->q_num; j++) {
> > +                       if (h->qs[i]) {
> > +                               s += sprintf(buf + s,
> > +                                       "(%llu,%llu; ",
> > +                                       h->qs[i]->tx_ring.stats.sw_err_cnt,
> > +                                       h->qs[i]->tx_ring.stats.io_err_cnt);
> > +                               s += sprintf(buf + s,
> > +                                       "%llu,%llu,%llu), ",
> > +                                       h->qs[i]->rx_ring.stats.sw_err_cnt,
> > +                                       h->qs[i]->rx_ring.stats.io_err_cnt,
> > +                                       h->qs[i]->rx_ring.stats.seg_pkt_cnt);
> > +                       } else {
> > +                               s += sprintf(buf + s, "(null)\n");
> > +                       }
> > +               }
> > +               s += sprintf(buf + s, "\n");
> > +       }
> > +
> > +       return s;
> > +}
> > +
> > +static DEVICE_ATTR_RO(handles);
> > +static struct attribute *hnae_class_attrs[] = {
> > +       &dev_attr_handles.attr,
> > +       NULL,
> > +};
> > +ATTRIBUTE_GROUPS(hnae_class);
> > +
> > +static int __init hnae_init(void)
> > +{
> > +       hnae_class = class_create(THIS_MODULE, "hnae");
> > +       if (IS_ERR(hnae_class))
> > +               return PTR_ERR(hnae_class);
> > +
> > +       hnae_class->dev_groups = hnae_class_groups;
> > +       return 0;
> > +}
> > +
> > +static void __exit hnae_exit(void)
> > +{
> > +       class_destroy(hnae_class);
> > +}
> > +
> > +subsys_initcall(hnae_init);
> > +module_exit(hnae_exit);
> > +
> > +MODULE_AUTHOR("Hisilicon, Inc.");
> > +MODULE_LICENSE("GPL");
> > +MODULE_DESCRIPTION("Hisilicon Network Acceleration Engine Framework");
> > +
> > +/* vi: set tw=78 noet: */
> > diff --git a/drivers/net/ethernet/hisilicon/hns/hnae.h b/drivers/net/ethernet/hisilicon/hns/hnae.h
> > new file mode 100644
> > index 0000000..e7856cf
> > --- /dev/null
> > +++ b/drivers/net/ethernet/hisilicon/hns/hnae.h
> > @@ -0,0 +1,582 @@
> > +/*
> > + * Copyright (c) 2014-2015 Hisilicon Limited.
> > + *
> > + * 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.
> > + */
> > +
> > +#ifndef __HNAE_H
> > +#define __HNAE_H
> > +
> > +/* Names used in this framework:
> > + *      ae handle (handle):
> > + *        a set of queues provided by AE
> > + *      ring buffer queue (rbq):
> > + *        the channel between upper layer and the AE, can do tx and rx
> > + *      ring:
> > + *        a tx or rx channel within a rbq
> > + *      ring description (desc):
> > + *        an element in the ring with packet information
> > + *      buffer:
> > + *        a memory region referred by desc with the full packet payload
> > + *
> > + * "num" means a static number set as a parameter, "count" mean a dynamic
> > + *   number set while running
> > + * "cb" means control block
> > + */
> > +
> > +#include <linux/delay.h>
> > +#include <linux/device.h>
> > +#include <linux/module.h>
> > +#include <linux/netdevice.h>
> > +#include <linux/notifier.h>
> > +#include <linux/types.h>
> > +
> > +#define HNAE_DRIVER_VERSION "1.1.0"
> > +#define HNAE_DRIVER_NAME "hns"
> > +#define HNAE_COPYRIGHT "Copyright(c) 2015 Huawei Corporation."
> > +#define HNAE_DRIVER_STRING "Hisilicon Network Subsystem Driver"
> > +#define HNAE_DEFAULT_DEVICE_DESCR "Hisilicon Network Subsystem"
> > +
> > +#ifdef DEBUG
> > +
> > +#ifndef assert
> > +#define assert(expr) \
> > +do { \
> > +       if (!(expr)) { \
> > +               pr_err("Assertion failed! %s, %s, %s, line %d\n", \
> > +                          #expr, __FILE__, __func__, __LINE__); \
> > +       } \
> > +} while (0)
> > +#endif
> > +
> > +#else
> > +
> > +#ifndef assert
> > +#define assert(expr)
> > +#endif
> > +
> > +#endif
> > +
> > +#define AE_NAME_SIZE 16
> > +#define AE_OPTS_SIZE 64
> > +
> > +/* some said the RX and TX RCB format should not be the same in the future. But
> > + * it is the same now...
> > + */
> > +#define RCB_REG_BASEADDR_L         0x00 /* P660 support only 32bit accessing */
> > +#define RCB_REG_BASEADDR_H         0x04
> > +#define RCB_REG_BD_NUM             0x08
> > +#define RCB_REG_BD_LEN             0x0C
> > +#define RCB_REG_PKTLINE            0x10
> > +#define RCB_REG_TAIL               0x18
> > +#define RCB_REG_HEAD               0x1C
> > +#define RCB_REG_FBDNUM             0x20
> > +#define RCB_REG_OFFSET             0x24 /* pkt num to be handled */
> > +#define RCB_REG_PKTNUM_RECORD      0x2C /* total pkt received */
> > +
> > +#define HNS_RX_HEAD_SIZE 256
> > +
> > +#define HNAE_AE_REGISTER 0x1
> > +
> > +#define RCB_RING_NAME_LEN 16
> > +
> > +enum hnae_led_state {
> > +       HNAE_LED_INACTIVE,
> > +       HNAE_LED_ACTIVE,
> > +       HNAE_LED_ON,
> > +       HNAE_LED_OFF
> > +};
> > +
> > +#define HNS_RX_FLAG_VLAN_PRESENT 0x1
> > +#define HNS_RX_FLAG_L3ID_IPV4 0x0
> > +#define HNS_RX_FLAG_L3ID_IPV6 0x1
> > +#define HNS_RX_FLAG_L4ID_UDP 0x0
> > +#define HNS_RX_FLAG_L4ID_TCP 0x1
> > +
> > +#define HNS_TXD_ASID_S 0
> > +#define HNS_TXD_ASID_M (0xff << HNS_TXD_ASID_S)
> > +#define HNS_TXD_BUFNUM_S 8
> > +#define HNS_TXD_BUFNUM_M (0x3 << HNS_TXD_BUFNUM_S)
> > +#define HNS_TXD_PORTID_S 10
> > +#define HNS_TXD_PORTID_M (0x7 << HNS_TXD_PORTID_S)
> > +
> > +#define HNS_TXD_RA_B 8
> > +#define HNS_TXD_RI_B 9
> > +#define HNS_TXD_L4CS_B 10
> > +#define HNS_TXD_L3CS_B 11
> > +#define HNS_TXD_FE_B 12
> > +#define HNS_TXD_VLD_B 13
> > +#define HNS_TXD_IPOFFSET_S 14
> > +#define HNS_TXD_IPOFFSET_M (0xff << HNS_TXD_IPOFFSET_S)
> > +
> > +#define HNS_RXD_IPOFFSET_S 0
> > +#define HNS_RXD_IPOFFSET_M (0xff << HNS_TXD_IPOFFSET_S)
> > +#define HNS_RXD_BUFNUM_S 8
> > +#define HNS_RXD_BUFNUM_M (0x3 << HNS_RXD_BUFNUM_S)
> > +#define HNS_RXD_PORTID_S 10
> > +#define HNS_RXD_PORTID_M (0x7 << HNS_RXD_PORTID_S)
> > +#define HNS_RXD_DMAC_S 13
> > +#define HNS_RXD_DMAC_M (0x3 << HNS_RXD_DMAC_S)
> > +#define HNS_RXD_VLAN_S 15
> > +#define HNS_RXD_VLAN_M (0x3 << HNS_RXD_VLAN_S)
> > +#define HNS_RXD_L3ID_S 17
> > +#define HNS_RXD_L3ID_M (0xf << HNS_RXD_L3ID_S)
> > +#define HNS_RXD_L4ID_S 21
> > +#define HNS_RXD_L4ID_M (0xf << HNS_RXD_L4ID_S)
> > +#define HNS_RXD_FE_B 25
> > +#define HNS_RXD_FRAG_B 26
> > +#define HNS_RXD_VLD_B 27
> > +#define HNS_RXD_L2E_B 28
> > +#define HNS_RXD_L3E_B 29
> > +#define HNS_RXD_L4E_B 30
> > +#define HNS_RXD_DROP_B 31
> > +
> > +#define HNS_RXD_VLANID_S 8
> > +#define HNS_RXD_VLANID_M (0xfff << HNS_RXD_VLANID_S)
> > +#define HNS_RXD_CFI_B 20
> > +#define HNS_RXD_PRI_S 21
> > +#define HNS_RXD_PRI_M (0x7 << HNS_RXD_PRI_S)
> > +#define HNS_RXD_ASID_S 24
> > +#define HNS_RXD_ASID_M (0xff << HNS_RXD_ASID_S)
> > +
> > +/* hardware spec ring buffer format */
> > +struct __packed hnae_desc {
> > +       __le64 addr;
> > +       union {
> > +               struct {
> > +                       __le16 asid_bufnum_pid;
> > +                       __le16 send_size;
> > +                       __le32 flag_ipoffset;
> > +                       __le32 reserved_3[4];
> > +               } tx;
> > +
> > +               struct {
> > +                       __le32 ipoff_bnum_pid_flag;
> > +                       __le16 pkt_len;
> > +                       __le16 size;
> > +                       __le32 vlan_pri_asid;
> > +                       __le32 reserved_2[3];
> > +               } rx;
> > +       };
> > +};
> > +
> > +struct hnae_desc_cb {
> > +       dma_addr_t dma; /* dma address of this desc */
> > +       void *buf;      /* cpu addr for a desc */
> > +
> > +       /* priv data for the desc, e.g. skb when use with ip stack*/
> > +       void *priv;
> > +       u16 page_offset;
> > +       u16 reuse_flag;
> > +
> > +       u16 length;     /* length of the buffer */
> > +
> > +       /* desc type, used by the ring user to mark the type of the priv data */
> > +       u16 type;
> > +};
> > +
> > +#define setflags(flags, bits) ((flags) |= (bits))
> > +#define unsetflags(flags, bits) ((flags) &= ~(bits))
> > +
> > +/* hnae_ring->flags fields */
> > +#define RINGF_DIR 0x1      /* TX or RX ring, set if TX */
> > +#define is_tx_ring(ring) ((ring)->flags & RINGF_DIR)
> > +#define is_rx_ring(ring) (!is_tx_ring(ring))
> > +#define ring_to_dma_dir(ring) (is_tx_ring(ring) ? \
> > +       DMA_TO_DEVICE : DMA_FROM_DEVICE)
> > +
> > +struct ring_stats {
> > +       u64 io_err_cnt;
> > +       u64 sw_err_cnt;
> > +       u64 seg_pkt_cnt;
> > +       u64 reuse_pg_cnt;
> > +       u64 err_pkt_len;
> > +       u64 non_vld_descs;
> > +       u64 err_bd_num;
> > +       u64 csum_err;
> > +       union {
> > +               u64 tx_pkts;
> > +               u64 rx_pkts;
> > +       } pkts;
> > +       union {
> > +               u64 tx_bytes;
> > +               u64 rx_bytes;
> > +       } bytes;
> > +       union {
> > +               u64 tx_err_cnt;
> > +               u64 rx_err_cnt;
> > +       } err_cnt;
> > +};
> > +
> > +struct hnae_queue;
> > +
> > +struct hnae_ring {
> > +       u8 __iomem *io_base; /* base io address for the ring */
> > +       struct hnae_desc *desc; /* dma map address space */
> > +       struct hnae_desc_cb *desc_cb;
> > +       struct hnae_queue *q;
> > +       int irq;
> > +       char ring_name[RCB_RING_NAME_LEN];
> > +
> > +       /* statistic */
> > +       struct ring_stats stats;
> > +
> > +       dma_addr_t desc_dma_addr;
> > +       u32 buf_size;       /* size for hnae_desc->addr, preset by AE */
> > +       u16 desc_num;       /* total number of desc */
> > +       u16 max_desc_num_per_pkt;
> > +       u16 max_raw_data_sz_per_desc;
> > +       u16 max_pkt_size;
> > +       int next_to_use;    /* idx of next spare desc */
> > +
> > +       /* idx of lastest sent desc, the ring is empty when equal to
> > +        * next_to_use
> > +        */
> > +       int next_to_clean;
> > +
> > +       int flags;          /* ring attribute */
> > +};
> > +
> > +#define ring_ptr_move_fw(ring, p) \
> > +       ((ring)->p = ((ring)->p + 1) % (ring)->desc_num)
> > +#define ring_ptr_move_bw(ring, p) \
> > +       ((ring)->p = ((ring)->p - 1 + (ring)->desc_num) % (ring)->desc_num)
> > +
> > +enum hns_desc_type {
> > +       DESC_TYPE_SKB,
> > +       DESC_TYPE_PAGE,
> > +};
> > +
> > +#define assert_is_ring_idx(ring, idx) \
> > +       assert((idx) >= 0 && (idx) < (ring)->desc_num)
> > +
> > +/* the distance between [begin, end) in a ring buffer
> > + * note: there is a unuse slot between the begin and the end
> > + */
> > +static inline int ring_dist(struct hnae_ring *ring, int begin, int end)
> > +{
> > +       assert_is_ring_idx(ring, begin);
> > +       assert_is_ring_idx(ring, end);
> > +
> > +       return (end - begin + ring->desc_num) % ring->desc_num;
> > +}
> > +
> > +static inline int ring_space(struct hnae_ring *ring)
> > +{
> > +       return ring->desc_num -
> > +               ring_dist(ring, ring->next_to_clean, ring->next_to_use) - 1;
> > +}
> > +
> > +static inline int is_ring_empty(struct hnae_ring *ring)
> > +{
> > +       assert_is_ring_idx(ring, ring->next_to_use);
> > +       assert_is_ring_idx(ring, ring->next_to_clean);
> > +
> > +       return ring->next_to_use == ring->next_to_clean;
> > +}
> > +
> > +#define hnae_buf_size(_ring) ((_ring)->buf_size)
> > +#define hnae_page_order(_ring) (get_order(hnae_buf_size(_ring)))
> > +#define hnae_page_size(_ring) (PAGE_SIZE << hnae_page_order(_ring))
> > +
> > +struct hnae_handle;
> > +
> > +/* allocate and dma map space for hnae desc */
> > +struct hnae_buf_ops {
> > +       int (*alloc_buffer)(struct hnae_ring *ring, struct hnae_desc_cb *cb);
> > +       void (*free_buffer)(struct hnae_ring *ring, struct hnae_desc_cb *cb);
> > +       int (*map_buffer)(struct hnae_ring *ring, struct hnae_desc_cb *cb);
> > +       void (*unmap_buffer)(struct hnae_ring *ring, struct hnae_desc_cb *cb);
> > +};
> > +
> > +struct hnae_queue {
> > +       void __iomem *io_base;
> > +       struct hnae_ae_dev *dev;        /* the device who use this queue */
> > +       struct hnae_ring rx_ring, tx_ring;
> > +       struct hnae_handle *handle;
> > +};
> > +
> > +/*hnae loop mode*/
> > +enum hnae_loop {
> > +       MAC_LOOP_NONE = 0,
> > +       MAC_INTERNALLOOP_MAC,
> > +       MAC_INTERNALLOOP_SERDES,
> > +       MAC_INTERNALLOOP_PHY,
> > +};
> > +
> > +/*hnae port type*/
> > +enum hnae_port_type {
> > +       HNAE_PORT_SERVICE = 0,
> > +       HNAE_PORT_DEBUG
> > +};
> > +
> > +/* This struct defines the operation on the handle.
> > + *
> > + * get_handle(): (mandatory)
> > + *   Get a handle from AE according to its name and options.
> > + *   the AE driver should manage the space used by handle and its queues while
> > + *   the HNAE framework will allocate desc and desc_cb for all rings in the
> > + *   queues.
> > + * put_handle():
> > + *   Release the handle.
> > + * start():
> > + *   Enable the hardware, include all queues
> > + * stop():
> > + *   Disable the hardware
> > + * set_opts(): (mandatory)
> > + *   Set options to the AE
> > + * get_opts(): (mandatory)
> > + *   Get options from the AE
> > + * get_status():
> > + *   Get the carrier state of the back channel of the handle, 1 for ok, 0 for
> > + *   non-ok
> > + * toggle_ring_irq(): (mandatory)
> > + *   Set the ring irq to be enabled(0) or disable(1)
> > + * toggle_queue_status(): (mandatory)
> > + *   Set the queue to be enabled(1) or disable(0), this will not change the
> > + *   ring irq state
> > + * adjust_link()
> > + *   adjust link status
> > + * set_loopback()
> > + *   set loopback
> > + * get_ring_bdnum_limit()
> > + *   get ring bd number limit
> > + * get_pauseparam()
> > + *   get tx and rx of pause frame use
> > + * set_autoneg()
> > + *   set auto autonegotiation of pause frame use
> > + * get_autoneg()
> > + *   get auto autonegotiation of pause frame use
> > + * set_pauseparam()
> > + *   set tx and rx of pause frame use
> > + * get_coalesce_usecs()
> > + *   get usecs to delay a TX interrupt after a packet is sent
> > + * get_rx_max_coalesced_frames()
> > + *   get Maximum number of packets to be sent before a TX interrupt.
> > + * set_coalesce_usecs()
> > + *   set usecs to delay a TX interrupt after a packet is sent
> > + * set_coalesce_frames()
> > + *   set Maximum number of packets to be sent before a TX interrupt.
> > + * get_ringnum()
> > + *   get RX/TX ring number
> > + * get_max_ringnum()
> > + *   get RX/TX ring maximum number
> > + * get_mac_addr()
> > + *   get mac address
> > + * set_mac_addr()
> > + *   set mac address
> > + * set_mc_addr()
> > + *   set multicast mode
> > + * set_mtu()
> > + *   set mtu
> > + * update_stats()
> > + *   update Old network device statistics
> > + * get_ethtool_stats()
> > + *   get ethtool network device statistics
> > + * get_strings()
> > + *   get a set of strings that describe the requested objects
> > + * get_sset_count()
> > + *   get number of strings that @get_strings will write
> > + * update_led_status()
> > + *   update the led status
> > + * set_led_id()
> > + *   set led id
> > + * get_regs()
> > + *   get regs dump
> > + * get_regs_len()
> > + *   get the len of the regs dump
> > + */
> > +struct hnae_ae_ops {
> > +       struct hnae_handle *(*get_handle)(struct hnae_ae_dev *dev,
> > +                                         const char *opts);
> > +       void (*put_handle)(struct hnae_handle *handle);
> > +       void (*init_queue)(struct hnae_queue *q);
> > +       void (*fini_queue)(struct hnae_queue *q);
> > +       int (*start)(struct hnae_handle *handle);
> > +       void (*stop)(struct hnae_handle *handle);
> > +       void (*reset)(struct hnae_handle *handle);
> > +       int (*set_opts)(struct hnae_handle *handle, int type, void *opts);
> > +       int (*get_opts)(struct hnae_handle *handle, int type, void **opts);
> > +       int (*get_status)(struct hnae_handle *handle);
> > +       int (*get_info)(struct hnae_handle *handle,
> > +                       u8 *auto_neg, u16 *speed, u8 *duplex);
> > +       int (*set_info)(struct hnae_handle *handle,
> > +                       u8 auto_neg, u16 speed, u8 duplex);
> > +       void (*toggle_ring_irq)(struct hnae_ring *ring, u32 val);
> > +       void (*toggle_queue_status)(struct hnae_queue *queue, u32 val);
> > +       void (*adjust_link)(struct hnae_handle *handle, int speed, int duplex);
> > +       int (*set_loopback)(struct hnae_handle *handle,
> > +                           enum hnae_loop loop_mode, int en);
> > +       void (*get_ring_bdnum_limit)(struct hnae_queue *queue,
> > +                                    u32 *uplimit, u32 *lowlimit);
> > +       void (*get_pauseparam)(struct hnae_handle *handle,
> > +                              u32 *auto_neg, u32 *rx_en, u32 *tx_en);
> > +       int (*set_autoneg)(struct hnae_handle *handle, u8 enable);
> > +       int (*get_autoneg)(struct hnae_handle *handle);
> > +       void (*set_pauseparam)(struct hnae_handle *handle,
> > +                              u32 rx_en, u32 tx_en);
> > +       void (*get_coalesce_usecs)(struct hnae_handle *handle,
> > +                                  u32 *tx_usecs, u32 *rx_usecs);
> > +       void (*get_rx_max_coalesced_frames)(struct hnae_handle *handle,
> > +                                           u32 *tx_frames, u32 *rx_frames);
> > +       void (*set_coalesce_usecs)(struct hnae_handle *handle, u32 timeout);
> > +       int (*set_coalesce_frames)(struct hnae_handle *handle,
> > +                                  u32 coalesce_frames);
> > +       void (*get_ringnum)(struct hnae_handle *handle, u32 *ringnum);
> > +       void (*get_max_ringnum)(struct hnae_handle *handle, u32 *max_ringnum);
> > +       int (*get_mac_addr)(struct hnae_handle *handle, void **p);
> > +       int (*set_mac_addr)(struct hnae_handle *handle, void *p);
> > +       int (*set_mc_addr)(struct hnae_handle *handle, void *addr);
> > +       int (*set_mtu)(struct hnae_handle *handle, int new_mtu);
> > +       void (*update_stats)(struct hnae_handle *handle,
> > +                            struct net_device_stats *net_stats);
> > +       void (*get_stats)(struct hnae_handle *handle, u64 *data);
> > +       void (*get_strings)(struct hnae_handle *handle,
> > +                           u32 stringset, u8 *data);
> > +       int (*get_sset_count)(struct hnae_handle *handle, int stringset);
> > +       void (*update_led_status)(struct hnae_handle *handle);
> > +       int (*set_led_id)(struct hnae_handle *handle,
> > +                         enum hnae_led_state status);
> > +       void (*get_regs)(struct hnae_handle *handle, void *data);
> > +       int (*get_regs_len)(struct hnae_handle *handle);
> > +};
> > +
> > +struct hnae_ae_dev {
> > +       struct device cls_dev; /* the class dev */
> > +       struct device *dev; /* the presented dev */
> > +       struct hnae_ae_ops *ops;
> > +       struct list_head node;
> > +       struct module *owner; /* the module who provides this dev */
> > +       int id;
> > +       char name[AE_NAME_SIZE];
> > +       struct list_head handle_list;
> > +       spinlock_t lock; /* lock to protect the handle_list */
> > +};
> > +
> > +struct hnae_handle {
> > +       struct device *owner_dev; /* the device which make use of this handle */
> > +       struct hnae_ae_dev *dev;  /* the device who provides this handle */
> > +       struct device_node *phy_node;
> > +       phy_interface_t phy_if;
> > +       u32 if_support;
> > +       int q_num;
> > +       const char *ae_opts;
> > +       enum hnae_port_type port_type;
> > +       struct list_head node;    /* list to hnae_ae_dev->handle_list */
> > +       struct hnae_buf_ops *bops; /* operation for the buffer */
> > +       struct net_device_stats net_stats;
> > +       struct hnae_queue **qs;  /* array base of all queues */
> > +};
> > +
> > +#define ring_to_dev(ring) ((ring)->q->dev->dev)
> > +
> > +struct hnae_handle *hnae_get_handle(struct device *owner_dev, const char *ae_id,
> > +                                   const char *ae_opts,
> > +                                   struct hnae_buf_ops *bops);
> > +void hnae_put_handle(struct hnae_handle *handle);
> > +int hnae_ae_register(struct hnae_ae_dev *dev, struct module *owner);
> > +void hnae_ae_unregister(struct hnae_ae_dev *dev);
> > +
> > +int hnae_register_notifier(struct notifier_block *nb);
> > +void hnae_unregister_notifier(struct notifier_block *nb);
> > +int hnae_reinit_handle(struct hnae_handle *handle);
> > +
> > +#define hnae_queue_xmit(q, buf_num) writel_relaxed(buf_num, \
> > +       (q)->tx_ring.io_base + RCB_REG_TAIL)
> > +
> > +#ifndef assert
> > +#define assert(cond)
> > +#endif
> > +
> > +static inline int hnae_reserve_buffer_map(struct hnae_ring *ring,
> > +                                         struct hnae_desc_cb *cb)
> > +{
> > +       struct hnae_buf_ops *bops = ring->q->handle->bops;
> > +       int ret;
> > +
> > +       ret = bops->alloc_buffer(ring, cb);
> > +       if (ret)
> > +               goto out;
> > +
> > +       ret = bops->map_buffer(ring, cb);
> > +       if (ret)
> > +               goto out_with_buf;
> > +
> > +       return 0;
> > +
> > +out_with_buf:
> > +       bops->free_buffer(ring, cb);
> > +out:
> > +       return ret;
> > +}
> > +
> > +static inline int hnae_alloc_buffer_attach(struct hnae_ring *ring, int i)
> > +{
> > +       int ret = hnae_reserve_buffer_map(ring, &ring->desc_cb[i]);
> > +
> > +       if (ret)
> > +               return ret;
> > +
> > +       ring->desc[i].addr = (__le64)ring->desc_cb[i].dma;
> > +
> > +       return 0;
> > +}
> > +
> > +static inline void hnae_buffer_detach(struct hnae_ring *ring, int i)
> > +{
> > +       ring->q->handle->bops->unmap_buffer(ring, &ring->desc_cb[i]);
> > +       ring->desc[i].addr = 0;
> > +}
> > +
> > +static inline void hnae_free_buffer_detach(struct hnae_ring *ring, int i)
> > +{
> > +       struct hnae_buf_ops *bops = ring->q->handle->bops;
> > +       struct hnae_desc_cb *cb = &ring->desc_cb[i];
> > +
> > +       if (!ring->desc_cb[i].dma)
> > +               return;
> > +
> > +       hnae_buffer_detach(ring, i);
> > +       bops->free_buffer(ring, cb);
> > +}
> > +
> > +/* detach a in-used buffer and replace with a reserved one  */
> > +static inline void hnae_replace_buffer(struct hnae_ring *ring, int i,
> > +                                      struct hnae_desc_cb *res_cb)
> > +{
> > +       struct hnae_buf_ops *bops = ring->q->handle->bops;
> > +       struct hnae_desc_cb tmp_cb = ring->desc_cb[i];
> > +
> > +       bops->unmap_buffer(ring, &ring->desc_cb[i]);
> > +       ring->desc_cb[i] = *res_cb;
> > +       *res_cb = tmp_cb;
> > +       ring->desc[i].addr = (__le64)ring->desc_cb[i].dma;
> > +       ring->desc[i].rx.ipoff_bnum_pid_flag = 0;
> > +}
> > +
> > +static inline void hnae_reuse_buffer(struct hnae_ring *ring, int i)
> > +{
> > +       ring->desc_cb[i].reuse_flag = 0;
> > +       ring->desc[i].addr = (__le64)(ring->desc_cb[i].dma
> > +               + ring->desc_cb[i].page_offset);
> > +       ring->desc[i].rx.ipoff_bnum_pid_flag = 0;
> > +}
> > +
> > +#define hnae_set_field(origin, mask, shift, val) \
> > +       do { \
> > +               (origin) &= (~(mask)); \
> > +               (origin) |= ((val) << (shift)) & (mask); \
> > +       } while (0)
> > +
> > +#define hnae_set_bit(origin, shift, val) \
> > +       hnae_set_field((origin), (0x1 << (shift)), (shift), (val))
> > +
> > +#define hnae_get_field(origin, mask, shift) (((origin) & (mask)) >> (shift))
> > +
> > +#define hnae_get_bit(origin, shift) \
> > +       hnae_get_field((origin), (0x1 << (shift)), (shift))
> > +
> > +#endif
> > --
> > 1.9.1
> >
> >
> > _______________________________________________
> > linux-arm-kernel mailing list
> > linux-arm-kernel at lists.infradead.org
> > http://lists.infradead.org/mailman/listinfo/linux-arm-kernel
> 
> 
> 
> -- 
> Best regards, Klimov Alexey


From jh80.chung at samsung.com  Thu Aug 20 23:35:34 2015
From: jh80.chung at samsung.com (Jaehoon Chung)
Date: Fri, 21 Aug 2015 15:35:34 +0900
Subject: [RFC PATCH v6 1/9] mmc: dw_mmc: Add external dma interface support
In-Reply-To: <55D6C57D.4070402@rock-chips.com>
References: <1440060204-26203-1-git-send-email-shawn.lin@rock-chips.com>
 <1440060233-26244-1-git-send-email-shawn.lin@rock-chips.com>
 <55D6C4D4.8010005@samsung.com> <55D6C57D.4070402@rock-chips.com>
Message-ID: <55D6C6B6.3060706@samsung.com>

On 08/21/2015 03:30 PM, Shawn Lin wrote:
> On 2015/8/21 14:27, Jaehoon Chung wrote:
>> Hi, Shawn.
>>
>> Is this based on Ulf's repository?
> 
> 
> no, it's based on "https://github.com/jh80chung/dw-mmc.git tags/dw-mmc-for-ulf-v4.2" ??

Oh..I will rebase to Ulf's next branch on this weekend.
Then could you rebase this patch? And i added more comments at below.. :)

Best Regards,
Jaehoon Chung

> 
>>
>> On 08/20/2015 05:43 PM, Shawn Lin wrote:
>>> DesignWare MMC Controller can supports two types of DMA
>>> mode: external dma and internal dma. We get a RK312x platform
>>> integrated dw_mmc and ARM pl330 dma controller. This patch add
>>> edmac ops to support these platforms. I've tested it on RK31xx
>>> platform with edmac mode and RK3288 platform with idmac mode.
>>>
>>> Signed-off-by: Shawn Lin <shawn.lin at rock-chips.com>
>>>
>>> ---
>>>
>>> Changes in v6:
>>> - add trans_mode condition for IDMAC initialization
>>>    suggested by Heiko
>>> - re-test my patch on rk3188 platform and update commit msg
>>> - update performance of pio vs edmac in cover letter
>>>
>>> Changes in v5:
>>> - add the title of cover letter
>>> - fix typo of comment
>>> - add macro for reading HCON register
>>> - add "Acked-by: Krzysztof Kozlowski <k.kozlowski at samsung.com>" for exynos_defconfig patch
>>> - add "Acked-by: Vineet Gupta <vgupta at synopsys.com>" for axs10x_defconfig patch
>>> - add "Acked-by: Govindraj Raja <govindraj.raja at imgtec.com>" and
>>>    "Acked-by: Ralf Baechle <ralf at linux-mips.org>" for pistachio_defconfig patch
>>> - add "Acked-by: Joachim Eastwood <manabian at gmail.com>" for lpc18xx_defconfig patch
>>> - add "Acked-by: Wei Xu <xuwei5 at hisilicon.com>" for hisi_defconfig patch
>>> - rebase on "https://github.com/jh80chung/dw-mmc.git tags/dw-mmc-for-ulf-v4.2" for merging easily
>>>
>>> Changes in v4:
>>> - remove "host->trans_mode" and use "host->use_dma" to indicate
>>>    transfer mode.
>>> - remove all bt-bindings' changes since we don't need new properities.
>>> - check transfer mode at runtime by reading HCON reg
>>> - spilt defconfig changes for each sub-architecture
>>> - fix the title of cover letter
>>> - reuse some code for reducing code size
>>>
>>> Changes in v3:
>>> - choose transfer mode at runtime
>>> - remove all CONFIG_MMC_DW_IDMAC config option
>>> - add supports-idmac property for some platforms
>>>
>>> Changes in v2:
>>> - Fix typo of dev_info msg
>>> - remove unused dmach from declaration of dw_mci_dma_slave
>>>
>>>   drivers/mmc/host/Kconfig        |  11 +-
>>>   drivers/mmc/host/dw_mmc-pltfm.c |   2 +
>>>   drivers/mmc/host/dw_mmc.c       | 264 ++++++++++++++++++++++++++++++++--------
>>>   drivers/mmc/host/dw_mmc.h       |   5 +
>>>   include/linux/mmc/dw_mmc.h      |  27 +++-
>>>   5 files changed, 242 insertions(+), 67 deletions(-)
>>>
>>> diff --git a/drivers/mmc/host/Kconfig b/drivers/mmc/host/Kconfig
>>> index 6a0f9c7..a86c0eb 100644
>>> --- a/drivers/mmc/host/Kconfig
>>> +++ b/drivers/mmc/host/Kconfig
>>> @@ -607,15 +607,7 @@ config MMC_DW
>>>       help
>>>         This selects support for the Synopsys DesignWare Mobile Storage IP
>>>         block, this provides host support for SD and MMC interfaces, in both
>>> -      PIO and external DMA modes.
>>> -
>>> -config MMC_DW_IDMAC
>>> -    bool "Internal DMAC interface"
>>> -    depends on MMC_DW
>>> -    help
>>> -      This selects support for the internal DMAC block within the Synopsys
>>> -      Designware Mobile Storage IP block. This disables the external DMA
>>> -      interface.
>>> +      PIO, internal DMA mode and external DMA modes.
>>>
>>>   config MMC_DW_PLTFM
>>>       tristate "Synopsys Designware MCI Support as platform device"
>>> @@ -644,7 +636,6 @@ config MMC_DW_K3
>>>       tristate "K3 specific extensions for Synopsys DW Memory Card Interface"
>>>       depends on MMC_DW
>>>       select MMC_DW_PLTFM
>>> -    select MMC_DW_IDMAC
>>>       help
>>>         This selects support for Hisilicon K3 SoC specific extensions to the
>>>         Synopsys DesignWare Memory Card Interface driver. Select this option
>>> diff --git a/drivers/mmc/host/dw_mmc-pltfm.c b/drivers/mmc/host/dw_mmc-pltfm.c
>>> index ec6dbcd..7e1d13b 100644
>>> --- a/drivers/mmc/host/dw_mmc-pltfm.c
>>> +++ b/drivers/mmc/host/dw_mmc-pltfm.c
>>> @@ -59,6 +59,8 @@ int dw_mci_pltfm_register(struct platform_device *pdev,
>>>       host->pdata = pdev->dev.platform_data;
>>>
>>>       regs = platform_get_resource(pdev, IORESOURCE_MEM, 0);
>>> +    /* Get registers' physical base address */
>>> +    host->phy_regs = (void *)(regs->start);
>>>       host->regs = devm_ioremap_resource(&pdev->dev, regs);
>>>       if (IS_ERR(host->regs))
>>>           return PTR_ERR(host->regs);
>>
>> Is this board specific code? If so, separate the patch.
>>
>>> diff --git a/drivers/mmc/host/dw_mmc.c b/drivers/mmc/host/dw_mmc.c
>>> index fcbf552..f943619 100644
>>> --- a/drivers/mmc/host/dw_mmc.c
>>> +++ b/drivers/mmc/host/dw_mmc.c
>>> @@ -56,7 +56,6 @@
>>>   #define DW_MCI_FREQ_MAX    200000000    /* unit: HZ */
>>>   #define DW_MCI_FREQ_MIN    400000        /* unit: HZ */
>>>
>>> -#ifdef CONFIG_MMC_DW_IDMAC
>>>   #define IDMAC_INT_CLR        (SDMMC_IDMAC_INT_AI | SDMMC_IDMAC_INT_NI | \
>>>                    SDMMC_IDMAC_INT_CES | SDMMC_IDMAC_INT_DU | \
>>>                    SDMMC_IDMAC_INT_FBE | SDMMC_IDMAC_INT_RI | \
>>> @@ -102,7 +101,6 @@ struct idmac_desc {
>>>
>>>   /* Each descriptor can transfer up to 4KB of data in chained mode */
>>>   #define DW_MCI_DESC_DATA_LENGTH    0x1000
>>> -#endif /* CONFIG_MMC_DW_IDMAC */
>>>
>>>   static bool dw_mci_reset(struct dw_mci *host);
>>>   static bool dw_mci_ctrl_reset(struct dw_mci *host, u32 reset);
>>> @@ -407,7 +405,6 @@ static int dw_mci_get_dma_dir(struct mmc_data *data)
>>>           return DMA_FROM_DEVICE;
>>>   }
>>>
>>> -#ifdef CONFIG_MMC_DW_IDMAC
>>>   static void dw_mci_dma_cleanup(struct dw_mci *host)
>>>   {
>>>       struct mmc_data *data = host->data;
>>> @@ -445,12 +442,21 @@ static void dw_mci_idmac_stop_dma(struct dw_mci *host)
>>>       mci_writel(host, BMOD, temp);
>>>   }
>>>
>>> -static void dw_mci_idmac_complete_dma(struct dw_mci *host)
>>> +static void dw_mci_dmac_complete_dma(void *arg)
>>>   {
>>> +    struct dw_mci *host = arg;
>>>       struct mmc_data *data = host->data;
>>>
>>>       dev_vdbg(host->dev, "DMA complete\n");
>>>
>>> +    if (host->use_dma == TRANS_MODE_EDMAC)
>>> +        if (data && (data->flags & MMC_DATA_READ))
>>
>> Combine one condition.
>>
>>> +            /* Invalidate cache after read */
>>> +            dma_sync_sg_for_cpu(mmc_dev(host->cur_slot->mmc),
>>> +                        data->sg,
>>> +                        data->sg_len,
>>> +                        DMA_FROM_DEVICE);
>>> +
>>>       host->dma_ops->cleanup(host);
>>>
>>>       /*
>>> @@ -564,7 +570,7 @@ static void dw_mci_translate_sglist(struct dw_mci *host, struct mmc_data *data,
>>>       wmb(); /* drain writebuffer */
>>>   }
>>>
>>> -static void dw_mci_idmac_start_dma(struct dw_mci *host, unsigned int sg_len)
>>> +static int dw_mci_idmac_start_dma(struct dw_mci *host, unsigned int sg_len)
>>>   {
>>>       u32 temp;
>>>
>>> @@ -589,6 +595,8 @@ static void dw_mci_idmac_start_dma(struct dw_mci *host, unsigned int sg_len)
>>>
>>>       /* Start it running */
>>>       mci_writel(host, PLDMND, 1);
>>> +
>>> +    return 0;
>>>   }
>>>
>>>   static int dw_mci_idmac_init(struct dw_mci *host)
>>> @@ -669,10 +677,112 @@ static const struct dw_mci_dma_ops dw_mci_idmac_ops = {
>>>       .init = dw_mci_idmac_init,
>>>       .start = dw_mci_idmac_start_dma,
>>>       .stop = dw_mci_idmac_stop_dma,
>>> -    .complete = dw_mci_idmac_complete_dma,
>>> +    .complete = dw_mci_dmac_complete_dma,
>>> +    .cleanup = dw_mci_dma_cleanup,
>>> +};
>>> +
>>> +static void dw_mci_edmac_stop_dma(struct dw_mci *host)
>>> +{
>>> +    dmaengine_terminate_all(host->dms->ch);
>>> +}
>>> +
>>> +static int dw_mci_edmac_start_dma(struct dw_mci *host,
>>> +                        unsigned int sg_len)
>>> +{
>>> +    struct dma_slave_config cfg;
>>> +    struct dma_async_tx_descriptor *desc = NULL;
>>> +    struct scatterlist *sgl = host->data->sg;
>>> +    const u32 mszs[] = {1, 4, 8, 16, 32, 64, 128, 256};
>>> +    u32 sg_elems = host->data->sg_len;
>>> +    u32 fifoth_val;
>>> +    u32 fifo_offset = host->fifo_reg - host->regs;
>>> +    int ret = 0;
>>> +
>>> +    /* Set external dma config: burst size, burst width */
>>> +    cfg.dst_addr = (dma_addr_t)(host->phy_regs + fifo_offset);
>>
>> host->phy_regs is not assigned?
>>
>>> +    cfg.src_addr = cfg.dst_addr;
>>> +    cfg.dst_addr_width = DMA_SLAVE_BUSWIDTH_4_BYTES;
>>> +    cfg.src_addr_width = DMA_SLAVE_BUSWIDTH_4_BYTES;
>>> +
>>> +    /* Match burst msize with external dma config */
>>> +    fifoth_val = mci_readl(host, FIFOTH);
>>> +    cfg.dst_maxburst = mszs[(fifoth_val >> 28) & 0x7];
>>> +    cfg.src_maxburst = cfg.dst_maxburst;
>>> +
>>> +    if (host->data->flags & MMC_DATA_WRITE)
>>> +        cfg.direction = DMA_MEM_TO_DEV;
>>> +    else /* MMC_DATA_READ */
>>> +        cfg.direction = DMA_DEV_TO_MEM;
>>> +
>>> +    ret = dmaengine_slave_config(host->dms->ch, &cfg);
>>> +    if (ret) {
>>> +        dev_err(host->dev, "Failed to config edmac.\n");
>>> +        return -EBUSY;
>>> +    }
>>> +
>>> +    desc = dmaengine_prep_slave_sg(host->dms->ch, sgl,
>>> +                       sg_len, cfg.direction,
>>> +                       DMA_PREP_INTERRUPT | DMA_CTRL_ACK);
>>> +    if (!desc) {
>>> +        dev_err(host->dev, "Can't prepare slave sg.\n");
>>> +        return -EBUSY;
>>> +    }
>>> +
>>> +    /* Set dw_mci_dmac_complete_dma as callback */
>>> +    desc->callback = dw_mci_dmac_complete_dma;
>>> +    desc->callback_param = (void *)host;
>>> +    dmaengine_submit(desc);
>>> +
>>> +    /* Flush cache before write */
>>> +    if (host->data->flags & MMC_DATA_WRITE)
>>> +        dma_sync_sg_for_device(mmc_dev(host->cur_slot->mmc), sgl,
>>> +                       sg_elems, DMA_TO_DEVICE);
>>> +
>>> +    dma_async_issue_pending(host->dms->ch);
>>> +
>>> +    return 0;
>>> +}
>>> +
>>> +static int dw_mci_edmac_init(struct dw_mci *host)
>>> +{
>>> +    /* Request external dma channel */
>>> +    host->dms = kzalloc(sizeof(struct dw_mci_dma_slave), GFP_KERNEL);
>>> +    if (!host->dms)
>>> +        return -ENOMEM;
>>> +
>>> +    host->dms->ch = dma_request_slave_channel(host->dev, "rx-tx");
>>> +    if (!host->dms->ch) {
>>> +        dev_err(host->dev,
>>> +            "Failed to get external DMA channel %d\n",
>>> +            host->dms->ch->chan_id);
>>> +        kfree(host->dms);
>>> +        host->dms = NULL;
>>> +        return -ENXIO;
>>> +    }
>>> +
>>> +    return 0;
>>> +}
>>> +
>>> +static void dw_mci_edmac_exit(struct dw_mci *host)
>>> +{
>>> +    if (host->dms) {
>>> +        if (host->dms->ch) {
>>> +            dma_release_channel(host->dms->ch);
>>> +            host->dms->ch = NULL;
>>> +        }
>>> +        kfree(host->dms);
>>> +        host->dms = NULL;
>>> +    }
>>> +}
>>> +
>>> +static const struct dw_mci_dma_ops dw_mci_edmac_ops = {
>>> +    .init = dw_mci_edmac_init,
>>> +    .exit = dw_mci_edmac_exit,
>>> +    .start = dw_mci_edmac_start_dma,
>>> +    .stop = dw_mci_edmac_stop_dma,
>>> +    .complete = dw_mci_dmac_complete_dma,
>>>       .cleanup = dw_mci_dma_cleanup,
>>>   };
>>> -#endif /* CONFIG_MMC_DW_IDMAC */
>>>
>>>   static int dw_mci_pre_dma_transfer(struct dw_mci *host,
>>>                      struct mmc_data *data,
>>> @@ -752,7 +862,6 @@ static void dw_mci_post_req(struct mmc_host *mmc,
>>>
>>>   static void dw_mci_adjust_fifoth(struct dw_mci *host, struct mmc_data *data)
>>>   {
>>> -#ifdef CONFIG_MMC_DW_IDMAC
>>>       unsigned int blksz = data->blksz;
>>>       const u32 mszs[] = {1, 4, 8, 16, 32, 64, 128, 256};
>>>       u32 fifo_width = 1 << host->data_shift;
>>> @@ -760,6 +869,10 @@ static void dw_mci_adjust_fifoth(struct dw_mci *host, struct mmc_data *data)
>>>       u32 msize = 0, rx_wmark = 1, tx_wmark, tx_wmark_invers;
>>>       int idx = ARRAY_SIZE(mszs) - 1;
>>>
>>> +    /* pio should ship this scenario */
>>> +    if (!host->use_dma)
>>> +        return;
>>> +
>>>       tx_wmark = (host->fifo_depth) / 2;
>>>       tx_wmark_invers = host->fifo_depth - tx_wmark;
>>>
>>> @@ -788,7 +901,6 @@ static void dw_mci_adjust_fifoth(struct dw_mci *host, struct mmc_data *data)
>>>   done:
>>>       fifoth_val = SDMMC_SET_FIFOTH(msize, rx_wmark, tx_wmark);
>>>       mci_writel(host, FIFOTH, fifoth_val);
>>> -#endif
>>>   }
>>>
>>>   static void dw_mci_ctrl_rd_thld(struct dw_mci *host, struct mmc_data *data)
>>> @@ -850,10 +962,12 @@ static int dw_mci_submit_data_dma(struct dw_mci *host, struct mmc_data *data)
>>>
>>>       host->using_dma = 1;
>>>
>>> -    dev_vdbg(host->dev,
>>> -         "sd sg_cpu: %#lx sg_dma: %#lx sg_len: %d\n",
>>> -         (unsigned long)host->sg_cpu, (unsigned long)host->sg_dma,
>>> -         sg_len);
>>> +    if (host->use_dma == TRANS_MODE_IDMAC)
>>> +        dev_vdbg(host->dev,
>>> +             "sd sg_cpu: %#lx sg_dma: %#lx sg_len: %d\n",
>>> +             (unsigned long)host->sg_cpu,
>>> +             (unsigned long)host->sg_dma,
>>> +             sg_len);
>>>
>>>       /*
>>>        * Decide the MSIZE and RX/TX Watermark.
>>> @@ -875,7 +989,11 @@ static int dw_mci_submit_data_dma(struct dw_mci *host, struct mmc_data *data)
>>>       mci_writel(host, INTMASK, temp);
>>>       spin_unlock_irqrestore(&host->irq_lock, irqflags);
>>>
>>> -    host->dma_ops->start(host, sg_len);
>>> +    if (host->dma_ops->start(host, sg_len)) {
>>> +        /* We can't do DMA */
>>> +        dev_err(host->dev, "%s: failed to start DMA.\n", __func__);
>>> +        return -ENODEV;
>>> +    }
>>>
>>>       return 0;
>>>   }
>>> @@ -2343,15 +2461,17 @@ static irqreturn_t dw_mci_interrupt(int irq, void *dev_id)
>>>
>>>       }
>>>
>>> -#ifdef CONFIG_MMC_DW_IDMAC
>>> -    /* Handle DMA interrupts */
>>> +    if (host->use_dma != TRANS_MODE_IDMAC)
>>> +        return IRQ_HANDLED;
>>> +
>>> +    /* Handle IDMA interrupts */
>>>       if (host->dma_64bit_address == 1) {
>>>           pending = mci_readl(host, IDSTS64);
>>>           if (pending & (SDMMC_IDMAC_INT_TI | SDMMC_IDMAC_INT_RI)) {
>>>               mci_writel(host, IDSTS64, SDMMC_IDMAC_INT_TI |
>>>                               SDMMC_IDMAC_INT_RI);
>>>               mci_writel(host, IDSTS64, SDMMC_IDMAC_INT_NI);
>>> -            host->dma_ops->complete(host);
>>> +            host->dma_ops->complete((void *)host);
>>>           }
>>>       } else {
>>>           pending = mci_readl(host, IDSTS);
>>> @@ -2359,10 +2479,9 @@ static irqreturn_t dw_mci_interrupt(int irq, void *dev_id)
>>>               mci_writel(host, IDSTS, SDMMC_IDMAC_INT_TI |
>>>                               SDMMC_IDMAC_INT_RI);
>>>               mci_writel(host, IDSTS, SDMMC_IDMAC_INT_NI);
>>> -            host->dma_ops->complete(host);
>>> +            host->dma_ops->complete((void *)host);
>>>           }
>>>       }
>>> -#endif
>>>
>>>       return IRQ_HANDLED;
>>>   }
>>> @@ -2471,13 +2590,21 @@ static int dw_mci_init_slot(struct dw_mci *host, unsigned int id)
>>>           goto err_host_allocated;
>>>
>>>       /* Useful defaults if platform data is unset. */
>>> -    if (host->use_dma) {
>>> +    if (host->use_dma == TRANS_MODE_IDMAC) {
>>>           mmc->max_segs = host->ring_size;
>>>           mmc->max_blk_size = 65536;
>>>           mmc->max_seg_size = 0x1000;
>>>           mmc->max_req_size = mmc->max_seg_size * host->ring_size;
>>>           mmc->max_blk_count = mmc->max_req_size / 512;
>>> +    } else if (host->use_dma == TRANS_MODE_EDMAC) {
>>> +            mmc->max_segs = 64;
>>> +            mmc->max_blk_size = 65536;
>>> +            mmc->max_blk_count = 65535;
>>> +            mmc->max_req_size =
>>> +                    mmc->max_blk_size * mmc->max_blk_count;
>>> +            mmc->max_seg_size = mmc->max_req_size;
>>
>> Fix the indention
>>
>>>       } else {
>>> +        /* TRANS_MODE_PIO */
>>>           mmc->max_segs = 64;
>>>           mmc->max_blk_size = 65536; /* BLKSIZ is 16 bits */
>>>           mmc->max_blk_count = 512;
>>> @@ -2517,35 +2644,66 @@ static void dw_mci_cleanup_slot(struct dw_mci_slot *slot, unsigned int id)
>>>   static void dw_mci_init_dma(struct dw_mci *host)
>>>   {
>>>       int addr_config;
>>> -    /* Check ADDR_CONFIG bit in HCON to find IDMAC address bus width */
>>> -    addr_config = (mci_readl(host, HCON) >> 27) & 0x01;
>>> -
>>> -    if (addr_config == 1) {
>>> -        /* host supports IDMAC in 64-bit address mode */
>>> -        host->dma_64bit_address = 1;
>>> -        dev_info(host->dev, "IDMAC supports 64-bit address mode.\n");
>>> -        if (!dma_set_mask(host->dev, DMA_BIT_MASK(64)))
>>> -            dma_set_coherent_mask(host->dev, DMA_BIT_MASK(64));
>>> -    } else {
>>> -        /* host supports IDMAC in 32-bit address mode */
>>> -        host->dma_64bit_address = 0;
>>> -        dev_info(host->dev, "IDMAC supports 32-bit address mode.\n");
>>> -    }
>>> +    int trans_mode;
>>> +    struct device *dev = host->dev;
>>> +    struct device_node *np = dev->of_node;
>>>
>>> -    /* Alloc memory for sg translation */
>>> -    host->sg_cpu = dmam_alloc_coherent(host->dev, PAGE_SIZE,
>>> -                      &host->sg_dma, GFP_KERNEL);
>>> -    if (!host->sg_cpu) {
>>> -        dev_err(host->dev, "%s: could not alloc DMA memory\n",
>>> -            __func__);
>>> +    /* Check tansfer mode */
>>> +    trans_mode = SDMMC_GET_TRANS_MODE(mci_readl(host, HCON));
>>> +    if (trans_mode == 0) {
>>> +        trans_mode = TRANS_MODE_IDMAC;
>>> +    } else if (trans_mode == 1 || trans_mode == 2) {
>>> +        trans_mode = TRANS_MODE_EDMAC;
>>> +    } else {
>>> +        trans_mode = TRANS_MODE_PIO;
>>
>> what are trans_mode "0, 1, 2"?
>> (00 - none) is NO-DMA interface, isn't? is it IDMAC mode?
>>
>>>           goto no_dma;
>>>       }
>>>
>>>       /* Determine which DMA interface to use */
>>> -#ifdef CONFIG_MMC_DW_IDMAC
>>> -    host->dma_ops = &dw_mci_idmac_ops;
>>> -    dev_info(host->dev, "Using internal DMA controller.\n");
>>> -#endif
>>> +    if (trans_mode == TRANS_MODE_IDMAC) {
>>> +        /*
>>> +        * Check ADDR_CONFIG bit in HCON to find
>>> +        * IDMAC address bus width
>>> +        */
>>> +        addr_config = SDMMC_GET_ADDR_CONFIG(mci_readl(host, HCON));
>>> +
>>> +        if (addr_config == 1) {
>>> +            /* host supports IDMAC in 64-bit address mode */
>>> +            host->dma_64bit_address = 1;
>>> +            dev_info(host->dev,
>>> +                 "IDMAC supports 64-bit address mode.\n");
>>> +            if (!dma_set_mask(host->dev, DMA_BIT_MASK(64)))
>>> +                dma_set_coherent_mask(host->dev,
>>> +                              DMA_BIT_MASK(64));
>>> +        } else {
>>> +            /* host supports IDMAC in 32-bit address mode */
>>> +            host->dma_64bit_address = 0;
>>> +            dev_info(host->dev,
>>> +                 "IDMAC supports 32-bit address mode.\n");
>>> +        }
>>> +
>>> +        /* Alloc memory for sg translation */
>>> +        host->sg_cpu = dmam_alloc_coherent(host->dev, PAGE_SIZE,
>>> +                           &host->sg_dma, GFP_KERNEL);
>>> +        if (!host->sg_cpu) {
>>> +            dev_err(host->dev,
>>> +                "%s: could not alloc DMA memory\n",
>>> +                __func__);
>>> +            goto no_dma;
>>> +        }
>>> +
>>> +        host->dma_ops = &dw_mci_idmac_ops;
>>> +        dev_info(host->dev, "Using internal DMA controller.\n");
>>> +    } else {
>>> +        /* TRANS_MODE_EDMAC: check dma bindings again */
>>> +        if ((of_property_count_strings(np, "dma-names") < 0) ||
>>> +            (!of_find_property(np, "dmas", NULL))) {
>>> +            trans_mode = TRANS_MODE_PIO;
>>> +            goto no_dma;
>>> +        }
>>> +        host->dma_ops = &dw_mci_edmac_ops;
>>> +        dev_info(host->dev, "Using external DMA controller.\n");
>>> +    }
>>>
>>>       if (!host->dma_ops)
>>>           goto no_dma;
>>> @@ -2562,12 +2720,12 @@ static void dw_mci_init_dma(struct dw_mci *host)
>>>           goto no_dma;
>>>       }
>>>
>>> -    host->use_dma = 1;
>>> +    host->use_dma = trans_mode;
>>
>> Also confuse, if trans_mode is assigned host->use_dma, can mode value be directly assigned to host->use_dma?
>>
>> trans_mode = TRAMS_MODE_PIO;
>> host->use_dma = trans_mode;
>>
>> -> host->use_dma = TRAMS_MODE_PIO;
>>
>> Then trans_mode can be removed.
>>
>>>       return;
>>>
>>>   no_dma:
>>>       dev_info(host->dev, "Using PIO mode.\n");
>>> -    host->use_dma = 0;
>>> +    host->use_dma = trans_mode;
>>>   }
>>>
>>>   static bool dw_mci_ctrl_reset(struct dw_mci *host, u32 reset)
>>> @@ -2650,10 +2808,9 @@ static bool dw_mci_reset(struct dw_mci *host)
>>>           }
>>>       }
>>>
>>> -#if IS_ENABLED(CONFIG_MMC_DW_IDMAC)
>>> -    /* It is also recommended that we reset and reprogram idmac */
>>> -    dw_mci_idmac_reset(host);
>>> -#endif
>>> +    if (host->use_dma == TRANS_MODE_IDMAC)
>>> +        /* It is also recommended that we reset and reprogram idmac */
>>> +        dw_mci_idmac_reset(host);
>>>
>>>       ret = true;
>>>
>>> @@ -2890,7 +3047,7 @@ int dw_mci_probe(struct dw_mci *host)
>>>        * Get the host data width - this assumes that HCON has been set with
>>>        * the correct values.
>>>        */
>>> -    i = (mci_readl(host, HCON) >> 7) & 0x7;
>>> +    i = SDMMC_GET_HDATA_WIDTH(mci_readl(host, HCON));
>>
>> This is not related with supporting external dma interface.
>> Separate this.
>>
>>>       if (!i) {
>>>           host->push_data = dw_mci_push_data16;
>>>           host->pull_data = dw_mci_pull_data16;
>>> @@ -2972,7 +3129,7 @@ int dw_mci_probe(struct dw_mci *host)
>>>       if (host->pdata->num_slots)
>>>           host->num_slots = host->pdata->num_slots;
>>>       else
>>> -        host->num_slots = ((mci_readl(host, HCON) >> 1) & 0x1F) + 1;
>>> +        host->num_slots = SDMMC_GET_SLOT_NUM(mci_readl(host, HCON));
>>
>> Ditto. (with above.)
>>
>>>
>>>       /*
>>>        * Enable interrupts for command done, data over, data empty,
>>> @@ -3067,6 +3224,9 @@ EXPORT_SYMBOL(dw_mci_remove);
>>>    */
>>>   int dw_mci_suspend(struct dw_mci *host)
>>>   {
>>> +    if (host->use_dma && host->dma_ops->exit)
>>> +        host->dma_ops->exit(host);
>>> +
>>>       return 0;
>>>   }
>>>   EXPORT_SYMBOL(dw_mci_suspend);
>>> diff --git a/drivers/mmc/host/dw_mmc.h b/drivers/mmc/host/dw_mmc.h
>>> index 8ce4674..c453e94 100644
>>> --- a/drivers/mmc/host/dw_mmc.h
>>> +++ b/drivers/mmc/host/dw_mmc.h
>>> @@ -148,6 +148,11 @@
>>>   #define SDMMC_SET_FIFOTH(m, r, t)    (((m) & 0x7) << 28 | \
>>>                        ((r) & 0xFFF) << 16 | \
>>>                        ((t) & 0xFFF))
>>> +/* HCON register defines */
>>> +#define SDMMC_GET_SLOT_NUM(x)        ((((x)>>1) & 0x1F) + 1)
>>> +#define SDMMC_GET_HDATA_WIDTH(x)    (((x)>>7) & 0x7)
>>> +#define SDMMC_GET_TRANS_MODE(x)        (((x)>>16) & 0x3)
>>> +#define SDMMC_GET_ADDR_CONFIG(x)    (((x)>>27) & 0x1)
>>>   /* Internal DMAC interrupt defines */
>>>   #define SDMMC_IDMAC_INT_AI        BIT(9)
>>>   #define SDMMC_IDMAC_INT_NI        BIT(8)
>>> diff --git a/include/linux/mmc/dw_mmc.h b/include/linux/mmc/dw_mmc.h
>>> index c846f42..6a2b83c 100644
>>> --- a/include/linux/mmc/dw_mmc.h
>>> +++ b/include/linux/mmc/dw_mmc.h
>>> @@ -16,6 +16,7 @@
>>>
>>>   #include <linux/scatterlist.h>
>>>   #include <linux/mmc/core.h>
>>> +#include <linux/dmaengine.h>
>>>
>>>   #define MAX_MCI_SLOTS    2
>>>
>>> @@ -40,6 +41,17 @@ enum {
>>>
>>>   struct mmc_data;
>>>
>>> +enum {
>>> +    TRANS_MODE_PIO = 0,
>>> +    TRANS_MODE_IDMAC,
>>> +    TRANS_MODE_EDMAC
>>> +};
>>> +
>>> +struct dw_mci_dma_slave {
>>> +    struct dma_chan *ch;
>>> +    enum dma_transfer_direction direction;
>>> +};
>>> +
>>>   /**
>>>    * struct dw_mci - MMC controller state shared between all slots
>>>    * @lock: Spinlock protecting the queue and associated data.
>>> @@ -154,11 +166,16 @@ struct dw_mci {
>>>       dma_addr_t        sg_dma;
>>>       void            *sg_cpu;
>>>       const struct dw_mci_dma_ops    *dma_ops;
>>> -#ifdef CONFIG_MMC_DW_IDMAC
>>> +    /* For idmac */
>>>       unsigned int        ring_size;
>>> -#else
>>> +
>>> +    /* For edmac */
>>> +    struct dw_mci_dma_slave *dms;
>>> +    /* Registers's physical base address */
>>> +    void                    *phy_regs;
>>> +
>>>       struct dw_mci_dma_data    *dma_data;
>>> -#endif
>>> +
>>
>> On ulf's repository, this point should be conflicted.
>>
>> Best Regards,
>> Jaehoon Chung
>>
>>>       u32            cmd_status;
>>>       u32            data_status;
>>>       u32            stop_cmdr;
>>> @@ -212,8 +229,8 @@ struct dw_mci {
>>>   struct dw_mci_dma_ops {
>>>       /* DMA Ops */
>>>       int (*init)(struct dw_mci *host);
>>> -    void (*start)(struct dw_mci *host, unsigned int sg_len);
>>> -    void (*complete)(struct dw_mci *host);
>>> +    int (*start)(struct dw_mci *host, unsigned int sg_len);
>>> +    void (*complete)(void *host);
>>>       void (*stop)(struct dw_mci *host);
>>>       void (*cleanup)(struct dw_mci *host);
>>>       void (*exit)(struct dw_mci *host);
>>>
>>
>>
>>
>>
> 
> 



From tomi.valkeinen at ti.com  Thu Aug 20 23:53:02 2015
From: tomi.valkeinen at ti.com (Tomi Valkeinen)
Date: Fri, 21 Aug 2015 09:53:02 +0300
Subject: [PATCH v1, TRIVIAL] Fix pxafb nonstd field documentation and
 add errata info
In-Reply-To: <55D63391.3080403@tul.cz>
References: <55C64864.6070405@tul.cz> <55D5B232.9090006@ti.com>
 <55D63391.3080403@tul.cz>
Message-ID: <55D6CACE.1080801@ti.com>



On 20/08/15 23:07, Petr Cvek wrote:
> Dne 20.8.2015 v 12:55 Tomi Valkeinen napsal(a):
>>
>>
>> On 08/08/15 21:20, Petr Cvek wrote:
>>
>>> diff --git a/drivers/video/fbdev/Kconfig b/drivers/video/fbdev/Kconfig
>>> index 2d98de5..8f485ec 100644
>>> --- a/drivers/video/fbdev/Kconfig
>>> +++ b/drivers/video/fbdev/Kconfig
>>> @@ -1893,6 +1893,11 @@ config FB_PXA_OVERLAY
>>>  	bool "Support PXA27x/PXA3xx Overlay(s) as framebuffer"
>>>  	default n
>>>  	depends on FB_PXA && (PXA27x || PXA3xx)
>>> +	---help---
>>> +	  Using the overlay 2 and YUV420 mode on a PXA27x C0 chip revision will
>>> +	  hang the LCD until the next SoC restart (errata E24).
>>
>> Shouldn't the driver handle this? It should not allow the combination to
>> be used.
>>
>>  Tomi
>>
> 
> Probably, but I don't know which revisions are OK and which are not. Errata document:
> 
> 	Marvell? PXA270M Processor Specification Update
> 	MV-S900957-00
> 
> has only 3 revisions, but PXA Manual lists 6 (2.2.5.1 Processor ID Register) and one revision from errata is not shown in my PXA Manual. I can exclude mine revision (from "system_rev" variable), but there should be some warning somewhere in configuration.

No, configuration or kernel docs is not the right place for this. The
user is not going to see that. And a single kernel image is supposed to
run on different soc/board versions, so you can't do selections like
this in the kernel config.

The driver should detect the bad revision, and then apply the
workaround, or if that's not possible, refuse the use of the
configuration that leads to the HW bug. Or if even that's not possible,
the driver should print a warning when starting, so that the user is
able to see it.

 Tomi

-------------- next part --------------
A non-text attachment was scrubbed...
Name: signature.asc
Type: application/pgp-signature
Size: 819 bytes
Desc: OpenPGP digital signature
URL: <http://lists.infradead.org/pipermail/linux-arm-kernel/attachments/20150821/16323465/attachment.sig>

From shawn.lin at rock-chips.com  Fri Aug 21 00:27:43 2015
From: shawn.lin at rock-chips.com (Shawn Lin)
Date: Fri, 21 Aug 2015 15:27:43 +0800
Subject: [RFC PATCH v6 1/9] mmc: dw_mmc: Add external dma interface support
In-Reply-To: <55D6C6B6.3060706@samsung.com>
References: <1440060204-26203-1-git-send-email-shawn.lin@rock-chips.com>
 <1440060233-26244-1-git-send-email-shawn.lin@rock-chips.com>
 <55D6C4D4.8010005@samsung.com> <55D6C57D.4070402@rock-chips.com>
 <55D6C6B6.3060706@samsung.com>
Message-ID: <55D6D2EF.7010501@rock-chips.com>

On 2015/8/21 14:35, Jaehoon Chung wrote:
> On 08/21/2015 03:30 PM, Shawn Lin wrote:
>> On 2015/8/21 14:27, Jaehoon Chung wrote:
>>> Hi, Shawn.
>>>
>>> Is this based on Ulf's repository?
>>
>>
>> no, it's based on "https://github.com/jh80chung/dw-mmc.git tags/dw-mmc-for-ulf-v4.2" ??
>
> Oh..I will rebase to Ulf's next branch on this weekend.
> Then could you rebase this patch? And i added more comments at below.. :)
>

Okay, I will rebase to Ulf's next.

> Best Regards,
> Jaehoon Chung
>
>>

[...]

>>>> index ec6dbcd..7e1d13b 100644
>>>> --- a/drivers/mmc/host/dw_mmc-pltfm.c
>>>> +++ b/drivers/mmc/host/dw_mmc-pltfm.c
>>>> @@ -59,6 +59,8 @@ int dw_mci_pltfm_register(struct platform_device *pdev,
>>>>        host->pdata = pdev->dev.platform_data;
>>>>
>>>>        regs = platform_get_resource(pdev, IORESOURCE_MEM, 0);
>>>> +    /* Get registers' physical base address */
>>>> +    host->phy_regs = (void *)(regs->start);
>>>>        host->regs = devm_ioremap_resource(&pdev->dev, regs);
>>>>        if (IS_ERR(host->regs))
>>>>            return PTR_ERR(host->regs);
>>>
>>> Is this board specific code? If so, separate the patch.

It's might not board specific code.
dmaengine need dw_mmc's *physical* fifo address for data transfer, so I 
get controller physical address  here in order to calculate physical 
fifo address.

regs is from dt-bindings, for instance:
          dwmmc0 at 12200000 {
                  compatible = "snps,dw-mshc";
                   clocks = <&clock 351>, <&clock 132>;
                  clock-names = "biu", "ciu";
                  reg = <0x12200000 0x1000>;
                  interrupts = <0 75 0>;
                  #address-cells = <1>;
                  #size-cells = <0>;
          };

so, host->phy_regs will be 0x12200000 .

[...]

>>>> +static void dw_mci_dmac_complete_dma(void *arg)
>>>>    {
>>>> +    struct dw_mci *host = arg;
>>>>        struct mmc_data *data = host->data;
>>>>
>>>>        dev_vdbg(host->dev, "DMA complete\n");
>>>>
>>>> +    if (host->use_dma == TRANS_MODE_EDMAC)
>>>> +        if (data && (data->flags & MMC_DATA_READ))
>>>
>>> Combine one condition.

okay.

[...]

>>>> +    u32 fifo_offset = host->fifo_reg - host->regs;
>>>> +    int ret = 0;
>>>> +
>>>> +    /* Set external dma config: burst size, burst width */
>>>> +    cfg.dst_addr = (dma_addr_t)(host->phy_regs + fifo_offset);
>>>
>>> host->phy_regs is not assigned?

we got it at dw_mci_pltfm_register. See comments above. :)

[...]

>>>>            mmc->max_blk_count = mmc->max_req_size / 512;
>>>> +    } else if (host->use_dma == TRANS_MODE_EDMAC) {
>>>> +            mmc->max_segs = 64;
>>>> +            mmc->max_blk_size = 65536;
>>>> +            mmc->max_blk_count = 65535;
>>>> +            mmc->max_req_size =
>>>> +                    mmc->max_blk_size * mmc->max_blk_count;
>>>> +            mmc->max_seg_size = mmc->max_req_size;
>>>
>>> Fix the indention

Hmm..I check it attentively but can't find the indention . Might it's 
because you apply it against Ulf's repo?

>>>

[...]

>>>>
>>>> -    /* Alloc memory for sg translation */
>>>> -    host->sg_cpu = dmam_alloc_coherent(host->dev, PAGE_SIZE,
>>>> -                      &host->sg_dma, GFP_KERNEL);
>>>> -    if (!host->sg_cpu) {
>>>> -        dev_err(host->dev, "%s: could not alloc DMA memory\n",
>>>> -            __func__);
>>>> +    /* Check tansfer mode */
>>>> +    trans_mode = SDMMC_GET_TRANS_MODE(mci_readl(host, HCON));
>>>> +    if (trans_mode == 0) {
>>>> +        trans_mode = TRANS_MODE_IDMAC;
>>>> +    } else if (trans_mode == 1 || trans_mode == 2) {
>>>> +        trans_mode = TRANS_MODE_EDMAC;
>>>> +    } else {
>>>> +        trans_mode = TRANS_MODE_PIO;
>>>
>>> what are trans_mode "0, 1, 2"?
>>> (00 - none) is NO-DMA interface, isn't? is it IDMAC mode?
>>>

No, I guess the databook's ambiguous description confuse everybody.

I got double comfirm from my ASCI team as well as Synoposys
2b'00: NO-DMA interface -->  It support IDMAC actually
2b'01 & 2b'02: DW_DMA & GENERIC_DMA --> Support 2 types of external dma.
2b'02: NON-DW-DMA --> only support PIO

refer to the description below:
Parameter Name: DMA_INTERFACE
Legal Values: 0-3
Default Value: 0
Description:
  0- No DMA Interface
  1- DesignWare DMA Interface
  2- Generic DMA Interface
  3- Non DW DMA Interface
In DesignWare DMA mode, request/acknowledge protocol meets DW_ahb_dmac
controller protocol. In this mode, host data bus is also used for DMA 
transfers.Generic DMA-type interface has simpler request/acknowledge 
handshake and has dedicated read/write data bus for DMA transfers. Non 
DW DMAC interface uses dw_dma_single interface in addition to the 
existing interface and uses host data bus for DMA transfers. This is 
configurable only if INTERNAL_DMAC=0.

>>>>            goto no_dma;
>>>>        }
>
>>>> +        dev_info(host->dev, "Using external DMA controller.\n");
>>>> +    }
>>>>
>>>>        if (!host->dma_ops)
>>>>            goto no_dma;
>>>> @@ -2562,12 +2720,12 @@ static void dw_mci_init_dma(struct dw_mci *host)
>>>>            goto no_dma;
>>>>        }
>>>>
>>>> -    host->use_dma = 1;
>>>> +    host->use_dma = trans_mode;
>>>
>>> Also confuse, if trans_mode is assigned host->use_dma, can mode value be directly assigned to host->use_dma?
>>>

Good idea, I will do it.  :)

>>> trans_mode = TRAMS_MODE_PIO;
>>> host->use_dma = trans_mode;
>>>

[...]

>>>>
>>>> @@ -2890,7 +3047,7 @@ int dw_mci_probe(struct dw_mci *host)
>>>>         * Get the host data width - this assumes that HCON has been set with
>>>>         * the correct values.
>>>>         */
>>>> -    i = (mci_readl(host, HCON) >> 7) & 0x7;
>>>> +    i = SDMMC_GET_HDATA_WIDTH(mci_readl(host, HCON));
>>>
>>> This is not related with supporting external dma interface.
>>> Separate this.
>>>

Okay, It will be split into another one.

>>>>        if (!i) {
>>>>            host->push_data = dw_mci_push_data16;
>>>>            host->pull_data = dw_mci_pull_data16;



-- 
Best Regards
Shawn Lin



From michal.simek at xilinx.com  Fri Aug 21 00:36:22 2015
From: michal.simek at xilinx.com (Michal Simek)
Date: Fri, 21 Aug 2015 09:36:22 +0200
Subject: [RESEND PATCH] dmaengine: Add Xilinx AXI Direct Memory Access
 Engine driver support
In-Reply-To: <CAAtXAHe3QjBo4_5unB32ixnOriO8Xt-1nLeddjgRgYvj5Kn_EA@mail.gmail.com>
References: <1439825512-16444-1-git-send-email-appanad@xilinx.com>
 <CAAtXAHf9S662okN1gchbD246=e4_bMFoyBMrbt5q48xm1uo_CA@mail.gmail.com>
 <C246CAC1457055469EF09E3A7AC4E11A4A4B2BBC@XAP-PVEXMBX01.xlnx.xilinx.com>
 <C246CAC1457055469EF09E3A7AC4E11A4A4B2C48@XAP-PVEXMBX01.xlnx.xilinx.com>
 <CAAtXAHe3QjBo4_5unB32ixnOriO8Xt-1nLeddjgRgYvj5Kn_EA@mail.gmail.com>
Message-ID: <55D6D4F6.4020100@xilinx.com>

Hi,

On 08/21/2015 03:16 AM, Moritz Fischer wrote:
> Hi,
> 
> your MUA produces funny messages somehow ...
> The driver did not probe for me in it's current form as the bindings
> were missing interrupt parents for the interrupts...

It is just a question where interrupt parent is listed. I have seen that
some SoCs are just setting up at one location for all IPs.
I remember some discussions that some properties don't need to be
documented again and again. That's why the question is if they are
really needed to be documented in the binding doc because it is just
documentation duplication in every binding document.

Definitely if you miss it in the binding doc, feel free to send the
patch and update it.

Thanks,
Michal



From jh80.chung at samsung.com  Fri Aug 21 00:38:41 2015
From: jh80.chung at samsung.com (Jaehoon Chung)
Date: Fri, 21 Aug 2015 16:38:41 +0900
Subject: [RFC PATCH v6 1/9] mmc: dw_mmc: Add external dma interface support
In-Reply-To: <55D6D2EF.7010501@rock-chips.com>
References: <1440060204-26203-1-git-send-email-shawn.lin@rock-chips.com>
 <1440060233-26244-1-git-send-email-shawn.lin@rock-chips.com>
 <55D6C4D4.8010005@samsung.com> <55D6C57D.4070402@rock-chips.com>
 <55D6C6B6.3060706@samsung.com> <55D6D2EF.7010501@rock-chips.com>
Message-ID: <55D6D581.3050509@samsung.com>

On 08/21/2015 04:27 PM, Shawn Lin wrote:
> On 2015/8/21 14:35, Jaehoon Chung wrote:
>> On 08/21/2015 03:30 PM, Shawn Lin wrote:
>>> On 2015/8/21 14:27, Jaehoon Chung wrote:
>>>> Hi, Shawn.
>>>>
>>>> Is this based on Ulf's repository?
>>>
>>>
>>> no, it's based on "https://github.com/jh80chung/dw-mmc.git tags/dw-mmc-for-ulf-v4.2" ??
>>
>> Oh..I will rebase to Ulf's next branch on this weekend.
>> Then could you rebase this patch? And i added more comments at below.. :)
>>
> 
> Okay, I will rebase to Ulf's next.
> 
>> Best Regards,
>> Jaehoon Chung
>>
>>>
> 
> [...]
> 
>>>>> index ec6dbcd..7e1d13b 100644
>>>>> --- a/drivers/mmc/host/dw_mmc-pltfm.c
>>>>> +++ b/drivers/mmc/host/dw_mmc-pltfm.c
>>>>> @@ -59,6 +59,8 @@ int dw_mci_pltfm_register(struct platform_device *pdev,
>>>>>        host->pdata = pdev->dev.platform_data;
>>>>>
>>>>>        regs = platform_get_resource(pdev, IORESOURCE_MEM, 0);
>>>>> +    /* Get registers' physical base address */
>>>>> +    host->phy_regs = (void *)(regs->start);
>>>>>        host->regs = devm_ioremap_resource(&pdev->dev, regs);
>>>>>        if (IS_ERR(host->regs))
>>>>>            return PTR_ERR(host->regs);
>>>>
>>>> Is this board specific code? If so, separate the patch.
> 
> It's might not board specific code.
> dmaengine need dw_mmc's *physical* fifo address for data transfer, so I get controller physical address  here in order to calculate physical fifo address.
> 
> regs is from dt-bindings, for instance:
>          dwmmc0 at 12200000 {
>                  compatible = "snps,dw-mshc";
>                   clocks = <&clock 351>, <&clock 132>;
>                  clock-names = "biu", "ciu";
>                  reg = <0x12200000 0x1000>;
>                  interrupts = <0 75 0>;
>                  #address-cells = <1>;
>                  #size-cells = <0>;
>          };
> 
> so, host->phy_regs will be 0x12200000 .
> 
> [...]
> 
>>>>> +static void dw_mci_dmac_complete_dma(void *arg)
>>>>>    {
>>>>> +    struct dw_mci *host = arg;
>>>>>        struct mmc_data *data = host->data;
>>>>>
>>>>>        dev_vdbg(host->dev, "DMA complete\n");
>>>>>
>>>>> +    if (host->use_dma == TRANS_MODE_EDMAC)
>>>>> +        if (data && (data->flags & MMC_DATA_READ))
>>>>
>>>> Combine one condition.
> 
> okay.
> 
> [...]
> 
>>>>> +    u32 fifo_offset = host->fifo_reg - host->regs;
>>>>> +    int ret = 0;
>>>>> +
>>>>> +    /* Set external dma config: burst size, burst width */
>>>>> +    cfg.dst_addr = (dma_addr_t)(host->phy_regs + fifo_offset);
>>>>
>>>> host->phy_regs is not assigned?
> 
> we got it at dw_mci_pltfm_register. See comments above. :)
> 
> [...]
> 
>>>>>            mmc->max_blk_count = mmc->max_req_size / 512;
>>>>> +    } else if (host->use_dma == TRANS_MODE_EDMAC) {
>>>>> +            mmc->max_segs = 64;
>>>>> +            mmc->max_blk_size = 65536;
>>>>> +            mmc->max_blk_count = 65535;
>>>>> +            mmc->max_req_size =
>>>>> +                    mmc->max_blk_size * mmc->max_blk_count;
>>>>> +            mmc->max_seg_size = mmc->max_req_size;
>>>>
>>>> Fix the indention
> 
> Hmm..I check it attentively but can't find the indention . Might it's because you apply it against Ulf's repo?
> 
>>>>
> 
> [...]
> 
>>>>>
>>>>> -    /* Alloc memory for sg translation */
>>>>> -    host->sg_cpu = dmam_alloc_coherent(host->dev, PAGE_SIZE,
>>>>> -                      &host->sg_dma, GFP_KERNEL);
>>>>> -    if (!host->sg_cpu) {
>>>>> -        dev_err(host->dev, "%s: could not alloc DMA memory\n",
>>>>> -            __func__);
>>>>> +    /* Check tansfer mode */
>>>>> +    trans_mode = SDMMC_GET_TRANS_MODE(mci_readl(host, HCON));
>>>>> +    if (trans_mode == 0) {
>>>>> +        trans_mode = TRANS_MODE_IDMAC;
>>>>> +    } else if (trans_mode == 1 || trans_mode == 2) {
>>>>> +        trans_mode = TRANS_MODE_EDMAC;
>>>>> +    } else {
>>>>> +        trans_mode = TRANS_MODE_PIO;
>>>>
>>>> what are trans_mode "0, 1, 2"?
>>>> (00 - none) is NO-DMA interface, isn't? is it IDMAC mode?
>>>>
> 
> No, I guess the databook's ambiguous description confuse everybody.
> 
> I got double comfirm from my ASCI team as well as Synoposys
> 2b'00: NO-DMA interface -->  It support IDMAC actually
> 2b'01 & 2b'02: DW_DMA & GENERIC_DMA --> Support 2 types of external dma.
> 2b'02: NON-DW-DMA --> only support PIO

Then Could you add the comment about this?
Use definition instead of "0, 1, 2". Developer don't know meaning that is 0, 1, 2.

Best Regards,
Jaehoon Chung

> 
> refer to the description below:
> Parameter Name: DMA_INTERFACE
> Legal Values: 0-3
> Default Value: 0
> Description:
>  0- No DMA Interface
>  1- DesignWare DMA Interface
>  2- Generic DMA Interface
>  3- Non DW DMA Interface
> In DesignWare DMA mode, request/acknowledge protocol meets DW_ahb_dmac
> controller protocol. In this mode, host data bus is also used for DMA transfers.Generic DMA-type interface has simpler request/acknowledge handshake and has dedicated read/write data bus for DMA transfers. Non DW DMAC interface uses dw_dma_single interface in addition to the existing interface and uses host data bus for DMA transfers. This is configurable only if INTERNAL_DMAC=0.
> 
>>>>>            goto no_dma;
>>>>>        }
>>
>>>>> +        dev_info(host->dev, "Using external DMA controller.\n");
>>>>> +    }
>>>>>
>>>>>        if (!host->dma_ops)
>>>>>            goto no_dma;
>>>>> @@ -2562,12 +2720,12 @@ static void dw_mci_init_dma(struct dw_mci *host)
>>>>>            goto no_dma;
>>>>>        }
>>>>>
>>>>> -    host->use_dma = 1;
>>>>> +    host->use_dma = trans_mode;
>>>>
>>>> Also confuse, if trans_mode is assigned host->use_dma, can mode value be directly assigned to host->use_dma?
>>>>
> 
> Good idea, I will do it.  :)
> 
>>>> trans_mode = TRAMS_MODE_PIO;
>>>> host->use_dma = trans_mode;
>>>>
> 
> [...]
> 
>>>>>
>>>>> @@ -2890,7 +3047,7 @@ int dw_mci_probe(struct dw_mci *host)
>>>>>         * Get the host data width - this assumes that HCON has been set with
>>>>>         * the correct values.
>>>>>         */
>>>>> -    i = (mci_readl(host, HCON) >> 7) & 0x7;
>>>>> +    i = SDMMC_GET_HDATA_WIDTH(mci_readl(host, HCON));
>>>>
>>>> This is not related with supporting external dma interface.
>>>> Separate this.
>>>>
> 
> Okay, It will be split into another one.
> 
>>>>>        if (!i) {
>>>>>            host->push_data = dw_mci_push_data16;
>>>>>            host->pull_data = dw_mci_pull_data16;
> 
> 
> 



From hdegoede at redhat.com  Fri Aug 21 00:42:44 2015
From: hdegoede at redhat.com (Hans de Goede)
Date: Fri, 21 Aug 2015 09:42:44 +0200
Subject: [linux-sunxi][PATCH] ARM: sun7i: dt: Add new Olimex A20 EVB device
In-Reply-To: <CAEKpxBnQ+kCVYfE8JL5JzH5ZXb3azjwmjfAE5OXULaVm0bj2ew@mail.gmail.com>
References: <1440002596-2611-1-git-send-email-codekipper@gmail.com>
 <20150820154545.GF30520@lukather>
 <CAEKpxBnQ+kCVYfE8JL5JzH5ZXb3azjwmjfAE5OXULaVm0bj2ew@mail.gmail.com>
Message-ID: <55D6D674.7060205@redhat.com>

Hi,

On 21-08-15 07:36, Code Kipper wrote:
> On 20 August 2015 at 17:45, Maxime Ripard <maxime.ripard at free-electrons.com>
> wrote:
>
>> Hi,
>>
>> On Wed, Aug 19, 2015 at 06:43:16PM +0200, codekipper at gmail.com wrote:
>>> From: Marcus Cooper <codekipper at gmail.com>
>>>
>>> The A20-SOM-EVB is a reference design of a 2-layer board for the
>>> A20-SOM.
>>> It expands the features of A20-SOM by adding VGA connector, HDMI
>>> connector, audio In/Out, LCD connector, 2 Mpix camera, gigabit
>>> Ethernet, SATA, USB-OTG and 2 USB hosts.
>>>
>>> This patch adds basic support for the device
>>> https://www.olimex.com/Products/SOM/A20/A20-SOM-EVB/
>>>
>>> More information on the SOM can be found here
>>> http://linux-sunxi.org/Olimex_A20-SOM.
>>>
>>> Signed-off-by: Marcus Cooper <codekipper at gmail.com>
>>
>> Is there any other SOM planned that could work with that baseboard? Or
>> any other baseboard for that SOM?
>>
> I've seen neither. We could always create a som.dtsi later is one emerges.
>
>>
>>> ---
>>>   arch/arm/boot/dts/Makefile                    |   1 +
>>>   arch/arm/boot/dts/sun7i-a20-olinuxino-evb.dts | 233
>> ++++++++++++++++++++++++++
>>>   2 files changed, 234 insertions(+)
>>>   create mode 100644 arch/arm/boot/dts/sun7i-a20-olinuxino-evb.dts
>>
> Relooking at their website I can see that the device does not come under
> the olinuxino brand so maybe I should rename the dts to
> sun7i-a20-olimex-som-evb.dts

Ack for renaming / +1

Regards,

Hans

>
>>>
>>> diff --git a/arch/arm/boot/dts/Makefile b/arch/arm/boot/dts/Makefile
>>> index 6d7cec1..fdbda9b 100644
>>> --- a/arch/arm/boot/dts/Makefile
>>> +++ b/arch/arm/boot/dts/Makefile
>>> @@ -613,6 +613,7 @@ dtb-$(CONFIG_MACH_SUN7I) += \
>>>        sun7i-a20-olinuxino-lime.dtb \
>>>        sun7i-a20-olinuxino-lime2.dtb \
>>>        sun7i-a20-olinuxino-micro.dtb \
>>> +     sun7i-a20-olinuxino-evb.dtb \
>>>        sun7i-a20-orangepi.dtb \
>>>        sun7i-a20-orangepi-mini.dtb \
>>>        sun7i-a20-pcduino3.dtb \
>>> diff --git a/arch/arm/boot/dts/sun7i-a20-olinuxino-evb.dts
>> b/arch/arm/boot/dts/sun7i-a20-olinuxino-evb.dts
>>> new file mode 100644
>>> index 0000000..a0071fa
>>> --- /dev/null
>>> +++ b/arch/arm/boot/dts/sun7i-a20-olinuxino-evb.dts
>>> @@ -0,0 +1,233 @@
>>> +/*
>>> + * Copyright 2015 - Marcus Cooper <codekipper at gmail.com>
>>> + *
>>> + * This file is dual-licensed: you can use it either under the terms
>>> + * of the GPL or the X11 license, at your option. Note that this dual
>>> + * licensing only applies to this file, and not this project as a
>>> + * whole.
>>> + *
>>> + *  a) This file is free software; you can redistribute it and/or
>>> + *     modify it under the terms of the GNU General Public License as
>>> + *     published by the Free Software Foundation; either version 2 of
>> the
>>> + *     License, or (at your option) any later version.
>>> + *
>>> + *     This file is distributed in the hope that it will be useful,
>>> + *     but WITHOUT ANY WARRANTY; without even the implied warranty of
>>> + *     MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
>>> + *     GNU General Public License for more details.
>>> + *
>>> + * Or, alternatively,
>>> + *
>>> + *  b) Permission is hereby granted, free of charge, to any person
>>> + *     obtaining a copy of this software and associated documentation
>>> + *     files (the "Software"), to deal in the Software without
>>> + *     restriction, including without limitation the rights to use,
>>> + *     copy, modify, merge, publish, distribute, sublicense, and/or
>>> + *     sell copies of the Software, and to permit persons to whom the
>>> + *     Software is furnished to do so, subject to the following
>>> + *     conditions:
>>> + *
>>> + *     The above copyright notice and this permission notice shall be
>>> + *     included in all copies or substantial portions of the Software.
>>> + *
>>> + *     THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
>>> + *     EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES
>>> + *     OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
>>> + *     NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT
>>> + *     HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY,
>>> + *     WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
>>> + *     FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR
>>> + *     OTHER DEALINGS IN THE SOFTWARE.
>>> + */
>>> +
>>> +/dts-v1/;
>>> +#include "sun7i-a20.dtsi"
>>> +#include "sunxi-common-regulators.dtsi"
>>> +
>>> +#include <dt-bindings/gpio/gpio.h>
>>> +#include <dt-bindings/interrupt-controller/irq.h>
>>> +#include <dt-bindings/pinctrl/sun4i-a10.h>
>>> +
>>> +/ {
>>> +     model = "Olimex A20-OLinuXino-EVB";
>>> +     compatible = "olimex,a20-olinuxino-evb", "allwinner,sun7i-a20";
>>> +
>>> +     aliases {
>>> +             serial0 = &uart0;
>>> +     };
>>> +
>>> +     chosen {
>>> +             stdout-path = "serial0:115200n8";
>>> +     };
>>> +
>>> +     leds {
>>> +             compatible = "gpio-leds";
>>> +             pinctrl-names = "default";
>>> +             pinctrl-0 = <&led_pins_olinuxinoevb>;
>>> +
>>> +             green {
>>> +                     label = "a20-olinuxino-evb:green:usr";
>>> +                     gpios = <&pio 7 2 GPIO_ACTIVE_HIGH>;
>>> +                     default-state = "on";
>>> +             };
>>> +     };
>>> +
>>> +     reg_axp_ipsout: axp_ipsout {
>>> +             compatible = "regulator-fixed";
>>> +             regulator-name = "axp-ipsout";
>>> +             regulator-min-microvolt = <5000000>;
>>> +             regulator-max-microvolt = <5000000>;
>>> +             regulator-always-on;
>>> +     };
>>> +};
>>> +
>>> +&ahci {
>>> +     target-supply = <&reg_ahci_5v>;
>>> +     status = "okay";
>>> +};
>>> +
>>> +&ehci0 {
>>> +     status = "okay";
>>> +};
>>> +
>>> +&ehci1 {
>>> +     status = "okay";
>>> +};
>>> +
>>> +&gmac {
>>> +     pinctrl-names = "default";
>>> +     pinctrl-0 = <&gmac_pins_rgmii_a>;
>>> +     phy = <&phy1>;
>>> +     phy-mode = "rgmii";
>>> +     status = "okay";
>>> +
>>> +     phy1: ethernet-phy at 1 {
>>> +             reg = <1>;
>>> +     };
>>> +};
>>> +
>>> +&i2c0 {
>>> +     pinctrl-names = "default";
>>> +     pinctrl-0 = <&i2c0_pins_a>;
>>> +     status = "okay";
>>> +
>>> +     axp209: pmic at 34 {
>>> +             compatible = "x-powers,axp209";
>>> +             reg = <0x34>;
>>> +             interrupt-parent = <&nmi_intc>;
>>> +             interrupts = <0 IRQ_TYPE_LEVEL_LOW>;
>>> +
>>> +             interrupt-controller;
>>> +             #interrupt-cells = <1>;
>>> +
>>> +             acin-supply = <&reg_axp_ipsout>;
>>> +             vin2-supply = <&reg_axp_ipsout>;
>>> +             vin3-supply = <&reg_axp_ipsout>;
>>> +             ldo24in-supply = <&reg_axp_ipsout>;
>>> +             ldo3in-supply = <&reg_axp_ipsout>;
>>
>> Please use the axp209 dtsi.
>>
> Will do
>
>>
>>> +
>>> +             regulators {
>>> +                     vdd_rtc: ldo1 {
>>> +                             regulator-min-microvolt = <1300000>;
>>> +                             regulator-max-microvolt = <1300000>;
>>> +                             regulator-always-on;
>>> +                     };
>>> +
>>> +                     avcc: ldo2 {
>>> +                             regulator-min-microvolt = <1800000>;
>>> +                             regulator-max-microvolt = <3300000>;
>>> +                             regulator-always-on;
>>> +                     };
>>> +
>>> +                     vcc_csi0: ldo3 {
>>> +                             regulator-min-microvolt = <700000>;
>>> +                             regulator-max-microvolt = <3500000>;
>>> +                             regulator-always-on;
>>> +                     };
>>> +
>>> +                     vcc_csi1: ldo4 {
>>> +                             regulator-min-microvolt = <1250000>;
>>> +                             regulator-max-microvolt = <3300000>;
>>> +                             regulator-always-on;
>>> +                     };
>>
>> the csi regulators are always-on too? What function do they provide?
>>
> This was a c & p from the lime 2 dts as their fex files are very similar. I
> can remove this for now.
>
>>
>>> +                     vdd_cpu: dcdc2 {
>>> +                             regulator-min-microvolt = <700000>;
>>> +                             regulator-max-microvolt = <2275000>;
>>
>> This is way outside of the CPU operating range. Are you sure of your
>> constraints?
>>
> ditto. I will check on this.
>
>
>>
>>> +                             regulator-always-on;
>>> +                     };
>>> +
>>> +                     vdd_int: dcdc3 {
>>> +                             regulator-min-microvolt = <700000>;
>>> +                             regulator-max-microvolt = <3500000>;
>>> +                             regulator-always-on;
>>> +                     };
>>> +             };
>>> +     };
>>> +};
>>> +
>>> +&i2c1 {
>>> +     pinctrl-names = "default";
>>> +     pinctrl-0 = <&i2c1_pins_a>;
>>> +     status = "okay";
>>> +};
>>> +
>>> +&mmc0 {
>>> +     pinctrl-names = "default";
>>> +     pinctrl-0 = <&mmc0_pins_a>, <&mmc0_cd_pin_reference_design>;
>>> +     vmmc-supply = <&reg_vcc3v3>;
>>> +     bus-width = <4>;
>>> +     cd-gpios = <&pio 7 1 GPIO_ACTIVE_HIGH>; /* PH1 */
>>> +     cd-inverted;
>>> +     status = "okay";
>>> +};
>>> +
>>> +&ohci0 {
>>> +     status = "okay";
>>> +};
>>> +
>>> +&ohci1 {
>>> +     status = "okay";
>>> +};
>>> +
>>> +&pio {
>>> +     ahci_pwr_pin_olinuxinoevb: ahci_pwr_pin at 1 {
>>> +             allwinner,pins = "PC3";
>>> +             allwinner,function = "gpio_out";
>>> +             allwinner,drive = <SUN4I_PINCTRL_10_MA>;
>>> +             allwinner,pull = <SUN4I_PINCTRL_NO_PULL>;
>>> +     };
>>> +
>>> +     led_pins_olinuxinoevb: led_pins at 0 {
>>> +             allwinner,pins = "PH2";
>>> +             allwinner,function = "gpio_out";
>>> +             allwinner,drive = <SUN4I_PINCTRL_20_MA>;
>>> +             allwinner,pull = <SUN4I_PINCTRL_NO_PULL>;
>>> +     };
>>> +};
>>> +
>>> +&reg_ahci_5v {
>>> +     pinctrl-0 = <&ahci_pwr_pin_olinuxinoevb>;
>>> +     gpio = <&pio 2 3 GPIO_ACTIVE_HIGH>;
>>> +     status = "okay";
>>> +};
>>> +
>>> +&reg_usb1_vbus {
>>> +     status = "okay";
>>> +};
>>> +
>>> +&reg_usb2_vbus {
>>> +     status = "okay";
>>> +};
>>> +
>>> +&uart0 {
>>> +     pinctrl-names = "default";
>>> +     pinctrl-0 = <&uart0_pins_a>;
>>> +     status = "okay";
>>> +};
>>> +
>>> +&usbphy {
>>> +     usb1_vbus-supply = <&reg_usb1_vbus>;
>>> +     usb2_vbus-supply = <&reg_usb2_vbus>;
>>> +     status = "okay";
>>> +};
>>> --
>>> 2.5.0
>>>
>>
>> Thanks,
>> Maxime
>>
>> --
>> Maxime Ripard, Free Electrons
>> Embedded Linux, Kernel and Android engineering
>> http://free-electrons.com
>>
>


From hdegoede at redhat.com  Fri Aug 21 00:43:37 2015
From: hdegoede at redhat.com (Hans de Goede)
Date: Fri, 21 Aug 2015 09:43:37 +0200
Subject: [linux-sunxi][PATCH] ARM: sun7i: dt: Add new Olimex A20 EVB device
In-Reply-To: <55D6D674.7060205@redhat.com>
References: <1440002596-2611-1-git-send-email-codekipper@gmail.com>
 <20150820154545.GF30520@lukather>
 <CAEKpxBnQ+kCVYfE8JL5JzH5ZXb3azjwmjfAE5OXULaVm0bj2ew@mail.gmail.com>
 <55D6D674.7060205@redhat.com>
Message-ID: <55D6D6A9.3080006@redhat.com>

Hi,

On 21-08-15 09:42, Hans de Goede wrote:
> Hi,
>
> On 21-08-15 07:36, Code Kipper wrote:
>> On 20 August 2015 at 17:45, Maxime Ripard <maxime.ripard at free-electrons.com>
>> wrote:
>>
>>> Hi,
>>>
>>> On Wed, Aug 19, 2015 at 06:43:16PM +0200, codekipper at gmail.com wrote:
>>>> From: Marcus Cooper <codekipper at gmail.com>
>>>>
>>>> The A20-SOM-EVB is a reference design of a 2-layer board for the
>>>> A20-SOM.
>>>> It expands the features of A20-SOM by adding VGA connector, HDMI
>>>> connector, audio In/Out, LCD connector, 2 Mpix camera, gigabit
>>>> Ethernet, SATA, USB-OTG and 2 USB hosts.
>>>>
>>>> This patch adds basic support for the device
>>>> https://www.olimex.com/Products/SOM/A20/A20-SOM-EVB/
>>>>
>>>> More information on the SOM can be found here
>>>> http://linux-sunxi.org/Olimex_A20-SOM.
>>>>
>>>> Signed-off-by: Marcus Cooper <codekipper at gmail.com>
>>>
>>> Is there any other SOM planned that could work with that baseboard? Or
>>> any other baseboard for that SOM?
>>>
>> I've seen neither. We could always create a som.dtsi later is one emerges.
>>
>>>
>>>> ---
>>>>   arch/arm/boot/dts/Makefile                    |   1 +
>>>>   arch/arm/boot/dts/sun7i-a20-olinuxino-evb.dts | 233
>>> ++++++++++++++++++++++++++
>>>>   2 files changed, 234 insertions(+)
>>>>   create mode 100644 arch/arm/boot/dts/sun7i-a20-olinuxino-evb.dts
>>>
>> Relooking at their website I can see that the device does not come under
>> the olinuxino brand so maybe I should rename the dts to
>> sun7i-a20-olimex-som-evb.dts
>
> Ack for renaming / +1
>
> Regards,
>
> Hans

p.s.

Can you please also send a v2 of the u-boot patch taking the renaming into
account ?

Regards,

Hans


From shawn.lin at rock-chips.com  Fri Aug 21 00:48:33 2015
From: shawn.lin at rock-chips.com (Shawn Lin)
Date: Fri, 21 Aug 2015 15:48:33 +0800
Subject: [RFC PATCH v6 1/9] mmc: dw_mmc: Add external dma interface support
In-Reply-To: <55D6D581.3050509@samsung.com>
References: <1440060204-26203-1-git-send-email-shawn.lin@rock-chips.com>
 <1440060233-26244-1-git-send-email-shawn.lin@rock-chips.com>
 <55D6C4D4.8010005@samsung.com> <55D6C57D.4070402@rock-chips.com>
 <55D6C6B6.3060706@samsung.com> <55D6D2EF.7010501@rock-chips.com>
 <55D6D581.3050509@samsung.com>
Message-ID: <55D6D7D1.90105@rock-chips.com>

On 2015/8/21 15:38, Jaehoon Chung wrote:
> On 08/21/2015 04:27 PM, Shawn Lin wrote:
>> On 2015/8/21 14:35, Jaehoon Chung wrote:
>>> On 08/21/2015 03:30 PM, Shawn Lin wrote:
>>>> On 2015/8/21 14:27, Jaehoon Chung wrote:
>>>>> Hi, Shawn.
>>>>>
>>>>> Is this based on Ulf's repository?
>>>>
>>>>
>>>> no, it's based on "https://github.com/jh80chung/dw-mmc.git tags/dw-mmc-for-ulf-v4.2" ??
>>>
>>> Oh..I will rebase to Ulf's next branch on this weekend.
>>> Then could you rebase this patch? And i added more comments at below.. :)
>>>
>>
>> Okay, I will rebase to Ulf's next.
>>
>>> Best Regards,
>>> Jaehoon Chung
>>>
>>>>
>>
>> [...]
>>
>>>>>> index ec6dbcd..7e1d13b 100644
>>>>>> --- a/drivers/mmc/host/dw_mmc-pltfm.c
>>>>>> +++ b/drivers/mmc/host/dw_mmc-pltfm.c
>>>>>> @@ -59,6 +59,8 @@ int dw_mci_pltfm_register(struct platform_device *pdev,
>>>>>>         host->pdata = pdev->dev.platform_data;
>>>>>>
>>>>>>         regs = platform_get_resource(pdev, IORESOURCE_MEM, 0);
>>>>>> +    /* Get registers' physical base address */
>>>>>> +    host->phy_regs = (void *)(regs->start);
>>>>>>         host->regs = devm_ioremap_resource(&pdev->dev, regs);
>>>>>>         if (IS_ERR(host->regs))
>>>>>>             return PTR_ERR(host->regs);
>>>>>
>>>>> Is this board specific code? If so, separate the patch.
>>
>> It's might not board specific code.
>> dmaengine need dw_mmc's *physical* fifo address for data transfer, so I get controller physical address  here in order to calculate physical fifo address.
>>
>> regs is from dt-bindings, for instance:
>>           dwmmc0 at 12200000 {
>>                   compatible = "snps,dw-mshc";
>>                    clocks = <&clock 351>, <&clock 132>;
>>                   clock-names = "biu", "ciu";
>>                   reg = <0x12200000 0x1000>;
>>                   interrupts = <0 75 0>;
>>                   #address-cells = <1>;
>>                   #size-cells = <0>;
>>           };
>>
>> so, host->phy_regs will be 0x12200000 .
>>
>> [...]
>>
>>>>>> +static void dw_mci_dmac_complete_dma(void *arg)
>>>>>>     {
>>>>>> +    struct dw_mci *host = arg;
>>>>>>         struct mmc_data *data = host->data;
>>>>>>
>>>>>>         dev_vdbg(host->dev, "DMA complete\n");
>>>>>>
>>>>>> +    if (host->use_dma == TRANS_MODE_EDMAC)
>>>>>> +        if (data && (data->flags & MMC_DATA_READ))
>>>>>
>>>>> Combine one condition.
>>
>> okay.
>>
>> [...]
>>
>>>>>> +    u32 fifo_offset = host->fifo_reg - host->regs;
>>>>>> +    int ret = 0;
>>>>>> +
>>>>>> +    /* Set external dma config: burst size, burst width */
>>>>>> +    cfg.dst_addr = (dma_addr_t)(host->phy_regs + fifo_offset);
>>>>>
>>>>> host->phy_regs is not assigned?
>>
>> we got it at dw_mci_pltfm_register. See comments above. :)
>>
>> [...]
>>
>>>>>>             mmc->max_blk_count = mmc->max_req_size / 512;
>>>>>> +    } else if (host->use_dma == TRANS_MODE_EDMAC) {
>>>>>> +            mmc->max_segs = 64;
>>>>>> +            mmc->max_blk_size = 65536;
>>>>>> +            mmc->max_blk_count = 65535;
>>>>>> +            mmc->max_req_size =
>>>>>> +                    mmc->max_blk_size * mmc->max_blk_count;
>>>>>> +            mmc->max_seg_size = mmc->max_req_size;
>>>>>
>>>>> Fix the indention
>>
>> Hmm..I check it attentively but can't find the indention . Might it's because you apply it against Ulf's repo?
>>
>>>>>
>>
>> [...]
>>
>>>>>>
>>>>>> -    /* Alloc memory for sg translation */
>>>>>> -    host->sg_cpu = dmam_alloc_coherent(host->dev, PAGE_SIZE,
>>>>>> -                      &host->sg_dma, GFP_KERNEL);
>>>>>> -    if (!host->sg_cpu) {
>>>>>> -        dev_err(host->dev, "%s: could not alloc DMA memory\n",
>>>>>> -            __func__);
>>>>>> +    /* Check tansfer mode */
>>>>>> +    trans_mode = SDMMC_GET_TRANS_MODE(mci_readl(host, HCON));
>>>>>> +    if (trans_mode == 0) {
>>>>>> +        trans_mode = TRANS_MODE_IDMAC;
>>>>>> +    } else if (trans_mode == 1 || trans_mode == 2) {
>>>>>> +        trans_mode = TRANS_MODE_EDMAC;
>>>>>> +    } else {
>>>>>> +        trans_mode = TRANS_MODE_PIO;
>>>>>
>>>>> what are trans_mode "0, 1, 2"?
>>>>> (00 - none) is NO-DMA interface, isn't? is it IDMAC mode?
>>>>>
>>
>> No, I guess the databook's ambiguous description confuse everybody.
>>
>> I got double comfirm from my ASCI team as well as Synoposys
>> 2b'00: NO-DMA interface -->  It support IDMAC actually
>> 2b'01 & 2b'02: DW_DMA & GENERIC_DMA --> Support 2 types of external dma.
>> 2b'02: NON-DW-DMA --> only support PIO
>
> Then Could you add the comment about this?
> Use definition instead of "0, 1, 2". Developer don't know meaning that is 0, 1, 2.
>

Okay. :)))

> Best Regards,
> Jaehoon Chung
>
>>
>> refer to the description below:
>> Parameter Name: DMA_INTERFACE
>> Legal Values: 0-3
>> Default Value: 0
>> Description:
>>   0- No DMA Interface
>>   1- DesignWare DMA Interface
>>   2- Generic DMA Interface
>>   3- Non DW DMA Interface
>> In DesignWare DMA mode, request/acknowledge protocol meets DW_ahb_dmac
>> controller protocol. In this mode, host data bus is also used for DMA transfers.Generic DMA-type interface has simpler request/acknowledge handshake and has dedicated read/write data bus for DMA transfers. Non DW DMAC interface uses dw_dma_single interface in addition to the existing interface and uses host data bus for DMA transfers. This is configurable only if INTERNAL_DMAC=0.
>>
>>>>>>             goto no_dma;
>>>>>>         }
>>>
>>>>>> +        dev_info(host->dev, "Using external DMA controller.\n");
>>>>>> +    }
>>>>>>
>>>>>>         if (!host->dma_ops)
>>>>>>             goto no_dma;
>>>>>> @@ -2562,12 +2720,12 @@ static void dw_mci_init_dma(struct dw_mci *host)
>>>>>>             goto no_dma;
>>>>>>         }
>>>>>>
>>>>>> -    host->use_dma = 1;
>>>>>> +    host->use_dma = trans_mode;
>>>>>
>>>>> Also confuse, if trans_mode is assigned host->use_dma, can mode value be directly assigned to host->use_dma?
>>>>>
>>
>> Good idea, I will do it.  :)
>>
>>>>> trans_mode = TRAMS_MODE_PIO;
>>>>> host->use_dma = trans_mode;
>>>>>
>>
>> [...]
>>
>>>>>>
>>>>>> @@ -2890,7 +3047,7 @@ int dw_mci_probe(struct dw_mci *host)
>>>>>>          * Get the host data width - this assumes that HCON has been set with
>>>>>>          * the correct values.
>>>>>>          */
>>>>>> -    i = (mci_readl(host, HCON) >> 7) & 0x7;
>>>>>> +    i = SDMMC_GET_HDATA_WIDTH(mci_readl(host, HCON));
>>>>>
>>>>> This is not related with supporting external dma interface.
>>>>> Separate this.
>>>>>
>>
>> Okay, It will be split into another one.
>>
>>>>>>         if (!i) {
>>>>>>             host->push_data = dw_mci_push_data16;
>>>>>>             host->pull_data = dw_mci_pull_data16;
>>
>>
>>
>
>
> _______________________________________________
> Linux-rockchip mailing list
> Linux-rockchip at lists.infradead.org
> http://lists.infradead.org/mailman/listinfo/linux-rockchip
>


-- 
Best Regards
Shawn Lin



From Haibo.Chen at freescale.com  Fri Aug 21 01:08:46 2015
From: Haibo.Chen at freescale.com (Chen Bough)
Date: Fri, 21 Aug 2015 08:08:46 +0000
Subject: [PATCH v2 1/5] input: touchscreen: add imx6ul_tsc driver support
In-Reply-To: <20150819051131.GA12545@dtor-pixel>
References: <1438077521-12857-1-git-send-email-haibo.chen@freescale.com>
 <1438077521-12857-2-git-send-email-haibo.chen@freescale.com>
 <20150819051131.GA12545@dtor-pixel>
Message-ID: <BY1PR03MB1388094367475E41BA4DB7BD9A650@BY1PR03MB1388.namprd03.prod.outlook.com>

Hi Dmitry,

Thanks for your patient review, especially for the patch you attached.

I test your patch these days, with below change, touch can work normally.
(also change the xnur to active low in dts)

In probe function:

> -	tsc->xnur_gpio = of_get_named_gpio(np, "xnur-gpio", 0);
> -	err = gpio_request_one(tsc->xnur_gpio, GPIOF_IN, "tsc_X-");
> -	if (err) {
> -		dev_err(&pdev->dev, "failed to request GPIO tsc_X-\n");
> +	input_set_drvdata(input_dev, tsc);
> +
> +	tsc->dev = &pdev->dev;
> +	tsc->input = input_dev;
> +	init_completion(&tsc->completion);
> +
> +	tsc->xnur_gpio = devm_gpiod_get(&pdev->dev, "xnur-gpio", GPIOD_IN);  

Here, we need to change "xnur-gpio" to "xnur", otherwise the gpio request will be failed.
This is because gpiod common code already add suffix '-gpio' or 'gpios'.  



For others, your patch seems normal and rational. I will add your patch and send patch-V3.

Thanks again!


Best Regards
Haibo Chen



> -----Original Message-----
> From: Dmitry Torokhov [mailto:dmitry.torokhov at gmail.com]
> Sent: Wednesday, August 19, 2015 1:12 PM
> To: Chen Haibo-B51421
> Cc: robh+dt at kernel.org; pawel.moll at arm.com; mark.rutland at arm.com;
> ijc+devicetree at hellion.org.uk; galak at codeaurora.org; shawnguo at kernel.org;
> kernel at pengutronix.de; linux at arm.linux.org.uk; hans.verkuil at cisco.com;
> hadess at hadess.net; mchehab at osg.samsung.com; mamlinav at gmail.com;
> arnd at arndb.de; jonathar at broadcom.com; hdegoede at redhat.com;
> christian.gmeiner at gmail.com; scott.liu at emc.com.tw; geert at linux-m68k.org;
> benjamin.tissoires at redhat.com; sebastien.szymanski at armadeus.com;
> sbranden at broadcom.com; devicetree at vger.kernel.org; linux-
> kernel at vger.kernel.org; linux-arm-kernel at lists.infradead.org; linux-
> input at vger.kernel.org
> Subject: Re: [PATCH v2 1/5] input: touchscreen: add imx6ul_tsc driver
> support
> 
> Hi Haibo,
> 
> On Tue, Jul 28, 2015 at 05:58:37PM +0800, Haibo Chen wrote:
> > Freescale i.MX6UL contains a internal touchscreen controller, this
> > patch add a driver to support this controller.
> >
> 
> This looks pretty reasonable; just a few comments below.
> 
> > Signed-off-by: Haibo Chen <haibo.chen at freescale.com>
> > ---
> >  drivers/input/touchscreen/Kconfig      |  12 +
> >  drivers/input/touchscreen/Makefile     |   1 +
> >  drivers/input/touchscreen/imx6ul_tsc.c | 504
> > +++++++++++++++++++++++++++++++++
> >  3 files changed, 517 insertions(+)
> >  create mode 100644 drivers/input/touchscreen/imx6ul_tsc.c
> >
> > diff --git a/drivers/input/touchscreen/Kconfig
> > b/drivers/input/touchscreen/Kconfig
> > index 5b272ba..32c300d 100644
> > --- a/drivers/input/touchscreen/Kconfig
> > +++ b/drivers/input/touchscreen/Kconfig
> > @@ -479,6 +479,18 @@ config TOUCHSCREEN_MTOUCH
> >  	  To compile this driver as a module, choose M here: the
> >  	  module will be called mtouch.
> >
> > +config TOUCHSCREEN_IMX6UL_TSC
> > +	tristate "Freescale i.MX6UL touchscreen controller"
> > +	depends on OF
> > +	help
> > +	  Say Y here if you have a Freescale i.MX6UL, and want to
> > +	  use the internal touchscreen controller.
> > +
> > +	  If unsure, say N.
> > +
> > +	  To compile this driver as a module, choose M here: the
> > +	  moduel will be called imx6ul_tsc.
> > +
> >  config TOUCHSCREEN_INEXIO
> >  	tristate "iNexio serial touchscreens"
> >  	select SERIO
> > diff --git a/drivers/input/touchscreen/Makefile
> > b/drivers/input/touchscreen/Makefile
> > index c85aae2..9379b32 100644
> > --- a/drivers/input/touchscreen/Makefile
> > +++ b/drivers/input/touchscreen/Makefile
> > @@ -38,6 +38,7 @@ obj-$(CONFIG_TOUCHSCREEN_EGALAX)	+= egalax_ts.o
> >  obj-$(CONFIG_TOUCHSCREEN_FUJITSU)	+= fujitsu_ts.o
> >  obj-$(CONFIG_TOUCHSCREEN_GOODIX)	+= goodix.o
> >  obj-$(CONFIG_TOUCHSCREEN_ILI210X)	+= ili210x.o
> > +obj-$(CONFIG_TOUCHSCREEN_IMX6UL_TSC)	+= imx6ul_tsc.o
> >  obj-$(CONFIG_TOUCHSCREEN_INEXIO)	+= inexio.o
> >  obj-$(CONFIG_TOUCHSCREEN_INTEL_MID)	+= intel-mid-touch.o
> >  obj-$(CONFIG_TOUCHSCREEN_IPROC)		+= bcm_iproc_tsc.o
> > diff --git a/drivers/input/touchscreen/imx6ul_tsc.c
> > b/drivers/input/touchscreen/imx6ul_tsc.c
> > new file mode 100644
> > index 0000000..807f1db
> > --- /dev/null
> > +++ b/drivers/input/touchscreen/imx6ul_tsc.c
> > @@ -0,0 +1,504 @@
> > +/*
> > + * Freescale i.MX6UL touchscreen controller driver
> > + *
> > + * Copyright (C) 2015 Freescale Semiconductor, Inc.
> > + *
> > + * This program is free software; you can redistribute it and/or
> > +modify
> > + * it under the terms of the GNU General Public License version 2 as
> > + * published by the Free Software Foundation.
> > + */
> > +
> > +#include <linux/errno.h>
> > +#include <linux/kernel.h>
> > +#include <linux/module.h>
> > +#include <linux/gpio.h>
> > +#include <linux/input.h>
> > +#include <linux/slab.h>
> > +#include <linux/completion.h>
> > +#include <linux/delay.h>
> > +#include <linux/of.h>
> > +#include <linux/of_device.h>
> > +#include <linux/of_gpio.h>
> > +#include <linux/of_irq.h>
> 
> I do not think you need of_irq and of_device.
> 
> > +#include <linux/interrupt.h>
> > +#include <linux/platform_device.h>
> > +#include <linux/clk.h>
> > +#include <linux/io.h>
> > +
> > +/* ADC configuration registers field define */
> > +#define ADC_AIEN		(0x1 << 7)
> > +#define ADC_CONV_DISABLE	0x1F
> > +#define ADC_CAL			(0x1 << 7)
> > +#define ADC_CALF		0x2
> > +#define ADC_12BIT_MODE		(0x2 << 2)
> > +#define ADC_IPG_CLK		0x00
> > +#define ADC_CLK_DIV_8		(0x03 << 5)
> > +#define ADC_SHORT_SAMPLE_MODE	(0x0 << 4)
> > +#define ADC_HARDWARE_TRIGGER	(0x1 << 13)
> > +#define SELECT_CHANNEL_4	0x04
> > +#define SELECT_CHANNEL_1	0x01
> > +#define DISABLE_CONVERSION_INT	(0x0 << 7)
> > +
> > +/* ADC registers */
> > +#define REG_ADC_HC0		0x00
> > +#define REG_ADC_HC1		0x04
> > +#define REG_ADC_HC2		0x08
> > +#define REG_ADC_HC3		0x0C
> > +#define REG_ADC_HC4		0x10
> > +#define REG_ADC_HS		0x14
> > +#define REG_ADC_R0		0x18
> > +#define REG_ADC_CFG		0x2C
> > +#define REG_ADC_GC		0x30
> > +#define REG_ADC_GS		0x34
> > +
> > +#define ADC_TIMEOUT		msecs_to_jiffies(100)
> > +
> > +/* TSC registers */
> > +#define REG_TSC_BASIC_SETING	0x00
> > +#define REG_TSC_PRE_CHARGE_TIME	0x10
> > +#define REG_TSC_FLOW_CONTROL	0x20
> > +#define REG_TSC_MEASURE_VALUE	0x30
> > +#define REG_TSC_INT_EN		0x40
> > +#define REG_TSC_INT_SIG_EN	0x50
> > +#define REG_TSC_INT_STATUS	0x60
> > +#define REG_TSC_DEBUG_MODE	0x70
> > +#define REG_TSC_DEBUG_MODE2	0x80
> > +
> > +/* TSC configuration registers field define */
> > +#define DETECT_4_WIRE_MODE	(0x0 << 4)
> > +#define AUTO_MEASURE		0x1
> > +#define MEASURE_SIGNAL		0x1
> > +#define DETECT_SIGNAL		(0x1 << 4)
> > +#define VALID_SIGNAL		(0x1 << 8)
> > +#define MEASURE_INT_EN		0x1
> > +#define MEASURE_SIG_EN		0x1
> > +#define VALID_SIG_EN		(0x1 << 8)
> > +#define DE_GLITCH_2		(0x2 << 29)
> > +#define START_SENSE		(0x1 << 12)
> > +#define TSC_DISABLE		(0x1 << 16)
> > +#define DETECT_MODE		0x2
> > +
> > +struct imx6ul_tsc {
> > +	struct device *dev;
> > +	struct input_dev *input;
> > +	void __iomem *tsc_regs;
> > +	void __iomem *adc_regs;
> > +	struct clk *tsc_clk;
> > +	struct clk *adc_clk;
> > +
> > +	int xnur_gpio;
> > +	int measure_delay_time;
> > +	int pre_charge_time;
> > +
> > +	struct completion completion;
> > +};
> > +
> > +/*
> > + * TSC module need ADC to get the measure value. So
> > + * before config TSC, we should initialize ADC module.
> > + */
> > +static void imx6ul_adc_init(struct imx6ul_tsc *tsc) {
> > +	int adc_hc = 0;
> > +	int adc_gc;
> > +	int adc_gs;
> > +	int adc_cfg;
> > +	int timeout;
> > +
> > +	adc_cfg = readl(tsc->adc_regs + REG_ADC_CFG);
> > +	adc_cfg |= ADC_12BIT_MODE | ADC_IPG_CLK;
> > +	adc_cfg |= ADC_CLK_DIV_8 | ADC_SHORT_SAMPLE_MODE;
> > +	adc_cfg &= ~ADC_HARDWARE_TRIGGER;
> > +	writel(adc_cfg, tsc->adc_regs + REG_ADC_CFG);
> > +
> > +	/* enable calibration interrupt */
> > +	adc_hc |= ADC_AIEN;
> > +	adc_hc |= ADC_CONV_DISABLE;
> > +	writel(adc_hc, tsc->adc_regs + REG_ADC_HC0);
> > +
> > +	/* start ADC calibration */
> > +	adc_gc = readl(tsc->adc_regs + REG_ADC_GC);
> > +	adc_gc |= ADC_CAL;
> > +	writel(adc_gc, tsc->adc_regs + REG_ADC_GC);
> > +
> 
> Since this is called on every resume you need to reinit completion;
> probably at the beginning of this function.
> 
> > +	timeout = wait_for_completion_timeout
> > +			(&tsc->completion, ADC_TIMEOUT);
> > +	if (timeout == 0)
> > +		dev_err(tsc->dev, "Timeout for adc calibration\n");
> > +
> > +	adc_gs = readl(tsc->adc_regs + REG_ADC_GS);
> > +	if (adc_gs & ADC_CALF)
> > +		dev_err(tsc->dev, "ADC calibration failed\n");
> > +
> > +	/* TSC need the ADC work in hardware trigger */
> > +	adc_cfg = readl(tsc->adc_regs + REG_ADC_CFG);
> > +	adc_cfg |= ADC_HARDWARE_TRIGGER;
> > +	writel(adc_cfg, tsc->adc_regs + REG_ADC_CFG); }
> > +
> > +/*
> > + * This is a TSC workaround. Currently TSC misconnect two
> > + * ADC channels, this function remap channel configure for
> > + * hardware trigger.
> > + */
> > +static void imx6ul_tsc_channel_config(struct imx6ul_tsc *tsc) {
> > +	int adc_hc0, adc_hc1, adc_hc2, adc_hc3, adc_hc4;
> > +
> > +	adc_hc0 = DISABLE_CONVERSION_INT;
> > +	writel(adc_hc0, tsc->adc_regs + REG_ADC_HC0);
> > +
> > +	adc_hc1 = DISABLE_CONVERSION_INT | SELECT_CHANNEL_4;
> > +	writel(adc_hc1, tsc->adc_regs + REG_ADC_HC1);
> > +
> > +	adc_hc2 = DISABLE_CONVERSION_INT;
> > +	writel(adc_hc2, tsc->adc_regs + REG_ADC_HC2);
> > +
> > +	adc_hc3 = DISABLE_CONVERSION_INT | SELECT_CHANNEL_1;
> > +	writel(adc_hc3, tsc->adc_regs + REG_ADC_HC3);
> > +
> > +	adc_hc4 = DISABLE_CONVERSION_INT;
> > +	writel(adc_hc4, tsc->adc_regs + REG_ADC_HC4); }
> > +
> > +/*
> > + * TSC setting, confige the pre-charge time and measure delay time.
> > + * different touch screen may need different pre-charge time and
> > + * measure delay time.
> > + */
> > +static void imx6ul_tsc_set(struct imx6ul_tsc *tsc) {
> > +	int basic_setting = 0;
> > +	int start;
> > +
> > +	basic_setting |= tsc->measure_delay_time << 8;
> > +	basic_setting |= DETECT_4_WIRE_MODE | AUTO_MEASURE;
> > +	writel(basic_setting, tsc->tsc_regs + REG_TSC_BASIC_SETING);
> > +
> > +	writel(DE_GLITCH_2, tsc->tsc_regs + REG_TSC_DEBUG_MODE2);
> > +
> > +	writel(tsc->pre_charge_time, tsc->tsc_regs +
> REG_TSC_PRE_CHARGE_TIME);
> > +	writel(MEASURE_INT_EN, tsc->tsc_regs + REG_TSC_INT_EN);
> > +	writel(MEASURE_SIG_EN | VALID_SIG_EN,
> > +		tsc->tsc_regs + REG_TSC_INT_SIG_EN);
> > +
> > +	/* start sense detection */
> > +	start = readl(tsc->tsc_regs + REG_TSC_FLOW_CONTROL);
> > +	start |= START_SENSE;
> > +	start &= ~TSC_DISABLE;
> > +	writel(start, tsc->tsc_regs + REG_TSC_FLOW_CONTROL); }
> > +
> > +static void imx6ul_tsc_init(struct imx6ul_tsc *tsc) {
> > +	imx6ul_adc_init(tsc);
> > +	imx6ul_tsc_channel_config(tsc);
> > +	imx6ul_tsc_set(tsc);
> > +}
> > +
> > +static irqreturn_t tsc_irq_fn(int irq, void *dev_id) {
> > +	struct imx6ul_tsc *tsc = (struct imx6ul_tsc *)dev_id;
> 
> No need to cast void pointers.
> 
> > +	int status;
> > +	int value;
> > +	int x, y;
> > +	int xnur;
> > +	int debug_mode2;
> > +	int state_machine;
> > +	int start;
> > +	unsigned long timeout;
> > +
> > +	status = readl(tsc->tsc_regs + REG_TSC_INT_STATUS);
> > +
> > +	/* write 1 to clear the bit measure-signal */
> > +	writel(MEASURE_SIGNAL | DETECT_SIGNAL,
> > +		tsc->tsc_regs + REG_TSC_INT_STATUS);
> > +
> > +	/* It's a HW self-clean bit. Set this bit and start sense detection
> */
> > +	start = readl(tsc->tsc_regs + REG_TSC_FLOW_CONTROL);
> > +	start |= START_SENSE;
> > +	writel(start, tsc->tsc_regs + REG_TSC_FLOW_CONTROL);
> > +
> > +	if (status & MEASURE_SIGNAL) {
> > +		value = readl(tsc->tsc_regs + REG_TSC_MEASURE_VALUE);
> > +		x = (value >> 16) & 0x0fff;
> > +		y = value & 0x0fff;
> > +
> > +		/*
> > +		 * Delay some time(max 2ms), wait the pre-charge done.
> > +		 * After the pre-change mode, TSC go into detect mode.
> > +		 * And in detect mode, we can get the xnur gpio value.
> > +		 * If xnur is low, this means the touch screen still
> > +		 * be touched. If xnur is high, this means finger leave
> > +		 * the touch screen.
> > +		 */
> > +		timeout = jiffies + HZ/500;
> > +		do {
> > +			if (time_after(jiffies, timeout)) {
> > +				xnur = 0;
> > +				goto touch_event;
> > +			}
> > +			usleep_range(200, 400);
> > +			debug_mode2 = readl(tsc->tsc_regs +
> REG_TSC_DEBUG_MODE2);
> > +			state_machine = (debug_mode2 >> 20) & 0x7;
> > +		} while (state_machine != DETECT_MODE);
> > +		usleep_range(200, 400);
> > +
> > +		xnur = gpio_get_value(tsc->xnur_gpio);
> 
> It seems to me that this GPIO is actually active low: we reporting active
> touch as long as we read 0.
> 
> > +touch_event:
> > +		if (xnur == 0) {
> > +			input_report_key(tsc->input, BTN_TOUCH, 1);
> > +			input_report_abs(tsc->input, ABS_X, x);
> > +			input_report_abs(tsc->input, ABS_Y, y);
> > +		} else
> > +			input_report_key(tsc->input, BTN_TOUCH, 0);
> 
> If one branch has braces all of them should have braces.
> 
> > +
> > +		input_sync(tsc->input);
> > +	}
> > +
> > +	return IRQ_HANDLED;
> > +}
> > +
> > +static irqreturn_t adc_irq_fn(int irq, void *dev_id) {
> > +	struct imx6ul_tsc *tsc = (struct imx6ul_tsc *)dev_id;
> > +	int coco;
> > +	int value;
> > +
> > +	coco = readl(tsc->adc_regs + REG_ADC_HS);
> > +	if (coco & 0x01) {
> > +		value = readl(tsc->adc_regs + REG_ADC_R0);
> > +		complete(&tsc->completion);
> > +	}
> > +
> > +	return IRQ_HANDLED;
> > +}
> > +
> > +static const struct of_device_id imx6ul_tsc_match[] = {
> > +	{ .compatible = "fsl,imx6ul-tsc", },
> > +	{ /* sentinel */ }
> > +};
> > +MODULE_DEVICE_TABLE(of, imx6ul_tsc_match);
> > +
> > +static int imx6ul_tsc_probe(struct platform_device *pdev) {
> > +	struct imx6ul_tsc *tsc;
> > +	struct resource *tsc_mem;
> > +	struct resource *adc_mem;
> > +	struct input_dev *input_dev;
> > +	struct device_node *np = pdev->dev.of_node;
> > +	int err;
> > +	int tsc_irq;
> > +	int adc_irq;
> > +
> > +	tsc = devm_kzalloc(&pdev->dev, sizeof(struct imx6ul_tsc),
> GFP_KERNEL);
> > +	input_dev = devm_input_allocate_device(&pdev->dev);
> 
> Using devm does not mean you do not need to check results of memory
> allocation.
> 
> > +
> > +	tsc->dev = &pdev->dev;
> > +
> > +	tsc->input = input_dev;
> > +	tsc->input->evbit[0] = BIT_MASK(EV_KEY) | BIT_MASK(EV_ABS);
> > +	tsc->input->keybit[BIT_WORD(BTN_TOUCH)] = BIT_MASK(BTN_TOUCH);
> > +	input_set_abs_params(tsc->input, ABS_X, 0, 0xFFF, 0, 0);
> > +	input_set_abs_params(tsc->input, ABS_Y, 0, 0xFFF, 0, 0);
> > +
> > +	tsc->input->name = "iMX6UL TouchScreen Controller";
> > +
> > +	tsc->xnur_gpio = of_get_named_gpio(np, "xnur-gpio", 0);
> > +	err = gpio_request_one(tsc->xnur_gpio, GPIOF_IN, "tsc_X-");
> 
> Why are you not using devm for gpio? Actually, why don't you also use
> gpiod? As is you are leaking that gpio in all error paths below.
> 
> > +	if (err) {
> > +		dev_err(&pdev->dev, "failed to request GPIO tsc_X-\n");
> > +		return err;
> > +	}
> > +
> > +	tsc_mem = platform_get_resource(pdev, IORESOURCE_MEM, 0);
> > +	tsc->tsc_regs = devm_ioremap_resource(&pdev->dev, tsc_mem);
> > +	if (IS_ERR(tsc->tsc_regs)) {
> > +		dev_err(&pdev->dev, "failed to remap tsc memory\n");
> > +		err = PTR_ERR(tsc->tsc_regs);
> > +		return err;
> > +	}
> > +
> > +	adc_mem = platform_get_resource(pdev, IORESOURCE_MEM, 1);
> > +	tsc->adc_regs = devm_ioremap_resource(&pdev->dev, adc_mem);
> > +	if (IS_ERR(tsc->adc_regs)) {
> > +		dev_err(&pdev->dev, "failed to remap adc memory\n");
> > +		err = PTR_ERR(tsc->adc_regs);
> > +		return err;
> > +	}
> > +
> > +	tsc->tsc_clk = devm_clk_get(&pdev->dev, "tsc");
> > +	if (IS_ERR(tsc->tsc_clk)) {
> > +		dev_err(&pdev->dev, "failed getting tsc clock\n");
> > +		err = PTR_ERR(tsc->tsc_clk);
> > +		return err;
> > +	}
> > +
> > +	tsc->adc_clk = devm_clk_get(&pdev->dev, "adc");
> > +	if (IS_ERR(tsc->adc_clk)) {
> > +		dev_err(&pdev->dev, "failed getting adc clock\n");
> > +		err = PTR_ERR(tsc->adc_clk);
> > +		return err;
> > +	}
> > +
> > +	tsc_irq = platform_get_irq(pdev, 0);
> > +	if (tsc_irq < 0) {
> > +		dev_err(&pdev->dev, "no tsc irq resource?\n");
> > +		return tsc_irq;
> > +	}
> > +
> > +	adc_irq = platform_get_irq(pdev, 1);
> > +	if (adc_irq <= 0) {
> > +		dev_err(&pdev->dev, "no adc irq resource?\n");
> > +		return adc_irq;
> > +	}
> > +
> > +	err = devm_request_threaded_irq(tsc->dev, tsc_irq,
> > +					NULL, tsc_irq_fn,
> > +					IRQF_TRIGGER_HIGH | IRQF_ONESHOT,
> > +					dev_name(&pdev->dev), tsc);
> > +	if (err < 0) {
> > +		dev_err(&pdev->dev,
> > +			"failed requesting tsc irq %d\n",
> > +					    tsc_irq);
> > +		return err;
> > +	}
> > +
> > +	err = devm_request_irq(tsc->dev, adc_irq,
> > +				adc_irq_fn, 0,
> > +				dev_name(&pdev->dev), tsc);
> > +	if (err < 0) {
> > +		dev_err(&pdev->dev,
> > +			"failed requesting adc irq %d\n",
> > +					    adc_irq);
> > +		return err;
> > +	}
> > +
> > +	err = of_property_read_u32(np, "measure-delay-time",
> > +				&tsc->measure_delay_time);
> > +	if (err)
> > +		tsc->measure_delay_time = 0xffff;
> > +
> > +	err = of_property_read_u32(np, "pre-charge-time",
> > +				&tsc->pre_charge_time);
> > +	if (err)
> > +		tsc->pre_charge_time = 0xfff;
> > +
> > +	init_completion(&tsc->completion);
> > +
> > +	err = clk_prepare_enable(tsc->adc_clk);
> > +	if (err) {
> > +		dev_err(&pdev->dev,
> > +			"Could not prepare or enable the adc clock.\n");
> > +		return err;
> > +	}
> > +
> > +	err = clk_prepare_enable(tsc->tsc_clk);
> > +	if (err) {
> > +		dev_err(&pdev->dev,
> > +			"Could not prepare or enable the tsc clock.\n");
> > +		goto error_tsc_clk_enable;
> > +	}
> > +
> > +	err = input_register_device(tsc->input);
> > +	if (err < 0) {
> > +		dev_err(&pdev->dev, "failed to register input device\n");
> > +		err = -EIO;
> > +		goto err_input_register;
> > +	}
> > +
> > +	imx6ul_tsc_init(tsc);
> 
> Enabling clock and initializing the controller is better in open() method
> of input device. If you also implement close() you can get rid of
> remove().
> 
> > +
> > +	platform_set_drvdata(pdev, tsc);
> > +	return 0;
> > +
> > +err_input_register:
> > +	clk_disable_unprepare(tsc->tsc_clk);
> > +error_tsc_clk_enable:
> > +	clk_disable_unprepare(tsc->adc_clk);
> > +
> > +	return err;
> > +}
> > +
> > +static void imx6ul_tsc_disable(struct imx6ul_tsc *tsc) {
> > +	int tsc_flow;
> > +	int adc_cfg;
> > +
> > +	/* TSC controller enters to idle status */
> > +	tsc_flow = readl(tsc->tsc_regs + REG_TSC_FLOW_CONTROL);
> > +	tsc_flow |= TSC_DISABLE;
> > +	writel(tsc_flow, tsc->tsc_regs + REG_TSC_FLOW_CONTROL);
> > +
> > +	/* ADC controller enters to stop mode */
> > +	adc_cfg = readl(tsc->adc_regs + REG_ADC_HC0);
> > +	adc_cfg |= ADC_CONV_DISABLE;
> > +	writel(adc_cfg, tsc->adc_regs + REG_ADC_HC0); }
> > +
> > +static int imx6ul_tsc_remove(struct platform_device *pdev) {
> > +	struct imx6ul_tsc *tsc = platform_get_drvdata(pdev);
> > +
> > +	imx6ul_tsc_disable(tsc);
> > +
> > +	clk_disable_unprepare(tsc->tsc_clk);
> > +	clk_disable_unprepare(tsc->adc_clk);
> > +	input_unregister_device(tsc->input);
> > +	kfree(tsc);
> 
> Tsc is allocated with devm(), you can't kfree() it.
> > +
> > +	return 0;
> > +}
> > +
> > +static int __maybe_unused imx6ul_tsc_suspend(struct device *dev) {
> > +	struct platform_device *pdev = to_platform_device(dev);
> > +	struct imx6ul_tsc *tsc = platform_get_drvdata(pdev);
> > +
> > +	imx6ul_tsc_disable(tsc);
> > +
> > +	clk_disable_unprepare(tsc->tsc_clk);
> > +	clk_disable_unprepare(tsc->adc_clk);
> > +
> > +	return 0;
> > +}
> > +
> > +static int __maybe_unused imx6ul_tsc_resume(struct device *dev) {
> > +	struct platform_device *pdev = to_platform_device(dev);
> > +	struct imx6ul_tsc *tsc = platform_get_drvdata(pdev);
> > +	int err;
> > +
> > +	err = clk_prepare_enable(tsc->adc_clk);
> > +	if (err)
> > +		return err;
> > +
> > +	err = clk_prepare_enable(tsc->tsc_clk);
> > +	if (err) {
> > +		clk_disable_unprepare(tsc->adc_clk);
> > +		return err;
> > +	}
> > +
> > +	imx6ul_tsc_init(tsc);
> > +	return 0;
> > +}
> > +
> > +static SIMPLE_DEV_PM_OPS(imx6ul_tsc_pm_ops,
> > +			 imx6ul_tsc_suspend,
> > +			 imx6ul_tsc_resume);
> > +
> > +static struct platform_driver imx6ul_tsc_driver = {
> > +	.driver		= {
> > +		.name	= "imx6ul-tsc",
> > +		.owner	= THIS_MODULE,
> > +		.of_match_table	= imx6ul_tsc_match,
> > +		.pm	= &imx6ul_tsc_pm_ops,
> > +	},
> > +	.probe		= imx6ul_tsc_probe,
> > +	.remove		= imx6ul_tsc_remove,
> > +};
> > +module_platform_driver(imx6ul_tsc_driver);
> > +
> > +MODULE_AUTHOR("Haibo Chen <haibo.chen at freescale.com>");
> > +MODULE_DESCRIPTION("Freescale i.MX6UL Touchscreen controller
> > +driver"); MODULE_LICENSE("GPL v2");
> > --
> > 1.9.1
> >
> 
> Can you try the patch below and let me know if it still works (you'll
> need to adjust your DTS for xnur gpio being active low).
> 
> Thanks!
> 
> --
> Dmitry
> 
> Input: imx6ul_tsc - misc changes
> 
> From: Dmitry Torokhov <dmitry.torokhov at gmail.com>
> 
> Signed-off-by: Dmitry Torokhov <dmitry.torokhov at gmail.com>
> ---
>  .../bindings/input/touchscreen/imx6ul_tsc.txt      |    2
>  drivers/input/touchscreen/Kconfig                  |    2
>  drivers/input/touchscreen/imx6ul_tsc.c             |  262 +++++++++++---
> ------
>  3 files changed, 143 insertions(+), 123 deletions(-)
> 
> diff --git
> a/Documentation/devicetree/bindings/input/touchscreen/imx6ul_tsc.txt
> b/Documentation/devicetree/bindings/input/touchscreen/imx6ul_tsc.txt
> index ac41c32..c933588 100644
> --- a/Documentation/devicetree/bindings/input/touchscreen/imx6ul_tsc.txt
> +++ b/Documentation/devicetree/bindings/input/touchscreen/imx6ul_tsc.txt
> @@ -29,7 +29,7 @@ Example:
>  		clock-names = "tsc", "adc";
>  		pinctrl-names = "default";
>  		pinctrl-0 = <&pinctrl_tsc>;
> -		xnur-gpio = <&gpio1 3 GPIO_ACTIVE_HIGH>;
> +		xnur-gpio = <&gpio1 3 GPIO_ACTIVE_LOW>;
>  		measure-delay-time = <0xfff>;
>  		pre-charge-time = <0xffff>;
>  		status = "okay";
> diff --git a/drivers/input/touchscreen/Kconfig
> b/drivers/input/touchscreen/Kconfig
> index 9a1a293..5ecf19b 100644
> --- a/drivers/input/touchscreen/Kconfig
> +++ b/drivers/input/touchscreen/Kconfig
> @@ -481,7 +481,7 @@ config TOUCHSCREEN_MTOUCH
> 
>  config TOUCHSCREEN_IMX6UL_TSC
>  	tristate "Freescale i.MX6UL touchscreen controller"
> -	depends on OF
> +	depends on (OF && GPIOLIB) || COMPILE_TEST
>  	help
>  	  Say Y here if you have a Freescale i.MX6UL, and want to
>  	  use the internal touchscreen controller.
> diff --git a/drivers/input/touchscreen/imx6ul_tsc.c
> b/drivers/input/touchscreen/imx6ul_tsc.c
> index 807f1db..1d028ed 100644
> --- a/drivers/input/touchscreen/imx6ul_tsc.c
> +++ b/drivers/input/touchscreen/imx6ul_tsc.c
> @@ -11,15 +11,12 @@
>  #include <linux/errno.h>
>  #include <linux/kernel.h>
>  #include <linux/module.h>
> -#include <linux/gpio.h>
> +#include <linux/gpio/consumer.h>
>  #include <linux/input.h>
>  #include <linux/slab.h>
>  #include <linux/completion.h>
>  #include <linux/delay.h>
>  #include <linux/of.h>
> -#include <linux/of_device.h>
> -#include <linux/of_gpio.h>
> -#include <linux/of_irq.h>
>  #include <linux/interrupt.h>
>  #include <linux/platform_device.h>
>  #include <linux/clk.h>
> @@ -85,8 +82,8 @@ struct imx6ul_tsc {
>  	void __iomem *adc_regs;
>  	struct clk *tsc_clk;
>  	struct clk *adc_clk;
> +	struct gpio_desc *xnur_gpio;
> 
> -	int xnur_gpio;
>  	int measure_delay_time;
>  	int pre_charge_time;
> 
> @@ -105,6 +102,8 @@ static void imx6ul_adc_init(struct imx6ul_tsc *tsc)
>  	int adc_cfg;
>  	int timeout;
> 
> +	reinit_completion(&tsc->completion);
> +
>  	adc_cfg = readl(tsc->adc_regs + REG_ADC_CFG);
>  	adc_cfg |= ADC_12BIT_MODE | ADC_IPG_CLK;
>  	adc_cfg |= ADC_CLK_DIV_8 | ADC_SHORT_SAMPLE_MODE;
> @@ -196,17 +195,33 @@ static void imx6ul_tsc_init(struct imx6ul_tsc *tsc)
>  	imx6ul_tsc_set(tsc);
>  }
> 
> +static void imx6ul_tsc_disable(struct imx6ul_tsc *tsc)
> +{
> +	int tsc_flow;
> +	int adc_cfg;
> +
> +	/* TSC controller enters to idle status */
> +	tsc_flow = readl(tsc->tsc_regs + REG_TSC_FLOW_CONTROL);
> +	tsc_flow |= TSC_DISABLE;
> +	writel(tsc_flow, tsc->tsc_regs + REG_TSC_FLOW_CONTROL);
> +
> +	/* ADC controller enters to stop mode */
> +	adc_cfg = readl(tsc->adc_regs + REG_ADC_HC0);
> +	adc_cfg |= ADC_CONV_DISABLE;
> +	writel(adc_cfg, tsc->adc_regs + REG_ADC_HC0);
> +}
> +
>  static irqreturn_t tsc_irq_fn(int irq, void *dev_id)
>  {
>  	struct imx6ul_tsc *tsc = (struct imx6ul_tsc *)dev_id;
>  	int status;
>  	int value;
>  	int x, y;
> -	int xnur;
>  	int debug_mode2;
>  	int state_machine;
>  	int start;
>  	unsigned long timeout;
> +	bool touch;
> 
>  	status = readl(tsc->tsc_regs + REG_TSC_INT_STATUS);
> 
> @@ -235,8 +250,8 @@ static irqreturn_t tsc_irq_fn(int irq, void *dev_id)
>  		timeout = jiffies + HZ/500;
>  		do {
>  			if (time_after(jiffies, timeout)) {
> -				xnur = 0;
> -				goto touch_event;
> +				touch = true;
> +				goto report_touch;
>  			}
>  			usleep_range(200, 400);
>  			debug_mode2 = readl(tsc->tsc_regs +
> REG_TSC_DEBUG_MODE2);
> @@ -244,14 +259,15 @@ static irqreturn_t tsc_irq_fn(int irq, void *dev_id)
>  		} while (state_machine != DETECT_MODE);
>  		usleep_range(200, 400);
> 
> -		xnur = gpio_get_value(tsc->xnur_gpio);
> -touch_event:
> -		if (xnur == 0) {
> +		touch = gpiod_get_value_cansleep(tsc->xnur_gpio);
> +report_touch:
> +		if (touch) {
>  			input_report_key(tsc->input, BTN_TOUCH, 1);
>  			input_report_abs(tsc->input, ABS_X, x);
>  			input_report_abs(tsc->input, ABS_Y, y);
> -		} else
> +		} else {
>  			input_report_key(tsc->input, BTN_TOUCH, 0);
> +		}
> 
>  		input_sync(tsc->input);
>  	}
> @@ -261,7 +277,7 @@ touch_event:
> 
>  static irqreturn_t adc_irq_fn(int irq, void *dev_id)
>  {
> -	struct imx6ul_tsc *tsc = (struct imx6ul_tsc *)dev_id;
> +	struct imx6ul_tsc *tsc = dev_id;
>  	int coco;
>  	int value;
> 
> @@ -274,70 +290,113 @@ static irqreturn_t adc_irq_fn(int irq, void
> *dev_id)
>  	return IRQ_HANDLED;
>  }
> 
> -static const struct of_device_id imx6ul_tsc_match[] = {
> -	{ .compatible = "fsl,imx6ul-tsc", },
> -	{ /* sentinel */ }
> -};
> -MODULE_DEVICE_TABLE(of, imx6ul_tsc_match);
> +static int imx6ul_tsc_open(struct input_dev *input_dev)
> +{
> +	struct imx6ul_tsc *tsc = input_get_drvdata(input_dev);
> +	int err;
> +
> +	err = clk_prepare_enable(tsc->adc_clk);
> +	if (err) {
> +		dev_err(tsc->dev,
> +			"Could not prepare or enable the adc clock: %d\n",
> +			err);
> +		return err;
> +	}
> +
> +	err = clk_prepare_enable(tsc->tsc_clk);
> +	if (err) {
> +		dev_err(tsc->dev,
> +			"Could not prepare or enable the tsc clock: %d\n",
> +			err);
> +		clk_disable_unprepare(tsc->adc_clk);
> +		return err;
> +	}
> +
> +	imx6ul_tsc_init(tsc);
> +
> +	return 0;
> +}
> +
> +static void imx6ul_tsc_close(struct input_dev *input_dev)
> +{
> +	struct imx6ul_tsc *tsc = input_get_drvdata(input_dev);
> +
> +	imx6ul_tsc_disable(tsc);
> +
> +	clk_disable_unprepare(tsc->tsc_clk);
> +	clk_disable_unprepare(tsc->adc_clk);
> +}
> 
>  static int imx6ul_tsc_probe(struct platform_device *pdev)
>  {
> +	struct device_node *np = pdev->dev.of_node;
>  	struct imx6ul_tsc *tsc;
> +	struct input_dev *input_dev;
>  	struct resource *tsc_mem;
>  	struct resource *adc_mem;
> -	struct input_dev *input_dev;
> -	struct device_node *np = pdev->dev.of_node;
>  	int err;
>  	int tsc_irq;
>  	int adc_irq;
> 
>  	tsc = devm_kzalloc(&pdev->dev, sizeof(struct imx6ul_tsc),
> GFP_KERNEL);
> +	if (!tsc)
> +		return -ENOMEM;
> +
>  	input_dev = devm_input_allocate_device(&pdev->dev);
> +	if (!input_dev)
> +		return -ENOMEM;
> 
> -	tsc->dev = &pdev->dev;
> +	input_dev->name = "iMX6UL TouchScreen Controller";
> +	input_dev->id.bustype = BUS_HOST;
> 
> -	tsc->input = input_dev;
> -	tsc->input->evbit[0] = BIT_MASK(EV_KEY) | BIT_MASK(EV_ABS);
> -	tsc->input->keybit[BIT_WORD(BTN_TOUCH)] = BIT_MASK(BTN_TOUCH);
> -	input_set_abs_params(tsc->input, ABS_X, 0, 0xFFF, 0, 0);
> -	input_set_abs_params(tsc->input, ABS_Y, 0, 0xFFF, 0, 0);
> +	input_dev->open = imx6ul_tsc_open;
> +	input_dev->close = imx6ul_tsc_close;
> 
> -	tsc->input->name = "iMX6UL TouchScreen Controller";
> +	input_set_capability(input_dev, EV_KEY, BTN_TOUCH);
> +	input_set_abs_params(input_dev, ABS_X, 0, 0xFFF, 0, 0);
> +	input_set_abs_params(input_dev, ABS_Y, 0, 0xFFF, 0, 0);
> 
> -	tsc->xnur_gpio = of_get_named_gpio(np, "xnur-gpio", 0);
> -	err = gpio_request_one(tsc->xnur_gpio, GPIOF_IN, "tsc_X-");
> -	if (err) {
> -		dev_err(&pdev->dev, "failed to request GPIO tsc_X-\n");
> +	input_set_drvdata(input_dev, tsc);
> +
> +	tsc->dev = &pdev->dev;
> +	tsc->input = input_dev;
> +	init_completion(&tsc->completion);
> +
> +	tsc->xnur_gpio = devm_gpiod_get(&pdev->dev, "xnur-gpio", GPIOD_IN);
> +	if (IS_ERR(tsc->xnur_gpio)) {
> +		err = PTR_ERR(tsc->xnur_gpio);
> +		dev_err(&pdev->dev,
> +			"failed to request GPIO tsc_X- (xnur): %d\n", err);
>  		return err;
>  	}
> 
>  	tsc_mem = platform_get_resource(pdev, IORESOURCE_MEM, 0);
>  	tsc->tsc_regs = devm_ioremap_resource(&pdev->dev, tsc_mem);
>  	if (IS_ERR(tsc->tsc_regs)) {
> -		dev_err(&pdev->dev, "failed to remap tsc memory\n");
>  		err = PTR_ERR(tsc->tsc_regs);
> +		dev_err(&pdev->dev, "failed to remap tsc memory: %d\n", err);
>  		return err;
>  	}
> 
>  	adc_mem = platform_get_resource(pdev, IORESOURCE_MEM, 1);
>  	tsc->adc_regs = devm_ioremap_resource(&pdev->dev, adc_mem);
>  	if (IS_ERR(tsc->adc_regs)) {
> -		dev_err(&pdev->dev, "failed to remap adc memory\n");
>  		err = PTR_ERR(tsc->adc_regs);
> +		dev_err(&pdev->dev, "failed to remap adc memory: %d\n", err);
>  		return err;
>  	}
> 
>  	tsc->tsc_clk = devm_clk_get(&pdev->dev, "tsc");
>  	if (IS_ERR(tsc->tsc_clk)) {
> -		dev_err(&pdev->dev, "failed getting tsc clock\n");
>  		err = PTR_ERR(tsc->tsc_clk);
> +		dev_err(&pdev->dev, "failed getting tsc clock: %d\n", err);
>  		return err;
>  	}
> 
>  	tsc->adc_clk = devm_clk_get(&pdev->dev, "adc");
>  	if (IS_ERR(tsc->adc_clk)) {
> -		dev_err(&pdev->dev, "failed getting adc clock\n");
>  		err = PTR_ERR(tsc->adc_clk);
> +		dev_err(&pdev->dev, "failed getting adc clock: %d\n", err);
>  		return err;
>  	}
> 
> @@ -354,111 +413,61 @@ static int imx6ul_tsc_probe(struct platform_device
> *pdev)
>  	}
> 
>  	err = devm_request_threaded_irq(tsc->dev, tsc_irq,
> -					NULL, tsc_irq_fn,
> -					IRQF_TRIGGER_HIGH | IRQF_ONESHOT,
> +					NULL, tsc_irq_fn, IRQF_ONESHOT,
>  					dev_name(&pdev->dev), tsc);
> -	if (err < 0) {
> +	if (err) {
>  		dev_err(&pdev->dev,
> -			"failed requesting tsc irq %d\n",
> -					    tsc_irq);
> +			"failed requesting tsc irq %di: %d\n",
> +			tsc_irq, err);
>  		return err;
>  	}
> 
> -	err = devm_request_irq(tsc->dev, adc_irq,
> -				adc_irq_fn, 0,
> +	err = devm_request_irq(tsc->dev, adc_irq, adc_irq_fn, 0,
>  				dev_name(&pdev->dev), tsc);
> -	if (err < 0) {
> +	if (err) {
>  		dev_err(&pdev->dev,
> -			"failed requesting adc irq %d\n",
> -					    adc_irq);
> +			"failed requesting adc irq %d: %d\n",
> +			adc_irq, err);
>  		return err;
>  	}
> 
>  	err = of_property_read_u32(np, "measure-delay-time",
> -				&tsc->measure_delay_time);
> +				   &tsc->measure_delay_time);
>  	if (err)
>  		tsc->measure_delay_time = 0xffff;
> 
>  	err = of_property_read_u32(np, "pre-charge-time",
> -				&tsc->pre_charge_time);
> +				   &tsc->pre_charge_time);
>  	if (err)
>  		tsc->pre_charge_time = 0xfff;
> 
> -	init_completion(&tsc->completion);
> -
> -	err = clk_prepare_enable(tsc->adc_clk);
> +	err = input_register_device(tsc->input);
>  	if (err) {
>  		dev_err(&pdev->dev,
> -			"Could not prepare or enable the adc clock.\n");
> +			"failed to register input device: %d\n", err);
>  		return err;
>  	}
> 
> -	err = clk_prepare_enable(tsc->tsc_clk);
> -	if (err) {
> -		dev_err(&pdev->dev,
> -			"Could not prepare or enable the tsc clock.\n");
> -		goto error_tsc_clk_enable;
> -	}
> -
> -	err = input_register_device(tsc->input);
> -	if (err < 0) {
> -		dev_err(&pdev->dev, "failed to register input device\n");
> -		err = -EIO;
> -		goto err_input_register;
> -	}
> -
> -	imx6ul_tsc_init(tsc);
> -
>  	platform_set_drvdata(pdev, tsc);
>  	return 0;
> -
> -err_input_register:
> -	clk_disable_unprepare(tsc->tsc_clk);
> -error_tsc_clk_enable:
> -	clk_disable_unprepare(tsc->adc_clk);
> -
> -	return err;
> -}
> -
> -static void imx6ul_tsc_disable(struct imx6ul_tsc *tsc)
> -{
> -	int tsc_flow;
> -	int adc_cfg;
> -
> -	/* TSC controller enters to idle status */
> -	tsc_flow = readl(tsc->tsc_regs + REG_TSC_FLOW_CONTROL);
> -	tsc_flow |= TSC_DISABLE;
> -	writel(tsc_flow, tsc->tsc_regs + REG_TSC_FLOW_CONTROL);
> -
> -	/* ADC controller enters to stop mode */
> -	adc_cfg = readl(tsc->adc_regs + REG_ADC_HC0);
> -	adc_cfg |= ADC_CONV_DISABLE;
> -	writel(adc_cfg, tsc->adc_regs + REG_ADC_HC0);
> -}
> -
> -static int imx6ul_tsc_remove(struct platform_device *pdev)
> -{
> -	struct imx6ul_tsc *tsc = platform_get_drvdata(pdev);
> -
> -	imx6ul_tsc_disable(tsc);
> -
> -	clk_disable_unprepare(tsc->tsc_clk);
> -	clk_disable_unprepare(tsc->adc_clk);
> -	input_unregister_device(tsc->input);
> -	kfree(tsc);
> -
> -	return 0;
>  }
> 
>  static int __maybe_unused imx6ul_tsc_suspend(struct device *dev)
>  {
>  	struct platform_device *pdev = to_platform_device(dev);
>  	struct imx6ul_tsc *tsc = platform_get_drvdata(pdev);
> +	struct input_dev *input_dev = tsc->input;
> 
> -	imx6ul_tsc_disable(tsc);
> +	mutex_lock(&input_dev->mutex);
> 
> -	clk_disable_unprepare(tsc->tsc_clk);
> -	clk_disable_unprepare(tsc->adc_clk);
> +	if (input_dev->users) {
> +		imx6ul_tsc_disable(tsc);
> +
> +		clk_disable_unprepare(tsc->tsc_clk);
> +		clk_disable_unprepare(tsc->adc_clk);
> +	}
> +
> +	mutex_unlock(&input_dev->mutex);
> 
>  	return 0;
>  }
> @@ -467,35 +476,46 @@ static int __maybe_unused imx6ul_tsc_resume(struct
> device *dev)
>  {
>  	struct platform_device *pdev = to_platform_device(dev);
>  	struct imx6ul_tsc *tsc = platform_get_drvdata(pdev);
> -	int err;
> +	struct input_dev *input_dev = tsc->input;
> +	int retval = 0;
> 
> -	err = clk_prepare_enable(tsc->adc_clk);
> -	if (err)
> -		return err;
> +	mutex_lock(&input_dev->mutex);
> 
> -	err = clk_prepare_enable(tsc->tsc_clk);
> -	if (err) {
> -		clk_disable_unprepare(tsc->adc_clk);
> -		return err;
> +	if (input_dev->users) {
> +		retval = clk_prepare_enable(tsc->adc_clk);
> +		if (retval)
> +			goto out;
> +
> +		retval = clk_prepare_enable(tsc->tsc_clk);
> +		if (retval) {
> +			clk_disable_unprepare(tsc->adc_clk);
> +			goto out;
> +		}
> +
> +		imx6ul_tsc_init(tsc);
>  	}
> 
> -	imx6ul_tsc_init(tsc);
> -	return 0;
> +out:
> +	mutex_unlock(&input_dev->mutex);
> +	return retval;
>  }
> 
>  static SIMPLE_DEV_PM_OPS(imx6ul_tsc_pm_ops,
> -			 imx6ul_tsc_suspend,
> -			 imx6ul_tsc_resume);
> +			 imx6ul_tsc_suspend, imx6ul_tsc_resume);
> +
> +static const struct of_device_id imx6ul_tsc_match[] = {
> +	{ .compatible = "fsl,imx6ul-tsc", },
> +	{ /* sentinel */ }
> +};
> +MODULE_DEVICE_TABLE(of, imx6ul_tsc_match);
> 
>  static struct platform_driver imx6ul_tsc_driver = {
>  	.driver		= {
>  		.name	= "imx6ul-tsc",
> -		.owner	= THIS_MODULE,
>  		.of_match_table	= imx6ul_tsc_match,
>  		.pm	= &imx6ul_tsc_pm_ops,
>  	},
>  	.probe		= imx6ul_tsc_probe,
> -	.remove		= imx6ul_tsc_remove,
>  };
>  module_platform_driver(imx6ul_tsc_driver);
> 


From jingoohan1 at gmail.com  Fri Aug 21 01:20:57 2015
From: jingoohan1 at gmail.com (Jingoo Han)
Date: Fri, 21 Aug 2015 17:20:57 +0900
Subject: [PATCH v3 0/14] Add Analogix Core Display Port Driver
In-Reply-To: <1439995728-18046-1-git-send-email-ykk@rock-chips.com>
References: <1439995728-18046-1-git-send-email-ykk@rock-chips.com>
Message-ID: <105A0032-83A0-4B75-AE94-258F12451670@gmail.com>

On 2015. 8. 19., at PM 11:48, Yakir Yang <ykk at rock-chips.com> wrote:
> 
> 

.....

> .../bindings/video/analogix_dp-rockchip.txt        |   83 ++
> .../devicetree/bindings/video/exynos_dp.txt        |   51 +-
> arch/arm/boot/dts/exynos5250-arndale.dts           |   10 +-
> arch/arm/boot/dts/exynos5250-smdk5250.dts          |   10 +-
> arch/arm/boot/dts/exynos5250-snow.dts              |   12 +-
> arch/arm/boot/dts/exynos5250-spring.dts            |   12 +-
> arch/arm/boot/dts/exynos5420-peach-pit.dts         |   12 +-
> arch/arm/boot/dts/exynos5420-smdk5420.dts          |   10 +-
> arch/arm/boot/dts/exynos5800-peach-pi.dts          |   12 +-
> drivers/gpu/drm/bridge/Kconfig                     |    5 +
> drivers/gpu/drm/bridge/Makefile                    |    1 +
> drivers/gpu/drm/bridge/analogix_dp_core.c          | 1382 +++++++++++++++++++
> drivers/gpu/drm/bridge/analogix_dp_core.h          |  286 ++++
> drivers/gpu/drm/bridge/analogix_dp_reg.c           | 1294 ++++++++++++++++++
> .../exynos_dp_reg.h => bridge/analogix_dp_reg.h}   |  270 ++--
> drivers/gpu/drm/exynos/Kconfig                     |    5 +-
> drivers/gpu/drm/exynos/Makefile                    |    2 +-
> drivers/gpu/drm/exynos/analogix_dp-exynos.c        |  347 +++++

Would you change this file name to "exynos_dp.c"?

Best regards,
Jingoo Han

> drivers/gpu/drm/exynos/exynos_dp_core.c            | 1416 --------------------
> drivers/gpu/drm/exynos/exynos_dp_core.h            |  282 ----
> drivers/gpu/drm/exynos/exynos_dp_reg.c             | 1263 -----------------
> drivers/gpu/drm/rockchip/Kconfig                   |    9 +
> drivers/gpu/drm/rockchip/Makefile                  |    1 +
> drivers/gpu/drm/rockchip/analogix_dp-rockchip.c    |  390 ++++++
> drivers/phy/Kconfig                                |    7 +
> drivers/phy/Makefile                               |    1 +
> drivers/phy/phy-rockchip-dp.c                      |  185 +++
> include/drm/bridge/analogix_dp.h                   |   40 +
> 30 files changed, 4325 insertions(+), 3172 deletions(-)
> create mode 100644 Documentation/devicetree/bindings/drm/bridge/analogix_dp.txt
> create mode 100644 Documentation/devicetree/bindings/phy/rockchip-dp-phy.txt
> create mode 100644 Documentation/devicetree/bindings/video/analogix_dp-rockchip.txt
> create mode 100644 drivers/gpu/drm/bridge/analogix_dp_core.c
> create mode 100644 drivers/gpu/drm/bridge/analogix_dp_core.h
> create mode 100644 drivers/gpu/drm/bridge/analogix_dp_reg.c
> rename drivers/gpu/drm/{exynos/exynos_dp_reg.h => bridge/analogix_dp_reg.h} (62%)
> create mode 100644 drivers/gpu/drm/exynos/analogix_dp-exynos.c
> delete mode 100644 drivers/gpu/drm/exynos/exynos_dp_core.c
> delete mode 100644 drivers/gpu/drm/exynos/exynos_dp_core.h
> delete mode 100644 drivers/gpu/drm/exynos/exynos_dp_reg.c
> create mode 100644 drivers/gpu/drm/rockchip/analogix_dp-rockchip.c
> create mode 100644 drivers/phy/phy-rockchip-dp.c
> create mode 100644 include/drm/bridge/analogix_dp.h
> 
> -- 
> 1.9.1
> 
> 


From mpa at pengutronix.de  Fri Aug 21 01:26:39 2015
From: mpa at pengutronix.de (Markus Pargmann)
Date: Fri, 21 Aug 2015 10:26:39 +0200
Subject: [PATCH v3 0/4] regmap: fixes
Message-ID: <1440145603-9612-1-git-send-email-mpa@pengutronix.de>

Hi,

I changed the comments you mentioned in your review. I hope they are better
to understand now.

Best Regards,

Markus


Changes in v3:
- Change comments in patch 1 'regmap: Add missing comments about struct regmap_bus'
- Change description in patch 2 'regmap: Fix regmap_bulk_write for bus writes'

Changes in v2:
- Fixed free_context typo
- use_single_rw is now internally split into use_single_read/write
- Removed patches that wrongly tried to fix things
- Added simpler patches which check for the existence of bus->read/write to
  avoid null dereferences


Markus Pargmann (4):
  regmap: Add missing comments about struct regmap_bus
  regmap: Fix regmap_bulk_write for bus writes
  regmap: Split use_single_rw internally into use_single_read/write
  regmap: No multi_write support if bus->write does not exist

 drivers/base/regmap/internal.h   |  6 ++++--
 drivers/base/regmap/regcache.c   |  2 +-
 drivers/base/regmap/regmap-irq.c |  4 ++--
 drivers/base/regmap/regmap.c     | 30 ++++++++++++++++++++++++------
 include/linux/regmap.h           |  5 ++++-
 5 files changed, 35 insertions(+), 12 deletions(-)

-- 
2.4.6



From mpa at pengutronix.de  Fri Aug 21 01:26:41 2015
From: mpa at pengutronix.de (Markus Pargmann)
Date: Fri, 21 Aug 2015 10:26:41 +0200
Subject: [PATCH v3 2/4] regmap: Fix regmap_bulk_write for bus writes
In-Reply-To: <1440145603-9612-1-git-send-email-mpa@pengutronix.de>
References: <1440145603-9612-1-git-send-email-mpa@pengutronix.de>
Message-ID: <1440145603-9612-3-git-send-email-mpa@pengutronix.de>

The regmap config does not prohibit val_bytes that are not powers of
two. But the current code of regmap_bulk_write for use_single_rw does
limit the possible val_bytes to 1, 2 and 4.

This patch fixes the behaviour to allow bus writes with non-standard
val_bytes sizes.

Cc: Stephen Boyd <sboyd at codeaurora.org>
Signed-off-by: Markus Pargmann <mpa at pengutronix.de>
---
 drivers/base/regmap/regmap.c | 21 +++++++++++++++++++--
 1 file changed, 19 insertions(+), 2 deletions(-)

diff --git a/drivers/base/regmap/regmap.c b/drivers/base/regmap/regmap.c
index 375fec92dc7e..e986e84b8871 100644
--- a/drivers/base/regmap/regmap.c
+++ b/drivers/base/regmap/regmap.c
@@ -1678,9 +1678,15 @@ int regmap_bulk_write(struct regmap *map, unsigned int reg, const void *val,
 
 	/*
 	 * Some devices don't support bulk write, for
-	 * them we have a series of single write operations.
+	 * them we have a series of single write operations in the first two if
+	 * blocks.
+	 *
+	 * The first if block is used for memory mapped io. It does not allow
+	 * val_bytes of 3 for example.
+	 * The second one is used for busses which do not have this limitation
+	 * and can write arbitrary value lengths.
 	 */
-	if (!map->bus || map->use_single_rw) {
+	if (!map->bus) {
 		map->lock(map->lock_arg);
 		for (i = 0; i < val_count; i++) {
 			unsigned int ival;
@@ -1712,6 +1718,17 @@ int regmap_bulk_write(struct regmap *map, unsigned int reg, const void *val,
 		}
 out:
 		map->unlock(map->lock_arg);
+	} else if (map->use_single_rw) {
+		map->lock(map->lock_arg);
+		for (i = 0; i < val_count; i++) {
+			ret = _regmap_raw_write(map,
+						reg + (i * map->reg_stride),
+						val + (i * val_bytes),
+						val_bytes);
+			if (ret)
+				break;
+		}
+		map->unlock(map->lock_arg);
 	} else {
 		void *wval;
 
-- 
2.4.6



From mpa at pengutronix.de  Fri Aug 21 01:26:43 2015
From: mpa at pengutronix.de (Markus Pargmann)
Date: Fri, 21 Aug 2015 10:26:43 +0200
Subject: [PATCH v3 4/4] regmap: No multi_write support if bus->write does not
 exist
In-Reply-To: <1440145603-9612-1-git-send-email-mpa@pengutronix.de>
References: <1440145603-9612-1-git-send-email-mpa@pengutronix.de>
Message-ID: <1440145603-9612-5-git-send-email-mpa@pengutronix.de>

There is no multi_write support available if we cannot use raw_write.
This is the case if bus->write is not implemented.

This patch adds a condition that we need bus and bus->write so that
can_multi_write is true.

Signed-off-by: Markus Pargmann <mpa at pengutronix.de>
---
 drivers/base/regmap/regmap.c | 2 +-
 1 file changed, 1 insertion(+), 1 deletion(-)

diff --git a/drivers/base/regmap/regmap.c b/drivers/base/regmap/regmap.c
index 75080774bf46..47fe0dfbbc46 100644
--- a/drivers/base/regmap/regmap.c
+++ b/drivers/base/regmap/regmap.c
@@ -575,7 +575,7 @@ struct regmap *regmap_init(struct device *dev,
 		map->reg_stride = 1;
 	map->use_single_read = config->use_single_rw || !bus || !bus->read;
 	map->use_single_write = config->use_single_rw || !bus || !bus->write;
-	map->can_multi_write = config->can_multi_write;
+	map->can_multi_write = config->can_multi_write && bus && bus->write;
 	map->dev = dev;
 	map->bus = bus;
 	map->bus_context = bus_context;
-- 
2.4.6



From mpa at pengutronix.de  Fri Aug 21 01:26:42 2015
From: mpa at pengutronix.de (Markus Pargmann)
Date: Fri, 21 Aug 2015 10:26:42 +0200
Subject: [PATCH v3 3/4] regmap: Split use_single_rw internally into
 use_single_read/write
In-Reply-To: <1440145603-9612-1-git-send-email-mpa@pengutronix.de>
References: <1440145603-9612-1-git-send-email-mpa@pengutronix.de>
Message-ID: <1440145603-9612-4-git-send-email-mpa@pengutronix.de>

use_single_rw currently reflects the capabilities of the connected
device. The capabilities of the bus are currently missing for this
variable.

As there are read only and write only buses we need seperate values for
use_single_rw to also reflect tha capabilities of the bus.

This patch splits use_single_rw into use_single_read and
use_single_write. The initialization is changed to check the
configuration for use_single_rw and to check the capabilities of the
used bus.

Signed-off-by: Markus Pargmann <mpa at pengutronix.de>
---
 drivers/base/regmap/internal.h   | 6 ++++--
 drivers/base/regmap/regcache.c   | 2 +-
 drivers/base/regmap/regmap-irq.c | 4 ++--
 drivers/base/regmap/regmap.c     | 9 +++++----
 4 files changed, 12 insertions(+), 9 deletions(-)

diff --git a/drivers/base/regmap/internal.h b/drivers/base/regmap/internal.h
index b2b2849fc6d3..d744ae3926dd 100644
--- a/drivers/base/regmap/internal.h
+++ b/drivers/base/regmap/internal.h
@@ -139,8 +139,10 @@ struct regmap {
 	struct reg_default *patch;
 	int patch_regs;
 
-	/* if set, converts bulk rw to single rw */
-	bool use_single_rw;
+	/* if set, converts bulk read to single read */
+	bool use_single_read;
+	/* if set, converts bulk read to single read */
+	bool use_single_write;
 	/* if set, the device supports multi write mode */
 	bool can_multi_write;
 
diff --git a/drivers/base/regmap/regcache.c b/drivers/base/regmap/regcache.c
index b9862d741a56..6f8a13ec32a4 100644
--- a/drivers/base/regmap/regcache.c
+++ b/drivers/base/regmap/regcache.c
@@ -729,7 +729,7 @@ int regcache_sync_block(struct regmap *map, void *block,
 			unsigned int block_base, unsigned int start,
 			unsigned int end)
 {
-	if (regmap_can_raw_write(map) && !map->use_single_rw)
+	if (regmap_can_raw_write(map) && !map->use_single_write)
 		return regcache_sync_block_raw(map, block, cache_present,
 					       block_base, start, end);
 	else
diff --git a/drivers/base/regmap/regmap-irq.c b/drivers/base/regmap/regmap-irq.c
index 2597600a5d26..38d1f72d869c 100644
--- a/drivers/base/regmap/regmap-irq.c
+++ b/drivers/base/regmap/regmap-irq.c
@@ -209,7 +209,7 @@ static irqreturn_t regmap_irq_thread(int irq, void *d)
 	 * Read in the statuses, using a single bulk read if possible
 	 * in order to reduce the I/O overheads.
 	 */
-	if (!map->use_single_rw && map->reg_stride == 1 &&
+	if (!map->use_single_read && map->reg_stride == 1 &&
 	    data->irq_reg_stride == 1) {
 		u8 *buf8 = data->status_reg_buf;
 		u16 *buf16 = data->status_reg_buf;
@@ -398,7 +398,7 @@ int regmap_add_irq_chip(struct regmap *map, int irq, int irq_flags,
 	else
 		d->irq_reg_stride = 1;
 
-	if (!map->use_single_rw && map->reg_stride == 1 &&
+	if (!map->use_single_read && map->reg_stride == 1 &&
 	    d->irq_reg_stride == 1) {
 		d->status_reg_buf = kmalloc(map->format.val_bytes *
 					    chip->num_regs, GFP_KERNEL);
diff --git a/drivers/base/regmap/regmap.c b/drivers/base/regmap/regmap.c
index e986e84b8871..75080774bf46 100644
--- a/drivers/base/regmap/regmap.c
+++ b/drivers/base/regmap/regmap.c
@@ -573,7 +573,8 @@ struct regmap *regmap_init(struct device *dev,
 		map->reg_stride = config->reg_stride;
 	else
 		map->reg_stride = 1;
-	map->use_single_rw = config->use_single_rw;
+	map->use_single_read = config->use_single_rw || !bus || !bus->read;
+	map->use_single_write = config->use_single_rw || !bus || !bus->write;
 	map->can_multi_write = config->can_multi_write;
 	map->dev = dev;
 	map->bus = bus;
@@ -763,7 +764,7 @@ struct regmap *regmap_init(struct device *dev,
 		if ((reg_endian != REGMAP_ENDIAN_BIG) ||
 		    (val_endian != REGMAP_ENDIAN_BIG))
 			goto err_map;
-		map->use_single_rw = true;
+		map->use_single_write = true;
 	}
 
 	if (!map->format.format_write &&
@@ -1718,7 +1719,7 @@ int regmap_bulk_write(struct regmap *map, unsigned int reg, const void *val,
 		}
 out:
 		map->unlock(map->lock_arg);
-	} else if (map->use_single_rw) {
+	} else if (map->use_single_write) {
 		map->lock(map->lock_arg);
 		for (i = 0; i < val_count; i++) {
 			ret = _regmap_raw_write(map,
@@ -2315,7 +2316,7 @@ int regmap_bulk_read(struct regmap *map, unsigned int reg, void *val,
 		 * Some devices does not support bulk read, for
 		 * them we have a series of single read operations.
 		 */
-		if (map->use_single_rw) {
+		if (map->use_single_read) {
 			for (i = 0; i < val_count; i++) {
 				ret = regmap_raw_read(map,
 						reg + (i * map->reg_stride),
-- 
2.4.6



From mpa at pengutronix.de  Fri Aug 21 01:26:40 2015
From: mpa at pengutronix.de (Markus Pargmann)
Date: Fri, 21 Aug 2015 10:26:40 +0200
Subject: [PATCH v3 1/4] regmap: Add missing comments about struct regmap_bus
In-Reply-To: <1440145603-9612-1-git-send-email-mpa@pengutronix.de>
References: <1440145603-9612-1-git-send-email-mpa@pengutronix.de>
Message-ID: <1440145603-9612-2-git-send-email-mpa@pengutronix.de>

There are some fields of this struct undocumented or old. This patch
updates the missing comments.

Signed-off-by: Markus Pargmann <mpa at pengutronix.de>
---
 include/linux/regmap.h | 5 ++++-
 1 file changed, 4 insertions(+), 1 deletion(-)

diff --git a/include/linux/regmap.h b/include/linux/regmap.h
index 59c55ea0f0b5..73fc34d0c4c2 100644
--- a/include/linux/regmap.h
+++ b/include/linux/regmap.h
@@ -296,8 +296,12 @@ typedef void (*regmap_hw_free_context)(void *context);
  *                if not implemented  on a given device.
  * @async_write: Write operation which completes asynchronously, optional and
  *               must serialise with respect to non-async I/O.
+ * @reg_write: Write a single register value to the given register address. This
+ *             write operation has to complete when returning from the function.
  * @read: Read operation.  Data is returned in the buffer used to transmit
  *         data.
+ * @reg_read: Read a single register value from a given register address.
+ * @free_context: Free context.
  * @async_alloc: Allocate a regmap_async() structure.
  * @read_flag_mask: Mask to be set in the top byte of the register when doing
  *                  a read.
@@ -307,7 +311,6 @@ typedef void (*regmap_hw_free_context)(void *context);
  * @val_format_endian_default: Default endianness for formatted register
  *     values. Used when the regmap_config specifies DEFAULT. If this is
  *     DEFAULT, BIG is assumed.
- * @async_size: Size of struct used for async work.
  */
 struct regmap_bus {
 	bool fast_io;
-- 
2.4.6



From Haibo.Chen at freescale.com  Fri Aug 21 01:30:16 2015
From: Haibo.Chen at freescale.com (Chen Bough)
Date: Fri, 21 Aug 2015 08:30:16 +0000
Subject: [PATCH v2 2/5] Documentation: Detail permitted DT properties for
 the imx6ul_tsc
In-Reply-To: <20150819055434.GF11161@pengutronix.de>
References: <1438077521-12857-1-git-send-email-haibo.chen@freescale.com>
 <1438077521-12857-3-git-send-email-haibo.chen@freescale.com>
 <20150819055434.GF11161@pengutronix.de>
Message-ID: <BY1PR03MB1388BBEF576297D76E7E3F839A650@BY1PR03MB1388.namprd03.prod.outlook.com>

Hi Markus,

> -----Original Message-----
> From: Markus Pargmann [mailto:mpa at pengutronix.de]
> Sent: Wednesday, August 19, 2015 1:55 PM
> To: Chen Haibo-B51421
> Cc: robh+dt at kernel.org; pawel.moll at arm.com; mark.rutland at arm.com;
> ijc+devicetree at hellion.org.uk; galak at codeaurora.org; shawnguo at kernel.org;
> kernel at pengutronix.de; linux at arm.linux.org.uk; dmitry.torokhov at gmail.com;
> devicetree at vger.kernel.org; sbranden at broadcom.com; arnd at arndb.de;
> mchehab at osg.samsung.com; christian.gmeiner at gmail.com;
> scott.liu at emc.com.tw; linux-kernel at vger.kernel.org; hdegoede at redhat.com;
> jonathar at broadcom.com; benjamin.tissoires at redhat.com;
> hans.verkuil at cisco.com; hadess at hadess.net; linux-input at vger.kernel.org;
> geert at linux-m68k.org; sebastien.szymanski at armadeus.com;
> mamlinav at gmail.com; linux-arm-kernel at lists.infradead.org
> Subject: Re: [PATCH v2 2/5] Documentation: Detail permitted DT properties
> for the imx6ul_tsc
> 
> Hi,
> 
> On Tue, Jul 28, 2015 at 05:58:38PM +0800, Haibo Chen wrote:
> > Here we apply required documentation for the imx6ul touch screen
> > controller driver which describe available properties and how to use
> > them.
> >
> > Signed-off-by: Haibo Chen <haibo.chen at freescale.com>
> > ---
> >  .../bindings/input/touchscreen/imx6ul_tsc.txt      | 36
> ++++++++++++++++++++++
> >  1 file changed, 36 insertions(+)
> >  create mode 100644
> > Documentation/devicetree/bindings/input/touchscreen/imx6ul_tsc.txt
> >
> > diff --git
> > a/Documentation/devicetree/bindings/input/touchscreen/imx6ul_tsc.txt
> > b/Documentation/devicetree/bindings/input/touchscreen/imx6ul_tsc.txt
> > new file mode 100644
> > index 0000000..ac41c32
> > --- /dev/null
> > +++ b/Documentation/devicetree/bindings/input/touchscreen/imx6ul_tsc.t
> > +++ xt
> > @@ -0,0 +1,36 @@
> > +* Freescale i.MX6UL Touch Controller
> > +
> > +Required properties:
> > +- compatible: must be "fsl,imx6ul-tsc".
> > +- reg: this touch controller address and the ADC2 address.
> 
> This suggests that this driver is using a unit ADC2. Which also means
> that there are more than one ADC which are probably identical?
> 
> Shouldn't these ADCs be properly described by their own device nodes
> instead of these two register ranges, two interrupts and two clocks?
> 
> Is 'ADC2' usable without tsc? Then ADC1/ADC2 should perhaps get a proper
> IIO driver.

For i.MX6UL, there are two ADC. ADC1 is a normal ADC, and ADC2 can only works for
TSC, the channels of ADC2 are connected to TSC directly. TSC and ADC2 should work
together as a touch screen controller. 

For ADC1, it share the driver vf610_adc.c (drivers/iio/adc/vf610_adc.c). 

Best Regards

Haibo 
 
> 
> Unfortunately I don't have the reference manual to have a look how this
> all works.
> 
> Best regards,
> 
> Markus
> 
> > +- interrupts: the interrupt of this touch controller and ADC2.
> > +- clocks: the root clock of touch controller and ADC2.
> > +- clock-names; must be "tsc" and "adc".
> > +- xnur-gpio: the X- gpio this controller connect to.
> > +  This xnur-gpio returns to high once the finger leave the touch
> > +screen (The
> > +  last touch event the touch controller capture).
> > +
> > +Optional properties:
> > +- measure-delay-time: the value of measure delay time.
> > +  Before X-axis or Y-axis measurement, the screen need some time
> > +before
> > +  even potential distribution ready.
> > +  This value depends on the touch screen.
> > +- pre-charge-time: the touch screen need some time to precharge.
> > +  This value depends on the touch screen.
> > +
> > +Example:
> > +	tsc: tsc at 02040000 {
> > +		compatible = "fsl,imx6ul-tsc";
> > +		reg = <0x02040000 0x4000>, <0x0219c000 0x4000>;
> > +		interrupts = <GIC_SPI 3 IRQ_TYPE_LEVEL_HIGH>,
> > +			     <GIC_SPI 101 IRQ_TYPE_LEVEL_HIGH>;
> > +		clocks = <&clks IMX6UL_CLK_IPG>,
> > +			 <&clks IMX6UL_CLK_ADC2>;
> > +		clock-names = "tsc", "adc";
> > +		pinctrl-names = "default";
> > +		pinctrl-0 = <&pinctrl_tsc>;
> > +		xnur-gpio = <&gpio1 3 GPIO_ACTIVE_HIGH>;
> > +		measure-delay-time = <0xfff>;
> > +		pre-charge-time = <0xffff>;
> > +		status = "okay";
> > +	};
> > --
> > 1.9.1
> >
> >
> >
> 
> --
> Pengutronix e.K.                           |
> |
> Industrial Linux Solutions                 | http://www.pengutronix.de/
> |
> Peiner Str. 6-8, 31137 Hildesheim, Germany | Phone: +49-5121-206917-0
> |
> Amtsgericht Hildesheim, HRA 2686           | Fax:   +49-5121-206917-5555
> |

From vinod.koul at intel.com  Fri Aug 21 01:39:46 2015
From: vinod.koul at intel.com (Vinod Koul)
Date: Fri, 21 Aug 2015 14:09:46 +0530
Subject: [PATCH] dmaengine: xgene-dma: Fix holding lock while calling tx
 callback in cleanup path
In-Reply-To: <1440066656-15516-1-git-send-email-rsahu@apm.com>
References: <1440066656-15516-1-git-send-email-rsahu@apm.com>
Message-ID: <20150821083946.GO13546@localhost>

On Thu, Aug 20, 2015 at 04:00:56PM +0530, Rameshwar Prasad Sahu wrote:
> This patch fixes the an locking issue where client callback performs
		^^^^^^^^^^^^
??

> further submission.
Do you men you are preventing that or fixing for this to be allowed?

> 
> Signed-off-by: Rameshwar Prasad Sahu <rsahu at apm.com>
> ---
>  drivers/dma/xgene-dma.c | 33 ++++++++++++++++++++++-----------
>  1 file changed, 22 insertions(+), 11 deletions(-)
> 
> diff --git a/drivers/dma/xgene-dma.c b/drivers/dma/xgene-dma.c
> index d1c8809..0b82bc0 100644
> --- a/drivers/dma/xgene-dma.c
> +++ b/drivers/dma/xgene-dma.c
> @@ -763,12 +763,17 @@ static void xgene_dma_cleanup_descriptors(struct xgene_dma_chan *chan)
>  	struct xgene_dma_ring *ring = &chan->rx_ring;
>  	struct xgene_dma_desc_sw *desc_sw, *_desc_sw;
>  	struct xgene_dma_desc_hw *desc_hw;
> +	struct list_head ld_completed;
>  	u8 status;
> 
> +	INIT_LIST_HEAD(&ld_completed);
> +
> +	spin_lock_bh(&chan->lock);
> +
>  	/* Clean already completed and acked descriptors */
>  	xgene_dma_clean_completed_descriptor(chan);
> 
> -	/* Run the callback for each descriptor, in order */
> +	/* Move all completed descriptors to ld completed queue, in order */
>  	list_for_each_entry_safe(desc_sw, _desc_sw, &chan->ld_running, node) {
>  		/* Get subsequent hw descriptor from DMA rx ring */
>  		desc_hw = &ring->desc_hw[ring->head];
> @@ -811,15 +816,17 @@ static void xgene_dma_cleanup_descriptors(struct xgene_dma_chan *chan)
>  		/* Mark this hw descriptor as processed */
>  		desc_hw->m0 = cpu_to_le64(XGENE_DMA_DESC_EMPTY_SIGNATURE);
> 
> -		xgene_dma_run_tx_complete_actions(chan, desc_sw);
> -
> -		xgene_dma_clean_running_descriptor(chan, desc_sw);
> -
>  		/*
>  		 * Decrement the pending transaction count
>  		 * as we have processed one
>  		 */
>  		chan->pending--;
> +
> +		/*
> +		 * Delete this node from ld running queue and append it to
> +		 * ld completed queue for further processing
> +		 */
> +		list_move_tail(&desc_sw->node, &ld_completed);
>  	}
> 
>  	/*
> @@ -828,6 +835,14 @@ static void xgene_dma_cleanup_descriptors(struct xgene_dma_chan *chan)
>  	 * ahead and free the descriptors below.
>  	 */
>  	xgene_chan_xfer_ld_pending(chan);
> +
> +	spin_unlock_bh(&chan->lock);
> +
> +	/* Run the callback for each descriptor, in order */
> +	list_for_each_entry_safe(desc_sw, _desc_sw, &ld_completed, node) {
> +		xgene_dma_run_tx_complete_actions(chan, desc_sw);
> +		xgene_dma_clean_running_descriptor(chan, desc_sw);
> +	}
>  }
> 
>  static int xgene_dma_alloc_chan_resources(struct dma_chan *dchan)
> @@ -876,11 +891,11 @@ static void xgene_dma_free_chan_resources(struct dma_chan *dchan)
>  	if (!chan->desc_pool)
>  		return;
> 
> -	spin_lock_bh(&chan->lock);
> -
>  	/* Process all running descriptor */
>  	xgene_dma_cleanup_descriptors(chan);
> 
> +	spin_lock_bh(&chan->lock);
> +
>  	/* Clean all link descriptor queues */
>  	xgene_dma_free_desc_list(chan, &chan->ld_pending);
>  	xgene_dma_free_desc_list(chan, &chan->ld_running);
> @@ -1200,15 +1215,11 @@ static void xgene_dma_tasklet_cb(unsigned long data)
>  {
>  	struct xgene_dma_chan *chan = (struct xgene_dma_chan *)data;
> 
> -	spin_lock_bh(&chan->lock);
> -
>  	/* Run all cleanup for descriptors which have been completed */
>  	xgene_dma_cleanup_descriptors(chan);
> 
>  	/* Re-enable DMA channel IRQ */
>  	enable_irq(chan->rx_irq);
> -
> -	spin_unlock_bh(&chan->lock);
>  }
> 
>  static irqreturn_t xgene_dma_chan_ring_isr(int irq, void *id)
> --
> 1.8.2.1
> 

-- 
~Vinod


From rsahu at apm.com  Fri Aug 21 01:45:08 2015
From: rsahu at apm.com (Rameshwar Sahu)
Date: Fri, 21 Aug 2015 14:15:08 +0530
Subject: [PATCH] dmaengine: xgene-dma: Fix holding lock while calling tx
 callback in cleanup path
In-Reply-To: <20150821083946.GO13546@localhost>
References: <1440066656-15516-1-git-send-email-rsahu@apm.com>
 <20150821083946.GO13546@localhost>
Message-ID: <CAFd313wEAWjzJa82R1ujh3vyMasDvicQ4nZHq1qqZ5y7D4ixzQ@mail.gmail.com>

Hi Vinod,

On Fri, Aug 21, 2015 at 2:09 PM, Vinod Koul <vinod.koul at intel.com> wrote:
> On Thu, Aug 20, 2015 at 04:00:56PM +0530, Rameshwar Prasad Sahu wrote:
>> This patch fixes the an locking issue where client callback performs
>                 ^^^^^^^^^^^^
> ??
>
>> further submission.
> Do you men you are preventing that or fixing for this to be allowed?

Fixing lock to allow client to submit further request in there
callback routine if they would like.
>
>>
>> Signed-off-by: Rameshwar Prasad Sahu <rsahu at apm.com>
>> ---
>>  drivers/dma/xgene-dma.c | 33 ++++++++++++++++++++++-----------
>>  1 file changed, 22 insertions(+), 11 deletions(-)
>>
>> diff --git a/drivers/dma/xgene-dma.c b/drivers/dma/xgene-dma.c
>> index d1c8809..0b82bc0 100644
>> --- a/drivers/dma/xgene-dma.c
>> +++ b/drivers/dma/xgene-dma.c
>> @@ -763,12 +763,17 @@ static void xgene_dma_cleanup_descriptors(struct xgene_dma_chan *chan)
>>       struct xgene_dma_ring *ring = &chan->rx_ring;
>>       struct xgene_dma_desc_sw *desc_sw, *_desc_sw;
>>       struct xgene_dma_desc_hw *desc_hw;
>> +     struct list_head ld_completed;
>>       u8 status;
>>
>> +     INIT_LIST_HEAD(&ld_completed);
>> +
>> +     spin_lock_bh(&chan->lock);
>> +
>>       /* Clean already completed and acked descriptors */
>>       xgene_dma_clean_completed_descriptor(chan);
>>
>> -     /* Run the callback for each descriptor, in order */
>> +     /* Move all completed descriptors to ld completed queue, in order */
>>       list_for_each_entry_safe(desc_sw, _desc_sw, &chan->ld_running, node) {
>>               /* Get subsequent hw descriptor from DMA rx ring */
>>               desc_hw = &ring->desc_hw[ring->head];
>> @@ -811,15 +816,17 @@ static void xgene_dma_cleanup_descriptors(struct xgene_dma_chan *chan)
>>               /* Mark this hw descriptor as processed */
>>               desc_hw->m0 = cpu_to_le64(XGENE_DMA_DESC_EMPTY_SIGNATURE);
>>
>> -             xgene_dma_run_tx_complete_actions(chan, desc_sw);
>> -
>> -             xgene_dma_clean_running_descriptor(chan, desc_sw);
>> -
>>               /*
>>                * Decrement the pending transaction count
>>                * as we have processed one
>>                */
>>               chan->pending--;
>> +
>> +             /*
>> +              * Delete this node from ld running queue and append it to
>> +              * ld completed queue for further processing
>> +              */
>> +             list_move_tail(&desc_sw->node, &ld_completed);
>>       }
>>
>>       /*
>> @@ -828,6 +835,14 @@ static void xgene_dma_cleanup_descriptors(struct xgene_dma_chan *chan)
>>        * ahead and free the descriptors below.
>>        */
>>       xgene_chan_xfer_ld_pending(chan);
>> +
>> +     spin_unlock_bh(&chan->lock);
>> +
>> +     /* Run the callback for each descriptor, in order */
>> +     list_for_each_entry_safe(desc_sw, _desc_sw, &ld_completed, node) {
>> +             xgene_dma_run_tx_complete_actions(chan, desc_sw);
>> +             xgene_dma_clean_running_descriptor(chan, desc_sw);
>> +     }
>>  }
>>
>>  static int xgene_dma_alloc_chan_resources(struct dma_chan *dchan)
>> @@ -876,11 +891,11 @@ static void xgene_dma_free_chan_resources(struct dma_chan *dchan)
>>       if (!chan->desc_pool)
>>               return;
>>
>> -     spin_lock_bh(&chan->lock);
>> -
>>       /* Process all running descriptor */
>>       xgene_dma_cleanup_descriptors(chan);
>>
>> +     spin_lock_bh(&chan->lock);
>> +
>>       /* Clean all link descriptor queues */
>>       xgene_dma_free_desc_list(chan, &chan->ld_pending);
>>       xgene_dma_free_desc_list(chan, &chan->ld_running);
>> @@ -1200,15 +1215,11 @@ static void xgene_dma_tasklet_cb(unsigned long data)
>>  {
>>       struct xgene_dma_chan *chan = (struct xgene_dma_chan *)data;
>>
>> -     spin_lock_bh(&chan->lock);
>> -
>>       /* Run all cleanup for descriptors which have been completed */
>>       xgene_dma_cleanup_descriptors(chan);
>>
>>       /* Re-enable DMA channel IRQ */
>>       enable_irq(chan->rx_irq);
>> -
>> -     spin_unlock_bh(&chan->lock);
>>  }
>>
>>  static irqreturn_t xgene_dma_chan_ring_isr(int irq, void *id)
>> --
>> 1.8.2.1
>>
>
> --
> ~Vinod


From vinod.koul at intel.com  Fri Aug 21 01:51:46 2015
From: vinod.koul at intel.com (Vinod Koul)
Date: Fri, 21 Aug 2015 14:21:46 +0530
Subject: [PATCH] dmaengine: xgene-dma: Fix holding lock while calling tx
 callback in cleanup path
In-Reply-To: <CAFd313wEAWjzJa82R1ujh3vyMasDvicQ4nZHq1qqZ5y7D4ixzQ@mail.gmail.com>
References: <1440066656-15516-1-git-send-email-rsahu@apm.com>
 <20150821083946.GO13546@localhost>
 <CAFd313wEAWjzJa82R1ujh3vyMasDvicQ4nZHq1qqZ5y7D4ixzQ@mail.gmail.com>
Message-ID: <20150821085146.GP13546@localhost>

On Fri, Aug 21, 2015 at 02:15:08PM +0530, Rameshwar Sahu wrote:
> Hi Vinod,
> 
> On Fri, Aug 21, 2015 at 2:09 PM, Vinod Koul <vinod.koul at intel.com> wrote:
> > On Thu, Aug 20, 2015 at 04:00:56PM +0530, Rameshwar Prasad Sahu wrote:
> >> This patch fixes the an locking issue where client callback performs
> >                 ^^^^^^^^^^^^
> > ??
> >
> >> further submission.
> > Do you men you are preventing that or fixing for this to be allowed?
> 
> Fixing lock to allow client to submit further request in there
> callback routine if they would like.

Okay please fix the changelog to make it clear :)

-- 
~Vinod



From axel.lin at ingics.com  Fri Aug 21 01:49:38 2015
From: axel.lin at ingics.com (Axel Lin)
Date: Fri, 21 Aug 2015 16:49:38 +0800
Subject: [PATCH RFT] phy: sun4i-usb: Use devm_gpiod_get_optional for
 optional GPIOs
Message-ID: <1440146978.29130.1.camel@ingics.com>

Both data->id_det_gpio and data->vbus_det_gpio are optional, so use
devm_gpiod_get_optional for them.

Signed-off-by: Axel Lin <axel.lin at ingics.com>
---
 drivers/phy/phy-sun4i-usb.c | 22 +++++++++-------------
 1 file changed, 9 insertions(+), 13 deletions(-)

diff --git a/drivers/phy/phy-sun4i-usb.c b/drivers/phy/phy-sun4i-usb.c
index 731b395..b12964b 100644
--- a/drivers/phy/phy-sun4i-usb.c
+++ b/drivers/phy/phy-sun4i-usb.c
@@ -551,19 +551,15 @@ static int sun4i_usb_phy_probe(struct platform_device *pdev)
 	if (IS_ERR(data->base))
 		return PTR_ERR(data->base);
 
-	data->id_det_gpio = devm_gpiod_get(dev, "usb0_id_det", GPIOD_IN);
-	if (IS_ERR(data->id_det_gpio)) {
-		if (PTR_ERR(data->id_det_gpio) == -EPROBE_DEFER)
-			return -EPROBE_DEFER;
-		data->id_det_gpio = NULL;
-	}
-
-	data->vbus_det_gpio = devm_gpiod_get(dev, "usb0_vbus_det", GPIOD_IN);
-	if (IS_ERR(data->vbus_det_gpio)) {
-		if (PTR_ERR(data->vbus_det_gpio) == -EPROBE_DEFER)
-			return -EPROBE_DEFER;
-		data->vbus_det_gpio = NULL;
-	}
+	data->id_det_gpio = devm_gpiod_get_optional(dev, "usb0_id_det",
+						    GPIOD_IN);
+	if (IS_ERR(data->id_det_gpio))
+		return PTR_ERR(data->id_det_gpio);
+
+	data->vbus_det_gpio = devm_gpiod_get_optional(dev, "usb0_vbus_det",
+						      GPIOD_IN);
+	if (IS_ERR(data->vbus_det_gpio))
+		return PTR_ERR(data->vbus_det_gpio);
 
 	if (of_find_property(np, "usb0_vbus_power-supply", NULL)) {
 		data->vbus_power_supply = devm_power_supply_get_by_phandle(dev,
-- 
2.1.0





From rsahu at apm.com  Fri Aug 21 01:50:58 2015
From: rsahu at apm.com (Rameshwar Sahu)
Date: Fri, 21 Aug 2015 14:20:58 +0530
Subject: [PATCH] dmaengine: xgene-dma: Fix holding lock while calling tx
 callback in cleanup path
In-Reply-To: <20150821085146.GP13546@localhost>
References: <1440066656-15516-1-git-send-email-rsahu@apm.com>
 <20150821083946.GO13546@localhost>
 <CAFd313wEAWjzJa82R1ujh3vyMasDvicQ4nZHq1qqZ5y7D4ixzQ@mail.gmail.com>
 <20150821085146.GP13546@localhost>
Message-ID: <CAFd313xZ1ZinER=xRnMDX4e_Z02+AtKDoKYaUaQ7BWGpfBg3iw@mail.gmail.com>

On Fri, Aug 21, 2015 at 2:21 PM, Vinod Koul <vinod.koul at intel.com> wrote:
> On Fri, Aug 21, 2015 at 02:15:08PM +0530, Rameshwar Sahu wrote:
>> Hi Vinod,
>>
>> On Fri, Aug 21, 2015 at 2:09 PM, Vinod Koul <vinod.koul at intel.com> wrote:
>> > On Thu, Aug 20, 2015 at 04:00:56PM +0530, Rameshwar Prasad Sahu wrote:
>> >> This patch fixes the an locking issue where client callback performs
>> >                 ^^^^^^^^^^^^
>> > ??
>> >
>> >> further submission.
>> > Do you men you are preventing that or fixing for this to be allowed?
>>
>> Fixing lock to allow client to submit further request in there
>> callback routine if they would like.
>
> Okay please fix the changelog to make it clear :)

Okay Vinod

>
> --
> ~Vinod
>
> --
> To unsubscribe from this list: send the line "unsubscribe dmaengine" in
> the body of a message to majordomo at vger.kernel.org
> More majordomo info at  http://vger.kernel.org/majordomo-info.html


From clemens.gruber at pqgruber.com  Fri Aug 21 01:53:42 2015
From: clemens.gruber at pqgruber.com (Clemens Gruber)
Date: Fri, 21 Aug 2015 10:53:42 +0200
Subject: RX packet loss on i.MX6Q running 4.2-rc7
In-Reply-To: <CALHpu37TYT8bL3BmaNhYCukiJQrMPMgmwXFToGH6Y7xRRrPJ-Q@mail.gmail.com>
References: <20150820223049.GA20710@pqgruber.com>
 <CALHpu37TYT8bL3BmaNhYCukiJQrMPMgmwXFToGH6Y7xRRrPJ-Q@mail.gmail.com>
Message-ID: <20150821085342.GA9849@pqgruber.com>

On Fri, Aug 21, 2015 at 06:49:20AM +0200, Jon Nettleton wrote:
> On Fri, Aug 21, 2015 at 12:30 AM, Clemens Gruber
> <clemens.gruber at pqgruber.com> wrote:
> > Hi,
> >
> > I am experiencing massive RX packet loss on my i.MX6Q (Chip rev 1.3) on Linux
> > 4.2-rc7 with a Marvell 88E1510 Gigabit Ethernet PHY connected over RGMII.
> > I noticed it when doing an UDP benchmark with iperf3. When sending UDP packets
> > from a Debian PC to the i.MX6 with a rate of 100 Mbit/s, 99% of the packets are
> > lost. With a rate of 10 Mbit/s, we are still losing 93% of all packets. TCP RX
> > does suffer from packet loss too, but still achieves about 211 Mbit/s.
> > TX is not affected.
> >
> > Steps to reproduce:
> > On the i.MX6: iperf3 -s
> > On a desktop PC:  iperf3 -b 10M -u -c MX6IP
> >
> > The iperf3 results:
> > [ ID] Interval           Transfer     Bandwidth       Jitter    Lost/Total
> > [  4]   0.00-10.00  sec  11.8 MBytes  9.90 Mbits/sec  0.687 ms  1397/1497 (93%)
> >
> > During the 10 Mbit UDP test, the IEEE_rx_macerr counter increased to 5371.
> > ifconfig eth0 shows:
> >  RX packets:9216 errors:5248 dropped:170 overruns:5248 frame:5248
> >  TX packets:83 errors:0 dropped:0 overruns:0 carrier:0
> >  collisions:0
> >
> > Here are the TCP results with iperf3 -c MX6IP:
> > [ ID] Interval           Transfer     Bandwidth       Retr
> > [  4]   0.00-10.00  sec   252 MBytes   211 Mbits/sec  4343             sender
> > [  4]   0.00-10.00  sec   251 MBytes   211 Mbits/sec                  receiver
> >
> > During the TCP test, IEEE_rx_macerr increased to 4059.
> > ifconfig eth0 shows:
> > RX packets:186368 errors:4206 dropped:50 overruns:4206 frame:4206
> > TX packets:41861 errors:0 dropped:0 overruns:0 carrier:0
> > collisions:0
> >
> > Freescale errata entry ERR004512 did mention a RX FIFO overrun. Is this related?
> >
> > Forcing pause frames via ethtool -A eth0 rx on tx on, does not improve it:
> > Same amount of UDP packet loss with reduced TCP throughput of 190 Mbit/s.
> > IEEE_rx_macerr increased up to 5232 during UDP 10Mbit and up to 4270 for TCP.
> >
> > I am already using the MX6QDL_PAD_GPIO_6__ENET_IRQ workaround, which solved the
> > ping latency issues from ERR006687 but not the packet loss problem.
> >
> > I read through the mailing list archives and found a discussion between Russell
> > King, Marek Vasut, Eric Nelson, Fugang Duan and others about a similar problem.
> > I therefore added you and contributors to fec_main.c to the CC.
> >
> > One suggestion I found, was adding udelay(210); to fec_enet_rx():
> > https://lkml.org/lkml/2014/8/22/88
> > But this also did not reduce the packet loss. (I added it to the fec_enet_rx
> > function just before return pkt_received; but I still got 93% packet loss)
> >
> > Does anyone have the equipment/setup to trace an i.MX6Q during UDP RX traffic
> > from iperf3 to find the root cause of this packet loss problem?
> >
> > What else could we do to fix this?
> >
> 
> This is a bug in iperf3's UDP tests.  Do the same test with iperf2 and
> you will see expected performance.  I believe there is a bug open in
> github about it.
> 
> -Jon

Thank you, Jon.
You are right: With iperf2 I get the following results:
10 Mbit/s: 0% packet loss
50 Mbit/s: 0.045% packet loss
100 Mbit/s: 0.31% packet loss
200 Mbit/s: 0.64% packet loss

Much better! :)

Cheers,
Clemens


From catalin.marinas at arm.com  Fri Aug 21 02:00:43 2015
From: catalin.marinas at arm.com (Catalin Marinas)
Date: Fri, 21 Aug 2015 10:00:43 +0100
Subject: [PATCH] arm64: enable generic idle loop
In-Reply-To: <1440128422-4170-1-git-send-email-leo.yan@linaro.org>
References: <1440128422-4170-1-git-send-email-leo.yan@linaro.org>
Message-ID: <20150821090043.GA14072@e104818-lin.cambridge.arm.com>

On Fri, Aug 21, 2015 at 11:40:22AM +0800, Leo Yan wrote:
> Enable generic idle loop for ARM64, so can support for hlt/nohlt
> command line options to override default idle loop behavior.

Just curious, what do you need this for?

-- 
Catalin


From rsahu at apm.com  Fri Aug 21 02:03:34 2015
From: rsahu at apm.com (Rameshwar Prasad Sahu)
Date: Fri, 21 Aug 2015 14:33:34 +0530
Subject: [PATCH v2] dmaengine: xgene-dma: Fix the lock to allow client for
 further submission of requests
Message-ID: <1440147814-22016-1-git-send-email-rsahu@apm.com>

This patch provides the fix in the cleanup routing such that client can perform
further submission by releasing the lock before calling client's callback function.

Signed-off-by: Rameshwar Prasad Sahu <rsahu at apm.com>
---
 drivers/dma/xgene-dma.c | 33 ++++++++++++++++++++++-----------
 1 file changed, 22 insertions(+), 11 deletions(-)

diff --git a/drivers/dma/xgene-dma.c b/drivers/dma/xgene-dma.c
index d1c8809..0b82bc0 100644
--- a/drivers/dma/xgene-dma.c
+++ b/drivers/dma/xgene-dma.c
@@ -763,12 +763,17 @@ static void xgene_dma_cleanup_descriptors(struct xgene_dma_chan *chan)
 	struct xgene_dma_ring *ring = &chan->rx_ring;
 	struct xgene_dma_desc_sw *desc_sw, *_desc_sw;
 	struct xgene_dma_desc_hw *desc_hw;
+	struct list_head ld_completed;
 	u8 status;

+	INIT_LIST_HEAD(&ld_completed);
+
+	spin_lock_bh(&chan->lock);
+
 	/* Clean already completed and acked descriptors */
 	xgene_dma_clean_completed_descriptor(chan);

-	/* Run the callback for each descriptor, in order */
+	/* Move all completed descriptors to ld completed queue, in order */
 	list_for_each_entry_safe(desc_sw, _desc_sw, &chan->ld_running, node) {
 		/* Get subsequent hw descriptor from DMA rx ring */
 		desc_hw = &ring->desc_hw[ring->head];
@@ -811,15 +816,17 @@ static void xgene_dma_cleanup_descriptors(struct xgene_dma_chan *chan)
 		/* Mark this hw descriptor as processed */
 		desc_hw->m0 = cpu_to_le64(XGENE_DMA_DESC_EMPTY_SIGNATURE);

-		xgene_dma_run_tx_complete_actions(chan, desc_sw);
-
-		xgene_dma_clean_running_descriptor(chan, desc_sw);
-
 		/*
 		 * Decrement the pending transaction count
 		 * as we have processed one
 		 */
 		chan->pending--;
+
+		/*
+		 * Delete this node from ld running queue and append it to
+		 * ld completed queue for further processing
+		 */
+		list_move_tail(&desc_sw->node, &ld_completed);
 	}

 	/*
@@ -828,6 +835,14 @@ static void xgene_dma_cleanup_descriptors(struct xgene_dma_chan *chan)
 	 * ahead and free the descriptors below.
 	 */
 	xgene_chan_xfer_ld_pending(chan);
+
+	spin_unlock_bh(&chan->lock);
+
+	/* Run the callback for each descriptor, in order */
+	list_for_each_entry_safe(desc_sw, _desc_sw, &ld_completed, node) {
+		xgene_dma_run_tx_complete_actions(chan, desc_sw);
+		xgene_dma_clean_running_descriptor(chan, desc_sw);
+	}
 }

 static int xgene_dma_alloc_chan_resources(struct dma_chan *dchan)
@@ -876,11 +891,11 @@ static void xgene_dma_free_chan_resources(struct dma_chan *dchan)
 	if (!chan->desc_pool)
 		return;

-	spin_lock_bh(&chan->lock);
-
 	/* Process all running descriptor */
 	xgene_dma_cleanup_descriptors(chan);

+	spin_lock_bh(&chan->lock);
+
 	/* Clean all link descriptor queues */
 	xgene_dma_free_desc_list(chan, &chan->ld_pending);
 	xgene_dma_free_desc_list(chan, &chan->ld_running);
@@ -1200,15 +1215,11 @@ static void xgene_dma_tasklet_cb(unsigned long data)
 {
 	struct xgene_dma_chan *chan = (struct xgene_dma_chan *)data;

-	spin_lock_bh(&chan->lock);
-
 	/* Run all cleanup for descriptors which have been completed */
 	xgene_dma_cleanup_descriptors(chan);

 	/* Re-enable DMA channel IRQ */
 	enable_irq(chan->rx_irq);
-
-	spin_unlock_bh(&chan->lock);
 }

 static irqreturn_t xgene_dma_chan_ring_isr(int irq, void *id)
--
1.8.2.1



From leo.yan at linaro.org  Fri Aug 21 02:14:46 2015
From: leo.yan at linaro.org (Leo Yan)
Date: Fri, 21 Aug 2015 17:14:46 +0800
Subject: [PATCH] arm64: enable generic idle loop
In-Reply-To: <20150821090043.GA14072@e104818-lin.cambridge.arm.com>
References: <1440128422-4170-1-git-send-email-leo.yan@linaro.org>
 <20150821090043.GA14072@e104818-lin.cambridge.arm.com>
Message-ID: <20150821091446.GB4280@leoy-linaro>

On Fri, Aug 21, 2015 at 10:00:43AM +0100, Catalin Marinas wrote:
> On Fri, Aug 21, 2015 at 11:40:22AM +0800, Leo Yan wrote:
> > Enable generic idle loop for ARM64, so can support for hlt/nohlt
> > command line options to override default idle loop behavior.
> 
> Just curious, what do you need this for?

With this config, usually we can add "nohlt" in command line to force
the cpu will never be powered off; so can quickly narrow down if some
issues are related with cpuidle or not.

And if CPU is powered off, then its debug logic also will be powered off.
So we can simply use this method to let debugger always hot connect with
the target CPU.

Thanks,
Leo Yan


From varada at codeaurora.org  Fri Aug 21 02:20:35 2015
From: varada at codeaurora.org (Varadarajan Narayanan)
Date: Fri, 21 Aug 2015 14:50:35 +0530
Subject: [PATCH] qcom: ipq40xx: Add basic board/dts support for IPQ40XX SoC
Message-ID: <20150821092035.GA22319@codeaurora.org>

Add initial dts files and SoC support for IPQ40XX

Signed-off-by: Varadarajan Narayanan <varada at codeaurora.org>

diff --git a/arch/arm/boot/dts/Makefile b/arch/arm/boot/dts/Makefile
index 246473a..6b4caee 100644
--- a/arch/arm/boot/dts/Makefile
+++ b/arch/arm/boot/dts/Makefile
@@ -477,7 +477,8 @@ dtb-$(CONFIG_ARCH_QCOM) += \
 	qcom-ipq8064-ap148.dtb \
 	qcom-msm8660-surf.dtb \
 	qcom-msm8960-cdp.dtb \
-	qcom-msm8974-sony-xperia-honami.dtb
+	qcom-msm8974-sony-xperia-honami.dtb \
+	qcom-ipq40xx-r3pc.dtb
 dtb-$(CONFIG_ARCH_REALVIEW) += \
 	arm-realview-pb1176.dtb
 dtb-$(CONFIG_ARCH_ROCKCHIP) += \
diff --git a/arch/arm/boot/dts/qcom-ipq40xx-r3pc.dts b/arch/arm/boot/dts/qcom-ipq40xx-r3pc.dts
new file mode 100644
index 0000000..7e4e629
--- /dev/null
+++ b/arch/arm/boot/dts/qcom-ipq40xx-r3pc.dts
@@ -0,0 +1,33 @@
+/* Copyright (c) 2014, The Linux Foundation. All rights reserved.
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License version 2 and
+ * only 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 "qcom-ipq40xx.dtsi"
+
+/ {
+	model = "Qualcomm Technologies, Inc. IPQ40XX R3PC";
+	compatible = "qcom,ipq40xx-r3pc", "qcom,ipq40xx";
+
+	memory {
+		device_type = "memory";
+		reg = <0x80000000 0x20000000>; /* 512MB */
+	};
+
+	chosen {
+		bootargs = "root=/dev/ram rw init=/init console=ttyMSM0,115200n8 initrd=0x82000000,0x000E2246";
+	};
+
+	soc {
+		serial at 78b0000 {
+			status = "ok";
+		};
+	};
+};
diff --git a/arch/arm/boot/dts/qcom-ipq40xx.dtsi b/arch/arm/boot/dts/qcom-ipq40xx.dtsi
new file mode 100644
index 0000000..f572f38
--- /dev/null
+++ b/arch/arm/boot/dts/qcom-ipq40xx.dtsi
@@ -0,0 +1,81 @@
+/*
+ * Copyright (c) 2014, The Linux Foundation. All rights reserved.
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License version 2 and
+ * only 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.
+ */
+
+/dts-v1/;
+
+#include "skeleton.dtsi"
+
+/ {
+	model = "Qualcomm Technologies, Inc. IPQ40XX";
+	compatible = "qcom,ipq40xx";
+	interrupt-parent = <&intc>;
+
+	cpus {
+		#address-cells = <1>;
+		#size-cells = <0>;
+		cpu at 0 {
+			device_type = "cpu";
+			compatible = "arm,cortex-a7";
+			reg = <0x0>;
+		};
+
+		cpu at 1 {
+			device_type = "cpu";
+			compatible = "arm,cortex-a7";
+			reg = <0x1>;
+		};
+
+		cpu at 2 {
+			device_type = "cpu";
+			compatible = "arm,cortex-a7";
+			reg = <0x2>;
+		};
+
+		cpu at 3 {
+			device_type = "cpu";
+			compatible = "arm,cortex-a7";
+			reg = <0x3>;
+		};
+	};
+
+	soc {
+		#address-cells = <1>;
+		#size-cells = <1>;
+		ranges;
+		compatible = "simple-bus";
+
+		intc: interrupt-controller at b000000 {
+			compatible = "qcom,msm-qgic2";
+			interrupt-controller;
+			#interrupt-cells = <3>;
+			reg = <0x0b000000 0x1000>,
+			<0x0b002000 0x1000>;
+		};
+
+		timer {
+			compatible = "arm,armv7-timer";
+			interrupts = <1 2 0xf08>,
+				     <1 3 0xf08>,
+				     <1 4 0xf08>,
+				     <1 1 0xf08>;
+			clock-frequency = <20833333>;
+		};
+
+		serial at 78b0000 {
+			compatible = "qcom,msm-uartdm-v1.4", "qcom,msm-uartdm";
+			reg = <0x78b0000 0x200>;
+			interrupts = <0 108 0>;
+			status = "disabled";
+		};
+	};
+};
diff --git a/arch/arm/configs/ipq_defconfig b/arch/arm/configs/ipq_defconfig
index 1cabd8b..054a159 100644
--- a/arch/arm/configs/ipq_defconfig
+++ b/arch/arm/configs/ipq_defconfig
@@ -22,6 +22,7 @@ CONFIG_ARCH_MSM8X60=y
 CONFIG_ARCH_MSM8960=y
 CONFIG_ARCH_MSM8974=y
 CONFIG_ARCH_IPQ8064=y
+CONFIG_ARCH_IPQ40XX=y
 CONFIG_SMP=y
 CONFIG_PREEMPT=y
 CONFIG_AEABI=y
diff --git a/arch/arm/mach-qcom/Kconfig b/arch/arm/mach-qcom/Kconfig
index fab49a2..3add9f9 100644
--- a/arch/arm/mach-qcom/Kconfig
+++ b/arch/arm/mach-qcom/Kconfig
@@ -26,4 +26,8 @@ config ARCH_IPQ8064
 	bool "Enable support for IPQ806x"
 	select CLKSRC_QCOM
 
+config ARCH_IPQ40XX
+	bool "Enable support for IPQ40XX"
+	select HAVE_ARM_ARCH_TIMER
+
 endif
diff --git a/arch/arm/mach-qcom/board.c b/arch/arm/mach-qcom/board.c
index 6d8bbf7..566487d 100644
--- a/arch/arm/mach-qcom/board.c
+++ b/arch/arm/mach-qcom/board.c
@@ -22,6 +22,7 @@ static const char * const qcom_dt_match[] __initconst = {
 	"qcom,ipq8064",
 	"qcom,msm8660-surf",
 	"qcom,msm8960-cdp",
+	"qcom,ipq40xx-r3pc",
 	NULL
 };
 


From will.deacon at arm.com  Fri Aug 21 02:24:30 2015
From: will.deacon at arm.com (Will Deacon)
Date: Fri, 21 Aug 2015 10:24:30 +0100
Subject: [PATCH v5 1/5] arm/arm64: add smccc ARCH32
In-Reply-To: <20150820113729.GA25962@ermac>
References: <1439973629-19505-1-git-send-email-jens.wiklander@linaro.org>
 <1439973629-19505-2-git-send-email-jens.wiklander@linaro.org>
 <20150819165009.GC10297@arm.com> <20150820113729.GA25962@ermac>
Message-ID: <20150821092430.GC30930@arm.com>

On Thu, Aug 20, 2015 at 12:37:29PM +0100, Jens Wiklander wrote:
> On Wed, Aug 19, 2015 at 05:50:09PM +0100, Will Deacon wrote:
> > On Wed, Aug 19, 2015 at 09:40:25AM +0100, Jens Wiklander wrote:
> > > Adds helpers to do SMC based on ARM SMC Calling Convention.
> > > CONFIG_HAVE_SMCCC is enabled for architectures that may support
> > > the SMC instruction. It's the responsibility of the caller to
> > > know if the SMC instruction is supported by the platform.
> > 
> > [...]
> > > diff --git a/arch/arm64/kernel/smccc-call.S b/arch/arm64/kernel/smccc-call.S
> > > new file mode 100644
> > > index 0000000..3ce7fe8
> > > --- /dev/null
> > > +++ b/arch/arm64/kernel/smccc-call.S
> > > @@ -0,0 +1,34 @@
> > > +/*
> > > + * Copyright (c) 2015, Linaro Limited
> > > + *
> > > + * 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/linkage.h>
> > > +
> > > +#define SMC_PARAM_W0_OFFS      0
> > > +#define SMC_PARAM_W2_OFFS      8
> > > +#define SMC_PARAM_W4_OFFS      16
> > > +#define SMC_PARAM_W6_OFFS      24
> > > +
> > > +/* void smccc_call32(struct smccc_param32 *param) */
> > > +ENTRY(smccc_call32)
> > > +       stp     x28, x30, [sp, #-16]!
> > 
> > Why are you saving lr?
> 
> Agree, no point in saving lr, but I still need to decrease sp with 16 to
> maintain correct alignment. I'll do it with an str instruction instead.

That or pad out with xzr

> > 
> > > +       mov     x28, x0
> > > +       ldp     w0, w1, [x28, #SMC_PARAM_W0_OFFS]
> > > +       ldp     w2, w3, [x28, #SMC_PARAM_W2_OFFS]
> > > +       ldp     w4, w5, [x28, #SMC_PARAM_W4_OFFS]
> > > +       ldp     w6, w7, [x28, #SMC_PARAM_W6_OFFS]
> > > +       smc     #0
> > > +       stp     w0, w1, [x28, #SMC_PARAM_W0_OFFS]
> > > +       stp     w2, w3, [x28, #SMC_PARAM_W2_OFFS]
> > > +       ldp     x28, x30, [sp], #16
> > > +       ret
> > > +ENDPROC(smccc_call32)
> > 
> > Could we deal with this like we do for PSCI instead? (see
> > __invoke_psci_fn_smc). We could also then rename psci-call.S to fw-call.S
> > and stick this in there too.
> 
> I assume you're referring to when to use "hvc" and "smc".

No, I mean use a C prototype to avoid marshalling the parameters in assembly
like this. As Rutland pointed out, the return value is a bit messy, but
the arguments align nicely with the PCS afaict.

Will


From mpa at pengutronix.de  Fri Aug 21 02:26:07 2015
From: mpa at pengutronix.de (Markus Pargmann)
Date: Fri, 21 Aug 2015 11:26:07 +0200
Subject: [PATCH v2 1/5] input: touchscreen: add imx6ul_tsc driver support
In-Reply-To: <1438077521-12857-2-git-send-email-haibo.chen@freescale.com>
References: <1438077521-12857-1-git-send-email-haibo.chen@freescale.com>
 <1438077521-12857-2-git-send-email-haibo.chen@freescale.com>
Message-ID: <20150821092607.GA706@pengutronix.de>

On Tue, Jul 28, 2015 at 05:58:37PM +0800, Haibo Chen wrote:
> Freescale i.MX6UL contains a internal touchscreen controller,
> this patch add a driver to support this controller.
> 
> Signed-off-by: Haibo Chen <haibo.chen at freescale.com>
> ---
>  drivers/input/touchscreen/Kconfig      |  12 +
>  drivers/input/touchscreen/Makefile     |   1 +
>  drivers/input/touchscreen/imx6ul_tsc.c | 504 +++++++++++++++++++++++++++++++++
>  3 files changed, 517 insertions(+)
>  create mode 100644 drivers/input/touchscreen/imx6ul_tsc.c
> 
> diff --git a/drivers/input/touchscreen/Kconfig b/drivers/input/touchscreen/Kconfig
> index 5b272ba..32c300d 100644
> --- a/drivers/input/touchscreen/Kconfig
> +++ b/drivers/input/touchscreen/Kconfig
> @@ -479,6 +479,18 @@ config TOUCHSCREEN_MTOUCH
>  	  To compile this driver as a module, choose M here: the
>  	  module will be called mtouch.
>  
> +config TOUCHSCREEN_IMX6UL_TSC
> +	tristate "Freescale i.MX6UL touchscreen controller"
> +	depends on OF
> +	help
> +	  Say Y here if you have a Freescale i.MX6UL, and want to
> +	  use the internal touchscreen controller.
> +
> +	  If unsure, say N.
> +
> +	  To compile this driver as a module, choose M here: the
> +	  moduel will be called imx6ul_tsc.
> +
>  config TOUCHSCREEN_INEXIO
>  	tristate "iNexio serial touchscreens"
>  	select SERIO
> diff --git a/drivers/input/touchscreen/Makefile b/drivers/input/touchscreen/Makefile
> index c85aae2..9379b32 100644
> --- a/drivers/input/touchscreen/Makefile
> +++ b/drivers/input/touchscreen/Makefile
> @@ -38,6 +38,7 @@ obj-$(CONFIG_TOUCHSCREEN_EGALAX)	+= egalax_ts.o
>  obj-$(CONFIG_TOUCHSCREEN_FUJITSU)	+= fujitsu_ts.o
>  obj-$(CONFIG_TOUCHSCREEN_GOODIX)	+= goodix.o
>  obj-$(CONFIG_TOUCHSCREEN_ILI210X)	+= ili210x.o
> +obj-$(CONFIG_TOUCHSCREEN_IMX6UL_TSC)	+= imx6ul_tsc.o
>  obj-$(CONFIG_TOUCHSCREEN_INEXIO)	+= inexio.o
>  obj-$(CONFIG_TOUCHSCREEN_INTEL_MID)	+= intel-mid-touch.o
>  obj-$(CONFIG_TOUCHSCREEN_IPROC)		+= bcm_iproc_tsc.o
> diff --git a/drivers/input/touchscreen/imx6ul_tsc.c b/drivers/input/touchscreen/imx6ul_tsc.c
> new file mode 100644
> index 0000000..807f1db
> --- /dev/null
> +++ b/drivers/input/touchscreen/imx6ul_tsc.c
> @@ -0,0 +1,504 @@
> +/*
> + * Freescale i.MX6UL touchscreen controller driver
> + *
> + * Copyright (C) 2015 Freescale Semiconductor, Inc.
> + *
> + * This program is free software; you can redistribute it and/or modify
> + * it under the terms of the GNU General Public License version 2 as
> + * published by the Free Software Foundation.
> + */
> +
> +#include <linux/errno.h>
> +#include <linux/kernel.h>
> +#include <linux/module.h>
> +#include <linux/gpio.h>
> +#include <linux/input.h>
> +#include <linux/slab.h>
> +#include <linux/completion.h>
> +#include <linux/delay.h>
> +#include <linux/of.h>
> +#include <linux/of_device.h>
> +#include <linux/of_gpio.h>
> +#include <linux/of_irq.h>
> +#include <linux/interrupt.h>
> +#include <linux/platform_device.h>
> +#include <linux/clk.h>
> +#include <linux/io.h>
> +
> +/* ADC configuration registers field define */
> +#define ADC_AIEN		(0x1 << 7)
> +#define ADC_CONV_DISABLE	0x1F
> +#define ADC_CAL			(0x1 << 7)
> +#define ADC_CALF		0x2
> +#define ADC_12BIT_MODE		(0x2 << 2)
> +#define ADC_IPG_CLK		0x00
> +#define ADC_CLK_DIV_8		(0x03 << 5)
> +#define ADC_SHORT_SAMPLE_MODE	(0x0 << 4)
> +#define ADC_HARDWARE_TRIGGER	(0x1 << 13)
> +#define SELECT_CHANNEL_4	0x04
> +#define SELECT_CHANNEL_1	0x01
> +#define DISABLE_CONVERSION_INT	(0x0 << 7)
> +
> +/* ADC registers */
> +#define REG_ADC_HC0		0x00
> +#define REG_ADC_HC1		0x04
> +#define REG_ADC_HC2		0x08
> +#define REG_ADC_HC3		0x0C
> +#define REG_ADC_HC4		0x10
> +#define REG_ADC_HS		0x14
> +#define REG_ADC_R0		0x18
> +#define REG_ADC_CFG		0x2C
> +#define REG_ADC_GC		0x30
> +#define REG_ADC_GS		0x34
> +
> +#define ADC_TIMEOUT		msecs_to_jiffies(100)

These defines are in two drivers. Here and in
drivers/iio/adc/vf610_adc.c

> +
> +/* TSC registers */
> +#define REG_TSC_BASIC_SETING	0x00
> +#define REG_TSC_PRE_CHARGE_TIME	0x10
> +#define REG_TSC_FLOW_CONTROL	0x20
> +#define REG_TSC_MEASURE_VALUE	0x30
> +#define REG_TSC_INT_EN		0x40
> +#define REG_TSC_INT_SIG_EN	0x50
> +#define REG_TSC_INT_STATUS	0x60
> +#define REG_TSC_DEBUG_MODE	0x70
> +#define REG_TSC_DEBUG_MODE2	0x80
> +
> +/* TSC configuration registers field define */
> +#define DETECT_4_WIRE_MODE	(0x0 << 4)
> +#define AUTO_MEASURE		0x1
> +#define MEASURE_SIGNAL		0x1
> +#define DETECT_SIGNAL		(0x1 << 4)
> +#define VALID_SIGNAL		(0x1 << 8)
> +#define MEASURE_INT_EN		0x1
> +#define MEASURE_SIG_EN		0x1
> +#define VALID_SIG_EN		(0x1 << 8)
> +#define DE_GLITCH_2		(0x2 << 29)
> +#define START_SENSE		(0x1 << 12)
> +#define TSC_DISABLE		(0x1 << 16)
> +#define DETECT_MODE		0x2
> +
> +struct imx6ul_tsc {
> +	struct device *dev;
> +	struct input_dev *input;
> +	void __iomem *tsc_regs;
> +	void __iomem *adc_regs;
> +	struct clk *tsc_clk;
> +	struct clk *adc_clk;
> +
> +	int xnur_gpio;
> +	int measure_delay_time;
> +	int pre_charge_time;
> +
> +	struct completion completion;
> +};
> +
> +/*
> + * TSC module need ADC to get the measure value. So
> + * before config TSC, we should initialize ADC module.
> + */
> +static void imx6ul_adc_init(struct imx6ul_tsc *tsc)
> +{
> +	int adc_hc = 0;
> +	int adc_gc;
> +	int adc_gs;
> +	int adc_cfg;
> +	int timeout;
> +
> +	adc_cfg = readl(tsc->adc_regs + REG_ADC_CFG);
> +	adc_cfg |= ADC_12BIT_MODE | ADC_IPG_CLK;
> +	adc_cfg |= ADC_CLK_DIV_8 | ADC_SHORT_SAMPLE_MODE;
> +	adc_cfg &= ~ADC_HARDWARE_TRIGGER;
> +	writel(adc_cfg, tsc->adc_regs + REG_ADC_CFG);
> +
> +	/* enable calibration interrupt */
> +	adc_hc |= ADC_AIEN;
> +	adc_hc |= ADC_CONV_DISABLE;
> +	writel(adc_hc, tsc->adc_regs + REG_ADC_HC0);
> +
> +	/* start ADC calibration */
> +	adc_gc = readl(tsc->adc_regs + REG_ADC_GC);
> +	adc_gc |= ADC_CAL;
> +	writel(adc_gc, tsc->adc_regs + REG_ADC_GC);
> +
> +	timeout = wait_for_completion_timeout
> +			(&tsc->completion, ADC_TIMEOUT);
> +	if (timeout == 0)
> +		dev_err(tsc->dev, "Timeout for adc calibration\n");
> +
> +	adc_gs = readl(tsc->adc_regs + REG_ADC_GS);
> +	if (adc_gs & ADC_CALF)
> +		dev_err(tsc->dev, "ADC calibration failed\n");
> +
> +	/* TSC need the ADC work in hardware trigger */
> +	adc_cfg = readl(tsc->adc_regs + REG_ADC_CFG);
> +	adc_cfg |= ADC_HARDWARE_TRIGGER;
> +	writel(adc_cfg, tsc->adc_regs + REG_ADC_CFG);
> +}
> +
> +/*
> + * This is a TSC workaround. Currently TSC misconnect two
> + * ADC channels, this function remap channel configure for
> + * hardware trigger.
> + */
> +static void imx6ul_tsc_channel_config(struct imx6ul_tsc *tsc)
> +{
> +	int adc_hc0, adc_hc1, adc_hc2, adc_hc3, adc_hc4;
> +
> +	adc_hc0 = DISABLE_CONVERSION_INT;
> +	writel(adc_hc0, tsc->adc_regs + REG_ADC_HC0);
> +
> +	adc_hc1 = DISABLE_CONVERSION_INT | SELECT_CHANNEL_4;
> +	writel(adc_hc1, tsc->adc_regs + REG_ADC_HC1);
> +
> +	adc_hc2 = DISABLE_CONVERSION_INT;
> +	writel(adc_hc2, tsc->adc_regs + REG_ADC_HC2);
> +
> +	adc_hc3 = DISABLE_CONVERSION_INT | SELECT_CHANNEL_1;
> +	writel(adc_hc3, tsc->adc_regs + REG_ADC_HC3);
> +
> +	adc_hc4 = DISABLE_CONVERSION_INT;
> +	writel(adc_hc4, tsc->adc_regs + REG_ADC_HC4);
> +}

Is this code similar to initialization of the adc driver? Does it make
sense to move this code to the ADC driver?

Best regards,

Markus

> +
> +/*
> + * TSC setting, confige the pre-charge time and measure delay time.
> + * different touch screen may need different pre-charge time and
> + * measure delay time.
> + */
> +static void imx6ul_tsc_set(struct imx6ul_tsc *tsc)
> +{
> +	int basic_setting = 0;
> +	int start;
> +
> +	basic_setting |= tsc->measure_delay_time << 8;
> +	basic_setting |= DETECT_4_WIRE_MODE | AUTO_MEASURE;
> +	writel(basic_setting, tsc->tsc_regs + REG_TSC_BASIC_SETING);
> +
> +	writel(DE_GLITCH_2, tsc->tsc_regs + REG_TSC_DEBUG_MODE2);
> +
> +	writel(tsc->pre_charge_time, tsc->tsc_regs + REG_TSC_PRE_CHARGE_TIME);
> +	writel(MEASURE_INT_EN, tsc->tsc_regs + REG_TSC_INT_EN);
> +	writel(MEASURE_SIG_EN | VALID_SIG_EN,
> +		tsc->tsc_regs + REG_TSC_INT_SIG_EN);
> +
> +	/* start sense detection */
> +	start = readl(tsc->tsc_regs + REG_TSC_FLOW_CONTROL);
> +	start |= START_SENSE;
> +	start &= ~TSC_DISABLE;
> +	writel(start, tsc->tsc_regs + REG_TSC_FLOW_CONTROL);
> +}
> +
> +static void imx6ul_tsc_init(struct imx6ul_tsc *tsc)
> +{
> +	imx6ul_adc_init(tsc);
> +	imx6ul_tsc_channel_config(tsc);
> +	imx6ul_tsc_set(tsc);
> +}
> +
> +static irqreturn_t tsc_irq_fn(int irq, void *dev_id)
> +{
> +	struct imx6ul_tsc *tsc = (struct imx6ul_tsc *)dev_id;
> +	int status;
> +	int value;
> +	int x, y;
> +	int xnur;
> +	int debug_mode2;
> +	int state_machine;
> +	int start;
> +	unsigned long timeout;
> +
> +	status = readl(tsc->tsc_regs + REG_TSC_INT_STATUS);
> +
> +	/* write 1 to clear the bit measure-signal */
> +	writel(MEASURE_SIGNAL | DETECT_SIGNAL,
> +		tsc->tsc_regs + REG_TSC_INT_STATUS);
> +
> +	/* It's a HW self-clean bit. Set this bit and start sense detection */
> +	start = readl(tsc->tsc_regs + REG_TSC_FLOW_CONTROL);
> +	start |= START_SENSE;
> +	writel(start, tsc->tsc_regs + REG_TSC_FLOW_CONTROL);
> +
> +	if (status & MEASURE_SIGNAL) {
> +		value = readl(tsc->tsc_regs + REG_TSC_MEASURE_VALUE);
> +		x = (value >> 16) & 0x0fff;
> +		y = value & 0x0fff;
> +
> +		/*
> +		 * Delay some time(max 2ms), wait the pre-charge done.
> +		 * After the pre-change mode, TSC go into detect mode.
> +		 * And in detect mode, we can get the xnur gpio value.
> +		 * If xnur is low, this means the touch screen still
> +		 * be touched. If xnur is high, this means finger leave
> +		 * the touch screen.
> +		 */
> +		timeout = jiffies + HZ/500;
> +		do {
> +			if (time_after(jiffies, timeout)) {
> +				xnur = 0;
> +				goto touch_event;
> +			}
> +			usleep_range(200, 400);
> +			debug_mode2 = readl(tsc->tsc_regs + REG_TSC_DEBUG_MODE2);
> +			state_machine = (debug_mode2 >> 20) & 0x7;
> +		} while (state_machine != DETECT_MODE);
> +		usleep_range(200, 400);
> +
> +		xnur = gpio_get_value(tsc->xnur_gpio);
> +touch_event:
> +		if (xnur == 0) {
> +			input_report_key(tsc->input, BTN_TOUCH, 1);
> +			input_report_abs(tsc->input, ABS_X, x);
> +			input_report_abs(tsc->input, ABS_Y, y);
> +		} else
> +			input_report_key(tsc->input, BTN_TOUCH, 0);
> +
> +		input_sync(tsc->input);
> +	}
> +
> +	return IRQ_HANDLED;
> +}
> +
> +static irqreturn_t adc_irq_fn(int irq, void *dev_id)
> +{
> +	struct imx6ul_tsc *tsc = (struct imx6ul_tsc *)dev_id;
> +	int coco;
> +	int value;
> +
> +	coco = readl(tsc->adc_regs + REG_ADC_HS);
> +	if (coco & 0x01) {
> +		value = readl(tsc->adc_regs + REG_ADC_R0);
> +		complete(&tsc->completion);
> +	}
> +
> +	return IRQ_HANDLED;
> +}
> +
> +static const struct of_device_id imx6ul_tsc_match[] = {
> +	{ .compatible = "fsl,imx6ul-tsc", },
> +	{ /* sentinel */ }
> +};
> +MODULE_DEVICE_TABLE(of, imx6ul_tsc_match);
> +
> +static int imx6ul_tsc_probe(struct platform_device *pdev)
> +{
> +	struct imx6ul_tsc *tsc;
> +	struct resource *tsc_mem;
> +	struct resource *adc_mem;
> +	struct input_dev *input_dev;
> +	struct device_node *np = pdev->dev.of_node;
> +	int err;
> +	int tsc_irq;
> +	int adc_irq;
> +
> +	tsc = devm_kzalloc(&pdev->dev, sizeof(struct imx6ul_tsc), GFP_KERNEL);
> +	input_dev = devm_input_allocate_device(&pdev->dev);
> +
> +	tsc->dev = &pdev->dev;
> +
> +	tsc->input = input_dev;
> +	tsc->input->evbit[0] = BIT_MASK(EV_KEY) | BIT_MASK(EV_ABS);
> +	tsc->input->keybit[BIT_WORD(BTN_TOUCH)] = BIT_MASK(BTN_TOUCH);
> +	input_set_abs_params(tsc->input, ABS_X, 0, 0xFFF, 0, 0);
> +	input_set_abs_params(tsc->input, ABS_Y, 0, 0xFFF, 0, 0);
> +
> +	tsc->input->name = "iMX6UL TouchScreen Controller";
> +
> +	tsc->xnur_gpio = of_get_named_gpio(np, "xnur-gpio", 0);
> +	err = gpio_request_one(tsc->xnur_gpio, GPIOF_IN, "tsc_X-");
> +	if (err) {
> +		dev_err(&pdev->dev, "failed to request GPIO tsc_X-\n");
> +		return err;
> +	}
> +
> +	tsc_mem = platform_get_resource(pdev, IORESOURCE_MEM, 0);
> +	tsc->tsc_regs = devm_ioremap_resource(&pdev->dev, tsc_mem);
> +	if (IS_ERR(tsc->tsc_regs)) {
> +		dev_err(&pdev->dev, "failed to remap tsc memory\n");
> +		err = PTR_ERR(tsc->tsc_regs);
> +		return err;
> +	}
> +
> +	adc_mem = platform_get_resource(pdev, IORESOURCE_MEM, 1);
> +	tsc->adc_regs = devm_ioremap_resource(&pdev->dev, adc_mem);
> +	if (IS_ERR(tsc->adc_regs)) {
> +		dev_err(&pdev->dev, "failed to remap adc memory\n");
> +		err = PTR_ERR(tsc->adc_regs);
> +		return err;
> +	}
> +
> +	tsc->tsc_clk = devm_clk_get(&pdev->dev, "tsc");
> +	if (IS_ERR(tsc->tsc_clk)) {
> +		dev_err(&pdev->dev, "failed getting tsc clock\n");
> +		err = PTR_ERR(tsc->tsc_clk);
> +		return err;
> +	}
> +
> +	tsc->adc_clk = devm_clk_get(&pdev->dev, "adc");
> +	if (IS_ERR(tsc->adc_clk)) {
> +		dev_err(&pdev->dev, "failed getting adc clock\n");
> +		err = PTR_ERR(tsc->adc_clk);
> +		return err;
> +	}
> +
> +	tsc_irq = platform_get_irq(pdev, 0);
> +	if (tsc_irq < 0) {
> +		dev_err(&pdev->dev, "no tsc irq resource?\n");
> +		return tsc_irq;
> +	}
> +
> +	adc_irq = platform_get_irq(pdev, 1);
> +	if (adc_irq <= 0) {
> +		dev_err(&pdev->dev, "no adc irq resource?\n");
> +		return adc_irq;
> +	}
> +
> +	err = devm_request_threaded_irq(tsc->dev, tsc_irq,
> +					NULL, tsc_irq_fn,
> +					IRQF_TRIGGER_HIGH | IRQF_ONESHOT,
> +					dev_name(&pdev->dev), tsc);
> +	if (err < 0) {
> +		dev_err(&pdev->dev,
> +			"failed requesting tsc irq %d\n",
> +					    tsc_irq);
> +		return err;
> +	}
> +
> +	err = devm_request_irq(tsc->dev, adc_irq,
> +				adc_irq_fn, 0,
> +				dev_name(&pdev->dev), tsc);
> +	if (err < 0) {
> +		dev_err(&pdev->dev,
> +			"failed requesting adc irq %d\n",
> +					    adc_irq);
> +		return err;
> +	}
> +
> +	err = of_property_read_u32(np, "measure-delay-time",
> +				&tsc->measure_delay_time);
> +	if (err)
> +		tsc->measure_delay_time = 0xffff;
> +
> +	err = of_property_read_u32(np, "pre-charge-time",
> +				&tsc->pre_charge_time);
> +	if (err)
> +		tsc->pre_charge_time = 0xfff;
> +
> +	init_completion(&tsc->completion);
> +
> +	err = clk_prepare_enable(tsc->adc_clk);
> +	if (err) {
> +		dev_err(&pdev->dev,
> +			"Could not prepare or enable the adc clock.\n");
> +		return err;
> +	}
> +
> +	err = clk_prepare_enable(tsc->tsc_clk);
> +	if (err) {
> +		dev_err(&pdev->dev,
> +			"Could not prepare or enable the tsc clock.\n");
> +		goto error_tsc_clk_enable;
> +	}
> +
> +	err = input_register_device(tsc->input);
> +	if (err < 0) {
> +		dev_err(&pdev->dev, "failed to register input device\n");
> +		err = -EIO;
> +		goto err_input_register;
> +	}
> +
> +	imx6ul_tsc_init(tsc);
> +
> +	platform_set_drvdata(pdev, tsc);
> +	return 0;
> +
> +err_input_register:
> +	clk_disable_unprepare(tsc->tsc_clk);
> +error_tsc_clk_enable:
> +	clk_disable_unprepare(tsc->adc_clk);
> +
> +	return err;
> +}
> +
> +static void imx6ul_tsc_disable(struct imx6ul_tsc *tsc)
> +{
> +	int tsc_flow;
> +	int adc_cfg;
> +
> +	/* TSC controller enters to idle status */
> +	tsc_flow = readl(tsc->tsc_regs + REG_TSC_FLOW_CONTROL);
> +	tsc_flow |= TSC_DISABLE;
> +	writel(tsc_flow, tsc->tsc_regs + REG_TSC_FLOW_CONTROL);
> +
> +	/* ADC controller enters to stop mode */
> +	adc_cfg = readl(tsc->adc_regs + REG_ADC_HC0);
> +	adc_cfg |= ADC_CONV_DISABLE;
> +	writel(adc_cfg, tsc->adc_regs + REG_ADC_HC0);
> +}
> +
> +static int imx6ul_tsc_remove(struct platform_device *pdev)
> +{
> +	struct imx6ul_tsc *tsc = platform_get_drvdata(pdev);
> +
> +	imx6ul_tsc_disable(tsc);
> +
> +	clk_disable_unprepare(tsc->tsc_clk);
> +	clk_disable_unprepare(tsc->adc_clk);
> +	input_unregister_device(tsc->input);
> +	kfree(tsc);
> +
> +	return 0;
> +}
> +
> +static int __maybe_unused imx6ul_tsc_suspend(struct device *dev)
> +{
> +	struct platform_device *pdev = to_platform_device(dev);
> +	struct imx6ul_tsc *tsc = platform_get_drvdata(pdev);
> +
> +	imx6ul_tsc_disable(tsc);
> +
> +	clk_disable_unprepare(tsc->tsc_clk);
> +	clk_disable_unprepare(tsc->adc_clk);
> +
> +	return 0;
> +}
> +
> +static int __maybe_unused imx6ul_tsc_resume(struct device *dev)
> +{
> +	struct platform_device *pdev = to_platform_device(dev);
> +	struct imx6ul_tsc *tsc = platform_get_drvdata(pdev);
> +	int err;
> +
> +	err = clk_prepare_enable(tsc->adc_clk);
> +	if (err)
> +		return err;
> +
> +	err = clk_prepare_enable(tsc->tsc_clk);
> +	if (err) {
> +		clk_disable_unprepare(tsc->adc_clk);
> +		return err;
> +	}
> +
> +	imx6ul_tsc_init(tsc);
> +	return 0;
> +}
> +
> +static SIMPLE_DEV_PM_OPS(imx6ul_tsc_pm_ops,
> +			 imx6ul_tsc_suspend,
> +			 imx6ul_tsc_resume);
> +
> +static struct platform_driver imx6ul_tsc_driver = {
> +	.driver		= {
> +		.name	= "imx6ul-tsc",
> +		.owner	= THIS_MODULE,
> +		.of_match_table	= imx6ul_tsc_match,
> +		.pm	= &imx6ul_tsc_pm_ops,
> +	},
> +	.probe		= imx6ul_tsc_probe,
> +	.remove		= imx6ul_tsc_remove,
> +};
> +module_platform_driver(imx6ul_tsc_driver);
> +
> +MODULE_AUTHOR("Haibo Chen <haibo.chen at freescale.com>");
> +MODULE_DESCRIPTION("Freescale i.MX6UL Touchscreen controller driver");
> +MODULE_LICENSE("GPL v2");
> -- 
> 1.9.1
> 
> --
> To unsubscribe from this list: send the line "unsubscribe linux-kernel" in
> the body of a message to majordomo at vger.kernel.org
> More majordomo info at  http://vger.kernel.org/majordomo-info.html
> Please read the FAQ at  http://www.tux.org/lkml/
> 

-- 
Pengutronix e.K.                           |                             |
Industrial Linux Solutions                 | http://www.pengutronix.de/  |
Peiner Str. 6-8, 31137 Hildesheim, Germany | Phone: +49-5121-206917-0    |
Amtsgericht Hildesheim, HRA 2686           | Fax:   +49-5121-206917-5555 |
-------------- next part --------------
A non-text attachment was scrubbed...
Name: signature.asc
Type: application/pgp-signature
Size: 819 bytes
Desc: Digital signature
URL: <http://lists.infradead.org/pipermail/linux-arm-kernel/attachments/20150821/922cf2d9/attachment.sig>

From mpa at pengutronix.de  Fri Aug 21 02:27:25 2015
From: mpa at pengutronix.de (Markus Pargmann)
Date: Fri, 21 Aug 2015 11:27:25 +0200
Subject: [PATCH v2 2/5] Documentation: Detail permitted DT properties for
 the imx6ul_tsc
In-Reply-To: <BY1PR03MB1388BBEF576297D76E7E3F839A650@BY1PR03MB1388.namprd03.prod.outlook.com>
References: <1438077521-12857-1-git-send-email-haibo.chen@freescale.com>
 <1438077521-12857-3-git-send-email-haibo.chen@freescale.com>
 <20150819055434.GF11161@pengutronix.de>
 <BY1PR03MB1388BBEF576297D76E7E3F839A650@BY1PR03MB1388.namprd03.prod.outlook.com>
Message-ID: <20150821092725.GB706@pengutronix.de>

On Fri, Aug 21, 2015 at 08:30:16AM +0000, Chen Bough wrote:
> Hi Markus,
> 
> > -----Original Message-----
> > From: Markus Pargmann [mailto:mpa at pengutronix.de]
> > Sent: Wednesday, August 19, 2015 1:55 PM
> > To: Chen Haibo-B51421
> > Cc: robh+dt at kernel.org; pawel.moll at arm.com; mark.rutland at arm.com;
> > ijc+devicetree at hellion.org.uk; galak at codeaurora.org; shawnguo at kernel.org;
> > kernel at pengutronix.de; linux at arm.linux.org.uk; dmitry.torokhov at gmail.com;
> > devicetree at vger.kernel.org; sbranden at broadcom.com; arnd at arndb.de;
> > mchehab at osg.samsung.com; christian.gmeiner at gmail.com;
> > scott.liu at emc.com.tw; linux-kernel at vger.kernel.org; hdegoede at redhat.com;
> > jonathar at broadcom.com; benjamin.tissoires at redhat.com;
> > hans.verkuil at cisco.com; hadess at hadess.net; linux-input at vger.kernel.org;
> > geert at linux-m68k.org; sebastien.szymanski at armadeus.com;
> > mamlinav at gmail.com; linux-arm-kernel at lists.infradead.org
> > Subject: Re: [PATCH v2 2/5] Documentation: Detail permitted DT properties
> > for the imx6ul_tsc
> > 
> > Hi,
> > 
> > On Tue, Jul 28, 2015 at 05:58:38PM +0800, Haibo Chen wrote:
> > > Here we apply required documentation for the imx6ul touch screen
> > > controller driver which describe available properties and how to use
> > > them.
> > >
> > > Signed-off-by: Haibo Chen <haibo.chen at freescale.com>
> > > ---
> > >  .../bindings/input/touchscreen/imx6ul_tsc.txt      | 36
> > ++++++++++++++++++++++
> > >  1 file changed, 36 insertions(+)
> > >  create mode 100644
> > > Documentation/devicetree/bindings/input/touchscreen/imx6ul_tsc.txt
> > >
> > > diff --git
> > > a/Documentation/devicetree/bindings/input/touchscreen/imx6ul_tsc.txt
> > > b/Documentation/devicetree/bindings/input/touchscreen/imx6ul_tsc.txt
> > > new file mode 100644
> > > index 0000000..ac41c32
> > > --- /dev/null
> > > +++ b/Documentation/devicetree/bindings/input/touchscreen/imx6ul_tsc.t
> > > +++ xt
> > > @@ -0,0 +1,36 @@
> > > +* Freescale i.MX6UL Touch Controller
> > > +
> > > +Required properties:
> > > +- compatible: must be "fsl,imx6ul-tsc".
> > > +- reg: this touch controller address and the ADC2 address.
> > 
> > This suggests that this driver is using a unit ADC2. Which also means
> > that there are more than one ADC which are probably identical?
> > 
> > Shouldn't these ADCs be properly described by their own device nodes
> > instead of these two register ranges, two interrupts and two clocks?
> > 
> > Is 'ADC2' usable without tsc? Then ADC1/ADC2 should perhaps get a proper
> > IIO driver.
> 
> For i.MX6UL, there are two ADC. ADC1 is a normal ADC, and ADC2 can only works for
> TSC, the channels of ADC2 are connected to TSC directly. TSC and ADC2 should work
> together as a touch screen controller. 

But as I understand these are two different units. Wouldn't it be better
to abstract it that way in the DT?

Best regards,

Markus

> 
> For ADC1, it share the driver vf610_adc.c (drivers/iio/adc/vf610_adc.c). 
> 
> Best Regards
> 
> Haibo 
>  
> > 
> > Unfortunately I don't have the reference manual to have a look how this
> > all works.
> > 
> > Best regards,
> > 
> > Markus
> > 
> > > +- interrupts: the interrupt of this touch controller and ADC2.
> > > +- clocks: the root clock of touch controller and ADC2.
> > > +- clock-names; must be "tsc" and "adc".
> > > +- xnur-gpio: the X- gpio this controller connect to.
> > > +  This xnur-gpio returns to high once the finger leave the touch
> > > +screen (The
> > > +  last touch event the touch controller capture).
> > > +
> > > +Optional properties:
> > > +- measure-delay-time: the value of measure delay time.
> > > +  Before X-axis or Y-axis measurement, the screen need some time
> > > +before
> > > +  even potential distribution ready.
> > > +  This value depends on the touch screen.
> > > +- pre-charge-time: the touch screen need some time to precharge.
> > > +  This value depends on the touch screen.
> > > +
> > > +Example:
> > > +	tsc: tsc at 02040000 {
> > > +		compatible = "fsl,imx6ul-tsc";
> > > +		reg = <0x02040000 0x4000>, <0x0219c000 0x4000>;
> > > +		interrupts = <GIC_SPI 3 IRQ_TYPE_LEVEL_HIGH>,
> > > +			     <GIC_SPI 101 IRQ_TYPE_LEVEL_HIGH>;
> > > +		clocks = <&clks IMX6UL_CLK_IPG>,
> > > +			 <&clks IMX6UL_CLK_ADC2>;
> > > +		clock-names = "tsc", "adc";
> > > +		pinctrl-names = "default";
> > > +		pinctrl-0 = <&pinctrl_tsc>;
> > > +		xnur-gpio = <&gpio1 3 GPIO_ACTIVE_HIGH>;
> > > +		measure-delay-time = <0xfff>;
> > > +		pre-charge-time = <0xffff>;
> > > +		status = "okay";
> > > +	};
> > > --
> > > 1.9.1
> > >
> > >
> > >
> > 
> > --
> > Pengutronix e.K.                           |
> > |
> > Industrial Linux Solutions                 | http://www.pengutronix.de/
> > |
> > Peiner Str. 6-8, 31137 Hildesheim, Germany | Phone: +49-5121-206917-0
> > |
> > Amtsgericht Hildesheim, HRA 2686           | Fax:   +49-5121-206917-5555
> > |

-- 
Pengutronix e.K.                           |                             |
Industrial Linux Solutions                 | http://www.pengutronix.de/  |
Peiner Str. 6-8, 31137 Hildesheim, Germany | Phone: +49-5121-206917-0    |
Amtsgericht Hildesheim, HRA 2686           | Fax:   +49-5121-206917-5555 |
-------------- next part --------------
A non-text attachment was scrubbed...
Name: signature.asc
Type: application/pgp-signature
Size: 819 bytes
Desc: Digital signature
URL: <http://lists.infradead.org/pipermail/linux-arm-kernel/attachments/20150821/3920152f/attachment-0001.sig>

From vinod.koul at intel.com  Fri Aug 21 03:19:27 2015
From: vinod.koul at intel.com (Vinod Koul)
Date: Fri, 21 Aug 2015 15:49:27 +0530
Subject: [PATCH v2] dmaengine: xgene-dma: Fix the lock to allow client
 for further submission of requests
In-Reply-To: <1440147814-22016-1-git-send-email-rsahu@apm.com>
References: <1440147814-22016-1-git-send-email-rsahu@apm.com>
Message-ID: <20150821101927.GQ13546@localhost>

On Fri, Aug 21, 2015 at 02:33:34PM +0530, Rameshwar Prasad Sahu wrote:
> This patch provides the fix in the cleanup routing such that client can perform
> further submission by releasing the lock before calling client's callback function.

Applied, thanks

-- 
~Vinod



From varada at codeaurora.org  Fri Aug 21 03:31:22 2015
From: varada at codeaurora.org (Varadarajan Narayanan)
Date: Fri, 21 Aug 2015 16:01:22 +0530
Subject: [PATCH] qcom: ipq40xx: Add basic board/dts support for IPQ40XX SoC
In-Reply-To: <20150821092035.GA22319@codeaurora.org>
References: <20150821092035.GA22319@codeaurora.org>
Message-ID: <20150821103122.GA17542@codeaurora.org>

On Fri, Aug 21, 2015 at 02:50:35PM +0530, Varadarajan Narayanan wrote:
> Add initial dts files and SoC support for IPQ40XX

Please ignore this. Missed the Devicetree bindings documentation.
Will post a revised patch.

Thanks
Varada

> Signed-off-by: Varadarajan Narayanan <varada at codeaurora.org>
> 
> diff --git a/arch/arm/boot/dts/Makefile b/arch/arm/boot/dts/Makefile
> index 246473a..6b4caee 100644
> --- a/arch/arm/boot/dts/Makefile
> +++ b/arch/arm/boot/dts/Makefile
> @@ -477,7 +477,8 @@ dtb-$(CONFIG_ARCH_QCOM) += \
>  	qcom-ipq8064-ap148.dtb \
>  	qcom-msm8660-surf.dtb \
>  	qcom-msm8960-cdp.dtb \
> -	qcom-msm8974-sony-xperia-honami.dtb
> +	qcom-msm8974-sony-xperia-honami.dtb \
> +	qcom-ipq40xx-r3pc.dtb
>  dtb-$(CONFIG_ARCH_REALVIEW) += \
>  	arm-realview-pb1176.dtb
>  dtb-$(CONFIG_ARCH_ROCKCHIP) += \
> diff --git a/arch/arm/boot/dts/qcom-ipq40xx-r3pc.dts b/arch/arm/boot/dts/qcom-ipq40xx-r3pc.dts
> new file mode 100644
> index 0000000..7e4e629
> --- /dev/null
> +++ b/arch/arm/boot/dts/qcom-ipq40xx-r3pc.dts
> @@ -0,0 +1,33 @@
> +/* Copyright (c) 2014, The Linux Foundation. All rights reserved.
> + *
> + * This program is free software; you can redistribute it and/or modify
> + * it under the terms of the GNU General Public License version 2 and
> + * only 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 "qcom-ipq40xx.dtsi"
> +
> +/ {
> +	model = "Qualcomm Technologies, Inc. IPQ40XX R3PC";
> +	compatible = "qcom,ipq40xx-r3pc", "qcom,ipq40xx";
> +
> +	memory {
> +		device_type = "memory";
> +		reg = <0x80000000 0x20000000>; /* 512MB */
> +	};
> +
> +	chosen {
> +		bootargs = "root=/dev/ram rw init=/init console=ttyMSM0,115200n8 initrd=0x82000000,0x000E2246";
> +	};
> +
> +	soc {
> +		serial at 78b0000 {
> +			status = "ok";
> +		};
> +	};
> +};
> diff --git a/arch/arm/boot/dts/qcom-ipq40xx.dtsi b/arch/arm/boot/dts/qcom-ipq40xx.dtsi
> new file mode 100644
> index 0000000..f572f38
> --- /dev/null
> +++ b/arch/arm/boot/dts/qcom-ipq40xx.dtsi
> @@ -0,0 +1,81 @@
> +/*
> + * Copyright (c) 2014, The Linux Foundation. All rights reserved.
> + *
> + * This program is free software; you can redistribute it and/or modify
> + * it under the terms of the GNU General Public License version 2 and
> + * only 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.
> + */
> +
> +/dts-v1/;
> +
> +#include "skeleton.dtsi"
> +
> +/ {
> +	model = "Qualcomm Technologies, Inc. IPQ40XX";
> +	compatible = "qcom,ipq40xx";
> +	interrupt-parent = <&intc>;
> +
> +	cpus {
> +		#address-cells = <1>;
> +		#size-cells = <0>;
> +		cpu at 0 {
> +			device_type = "cpu";
> +			compatible = "arm,cortex-a7";
> +			reg = <0x0>;
> +		};
> +
> +		cpu at 1 {
> +			device_type = "cpu";
> +			compatible = "arm,cortex-a7";
> +			reg = <0x1>;
> +		};
> +
> +		cpu at 2 {
> +			device_type = "cpu";
> +			compatible = "arm,cortex-a7";
> +			reg = <0x2>;
> +		};
> +
> +		cpu at 3 {
> +			device_type = "cpu";
> +			compatible = "arm,cortex-a7";
> +			reg = <0x3>;
> +		};
> +	};
> +
> +	soc {
> +		#address-cells = <1>;
> +		#size-cells = <1>;
> +		ranges;
> +		compatible = "simple-bus";
> +
> +		intc: interrupt-controller at b000000 {
> +			compatible = "qcom,msm-qgic2";
> +			interrupt-controller;
> +			#interrupt-cells = <3>;
> +			reg = <0x0b000000 0x1000>,
> +			<0x0b002000 0x1000>;
> +		};
> +
> +		timer {
> +			compatible = "arm,armv7-timer";
> +			interrupts = <1 2 0xf08>,
> +				     <1 3 0xf08>,
> +				     <1 4 0xf08>,
> +				     <1 1 0xf08>;
> +			clock-frequency = <20833333>;
> +		};
> +
> +		serial at 78b0000 {
> +			compatible = "qcom,msm-uartdm-v1.4", "qcom,msm-uartdm";
> +			reg = <0x78b0000 0x200>;
> +			interrupts = <0 108 0>;
> +			status = "disabled";
> +		};
> +	};
> +};
> diff --git a/arch/arm/configs/ipq_defconfig b/arch/arm/configs/ipq_defconfig
> index 1cabd8b..054a159 100644
> --- a/arch/arm/configs/ipq_defconfig
> +++ b/arch/arm/configs/ipq_defconfig
> @@ -22,6 +22,7 @@ CONFIG_ARCH_MSM8X60=y
>  CONFIG_ARCH_MSM8960=y
>  CONFIG_ARCH_MSM8974=y
>  CONFIG_ARCH_IPQ8064=y
> +CONFIG_ARCH_IPQ40XX=y
>  CONFIG_SMP=y
>  CONFIG_PREEMPT=y
>  CONFIG_AEABI=y
> diff --git a/arch/arm/mach-qcom/Kconfig b/arch/arm/mach-qcom/Kconfig
> index fab49a2..3add9f9 100644
> --- a/arch/arm/mach-qcom/Kconfig
> +++ b/arch/arm/mach-qcom/Kconfig
> @@ -26,4 +26,8 @@ config ARCH_IPQ8064
>  	bool "Enable support for IPQ806x"
>  	select CLKSRC_QCOM
>  
> +config ARCH_IPQ40XX
> +	bool "Enable support for IPQ40XX"
> +	select HAVE_ARM_ARCH_TIMER
> +
>  endif
> diff --git a/arch/arm/mach-qcom/board.c b/arch/arm/mach-qcom/board.c
> index 6d8bbf7..566487d 100644
> --- a/arch/arm/mach-qcom/board.c
> +++ b/arch/arm/mach-qcom/board.c
> @@ -22,6 +22,7 @@ static const char * const qcom_dt_match[] __initconst = {
>  	"qcom,ipq8064",
>  	"qcom,msm8660-surf",
>  	"qcom,msm8960-cdp",
> +	"qcom,ipq40xx-r3pc",
>  	NULL
>  };
>  
> 
> _______________________________________________
> linux-arm-kernel mailing list
> linux-arm-kernel at lists.infradead.org
> http://lists.infradead.org/mailman/listinfo/linux-arm-kernel


From varada at codeaurora.org  Fri Aug 21 03:32:53 2015
From: varada at codeaurora.org (Varadarajan Narayanan)
Date: Fri, 21 Aug 2015 16:02:53 +0530
Subject: [PATCH v2] qcom: ipq40xx: Add basic board/dts support for IPQ40XX SoC
Message-ID: <20150821103253.GA27466@codeaurora.org>

Add initial dts files and SoC support for IPQ40XX

Signed-off-by: Varadarajan Narayanan <varada at codeaurora.org>
---
Changes in v2:
  - Added devicetree bindings documentation

 .../devicetree/bindings/clock/qca,gcnt.txt         | 14 ++++
 Documentation/devicetree/bindings/ipq.txt          | 16 ++++
 arch/arm/boot/dts/Makefile                         |  3 +-
 arch/arm/boot/dts/qcom-ipq40xx-r3pc.dts            | 33 +++++++++
 arch/arm/boot/dts/qcom-ipq40xx.dtsi                | 86 ++++++++++++++++++++++
 arch/arm/configs/ipq_defconfig                     |  1 +
 arch/arm/mach-qcom/Kconfig                         |  4 +
 arch/arm/mach-qcom/board.c                         |  1 +
 8 files changed, 157 insertions(+), 1 deletion(-)
 create mode 100644 Documentation/devicetree/bindings/clock/qca,gcnt.txt
 create mode 100644 Documentation/devicetree/bindings/ipq.txt
 create mode 100644 arch/arm/boot/dts/qcom-ipq40xx-r3pc.dts
 create mode 100644 arch/arm/boot/dts/qcom-ipq40xx.dtsi

diff --git a/Documentation/devicetree/bindings/clock/qca,gcnt.txt b/Documentation/devicetree/bindings/clock/qca,gcnt.txt
new file mode 100644
index 0000000..dd0d71e
--- /dev/null
+++ b/Documentation/devicetree/bindings/clock/qca,gcnt.txt
@@ -0,0 +1,14 @@
+QCA Global Counter
+------------------------------------------------
+
+Required properties :
+- compatible : "qcom,qca-gcnt"
+
+- reg : shall contain base register location and length
+
+Example:
+
+	counter {
+		compatible = "qcom,qca-gcnt";
+		reg = <0x004a1000 0x4>;
+	};
diff --git a/Documentation/devicetree/bindings/ipq.txt b/Documentation/devicetree/bindings/ipq.txt
new file mode 100644
index 0000000..7d56bd0
--- /dev/null
+++ b/Documentation/devicetree/bindings/ipq.txt
@@ -0,0 +1,16 @@
+Qualcomm IPQ device tree bindings
+---------------------------------
+
+System on Chip
+
+Device tree must specify which SoC it uses, with one of the
+following compatible strings
+
+       "qcom,ipq40xx"
+
+Platform
+
+Device tree must specify which Platform it uses, with one of the
+following compatible strings
+
+       "qcom,ipq40xx-r3pc"
diff --git a/arch/arm/boot/dts/Makefile b/arch/arm/boot/dts/Makefile
index 246473a..6b4caee 100644
--- a/arch/arm/boot/dts/Makefile
+++ b/arch/arm/boot/dts/Makefile
@@ -477,7 +477,8 @@ dtb-$(CONFIG_ARCH_QCOM) += \
 	qcom-ipq8064-ap148.dtb \
 	qcom-msm8660-surf.dtb \
 	qcom-msm8960-cdp.dtb \
-	qcom-msm8974-sony-xperia-honami.dtb
+	qcom-msm8974-sony-xperia-honami.dtb \
+	qcom-ipq40xx-r3pc.dtb
 dtb-$(CONFIG_ARCH_REALVIEW) += \
 	arm-realview-pb1176.dtb
 dtb-$(CONFIG_ARCH_ROCKCHIP) += \
diff --git a/arch/arm/boot/dts/qcom-ipq40xx-r3pc.dts b/arch/arm/boot/dts/qcom-ipq40xx-r3pc.dts
new file mode 100644
index 0000000..7e4e629
--- /dev/null
+++ b/arch/arm/boot/dts/qcom-ipq40xx-r3pc.dts
@@ -0,0 +1,33 @@
+/* Copyright (c) 2014, The Linux Foundation. All rights reserved.
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License version 2 and
+ * only 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 "qcom-ipq40xx.dtsi"
+
+/ {
+	model = "Qualcomm Technologies, Inc. IPQ40XX R3PC";
+	compatible = "qcom,ipq40xx-r3pc", "qcom,ipq40xx";
+
+	memory {
+		device_type = "memory";
+		reg = <0x80000000 0x20000000>; /* 512MB */
+	};
+
+	chosen {
+		bootargs = "root=/dev/ram rw init=/init console=ttyMSM0,115200n8 initrd=0x82000000,0x000E2246";
+	};
+
+	soc {
+		serial at 78b0000 {
+			status = "ok";
+		};
+	};
+};
diff --git a/arch/arm/boot/dts/qcom-ipq40xx.dtsi b/arch/arm/boot/dts/qcom-ipq40xx.dtsi
new file mode 100644
index 0000000..76c55a3
--- /dev/null
+++ b/arch/arm/boot/dts/qcom-ipq40xx.dtsi
@@ -0,0 +1,86 @@
+/*
+ * Copyright (c) 2014, The Linux Foundation. All rights reserved.
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License version 2 and
+ * only 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.
+ */
+
+/dts-v1/;
+
+#include "skeleton.dtsi"
+
+/ {
+	model = "Qualcomm Technologies, Inc. IPQ40XX";
+	compatible = "qcom,ipq40xx";
+	interrupt-parent = <&intc>;
+
+	cpus {
+		#address-cells = <1>;
+		#size-cells = <0>;
+		cpu at 0 {
+			device_type = "cpu";
+			compatible = "arm,cortex-a7";
+			reg = <0x0>;
+		};
+
+		cpu at 1 {
+			device_type = "cpu";
+			compatible = "arm,cortex-a7";
+			reg = <0x1>;
+		};
+
+		cpu at 2 {
+			device_type = "cpu";
+			compatible = "arm,cortex-a7";
+			reg = <0x2>;
+		};
+
+		cpu at 3 {
+			device_type = "cpu";
+			compatible = "arm,cortex-a7";
+			reg = <0x3>;
+		};
+	};
+
+	soc {
+		#address-cells = <1>;
+		#size-cells = <1>;
+		ranges;
+		compatible = "simple-bus";
+
+		intc: interrupt-controller at b000000 {
+			compatible = "qcom,msm-qgic2";
+			interrupt-controller;
+			#interrupt-cells = <3>;
+			reg = <0x0b000000 0x1000>,
+			<0x0b002000 0x1000>;
+		};
+
+		counter {
+			compatible = "qcom,qca-gcnt";
+			reg = <0x004a1000 0x4>;
+		};
+
+		timer {
+			compatible = "arm,armv7-timer";
+			interrupts = <1 2 0xf08>,
+				     <1 3 0xf08>,
+				     <1 4 0xf08>,
+				     <1 1 0xf08>;
+			clock-frequency = <20833333>;
+		};
+
+		serial at 78b0000 {
+			compatible = "qcom,msm-uartdm-v1.4", "qcom,msm-uartdm";
+			reg = <0x78b0000 0x200>;
+			interrupts = <0 108 0>;
+			status = "disabled";
+		};
+	};
+};
diff --git a/arch/arm/configs/ipq_defconfig b/arch/arm/configs/ipq_defconfig
index 1cabd8b..054a159 100644
--- a/arch/arm/configs/ipq_defconfig
+++ b/arch/arm/configs/ipq_defconfig
@@ -22,6 +22,7 @@ CONFIG_ARCH_MSM8X60=y
 CONFIG_ARCH_MSM8960=y
 CONFIG_ARCH_MSM8974=y
 CONFIG_ARCH_IPQ8064=y
+CONFIG_ARCH_IPQ40XX=y
 CONFIG_SMP=y
 CONFIG_PREEMPT=y
 CONFIG_AEABI=y
diff --git a/arch/arm/mach-qcom/Kconfig b/arch/arm/mach-qcom/Kconfig
index fab49a2..3add9f9 100644
--- a/arch/arm/mach-qcom/Kconfig
+++ b/arch/arm/mach-qcom/Kconfig
@@ -26,4 +26,8 @@ config ARCH_IPQ8064
 	bool "Enable support for IPQ806x"
 	select CLKSRC_QCOM
 
+config ARCH_IPQ40XX
+	bool "Enable support for IPQ40XX"
+	select HAVE_ARM_ARCH_TIMER
+
 endif
diff --git a/arch/arm/mach-qcom/board.c b/arch/arm/mach-qcom/board.c
index 6d8bbf7..566487d 100644
--- a/arch/arm/mach-qcom/board.c
+++ b/arch/arm/mach-qcom/board.c
@@ -22,6 +22,7 @@ static const char * const qcom_dt_match[] __initconst = {
 	"qcom,ipq8064",
 	"qcom,msm8660-surf",
 	"qcom,msm8960-cdp",
+	"qcom,ipq40xx-r3pc",
 	NULL
 };
 
-- 
1.8.2.1



From benoar at dolka.fr  Fri Aug 21 04:33:56 2015
From: benoar at dolka.fr (Benjamin Cama)
Date: Fri, 21 Aug 2015 13:33:56 +0200
Subject: [PATCH] ARM: orion5x: fix legacy orion5x IRQ numbers
In-Reply-To: <1439648246-32757-1-git-send-email-gregory.clement@free-electrons.com>
References: <1439648246-32757-1-git-send-email-gregory.clement@free-electrons.com>
Message-ID: <1440156836.5070.9.camel@dolka.fr>

Hi Gr?gory,

Le samedi 15 ao?t 2015 ? 16:17 +0200, Gregory CLEMENT a ?crit :
> I amended the patch from Benjamin as it break the build for
> dove. Could you test it again wit this version?

Thanks for the fix. I don't have much time to test it, but as the dts
conversion patch for my Linkstation Mini is in the series, this fix
shouldn't change anything, as the dts board file uses the generic
irqchip handler, isn't it?

Tell me if I missed something. Regards,
--
benjamin


From jens.wiklander at linaro.org  Fri Aug 21 04:43:32 2015
From: jens.wiklander at linaro.org (Jens Wiklander)
Date: Fri, 21 Aug 2015 13:43:32 +0200
Subject: [PATCH v5 1/5] arm/arm64: add smccc ARCH32
In-Reply-To: <20150821092430.GC30930@arm.com>
References: <1439973629-19505-1-git-send-email-jens.wiklander@linaro.org>
 <1439973629-19505-2-git-send-email-jens.wiklander@linaro.org>
 <20150819165009.GC10297@arm.com> <20150820113729.GA25962@ermac>
 <20150821092430.GC30930@arm.com>
Message-ID: <20150821114331.GA11701@ermac>

On Fri, Aug 21, 2015 at 10:24:30AM +0100, Will Deacon wrote:
> On Thu, Aug 20, 2015 at 12:37:29PM +0100, Jens Wiklander wrote:
> > On Wed, Aug 19, 2015 at 05:50:09PM +0100, Will Deacon wrote:
> > > On Wed, Aug 19, 2015 at 09:40:25AM +0100, Jens Wiklander wrote:
> > > > Adds helpers to do SMC based on ARM SMC Calling Convention.
> > > > CONFIG_HAVE_SMCCC is enabled for architectures that may support
> > > > the SMC instruction. It's the responsibility of the caller to
> > > > know if the SMC instruction is supported by the platform.
> > > 
> > > [...]
> > > > diff --git a/arch/arm64/kernel/smccc-call.S b/arch/arm64/kernel/smccc-call.S
> > > > new file mode 100644
> > > > index 0000000..3ce7fe8
> > > > --- /dev/null
> > > > +++ b/arch/arm64/kernel/smccc-call.S
> > > > @@ -0,0 +1,34 @@
> > > > +/*
> > > > + * Copyright (c) 2015, Linaro Limited
> > > > + *
> > > > + * 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/linkage.h>
> > > > +
> > > > +#define SMC_PARAM_W0_OFFS      0
> > > > +#define SMC_PARAM_W2_OFFS      8
> > > > +#define SMC_PARAM_W4_OFFS      16
> > > > +#define SMC_PARAM_W6_OFFS      24
> > > > +
> > > > +/* void smccc_call32(struct smccc_param32 *param) */
> > > > +ENTRY(smccc_call32)
> > > > +       stp     x28, x30, [sp, #-16]!
> > > 
> > > Why are you saving lr?
> > 
> > Agree, no point in saving lr, but I still need to decrease sp with 16 to
> > maintain correct alignment. I'll do it with an str instruction instead.
> 
> That or pad out with xzr
> 
> > > 
> > > > +       mov     x28, x0
> > > > +       ldp     w0, w1, [x28, #SMC_PARAM_W0_OFFS]
> > > > +       ldp     w2, w3, [x28, #SMC_PARAM_W2_OFFS]
> > > > +       ldp     w4, w5, [x28, #SMC_PARAM_W4_OFFS]
> > > > +       ldp     w6, w7, [x28, #SMC_PARAM_W6_OFFS]
> > > > +       smc     #0
> > > > +       stp     w0, w1, [x28, #SMC_PARAM_W0_OFFS]
> > > > +       stp     w2, w3, [x28, #SMC_PARAM_W2_OFFS]
> > > > +       ldp     x28, x30, [sp], #16
> > > > +       ret
> > > > +ENDPROC(smccc_call32)
> > > 
> > > Could we deal with this like we do for PSCI instead? (see
> > > __invoke_psci_fn_smc). We could also then rename psci-call.S to fw-call.S
> > > and stick this in there too.
> > 
> > I assume you're referring to when to use "hvc" and "smc".
> 
> No, I mean use a C prototype to avoid marshalling the parameters in assembly
> like this. As Rutland pointed out, the return value is a bit messy, but
> the arguments align nicely with the PCS afaict.

If possible I'd like the function to have the same prototype for both
arm and arm64. For arm it's not possible to supply more than 4
parameters. To fully support SMC Calling Convention we need to be able
to pass 8 parameters and have 4 return values. The OP-TEE driver in this
patch set depends on this. I don't see how we can avoid the marshalling
here.

We could have two versions of the SMCCC functions, one simplified which
only uses registers and one complete like this one with marshalling.

Thanks,
Jens


From maitysanchayan at gmail.com  Fri Aug 21 05:11:44 2015
From: maitysanchayan at gmail.com (maitysanchayan at gmail.com)
Date: Fri, 21 Aug 2015 17:41:44 +0530
Subject: [PATCH] ARM: dts: vfxxx: Add iio_hwmon node for ADC temperature
 channel
In-Reply-To: <b639ca620369d196491a4af8739b87d580e71bf6.1438876380.git.maitysanchayan@gmail.com>
References: <b639ca620369d196491a4af8739b87d580e71bf6.1438876380.git.maitysanchayan@gmail.com>
Message-ID: <20150821121144.GE2233@Sanchayan-Arch.toradex.int>

Ping?

- Sanchayan.

On 15-08-06 21:28:22, Sanchayan Maity wrote:
> Add iio_hwmon node to expose the temperature channel on Vybrid
> as hardware monitor device using the iio_hwmon driver.
> 
> Signed-off-by: Sanchayan Maity <maitysanchayan at gmail.com>
> ---
>  arch/arm/boot/dts/vfxxx.dtsi | 5 +++++
>  1 file changed, 5 insertions(+)
> 
> diff --git a/arch/arm/boot/dts/vfxxx.dtsi b/arch/arm/boot/dts/vfxxx.dtsi
> index 39173bb..0993d66 100644
> --- a/arch/arm/boot/dts/vfxxx.dtsi
> +++ b/arch/arm/boot/dts/vfxxx.dtsi
> @@ -597,5 +597,10 @@
>  				status = "disabled";
>  			};
>  		};
> +
> +		iio_hwmon {
> +			compatible = "iio-hwmon";
> +			io-channels = <&adc0 16>;
> +		};
>  	};
>  };
> -- 
> 2.5.0
> 


From gregory.clement at free-electrons.com  Fri Aug 21 05:19:00 2015
From: gregory.clement at free-electrons.com (Gregory CLEMENT)
Date: Fri, 21 Aug 2015 14:19:00 +0200
Subject: MUSB dual-role on AM335x behaving weirdly
In-Reply-To: <20150820164656.GA4938@saruman.tx.rr.com>
References: <20150526145118.GD26599@saruman.tx.rr.com>
 <20150527094205.GO3199@piout.net> <5594E56B.3040200@free-electrons.com>
 <CADYTM3ZF5m++N1NqmOJoH5agbYrzpvSbLnuLVgttxwzdzwmGwQ@mail.gmail.com>
 <55C0B954.3020106@free-electrons.com> <55C0CAC6.3020603@free-electrons.com>
 <20150804193257.GF9623@saruman.tx.rr.com>
 <55D326BD.2030706@free-electrons.com>
 <20150818141334.GC9143@saruman.tx.rr.com> <55D601C5.40608@free-electrons.com>
 <20150820164656.GA4938@saruman.tx.rr.com>
Message-ID: <55D71734.2030801@free-electrons.com>

On 20/08/2015 18:46, Felipe Balbi wrote:
> On Thu, Aug 20, 2015 at 06:35:17PM +0200, Gregory CLEMENT wrote:
>> Hi Felipe,
>>
>> On 18/08/2015 16:13, Felipe Balbi wrote:
>>> Hi,
>>>
>>> On Tue, Aug 18, 2015 at 02:36:13PM +0200, Gregory CLEMENT wrote:
>>>> Hi again Felipe,
>>>>
>>>> I sent this email again without the capture because it prevented to be delivered
>>>> to the mailing lists.
>>>>
>>>> On 04/08/2015 21:32, Felipe Balbi wrote:
>>>>> On Tue, Aug 04, 2015 at 04:23:02PM +0200, Gregory CLEMENT wrote:
>>>>>> Hi again,
>>>>>> On 04/08/2015 15:08, Gregory CLEMENT wrote:
>>>>>>> Hi Bin,
>>>>>>>
>>>>>>> On 02/07/2015 19:05, Bin Liu wrote:
>>>>>>>> Hi,
>>>>>>>>
>>>>>>>> On Thu, Jul 2, 2015 at 2:16 AM, Gregory CLEMENT
>>>>>>>> <gregory.clement at free-electrons.com> wrote:
>>>>>>>>> Hi Felipe,
>>>>>>>>>
>>>>>>>>> On 27/05/2015 11:42, Alexandre Belloni wrote:
>>>>>>>>>> Hi,
>>>>>>>>>>
>>>>>>>>>> On 26/05/2015 at 09:51:18 -0500, Felipe Balbi wrote :
>>>>>>>>>>> On Thu, May 14, 2015 at 04:36:33PM -0500, Bin Liu wrote:
>>>>>>>>>>>> Alexandre,
>>>>>>>>>>>>
>>>>>>>>>>>> On Thu, May 14, 2015 at 4:26 PM, Alexandre Belloni
>>>>>>>>>>>> <alexandre.belloni at free-electrons.com> wrote:
>>>>>>>>>>>>> On 14/05/2015 at 16:16:12 -0500, Bin Liu wrote :
>>>>>>>>>>>>>> I think I found the root cause of the problem: board design issue - I
>>>>>>>>>>>>>> bet the custom board has too much cap on VBUS line. It should be <
>>>>>>>>>>>>>> 10uF.
>>>>>>>>>>>>>>
>>>>>>>>>>>>>
>>>>>>>>>>>>> We have a custom board that exhibits the issue but it only has a 100nF
>>>>>>>>>>>>> cap on VBUS.
>>>>>>>>>>>>
>>>>>>>>>>>> Have you measured the VBUS discharging? Is there any way to share your
>>>>>>>>>>>> schematics?
>>>>>>>>>>>
>>>>>>>>>>> Alexandre, any further comments ?
>>>>>>>>>>>
>>>>>>>>>>
>>>>>>>>>> Yeah, I have just got more info.
>>>>>>>>>>
>>>>>>>>>> This is the relevant part of the schematic:
>>>>>>>>>> http://free-electrons.com/~alexandre/usb.png
>>>>>>>>>>
>>>>>>>>>> The total VBUS capacitance is 200nF and the USB0 pins are connected
>>>>>>>>>> directly to the AM3358 pins. U1 is actually not fitted.
>>>>>>>>>>
>>>>>>>>>> We didn't measure VBUS discharging but we observe the OTG pin sensing
>>>>>>>>>> stops when plugging an OTG cable without any device.
>>>>>>>>>
>>>>>>>>> Do you have any news about this topic?
>>>>>>>>>
>>>>>>>>>
>>>>>>>>> Is there something else that we can do to help solving this issue?
>>>>>>>>
>>>>>>>> In the case of CONFIG_USB_MUSB_DUAL_ROLE=y and dr_mode=otg, how is the
>>>>>>>> gadget driver configured? It has to be a module not built-in.
>>>>>>>
>>>>>>> Indeed when I configured CONFIG_USB_MUSB_HDRC=m and CONFIG_USB_MUSB_DSPS=m
>>>>>>> it worked seamless.
>>>>>>>
>>>>>>
>>>>>> Actually it didn't worked. And now sometimes I even received continuously
>>>>>> the following message:
>>>>>>
>>>>>>  musb_bus_suspend 2484: trying to suspend as a_wait_vfall while active
>>>>>
>>>>> this is likely because your VBUS hasn't dropped below 0.8V fast enough.
>>>>>
>>>>> I could only trigger this message in that situation. Use a scope to poke
>>>>> at VBUS and see how long is takes to reach 0.8V, this could all be cause
>>>>> by too much capacitance on VBUS line.
>>>>
>>>> We got some news:
>>>> "The capacitance on VBUS due to components is 200nF and the additional parasitic
>>>> capacitance will be much smaller than this"
>>>>
>>>> The rail discharge time is ~36ms when an USB drive is removed from the OTG adapter.
>>>> I attached a capture of this.
>>>>
>>>> What do you think about these values?
>>>>
>>>>
>>>> However, "there appears to be a considerable delay between the removal of a usb
>>>> drive and the initiation of the VBUS discharge (maybe ~1 second, I wasn't able
>>>> to measure this time)."
>>>
>>> yeah, this is really weird. I can't think of anything that would make
>>> VBUS discharge slower from a SW point of view. Once you remove the
>>> cable, VBUS is physically removed and there's nothing else charging it.
>>
>> I have more feedback about it: "When I look at it on the oscilloscope
>> this isn't a 'slow discharge' like a slowly draining capacitor, it is
>> a delay between the removal of a device and the initiation of the
>> discharge.  The discharge itself is quite fast once it begins, it just
>> seems as if the SOC/driver is taking a long time to notice the cable
>> is disconnected. At this stage, this isn't actually a problem, just
>> odd."
>>
>> While working on this issue we found that the
>> tg_state_a_wait_vrise_timeout case seemed not managed by musb_dsps
>> driver. I've just submitted a patch for it:
>> https://lkml.org/lkml/2015/8/20/507
> 
> cool, I'll test it next week. Good finding btw.

Thanks, however it seemed already needs to be amended.

> 
>> I made most of my test on a 3.17 kernel and today by using a 4.1
>> kernel with the patch I have submitted I didn't manage to reproduce
>> the issue. I saw that since 3.17, there were some patches related to
>> the babble interrupts; so maybe it was enough to fix the issue we saw.
>> It is still weird because one month ago I also tested with a 4.1
>> kernel and I had issues...
>>
>> It needs more testing to see if it is really fixed because the issue
>> comes only time to time. I will keep you inform about our last tests.
> 
> all right. Seems like we really need to turn some of those states
> handling into a reusable (musb-specific) library.


There is something in drivers/usb/common/usb-otg-fsm.c. First I thought it
was handle until I realized that this file was nit used at all for musb
driver.

Thanks,

Gregory



-- 
Gregory Clement, Free Electrons
Kernel, drivers, real-time and embedded Linux
development, consulting, training and support.
http://free-electrons.com


From ijc at debian.org  Fri Aug 21 05:24:17 2015
From: ijc at debian.org (Ian Campbell)
Date: Fri, 21 Aug 2015 13:24:17 +0100
Subject: I/O issues with writing to mtdblock devices on kirkwood
Message-ID: <1440159857.19360.50.camel@debian.org>

Hi kirkwood-upstream,

We (Debian) have had a couple of reports of I/O errors running Debian
on kirkwood, specifically it seems to relate to later kernels (e.g.
4.0+) and I _suspect_ (without proof) that it may be due to the switch
from board files to the DTS based kernel, or some change implied by
this (e.g. different SATA driver now or timeouts have changed
perhaps?).

There are two reports that writing to mdtblock (as a raw device, where
the bootloader expects to find the kernel etc) causes SATA to fall
apart. Please see this thread:
http://mid.gmane.org/<
CAMLx2CqT+2fzfa9_Bc0fXLAJ1wJ+yQuJvUThJwN48kGJTJhJxg at mail.gmail.com>

There was an earlier iteration of the same thing as the above:
http://mid.gmane.org/<CAKzmTe1vUGjiPt8k3VHNUP9aHs7zF9wCXoXOo8XFjD-YEH-U5A at mail.gmail.com>

Thanks for any pointers you can give. I've copied the reporters as well
as the debian-arm list.

@debian-arm: I had the impression there had been more reports than
these two/three but I'm not seeing them in my folder, if you know of
others then please chime in.

Ian.


From gregory.clement at free-electrons.com  Fri Aug 21 05:29:37 2015
From: gregory.clement at free-electrons.com (Gregory CLEMENT)
Date: Fri, 21 Aug 2015 14:29:37 +0200
Subject: [PATCH] usb: musb: dsps: handle the otg_state_a_wait_vrise_timeout
 case
In-Reply-To: <1440087153-31084-1-git-send-email-gregory.clement@free-electrons.com>
References: <1440087153-31084-1-git-send-email-gregory.clement@free-electrons.com>
Message-ID: <55D719B1.8010700@free-electrons.com>

Hi all,

On 20/08/2015 18:12, Gregory CLEMENT wrote:
> According to the OTG specification after a timeout of
> OTG_TIME_A_WAIT_VRISE (the maximum value is 100ms) the driver must
> move from the state a_wait_vrise to the state a_wait_bcon. However,
> the dsps version of musb does not handle this case.
> 
> Without it, the driver could remain stuck in the a_wait_vrise. It can
> be reproduce with the following steps:
> 
> 1) Boot a board with no USB adapter inserted
> 2) Insert an empty OTG adapter
> 3) Wait 2 seconds then remove the OTG adapter
> 4) The unit is now stuck in host mode, the VBUS switch is latched on
> and the ID pin is no longer polled.
> 
> The only way to exit this state was to insert a OTG adapter with an
> USB device connected. Until this, the usb device mode was not
> available.
> 
> It was tested on a AM35x based board.
> 
> CC: <stable at vger.kernel.org>
> Signed-off-by: Gregory CLEMENT <gregory.clement at free-electrons.com>
> ---
>  drivers/usb/musb/musb_dsps.c | 14 +++++++++++++-
>  1 file changed, 13 insertions(+), 1 deletion(-)
> 
> diff --git a/drivers/usb/musb/musb_dsps.c b/drivers/usb/musb/musb_dsps.c
> index 65d931a..2d22683 100644
> --- a/drivers/usb/musb/musb_dsps.c
> +++ b/drivers/usb/musb/musb_dsps.c
> @@ -145,6 +145,7 @@ struct dsps_glue {
>  	struct timer_list timer;	/* otg_workaround timer */
>  	unsigned long last_timer;    /* last timer data for each instance */
>  	bool sw_babble_enabled;
> +	int otg_state_a_wait_vrise_timeout;
>  
>  	struct dsps_context context;
>  	struct debugfs_regset32 regset;
> @@ -268,9 +269,18 @@ static void otg_timer(unsigned long _musb)
>  
>  	spin_lock_irqsave(&musb->lock, flags);
>  	switch (musb->xceiv->otg->state) {
> +	case OTG_STATE_A_WAIT_VRISE:
> +		if ((glue->otg_state_a_wait_vrise_timeout)) {
> +				musb->xceiv->otg->state = OTG_STATE_A_WAIT_BCON;
> +				musb->is_active = 0;
> +			}
> +		mod_timer(&glue->timer, jiffies +
> +			  msecs_to_jiffies(OTG_TIME_A_WAIT_VRISE));

After more test on more USB drive, it seems that for some of them
OTG_TIME_A_WAIT_VRISE is too short. 200ms seems better. It is
disturbing because according to the OTG specification the maximum
is 100ms, however I am not so surprised that USB device maker don't
follow it.


> +		break;
>  	case OTG_STATE_A_WAIT_BCON:
>  		dsps_writeb(musb->mregs, MUSB_DEVCTL, 0);
>  		skip_session = 1;
> +		glue->otg_state_a_wait_vrise_timeout = 0;
>  		/* fall */
>  
>  	case OTG_STATE_A_IDLE:
> @@ -359,7 +369,9 @@ static irqreturn_t dsps_interrupt(int irq, void *hci)
>  			MUSB_HST_MODE(musb);
>  			musb->xceiv->otg->default_a = 1;
>  			musb->xceiv->otg->state = OTG_STATE_A_WAIT_VRISE;
> -			del_timer(&glue->timer);
> +			glue->otg_state_a_wait_vrise_timeout = 1;
> +			mod_timer(&glue->timer, jiffies +
> +				  msecs_to_jiffies(OTG_TIME_A_WAIT_VRISE));
>  		} else {
>  			musb->is_active = 0;
>  			MUSB_DEV_MODE(musb);
> 


-- 
Gregory Clement, Free Electrons
Kernel, drivers, real-time and embedded Linux
development, consulting, training and support.
http://free-electrons.com


From hdegoede at redhat.com  Fri Aug 21 05:33:37 2015
From: hdegoede at redhat.com (Hans de Goede)
Date: Fri, 21 Aug 2015 14:33:37 +0200
Subject: [PATCH RFT] phy: sun4i-usb: Use devm_gpiod_get_optional for
 optional GPIOs
In-Reply-To: <1440146978.29130.1.camel@ingics.com>
References: <1440146978.29130.1.camel@ingics.com>
Message-ID: <55D71AA1.9050607@redhat.com>

Hi,

On 21-08-15 10:49, Axel Lin wrote:
> Both data->id_det_gpio and data->vbus_det_gpio are optional, so use
> devm_gpiod_get_optional for them.
>
> Signed-off-by: Axel Lin <axel.lin at ingics.com>

Thanks for the patch, looks good to me:

Reviewed-by: Hans de Goede <hdegoede at redhat.com>

Regards,

Hans


> ---
>   drivers/phy/phy-sun4i-usb.c | 22 +++++++++-------------
>   1 file changed, 9 insertions(+), 13 deletions(-)
>
> diff --git a/drivers/phy/phy-sun4i-usb.c b/drivers/phy/phy-sun4i-usb.c
> index 731b395..b12964b 100644
> --- a/drivers/phy/phy-sun4i-usb.c
> +++ b/drivers/phy/phy-sun4i-usb.c
> @@ -551,19 +551,15 @@ static int sun4i_usb_phy_probe(struct platform_device *pdev)
>   	if (IS_ERR(data->base))
>   		return PTR_ERR(data->base);
>
> -	data->id_det_gpio = devm_gpiod_get(dev, "usb0_id_det", GPIOD_IN);
> -	if (IS_ERR(data->id_det_gpio)) {
> -		if (PTR_ERR(data->id_det_gpio) == -EPROBE_DEFER)
> -			return -EPROBE_DEFER;
> -		data->id_det_gpio = NULL;
> -	}
> -
> -	data->vbus_det_gpio = devm_gpiod_get(dev, "usb0_vbus_det", GPIOD_IN);
> -	if (IS_ERR(data->vbus_det_gpio)) {
> -		if (PTR_ERR(data->vbus_det_gpio) == -EPROBE_DEFER)
> -			return -EPROBE_DEFER;
> -		data->vbus_det_gpio = NULL;
> -	}
> +	data->id_det_gpio = devm_gpiod_get_optional(dev, "usb0_id_det",
> +						    GPIOD_IN);
> +	if (IS_ERR(data->id_det_gpio))
> +		return PTR_ERR(data->id_det_gpio);
> +
> +	data->vbus_det_gpio = devm_gpiod_get_optional(dev, "usb0_vbus_det",
> +						      GPIOD_IN);
> +	if (IS_ERR(data->vbus_det_gpio))
> +		return PTR_ERR(data->vbus_det_gpio);
>
>   	if (of_find_property(np, "usb0_vbus_power-supply", NULL)) {
>   		data->vbus_power_supply = devm_power_supply_get_by_phandle(dev,
>


From andrew at lunn.ch  Fri Aug 21 06:07:25 2015
From: andrew at lunn.ch (Andrew Lunn)
Date: Fri, 21 Aug 2015 15:07:25 +0200
Subject: I/O issues with writing to mtdblock devices on kirkwood
In-Reply-To: <1440159857.19360.50.camel@debian.org>
References: <1440159857.19360.50.camel@debian.org>
Message-ID: <20150821130725.GA6108@lunn.ch>

On Fri, Aug 21, 2015 at 01:24:17PM +0100, Ian Campbell wrote:
> Hi kirkwood-upstream,

Hi Ian

Thanks for forwarding the reports to us. I will try to reproduce it on my
TS-119P.

I'm travelling for the next 10 days, so it may take a while.

    Andrew


From treding at nvidia.com  Fri Aug 21 06:16:33 2015
From: treding at nvidia.com (Thierry Reding)
Date: Fri, 21 Aug 2015 15:16:33 +0200
Subject: [PATCH v3 0/14] Add Analogix Core Display Port Driver
In-Reply-To: <8384E112-E1F4-4CD3-85BF-A2A25989783F@gmail.com>
References: <1439995728-18046-1-git-send-email-ykk@rock-chips.com>
 <105A0032-83A0-4B75-AE94-258F12451670@gmail.com>
 <55D6F6F8.70504@rock-chips.com>
 <8384E112-E1F4-4CD3-85BF-A2A25989783F@gmail.com>
Message-ID: <20150821131631.GC22118@ulmo.nvidia.com>

On Fri, Aug 21, 2015 at 08:24:16PM +0900, Jingoo Han wrote:
> On 2015. 8. 21., at PM 7:01, Yakir Yang <ykk at rock-chips.com> wrote:
> > 
> > Hi Jingoo,
> > 
> >> ? 2015/8/21 16:20, Jingoo Han ??:
> >>> On 2015. 8. 19., at PM 11:48, Yakir Yang <ykk at rock-chips.com> wrote:
> >> 
> >> .....
> >> 
> >>> .../bindings/video/analogix_dp-rockchip.txt        |   83 ++
> >>> .../devicetree/bindings/video/exynos_dp.txt        |   51 +-
> >>> arch/arm/boot/dts/exynos5250-arndale.dts           |   10 +-
> >>> arch/arm/boot/dts/exynos5250-smdk5250.dts          |   10 +-
> >>> arch/arm/boot/dts/exynos5250-snow.dts              |   12 +-
> >>> arch/arm/boot/dts/exynos5250-spring.dts            |   12 +-
> >>> arch/arm/boot/dts/exynos5420-peach-pit.dts         |   12 +-
> >>> arch/arm/boot/dts/exynos5420-smdk5420.dts          |   10 +-
> >>> arch/arm/boot/dts/exynos5800-peach-pi.dts          |   12 +-
> >>> drivers/gpu/drm/bridge/Kconfig                     |    5 +
> >>> drivers/gpu/drm/bridge/Makefile                    |    1 +
> >>> drivers/gpu/drm/bridge/analogix_dp_core.c          | 1382 +++++++++++++++++++
> >>> drivers/gpu/drm/bridge/analogix_dp_core.h          |  286 ++++
> >>> drivers/gpu/drm/bridge/analogix_dp_reg.c           | 1294 ++++++++++++++++++
> >>> .../exynos_dp_reg.h => bridge/analogix_dp_reg.h}   |  270 ++--
> >>> drivers/gpu/drm/exynos/Kconfig                     |    5 +-
> >>> drivers/gpu/drm/exynos/Makefile                    |    2 +-
> >>> drivers/gpu/drm/exynos/analogix_dp-exynos.c        |  347 +++++
> >> Would you change this file name to "exynos_dp.c"?
> > 
> > Sorry, I don't think so  ;(
> > 
> > I think IP_name+Soc_name would be better in this re-use case.
> 
> So? Is there the naming rule such as "IP_name+SoC_name"?
> 
> > Beside I see
> > there are lots of driver named with this format in kernel, such as dw_hdmi & dw_mmc
> 
> Please look at other dw cases.
> For example, look at dw_pcie.
> 
> drivers/pci/host/
> pcie-designware.c
> pci-spear13xx.c
> pci-exynos.c
> 
> In this case, pci-spear13xx.c and pci-exynos.c do not use "IP_name+SoC_name", even though these are dw IPs.
> 
> Also, naming consistency is more important.
> Now, Exynos DRM files are using "exynos_drm_" prefix.
> 
> drivers/gpu/drm/exynos/
> exynos_drm_buf.c
> exynos_drm_core.c
> ....
> 
> However, "analogix_dp-exynos.c" looks very inconsistent.
> 
> If there is no strict naming rule, please use "exynos_dp.c"
> or "exynos_drm_dp.c". 

Exynos DRM maintainers get to pick their filenames, so Yakir, please
rename as Jingoo suggested.

Even if you didn't the first thing that would go into the Exynos DRM
driver tree after this is merged is a rename patch anyway.

Thierry
-------------- next part --------------
A non-text attachment was scrubbed...
Name: signature.asc
Type: application/pgp-signature
Size: 819 bytes
Desc: not available
URL: <http://lists.infradead.org/pipermail/linux-arm-kernel/attachments/20150821/542c4e0f/attachment.sig>

From maitysanchayan at gmail.com  Fri Aug 21 06:26:29 2015
From: maitysanchayan at gmail.com (Sanchayan Maity)
Date: Fri, 21 Aug 2015 18:56:29 +0530
Subject: [PATCH v4 0/3] Add support for touchscreen on Colibri VF50
Message-ID: <cover.1440162473.git.maitysanchayan@gmail.com>

Hello,

The patchset adds support for 4 wire touchscreen on Toradex Colibri
VF50 modules.

Thanks Dmitry for your feedback.

Changes since v3:
1. Add a #define for the average readings measurement.
2. Instead of configuring gpios every open, configure them on request.
3. Use a memory barrier and synchronize irq call to make sure IRQ is
not running past close.
4. Drop inline for vf50_ts_get_gpiod
5. Convert "ret" to "error"
6. Use devm_add_action to add a function for releasing iio channels and
drop remove completely.
7. Kill __set_bits()
8. Instead of requesting for pen irq as gpio and then irq, use the
interrupts property for DT and let it be handled automatically. Anyways
we never read it's state.
9. Just use IRQF_ONESHOT here, rely on the platform/OF to read and set up
the trigger properly (via "interrupts" property).

Changes since v2:
1. Fix pin multiplexing for pins in idle state. Configuration of the
pen detect pull up viz. PTA19__GPIO_9 resulted in generation of pen
irq's on a continuous basis.
2. Fix pinmux of the ADC pins as per the recommended pinmux in TRM.
3. Use a threaded irq handler instead of a irq handler plus workqueue
approach.
4. Use a low level trigger with oneshot flag specifier instead of the
previous falling edge triggered irq's. This coupled with the fix in
point 1 fixes the previous continuous spurious irq generation bug.
5. Change/fix the TS measurement logic to account for the fact that
iio_channel_read_raw might actually return an error. To be more
specific use break instead of continue and take care to close the
FET's in case of channel read error.
6. Drop the first patch "Add io-channel-cells property for ADC node"
as it has already been applied.
7. Move the iio channel get call again at the start. Having it in
the end resulted in crashes sometimes when iio was not probed and
the ts device got probed and opened earlier.

Changes since v1:
1. Fix/drop comments
2. Use an inline function for multiple gpiod_get calls in probe
3. Remove the pull up in the pinmux specified in DT for touchctrl_gpios
4. Add the io-channel-cells property before status property.
5. Add GPIOLIB as dependency in the Kconfig file

Version 3 of the patchset can be found here
https://lkml.org/lkml/2015/8/5/173

Version 2 of the patchset can be found here
https://www.mail-archive.com/linux-input at vger.kernel.org/msg18090.html

Version 1 of the patchset can be found here
https://lkml.org/lkml/2015/6/30/103

Thank you very much for the feedback till now.

Regards,
Sanchayan.

Sanchayan Maity (3):
  ARM: dts: vf500-colibri: Add device tree node for touchscreen support
  input: Add DT binding documentation for Colibri VF50 touchscreen
  touchscreen: colibri-vf50-ts: Add touchscreen support for Colibri VF50

 .../bindings/input/touchscreen/colibri-vf50-ts.txt |  36 ++
 arch/arm/boot/dts/vf500-colibri-eval-v3.dts        |   4 +
 arch/arm/boot/dts/vf500-colibri.dtsi               |  47 +++
 drivers/input/touchscreen/Kconfig                  |  12 +
 drivers/input/touchscreen/Makefile                 |   1 +
 drivers/input/touchscreen/colibri-vf50-ts.c        | 370 +++++++++++++++++++++
 6 files changed, 470 insertions(+)
 create mode 100644 Documentation/devicetree/bindings/input/touchscreen/colibri-vf50-ts.txt
 create mode 100644 drivers/input/touchscreen/colibri-vf50-ts.c

-- 
2.5.0



From maitysanchayan at gmail.com  Fri Aug 21 06:26:30 2015
From: maitysanchayan at gmail.com (Sanchayan Maity)
Date: Fri, 21 Aug 2015 18:56:30 +0530
Subject: [PATCH v4 1/3] ARM: dts: vf500-colibri: Add device tree node for
 touchscreen support
In-Reply-To: <cover.1440162473.git.maitysanchayan@gmail.com>
References: <cover.1440162473.git.maitysanchayan@gmail.com>
Message-ID: <a960c538cf419a816d73fbea7d4380ea773aa6ba.1440162473.git.maitysanchayan@gmail.com>

Add device tree node for touchscreen support on Colibri VF50. The
touchscreen functionality on VF50 uses the ADC channels of Vybrid
and some GPIOs. Also add pinctrl nodes for proper pinmux.

Signed-off-by: Sanchayan Maity <maitysanchayan at gmail.com>
---
 arch/arm/boot/dts/vf500-colibri-eval-v3.dts |  4 +++
 arch/arm/boot/dts/vf500-colibri.dtsi        | 47 +++++++++++++++++++++++++++++
 2 files changed, 51 insertions(+)

diff --git a/arch/arm/boot/dts/vf500-colibri-eval-v3.dts b/arch/arm/boot/dts/vf500-colibri-eval-v3.dts
index 7fc782c..14c0b00 100644
--- a/arch/arm/boot/dts/vf500-colibri-eval-v3.dts
+++ b/arch/arm/boot/dts/vf500-colibri-eval-v3.dts
@@ -15,3 +15,7 @@
 	model = "Toradex Colibri VF50 on Colibri Evaluation Board";
 	compatible = "toradex,vf500-colibri_vf50-on-eval", "toradex,vf500-colibri_vf50", "fsl,vf500";
 };
+
+&touchscreen {
+	status = "okay";
+};
diff --git a/arch/arm/boot/dts/vf500-colibri.dtsi b/arch/arm/boot/dts/vf500-colibri.dtsi
index cee34a3..84f091d 100644
--- a/arch/arm/boot/dts/vf500-colibri.dtsi
+++ b/arch/arm/boot/dts/vf500-colibri.dtsi
@@ -17,4 +17,51 @@
 	memory {
 		reg = <0x80000000 0x8000000>;
 	};
+
+	touchscreen: vf50-touchscreen {
+		compatible = "toradex,vf50-touchscreen";
+		io-channels = <&adc1 0>,<&adc0 0>,
+				<&adc0 1>,<&adc1 2>;
+		xp-gpios = <&gpio0 13 GPIO_ACTIVE_LOW>;
+		xm-gpios = <&gpio2 29 GPIO_ACTIVE_HIGH>;
+		yp-gpios = <&gpio0 12 GPIO_ACTIVE_LOW>;
+		ym-gpios = <&gpio0 4 GPIO_ACTIVE_HIGH>;
+		interrupt-parent = <&gpio0>;
+		interrupts = <8 IRQ_TYPE_LEVEL_LOW>;
+		pinctrl-names = "idle","default","gpios";
+		pinctrl-0 = <&pinctrl_touchctrl_idle>;
+		pinctrl-1 = <&pinctrl_touchctrl_default>;
+		pinctrl-2 = <&pinctrl_touchctrl_gpios>;
+		vf50-ts-min-pressure = <200>;
+		status = "disabled";
+	};
+};
+
+&iomuxc {
+	vf610-colibri {
+		pinctrl_touchctrl_idle: touchctrl_idle {
+			fsl,pins = <
+				VF610_PAD_PTA18__GPIO_8		0x006d
+				VF610_PAD_PTA19__GPIO_9		0x006c
+				>;
+		};
+
+		pinctrl_touchctrl_default: touchctrl_default {
+			fsl,pins = <
+				VF610_PAD_PTA18__ADC0_SE0	0x0040
+				VF610_PAD_PTA19__ADC0_SE1	0x0040
+				VF610_PAD_PTA16__ADC1_SE0	0x0040
+				VF610_PAD_PTB2__ADC1_SE2	0x0040
+				>;
+		};
+
+		pinctrl_touchctrl_gpios: touchctrl_gpios {
+			fsl,pins = <
+				VF610_PAD_PTA23__GPIO_13	0x22e9
+				VF610_PAD_PTB23__GPIO_93	0x22e9
+				VF610_PAD_PTA22__GPIO_12	0x22e9
+				VF610_PAD_PTA11__GPIO_4		0x22e9
+				>;
+		};
+	};
 };
-- 
2.5.0



From maitysanchayan at gmail.com  Fri Aug 21 06:26:31 2015
From: maitysanchayan at gmail.com (Sanchayan Maity)
Date: Fri, 21 Aug 2015 18:56:31 +0530
Subject: [PATCH v4 2/3] input: Add DT binding documentation for Colibri VF50
 touchscreen
In-Reply-To: <cover.1440162473.git.maitysanchayan@gmail.com>
References: <cover.1440162473.git.maitysanchayan@gmail.com>
Message-ID: <8446d6df4b39f0b0acdc37afd4d66dbcca4d09ba.1440162473.git.maitysanchayan@gmail.com>

This adds device tree binding documentation for the Colibri VF50
touchscreen driver.

Signed-off-by: Sanchayan Maity <maitysanchayan at gmail.com>
---
 .../bindings/input/touchscreen/colibri-vf50-ts.txt | 36 ++++++++++++++++++++++
 1 file changed, 36 insertions(+)
 create mode 100644 Documentation/devicetree/bindings/input/touchscreen/colibri-vf50-ts.txt

diff --git a/Documentation/devicetree/bindings/input/touchscreen/colibri-vf50-ts.txt b/Documentation/devicetree/bindings/input/touchscreen/colibri-vf50-ts.txt
new file mode 100644
index 0000000..e615aa9
--- /dev/null
+++ b/Documentation/devicetree/bindings/input/touchscreen/colibri-vf50-ts.txt
@@ -0,0 +1,36 @@
+* Toradex Colibri VF50 Touchscreen driver
+
+Required Properties:
+- compatible must be toradex,vf50-touchscreen
+- io-channels: adc channels being used by the Colibri VF50 module
+- xp-gpios: FET gate driver for input of X+
+- xm-gpios: FET gate driver for input of X-
+- yp-gpios: FET gate driver for input of Y+
+- ym-gpios: FET gate driver for input of Y-
+- interrupt-parent: phandle for the interrupt controller
+- interrupts: pen irq interrupt for touch detection
+- pinctrl-names: "idle", "default", "gpios"
+- pinctrl-0: pinctrl node for idle state gpio pinmux
+- pinctrl-1: pinctrl node for touch detection state pinmux
+- pinctrl-2: pinctrl node for gpios functioning as FET gate drivers
+- vf50-ts-min-pressure: pressure level at which to stop measuring X/Y values
+
+Example:
+
+	touchctrl: vf50_touchctrl {
+		compatible = "toradex,vf50-touchscreen";
+		io-channels = <&adc1 0>,<&adc0 0>,
+				<&adc0 1>,<&adc1 2>;
+		xp-gpios = <&gpio0 13 GPIO_ACTIVE_LOW>;
+		xm-gpios = <&gpio2 29 GPIO_ACTIVE_HIGH>;
+		yp-gpios = <&gpio0 12 GPIO_ACTIVE_LOW>;
+		ym-gpios = <&gpio0 4 GPIO_ACTIVE_HIGH>;
+		interrupt-parent = <&gpio0>;
+		interrupts = <8 IRQ_TYPE_LEVEL_LOW>;
+		pinctrl-names = "idle","default","gpios";
+		pinctrl-0 = <&pinctrl_touchctrl_idle>;
+		pinctrl-1 = <&pinctrl_touchctrl_default>;
+		pinctrl-2 = <&pinctrl_touchctrl_gpios>;
+		vf50-ts-min-pressure = <200>;
+		status = "disabled";
+	};
-- 
2.5.0



From maitysanchayan at gmail.com  Fri Aug 21 06:26:32 2015
From: maitysanchayan at gmail.com (Sanchayan Maity)
Date: Fri, 21 Aug 2015 18:56:32 +0530
Subject: [PATCH v4 3/3] touchscreen: colibri-vf50-ts: Add touchscreen support
 for Colibri VF50
In-Reply-To: <cover.1440162473.git.maitysanchayan@gmail.com>
References: <cover.1440162473.git.maitysanchayan@gmail.com>
Message-ID: <915c9122cfba83c6fbbc519c10ae2d101e27bc5b.1440162473.git.maitysanchayan@gmail.com>

The Colibri Vybrid VF50 module supports 4-wire touchscreens using
FETs and ADC inputs. This driver uses the IIO consumer interface
and relies on the vf610_adc driver based on the IIO framework.

Signed-off-by: Sanchayan Maity <maitysanchayan at gmail.com>
---
 drivers/input/touchscreen/Kconfig           |  12 +
 drivers/input/touchscreen/Makefile          |   1 +
 drivers/input/touchscreen/colibri-vf50-ts.c | 370 ++++++++++++++++++++++++++++
 3 files changed, 383 insertions(+)
 create mode 100644 drivers/input/touchscreen/colibri-vf50-ts.c

diff --git a/drivers/input/touchscreen/Kconfig b/drivers/input/touchscreen/Kconfig
index 80f6386..28948ca 100644
--- a/drivers/input/touchscreen/Kconfig
+++ b/drivers/input/touchscreen/Kconfig
@@ -1027,4 +1027,16 @@ config TOUCHSCREEN_ZFORCE
 	  To compile this driver as a module, choose M here: the
 	  module will be called zforce_ts.
 
+config TOUCHSCREEN_COLIBRI_VF50
+	tristate "Toradex Colibri on board touchscreen driver"
+	depends on GPIOLIB && IIO && VF610_ADC
+	help
+	  Say Y here if you have a Colibri VF50 and plan to use
+	  the on-board provided 4-wire touchscreen driver.
+
+	  If unsure, say N.
+
+	  To compile this driver as a module, choose M here: the
+	  module will be called colibri_vf50_ts.
+
 endif
diff --git a/drivers/input/touchscreen/Makefile b/drivers/input/touchscreen/Makefile
index 44deea7..93746a0 100644
--- a/drivers/input/touchscreen/Makefile
+++ b/drivers/input/touchscreen/Makefile
@@ -84,3 +84,4 @@ obj-$(CONFIG_TOUCHSCREEN_W90X900)	+= w90p910_ts.o
 obj-$(CONFIG_TOUCHSCREEN_SX8654)	+= sx8654.o
 obj-$(CONFIG_TOUCHSCREEN_TPS6507X)	+= tps6507x-ts.o
 obj-$(CONFIG_TOUCHSCREEN_ZFORCE)	+= zforce_ts.o
+obj-$(CONFIG_TOUCHSCREEN_COLIBRI_VF50)	+= colibri-vf50-ts.o
diff --git a/drivers/input/touchscreen/colibri-vf50-ts.c b/drivers/input/touchscreen/colibri-vf50-ts.c
new file mode 100644
index 0000000..0793fdc
--- /dev/null
+++ b/drivers/input/touchscreen/colibri-vf50-ts.c
@@ -0,0 +1,370 @@
+/* Copyright 2015 Toradex AG
+ *
+ * Toradex Colibri VF50 Touchscreen driver
+ *
+ * Originally authored by Stefan Agner for 3.0 kernel
+ *
+ * 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.
+ */
+
+#include <linux/delay.h>
+#include <linux/err.h>
+#include <linux/gpio.h>
+#include <linux/iio/consumer.h>
+#include <linux/iio/types.h>
+#include <linux/input.h>
+#include <linux/interrupt.h>
+#include <linux/kernel.h>
+#include <linux/module.h>
+#include <linux/pinctrl/consumer.h>
+#include <linux/platform_device.h>
+#include <linux/slab.h>
+#include <linux/types.h>
+
+#define DRIVER_NAME "colibri-vf50-ts"
+#define DRV_VERSION "1.0"
+
+#define VF_ADC_MAX ((1 << 12) - 1)
+
+#define COLI_TOUCH_MIN_DELAY_US 1000
+#define COLI_TOUCH_MAX_DELAY_US 2000
+#define COLI_TOUCH_NO_OF_AVGS	5
+
+struct vf50_touch_device {
+	struct platform_device	*pdev;
+	struct input_dev	*ts_input;
+	struct iio_channel	*channels;
+	struct gpio_desc *gpio_xp;
+	struct gpio_desc *gpio_xm;
+	struct gpio_desc *gpio_yp;
+	struct gpio_desc *gpio_ym;
+	struct gpio_desc *gpio_pen_detect;
+	int pen_irq;
+	int min_pressure;
+	bool stop_touchscreen;
+};
+
+/*
+ * Enables given plates and measures touch parameters using ADC
+ */
+static int adc_ts_measure(struct iio_channel *channel,
+		  struct gpio_desc *plate_p, struct gpio_desc *plate_m)
+{
+	int i, value = 0, val = 0;
+	int ret;
+
+	gpiod_set_value(plate_p, 1);
+	gpiod_set_value(plate_m, 1);
+
+	usleep_range(COLI_TOUCH_MIN_DELAY_US, COLI_TOUCH_MAX_DELAY_US);
+
+	for (i = 0; i < COLI_TOUCH_NO_OF_AVGS; i++) {
+		ret = iio_read_channel_raw(channel, &val);
+		if (ret < 0) {
+			value = ret;
+			goto error_iio_read;
+		}
+
+		value += val;
+	}
+
+	value /= COLI_TOUCH_NO_OF_AVGS;
+
+error_iio_read:
+	gpiod_set_value(plate_p, 0);
+	gpiod_set_value(plate_m, 0);
+
+	return value;
+}
+
+/*
+ * Enable touch detection using falling edge detection on XM
+ */
+static void vf50_ts_enable_touch_detection(struct vf50_touch_device *vf50_ts)
+{
+	/* Enable plate YM (needs to be strong GND, high active) */
+	gpiod_set_value(vf50_ts->gpio_ym, 1);
+
+	/*
+	 * Let the platform mux to idle state in order to enable
+	 * Pull-Up on GPIO
+	 */
+	pinctrl_pm_select_idle_state(&vf50_ts->pdev->dev);
+}
+
+/*
+ * ADC touch screen sampling bottom half irq handler
+ */
+static irqreturn_t vf50_ts_irq_bh(int irq, void *private)
+{
+	struct vf50_touch_device *vf50_ts = (struct vf50_touch_device *)private;
+	struct device *dev = &vf50_ts->pdev->dev;
+	int val_x, val_y, val_z1, val_z2, val_p = 0;
+	bool discard_val_on_start = true;
+
+	/* Disable the touch detection plates */
+	gpiod_set_value(vf50_ts->gpio_ym, 0);
+
+	/* Let the platform mux to default state in order to mux as ADC */
+	pinctrl_pm_select_default_state(dev);
+
+	while (!vf50_ts->stop_touchscreen) {
+		/* X-Direction */
+		val_x = adc_ts_measure(&vf50_ts->channels[0],
+				vf50_ts->gpio_xp, vf50_ts->gpio_xm);
+		if (val_x < 0)
+			break;
+
+		/* Y-Direction */
+		val_y = adc_ts_measure(&vf50_ts->channels[1],
+				vf50_ts->gpio_yp, vf50_ts->gpio_ym);
+		if (val_y < 0)
+			break;
+
+		/*
+		 * Touch pressure
+		 * Measure on XP/YM
+		 */
+		val_z1 = adc_ts_measure(&vf50_ts->channels[2],
+				vf50_ts->gpio_yp, vf50_ts->gpio_xm);
+		if (val_z1 < 0)
+			break;
+		val_z2 = adc_ts_measure(&vf50_ts->channels[3],
+				vf50_ts->gpio_yp, vf50_ts->gpio_xm);
+		if (val_z2 < 0)
+			break;
+
+		/* Validate signal (avoid calculation using noise) */
+		if (val_z1 > 64 && val_x > 64) {
+			/*
+			 * Calculate resistance between the plates
+			 * lower resistance means higher pressure
+			 */
+			int r_x = (1000 * val_x) / VF_ADC_MAX;
+
+			val_p = (r_x * val_z2) / val_z1 - r_x;
+
+		} else {
+			val_p = 2000;
+		}
+
+		val_p = 2000 - val_p;
+		dev_dbg(dev, "Measured values: x: %d, y: %d, z1: %d, z2: %d, "
+			"p: %d\n", val_x, val_y, val_z1, val_z2, val_p);
+
+		/*
+		 * If touch pressure is too low, stop measuring and reenable
+		 * touch detection
+		 */
+		if (val_p < vf50_ts->min_pressure || val_p > 2000)
+			break;
+
+		/*
+		 * The pressure may not be enough for the first x and the
+		 * second y measurement, but, the pressure is ok when the
+		 * driver is doing the third and fourth measurement. To
+		 * take care of this, we drop the first measurement always.
+		 */
+		if (discard_val_on_start) {
+			discard_val_on_start = false;
+		} else {
+			/*
+			 * Report touch position and sleep for
+			 * next measurement
+			 */
+			input_report_abs(vf50_ts->ts_input,
+					ABS_X, VF_ADC_MAX - val_x);
+			input_report_abs(vf50_ts->ts_input,
+					ABS_Y, VF_ADC_MAX - val_y);
+			input_report_abs(vf50_ts->ts_input,
+					ABS_PRESSURE, val_p);
+			input_report_key(vf50_ts->ts_input, BTN_TOUCH, 1);
+			input_sync(vf50_ts->ts_input);
+		}
+
+		msleep(10);
+	}
+
+	/* Report no more touch, reenable touch detection */
+	input_report_abs(vf50_ts->ts_input, ABS_PRESSURE, 0);
+	input_report_key(vf50_ts->ts_input, BTN_TOUCH, 0);
+	input_sync(vf50_ts->ts_input);
+
+	vf50_ts_enable_touch_detection(vf50_ts);
+
+	/* Wait for the pull-up to be stable on high */
+	msleep(10);
+
+	return IRQ_HANDLED;
+}
+
+static int vf50_ts_open(struct input_dev *dev_input)
+{
+	struct vf50_touch_device *touchdev = input_get_drvdata(dev_input);
+	struct device *dev = &touchdev->pdev->dev;
+
+	dev_dbg(dev, "Input device %s opened, starting touch detection\n",
+			dev_input->name);
+
+	touchdev->stop_touchscreen = false;
+
+	/* Mux detection before request IRQ, wait for pull-up to settle */
+	vf50_ts_enable_touch_detection(touchdev);
+	msleep(10);
+
+	return 0;
+}
+
+static void vf50_ts_close(struct input_dev *dev_input)
+{
+	struct vf50_touch_device *touchdev = input_get_drvdata(dev_input);
+	struct device *dev = &touchdev->pdev->dev;
+
+	touchdev->stop_touchscreen = true;
+
+	/* Make sure IRQ is not running past close */
+	mb();
+	synchronize_irq(touchdev->pen_irq);
+
+	dev_dbg(dev, "Input device %s closed, disable touch detection\n",
+		dev_input->name);
+}
+
+static int vf50_ts_get_gpiod(struct device *dev,
+	struct gpio_desc **gpio_d, const char *con_id, enum gpiod_flags flags)
+{
+	int error;
+
+	*gpio_d = devm_gpiod_get(dev, con_id, flags);
+	if (IS_ERR(*gpio_d)) {
+		error = PTR_ERR(*gpio_d);
+		dev_err(dev, "Could not get gpio_%s %d\n", con_id, error);
+		return error;
+	}
+
+	return 0;
+}
+
+static void vf50_ts_channel_release(void *data)
+{
+	struct vf50_touch_device *touchdev = data;
+
+	iio_channel_release_all(touchdev->channels);
+}
+
+static int vf50_ts_probe(struct platform_device *pdev)
+{
+	struct input_dev *input;
+	struct iio_channel *channels;
+	struct device *dev = &pdev->dev;
+	struct vf50_touch_device *touchdev;
+	int error;
+
+	channels = iio_channel_get_all(dev);
+	if (IS_ERR(channels))
+		return PTR_ERR(channels);
+
+	touchdev = devm_kzalloc(dev, sizeof(*touchdev), GFP_KERNEL);
+	if (!touchdev) {
+		error = -ENOMEM;
+		return error;
+	}
+
+	error = of_property_read_u32(dev->of_node, "vf50-ts-min-pressure",
+				 &touchdev->min_pressure);
+	if (error)
+		return error;
+
+	error = devm_add_action(dev, vf50_ts_channel_release, channels);
+	if (error) {
+		dev_err(dev, "Failed to register iio channel release action");
+		return error;
+	}
+
+	input = devm_input_allocate_device(dev);
+	if (!input) {
+		dev_err(dev, "Failed to allocate TS input device\n");
+		error = -ENOMEM;
+		return error;
+	}
+
+	platform_set_drvdata(pdev, touchdev);
+
+	touchdev->pdev = pdev;
+	touchdev->channels = channels;
+
+	input->name = DRIVER_NAME;
+	input->id.bustype = BUS_HOST;
+	input->dev.parent = dev;
+	input->open = vf50_ts_open;
+	input->close = vf50_ts_close;
+
+	input_set_capability(input, EV_KEY, BTN_TOUCH);
+	input_set_abs_params(input, ABS_X, 0, VF_ADC_MAX, 0, 0);
+	input_set_abs_params(input, ABS_Y, 0, VF_ADC_MAX, 0, 0);
+	input_set_abs_params(input, ABS_PRESSURE, 0, VF_ADC_MAX, 0, 0);
+
+	touchdev->ts_input = input;
+	input_set_drvdata(input, touchdev);
+	error = input_register_device(input);
+	if (error) {
+		dev_err(dev, "Failed to register input device\n");
+		return error;
+	}
+
+	error = vf50_ts_get_gpiod(dev, &touchdev->gpio_xp,
+				"xp", GPIOD_OUT_LOW);
+	if (error)
+		return error;
+
+	error = vf50_ts_get_gpiod(dev, &touchdev->gpio_xm,
+				"xm", GPIOD_OUT_LOW);
+	if (error)
+		return error;
+
+	error = vf50_ts_get_gpiod(dev, &touchdev->gpio_yp,
+				"yp", GPIOD_OUT_LOW);
+	if (error)
+		return error;
+
+	error = vf50_ts_get_gpiod(dev, &touchdev->gpio_ym,
+				"ym", GPIOD_OUT_LOW);
+	if (error)
+		return error;
+
+	touchdev->pen_irq = platform_get_irq(pdev, 0);
+	if (touchdev->pen_irq < 0)
+		return touchdev->pen_irq;
+
+	error = devm_request_threaded_irq(dev, touchdev->pen_irq, NULL,
+			vf50_ts_irq_bh, IRQF_ONESHOT,
+			"vf50 touch", touchdev);
+	if (error < 0)
+		return error;
+
+	return 0;
+}
+
+static const struct of_device_id vf50_touch_of_match[] = {
+	{ .compatible = "toradex,vf50-touchscreen", },
+	{ }
+};
+MODULE_DEVICE_TABLE(of, vf50_touch_of_match);
+
+static struct platform_driver vf50_touch_driver = {
+	.driver = {
+		.name = "toradex,vf50_touchctrl",
+		.of_match_table = vf50_touch_of_match,
+	},
+	.probe = vf50_ts_probe,
+};
+
+module_platform_driver(vf50_touch_driver);
+
+MODULE_AUTHOR("Sanchayan Maity");
+MODULE_DESCRIPTION("Colibri VF50 Touchscreen driver");
+MODULE_LICENSE("GPL v2");
+MODULE_VERSION(DRV_VERSION);
-- 
2.5.0



From rmk+kernel at arm.linux.org.uk  Fri Aug 21 06:31:15 2015
From: rmk+kernel at arm.linux.org.uk (Russell King)
Date: Fri, 21 Aug 2015 14:31:15 +0100
Subject: [PATCH 1/9] ARM: domains: switch to keeping domain value in register
In-Reply-To: <20150821133043.GV7557@n2100.arm.linux.org.uk>
References: <20150821133043.GV7557@n2100.arm.linux.org.uk>
Message-ID: <E1ZSmPb-0002yl-AY@rmk-PC.arm.linux.org.uk>

Rather than modifying both the domain access control register and our
per-thread copy, modify only the domain access control register, and
use the per-thread copy to save and restore the register over context
switches.  We can also avoid the explicit initialisation of the
init thread_info structure.

This allows us to avoid needing to gain access to the thread information
at the uaccess control sites.

Signed-off-by: Russell King <rmk+kernel at arm.linux.org.uk>
---
 arch/arm/include/asm/domain.h      | 20 +++++++++++++++-----
 arch/arm/include/asm/thread_info.h |  3 ---
 arch/arm/kernel/entry-armv.S       |  2 ++
 arch/arm/kernel/process.c          | 13 ++++++++++---
 4 files changed, 27 insertions(+), 11 deletions(-)

diff --git a/arch/arm/include/asm/domain.h b/arch/arm/include/asm/domain.h
index 6ddbe446425e..7f2941905714 100644
--- a/arch/arm/include/asm/domain.h
+++ b/arch/arm/include/asm/domain.h
@@ -59,6 +59,17 @@
 
 #ifndef __ASSEMBLY__
 
+static inline unsigned int get_domain(void)
+{
+	unsigned int domain;
+
+	asm(
+	"mrc	p15, 0, %0, c3, c0	@ get domain"
+	 : "=r" (domain));
+
+	return domain;
+}
+
 #ifdef CONFIG_CPU_USE_DOMAINS
 static inline void set_domain(unsigned val)
 {
@@ -70,11 +81,10 @@ static inline void set_domain(unsigned val)
 
 #define modify_domain(dom,type)					\
 	do {							\
-	struct thread_info *thread = current_thread_info();	\
-	unsigned int domain = thread->cpu_domain;		\
-	domain &= ~domain_val(dom, DOMAIN_MANAGER);		\
-	thread->cpu_domain = domain | domain_val(dom, type);	\
-	set_domain(thread->cpu_domain);				\
+		unsigned int domain = get_domain();		\
+		domain &= ~domain_val(dom, DOMAIN_MANAGER);	\
+		domain = domain | domain_val(dom, type);	\
+		set_domain(domain);				\
 	} while (0)
 
 #else
diff --git a/arch/arm/include/asm/thread_info.h b/arch/arm/include/asm/thread_info.h
index bd32eded3e50..0a0aec410d8c 100644
--- a/arch/arm/include/asm/thread_info.h
+++ b/arch/arm/include/asm/thread_info.h
@@ -74,9 +74,6 @@ struct thread_info {
 	.flags		= 0,						\
 	.preempt_count	= INIT_PREEMPT_COUNT,				\
 	.addr_limit	= KERNEL_DS,					\
-	.cpu_domain	= domain_val(DOMAIN_USER, DOMAIN_MANAGER) |	\
-			  domain_val(DOMAIN_KERNEL, DOMAIN_MANAGER) |	\
-			  domain_val(DOMAIN_IO, DOMAIN_CLIENT),		\
 }
 
 #define init_thread_info	(init_thread_union.thread_info)
diff --git a/arch/arm/kernel/entry-armv.S b/arch/arm/kernel/entry-armv.S
index 7dac3086e361..d19adcf6c580 100644
--- a/arch/arm/kernel/entry-armv.S
+++ b/arch/arm/kernel/entry-armv.S
@@ -770,6 +770,8 @@ ENTRY(__switch_to)
 	ldr	r4, [r2, #TI_TP_VALUE]
 	ldr	r5, [r2, #TI_TP_VALUE + 4]
 #ifdef CONFIG_CPU_USE_DOMAINS
+	mrc	p15, 0, r6, c3, c0, 0		@ Get domain register
+	str	r6, [r1, #TI_CPU_DOMAIN]	@ Save old domain register
 	ldr	r6, [r2, #TI_CPU_DOMAIN]
 #endif
 	switch_tls r1, r4, r5, r3, r7
diff --git a/arch/arm/kernel/process.c b/arch/arm/kernel/process.c
index f192a2a41719..e722f9b3c9b1 100644
--- a/arch/arm/kernel/process.c
+++ b/arch/arm/kernel/process.c
@@ -146,10 +146,9 @@ void __show_regs(struct pt_regs *regs)
 		buf[0] = '\0';
 #ifdef CONFIG_CPU_CP15_MMU
 		{
-			unsigned int transbase, dac;
+			unsigned int transbase, dac = get_domain();
 			asm("mrc p15, 0, %0, c2, c0\n\t"
-			    "mrc p15, 0, %1, c3, c0\n"
-			    : "=r" (transbase), "=r" (dac));
+			    : "=r" (transbase));
 			snprintf(buf, sizeof(buf), "  Table: %08x  DAC: %08x",
 			  	transbase, dac);
 		}
@@ -210,6 +209,14 @@ copy_thread(unsigned long clone_flags, unsigned long stack_start,
 
 	memset(&thread->cpu_context, 0, sizeof(struct cpu_context_save));
 
+	/*
+	 * Copy the initial value of the domain access control register
+	 * from the current thread: thread->addr_limit will have been
+	 * copied from the current thread via setup_thread_stack() in
+	 * kernel/fork.c
+	 */
+	thread->cpu_domain = get_domain();
+
 	if (likely(!(p->flags & PF_KTHREAD))) {
 		*childregs = *current_pt_regs();
 		childregs->ARM_r0 = 0;
-- 
2.1.0



From rmk+kernel at arm.linux.org.uk  Fri Aug 21 06:31:20 2015
From: rmk+kernel at arm.linux.org.uk (Russell King)
Date: Fri, 21 Aug 2015 14:31:20 +0100
Subject: [PATCH 2/9] ARM: domains: provide domain_mask()
In-Reply-To: <20150821133043.GV7557@n2100.arm.linux.org.uk>
References: <20150821133043.GV7557@n2100.arm.linux.org.uk>
Message-ID: <E1ZSmPg-0002yr-Gl@rmk-PC.arm.linux.org.uk>

Provide a macro to generate the mask for a domain, rather than using
domain_val(, DOMAIN_MANAGER) which won't work when CPU_USE_DOMAINS
is turned off.

Signed-off-by: Russell King <rmk+kernel at arm.linux.org.uk>
---
 arch/arm/include/asm/domain.h | 5 +++--
 1 file changed, 3 insertions(+), 2 deletions(-)

diff --git a/arch/arm/include/asm/domain.h b/arch/arm/include/asm/domain.h
index 7f2941905714..045b9b453bcd 100644
--- a/arch/arm/include/asm/domain.h
+++ b/arch/arm/include/asm/domain.h
@@ -55,7 +55,8 @@
 #define DOMAIN_MANAGER	1
 #endif
 
-#define domain_val(dom,type)	((type) << (2*(dom)))
+#define domain_mask(dom)	((3) << (2 * (dom)))
+#define domain_val(dom,type)	((type) << (2 * (dom)))
 
 #ifndef __ASSEMBLY__
 
@@ -82,7 +83,7 @@ static inline void set_domain(unsigned val)
 #define modify_domain(dom,type)					\
 	do {							\
 		unsigned int domain = get_domain();		\
-		domain &= ~domain_val(dom, DOMAIN_MANAGER);	\
+		domain &= ~domain_mask(dom);			\
 		domain = domain | domain_val(dom, type);	\
 		set_domain(domain);				\
 	} while (0)
-- 
2.1.0



From rmk+kernel at arm.linux.org.uk  Fri Aug 21 06:31:25 2015
From: rmk+kernel at arm.linux.org.uk (Russell King)
Date: Fri, 21 Aug 2015 14:31:25 +0100
Subject: [PATCH 3/9] ARM: domains: move initial domain setting value to
 asm/domains.h
In-Reply-To: <20150821133043.GV7557@n2100.arm.linux.org.uk>
References: <20150821133043.GV7557@n2100.arm.linux.org.uk>
Message-ID: <E1ZSmPl-0002yx-MO@rmk-PC.arm.linux.org.uk>

Signed-off-by: Russell King <rmk+kernel at arm.linux.org.uk>
---
 arch/arm/include/asm/domain.h | 6 ++++++
 arch/arm/kernel/head.S        | 5 +----
 2 files changed, 7 insertions(+), 4 deletions(-)

diff --git a/arch/arm/include/asm/domain.h b/arch/arm/include/asm/domain.h
index 045b9b453bcd..4218f88e8f7e 100644
--- a/arch/arm/include/asm/domain.h
+++ b/arch/arm/include/asm/domain.h
@@ -58,6 +58,12 @@
 #define domain_mask(dom)	((3) << (2 * (dom)))
 #define domain_val(dom,type)	((type) << (2 * (dom)))
 
+#define DACR_INIT \
+	(domain_val(DOMAIN_USER, DOMAIN_MANAGER) | \
+	 domain_val(DOMAIN_KERNEL, DOMAIN_MANAGER) | \
+	 domain_val(DOMAIN_TABLE, DOMAIN_MANAGER) | \
+	 domain_val(DOMAIN_IO, DOMAIN_CLIENT))
+
 #ifndef __ASSEMBLY__
 
 static inline unsigned int get_domain(void)
diff --git a/arch/arm/kernel/head.S b/arch/arm/kernel/head.S
index bd755d97e459..d56e5e9a9e1e 100644
--- a/arch/arm/kernel/head.S
+++ b/arch/arm/kernel/head.S
@@ -461,10 +461,7 @@ __enable_mmu:
 #ifdef CONFIG_ARM_LPAE
 	mcrr	p15, 0, r4, r5, c2		@ load TTBR0
 #else
-	mov	r5, #(domain_val(DOMAIN_USER, DOMAIN_MANAGER) | \
-		      domain_val(DOMAIN_KERNEL, DOMAIN_MANAGER) | \
-		      domain_val(DOMAIN_TABLE, DOMAIN_MANAGER) | \
-		      domain_val(DOMAIN_IO, DOMAIN_CLIENT))
+	mov	r5, #DACR_INIT
 	mcr	p15, 0, r5, c3, c0, 0		@ load domain access register
 	mcr	p15, 0, r4, c2, c0, 0		@ load page table pointer
 #endif
-- 
2.1.0



From rmk+kernel at arm.linux.org.uk  Fri Aug 21 06:31:30 2015
From: rmk+kernel at arm.linux.org.uk (Russell King)
Date: Fri, 21 Aug 2015 14:31:30 +0100
Subject: [PATCH 4/9] ARM: domains: get rid of manager mode for user domain
In-Reply-To: <20150821133043.GV7557@n2100.arm.linux.org.uk>
References: <20150821133043.GV7557@n2100.arm.linux.org.uk>
Message-ID: <E1ZSmPq-0002z5-QI@rmk-PC.arm.linux.org.uk>

Since we switched to early trap initialisation in 94e5a85b3be0
("ARM: earlier initialization of vectors page") we haven't been writing
directly to the vectors page, and so there's no need for this domain
to be in manager mode.  Switch it to client mode.

Signed-off-by: Russell King <rmk+kernel at arm.linux.org.uk>
---
 arch/arm/include/asm/domain.h | 2 +-
 arch/arm/kernel/traps.c       | 1 -
 2 files changed, 1 insertion(+), 2 deletions(-)

diff --git a/arch/arm/include/asm/domain.h b/arch/arm/include/asm/domain.h
index 4218f88e8f7e..08b601e69ddc 100644
--- a/arch/arm/include/asm/domain.h
+++ b/arch/arm/include/asm/domain.h
@@ -59,7 +59,7 @@
 #define domain_val(dom,type)	((type) << (2 * (dom)))
 
 #define DACR_INIT \
-	(domain_val(DOMAIN_USER, DOMAIN_MANAGER) | \
+	(domain_val(DOMAIN_USER, DOMAIN_CLIENT) | \
 	 domain_val(DOMAIN_KERNEL, DOMAIN_MANAGER) | \
 	 domain_val(DOMAIN_TABLE, DOMAIN_MANAGER) | \
 	 domain_val(DOMAIN_IO, DOMAIN_CLIENT))
diff --git a/arch/arm/kernel/traps.c b/arch/arm/kernel/traps.c
index d358226236f2..969f9d9e665f 100644
--- a/arch/arm/kernel/traps.c
+++ b/arch/arm/kernel/traps.c
@@ -870,7 +870,6 @@ void __init early_trap_init(void *vectors_base)
 	kuser_init(vectors_base);
 
 	flush_icache_range(vectors, vectors + PAGE_SIZE * 2);
-	modify_domain(DOMAIN_USER, DOMAIN_CLIENT);
 #else /* ifndef CONFIG_CPU_V7M */
 	/*
 	 * on V7-M there is no need to copy the vector table to a dedicated
-- 
2.1.0



From rmk+kernel at arm.linux.org.uk  Fri Aug 21 06:31:35 2015
From: rmk+kernel at arm.linux.org.uk (Russell King)
Date: Fri, 21 Aug 2015 14:31:35 +0100
Subject: [PATCH 5/9] ARM: domains: keep vectors in separate domain
In-Reply-To: <20150821133043.GV7557@n2100.arm.linux.org.uk>
References: <20150821133043.GV7557@n2100.arm.linux.org.uk>
Message-ID: <E1ZSmPv-0002zB-Uf@rmk-PC.arm.linux.org.uk>

Keep the machine vectors in its own domain to avoid software based
user access control from making the vector code inaccessible, and
thereby deadlocking the machine.

Signed-off-by: Russell King <rmk+kernel at arm.linux.org.uk>
---
 arch/arm/include/asm/domain.h               |  4 +++-
 arch/arm/include/asm/pgtable-2level-hwdef.h |  1 +
 arch/arm/mm/mmu.c                           |  4 ++--
 arch/arm/mm/pgd.c                           | 10 ++++++++++
 4 files changed, 16 insertions(+), 3 deletions(-)

diff --git a/arch/arm/include/asm/domain.h b/arch/arm/include/asm/domain.h
index 08b601e69ddc..396a12e486fe 100644
--- a/arch/arm/include/asm/domain.h
+++ b/arch/arm/include/asm/domain.h
@@ -43,6 +43,7 @@
 #define DOMAIN_USER	1
 #define DOMAIN_IO	0
 #endif
+#define DOMAIN_VECTORS	3
 
 /*
  * Domain types
@@ -62,7 +63,8 @@
 	(domain_val(DOMAIN_USER, DOMAIN_CLIENT) | \
 	 domain_val(DOMAIN_KERNEL, DOMAIN_MANAGER) | \
 	 domain_val(DOMAIN_TABLE, DOMAIN_MANAGER) | \
-	 domain_val(DOMAIN_IO, DOMAIN_CLIENT))
+	 domain_val(DOMAIN_IO, DOMAIN_CLIENT) | \
+	 domain_val(DOMAIN_VECTORS, DOMAIN_CLIENT))
 
 #ifndef __ASSEMBLY__
 
diff --git a/arch/arm/include/asm/pgtable-2level-hwdef.h b/arch/arm/include/asm/pgtable-2level-hwdef.h
index 5e68278e953e..d0131ee6f6af 100644
--- a/arch/arm/include/asm/pgtable-2level-hwdef.h
+++ b/arch/arm/include/asm/pgtable-2level-hwdef.h
@@ -23,6 +23,7 @@
 #define PMD_PXNTABLE		(_AT(pmdval_t, 1) << 2)     /* v7 */
 #define PMD_BIT4		(_AT(pmdval_t, 1) << 4)
 #define PMD_DOMAIN(x)		(_AT(pmdval_t, (x)) << 5)
+#define PMD_DOMAIN_MASK		PMD_DOMAIN(0x0f)
 #define PMD_PROTECTION		(_AT(pmdval_t, 1) << 9)		/* v5 */
 /*
  *   - section
diff --git a/arch/arm/mm/mmu.c b/arch/arm/mm/mmu.c
index 6ca7d9aa896f..a016de248034 100644
--- a/arch/arm/mm/mmu.c
+++ b/arch/arm/mm/mmu.c
@@ -291,13 +291,13 @@ static struct mem_type mem_types[] = {
 		.prot_pte  = L_PTE_PRESENT | L_PTE_YOUNG | L_PTE_DIRTY |
 				L_PTE_RDONLY,
 		.prot_l1   = PMD_TYPE_TABLE,
-		.domain    = DOMAIN_USER,
+		.domain    = DOMAIN_VECTORS,
 	},
 	[MT_HIGH_VECTORS] = {
 		.prot_pte  = L_PTE_PRESENT | L_PTE_YOUNG | L_PTE_DIRTY |
 				L_PTE_USER | L_PTE_RDONLY,
 		.prot_l1   = PMD_TYPE_TABLE,
-		.domain    = DOMAIN_USER,
+		.domain    = DOMAIN_VECTORS,
 	},
 	[MT_MEMORY_RWX] = {
 		.prot_pte  = L_PTE_PRESENT | L_PTE_YOUNG | L_PTE_DIRTY,
diff --git a/arch/arm/mm/pgd.c b/arch/arm/mm/pgd.c
index a3681f11dd9f..e683db1b90a3 100644
--- a/arch/arm/mm/pgd.c
+++ b/arch/arm/mm/pgd.c
@@ -84,6 +84,16 @@ pgd_t *pgd_alloc(struct mm_struct *mm)
 		if (!new_pte)
 			goto no_pte;
 
+#ifndef CONFIG_ARM_LPAE
+		/*
+		 * Modify the PTE pointer to have the correct domain.  This
+		 * needs to be the vectors domain to avoid the low vectors
+		 * being unmapped.
+		 */
+		pmd_val(*new_pmd) &= ~PMD_DOMAIN_MASK;
+		pmd_val(*new_pmd) |= PMD_DOMAIN(DOMAIN_VECTORS);
+#endif
+
 		init_pud = pud_offset(init_pgd, 0);
 		init_pmd = pmd_offset(init_pud, 0);
 		init_pte = pte_offset_map(init_pmd, 0);
-- 
2.1.0



From rmk+kernel at arm.linux.org.uk  Fri Aug 21 06:31:41 2015
From: rmk+kernel at arm.linux.org.uk (Russell King)
Date: Fri, 21 Aug 2015 14:31:41 +0100
Subject: [PATCH 6/9] ARM: domains: remove DOMAIN_TABLE
In-Reply-To: <20150821133043.GV7557@n2100.arm.linux.org.uk>
References: <20150821133043.GV7557@n2100.arm.linux.org.uk>
Message-ID: <E1ZSmQ1-0002zH-1k@rmk-PC.arm.linux.org.uk>

DOMAIN_TABLE is not used; in any case, it aliases to the kernel domain.
Remove this definition.

Signed-off-by: Russell King <rmk+kernel at arm.linux.org.uk>
---
 arch/arm/include/asm/domain.h | 3 ---
 1 file changed, 3 deletions(-)

diff --git a/arch/arm/include/asm/domain.h b/arch/arm/include/asm/domain.h
index 396a12e486fe..2be929549938 100644
--- a/arch/arm/include/asm/domain.h
+++ b/arch/arm/include/asm/domain.h
@@ -34,12 +34,10 @@
  */
 #ifndef CONFIG_IO_36
 #define DOMAIN_KERNEL	0
-#define DOMAIN_TABLE	0
 #define DOMAIN_USER	1
 #define DOMAIN_IO	2
 #else
 #define DOMAIN_KERNEL	2
-#define DOMAIN_TABLE	2
 #define DOMAIN_USER	1
 #define DOMAIN_IO	0
 #endif
@@ -62,7 +60,6 @@
 #define DACR_INIT \
 	(domain_val(DOMAIN_USER, DOMAIN_CLIENT) | \
 	 domain_val(DOMAIN_KERNEL, DOMAIN_MANAGER) | \
-	 domain_val(DOMAIN_TABLE, DOMAIN_MANAGER) | \
 	 domain_val(DOMAIN_IO, DOMAIN_CLIENT) | \
 	 domain_val(DOMAIN_VECTORS, DOMAIN_CLIENT))
 
-- 
2.1.0



From rmk+kernel at arm.linux.org.uk  Fri Aug 21 06:31:46 2015
From: rmk+kernel at arm.linux.org.uk (Russell King)
Date: Fri, 21 Aug 2015 14:31:46 +0100
Subject: [PATCH 7/9] ARM: uaccess: provide uaccess_save_and_enable() and
 uaccess_restore()
In-Reply-To: <20150821133043.GV7557@n2100.arm.linux.org.uk>
References: <20150821133043.GV7557@n2100.arm.linux.org.uk>
Message-ID: <E1ZSmQ6-0002zN-6T@rmk-PC.arm.linux.org.uk>

Provide uaccess_save_and_enable() and uaccess_restore() to permit
control of userspace visibility to the kernel, and hook these into
the appropriate places in the kernel where we need to access
userspace.

Signed-off-by: Russell King <rmk+kernel at arm.linux.org.uk>
---
 arch/arm/include/asm/futex.h       | 19 ++++++++--
 arch/arm/include/asm/uaccess.h     | 71 +++++++++++++++++++++++++++++++++++---
 arch/arm/kernel/armksyms.c         |  6 ++--
 arch/arm/lib/clear_user.S          |  6 ++--
 arch/arm/lib/copy_from_user.S      |  6 ++--
 arch/arm/lib/copy_to_user.S        |  6 ++--
 arch/arm/lib/uaccess_with_memcpy.c |  4 +--
 7 files changed, 97 insertions(+), 21 deletions(-)

diff --git a/arch/arm/include/asm/futex.h b/arch/arm/include/asm/futex.h
index 5eed82809d82..6795368ad023 100644
--- a/arch/arm/include/asm/futex.h
+++ b/arch/arm/include/asm/futex.h
@@ -22,8 +22,11 @@
 #ifdef CONFIG_SMP
 
 #define __futex_atomic_op(insn, ret, oldval, tmp, uaddr, oparg)	\
+({								\
+	unsigned int __ua_flags;				\
 	smp_mb();						\
 	prefetchw(uaddr);					\
+	__ua_flags = uaccess_save_and_enable();			\
 	__asm__ __volatile__(					\
 	"1:	ldrex	%1, [%3]\n"				\
 	"	" insn "\n"					\
@@ -34,12 +37,15 @@
 	__futex_atomic_ex_table("%5")				\
 	: "=&r" (ret), "=&r" (oldval), "=&r" (tmp)		\
 	: "r" (uaddr), "r" (oparg), "Ir" (-EFAULT)		\
-	: "cc", "memory")
+	: "cc", "memory");					\
+	uaccess_restore(__ua_flags);				\
+})
 
 static inline int
 futex_atomic_cmpxchg_inatomic(u32 *uval, u32 __user *uaddr,
 			      u32 oldval, u32 newval)
 {
+	unsigned int __ua_flags;
 	int ret;
 	u32 val;
 
@@ -49,6 +55,7 @@ futex_atomic_cmpxchg_inatomic(u32 *uval, u32 __user *uaddr,
 	smp_mb();
 	/* Prefetching cannot fault */
 	prefetchw(uaddr);
+	__ua_flags = uaccess_save_and_enable();
 	__asm__ __volatile__("@futex_atomic_cmpxchg_inatomic\n"
 	"1:	ldrex	%1, [%4]\n"
 	"	teq	%1, %2\n"
@@ -61,6 +68,7 @@ futex_atomic_cmpxchg_inatomic(u32 *uval, u32 __user *uaddr,
 	: "=&r" (ret), "=&r" (val)
 	: "r" (oldval), "r" (newval), "r" (uaddr), "Ir" (-EFAULT)
 	: "cc", "memory");
+	uaccess_restore(__ua_flags);
 	smp_mb();
 
 	*uval = val;
@@ -73,6 +81,8 @@ futex_atomic_cmpxchg_inatomic(u32 *uval, u32 __user *uaddr,
 #include <asm/domain.h>
 
 #define __futex_atomic_op(insn, ret, oldval, tmp, uaddr, oparg)	\
+({								\
+	unsigned int __ua_flags = uaccess_save_and_enable();	\
 	__asm__ __volatile__(					\
 	"1:	" TUSER(ldr) "	%1, [%3]\n"			\
 	"	" insn "\n"					\
@@ -81,12 +91,15 @@ futex_atomic_cmpxchg_inatomic(u32 *uval, u32 __user *uaddr,
 	__futex_atomic_ex_table("%5")				\
 	: "=&r" (ret), "=&r" (oldval), "=&r" (tmp)		\
 	: "r" (uaddr), "r" (oparg), "Ir" (-EFAULT)		\
-	: "cc", "memory")
+	: "cc", "memory");					\
+	uaccess_restore(__ua_flags);				\
+})
 
 static inline int
 futex_atomic_cmpxchg_inatomic(u32 *uval, u32 __user *uaddr,
 			      u32 oldval, u32 newval)
 {
+	unsigned int __ua_flags;
 	int ret = 0;
 	u32 val;
 
@@ -94,6 +107,7 @@ futex_atomic_cmpxchg_inatomic(u32 *uval, u32 __user *uaddr,
 		return -EFAULT;
 
 	preempt_disable();
+	__ua_flags = uaccess_save_and_enable();
 	__asm__ __volatile__("@futex_atomic_cmpxchg_inatomic\n"
 	"1:	" TUSER(ldr) "	%1, [%4]\n"
 	"	teq	%1, %2\n"
@@ -103,6 +117,7 @@ futex_atomic_cmpxchg_inatomic(u32 *uval, u32 __user *uaddr,
 	: "+r" (ret), "=&r" (val)
 	: "r" (oldval), "r" (newval), "r" (uaddr), "Ir" (-EFAULT)
 	: "cc", "memory");
+	uaccess_restore(__ua_flags);
 
 	*uval = val;
 	preempt_enable();
diff --git a/arch/arm/include/asm/uaccess.h b/arch/arm/include/asm/uaccess.h
index 74b17d09ef7a..4ae10967a8ba 100644
--- a/arch/arm/include/asm/uaccess.h
+++ b/arch/arm/include/asm/uaccess.h
@@ -94,6 +94,21 @@ static inline void set_fs(mm_segment_t fs)
 	flag; })
 
 /*
+ * These two functions allow hooking accesses to userspace to increase
+ * system integrity by ensuring that the kernel can not inadvertantly
+ * perform such accesses (eg, via list poison values) which could then
+ * be exploited for priviledge escalation.
+ */
+static inline unsigned int uaccess_save_and_enable(void)
+{
+	return 0;
+}
+
+static inline void uaccess_restore(unsigned int flags)
+{
+}
+
+/*
  * Single-value transfer routines.  They automatically use the right
  * size if we just have the right pointer type.  Note that the functions
  * which read from user space (*get_*) need to take care not to leak
@@ -165,6 +180,7 @@ extern int __get_user_64t_4(void *);
 		register typeof(x) __r2 asm("r2");			\
 		register unsigned long __l asm("r1") = __limit;		\
 		register int __e asm("r0");				\
+		unsigned int __ua_flags = uaccess_save_and_enable();	\
 		switch (sizeof(*(__p))) {				\
 		case 1:							\
 			if (sizeof((x)) >= 8)				\
@@ -192,6 +208,7 @@ extern int __get_user_64t_4(void *);
 			break;						\
 		default: __e = __get_user_bad(); break;			\
 		}							\
+		uaccess_restore(__ua_flags);				\
 		x = (typeof(*(p))) __r2;				\
 		__e;							\
 	})
@@ -224,6 +241,7 @@ extern int __put_user_8(void *, unsigned long long);
 		register const typeof(*(p)) __user *__p asm("r0") = __tmp_p; \
 		register unsigned long __l asm("r1") = __limit;		\
 		register int __e asm("r0");				\
+		unsigned int __ua_flags = uaccess_save_and_enable();	\
 		switch (sizeof(*(__p))) {				\
 		case 1:							\
 			__put_user_x(__r2, __p, __e, __l, 1);		\
@@ -239,6 +257,7 @@ extern int __put_user_8(void *, unsigned long long);
 			break;						\
 		default: __e = __put_user_bad(); break;			\
 		}							\
+		uaccess_restore(__ua_flags);				\
 		__e;							\
 	})
 
@@ -300,14 +319,17 @@ static inline void set_fs(mm_segment_t fs)
 do {									\
 	unsigned long __gu_addr = (unsigned long)(ptr);			\
 	unsigned long __gu_val;						\
+	unsigned int __ua_flags;					\
 	__chk_user_ptr(ptr);						\
 	might_fault();							\
+	__ua_flags = uaccess_save_and_enable();				\
 	switch (sizeof(*(ptr))) {					\
 	case 1:	__get_user_asm_byte(__gu_val, __gu_addr, err);	break;	\
 	case 2:	__get_user_asm_half(__gu_val, __gu_addr, err);	break;	\
 	case 4:	__get_user_asm_word(__gu_val, __gu_addr, err);	break;	\
 	default: (__gu_val) = __get_user_bad();				\
 	}								\
+	uaccess_restore(__ua_flags);					\
 	(x) = (__typeof__(*(ptr)))__gu_val;				\
 } while (0)
 
@@ -381,9 +403,11 @@ do {									\
 #define __put_user_err(x, ptr, err)					\
 do {									\
 	unsigned long __pu_addr = (unsigned long)(ptr);			\
+	unsigned int __ua_flags;					\
 	__typeof__(*(ptr)) __pu_val = (x);				\
 	__chk_user_ptr(ptr);						\
 	might_fault();							\
+	__ua_flags = uaccess_save_and_enable();				\
 	switch (sizeof(*(ptr))) {					\
 	case 1: __put_user_asm_byte(__pu_val, __pu_addr, err);	break;	\
 	case 2: __put_user_asm_half(__pu_val, __pu_addr, err);	break;	\
@@ -391,6 +415,7 @@ do {									\
 	case 8:	__put_user_asm_dword(__pu_val, __pu_addr, err);	break;	\
 	default: __put_user_bad();					\
 	}								\
+	uaccess_restore(__ua_flags);					\
 } while (0)
 
 #define __put_user_asm_byte(x, __pu_addr, err)			\
@@ -474,11 +499,46 @@ do {									\
 
 
 #ifdef CONFIG_MMU
-extern unsigned long __must_check __copy_from_user(void *to, const void __user *from, unsigned long n);
-extern unsigned long __must_check __copy_to_user(void __user *to, const void *from, unsigned long n);
-extern unsigned long __must_check __copy_to_user_std(void __user *to, const void *from, unsigned long n);
-extern unsigned long __must_check __clear_user(void __user *addr, unsigned long n);
-extern unsigned long __must_check __clear_user_std(void __user *addr, unsigned long n);
+extern unsigned long __must_check
+arm_copy_from_user(void *to, const void __user *from, unsigned long n);
+
+static inline unsigned long __must_check
+__copy_from_user(void *to, const void __user *from, unsigned long n)
+{
+	unsigned int __ua_flags = uaccess_save_and_enable();
+	n = arm_copy_from_user(to, from, n);
+	uaccess_restore(__ua_flags);
+	return n;
+}
+
+extern unsigned long __must_check
+arm_copy_to_user(void __user *to, const void *from, unsigned long n);
+extern unsigned long __must_check
+__copy_to_user_std(void __user *to, const void *from, unsigned long n);
+
+static inline unsigned long __must_check
+__copy_to_user(void __user *to, const void *from, unsigned long n)
+{
+	unsigned int __ua_flags = uaccess_save_and_enable();
+	n = arm_copy_to_user(to, from, n);
+	uaccess_restore(__ua_flags);
+	return n;
+}
+
+extern unsigned long __must_check
+arm_clear_user(void __user *addr, unsigned long n);
+extern unsigned long __must_check
+__clear_user_std(void __user *addr, unsigned long n);
+
+static inline unsigned long __must_check
+__clear_user(void __user *addr, unsigned long n)
+{
+	unsigned int __ua_flags = uaccess_save_and_enable();
+	n = arm_clear_user(addr, n);
+	uaccess_restore(__ua_flags);
+	return n;
+}
+
 #else
 #define __copy_from_user(to, from, n)	(memcpy(to, (void __force *)from, n), 0)
 #define __copy_to_user(to, from, n)	(memcpy((void __force *)to, from, n), 0)
@@ -511,6 +571,7 @@ static inline unsigned long __must_check clear_user(void __user *to, unsigned lo
 	return n;
 }
 
+/* These are from lib/ code, and use __get_user() and friends */
 extern long strncpy_from_user(char *dest, const char __user *src, long count);
 
 extern __must_check long strlen_user(const char __user *str);
diff --git a/arch/arm/kernel/armksyms.c b/arch/arm/kernel/armksyms.c
index a88671cfe1ff..a35d72d30b56 100644
--- a/arch/arm/kernel/armksyms.c
+++ b/arch/arm/kernel/armksyms.c
@@ -91,9 +91,9 @@ EXPORT_SYMBOL(__memzero);
 #ifdef CONFIG_MMU
 EXPORT_SYMBOL(copy_page);
 
-EXPORT_SYMBOL(__copy_from_user);
-EXPORT_SYMBOL(__copy_to_user);
-EXPORT_SYMBOL(__clear_user);
+EXPORT_SYMBOL(arm_copy_from_user);
+EXPORT_SYMBOL(arm_copy_to_user);
+EXPORT_SYMBOL(arm_clear_user);
 
 EXPORT_SYMBOL(__get_user_1);
 EXPORT_SYMBOL(__get_user_2);
diff --git a/arch/arm/lib/clear_user.S b/arch/arm/lib/clear_user.S
index 1710fd7db2d5..970d6c043774 100644
--- a/arch/arm/lib/clear_user.S
+++ b/arch/arm/lib/clear_user.S
@@ -12,14 +12,14 @@
 
 		.text
 
-/* Prototype: int __clear_user(void *addr, size_t sz)
+/* Prototype: unsigned long arm_clear_user(void *addr, size_t sz)
  * Purpose  : clear some user memory
  * Params   : addr - user memory address to clear
  *          : sz   - number of bytes to clear
  * Returns  : number of bytes NOT cleared
  */
 ENTRY(__clear_user_std)
-WEAK(__clear_user)
+WEAK(arm_clear_user)
 		stmfd	sp!, {r1, lr}
 		mov	r2, #0
 		cmp	r1, #4
@@ -44,7 +44,7 @@ WEAK(__clear_user)
 USER(		strnebt	r2, [r0])
 		mov	r0, #0
 		ldmfd	sp!, {r1, pc}
-ENDPROC(__clear_user)
+ENDPROC(arm_clear_user)
 ENDPROC(__clear_user_std)
 
 		.pushsection .text.fixup,"ax"
diff --git a/arch/arm/lib/copy_from_user.S b/arch/arm/lib/copy_from_user.S
index 7a235b9952be..1512bebfbf1b 100644
--- a/arch/arm/lib/copy_from_user.S
+++ b/arch/arm/lib/copy_from_user.S
@@ -17,7 +17,7 @@
 /*
  * Prototype:
  *
- *	size_t __copy_from_user(void *to, const void *from, size_t n)
+ *	size_t arm_copy_from_user(void *to, const void *from, size_t n)
  *
  * Purpose:
  *
@@ -89,11 +89,11 @@
 
 	.text
 
-ENTRY(__copy_from_user)
+ENTRY(arm_copy_from_user)
 
 #include "copy_template.S"
 
-ENDPROC(__copy_from_user)
+ENDPROC(arm_copy_from_user)
 
 	.pushsection .fixup,"ax"
 	.align 0
diff --git a/arch/arm/lib/copy_to_user.S b/arch/arm/lib/copy_to_user.S
index 9648b0675a3e..caf5019d8161 100644
--- a/arch/arm/lib/copy_to_user.S
+++ b/arch/arm/lib/copy_to_user.S
@@ -17,7 +17,7 @@
 /*
  * Prototype:
  *
- *	size_t __copy_to_user(void *to, const void *from, size_t n)
+ *	size_t arm_copy_to_user(void *to, const void *from, size_t n)
  *
  * Purpose:
  *
@@ -93,11 +93,11 @@
 	.text
 
 ENTRY(__copy_to_user_std)
-WEAK(__copy_to_user)
+WEAK(arm_copy_to_user)
 
 #include "copy_template.S"
 
-ENDPROC(__copy_to_user)
+ENDPROC(arm_copy_to_user)
 ENDPROC(__copy_to_user_std)
 
 	.pushsection .text.fixup,"ax"
diff --git a/arch/arm/lib/uaccess_with_memcpy.c b/arch/arm/lib/uaccess_with_memcpy.c
index 3e58d710013c..77f020e75ccd 100644
--- a/arch/arm/lib/uaccess_with_memcpy.c
+++ b/arch/arm/lib/uaccess_with_memcpy.c
@@ -136,7 +136,7 @@ __copy_to_user_memcpy(void __user *to, const void *from, unsigned long n)
 }
 
 unsigned long
-__copy_to_user(void __user *to, const void *from, unsigned long n)
+arm_copy_to_user(void __user *to, const void *from, unsigned long n)
 {
 	/*
 	 * This test is stubbed out of the main function above to keep
@@ -190,7 +190,7 @@ __clear_user_memset(void __user *addr, unsigned long n)
 	return n;
 }
 
-unsigned long __clear_user(void __user *addr, unsigned long n)
+unsigned long arm_clear_user(void __user *addr, unsigned long n)
 {
 	/* See rational for this in __copy_to_user() above. */
 	if (n < 64)
-- 
2.1.0



From rmk+kernel at arm.linux.org.uk  Fri Aug 21 06:31:51 2015
From: rmk+kernel at arm.linux.org.uk (Russell King)
Date: Fri, 21 Aug 2015 14:31:51 +0100
Subject: [PATCH 8/9] ARM: entry: provide uaccess assembly macro hooks
In-Reply-To: <20150821133043.GV7557@n2100.arm.linux.org.uk>
References: <20150821133043.GV7557@n2100.arm.linux.org.uk>
Message-ID: <E1ZSmQB-0002zT-A6@rmk-PC.arm.linux.org.uk>

Provide hooks into the kernel entry and exit paths to permit control
of userspace visibility to the kernel.  The intended use is:

- on entry to kernel from user, uaccess_disable will be called to
  disable userspace visibility
- on exit from kernel to user, uaccess_enable will be called to
  enable userspace visibility
- on entry from a kernel exception, uaccess_save_and_disable will be
  called to save the current userspace visibility setting, and disable
  access
- on exit from a kernel exception, uaccess_restore will be called to
  restore the userspace visibility as it was before the exception
  occurred.

These hooks allows us to keep userspace visibility disabled for the
vast majority of the kernel, except for localised regions where we
want to explicitly access userspace.

Signed-off-by: Russell King <rmk+kernel at arm.linux.org.uk>
---
 arch/arm/kernel/entry-armv.S   | 25 ++++++++++++++++++-------
 arch/arm/kernel/entry-common.S |  2 ++
 arch/arm/kernel/entry-header.S | 17 +++++++++++++++++
 3 files changed, 37 insertions(+), 7 deletions(-)

diff --git a/arch/arm/kernel/entry-armv.S b/arch/arm/kernel/entry-armv.S
index d19adcf6c580..f6102b39517c 100644
--- a/arch/arm/kernel/entry-armv.S
+++ b/arch/arm/kernel/entry-armv.S
@@ -152,7 +152,7 @@ ENDPROC(__und_invalid)
 	.macro	svc_entry, stack_hole=0, trace=1
  UNWIND(.fnstart		)
  UNWIND(.save {r0 - pc}		)
-	sub	sp, sp, #(S_FRAME_SIZE + \stack_hole - 4)
+	sub	sp, sp, #(S_FRAME_SIZE + 8 + \stack_hole - 4)
 #ifdef CONFIG_THUMB2_KERNEL
  SPFIX(	str	r0, [sp]	)	@ temporarily saved
  SPFIX(	mov	r0, sp		)
@@ -167,7 +167,7 @@ ENDPROC(__und_invalid)
 	ldmia	r0, {r3 - r5}
 	add	r7, sp, #S_SP - 4	@ here for interlock avoidance
 	mov	r6, #-1			@  ""  ""      ""       ""
-	add	r2, sp, #(S_FRAME_SIZE + \stack_hole - 4)
+	add	r2, sp, #(S_FRAME_SIZE + 8 + \stack_hole - 4)
  SPFIX(	addeq	r2, r2, #4	)
 	str	r3, [sp, #-4]!		@ save the "real" r0 copied
 					@ from the exception stack
@@ -185,6 +185,8 @@ ENDPROC(__und_invalid)
 	@
 	stmia	r7, {r2 - r6}
 
+	uaccess_save_and_disable r0
+
 	.if \trace
 #ifdef CONFIG_TRACE_IRQFLAGS
 	bl	trace_hardirqs_off
@@ -368,7 +370,7 @@ ENDPROC(__fiq_abt)
 #error "sizeof(struct pt_regs) must be a multiple of 8"
 #endif
 
-	.macro	usr_entry, trace=1
+	.macro	usr_entry, trace=1, uaccess=1
  UNWIND(.fnstart	)
  UNWIND(.cantunwind	)	@ don't unwind the user space
 	sub	sp, sp, #S_FRAME_SIZE
@@ -400,6 +402,10 @@ ENDPROC(__fiq_abt)
  ARM(	stmdb	r0, {sp, lr}^			)
  THUMB(	store_user_sp_lr r0, r1, S_SP - S_PC	)
 
+	.if \uaccess
+	uaccess_disable ip
+	.endif
+
 	@ Enable the alignment trap while in kernel mode
  ATRAP(	teq	r8, r7)
  ATRAP( mcrne	p15, 0, r8, c1, c0, 0)
@@ -458,7 +464,7 @@ ENDPROC(__irq_usr)
 
 	.align	5
 __und_usr:
-	usr_entry
+	usr_entry uaccess=0
 
 	mov	r2, r4
 	mov	r3, r5
@@ -484,6 +490,8 @@ __und_usr:
 1:	ldrt	r0, [r4]
  ARM_BE8(rev	r0, r0)				@ little endian instruction
 
+	uaccess_disable ip
+
 	@ r0 = 32-bit ARM instruction which caused the exception
 	@ r2 = PC value for the following instruction (:= regs->ARM_pc)
 	@ r4 = PC value for the faulting instruction
@@ -518,9 +526,10 @@ __und_usr_thumb:
 2:	ldrht	r5, [r4]
 ARM_BE8(rev16	r5, r5)				@ little endian instruction
 	cmp	r5, #0xe800			@ 32bit instruction if xx != 0
-	blo	__und_usr_fault_16		@ 16bit undefined instruction
+	blo	__und_usr_fault_16_pan		@ 16bit undefined instruction
 3:	ldrht	r0, [r2]
 ARM_BE8(rev16	r0, r0)				@ little endian instruction
+	uaccess_disable ip
 	add	r2, r2, #2			@ r2 is PC + 2, make it PC + 4
 	str	r2, [sp, #S_PC]			@ it's a 2x16bit instr, update
 	orr	r0, r0, r5, lsl #16
@@ -715,6 +724,8 @@ ENDPROC(no_fp)
 __und_usr_fault_32:
 	mov	r1, #4
 	b	1f
+__und_usr_fault_16_pan:
+	uaccess_disable ip
 __und_usr_fault_16:
 	mov	r1, #2
 1:	mov	r0, sp
@@ -769,7 +780,7 @@ ENTRY(__switch_to)
  THUMB(	str	lr, [ip], #4		   )
 	ldr	r4, [r2, #TI_TP_VALUE]
 	ldr	r5, [r2, #TI_TP_VALUE + 4]
-#ifdef CONFIG_CPU_USE_DOMAINS
+#if defined(CONFIG_CPU_USE_DOMAINS) || defined(CONFIG_CPU_SW_DOMAIN_PAN)
 	mrc	p15, 0, r6, c3, c0, 0		@ Get domain register
 	str	r6, [r1, #TI_CPU_DOMAIN]	@ Save old domain register
 	ldr	r6, [r2, #TI_CPU_DOMAIN]
@@ -780,7 +791,7 @@ ENTRY(__switch_to)
 	ldr	r8, =__stack_chk_guard
 	ldr	r7, [r7, #TSK_STACK_CANARY]
 #endif
-#ifdef CONFIG_CPU_USE_DOMAINS
+#if defined(CONFIG_CPU_USE_DOMAINS) || defined(CONFIG_CPU_SW_DOMAIN_PAN)
 	mcr	p15, 0, r6, c3, c0, 0		@ Set domain register
 #endif
 	mov	r5, r0
diff --git a/arch/arm/kernel/entry-common.S b/arch/arm/kernel/entry-common.S
index 92828a1dec80..189154980703 100644
--- a/arch/arm/kernel/entry-common.S
+++ b/arch/arm/kernel/entry-common.S
@@ -173,6 +173,8 @@ ENTRY(vector_swi)
  USER(	ldr	scno, [lr, #-4]		)	@ get SWI instruction
 #endif
 
+	uaccess_disable tbl
+
 	adr	tbl, sys_call_table		@ load syscall table pointer
 
 #if defined(CONFIG_OABI_COMPAT)
diff --git a/arch/arm/kernel/entry-header.S b/arch/arm/kernel/entry-header.S
index 1a0045abead7..3aa6c3742182 100644
--- a/arch/arm/kernel/entry-header.S
+++ b/arch/arm/kernel/entry-header.S
@@ -53,6 +53,18 @@
 #endif
 	.endm
 
+	.macro	uaccess_disable, tmp
+	.endm
+
+	.macro	uaccess_enable, tmp
+	.endm
+
+	.macro	uaccess_save_and_disable, tmp
+	.endm
+
+	.macro	uaccess_restore
+	.endm
+
 #ifdef CONFIG_CPU_V7M
 /*
  * ARMv7-M exception entry/exit macros.
@@ -215,6 +227,7 @@
 	blne	trace_hardirqs_off
 #endif
 	.endif
+	uaccess_restore
 	msr	spsr_cxsf, \rpsr
 #if defined(CONFIG_CPU_V6) || defined(CONFIG_CPU_32v6K)
 	@ We must avoid clrex due to Cortex-A15 erratum #830321
@@ -241,6 +254,7 @@
 	@ on the stack remains correct).
 	@
 	.macro  svc_exit_via_fiq
+	uaccess_restore
 	mov	r0, sp
 	ldmib	r0, {r1 - r14}	@ abort is deadly from here onward (it will
 				@ clobber state restored below)
@@ -253,6 +267,7 @@
 	.endm
 
 	.macro	restore_user_regs, fast = 0, offset = 0
+	uaccess_enable r1
 	mov	r2, sp
 	ldr	r1, [r2, #\offset + S_PSR]	@ get calling cpsr
 	ldr	lr, [r2, #\offset + S_PC]!	@ get pc
@@ -329,6 +344,7 @@
 	 * part of each exception entry and exit sequence.
 	 */
 	.macro	restore_user_regs, fast = 0, offset = 0
+	uaccess_enable r1
 	.if	\offset
 	add	sp, #\offset
 	.endif
@@ -336,6 +352,7 @@
 	.endm
 #else	/* ifdef CONFIG_CPU_V7M */
 	.macro	restore_user_regs, fast = 0, offset = 0
+	uaccess_enable r1
 	mov	r2, sp
 	load_user_sp_lr r2, r3, \offset + S_SP	@ calling sp, lr
 	ldr	r1, [sp, #\offset + S_PSR]	@ get calling cpsr
-- 
2.1.0



From rmk+kernel at arm.linux.org.uk  Fri Aug 21 06:31:56 2015
From: rmk+kernel at arm.linux.org.uk (Russell King)
Date: Fri, 21 Aug 2015 14:31:56 +0100
Subject: [PATCH 9/9] ARM: software-based priviledged-no-access support
In-Reply-To: <20150821133043.GV7557@n2100.arm.linux.org.uk>
References: <20150821133043.GV7557@n2100.arm.linux.org.uk>
Message-ID: <E1ZSmQG-0002za-E3@rmk-PC.arm.linux.org.uk>

Provide a software-based implementation of the priviledged no access
support found in ARMv8.1.

Userspace pages are mapped using a different domain number from the
kernel and IO mappings.  If we switch the user domain to "no access"
when we enter the kernel, we can prevent the kernel from touching
userspace.

However, the kernel needs to be able to access userspace via the
various user accessor functions.  With the wrapping in the previous
patch, we can temporarily enable access when the kernel needs user
access, and re-disable it afterwards.

This allows us to trap non-intended accesses to userspace, eg, caused
by an inadvertent dereference of the LIST_POISON* values, which, with
appropriate user mappings setup, can be made to succeed.  This in turn
can allow use-after-free bugs to be further exploited than would
otherwise be possible.

Signed-off-by: Russell King <rmk+kernel at arm.linux.org.uk>
---
 arch/arm/Kconfig               | 15 +++++++++++++++
 arch/arm/include/asm/domain.h  | 15 ++++++++++++---
 arch/arm/include/asm/uaccess.h | 14 ++++++++++++++
 arch/arm/kernel/entry-header.S | 25 +++++++++++++++++++++++++
 arch/arm/kernel/process.c      | 24 ++++++++++++++++++------
 5 files changed, 84 insertions(+), 9 deletions(-)

diff --git a/arch/arm/Kconfig b/arch/arm/Kconfig
index a750c1425c3a..a898eb72da51 100644
--- a/arch/arm/Kconfig
+++ b/arch/arm/Kconfig
@@ -1694,6 +1694,21 @@ config HIGHPTE
 	bool "Allocate 2nd-level pagetables from highmem"
 	depends on HIGHMEM
 
+config CPU_SW_DOMAIN_PAN
+	bool "Enable use of CPU domains to implement priviledged no-access"
+	depends on MMU && !ARM_LPAE
+	default y
+	help
+	  Increase kernel security by ensuring that normal kernel accesses
+	  are unable to access userspace addresses.  This can help prevent
+	  use-after-free bugs becoming an exploitable privilege escalation
+	  by ensuring that magic values (such as LIST_POISON) will always
+	  fault when dereferenced.
+
+	  CPUs with low-vector mappings use a best-efforts implementation.
+	  Their lower 1MB needs to remain accessible for the vectors, but
+	  the remainder of userspace will become appropriately inaccessible.
+
 config HW_PERF_EVENTS
 	bool "Enable hardware performance counter support for perf events"
 	depends on PERF_EVENTS
diff --git a/arch/arm/include/asm/domain.h b/arch/arm/include/asm/domain.h
index 2be929549938..0c373979af00 100644
--- a/arch/arm/include/asm/domain.h
+++ b/arch/arm/include/asm/domain.h
@@ -58,11 +58,21 @@
 #define domain_val(dom,type)	((type) << (2 * (dom)))
 
 #define DACR_INIT \
-	(domain_val(DOMAIN_USER, DOMAIN_CLIENT) | \
+	(domain_val(DOMAIN_USER, DOMAIN_NOACCESS) | \
 	 domain_val(DOMAIN_KERNEL, DOMAIN_MANAGER) | \
 	 domain_val(DOMAIN_IO, DOMAIN_CLIENT) | \
 	 domain_val(DOMAIN_VECTORS, DOMAIN_CLIENT))
 
+#define __DACR_DEFAULT \
+	domain_val(DOMAIN_KERNEL, DOMAIN_CLIENT) | \
+	domain_val(DOMAIN_IO, DOMAIN_CLIENT) | \
+	domain_val(DOMAIN_VECTORS, DOMAIN_CLIENT)
+
+#define DACR_UACCESS_DISABLE	\
+	(__DACR_DEFAULT | domain_val(DOMAIN_USER, DOMAIN_NOACCESS))
+#define DACR_UACCESS_ENABLE	\
+	(__DACR_DEFAULT | domain_val(DOMAIN_USER, DOMAIN_CLIENT))
+
 #ifndef __ASSEMBLY__
 
 static inline unsigned int get_domain(void)
@@ -76,7 +86,6 @@ static inline unsigned int get_domain(void)
 	return domain;
 }
 
-#ifdef CONFIG_CPU_USE_DOMAINS
 static inline void set_domain(unsigned val)
 {
 	asm volatile(
@@ -85,6 +94,7 @@ static inline void set_domain(unsigned val)
 	isb();
 }
 
+#ifdef CONFIG_CPU_USE_DOMAINS
 #define modify_domain(dom,type)					\
 	do {							\
 		unsigned int domain = get_domain();		\
@@ -94,7 +104,6 @@ static inline void set_domain(unsigned val)
 	} while (0)
 
 #else
-static inline void set_domain(unsigned val) { }
 static inline void modify_domain(unsigned dom, unsigned type)	{ }
 #endif
 
diff --git a/arch/arm/include/asm/uaccess.h b/arch/arm/include/asm/uaccess.h
index 4ae10967a8ba..cb802870ffb9 100644
--- a/arch/arm/include/asm/uaccess.h
+++ b/arch/arm/include/asm/uaccess.h
@@ -101,11 +101,25 @@ static inline void set_fs(mm_segment_t fs)
  */
 static inline unsigned int uaccess_save_and_enable(void)
 {
+#ifdef CONFIG_CPU_SW_DOMAIN_PAN
+	unsigned int old_domain = get_domain();
+
+	/* Set the current domain access to permit user accesses */
+	set_domain((old_domain & ~domain_mask(DOMAIN_USER)) |
+		   domain_val(DOMAIN_USER, DOMAIN_CLIENT));
+
+	return old_domain;
+#else
 	return 0;
+#endif
 }
 
 static inline void uaccess_restore(unsigned int flags)
 {
+#ifdef CONFIG_CPU_SW_DOMAIN_PAN
+	/* Restore the user access mask */
+	set_domain(flags);
+#endif
 }
 
 /*
diff --git a/arch/arm/kernel/entry-header.S b/arch/arm/kernel/entry-header.S
index 3aa6c3742182..bec7ee0764e1 100644
--- a/arch/arm/kernel/entry-header.S
+++ b/arch/arm/kernel/entry-header.S
@@ -54,15 +54,40 @@
 	.endm
 
 	.macro	uaccess_disable, tmp
+#ifdef CONFIG_CPU_SW_DOMAIN_PAN
+	/*
+	 * Whenever we re-enter userspace, the domains should always be
+	 * set appropriately.
+	 */
+	mov	\tmp, #DACR_UACCESS_DISABLE
+	mcr	p15, 0, \tmp, c3, c0, 0		@ Set domain register
+#endif
 	.endm
 
 	.macro	uaccess_enable, tmp
+#ifdef CONFIG_CPU_SW_DOMAIN_PAN
+	/*
+	 * Whenever we re-enter userspace, the domains should always be
+	 * set appropriately.
+	 */
+	mov	\tmp, #DACR_UACCESS_ENABLE
+	mcr	p15, 0, \tmp, c3, c0, 0
+#endif
 	.endm
 
 	.macro	uaccess_save_and_disable, tmp
+#ifdef CONFIG_CPU_SW_DOMAIN_PAN
+	mrc	p15, 0, \tmp, c3, c0, 0
+	str	\tmp, [sp, #S_FRAME_SIZE]
+#endif
+	uaccess_disable \tmp
 	.endm
 
 	.macro	uaccess_restore
+#ifdef CONFIG_CPU_SW_DOMAIN_PAN
+	ldr	r0, [sp, #S_FRAME_SIZE]
+	mcr	p15, 0, r0, c3, c0, 0
+#endif
 	.endm
 
 #ifdef CONFIG_CPU_V7M
diff --git a/arch/arm/kernel/process.c b/arch/arm/kernel/process.c
index e722f9b3c9b1..b407cc7a7b55 100644
--- a/arch/arm/kernel/process.c
+++ b/arch/arm/kernel/process.c
@@ -129,12 +129,24 @@ void __show_regs(struct pt_regs *regs)
 	buf[4] = '\0';
 
 #ifndef CONFIG_CPU_V7M
-	printk("Flags: %s  IRQs o%s  FIQs o%s  Mode %s  ISA %s  Segment %s\n",
-		buf, interrupts_enabled(regs) ? "n" : "ff",
-		fast_interrupts_enabled(regs) ? "n" : "ff",
-		processor_modes[processor_mode(regs)],
-		isa_modes[isa_mode(regs)],
-		get_fs() == get_ds() ? "kernel" : "user");
+	{
+		unsigned int domain = get_domain();
+		const char *segment;
+
+		if ((domain & domain_mask(DOMAIN_USER)) ==
+		    domain_val(DOMAIN_USER, DOMAIN_NOACCESS))
+			segment = "none";
+		else if (get_fs() == get_ds())
+			segment = "kernel";
+		else
+			segment = "user";
+
+		printk("Flags: %s  IRQs o%s  FIQs o%s  Mode %s  ISA %s  Segment %s\n",
+			buf, interrupts_enabled(regs) ? "n" : "ff",
+			fast_interrupts_enabled(regs) ? "n" : "ff",
+			processor_modes[processor_mode(regs)],
+			isa_modes[isa_mode(regs)], segment);
+	}
 #else
 	printk("xPSR: %08lx\n", regs->ARM_cpsr);
 #endif
-- 
2.1.0



From linux at arm.linux.org.uk  Fri Aug 21 06:30:43 2015
From: linux at arm.linux.org.uk (Russell King - ARM Linux)
Date: Fri, 21 Aug 2015 14:30:43 +0100
Subject: Prevent list poison values from being mapped by userspace
 processes
In-Reply-To: <CABXk95C=CpeL4mNmS6-jJ-0bMJf6fawwfs6DM1-p8FctTEFbpw@mail.gmail.com>
References: <CABXk95C=CpeL4mNmS6-jJ-0bMJf6fawwfs6DM1-p8FctTEFbpw@mail.gmail.com>
Message-ID: <20150821133043.GV7557@n2100.arm.linux.org.uk>

On Tue, Aug 18, 2015 at 02:42:44PM -0700, Jeffrey Vander Stoep wrote:
> List poison pointer values point to memory that is mappable by
> userspace. i.e. LIST_POISON1 = 0x00100100 and LIST_POISON2 =
> 0x00200200. This means poison values can be valid pointers controlled
> by userspace and can be used to exploit the kernel as demonstrated in
> a recent blackhat talk:
> https://www.blackhat.com/docs/us-15/materials/us-15-Xu-Ah-Universal-Android-Rooting-Is-Back-wp.pdf
> 
> Can these poison values be moved to an area not mappable by userspace
> on 32 bit ARM?

As was discussed privately before your message, both Catalin and myself
agreed that this is not possible, and I proposed alternatives which were
feasible.

I have now implemented the domain access alternative which I mentioned
during that discussion, which is suitable for all non-LPAE setups, which
has the effect of blocking almost all implicit kernel accesses to
userspace, thereby substantially reducing the possibility for an attack
similar to that given in the above paper.

It should be said that with the following patches applied, it won't stop
the original bug being used to crash the system (that's already been
fixed) but it will prevent userspace being able to mask the crash, and
therefore prevent such use-after-free bugs being used to gain privileges.

This approach also covers low-vector CPUs as well, with one caveat: the
lower 1MB of userspace will remain accessible to the kernel due to the
need for the vectors to remain visible.  Doing otherwise crashes the
machine on the first exception event.  So here, we offer a "best efforts"
implementation rather than something which completely blocks userspace
access from kernel space.

This is not a simple fix - it's quite involved, and it changes a fair
number of places in the kernel.  It needs time to be proven before any
thought can be given to backporting these changes to stable kernels.
It would be good to get some testing of these changes.

 arch/arm/Kconfig                            | 15 +++++
 arch/arm/include/asm/domain.h               | 45 +++++++++++----
 arch/arm/include/asm/futex.h                | 19 ++++++-
 arch/arm/include/asm/pgtable-2level-hwdef.h |  1 +
 arch/arm/include/asm/thread_info.h          |  3 -
 arch/arm/include/asm/uaccess.h              | 85 +++++++++++++++++++++++++++--
 arch/arm/kernel/armksyms.c                  |  6 +-
 arch/arm/kernel/entry-armv.S                | 27 ++++++---
 arch/arm/kernel/entry-common.S              |  2 +
 arch/arm/kernel/entry-header.S              | 42 ++++++++++++++
 arch/arm/kernel/head.S                      |  5 +-
 arch/arm/kernel/process.c                   | 37 ++++++++++---
 arch/arm/kernel/traps.c                     |  1 -
 arch/arm/lib/clear_user.S                   |  6 +-
 arch/arm/lib/copy_from_user.S               |  6 +-
 arch/arm/lib/copy_to_user.S                 |  6 +-
 arch/arm/lib/uaccess_with_memcpy.c          |  4 +-
 arch/arm/mm/mmu.c                           |  4 +-
 arch/arm/mm/pgd.c                           | 10 ++++
 19 files changed, 267 insertions(+), 57 deletions(-)

-- 
FTTC broadband for 0.8mile line: currently at 10.5Mbps down 400kbps up
according to speedtest.net.


From Liviu.Dudau at arm.com  Fri Aug 21 06:42:30 2015
From: Liviu.Dudau at arm.com (Liviu Dudau)
Date: Fri, 21 Aug 2015 14:42:30 +0100
Subject: [PATCH v7 3/6] PCI: designware: Add ARM64 support
In-Reply-To: <EE11001F9E5DDD47B7634E2F8A612F2E01D81BAC@lhreml503-mbs>
References: <1439812554-180426-1-git-send-email-wangzhou1@hisilicon.com>
 <1439812554-180426-4-git-send-email-wangzhou1@hisilicon.com>
 <1439988852.31432.15.camel@pengutronix.de>
 <EE11001F9E5DDD47B7634E2F8A612F2E01D81315@lhreml503-mbs>
 <1439998622.31432.44.camel@pengutronix.de>
 <EE11001F9E5DDD47B7634E2F8A612F2E01D8139B@lhreml503-mbs>
 <1440059243.31432.59.camel@pengutronix.de>
 <EE11001F9E5DDD47B7634E2F8A612F2E01D81BAC@lhreml503-mbs>
Message-ID: <20150821134230.GQ1020@e106497-lin.cambridge.arm.com>

On Thu, Aug 20, 2015 at 12:10:24PM +0100, Gabriele Paoloni wrote:
> Hi Lucas
> 
> Again many thanks for explaining and for your time.
> 
> I got your point now and I have dug a bit better in the PCI_DOMAINS code.
> 
> However I have a question...see inline below
> 
> > -----Original Message-----
> > From: Lucas Stach [mailto:l.stach at pengutronix.de]
> > Sent: Thursday, August 20, 2015 9:27 AM
> > To: Gabriele Paoloni
> > Cc: Wangzhou (B); Bjorn Helgaas; jingoohan1 at gmail.com; Pratyush Anand;
> > Arnd Bergmann; linux at arm.linux.org.uk; thomas.petazzoni at free-
> > electrons.com; lorenzo.pieralisi at arm.com; james.morse at arm.com;
> > Liviu.Dudau at arm.com; jason at lakedaemon.net; robh at kernel.org; linux-
> > pci at vger.kernel.org; linux-arm-kernel at lists.infradead.org;
> > devicetree at vger.kernel.org; Yuanzhichang; Zhudacai; zhangjukuo;
> > qiuzhenfa; liudongdong (C); qiujiang; xuwei (O); Liguozhu (Kenneth)
> > Subject: Re: [PATCH v7 3/6] PCI: designware: Add ARM64 support
> > 
> > Hi Gab,
> > 
> > Am Mittwoch, den 19.08.2015, 16:34 +0000 schrieb Gabriele Paoloni:
> > > Hi Lucas
> > >
> > > First of all many thanks for the quick reply, really appreciated
> > >
> > > > -----Original Message-----
> > > > From: Lucas Stach [mailto:l.stach at pengutronix.de]
> > > > Sent: Wednesday, August 19, 2015 4:37 PM
> > > > To: Gabriele Paoloni
> > > > Cc: Wangzhou (B); Bjorn Helgaas; jingoohan1 at gmail.com; Pratyush
> > Anand;
> > > > Arnd Bergmann; linux at arm.linux.org.uk; thomas.petazzoni at free-
> > > > electrons.com; lorenzo.pieralisi at arm.com; james.morse at arm.com;
> > > > Liviu.Dudau at arm.com; jason at lakedaemon.net; robh at kernel.org; linux-
> > > > pci at vger.kernel.org; linux-arm-kernel at lists.infradead.org;
> > > > devicetree at vger.kernel.org; Yuanzhichang; Zhudacai; zhangjukuo;
> > > > qiuzhenfa; liudongdong (C); qiujiang; xuwei (O); Liguozhu (Kenneth)
> > > > Subject: Re: [PATCH v7 3/6] PCI: designware: Add ARM64 support
> > > >
> > > > Hi Gab,
> > > >
> > > > Am Mittwoch, den 19.08.2015, 15:16 +0000 schrieb Gabriele Paoloni:
> > > > > Hi Lucas
> > > > >
> > > > > I have rewritten the patch to take into account multiple
> > controllers.
> > > > >
> > > > > As you can see now there is a static var in dw_pcie_host_init()
> > that
> > > > tracks
> > > > > the bus numbers used.
> > > >
> > > > This is wrong. The DT specifies the valid bus number range. You can
> > not
> > > > just assign the next free bus number to the root bus.
> > >
> > > I think this is what is being done in
> > > http://lxr.free-electrons.com/source/arch/arm/kernel/bios32.c#L495
> > > and currently designware assigns the root bus number in
> > > http://lxr.free-electrons.com/source/drivers/pci/host/pcie-
> > designware.c#L730
> > >
> > You found the right spot. It works a bit different than I remember, but
> > is less broken than your current code. :)
> > 
> > It actually assigns the next instance a root bus number behind the
> > current instances bus range. Please note the difference to your code
> > which assigns the next free bus number, which may still lay within the
> > current instances bus range.

Hi Gabriele,

> 
> Mmmm here I have done a mistake: in the current designware the number of hw
> controllers is always 1
> http://lxr.free-electrons.com/source/drivers/pci/host/pcie-designware.c#L510
> So the loop in bios32.c does not work on multiple PCIe ports...

Bios32.c is broken for multiple PCIe hosts for multiple reasons, this is just
one of them. Hence the effort to get rid of it for maintained drivers.

> However your comment about PCI_DOMAINS enlightened my mind and now I see
> that when CONFIG_PCI_DOMAINS is defined we have the domains numbers
> (tracked by __domain_nr).

CONFIG_PCI_DOMAINS in itself doesn't do much without adding code to your driver.
You could request a new domain for each controller with a special property to
disable that behaviour in the dts, or you could enable CONFIG_PCI_DOMAINS_GENERIC
which will give you a new domain automatically.

> So (correct me if I am wrong) if we have 2 PCIe ports that do not specify
> the "bus-range" property, both root ports will enumerate starting from 
> root_bus_nr = 0 and everything will still work ok.

Correct.

Best regards,
Liviu

> 
> So if my assumption is correct, I do not see why the orginal patch from Wang 
> Zhou is wrong. 
> The only point can be that assigning pp->root_bus_nr = 0 is not required 
> as pp memory is kzalloc'ed (an therefore init to zero).
> 
> 
> > 
> > >
> > > In general I agree with you but if you look at all the current
> > drivers
> > > based on designware none of them define the "bus-range" dtb property.
> > > Therefore doing as you say would break the current driver when we
> > have
> > > multiple controllers...am I right?
> > >
> > The current _code_ works fine for multiple controllers. It's just that
> > you must define the bus range property in the DTB if you want to enable
> > multiple instances of one controller and support a kernel without PCI
> > domains support. As all current implementations have only a single
> > instance of the controller per SoC, or depend on PCI domain support,
> > it's totally fine for them to not define the bus ranges property, as
> > it's an optional property and it is well defined how things behave if
> > it
> > is absent. We absolutely need to keep that specified behavior.
> > 
> > > If that is the case in order to fix this in the way you say I would
> > need
> > > to assign "bus-range" for all the PCIe drivers with multiple
> > controllers:
> > > in this case I would split the default range evenly (that is, if we
> > have
> > > two controllers I would define "bus-range"  0-127 and 128-255)
> > >
> > > If you think this solution is ok I can go for it. My only doubt was
> > about
> > > touching other vendors DTBs....
> > >
> > You don't need to touch any of the current DTBs, as they are fine with
> > the default bus range behavior. You need to keep the specified behavior
> > of the bus range property with the new code.
> > 
> > Regards,
> > Lucas
> > >
> > > >
> > > > It is perfectly valid to have a bus range of 0x00-0x10 assigned to
> > one
> > > > instance and 0x50-0xff to the next instance. Additional with PCIe
> > > > hotplug you may not use the full range of the bus numbers on one
> > > > instance at the first scan, but only later populate more buses when
> > > > more
> > > > bridges are added to the tree.
> > > >
> > > > > Drivers that do not specify the bus range in the DTB set pp-
> > > > >root_bus_nr = DW_ROOT_NR_UNDEFINED.
> > > > > Designware will check if the flag is set and will use the
> > automatic
> > > > bus range
> > > > > assignment.
> > > >
> > > > No, please lets get rid of this assignment altogether. The glue
> > drivers
> > > > have no business in assigning the bus range. Please remove the
> > > > pp->root_bus_nr assignment from all the glue drivers.
> > > >
> > > > "bus range" is a generic DW PCIe property, so just parse the root
> > bus
> > > > number from the DT, it is handled the same way for all the DW based
> > > > PCIe
> > > > drivers. The bindings specifies that if the bus range property is
> > > > missing the range is 0x00-0xff, so you can default to 0 as the root
> > bus
> > > > number in that case.
> > > >
> > > > Also I would think this conversion warrants a patch on its own and
> > > > should not be mixed in the ARM64 support patch.
> > > >
> > > > Regards,
> > > > Lucas
> > > >
> > 
> > --
> > Pengutronix e.K.             | Lucas Stach                 |
> > Industrial Linux Solutions   | http://www.pengutronix.de/  |
> 

-- 
====================
| I would like to |
| fix the world,  |
| but they're not |
| giving me the   |
 \ source code!  /
  ---------------
    ?\_(?)_/?



From Shenwei.Wang at freescale.com  Fri Aug 21 06:45:13 2015
From: Shenwei.Wang at freescale.com (Shenwei Wang)
Date: Fri, 21 Aug 2015 13:45:13 +0000
Subject: [PATCH v8 1/2] irqchip: imx-gpcv2: IMX GPCv2 driver for wakeup
 sources
In-Reply-To: <1438378439-11569-2-git-send-email-shenwei.wang@freescale.com>
References: <1438378439-11569-1-git-send-email-shenwei.wang@freescale.com>
 <1438378439-11569-2-git-send-email-shenwei.wang@freescale.com>
Message-ID: <CY1PR0301MB0843A3B4D44039634480C4B083650@CY1PR0301MB0843.namprd03.prod.outlook.com>

Ping.

Shenwei

> -----Original Message-----
> From: linux-kernel-owner at vger.kernel.org
> [mailto:linux-kernel-owner at vger.kernel.org] On Behalf Of Shenwei Wang
> Sent: 2015?7?31? 16:34
> To: shawn.guo at linaro.org; tglx at linutronix.de; jason at lakedaemon.net
> Cc: linux-arm-kernel at lists.infradead.org; linux-kernel at vger.kernel.org; Huang
> Yongcai-B20788
> Subject: [PATCH v8 1/2] irqchip: imx-gpcv2: IMX GPCv2 driver for wakeup sources
> 
> IMX7D contains a new version of GPC IP block (GPCv2). It has two major functions:
> power management and wakeup source management.
> This patch adds a new irqchip driver to manage the interrupt wakeup sources on
> IMX7D.
> When the system is in WFI (wait for interrupt) mode, this GPC block will be the
> first block on the platform to be activated and signaled.
> Under normal wait mode during cpu idle, the system can be woke up by any
> enabled interrupts. Under standby or suspend mode, the system can only be
> woke up by the pre-defined wakeup sources.
> 
> Signed-off-by: Shenwei Wang <shenwei.wang at freescale.com>
> Signed-off-by: Anson Huang <b20788 at freescale.com>
> ---
>  drivers/irqchip/Kconfig         |   7 ++
>  drivers/irqchip/Makefile        |   1 +
>  drivers/irqchip/irq-imx-gpcv2.c | 273
> ++++++++++++++++++++++++++++++++++++++++
>  3 files changed, 281 insertions(+)
>  create mode 100644 drivers/irqchip/irq-imx-gpcv2.c
> 
> diff --git a/drivers/irqchip/Kconfig b/drivers/irqchip/Kconfig index
> 120d815..3fc0fac 100644
> --- a/drivers/irqchip/Kconfig
> +++ b/drivers/irqchip/Kconfig
> @@ -177,3 +177,10 @@ config RENESAS_H8300H_INTC  config
> RENESAS_H8S_INTC
>          bool
>  	select IRQ_DOMAIN
> +
> +config IMX_GPCV2
> +	bool
> +	select IRQ_DOMAIN
> +	help
> +	  Enables the wakeup IRQs for IMX platforms with GPCv2 block
> +
> diff --git a/drivers/irqchip/Makefile b/drivers/irqchip/Makefile index
> b8d4e96..8eb5f60 100644
> --- a/drivers/irqchip/Makefile
> +++ b/drivers/irqchip/Makefile
> @@ -52,3 +52,4 @@ obj-$(CONFIG_RENESAS_H8300H_INTC)	+=
> irq-renesas-h8300h.o
>  obj-$(CONFIG_RENESAS_H8S_INTC)		+= irq-renesas-h8s.o
>  obj-$(CONFIG_ARCH_SA1100)		+= irq-sa11x0.o
>  obj-$(CONFIG_INGENIC_IRQ)		+= irq-ingenic.o
> +obj-$(CONFIG_IMX_GPCV2)			+= irq-imx-gpcv2.o
> diff --git a/drivers/irqchip/irq-imx-gpcv2.c b/drivers/irqchip/irq-imx-gpcv2.c new
> file mode 100644 index 0000000..c2728b0
> --- /dev/null
> +++ b/drivers/irqchip/irq-imx-gpcv2.c
> @@ -0,0 +1,273 @@
> +/*
> + * Copyright (C) 2015 Freescale Semiconductor, Inc.
> + *
> + * This program is free software; you can redistribute it and/or modify
> + * it under the terms of the GNU General Public License version 2 as
> + * published by the Free Software Foundation.
> + */
> +
> +#include <linux/of_address.h>
> +#include <linux/of_irq.h>
> +#include <linux/slab.h>
> +#include <linux/irqchip.h>
> +#include <linux/syscore_ops.h>
> +
> +#define IMR_NUM			4
> +#define GPC_MAX_IRQS            (IMR_NUM * 32)
> +
> +#define GPC_IMR1_CORE0		0x30
> +#define GPC_IMR1_CORE1		0x40
> +
> +struct gpcv2_irqchip_data {
> +	struct raw_spinlock rlock;
> +	void __iomem *gpc_base;
> +	u32 wakeup_sources[IMR_NUM];
> +	u32 enabled_irqs[IMR_NUM];
> +	u32 cpu2wakeup;
> +};
> +
> +static struct gpcv2_irqchip_data *imx_gpcv2_instance;
> +
> +u32 imx_gpcv2_get_wakeup_source(u32 **sources) {
> +	if (!imx_gpcv2_instance)
> +		return 0;
> +
> +	if (sources)
> +		*sources = imx_gpcv2_instance->wakeup_sources;
> +
> +	return IMR_NUM;
> +}
> +
> +static int gpcv2_wakeup_source_save(void) {
> +	struct gpcv2_irqchip_data *cd;
> +	void __iomem *reg;
> +	int i;
> +
> +	cd = imx_gpcv2_instance;
> +	if (!cd)
> +		return 0;
> +
> +	for (i = 0; i < IMR_NUM; i++) {
> +		reg = cd->gpc_base + cd->cpu2wakeup + i * 4;
> +		cd->enabled_irqs[i] = readl_relaxed(reg);
> +		writel_relaxed(cd->wakeup_sources[i], reg);
> +	}
> +
> +	return 0;
> +}
> +
> +static void gpcv2_wakeup_source_restore(void) {
> +	struct gpcv2_irqchip_data *cd;
> +	void __iomem *reg;
> +	int i;
> +
> +	cd = imx_gpcv2_instance;
> +	if (!cd)
> +		return;
> +
> +	for (i = 0; i < IMR_NUM; i++) {
> +		reg = cd->gpc_base + cd->cpu2wakeup + i * 4;
> +		writel_relaxed(cd->enabled_irqs[i], reg);
> +		cd->wakeup_sources[i] = ~0;
> +	}
> +}
> +
> +static struct syscore_ops imx_gpcv2_syscore_ops = {
> +	.suspend	= gpcv2_wakeup_source_save,
> +	.resume		= gpcv2_wakeup_source_restore,
> +};
> +
> +static int imx_gpcv2_irq_set_wake(struct irq_data *d, unsigned int on)
> +{
> +	struct gpcv2_irqchip_data *cd = d->chip_data;
> +	unsigned int idx = d->hwirq / 32;
> +	unsigned long flags;
> +	void __iomem *reg;
> +	u32 mask, val;
> +
> +	raw_spin_lock_irqsave(&cd->rlock, flags);
> +	reg = cd->gpc_base + cd->cpu2wakeup + idx * 4;
> +	mask = 1 << d->hwirq % 32;
> +	val = cd->wakeup_sources[idx];
> +
> +	cd->wakeup_sources[idx] = on ? (val & ~mask) : (val | mask);
> +	raw_spin_unlock_irqrestore(&cd->rlock, flags);
> +
> +	/*
> +	 * Do *not* call into the parent, as the GIC doesn't have any
> +	 * wake-up facility...
> +	 */
> +
> +	return 0;
> +}
> +
> +static void imx_gpcv2_irq_unmask(struct irq_data *d) {
> +	struct gpcv2_irqchip_data *cd = d->chip_data;
> +	void __iomem *reg;
> +	u32 val;
> +
> +	raw_spin_lock(&cd->rlock);
> +	reg = cd->gpc_base + cd->cpu2wakeup + d->hwirq / 32 * 4;
> +	val = readl_relaxed(reg);
> +	val &= ~(1 << d->hwirq % 32);
> +	writel_relaxed(val, reg);
> +	raw_spin_unlock(&cd->rlock);
> +
> +	irq_chip_unmask_parent(d);
> +}
> +
> +static void imx_gpcv2_irq_mask(struct irq_data *d) {
> +	struct gpcv2_irqchip_data *cd = d->chip_data;
> +	void __iomem *reg;
> +	u32 val;
> +
> +	raw_spin_lock(&cd->rlock);
> +	reg = cd->gpc_base + cd->cpu2wakeup + d->hwirq / 32 * 4;
> +	val = readl_relaxed(reg);
> +	val |= 1 << (d->hwirq % 32);
> +	writel_relaxed(val, reg);
> +	raw_spin_unlock(&cd->rlock);
> +
> +	irq_chip_mask_parent(d);
> +}
> +
> +static struct irq_chip gpcv2_irqchip_data_chip = {
> +	.name			= "GPCv2",
> +	.irq_eoi		= irq_chip_eoi_parent,
> +	.irq_mask		= imx_gpcv2_irq_mask,
> +	.irq_unmask		= imx_gpcv2_irq_unmask,
> +	.irq_set_wake		= imx_gpcv2_irq_set_wake,
> +	.irq_retrigger		= irq_chip_retrigger_hierarchy,
> +#ifdef CONFIG_SMP
> +	.irq_set_affinity	= irq_chip_set_affinity_parent,
> +#endif
> +};
> +
> +static int imx_gpcv2_domain_xlate(struct irq_domain *domain,
> +				struct device_node *controller,
> +				const u32 *intspec,
> +				unsigned int intsize,
> +				unsigned long *out_hwirq,
> +				unsigned int *out_type)
> +{
> +	/* Shouldn't happen, really... */
> +	if (domain->of_node != controller)
> +		return -EINVAL;
> +
> +	/* Not GIC compliant */
> +	if (intsize != 3)
> +		return -EINVAL;
> +
> +	/* No PPI should point to this domain */
> +	if (intspec[0] != 0)
> +		return -EINVAL;
> +
> +	*out_hwirq = intspec[1];
> +	*out_type = intspec[2];
> +	return 0;
> +}
> +
> +static int imx_gpcv2_domain_alloc(struct irq_domain *domain,
> +				  unsigned int irq, unsigned int nr_irqs,
> +				  void *data)
> +{
> +	struct of_phandle_args *args = data;
> +	struct of_phandle_args parent_args;
> +	irq_hw_number_t hwirq;
> +	int i;
> +
> +	/* Not GIC compliant */
> +	if (args->args_count != 3)
> +		return -EINVAL;
> +
> +	/* No PPI should point to this domain */
> +	if (args->args[0] != 0)
> +		return -EINVAL;
> +
> +	/* Can't deal with this */
> +	hwirq = args->args[1];
> +	if (hwirq >= GPC_MAX_IRQS)
> +		return -EINVAL;
> +
> +	for (i = 0; i < nr_irqs; i++) {
> +		irq_domain_set_hwirq_and_chip(domain, irq + i, hwirq + i,
> +				&gpcv2_irqchip_data_chip, domain->host_data);
> +	}
> +
> +	parent_args = *args;
> +	parent_args.np = domain->parent->of_node;
> +	return irq_domain_alloc_irqs_parent(domain, irq, nr_irqs,
> +&parent_args); }
> +
> +static struct irq_domain_ops gpcv2_irqchip_data_domain_ops = {
> +	.xlate	= imx_gpcv2_domain_xlate,
> +	.alloc	= imx_gpcv2_domain_alloc,
> +	.free	= irq_domain_free_irqs_common,
> +};
> +
> +static int __init imx_gpcv2_irqchip_init(struct device_node *node,
> +			       struct device_node *parent)
> +{
> +	struct irq_domain *parent_domain, *domain;
> +	struct gpcv2_irqchip_data *cd;
> +	int i;
> +
> +	if (!parent) {
> +		pr_err("%s: no parent, giving up\n", node->full_name);
> +		return -ENODEV;
> +	}
> +
> +	parent_domain = irq_find_host(parent);
> +	if (!parent_domain) {
> +		pr_err("%s: unable to get parent domain\n", node->full_name);
> +		return -ENXIO;
> +	}
> +
> +	cd = kzalloc(sizeof(struct gpcv2_irqchip_data), GFP_KERNEL);
> +	BUG_ON(!cd);
> +
> +	cd->gpc_base = of_iomap(node, 0);
> +	if (!cd->gpc_base) {
> +		pr_err("fsl-gpcv2: unable to map gpc registers\n");
> +		kfree(cd);
> +		return -ENOMEM;
> +	}
> +
> +	domain = irq_domain_add_hierarchy(parent_domain, 0, GPC_MAX_IRQS,
> +				node, &gpcv2_irqchip_data_domain_ops, cd);
> +	if (!domain) {
> +		iounmap(cd->gpc_base);
> +		kfree(cd);
> +		return -ENOMEM;
> +	}
> +	irq_set_default_host(domain);
> +
> +	/* Initially mask all interrupts */
> +	for (i = 0; i < IMR_NUM; i++) {
> +		writel_relaxed(~0, cd->gpc_base + GPC_IMR1_CORE0 + i * 4);
> +		writel_relaxed(~0, cd->gpc_base + GPC_IMR1_CORE1 + i * 4);
> +		cd->wakeup_sources[i] = ~0;
> +	}
> +
> +	/* Let CORE0 as the default CPU to wake up by GPC */
> +	cd->cpu2wakeup = GPC_IMR1_CORE0;
> +
> +	/*
> +	 * Due to hardware design failure, need to make sure GPR
> +	 * interrupt(#32) is unmasked during RUN mode to avoid entering
> +	 * DSM by mistake.
> +	 */
> +	writel_relaxed(~0x1, cd->gpc_base + cd->cpu2wakeup);
> +
> +	imx_gpcv2_instance = cd;
> +	register_syscore_ops(&imx_gpcv2_syscore_ops);
> +
> +	return 0;
> +}
> +
> +IRQCHIP_DECLARE(imx_gpcv2, "fsl,imx7d-gpc", imx_gpcv2_irqchip_init);
> --
> 2.5.0.rc2
> 
> 
> --
> To unsubscribe from this list: send the line "unsubscribe linux-kernel" in
> the body of a message to majordomo at vger.kernel.org
> More majordomo info at  http://vger.kernel.org/majordomo-info.html
> Please read the FAQ at  http://www.tux.org/lkml/

From Shenwei.Wang at freescale.com  Fri Aug 21 06:45:28 2015
From: Shenwei.Wang at freescale.com (Shenwei Wang)
Date: Fri, 21 Aug 2015 13:45:28 +0000
Subject: [PATCH v8 2/2] ARM: imx: support suspend states on imx7D
In-Reply-To: <1438378439-11569-3-git-send-email-shenwei.wang@freescale.com>
References: <1438378439-11569-1-git-send-email-shenwei.wang@freescale.com>
 <1438378439-11569-3-git-send-email-shenwei.wang@freescale.com>
Message-ID: <CY1PR0301MB0843CCDFD7C0E4AAC338622483650@CY1PR0301MB0843.namprd03.prod.outlook.com>

Ping.

Shenwei

> -----Original Message-----
> From: linux-kernel-owner at vger.kernel.org
> [mailto:linux-kernel-owner at vger.kernel.org] On Behalf Of Shenwei Wang
> Sent: 2015?7?31? 16:34
> To: shawn.guo at linaro.org; tglx at linutronix.de; jason at lakedaemon.net
> Cc: linux-arm-kernel at lists.infradead.org; linux-kernel at vger.kernel.org; Huang
> Yongcai-B20788
> Subject: [PATCH v8 2/2] ARM: imx: support suspend states on imx7D
> 
> IMX7D contains a new version of GPC IP block (GPCv2). It has two major functions:
> power management and wakeup source management.
> 
> GPCv2 provides low power mode control for Cortex-A7 and Cortex-M4 domains.
> And it can support WAIT, STOP, and DSM(Deep Sleep Mode) modes.
> After configuring the GPCv2 module, the platform can enter into a selected mode
> either automatically triggered by ARM WFI instruction or manually by software.
> The system will exit the low power states by the predefined wakeup sources
> which are managed by the gpcv2 irqchip driver.
> 
> This patch adds a new suspend driver to manage the power states on IMX7D.
> It currently supports "SUSPEND_STANDBY" and "SUSPEND_MEM" states.
> 
> Signed-off-by: Shenwei Wang <shenwei.wang at freescale.com>
> Signed-off-by: Anson Huang <b20788 at freescale.com>
> ---
>  arch/arm/mach-imx/Kconfig        |   1 +
>  arch/arm/mach-imx/Makefile       |   2 +
>  arch/arm/mach-imx/common.h       |   4 +
>  arch/arm/mach-imx/pm-imx7.c      | 917
> +++++++++++++++++++++++++++++++++++++++
>  arch/arm/mach-imx/suspend-imx7.S | 529 ++++++++++++++++++++++
>  5 files changed, 1453 insertions(+)
>  create mode 100644 arch/arm/mach-imx/pm-imx7.c  create mode 100644
> arch/arm/mach-imx/suspend-imx7.S
> 
> diff --git a/arch/arm/mach-imx/Kconfig b/arch/arm/mach-imx/Kconfig index
> 8ceda28..54f8553 100644
> --- a/arch/arm/mach-imx/Kconfig
> +++ b/arch/arm/mach-imx/Kconfig
> @@ -562,6 +562,7 @@ config SOC_IMX7D
>  	select ARM_GIC
>  	select HAVE_IMX_ANATOP
>  	select HAVE_IMX_MMDC
> +	select IMX_GPCV2
>  	help
>  		This enables support for Freescale i.MX7 Dual processor.
> 
> diff --git a/arch/arm/mach-imx/Makefile b/arch/arm/mach-imx/Makefile index
> fb689d8..60f13fd 100644
> --- a/arch/arm/mach-imx/Makefile
> +++ b/arch/arm/mach-imx/Makefile
> @@ -88,6 +88,8 @@ obj-$(CONFIG_SOC_IMX7D) += mach-imx7d.o
> 
>  ifeq ($(CONFIG_SUSPEND),y)
>  AFLAGS_suspend-imx6.o :=-Wa,-march=armv7-a
> +AFLAGS_suspend-imx7.o :=-Wa,-march=armv7-a
> +obj-$(CONFIG_SOC_IMX7D)	+= suspend-imx7.o pm-imx7.o
>  obj-$(CONFIG_SOC_IMX6) += suspend-imx6.o
>  obj-$(CONFIG_SOC_IMX53) += suspend-imx53.o  endif diff --git
> a/arch/arm/mach-imx/common.h b/arch/arm/mach-imx/common.h index
> 21e4e86..c5767f4 100644
> --- a/arch/arm/mach-imx/common.h
> +++ b/arch/arm/mach-imx/common.h
> @@ -126,6 +126,10 @@ static const u32 imx53_suspend_sz;  static inline void
> imx6_suspend(void __iomem *ocram_vbase) {}  #endif
> 
> +void ca7_cpu_resume(void);
> +void imx7_suspend(void __iomem *ocram_vbase);
> +u32 imx_gpcv2_get_wakeup_source(u32 **sources);
> +
>  void imx6_pm_ccm_init(const char *ccm_compat);  void imx6q_pm_init(void);
> void imx6dl_pm_init(void); diff --git a/arch/arm/mach-imx/pm-imx7.c
> b/arch/arm/mach-imx/pm-imx7.c new file mode 100644 index 0000000..052c2cb
> --- /dev/null
> +++ b/arch/arm/mach-imx/pm-imx7.c
> @@ -0,0 +1,917 @@
> +/*
> + * Copyright (C) 2015 Freescale Semiconductor, Inc.
> + *
> + * This program is free software; you can redistribute it and/or modify
> + * it under the terms of the GNU General Public License version 2 as
> + * published by the Free Software Foundation.
> + */
> +
> +#include <linux/mfd/syscon.h>
> +#include <linux/of_address.h>
> +#include <linux/of_irq.h>
> +#include <linux/regmap.h>
> +#include <linux/suspend.h>
> +#include <linux/slab.h>
> +#include <asm/suspend.h>
> +#include <asm/fncpy.h>
> +
> +#include "common.h"
> +
> +#define GPC_LPCR_A7_BSC		0x0
> +#define GPC_LPCR_A7_AD		0x4
> +#define GPC_LPCR_M4		0x8
> +
> +#define GPC_SLPCR		0x14
> +#define GPC_PGC_ACK_SEL_A7	0x24
> +
> +#define GPC_SLOTx_CFG(x) 	(0xb0 + 4 * (x))
> +
> +#define GPC_PGC_CPU_MAPPING	0xec
> +
> +#define GPC_PGC_C0		0x800
> +#define GPC_PGC_C1		0x840
> +#define GPC_PGC_SCU		0x880
> +#define GPC_PGC_SCU_TIMING	0x890
> +#define GPC_PGC_FM		0xa00
> +#define GPC_PGC_MIPI_PHY	0xc00
> +#define GPC_PGC_PCIE_PHY	0xc40
> +#define GPC_PGC_USB_OTG1_PHY	0xc80
> +#define GPC_PGC_USB_OTG2_PHY	0xcc0
> +#define GPC_PGC_USB_HSIC_PHY	0xd00
> +
> +#define ANADIG_ARM_PLL		0x60
> +#define ANADIG_DDR_PLL		0x70
> +#define ANADIG_SYS_PLL		0xb0
> +#define ANADIG_ENET_PLL		0xe0
> +#define ANADIG_AUDIO_PLL	0xf0
> +#define ANADIG_VIDEO_PLL	0x130
> +
> +#define BM_LPCR_A7_AD_L2PGE			(0x1 << 16)
> +#define BM_LPCR_A7_AD_EN_C1_PUP			(0x1 << 11)
> +#define BM_LPCR_A7_AD_EN_C1_IRQ_PUP		(0x1 << 10)
> +#define BM_LPCR_A7_AD_EN_C0_PUP			(0x1 << 9)
> +#define BM_LPCR_A7_AD_EN_C0_IRQ_PUP		(0x1 << 8)
> +#define BM_LPCR_A7_AD_EN_PLAT_PDN		(0x1 << 4)
> +#define BM_LPCR_A7_AD_EN_C1_PDN			(0x1 << 3)
> +#define BM_LPCR_A7_AD_EN_C1_WFI_PDN		(0x1 << 2)
> +#define BM_LPCR_A7_AD_EN_C0_PDN			(0x1 << 1)
> +#define BM_LPCR_A7_AD_EN_C0_WFI_PDN		(0x1)
> +
> +#define BM_LPCR_A7_BSC_IRQ_SRC_A7_WAKEUP	(0x7 << 28)
> +#define BM_LPCR_A7_BSC_CPU_CLK_ON_LPM		(0x1 << 14)
> +#define BM_LPCR_A7_BSC_LPM1			(0x3 << 2)
> +#define BM_LPCR_A7_BSC_LPM0			(0x3)
> +
> +#define BM_LPCR_M4_MASK_DSM_TRIGGER		(0x1 << 31)
> +
> +#define BM_SLPCR_EN_DSM				(0x1 << 31)
> +#define BM_SLPCR_RBC_EN				(0x1 << 30)
> +#define BM_SLPCR_VSTBY				(0x1 << 2)
> +#define BM_SLPCR_SBYOS				(0x1 << 1)
> +#define BM_SLPCR_BYPASS_PMIC_READY		(0x1)
> +
> +#define BM_GPC_PGC_ACK_SEL_A7_DUMMY_PUP		(0x1 << 31)
> +#define BM_GPC_PGC_ACK_SEL_A7_DUMMY_PDN		(0x1 << 15)
> +
> +#define BM_ANADIG_ARM_PLL_OVERRIDE		(0x1 << 20)
> +#define BM_ANADIG_DDR_PLL_OVERRIDE		(0x1 << 19)
> +#define BM_ANADIG_SYS_PLL_PFDx_OVERRIDE		(0x1FF << 17)
> +#define BM_ANADIG_ENET_PLL_OVERRIDE		(0x1 << 13)
> +#define BM_ANADIG_AUDIO_PLL_OVERRIDE		(0x1 << 24)
> +#define BM_ANADIG_VIDEO_PLL_OVERRIDE		(0x1 << 24)
> +
> +#define A7_LPM_WAIT		0x5
> +#define A7_LPM_STOP		0xa
> +#define GPC_MAX_SLOT_NUMBER	10
> +
> +#define REG_SET			0x4
> +#define REG_CLR			0x8
> +
> +#define MX7_MAX_DDRC_NUM		32
> +#define MX7_MAX_DDRC_PHY_NUM		16
> +
> +#define READ_DATA_FROM_HARDWARE		0
> +#define MX7_SUSPEND_OCRAM_SIZE		0x1000
> +
> +enum gpcv2_mode {
> +	GPC_WAIT_CLOCKED,
> +	GPC_WAIT_UNCLOCKED,
> +	GPC_STOP_POWER_ON,
> +	GPC_STOP_POWER_OFF,
> +};
> +
> +/*
> + * GPCv2 has the following power domains, and each domain can be
> +power-up
> + * and power-down via GPC settings.
> + *
> + * 	Core 0 of A7 power domain
> + * 	Core1 of A7 power domain
> + * 	SCU/L2 cache RAM of A7 power domain
> + * 	Fastmix and megamix power domain
> + * 	USB OTG1 PHY power domain
> + * 	USB OTG2 PHY power domain
> + * 	PCIE PHY power domain
> + * 	USB HSIC PHY power domain
> + *	Core 0 of M4 power domain
> + */
> +
> +enum gpcv2_slot {
> +	CORE0_A7,
> +	CORE1_A7,
> +	SCU_A7,
> +	FAST_MEGA_MIX,
> +	MIPI_PHY,
> +	PCIE_PHY,
> +	USB_OTG1_PHY,
> +	USB_OTG2_PHY,
> +	USB_HSIC_PHY,
> +	CORE0_M4,
> +};
> +
> +struct imx_gpcv2;
> +
> +struct imx_gpcv2_suspend {
> +	void (*set_mode)(struct imx_gpcv2 *, enum gpcv2_mode mode);
> +	void (*lpm_cpu_power_gate)(struct imx_gpcv2 *, u32, bool);
> +	void (*lpm_plat_power_gate)(struct imx_gpcv2 *, bool);
> +	void (*lpm_env_setup)(struct imx_gpcv2 *);
> +	void (*lpm_env_clean)(struct imx_gpcv2 *);
> +
> +	void (*set_slot)(struct imx_gpcv2 *cd, u32 index,
> +			enum gpcv2_slot slot, bool mode);
> +	void (*set_act)(struct imx_gpcv2 *cd,
> +			enum gpcv2_slot slot, bool mode);
> +	void (*clear_slots)(struct imx_gpcv2 *);
> +	void (*lpm_enable_core)(struct imx_gpcv2 *,
> +			bool enable, u32 offset);
> +
> +	void (*standby)(struct imx_gpcv2 *);
> +	void (*suspend)(struct imx_gpcv2 *);
> +
> +	void (*suspend_fn_in_ocram)(void __iomem *ocram_vbase);
> +	void __iomem *ocram_vbase;
> +};
> +
> +struct imx_gpcv2 {
> +	u32 *wakeupmix_mask;
> +	u32 *lpsrmix_mask;
> +	u32 *mfmix_mask;
> +	spinlock_t lock;
> +
> +	struct imx_gpcv2_suspend *pm;
> +	struct regmap *anatop;
> +	struct regmap *gpcv2;
> +
> +	u32 (*get_wakeup_source)(u32 **);
> +};
> +
> +struct imx7_pm_base {
> +	phys_addr_t pbase;
> +	void __iomem *vbase;
> +};
> +
> +struct imx7_pm_socdata {
> +	u32 ddr_type;
> +	const char *ddrc_compat;
> +	const char *ddrc_phy_compat;
> +	const char *src_compat;
> +	const char *iomuxc_gpr_compat;
> +	const char *ccm_compat;
> +	const char *gpc_compat;
> +	const char *anatop_compat;
> +	const u32 ddrc_num;
> +	const u32 (*ddrc_offset)[2];
> +	const u32 ddrc_phy_num;
> +	const u32 (*ddrc_phy_offset)[2];
> +};
> +
> +/*
> + * This structure is for passing necessary data for low level ocram
> + * suspend code(arch/arm/mach-imx/suspend-imx7.S), if this struct
> + * definition is changed, the offset definition in
> + * arch/arm/mach-imx/suspend-imx7.S must be also changed accordingly,
> + * otherwise, the suspend to ocram function will be broken!
> + */
> +
> +struct imx7_cpu_pm_info {
> +	u32 m4_reserve0;
> +	u32 m4_reserve1;
> +	u32 m4_reserve2;
> +
> +	/* The physical address of pm_info. */
> +	phys_addr_t pbase;
> +
> +	/* The physical resume address for asm code */
> +	phys_addr_t resume_addr;
> +	u32 ddr_type;
> +
> +	u32 pm_info_size;
> +
> +	struct imx7_pm_base ddrc_base;
> +	struct imx7_pm_base ddrc_phy_base;
> +	struct imx7_pm_base src_base;
> +	struct imx7_pm_base iomuxc_gpr_base;
> +	struct imx7_pm_base ccm_base;
> +	struct imx7_pm_base gpc_base;
> +	struct imx7_pm_base l2_base;
> +	struct imx7_pm_base anatop_base;
> +
> +	u32 ttbr1;
> +
> +	/* Number of DDRC which need saved/restored. */
> +	u32 ddrc_num;
> +
> +	/* To save offset and value */
> +	u32 ddrc_val[MX7_MAX_DDRC_NUM][2];
> +
> +	/* Number of DDRC which need saved/restored. */
> +	u32 ddrc_phy_num;
> +
> +	/* To save offset and value */
> +	u32 ddrc_phy_val[MX7_MAX_DDRC_NUM][2];
> +} __aligned(8);
> +
> +static const u32 imx7d_ddrc_ddr3_setting[][2] __initconst = {
> +	{ 0x0, READ_DATA_FROM_HARDWARE },
> +	{ 0x1a0, READ_DATA_FROM_HARDWARE },
> +	{ 0x1a4, READ_DATA_FROM_HARDWARE },
> +	{ 0x1a8, READ_DATA_FROM_HARDWARE },
> +	{ 0x64, READ_DATA_FROM_HARDWARE },
> +	{ 0x490, 0x00000001 },
> +	{ 0xd0, 0xc0020001 },
> +	{ 0xd4, READ_DATA_FROM_HARDWARE },
> +	{ 0xdc, READ_DATA_FROM_HARDWARE },
> +	{ 0xe0, READ_DATA_FROM_HARDWARE },
> +	{ 0xe4, READ_DATA_FROM_HARDWARE },
> +	{ 0xf4, READ_DATA_FROM_HARDWARE },
> +	{ 0x100, READ_DATA_FROM_HARDWARE },
> +	{ 0x104, READ_DATA_FROM_HARDWARE },
> +	{ 0x108, READ_DATA_FROM_HARDWARE },
> +	{ 0x10c, READ_DATA_FROM_HARDWARE },
> +	{ 0x110, READ_DATA_FROM_HARDWARE },
> +	{ 0x114, READ_DATA_FROM_HARDWARE },
> +	{ 0x120, 0x03030803 },
> +	{ 0x180, READ_DATA_FROM_HARDWARE },
> +	{ 0x190, READ_DATA_FROM_HARDWARE },
> +	{ 0x194, READ_DATA_FROM_HARDWARE },
> +	{ 0x200, READ_DATA_FROM_HARDWARE },
> +	{ 0x204, READ_DATA_FROM_HARDWARE },
> +	{ 0x214, READ_DATA_FROM_HARDWARE },
> +	{ 0x218, READ_DATA_FROM_HARDWARE },
> +	{ 0x240, 0x06000601 },
> +	{ 0x244, READ_DATA_FROM_HARDWARE },
> +};
> +
> +static const u32 imx7d_ddrc_phy_ddr3_setting[][2] __initconst = {
> +	{ 0x0, READ_DATA_FROM_HARDWARE },
> +	{ 0x4, READ_DATA_FROM_HARDWARE },
> +	{ 0x10, READ_DATA_FROM_HARDWARE },
> +	{ 0x9c, READ_DATA_FROM_HARDWARE },
> +	{ 0x20, READ_DATA_FROM_HARDWARE },
> +	{ 0x30, READ_DATA_FROM_HARDWARE },
> +	{ 0x50, 0x01000010 },
> +	{ 0x50, 0x00000010 },
> +	{ 0xc0, 0x0e407304 },
> +	{ 0xc0, 0x0e447304 },
> +	{ 0xc0, 0x0e447306 },
> +	{ 0xc0, 0x0e447304 },
> +	{ 0xc0, 0x0e407306 },
> +};
> +
> +static const struct imx7_pm_socdata imx7d_pm_data_ddr3 __initconst = {
> +	.iomuxc_gpr_compat = "fsl,imx7d-iomuxc",
> +	.ddrc_phy_compat = "fsl,imx7d-ddrc-phy",
> +	.anatop_compat = "fsl,imx7d-anatop",
> +	.ddrc_compat = "fsl,imx7d-ddrc",
> +	.ccm_compat = "fsl,imx7d-ccm",
> +	.src_compat = "fsl,imx7d-src",
> +	.gpc_compat = "fsl,imx7d-gpc",
> +	.ddrc_phy_num = ARRAY_SIZE(imx7d_ddrc_phy_ddr3_setting),
> +	.ddrc_phy_offset = imx7d_ddrc_phy_ddr3_setting,
> +	.ddrc_num = ARRAY_SIZE(imx7d_ddrc_ddr3_setting),
> +	.ddrc_offset = imx7d_ddrc_ddr3_setting, };
> +
> +static struct imx_gpcv2 *gpcv2_instance;
> +
> +static void imx_gpcv2_lpm_clear_slots(struct imx_gpcv2 *gpc) {
> +	int i;
> +
> +	for (i = 0; i < GPC_MAX_SLOT_NUMBER; i++)
> +		regmap_write(gpc->gpcv2, GPC_SLOTx_CFG(i), 0x0);
> +
> +	regmap_write(gpc->gpcv2, GPC_PGC_ACK_SEL_A7,
> +			BM_GPC_PGC_ACK_SEL_A7_DUMMY_PUP |
> +			BM_GPC_PGC_ACK_SEL_A7_DUMMY_PDN);
> +}
> +
> +static void imx_gpcv2_lpm_enable_core(struct imx_gpcv2 *gpc,
> +			bool enable, u32 offset)
> +{
> +	regmap_write(gpc->gpcv2, offset, enable); }
> +
> +static void imx_gpcv2_lpm_slot_setup(struct imx_gpcv2 *gpc,
> +		u32 index, enum gpcv2_slot slot, bool powerup) {
> +	u32 val;
> +
> +	if (index >= GPC_MAX_SLOT_NUMBER) {
> +		pr_err("Invalid slot index!\n");
> +		return;
> +	}
> +
> +	val = (powerup ? 0x2 : 0x1) << (slot * 2);
> +	regmap_write(gpc->gpcv2, GPC_SLOTx_CFG(index), val); }
> +
> +static void imx_gpcv2_lpm_set_ack(struct imx_gpcv2 *gpc,
> +		enum gpcv2_slot slot, bool powerup)
> +{
> +	u32 val;
> +
> +	regmap_read(gpc->gpcv2, GPC_PGC_ACK_SEL_A7, &val);
> +
> +	/* clear dummy ack */
> +	val &= ~(powerup ? BM_GPC_PGC_ACK_SEL_A7_DUMMY_PUP :
> +				BM_GPC_PGC_ACK_SEL_A7_DUMMY_PDN);
> +
> +	val |= 1 << (slot + (powerup ? 16 : 0));
> +	regmap_write(gpc->gpcv2, GPC_PGC_ACK_SEL_A7, val); }
> +
> +static void imx_gpcv2_lpm_env_setup(struct imx_gpcv2 *gpc) {
> +	/* PLL and PFDs overwrite set */
> +	regmap_write(gpc->anatop, ANADIG_ARM_PLL + REG_SET,
> +			BM_ANADIG_ARM_PLL_OVERRIDE);
> +	regmap_write(gpc->anatop, ANADIG_DDR_PLL + REG_SET,
> +			BM_ANADIG_DDR_PLL_OVERRIDE);
> +	regmap_write(gpc->anatop, ANADIG_SYS_PLL + REG_SET,
> +			BM_ANADIG_SYS_PLL_PFDx_OVERRIDE);
> +	regmap_write(gpc->anatop, ANADIG_ENET_PLL + REG_SET,
> +			BM_ANADIG_ENET_PLL_OVERRIDE);
> +	regmap_write(gpc->anatop, ANADIG_AUDIO_PLL + REG_SET,
> +			BM_ANADIG_AUDIO_PLL_OVERRIDE);
> +	regmap_write(gpc->anatop, ANADIG_VIDEO_PLL + REG_SET,
> +			BM_ANADIG_VIDEO_PLL_OVERRIDE);
> +}
> +
> +static void imx_gpcv2_lpm_env_clean(struct imx_gpcv2 *gpc) {
> +	/* PLL and PFDs overwrite clear */
> +	regmap_write(gpc->anatop, ANADIG_ARM_PLL + REG_CLR,
> +			BM_ANADIG_ARM_PLL_OVERRIDE);
> +	regmap_write(gpc->anatop, ANADIG_DDR_PLL + REG_CLR,
> +			BM_ANADIG_DDR_PLL_OVERRIDE);
> +	regmap_write(gpc->anatop, ANADIG_SYS_PLL + REG_CLR,
> +			BM_ANADIG_SYS_PLL_PFDx_OVERRIDE);
> +	regmap_write(gpc->anatop, ANADIG_ENET_PLL + REG_CLR,
> +			BM_ANADIG_ENET_PLL_OVERRIDE);
> +	regmap_write(gpc->anatop, ANADIG_AUDIO_PLL + REG_CLR,
> +			BM_ANADIG_AUDIO_PLL_OVERRIDE);
> +	regmap_write(gpc->anatop, ANADIG_VIDEO_PLL + REG_CLR,
> +			BM_ANADIG_VIDEO_PLL_OVERRIDE);
> +}
> +
> +static void imx_gpcv2_lpm_set_mode(struct imx_gpcv2 *gpc,
> +		enum gpcv2_mode mode)
> +{
> +	u32 lpcr, slpcr;
> +
> +	regmap_read(gpc->gpcv2, GPC_LPCR_A7_BSC, &lpcr);
> +	regmap_read(gpc->gpcv2, GPC_SLPCR, &slpcr);
> +
> +	/* all cores' LPM settings must be same */
> +	lpcr &= ~(BM_LPCR_A7_BSC_LPM0 | BM_LPCR_A7_BSC_LPM1);
> +	lpcr |= BM_LPCR_A7_BSC_CPU_CLK_ON_LPM;
> +
> +	slpcr &= ~(BM_SLPCR_EN_DSM | BM_SLPCR_VSTBY | BM_SLPCR_RBC_EN
> |
> +		BM_SLPCR_SBYOS | BM_SLPCR_BYPASS_PMIC_READY);
> +
> +	switch (mode) {
> +	case GPC_WAIT_CLOCKED:
> +		break;
> +	case GPC_WAIT_UNCLOCKED:
> +		lpcr |= A7_LPM_WAIT;
> +		lpcr &= ~BM_LPCR_A7_BSC_CPU_CLK_ON_LPM;
> +		break;
> +	case GPC_STOP_POWER_ON:
> +		lpcr |= A7_LPM_STOP;
> +		lpcr &= ~BM_LPCR_A7_BSC_CPU_CLK_ON_LPM;
> +		slpcr |= (BM_SLPCR_EN_DSM | BM_SLPCR_RBC_EN |
> +			BM_SLPCR_BYPASS_PMIC_READY);
> +		break;
> +	case GPC_STOP_POWER_OFF:
> +		lpcr |= A7_LPM_STOP;
> +		lpcr &= ~BM_LPCR_A7_BSC_CPU_CLK_ON_LPM;
> +		slpcr |= (BM_SLPCR_EN_DSM | BM_SLPCR_RBC_EN |
> +			BM_SLPCR_SBYOS | BM_SLPCR_VSTBY  |
> +			BM_SLPCR_BYPASS_PMIC_READY);
> +		break;
> +	default:
> +		return;
> +	}
> +	regmap_write(gpc->gpcv2, GPC_LPCR_A7_BSC, lpcr);
> +	regmap_write(gpc->gpcv2, GPC_SLPCR, slpcr); }
> +
> +static void imx_gpcv2_lpm_cpu_power_gate(struct imx_gpcv2 *gpc,
> +				u32 cpu, bool engate)
> +{
> +	u32 val;
> +
> +	const u32 val_pdn[2] = {
> +		BM_LPCR_A7_AD_EN_C0_PDN | BM_LPCR_A7_AD_EN_C0_PUP,
> +		BM_LPCR_A7_AD_EN_C1_PDN | BM_LPCR_A7_AD_EN_C1_PUP,
> +	};
> +
> +	regmap_read(gpc->gpcv2, GPC_LPCR_A7_AD, &val);
> +	if (engate)
> +		val |= val_pdn[cpu];
> +	else
> +		val &= ~val_pdn[cpu];
> +
> +	regmap_write(gpc->gpcv2, GPC_LPCR_A7_AD, val); }
> +
> +static void imx_lpm_plat_power_gate(struct imx_gpcv2 *gpc, bool engate)
> +{
> +	u32 val;
> +
> +	regmap_read(gpc->gpcv2, GPC_LPCR_A7_AD, &val);
> +	val &= ~(BM_LPCR_A7_AD_EN_PLAT_PDN | BM_LPCR_A7_AD_L2PGE);
> +	if (engate)
> +		val |= BM_LPCR_A7_AD_EN_PLAT_PDN | BM_LPCR_A7_AD_L2PGE;
> +
> +	regmap_write(gpc->gpcv2, GPC_LPCR_A7_AD, val); }
> +
> +static void imx_gpcv2_lpm_standby(struct imx_gpcv2 *gpc) {
> +	struct imx_gpcv2_suspend *pm = gpc->pm;
> +
> +	pm->lpm_env_setup(gpc);
> +	/* pm->set_mode(gpc, GPC_STOP_POWER_OFF); */
> +	pm->set_mode(gpc, GPC_WAIT_UNCLOCKED);
> +
> +	/* Zzz ... */
> +	cpu_do_idle();
> +
> +	pm->set_mode(gpc, GPC_WAIT_CLOCKED);
> +	pm->lpm_env_clean(gpc);
> +}
> +
> +static int gpcv2_suspend_finish(unsigned long val) {
> +	struct imx_gpcv2_suspend *pm = (struct imx_gpcv2_suspend *)val;
> +
> +	if (!pm->suspend_fn_in_ocram) {
> +		cpu_do_idle();
> +	} else {
> +		/*
> +		 * call low level suspend function in ocram,
> +		 * as we need to float DDR IO.
> +		 */
> +		local_flush_tlb_all();
> +		pm->suspend_fn_in_ocram(pm->ocram_vbase);
> +	}
> +
> +	return 0;
> +}
> +
> +static void imx_gpcv2_lpm_suspend(struct imx_gpcv2 *gpc) {
> +	struct imx_gpcv2_suspend *pm = gpc->pm;
> +	u32 *sources;
> +	int i, num;
> +
> +	pm->lpm_env_setup(gpc);
> +	pm->set_mode(gpc, GPC_STOP_POWER_OFF);
> +
> +	/* enable core0 power down/up with low power mode */
> +	pm->lpm_cpu_power_gate(gpc, 0, true);
> +
> +	/* enable plat power down with low power mode */
> +	pm->lpm_plat_power_gate(gpc, true);
> +
> +	/*
> +	 * To avoid confuse, we use slot 0~4 for power down,
> +	 * slot 5~9 for power up.
> +	 *
> +	 * Power down slot sequence:
> +	 * Slot0 -> CORE0
> +	 * Slot1 -> Mega/Fast MIX
> +	 * Slot2 -> SCU
> +	 *
> +	 * Power up slot sequence:
> +	 * Slot5 -> Mega/Fast MIX
> +	 * Slot6 -> SCU
> +	 * Slot7 -> CORE0
> +	 */
> +	pm->set_slot(gpc, 0, CORE0_A7, false);
> +	pm->set_slot(gpc, 2, SCU_A7, false);
> +
> +	if (gpc->get_wakeup_source) {
> +		pm->set_slot(gpc, 1, FAST_MEGA_MIX, false);
> +		pm->set_slot(gpc, 5, FAST_MEGA_MIX, true);
> +		pm->lpm_enable_core(gpc, true, GPC_PGC_FM);
> +		num = gpc->get_wakeup_source(&sources);
> +		for (i = 0; i < num; i++) {
> +			if ((~sources[i] & gpc->mfmix_mask[i]) == 0)
> +				continue;
> +			pm->lpm_enable_core(gpc, false, GPC_PGC_FM);
> +			break;
> +		}
> +	}
> +
> +	pm->set_slot(gpc, 6, SCU_A7, true);
> +	pm->set_slot(gpc, 7, CORE0_A7, true);
> +
> +	/* Set Power down act */
> +	pm->set_act(gpc, SCU_A7, false);
> +
> +	/* Set Power up act */
> +	pm->set_act(gpc, CORE0_A7, true);
> +
> +	/* enable core0, scu */
> +	pm->lpm_enable_core(gpc, true, GPC_PGC_C0);
> +	pm->lpm_enable_core(gpc, true, GPC_PGC_SCU);
> +
> +	cpu_suspend((unsigned long)pm, gpcv2_suspend_finish);
> +
> +	pm->lpm_env_clean(gpc);
> +	pm->set_mode(gpc, GPC_WAIT_CLOCKED);
> +	pm->lpm_cpu_power_gate(gpc, 0, false);
> +	pm->lpm_plat_power_gate(gpc, false);
> +
> +	pm->lpm_enable_core(gpc, false, GPC_PGC_C0);
> +	pm->lpm_enable_core(gpc, false, GPC_PGC_SCU);
> +	pm->lpm_enable_core(gpc, false, GPC_PGC_FM);
> +	pm->clear_slots(gpc);
> +}
> +
> +static int imx_gpcv2_pm_enter(suspend_state_t state) {
> +	struct imx_gpcv2_suspend *pm;
> +
> +	BUG_ON(!gpcv2_instance);
> +	pm = gpcv2_instance->pm;
> +
> +	switch (state) {
> +	case PM_SUSPEND_STANDBY:
> +		pm->standby(gpcv2_instance);
> +		break;
> +
> +	case PM_SUSPEND_MEM:
> +		pm->suspend(gpcv2_instance);
> +		break;
> +	default:
> +		return -EINVAL;
> +	}
> +
> +	return 0;
> +}
> +
> +static int imx_gpcv2_pm_valid(suspend_state_t state) {
> +	return state == PM_SUSPEND_MEM || state == PM_SUSPEND_STANDBY; }
> +
> +static int __init imx_get_base_from_node(struct device_node *node,
> +			struct imx7_pm_base *base)
> +{
> +	struct resource res;
> +	int ret = 0;
> +
> +	ret = of_address_to_resource(node, 0, &res);
> +	if (ret)
> +		goto put_node;
> +
> +	base->pbase = res.start;
> +	base->vbase = ioremap(res.start, resource_size(&res));
> +	if (!base->vbase) {
> +		iounmap(base->vbase);
> +		ret = -ENOMEM;
> +	}
> +put_node:
> +	of_node_put(node);
> +
> +	return ret;
> +}
> +
> +static int __init imx_get_base_from_dt(struct imx7_pm_base *base,
> +				const char *compat)
> +{
> +	struct device_node *node;
> +	struct resource res;
> +	int ret = 0;
> +
> +	node = of_find_compatible_node(NULL, NULL, compat);
> +	if (!node) {
> +		ret = -ENODEV;
> +		goto out;
> +	}
> +
> +	ret = of_address_to_resource(node, 0, &res);
> +	if (ret)
> +		goto put_node;
> +
> +	base->pbase = res.start;
> +	base->vbase = ioremap(res.start, resource_size(&res));
> +	if (!base->vbase)
> +		ret = -ENOMEM;
> +
> +put_node:
> +	of_node_put(node);
> +out:
> +	return ret;
> +}
> +
> +static int __init imx_get_exec_base_from_dt(struct imx7_pm_base *base,
> +				const char *compat)
> +{
> +	struct device_node *node;
> +	struct resource res;
> +	int ret = 0;
> +
> +	node = of_find_compatible_node(NULL, NULL, compat);
> +	if (!node) {
> +		ret = -ENODEV;
> +		goto out;
> +	}
> +
> +	ret = of_address_to_resource(node, 0, &res);
> +	if (ret)
> +		goto put_node;
> +
> +	base->pbase = res.start;
> +	base->vbase = __arm_ioremap_exec(res.start, resource_size(&res),
> +false);
> +
> +	if (!base->vbase)
> +		ret = -ENOMEM;
> +
> +put_node:
> +	of_node_put(node);
> +out:
> +	return ret;
> +}
> +
> +static int __init imx_gpcv2_suspend_init(struct imx_gpcv2_suspend *pm,
> +			const struct imx7_pm_socdata *socdata) {
> +	struct imx7_pm_base aips_base[3] = { {0, 0}, {0, 0}, {0, 0} };
> +	struct imx7_pm_base sram_base = {0, 0};
> +	struct imx7_cpu_pm_info *pm_info;
> +	struct device_node *node = NULL;
> +	int i, ret = 0;
> +
> +	const u32 (*ddrc_phy_offset_array)[2];
> +	const u32 (*ddrc_offset_array)[2];
> +
> +	if (!socdata || !pm) {
> +		pr_warn("%s: invalid argument!\n", __func__);
> +		return -EINVAL;
> +	}
> +
> +	for (i = 0; i < 3; i++) {
> +		node = of_find_compatible_node(node, NULL, "fsl,aips-bus");
> +		if (!node) {
> +			pr_warn("%s: failed to find aips %d node!\n",
> +					__func__, i);
> +			break;
> +		}
> +		ret = imx_get_base_from_node(node, &aips_base[i]);
> +		if (ret) {
> +			pr_warn("%s: failed to get aips[%d] base %d!\n",
> +					__func__, i, ret);
> +		}
> +	}
> +
> +	ret = imx_get_exec_base_from_dt(&sram_base, "fsl,lpm-sram");
> +	if (ret) {
> +		pr_warn("%s: failed to get lpm-sram base %d!\n",
> +				__func__, ret);
> +		goto lpm_sram_map_failed;
> +	}
> +
> +	pm_info = sram_base.vbase;
> +	pm_info->pbase = sram_base.pbase;
> +	pm_info->resume_addr = virt_to_phys(ca7_cpu_resume);
> +	pm_info->pm_info_size = sizeof(*pm_info);
> +
> +	ret = imx_get_base_from_dt(&pm_info->ccm_base,
> socdata->ccm_compat);
> +	if (ret) {
> +		pr_warn("%s: failed to get ccm base %d!\n", __func__, ret);
> +		goto ccm_map_failed;
> +	}
> +
> +	ret = imx_get_base_from_dt(&pm_info->ddrc_base,
> socdata->ddrc_compat);
> +	if (ret) {
> +		pr_warn("%s: failed to get ddrc base %d!\n", __func__, ret);
> +		goto ddrc_map_failed;
> +	}
> +
> +	ret = imx_get_base_from_dt(&pm_info->ddrc_phy_base,
> +				socdata->ddrc_phy_compat);
> +	if (ret) {
> +		pr_warn("%s: failed to get ddrc_phy base %d!\n", __func__, ret);
> +		goto ddrc_phy_map_failed;
> +	}
> +
> +	ret = imx_get_base_from_dt(&pm_info->src_base, socdata->src_compat);
> +	if (ret) {
> +		pr_warn("%s: failed to get src base %d!\n", __func__, ret);
> +		goto src_map_failed;
> +	}
> +
> +	ret = imx_get_base_from_dt(&pm_info->iomuxc_gpr_base,
> +				socdata->iomuxc_gpr_compat);
> +	if (ret) {
> +		pr_warn("%s: failed to get iomuxc_gpr base %d!\n",
> +					__func__, ret);
> +		goto iomuxc_gpr_map_failed;
> +	}
> +
> +	ret = imx_get_base_from_dt(&pm_info->gpc_base, socdata->gpc_compat);
> +	if (ret) {
> +		pr_warn("%s: failed to get gpc base %d!\n", __func__, ret);
> +		goto gpc_map_failed;
> +	}
> +
> +	ret = imx_get_base_from_dt(&pm_info->anatop_base,
> +				socdata->anatop_compat);
> +	if (ret) {
> +		pr_warn("%s: failed to get anatop base %d!\n", __func__, ret);
> +		goto anatop_map_failed;
> +	}
> +
> +	pm_info->ddrc_num = socdata->ddrc_num;
> +	ddrc_offset_array = socdata->ddrc_offset;
> +	pm_info->ddrc_phy_num = socdata->ddrc_phy_num;
> +	ddrc_phy_offset_array = socdata->ddrc_phy_offset;
> +
> +	/* initialize DDRC settings */
> +	for (i = 0; i < pm_info->ddrc_num; i++) {
> +		pm_info->ddrc_val[i][0] = ddrc_offset_array[i][0];
> +		if (ddrc_offset_array[i][1] == READ_DATA_FROM_HARDWARE)
> +			pm_info->ddrc_val[i][1] =
> +				readl_relaxed(pm_info->ddrc_base.vbase +
> +				ddrc_offset_array[i][0]);
> +		else
> +			pm_info->ddrc_val[i][1] = ddrc_offset_array[i][1];
> +	}
> +
> +	/* initialize DDRC PHY settings */
> +	for (i = 0; i < pm_info->ddrc_phy_num; i++) {
> +		pm_info->ddrc_phy_val[i][0] =
> +			ddrc_phy_offset_array[i][0];
> +		if (ddrc_phy_offset_array[i][1] == READ_DATA_FROM_HARDWARE)
> +			pm_info->ddrc_phy_val[i][1] =
> +				readl_relaxed(pm_info->ddrc_phy_base.vbase +
> +				ddrc_phy_offset_array[i][0]);
> +		else
> +			pm_info->ddrc_phy_val[i][1] =
> +				ddrc_phy_offset_array[i][1];
> +	}
> +
> +	pm->suspend_fn_in_ocram = fncpy(
> +		sram_base.vbase + sizeof(*pm_info),
> +		&imx7_suspend,
> +		MX7_SUSPEND_OCRAM_SIZE - sizeof(*pm_info));
> +	pm->ocram_vbase = sram_base.vbase;
> +
> +	goto put_node;
> +
> +anatop_map_failed:
> +	iounmap(pm_info->anatop_base.vbase);
> +gpc_map_failed:
> +	iounmap(pm_info->gpc_base.vbase);
> +iomuxc_gpr_map_failed:
> +	iounmap(pm_info->iomuxc_gpr_base.vbase);
> +src_map_failed:
> +	iounmap(pm_info->src_base.vbase);
> +ddrc_phy_map_failed:
> +	iounmap(pm_info->ddrc_phy_base.vbase);
> +ddrc_map_failed:
> +	iounmap(pm_info->ddrc_base.vbase);
> +ccm_map_failed:
> +	iounmap(pm_info->ccm_base.vbase);
> +lpm_sram_map_failed:
> +	iounmap(sram_base.vbase);
> +put_node:
> +	of_node_put(node);
> +
> +	return ret;
> +}
> +
> +static const struct platform_suspend_ops imx_gpcv2_pm_ops = {
> +	.enter = imx_gpcv2_pm_enter,
> +	.valid = imx_gpcv2_pm_valid,
> +};
> +
> +static int __init imx_gpcv2_pm_init(void) {
> +	struct imx_gpcv2_suspend *pm;
> +	struct imx_gpcv2 *gpc;
> +	int val, num;
> +
> +	pm = kzalloc(sizeof(struct imx_gpcv2_suspend), GFP_KERNEL);
> +	if (!pm) {
> +		pr_warn("[GPCv2] %s init failed\r\n", __func__);
> +		return -ENOMEM;
> +	}
> +
> +	gpc = kzalloc(sizeof(struct imx_gpcv2), GFP_KERNEL);
> +	if (!gpc) {
> +		pr_warn("[GPCv2] %s init failed\r\n", __func__);
> +		kfree(pm);
> +		return -ENOMEM;
> +	}
> +
> +	imx_gpcv2_suspend_init(pm, &imx7d_pm_data_ddr3);
> +
> +	pm->lpm_env_setup = imx_gpcv2_lpm_env_setup;
> +	pm->lpm_env_clean = imx_gpcv2_lpm_env_clean;
> +
> +	pm->lpm_cpu_power_gate = imx_gpcv2_lpm_cpu_power_gate;
> +	pm->lpm_plat_power_gate = imx_lpm_plat_power_gate;
> +	pm->lpm_enable_core = imx_gpcv2_lpm_enable_core;
> +	pm->set_mode = imx_gpcv2_lpm_set_mode;
> +
> +	pm->clear_slots = imx_gpcv2_lpm_clear_slots;
> +	pm->set_slot = imx_gpcv2_lpm_slot_setup;
> +	pm->set_act = imx_gpcv2_lpm_set_ack;
> +
> +	pm->standby = imx_gpcv2_lpm_standby;
> +	pm->suspend = imx_gpcv2_lpm_suspend;
> +
> +	gpc->anatop = syscon_regmap_lookup_by_compatible("fsl,imx6q-anatop");
> +	if (IS_ERR(gpc->anatop))
> +		goto error_exit;
> +
> +	gpc->gpcv2 = syscon_regmap_lookup_by_compatible("fsl,imx7d-gpc");
> +	if (IS_ERR(gpc->gpcv2))
> +		goto error_exit;
> +
> +	/* only external IRQs to wake up LPM and core 0/1 */
> +	regmap_read(gpc->gpcv2, GPC_LPCR_A7_BSC, &val);
> +	val |= BM_LPCR_A7_BSC_IRQ_SRC_A7_WAKEUP;
> +	regmap_write(gpc->gpcv2, GPC_LPCR_A7_BSC, val);
> +	/* mask m4 dsm trigger */
> +	regmap_read(gpc->gpcv2, GPC_LPCR_M4, &val);
> +	val |= BM_LPCR_M4_MASK_DSM_TRIGGER;
> +	regmap_write(gpc->gpcv2, GPC_LPCR_M4, val);
> +
> +	/* set mega/fast mix in A7 domain */
> +	regmap_write(gpc->gpcv2, GPC_PGC_CPU_MAPPING, 0x1);
> +	/* set SCU timing */
> +	val = (0x59 << 10) | 0x5B | (0x51 << 20);
> +	regmap_write(gpc->gpcv2, GPC_PGC_SCU_TIMING, val);
> +
> +	gpc->pm = pm;
> +	gpc->get_wakeup_source = imx_gpcv2_get_wakeup_source;
> +	gpcv2_instance = gpc;
> +
> +	num = imx_gpcv2_get_wakeup_source(0);
> +
> +	/*
> +	 * The IP blocks which may be the wakeup sources are allocated into
> +	 * several power domains. MFMIX, LPSRMX, and WAKEUPMIX are three of
> +	 * those power domains. If a bit is '1' in the mask, it means the IP
> +	 * block is inside the power domain. The mask will be used to decide
> +	 * if a power domain should be shutdown or not when system goes into
> +	 * suspend states.
> +	 */
> +
> +	if (num)
> +		gpc->wakeupmix_mask = kzalloc(sizeof(u32)*num*3, GFP_KERNEL);
> +
> +	if (!gpc->wakeupmix_mask)
> +		goto error_exit;
> +
> +	/*
> +	 * Shutdown LPSRMIX and WAKEUP power domain has not been
> +	 * implemented in this patch yet.
> +	 */
> +
> +	gpc->lpsrmix_mask = gpc->wakeupmix_mask + num;
> +	gpc->mfmix_mask = gpc->wakeupmix_mask + num*2;
> +
> +	/* Mask the wakeup sources in M/F power domain */
> +	gpc->mfmix_mask[0] = 0x54010000;
> +	gpc->mfmix_mask[1] = 0xC00;
> +	gpc->mfmix_mask[2] = 0x0;
> +	gpc->mfmix_mask[3] = 0x400010;
> +
> +	suspend_set_ops(&imx_gpcv2_pm_ops);
> +	return 0;
> +
> +error_exit:
> +	kfree(pm);
> +	kfree(gpc);
> +	return -ENODEV;
> +}
> +
> +device_initcall(imx_gpcv2_pm_init);
> diff --git a/arch/arm/mach-imx/suspend-imx7.S
> b/arch/arm/mach-imx/suspend-imx7.S
> new file mode 100644
> index 0000000..8c3f516
> --- /dev/null
> +++ b/arch/arm/mach-imx/suspend-imx7.S
> @@ -0,0 +1,529 @@
> +/*
> + * Copyright (C) 2015 Freescale Semiconductor, Inc.
> + *
> + * The code contained herein is licensed under the GNU General Public
> + * License. You may obtain a copy of the GNU General Public License
> + * Version 2 or later at the following locations:
> + *
> + * http://www.opensource.org/licenses/gpl-license.html
> + * http://www.gnu.org/copyleft/gpl.html
> + */
> +
> +#include <linux/linkage.h>
> +#include <asm/asm-offsets.h>
> +#include "hardware.h"
> +
> +/*
> + * ==================== low level suspend ====================
> + *
> + * Better to follow below rules to use ARM registers:
> + * r0: pm_info structure address;
> + * r1 ~ r4: for saving pm_info members;
> + * r5 ~ r10: free registers;
> + * r11: io base address.
> + *
> + * suspend ocram space layout:
> + * ======================== high address ======================
> + *                              .
> + *                              .
> + *                              .
> + *                              ^
> + *                              ^
> + *                              ^
> + *                      imx7_suspend code
> + *              PM_INFO structure(imx7_cpu_pm_info)
> + * ======================== low address =======================  */
> +
> +/*
> + * Below offsets are based on struct imx7_cpu_pm_info
> + * which defined in arch/arm/mach-imx/pm-imx7.c, this
> + * structure contains necessary pm info for low level
> + * suspend related code.
> + */
> +#define PM_INFO_M4_RESERVE0_OFFSET		0x0
> +#define PM_INFO_M4_RESERVE1_OFFSET		0x4
> +#define PM_INFO_M4_RESERVE2_OFFSET		0x8
> +#define PM_INFO_PBASE_OFFSET			0xc
> +#define PM_INFO_RESUME_ADDR_OFFSET		0x10
> +#define PM_INFO_DDR_TYPE_OFFSET			0x14
> +#define PM_INFO_PM_INFO_SIZE_OFFSET		0x18
> +#define PM_INFO_MX7_DDRC_P_OFFSET		0x1c
> +#define PM_INFO_MX7_DDRC_V_OFFSET		0x20
> +#define PM_INFO_MX7_DDRC_PHY_P_OFFSET		0x24
> +#define PM_INFO_MX7_DDRC_PHY_V_OFFSET		0x28
> +#define PM_INFO_MX7_SRC_P_OFFSET		0x2c
> +#define PM_INFO_MX7_SRC_V_OFFSET		0x30
> +#define PM_INFO_MX7_IOMUXC_GPR_P_OFFSET		0x34
> +#define PM_INFO_MX7_IOMUXC_GPR_V_OFFSET		0x38
> +#define PM_INFO_MX7_CCM_P_OFFSET		0x3c
> +#define PM_INFO_MX7_CCM_V_OFFSET		0x40
> +#define PM_INFO_MX7_GPC_P_OFFSET		0x44
> +#define PM_INFO_MX7_GPC_V_OFFSET		0x48
> +#define PM_INFO_MX7_L2_P_OFFSET			0x4c
> +#define PM_INFO_MX7_L2_V_OFFSET			0x50
> +#define PM_INFO_MX7_ANATOP_P_OFFSET		0x54
> +#define PM_INFO_MX7_ANATOP_V_OFFSET		0x58
> +#define PM_INFO_MX7_TTBR1_V_OFFSET		0x5c
> +#define PM_INFO_DDRC_REG_NUM_OFFSET		0x60
> +#define PM_INFO_DDRC_REG_OFFSET			0x64
> +#define PM_INFO_DDRC_VALUE_OFFSET		0x68
> +#define PM_INFO_DDRC_PHY_REG_NUM_OFFSET		0x164
> +#define PM_INFO_DDRC_PHY_REG_OFFSET		0x168
> +#define PM_INFO_DDRC_PHY_VALUE_OFFSET		0x16c
> +
> +#define MX7_SRC_GPR1	0x74
> +#define MX7_SRC_GPR2	0x78
> +#define GPC_PGC_FM	0xa00
> +#define ANADIG_SNVS_MISC_CTRL	0x380
> +#define DDRC_STAT	0x4
> +#define DDRC_PWRCTL	0x30
> +#define DDRC_PSTAT	0x3fc
> +#define DDRC_PCTRL_0	0x490
> +#define DDRC_DFIMISC	0x1b0
> +#define DDRC_SWCTL	0x320
> +#define DDRC_SWSTAT	0x324
> +#define DDRPHY_LP_CON0	0x18
> +
> +	.align 3
> +
> +	.macro	disable_l1_dcache
> +
> +	/*
> +	 * Flush all data from the L1 data cache before disabling
> +	 * SCTLR.C bit.
> +	 */
> +	push	{r0 - r10, lr}
> +	ldr	r7, =v7_flush_dcache_all
> +	mov	lr, pc
> +	mov	pc, r7
> +	pop	{r0 - r10, lr}
> +
> +	/* disable d-cache */
> +	mrc	p15, 0, r7, c1, c0, 0
> +	bic	r7, r7, #(1 << 2)
> +	mcr	p15, 0, r7, c1, c0, 0
> +	dsb
> +	isb
> +
> +	push	{r0 - r10, lr}
> +	ldr	r7, =v7_flush_dcache_all
> +	mov	lr, pc
> +	mov	pc, r7
> +	pop	{r0 - r10, lr}
> +
> +	.endm
> +
> +
> +	.macro enable_l1_dcache
> +
> +	/* Enable L1 data cache. */
> +	mrc	p15, 0, r6, c1, c0, 0
> +	orr	r6, r6, #0x4
> +	mcr	p15, 0, r6, c1, c0, 0
> +
> +	dsb
> +	isb
> +
> +	.endm
> +
> +
> +	.macro ddrc_enter_self_refresh
> +
> +	ldr	r11, [r0, #PM_INFO_MX7_DDRC_V_OFFSET]
> +
> +	/* let DDR out of self-refresh */
> +	ldr	r7, =0x0
> +	str	r7, [r11, #DDRC_PWRCTL]
> +
> +	/* wait rw port_busy clear */
> +	ldr	r6, =(0x1 << 16)
> +	orr	r6, r6, #0x1
> +1:
> +	ldr	r7, [r11, #DDRC_PSTAT]
> +	ands	r7, r7, r6
> +	bne	1b
> +
> +	/* enter self-refresh bit 5 */
> +	ldr	r7, =(0x1 << 5)
> +	str	r7, [r11, #DDRC_PWRCTL]
> +
> +	/* wait until self-refresh mode entered */
> +2:
> +	ldr	r7, [r11, #DDRC_STAT]
> +	and	r7, r7, #0x3
> +	cmp	r7, #0x3
> +	bne	2b
> +3:
> +	ldr	r7, [r11, #DDRC_STAT]
> +	ands	r7, r7, #0x20
> +	beq	3b
> +
> +	/* disable dram clk */
> +	ldr	r7, [r11, #DDRC_PWRCTL]
> +	orr	r7, r7, #(1 << 3)
> +	str	r7, [r11, #DDRC_PWRCTL]
> +
> +	.endm
> +
> +	.macro ddrc_exit_self_refresh
> +
> +	cmp	r5, #0x0
> +	ldreq	r11, [r0, #PM_INFO_MX7_DDRC_V_OFFSET]
> +	ldrne	r11, [r0, #PM_INFO_MX7_DDRC_P_OFFSET]
> +
> +	/* let DDR out of self-refresh */
> +	ldr	r7, =0x0
> +	str	r7, [r11, #DDRC_PWRCTL]
> +
> +	/* wait until self-refresh mode entered */
> +4:
> +	ldr	r7, [r11, #DDRC_STAT]
> +	and	r7, r7, #0x3
> +	cmp	r7, #0x3
> +	beq	4b
> +
> +	/* enable auto self-refresh */
> +	ldr	r7, [r11, #DDRC_PWRCTL]
> +	orr	r7, r7, #(1 << 0)
> +	str	r7, [r11, #DDRC_PWRCTL]
> +
> +	.endm
> +
> +	.macro wait_delay
> +5:
> +	subs	r6, r6, #0x1
> +	bne	5b
> +
> +	.endm
> +
> +	.macro ddr_enter_retention
> +
> +	ldr	r11, [r0, #PM_INFO_MX7_DDRC_V_OFFSET]
> +
> +	/* let DDR out of self-refresh */
> +	ldr	r7, =0x0
> +	str	r7, [r11, #DDRC_PCTRL_0]
> +
> +	/* wait rw port_busy clear */
> +	ldr	r6, =(0x1 << 16)
> +	orr	r6, r6, #0x1
> +6:
> +	ldr	r7, [r11, #DDRC_PSTAT]
> +	ands	r7, r7, r6
> +	bne	6b
> +
> +	ldr	r11, [r0, #PM_INFO_MX7_DDRC_V_OFFSET]
> +	/* enter self-refresh bit 5 */
> +	ldr	r7, =(0x1 << 5)
> +	str	r7, [r11, #DDRC_PWRCTL]
> +
> +	/* wait until self-refresh mode entered */
> +7:
> +	ldr	r7, [r11, #DDRC_STAT]
> +	and	r7, r7, #0x3
> +	cmp	r7, #0x3
> +	bne	7b
> +8:
> +	ldr	r7, [r11, #DDRC_STAT]
> +	ands	r7, r7, #0x20
> +	beq	8b
> +
> +	/* disable dram clk */
> +	ldr	r7, =(0x1 << 5)
> +	orr	r7, r7, #(1 << 3)
> +	str	r7, [r11, #DDRC_PWRCTL]
> +
> +	/* reset ddr_phy  */
> +	ldr	r11, [r0, #PM_INFO_MX7_ANATOP_V_OFFSET]
> +	ldr	r7, =0x0
> +	str	r7, [r11, #ANADIG_SNVS_MISC_CTRL]
> +
> +	/* delay 7 us */
> +	ldr	r6, =6000
> +	wait_delay
> +
> +	ldr	r11, [r0, #PM_INFO_MX7_SRC_V_OFFSET]
> +	ldr	r6, =0x1000
> +	ldr	r7, [r11, r6]
> +	orr	r7, r7, #0x1
> +	str	r7, [r11, r6]
> +	/* turn off ddr power */
> +	ldr	r11, [r0, #PM_INFO_MX7_ANATOP_V_OFFSET]
> +	ldr	r7, =(0x1 << 29)
> +	str	r7, [r11, #ANADIG_SNVS_MISC_CTRL]
> +
> +	.endm
> +
> +	.macro ddr_exit_retention
> +
> +	cmp	r5, #0x0
> +	ldreq	r1, [r0, #PM_INFO_MX7_ANATOP_V_OFFSET]
> +	ldrne	r1, [r0, #PM_INFO_MX7_ANATOP_P_OFFSET]
> +	ldreq	r2, [r0, #PM_INFO_MX7_SRC_V_OFFSET]
> +	ldrne	r2, [r0, #PM_INFO_MX7_SRC_P_OFFSET]
> +	ldreq	r3, [r0, #PM_INFO_MX7_DDRC_V_OFFSET]
> +	ldrne	r3, [r0, #PM_INFO_MX7_DDRC_P_OFFSET]
> +	ldreq	r4, [r0, #PM_INFO_MX7_DDRC_PHY_V_OFFSET]
> +	ldrne	r4, [r0, #PM_INFO_MX7_DDRC_PHY_P_OFFSET]
> +	ldreq	r10, [r0, #PM_INFO_MX7_CCM_V_OFFSET]
> +	ldrne	r10, [r0, #PM_INFO_MX7_CCM_P_OFFSET]
> +	ldreq	r11, [r0, #PM_INFO_MX7_IOMUXC_GPR_V_OFFSET]
> +	ldrne	r11, [r0, #PM_INFO_MX7_IOMUXC_GPR_P_OFFSET]
> +
> +	/* turn on ddr power */
> +	ldr	r7, =(0x1 << 29)
> +	str	r7, [r1, #ANADIG_SNVS_MISC_CTRL]
> +
> +	ldr	r6, =50
> +	wait_delay
> +
> +	ldr	r7, =0x0
> +	str	r7, [r1, #ANADIG_SNVS_MISC_CTRL]
> +
> +	/* clear ddr_phy reset */
> +	ldr	r6, =0x1000
> +	ldr	r7, [r2, r6]
> +	orr	r7, r7, #0x3
> +	str	r7, [r2, r6]
> +	ldr	r7, [r2, r6]
> +	bic	r7, r7, #0x1
> +	str	r7, [r2, r6]
> +
> +	ldr	r6, [r0, #PM_INFO_DDRC_REG_NUM_OFFSET]
> +	ldr	r7, =PM_INFO_DDRC_REG_OFFSET
> +	add	r7, r7, r0
> +9:
> +	ldr	r8, [r7], #0x4
> +	ldr	r9, [r7], #0x4
> +	str	r9, [r3, r8]
> +	subs	r6, r6, #0x1
> +	bne	9b
> +	ldr	r7, =0x20
> +	str	r7, [r3, #DDRC_PWRCTL]
> +	ldr	r7, =0x0
> +	str	r7, [r3, #DDRC_DFIMISC]
> +
> +	/* do PHY, clear ddr_phy reset */
> +	ldr	r6, =0x1000
> +	ldr	r7, [r2, r6]
> +	bic	r7, r7, #0x2
> +	str	r7, [r2, r6]
> +
> +	ldr	r7, =(0x1 << 30)
> +	str	r7, [r1, #ANADIG_SNVS_MISC_CTRL]
> +
> +	/* need to delay ~5mS */
> +	ldr	r6, =0x100000
> +	wait_delay
> +
> +	ldr	r6, [r0, #PM_INFO_DDRC_PHY_REG_NUM_OFFSET]
> +	ldr	r7, =PM_INFO_DDRC_PHY_REG_OFFSET
> +	add	r7, r7, r0
> +
> +10:
> +	ldr	r8, [r7], #0x4
> +	ldr	r9, [r7], #0x4
> +	str	r9, [r4, r8]
> +	subs	r6, r6, #0x1
> +	bne	10b
> +
> +	ldr	r7, =0x0
> +	add	r9, r10, #0x4000
> +	str	r7, [r9, #0x130]
> +
> +	cmp	r5, #0x0
> +	beq	101f
> +	ldr	r7, =0x170
> +	orr	r7, r7, #0x8
> +	str	r7, [r11, #0x20]
> +
> +101:
> +	ldr	r7, =0x2
> +	add	r9, r10, #0x4000
> +	str	r7, [r9, #0x130]
> +
> +	ldr	r7, =0xf
> +	str	r7, [r4, #DDRPHY_LP_CON0]
> +
> +	/* wait until self-refresh mode entered */
> +11:
> +	ldr	r7, [r3, #DDRC_STAT]
> +	and	r7, r7, #0x3
> +	cmp	r7, #0x3
> +	bne	11b
> +	ldr	r7, =0x0
> +	str	r7, [r3, #DDRC_SWCTL]
> +	ldr	r7, =0x1
> +	str	r7, [r3, #DDRC_DFIMISC]
> +	ldr	r7, =0x1
> +	str	r7, [r3, #DDRC_SWCTL]
> +12:
> +	ldr	r7, [r3, #DDRC_SWSTAT]
> +	and	r7, r7, #0x1
> +	cmp	r7, #0x1
> +	bne	12b
> +13:
> +	ldr	r7, [r3, #DDRC_STAT]
> +	and	r7, r7, #0x20
> +	cmp	r7, #0x20
> +	bne	13b
> +
> +	/* let DDR out of self-refresh */
> +	ldr	r7, =0x0
> +	str	r7, [r3, #DDRC_PWRCTL]
> +14:
> +	ldr	r7, [r3, #DDRC_STAT]
> +	and	r7, r7, #0x30
> +	cmp	r7, #0x0
> +	bne	14b
> +
> +15:
> +	ldr	r7, [r3, #DDRC_STAT]
> +	and	r7, r7, #0x3
> +	cmp	r7, #0x1
> +	bne	15b
> +
> +	/* enable port */
> +	ldr	r7, =0x1
> +	str	r7, [r3, #DDRC_PCTRL_0]
> +
> +	.endm
> +
> +ENTRY(imx7_suspend)
> +	push	{r4-r12}
> +
> +	/*
> +	 * The value of r0 is mapped the same in origin table and IRAM table,
> +	 * thus no need to care r0 here.
> +	 */
> +	ldr	r1, [r0, #PM_INFO_PBASE_OFFSET]
> +	ldr	r2, [r0, #PM_INFO_RESUME_ADDR_OFFSET]
> +	ldr	r3, [r0, #PM_INFO_DDR_TYPE_OFFSET]
> +	ldr	r4, [r0, #PM_INFO_PM_INFO_SIZE_OFFSET]
> +
> +	/*
> +	 * counting the resume address in iram
> +	 * to set it in SRC register.
> +	 */
> +	ldr	r6, =imx7_suspend
> +	ldr	r7, =resume
> +	sub	r7, r7, r6
> +	add	r8, r1, r4
> +	add	r9, r8, r7
> +
> +	ldr	r11, [r0, #PM_INFO_MX7_SRC_V_OFFSET]
> +	/* store physical resume addr and pm_info address. */
> +	str	r9, [r11, #MX7_SRC_GPR1]
> +	str	r1, [r11, #MX7_SRC_GPR2]
> +
> +	disable_l1_dcache
> +
> +	/*
> +	 * make sure TLB contain the addr we want,
> +	 * as we will access them after DDR is in
> +	 * self-refresh mode.
> +	 */
> +	ldr	r6, [r0, #PM_INFO_MX7_IOMUXC_GPR_V_OFFSET]
> +	ldr	r7, [r0, #0x0]
> +	ldr	r6, [r0, #PM_INFO_MX7_CCM_V_OFFSET]
> +	add	r6, #0x4000
> +	ldr	r7, [r6]
> +	ldr	r6, [r0, #PM_INFO_MX7_ANATOP_V_OFFSET]
> +	ldr	r7, [r6, #0x0]
> +	ldr	r6, [r0, #PM_INFO_MX7_SRC_V_OFFSET]
> +	ldr	r7, [r6, #0x0]
> +	add	r6, #0x1000
> +	ldr	r7, [r6]
> +	ldr	r6, [r0, #PM_INFO_MX7_DDRC_V_OFFSET]
> +	ldr	r7, [r6, #0x0]
> +	ldr	r7, [r6, #0x490]
> +	ldr	r6, [r0, #PM_INFO_MX7_DDRC_PHY_V_OFFSET]
> +	ldr	r7, [r6, #0x0]
> +
> +	ldr	r11, [r0, #PM_INFO_MX7_GPC_V_OFFSET]
> +	ldr	r7, [r11, #GPC_PGC_FM]
> +	cmp	r7, #0
> +	beq	ddr_only_self_refresh
> +
> +	ddr_enter_retention
> +	b	ddr_retention_enter_out
> +ddr_only_self_refresh:
> +	ddrc_enter_self_refresh
> +ddr_retention_enter_out:
> +
> +	/* Zzz, enter stop mode */
> +	wfi
> +	nop
> +	nop
> +	nop
> +	nop
> +
> +	mov	r5, #0x0
> +
> +	ldr	r11, [r0, #PM_INFO_MX7_GPC_V_OFFSET]
> +	ldr	r7, [r11, #GPC_PGC_FM]
> +	cmp	r7, #0
> +	beq	wfi_ddr_self_refresh_out
> +
> +	ddr_exit_retention
> +	b	wfi_ddr_retention_out
> +wfi_ddr_self_refresh_out:
> +	ddrc_exit_self_refresh
> +wfi_ddr_retention_out:
> +
> +	ldr	r11, [r0, #PM_INFO_MX7_IOMUXC_GPR_V_OFFSET]
> +	ldr	r7, =0x170
> +	orr	r7, r7, #0x8
> +	str	r7, [r11, #0x20]
> +
> +	/* clear core0's entry and parameter */
> +	ldr	r11, [r0, #PM_INFO_MX7_SRC_V_OFFSET]
> +	mov	r7, #0x0
> +	str	r7, [r11, #MX7_SRC_GPR1]
> +	str	r7, [r11, #MX7_SRC_GPR2]
> +
> +	enable_l1_dcache
> +
> +	pop	{r4-r12}
> +	/* return to suspend finish */
> +	mov	pc, lr
> +
> +resume:
> +	/* invalidate L1 I-cache first */
> +	mov     r6, #0x0
> +	mcr     p15, 0, r6, c7, c5, 0
> +	mcr     p15, 0, r6, c7, c5, 6
> +	/* enable the Icache and branch prediction */
> +	mov     r6, #0x1800
> +	mcr     p15, 0, r6, c1, c0, 0
> +	isb
> +
> +	/* get physical resume address from pm_info. */
> +	ldr	lr, [r0, #PM_INFO_RESUME_ADDR_OFFSET]
> +	/* clear core0's entry and parameter */
> +	ldr	r11, [r0, #PM_INFO_MX7_SRC_P_OFFSET]
> +	mov	r7, #0x0
> +	str	r7, [r11, #MX7_SRC_GPR1]
> +	str	r7, [r11, #MX7_SRC_GPR2]
> +
> +	mov	r5, #0x1
> +
> +	ldr	r11, [r0, #PM_INFO_MX7_GPC_P_OFFSET]
> +	ldr	r7, [r11, #GPC_PGC_FM]
> +	cmp	r7, #0
> +	beq	dsm_ddr_self_refresh_out
> +
> +	ddr_exit_retention
> +	b	dsm_ddr_retention_out
> +dsm_ddr_self_refresh_out:
> +	ddrc_exit_self_refresh
> +dsm_ddr_retention_out:
> +
> +	mov	pc, lr
> +ENDPROC(imx7_suspend)
> +
> +ENTRY(ca7_cpu_resume)
> +	bl	v7_invalidate_l1
> +	b	cpu_resume
> +ENDPROC(ca7_cpu_resume)
> --
> 2.5.0.rc2
> 
> 
> --
> To unsubscribe from this list: send the line "unsubscribe linux-kernel" in
> the body of a message to majordomo at vger.kernel.org
> More majordomo info at  http://vger.kernel.org/majordomo-info.html
> Please read the FAQ at  http://www.tux.org/lkml/

From linux at arm.linux.org.uk  Fri Aug 21 06:46:30 2015
From: linux at arm.linux.org.uk (Russell King - ARM Linux)
Date: Fri, 21 Aug 2015 14:46:30 +0100
Subject: [PATCH 0/4] Efficiency cleanups
In-Reply-To: <20150821133043.GV7557@n2100.arm.linux.org.uk>
References: <CABXk95C=CpeL4mNmS6-jJ-0bMJf6fawwfs6DM1-p8FctTEFbpw@mail.gmail.com>
 <20150821133043.GV7557@n2100.arm.linux.org.uk>
Message-ID: <20150821134630.GW7557@n2100.arm.linux.org.uk>

While developing the previous patch set, I noticed that the kernel's
"fast" exit path efficiency was not what it's supposed to be due to the
addition of trace and context tracking.

These add several instances of register stacking and unstacking around
various function calls, several of which we can avoid.  Many of these
instances don't need to stack any register other than r0.

Moreover, we can avoid stacking and unstacking r0 if these features are
enabled by storing r0 in the pt_regs as we would do in our slow return
path.

Various other cleanups are included in this set as well.  Acks welcome.

 arch/arm/include/asm/assembler.h   | 22 ++++++++------
 arch/arm/include/asm/thread_info.h | 20 +++++--------
 arch/arm/include/asm/uaccess.h     | 47 ++++++++---------------------
 arch/arm/kernel/entry-common.S     | 61 ++++++++++++++++++++++++++++----------
 arch/arm/kernel/signal.c           |  6 ++++
 5 files changed, 84 insertions(+), 72 deletions(-)

-- 
FTTC broadband for 0.8mile line: currently at 10.5Mbps down 400kbps up
according to speedtest.net.


From arnd at arndb.de  Fri Aug 21 06:45:53 2015
From: arnd at arndb.de (Arnd Bergmann)
Date: Fri, 21 Aug 2015 15:45:53 +0200
Subject: [PATCH v2 09/21] ARM: pxa: magician: Add OV9640 camera support
In-Reply-To: <55D65722.9030508@tul.cz>
References: <cover.1439843482.git.petr.cvek@tul.cz>
 <2889798.x6xcIzdYMU@wuerfel> <55D65722.9030508@tul.cz>
Message-ID: <1634812.ZDaECJ9ClW@wuerfel>

On Friday 21 August 2015 00:39:30 Petr Cvek wrote:
> Dne 20.8.2015 v 22:26 Arnd Bergmann napsal(a):
> > On Thursday 20 August 2015 21:48:20 Robert Jarzmik wrote:
> >> Petr Cvek <petr.cvek at tul.cz> writes:
> >>
> >>> +     mdelay(3);
> >> Okay, there are several mdelay(3) in this file.
> >>
> >> Could you please test if removing these mdelays prevents the camera from working
> >> ? If not, I'd like to have them removed.
> >>
> >>
> > 
> > FWIW, it might be possible to replace some of them with msleep() calls,
> > potentially after replacing spinlocks with mutexes where necessary.
> > 
> >       Arnd
> > 
> 
> Datasheet says:
> 
>         tS:RESET        Setting time after software/hardware reset      1 ms
> 
> So at least one ~1 ms should be left there. Are msleep less than 20ms valid? 
> 
> (checkpatch: msleep < 20ms  can sleep for up to 20ms)

On most kernels, an msleep(1) will sleep somewhere between 1 and 3 milliseconds
(but could be much longer), while an mdelay(1) tries to sleep around one
millisecond, more or less.

	Arnd


From rmk+kernel at arm.linux.org.uk  Fri Aug 21 06:48:15 2015
From: rmk+kernel at arm.linux.org.uk (Russell King)
Date: Fri, 21 Aug 2015 14:48:15 +0100
Subject: [PATCH 1/4] ARM: uaccess: simplify user access assembly
In-Reply-To: <20150821134630.GW7557@n2100.arm.linux.org.uk>
References: <20150821134630.GW7557@n2100.arm.linux.org.uk>
Message-ID: <E1ZSmg3-00044O-6s@rmk-PC.arm.linux.org.uk>

The user assembly for byte and word accesses was virtually identical.
Rather than duplicating this, use a macro instead.

Signed-off-by: Russell King <rmk+kernel at arm.linux.org.uk>
---
 arch/arm/include/asm/uaccess.h | 47 +++++++++++-------------------------------
 1 file changed, 12 insertions(+), 35 deletions(-)

diff --git a/arch/arm/include/asm/uaccess.h b/arch/arm/include/asm/uaccess.h
index 74b17d09ef7a..4cf54ebe408a 100644
--- a/arch/arm/include/asm/uaccess.h
+++ b/arch/arm/include/asm/uaccess.h
@@ -311,9 +311,9 @@ do {									\
 	(x) = (__typeof__(*(ptr)))__gu_val;				\
 } while (0)
 
-#define __get_user_asm_byte(x, addr, err)			\
+#define __get_user_asm(x, addr, err, instr)			\
 	__asm__ __volatile__(					\
-	"1:	" TUSER(ldrb) "	%1,[%2],#0\n"			\
+	"1:	" TUSER(instr) " %1, [%2], #0\n"		\
 	"2:\n"							\
 	"	.pushsection .text.fixup,\"ax\"\n"		\
 	"	.align	2\n"					\
@@ -329,6 +329,9 @@ do {									\
 	: "r" (addr), "i" (-EFAULT)				\
 	: "cc")
 
+#define __get_user_asm_byte(x, addr, err)			\
+	__get_user_asm(x, addr, err, ldrb)
+
 #ifndef __ARMEB__
 #define __get_user_asm_half(x, __gu_addr, err)			\
 ({								\
@@ -348,22 +351,7 @@ do {									\
 #endif
 
 #define __get_user_asm_word(x, addr, err)			\
-	__asm__ __volatile__(					\
-	"1:	" TUSER(ldr) "	%1,[%2],#0\n"			\
-	"2:\n"							\
-	"	.pushsection .text.fixup,\"ax\"\n"		\
-	"	.align	2\n"					\
-	"3:	mov	%0, %3\n"				\
-	"	mov	%1, #0\n"				\
-	"	b	2b\n"					\
-	"	.popsection\n"					\
-	"	.pushsection __ex_table,\"a\"\n"		\
-	"	.align	3\n"					\
-	"	.long	1b, 3b\n"				\
-	"	.popsection"					\
-	: "+r" (err), "=&r" (x)					\
-	: "r" (addr), "i" (-EFAULT)				\
-	: "cc")
+	__get_user_asm(x, addr, err, ldr)
 
 #define __put_user(x, ptr)						\
 ({									\
@@ -393,9 +381,9 @@ do {									\
 	}								\
 } while (0)
 
-#define __put_user_asm_byte(x, __pu_addr, err)			\
+#define __put_user_asm(x, __pu_addr, err, instr)		\
 	__asm__ __volatile__(					\
-	"1:	" TUSER(strb) "	%1,[%2],#0\n"			\
+	"1:	" TUSER(instr) " %1, [%2], #0\n"		\
 	"2:\n"							\
 	"	.pushsection .text.fixup,\"ax\"\n"		\
 	"	.align	2\n"					\
@@ -410,6 +398,9 @@ do {									\
 	: "r" (x), "r" (__pu_addr), "i" (-EFAULT)		\
 	: "cc")
 
+#define __put_user_asm_byte(x, __pu_addr, err)			\
+	__put_user_asm(x, __pu_addr, err, strb)
+
 #ifndef __ARMEB__
 #define __put_user_asm_half(x, __pu_addr, err)			\
 ({								\
@@ -427,21 +418,7 @@ do {									\
 #endif
 
 #define __put_user_asm_word(x, __pu_addr, err)			\
-	__asm__ __volatile__(					\
-	"1:	" TUSER(str) "	%1,[%2],#0\n"			\
-	"2:\n"							\
-	"	.pushsection .text.fixup,\"ax\"\n"		\
-	"	.align	2\n"					\
-	"3:	mov	%0, %3\n"				\
-	"	b	2b\n"					\
-	"	.popsection\n"					\
-	"	.pushsection __ex_table,\"a\"\n"		\
-	"	.align	3\n"					\
-	"	.long	1b, 3b\n"				\
-	"	.popsection"					\
-	: "+r" (err)						\
-	: "r" (x), "r" (__pu_addr), "i" (-EFAULT)		\
-	: "cc")
+	__put_user_asm(x, __pu_addr, err, str)
 
 #ifndef __ARMEB__
 #define	__reg_oper0	"%R2"
-- 
2.1.0



From rmk+kernel at arm.linux.org.uk  Fri Aug 21 06:48:20 2015
From: rmk+kernel at arm.linux.org.uk (Russell King)
Date: Fri, 21 Aug 2015 14:48:20 +0100
Subject: [PATCH 2/4] ARM: entry: get rid of asm_trace_hardirqs_on_cond
In-Reply-To: <20150821134630.GW7557@n2100.arm.linux.org.uk>
References: <20150821134630.GW7557@n2100.arm.linux.org.uk>
Message-ID: <E1ZSmg8-00044U-BD@rmk-PC.arm.linux.org.uk>

There's no need for this macro, it can use a default for the
condition argument.

Signed-off-by: Russell King <rmk+kernel at arm.linux.org.uk>
---
 arch/arm/include/asm/assembler.h | 8 ++------
 1 file changed, 2 insertions(+), 6 deletions(-)

diff --git a/arch/arm/include/asm/assembler.h b/arch/arm/include/asm/assembler.h
index 4abe57279c66..742495eb5526 100644
--- a/arch/arm/include/asm/assembler.h
+++ b/arch/arm/include/asm/assembler.h
@@ -116,7 +116,7 @@
 #endif
 	.endm
 
-	.macro asm_trace_hardirqs_on_cond, cond
+	.macro asm_trace_hardirqs_on, cond=al
 #if defined(CONFIG_TRACE_IRQFLAGS)
 	/*
 	 * actually the registers should be pushed and pop'd conditionally, but
@@ -128,10 +128,6 @@
 #endif
 	.endm
 
-	.macro asm_trace_hardirqs_on
-	asm_trace_hardirqs_on_cond al
-	.endm
-
 	.macro disable_irq
 	disable_irq_notrace
 	asm_trace_hardirqs_off
@@ -173,7 +169,7 @@
 
 	.macro restore_irqs, oldcpsr
 	tst	\oldcpsr, #PSR_I_BIT
-	asm_trace_hardirqs_on_cond eq
+	asm_trace_hardirqs_on cond=eq
 	restore_irqs_notrace \oldcpsr
 	.endm
 
-- 
2.1.0



From rmk+kernel at arm.linux.org.uk  Fri Aug 21 06:48:25 2015
From: rmk+kernel at arm.linux.org.uk (Russell King)
Date: Fri, 21 Aug 2015 14:48:25 +0100
Subject: [PATCH 3/4] ARM: entry: efficiency cleanups
In-Reply-To: <20150821134630.GW7557@n2100.arm.linux.org.uk>
References: <20150821134630.GW7557@n2100.arm.linux.org.uk>
Message-ID: <E1ZSmgD-00044a-FE@rmk-PC.arm.linux.org.uk>

Make the "fast" syscall return path fast again.  The addition of IRQ
tracing and context tracking has made this path grossly inefficient.
We can do much better if these options are enabled if we save the
syscall return code on the stack - we then don't need to save a bunch
of registers around every single callout to C code.

Signed-off-by: Russell King <rmk+kernel at arm.linux.org.uk>
---
 arch/arm/include/asm/assembler.h   | 16 +++++++---
 arch/arm/include/asm/thread_info.h | 20 +++++--------
 arch/arm/kernel/entry-common.S     | 61 ++++++++++++++++++++++++++++----------
 arch/arm/kernel/signal.c           |  6 ++++
 4 files changed, 71 insertions(+), 32 deletions(-)

diff --git a/arch/arm/include/asm/assembler.h b/arch/arm/include/asm/assembler.h
index 742495eb5526..5a5504f90d5f 100644
--- a/arch/arm/include/asm/assembler.h
+++ b/arch/arm/include/asm/assembler.h
@@ -108,29 +108,37 @@
 	.endm
 #endif
 
-	.macro asm_trace_hardirqs_off
+	.macro asm_trace_hardirqs_off, save=1
 #if defined(CONFIG_TRACE_IRQFLAGS)
+	.if \save
 	stmdb   sp!, {r0-r3, ip, lr}
+	.endif
 	bl	trace_hardirqs_off
+	.if \save
 	ldmia	sp!, {r0-r3, ip, lr}
+	.endif
 #endif
 	.endm
 
-	.macro asm_trace_hardirqs_on, cond=al
+	.macro asm_trace_hardirqs_on, cond=al, save=1
 #if defined(CONFIG_TRACE_IRQFLAGS)
 	/*
 	 * actually the registers should be pushed and pop'd conditionally, but
 	 * after bl the flags are certainly clobbered
 	 */
+	.if \save
 	stmdb   sp!, {r0-r3, ip, lr}
+	.endif
 	bl\cond	trace_hardirqs_on
+	.if \save
 	ldmia	sp!, {r0-r3, ip, lr}
+	.endif
 #endif
 	.endm
 
-	.macro disable_irq
+	.macro disable_irq, save=1
 	disable_irq_notrace
-	asm_trace_hardirqs_off
+	asm_trace_hardirqs_off \save
 	.endm
 
 	.macro enable_irq
diff --git a/arch/arm/include/asm/thread_info.h b/arch/arm/include/asm/thread_info.h
index bd32eded3e50..71e0ffcedf8e 100644
--- a/arch/arm/include/asm/thread_info.h
+++ b/arch/arm/include/asm/thread_info.h
@@ -136,22 +136,18 @@ extern int vfp_restore_user_hwstate(struct user_vfp __user *,
 
 /*
  * thread information flags:
- *  TIF_SYSCALL_TRACE	- syscall trace active
- *  TIF_SYSCAL_AUDIT	- syscall auditing active
- *  TIF_SIGPENDING	- signal pending
- *  TIF_NEED_RESCHED	- rescheduling necessary
- *  TIF_NOTIFY_RESUME	- callback before returning to user
  *  TIF_USEDFPU		- FPU was used by this task this quantum (SMP)
  *  TIF_POLLING_NRFLAG	- true if poll_idle() is polling TIF_NEED_RESCHED
  */
-#define TIF_SIGPENDING		0
-#define TIF_NEED_RESCHED	1
+#define TIF_SIGPENDING		0	/* signal pending */
+#define TIF_NEED_RESCHED	1	/* rescheduling necessary */
 #define TIF_NOTIFY_RESUME	2	/* callback before returning to user */
-#define TIF_UPROBE		7
-#define TIF_SYSCALL_TRACE	8
-#define TIF_SYSCALL_AUDIT	9
-#define TIF_SYSCALL_TRACEPOINT	10
-#define TIF_SECCOMP		11	/* seccomp syscall filtering active */
+#define TIF_UPROBE		3	/* breakpointed or singlestepping */
+#define TIF_SYSCALL_TRACE	4	/* syscall trace active */
+#define TIF_SYSCALL_AUDIT	5	/* syscall auditing active */
+#define TIF_SYSCALL_TRACEPOINT	6	/* syscall tracepoint instrumentation */
+#define TIF_SECCOMP		7	/* seccomp syscall filtering active */
+
 #define TIF_NOHZ		12	/* in adaptive nohz mode */
 #define TIF_USING_IWMMXT	17
 #define TIF_MEMDIE		18	/* is terminating due to OOM killer */
diff --git a/arch/arm/kernel/entry-common.S b/arch/arm/kernel/entry-common.S
index 92828a1dec80..dd3721d1185e 100644
--- a/arch/arm/kernel/entry-common.S
+++ b/arch/arm/kernel/entry-common.S
@@ -24,35 +24,55 @@
 
 
 	.align	5
+#if !(IS_ENABLED(CONFIG_TRACE_IRQFLAGS) || IS_ENABLED(CONFIG_CONTEXT_TRACKING))
 /*
- * This is the fast syscall return path.  We do as little as
- * possible here, and this includes saving r0 back into the SVC
- * stack.
+ * This is the fast syscall return path.  We do as little as possible here,
+ * such as avoiding writing r0 to the stack.  We only use this path if we
+ * have tracing and context tracking disabled - the overheads from those
+ * features make this path too inefficient.
  */
 ret_fast_syscall:
  UNWIND(.fnstart	)
  UNWIND(.cantunwind	)
-	disable_irq				@ disable interrupts
+	disable_irq_notrace			@ disable interrupts
 	ldr	r1, [tsk, #TI_FLAGS]		@ re-check for syscall tracing
-	tst	r1, #_TIF_SYSCALL_WORK
-	bne	__sys_trace_return
-	tst	r1, #_TIF_WORK_MASK
+	tst	r1, #_TIF_SYSCALL_WORK | _TIF_WORK_MASK
 	bne	fast_work_pending
-	asm_trace_hardirqs_on
 
 	/* perform architecture specific actions before user return */
 	arch_ret_to_user r1, lr
-	ct_user_enter
 
 	restore_user_regs fast = 1, offset = S_OFF
  UNWIND(.fnend		)
+ENDPROC(ret_fast_syscall)
 
-/*
- * Ok, we need to do extra processing, enter the slow path.
- */
+	/* Ok, we need to do extra processing, enter the slow path. */
 fast_work_pending:
 	str	r0, [sp, #S_R0+S_OFF]!		@ returned r0
-work_pending:
+	/* fall through to work_pending */
+#else
+/*
+ * The "replacement" ret_fast_syscall for when tracing or context tracking
+ * is enabled.  As we will need to call out to some C functions, we save
+ * r0 first to avoid needing to save registers around each C function call.
+ */
+ret_fast_syscall:
+ UNWIND(.fnstart	)
+ UNWIND(.cantunwind	)
+	str	r0, [sp, #S_R0 + S_OFF]!	@ save returned r0
+	disable_irq_notrace			@ disable interrupts
+	ldr	r1, [tsk, #TI_FLAGS]		@ re-check for syscall tracing
+	tst	r1, #_TIF_SYSCALL_WORK | _TIF_WORK_MASK
+	beq	no_work_pending
+ UNWIND(.fnend		)
+ENDPROC(ret_fast_syscall)
+
+	/* Slower path - fall through to work_pending */
+#endif
+
+	tst	r1, #_TIF_SYSCALL_WORK
+	bne	__sys_trace_return_nosave
+slow_work_pending:
 	mov	r0, sp				@ 'regs'
 	mov	r2, why				@ 'syscall'
 	bl	do_work_pending
@@ -64,16 +84,19 @@ work_pending:
 
 /*
  * "slow" syscall return path.  "why" tells us if this was a real syscall.
+ * IRQs may be enabled here, so always disable them.  Note that we use the
+ * "notrace" version to avoid calling into the tracing code unnecessarily.
+ * do_work_pending() will update this state if necessary.
  */
 ENTRY(ret_to_user)
 ret_slow_syscall:
-	disable_irq				@ disable interrupts
+	disable_irq_notrace			@ disable interrupts
 ENTRY(ret_to_user_from_irq)
 	ldr	r1, [tsk, #TI_FLAGS]
 	tst	r1, #_TIF_WORK_MASK
-	bne	work_pending
+	bne	slow_work_pending
 no_work_pending:
-	asm_trace_hardirqs_on
+	asm_trace_hardirqs_on save = 0
 
 	/* perform architecture specific actions before user return */
 	arch_ret_to_user r1, lr
@@ -251,6 +274,12 @@ __sys_trace_return:
 	bl	syscall_trace_exit
 	b	ret_slow_syscall
 
+__sys_trace_return_nosave:
+	asm_trace_hardirqs_off save=0
+	mov	r0, sp
+	bl	syscall_trace_exit
+	b	ret_slow_syscall
+
 	.align	5
 #ifdef CONFIG_ALIGNMENT_TRAP
 	.type	__cr_alignment, #object
diff --git a/arch/arm/kernel/signal.c b/arch/arm/kernel/signal.c
index 423663e23791..b6cda06b455f 100644
--- a/arch/arm/kernel/signal.c
+++ b/arch/arm/kernel/signal.c
@@ -562,6 +562,12 @@ static int do_signal(struct pt_regs *regs, int syscall)
 asmlinkage int
 do_work_pending(struct pt_regs *regs, unsigned int thread_flags, int syscall)
 {
+	/*
+	 * The assembly code enters us with IRQs off, but it hasn't
+	 * informed the tracing code of that for efficiency reasons.
+	 * Update the trace code with the current status.
+	 */
+	trace_hardirqs_off();
 	do {
 		if (likely(thread_flags & _TIF_NEED_RESCHED)) {
 			schedule();
-- 
2.1.0



From rmk+kernel at arm.linux.org.uk  Fri Aug 21 06:48:30 2015
From: rmk+kernel at arm.linux.org.uk (Russell King)
Date: Fri, 21 Aug 2015 14:48:30 +0100
Subject: [PATCH 4/4] ARM: entry: ensure that IRQs are enabled when calling
 syscall_trace_exit()
In-Reply-To: <20150821134630.GW7557@n2100.arm.linux.org.uk>
References: <20150821134630.GW7557@n2100.arm.linux.org.uk>
Message-ID: <E1ZSmgI-00044i-JK@rmk-PC.arm.linux.org.uk>

The audit code looks like it's been written to cope with being called
with IRQs enabled.  However, it's unclear whether IRQs should be
enabled or disabled when calling the syscall tracing infrastructure.

Right now, sometimes we call this with IRQs enabled, and other times
with IRQs disabled.  Opt for IRQs being enabled for consistency.

Signed-off-by: Russell King <rmk+kernel at arm.linux.org.uk>
---
 arch/arm/kernel/entry-common.S | 2 +-
 1 file changed, 1 insertion(+), 1 deletion(-)

diff --git a/arch/arm/kernel/entry-common.S b/arch/arm/kernel/entry-common.S
index dd3721d1185e..d83a40d8e055 100644
--- a/arch/arm/kernel/entry-common.S
+++ b/arch/arm/kernel/entry-common.S
@@ -275,7 +275,7 @@ __sys_trace_return:
 	b	ret_slow_syscall
 
 __sys_trace_return_nosave:
-	asm_trace_hardirqs_off save=0
+	enable_irq_notrace
 	mov	r0, sp
 	bl	syscall_trace_exit
 	b	ret_slow_syscall
-- 
2.1.0



From arnd at arndb.de  Fri Aug 21 07:00:35 2015
From: arnd at arndb.de (Arnd Bergmann)
Date: Fri, 21 Aug 2015 16:00:35 +0200
Subject: =?UTF-8?B?562U5aSNOg==?= [PATCH 1/5] net: add Hisilicon Network
 Subsystem support (config and documents)
In-Reply-To: <161EFA05D917D0419F95C4CAEEF86C1094E95FAA@SZXEMA504-MBS.china.huawei.com>
References: <1439548222-231611-1-git-send-email-liguozhu@hisilicon.com>
 <1536926.jEJjsM70Lj@wuerfel>
 <161EFA05D917D0419F95C4CAEEF86C1094E95FAA@SZXEMA504-MBS.china.huawei.com>
Message-ID: <2543796.7JthO5WCfI@wuerfel>

On Monday 17 August 2015 01:28:07 Liguozhu wrote:
> Thanks, Arnd. 
> 
> Regarding the ae-name: it is the name of the Acceleration Engine. It is provided
> by the BIOS according to the position and the feature enabled of the IP.
> So "soc0" means it is on SoC No. 0, while "n4" means it is running on 
>"Non-dsaf mode 4". Ideally, we should setup the rule to name it. But as I
> said in the patchset, the IP is original designed for a bare metal solution,
> it is worthless to export all modes and we are planning to add more mode
> for Linux itself in the IP in future version. So I think the better way is
> to leave it as a "name" but add more meaning in the future.

The name property is a bit awkward. The position is normally implied by
the location of the parent device in the DT, so you should not need that
at all and instead derive it elsewhere. You can also add strings to the
compatible property instead of this, to signify differences in the programming
that are based on how the IP block is used.
 
> Regarding the ae-opts: it is the initial value for the AE's runtime options,
> Currently, we have only "port number" (there are 6XGE+2GE port for a DSAF AE)
> as option. But for future version, we will add other options such as "enable
> Spanning Tree Protocol algorithm)" and so on. 

I think these can easily be converted into an index property and boolean
flags (present if true, absent otherwise) for additional features.
 
> Should I add these background to somewhere?

The binding document needs to list all supported configurations, if you
have a string property, describe specifically what strings are allowed
and what they mean, but better try to avoid strings altogether.

	Arnd


From arnd at arndb.de  Fri Aug 21 07:01:02 2015
From: arnd at arndb.de (Arnd Bergmann)
Date: Fri, 21 Aug 2015 16:01:02 +0200
Subject: [PATCH 3/5] net: add Hisilicon Network Subsystem MDIO support
In-Reply-To: <20150817091750.GA134983@Turing-Arch-b>
References: <1439548222-231611-1-git-send-email-liguozhu@hisilicon.com>
 <2142879.tTtWetb0nc@wuerfel> <20150817091750.GA134983@Turing-Arch-b>
Message-ID: <2127960.zhC3sTrby5@wuerfel>

On Monday 17 August 2015 17:17:50 Kenneth Lee wrote:
> Thanks, Arnd, 
> 
> You are right. This is the same IP as hip04_mdio.c. We just mis-understand the
> hardware design. We will merge them and re-submit the patches.

Ok, great!

	Arnd


From gabriele.paoloni at huawei.com  Fri Aug 21 07:19:32 2015
From: gabriele.paoloni at huawei.com (Gabriele Paoloni)
Date: Fri, 21 Aug 2015 14:19:32 +0000
Subject: [PATCH v7 3/6] PCI: designware: Add ARM64 support
In-Reply-To: <20150821134230.GQ1020@e106497-lin.cambridge.arm.com>
References: <1439812554-180426-1-git-send-email-wangzhou1@hisilicon.com>
 <1439812554-180426-4-git-send-email-wangzhou1@hisilicon.com>
 <1439988852.31432.15.camel@pengutronix.de>
 <EE11001F9E5DDD47B7634E2F8A612F2E01D81315@lhreml503-mbs>
 <1439998622.31432.44.camel@pengutronix.de>
 <EE11001F9E5DDD47B7634E2F8A612F2E01D8139B@lhreml503-mbs>
 <1440059243.31432.59.camel@pengutronix.de>
 <EE11001F9E5DDD47B7634E2F8A612F2E01D81BAC@lhreml503-mbs>
 <20150821134230.GQ1020@e106497-lin.cambridge.arm.com>
Message-ID: <EE11001F9E5DDD47B7634E2F8A612F2E01D826BD@lhreml503-mbs>

Hi Liviu

Many Thanks for reviewing

> -----Original Message-----
> From: linux-pci-owner at vger.kernel.org [mailto:linux-pci-
> owner at vger.kernel.org] On Behalf Of Liviu Dudau
> Sent: Friday, August 21, 2015 2:43 PM
> To: Gabriele Paoloni
> Cc: Lucas Stach; Wangzhou (B); Bjorn Helgaas; jingoohan1 at gmail.com;
> Pratyush Anand; Arnd Bergmann; linux at arm.linux.org.uk;
> thomas.petazzoni at free-electrons.com; Lorenzo Pieralisi; James Morse;
> jason at lakedaemon.net; robh at kernel.org; linux-pci at vger.kernel.org;
> linux-arm-kernel at lists.infradead.org; devicetree at vger.kernel.org;
> Yuanzhichang; Zhudacai; zhangjukuo; qiuzhenfa; liudongdong (C);
> qiujiang; xuwei (O); Liguozhu (Kenneth)
> Subject: Re: [PATCH v7 3/6] PCI: designware: Add ARM64 support
> 
> On Thu, Aug 20, 2015 at 12:10:24PM +0100, Gabriele Paoloni wrote:
> > Hi Lucas
> >
> > Again many thanks for explaining and for your time.
> >
> > I got your point now and I have dug a bit better in the PCI_DOMAINS
> code.
> >
> > However I have a question...see inline below
> >
> > > -----Original Message-----
> > > From: Lucas Stach [mailto:l.stach at pengutronix.de]
> > > Sent: Thursday, August 20, 2015 9:27 AM
> > > To: Gabriele Paoloni
> > > Cc: Wangzhou (B); Bjorn Helgaas; jingoohan1 at gmail.com; Pratyush
> Anand;
> > > Arnd Bergmann; linux at arm.linux.org.uk; thomas.petazzoni at free-
> > > electrons.com; lorenzo.pieralisi at arm.com; james.morse at arm.com;
> > > Liviu.Dudau at arm.com; jason at lakedaemon.net; robh at kernel.org; linux-
> > > pci at vger.kernel.org; linux-arm-kernel at lists.infradead.org;
> > > devicetree at vger.kernel.org; Yuanzhichang; Zhudacai; zhangjukuo;
> > > qiuzhenfa; liudongdong (C); qiujiang; xuwei (O); Liguozhu (Kenneth)
> > > Subject: Re: [PATCH v7 3/6] PCI: designware: Add ARM64 support
> > >
> > > Hi Gab,
> > >
> > > Am Mittwoch, den 19.08.2015, 16:34 +0000 schrieb Gabriele Paoloni:
> > > > Hi Lucas
> > > >
> > > > First of all many thanks for the quick reply, really appreciated
> > > >
> > > > > -----Original Message-----
> > > > > From: Lucas Stach [mailto:l.stach at pengutronix.de]
> > > > > Sent: Wednesday, August 19, 2015 4:37 PM
> > > > > To: Gabriele Paoloni
> > > > > Cc: Wangzhou (B); Bjorn Helgaas; jingoohan1 at gmail.com; Pratyush
> > > Anand;
> > > > > Arnd Bergmann; linux at arm.linux.org.uk; thomas.petazzoni at free-
> > > > > electrons.com; lorenzo.pieralisi at arm.com; james.morse at arm.com;
> > > > > Liviu.Dudau at arm.com; jason at lakedaemon.net; robh at kernel.org;
> linux-
> > > > > pci at vger.kernel.org; linux-arm-kernel at lists.infradead.org;
> > > > > devicetree at vger.kernel.org; Yuanzhichang; Zhudacai; zhangjukuo;
> > > > > qiuzhenfa; liudongdong (C); qiujiang; xuwei (O); Liguozhu
> (Kenneth)
> > > > > Subject: Re: [PATCH v7 3/6] PCI: designware: Add ARM64 support
> > > > >
> > > > > Hi Gab,
> > > > >
> > > > > Am Mittwoch, den 19.08.2015, 15:16 +0000 schrieb Gabriele
> Paoloni:
> > > > > > Hi Lucas
> > > > > >
> > > > > > I have rewritten the patch to take into account multiple
> > > controllers.
> > > > > >
> > > > > > As you can see now there is a static var in
> dw_pcie_host_init()
> > > that
> > > > > tracks
> > > > > > the bus numbers used.
> > > > >
> > > > > This is wrong. The DT specifies the valid bus number range. You
> can
> > > not
> > > > > just assign the next free bus number to the root bus.
> > > >
> > > > I think this is what is being done in
> > > > http://lxr.free-
> electrons.com/source/arch/arm/kernel/bios32.c#L495
> > > > and currently designware assigns the root bus number in
> > > > http://lxr.free-electrons.com/source/drivers/pci/host/pcie-
> > > designware.c#L730
> > > >
> > > You found the right spot. It works a bit different than I remember,
> but
> > > is less broken than your current code. :)
> > >
> > > It actually assigns the next instance a root bus number behind the
> > > current instances bus range. Please note the difference to your
> code
> > > which assigns the next free bus number, which may still lay within
> the
> > > current instances bus range.
> 
> Hi Gabriele,
> 
> >
> > Mmmm here I have done a mistake: in the current designware the number
> of hw
> > controllers is always 1
> > http://lxr.free-electrons.com/source/drivers/pci/host/pcie-
> designware.c#L510
> > So the loop in bios32.c does not work on multiple PCIe ports...
> 
> Bios32.c is broken for multiple PCIe hosts for multiple reasons, this
> is just
> one of them. Hence the effort to get rid of it for maintained drivers.

As you can see we're pushing hard for this :)

> 
> > However your comment about PCI_DOMAINS enlightened my mind and now I
> see
> > that when CONFIG_PCI_DOMAINS is defined we have the domains numbers
> > (tracked by __domain_nr).
> 
> CONFIG_PCI_DOMAINS in itself doesn't do much without adding code to
> your driver.
> You could request a new domain for each controller with a special
> property to
> disable that behaviour in the dts, or you could enable
> CONFIG_PCI_DOMAINS_GENERIC
> which will give you a new domain automatically.

So far I see that for ARM and ARM64 CONFIG_PCI_DOMAINS_GENERIC defaults to 
the same value as CONFIG_PCI_DOMAINS (see arch/arm/Kconfig, arch/arm64/Kconfig). 
So I think this is how current designware based drivers get multiple PCIe 
controller to work (they just enable CONFIG_PCI_DOMAINS)...

 

> 
> > So (correct me if I am wrong) if we have 2 PCIe ports that do not
> specify
> > the "bus-range" property, both root ports will enumerate starting
> from
> > root_bus_nr = 0 and everything will still work ok.
> 
> Correct.
> 
> Best regards,
> Liviu
> 
> >
> > So if my assumption is correct, I do not see why the orginal patch
> from Wang
> > Zhou is wrong.
> > The only point can be that assigning pp->root_bus_nr = 0 is not
> required
> > as pp memory is kzalloc'ed (an therefore init to zero).
> >
> >
> > >
> > > >
> > > > In general I agree with you but if you look at all the current
> > > drivers
> > > > based on designware none of them define the "bus-range" dtb
> property.
> > > > Therefore doing as you say would break the current driver when we
> > > have
> > > > multiple controllers...am I right?
> > > >
> > > The current _code_ works fine for multiple controllers. It's just
> that
> > > you must define the bus range property in the DTB if you want to
> enable
> > > multiple instances of one controller and support a kernel without
> PCI
> > > domains support. As all current implementations have only a single
> > > instance of the controller per SoC, or depend on PCI domain support,
> > > it's totally fine for them to not define the bus ranges property,
> as
> > > it's an optional property and it is well defined how things behave
> if
> > > it
> > > is absent. We absolutely need to keep that specified behavior.
> > >
> > > > If that is the case in order to fix this in the way you say I
> would
> > > need
> > > > to assign "bus-range" for all the PCIe drivers with multiple
> > > controllers:
> > > > in this case I would split the default range evenly (that is, if
> we
> > > have
> > > > two controllers I would define "bus-range"  0-127 and 128-255)
> > > >
> > > > If you think this solution is ok I can go for it. My only doubt
> was
> > > about
> > > > touching other vendors DTBs....
> > > >
> > > You don't need to touch any of the current DTBs, as they are fine
> with
> > > the default bus range behavior. You need to keep the specified
> behavior
> > > of the bus range property with the new code.
> > >
> > > Regards,
> > > Lucas
> > > >
> > > > >
> > > > > It is perfectly valid to have a bus range of 0x00-0x10 assigned
> to
> > > one
> > > > > instance and 0x50-0xff to the next instance. Additional with
> PCIe
> > > > > hotplug you may not use the full range of the bus numbers on
> one
> > > > > instance at the first scan, but only later populate more buses
> when
> > > > > more
> > > > > bridges are added to the tree.
> > > > >
> > > > > > Drivers that do not specify the bus range in the DTB set pp-
> > > > > >root_bus_nr = DW_ROOT_NR_UNDEFINED.
> > > > > > Designware will check if the flag is set and will use the
> > > automatic
> > > > > bus range
> > > > > > assignment.
> > > > >
> > > > > No, please lets get rid of this assignment altogether. The glue
> > > drivers
> > > > > have no business in assigning the bus range. Please remove the
> > > > > pp->root_bus_nr assignment from all the glue drivers.
> > > > >
> > > > > "bus range" is a generic DW PCIe property, so just parse the
> root
> > > bus
> > > > > number from the DT, it is handled the same way for all the DW
> based
> > > > > PCIe
> > > > > drivers. The bindings specifies that if the bus range property
> is
> > > > > missing the range is 0x00-0xff, so you can default to 0 as the
> root
> > > bus
> > > > > number in that case.
> > > > >
> > > > > Also I would think this conversion warrants a patch on its own
> and
> > > > > should not be mixed in the ARM64 support patch.
> > > > >
> > > > > Regards,
> > > > > Lucas
> > > > >
> > >
> > > --
> > > Pengutronix e.K.             | Lucas Stach                 |
> > > Industrial Linux Solutions   | http://www.pengutronix.de/  |
> >
> 
> --
> ====================
> | I would like to |
> | fix the world,  |
> | but they're not |
> | giving me the   |
>  \ source code!  /
>   ---------------
>     ?\_(?)_/?
> 
> --
> To unsubscribe from this list: send the line "unsubscribe linux-pci" in
> the body of a message to majordomo at vger.kernel.org
> More majordomo info at  http://vger.kernel.org/majordomo-info.html

From yingjoe.chen at mediatek.com  Fri Aug 21 07:39:10 2015
From: yingjoe.chen at mediatek.com (Yingjoe Chen)
Date: Fri, 21 Aug 2015 22:39:10 +0800
Subject: [PATCH v2 1/5] clocksource: mediatek: do not enable GPT_CLK_EVT
 when setup
In-Reply-To: <55D5E40A.6080904@linaro.org>
References: <CAGS+omD8k_Cfxv3bYyjmjtLbiavo-WmJPn0Z-CBhN_nnv65Tag@mail.gmail.com>
 <1437552878-3684-1-git-send-email-yingjoe.chen@mediatek.com>
 <55CC56C4.8080201@linaro.org> <1439820602.3414.12.camel@mtksdaap41>
 <55D5E40A.6080904@linaro.org>
Message-ID: <1440167950.20169.29.camel@mtksdaap41>

On Thu, 2015-08-20 at 16:28 +0200, Daniel Lezcano wrote:
> On 08/17/2015 04:10 PM, Yingjoe Chen wrote:
> > On Thu, 2015-08-13 at 10:35 +0200, Daniel Lezcano wrote:
> >> On 07/22/2015 10:14 AM, Yingjoe Chen wrote:
> >>> Spurious mtk timer interrupt is noticed at boot and cause kernel
> >>> crash. It seems if GPT is enabled, it will latch irq status even
> >>> when its IRQ is disabled.
> 
> It "seems" ?

Hi,

Datasheet doesn't mention detail. So I did some experiments, playing
around with registers. Based on my observation, I think this is what
happens:

For each GPT timer, it has ENABLE, IRQ_EN, IRQ status, IRQ_ACK, counter
& compare.

When mtk_timer_init calls mtk_timer_setup to setup GPT_CLK_EVT, it
enable the timer but didn't set counter or compare. Both counter &
compare is zero on reset, so GPT immediately raise IRQ status. IRQ_EN is
still disabled now, so it didn't trigger interrupt right away.

At end of mtk_timer_init, it calls mtk_timer_enable_irq to enable irq.
Since IRQ status is 1 now, GPT trigger interrupt immediately. The
interrupt is serviced by mtk_timer_interrupt. Since this is not an
expected event, evt->dev.event_handler will be NULL and system crashed
in the handler.

> >>> When irq is enabled afterward, we see
> >>> spurious interrupt.
> 
> Doesn't have the firmware something to do with that ?

We have 6 GPT on mt8173, mtk timer use 2 of them. The spurious interrupt
only happens on GPT_CLK_EVT (GPT1). Our firmware didn't touch that one,
so it is in reset default when mtk timer driver try to enable it.

> I have a mtk 8173 board I can use next week. How do you reproduce the 
> issue ?
>
> >>> Change init flow to only enable GPT_CLK_SRC at mtk_timer_init.
> >>>
> >>> Acked-by: Matthias Brugger <matthias.bgg at gmail.com>
> >>> Reviewed-by: Daniel Kurtz <djkurtz at chromium.org>
> >>> Signed-off-by: Yingjoe Chen <yingjoe.chen at mediatek.com>
> >>> ---
> >>>
> >>> Update to my patch [1], added __init as Daniel suggest. This is the
> >>> only patch that need to change in that series, so I only sent this one.
> >>>
> >>> http://lists.infradead.org/pipermail/linux-mediatek/2015-July/001545.html
> >>>
> >>>    drivers/clocksource/mtk_timer.c | 16 ++++++++++------
> >>>    1 file changed, 10 insertions(+), 6 deletions(-)
> >>>
> >>> diff --git a/drivers/clocksource/mtk_timer.c b/drivers/clocksource/mtk_timer.c
> >>> index 68ab423..2ba5b66 100644
> >>> --- a/drivers/clocksource/mtk_timer.c
> >>> +++ b/drivers/clocksource/mtk_timer.c
> >>> @@ -156,9 +156,11 @@ static void mtk_timer_global_reset(struct mtk_clock_event_device *evt)
> >>>    	writel(0x3f, evt->gpt_base + GPT_IRQ_ACK_REG);
> >>>    }
> >>>
> >>> -static void
> >>> -mtk_timer_setup(struct mtk_clock_event_device *evt, u8 timer, u8 option)
> >>> +static void __init mtk_timer_setup(struct mtk_clock_event_device *evt,
> >>> +				   u8 timer, u8 option, bool enable)
> >>>    {
> >>> +	u32 val;
> >>> +
> >>>    	writel(TIMER_CTRL_CLEAR | TIMER_CTRL_DISABLE,
> >>>    		evt->gpt_base + TIMER_CTRL_REG(timer));
> >>>
> >>> @@ -167,8 +169,10 @@ mtk_timer_setup(struct mtk_clock_event_device *evt, u8 timer, u8 option)
> >>>
> >>>    	writel(0x0, evt->gpt_base + TIMER_CMP_REG(timer));
> >>>
> >>> -	writel(TIMER_CTRL_OP(option) | TIMER_CTRL_ENABLE,
> >>> -			evt->gpt_base + TIMER_CTRL_REG(timer));
> >>> +	val = TIMER_CTRL_OP(option);
> >>> +	if (enable)
> >>> +		val |= TIMER_CTRL_ENABLE;
> >>> +	writel(val, evt->gpt_base + TIMER_CTRL_REG(timer));
> >>
> >> Instead of the 'enable' new option, I prefer a test with 'timer' with a
> >> comment:
> >>
> >> 	/*
> >> 	 * the timer hw is broken in that way ... bla bla, so we only
> >> 	 * enable the clocksource ...
> >> 	 */
> >> 	if (timer == GPT_CLK_SRC)
> >> 		val |= TIMER_CTRL_ENABLE;
> >
> > Hi Daniel,
> >
> > Thanks for your review.
> > Since this bug happens to anyone using interrupt,
> 
> Can you elaborate ? I don't get the point.
> 
> > I'm not sure checking
> > timer and only enable it for GPT_CLK_SRC is easier to read. Anyway, I'll
> > change to this in next version.
> >> That said, can you have a look at commit 1096be08 ?
> >> "clockevents: sun5i: Fix setup_irq init sequence"
> >>
> >> first and check if moving the interrupt request after the
> >> clockevents_config_and_register could fix your issue.
> >
> > I've tested this before, see:
> >
> > http://lists.infradead.org/pipermail/linux-mediatek/2015-May/000539.html
> > http://lists.infradead.org/pipermail/linux-mediatek/2015-May/000551.html
> 
> I could take or ack this patch trusting it fixes the issue but there are 
> some points that need clarifications.
> 
>   - Does the spurious interrupt occurs *every* time ? at each boot ?

Yes. If you applied this series to enable mtk timer without this fix on
mt8173 or mt8135 you can reproduce it. It occurs for every boot.

It crash before uart driver is ready, so you'll have to use earlycon to
see the crash log.

> The previous patches were supposed to fix the issue but they actually 
> didn't. So how is tested the patch ?

I'm not sure. I believe Matthias test that one on mt6589, maybe it have
different behavior, or different timing.

> Regarding the different fixes for this problem, it sounds like you are 
> proceeding by trial and error.
> 
> Please give a more detailed analysis of the problem and especially check 
> the timer is not altered by the firmware leaving it in a transient state 
> or whatever.

See above for my analysis.
Thanks.

Joe.C




From gregory.clement at free-electrons.com  Fri Aug 21 08:50:56 2015
From: gregory.clement at free-electrons.com (Gregory CLEMENT)
Date: Fri, 21 Aug 2015 17:50:56 +0200
Subject: [GIT PULL] ARM: mvebu: cleanup changes for v4.3
Message-ID: <55D748E0.3080004@free-electrons.com>

Hi,

Here is the first pull request for fixes for mvebu for v4.2.
I hope it is not too late, if it can't make ti for 4.2, then we
will apply it on 4.3, anyway the bug is here since 3.18.

Gregory

The following changes since commit d770e558e21961ad6cfdf0ff7df0eb5d7d4f0754:

  Linux 4.2-rc1 (2015-07-05 11:01:52 -0700)

are available in the git repository at:

  git://git.infradead.org/linux-mvebu.git tags/mvebu-fixes-4.2-1

for you to fetch changes up to 5be9fc23cdb42e1d383ecc8eae8a8ff70a752708:

  ARM: orion5x: fix legacy orion5x IRQ numbers (2015-08-21 17:33:08 +0200)

----------------------------------------------------------------
mvebu fixes changes for v4.2

Fix legacy orion5x IRQ numbers broken since 3.18

----------------------------------------------------------------
Benjamin Cama (1):
      ARM: orion5x: fix legacy orion5x IRQ numbers

 arch/arm/Kconfig                          |  1 +
 arch/arm/mach-orion5x/include/mach/irqs.h | 64 +++++++++++++++----------------
 arch/arm/mach-orion5x/irq.c               |  4 +-
 3 files changed, 35 insertions(+), 34 deletions(-)

-- 
Gregory Clement, Free Electrons
Kernel, drivers, real-time and embedded Linux
development, consulting, training and support.
http://free-electrons.com




From gregory.clement at free-electrons.com  Fri Aug 21 08:53:21 2015
From: gregory.clement at free-electrons.com (Gregory CLEMENT)
Date: Fri, 21 Aug 2015 17:53:21 +0200
Subject: [GIT PULL] ARM: mvebu: cleanup changes for v4.3
In-Reply-To: <55D748E0.3080004@free-electrons.com>
References: <55D748E0.3080004@free-electrons.com>
Message-ID: <55D74971.2090404@free-electrons.com>

On 21/08/2015 17:50, Gregory CLEMENT wrote:
> Hi,
> 
> Here is the first pull request for fixes for mvebu for v4.2.

Obviously the title is wrong! it is really a fix for 4.2 and not a
cleanup for 4.3

> I hope it is not too late, if it can't make ti for 4.2, then we
> will apply it on 4.3, anyway the bug is here since 3.18.
> 
> Gregory
> 
> The following changes since commit d770e558e21961ad6cfdf0ff7df0eb5d7d4f0754:
> 
>   Linux 4.2-rc1 (2015-07-05 11:01:52 -0700)
> 
> are available in the git repository at:
> 
>   git://git.infradead.org/linux-mvebu.git tags/mvebu-fixes-4.2-1
> 
> for you to fetch changes up to 5be9fc23cdb42e1d383ecc8eae8a8ff70a752708:
> 
>   ARM: orion5x: fix legacy orion5x IRQ numbers (2015-08-21 17:33:08 +0200)
> 
> ----------------------------------------------------------------
> mvebu fixes changes for v4.2
> 
> Fix legacy orion5x IRQ numbers broken since 3.18
> 
> ----------------------------------------------------------------
> Benjamin Cama (1):
>       ARM: orion5x: fix legacy orion5x IRQ numbers
> 
>  arch/arm/Kconfig                          |  1 +
>  arch/arm/mach-orion5x/include/mach/irqs.h | 64 +++++++++++++++----------------
>  arch/arm/mach-orion5x/irq.c               |  4 +-
>  3 files changed, 35 insertions(+), 34 deletions(-)
> 


-- 
Gregory Clement, Free Electrons
Kernel, drivers, real-time and embedded Linux
development, consulting, training and support.
http://free-electrons.com


From catalin.marinas at arm.com  Fri Aug 21 08:54:25 2015
From: catalin.marinas at arm.com (Catalin Marinas)
Date: Fri, 21 Aug 2015 16:54:25 +0100
Subject: [PATCH] arm64: enable generic idle loop
In-Reply-To: <20150821091446.GB4280@leoy-linaro>
References: <1440128422-4170-1-git-send-email-leo.yan@linaro.org>
 <20150821090043.GA14072@e104818-lin.cambridge.arm.com>
 <20150821091446.GB4280@leoy-linaro>
Message-ID: <20150821155425.GC16410@e104818-lin.cambridge.arm.com>

On Fri, Aug 21, 2015 at 05:14:46PM +0800, Leo Yan wrote:
> On Fri, Aug 21, 2015 at 10:00:43AM +0100, Catalin Marinas wrote:
> > On Fri, Aug 21, 2015 at 11:40:22AM +0800, Leo Yan wrote:
> > > Enable generic idle loop for ARM64, so can support for hlt/nohlt
> > > command line options to override default idle loop behavior.
> > 
> > Just curious, what do you need this for?
> 
> With this config, usually we can add "nohlt" in command line to force
> the cpu will never be powered off; so can quickly narrow down if some
> issues are related with cpuidle or not.
> 
> And if CPU is powered off, then its debug logic also will be powered off.
> So we can simply use this method to let debugger always hot connect with
> the target CPU.

OK.

Acked-by: Catalin Marinas <catalin.marinas at arm.com>


From gregory.clement at free-electrons.com  Fri Aug 21 08:55:38 2015
From: gregory.clement at free-electrons.com (Gregory CLEMENT)
Date: Fri, 21 Aug 2015 17:55:38 +0200
Subject: [PATCH] ARM: orion5x: fix legacy orion5x IRQ numbers
In-Reply-To: <1440156836.5070.9.camel@dolka.fr>
References: <1439648246-32757-1-git-send-email-gregory.clement@free-electrons.com>
 <1440156836.5070.9.camel@dolka.fr>
Message-ID: <55D749FA.6010600@free-electrons.com>

Hi Benjamin,

On 21/08/2015 13:33, Benjamin Cama wrote:
> Hi Gr?gory,
> 
> Le samedi 15 ao?t 2015 ? 16:17 +0200, Gregory CLEMENT a ?crit :
>> I amended the patch from Benjamin as it break the build for
>> dove. Could you test it again wit this version?
> 
> Thanks for the fix. I don't have much time to test it, but as the dts
> conversion patch for my Linkstation Mini is in the series, this fix
> shouldn't change anything, as the dts board file uses the generic
> irqchip handler, isn't it?
> 
> Tell me if I missed something. Regards,

Detlef tested it so it's OK. I was asking you also because it a patch
you wrote.


Thanks,

Gregory


> --
> benjamin
> 


-- 
Gregory Clement, Free Electrons
Kernel, drivers, real-time and embedded Linux
development, consulting, training and support.
http://free-electrons.com


From gregory.clement at free-electrons.com  Fri Aug 21 09:01:14 2015
From: gregory.clement at free-electrons.com (Gregory CLEMENT)
Date: Fri, 21 Aug 2015 18:01:14 +0200
Subject: [PATCH v2 2/2] ARM: dma-mapping: Fix the coherent case when iommu
 is used
In-Reply-To: <20150814175505.GB21966@e104818-lin.cambridge.arm.com>
References: <1439568776-17864-1-git-send-email-gregory.clement@free-electrons.com>
 <1439568776-17864-3-git-send-email-gregory.clement@free-electrons.com>
 <20150814175505.GB21966@e104818-lin.cambridge.arm.com>
Message-ID: <55D74B4A.4000800@free-electrons.com>

Hi Catalin,

Sorry to answer only today, I xas busy on other task until now.

On 14/08/2015 19:55, Catalin Marinas wrote:
> On Fri, Aug 14, 2015 at 06:12:56PM +0200, Gregory CLEMENT wrote:
>> When doing dma allocation with IOMMU the __iommu_alloc_atomic() was
>> used even when the system was coherent. However, this function
>> allocates from a non-cacheable pool, which is fine when the device is
>> not cache coherent but won't work as expected in the device is cache
>> coherent. Indeed, the CPU and device must access the memory using the
>> same cacheability attributes.
>>
>> Tested-by: We need someone here
> 
> And at least a build on your side ;).

It build but I forgot to set the CONFIG_ARM_DMA_USE_IOMMU config!

> 
> Rob Herring added the coherent IOMMU ops in commit 0fa478df444f ("ARM:
> add coherent iommu dma ops"). But it doesn't look like he needed the
> coherent DMA API, only the streaming one.
> 
>> @@ -1885,7 +1903,7 @@ struct dma_map_ops iommu_ops = {
>>  };
>>  
>>  struct dma_map_ops iommu_coherent_ops = {
>> -	.alloc		= arm_iommu_alloc_attrs,
>> +	.alloc		= arm_coherent_iommu_alloc_attrs,
>>  	.free		= arm_iommu_free_attrs,
> 
> Does this compile? You renamed arm_iommu_free_attrs to
> __arm_iommu_alloc_attrs but I don't see arm_iommu_free_attrs
> and arm_coherent_iommu_free_attrs functions.
> 
>>  	.mmap		= arm_iommu_mmap_attrs,
> 
> And we need an arm_coherent_iommu_mmap_attrs (similar to
> arm_iommu_mmap_attrs but without __get_dma_pgprot. Use
> arm_(coherent_)dma_mmap as an example.
> 
I am going to take care of it

Thanks,

Gregory


-- 
Gregory Clement, Free Electrons
Kernel, drivers, real-time and embedded Linux
development, consulting, training and support.
http://free-electrons.com


From olof at lixom.net  Fri Aug 21 09:09:05 2015
From: olof at lixom.net (Olof Johansson)
Date: Fri, 21 Aug 2015 09:09:05 -0700
Subject: [GIT PULL 8/9] ARM: tegra: Devicetree changes for v4.3-rc1
In-Reply-To: <20150821015848.GM4865@localhost>
References: <1439563720-13189-1-git-send-email-thierry.reding@gmail.com>
 <1439563720-13189-9-git-send-email-thierry.reding@gmail.com>
 <20150821015848.GM4865@localhost>
Message-ID: <20150821160905.GP4865@localhost>

On Thu, Aug 20, 2015 at 06:58:48PM -0700, Olof Johansson wrote:
> On Fri, Aug 14, 2015 at 04:48:39PM +0200, Thierry Reding wrote:
> > Hi ARM SoC maintainers,
> > 
> > The following changes since commit d770e558e21961ad6cfdf0ff7df0eb5d7d4f0754:
> > 
> >   Linux 4.2-rc1 (2015-07-05 11:01:52 -0700)
> > 
> > are available in the git repository at:
> > 
> >   git://git.kernel.org/pub/scm/linux/kernel/git/tegra/linux.git tags/tegra-for-4.3-dt
> > 
> > for you to fetch changes up to 6909c6632fdbea441b5077b4f882c0bf4b71997e:
> > 
> >   ARM: tegra: Add gpio-ranges property (2015-08-13 16:31:53 +0200)
> > 
> > Thanks,
> > Thierry
> > 
> > ----------------------------------------------------------------
> > ARM: tegra: Devicetree changes for v4.3-rc1
> > 
> > Enables CPU frequency scaling on Jetson TK1 and enables the GK20A GPU on
> > Venice2 and Jetson TK1. This also enables support for the PMU hardware
> > found on Tegra124, which among other things, can be used for performance
> > measurements.
> 
> Merged, thanks.

This caused build failures due to missing tegra124-car.h:

http://arm-soc.lixom.net/buildlogs/arm-soc/v4.2-rc2-954-g5825349/buildall.arm.tegra_defconfig.log.failed

I've dropped this branch again.


-Olof


From olof at lixom.net  Fri Aug 21 09:10:15 2015
From: olof at lixom.net (Olof Johansson)
Date: Fri, 21 Aug 2015 09:10:15 -0700
Subject: [GIT PULL] Xilinx Zynq DT changes for v4.3 v2
In-Reply-To: <55D6C6D9.3070401@monstr.eu>
References: <55D4646F.7010404@monstr.eu> <20150821020322.GO4865@localhost>
 <55D6C6D9.3070401@monstr.eu>
Message-ID: <20150821161015.GA14452@localhost>

On Fri, Aug 21, 2015 at 08:36:09AM +0200, Michal Simek wrote:
> On 08/21/2015 04:03 AM, Olof Johansson wrote:
> > On Wed, Aug 19, 2015 at 01:11:43PM +0200, Michal Simek wrote:
> >> Hi guys,
> >>
> >> Philipp just sent his PR to you with adding reset controller for Zynq
> >> (http://www.spinics.net/lists/arm-kernel/msg440136.html).
> >> Can you please consider to add this one more patch to your tree?
> >> It is one more patch on the top of existing zynq/dt branch which you
> >> already have in arm-soc git repo.
> > 
> > The change is small enough, so yes we can merge it with the below fixed:
> > 
> >> Moritz Fischer (1):
> >>       dts: zynq: Add devicetree entry for Xilinx Zynq reset controller.
> > 
> > ARM: dts: <....> is the format we want here -- that's what most other platforms
> > use as well. I.e. please add ARM as a prefix.
> 
> ok. Will keep my eye on it.
> 
> > 
> > I can do it here and just apply as a patch too instead of merging, just let me
> > know.
> 
> Yes that will be great if you can do that change on your side.

Great, patch applied to next/dt.


-Olof


From olof at lixom.net  Fri Aug 21 09:12:30 2015
From: olof at lixom.net (Olof Johansson)
Date: Fri, 21 Aug 2015 09:12:30 -0700
Subject: [GIT PULL] ARM: mvebu: cleanup changes for v4.3
In-Reply-To: <55D748E0.3080004@free-electrons.com>
References: <55D748E0.3080004@free-electrons.com>
Message-ID: <20150821161230.GB14452@localhost>

Hi,

On Fri, Aug 21, 2015 at 05:50:56PM +0200, Gregory CLEMENT wrote:
> Hi,
> 
> Here is the first pull request for fixes for mvebu for v4.2.
> I hope it is not too late, if it can't make ti for 4.2, then we
> will apply it on 4.3, anyway the bug is here since 3.18.

Given the longevity of the bug (i.e. not a recent regression) and the lateness
in the release cycle, I've decided to queue this up for the 4.3
next/fixes-non-critical branch instead. I.e. it'll be included in the next
merge window.

> The following changes since commit d770e558e21961ad6cfdf0ff7df0eb5d7d4f0754:
> 
>   Linux 4.2-rc1 (2015-07-05 11:01:52 -0700)
> 
> are available in the git repository at:
> 
>   git://git.infradead.org/linux-mvebu.git tags/mvebu-fixes-4.2-1
> 
> for you to fetch changes up to 5be9fc23cdb42e1d383ecc8eae8a8ff70a752708:
> 
>   ARM: orion5x: fix legacy orion5x IRQ numbers (2015-08-21 17:33:08 +0200)

Merged, thanks!


-Olof



From olof at lixom.net  Fri Aug 21 09:17:32 2015
From: olof at lixom.net (Olof Johansson)
Date: Fri, 21 Aug 2015 09:17:32 -0700
Subject: [GIT PULL] ARM64: juno: SCPI and dependent drivers for v4.3
In-Reply-To: <55CCAF50.4040503@arm.com>
References: <55C1E3FB.5090309@arm.com> <20150813124026.GD23581@localhost>
 <20150813142444.GA4602@e104818-lin.cambridge.arm.com>
 <55CCAF50.4040503@arm.com>
Message-ID: <20150821161732.GC14452@localhost>

Hi,

On Thu, Aug 13, 2015 at 03:53:04PM +0100, Sudeep Holla wrote:
> 
> 
> On 13/08/15 15:24, Catalin Marinas wrote:
> >On Thu, Aug 13, 2015 at 02:40:26PM +0200, Olof Johansson wrote:
> >>On Wed, Aug 05, 2015 at 11:22:51AM +0100, Sudeep Holla wrote:
> >>>Here is the first pull request for SCPI, clock and cpufreq support on
> >>>ARM64 Juno development platform for v4.3
> >>
> >>I'd like to hear from Catalin and Will on why ARM is doing this. Catalin
> >>and Will are pushing back very hard at vendors who don't use PSCI for
> >>CPU power management, and then they have coworkers that are looking to
> >>merge this directly into the kernel.
> >
> >Actually, the arm64 CPU power management story is pretty much handled by
> >Lorenzo and Sudeep in my team, so I trust their judgement ;). But I
> >agree with you that a better explanation on the reasons behind this is
> >needed, otherwise we risk confusing messages. I'll try to summarise it
> >below but Sudeep can reply with more details.
> >
> 
> (I will use the acronomys directly as Catalin has already explained the
> difference)
> 
> Thanks Catalin for the detailed explanation. I agree that this pull
> request has not much details, but the patch series makes reference only
> to the clocks and features provided by the SCP(System Control Processor)
> to be used by Linux(non-secure) and nothing about CPU power states that
> are handled by PSCI. This SCPI is completely independent and orthogonal
> to PSCI.

Yes, I am aware that PSCI and SCPI are two confusingly similar acronyms that
represent separate things. My concern though is that we're letting in a poorly
architected solution into the kernel with SCPI. PSCI is already choosing to
abstract this outside of the kernel. Is there a reason SCPI isn't using the
same approach?

> >PSCI only covers CPU boot/cpuidle and platform suspend. It does not have
> >any provisions for DVFS and I'm not sure this could be easily
> >standardised (or whether we could find enough supporters to get it
> >adopted).
> >
> 
> Though we are not campaigning it as aggressively as PSCI.

Which, given the resistance to pick up PSCI, this is unlikely to be used by
anyone...

> >SCPI is a (standard) interface to a coprocessor handling clocks etc. to
> >be used with cpufreq. This patchset adds support for cpufreq/dvs which
> >is not handled by PSCI. So, just to clarify the acronyms:
> >
> >SCPI - System Control and Power Interface - it's a protocol for
> >communicating with a System Control Processor (e.g. Cortex-M3) via
> >mailboxes. It is used in Linux for DVFS but this is *not* a secure/EL3
> >firmware interface (a.k.a. SMC calls). It indeed a firmware interface
> >but the firmware runs on a separate coprocessor and not on the CPU itself.
> >
> >PSCI - Power State Coordination Interface - it is a secure firmware
> >interface for coordinating the CPU power states (idle, not DVFS). The
> >firmware may use an SCPI communication channel (e.g. deeper sleep states
> >where clock changes are needed).
> >
> 
> I will add some more information to (hopefully) clarify the doubts.
> 
> SCP(System Control Processor) offers control and management of the
> core/cluster power states, various power domain DVFS including the
> core/cluster, certain system clocks configuration, thermal sensors and
> many others.
> 
> Though the core/cluster power states are also handled this SCP,
> they are accessible only through secure channels and PSCI firmware
> implementations on the platform rely on that internally. Non-secure
> access/requests are not possible.
> 
> Just to summarize, this SCP helps to offload all the power management
> work to a dedicated low power processor which can be always running.
> On Juno, its Cortex-M while on AMD Seattle it's Cortex-A5.

I understand what the SCP is used for. What I don't understand is why you're
adding all this complexity in the kernel for it.

Also, is there only one known implementation of this today on Juno? Are there
others coming soon? Single-user frameworks tend to be hard to get right, and
it's usually much better to wait until it's clear it will fit more than just
the original target.

Anyway, the git server you provided the link to in the original email
(linux-arm.org) seems to be offline so I couldn't fetch a fresh copy of
the branch to look at.

It's pretty clear this is not 4.3 material at this point, so I'll take
a look at it later.


-Olof


From bjorn.andersson at sonymobile.com  Fri Aug 21 09:21:33 2015
From: bjorn.andersson at sonymobile.com (Bjorn Andersson)
Date: Fri, 21 Aug 2015 09:21:33 -0700
Subject: [PATCH v2] qcom: ipq40xx: Add basic board/dts support for
 IPQ40XX SoC
In-Reply-To: <20150821103253.GA27466@codeaurora.org>
References: <20150821103253.GA27466@codeaurora.org>
Message-ID: <20150821162133.GF13472@usrtlx11787.corpusers.net>

On Fri 21 Aug 03:32 PDT 2015, Varadarajan Narayanan wrote:

> Add initial dts files and SoC support for IPQ40XX
> 
> Signed-off-by: Varadarajan Narayanan <varada at codeaurora.org>
> ---
> Changes in v2:
>   - Added devicetree bindings documentation
> 
>  .../devicetree/bindings/clock/qca,gcnt.txt         | 14 ++++
>  Documentation/devicetree/bindings/ipq.txt          | 16 ++++
>  arch/arm/boot/dts/Makefile                         |  3 +-
>  arch/arm/boot/dts/qcom-ipq40xx-r3pc.dts            | 33 +++++++++
>  arch/arm/boot/dts/qcom-ipq40xx.dtsi                | 86 ++++++++++++++++++++++
>  arch/arm/configs/ipq_defconfig                     |  1 +
>  arch/arm/mach-qcom/Kconfig                         |  4 +
>  arch/arm/mach-qcom/board.c                         |  1 +
>  8 files changed, 157 insertions(+), 1 deletion(-)
>  create mode 100644 Documentation/devicetree/bindings/clock/qca,gcnt.txt
>  create mode 100644 Documentation/devicetree/bindings/ipq.txt
>  create mode 100644 arch/arm/boot/dts/qcom-ipq40xx-r3pc.dts
>  create mode 100644 arch/arm/boot/dts/qcom-ipq40xx.dtsi
> 
> diff --git a/Documentation/devicetree/bindings/clock/qca,gcnt.txt b/Documentation/devicetree/bindings/clock/qca,gcnt.txt
> new file mode 100644
> index 0000000..dd0d71e
> --- /dev/null
> +++ b/Documentation/devicetree/bindings/clock/qca,gcnt.txt
> @@ -0,0 +1,14 @@
> +QCA Global Counter

I don't think I've seen the "global counter" blocks before, what is it?
What does it do? Do you have a upcoming driver for it? (Have I just
missed it?)

You add it to the dts below, but don't seem to reference it. What is
its purpose?

Also, you should split this definition into its own patch.

> +------------------------------------------------
> +
> +Required properties :
> +- compatible : "qcom,qca-gcnt"
> +
> +- reg : shall contain base register location and length
> +
> +Example:
> +
> +	counter {
> +		compatible = "qcom,qca-gcnt";
> +		reg = <0x004a1000 0x4>;

Most of the time when there's a device consuming one register it turns
out to be part of some larger hw block and down the road things get
complicated from the fact that we mapped 4 bytes in the middle.

Is this part of a larger block? Can we better implement that as a
simple-mfd or syscon?

> +	};
> diff --git a/Documentation/devicetree/bindings/ipq.txt b/Documentation/devicetree/bindings/ipq.txt
> new file mode 100644
> index 0000000..7d56bd0
> --- /dev/null
> +++ b/Documentation/devicetree/bindings/ipq.txt

This doesn't really follow the general pattern of this directory. There
are some files like this, but then you should probably name it
qualcomm.txt.

> @@ -0,0 +1,16 @@
> +Qualcomm IPQ device tree bindings
> +---------------------------------
> +
> +System on Chip
> +
> +Device tree must specify which SoC it uses, with one of the
> +following compatible strings
> +
> +       "qcom,ipq40xx"
> +
> +Platform
> +
> +Device tree must specify which Platform it uses, with one of the
> +following compatible strings
> +
> +       "qcom,ipq40xx-r3pc"

I would expect an "ipq.txt" to contain "qcom,ipq8064-ap148" and
"qcom,ipq8064" as well.

> diff --git a/arch/arm/boot/dts/Makefile b/arch/arm/boot/dts/Makefile
> index 246473a..6b4caee 100644
> --- a/arch/arm/boot/dts/Makefile
> +++ b/arch/arm/boot/dts/Makefile
> @@ -477,7 +477,8 @@ dtb-$(CONFIG_ARCH_QCOM) += \
>  	qcom-ipq8064-ap148.dtb \
>  	qcom-msm8660-surf.dtb \
>  	qcom-msm8960-cdp.dtb \
> -	qcom-msm8974-sony-xperia-honami.dtb
> +	qcom-msm8974-sony-xperia-honami.dtb \
> +	qcom-ipq40xx-r3pc.dtb

Please insert your entry alphabetically.

>  dtb-$(CONFIG_ARCH_REALVIEW) += \
>  	arm-realview-pb1176.dtb
>  dtb-$(CONFIG_ARCH_ROCKCHIP) += \
> diff --git a/arch/arm/boot/dts/qcom-ipq40xx-r3pc.dts b/arch/arm/boot/dts/qcom-ipq40xx-r3pc.dts
> new file mode 100644
> index 0000000..7e4e629
> --- /dev/null
> +++ b/arch/arm/boot/dts/qcom-ipq40xx-r3pc.dts
> @@ -0,0 +1,33 @@
> +/* Copyright (c) 2014, The Linux Foundation. All rights reserved.
> + *
> + * This program is free software; you can redistribute it and/or modify
> + * it under the terms of the GNU General Public License version 2 and
> + * only 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 "qcom-ipq40xx.dtsi"
> +
> +/ {
> +	model = "Qualcomm Technologies, Inc. IPQ40XX R3PC";
> +	compatible = "qcom,ipq40xx-r3pc", "qcom,ipq40xx";
> +
> +	memory {
> +		device_type = "memory";
> +		reg = <0x80000000 0x20000000>; /* 512MB */
> +	};
> +
> +	chosen {
> +		bootargs = "root=/dev/ram rw init=/init console=ttyMSM0,115200n8 initrd=0x82000000,0x000E2246";
> +	};
> +
> +	soc {
> +		serial at 78b0000 {
> +			status = "ok";
> +		};
> +	};
> +};

This part looks good.

> diff --git a/arch/arm/boot/dts/qcom-ipq40xx.dtsi b/arch/arm/boot/dts/qcom-ipq40xx.dtsi
> new file mode 100644
> index 0000000..76c55a3
> --- /dev/null
> +++ b/arch/arm/boot/dts/qcom-ipq40xx.dtsi
> @@ -0,0 +1,86 @@
> +/*
> + * Copyright (c) 2014, The Linux Foundation. All rights reserved.
> + *
> + * This program is free software; you can redistribute it and/or modify
> + * it under the terms of the GNU General Public License version 2 and
> + * only 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.
> + */
> +
> +/dts-v1/;
> +
> +#include "skeleton.dtsi"
> +
> +/ {
> +	model = "Qualcomm Technologies, Inc. IPQ40XX";
> +	compatible = "qcom,ipq40xx";
> +	interrupt-parent = <&intc>;
> +
> +	cpus {
> +		#address-cells = <1>;
> +		#size-cells = <0>;
> +		cpu at 0 {
> +			device_type = "cpu";
> +			compatible = "arm,cortex-a7";
> +			reg = <0x0>;
> +		};
> +
> +		cpu at 1 {
> +			device_type = "cpu";
> +			compatible = "arm,cortex-a7";
> +			reg = <0x1>;
> +		};
> +
> +		cpu at 2 {
> +			device_type = "cpu";
> +			compatible = "arm,cortex-a7";
> +			reg = <0x2>;
> +		};
> +
> +		cpu at 3 {
> +			device_type = "cpu";
> +			compatible = "arm,cortex-a7";
> +			reg = <0x3>;
> +		};
> +	};
> +
> +	soc {
> +		#address-cells = <1>;
> +		#size-cells = <1>;
> +		ranges;
> +		compatible = "simple-bus";
> +
> +		intc: interrupt-controller at b000000 {
> +			compatible = "qcom,msm-qgic2";
> +			interrupt-controller;
> +			#interrupt-cells = <3>;
> +			reg = <0x0b000000 0x1000>,
> +			<0x0b002000 0x1000>;
> +		};
> +
> +		counter {
> +			compatible = "qcom,qca-gcnt";
> +			reg = <0x004a1000 0x4>;
> +		};
> +
> +		timer {
> +			compatible = "arm,armv7-timer";
> +			interrupts = <1 2 0xf08>,
> +				     <1 3 0xf08>,
> +				     <1 4 0xf08>,
> +				     <1 1 0xf08>;
> +			clock-frequency = <20833333>;
> +		};
> +
> +		serial at 78b0000 {
> +			compatible = "qcom,msm-uartdm-v1.4", "qcom,msm-uartdm";
> +			reg = <0x78b0000 0x200>;
> +			interrupts = <0 108 0>;
> +			status = "disabled";
> +		};
> +	};
> +};

Unless the counter has a critical function I suggest you add that
separately, otherwise this looks good.

> diff --git a/arch/arm/configs/ipq_defconfig b/arch/arm/configs/ipq_defconfig
> index 1cabd8b..054a159 100644
> --- a/arch/arm/configs/ipq_defconfig
> +++ b/arch/arm/configs/ipq_defconfig
> @@ -22,6 +22,7 @@ CONFIG_ARCH_MSM8X60=y
>  CONFIG_ARCH_MSM8960=y
>  CONFIG_ARCH_MSM8974=y
>  CONFIG_ARCH_IPQ8064=y
> +CONFIG_ARCH_IPQ40XX=y
>  CONFIG_SMP=y
>  CONFIG_PREEMPT=y
>  CONFIG_AEABI=y
> diff --git a/arch/arm/mach-qcom/Kconfig b/arch/arm/mach-qcom/Kconfig
> index fab49a2..3add9f9 100644
> --- a/arch/arm/mach-qcom/Kconfig
> +++ b/arch/arm/mach-qcom/Kconfig
> @@ -26,4 +26,8 @@ config ARCH_IPQ8064
>  	bool "Enable support for IPQ806x"
>  	select CLKSRC_QCOM
>  
> +config ARCH_IPQ40XX
> +	bool "Enable support for IPQ40XX"
> +	select HAVE_ARM_ARCH_TIMER
> +

Please insert your entry alphabetically.

>  endif
> diff --git a/arch/arm/mach-qcom/board.c b/arch/arm/mach-qcom/board.c
> index 6d8bbf7..566487d 100644
> --- a/arch/arm/mach-qcom/board.c
> +++ b/arch/arm/mach-qcom/board.c
> @@ -22,6 +22,7 @@ static const char * const qcom_dt_match[] __initconst = {
>  	"qcom,ipq8064",
>  	"qcom,msm8660-surf",
>  	"qcom,msm8960-cdp",
> +	"qcom,ipq40xx-r3pc",

Please add qcom,ipq40xx instead, so that we don't need to list every
single device.

Also, please keep the list alphabetically sorted.

>  	NULL
>  };

Regards,
Bjorn


From jonathanh at nvidia.com  Fri Aug 21 09:27:51 2015
From: jonathanh at nvidia.com (Jon Hunter)
Date: Fri, 21 Aug 2015 17:27:51 +0100
Subject: [GIT PULL 8/9] ARM: tegra: Devicetree changes for v4.3-rc1
In-Reply-To: <20150821160905.GP4865@localhost>
References: <1439563720-13189-1-git-send-email-thierry.reding@gmail.com>
 <1439563720-13189-9-git-send-email-thierry.reding@gmail.com>
 <20150821015848.GM4865@localhost> <20150821160905.GP4865@localhost>
Message-ID: <55D75187.8010007@nvidia.com>


On 21/08/15 17:09, Olof Johansson wrote:
> On Thu, Aug 20, 2015 at 06:58:48PM -0700, Olof Johansson wrote:
>> On Fri, Aug 14, 2015 at 04:48:39PM +0200, Thierry Reding wrote:
>>> Hi ARM SoC maintainers,
>>>
>>> The following changes since commit d770e558e21961ad6cfdf0ff7df0eb5d7d4f0754:
>>>
>>>   Linux 4.2-rc1 (2015-07-05 11:01:52 -0700)
>>>
>>> are available in the git repository at:
>>>
>>>   git://git.kernel.org/pub/scm/linux/kernel/git/tegra/linux.git tags/tegra-for-4.3-dt
>>>
>>> for you to fetch changes up to 6909c6632fdbea441b5077b4f882c0bf4b71997e:
>>>
>>>   ARM: tegra: Add gpio-ranges property (2015-08-13 16:31:53 +0200)
>>>
>>> Thanks,
>>> Thierry
>>>
>>> ----------------------------------------------------------------
>>> ARM: tegra: Devicetree changes for v4.3-rc1
>>>
>>> Enables CPU frequency scaling on Jetson TK1 and enables the GK20A GPU on
>>> Venice2 and Jetson TK1. This also enables support for the PMU hardware
>>> found on Tegra124, which among other things, can be used for performance
>>> measurements.
>>
>> Merged, thanks.
> 
> This caused build failures due to missing tegra124-car.h:

Should be included by Paul's patch, "clk: tegra: Add DFLL DVCO reset
control for Tegra124", which is part of the clk series pull request [0].

> http://arm-soc.lixom.net/buildlogs/arm-soc/v4.2-rc2-954-g5825349/buildall.arm.tegra_defconfig.log.failed
> 
> I've dropped this branch again.

It is building ok on linux-next today.

Cheers
Jon

[0] http://www.spinics.net/lists/arm-kernel/msg439463.html


From moritz.fischer at ettus.com  Fri Aug 21 09:32:55 2015
From: moritz.fischer at ettus.com (Moritz Fischer)
Date: Fri, 21 Aug 2015 09:32:55 -0700
Subject: [PATCH] doc: dt: Add interrupt parent to Xilinx AXI DMA instantation
 example.
Message-ID: <1440174775-14470-1-git-send-email-moritz.fischer@ettus.com>

This patch adds 'interrupt-parent' properties to the instantation example in
the docs for the devicetree bindings of the Xilinx AXI DMA driver.

Signed-off-by: Moritz Fischer <moritz.fischer at ettus.com>
---
 Documentation/devicetree/bindings/dma/xilinx/xilinx_dma.txt | 3 +++
 1 file changed, 3 insertions(+)

diff --git a/Documentation/devicetree/bindings/dma/xilinx/xilinx_dma.txt b/Documentation/devicetree/bindings/dma/xilinx/xilinx_dma.txt
index 2291c40..7c956e9 100644
--- a/Documentation/devicetree/bindings/dma/xilinx/xilinx_dma.txt
+++ b/Documentation/devicetree/bindings/dma/xilinx/xilinx_dma.txt
@@ -19,6 +19,7 @@ Required child node properties:
 - compatible: It should be either "xlnx,axi-dma-mm2s-channel" or
 	"xlnx,axi-dma-s2mm-channel".
 - interrupts: Should contain per channel DMA interrupts.
+- interrupt-parent: Should contain interrupt parent.
 - xlnx,datawidth: Should contain the stream data width, take values
 	{32,64...1024}.
 
@@ -36,11 +37,13 @@ axi_dma_0: axidma at 40400000 {
 	dma-channel at 40400000 {
 		compatible = "xlnx,axi-dma-mm2s-channel";
 		interrupts = < 0 59 4 >;
+		interrupt-parent = <&intc>;
 		xlnx,datawidth = <0x40>;
 	} ;
 	dma-channel at 40400030 {
 		compatible = "xlnx,axi-dma-s2mm-channel";
 		interrupts = < 0 58 4 >;
+		interrupt-parent = <&intc>;
 		xlnx,datawidth = <0x40>;
 	} ;
 } ;
-- 
2.4.3



From olof at lixom.net  Fri Aug 21 09:33:44 2015
From: olof at lixom.net (Olof Johansson)
Date: Fri, 21 Aug 2015 09:33:44 -0700
Subject: [GIT PULL 8/9] ARM: tegra: Devicetree changes for v4.3-rc1
In-Reply-To: <55D75187.8010007@nvidia.com>
References: <1439563720-13189-1-git-send-email-thierry.reding@gmail.com>
 <1439563720-13189-9-git-send-email-thierry.reding@gmail.com>
 <20150821015848.GM4865@localhost> <20150821160905.GP4865@localhost>
 <55D75187.8010007@nvidia.com>
Message-ID: <20150821163344.GA18595@localhost>

On Fri, Aug 21, 2015 at 05:27:51PM +0100, Jon Hunter wrote:
> 
> On 21/08/15 17:09, Olof Johansson wrote:
> > On Thu, Aug 20, 2015 at 06:58:48PM -0700, Olof Johansson wrote:
> >> On Fri, Aug 14, 2015 at 04:48:39PM +0200, Thierry Reding wrote:
> >>> Hi ARM SoC maintainers,
> >>>
> >>> The following changes since commit d770e558e21961ad6cfdf0ff7df0eb5d7d4f0754:
> >>>
> >>>   Linux 4.2-rc1 (2015-07-05 11:01:52 -0700)
> >>>
> >>> are available in the git repository at:
> >>>
> >>>   git://git.kernel.org/pub/scm/linux/kernel/git/tegra/linux.git tags/tegra-for-4.3-dt
> >>>
> >>> for you to fetch changes up to 6909c6632fdbea441b5077b4f882c0bf4b71997e:
> >>>
> >>>   ARM: tegra: Add gpio-ranges property (2015-08-13 16:31:53 +0200)
> >>>
> >>> Thanks,
> >>> Thierry
> >>>
> >>> ----------------------------------------------------------------
> >>> ARM: tegra: Devicetree changes for v4.3-rc1
> >>>
> >>> Enables CPU frequency scaling on Jetson TK1 and enables the GK20A GPU on
> >>> Venice2 and Jetson TK1. This also enables support for the PMU hardware
> >>> found on Tegra124, which among other things, can be used for performance
> >>> measurements.
> >>
> >> Merged, thanks.
> > 
> > This caused build failures due to missing tegra124-car.h:
> 
> Should be included by Paul's patch, "clk: tegra: Add DFLL DVCO reset
> control for Tegra124", which is part of the clk series pull request [0].
> 
> > http://arm-soc.lixom.net/buildlogs/arm-soc/v4.2-rc2-954-g5825349/buildall.arm.tegra_defconfig.log.failed
> > 
> > I've dropped this branch again.
> 
> It is building ok on linux-next today.

Yeah, it builds when the dependent changes from the clk tree are included, but
this breaks bisectability potentially for quite a bit of code, and requires
that we merge after the clk branch goes in or mainline will be busted.

As mentioned just now on IRC too, it might make most sense to rebase on top
of the clk branch to avoid this breakage. Either that or drop the patch in
question for 4.3.


-Olof


From olof at lixom.net  Fri Aug 21 09:37:00 2015
From: olof at lixom.net (Olof Johansson)
Date: Fri, 21 Aug 2015 09:37:00 -0700
Subject: [PATCH] ARM: imx: mach-imx6ul: Fix allmodconfig build
In-Reply-To: <1440009090-25799-1-git-send-email-festevam@gmail.com>
References: <1440009090-25799-1-git-send-email-festevam@gmail.com>
Message-ID: <20150821163700.GA25276@localhost>

On Wed, Aug 19, 2015 at 03:31:30PM -0300, Fabio Estevam wrote:
> From: Fabio Estevam <fabio.estevam at freescale.com>
> 
> We should call phy_register_fixup_for_uid() only when CONFIG_PHYLIB
> is built-in, otherwise we get the following link error when building
> allmodconfig:
> 
> arch/arm/mach-imx/built-in.o: In function `imx6ul_init_machine':
> :(.init.text+0xa714): undefined reference to `phy_register_fixup_for_uid'
> 
> This is the same approach done in mach-imx6q.c and mach-imx6sx.c.
> 
> Reported-by: Olof Johansson <olof at lixom.net>
> Signed-off-by: Fabio Estevam <fabio.estevam at freescale.com>

Thanks, applied.


-Olof



From boris.brezillon at free-electrons.com  Fri Aug 21 09:41:10 2015
From: boris.brezillon at free-electrons.com (Boris Brezillon)
Date: Fri, 21 Aug 2015 18:41:10 +0200
Subject: [PATCH] mtd: nand: sunxi: rely on nand_dt_init initialization
Message-ID: <1440175270-11334-1-git-send-email-boris.brezillon@free-electrons.com>

nand_dt_init(), called from nand_scan_ident(), is already parsing the
generic MTD/NAND DT properties, and initializing the nand_chip struct
accordingly.
Rely on this initialization instead of manually parsing those properties.

Signed-off-by: Boris Brezillon <boris.brezillon at free-electrons.com>
---
 drivers/mtd/nand/sunxi_nand.c | 18 +++++-------------
 1 file changed, 5 insertions(+), 13 deletions(-)

diff --git a/drivers/mtd/nand/sunxi_nand.c b/drivers/mtd/nand/sunxi_nand.c
index f97a58d..6bd7099 100644
--- a/drivers/mtd/nand/sunxi_nand.c
+++ b/drivers/mtd/nand/sunxi_nand.c
@@ -1166,12 +1166,7 @@ static int sunxi_nand_ecc_init(struct mtd_info *mtd, struct nand_ecc_ctrl *ecc,
 	int blk_size;
 	int ret;
 
-	blk_size = of_get_nand_ecc_step_size(np);
-	strength = of_get_nand_ecc_strength(np);
-	if (blk_size > 0 && strength > 0) {
-		ecc->size = blk_size;
-		ecc->strength = strength;
-	} else {
+	if (!ecc->size) {
 		ecc->size = nand->ecc_step_ds;
 		ecc->strength = nand->ecc_strength_ds;
 	}
@@ -1181,10 +1176,6 @@ static int sunxi_nand_ecc_init(struct mtd_info *mtd, struct nand_ecc_ctrl *ecc,
 
 	ecc->mode = NAND_ECC_HW;
 
-	ret = of_get_nand_ecc_mode(np);
-	if (ret >= 0)
-		ecc->mode = ret;
-
 	switch (ecc->mode) {
 	case NAND_ECC_SOFT_BCH:
 		break;
@@ -1310,15 +1301,13 @@ static int sunxi_nand_chip_init(struct device *dev, struct sunxi_nfc *nfc,
 	/* Default tR value specified in the ONFI spec (chapter 4.15.1) */
 	nand->chip_delay = 200;
 	nand->controller = &nfc->controller;
+	nand->dn = np;
 	nand->select_chip = sunxi_nfc_select_chip;
 	nand->cmd_ctrl = sunxi_nfc_cmd_ctrl;
 	nand->read_buf = sunxi_nfc_read_buf;
 	nand->write_buf = sunxi_nfc_write_buf;
 	nand->read_byte = sunxi_nfc_read_byte;
 
-	if (of_get_nand_on_flash_bbt(np))
-		nand->bbt_options |= NAND_BBT_USE_FLASH | NAND_BBT_NO_OOB;
-
 	mtd = &chip->mtd;
 	mtd->dev.parent = dev;
 	mtd->priv = nand;
@@ -1328,6 +1317,9 @@ static int sunxi_nand_chip_init(struct device *dev, struct sunxi_nfc *nfc,
 	if (ret)
 		return ret;
 
+	if (nand->bbt_options & NAND_BBT_USE_FLASH)
+		nand->bbt_options |= NAND_BBT_NO_OOB;
+
 	ret = sunxi_nand_chip_init_timings(chip, np);
 	if (ret) {
 		dev_err(dev, "could not configure chip timings: %d\n", ret);
-- 
1.9.1



From moritz.fischer at ettus.com  Fri Aug 21 09:42:24 2015
From: moritz.fischer at ettus.com (Moritz Fischer)
Date: Fri, 21 Aug 2015 09:42:24 -0700
Subject: [PATCH v4 1/2] Documentation: dt: Add Xilinx zynqmp dma device
 tree binding documentation
In-Reply-To: <1438831173-8761-1-git-send-email-punnaia@xilinx.com>
References: <1438831173-8761-1-git-send-email-punnaia@xilinx.com>
Message-ID: <CAAtXAHdu10dchedaApLiw6+b583z4D8Of1TAEGDmhhVLOy+8YA@mail.gmail.com>

Hi all,

sorry for HTML mail spam last night ... couple of nits below

On Wed, Aug 5, 2015 at 8:19 PM, Punnaiah Choudary Kalluri
<punnaiah.choudary.kalluri at xilinx.com> wrote:
> Device-tree binding documentation for Xilinx zynqmp dma engine used in
> Zynq UltraScale+ MPSoC.
>
> Signed-off-by: Punnaiah Choudary Kalluri <punnaia at xilinx.com>
> ---
> Changes in v4:
> - None
> Changes in v3:
> - None
> Changes in v2:
> - None
> ---
>  .../devicetree/bindings/dma/xilinx/zynqmp_dma.txt  |   61 ++++++++++++++++++++
>  1 files changed, 61 insertions(+), 0 deletions(-)
>  create mode 100644 Documentation/devicetree/bindings/dma/xilinx/zynqmp_dma.txt
>
> diff --git a/Documentation/devicetree/bindings/dma/xilinx/zynqmp_dma.txt b/Documentation/devicetree/bindings/dma/xilinx/zynqmp_dma.txt
> new file mode 100644
> index 0000000..e4f92b9
> --- /dev/null
> +++ b/Documentation/devicetree/bindings/dma/xilinx/zynqmp_dma.txt
> @@ -0,0 +1,61 @@
> +Xilinx ZynqMP DMA engine, it does support memory to memory transfers,
> +memory to device and device to memory transfers. It also has flow
> +control and rate control support for slave/peripheral dma access.

How about: The Xilinx ZynqMP DMA engine does support memory to memory transfers,
memory to device and device to memory transfers. It also has flow
control and rate control
support for slave / peripheral DMA access.
> +
> +Required properties:
> +- compatible: Should be "xlnx,zynqmp-dma-1.0"
> +- #dma-cells: Should be <1>, a single cell holding a line request number
> +- reg: Memory map for module access
> +- interrupt-parent: Interrupt controller the interrupt is routed through
> +- interrupts: Should contain DMA channel interrupt
> +- xlnx,bus-width: AXI buswidth in bits. Should contain 128 or 64
> +
> +Optional properties:
> +- xlnx,include-sg: Indicates the controller to operate in simple or scatter
> +                  gather dma mode
s/dma/DMA
> +- xlnx,ratectrl: Scheduling interval in terms of clock cycles for
> +                source AXI transaction
> +- xlnx,overfetch: Tells whether the channel is allowed to over fetch the data
(Maybe) s/Tells/Determines/
> +- xlnx,src-issue: Number of AXI outstanding transactions on source side
> +- xlnx,desc-axi-cohrnt: Tells whether the AXI transactions generated for the
> +                       descriptor read are marked Non-coherent
(Maybe) s/Tells/Determines/
> +- xlnx,src-axi-cohrnt: Tells whether the AXI transactions generated for the
> +                       source descriptor payload are marked Non-coherent
same
> +- xlnx,dst-axi-cohrnt: Tells whether the AXI transactions generated for the
> +                       dst descriptor payload are marked Non-coherent
> +- xlnx,desc-axi-qos: AXI QOS bits to be used for descriptor fetch
> +- xlnx,src-axi-qos: AXI QOS bits to be used for data read
> +- xlnx,dst-axi-qos: AXI QOS bits to be used for data write
> +- xlnx,desc-axi-cache: AXI cache bits to be used for descriptor fetch.
> +- xlnx,desc-axi-cache: AXI cache bits to be used for data read
> +- xlnx,desc-axi-cache: AXI cache bits to be used for data write
> +- xlnx,src-burst-len: AXI length for data read. Support only power of 2 values
> +                     i.e 1,2,4,8 and 16
> +- xlnx,dst-burst-len: AXI length for data write. Support only power of 2 values
> +                     i.e 1,2,4,8 and 16
> +
> +Example:
> +++++++++
> +fpd_dma_chan1: dma at FD500000 {
> +       compatible = "xlnx,zynqmp-dma-1.0";
> +       reg = <0x0 0xFD500000 0x1000>;
> +       #dma_cells = <1>;
#dma-cells = <1>;
> +       interrupt-parent = <&gic>;
> +       interrupts = <0 117 4>;
> +       xlnx,bus-width = <128>;
> +       xlnx,include-sg;
> +       xlnx,overfetch;
> +       xlnx,ratectrl = <0>;
> +       xlnx,src-issue = <16>;
> +       xlnx,desc-axi-cohrnt;
> +       xlnx,src-axi-cohrnt;
> +       xlnx,dst-axi-cohrnt;
> +       xlnx,desc-axi-qos = <0>;
> +       xlnx,desc-axi-cache = <0>;
> +       xlnx,src-axi-qos = <0>;
> +       xlnx,src-axi-cache = <2>;
> +       xlnx,dst-axi-qos = <0>;
> +       xlnx,dst-axi-cache = <2>;
> +       xlnx,src-burst-len = <4>;
> +       xlnx,dst-burst-len = <4>;
> +};
> --
> 1.7.4
>
>
> _______________________________________________
> linux-arm-kernel mailing list
> linux-arm-kernel at lists.infradead.org
> http://lists.infradead.org/mailman/listinfo/linux-arm-kernel

Cheers,

Moritz


From timur at codeaurora.org  Fri Aug 21 09:45:18 2015
From: timur at codeaurora.org (Timur Tabi)
Date: Fri, 21 Aug 2015 11:45:18 -0500
Subject: [PATCH v3 15/31] arm64: SMP support
In-Reply-To: <55C8D9DB.5080207@codeaurora.org>
References: <1347035226-18649-1-git-send-email-catalin.marinas@arm.com>
 <1347035226-18649-16-git-send-email-catalin.marinas@arm.com>
 <CAOZdJXVoDJM3y2mnKO+91yf2EHogKfMjumjhhi85REAfhcJM=Q@mail.gmail.com>
 <20150806095621.GB17691@e104818-lin.cambridge.arm.com>
 <55C8843D.8050600@linaro.org> <55C8D9DB.5080207@codeaurora.org>
Message-ID: <55D7559E.8080609@codeaurora.org>

On 08/10/2015 12:05 PM, Timur Tabi wrote:
>>>
>>> This code was inherited from arch/arm which initially was always dumping
>>> the stack but it later gained the system_state check. Unless it's useful
>>> to anyone for debugging purposes, I'm ok with removing it.
>>
>> Do you have patch for this one? My colleagues said that they met the
>> same problem :)
>
> Dropping the call to dump_stack() would probably be sufficient.

Actually, I think we need to keep it.  I just heard from another 
developer who does actually use it for debugging.

I think the real problem is that emergency_restart() should not be 
causing these outputs.  Shouldn't machine_restart() change the 
system_state to SYSTEM_RESTART before it calls smp_send_stop()?

-- 
Qualcomm Innovation Center, Inc.
The Qualcomm Innovation Center, Inc. is a member of the
Code Aurora Forum, a Linux Foundation Collaborative Project.


From broonie at kernel.org  Fri Aug 21 09:47:09 2015
From: broonie at kernel.org (Mark Brown)
Date: Fri, 21 Aug 2015 09:47:09 -0700
Subject: [PATCH v2 1/4] regmap: Introduce max_raw_read/write for
 regmap_bulk_read/write
In-Reply-To: <1440064807-26346-2-git-send-email-mpa@pengutronix.de>
References: <1440064807-26346-1-git-send-email-mpa@pengutronix.de>
 <1440064807-26346-2-git-send-email-mpa@pengutronix.de>
Message-ID: <20150821164709.GF12027@sirena.org.uk>

On Thu, Aug 20, 2015 at 12:00:04PM +0200, Markus Pargmann wrote:
> There are some buses which have a limit on the maximum number of bytes
> that can be send/received. An example for this is
> I2C_FUNC_SMBUS_I2C_BLOCK which does not support any reads/writes of more
> than 32 bytes. The regmap_bulk operations should still be able to
> utilize the full 32 bytes in this case.

This doesn't seem to apply against current code, can you please check
and resend?
-------------- next part --------------
A non-text attachment was scrubbed...
Name: signature.asc
Type: application/pgp-signature
Size: 473 bytes
Desc: Digital signature
URL: <http://lists.infradead.org/pipermail/linux-arm-kernel/attachments/20150821/d66efb11/attachment.sig>

From dinguyen at opensource.altera.com  Fri Aug 21 09:41:44 2015
From: dinguyen at opensource.altera.com (dinguyen at opensource.altera.com)
Date: Fri, 21 Aug 2015 11:41:44 -0500
Subject: [PATCv3] arm64: dts: Add base stratix 10 dtsi
Message-ID: <1440175304-11148-1-git-send-email-dinguyen@opensource.altera.com>

From: Dinh Nguyen <dinguyen at opensource.altera.com>

Add the base DTS for Altera's SoCFPGA Stratix 10 platform.

Signed-off-by: Dinh Nguyen <dinguyen at opensource.altera.com>
---
v3: change #address-cells and #size-cells to <2>
    change the GIC address to 0xfffc1000
    update the GIC virtual CPU reg length to 0x2000
v2: use interrupt-affinity for pmu node
---
 arch/arm64/Kconfig                                 |   5 +
 arch/arm64/boot/dts/Makefile                       |   1 +
 arch/arm64/boot/dts/altera/Makefile                |   5 +
 arch/arm64/boot/dts/altera/socfpga_stratix10.dtsi  | 358 +++++++++++++++++++++
 .../boot/dts/altera/socfpga_stratix10_socdk.dts    |  38 +++
 arch/arm64/configs/defconfig                       |   1 +
 6 files changed, 408 insertions(+)
 create mode 100644 arch/arm64/boot/dts/altera/Makefile
 create mode 100644 arch/arm64/boot/dts/altera/socfpga_stratix10.dtsi
 create mode 100644 arch/arm64/boot/dts/altera/socfpga_stratix10_socdk.dts

diff --git a/arch/arm64/Kconfig b/arch/arm64/Kconfig
index 318175f..0f8ab2b 100644
--- a/arch/arm64/Kconfig
+++ b/arch/arm64/Kconfig
@@ -207,6 +207,11 @@ config ARCH_SEATTLE
 	help
 	  This enables support for AMD Seattle SOC Family
 
+config ARCH_STRATIX10
+	bool "Altera's Stratix 10 SoCFPGA Family"
+	help
+	  This enables support for Altera's Stratix 10 SoCFPGA Family
+
 config ARCH_TEGRA
 	bool "NVIDIA Tegra SoC Family"
 	select ARCH_HAS_RESET_CONTROLLER
diff --git a/arch/arm64/boot/dts/Makefile b/arch/arm64/boot/dts/Makefile
index 38913be..7fb421a 100644
--- a/arch/arm64/boot/dts/Makefile
+++ b/arch/arm64/boot/dts/Makefile
@@ -1,3 +1,4 @@
+dts-dirs += altera
 dts-dirs += amd
 dts-dirs += apm
 dts-dirs += arm
diff --git a/arch/arm64/boot/dts/altera/Makefile b/arch/arm64/boot/dts/altera/Makefile
new file mode 100644
index 0000000..d7a6416
--- /dev/null
+++ b/arch/arm64/boot/dts/altera/Makefile
@@ -0,0 +1,5 @@
+dtb-$(CONFIG_ARCH_STRATIX10) += socfpga_stratix10_socdk.dtb
+
+always		:= $(dtb-y)
+subdir-y	:= $(dts-dirs)
+clean-files	:= *.dtb
diff --git a/arch/arm64/boot/dts/altera/socfpga_stratix10.dtsi b/arch/arm64/boot/dts/altera/socfpga_stratix10.dtsi
new file mode 100644
index 0000000..d5f51a5
--- /dev/null
+++ b/arch/arm64/boot/dts/altera/socfpga_stratix10.dtsi
@@ -0,0 +1,358 @@
+/*
+ * Copyright Altera Corporation (C) 2015. All rights reserved.
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms and conditions of the GNU General Public License,
+ * version 2, as published by the Free Software Foundation.
+ *
+ * This program is distributed in the hope 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.
+ *
+ * You should have received a copy of the GNU General Public License along with
+ * this program.  If not, see <http://www.gnu.org/licenses/>.
+ */
+
+/dts-v1/;
+
+/ {
+	compatible = "altr,socfpga-stratix10";
+	#address-cells = <2>;
+	#size-cells = <2>;
+
+	cpus {
+		#address-cells = <1>;
+		#size-cells = <0>;
+
+		cpu0: cpu at 0 {
+			compatible = "arm,cortex-a53", "arm,armv8";
+			device_type = "cpu";
+			enable-method = "psci";
+			reg = <0x0>;
+		};
+
+		cpu1: cpu at 1 {
+			compatible = "arm,cortex-a53", "arm,armv8";
+			device_type = "cpu";
+			enable-method = "psci";
+			reg = <0x1>;
+		};
+
+		cpu2: cpu at 2 {
+			compatible = "arm,cortex-a53", "arm,armv8";
+			device_type = "cpu";
+			enable-method = "psci";
+			reg = <0x2>;
+		};
+
+		cpu3: cpu at 3 {
+			compatible = "arm,cortex-a53", "arm,armv8";
+			device_type = "cpu";
+			enable-method = "psci";
+			reg = <0x3>;
+		};
+	};
+
+	pmu {
+		compatible = "arm,armv8-pmuv3";
+		interrupts = <0 120 8>,
+			     <0 121 8>,
+			     <0 122 8>,
+			     <0 123 8>;
+		interrupt-affinity = <&cpu0>,
+				     <&cpu1>,
+				     <&cpu2>,
+				     <&cpu3>;
+	};
+
+	psci {
+		compatible = "arm,psci-0.2";
+		method = "smc";
+	};
+
+	intc: intc at fffc1000 {
+		compatible = "arm,gic-400", "arm,cortex-a15-gic";
+		#interrupt-cells = <3>;
+		interrupt-controller;
+		reg = <0x0 0xfffc1000 0x1000>,
+		      <0x0 0xfffc2000 0x2000>,
+		      <0x0 0xfffc4000 0x2000>,
+		      <0x0 0xfffc6000 0x2000>;
+	};
+
+	soc {
+		#address-cells = <1>;
+		#size-cells = <1>;
+		compatible = "simple-bus";
+		device_type = "soc";
+		interrupt-parent = <&intc>;
+		ranges;
+
+		clkmgr at ffd1000 {
+			compatible = "altr,clk-mgr";
+			reg = <0xffd10000 0x1000>;
+		};
+
+		gmac0: ethernet at ff800000 {
+			compatible = "altr,socfpga-stmmac", "snps,dwmac-3.74a", "snps,dwmac";
+			reg = <0xff800000 0x2000>;
+			interrupts = <0 90 4>;
+			interrupt-names = "macirq";
+			mac-address = [00 00 00 00 00 00];
+			status = "disabled";
+		};
+
+		gmac1: ethernet at ff802000 {
+			compatible = "altr,socfpga-stmmac", "snps,dwmac-3.74a", "snps,dwmac";
+			reg = <0xff802000 0x2000>;
+			interrupts = <0 91 4>;
+			interrupt-names = "macirq";
+			mac-address = [00 00 00 00 00 00];
+			status = "disabled";
+		};
+
+		gmac2: ethernet at ff804000 {
+			compatible = "altr,socfpga-stmmac", "snps,dwmac-3.74a", "snps,dwmac";
+			reg = <0xff804000 0x2000>;
+			interrupts = <0 92 4>;
+			interrupt-names = "macirq";
+			mac-address = [00 00 00 00 00 00];
+			status = "disabled";
+		};
+
+		gpio0: gpio at ffc03200 {
+			#address-cells = <1>;
+			#size-cells = <0>;
+			compatible = "snps,dw-apb-gpio";
+			reg = <0xffc03200 0x100>;
+			status = "disabled";
+
+			porta: gpio-controller at 0 {
+				compatible = "snps,dw-apb-gpio-port";
+				gpio-controller;
+				#gpio-cells = <2>;
+				snps,nr-gpios = <24>;
+				reg = <0>;
+				interrupt-controller;
+				#interrupt-cells = <2>;
+				interrupts = <0 110 4>;
+			};
+		};
+
+		gpio1: gpio at ffc03300 {
+			#address-cells = <1>;
+			#size-cells = <0>;
+			compatible = "snps,dw-apb-gpio";
+			reg = <0xffc03300 0x100>;
+			status = "disabled";
+
+			portb: gpio-controller at 0 {
+				compatible = "snps,dw-apb-gpio-port";
+				gpio-controller;
+				#gpio-cells = <2>;
+				snps,nr-gpios = <24>;
+				reg = <0>;
+				interrupt-controller;
+				#interrupt-cells = <2>;
+				interrupts = <0 110 4>;
+			};
+		};
+
+		i2c0: i2c at ffc02800 {
+			#address-cells = <1>;
+			#size-cells = <0>;
+			compatible = "snps,designware-i2c";
+			reg = <0xffc02800 0x100>;
+			interrupts = <0 103 4>;
+			status = "disabled";
+		};
+
+		i2c1: i2c at ffc02900 {
+			#address-cells = <1>;
+			#size-cells = <0>;
+			compatible = "snps,designware-i2c";
+			reg = <0xffc02900 0x100>;
+			interrupts = <0 104 4>;
+			status = "disabled";
+		};
+
+		i2c2: i2c at ffc02a00 {
+			#address-cells = <1>;
+			#size-cells = <0>;
+			compatible = "snps,designware-i2c";
+			reg = <0xffc02a00 0x100>;
+			interrupts = <0 105 4>;
+			status = "disabled";
+		};
+
+		i2c3: i2c at ffc02b00 {
+			#address-cells = <1>;
+			#size-cells = <0>;
+			compatible = "snps,designware-i2c";
+			reg = <0xffc02b00 0x100>;
+			interrupts = <0 106 4>;
+			status = "disabled";
+		};
+
+		i2c4: i2c at ffc02c00 {
+			#address-cells = <1>;
+			#size-cells = <0>;
+			compatible = "snps,designware-i2c";
+			reg = <0xffc02c00 0x100>;
+			interrupts = <0 107 4>;
+			status = "disabled";
+		};
+
+		mmc: dwmmc0 at ff808000 {
+			#address-cells = <1>;
+			#size-cells = <0>;
+			compatible = "altr,socfpga-dw-mshc";
+			reg = <0xff808000 0x1000>;
+			interrupts = <0 96 4>;
+			fifo-depth = <0x400>;
+			status = "disabled";
+		};
+
+		ocram: sram at ffe00000 {
+			compatible = "mmio-sram";
+			reg = <0xffe00000 0x100000>;
+		};
+
+		rst: rstmgr at ffd11000 {
+			#reset-cells = <1>;
+			compatible = "altr,rst-mgr";
+			reg = <0xffd11000 0x1000>;
+		};
+
+		spi0: spi at ffda4000 {
+			compatible = "snps,dw-apb-ssi";
+			#address-cells = <1>;
+			#size-cells = <0>;
+			reg = <0xffda4000 0x1000>;
+			interrupts = <0 101 4>;
+			num-chipselect = <4>;
+			bus-num = <0>;
+			status = "disabled";
+		};
+
+		spi1: spi at ffda5000 {
+			compatible = "snps,dw-apb-ssi";
+			#address-cells = <1>;
+			#size-cells = <0>;
+			reg = <0xffda5000 0x1000>;
+			interrupts = <0 102 4>;
+			num-chipselect = <4>;
+			bus-num = <0>;
+			status = "disabled";
+		};
+
+		sysmgr: sysmgr at ffd12000 {
+			compatible = "altr,sys-mgr", "syscon";
+			reg = <0xffd12000 0x1000>;
+		};
+
+		/* Local timer */
+		timer {
+			compatible = "arm,armv8-timer";
+			interrupts = <1 13 0xf01>,
+				     <1 14 0xf01>,
+				     <1 11 0xf01>,
+				     <1 10 0xf01>;
+		};
+
+		timer0: timer0 at ffc03000 {
+			compatible = "snps,dw-apb-timer";
+			interrupts = <0 113 4>;
+			reg = <0xffc03000 0x100>;
+		};
+
+		timer1: timer1 at ffc03100 {
+			compatible = "snps,dw-apb-timer";
+			interrupts = <0 114 4>;
+			reg = <0xffc03100 0x100>;
+		};
+
+		timer2: timer2 at ffd00000 {
+			compatible = "snps,dw-apb-timer";
+			interrupts = <0 115 4>;
+			reg = <0xffd00000 0x100>;
+		};
+
+		timer3: timer3 at ffd00100 {
+			compatible = "snps,dw-apb-timer";
+			interrupts = <0 116 4>;
+			reg = <0xffd00100 0x100>;
+		};
+
+		uart0: serial0 at ffc02000 {
+			compatible = "snps,dw-apb-uart";
+			reg = <0xffc02000 0x100>;
+			interrupts = <0 108 4>;
+			reg-shift = <2>;
+			reg-io-width = <4>;
+			status = "disabled";
+		};
+
+		uart1: serial1 at ffc02100 {
+			compatible = "snps,dw-apb-uart";
+			reg = <0xffc02100 0x100>;
+			interrupts = <0 109 4>;
+			reg-shift = <2>;
+			reg-io-width = <4>;
+			status = "disabled";
+		};
+
+		usbphy0: usbphy at 0 {
+			#phy-cells = <0>;
+			compatible = "usb-nop-xceiv";
+			status = "okay";
+		};
+
+		usb0: usb at ffb00000 {
+			compatible = "snps,dwc2";
+			reg = <0xffb00000 0x40000>;
+			interrupts = <0 93 4>;
+			phys = <&usbphy0>;
+			phy-names = "usb2-phy";
+			status = "disabled";
+		};
+
+		usb1: usb at ffb40000 {
+			compatible = "snps,dwc2";
+			reg = <0xffb40000 0x40000>;
+			interrupts = <0 94 4>;
+			phys = <&usbphy0>;
+			phy-names = "usb2-phy";
+			status = "disabled";
+		};
+
+		watchdog0: watchdog at ffd00200 {
+			compatible = "snps,dw-wdt";
+			reg = <0xffd00200 0x100>;
+			interrupts = <0 117 4>;
+			status = "disabled";
+		};
+
+		watchdog1: watchdog at ffd00300 {
+			compatible = "snps,dw-wdt";
+			reg = <0xffd00300 0x100>;
+			interrupts = <0 118 4>;
+			status = "disabled";
+		};
+
+		watchdog2: watchdog at ffd00400 {
+			compatible = "snps,dw-wdt";
+			reg = <0xffd00400 0x100>;
+			interrupts = <0 125 4>;
+			status = "disabled";
+		};
+
+		watchdog3: watchdog at ffd00500 {
+			compatible = "snps,dw-wdt";
+			reg = <0xffd00500 0x100>;
+			interrupts = <0 126 4>;
+			status = "disabled";
+		};
+	};
+};
diff --git a/arch/arm64/boot/dts/altera/socfpga_stratix10_socdk.dts b/arch/arm64/boot/dts/altera/socfpga_stratix10_socdk.dts
new file mode 100644
index 0000000..8b162ef
--- /dev/null
+++ b/arch/arm64/boot/dts/altera/socfpga_stratix10_socdk.dts
@@ -0,0 +1,38 @@
+/*
+ * Copyright Altera Corporation (C) 2015. All rights reserved.
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms and conditions of the GNU General Public License,
+ * version 2, as published by the Free Software Foundation.
+ *
+ * This program is distributed in the hope 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.
+ *
+ * You should have received a copy of the GNU General Public License along with
+ * this program.  If not, see <http://www.gnu.org/licenses/>.
+ */
+
+/include/ "socfpga_stratix10.dtsi"
+
+/ {
+	model = "SoCFPGA Stratix 10 SoCDK";
+
+	aliases {
+		serial0 = &uart0;
+	};
+
+	chosen {
+		stdout-path = "serial0:115200n8";
+	};
+
+	memory {
+		device_type = "memory";
+		reg = <0x0 0x40000000>;
+	};
+};
+
+&uart0 {
+	status = "okay";
+};
diff --git a/arch/arm64/configs/defconfig b/arch/arm64/configs/defconfig
index 4e17e7e..ad3b636 100644
--- a/arch/arm64/configs/defconfig
+++ b/arch/arm64/configs/defconfig
@@ -36,6 +36,7 @@ CONFIG_ARCH_FSL_LS2085A=y
 CONFIG_ARCH_HISI=y
 CONFIG_ARCH_MEDIATEK=y
 CONFIG_ARCH_SEATTLE=y
+CONFIG_ARCH_STRATIX10=y
 CONFIG_ARCH_TEGRA=y
 CONFIG_ARCH_TEGRA_132_SOC=y
 CONFIG_ARCH_QCOM=y
-- 
2.4.5



From thierry.reding at gmail.com  Fri Aug 21 09:52:19 2015
From: thierry.reding at gmail.com (Thierry Reding)
Date: Fri, 21 Aug 2015 18:52:19 +0200
Subject: [GIT PULL 8/9] ARM: tegra: Devicetree changes for v4.3-rc1 (updated)
In-Reply-To: <1439563720-13189-9-git-send-email-thierry.reding@gmail.com>
References: <1439563720-13189-9-git-send-email-thierry.reding@gmail.com>
Message-ID: <1440175939-13663-1-git-send-email-thierry.reding@gmail.com>

Hi ARM SoC maintainers,

The following changes since commit d770e558e21961ad6cfdf0ff7df0eb5d7d4f0754:

  Linux 4.2-rc1 (2015-07-05 11:01:52 -0700)

are available in the git repository at:

  git://git.kernel.org/pub/scm/linux/kernel/git/tegra/linux.git tags/tegra-for-4.3-dt

for you to fetch changes up to 17cdddf0fb684f5456c1af3aa2c10aca3b68b8de:

  ARM: tegra: Add gpio-ranges property (2015-08-21 18:44:28 +0200)

This updated version of the pull request includes the for-4.3/clk branch
which is a build-time dependency for for-4.3/dt.

Thanks,
Thierry

----------------------------------------------------------------
ARM: tegra: Devicetree changes for v4.3-rc1

Enables CPU frequency scaling on Jetson TK1 and enables the GK20A GPU on
Venice2 and Jetson TK1. This also enables support for the PMU hardware
found on Tegra124, which among other things, can be used for performance
measurements.

----------------------------------------------------------------
Alexandre Courbot (2):
      ARM: tegra: Add IOMMU node to GK20A
      ARM: tegra: jetson-tk1: Add GK20A GPU DT node

Kyle Huey (1):
      ARM: tegra: Add Tegra124 PMU support

Mikko Perttunen (2):
      clk: tegra: Introduce ability for SoC-specific reset control callbacks
      ARM: tegra: Add CPU regulator to the Jetson TK1 device tree

Nicolas Chauvet (1):
      ARM: tegra: Fix AHB base address on Tegra20, Tegra30 and Tegra114

Paul Walmsley (1):
      clk: tegra: Add DFLL DVCO reset control for Tegra124

Thierry Reding (3):
      Merge branch 'for-4.3/pinctrl' into for-4.3/dt
      Merge branch 'for-4.3/clk' into for-4.3/dt
      ARM: tegra: venice2: Add GK20A GPU DT node

Tomeu Vizoso (2):
      pinctrl: tegra: Only set the gpio range if needed
      ARM: tegra: Add gpio-ranges property

Tuomas Tynkkynen (10):
      clk: tegra: Add binding for the Tegra124 DFLL clocksource
      clk: tegra: Add library for the DFLL clock source (open-loop mode)
      clk: tegra: Add closed loop support for the DFLL
      clk: tegra: Add functions for parsing CVB tables
      clk: tegra: Add Tegra124 DFLL clocksource platform driver
      clk: tegra: Save/restore CCLKG_BURST_POLICY on suspend
      clk: tegra: Add the DFLL as a possible parent of the cclk_g clock
      ARM: tegra: Add the DFLL to Tegra124 device tree
      ARM: tegra: Enable the DFLL on the Jetson TK1
      ARM: tegra: Add entries for cpufreq on Tegra124

 .../bindings/clock/nvidia,tegra124-dfll.txt        |   79 +
 arch/arm/boot/dts/tegra114.dtsi                    |    5 +-
 arch/arm/boot/dts/tegra124-jetson-tk1.dts          |   25 +-
 arch/arm/boot/dts/tegra124-venice2.dts             |   10 +-
 arch/arm/boot/dts/tegra124.dtsi                    |   50 +
 arch/arm/boot/dts/tegra20.dtsi                     |    5 +-
 arch/arm/boot/dts/tegra30.dtsi                     |    5 +-
 arch/arm/mach-tegra/Kconfig                        |    1 +
 drivers/clk/tegra/Makefile                         |    3 +
 drivers/clk/tegra/clk-dfll.c                       | 1755 ++++++++++++++++++++
 drivers/clk/tegra/clk-dfll.h                       |   54 +
 drivers/clk/tegra/clk-tegra-super-gen4.c           |    4 +-
 drivers/clk/tegra/clk-tegra124-dfll-fcpu.c         |  166 ++
 drivers/clk/tegra/clk-tegra124.c                   |   82 +
 drivers/clk/tegra/clk.c                            |   39 +-
 drivers/clk/tegra/clk.h                            |    3 +
 drivers/clk/tegra/cvb.c                            |  140 ++
 drivers/clk/tegra/cvb.h                            |   67 +
 drivers/pinctrl/pinctrl-tegra.c                    |   19 +-
 include/dt-bindings/reset/tegra124-car.h           |   12 +
 20 files changed, 2505 insertions(+), 19 deletions(-)
 create mode 100644 Documentation/devicetree/bindings/clock/nvidia,tegra124-dfll.txt
 create mode 100644 drivers/clk/tegra/clk-dfll.c
 create mode 100644 drivers/clk/tegra/clk-dfll.h
 create mode 100644 drivers/clk/tegra/clk-tegra124-dfll-fcpu.c
 create mode 100644 drivers/clk/tegra/cvb.c
 create mode 100644 drivers/clk/tegra/cvb.h
 create mode 100644 include/dt-bindings/reset/tegra124-car.h


From catalin.marinas at arm.com  Fri Aug 21 10:32:42 2015
From: catalin.marinas at arm.com (Catalin Marinas)
Date: Fri, 21 Aug 2015 18:32:42 +0100
Subject: Prevent list poison values from being mapped by userspace
 processes
In-Reply-To: <20150821133043.GV7557@n2100.arm.linux.org.uk>
References: <CABXk95C=CpeL4mNmS6-jJ-0bMJf6fawwfs6DM1-p8FctTEFbpw@mail.gmail.com>
 <20150821133043.GV7557@n2100.arm.linux.org.uk>
Message-ID: <20150821173242.GD16410@e104818-lin.cambridge.arm.com>

On Fri, Aug 21, 2015 at 02:30:43PM +0100, Russell King - ARM Linux wrote:
> On Tue, Aug 18, 2015 at 02:42:44PM -0700, Jeffrey Vander Stoep wrote:
> > List poison pointer values point to memory that is mappable by
> > userspace. i.e. LIST_POISON1 = 0x00100100 and LIST_POISON2 =
> > 0x00200200. This means poison values can be valid pointers controlled
> > by userspace and can be used to exploit the kernel as demonstrated in
> > a recent blackhat talk:
> > https://www.blackhat.com/docs/us-15/materials/us-15-Xu-Ah-Universal-Android-Rooting-Is-Back-wp.pdf
> > 
> > Can these poison values be moved to an area not mappable by userspace
> > on 32 bit ARM?
> 
> As was discussed privately before your message, both Catalin and myself
> agreed that this is not possible, and I proposed alternatives which were
> feasible.

Nice to see these patches so quickly. However, I'll be away for the next
~12 days, so I won't be able to review them.

-- 
Catalin


From sudeep.holla at arm.com  Fri Aug 21 10:37:21 2015
From: sudeep.holla at arm.com (Sudeep Holla)
Date: Fri, 21 Aug 2015 18:37:21 +0100
Subject: [GIT PULL] ARM64: juno: SCPI and dependent drivers for v4.3
In-Reply-To: <20150821161732.GC14452@localhost>
References: <55C1E3FB.5090309@arm.com> <20150813124026.GD23581@localhost>
 <20150813142444.GA4602@e104818-lin.cambridge.arm.com>
 <55CCAF50.4040503@arm.com> <20150821161732.GC14452@localhost>
Message-ID: <CAPKp9uaO7pznZM0ZOqEGTuJCvNXRPcH1rwQCUa2wwScb8ekQpg@mail.gmail.com>

Hi Olof,

On Fri, Aug 21, 2015 at 5:17 PM, Olof Johansson <olof at lixom.net> wrote:
> Hi,
>
> On Thu, Aug 13, 2015 at 03:53:04PM +0100, Sudeep Holla wrote:
>>
>>
>> On 13/08/15 15:24, Catalin Marinas wrote:
>> >On Thu, Aug 13, 2015 at 02:40:26PM +0200, Olof Johansson wrote:
>> >>On Wed, Aug 05, 2015 at 11:22:51AM +0100, Sudeep Holla wrote:
>> >>>Here is the first pull request for SCPI, clock and cpufreq support on
>> >>>ARM64 Juno development platform for v4.3
>> >>
>> >>I'd like to hear from Catalin and Will on why ARM is doing this. Catalin
>> >>and Will are pushing back very hard at vendors who don't use PSCI for
>> >>CPU power management, and then they have coworkers that are looking to
>> >>merge this directly into the kernel.
>> >
>> >Actually, the arm64 CPU power management story is pretty much handled by
>> >Lorenzo and Sudeep in my team, so I trust their judgement ;). But I
>> >agree with you that a better explanation on the reasons behind this is
>> >needed, otherwise we risk confusing messages. I'll try to summarise it
>> >below but Sudeep can reply with more details.
>> >
>>
>> (I will use the acronomys directly as Catalin has already explained the
>> difference)
>>
>> Thanks Catalin for the detailed explanation. I agree that this pull
>> request has not much details, but the patch series makes reference only
>> to the clocks and features provided by the SCP(System Control Processor)
>> to be used by Linux(non-secure) and nothing about CPU power states that
>> are handled by PSCI. This SCPI is completely independent and orthogonal
>> to PSCI.
>
> Yes, I am aware that PSCI and SCPI are two confusingly similar acronyms that
> represent separate things. My concern though is that we're letting in a poorly
> architected solution into the kernel with SCPI. PSCI is already choosing to
> abstract this outside of the kernel. Is there a reason SCPI isn't using the
> same approach?
>

I am not sure we can compare the CPU power states with the CPU DVFS.
In case of power states, we need to ensure all the exception levels have
saved the context and hence PSCI abstraction makes sense for the kernel.
However the CPU DVFS is mostly driven by the kernel based on the load,
so we talk directly to the power controller from the kernel.

In way SCPI is abstracting by hiding all the regulators and PLLs you need
to handle. So I may be missing to understand when you say SCPI also use
PSCI approach.

>> >PSCI only covers CPU boot/cpuidle and platform suspend. It does not have
>> >any provisions for DVFS and I'm not sure this could be easily
>> >standardised (or whether we could find enough supporters to get it
>> >adopted).
>> >
>>
>> Though we are not campaigning it as aggressively as PSCI.
>
> Which, given the resistance to pick up PSCI, this is unlikely to be used by
> anyone...
>

Agreed even I am not sure how widely will that be accepted, but we need to
support the systems which have SCPI right ? Like Juno for now.

>> >SCPI is a (standard) interface to a coprocessor handling clocks etc. to
>> >be used with cpufreq. This patchset adds support for cpufreq/dvs which
>> >is not handled by PSCI. So, just to clarify the acronyms:
>> >
>> >SCPI - System Control and Power Interface - it's a protocol for
>> >communicating with a System Control Processor (e.g. Cortex-M3) via
>> >mailboxes. It is used in Linux for DVFS but this is *not* a secure/EL3
>> >firmware interface (a.k.a. SMC calls). It indeed a firmware interface
>> >but the firmware runs on a separate coprocessor and not on the CPU itself.
>> >
>> >PSCI - Power State Coordination Interface - it is a secure firmware
>> >interface for coordinating the CPU power states (idle, not DVFS). The
>> >firmware may use an SCPI communication channel (e.g. deeper sleep states
>> >where clock changes are needed).
>> >
>>
>> I will add some more information to (hopefully) clarify the doubts.
>>
>> SCP(System Control Processor) offers control and management of the
>> core/cluster power states, various power domain DVFS including the
>> core/cluster, certain system clocks configuration, thermal sensors and
>> many others.
>>
>> Though the core/cluster power states are also handled this SCP,
>> they are accessible only through secure channels and PSCI firmware
>> implementations on the platform rely on that internally. Non-secure
>> access/requests are not possible.
>>
>> Just to summarize, this SCP helps to offload all the power management
>> work to a dedicated low power processor which can be always running.
>> On Juno, its Cortex-M while on AMD Seattle it's Cortex-A5.
>
> I understand what the SCP is used for. What I don't understand is why you're
> adding all this complexity in the kernel for it.
>

I am not sure how we can avoid that though. Any thoughts ?

> Also, is there only one known implementation of this today on Juno? Are there
> others coming soon? Single-user frameworks tend to be hard to get right, and
> it's usually much better to wait until it's clear it will fit more than just
> the original target.
>

No argument on that, the specification is not reviewed as much as PSCI but we do
have version, so can be fixed/enhanced in future. It's no different
w.r.t PSCI in that
respect IMO.

Yes currently only on Juno, but future ARM Ltd. platforms have plans to reuse
the same.

> Anyway, the git server you provided the link to in the original email
> (linux-arm.org) seems to be offline so I couldn't fetch a fresh copy of
> the branch to look at.
>

Extremely sorry for that(not much under my control :(), I will get it
fixed ASAP.
I am current away attending LPC.

> It's pretty clear this is not 4.3 material at this point, so I'll take
> a look at it later.
>

Fair enough, I understand that its too late for v4.3

Regards,
Sudeep


From robert.jarzmik at free.fr  Fri Aug 21 10:36:09 2015
From: robert.jarzmik at free.fr (Robert Jarzmik)
Date: Fri, 21 Aug 2015 19:36:09 +0200
Subject: [PATCH v2 09/21] ARM: pxa: magician: Add OV9640 camera support
In-Reply-To: <1634812.ZDaECJ9ClW@wuerfel> (Arnd Bergmann's message of "Fri, 21
 Aug 2015 15:45:53 +0200")
References: <cover.1439843482.git.petr.cvek@tul.cz>
 <2889798.x6xcIzdYMU@wuerfel> <55D65722.9030508@tul.cz>
 <1634812.ZDaECJ9ClW@wuerfel>
Message-ID: <874mjs5yt2.fsf@belgarion.home>

I shrunk a bit the mailing list.

Arnd Bergmann <arnd at arndb.de> writes:

> On Friday 21 August 2015 00:39:30 Petr Cvek wrote:
>> Dne 20.8.2015 v 22:26 Arnd Bergmann napsal(a):
>> > On Thursday 20 August 2015 21:48:20 Robert Jarzmik wrote:
>> >> Petr Cvek <petr.cvek at tul.cz> writes:
>> Datasheet says:
>> 
>>         tS:RESET        Setting time after software/hardware reset      1 ms
>> 
>> So at least one ~1 ms should be left there. Are msleep less than 20ms valid? 
>> 
>> (checkpatch: msleep < 20ms  can sleep for up to 20ms)
>
> On most kernels, an msleep(1) will sleep somewhere between 1 and 3 milliseconds
> (but could be much longer), while an mdelay(1) tries to sleep around one
> millisecond, more or less.

I have rethought of that a bit more. I'm convinced a delay of "at least 1ms" is
necessary according to the specification, it can also be more.

Moreover, I came to the conclusion this reset sequence is not something that is
"magician" specific (see palmz72_camera_reset() in
.../mach-pxa/palmz72.c). Actually it's not even mach-pxa specific, it's "ov9640"
specific.

Now add this to the fact that it would be good to have a solution working for
devicetree as well, and on any board, and the conclusion I came to was that this
handling deserves to be in ov9640 driver (please correct me if I'm wrong).

The idea behind it is have the reset handled in ov9640, and the gpio provided by
platform data or devicetree.

So Guennadi, is it possible to add a gpio through platform data to ov9640
driver, does it make sense, and would you accept to have the reset handled there
? And if yes, would you, Petr, accept to revamp your patch to have the reset and
power handled in ov9640 ?

Please note that it is a proposal, I'm not forcing anybody, I'd like to choose a
path that agrees with the future push to remove as many machine files as possible.

Cheers.

-- 
Robert


From heiko at sntech.de  Fri Aug 21 10:46:31 2015
From: heiko at sntech.de (Heiko Stuebner)
Date: Fri, 21 Aug 2015 19:46:31 +0200
Subject: [PATCH 1/3] clk: add flag for clocks that need to be enabled on rate
 changes
Message-ID: <1929669.AsgMSusdJb@phil>

Some clocks need to be enabled to accept rate changes. This patch adds a
new flag CLK_SET_RATE_UNGATE that lets clk_change_rate enable the clock
before trying to change the rate and disable it again afterwards.
This of course doesn't effect clocks that are already running at that
point, as their refcount will only temporarily increase.

Signed-off-by: Heiko Stuebner <heiko at sntech.de>
---
 drivers/clk/clk.c            | 18 ++++++++++++++++++
 include/linux/clk-provider.h |  1 +
 2 files changed, 19 insertions(+)

diff --git a/drivers/clk/clk.c b/drivers/clk/clk.c
index 28cd923..564f11e 100644
--- a/drivers/clk/clk.c
+++ b/drivers/clk/clk.c
@@ -1438,6 +1438,15 @@ static void clk_change_rate(struct clk_core *core)
 	else if (core->parent)
 		best_parent_rate = core->parent->rate;
 
+	if (core->flags & CLK_SET_RATE_UNGATE) {
+		unsigned long flags;
+
+		clk_core_prepare(core);
+		flags = clk_enable_lock();
+		clk_core_enable(core);
+		clk_enable_unlock(flags);
+	}
+
 	if (core->new_parent && core->new_parent != core->parent) {
 		old_parent = __clk_set_parent_before(core, core->new_parent);
 		trace_clk_set_parent(core, core->new_parent);
@@ -1464,6 +1473,15 @@ static void clk_change_rate(struct clk_core *core)
 
 	core->rate = clk_recalc(core, best_parent_rate);
 
+	if (core->flags & CLK_SET_RATE_UNGATE) {
+		unsigned long flags;
+
+		flags = clk_enable_lock();
+		clk_core_disable(core);
+		clk_enable_unlock(flags);
+		clk_core_unprepare(core);
+	}
+
 	if (core->notifier_count && old_rate != core->rate)
 		__clk_notify(core, POST_RATE_CHANGE, old_rate, core->rate);
 
diff --git a/include/linux/clk-provider.h b/include/linux/clk-provider.h
index 3ecc07d..21e0025 100644
--- a/include/linux/clk-provider.h
+++ b/include/linux/clk-provider.h
@@ -31,6 +31,7 @@
 #define CLK_SET_RATE_NO_REPARENT BIT(7) /* don't re-parent on rate change */
 #define CLK_GET_ACCURACY_NOCACHE BIT(8) /* do not use the cached clk accuracy */
 #define CLK_RECALC_NEW_RATES	BIT(9) /* recalc rates after notifications */
+#define CLK_SET_RATE_UNGATE	BIT(10) /* clock needs to run to set rate */
 
 struct clk;
 struct clk_hw;
-- 
2.1.4




From heiko at sntech.de  Fri Aug 21 10:47:32 2015
From: heiko at sntech.de (Heiko Stuebner)
Date: Fri, 21 Aug 2015 19:47:32 +0200
Subject: [PATCH 2/3] clk: rockchip: handle mux dependency of fractional
 dividers
In-Reply-To: <1929669.AsgMSusdJb@phil>
References: <1929669.AsgMSusdJb@phil>
Message-ID: <1990916.Xur8Q3rQIb@phil>

The fractional dividers of Rockchip SoCs contain an "auto-gating-feature"
that requires the downstream mux to actually point to the fractional
divider and the fractional divider gate to be enabled, for it to really
accept changes to the divider ratio.

The downstream muxes themselfs are not generic enough to include them
directly into the fractional divider, as they have varying sources of
parent clocks including not only clocks related to the fractional
dividers but other clocks as well.

To solve this, allow our clock branches to specify direct child clock-
branches in the new child property, let the fractional divider register
its downstream mux through this and add a clock notifier that temporarily
switches the mux setting when it notices rate changes to the fractional
divider.

Signed-off-by: Heiko Stuebner <heiko at sntech.de>
---
 drivers/clk/rockchip/clk.c | 137 ++++++++++++++++++++++++++++++++++++++++-----
 drivers/clk/rockchip/clk.h |  19 +++++++
 2 files changed, 142 insertions(+), 14 deletions(-)

diff --git a/drivers/clk/rockchip/clk.c b/drivers/clk/rockchip/clk.c
index 2493881..8c7fd2b 100644
--- a/drivers/clk/rockchip/clk.c
+++ b/drivers/clk/rockchip/clk.c
@@ -102,22 +102,82 @@ static struct clk *rockchip_clk_register_branch(const char *name,
 	return clk;
 }
 
+struct rockchip_clk_frac {
+	struct notifier_block			clk_nb;
+	struct clk_fractional_divider		div;
+	struct clk_gate				gate;
+
+	struct clk_mux				mux;
+	const struct clk_ops			*mux_ops;
+	int					mux_frac_idx;
+
+	bool					rate_change_remuxed;
+	int					rate_change_idx;
+};
+
+#define to_rockchip_clk_frac_nb(nb) \
+			container_of(nb, struct rockchip_clk_frac, clk_nb)
+
+static int rockchip_clk_frac_notifier_cb(struct notifier_block *nb,
+					 unsigned long event, void *data)
+{
+	struct clk_notifier_data *ndata = data;
+	struct rockchip_clk_frac *frac = to_rockchip_clk_frac_nb(nb);
+	struct clk_mux *frac_mux = &frac->mux;
+	int ret = 0;
+
+	pr_debug("%s: event %lu, old_rate %lu, new_rate: %lu\n",
+		 __func__, event, ndata->old_rate, ndata->new_rate);
+	if (event == PRE_RATE_CHANGE) {
+		frac->rate_change_idx = frac->mux_ops->get_parent(&frac_mux->hw);
+		if (frac->rate_change_idx != frac->mux_frac_idx) {
+			frac->mux_ops->set_parent(&frac_mux->hw, frac->mux_frac_idx);
+			frac->rate_change_remuxed = 1;
+		}
+	} else if (event == POST_RATE_CHANGE) {
+		/*
+		 * The POST_RATE_CHANGE notifier runs directly after the
+		 * divider clock is set in clk_change_rate, so we'll have
+		 * remuxed back to the original parent before clk_change_rate
+		 * reaches the mux itself.
+		 */
+		if (frac->rate_change_remuxed) {
+			frac->mux_ops->set_parent(&frac_mux->hw, frac->rate_change_idx);
+			frac->rate_change_remuxed = 0;
+		}
+	}
+
+	return notifier_from_errno(ret);
+}
+
 static struct clk *rockchip_clk_register_frac_branch(const char *name,
 		const char *const *parent_names, u8 num_parents,
 		void __iomem *base, int muxdiv_offset, u8 div_flags,
 		int gate_offset, u8 gate_shift, u8 gate_flags,
-		unsigned long flags, spinlock_t *lock)
+		unsigned long flags, struct rockchip_clk_branch *child,
+		spinlock_t *lock)
 {
+	struct rockchip_clk_frac *frac;
 	struct clk *clk;
 	struct clk_gate *gate = NULL;
 	struct clk_fractional_divider *div = NULL;
 	const struct clk_ops *div_ops = NULL, *gate_ops = NULL;
 
-	if (gate_offset >= 0) {
-		gate = kzalloc(sizeof(*gate), GFP_KERNEL);
-		if (!gate)
-			return ERR_PTR(-ENOMEM);
+	if (muxdiv_offset < 0)
+		return ERR_PTR(-EINVAL);
 
+	if (child && child->branch_type != branch_mux) {
+		pr_err("%s: fractional child clock for %s can only be a mux\n",
+		       __func__, name);
+		return ERR_PTR(-EINVAL);
+	}
+
+	frac = kzalloc(sizeof(*frac), GFP_KERNEL);
+	if (!frac)
+		return ERR_PTR(-ENOMEM);
+
+	if (gate_offset >= 0) {
+		gate = &frac->gate;
 		gate->flags = gate_flags;
 		gate->reg = base + gate_offset;
 		gate->bit_idx = gate_shift;
@@ -125,13 +185,7 @@ static struct clk *rockchip_clk_register_frac_branch(const char *name,
 		gate_ops = &clk_gate_ops;
 	}
 
-	if (muxdiv_offset < 0)
-		return ERR_PTR(-EINVAL);
-
-	div = kzalloc(sizeof(*div), GFP_KERNEL);
-	if (!div)
-		return ERR_PTR(-ENOMEM);
-
+	div = &frac->div;
 	div->flags = div_flags;
 	div->reg = base + muxdiv_offset;
 	div->mshift = 16;
@@ -145,7 +199,61 @@ static struct clk *rockchip_clk_register_frac_branch(const char *name,
 				     NULL, NULL,
 				     &div->hw, div_ops,
 				     gate ? &gate->hw : NULL, gate_ops,
-				     flags);
+				     flags | CLK_SET_RATE_UNGATE);
+	if (IS_ERR(clk)) {
+		kfree(frac);
+		return clk;
+	}
+
+	if (child) {
+		struct clk_mux *frac_mux = &frac->mux;
+		struct clk_init_data init;
+		struct clk *mux_clk;
+		int i, ret;
+
+		frac->mux_frac_idx = -1;
+		for (i = 0; i < child->num_parents; i++) {
+			if (!strcmp(name, child->parent_names[i])) {
+				pr_debug("%s: found fractional parent in mux at pos %d\n",
+					 __func__, i);
+				frac->mux_frac_idx = i;
+				break;
+			}
+		}
+
+		frac->mux_ops = &clk_mux_ops;
+		frac->clk_nb.notifier_call = rockchip_clk_frac_notifier_cb;
+
+		frac_mux->reg = base + child->muxdiv_offset;
+		frac_mux->shift = child->mux_shift;
+		frac_mux->mask = BIT(child->mux_width) - 1;
+		frac_mux->flags = child->mux_flags;
+		frac_mux->lock = lock;
+		frac_mux->hw.init = &init;
+
+		init.name = child->name;
+		init.flags = child->flags | CLK_SET_RATE_PARENT;
+		init.ops = frac->mux_ops;
+		init.parent_names = child->parent_names;
+		init.num_parents = child->num_parents;
+
+		mux_clk = clk_register(NULL, &frac_mux->hw);
+		if (IS_ERR(mux_clk))
+			return clk;
+
+		rockchip_clk_add_lookup(mux_clk, child->id);
+
+		/* notifier on the fraction divider to catch rate changes */
+		if (frac->mux_frac_idx >= 0) {
+			ret = clk_notifier_register(clk, &frac->clk_nb);
+			if (ret)
+				pr_err("%s: failed to register clock notifier for %s\n",
+						__func__, name);
+		} else {
+			pr_warn("%s: could not find %s as parent of %s, rate changes may not work\n",
+				__func__, name, child->name);
+		}
+	}
 
 	return clk;
 }
@@ -249,7 +357,8 @@ void __init rockchip_clk_register_branches(
 				list->parent_names, list->num_parents,
 				reg_base, list->muxdiv_offset, list->div_flags,
 				list->gate_offset, list->gate_shift,
-				list->gate_flags, flags, &clk_lock);
+				list->gate_flags, flags, list->child,
+				&clk_lock);
 			break;
 		case branch_gate:
 			flags |= CLK_SET_RATE_PARENT;
diff --git a/drivers/clk/rockchip/clk.h b/drivers/clk/rockchip/clk.h
index dc8ecb2..147db79 100644
--- a/drivers/clk/rockchip/clk.h
+++ b/drivers/clk/rockchip/clk.h
@@ -235,6 +235,7 @@ struct rockchip_clk_branch {
 	int				gate_offset;
 	u8				gate_shift;
 	u8				gate_flags;
+	struct rockchip_clk_branch	*child;
 };
 
 #define COMPOSITE(_id, cname, pnames, f, mo, ms, mw, mf, ds, dw,\
@@ -369,6 +370,24 @@ struct rockchip_clk_branch {
 		.gate_flags	= gf,				\
 	}
 
+#define COMPOSITE_FRACMUX(_id, cname, pname, f, mo, df, go, gs, gf, ch) \
+	{							\
+		.id		= _id,				\
+		.branch_type	= branch_fraction_divider,	\
+		.name		= cname,			\
+		.parent_names	= (const char *[]){ pname },	\
+		.num_parents	= 1,				\
+		.flags		= f,				\
+		.muxdiv_offset	= mo,				\
+		.div_shift	= 16,				\
+		.div_width	= 16,				\
+		.div_flags	= df,				\
+		.gate_offset	= go,				\
+		.gate_shift	= gs,				\
+		.gate_flags	= gf,				\
+		.child		= &(struct rockchip_clk_branch)ch, \
+	}
+
 #define MUX(_id, cname, pnames, f, o, s, w, mf)			\
 	{							\
 		.id		= _id,				\
-- 
2.1.4




From heiko at sntech.de  Fri Aug 21 10:48:22 2015
From: heiko at sntech.de (Heiko Stuebner)
Date: Fri, 21 Aug 2015 19:48:22 +0200
Subject: [PATCH 3/3] clk: rockchip: include downstream muxes into fractional
 dividers
In-Reply-To: <1929669.AsgMSusdJb@phil>
References: <1929669.AsgMSusdJb@phil>
Message-ID: <4275248.XCb031JeuI@phil>

Use the newly introduced possibility to combine the fractional dividers
with their downstream muxes for all fractional dividers on currently
supported Rockchip SoCs.

Signed-off-by: Heiko Stuebner <heiko at sntech.de>
---
 drivers/clk/rockchip/clk-rk3188.c | 80 +++++++++++++++++++--------------------
 drivers/clk/rockchip/clk-rk3288.c | 66 ++++++++++++++++----------------
 2 files changed, 74 insertions(+), 72 deletions(-)

diff --git a/drivers/clk/rockchip/clk-rk3188.c b/drivers/clk/rockchip/clk-rk3188.c
index ed02bbc..faa6695 100644
--- a/drivers/clk/rockchip/clk-rk3188.c
+++ b/drivers/clk/rockchip/clk-rk3188.c
@@ -335,11 +335,11 @@ static struct rockchip_clk_branch common_clk_branches[] __initdata = {
 	COMPOSITE(0, "hsadc_src", mux_pll_src_gpll_cpll_p, 0,
 			RK2928_CLKSEL_CON(22), 0, 1, MFLAGS, 8, 8, DFLAGS,
 			RK2928_CLKGATE_CON(2), 6, GFLAGS),
-	COMPOSITE_FRAC(0, "hsadc_frac", "hsadc_src", 0,
+	COMPOSITE_FRACMUX(0, "hsadc_frac", "hsadc_src", 0,
 			RK2928_CLKSEL_CON(23), 0,
-			RK2928_CLKGATE_CON(2), 7, GFLAGS),
-	MUX(0, "sclk_hsadc_out", mux_sclk_hsadc_p, 0,
-			RK2928_CLKSEL_CON(22), 4, 2, MFLAGS),
+			RK2928_CLKGATE_CON(2), 7, GFLAGS,
+		MUX(0, "sclk_hsadc_out", mux_sclk_hsadc_p, 0,
+				RK2928_CLKSEL_CON(22), 4, 2, MFLAGS)),
 	INVERTER(SCLK_HSADC, "sclk_hsadc", "sclk_hsadc_out",
 			RK2928_CLKSEL_CON(22), 7, IFLAGS),
 
@@ -350,11 +350,11 @@ static struct rockchip_clk_branch common_clk_branches[] __initdata = {
 	COMPOSITE_NOMUX(0, "spdif_pre", "i2s_src", 0,
 			RK2928_CLKSEL_CON(5), 0, 7, DFLAGS,
 			RK2928_CLKGATE_CON(0), 13, GFLAGS),
-	COMPOSITE_FRAC(0, "spdif_frac", "spdif_pre", CLK_SET_RATE_PARENT,
+	COMPOSITE_FRACMUX(0, "spdif_frac", "spdif_pll", CLK_SET_RATE_PARENT,
 			RK2928_CLKSEL_CON(9), 0,
-			RK2928_CLKGATE_CON(0), 14, GFLAGS),
-	MUX(SCLK_SPDIF, "sclk_spdif", mux_sclk_spdif_p, CLK_SET_RATE_PARENT,
-			RK2928_CLKSEL_CON(5), 8, 2, MFLAGS),
+			RK2928_CLKGATE_CON(0), 14, GFLAGS,
+		MUX(SCLK_SPDIF, "sclk_spdif", mux_sclk_spdif_p, CLK_SET_RATE_PARENT,
+				RK2928_CLKSEL_CON(5), 8, 2, MFLAGS)),
 
 	/*
 	 * Clock-Architecture Diagram 4
@@ -385,35 +385,35 @@ static struct rockchip_clk_branch common_clk_branches[] __initdata = {
 	COMPOSITE_NOMUX(0, "uart0_pre", "uart_src", 0,
 			RK2928_CLKSEL_CON(13), 0, 7, DFLAGS,
 			RK2928_CLKGATE_CON(1), 8, GFLAGS),
-	COMPOSITE_FRAC(0, "uart0_frac", "uart0_pre", 0,
+	COMPOSITE_FRACMUX(0, "uart0_frac", "uart0_pre", 0,
 			RK2928_CLKSEL_CON(17), 0,
-			RK2928_CLKGATE_CON(1), 9, GFLAGS),
-	MUX(SCLK_UART0, "sclk_uart0", mux_sclk_uart0_p, 0,
-			RK2928_CLKSEL_CON(13), 8, 2, MFLAGS),
+			RK2928_CLKGATE_CON(1), 9, GFLAGS,
+		MUX(SCLK_UART0, "sclk_uart0", mux_sclk_uart0_p, 0,
+				RK2928_CLKSEL_CON(13), 8, 2, MFLAGS)),
 	COMPOSITE_NOMUX(0, "uart1_pre", "uart_src", 0,
 			RK2928_CLKSEL_CON(14), 0, 7, DFLAGS,
 			RK2928_CLKGATE_CON(1), 10, GFLAGS),
-	COMPOSITE_FRAC(0, "uart1_frac", "uart1_pre", 0,
+	COMPOSITE_FRACMUX(0, "uart1_frac", "uart1_pre", 0,
 			RK2928_CLKSEL_CON(18), 0,
-			RK2928_CLKGATE_CON(1), 11, GFLAGS),
-	MUX(SCLK_UART1, "sclk_uart1", mux_sclk_uart1_p, 0,
-			RK2928_CLKSEL_CON(14), 8, 2, MFLAGS),
+			RK2928_CLKGATE_CON(1), 11, GFLAGS,
+		MUX(SCLK_UART1, "sclk_uart1", mux_sclk_uart1_p, 0,
+				RK2928_CLKSEL_CON(14), 8, 2, MFLAGS)),
 	COMPOSITE_NOMUX(0, "uart2_pre", "uart_src", 0,
 			RK2928_CLKSEL_CON(15), 0, 7, DFLAGS,
 			RK2928_CLKGATE_CON(1), 12, GFLAGS),
-	COMPOSITE_FRAC(0, "uart2_frac", "uart2_pre", 0,
+	COMPOSITE_FRACMUX(0, "uart2_frac", "uart2_pre", 0,
 			RK2928_CLKSEL_CON(19), 0,
-			RK2928_CLKGATE_CON(1), 13, GFLAGS),
-	MUX(SCLK_UART2, "sclk_uart2", mux_sclk_uart2_p, 0,
-			RK2928_CLKSEL_CON(15), 8, 2, MFLAGS),
+			RK2928_CLKGATE_CON(1), 13, GFLAGS,
+		MUX(SCLK_UART2, "sclk_uart2", mux_sclk_uart2_p, 0,
+				RK2928_CLKSEL_CON(15), 8, 2, MFLAGS)),
 	COMPOSITE_NOMUX(0, "uart3_pre", "uart_src", 0,
 			RK2928_CLKSEL_CON(16), 0, 7, DFLAGS,
 			RK2928_CLKGATE_CON(1), 14, GFLAGS),
-	COMPOSITE_FRAC(0, "uart3_frac", "uart3_pre", 0,
+	COMPOSITE_FRACMUX(0, "uart3_frac", "uart3_pre", 0,
 			RK2928_CLKSEL_CON(20), 0,
-			RK2928_CLKGATE_CON(1), 15, GFLAGS),
-	MUX(SCLK_UART3, "sclk_uart3", mux_sclk_uart3_p, 0,
-			RK2928_CLKSEL_CON(16), 8, 2, MFLAGS),
+			RK2928_CLKGATE_CON(1), 15, GFLAGS,
+		MUX(SCLK_UART3, "sclk_uart3", mux_sclk_uart3_p, 0,
+				RK2928_CLKSEL_CON(16), 8, 2, MFLAGS)),
 
 	GATE(SCLK_JTAG, "jtag", "ext_jtag", 0, RK2928_CLKGATE_CON(1), 3, GFLAGS),
 
@@ -584,27 +584,27 @@ static struct rockchip_clk_branch rk3066a_clk_branches[] __initdata = {
 	COMPOSITE_NOMUX(0, "i2s0_pre", "i2s_src", 0,
 			RK2928_CLKSEL_CON(2), 0, 7, DFLAGS,
 			RK2928_CLKGATE_CON(0), 7, GFLAGS),
-	COMPOSITE_FRAC(0, "i2s0_frac", "i2s0_pre", 0,
+	COMPOSITE_FRACMUX(0, "i2s0_frac", "i2s0_pre", 0,
 			RK2928_CLKSEL_CON(6), 0,
-			RK2928_CLKGATE_CON(0), 8, GFLAGS),
-	MUX(SCLK_I2S0, "sclk_i2s0", mux_sclk_i2s0_p, 0,
-			RK2928_CLKSEL_CON(2), 8, 2, MFLAGS),
+			RK2928_CLKGATE_CON(0), 8, GFLAGS,
+		MUX(SCLK_I2S0, "sclk_i2s0", mux_sclk_i2s0_p, 0,
+				RK2928_CLKSEL_CON(2), 8, 2, MFLAGS)),
 	COMPOSITE_NOMUX(0, "i2s1_pre", "i2s_src", 0,
 			RK2928_CLKSEL_CON(3), 0, 7, DFLAGS,
 			RK2928_CLKGATE_CON(0), 9, GFLAGS),
-	COMPOSITE_FRAC(0, "i2s1_frac", "i2s1_pre", 0,
+	COMPOSITE_FRACMUX(0, "i2s1_frac", "i2s1_pre", 0,
 			RK2928_CLKSEL_CON(7), 0,
-			RK2928_CLKGATE_CON(0), 10, GFLAGS),
-	MUX(SCLK_I2S1, "sclk_i2s1", mux_sclk_i2s1_p, 0,
-			RK2928_CLKSEL_CON(3), 8, 2, MFLAGS),
+			RK2928_CLKGATE_CON(0), 10, GFLAGS,
+		MUX(SCLK_I2S1, "sclk_i2s1", mux_sclk_i2s1_p, 0,
+				RK2928_CLKSEL_CON(3), 8, 2, MFLAGS)),
 	COMPOSITE_NOMUX(0, "i2s2_pre", "i2s_src", 0,
 			RK2928_CLKSEL_CON(4), 0, 7, DFLAGS,
 			RK2928_CLKGATE_CON(0), 11, GFLAGS),
-	COMPOSITE_FRAC(0, "i2s2_frac", "i2s2_pre", 0,
+	COMPOSITE_FRACMUX(0, "i2s2_frac", "i2s2_pre", 0,
 			RK2928_CLKSEL_CON(8), 0,
-			RK2928_CLKGATE_CON(0), 12, GFLAGS),
-	MUX(SCLK_I2S2, "sclk_i2s2", mux_sclk_i2s2_p, 0,
-			RK2928_CLKSEL_CON(4), 8, 2, MFLAGS),
+			RK2928_CLKGATE_CON(0), 12, GFLAGS,
+		MUX(SCLK_I2S2, "sclk_i2s2", mux_sclk_i2s2_p, 0,
+				RK2928_CLKSEL_CON(4), 8, 2, MFLAGS)),
 
 	GATE(HCLK_I2S1, "hclk_i2s1", "hclk_cpu", 0, RK2928_CLKGATE_CON(7), 3, GFLAGS),
 	GATE(HCLK_I2S2, "hclk_i2s2", "hclk_cpu", 0, RK2928_CLKGATE_CON(7), 4, GFLAGS),
@@ -691,11 +691,11 @@ static struct rockchip_clk_branch rk3188_clk_branches[] __initdata = {
 	COMPOSITE_NOMUX(0, "i2s0_pre", "i2s_src", 0,
 			RK2928_CLKSEL_CON(3), 0, 7, DFLAGS,
 			RK2928_CLKGATE_CON(0), 9, GFLAGS),
-	COMPOSITE_FRAC(0, "i2s0_frac", "i2s0_pre", 0,
+	COMPOSITE_FRACMUX(0, "i2s0_frac", "i2s0_pre", 0,
 			RK2928_CLKSEL_CON(7), 0,
-			RK2928_CLKGATE_CON(0), 10, GFLAGS),
-	MUX(SCLK_I2S0, "sclk_i2s0", mux_sclk_i2s0_p, 0,
-			RK2928_CLKSEL_CON(3), 8, 2, MFLAGS),
+			RK2928_CLKGATE_CON(0), 10, GFLAGS,
+		MUX(SCLK_I2S0, "sclk_i2s0", mux_sclk_i2s0_p, 0,
+				RK2928_CLKSEL_CON(3), 8, 2, MFLAGS)),
 
 	GATE(0, "hclk_imem0", "hclk_cpu", 0, RK2928_CLKGATE_CON(4), 14, GFLAGS),
 	GATE(0, "hclk_imem1", "hclk_cpu", 0, RK2928_CLKGATE_CON(4), 15, GFLAGS),
diff --git a/drivers/clk/rockchip/clk-rk3288.c b/drivers/clk/rockchip/clk-rk3288.c
index 0df5bae..18fcdb1 100644
--- a/drivers/clk/rockchip/clk-rk3288.c
+++ b/drivers/clk/rockchip/clk-rk3288.c
@@ -304,11 +304,11 @@ static struct rockchip_clk_branch rk3288_clk_branches[] __initdata = {
 	COMPOSITE(0, "i2s_src", mux_pll_src_cpll_gpll_p, 0,
 			RK3288_CLKSEL_CON(4), 15, 1, MFLAGS, 0, 7, DFLAGS,
 			RK3288_CLKGATE_CON(4), 1, GFLAGS),
-	COMPOSITE_FRAC(0, "i2s_frac", "i2s_src", CLK_SET_RATE_PARENT,
+	COMPOSITE_FRACMUX(0, "i2s_frac", "i2s_src", CLK_SET_RATE_PARENT,
 			RK3288_CLKSEL_CON(8), 0,
-			RK3288_CLKGATE_CON(4), 2, GFLAGS),
-	MUX(0, "i2s_pre", mux_i2s_pre_p, CLK_SET_RATE_PARENT,
-			RK3288_CLKSEL_CON(4), 8, 2, MFLAGS),
+			RK3288_CLKGATE_CON(4), 2, GFLAGS,
+		MUX(0, "i2s_pre", mux_i2s_pre_p, CLK_SET_RATE_PARENT,
+				RK3288_CLKSEL_CON(4), 8, 2, MFLAGS)),
 	COMPOSITE_NODIV(SCLK_I2S0_OUT, "i2s0_clkout", mux_i2s_clkout_p, 0,
 			RK3288_CLKSEL_CON(4), 12, 1, MFLAGS,
 			RK3288_CLKGATE_CON(4), 0, GFLAGS),
@@ -320,20 +320,22 @@ static struct rockchip_clk_branch rk3288_clk_branches[] __initdata = {
 	COMPOSITE_NOMUX(0, "spdif_pre", "spdif_src", 0,
 			RK3288_CLKSEL_CON(5), 0, 7, DFLAGS,
 			RK3288_CLKGATE_CON(4), 4, GFLAGS),
-	COMPOSITE_FRAC(0, "spdif_frac", "spdif_src", 0,
+	COMPOSITE_FRACMUX(0, "spdif_frac", "spdif_src", 0,
 			RK3288_CLKSEL_CON(9), 0,
-			RK3288_CLKGATE_CON(4), 5, GFLAGS),
-	COMPOSITE_NODIV(SCLK_SPDIF, "sclk_spdif", mux_spdif_p, 0,
-			RK3288_CLKSEL_CON(5), 8, 2, MFLAGS,
+			RK3288_CLKGATE_CON(4), 5, GFLAGS,
+		MUX(0, "spdif_mux", mux_spdif_p, 0,
+				RK3288_CLKSEL_CON(5), 8, 2, MFLAGS)),
+	GATE(SCLK_SPDIF, "sclk_spdif", "spdif_mux", 0,
 			RK3288_CLKGATE_CON(4), 6, GFLAGS),
 	COMPOSITE_NOMUX(0, "spdif_8ch_pre", "spdif_src", 0,
 			RK3288_CLKSEL_CON(40), 0, 7, DFLAGS,
 			RK3288_CLKGATE_CON(4), 7, GFLAGS),
-	COMPOSITE_FRAC(0, "spdif_8ch_frac", "spdif_8ch_pre", 0,
+	COMPOSITE_FRACMUX(0, "spdif_8ch_frac", "spdif_8ch_pre", 0,
 			RK3288_CLKSEL_CON(41), 0,
-			RK3288_CLKGATE_CON(4), 8, GFLAGS),
-	COMPOSITE_NODIV(SCLK_SPDIF8CH, "sclk_spdif_8ch", mux_spdif_8ch_p, 0,
-			RK3288_CLKSEL_CON(40), 8, 2, MFLAGS,
+			RK3288_CLKGATE_CON(4), 8, GFLAGS,
+		MUX(0, "spdif_8ch_mux", mux_spdif_8ch_p, 0,
+				RK3288_CLKSEL_CON(40), 8, 2, MFLAGS)),
+	GATE(SCLK_SPDIF8CH, "sclk_spdif_8ch", "spdif_8ch_mux", 0,
 			RK3288_CLKGATE_CON(4), 9, GFLAGS),
 
 	GATE(0, "sclk_acc_efuse", "xin24m", 0,
@@ -536,45 +538,45 @@ static struct rockchip_clk_branch rk3288_clk_branches[] __initdata = {
 	COMPOSITE(0, "uart0_src", mux_pll_src_cpll_gll_usb_npll_p, 0,
 			RK3288_CLKSEL_CON(13), 13, 2, MFLAGS, 0, 7, DFLAGS,
 			RK3288_CLKGATE_CON(1), 8, GFLAGS),
-	COMPOSITE_FRAC(0, "uart0_frac", "uart0_src", CLK_SET_RATE_PARENT,
+	COMPOSITE_FRACMUX(0, "uart0_frac", "uart0_src", CLK_SET_RATE_PARENT,
 			RK3288_CLKSEL_CON(17), 0,
-			RK3288_CLKGATE_CON(1), 9, GFLAGS),
-	MUX(SCLK_UART0, "sclk_uart0", mux_uart0_p, CLK_SET_RATE_PARENT,
-			RK3288_CLKSEL_CON(13), 8, 2, MFLAGS),
+			RK3288_CLKGATE_CON(1), 9, GFLAGS,
+		MUX(SCLK_UART0, "sclk_uart0", mux_uart0_p, CLK_SET_RATE_PARENT,
+				RK3288_CLKSEL_CON(13), 8, 2, MFLAGS)),
 	MUX(0, "uart_src", mux_pll_src_cpll_gpll_p, 0,
 			RK3288_CLKSEL_CON(13), 15, 1, MFLAGS),
 	COMPOSITE_NOMUX(0, "uart1_src", "uart_src", 0,
 			RK3288_CLKSEL_CON(14), 0, 7, DFLAGS,
 			RK3288_CLKGATE_CON(1), 10, GFLAGS),
-	COMPOSITE_FRAC(0, "uart1_frac", "uart1_src", CLK_SET_RATE_PARENT,
+	COMPOSITE_FRACMUX(0, "uart1_frac", "uart1_src", CLK_SET_RATE_PARENT,
 			RK3288_CLKSEL_CON(18), 0,
-			RK3288_CLKGATE_CON(1), 11, GFLAGS),
-	MUX(SCLK_UART1, "sclk_uart1", mux_uart1_p, CLK_SET_RATE_PARENT,
-			RK3288_CLKSEL_CON(14), 8, 2, MFLAGS),
+			RK3288_CLKGATE_CON(1), 11, GFLAGS,
+		MUX(SCLK_UART1, "sclk_uart1", mux_uart1_p, CLK_SET_RATE_PARENT,
+				RK3288_CLKSEL_CON(14), 8, 2, MFLAGS)),
 	COMPOSITE_NOMUX(0, "uart2_src", "uart_src", 0,
 			RK3288_CLKSEL_CON(15), 0, 7, DFLAGS,
 			RK3288_CLKGATE_CON(1), 12, GFLAGS),
-	COMPOSITE_FRAC(0, "uart2_frac", "uart2_src", CLK_SET_RATE_PARENT,
+	COMPOSITE_FRACMUX(0, "uart2_frac", "uart2_src", CLK_SET_RATE_PARENT,
 			RK3288_CLKSEL_CON(19), 0,
-			RK3288_CLKGATE_CON(1), 13, GFLAGS),
-	MUX(SCLK_UART2, "sclk_uart2", mux_uart2_p, CLK_SET_RATE_PARENT,
-			RK3288_CLKSEL_CON(15), 8, 2, MFLAGS),
+			RK3288_CLKGATE_CON(1), 13, GFLAGS,
+		MUX(SCLK_UART2, "sclk_uart2", mux_uart2_p, CLK_SET_RATE_PARENT,
+				RK3288_CLKSEL_CON(15), 8, 2, MFLAGS)),
 	COMPOSITE_NOMUX(0, "uart3_src", "uart_src", 0,
 			RK3288_CLKSEL_CON(16), 0, 7, DFLAGS,
 			RK3288_CLKGATE_CON(1), 14, GFLAGS),
-	COMPOSITE_FRAC(0, "uart3_frac", "uart3_src", CLK_SET_RATE_PARENT,
+	COMPOSITE_FRACMUX(0, "uart3_frac", "uart3_src", CLK_SET_RATE_PARENT,
 			RK3288_CLKSEL_CON(20), 0,
-			RK3288_CLKGATE_CON(1), 15, GFLAGS),
-	MUX(SCLK_UART3, "sclk_uart3", mux_uart3_p, CLK_SET_RATE_PARENT,
-			RK3288_CLKSEL_CON(16), 8, 2, MFLAGS),
+			RK3288_CLKGATE_CON(1), 15, GFLAGS,
+		MUX(SCLK_UART3, "sclk_uart3", mux_uart3_p, CLK_SET_RATE_PARENT,
+				RK3288_CLKSEL_CON(16), 8, 2, MFLAGS)),
 	COMPOSITE_NOMUX(0, "uart4_src", "uart_src", 0,
 			RK3288_CLKSEL_CON(3), 0, 7, DFLAGS,
 			RK3288_CLKGATE_CON(2), 12, GFLAGS),
-	COMPOSITE_FRAC(0, "uart4_frac", "uart4_src", CLK_SET_RATE_PARENT,
+	COMPOSITE_FRACMUX(0, "uart4_frac", "uart4_src", CLK_SET_RATE_PARENT,
 			RK3288_CLKSEL_CON(7), 0,
-			RK3288_CLKGATE_CON(2), 13, GFLAGS),
-	MUX(SCLK_UART4, "sclk_uart4", mux_uart4_p, CLK_SET_RATE_PARENT,
-			RK3288_CLKSEL_CON(3), 8, 2, MFLAGS),
+			RK3288_CLKGATE_CON(2), 13, GFLAGS,
+		MUX(SCLK_UART4, "sclk_uart4", mux_uart4_p, CLK_SET_RATE_PARENT,
+				RK3288_CLKSEL_CON(3), 8, 2, MFLAGS)),
 
 	COMPOSITE(0, "mac_pll_src", mux_pll_src_npll_cpll_gpll_p, 0,
 			RK3288_CLKSEL_CON(21), 0, 2, MFLAGS, 8, 5, DFLAGS,
-- 
2.1.4




From heiko at sntech.de  Fri Aug 21 10:51:41 2015
From: heiko at sntech.de (Heiko Stuebner)
Date: Fri, 21 Aug 2015 19:51:41 +0200
Subject: [PATCH] clk: rockchip: handle critical clocks after registrering all
 clocks
Message-ID: <7786473.0oe27txQFN@phil>

Currently the registration of critical clocks is done in the function
shared between rk3066 and rk3188 clock trees. That results in them
getting handled maybe before all of them are registered.

Therefore move the critical clock handling down to the end of the soc-
specific clock registration function, so that all clocks are registered
before they're maybe handled as critical clock.

Signed-off-by: Heiko Stuebner <heiko at sntech.de>
---
It looks like with the recent flexibilization of the gpio clocks in the
pinctrl driver, we're shaking out some oddities from the clock trees.
This is another one that surfaced.

 drivers/clk/rockchip/clk-rk3188.c | 7 +++++--
 1 file changed, 5 insertions(+), 2 deletions(-)

diff --git a/drivers/clk/rockchip/clk-rk3188.c b/drivers/clk/rockchip/clk-
rk3188.c
index faa6695..bd88542 100644
--- a/drivers/clk/rockchip/clk-rk3188.c
+++ b/drivers/clk/rockchip/clk-rk3188.c
@@ -744,8 +744,6 @@ static void __init rk3188_common_clk_init(struct 
device_node *np)
 
 	rockchip_clk_register_branches(common_clk_branches,
 				  ARRAY_SIZE(common_clk_branches));
-	rockchip_clk_protect_critical(rk3188_critical_clocks,
-				      ARRAY_SIZE(rk3188_critical_clocks));
 
 	rockchip_register_softrst(np, 9, reg_base + RK2928_SOFTRST_CON(0),
 				  ROCKCHIP_SOFTRST_HIWORD_MASK);
@@ -765,6 +763,8 @@ static void __init rk3066a_clk_init(struct device_node 
*np)
 			mux_armclk_p, ARRAY_SIZE(mux_armclk_p),
 			&rk3066_cpuclk_data, rk3066_cpuclk_rates,
 			ARRAY_SIZE(rk3066_cpuclk_rates));
+	rockchip_clk_protect_critical(rk3188_critical_clocks,
+				      ARRAY_SIZE(rk3188_critical_clocks));
 }
 CLK_OF_DECLARE(rk3066a_cru, "rockchip,rk3066a-cru", rk3066a_clk_init);
 
@@ -801,6 +801,9 @@ static void __init rk3188a_clk_init(struct device_node 
*np)
 		pr_warn("%s: missing clocks to reparent aclk_cpu_pre to gpll\n",
 			__func__);
 	}
+
+	rockchip_clk_protect_critical(rk3188_critical_clocks,
+				      ARRAY_SIZE(rk3188_critical_clocks));
 }
 CLK_OF_DECLARE(rk3188a_cru, "rockchip,rk3188a-cru", rk3188a_clk_init);
 
-- 
2.1.4




From romain.perier at gmail.com  Fri Aug 21 11:10:27 2015
From: romain.perier at gmail.com (Romain Perier)
Date: Fri, 21 Aug 2015 18:10:27 +0000
Subject: [PATCH] clk: rockchip: Add pclk_peri to critical clocks on
 RK3066/RK3188
Message-ID: <1440180627-4566-1-git-send-email-romain.perier@gmail.com>

Clocks for bank GPIO3 and GPIO4 are supplied by pclk_peri. These clocks need to
stay on, otherwise pinctrl hangs the system when the driver is probed.

Signed-off-by: Romain Perier <romain.perier at gmail.com>
---
 drivers/clk/rockchip/clk-rk3188.c | 1 +
 1 file changed, 1 insertion(+)

diff --git a/drivers/clk/rockchip/clk-rk3188.c b/drivers/clk/rockchip/clk-rk3188.c
index f63a642..596be81 100644
--- a/drivers/clk/rockchip/clk-rk3188.c
+++ b/drivers/clk/rockchip/clk-rk3188.c
@@ -717,6 +717,7 @@ static const char *const rk3188_critical_clocks[] __initconst = {
 	"aclk_peri",
 	"hclk_peri",
 	"pclk_cpu",
+	"pclk_peri",
 };
 
 static void __init rk3188_common_clk_init(struct device_node *np)
-- 
2.1.4



From heiko at sntech.de  Fri Aug 21 11:24:25 2015
From: heiko at sntech.de (Heiko Stuebner)
Date: Fri, 21 Aug 2015 20:24:25 +0200
Subject: [PATCH] clk: rockchip: Add pclk_peri to critical clocks on
 RK3066/RK3188
In-Reply-To: <1440180627-4566-1-git-send-email-romain.perier@gmail.com>
References: <1440180627-4566-1-git-send-email-romain.perier@gmail.com>
Message-ID: <1855234.LF6EVPIbW1@phil>

Hi Romain,

Am Freitag, 21. August 2015, 18:10:27 schrieb Romain Perier:
> Clocks for bank GPIO3 and GPIO4 are supplied by pclk_peri. These clocks need
> to stay on, otherwise pinctrl hangs the system when the driver is probed.

I don't agree with the commit message.

The issue you see does not originate from the pinctrl driver itself. Instead 
only the new flexible clock handling causes some other (still unhandled) 
component reyling on pclk_peri to hang the system.

In the past the clocks for the gpio banks were simply enabled once during 
probe, so pclk_peri as parent clock would also stay enabled for eternity. Now 
we enable the gpio clocks only when necessary, which results in that pclk_peri 
might get disabled too when no other component has claimed it - hence its 
addition to critical clocks.

Also, please note that Stephen Boyd is now also clock maintainer.


> 
> Signed-off-by: Romain Perier <romain.perier at gmail.com>
> ---
>  drivers/clk/rockchip/clk-rk3188.c | 1 +
>  1 file changed, 1 insertion(+)
> 
> diff --git a/drivers/clk/rockchip/clk-rk3188.c
> b/drivers/clk/rockchip/clk-rk3188.c index f63a642..596be81 100644
> --- a/drivers/clk/rockchip/clk-rk3188.c
> +++ b/drivers/clk/rockchip/clk-rk3188.c
> @@ -717,6 +717,7 @@ static const char *const rk3188_critical_clocks[]
> __initconst = { "aclk_peri",
>  	"hclk_peri",
>  	"pclk_cpu",
> +	"pclk_peri",
>  };
> 
>  static void __init rk3188_common_clk_init(struct device_node *np)



From mark.rutland at arm.com  Fri Aug 21 11:40:59 2015
From: mark.rutland at arm.com (Mark Rutland)
Date: Fri, 21 Aug 2015 19:40:59 +0100
Subject: [PATCH v1 3/3] arm64: dts: add Hi6220 mailbox node
In-Reply-To: <1439977055-1747-4-git-send-email-leo.yan@linaro.org>
References: <1439977055-1747-1-git-send-email-leo.yan@linaro.org>
 <1439977055-1747-4-git-send-email-leo.yan@linaro.org>
Message-ID: <20150821184059.GB2000@svinekod>

On Wed, Aug 19, 2015 at 10:37:35AM +0100, Leo Yan wrote:
> On Hi6220, below memory regions in DDR have specific purpose:
> 
>   0x05e0,0000 - 0x05ef,ffff: For MCU firmware using at runtime;
>   0x0740,f000 - 0x0740,ffff: For MCU firmware's section;
>   0x06df,f000 - 0x06df,ffff: For mailbox message data.
> 
> This patch reserves these memory regions and add device node for
> mailbox in dts.
> 
> Signed-off-by: Leo Yan <leo.yan at linaro.org>
> ---
>  arch/arm64/boot/dts/hisilicon/hi6220-hikey.dts | 20 +++++++++++++++++---
>  arch/arm64/boot/dts/hisilicon/hi6220.dtsi      |  8 ++++++++
>  2 files changed, 25 insertions(+), 3 deletions(-)
> 
> diff --git a/arch/arm64/boot/dts/hisilicon/hi6220-hikey.dts b/arch/arm64/boot/dts/hisilicon/hi6220-hikey.dts
> index e36a539..d5470d3 100644
> --- a/arch/arm64/boot/dts/hisilicon/hi6220-hikey.dts
> +++ b/arch/arm64/boot/dts/hisilicon/hi6220-hikey.dts
> @@ -7,9 +7,6 @@
>  
>  /dts-v1/;
>  
> -/*Reserved 1MB memory for MCU*/
> -/memreserve/ 0x05e00000 0x00100000;
> -
>  #include "hi6220.dtsi"
>  
>  / {
> @@ -28,4 +25,21 @@
>  		device_type = "memory";
>  		reg = <0x0 0x0 0x0 0x40000000>;
>  	};
> +
> +	reserved-memory {
> +		#address-cells = <2>;
> +		#size-cells = <2>;
> +		ranges;
> +
> +		mcu-buf at 05e00000 {
> +			no-map;
> +			reg = <0x0 0x05e00000 0x0 0x00100000>,	/* MCU firmware buffer */
> +			      <0x0 0x0740f000 0x0 0x00001000>;	/* MCU firmware section */
> +		};
> +
> +		mbox-buf at 06dff000 {
> +			no-map;
> +			reg = <0x0 0x06dff000 0x0 0x00001000>;	/* Mailbox message buf */
> +		};
> +	};

As far as I can see, it would be simpler to simply carve these out of the
memory node.

I don't see why you need reserved-memory here, given you're not referring to
these regions by phandle anyway.

Thanks,
Mark.


>  };
> diff --git a/arch/arm64/boot/dts/hisilicon/hi6220.dtsi b/arch/arm64/boot/dts/hisilicon/hi6220.dtsi
> index 3f03380..9ff25bc 100644
> --- a/arch/arm64/boot/dts/hisilicon/hi6220.dtsi
> +++ b/arch/arm64/boot/dts/hisilicon/hi6220.dtsi
> @@ -167,5 +167,13 @@
>  			clocks = <&ao_ctrl 36>, <&ao_ctrl 36>;
>  			clock-names = "uartclk", "apb_pclk";
>  		};
> +
> +		mailbox: mailbox at f7510000 {
> +			#mbox-cells = <1>;
> +			compatible = "hisilicon,hi6220-mbox";
> +			reg = <0x0 0xf7510000 0x0 0x1000>, /* IPC_S */
> +			      <0x0 0x06dff800 0x0 0x0800>; /* Mailbox buffer */
> +			interrupts = <GIC_SPI 94 IRQ_TYPE_LEVEL_HIGH>;
> +		};
>  	};
>  };
> -- 
> 1.9.1
> 


From ijc at debian.org  Fri Aug 21 13:23:46 2015
From: ijc at debian.org (Ian Campbell)
Date: Fri, 21 Aug 2015 21:23:46 +0100
Subject: I/O issues with writing to mtdblock devices on kirkwood
In-Reply-To: <20150821130725.GA6108@lunn.ch>
References: <1440159857.19360.50.camel@debian.org>
 <20150821130725.GA6108@lunn.ch>
Message-ID: <1440188626.23097.35.camel@debian.org>

On Fri, 2015-08-21 at 15:07 +0200, Andrew Lunn wrote:
> On Fri, Aug 21, 2015 at 01:24:17PM +0100, Ian Campbell wrote:
> > Hi kirkwood-upstream,
> 
> Hi Ian
> 
> Thanks for forwarding the reports to us. I will try to reproduce it on my
> TS-119P.

No problem.

BTW maybe Debian bug #794265[0] is related, it is "flash-kernel
subsequent actions result in segfault" where "flash-kernel" is the tool
which writes the mtdblock device (causing SATA issues in the original
mail).

> I'm travelling for the next 10 days, so it may take a while.

Ack. FYI I'll be on vacation from Sunday for a week.

Cheer,
Ian.

[0] https://bugs.debian.org/cgi-bin/bugreport.cgi?bug=794265



From sergei.shtylyov at cogentembedded.com  Fri Aug 21 13:57:09 2015
From: sergei.shtylyov at cogentembedded.com (Sergei Shtylyov)
Date: Fri, 21 Aug 2015 23:57:09 +0300
Subject: [PATCH v2] ARM: shmobile: silk: add SDHI1 DT support
In-Reply-To: <20150812012652.GH15957@verge.net.au>
References: <10037494.4LD4T2QGPX@wasted.cogentembedded.com>
 <2757472.iuyUyRzJ3z@wasted.cogentembedded.com>
 <20150812012652.GH15957@verge.net.au>
Message-ID: <55D790A5.1050008@cogentembedded.com>

On 08/12/2015 04:26 AM, Simon Horman wrote:

>> Define the SILK board dependent part of the SDHI1 (connected to micro-SD slot)
>> device nodes along with the necessary voltage regulators.
>>
>> Based on the original patch by Vladimir Barinov
>> <vladimir.barinov at cogentembedded.com>.
>>
>> Signed-off-by: Sergei Shtylyov <sergei.shtylyov at cogentembedded.com>
>>
>> ---
>> This patch is against 'renesas-devel-20150810-v4.2-rc6' tag of Simon Horman's
>> 'renesas.git' repo plus the R8A7794/SILK QSPI patches just re-posted. It needs
>> the R8A7794 GPIO patches in order to compile.
>>
>> Changes in version 2:
>> - removed not working SDHI0 stuff, renamed the patch;
>> - replaced SDHI1's "wp-gpios" property with "disable-wp".
>
> I am wondering if you could explain the motivation for the "disable-wp"
> update

    Please see the comment in mmc_sd_get_ro().

> and weather it is appropriate for other r8a779* dts files.

    In case of micro-SD slots, yes.

> Thanks.

MBR, Sergei



From khilman at kernel.org  Fri Aug 21 14:04:20 2015
From: khilman at kernel.org (Kevin Hilman)
Date: Fri, 21 Aug 2015 14:04:20 -0700
Subject: [PATCH 2/9] PM / Domains: Remove dev->driver check for runtime PM
In-Reply-To: <CAMuHMdV2gDBaPRb3yE=tVPO_pr7PFA6bwhyQE5raumCh_qPXww@mail.gmail.com>
 (Geert Uytterhoeven's message of "Sun, 16 Aug 2015 11:24:51 +0200")
References: <1438731339-58317-1-git-send-email-lina.iyer@linaro.org>
 <1438731339-58317-3-git-send-email-lina.iyer@linaro.org>
 <7hfv3onv5c.fsf@deeprootsystems.com>
 <CAMuHMdVeffa-jgXuSjDQBKTrhgW-d87OKzs1iXX+4y-9U_AJbg@mail.gmail.com>
 <7hwpwylepx.fsf@deeprootsystems.com>
 <CAMuHMdW-T9rUWXsQeffwtXspHbjfGqo_0G4QMB1o0TwTLJAQAg@mail.gmail.com>
 <CAMAWPa-0R42thqBo0omn0KK7y0wyxoyaP+wsfoRvXBmWhBytKg@mail.gmail.com>
 <CAMuHMdV2gDBaPRb3yE=tVPO_pr7PFA6bwhyQE5raumCh_qPXww@mail.gmail.com>
Message-ID: <7hio88gxpn.fsf@deeprootsystems.com>

Geert Uytterhoeven <geert at linux-m68k.org> writes:

> Hi Kevin,
>
> On Fri, Aug 14, 2015 at 7:19 PM, Kevin Hilman <khilman at kernel.org> wrote:
>> On Fri, Aug 14, 2015 at 12:24 AM, Geert Uytterhoeven
>> <geert at linux-m68k.org> wrote:
>>> On Fri, Aug 14, 2015 at 5:40 AM, Kevin Hilman <khilman at kernel.org> wrote:
>>>> Geert Uytterhoeven <geert at linux-m68k.org> writes:
>>>>> On Wed, Aug 12, 2015 at 9:50 PM, Kevin Hilman <khilman at kernel.org> wrote:
>>>>>> This check might have made sense before PM domains, but with PM domains,
>>>>>> it's entirely possible to have a simple device without a driver and the
>>>>>> PM domain handles all the necesary PM, so I think this check
>>>>>> could/should be removed.
>>>>>>
>>>>>> Thoughts?
>>>>>
>>>>> Simple devices without a driver aren't handled automatically.
>>>>> At minimum, the driver should call pm_runtime_enable(), cfr.
>>>>> drivers/bus/simple-pm-bus.c.
>>>>
>>>> That's correct, and in the proof-of-concept stuff I hacked up and in
>>>> Lina's series, the CPU "devices" do indeed to this.  Without that, they
>>>> wouldn't end up ever taking this codepath through genpd's
>>>> runtime_suspend and power_off hooks.
>>>>
>>>> Also, I'm not sure if your comment was meant to be an objection to the
>>>> patch?  or if you're OK with it.
>>>
>>> My comment was purely meant as a response to "it's entirely possible to have a
>>> simple device without a driver and the PM domain handles all the necesary PM".
>>
>> Right, so if the PM domain does the pm_runtime_enable() for these
>> "simple" devices without drivers, they can still exist without a
>> driver, and the PM domain doing all the magic.
>
> Is it possible to let the PM Domain do the pm_runtime_enable() itself in
> the absence of a driver? 

Well, I suppose it's possible, not sure it's recommended. :)

> If yes, I wouldn't have needed simple-pm-bus.c.  
> What if a driver is bound later?

Yeah, you're approach is better.

Kevin


From fkan at apm.com  Fri Aug 21 15:00:58 2015
From: fkan at apm.com (Feng Kan)
Date: Fri, 21 Aug 2015 15:00:58 -0700
Subject: [PATCH V4 0/2] arm64: copy to/in/from user optimization
Message-ID: <1440194458-4837-1-git-send-email-fkan@apm.com>

This coverts all copy in/from/to user file to use the copy template file.
The copy template file is based on the memcpy.S. The second patch converts
the memcpy to use the copy template as well. Overnight trinity test and
10G iperf was used to test correctness and performance. Noticeable
iperf improvement (~30%) on the receive side.

V4 Change:
	- base the copy template file on the existing memcpy.S
	- convert copy*.s to user copy template
	- conver the memcpy to use the copy template.

Feng Kan (2):
  arm64: copy_to-from-in_user optimization using copy template
  arm64: Change memcpy in kernel to use the copy template file

 arch/arm64/lib/copy_from_user.S |  78 +++++++++-------
 arch/arm64/lib/copy_in_user.S   |  66 ++++++++------
 arch/arm64/lib/copy_template.S  | 196 ++++++++++++++++++++++++++++++++++++++++
 arch/arm64/lib/copy_to_user.S   |  66 ++++++++------
 arch/arm64/lib/memcpy.S         | 179 ++++++------------------------------
 5 files changed, 340 insertions(+), 245 deletions(-)
 create mode 100644 arch/arm64/lib/copy_template.S

-- 
1.9.1



From fkan at apm.com  Fri Aug 21 15:01:33 2015
From: fkan at apm.com (Feng Kan)
Date: Fri, 21 Aug 2015 15:01:33 -0700
Subject: [PATCH V4 1/2] arm64: copy_to-from-in_user optimization using copy
 template
Message-ID: <1440194493-4907-1-git-send-email-fkan@apm.com>

This patch optimize copy_to-from-in_user for arm 64bit architecture.
The copy template is using the memcpy.S as a base. This allows the
sharing of the copy template with all of the copy*.S files.

Signed-off-by: Feng Kan <fkan at apm.com>
Signed-off-by: Balamurugan Shanmugam <bshanmugam at apm.com>
---
 arch/arm64/lib/copy_from_user.S |  78 +++++++++-------
 arch/arm64/lib/copy_in_user.S   |  66 ++++++++------
 arch/arm64/lib/copy_template.S  | 196 ++++++++++++++++++++++++++++++++++++++++
 arch/arm64/lib/copy_to_user.S   |  66 ++++++++------
 4 files changed, 314 insertions(+), 92 deletions(-)
 create mode 100644 arch/arm64/lib/copy_template.S

diff --git a/arch/arm64/lib/copy_from_user.S b/arch/arm64/lib/copy_from_user.S
index 1be9ef2..cb085cf 100644
--- a/arch/arm64/lib/copy_from_user.S
+++ b/arch/arm64/lib/copy_from_user.S
@@ -18,6 +18,7 @@
 
 #include <asm/alternative.h>
 #include <asm/assembler.h>
+#include <asm/cache.h>
 #include <asm/cpufeature.h>
 #include <asm/sysreg.h>
 
@@ -31,49 +32,58 @@
  * Returns:
  *	x0 - bytes not copied
  */
+
+	.macro ldrb1 label, ptr, regB, val
+	USER(\label, ldrb  \ptr, [\regB], \val)
+	.endm
+
+	.macro strb1 label, ptr, regB, val
+	strb \ptr, [\regB], \val
+	.endm
+
+	.macro ldrh1 label, ptr, regB, val
+	USER(\label, ldrh  \ptr, [\regB], \val)
+	.endm
+
+	.macro strh1 label, ptr, regB, val
+	strh \ptr, [\regB], \val
+	.endm
+
+	.macro ldr1 label, ptr, regB, val
+	USER(\label, ldr \ptr, [\regB], \val)
+	.endm
+
+	.macro str1 label, ptr, regB, val
+	str \ptr, [\regB], \val
+	.endm
+
+	.macro ldp1 label, ptr, regB, regC, val
+	USER(\label, ldp \ptr, \regB, [\regC], \val)
+	.endm
+
+	.macro stp1 label, ptr, regB, regC, val
+	stp \ptr, \regB, [\regC], \val
+	.endm
+
 ENTRY(__copy_from_user)
 ALTERNATIVE("nop", __stringify(SET_PSTATE_PAN(0)), ARM64_HAS_PAN, \
 	    CONFIG_ARM64_PAN)
-	add	x5, x1, x2			// upper user buffer boundary
-	subs	x2, x2, #16
-	b.mi	1f
-0:
-USER(9f, ldp	x3, x4, [x1], #16)
-	subs	x2, x2, #16
-	stp	x3, x4, [x0], #16
-	b.pl	0b
-1:	adds	x2, x2, #8
-	b.mi	2f
-USER(9f, ldr	x3, [x1], #8	)
-	sub	x2, x2, #8
-	str	x3, [x0], #8
-2:	adds	x2, x2, #4
-	b.mi	3f
-USER(9f, ldr	w3, [x1], #4	)
-	sub	x2, x2, #4
-	str	w3, [x0], #4
-3:	adds	x2, x2, #2
-	b.mi	4f
-USER(9f, ldrh	w3, [x1], #2	)
-	sub	x2, x2, #2
-	strh	w3, [x0], #2
-4:	adds	x2, x2, #1
-	b.mi	5f
-USER(9f, ldrb	w3, [x1]	)
-	strb	w3, [x0]
-5:	mov	x0, #0
+#include "copy_template.S"
 ALTERNATIVE("nop", __stringify(SET_PSTATE_PAN(1)), ARM64_HAS_PAN, \
 	    CONFIG_ARM64_PAN)
+	mov	x0, #0				// Nothing to copy
 	ret
 ENDPROC(__copy_from_user)
 
 	.section .fixup,"ax"
 	.align	2
-9:	sub	x2, x5, x1
-	mov	x3, x2
-10:	strb	wzr, [x0], #1			// zero remaining buffer space
-	subs	x3, x3, #1
-	b.ne	10b
-	mov	x0, x2				// bytes not copied
+11:
+	sub	x4, tmp3, dst
+	mov	x0, x4
+	sub	dst, tmp3, x4
+
+20:	strb	wzr, [dst], #1			// zero remaining buffer space
+	subs	x4, x4, #1
+	b.ne	20b
 	ret
 	.previous
diff --git a/arch/arm64/lib/copy_in_user.S b/arch/arm64/lib/copy_in_user.S
index 1b94661e..b54d44e 100644
--- a/arch/arm64/lib/copy_in_user.S
+++ b/arch/arm64/lib/copy_in_user.S
@@ -20,6 +20,7 @@
 
 #include <asm/alternative.h>
 #include <asm/assembler.h>
+#include <asm/cache.h>
 #include <asm/cpufeature.h>
 #include <asm/sysreg.h>
 
@@ -33,44 +34,51 @@
  * Returns:
  *	x0 - bytes not copied
  */
+	.macro ldrb1 label, ptr, regB, val
+	USER(\label, ldrb  \ptr, [\regB], \val)
+	.endm
+
+	.macro strb1 label, ptr, regB, val
+	USER(\label, strb \ptr, [\regB], \val)
+	.endm
+
+	.macro ldrh1 label, ptr, regB, val
+	USER(\label, ldrh  \ptr, [\regB], \val)
+	.endm
+
+	.macro strh1 label, ptr, regB, val
+	USER(\label, strh \ptr, [\regB], \val)
+	.endm
+
+	.macro ldr1 label, ptr, regB, val
+	USER(\label, ldr \ptr, [\regB], \val)
+	.endm
+
+	.macro str1 label, ptr, regB, val
+	USER(\label, str \ptr, [\regB], \val)
+	.endm
+
+	.macro ldp1 label, ptr, regB, regC, val
+	USER(\label, ldp \ptr, \regB, [\regC], \val)
+	.endm
+
+	.macro stp1 label, ptr, regB, regC, val
+	USER(\label, stp \ptr, \regB, [\regC], \val)
+	.endm
+
 ENTRY(__copy_in_user)
 ALTERNATIVE("nop", __stringify(SET_PSTATE_PAN(0)), ARM64_HAS_PAN, \
 	    CONFIG_ARM64_PAN)
-	add	x5, x0, x2			// upper user buffer boundary
-	subs	x2, x2, #16
-	b.mi	1f
-0:
-USER(9f, ldp	x3, x4, [x1], #16)
-	subs	x2, x2, #16
-USER(9f, stp	x3, x4, [x0], #16)
-	b.pl	0b
-1:	adds	x2, x2, #8
-	b.mi	2f
-USER(9f, ldr	x3, [x1], #8	)
-	sub	x2, x2, #8
-USER(9f, str	x3, [x0], #8	)
-2:	adds	x2, x2, #4
-	b.mi	3f
-USER(9f, ldr	w3, [x1], #4	)
-	sub	x2, x2, #4
-USER(9f, str	w3, [x0], #4	)
-3:	adds	x2, x2, #2
-	b.mi	4f
-USER(9f, ldrh	w3, [x1], #2	)
-	sub	x2, x2, #2
-USER(9f, strh	w3, [x0], #2	)
-4:	adds	x2, x2, #1
-	b.mi	5f
-USER(9f, ldrb	w3, [x1]	)
-USER(9f, strb	w3, [x0]	)
-5:	mov	x0, #0
+#include "copy_template.S"
 ALTERNATIVE("nop", __stringify(SET_PSTATE_PAN(1)), ARM64_HAS_PAN, \
 	    CONFIG_ARM64_PAN)
+	mov	x0, #0
 	ret
 ENDPROC(__copy_in_user)
 
 	.section .fixup,"ax"
 	.align	2
-9:	sub	x0, x5, x0			// bytes not copied
+11:	sub	tmp3, tmp3, dst			// bytes not copied
+	mov	x0, tmp3
 	ret
 	.previous
diff --git a/arch/arm64/lib/copy_template.S b/arch/arm64/lib/copy_template.S
new file mode 100644
index 0000000..c9ece2f
--- /dev/null
+++ b/arch/arm64/lib/copy_template.S
@@ -0,0 +1,196 @@
+/*
+ * Copyright (C) 2013 ARM Ltd.
+ * Copyright (C) 2013 Linaro.
+ *
+ * This code is based on glibc cortex strings work originally authored by Linaro
+ * and re-licensed under GPLv2 for the Linux kernel. The original code can
+ * be found @
+ *
+ * http://bazaar.launchpad.net/~linaro-toolchain-dev/cortex-strings/trunk/
+ * files/head:/src/aarch64/
+ *
+ * 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.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program.  If not, see <http://www.gnu.org/licenses/>.
+ */
+
+
+/*
+ * Copy a buffer from src to dest (alignment handled by the hardware)
+ *
+ * Parameters:
+ *	x0 - dest
+ *	x1 - src
+ *	x2 - n
+ * Returns:
+ *	x0 - dest
+ */
+dstin	.req	x0
+src	.req	x1
+count	.req	x2
+tmp1	.req	x3
+tmp1w	.req	w3
+tmp2	.req	x4
+tmp2w	.req	w4
+tmp3	.req	x5
+tmp3w	.req	w5
+dst	.req	x6
+
+A_l	.req	x7
+A_h	.req	x8
+B_l	.req	x9
+B_h	.req	x10
+C_l	.req	x11
+C_h	.req	x12
+D_l	.req	x13
+D_h	.req	x14
+
+	mov	dst, dstin
+	add	tmp3, dst, count
+	cmp	count, #16
+	/*When memory length is less than 16, the accessed are not aligned.*/
+	b.lo	.Ltiny15
+
+	neg	tmp2, src
+	ands	tmp2, tmp2, #15/* Bytes to reach alignment. */
+	b.eq	.LSrcAligned
+	sub	count, count, tmp2
+	/*
+	* Copy the leading memory data from src to dst in an increasing
+	* address order.By this way,the risk of overwritting the source
+	* memory data is eliminated when the distance between src and
+	* dst is less than 16. The memory accesses here are alignment.
+	*/
+	tbz	tmp2, #0, 1f
+	ldrb1	11f, tmp1w, src, #1
+	strb1	11f, tmp1w, dst, #1
+1:
+	tbz	tmp2, #1, 2f
+	ldrh1	11f, tmp1w, src, #2
+	strh1	11f, tmp1w, dst, #2
+2:
+	tbz	tmp2, #2, 3f
+	ldr1	11f, tmp1w, src, #4
+	str1	11f, tmp1w, dst, #4
+3:
+	tbz	tmp2, #3, .LSrcAligned
+	ldr1	11f, tmp1, src, #8
+	str1	11f, tmp1, dst, #8
+
+.LSrcAligned:
+	cmp	count, #64
+	b.ge	.Lcpy_over64
+	/*
+	* Deal with small copies quickly by dropping straight into the
+	* exit block.
+	*/
+.Ltail63:
+	/*
+	* Copy up to 48 bytes of data. At this point we only need the
+	* bottom 6 bits of count to be accurate.
+	*/
+	ands	tmp1, count, #0x30
+	b.eq	.Ltiny15
+	cmp	tmp1w, #0x20
+	b.eq	1f
+	b.lt	2f
+	ldp1	11f, A_l, A_h, src, #16
+	stp1	11f, A_l, A_h, dst, #16
+1:
+	ldp1	11f, A_l, A_h, src, #16
+	stp1	11f, A_l, A_h, dst, #16
+2:
+	ldp1	11f, A_l, A_h, src, #16
+	stp1	11f, A_l, A_h, dst, #16
+.Ltiny15:
+	/*
+	* Prefer to break one ldp/stp into several load/store to access
+	* memory in an increasing address order,rather than to load/store 16
+	* bytes from (src-16) to (dst-16) and to backward the src to aligned
+	* address,which way is used in original cortex memcpy. If keeping
+	* the original memcpy process here, memmove need to satisfy the
+	* precondition that src address is at least 16 bytes bigger than dst
+	* address,otherwise some source data will be overwritten when memove
+	* call memcpy directly. To make memmove simpler and decouple the
+	* memcpy's dependency on memmove, withdrew the original process.
+	*/
+	tbz	count, #3, 1f
+	ldr1	11f, tmp1, src, #8
+	str1	11f, tmp1, dst, #8
+1:
+	tbz	count, #2, 2f
+	ldr1	11f, tmp1w, src, #4
+	str1	11f, tmp1w, dst, #4
+2:
+	tbz	count, #1, 3f
+	ldrh1	11f, tmp1w, src, #2
+	strh1	11f, tmp1w, dst, #2
+3:
+	tbz	count, #0, .Lexitfunc
+	ldrb1	11f, tmp1w, src, #1
+	strb1	11f, tmp1w, dst, #1
+
+	b	.Lexitfunc
+
+.Lcpy_over64:
+	subs	count, count, #128
+	b.ge	.Lcpy_body_large
+	/*
+	* Less than 128 bytes to copy, so handle 64 here and then jump
+	* to the tail.
+	*/
+	ldp1	11f, A_l, A_h, src, #16
+	stp1	11f, A_l, A_h, dst, #16
+	ldp1	11f, B_l, B_h, src, #16
+	ldp1	11f, C_l, C_h, src, #16
+	stp1	11f, B_l, B_h, dst, #16
+	stp1	11f, C_l, C_h, dst, #16
+	ldp1	11f, D_l, D_h, src, #16
+	stp1	11f, D_l, D_h, dst, #16
+
+	tst	count, #0x3f
+	b.ne	.Ltail63
+	b	.Lexitfunc
+
+	/*
+	* Critical loop.  Start at a new cache line boundary.  Assuming
+	* 64 bytes per line this ensures the entire loop is in one line.
+	*/
+	.p2align	L1_CACHE_SHIFT
+.Lcpy_body_large:
+	/* pre-get 64 bytes data. */
+	ldp1	11f, A_l, A_h, src, #16
+	ldp1	11f, B_l, B_h, src, #16
+	ldp1	11f, C_l, C_h, src, #16
+	ldp1	11f, D_l, D_h, src, #16
+1:
+	/*
+	* interlace the load of next 64 bytes data block with store of the last
+	* loaded 64 bytes data.
+	*/
+	stp1	11f, A_l, A_h, dst, #16
+	ldp1	11f, A_l, A_h, src, #16
+	stp1	11f, B_l, B_h, dst, #16
+	ldp1	11f, B_l, B_h, src, #16
+	stp1	11f, C_l, C_h, dst, #16
+	ldp1	11f, C_l, C_h, src, #16
+	stp1	11f, D_l, D_h, dst, #16
+	ldp1	11f, D_l, D_h, src, #16
+	subs	count, count, #64
+	b.ge	1b
+	stp1	11f, A_l, A_h, dst, #16
+	stp1	11f, B_l, B_h, dst, #16
+	stp1	11f, C_l, C_h, dst, #16
+	stp1	11f, D_l, D_h, dst, #16
+
+	tst	count, #0x3f
+	b.ne	.Ltail63
+.Lexitfunc:
diff --git a/arch/arm64/lib/copy_to_user.S b/arch/arm64/lib/copy_to_user.S
index a257b47..0ef3eb2 100644
--- a/arch/arm64/lib/copy_to_user.S
+++ b/arch/arm64/lib/copy_to_user.S
@@ -18,6 +18,7 @@
 
 #include <asm/alternative.h>
 #include <asm/assembler.h>
+#include <asm/cache.h>
 #include <asm/cpufeature.h>
 #include <asm/sysreg.h>
 
@@ -31,44 +32,51 @@
  * Returns:
  *	x0 - bytes not copied
  */
+	.macro ldrb1 label, ptr, regB, val
+	ldrb  \ptr, [\regB], \val
+	.endm
+
+	.macro strb1 label, ptr, regB, val
+	USER(\label, strb \ptr, [\regB], \val)
+	.endm
+
+	.macro ldrh1 label, ptr, regB, val
+	ldrh  \ptr, [\regB], \val
+	.endm
+
+	.macro strh1 label, ptr, regB, val
+	USER(\label, strh \ptr, [\regB], \val)
+	.endm
+
+	.macro ldr1 label, ptr, regB, val
+	ldr \ptr, [\regB], \val
+	.endm
+
+	.macro str1 label, ptr, regB, val
+	USER(\label, str \ptr, [\regB], \val)
+	.endm
+
+	.macro ldp1 label, ptr, regB, regC, val
+	ldp \ptr, \regB, [\regC], \val
+	.endm
+
+	.macro stp1 label, ptr, regB, regC, val
+	USER(\label, stp \ptr, \regB, [\regC], \val)
+	.endm
+
 ENTRY(__copy_to_user)
 ALTERNATIVE("nop", __stringify(SET_PSTATE_PAN(0)), ARM64_HAS_PAN, \
 	    CONFIG_ARM64_PAN)
-	add	x5, x0, x2			// upper user buffer boundary
-	subs	x2, x2, #16
-	b.mi	1f
-0:
-	ldp	x3, x4, [x1], #16
-	subs	x2, x2, #16
-USER(9f, stp	x3, x4, [x0], #16)
-	b.pl	0b
-1:	adds	x2, x2, #8
-	b.mi	2f
-	ldr	x3, [x1], #8
-	sub	x2, x2, #8
-USER(9f, str	x3, [x0], #8	)
-2:	adds	x2, x2, #4
-	b.mi	3f
-	ldr	w3, [x1], #4
-	sub	x2, x2, #4
-USER(9f, str	w3, [x0], #4	)
-3:	adds	x2, x2, #2
-	b.mi	4f
-	ldrh	w3, [x1], #2
-	sub	x2, x2, #2
-USER(9f, strh	w3, [x0], #2	)
-4:	adds	x2, x2, #1
-	b.mi	5f
-	ldrb	w3, [x1]
-USER(9f, strb	w3, [x0]	)
-5:	mov	x0, #0
+#include "copy_template.S"
 ALTERNATIVE("nop", __stringify(SET_PSTATE_PAN(1)), ARM64_HAS_PAN, \
 	    CONFIG_ARM64_PAN)
+	mov	x0, #0
 	ret
 ENDPROC(__copy_to_user)
 
 	.section .fixup,"ax"
 	.align	2
-9:	sub	x0, x5, x0			// bytes not copied
+11:	sub	tmp3, tmp3, dst			// bytes not copied
+	mov	x0, tmp3
 	ret
 	.previous
-- 
1.9.1



From fkan at apm.com  Fri Aug 21 15:01:41 2015
From: fkan at apm.com (Feng Kan)
Date: Fri, 21 Aug 2015 15:01:41 -0700
Subject: [PATCH V4 2/2] arm64: Change memcpy in kernel to use the copy
 template file
Message-ID: <1440194501-4953-1-git-send-email-fkan@apm.com>

This converts the memcpy.S to use the copy template file. The copy
template file was based originally on the memcpy.S. Minor changes
was made to it to accommodate the copy to/from/in user files.

Signed-off-by: Feng Kan <fkan at apm.com>
---
 arch/arm64/lib/memcpy.S | 179 +++++++-----------------------------------------
 1 file changed, 26 insertions(+), 153 deletions(-)

diff --git a/arch/arm64/lib/memcpy.S b/arch/arm64/lib/memcpy.S
index 8a9a96d..761acd7 100644
--- a/arch/arm64/lib/memcpy.S
+++ b/arch/arm64/lib/memcpy.S
@@ -36,166 +36,39 @@
  * Returns:
  *	x0 - dest
  */
-dstin	.req	x0
-src	.req	x1
-count	.req	x2
-tmp1	.req	x3
-tmp1w	.req	w3
-tmp2	.req	x4
-tmp2w	.req	w4
-tmp3	.req	x5
-tmp3w	.req	w5
-dst	.req	x6
+        .macro ldrb1 label, ptr, regB, val
+        ldrb  \ptr, [\regB], \val
+        .endm
 
-A_l	.req	x7
-A_h	.req	x8
-B_l	.req	x9
-B_h	.req	x10
-C_l	.req	x11
-C_h	.req	x12
-D_l	.req	x13
-D_h	.req	x14
+        .macro strb1 label, ptr, regB, val
+        strb \ptr, [\regB], \val
+        .endm
 
-ENTRY(memcpy)
-	mov	dst, dstin
-	cmp	count, #16
-	/*When memory length is less than 16, the accessed are not aligned.*/
-	b.lo	.Ltiny15
+        .macro ldrh1 label, ptr, regB, val
+        ldrh  \ptr, [\regB], \val
+        .endm
 
-	neg	tmp2, src
-	ands	tmp2, tmp2, #15/* Bytes to reach alignment. */
-	b.eq	.LSrcAligned
-	sub	count, count, tmp2
-	/*
-	* Copy the leading memory data from src to dst in an increasing
-	* address order.By this way,the risk of overwritting the source
-	* memory data is eliminated when the distance between src and
-	* dst is less than 16. The memory accesses here are alignment.
-	*/
-	tbz	tmp2, #0, 1f
-	ldrb	tmp1w, [src], #1
-	strb	tmp1w, [dst], #1
-1:
-	tbz	tmp2, #1, 2f
-	ldrh	tmp1w, [src], #2
-	strh	tmp1w, [dst], #2
-2:
-	tbz	tmp2, #2, 3f
-	ldr	tmp1w, [src], #4
-	str	tmp1w, [dst], #4
-3:
-	tbz	tmp2, #3, .LSrcAligned
-	ldr	tmp1, [src],#8
-	str	tmp1, [dst],#8
+        .macro strh1 label, ptr, regB, val
+        strh \ptr, [\regB], \val
+        .endm
 
-.LSrcAligned:
-	cmp	count, #64
-	b.ge	.Lcpy_over64
-	/*
-	* Deal with small copies quickly by dropping straight into the
-	* exit block.
-	*/
-.Ltail63:
-	/*
-	* Copy up to 48 bytes of data. At this point we only need the
-	* bottom 6 bits of count to be accurate.
-	*/
-	ands	tmp1, count, #0x30
-	b.eq	.Ltiny15
-	cmp	tmp1w, #0x20
-	b.eq	1f
-	b.lt	2f
-	ldp	A_l, A_h, [src], #16
-	stp	A_l, A_h, [dst], #16
-1:
-	ldp	A_l, A_h, [src], #16
-	stp	A_l, A_h, [dst], #16
-2:
-	ldp	A_l, A_h, [src], #16
-	stp	A_l, A_h, [dst], #16
-.Ltiny15:
-	/*
-	* Prefer to break one ldp/stp into several load/store to access
-	* memory in an increasing address order,rather than to load/store 16
-	* bytes from (src-16) to (dst-16) and to backward the src to aligned
-	* address,which way is used in original cortex memcpy. If keeping
-	* the original memcpy process here, memmove need to satisfy the
-	* precondition that src address is at least 16 bytes bigger than dst
-	* address,otherwise some source data will be overwritten when memove
-	* call memcpy directly. To make memmove simpler and decouple the
-	* memcpy's dependency on memmove, withdrew the original process.
-	*/
-	tbz	count, #3, 1f
-	ldr	tmp1, [src], #8
-	str	tmp1, [dst], #8
-1:
-	tbz	count, #2, 2f
-	ldr	tmp1w, [src], #4
-	str	tmp1w, [dst], #4
-2:
-	tbz	count, #1, 3f
-	ldrh	tmp1w, [src], #2
-	strh	tmp1w, [dst], #2
-3:
-	tbz	count, #0, .Lexitfunc
-	ldrb	tmp1w, [src]
-	strb	tmp1w, [dst]
+        .macro ldr1 label, ptr, regB, val
+        ldr \ptr, [\regB], \val
+        .endm
 
-.Lexitfunc:
-	ret
+        .macro str1 label, ptr, regB, val
+        str \ptr, [\regB], \val
+        .endm
 
-.Lcpy_over64:
-	subs	count, count, #128
-	b.ge	.Lcpy_body_large
-	/*
-	* Less than 128 bytes to copy, so handle 64 here and then jump
-	* to the tail.
-	*/
-	ldp	A_l, A_h, [src],#16
-	stp	A_l, A_h, [dst],#16
-	ldp	B_l, B_h, [src],#16
-	ldp	C_l, C_h, [src],#16
-	stp	B_l, B_h, [dst],#16
-	stp	C_l, C_h, [dst],#16
-	ldp	D_l, D_h, [src],#16
-	stp	D_l, D_h, [dst],#16
+        .macro ldp1 label, ptr, regB, regC, val
+        ldp \ptr, \regB, [\regC], \val
+        .endm
 
-	tst	count, #0x3f
-	b.ne	.Ltail63
-	ret
+        .macro stp1 label, ptr, regB, regC, val
+        stp \ptr, \regB, [\regC], \val
+        .endm
 
-	/*
-	* Critical loop.  Start at a new cache line boundary.  Assuming
-	* 64 bytes per line this ensures the entire loop is in one line.
-	*/
-	.p2align	L1_CACHE_SHIFT
-.Lcpy_body_large:
-	/* pre-get 64 bytes data. */
-	ldp	A_l, A_h, [src],#16
-	ldp	B_l, B_h, [src],#16
-	ldp	C_l, C_h, [src],#16
-	ldp	D_l, D_h, [src],#16
-1:
-	/*
-	* interlace the load of next 64 bytes data block with store of the last
-	* loaded 64 bytes data.
-	*/
-	stp	A_l, A_h, [dst],#16
-	ldp	A_l, A_h, [src],#16
-	stp	B_l, B_h, [dst],#16
-	ldp	B_l, B_h, [src],#16
-	stp	C_l, C_h, [dst],#16
-	ldp	C_l, C_h, [src],#16
-	stp	D_l, D_h, [dst],#16
-	ldp	D_l, D_h, [src],#16
-	subs	count, count, #64
-	b.ge	1b
-	stp	A_l, A_h, [dst],#16
-	stp	B_l, B_h, [dst],#16
-	stp	C_l, C_h, [dst],#16
-	stp	D_l, D_h, [dst],#16
-
-	tst	count, #0x3f
-	b.ne	.Ltail63
+ENTRY(memcpy)
+#include "copy_template.S"
 	ret
 ENDPROC(memcpy)
-- 
1.9.1



From petr.cvek at tul.cz  Fri Aug 21 15:09:10 2015
From: petr.cvek at tul.cz (Petr Cvek)
Date: Sat, 22 Aug 2015 00:09:10 +0200
Subject: [PATCH v2 09/21] ARM: pxa: magician: Add OV9640 camera support
In-Reply-To: <874mjs5yt2.fsf@belgarion.home>
References: <cover.1439843482.git.petr.cvek@tul.cz>
 <2889798.x6xcIzdYMU@wuerfel> <55D65722.9030508@tul.cz>
 <1634812.ZDaECJ9ClW@wuerfel> <874mjs5yt2.fsf@belgarion.home>
Message-ID: <55D7A186.4000505@tul.cz>

Dne 21.8.2015 v 19:36 Robert Jarzmik napsal(a):
> I shrunk a bit the mailing list.
> 
> Arnd Bergmann <arnd at arndb.de> writes:
> 
>> On Friday 21 August 2015 00:39:30 Petr Cvek wrote:
>>> Dne 20.8.2015 v 22:26 Arnd Bergmann napsal(a):
>>>> On Thursday 20 August 2015 21:48:20 Robert Jarzmik wrote:
>>>>> Petr Cvek <petr.cvek at tul.cz> writes:
>>> Datasheet says:
>>>
>>>         tS:RESET        Setting time after software/hardware reset      1 ms
>>>
>>> So at least one ~1 ms should be left there. Are msleep less than 20ms valid? 
>>>
>>> (checkpatch: msleep < 20ms  can sleep for up to 20ms)
>>
>> On most kernels, an msleep(1) will sleep somewhere between 1 and 3 milliseconds
>> (but could be much longer), while an mdelay(1) tries to sleep around one
>> millisecond, more or less.
> 
> I have rethought of that a bit more. I'm convinced a delay of "at least 1ms" is
> necessary according to the specification, it can also be more.
> 
> Moreover, I came to the conclusion this reset sequence is not something that is
> "magician" specific (see palmz72_camera_reset() in
> .../mach-pxa/palmz72.c). Actually it's not even mach-pxa specific, it's "ov9640"
> specific.
> 
> Now add this to the fact that it would be good to have a solution working for
> devicetree as well, and on any board, and the conclusion I came to was that this
> handling deserves to be in ov9640 driver (please correct me if I'm wrong).
> 
> The idea behind it is have the reset handled in ov9640, and the gpio provided by
> platform data or devicetree.
> 
> So Guennadi, is it possible to add a gpio through platform data to ov9640
> driver, does it make sense, and would you accept to have the reset handled there
> ? And if yes, would you, Petr, accept to revamp your patch to have the reset and
> power handled in ov9640 ?
> 

OK, why not, so power and reset gpio with polarity settings?

> Please note that it is a proposal, I'm not forcing anybody, I'd like to choose a
> path that agrees with the future push to remove as many machine files as possible.

Anyway I'm planning to send patch for OV9640 in future too (color correction matrix is not complete and some registers too).

> 
> Cheers.
> 



From sergei.shtylyov at cogentembedded.com  Fri Aug 21 15:18:09 2015
From: sergei.shtylyov at cogentembedded.com (Sergei Shtylyov)
Date: Sat, 22 Aug 2015 01:18:09 +0300
Subject: [PATCH v2] ARM: shmobile: silk: add SDHI1 DT support
In-Reply-To: <55D790A5.1050008@cogentembedded.com>
References: <10037494.4LD4T2QGPX@wasted.cogentembedded.com>
 <2757472.iuyUyRzJ3z@wasted.cogentembedded.com>
 <20150812012652.GH15957@verge.net.au> <55D790A5.1050008@cogentembedded.com>
Message-ID: <55D7A3A1.9020009@cogentembedded.com>

On 08/21/2015 11:57 PM, Sergei Shtylyov wrote:

>>> Define the SILK board dependent part of the SDHI1 (connected to micro-SD slot)
>>> device nodes along with the necessary voltage regulators.
>>>
>>> Based on the original patch by Vladimir Barinov
>>> <vladimir.barinov at cogentembedded.com>.
>>>
>>> Signed-off-by: Sergei Shtylyov <sergei.shtylyov at cogentembedded.com>
>>>
>>> ---
>>> This patch is against 'renesas-devel-20150810-v4.2-rc6' tag of Simon Horman's
>>> 'renesas.git' repo plus the R8A7794/SILK QSPI patches just re-posted. It needs
>>> the R8A7794 GPIO patches in order to compile.
>>>
>>> Changes in version 2:
>>> - removed not working SDHI0 stuff, renamed the patch;
>>> - replaced SDHI1's "wp-gpios" property with "disable-wp".
>>
>> I am wondering if you could explain the motivation for the "disable-wp"
>> update
>
>     Please see the comment in mmc_sd_get_ro().
>
>> and weather it is appropriate for other r8a779* dts files.
>
>     In case of micro-SD slots, yes.

    The MMC binding document says it should only be specified if the 
controller has WP detection logic. We, so far, seem to have been replying on 
the GPIOs despite this logic is present (according to the R-Car gen2 SDHI 
manuals I have). The driver will first call mmc_gpio_get_ro() and when that 
fails due to "wp-gpios" not being specified, it proceeds to reading the 
register but that is forbidden by TMIO_MMC_WRPROTECT_DISABLE flag set for the 
R-Car gen1/2 chips, so 0 is always returned from tmio_mmc_get_ro(). There 
seems to be no point in going that far (and doing the runtime PM dances) --
and MMC_CAP2_NO_WRITE_PROTECT (set when "disable-wp" is specified) prohibits 
doing that...

MBR, Sergei



From stefan at agner.ch  Fri Aug 21 15:56:42 2015
From: stefan at agner.ch (Stefan Agner)
Date: Fri, 21 Aug 2015 15:56:42 -0700
Subject: [PATCH] gpio: vf610: handle level IRQ's properly
Message-ID: <1440197802-29720-1-git-send-email-stefan@agner.ch>

The GPIO IRQ controller is able to generate level triggered
interrupts, however, these were handled by handle_simple_irq so far
which did not take care of IRQ masking. This lead to "nobody cared
(try booting with the "irqpoll" option)" stack traces.

Use the generic interrupt handlers depending on the IRQ type.

Signed-off-by: Stefan Agner <stefan at agner.ch>
---
 drivers/gpio/gpio-vf610.c | 9 ++++++++-
 1 file changed, 8 insertions(+), 1 deletion(-)

diff --git a/drivers/gpio/gpio-vf610.c b/drivers/gpio/gpio-vf610.c
index 7bd9f20..b6a0887 100644
--- a/drivers/gpio/gpio-vf610.c
+++ b/drivers/gpio/gpio-vf610.c
@@ -60,6 +60,8 @@ struct vf610_gpio_port {
 #define PORT_INT_EITHER_EDGE	0xb
 #define PORT_INT_LOGIC_ONE	0xc
 
+static struct irq_chip vf610_gpio_irq_chip;
+
 static const struct of_device_id vf610_gpio_dt_ids[] = {
 	{ .compatible = "fsl,vf610-gpio" },
 	{ /* sentinel */ }
@@ -173,6 +175,11 @@ static int vf610_gpio_irq_set_type(struct irq_data *d, u32 type)
 
 	port->irqc[d->hwirq] = irqc;
 
+	if (type & IRQ_TYPE_LEVEL_MASK)
+		__irq_set_handler_locked(d->irq, handle_level_irq);
+	else
+		__irq_set_handler_locked(d->irq, handle_edge_irq);
+
 	return 0;
 }
 
@@ -263,7 +270,7 @@ static int vf610_gpio_probe(struct platform_device *pdev)
 	vf610_gpio_writel(~0, port->base + PORT_ISFR);
 
 	ret = gpiochip_irqchip_add(gc, &vf610_gpio_irq_chip, 0,
-				   handle_simple_irq, IRQ_TYPE_NONE);
+				   handle_edge_irq, IRQ_TYPE_NONE);
 	if (ret) {
 		dev_err(dev, "failed to add irqchip\n");
 		gpiochip_remove(gc);
-- 
2.5.0



From f.fainelli at gmail.com  Fri Aug 21 16:27:23 2015
From: f.fainelli at gmail.com (Florian Fainelli)
Date: Fri, 21 Aug 2015 16:27:23 -0700
Subject: [GIT PULL] RPi DT changes due for v4.3
In-Reply-To: <20150813103056.GY30160@localhost>
References: <20150811160642.GQ18282@x1> <20150813103056.GY30160@localhost>
Message-ID: <55D7B3DB.8070405@gmail.com>

On 13/08/15 03:30, Olof Johansson wrote:
> Hi,
> 
> On Tue, Aug 11, 2015 at 05:06:42PM +0100, Lee Jones wrote:
>> ARM SoC Chaps,
>>
>> Please find a couple of simple RPi changes pertaining to Firmware.
>>
>> The following changes since commit bc0195aad0daa2ad5b0d76cce22b167bc3435590:
>>
>>   Linux 4.2-rc2 (2015-07-12 15:10:30 -0700)
>>
>> are available in the git repository at:
>>
>>   git://git.kernel.org/pub/scm/linux/kernel/git/rpi/linux-rpi.git tags/rpi-dt-for-armsoc-4.3
>>
>> for you to fetch changes up to fd26f8830979de48eb3f1c253eb9d2ee2e468eb6:
>>
>>   dt/bindings: Add binding for the Raspberry Pi firmware driver (2015-08-11 16:56:41 +0100)
> 
> I've merged this but I'm a little confused about bcm2835 maintainership:
> I got a MAINTAINERS update from Florian earlier grouped in a set of
> other bcm changes (adding Eric), and now this directly from you.
> 
> In general the bcm platforms are quite diverse and we've asked Florian
> to be the funnel for all of the new ones, but I don't think we talked
> much about 2835 at that time. Should we expect to see merges directly
> from you and the other maintainers there or will it go through Florian?
> 
> Either way is OK with me, just looking to clarify.

Could you merge this pull request directly? Eric and I met recently and
we agreed on a more formal process for the next submissions which will
be having me route the RPi changes through the Broadcom pull requests.

Thanks!
-- 
Florian


From olof at lixom.net  Fri Aug 21 16:32:47 2015
From: olof at lixom.net (Olof Johansson)
Date: Fri, 21 Aug 2015 16:32:47 -0700
Subject: [GIT PULL] RPi DT changes due for v4.3
In-Reply-To: <55D7B3DB.8070405@gmail.com>
References: <20150811160642.GQ18282@x1> <20150813103056.GY30160@localhost>
 <55D7B3DB.8070405@gmail.com>
Message-ID: <CAOesGMjpR01rLHpj5ZSJq6eze4wU8KDS3wBmZdqKOAJmH0U5UQ@mail.gmail.com>

On Fri, Aug 21, 2015 at 4:27 PM, Florian Fainelli <f.fainelli at gmail.com> wrote:
> On 13/08/15 03:30, Olof Johansson wrote:
>> Hi,
>>
>> On Tue, Aug 11, 2015 at 05:06:42PM +0100, Lee Jones wrote:
>>> ARM SoC Chaps,
>>>
>>> Please find a couple of simple RPi changes pertaining to Firmware.
>>>
>>> The following changes since commit bc0195aad0daa2ad5b0d76cce22b167bc3435590:
>>>
>>>   Linux 4.2-rc2 (2015-07-12 15:10:30 -0700)
>>>
>>> are available in the git repository at:
>>>
>>>   git://git.kernel.org/pub/scm/linux/kernel/git/rpi/linux-rpi.git tags/rpi-dt-for-armsoc-4.3
>>>
>>> for you to fetch changes up to fd26f8830979de48eb3f1c253eb9d2ee2e468eb6:
>>>
>>>   dt/bindings: Add binding for the Raspberry Pi firmware driver (2015-08-11 16:56:41 +0100)
>>
>> I've merged this but I'm a little confused about bcm2835 maintainership:
>> I got a MAINTAINERS update from Florian earlier grouped in a set of
>> other bcm changes (adding Eric), and now this directly from you.
>>
>> In general the bcm platforms are quite diverse and we've asked Florian
>> to be the funnel for all of the new ones, but I don't think we talked
>> much about 2835 at that time. Should we expect to see merges directly
>> from you and the other maintainers there or will it go through Florian?
>>
>> Either way is OK with me, just looking to clarify.
>
> Could you merge this pull request directly? Eric and I met recently and
> we agreed on a more formal process for the next submissions which will
> be having me route the RPi changes through the Broadcom pull requests.

Yeah, as I said above I merged it already, I was just looking for clarification.

Merging through you sounds like a good way forward, and keeps the brcm
platforms consistent.


Thanks!

-Olof


From fugang.duan at freescale.com  Fri Aug 21 16:48:10 2015
From: fugang.duan at freescale.com (Duan Andy)
Date: Fri, 21 Aug 2015 23:48:10 +0000
Subject: [PATCH v1 0/6] Add fec1 and fec2 support for i.MX7d sdb board
In-Reply-To: <55D64330.4020503@gmail.com>
References: <1439962444-27486-1-git-send-email-b38611@freescale.com>
 <20150820.140531.1320709021949935376.davem@davemloft.net>
 <55D64330.4020503@gmail.com>
Message-ID: <BN3PR0301MB1219287CCC621469BA444143F5650@BN3PR0301MB1219.namprd03.prod.outlook.com>

From: Florian Fainelli <f.fainelli at gmail.com>
> Sent: Friday, August 21, 2015 5:14 AM
> To: David Miller; Duan Fugang-B38611
> Cc: netdev at vger.kernel.org; shawnguo at kernel.org; linux-arm-
> kernel at lists.infradead.org
> Subject: Re: [PATCH v1 0/6] Add fec1 and fec2 support for i.MX7d sdb
> board
> 
> On 20/08/15 14:05, David Miller wrote:
> > From: Fugang Duan <b38611 at freescale.com>
> > Date: Wed, 19 Aug 2015 13:33:58 +0800
> >
> >> The patch series is to add fec support for i.MX7d sdb board. Since
> >> i.MX7d fec ip is the same as i.MX6SX, so there have no change for
> driver itself.
> >>
> >> Patch#1: add bcm54220 PHY ID entry into brcmphy.h file.
> >
> > This is completely, and utterly, pointless.
> >
> > The only reason a PHY ID should be defined in brcmphy.h is so that it
> > can be used in the broadcom.c PHY driver or similar.
> >
> > If there is no user in the tree, there is no reason to add it to the
> > header file.
> 
> There is a valid reason for which you may have a PHY id, which is
> defining a PHY fixup in your platform code like Andy is doing, however,
> this should not be used in conjunction with the Generic PHY driver,
> because this driver has absolutely no clue about your PHY fixup, and this
> could create at best inconsistencies in how the fixup is managed later on.
> 
> At the very least, I would like to see a change to
> drivers/net/phy/broadcom.c which identifies this PHY id, and eventually
> just invokes the genphy_* functions where relevant.
> --
> Florian

I will try to add the phy support in Broadcom phy driver. Thanks for your comments.

Regards,
Andy

From fugang.duan at freescale.com  Fri Aug 21 16:49:41 2015
From: fugang.duan at freescale.com (Duan Andy)
Date: Fri, 21 Aug 2015 23:49:41 +0000
Subject: [PATCH v1 0/6] Add fec1 and fec2 support for i.MX7d sdb board
In-Reply-To: <20150820.140531.1320709021949935376.davem@davemloft.net>
References: <1439962444-27486-1-git-send-email-b38611@freescale.com>
 <20150820.140531.1320709021949935376.davem@davemloft.net>
Message-ID: <BN3PR0301MB1219615039D291CCCD751B2EF5650@BN3PR0301MB1219.namprd03.prod.outlook.com>

From: David Miller <davem at davemloft.net> Sent: Friday, August 21, 2015 5:06 AM
> To: Duan Fugang-B38611
> Cc: shawnguo at kernel.org; linux-arm-kernel at lists.infradead.org;
> netdev at vger.kernel.org
> Subject: Re: [PATCH v1 0/6] Add fec1 and fec2 support for i.MX7d sdb
> board
> 
> From: Fugang Duan <b38611 at freescale.com>
> Date: Wed, 19 Aug 2015 13:33:58 +0800
> 
> > The patch series is to add fec support for i.MX7d sdb board. Since
> > i.MX7d fec ip is the same as i.MX6SX, so there have no change for
> driver itself.
> >
> > Patch#1: add bcm54220 PHY ID entry into brcmphy.h file.
> 
> This is completely, and utterly, pointless.
> 
> The only reason a PHY ID should be defined in brcmphy.h is so that it can
> be used in the broadcom.c PHY driver or similar.
> 
> If there is no user in the tree, there is no reason to add it to the
> header file.

Ok, I will try to add the phy support in Broadcom phy driver. Thanks for your comment.

Regards,
Andy


From chunfeng.yun at mediatek.com  Fri Aug 21 18:45:08 2015
From: chunfeng.yun at mediatek.com (Chunfeng Yun)
Date: Sat, 22 Aug 2015 09:45:08 +0800
Subject: [PATCH v6 2/5] dt-bindings: Add a binding for Mediatek xHCI host
 controller
In-Reply-To: <1440207911-17666-1-git-send-email-chunfeng.yun@mediatek.com>
References: <1440207911-17666-1-git-send-email-chunfeng.yun@mediatek.com>
Message-ID: <1440207911-17666-3-git-send-email-chunfeng.yun@mediatek.com>

add a DT binding documentation of xHCI host controller for the
MT8173 SoC from Mediatek.

Signed-off-by: Chunfeng Yun <chunfeng.yun at mediatek.com>
---
 .../devicetree/bindings/usb/mt8173-xhci.txt        | 52 ++++++++++++++++++++++
 1 file changed, 52 insertions(+)
 create mode 100644 Documentation/devicetree/bindings/usb/mt8173-xhci.txt

diff --git a/Documentation/devicetree/bindings/usb/mt8173-xhci.txt b/Documentation/devicetree/bindings/usb/mt8173-xhci.txt
new file mode 100644
index 0000000..8e6e463
--- /dev/null
+++ b/Documentation/devicetree/bindings/usb/mt8173-xhci.txt
@@ -0,0 +1,52 @@
+mt65XX xHCI
+
+The device node for Mediatek SOC usb3.0 host controller
+
+Required properties:
+ - compatible : should contain "mediatek,mt8173-xhci"
+ - reg : specifies physical base address and size of the registers,
+	the first one for MAC, the second for IPPC
+ - interrupts : interrupt used by the controller
+ - power-domains : a phandle to USB power domain node to control usb's
+	mtcmos
+ - vusb33-supply : regulator of usb avdd3.3v
+
+ - clocks : a list of phandle + clock-specifier pairs, one for each
+	entry in clock-names
+ - clock-names : must contain
+	"sys_ck": for clock of xHCI MAC
+	"wakeup_deb_p0": for usb wakeup debounce clock of port0
+	"wakeup_deb_p0": for usb wakeup debounce clock of port1
+
+ - phys : a list of phandle + phy specifier pairs
+ - usb3-lpm-capable : supports USB3 LPM
+ - mediatek,syscon-wakeup : phandle to syscon used to access usb wakeup
+	control register
+ - mediatek,wakeup-src : 1: ip sleep wakeup mode; 2: line state wakeup
+	mode; others means don't enable wakeup source of usb
+
+Optional properties:
+ - vbus-supply : Reference to the VBUS regulator;
+
+Example:
+usb30: usb at 11270000 {
+	compatible = "mediatek,mt8173-xhci";
+	reg = <0 0x11270000 0 0x4000>,
+	      <0 0x11280000 0 0x0800>;
+	interrupts = <GIC_SPI 115 IRQ_TYPE_LEVEL_LOW>;
+	power-domains = <&scpsys MT8173_POWER_DOMAIN_USB>;
+	clocks = <&topckgen CLK_TOP_USB30_SEL>,
+		 <&pericfg CLK_PERI_USB0>,
+		 <&pericfg CLK_PERI_USB1>;
+	clock-names = "sys_ck",
+		      "wakeup_deb_p0",
+		      "wakeup_deb_p1";
+	phys = <&phy_port0 PHY_TYPE_USB3>,
+	       <&phy_port1 PHY_TYPE_USB2>;
+	vusb33-supply = <&mt6397_vusb_reg>;
+	vbus-supply = <&usb_p1_vbus>;
+	usb3-lpm-capable;
+	mediatek,syscon-wakeup = <&pericfg>;
+	mediatek,wakeup-src = <1>;
+	status = "okay";
+};
-- 
1.8.1.1.dirty



From chunfeng.yun at mediatek.com  Fri Aug 21 18:45:10 2015
From: chunfeng.yun at mediatek.com (Chunfeng Yun)
Date: Sat, 22 Aug 2015 09:45:10 +0800
Subject: [PATCH v6 4/5] xhci: mediatek: support MTK xHCI host controller
In-Reply-To: <1440207911-17666-1-git-send-email-chunfeng.yun@mediatek.com>
References: <1440207911-17666-1-git-send-email-chunfeng.yun@mediatek.com>
Message-ID: <1440207911-17666-5-git-send-email-chunfeng.yun@mediatek.com>

MTK xhci host controller defines some extra SW scheduling
parameters for HW to minimize the scheduling effort for
synchronous and interrupt endpoints. The parameters are
put into reseved DWs of slot context and endpoint context

Signed-off-by: Chunfeng Yun <chunfeng.yun at mediatek.com>
---
 drivers/usb/host/Kconfig        |   9 +
 drivers/usb/host/Makefile       |   4 +
 drivers/usb/host/xhci-mtk-sch.c | 436 +++++++++++++++++++++
 drivers/usb/host/xhci-mtk.c     | 831 ++++++++++++++++++++++++++++++++++++++++
 drivers/usb/host/xhci-mtk.h     | 133 +++++++
 drivers/usb/host/xhci-ring.c    |  35 +-
 drivers/usb/host/xhci.c         |  19 +-
 drivers/usb/host/xhci.h         |   1 +
 8 files changed, 1461 insertions(+), 7 deletions(-)
 create mode 100644 drivers/usb/host/xhci-mtk-sch.c
 create mode 100644 drivers/usb/host/xhci-mtk.c
 create mode 100644 drivers/usb/host/xhci-mtk.h

diff --git a/drivers/usb/host/Kconfig b/drivers/usb/host/Kconfig
index 8afc3c1..358ab6d 100644
--- a/drivers/usb/host/Kconfig
+++ b/drivers/usb/host/Kconfig
@@ -34,6 +34,15 @@ config USB_XHCI_PCI
 config USB_XHCI_PLATFORM
 	tristate
 
+config USB_XHCI_MTK
+	tristate "xHCI support for Mediatek MT65xx"
+	select MFD_SYSCON
+	depends on ARCH_MEDIATEK || COMPILE_TEST
+	---help---
+	  Say 'Y' to enable the support for the xHCI host controller
+	  found in Mediatek MT65xx SoCs.
+	  If unsure, say N.
+
 config USB_XHCI_MVEBU
 	tristate "xHCI support for Marvell Armada 375/38x"
 	select USB_XHCI_PLATFORM
diff --git a/drivers/usb/host/Makefile b/drivers/usb/host/Makefile
index 754efaa..00401f9 100644
--- a/drivers/usb/host/Makefile
+++ b/drivers/usb/host/Makefile
@@ -13,6 +13,9 @@ fhci-$(CONFIG_FHCI_DEBUG) += fhci-dbg.o
 xhci-hcd-y := xhci.o xhci-mem.o
 xhci-hcd-y += xhci-ring.o xhci-hub.o xhci-dbg.o
 xhci-hcd-y += xhci-trace.o
+ifneq ($(CONFIG_USB_XHCI_MTK), )
+	xhci-hcd-y += xhci-mtk-sch.o
+endif
 
 xhci-plat-hcd-y := xhci-plat.o
 ifneq ($(CONFIG_USB_XHCI_MVEBU), )
@@ -30,6 +33,7 @@ endif
 
 obj-$(CONFIG_USB_XHCI_PCI)	+= xhci-pci.o
 obj-$(CONFIG_USB_XHCI_PLATFORM) += xhci-plat-hcd.o
+obj-$(CONFIG_USB_XHCI_MTK)	+= xhci-mtk.o
 
 obj-$(CONFIG_USB_EHCI_HCD)	+= ehci-hcd.o
 obj-$(CONFIG_USB_EHCI_PCI)	+= ehci-pci.o
diff --git a/drivers/usb/host/xhci-mtk-sch.c b/drivers/usb/host/xhci-mtk-sch.c
new file mode 100644
index 0000000..d4b41a6
--- /dev/null
+++ b/drivers/usb/host/xhci-mtk-sch.c
@@ -0,0 +1,436 @@
+/*
+ * Copyright (c) 2015 MediaTek Inc.
+ * Author:
+ *  Zhigang.Wei <zhigang.wei at mediatek.com>
+ *  Chunfeng.Yun <chunfeng.yun at mediatek.com>
+ *
+ * This software is licensed under the terms of the GNU General Public
+ * License version 2, as published by the Free Software Foundation, and
+ * may be copied, distributed, and modified under those terms.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ * GNU General Public License for more details.
+ *
+ */
+
+#include <linux/kernel.h>
+#include <linux/module.h>
+#include <linux/slab.h>
+
+#include "xhci.h"
+#include "xhci-mtk.h"
+
+#define SS_BW_BOUNDARY	51000
+/* table 5-5. High-speed Isoc Transaction Limits in usb_20 spec */
+#define HS_BW_BOUNDARY	6144
+/* usb2 spec section11.18.1: at most 188 FS bytes per microframe */
+#define FS_PAYLOAD_MAX 188
+
+/* mtk scheduler bitmasks */
+#define EP_BPKTS(p)	((p) & 0x3f)
+#define EP_BCSCOUNT(p)	(((p) & 0x7) << 8)
+#define EP_BBM(p)	((p) << 11)
+#define EP_BOFFSET(p)	((p) & 0x3fff)
+#define EP_BREPEAT(p)	(((p) & 0x7fff) << 16)
+
+static int is_fs_or_ls(enum usb_device_speed speed)
+{
+	return speed == USB_SPEED_FULL || speed == USB_SPEED_LOW;
+}
+
+static int get_bw_index(struct xhci_hcd *xhci, struct usb_device *udev,
+	struct usb_host_endpoint *ep)
+{
+	int bw_index;
+	int port_id;
+	struct xhci_virt_device *virt_dev;
+
+	virt_dev = xhci->devs[udev->slot_id];
+	port_id = virt_dev->real_port;
+
+	if (udev->speed == USB_SPEED_SUPER) {
+		if (usb_endpoint_dir_out(&ep->desc))
+			bw_index = (port_id - 1) * 2;
+		else
+			bw_index = (port_id - 1) * 2 + 1;
+	} else {
+		bw_index = port_id + xhci->num_usb3_ports - 1;
+	}
+
+	return bw_index;
+}
+
+static void setup_sch_info(struct usb_device *udev,
+		struct xhci_ep_ctx *ep_ctx, struct mu3h_sch_ep_info *sch_ep)
+{
+	u32 ep_type;
+	u32 ep_interval;
+	u32 max_packet_size;
+	u32 max_burst;
+	u32 mult;
+	u32 esit_pkts;
+
+	ep_type = CTX_TO_EP_TYPE(le32_to_cpu(ep_ctx->ep_info2));
+	ep_interval = CTX_TO_EP_INTERVAL(le32_to_cpu(ep_ctx->ep_info));
+	max_packet_size = MAX_PACKET_DECODED(le32_to_cpu(ep_ctx->ep_info2));
+	max_burst = CTX_TO_MAX_BURST(le32_to_cpu(ep_ctx->ep_info2));
+	mult = CTX_TO_EP_MULT(le32_to_cpu(ep_ctx->ep_info));
+
+	sch_ep->ep_type = ep_type;
+	sch_ep->max_packet_size = max_packet_size;
+	sch_ep->esit = 1 << ep_interval;
+	sch_ep->offset = 0;
+	sch_ep->burst_mode = 0;
+
+	if (udev->speed == USB_SPEED_HIGH) {
+		sch_ep->cs_count = 0;
+		/*
+		 * usb_20 spec section5.9
+		 * a single microframe is enough for HS synchromous endpoints
+		 * in a interval
+		 */
+		sch_ep->num_budget_microframes = 1;
+		sch_ep->repeat = 0;
+		/*
+		 * xHCI spec section6.2.3.4
+		 * @max_busrt is the number of additional transactions
+		 * opportunities per microframe
+		 */
+		sch_ep->pkts = max_burst + 1;
+		sch_ep->bw_cost_per_microframe = max_packet_size * sch_ep->pkts;
+	} else if (udev->speed == USB_SPEED_SUPER) {
+		/* usb3_r1 spec section4.4.7 & 4.4.8 */
+		sch_ep->cs_count = 0;
+		esit_pkts = (mult + 1) * (max_burst + 1);
+		if (ep_type == INT_IN_EP || ep_type == INT_OUT_EP) {
+			sch_ep->pkts = esit_pkts;
+			sch_ep->num_budget_microframes = 1;
+			sch_ep->repeat = 0;
+		}
+
+		if (ep_type == ISOC_IN_EP || ep_type == ISOC_OUT_EP) {
+			if (esit_pkts <= sch_ep->esit)
+				sch_ep->pkts = 1;
+			else
+				sch_ep->pkts = roundup_pow_of_two(esit_pkts)
+					/ sch_ep->esit;
+
+			sch_ep->num_budget_microframes =
+				DIV_ROUND_UP(esit_pkts, sch_ep->pkts);
+
+			if (sch_ep->num_budget_microframes > 1)
+				sch_ep->repeat = 1;
+			else
+				sch_ep->repeat = 0;
+		}
+		sch_ep->bw_cost_per_microframe = max_packet_size * sch_ep->pkts;
+	} else if (is_fs_or_ls(udev->speed)) {
+		/*
+		 * usb_20 spec section11.18.4
+		 * assume worst cases
+		 */
+		sch_ep->repeat = 0;
+		sch_ep->pkts = 1; /* at most one packet for each microframe */
+		if (ep_type == INT_IN_EP || ep_type == INT_OUT_EP) {
+			sch_ep->cs_count = 3; /* at most need 3 CS*/
+			/* one for SS and one for budgeted transaction */
+			sch_ep->num_budget_microframes = sch_ep->cs_count + 2;
+			sch_ep->bw_cost_per_microframe = max_packet_size;
+		}
+		if (ep_type == ISOC_OUT_EP) {
+			/* must never schedule a cs ISOC OUT ep */
+			sch_ep->cs_count = 0;
+			/*
+			 * the best case FS budget assumes that 188 FS bytes
+			 * occur in each microframe
+			 */
+			sch_ep->num_budget_microframes = DIV_ROUND_UP(
+				sch_ep->max_packet_size, FS_PAYLOAD_MAX);
+			sch_ep->bw_cost_per_microframe = FS_PAYLOAD_MAX;
+		}
+		if (ep_type == ISOC_IN_EP) {
+			/* at most need additional two CS. */
+			sch_ep->cs_count = DIV_ROUND_UP(
+				sch_ep->max_packet_size, FS_PAYLOAD_MAX) + 2;
+			sch_ep->num_budget_microframes = sch_ep->cs_count + 2;
+			sch_ep->bw_cost_per_microframe = FS_PAYLOAD_MAX;
+		}
+	}
+}
+
+/* Get maximum bandwidth when we schedule at offset slot. */
+static u32 get_max_bw(struct mu3h_sch_bw_info *sch_bw,
+	struct mu3h_sch_ep_info *sch_ep, u32 offset)
+{
+	u32 num_esit;
+	u32 max_bw = 0;
+	int i;
+	int j;
+
+	num_esit = XHCI_MTK_MAX_ESIT / sch_ep->esit;
+	for (i = 0; i < num_esit; i++) {
+		u32 base = offset + i * sch_ep->esit;
+
+		for (j = 0; j < sch_ep->num_budget_microframes; j++) {
+			if (sch_bw->bus_bw[base + j] > max_bw)
+				max_bw = sch_bw->bus_bw[base + j];
+		}
+	}
+	return max_bw;
+}
+
+static void update_bus_bw(struct mu3h_sch_bw_info *sch_bw,
+	struct mu3h_sch_ep_info *sch_ep, int bw_cost)
+{
+	u32 num_esit;
+	u32 base;
+	int i;
+	int j;
+
+	num_esit = XHCI_MTK_MAX_ESIT / sch_ep->esit;
+	for (i = 0; i < num_esit; i++) {
+		base = sch_ep->offset + i * sch_ep->esit;
+		for (j = 0; j < sch_ep->num_budget_microframes; j++)
+			sch_bw->bus_bw[base + j] += bw_cost;
+	}
+}
+
+static int check_sch_bw(struct usb_device *udev,
+	struct mu3h_sch_bw_info *sch_bw, struct mu3h_sch_ep_info *sch_ep)
+{
+	u32 offset;
+	u32 esit;
+	u32 num_budget_microframes;
+	u32 min_bw;
+	u32 min_index;
+	u32 worst_bw;
+	u32 bw_boundary;
+
+	if (sch_ep->esit > XHCI_MTK_MAX_ESIT)
+		sch_ep->esit = XHCI_MTK_MAX_ESIT;
+
+	esit = sch_ep->esit;
+	num_budget_microframes = sch_ep->num_budget_microframes;
+
+	/*
+	 * Search through all possible schedule microframes.
+	 * and find a microframe where its worst bandwidth is minimum.
+	 */
+	min_bw = ~0;
+	min_index = 0;
+	for (offset = 0; offset < esit; offset++) {
+		if ((offset + num_budget_microframes) > sch_ep->esit)
+			break;
+		/*
+		 * usb_20 spec section11.18:
+		 * must never schedule Start-Split in Y6
+		 */
+		if (is_fs_or_ls(udev->speed) && (offset % 8 == 6))
+			continue;
+
+		worst_bw = get_max_bw(sch_bw, sch_ep, offset);
+		if (min_bw > worst_bw) {
+			min_bw = worst_bw;
+			min_index = offset;
+		}
+		if (min_bw == 0)
+			break;
+	}
+	sch_ep->offset = min_index;
+
+	bw_boundary = (udev->speed == USB_SPEED_SUPER)
+				? SS_BW_BOUNDARY : HS_BW_BOUNDARY;
+
+	/* check bandwidth */
+	if (min_bw + sch_ep->bw_cost_per_microframe > bw_boundary)
+		return -1;
+
+	/* update bus bandwidth info */
+	update_bus_bw(sch_bw, sch_ep, sch_ep->bw_cost_per_microframe);
+
+	return 0;
+}
+
+static bool need_bw_sch(struct usb_host_endpoint *ep,
+	enum usb_device_speed speed, int has_tt)
+{
+	/* only for periodic endpoints */
+	if (usb_endpoint_xfer_control(&ep->desc)
+		|| usb_endpoint_xfer_bulk(&ep->desc))
+		return false;
+	/*
+	 * for LS & FS periodic endpoints which its device don't attach
+	 * to TT are also ignored, root-hub will schedule them directly
+	 */
+	if (is_fs_or_ls(speed) && !has_tt)
+		return false;
+
+	return true;
+}
+
+int xhci_mtk_sch_init(struct xhci_hcd *xhci)
+{
+	struct usb_hcd *hcd = xhci_to_hcd(xhci);
+	struct device *dev = hcd->self.controller;
+	struct xhci_hcd_mtk *mtk = dev_get_drvdata(dev);
+	struct mu3h_sch_bw_info *sch_array;
+	int num_usb_bus;
+	int i;
+
+	/* ss IN and OUT are separated */
+	num_usb_bus = xhci->num_usb3_ports * 2 + xhci->num_usb2_ports;
+
+	sch_array = kcalloc(num_usb_bus, sizeof(*sch_array), GFP_KERNEL);
+	if (sch_array == NULL)
+		return -ENOMEM;
+
+	for (i = 0; i < num_usb_bus; i++)
+		INIT_LIST_HEAD(&sch_array[i].bw_ep_list);
+
+	mtk->sch_array = sch_array;
+
+	return 0;
+}
+EXPORT_SYMBOL_GPL(xhci_mtk_sch_init);
+
+void xhci_mtk_sch_exit(struct xhci_hcd *xhci)
+{
+	struct usb_hcd *hcd = xhci_to_hcd(xhci);
+	struct device *dev = hcd->self.controller;
+	struct xhci_hcd_mtk *mtk = dev_get_drvdata(dev);
+
+	kfree(mtk->sch_array);
+}
+EXPORT_SYMBOL_GPL(xhci_mtk_sch_exit);
+
+int xhci_mtk_add_ep_quirk(struct usb_hcd *hcd, struct usb_device *udev,
+		struct usb_host_endpoint *ep)
+{
+	struct device *dev = hcd->self.controller;
+	struct xhci_hcd_mtk *mtk = dev_get_drvdata(dev);
+
+	int ret = 0;
+	int port_id;
+	int bw_index;
+	struct xhci_hcd *xhci;
+	unsigned int ep_index;
+	struct xhci_ep_ctx *ep_ctx;
+	struct xhci_slot_ctx *slot_ctx;
+	struct xhci_virt_device *virt_dev;
+	struct mu3h_sch_bw_info *sch_bw;
+	struct mu3h_sch_ep_info *sch_ep;
+	struct mu3h_sch_bw_info *sch_array;
+
+	xhci = hcd_to_xhci(hcd);
+	virt_dev = xhci->devs[udev->slot_id];
+	ep_index = xhci_get_endpoint_index(&ep->desc);
+	slot_ctx = xhci_get_slot_ctx(xhci, virt_dev->in_ctx);
+	ep_ctx = xhci_get_ep_ctx(xhci, virt_dev->in_ctx, ep_index);
+	sch_array = mtk->sch_array;
+
+	port_id = virt_dev->real_port;
+	xhci_dbg(xhci, "%s() xfer_type: %d, speed:%d, ep:%p\n", __func__,
+		usb_endpoint_type(&ep->desc), udev->speed, ep);
+
+	if (!need_bw_sch(ep, udev->speed, slot_ctx->tt_info & TT_SLOT))
+		return 0;
+
+	bw_index = get_bw_index(xhci, udev, ep);
+	sch_bw = &sch_array[bw_index];
+
+	sch_ep = kzalloc(sizeof(struct mu3h_sch_ep_info), GFP_NOIO);
+	if (!sch_ep)
+		return -ENOMEM;
+
+	setup_sch_info(udev, ep_ctx, sch_ep);
+
+	ret = check_sch_bw(udev, sch_bw, sch_ep);
+	if (ret) {
+		xhci_err(xhci, "Not enough bandwidth!\n");
+		kfree(sch_ep);
+		return -ENOSPC;
+	}
+
+	list_add_tail(&sch_ep->endpoint, &sch_bw->bw_ep_list);
+	sch_ep->ep = ep;
+
+	ep_ctx->reserved[0] |= cpu_to_le32(EP_BPKTS(sch_ep->pkts)
+		| EP_BCSCOUNT(sch_ep->cs_count) | EP_BBM(sch_ep->burst_mode));
+	ep_ctx->reserved[1] |= cpu_to_le32(EP_BOFFSET(sch_ep->offset)
+		| EP_BREPEAT(sch_ep->repeat));
+
+	return 0;
+}
+EXPORT_SYMBOL_GPL(xhci_mtk_add_ep_quirk);
+
+void xhci_mtk_drop_ep_quirk(struct usb_hcd *hcd, struct usb_device *udev,
+		struct usb_host_endpoint *ep)
+{
+	struct device *dev = hcd->self.controller;
+	struct xhci_hcd_mtk *mtk = dev_get_drvdata(dev);
+
+	int bw_index;
+	struct xhci_hcd *xhci;
+	struct xhci_slot_ctx *slot_ctx;
+	struct xhci_virt_device *virt_dev;
+	struct mu3h_sch_bw_info *sch_array;
+	struct mu3h_sch_bw_info *sch_bw;
+	struct mu3h_sch_ep_info *sch_ep;
+
+	xhci = hcd_to_xhci(hcd);
+	virt_dev = xhci->devs[udev->slot_id];
+	slot_ctx = xhci_get_slot_ctx(xhci, virt_dev->in_ctx);
+	sch_array = mtk->sch_array;
+
+	xhci_dbg(xhci, "%s() xfer_type: %d, speed:%d, ep:%p\n", __func__,
+		usb_endpoint_type(&ep->desc), udev->speed, ep);
+
+	if (!need_bw_sch(ep, udev->speed, slot_ctx->tt_info & TT_SLOT))
+		return;
+
+	bw_index = get_bw_index(xhci, udev, ep);
+	sch_bw = &sch_array[bw_index];
+
+	list_for_each_entry(sch_ep, &sch_bw->bw_ep_list, endpoint) {
+		if (sch_ep->ep == ep) {
+			update_bus_bw(sch_bw, sch_ep,
+				-sch_ep->bw_cost_per_microframe);
+			list_del(&sch_ep->endpoint);
+			kfree(sch_ep);
+			break;
+		}
+	}
+}
+EXPORT_SYMBOL_GPL(xhci_mtk_drop_ep_quirk);
+
+/*
+ * The TD size is the number of max packet sized packets remaining in the TD
+ * (including this TRB), right shifted by 10.
+ * It must fit in bits 21:17, so it can't be bigger than 31.
+ */
+u32 xhci_mtk_td_remainder_quirk(unsigned int td_running_total,
+	unsigned trb_buffer_length, struct urb *urb)
+{
+	u32 max = 31;
+	int remainder, td_packet_count, packet_transferred;
+	unsigned int td_transfer_size = urb->transfer_buffer_length;
+	unsigned int maxp;
+
+	maxp = GET_MAX_PACKET(usb_endpoint_maxp(&urb->ep->desc));
+
+	/* 0 for the last TRB */
+	if (td_running_total + trb_buffer_length == td_transfer_size)
+		return 0;
+
+	packet_transferred = td_running_total / maxp;
+	td_packet_count = DIV_ROUND_UP(td_transfer_size, maxp);
+	remainder = td_packet_count - packet_transferred;
+
+	if (remainder > max)
+		return max << 17;
+	else
+		return remainder << 17;
+}
+EXPORT_SYMBOL_GPL(xhci_mtk_td_remainder_quirk);
diff --git a/drivers/usb/host/xhci-mtk.c b/drivers/usb/host/xhci-mtk.c
new file mode 100644
index 0000000..89c1417
--- /dev/null
+++ b/drivers/usb/host/xhci-mtk.c
@@ -0,0 +1,831 @@
+/*
+ * Copyright (c) 2015 MediaTek Inc.
+ * Author:
+ *  Chunfeng Yun <chunfeng.yun at mediatek.com>
+ *
+ * This software is licensed under the terms of the GNU General Public
+ * License version 2, as published by the Free Software Foundation, and
+ * may be copied, distributed, and modified under those terms.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ * GNU General Public License for more details.
+ *
+ */
+
+#include <linux/clk.h>
+#include <linux/dma-mapping.h>
+#include <linux/iopoll.h>
+#include <linux/kernel.h>
+#include <linux/mfd/syscon.h>
+#include <linux/module.h>
+#include <linux/of.h>
+#include <linux/phy/phy.h>
+#include <linux/platform_device.h>
+#include <linux/pm_runtime.h>
+#include <linux/regmap.h>
+#include <linux/regulator/consumer.h>
+#include <linux/slab.h>
+#include <linux/usb/phy.h>
+#include <linux/usb/xhci_pdriver.h>
+
+#include "xhci.h"
+#include "xhci-mtk.h"
+
+#define SSUSB_USB3_MAC_CSR_BASE	(0x2400)
+#define SSUSB_USB3_SYS_CSR_BASE	(0x2400)
+#define SSUSB_USB2_CSR_BASE	(0x3400)
+
+#define SSUSB_SIFSLV_IPPC_BASE	(0x700)
+
+#define U3P_UX_EXIT_LFPS_PARAM	(SSUSB_USB3_MAC_CSR_BASE + 0x00A0)
+#define RX_UX_EXIT_REF		(0xff << 8)
+#define RX_UX_EXIT_REF_VAL	(0x3 << 8)
+
+#define U3P_REF_CLK_PARAM	(SSUSB_USB3_MAC_CSR_BASE + 0x00B0)
+#define REF_CLK_1000NS		(0xff << 0)
+#define REF_CLK_VAL_DEF		(0xa << 0)
+
+#define U3P_LINK_PM_TIMER	(SSUSB_USB3_SYS_CSR_BASE + 0x0208)
+#define PM_LC_TIMEOUT		(0xf << 0)
+#define PM_LC_TIMEOUT_VAL	(0x3 << 0)
+
+#define U3P_TIMING_PULSE_CTRL	(SSUSB_USB3_SYS_CSR_BASE + 0x02B4)
+#define U3T_CNT_1US			(0xff << 0)
+#define U3T_CNT_1US_VAL		(0x3f << 0)	/* 62.5MHz: 63 */
+
+#define U3P_U2_TIMING_PARAM	(SSUSB_USB2_CSR_BASE + 0x0040)
+#define U2T_VAL_1US		(0xff << 0)
+#define U2T_VAL_1US_VAL	(0x3f << 0)	/* 62.5MHz: 63 */
+
+#define U3P_IP_PW_CTRL0	(SSUSB_SIFSLV_IPPC_BASE + 0x0000)
+#define CTRL0_IP_SW_RST	BIT(0)
+
+#define U3P_IP_PW_CTRL1	(SSUSB_SIFSLV_IPPC_BASE + 0x0004)
+#define CTRL1_IP_HOST_PDN	BIT(0)
+
+#define U3P_IP_PW_CTRL2	(SSUSB_SIFSLV_IPPC_BASE + 0x0008)
+#define CTRL2_IP_DEV_PDN	BIT(0)
+
+#define U3P_IP_PW_STS1	(SSUSB_SIFSLV_IPPC_BASE + 0x0010)
+#define STS1_IP_SLEEP_STS	BIT(30)
+#define STS1_U3_MAC_RST	BIT(16)
+#define STS1_SYS125_RST	BIT(10)
+#define STS1_REF_RST		BIT(8)
+#define STS1_SYSPLL_STABLE	BIT(0)
+
+#define U3P_IP_PW_STS2	(SSUSB_SIFSLV_IPPC_BASE + 0x0014)
+#define STS2_U2_MAC_RST	BIT(0)
+
+#define U3P_IP_XHCI_CAP	(SSUSB_SIFSLV_IPPC_BASE + 0x0024)
+#define CAP_U3_PORT_NUM(p)	((p) & 0xff)
+#define CAP_U2_PORT_NUM(p)	(((p) >> 8) & 0xff)
+
+#define U3P_U3_CTRL_0P	(SSUSB_SIFSLV_IPPC_BASE + 0x0030)
+#define CTRL_U3_PORT_HOST_SEL	BIT(2)
+#define CTRL_U3_PORT_PDN	BIT(1)
+#define CTRL_U3_PORT_DIS	BIT(0)
+
+#define U3P_U2_CTRL_0P	(SSUSB_SIFSLV_IPPC_BASE + 0x0050)
+#define CTRL_U2_PORT_HOST_SEL	BIT(2)
+#define CTRL_U2_PORT_PDN	BIT(1)
+#define CTRL_U2_PORT_DIS	BIT(0)
+
+#define U3P_U2_PHY_PLL	(SSUSB_SIFSLV_IPPC_BASE+0x007c)
+#define CTRL_U2_FORCE_PLL_STB	(0x1<<28)
+
+#define U3P_U3_CTRL(p)	(U3P_U3_CTRL_0P + ((p) * 0x08))
+#define U3P_U2_CTRL(p)	(U3P_U2_CTRL_0P + ((p) * 0x08))
+
+#define PERI_WK_CTRL0		0x400
+#define UWK_CTR0_0P_LS_PE	BIT(8)  /* posedge */
+#define UWK_CTR0_0P_LS_NE	BIT(7)  /* negedge for 0p linestate*/
+#define UWK_CTL1_1P_LS_C(x)	(((x) & 0xf) << 1)
+#define UWK_CTL1_1P_LS_E	BIT(0)
+
+#define PERI_WK_CTRL1		0x404
+#define UWK_CTL1_IS_C(x)	(((x) & 0xf) << 26)
+#define UWK_CTL1_IS_E		BIT(25)
+#define UWK_CTL1_0P_LS_C(x)	(((x) & 0xf) << 21)
+#define UWK_CTL1_0P_LS_E	BIT(20)
+#define UWK_CTL1_IDDIG_C(x)	(((x) & 0xf) << 11)  /* cycle debounce */
+#define UWK_CTL1_IDDIG_E	BIT(10) /* enable debounce */
+#define UWK_CTL1_IDDIG_P	BIT(9)  /* polarity */
+#define UWK_CTL1_0P_LS_P	BIT(7)
+#define UWK_CTL1_IS_P		BIT(6)  /* polarity for ip sleep */
+
+enum ssusb_wakeup_src {
+	SSUSB_WK_IP_SLEEP = 1,
+	SSUSB_WK_LINE_STATE = 2,
+};
+
+static int check_ip_clk_status(struct xhci_hcd_mtk *mtk)
+{
+	int ret;
+	int u3_port_num;
+	int u2_port_num;
+	u32 xhci_cap;
+	u32 val;
+	void __iomem *ippc_base = mtk->ippc_base;
+
+	xhci_cap = readl(ippc_base + U3P_IP_XHCI_CAP);
+	u3_port_num = CAP_U3_PORT_NUM(xhci_cap);
+	u2_port_num = CAP_U2_PORT_NUM(xhci_cap);
+
+	ret = readl_poll_timeout(ippc_base + U3P_IP_PW_STS1, val,
+			  (val & STS1_SYSPLL_STABLE), 100, 10000);
+	if (ret) {
+		dev_err(mtk->dev, "syspll is not stable!!!\n");
+		return ret;
+	}
+
+	ret = readl_poll_timeout(ippc_base + U3P_IP_PW_STS1, val,
+			  (val & STS1_REF_RST), 100, 10000);
+	if (ret) {
+		dev_err(mtk->dev, "ref_clk is still active!!!\n");
+		return ret;
+	}
+
+	ret = readl_poll_timeout(ippc_base + U3P_IP_PW_STS1, val,
+			   (val & STS1_SYS125_RST), 100, 10000);
+	if (ret) {
+		dev_err(mtk->dev, "sys125_ck is still active!!!\n");
+		return ret;
+	}
+
+	if (u3_port_num) {
+		ret = readl_poll_timeout(ippc_base + U3P_IP_PW_STS1, val,
+				   (val & STS1_U3_MAC_RST), 100, 10000);
+		if (ret) {
+			dev_err(mtk->dev, "mac3_mac_ck is still active!!!\n");
+			return ret;
+		}
+	}
+
+	if (u2_port_num) {
+		ret = readl_poll_timeout(ippc_base + U3P_IP_PW_STS2, val,
+				   (val & STS2_U2_MAC_RST), 100, 10000);
+		if (ret) {
+			dev_err(mtk->dev, "mac2_sys_ck is still active!!!\n");
+			return ret;
+		}
+	}
+
+	return 0;
+}
+
+static int xhci_mtk_ports_enable(struct xhci_hcd_mtk *mtk)
+{
+	int i;
+	u32 temp;
+	int u3_port_num;
+	int u2_port_num;
+	void __iomem *ippc_base = mtk->ippc_base;
+
+	temp = readl(ippc_base + U3P_IP_XHCI_CAP);
+	u3_port_num = CAP_U3_PORT_NUM(temp);
+	u2_port_num = CAP_U2_PORT_NUM(temp);
+	dev_dbg(mtk->dev, "%s u2p:%d, u3p:%d\n", __func__,
+			u2_port_num, u3_port_num);
+
+	/* power on host ip */
+	temp = readl(ippc_base + U3P_IP_PW_CTRL1);
+	temp &= ~CTRL1_IP_HOST_PDN;
+	writel(temp, ippc_base + U3P_IP_PW_CTRL1);
+
+	/* power on and enable all u3 ports */
+	for (i = 0; i < u3_port_num; i++) {
+		temp = readl(ippc_base + U3P_U3_CTRL(i));
+		temp &= ~(CTRL_U3_PORT_PDN | CTRL_U3_PORT_DIS);
+		temp |= CTRL_U3_PORT_HOST_SEL;
+		writel(temp, ippc_base + U3P_U3_CTRL(i));
+	}
+
+	/* power on and enable all u2 ports */
+	for (i = 0; i < u2_port_num; i++) {
+		temp = readl(ippc_base + U3P_U2_CTRL(i));
+		temp &= ~(CTRL_U2_PORT_PDN | CTRL_U2_PORT_DIS);
+		temp |= CTRL_U2_PORT_HOST_SEL;
+		writel(temp, ippc_base + U3P_U2_CTRL(i));
+	}
+	return check_ip_clk_status(mtk);
+}
+
+static int xhci_mtk_ports_disable(struct xhci_hcd_mtk *mtk)
+{
+	int i;
+	u32 temp;
+	int ret;
+	int u3_port_num;
+	int u2_port_num;
+	void __iomem *ippc_base = mtk->ippc_base;
+
+	temp = readl(ippc_base + U3P_IP_XHCI_CAP);
+	u3_port_num = CAP_U3_PORT_NUM(temp);
+	u2_port_num = CAP_U2_PORT_NUM(temp);
+	dev_dbg(mtk->dev, "%s u2p:%d, u3p:%d\n", __func__,
+			u2_port_num, u3_port_num);
+
+	/* disable all u3 ports */
+	for (i = 0; i < u3_port_num; i++) {
+		temp = readl(ippc_base + U3P_U3_CTRL(i));
+		temp |= CTRL_U3_PORT_PDN;
+		writel(temp, ippc_base + U3P_U3_CTRL(i));
+	}
+
+	/* disable all u2 ports */
+	for (i = 0; i < u2_port_num; i++) {
+		temp = readl(ippc_base + U3P_U2_CTRL(i));
+		temp |= CTRL_U2_PORT_PDN;
+		writel(temp, ippc_base + U3P_U2_CTRL(i));
+	}
+
+	/* power off ip */
+	temp = readl(ippc_base + U3P_IP_PW_CTRL1);
+	temp |= CTRL1_IP_HOST_PDN;
+	writel(temp, ippc_base + U3P_IP_PW_CTRL1);
+
+	temp = readl(ippc_base + U3P_IP_PW_CTRL2);
+	temp |= CTRL2_IP_DEV_PDN;
+	writel(temp, ippc_base + U3P_IP_PW_CTRL2);
+
+	ret = readl_poll_timeout(ippc_base + U3P_IP_PW_STS1, temp,
+			  (temp & STS1_IP_SLEEP_STS), 100, 100000);
+	if (ret) {
+		dev_err(mtk->dev, "ip sleep failed!!!\n");
+		return ret;
+	}
+	return 0;
+}
+
+static void xhci_mtk_timing_init(struct xhci_hcd_mtk *mtk)
+{
+	void __iomem *mbase = mtk->mac_base;
+	int u3_port_num;
+	u32 temp;
+
+	temp = readl(mtk->ippc_base + U3P_IP_XHCI_CAP);
+	u3_port_num = CAP_U3_PORT_NUM(temp);
+
+	if (u3_port_num) {
+		/* set MAC reference clock speed */
+		temp = readl(mbase + U3P_UX_EXIT_LFPS_PARAM);
+		temp &= ~RX_UX_EXIT_REF;
+		temp |= RX_UX_EXIT_REF_VAL;
+		writel(temp, mbase + U3P_UX_EXIT_LFPS_PARAM);
+		/* set REF_CLK */
+		temp = readl(mbase + U3P_REF_CLK_PARAM);
+		temp &= ~REF_CLK_1000NS;
+		temp |= REF_CLK_VAL_DEF;
+		writel(temp, mbase + U3P_REF_CLK_PARAM);
+		/* set SYS_CLK */
+		temp = readl(mbase + U3P_TIMING_PULSE_CTRL);
+		temp &= ~U3T_CNT_1US;
+		temp |= U3T_CNT_1US_VAL;
+		writel(temp, mbase + U3P_TIMING_PULSE_CTRL);
+		/* set LINK_PM_TIMER=3 */
+		temp = readl(mbase + U3P_LINK_PM_TIMER);
+		temp &= ~PM_LC_TIMEOUT;
+		temp |= PM_LC_TIMEOUT_VAL;
+		writel(temp, mbase + U3P_LINK_PM_TIMER);
+	}
+
+	temp = readl(mbase + U3P_U2_TIMING_PARAM);
+	temp &= ~U2T_VAL_1US;
+	temp |= U2T_VAL_1US_VAL;
+	writel(temp, mbase + U3P_U2_TIMING_PARAM);
+}
+
+static void xhci_mtk_ports_config(struct xhci_hcd_mtk *mtk)
+{
+	u32 temp;
+
+	/* reset whole ip */
+	temp = readl(mtk->ippc_base + U3P_IP_PW_CTRL0);
+	temp |= CTRL0_IP_SW_RST;
+	writel(temp, mtk->ippc_base + U3P_IP_PW_CTRL0);
+	udelay(1);
+	temp = readl(mtk->ippc_base + U3P_IP_PW_CTRL0);
+	temp &= ~CTRL0_IP_SW_RST;
+	writel(temp, mtk->ippc_base + U3P_IP_PW_CTRL0);
+
+	xhci_mtk_ports_enable(mtk);
+	xhci_mtk_timing_init(mtk);
+}
+
+static int xhci_mtk_clks_enable(struct xhci_hcd_mtk *mtk)
+{
+	int ret;
+
+	ret = clk_prepare_enable(mtk->sys_mac);
+	if (ret) {
+		dev_err(mtk->dev, "failed to enable u3phya_ref\n");
+		goto u3phya_ref_err;
+	}
+	ret = clk_prepare_enable(mtk->wk_deb_p0);
+	if (ret) {
+		dev_err(mtk->dev, "failed to enable wk_deb_p0\n");
+		goto usb_p0_err;
+	}
+	if (mtk->num_phys > 1) {
+		ret = clk_prepare_enable(mtk->wk_deb_p1);
+		if (ret) {
+			dev_err(mtk->dev, "failed to enable wk_deb_p1\n");
+			goto usb_p1_err;
+		}
+	}
+
+	return 0;
+
+usb_p1_err:
+	clk_disable_unprepare(mtk->wk_deb_p0);
+usb_p0_err:
+	clk_disable_unprepare(mtk->sys_mac);
+u3phya_ref_err:
+	return -EINVAL;
+}
+
+static void xhci_mtk_clks_disable(struct xhci_hcd_mtk *mtk)
+{
+	if (mtk->num_phys > 1)
+		clk_disable_unprepare(mtk->wk_deb_p1);
+	clk_disable_unprepare(mtk->wk_deb_p0);
+	clk_disable_unprepare(mtk->sys_mac);
+}
+
+/* only clocks can be turn off for ip-sleep wakeup mode */
+static void usb_wakeup_ip_sleep_en(struct xhci_hcd_mtk *mtk)
+{
+	u32 tmp;
+	struct regmap *pericfg = mtk->pericfg;
+
+	regmap_read(pericfg, PERI_WK_CTRL1, &tmp);
+	tmp &= ~UWK_CTL1_IS_P;
+	tmp &= ~(UWK_CTL1_IS_C(0xf));
+	tmp |= UWK_CTL1_IS_C(0x8);
+	regmap_write(pericfg, PERI_WK_CTRL1, tmp);
+	regmap_write(pericfg, PERI_WK_CTRL1, tmp | UWK_CTL1_IS_E);
+
+	regmap_read(pericfg, PERI_WK_CTRL1, &tmp);
+	dev_dbg(mtk->dev, "%s(): WK_CTRL1[P6,E25,C26:29]=%#x\n",
+		__func__, tmp);
+}
+
+static void usb_wakeup_ip_sleep_dis(struct xhci_hcd_mtk *mtk)
+{
+	u32 tmp;
+
+	regmap_read(mtk->pericfg, PERI_WK_CTRL1, &tmp);
+	tmp &= ~UWK_CTL1_IS_E;
+	regmap_write(mtk->pericfg, PERI_WK_CTRL1, tmp);
+}
+
+/*
+* for line-state wakeup mode, phy's power should not power-down
+* and only support cable plug in/out
+*/
+static void usb_wakeup_line_state_en(struct xhci_hcd_mtk *mtk)
+{
+	u32 tmp;
+	struct regmap *pericfg = mtk->pericfg;
+
+	/* line-state of u2-port0 */
+	regmap_read(pericfg, PERI_WK_CTRL1, &tmp);
+	tmp &= ~UWK_CTL1_0P_LS_P;
+	tmp &= ~(UWK_CTL1_0P_LS_C(0xf));
+	tmp |= UWK_CTL1_0P_LS_C(0x8);
+	regmap_write(pericfg, PERI_WK_CTRL1, tmp);
+	regmap_read(pericfg, PERI_WK_CTRL1, &tmp);
+	regmap_write(pericfg, PERI_WK_CTRL1, tmp | UWK_CTL1_0P_LS_E);
+
+	/* line-state of u2-port1 if support */
+	if (mtk->num_phys > 1) {
+		regmap_read(pericfg, PERI_WK_CTRL0, &tmp);
+		tmp &= ~(UWK_CTL1_1P_LS_C(0xf));
+		tmp |= UWK_CTL1_1P_LS_C(0x8);
+		regmap_write(pericfg, PERI_WK_CTRL0, tmp);
+		regmap_write(pericfg, PERI_WK_CTRL0, tmp | UWK_CTL1_1P_LS_E);
+	}
+}
+
+static void usb_wakeup_line_state_dis(struct xhci_hcd_mtk *mtk)
+{
+	u32 tmp;
+	struct regmap *pericfg = mtk->pericfg;
+
+	regmap_read(pericfg, PERI_WK_CTRL1, &tmp);
+	tmp &= ~UWK_CTL1_0P_LS_E;
+	regmap_write(pericfg, PERI_WK_CTRL1, tmp);
+
+	if (mtk->num_phys > 1) {
+		regmap_read(pericfg, PERI_WK_CTRL0, &tmp);
+		tmp &= ~UWK_CTL1_1P_LS_E;
+		regmap_write(pericfg, PERI_WK_CTRL0, tmp);
+	}
+}
+
+static void usb_wakeup_enable(struct xhci_hcd_mtk *mtk)
+{
+	if (mtk->wakeup_src == SSUSB_WK_IP_SLEEP)
+		usb_wakeup_ip_sleep_en(mtk);
+	else if (mtk->wakeup_src == SSUSB_WK_LINE_STATE)
+		usb_wakeup_line_state_en(mtk);
+}
+
+static void usb_wakeup_disable(struct xhci_hcd_mtk *mtk)
+{
+	if (mtk->wakeup_src == SSUSB_WK_IP_SLEEP)
+		usb_wakeup_ip_sleep_dis(mtk);
+	else if (mtk->wakeup_src == SSUSB_WK_LINE_STATE)
+		usb_wakeup_line_state_dis(mtk);
+}
+
+
+static int xhci_mtk_setup(struct usb_hcd *hcd);
+static const struct xhci_driver_overrides xhci_mtk_overrides __initconst = {
+	.extra_priv_size = sizeof(struct xhci_hcd),
+	.reset = xhci_mtk_setup,
+};
+
+static struct hc_driver __read_mostly xhci_mtk_hc_driver;
+
+static int xhci_mtk_phy_enable(struct xhci_hcd_mtk *mtk)
+{
+	unsigned int i;
+	int ret;
+
+	for (i = 0; i < mtk->num_phys; i++) {
+		ret = phy_init(mtk->phys[i]);
+		if (ret)
+			goto disable_phy;
+		ret = phy_power_on(mtk->phys[i]);
+		if (ret) {
+			phy_exit(mtk->phys[i]);
+			goto disable_phy;
+		}
+	}
+
+	return 0;
+
+disable_phy:
+	for (; i > 0; i--) {
+		phy_power_off(mtk->phys[i - 1]);
+		phy_exit(mtk->phys[i - 1]);
+	}
+	return ret;
+}
+
+static void xhci_mtk_phy_disable(struct xhci_hcd_mtk *mtk)
+{
+	unsigned int i;
+
+	for (i = 0; i < mtk->num_phys; i++) {
+		phy_power_off(mtk->phys[i]);
+		phy_exit(mtk->phys[i]);
+	}
+}
+
+static int xhci_mtk_ldos_enable(struct xhci_hcd_mtk *mtk)
+{
+	int ret;
+
+	ret = regulator_enable(mtk->vbus);
+	if (ret) {
+		dev_err(mtk->dev, "failed to enable vbus\n");
+		return ret;
+	}
+
+	ret = regulator_enable(mtk->vusb33);
+	if (ret) {
+		dev_err(mtk->dev, "failed to enable vusb33\n");
+		regulator_disable(mtk->vbus);
+		return ret;
+	}
+	return 0;
+}
+
+static void xhci_mtk_ldos_disable(struct xhci_hcd_mtk *mtk)
+{
+	regulator_disable(mtk->vbus);
+	regulator_disable(mtk->vusb33);
+}
+
+static void xhci_mtk_quirks(struct device *dev, struct xhci_hcd *xhci)
+{
+	/*
+	 * As of now platform drivers don't provide MSI support so we ensure
+	 * here that the generic code does not try to make a pci_dev from our
+	 * dev struct in order to setup MSI
+	 */
+	xhci->quirks |= XHCI_PLAT;
+	xhci->quirks |= XHCI_MTK_HOST;
+	/*
+	 * MTK host controller gives a spurious successful event after a
+	 * short transfer. Ignore it.
+	 */
+	xhci->quirks |= XHCI_SPURIOUS_SUCCESS;
+}
+
+/* called during probe() after chip reset completes */
+static int xhci_mtk_setup(struct usb_hcd *hcd)
+{
+	struct xhci_hcd *xhci;
+	int ret;
+
+	ret = xhci_gen_setup(hcd, xhci_mtk_quirks);
+	if (ret)
+		return ret;
+
+	if (!usb_hcd_is_primary_hcd(hcd))
+		return 0;
+
+	xhci = hcd_to_xhci(hcd);
+	ret = xhci_mtk_sch_init(xhci);
+	if (ret) {
+		kfree(xhci);
+		return ret;
+	}
+
+	return ret;
+}
+
+
+static int xhci_mtk_probe(struct platform_device *pdev)
+{
+	struct device *dev = &pdev->dev;
+	struct device_node *node = dev->of_node;
+	struct usb_xhci_pdata *pdata = dev_get_platdata(dev);
+	struct xhci_hcd_mtk *mtk;
+	const struct hc_driver *driver;
+	struct xhci_hcd *xhci;
+	struct resource *res;
+	struct usb_hcd *hcd;
+	struct phy *phy;
+	int phy_num;
+	int ret = -ENODEV;
+	int irq;
+
+	if (usb_disabled())
+		return -ENODEV;
+
+	driver = &xhci_mtk_hc_driver;
+	mtk = devm_kzalloc(dev, sizeof(*mtk), GFP_KERNEL);
+	if (!mtk)
+		return -ENOMEM;
+
+	mtk->dev = dev;
+	mtk->vbus = devm_regulator_get(dev, "vbus");
+	if (IS_ERR(mtk->vbus)) {
+		dev_err(dev, "fail to get vbus\n");
+		return PTR_ERR(mtk->vbus);
+	}
+
+	mtk->vusb33 = devm_regulator_get(dev, "vusb33");
+	if (IS_ERR(mtk->vusb33)) {
+		dev_err(dev, "fail to get vusb33\n");
+		return PTR_ERR(mtk->vusb33);
+	}
+
+	mtk->sys_mac = devm_clk_get(dev, "sys_ck");
+	if (IS_ERR(mtk->sys_mac)) {
+		dev_err(dev, "fail to get sys_ck\n");
+		return PTR_ERR(mtk->sys_mac);
+	}
+
+	of_property_read_u32(node, "mediatek,wakeup-src", &mtk->wakeup_src);
+
+	mtk->wk_deb_p0 = devm_clk_get(dev, "wakeup_deb_p0");
+	if (IS_ERR(mtk->wk_deb_p0)) {
+		dev_err(dev, "fail to get wakeup_deb_p0\n");
+		return PTR_ERR(mtk->wk_deb_p0);
+	}
+
+	mtk->wk_deb_p1 = devm_clk_get(dev, "wakeup_deb_p1");
+	if (IS_ERR(mtk->wk_deb_p1)) {
+		dev_err(dev, "fail to get wakeup_deb_p1\n");
+		return PTR_ERR(mtk->wk_deb_p1);
+	}
+
+	mtk->pericfg = syscon_regmap_lookup_by_phandle(node,
+						"mediatek,syscon-wakeup");
+	if (IS_ERR(mtk->pericfg)) {
+		dev_err(dev, "fail to get pericfg regs\n");
+		return PTR_ERR(mtk->pericfg);
+	}
+
+	mtk->num_phys = of_count_phandle_with_args(node,
+			"phys", "#phy-cells");
+	if (mtk->num_phys > 0) {
+		mtk->phys = devm_kcalloc(dev, mtk->num_phys,
+					sizeof(*mtk->phys), GFP_KERNEL);
+		if (!mtk->phys)
+			return -ENOMEM;
+	} else {
+		mtk->num_phys = 0;
+	}
+	pm_runtime_enable(dev);
+	pm_runtime_get_sync(dev);
+
+	ret = xhci_mtk_ldos_enable(mtk);
+	if (ret)
+		goto disable_pm;
+
+	ret = xhci_mtk_clks_enable(mtk);
+	if (ret)
+		goto disable_ldos;
+
+	irq = platform_get_irq(pdev, 0);
+	if (irq < 0)
+		goto disable_clk;
+
+	/* Initialize dma_mask and coherent_dma_mask to 32-bits */
+	ret = dma_set_coherent_mask(dev, DMA_BIT_MASK(32));
+	if (ret)
+		goto disable_clk;
+
+	if (!dev->dma_mask)
+		dev->dma_mask = &dev->coherent_dma_mask;
+	else
+		dma_set_mask(dev, DMA_BIT_MASK(32));
+
+	hcd = usb_create_hcd(driver, dev, dev_name(dev));
+	if (!hcd) {
+		ret = -ENOMEM;
+		goto disable_clk;
+	}
+
+	/*
+	 * USB 2.0 roothub is stored in the platform_device.
+	 * Swap it with mtk HCD.
+	 */
+	mtk->hcd = platform_get_drvdata(pdev);
+	platform_set_drvdata(pdev, mtk);
+
+	res = platform_get_resource(pdev, IORESOURCE_MEM, 0);
+	hcd->regs = devm_ioremap_resource(dev, res);
+	if (IS_ERR(hcd->regs)) {
+		ret = PTR_ERR(hcd->regs);
+		goto put_usb2_hcd;
+	}
+	hcd->rsrc_start = res->start;
+	hcd->rsrc_len = resource_size(res);
+	mtk->mac_base = hcd->regs;
+
+	res = platform_get_resource(pdev, IORESOURCE_MEM, 1);
+	mtk->ippc_base = devm_ioremap_resource(dev, res);
+	if (IS_ERR(mtk->ippc_base)) {
+		ret = PTR_ERR(mtk->ippc_base);
+		goto put_usb2_hcd;
+	}
+
+	for (phy_num = 0; phy_num < mtk->num_phys; phy_num++) {
+		phy = devm_of_phy_get_by_index(dev, node, phy_num);
+		if (IS_ERR(phy)) {
+			ret = PTR_ERR(phy);
+			goto put_usb2_hcd;
+		}
+		mtk->phys[phy_num] = phy;
+	}
+
+	xhci_mtk_ports_config(mtk);
+	xhci_mtk_phy_enable(mtk);
+	device_init_wakeup(dev, 1);
+
+	xhci = hcd_to_xhci(hcd);
+	xhci->main_hcd = hcd;
+	xhci->shared_hcd = usb_create_shared_hcd(driver, dev,
+			dev_name(dev), hcd);
+	if (!xhci->shared_hcd) {
+		ret = -ENOMEM;
+		goto disable_usb_phy;
+	}
+
+	if ((node && of_property_read_bool(node, "usb3-lpm-capable")) ||
+			(pdata && pdata->usb3_lpm_capable))
+		xhci->quirks |= XHCI_LPM_SUPPORT;
+
+	if (HCC_MAX_PSA(xhci->hcc_params) >= 4)
+		xhci->shared_hcd->can_do_streams = 1;
+
+	ret = usb_add_hcd(hcd, irq, IRQF_SHARED);
+	if (ret)
+		goto put_usb3_hcd;
+
+	ret = usb_add_hcd(xhci->shared_hcd, irq, IRQF_SHARED);
+	if (ret)
+		goto dealloc_usb2_hcd;
+
+	return 0;
+
+dealloc_usb2_hcd:
+	usb_remove_hcd(hcd);
+
+put_usb3_hcd:
+	usb_put_hcd(xhci->shared_hcd);
+
+disable_usb_phy:
+	xhci_mtk_phy_disable(mtk);
+	device_init_wakeup(dev, 0);
+
+put_usb2_hcd:
+	usb_put_hcd(hcd);
+
+disable_clk:
+	xhci_mtk_clks_disable(mtk);
+
+disable_ldos:
+	xhci_mtk_ldos_disable(mtk);
+
+disable_pm:
+	pm_runtime_put_sync(dev);
+	pm_runtime_disable(dev);
+	return ret;
+}
+
+static int xhci_mtk_remove(struct platform_device *dev)
+{
+	struct xhci_hcd_mtk *mtk = platform_get_drvdata(dev);
+	struct usb_hcd	*hcd = mtk->hcd;
+	struct xhci_hcd	*xhci = hcd_to_xhci(hcd);
+
+	usb_remove_hcd(xhci->shared_hcd);
+	xhci_mtk_phy_disable(mtk);
+	device_init_wakeup(&dev->dev, 0);
+
+	usb_remove_hcd(hcd);
+	usb_put_hcd(xhci->shared_hcd);
+	usb_put_hcd(hcd);
+	xhci_mtk_sch_exit(xhci);
+	xhci_mtk_clks_disable(mtk);
+	xhci_mtk_ldos_disable(mtk);
+	pm_runtime_put_sync(&dev->dev);
+	pm_runtime_disable(&dev->dev);
+
+	return 0;
+}
+
+#ifdef CONFIG_PM_SLEEP
+static int xhci_mtk_suspend(struct device *dev)
+{
+	struct xhci_hcd_mtk *mtk = dev_get_drvdata(dev);
+
+	xhci_mtk_ports_disable(mtk);
+	xhci_mtk_phy_disable(mtk);
+	xhci_mtk_clks_disable(mtk);
+	usb_wakeup_enable(mtk);
+	return 0;
+}
+
+static int xhci_mtk_resume(struct device *dev)
+{
+	struct xhci_hcd_mtk *mtk = dev_get_drvdata(dev);
+
+	usb_wakeup_disable(mtk);
+	xhci_mtk_clks_enable(mtk);
+	xhci_mtk_phy_enable(mtk);
+	xhci_mtk_ports_enable(mtk);
+	return 0;
+}
+
+static const struct dev_pm_ops xhci_mtk_pm_ops = {
+	SET_SYSTEM_SLEEP_PM_OPS(xhci_mtk_suspend, xhci_mtk_resume)
+};
+#define DEV_PM_OPS	(&xhci_mtk_pm_ops)
+#else
+#define DEV_PM_OPS	NULL
+#endif /* CONFIG_PM */
+
+#ifdef CONFIG_OF
+static const struct of_device_id mtk_xhci_of_match[] = {
+	{ .compatible = "mediatek,mt8173-xhci"},
+	{ },
+};
+MODULE_DEVICE_TABLE(of, mtk_xhci_of_match);
+#endif
+
+static struct platform_driver mtk_xhci_driver = {
+	.probe	= xhci_mtk_probe,
+	.remove	= xhci_mtk_remove,
+	.driver	= {
+		.name = "xhci-mtk",
+		.pm = DEV_PM_OPS,
+		.of_match_table = of_match_ptr(mtk_xhci_of_match),
+	},
+};
+
+static int __init xhci_mtk_init(void)
+{
+	xhci_init_driver(&xhci_mtk_hc_driver, &xhci_mtk_overrides);
+	return platform_driver_register(&mtk_xhci_driver);
+}
+module_init(xhci_mtk_init);
+
+static void __exit xhci_mtk_exit(void)
+{
+	platform_driver_unregister(&mtk_xhci_driver);
+}
+module_exit(xhci_mtk_exit);
+
+MODULE_DESCRIPTION("MediaTek xHCI Host Controller Driver");
+MODULE_LICENSE("GPL v2");
diff --git a/drivers/usb/host/xhci-mtk.h b/drivers/usb/host/xhci-mtk.h
new file mode 100644
index 0000000..5adba62
--- /dev/null
+++ b/drivers/usb/host/xhci-mtk.h
@@ -0,0 +1,133 @@
+/*
+ * Copyright (c) 2015 MediaTek Inc.
+ * Author:
+ *  Zhigang.Wei <zhigang.wei at mediatek.com>
+ *  Chunfeng.Yun <chunfeng.yun at mediatek.com>
+ *
+ * This software is licensed under the terms of the GNU General Public
+ * License version 2, as published by the Free Software Foundation, and
+ * may be copied, distributed, and modified under those terms.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ * GNU General Public License for more details.
+ *
+ */
+
+#ifndef _XHCI_MTK_H_
+#define _XHCI_MTK_H_
+
+#include "xhci.h"
+
+/**
+ * To simplify scheduler algorithm, set a upper limit for ESIT,
+ * if a synchromous ep's ESIT is larger than @XHCI_MTK_MAX_ESIT,
+ * round down to the limit value, that means allocating more
+ * bandwidth to it.
+ */
+#define XHCI_MTK_MAX_ESIT	64
+
+/**
+ * struct mu3h_sch_bw_info
+ * @bus_bw: array to keep track of bandwidth already used at each uframes
+ * @bw_ep_list: eps in the bandwidth domain
+ *
+ * treat a HS root port as a bandwidth domain, but treat a SS root port as
+ * two bandwidth domains, one for IN eps and another for OUT eps.
+ */
+struct mu3h_sch_bw_info {
+	u32 bus_bw[XHCI_MTK_MAX_ESIT];
+	struct list_head bw_ep_list;
+};
+
+/**
+ * struct mu3h_sch_ep_info
+ * @esit: unit is 125us, equal to 2 << Interval field in ep-context
+ * @num_budget_microframes: number of continuous uframes
+ *		(@repeat==1) scheduled within the interval
+ * @ep: address of usb_host_endpoint
+ * @offset: which uframe of the interval that transfer should be
+ *		scheduled first time within the interval
+ * @repeat: the time gap between two uframes that transfers are
+ *		scheduled within a interval. in the simple algorithm, only
+ *		assign 0 or 1 to it; 0 means using only one uframe in a
+ *		interval, and1 means using @num_budget_microframes
+ *		continuous uframes
+ * @pkts: number of packets to be transferred in the scheduled uframes
+ * @cs_count: number of CS that host will trigger
+ */
+struct mu3h_sch_ep_info {
+	u32 ep_type;
+	u32 max_packet_size;
+	u32 esit;
+	u32 num_budget_microframes;
+	u32 bw_cost_per_microframe;
+	void *ep;
+	struct list_head endpoint;
+
+	/* mtk xhci scheduling info */
+	u32 offset;
+	u32 repeat;
+	u32 pkts;
+	u32 cs_count;
+	u32 burst_mode;
+};
+
+struct xhci_hcd_mtk {
+	struct device *dev;
+	struct usb_hcd *hcd;
+	struct mu3h_sch_bw_info *sch_array;
+	void __iomem *mac_base;
+	void __iomem *ippc_base;
+	struct regulator *vusb33;
+	struct regulator *vbus;
+	struct clk *sys_mac;	/* sys and mac clock */
+	struct clk *wk_deb_p0;	/* port0's wakeup debounce clock */
+	struct clk *wk_deb_p1;
+	struct regmap *pericfg;
+	int wakeup_src;
+	struct phy **phys;
+	int num_phys;
+};
+
+#if IS_ENABLED(CONFIG_USB_XHCI_MTK)
+int xhci_mtk_sch_init(struct xhci_hcd *xhci);
+void xhci_mtk_sch_exit(struct xhci_hcd *xhci);
+int xhci_mtk_add_ep_quirk(struct usb_hcd *hcd, struct usb_device *udev,
+		struct usb_host_endpoint *ep);
+void xhci_mtk_drop_ep_quirk(struct usb_hcd *hcd, struct usb_device *udev,
+		struct usb_host_endpoint *ep);
+u32 xhci_mtk_td_remainder_quirk(unsigned int td_running_total,
+	unsigned trb_buffer_length, struct urb *urb);
+
+#else
+static inline int xhci_mtk_sch_init(struct xhci_hcd *xhci)
+{
+	return 0;
+}
+
+static inline void xhci_mtk_sch_exit(struct xhci_hcd *xhci)
+{
+}
+
+static inline int xhci_mtk_add_ep_quirk(struct usb_hcd *hcd,
+	struct usb_device *udev, struct usb_host_endpoint *ep)
+{
+	return 0;
+}
+
+static inline void xhci_mtk_drop_ep_quirk(struct usb_hcd *hcd,
+	struct usb_device *udev, struct usb_host_endpoint *ep)
+{
+}
+
+static inline u32 xhci_mtk_td_remainder_quirk(unsigned int td_running_total,
+	unsigned trb_buffer_length, struct urb *urb)
+{
+	return 0;
+}
+
+#endif
+
+#endif		/* _XHCI_MTK_H_ */
diff --git a/drivers/usb/host/xhci-ring.c b/drivers/usb/host/xhci-ring.c
index 94416ff..73997a0 100644
--- a/drivers/usb/host/xhci-ring.c
+++ b/drivers/usb/host/xhci-ring.c
@@ -68,6 +68,7 @@
 #include <linux/slab.h>
 #include "xhci.h"
 #include "xhci-trace.h"
+#include "xhci-mtk.h"
 
 /*
  * Returns zero if the TRB isn't in this segment, otherwise it returns the DMA
@@ -3131,9 +3132,14 @@ static int queue_bulk_sg_tx(struct xhci_hcd *xhci, gfp_t mem_flags,
 
 		/* Set the TRB length, TD size, and interrupter fields. */
 		if (xhci->hci_version < 0x100) {
-			remainder = xhci_td_remainder(
+			if (xhci->quirks & XHCI_MTK_HOST) {
+				remainder = xhci_mtk_td_remainder_quirk(
+					running_total, trb_buff_len, urb);
+			} else {
+				remainder = xhci_td_remainder(
 					urb->transfer_buffer_length -
 					running_total);
+			}
 		} else {
 			remainder = xhci_v1_0_td_remainder(running_total,
 					trb_buff_len, total_packet_count, urb,
@@ -3286,9 +3292,14 @@ int xhci_queue_bulk_tx(struct xhci_hcd *xhci, gfp_t mem_flags,
 
 		/* Set the TRB length, TD size, and interrupter fields. */
 		if (xhci->hci_version < 0x100) {
-			remainder = xhci_td_remainder(
+			if (xhci->quirks & XHCI_MTK_HOST) {
+				remainder = xhci_mtk_td_remainder_quirk(
+					running_total, trb_buff_len, urb);
+			} else {
+				remainder = xhci_td_remainder(
 					urb->transfer_buffer_length -
 					running_total);
+			}
 		} else {
 			remainder = xhci_v1_0_td_remainder(running_total,
 					trb_buff_len, total_packet_count, urb,
@@ -3383,7 +3394,7 @@ int xhci_queue_ctrl_tx(struct xhci_hcd *xhci, gfp_t mem_flags,
 		field |= 0x1;
 
 	/* xHCI 1.0 6.4.1.2.1: Transfer Type field */
-	if (xhci->hci_version == 0x100) {
+	if ((xhci->hci_version == 0x100) || (xhci->quirks & XHCI_MTK_HOST)) {
 		if (urb->transfer_buffer_length > 0) {
 			if (setup->bRequestType & USB_DIR_IN)
 				field |= TRB_TX_TYPE(TRB_DATA_IN);
@@ -3407,8 +3418,14 @@ int xhci_queue_ctrl_tx(struct xhci_hcd *xhci, gfp_t mem_flags,
 		field = TRB_TYPE(TRB_DATA);
 
 	length_field = TRB_LEN(urb->transfer_buffer_length) |
-		xhci_td_remainder(urb->transfer_buffer_length) |
 		TRB_INTR_TARGET(0);
+
+	if (xhci->quirks & XHCI_MTK_HOST)
+		length_field |= xhci_mtk_td_remainder_quirk(0,
+				urb->transfer_buffer_length, urb);
+	else
+		length_field |= xhci_td_remainder(urb->transfer_buffer_length);
+
 	if (urb->transfer_buffer_length > 0) {
 		if (setup->bRequestType & USB_DIR_IN)
 			field |= TRB_DIR_IN;
@@ -3632,8 +3649,14 @@ static int xhci_queue_isoc_tx(struct xhci_hcd *xhci, gfp_t mem_flags,
 
 			/* Set the TRB length, TD size, & interrupter fields. */
 			if (xhci->hci_version < 0x100) {
-				remainder = xhci_td_remainder(
-						td_len - running_total);
+				if (xhci->quirks & XHCI_MTK_HOST) {
+					remainder = xhci_mtk_td_remainder_quirk(
+						running_total, trb_buff_len,
+						urb);
+				} else {
+					remainder = xhci_td_remainder(
+							td_len - running_total);
+				}
 			} else {
 				remainder = xhci_v1_0_td_remainder(
 						running_total, trb_buff_len,
diff --git a/drivers/usb/host/xhci.c b/drivers/usb/host/xhci.c
index 7da0d60..209fc8a 100644
--- a/drivers/usb/host/xhci.c
+++ b/drivers/usb/host/xhci.c
@@ -31,6 +31,7 @@
 
 #include "xhci.h"
 #include "xhci-trace.h"
+#include "xhci-mtk.h"
 
 #define DRIVER_AUTHOR "Sarah Sharp"
 #define DRIVER_DESC "'eXtensible' Host Controller (xHC) Driver"
@@ -623,7 +624,11 @@ int xhci_run(struct usb_hcd *hcd)
 			"// Set the interrupt modulation register");
 	temp = readl(&xhci->ir_set->irq_control);
 	temp &= ~ER_IRQ_INTERVAL_MASK;
-	temp |= (u32) 160;
+	/*
+	 * the increment interval is 8 times as much as that defined
+	 * in xHCI spec on MTK's controller
+	 */
+	temp |= (u32) ((xhci->quirks & XHCI_MTK_HOST) ? 20 : 160);
 	writel(temp, &xhci->ir_set->irq_control);
 
 	/* Set the HCD state before we enable the irqs */
@@ -1688,6 +1693,9 @@ int xhci_drop_endpoint(struct usb_hcd *hcd, struct usb_device *udev,
 
 	xhci_endpoint_zero(xhci, xhci->devs[udev->slot_id], ep);
 
+	if (xhci->quirks & XHCI_MTK_HOST)
+		xhci_mtk_drop_ep_quirk(hcd, udev, ep);
+
 	xhci_dbg(xhci, "drop ep 0x%x, slot id %d, new drop flags = %#x, new add flags = %#x\n",
 			(unsigned int) ep->desc.bEndpointAddress,
 			udev->slot_id,
@@ -1783,6 +1791,15 @@ int xhci_add_endpoint(struct usb_hcd *hcd, struct usb_device *udev,
 		return -ENOMEM;
 	}
 
+	if (xhci->quirks & XHCI_MTK_HOST) {
+		ret = xhci_mtk_add_ep_quirk(hcd, udev, ep);
+		if (ret < 0) {
+			xhci_free_or_cache_endpoint_ring(xhci,
+				virt_dev, ep_index);
+			return ret;
+		}
+	}
+
 	ctrl_ctx->add_flags |= cpu_to_le32(added_ctxs);
 	new_add_flags = le32_to_cpu(ctrl_ctx->add_flags);
 
diff --git a/drivers/usb/host/xhci.h b/drivers/usb/host/xhci.h
index 31e46cc..d257ce3 100644
--- a/drivers/usb/host/xhci.h
+++ b/drivers/usb/host/xhci.h
@@ -1567,6 +1567,7 @@ struct xhci_hcd {
 /* For controllers with a broken beyond repair streams implementation */
 #define XHCI_BROKEN_STREAMS	(1 << 19)
 #define XHCI_PME_STUCK_QUIRK	(1 << 20)
+#define XHCI_MTK_HOST		(1 << 21)
 	unsigned int		num_active_eps;
 	unsigned int		limit_active_eps;
 	/* There are two roothubs to keep track of bus suspend info for */
-- 
1.8.1.1.dirty



From chunfeng.yun at mediatek.com  Fri Aug 21 18:45:07 2015
From: chunfeng.yun at mediatek.com (Chunfeng Yun)
Date: Sat, 22 Aug 2015 09:45:07 +0800
Subject: [PATCH v6 1/5] dt-bindings: Add usb3.0 phy binding for MT65xx SoCs
In-Reply-To: <1440207911-17666-1-git-send-email-chunfeng.yun@mediatek.com>
References: <1440207911-17666-1-git-send-email-chunfeng.yun@mediatek.com>
Message-ID: <1440207911-17666-2-git-send-email-chunfeng.yun@mediatek.com>

add a DT binding documentation of usb3.0 phy for MT65xx
SoCs from Mediatek.

Signed-off-by: Chunfeng Yun <chunfeng.yun at mediatek.com>
---
 .../devicetree/bindings/phy/phy-mt65xx-usb.txt     | 69 ++++++++++++++++++++++
 1 file changed, 69 insertions(+)
 create mode 100644 Documentation/devicetree/bindings/phy/phy-mt65xx-usb.txt

diff --git a/Documentation/devicetree/bindings/phy/phy-mt65xx-usb.txt b/Documentation/devicetree/bindings/phy/phy-mt65xx-usb.txt
new file mode 100644
index 0000000..5812d20
--- /dev/null
+++ b/Documentation/devicetree/bindings/phy/phy-mt65xx-usb.txt
@@ -0,0 +1,69 @@
+mt65xx USB3.0 PHY binding
+--------------------------
+
+This binding describes a usb3.0 phy for mt65xx platforms of Medaitek SoC.
+
+Required properties (controller (parent) node):
+ - compatible	: should be "mediatek,mt8173-u3phy"
+ - reg		: offset and length of register for phy, exclude port's
+		  register.
+ - clocks	: a list of phandle + clock-specifier pairs, one for each
+		  entry in clock-names
+ - clock-names	: must contain
+		  "u3phya_ref": for reference clock of usb3.0 analog phy.
+
+Required nodes	: a sub-node is required for each port the controller
+		  provides. Address range information including the usual
+		  'reg' property is used inside these nodes to describe
+		  the controller's topology. These nodes are translated
+		  by the driver's .xlate() function.
+
+Required properties (port (child) node):
+- reg		: address and length of the register set for the port.
+- #phy-cells	: should be 1 (See second example)
+		  cell after port phandle is phy type from:
+			- PHY_TYPE_USB2
+			- PHY_TYPE_USB3
+
+Example:
+
+u3phy: usb-phy at 11290000 {
+	compatible = "mediatek,mt8173-u3phy";
+	reg = <0 0x11290000 0 0x800>;
+	clocks = <&apmixedsys CLK_APMIXED_REF2USB_TX>;
+	clock-names = "u3phya_ref";
+	#address-cells = <2>;
+	#size-cells = <2>;
+	ranges;
+	status = "okay";
+
+	phy_port0: port at 11290800 {
+		reg = <0 0x11290800 0 0x800>;
+		#phy-cells = <1>;
+		status = "okay";
+	};
+
+	phy_port1: port at 11291000 {
+		reg = <0 0x11291000 0 0x800>;
+		#phy-cells = <1>;
+		status = "okay";
+	};
+};
+
+Specifying phy control of devices
+---------------------------------
+
+Device nodes should specify the configuration required in their "phys"
+property, containing a phandle to the phy port node and a device type;
+phy-names for each port are optional.
+
+Example:
+
+#include <dt-bindings/phy/phy.h>
+
+usb30: usb at 11270000 {
+	...
+	phys = <&phy_port0 PHY_TYPE_USB3>;
+	phy-names = "usb3-0";
+	...
+};
-- 
1.8.1.1.dirty



From chunfeng.yun at mediatek.com  Fri Aug 21 18:45:06 2015
From: chunfeng.yun at mediatek.com (Chunfeng Yun)
Date: Sat, 22 Aug 2015 09:45:06 +0800
Subject: Mediatek xHCI support
Message-ID: <1440207911-17666-1-git-send-email-chunfeng.yun@mediatek.com>

>From 4cab60015fd73f37b7c970ba56c2625fe346fcf3 Mon Sep 17 00:00:00 2001
From: Chunfeng Yun <chunfeng.yun at mediatek.com>
Date: Sat, 22 Aug 2015 09:35:14 +0800
Subject: [PATCH v6 0/5] Mediatek xHCI support

The patch supports MediaTek's xHCI controller.

There are some differences from xHCI spec:
1. The interval is specified in 250 * 8ns increments for Interrupt Moderation
Interval(IMODI) of the Interrupter Moderation(IMOD) register, it is 8 times as
much as that defined in xHCI spec.

2. For the value of TD Size in Normal TRB, MTK's xHCI controller defines a
number of packets that remain to be transferred for a TD after processing all
Max packets in all previous TRBs,that means don't include the current TRB's,
but in xHCI spec it includes the current ones.

3. To minimize the scheduling effort for synchronous endpoints in xHC, the MTK
architecture defines some extra SW scheduling parameters for HW. According to
these parameters provided by SW, the xHC can easily decide whether a
synchronous endpoint should be scheduled in a specific uFrame. The extra SW
scheduling parameters are put into reserved DWs in Slot and Endpoint Context.
And a bandwidth scheduler algorithm is added to support such feature.

A usb3.0 phy driver is also added which used by mt65xx SoCs platform, it
supports two usb2.0 ports and one usb3.0 port.

Change in v6:
1. get register base address of port in probe instead of of_xlate
2. enable clock in phy_init instead of probe

Change in v5:
1. descripte more exactly for each specifiers in xHCI binding
2. make use of new multi-phy feature for phy driver

Change in v4:
1. descripte more exactly for each specifiers in binding file
2. use BIT() to define a bit mask mcro

Change in v3:
1. implement generic phy
2. move opperations for IPPC and wakeup from phy driver to xHCI driver
3. seperate quirk functions into a single C file to fix up dependence issue

Change in v2:
1. Rebase to 4.2-rc1
2. Remove probe phy before add usb_hcd patch from this series due to 4.2-rc1
   already fix this issue
3. add xhci mac clocks
4. add suspend/resume
5. support remote wakeup


Chunfeng Yun (5):
  dt-bindings: Add usb3.0 phy binding for MT65xx SoCs
  dt-bindings: Add a binding for Mediatek xHCI host controller
  usb: phy: add usb3.0 phy driver for mt65xx SoCs
  xhci: mediatek: support MTK xHCI host controller
  arm64: dts: mediatek: add xHCI & usb phy for mt8173

 .../devicetree/bindings/phy/phy-mt65xx-usb.txt     |  69 ++
 .../devicetree/bindings/usb/mt8173-xhci.txt        |  52 ++
 arch/arm64/boot/dts/mediatek/mt8173-evb.dts        |  16 +
 arch/arm64/boot/dts/mediatek/mt8173.dtsi           |  44 ++
 drivers/phy/Kconfig                                |   9 +
 drivers/phy/Makefile                               |   1 +
 drivers/phy/phy-mt65xx-usb3.c                      | 456 +++++++++++
 drivers/usb/host/Kconfig                           |   9 +
 drivers/usb/host/Makefile                          |   4 +
 drivers/usb/host/xhci-mtk-sch.c                    | 436 +++++++++++
 drivers/usb/host/xhci-mtk.c                        | 831 +++++++++++++++++++++
 drivers/usb/host/xhci-mtk.h                        | 133 ++++
 drivers/usb/host/xhci-ring.c                       |  35 +-
 drivers/usb/host/xhci.c                            |  19 +-
 drivers/usb/host/xhci.h                            |   1 +
 15 files changed, 2108 insertions(+), 7 deletions(-)
 create mode 100644 Documentation/devicetree/bindings/phy/phy-mt65xx-usb.txt
 create mode 100644 Documentation/devicetree/bindings/usb/mt8173-xhci.txt
 create mode 100644 drivers/phy/phy-mt65xx-usb3.c
 create mode 100644 drivers/usb/host/xhci-mtk-sch.c
 create mode 100644 drivers/usb/host/xhci-mtk.c
 create mode 100644 drivers/usb/host/xhci-mtk.h

--
1.8.1.1.dirty




From chunfeng.yun at mediatek.com  Fri Aug 21 18:45:09 2015
From: chunfeng.yun at mediatek.com (Chunfeng Yun)
Date: Sat, 22 Aug 2015 09:45:09 +0800
Subject: [PATCH v6 3/5] usb: phy: add usb3.0 phy driver for mt65xx SoCs
In-Reply-To: <1440207911-17666-1-git-send-email-chunfeng.yun@mediatek.com>
References: <1440207911-17666-1-git-send-email-chunfeng.yun@mediatek.com>
Message-ID: <1440207911-17666-4-git-send-email-chunfeng.yun@mediatek.com>

support usb3.0 phy of mt65xx SoCs

Signed-off-by: Chunfeng Yun <chunfeng.yun at mediatek.com>
---
 drivers/phy/Kconfig           |   9 +
 drivers/phy/Makefile          |   1 +
 drivers/phy/phy-mt65xx-usb3.c | 456 ++++++++++++++++++++++++++++++++++++++++++
 3 files changed, 466 insertions(+)
 create mode 100644 drivers/phy/phy-mt65xx-usb3.c

diff --git a/drivers/phy/Kconfig b/drivers/phy/Kconfig
index c0e6ede..019cf8b 100644
--- a/drivers/phy/Kconfig
+++ b/drivers/phy/Kconfig
@@ -193,6 +193,15 @@ config PHY_HIX5HD2_SATA
 	help
 	  Support for SATA PHY on Hisilicon hix5hd2 Soc.
 
+config PHY_MT65XX_USB3
+	tristate "Mediatek USB3.0 PHY Driver"
+	depends on ARCH_MEDIATEK && OF
+	select GENERIC_PHY
+	help
+	  Say 'Y' here to add support for Mediatek USB3.0 PHY driver
+	  for mt65xx SoCs. it supports two usb2.0 ports and
+	  one usb3.0 port.
+
 config PHY_SUN4I_USB
 	tristate "Allwinner sunxi SoC USB PHY driver"
 	depends on ARCH_SUNXI && HAS_IOMEM && OF
diff --git a/drivers/phy/Makefile b/drivers/phy/Makefile
index f344e1b..3ceff2a 100644
--- a/drivers/phy/Makefile
+++ b/drivers/phy/Makefile
@@ -22,6 +22,7 @@ obj-$(CONFIG_TI_PIPE3)			+= phy-ti-pipe3.o
 obj-$(CONFIG_TWL4030_USB)		+= phy-twl4030-usb.o
 obj-$(CONFIG_PHY_EXYNOS5250_SATA)	+= phy-exynos5250-sata.o
 obj-$(CONFIG_PHY_HIX5HD2_SATA)		+= phy-hix5hd2-sata.o
+obj-$(CONFIG_PHY_MT65XX_USB3)		+= phy-mt65xx-usb3.o
 obj-$(CONFIG_PHY_SUN4I_USB)		+= phy-sun4i-usb.o
 obj-$(CONFIG_PHY_SUN9I_USB)		+= phy-sun9i-usb.o
 obj-$(CONFIG_PHY_SAMSUNG_USB2)		+= phy-exynos-usb2.o
diff --git a/drivers/phy/phy-mt65xx-usb3.c b/drivers/phy/phy-mt65xx-usb3.c
new file mode 100644
index 0000000..7510fda
--- /dev/null
+++ b/drivers/phy/phy-mt65xx-usb3.c
@@ -0,0 +1,456 @@
+/*
+ * Copyright (c) 2015 MediaTek Inc.
+ * Author: Chunfeng Yun <chunfeng.yun at mediatek.com>
+ *
+ * This software is licensed under the terms of the GNU General Public
+ * License version 2, as published by the Free Software Foundation, and
+ * may be copied, distributed, and modified under those terms.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ * GNU General Public License for more details.
+ *
+ */
+
+#include <dt-bindings/phy/phy.h>
+#include <linux/clk.h>
+#include <linux/delay.h>
+#include <linux/io.h>
+#include <linux/module.h>
+#include <linux/of_address.h>
+#include <linux/phy/phy.h>
+#include <linux/platform_device.h>
+
+/*
+ * for sifslv2 register, but exclude port's;
+ * relative to USB3_SIF2_BASE base address
+ */
+#define SSUSB_SIFSLV_SPLLC		0x0000
+
+/* offsets of sub-segment in each port registers */
+#define SSUSB_SIFSLV_U2PHY_COM_BASE	0x0000
+#define SSUSB_SIFSLV_U3PHYD_BASE	0x0100
+#define SSUSB_USB30_PHYA_SIV_B_BASE	0x0300
+#define SSUSB_SIFSLV_U3PHYA_DA_BASE	0x0400
+
+#define U3P_USBPHYACR0		(SSUSB_SIFSLV_U2PHY_COM_BASE + 0x0000)
+#define PA0_RG_U2PLL_FORCE_ON		BIT(15)
+
+#define U3P_USBPHYACR2		(SSUSB_SIFSLV_U2PHY_COM_BASE + 0x0008)
+#define PA2_RG_SIF_U2PLL_FORCE_EN	BIT(18)
+
+#define U3P_USBPHYACR5		(SSUSB_SIFSLV_U2PHY_COM_BASE + 0x0014)
+#define PA5_RG_U2_HSTX_SRCTRL		(0x7 << 12)
+#define PA5_RG_U2_HSTX_SRCTRL_VAL(x)	((0x7 & (x)) << 12)
+#define PA5_RG_U2_HS_100U_U3_EN	BIT(11)
+
+#define U3P_USBPHYACR6		(SSUSB_SIFSLV_U2PHY_COM_BASE + 0x0018)
+#define PA6_RG_U2_ISO_EN		BIT(31)
+#define PA6_RG_U2_BC11_SW_EN		BIT(23)
+#define PA6_RG_U2_OTG_VBUSCMP_EN	BIT(20)
+
+#define U3P_U2PHYACR4		(SSUSB_SIFSLV_U2PHY_COM_BASE + 0x0020)
+#define P2C_RG_USB20_GPIO_CTL		BIT(9)
+#define P2C_USB20_GPIO_MODE		BIT(8)
+#define P2C_U2_GPIO_CTR_MSK	(P2C_RG_USB20_GPIO_CTL | P2C_USB20_GPIO_MODE)
+
+#define U3D_U2PHYDCR0		(SSUSB_SIFSLV_U2PHY_COM_BASE + 0x0060)
+#define P2C_RG_SIF_U2PLL_FORCE_ON	BIT(24)
+
+#define U3P_U2PHYDTM0		(SSUSB_SIFSLV_U2PHY_COM_BASE + 0x0068)
+#define P2C_FORCE_UART_EN		BIT(26)
+#define P2C_FORCE_DATAIN		BIT(23)
+#define P2C_FORCE_DM_PULLDOWN		BIT(21)
+#define P2C_FORCE_DP_PULLDOWN		BIT(20)
+#define P2C_FORCE_XCVRSEL		BIT(19)
+#define P2C_FORCE_SUSPENDM		BIT(18)
+#define P2C_FORCE_TERMSEL		BIT(17)
+#define P2C_RG_DATAIN			(0xf << 10)
+#define P2C_RG_DATAIN_VAL(x)		((0xf & (x)) << 10)
+#define P2C_RG_DMPULLDOWN		BIT(7)
+#define P2C_RG_DPPULLDOWN		BIT(6)
+#define P2C_RG_XCVRSEL			(0x3 << 4)
+#define P2C_RG_XCVRSEL_VAL(x)		((0x3 & (x)) << 4)
+#define P2C_RG_SUSPENDM			BIT(3)
+#define P2C_RG_TERMSEL			BIT(2)
+#define P2C_DTM0_PART_MASK \
+		(P2C_FORCE_DATAIN | P2C_FORCE_DM_PULLDOWN | \
+		P2C_FORCE_DP_PULLDOWN | P2C_FORCE_XCVRSEL | \
+		P2C_FORCE_TERMSEL | P2C_RG_DMPULLDOWN | \
+		P2C_RG_DPPULLDOWN | P2C_RG_TERMSEL)
+
+#define U3P_U2PHYDTM1		(SSUSB_SIFSLV_U2PHY_COM_BASE + 0x006C)
+#define P2C_RG_UART_EN			BIT(16)
+#define P2C_RG_VBUSVALID		BIT(5)
+#define P2C_RG_SESSEND			BIT(4)
+#define P2C_RG_AVALID			BIT(2)
+
+#define U3P_U3_PHYA_REG0	(SSUSB_USB30_PHYA_SIV_B_BASE + 0x0000)
+#define P3A_RG_U3_VUSB10_ON		BIT(5)
+
+#define U3P_U3_PHYA_REG6	(SSUSB_USB30_PHYA_SIV_B_BASE + 0x0018)
+#define P3A_RG_TX_EIDLE_CM		(0xf << 28)
+#define P3A_RG_TX_EIDLE_CM_VAL(x)	((0xf & (x)) << 28)
+
+#define U3P_U3_PHYA_REG9	(SSUSB_USB30_PHYA_SIV_B_BASE + 0x0024)
+#define P3A_RG_RX_DAC_MUX		(0x1f << 1)
+#define P3A_RG_RX_DAC_MUX_VAL(x)	((0x1f & (x)) << 1)
+
+#define U3P_U3PHYA_DA_REG0	(SSUSB_SIFSLV_U3PHYA_DA_BASE + 0x0000)
+#define P3A_RG_XTAL_EXT_EN_U3		(0x3 << 10)
+#define P3A_RG_XTAL_EXT_EN_U3_VAL(x)	((0x3 & (x)) << 10)
+
+#define U3P_PHYD_CDR1		(SSUSB_SIFSLV_U3PHYD_BASE + 0x005c)
+#define P3D_RG_CDR_BIR_LTD1		(0x1f << 24)
+#define P3D_RG_CDR_BIR_LTD1_VAL(x)	((0x1f & (x)) << 24)
+#define P3D_RG_CDR_BIR_LTD0		(0x1f << 8)
+#define P3D_RG_CDR_BIR_LTD0_VAL(x)	((0x1f & (x)) << 8)
+
+#define U3P_XTALCTL3		(SSUSB_SIFSLV_SPLLC + 0x0018)
+#define XC3_RG_U3_XTAL_RX_PWD		BIT(9)
+#define XC3_RG_U3_FRC_XTAL_RX_PWD	BIT(8)
+
+struct mt65xx_phy_instance {
+	struct phy *phy;
+	void __iomem *port_base;
+	u32 index;
+	u8 type;
+};
+
+struct mt65xx_u3phy {
+	struct device *dev;
+	void __iomem *sif_base;	/* include sif2, but exclude port's */
+	struct clk *u3phya_ref;	/* reference clock of usb3 anolog phy */
+	struct mt65xx_phy_instance **phys;
+	int nphys;
+};
+
+static void phy_instance_init(struct mt65xx_u3phy *u3phy,
+	struct mt65xx_phy_instance *instance)
+{
+	void __iomem *port_base = instance->port_base;
+	u32 index = instance->index;
+	u32 tmp;
+
+	/* switch to USB function. (system register, force ip into usb mode) */
+	tmp = readl(port_base + U3P_U2PHYDTM0);
+	tmp &= ~P2C_FORCE_UART_EN;
+	writel(tmp, port_base + U3P_U2PHYDTM0);
+
+	tmp = readl(port_base + U3P_U2PHYDTM1);
+	tmp &= ~P2C_RG_UART_EN;
+	writel(tmp, port_base + U3P_U2PHYDTM1);
+
+	if (!index) {
+		tmp = readl(port_base + U3P_U2PHYACR4);
+		tmp &= ~P2C_U2_GPIO_CTR_MSK;
+		writel(tmp, port_base + U3P_U2PHYACR4);
+	}
+
+	/* DP/DM BC1.1 path Disable */
+	tmp = readl(port_base + U3P_USBPHYACR6);
+	tmp &= ~PA6_RG_U2_BC11_SW_EN;
+	writel(tmp, port_base + U3P_USBPHYACR6);
+
+	tmp = readl(port_base + U3P_U3PHYA_DA_REG0);
+	tmp &= ~P3A_RG_XTAL_EXT_EN_U3;
+	tmp |= P3A_RG_XTAL_EXT_EN_U3_VAL(2);
+	writel(tmp, port_base + U3P_U3PHYA_DA_REG0);
+
+	tmp = readl(port_base + U3P_U3_PHYA_REG9);
+	tmp &= ~P3A_RG_RX_DAC_MUX;
+	tmp |= P3A_RG_RX_DAC_MUX_VAL(4);
+	writel(tmp, port_base + U3P_U3_PHYA_REG9);
+
+	tmp = readl(port_base + U3P_U3_PHYA_REG6);
+	tmp &= ~P3A_RG_TX_EIDLE_CM;
+	tmp |= P3A_RG_TX_EIDLE_CM_VAL(0xe);
+	writel(tmp, port_base + U3P_U3_PHYA_REG6);
+
+	tmp = readl(port_base + U3P_PHYD_CDR1);
+	tmp &= ~(P3D_RG_CDR_BIR_LTD0 | P3D_RG_CDR_BIR_LTD1);
+	tmp |= P3D_RG_CDR_BIR_LTD0_VAL(0xc) | P3D_RG_CDR_BIR_LTD1_VAL(0x3);
+	writel(tmp, port_base + U3P_PHYD_CDR1);
+
+	dev_dbg(u3phy->dev, "%s(%d)\n", __func__, index);
+}
+
+static void phy_instance_power_on(struct mt65xx_u3phy *u3phy,
+	struct mt65xx_phy_instance *instance)
+{
+	void __iomem *port_base = instance->port_base;
+	u32 index = instance->index;
+	u32 tmp;
+
+	if (!index) {
+		/* Set RG_SSUSB_VUSB10_ON as 1 after VUSB10 ready */
+		tmp = readl(port_base + U3P_U3_PHYA_REG0);
+		tmp |= P3A_RG_U3_VUSB10_ON;
+		writel(tmp, port_base + U3P_U3_PHYA_REG0);
+	}
+
+	/* (force_suspendm=0) (let suspendm=1, enable usb 480MHz pll) */
+	tmp = readl(port_base + U3P_U2PHYDTM0);
+	tmp &= ~(P2C_FORCE_SUSPENDM | P2C_RG_XCVRSEL);
+	tmp &= ~(P2C_RG_DATAIN | P2C_DTM0_PART_MASK);
+	writel(tmp, port_base + U3P_U2PHYDTM0);
+
+	/* OTG Enable */
+	tmp = readl(port_base + U3P_USBPHYACR6);
+	tmp |= PA6_RG_U2_OTG_VBUSCMP_EN;
+	writel(tmp, port_base + U3P_USBPHYACR6);
+
+	if (!index) {
+		tmp = readl(u3phy->sif_base + U3P_XTALCTL3);
+		tmp |= XC3_RG_U3_XTAL_RX_PWD | XC3_RG_U3_FRC_XTAL_RX_PWD;
+		writel(tmp, u3phy->sif_base + U3P_XTALCTL3);
+		/* [mt8173]disable Change 100uA current from SSUSB */
+		tmp = readl(port_base + U3P_USBPHYACR5);
+		tmp &= ~PA5_RG_U2_HS_100U_U3_EN;
+		writel(tmp, port_base + U3P_USBPHYACR5);
+	}
+	udelay(800);
+
+	tmp = readl(port_base + U3P_U2PHYDTM1);
+	tmp |= P2C_RG_VBUSVALID | P2C_RG_AVALID;
+	tmp &= ~P2C_RG_SESSEND;
+	writel(tmp, port_base + U3P_U2PHYDTM1);
+	/* USB 2.0 slew rate calibration */
+	tmp = readl(port_base + U3P_USBPHYACR5);
+	tmp &= ~PA5_RG_U2_HSTX_SRCTRL;
+	tmp |= PA5_RG_U2_HSTX_SRCTRL_VAL(4);
+	writel(tmp, port_base + U3P_USBPHYACR5);
+
+	dev_dbg(u3phy->dev, "%s(%d)\n", __func__, index);
+}
+
+static void phy_instance_power_off(struct mt65xx_u3phy *u3phy,
+	struct mt65xx_phy_instance *instance)
+{
+	void __iomem *port_base = instance->port_base;
+	u32 index = instance->index;
+	u32 tmp;
+
+	tmp = readl(port_base + U3P_U2PHYDTM0);
+	tmp &= ~(P2C_RG_XCVRSEL | P2C_RG_DATAIN);
+	tmp |= P2C_RG_XCVRSEL_VAL(1) | P2C_RG_DATAIN_VAL(0);
+	tmp |= P2C_FORCE_SUSPENDM;
+	writel(tmp, port_base + U3P_U2PHYDTM0);
+
+	/* OTG Disable */
+	tmp = readl(port_base + U3P_USBPHYACR6);
+	tmp &= ~PA6_RG_U2_OTG_VBUSCMP_EN;
+	writel(tmp, port_base + U3P_USBPHYACR6);
+	if (!index) {
+		/* (also disable)Change 100uA current switch to USB2.0 */
+		tmp = readl(port_base + U3P_USBPHYACR5);
+		tmp &= ~PA5_RG_U2_HS_100U_U3_EN;
+		writel(tmp, port_base + U3P_USBPHYACR5);
+	}
+	udelay(800);
+
+	/* let suspendm=0, set utmi into analog power down */
+	tmp = readl(port_base + U3P_U2PHYDTM0);
+	tmp &= ~P2C_RG_SUSPENDM;
+	writel(tmp, port_base + U3P_U2PHYDTM0);
+	udelay(1);
+
+	tmp = readl(port_base + U3P_U2PHYDTM1);
+	tmp &= ~(P2C_RG_VBUSVALID | P2C_RG_AVALID);
+	tmp |= P2C_RG_SESSEND;
+	writel(tmp, port_base + U3P_U2PHYDTM1);
+
+	if (!index) {
+		tmp = readl(port_base + U3P_U3_PHYA_REG0);
+		tmp &= ~P3A_RG_U3_VUSB10_ON;
+		writel(tmp, port_base + U3P_U3_PHYA_REG0);
+	}
+
+	dev_dbg(u3phy->dev, "%s(%d)\n", __func__, index);
+}
+
+static int mt65xx_phy_init(struct phy *phy)
+{
+	struct mt65xx_phy_instance *instance = phy_get_drvdata(phy);
+	struct mt65xx_u3phy *u3phy = dev_get_drvdata(phy->dev.parent);
+	int ret;
+
+	ret = clk_prepare_enable(u3phy->u3phya_ref);
+	if (ret) {
+		dev_err(u3phy->dev, "failed to enable u3phya_ref\n");
+		return ret;
+	}
+
+	phy_instance_init(u3phy, instance);
+	return 0;
+}
+
+static int mt65xx_phy_power_on(struct phy *phy)
+{
+	struct mt65xx_phy_instance *instance = phy_get_drvdata(phy);
+	struct mt65xx_u3phy *u3phy = dev_get_drvdata(phy->dev.parent);
+
+	phy_instance_power_on(u3phy, instance);
+	return 0;
+}
+
+static int mt65xx_phy_power_off(struct phy *phy)
+{
+	struct mt65xx_phy_instance *instance = phy_get_drvdata(phy);
+	struct mt65xx_u3phy *u3phy = dev_get_drvdata(phy->dev.parent);
+
+	phy_instance_power_off(u3phy, instance);
+	return 0;
+}
+
+static int mt65xx_phy_exit(struct phy *phy)
+{
+	struct mt65xx_u3phy *u3phy = dev_get_drvdata(phy->dev.parent);
+
+	clk_disable_unprepare(u3phy->u3phya_ref);
+	return 0;
+}
+
+static struct phy *mt65xx_phy_xlate(struct device *dev,
+					struct of_phandle_args *args)
+{
+	struct mt65xx_u3phy *u3phy = dev_get_drvdata(dev);
+	struct mt65xx_phy_instance *instance = NULL;
+	struct device_node *phy_np = args->np;
+	int index;
+
+
+	if (args->args_count != 1) {
+		dev_err(dev, "invalid number of cells in 'phy' property\n");
+		return ERR_PTR(-EINVAL);
+	}
+
+	for (index = 0; index < u3phy->nphys; index++)
+		if (phy_np == u3phy->phys[index]->phy->dev.of_node) {
+			instance = u3phy->phys[index];
+			break;
+		}
+
+	if (!instance) {
+		dev_err(dev, "failed to find appropriate phy\n");
+		return ERR_PTR(-EINVAL);
+	}
+
+	instance->type = args->args[0];
+
+	if (!(instance->type == PHY_TYPE_USB2 ||
+	      instance->type == PHY_TYPE_USB3)) {
+		dev_err(dev, "unsupported device type: %d\n", instance->type);
+		return ERR_PTR(-EINVAL);
+	}
+
+	return instance->phy;
+}
+
+static struct phy_ops mt65xx_u3phy_ops = {
+	.init		= mt65xx_phy_init,
+	.exit		= mt65xx_phy_exit,
+	.power_on	= mt65xx_phy_power_on,
+	.power_off	= mt65xx_phy_power_off,
+	.owner		= THIS_MODULE,
+};
+
+static int mt65xx_u3phy_probe(struct platform_device *pdev)
+{
+	struct device *dev = &pdev->dev;
+	struct device_node *np = dev->of_node;
+	struct device_node *child_np;
+	struct phy_provider *provider;
+	struct resource *sif_res;
+	struct mt65xx_u3phy *u3phy;
+	struct resource res;
+	int port;
+
+	u3phy = devm_kzalloc(dev, sizeof(*u3phy), GFP_KERNEL);
+	if (!u3phy)
+		return -ENOMEM;
+
+	u3phy->nphys = of_get_child_count(np);
+	u3phy->phys = devm_kcalloc(dev, u3phy->nphys,
+				       sizeof(*u3phy->phys), GFP_KERNEL);
+	if (!u3phy->phys)
+		return -ENOMEM;
+
+	u3phy->dev = dev;
+	platform_set_drvdata(pdev, u3phy);
+
+	sif_res = platform_get_resource(pdev, IORESOURCE_MEM, 0);
+	u3phy->sif_base = devm_ioremap_resource(dev, sif_res);
+	if (IS_ERR(u3phy->sif_base)) {
+		dev_err(dev, "failed to remap sif regs\n");
+		return PTR_ERR(u3phy->sif_base);
+	}
+
+	u3phy->u3phya_ref = devm_clk_get(dev, "u3phya_ref");
+	if (IS_ERR(u3phy->u3phya_ref)) {
+		dev_err(dev, "error to get u3phya_ref\n");
+		return PTR_ERR(u3phy->u3phya_ref);
+	}
+
+	port = 0;
+	for_each_child_of_node(np, child_np) {
+		struct mt65xx_phy_instance *instance;
+		struct phy *phy;
+		int retval;
+
+		instance = devm_kzalloc(dev, sizeof(*instance), GFP_KERNEL);
+		if (!instance)
+			return -ENOMEM;
+
+		u3phy->phys[port] = instance;
+
+		phy = devm_phy_create(dev, child_np, &mt65xx_u3phy_ops);
+		if (IS_ERR(phy)) {
+			dev_err(dev, "failed to create phy\n");
+			return PTR_ERR(phy);
+		}
+
+		retval = of_address_to_resource(child_np, 0, &res);
+		if (retval) {
+			dev_err(dev, "failed to get address resource(id-%d)\n",
+				port);
+			return retval;
+		}
+
+		instance->port_base = devm_ioremap_resource(&phy->dev, &res);
+		if (IS_ERR(instance->port_base)) {
+			dev_err(dev, "failed to remap phy regs\n");
+			return PTR_ERR(instance->port_base);
+		}
+
+		instance->phy = phy;
+		instance->index = port;
+		phy_set_drvdata(phy, instance);
+		port++;
+	}
+
+	provider = devm_of_phy_provider_register(dev, mt65xx_phy_xlate);
+
+	return PTR_ERR_OR_ZERO(provider);
+}
+
+static const struct of_device_id mt65xx_u3phy_id_table[] = {
+	{ .compatible = "mediatek,mt8173-u3phy", },
+	{ },
+};
+MODULE_DEVICE_TABLE(of, mt65xx_u3phy_id_table);
+
+static struct platform_driver mt65xx_u3phy_driver = {
+	.probe		= mt65xx_u3phy_probe,
+	.driver		= {
+		.name	= "mt65xx-u3phy",
+		.of_match_table = mt65xx_u3phy_id_table,
+	},
+};
+
+module_platform_driver(mt65xx_u3phy_driver);
+
+MODULE_AUTHOR("Chunfeng Yun <chunfeng.yun at mediatek.com>");
+MODULE_DESCRIPTION("mt65xx USB PHY driver");
+MODULE_LICENSE("GPL v2");
-- 
1.8.1.1.dirty



From chunfeng.yun at mediatek.com  Fri Aug 21 18:45:11 2015
From: chunfeng.yun at mediatek.com (Chunfeng Yun)
Date: Sat, 22 Aug 2015 09:45:11 +0800
Subject: [PATCH v6 5/5] arm64: dts: mediatek: add xHCI & usb phy for mt8173
In-Reply-To: <1440207911-17666-1-git-send-email-chunfeng.yun@mediatek.com>
References: <1440207911-17666-1-git-send-email-chunfeng.yun@mediatek.com>
Message-ID: <1440207911-17666-6-git-send-email-chunfeng.yun@mediatek.com>

add xHCI and phy drivers for MT8173-EVB

Signed-off-by: Chunfeng Yun <chunfeng.yun at mediatek.com>
---
 arch/arm64/boot/dts/mediatek/mt8173-evb.dts | 16 +++++++++++
 arch/arm64/boot/dts/mediatek/mt8173.dtsi    | 44 +++++++++++++++++++++++++++++
 2 files changed, 60 insertions(+)

diff --git a/arch/arm64/boot/dts/mediatek/mt8173-evb.dts b/arch/arm64/boot/dts/mediatek/mt8173-evb.dts
index f433c21..112f3f3 100644
--- a/arch/arm64/boot/dts/mediatek/mt8173-evb.dts
+++ b/arch/arm64/boot/dts/mediatek/mt8173-evb.dts
@@ -13,6 +13,7 @@
  */
 
 /dts-v1/;
+#include <dt-bindings/gpio/gpio.h>
 #include "mt8173.dtsi"
 
 / {
@@ -32,6 +33,15 @@
 	};
 
 	chosen { };
+
+	usb_p1_vbus: regulator at 0 {
+		compatible = "regulator-fixed";
+		regulator-name = "usb_vbus";
+		regulator-min-microvolt = <5000000>;
+		regulator-max-microvolt = <5000000>;
+		gpio = <&pio 130 GPIO_ACTIVE_HIGH>;
+		enable-active-high;
+	};
 };
 
 &pwrap {
@@ -211,3 +221,9 @@
 &uart0 {
 	status = "okay";
 };
+
+&usb30 {
+	vusb33-supply = <&mt6397_vusb_reg>;
+	vbus-supply = <&usb_p1_vbus>;
+	mediatek,wakeup-src = <1>;
+};
diff --git a/arch/arm64/boot/dts/mediatek/mt8173.dtsi b/arch/arm64/boot/dts/mediatek/mt8173.dtsi
index 0696f8f..f88b2f9 100644
--- a/arch/arm64/boot/dts/mediatek/mt8173.dtsi
+++ b/arch/arm64/boot/dts/mediatek/mt8173.dtsi
@@ -14,6 +14,8 @@
 #include <dt-bindings/clock/mt8173-clk.h>
 #include <dt-bindings/interrupt-controller/irq.h>
 #include <dt-bindings/interrupt-controller/arm-gic.h>
+#include <dt-bindings/phy/phy.h>
+#include <dt-bindings/power/mt8173-power.h>
 #include <dt-bindings/reset-controller/mt8173-resets.h>
 #include "mt8173-pinfunc.h"
 
@@ -393,6 +395,48 @@
 			#size-cells = <0>;
 			status = "disabled";
 		};
+
+		usb30: usb at 11270000 {
+			compatible = "mediatek,mt8173-xhci";
+			reg = <0 0x11270000 0 0x4000>,
+			      <0 0x11280000 0 0x0800>;
+			interrupts = <GIC_SPI 115 IRQ_TYPE_LEVEL_LOW>;
+			power-domains = <&scpsys MT8173_POWER_DOMAIN_USB>;
+			clocks = <&topckgen CLK_TOP_USB30_SEL>,
+				 <&pericfg CLK_PERI_USB0>,
+				 <&pericfg CLK_PERI_USB1>;
+			clock-names = "sys_ck",
+				      "wakeup_deb_p0",
+				      "wakeup_deb_p1";
+			phys = <&phy_port0 PHY_TYPE_USB3>,
+			       <&phy_port1 PHY_TYPE_USB2>;
+			usb3-lpm-capable;
+			mediatek,syscon-wakeup = <&pericfg>;
+			status = "okay";
+		};
+
+		u3phy: usb-phy at 11290000 {
+			compatible = "mediatek,mt8173-u3phy";
+			reg = <0 0x11290000 0 0x800>;
+			clocks = <&apmixedsys CLK_APMIXED_REF2USB_TX>;
+			clock-names = "u3phya_ref";
+			#address-cells = <2>;
+			#size-cells = <2>;
+			ranges;
+			status = "okay";
+
+			phy_port0: port at 11290800 {
+				reg = <0 0x11290800 0 0x800>;
+				#phy-cells = <1>;
+				status = "okay";
+			};
+
+			phy_port1: port at 11291000 {
+				reg = <0 0x11291000 0 0x800>;
+				#phy-cells = <1>;
+				status = "okay";
+			};
+		};
 	};
 };
 
-- 
1.8.1.1.dirty



From pbonzini at redhat.com  Sat Aug 22 00:00:23 2015
From: pbonzini at redhat.com (Paolo Bonzini)
Date: Sat, 22 Aug 2015 00:00:23 -0700
Subject: [GIT PULL] KVM/ARM pull request for 4.3
In-Reply-To: <1440088143-4722-1-git-send-email-marc.zyngier@arm.com>
References: <1440088143-4722-1-git-send-email-marc.zyngier@arm.com>
Message-ID: <55D81E07.2080002@redhat.com>



On 20/08/2015 09:28, Marc Zyngier wrote:
> Hi Paolo,
> 
> This is the KVM/ARM pull request for Linux 4.3. Some rather major
> things this time around (guest debug, management of interrupt active
> state, lazy FP save/restore).
> 
> Thanks!
> 
> 	M.
> 
> The following changes since commit bc0195aad0daa2ad5b0d76cce22b167bc3435590:
> 
>   Linux 4.2-rc2 (2015-07-12 15:10:30 -0700)
> 
> are available in the git repository at:
> 
>   git://git.kernel.org/pub/scm/linux/kernel/git/kvmarm/kvmarm.git tags/kvm-arm-for-4.3
> 
> for you to fetch changes up to 054167b3d55127feb64978eddf3f9f3a84fe493b:
> 
>   arm: KVM: keep arm vfp/simd exit handling consistent with arm64 (2015-08-19 22:27:58 +0100)

Pulled---for now in kvm/queue until I get Alex's pull request.

Paolo

> ----------------------------------------------------------------
> KVM/ARM changes for 4.3
> 
> - Full debug support for arm64
> - Active state switching for timer interrupts
> - Lazy FP/SIMD save/restore for arm64
> - Generic ARMv8 target
> 
> ----------------------------------------------------------------
> Alex Benn?e (11):
>       KVM: add comments for kvm_debug_exit_arch struct
>       KVM: arm64: guest debug, define API headers
>       KVM: arm: guest debug, add stub KVM_SET_GUEST_DEBUG ioctl
>       KVM: arm: introduce kvm_arm_init/setup/clear_debug
>       KVM: arm64: guest debug, add SW break point support
>       KVM: arm64: guest debug, add support for single-step
>       KVM: arm64: re-factor hyp.S debug register code
>       KVM: arm64: introduce vcpu->arch.debug_ptr
>       KVM: arm64: guest debug, HW assisted debug support
>       KVM: arm64: enable KVM_CAP_SET_GUEST_DEBUG
>       KVM: arm64: add trace points for guest_debug debug
> 
> Marc Zyngier (10):
>       arm/arm64: KVM: Fix ordering of timer/GIC on guest entry
>       arm/arm64: KVM: Move vgic handling to a non-preemptible section
>       KVM: arm/arm64: vgic: Convert struct vgic_lr to use bitfields
>       KVM: arm/arm64: vgic: Allow HW irq to be encoded in LR
>       KVM: arm/arm64: vgic: Relax vgic_can_sample_irq for edge IRQs
>       KVM: arm/arm64: vgic: Allow dynamic mapping of physical/virtual interrupts
>       KVM: arm/arm64: vgic: Allow HW interrupts to be queued to a guest
>       KVM: arm/arm64: vgic: Add vgic_{get,set}_phys_irq_active
>       KVM: arm/arm64: vgic: Prevent userspace injection of a mapped interrupt
>       KVM: arm/arm64: timer: Allow the timer to control the active state
> 
> Mario Smarduch (2):
>       arm64: KVM: Optimize arm64 skip 30-50% vfp/simd save/restore on exits
>       arm: KVM: keep arm vfp/simd exit handling consistent with arm64
> 
> Suzuki K. Poulose (1):
>       arm64/kvm: Add generic v8 KVM target
> 
> Vladimir Murzin (1):
>       arm64: KVM: remove remaining reference to vgic_sr_vectors
> 
>  Documentation/virtual/kvm/api.txt      |  15 +-
>  arch/arm/include/asm/kvm_host.h        |   5 +
>  arch/arm/kvm/arm.c                     |  36 +-
>  arch/arm/kvm/guest.c                   |   6 +
>  arch/arm/kvm/interrupts.S              |  14 +-
>  arch/arm/kvm/reset.c                   |   4 +-
>  arch/arm64/include/asm/hw_breakpoint.h |  14 +
>  arch/arm64/include/asm/kvm_arm.h       |   5 +-
>  arch/arm64/include/asm/kvm_asm.h       |  26 +-
>  arch/arm64/include/asm/kvm_host.h      |  42 ++-
>  arch/arm64/include/uapi/asm/kvm.h      |  37 +-
>  arch/arm64/kernel/asm-offsets.c        |   9 +-
>  arch/arm64/kernel/hw_breakpoint.c      |  12 -
>  arch/arm64/kvm/Makefile                |   2 +-
>  arch/arm64/kvm/debug.c                 | 217 ++++++++++++
>  arch/arm64/kvm/guest.c                 |  43 ++-
>  arch/arm64/kvm/handle_exit.c           |  44 +++
>  arch/arm64/kvm/hyp.S                   | 617 ++++++++++++---------------------
>  arch/arm64/kvm/reset.c                 |  20 +-
>  arch/arm64/kvm/sys_regs.c              | 291 ++++++++++++++--
>  arch/arm64/kvm/sys_regs.h              |   6 +
>  arch/arm64/kvm/sys_regs_generic_v8.c   |   2 +
>  arch/arm64/kvm/trace.h                 | 123 +++++++
>  include/kvm/arm_arch_timer.h           |   7 +-
>  include/kvm/arm_vgic.h                 |  39 ++-
>  include/linux/irqchip/arm-gic-v3.h     |   3 +
>  include/linux/irqchip/arm-gic.h        |   3 +-
>  include/uapi/linux/kvm.h               |   5 +
>  virt/kvm/arm/arch_timer.c              |  29 +-
>  virt/kvm/arm/vgic-v2.c                 |  16 +-
>  virt/kvm/arm/vgic-v3.c                 |  21 +-
>  virt/kvm/arm/vgic.c                    | 427 +++++++++++++++++++++--
>  32 files changed, 1596 insertions(+), 544 deletions(-)
>  create mode 100644 arch/arm64/kvm/debug.c
> 


From mingo at kernel.org  Sat Aug 22 03:09:22 2015
From: mingo at kernel.org (Ingo Molnar)
Date: Sat, 22 Aug 2015 12:09:22 +0200
Subject: [PATCH 0/2] x86/KASAN updates for 4.3
In-Reply-To: <20150813172310.GK10280@arm.com>
References: <1439444244-26057-1-git-send-email-ryabinin.a.a@gmail.com>
 <20150813065040.GA17983@gmail.com>
 <20150813081641.GA14402@gmail.com> <20150813090119.GA10280@arm.com>
 <CAPAsAGxk2+v5VG77cOHAThsXyWx-_UJ1XVeJProaa0gQWH5jvA@mail.gmail.com>
 <20150813112428.GG10280@arm.com> <20150813172310.GK10280@arm.com>
Message-ID: <20150822100922.GA25039@gmail.com>


* Will Deacon <will.deacon at arm.com> wrote:

> On Thu, Aug 13, 2015 at 12:24:28PM +0100, Will Deacon wrote:
> > On Thu, Aug 13, 2015 at 12:02:26PM +0100, Andrey Ryabinin wrote:
> > > 2015-08-13 12:01 GMT+03:00 Will Deacon <will.deacon at arm.com>:
> > > > Yes please, works for me! If we're targetting 4.3, then please can you base
> > > > on 4.2-rc4, as that's what our current arm64 queue is using?
> > > >
> > > 
> > > Does this mean that we are targeting arm64 part for 4.3 too?
> > 
> > It depends on how well it merges with our current queue and whether it
> > holds up to regression testing. The patches have been reviewed, so I'm
> > comfortable with the content, but we're not at a stage where we can debug
> > and fix any failures that might crop up from the merge.
> 
> Scratch that :(
> 
> I tried this out under EFI and it dies horribly in the stub code because
> we're missing at least one KASAN_SANITIZE_ Makefile entry.
> 
> So I think this needs longer to stew before hitting mainline. By all means
> get the x86 dependencies in for 4.3, but the arm64 port can probably use
> another cycle to iron out the bugs.

Is there any known problem with the two patches in this series, or can I apply 
them?

Thanks,

	Ingo


From punnaia at xilinx.com  Sat Aug 22 03:47:36 2015
From: punnaia at xilinx.com (punnaiah choudary kalluri)
Date: Sat, 22 Aug 2015 16:17:36 +0530
Subject: [PATCH v4 1/2] Documentation: dt: Add Xilinx zynqmp dma device
 tree binding documentation
In-Reply-To: <CAAtXAHdu10dchedaApLiw6+b583z4D8Of1TAEGDmhhVLOy+8YA@mail.gmail.com>
References: <1438831173-8761-1-git-send-email-punnaia@xilinx.com>
 <CAAtXAHdu10dchedaApLiw6+b583z4D8Of1TAEGDmhhVLOy+8YA@mail.gmail.com>
Message-ID: <CAGnW=Bb=pJgdDRv_isrMC2b+z5cPwKJLhR4E0Z8=L0uCGAh0xQ@mail.gmail.com>

Hi Moritz,

  Thanks. I will take care of these suggestions in next version

Regards,
Punnaiah

On Fri, Aug 21, 2015 at 10:12 PM, Moritz Fischer
<moritz.fischer at ettus.com> wrote:
> Hi all,
>
> sorry for HTML mail spam last night ... couple of nits below
>
> On Wed, Aug 5, 2015 at 8:19 PM, Punnaiah Choudary Kalluri
> <punnaiah.choudary.kalluri at xilinx.com> wrote:
>> Device-tree binding documentation for Xilinx zynqmp dma engine used in
>> Zynq UltraScale+ MPSoC.
>>
>> Signed-off-by: Punnaiah Choudary Kalluri <punnaia at xilinx.com>
>> ---
>> Changes in v4:
>> - None
>> Changes in v3:
>> - None
>> Changes in v2:
>> - None
>> ---
>>  .../devicetree/bindings/dma/xilinx/zynqmp_dma.txt  |   61 ++++++++++++++++++++
>>  1 files changed, 61 insertions(+), 0 deletions(-)
>>  create mode 100644 Documentation/devicetree/bindings/dma/xilinx/zynqmp_dma.txt
>>
>> diff --git a/Documentation/devicetree/bindings/dma/xilinx/zynqmp_dma.txt b/Documentation/devicetree/bindings/dma/xilinx/zynqmp_dma.txt
>> new file mode 100644
>> index 0000000..e4f92b9
>> --- /dev/null
>> +++ b/Documentation/devicetree/bindings/dma/xilinx/zynqmp_dma.txt
>> @@ -0,0 +1,61 @@
>> +Xilinx ZynqMP DMA engine, it does support memory to memory transfers,
>> +memory to device and device to memory transfers. It also has flow
>> +control and rate control support for slave/peripheral dma access.
>
> How about: The Xilinx ZynqMP DMA engine does support memory to memory transfers,
> memory to device and device to memory transfers. It also has flow
> control and rate control
> support for slave / peripheral DMA access.
>> +
>> +Required properties:
>> +- compatible: Should be "xlnx,zynqmp-dma-1.0"
>> +- #dma-cells: Should be <1>, a single cell holding a line request number
>> +- reg: Memory map for module access
>> +- interrupt-parent: Interrupt controller the interrupt is routed through
>> +- interrupts: Should contain DMA channel interrupt
>> +- xlnx,bus-width: AXI buswidth in bits. Should contain 128 or 64
>> +
>> +Optional properties:
>> +- xlnx,include-sg: Indicates the controller to operate in simple or scatter
>> +                  gather dma mode
> s/dma/DMA
>> +- xlnx,ratectrl: Scheduling interval in terms of clock cycles for
>> +                source AXI transaction
>> +- xlnx,overfetch: Tells whether the channel is allowed to over fetch the data
> (Maybe) s/Tells/Determines/
>> +- xlnx,src-issue: Number of AXI outstanding transactions on source side
>> +- xlnx,desc-axi-cohrnt: Tells whether the AXI transactions generated for the
>> +                       descriptor read are marked Non-coherent
> (Maybe) s/Tells/Determines/
>> +- xlnx,src-axi-cohrnt: Tells whether the AXI transactions generated for the
>> +                       source descriptor payload are marked Non-coherent
> same
>> +- xlnx,dst-axi-cohrnt: Tells whether the AXI transactions generated for the
>> +                       dst descriptor payload are marked Non-coherent
>> +- xlnx,desc-axi-qos: AXI QOS bits to be used for descriptor fetch
>> +- xlnx,src-axi-qos: AXI QOS bits to be used for data read
>> +- xlnx,dst-axi-qos: AXI QOS bits to be used for data write
>> +- xlnx,desc-axi-cache: AXI cache bits to be used for descriptor fetch.
>> +- xlnx,desc-axi-cache: AXI cache bits to be used for data read
>> +- xlnx,desc-axi-cache: AXI cache bits to be used for data write
>> +- xlnx,src-burst-len: AXI length for data read. Support only power of 2 values
>> +                     i.e 1,2,4,8 and 16
>> +- xlnx,dst-burst-len: AXI length for data write. Support only power of 2 values
>> +                     i.e 1,2,4,8 and 16
>> +
>> +Example:
>> +++++++++
>> +fpd_dma_chan1: dma at FD500000 {
>> +       compatible = "xlnx,zynqmp-dma-1.0";
>> +       reg = <0x0 0xFD500000 0x1000>;
>> +       #dma_cells = <1>;
> #dma-cells = <1>;
>> +       interrupt-parent = <&gic>;
>> +       interrupts = <0 117 4>;
>> +       xlnx,bus-width = <128>;
>> +       xlnx,include-sg;
>> +       xlnx,overfetch;
>> +       xlnx,ratectrl = <0>;
>> +       xlnx,src-issue = <16>;
>> +       xlnx,desc-axi-cohrnt;
>> +       xlnx,src-axi-cohrnt;
>> +       xlnx,dst-axi-cohrnt;
>> +       xlnx,desc-axi-qos = <0>;
>> +       xlnx,desc-axi-cache = <0>;
>> +       xlnx,src-axi-qos = <0>;
>> +       xlnx,src-axi-cache = <2>;
>> +       xlnx,dst-axi-qos = <0>;
>> +       xlnx,dst-axi-cache = <2>;
>> +       xlnx,src-burst-len = <4>;
>> +       xlnx,dst-burst-len = <4>;
>> +};
>> --
>> 1.7.4
>>
>>
>> _______________________________________________
>> linux-arm-kernel mailing list
>> linux-arm-kernel at lists.infradead.org
>> http://lists.infradead.org/mailman/listinfo/linux-arm-kernel
>
> Cheers,
>
> Moritz


From appana.durga.rao at xilinx.com  Sat Aug 22 04:06:00 2015
From: appana.durga.rao at xilinx.com (Appana Durga Kedareswara Rao)
Date: Sat, 22 Aug 2015 11:06:00 +0000
Subject: [RESEND PATCH] dmaengine: Add Xilinx AXI Direct Memory Access
 Engine driver support
In-Reply-To: <CAAtXAHe3QjBo4_5unB32ixnOriO8Xt-1nLeddjgRgYvj5Kn_EA@mail.gmail.com>
References: <1439825512-16444-1-git-send-email-appanad@xilinx.com>
 <CAAtXAHf9S662okN1gchbD246=e4_bMFoyBMrbt5q48xm1uo_CA@mail.gmail.com>
 <C246CAC1457055469EF09E3A7AC4E11A4A4B2BBC@XAP-PVEXMBX01.xlnx.xilinx.com>
 <C246CAC1457055469EF09E3A7AC4E11A4A4B2C48@XAP-PVEXMBX01.xlnx.xilinx.com>
 <CAAtXAHe3QjBo4_5unB32ixnOriO8Xt-1nLeddjgRgYvj5Kn_EA@mail.gmail.com>
Message-ID: <C246CAC1457055469EF09E3A7AC4E11A4A4B374A@XAP-PVEXMBX01.xlnx.xilinx.com>

Hi Moritz,

	Thanks for the comments

> -----Original Message-----
> From: Moritz Fischer [mailto:moritz.fischer at ettus.com]
> Sent: Friday, August 21, 2015 6:47 AM
> To: Appana Durga Kedareswara Rao
> Cc: Appana Durga Kedareswara Rao; vinod.koul at intel.com;
> dan.j.williams at intel.com; Michal Simek; Soren Brinkmann;
> dmaengine at vger.kernel.org; linux-kernel at vger.kernel.org; linux-arm-kernel;
> Anirudha Sarangi
> Subject: Re: [RESEND PATCH] dmaengine: Add Xilinx AXI Direct Memory Access
> Engine driver support
> 
> Hi,
> 
> your MUA produces funny messages somehow ...

I have fixed it now sorry for the noise.

> The driver did not probe for me in it's current form as the bindings
> were missing interrupt parents for the interrupts...

Ok Will fix it as Michal said in the earlier mail I think there is a discussion going on it whether to have the 
Interrupt parents in the DT binding doc or not. Please let me know if it is mandatory to have interrupt parent in the 
Binding doc will send a patch for it.

> 
> On Thu, Aug 20, 2015 at 12:01 AM, Appana Durga Kedareswara Rao
> <appana.durga.rao at xilinx.com> wrote:
> > Hi ,
> >
> >> -----Original Message-----
> >> From: dmaengine-owner at vger.kernel.org [mailto:dmaengine-
> >> owner at vger.kernel.org] On Behalf Of Appana Durga Kedareswara Rao
> >> Sent: Thursday, August 20, 2015 11:11 AM
> >> To: Moritz Fischer
> >> Cc: vinod.koul at intel.com; dan.j.williams at intel.com; Michal Simek; Soren
> >> Brinkmann; anirudha at xilinx.com; dmaengine at vger.kernel.org; linux-
> >> kernel at vger.kernel.org; linux-arm-kernel
> >> Subject: RE: [RESEND PATCH] dmaengine: Add Xilinx AXI Direct Memory
> Access
> >> Engine driver support
> >>
> >> Hi Moritz Fischer,
> >>
> >>       Thanks for reviewing the patch.
> >>
> >> > -----Original Message-----
> >> > From: Moritz Fischer [mailto:moritz.fischer at ettus.com]
> >> > Sent: Thursday, August 20, 2015 3:21 AM
> >> > To: Appana Durga Kedareswara Rao
> >> > Cc: vinod.koul at intel.com; dan.j.williams at intel.com; Michal Simek;
> >> > Soren Brinkmann; Appana Durga Kedareswara Rao; anirudha at xilinx.com;
> >> > dmaengine at vger.kernel.org; linux-kernel at vger.kernel.org;
> >> > linux-arm-kernel; Srikanth Thokala
> >> > Subject: Re: [RESEND PATCH] dmaengine: Add Xilinx AXI Direct Memory
> >> > Access Engine driver support
> >> >
> >> > Hi there,
> >> >
> >> > see comment below. I just did a quick compile test. Will take another
> >> > look once I synthesized an image.
> >> >
> >> > On Mon, Aug 17, 2015 at 8:31 AM, Kedareswara rao Appana
> >> > <appana.durga.rao at xilinx.com> wrote:
> >> > > This is the driver for the AXI Direct Memory Access (AXI DMA) core,
> >> > > which is a soft Xilinx IP core that provides high- bandwidth direct
> >> > > memory access between memory and AXI4-Stream type target
> peripherals.
> >> > >
> >> > > Signed-off-by: Srikanth Thokala <sthokal at xilinx.com>
> >> > > Signed-off-by: Kedareswara rao Appana <appanad at xilinx.com>
> >> > > ---
> >> > > The deivce tree doc got applied in the slave-dmaengine.git.
> >> > >
> >> > > Forgot to include dmaengine at vger.kernel.org in the cc list resending
> >> > > the patch.
> >> > >
> >> > > Changes in v8:
> >> > > - Updated the SG handling as suggested by Nicolae Rosia.
> >> > > - Removed the unnecessary xilinx_dma_channel_set_config API the
> >> properties
> >> > >   in this API is not being used by the driver.
> >> > > Changes in v7:
> >> > > - Updated license in the driver as suggested by Paul.
> >> > > - Corrected return value in is_idle funtion.
> >> > > Changes in v6:
> >> > > - Fixed Odd indention in the Kconfig.
> >> > > - used GFP_NOWAIT instead of GFP_KERNEL during the desc allocation
> >> > > - Calculated residue in the tx_status instead of complete_descriptor.
> >> > > - Update copy right to 2015.
> >> > > - Modified spin_lock handling moved the spin_lock to the appropriate
> >> > > functions (instead of xilinx_dma_start_transfer doing it
> >> > xilinx_dma_issue_pending api).
> >> > > - device_control and declare slave caps updated as per newer APi's.
> >> > > Changes in v5:
> >> > > - Modified the xilinx_dma.h header file location to the
> >> > >   include/linux/dma/xilinx_dma.h
> >> > > Changes in v4:
> >> > > - Add direction field to DMA descriptor structure and removed from
> >> > >   channel structure to avoid duplication.
> >> > > - Check for DMA idle condition before changing the configuration.
> >> > > - Residue is being calculated in complete_descriptor() and is reported
> >> > >   to slave driver.
> >> > > Changes in v3:
> >> > > - Rebased on 3.16-rc7
> >> > > Changes in v2:
> >> > > - Simplified the logic to set SOP and APP words in prep_slave_sg().
> >> > > - Corrected function description comments to match the return type.
> >> > > - Fixed some minor comments as suggested by Andy.
> >> > >
> >> > >  drivers/dma/Kconfig             |   13 +
> >> > >  drivers/dma/xilinx/Makefile     |    1 +
> >> > >  drivers/dma/xilinx/xilinx_dma.c | 1179
> >> > > +++++++++++++++++++++++++++++++++++++++
> >> > >  3 files changed, 1193 insertions(+)  create mode 100644
> >> > > drivers/dma/xilinx/xilinx_dma.c
> >> > >
> >> > > diff --git a/drivers/dma/Kconfig b/drivers/dma/Kconfig index
> >> > > 88d474b..5e95f07 100644
> >> > > --- a/drivers/dma/Kconfig
> >> > > +++ b/drivers/dma/Kconfig
> >> > > @@ -507,4 +507,17 @@ config QCOM_BAM_DMA
> >> > >           Enable support for the QCOM BAM DMA controller.  This controller
> >> > >           provides DMA capabilities for a variety of on-chip devices.
> >> > >
> >> > > +config XILINX_DMA
> >> > > +        tristate "Xilinx AXI DMA Engine"
> >> > > +        depends on (ARCH_ZYNQ || MICROBLAZE)
> >> > > +        select DMA_ENGINE
> >> > > +        help
> >> > > +          Enable support for Xilinx AXI DMA Soft IP.
> >> > > +
> >> > > +          This engine provides high-bandwidth direct memory access
> >> > > +          between memory and AXI4-Stream type target peripherals.
> >> > > +          It has two stream interfaces/channels, Memory Mapped to
> >> > > +          Stream (MM2S) and Stream to Memory Mapped (S2MM) for the
> >> > > +          data transfers.
> >> > > +
> >> > >  endif
> >> > > diff --git a/drivers/dma/xilinx/Makefile
> >> > > b/drivers/dma/xilinx/Makefile index 3c4e9f2..6224a49 100644
> >> > > --- a/drivers/dma/xilinx/Makefile
> >> > > +++ b/drivers/dma/xilinx/Makefile
> >> > > @@ -1 +1,2 @@
> >> > >  obj-$(CONFIG_XILINX_VDMA) += xilinx_vdma.o
> >> > > +obj-$(CONFIG_XILINX_DMA) += xilinx_dma.o
> >> > > diff --git a/drivers/dma/xilinx/xilinx_dma.c
> >> > > b/drivers/dma/xilinx/xilinx_dma.c new file mode 100644 index
> >> > > 0000000..a9be197
> >> > > --- /dev/null
> >> > > +++ b/drivers/dma/xilinx/xilinx_dma.c
> >> > > @@ -0,0 +1,1179 @@
> >> > > +/*
> >> > > + * DMA driver for Xilinx DMA Engine
> >> > > + *
> >> > > + * Copyright (C) 2010 - 2015 Xilinx, Inc. All rights reserved.
> >> > > + *
> >> > > + * Based on the Freescale DMA driver.
> >> > > + *
> >> > > + * Description:
> >> > > + *  The AXI DMA, is a soft IP, which provides high-bandwidth Direct
> >> > > +Memory
> >> > > + *  Access between memory and AXI4-Stream-type target peripherals.
> >> > > +It can be
> >> > > + *  configured to have one channel or two channels and if
> >> > > +configured as two
> >> > > + *  channels, one is to transmit data from memory to a device and
> >> > > +another is
> >> > > + *  to receive from a device.
> >> > > + *
> >> > > + * This 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.
> >> > > + */
> >> > > +
> >> > > +#include <linux/bitops.h>
> >> > > +#include <linux/dma/xilinx_dma.h>
> >> > > +#include <linux/init.h>
> >> > > +#include <linux/interrupt.h>
> >> > > +#include <linux/io.h>
> >> > > +#include <linux/module.h>
> >> > > +#include <linux/of_address.h>
> >> > > +#include <linux/of_dma.h>
> >> > > +#include <linux/of_irq.h>
> >> > > +#include <linux/of_platform.h>
> >> > > +#include <linux/slab.h>
> >> > > +
> >> > > +#include "../dmaengine.h"
> >> > > +
> >> > > +/* Register Offsets */
> >> > > +#define XILINX_DMA_REG_CONTROL         0x00
> >> > > +#define XILINX_DMA_REG_STATUS          0x04
> >> > > +#define XILINX_DMA_REG_CURDESC         0x08
> >> > > +#define XILINX_DMA_REG_TAILDESC                0x10
> >> > > +#define XILINX_DMA_REG_SRCADDR         0x18
> >> > > +#define XILINX_DMA_REG_DSTADDR         0x20
> >> > > +#define XILINX_DMA_REG_BTT             0x28
> >> > > +
> >> > > +/* Channel/Descriptor Offsets */
> >> > > +#define XILINX_DMA_MM2S_CTRL_OFFSET    0x00
> >> > > +#define XILINX_DMA_S2MM_CTRL_OFFSET    0x30
> >> > > +
> >> > > +/* General register bits definitions */
> >> > > +#define XILINX_DMA_CR_RUNSTOP_MASK     BIT(0)
> >> > > +#define XILINX_DMA_CR_RESET_MASK       BIT(2)
> >> > > +
> >> > > +#define XILINX_DMA_CR_DELAY_SHIFT      24
> >> > > +#define XILINX_DMA_CR_COALESCE_SHIFT   16
> >> > > +
> >> > > +#define XILINX_DMA_CR_DELAY_MAX                GENMASK(7, 0)
> >> > > +#define XILINX_DMA_CR_COALESCE_MAX     GENMASK(7, 0)
> >> > > +
> >> > > +#define XILINX_DMA_SR_HALTED_MASK      BIT(0)
> >> > > +#define XILINX_DMA_SR_IDLE_MASK                BIT(1)
> >> > > +
> >> > > +#define XILINX_DMA_XR_IRQ_IOC_MASK     BIT(12)
> >> > > +#define XILINX_DMA_XR_IRQ_DELAY_MASK   BIT(13)
> >> > > +#define XILINX_DMA_XR_IRQ_ERROR_MASK   BIT(14)
> >> > > +#define XILINX_DMA_XR_IRQ_ALL_MASK     GENMASK(14, 12)
> >> > > +
> >> > > +/* BD definitions */
> >> > > +#define XILINX_DMA_BD_STS_ALL_MASK     GENMASK(31, 28)
> >> > > +#define XILINX_DMA_BD_SOP              BIT(27)
> >> > > +#define XILINX_DMA_BD_EOP              BIT(26)
> >> > > +
> >> > > +/* Hw specific definitions */
> >> > > +#define XILINX_DMA_MAX_CHANS_PER_DEVICE        0x2
> >> > > +#define XILINX_DMA_MAX_TRANS_LEN       GENMASK(22, 0)
> >> > > +
> >> > > +/* Delay loop counter to prevent hardware failure */
> >> > > +#define XILINX_DMA_LOOP_COUNT          1000000
> >> > > +
> >> > > +/* Maximum number of Descriptors */
> >> > > +#define XILINX_DMA_NUM_DESCS           255
> >> > > +#define XILINX_DMA_COALESCE_MAX                255
> >> > > +#define XILINX_DMA_NUM_APP_WORDS       5
> >> > > +
> >> > > +/**
> >> > > + * struct xilinx_dma_desc_hw - Hardware Descriptor
> >> > > + * @next_desc: Next Descriptor Pointer @0x00
> >> > > + * @pad1: Reserved @0x04
> >> > > + * @buf_addr: Buffer address @0x08
> >> > > + * @pad2: Reserved @0x0C
> >> > > + * @pad3: Reserved @0x10
> >> > > + * @pad4: Reserved @0x14
> >> > > + * @control: Control field @0x18
> >> > > + * @status: Status field @0x1C
> >> > > + * @app: APP Fields @0x20 - 0x30
> >> > > + */
> >> > > +struct xilinx_dma_desc_hw {
> >> > > +       u32 next_desc;
> >> > > +       u32 pad1;
> >> > > +       u32 buf_addr;
> >> > > +       u32 pad2;
> >> > > +       u32 pad3;
> >> > > +       u32 pad4;
> >> > > +       u32 control;
> >> > > +       u32 status;
> >> > > +       u32 app[XILINX_DMA_NUM_APP_WORDS]; } __aligned(64);
> >> > > +
> >> > > +/**
> >> > > + * struct xilinx_dma_tx_segment - Descriptor segment
> >> > > + * @hw: Hardware descriptor
> >> > > + * @node: Node in the descriptor segments list
> >> > > + * @phys: Physical address of segment  */ struct
> >> > > +xilinx_dma_tx_segment {
> >> > > +       struct xilinx_dma_desc_hw hw;
> >> > > +       struct list_head node;
> >> > > +       dma_addr_t phys;
> >> > > +} __aligned(64);
> >> > > +
> >> > > +/**
> >> > > + * struct xilinx_dma_tx_descriptor - Per Transaction structure
> >> > > + * @async_tx: Async transaction descriptor
> >> > > + * @segments: TX segments list
> >> > > + * @node: Node in the channel descriptors list
> >> > > + * @direction: Transfer direction
> >> > > + */
> >> > > +struct xilinx_dma_tx_descriptor {
> >> > > +       struct dma_async_tx_descriptor async_tx;
> >> > > +       struct list_head segments;
> >> > > +       struct list_head node;
> >> > > +       enum dma_transfer_direction direction; };
> >> > > +
> >> > > +/**
> >> > > + * struct xilinx_dma_chan - Driver specific DMA channel structure
> >> > > + * @xdev: Driver specific device structure
> >> > > + * @ctrl_offset: Control registers offset
> >> > > + * @ctrl_reg: Control register value
> >> > > + * @lock: Descriptor operation lock
> >> > > + * @pending_list: Descriptors waiting
> >> > > + * @active_list: Descriptors ready to submit
> >> > > + * @done_list: Complete descriptors
> >> > > + * @free_seg_list: Free descriptors
> >> > > + * @common: DMA common channel
> >> > > + * @seg_v: Statically allocated segments base
> >> > > + * @seg_p: Physical allocated segments base
> >> > > + * @dev: The dma device
> >> > > + * @irq: Channel IRQ
> >> > > + * @id: Channel ID
> >> > > + * @has_sg: Support scatter transfers
> >> > > + * @idle: Check for channel idle
> >> > > + * @err: Channel has errors
> >> > > + * @tasklet: Cleanup work after irq
> >> > > + * @residue: Residue
> >> > > + * @desc_pendingcount: Descriptor pending count  */ struct
> >> > > +xilinx_dma_chan {
> >> > > +       struct xilinx_dma_device *xdev;
> >> > > +       u32 ctrl_offset;
> >> > > +       u32 ctrl_reg;
> >> > > +       spinlock_t lock;
> >> > > +       struct list_head pending_list;
> >> > > +       struct list_head done_list;
> >> > > +       struct list_head active_list;
> >> > > +       struct list_head free_seg_list;
> >> > > +       struct dma_chan common;
> >> > > +       struct xilinx_dma_tx_segment *seg_v;
> >> > > +       dma_addr_t seg_p;
> >> > > +       struct device *dev;
> >> > > +       int irq;
> >> > > +       int id;
> >> > > +       bool has_sg;
> >> > > +       bool idle;
> >> > > +       int err;
> >> > > +       struct tasklet_struct tasklet;
> >> > > +       u32 residue;
> >> > > +       u32 desc_pendingcount;
> >> > > +};
> >> > > +
> >> > > +/**
> >> > > + * struct xilinx_dma_device - DMA device structure
> >> > > + * @regs: I/O mapped base address
> >> > > + * @dev: Device Structure
> >> > > + * @common: DMA device structure
> >> > > + * @chan: Driver specific DMA channel
> >> > > + * @has_sg: Specifies whether Scatter-Gather is present or not  */
> >> > > +struct xilinx_dma_device {
> >> > > +       void __iomem *regs;
> >> > > +       struct device *dev;
> >> > > +       struct dma_device common;
> >> > > +       struct xilinx_dma_chan
> >> *chan[XILINX_DMA_MAX_CHANS_PER_DEVICE];
> >> > > +       bool has_sg;
> >> > > +};
> >> > > +
> >> > > +/* Macros */
> >> > > +#define to_xilinx_chan(chan) \
> >> > > +       container_of(chan, struct xilinx_dma_chan, common) #define
> >> > > +to_dma_tx_descriptor(tx) \
> >> > > +       container_of(tx, struct xilinx_dma_tx_descriptor, async_tx)
> >> > > +
> >> > > +/* IO accessors */
> >> > > +static inline void dma_write(struct xilinx_dma_chan *chan, u32 reg,
> >> > > +u32 value) {
> >> > > +       iowrite32(value, chan->xdev->regs + reg);
> >> > Any reason to not use write here?
> >> Most of the Xilinx drivers and the VDMA driver that got up streamed Use
> iowrite
> >> to make consistency b/w the drivers I used the same API's.
> >>
> >> What is the advantage we will gain by using writel instead of iowrite32?
> 
> https://lkml.org/lkml/2011/1/19/158

Ok will use writel variants thanks for the pointers.

> >>
> >> > > +}
> >> > > +
> >> > > +static inline u32 dma_read(struct xilinx_dma_chan *chan, u32 reg) {
> >> > > +       return ioread32(chan->xdev->regs + reg);
> >> > Any reason to not use readl here?
> >> > > +}
> >> > > +
> >> > > +static inline u32 dma_ctrl_read(struct xilinx_dma_chan *chan, u32
> >> > > +reg) {
> >> > > +       return dma_read(chan, chan->ctrl_offset + reg); }
> >> > > +
> >> > > +static inline void dma_ctrl_write(struct xilinx_dma_chan *chan, u32 reg,
> >> > > +                                 u32 value) {
> >> > > +       dma_write(chan, chan->ctrl_offset + reg, value); }
> >> > > +
> >> > > +/*
> >> > > +-------------------------------------------------------------------
> >> > > +--
> >> > > +--------
> >> > > + * Descriptors and segments alloc and free  */
> >> > > +
> >> > > +/**
> >> > > + * xilinx_dma_alloc_tx_segment - Allocate transaction segment
> >> > > + * @chan: Driver specific dma channel
> >> > > + *
> >> > > + * Return: The allocated segment on success and NULL on failure.
> >> > > + */
> >> > > +static struct xilinx_dma_tx_segment *
> >> > > +xilinx_dma_alloc_tx_segment(struct xilinx_dma_chan *chan) {
> >> > > +       struct xilinx_dma_tx_segment *segment = NULL;
> >> > > +       unsigned long flags;
> >> > > +
> >> > > +       spin_lock_irqsave(&chan->lock, flags);
> >> > > +       if (!list_empty(&chan->free_seg_list)) {
> >> > > +               segment = list_first_entry(&chan->free_seg_list,
> >> > > +                                          struct xilinx_dma_tx_segment,
> >> > > +                                          node);
> >> > > +               list_del(&segment->node);
> >> > > +       }
> >> > > +       spin_unlock_irqrestore(&chan->lock, flags);
> >> > > +
> >> > > +       return segment;
> >> > > +}
> >> > > +
> >> > > +/**
> >> > > + * xilinx_dma_clean_hw_desc - Clean hardware descriptor
> >> > > + * @hw: HW descriptor to clean
> >> > > + */
> >> > > +static void xilinx_dma_clean_hw_desc(struct xilinx_dma_desc_hw *hw) {
> >> > > +       u32 next_desc = hw->next_desc;
> >> > > +
> >> > > +       memset(hw, 0, sizeof(struct xilinx_dma_desc_hw));
> >> > > +
> >> > > +       hw->next_desc = next_desc;
> >> > > +}
> >> > > +
> >> > > +/**
> >> > > + * xilinx_dma_free_tx_segment - Free transaction segment
> >> > > + * @chan: Driver specific dma channel
> >> > > + * @segment: dma transaction segment  */ static void
> >> > > +xilinx_dma_free_tx_segment(struct xilinx_dma_chan *chan,
> >> > > +                                      struct xilinx_dma_tx_segment
> >> > > +*segment) {
> >> > > +       xilinx_dma_clean_hw_desc(&segment->hw);
> >> > > +
> >> > > +       list_add_tail(&segment->node, &chan->free_seg_list); }
> >> > > +
> >> > > +/**
> >> > > + * xilinx_dma_tx_descriptor - Allocate transaction descriptor
> >> > > + * @chan: Driver specific dma channel
> >> > > + *
> >> > > + * Return: The allocated descriptor on success and NULL on failure.
> >> > > + */
> >> > > +static struct xilinx_dma_tx_descriptor *
> >> > > +xilinx_dma_alloc_tx_descriptor(struct xilinx_dma_chan *chan) {
> >> > > +       struct xilinx_dma_tx_descriptor *desc;
> >> > > +
> >> > > +       desc = kzalloc(sizeof(*desc), GFP_NOWAIT);
> >> > > +       if (!desc)
> >> > > +               return NULL;
> >> > > +
> >> > > +       INIT_LIST_HEAD(&desc->segments);
> >> > > +
> >> > > +       return desc;
> >> > > +}
> >> > > +
> >> > > +/**
> >> > > + * xilinx_dma_free_tx_descriptor - Free transaction descriptor
> >> > > + * @chan: Driver specific dma channel
> >> > > + * @desc: dma transaction descriptor  */ static void
> >> > > +xilinx_dma_free_tx_descriptor(struct xilinx_dma_chan *chan,
> >> > > +                             struct xilinx_dma_tx_descriptor *desc) {
> >> > > +       struct xilinx_dma_tx_segment *segment, *next;
> >> > > +
> >> > > +       if (!desc)
> >> > > +               return;
> >> > > +
> >> > > +       list_for_each_entry_safe(segment, next, &desc->segments, node) {
> >> > > +               list_del(&segment->node);
> >> > > +               xilinx_dma_free_tx_segment(chan, segment);
> >> > > +       }
> >> > > +
> >> > > +       kfree(desc);
> >> > > +}
> >> > > +
> >> > > +/**
> >> > > + * xilinx_dma_alloc_chan_resources - Allocate channel resources
> >> > > + * @dchan: DMA channel
> >> > > + *
> >> > > + * Return: '0' on success and failure value on error  */ static int
> >> > > +xilinx_dma_alloc_chan_resources(struct dma_chan *dchan) {
> >> > > +       struct xilinx_dma_chan *chan = to_xilinx_chan(dchan);
> >> > > +       int i;
> >> > > +
> >> > > +       /* Allocate the buffer descriptors. */
> >> > > +       chan->seg_v = dma_zalloc_coherent(chan->dev,
> >> > > +                                         sizeof(*chan->seg_v) *
> >> > > +                                         XILINX_DMA_NUM_DESCS,
> >> > > +                                         &chan->seg_p, GFP_KERNEL);
> >> > > +       if (!chan->seg_v) {
> >> > > +               dev_err(chan->dev,
> >> > > +                       "unable to allocate channel %d descriptors\n",
> >> > > +                       chan->id);
> >> > > +               return -ENOMEM;
> >> > > +       }
> >> > > +
> >> > > +       for (i = 0; i < XILINX_DMA_NUM_DESCS; i++) {
> >> > > +               chan->seg_v[i].hw.next_desc =
> >> > > +                               chan->seg_p + sizeof(*chan->seg_v) *
> >> > > +                               ((i + 1) % XILINX_DMA_NUM_DESCS);
> >> > > +               chan->seg_v[i].phys =
> >> > > +                               chan->seg_p + sizeof(*chan->seg_v) * i;
> >> > > +               list_add_tail(&chan->seg_v[i].node, &chan->free_seg_list);
> >> > > +       }
> >> > > +
> >> > > +       dma_cookie_init(dchan);
> >> > > +
> >> > > +       /* Enable interrupts */
> >> > > +       chan->ctrl_reg |= XILINX_DMA_XR_IRQ_ALL_MASK;
> >> > > +       dma_ctrl_write(chan, XILINX_DMA_REG_CONTROL,
> >> > > + chan->ctrl_reg);
> >> > > +
> >> > > +       return 0;
> >> > > +}
> >> > > +
> >> > > +/**
> >> > > + * xilinx_dma_free_desc_list - Free descriptors list
> >> > > + * @chan: Driver specific dma channel
> >> > > + * @list: List to parse and delete the descriptor  */ static void
> >> > > +xilinx_dma_free_desc_list(struct xilinx_dma_chan *chan,
> >> > > +                                     struct list_head *list) {
> >> > > +       struct xilinx_dma_tx_descriptor *desc, *next;
> >> > > +
> >> > > +       list_for_each_entry_safe(desc, next, list, node) {
> >> > > +               list_del(&desc->node);
> >> > > +               xilinx_dma_free_tx_descriptor(chan, desc);
> >> > > +       }
> >> > > +}
> >> > > +
> >> > > +/**
> >> > > + * xilinx_dma_free_descriptors - Free channel descriptors
> >> > > + * @chan: Driver specific dma channel  */ static void
> >> > > +xilinx_dma_free_descriptors(struct xilinx_dma_chan *chan) {
> >> > > +       unsigned long flags;
> >> > > +
> >> > > +       spin_lock_irqsave(&chan->lock, flags);
> >> > > +
> >> > > +       xilinx_dma_free_desc_list(chan, &chan->pending_list);
> >> > > +       xilinx_dma_free_desc_list(chan, &chan->done_list);
> >> > > +       xilinx_dma_free_desc_list(chan, &chan->active_list);
> >> > > +
> >> > > +       spin_unlock_irqrestore(&chan->lock, flags); }
> >> > > +
> >> > > +/**
> >> > > + * xilinx_dma_free_chan_resources - Free channel resources
> >> > > + * @dchan: DMA channel
> >> > > + */
> >> > > +static void xilinx_dma_free_chan_resources(struct dma_chan *dchan) {
> >> > > +       struct xilinx_dma_chan *chan = to_xilinx_chan(dchan);
> >> > > +
> >> > > +       xilinx_dma_free_descriptors(chan);
> >> > > +
> >> > > +       dma_free_coherent(chan->dev,
> >> > > +                         sizeof(*chan->seg_v) * XILINX_DMA_NUM_DESCS,
> >> > > +                         chan->seg_v, chan->seg_p); }
> >> > > +
> >> > > +/**
> >> > > + * xilinx_dma_chan_desc_cleanup - Clean channel descriptors
> >> > > + * @chan: Driver specific dma channel  */ static void
> >> > > +xilinx_dma_chan_desc_cleanup(struct xilinx_dma_chan *chan) {
> >> > > +       struct xilinx_dma_tx_descriptor *desc;
> >> > > +       unsigned long flags;
> >> > > +
> >> > > +       spin_lock_irqsave(&chan->lock, flags);
> >> > > +
> >> > > +       while (!list_empty(&chan->done_list)) {
> >> > > +               dma_async_tx_callback callback;
> >> > > +               void *callback_param;
> >> > > +
> >> > > +               desc = list_first_entry(&chan->done_list,
> >> > > +                       struct xilinx_dma_tx_descriptor, node);
> >> > > +
> >> > > +               /* Remove from the list of running transactions */
> >> > > +               list_del(&desc->node);
> >> > > +
> >> > > +               /* Run the link descriptor callback function */
> >> > > +               callback = desc->async_tx.callback;
> >> > > +               callback_param = desc->async_tx.callback_param;
> >> > > +               if (callback) {
> >> > > +                       spin_unlock_irqrestore(&chan->lock, flags);
> >> > > +                       callback(callback_param);
> >> > > +                       spin_lock_irqsave(&chan->lock, flags);
> >> > > +               }
> >> > > +
> >> > > +               /* Run any dependencies, then free the descriptor */
> >> > > +               dma_run_dependencies(&desc->async_tx);
> >> > > +               xilinx_dma_free_tx_descriptor(chan, desc);
> >> > > +       }
> >> > > +
> >> > > +       spin_unlock_irqrestore(&chan->lock, flags); }
> >> > > +
> >> > > +/**
> >> > > + * xilinx_dma_tx_status - Get dma transaction status
> >> > > + * @dchan: DMA channel
> >> > > + * @cookie: Transaction identifier
> >> > > + * @txstate: Transaction state
> >> > > + *
> >> > > + * Return: DMA transaction status
> >> > > + */
> >> > > +static enum dma_status xilinx_dma_tx_status(struct dma_chan *dchan,
> >> > > +                                           dma_cookie_t cookie,
> >> > > +                                           struct dma_tx_state
> >> > > +*txstate) {
> >> > > +       struct xilinx_dma_chan *chan = to_xilinx_chan(dchan);
> >> > > +       struct xilinx_dma_tx_descriptor *desc;
> >> > > +       struct xilinx_dma_tx_segment *segment;
> >> > > +       struct xilinx_dma_desc_hw *hw;
> >> > > +       enum dma_status ret;
> >> > > +       unsigned long flags;
> >> > > +       u32 residue;
> >> >
> >> > While compiling this threw a residue may be used uninitialized
> >> > warning, I suppose 0 would be a sensible default value?
> >>
> >> Ok will fix it.
> >>
> >> > > +
> >> > > +       ret = dma_cookie_status(dchan, cookie, txstate);
> >> > > +       if (ret == DMA_COMPLETE || !txstate)
> >> > > +               return ret;
> >> > > +
> >> > > +       desc = list_last_entry(&chan->active_list,
> >> > > +                              struct xilinx_dma_tx_descriptor,
> >> > > + node);
> >> > > +
> >> > > +       spin_lock_irqsave(&chan->lock, flags);
> >> > > +       if (chan->has_sg) {
> >> > > +               while (!list_empty(&desc->segments)) {
> >> > > +                       segment = list_first_entry(&desc->segments,
> >> > > +                                       struct xilinx_dma_tx_segment, node);
> >> > > +                       hw = &segment->hw;
> >> > > +                       residue += (hw->control - hw->status) &
> >> > > +                                  XILINX_DMA_MAX_TRANS_LEN;
> >> > > +               }
> >> > > +       }
> >> > > +
> >> > > +       chan->residue = residue;
> >> > > +       dma_set_residue(txstate, chan->residue);
> >> > > +       spin_unlock_irqrestore(&chan->lock, flags);
> >> > > +
> >> > > +       return ret;
> >> > > +}
> >> > > +
> >> > > +/**
> >> > > + * xilinx_dma_halt - Halt DMA channel
> >> > > + * @chan: Driver specific DMA channel  */ static void
> >> > > +xilinx_dma_halt(struct xilinx_dma_chan *chan) {
> >> > > +       int loop = XILINX_DMA_LOOP_COUNT;
> >> > > +
> >> > > +       chan->ctrl_reg &= ~XILINX_DMA_CR_RUNSTOP_MASK;
> >> > > +       dma_ctrl_write(chan, XILINX_DMA_REG_CONTROL,
> >> > > + chan->ctrl_reg);
> >> > > +
> >> > > +       /* Wait for the hardware to halt */
> >> > > +       do {
> >> > > +               if (dma_ctrl_read(chan, XILINX_DMA_REG_STATUS) &
> >> > > +                       XILINX_DMA_SR_HALTED_MASK)
> >> > > +                       break;
> >> > > +       } while (loop--);
> >> > > +
> >> > > +       if (!loop) {
> >> > > +               dev_err(chan->dev, "Cannot stop channel %p: %x\n",
> >> > > +                       chan, dma_ctrl_read(chan, XILINX_DMA_REG_STATUS));
> >> > > +               chan->err = true;
> >> > > +       }
> >> > > +}
> >> > > +
> >> > > +/**
> >> > > + * xilinx_dma_start - Start DMA channel
> >> > > + * @chan: Driver specific DMA channel  */ static void
> >> > > +xilinx_dma_start(struct xilinx_dma_chan *chan) {
> >> > > +       int loop = XILINX_DMA_LOOP_COUNT;
> >> > > +
> >> > > +       chan->ctrl_reg |= XILINX_DMA_CR_RUNSTOP_MASK;
> >> > > +       dma_ctrl_write(chan, XILINX_DMA_REG_CONTROL,
> >> > > + chan->ctrl_reg);
> >> > > +
> >> > > +       /* Wait for the hardware to start */
> >> > > +       do {
> >> > > +               if (!dma_ctrl_read(chan, XILINX_DMA_REG_STATUS) &
> >> > > +                       XILINX_DMA_SR_HALTED_MASK)
> >> > > +                       break;
> >> > > +       } while (loop--);
> >> > Maybe use one of the readx_poll_timeout functions?
> >>
> >> Ok will fix it.
> >
> > Seems to be the readx_poll_timeout api is not suits for my driver requirement.
> > The API has some limitations when I try to use this API the code looks ugly.
> >
> > The issue that I am facing is:
> > The readx_poll_timeout API 1st argument is expecting only the address
> (https://lwn.net/Articles/626525/).
> > But in my case I need to pass the channel info and a particular offset in the
> channel.
> > If I pass all these info in the API's where I am using readx_poll_timeout the
> code looks ugly.
> >
> > Do you have any other suggestions?
> 
> How about:
> #define xilinx_dma_poll_timeout(chan, reg, val, cond, delay_us, timeout_us) \
>     readl_poll_timeout(chan->xdev->regs + reg, val, cond, delay_us, timeout_us)

Ok sure will fix it in the next version of the patch.

Regards,
Kedar.

> >
> > Regards,
> > Kedar.
> >
> >>
> >> > > +
> >> > > +       if (!loop) {
> >> > > +               dev_err(chan->dev, "Cannot start channel %p: %x\n",
> >> > > +                        chan, dma_ctrl_read(chan, XILINX_DMA_REG_STATUS));
> >> > > +               chan->err = true;
> >> > > +       }
> >> > > +}
> >> > > +
> >> > > +/**
> >> > > + * xilinx_dma_start_transfer - Starts DMA transfer
> >> > > + * @chan: Driver specific channel struct pointer  */ static void
> >> > > +xilinx_dma_start_transfer(struct xilinx_dma_chan *chan) {
> >> > > +       struct xilinx_dma_tx_descriptor *head_desc, *tail_desc;
> >> > > +       struct xilinx_dma_tx_segment *tail_segment;
> >> > > +
> >> > > +       if (chan->err)
> >> > > +               return;
> >> > > +
> >> > > +       if (list_empty(&chan->pending_list))
> >> > > +               return;
> >> > > +
> >> > > +       if (!chan->idle)
> >> > > +               return;
> >> > > +
> >> > > +       head_desc = list_first_entry(&chan->pending_list,
> >> > > +                                    struct xilinx_dma_tx_descriptor, node);
> >> > > +       tail_desc = list_last_entry(&chan->pending_list,
> >> > > +                                   struct xilinx_dma_tx_descriptor, node);
> >> > > +       tail_segment = list_last_entry(&tail_desc->segments,
> >> > > +                                      struct xilinx_dma_tx_segment,
> >> > > + node);
> >> > > +
> >> > > +       if (chan->desc_pendingcount <= XILINX_DMA_COALESCE_MAX) {
> >> > > +               chan->ctrl_reg &= ~XILINX_DMA_CR_COALESCE_MAX;
> >> > > +               chan->ctrl_reg |= chan->desc_pendingcount <<
> >> > > +                                 XILINX_DMA_CR_COALESCE_SHIFT;
> >> > > +               dma_ctrl_write(chan, XILINX_DMA_REG_CONTROL, chan-
> >> >ctrl_reg);
> >> > > +       }
> >> > > +
> >> > > +       if (chan->has_sg)
> >> > > +               dma_ctrl_write(chan, XILINX_DMA_REG_CURDESC,
> >> > > +                              head_desc->async_tx.phys);
> >> > > +
> >> > > +       xilinx_dma_start(chan);
> >> > > +
> >> > > +       if (chan->err)
> >> > > +               return;
> >> > > +
> >> > > +       /* Start the transfer */
> >> > > +       if (chan->has_sg) {
> >> > > +               dma_ctrl_write(chan, XILINX_DMA_REG_TAILDESC,
> >> > > +                              tail_segment->phys);
> >> > > +       } else {
> >> > > +               struct xilinx_dma_tx_segment *segment;
> >> > > +               struct xilinx_dma_desc_hw *hw;
> >> > > +
> >> > > +               segment = list_first_entry(&head_desc->segments,
> >> > > +                                          struct xilinx_dma_tx_segment, node);
> >> > > +               hw = &segment->hw;
> >> > > +
> >> > > +               if (head_desc->direction == DMA_MEM_TO_DEV)
> >> > > +                       dma_ctrl_write(chan, XILINX_DMA_REG_SRCADDR,
> >> > > +                                      hw->buf_addr);
> >> > > +               else
> >> > > +                       dma_ctrl_write(chan, XILINX_DMA_REG_DSTADDR,
> >> > > +                                      hw->buf_addr);
> >> > > +
> >> > > +               /* Start the transfer */
> >> > > +               dma_ctrl_write(chan, XILINX_DMA_REG_BTT,
> >> > > +                              hw->control & XILINX_DMA_MAX_TRANS_LEN);
> >> > > +       }
> >> > > +
> >> > > +       list_splice_tail_init(&chan->pending_list, &chan->active_list);
> >> > > +       chan->desc_pendingcount = 0;
> >> > > +       chan->idle = false;
> >> > > +}
> >> > > +
> >> > > +/**
> >> > > + * xilinx_dma_issue_pending - Issue pending transactions
> >> > > + * @dchan: DMA channel
> >> > > + */
> >> > > +static void xilinx_dma_issue_pending(struct dma_chan *dchan) {
> >> > > +       struct xilinx_dma_chan *chan = to_xilinx_chan(dchan);
> >> > > +       unsigned long flags;
> >> > > +
> >> > > +       spin_lock_irqsave(&chan->lock, flags);
> >> > > +       xilinx_dma_start_transfer(chan);
> >> > > +       spin_unlock_irqrestore(&chan->lock, flags); }
> >> > > +
> >> > > +/**
> >> > > + * xilinx_dma_complete_descriptor - Mark the active descriptor as
> >> > > +complete
> >> > > + * @chan : xilinx DMA channel
> >> > > + */
> >> > > +static void xilinx_dma_complete_descriptor(struct xilinx_dma_chan
> >> > > +*chan) {
> >> > > +       struct xilinx_dma_tx_descriptor *desc, *next;
> >> > > +
> >> > > +       if (list_empty(&chan->active_list))
> >> > > +               return;
> >> > > +
> >> > > +       list_for_each_entry_safe(desc, next, &chan->active_list, node) {
> >> > > +               list_del(&desc->node);
> >> > > +               dma_cookie_complete(&desc->async_tx);
> >> > > +               list_add_tail(&desc->node, &chan->done_list);
> >> > > +       }
> >> > > +}
> >> > > +
> >> > > +/**
> >> > > + * xilinx_dma_reset - Reset DMA channel
> >> > > + * @chan: Driver specific DMA channel
> >> > > + *
> >> > > + * Return: '0' on success and failure value on error  */ static int
> >> > > +xilinx_dma_chan_reset(struct xilinx_dma_chan *chan) {
> >> > > +       int loop = XILINX_DMA_LOOP_COUNT;
> >> > > +       u32 tmp;
> >> > > +
> >> > > +       chan->ctrl_reg = dma_ctrl_read(chan,
> XILINX_DMA_REG_CONTROL);
> >> > > +       dma_ctrl_write(chan, XILINX_DMA_REG_CONTROL, chan->ctrl_reg |
> >> > > +                      XILINX_DMA_CR_RESET_MASK);
> >> > > +
> >> > > +       tmp = dma_ctrl_read(chan, XILINX_DMA_REG_CONTROL) &
> >> > > +             XILINX_DMA_CR_RESET_MASK;
> >> > > +
> >> > > +       /* Wait for the hardware to finish reset */
> >> > > +       do {
> >> > > +               tmp = dma_ctrl_read(chan, XILINX_DMA_REG_CONTROL) &
> >> > > +                     XILINX_DMA_CR_RESET_MASK;
> >> > > +       } while (loop-- && tmp);
> >> > See above
> >>
> >> Ok will fix it.
> >>
> >> Regards,
> >> Kedar.
> >>
> >> > > +
> >> > > +       if (!loop) {
> >> > > +               dev_err(chan->dev, "reset timeout, cr %x, sr %x\n",
> >> > > +                       dma_ctrl_read(chan, XILINX_DMA_REG_CONTROL),
> >> > > +                       dma_ctrl_read(chan, XILINX_DMA_REG_STATUS));
> >> > > +               return -EBUSY;
> >> > > +       }
> >> > > +
> >> > > +       chan->err = false;
> >> > > +
> >> > > +       return 0;
> >> > > +}
> >> > > +
> >> > > +/**
> >> > > + * xilinx_dma_irq_handler - DMA Interrupt handler
> >> > > + * @irq: IRQ number
> >> > > + * @data: Pointer to the Xilinx DMA channel structure
> >> > > + *
> >> > > + * Return: IRQ_HANDLED/IRQ_NONE
> >> > > + */
> >> > > +static irqreturn_t xilinx_dma_irq_handler(int irq, void *data) {
> >> > > +       struct xilinx_dma_chan *chan = data;
> >> > > +       u32 status;
> >> > > +
> >> > > +       /* Read the status and ack the interrupts. */
> >> > > +       status = dma_ctrl_read(chan, XILINX_DMA_REG_STATUS);
> >> > > +       if (!(status & XILINX_DMA_XR_IRQ_ALL_MASK))
> >> > > +               return IRQ_NONE;
> >> > > +
> >> > > +       dma_ctrl_write(chan, XILINX_DMA_REG_STATUS,
> >> > > +                      status & XILINX_DMA_XR_IRQ_ALL_MASK);
> >> > > +
> >> > > +       if (status & XILINX_DMA_XR_IRQ_ERROR_MASK) {
> >> > > +               dev_err(chan->dev,
> >> > > +                       "Channel %p has errors %x, cdr %x tdr %x\n",
> >> > > +                       chan, dma_ctrl_read(chan, XILINX_DMA_REG_STATUS),
> >> > > +                       dma_ctrl_read(chan, XILINX_DMA_REG_CURDESC),
> >> > > +                       dma_ctrl_read(chan, XILINX_DMA_REG_TAILDESC));
> >> > > +               chan->err = true;
> >> > > +       }
> >> > > +
> >> > > +       /*
> >> > > +        * Device takes too long to do the transfer when user requires
> >> > > +        * responsiveness
> >> > > +        */
> >> > > +       if (status & XILINX_DMA_XR_IRQ_DELAY_MASK)
> >> > > +               dev_dbg(chan->dev, "Inter-packet latency too
> >> > > + long\n");
> >> > > +
> >> > > +       if (status & XILINX_DMA_XR_IRQ_IOC_MASK) {
> >> > > +               spin_lock(&chan->lock);
> >> > > +               xilinx_dma_complete_descriptor(chan);
> >> > > +               chan->idle = true;
> >> > > +               xilinx_dma_start_transfer(chan);
> >> > > +               spin_unlock(&chan->lock);
> >> > > +       }
> >> > > +
> >> > > +       tasklet_schedule(&chan->tasklet);
> >> > > +       return IRQ_HANDLED;
> >> > > +}
> >> > > +
> >> > > +/**
> >> > > + * xilinx_dma_do_tasklet - Schedule completion tasklet
> >> > > + * @data: Pointer to the Xilinx dma channel structure  */ static
> >> > > +void xilinx_dma_do_tasklet(unsigned long data) {
> >> > > +       struct xilinx_dma_chan *chan = (struct xilinx_dma_chan
> >> > > +*)data;
> >> > > +
> >> > > +       xilinx_dma_chan_desc_cleanup(chan);
> >> > > +}
> >> > > +
> >> > > +/**
> >> > > + * append_desc_queue - Queuing descriptor
> >> > > + * @chan: Driver specific dma channel
> >> > > + * @desc: dma transaction descriptor  */ static void
> >> > > +append_desc_queue(struct xilinx_dma_chan *chan,
> >> > > +                             struct xilinx_dma_tx_descriptor *desc) {
> >> > > +       struct xilinx_dma_tx_segment *tail_segment;
> >> > > +       struct xilinx_dma_tx_descriptor *tail_desc;
> >> > > +
> >> > > +       if (list_empty(&chan->pending_list))
> >> > > +               goto append;
> >> > > +
> >> > > +       /*
> >> > > +        * Add the hardware descriptor to the chain of hardware descriptors
> >> > > +        * that already exists in memory.
> >> > > +        */
> >> > > +       tail_desc = list_last_entry(&chan->pending_list,
> >> > > +                                   struct xilinx_dma_tx_descriptor, node);
> >> > > +       tail_segment = list_last_entry(&tail_desc->segments,
> >> > > +                                      struct xilinx_dma_tx_segment, node);
> >> > > +       tail_segment->hw.next_desc = (u32)desc->async_tx.phys;
> >> > > +
> >> > > +       /*
> >> > > +        * Add the software descriptor and all children to the list
> >> > > +        * of pending transactions
> >> > > +        */
> >> > > +append:
> >> > > +       list_add_tail(&desc->node, &chan->pending_list);
> >> > > +       chan->desc_pendingcount++;
> >> > > +
> >> > > +       if (unlikely(chan->desc_pendingcount >
> XILINX_DMA_COALESCE_MAX))
> >> {
> >> > > +               dev_dbg(chan->dev, "desc pendingcount is too high\n");
> >> > > +               chan->desc_pendingcount = XILINX_DMA_COALESCE_MAX;
> >> > > +               BUG();
> >> > > +       }
> >> > > +}
> >> > > +
> >> > > +/**
> >> > > + * xilinx_dma_tx_submit - Submit DMA transaction
> >> > > + * @tx: Async transaction descriptor
> >> > > + *
> >> > > + * Return: cookie value on success and failure value on error  */
> >> > > +static dma_cookie_t xilinx_dma_tx_submit(struct
> >> > > +dma_async_tx_descriptor *tx) {
> >> > > +       struct xilinx_dma_tx_descriptor *desc = to_dma_tx_descriptor(tx);
> >> > > +       struct xilinx_dma_chan *chan = to_xilinx_chan(tx->chan);
> >> > > +       dma_cookie_t cookie;
> >> > > +       unsigned long flags;
> >> > > +       int err;
> >> > > +
> >> > > +       if (chan->err) {
> >> > > +               /*
> >> > > +                * If reset fails, need to hard reset the system.
> >> > > +                * Channel is no longer functional
> >> > > +                */
> >> > > +               err = xilinx_dma_chan_reset(chan);
> >> > > +               if (err < 0)
> >> > > +                       return err;
> >> > > +       }
> >> > > +
> >> > > +       spin_lock_irqsave(&chan->lock, flags);
> >> > > +
> >> > > +       cookie = dma_cookie_assign(tx);
> >> > > +
> >> > > +       /* Put this transaction onto the tail of the pending queue */
> >> > > +       append_desc_queue(chan, desc);
> >> > > +
> >> > > +       spin_unlock_irqrestore(&chan->lock, flags);
> >> > > +
> >> > > +       return cookie;
> >> > > +}
> >> > > +
> >> > > +/**
> >> > > + * xilinx_dma_prep_slave_sg - prepare descriptors for a DMA_SLAVE
> >> > > +transaction
> >> > > + * @dchan: DMA channel
> >> > > + * @sgl: scatterlist to transfer to/from
> >> > > + * @sg_len: number of entries in @scatterlist
> >> > > + * @direction: DMA direction
> >> > > + * @flags: transfer ack flags
> >> > > + * @context: APP words of the descriptor
> >> > > + *
> >> > > + * Return: Async transaction descriptor on success and NULL on
> >> > > +failure  */ static struct dma_async_tx_descriptor
> >> > > +*xilinx_dma_prep_slave_sg(
> >> > > +       struct dma_chan *dchan, struct scatterlist *sgl, unsigned int sg_len,
> >> > > +       enum dma_transfer_direction direction, unsigned long flags,
> >> > > +       void *context)
> >> > > +{
> >> > > +       struct xilinx_dma_chan *chan = to_xilinx_chan(dchan);
> >> > > +       struct xilinx_dma_tx_descriptor *desc;
> >> > > +       struct xilinx_dma_tx_segment *segment;
> >> > > +       u32 *app_w = (u32 *)context;
> >> > > +       struct scatterlist *sg;
> >> > > +       size_t copy, sg_used;
> >> > > +       int i;
> >> > > +
> >> > > +       if (!is_slave_direction(direction))
> >> > > +               return NULL;
> >> > > +
> >> > > +       /* Allocate a transaction descriptor. */
> >> > > +       desc = xilinx_dma_alloc_tx_descriptor(chan);
> >> > > +       if (!desc)
> >> > > +               return NULL;
> >> > > +
> >> > > +       desc->direction = direction;
> >> > > +       dma_async_tx_descriptor_init(&desc->async_tx, &chan->common);
> >> > > +       desc->async_tx.tx_submit = xilinx_dma_tx_submit;
> >> > > +
> >> > > +       /* Build transactions using information in the scatter gather list */
> >> > > +       for_each_sg(sgl, sg, sg_len, i) {
> >> > > +               sg_used = 0;
> >> > > +
> >> > > +               /* Loop until the entire scatterlist entry is used */
> >> > > +               while (sg_used < sg_dma_len(sg)) {
> >> > > +                       struct xilinx_dma_desc_hw *hw;
> >> > > +
> >> > > +                       /* Get a free segment */
> >> > > +                       segment = xilinx_dma_alloc_tx_segment(chan);
> >> > > +                       if (!segment)
> >> > > +                               goto error;
> >> > > +
> >> > > +                       /*
> >> > > +                        * Calculate the maximum number of bytes to transfer,
> >> > > +                        * making sure it is less than the hw limit
> >> > > +                        */
> >> > > +                       copy = min_t(size_t, sg_dma_len(sg) - sg_used,
> >> > > +                                    XILINX_DMA_MAX_TRANS_LEN);
> >> > > +                       hw = &segment->hw;
> >> > > +
> >> > > +                       /* Fill in the descriptor */
> >> > > +                       hw->buf_addr = sg_dma_address(sg) + sg_used;
> >> > > +
> >> > > +                       hw->control = copy;
> >> > > +
> >> > > +                       if (direction == DMA_MEM_TO_DEV) {
> >> > > +                               if (app_w)
> >> > > +                                       memcpy(hw->app, app_w, sizeof(u32) *
> >> > > +                                              XILINX_DMA_NUM_APP_WORDS);
> >> > > +                       }
> >> > > +
> >> > > +                       sg_used += copy;
> >> > > +
> >> > > +                       /*
> >> > > +                        * Insert the segment into the descriptor segments
> >> > > +                        * list.
> >> > > +                        */
> >> > > +                       list_add_tail(&segment->node, &desc->segments);
> >> > > +               }
> >> > > +       }
> >> > > +
> >> > > +       segment = list_first_entry(&desc->segments,
> >> > > +                                  struct xilinx_dma_tx_segment, node);
> >> > > +       desc->async_tx.phys = segment->phys;
> >> > > +
> >> > > +       /* For the last DMA_MEM_TO_DEV transfer, set EOP */
> >> > > +       if (direction == DMA_MEM_TO_DEV) {
> >> > > +               segment->hw.control |= XILINX_DMA_BD_SOP;
> >> > > +               segment = list_last_entry(&desc->segments,
> >> > > +                                         struct xilinx_dma_tx_segment,
> >> > > +                                         node);
> >> > > +               segment->hw.control |= XILINX_DMA_BD_EOP;
> >> > > +       }
> >> > > +
> >> > > +       return &desc->async_tx;
> >> > > +
> >> > > +error:
> >> > > +       xilinx_dma_free_tx_descriptor(chan, desc);
> >> > > +       return NULL;
> >> > > +}
> >> > > +
> >> > > +/**
> >> > > + * xilinx_dma_terminate_all - Halt the channel and free descriptors
> >> > > + * @dchan: DMA Channel pointer
> >> > > + *
> >> > > + * Return: '0' always
> >> > > + */
> >> > > +static int xilinx_dma_terminate_all(struct dma_chan *dchan) {
> >> > > +       struct xilinx_dma_chan *chan = to_xilinx_chan(dchan);
> >> > > +
> >> > > +       /* Halt the DMA engine */
> >> > > +       xilinx_dma_halt(chan);
> >> > > +
> >> > > +       /* Remove and free all of the descriptors in the lists */
> >> > > +       xilinx_dma_free_descriptors(chan);
> >> > > +
> >> > > +       return 0;
> >> > > +}
> >> > > +
> >> > > +/**
> >> > > + * xilinx_dma_chan_remove - Per Channel remove function
> >> > > + * @chan: Driver specific DMA channel  */ static void
> >> > > +xilinx_dma_chan_remove(struct xilinx_dma_chan *chan) {
> >> > > +       /* Disable interrupts */
> >> > > +       chan->ctrl_reg &= ~XILINX_DMA_XR_IRQ_ALL_MASK;
> >> > > +       dma_ctrl_write(chan, XILINX_DMA_REG_CONTROL,
> >> > > +chan->ctrl_reg);
> >> > > +
> >> > > +       if (chan->irq > 0)
> >> > > +               free_irq(chan->irq, chan);
> >> > > +
> >> > > +       tasklet_kill(&chan->tasklet);
> >> > > +
> >> > > +       list_del(&chan->common.device_node);
> >> > > +}
> >> > > +
> >> > > +/**
> >> > > + * xilinx_dma_chan_probe - Per Channel Probing
> >> > > + * It get channel features from the device tree entry and
> >> > > + * initialize special channel handling routines
> >> > > + *
> >> > > + * @xdev: Driver specific device structure
> >> > > + * @node: Device node
> >> > > + *
> >> > > + * Return: '0' on success and failure value on error  */ static int
> >> > > +xilinx_dma_chan_probe(struct xilinx_dma_device *xdev,
> >> > > +                                struct device_node *node) {
> >> > > +       struct xilinx_dma_chan *chan;
> >> > > +       int err;
> >> > > +       bool has_dre;
> >> > > +       u32 value, width = 0;
> >> > > +
> >> > > +       /* alloc channel */
> >> > > +       chan = devm_kzalloc(xdev->dev, sizeof(*chan), GFP_KERNEL);
> >> > > +       if (!chan)
> >> > > +               return -ENOMEM;
> >> > > +
> >> > > +       chan->dev = xdev->dev;
> >> > > +       chan->xdev = xdev;
> >> > > +       chan->has_sg = xdev->has_sg;
> >> > > +       chan->desc_pendingcount = 0x0;
> >> > > +
> >> > > +       has_dre = of_property_read_bool(node, "xlnx,include-dre");
> >> > > +
> >> > > +       err = of_property_read_u32(node, "xlnx,datawidth", &value);
> >> > > +       if (err) {
> >> > > +               dev_err(xdev->dev, "unable to read datawidth property");
> >> > > +               return err;
> >> > > +       }
> >> > > +
> >> > > +       width = value >> 3; /* Convert bits to bytes */
> >> > > +
> >> > > +       /* If data width is greater than 8 bytes, DRE is not in hw */
> >> > > +       if (width > 8)
> >> > > +               has_dre = false;
> >> > > +
> >> > > +       if (!has_dre)
> >> > > +               xdev->common.copy_align = fls(width - 1);
> >> > > +
> >> > > +       if (of_device_is_compatible(node, "xlnx,axi-dma-mm2s-channel")) {
> >> > > +               chan->id = 0;
> >> > > +               chan->ctrl_offset = XILINX_DMA_MM2S_CTRL_OFFSET;
> >> > > +       } else if (of_device_is_compatible(node, "xlnx,axi-dma-s2mm-
> >> channel")) {
> >> > > +               chan->id = 1;
> >> > > +               chan->ctrl_offset = XILINX_DMA_S2MM_CTRL_OFFSET;
> >> > > +       } else {
> >> > > +               dev_err(xdev->dev, "Invalid channel compatible node\n");
> >> > > +               return -EINVAL;
> >> > > +       }
> >> > > +
> >> > > +       xdev->chan[chan->id] = chan;
> >> > > +
> >> > > +       /* Initialize the channel */
> >> > > +       err = xilinx_dma_chan_reset(chan);
> >> > > +       if (err) {
> >> > > +               dev_err(xdev->dev, "Reset channel failed\n");
> >> > > +               return err;
> >> > > +       }
> >> > > +
> >> > > +       spin_lock_init(&chan->lock);
> >> > > +       INIT_LIST_HEAD(&chan->pending_list);
> >> > > +       INIT_LIST_HEAD(&chan->done_list);
> >> > > +       INIT_LIST_HEAD(&chan->active_list);
> >> > > +       INIT_LIST_HEAD(&chan->free_seg_list);
> >> > > +
> >> > > +       chan->common.device = &xdev->common;
> >> > > +
> >> > > +       /* find the IRQ line, if it exists in the device tree */
> >> > > +       chan->irq = irq_of_parse_and_map(node, 0);
> >> > > +       err = request_irq(chan->irq, xilinx_dma_irq_handler,
> >> > > +                         IRQF_SHARED,
> >> > > +                         "xilinx-dma-controller", chan);
> >> > > +       if (err) {
> >> > > +               dev_err(xdev->dev, "unable to request IRQ %d\n", chan->irq);
> >> > > +               return err;
> >> > > +       }
> >> > > +
> >> > > +       /* Initialize the tasklet */
> >> > > +       tasklet_init(&chan->tasklet, xilinx_dma_do_tasklet,
> >> > > +                    (unsigned long)chan);
> >> > > +
> >> > > +       /* Add the channel to DMA device channel list */
> >> > > +       list_add_tail(&chan->common.device_node,
> >> > > + &xdev->common.channels);
> >> > > +
> >> > > +       chan->idle = true;
> >> > > +
> >> > > +       return 0;
> >> > > +}
> >> > > +
> >> > > +/**
> >> > > + * of_dma_xilinx_xlate - Translation function
> >> > > + * @dma_spec: Pointer to DMA specifier as found in the device tree
> >> > > + * @ofdma: Pointer to DMA controller data
> >> > > + *
> >> > > + * Return: DMA channel pointer on success and NULL on error  */
> >> > > +static struct dma_chan *of_dma_xilinx_xlate(struct of_phandle_args
> >> > *dma_spec,
> >> > > +                                           struct of_dma *ofdma) {
> >> > > +       struct xilinx_dma_device *xdev = ofdma->of_dma_data;
> >> > > +       int chan_id = dma_spec->args[0];
> >> > > +
> >> > > +       if (chan_id >= XILINX_DMA_MAX_CHANS_PER_DEVICE)
> >> > > +               return NULL;
> >> > > +
> >> > > +       return dma_get_slave_channel(&xdev->chan[chan_id]->common);
> >> > > +}
> >> > > +
> >> > > +/**
> >> > > + * xilinx_dma_probe - Driver probe function
> >> > > + * @pdev: Pointer to the platform_device structure
> >> > > + *
> >> > > + * Return: '0' on success and failure value on error  */ static int
> >> > > +xilinx_dma_probe(struct platform_device *pdev) {
> >> > > +       struct xilinx_dma_device *xdev;
> >> > > +       struct device_node *child, *node;
> >> > > +       struct resource *res;
> >> > > +       int i, ret;
> >> > > +
> >> > > +       xdev = devm_kzalloc(&pdev->dev, sizeof(*xdev), GFP_KERNEL);
> >> > > +       if (!xdev)
> >> > > +               return -ENOMEM;
> >> > > +
> >> > > +       xdev->dev = &(pdev->dev);
> >> > > +       INIT_LIST_HEAD(&xdev->common.channels);
> >> > > +
> >> > > +       node = pdev->dev.of_node;
> >> > > +
> >> > > +       /* Map the registers */
> >> > > +       res = platform_get_resource(pdev, IORESOURCE_MEM, 0);
> >> > > +       xdev->regs = devm_ioremap_resource(&pdev->dev, res);
> >> > > +       if (IS_ERR(xdev->regs))
> >> > > +               return PTR_ERR(xdev->regs);
> >> > > +
> >> > > +       /* Check if SG is enabled */
> >> > > +       xdev->has_sg = of_property_read_bool(node,
> >> > > + "xlnx,include-sg");
> >> > > +
> >> > > +       /* Axi DMA only do slave transfers */
> >> > > +       dma_cap_set(DMA_SLAVE, xdev->common.cap_mask);
> >> > > +       dma_cap_set(DMA_PRIVATE, xdev->common.cap_mask);
> >> > > +       xdev->common.device_prep_slave_sg = xilinx_dma_prep_slave_sg;
> >> > > +       xdev->common.device_terminate_all = xilinx_dma_terminate_all;
> >> > > +       xdev->common.device_issue_pending = xilinx_dma_issue_pending;
> >> > > +       xdev->common.device_alloc_chan_resources =
> >> > > +               xilinx_dma_alloc_chan_resources;
> >> > > +       xdev->common.device_free_chan_resources =
> >> > > +               xilinx_dma_free_chan_resources;
> >> > > +       xdev->common.device_tx_status = xilinx_dma_tx_status;
> >> > > +       xdev->common.directions = BIT(DMA_DEV_TO_MEM) |
> >> > BIT(DMA_MEM_TO_DEV);
> >> > > +       xdev->common.residue_granularity =
> >> > DMA_RESIDUE_GRANULARITY_SEGMENT;
> >> > > +       xdev->common.dev = &pdev->dev;
> >> > > +
> >> > > +       platform_set_drvdata(pdev, xdev);
> >> > > +
> >> > > +       for_each_child_of_node(node, child) {
> >> > > +               ret = xilinx_dma_chan_probe(xdev, child);
> >> > > +               if (ret) {
> >> > > +                       dev_err(&pdev->dev, "Probing channels failed\n");
> >> > > +                       goto free_chan_resources;
> >> > > +               }
> >> > > +       }
> >> > > +
> >> > > +       dma_async_device_register(&xdev->common);
> >> > > +
> >> > > +       ret = of_dma_controller_register(node, of_dma_xilinx_xlate, xdev);
> >> > > +       if (ret) {
> >> > > +               dev_err(&pdev->dev, "Unable to register DMA to DT\n");
> >> > > +               dma_async_device_unregister(&xdev->common);
> >> > > +               goto free_chan_resources;
> >> > > +       }
> >> > > +
> >> > > +       dev_info(&pdev->dev, "Xilinx AXI DMA Engine driver
> >> > > + Probed!!\n");
> >> > > +
> >> > > +       return 0;
> >> > > +
> >> > > +free_chan_resources:
> >> > > +       for (i = 0; i < XILINX_DMA_MAX_CHANS_PER_DEVICE; i++)
> >> > > +               if (xdev->chan[i])
> >> > > +                       xilinx_dma_chan_remove(xdev->chan[i]);
> >> > > +
> >> > > +       return ret;
> >> > > +}
> >> > > +
> >> > > +/**
> >> > > + * xilinx_dma_remove - Driver remove function
> >> > > + * @pdev: Pointer to the platform_device structure
> >> > > + *
> >> > > + * Return: Always '0'
> >> > > + */
> >> > > +static int xilinx_dma_remove(struct platform_device *pdev) {
> >> > > +       struct xilinx_dma_device *xdev = platform_get_drvdata(pdev);
> >> > > +       int i;
> >> > > +
> >> > > +       of_dma_controller_free(pdev->dev.of_node);
> >> > > +       dma_async_device_unregister(&xdev->common);
> >> > > +
> >> > > +       for (i = 0; i < XILINX_DMA_MAX_CHANS_PER_DEVICE; i++)
> >> > > +               if (xdev->chan[i])
> >> > > +                       xilinx_dma_chan_remove(xdev->chan[i]);
> >> > > +
> >> > > +       return 0;
> >> > > +}
> >> > > +
> >> > > +static const struct of_device_id xilinx_dma_of_match[] = {
> >> > > +       { .compatible = "xlnx,axi-dma-1.00.a",},
> >> > > +       {}
> >> > > +};
> >> > > +MODULE_DEVICE_TABLE(of, xilinx_dma_of_match);
> >> > > +
> >> > > +static struct platform_driver xilinx_dma_driver = {
> >> > > +       .driver = {
> >> > > +               .name = "xilinx-dma",
> >> > > +               .of_match_table = xilinx_dma_of_match,
> >> > > +       },
> >> > > +       .probe = xilinx_dma_probe,
> >> > > +       .remove = xilinx_dma_remove, };
> >> > > +
> >> > > +module_platform_driver(xilinx_dma_driver);
> >> > > +
> >> > > +MODULE_AUTHOR("Xilinx, Inc.");
> >> > > +MODULE_DESCRIPTION("Xilinx DMA driver"); MODULE_LICENSE("GPL");
> >> > > --
> >> > > 2.1.2
> >> > >
> >> > >
> >> > > _______________________________________________
> >> > > linux-arm-kernel mailing list
> >> > > linux-arm-kernel at lists.infradead.org
> >> > > http://lists.infradead.org/mailman/listinfo/linux-arm-kernel
> >> >
> >> > Cheers,
> >> >
> >> > Moritz
> 
> Thanks,
> Moritz


From robert.jarzmik at free.fr  Sat Aug 22 05:41:10 2015
From: robert.jarzmik at free.fr (Robert Jarzmik)
Date: Sat, 22 Aug 2015 14:41:10 +0200
Subject: [PATCH v2 09/21] ARM: pxa: magician: Add OV9640 camera support
In-Reply-To: <55D7A186.4000505@tul.cz> (Petr Cvek's message of "Sat, 22 Aug
 2015 00:09:10 +0200")
References: <cover.1439843482.git.petr.cvek@tul.cz>
 <2889798.x6xcIzdYMU@wuerfel> <55D65722.9030508@tul.cz>
 <1634812.ZDaECJ9ClW@wuerfel> <874mjs5yt2.fsf@belgarion.home>
 <55D7A186.4000505@tul.cz>
Message-ID: <87zj1j4hsp.fsf@belgarion.home>

Petr Cvek <petr.cvek at tul.cz> writes:

>> So Guennadi, is it possible to add a gpio through platform data to ov9640
>> driver, does it make sense, and would you accept to have the reset handled there
>> ? And if yes, would you, Petr, accept to revamp your patch to have the reset and
>> power handled in ov9640 ?
>> 
>
> OK, why not, so power and reset gpio with polarity settings?
Even better pass ... nothing through platform-data.

I think there is now a gpio binding for devices which works this way :
 - in ov9640 : devm_gpiod_get(dev, "reset")
 - in magician: GPIO_LOOKUP() and gpiod_add_lookup_table()

In this way I think we'll gather at the same time :
 - no new platform data
 - ov9640 will follow the same path for devicetree and platform data

> Anyway I'm planning to send patch for OV9640 in future too (color correction
> matrix is not complete and some registers too).
Good.

Cheers.

-- 
Robert


From ryabinin.a.a at gmail.com  Sat Aug 22 05:51:03 2015
From: ryabinin.a.a at gmail.com (Andrey Ryabinin)
Date: Sat, 22 Aug 2015 15:51:03 +0300
Subject: [PATCH 0/2] x86/KASAN updates for 4.3
In-Reply-To: <20150822100922.GA25039@gmail.com>
References: <1439444244-26057-1-git-send-email-ryabinin.a.a@gmail.com>
 <20150813065040.GA17983@gmail.com>
 <20150813081641.GA14402@gmail.com> <20150813090119.GA10280@arm.com>
 <CAPAsAGxk2+v5VG77cOHAThsXyWx-_UJ1XVeJProaa0gQWH5jvA@mail.gmail.com>
 <20150813112428.GG10280@arm.com> <20150813172310.GK10280@arm.com>
 <20150822100922.GA25039@gmail.com>
Message-ID: <CAPAsAGz7Ew3oomDnYvHbq-ANhp5bhZGeUtc-iHXJX4PW5ZUcyg@mail.gmail.com>

2015-08-22 13:09 GMT+03:00 Ingo Molnar <mingo at kernel.org>:
>
> * Will Deacon <will.deacon at arm.com> wrote:
>
>> On Thu, Aug 13, 2015 at 12:24:28PM +0100, Will Deacon wrote:
>> > On Thu, Aug 13, 2015 at 12:02:26PM +0100, Andrey Ryabinin wrote:
>> > > 2015-08-13 12:01 GMT+03:00 Will Deacon <will.deacon at arm.com>:
>> > > > Yes please, works for me! If we're targetting 4.3, then please can you base
>> > > > on 4.2-rc4, as that's what our current arm64 queue is using?
>> > > >
>> > >
>> > > Does this mean that we are targeting arm64 part for 4.3 too?
>> >
>> > It depends on how well it merges with our current queue and whether it
>> > holds up to regression testing. The patches have been reviewed, so I'm
>> > comfortable with the content, but we're not at a stage where we can debug
>> > and fix any failures that might crop up from the merge.
>>
>> Scratch that :(
>>
>> I tried this out under EFI and it dies horribly in the stub code because
>> we're missing at least one KASAN_SANITIZE_ Makefile entry.
>>
>> So I think this needs longer to stew before hitting mainline. By all means
>> get the x86 dependencies in for 4.3, but the arm64 port can probably use
>> another cycle to iron out the bugs.
>
> Is there any known problem with the two patches in this series, or can I apply
> them?
>

None, as far as I know.

BTW, the second patch was  Acked-by: Catalin Marinas <catalin.marinas at arm.com>
(https://lkml.org/lkml/2015/8/11/546). I just forgot to add this into changelog.



> Thanks,
>
>         Ingo


From robert.richter at caviumnetworks.com  Sat Aug 22 06:10:50 2015
From: robert.richter at caviumnetworks.com (Robert Richter)
Date: Sat, 22 Aug 2015 15:10:50 +0200
Subject: [PATCH] irqchip, gicv3-its, numa: Workaround for Cavium ThunderX
 erratum 23144
Message-ID: <20150822131050.GK1820@rric.localdomain>

The patch below adds a workaround for gicv3 in a numa environment. It
is on top of my recent gicv3 errata patch submission v4 and Ganapat's
arm64 numa patches for devicetree v5.

Please comment.

Thanks,

-Robert



>From c432820451a46b8d1e299b8bfbfcdcb3b75340e7 Mon Sep 17 00:00:00 2001
From: Ganapatrao Kulkarni <gkulkarni at caviumnetworks.com>
Date: Wed, 19 Aug 2015 23:40:05 +0530
Subject: [PATCH] irqchip, gicv3-its, numa: Workaround for Cavium ThunderX erratum
 23144

This implements a workaround for gicv3-its erratum 23144 applicable
for Cavium's ThunderX multinode systems.

The erratum fixes the hang of ITS SYNC command by avoiding inter node
io and collections/cpu mapping. This fix is only applicable for
Cavium's ThunderX dual-socket platforms.

Signed-off-by: Ganapatrao Kulkarni <gkulkarni at caviumnetworks.com>
[ rric: Reworked errata code, added helper functions, updated commit
  	message. ]

Signed-off-by: Robert Richter <rrichter at cavium.com>
---
 arch/arm64/Kconfig               | 14 +++++++++++
 drivers/irqchip/irq-gic-common.c |  5 ++--
 drivers/irqchip/irq-gic-v3-its.c | 54 ++++++++++++++++++++++++++++++++++------
 3 files changed, 64 insertions(+), 9 deletions(-)

diff --git a/arch/arm64/Kconfig b/arch/arm64/Kconfig
index 3809187ed653..b92b7b70b29b 100644
--- a/arch/arm64/Kconfig
+++ b/arch/arm64/Kconfig
@@ -421,6 +421,20 @@ config ARM64_ERRATUM_845719
 
 	  If unsure, say Y.
 
+config CAVIUM_ERRATUM_22375
+	bool "Cavium erratum 22375, 24313"
+	depends on NUMA
+	default y
+	help
+		Enable workaround for erratum 22375, 24313.
+
+config CAVIUM_ERRATUM_23144
+	bool "Cavium erratum 23144"
+	depends on NUMA
+	default y
+	help
+		Enable workaround for erratum 23144.
+
 config CAVIUM_ERRATUM_23154
 	bool "Cavium erratum 23154: Access to ICC_IAR1_EL1 is not sync'ed"
 	depends on ARCH_THUNDER
diff --git a/drivers/irqchip/irq-gic-common.c b/drivers/irqchip/irq-gic-common.c
index ee789b07f2d1..1dfce64dbdac 100644
--- a/drivers/irqchip/irq-gic-common.c
+++ b/drivers/irqchip/irq-gic-common.c
@@ -24,11 +24,12 @@
 void gic_check_capabilities(u32 iidr, const struct gic_capabilities *cap,
 			void *data)
 {
-	for (; cap->desc; cap++) {
+	for (; cap->init; cap++) {
 		if (cap->iidr != (cap->mask & iidr))
 			continue;
 		cap->init(data);
-		pr_info("%s\n", cap->desc);
+		if (cap->desc)
+			pr_info("%s\n", cap->desc);
 	}
 }
 
diff --git a/drivers/irqchip/irq-gic-v3-its.c b/drivers/irqchip/irq-gic-v3-its.c
index 4bb135721e72..666be39f13a9 100644
--- a/drivers/irqchip/irq-gic-v3-its.c
+++ b/drivers/irqchip/irq-gic-v3-its.c
@@ -43,7 +43,8 @@
 #include "irqchip.h"
 
 #define ITS_FLAGS_CMDQ_NEEDS_FLUSHING		(1ULL << 0)
-#define ITS_FLAGS_CAVIUM_THUNDERX		(1ULL << 1)
+#define ITS_WORKAROUND_CAVIUM_22375		(1ULL << 1)
+#define ITS_WORKAROUND_CAVIUM_23144		(1ULL << 2)
 
 #define RDIST_FLAGS_PROPBASE_NEEDS_FLUSHING	(1 << 0)
 
@@ -76,6 +77,7 @@ struct its_node {
 	struct list_head	its_device_list;
 	u64			flags;
 	u32			ite_size;
+	int			numa_node;
 };
 
 #define ITS_ITT_ALIGN		SZ_256
@@ -609,11 +611,18 @@ static void its_eoi_irq(struct irq_data *d)
 static int its_set_affinity(struct irq_data *d, const struct cpumask *mask_val,
 			    bool force)
 {
-	unsigned int cpu = cpumask_any_and(mask_val, cpu_online_mask);
+	unsigned int cpu;
 	struct its_device *its_dev = irq_data_get_irq_chip_data(d);
 	struct its_collection *target_col;
 	u32 id = its_get_event_id(d);
 
+	if (its_dev->its->flags & ITS_WORKAROUND_CAVIUM_23144) {
+		cpu = cpumask_any_and(mask_val,
+				cpumask_of_node(its_dev->its->numa_node));
+	} else {
+		cpu = cpumask_any_and(mask_val, cpu_online_mask);
+	}
+
 	if (cpu >= nr_cpu_ids)
 		return -EINVAL;
 
@@ -845,7 +854,7 @@ static int its_alloc_tables(struct its_node *its)
 	u64 typer;
 	u32 ids;
 
-	if (its->flags & ITS_FLAGS_CAVIUM_THUNDERX) {
+	if (its->flags & ITS_WORKAROUND_CAVIUM_22375) {
 		/*
 		 * erratum 22375: only alloc 8MB table size
 		 * erratum 24313: ignore memory access type
@@ -1093,6 +1102,11 @@ static void its_cpu_init_lpis(void)
 	dsb(sy);
 }
 
+static inline int numa_node_id_early(void)
+{
+	return MPIDR_AFFINITY_LEVEL(read_cpuid_mpidr(), 2);
+}
+
 static void its_cpu_init_collection(void)
 {
 	struct its_node *its;
@@ -1104,6 +1118,11 @@ static void its_cpu_init_collection(void)
 	list_for_each_entry(its, &its_nodes, entry) {
 		u64 target;
 
+		/* avoid cross node core and its mapping */
+		if ((its->flags & ITS_WORKAROUND_CAVIUM_23144) &&
+			its->numa_node != numa_node_id_early())
+				continue;
+
 		/*
 		 * We now have to bind each collection to its target
 		 * redistributor.
@@ -1372,9 +1391,15 @@ static void its_irq_domain_activate(struct irq_domain *domain,
 {
 	struct its_device *its_dev = irq_data_get_irq_chip_data(d);
 	u32 event = its_get_event_id(d);
+	unsigned int cpu;
+
+	if (its_dev->its->flags & ITS_WORKAROUND_CAVIUM_23144)
+		cpu = cpumask_first(cpumask_of_node(its_dev->its->numa_node));
+	else
+		cpu = cpumask_first(cpu_online_mask);
 
 	/* Bind the LPI to the first possible CPU */
-	its_dev->event_map.col_map[event] = cpumask_first(cpu_online_mask);
+	its_dev->event_map.col_map[event] = cpu;
 
 	/* Map the GIC IRQ and event to the device */
 	its_send_mapvi(its_dev, d->hwirq, event);
@@ -1457,16 +1482,31 @@ static int its_force_quiescent(void __iomem *base)
 	}
 }
 
+static inline int its_get_node_thunderx(struct its_node *its)
+{
+	return (its->phys_base >> 44) & 0x3;
+}
+
 static void its_enable_cavium_thunderx(void *data)
 {
-	struct its_node *its = data;
+	struct its_node __maybe_unused *its = data;
 
-	its->flags |= ITS_FLAGS_CAVIUM_THUNDERX;
+#ifdef CONFIG_CAVIUM_ERRATUM_22375
+	its->flags |= ITS_WORKAROUND_CAVIUM_22375;
+	pr_info("ITS: Enabling workaround for 22375, 24313\n");
+#endif
+
+#ifdef CONFIG_CAVIUM_ERRATUM_23144
+	if (num_possible_nodes() > 1) {
+		its->numa_node = its_get_node_thunderx(its);
+		its->flags |= ITS_WORKAROUND_CAVIUM_23144;
+		pr_info("ITS: Enabling workaround for 23144\n");
+	}
+#endif
 }
 
 static const struct gic_capabilities its_errata[] = {
 	{
-		.desc	= "ITS: Cavium errata 22375, 24313",
 		.iidr	= 0xa100034c,	/* ThunderX pass 1.x */
 		.mask	= 0xffff0fff,
 		.init	= its_enable_cavium_thunderx,
-- 
2.1.1



From sergei.shtylyov at cogentembedded.com  Sat Aug 22 06:23:41 2015
From: sergei.shtylyov at cogentembedded.com (Sergei Shtylyov)
Date: Sat, 22 Aug 2015 16:23:41 +0300
Subject: [PATCH v6 2/5] dt-bindings: Add a binding for Mediatek xHCI host
 controller
In-Reply-To: <1440207911-17666-3-git-send-email-chunfeng.yun@mediatek.com>
References: <1440207911-17666-1-git-send-email-chunfeng.yun@mediatek.com>
 <1440207911-17666-3-git-send-email-chunfeng.yun@mediatek.com>
Message-ID: <55D877DD.3010400@cogentembedded.com>

Hello.

On 8/22/2015 4:45 AM, Chunfeng Yun wrote:

> add a DT binding documentation of xHCI host controller for the
> MT8173 SoC from Mediatek.

> Signed-off-by: Chunfeng Yun <chunfeng.yun at mediatek.com>
> ---
>   .../devicetree/bindings/usb/mt8173-xhci.txt        | 52 ++++++++++++++++++++++
>   1 file changed, 52 insertions(+)
>   create mode 100644 Documentation/devicetree/bindings/usb/mt8173-xhci.txt
>
> diff --git a/Documentation/devicetree/bindings/usb/mt8173-xhci.txt b/Documentation/devicetree/bindings/usb/mt8173-xhci.txt
> new file mode 100644
> index 0000000..8e6e463
> --- /dev/null
> +++ b/Documentation/devicetree/bindings/usb/mt8173-xhci.txt
> @@ -0,0 +1,52 @@
> +mt65XX xHCI

    The file is called mt8173-xhci.txt. Are you sure MT65xx should be here?

> +
> +The device node for Mediatek SOC usb3.0 host controller
> +
> +Required properties:
> + - compatible : should contain "mediatek,mt8173-xhci"
> + - reg : specifies physical base address and size of the registers,
> +	the first one for MAC, the second for IPPC
> + - interrupts : interrupt used by the controller
> + - power-domains : a phandle to USB power domain node to control usb's

    USB's -- be consistent, please.

> +	mtcmos
> + - vusb33-supply : regulator of usb avdd3.3v
> +
> + - clocks : a list of phandle + clock-specifier pairs, one for each
> +	entry in clock-names
> + - clock-names : must contain
> +	"sys_ck": for clock of xHCI MAC
> +	"wakeup_deb_p0": for usb wakeup debounce clock of port0
> +	"wakeup_deb_p0": for usb wakeup debounce clock of port1

    USB.

> +
> + - phys : a list of phandle + phy specifier pairs
> + - usb3-lpm-capable : supports USB3 LPM
> + - mediatek,syscon-wakeup : phandle to syscon used to access usb wakeup
> +	control register
> + - mediatek,wakeup-src : 1: ip sleep wakeup mode; 2: line state wakeup
> +	mode; others means don't enable wakeup source of usb

    "Others mean" and "USB".

[...]

MBR, Sergei



From leo.yan at linaro.org  Sat Aug 22 06:30:50 2015
From: leo.yan at linaro.org (Leo Yan)
Date: Sat, 22 Aug 2015 21:30:50 +0800
Subject: [PATCH v1 3/3] arm64: dts: add Hi6220 mailbox node
In-Reply-To: <20150821184059.GB2000@svinekod>
References: <1439977055-1747-1-git-send-email-leo.yan@linaro.org>
 <1439977055-1747-4-git-send-email-leo.yan@linaro.org>
 <20150821184059.GB2000@svinekod>
Message-ID: <20150822133050.GA4265@leoy-linaro>

Hi Mark,

On Fri, Aug 21, 2015 at 07:40:59PM +0100, Mark Rutland wrote:
> On Wed, Aug 19, 2015 at 10:37:35AM +0100, Leo Yan wrote:
> > On Hi6220, below memory regions in DDR have specific purpose:
> > 
> >   0x05e0,0000 - 0x05ef,ffff: For MCU firmware using at runtime;
> >   0x0740,f000 - 0x0740,ffff: For MCU firmware's section;
> >   0x06df,f000 - 0x06df,ffff: For mailbox message data.
> > 
> > This patch reserves these memory regions and add device node for
> > mailbox in dts.
> > 
> > Signed-off-by: Leo Yan <leo.yan at linaro.org>
> > ---
> >  arch/arm64/boot/dts/hisilicon/hi6220-hikey.dts | 20 +++++++++++++++++---
> >  arch/arm64/boot/dts/hisilicon/hi6220.dtsi      |  8 ++++++++
> >  2 files changed, 25 insertions(+), 3 deletions(-)
> > 
> > diff --git a/arch/arm64/boot/dts/hisilicon/hi6220-hikey.dts b/arch/arm64/boot/dts/hisilicon/hi6220-hikey.dts
> > index e36a539..d5470d3 100644
> > --- a/arch/arm64/boot/dts/hisilicon/hi6220-hikey.dts
> > +++ b/arch/arm64/boot/dts/hisilicon/hi6220-hikey.dts
> > @@ -7,9 +7,6 @@
> >  
> >  /dts-v1/;
> >  
> > -/*Reserved 1MB memory for MCU*/
> > -/memreserve/ 0x05e00000 0x00100000;
> > -
> >  #include "hi6220.dtsi"
> >  
> >  / {
> > @@ -28,4 +25,21 @@
> >  		device_type = "memory";
> >  		reg = <0x0 0x0 0x0 0x40000000>;
> >  	};
> > +
> > +	reserved-memory {
> > +		#address-cells = <2>;
> > +		#size-cells = <2>;
> > +		ranges;
> > +
> > +		mcu-buf at 05e00000 {
> > +			no-map;
> > +			reg = <0x0 0x05e00000 0x0 0x00100000>,	/* MCU firmware buffer */
> > +			      <0x0 0x0740f000 0x0 0x00001000>;	/* MCU firmware section */
> > +		};
> > +
> > +		mbox-buf at 06dff000 {
> > +			no-map;
> > +			reg = <0x0 0x06dff000 0x0 0x00001000>;	/* Mailbox message buf */
> > +		};
> > +	};
> 
> As far as I can see, it would be simpler to simply carve these out of the
> memory node.

Will modify for MCU firmware buffer and section.

> I don't see why you need reserved-memory here, given you're not referring to
> these regions by phandle anyway.

mbox-buf is used by below mailbox's node, but the start address has
been truncated with 4KB alignment; so should keep it, right?

Thanks,
Leo Yan

> >  };
> > diff --git a/arch/arm64/boot/dts/hisilicon/hi6220.dtsi b/arch/arm64/boot/dts/hisilicon/hi6220.dtsi
> > index 3f03380..9ff25bc 100644
> > --- a/arch/arm64/boot/dts/hisilicon/hi6220.dtsi
> > +++ b/arch/arm64/boot/dts/hisilicon/hi6220.dtsi
> > @@ -167,5 +167,13 @@
> >  			clocks = <&ao_ctrl 36>, <&ao_ctrl 36>;
> >  			clock-names = "uartclk", "apb_pclk";
> >  		};
> > +
> > +		mailbox: mailbox at f7510000 {
> > +			#mbox-cells = <1>;
> > +			compatible = "hisilicon,hi6220-mbox";
> > +			reg = <0x0 0xf7510000 0x0 0x1000>, /* IPC_S */
> > +			      <0x0 0x06dff800 0x0 0x0800>; /* Mailbox buffer */
> > +			interrupts = <GIC_SPI 94 IRQ_TYPE_LEVEL_HIGH>;
> > +		};
> >  	};
> >  };
> > -- 
> > 1.9.1
> > 


From robert.richter at caviumnetworks.com  Sat Aug 22 08:06:16 2015
From: robert.richter at caviumnetworks.com (Robert Richter)
Date: Sat, 22 Aug 2015 17:06:16 +0200
Subject: [PATCH v5 2/4] Documentation: arm64/arm: dt bindings for numa.
In-Reply-To: <1439570374-4079-3-git-send-email-gkulkarni@caviumnetworks.com>
References: <1439570374-4079-1-git-send-email-gkulkarni@caviumnetworks.com>
 <1439570374-4079-3-git-send-email-gkulkarni@caviumnetworks.com>
Message-ID: <20150822150616.GC8624@rric.localhost>

On 14.08.15 22:09:32, Ganapatrao Kulkarni wrote:
> DT bindings for numa map for memory, cores and IOs using
> arm,associativity device node property.

Arnd, Rob,

as the change below suggests the same topology syntax as already
implemented for PPC, could you take a look at this one for arm64?
Please ack the devicetree changes, assuming you are fine with it.

All other review comments are addressed so far and there are no open
issues with the patches. This would help us to further drive this
series upstream.

Many thanks,

-Robert


> Signed-off-by: Ganapatrao Kulkarni <gkulkarni at caviumnetworks.com>
> ---
>  Documentation/devicetree/bindings/arm/numa.txt | 212 +++++++++++++++++++++++++
>  1 file changed, 212 insertions(+)
>  create mode 100644 Documentation/devicetree/bindings/arm/numa.txt
> 
> diff --git a/Documentation/devicetree/bindings/arm/numa.txt b/Documentation/devicetree/bindings/arm/numa.txt
> new file mode 100644
> index 0000000..dc3ef86
> --- /dev/null
> +++ b/Documentation/devicetree/bindings/arm/numa.txt
> @@ -0,0 +1,212 @@
> +==============================================================================
> +NUMA binding description.
> +==============================================================================
> +
> +==============================================================================
> +1 - Introduction
> +==============================================================================
> +
> +Systems employing a Non Uniform Memory Access (NUMA) architecture contain
> +collections of hardware resources including processors, memory, and I/O buses,
> +that comprise what is commonly known as a NUMA node.
> +Processor accesses to memory within the local NUMA node is generally faster
> +than processor accesses to memory outside of the local NUMA node.
> +DT defines interfaces that allow the platform to convey NUMA node
> +topology information to OS.
> +
> +==============================================================================
> +2 - arm,associativity
> +==============================================================================
> +The mapping is done using arm,associativity device property.
> +this property needs to be present in every device node which needs to to be
> +mapped to numa nodes.
> +
> +arm,associativity property is set of 32-bit integers which defines level of
> +topology and boundary in the system at which a significant difference in
> +performance can be measured between cross-device accesses within
> +a single location and those spanning multiple locations.
> +The first cell always contains the broadest subdivision within the system,
> +while the last cell enumerates the individual devices, such as an SMT thread
> +of a CPU, or a bus bridge within an SoC".
> +
> +ex:
> +	/* board 0, socket 0, cluster 0, core 0  thread 0 */
> +	arm,associativity = <0 0 0 0 0>;
> +
> +==============================================================================
> +3 - arm,associativity-reference-points
> +==============================================================================
> +This property is a set of 32-bit integers, each representing an index into
> +the arm,associativity nodes. The first integer is the most significant
> +NUMA boundary and the following are progressively less significant boundaries.
> +There can be more than one level of NUMA.
> +
> +Ex:
> +	arm,associativity-reference-points = <0 1>;
> +	The board Id(index 0) used first to calculate the associativity (node
> +	distance), then follows the  socket id(index 1).
> +
> +	arm,associativity-reference-points = <1 0>;
> +	The socket Id(index 1) used first to calculate the associativity,
> +	then follows the board id(index 0).
> +
> +	arm,associativity-reference-points = <0>;
> +	Only the board Id(index 0) used to calculate the associativity.
> +
> +	arm,associativity-reference-points = <1>;
> +	Only socket Id(index 1) used to calculate the associativity.
> +
> +==============================================================================
> +4 - Example dts
> +==============================================================================
> +
> +Example: 2 Node system consists of 2 boards and each board having one socket
> +and 8 core in each socket.
> +
> +	arm,associativity-reference-points = <0>;
> +
> +	memory at 00c00000 {
> +		device_type = "memory";
> +		reg = <0x0 0x00c00000 0x0 0x80000000>;
> +		/* board 0, socket 0, no specific core */
> +		arm,associativity = <0 0 0xffff>;
> +	};
> +
> +	memory at 10000000000 {
> +		device_type = "memory";
> +		reg = <0x100 0x00000000 0x0 0x80000000>;
> +		/* board 1, socket 0, no specific core */
> +		arm,associativity = <1 0 0xffff>;
> +	};
> +
> +	cpus {
> +		#address-cells = <2>;
> +		#size-cells = <0>;
> +
> +		cpu at 000 {
> +			device_type = "cpu";
> +			compatible =  "arm,armv8";
> +			reg = <0x0 0x000>;
> +			enable-method = "psci";
> +			/* board 0, socket 0, core 0*/
> +			arm,associativity = <0 0 0>;
> +		};
> +		cpu at 001 {
> +			device_type = "cpu";
> +			compatible =  "arm,armv8";
> +			reg = <0x0 0x001>;
> +			enable-method = "psci";
> +			arm,associativity = <0 0 1>;
> +		};
> +		cpu at 002 {
> +			device_type = "cpu";
> +			compatible =  "arm,armv8";
> +			reg = <0x0 0x002>;
> +			enable-method = "psci";
> +			arm,associativity = <0 0 2>;
> +		};
> +		cpu at 003 {
> +			device_type = "cpu";
> +			compatible =  "arm,armv8";
> +			reg = <0x0 0x003>;
> +			enable-method = "psci";
> +			arm,associativity = <0 0 3>;
> +		};
> +		cpu at 004 {
> +			device_type = "cpu";
> +			compatible =  "arm,armv8";
> +			reg = <0x0 0x004>;
> +			enable-method = "psci";
> +			arm,associativity = <0 0 4>;
> +		};
> +		cpu at 005 {
> +			device_type = "cpu";
> +			compatible =  "arm,armv8";
> +			reg = <0x0 0x005>;
> +			enable-method = "psci";
> +			arm,associativity = <0 0 5>;
> +		};
> +		cpu at 006 {
> +			device_type = "cpu";
> +			compatible =  "arm,armv8";
> +			reg = <0x0 0x006>;
> +			enable-method = "psci";
> +			arm,associativity = <0 0 6>;
> +		};
> +		cpu at 007 {
> +			device_type = "cpu";
> +			compatible =  "arm,armv8";
> +			reg = <0x0 0x007>;
> +			enable-method = "psci";
> +			arm,associativity = <0 0 7>;
> +		};
> +		cpu at 008 {
> +			device_type = "cpu";
> +			compatible =  "arm,armv8";
> +			reg = <0x0 0x008>;
> +			enable-method = "psci";
> +			/* board 1, socket 0, core 0*/
> +			arm,associativity = <1 0 0>;
> +		};
> +		cpu at 009 {
> +			device_type = "cpu";
> +			compatible =  "arm,armv8";
> +			reg = <0x0 0x009>;
> +			enable-method = "psci";
> +			arm,associativity = <1 0 1>;
> +		};
> +		cpu at 00a {
> +			device_type = "cpu";
> +			compatible =  "arm,armv8";
> +			reg = <0x0 0x00a>;
> +			enable-method = "psci";
> +			arm,associativity = <0 0 2>;
> +		};
> +		cpu at 00b {
> +			device_type = "cpu";
> +			compatible =  "arm,armv8";
> +			reg = <0x0 0x00b>;
> +			enable-method = "psci";
> +			arm,associativity = <1 0 3>;
> +		};
> +		cpu at 00c {
> +			device_type = "cpu";
> +			compatible =  "arm,armv8";
> +			reg = <0x0 0x00c>;
> +			enable-method = "psci";
> +			arm,associativity = <1 0 4>;
> +		};
> +		cpu at 00d {
> +			device_type = "cpu";
> +			compatible =  "arm,armv8";
> +			reg = <0x0 0x00d>;
> +			enable-method = "psci";
> +			arm,associativity = <1 0 5>;
> +		};
> +		cpu at 00e {
> +			device_type = "cpu";
> +			compatible =  "arm,armv8";
> +			reg = <0x0 0x00e>;
> +			enable-method = "psci";
> +			arm,associativity = <1 0 6>;
> +		};
> +		cpu at 00f {
> +			device_type = "cpu";
> +			compatible =  "arm,armv8";
> +			reg = <0x0 0x00f>;
> +			enable-method = "psci";
> +			arm,associativity = <1 0 7>;
> +		};
> +	};
> +
> +	pcie0: pcie0 at 0x8480,00000000 {
> +		compatible = "arm,armv8";
> +		device_type = "pci";
> +		bus-range = <0 255>;
> +		#size-cells = <2>;
> +		#address-cells = <3>;
> +		reg = <0x8480 0x00000000 0 0x10000000>;  /* Configuration space */
> +		ranges = <0x03000000 0x8010 0x00000000 0x8010 0x00000000 0x70 0x00000000>; /* mem ranges */
> +		/* board 0, socket 0, pci bus 0*/
> +		arm,associativity = <0 0 0>;
> +        };
> -- 
> 1.8.1.4
> 
> 
> _______________________________________________
> linux-arm-kernel mailing list
> linux-arm-kernel at lists.infradead.org
> http://lists.infradead.org/mailman/listinfo/linux-arm-kernel


From linux at mniewoehner.de  Sat Aug 22 08:04:52 2015
From: linux at mniewoehner.de (Michael Niewoehner)
Date: Sat, 22 Aug 2015 17:04:52 +0200
Subject: [PATCH] clk: rockchip: handle critical clocks after registrering
 all clocks
In-Reply-To: <7786473.0oe27txQFN@phil>
References: <7786473.0oe27txQFN@phil>
Message-ID: <12B8A81E-1B35-4EF1-AEC4-08714F91AEC0@mniewoehner.de>


Am 21.08.2015 um 19:51 schrieb Heiko Stuebner <heiko at sntech.de>:

> Currently the registration of critical clocks is done in the function
> shared between rk3066 and rk3188 clock trees. That results in them
> getting handled maybe before all of them are registered.
> 
> Therefore move the critical clock handling down to the end of the soc-
> specific clock registration function, so that all clocks are registered
> before they're maybe handled as critical clock.
> 
> Signed-off-by: Heiko Stuebner <heiko at sntech.de>
Tested-by: Michael Niewoehner <linux at mniewoehner.de>
> ---
> It looks like with the recent flexibilization of the gpio clocks in the
> pinctrl driver, we're shaking out some oddities from the clock trees.
> This is another one that surfaced.
> 
> drivers/clk/rockchip/clk-rk3188.c | 7 +++++--
> 1 file changed, 5 insertions(+), 2 deletions(-)
> 
> diff --git a/drivers/clk/rockchip/clk-rk3188.c b/drivers/clk/rockchip/clk-
> rk3188.c
> index faa6695..bd88542 100644
> --- a/drivers/clk/rockchip/clk-rk3188.c
> +++ b/drivers/clk/rockchip/clk-rk3188.c
> @@ -744,8 +744,6 @@ static void __init rk3188_common_clk_init(struct 
> device_node *np)
> 
> 	rockchip_clk_register_branches(common_clk_branches,
> 				  ARRAY_SIZE(common_clk_branches));
> -	rockchip_clk_protect_critical(rk3188_critical_clocks,
> -				      ARRAY_SIZE(rk3188_critical_clocks));
> 
> 	rockchip_register_softrst(np, 9, reg_base + RK2928_SOFTRST_CON(0),
> 				  ROCKCHIP_SOFTRST_HIWORD_MASK);
> @@ -765,6 +763,8 @@ static void __init rk3066a_clk_init(struct device_node 
> *np)
> 			mux_armclk_p, ARRAY_SIZE(mux_armclk_p),
> 			&rk3066_cpuclk_data, rk3066_cpuclk_rates,
> 			ARRAY_SIZE(rk3066_cpuclk_rates));
> +	rockchip_clk_protect_critical(rk3188_critical_clocks,
> +				      ARRAY_SIZE(rk3188_critical_clocks));
> }
> CLK_OF_DECLARE(rk3066a_cru, "rockchip,rk3066a-cru", rk3066a_clk_init);
> 
> @@ -801,6 +801,9 @@ static void __init rk3188a_clk_init(struct device_node 
> *np)
> 		pr_warn("%s: missing clocks to reparent aclk_cpu_pre to gpll\n",
> 			__func__);
> 	}
> +
> +	rockchip_clk_protect_critical(rk3188_critical_clocks,
> +				      ARRAY_SIZE(rk3188_critical_clocks));
> }
> CLK_OF_DECLARE(rk3188a_cru, "rockchip,rk3188a-cru", rk3188a_clk_init);
> 
> -- 
> 2.1.4
> 
> 
> 
> _______________________________________________
> linux-arm-kernel mailing list
> linux-arm-kernel at lists.infradead.org
> http://lists.infradead.org/mailman/listinfo/linux-arm-kernel




From linux at mniewoehner.de  Sat Aug 22 08:05:22 2015
From: linux at mniewoehner.de (Michael Niewoehner)
Date: Sat, 22 Aug 2015 17:05:22 +0200
Subject: [PATCH] clk: rockchip: Add pclk_peri to critical clocks on
 RK3066/RK3188
In-Reply-To: <1440180627-4566-1-git-send-email-romain.perier@gmail.com>
References: <1440180627-4566-1-git-send-email-romain.perier@gmail.com>
Message-ID: <4BB6E60D-332B-4C12-9AF2-ACEEF157BEA0@mniewoehner.de>


Am 21.08.2015 um 20:10 schrieb Romain Perier <romain.perier at gmail.com>:

> Clocks for bank GPIO3 and GPIO4 are supplied by pclk_peri. These clocks need to
> stay on, otherwise pinctrl hangs the system when the driver is probed.
> 
> Signed-off-by: Romain Perier <romain.perier at gmail.com>
Tested-by: Michael Niewoehner <linux at mniewoehner.de>
> ---
> drivers/clk/rockchip/clk-rk3188.c | 1 +
> 1 file changed, 1 insertion(+)
> 
> diff --git a/drivers/clk/rockchip/clk-rk3188.c b/drivers/clk/rockchip/clk-rk3188.c
> index f63a642..596be81 100644
> --- a/drivers/clk/rockchip/clk-rk3188.c
> +++ b/drivers/clk/rockchip/clk-rk3188.c
> @@ -717,6 +717,7 @@ static const char *const rk3188_critical_clocks[] __initconst = {
> 	"aclk_peri",
> 	"hclk_peri",
> 	"pclk_cpu",
> +	"pclk_peri",
> };
> 
> static void __init rk3188_common_clk_init(struct device_node *np)
> -- 
> 2.1.4
> 
> 
> _______________________________________________
> linux-arm-kernel mailing list
> linux-arm-kernel at lists.infradead.org
> http://lists.infradead.org/mailman/listinfo/linux-arm-kernel




From robert.jarzmik at free.fr  Sat Aug 22 09:25:32 2015
From: robert.jarzmik at free.fr (Robert Jarzmik)
Date: Sat, 22 Aug 2015 18:25:32 +0200
Subject: [PATCH v2 17/21] ARM: pxa: magician: Remove (temporarily) pasic3
 LED support
In-Reply-To: <55D25A74.3030902@tul.cz> (Petr Cvek's message of "Tue, 18 Aug
 2015 00:04:36 +0200")
References: <cover.1439843482.git.petr.cvek@tul.cz> <55D25A74.3030902@tul.cz>
Message-ID: <87vbc747er.fsf@belgarion.home>

Petr Cvek <petr.cvek at tul.cz> writes:

> Temporarily remove pasic3 LEDs definition as it is not used (yet).
I don't understand the split between this patch and patch 19/21. Is it for
bisectability, are they symetric (this one removes what the next adds) ?

As the patch 18/21 will probably go through Lee's tree, is there any value in
keeping them apart ?

Cheers.

--
Robert


From robert.jarzmik at free.fr  Sat Aug 22 09:27:30 2015
From: robert.jarzmik at free.fr (Robert Jarzmik)
Date: Sat, 22 Aug 2015 18:27:30 +0200
Subject: [PATCH v2 21/21] ARM: pxa: magician: Move platform_add_devices()
 to the end of magician_init()
In-Reply-To: <55D25B07.1080703@tul.cz> (Petr Cvek's message of "Tue, 18 Aug
 2015 00:07:03 +0200")
References: <cover.1439843482.git.petr.cvek@tul.cz> <55D25B07.1080703@tul.cz>
Message-ID: <87r3mv47bh.fsf@belgarion.home>

Petr Cvek <petr.cvek at tul.cz> writes:

> Move platform_add_devices() to the end of magician_init() for better
> clarity of code.
>
> Signed-off-by: Petr Cvek <petr.cvek at tul.cz>
With Philipp's ack.

-- 
Robert


From Julia.Lawall at lip6.fr  Sat Aug 22 17:11:11 2015
From: Julia.Lawall at lip6.fr (Julia Lawall)
Date: Sun, 23 Aug 2015 02:11:11 +0200
Subject: [PATCH 00/11] fix error return code
Message-ID: <1440288682-12732-1-git-send-email-Julia.Lawall@lip6.fr>

The complate semantic patch that finds this problem is as follows:
(http://coccinelle.lip6.fr/)

// <smpl>
@ok exists@
identifier f,ret,i;
expression e;
constant c;
@@

// identify a function that returns a negative return value at least once.
f(...) {
... when any
(
return -c at i;
|
ret = -c at i;
... when != ret = e
return ret;
|
if (ret < 0) { ... return ret; }
)
... when any
}

@r exists@
identifier ret,ok.f,fn;
expression e1,e2,e3,e4,e5,e6,x;
statement S,S1;
position p1,p2,p3;
@@

// identify a case where the return variable is set to a non-negative value
// and then returned in error-handling code
f(...) {
... when any
(
if at p1 (\(ret < 0\|ret != 0\))
 { ... return ret; }
|
ret at p1 = 0
)
... when != \(ret = e1\|ret++\|ret--\|ret+=e1\|ret-=e1\)
    when != &ret
    when any
(
 if (<+... ret = e5 ...+>) S1
|
 if (<+... &ret ...+>) S1
|
if at p2(<+...x = fn(...)...+>)
 {
  ... when != ret = e6
      when forall
 return at p3 ret;
}
|
break;
|
x = fn(...)
... when != \(ret = e4\|ret++\|ret--\|ret+=e4\|ret-=e4\)
    when != &ret
(
 if (<+... ret = e3 ...+>) S
|
 if (<+... &ret ...+>) S
|
if at p2(<+...\(x != 0\|x < 0\|x == NULL\|IS_ERR(x)\)...+>)
 {
  ... when != ret = e2
      when forall
 return at p3 ret;
}
)
)
... when any
}

@printer depends on r@
position p;
identifier ok.f,pr;
constant char [] c;
@@

f(...) { <...pr at p(...,c,...)...> }

@bad0 exists@
identifier r.ret,ok.f,g != {ERR_PTR,IS_ERR};
position p != printer.p;
@@

f(...) { ... when any
g at p(...,ret,...)
... when any
 }

@bad depends on !bad0 exists@
position r.p1,r.p2;
statement S1,S2;
identifier r.ret;
expression e1;
@@

// ignore the above if there is some path where the variable is set to
// something else
(
if at p1 (\(ret < 0\|ret != 0\)) S1
|
ret at p1 = 0
)
... when any
 \(ret = e1\|ret++\|ret--\|ret+=e1\|ret-=e1\|&ret\)
... when any
if at p2(...) S2

@bad1 depends on !bad0 && !bad exists@
position r.p2;
statement S2;
identifier r.ret;
expression e1;
constant c;
@@

ret = -c
... when != \(ret = e1\|ret++\|ret--\|ret+=e1\|ret-=e1\)
    when != &ret
    when any
if at p2(...) S2

@bad2 depends on !bad0 && !bad && !bad1 exists@
position r.p1,r.p2;
identifier r.ret;
expression e1;
statement S2;
constant c;
@@

// likewise ignore it if there has been an intervening return
ret at p1 = 0
... when != if (...) { ... ret = e1 ... return ret; }
    when != if (...) { ... return -c; }
    when any
if at p2(...) S2

@script:python depends on !bad0 && !bad && !bad1 && !bad2@
p1 << r.p1;
p2 << r.p2;
p3 << r.p3;
@@

cocci.print_main("",p1)
cocci.print_secs("",p2)
cocci.print_secs("",p3)
// </smpl>



From Julia.Lawall at lip6.fr  Sat Aug 22 17:11:13 2015
From: Julia.Lawall at lip6.fr (Julia Lawall)
Date: Sun, 23 Aug 2015 02:11:13 +0200
Subject: [PATCH 02/11] soc: ti: knav_qmss_queue: fix error return code
In-Reply-To: <1440288682-12732-1-git-send-email-Julia.Lawall@lip6.fr>
References: <1440288682-12732-1-git-send-email-Julia.Lawall@lip6.fr>
Message-ID: <1440288682-12732-3-git-send-email-Julia.Lawall@lip6.fr>

Return a negative error code on failure.

A simplified version of the semantic match that finds this problem is as
follows: (http://coccinelle.lip6.fr/)

// <smpl>
@@
identifier ret; expression e1,e2;
@@
(
if (\(ret < 0\|ret != 0\))
 { ... return ret; }
|
ret = 0
)
... when != ret = e1
    when != &ret
*if(...)
{
  ... when != ret = e2
      when forall
 return ret;
}
// </smpl>

Signed-off-by: Julia Lawall <Julia.Lawall at lip6.fr>

---
 drivers/soc/ti/knav_qmss_queue.c |    1 +
 1 file changed, 1 insertion(+)

diff --git a/drivers/soc/ti/knav_qmss_queue.c b/drivers/soc/ti/knav_qmss_queue.c
index 6d8646d..822ead8 100644
--- a/drivers/soc/ti/knav_qmss_queue.c
+++ b/drivers/soc/ti/knav_qmss_queue.c
@@ -1768,6 +1768,7 @@ static int knav_queue_probe(struct platform_device *pdev)
 	regions =  of_get_child_by_name(node, "descriptor-regions");
 	if (!regions) {
 		dev_err(dev, "descriptor-regions not specified\n");
+		ret = -ENODEV;
 		goto err;
 	}
 	ret = knav_queue_setup_regions(kdev, regions);



From Julia.Lawall at lip6.fr  Sat Aug 22 17:11:19 2015
From: Julia.Lawall at lip6.fr (Julia Lawall)
Date: Sun, 23 Aug 2015 02:11:19 +0200
Subject: [PATCH 08/11] drm/exynos: mic: fix error return code
In-Reply-To: <1440288682-12732-1-git-send-email-Julia.Lawall@lip6.fr>
References: <1440288682-12732-1-git-send-email-Julia.Lawall@lip6.fr>
Message-ID: <1440288682-12732-9-git-send-email-Julia.Lawall@lip6.fr>

Propagate error code on failure.

A simplified version of the semantic match that finds this problem is as
follows: (http://coccinelle.lip6.fr/)

// <smpl>
@@
identifier ret; expression e1,e2;
@@
(
if (\(ret < 0\|ret != 0\))
 { ... return ret; }
|
ret = 0
)
... when != ret = e1
    when != &ret
*if(...)
{
  ... when != ret = e2
      when forall
 return ret;
}
// </smpl>

Signed-off-by: Julia Lawall <Julia.Lawall at lip6.fr>

---
 drivers/gpu/drm/exynos/exynos_drm_mic.c |    1 +
 1 file changed, 1 insertion(+)

diff --git a/drivers/gpu/drm/exynos/exynos_drm_mic.c b/drivers/gpu/drm/exynos/exynos_drm_mic.c
index 8994eab..ddf0b6c 100644
--- a/drivers/gpu/drm/exynos/exynos_drm_mic.c
+++ b/drivers/gpu/drm/exynos/exynos_drm_mic.c
@@ -432,6 +432,7 @@ int exynos_mic_probe(struct platform_device *pdev)
 							"samsung,disp-syscon");
 	if (IS_ERR(mic->sysreg)) {
 		DRM_ERROR("mic: Failed to get system register.\n");
+		ret = PTR_ERR(mic->sysreg);
 		goto err;
 	}
 



From santosh.shilimkar at oracle.com  Sat Aug 22 18:12:42 2015
From: santosh.shilimkar at oracle.com (santosh.shilimkar at oracle.com)
Date: Sat, 22 Aug 2015 18:12:42 -0700
Subject: [PATCH 02/11] soc: ti: knav_qmss_queue: fix error return code
In-Reply-To: <1440288682-12732-3-git-send-email-Julia.Lawall@lip6.fr>
References: <1440288682-12732-1-git-send-email-Julia.Lawall@lip6.fr>
 <1440288682-12732-3-git-send-email-Julia.Lawall@lip6.fr>
Message-ID: <55D91E0A.20602@oracle.com>

On 8/22/15 5:11 PM, Julia Lawall wrote:
> Return a negative error code on failure.
>
> A simplified version of the semantic match that finds this problem is as
> follows: (http://coccinelle.lip6.fr/)
>
> // <smpl>
> @@
> identifier ret; expression e1,e2;
> @@
> (
> if (\(ret < 0\|ret != 0\))
>   { ... return ret; }
> |
> ret = 0
> )
> ... when != ret = e1
>      when != &ret
> *if(...)
> {
>    ... when != ret = e2
>        when forall
>   return ret;
> }
> // </smpl>
>
> Signed-off-by: Julia Lawall <Julia.Lawall at lip6.fr>
>
Acked-by: Santosh Shilimkar <ssantosh at kernel.org>


From stefan at agner.ch  Sat Aug 22 18:36:54 2015
From: stefan at agner.ch (Stefan Agner)
Date: Sat, 22 Aug 2015 18:36:54 -0700
Subject: [PATCH v4 2/3] input: Add DT binding documentation for Colibri
 VF50 touchscreen
In-Reply-To: <8446d6df4b39f0b0acdc37afd4d66dbcca4d09ba.1440162473.git.maitysanchayan@gmail.com>
References: <cover.1440162473.git.maitysanchayan@gmail.com>
 <8446d6df4b39f0b0acdc37afd4d66dbcca4d09ba.1440162473.git.maitysanchayan@gmail.com>
Message-ID: <24b47f359d019e8871887777372b442b@agner.ch>

On 2015-08-21 06:26, Sanchayan Maity wrote:
> This adds device tree binding documentation for the Colibri VF50
> touchscreen driver.
> 
> Signed-off-by: Sanchayan Maity <maitysanchayan at gmail.com>
> ---
>  .../bindings/input/touchscreen/colibri-vf50-ts.txt | 36 ++++++++++++++++++++++
>  1 file changed, 36 insertions(+)
>  create mode 100644
> Documentation/devicetree/bindings/input/touchscreen/colibri-vf50-ts.txt
> 
> diff --git
> a/Documentation/devicetree/bindings/input/touchscreen/colibri-vf50-ts.txt
> b/Documentation/devicetree/bindings/input/touchscreen/colibri-vf50-ts.txt
> new file mode 100644
> index 0000000..e615aa9
> --- /dev/null
> +++ b/Documentation/devicetree/bindings/input/touchscreen/colibri-vf50-ts.txt
> @@ -0,0 +1,36 @@
> +* Toradex Colibri VF50 Touchscreen driver
> +
> +Required Properties:
> +- compatible must be toradex,vf50-touchscreen
> +- io-channels: adc channels being used by the Colibri VF50 module
> +- xp-gpios: FET gate driver for input of X+
> +- xm-gpios: FET gate driver for input of X-
> +- yp-gpios: FET gate driver for input of Y+
> +- ym-gpios: FET gate driver for input of Y-
> +- interrupt-parent: phandle for the interrupt controller
> +- interrupts: pen irq interrupt for touch detection

I like the use of the interrupt interface for the touch detection pin.
Maybe you can mention here that this is (typically) a GPIO...

> +- pinctrl-names: "idle", "default", "gpios"
> +- pinctrl-0: pinctrl node for idle state gpio pinmux
> +- pinctrl-1: pinctrl node for touch detection state pinmux

"touch detection" for default is rather confusing or even wrong. The
Idle state is used for pen/touch detection, default is used for X/Y and
Pressure measurement (maybe better described as touch measurement).

> +- pinctrl-2: pinctrl node for gpios functioning as FET gate drivers
> +- vf50-ts-min-pressure: pressure level at which to stop measuring X/Y values
> +
> +Example:
> +
> +	touchctrl: vf50_touchctrl {
> +		compatible = "toradex,vf50-touchscreen";
> +		io-channels = <&adc1 0>,<&adc0 0>,
> +				<&adc0 1>,<&adc1 2>;
> +		xp-gpios = <&gpio0 13 GPIO_ACTIVE_LOW>;
> +		xm-gpios = <&gpio2 29 GPIO_ACTIVE_HIGH>;
> +		yp-gpios = <&gpio0 12 GPIO_ACTIVE_LOW>;
> +		ym-gpios = <&gpio0 4 GPIO_ACTIVE_HIGH>;
> +		interrupt-parent = <&gpio0>;
> +		interrupts = <8 IRQ_TYPE_LEVEL_LOW>;
> +		pinctrl-names = "idle","default","gpios";
> +		pinctrl-0 = <&pinctrl_touchctrl_idle>;
> +		pinctrl-1 = <&pinctrl_touchctrl_default>;
> +		pinctrl-2 = <&pinctrl_touchctrl_gpios>;
> +		vf50-ts-min-pressure = <200>;
> +		status = "disabled";
> +	};

Otherwise I agree with 1 and 2:

Acked-by: Stefan Agner <stefan at agner.ch>

--
Stefan



From stefan at agner.ch  Sat Aug 22 18:52:28 2015
From: stefan at agner.ch (Stefan Agner)
Date: Sat, 22 Aug 2015 18:52:28 -0700
Subject: [PATCH v4 3/3] touchscreen: colibri-vf50-ts: Add touchscreen
 support for Colibri VF50
In-Reply-To: <915c9122cfba83c6fbbc519c10ae2d101e27bc5b.1440162473.git.maitysanchayan@gmail.com>
References: <cover.1440162473.git.maitysanchayan@gmail.com>
 <915c9122cfba83c6fbbc519c10ae2d101e27bc5b.1440162473.git.maitysanchayan@gmail.com>
Message-ID: <c5cd11ba9b5c3ec228a120e0f1c3c156@agner.ch>

Hi Sanchayan,

On 2015-08-21 06:26, Sanchayan Maity wrote:
> +static int vf50_ts_probe(struct platform_device *pdev)
> +{
> +	struct input_dev *input;
> +	struct iio_channel *channels;
> +	struct device *dev = &pdev->dev;
> +	struct vf50_touch_device *touchdev;
> +	int error;
> +
> +	channels = iio_channel_get_all(dev);
> +	if (IS_ERR(channels))
> +		return PTR_ERR(channels);

Hm, we expect here that four channels are returned, however a faulty
device tree could contain less. Access to the fourth channel above would
lead to a bug.

Can you check the amount of channels returned? The returned list is
explicitly terminated with a null entry, you can rely on that. Something
similar to hwmon should do the job.
http://lxr.free-electrons.com/source/drivers/hwmon/iio_hwmon.c#L86


Otherwise, Acked-by: Stefan Agner <stefan at agner.ch>

--
Stefan


From stefan at agner.ch  Sat Aug 22 18:54:28 2015
From: stefan at agner.ch (Stefan Agner)
Date: Sat, 22 Aug 2015 18:54:28 -0700
Subject: [PATCH v4 1/3] ARM: dts: vf500-colibri: Add device tree node for
 touchscreen support
In-Reply-To: <a960c538cf419a816d73fbea7d4380ea773aa6ba.1440162473.git.maitysanchayan@gmail.com>
References: <cover.1440162473.git.maitysanchayan@gmail.com>
 <a960c538cf419a816d73fbea7d4380ea773aa6ba.1440162473.git.maitysanchayan@gmail.com>
Message-ID: <a20cfadaea07ab255ac94fd5e567e5cf@agner.ch>

On 2015-08-21 06:26, Sanchayan Maity wrote:
> Add device tree node for touchscreen support on Colibri VF50. The
> touchscreen functionality on VF50 uses the ADC channels of Vybrid
> and some GPIOs. Also add pinctrl nodes for proper pinmux.
> 
> Signed-off-by: Sanchayan Maity <maitysanchayan at gmail.com>
> ---
>  arch/arm/boot/dts/vf500-colibri-eval-v3.dts |  4 +++
>  arch/arm/boot/dts/vf500-colibri.dtsi        | 47 +++++++++++++++++++++++++++++
>  2 files changed, 51 insertions(+)
> 
> diff --git a/arch/arm/boot/dts/vf500-colibri-eval-v3.dts
> b/arch/arm/boot/dts/vf500-colibri-eval-v3.dts
> index 7fc782c..14c0b00 100644
> --- a/arch/arm/boot/dts/vf500-colibri-eval-v3.dts
> +++ b/arch/arm/boot/dts/vf500-colibri-eval-v3.dts
> @@ -15,3 +15,7 @@
>  	model = "Toradex Colibri VF50 on Colibri Evaluation Board";
>  	compatible = "toradex,vf500-colibri_vf50-on-eval",
> "toradex,vf500-colibri_vf50", "fsl,vf500";
>  };
> +
> +&touchscreen {
> +	status = "okay";
> +};
> diff --git a/arch/arm/boot/dts/vf500-colibri.dtsi
> b/arch/arm/boot/dts/vf500-colibri.dtsi
> index cee34a3..84f091d 100644
> --- a/arch/arm/boot/dts/vf500-colibri.dtsi
> +++ b/arch/arm/boot/dts/vf500-colibri.dtsi
> @@ -17,4 +17,51 @@
>  	memory {
>  		reg = <0x80000000 0x8000000>;
>  	};
> +
> +	touchscreen: vf50-touchscreen {
> +		compatible = "toradex,vf50-touchscreen";
> +		io-channels = <&adc1 0>,<&adc0 0>,
> +				<&adc0 1>,<&adc1 2>;
> +		xp-gpios = <&gpio0 13 GPIO_ACTIVE_LOW>;
> +		xm-gpios = <&gpio2 29 GPIO_ACTIVE_HIGH>;
> +		yp-gpios = <&gpio0 12 GPIO_ACTIVE_LOW>;
> +		ym-gpios = <&gpio0 4 GPIO_ACTIVE_HIGH>;
> +		interrupt-parent = <&gpio0>;
> +		interrupts = <8 IRQ_TYPE_LEVEL_LOW>;
> +		pinctrl-names = "idle","default","gpios";
> +		pinctrl-0 = <&pinctrl_touchctrl_idle>;
> +		pinctrl-1 = <&pinctrl_touchctrl_default>;
> +		pinctrl-2 = <&pinctrl_touchctrl_gpios>;
> +		vf50-ts-min-pressure = <200>;

Since this is a touch screen related property, we even would want to
have that in the board specific device-tree (vf500-colibri-eval-v3.dts).


--
Stefan


From scott.shu at mediatek.com  Sun Aug 23 02:01:00 2015
From: scott.shu at mediatek.com (Scott Shu)
Date: Sun, 23 Aug 2015 17:01:00 +0800
Subject: [PATCH v4 1/8] Document: bindings: DT: Add SMP enable method for
 MT6580 SoC platform
In-Reply-To: <1440320467-26118-1-git-send-email-scott.shu@mediatek.com>
References: <1440320467-26118-1-git-send-email-scott.shu@mediatek.com>
Message-ID: <1440320467-26118-2-git-send-email-scott.shu@mediatek.com>

For MT6580 SoC platform, the secondary cores are in powered off state
as default, so compared with MT6589, one new enable method is needed.
This method using the SPM (System Power Manager) inside the SCPSYS to
control the CPU power.

Signed-off-by: Scott Shu <scott.shu at mediatek.com>
---
 Documentation/devicetree/bindings/arm/cpus.txt | 1 +
 1 file changed, 1 insertion(+)

diff --git a/Documentation/devicetree/bindings/arm/cpus.txt b/Documentation/devicetree/bindings/arm/cpus.txt
index d58eb45..66a8f03 100644
--- a/Documentation/devicetree/bindings/arm/cpus.txt
+++ b/Documentation/devicetree/bindings/arm/cpus.txt
@@ -195,6 +195,7 @@ nodes to be present and contain the properties described below.
 			    "marvell,armada-380-smp"
 			    "marvell,armada-390-smp"
 			    "marvell,armada-xp-smp"
+			    "mediatek,mt6580-smp"
 			    "mediatek,mt6589-smp"
 			    "mediatek,mt81xx-tz-smp"
 			    "qcom,gcc-msm8660"
-- 
1.9.1

************* Email Confidentiality Notice ********************
The information contained in this e-mail message (including any 
attachments) may be confidential, proprietary, privileged, or otherwise
exempt from disclosure under applicable laws. It is intended to be 
conveyed only to the designated recipient(s). Any use, dissemination, 
distribution, printing, retaining or copying of this e-mail (including its 
attachments) by unintended recipient(s) is strictly prohibited and may 
be unlawful. If you are not an intended recipient of this e-mail, or believe 
that you have received this e-mail in error, please notify the sender 
immediately (by replying to this e-mail), delete any and all copies of 
this e-mail (including any attachments) from your system, and do not
disclose the content of this e-mail to any other person. Thank you!


From scott.shu at mediatek.com  Sun Aug 23 02:01:01 2015
From: scott.shu at mediatek.com (Scott Shu)
Date: Sun, 23 Aug 2015 17:01:01 +0800
Subject: [PATCH v4 2/8] dt-bindings: soc: Add SCPSYS compatible support for
 mt6580
In-Reply-To: <1440320467-26118-1-git-send-email-scott.shu@mediatek.com>
References: <1440320467-26118-1-git-send-email-scott.shu@mediatek.com>
Message-ID: <1440320467-26118-3-git-send-email-scott.shu@mediatek.com>

This adds "mediatek,mt6580-scpsys" in the compatible properties of
SCPSYS node for MT6580 SoC.

Signed-off-by: Scott Shu <scott.shu at mediatek.com>
---
 Documentation/devicetree/bindings/soc/mediatek/scpsys.txt | 2 +-
 1 file changed, 1 insertion(+), 1 deletion(-)

diff --git a/Documentation/devicetree/bindings/soc/mediatek/scpsys.txt b/Documentation/devicetree/bindings/soc/mediatek/scpsys.txt
index c051114..7998bc2 100644
--- a/Documentation/devicetree/bindings/soc/mediatek/scpsys.txt
+++ b/Documentation/devicetree/bindings/soc/mediatek/scpsys.txt
@@ -12,7 +12,7 @@ power/power_domain.txt. It provides the power domains defined in
 include/dt-bindings/power/mt8173-power.h.
 
 Required properties:
-- compatible: Must be "mediatek,mt8173-scpsys"
+- compatible: Must be "mediatek,mt6580-scpsys" or "mediatek,mt8173-scpsys"
 - #power-domain-cells: Must be 1
 - reg: Address range of the SCPSYS unit
 - infracfg: must contain a phandle to the infracfg controller
-- 
1.9.1

************* Email Confidentiality Notice ********************
The information contained in this e-mail message (including any 
attachments) may be confidential, proprietary, privileged, or otherwise
exempt from disclosure under applicable laws. It is intended to be 
conveyed only to the designated recipient(s). Any use, dissemination, 
distribution, printing, retaining or copying of this e-mail (including its 
attachments) by unintended recipient(s) is strictly prohibited and may 
be unlawful. If you are not an intended recipient of this e-mail, or believe 
that you have received this e-mail in error, please notify the sender 
immediately (by replying to this e-mail), delete any and all copies of 
this e-mail (including any attachments) from your system, and do not
disclose the content of this e-mail to any other person. Thank you!


From scott.shu at mediatek.com  Sun Aug 23 02:00:59 2015
From: scott.shu at mediatek.com (Scott Shu)
Date: Sun, 23 Aug 2015 17:00:59 +0800
Subject: [PATCH v4 0/8] This series adds SMP support for the MediaTek MT6580.
Message-ID: <1440320467-26118-1-git-send-email-scott.shu@mediatek.com>

This patchset adds support SMP on MediaTek MT6580 Cortex-A7 quad-core SoC.

This is based on v4.2-rc1 and following patch series:
(1) Yingjoe Chen's "Add SMP bringup support for mt65xx socs" [1]
(2) Mars Cheng's "Add mt6580 basic chip support" [2]
(3) Sascha Hauer's "Mediatek SCPSYS power domain support" [3]

The secondary cores are power off as default on MT6580, this change adds
a new enable-method to turn on power to the cores during booting process.

The System Power Manager (SPM) inside the SCPSYS is for the CPU MTCMOS
power domain control. Please check [3] for more information about SCPSYS.

[1] https://lkml.org/lkml/2015/5/16/33
[2] https://lkml.org/lkml/2015/6/30/119
[3] https://lkml.org/lkml/2015/6/9/172

Change in v4:
1. Remove boot_lock and pen_release stuff
2. Fix some coding style

Change in v3:
1. Add CPU power control in SCPSYS driver

Change in v2:
1. Rebase to 4.2-rc1
2. Fix using usleep() in atomic context
3. Put a timeout in cpu power on/off sequence
4. Fix some coding style

Scott Shu (8):
  Document: bindings: DT: Add SMP enable method for MT6580 SoC platform
  dt-bindings: soc: Add SCPSYS compatible support for mt6580
  soc: Mediatek: Add SCPSYS CPU power domain driver
  ARM: multi_v7_defconfig: enable INFRACFG and SCPSYS modules
  ARM: mediatek: add smp bringup code for MT6580
  ARM: Mediatek: enable GPT6 on boot up to make arch timer working    
    for MT6580
  ARM: dts: mt6580: Add device nodes to the MT6580 dtsi file
  ARM: dts: mt6580: enable basic SMP bringup for MT6580

 Documentation/devicetree/bindings/arm/cpus.txt     |   1 +
 .../devicetree/bindings/soc/mediatek/scpsys.txt    |   2 +-
 arch/arm/boot/dts/mt6580.dtsi                      |  26 +++
 arch/arm/configs/multi_v7_defconfig                |   2 +
 arch/arm/mach-mediatek/mediatek.c                  |   4 +-
 arch/arm/mach-mediatek/platsmp.c                   |  67 ++++++
 drivers/soc/mediatek/mtk-scpsys.c                  | 250 +++++++++++++++++++++
 include/linux/soc/mediatek/scpsys.h                |   9 +
 8 files changed, 359 insertions(+), 2 deletions(-)
 create mode 100644 include/linux/soc/mediatek/scpsys.h

-- 
1.9.1

************* Email Confidentiality Notice ********************
The information contained in this e-mail message (including any 
attachments) may be confidential, proprietary, privileged, or otherwise
exempt from disclosure under applicable laws. It is intended to be 
conveyed only to the designated recipient(s). Any use, dissemination, 
distribution, printing, retaining or copying of this e-mail (including its 
attachments) by unintended recipient(s) is strictly prohibited and may 
be unlawful. If you are not an intended recipient of this e-mail, or believe 
that you have received this e-mail in error, please notify the sender 
immediately (by replying to this e-mail), delete any and all copies of 
this e-mail (including any attachments) from your system, and do not
disclose the content of this e-mail to any other person. Thank you!


From scott.shu at mediatek.com  Sun Aug 23 02:01:03 2015
From: scott.shu at mediatek.com (Scott Shu)
Date: Sun, 23 Aug 2015 17:01:03 +0800
Subject: [PATCH v4 4/8] ARM: multi_v7_defconfig: enable INFRACFG and SCPSYS
 modules
In-Reply-To: <1440320467-26118-1-git-send-email-scott.shu@mediatek.com>
References: <1440320467-26118-1-git-send-email-scott.shu@mediatek.com>
Message-ID: <1440320467-26118-5-git-send-email-scott.shu@mediatek.com>

The INFRACFG contains various infrastructure registers and the SCPSYS handles
several power management related tasks. Both are needed for SMP and CPU
hotplug on MT6580.

Signed-off-by: Scott Shu <scott.shu at mediatek.com>
---
 arch/arm/configs/multi_v7_defconfig | 2 ++
 1 file changed, 2 insertions(+)

diff --git a/arch/arm/configs/multi_v7_defconfig b/arch/arm/configs/multi_v7_defconfig
index 6d83a1b..c272edd 100644
--- a/arch/arm/configs/multi_v7_defconfig
+++ b/arch/arm/configs/multi_v7_defconfig
@@ -596,6 +596,8 @@ CONFIG_KEYBOARD_NVEC=y
 CONFIG_SERIO_NVEC_PS2=y
 CONFIG_NVEC_POWER=y
 CONFIG_NVEC_PAZ00=y
+CONFIG_MTK_INFRACFG=y
+CONFIG_MTK_SCPSYS=y
 CONFIG_QCOM_GSBI=y
 CONFIG_QCOM_PM=y
 CONFIG_COMMON_CLK_QCOM=y
-- 
1.9.1

************* Email Confidentiality Notice ********************
The information contained in this e-mail message (including any 
attachments) may be confidential, proprietary, privileged, or otherwise
exempt from disclosure under applicable laws. It is intended to be 
conveyed only to the designated recipient(s). Any use, dissemination, 
distribution, printing, retaining or copying of this e-mail (including its 
attachments) by unintended recipient(s) is strictly prohibited and may 
be unlawful. If you are not an intended recipient of this e-mail, or believe 
that you have received this e-mail in error, please notify the sender 
immediately (by replying to this e-mail), delete any and all copies of 
this e-mail (including any attachments) from your system, and do not
disclose the content of this e-mail to any other person. Thank you!


From scott.shu at mediatek.com  Sun Aug 23 02:01:07 2015
From: scott.shu at mediatek.com (Scott Shu)
Date: Sun, 23 Aug 2015 17:01:07 +0800
Subject: [PATCH v4 8/8] ARM: dts: mt6580: enable basic SMP bringup for MT6580
In-Reply-To: <1440320467-26118-1-git-send-email-scott.shu@mediatek.com>
References: <1440320467-26118-1-git-send-email-scott.shu@mediatek.com>
Message-ID: <1440320467-26118-9-git-send-email-scott.shu@mediatek.com>

Add arch timer node to enable arch-timer support. MT6580 firmware
doesn't correctly setup arch-timer frequency and CNTVOFF, add
properties to workaround this.

This set cpu enable-method to enable SMP.

Signed-off-by: Scott Shu <scott.shu at mediatek.com>
---
 arch/arm/boot/dts/mt6580.dtsi | 20 ++++++++++++++++++++
 1 file changed, 20 insertions(+)

diff --git a/arch/arm/boot/dts/mt6580.dtsi b/arch/arm/boot/dts/mt6580.dtsi
index 40957d3..70531b2 100644
--- a/arch/arm/boot/dts/mt6580.dtsi
+++ b/arch/arm/boot/dts/mt6580.dtsi
@@ -25,26 +25,31 @@
 	cpus {
 		#address-cells = <1>;
 		#size-cells = <0>;
+		enable-method = "mediatek,mt6580-smp";
 
 		cpu at 0 {
 			device_type = "cpu";
 			compatible = "arm,cortex-a7";
 			reg = <0x0>;
+			clock-frequency = <1700000000>;
 		};
 		cpu at 1 {
 			device_type = "cpu";
 			compatible = "arm,cortex-a7";
 			reg = <0x1>;
+			clock-frequency = <1700000000>;
 		};
 		cpu at 2 {
 			device_type = "cpu";
 			compatible = "arm,cortex-a7";
 			reg = <0x2>;
+			clock-frequency = <1700000000>;
 		};
 		cpu at 3 {
 			device_type = "cpu";
 			compatible = "arm,cortex-a7";
 			reg = <0x3>;
+			clock-frequency = <1700000000>;
 		};
 
 	};
@@ -67,6 +72,21 @@
 		#clock-cells = <0>;
 	};
 
+	timer {
+		compatible = "arm,armv7-timer";
+		interrupt-parent = <&gic>;
+		interrupts = <GIC_PPI 13 (GIC_CPU_MASK_SIMPLE(4) |
+					  IRQ_TYPE_LEVEL_LOW)>,
+				<GIC_PPI 14 (GIC_CPU_MASK_SIMPLE(4) |
+					  IRQ_TYPE_LEVEL_LOW)>,
+				<GIC_PPI 11 (GIC_CPU_MASK_SIMPLE(4) |
+					  IRQ_TYPE_LEVEL_LOW)>,
+				<GIC_PPI 10 (GIC_CPU_MASK_SIMPLE(4) |
+					  IRQ_TYPE_LEVEL_LOW)>;
+		clock-frequency = <13000000>;
+		arm,cpu-registers-not-fw-configured;
+	};
+
 	scpsys: scpsys at 10006000 {
 		#power-domain-cells = <1>;
 		compatible = "mediatek,mt6580-scpsys";
-- 
1.9.1

************* Email Confidentiality Notice ********************
The information contained in this e-mail message (including any 
attachments) may be confidential, proprietary, privileged, or otherwise
exempt from disclosure under applicable laws. It is intended to be 
conveyed only to the designated recipient(s). Any use, dissemination, 
distribution, printing, retaining or copying of this e-mail (including its 
attachments) by unintended recipient(s) is strictly prohibited and may 
be unlawful. If you are not an intended recipient of this e-mail, or believe 
that you have received this e-mail in error, please notify the sender 
immediately (by replying to this e-mail), delete any and all copies of 
this e-mail (including any attachments) from your system, and do not
disclose the content of this e-mail to any other person. Thank you!


From scott.shu at mediatek.com  Sun Aug 23 02:01:02 2015
From: scott.shu at mediatek.com (Scott Shu)
Date: Sun, 23 Aug 2015 17:01:02 +0800
Subject: [PATCH v4 3/8] soc: Mediatek: Add SCPSYS CPU power domain driver
In-Reply-To: <1440320467-26118-1-git-send-email-scott.shu@mediatek.com>
References: <1440320467-26118-1-git-send-email-scott.shu@mediatek.com>
Message-ID: <1440320467-26118-4-git-send-email-scott.shu@mediatek.com>

This adds a CPU power domain driver for the Mediatek SCPSYS unit on
MT6580.

Signed-off-by: Scott Shu <scott.shu at mediatek.com>
---
 drivers/soc/mediatek/mtk-scpsys.c   | 250 ++++++++++++++++++++++++++++++++++++
 include/linux/soc/mediatek/scpsys.h |   9 ++
 2 files changed, 259 insertions(+)
 create mode 100644 include/linux/soc/mediatek/scpsys.h

diff --git a/drivers/soc/mediatek/mtk-scpsys.c b/drivers/soc/mediatek/mtk-scpsys.c
index 43a79ed..8136185 100644
--- a/drivers/soc/mediatek/mtk-scpsys.c
+++ b/drivers/soc/mediatek/mtk-scpsys.c
@@ -15,18 +15,30 @@
 #include <linux/io.h>
 #include <linux/kernel.h>
 #include <linux/mfd/syscon.h>
+#include <linux/of.h>
 #include <linux/of_device.h>
+#include <linux/of_address.h>
 #include <linux/platform_device.h>
 #include <linux/pm_domain.h>
 #include <linux/regmap.h>
 #include <linux/soc/mediatek/infracfg.h>
+#include <linux/soc/mediatek/scpsys.h>
 #include <dt-bindings/power/mt8173-power.h>
 
+#define SPM_POWERON_CONFIG_SET		0x0000
+#define SPM_CA7_CPU0_PWR_CON		0x0200
 #define SPM_VDE_PWR_CON			0x0210
 #define SPM_MFG_PWR_CON			0x0214
+#define SPM_CA7_CPU1_PWR_CON		0x0218
+#define SPM_CA7_CPU2_PWR_CON		0x021c
+#define SPM_CA7_CPU3_PWR_CON		0x0220
 #define SPM_VEN_PWR_CON			0x0230
 #define SPM_ISP_PWR_CON			0x0238
 #define SPM_DIS_PWR_CON			0x023c
+#define SPM_CA7_CPU0_L1_PDN		0x025c
+#define SPM_CA7_CPU1_L1_PDN		0x0264
+#define SPM_CA7_CPU2_L1_PDN		0x026c
+#define SPM_CA7_CPU3_L1_PDN		0x0274
 #define SPM_VEN2_PWR_CON		0x0298
 #define SPM_AUDIO_PWR_CON		0x029c
 #define SPM_MFG_2D_PWR_CON		0x02c0
@@ -34,12 +46,20 @@
 #define SPM_USB_PWR_CON			0x02cc
 #define SPM_PWR_STATUS			0x060c
 #define SPM_PWR_STATUS_2ND		0x0610
+#define SPM_SLEEP_TIMER_STA		0x0720
 
+/* bit definition in SPM_CA7_CPUx_PWR_CON */
 #define PWR_RST_B_BIT			BIT(0)
 #define PWR_ISO_BIT			BIT(1)
 #define PWR_ON_BIT			BIT(2)
 #define PWR_ON_2ND_BIT			BIT(3)
 #define PWR_CLK_DIS_BIT			BIT(4)
+#define SRAM_CKISO_BIT			BIT(5)
+#define SRAM_ISOINT_B_BIT		BIT(6)
+
+/* bit definition in SPM_CA7_CPUx_L1_PDN */
+#define L1_PDN				BIT(0)
+#define L1_PDN_ACK			BIT(8)
 
 #define PWR_STATUS_DISP			BIT(3)
 #define PWR_STATUS_MFG			BIT(4)
@@ -52,6 +72,31 @@
 #define PWR_STATUS_AUDIO		BIT(24)
 #define PWR_STATUS_USB			BIT(25)
 
+#define MT6580_MAX_CPUS			4
+
+#define SPM_REGWR_EN		BIT(0)
+#define SPM_PROJECT_CODE	0x0B16
+
+#ifdef CONFIG_SMP
+static DEFINE_SPINLOCK(spm_cpu_lock);
+
+static void __iomem *spm_cpu_base;
+
+static const u32 spm_cpu_pwr_con[MT6580_MAX_CPUS] = {
+	SPM_CA7_CPU0_PWR_CON,
+	SPM_CA7_CPU1_PWR_CON,
+	SPM_CA7_CPU2_PWR_CON,
+	SPM_CA7_CPU3_PWR_CON,
+};
+
+static const u32 spm_cpu_l1_pdn[MT6580_MAX_CPUS] = {
+	SPM_CA7_CPU0_L1_PDN,
+	SPM_CA7_CPU1_L1_PDN,
+	SPM_CA7_CPU2_L1_PDN,
+	SPM_CA7_CPU3_L1_PDN,
+};
+#endif
+
 enum clk_id {
 	MT8173_CLK_MM,
 	MT8173_CLK_MFG,
@@ -485,3 +530,208 @@ static struct platform_driver scpsys_drv = {
 };
 
 module_platform_driver_probe(scpsys_drv, scpsys_probe);
+
+#ifdef CONFIG_SMP
+int scpsys_cpu_power_on(int cpu)
+{
+	unsigned long flags;
+	static u32 spmcpu_pwr_con, spmcpu_l1_pdn;
+	unsigned int cbit, temp;
+	int timeout = 10;
+	int ret = 0;
+
+	temp = (SPM_PROJECT_CODE << 16) | SPM_REGWR_EN;
+	writel_relaxed(temp, spm_cpu_base + SPM_POWERON_CONFIG_SET);
+
+	spmcpu_pwr_con = spm_cpu_pwr_con[cpu];
+	spmcpu_l1_pdn = spm_cpu_l1_pdn[cpu];
+
+	spin_lock_irqsave(&spm_cpu_lock, flags);
+
+	/* Set PWR_ON */
+	temp = readl_relaxed(spm_cpu_base + spmcpu_pwr_con);
+	temp |= PWR_ON_BIT;
+	writel_relaxed(temp, spm_cpu_base + spmcpu_pwr_con);
+
+	/* Wait for charging core power */
+	udelay(1);
+
+	/* Set PWR_ON_2ND */
+	temp = readl_relaxed(spm_cpu_base + spmcpu_pwr_con);
+	temp |= PWR_ON_2ND_BIT;
+	writel_relaxed(temp, spm_cpu_base + spmcpu_pwr_con);
+
+	/* Wait for the power-ack */
+	cbit = BIT(13 - cpu);
+	while (((readl_relaxed(spm_cpu_base + SPM_PWR_STATUS) &
+		 cbit) != cbit) ||
+	       (readl_relaxed(spm_cpu_base + SPM_PWR_STATUS_2ND) &
+		 cbit) != cbit) {
+		if (--timeout == 0) {
+			ret = -ENXIO;
+			goto fail;
+		}
+		udelay(1);
+	}
+
+	temp = readl_relaxed(spm_cpu_base + spmcpu_pwr_con);
+	temp &= ~PWR_ISO_BIT;
+	writel_relaxed(temp, spm_cpu_base + spmcpu_pwr_con);
+
+	/* L1 power on */
+	temp = readl_relaxed(spm_cpu_base + spmcpu_l1_pdn);
+	temp &= ~L1_PDN;
+	writel_relaxed(temp, spm_cpu_base + spmcpu_l1_pdn);
+	timeout = 10;
+	while ((readl_relaxed(spm_cpu_base + spmcpu_l1_pdn) &
+		L1_PDN_ACK) != 0) {
+		if (--timeout == 0) {
+			ret = -ENXIO;
+			goto fail;
+		}
+		udelay(1);
+	}
+
+	/* Wait for memory power ready */
+	udelay(1);
+
+	/* Set SRAM_ISOINT_B */
+	temp = readl_relaxed(spm_cpu_base + spmcpu_pwr_con);
+	temp |= SRAM_ISOINT_B_BIT;
+	writel_relaxed(temp, spm_cpu_base + spmcpu_pwr_con);
+
+	/* Clear SRAM_CKISO */
+	temp = readl_relaxed(spm_cpu_base + spmcpu_pwr_con);
+	temp &= ~SRAM_CKISO_BIT;
+	writel_relaxed(temp, spm_cpu_base + spmcpu_pwr_con);
+
+	/* Clear PWR_CLK_DIS */
+	temp = readl_relaxed(spm_cpu_base + spmcpu_pwr_con);
+	temp &= ~PWR_CLK_DIS_BIT;
+	writel_relaxed(temp, spm_cpu_base + spmcpu_pwr_con);
+
+	/* Set PWR_RST_B to finish power on and reset sequences */
+	temp = readl_relaxed(spm_cpu_base + spmcpu_pwr_con);
+	temp |= PWR_RST_B_BIT;
+	writel_relaxed(temp, spm_cpu_base + spmcpu_pwr_con);
+fail:
+	spin_unlock_irqrestore(&spm_cpu_lock, flags);
+
+	return ret;
+}
+
+int scpsys_cpu_power_off(int cpu, bool wfi)
+{
+	unsigned long flags;
+	static u32 spmcpu_pwr_con, spmcpu_l1_pdn;
+	unsigned int cbit, temp;
+	int timeout = 10;
+	int ret = 0;
+
+	temp = (SPM_PROJECT_CODE << 16) | SPM_REGWR_EN;
+	writel_relaxed(temp, spm_cpu_base + SPM_POWERON_CONFIG_SET);
+
+	spmcpu_pwr_con = spm_cpu_pwr_con[cpu];
+	spmcpu_l1_pdn = spm_cpu_l1_pdn[cpu];
+
+	if (wfi) {
+		while ((readl_relaxed(spm_cpu_base + SPM_SLEEP_TIMER_STA) &
+			(1U << (16 + cpu))) == 0) {
+			if (--timeout == 0)
+				return -ENXIO;
+			udelay(1);
+		}
+	}
+
+	spin_lock_irqsave(&spm_cpu_lock, flags);
+
+	/* Set PWR_ISO */
+	temp = readl_relaxed(spm_cpu_base + spmcpu_pwr_con);
+	temp |= PWR_ISO_BIT;
+	writel_relaxed(temp, spm_cpu_base + spmcpu_pwr_con);
+
+	/* Set SRAM_CKISO */
+	temp = readl_relaxed(spm_cpu_base + spmcpu_pwr_con);
+	temp |= SRAM_CKISO_BIT;
+	writel_relaxed(temp, spm_cpu_base + spmcpu_pwr_con);
+
+	/* Clear SRAM_ISOINT_B */
+	temp = readl_relaxed(spm_cpu_base + spmcpu_pwr_con);
+	temp &= ~SRAM_ISOINT_B_BIT;
+	writel_relaxed(temp, spm_cpu_base + spmcpu_pwr_con);
+
+	/* L1 power off */
+	temp = readl_relaxed(spm_cpu_base + spmcpu_l1_pdn);
+	temp |= L1_PDN;
+	writel_relaxed(temp, spm_cpu_base + spmcpu_l1_pdn);
+	timeout = 10;
+	while ((readl_relaxed(spm_cpu_base + spmcpu_l1_pdn) &
+		L1_PDN_ACK) != L1_PDN_ACK) {
+		if (--timeout == 0) {
+			ret = -ENXIO;
+			goto fail;
+		}
+		udelay(1);
+	}
+
+	/* Clear PWR_RST_B */
+	temp = readl_relaxed(spm_cpu_base + spmcpu_pwr_con);
+	temp &= ~PWR_RST_B_BIT;
+	writel_relaxed(temp, spm_cpu_base + spmcpu_pwr_con);
+
+	/* Set PWR_CLK_DIS */
+	temp = readl_relaxed(spm_cpu_base + spmcpu_pwr_con);
+	temp |= PWR_CLK_DIS_BIT;
+	writel_relaxed(temp, spm_cpu_base + spmcpu_pwr_con);
+
+	/* Clear PWR_ON */
+	temp = readl_relaxed(spm_cpu_base + spmcpu_pwr_con);
+	temp &= ~PWR_ON_BIT;
+	writel_relaxed(temp, spm_cpu_base + spmcpu_pwr_con);
+
+	/* Clear PWR_ON_2ND */
+	temp = readl_relaxed(spm_cpu_base + spmcpu_pwr_con);
+	temp &= ~PWR_ON_2ND_BIT;
+	writel_relaxed(temp, spm_cpu_base + spmcpu_pwr_con);
+
+	timeout = 10;
+	cbit = BIT(13 - cpu);
+	while (((readl_relaxed(spm_cpu_base + SPM_PWR_STATUS) & cbit) != 0) ||
+	       ((readl_relaxed(spm_cpu_base + SPM_PWR_STATUS_2ND) &
+		 cbit) != 0)) {
+		if (--timeout == 0) {
+			ret = -ENXIO;
+			goto fail;
+		}
+		udelay(1);
+	}
+fail:
+	spin_unlock_irqrestore(&spm_cpu_lock, flags);
+
+	return ret;
+}
+#endif /* CONFIG_SMP */
+
+static int __init mtk_scpsys_early_init(void)
+{
+	struct device_node *node;
+	struct resource regs;
+
+	node = of_find_compatible_node(NULL, NULL, "mediatek,mt6580-scpsys");
+	if (node) {
+		if (of_address_to_resource(node, 0, &regs) < 0) {
+			pr_err("Failed to get SCPSYS registers\n");
+			return -ENXIO;
+		}
+
+		spm_cpu_base = ioremap_nocache(regs.start,
+					       resource_size(&regs));
+		if (!spm_cpu_base) {
+			pr_err("%s: Unable to map I/O memory\n", __func__);
+			return -ENODEV;
+		}
+	}
+
+	return 0;
+}
+early_initcall(mtk_scpsys_early_init);
diff --git a/include/linux/soc/mediatek/scpsys.h b/include/linux/soc/mediatek/scpsys.h
new file mode 100644
index 0000000..4fe978d
--- /dev/null
+++ b/include/linux/soc/mediatek/scpsys.h
@@ -0,0 +1,9 @@
+#ifndef __SOC_MEDIATEK_SCPSYS_H
+#define __SOC_MEDIATEK_SCPSYS_H
+
+#include <linux/kernel.h>
+
+int scpsys_cpu_power_on(int cpu);
+int scpsys_cpu_power_off(int cpu, bool wfi);
+
+#endif
-- 
1.9.1

************* Email Confidentiality Notice ********************
The information contained in this e-mail message (including any 
attachments) may be confidential, proprietary, privileged, or otherwise
exempt from disclosure under applicable laws. It is intended to be 
conveyed only to the designated recipient(s). Any use, dissemination, 
distribution, printing, retaining or copying of this e-mail (including its 
attachments) by unintended recipient(s) is strictly prohibited and may 
be unlawful. If you are not an intended recipient of this e-mail, or believe 
that you have received this e-mail in error, please notify the sender 
immediately (by replying to this e-mail), delete any and all copies of 
this e-mail (including any attachments) from your system, and do not
disclose the content of this e-mail to any other person. Thank you!


From scott.shu at mediatek.com  Sun Aug 23 02:01:04 2015
From: scott.shu at mediatek.com (Scott Shu)
Date: Sun, 23 Aug 2015 17:01:04 +0800
Subject: [PATCH v4 5/8] ARM: mediatek: add smp bringup code for MT6580
In-Reply-To: <1440320467-26118-1-git-send-email-scott.shu@mediatek.com>
References: <1440320467-26118-1-git-send-email-scott.shu@mediatek.com>
Message-ID: <1440320467-26118-6-git-send-email-scott.shu@mediatek.com>

Add support for cpu enable-method "mediatek,mt6580-smp" for booting
secondary CPUs on MT6580.

Signed-off-by: Scott Shu <scott.shu at mediatek.com>
---
 arch/arm/mach-mediatek/platsmp.c | 67 ++++++++++++++++++++++++++++++++++++++++
 1 file changed, 67 insertions(+)

diff --git a/arch/arm/mach-mediatek/platsmp.c b/arch/arm/mach-mediatek/platsmp.c
index a5bc108..41fade2 100644
--- a/arch/arm/mach-mediatek/platsmp.c
+++ b/arch/arm/mach-mediatek/platsmp.c
@@ -21,10 +21,19 @@
 #include <linux/of_address.h>
 #include <linux/string.h>
 #include <linux/threads.h>
+#include <linux/delay.h>
+#include <asm/cacheflush.h>
+
+#include <linux/soc/mediatek/scpsys.h>
 
 #define MTK_MAX_CPU		8
 #define MTK_SMP_REG_SIZE	0x1000
 
+#define MT6580_INFRACFG_AO	0x10001000
+#define INFRACFG_AO_BOOT_ADDR	0x800
+#define INFRACFG_AO_SEC_CTRL	0x804
+#define SW_ROM_PD		BIT(31)
+
 struct mtk_smp_boot_info {
 	unsigned long smp_base;
 	unsigned int jump_reg;
@@ -56,6 +65,54 @@ static const struct of_device_id mtk_smp_boot_infos[] __initconst = {
 static void __iomem *mtk_smp_base;
 static const struct mtk_smp_boot_info *mtk_smp_info;
 
+#ifdef CONFIG_HOTPLUG_CPU
+static int mt6580_cpu_kill(unsigned cpu)
+{
+	int ret;
+
+	ret = scpsys_cpu_power_off(cpu, 1);
+	if (ret < 0)
+		return 0;
+
+	return 1;
+}
+
+static void mt6580_cpu_die(unsigned int cpu)
+{
+	for (;;)
+		cpu_do_idle();
+}
+#endif
+
+static int mt6580_boot_secondary(unsigned int cpu, struct task_struct *idle)
+{
+	return scpsys_cpu_power_on(cpu);
+}
+
+static void __init mt6580_smp_prepare_cpus(unsigned int max_cpus)
+{
+	static void __iomem *infracfg_ao_base;
+	static unsigned int temp;
+
+	infracfg_ao_base = ioremap(MT6580_INFRACFG_AO, 0x1000);
+	if (!infracfg_ao_base) {
+		pr_err("%s: Unable to map I/O memory\n", __func__);
+		return;
+	}
+
+	/* Enable bootrom power down mode */
+	temp = readl(infracfg_ao_base + INFRACFG_AO_SEC_CTRL);
+	temp |= SW_ROM_PD;
+	writel_relaxed(temp, infracfg_ao_base + INFRACFG_AO_SEC_CTRL);
+
+	/* Write the address of slave startup into boot address
+	   register for bootrom power down mode */
+	writel_relaxed(virt_to_phys(secondary_startup_arm),
+		       infracfg_ao_base + INFRACFG_AO_BOOT_ADDR);
+
+	iounmap(infracfg_ao_base);
+}
+
 static int mtk_boot_secondary(unsigned int cpu, struct task_struct *idle)
 {
 	if (!mtk_smp_base)
@@ -142,3 +199,13 @@ static struct smp_operations mt6589_smp_ops __initdata = {
 	.smp_boot_secondary = mtk_boot_secondary,
 };
 CPU_METHOD_OF_DECLARE(mt6589_smp, "mediatek,mt6589-smp", &mt6589_smp_ops);
+
+static struct smp_operations mt6580_smp_ops __initdata = {
+	.smp_prepare_cpus = mt6580_smp_prepare_cpus,
+	.smp_boot_secondary = mt6580_boot_secondary,
+#ifdef CONFIG_HOTPLUG_CPU
+	.cpu_kill = mt6580_cpu_kill,
+	.cpu_die = mt6580_cpu_die,
+#endif
+};
+CPU_METHOD_OF_DECLARE(mt6580_smp, "mediatek,mt6580-smp", &mt6580_smp_ops);
-- 
1.9.1

************* Email Confidentiality Notice ********************
The information contained in this e-mail message (including any 
attachments) may be confidential, proprietary, privileged, or otherwise
exempt from disclosure under applicable laws. It is intended to be 
conveyed only to the designated recipient(s). Any use, dissemination, 
distribution, printing, retaining or copying of this e-mail (including its 
attachments) by unintended recipient(s) is strictly prohibited and may 
be unlawful. If you are not an intended recipient of this e-mail, or believe 
that you have received this e-mail in error, please notify the sender 
immediately (by replying to this e-mail), delete any and all copies of 
this e-mail (including any attachments) from your system, and do not
disclose the content of this e-mail to any other person. Thank you!


From scott.shu at mediatek.com  Sun Aug 23 02:01:05 2015
From: scott.shu at mediatek.com (Scott Shu)
Date: Sun, 23 Aug 2015 17:01:05 +0800
Subject: [PATCH v4 6/8] ARM: Mediatek: enable GPT6 on boot up to make arch
 timer working for MT6580
In-Reply-To: <1440320467-26118-1-git-send-email-scott.shu@mediatek.com>
References: <1440320467-26118-1-git-send-email-scott.shu@mediatek.com>
Message-ID: <1440320467-26118-7-git-send-email-scott.shu@mediatek.com>

We enable GTP6 which ungates the arch timer clock.

Signed-off-by: Scott Shu <scott.shu at mediatek.com>
---
 arch/arm/mach-mediatek/mediatek.c | 4 +++-
 1 file changed, 3 insertions(+), 1 deletion(-)

diff --git a/arch/arm/mach-mediatek/mediatek.c b/arch/arm/mach-mediatek/mediatek.c
index 6b38d67..469d332 100644
--- a/arch/arm/mach-mediatek/mediatek.c
+++ b/arch/arm/mach-mediatek/mediatek.c
@@ -28,7 +28,8 @@ static void __init mediatek_timer_init(void)
 {
 	void __iomem *gpt_base = 0;
 
-	if (of_machine_is_compatible("mediatek,mt6589") ||
+	if (of_machine_is_compatible("mediatek,mt6580") ||
+	    of_machine_is_compatible("mediatek,mt6589") ||
 	    of_machine_is_compatible("mediatek,mt8135") ||
 	    of_machine_is_compatible("mediatek,mt8127")) {
 		/* turn on GPT6 which ungates arch timer clocks */
@@ -46,6 +47,7 @@ static void __init mediatek_timer_init(void)
 };
 
 static const char * const mediatek_board_dt_compat[] = {
+	"mediatek,mt6580",
 	"mediatek,mt6589",
 	"mediatek,mt6592",
 	"mediatek,mt8127",
-- 
1.9.1

************* Email Confidentiality Notice ********************
The information contained in this e-mail message (including any 
attachments) may be confidential, proprietary, privileged, or otherwise
exempt from disclosure under applicable laws. It is intended to be 
conveyed only to the designated recipient(s). Any use, dissemination, 
distribution, printing, retaining or copying of this e-mail (including its 
attachments) by unintended recipient(s) is strictly prohibited and may 
be unlawful. If you are not an intended recipient of this e-mail, or believe 
that you have received this e-mail in error, please notify the sender 
immediately (by replying to this e-mail), delete any and all copies of 
this e-mail (including any attachments) from your system, and do not
disclose the content of this e-mail to any other person. Thank you!


From scott.shu at mediatek.com  Sun Aug 23 02:01:06 2015
From: scott.shu at mediatek.com (Scott Shu)
Date: Sun, 23 Aug 2015 17:01:06 +0800
Subject: [PATCH v4 7/8] ARM: dts: mt6580: Add device nodes to the MT6580 dtsi
 file
In-Reply-To: <1440320467-26118-1-git-send-email-scott.shu@mediatek.com>
References: <1440320467-26118-1-git-send-email-scott.shu@mediatek.com>
Message-ID: <1440320467-26118-8-git-send-email-scott.shu@mediatek.com>

This adds the SCPSYS device node to the MT6580 dtsi file.

Signed-off-by: Scott Shu <scott.shu at mediatek.com>
---
 arch/arm/boot/dts/mt6580.dtsi | 6 ++++++
 1 file changed, 6 insertions(+)

diff --git a/arch/arm/boot/dts/mt6580.dtsi b/arch/arm/boot/dts/mt6580.dtsi
index 06fdf6c..40957d3 100644
--- a/arch/arm/boot/dts/mt6580.dtsi
+++ b/arch/arm/boot/dts/mt6580.dtsi
@@ -67,6 +67,12 @@
 		#clock-cells = <0>;
 	};
 
+	scpsys: scpsys at 10006000 {
+		#power-domain-cells = <1>;
+		compatible = "mediatek,mt6580-scpsys";
+		reg = <0x10006000 0x1000>;
+	};
+
 	timer: timer at 10008000 {
 		compatible = "mediatek,mt6580-timer",
 			     "mediatek,mt6577-timer";
-- 
1.9.1

************* Email Confidentiality Notice ********************
The information contained in this e-mail message (including any 
attachments) may be confidential, proprietary, privileged, or otherwise
exempt from disclosure under applicable laws. It is intended to be 
conveyed only to the designated recipient(s). Any use, dissemination, 
distribution, printing, retaining or copying of this e-mail (including its 
attachments) by unintended recipient(s) is strictly prohibited and may 
be unlawful. If you are not an intended recipient of this e-mail, or believe 
that you have received this e-mail in error, please notify the sender 
immediately (by replying to this e-mail), delete any and all copies of 
this e-mail (including any attachments) from your system, and do not
disclose the content of this e-mail to any other person. Thank you!


From romain.perier at gmail.com  Sun Aug 23 02:32:37 2015
From: romain.perier at gmail.com (Romain Perier)
Date: Sun, 23 Aug 2015 11:32:37 +0200
Subject: [PATCH v2] clk: rockchip: Add pclk_peri to critical clocks on
 RK3066/RK3188
Message-ID: <1440322357-2621-1-git-send-email-romain.perier@gmail.com>

Now that the rockchip clock subsystem does clock gating with GPIO banks,
these are no longer enabled once during probe and no longer stay enabled
for eternity. When all these clocks are disabled, the parent clock pclk_peri
might be disabled too, as no other child claims it. So, we need to add pclk_peri
to the critical clocks.

Signed-off-by: Romain Perier <romain.perier at gmail.com>
Tested-by: Michael Niewoehner <linux at mniewoehner.de>
---

changes in v2:
- Improved commit messages
- Added "Tested-by" from Michael Niewoehner, as he tested v1 and no code changed

 drivers/clk/rockchip/clk-rk3188.c | 1 +
 1 file changed, 1 insertion(+)

diff --git a/drivers/clk/rockchip/clk-rk3188.c b/drivers/clk/rockchip/clk-rk3188.c
index bf20214..839a22a 100644
--- a/drivers/clk/rockchip/clk-rk3188.c
+++ b/drivers/clk/rockchip/clk-rk3188.c
@@ -717,6 +717,7 @@ static const char *const rk3188_critical_clocks[] __initconst = {
 	"aclk_peri",
 	"hclk_peri",
 	"pclk_cpu",
+	"pclk_peri",
 };
 
 static void __init rk3188_common_clk_init(struct device_node *np)
-- 
2.1.4



From alexandre.belloni at free-electrons.com  Sun Aug 23 03:00:08 2015
From: alexandre.belloni at free-electrons.com (Alexandre Belloni)
Date: Sun, 23 Aug 2015 12:00:08 +0200
Subject: Problems with device tree PMC clocks and threadirqs on at91
In-Reply-To: <loom.20150814T101121-265@post.gmane.org>
References: <555C8117.9010508@pcs.com>
 <loom.20150814T101121-265@post.gmane.org>
Message-ID: <20150823100008.GA13155@piout.net>

On 14/08/2015 at 08:28:01 +0000, baranikumar.venkatesan wrote :
> I'm getting the same issue as described above for Atmel SAMA5D31 board which
> is supported in kernel v3.18.9 with rt5+ patch. Also I've attempted your
> suggestion numbered 3(Do not wake up kthreadd_task in
> kthread_create_on_node() if kthreadd_task is NULL), but no luck. Could you
> help me if at all you have the solution?
> 

The following patch is the current workaround:
http://lists.infradead.org/pipermail/linux-arm-kernel/2015-July/354024.html

-- 
Alexandre Belloni, Free Electrons
Embedded Linux, Kernel and Android engineering
http://free-electrons.com


From tglx at linutronix.de  Sun Aug 23 03:57:52 2015
From: tglx at linutronix.de (Thomas Gleixner)
Date: Sun, 23 Aug 2015 12:57:52 +0200 (CEST)
Subject: [PATCH v8 1/2] irqchip: imx-gpcv2: IMX GPCv2 driver for wakeup
 sources
In-Reply-To: <1438378439-11569-2-git-send-email-shenwei.wang@freescale.com>
References: <1438378439-11569-1-git-send-email-shenwei.wang@freescale.com>
 <1438378439-11569-2-git-send-email-shenwei.wang@freescale.com>
Message-ID: <alpine.DEB.2.11.1508231251040.3873@nanos>

On Fri, 31 Jul 2015, Shenwei Wang wrote:
> +struct gpcv2_irqchip_data {
> +	struct raw_spinlock rlock;
> +	void __iomem *gpc_base;
> +	u32 wakeup_sources[IMR_NUM];
> +	u32 enabled_irqs[IMR_NUM];
> +	u32 cpu2wakeup;

Can you please format that in a readable way?

      struct raw_spinlock    rlock;
      void __iomem	     *gpc_base;
      ....

> +};
> +
> +static struct gpcv2_irqchip_data *imx_gpcv2_instance;
> +
> +u32 imx_gpcv2_get_wakeup_source(u32 **sources)
> +{
> +	if (!imx_gpcv2_instance)
> +		return 0;
> +
> +	if (sources)
> +		*sources = imx_gpcv2_instance->wakeup_sources;
> +
> +	return IMR_NUM;
> +}
> +
> +static int gpcv2_wakeup_source_save(void)
> +{
> +	struct gpcv2_irqchip_data *cd;
> +	void __iomem *reg;
> +	int i;
> +
> +	cd = imx_gpcv2_instance;
> +	if (!cd)
> +		return 0;
> +
> +	for (i = 0; i < IMR_NUM; i++) {
> +		reg = cd->gpc_base + cd->cpu2wakeup + i * 4;
> +		cd->enabled_irqs[i] = readl_relaxed(reg);

You read the full state of the register and restore the full state. So
why enabled_irqs?

> +		writel_relaxed(cd->wakeup_sources[i], reg);
> +	}
> +
> +	return 0;
> +}
> +
> +static void gpcv2_wakeup_source_restore(void)
> +{
> +	struct gpcv2_irqchip_data *cd;
> +	void __iomem *reg;
> +	int i;
> +
> +	cd = imx_gpcv2_instance;
> +	if (!cd)
> +		return;
> +
> +	for (i = 0; i < IMR_NUM; i++) {
> +		reg = cd->gpc_base + cd->cpu2wakeup + i * 4;
> +		writel_relaxed(cd->enabled_irqs[i], reg);
> +		cd->wakeup_sources[i] = ~0;

Why are you clearing that info on resume? Drivers will clear that via
set_wake() or leave it when they want to have resume functionality?

> +static int __init imx_gpcv2_irqchip_init(struct device_node *node,
> +			       struct device_node *parent)
> +{
> +	struct irq_domain *parent_domain, *domain;
> +	struct gpcv2_irqchip_data *cd;
> +	int i;
> +
> +	if (!parent) {
> +		pr_err("%s: no parent, giving up\n", node->full_name);
> +		return -ENODEV;
> +	}
> +
> +	parent_domain = irq_find_host(parent);
> +	if (!parent_domain) {
> +		pr_err("%s: unable to get parent domain\n", node->full_name);
> +		return -ENXIO;
> +	}
> +
> +	cd = kzalloc(sizeof(struct gpcv2_irqchip_data), GFP_KERNEL);
> +	BUG_ON(!cd);

You return an error code for all other failures. Why BUG here?

Otherwise this looks very clean now. Can you please resend ASAP with
these minor points addressed?

Thanks,

	tglx




From kuleshovmail at gmail.com  Sun Aug 23 06:24:44 2015
From: kuleshovmail at gmail.com (Alexander Kuleshov)
Date: Sun, 23 Aug 2015 19:24:44 +0600
Subject: [PATCH] arm64: Fix source code file path in comments
Message-ID: <1440336284-3907-1-git-send-email-kuleshovmail@gmail.com>

Architecture specific code for i386 and x86_64 was unified and merged to
the arch/x86. This patch fix old path of x86 architecture in a comment
from the arch/arm64/include/asm/fixmap.h.

Signed-off-by: Alexander Kuleshov <kuleshovmail at gmail.com>
---
 arch/arm64/include/asm/fixmap.h | 2 +-
 1 file changed, 1 insertion(+), 1 deletion(-)

diff --git a/arch/arm64/include/asm/fixmap.h b/arch/arm64/include/asm/fixmap.h
index c0739187..8b9884c 100644
--- a/arch/arm64/include/asm/fixmap.h
+++ b/arch/arm64/include/asm/fixmap.h
@@ -8,7 +8,7 @@
  * Copyright (C) 1998 Ingo Molnar
  * Copyright (C) 2013 Mark Salter <msalter at redhat.com>
  *
- * Adapted from arch/x86_64 version.
+ * Adapted from arch/x86 version.
  *
  */
 
-- 
2.5.0



From vinod.koul at intel.com  Sun Aug 23 06:39:33 2015
From: vinod.koul at intel.com (Vinod Koul)
Date: Sun, 23 Aug 2015 19:09:33 +0530
Subject: [PATCH] dmaengine: vdma: Add 64 bit addressing support to the
 driver
In-Reply-To: <2348343.VuhoH7scrX@avalon>
References: <1438775257-3511-1-git-send-email-anuragku@xilinx.com>
 <2214014.FVHbR3JRBK@avalon>
 <3802E9A6666DF54886E2B9CBF743BA9801BF8264@XAP-PVEXMBX01.xlnx.xilinx.com>
 <2348343.VuhoH7scrX@avalon>
Message-ID: <20150823133933.GY13546@localhost>

On Fri, Aug 21, 2015 at 02:01:59AM +0300, Laurent Pinchart wrote:
> > > How is 64 bit DMA addressing implemented ? Can you use a 64-bit VDMA on
> > > a 32- bit platform with LPAE ? Can you use a 32-bit VDMA on a 64-bit
> > > platform ? Given that VDMA is an IP core you can instantiate in the
> > > programmable logic I expect some level of flexibility to be possible, but
> > > this patch doesn't seem to support it. Please provide more context to
> > > allow a proper review (and please include it in the commit message of v2).
> > 
> > The VDMA core is a soft ip, which can be programmed to support both 32 bit
> > and 64 bit addressing.When the VDMA core is configured for 32 bit address
> > space , transfer start address is specified by a single register.
> > 
> > When the  VDMA core is configured for an address space greater than 32, each
> > start address is specified by a combination of two registers.The first
> > register specifies the LSB 32 bits of address, while the next register
> > specifies the MSB 32 bits of address.For example,5Ch will specify the LSB
> > bits while 60h will specify the MSB bits of the first start address. So we
> > need to program two registers at a time.
> > 
> > Yes,64 bit vdma can be used on 32 bit platform and 32 bit vdma can also be
> > used on 64 bit platform.As far as i know , there is no use case where 64
> > bit dma can be used on 32 bit platform.Please correct me if i am wrong.
> 
> I'm not sure what the use cases would be, but it makes me feel uncomfortable 
> to decide on whether the VDMA is 32 or 64 bits based on the type of CPU.
> 
> As the VDMA flavour is selected at synthesis time, how about specifying it in 
> DT instead ? You could just add an address-width property.
That would be saner thing to do. People wont check which IP and will mix and
match. So you may have a 64 bit system with your 32 bit IP...

-- 
~Vinod


From arnd at arndb.de  Sun Aug 23 06:59:45 2015
From: arnd at arndb.de (Arnd Bergmann)
Date: Sun, 23 Aug 2015 15:59:45 +0200
Subject: [PATCH] dmaengine: vdma: Add 64 bit addressing support to the
 driver
In-Reply-To: <20150823133933.GY13546@localhost>
References: <1438775257-3511-1-git-send-email-anuragku@xilinx.com>
 <2348343.VuhoH7scrX@avalon> <20150823133933.GY13546@localhost>
Message-ID: <3107999.Bu5nBsJYRS@wuerfel>

On Sunday 23 August 2015 19:09:33 Vinod Koul wrote:
> On Fri, Aug 21, 2015 at 02:01:59AM +0300, Laurent Pinchart wrote:
> > > > How is 64 bit DMA addressing implemented ? Can you use a 64-bit VDMA on
> > > > a 32- bit platform with LPAE ? Can you use a 32-bit VDMA on a 64-bit
> > > > platform ? Given that VDMA is an IP core you can instantiate in the
> > > > programmable logic I expect some level of flexibility to be possible, but
> > > > this patch doesn't seem to support it. Please provide more context to
> > > > allow a proper review (and please include it in the commit message of v2).
> > > 
> > > The VDMA core is a soft ip, which can be programmed to support both 32 bit
> > > and 64 bit addressing.When the VDMA core is configured for 32 bit address
> > > space , transfer start address is specified by a single register.
> > > 
> > > When the  VDMA core is configured for an address space greater than 32, each
> > > start address is specified by a combination of two registers.The first
> > > register specifies the LSB 32 bits of address, while the next register
> > > specifies the MSB 32 bits of address.For example,5Ch will specify the LSB
> > > bits while 60h will specify the MSB bits of the first start address. So we
> > > need to program two registers at a time.
> > > 
> > > Yes,64 bit vdma can be used on 32 bit platform and 32 bit vdma can also be
> > > used on 64 bit platform.As far as i know , there is no use case where 64
> > > bit dma can be used on 32 bit platform.Please correct me if i am wrong.
> > 
> > I'm not sure what the use cases would be, but it makes me feel uncomfortable 
> > to decide on whether the VDMA is 32 or 64 bits based on the type of CPU.
> > 
> > As the VDMA flavour is selected at synthesis time, how about specifying it in 
> > DT instead ? You could just add an address-width property.
> That would be saner thing to do. People wont check which IP and will mix and
> match. So you may have a 64 bit system with your 32 bit IP...

Note that you need two things here: an identification of whether the IP block
itself is configured as 64-bit or 32-bit (either using the compatible string,
or a separate property), and a dma-ranges property of the parent bus that
describes what the bus can do and how the address range of the device maps to
the address range of the parent bus.

The DT probe code will set the dma offset according to the dma-ranges, and
will prevent the device from setting a mask that does not get translated
properly, e.g. if you have a 64-bit capable device on a 32-bit bus.

	Arnd


From vinod.koul at intel.com  Sun Aug 23 07:08:23 2015
From: vinod.koul at intel.com (Vinod Koul)
Date: Sun, 23 Aug 2015 19:38:23 +0530
Subject: [PATCH v4 2/2] dma: Add Xilinx zynqmp dma engine driver support
In-Reply-To: <CAGnW=BaU__+B2uAK=qpV3QP60SqSUxx-kgJVs0t42K0fqTxL0g@mail.gmail.com>
References: <1438831173-8761-1-git-send-email-punnaia@xilinx.com>
 <1438831173-8761-2-git-send-email-punnaia@xilinx.com>
 <20150820061312.GA13546@localhost>
 <CAGnW=BaU__+B2uAK=qpV3QP60SqSUxx-kgJVs0t42K0fqTxL0g@mail.gmail.com>
Message-ID: <20150823140823.GA13546@localhost>

On Thu, Aug 20, 2015 at 12:01:27PM +0530, punnaiah choudary kalluri wrote:
> On Thu, Aug 20, 2015 at 11:43 AM, Vinod Koul <vinod.koul at intel.com> wrote:
> > On Thu, Aug 06, 2015 at 08:49:33AM +0530, Punnaiah Choudary Kalluri wrote:
> >
> >> +     list_for_each_entry_safe(desc, next, &chan->done_list, node) {
> >> +             dma_async_tx_callback callback;
> >> +             void *callback_param;
> >> +
> >> +             list_del(&desc->node);
> >> +
> >> +             callback = desc->async_tx.callback;
> >> +             callback_param = desc->async_tx.callback_param;
> >> +             if (callback) {
> >> +                     if (in_interrupt())
> >> +                             spin_unlock_bh(&chan->lock);
> >> +                     else
> >> +                             spin_unlock(&chan->lock);
> >
> > This looks bad!
> > Why would callback be called from different context. It should only be
> > invoked from your tasklet
> 
> During the terminate call, driver need to clean up the existing BDs so that time
> this function will be called from the thread or process context in
> addition to the
> tasklet context.
> 
> DO you have any suggestion here ?

Yes you need to terminate but you don't need to invoke user for terminate
flow. It is not expected.
Terminate flow expect youu to clean the channels

-- 
~Vinod


From punnaia at xilinx.com  Sun Aug 23 07:54:16 2015
From: punnaia at xilinx.com (punnaiah choudary kalluri)
Date: Sun, 23 Aug 2015 20:24:16 +0530
Subject: [PATCH v4 2/2] dma: Add Xilinx zynqmp dma engine driver support
In-Reply-To: <20150823140823.GA13546@localhost>
References: <1438831173-8761-1-git-send-email-punnaia@xilinx.com>
 <1438831173-8761-2-git-send-email-punnaia@xilinx.com>
 <20150820061312.GA13546@localhost>
 <CAGnW=BaU__+B2uAK=qpV3QP60SqSUxx-kgJVs0t42K0fqTxL0g@mail.gmail.com>
 <20150823140823.GA13546@localhost>
Message-ID: <CAGnW=BYSS0kQuY+qYArgg5+Zrots+K9trui_PpJimzctkO-J0g@mail.gmail.com>

On Sun, Aug 23, 2015 at 7:38 PM, Vinod Koul <vinod.koul at intel.com> wrote:
> On Thu, Aug 20, 2015 at 12:01:27PM +0530, punnaiah choudary kalluri wrote:
>> On Thu, Aug 20, 2015 at 11:43 AM, Vinod Koul <vinod.koul at intel.com> wrote:
>> > On Thu, Aug 06, 2015 at 08:49:33AM +0530, Punnaiah Choudary Kalluri wrote:
>> >
>> >> +     list_for_each_entry_safe(desc, next, &chan->done_list, node) {
>> >> +             dma_async_tx_callback callback;
>> >> +             void *callback_param;
>> >> +
>> >> +             list_del(&desc->node);
>> >> +
>> >> +             callback = desc->async_tx.callback;
>> >> +             callback_param = desc->async_tx.callback_param;
>> >> +             if (callback) {
>> >> +                     if (in_interrupt())
>> >> +                             spin_unlock_bh(&chan->lock);
>> >> +                     else
>> >> +                             spin_unlock(&chan->lock);
>> >
>> > This looks bad!
>> > Why would callback be called from different context. It should only be
>> > invoked from your tasklet
>>
>> During the terminate call, driver need to clean up the existing BDs so that time
>> this function will be called from the thread or process context in
>> addition to the
>> tasklet context.
>>
>> DO you have any suggestion here ?
>
> Yes you need to terminate but you don't need to invoke user for terminate
> flow. It is not expected.
> Terminate flow expect youu to clean the channels

Ok. Thanks. I will fix this and send v5 soon.

Regards,
Punnaiah
>
> --
> ~Vinod
> --
> To unsubscribe from this list: send the line "unsubscribe linux-kernel" in
> the body of a message to majordomo at vger.kernel.org
> More majordomo info at  http://vger.kernel.org/majordomo-info.html
> Please read the FAQ at  http://www.tux.org/lkml/


From maitysanchayan at gmail.com  Sun Aug 23 08:30:01 2015
From: maitysanchayan at gmail.com (maitysanchayan at gmail.com)
Date: Sun, 23 Aug 2015 21:00:01 +0530
Subject: [PATCH v4 1/3] ARM: dts: vf500-colibri: Add device tree node for
 touchscreen support
In-Reply-To: <a20cfadaea07ab255ac94fd5e567e5cf@agner.ch>
References: <cover.1440162473.git.maitysanchayan@gmail.com>
 <a960c538cf419a816d73fbea7d4380ea773aa6ba.1440162473.git.maitysanchayan@gmail.com>
 <a20cfadaea07ab255ac94fd5e567e5cf@agner.ch>
Message-ID: <20150823153001.GA3935@Sanchayan-Arch>

On 15-08-22 18:54:28, Stefan Agner wrote:
> On 2015-08-21 06:26, Sanchayan Maity wrote:
> > Add device tree node for touchscreen support on Colibri VF50. The
> > touchscreen functionality on VF50 uses the ADC channels of Vybrid
> > and some GPIOs. Also add pinctrl nodes for proper pinmux.
> > 
> > Signed-off-by: Sanchayan Maity <maitysanchayan at gmail.com>
> > ---
> >  arch/arm/boot/dts/vf500-colibri-eval-v3.dts |  4 +++
> >  arch/arm/boot/dts/vf500-colibri.dtsi        | 47 +++++++++++++++++++++++++++++
> >  2 files changed, 51 insertions(+)
> > 
> > diff --git a/arch/arm/boot/dts/vf500-colibri-eval-v3.dts
> > b/arch/arm/boot/dts/vf500-colibri-eval-v3.dts
> > index 7fc782c..14c0b00 100644
> > --- a/arch/arm/boot/dts/vf500-colibri-eval-v3.dts
> > +++ b/arch/arm/boot/dts/vf500-colibri-eval-v3.dts
> > @@ -15,3 +15,7 @@
> >  	model = "Toradex Colibri VF50 on Colibri Evaluation Board";
> >  	compatible = "toradex,vf500-colibri_vf50-on-eval",
> > "toradex,vf500-colibri_vf50", "fsl,vf500";
> >  };
> > +
> > +&touchscreen {
> > +	status = "okay";
> > +};
> > diff --git a/arch/arm/boot/dts/vf500-colibri.dtsi
> > b/arch/arm/boot/dts/vf500-colibri.dtsi
> > index cee34a3..84f091d 100644
> > --- a/arch/arm/boot/dts/vf500-colibri.dtsi
> > +++ b/arch/arm/boot/dts/vf500-colibri.dtsi
> > @@ -17,4 +17,51 @@
> >  	memory {
> >  		reg = <0x80000000 0x8000000>;
> >  	};
> > +
> > +	touchscreen: vf50-touchscreen {
> > +		compatible = "toradex,vf50-touchscreen";
> > +		io-channels = <&adc1 0>,<&adc0 0>,
> > +				<&adc0 1>,<&adc1 2>;
> > +		xp-gpios = <&gpio0 13 GPIO_ACTIVE_LOW>;
> > +		xm-gpios = <&gpio2 29 GPIO_ACTIVE_HIGH>;
> > +		yp-gpios = <&gpio0 12 GPIO_ACTIVE_LOW>;
> > +		ym-gpios = <&gpio0 4 GPIO_ACTIVE_HIGH>;
> > +		interrupt-parent = <&gpio0>;
> > +		interrupts = <8 IRQ_TYPE_LEVEL_LOW>;
> > +		pinctrl-names = "idle","default","gpios";
> > +		pinctrl-0 = <&pinctrl_touchctrl_idle>;
> > +		pinctrl-1 = <&pinctrl_touchctrl_default>;
> > +		pinctrl-2 = <&pinctrl_touchctrl_gpios>;
> > +		vf50-ts-min-pressure = <200>;
> 
> Since this is a touch screen related property, we even would want to
> have that in the board specific device-tree (vf500-colibri-eval-v3.dts).

So the same property specified again in vf500-colibri-eval-v3.dts? Ok will
include the same.

- Sanchayan.


From maitysanchayan at gmail.com  Sun Aug 23 08:31:48 2015
From: maitysanchayan at gmail.com (maitysanchayan at gmail.com)
Date: Sun, 23 Aug 2015 21:01:48 +0530
Subject: [PATCH v4 3/3] touchscreen: colibri-vf50-ts: Add touchscreen
 support for Colibri VF50
In-Reply-To: <c5cd11ba9b5c3ec228a120e0f1c3c156@agner.ch>
References: <cover.1440162473.git.maitysanchayan@gmail.com>
 <915c9122cfba83c6fbbc519c10ae2d101e27bc5b.1440162473.git.maitysanchayan@gmail.com>
 <c5cd11ba9b5c3ec228a120e0f1c3c156@agner.ch>
Message-ID: <20150823153148.GB3935@Sanchayan-Arch>

On 15-08-22 18:52:28, Stefan Agner wrote:
> Hi Sanchayan,
> 
> On 2015-08-21 06:26, Sanchayan Maity wrote:
> > +static int vf50_ts_probe(struct platform_device *pdev)
> > +{
> > +	struct input_dev *input;
> > +	struct iio_channel *channels;
> > +	struct device *dev = &pdev->dev;
> > +	struct vf50_touch_device *touchdev;
> > +	int error;
> > +
> > +	channels = iio_channel_get_all(dev);
> > +	if (IS_ERR(channels))
> > +		return PTR_ERR(channels);
> 
> Hm, we expect here that four channels are returned, however a faulty
> device tree could contain less. Access to the fourth channel above would
> lead to a bug.
> 
> Can you check the amount of channels returned? The returned list is
> explicitly terminated with a null entry, you can rely on that. Something
> similar to hwmon should do the job.
> http://lxr.free-electrons.com/source/drivers/hwmon/iio_hwmon.c#L86

I agree. It did be nice to have this error check. Thanks. I will add
this check so we can bail out if less channels are specified.

- Sanchayan.

> 
> 
> Otherwise, Acked-by: Stefan Agner <stefan at agner.ch>
> 
> --
> Stefan


From maitysanchayan at gmail.com  Sun Aug 23 09:15:28 2015
From: maitysanchayan at gmail.com (maitysanchayan at gmail.com)
Date: Sun, 23 Aug 2015 21:45:28 +0530
Subject: [PATCH v4 2/3] input: Add DT binding documentation for Colibri
 VF50 touchscreen
In-Reply-To: <24b47f359d019e8871887777372b442b@agner.ch>
References: <cover.1440162473.git.maitysanchayan@gmail.com>
 <8446d6df4b39f0b0acdc37afd4d66dbcca4d09ba.1440162473.git.maitysanchayan@gmail.com>
 <24b47f359d019e8871887777372b442b@agner.ch>
Message-ID: <20150823161528.GD3935@Sanchayan-Arch>

On 15-08-22 18:36:54, Stefan Agner wrote:
> On 2015-08-21 06:26, Sanchayan Maity wrote:
> > This adds device tree binding documentation for the Colibri VF50
> > touchscreen driver.
> > 
> > Signed-off-by: Sanchayan Maity <maitysanchayan at gmail.com>
> > ---
> >  .../bindings/input/touchscreen/colibri-vf50-ts.txt | 36 ++++++++++++++++++++++
> >  1 file changed, 36 insertions(+)
> >  create mode 100644
> > Documentation/devicetree/bindings/input/touchscreen/colibri-vf50-ts.txt
> > 
> > diff --git
> > a/Documentation/devicetree/bindings/input/touchscreen/colibri-vf50-ts.txt
> > b/Documentation/devicetree/bindings/input/touchscreen/colibri-vf50-ts.txt
> > new file mode 100644
> > index 0000000..e615aa9
> > --- /dev/null
> > +++ b/Documentation/devicetree/bindings/input/touchscreen/colibri-vf50-ts.txt
> > @@ -0,0 +1,36 @@
> > +* Toradex Colibri VF50 Touchscreen driver
> > +
> > +Required Properties:
> > +- compatible must be toradex,vf50-touchscreen
> > +- io-channels: adc channels being used by the Colibri VF50 module
> > +- xp-gpios: FET gate driver for input of X+
> > +- xm-gpios: FET gate driver for input of X-
> > +- yp-gpios: FET gate driver for input of Y+
> > +- ym-gpios: FET gate driver for input of Y-
> > +- interrupt-parent: phandle for the interrupt controller
> > +- interrupts: pen irq interrupt for touch detection
> 
> I like the use of the interrupt interface for the touch detection pin.
> Maybe you can mention here that this is (typically) a GPIO...
> 
> > +- pinctrl-names: "idle", "default", "gpios"
> > +- pinctrl-0: pinctrl node for idle state gpio pinmux
> > +- pinctrl-1: pinctrl node for touch detection state pinmux
> 
> "touch detection" for default is rather confusing or even wrong. The
> Idle state is used for pen/touch detection, default is used for X/Y and
> Pressure measurement (maybe better described as touch measurement).

Ok. Understood. I see how my wordings can create confusion or are
misleading. Will fix.

- Sanchayan.

> 
> > +- pinctrl-2: pinctrl node for gpios functioning as FET gate drivers
> > +- vf50-ts-min-pressure: pressure level at which to stop measuring X/Y values
> > +
> > +Example:
> > +
> > +	touchctrl: vf50_touchctrl {
> > +		compatible = "toradex,vf50-touchscreen";
> > +		io-channels = <&adc1 0>,<&adc0 0>,
> > +				<&adc0 1>,<&adc1 2>;
> > +		xp-gpios = <&gpio0 13 GPIO_ACTIVE_LOW>;
> > +		xm-gpios = <&gpio2 29 GPIO_ACTIVE_HIGH>;
> > +		yp-gpios = <&gpio0 12 GPIO_ACTIVE_LOW>;
> > +		ym-gpios = <&gpio0 4 GPIO_ACTIVE_HIGH>;
> > +		interrupt-parent = <&gpio0>;
> > +		interrupts = <8 IRQ_TYPE_LEVEL_LOW>;
> > +		pinctrl-names = "idle","default","gpios";
> > +		pinctrl-0 = <&pinctrl_touchctrl_idle>;
> > +		pinctrl-1 = <&pinctrl_touchctrl_default>;
> > +		pinctrl-2 = <&pinctrl_touchctrl_gpios>;
> > +		vf50-ts-min-pressure = <200>;
> > +		status = "disabled";
> > +	};
> 
> Otherwise I agree with 1 and 2:
> 
> Acked-by: Stefan Agner <stefan at agner.ch>
> 
> --
> Stefan
> 


From hdegoede at redhat.com  Sun Aug 23 11:31:38 2015
From: hdegoede at redhat.com (Hans de Goede)
Date: Sun, 23 Aug 2015 20:31:38 +0200
Subject: [PATCH] net: sun4i-emac: Claim emac sram
Message-ID: <1440354698-11144-1-git-send-email-hdegoede@redhat.com>

Claim the emac sram ourselves, rather then relying on the bootloader
having mapped the sram to the emac controller during boot.

Signed-off-by: Hans de Goede <hdegoede at redhat.com>
---
 drivers/net/ethernet/allwinner/sun4i-emac.c | 13 +++++++++++--
 1 file changed, 11 insertions(+), 2 deletions(-)

diff --git a/drivers/net/ethernet/allwinner/sun4i-emac.c b/drivers/net/ethernet/allwinner/sun4i-emac.c
index bab01c84..48ce83e 100644
--- a/drivers/net/ethernet/allwinner/sun4i-emac.c
+++ b/drivers/net/ethernet/allwinner/sun4i-emac.c
@@ -28,6 +28,7 @@
 #include <linux/of_platform.h>
 #include <linux/platform_device.h>
 #include <linux/phy.h>
+#include <linux/soc/sunxi/sunxi_sram.h>
 
 #include "sun4i-emac.h"
 
@@ -857,11 +858,17 @@ static int emac_probe(struct platform_device *pdev)
 
 	clk_prepare_enable(db->clk);
 
+	ret = sunxi_sram_claim(&pdev->dev);
+	if (ret) {
+		dev_err(&pdev->dev, "Error couldn't map SRAM to device\n");
+		goto out;
+	}
+
 	db->phy_node = of_parse_phandle(np, "phy", 0);
 	if (!db->phy_node) {
 		dev_err(&pdev->dev, "no associated PHY\n");
 		ret = -ENODEV;
-		goto out;
+		goto out_release_sram;
 	}
 
 	/* Read MAC-address from DT */
@@ -893,7 +900,7 @@ static int emac_probe(struct platform_device *pdev)
 	if (ret) {
 		dev_err(&pdev->dev, "Registering netdev failed!\n");
 		ret = -ENODEV;
-		goto out;
+		goto out_release_sram;
 	}
 
 	dev_info(&pdev->dev, "%s: at %p, IRQ %d MAC: %pM\n",
@@ -901,6 +908,8 @@ static int emac_probe(struct platform_device *pdev)
 
 	return 0;
 
+out_release_sram:
+	sunxi_sram_release(&pdev->dev);
 out:
 	dev_err(db->dev, "not found (%d).\n", ret);
 
-- 
2.4.3



From robert.jarzmik at free.fr  Sun Aug 23 12:13:57 2015
From: robert.jarzmik at free.fr (Robert Jarzmik)
Date: Sun, 23 Aug 2015 21:13:57 +0200
Subject: [PATCH] ARM: pxa: fix DFI bus lockups on startup
Message-ID: <1440357237-26713-1-git-send-email-robert.jarzmik@free.fr>

After the conversion of pxa architecture to common clock framework, the
NAND clock can be disabled on startup if no nand driver claims it.

In this case, it happens that if the bootloader used the NAND and set
the DFI arbitration bit, the next access to a static memory controller
area, such as an ethernet card, the system bus will stall, and the core
will be stalled forever.

Fix this by clearing the DFI arbritration bit in pxa3xx startup. The bit
will be enabled the pxa3xx-nand driver on need anyway. The only left
requirement is that upon pxa3xx-nand removal, the bit should be cleared
before the clock is disabled.

Signed-off-by: Robert Jarzmik <robert.jarzmik at free.fr>
---
 arch/arm/mach-pxa/include/mach/addr-map.h |  7 +++++++
 arch/arm/mach-pxa/pxa3xx.c                | 21 ++++++++++++++++++++-
 2 files changed, 27 insertions(+), 1 deletion(-)

diff --git a/arch/arm/mach-pxa/include/mach/addr-map.h b/arch/arm/mach-pxa/include/mach/addr-map.h
index d28fe291233a..07b93fd24474 100644
--- a/arch/arm/mach-pxa/include/mach/addr-map.h
+++ b/arch/arm/mach-pxa/include/mach/addr-map.h
@@ -44,6 +44,13 @@
  */
 
 /*
+ * DFI Bus for NAND, PXA3xx only
+ */
+#define NAND_PHYS		0x43100000
+#define NAND_VIRT		IOMEM(0xf6300000)
+#define NAND_SIZE		0x00100000
+
+/*
  * Internal Memory Controller (PXA27x and later)
  */
 #define IMEMC_PHYS		0x58000000
diff --git a/arch/arm/mach-pxa/pxa3xx.c b/arch/arm/mach-pxa/pxa3xx.c
index aa85ec1a3065..26105167d433 100644
--- a/arch/arm/mach-pxa/pxa3xx.c
+++ b/arch/arm/mach-pxa/pxa3xx.c
@@ -47,6 +47,13 @@ extern void __init pxa_dt_irq_init(int (*fn)(struct irq_data *, unsigned int));
 #define ISRAM_START	0x5c000000
 #define ISRAM_SIZE	SZ_256K
 
+/*
+ * NAND NFC: DFI bus arbitration subset
+ */
+#define NDCR			(*(volatile u32 __iomem*)(NAND_VIRT + 0))
+#define NDCR_ND_ARB_EN		(1 << 12)
+#define NDCR_ND_ARB_CNTL	(1 << 19)
+
 static void __iomem *sram;
 static unsigned long wakeup_src;
 
@@ -362,7 +369,12 @@ static struct map_desc pxa3xx_io_desc[] __initdata = {
 		.pfn		= __phys_to_pfn(PXA3XX_SMEMC_BASE),
 		.length		= SMEMC_SIZE,
 		.type		= MT_DEVICE
-	}
+	}, {
+		.virtual	= (unsigned long)NAND_VIRT,
+		.pfn		= __phys_to_pfn(NAND_PHYS),
+		.length		= NAND_SIZE,
+		.type		= MT_DEVICE
+	},
 };
 
 void __init pxa3xx_map_io(void)
@@ -420,6 +432,13 @@ static int __init pxa3xx_init(void)
 		 */
 		ASCR &= ~(ASCR_RDH | ASCR_D1S | ASCR_D2S | ASCR_D3S);
 
+		/*
+		 * Disable DFI bus arbitration, to prevent a system bus lock if
+		 * somebody disables the NAND clock (unused clock) while this
+		 * bit remains set.
+		 */
+		NDCR = (NDCR & ~NDCR_ND_ARB_EN) | NDCR_ND_ARB_CNTL;
+
 		if ((ret = pxa_init_dma(IRQ_DMA, 32)))
 			return ret;
 
-- 
2.1.4



From mchehab at osg.samsung.com  Sun Aug 23 13:17:28 2015
From: mchehab at osg.samsung.com (Mauro Carvalho Chehab)
Date: Sun, 23 Aug 2015 17:17:28 -0300
Subject: [PATCH v7 11/44] [media] media: use entity.graph_obj.mdev instead of
 .parent
In-Reply-To: <cover.1440359643.git.mchehab@osg.samsung.com>
References: <cover.1440359643.git.mchehab@osg.samsung.com>
Message-ID: <dc1be98277c46ddd87e431148fc7e332176828ab.1440359643.git.mchehab@osg.samsung.com>

From: Javier Martinez Canillas <javier at osg.samsung.com>

The struct media_entity has a .parent field that stores a pointer
to the parent struct media_device. But recently a media_gobj was
embedded into the entities and since struct media_gojb already has
a pointer to a struct media_device in the .mdev field, the .parent
field becomes redundant and can be removed.

This patch replaces all the usage of .parent by .graph_obj.mdev so
that field will become unused and can be removed on a later patch.

No functional changes.

The transformation was made using the following coccinelle spatch:

@@
struct media_entity *me;
@@

- me->parent
+ me->graph_obj.mdev

@@
struct media_entity *link;
@@

- link->source->entity->parent
+ link->source->entity->graph_obj.mdev

@@
struct exynos_video_entity *ve;
@@

- ve->vdev.entity.parent
+ ve->vdev.entity.graph_obj.mdev

Suggested-by: Mauro Carvalho Chehab <mchehab at osg.samsung.com>

Signed-off-by: Javier Martinez Canillas <javier at osg.samsung.com>
Signed-off-by: Mauro Carvalho Chehab <mchehab at osg.samsung.com>

diff --git a/drivers/media/media-device.c b/drivers/media/media-device.c
index 0f3844470147..138b18416460 100644
--- a/drivers/media/media-device.c
+++ b/drivers/media/media-device.c
@@ -435,8 +435,8 @@ int __must_check media_device_register_entity(struct media_device *mdev,
 	int i;
 
 	/* Warn if we apparently re-register an entity */
-	WARN_ON(entity->parent != NULL);
-	entity->parent = mdev;
+	WARN_ON(entity->graph_obj.mdev != NULL);
+	entity->graph_obj.mdev = mdev;
 
 	spin_lock(&mdev->lock);
 	/* Initialize media_gobj embedded at the entity */
@@ -471,7 +471,7 @@ EXPORT_SYMBOL_GPL(media_device_register_entity);
 void media_device_unregister_entity(struct media_entity *entity)
 {
 	int i;
-	struct media_device *mdev = entity->parent;
+	struct media_device *mdev = entity->graph_obj.mdev;
 
 	if (mdev == NULL)
 		return;
@@ -484,7 +484,7 @@ void media_device_unregister_entity(struct media_entity *entity)
 	media_gobj_remove(&entity->graph_obj);
 	list_del(&entity->list);
 	spin_unlock(&mdev->lock);
-	entity->parent = NULL;
+	entity->graph_obj.mdev = NULL;
 }
 EXPORT_SYMBOL_GPL(media_device_unregister_entity);
 
diff --git a/drivers/media/media-entity.c b/drivers/media/media-entity.c
index 35e52cd1fc5a..a23c93369a04 100644
--- a/drivers/media/media-entity.c
+++ b/drivers/media/media-entity.c
@@ -332,7 +332,7 @@ EXPORT_SYMBOL_GPL(media_entity_graph_walk_next);
 __must_check int media_entity_pipeline_start(struct media_entity *entity,
 					     struct media_pipeline *pipe)
 {
-	struct media_device *mdev = entity->parent;
+	struct media_device *mdev = entity->graph_obj.mdev;
 	struct media_entity_graph graph;
 	struct media_entity *entity_err = entity;
 	int ret;
@@ -387,7 +387,7 @@ __must_check int media_entity_pipeline_start(struct media_entity *entity,
 
 			ret = entity->ops->link_validate(link);
 			if (ret < 0 && ret != -ENOIOCTLCMD) {
-				dev_dbg(entity->parent->dev,
+				dev_dbg(entity->graph_obj.mdev->dev,
 					"link validation failed for \"%s\":%u -> \"%s\":%u, error %d\n",
 					link->source->entity->name,
 					link->source->index,
@@ -401,7 +401,7 @@ __must_check int media_entity_pipeline_start(struct media_entity *entity,
 
 		if (!bitmap_full(active, entity->num_pads)) {
 			ret = -EPIPE;
-			dev_dbg(entity->parent->dev,
+			dev_dbg(entity->graph_obj.mdev->dev,
 				"\"%s\":%u must be connected by an enabled link\n",
 				entity->name,
 				(unsigned)find_first_zero_bit(
@@ -454,7 +454,7 @@ EXPORT_SYMBOL_GPL(media_entity_pipeline_start);
  */
 void media_entity_pipeline_stop(struct media_entity *entity)
 {
-	struct media_device *mdev = entity->parent;
+	struct media_device *mdev = entity->graph_obj.mdev;
 	struct media_entity_graph graph;
 
 	mutex_lock(&mdev->graph_mutex);
@@ -490,8 +490,8 @@ struct media_entity *media_entity_get(struct media_entity *entity)
 	if (entity == NULL)
 		return NULL;
 
-	if (entity->parent->dev &&
-	    !try_module_get(entity->parent->dev->driver->owner))
+	if (entity->graph_obj.mdev->dev &&
+	    !try_module_get(entity->graph_obj.mdev->dev->driver->owner))
 		return NULL;
 
 	return entity;
@@ -511,8 +511,8 @@ void media_entity_put(struct media_entity *entity)
 	if (entity == NULL)
 		return;
 
-	if (entity->parent->dev)
-		module_put(entity->parent->dev->driver->owner);
+	if (entity->graph_obj.mdev->dev)
+		module_put(entity->graph_obj.mdev->dev->driver->owner);
 }
 EXPORT_SYMBOL_GPL(media_entity_put);
 
@@ -561,7 +561,8 @@ media_create_pad_link(struct media_entity *source, u16 source_pad,
 	link->flags = flags;
 
 	/* Initialize graph object embedded at the new link */
-	media_gobj_init(source->parent, MEDIA_GRAPH_LINK, &link->graph_obj);
+	media_gobj_init(source->graph_obj.mdev, MEDIA_GRAPH_LINK,
+			&link->graph_obj);
 
 	/* Create the backlink. Backlinks are used to help graph traversal and
 	 * are not reported to userspace.
@@ -577,7 +578,8 @@ media_create_pad_link(struct media_entity *source, u16 source_pad,
 	backlink->flags = flags;
 
 	/* Initialize graph object embedded at the new link */
-	media_gobj_init(sink->parent, MEDIA_GRAPH_LINK, &backlink->graph_obj);
+	media_gobj_init(sink->graph_obj.mdev, MEDIA_GRAPH_LINK,
+			&backlink->graph_obj);
 
 	link->reverse = backlink;
 	backlink->reverse = link;
@@ -629,12 +631,12 @@ EXPORT_SYMBOL_GPL(__media_entity_remove_links);
 void media_entity_remove_links(struct media_entity *entity)
 {
 	/* Do nothing if the entity is not registered. */
-	if (entity->parent == NULL)
+	if (entity->graph_obj.mdev == NULL)
 		return;
 
-	mutex_lock(&entity->parent->graph_mutex);
+	mutex_lock(&entity->graph_obj.mdev->graph_mutex);
 	__media_entity_remove_links(entity);
-	mutex_unlock(&entity->parent->graph_mutex);
+	mutex_unlock(&entity->graph_obj.mdev->graph_mutex);
 }
 EXPORT_SYMBOL_GPL(media_entity_remove_links);
 
@@ -703,7 +705,7 @@ int __media_entity_setup_link(struct media_link *link, u32 flags)
 	    (source->stream_count || sink->stream_count))
 		return -EBUSY;
 
-	mdev = source->parent;
+	mdev = source->graph_obj.mdev;
 
 	if (mdev->link_notify) {
 		ret = mdev->link_notify(link, flags,
@@ -724,9 +726,9 @@ int media_entity_setup_link(struct media_link *link, u32 flags)
 {
 	int ret;
 
-	mutex_lock(&link->source->entity->parent->graph_mutex);
+	mutex_lock(&link->source->entity->graph_obj.mdev->graph_mutex);
 	ret = __media_entity_setup_link(link, flags);
-	mutex_unlock(&link->source->entity->parent->graph_mutex);
+	mutex_unlock(&link->source->entity->graph_obj.mdev->graph_mutex);
 
 	return ret;
 }
diff --git a/drivers/media/platform/exynos4-is/fimc-isp-video.c b/drivers/media/platform/exynos4-is/fimc-isp-video.c
index b7dc5ac66e36..3d9ccbf5f10f 100644
--- a/drivers/media/platform/exynos4-is/fimc-isp-video.c
+++ b/drivers/media/platform/exynos4-is/fimc-isp-video.c
@@ -288,7 +288,7 @@ static int isp_video_open(struct file *file)
 		goto rel_fh;
 
 	if (v4l2_fh_is_singular_file(file)) {
-		mutex_lock(&me->parent->graph_mutex);
+		mutex_lock(&me->graph_obj.mdev->graph_mutex);
 
 		ret = fimc_pipeline_call(ve, open, me, true);
 
@@ -296,7 +296,7 @@ static int isp_video_open(struct file *file)
 		if (ret == 0)
 			me->use_count++;
 
-		mutex_unlock(&me->parent->graph_mutex);
+		mutex_unlock(&me->graph_obj.mdev->graph_mutex);
 	}
 	if (!ret)
 		goto unlock;
@@ -312,7 +312,7 @@ static int isp_video_release(struct file *file)
 	struct fimc_isp *isp = video_drvdata(file);
 	struct fimc_is_video *ivc = &isp->video_capture;
 	struct media_entity *entity = &ivc->ve.vdev.entity;
-	struct media_device *mdev = entity->parent;
+	struct media_device *mdev = entity->graph_obj.mdev;
 
 	mutex_lock(&isp->video_lock);
 
diff --git a/drivers/media/platform/exynos4-is/fimc-lite.c b/drivers/media/platform/exynos4-is/fimc-lite.c
index e8f707d1729b..b2607da4ad14 100644
--- a/drivers/media/platform/exynos4-is/fimc-lite.c
+++ b/drivers/media/platform/exynos4-is/fimc-lite.c
@@ -500,7 +500,7 @@ static int fimc_lite_open(struct file *file)
 	    atomic_read(&fimc->out_path) != FIMC_IO_DMA)
 		goto unlock;
 
-	mutex_lock(&me->parent->graph_mutex);
+	mutex_lock(&me->graph_obj.mdev->graph_mutex);
 
 	ret = fimc_pipeline_call(&fimc->ve, open, me, true);
 
@@ -508,7 +508,7 @@ static int fimc_lite_open(struct file *file)
 	if (ret == 0)
 		me->use_count++;
 
-	mutex_unlock(&me->parent->graph_mutex);
+	mutex_unlock(&me->graph_obj.mdev->graph_mutex);
 
 	if (!ret) {
 		fimc_lite_clear_event_counters(fimc);
@@ -541,9 +541,9 @@ static int fimc_lite_release(struct file *file)
 		fimc_pipeline_call(&fimc->ve, close);
 		clear_bit(ST_FLITE_IN_USE, &fimc->state);
 
-		mutex_lock(&entity->parent->graph_mutex);
+		mutex_lock(&entity->graph_obj.mdev->graph_mutex);
 		entity->use_count--;
-		mutex_unlock(&entity->parent->graph_mutex);
+		mutex_unlock(&entity->graph_obj.mdev->graph_mutex);
 	}
 
 	_vb2_fop_release(file, NULL);
diff --git a/drivers/media/platform/exynos4-is/media-dev.c b/drivers/media/platform/exynos4-is/media-dev.c
index 3ba76940eef5..92dbade2fffc 100644
--- a/drivers/media/platform/exynos4-is/media-dev.c
+++ b/drivers/media/platform/exynos4-is/media-dev.c
@@ -1046,7 +1046,7 @@ static int __fimc_md_modify_pipeline(struct media_entity *entity, bool enable)
 	return ret;
 }
 
-/* Locking: called with entity->parent->graph_mutex mutex held. */
+/* Locking: called with entity->graph_obj.mdev->graph_mutex mutex held. */
 static int __fimc_md_modify_pipelines(struct media_entity *entity, bool enable)
 {
 	struct media_entity *entity_err = entity;
diff --git a/drivers/media/platform/exynos4-is/media-dev.h b/drivers/media/platform/exynos4-is/media-dev.h
index 03214541f149..9a69913b31cb 100644
--- a/drivers/media/platform/exynos4-is/media-dev.h
+++ b/drivers/media/platform/exynos4-is/media-dev.h
@@ -164,8 +164,8 @@ struct fimc_sensor_info *source_to_sensor_info(struct fimc_source_info *si)
 
 static inline struct fimc_md *entity_to_fimc_mdev(struct media_entity *me)
 {
-	return me->parent == NULL ? NULL :
-		container_of(me->parent, struct fimc_md, media_dev);
+	return me->graph_obj.mdev == NULL ? NULL :
+		container_of(me->graph_obj.mdev, struct fimc_md, media_dev);
 }
 
 static inline struct fimc_md *notifier_to_fimc_md(struct v4l2_async_notifier *n)
@@ -175,12 +175,12 @@ static inline struct fimc_md *notifier_to_fimc_md(struct v4l2_async_notifier *n)
 
 static inline void fimc_md_graph_lock(struct exynos_video_entity *ve)
 {
-	mutex_lock(&ve->vdev.entity.parent->graph_mutex);
+	mutex_lock(&ve->vdev.entity.graph_obj.mdev->graph_mutex);
 }
 
 static inline void fimc_md_graph_unlock(struct exynos_video_entity *ve)
 {
-	mutex_unlock(&ve->vdev.entity.parent->graph_mutex);
+	mutex_unlock(&ve->vdev.entity.graph_obj.mdev->graph_mutex);
 }
 
 int fimc_md_set_camclk(struct v4l2_subdev *sd, bool on);
diff --git a/drivers/media/platform/omap3isp/isp.c b/drivers/media/platform/omap3isp/isp.c
index 6351f35b0a65..aa13b17d19a0 100644
--- a/drivers/media/platform/omap3isp/isp.c
+++ b/drivers/media/platform/omap3isp/isp.c
@@ -787,7 +787,7 @@ int omap3isp_pipeline_pm_use(struct media_entity *entity, int use)
 	int change = use ? 1 : -1;
 	int ret;
 
-	mutex_lock(&entity->parent->graph_mutex);
+	mutex_lock(&entity->graph_obj.mdev->graph_mutex);
 
 	/* Apply use count to node. */
 	entity->use_count += change;
@@ -798,7 +798,7 @@ int omap3isp_pipeline_pm_use(struct media_entity *entity, int use)
 	if (ret < 0)
 		entity->use_count -= change;
 
-	mutex_unlock(&entity->parent->graph_mutex);
+	mutex_unlock(&entity->graph_obj.mdev->graph_mutex);
 
 	return ret;
 }
diff --git a/drivers/media/platform/omap3isp/ispvideo.c b/drivers/media/platform/omap3isp/ispvideo.c
index 6c89dc40df85..4c367352b1f7 100644
--- a/drivers/media/platform/omap3isp/ispvideo.c
+++ b/drivers/media/platform/omap3isp/ispvideo.c
@@ -226,7 +226,7 @@ static int isp_video_get_graph_data(struct isp_video *video,
 {
 	struct media_entity_graph graph;
 	struct media_entity *entity = &video->video.entity;
-	struct media_device *mdev = entity->parent;
+	struct media_device *mdev = entity->graph_obj.mdev;
 	struct isp_video *far_end = NULL;
 
 	mutex_lock(&mdev->graph_mutex);
diff --git a/drivers/media/platform/vsp1/vsp1_video.c b/drivers/media/platform/vsp1/vsp1_video.c
index debe4e539df6..1f94c1a54e00 100644
--- a/drivers/media/platform/vsp1/vsp1_video.c
+++ b/drivers/media/platform/vsp1/vsp1_video.c
@@ -409,7 +409,7 @@ static int vsp1_pipeline_validate(struct vsp1_pipeline *pipe,
 {
 	struct media_entity_graph graph;
 	struct media_entity *entity = &video->video.entity;
-	struct media_device *mdev = entity->parent;
+	struct media_device *mdev = entity->graph_obj.mdev;
 	unsigned int i;
 	int ret;
 
diff --git a/drivers/media/platform/xilinx/xilinx-dma.c b/drivers/media/platform/xilinx/xilinx-dma.c
index f7f9aa353a55..92e8116dc28f 100644
--- a/drivers/media/platform/xilinx/xilinx-dma.c
+++ b/drivers/media/platform/xilinx/xilinx-dma.c
@@ -181,7 +181,7 @@ static int xvip_pipeline_validate(struct xvip_pipeline *pipe,
 {
 	struct media_entity_graph graph;
 	struct media_entity *entity = &start->video.entity;
-	struct media_device *mdev = entity->parent;
+	struct media_device *mdev = entity->graph_obj.mdev;
 	unsigned int num_inputs = 0;
 	unsigned int num_outputs = 0;
 
diff --git a/drivers/staging/media/davinci_vpfe/vpfe_video.c b/drivers/staging/media/davinci_vpfe/vpfe_video.c
index 61a8d5beff58..92573fa852a9 100644
--- a/drivers/staging/media/davinci_vpfe/vpfe_video.c
+++ b/drivers/staging/media/davinci_vpfe/vpfe_video.c
@@ -130,7 +130,7 @@ __vpfe_video_get_format(struct vpfe_video_device *video,
 static void vpfe_prepare_pipeline(struct vpfe_video_device *video)
 {
 	struct media_entity *entity = &video->video_dev.entity;
-	struct media_device *mdev = entity->parent;
+	struct media_device *mdev = entity->graph_obj.mdev;
 	struct vpfe_pipeline *pipe = &video->pipe;
 	struct vpfe_video_device *far_end = NULL;
 	struct media_entity_graph graph;
@@ -288,7 +288,7 @@ static int vpfe_pipeline_enable(struct vpfe_pipeline *pipe)
 	else
 		entity = &pipe->inputs[0]->video_dev.entity;
 
-	mdev = entity->parent;
+	mdev = entity->graph_obj.mdev;
 	mutex_lock(&mdev->graph_mutex);
 	media_entity_graph_walk_start(&graph, entity);
 	while ((entity = media_entity_graph_walk_next(&graph))) {
@@ -328,7 +328,7 @@ static int vpfe_pipeline_disable(struct vpfe_pipeline *pipe)
 	else
 		entity = &pipe->inputs[0]->video_dev.entity;
 
-	mdev = entity->parent;
+	mdev = entity->graph_obj.mdev;
 	mutex_lock(&mdev->graph_mutex);
 	media_entity_graph_walk_start(&graph, entity);
 
diff --git a/drivers/staging/media/omap4iss/iss.c b/drivers/staging/media/omap4iss/iss.c
index 7226553ceb2f..40591963b42b 100644
--- a/drivers/staging/media/omap4iss/iss.c
+++ b/drivers/staging/media/omap4iss/iss.c
@@ -494,7 +494,7 @@ int omap4iss_pipeline_pm_use(struct media_entity *entity, int use)
 	int change = use ? 1 : -1;
 	int ret;
 
-	mutex_lock(&entity->parent->graph_mutex);
+	mutex_lock(&entity->graph_obj.mdev->graph_mutex);
 
 	/* Apply use count to node. */
 	entity->use_count += change;
@@ -505,7 +505,7 @@ int omap4iss_pipeline_pm_use(struct media_entity *entity, int use)
 	if (ret < 0)
 		entity->use_count -= change;
 
-	mutex_unlock(&entity->parent->graph_mutex);
+	mutex_unlock(&entity->graph_obj.mdev->graph_mutex);
 
 	return ret;
 }
diff --git a/drivers/staging/media/omap4iss/iss_video.c b/drivers/staging/media/omap4iss/iss_video.c
index 25e9e7a6b99d..45a3f2d778fc 100644
--- a/drivers/staging/media/omap4iss/iss_video.c
+++ b/drivers/staging/media/omap4iss/iss_video.c
@@ -207,7 +207,7 @@ iss_video_far_end(struct iss_video *video)
 {
 	struct media_entity_graph graph;
 	struct media_entity *entity = &video->video.entity;
-	struct media_device *mdev = entity->parent;
+	struct media_device *mdev = entity->graph_obj.mdev;
 	struct iss_video *far_end = NULL;
 
 	mutex_lock(&mdev->graph_mutex);
-- 
2.4.3



From mchehab at osg.samsung.com  Sun Aug 23 13:17:27 2015
From: mchehab at osg.samsung.com (Mauro Carvalho Chehab)
Date: Sun, 23 Aug 2015 17:17:27 -0300
Subject: [PATCH v7 10/44] [media] media: rename the function that create pad
 links
In-Reply-To: <cover.1440359643.git.mchehab@osg.samsung.com>
References: <cover.1440359643.git.mchehab@osg.samsung.com>
Message-ID: <f095b87884d435e296a455ab07a9951a74c0c3a6.1440359643.git.mchehab@osg.samsung.com>

Now that a link can be either between two different graph
objects, we'll need to add more functions to create links.
So, rename the existing one that create links only between
two pads as media_create_pad_link().

No functional changes.

This patch was created via this shell script:
	for i in $(find drivers/media -name '*.[ch]' -type f) $(find drivers/staging/media -name '*.[ch]' -type f) $(find include/ -name '*.h' -type f) ; do sed s,media_entity_create_link,media_create_pad_link,g <$i >a && mv a $i; done

Signed-off-by: Mauro Carvalho Chehab <mchehab at osg.samsung.com>
Acked-by: Hans Verkuil <hans.verkuil at cisco.com>
Signed-off-by: Mauro Carvalho Chehab <mchehab at osg.samsung.com>

diff --git a/Documentation/media-framework.txt b/Documentation/media-framework.txt
index 6903b2503577..b424de6c3bb3 100644
--- a/Documentation/media-framework.txt
+++ b/Documentation/media-framework.txt
@@ -199,7 +199,7 @@ pre-allocated and grows dynamically as needed.
 
 Drivers create links by calling
 
-	media_entity_create_link(struct media_entity *source, u16 source_pad,
+	media_create_pad_link(struct media_entity *source, u16 source_pad,
 				 struct media_entity *sink,   u16 sink_pad,
 				 u32 flags);
 
diff --git a/drivers/media/dvb-core/dvbdev.c b/drivers/media/dvb-core/dvbdev.c
index 2fdcbb5f000a..65f59f2124b4 100644
--- a/drivers/media/dvb-core/dvbdev.c
+++ b/drivers/media/dvb-core/dvbdev.c
@@ -412,16 +412,16 @@ void dvb_create_media_graph(struct dvb_adapter *adap)
 	}
 
 	if (tuner && fe)
-		media_entity_create_link(tuner, 0, fe, 0, 0);
+		media_create_pad_link(tuner, 0, fe, 0, 0);
 
 	if (fe && demux)
-		media_entity_create_link(fe, 1, demux, 0, MEDIA_LNK_FL_ENABLED);
+		media_create_pad_link(fe, 1, demux, 0, MEDIA_LNK_FL_ENABLED);
 
 	if (demux && dvr)
-		media_entity_create_link(demux, 1, dvr, 0, MEDIA_LNK_FL_ENABLED);
+		media_create_pad_link(demux, 1, dvr, 0, MEDIA_LNK_FL_ENABLED);
 
 	if (demux && ca)
-		media_entity_create_link(demux, 1, ca, 0, MEDIA_LNK_FL_ENABLED);
+		media_create_pad_link(demux, 1, ca, 0, MEDIA_LNK_FL_ENABLED);
 }
 EXPORT_SYMBOL_GPL(dvb_create_media_graph);
 #endif
diff --git a/drivers/media/i2c/s5c73m3/s5c73m3-core.c b/drivers/media/i2c/s5c73m3/s5c73m3-core.c
index 6d167428727d..c81bfbfea32f 100644
--- a/drivers/media/i2c/s5c73m3/s5c73m3-core.c
+++ b/drivers/media/i2c/s5c73m3/s5c73m3-core.c
@@ -1482,11 +1482,11 @@ static int s5c73m3_oif_registered(struct v4l2_subdev *sd)
 		return ret;
 	}
 
-	ret = media_entity_create_link(&state->sensor_sd.entity,
+	ret = media_create_pad_link(&state->sensor_sd.entity,
 			S5C73M3_ISP_PAD, &state->oif_sd.entity, OIF_ISP_PAD,
 			MEDIA_LNK_FL_IMMUTABLE | MEDIA_LNK_FL_ENABLED);
 
-	ret = media_entity_create_link(&state->sensor_sd.entity,
+	ret = media_create_pad_link(&state->sensor_sd.entity,
 			S5C73M3_JPEG_PAD, &state->oif_sd.entity, OIF_JPEG_PAD,
 			MEDIA_LNK_FL_IMMUTABLE | MEDIA_LNK_FL_ENABLED);
 
diff --git a/drivers/media/i2c/s5k5baf.c b/drivers/media/i2c/s5k5baf.c
index 30a9ca62e034..d3bff30bcb6f 100644
--- a/drivers/media/i2c/s5k5baf.c
+++ b/drivers/media/i2c/s5k5baf.c
@@ -1756,7 +1756,7 @@ static int s5k5baf_registered(struct v4l2_subdev *sd)
 		v4l2_err(sd, "failed to register subdev %s\n",
 			 state->cis_sd.name);
 	else
-		ret = media_entity_create_link(&state->cis_sd.entity, PAD_CIS,
+		ret = media_create_pad_link(&state->cis_sd.entity, PAD_CIS,
 					       &state->sd.entity, PAD_CIS,
 					       MEDIA_LNK_FL_IMMUTABLE |
 					       MEDIA_LNK_FL_ENABLED);
diff --git a/drivers/media/i2c/smiapp/smiapp-core.c b/drivers/media/i2c/smiapp/smiapp-core.c
index 308613ea0aed..5aa49eb393a9 100644
--- a/drivers/media/i2c/smiapp/smiapp-core.c
+++ b/drivers/media/i2c/smiapp/smiapp-core.c
@@ -2495,7 +2495,7 @@ static int smiapp_register_subdevs(struct smiapp_sensor *sensor)
 			return rval;
 		}
 
-		rval = media_entity_create_link(&this->sd.entity,
+		rval = media_create_pad_link(&this->sd.entity,
 						this->source_pad,
 						&last->sd.entity,
 						last->sink_pad,
@@ -2503,7 +2503,7 @@ static int smiapp_register_subdevs(struct smiapp_sensor *sensor)
 						MEDIA_LNK_FL_IMMUTABLE);
 		if (rval) {
 			dev_err(&client->dev,
-				"media_entity_create_link failed\n");
+				"media_create_pad_link failed\n");
 			return rval;
 		}
 
diff --git a/drivers/media/media-entity.c b/drivers/media/media-entity.c
index 6d515e149d7f..35e52cd1fc5a 100644
--- a/drivers/media/media-entity.c
+++ b/drivers/media/media-entity.c
@@ -542,7 +542,7 @@ static struct media_link *media_entity_add_link(struct media_entity *entity)
 }
 
 int
-media_entity_create_link(struct media_entity *source, u16 source_pad,
+media_create_pad_link(struct media_entity *source, u16 source_pad,
 			 struct media_entity *sink, u16 sink_pad, u32 flags)
 {
 	struct media_link *link;
@@ -586,7 +586,7 @@ media_entity_create_link(struct media_entity *source, u16 source_pad,
 
 	return 0;
 }
-EXPORT_SYMBOL_GPL(media_entity_create_link);
+EXPORT_SYMBOL_GPL(media_create_pad_link);
 
 void __media_entity_remove_links(struct media_entity *entity)
 {
diff --git a/drivers/media/platform/exynos4-is/media-dev.c b/drivers/media/platform/exynos4-is/media-dev.c
index 4f5586a4cbff..3ba76940eef5 100644
--- a/drivers/media/platform/exynos4-is/media-dev.c
+++ b/drivers/media/platform/exynos4-is/media-dev.c
@@ -729,7 +729,7 @@ static int __fimc_md_create_fimc_sink_links(struct fimc_md *fmd,
 		flags = ((1 << i) & link_mask) ? MEDIA_LNK_FL_ENABLED : 0;
 
 		sink = &fmd->fimc[i]->vid_cap.subdev.entity;
-		ret = media_entity_create_link(source, pad, sink,
+		ret = media_create_pad_link(source, pad, sink,
 					      FIMC_SD_PAD_SINK_CAM, flags);
 		if (ret)
 			return ret;
@@ -749,7 +749,7 @@ static int __fimc_md_create_fimc_sink_links(struct fimc_md *fmd,
 			continue;
 
 		sink = &fmd->fimc_lite[i]->subdev.entity;
-		ret = media_entity_create_link(source, pad, sink,
+		ret = media_create_pad_link(source, pad, sink,
 					       FLITE_SD_PAD_SINK, 0);
 		if (ret)
 			return ret;
@@ -781,13 +781,13 @@ static int __fimc_md_create_flite_source_links(struct fimc_md *fmd)
 		source = &fimc->subdev.entity;
 		sink = &fimc->ve.vdev.entity;
 		/* FIMC-LITE's subdev and video node */
-		ret = media_entity_create_link(source, FLITE_SD_PAD_SOURCE_DMA,
+		ret = media_create_pad_link(source, FLITE_SD_PAD_SOURCE_DMA,
 					       sink, 0, 0);
 		if (ret)
 			break;
 		/* Link from FIMC-LITE to IS-ISP subdev */
 		sink = &fmd->fimc_is->isp.subdev.entity;
-		ret = media_entity_create_link(source, FLITE_SD_PAD_SOURCE_ISP,
+		ret = media_create_pad_link(source, FLITE_SD_PAD_SOURCE_ISP,
 					       sink, 0, 0);
 		if (ret)
 			break;
@@ -811,7 +811,7 @@ static int __fimc_md_create_fimc_is_links(struct fimc_md *fmd)
 
 		/* Link from FIMC-IS-ISP subdev to FIMC */
 		sink = &fmd->fimc[i]->vid_cap.subdev.entity;
-		ret = media_entity_create_link(source, FIMC_ISP_SD_PAD_SRC_FIFO,
+		ret = media_create_pad_link(source, FIMC_ISP_SD_PAD_SRC_FIFO,
 					       sink, FIMC_SD_PAD_SINK_FIFO, 0);
 		if (ret)
 			return ret;
@@ -824,7 +824,7 @@ static int __fimc_md_create_fimc_is_links(struct fimc_md *fmd)
 	if (sink->num_pads == 0)
 		return 0;
 
-	return media_entity_create_link(source, FIMC_ISP_SD_PAD_SRC_DMA,
+	return media_create_pad_link(source, FIMC_ISP_SD_PAD_SRC_DMA,
 					sink, 0, 0);
 }
 
@@ -873,7 +873,7 @@ static int fimc_md_create_links(struct fimc_md *fmd)
 				return -EINVAL;
 
 			pad = sensor->entity.num_pads - 1;
-			ret = media_entity_create_link(&sensor->entity, pad,
+			ret = media_create_pad_link(&sensor->entity, pad,
 					      &csis->entity, CSIS_PAD_SINK,
 					      MEDIA_LNK_FL_IMMUTABLE |
 					      MEDIA_LNK_FL_ENABLED);
@@ -927,7 +927,7 @@ static int fimc_md_create_links(struct fimc_md *fmd)
 		source = &fmd->fimc[i]->vid_cap.subdev.entity;
 		sink = &fmd->fimc[i]->vid_cap.ve.vdev.entity;
 
-		ret = media_entity_create_link(source, FIMC_SD_PAD_SOURCE,
+		ret = media_create_pad_link(source, FIMC_SD_PAD_SOURCE,
 					      sink, 0, flags);
 		if (ret)
 			break;
diff --git a/drivers/media/platform/omap3isp/isp.c b/drivers/media/platform/omap3isp/isp.c
index e08183f9d0f7..6351f35b0a65 100644
--- a/drivers/media/platform/omap3isp/isp.c
+++ b/drivers/media/platform/omap3isp/isp.c
@@ -1865,7 +1865,7 @@ static int isp_link_entity(
 		return -EINVAL;
 	}
 
-	return media_entity_create_link(entity, i, input, pad, flags);
+	return media_create_pad_link(entity, i, input, pad, flags);
 }
 
 static int isp_register_entities(struct isp_device *isp)
@@ -2004,51 +2004,51 @@ static int isp_initialize_modules(struct isp_device *isp)
 	}
 
 	/* Connect the submodules. */
-	ret = media_entity_create_link(
+	ret = media_create_pad_link(
 			&isp->isp_csi2a.subdev.entity, CSI2_PAD_SOURCE,
 			&isp->isp_ccdc.subdev.entity, CCDC_PAD_SINK, 0);
 	if (ret < 0)
 		goto error_link;
 
-	ret = media_entity_create_link(
+	ret = media_create_pad_link(
 			&isp->isp_ccp2.subdev.entity, CCP2_PAD_SOURCE,
 			&isp->isp_ccdc.subdev.entity, CCDC_PAD_SINK, 0);
 	if (ret < 0)
 		goto error_link;
 
-	ret = media_entity_create_link(
+	ret = media_create_pad_link(
 			&isp->isp_ccdc.subdev.entity, CCDC_PAD_SOURCE_VP,
 			&isp->isp_prev.subdev.entity, PREV_PAD_SINK, 0);
 	if (ret < 0)
 		goto error_link;
 
-	ret = media_entity_create_link(
+	ret = media_create_pad_link(
 			&isp->isp_ccdc.subdev.entity, CCDC_PAD_SOURCE_OF,
 			&isp->isp_res.subdev.entity, RESZ_PAD_SINK, 0);
 	if (ret < 0)
 		goto error_link;
 
-	ret = media_entity_create_link(
+	ret = media_create_pad_link(
 			&isp->isp_prev.subdev.entity, PREV_PAD_SOURCE,
 			&isp->isp_res.subdev.entity, RESZ_PAD_SINK, 0);
 	if (ret < 0)
 		goto error_link;
 
-	ret = media_entity_create_link(
+	ret = media_create_pad_link(
 			&isp->isp_ccdc.subdev.entity, CCDC_PAD_SOURCE_VP,
 			&isp->isp_aewb.subdev.entity, 0,
 			MEDIA_LNK_FL_ENABLED | MEDIA_LNK_FL_IMMUTABLE);
 	if (ret < 0)
 		goto error_link;
 
-	ret = media_entity_create_link(
+	ret = media_create_pad_link(
 			&isp->isp_ccdc.subdev.entity, CCDC_PAD_SOURCE_VP,
 			&isp->isp_af.subdev.entity, 0,
 			MEDIA_LNK_FL_ENABLED | MEDIA_LNK_FL_IMMUTABLE);
 	if (ret < 0)
 		goto error_link;
 
-	ret = media_entity_create_link(
+	ret = media_create_pad_link(
 			&isp->isp_ccdc.subdev.entity, CCDC_PAD_SOURCE_VP,
 			&isp->isp_hist.subdev.entity, 0,
 			MEDIA_LNK_FL_ENABLED | MEDIA_LNK_FL_IMMUTABLE);
diff --git a/drivers/media/platform/omap3isp/ispccdc.c b/drivers/media/platform/omap3isp/ispccdc.c
index d96e3be5e252..27555e4f4aa8 100644
--- a/drivers/media/platform/omap3isp/ispccdc.c
+++ b/drivers/media/platform/omap3isp/ispccdc.c
@@ -2667,7 +2667,7 @@ static int ccdc_init_entities(struct isp_ccdc_device *ccdc)
 		goto error_video;
 
 	/* Connect the CCDC subdev to the video node. */
-	ret = media_entity_create_link(&ccdc->subdev.entity, CCDC_PAD_SOURCE_OF,
+	ret = media_create_pad_link(&ccdc->subdev.entity, CCDC_PAD_SOURCE_OF,
 			&ccdc->video_out.video.entity, 0, 0);
 	if (ret < 0)
 		goto error_link;
diff --git a/drivers/media/platform/omap3isp/ispccp2.c b/drivers/media/platform/omap3isp/ispccp2.c
index e1b5f5bea541..b215eb5049d6 100644
--- a/drivers/media/platform/omap3isp/ispccp2.c
+++ b/drivers/media/platform/omap3isp/ispccp2.c
@@ -1100,7 +1100,7 @@ static int ccp2_init_entities(struct isp_ccp2_device *ccp2)
 		goto error_video;
 
 	/* Connect the video node to the ccp2 subdev. */
-	ret = media_entity_create_link(&ccp2->video_in.video.entity, 0,
+	ret = media_create_pad_link(&ccp2->video_in.video.entity, 0,
 				       &ccp2->subdev.entity, CCP2_PAD_SINK, 0);
 	if (ret < 0)
 		goto error_link;
diff --git a/drivers/media/platform/omap3isp/ispcsi2.c b/drivers/media/platform/omap3isp/ispcsi2.c
index 6fff92f0813a..fcefc1e74881 100644
--- a/drivers/media/platform/omap3isp/ispcsi2.c
+++ b/drivers/media/platform/omap3isp/ispcsi2.c
@@ -1265,7 +1265,7 @@ static int csi2_init_entities(struct isp_csi2_device *csi2)
 		goto error_video;
 
 	/* Connect the CSI2 subdev to the video node. */
-	ret = media_entity_create_link(&csi2->subdev.entity, CSI2_PAD_SOURCE,
+	ret = media_create_pad_link(&csi2->subdev.entity, CSI2_PAD_SOURCE,
 				       &csi2->video_out.video.entity, 0, 0);
 	if (ret < 0)
 		goto error_link;
diff --git a/drivers/media/platform/omap3isp/isppreview.c b/drivers/media/platform/omap3isp/isppreview.c
index b440c6342ca4..ad38d20c7770 100644
--- a/drivers/media/platform/omap3isp/isppreview.c
+++ b/drivers/media/platform/omap3isp/isppreview.c
@@ -2312,12 +2312,12 @@ static int preview_init_entities(struct isp_prev_device *prev)
 		goto error_video_out;
 
 	/* Connect the video nodes to the previewer subdev. */
-	ret = media_entity_create_link(&prev->video_in.video.entity, 0,
+	ret = media_create_pad_link(&prev->video_in.video.entity, 0,
 			&prev->subdev.entity, PREV_PAD_SINK, 0);
 	if (ret < 0)
 		goto error_link;
 
-	ret = media_entity_create_link(&prev->subdev.entity, PREV_PAD_SOURCE,
+	ret = media_create_pad_link(&prev->subdev.entity, PREV_PAD_SOURCE,
 			&prev->video_out.video.entity, 0, 0);
 	if (ret < 0)
 		goto error_link;
diff --git a/drivers/media/platform/omap3isp/ispresizer.c b/drivers/media/platform/omap3isp/ispresizer.c
index 3deb1ec4a973..b48ad4d4b834 100644
--- a/drivers/media/platform/omap3isp/ispresizer.c
+++ b/drivers/media/platform/omap3isp/ispresizer.c
@@ -1756,12 +1756,12 @@ static int resizer_init_entities(struct isp_res_device *res)
 	res->video_out.video.entity.flags |= MEDIA_ENT_FL_DEFAULT;
 
 	/* Connect the video nodes to the resizer subdev. */
-	ret = media_entity_create_link(&res->video_in.video.entity, 0,
+	ret = media_create_pad_link(&res->video_in.video.entity, 0,
 			&res->subdev.entity, RESZ_PAD_SINK, 0);
 	if (ret < 0)
 		goto error_link;
 
-	ret = media_entity_create_link(&res->subdev.entity, RESZ_PAD_SOURCE,
+	ret = media_create_pad_link(&res->subdev.entity, RESZ_PAD_SOURCE,
 			&res->video_out.video.entity, 0, 0);
 	if (ret < 0)
 		goto error_link;
diff --git a/drivers/media/platform/s3c-camif/camif-core.c b/drivers/media/platform/s3c-camif/camif-core.c
index f47b332f0418..3e33c60be004 100644
--- a/drivers/media/platform/s3c-camif/camif-core.c
+++ b/drivers/media/platform/s3c-camif/camif-core.c
@@ -263,7 +263,7 @@ static int camif_create_media_links(struct camif_dev *camif)
 {
 	int i, ret;
 
-	ret = media_entity_create_link(&camif->sensor.sd->entity, 0,
+	ret = media_create_pad_link(&camif->sensor.sd->entity, 0,
 				&camif->subdev.entity, CAMIF_SD_PAD_SINK,
 				MEDIA_LNK_FL_IMMUTABLE |
 				MEDIA_LNK_FL_ENABLED);
@@ -271,7 +271,7 @@ static int camif_create_media_links(struct camif_dev *camif)
 		return ret;
 
 	for (i = 1; i < CAMIF_SD_PADS_NUM && !ret; i++) {
-		ret = media_entity_create_link(&camif->subdev.entity, i,
+		ret = media_create_pad_link(&camif->subdev.entity, i,
 				&camif->vp[i - 1].vdev.entity, 0,
 				MEDIA_LNK_FL_IMMUTABLE |
 				MEDIA_LNK_FL_ENABLED);
diff --git a/drivers/media/platform/vsp1/vsp1_drv.c b/drivers/media/platform/vsp1/vsp1_drv.c
index 4e61886384e3..9cd94a76a9ed 100644
--- a/drivers/media/platform/vsp1/vsp1_drv.c
+++ b/drivers/media/platform/vsp1/vsp1_drv.c
@@ -101,7 +101,7 @@ static int vsp1_create_links(struct vsp1_device *vsp1, struct vsp1_entity *sink)
 			if (!(entity->pads[pad].flags & MEDIA_PAD_FL_SINK))
 				continue;
 
-			ret = media_entity_create_link(&source->subdev.entity,
+			ret = media_create_pad_link(&source->subdev.entity,
 						       source->source_pad,
 						       entity, pad, flags);
 			if (ret < 0)
@@ -262,7 +262,7 @@ static int vsp1_create_entities(struct vsp1_device *vsp1)
 	}
 
 	if (vsp1->pdata.features & VSP1_HAS_LIF) {
-		ret = media_entity_create_link(
+		ret = media_create_pad_link(
 			&vsp1->wpf[0]->entity.subdev.entity, RWPF_PAD_SOURCE,
 			&vsp1->lif->entity.subdev.entity, LIF_PAD_SINK, 0);
 		if (ret < 0)
diff --git a/drivers/media/platform/vsp1/vsp1_rpf.c b/drivers/media/platform/vsp1/vsp1_rpf.c
index 3294529a3108..b60a528a8fe8 100644
--- a/drivers/media/platform/vsp1/vsp1_rpf.c
+++ b/drivers/media/platform/vsp1/vsp1_rpf.c
@@ -278,7 +278,7 @@ struct vsp1_rwpf *vsp1_rpf_create(struct vsp1_device *vsp1, unsigned int index)
 	rpf->entity.video = video;
 
 	/* Connect the video device to the RPF. */
-	ret = media_entity_create_link(&rpf->video.video.entity, 0,
+	ret = media_create_pad_link(&rpf->video.video.entity, 0,
 				       &rpf->entity.subdev.entity,
 				       RWPF_PAD_SINK,
 				       MEDIA_LNK_FL_ENABLED |
diff --git a/drivers/media/platform/vsp1/vsp1_wpf.c b/drivers/media/platform/vsp1/vsp1_wpf.c
index 1d2b3a2f1573..d39aa4b8aea1 100644
--- a/drivers/media/platform/vsp1/vsp1_wpf.c
+++ b/drivers/media/platform/vsp1/vsp1_wpf.c
@@ -284,7 +284,7 @@ struct vsp1_rwpf *vsp1_wpf_create(struct vsp1_device *vsp1, unsigned int index)
 	if (!(vsp1->pdata.features & VSP1_HAS_LIF) || index != 0)
 		flags |= MEDIA_LNK_FL_IMMUTABLE;
 
-	ret = media_entity_create_link(&wpf->entity.subdev.entity,
+	ret = media_create_pad_link(&wpf->entity.subdev.entity,
 				       RWPF_PAD_SOURCE,
 				       &wpf->video.video.entity, 0, flags);
 	if (ret < 0)
diff --git a/drivers/media/platform/xilinx/xilinx-vipp.c b/drivers/media/platform/xilinx/xilinx-vipp.c
index 7b7cb9c28d2c..79d4be7ce9a5 100644
--- a/drivers/media/platform/xilinx/xilinx-vipp.c
+++ b/drivers/media/platform/xilinx/xilinx-vipp.c
@@ -156,7 +156,7 @@ static int xvip_graph_build_one(struct xvip_composite_device *xdev,
 			local->name, local_pad->index,
 			remote->name, remote_pad->index);
 
-		ret = media_entity_create_link(local, local_pad->index,
+		ret = media_create_pad_link(local, local_pad->index,
 					       remote, remote_pad->index,
 					       link_flags);
 		if (ret < 0) {
@@ -270,7 +270,7 @@ static int xvip_graph_build_dma(struct xvip_composite_device *xdev)
 			source->name, source_pad->index,
 			sink->name, sink_pad->index);
 
-		ret = media_entity_create_link(source, source_pad->index,
+		ret = media_create_pad_link(source, source_pad->index,
 					       sink, sink_pad->index,
 					       link_flags);
 		if (ret < 0) {
diff --git a/drivers/media/usb/au0828/au0828-core.c b/drivers/media/usb/au0828/au0828-core.c
index 0378a2c99ebb..a55eb524ea21 100644
--- a/drivers/media/usb/au0828/au0828-core.c
+++ b/drivers/media/usb/au0828/au0828-core.c
@@ -260,13 +260,13 @@ static void au0828_create_media_graph(struct au0828_dev *dev)
 		return;
 
 	if (tuner)
-		media_entity_create_link(tuner, 0, decoder, 0,
+		media_create_pad_link(tuner, 0, decoder, 0,
 					 MEDIA_LNK_FL_ENABLED);
 	if (dev->vdev.entity.links)
-		media_entity_create_link(decoder, 1, &dev->vdev.entity, 0,
+		media_create_pad_link(decoder, 1, &dev->vdev.entity, 0,
 				 MEDIA_LNK_FL_ENABLED);
 	if (dev->vbi_dev.entity.links)
-		media_entity_create_link(decoder, 2, &dev->vbi_dev.entity, 0,
+		media_create_pad_link(decoder, 2, &dev->vbi_dev.entity, 0,
 				 MEDIA_LNK_FL_ENABLED);
 #endif
 }
diff --git a/drivers/media/usb/cx231xx/cx231xx-cards.c b/drivers/media/usb/cx231xx/cx231xx-cards.c
index 4a117a58c39a..3b5c9ae39ad3 100644
--- a/drivers/media/usb/cx231xx/cx231xx-cards.c
+++ b/drivers/media/usb/cx231xx/cx231xx-cards.c
@@ -1264,11 +1264,11 @@ static void cx231xx_create_media_graph(struct cx231xx *dev)
 		return;
 
 	if (tuner)
-		media_entity_create_link(tuner, 0, decoder, 0,
+		media_create_pad_link(tuner, 0, decoder, 0,
 					 MEDIA_LNK_FL_ENABLED);
-	media_entity_create_link(decoder, 1, &dev->vdev.entity, 0,
+	media_create_pad_link(decoder, 1, &dev->vdev.entity, 0,
 				 MEDIA_LNK_FL_ENABLED);
-	media_entity_create_link(decoder, 2, &dev->vbi_dev.entity, 0,
+	media_create_pad_link(decoder, 2, &dev->vbi_dev.entity, 0,
 				 MEDIA_LNK_FL_ENABLED);
 #endif
 }
diff --git a/drivers/media/usb/uvc/uvc_entity.c b/drivers/media/usb/uvc/uvc_entity.c
index 245445491516..429e428ccd93 100644
--- a/drivers/media/usb/uvc/uvc_entity.c
+++ b/drivers/media/usb/uvc/uvc_entity.c
@@ -56,7 +56,7 @@ static int uvc_mc_register_entity(struct uvc_video_chain *chain,
 			continue;
 
 		remote_pad = remote->num_pads - 1;
-		ret = media_entity_create_link(source, remote_pad,
+		ret = media_create_pad_link(source, remote_pad,
 					       sink, i, flags);
 		if (ret < 0)
 			return ret;
diff --git a/drivers/staging/media/davinci_vpfe/dm365_ipipeif.c b/drivers/staging/media/davinci_vpfe/dm365_ipipeif.c
index 8fb676186898..d96bdaaae50e 100644
--- a/drivers/staging/media/davinci_vpfe/dm365_ipipeif.c
+++ b/drivers/staging/media/davinci_vpfe/dm365_ipipeif.c
@@ -971,7 +971,7 @@ vpfe_ipipeif_register_entities(struct vpfe_ipipeif_device *ipipeif,
 	ipipeif->video_in.vpfe_dev = vpfe_dev;
 
 	flags = 0;
-	ret = media_entity_create_link(&ipipeif->video_in.video_dev.entity, 0,
+	ret = media_create_pad_link(&ipipeif->video_in.video_dev.entity, 0,
 					&ipipeif->subdev.entity, 0, flags);
 	if (ret < 0)
 		goto fail;
diff --git a/drivers/staging/media/davinci_vpfe/dm365_isif.c b/drivers/staging/media/davinci_vpfe/dm365_isif.c
index b1f01adfa7c8..df77288b0ec0 100644
--- a/drivers/staging/media/davinci_vpfe/dm365_isif.c
+++ b/drivers/staging/media/davinci_vpfe/dm365_isif.c
@@ -1817,7 +1817,7 @@ int vpfe_isif_register_entities(struct vpfe_isif_device *isif,
 	isif->video_out.vpfe_dev = vpfe_dev;
 	flags = 0;
 	/* connect isif to video node */
-	ret = media_entity_create_link(&isif->subdev.entity, 1,
+	ret = media_create_pad_link(&isif->subdev.entity, 1,
 				       &isif->video_out.video_dev.entity,
 				       0, flags);
 	if (ret < 0)
diff --git a/drivers/staging/media/davinci_vpfe/dm365_resizer.c b/drivers/staging/media/davinci_vpfe/dm365_resizer.c
index 692789aa22f4..ae942de3a23d 100644
--- a/drivers/staging/media/davinci_vpfe/dm365_resizer.c
+++ b/drivers/staging/media/davinci_vpfe/dm365_resizer.c
@@ -1831,27 +1831,27 @@ int vpfe_resizer_register_entities(struct vpfe_resizer_device *resizer,
 	resizer->resizer_b.video_out.vpfe_dev = vpfe_dev;
 
 	/* create link between Resizer Crop----> Resizer A*/
-	ret = media_entity_create_link(&resizer->crop_resizer.subdev.entity, 1,
+	ret = media_create_pad_link(&resizer->crop_resizer.subdev.entity, 1,
 				&resizer->resizer_a.subdev.entity,
 				0, flags);
 	if (ret < 0)
 		goto out_create_link;
 
 	/* create link between Resizer Crop----> Resizer B*/
-	ret = media_entity_create_link(&resizer->crop_resizer.subdev.entity, 2,
+	ret = media_create_pad_link(&resizer->crop_resizer.subdev.entity, 2,
 				&resizer->resizer_b.subdev.entity,
 				0, flags);
 	if (ret < 0)
 		goto out_create_link;
 
 	/* create link between Resizer A ----> video out */
-	ret = media_entity_create_link(&resizer->resizer_a.subdev.entity, 1,
+	ret = media_create_pad_link(&resizer->resizer_a.subdev.entity, 1,
 		&resizer->resizer_a.video_out.video_dev.entity, 0, flags);
 	if (ret < 0)
 		goto out_create_link;
 
 	/* create link between Resizer B ----> video out */
-	ret = media_entity_create_link(&resizer->resizer_b.subdev.entity, 1,
+	ret = media_create_pad_link(&resizer->resizer_b.subdev.entity, 1,
 		&resizer->resizer_b.video_out.video_dev.entity, 0, flags);
 	if (ret < 0)
 		goto out_create_link;
diff --git a/drivers/staging/media/davinci_vpfe/vpfe_mc_capture.c b/drivers/staging/media/davinci_vpfe/vpfe_mc_capture.c
index 57426199ad7a..08c8a5f967d3 100644
--- a/drivers/staging/media/davinci_vpfe/vpfe_mc_capture.c
+++ b/drivers/staging/media/davinci_vpfe/vpfe_mc_capture.c
@@ -445,32 +445,32 @@ static int vpfe_register_entities(struct vpfe_device *vpfe_dev)
 		/* if entity has no pads (ex: amplifier),
 		   cant establish link */
 		if (vpfe_dev->sd[i]->entity.num_pads) {
-			ret = media_entity_create_link(&vpfe_dev->sd[i]->entity,
+			ret = media_create_pad_link(&vpfe_dev->sd[i]->entity,
 				0, &vpfe_dev->vpfe_isif.subdev.entity,
 				0, flags);
 			if (ret < 0)
 				goto out_resizer_register;
 		}
 
-	ret = media_entity_create_link(&vpfe_dev->vpfe_isif.subdev.entity, 1,
+	ret = media_create_pad_link(&vpfe_dev->vpfe_isif.subdev.entity, 1,
 				       &vpfe_dev->vpfe_ipipeif.subdev.entity,
 				       0, flags);
 	if (ret < 0)
 		goto out_resizer_register;
 
-	ret = media_entity_create_link(&vpfe_dev->vpfe_ipipeif.subdev.entity, 1,
+	ret = media_create_pad_link(&vpfe_dev->vpfe_ipipeif.subdev.entity, 1,
 				       &vpfe_dev->vpfe_ipipe.subdev.entity,
 				       0, flags);
 	if (ret < 0)
 		goto out_resizer_register;
 
-	ret = media_entity_create_link(&vpfe_dev->vpfe_ipipe.subdev.entity,
+	ret = media_create_pad_link(&vpfe_dev->vpfe_ipipe.subdev.entity,
 			1, &vpfe_dev->vpfe_resizer.crop_resizer.subdev.entity,
 			0, flags);
 	if (ret < 0)
 		goto out_resizer_register;
 
-	ret = media_entity_create_link(&vpfe_dev->vpfe_ipipeif.subdev.entity, 1,
+	ret = media_create_pad_link(&vpfe_dev->vpfe_ipipeif.subdev.entity, 1,
 			&vpfe_dev->vpfe_resizer.crop_resizer.subdev.entity,
 			0, flags);
 	if (ret < 0)
diff --git a/drivers/staging/media/omap4iss/iss.c b/drivers/staging/media/omap4iss/iss.c
index e54a7afd31de..7226553ceb2f 100644
--- a/drivers/staging/media/omap4iss/iss.c
+++ b/drivers/staging/media/omap4iss/iss.c
@@ -1259,7 +1259,7 @@ static int iss_register_entities(struct iss_device *iss)
 			goto done;
 		}
 
-		ret = media_entity_create_link(&sensor->entity, 0, input, pad,
+		ret = media_create_pad_link(&sensor->entity, 0, input, pad,
 					       flags);
 		if (ret < 0)
 			goto done;
@@ -1317,31 +1317,31 @@ static int iss_initialize_modules(struct iss_device *iss)
 	}
 
 	/* Connect the submodules. */
-	ret = media_entity_create_link(
+	ret = media_create_pad_link(
 			&iss->csi2a.subdev.entity, CSI2_PAD_SOURCE,
 			&iss->ipipeif.subdev.entity, IPIPEIF_PAD_SINK, 0);
 	if (ret < 0)
 		goto error_link;
 
-	ret = media_entity_create_link(
+	ret = media_create_pad_link(
 			&iss->csi2b.subdev.entity, CSI2_PAD_SOURCE,
 			&iss->ipipeif.subdev.entity, IPIPEIF_PAD_SINK, 0);
 	if (ret < 0)
 		goto error_link;
 
-	ret = media_entity_create_link(
+	ret = media_create_pad_link(
 			&iss->ipipeif.subdev.entity, IPIPEIF_PAD_SOURCE_VP,
 			&iss->resizer.subdev.entity, RESIZER_PAD_SINK, 0);
 	if (ret < 0)
 		goto error_link;
 
-	ret = media_entity_create_link(
+	ret = media_create_pad_link(
 			&iss->ipipeif.subdev.entity, IPIPEIF_PAD_SOURCE_VP,
 			&iss->ipipe.subdev.entity, IPIPE_PAD_SINK, 0);
 	if (ret < 0)
 		goto error_link;
 
-	ret = media_entity_create_link(
+	ret = media_create_pad_link(
 			&iss->ipipe.subdev.entity, IPIPE_PAD_SOURCE_VP,
 			&iss->resizer.subdev.entity, RESIZER_PAD_SINK, 0);
 	if (ret < 0)
diff --git a/drivers/staging/media/omap4iss/iss_csi2.c b/drivers/staging/media/omap4iss/iss_csi2.c
index e936cfc218cb..6b4dcbfa9425 100644
--- a/drivers/staging/media/omap4iss/iss_csi2.c
+++ b/drivers/staging/media/omap4iss/iss_csi2.c
@@ -1291,7 +1291,7 @@ static int csi2_init_entities(struct iss_csi2_device *csi2, const char *subname)
 		goto error_video;
 
 	/* Connect the CSI2 subdev to the video node. */
-	ret = media_entity_create_link(&csi2->subdev.entity, CSI2_PAD_SOURCE,
+	ret = media_create_pad_link(&csi2->subdev.entity, CSI2_PAD_SOURCE,
 				       &csi2->video_out.video.entity, 0, 0);
 	if (ret < 0)
 		goto error_link;
diff --git a/drivers/staging/media/omap4iss/iss_ipipeif.c b/drivers/staging/media/omap4iss/iss_ipipeif.c
index be5f80d7b5dc..44c432ef2ac5 100644
--- a/drivers/staging/media/omap4iss/iss_ipipeif.c
+++ b/drivers/staging/media/omap4iss/iss_ipipeif.c
@@ -762,7 +762,7 @@ static int ipipeif_init_entities(struct iss_ipipeif_device *ipipeif)
 		return ret;
 
 	/* Connect the IPIPEIF subdev to the video node. */
-	ret = media_entity_create_link(&ipipeif->subdev.entity,
+	ret = media_create_pad_link(&ipipeif->subdev.entity,
 				       IPIPEIF_PAD_SOURCE_ISIF_SF,
 				       &ipipeif->video_out.video.entity, 0, 0);
 	if (ret < 0)
diff --git a/drivers/staging/media/omap4iss/iss_resizer.c b/drivers/staging/media/omap4iss/iss_resizer.c
index 91e724085dba..b659e465cb56 100644
--- a/drivers/staging/media/omap4iss/iss_resizer.c
+++ b/drivers/staging/media/omap4iss/iss_resizer.c
@@ -806,7 +806,7 @@ static int resizer_init_entities(struct iss_resizer_device *resizer)
 		return ret;
 
 	/* Connect the RESIZER subdev to the video node. */
-	ret = media_entity_create_link(&resizer->subdev.entity,
+	ret = media_create_pad_link(&resizer->subdev.entity,
 				       RESIZER_PAD_SOURCE_MEM,
 				       &resizer->video_out.video.entity, 0, 0);
 	if (ret < 0)
diff --git a/include/media/media-entity.h b/include/media/media-entity.h
index af6646ddf6db..e0e4b014ce62 100644
--- a/include/media/media-entity.h
+++ b/include/media/media-entity.h
@@ -208,7 +208,7 @@ int media_entity_init(struct media_entity *entity, u16 num_pads,
 		struct media_pad *pads);
 void media_entity_cleanup(struct media_entity *entity);
 
-int media_entity_create_link(struct media_entity *source, u16 source_pad,
+int media_create_pad_link(struct media_entity *source, u16 source_pad,
 		struct media_entity *sink, u16 sink_pad, u32 flags);
 void __media_entity_remove_links(struct media_entity *entity);
 void media_entity_remove_links(struct media_entity *entity);
-- 
2.4.3



From mchehab at osg.samsung.com  Sun Aug 23 13:17:45 2015
From: mchehab at osg.samsung.com (Mauro Carvalho Chehab)
Date: Sun, 23 Aug 2015 17:17:45 -0300
Subject: [PATCH v7 28/44] [media] media: use macros to check for V4L2 subdev
 entities
In-Reply-To: <cover.1440359643.git.mchehab@osg.samsung.com>
References: <cover.1440359643.git.mchehab@osg.samsung.com>
Message-ID: <dd6ce157dc49ac77fd54145cc25c76fce51a3cdc.1440359643.git.mchehab@osg.samsung.com>

Instead of relying on media subtype, use the new macros to detect
if an entity is a subdev or an A/V DMA entity.

Please note that most drivers assume that there's just AV_DMA or
V4L2 subdevs. This is not true anymore, as we've added MC support
for DVB, and there are plans to add support for ALSA and FB/DRM
too.

Ok, on the current pipelines supported by those drivers, just V4L
stuff are there, but, assuming that some day a pipeline that also
works with other subsystems will ever added, it is better to add
explicit checks for the AV_DMA stuff.

Signed-off-by: Mauro Carvalho Chehab <mchehab at osg.samsung.com>

diff --git a/drivers/media/platform/exynos4-is/common.c b/drivers/media/platform/exynos4-is/common.c
index 0eb34ecb8ee4..1f1b9a56e24e 100644
--- a/drivers/media/platform/exynos4-is/common.c
+++ b/drivers/media/platform/exynos4-is/common.c
@@ -22,8 +22,7 @@ struct v4l2_subdev *fimc_find_remote_sensor(struct media_entity *entity)
 	while (pad->flags & MEDIA_PAD_FL_SINK) {
 		/* source pad */
 		pad = media_entity_remote_pad(pad);
-		if (pad == NULL ||
-		    media_entity_type(pad->entity) != MEDIA_ENT_T_V4L2_SUBDEV)
+		if (!is_media_entity_v4l2_subdev(pad->entity))
 			break;
 
 		sd = media_entity_to_v4l2_subdev(pad->entity);
diff --git a/drivers/media/platform/exynos4-is/fimc-capture.c b/drivers/media/platform/exynos4-is/fimc-capture.c
index 0627a93b2f3b..79b43b89266a 100644
--- a/drivers/media/platform/exynos4-is/fimc-capture.c
+++ b/drivers/media/platform/exynos4-is/fimc-capture.c
@@ -1141,8 +1141,7 @@ static int fimc_pipeline_validate(struct fimc_dev *fimc)
 			}
 		}
 
-		if (src_pad == NULL ||
-		    media_entity_type(src_pad->entity) != MEDIA_ENT_T_V4L2_SUBDEV)
+		if (!is_media_entity_v4l2_subdev(src_pad->entity))
 			break;
 
 		/* Don't call FIMC subdev operation to avoid nested locking */
@@ -1397,7 +1396,7 @@ static int fimc_link_setup(struct media_entity *entity,
 	struct fimc_vid_cap *vc = &fimc->vid_cap;
 	struct v4l2_subdev *sensor;
 
-	if (media_entity_type(remote->entity) != MEDIA_ENT_T_V4L2_SUBDEV)
+	if (!is_media_entity_v4l2_subdev(remote->entity))
 		return -EINVAL;
 
 	if (WARN_ON(fimc == NULL))
diff --git a/drivers/media/platform/exynos4-is/fimc-isp-video.c b/drivers/media/platform/exynos4-is/fimc-isp-video.c
index 3d9ccbf5f10f..0ea948ad668c 100644
--- a/drivers/media/platform/exynos4-is/fimc-isp-video.c
+++ b/drivers/media/platform/exynos4-is/fimc-isp-video.c
@@ -467,8 +467,7 @@ static int isp_video_pipeline_validate(struct fimc_isp *isp)
 
 		/* Retrieve format at the source pad */
 		pad = media_entity_remote_pad(pad);
-		if (pad == NULL ||
-		    media_entity_type(pad->entity) != MEDIA_ENT_T_V4L2_SUBDEV)
+		if (!is_media_entity_v4l2_subdev(pad->entity))
 			break;
 
 		sd = media_entity_to_v4l2_subdev(pad->entity);
diff --git a/drivers/media/platform/exynos4-is/fimc-lite.c b/drivers/media/platform/exynos4-is/fimc-lite.c
index b2607da4ad14..df2ac6b0afd1 100644
--- a/drivers/media/platform/exynos4-is/fimc-lite.c
+++ b/drivers/media/platform/exynos4-is/fimc-lite.c
@@ -814,8 +814,7 @@ static int fimc_pipeline_validate(struct fimc_lite *fimc)
 		}
 		/* Retrieve format at the source pad */
 		pad = media_entity_remote_pad(pad);
-		if (pad == NULL ||
-		    media_entity_type(pad->entity) != MEDIA_ENT_T_V4L2_SUBDEV)
+		if (!is_media_entity_v4l2_subdev(pad->entity))
 			break;
 
 		sd = media_entity_to_v4l2_subdev(pad->entity);
@@ -988,7 +987,6 @@ static int fimc_lite_link_setup(struct media_entity *entity,
 {
 	struct v4l2_subdev *sd = media_entity_to_v4l2_subdev(entity);
 	struct fimc_lite *fimc = v4l2_get_subdevdata(sd);
-	unsigned int remote_ent_type = media_entity_type(remote->entity);
 	int ret = 0;
 
 	if (WARN_ON(fimc == NULL))
@@ -1000,7 +998,7 @@ static int fimc_lite_link_setup(struct media_entity *entity,
 
 	switch (local->index) {
 	case FLITE_SD_PAD_SINK:
-		if (remote_ent_type != MEDIA_ENT_T_V4L2_SUBDEV) {
+		if (!is_media_entity_v4l2_subdev(remote->entity)) {
 			ret = -EINVAL;
 			break;
 		}
@@ -1018,7 +1016,7 @@ static int fimc_lite_link_setup(struct media_entity *entity,
 	case FLITE_SD_PAD_SOURCE_DMA:
 		if (!(flags & MEDIA_LNK_FL_ENABLED))
 			atomic_set(&fimc->out_path, FIMC_IO_NONE);
-		else if (remote_ent_type == MEDIA_ENT_T_DEVNODE)
+		else if (is_media_v4l2_io(remote->entity))
 			atomic_set(&fimc->out_path, FIMC_IO_DMA);
 		else
 			ret = -EINVAL;
@@ -1027,7 +1025,7 @@ static int fimc_lite_link_setup(struct media_entity *entity,
 	case FLITE_SD_PAD_SOURCE_ISP:
 		if (!(flags & MEDIA_LNK_FL_ENABLED))
 			atomic_set(&fimc->out_path, FIMC_IO_NONE);
-		else if (remote_ent_type == MEDIA_ENT_T_V4L2_SUBDEV)
+		else if (is_media_entity_v4l2_subdev(remote->entity)))
 			atomic_set(&fimc->out_path, FIMC_IO_ISP);
 		else
 			ret = -EINVAL;
diff --git a/drivers/media/platform/exynos4-is/media-dev.c b/drivers/media/platform/exynos4-is/media-dev.c
index 92dbade2fffc..428fead69095 100644
--- a/drivers/media/platform/exynos4-is/media-dev.c
+++ b/drivers/media/platform/exynos4-is/media-dev.c
@@ -88,8 +88,7 @@ static void fimc_pipeline_prepare(struct fimc_pipeline *p,
 				break;
 		}
 
-		if (pad == NULL ||
-		    media_entity_type(pad->entity) != MEDIA_ENT_T_V4L2_SUBDEV)
+		if (!is_media_entity_v4l2_subdev(pad->entity))
 			break;
 		sd = media_entity_to_v4l2_subdev(pad->entity);
 
@@ -1062,7 +1061,7 @@ static int __fimc_md_modify_pipelines(struct media_entity *entity, bool enable)
 	media_entity_graph_walk_start(&graph, entity);
 
 	while ((entity = media_entity_graph_walk_next(&graph))) {
-		if (media_entity_type(entity) != MEDIA_ENT_T_DEVNODE)
+		if (!is_media_entity_v4l2_io(entity))
 			continue;
 
 		ret  = __fimc_md_modify_pipeline(entity, enable);
@@ -1076,7 +1075,7 @@ static int __fimc_md_modify_pipelines(struct media_entity *entity, bool enable)
 	media_entity_graph_walk_start(&graph, entity_err);
 
 	while ((entity_err = media_entity_graph_walk_next(&graph))) {
-		if (media_entity_type(entity_err) != MEDIA_ENT_T_DEVNODE)
+		if (!is_media_entity_v4l2_io(entity_err))
 			continue;
 
 		__fimc_md_modify_pipeline(entity_err, !enable);
diff --git a/drivers/media/platform/omap3isp/isp.c b/drivers/media/platform/omap3isp/isp.c
index aa13b17d19a0..fe29e56528ed 100644
--- a/drivers/media/platform/omap3isp/isp.c
+++ b/drivers/media/platform/omap3isp/isp.c
@@ -691,7 +691,7 @@ static int isp_pipeline_pm_use_count(struct media_entity *entity)
 	media_entity_graph_walk_start(&graph, entity);
 
 	while ((entity = media_entity_graph_walk_next(&graph))) {
-		if (media_entity_type(entity) == MEDIA_ENT_T_DEVNODE)
+		if (is_media_entity_v4l2_io(entity))
 			use += entity->use_count;
 	}
 
@@ -714,7 +714,7 @@ static int isp_pipeline_pm_power_one(struct media_entity *entity, int change)
 	struct v4l2_subdev *subdev;
 	int ret;
 
-	subdev = media_entity_type(entity) == MEDIA_ENT_T_V4L2_SUBDEV
+	subdev = is_media_entity_v4l2_subdev(entity))
 	       ? media_entity_to_v4l2_subdev(entity) : NULL;
 
 	if (entity->use_count == 0 && change > 0 && subdev != NULL) {
@@ -754,7 +754,7 @@ static int isp_pipeline_pm_power(struct media_entity *entity, int change)
 	media_entity_graph_walk_start(&graph, entity);
 
 	while (!ret && (entity = media_entity_graph_walk_next(&graph)))
-		if (media_entity_type(entity) != MEDIA_ENT_T_DEVNODE)
+		if (is_media_entity_v4l2_subdev(entity))
 			ret = isp_pipeline_pm_power_one(entity, change);
 
 	if (!ret)
@@ -764,7 +764,7 @@ static int isp_pipeline_pm_power(struct media_entity *entity, int change)
 
 	while ((first = media_entity_graph_walk_next(&graph))
 	       && first != entity)
-		if (media_entity_type(first) != MEDIA_ENT_T_DEVNODE)
+		if (is_media_entity_v4l2_subdev(first))
 			isp_pipeline_pm_power_one(first, -change);
 
 	return ret;
@@ -897,8 +897,7 @@ static int isp_pipeline_enable(struct isp_pipeline *pipe,
 			break;
 
 		pad = media_entity_remote_pad(pad);
-		if (pad == NULL ||
-		    media_entity_type(pad->entity) != MEDIA_ENT_T_V4L2_SUBDEV)
+		if (!is_media_entity_v4l2_subdev(pad->entity))
 			break;
 
 		entity = pad->entity;
@@ -988,8 +987,7 @@ static int isp_pipeline_disable(struct isp_pipeline *pipe)
 			break;
 
 		pad = media_entity_remote_pad(pad);
-		if (pad == NULL ||
-		    media_entity_type(pad->entity) != MEDIA_ENT_T_V4L2_SUBDEV)
+		if (!is_media_entity_v4l2_subdev(pad->entity))
 			break;
 
 		entity = pad->entity;
diff --git a/drivers/media/platform/omap3isp/ispvideo.c b/drivers/media/platform/omap3isp/ispvideo.c
index 4c367352b1f7..3518c7d283d0 100644
--- a/drivers/media/platform/omap3isp/ispvideo.c
+++ b/drivers/media/platform/omap3isp/ispvideo.c
@@ -210,8 +210,7 @@ isp_video_remote_subdev(struct isp_video *video, u32 *pad)
 
 	remote = media_entity_remote_pad(&video->pad);
 
-	if (remote == NULL ||
-	    media_entity_type(remote->entity) != MEDIA_ENT_T_V4L2_SUBDEV)
+	if (!is_media_entity_v4l2_subdev(remote->entity))
 		return NULL;
 
 	if (pad)
@@ -243,7 +242,7 @@ static int isp_video_get_graph_data(struct isp_video *video,
 		if (entity == &video->video.entity)
 			continue;
 
-		if (media_entity_type(entity) != MEDIA_ENT_T_DEVNODE)
+		if (!is_media_entity_v4l2_io(entity))
 			continue;
 
 		__video = to_isp_video(media_entity_to_video_device(entity));
@@ -917,7 +916,7 @@ static int isp_video_check_external_subdevs(struct isp_video *video,
 		return -EINVAL;
 	}
 
-	if (media_entity_type(source) != MEDIA_ENT_T_V4L2_SUBDEV)
+	if (!is_media_entity_v4l2_subdev(source->entity))
 		return 0;
 
 	pipe->external = media_entity_to_v4l2_subdev(source);
diff --git a/drivers/media/platform/s3c-camif/camif-capture.c b/drivers/media/platform/s3c-camif/camif-capture.c
index eae667eab1b9..50f511439e67 100644
--- a/drivers/media/platform/s3c-camif/camif-capture.c
+++ b/drivers/media/platform/s3c-camif/camif-capture.c
@@ -837,7 +837,7 @@ static int camif_pipeline_validate(struct camif_dev *camif)
 
 	/* Retrieve format at the sensor subdev source pad */
 	pad = media_entity_remote_pad(&camif->pads[0]);
-	if (!pad || media_entity_type(pad->entity) != MEDIA_ENT_T_V4L2_SUBDEV)
+	if (!is_media_entity_v4l2_subdev(pad->entity))
 		return -EPIPE;
 
 	src_fmt.pad = pad->index;
diff --git a/drivers/media/platform/vsp1/vsp1_video.c b/drivers/media/platform/vsp1/vsp1_video.c
index 1f94c1a54e00..8d202f42b318 100644
--- a/drivers/media/platform/vsp1/vsp1_video.c
+++ b/drivers/media/platform/vsp1/vsp1_video.c
@@ -160,8 +160,7 @@ vsp1_video_remote_subdev(struct media_pad *local, u32 *pad)
 	struct media_pad *remote;
 
 	remote = media_entity_remote_pad(local);
-	if (remote == NULL ||
-	    media_entity_type(remote->entity) != MEDIA_ENT_T_V4L2_SUBDEV)
+	if (!is_media_entity_v4l2_subdev(remote->entity))
 		return NULL;
 
 	if (pad)
@@ -326,7 +325,7 @@ static int vsp1_pipeline_validate_branch(struct vsp1_pipeline *pipe,
 			return -EPIPE;
 
 		/* We've reached a video node, that shouldn't have happened. */
-		if (media_entity_type(pad->entity) != MEDIA_ENT_T_V4L2_SUBDEV)
+		if (!is_media_entity_v4l2_subdev(pad->entity))
 			return -EPIPE;
 
 		entity = to_vsp1_entity(media_entity_to_v4l2_subdev(pad->entity));
@@ -423,7 +422,7 @@ static int vsp1_pipeline_validate(struct vsp1_pipeline *pipe,
 		struct vsp1_rwpf *rwpf;
 		struct vsp1_entity *e;
 
-		if (media_entity_type(entity) != MEDIA_ENT_T_V4L2_SUBDEV) {
+		if (is_media_entity_v4l2_io(entity)) {
 			pipe->num_video++;
 			continue;
 		}
@@ -692,7 +691,7 @@ void vsp1_pipeline_propagate_alpha(struct vsp1_pipeline *pipe,
 	pad = media_entity_remote_pad(&input->pads[RWPF_PAD_SOURCE]);
 
 	while (pad) {
-		if (media_entity_type(pad->entity) != MEDIA_ENT_T_V4L2_SUBDEV)
+		if (!is_media_entity_v4l2_subdev(pad->entity))
 			break;
 
 		entity = to_vsp1_entity(media_entity_to_v4l2_subdev(pad->entity));
diff --git a/drivers/media/platform/xilinx/xilinx-dma.c b/drivers/media/platform/xilinx/xilinx-dma.c
index 88cd789cdaf7..bbbde73c05b8 100644
--- a/drivers/media/platform/xilinx/xilinx-dma.c
+++ b/drivers/media/platform/xilinx/xilinx-dma.c
@@ -49,8 +49,7 @@ xvip_dma_remote_subdev(struct media_pad *local, u32 *pad)
 	struct media_pad *remote;
 
 	remote = media_entity_remote_pad(local);
-	if (remote == NULL ||
-	    media_entity_type(remote->entity) != MEDIA_ENT_T_V4L2_SUBDEV)
+	if (!is_media_entity_v4l2_subdev(remote->entity))
 		return NULL;
 
 	if (pad)
@@ -113,8 +112,7 @@ static int xvip_pipeline_start_stop(struct xvip_pipeline *pipe, bool start)
 			break;
 
 		pad = media_entity_remote_pad(pad);
-		if (pad == NULL ||
-		    media_entity_type(pad->entity) != MEDIA_ENT_T_V4L2_SUBDEV)
+		if (!is_media_entity_v4l2_subdev(pad->entity))
 			break;
 
 		entity = pad->entity;
diff --git a/drivers/media/v4l2-core/v4l2-subdev.c b/drivers/media/v4l2-core/v4l2-subdev.c
index e6e1115d8215..60da43772de9 100644
--- a/drivers/media/v4l2-core/v4l2-subdev.c
+++ b/drivers/media/v4l2-core/v4l2-subdev.c
@@ -526,7 +526,7 @@ static int
 v4l2_subdev_link_validate_get_format(struct media_pad *pad,
 				     struct v4l2_subdev_format *fmt)
 {
-	if (media_entity_type(pad->entity) == MEDIA_ENT_T_V4L2_SUBDEV) {
+	if (is_media_entity_v4l2_subdev(pad->entity)) {
 		struct v4l2_subdev *sd =
 			media_entity_to_v4l2_subdev(pad->entity);
 
diff --git a/drivers/staging/media/davinci_vpfe/vpfe_video.c b/drivers/staging/media/davinci_vpfe/vpfe_video.c
index 92573fa852a9..16763e0831f2 100644
--- a/drivers/staging/media/davinci_vpfe/vpfe_video.c
+++ b/drivers/staging/media/davinci_vpfe/vpfe_video.c
@@ -148,7 +148,7 @@ static void vpfe_prepare_pipeline(struct vpfe_video_device *video)
 	while ((entity = media_entity_graph_walk_next(&graph))) {
 		if (entity == &video->video_dev.entity)
 			continue;
-		if (media_entity_type(entity) != MEDIA_ENT_T_DEVNODE)
+		if ((!is_media_entity_v4l2_io(remote->entity))
 			continue;
 		far_end = to_vpfe_video(media_entity_to_video_device(entity));
 		if (far_end->type == V4L2_BUF_TYPE_VIDEO_OUTPUT)
@@ -293,7 +293,7 @@ static int vpfe_pipeline_enable(struct vpfe_pipeline *pipe)
 	media_entity_graph_walk_start(&graph, entity);
 	while ((entity = media_entity_graph_walk_next(&graph))) {
 
-		if (media_entity_type(entity) == MEDIA_ENT_T_DEVNODE)
+		if !is_media_entity_v4l2_subdev(entity))
 			continue;
 		subdev = media_entity_to_v4l2_subdev(entity);
 		ret = v4l2_subdev_call(subdev, video, s_stream, 1);
@@ -334,7 +334,7 @@ static int vpfe_pipeline_disable(struct vpfe_pipeline *pipe)
 
 	while ((entity = media_entity_graph_walk_next(&graph))) {
 
-		if (media_entity_type(entity) == MEDIA_ENT_T_DEVNODE)
+		if (!is_media_entity_v4l2_subdev(entity))
 			continue;
 		subdev = media_entity_to_v4l2_subdev(entity);
 		ret = v4l2_subdev_call(subdev, video, s_stream, 0);
diff --git a/drivers/staging/media/omap4iss/iss.c b/drivers/staging/media/omap4iss/iss.c
index 40591963b42b..fc7d329a06bd 100644
--- a/drivers/staging/media/omap4iss/iss.c
+++ b/drivers/staging/media/omap4iss/iss.c
@@ -397,7 +397,7 @@ static int iss_pipeline_pm_use_count(struct media_entity *entity)
 	media_entity_graph_walk_start(&graph, entity);
 
 	while ((entity = media_entity_graph_walk_next(&graph))) {
-		if (media_entity_type(entity) == MEDIA_ENT_T_DEVNODE)
+		if (is_media_entity_v4l2_io(entity))
 			use += entity->use_count;
 	}
 
@@ -419,7 +419,7 @@ static int iss_pipeline_pm_power_one(struct media_entity *entity, int change)
 {
 	struct v4l2_subdev *subdev;
 
-	subdev = media_entity_type(entity) == MEDIA_ENT_T_V4L2_SUBDEV
+	subdev = is_media_entity_v4l2_subdev(entity))
 	       ? media_entity_to_v4l2_subdev(entity) : NULL;
 
 	if (entity->use_count == 0 && change > 0 && subdev != NULL) {
@@ -461,7 +461,7 @@ static int iss_pipeline_pm_power(struct media_entity *entity, int change)
 	media_entity_graph_walk_start(&graph, entity);
 
 	while (!ret && (entity = media_entity_graph_walk_next(&graph)))
-		if (media_entity_type(entity) != MEDIA_ENT_T_DEVNODE)
+		if (is_media_entity_v4l2_subdev(entity))
 			ret = iss_pipeline_pm_power_one(entity, change);
 
 	if (!ret)
@@ -471,7 +471,7 @@ static int iss_pipeline_pm_power(struct media_entity *entity, int change)
 
 	while ((first = media_entity_graph_walk_next(&graph))
 	       && first != entity)
-		if (media_entity_type(first) != MEDIA_ENT_T_DEVNODE)
+		if (is_media_entity_v4l2_subdev(first))
 			iss_pipeline_pm_power_one(first, -change);
 
 	return ret;
@@ -590,8 +590,7 @@ static int iss_pipeline_disable(struct iss_pipeline *pipe,
 			break;
 
 		pad = media_entity_remote_pad(pad);
-		if (pad == NULL ||
-		    media_entity_type(pad->entity) != MEDIA_ENT_T_V4L2_SUBDEV)
+		if !is_media_entity_v4l2_subdev(pad->entity))
 			break;
 
 		entity = pad->entity;
@@ -658,8 +657,7 @@ static int iss_pipeline_enable(struct iss_pipeline *pipe,
 			break;
 
 		pad = media_entity_remote_pad(pad);
-		if (pad == NULL ||
-		    media_entity_type(pad->entity) != MEDIA_ENT_T_V4L2_SUBDEV)
+		if (!is_media_entity_v4l2_subdev(pad->entity))
 			break;
 
 		entity = pad->entity;
diff --git a/drivers/staging/media/omap4iss/iss_video.c b/drivers/staging/media/omap4iss/iss_video.c
index 45a3f2d778fc..9aae72bc24a0 100644
--- a/drivers/staging/media/omap4iss/iss_video.c
+++ b/drivers/staging/media/omap4iss/iss_video.c
@@ -191,8 +191,7 @@ iss_video_remote_subdev(struct iss_video *video, u32 *pad)
 
 	remote = media_entity_remote_pad(&video->pad);
 
-	if (remote == NULL ||
-	    media_entity_type(remote->entity) != MEDIA_ENT_T_V4L2_SUBDEV)
+	if ((!is_media_entity_v4l2_subdev(remote->entity))
 		return NULL;
 
 	if (pad)
@@ -217,7 +216,7 @@ iss_video_far_end(struct iss_video *video)
 		if (entity == &video->video.entity)
 			continue;
 
-		if (media_entity_type(entity) != MEDIA_ENT_T_DEVNODE)
+		if (!is_media_entity_v4l2_io(entity))
 			continue;
 
 		far_end = to_iss_video(media_entity_to_video_device(entity));
-- 
2.4.3



From mchehab at osg.samsung.com  Sun Aug 23 13:17:42 2015
From: mchehab at osg.samsung.com (Mauro Carvalho Chehab)
Date: Sun, 23 Aug 2015 17:17:42 -0300
Subject: [PATCH v7 25/44] [media] replace all occurrences of
 MEDIA_ENT_T_DEVNODE_V4L
In-Reply-To: <cover.1440359643.git.mchehab@osg.samsung.com>
References: <cover.1440359643.git.mchehab@osg.samsung.com>
Message-ID: <23e2f9440a259e1162e15dba7e6261dbc4c521c6.1440359643.git.mchehab@osg.samsung.com>

Now that interfaces and entities are distinct, it makes no sense
of keeping something named as MEDIA_ENT_T_DEVNODE.

This change was done with this script:

	for i in $(git grep -l MEDIA_ENT_T|grep -v uapi/linux/media.h); do sed s,MEDIA_ENT_T_DEVNODE_V4L,MEDIA_ENT_T_V4L2_VIDEO, <$i >a && mv a $i; done

Signed-off-by: Mauro Carvalho Chehab <mchehab at osg.samsung.com>

diff --git a/Documentation/DocBook/media/v4l/media-ioc-enum-entities.xml b/Documentation/DocBook/media/v4l/media-ioc-enum-entities.xml
index 5872f8bbf774..910243d4edb8 100644
--- a/Documentation/DocBook/media/v4l/media-ioc-enum-entities.xml
+++ b/Documentation/DocBook/media/v4l/media-ioc-enum-entities.xml
@@ -183,7 +183,7 @@
 	    <entry>Unknown device node</entry>
 	  </row>
 	  <row>
-	    <entry><constant>MEDIA_ENT_T_DEVNODE_V4L</constant></entry>
+	    <entry><constant>MEDIA_ENT_T_V4L2_VIDEO</constant></entry>
 	    <entry>V4L video, radio or vbi device node</entry>
 	  </row>
 	  <row>
diff --git a/drivers/media/platform/xilinx/xilinx-dma.c b/drivers/media/platform/xilinx/xilinx-dma.c
index 92e8116dc28f..88cd789cdaf7 100644
--- a/drivers/media/platform/xilinx/xilinx-dma.c
+++ b/drivers/media/platform/xilinx/xilinx-dma.c
@@ -193,7 +193,7 @@ static int xvip_pipeline_validate(struct xvip_pipeline *pipe,
 	while ((entity = media_entity_graph_walk_next(&graph))) {
 		struct xvip_dma *dma;
 
-		if (entity->type != MEDIA_ENT_T_DEVNODE_V4L)
+		if (entity->type != MEDIA_ENT_T_V4L2_VIDEO)
 			continue;
 
 		dma = to_xvip_dma(media_entity_to_video_device(entity));
diff --git a/drivers/media/v4l2-core/v4l2-dev.c b/drivers/media/v4l2-core/v4l2-dev.c
index 71a1b93b0790..44b330589787 100644
--- a/drivers/media/v4l2-core/v4l2-dev.c
+++ b/drivers/media/v4l2-core/v4l2-dev.c
@@ -912,7 +912,7 @@ int __video_register_device(struct video_device *vdev, int type, int nr,
 	/* Part 5: Register the entity. */
 	if (vdev->v4l2_dev->mdev &&
 	    vdev->vfl_type != VFL_TYPE_SUBDEV) {
-		vdev->entity.type = MEDIA_ENT_T_DEVNODE_V4L;
+		vdev->entity.type = MEDIA_ENT_T_V4L2_VIDEO;
 		vdev->entity.name = vdev->name;
 		vdev->entity.info.dev.major = VIDEO_MAJOR;
 		vdev->entity.info.dev.minor = vdev->minor;
diff --git a/drivers/media/v4l2-core/v4l2-subdev.c b/drivers/media/v4l2-core/v4l2-subdev.c
index 83615b8fb46a..e6e1115d8215 100644
--- a/drivers/media/v4l2-core/v4l2-subdev.c
+++ b/drivers/media/v4l2-core/v4l2-subdev.c
@@ -535,7 +535,7 @@ v4l2_subdev_link_validate_get_format(struct media_pad *pad,
 		return v4l2_subdev_call(sd, pad, get_fmt, NULL, fmt);
 	}
 
-	WARN(pad->entity->type != MEDIA_ENT_T_DEVNODE_V4L,
+	WARN(pad->entity->type != MEDIA_ENT_T_V4L2_VIDEO,
 	     "Driver bug! Wrong media entity type 0x%08x, entity %s\n",
 	     pad->entity->type, pad->entity->name);
 
-- 
2.4.3



From petr.cvek at tul.cz  Sun Aug 23 13:55:51 2015
From: petr.cvek at tul.cz (Petr Cvek)
Date: Sun, 23 Aug 2015 22:55:51 +0200
Subject: [PATCH v2 16/21] ARM: pxa: magician: Add support for alternative
 LCD backlight
In-Reply-To: <878u95685t.fsf@belgarion.home>
References: <cover.1439843482.git.petr.cvek@tul.cz> <55D25A60.7000900@tul.cz>
 <878u95685t.fsf@belgarion.home>
Message-ID: <55DA3357.6050304@tul.cz>

Dne 20.8.2015 v 22:01 Robert Jarzmik napsal(a):
> Petr Cvek <petr.cvek at tul.cz> writes:
> 
>> Add support for alternative LCD backlight with GPIO (no brightness).
> Here, I don't understand, the commit message is too short.
> 
> Are there 2 brightness controls on magician, or are these 2 different magicians
> (hardware wise), each having a different backlight control ? Or is it there is a
> GPIO to light up the screen and a PWM backlight ?
> 
> I have to understand first.
> 
I have aimed for a configuration, where user can use PWM xor GPIO backlight. As pin mux can set GPIO or PWM (or UART :-D) on PWM pin, you can choose if you spare few kB (as magician has only 64MB RAM and 64MB flash) on GPIO or will have smooth backlight with PWM.

I have tested both (I think I have added the gpio backlight for debugging a regression in pwm_bl).

Only ugly thing is the GPIO definition:

#if IS_ENABLED(CONFIG_PWM_PXA)
	/* PWM 0 - LCD backlight */
	GPIO16_PWM0_OUT,
#else
	/* Ensure static backlight without any driver */
	MFP_CFG_OUT(GPIO16, AF0, DRIVE_LOW),    /* Backlight enabled */
#endif

Hmmm.. I think I can do this better in pwm-backlight init/exit (same way as pxa_ficp). During init the pin mux will switch to Alternate Function (PWM) and during exit it will switch to GPIO (which can be used by gpio-backlight). This will remove ugly ifdef.

Best regards,
Petr



From alexandre.belloni at free-electrons.com  Sun Aug 23 14:43:15 2015
From: alexandre.belloni at free-electrons.com (Alexandre Belloni)
Date: Sun, 23 Aug 2015 23:43:15 +0200
Subject: [GIT PULL] SA1100/PXA RTC for 4.3
In-Reply-To: <CAL_JsqKMN1SEQoJRSPixih4ckDh1pGb4x3T_t+2oWVvW8fqzmg@mail.gmail.com>
References: <CAL_JsqKMN1SEQoJRSPixih4ckDh1pGb4x3T_t+2oWVvW8fqzmg@mail.gmail.com>
Message-ID: <20150823214315.GB13155@piout.net>

Hi,

On 14/08/2015 at 11:09:21 -0500, Rob Herring wrote :
> Alexandre,
> 
> Please pull SA1100/PXA changes for 4.3. This series has had several
> rounds of review over several months without comment from PXA
> maintainers other than Robert.
> 
> Rob
> 
> The following changes since commit 52721d9d3334c1cb1f76219a161084094ec634dc:
> 
>   Linux 4.2-rc3 (2015-07-19 14:45:02 -0700)
> 
> are available in the git repository at:
> 
>   git://git.kernel.org/pub/scm/linux/kernel/git/robh/linux.git
> tags/pxa-rtc-for-4.3
> 
> for you to fetch changes up to e473ff0fe8548941ef67bf956a6b7943f4663ab1:
> 
>   ARM: config: Switch PXA27x platforms to use PXA RTC driver
> (2015-08-14 10:53:44 -0500)
> 

Pulled three days ago, it has been in rtc-next since then but didn't hit
linux-next yet. Thanks!

-- 
Alexandre Belloni, Free Electrons
Embedded Linux, Kernel and Android engineering
http://free-electrons.com


From robherring2 at gmail.com  Sun Aug 23 14:49:42 2015
From: robherring2 at gmail.com (Rob Herring)
Date: Sun, 23 Aug 2015 16:49:42 -0500
Subject: [PATCH v5 2/4] Documentation: arm64/arm: dt bindings for numa.
In-Reply-To: <1439570374-4079-3-git-send-email-gkulkarni@caviumnetworks.com>
References: <1439570374-4079-1-git-send-email-gkulkarni@caviumnetworks.com>
 <1439570374-4079-3-git-send-email-gkulkarni@caviumnetworks.com>
Message-ID: <CAL_JsqJSeehY91D_bbN+XK22aDvWMymeGbHfBmqQX+NotB7ORg@mail.gmail.com>

On Fri, Aug 14, 2015 at 11:39 AM, Ganapatrao Kulkarni
<gkulkarni at caviumnetworks.com> wrote:
> DT bindings for numa map for memory, cores and IOs using
> arm,associativity device node property.
>
> Signed-off-by: Ganapatrao Kulkarni <gkulkarni at caviumnetworks.com>

Given this matches PPC, looks fine to me.

Acked-by: Rob Herring <robh at kernel.org>

> ---
>  Documentation/devicetree/bindings/arm/numa.txt | 212 +++++++++++++++++++++++++
>  1 file changed, 212 insertions(+)
>  create mode 100644 Documentation/devicetree/bindings/arm/numa.txt
>
> diff --git a/Documentation/devicetree/bindings/arm/numa.txt b/Documentation/devicetree/bindings/arm/numa.txt
> new file mode 100644
> index 0000000..dc3ef86
> --- /dev/null
> +++ b/Documentation/devicetree/bindings/arm/numa.txt
> @@ -0,0 +1,212 @@
> +==============================================================================
> +NUMA binding description.
> +==============================================================================
> +
> +==============================================================================
> +1 - Introduction
> +==============================================================================
> +
> +Systems employing a Non Uniform Memory Access (NUMA) architecture contain
> +collections of hardware resources including processors, memory, and I/O buses,
> +that comprise what is commonly known as a NUMA node.
> +Processor accesses to memory within the local NUMA node is generally faster
> +than processor accesses to memory outside of the local NUMA node.
> +DT defines interfaces that allow the platform to convey NUMA node
> +topology information to OS.
> +
> +==============================================================================
> +2 - arm,associativity
> +==============================================================================
> +The mapping is done using arm,associativity device property.
> +this property needs to be present in every device node which needs to to be
> +mapped to numa nodes.
> +
> +arm,associativity property is set of 32-bit integers which defines level of
> +topology and boundary in the system at which a significant difference in
> +performance can be measured between cross-device accesses within
> +a single location and those spanning multiple locations.
> +The first cell always contains the broadest subdivision within the system,
> +while the last cell enumerates the individual devices, such as an SMT thread
> +of a CPU, or a bus bridge within an SoC".
> +
> +ex:
> +       /* board 0, socket 0, cluster 0, core 0  thread 0 */
> +       arm,associativity = <0 0 0 0 0>;
> +
> +==============================================================================
> +3 - arm,associativity-reference-points
> +==============================================================================
> +This property is a set of 32-bit integers, each representing an index into
> +the arm,associativity nodes. The first integer is the most significant
> +NUMA boundary and the following are progressively less significant boundaries.
> +There can be more than one level of NUMA.
> +
> +Ex:
> +       arm,associativity-reference-points = <0 1>;
> +       The board Id(index 0) used first to calculate the associativity (node
> +       distance), then follows the  socket id(index 1).
> +
> +       arm,associativity-reference-points = <1 0>;
> +       The socket Id(index 1) used first to calculate the associativity,
> +       then follows the board id(index 0).
> +
> +       arm,associativity-reference-points = <0>;
> +       Only the board Id(index 0) used to calculate the associativity.
> +
> +       arm,associativity-reference-points = <1>;
> +       Only socket Id(index 1) used to calculate the associativity.
> +
> +==============================================================================
> +4 - Example dts
> +==============================================================================
> +
> +Example: 2 Node system consists of 2 boards and each board having one socket
> +and 8 core in each socket.
> +
> +       arm,associativity-reference-points = <0>;
> +
> +       memory at 00c00000 {
> +               device_type = "memory";
> +               reg = <0x0 0x00c00000 0x0 0x80000000>;
> +               /* board 0, socket 0, no specific core */
> +               arm,associativity = <0 0 0xffff>;
> +       };
> +
> +       memory at 10000000000 {
> +               device_type = "memory";
> +               reg = <0x100 0x00000000 0x0 0x80000000>;
> +               /* board 1, socket 0, no specific core */
> +               arm,associativity = <1 0 0xffff>;
> +       };
> +
> +       cpus {
> +               #address-cells = <2>;
> +               #size-cells = <0>;
> +
> +               cpu at 000 {
> +                       device_type = "cpu";
> +                       compatible =  "arm,armv8";
> +                       reg = <0x0 0x000>;
> +                       enable-method = "psci";
> +                       /* board 0, socket 0, core 0*/
> +                       arm,associativity = <0 0 0>;
> +               };
> +               cpu at 001 {
> +                       device_type = "cpu";
> +                       compatible =  "arm,armv8";
> +                       reg = <0x0 0x001>;
> +                       enable-method = "psci";
> +                       arm,associativity = <0 0 1>;
> +               };
> +               cpu at 002 {
> +                       device_type = "cpu";
> +                       compatible =  "arm,armv8";
> +                       reg = <0x0 0x002>;
> +                       enable-method = "psci";
> +                       arm,associativity = <0 0 2>;
> +               };
> +               cpu at 003 {
> +                       device_type = "cpu";
> +                       compatible =  "arm,armv8";
> +                       reg = <0x0 0x003>;
> +                       enable-method = "psci";
> +                       arm,associativity = <0 0 3>;
> +               };
> +               cpu at 004 {
> +                       device_type = "cpu";
> +                       compatible =  "arm,armv8";
> +                       reg = <0x0 0x004>;
> +                       enable-method = "psci";
> +                       arm,associativity = <0 0 4>;
> +               };
> +               cpu at 005 {
> +                       device_type = "cpu";
> +                       compatible =  "arm,armv8";
> +                       reg = <0x0 0x005>;
> +                       enable-method = "psci";
> +                       arm,associativity = <0 0 5>;
> +               };
> +               cpu at 006 {
> +                       device_type = "cpu";
> +                       compatible =  "arm,armv8";
> +                       reg = <0x0 0x006>;
> +                       enable-method = "psci";
> +                       arm,associativity = <0 0 6>;
> +               };
> +               cpu at 007 {
> +                       device_type = "cpu";
> +                       compatible =  "arm,armv8";
> +                       reg = <0x0 0x007>;
> +                       enable-method = "psci";
> +                       arm,associativity = <0 0 7>;
> +               };
> +               cpu at 008 {
> +                       device_type = "cpu";
> +                       compatible =  "arm,armv8";
> +                       reg = <0x0 0x008>;
> +                       enable-method = "psci";
> +                       /* board 1, socket 0, core 0*/
> +                       arm,associativity = <1 0 0>;
> +               };
> +               cpu at 009 {
> +                       device_type = "cpu";
> +                       compatible =  "arm,armv8";
> +                       reg = <0x0 0x009>;
> +                       enable-method = "psci";
> +                       arm,associativity = <1 0 1>;
> +               };
> +               cpu at 00a {
> +                       device_type = "cpu";
> +                       compatible =  "arm,armv8";
> +                       reg = <0x0 0x00a>;
> +                       enable-method = "psci";
> +                       arm,associativity = <0 0 2>;
> +               };
> +               cpu at 00b {
> +                       device_type = "cpu";
> +                       compatible =  "arm,armv8";
> +                       reg = <0x0 0x00b>;
> +                       enable-method = "psci";
> +                       arm,associativity = <1 0 3>;
> +               };
> +               cpu at 00c {
> +                       device_type = "cpu";
> +                       compatible =  "arm,armv8";
> +                       reg = <0x0 0x00c>;
> +                       enable-method = "psci";
> +                       arm,associativity = <1 0 4>;
> +               };
> +               cpu at 00d {
> +                       device_type = "cpu";
> +                       compatible =  "arm,armv8";
> +                       reg = <0x0 0x00d>;
> +                       enable-method = "psci";
> +                       arm,associativity = <1 0 5>;
> +               };
> +               cpu at 00e {
> +                       device_type = "cpu";
> +                       compatible =  "arm,armv8";
> +                       reg = <0x0 0x00e>;
> +                       enable-method = "psci";
> +                       arm,associativity = <1 0 6>;
> +               };
> +               cpu at 00f {
> +                       device_type = "cpu";
> +                       compatible =  "arm,armv8";
> +                       reg = <0x0 0x00f>;
> +                       enable-method = "psci";
> +                       arm,associativity = <1 0 7>;
> +               };
> +       };
> +
> +       pcie0: pcie0 at 0x8480,00000000 {
> +               compatible = "arm,armv8";
> +               device_type = "pci";
> +               bus-range = <0 255>;
> +               #size-cells = <2>;
> +               #address-cells = <3>;
> +               reg = <0x8480 0x00000000 0 0x10000000>;  /* Configuration space */
> +               ranges = <0x03000000 0x8010 0x00000000 0x8010 0x00000000 0x70 0x00000000>; /* mem ranges */
> +               /* board 0, socket 0, pci bus 0*/
> +               arm,associativity = <0 0 0>;
> +        };
> --
> 1.8.1.4
>
>
> _______________________________________________
> linux-arm-kernel mailing list
> linux-arm-kernel at lists.infradead.org
> http://lists.infradead.org/mailman/listinfo/linux-arm-kernel


From robh at kernel.org  Sun Aug 23 15:01:09 2015
From: robh at kernel.org (Rob Herring)
Date: Sun, 23 Aug 2015 17:01:09 -0500
Subject: [PATCH 1/2] of/fdt: make memblock maximum physical address arch
 configurable
In-Reply-To: <1439890482-20798-2-git-send-email-ard.biesheuvel@linaro.org>
References: <1439890482-20798-1-git-send-email-ard.biesheuvel@linaro.org>
 <1439890482-20798-2-git-send-email-ard.biesheuvel@linaro.org>
Message-ID: <CAL_JsqKRvUfUhF7k8Nf3NbVetiM8_OjPyG81hqgxM=_qe+w0rw@mail.gmail.com>

On Tue, Aug 18, 2015 at 4:34 AM, Ard Biesheuvel
<ard.biesheuvel at linaro.org> wrote:
> When parsing the memory nodes to populate the memblock memory
> table, we check against high and low limits and clip any memory
> that exceeds either one of them.
>
> However, for arm64, the high limit of (phys_addr_t)~0 is not very
> meaningful, since phys_addr_t is 64 bits (i.e., no limit) but there
> may be other constraints that limit the memory ranges that we can
> support.
>
> So rename MAX_PHYS_ADDR to MAX_MEMBLOCK_ADDR (for clarity) and only
> define it if the arch does not supply a definition of its own.
>
> Signed-off-by: Ard Biesheuvel <ard.biesheuvel at linaro.org>

Acked-by: Rob Herring <robh at kernel.org>

> ---
>  drivers/of/fdt.c | 12 +++++++-----
>  1 file changed, 7 insertions(+), 5 deletions(-)
>
> diff --git a/drivers/of/fdt.c b/drivers/of/fdt.c
> index 07496560e5b9..6e82bc42373b 100644
> --- a/drivers/of/fdt.c
> +++ b/drivers/of/fdt.c
> @@ -967,7 +967,9 @@ int __init early_init_dt_scan_chosen(unsigned long node, const char *uname,
>  }
>
>  #ifdef CONFIG_HAVE_MEMBLOCK
> -#define MAX_PHYS_ADDR  ((phys_addr_t)~0)
> +#ifndef MAX_MEMBLOCK_ADDR
> +#define MAX_MEMBLOCK_ADDR      ((phys_addr_t)~0)
> +#endif
>
>  void __init __weak early_init_dt_add_memory_arch(u64 base, u64 size)
>  {
> @@ -984,16 +986,16 @@ void __init __weak early_init_dt_add_memory_arch(u64 base, u64 size)
>         }
>         size &= PAGE_MASK;
>
> -       if (base > MAX_PHYS_ADDR) {
> +       if (base > MAX_MEMBLOCK_ADDR) {
>                 pr_warning("Ignoring memory block 0x%llx - 0x%llx\n",
>                                 base, base + size);
>                 return;
>         }
>
> -       if (base + size - 1 > MAX_PHYS_ADDR) {
> +       if (base + size - 1 > MAX_MEMBLOCK_ADDR) {
>                 pr_warning("Ignoring memory range 0x%llx - 0x%llx\n",
> -                               ((u64)MAX_PHYS_ADDR) + 1, base + size);
> -               size = MAX_PHYS_ADDR - base + 1;
> +                               ((u64)MAX_MEMBLOCK_ADDR) + 1, base + size);
> +               size = MAX_MEMBLOCK_ADDR - base + 1;
>         }
>
>         if (base + size < phys_offset) {
> --
> 1.9.1
>


From hdegoede at redhat.com  Sun Aug 23 15:37:24 2015
From: hdegoede at redhat.com (Hans de Goede)
Date: Mon, 24 Aug 2015 00:37:24 +0200
Subject: [PATCH 3/5] ARM: dts: sun4i: inet97fv2: Enable otg controller
In-Reply-To: <1440369446-22195-1-git-send-email-hdegoede@redhat.com>
References: <1440369446-22195-1-git-send-email-hdegoede@redhat.com>
Message-ID: <1440369446-22195-3-git-send-email-hdegoede@redhat.com>

Enable the otg controller on the inet97fv2 tablet.

Signed-off-by: Hans de Goede <hdegoede at redhat.com>
---
 arch/arm/boot/dts/sun4i-a10-inet97fv2.dts | 34 +++++++++++++++++++++++++++++++
 1 file changed, 34 insertions(+)

diff --git a/arch/arm/boot/dts/sun4i-a10-inet97fv2.dts b/arch/arm/boot/dts/sun4i-a10-inet97fv2.dts
index 69e22bd..309a0da 100644
--- a/arch/arm/boot/dts/sun4i-a10-inet97fv2.dts
+++ b/arch/arm/boot/dts/sun4i-a10-inet97fv2.dts
@@ -92,6 +92,26 @@
 	status = "okay";
 };
 
+&otg_sram {
+	status = "okay";
+};
+
+&pio {
+	usb0_id_detect_pin: usb0_id_detect_pin at 0 {
+		allwinner,pins = "PH4";
+		allwinner,function = "gpio_in";
+		allwinner,drive = <SUN4I_PINCTRL_10_MA>;
+		allwinner,pull = <SUN4I_PINCTRL_PULL_UP>;
+	};
+
+	usb0_vbus_detect_pin: usb0_vbus_detect_pin at 0 {
+		allwinner,pins = "PH5";
+		allwinner,function = "gpio_in";
+		allwinner,drive = <SUN4I_PINCTRL_10_MA>;
+		allwinner,pull = <SUN4I_PINCTRL_PULL_DOWN>;
+	};
+};
+
 &reg_dcdc2 {
 	regulator-always-on;
 	regulator-min-microvolt = <1000000>;
@@ -117,6 +137,10 @@
 	regulator-name = "avcc";
 };
 
+&reg_usb0_vbus {
+	status = "okay";
+};
+
 &reg_usb2_vbus {
 	status = "okay";
 };
@@ -127,7 +151,17 @@
 	status = "okay";
 };
 
+&usb_otg {
+	dr_mode = "otg";
+	status = "okay";
+};
+
 &usbphy {
+	pinctrl-names = "default";
+	pinctrl-0 = <&usb0_id_detect_pin>, <&usb0_vbus_detect_pin>;
+	usb0_id_det-gpio = <&pio 7 4 GPIO_ACTIVE_HIGH>; /* PH4 */
+	usb0_vbus_det-gpio = <&pio 7 5 GPIO_ACTIVE_HIGH>; /* PH5 */
+	usb0_vbus-supply = <&reg_usb0_vbus>;
 	usb2_vbus-supply = <&reg_usb2_vbus>;
 	status = "okay";
 };
-- 
2.4.3



From hdegoede at redhat.com  Sun Aug 23 15:37:22 2015
From: hdegoede at redhat.com (Hans de Goede)
Date: Mon, 24 Aug 2015 00:37:22 +0200
Subject: [PATCH 1/5] ARM: dts: sun4i: inet97fv2: Disable unused usb controllers
Message-ID: <1440369446-22195-1-git-send-email-hdegoede@redhat.com>

The inet97fv2 tablet only has a usb-2 wifi device connected to the second
ehci controller, disable the first ehci controller and both ohci
controllers.

Signed-off-by: Hans de Goede <hdegoede at redhat.com>
---
 arch/arm/boot/dts/sun4i-a10-inet97fv2.dts | 17 -----------------
 1 file changed, 17 deletions(-)

diff --git a/arch/arm/boot/dts/sun4i-a10-inet97fv2.dts b/arch/arm/boot/dts/sun4i-a10-inet97fv2.dts
index 6c927a8..51621c5 100644
--- a/arch/arm/boot/dts/sun4i-a10-inet97fv2.dts
+++ b/arch/arm/boot/dts/sun4i-a10-inet97fv2.dts
@@ -61,10 +61,6 @@
 	};
 };
 
-&ehci0 {
-	status = "okay";
-};
-
 &ehci1 {
 	status = "okay";
 };
@@ -94,18 +90,6 @@
 	status = "okay";
 };
 
-&ohci0 {
-	status = "okay";
-};
-
-&ohci1 {
-	status = "okay";
-};
-
-&reg_usb1_vbus {
-	status = "okay";
-};
-
 &reg_usb2_vbus {
 	status = "okay";
 };
@@ -117,7 +101,6 @@
 };
 
 &usbphy {
-	usb1_vbus-supply = <&reg_usb1_vbus>;
 	usb2_vbus-supply = <&reg_usb2_vbus>;
 	status = "okay";
 };
-- 
2.4.3



From hdegoede at redhat.com  Sun Aug 23 15:37:25 2015
From: hdegoede at redhat.com (Hans de Goede)
Date: Mon, 24 Aug 2015 00:37:25 +0200
Subject: [PATCH 4/5] ARM: dts: sun4i: inet97fv2: Enable support for tablet keys
In-Reply-To: <1440369446-22195-1-git-send-email-hdegoede@redhat.com>
References: <1440369446-22195-1-git-send-email-hdegoede@redhat.com>
Message-ID: <1440369446-22195-4-git-send-email-hdegoede@redhat.com>

Enable support for the tablet keys which are connected via the lradc.

Signed-off-by: Hans de Goede <hdegoede at redhat.com>
---
 arch/arm/boot/dts/sun4i-a10-inet97fv2.dts | 41 +++++++++++++++++++++++++++++++
 1 file changed, 41 insertions(+)

diff --git a/arch/arm/boot/dts/sun4i-a10-inet97fv2.dts b/arch/arm/boot/dts/sun4i-a10-inet97fv2.dts
index 309a0da..909fde9 100644
--- a/arch/arm/boot/dts/sun4i-a10-inet97fv2.dts
+++ b/arch/arm/boot/dts/sun4i-a10-inet97fv2.dts
@@ -47,6 +47,7 @@
 #include "sunxi-common-regulators.dtsi"
 
 #include <dt-bindings/gpio/gpio.h>
+#include <dt-bindings/input/input.h>
 
 / {
 	model = "INet-97F Rev 02";
@@ -82,6 +83,46 @@
 
 #include "axp209.dtsi"
 
+&lradc {
+	vref-supply = <&reg_ldo2>;
+	status = "okay";
+
+	button at 200 {
+		label = "Menu";
+		linux,code = <KEY_MENU>;
+		channel = <0>;
+		voltage = <200000>;
+	};
+
+	button at 600 {
+		label = "Volume Up";
+		linux,code = <KEY_VOLUMEUP>;
+		channel = <0>;
+		voltage = <600000>;
+	};
+
+	button at 800 {
+		label = "Volume Down";
+		linux,code = <KEY_VOLUMEDOWN>;
+		channel = <0>;
+		voltage = <800000>;
+	};
+
+	button at 1000 {
+		label = "Home";
+		linux,code = <KEY_HOMEPAGE>;
+		channel = <0>;
+		voltage = <1000000>;
+	};
+
+	button at 1200 {
+		label = "Esc";
+		linux,code = <KEY_ESC>;
+		channel = <0>;
+		voltage = <1200000>;
+	};
+};
+
 &mmc0 {
 	pinctrl-names = "default";
 	pinctrl-0 = <&mmc0_pins_a>, <&mmc0_cd_pin_reference_design>;
-- 
2.4.3



From hdegoede at redhat.com  Sun Aug 23 15:37:23 2015
From: hdegoede at redhat.com (Hans de Goede)
Date: Mon, 24 Aug 2015 00:37:23 +0200
Subject: [PATCH 2/5] ARM: dts: sun4i: inet97fv2: Add regulator nodes
In-Reply-To: <1440369446-22195-1-git-send-email-hdegoede@redhat.com>
References: <1440369446-22195-1-git-send-email-hdegoede@redhat.com>
Message-ID: <1440369446-22195-2-git-send-email-hdegoede@redhat.com>

Use axp209.dtsi and add regulator nodes for the regulators used on the
inet97fv2 tablet.

Signed-off-by: Hans de Goede <hdegoede at redhat.com>
---
 arch/arm/boot/dts/sun4i-a10-inet97fv2.dts | 35 +++++++++++++++++++++++++++----
 1 file changed, 31 insertions(+), 4 deletions(-)

diff --git a/arch/arm/boot/dts/sun4i-a10-inet97fv2.dts b/arch/arm/boot/dts/sun4i-a10-inet97fv2.dts
index 51621c5..69e22bd 100644
--- a/arch/arm/boot/dts/sun4i-a10-inet97fv2.dts
+++ b/arch/arm/boot/dts/sun4i-a10-inet97fv2.dts
@@ -61,6 +61,10 @@
 	};
 };
 
+&cpu0 {
+	cpu-supply = <&reg_dcdc2>;
+};
+
 &ehci1 {
 	status = "okay";
 };
@@ -71,15 +75,13 @@
 	status = "okay";
 
 	axp209: pmic at 34 {
-		compatible = "x-powers,axp209";
 		reg = <0x34>;
 		interrupts = <0>;
-
-		interrupt-controller;
-		#interrupt-cells = <1>;
 	};
 };
 
+#include "axp209.dtsi"
+
 &mmc0 {
 	pinctrl-names = "default";
 	pinctrl-0 = <&mmc0_pins_a>, <&mmc0_cd_pin_reference_design>;
@@ -90,6 +92,31 @@
 	status = "okay";
 };
 
+&reg_dcdc2 {
+	regulator-always-on;
+	regulator-min-microvolt = <1000000>;
+	regulator-max-microvolt = <1400000>;
+	regulator-name = "vdd-cpu";
+};
+
+&reg_dcdc3 {
+	regulator-always-on;
+	regulator-min-microvolt = <1250000>;
+	regulator-max-microvolt = <1250000>;
+	regulator-name = "vdd-int-dll";
+};
+
+&reg_ldo1 {
+	regulator-name = "vdd-rtc";
+};
+
+&reg_ldo2 {
+	regulator-always-on;
+	regulator-min-microvolt = <3000000>;
+	regulator-max-microvolt = <3000000>;
+	regulator-name = "avcc";
+};
+
 &reg_usb2_vbus {
 	status = "okay";
 };
-- 
2.4.3



From hdegoede at redhat.com  Sun Aug 23 15:37:26 2015
From: hdegoede at redhat.com (Hans de Goede)
Date: Mon, 24 Aug 2015 00:37:26 +0200
Subject: [PATCH 5/5] ARM: dts: sun4i: inet97fv2: Enable i2c1 and i2c2
 controllers
In-Reply-To: <1440369446-22195-1-git-send-email-hdegoede@redhat.com>
References: <1440369446-22195-1-git-send-email-hdegoede@redhat.com>
Message-ID: <1440369446-22195-5-git-send-email-hdegoede@redhat.com>

Enable i2c1 and i2c2 controllers, these are used for the touchscreen resp.
the accelerometer.

Signed-off-by: Hans de Goede <hdegoede at redhat.com>
---
 arch/arm/boot/dts/sun4i-a10-inet97fv2.dts | 12 ++++++++++++
 1 file changed, 12 insertions(+)

diff --git a/arch/arm/boot/dts/sun4i-a10-inet97fv2.dts b/arch/arm/boot/dts/sun4i-a10-inet97fv2.dts
index 909fde9..77c31da 100644
--- a/arch/arm/boot/dts/sun4i-a10-inet97fv2.dts
+++ b/arch/arm/boot/dts/sun4i-a10-inet97fv2.dts
@@ -83,6 +83,18 @@
 
 #include "axp209.dtsi"
 
+&i2c1 {
+	pinctrl-names = "default";
+	pinctrl-0 = <&i2c1_pins_a>;
+	status = "okay";
+};
+
+&i2c2 {
+	pinctrl-names = "default";
+	pinctrl-0 = <&i2c2_pins_a>;
+	status = "okay";
+};
+
 &lradc {
 	vref-supply = <&reg_ldo2>;
 	status = "okay";
-- 
2.4.3



From robherring2 at gmail.com  Sun Aug 23 15:43:03 2015
From: robherring2 at gmail.com (Rob Herring)
Date: Sun, 23 Aug 2015 17:43:03 -0500
Subject: [PATCH v3 1/8] rsb: Add generic Reduced Serial Bus (RSB)
 controller binding documentation
In-Reply-To: <1439958009-14056-2-git-send-email-wens@csie.org>
References: <1439958009-14056-1-git-send-email-wens@csie.org>
 <1439958009-14056-2-git-send-email-wens@csie.org>
Message-ID: <CAL_JsqJA6MEtnF35ThPDgVmEZHyui39-HLsefWPQ1tzzfLAW3w@mail.gmail.com>

On Tue, Aug 18, 2015 at 11:20 PM, Chen-Yu Tsai <wens at csie.org> wrote:
> Reduced Serial Bus is a proprietary 2-line push-pull serial bus
> supporting multiple slave devices.
>
> It was developed by Allwinner, Inc. and used by Allwinner and X-Powers,
> Inc. for their line of PMICs and other peripheral ICs.
>
> Signed-off-by: Chen-Yu Tsai <wens at csie.org>
> ---
>  Documentation/devicetree/bindings/rsb/rsb.txt | 50 +++++++++++++++++++++++++++
>  1 file changed, 50 insertions(+)
>  create mode 100644 Documentation/devicetree/bindings/rsb/rsb.txt
>
> diff --git a/Documentation/devicetree/bindings/rsb/rsb.txt b/Documentation/devicetree/bindings/rsb/rsb.txt
> new file mode 100644
> index 000000000000..0b027948ca9c
> --- /dev/null
> +++ b/Documentation/devicetree/bindings/rsb/rsb.txt
> @@ -0,0 +1,50 @@
> +Reduced Serial Bus (RSB) Controller
> +
> +This document defines a generic set of bindings for use by RSB controllers.
> +A controller is modelled in device tree as a node with zero or more child
> +nodes, each representing a unique slave device on the bus.
> +
> +Required properties:
> +
> + - #address-cells : must be 2
> + - #size-cells : must be 0
> +
> +Optional properties:
> +
> + - clock-frequency : Desired bus clock frequency in Hz. Maximum is 20 MHz.
> +
> +Child nodes:
> +
> +An RSB controller node can contain zero or more child nodes representing
> +slave devices on the bus.  Child 'reg' properties are specified as a
> +runtime address, hardware address pair. The hardware address is hardwired
> +in the device, which can normally be found in the datasheet. The runtime
> +address is set by software. No 2 devices on the same bus shall have the
> +same runtime address.
> +
> +Valid runtime addresses - There are only 15 valid runtime addresses:
> +
> +    0x17, 0x2d, 0x3a, 0x4e, 0x59, 0x63, 0x74, 0x8b,
> +    0x9c, 0xa6, 0xb1, 0xc5, 0xd2, 0xe8, 0xff
> +
> +It is highly recommended that one choose the same runtime addresses as
> +vendor BSPs use so that a) the addresses remain the same across different
> +software systems, and b) addresses of supported and listed slave devices
> +don't conflict with unsupported or not yet listed devices.

I fail to understand why the run-time address belongs in DT or why
alignment to vendor BSP matters? I can see the desire to align DTs if
the vendor OS was dependent on having this information. Having to
access the vendor OS to determine what address to pick does not seem
like the right way to write a DTS. It seems to me that the RSB bus
driver should allocate run-time addresses dynamically.

Rob


From klimov.linux at gmail.com  Sun Aug 23 15:53:59 2015
From: klimov.linux at gmail.com (Alexey Klimov)
Date: Mon, 24 Aug 2015 01:53:59 +0300
Subject: [PATCH] lib: Make _find_next_bit helper function inline
In-Reply-To: <55B93A47.90107@codeaurora.org>
References: <1438110564-19932-1-git-send-email-cburden@codeaurora.org>
 <55B7F2C6.9010000@gmail.com>
 <20150728144537.67d46b5714c99d25f0bb33fb@linux-foundation.org>
 <1438176656.18723.8.camel@ceres> <55B93A47.90107@codeaurora.org>
Message-ID: <CALW4P+LU2iLkT7d=BiaC_=oSJ6K_g152VsVSjfcQGUKx_5q4tQ@mail.gmail.com>

Hi Cassidy,


On Wed, Jul 29, 2015 at 11:40 PM, Cassidy Burden <cburden at codeaurora.org> wrote:
> I changed the test module to now set the entire array to all 0/1s and
> only flip a few bits. There appears to be a performance benefit, but
> it's only 2-3% better (if that). If the main benefit of the original
> patch was to save space then inlining definitely doesn't seem worth the
> small gains in real use cases.
>
> find_next_zero_bit (us)
> old      new     inline
> 14440    17080   17086
> 4779     5181    5069
> 10844    12720   12746
> 9642     11312   11253
> 3858     3818    3668
> 10540    12349   12307
> 12470    14716   14697
> 5403     6002    5942
> 2282     1820    1418
> 13632    16056   15998
> 11048    13019   13030
> 6025     6790    6706
> 13255    15586   15605
> 3038     2744    2539
> 10353    12219   12239
> 10498    12251   12322
> 14767    17452   17454
> 12785    15048   15052
> 1655     1034    691
> 9924     11611   11558
>
> find_next_bit (us)
> old      new     inline
> 8535     9936    9667
> 14666    17372   16880
> 2315     1799    1355
> 6578     9092    8806
> 6548     7558    7274
> 9448     11213   10821
> 3467     3497    3449
> 2719     3079    2911
> 6115     7989    7796
> 13582    16113   15643
> 4643     4946    4766
> 3406     3728    3536
> 7118     9045    8805
> 3174     3011    2701
> 13300    16780   16252
> 14285    16848   16330
> 11583    13669   13207
> 13063    15455   14989
> 12661    14955   14500
> 12068    14166   13790
>
> On 7/29/2015 6:30 AM, Alexey Klimov wrote:
>>
>> I will re-check on another machine. It's really interesting if
>> __always_inline makes things better for aarch64 and worse for x86_64. It
>> will be nice if someone will check it on x86_64 too.
>
>
> Very odd, this may be related to the other compiler optimizations Yuri
> mentioned?

It's better to ask Yury, i hope he can answer some day.

Do you need to re-check this (with more iterations or on another machine(s))?

-- 
Best regards, Klimov Alexey


From olof at lixom.net  Sun Aug 23 16:13:54 2015
From: olof at lixom.net (Olof Johansson)
Date: Sun, 23 Aug 2015 16:13:54 -0700
Subject: [PATCH v5] dtb: Create a common home for cross-architecture dtsi
 files.
In-Reply-To: <CAL_JsqKv2aOEM-U7JNZnaHomA6HFBSFhSLZ-zhp7c20s6gQBaQ@mail.gmail.com>
References: <1438618000-1091-1-git-send-email-ian.campbell@citrix.com>
 <1439287646.9747.212.camel@citrix.com>
 <CAL_JsqKv2aOEM-U7JNZnaHomA6HFBSFhSLZ-zhp7c20s6gQBaQ@mail.gmail.com>
Message-ID: <CAOesGMj46mvbdya1OQnZzL8VrxVwxAV3KoZZRtk3c0CTVx7d5w@mail.gmail.com>

On Fri, Aug 14, 2015 at 2:21 PM, Rob Herring <robherring2 at gmail.com> wrote:
> +arm-soc
>
> On Tue, Aug 11, 2015 at 5:07 AM, Ian Campbell <ian.campbell at citrix.com> wrote:
>> On Mon, 2015-08-03 at 17:06 +0100, Ian Campbell wrote:
>>> Commit 9ccd608070b6 ("arm64: dts: add device tree for ARM SMM-A53x2 on
>>> LogicTile Express 20MG") added a new dts file to arch/arm64 which
>>> included "../../../../arm/boot/dts/vexpress-v2m-rs1.dtsi", i.e. a
>>> .dtsi supplied by arch/arm.
>>>
>>> Unfortunately this causes some issues for the split device tree
>>> repository[0], since things get moved around there. In that context
>>> the new .dts ends up at src/arm64/arm/vexpress-v2f-1xv7-ca53x2.dts
>>> while the include is at src/arm/vexpress-v2m-rs1.dtsi.
>>
>> Hi Grant,
>>
>> Do you think there is any chance of getting this into 4.2-rc$NEXT or shall
>> we wait until 4.3? I'm assuming this should go via the DT tree, but maybe
>> it should go via an ARM tree?
>
> I was assuming this would go thru the arm-soc tree which is why I
> acked it. It is getting a bit late for 4.2 at this point, but I guess
> the standalone tree remains broken for these platforms until this is
> done. Probably not such a big deal in grand scheme of things.

I'm cc:d in the far tail of a thread, so I'll just comment here
instead of further up:

I'm not a fan at all of creating kernel/dts/<arch>/*, at least if
there's expected to be contents in there.

We don't have include/linux/asm-<arch>/ in the common tree either.
Let's not create that for dts.

So, while I'm all for a prefix-based sharing of DTSI files, I don't
want them to go in a common kernel/dts directory.

Besides sharing some snippets between arm and arm64, what else is
expected to need to go into such a shared location today?


-Olof


From robherring2 at gmail.com  Sun Aug 23 16:23:14 2015
From: robherring2 at gmail.com (Rob Herring)
Date: Sun, 23 Aug 2015 18:23:14 -0500
Subject: [PATCH v3 06/14] Documentation: drm/bridge: add document for
 analogix_dp
In-Reply-To: <1439995834-18363-1-git-send-email-ykk@rock-chips.com>
References: <1439995728-18046-1-git-send-email-ykk@rock-chips.com>
 <1439995834-18363-1-git-send-email-ykk@rock-chips.com>
Message-ID: <CAL_JsqLz+8RtBucctUj4euXZ3Ac0DvB52N9ONpAerh5T9BiTJg@mail.gmail.com>

On Wed, Aug 19, 2015 at 9:50 AM, Yakir Yang <ykk at rock-chips.com> wrote:
> Analogix dp driver is split from exynos dp driver, so we just
> make an copy of exynos_dp.txt, and then simplify exynos_dp.txt
>
> Beside update some exynos dtsi file with the latest change
> according to the devicetree binding documents.

You can't just change the exynos bindings and break compatibility. Is
there some agreement with exynos folks to do this?


> Signed-off-by: Yakir Yang <ykk at rock-chips.com>
> ---
> Changes in v3:
> - Take Heiko suggest, add devicetree binding documents.
> - Take Thierry Reding suggest, remove sync pol & colorimetry properies
>   from the new analogix dp driver devicetree binding.
> - Update the exist exynos dtsi file with the latest DP DT properies.
>
> Changes in v2: None
>
>  .../devicetree/bindings/drm/bridge/analogix_dp.txt | 70 ++++++++++++++++++++++
>  .../devicetree/bindings/video/exynos_dp.txt        | 50 ++++++----------
>  arch/arm/boot/dts/exynos5250-arndale.dts           | 10 ++--
>  arch/arm/boot/dts/exynos5250-smdk5250.dts          | 10 ++--
>  arch/arm/boot/dts/exynos5250-snow.dts              | 12 ++--
>  arch/arm/boot/dts/exynos5250-spring.dts            | 12 ++--
>  arch/arm/boot/dts/exynos5420-peach-pit.dts         | 12 ++--
>  arch/arm/boot/dts/exynos5420-smdk5420.dts          | 10 ++--
>  arch/arm/boot/dts/exynos5800-peach-pi.dts          | 12 ++--
>  9 files changed, 119 insertions(+), 79 deletions(-)
>  create mode 100644 Documentation/devicetree/bindings/drm/bridge/analogix_dp.txt
>
> diff --git a/Documentation/devicetree/bindings/drm/bridge/analogix_dp.txt b/Documentation/devicetree/bindings/drm/bridge/analogix_dp.txt
> new file mode 100644
> index 0000000..6127018
> --- /dev/null
> +++ b/Documentation/devicetree/bindings/drm/bridge/analogix_dp.txt
> @@ -0,0 +1,70 @@
> +Analogix Display Port bridge bindings
> +
> +Required properties for dp-controller:
> +       -compatible:
> +               platform specific such as:
> +                * "samsung,exynos5-dp"
> +                * "rockchip,rk3288-dp"
> +       -reg:
> +               physical base address of the controller and length
> +               of memory mapped region.
> +       -interrupts:
> +               interrupt combiner values.
> +       -clocks:
> +               from common clock binding: handle to dp clock.
> +       -clock-names:
> +               from common clock binding: Shall be "dp".
> +       -interrupt-parent:
> +               phandle to Interrupt combiner node.
> +       -phys:
> +               from general PHY binding: the phandle for the PHY device.
> +       -phy-names:
> +               from general PHY binding: Should be "dp".
> +       -analogix,color-space:
> +               input video data format.
> +                       COLOR_RGB = 0, COLOR_YCBCR422 = 1, COLOR_YCBCR444 = 2
> +       -analogix,color-depth:
> +               number of bits per colour component.
> +                       COLOR_6 = 0, COLOR_8 = 1, COLOR_10 = 2, COLOR_12 = 3

This seems pretty generic. Just use 6, 8, 10, or 12 for values. And
drop the vendor prefix.

> +       -analogix,link-rate:
> +               max link rate supported by the eDP controller.
> +                       LINK_RATE_1_62GBPS = 0x6, LINK_RATE_2_70GBPS = 0x0A,
> +                       LINK_RATE_5_40GBPS = 0x14

Same here. I'd rather see something like "link-rate-mbps" and use the
actual rate.

> +       -analogix,lane-count:
> +               max number of lanes supported by the eDP contoller.
> +                       LANE_COUNT1 = 1, LANE_COUNT2 = 2, LANE_COUNT4 = 4

And drop the vendor prefix here.

> +       -port@[X]: SoC specific port nodes with endpoint definitions as defined
> +               in Documentation/devicetree/bindings/media/video-interfaces.txt,
> +               please refer to the SoC specific binding document:
> +               * Documentation/devicetree/bindings/video/exynos_dp.txt
> +               * Documentation/devicetree/bindings/video/analogix_dp-rockchip.txt
> +
> +Optional properties for dp-controller:
> +       -analogix,hpd-gpio:
> +               Hotplug detect GPIO.
> +                       Indicates which GPIO should be used for hotplug
> +                       detection

We should align with "hpd-gpios" used by HDMI connector binding. Or do
we need a DP connector binding that this should be defined in?
Probably so.

The DRM related bindings are such a cluster f*ck with everyone picking
their own way to do things. Just grep hpd in bindings for starters.
That is just the tip.

> +       -video interfaces: Device node can contain video interface port
> +                           nodes according to [1].

Isn't this the same as ports above? How are they optional? 0 ports
would be pretty useless.

> +
> +[1]: Documentation/devicetree/bindings/media/video-interfaces.txt
> +-------------------------------------------------------------------------------
> +
> +Example:
> +
> +       dp-controller {
> +               compatible = "samsung,exynos5-dp";
> +               reg = <0x145b0000 0x10000>;
> +               interrupts = <10 3>;
> +               interrupt-parent = <&combiner>;
> +               clocks = <&clock 342>;
> +               clock-names = "dp";
> +
> +               phys = <&dp_phy>;
> +               phy-names = "dp";
> +
> +               analogix,color-space = <0>;
> +               analogix,color-depth = <1>;
> +               analogix,link-rate = <0x0a>;
> +               analogix,lane-count = <4>;
> +       };
> diff --git a/Documentation/devicetree/bindings/video/exynos_dp.txt b/Documentation/devicetree/bindings/video/exynos_dp.txt
> index 7a3a9cd..177506f 100644
> --- a/Documentation/devicetree/bindings/video/exynos_dp.txt
> +++ b/Documentation/devicetree/bindings/video/exynos_dp.txt
> @@ -31,28 +31,10 @@ Required properties for dp-controller:
>                 from general PHY binding: the phandle for the PHY device.
>         -phy-names:
>                 from general PHY binding: Should be "dp".
> -       -samsung,color-space:
> -               input video data format.
> -                       COLOR_RGB = 0, COLOR_YCBCR422 = 1, COLOR_YCBCR444 = 2
> -       -samsung,dynamic-range:
> -               dynamic range for input video data.
> -                       VESA = 0, CEA = 1
> -       -samsung,ycbcr-coeff:
> -               YCbCr co-efficients for input video.
> -                       COLOR_YCBCR601 = 0, COLOR_YCBCR709 = 1
> -       -samsung,color-depth:
> -               number of bits per colour component.
> -                       COLOR_6 = 0, COLOR_8 = 1, COLOR_10 = 2, COLOR_12 = 3
> -       -samsung,link-rate:
> -               link rate supported by the panel.
> -                       LINK_RATE_1_62GBPS = 0x6, LINK_RATE_2_70GBPS = 0x0A
> -       -samsung,lane-count:
> -               number of lanes supported by the panel.
> -                       LANE_COUNT1 = 1, LANE_COUNT2 = 2, LANE_COUNT4 = 4
> -       - display-timings: timings for the connected panel as described by
> -               Documentation/devicetree/bindings/video/display-timing.txt
>
>  Optional properties for dp-controller:
> +       - display-timings: timings for the connected panel as described by
> +               Documentation/devicetree/bindings/video/display-timing.txt
>         -interlaced:
>                 interlace scan mode.
>                         Progressive if defined, Interlaced if not defined
> @@ -62,14 +44,18 @@ Optional properties for dp-controller:
>         -hsync-active-high:
>                 HSYNC polarity configuration.
>                         High if defined, Low if not defined
> -       -samsung,hpd-gpio:
> -               Hotplug detect GPIO.
> -                       Indicates which GPIO should be used for hotplug
> -                       detection
> -       -video interfaces: Device node can contain video interface port
> -                           nodes according to [1].
>
> -[1]: Documentation/devicetree/bindings/media/video-interfaces.txt
> +For the below properties, please refer to Analogix DP binding document:
> + * Documentation/devicetree/bindings/drm/bridge/analogix_dp.txt
> +       -phys (required)
> +       -phy-names (required)
> +       -analogix,color-space (required)
> +       -analogix,color-depth (required)
> +       -analogix,link-rate (required)
> +       -analogix,lane-count (required)
> +       -analogix,hpd-gpio (optional)
> +       -video interfaces (optional)
> +-------------------------------------------------------------------------------
>
>  Example:
>
> @@ -88,12 +74,10 @@ SOC specific portion:
>
>  Board Specific portion:
>         dp-controller {
> -               samsung,color-space = <0>;
> -               samsung,dynamic-range = <0>;
> -               samsung,ycbcr-coeff = <0>;
> -               samsung,color-depth = <1>;
> -               samsung,link-rate = <0x0a>;
> -               samsung,lane-count = <4>;
> +               analogix,color-space = <0>;
> +               analogix,color-depth = <1>;
> +               analogix,link-rate = <0x0a>;
> +               analogix,lane-count = <4>;
>
>                 display-timings {
>                         native-mode = <&lcd_timing>;
> diff --git a/arch/arm/boot/dts/exynos5250-arndale.dts b/arch/arm/boot/dts/exynos5250-arndale.dts
> index 7e728a1..e48798d 100644
> --- a/arch/arm/boot/dts/exynos5250-arndale.dts
> +++ b/arch/arm/boot/dts/exynos5250-arndale.dts
> @@ -119,12 +119,10 @@
>
>  &dp {
>         status = "okay";
> -       samsung,color-space = <0>;
> -       samsung,dynamic-range = <0>;
> -       samsung,ycbcr-coeff = <0>;
> -       samsung,color-depth = <1>;
> -       samsung,link-rate = <0x0a>;
> -       samsung,lane-count = <4>;
> +       analogix,color-space = <0>;
> +       analogix,color-depth = <1>;
> +       analogix,link-rate = <0x0a>;
> +       analogix,lane-count = <4>;
>  };
>
>  &fimd {
> diff --git a/arch/arm/boot/dts/exynos5250-smdk5250.dts b/arch/arm/boot/dts/exynos5250-smdk5250.dts
> index 4fe186d..b8c6b8b 100644
> --- a/arch/arm/boot/dts/exynos5250-smdk5250.dts
> +++ b/arch/arm/boot/dts/exynos5250-smdk5250.dts
> @@ -75,12 +75,10 @@
>  };
>
>  &dp {
> -       samsung,color-space = <0>;
> -       samsung,dynamic-range = <0>;
> -       samsung,ycbcr-coeff = <0>;
> -       samsung,color-depth = <1>;
> -       samsung,link-rate = <0x0a>;
> -       samsung,lane-count = <4>;
> +       analogix,color-space = <0>;
> +       analogix,color-depth = <1>;
> +       analogix,link-rate = <0x0a>;
> +       analogix,lane-count = <4>;
>
>         pinctrl-names = "default";
>         pinctrl-0 = <&dp_hpd>;
> diff --git a/arch/arm/boot/dts/exynos5250-snow.dts b/arch/arm/boot/dts/exynos5250-snow.dts
> index b7f4122..9ce2b89 100644
> --- a/arch/arm/boot/dts/exynos5250-snow.dts
> +++ b/arch/arm/boot/dts/exynos5250-snow.dts
> @@ -239,13 +239,11 @@
>         status = "okay";
>         pinctrl-names = "default";
>         pinctrl-0 = <&dp_hpd>;
> -       samsung,color-space = <0>;
> -       samsung,dynamic-range = <0>;
> -       samsung,ycbcr-coeff = <0>;
> -       samsung,color-depth = <1>;
> -       samsung,link-rate = <0x0a>;
> -       samsung,lane-count = <2>;
> -       samsung,hpd-gpio = <&gpx0 7 GPIO_ACTIVE_HIGH>;
> +       analogix,color-space = <0>;
> +       analogix,color-depth = <1>;
> +       analogix,link-rate = <0x0a>;
> +       analogix,lane-count = <2>;
> +       analogix,hpd-gpio = <&gpx0 7 GPIO_ACTIVE_HIGH>;
>
>         ports {
>                 port at 0 {
> diff --git a/arch/arm/boot/dts/exynos5250-spring.dts b/arch/arm/boot/dts/exynos5250-spring.dts
> index d03f9b8..9288ae6 100644
> --- a/arch/arm/boot/dts/exynos5250-spring.dts
> +++ b/arch/arm/boot/dts/exynos5250-spring.dts
> @@ -69,13 +69,11 @@
>         status = "okay";
>         pinctrl-names = "default";
>         pinctrl-0 = <&dp_hpd_gpio>;
> -       samsung,color-space = <0>;
> -       samsung,dynamic-range = <0>;
> -       samsung,ycbcr-coeff = <0>;
> -       samsung,color-depth = <1>;
> -       samsung,link-rate = <0x0a>;
> -       samsung,lane-count = <1>;
> -       samsung,hpd-gpio = <&gpc3 0 GPIO_ACTIVE_HIGH>;
> +       analogix,color-space = <0>;
> +       analogix,color-depth = <1>;
> +       analogix,link-rate = <0x0a>;
> +       analogix,lane-count = <1>;
> +       analogix,hpd-gpio = <&gpc3 0 GPIO_ACTIVE_HIGH>;
>  };
>
>  &ehci {
> diff --git a/arch/arm/boot/dts/exynos5420-peach-pit.dts b/arch/arm/boot/dts/exynos5420-peach-pit.dts
> index 8f4d76c..695a380 100644
> --- a/arch/arm/boot/dts/exynos5420-peach-pit.dts
> +++ b/arch/arm/boot/dts/exynos5420-peach-pit.dts
> @@ -147,13 +147,11 @@
>         status = "okay";
>         pinctrl-names = "default";
>         pinctrl-0 = <&dp_hpd_gpio>;
> -       samsung,color-space = <0>;
> -       samsung,dynamic-range = <0>;
> -       samsung,ycbcr-coeff = <0>;
> -       samsung,color-depth = <1>;
> -       samsung,link-rate = <0x06>;
> -       samsung,lane-count = <2>;
> -       samsung,hpd-gpio = <&gpx2 6 0>;
> +       analogix,color-space = <0>;
> +       analogix,color-depth = <1>;
> +       analogix,link-rate = <0x06>;
> +       analogix,lane-count = <2>;
> +       analogix,hpd-gpio = <&gpx2 6 0>;
>
>         ports {
>                 port at 0 {
> diff --git a/arch/arm/boot/dts/exynos5420-smdk5420.dts b/arch/arm/boot/dts/exynos5420-smdk5420.dts
> index 98871f9..fd46714 100644
> --- a/arch/arm/boot/dts/exynos5420-smdk5420.dts
> +++ b/arch/arm/boot/dts/exynos5420-smdk5420.dts
> @@ -91,12 +91,10 @@
>  &dp {
>         pinctrl-names = "default";
>         pinctrl-0 = <&dp_hpd>;
> -       samsung,color-space = <0>;
> -       samsung,dynamic-range = <0>;
> -       samsung,ycbcr-coeff = <0>;
> -       samsung,color-depth = <1>;
> -       samsung,link-rate = <0x0a>;
> -       samsung,lane-count = <4>;
> +       analogix,color-space = <0>;
> +       analogix,color-depth = <1>;
> +       analogix,link-rate = <0x0a>;
> +       analogix,lane-count = <4>;
>         status = "okay";
>  };
>
> diff --git a/arch/arm/boot/dts/exynos5800-peach-pi.dts b/arch/arm/boot/dts/exynos5800-peach-pi.dts
> index 7d5b386..54b4c63 100644
> --- a/arch/arm/boot/dts/exynos5800-peach-pi.dts
> +++ b/arch/arm/boot/dts/exynos5800-peach-pi.dts
> @@ -141,13 +141,11 @@
>         status = "okay";
>         pinctrl-names = "default";
>         pinctrl-0 = <&dp_hpd_gpio>;
> -       samsung,color-space = <0>;
> -       samsung,dynamic-range = <0>;
> -       samsung,ycbcr-coeff = <0>;
> -       samsung,color-depth = <1>;
> -       samsung,link-rate = <0x0a>;
> -       samsung,lane-count = <2>;
> -       samsung,hpd-gpio = <&gpx2 6 0>;
> +       analogix,color-space = <0>;
> +       analogix,color-depth = <1>;
> +       analogix,link-rate = <0x0a>;
> +       analogix,lane-count = <2>;
> +       analogix,hpd-gpio = <&gpx2 6 0>;
>         panel = <&panel>;
>  };
>
> --
> 1.9.1
>
>
>
> _______________________________________________
> linux-arm-kernel mailing list
> linux-arm-kernel at lists.infradead.org
> http://lists.infradead.org/mailman/listinfo/linux-arm-kernel


From robherring2 at gmail.com  Sun Aug 23 16:42:23 2015
From: robherring2 at gmail.com (Rob Herring)
Date: Sun, 23 Aug 2015 18:42:23 -0500
Subject: [PATCH v5] dtb: Create a common home for cross-architecture dtsi
 files.
In-Reply-To: <CAOesGMj46mvbdya1OQnZzL8VrxVwxAV3KoZZRtk3c0CTVx7d5w@mail.gmail.com>
References: <1438618000-1091-1-git-send-email-ian.campbell@citrix.com>
 <1439287646.9747.212.camel@citrix.com>
 <CAL_JsqKv2aOEM-U7JNZnaHomA6HFBSFhSLZ-zhp7c20s6gQBaQ@mail.gmail.com>
 <CAOesGMj46mvbdya1OQnZzL8VrxVwxAV3KoZZRtk3c0CTVx7d5w@mail.gmail.com>
Message-ID: <CAL_Jsq+tUmRfvKE6vf+za6TsG_fhMWn5M2DDDLcCfkDt=KJGVg@mail.gmail.com>

On Sun, Aug 23, 2015 at 6:13 PM, Olof Johansson <olof at lixom.net> wrote:
> On Fri, Aug 14, 2015 at 2:21 PM, Rob Herring <robherring2 at gmail.com> wrote:
>> +arm-soc
>>
>> On Tue, Aug 11, 2015 at 5:07 AM, Ian Campbell <ian.campbell at citrix.com> wrote:
>>> On Mon, 2015-08-03 at 17:06 +0100, Ian Campbell wrote:
>>>> Commit 9ccd608070b6 ("arm64: dts: add device tree for ARM SMM-A53x2 on
>>>> LogicTile Express 20MG") added a new dts file to arch/arm64 which
>>>> included "../../../../arm/boot/dts/vexpress-v2m-rs1.dtsi", i.e. a
>>>> .dtsi supplied by arch/arm.
>>>>
>>>> Unfortunately this causes some issues for the split device tree
>>>> repository[0], since things get moved around there. In that context
>>>> the new .dts ends up at src/arm64/arm/vexpress-v2f-1xv7-ca53x2.dts
>>>> while the include is at src/arm/vexpress-v2m-rs1.dtsi.
>>>
>>> Hi Grant,
>>>
>>> Do you think there is any chance of getting this into 4.2-rc$NEXT or shall
>>> we wait until 4.3? I'm assuming this should go via the DT tree, but maybe
>>> it should go via an ARM tree?
>>
>> I was assuming this would go thru the arm-soc tree which is why I
>> acked it. It is getting a bit late for 4.2 at this point, but I guess
>> the standalone tree remains broken for these platforms until this is
>> done. Probably not such a big deal in grand scheme of things.
>
> I'm cc:d in the far tail of a thread, so I'll just comment here
> instead of further up:
>
> I'm not a fan at all of creating kernel/dts/<arch>/*, at least if
> there's expected to be contents in there.
>
> We don't have include/linux/asm-<arch>/ in the common tree either.
> Let's not create that for dts.

I'd really like to move ALL dts files from arch/*. There's nothing
really tied to the architecture. They may happen to use some bindings
that only apply to an architecture, but fundamentally they don't
depend on the arch. Also, I'd like to be able to do "make all-dtbs"
and build every dtb in the tree.

That said, I'm not crazy enough to propose this re-org in the kernel
tree, but would like to do that if/when we moved dts files out of the
kernel.

> So, while I'm all for a prefix-based sharing of DTSI files, I don't
> want them to go in a common kernel/dts directory.
>
> Besides sharing some snippets between arm and arm64, what else is
> expected to need to go into such a shared location today?

Overlays. You easily have the same sharing of common boards. There are
also usecases of overlays on architectures that don't generally use DT
(x86).

We could also see sharing between PPC and ARM on FSL networking parts,
but I've not heard if they actually have that problem.

Rob


From olof at lixom.net  Sun Aug 23 16:52:32 2015
From: olof at lixom.net (Olof Johansson)
Date: Sun, 23 Aug 2015 16:52:32 -0700
Subject: [PATCH v5] dtb: Create a common home for cross-architecture dtsi
 files.
In-Reply-To: <CAL_Jsq+tUmRfvKE6vf+za6TsG_fhMWn5M2DDDLcCfkDt=KJGVg@mail.gmail.com>
References: <1438618000-1091-1-git-send-email-ian.campbell@citrix.com>
 <1439287646.9747.212.camel@citrix.com>
 <CAL_JsqKv2aOEM-U7JNZnaHomA6HFBSFhSLZ-zhp7c20s6gQBaQ@mail.gmail.com>
 <CAOesGMj46mvbdya1OQnZzL8VrxVwxAV3KoZZRtk3c0CTVx7d5w@mail.gmail.com>
 <CAL_Jsq+tUmRfvKE6vf+za6TsG_fhMWn5M2DDDLcCfkDt=KJGVg@mail.gmail.com>
Message-ID: <CAOesGMigmaEviCDBAncomkq+uowr18B5FTOmOyBHsNz4p6F6Dw@mail.gmail.com>

On Sun, Aug 23, 2015 at 4:42 PM, Rob Herring <robherring2 at gmail.com> wrote:
> On Sun, Aug 23, 2015 at 6:13 PM, Olof Johansson <olof at lixom.net> wrote:
>> On Fri, Aug 14, 2015 at 2:21 PM, Rob Herring <robherring2 at gmail.com> wrote:
>>> +arm-soc
>>>
>>> On Tue, Aug 11, 2015 at 5:07 AM, Ian Campbell <ian.campbell at citrix.com> wrote:
>>>> On Mon, 2015-08-03 at 17:06 +0100, Ian Campbell wrote:
>>>>> Commit 9ccd608070b6 ("arm64: dts: add device tree for ARM SMM-A53x2 on
>>>>> LogicTile Express 20MG") added a new dts file to arch/arm64 which
>>>>> included "../../../../arm/boot/dts/vexpress-v2m-rs1.dtsi", i.e. a
>>>>> .dtsi supplied by arch/arm.
>>>>>
>>>>> Unfortunately this causes some issues for the split device tree
>>>>> repository[0], since things get moved around there. In that context
>>>>> the new .dts ends up at src/arm64/arm/vexpress-v2f-1xv7-ca53x2.dts
>>>>> while the include is at src/arm/vexpress-v2m-rs1.dtsi.
>>>>
>>>> Hi Grant,
>>>>
>>>> Do you think there is any chance of getting this into 4.2-rc$NEXT or shall
>>>> we wait until 4.3? I'm assuming this should go via the DT tree, but maybe
>>>> it should go via an ARM tree?
>>>
>>> I was assuming this would go thru the arm-soc tree which is why I
>>> acked it. It is getting a bit late for 4.2 at this point, but I guess
>>> the standalone tree remains broken for these platforms until this is
>>> done. Probably not such a big deal in grand scheme of things.
>>
>> I'm cc:d in the far tail of a thread, so I'll just comment here
>> instead of further up:
>>
>> I'm not a fan at all of creating kernel/dts/<arch>/*, at least if
>> there's expected to be contents in there.
>>
>> We don't have include/linux/asm-<arch>/ in the common tree either.
>> Let's not create that for dts.
>
> I'd really like to move ALL dts files from arch/*. There's nothing
> really tied to the architecture. They may happen to use some bindings
> that only apply to an architecture, but fundamentally they don't
> depend on the arch. Also, I'd like to be able to do "make all-dtbs"
> and build every dtb in the tree.

The main benefit of keeping it per architecture and platform is that
it partitions the maintainer and review space a bit.

Right now it's not possible to do even per-arch "all-dtbs" since only
the currently configured platforms will get their dtbs compiled.

> That said, I'm not crazy enough to propose this re-org in the kernel
> tree, but would like to do that if/when we moved dts files out of the
> kernel.

I believe this is currently still quite firmly in the "if" stage. :(

>> So, while I'm all for a prefix-based sharing of DTSI files, I don't
>> want them to go in a common kernel/dts directory.
>>
>> Besides sharing some snippets between arm and arm64, what else is
>> expected to need to go into such a shared location today?
>
> Overlays. You easily have the same sharing of common boards. There are
> also usecases of overlays on architectures that don't generally use DT
> (x86).

Ok, overlays might make sense if they can be made to work generically
enough and not be tied to expectations of the base board platform.

Still, even then I don't see dts as a core kernel feature (kernel/*),
lib/* might make more sense. And I don't want to see things like
vexpress stuff in there.

> We could also see sharing between PPC and ARM on FSL networking parts,
> but I've not heard if they actually have that problem.

Yeah, there could potentially be some sharing between MIPS and
ARM{,64} too, but I don't know if we'll actually see it done.


-Olof


From sfr at canb.auug.org.au  Sun Aug 23 16:55:48 2015
From: sfr at canb.auug.org.au (Stephen Rothwell)
Date: Mon, 24 Aug 2015 09:55:48 +1000
Subject: linux-next: manual merge of the arm-soc tree with Linus' tree
Message-ID: <20150824095548.6bb25c3a@canb.auug.org.au>

Hi all,

Today's linux-next merge of the arm-soc tree got a conflict in:

  drivers/cpufreq/exynos-cpufreq.c

between commit:

  62c3f2fddd43 ("cpufreq: exynos: Fix for memory leak in case SoC name does not match")

from Linus' tree and commits:

  ac4c90c82e4d ("cpufreq: exynos: remove exynos5250 specific cpufreq driver support")
  966f2a71a92d ("cpufreq: exynos: remove Exynos4x12 specific cpufreq driver support")

from the arm-soc tree.

I fixed it up (the latter commit removed the file, so I did that) and
can carry the fix as necessary (no action is required).

-- 
Cheers,
Stephen Rothwell                    sfr at canb.auug.org.au


From k.kozlowski at samsung.com  Sun Aug 23 17:43:32 2015
From: k.kozlowski at samsung.com (Krzysztof Kozlowski)
Date: Mon, 24 Aug 2015 09:43:32 +0900
Subject: [PATCH v3 06/14] Documentation: drm/bridge: add document for
 analogix_dp
In-Reply-To: <CAL_JsqLz+8RtBucctUj4euXZ3Ac0DvB52N9ONpAerh5T9BiTJg@mail.gmail.com>
References: <1439995728-18046-1-git-send-email-ykk@rock-chips.com>
 <1439995834-18363-1-git-send-email-ykk@rock-chips.com>
 <CAL_JsqLz+8RtBucctUj4euXZ3Ac0DvB52N9ONpAerh5T9BiTJg@mail.gmail.com>
Message-ID: <CAJKOXPeEm8exg_UG0tDnaEGO40ejBKZ-ok=bKbVrwYvXnDaMdg@mail.gmail.com>

2015-08-24 8:23 GMT+09:00 Rob Herring <robherring2 at gmail.com>:
> On Wed, Aug 19, 2015 at 9:50 AM, Yakir Yang <ykk at rock-chips.com> wrote:
>> Analogix dp driver is split from exynos dp driver, so we just
>> make an copy of exynos_dp.txt, and then simplify exynos_dp.txt
>>
>> Beside update some exynos dtsi file with the latest change
>> according to the devicetree binding documents.
>
> You can't just change the exynos bindings and break compatibility. Is
> there some agreement with exynos folks to do this?

No, there is no agreement. This wasn't even sent to Exynos maintainers.
Additionally the patchset did not look interesting to me because of
misleading subject - Documentation instead of "ARM: dts:".

Yakir, please:
1. Provide backward compatibility. Mark old properties as deprecated
but still support them.
2. Separate all DTS changes to a separate patch, unless bisectability
would be hurt. Anyway you should prepare it in a such way that
separation would be possible without breaking bisectability.
3. Use proper subject for the patch changing DTS. This is not
documentation change!
4. Please use script get_maintainers to obtain list of valid
maintainers and CC-them with at least cover letter and patches
requiring their attention.

Best regards,
Krzysztof


>
>
>> Signed-off-by: Yakir Yang <ykk at rock-chips.com>
>> ---
>> Changes in v3:
>> - Take Heiko suggest, add devicetree binding documents.
>> - Take Thierry Reding suggest, remove sync pol & colorimetry properies
>>   from the new analogix dp driver devicetree binding.
>> - Update the exist exynos dtsi file with the latest DP DT properies.
>>
>> Changes in v2: None
>>
>>  .../devicetree/bindings/drm/bridge/analogix_dp.txt | 70 ++++++++++++++++++++++
>>  .../devicetree/bindings/video/exynos_dp.txt        | 50 ++++++----------
>>  arch/arm/boot/dts/exynos5250-arndale.dts           | 10 ++--
>>  arch/arm/boot/dts/exynos5250-smdk5250.dts          | 10 ++--
>>  arch/arm/boot/dts/exynos5250-snow.dts              | 12 ++--
>>  arch/arm/boot/dts/exynos5250-spring.dts            | 12 ++--
>>  arch/arm/boot/dts/exynos5420-peach-pit.dts         | 12 ++--
>>  arch/arm/boot/dts/exynos5420-smdk5420.dts          | 10 ++--
>>  arch/arm/boot/dts/exynos5800-peach-pi.dts          | 12 ++--
>>  9 files changed, 119 insertions(+), 79 deletions(-)
>>  create mode 100644 Documentation/devicetree/bindings/drm/bridge/analogix_dp.txt
>>
>> diff --git a/Documentation/devicetree/bindings/drm/bridge/analogix_dp.txt b/Documentation/devicetree/bindings/drm/bridge/analogix_dp.txt
>> new file mode 100644
>> index 0000000..6127018
>> --- /dev/null
>> +++ b/Documentation/devicetree/bindings/drm/bridge/analogix_dp.txt
>> @@ -0,0 +1,70 @@
>> +Analogix Display Port bridge bindings
>> +
>> +Required properties for dp-controller:
>> +       -compatible:
>> +               platform specific such as:
>> +                * "samsung,exynos5-dp"
>> +                * "rockchip,rk3288-dp"
>> +       -reg:
>> +               physical base address of the controller and length
>> +               of memory mapped region.
>> +       -interrupts:
>> +               interrupt combiner values.
>> +       -clocks:
>> +               from common clock binding: handle to dp clock.
>> +       -clock-names:
>> +               from common clock binding: Shall be "dp".
>> +       -interrupt-parent:
>> +               phandle to Interrupt combiner node.
>> +       -phys:
>> +               from general PHY binding: the phandle for the PHY device.
>> +       -phy-names:
>> +               from general PHY binding: Should be "dp".
>> +       -analogix,color-space:
>> +               input video data format.
>> +                       COLOR_RGB = 0, COLOR_YCBCR422 = 1, COLOR_YCBCR444 = 2
>> +       -analogix,color-depth:
>> +               number of bits per colour component.
>> +                       COLOR_6 = 0, COLOR_8 = 1, COLOR_10 = 2, COLOR_12 = 3
>
> This seems pretty generic. Just use 6, 8, 10, or 12 for values. And
> drop the vendor prefix.
>
>> +       -analogix,link-rate:
>> +               max link rate supported by the eDP controller.
>> +                       LINK_RATE_1_62GBPS = 0x6, LINK_RATE_2_70GBPS = 0x0A,
>> +                       LINK_RATE_5_40GBPS = 0x14
>
> Same here. I'd rather see something like "link-rate-mbps" and use the
> actual rate.
>
>> +       -analogix,lane-count:
>> +               max number of lanes supported by the eDP contoller.
>> +                       LANE_COUNT1 = 1, LANE_COUNT2 = 2, LANE_COUNT4 = 4
>
> And drop the vendor prefix here.
>
>> +       -port@[X]: SoC specific port nodes with endpoint definitions as defined
>> +               in Documentation/devicetree/bindings/media/video-interfaces.txt,
>> +               please refer to the SoC specific binding document:
>> +               * Documentation/devicetree/bindings/video/exynos_dp.txt
>> +               * Documentation/devicetree/bindings/video/analogix_dp-rockchip.txt
>> +
>> +Optional properties for dp-controller:
>> +       -analogix,hpd-gpio:
>> +               Hotplug detect GPIO.
>> +                       Indicates which GPIO should be used for hotplug
>> +                       detection
>
> We should align with "hpd-gpios" used by HDMI connector binding. Or do
> we need a DP connector binding that this should be defined in?
> Probably so.
>
> The DRM related bindings are such a cluster f*ck with everyone picking
> their own way to do things. Just grep hpd in bindings for starters.
> That is just the tip.
>
>> +       -video interfaces: Device node can contain video interface port
>> +                           nodes according to [1].
>
> Isn't this the same as ports above? How are they optional? 0 ports
> would be pretty useless.
>
>> +
>> +[1]: Documentation/devicetree/bindings/media/video-interfaces.txt
>> +-------------------------------------------------------------------------------
>> +
>> +Example:
>> +
>> +       dp-controller {
>> +               compatible = "samsung,exynos5-dp";
>> +               reg = <0x145b0000 0x10000>;
>> +               interrupts = <10 3>;
>> +               interrupt-parent = <&combiner>;
>> +               clocks = <&clock 342>;
>> +               clock-names = "dp";
>> +
>> +               phys = <&dp_phy>;
>> +               phy-names = "dp";
>> +
>> +               analogix,color-space = <0>;
>> +               analogix,color-depth = <1>;
>> +               analogix,link-rate = <0x0a>;
>> +               analogix,lane-count = <4>;
>> +       };
>> diff --git a/Documentation/devicetree/bindings/video/exynos_dp.txt b/Documentation/devicetree/bindings/video/exynos_dp.txt
>> index 7a3a9cd..177506f 100644
>> --- a/Documentation/devicetree/bindings/video/exynos_dp.txt
>> +++ b/Documentation/devicetree/bindings/video/exynos_dp.txt
>> @@ -31,28 +31,10 @@ Required properties for dp-controller:
>>                 from general PHY binding: the phandle for the PHY device.
>>         -phy-names:
>>                 from general PHY binding: Should be "dp".
>> -       -samsung,color-space:
>> -               input video data format.
>> -                       COLOR_RGB = 0, COLOR_YCBCR422 = 1, COLOR_YCBCR444 = 2
>> -       -samsung,dynamic-range:
>> -               dynamic range for input video data.
>> -                       VESA = 0, CEA = 1
>> -       -samsung,ycbcr-coeff:
>> -               YCbCr co-efficients for input video.
>> -                       COLOR_YCBCR601 = 0, COLOR_YCBCR709 = 1
>> -       -samsung,color-depth:
>> -               number of bits per colour component.
>> -                       COLOR_6 = 0, COLOR_8 = 1, COLOR_10 = 2, COLOR_12 = 3
>> -       -samsung,link-rate:
>> -               link rate supported by the panel.
>> -                       LINK_RATE_1_62GBPS = 0x6, LINK_RATE_2_70GBPS = 0x0A
>> -       -samsung,lane-count:
>> -               number of lanes supported by the panel.
>> -                       LANE_COUNT1 = 1, LANE_COUNT2 = 2, LANE_COUNT4 = 4
>> -       - display-timings: timings for the connected panel as described by
>> -               Documentation/devicetree/bindings/video/display-timing.txt
>>
>>  Optional properties for dp-controller:
>> +       - display-timings: timings for the connected panel as described by
>> +               Documentation/devicetree/bindings/video/display-timing.txt
>>         -interlaced:
>>                 interlace scan mode.
>>                         Progressive if defined, Interlaced if not defined
>> @@ -62,14 +44,18 @@ Optional properties for dp-controller:
>>         -hsync-active-high:
>>                 HSYNC polarity configuration.
>>                         High if defined, Low if not defined
>> -       -samsung,hpd-gpio:
>> -               Hotplug detect GPIO.
>> -                       Indicates which GPIO should be used for hotplug
>> -                       detection
>> -       -video interfaces: Device node can contain video interface port
>> -                           nodes according to [1].
>>
>> -[1]: Documentation/devicetree/bindings/media/video-interfaces.txt
>> +For the below properties, please refer to Analogix DP binding document:
>> + * Documentation/devicetree/bindings/drm/bridge/analogix_dp.txt
>> +       -phys (required)
>> +       -phy-names (required)
>> +       -analogix,color-space (required)
>> +       -analogix,color-depth (required)
>> +       -analogix,link-rate (required)
>> +       -analogix,lane-count (required)
>> +       -analogix,hpd-gpio (optional)
>> +       -video interfaces (optional)
>> +-------------------------------------------------------------------------------
>>
>>  Example:
>>
>> @@ -88,12 +74,10 @@ SOC specific portion:
>>
>>  Board Specific portion:
>>         dp-controller {
>> -               samsung,color-space = <0>;
>> -               samsung,dynamic-range = <0>;
>> -               samsung,ycbcr-coeff = <0>;
>> -               samsung,color-depth = <1>;
>> -               samsung,link-rate = <0x0a>;
>> -               samsung,lane-count = <4>;
>> +               analogix,color-space = <0>;
>> +               analogix,color-depth = <1>;
>> +               analogix,link-rate = <0x0a>;
>> +               analogix,lane-count = <4>;
>>
>>                 display-timings {
>>                         native-mode = <&lcd_timing>;
>> diff --git a/arch/arm/boot/dts/exynos5250-arndale.dts b/arch/arm/boot/dts/exynos5250-arndale.dts
>> index 7e728a1..e48798d 100644
>> --- a/arch/arm/boot/dts/exynos5250-arndale.dts
>> +++ b/arch/arm/boot/dts/exynos5250-arndale.dts
>> @@ -119,12 +119,10 @@
>>
>>  &dp {
>>         status = "okay";
>> -       samsung,color-space = <0>;
>> -       samsung,dynamic-range = <0>;
>> -       samsung,ycbcr-coeff = <0>;
>> -       samsung,color-depth = <1>;
>> -       samsung,link-rate = <0x0a>;
>> -       samsung,lane-count = <4>;
>> +       analogix,color-space = <0>;
>> +       analogix,color-depth = <1>;
>> +       analogix,link-rate = <0x0a>;
>> +       analogix,lane-count = <4>;
>>  };
>>
>>  &fimd {
>> diff --git a/arch/arm/boot/dts/exynos5250-smdk5250.dts b/arch/arm/boot/dts/exynos5250-smdk5250.dts
>> index 4fe186d..b8c6b8b 100644
>> --- a/arch/arm/boot/dts/exynos5250-smdk5250.dts
>> +++ b/arch/arm/boot/dts/exynos5250-smdk5250.dts
>> @@ -75,12 +75,10 @@
>>  };
>>
>>  &dp {
>> -       samsung,color-space = <0>;
>> -       samsung,dynamic-range = <0>;
>> -       samsung,ycbcr-coeff = <0>;
>> -       samsung,color-depth = <1>;
>> -       samsung,link-rate = <0x0a>;
>> -       samsung,lane-count = <4>;
>> +       analogix,color-space = <0>;
>> +       analogix,color-depth = <1>;
>> +       analogix,link-rate = <0x0a>;
>> +       analogix,lane-count = <4>;
>>
>>         pinctrl-names = "default";
>>         pinctrl-0 = <&dp_hpd>;
>> diff --git a/arch/arm/boot/dts/exynos5250-snow.dts b/arch/arm/boot/dts/exynos5250-snow.dts
>> index b7f4122..9ce2b89 100644
>> --- a/arch/arm/boot/dts/exynos5250-snow.dts
>> +++ b/arch/arm/boot/dts/exynos5250-snow.dts
>> @@ -239,13 +239,11 @@
>>         status = "okay";
>>         pinctrl-names = "default";
>>         pinctrl-0 = <&dp_hpd>;
>> -       samsung,color-space = <0>;
>> -       samsung,dynamic-range = <0>;
>> -       samsung,ycbcr-coeff = <0>;
>> -       samsung,color-depth = <1>;
>> -       samsung,link-rate = <0x0a>;
>> -       samsung,lane-count = <2>;
>> -       samsung,hpd-gpio = <&gpx0 7 GPIO_ACTIVE_HIGH>;
>> +       analogix,color-space = <0>;
>> +       analogix,color-depth = <1>;
>> +       analogix,link-rate = <0x0a>;
>> +       analogix,lane-count = <2>;
>> +       analogix,hpd-gpio = <&gpx0 7 GPIO_ACTIVE_HIGH>;
>>
>>         ports {
>>                 port at 0 {
>> diff --git a/arch/arm/boot/dts/exynos5250-spring.dts b/arch/arm/boot/dts/exynos5250-spring.dts
>> index d03f9b8..9288ae6 100644
>> --- a/arch/arm/boot/dts/exynos5250-spring.dts
>> +++ b/arch/arm/boot/dts/exynos5250-spring.dts
>> @@ -69,13 +69,11 @@
>>         status = "okay";
>>         pinctrl-names = "default";
>>         pinctrl-0 = <&dp_hpd_gpio>;
>> -       samsung,color-space = <0>;
>> -       samsung,dynamic-range = <0>;
>> -       samsung,ycbcr-coeff = <0>;
>> -       samsung,color-depth = <1>;
>> -       samsung,link-rate = <0x0a>;
>> -       samsung,lane-count = <1>;
>> -       samsung,hpd-gpio = <&gpc3 0 GPIO_ACTIVE_HIGH>;
>> +       analogix,color-space = <0>;
>> +       analogix,color-depth = <1>;
>> +       analogix,link-rate = <0x0a>;
>> +       analogix,lane-count = <1>;
>> +       analogix,hpd-gpio = <&gpc3 0 GPIO_ACTIVE_HIGH>;
>>  };
>>
>>  &ehci {
>> diff --git a/arch/arm/boot/dts/exynos5420-peach-pit.dts b/arch/arm/boot/dts/exynos5420-peach-pit.dts
>> index 8f4d76c..695a380 100644
>> --- a/arch/arm/boot/dts/exynos5420-peach-pit.dts
>> +++ b/arch/arm/boot/dts/exynos5420-peach-pit.dts
>> @@ -147,13 +147,11 @@
>>         status = "okay";
>>         pinctrl-names = "default";
>>         pinctrl-0 = <&dp_hpd_gpio>;
>> -       samsung,color-space = <0>;
>> -       samsung,dynamic-range = <0>;
>> -       samsung,ycbcr-coeff = <0>;
>> -       samsung,color-depth = <1>;
>> -       samsung,link-rate = <0x06>;
>> -       samsung,lane-count = <2>;
>> -       samsung,hpd-gpio = <&gpx2 6 0>;
>> +       analogix,color-space = <0>;
>> +       analogix,color-depth = <1>;
>> +       analogix,link-rate = <0x06>;
>> +       analogix,lane-count = <2>;
>> +       analogix,hpd-gpio = <&gpx2 6 0>;
>>
>>         ports {
>>                 port at 0 {
>> diff --git a/arch/arm/boot/dts/exynos5420-smdk5420.dts b/arch/arm/boot/dts/exynos5420-smdk5420.dts
>> index 98871f9..fd46714 100644
>> --- a/arch/arm/boot/dts/exynos5420-smdk5420.dts
>> +++ b/arch/arm/boot/dts/exynos5420-smdk5420.dts
>> @@ -91,12 +91,10 @@
>>  &dp {
>>         pinctrl-names = "default";
>>         pinctrl-0 = <&dp_hpd>;
>> -       samsung,color-space = <0>;
>> -       samsung,dynamic-range = <0>;
>> -       samsung,ycbcr-coeff = <0>;
>> -       samsung,color-depth = <1>;
>> -       samsung,link-rate = <0x0a>;
>> -       samsung,lane-count = <4>;
>> +       analogix,color-space = <0>;
>> +       analogix,color-depth = <1>;
>> +       analogix,link-rate = <0x0a>;
>> +       analogix,lane-count = <4>;
>>         status = "okay";
>>  };
>>
>> diff --git a/arch/arm/boot/dts/exynos5800-peach-pi.dts b/arch/arm/boot/dts/exynos5800-peach-pi.dts
>> index 7d5b386..54b4c63 100644
>> --- a/arch/arm/boot/dts/exynos5800-peach-pi.dts
>> +++ b/arch/arm/boot/dts/exynos5800-peach-pi.dts
>> @@ -141,13 +141,11 @@
>>         status = "okay";
>>         pinctrl-names = "default";
>>         pinctrl-0 = <&dp_hpd_gpio>;
>> -       samsung,color-space = <0>;
>> -       samsung,dynamic-range = <0>;
>> -       samsung,ycbcr-coeff = <0>;
>> -       samsung,color-depth = <1>;
>> -       samsung,link-rate = <0x0a>;
>> -       samsung,lane-count = <2>;
>> -       samsung,hpd-gpio = <&gpx2 6 0>;
>> +       analogix,color-space = <0>;
>> +       analogix,color-depth = <1>;
>> +       analogix,link-rate = <0x0a>;
>> +       analogix,lane-count = <2>;
>> +       analogix,hpd-gpio = <&gpx2 6 0>;
>>         panel = <&panel>;
>>  };
>>
>> --
>> 1.9.1
>>
>>
>>
>> _______________________________________________
>> linux-arm-kernel mailing list
>> linux-arm-kernel at lists.infradead.org
>> http://lists.infradead.org/mailman/listinfo/linux-arm-kernel
>
> _______________________________________________
> linux-arm-kernel mailing list
> linux-arm-kernel at lists.infradead.org
> http://lists.infradead.org/mailman/listinfo/linux-arm-kernel


From dmitry.torokhov at gmail.com  Fri Aug 21 18:30:57 2015
From: dmitry.torokhov at gmail.com (Dmitry Torokhov)
Date: Fri, 21 Aug 2015 18:30:57 -0700
Subject: [PATCH v4 3/3] touchscreen: colibri-vf50-ts: Add touchscreen
 support for Colibri VF50
In-Reply-To: <915c9122cfba83c6fbbc519c10ae2d101e27bc5b.1440162473.git.maitysanchayan@gmail.com>
References: <cover.1440162473.git.maitysanchayan@gmail.com>
 <915c9122cfba83c6fbbc519c10ae2d101e27bc5b.1440162473.git.maitysanchayan@gmail.com>
Message-ID: <20150822013057.GA12702@dtor-pixel>

Hi Sanchayan,

On Fri, Aug 21, 2015 at 06:56:32PM +0530, Sanchayan Maity wrote:
> The Colibri Vybrid VF50 module supports 4-wire touchscreens using
> FETs and ADC inputs. This driver uses the IIO consumer interface
> and relies on the vf610_adc driver based on the IIO framework.
> 

Thank you for making changes. I have a few comments still.

> Signed-off-by: Sanchayan Maity <maitysanchayan at gmail.com>
> ---
>  drivers/input/touchscreen/Kconfig           |  12 +
>  drivers/input/touchscreen/Makefile          |   1 +
>  drivers/input/touchscreen/colibri-vf50-ts.c | 370 ++++++++++++++++++++++++++++
>  3 files changed, 383 insertions(+)
>  create mode 100644 drivers/input/touchscreen/colibri-vf50-ts.c
> 
> diff --git a/drivers/input/touchscreen/Kconfig b/drivers/input/touchscreen/Kconfig
> index 80f6386..28948ca 100644
> --- a/drivers/input/touchscreen/Kconfig
> +++ b/drivers/input/touchscreen/Kconfig
> @@ -1027,4 +1027,16 @@ config TOUCHSCREEN_ZFORCE
>  	  To compile this driver as a module, choose M here: the
>  	  module will be called zforce_ts.
>  
> +config TOUCHSCREEN_COLIBRI_VF50
> +	tristate "Toradex Colibri on board touchscreen driver"
> +	depends on GPIOLIB && IIO && VF610_ADC

Can we possibly add "|| COMPILE_TEST" dependency? Will it compile
without IIO or VF610_ADC enabled?


> +	help
> +	  Say Y here if you have a Colibri VF50 and plan to use
> +	  the on-board provided 4-wire touchscreen driver.
> +
> +	  If unsure, say N.
> +
> +	  To compile this driver as a module, choose M here: the
> +	  module will be called colibri_vf50_ts.
> +
>  endif
> diff --git a/drivers/input/touchscreen/Makefile b/drivers/input/touchscreen/Makefile
> index 44deea7..93746a0 100644
> --- a/drivers/input/touchscreen/Makefile
> +++ b/drivers/input/touchscreen/Makefile
> @@ -84,3 +84,4 @@ obj-$(CONFIG_TOUCHSCREEN_W90X900)	+= w90p910_ts.o
>  obj-$(CONFIG_TOUCHSCREEN_SX8654)	+= sx8654.o
>  obj-$(CONFIG_TOUCHSCREEN_TPS6507X)	+= tps6507x-ts.o
>  obj-$(CONFIG_TOUCHSCREEN_ZFORCE)	+= zforce_ts.o
> +obj-$(CONFIG_TOUCHSCREEN_COLIBRI_VF50)	+= colibri-vf50-ts.o
> diff --git a/drivers/input/touchscreen/colibri-vf50-ts.c b/drivers/input/touchscreen/colibri-vf50-ts.c
> new file mode 100644
> index 0000000..0793fdc
> --- /dev/null
> +++ b/drivers/input/touchscreen/colibri-vf50-ts.c
> @@ -0,0 +1,370 @@
> +/* Copyright 2015 Toradex AG
> + *
> + * Toradex Colibri VF50 Touchscreen driver
> + *
> + * Originally authored by Stefan Agner for 3.0 kernel
> + *
> + * 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.
> + */
> +
> +#include <linux/delay.h>
> +#include <linux/err.h>
> +#include <linux/gpio.h>
> +#include <linux/iio/consumer.h>
> +#include <linux/iio/types.h>
> +#include <linux/input.h>
> +#include <linux/interrupt.h>
> +#include <linux/kernel.h>
> +#include <linux/module.h>
> +#include <linux/pinctrl/consumer.h>

Don't you need gpio/consumer.h?

> +#include <linux/platform_device.h>
> +#include <linux/slab.h>
> +#include <linux/types.h>
> +
> +#define DRIVER_NAME "colibri-vf50-ts"
> +#define DRV_VERSION "1.0"
> +
> +#define VF_ADC_MAX ((1 << 12) - 1)
> +
> +#define COLI_TOUCH_MIN_DELAY_US 1000
> +#define COLI_TOUCH_MAX_DELAY_US 2000
> +#define COLI_TOUCH_NO_OF_AVGS	5
> +
> +struct vf50_touch_device {
> +	struct platform_device	*pdev;
> +	struct input_dev	*ts_input;
> +	struct iio_channel	*channels;
> +	struct gpio_desc *gpio_xp;
> +	struct gpio_desc *gpio_xm;
> +	struct gpio_desc *gpio_yp;
> +	struct gpio_desc *gpio_ym;
> +	struct gpio_desc *gpio_pen_detect;

I do not see gpio_pen_detect being used anymore.

> +	int pen_irq;
> +	int min_pressure;
> +	bool stop_touchscreen;
> +};
> +
> +/*
> + * Enables given plates and measures touch parameters using ADC
> + */
> +static int adc_ts_measure(struct iio_channel *channel,
> +		  struct gpio_desc *plate_p, struct gpio_desc *plate_m)
> +{
> +	int i, value = 0, val = 0;
> +	int ret;
> +
> +	gpiod_set_value(plate_p, 1);
> +	gpiod_set_value(plate_m, 1);
> +
> +	usleep_range(COLI_TOUCH_MIN_DELAY_US, COLI_TOUCH_MAX_DELAY_US);
> +
> +	for (i = 0; i < COLI_TOUCH_NO_OF_AVGS; i++) {
> +		ret = iio_read_channel_raw(channel, &val);
> +		if (ret < 0) {
> +			value = ret;
> +			goto error_iio_read;
> +		}
> +
> +		value += val;
> +	}
> +
> +	value /= COLI_TOUCH_NO_OF_AVGS;
> +
> +error_iio_read:
> +	gpiod_set_value(plate_p, 0);
> +	gpiod_set_value(plate_m, 0);
> +
> +	return value;
> +}
> +
> +/*
> + * Enable touch detection using falling edge detection on XM
> + */
> +static void vf50_ts_enable_touch_detection(struct vf50_touch_device *vf50_ts)
> +{
> +	/* Enable plate YM (needs to be strong GND, high active) */
> +	gpiod_set_value(vf50_ts->gpio_ym, 1);
> +
> +	/*
> +	 * Let the platform mux to idle state in order to enable
> +	 * Pull-Up on GPIO
> +	 */
> +	pinctrl_pm_select_idle_state(&vf50_ts->pdev->dev);
> +}
> +
> +/*
> + * ADC touch screen sampling bottom half irq handler
> + */
> +static irqreturn_t vf50_ts_irq_bh(int irq, void *private)
> +{
> +	struct vf50_touch_device *vf50_ts = (struct vf50_touch_device *)private;

No need to cast from void * pointer.

> +	struct device *dev = &vf50_ts->pdev->dev;
> +	int val_x, val_y, val_z1, val_z2, val_p = 0;
> +	bool discard_val_on_start = true;
> +
> +	/* Disable the touch detection plates */
> +	gpiod_set_value(vf50_ts->gpio_ym, 0);
> +
> +	/* Let the platform mux to default state in order to mux as ADC */
> +	pinctrl_pm_select_default_state(dev);
> +
> +	while (!vf50_ts->stop_touchscreen) {
> +		/* X-Direction */
> +		val_x = adc_ts_measure(&vf50_ts->channels[0],
> +				vf50_ts->gpio_xp, vf50_ts->gpio_xm);
> +		if (val_x < 0)
> +			break;
> +
> +		/* Y-Direction */
> +		val_y = adc_ts_measure(&vf50_ts->channels[1],
> +				vf50_ts->gpio_yp, vf50_ts->gpio_ym);
> +		if (val_y < 0)
> +			break;
> +
> +		/*
> +		 * Touch pressure
> +		 * Measure on XP/YM
> +		 */
> +		val_z1 = adc_ts_measure(&vf50_ts->channels[2],
> +				vf50_ts->gpio_yp, vf50_ts->gpio_xm);
> +		if (val_z1 < 0)
> +			break;
> +		val_z2 = adc_ts_measure(&vf50_ts->channels[3],
> +				vf50_ts->gpio_yp, vf50_ts->gpio_xm);
> +		if (val_z2 < 0)
> +			break;
> +
> +		/* Validate signal (avoid calculation using noise) */
> +		if (val_z1 > 64 && val_x > 64) {
> +			/*
> +			 * Calculate resistance between the plates
> +			 * lower resistance means higher pressure
> +			 */
> +			int r_x = (1000 * val_x) / VF_ADC_MAX;
> +
> +			val_p = (r_x * val_z2) / val_z1 - r_x;
> +
> +		} else {
> +			val_p = 2000;
> +		}
> +
> +		val_p = 2000 - val_p;
> +		dev_dbg(dev, "Measured values: x: %d, y: %d, z1: %d, z2: %d, "
> +			"p: %d\n", val_x, val_y, val_z1, val_z2, val_p);
> +
> +		/*
> +		 * If touch pressure is too low, stop measuring and reenable
> +		 * touch detection
> +		 */
> +		if (val_p < vf50_ts->min_pressure || val_p > 2000)
> +			break;
> +
> +		/*
> +		 * The pressure may not be enough for the first x and the
> +		 * second y measurement, but, the pressure is ok when the
> +		 * driver is doing the third and fourth measurement. To
> +		 * take care of this, we drop the first measurement always.
> +		 */
> +		if (discard_val_on_start) {
> +			discard_val_on_start = false;
> +		} else {
> +			/*
> +			 * Report touch position and sleep for
> +			 * next measurement
> +			 */
> +			input_report_abs(vf50_ts->ts_input,
> +					ABS_X, VF_ADC_MAX - val_x);
> +			input_report_abs(vf50_ts->ts_input,
> +					ABS_Y, VF_ADC_MAX - val_y);
> +			input_report_abs(vf50_ts->ts_input,
> +					ABS_PRESSURE, val_p);
> +			input_report_key(vf50_ts->ts_input, BTN_TOUCH, 1);
> +			input_sync(vf50_ts->ts_input);
> +		}
> +
> +		msleep(10);
> +	}
> +
> +	/* Report no more touch, reenable touch detection */
> +	input_report_abs(vf50_ts->ts_input, ABS_PRESSURE, 0);
> +	input_report_key(vf50_ts->ts_input, BTN_TOUCH, 0);
> +	input_sync(vf50_ts->ts_input);
> +
> +	vf50_ts_enable_touch_detection(vf50_ts);
> +
> +	/* Wait for the pull-up to be stable on high */
> +	msleep(10);
> +
> +	return IRQ_HANDLED;
> +}
> +
> +static int vf50_ts_open(struct input_dev *dev_input)
> +{
> +	struct vf50_touch_device *touchdev = input_get_drvdata(dev_input);
> +	struct device *dev = &touchdev->pdev->dev;
> +
> +	dev_dbg(dev, "Input device %s opened, starting touch detection\n",
> +			dev_input->name);
> +
> +	touchdev->stop_touchscreen = false;
> +
> +	/* Mux detection before request IRQ, wait for pull-up to settle */
> +	vf50_ts_enable_touch_detection(touchdev);
> +	msleep(10);
> +
> +	return 0;
> +}
> +
> +static void vf50_ts_close(struct input_dev *dev_input)
> +{
> +	struct vf50_touch_device *touchdev = input_get_drvdata(dev_input);
> +	struct device *dev = &touchdev->pdev->dev;
> +
> +	touchdev->stop_touchscreen = true;
> +
> +	/* Make sure IRQ is not running past close */
> +	mb();
> +	synchronize_irq(touchdev->pen_irq);
> +

Should we drive the gpio_ym inactive here? What about pin control?

> +	dev_dbg(dev, "Input device %s closed, disable touch detection\n",
> +		dev_input->name);
> +}
> +
> +static int vf50_ts_get_gpiod(struct device *dev,
> +	struct gpio_desc **gpio_d, const char *con_id, enum gpiod_flags flags)
> +{
> +	int error;
> +
> +	*gpio_d = devm_gpiod_get(dev, con_id, flags);
> +	if (IS_ERR(*gpio_d)) {
> +		error = PTR_ERR(*gpio_d);
> +		dev_err(dev, "Could not get gpio_%s %d\n", con_id, error);
> +		return error;
> +	}
> +
> +	return 0;
> +}
> +
> +static void vf50_ts_channel_release(void *data)
> +{
> +	struct vf50_touch_device *touchdev = data;
> +
> +	iio_channel_release_all(touchdev->channels);
> +}
> +
> +static int vf50_ts_probe(struct platform_device *pdev)
> +{
> +	struct input_dev *input;
> +	struct iio_channel *channels;
> +	struct device *dev = &pdev->dev;
> +	struct vf50_touch_device *touchdev;
> +	int error;
> +
> +	channels = iio_channel_get_all(dev);
> +	if (IS_ERR(channels))
> +		return PTR_ERR(channels);
> +
> +	touchdev = devm_kzalloc(dev, sizeof(*touchdev), GFP_KERNEL);
> +	if (!touchdev) {
> +		error = -ENOMEM;
> +		return error;

Why not simply

		return -ENOMEM;

here?

Also you are leaking your iio channels here. You need to install the
custom action earlier.

> +	}
> +
> +	error = of_property_read_u32(dev->of_node, "vf50-ts-min-pressure",
> +				 &touchdev->min_pressure);
> +	if (error)
> +		return error;
> +
> +	error = devm_add_action(dev, vf50_ts_channel_release, channels);
> +	if (error) {
> +		dev_err(dev, "Failed to register iio channel release action");

You also need

		vf50_ts_channel_release(touchdev);

> +		return error;
> +	}
> +
> +	input = devm_input_allocate_device(dev);
> +	if (!input) {
> +		dev_err(dev, "Failed to allocate TS input device\n");
> +		error = -ENOMEM;
> +		return error;

Again simply return error code, no need to assign to the error variable.

> +	}
> +
> +	platform_set_drvdata(pdev, touchdev);
> +
> +	touchdev->pdev = pdev;
> +	touchdev->channels = channels;
> +
> +	input->name = DRIVER_NAME;
> +	input->id.bustype = BUS_HOST;
> +	input->dev.parent = dev;
> +	input->open = vf50_ts_open;
> +	input->close = vf50_ts_close;
> +
> +	input_set_capability(input, EV_KEY, BTN_TOUCH);
> +	input_set_abs_params(input, ABS_X, 0, VF_ADC_MAX, 0, 0);
> +	input_set_abs_params(input, ABS_Y, 0, VF_ADC_MAX, 0, 0);
> +	input_set_abs_params(input, ABS_PRESSURE, 0, VF_ADC_MAX, 0, 0);
> +
> +	touchdev->ts_input = input;
> +	input_set_drvdata(input, touchdev);
> +	error = input_register_device(input);
> +	if (error) {
> +		dev_err(dev, "Failed to register input device\n");
> +		return error;
> +	}
> +
> +	error = vf50_ts_get_gpiod(dev, &touchdev->gpio_xp,
> +				"xp", GPIOD_OUT_LOW);
> +	if (error)
> +		return error;
> +
> +	error = vf50_ts_get_gpiod(dev, &touchdev->gpio_xm,
> +				"xm", GPIOD_OUT_LOW);
> +	if (error)
> +		return error;
> +
> +	error = vf50_ts_get_gpiod(dev, &touchdev->gpio_yp,
> +				"yp", GPIOD_OUT_LOW);
> +	if (error)
> +		return error;
> +
> +	error = vf50_ts_get_gpiod(dev, &touchdev->gpio_ym,
> +				"ym", GPIOD_OUT_LOW);
> +	if (error)
> +		return error;
> +
> +	touchdev->pen_irq = platform_get_irq(pdev, 0);
> +	if (touchdev->pen_irq < 0)
> +		return touchdev->pen_irq;
> +
> +	error = devm_request_threaded_irq(dev, touchdev->pen_irq, NULL,
> +			vf50_ts_irq_bh, IRQF_ONESHOT,
> +			"vf50 touch", touchdev);
> +	if (error < 0)
> +		return error;
> +
> +	return 0;
> +}
> +
> +static const struct of_device_id vf50_touch_of_match[] = {
> +	{ .compatible = "toradex,vf50-touchscreen", },
> +	{ }
> +};
> +MODULE_DEVICE_TABLE(of, vf50_touch_of_match);
> +
> +static struct platform_driver vf50_touch_driver = {
> +	.driver = {
> +		.name = "toradex,vf50_touchctrl",
> +		.of_match_table = vf50_touch_of_match,
> +	},
> +	.probe = vf50_ts_probe,
> +};
> +
> +module_platform_driver(vf50_touch_driver);
> +
> +MODULE_AUTHOR("Sanchayan Maity");
> +MODULE_DESCRIPTION("Colibri VF50 Touchscreen driver");
> +MODULE_LICENSE("GPL v2");

Please change it to "GPL" which means GPL v2+ to match license notice at
the top.

> +MODULE_VERSION(DRV_VERSION);
> -- 
> 2.5.0
> 

Thank you.

-- 
Dmitry


From shawn.lin at rock-chips.com  Sun Aug 23 18:25:36 2015
From: shawn.lin at rock-chips.com (Shawn Lin)
Date: Mon, 24 Aug 2015 09:25:36 +0800
Subject: [RFC PATCH v7 01/10] mmc: dw_mmc: Add external dma interface support
In-Reply-To: <1440379479-24308-1-git-send-email-shawn.lin@rock-chips.com>
References: <1440379479-24308-1-git-send-email-shawn.lin@rock-chips.com>
Message-ID: <1440379536-24400-1-git-send-email-shawn.lin@rock-chips.com>

DesignWare MMC Controller can supports two types of DMA
mode: external dma and internal dma. We get a RK312x platform
integrated dw_mmc and ARM pl330 dma controller. This patch add
edmac ops to support these platforms. I've tested it on RK31xx
platform with edmac mode and RK3288 platform with idmac mode.

Signed-off-by: Shawn Lin <shawn.lin at rock-chips.com>

---

Changes in v7:
- rebased on Ulf's next
- combine condition state
- elaborate more about DMA_INTERFACE
- define some macro for DMA_INERFACE value
- spilt HCON ops' changes into another patch

Changes in v6:
- add trans_mode condition for IDMAC initialization
  suggested by Heiko
- re-test my patch on rk3188 platform and update commit msg
- update performance of pio vs edmac in cover letter

Changes in v5:
- add the title of cover letter
- fix typo of comment
- add macro for reading HCON register
- add "Acked-by: Krzysztof Kozlowski <k.kozlowski at samsung.com>" for exynos_defconfig patch
- add "Acked-by: Vineet Gupta <vgupta at synopsys.com>" for axs10x_defconfig patch
- add "Acked-by: Govindraj Raja <govindraj.raja at imgtec.com>" and
  "Acked-by: Ralf Baechle <ralf at linux-mips.org>" for pistachio_defconfig patch
- add "Acked-by: Joachim Eastwood <manabian at gmail.com>" for lpc18xx_defconfig patch
- add "Acked-by: Wei Xu <xuwei5 at hisilicon.com>" for hisi_defconfig patch
- rebase on "https://github.com/jh80chung/dw-mmc.git tags/dw-mmc-for-ulf-v4.2" for merging easily

Changes in v4:
- remove "host->trans_mode" and use "host->use_dma" to indicate
  transfer mode.
- remove all bt-bindings' changes since we don't need new properities.
- check transfer mode at runtime by reading HCON reg
- spilt defconfig changes for each sub-architecture
- fix the title of cover letter
- reuse some code for reducing code size

Changes in v3:
- choose transfer mode at runtime
- remove all CONFIG_MMC_DW_IDMAC config option
- add supports-idmac property for some platforms

Changes in v2:
- Fix typo of dev_info msg
- remove unused dmach from declaration of dw_mci_dma_slave

 drivers/mmc/host/Kconfig        |  11 +-
 drivers/mmc/host/dw_mmc-pltfm.c |   2 +
 drivers/mmc/host/dw_mmc.c       | 273 ++++++++++++++++++++++++++++++++--------
 drivers/mmc/host/dw_mmc.h       |   6 +
 include/linux/mmc/dw_mmc.h      |  23 +++-
 5 files changed, 253 insertions(+), 62 deletions(-)

diff --git a/drivers/mmc/host/Kconfig b/drivers/mmc/host/Kconfig
index 6a0f9c7..539b1a6 100644
--- a/drivers/mmc/host/Kconfig
+++ b/drivers/mmc/host/Kconfig
@@ -607,15 +607,7 @@ config MMC_DW
 	help
 	  This selects support for the Synopsys DesignWare Mobile Storage IP
 	  block, this provides host support for SD and MMC interfaces, in both
-	  PIO and external DMA modes.
-
-config MMC_DW_IDMAC
-	bool "Internal DMAC interface"
-	depends on MMC_DW
-	help
-	  This selects support for the internal DMAC block within the Synopsys
-	  Designware Mobile Storage IP block. This disables the external DMA
-	  interface.
+	  PIO, internal DMA mode and external DMA mode.
 
 config MMC_DW_PLTFM
 	tristate "Synopsys Designware MCI Support as platform device"
@@ -644,7 +636,6 @@ config MMC_DW_K3
 	tristate "K3 specific extensions for Synopsys DW Memory Card Interface"
 	depends on MMC_DW
 	select MMC_DW_PLTFM
-	select MMC_DW_IDMAC
 	help
 	  This selects support for Hisilicon K3 SoC specific extensions to the
 	  Synopsys DesignWare Memory Card Interface driver. Select this option
diff --git a/drivers/mmc/host/dw_mmc-pltfm.c b/drivers/mmc/host/dw_mmc-pltfm.c
index ec6dbcd..7e1d13b 100644
--- a/drivers/mmc/host/dw_mmc-pltfm.c
+++ b/drivers/mmc/host/dw_mmc-pltfm.c
@@ -59,6 +59,8 @@ int dw_mci_pltfm_register(struct platform_device *pdev,
 	host->pdata = pdev->dev.platform_data;
 
 	regs = platform_get_resource(pdev, IORESOURCE_MEM, 0);
+	/* Get registers' physical base address */
+	host->phy_regs = (void *)(regs->start);
 	host->regs = devm_ioremap_resource(&pdev->dev, regs);
 	if (IS_ERR(host->regs))
 		return PTR_ERR(host->regs);
diff --git a/drivers/mmc/host/dw_mmc.c b/drivers/mmc/host/dw_mmc.c
index fcbf552..9c91983 100644
--- a/drivers/mmc/host/dw_mmc.c
+++ b/drivers/mmc/host/dw_mmc.c
@@ -56,7 +56,6 @@
 #define DW_MCI_FREQ_MAX	200000000	/* unit: HZ */
 #define DW_MCI_FREQ_MIN	400000		/* unit: HZ */
 
-#ifdef CONFIG_MMC_DW_IDMAC
 #define IDMAC_INT_CLR		(SDMMC_IDMAC_INT_AI | SDMMC_IDMAC_INT_NI | \
 				 SDMMC_IDMAC_INT_CES | SDMMC_IDMAC_INT_DU | \
 				 SDMMC_IDMAC_INT_FBE | SDMMC_IDMAC_INT_RI | \
@@ -102,7 +101,6 @@ struct idmac_desc {
 
 /* Each descriptor can transfer up to 4KB of data in chained mode */
 #define DW_MCI_DESC_DATA_LENGTH	0x1000
-#endif /* CONFIG_MMC_DW_IDMAC */
 
 static bool dw_mci_reset(struct dw_mci *host);
 static bool dw_mci_ctrl_reset(struct dw_mci *host, u32 reset);
@@ -407,7 +405,6 @@ static int dw_mci_get_dma_dir(struct mmc_data *data)
 		return DMA_FROM_DEVICE;
 }
 
-#ifdef CONFIG_MMC_DW_IDMAC
 static void dw_mci_dma_cleanup(struct dw_mci *host)
 {
 	struct mmc_data *data = host->data;
@@ -445,12 +442,21 @@ static void dw_mci_idmac_stop_dma(struct dw_mci *host)
 	mci_writel(host, BMOD, temp);
 }
 
-static void dw_mci_idmac_complete_dma(struct dw_mci *host)
+static void dw_mci_dmac_complete_dma(void *arg)
 {
+	struct dw_mci *host = arg;
 	struct mmc_data *data = host->data;
 
 	dev_vdbg(host->dev, "DMA complete\n");
 
+	if ((host->use_dma == TRANS_MODE_EDMAC) &&
+	    data && (data->flags & MMC_DATA_READ))
+		/* Invalidate cache after read */
+		dma_sync_sg_for_cpu(mmc_dev(host->cur_slot->mmc),
+				    data->sg,
+				    data->sg_len,
+				    DMA_FROM_DEVICE);
+
 	host->dma_ops->cleanup(host);
 
 	/*
@@ -564,7 +570,7 @@ static void dw_mci_translate_sglist(struct dw_mci *host, struct mmc_data *data,
 	wmb(); /* drain writebuffer */
 }
 
-static void dw_mci_idmac_start_dma(struct dw_mci *host, unsigned int sg_len)
+static int dw_mci_idmac_start_dma(struct dw_mci *host, unsigned int sg_len)
 {
 	u32 temp;
 
@@ -589,6 +595,8 @@ static void dw_mci_idmac_start_dma(struct dw_mci *host, unsigned int sg_len)
 
 	/* Start it running */
 	mci_writel(host, PLDMND, 1);
+
+	return 0;
 }
 
 static int dw_mci_idmac_init(struct dw_mci *host)
@@ -669,10 +677,112 @@ static const struct dw_mci_dma_ops dw_mci_idmac_ops = {
 	.init = dw_mci_idmac_init,
 	.start = dw_mci_idmac_start_dma,
 	.stop = dw_mci_idmac_stop_dma,
-	.complete = dw_mci_idmac_complete_dma,
+	.complete = dw_mci_dmac_complete_dma,
+	.cleanup = dw_mci_dma_cleanup,
+};
+
+static void dw_mci_edmac_stop_dma(struct dw_mci *host)
+{
+	dmaengine_terminate_all(host->dms->ch);
+}
+
+static int dw_mci_edmac_start_dma(struct dw_mci *host,
+					    unsigned int sg_len)
+{
+	struct dma_slave_config cfg;
+	struct dma_async_tx_descriptor *desc = NULL;
+	struct scatterlist *sgl = host->data->sg;
+	const u32 mszs[] = {1, 4, 8, 16, 32, 64, 128, 256};
+	u32 sg_elems = host->data->sg_len;
+	u32 fifoth_val;
+	u32 fifo_offset = host->fifo_reg - host->regs;
+	int ret = 0;
+
+	/* Set external dma config: burst size, burst width */
+	cfg.dst_addr = (dma_addr_t)(host->phy_regs + fifo_offset);
+	cfg.src_addr = cfg.dst_addr;
+	cfg.dst_addr_width = DMA_SLAVE_BUSWIDTH_4_BYTES;
+	cfg.src_addr_width = DMA_SLAVE_BUSWIDTH_4_BYTES;
+
+	/* Match burst msize with external dma config */
+	fifoth_val = mci_readl(host, FIFOTH);
+	cfg.dst_maxburst = mszs[(fifoth_val >> 28) & 0x7];
+	cfg.src_maxburst = cfg.dst_maxburst;
+
+	if (host->data->flags & MMC_DATA_WRITE)
+		cfg.direction = DMA_MEM_TO_DEV;
+	else /* MMC_DATA_READ */
+		cfg.direction = DMA_DEV_TO_MEM;
+
+	ret = dmaengine_slave_config(host->dms->ch, &cfg);
+	if (ret) {
+		dev_err(host->dev, "Failed to config edmac.\n");
+		return -EBUSY;
+	}
+
+	desc = dmaengine_prep_slave_sg(host->dms->ch, sgl,
+				       sg_len, cfg.direction,
+				       DMA_PREP_INTERRUPT | DMA_CTRL_ACK);
+	if (!desc) {
+		dev_err(host->dev, "Can't prepare slave sg.\n");
+		return -EBUSY;
+	}
+
+	/* Set dw_mci_dmac_complete_dma as callback */
+	desc->callback = dw_mci_dmac_complete_dma;
+	desc->callback_param = (void *)host;
+	dmaengine_submit(desc);
+
+	/* Flush cache before write */
+	if (host->data->flags & MMC_DATA_WRITE)
+		dma_sync_sg_for_device(mmc_dev(host->cur_slot->mmc), sgl,
+				       sg_elems, DMA_TO_DEVICE);
+
+	dma_async_issue_pending(host->dms->ch);
+
+	return 0;
+}
+
+static int dw_mci_edmac_init(struct dw_mci *host)
+{
+	/* Request external dma channel */
+	host->dms = kzalloc(sizeof(struct dw_mci_dma_slave), GFP_KERNEL);
+	if (!host->dms)
+		return -ENOMEM;
+
+	host->dms->ch = dma_request_slave_channel(host->dev, "rx-tx");
+	if (!host->dms->ch) {
+		dev_err(host->dev,
+			"Failed to get external DMA channel %d\n",
+			host->dms->ch->chan_id);
+		kfree(host->dms);
+		host->dms = NULL;
+		return -ENXIO;
+	}
+
+	return 0;
+}
+
+static void dw_mci_edmac_exit(struct dw_mci *host)
+{
+	if (host->dms) {
+		if (host->dms->ch) {
+			dma_release_channel(host->dms->ch);
+			host->dms->ch = NULL;
+		}
+		kfree(host->dms);
+		host->dms = NULL;
+	}
+}
+
+static const struct dw_mci_dma_ops dw_mci_edmac_ops = {
+	.init = dw_mci_edmac_init,
+	.exit = dw_mci_edmac_exit,
+	.start = dw_mci_edmac_start_dma,
+	.stop = dw_mci_edmac_stop_dma,
+	.complete = dw_mci_dmac_complete_dma,
 	.cleanup = dw_mci_dma_cleanup,
 };
-#endif /* CONFIG_MMC_DW_IDMAC */
 
 static int dw_mci_pre_dma_transfer(struct dw_mci *host,
 				   struct mmc_data *data,
@@ -752,7 +862,6 @@ static void dw_mci_post_req(struct mmc_host *mmc,
 
 static void dw_mci_adjust_fifoth(struct dw_mci *host, struct mmc_data *data)
 {
-#ifdef CONFIG_MMC_DW_IDMAC
 	unsigned int blksz = data->blksz;
 	const u32 mszs[] = {1, 4, 8, 16, 32, 64, 128, 256};
 	u32 fifo_width = 1 << host->data_shift;
@@ -760,6 +869,10 @@ static void dw_mci_adjust_fifoth(struct dw_mci *host, struct mmc_data *data)
 	u32 msize = 0, rx_wmark = 1, tx_wmark, tx_wmark_invers;
 	int idx = ARRAY_SIZE(mszs) - 1;
 
+	/* pio should ship this scenario */
+	if (!host->use_dma)
+		return;
+
 	tx_wmark = (host->fifo_depth) / 2;
 	tx_wmark_invers = host->fifo_depth - tx_wmark;
 
@@ -788,7 +901,6 @@ static void dw_mci_adjust_fifoth(struct dw_mci *host, struct mmc_data *data)
 done:
 	fifoth_val = SDMMC_SET_FIFOTH(msize, rx_wmark, tx_wmark);
 	mci_writel(host, FIFOTH, fifoth_val);
-#endif
 }
 
 static void dw_mci_ctrl_rd_thld(struct dw_mci *host, struct mmc_data *data)
@@ -850,10 +962,12 @@ static int dw_mci_submit_data_dma(struct dw_mci *host, struct mmc_data *data)
 
 	host->using_dma = 1;
 
-	dev_vdbg(host->dev,
-		 "sd sg_cpu: %#lx sg_dma: %#lx sg_len: %d\n",
-		 (unsigned long)host->sg_cpu, (unsigned long)host->sg_dma,
-		 sg_len);
+	if (host->use_dma == TRANS_MODE_IDMAC)
+		dev_vdbg(host->dev,
+			 "sd sg_cpu: %#lx sg_dma: %#lx sg_len: %d\n",
+			 (unsigned long)host->sg_cpu,
+			 (unsigned long)host->sg_dma,
+			 sg_len);
 
 	/*
 	 * Decide the MSIZE and RX/TX Watermark.
@@ -875,7 +989,11 @@ static int dw_mci_submit_data_dma(struct dw_mci *host, struct mmc_data *data)
 	mci_writel(host, INTMASK, temp);
 	spin_unlock_irqrestore(&host->irq_lock, irqflags);
 
-	host->dma_ops->start(host, sg_len);
+	if (host->dma_ops->start(host, sg_len)) {
+		/* We can't do DMA */
+		dev_err(host->dev, "%s: failed to start DMA.\n", __func__);
+		return -ENODEV;
+	}
 
 	return 0;
 }
@@ -2343,15 +2461,17 @@ static irqreturn_t dw_mci_interrupt(int irq, void *dev_id)
 
 	}
 
-#ifdef CONFIG_MMC_DW_IDMAC
-	/* Handle DMA interrupts */
+	if (host->use_dma != TRANS_MODE_IDMAC)
+		return IRQ_HANDLED;
+
+	/* Handle IDMA interrupts */
 	if (host->dma_64bit_address == 1) {
 		pending = mci_readl(host, IDSTS64);
 		if (pending & (SDMMC_IDMAC_INT_TI | SDMMC_IDMAC_INT_RI)) {
 			mci_writel(host, IDSTS64, SDMMC_IDMAC_INT_TI |
 							SDMMC_IDMAC_INT_RI);
 			mci_writel(host, IDSTS64, SDMMC_IDMAC_INT_NI);
-			host->dma_ops->complete(host);
+			host->dma_ops->complete((void *)host);
 		}
 	} else {
 		pending = mci_readl(host, IDSTS);
@@ -2359,10 +2479,9 @@ static irqreturn_t dw_mci_interrupt(int irq, void *dev_id)
 			mci_writel(host, IDSTS, SDMMC_IDMAC_INT_TI |
 							SDMMC_IDMAC_INT_RI);
 			mci_writel(host, IDSTS, SDMMC_IDMAC_INT_NI);
-			host->dma_ops->complete(host);
+			host->dma_ops->complete((void *)host);
 		}
 	}
-#endif
 
 	return IRQ_HANDLED;
 }
@@ -2471,13 +2590,21 @@ static int dw_mci_init_slot(struct dw_mci *host, unsigned int id)
 		goto err_host_allocated;
 
 	/* Useful defaults if platform data is unset. */
-	if (host->use_dma) {
+	if (host->use_dma == TRANS_MODE_IDMAC) {
 		mmc->max_segs = host->ring_size;
 		mmc->max_blk_size = 65536;
 		mmc->max_seg_size = 0x1000;
 		mmc->max_req_size = mmc->max_seg_size * host->ring_size;
 		mmc->max_blk_count = mmc->max_req_size / 512;
+	} else if (host->use_dma == TRANS_MODE_EDMAC) {
+			mmc->max_segs = 64;
+			mmc->max_blk_size = 65536;
+			mmc->max_blk_count = 65535;
+			mmc->max_req_size =
+					mmc->max_blk_size * mmc->max_blk_count;
+			mmc->max_seg_size = mmc->max_req_size;
 	} else {
+		/* TRANS_MODE_PIO */
 		mmc->max_segs = 64;
 		mmc->max_blk_size = 65536; /* BLKSIZ is 16 bits */
 		mmc->max_blk_count = 512;
@@ -2517,35 +2644,79 @@ static void dw_mci_cleanup_slot(struct dw_mci_slot *slot, unsigned int id)
 static void dw_mci_init_dma(struct dw_mci *host)
 {
 	int addr_config;
-	/* Check ADDR_CONFIG bit in HCON to find IDMAC address bus width */
-	addr_config = (mci_readl(host, HCON) >> 27) & 0x01;
-
-	if (addr_config == 1) {
-		/* host supports IDMAC in 64-bit address mode */
-		host->dma_64bit_address = 1;
-		dev_info(host->dev, "IDMAC supports 64-bit address mode.\n");
-		if (!dma_set_mask(host->dev, DMA_BIT_MASK(64)))
-			dma_set_coherent_mask(host->dev, DMA_BIT_MASK(64));
-	} else {
-		/* host supports IDMAC in 32-bit address mode */
-		host->dma_64bit_address = 0;
-		dev_info(host->dev, "IDMAC supports 32-bit address mode.\n");
-	}
+	int trans_mode;
+	struct device *dev = host->dev;
+	struct device_node *np = dev->of_node;
 
-	/* Alloc memory for sg translation */
-	host->sg_cpu = dmam_alloc_coherent(host->dev, PAGE_SIZE,
-					  &host->sg_dma, GFP_KERNEL);
-	if (!host->sg_cpu) {
-		dev_err(host->dev, "%s: could not alloc DMA memory\n",
-			__func__);
+	/*
+	* Check tansfer mode from HCON[17:16]
+	* Clear the ambiguous description of dw_mmc databook:
+	* 2b'00: No DMA Interface -> Actually means using Internal DMA block
+	* 2b'01: DesignWare DMA Interface -> Synopsys DW-DMA block
+	* 2b'10: Generic DMA Interface -> non-Synopsys generic DMA block
+	* 2b'11: Non DW DMA Interface -> pio only
+	* Compared to DesignWare DMA Interface, Generic DMA Interface has a
+	* simpler request/acknowledge handshake mechanism and both of them
+	* are regarded as external dma master for dw_mmc.
+	* Note: host->use_dma can't take HCON[17:16] value directly for the
+	* the reason mentioned above.
+	*/
+	trans_mode = SDMMC_GET_TRANS_MODE(mci_readl(host, HCON));
+	if (trans_mode == DMA_INTERFACE_IDMA) {
+		trans_mode = TRANS_MODE_IDMAC;
+	} else if (trans_mode == DMA_INTERFACE_DWDMA ||
+		   trans_mode == DMA_INTERFACE_GDMA) {
+		trans_mode = TRANS_MODE_EDMAC;
+	} else {
+		trans_mode = TRANS_MODE_PIO;
 		goto no_dma;
 	}
 
 	/* Determine which DMA interface to use */
-#ifdef CONFIG_MMC_DW_IDMAC
-	host->dma_ops = &dw_mci_idmac_ops;
-	dev_info(host->dev, "Using internal DMA controller.\n");
-#endif
+	if (trans_mode == TRANS_MODE_IDMAC) {
+		/*
+		* Check ADDR_CONFIG bit in HCON to find
+		* IDMAC address bus width
+		*/
+		addr_config = (mci_readl(host, HCON) >> 27) & 0x01;
+
+		if (addr_config == 1) {
+			/* host supports IDMAC in 64-bit address mode */
+			host->dma_64bit_address = 1;
+			dev_info(host->dev,
+				 "IDMAC supports 64-bit address mode.\n");
+			if (!dma_set_mask(host->dev, DMA_BIT_MASK(64)))
+				dma_set_coherent_mask(host->dev,
+						      DMA_BIT_MASK(64));
+		} else {
+			/* host supports IDMAC in 32-bit address mode */
+			host->dma_64bit_address = 0;
+			dev_info(host->dev,
+				 "IDMAC supports 32-bit address mode.\n");
+		}
+
+		/* Alloc memory for sg translation */
+		host->sg_cpu = dmam_alloc_coherent(host->dev, PAGE_SIZE,
+						   &host->sg_dma, GFP_KERNEL);
+		if (!host->sg_cpu) {
+			dev_err(host->dev,
+				"%s: could not alloc DMA memory\n",
+				__func__);
+			goto no_dma;
+		}
+
+		host->dma_ops = &dw_mci_idmac_ops;
+		dev_info(host->dev, "Using internal DMA controller.\n");
+	} else {
+		/* TRANS_MODE_EDMAC: check dma bindings again */
+		if ((of_property_count_strings(np, "dma-names") < 0) ||
+		    (!of_find_property(np, "dmas", NULL))) {
+			trans_mode = TRANS_MODE_PIO;
+			goto no_dma;
+		}
+		host->dma_ops = &dw_mci_edmac_ops;
+		dev_info(host->dev, "Using external DMA controller.\n");
+	}
 
 	if (!host->dma_ops)
 		goto no_dma;
@@ -2562,12 +2733,12 @@ static void dw_mci_init_dma(struct dw_mci *host)
 		goto no_dma;
 	}
 
-	host->use_dma = 1;
+	host->use_dma = trans_mode;
 	return;
 
 no_dma:
 	dev_info(host->dev, "Using PIO mode.\n");
-	host->use_dma = 0;
+	host->use_dma = trans_mode;
 }
 
 static bool dw_mci_ctrl_reset(struct dw_mci *host, u32 reset)
@@ -2650,10 +2821,9 @@ static bool dw_mci_reset(struct dw_mci *host)
 		}
 	}
 
-#if IS_ENABLED(CONFIG_MMC_DW_IDMAC)
-	/* It is also recommended that we reset and reprogram idmac */
-	dw_mci_idmac_reset(host);
-#endif
+	if (host->use_dma == TRANS_MODE_IDMAC)
+		/* It is also recommended that we reset and reprogram idmac */
+		dw_mci_idmac_reset(host);
 
 	ret = true;
 
@@ -3067,6 +3237,9 @@ EXPORT_SYMBOL(dw_mci_remove);
  */
 int dw_mci_suspend(struct dw_mci *host)
 {
+	if (host->use_dma && host->dma_ops->exit)
+		host->dma_ops->exit(host);
+
 	return 0;
 }
 EXPORT_SYMBOL(dw_mci_suspend);
diff --git a/drivers/mmc/host/dw_mmc.h b/drivers/mmc/host/dw_mmc.h
index 8ce4674..811d467 100644
--- a/drivers/mmc/host/dw_mmc.h
+++ b/drivers/mmc/host/dw_mmc.h
@@ -148,6 +148,12 @@
 #define SDMMC_SET_FIFOTH(m, r, t)	(((m) & 0x7) << 28 | \
 					 ((r) & 0xFFF) << 16 | \
 					 ((t) & 0xFFF))
+/* HCON register defines */
+#define DMA_INTERFACE_IDMA		(0x0)
+#define DMA_INTERFACE_DWDMA		(0x1)
+#define DMA_INTERFACE_GDMA		(0x2)
+#define DMA_INTERFACE_NODMA		(0x3)
+#define SDMMC_GET_TRANS_MODE(x)		(((x)>>16) & 0x3)
 /* Internal DMAC interrupt defines */
 #define SDMMC_IDMAC_INT_AI		BIT(9)
 #define SDMMC_IDMAC_INT_NI		BIT(8)
diff --git a/include/linux/mmc/dw_mmc.h b/include/linux/mmc/dw_mmc.h
index 134c574..f67b2ec 100644
--- a/include/linux/mmc/dw_mmc.h
+++ b/include/linux/mmc/dw_mmc.h
@@ -16,6 +16,7 @@
 
 #include <linux/scatterlist.h>
 #include <linux/mmc/core.h>
+#include <linux/dmaengine.h>
 
 #define MAX_MCI_SLOTS	2
 
@@ -40,6 +41,17 @@ enum {
 
 struct mmc_data;
 
+enum {
+	TRANS_MODE_PIO = 0,
+	TRANS_MODE_IDMAC,
+	TRANS_MODE_EDMAC
+};
+
+struct dw_mci_dma_slave {
+	struct dma_chan *ch;
+	enum dma_transfer_direction direction;
+};
+
 /**
  * struct dw_mci - MMC controller state shared between all slots
  * @lock: Spinlock protecting the queue and associated data.
@@ -154,7 +166,14 @@ struct dw_mci {
 	dma_addr_t		sg_dma;
 	void			*sg_cpu;
 	const struct dw_mci_dma_ops	*dma_ops;
+	/* For idmac */
 	unsigned int		ring_size;
+
+	/* For edmac */
+	struct dw_mci_dma_slave *dms;
+	/* Registers's physical base address */
+	void                    *phy_regs;
+
 	u32			cmd_status;
 	u32			data_status;
 	u32			stop_cmdr;
@@ -208,8 +227,8 @@ struct dw_mci {
 struct dw_mci_dma_ops {
 	/* DMA Ops */
 	int (*init)(struct dw_mci *host);
-	void (*start)(struct dw_mci *host, unsigned int sg_len);
-	void (*complete)(struct dw_mci *host);
+	int (*start)(struct dw_mci *host, unsigned int sg_len);
+	void (*complete)(void *host);
 	void (*stop)(struct dw_mci *host);
 	void (*cleanup)(struct dw_mci *host);
 	void (*exit)(struct dw_mci *host);
-- 
2.3.7




From shawn.lin at rock-chips.com  Sun Aug 23 18:25:54 2015
From: shawn.lin at rock-chips.com (Shawn Lin)
Date: Mon, 24 Aug 2015 09:25:54 +0800
Subject: [RFC PATCH v7 02/10] mmc: dw_mmc: use macro for HCON register
 operations
In-Reply-To: <1440379479-24308-1-git-send-email-shawn.lin@rock-chips.com>
References: <1440379479-24308-1-git-send-email-shawn.lin@rock-chips.com>
Message-ID: <1440379554-24444-1-git-send-email-shawn.lin@rock-chips.com>

This patch add some macros for HCON register operations
to make code more readable.

Signed-off-by: Shawn Lin <shawn.lin at rock-chips.com>
---

Changes in v7: None
Changes in v6: None
Changes in v5: None
Changes in v4: None
Changes in v3: None
Changes in v2: None

 drivers/mmc/host/dw_mmc.c | 6 +++---
 drivers/mmc/host/dw_mmc.h | 3 +++
 2 files changed, 6 insertions(+), 3 deletions(-)

diff --git a/drivers/mmc/host/dw_mmc.c b/drivers/mmc/host/dw_mmc.c
index 9c91983..0a3c63c 100644
--- a/drivers/mmc/host/dw_mmc.c
+++ b/drivers/mmc/host/dw_mmc.c
@@ -2678,7 +2678,7 @@ static void dw_mci_init_dma(struct dw_mci *host)
 		* Check ADDR_CONFIG bit in HCON to find
 		* IDMAC address bus width
 		*/
-		addr_config = (mci_readl(host, HCON) >> 27) & 0x01;
+		addr_config = SDMMC_GET_ADDR_CONFIG(mci_readl(host, HCON));
 
 		if (addr_config == 1) {
 			/* host supports IDMAC in 64-bit address mode */
@@ -3060,7 +3060,7 @@ int dw_mci_probe(struct dw_mci *host)
 	 * Get the host data width - this assumes that HCON has been set with
 	 * the correct values.
 	 */
-	i = (mci_readl(host, HCON) >> 7) & 0x7;
+	i = SDMMC_GET_HDATA_WIDTH(mci_readl(host, HCON));
 	if (!i) {
 		host->push_data = dw_mci_push_data16;
 		host->pull_data = dw_mci_pull_data16;
@@ -3142,7 +3142,7 @@ int dw_mci_probe(struct dw_mci *host)
 	if (host->pdata->num_slots)
 		host->num_slots = host->pdata->num_slots;
 	else
-		host->num_slots = ((mci_readl(host, HCON) >> 1) & 0x1F) + 1;
+		host->num_slots = SDMMC_GET_SLOT_NUM(mci_readl(host, HCON));
 
 	/*
 	 * Enable interrupts for command done, data over, data empty,
diff --git a/drivers/mmc/host/dw_mmc.h b/drivers/mmc/host/dw_mmc.h
index 811d467..f2a88d4 100644
--- a/drivers/mmc/host/dw_mmc.h
+++ b/drivers/mmc/host/dw_mmc.h
@@ -154,6 +154,9 @@
 #define DMA_INTERFACE_GDMA		(0x2)
 #define DMA_INTERFACE_NODMA		(0x3)
 #define SDMMC_GET_TRANS_MODE(x)		(((x)>>16) & 0x3)
+#define SDMMC_GET_SLOT_NUM(x)		((((x)>>1) & 0x1F) + 1)
+#define SDMMC_GET_HDATA_WIDTH(x)	(((x)>>7) & 0x7)
+#define SDMMC_GET_ADDR_CONFIG(x)	(((x)>>27) & 0x1)
 /* Internal DMAC interrupt defines */
 #define SDMMC_IDMAC_INT_AI		BIT(9)
 #define SDMMC_IDMAC_INT_NI		BIT(8)
-- 
2.3.7




From shawn.lin at rock-chips.com  Sun Aug 23 18:24:39 2015
From: shawn.lin at rock-chips.com (Shawn Lin)
Date: Mon, 24 Aug 2015 09:24:39 +0800
Subject: [RFC PATCH v7 0/10] Add external dma support for Synopsys MSHC
Message-ID: <1440379479-24308-1-git-send-email-shawn.lin@rock-chips.com>


Synopsys DesignWare mobile storage host controller supports three
types of transfer mode: pio, internal dma and external dma. However,
dw_mmc can only supports pio and internal dma now. Thus some platforms
using dw-mshc integrated with generic dma can't work in dma mode. So we
submit this patch to achieve it.

And the config option, CONFIG_MMC_DW_IDMAC, was added by Will Newton
(commit:f95f3850) for the first version of dw_mmc and never be touched since
then. At that time dt-bindings hadn't been introduced into dw_mmc yet means
we should select CONFIG_MMC_DW_IDMAC to enable internal dma mode at compile
time. Nowadays, device-tree helps us to support a variety of boards with one
kernel. That's why we need to remove it and decide the transfer mode by reading
dw_mmc's HCON reg at runtime.

This RFC patch needs lots of ACKs. I know it's hard, but it does need someone
to make the running.

Patch does the following things:
- remove CONFIG_MMC_DW_IDMAC config option
- add bindings for edmac used by synopsys-dw-mshc
  at runtime
- add edmac support for synopsys-dw-mshc

Patch is based on next of git://git.linaro.org/people/ulf.hansson/mmc

Test emmc throughput on my platform with edmac support and without edmac support(pio only)
iozone -L64 -S32 -azecwI -+n -r4k -r64k -r128k -s1g -i0 -i1 -i2 -f datafile -Rb out.xls > /mnt/result.txt
(light cpu loading, Direct IO, fixed line size, all pattern recycle, 1GB data in total)
 ___________________________________________________________
|                   external dma mode                       |
|-----------------------------------------------------------|
|blksz | Random Read | Random Write | Seq Read   | Seq Write|
|-----------------------------------------------------------|
|4kB   |  13953kB/s  |    8602kB/s  | 13672kB/s  |  9785kB/s|
|-----------------------------------------------------------|
|64kB  |  46058kB/s  |   24794kB/s  | 48058kB/s  | 25418kB/s|
|-----------------------------------------------------------|
|128kB |  57026kB/s  |   35117kB/s  | 57375kB/s  | 35183kB/s|
|-----------------------------------------------------------|
                           VS
 ___________________________________________________________
|                          pio mode                         |
|-----------------------------------------------------------|
|blksz | Random Read  | Random Write | Seq Read  | Seq Write|
|-----------------------------------------------------------|
|4kB   |  11720kB/s   |    8644kB/s  | 11549kB/s |  9624kB/s|
|-----------------------------------------------------------|
|64kB  |  21869kB/s   |   24414kB/s  | 22031kB/s | 27986kB/s|
|-----------------------------------------------------------|
|128kB |  23718kB/s   |   34495kB/s  | 24698kB/s | 34637kB/s|
|-----------------------------------------------------------|


Changes in v7:
- rebased on Ulf's next
- combine condition state
- elaborate more about DMA_INTERFACE
- define some macro for DMA_INERFACE value
- spilt HCON ops' changes into another patch

Changes in v6:
- add trans_mode condition for IDMAC initialization
  suggested by Heiko
- re-test my patch on rk3188 platform and update commit msg
- update performance of pio vs edmac in cover letter

Changes in v5:
- add the title of cover letter
- fix typo of comment
- add macro for reading HCON register
- add "Acked-by: Krzysztof Kozlowski <k.kozlowski at samsung.com>" for exynos_defconfig patch
- add "Acked-by: Vineet Gupta <vgupta at synopsys.com>" for axs10x_defconfig patch
- add "Acked-by: Govindraj Raja <govindraj.raja at imgtec.com>" and
  "Acked-by: Ralf Baechle <ralf at linux-mips.org>" for pistachio_defconfig patch
- add "Acked-by: Joachim Eastwood <manabian at gmail.com>" for lpc18xx_defconfig patch
- add "Acked-by: Wei Xu <xuwei5 at hisilicon.com>" for hisi_defconfig patch
- rebase on "https://github.com/jh80chung/dw-mmc.git tags/dw-mmc-for-ulf-v4.2" for merging easily

Changes in v4:
- remove "host->trans_mode" and use "host->use_dma" to indicate
  transfer mode.
- remove all bt-bindings' changes since we don't need new properities.
- check transfer mode at runtime by reading HCON reg
- spilt defconfig changes for each sub-architecture
- fix the title of cover letter
- reuse some code for reducing code size

Changes in v3:
- choose transfer mode at runtime
- remove all CONFIG_MMC_DW_IDMAC config option
- add supports-idmac property for some platforms

Changes in v2:
- Fix typo of dev_info msg
- remove unused dmach from declaration of dw_mci_dma_slave

Shawn Lin (10):
  mmc: dw_mmc: Add external dma interface support
  mmc: dw_mmc: use macro for HCON register operations
  Documentation: synopsys-dw-mshc: add bindings for idmac and edmac
  mips: pistachio_defconfig: remove CONFIG_MMC_DW_IDMAC
  arc: axs10x_defconfig: remove CONFIG_MMC_DW_IDMAC
  arm: exynos_defconfig: remove CONFIG_MMC_DW_IDMAC
  arm: hisi_defconfig: remove CONFIG_MMC_DW_IDMAC
  arm: lpc18xx_defconfig: remove CONFIG_MMC_DW_IDMAC
  arm: multi_v7_defconfig: remove CONFIG_MMC_DW_IDMAC
  arm: zx_defconfig: remove CONFIG_MMC_DW_IDMAC

 .../devicetree/bindings/mmc/synopsys-dw-mshc.txt   |  25 ++
 arch/arc/configs/axs101_defconfig                  |   1 -
 arch/arc/configs/axs103_defconfig                  |   1 -
 arch/arc/configs/axs103_smp_defconfig              |   1 -
 arch/arm/configs/exynos_defconfig                  |   1 -
 arch/arm/configs/hisi_defconfig                    |   1 -
 arch/arm/configs/lpc18xx_defconfig                 |   1 -
 arch/arm/configs/multi_v7_defconfig                |   1 -
 arch/arm/configs/zx_defconfig                      |   1 -
 arch/mips/configs/pistachio_defconfig              |   1 -
 drivers/mmc/host/Kconfig                           |  11 +-
 drivers/mmc/host/dw_mmc-pltfm.c                    |   2 +
 drivers/mmc/host/dw_mmc.c                          | 277 +++++++++++++++++----
 drivers/mmc/host/dw_mmc.h                          |   9 +
 include/linux/mmc/dw_mmc.h                         |  23 +-
 15 files changed, 283 insertions(+), 73 deletions(-)

-- 
2.3.7




From shawn.lin at rock-chips.com  Sun Aug 23 18:26:19 2015
From: shawn.lin at rock-chips.com (Shawn Lin)
Date: Mon, 24 Aug 2015 09:26:19 +0800
Subject: [RFC PATCH v7 03/10] Documentation: synopsys-dw-mshc: add bindings
 for idmac and edmac
In-Reply-To: <1440379479-24308-1-git-send-email-shawn.lin@rock-chips.com>
References: <1440379479-24308-1-git-send-email-shawn.lin@rock-chips.com>
Message-ID: <1440379579-24485-1-git-send-email-shawn.lin@rock-chips.com>

synopsys-dw-mshc supports three types of transfer mode. We add
bindings and description for how to use them at runtime.

Signed-off-by: Shawn Lin <shawn.lin at rock-chips.com>
---

Changes in v7: None
Changes in v6: None
Changes in v5: None
Changes in v4: None
Changes in v3: None
Changes in v2: None

 .../devicetree/bindings/mmc/synopsys-dw-mshc.txt   | 25 ++++++++++++++++++++++
 1 file changed, 25 insertions(+)

diff --git a/Documentation/devicetree/bindings/mmc/synopsys-dw-mshc.txt b/Documentation/devicetree/bindings/mmc/synopsys-dw-mshc.txt
index 346c609..8636f5a 100644
--- a/Documentation/devicetree/bindings/mmc/synopsys-dw-mshc.txt
+++ b/Documentation/devicetree/bindings/mmc/synopsys-dw-mshc.txt
@@ -75,6 +75,12 @@ Optional properties:
 * vmmc-supply: The phandle to the regulator to use for vmmc.  If this is
   specified we'll defer probe until we can find this regulator.
 
+* dmas: List of DMA specifiers with the controller specific format as described
+  in the generic DMA client binding. Refer to dma.txt for details.
+
+* dma-names: request names for generic DMA client binding. Must be "rx-tx".
+  Refer to dma.txt for details.
+
 Aliases:
 
 - All the MSHC controller nodes should be represented in the aliases node using
@@ -95,6 +101,23 @@ board specific portions as listed below.
 		#size-cells = <0>;
 	};
 
+[board specific internal DMA resources]
+
+	dwmmc0 at 12200000 {
+		clock-frequency = <400000000>;
+		clock-freq-min-max = <400000 200000000>;
+		num-slots = <1>;
+		broken-cd;
+		fifo-depth = <0x80>;
+		card-detect-delay = <200>;
+		vmmc-supply = <&buck8>;
+		bus-width = <8>;
+		cap-mmc-highspeed;
+		cap-sd-highspeed;
+	};
+
+[board specific generic DMA request binding]
+
 	dwmmc0 at 12200000 {
 		clock-frequency = <400000000>;
 		clock-freq-min-max = <400000 200000000>;
@@ -106,4 +129,6 @@ board specific portions as listed below.
 		bus-width = <8>;
 		cap-mmc-highspeed;
 		cap-sd-highspeed;
+		dmas = <&pdma 12>;
+		dma-names = "rx-tx";
 	};
-- 
2.3.7




From shawn.lin at rock-chips.com  Sun Aug 23 18:26:32 2015
From: shawn.lin at rock-chips.com (Shawn Lin)
Date: Mon, 24 Aug 2015 09:26:32 +0800
Subject: [RFC PATCH v7 04/10] mips: pistachio_defconfig: remove
 CONFIG_MMC_DW_IDMAC
In-Reply-To: <1440379479-24308-1-git-send-email-shawn.lin@rock-chips.com>
References: <1440379479-24308-1-git-send-email-shawn.lin@rock-chips.com>
Message-ID: <1440379592-24528-1-git-send-email-shawn.lin@rock-chips.com>

DesignWare MMC Controller's transfer mode should be decided
at runtime instead of compile-time. So we remove this config
option and read dw_mmc's register to select DMA master.

Signed-off-by: Shawn Lin <shawn.lin at rock-chips.com>
Acked-by: Govindraj Raja <govindraj.raja at imgtec.com>
Acked-by: Ralf Baechle <ralf at linux-mips.org>
---

Changes in v7: None
Changes in v6: None
Changes in v5: None
Changes in v4: None
Changes in v3: None
Changes in v2: None

 arch/mips/configs/pistachio_defconfig | 1 -
 1 file changed, 1 deletion(-)

diff --git a/arch/mips/configs/pistachio_defconfig b/arch/mips/configs/pistachio_defconfig
index 1646cce..013c62c 100644
--- a/arch/mips/configs/pistachio_defconfig
+++ b/arch/mips/configs/pistachio_defconfig
@@ -257,7 +257,6 @@ CONFIG_MMC=y
 CONFIG_MMC_BLOCK_MINORS=16
 CONFIG_MMC_TEST=m
 CONFIG_MMC_DW=y
-CONFIG_MMC_DW_IDMAC=y
 CONFIG_NEW_LEDS=y
 CONFIG_LEDS_CLASS=y
 CONFIG_RTC_CLASS=y
-- 
2.3.7




From shawn.lin at rock-chips.com  Sun Aug 23 18:26:45 2015
From: shawn.lin at rock-chips.com (Shawn Lin)
Date: Mon, 24 Aug 2015 09:26:45 +0800
Subject: [RFC PATCH v7 05/10] arc: axs10x_defconfig: remove CONFIG_MMC_DW_IDMAC
In-Reply-To: <1440379479-24308-1-git-send-email-shawn.lin@rock-chips.com>
References: <1440379479-24308-1-git-send-email-shawn.lin@rock-chips.com>
Message-ID: <1440379605-24585-1-git-send-email-shawn.lin@rock-chips.com>

DesignWare MMC Controller's transfer mode should be decided
at runtime instead of compile-time. So we remove this config
option and read dw_mmc's register to select DMA master.

Signed-off-by: Shawn Lin <shawn.lin at rock-chips.com>
Acked-by: Vineet Gupta <vgupta at synopsys.com>
---

Changes in v7: None
Changes in v6: None
Changes in v5: None
Changes in v4: None
Changes in v3: None
Changes in v2: None

 arch/arc/configs/axs101_defconfig     | 1 -
 arch/arc/configs/axs103_defconfig     | 1 -
 arch/arc/configs/axs103_smp_defconfig | 1 -
 3 files changed, 3 deletions(-)

diff --git a/arch/arc/configs/axs101_defconfig b/arch/arc/configs/axs101_defconfig
index 562dac6..c92c0ef 100644
--- a/arch/arc/configs/axs101_defconfig
+++ b/arch/arc/configs/axs101_defconfig
@@ -89,7 +89,6 @@ CONFIG_MMC=y
 CONFIG_MMC_SDHCI=y
 CONFIG_MMC_SDHCI_PLTFM=y
 CONFIG_MMC_DW=y
-CONFIG_MMC_DW_IDMAC=y
 # CONFIG_IOMMU_SUPPORT is not set
 CONFIG_EXT3_FS=y
 CONFIG_EXT4_FS=y
diff --git a/arch/arc/configs/axs103_defconfig b/arch/arc/configs/axs103_defconfig
index 83a6d8d..cfac24e 100644
--- a/arch/arc/configs/axs103_defconfig
+++ b/arch/arc/configs/axs103_defconfig
@@ -95,7 +95,6 @@ CONFIG_MMC=y
 CONFIG_MMC_SDHCI=y
 CONFIG_MMC_SDHCI_PLTFM=y
 CONFIG_MMC_DW=y
-CONFIG_MMC_DW_IDMAC=y
 # CONFIG_IOMMU_SUPPORT is not set
 CONFIG_EXT3_FS=y
 CONFIG_EXT4_FS=y
diff --git a/arch/arc/configs/axs103_smp_defconfig b/arch/arc/configs/axs103_smp_defconfig
index f1e1c84..9922a11 100644
--- a/arch/arc/configs/axs103_smp_defconfig
+++ b/arch/arc/configs/axs103_smp_defconfig
@@ -96,7 +96,6 @@ CONFIG_MMC=y
 CONFIG_MMC_SDHCI=y
 CONFIG_MMC_SDHCI_PLTFM=y
 CONFIG_MMC_DW=y
-CONFIG_MMC_DW_IDMAC=y
 # CONFIG_IOMMU_SUPPORT is not set
 CONFIG_EXT3_FS=y
 CONFIG_EXT4_FS=y
-- 
2.3.7




From shawn.lin at rock-chips.com  Sun Aug 23 18:27:00 2015
From: shawn.lin at rock-chips.com (Shawn Lin)
Date: Mon, 24 Aug 2015 09:27:00 +0800
Subject: [RFC PATCH v7 06/10] arm: exynos_defconfig: remove CONFIG_MMC_DW_IDMAC
In-Reply-To: <1440379479-24308-1-git-send-email-shawn.lin@rock-chips.com>
References: <1440379479-24308-1-git-send-email-shawn.lin@rock-chips.com>
Message-ID: <1440379620-24638-1-git-send-email-shawn.lin@rock-chips.com>

DesignWare MMC Controller's transfer mode should be decided
at runtime instead of compile-time. So we remove this config
option and read dw_mmc's register to select DMA master.

Signed-off-by: Shawn Lin <shawn.lin at rock-chips.com>
Acked-by: Krzysztof Kozlowski <k.kozlowski at samsung.com>
---

Changes in v7: None
Changes in v6: None
Changes in v5: None
Changes in v4: None
Changes in v3: None
Changes in v2: None

 arch/arm/configs/exynos_defconfig | 1 -
 1 file changed, 1 deletion(-)

diff --git a/arch/arm/configs/exynos_defconfig b/arch/arm/configs/exynos_defconfig
index 9504e77..7e4af6e 100644
--- a/arch/arm/configs/exynos_defconfig
+++ b/arch/arm/configs/exynos_defconfig
@@ -161,7 +161,6 @@ CONFIG_MMC_SDHCI=y
 CONFIG_MMC_SDHCI_S3C=y
 CONFIG_MMC_SDHCI_S3C_DMA=y
 CONFIG_MMC_DW=y
-CONFIG_MMC_DW_IDMAC=y
 CONFIG_MMC_DW_EXYNOS=y
 CONFIG_RTC_CLASS=y
 CONFIG_RTC_DRV_MAX77686=y
-- 
2.3.7




From shawn.lin at rock-chips.com  Sun Aug 23 18:27:12 2015
From: shawn.lin at rock-chips.com (Shawn Lin)
Date: Mon, 24 Aug 2015 09:27:12 +0800
Subject: [RFC PATCH v7 07/10] arm: hisi_defconfig: remove CONFIG_MMC_DW_IDMAC
In-Reply-To: <1440379479-24308-1-git-send-email-shawn.lin@rock-chips.com>
References: <1440379479-24308-1-git-send-email-shawn.lin@rock-chips.com>
Message-ID: <1440379632-24679-1-git-send-email-shawn.lin@rock-chips.com>

DesignWare MMC Controller's transfer mode should be decided
at runtime instead of compile-time. So we remove this config
option and read dw_mmc's register to select DMA master.

Signed-off-by: Shawn Lin <shawn.lin at rock-chips.com>
Acked-by: Wei Xu <xuwei5 at hisilicon.com>
---

Changes in v7: None
Changes in v6: None
Changes in v5: None
Changes in v4: None
Changes in v3: None
Changes in v2: None

 arch/arm/configs/hisi_defconfig | 1 -
 1 file changed, 1 deletion(-)

diff --git a/arch/arm/configs/hisi_defconfig b/arch/arm/configs/hisi_defconfig
index 5997dbc..b2e340b 100644
--- a/arch/arm/configs/hisi_defconfig
+++ b/arch/arm/configs/hisi_defconfig
@@ -69,7 +69,6 @@ CONFIG_NOP_USB_XCEIV=y
 CONFIG_MMC=y
 CONFIG_RTC_CLASS=y
 CONFIG_MMC_DW=y
-CONFIG_MMC_DW_IDMAC=y
 CONFIG_MMC_DW_PLTFM=y
 CONFIG_RTC_DRV_PL031=y
 CONFIG_DMADEVICES=y
-- 
2.3.7




From shawn.lin at rock-chips.com  Sun Aug 23 18:27:26 2015
From: shawn.lin at rock-chips.com (Shawn Lin)
Date: Mon, 24 Aug 2015 09:27:26 +0800
Subject: [RFC PATCH v7 08/10] arm: lpc18xx_defconfig: remove
 CONFIG_MMC_DW_IDMAC
In-Reply-To: <1440379479-24308-1-git-send-email-shawn.lin@rock-chips.com>
References: <1440379479-24308-1-git-send-email-shawn.lin@rock-chips.com>
Message-ID: <1440379646-24722-1-git-send-email-shawn.lin@rock-chips.com>

DesignWare MMC Controller's transfer mode should be decided
at runtime instead of compile-time. So we remove this config
option and read dw_mmc's register to select DMA master.

Signed-off-by: Shawn Lin <shawn.lin at rock-chips.com>
Acked-by: Joachim Eastwood <manabian at gmail.com>
---

Changes in v7: None
Changes in v6: None
Changes in v5: None
Changes in v4: None
Changes in v3: None
Changes in v2: None

 arch/arm/configs/lpc18xx_defconfig | 1 -
 1 file changed, 1 deletion(-)

diff --git a/arch/arm/configs/lpc18xx_defconfig b/arch/arm/configs/lpc18xx_defconfig
index 1c47f86..b7e8cda 100644
--- a/arch/arm/configs/lpc18xx_defconfig
+++ b/arch/arm/configs/lpc18xx_defconfig
@@ -119,7 +119,6 @@ CONFIG_USB_EHCI_HCD=y
 CONFIG_USB_EHCI_ROOT_HUB_TT=y
 CONFIG_MMC=y
 CONFIG_MMC_DW=y
-CONFIG_MMC_DW_IDMAC=y
 CONFIG_NEW_LEDS=y
 CONFIG_LEDS_CLASS=y
 CONFIG_LEDS_PCA9532=y
-- 
2.3.7




From shawn.lin at rock-chips.com  Sun Aug 23 18:27:43 2015
From: shawn.lin at rock-chips.com (Shawn Lin)
Date: Mon, 24 Aug 2015 09:27:43 +0800
Subject: [RFC PATCH v7 09/10] arm: multi_v7_defconfig: remove
 CONFIG_MMC_DW_IDMAC
In-Reply-To: <1440379479-24308-1-git-send-email-shawn.lin@rock-chips.com>
References: <1440379479-24308-1-git-send-email-shawn.lin@rock-chips.com>
Message-ID: <1440379663-24767-1-git-send-email-shawn.lin@rock-chips.com>

DesignWare MMC Controller's transfer mode should be decided
at runtime instead of compile-time. So we remove this config
option and read dw_mmc's register to select DMA master.

Signed-off-by: Shawn Lin <shawn.lin at rock-chips.com>
---

Changes in v7: None
Changes in v6: None
Changes in v5: None
Changes in v4: None
Changes in v3: None
Changes in v2: None

 arch/arm/configs/multi_v7_defconfig | 1 -
 1 file changed, 1 deletion(-)

diff --git a/arch/arm/configs/multi_v7_defconfig b/arch/arm/configs/multi_v7_defconfig
index 5fd8df6..a3734b5 100644
--- a/arch/arm/configs/multi_v7_defconfig
+++ b/arch/arm/configs/multi_v7_defconfig
@@ -520,7 +520,6 @@ CONFIG_MMC_ATMELMCI=y
 CONFIG_MMC_MVSDIO=y
 CONFIG_MMC_SDHI=y
 CONFIG_MMC_DW=y
-CONFIG_MMC_DW_IDMAC=y
 CONFIG_MMC_DW_PLTFM=y
 CONFIG_MMC_DW_EXYNOS=y
 CONFIG_MMC_DW_ROCKCHIP=y
-- 
2.3.7




From shawn.lin at rock-chips.com  Sun Aug 23 18:28:04 2015
From: shawn.lin at rock-chips.com (Shawn Lin)
Date: Mon, 24 Aug 2015 09:28:04 +0800
Subject: [RFC PATCH v7 10/10] arm: zx_defconfig: remove CONFIG_MMC_DW_IDMAC
In-Reply-To: <1440379479-24308-1-git-send-email-shawn.lin@rock-chips.com>
References: <1440379479-24308-1-git-send-email-shawn.lin@rock-chips.com>
Message-ID: <1440379684-24811-1-git-send-email-shawn.lin@rock-chips.com>

DesignWare MMC Controller's transfer mode should be decided
at runtime instead of compile-time. So we remove this config
option and read dw_mmc's register to select DMA master.

Signed-off-by: Shawn Lin <shawn.lin at rock-chips.com>
---

Changes in v7: None
Changes in v6: None
Changes in v5: None
Changes in v4: None
Changes in v3: None
Changes in v2: None

 arch/arm/configs/zx_defconfig | 1 -
 1 file changed, 1 deletion(-)

diff --git a/arch/arm/configs/zx_defconfig b/arch/arm/configs/zx_defconfig
index b200bb0..ab683fb 100644
--- a/arch/arm/configs/zx_defconfig
+++ b/arch/arm/configs/zx_defconfig
@@ -83,7 +83,6 @@ CONFIG_MMC=y
 CONFIG_MMC_UNSAFE_RESUME=y
 CONFIG_MMC_BLOCK_MINORS=16
 CONFIG_MMC_DW=y
-CONFIG_MMC_DW_IDMAC=y
 CONFIG_EXT2_FS=y
 CONFIG_EXT4_FS=y
 CONFIG_EXT4_FS_POSIX_ACL=y
-- 
2.3.7




From yamada.masahiro at socionext.com  Sun Aug 23 19:18:09 2015
From: yamada.masahiro at socionext.com (Masahiro Yamada)
Date: Mon, 24 Aug 2015 11:18:09 +0900
Subject: [PATCH 0/3] ARM: uniphier: add outer cache support and rework SMP
 operations
Message-ID: <1440382692-3855-1-git-send-email-yamada.masahiro@socionext.com>

1/3: add outer cache support
2/3: rework SMP operations
3/3: add device tree nodes

Because 2/3 highly depends on 1/3, I hope whole of this series
is applied to ARM-SOC tree.

Olof,
>From this series, I am using "ARM: uniphier:" rather than "ARM: UniPhier:"
for the subject prefixes because I noticed you often rephased so when you
applied my patches.
Are sub-arch names in lower cases preferable in subject prefixes?



Masahiro Yamada (3):
  ARM: uniphier: add outer cache support
  ARM: uniphier: rework SMP operations to use trampoline code
  ARM: dts: uniphier: add outer cache controller nodes

 .../bindings/arm/uniphier/cache-uniphier.txt       |  30 ++
 MAINTAINERS                                        |   2 +
 arch/arm/boot/dts/uniphier-ph1-ld4.dtsi            |   7 +
 arch/arm/boot/dts/uniphier-ph1-pro4.dtsi           |   7 +
 arch/arm/boot/dts/uniphier-ph1-pro5.dtsi           |  14 +
 arch/arm/boot/dts/uniphier-ph1-sld3.dtsi           |   7 +
 arch/arm/boot/dts/uniphier-ph1-sld8.dtsi           |   7 +
 arch/arm/boot/dts/uniphier-proxstream2.dtsi        |   7 +
 arch/arm/include/asm/hardware/cache-uniphier.h     |  40 ++
 arch/arm/mach-uniphier/Makefile                    |   2 +-
 arch/arm/mach-uniphier/headsmp.S                   |  43 ++
 arch/arm/mach-uniphier/platsmp.c                   | 183 ++++++--
 arch/arm/mach-uniphier/uniphier.c                  |  11 +
 arch/arm/mm/Kconfig                                |  10 +
 arch/arm/mm/Makefile                               |   1 +
 arch/arm/mm/cache-uniphier.c                       | 518 +++++++++++++++++++++
 16 files changed, 857 insertions(+), 32 deletions(-)
 create mode 100644 Documentation/devicetree/bindings/arm/uniphier/cache-uniphier.txt
 create mode 100644 arch/arm/include/asm/hardware/cache-uniphier.h
 create mode 100644 arch/arm/mach-uniphier/headsmp.S
 create mode 100644 arch/arm/mm/cache-uniphier.c

-- 
1.9.1



From yamada.masahiro at socionext.com  Sun Aug 23 19:18:12 2015
From: yamada.masahiro at socionext.com (Masahiro Yamada)
Date: Mon, 24 Aug 2015 11:18:12 +0900
Subject: [PATCH 3/3] ARM: dts: uniphier: add outer cache controller nodes
In-Reply-To: <1440382692-3855-1-git-send-email-yamada.masahiro@socionext.com>
References: <1440382692-3855-1-git-send-email-yamada.masahiro@socionext.com>
Message-ID: <1440382692-3855-4-git-send-email-yamada.masahiro@socionext.com>

Add L2 cache controller nodes for all the UniPhier SoC DTSI.
Also, add an L3 cache controller node for PH1-Pro5 DTSI.

Signed-off-by: Masahiro Yamada <yamada.masahiro at socionext.com>
---

 arch/arm/boot/dts/uniphier-ph1-ld4.dtsi     |  7 +++++++
 arch/arm/boot/dts/uniphier-ph1-pro4.dtsi    |  7 +++++++
 arch/arm/boot/dts/uniphier-ph1-pro5.dtsi    | 14 ++++++++++++++
 arch/arm/boot/dts/uniphier-ph1-sld3.dtsi    |  7 +++++++
 arch/arm/boot/dts/uniphier-ph1-sld8.dtsi    |  7 +++++++
 arch/arm/boot/dts/uniphier-proxstream2.dtsi |  7 +++++++
 6 files changed, 49 insertions(+)

diff --git a/arch/arm/boot/dts/uniphier-ph1-ld4.dtsi b/arch/arm/boot/dts/uniphier-ph1-ld4.dtsi
index a6a185f..2d60960 100644
--- a/arch/arm/boot/dts/uniphier-ph1-ld4.dtsi
+++ b/arch/arm/boot/dts/uniphier-ph1-ld4.dtsi
@@ -91,6 +91,13 @@
 			#size-cells = <1>;
 		};
 
+		l2-cache at 500c0000 {
+			compatible = "socionext,uniphier-l2-cache";
+			reg = <0x500c0000 0x2000>, <0x503c0100 0x4>,
+			      <0x506c0000 0x400>;
+			interrupts = <0 174 4>, <0 175 4>;
+		};
+
 		serial0: serial at 54006800 {
 			compatible = "socionext,uniphier-uart";
 			status = "disabled";
diff --git a/arch/arm/boot/dts/uniphier-ph1-pro4.dtsi b/arch/arm/boot/dts/uniphier-ph1-pro4.dtsi
index e8bbc45..02acc07 100644
--- a/arch/arm/boot/dts/uniphier-ph1-pro4.dtsi
+++ b/arch/arm/boot/dts/uniphier-ph1-pro4.dtsi
@@ -98,6 +98,13 @@
 			#size-cells = <1>;
 		};
 
+		l2-cache at 500c0000 {
+			compatible = "socionext,uniphier-l2-cache";
+			reg = <0x500c0000 0x2000>, <0x503c0100 0x4>,
+			      <0x506c0000 0x400>;
+			interrupts = <0 174 4>, <0 175 4>;
+		};
+
 		serial0: serial at 54006800 {
 			compatible = "socionext,uniphier-uart";
 			status = "disabled";
diff --git a/arch/arm/boot/dts/uniphier-ph1-pro5.dtsi b/arch/arm/boot/dts/uniphier-ph1-pro5.dtsi
index 59c2b12..084bc47 100644
--- a/arch/arm/boot/dts/uniphier-ph1-pro5.dtsi
+++ b/arch/arm/boot/dts/uniphier-ph1-pro5.dtsi
@@ -98,6 +98,20 @@
 			#size-cells = <1>;
 		};
 
+		l2-cache at 500c0000 {
+			compatible = "socionext,uniphier-l2-cache";
+			reg = <0x500c0000 0x2000>, <0x503c0100 0x8>,
+			      <0x506c0000 0x400>;
+			interrupts = <0 190 4>, <0 191 4>;
+		};
+
+		l3-cache at 500c8000 {
+			compatible = "socionext,uniphier-l3-cache";
+			reg = <0x500c8000 0x2000>, <0x503c8100 0x8>,
+			      <0x506c8000 0x400>;
+			interrupts = <0 174 4>, <0 175 4>;
+		};
+
 		serial0: serial at 54006800 {
 			compatible = "socionext,uniphier-uart";
 			status = "disabled";
diff --git a/arch/arm/boot/dts/uniphier-ph1-sld3.dtsi b/arch/arm/boot/dts/uniphier-ph1-sld3.dtsi
index 3cc90cd..e989281 100644
--- a/arch/arm/boot/dts/uniphier-ph1-sld3.dtsi
+++ b/arch/arm/boot/dts/uniphier-ph1-sld3.dtsi
@@ -120,6 +120,13 @@
 			      <0x20000100 0x100>;
 		};
 
+		l2-cache at 500c0000 {
+			compatible = "socionext,uniphier-l2-cache";
+			reg = <0x500c0000 0x2000>, <0x503c0100 0x4>,
+			      <0x506c0000 0x400>;
+			interrupts = <0 174 4>, <0 175 4>;
+		};
+
 		serial0: serial at 54006800 {
 			compatible = "socionext,uniphier-uart";
 			status = "disabled";
diff --git a/arch/arm/boot/dts/uniphier-ph1-sld8.dtsi b/arch/arm/boot/dts/uniphier-ph1-sld8.dtsi
index 58067df..3ff897c 100644
--- a/arch/arm/boot/dts/uniphier-ph1-sld8.dtsi
+++ b/arch/arm/boot/dts/uniphier-ph1-sld8.dtsi
@@ -91,6 +91,13 @@
 			#size-cells = <1>;
 		};
 
+		l2-cache at 500c0000 {
+			compatible = "socionext,uniphier-l2-cache";
+			reg = <0x500c0000 0x2000>, <0x503c0100 0x4>,
+			      <0x506c0000 0x400>;
+			interrupts = <0 174 4>, <0 175 4>;
+		};
+
 		serial0: serial at 54006800 {
 			compatible = "socionext,uniphier-uart";
 			status = "disabled";
diff --git a/arch/arm/boot/dts/uniphier-proxstream2.dtsi b/arch/arm/boot/dts/uniphier-proxstream2.dtsi
index 4c7b246..f318548 100644
--- a/arch/arm/boot/dts/uniphier-proxstream2.dtsi
+++ b/arch/arm/boot/dts/uniphier-proxstream2.dtsi
@@ -110,6 +110,13 @@
 			#size-cells = <1>;
 		};
 
+		l2-cache at 500c0000 {
+			compatible = "socionext,uniphier-l2-cache";
+			reg = <0x500c0000 0x2000>, <0x503c0100 0x4>,
+			      <0x506c0000 0x400>;
+			interrupts = <0 174 4>, <0 175 4>, <0 190 4>, <0 191 4>;
+		};
+
 		serial0: serial at 54006800 {
 			compatible = "socionext,uniphier-uart";
 			status = "disabled";
-- 
1.9.1



From yamada.masahiro at socionext.com  Sun Aug 23 19:18:11 2015
From: yamada.masahiro at socionext.com (Masahiro Yamada)
Date: Mon, 24 Aug 2015 11:18:11 +0900
Subject: [PATCH 2/3] ARM: uniphier: rework SMP operations to use trampoline
 code
In-Reply-To: <1440382692-3855-1-git-send-email-yamada.masahiro@socionext.com>
References: <1440382692-3855-1-git-send-email-yamada.masahiro@socionext.com>
Message-ID: <1440382692-3855-3-git-send-email-yamada.masahiro@socionext.com>

The complexity of the boot sequence of UniPhier SoC family is
a PITA due to the following hardware limitations:

[1] No dedicated on-chip SRAM
SoCs in general have small SRAM, on which a tiny firmware or a boot
loader can run before SDRAM is initialized.  As UniPhier SoCs do not
have any dedicated SRAM accessible from CPUs, the locked outer cache
is used instead.  Due to the ARM specification, to have access to
the outer cache, the MMU must be enabled.  This is done for all CPU
cores by the program hard-wired in the boot ROM.  The boot ROM code
loads a small amount of program (this is usually SPL of U-Boot) from
a non-volatile device onto the locked outer cache, and the primary
CPU jumps to it.  The secondary CPUs stay in the boot ROM until they
are kicked by the primary CPU.

[2] CPUs can not directly jump to SDRAM address space
As mentioned above, the MMU is enable for all the CPUs with the page
table hard-wired in the boot ROM.  Unfortunately, the page table only
has minimal sets of valid sections; all the sections of SDRAM address
space are zero-filled.  That means all the CPUs, including secondary
ones, can not jump directly to SDRAM address space.  So, the primary
CPU must bring up secondary CPUs to accessible address mapped onto
the outer cache, then again kick them to SDRAM address space.

Before this commit, this complex task was done with help of a boot
loader (U-Boot); U-Boot SPL brings up the secondary CPUs to the entry
of U-Boot SPL and they stay there until they are kicked by Linux.
This is not nice because a boot loader must put the secondary CPUs
into a certain state the kernel expects.  It makes difficult to port
another boot loader because the boot loader and the kernel must work
in sync to wake up the secondary CPUs.

This commit reworks the SMP operations without any help of the boot
loader; the SMP operations (mach-uniphier/platsmp.c) enables the
locked outer cache and puts trampoline code (mach-uniphier/headsmp.S)
there.  The secondary CPUs jump from the boot ROM to secondary_entry
via the trampoline code.  The boot loader no longer need to take care
of SMP.

Signed-off-by: Masahiro Yamada <yamada.masahiro at socionext.com>
---

 arch/arm/mach-uniphier/Makefile   |   2 +-
 arch/arm/mach-uniphier/headsmp.S  |  43 +++++++++
 arch/arm/mach-uniphier/platsmp.c  | 183 +++++++++++++++++++++++++++++++-------
 arch/arm/mach-uniphier/uniphier.c |   2 +-
 4 files changed, 197 insertions(+), 33 deletions(-)
 create mode 100644 arch/arm/mach-uniphier/headsmp.S

diff --git a/arch/arm/mach-uniphier/Makefile b/arch/arm/mach-uniphier/Makefile
index 60bd226..1233f9b 100644
--- a/arch/arm/mach-uniphier/Makefile
+++ b/arch/arm/mach-uniphier/Makefile
@@ -1,2 +1,2 @@
 obj-y			:= uniphier.o
-obj-$(CONFIG_SMP)	+= platsmp.o
+obj-$(CONFIG_SMP)	+= platsmp.o headsmp.o
diff --git a/arch/arm/mach-uniphier/headsmp.S b/arch/arm/mach-uniphier/headsmp.S
new file mode 100644
index 0000000..c819dff
--- /dev/null
+++ b/arch/arm/mach-uniphier/headsmp.S
@@ -0,0 +1,43 @@
+/*
+ * Copyright (C) 2015 Masahiro Yamada <yamada.masahiro at socionext.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/linkage.h>
+#include <asm/assembler.h>
+#include <asm/cp15.h>
+
+ENTRY(uniphier_smp_trampoline)
+ARM_BE8(setend	be)			@ ensure we are in BE8 mode
+	mrc	p15, 0, r0, c0, c0, 5	@ MPIDR (Multiprocessor Affinity Reg)
+	and  	r2, r0, #0x3		@ CPU ID
+	ldr	r1, uniphier_smp_trampoline_jump
+	ldr	r3, uniphier_smp_trampoline_poll_addr
+	mrc	p15, 0, r0, c1, c0, 0	@ SCTLR (System Control Register)
+	orr	r0, r0, #CR_I		@ Enable ICache
+	bic	r0, r0, #(CR_C | CR_M)	@ Disable MMU and Dcache
+	mcr	p15, 0, r0, c1, c0, 0
+	b	1f			@ cache the following 5 instructions
+0:	wfe
+1:	ldr	r0, [r3]
+	cmp	r0, r2
+	bxeq	r1			@ branch to secondary_startup
+	b	0b
+	.globl	uniphier_smp_trampoline_jump
+uniphier_smp_trampoline_jump:
+	.word	0			@ set virt_to_phys(secondary_startup)
+	.globl	uniphier_smp_trampoline_poll_addr
+uniphier_smp_trampoline_poll_addr:
+	.word	0			@ set CPU ID to be kicked to this reg
+	.globl	uniphier_smp_trampoline_end
+uniphier_smp_trampoline_end:
+ENDPROC(uniphier_smp_trampoline)
diff --git a/arch/arm/mach-uniphier/platsmp.c b/arch/arm/mach-uniphier/platsmp.c
index 4b784f7..774dd5f 100644
--- a/arch/arm/mach-uniphier/platsmp.c
+++ b/arch/arm/mach-uniphier/platsmp.c
@@ -12,73 +12,194 @@
  * GNU General Public License for more details.
  */
 
-#include <linux/sizes.h>
-#include <linux/compiler.h>
 #include <linux/init.h>
 #include <linux/io.h>
-#include <linux/regmap.h>
-#include <linux/mfd/syscon.h>
+#include <linux/ioport.h>
+#include <linux/of.h>
+#include <linux/of_address.h>
+#include <linux/sizes.h>
+#include <asm/cacheflush.h>
+#include <asm/hardware/cache-uniphier.h>
+#include <asm/pgtable.h>
 #include <asm/smp.h>
 #include <asm/smp_scu.h>
 
-static struct regmap *sbcm_regmap;
+/*
+ * The secondary CPUs check this register from the boot ROM for the jump
+ * destination.  After that, it can be reused as a scratch register.
+ */
+#define UNIPHIER_SBC_ROM_BOOT_RSV2	0x1208
+
+static void __iomem *uniphier_smp_rom_boot_rsv2;
+static unsigned int uniphier_smp_max_cpus;
 
-static void __init uniphier_smp_prepare_cpus(unsigned int max_cpus)
+extern char uniphier_smp_trampoline;
+extern char uniphier_smp_trampoline_jump;
+extern char uniphier_smp_trampoline_poll_addr;
+extern char uniphier_smp_trampoline_end;
+
+/*
+ * Copy trampoline code to the tail of the 1st section of the page table used
+ * in the boot ROM.  This area is directly accessible by the secondary CPUs
+ * for all the UniPhier SoCs.
+ */
+static const phys_addr_t uniphier_smp_trampoline_dest_end = SECTION_SIZE;
+static phys_addr_t uniphier_smp_trampoline_dest;
+
+static int __init uniphier_smp_copy_trampoline(phys_addr_t poll_addr)
 {
-	static cpumask_t only_cpu_0 = { CPU_BITS_CPU0 };
-	unsigned long scu_base_phys = 0;
-	void __iomem *scu_base;
+	size_t trmp_size;
+	static void __iomem *trmp_base;
+	int ret;
 
-	sbcm_regmap = syscon_regmap_lookup_by_compatible(
-			"socionext,uniphier-system-bus-controller-misc");
-	if (IS_ERR(sbcm_regmap)) {
-		pr_err("failed to regmap system-bus-controller-misc\n");
-		goto err;
+	trmp_size = &uniphier_smp_trampoline_end - &uniphier_smp_trampoline;
+	uniphier_smp_trampoline_dest = uniphier_smp_trampoline_dest_end -
+								trmp_size;
+
+	ret = uniphier_cache_init_locked();
+	if (ret) {
+		pr_warn("uniphier: outer cache was not locked\n");
+		return ret;
+	}
+
+	uniphier_cache_touch_range(uniphier_smp_trampoline_dest,
+				   uniphier_smp_trampoline_dest_end);
+
+	trmp_base = ioremap_cache(uniphier_smp_trampoline_dest, trmp_size);
+	if (!trmp_base) {
+		pr_err("uniphier: failed to map trampoline destination\n");
+		return -ENOMEM;
+	}
+
+	memcpy(trmp_base, &uniphier_smp_trampoline, trmp_size);
+
+	writel(virt_to_phys(secondary_startup),
+	       trmp_base + (&uniphier_smp_trampoline_jump -
+			    &uniphier_smp_trampoline));
+
+	writel(poll_addr, trmp_base + (&uniphier_smp_trampoline_poll_addr -
+				       &uniphier_smp_trampoline));
+
+	flush_cache_all();
+
+	iounmap(trmp_base);
+
+	return 0;
+}
+
+static int __init uniphier_smp_prepare_trampoline(unsigned int max_cpus)
+{
+	struct device_node *np;
+	struct resource res;
+	phys_addr_t rom_rsv2_phys;
+	int ret;
+
+	np = of_find_compatible_node(NULL, NULL,
+				"socionext,uniphier-system-bus-controller");
+	ret = of_address_to_resource(np, 1, &res);
+	if (ret) {
+		pr_err("uniphier: failed to get resource of system-bus-controller\n");
+		return ret;
+	}
+
+	rom_rsv2_phys = res.start + UNIPHIER_SBC_ROM_BOOT_RSV2;
+
+	ret = uniphier_smp_copy_trampoline(rom_rsv2_phys);
+	if (ret)
+		return ret;
+
+	uniphier_smp_rom_boot_rsv2 = ioremap(rom_rsv2_phys, sizeof(SZ_4));
+	if (!uniphier_smp_rom_boot_rsv2) {
+		pr_err("uniphier: failed to map ROM_BOOT_RSV2 register\n");
+		return -ENOMEM;
 	}
 
+	writel(uniphier_smp_trampoline_dest, uniphier_smp_rom_boot_rsv2);
+	asm("sev"); /* Bring up all secondary CPUs to the trampoline code */
+
+	uniphier_smp_max_cpus = max_cpus;	/* save for later use */
+
+	return 0;
+}
+
+static void __init uniphier_smp_unprepare_trampoline(void)
+{
+	iounmap(uniphier_smp_rom_boot_rsv2);
+	/*
+	 * This should be always safe because uniphier_smp_trampoline_dest
+	 * has been set before outer_inv_range becomes effective.
+	 */
+	outer_inv_range(uniphier_smp_trampoline_dest,
+			uniphier_smp_trampoline_dest_end);
+}
+
+static int __init uniphier_smp_enable_scu(void)
+{
+	unsigned long scu_base_phys = 0;
+	void __iomem *scu_base;
+
 	if (scu_a9_has_base())
 		scu_base_phys = scu_a9_get_base();
 
 	if (!scu_base_phys) {
-		pr_err("failed to get scu base\n");
-		goto err;
+		pr_err("uniphier: failed to get scu base\n");
+		return -ENODEV;
 	}
 
 	scu_base = ioremap(scu_base_phys, SZ_128);
 	if (!scu_base) {
-		pr_err("failed to remap scu base (0x%08lx)\n", scu_base_phys);
-		goto err;
+		pr_err("uniphier: failed to map scu base\n");
+		return -ENOMEM;
 	}
 
 	scu_enable(scu_base);
 	iounmap(scu_base);
 
+	return 0;
+}
+
+static void __init uniphier_smp_prepare_cpus(unsigned int max_cpus)
+{
+	static cpumask_t only_cpu_0 = { CPU_BITS_CPU0 };
+	int ret;
+
+	ret = uniphier_smp_prepare_trampoline(max_cpus);
+	if (ret)
+		goto err;
+
+	ret = uniphier_smp_enable_scu();
+	if (ret)
+		goto err;
+
 	return;
 err:
-	pr_warn("disabling SMP\n");
+	pr_warn("uniphier: disabling SMP\n");
 	init_cpu_present(&only_cpu_0);
-	sbcm_regmap = NULL;
+	uniphier_smp_unprepare_trampoline();
 }
 
-static int uniphier_boot_secondary(unsigned int cpu,
-				   struct task_struct *idle)
+static int __init uniphier_smp_boot_secondary(unsigned int cpu,
+					      struct task_struct *idle)
 {
-	int ret;
+	if (!uniphier_smp_rom_boot_rsv2)
+		BUG();
 
-	if (!sbcm_regmap)
-		return -ENODEV;
+	writel(cpu, uniphier_smp_rom_boot_rsv2);
+	readl(uniphier_smp_rom_boot_rsv2); /* relax */
 
-	ret = regmap_write(sbcm_regmap, 0x1208,
-			   virt_to_phys(secondary_startup));
-	if (!ret)
-		asm("sev"); /* wake up secondary CPU */
+	asm("sev"); /* wake up secondary CPUs sleeping in the trampoline */
+
+	if (cpu == uniphier_smp_max_cpus - 1) {
+		/* clean up resources if this is the last CPU */
+		uniphier_smp_unprepare_trampoline();
+	}
 
-	return ret;
+	return 0;
 }
 
 struct smp_operations uniphier_smp_ops __initdata = {
 	.smp_prepare_cpus	= uniphier_smp_prepare_cpus,
-	.smp_boot_secondary	= uniphier_boot_secondary,
+	.smp_boot_secondary	= uniphier_smp_boot_secondary,
 };
 CPU_METHOD_OF_DECLARE(uniphier_smp, "socionext,uniphier-smp",
 		      &uniphier_smp_ops);
diff --git a/arch/arm/mach-uniphier/uniphier.c b/arch/arm/mach-uniphier/uniphier.c
index 6aed136..dafb1a0 100644
--- a/arch/arm/mach-uniphier/uniphier.c
+++ b/arch/arm/mach-uniphier/uniphier.c
@@ -30,7 +30,7 @@ static const char * const uniphier_dt_compat[] __initconst = {
 static void __init uniphier_init_machine(void)
 {
 	if (uniphier_cache_init())
-		pr_warn("outer cache was not enabled");
+		pr_warn("uniphier: outer cache was not enabled\n");
 
 	of_platform_populate(NULL, of_default_bus_match_table, NULL, NULL);
 }
-- 
1.9.1



From yamada.masahiro at socionext.com  Sun Aug 23 19:18:10 2015
From: yamada.masahiro at socionext.com (Masahiro Yamada)
Date: Mon, 24 Aug 2015 11:18:10 +0900
Subject: [PATCH 1/3] ARM: uniphier: add outer cache support
In-Reply-To: <1440382692-3855-1-git-send-email-yamada.masahiro@socionext.com>
References: <1440382692-3855-1-git-send-email-yamada.masahiro@socionext.com>
Message-ID: <1440382692-3855-2-git-send-email-yamada.masahiro@socionext.com>

This commit adds support for UniPhier outer cache controller.
All the UniPhier SoCs are equipped with the L2 cache, while the L3
cache is currently only integrated on PH1-Pro5 SoC.

Signed-off-by: Masahiro Yamada <yamada.masahiro at socionext.com>
---

 .../bindings/arm/uniphier/cache-uniphier.txt       |  30 ++
 MAINTAINERS                                        |   2 +
 arch/arm/include/asm/hardware/cache-uniphier.h     |  40 ++
 arch/arm/mach-uniphier/uniphier.c                  |  11 +
 arch/arm/mm/Kconfig                                |  10 +
 arch/arm/mm/Makefile                               |   1 +
 arch/arm/mm/cache-uniphier.c                       | 518 +++++++++++++++++++++
 7 files changed, 612 insertions(+)
 create mode 100644 Documentation/devicetree/bindings/arm/uniphier/cache-uniphier.txt
 create mode 100644 arch/arm/include/asm/hardware/cache-uniphier.h
 create mode 100644 arch/arm/mm/cache-uniphier.c

diff --git a/Documentation/devicetree/bindings/arm/uniphier/cache-uniphier.txt b/Documentation/devicetree/bindings/arm/uniphier/cache-uniphier.txt
new file mode 100644
index 0000000..6428289
--- /dev/null
+++ b/Documentation/devicetree/bindings/arm/uniphier/cache-uniphier.txt
@@ -0,0 +1,30 @@
+UniPhier outer cache controller
+
+UniPhier SoCs are integrated with a level 2 cache controller that resides
+outside of the ARM cores, some of them also have a level 3 cache controller.
+
+Required properties:
+- compatible: should be one of the followings:
+	"socionext,uniphier-l2-cache"	(L2 cache)
+	"socionext,uniphier-l3-cache"	(L3 cache)
+- reg: offsets and lengths of the register sets for the device.  It should
+  contain 3 regions: control registers, revision registers, operation
+  registers, in this order.
+
+The L2 cache must exist to use the L3 cache; adding only an L3 cache device
+node to the device tree causes the initialization failure of the whole outer
+cache system.
+
+Example:
+	l2-cache at 500c0000 {
+		compatible = "socionext,uniphier-l2-cache";
+		reg = <0x500c0000 0x2000>, <0x503c0100 0x8>,
+		      <0x506c0000 0x400>;
+	};
+
+	/* Not all of UniPhier SoCs have L3 cache */
+	l3-cache at 500c8000 {
+		compatible = "socionext,uniphier-l3-cache";
+		reg = <0x500c8000 0x2000>, <0x503c8100 0x8>,
+		      <0x506c8000 0x400>;
+	};
diff --git a/MAINTAINERS b/MAINTAINERS
index a4fbfc8..62e0784 100644
--- a/MAINTAINERS
+++ b/MAINTAINERS
@@ -1578,7 +1578,9 @@ M:	Masahiro Yamada <yamada.masahiro at socionext.com>
 L:	linux-arm-kernel at lists.infradead.org (moderated for non-subscribers)
 S:	Maintained
 F:	arch/arm/boot/dts/uniphier*
+F:	arch/arm/include/asm/hardware/cache-uniphier.h
 F:	arch/arm/mach-uniphier/
+F:	arch/arm/mm/cache-uniphier.c
 F:	drivers/pinctrl/uniphier/
 F:	drivers/tty/serial/8250/8250_uniphier.c
 N:	uniphier
diff --git a/arch/arm/include/asm/hardware/cache-uniphier.h b/arch/arm/include/asm/hardware/cache-uniphier.h
new file mode 100644
index 0000000..641d32f
--- /dev/null
+++ b/arch/arm/include/asm/hardware/cache-uniphier.h
@@ -0,0 +1,40 @@
+/*
+ * Copyright (C) 2015 Masahiro Yamada <yamada.masahiro at socionext.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.
+ */
+
+#ifndef __CACHE_UNIPHIER_H
+#define __CACHE_UNIPHIER_H
+
+#ifdef CONFIG_CACHE_UNIPHIER
+int uniphier_cache_init(void);
+int uniphier_cache_init_locked(void);
+void uniphier_cache_touch_range(unsigned long start, unsigned long end);
+#else
+static inline int uniphier_cache_init(void)
+{
+	return -ENODEV;
+}
+
+static inline int uniphier_cache_init_locked(void)
+{
+	return -ENODEV;
+}
+
+static inline void uniphier_cache_touch_range(unsigned long start,
+					      unsigned long end)
+{
+}
+
+#endif
+
+#endif /* __CACHE_UNIPHIER_H */
diff --git a/arch/arm/mach-uniphier/uniphier.c b/arch/arm/mach-uniphier/uniphier.c
index 9be10ef..6aed136 100644
--- a/arch/arm/mach-uniphier/uniphier.c
+++ b/arch/arm/mach-uniphier/uniphier.c
@@ -12,6 +12,8 @@
  * GNU General Public License for more details.
  */
 
+#include <linux/of_platform.h>
+#include <asm/hardware/cache-uniphier.h>
 #include <asm/mach/arch.h>
 
 static const char * const uniphier_dt_compat[] __initconst = {
@@ -25,6 +27,15 @@ static const char * const uniphier_dt_compat[] __initconst = {
 	NULL,
 };
 
+static void __init uniphier_init_machine(void)
+{
+	if (uniphier_cache_init())
+		pr_warn("outer cache was not enabled");
+
+	of_platform_populate(NULL, of_default_bus_match_table, NULL, NULL);
+}
+
 DT_MACHINE_START(UNIPHIER, "Socionext UniPhier")
 	.dt_compat	= uniphier_dt_compat,
+	.init_machine	= uniphier_init_machine,
 MACHINE_END
diff --git a/arch/arm/mm/Kconfig b/arch/arm/mm/Kconfig
index 7c6b976..7b33ff3 100644
--- a/arch/arm/mm/Kconfig
+++ b/arch/arm/mm/Kconfig
@@ -985,6 +985,16 @@ config CACHE_TAUROS2
 	  This option enables the Tauros2 L2 cache controller (as
 	  found on PJ1/PJ4).
 
+config CACHE_UNIPHIER
+	bool "Enable the UniPhier outer cache controller"
+	depends on ARCH_UNIPHIER
+	default y
+	select OUTER_CACHE
+	select OUTER_CACHE_SYNC
+	help
+	  This option enables the UniPhier outer cache (system cache)
+	  controller.
+
 config CACHE_XSC3L2
 	bool "Enable the L2 cache on XScale3"
 	depends on CPU_XSC3
diff --git a/arch/arm/mm/Makefile b/arch/arm/mm/Makefile
index 57c8df5..7f76d96 100644
--- a/arch/arm/mm/Makefile
+++ b/arch/arm/mm/Makefile
@@ -103,3 +103,4 @@ obj-$(CONFIG_CACHE_FEROCEON_L2)	+= cache-feroceon-l2.o
 obj-$(CONFIG_CACHE_L2X0)	+= cache-l2x0.o l2c-l2x0-resume.o
 obj-$(CONFIG_CACHE_XSC3L2)	+= cache-xsc3l2.o
 obj-$(CONFIG_CACHE_TAUROS2)	+= cache-tauros2.o
+obj-$(CONFIG_CACHE_UNIPHIER)	+= cache-uniphier.o
diff --git a/arch/arm/mm/cache-uniphier.c b/arch/arm/mm/cache-uniphier.c
new file mode 100644
index 0000000..9eb0665
--- /dev/null
+++ b/arch/arm/mm/cache-uniphier.c
@@ -0,0 +1,518 @@
+/*
+ * Copyright (C) 2015 Masahiro Yamada <yamada.masahiro at socionext.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/init.h>
+#include <linux/io.h>
+#include <linux/of_address.h>
+#include <asm/hardware/cache-uniphier.h>
+#include <asm/outercache.h>
+
+/* control registers */
+#define UNIPHIER_SSCC		0x0	/* Control Register */
+#define    UNIPHIER_SSCC_BST			BIT(20)	/* UCWG burst read */
+#define    UNIPHIER_SSCC_ACT			BIT(19)	/* Inst-Data separate */
+#define    UNIPHIER_SSCC_WTG			BIT(18)	/* WT gathering on */
+#define    UNIPHIER_SSCC_PRD			BIT(17)	/* enable pre-fetch */
+#define    UNIPHIER_SSCC_ON			BIT(0)	/* enable cache */
+#define UNIPHIER_SSCLPDAWCR	0x30	/* Unified/Data Active Way Control */
+#define UNIPHIER_SSCLPIAWCR	0x34	/* Instruction Active Way Control */
+
+/* revision registers */
+#define UNIPHIER_SSCID		0x0	/* ID Register */
+
+/* operation registers */
+#define UNIPHIER_SSCOPE		0x244	/* Cache Operation Primitive Entry */
+#define    UNIPHIER_SSCOPE_CM_INV		0x0	/* invalidate */
+#define    UNIPHIER_SSCOPE_CM_CLEAN		0x1	/* clean */
+#define    UNIPHIER_SSCOPE_CM_FLUSH		0x2	/* flush */
+#define    UNIPHIER_SSCOPE_CM_SYNC		0x8	/* sync (drain bufs) */
+#define    UNIPHIER_SSCOPE_CM_FLUSH_PREFETCH	0x9	/* flush p-fetch buf */
+#define UNIPHIER_SSCOQM		0x248	/* Cache Operation Queue Mode */
+#define    UNIPHIER_SSCOQM_TID_MASK		(0x3 << 21)
+#define    UNIPHIER_SSCOQM_TID_LRU_DATA		(0x0 << 21)
+#define    UNIPHIER_SSCOQM_TID_LRU_INST		(0x1 << 21)
+#define    UNIPHIER_SSCOQM_TID_WAY		(0x2 << 21)
+#define    UNIPHIER_SSCOQM_S_MASK		(0x3 << 17)
+#define    UNIPHIER_SSCOQM_S_RANGE		(0x0 << 17)
+#define    UNIPHIER_SSCOQM_S_ALL		(0x1 << 17)
+#define    UNIPHIER_SSCOQM_S_WAY		(0x2 << 17)
+#define    UNIPHIER_SSCOQM_CE			BIT(15)	/* notify completion */
+#define    UNIPHIER_SSCOQM_CM_INV		0x0	/* invalidate */
+#define    UNIPHIER_SSCOQM_CM_CLEAN		0x1	/* clean */
+#define    UNIPHIER_SSCOQM_CM_FLUSH		0x2	/* flush */
+#define    UNIPHIER_SSCOQM_CM_PREFETCH		0x3	/* prefetch to cache */
+#define    UNIPHIER_SSCOQM_CM_PREFETCH_BUF	0x4	/* prefetch to pf-buf */
+#define    UNIPHIER_SSCOQM_CM_TOUCH		0x5	/* touch */
+#define    UNIPHIER_SSCOQM_CM_TOUCH_ZERO	0x6	/* touch to zero */
+#define    UNIPHIER_SSCOQM_CM_TOUCH_DIRTY	0x7	/* touch with dirty */
+#define UNIPHIER_SSCOQAD	0x24c	/* Cache Operation Queue Address */
+#define UNIPHIER_SSCOQSZ	0x250	/* Cache Operation Queue Size */
+#define UNIPHIER_SSCOQMASK	0x254	/* Cache Operation Queue Address Mask */
+#define UNIPHIER_SSCOQWN	0x258	/* Cache Operation Queue Way Number */
+#define UNIPHIER_SSCOPPQSEF	0x25c	/* Cache Operation Queue Set Complete*/
+#define    UNIPHIER_SSCOPPQSEF_FE		BIT(1)
+#define    UNIPHIER_SSCOPPQSEF_OE		BIT(0)
+#define UNIPHIER_SSCOLPQS	0x260	/* Cache Operation Queue Status */
+#define    UNIPHIER_SSCOLPQS_EF			BIT(2)
+#define    UNIPHIER_SSCOLPQS_EST		BIT(1)
+#define    UNIPHIER_SSCOLPQS_QST		BIT(0)
+
+/* Is the touch/pre-fetch destination specified by ways? */
+#define UNIPHIER_SSCOQM_TID_IS_WAY(op) \
+		((op & UNIPHIER_SSCOQM_TID_MASK) == UNIPHIER_SSCOQM_TID_WAY)
+/* Is the operation region specified by address range? */
+#define UNIPHIER_SSCOQM_S_IS_RANGE(op) \
+		((op & UNIPHIER_SSCOQM_S_MASK) == UNIPHIER_SSCOQM_S_RANGE)
+/* Is the operation region specified by ways? */
+#define UNIPHIER_SSCOQM_S_IS_WAY(op) \
+		((op & UNIPHIER_SSCOQM_S_MASK) == UNIPHIER_SSCOQM_S_WAY)
+
+#define UNIPHIER_L2_CACHE_LINE_SIZE		128
+#define UNIPHIER_L3_CACHE_LINE_SIZE		256
+
+/**
+ * uniphier_cache_data - UniPhier outer cache specific data
+ *
+ * @ctrl_base: virtual base address of control registers
+ * @rev_base: virtual base address of revision registers
+ * @op_base: virtual base address of operation registers
+ * @line_size: line size, which range operations must be aligned to
+ * @range_op_max_size: max data size for a single range operation can handle
+ */
+static struct uniphier_cache_data {
+	void __iomem *ctrl_base;
+	void __iomem *rev_base;
+	void __iomem *op_base;
+	unsigned int line_size;
+	unsigned long range_op_max_size;
+} uniphier_cache_data[];
+
+/* the number of detected outer cache levels (0: none, 1: L2, 2: L2&L3) */
+static int uniphier_outer_levels;
+
+/**
+ * __uniphier_cache_sync - perform a sync point for a particular cache level
+ *
+ * @data: cache controller specific data
+ */
+static void __uniphier_cache_sync(struct uniphier_cache_data *data)
+{
+	/* This sequence need not be atomic.  Do not disable IRQ. */
+	writel_relaxed(UNIPHIER_SSCOPE_CM_SYNC,
+		       data->op_base + UNIPHIER_SSCOPE);
+	/* need a read back to confirm */
+	readl_relaxed(data->op_base + UNIPHIER_SSCOPE);
+}
+
+/**
+ * __uniphier_cache_maint_common - run a queue operation for a particular level
+ *
+ * @data: cache controller specific data
+ * @start: start address of range operation (don't care for "all" operation)
+ * @size: data size of range operation (don't care for "all" operation)
+ * @operation: flags to specify the desired cache operation
+ */
+static void __uniphier_cache_maint_common(struct uniphier_cache_data *data,
+					  unsigned long start,
+					  unsigned long size,
+					  u32 operation)
+{
+	unsigned long flags;
+
+	/*
+	 * The IRQ must be disable during this sequence because the accessor
+	 * holds the access right of the operation queue registers.
+	 * Restore the IRQ after releasing the register access right.
+	 */
+	local_irq_save(flags);
+
+	/* clear the complete notification flag */
+	writel_relaxed(UNIPHIER_SSCOLPQS_EF, data->op_base + UNIPHIER_SSCOLPQS);
+
+	/*
+	 * We do not need a spin lock here because the hardware guarantees
+	 * this sequence is atomic, i.e. the write access is arbitrated
+	 * and only the winner's write accesses take effect.
+	 * After register settings, we need to check the UNIPHIER_SSCOPPQSEF to
+	 * see if we won the arbitration or not.
+	 * If the command was not successfully set, just try again.
+	 */
+	do {
+		/* set cache operation */
+		writel_relaxed(UNIPHIER_SSCOQM_CE | operation,
+			       data->op_base + UNIPHIER_SSCOQM);
+
+		/* set address range if needed */
+		if (likely(UNIPHIER_SSCOQM_S_IS_RANGE(operation))) {
+			writel_relaxed(start, data->op_base + UNIPHIER_SSCOQAD);
+			writel_relaxed(size, data->op_base + UNIPHIER_SSCOQSZ);
+		}
+
+		/* set target ways if needed */
+		if (unlikely(UNIPHIER_SSCOQM_S_IS_WAY(operation) ||
+			     UNIPHIER_SSCOQM_TID_IS_WAY(operation)))
+			/* set all the locked ways as destination */
+			writel_relaxed(~readl_relaxed(data->ctrl_base +
+						      UNIPHIER_SSCLPDAWCR),
+				       data->op_base + UNIPHIER_SSCOQWN);
+	} while (unlikely(readl_relaxed(data->op_base + UNIPHIER_SSCOPPQSEF) &
+			  (UNIPHIER_SSCOPPQSEF_FE | UNIPHIER_SSCOPPQSEF_OE)));
+
+	/* wait until the operation is completed */
+	while (likely(readl_relaxed(data->op_base + UNIPHIER_SSCOLPQS) !=
+		      UNIPHIER_SSCOLPQS_EF))
+		cpu_relax();
+
+	local_irq_restore(flags);
+}
+
+static void __uniphier_cache_maint_all(struct uniphier_cache_data *data,
+				       u32 operation)
+{
+	__uniphier_cache_maint_common(data, 0, 0,
+				      UNIPHIER_SSCOQM_S_ALL | operation);
+
+	__uniphier_cache_sync(data);
+}
+
+static void __uniphier_cache_maint_range(struct uniphier_cache_data *data,
+					 unsigned long start, unsigned long end,
+					 u32 operation)
+{
+	unsigned long size;
+
+	/*
+	 * If the start address is not aligned,
+	 * perform a cache operation for the first cache-line
+	 */
+	start = start & ~(data->line_size - 1);
+
+	size = end - start;
+
+	if (unlikely(size >= (unsigned long)(-data->line_size))) {
+		/* this means cache operation for all range */
+		__uniphier_cache_maint_all(data, operation);
+		return;
+	}
+
+	/*
+	 * If the end address is not aligned,
+	 * perform a cache operation for the last cache-line
+	 */
+	size = ALIGN(size, data->line_size);
+
+	while (size) {
+		u32 chunk_size = min(size, data->range_op_max_size);
+
+		__uniphier_cache_maint_common(data, start, chunk_size,
+					UNIPHIER_SSCOQM_S_RANGE | operation);
+
+		start += chunk_size;
+		size -= chunk_size;
+	}
+
+	__uniphier_cache_sync(data);
+}
+
+static void __uniphier_cache_enable(struct uniphier_cache_data *data, bool on)
+{
+	u32 val = 0;
+
+	if (on)
+		val = UNIPHIER_SSCC_WTG | UNIPHIER_SSCC_PRD | UNIPHIER_SSCC_ON;
+
+	writel_relaxed(val, data->ctrl_base + UNIPHIER_SSCC);
+}
+
+static void __uniphier_cache_set_active_ways(struct uniphier_cache_data *data,
+					     u32 ways)
+{
+	writel_relaxed(ways, data->ctrl_base + UNIPHIER_SSCLPDAWCR);
+}
+
+static void uniphier_cache_maint_all(u32 operation)
+{
+	int i;
+
+	for (i = 0; i < uniphier_outer_levels; i++)
+		__uniphier_cache_maint_all(&uniphier_cache_data[i], operation);
+}
+
+static void uniphier_cache_maint_range(unsigned long start, unsigned long end,
+				       u32 operation)
+{
+	int i;
+
+	for (i = 0; i < uniphier_outer_levels; i++)
+		__uniphier_cache_maint_range(&uniphier_cache_data[i],
+					     start, end, operation);
+}
+
+static void uniphier_cache_inv_range(unsigned long start, unsigned long end)
+{
+	uniphier_cache_maint_range(start, end, UNIPHIER_SSCOQM_CM_INV);
+}
+
+static void uniphier_cache_clean_range(unsigned long start, unsigned long end)
+{
+	uniphier_cache_maint_range(start, end, UNIPHIER_SSCOQM_CM_CLEAN);
+}
+
+static void uniphier_cache_flush_range(unsigned long start, unsigned long end)
+{
+	uniphier_cache_maint_range(start, end, UNIPHIER_SSCOQM_CM_FLUSH);
+}
+
+void __init uniphier_cache_touch_range(unsigned long start, unsigned long end)
+{
+	uniphier_cache_maint_range(start, end, UNIPHIER_SSCOQM_TID_WAY |
+				   UNIPHIER_SSCOQM_CM_TOUCH);
+}
+
+static void __init uniphier_cache_inv_all(void)
+{
+	uniphier_cache_maint_all(UNIPHIER_SSCOQM_CM_INV);
+}
+
+static void uniphier_cache_flush_all(void)
+{
+	uniphier_cache_maint_all(UNIPHIER_SSCOQM_CM_FLUSH);
+}
+
+static void uniphier_cache_disable(void)
+{
+	int i;
+
+	for (i = uniphier_outer_levels - 1; i >= 0; i--)
+		__uniphier_cache_enable(&uniphier_cache_data[i], false);
+
+	uniphier_cache_flush_all();
+}
+
+static void __init uniphier_cache_enable(void)
+{
+	int i;
+
+	uniphier_cache_inv_all();
+
+	for (i = 0; i < uniphier_outer_levels; i++)
+		__uniphier_cache_enable(&uniphier_cache_data[i], true);
+}
+
+static void uniphier_cache_sync(void)
+{
+	int i;
+
+	for (i = 0; i < uniphier_outer_levels; i++)
+		__uniphier_cache_sync(&uniphier_cache_data[i]);
+}
+
+static void __init uniphier_cache_set_active_ways(u32 ways)
+{
+	int i;
+
+	for (i = 0; i < uniphier_outer_levels; i++)
+		__uniphier_cache_set_active_ways(&uniphier_cache_data[i],
+						 ways);
+}
+
+static int __init uniphier_cache_common_init(struct device_node *np,
+					     struct uniphier_cache_data *data)
+{
+	data->ctrl_base = of_iomap(np, 0);
+	if (!data->ctrl_base)
+		return -ENOMEM;
+
+	data->rev_base = of_iomap(np, 1);
+	if (!data->rev_base)
+		goto err;
+
+	data->op_base = of_iomap(np, 2);
+	if (!data->op_base)
+		goto err;
+
+	return 0;
+err:
+	iounmap(data->rev_base);
+	iounmap(data->ctrl_base);
+
+	return -ENOMEM;
+}
+
+static int __init uniphier_l2_cache_init(struct device_node *np,
+					 struct uniphier_cache_data *data)
+{
+	int ret;
+	u32 revision;
+
+	ret = uniphier_cache_common_init(np, data);
+	if (ret)
+		return ret;
+
+	data->line_size = UNIPHIER_L2_CACHE_LINE_SIZE;
+
+	revision = readl(data->rev_base + UNIPHIER_SSCID);
+
+	if (revision >= 0x17) /* PH1-Pro5 or later */
+		data->range_op_max_size = (u32)-data->line_size;
+	else
+		data->range_op_max_size = (1UL << 22) - data->line_size;
+
+	writel_relaxed(0, data->ctrl_base + UNIPHIER_SSCC);
+
+	return 0;
+}
+
+static int __init uniphier_l3_cache_init(struct device_node *np,
+					 struct uniphier_cache_data *data)
+{
+	int ret;
+
+	ret = uniphier_cache_common_init(np, data);
+	if (ret)
+		return ret;
+
+	data->line_size = UNIPHIER_L3_CACHE_LINE_SIZE;
+
+	data->range_op_max_size = (u32)-data->line_size;
+
+	return 0;
+}
+
+static const struct of_device_id uniphier_l2_cache_match[] __initconst = {
+	{
+		.compatible = "socionext,uniphier-l2-cache",
+		.data = uniphier_l2_cache_init,
+	},
+	{ /* sentinel */ }
+};
+
+static const struct of_device_id uniphier_l3_cache_match[] __initconst = {
+	{
+		.compatible = "socionext,uniphier-l3-cache",
+		.data = uniphier_l3_cache_init,
+	},
+	{ /* sentinel */ }
+};
+
+static const struct of_device_id *const uniphier_cache_matches[] __initconst = {
+	uniphier_l2_cache_match,
+	uniphier_l3_cache_match,
+};
+
+#define UNIPHIER_CACHE_LEVELS		(ARRAY_SIZE(uniphier_cache_matches))
+
+static struct uniphier_cache_data uniphier_cache_data[UNIPHIER_CACHE_LEVELS];
+
+static int __init __uniphier_cache_init(void)
+{
+	int (*initf)(struct device_node *np, struct uniphier_cache_data *data);
+	static int done;
+	static int ret;
+	struct device_node *np;
+	const struct of_device_id *match;
+	int i;
+
+	if (done)
+		return ret;
+
+	for (i = 0; ARRAY_SIZE(uniphier_cache_matches); i++) {
+		np = of_find_matching_node_and_match(NULL,
+						     uniphier_cache_matches[i],
+						     &match);
+		if (!np) {
+			ret = -ENODEV;
+			break;
+		}
+
+		initf = match->data;
+		ret = initf(np, &uniphier_cache_data[i]);
+		if (ret)
+			break;
+	}
+
+	uniphier_outer_levels = i;
+
+	/*
+	 * Error out iif L2 initialization fails.
+	 * Continue with any error on L3 because it is optional.
+	 */
+	if (uniphier_outer_levels == 0) {
+		ret = ret ?: -ENODEV;
+		pr_err("uniphier: failed to initialize outer cache\n");
+		goto out;
+	} else {
+		ret = 0;
+	}
+
+	outer_cache.inv_range = uniphier_cache_inv_range;
+	outer_cache.clean_range = uniphier_cache_clean_range;
+	outer_cache.flush_range = uniphier_cache_flush_range;
+	outer_cache.flush_all = uniphier_cache_flush_all;
+	outer_cache.disable = uniphier_cache_disable;
+	outer_cache.sync = uniphier_cache_sync;
+
+	uniphier_cache_enable();
+
+out:
+	done = 1;
+
+	return ret;
+}
+
+/**
+ * uniphier_cache_init - initialize outer cache and set all the ways active
+ *
+ * This enables the outer cache for the normal operation.
+ */
+int __init uniphier_cache_init(void)
+{
+	int ret;
+
+	ret = __uniphier_cache_init();
+	if (ret)
+		return ret;
+
+	uniphier_cache_set_active_ways(U32_MAX);
+
+	pr_info("uniphier: enabled outer cache (%s)\n",
+		uniphier_outer_levels >= 2 ? "L2 and L3" : "L2");
+
+	return 0;
+}
+
+/**
+ * uniphier_cache_init_locked - initialize outer cache and lock all the ways
+ *
+ * This enables the outer cache, but never performs the refill operations.
+ * If the data at the accessed address is found in the cache (cache-hit), the
+ * data is transferred to the CPU.  If not (cache-miss), the desired data is
+ * fetched from the main memory, but the contents in the cache are _not_
+ * replaced.  This is generally used to keep particular data in the cache.
+ */
+int __init uniphier_cache_init_locked(void)
+{
+	int ret;
+
+	ret = __uniphier_cache_init();
+	if (ret)
+		return ret;
+
+	uniphier_cache_set_active_ways(0);
+
+	pr_info("uniphier: set up outer cache (%s) as locked cache\n",
+		uniphier_outer_levels >= 2 ? "L2 and L3" : "L2");
+
+	return 0;
+}
-- 
1.9.1



From joe at perches.com  Sun Aug 23 19:29:19 2015
From: joe at perches.com (Joe Perches)
Date: Sun, 23 Aug 2015 19:29:19 -0700
Subject: [PATCH 1/3] ARM: uniphier: add outer cache support
In-Reply-To: <1440382692-3855-2-git-send-email-yamada.masahiro@socionext.com>
References: <1440382692-3855-1-git-send-email-yamada.masahiro@socionext.com>
 <1440382692-3855-2-git-send-email-yamada.masahiro@socionext.com>
Message-ID: <1440383359.2670.15.camel@perches.com>

On Mon, 2015-08-24 at 11:18 +0900, Masahiro Yamada wrote:
> This commit adds support for UniPhier outer cache controller.
> All the UniPhier SoCs are equipped with the L2 cache, while the L3
> cache is currently only integrated on PH1-Pro5 SoC.

style trivia:

You might add and use
	#define pr_fmt(fmt) "uniphier: " fmt
before any other #include so all of the pr_<level>
uses are automatically prefixed.

> diff --git a/arch/arm/mm/cache-uniphier.c b/arch/arm/mm/cache-uniphier.c
[]
> +static int __init __uniphier_cache_init(void)
> +{
[]
> +	if (uniphier_outer_levels == 0) {
> +		ret = ret ?: -ENODEV;
> +		pr_err("uniphier: failed to initialize outer cache\n");

So this becomes:
		pr_err("failed to initialize outer cache\n");

> +int __init uniphier_cache_init(void)
> +{
[]
> +	pr_info("uniphier: enabled outer cache (%s)\n",
> +		uniphier_outer_levels >= 2 ? "L2 and L3" : "L2");

	pr_info("enabled outer cache (%s)\n",
		uniphier_outer_levels >= 2 ? "L2 and L3" : "L2");

etc...




From dianders at chromium.org  Sun Aug 23 19:45:15 2015
From: dianders at chromium.org (Doug Anderson)
Date: Sun, 23 Aug 2015 19:45:15 -0700
Subject: [BUG] arm: kgdb: patch_text() in kgdb_arch_set_breakpoint() may
 sleep
In-Reply-To: <55C230C7.2000909@nvidia.com>
References: <55C230C7.2000909@nvidia.com>
Message-ID: <CAD=FV=V_E+YMQuW5kvn+52Ugc_5hZsyXKKQ9Ywo_emoqK-N+Qw@mail.gmail.com>

Aapo,

Including the stack trace with this would have been helpful, though
it's not too hard to reproduce.  Here it is:

[  416.510559] BUG: scheduling while atomic: swapper/0/0/0x00010007
[  416.516554] Modules linked in:
[  416.519614] CPU: 0 PID: 0 Comm: swapper/0 Not tainted
4.2.0-rc7-00133-geb63b34 #1073
[  416.527341] Hardware name: Rockchip (Device Tree)
[  416.532042] [<c0017a4c>] (unwind_backtrace) from [<c00133d4>]
(show_stack+0x20/0x24)
[  416.539772] [<c00133d4>] (show_stack) from [<c05400e8>]
(dump_stack+0x84/0xb8)
[  416.546983] [<c05400e8>] (dump_stack) from [<c004913c>]
(__schedule_bug+0x54/0x6c)
[  416.554540] [<c004913c>] (__schedule_bug) from [<c054065c>]
(__schedule+0x80/0x668)
[  416.562183] [<c054065c>] (__schedule) from [<c0540cfc>] (schedule+0xb8/0xd4)
[  416.569219] [<c0540cfc>] (schedule) from [<c0543a3c>]
(schedule_timeout+0x2c/0x234)
[  416.576861] [<c0543a3c>] (schedule_timeout) from [<c05417c0>]
(wait_for_common+0xf4/0x188)
[  416.585109] [<c05417c0>] (wait_for_common) from [<c0541874>]
(wait_for_completion+0x20/0x24)
[  416.593531] [<c0541874>] (wait_for_completion) from [<c00a0104>]
(__stop_cpus+0x58/0x70)
[  416.601608] [<c00a0104>] (__stop_cpus) from [<c00a0580>]
(stop_cpus+0x3c/0x54)
[  416.608817] [<c00a0580>] (stop_cpus) from [<c00a06c4>]
(__stop_machine+0xcc/0xe8)
[  416.616286] [<c00a06c4>] (__stop_machine) from [<c00a0714>]
(stop_machine+0x34/0x44)
[  416.624016] [<c00a0714>] (stop_machine) from [<c00173e8>]
(patch_text+0x28/0x34)
[  416.631399] [<c00173e8>] (patch_text) from [<c001733c>]
(kgdb_arch_set_breakpoint+0x40/0x4c)
[  416.639823] [<c001733c>] (kgdb_arch_set_breakpoint) from
[<c00a0d68>] (kgdb_validate_break_address+0x2c/0x60)
[  416.649719] [<c00a0d68>] (kgdb_validate_break_address) from
[<c00a0e90>] (dbg_set_sw_break+0x1c/0xdc)
[  416.658922] [<c00a0e90>] (dbg_set_sw_break) from [<c00a2e88>]
(gdb_serial_stub+0x9c4/0xba4)
[  416.667259] [<c00a2e88>] (gdb_serial_stub) from [<c00a11cc>]
(kgdb_cpu_enter+0x1f8/0x60c)
[  416.675423] [<c00a11cc>] (kgdb_cpu_enter) from [<c00a18cc>]
(kgdb_handle_exception+0x19c/0x1d0)
[  416.684106] [<c00a18cc>] (kgdb_handle_exception) from [<c0016f7c>]
(kgdb_compiled_brk_fn+0x30/0x3c)
[  416.693135] [<c0016f7c>] (kgdb_compiled_brk_fn) from [<c00091a4>]
(do_undefinstr+0x1a4/0x20c)
[  416.701643] [<c00091a4>] (do_undefinstr) from [<c001400c>]
(__und_svc_finish+0x0/0x34)
[  416.709543] Exception stack(0xc07c1ce8 to 0xc07c1d30)
[  416.714584] 1ce0:                   00000000 c07c6504 c086e290
c086e294 c086e294 c086e290
[  416.722745] 1d00: c07c6504 00000067 00000001 c07c2100 00000027
c07c1d4c c07c1d50 c07c1d30
[  416.730905] 1d20: c00a0990 c00a08d0 60000193 ffffffff
[  416.735947] [<c001400c>] (__und_svc_finish) from [<c00a08d0>]
(kgdb_breakpoint+0x58/0x94)
[  416.744110] [<c00a08d0>] (kgdb_breakpoint) from [<c00a0990>]
(sysrq_handle_dbg+0x58/0x6c)
[  416.752273] [<c00a0990>] (sysrq_handle_dbg) from [<c02c230c>]
(__handle_sysrq+0xac/0x15c)
[  416.760437] [<c02c230c>] (__handle_sysrq) from [<c02c23ec>]
(handle_sysrq+0x30/0x34)


Kees: I think you've dealt with a lot more of these types of issues
than I have.  Any quick thoughts?  If not I can put it on my long-term
list of things to do, but until then we could always just post a
Revert...


-Doug


On Wed, Aug 5, 2015 at 8:50 AM, Aapo Vienamo <avienamo at nvidia.com> wrote:
> Hi,
>
> The breakpoint setting code in arch/arm/kernel/kgdb.c calls
> patch_text(), which ends up trying to sleep while in interrupt context.
> The bug was introduced by commit: 23a4e40 arm: kgdb: Handle read-only
> text / modules. The resulting behavior is "BUG: scheduling while
> atomic..." when setting a breakpoint in kgdb. This was tested on an
> Nvidia Jetson TK1 board with 4.2.0-rc5-next-20150805 kernel.
>
> Regards,
> Aapo Vienamo


From yamada.masahiro at socionext.com  Sun Aug 23 19:58:39 2015
From: yamada.masahiro at socionext.com (Masahiro Yamada)
Date: Mon, 24 Aug 2015 11:58:39 +0900
Subject: [PATCH 1/3] ARM: uniphier: add outer cache support
In-Reply-To: <1440383359.2670.15.camel@perches.com>
References: <1440382692-3855-1-git-send-email-yamada.masahiro@socionext.com>
 <1440382692-3855-2-git-send-email-yamada.masahiro@socionext.com>
 <1440383359.2670.15.camel@perches.com>
Message-ID: <CAK7LNASYUaHkarg8CghDdFWGzTtN90qv2X7_rL-q0CDjAKPZaw@mail.gmail.com>

Hi Joe,


2015-08-24 11:29 GMT+09:00 Joe Perches <joe at perches.com>:
> On Mon, 2015-08-24 at 11:18 +0900, Masahiro Yamada wrote:
>> This commit adds support for UniPhier outer cache controller.
>> All the UniPhier SoCs are equipped with the L2 cache, while the L3
>> cache is currently only integrated on PH1-Pro5 SoC.
>
> style trivia:
>
> You might add and use
>         #define pr_fmt(fmt) "uniphier: " fmt
> before any other #include so all of the pr_<level>
> uses are automatically prefixed.


I did not know that.  Thanks!

I will do so for the whole series in v2.





-- 
Best Regards
Masahiro Yamada


From leo.yan at linaro.org  Sun Aug 23 20:27:55 2015
From: leo.yan at linaro.org (Leo Yan)
Date: Mon, 24 Aug 2015 11:27:55 +0800
Subject: [PATCH v1 3/3] arm64: dts: add Hi6220 mailbox node
In-Reply-To: <20150822133050.GA4265@leoy-linaro>
References: <1439977055-1747-1-git-send-email-leo.yan@linaro.org>
 <1439977055-1747-4-git-send-email-leo.yan@linaro.org>
 <20150821184059.GB2000@svinekod>
 <20150822133050.GA4265@leoy-linaro>
Message-ID: <20150824032755.GA29395@leoy-linaro>

Hi Mark,

On Sat, Aug 22, 2015 at 09:30:50PM +0800, Leo Yan wrote:
> On Fri, Aug 21, 2015 at 07:40:59PM +0100, Mark Rutland wrote:
> > On Wed, Aug 19, 2015 at 10:37:35AM +0100, Leo Yan wrote:
> > > On Hi6220, below memory regions in DDR have specific purpose:
> > > 
> > >   0x05e0,0000 - 0x05ef,ffff: For MCU firmware using at runtime;
> > >   0x0740,f000 - 0x0740,ffff: For MCU firmware's section;
> > >   0x06df,f000 - 0x06df,ffff: For mailbox message data.
> > > 
> > > This patch reserves these memory regions and add device node for
> > > mailbox in dts.
> > > 
> > > Signed-off-by: Leo Yan <leo.yan at linaro.org>
> > > ---
> > >  arch/arm64/boot/dts/hisilicon/hi6220-hikey.dts | 20 +++++++++++++++++---
> > >  arch/arm64/boot/dts/hisilicon/hi6220.dtsi      |  8 ++++++++
> > >  2 files changed, 25 insertions(+), 3 deletions(-)
> > > 
> > > diff --git a/arch/arm64/boot/dts/hisilicon/hi6220-hikey.dts b/arch/arm64/boot/dts/hisilicon/hi6220-hikey.dts
> > > index e36a539..d5470d3 100644
> > > --- a/arch/arm64/boot/dts/hisilicon/hi6220-hikey.dts
> > > +++ b/arch/arm64/boot/dts/hisilicon/hi6220-hikey.dts
> > > @@ -7,9 +7,6 @@
> > >  
> > >  /dts-v1/;
> > >  
> > > -/*Reserved 1MB memory for MCU*/
> > > -/memreserve/ 0x05e00000 0x00100000;
> > > -
> > >  #include "hi6220.dtsi"
> > >  
> > >  / {
> > > @@ -28,4 +25,21 @@
> > >  		device_type = "memory";
> > >  		reg = <0x0 0x0 0x0 0x40000000>;
> > >  	};
> > > +
> > > +	reserved-memory {
> > > +		#address-cells = <2>;
> > > +		#size-cells = <2>;
> > > +		ranges;
> > > +
> > > +		mcu-buf at 05e00000 {
> > > +			no-map;
> > > +			reg = <0x0 0x05e00000 0x0 0x00100000>,	/* MCU firmware buffer */
> > > +			      <0x0 0x0740f000 0x0 0x00001000>;	/* MCU firmware section */
> > > +		};
> > > +
> > > +		mbox-buf at 06dff000 {
> > > +			no-map;
> > > +			reg = <0x0 0x06dff000 0x0 0x00001000>;	/* Mailbox message buf */
> > > +		};
> > > +	};
> > 
> > As far as I can see, it would be simpler to simply carve these out of the
> > memory node.
> 
> Will modify for MCU firmware buffer and section.
> 
> > I don't see why you need reserved-memory here, given you're not referring to
> > these regions by phandle anyway.
> 
> mbox-buf is used by below mailbox's node, but the start address has
> been truncated with 4KB alignment; so should keep it, right?

I think i got your point, all these nodes can be removed and just use
memory node to carve them out; but currently i saw the memory node
cannot be passed correctly from UEFI to kernel, we will check for
this. So will follow your suggestion if without any unknown reason.

Thanks,
Leo Yan

> > >  };
> > > diff --git a/arch/arm64/boot/dts/hisilicon/hi6220.dtsi b/arch/arm64/boot/dts/hisilicon/hi6220.dtsi
> > > index 3f03380..9ff25bc 100644
> > > --- a/arch/arm64/boot/dts/hisilicon/hi6220.dtsi
> > > +++ b/arch/arm64/boot/dts/hisilicon/hi6220.dtsi
> > > @@ -167,5 +167,13 @@
> > >  			clocks = <&ao_ctrl 36>, <&ao_ctrl 36>;
> > >  			clock-names = "uartclk", "apb_pclk";
> > >  		};
> > > +
> > > +		mailbox: mailbox at f7510000 {
> > > +			#mbox-cells = <1>;
> > > +			compatible = "hisilicon,hi6220-mbox";
> > > +			reg = <0x0 0xf7510000 0x0 0x1000>, /* IPC_S */
> > > +			      <0x0 0x06dff800 0x0 0x0800>; /* Mailbox buffer */
> > > +			interrupts = <GIC_SPI 94 IRQ_TYPE_LEVEL_HIGH>;
> > > +		};
> > >  	};
> > >  };
> > > -- 
> > > 1.9.1
> > > 


From b38611 at freescale.com  Sun Aug 23 20:29:47 2015
From: b38611 at freescale.com (Fugang Duan)
Date: Mon, 24 Aug 2015 11:29:47 +0800
Subject: [PATCH v2 0/5] Add fec1 and fec2 support for i.MX7d sdb board
Message-ID: <1440386992-6775-1-git-send-email-b38611@freescale.com>

The patch series is to add fec support for i.MX7d sdb board. Since i.MX7d fec ip is
the same as i.MX6SX, so there have no change for driver itself.

Patch#1: add bcm54220 PHY ID entry into brcmphy.h file.
Patch#2: add new iomux-gpr file to define iomux-gpr register and field for i.MX7d.
Patch#3: i.MX7d sdb board install bcm54220 phy, i.MX7d arm2 board install AR8031 phy.
         For the two phys, there needs extra phy setting, so package the setting to fixup.
Patch#4~6: Add fec dts node and pinmux setting in dts file.

Change:
V2:
	* Remove patch#1 in V1 patch series. Move the sigle BCM54220 PHY ID define to machine file.
	* The current BCM54220 switch phy still use generic phy driver since broadcom phy driver don't
	  support the switch phy, there need effort to add the switch phy support. Once broadcom phy driver
	  will support the bcm54220 switch phy, we can add the special config to imx_v6_v7_defconfig.


Fugang Duan (5):
  ARM: imx7d: add imx7d iomux-gpr field define
  ARM: imx: add enet init for i.MX7D platform
  ARM: dts: imx: pinfunc: add GPIO1 pin define for i.MX7d
  ARM: dts: imx7d: add fec1 and fec2 support for i.MX7d soc
  ARM: dts: imx7d-sdb: add fec1 and fec2 support

 arch/arm/boot/dts/imx7d-pinfunc.h          | 115 +++++++++++++++++++++++++++++
 arch/arm/boot/dts/imx7d-sdb.dts            |  76 ++++++++++++++++++-
 arch/arm/boot/dts/imx7d.dtsi               |  36 +++++++++
 arch/arm/mach-imx/mach-imx7d.c             |  76 ++++++++++++++++++-
 include/linux/mfd/syscon/imx7-iomuxc-gpr.h |  49 ++++++++++++
 5 files changed, 349 insertions(+), 3 deletions(-)
 create mode 100644 include/linux/mfd/syscon/imx7-iomuxc-gpr.h

-- 
1.9.1



From b38611 at freescale.com  Sun Aug 23 20:29:52 2015
From: b38611 at freescale.com (Fugang Duan)
Date: Mon, 24 Aug 2015 11:29:52 +0800
Subject: [PATCH v2 5/5] ARM: dts: imx7d-sdb: add fec1 and fec2 support
In-Reply-To: <1440386992-6775-1-git-send-email-b38611@freescale.com>
References: <1440386992-6775-1-git-send-email-b38611@freescale.com>
Message-ID: <1440386992-6775-6-git-send-email-b38611@freescale.com>

Enable fec1 and fec2 for i.MX7d-sdb board.

Signed-off-by: Fugang Duan <B38611 at freescale.com>
---
 arch/arm/boot/dts/imx7d-sdb.dts | 76 ++++++++++++++++++++++++++++++++++++++++-
 1 file changed, 75 insertions(+), 1 deletion(-)

diff --git a/arch/arm/boot/dts/imx7d-sdb.dts b/arch/arm/boot/dts/imx7d-sdb.dts
index 4d1a4b9..7d3e980 100644
--- a/arch/arm/boot/dts/imx7d-sdb.dts
+++ b/arch/arm/boot/dts/imx7d-sdb.dts
@@ -101,6 +101,45 @@
 	arm-supply = <&sw1a_reg>;
 };
 
+&fec1 {
+	pinctrl-names = "default";
+	pinctrl-0 = <&pinctrl_enet1>;
+	assigned-clocks = <&clks IMX7D_ENET1_TIME_ROOT_SRC>,
+			  <&clks IMX7D_ENET1_TIME_ROOT_CLK>;
+	assigned-clock-parents = <&clks IMX7D_PLL_ENET_MAIN_100M_CLK>;
+	assigned-clock-rates = <0>, <100000000>;
+	phy-mode = "rgmii";
+	phy-handle = <&ethphy0>;
+	fsl,magic-packet;
+	status = "okay";
+
+	mdio {
+		#address-cells = <1>;
+		#size-cells = <0>;
+
+		ethphy0: ethernet-phy at 0 {
+			reg = <0>;
+		};
+
+		ethphy1: ethernet-phy at 1 {
+			reg = <1>;
+		};
+	};
+};
+
+&fec2 {
+	pinctrl-names = "default";
+	pinctrl-0 = <&pinctrl_enet2>;
+	assigned-clocks = <&clks IMX7D_ENET2_TIME_ROOT_SRC>,
+			  <&clks IMX7D_ENET2_TIME_ROOT_CLK>;
+	assigned-clock-parents = <&clks IMX7D_PLL_ENET_MAIN_100M_CLK>;
+	assigned-clock-rates = <0>, <100000000>;
+	phy-mode = "rgmii";
+	phy-handle = <&ethphy1>;
+	fsl,magic-packet;
+	status = "okay";
+};
+
 &i2c1 {
 	pinctrl-names = "default";
 	pinctrl-0 = <&pinctrl_i2c1>;
@@ -246,6 +285,42 @@
 	pinctrl-0 = <&pinctrl_hog>;
 
 	imx7d-sdb {
+		pinctrl_enet1: enet1grp {
+			fsl,pins = <
+				MX7D_PAD_GPIO1_IO10__ENET1_MDIO			0x3
+				MX7D_PAD_GPIO1_IO11__ENET1_MDC			0x3
+				MX7D_PAD_ENET1_RGMII_TXC__ENET1_RGMII_TXC	0x1
+				MX7D_PAD_ENET1_RGMII_TD0__ENET1_RGMII_TD0	0x1
+				MX7D_PAD_ENET1_RGMII_TD1__ENET1_RGMII_TD1	0x1
+				MX7D_PAD_ENET1_RGMII_TD2__ENET1_RGMII_TD2	0x1
+				MX7D_PAD_ENET1_RGMII_TD3__ENET1_RGMII_TD3	0x1
+				MX7D_PAD_ENET1_RGMII_TX_CTL__ENET1_RGMII_TX_CTL	0x1
+				MX7D_PAD_ENET1_RGMII_RXC__ENET1_RGMII_RXC	0x1
+				MX7D_PAD_ENET1_RGMII_RD0__ENET1_RGMII_RD0	0x1
+				MX7D_PAD_ENET1_RGMII_RD1__ENET1_RGMII_RD1	0x1
+				MX7D_PAD_ENET1_RGMII_RD2__ENET1_RGMII_RD2	0x1
+				MX7D_PAD_ENET1_RGMII_RD3__ENET1_RGMII_RD3	0x1
+				MX7D_PAD_ENET1_RGMII_RX_CTL__ENET1_RGMII_RX_CTL	0x1
+			>;
+		};
+
+		pinctrl_enet2: enet2grp {
+			fsl,pins = <
+				MX7D_PAD_EPDC_GDSP__ENET2_RGMII_TXC		0x1
+				MX7D_PAD_EPDC_SDCE2__ENET2_RGMII_TD0		0x1
+				MX7D_PAD_EPDC_SDCE3__ENET2_RGMII_TD1		0x1
+				MX7D_PAD_EPDC_GDCLK__ENET2_RGMII_TD2		0x1
+				MX7D_PAD_EPDC_GDOE__ENET2_RGMII_TD3		0x1
+				MX7D_PAD_EPDC_GDRL__ENET2_RGMII_TX_CTL		0x1
+				MX7D_PAD_EPDC_SDCE1__ENET2_RGMII_RXC		0x1
+				MX7D_PAD_EPDC_SDCLK__ENET2_RGMII_RD0		0x1
+				MX7D_PAD_EPDC_SDLE__ENET2_RGMII_RD1		0x1
+				MX7D_PAD_EPDC_SDOE__ENET2_RGMII_RD2		0x1
+				MX7D_PAD_EPDC_SDSHR__ENET2_RGMII_RD3		0x1
+				MX7D_PAD_EPDC_SDCE0__ENET2_RGMII_RX_CTL		0x1
+			>;
+		};
+
 		pinctrl_hog: hoggrp {
 			fsl,pins = <
 				MX7D_PAD_UART3_CTS_B__GPIO4_IO7		0x14
@@ -281,7 +356,6 @@
 			>;
 		};
 
-
 		pinctrl_uart1: uart1grp {
 			fsl,pins = <
 				MX7D_PAD_UART1_TX_DATA__UART1_DCE_TX	0x79
-- 
1.9.1



From b38611 at freescale.com  Sun Aug 23 20:29:48 2015
From: b38611 at freescale.com (Fugang Duan)
Date: Mon, 24 Aug 2015 11:29:48 +0800
Subject: [PATCH v2 1/5] ARM: imx7d: add imx7d iomux-gpr field define
In-Reply-To: <1440386992-6775-1-git-send-email-b38611@freescale.com>
References: <1440386992-6775-1-git-send-email-b38611@freescale.com>
Message-ID: <1440386992-6775-2-git-send-email-b38611@freescale.com>

Add imx7d iomux-gpr field define.

Signed-off-by: Fugang Duan <B38611 at freescale.com>
---
 include/linux/mfd/syscon/imx7-iomuxc-gpr.h | 49 ++++++++++++++++++++++++++++++
 1 file changed, 49 insertions(+)

diff --git a/include/linux/mfd/syscon/imx7-iomuxc-gpr.h b/include/linux/mfd/syscon/imx7-iomuxc-gpr.h
new file mode 100644
index 0000000..5cc0553
--- /dev/null
+++ b/include/linux/mfd/syscon/imx7-iomuxc-gpr.h
@@ -0,0 +1,49 @@
+/*
+ * Copyright (C) 2015 Freescale Semiconductor, Inc.
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License version 2 as
+ * published by the Free Software Foundation.
+ */
+
+#ifndef __LINUX_IMX7_IOMUXC_GPR_H
+#define __LINUX_IMX7_IOMUXC_GPR_H
+
+#include <linux/bitops.h>
+
+#define IOMUXC_GPR0	0x00
+#define IOMUXC_GPR1	0x04
+#define IOMUXC_GPR2	0x08
+#define IOMUXC_GPR3	0x0c
+#define IOMUXC_GPR4	0x10
+#define IOMUXC_GPR5	0x14
+#define IOMUXC_GPR6	0x18
+#define IOMUXC_GPR7	0x1c
+#define IOMUXC_GPR8	0x20
+#define IOMUXC_GPR9	0x24
+#define IOMUXC_GPR10	0x28
+#define IOMUXC_GPR11	0x2c
+#define IOMUXC_GPR12	0x30
+#define IOMUXC_GPR13	0x34
+#define IOMUXC_GPR14	0x38
+#define IOMUXC_GPR15	0x3c
+#define IOMUXC_GPR16	0x40
+#define IOMUXC_GPR17	0x44
+#define IOMUXC_GPR18	0x48
+#define IOMUXC_GPR19	0x4c
+#define IOMUXC_GPR20	0x50
+#define IOMUXC_GPR21	0x54
+#define IOMUXC_GPR22	0x58
+
+/* For imx7d iomux gpr register field define */
+#define IMX7D_GPR1_IRQ_MASK			(0x1 << 12)
+#define IMX7D_GPR1_ENET1_TX_CLK_SEL_MASK	(0x1 << 13)
+#define IMX7D_GPR1_ENET2_TX_CLK_SEL_MASK	(0x1 << 14)
+#define IMX7D_GPR1_ENET_TX_CLK_SEL_MASK		(0x3 << 13)
+#define IMX7D_GPR1_ENET1_CLK_DIR_MASK		(0x1 << 17)
+#define IMX7D_GPR1_ENET2_CLK_DIR_MASK		(0x1 << 18)
+#define IMX7D_GPR1_ENET_CLK_DIR_MASK		(0x3 << 17)
+
+#define IMX7D_GPR5_CSI_MUX_CONTROL_MIPI		(0x1 << 4)
+
+#endif /* __LINUX_IMX7_IOMUXC_GPR_H */
-- 
1.9.1



From b38611 at freescale.com  Sun Aug 23 20:29:49 2015
From: b38611 at freescale.com (Fugang Duan)
Date: Mon, 24 Aug 2015 11:29:49 +0800
Subject: [PATCH v2 2/5] ARM: imx: add enet init for i.MX7D platform
In-Reply-To: <1440386992-6775-1-git-send-email-b38611@freescale.com>
References: <1440386992-6775-1-git-send-email-b38611@freescale.com>
Message-ID: <1440386992-6775-3-git-send-email-b38611@freescale.com>

Add enet phy fixup, clock source init for i.MX7D platform.

Signed-off-by: Fugang Duan <B38611 at freescale.com>
---
 arch/arm/mach-imx/mach-imx7d.c | 76 ++++++++++++++++++++++++++++++++++++++++--
 1 file changed, 74 insertions(+), 2 deletions(-)

diff --git a/arch/arm/mach-imx/mach-imx7d.c b/arch/arm/mach-imx/mach-imx7d.c
index 4d4a190..07e9a7e 100644
--- a/arch/arm/mach-imx/mach-imx7d.c
+++ b/arch/arm/mach-imx/mach-imx7d.c
@@ -5,13 +5,84 @@
  * it under the terms of the GNU General Public License version 2 as
  * published by the Free Software Foundation.
  */
-#include <linux/irqchip.h>
-#include <linux/of_platform.h>
 #include <asm/mach/arch.h>
 #include <asm/mach/map.h>
+#include <linux/irqchip.h>
+#include <linux/mfd/syscon.h>
+#include <linux/mfd/syscon/imx7-iomuxc-gpr.h>
+#include <linux/of_platform.h>
+#include <linux/phy.h>
+#include <linux/regmap.h>
 
 #include "common.h"
 
+static int ar8031_phy_fixup(struct phy_device *dev)
+{
+	u16 val;
+
+	/* Set RGMII IO voltage to 1.8V */
+	phy_write(dev, 0x1d, 0x1f);
+	phy_write(dev, 0x1e, 0x8);
+
+	/* disable phy AR8031 SmartEEE function. */
+	phy_write(dev, 0xd, 0x3);
+	phy_write(dev, 0xe, 0x805d);
+	phy_write(dev, 0xd, 0x4003);
+	val = phy_read(dev, 0xe);
+	val &= ~(0x1 << 8);
+	phy_write(dev, 0xe, val);
+
+	/* introduce tx clock delay */
+	phy_write(dev, 0x1d, 0x5);
+	val = phy_read(dev, 0x1e);
+	val |= 0x0100;
+	phy_write(dev, 0x1e, val);
+
+	return 0;
+}
+
+static int bcm54220_phy_fixup(struct phy_device *dev)
+{
+	/* enable RXC skew select RGMII copper mode */
+	phy_write(dev, 0x1e, 0x21);
+	phy_write(dev, 0x1f, 0x7ea8);
+	phy_write(dev, 0x1e, 0x2f);
+	phy_write(dev, 0x1f, 0x71b7);
+
+	return 0;
+}
+
+#define PHY_ID_AR8031	0x004dd074
+#define PHY_ID_BCM54220	0x600d8589
+static void __init imx7d_enet_phy_init(void)
+{
+	if (IS_BUILTIN(CONFIG_PHYLIB)) {
+		phy_register_fixup_for_uid(PHY_ID_AR8031, 0xffffffff,
+					   ar8031_phy_fixup);
+		phy_register_fixup_for_uid(PHY_ID_BCM54220, 0xffffffff,
+					   bcm54220_phy_fixup);
+	}
+}
+
+static void __init imx7d_enet_clk_sel(void)
+{
+	struct regmap *gpr;
+
+	gpr = syscon_regmap_lookup_by_compatible("fsl,imx7d-iomuxc-gpr");
+	if (!IS_ERR(gpr)) {
+		regmap_update_bits(gpr, IOMUXC_GPR1, IMX7D_GPR1_ENET_TX_CLK_SEL_MASK, 0);
+		regmap_update_bits(gpr, IOMUXC_GPR1, IMX7D_GPR1_ENET_CLK_DIR_MASK, 0);
+	} else {
+		pr_err("failed to find fsl,imx7d-iomux-gpr regmap\n");
+	}
+}
+
+static inline void imx7d_enet_init(void)
+{
+	imx7d_enet_phy_init();
+	imx7d_enet_clk_sel();
+}
+
 static void __init imx7d_init_machine(void)
 {
 	struct device *parent;
@@ -22,6 +93,7 @@ static void __init imx7d_init_machine(void)
 
 	of_platform_populate(NULL, of_default_bus_match_table, NULL, NULL);
 	imx_anatop_init();
+	imx7d_enet_init();
 }
 
 static void __init imx7d_init_irq(void)
-- 
1.9.1



From b38611 at freescale.com  Sun Aug 23 20:29:50 2015
From: b38611 at freescale.com (Fugang Duan)
Date: Mon, 24 Aug 2015 11:29:50 +0800
Subject: [PATCH v2 3/5] ARM: dts: imx: pinfunc: add GPIO1 pin define for i.MX7d
In-Reply-To: <1440386992-6775-1-git-send-email-b38611@freescale.com>
References: <1440386992-6775-1-git-send-email-b38611@freescale.com>
Message-ID: <1440386992-6775-4-git-send-email-b38611@freescale.com>

Add GPIO1 pin define for i.MX7d.

Signed-off-by: Fugang Duan <B38611 at freescale.com>
---
 arch/arm/boot/dts/imx7d-pinfunc.h | 115 ++++++++++++++++++++++++++++++++++++++
 1 file changed, 115 insertions(+)

diff --git a/arch/arm/boot/dts/imx7d-pinfunc.h b/arch/arm/boot/dts/imx7d-pinfunc.h
index a8d8149..8b3cf2bc 100644
--- a/arch/arm/boot/dts/imx7d-pinfunc.h
+++ b/arch/arm/boot/dts/imx7d-pinfunc.h
@@ -15,6 +15,121 @@
  * <mux_reg conf_reg input_reg mux_mode input_val>
  */
 
+#define MX7D_PAD_GPIO1_IO00__GPIO1_IO0				  0x0000 0x0030 0x0000 0x0 0x0
+#define MX7D_PAD_GPIO1_IO00__PWM4_OUT				  0x0000 0x0030 0x0000 0x1 0x0
+#define MX7D_PAD_GPIO1_IO00__WDOD1_WDOG_ANY			  0x0000 0x0030 0x0000 0x2 0x0
+#define MX7D_PAD_GPIO1_IO00__WDOD1_WDOG_B			  0x0000 0x0030 0x0000 0x3 0x0
+#define MX7D_PAD_GPIO1_IO00__WDOD1_WDOG__RST_B_DEB		  0x0000 0x0030 0x0000 0x4 0x0
+#define MX7D_PAD_GPIO1_IO01__GPIO1_IO1				  0x0004 0x0034 0x0000 0x0 0x0
+#define MX7D_PAD_GPIO1_IO01__PWM1_OUT				  0x0004 0x0034 0x0000 0x1 0x0
+#define MX7D_PAD_GPIO1_IO01__CCM_ENET_REF_CLK3			  0x0004 0x0034 0x0000 0x2 0x0
+#define MX7D_PAD_GPIO1_IO01__SAI1_MCLK				  0x0004 0x0034 0x0000 0x3 0x0
+#define MX7D_PAD_GPIO1_IO01__OBSERVE0_OUT			  0x0004 0x0034 0x0000 0x6 0x0
+#define MX7D_PAD_GPIO1_IO02__GPIO1_IO2				  0x0008 0x0038 0x0000 0x0 0x0
+#define MX7D_PAD_GPIO1_IO02__PWM2_OUT				  0x0008 0x0038 0x0000 0x1 0x0
+#define MX7D_PAD_GPIO1_IO02__CCM_ENET_REF_CLK1			  0x0008 0x0038 0x0564 0x2 0x3
+#define MX7D_PAD_GPIO1_IO02__SAI2_MCLK				  0x0008 0x0038 0x0000 0x3 0x0
+#define MX7D_PAD_GPIO1_IO02__CCM_CLKO1				  0x0008 0x0038 0x0000 0x5 0x0
+#define MX7D_PAD_GPIO1_IO02__OBSERVE1_OUT			  0x0008 0x0038 0x0000 0x6 0x0
+#define MX7D_PAD_GPIO1_IO02__USB_OTG1_ID			  0x0008 0x0038 0x0734 0x7 0x3
+#define MX7D_PAD_GPIO1_IO03__GPIO1_IO3				  0x000C 0x003C 0x0000 0x0 0x0
+#define MX7D_PAD_GPIO1_IO03__PWM3_OUT				  0x000C 0x003C 0x0000 0x1 0x0
+#define MX7D_PAD_GPIO1_IO03__CCM_ENET_REF_CLK2			  0x000C 0x003C 0x0570 0x2 0x3
+#define MX7D_PAD_GPIO1_IO03__SAI3_MCLK				  0x000C 0x003C 0x0000 0x3 0x0
+#define MX7D_PAD_GPIO1_IO03__CCM_CLKO2				  0x000C 0x003C 0x0000 0x5 0x0
+#define MX7D_PAD_GPIO1_IO03__OBSERVE2_OUT			  0x000C 0x003C 0x0000 0x6 0x0
+#define MX7D_PAD_GPIO1_IO03__USB_OTG2_ID			  0x000C 0x003C 0x0730 0x7 0x3
+#define MX7D_PAD_GPIO1_IO04__GPIO1_IO4				  0x0010 0x0040 0x0000 0x0 0x0
+#define MX7D_PAD_GPIO1_IO04__USB_OTG1_OC			  0x0010 0x0040 0x072C 0x1 0x1
+#define MX7D_PAD_GPIO1_IO04__FLEXTIMER1_CH4			  0x0010 0x0040 0x0594 0x2 0x1
+#define MX7D_PAD_GPIO1_IO04__UART5_CTS_B			  0x0010 0x0040 0x0710 0x3 0x4
+#define MX7D_PAD_GPIO1_IO04__I2C1_SCL				  0x0010 0x0040 0x05D4 0x4 0x2
+#define MX7D_PAD_GPIO1_IO04__OBSERVE3_OUT			  0x0010 0x0040 0x0000 0x6 0x0
+#define MX7D_PAD_GPIO1_IO05__GPIO1_IO5				  0x0014 0x0044 0x0000 0x0 0x0
+#define MX7D_PAD_GPIO1_IO05__USB_OTG1_PWR			  0x0014 0x0044 0x0000 0x1 0x0
+#define MX7D_PAD_GPIO1_IO05__FLEXTIMER1_CH5			  0x0014 0x0044 0x0598 0x2 0x1
+#define MX7D_PAD_GPIO1_IO05__UART5_RTS_B			  0x0014 0x0044 0x0710 0x3 0x5
+#define MX7D_PAD_GPIO1_IO05__I2C1_SDA				  0x0014 0x0044 0x05D8 0x4 0x2
+#define MX7D_PAD_GPIO1_IO05__OBSERVE4_OUT			  0x0014 0x0044 0x0000 0x6 0x0
+#define MX7D_PAD_GPIO1_IO06__GPIO1_IO6				  0x0018 0x0048 0x0000 0x0 0x0
+#define MX7D_PAD_GPIO1_IO06__USB_OTG2_OC			  0x0018 0x0048 0x0728 0x1 0x1
+#define MX7D_PAD_GPIO1_IO06__FLEXTIMER1_CH6			  0x0018 0x0048 0x059C 0x2 0x1
+#define MX7D_PAD_GPIO1_IO06__UART5_RX_DATA			  0x0018 0x0048 0x0714 0x3 0x4
+#define MX7D_PAD_GPIO1_IO06__I2C2_SCL				  0x0018 0x0048 0x05DC 0x4 0x2
+#define MX7D_PAD_GPIO1_IO06__CCM_WAIT				  0x0018 0x0048 0x0000 0x5 0x0
+#define MX7D_PAD_GPIO1_IO06__KPP_ROW4				  0x0018 0x0048 0x0624 0x6 0x1
+#define MX7D_PAD_GPIO1_IO07__GPIO1_IO7				  0x001C 0x004C 0x0000 0x0 0x0
+#define MX7D_PAD_GPIO1_IO07__USB_OTG2_PWR			  0x001C 0x004C 0x0000 0x1 0x0
+#define MX7D_PAD_GPIO1_IO07__FLEXTIMER1_CH7			  0x001C 0x004C 0x05A0 0x2 0x1
+#define MX7D_PAD_GPIO1_IO07__UART5_TX_DATA			  0x001C 0x004C 0x0714 0x3 0x5
+#define MX7D_PAD_GPIO1_IO07__I2C2_SDA				  0x001C 0x004C 0x05E0 0x4 0x2
+#define MX7D_PAD_GPIO1_IO07__CCM_STOP				  0x001C 0x004C 0x0000 0x5 0x0
+#define MX7D_PAD_GPIO1_IO07__KPP_COL4				  0x001C 0x004C 0x0604 0x6 0x1
+#define MX7D_PAD_GPIO1_IO08__GPIO1_IO8                            0x0014 0x026C 0x0000 0x0 0x0
+#define MX7D_PAD_GPIO1_IO08__SD1_VSELECT                          0x0014 0x026C 0x0000 0x1 0x0
+#define MX7D_PAD_GPIO1_IO08__WDOG1_WDOG_B                         0x0014 0x026C 0x0000 0x2 0x0
+#define MX7D_PAD_GPIO1_IO08__UART3_DCE_RX                         0x0014 0x026C 0x0704 0x3 0x0
+#define MX7D_PAD_GPIO1_IO08__UART3_DTE_TX                         0x0014 0x026C 0x0000 0x3 0x0
+#define MX7D_PAD_GPIO1_IO08__I2C3_SCL                             0x0014 0x026C 0x05E4 0x4 0x0
+#define MX7D_PAD_GPIO1_IO08__KPP_COL5                             0x0014 0x026C 0x0608 0x6 0x0
+#define MX7D_PAD_GPIO1_IO08__PWM1_OUT                             0x0014 0x026C 0x0000 0x7 0x0
+#define MX7D_PAD_GPIO1_IO09__GPIO1_IO9                            0x0018 0x0270 0x0000 0x0 0x0
+#define MX7D_PAD_GPIO1_IO09__SD1_LCTL                             0x0018 0x0270 0x0000 0x1 0x0
+#define MX7D_PAD_GPIO1_IO09__CCM_ENET_REF_CLK3                    0x0018 0x0270 0x0000 0x2 0x0
+#define MX7D_PAD_GPIO1_IO09__UART3_DCE_TX                         0x0018 0x0270 0x0000 0x3 0x0
+#define MX7D_PAD_GPIO1_IO09__UART3_DTE_RX                         0x0018 0x0270 0x0704 0x3 0x1
+#define MX7D_PAD_GPIO1_IO09__I2C3_SDA                             0x0018 0x0270 0x05E8 0x4 0x0
+#define MX7D_PAD_GPIO1_IO09__CCM_PMIC_READY                       0x0018 0x0270 0x04F4 0x5 0x0
+#define MX7D_PAD_GPIO1_IO09__KPP_ROW5                             0x0018 0x0270 0x0628 0x6 0x0
+#define MX7D_PAD_GPIO1_IO09__PWM2_OUT                             0x0018 0x0270 0x0000 0x7 0x0
+#define MX7D_PAD_GPIO1_IO10__GPIO1_IO10                           0x001C 0x0274 0x0000 0x0 0x0
+#define MX7D_PAD_GPIO1_IO10__SD2_LCTL                             0x001C 0x0274 0x0000 0x1 0x0
+#define MX7D_PAD_GPIO1_IO10__ENET1_MDIO                           0x001C 0x0274 0x0568 0x2 0x0
+#define MX7D_PAD_GPIO1_IO10__UART3_DCE_RTS                        0x001C 0x0274 0x0700 0x3 0x0
+#define MX7D_PAD_GPIO1_IO10__UART3_DTE_CTS                        0x001C 0x0274 0x0000 0x3 0x0
+#define MX7D_PAD_GPIO1_IO10__I2C4_SCL                             0x001C 0x0274 0x05EC 0x4 0x0
+#define MX7D_PAD_GPIO1_IO10__FLEXTIMER1_PHA                       0x001C 0x0274 0x05A4 0x5 0x0
+#define MX7D_PAD_GPIO1_IO10__KPP_COL6                             0x001C 0x0274 0x060C 0x6 0x0
+#define MX7D_PAD_GPIO1_IO10__PWM3_OUT                             0x001C 0x0274 0x0000 0x7 0x0
+#define MX7D_PAD_GPIO1_IO11__GPIO1_IO11                           0x0020 0x0278 0x0000 0x0 0x0
+#define MX7D_PAD_GPIO1_IO11__SD3_LCTL                             0x0020 0x0278 0x0000 0x1 0x0
+#define MX7D_PAD_GPIO1_IO11__ENET1_MDC                            0x0020 0x0278 0x0000 0x2 0x0
+#define MX7D_PAD_GPIO1_IO11__UART3_DCE_CTS                        0x0020 0x0278 0x0000 0x3 0x0
+#define MX7D_PAD_GPIO1_IO11__UART3_DTE_RTS                        0x0020 0x0278 0x0700 0x3 0x1
+#define MX7D_PAD_GPIO1_IO11__I2C4_SDA                             0x0020 0x0278 0x05F0 0x4 0x0
+#define MX7D_PAD_GPIO1_IO11__FLEXTIMER1_PHB                       0x0020 0x0278 0x05A8 0x5 0x0
+#define MX7D_PAD_GPIO1_IO11__KPP_ROW6                             0x0020 0x0278 0x062C 0x6 0x0
+#define MX7D_PAD_GPIO1_IO11__PWM4_OUT                             0x0020 0x0278 0x0000 0x7 0x0
+#define MX7D_PAD_GPIO1_IO12__GPIO1_IO12                           0x0024 0x027C 0x0000 0x0 0x0
+#define MX7D_PAD_GPIO1_IO12__SD2_VSELECT                          0x0024 0x027C 0x0000 0x1 0x0
+#define MX7D_PAD_GPIO1_IO12__CCM_ENET_REF_CLK1                    0x0024 0x027C 0x0564 0x2 0x0
+#define MX7D_PAD_GPIO1_IO12__FLEXCAN1_RX                          0x0024 0x027C 0x04DC 0x3 0x0
+#define MX7D_PAD_GPIO1_IO12__CM4_NMI                              0x0024 0x027C 0x0000 0x4 0x0
+#define MX7D_PAD_GPIO1_IO12__CCM_EXT_CLK1                         0x0024 0x027C 0x04E4 0x5 0x0
+#define MX7D_PAD_GPIO1_IO12__SNVS_VIO_5                           0x0024 0x027C 0x0000 0x6 0x0
+#define MX7D_PAD_GPIO1_IO12__USB_OTG1_ID                          0x0024 0x027C 0x0734 0x7 0x0
+#define MX7D_PAD_GPIO1_IO13__GPIO1_IO13                           0x0028 0x0280 0x0000 0x0 0x0
+#define MX7D_PAD_GPIO1_IO13__SD3_VSELECT                          0x0028 0x0280 0x0000 0x1 0x0
+#define MX7D_PAD_GPIO1_IO13__CCM_ENET_REF_CLK2                    0x0028 0x0280 0x0570 0x2 0x0
+#define MX7D_PAD_GPIO1_IO13__FLEXCAN1_TX                          0x0028 0x0280 0x0000 0x3 0x0
+#define MX7D_PAD_GPIO1_IO13__CCM_PMIC_READY                       0x0028 0x0280 0x04F4 0x4 0x1
+#define MX7D_PAD_GPIO1_IO13__CCM_EXT_CLK2                         0x0028 0x0280 0x04E8 0x5 0x0
+#define MX7D_PAD_GPIO1_IO13__SNVS_VIO_5_CTL                       0x0028 0x0280 0x0000 0x6 0x0
+#define MX7D_PAD_GPIO1_IO13__USB_OTG2_ID                          0x0028 0x0280 0x0730 0x7 0x0
+#define MX7D_PAD_GPIO1_IO14__GPIO1_IO14                           0x002C 0x0284 0x0000 0x0 0x0
+#define MX7D_PAD_GPIO1_IO14__SD3_CD_B                             0x002C 0x0284 0x0738 0x1 0x0
+#define MX7D_PAD_GPIO1_IO14__ENET2_MDIO                           0x002C 0x0284 0x0574 0x2 0x0
+#define MX7D_PAD_GPIO1_IO14__FLEXCAN2_RX                          0x002C 0x0284 0x04E0 0x3 0x0
+#define MX7D_PAD_GPIO1_IO14__WDOG3_WDOG_B                         0x002C 0x0284 0x0000 0x4 0x0
+#define MX7D_PAD_GPIO1_IO14__CCM_EXT_CLK3                         0x002C 0x0284 0x04EC 0x5 0x0
+#define MX7D_PAD_GPIO1_IO14__SDMA_EXT_EVENT0                      0x002C 0x0284 0x06D8 0x6 0x0
+#define MX7D_PAD_GPIO1_IO15__GPIO1_IO15                           0x0030 0x0288 0x0000 0x0 0x0
+#define MX7D_PAD_GPIO1_IO15__SD3_WP                               0x0030 0x0288 0x073C 0x1 0x0
+#define MX7D_PAD_GPIO1_IO15__ENET2_MDC                            0x0030 0x0288 0x0000 0x2 0x0
+#define MX7D_PAD_GPIO1_IO15__FLEXCAN2_TX                          0x0030 0x0288 0x0000 0x3 0x0
+#define MX7D_PAD_GPIO1_IO15__WDOG4_WDOG_B                         0x0030 0x0288 0x0000 0x4 0x0
+#define MX7D_PAD_GPIO1_IO15__CCM_EXT_CLK4                         0x0030 0x0288 0x04F0 0x5 0x0
+#define MX7D_PAD_GPIO1_IO15__SDMA_EXT_EVENT1                      0x0030 0x0288 0x06DC 0x6 0x0
 #define MX7D_PAD_EPDC_DATA00__EPDC_DATA0                          0x0034 0x02A4 0x0000 0x0 0x0
 #define MX7D_PAD_EPDC_DATA00__SIM1_PORT2_TRXD                     0x0034 0x02A4 0x0000 0x1 0x0
 #define MX7D_PAD_EPDC_DATA00__QSPI_A_DATA0                        0x0034 0x02A4 0x0000 0x2 0x0
-- 
1.9.1



From b38611 at freescale.com  Sun Aug 23 20:29:51 2015
From: b38611 at freescale.com (Fugang Duan)
Date: Mon, 24 Aug 2015 11:29:51 +0800
Subject: [PATCH v2 4/5] ARM: dts: imx7d: add fec1 and fec2 support for i.MX7d
 soc
In-Reply-To: <1440386992-6775-1-git-send-email-b38611@freescale.com>
References: <1440386992-6775-1-git-send-email-b38611@freescale.com>
Message-ID: <1440386992-6775-5-git-send-email-b38611@freescale.com>

Add fec1 and fec2 nodes for i.MX7d soc.

Signed-off-by: Fugang Duan <B38611 at freescale.com>
---
 arch/arm/boot/dts/imx7d.dtsi | 36 ++++++++++++++++++++++++++++++++++++
 1 file changed, 36 insertions(+)

diff --git a/arch/arm/boot/dts/imx7d.dtsi b/arch/arm/boot/dts/imx7d.dtsi
index b738ce0..7631492 100644
--- a/arch/arm/boot/dts/imx7d.dtsi
+++ b/arch/arm/boot/dts/imx7d.dtsi
@@ -729,6 +729,42 @@
 				bus-width = <4>;
 				status = "disabled";
 			};
+
+			fec1: ethernet at 30be0000 {
+				compatible = "fsl,imx7d-fec", "fsl,imx6sx-fec";
+				reg = <0x30be0000 0x10000>;
+				interrupts = <GIC_SPI 118 IRQ_TYPE_LEVEL_HIGH>,
+					<GIC_SPI 119 IRQ_TYPE_LEVEL_HIGH>,
+					<GIC_SPI 120 IRQ_TYPE_LEVEL_HIGH>;
+				clocks = <&clks IMX7D_ENET_AXI_ROOT_CLK>,
+					<&clks IMX7D_ENET_AXI_ROOT_CLK>,
+					<&clks IMX7D_ENET1_TIME_ROOT_CLK>,
+					<&clks IMX7D_PLL_ENET_MAIN_125M_CLK>,
+					<&clks IMX7D_ENET_PHY_REF_ROOT_CLK>;
+				clock-names = "ipg", "ahb", "ptp",
+					"enet_clk_ref", "enet_out";
+				fsl,num-tx-queues=<3>;
+				fsl,num-rx-queues=<3>;
+				status = "disabled";
+			};
+
+			fec2: ethernet at 30bf0000 {
+				compatible = "fsl,imx7d-fec", "fsl,imx6sx-fec";
+				reg = <0x30bf0000 0x10000>;
+				interrupts = <GIC_SPI 100 IRQ_TYPE_LEVEL_HIGH>,
+					<GIC_SPI 101 IRQ_TYPE_LEVEL_HIGH>,
+					<GIC_SPI 102 IRQ_TYPE_LEVEL_HIGH>;
+				clocks = <&clks IMX7D_ENET_AXI_ROOT_CLK>,
+					<&clks IMX7D_ENET_AXI_ROOT_CLK>,
+					<&clks IMX7D_ENET2_TIME_ROOT_CLK>,
+					<&clks IMX7D_PLL_ENET_MAIN_125M_CLK>,
+					<&clks IMX7D_ENET_PHY_REF_ROOT_CLK>;
+				clock-names = "ipg", "ahb", "ptp",
+					"enet_clk_ref", "enet_out";
+				fsl,num-tx-queues=<3>;
+				fsl,num-rx-queues=<3>;
+				status = "disabled";
+			};
 		};
 	};
 };
-- 
1.9.1



From petr.cvek at tul.cz  Sun Aug 23 20:39:57 2015
From: petr.cvek at tul.cz (Petr Cvek)
Date: Mon, 24 Aug 2015 05:39:57 +0200
Subject: [PATCH v2 01/21] ARM: pxa: magician: Fix Kconfig for magician to
 always include htc-egpio
In-Reply-To: <1439969382.11928.6.camel@gmail.com>
References: <cover.1439843482.git.petr.cvek@tul.cz> <55D25880.3030507@tul.cz>
 <87zj1o8n3w.fsf@belgarion.home> <55D38F60.7010405@tul.cz>
 <1439969382.11928.6.camel@gmail.com>
Message-ID: <55DA920D.4030605@tul.cz>

Dne 19.8.2015 v 09:29 Philipp Zabel napsal(a):
> Am Dienstag, den 18.08.2015, 22:02 +0200 schrieb Petr Cvek:
>> Dne 18.8.2015 v 20:31 Robert Jarzmik napsal(a):
>>> Petr Cvek <petr.cvek at tul.cz> writes:
>>>
>>>> The htc-egpio driver should be always included in the kernel as 
>>>> it
>>>> controls MMC/charging/IrDA power, which is the only way to get
>>>> an useful rootfs.
>>>>
>>>> Signed-off-by: Petr Cvek <petr.cvek at tul.cz>
>>> It's already defined in magician_defconfig, why enforce it in 
>>> Kconfig ?
>>
>> Good remark, I did not use defconfig at all (as I had to fix from 
>> zero configuration + I did not know if defconfig works and will be 
>> supported in the future).
>>
>> I will check if magician_defconfig needs to be updated (probably for 
>> leds).
>>
>>>
>>> And if it's enforced and I want to build a kernel for magician 
>>> without
>>> MMC/charging/IrDA, why should I be forced to build in HTC_EGPIO ?
>>>
>>> Or said differently, does a kernel without HTC_EGPIO is proven to 
>>> fail 100%
>>> without this option ?
>>
>> Kernel will probably run OK, but the phone will be unusable (for any 
>> practical purposes). The EGPIO chip (CPLD) will stay in the state 
>> programmed from the previous environment (bootloader or WinCE/Mobile) 
>> and drivers fail to init because of the missing EGPIO (and if they 
>> init, they will be without any idea about state of the peripherals 
>> (no charger detection/charging current stuck on the previous 
>> settings, no LCD backlight control, no IrDA, no rootfs, no GSM, no 
>> sound, no LEDs).
>>
>> Different PCB revisions probably use EGPIO pin for LCD power (and at 
>> least on my phone, LCD power must have very specific order).
>>
>> For future (when ROM XIP will work) I would like to be able boot 
>> kernel from flash, which itself uses EGPIO for Vpp control (another 
>> initial EGPIO configuration). Last possible boot is from JTAG and 
>> there will be no previous EGPIO initialization.
>>
>> Petr
> 
> I agree with Robert, let's drop this patch.
As finishing patchset v3 I've finally got enough deterministic configuration.

Situation A:
	Most code same as v2 patchset (GPIO init, devices, ...)
	RTC patch (not in patchset, but vanilla causes errors during boot)
	Boot from bootloader (htc-tools), kernel from RAM 
	Rootfs on SDHC
	EGPIO driver in kernel
	-> boot
Situation B:
	EGPIO disabled
	-> every EGPIO requests fail (bad LCD readability, but most probably by -EDEFER)
	mci driver fails to start (SD card power EGPIO and others are not found)
	kernel prints cannot open root device ...
	there is kernel panic from rootfs mount (stackdump with some *mount* function name)

-> So it seems EGPIO driver is required for standard boot.

When trying to boot with initrd, the htc-boot will freeze during image upload (around 5 MB of initrd, not enough for rootfs), but maybe I'm doing something wrong. 

-> Without initrd, there is no way to get useful rootfs.

Petr


From leilk.liu at mediatek.com  Sun Aug 23 20:45:14 2015
From: leilk.liu at mediatek.com (Leilk Liu)
Date: Mon, 24 Aug 2015 11:45:14 +0800
Subject: [PATCHi v3 0/4] Fixup mediatek spi driver 
Message-ID: <1440387918-22191-1-git-send-email-leilk.liu@mediatek.com>

From: Leilk Liu <leilk.liu at mediatek.com>

This series are based on 4.2-rc1 and provide four patches to fix mediatek spi driver.

Change in v3:
1. The follow patches are applied, so remove them from series:
  - spi: mediatek: fix spi incorrect endian usage
  - spi: medaitek: revise quirks compatibility style
  - spi: mediatek: use BIT() to instead of SPI_CMD_*_OFFSET
2. The patch "spi: mediatek: revise coding style" title is not clear, so split it to four patches.

Change in v2:
1. The patch "spi: mediatek: remove redundant clock in prepare_hardware/unprepare_hardware" 
   is applied, so remove it from series.
2. fix incorrect endian usage to support little-endian and big-endian system.
3. revise quirks style to bool.
4. use BIT() to instead of SPI_CMD_*_OFFSET.
5. revise coding style, such as time name, and variable type. 

Leilk Liu (4):
  spi: mediatek: add linux/io.h include file
  spi: mediatek: replace int with u32, delete TAB and define
    MTK_SPI_PAUSE_INT_STATUS marco
  spi: mediatek: add PM clk_prepare_enable fail flow
  spi: mediatek: replace *_time name

 drivers/spi/spi-mt65xx.c | 52 ++++++++++++++++++++++++++++--------------------
 1 file changed, 30 insertions(+), 22 deletions(-)

--
1.8.1.1.dirty



From leilk.liu at mediatek.com  Sun Aug 23 20:45:16 2015
From: leilk.liu at mediatek.com (Leilk Liu)
Date: Mon, 24 Aug 2015 11:45:16 +0800
Subject: [PATCH v3 2/4] spi: mediatek: replace int with u32,
 delete TAB and define MTK_SPI_PAUSE_INT_STATUS marco
In-Reply-To: <1440387918-22191-1-git-send-email-leilk.liu@mediatek.com>
References: <1440387918-22191-1-git-send-email-leilk.liu@mediatek.com>
Message-ID: <1440387918-22191-3-git-send-email-leilk.liu@mediatek.com>

this patch replaces int with u32, deletes TAB, and defines
MTK_SPI_PAUSE_INT_STATUS marco.

Signed-off-by: Leilk Liu <leilk.liu at mediatek.com>
---
 drivers/spi/spi-mt65xx.c | 18 ++++++++++--------
 1 file changed, 10 insertions(+), 8 deletions(-)

diff --git a/drivers/spi/spi-mt65xx.c b/drivers/spi/spi-mt65xx.c
index fe4eda3..f81618c 100644
--- a/drivers/spi/spi-mt65xx.c
+++ b/drivers/spi/spi-mt65xx.c
@@ -67,6 +67,8 @@
 
 #define MT8173_SPI_MAX_PAD_SEL 3
 
+#define MTK_SPI_PAUSE_INT_STATUS 0x2
+
 #define MTK_SPI_IDLE 0
 #define MTK_SPI_PAUSED 1
 
@@ -179,7 +181,7 @@ static int mtk_spi_prepare_hardware(struct spi_master *master)
 
 	trans = list_first_entry(&msg->transfers, struct spi_transfer,
 				 transfer_list);
-	if (trans->cs_change == 0) {
+	if (!trans->cs_change) {
 		mdata->state = MTK_SPI_IDLE;
 		mtk_spi_reset(mdata);
 	}
@@ -269,11 +271,11 @@ static void mtk_spi_setup_packet(struct spi_master *master)
 	u32 packet_size, packet_loop, reg_val;
 	struct mtk_spi *mdata = spi_master_get_devdata(master);
 
-	packet_size = min_t(unsigned, mdata->xfer_len, MTK_SPI_PACKET_SIZE);
+	packet_size = min_t(u32, mdata->xfer_len, MTK_SPI_PACKET_SIZE);
 	packet_loop = mdata->xfer_len / packet_size;
 
 	reg_val = readl(mdata->base + SPI_CFG1_REG);
-	reg_val &= ~(SPI_CFG1_PACKET_LENGTH_MASK + SPI_CFG1_PACKET_LOOP_MASK);
+	reg_val &= ~(SPI_CFG1_PACKET_LENGTH_MASK | SPI_CFG1_PACKET_LOOP_MASK);
 	reg_val |= (packet_size - 1) << SPI_CFG1_PACKET_LENGTH_OFFSET;
 	reg_val |= (packet_loop - 1) << SPI_CFG1_PACKET_LOOP_OFFSET;
 	writel(reg_val, mdata->base + SPI_CFG1_REG);
@@ -281,7 +283,7 @@ static void mtk_spi_setup_packet(struct spi_master *master)
 
 static void mtk_spi_enable_transfer(struct spi_master *master)
 {
-	int cmd;
+	u32 cmd;
 	struct mtk_spi *mdata = spi_master_get_devdata(master);
 
 	cmd = readl(mdata->base + SPI_CMD_REG);
@@ -292,9 +294,9 @@ static void mtk_spi_enable_transfer(struct spi_master *master)
 	writel(cmd, mdata->base + SPI_CMD_REG);
 }
 
-static int mtk_spi_get_mult_delta(int xfer_len)
+static int mtk_spi_get_mult_delta(u32 xfer_len)
 {
-	int mult_delta;
+	u32 mult_delta;
 
 	if (xfer_len > MTK_SPI_PACKET_SIZE)
 		mult_delta = xfer_len % MTK_SPI_PACKET_SIZE;
@@ -435,7 +437,7 @@ static irqreturn_t mtk_spi_interrupt(int irq, void *dev_id)
 	struct spi_transfer *trans = mdata->cur_transfer;
 
 	reg_val = readl(mdata->base + SPI_STATUS0_REG);
-	if (reg_val & 0x2)
+	if (reg_val & MTK_SPI_PAUSE_INT_STATUS)
 		mdata->state = MTK_SPI_PAUSED;
 	else
 		mdata->state = MTK_SPI_IDLE;
@@ -498,7 +500,7 @@ static int mtk_spi_probe(struct platform_device *pdev)
 	struct mtk_spi *mdata;
 	const struct of_device_id *of_id;
 	struct resource *res;
-	int	irq, ret;
+	int irq, ret;
 
 	master = spi_alloc_master(&pdev->dev, sizeof(*mdata));
 	if (!master) {
-- 
1.8.1.1.dirty



From leilk.liu at mediatek.com  Sun Aug 23 20:45:18 2015
From: leilk.liu at mediatek.com (Leilk Liu)
Date: Mon, 24 Aug 2015 11:45:18 +0800
Subject: [PATCH v3 4/4] spi: mediatek: replace *_time name
In-Reply-To: <1440387918-22191-1-git-send-email-leilk.liu@mediatek.com>
References: <1440387918-22191-1-git-send-email-leilk.liu@mediatek.com>
Message-ID: <1440387918-22191-5-git-send-email-leilk.liu@mediatek.com>

This patch replaces *_time name in mtk_spi_prepare_transfer().

Signed-off-by: Leilk Liu <leilk.liu at mediatek.com>
---
 drivers/spi/spi-mt65xx.c | 20 ++++++++------------
 1 file changed, 8 insertions(+), 12 deletions(-)

diff --git a/drivers/spi/spi-mt65xx.c b/drivers/spi/spi-mt65xx.c
index e14f583..eaadc7e 100644
--- a/drivers/spi/spi-mt65xx.c
+++ b/drivers/spi/spi-mt65xx.c
@@ -238,8 +238,7 @@ static void mtk_spi_set_cs(struct spi_device *spi, bool enable)
 static void mtk_spi_prepare_transfer(struct spi_master *master,
 				     struct spi_transfer *xfer)
 {
-	u32 spi_clk_hz, div, high_time, low_time, holdtime,
-	    setuptime, cs_idletime, reg_val = 0;
+	u32 spi_clk_hz, div, sck_time, cs_time, reg_val = 0;
 	struct mtk_spi *mdata = spi_master_get_devdata(master);
 
 	spi_clk_hz = clk_get_rate(mdata->spi_clk);
@@ -248,21 +247,18 @@ static void mtk_spi_prepare_transfer(struct spi_master *master,
 	else
 		div = 1;
 
-	high_time = (div + 1) / 2;
-	low_time = (div + 1) / 2;
-	holdtime = (div + 1) / 2 * 2;
-	setuptime = (div + 1) / 2 * 2;
-	cs_idletime = (div + 1) / 2 * 2;
+	sck_time = (div + 1) / 2;
+	cs_time = sck_time * 2;
 
-	reg_val |= (((high_time - 1) & 0xff) << SPI_CFG0_SCK_HIGH_OFFSET);
-	reg_val |= (((low_time - 1) & 0xff) << SPI_CFG0_SCK_LOW_OFFSET);
-	reg_val |= (((holdtime - 1) & 0xff) << SPI_CFG0_CS_HOLD_OFFSET);
-	reg_val |= (((setuptime - 1) & 0xff) << SPI_CFG0_CS_SETUP_OFFSET);
+	reg_val |= (((sck_time - 1) & 0xff) << SPI_CFG0_SCK_HIGH_OFFSET);
+	reg_val |= (((sck_time - 1) & 0xff) << SPI_CFG0_SCK_LOW_OFFSET);
+	reg_val |= (((cs_time - 1) & 0xff) << SPI_CFG0_CS_HOLD_OFFSET);
+	reg_val |= (((cs_time - 1) & 0xff) << SPI_CFG0_CS_SETUP_OFFSET);
 	writel(reg_val, mdata->base + SPI_CFG0_REG);
 
 	reg_val = readl(mdata->base + SPI_CFG1_REG);
 	reg_val &= ~SPI_CFG1_CS_IDLE_MASK;
-	reg_val |= (((cs_idletime - 1) & 0xff) << SPI_CFG1_CS_IDLE_OFFSET);
+	reg_val |= (((cs_time - 1) & 0xff) << SPI_CFG1_CS_IDLE_OFFSET);
 	writel(reg_val, mdata->base + SPI_CFG1_REG);
 }
 
-- 
1.8.1.1.dirty



From leilk.liu at mediatek.com  Sun Aug 23 20:45:15 2015
From: leilk.liu at mediatek.com (Leilk Liu)
Date: Mon, 24 Aug 2015 11:45:15 +0800
Subject: [PATCH v3 1/4] spi: mediatek: add linux/io.h include file
In-Reply-To: <1440387918-22191-1-git-send-email-leilk.liu@mediatek.com>
References: <1440387918-22191-1-git-send-email-leilk.liu@mediatek.com>
Message-ID: <1440387918-22191-2-git-send-email-leilk.liu@mediatek.com>

mediatek spi driver uses readl/writel, so add linux/io.h,
even so it's implicitly imported by spi/spi.h

Signed-off-by: Leilk Liu <leilk.liu at mediatek.com>
---
 drivers/spi/spi-mt65xx.c | 1 +
 1 file changed, 1 insertion(+)

diff --git a/drivers/spi/spi-mt65xx.c b/drivers/spi/spi-mt65xx.c
index 43c1dd5..fe4eda3 100644
--- a/drivers/spi/spi-mt65xx.c
+++ b/drivers/spi/spi-mt65xx.c
@@ -16,6 +16,7 @@
 #include <linux/device.h>
 #include <linux/err.h>
 #include <linux/interrupt.h>
+#include <linux/io.h>
 #include <linux/ioport.h>
 #include <linux/module.h>
 #include <linux/of.h>
-- 
1.8.1.1.dirty



From leilk.liu at mediatek.com  Sun Aug 23 20:45:17 2015
From: leilk.liu at mediatek.com (Leilk Liu)
Date: Mon, 24 Aug 2015 11:45:17 +0800
Subject: [PATCH v3 3/4] spi: mediatek: add PM clk_prepare_enable fail flow
In-Reply-To: <1440387918-22191-1-git-send-email-leilk.liu@mediatek.com>
References: <1440387918-22191-1-git-send-email-leilk.liu@mediatek.com>
Message-ID: <1440387918-22191-4-git-send-email-leilk.liu@mediatek.com>

This patch adds PM clk_prepare_enable fail flow.

Signed-off-by: Leilk Liu <leilk.liu at mediatek.com>
---
 drivers/spi/spi-mt65xx.c | 13 +++++++++++--
 1 file changed, 11 insertions(+), 2 deletions(-)

diff --git a/drivers/spi/spi-mt65xx.c b/drivers/spi/spi-mt65xx.c
index f81618c..e14f583 100644
--- a/drivers/spi/spi-mt65xx.c
+++ b/drivers/spi/spi-mt65xx.c
@@ -665,8 +665,10 @@ static int mtk_spi_resume(struct device *dev)
 
 	if (!pm_runtime_suspended(dev)) {
 		ret = clk_prepare_enable(mdata->spi_clk);
-		if (ret < 0)
+		if (ret < 0) {
+			dev_err(dev, "failed to enable spi_clk (%d)\n", ret);
 			return ret;
+		}
 	}
 
 	ret = spi_master_resume(master);
@@ -692,8 +694,15 @@ static int mtk_spi_runtime_resume(struct device *dev)
 {
 	struct spi_master *master = dev_get_drvdata(dev);
 	struct mtk_spi *mdata = spi_master_get_devdata(master);
+	int ret;
+
+	ret = clk_prepare_enable(mdata->spi_clk);
+	if (ret < 0) {
+		dev_err(dev, "failed to enable spi_clk (%d)\n", ret);
+		return ret;
+	}
 
-	return clk_prepare_enable(mdata->spi_clk);
+	return 0;
 }
 #endif /* CONFIG_PM */
 
-- 
1.8.1.1.dirty



From k.kozlowski at samsung.com  Sun Aug 23 21:20:02 2015
From: k.kozlowski at samsung.com (Krzysztof Kozlowski)
Date: Mon, 24 Aug 2015 13:20:02 +0900
Subject: [PATCH v3 06/14] Documentation: drm/bridge: add document for
 analogix_dp
In-Reply-To: <55DA8486.1000803@rock-chips.com>
References: <1439995728-18046-1-git-send-email-ykk@rock-chips.com>
 <1439995834-18363-1-git-send-email-ykk@rock-chips.com>
 <CAL_JsqLz+8RtBucctUj4euXZ3Ac0DvB52N9ONpAerh5T9BiTJg@mail.gmail.com>
 <CAJKOXPeEm8exg_UG0tDnaEGO40ejBKZ-ok=bKbVrwYvXnDaMdg@mail.gmail.com>
 <55DA8486.1000803@rock-chips.com>
Message-ID: <55DA9B72.1030804@samsung.com>

On 24.08.2015 11:42, Yakir Yang wrote:
> Hi Krzysztof,
> 
> ? 08/23/2015 07:43 PM, Krzysztof Kozlowski ??:
>> 2015-08-24 8:23 GMT+09:00 Rob Herring <robherring2 at gmail.com>:
>>> On Wed, Aug 19, 2015 at 9:50 AM, Yakir Yang <ykk at rock-chips.com> wrote:
>>>> Analogix dp driver is split from exynos dp driver, so we just
>>>> make an copy of exynos_dp.txt, and then simplify exynos_dp.txt
>>>>
>>>> Beside update some exynos dtsi file with the latest change
>>>> according to the devicetree binding documents.
>>> You can't just change the exynos bindings and break compatibility. Is
>>> there some agreement with exynos folks to do this?
>> No, there is no agreement. This wasn't even sent to Exynos maintainers.
> 
> Sorry about this one, actually I have add Exynos maintainers in version
> 1 & version 2,
> but lose some maintainers in version 3, I would fix it in bellow versions.
> 
>> Additionally the patchset did not look interesting to me because of
>> misleading subject - Documentation instead of "ARM: dts:".
>>
>> Yakir, please:
>> 1. Provide backward compatibility. Mark old properties as deprecated
>> but still support them.
> 
> Do you mean that I should keep the old properties declare in exynos-dp.txt,
> but just mark them as deprecated flag.

That is one of ways how to do this. However more important is that
driver should still support old bindings so such code:

-       if (of_property_read_u32(dp_node, "samsung,color-space",
+       if (of_property_read_u32(dp_node, "analogix,color-space",

is probably wrong. Will the driver support old DTB in the same way as it
was supporting before the change?

> Let me show same examples, make
> me understand your suggest rightly.

exynos-dp already contains deprecated properties. Other ways of doing
this would be:
Documentation/devicetree/bindings/input/touchscreen/touchscreen.txt
Documentation/devicetree/bindings/rtc/s3c-rtc.txt

It depends up to you. The "touchscreen" looks good because it organizes
old properties in a common section. In case of exynos-dp.txt you can add
at beginning of file information about new bindings and mark everything
deprecated.

> 
> 1. "samsung,ycbcr-coeff" is abandoned in latest analogix-dp driver,
> absolutely
>     I should not carry this to analogix-dp.txt document. But I should
> keep this in
>     exynos-dp.txt document, and mark them with an little "deprecated" flag.
> 
> [Documentation/devicetree/bindings/video/exynos_dp.txt]
> Required properties for dp-controller:
>    [...]
>     -samsung,ycbcr-coeff (DEPRECATED):
>         YCbCr co-efficients for input video.
>             COLOR_YCBCR601 = 0, COLOR_YCBCR709 = 1
> 
> Is it right ?

Yes, this is right.

> 
>> 2. Separate all DTS changes to a separate patch, unless bisectability
>> would be hurt. Anyway you should prepare it in a such way that
>> separation would be possible without breaking bisectability.
> 
> So I should separate this patch into two parts, one is name "Document:",
> the other is "ARM: dts: ".

Yes.

> 
> Honestly, I don't understand what the "bisectability" means in this case.

I was referring to bisectability in general. The patchset should be
fully bisectable which means that it does not introduce any issues
during "git bisect". This effectively means that at each intermediate
step (after applying each patch, one by one) every existing stuff works
the same as previously without any regression. Including booting with
old DTB.

> 
>> 3. Use proper subject for the patch changing DTS. This is not
>> documentation change!
> 
> Hmm... when I separate this patch into two parts, I though I can keep
> "Documentation" proper subject in this patch, and the other is the "ARM:
> dts"
> proper subject. Am I right ?

Yes, you're right.

> 
>> 4. Please use script get_maintainers to obtain list of valid
>> maintainers and CC-them with at least cover letter and patches
>> requiring their attention.
> 
> Yeah, thanks.

Sure. Now I found older versions of the patchset but previously there
were no changes to the bindings. Again the prefix in subject is
important to easily filter out and find necessary emails.

BTW, I like the patchset because I like in general works which merge
code and reduce duplicate stuff.

Best regards,
Krzysztof




From maitysanchayan at gmail.com  Sun Aug 23 21:32:13 2015
From: maitysanchayan at gmail.com (maitysanchayan at gmail.com)
Date: Mon, 24 Aug 2015 10:02:13 +0530
Subject: [PATCH v4 3/3] touchscreen: colibri-vf50-ts: Add touchscreen
 support for Colibri VF50
In-Reply-To: <20150822013057.GA12702@dtor-pixel>
References: <cover.1440162473.git.maitysanchayan@gmail.com>
 <915c9122cfba83c6fbbc519c10ae2d101e27bc5b.1440162473.git.maitysanchayan@gmail.com>
 <20150822013057.GA12702@dtor-pixel>
Message-ID: <20150824043213.GA2722@Sanchayan-Arch.toradex.int>

Hello Dmitry,

On 15-08-21 18:30:57, Dmitry Torokhov wrote:
> Hi Sanchayan,
> 
> On Fri, Aug 21, 2015 at 06:56:32PM +0530, Sanchayan Maity wrote:
> > The Colibri Vybrid VF50 module supports 4-wire touchscreens using
> > FETs and ADC inputs. This driver uses the IIO consumer interface
> > and relies on the vf610_adc driver based on the IIO framework.
> > 
> 
> Thank you for making changes. I have a few comments still.

It has really improved with your comments. Thanks for your feedback.

> 
> > Signed-off-by: Sanchayan Maity <maitysanchayan at gmail.com>
> > ---
> >  drivers/input/touchscreen/Kconfig           |  12 +
> >  drivers/input/touchscreen/Makefile          |   1 +
> >  drivers/input/touchscreen/colibri-vf50-ts.c | 370 ++++++++++++++++++++++++++++
> >  3 files changed, 383 insertions(+)
> >  create mode 100644 drivers/input/touchscreen/colibri-vf50-ts.c
> > 
> > diff --git a/drivers/input/touchscreen/Kconfig b/drivers/input/touchscreen/Kconfig
> > index 80f6386..28948ca 100644
> > --- a/drivers/input/touchscreen/Kconfig
> > +++ b/drivers/input/touchscreen/Kconfig
> > @@ -1027,4 +1027,16 @@ config TOUCHSCREEN_ZFORCE
> >  	  To compile this driver as a module, choose M here: the
> >  	  module will be called zforce_ts.
> >  
> > +config TOUCHSCREEN_COLIBRI_VF50
> > +	tristate "Toradex Colibri on board touchscreen driver"
> > +	depends on GPIOLIB && IIO && VF610_ADC
> 
> Can we possibly add "|| COMPILE_TEST" dependency? Will it compile
> without IIO or VF610_ADC enabled?

I will add and do the checks. It should compile without VF610_ADC
atleast, I don't see how it will without the others. I will check
once at my end also with other configs.

> 
> 
> > +	help
> > +	  Say Y here if you have a Colibri VF50 and plan to use
> > +	  the on-board provided 4-wire touchscreen driver.
> > +
> > +	  If unsure, say N.
> > +
> > +	  To compile this driver as a module, choose M here: the
> > +	  module will be called colibri_vf50_ts.
> > +
> >  endif
> > diff --git a/drivers/input/touchscreen/Makefile b/drivers/input/touchscreen/Makefile
> > index 44deea7..93746a0 100644
> > --- a/drivers/input/touchscreen/Makefile
> > +++ b/drivers/input/touchscreen/Makefile
> > @@ -84,3 +84,4 @@ obj-$(CONFIG_TOUCHSCREEN_W90X900)	+= w90p910_ts.o
> >  obj-$(CONFIG_TOUCHSCREEN_SX8654)	+= sx8654.o
> >  obj-$(CONFIG_TOUCHSCREEN_TPS6507X)	+= tps6507x-ts.o
> >  obj-$(CONFIG_TOUCHSCREEN_ZFORCE)	+= zforce_ts.o
> > +obj-$(CONFIG_TOUCHSCREEN_COLIBRI_VF50)	+= colibri-vf50-ts.o
> > diff --git a/drivers/input/touchscreen/colibri-vf50-ts.c b/drivers/input/touchscreen/colibri-vf50-ts.c
> > new file mode 100644
> > index 0000000..0793fdc
> > --- /dev/null
> > +++ b/drivers/input/touchscreen/colibri-vf50-ts.c
> > @@ -0,0 +1,370 @@
> > +/* Copyright 2015 Toradex AG
> > + *
> > + * Toradex Colibri VF50 Touchscreen driver
> > + *
> > + * Originally authored by Stefan Agner for 3.0 kernel
> > + *
> > + * 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.
> > + */
> > +
> > +#include <linux/delay.h>
> > +#include <linux/err.h>
> > +#include <linux/gpio.h>
> > +#include <linux/iio/consumer.h>
> > +#include <linux/iio/types.h>
> > +#include <linux/input.h>
> > +#include <linux/interrupt.h>
> > +#include <linux/kernel.h>
> > +#include <linux/module.h>
> > +#include <linux/pinctrl/consumer.h>
> 
> Don't you need gpio/consumer.h?

Yes.

> 
> > +#include <linux/platform_device.h>
> > +#include <linux/slab.h>
> > +#include <linux/types.h>
> > +
> > +#define DRIVER_NAME "colibri-vf50-ts"
> > +#define DRV_VERSION "1.0"
> > +
> > +#define VF_ADC_MAX ((1 << 12) - 1)
> > +
> > +#define COLI_TOUCH_MIN_DELAY_US 1000
> > +#define COLI_TOUCH_MAX_DELAY_US 2000
> > +#define COLI_TOUCH_NO_OF_AVGS	5
> > +
> > +struct vf50_touch_device {
> > +	struct platform_device	*pdev;
> > +	struct input_dev	*ts_input;
> > +	struct iio_channel	*channels;
> > +	struct gpio_desc *gpio_xp;
> > +	struct gpio_desc *gpio_xm;
> > +	struct gpio_desc *gpio_yp;
> > +	struct gpio_desc *gpio_ym;
> > +	struct gpio_desc *gpio_pen_detect;
> 
> I do not see gpio_pen_detect being used anymore.

Sorry. My mistake. It needs to be deleted. Will fix.

> 
> > +	int pen_irq;
> > +	int min_pressure;
> > +	bool stop_touchscreen;
> > +};
> > +
> > +/*
> > + * Enables given plates and measures touch parameters using ADC
> > + */
> > +static int adc_ts_measure(struct iio_channel *channel,
> > +		  struct gpio_desc *plate_p, struct gpio_desc *plate_m)
> > +{
> > +	int i, value = 0, val = 0;
> > +	int ret;
> > +
> > +	gpiod_set_value(plate_p, 1);
> > +	gpiod_set_value(plate_m, 1);
> > +
> > +	usleep_range(COLI_TOUCH_MIN_DELAY_US, COLI_TOUCH_MAX_DELAY_US);
> > +
> > +	for (i = 0; i < COLI_TOUCH_NO_OF_AVGS; i++) {
> > +		ret = iio_read_channel_raw(channel, &val);
> > +		if (ret < 0) {
> > +			value = ret;
> > +			goto error_iio_read;
> > +		}
> > +
> > +		value += val;
> > +	}
> > +
> > +	value /= COLI_TOUCH_NO_OF_AVGS;
> > +
> > +error_iio_read:
> > +	gpiod_set_value(plate_p, 0);
> > +	gpiod_set_value(plate_m, 0);
> > +
> > +	return value;
> > +}
> > +
> > +/*
> > + * Enable touch detection using falling edge detection on XM
> > + */
> > +static void vf50_ts_enable_touch_detection(struct vf50_touch_device *vf50_ts)
> > +{
> > +	/* Enable plate YM (needs to be strong GND, high active) */
> > +	gpiod_set_value(vf50_ts->gpio_ym, 1);
> > +
> > +	/*
> > +	 * Let the platform mux to idle state in order to enable
> > +	 * Pull-Up on GPIO
> > +	 */
> > +	pinctrl_pm_select_idle_state(&vf50_ts->pdev->dev);
> > +}
> > +
> > +/*
> > + * ADC touch screen sampling bottom half irq handler
> > + */
> > +static irqreturn_t vf50_ts_irq_bh(int irq, void *private)
> > +{
> > +	struct vf50_touch_device *vf50_ts = (struct vf50_touch_device *)private;
> 
> No need to cast from void * pointer.

Ok.

> 
> > +	struct device *dev = &vf50_ts->pdev->dev;
> > +	int val_x, val_y, val_z1, val_z2, val_p = 0;
> > +	bool discard_val_on_start = true;
> > +
> > +	/* Disable the touch detection plates */
> > +	gpiod_set_value(vf50_ts->gpio_ym, 0);
> > +
> > +	/* Let the platform mux to default state in order to mux as ADC */
> > +	pinctrl_pm_select_default_state(dev);
> > +
> > +	while (!vf50_ts->stop_touchscreen) {
> > +		/* X-Direction */
> > +		val_x = adc_ts_measure(&vf50_ts->channels[0],
> > +				vf50_ts->gpio_xp, vf50_ts->gpio_xm);
> > +		if (val_x < 0)
> > +			break;
> > +
> > +		/* Y-Direction */
> > +		val_y = adc_ts_measure(&vf50_ts->channels[1],
> > +				vf50_ts->gpio_yp, vf50_ts->gpio_ym);
> > +		if (val_y < 0)
> > +			break;
> > +
> > +		/*
> > +		 * Touch pressure
> > +		 * Measure on XP/YM
> > +		 */
> > +		val_z1 = adc_ts_measure(&vf50_ts->channels[2],
> > +				vf50_ts->gpio_yp, vf50_ts->gpio_xm);
> > +		if (val_z1 < 0)
> > +			break;
> > +		val_z2 = adc_ts_measure(&vf50_ts->channels[3],
> > +				vf50_ts->gpio_yp, vf50_ts->gpio_xm);
> > +		if (val_z2 < 0)
> > +			break;
> > +
> > +		/* Validate signal (avoid calculation using noise) */
> > +		if (val_z1 > 64 && val_x > 64) {
> > +			/*
> > +			 * Calculate resistance between the plates
> > +			 * lower resistance means higher pressure
> > +			 */
> > +			int r_x = (1000 * val_x) / VF_ADC_MAX;
> > +
> > +			val_p = (r_x * val_z2) / val_z1 - r_x;
> > +
> > +		} else {
> > +			val_p = 2000;
> > +		}
> > +
> > +		val_p = 2000 - val_p;
> > +		dev_dbg(dev, "Measured values: x: %d, y: %d, z1: %d, z2: %d, "
> > +			"p: %d\n", val_x, val_y, val_z1, val_z2, val_p);
> > +
> > +		/*
> > +		 * If touch pressure is too low, stop measuring and reenable
> > +		 * touch detection
> > +		 */
> > +		if (val_p < vf50_ts->min_pressure || val_p > 2000)
> > +			break;
> > +
> > +		/*
> > +		 * The pressure may not be enough for the first x and the
> > +		 * second y measurement, but, the pressure is ok when the
> > +		 * driver is doing the third and fourth measurement. To
> > +		 * take care of this, we drop the first measurement always.
> > +		 */
> > +		if (discard_val_on_start) {
> > +			discard_val_on_start = false;
> > +		} else {
> > +			/*
> > +			 * Report touch position and sleep for
> > +			 * next measurement
> > +			 */
> > +			input_report_abs(vf50_ts->ts_input,
> > +					ABS_X, VF_ADC_MAX - val_x);
> > +			input_report_abs(vf50_ts->ts_input,
> > +					ABS_Y, VF_ADC_MAX - val_y);
> > +			input_report_abs(vf50_ts->ts_input,
> > +					ABS_PRESSURE, val_p);
> > +			input_report_key(vf50_ts->ts_input, BTN_TOUCH, 1);
> > +			input_sync(vf50_ts->ts_input);
> > +		}
> > +
> > +		msleep(10);
> > +	}
> > +
> > +	/* Report no more touch, reenable touch detection */
> > +	input_report_abs(vf50_ts->ts_input, ABS_PRESSURE, 0);
> > +	input_report_key(vf50_ts->ts_input, BTN_TOUCH, 0);
> > +	input_sync(vf50_ts->ts_input);
> > +
> > +	vf50_ts_enable_touch_detection(vf50_ts);
> > +
> > +	/* Wait for the pull-up to be stable on high */
> > +	msleep(10);
> > +
> > +	return IRQ_HANDLED;
> > +}
> > +
> > +static int vf50_ts_open(struct input_dev *dev_input)
> > +{
> > +	struct vf50_touch_device *touchdev = input_get_drvdata(dev_input);
> > +	struct device *dev = &touchdev->pdev->dev;
> > +
> > +	dev_dbg(dev, "Input device %s opened, starting touch detection\n",
> > +			dev_input->name);
> > +
> > +	touchdev->stop_touchscreen = false;
> > +
> > +	/* Mux detection before request IRQ, wait for pull-up to settle */
> > +	vf50_ts_enable_touch_detection(touchdev);
> > +	msleep(10);
> > +
> > +	return 0;
> > +}
> > +
> > +static void vf50_ts_close(struct input_dev *dev_input)
> > +{
> > +	struct vf50_touch_device *touchdev = input_get_drvdata(dev_input);
> > +	struct device *dev = &touchdev->pdev->dev;
> > +
> > +	touchdev->stop_touchscreen = true;
> > +
> > +	/* Make sure IRQ is not running past close */
> > +	mb();
> > +	synchronize_irq(touchdev->pen_irq);
> > +
> 
> Should we drive the gpio_ym inactive here? What about pin control?

My understanding is that the last IRQ handler run should leave things in
the pen irq detect and idle pictrl state. And since these lines are not
provided for any other use on the module, that state is left as is since
it is the same state we assume in open. However yes, I should turn off the
ym gpio inactive.

> 
> > +	dev_dbg(dev, "Input device %s closed, disable touch detection\n",
> > +		dev_input->name);
> > +}
> > +
> > +static int vf50_ts_get_gpiod(struct device *dev,
> > +	struct gpio_desc **gpio_d, const char *con_id, enum gpiod_flags flags)
> > +{
> > +	int error;
> > +
> > +	*gpio_d = devm_gpiod_get(dev, con_id, flags);
> > +	if (IS_ERR(*gpio_d)) {
> > +		error = PTR_ERR(*gpio_d);
> > +		dev_err(dev, "Could not get gpio_%s %d\n", con_id, error);
> > +		return error;
> > +	}
> > +
> > +	return 0;
> > +}
> > +
> > +static void vf50_ts_channel_release(void *data)
> > +{
> > +	struct vf50_touch_device *touchdev = data;
> > +
> > +	iio_channel_release_all(touchdev->channels);
> > +}
> > +
> > +static int vf50_ts_probe(struct platform_device *pdev)
> > +{
> > +	struct input_dev *input;
> > +	struct iio_channel *channels;
> > +	struct device *dev = &pdev->dev;
> > +	struct vf50_touch_device *touchdev;
> > +	int error;
> > +
> > +	channels = iio_channel_get_all(dev);
> > +	if (IS_ERR(channels))
> > +		return PTR_ERR(channels);
> > +
> > +	touchdev = devm_kzalloc(dev, sizeof(*touchdev), GFP_KERNEL);
> > +	if (!touchdev) {
> > +		error = -ENOMEM;
> > +		return error;
> 
> Why not simply
> 
> 		return -ENOMEM;
> 
> here?

Ok.

> 
> Also you are leaking your iio channels here. You need to install the
> custom action earlier.

I will reorder this set of four calls here which will be better.

> 
> > +	}
> > +
> > +	error = of_property_read_u32(dev->of_node, "vf50-ts-min-pressure",
> > +				 &touchdev->min_pressure);
> > +	if (error)
> > +		return error;
> > +
> > +	error = devm_add_action(dev, vf50_ts_channel_release, channels);
> > +	if (error) {
> > +		dev_err(dev, "Failed to register iio channel release action");
> 
> You also need
> 
> 		vf50_ts_channel_release(touchdev);
> 
> > +		return error;
> > +	}
> > +
> > +	input = devm_input_allocate_device(dev);
> > +	if (!input) {
> > +		dev_err(dev, "Failed to allocate TS input device\n");
> > +		error = -ENOMEM;
> > +		return error;
> 
> Again simply return error code, no need to assign to the error variable.

Ok.

> 
> > +	}
> > +
> > +	platform_set_drvdata(pdev, touchdev);
> > +
> > +	touchdev->pdev = pdev;
> > +	touchdev->channels = channels;
> > +
> > +	input->name = DRIVER_NAME;
> > +	input->id.bustype = BUS_HOST;
> > +	input->dev.parent = dev;
> > +	input->open = vf50_ts_open;
> > +	input->close = vf50_ts_close;
> > +
> > +	input_set_capability(input, EV_KEY, BTN_TOUCH);
> > +	input_set_abs_params(input, ABS_X, 0, VF_ADC_MAX, 0, 0);
> > +	input_set_abs_params(input, ABS_Y, 0, VF_ADC_MAX, 0, 0);
> > +	input_set_abs_params(input, ABS_PRESSURE, 0, VF_ADC_MAX, 0, 0);
> > +
> > +	touchdev->ts_input = input;
> > +	input_set_drvdata(input, touchdev);
> > +	error = input_register_device(input);
> > +	if (error) {
> > +		dev_err(dev, "Failed to register input device\n");
> > +		return error;
> > +	}
> > +
> > +	error = vf50_ts_get_gpiod(dev, &touchdev->gpio_xp,
> > +				"xp", GPIOD_OUT_LOW);
> > +	if (error)
> > +		return error;
> > +
> > +	error = vf50_ts_get_gpiod(dev, &touchdev->gpio_xm,
> > +				"xm", GPIOD_OUT_LOW);
> > +	if (error)
> > +		return error;
> > +
> > +	error = vf50_ts_get_gpiod(dev, &touchdev->gpio_yp,
> > +				"yp", GPIOD_OUT_LOW);
> > +	if (error)
> > +		return error;
> > +
> > +	error = vf50_ts_get_gpiod(dev, &touchdev->gpio_ym,
> > +				"ym", GPIOD_OUT_LOW);
> > +	if (error)
> > +		return error;
> > +
> > +	touchdev->pen_irq = platform_get_irq(pdev, 0);
> > +	if (touchdev->pen_irq < 0)
> > +		return touchdev->pen_irq;
> > +
> > +	error = devm_request_threaded_irq(dev, touchdev->pen_irq, NULL,
> > +			vf50_ts_irq_bh, IRQF_ONESHOT,
> > +			"vf50 touch", touchdev);
> > +	if (error < 0)
> > +		return error;
> > +
> > +	return 0;
> > +}
> > +
> > +static const struct of_device_id vf50_touch_of_match[] = {
> > +	{ .compatible = "toradex,vf50-touchscreen", },
> > +	{ }
> > +};
> > +MODULE_DEVICE_TABLE(of, vf50_touch_of_match);
> > +
> > +static struct platform_driver vf50_touch_driver = {
> > +	.driver = {
> > +		.name = "toradex,vf50_touchctrl",
> > +		.of_match_table = vf50_touch_of_match,
> > +	},
> > +	.probe = vf50_ts_probe,
> > +};
> > +
> > +module_platform_driver(vf50_touch_driver);
> > +
> > +MODULE_AUTHOR("Sanchayan Maity");
> > +MODULE_DESCRIPTION("Colibri VF50 Touchscreen driver");
> > +MODULE_LICENSE("GPL v2");
> 
> Please change it to "GPL" which means GPL v2+ to match license notice at
> the top.

Ok.

--  Sanchayan.

> 
> > +MODULE_VERSION(DRV_VERSION);
> > -- 
> > 2.5.0
> > 
> 
> Thank you.
> 
> -- 
> Dmitry


From yamada.masahiro at socionext.com  Sun Aug 23 21:36:03 2015
From: yamada.masahiro at socionext.com (Masahiro Yamada)
Date: Mon, 24 Aug 2015 13:36:03 +0900
Subject: [PATCH 03/18] ARM: alpine: use const and __initconst for
 smp_operations
In-Reply-To: <1440390978-22796-1-git-send-email-yamada.masahiro@socionext.com>
References: <1440390978-22796-1-git-send-email-yamada.masahiro@socionext.com>
Message-ID: <1440390978-22796-4-git-send-email-yamada.masahiro@socionext.com>

The smp_operations structure is not over-written, so add const
qualifier and replace __initdata with __initconst.

Signed-off-by: Masahiro Yamada <yamada.masahiro at socionext.com>
---

 arch/arm/mach-alpine/platsmp.c | 2 +-
 1 file changed, 1 insertion(+), 1 deletion(-)

diff --git a/arch/arm/mach-alpine/platsmp.c b/arch/arm/mach-alpine/platsmp.c
index f78429f..dd77ea2 100644
--- a/arch/arm/mach-alpine/platsmp.c
+++ b/arch/arm/mach-alpine/platsmp.c
@@ -42,7 +42,7 @@ static void __init alpine_smp_prepare_cpus(unsigned int max_cpus)
 	alpine_cpu_pm_init();
 }
 
-static struct smp_operations alpine_smp_ops __initdata = {
+static const struct smp_operations alpine_smp_ops __initconst = {
 	.smp_prepare_cpus	= alpine_smp_prepare_cpus,
 	.smp_boot_secondary	= alpine_boot_secondary,
 };
-- 
1.9.1



From yamada.masahiro at socionext.com  Sun Aug 23 21:36:02 2015
From: yamada.masahiro at socionext.com (Masahiro Yamada)
Date: Mon, 24 Aug 2015 13:36:02 +0900
Subject: [PATCH 02/18] ARM: add const qualifier to smp_operations member in
 structures
In-Reply-To: <1440390978-22796-1-git-send-email-yamada.masahiro@socionext.com>
References: <1440390978-22796-1-git-send-email-yamada.masahiro@socionext.com>
Message-ID: <1440390978-22796-3-git-send-email-yamada.masahiro@socionext.com>

The core framework does not modify smp_operations structures.
To clarify it, this commit adds 'const' qualifier to the 'ops'
member of struct of_cpu_method and the 'smp' member of struct
machine_desc.

This change allows each SoC code to add 'const' qualifier to its
smp_operation structure.

Signed-off-by: Masahiro Yamada <yamada.masahiro at socionext.com>
---

 arch/arm/include/asm/mach/arch.h | 2 +-
 arch/arm/include/asm/smp.h       | 2 +-
 2 files changed, 2 insertions(+), 2 deletions(-)

diff --git a/arch/arm/include/asm/mach/arch.h b/arch/arm/include/asm/mach/arch.h
index cb3a407..5c1ad11 100644
--- a/arch/arm/include/asm/mach/arch.h
+++ b/arch/arm/include/asm/mach/arch.h
@@ -47,7 +47,7 @@ struct machine_desc {
 	unsigned		l2c_aux_val;	/* L2 cache aux value	*/
 	unsigned		l2c_aux_mask;	/* L2 cache aux mask	*/
 	void			(*l2c_write_sec)(unsigned long, unsigned);
-	struct smp_operations	*smp;		/* SMP operations	*/
+	const struct smp_operations	*smp;	/* SMP operations	*/
 	bool			(*smp_init)(void);
 	void			(*fixup)(struct tag *, char **);
 	void			(*dt_fixup)(void);
diff --git a/arch/arm/include/asm/smp.h b/arch/arm/include/asm/smp.h
index cd81540..50aff58 100644
--- a/arch/arm/include/asm/smp.h
+++ b/arch/arm/include/asm/smp.h
@@ -112,7 +112,7 @@ struct smp_operations {
 
 struct of_cpu_method {
 	const char *method;
-	struct smp_operations *ops;
+	const struct smp_operations *ops;
 };
 
 #define CPU_METHOD_OF_DECLARE(name, _method, _ops)			\
-- 
1.9.1



From yamada.masahiro at socionext.com  Sun Aug 23 21:36:01 2015
From: yamada.masahiro at socionext.com (Masahiro Yamada)
Date: Mon, 24 Aug 2015 13:36:01 +0900
Subject: [PATCH 01/18] ARM: add const qualifier to the argument of
 smp_set_ops()
In-Reply-To: <1440390978-22796-1-git-send-email-yamada.masahiro@socionext.com>
References: <1440390978-22796-1-git-send-email-yamada.masahiro@socionext.com>
Message-ID: <1440390978-22796-2-git-send-email-yamada.masahiro@socionext.com>

This function just copies '*ops' to 'smp_ops', so the given
structure '*ops' is not modified at all.

Signed-off-by: Masahiro Yamada <yamada.masahiro at socionext.com>
---

 arch/arm/include/asm/smp.h | 2 +-
 arch/arm/kernel/smp.c      | 2 +-
 2 files changed, 2 insertions(+), 2 deletions(-)

diff --git a/arch/arm/include/asm/smp.h b/arch/arm/include/asm/smp.h
index 2f3ac1b..cd81540 100644
--- a/arch/arm/include/asm/smp.h
+++ b/arch/arm/include/asm/smp.h
@@ -122,6 +122,6 @@ struct of_cpu_method {
 /*
  * set platform specific SMP operations
  */
-extern void smp_set_ops(struct smp_operations *);
+extern void smp_set_ops(const struct smp_operations *);
 
 #endif /* ifndef __ASM_ARM_SMP_H */
diff --git a/arch/arm/kernel/smp.c b/arch/arm/kernel/smp.c
index 3d6b782..bb63a4e 100644
--- a/arch/arm/kernel/smp.c
+++ b/arch/arm/kernel/smp.c
@@ -78,7 +78,7 @@ static DECLARE_COMPLETION(cpu_running);
 
 static struct smp_operations smp_ops;
 
-void __init smp_set_ops(struct smp_operations *ops)
+void __init smp_set_ops(const struct smp_operations *ops)
 {
 	if (ops)
 		smp_ops = *ops;
-- 
1.9.1



From yamada.masahiro at socionext.com  Sun Aug 23 21:36:00 2015
From: yamada.masahiro at socionext.com (Masahiro Yamada)
Date: Mon, 24 Aug 2015 13:36:00 +0900
Subject: [PATCH 00/18] ARM: use const and __initconst for smp_operations
Message-ID: <1440390978-22796-1-git-send-email-yamada.masahiro@socionext.com>


Currently, SoC code can not add const qualifier to smp_operations
structures although they are never over-written.

01/18 and 02/18 add small changes to the ARM core to fix that.
The rest of this series replace "__initdata" with "const ... __initconst"
for each of SoC code.

I split this series into per-SoC so that each sub-arch maintainer
can easily give their Acked-by.  (Is this better?)

Russell, Olof, and Arnd:

How should this series be applied (if it looks good)?
The first two are ARM-tree wide and looks like in the field of Russell.
The rest are highly SoC-related.



Masahiro Yamada (18):
  ARM: add const qualifier to the argument of smp_set_ops()
  ARM: add const qualifier to smp_operations member in structures
  ARM: alpine: use const and __initconst for smp_operations
  ARM: axxia: use const and __initconst for smp_operations
  ARM: BCM: use const and __initconst for smp_operations
  ARM: berlin: use const and __initconst for smp_operations
  ARM: EXYNOS: use const and __initconst for smp_operations
  ARM: hisi: do not export smp_operations structures
  ARM: hisi: use const and __initconst for smp_operations
  ARM: mvebu: use const and __initconst for smp_operations
  ARM: qcom: use const and __initconst for smp_operations
  ARM: rockchip: use const and __initconst for smp_operations
  ARM: socfpga: use const and __initconst for smp_operations
  ARM: sunxi: use const and __initconst for smp_operations
  ARM: uniphier: use const and __initconst for smp_operations
  ARM: zx: use const and __initconst for smp_operations
  ARM: zynq: use const and __initconst for smp_operations
  ARM: mcpm: use const and __initconst for smp_operations

 arch/arm/common/mcpm_platsmp.c      | 2 +-
 arch/arm/include/asm/mach/arch.h    | 2 +-
 arch/arm/include/asm/smp.h          | 4 ++--
 arch/arm/kernel/smp.c               | 2 +-
 arch/arm/mach-alpine/platsmp.c      | 2 +-
 arch/arm/mach-axxia/platsmp.c       | 2 +-
 arch/arm/mach-bcm/bcm63xx_smp.c     | 2 +-
 arch/arm/mach-bcm/kona_smp.c        | 2 +-
 arch/arm/mach-bcm/platsmp-brcmstb.c | 2 +-
 arch/arm/mach-berlin/platsmp.c      | 2 +-
 arch/arm/mach-exynos/common.h       | 2 +-
 arch/arm/mach-exynos/platsmp.c      | 2 +-
 arch/arm/mach-hisi/core.h           | 3 ---
 arch/arm/mach-hisi/platsmp.c        | 6 +++---
 arch/arm/mach-mvebu/armada-370-xp.h | 2 +-
 arch/arm/mach-mvebu/platsmp-a9.c    | 4 ++--
 arch/arm/mach-mvebu/platsmp.c       | 2 +-
 arch/arm/mach-qcom/platsmp.c        | 6 +++---
 arch/arm/mach-rockchip/platsmp.c    | 2 +-
 arch/arm/mach-socfpga/platsmp.c     | 4 ++--
 arch/arm/mach-sunxi/platsmp.c       | 4 ++--
 arch/arm/mach-uniphier/platsmp.c    | 2 +-
 arch/arm/mach-zx/platsmp.c          | 2 +-
 arch/arm/mach-zynq/common.h         | 2 +-
 arch/arm/mach-zynq/platsmp.c        | 2 +-
 25 files changed, 32 insertions(+), 35 deletions(-)

-- 
1.9.1



From yamada.masahiro at socionext.com  Sun Aug 23 21:36:13 2015
From: yamada.masahiro at socionext.com (Masahiro Yamada)
Date: Mon, 24 Aug 2015 13:36:13 +0900
Subject: [PATCH 13/18] ARM: socfpga: use const and __initconst for
 smp_operations
In-Reply-To: <1440390978-22796-1-git-send-email-yamada.masahiro@socionext.com>
References: <1440390978-22796-1-git-send-email-yamada.masahiro@socionext.com>
Message-ID: <1440390978-22796-14-git-send-email-yamada.masahiro@socionext.com>

The smp_operations structure is not over-written, so add const
qualifier and replace __initdata with __initconst.

Signed-off-by: Masahiro Yamada <yamada.masahiro at socionext.com>
---

 arch/arm/mach-socfpga/platsmp.c | 4 ++--
 1 file changed, 2 insertions(+), 2 deletions(-)

diff --git a/arch/arm/mach-socfpga/platsmp.c b/arch/arm/mach-socfpga/platsmp.c
index 15c8ce8..cbb0a54 100644
--- a/arch/arm/mach-socfpga/platsmp.c
+++ b/arch/arm/mach-socfpga/platsmp.c
@@ -117,7 +117,7 @@ static int socfpga_cpu_kill(unsigned int cpu)
 	return 1;
 }
 
-static struct smp_operations socfpga_smp_ops __initdata = {
+static const struct smp_operations socfpga_smp_ops __initconst = {
 	.smp_prepare_cpus	= socfpga_smp_prepare_cpus,
 	.smp_boot_secondary	= socfpga_boot_secondary,
 #ifdef CONFIG_HOTPLUG_CPU
@@ -126,7 +126,7 @@ static struct smp_operations socfpga_smp_ops __initdata = {
 #endif
 };
 
-static struct smp_operations socfpga_a10_smp_ops __initdata = {
+static const struct smp_operations socfpga_a10_smp_ops __initconst = {
 	.smp_prepare_cpus	= socfpga_smp_prepare_cpus,
 	.smp_boot_secondary	= socfpga_a10_boot_secondary,
 #ifdef CONFIG_HOTPLUG_CPU
-- 
1.9.1



From yamada.masahiro at socionext.com  Sun Aug 23 21:36:15 2015
From: yamada.masahiro at socionext.com (Masahiro Yamada)
Date: Mon, 24 Aug 2015 13:36:15 +0900
Subject: [PATCH 15/18] ARM: uniphier: use const and __initconst for
 smp_operations
In-Reply-To: <1440390978-22796-1-git-send-email-yamada.masahiro@socionext.com>
References: <1440390978-22796-1-git-send-email-yamada.masahiro@socionext.com>
Message-ID: <1440390978-22796-16-git-send-email-yamada.masahiro@socionext.com>

The smp_operations structure is not over-written, so add const
qualifier and replace __initdata with __initconst.

Signed-off-by: Masahiro Yamada <yamada.masahiro at socionext.com>
---

 arch/arm/mach-uniphier/platsmp.c | 2 +-
 1 file changed, 1 insertion(+), 1 deletion(-)

diff --git a/arch/arm/mach-uniphier/platsmp.c b/arch/arm/mach-uniphier/platsmp.c
index 4b784f7..da5359c 100644
--- a/arch/arm/mach-uniphier/platsmp.c
+++ b/arch/arm/mach-uniphier/platsmp.c
@@ -76,7 +76,7 @@ static int uniphier_boot_secondary(unsigned int cpu,
 	return ret;
 }
 
-struct smp_operations uniphier_smp_ops __initdata = {
+static const struct smp_operations uniphier_smp_ops __initconst = {
 	.smp_prepare_cpus	= uniphier_smp_prepare_cpus,
 	.smp_boot_secondary	= uniphier_boot_secondary,
 };
-- 
1.9.1



From yamada.masahiro at socionext.com  Sun Aug 23 21:36:06 2015
From: yamada.masahiro at socionext.com (Masahiro Yamada)
Date: Mon, 24 Aug 2015 13:36:06 +0900
Subject: [PATCH 06/18] ARM: berlin: use const and __initconst for
 smp_operations
In-Reply-To: <1440390978-22796-1-git-send-email-yamada.masahiro@socionext.com>
References: <1440390978-22796-1-git-send-email-yamada.masahiro@socionext.com>
Message-ID: <1440390978-22796-7-git-send-email-yamada.masahiro@socionext.com>

The smp_operations structure is not over-written, so add const
qualifier and replace __initdata with __initconst.

Signed-off-by: Masahiro Yamada <yamada.masahiro at socionext.com>
---

 arch/arm/mach-berlin/platsmp.c | 2 +-
 1 file changed, 1 insertion(+), 1 deletion(-)

diff --git a/arch/arm/mach-berlin/platsmp.c b/arch/arm/mach-berlin/platsmp.c
index 34a3753..41a626b 100644
--- a/arch/arm/mach-berlin/platsmp.c
+++ b/arch/arm/mach-berlin/platsmp.c
@@ -91,7 +91,7 @@ unmap_scu:
 	iounmap(scu_base);
 }
 
-static struct smp_operations berlin_smp_ops __initdata = {
+static const struct smp_operations berlin_smp_ops __initconst = {
 	.smp_prepare_cpus	= berlin_smp_prepare_cpus,
 	.smp_boot_secondary	= berlin_boot_secondary,
 };
-- 
1.9.1



From yamada.masahiro at socionext.com  Sun Aug 23 21:36:04 2015
From: yamada.masahiro at socionext.com (Masahiro Yamada)
Date: Mon, 24 Aug 2015 13:36:04 +0900
Subject: [PATCH 04/18] ARM: axxia: use const and __initconst for smp_operations
In-Reply-To: <1440390978-22796-1-git-send-email-yamada.masahiro@socionext.com>
References: <1440390978-22796-1-git-send-email-yamada.masahiro@socionext.com>
Message-ID: <1440390978-22796-5-git-send-email-yamada.masahiro@socionext.com>

The smp_operations structure is not over-written, so add const
qualifier and replace __initdata with __initconst.

Signed-off-by: Masahiro Yamada <yamada.masahiro at socionext.com>
---

 arch/arm/mach-axxia/platsmp.c | 2 +-
 1 file changed, 1 insertion(+), 1 deletion(-)

diff --git a/arch/arm/mach-axxia/platsmp.c b/arch/arm/mach-axxia/platsmp.c
index 959d4df..ffbd71d 100644
--- a/arch/arm/mach-axxia/platsmp.c
+++ b/arch/arm/mach-axxia/platsmp.c
@@ -82,7 +82,7 @@ static void __init axxia_smp_prepare_cpus(unsigned int max_cpus)
 	}
 }
 
-static struct smp_operations axxia_smp_ops __initdata = {
+static const struct smp_operations axxia_smp_ops __initconst = {
 	.smp_prepare_cpus	= axxia_smp_prepare_cpus,
 	.smp_boot_secondary	= axxia_boot_secondary,
 };
-- 
1.9.1



From yamada.masahiro at socionext.com  Sun Aug 23 21:36:07 2015
From: yamada.masahiro at socionext.com (Masahiro Yamada)
Date: Mon, 24 Aug 2015 13:36:07 +0900
Subject: [PATCH 07/18] ARM: EXYNOS: use const and __initconst for
 smp_operations
In-Reply-To: <1440390978-22796-1-git-send-email-yamada.masahiro@socionext.com>
References: <1440390978-22796-1-git-send-email-yamada.masahiro@socionext.com>
Message-ID: <1440390978-22796-8-git-send-email-yamada.masahiro@socionext.com>

The smp_operations structure is not over-written, so add const
qualifier and replace __initdata with __initconst.

Signed-off-by: Masahiro Yamada <yamada.masahiro at socionext.com>
---

 arch/arm/mach-exynos/common.h  | 2 +-
 arch/arm/mach-exynos/platsmp.c | 2 +-
 2 files changed, 2 insertions(+), 2 deletions(-)

diff --git a/arch/arm/mach-exynos/common.h b/arch/arm/mach-exynos/common.h
index 1534925..e349a03 100644
--- a/arch/arm/mach-exynos/common.h
+++ b/arch/arm/mach-exynos/common.h
@@ -149,7 +149,7 @@ static inline void exynos_pm_init(void) {}
 extern void exynos_cpu_resume(void);
 extern void exynos_cpu_resume_ns(void);
 
-extern struct smp_operations exynos_smp_ops;
+extern const struct smp_operations exynos_smp_ops;
 
 extern void exynos_cpu_power_down(int cpu);
 extern void exynos_cpu_power_up(int cpu);
diff --git a/arch/arm/mach-exynos/platsmp.c b/arch/arm/mach-exynos/platsmp.c
index 98a2c0c..5bd9559 100644
--- a/arch/arm/mach-exynos/platsmp.c
+++ b/arch/arm/mach-exynos/platsmp.c
@@ -479,7 +479,7 @@ static void exynos_cpu_die(unsigned int cpu)
 }
 #endif /* CONFIG_HOTPLUG_CPU */
 
-struct smp_operations exynos_smp_ops __initdata = {
+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,
-- 
1.9.1



From yamada.masahiro at socionext.com  Sun Aug 23 21:36:09 2015
From: yamada.masahiro at socionext.com (Masahiro Yamada)
Date: Mon, 24 Aug 2015 13:36:09 +0900
Subject: [PATCH 09/18] ARM: hisi: use const and __initconst for smp_operations
In-Reply-To: <1440390978-22796-1-git-send-email-yamada.masahiro@socionext.com>
References: <1440390978-22796-1-git-send-email-yamada.masahiro@socionext.com>
Message-ID: <1440390978-22796-10-git-send-email-yamada.masahiro@socionext.com>

The smp_operations structure is not over-written, so add const
qualifier and replace __initdata with __initconst.

Signed-off-by: Masahiro Yamada <yamada.masahiro at socionext.com>
---

 arch/arm/mach-hisi/platsmp.c | 6 +++---
 1 file changed, 3 insertions(+), 3 deletions(-)

diff --git a/arch/arm/mach-hisi/platsmp.c b/arch/arm/mach-hisi/platsmp.c
index 3c5237d..47ed32c 100644
--- a/arch/arm/mach-hisi/platsmp.c
+++ b/arch/arm/mach-hisi/platsmp.c
@@ -89,7 +89,7 @@ static int hi3xxx_boot_secondary(unsigned int cpu, struct task_struct *idle)
 	return 0;
 }
 
-static struct smp_operations hi3xxx_smp_ops __initdata = {
+static const struct smp_operations hi3xxx_smp_ops __initconst = {
 	.smp_prepare_cpus	= hi3xxx_smp_prepare_cpus,
 	.smp_boot_secondary	= hi3xxx_boot_secondary,
 #ifdef CONFIG_HOTPLUG_CPU
@@ -126,7 +126,7 @@ static int hix5hd2_boot_secondary(unsigned int cpu, struct task_struct *idle)
 }
 
 
-static struct smp_operations hix5hd2_smp_ops __initdata = {
+static const struct smp_operations hix5hd2_smp_ops __initconst = {
 	.smp_prepare_cpus	= hisi_common_smp_prepare_cpus,
 	.smp_boot_secondary	= hix5hd2_boot_secondary,
 #ifdef CONFIG_HOTPLUG_CPU
@@ -176,7 +176,7 @@ static int hip01_boot_secondary(unsigned int cpu, struct task_struct *idle)
 	return 0;
 }
 
-static struct smp_operations hip01_smp_ops __initdata = {
+static const struct smp_operations hip01_smp_ops __initconst = {
 	.smp_prepare_cpus       = hisi_common_smp_prepare_cpus,
 	.smp_boot_secondary     = hip01_boot_secondary,
 };
-- 
1.9.1



From yamada.masahiro at socionext.com  Sun Aug 23 21:36:11 2015
From: yamada.masahiro at socionext.com (Masahiro Yamada)
Date: Mon, 24 Aug 2015 13:36:11 +0900
Subject: [PATCH 11/18] ARM: qcom: use const and __initconst for smp_operations
In-Reply-To: <1440390978-22796-1-git-send-email-yamada.masahiro@socionext.com>
References: <1440390978-22796-1-git-send-email-yamada.masahiro@socionext.com>
Message-ID: <1440390978-22796-12-git-send-email-yamada.masahiro@socionext.com>

The smp_operations structure is not over-written, so add const
qualifier and replace __initdata with __initconst.

Signed-off-by: Masahiro Yamada <yamada.masahiro at socionext.com>
---

 arch/arm/mach-qcom/platsmp.c | 6 +++---
 1 file changed, 3 insertions(+), 3 deletions(-)

diff --git a/arch/arm/mach-qcom/platsmp.c b/arch/arm/mach-qcom/platsmp.c
index 5cde63a..11847cd 100644
--- a/arch/arm/mach-qcom/platsmp.c
+++ b/arch/arm/mach-qcom/platsmp.c
@@ -332,7 +332,7 @@ static void __init qcom_smp_prepare_cpus(unsigned int max_cpus)
 	}
 }
 
-static struct smp_operations smp_msm8660_ops __initdata = {
+static const struct smp_operations smp_msm8660_ops __initconst = {
 	.smp_prepare_cpus	= qcom_smp_prepare_cpus,
 	.smp_secondary_init	= qcom_secondary_init,
 	.smp_boot_secondary	= msm8660_boot_secondary,
@@ -342,7 +342,7 @@ static struct smp_operations smp_msm8660_ops __initdata = {
 };
 CPU_METHOD_OF_DECLARE(qcom_smp, "qcom,gcc-msm8660", &smp_msm8660_ops);
 
-static struct smp_operations qcom_smp_kpssv1_ops __initdata = {
+static const struct smp_operations qcom_smp_kpssv1_ops __initconst = {
 	.smp_prepare_cpus	= qcom_smp_prepare_cpus,
 	.smp_secondary_init	= qcom_secondary_init,
 	.smp_boot_secondary	= kpssv1_boot_secondary,
@@ -352,7 +352,7 @@ static struct smp_operations qcom_smp_kpssv1_ops __initdata = {
 };
 CPU_METHOD_OF_DECLARE(qcom_smp_kpssv1, "qcom,kpss-acc-v1", &qcom_smp_kpssv1_ops);
 
-static struct smp_operations qcom_smp_kpssv2_ops __initdata = {
+static const struct smp_operations qcom_smp_kpssv2_ops __initconst = {
 	.smp_prepare_cpus	= qcom_smp_prepare_cpus,
 	.smp_secondary_init	= qcom_secondary_init,
 	.smp_boot_secondary	= kpssv2_boot_secondary,
-- 
1.9.1



From yamada.masahiro at socionext.com  Sun Aug 23 21:36:05 2015
From: yamada.masahiro at socionext.com (Masahiro Yamada)
Date: Mon, 24 Aug 2015 13:36:05 +0900
Subject: [PATCH 05/18] ARM: BCM: use const and __initconst for smp_operations
In-Reply-To: <1440390978-22796-1-git-send-email-yamada.masahiro@socionext.com>
References: <1440390978-22796-1-git-send-email-yamada.masahiro@socionext.com>
Message-ID: <1440390978-22796-6-git-send-email-yamada.masahiro@socionext.com>

The smp_operations structure is not over-written, so add const
qualifier and replace __initdata with __initconst.

Also, add static to bcm63138_smp_ops.

Signed-off-by: Masahiro Yamada <yamada.masahiro at socionext.com>
---

 arch/arm/mach-bcm/bcm63xx_smp.c     | 2 +-
 arch/arm/mach-bcm/kona_smp.c        | 2 +-
 arch/arm/mach-bcm/platsmp-brcmstb.c | 2 +-
 3 files changed, 3 insertions(+), 3 deletions(-)

diff --git a/arch/arm/mach-bcm/bcm63xx_smp.c b/arch/arm/mach-bcm/bcm63xx_smp.c
index 19be904..9b6727e 100644
--- a/arch/arm/mach-bcm/bcm63xx_smp.c
+++ b/arch/arm/mach-bcm/bcm63xx_smp.c
@@ -161,7 +161,7 @@ static void __init bcm63138_smp_prepare_cpus(unsigned int max_cpus)
 	}
 }
 
-struct smp_operations bcm63138_smp_ops __initdata = {
+static const struct smp_operations bcm63138_smp_ops __initconst = {
 	.smp_prepare_cpus	= bcm63138_smp_prepare_cpus,
 	.smp_boot_secondary	= bcm63138_smp_boot_secondary,
 };
diff --git a/arch/arm/mach-bcm/kona_smp.c b/arch/arm/mach-bcm/kona_smp.c
index 66a0465..da8328b 100644
--- a/arch/arm/mach-bcm/kona_smp.c
+++ b/arch/arm/mach-bcm/kona_smp.c
@@ -194,7 +194,7 @@ static int bcm_boot_secondary(unsigned int cpu, struct task_struct *idle)
 	return -ENOSYS;
 }
 
-static struct smp_operations bcm_smp_ops __initdata = {
+static const struct smp_operations bcm_smp_ops __initconst = {
 	.smp_prepare_cpus	= bcm_smp_prepare_cpus,
 	.smp_boot_secondary	= bcm_boot_secondary,
 };
diff --git a/arch/arm/mach-bcm/platsmp-brcmstb.c b/arch/arm/mach-bcm/platsmp-brcmstb.c
index 44d6bddf..40dc844 100644
--- a/arch/arm/mach-bcm/platsmp-brcmstb.c
+++ b/arch/arm/mach-bcm/platsmp-brcmstb.c
@@ -356,7 +356,7 @@ static int brcmstb_boot_secondary(unsigned int cpu, struct task_struct *idle)
 	return 0;
 }
 
-static struct smp_operations brcmstb_smp_ops __initdata = {
+static const struct smp_operations brcmstb_smp_ops __initconst = {
 	.smp_prepare_cpus	= brcmstb_cpu_ctrl_setup,
 	.smp_boot_secondary	= brcmstb_boot_secondary,
 #ifdef CONFIG_HOTPLUG_CPU
-- 
1.9.1



From yamada.masahiro at socionext.com  Sun Aug 23 21:36:12 2015
From: yamada.masahiro at socionext.com (Masahiro Yamada)
Date: Mon, 24 Aug 2015 13:36:12 +0900
Subject: [PATCH 12/18] ARM: rockchip: use const and __initconst for
 smp_operations
In-Reply-To: <1440390978-22796-1-git-send-email-yamada.masahiro@socionext.com>
References: <1440390978-22796-1-git-send-email-yamada.masahiro@socionext.com>
Message-ID: <1440390978-22796-13-git-send-email-yamada.masahiro@socionext.com>

The smp_operations structure is not over-written, so add const
qualifier and replace __initdata with __initconst.

Signed-off-by: Masahiro Yamada <yamada.masahiro at socionext.com>
---

 arch/arm/mach-rockchip/platsmp.c | 2 +-
 1 file changed, 1 insertion(+), 1 deletion(-)

diff --git a/arch/arm/mach-rockchip/platsmp.c b/arch/arm/mach-rockchip/platsmp.c
index 3e7a4b7..938888f 100644
--- a/arch/arm/mach-rockchip/platsmp.c
+++ b/arch/arm/mach-rockchip/platsmp.c
@@ -340,7 +340,7 @@ static void rockchip_cpu_die(unsigned int cpu)
 }
 #endif
 
-static struct smp_operations rockchip_smp_ops __initdata = {
+static const struct smp_operations rockchip_smp_ops __initconst = {
 	.smp_prepare_cpus	= rockchip_smp_prepare_cpus,
 	.smp_boot_secondary	= rockchip_boot_secondary,
 #ifdef CONFIG_HOTPLUG_CPU
-- 
1.9.1



From yamada.masahiro at socionext.com  Sun Aug 23 21:36:08 2015
From: yamada.masahiro at socionext.com (Masahiro Yamada)
Date: Mon, 24 Aug 2015 13:36:08 +0900
Subject: [PATCH 08/18] ARM: hisi: do not export smp_operations structures
In-Reply-To: <1440390978-22796-1-git-send-email-yamada.masahiro@socionext.com>
References: <1440390978-22796-1-git-send-email-yamada.masahiro@socionext.com>
Message-ID: <1440390978-22796-9-git-send-email-yamada.masahiro@socionext.com>

These three structures are only defined and referenced in
mach-hisi/platsmp.c.

Drop the declarations from the header and add static qualifier
to the definitions.

Signed-off-by: Masahiro Yamada <yamada.masahiro at socionext.com>
---

 arch/arm/mach-hisi/core.h    | 3 ---
 arch/arm/mach-hisi/platsmp.c | 6 +++---
 2 files changed, 3 insertions(+), 6 deletions(-)

diff --git a/arch/arm/mach-hisi/core.h b/arch/arm/mach-hisi/core.h
index c7648ef..e883583 100644
--- a/arch/arm/mach-hisi/core.h
+++ b/arch/arm/mach-hisi/core.h
@@ -6,17 +6,14 @@
 extern void hi3xxx_set_cpu_jump(int cpu, void *jump_addr);
 extern int hi3xxx_get_cpu_jump(int cpu);
 extern void secondary_startup(void);
-extern struct smp_operations hi3xxx_smp_ops;
 
 extern void hi3xxx_cpu_die(unsigned int cpu);
 extern int hi3xxx_cpu_kill(unsigned int cpu);
 extern void hi3xxx_set_cpu(int cpu, bool enable);
 
-extern struct smp_operations hix5hd2_smp_ops;
 extern void hix5hd2_set_cpu(int cpu, bool enable);
 extern void hix5hd2_cpu_die(unsigned int cpu);
 
-extern struct smp_operations hip01_smp_ops;
 extern void hip01_set_cpu(int cpu, bool enable);
 extern void hip01_cpu_die(unsigned int cpu);
 #endif
diff --git a/arch/arm/mach-hisi/platsmp.c b/arch/arm/mach-hisi/platsmp.c
index 5174412..3c5237d 100644
--- a/arch/arm/mach-hisi/platsmp.c
+++ b/arch/arm/mach-hisi/platsmp.c
@@ -89,7 +89,7 @@ static int hi3xxx_boot_secondary(unsigned int cpu, struct task_struct *idle)
 	return 0;
 }
 
-struct smp_operations hi3xxx_smp_ops __initdata = {
+static struct smp_operations hi3xxx_smp_ops __initdata = {
 	.smp_prepare_cpus	= hi3xxx_smp_prepare_cpus,
 	.smp_boot_secondary	= hi3xxx_boot_secondary,
 #ifdef CONFIG_HOTPLUG_CPU
@@ -126,7 +126,7 @@ static int hix5hd2_boot_secondary(unsigned int cpu, struct task_struct *idle)
 }
 
 
-struct smp_operations hix5hd2_smp_ops __initdata = {
+static struct smp_operations hix5hd2_smp_ops __initdata = {
 	.smp_prepare_cpus	= hisi_common_smp_prepare_cpus,
 	.smp_boot_secondary	= hix5hd2_boot_secondary,
 #ifdef CONFIG_HOTPLUG_CPU
@@ -176,7 +176,7 @@ static int hip01_boot_secondary(unsigned int cpu, struct task_struct *idle)
 	return 0;
 }
 
-struct smp_operations hip01_smp_ops __initdata = {
+static struct smp_operations hip01_smp_ops __initdata = {
 	.smp_prepare_cpus       = hisi_common_smp_prepare_cpus,
 	.smp_boot_secondary     = hip01_boot_secondary,
 };
-- 
1.9.1



From yamada.masahiro at socionext.com  Sun Aug 23 21:36:14 2015
From: yamada.masahiro at socionext.com (Masahiro Yamada)
Date: Mon, 24 Aug 2015 13:36:14 +0900
Subject: [PATCH 14/18] ARM: sunxi: use const and __initconst for smp_operations
In-Reply-To: <1440390978-22796-1-git-send-email-yamada.masahiro@socionext.com>
References: <1440390978-22796-1-git-send-email-yamada.masahiro@socionext.com>
Message-ID: <1440390978-22796-15-git-send-email-yamada.masahiro@socionext.com>

The smp_operations structure is not over-written, so add const
qualifier and replace __initdata with __initconst.

Also, add static to sun8i_smp_ops.

Signed-off-by: Masahiro Yamada <yamada.masahiro at socionext.com>
---

 arch/arm/mach-sunxi/platsmp.c | 4 ++--
 1 file changed, 2 insertions(+), 2 deletions(-)

diff --git a/arch/arm/mach-sunxi/platsmp.c b/arch/arm/mach-sunxi/platsmp.c
index e8483ec..6642267 100644
--- a/arch/arm/mach-sunxi/platsmp.c
+++ b/arch/arm/mach-sunxi/platsmp.c
@@ -116,7 +116,7 @@ static int sun6i_smp_boot_secondary(unsigned int cpu,
 	return 0;
 }
 
-static struct smp_operations sun6i_smp_ops __initdata = {
+static const struct smp_operations sun6i_smp_ops __initconst = {
 	.smp_prepare_cpus	= sun6i_smp_prepare_cpus,
 	.smp_boot_secondary	= sun6i_smp_boot_secondary,
 };
@@ -185,7 +185,7 @@ static int sun8i_smp_boot_secondary(unsigned int cpu,
 	return 0;
 }
 
-struct smp_operations sun8i_smp_ops __initdata = {
+static const struct smp_operations sun8i_smp_ops __initconst = {
 	.smp_prepare_cpus	= sun8i_smp_prepare_cpus,
 	.smp_boot_secondary	= sun8i_smp_boot_secondary,
 };
-- 
1.9.1



From yamada.masahiro at socionext.com  Sun Aug 23 21:36:17 2015
From: yamada.masahiro at socionext.com (Masahiro Yamada)
Date: Mon, 24 Aug 2015 13:36:17 +0900
Subject: [PATCH 17/18] ARM: zynq: use const and __initconst for smp_operations
In-Reply-To: <1440390978-22796-1-git-send-email-yamada.masahiro@socionext.com>
References: <1440390978-22796-1-git-send-email-yamada.masahiro@socionext.com>
Message-ID: <1440390978-22796-18-git-send-email-yamada.masahiro@socionext.com>

The smp_operations structure is not over-written, so add const
qualifier and replace __initdata with __initconst.

Signed-off-by: Masahiro Yamada <yamada.masahiro at socionext.com>
---

 arch/arm/mach-zynq/common.h  | 2 +-
 arch/arm/mach-zynq/platsmp.c | 2 +-
 2 files changed, 2 insertions(+), 2 deletions(-)

diff --git a/arch/arm/mach-zynq/common.h b/arch/arm/mach-zynq/common.h
index 79cda2e..e771933 100644
--- a/arch/arm/mach-zynq/common.h
+++ b/arch/arm/mach-zynq/common.h
@@ -30,7 +30,7 @@ extern char zynq_secondary_trampoline;
 extern char zynq_secondary_trampoline_jump;
 extern char zynq_secondary_trampoline_end;
 extern int zynq_cpun_start(u32 address, int cpu);
-extern struct smp_operations zynq_smp_ops __initdata;
+extern const struct smp_operations zynq_smp_ops;
 #endif
 
 extern void __iomem *zynq_scu_base;
diff --git a/arch/arm/mach-zynq/platsmp.c b/arch/arm/mach-zynq/platsmp.c
index f66816c..7cd9865 100644
--- a/arch/arm/mach-zynq/platsmp.c
+++ b/arch/arm/mach-zynq/platsmp.c
@@ -157,7 +157,7 @@ static void zynq_cpu_die(unsigned int cpu)
 }
 #endif
 
-struct smp_operations zynq_smp_ops __initdata = {
+const struct smp_operations zynq_smp_ops __initconst = {
 	.smp_init_cpus		= zynq_smp_init_cpus,
 	.smp_prepare_cpus	= zynq_smp_prepare_cpus,
 	.smp_boot_secondary	= zynq_boot_secondary,
-- 
1.9.1



From yamada.masahiro at socionext.com  Sun Aug 23 21:36:10 2015
From: yamada.masahiro at socionext.com (Masahiro Yamada)
Date: Mon, 24 Aug 2015 13:36:10 +0900
Subject: [PATCH 10/18] ARM: mvebu: use const and __initconst for smp_operations
In-Reply-To: <1440390978-22796-1-git-send-email-yamada.masahiro@socionext.com>
References: <1440390978-22796-1-git-send-email-yamada.masahiro@socionext.com>
Message-ID: <1440390978-22796-11-git-send-email-yamada.masahiro@socionext.com>

The smp_operations structure is not over-written, so add const
qualifier and replace __initdata with __initconst.

Signed-off-by: Masahiro Yamada <yamada.masahiro at socionext.com>
---

 arch/arm/mach-mvebu/armada-370-xp.h | 2 +-
 arch/arm/mach-mvebu/platsmp-a9.c    | 4 ++--
 arch/arm/mach-mvebu/platsmp.c       | 2 +-
 3 files changed, 4 insertions(+), 4 deletions(-)

diff --git a/arch/arm/mach-mvebu/armada-370-xp.h b/arch/arm/mach-mvebu/armada-370-xp.h
index c55bbf8..09413b6 100644
--- a/arch/arm/mach-mvebu/armada-370-xp.h
+++ b/arch/arm/mach-mvebu/armada-370-xp.h
@@ -17,7 +17,7 @@
 
 #ifdef CONFIG_SMP
 void armada_xp_secondary_startup(void);
-extern struct smp_operations armada_xp_smp_ops;
+extern const struct smp_operations armada_xp_smp_ops;
 #endif
 
 #endif /* __MACH_ARMADA_370_XP_H */
diff --git a/arch/arm/mach-mvebu/platsmp-a9.c b/arch/arm/mach-mvebu/platsmp-a9.c
index 3d50004..d715dec 100644
--- a/arch/arm/mach-mvebu/platsmp-a9.c
+++ b/arch/arm/mach-mvebu/platsmp-a9.c
@@ -93,11 +93,11 @@ static int armada_38x_cpu_kill(unsigned int cpu)
 }
 #endif
 
-static struct smp_operations mvebu_cortex_a9_smp_ops __initdata = {
+static const struct smp_operations mvebu_cortex_a9_smp_ops __initconst = {
 	.smp_boot_secondary	= mvebu_cortex_a9_boot_secondary,
 };
 
-static struct smp_operations armada_38x_smp_ops __initdata = {
+static const struct smp_operations armada_38x_smp_ops __initconst = {
 	.smp_boot_secondary	= mvebu_cortex_a9_boot_secondary,
 	.smp_secondary_init     = armada_38x_secondary_init,
 #ifdef CONFIG_HOTPLUG_CPU
diff --git a/arch/arm/mach-mvebu/platsmp.c b/arch/arm/mach-mvebu/platsmp.c
index 58cc8c1..f9597b7 100644
--- a/arch/arm/mach-mvebu/platsmp.c
+++ b/arch/arm/mach-mvebu/platsmp.c
@@ -170,7 +170,7 @@ static int armada_xp_cpu_kill(unsigned int cpu)
 }
 #endif
 
-struct smp_operations armada_xp_smp_ops __initdata = {
+const struct smp_operations armada_xp_smp_ops __initconst = {
 	.smp_init_cpus		= armada_xp_smp_init_cpus,
 	.smp_prepare_cpus	= armada_xp_smp_prepare_cpus,
 	.smp_boot_secondary	= armada_xp_boot_secondary,
-- 
1.9.1



From yamada.masahiro at socionext.com  Sun Aug 23 21:36:18 2015
From: yamada.masahiro at socionext.com (Masahiro Yamada)
Date: Mon, 24 Aug 2015 13:36:18 +0900
Subject: [PATCH 18/18] ARM: mcpm: use const and __initconst for smp_operations
In-Reply-To: <1440390978-22796-1-git-send-email-yamada.masahiro@socionext.com>
References: <1440390978-22796-1-git-send-email-yamada.masahiro@socionext.com>
Message-ID: <1440390978-22796-19-git-send-email-yamada.masahiro@socionext.com>

The smp_operations structure is not over-written, so add const
qualifier and replace __initdata with __initconst.

Also, __initconst has been moved after mcpm_smp_ops because
scripts/checkpatch.pl suggests to do so.

Signed-off-by: Masahiro Yamada <yamada.masahiro at socionext.com>
---

 arch/arm/common/mcpm_platsmp.c | 2 +-
 1 file changed, 1 insertion(+), 1 deletion(-)

diff --git a/arch/arm/common/mcpm_platsmp.c b/arch/arm/common/mcpm_platsmp.c
index 92e54d7..1011b0e 100644
--- a/arch/arm/common/mcpm_platsmp.c
+++ b/arch/arm/common/mcpm_platsmp.c
@@ -87,7 +87,7 @@ static void mcpm_cpu_die(unsigned int cpu)
 
 #endif
 
-static struct smp_operations __initdata mcpm_smp_ops = {
+static const struct smp_operations mcpm_smp_ops __initconst = {
 	.smp_boot_secondary	= mcpm_boot_secondary,
 	.smp_secondary_init	= mcpm_secondary_init,
 #ifdef CONFIG_HOTPLUG_CPU
-- 
1.9.1



From yamada.masahiro at socionext.com  Sun Aug 23 21:36:16 2015
From: yamada.masahiro at socionext.com (Masahiro Yamada)
Date: Mon, 24 Aug 2015 13:36:16 +0900
Subject: [PATCH 16/18] ARM: zx: use const and __initconst for smp_operations
In-Reply-To: <1440390978-22796-1-git-send-email-yamada.masahiro@socionext.com>
References: <1440390978-22796-1-git-send-email-yamada.masahiro@socionext.com>
Message-ID: <1440390978-22796-17-git-send-email-yamada.masahiro@socionext.com>

The smp_operations structure is not over-written, so add const
qualifier and replace __initdata with __initconst.

Also, add static to the structure.

Signed-off-by: Masahiro Yamada <yamada.masahiro at socionext.com>
---

 arch/arm/mach-zx/platsmp.c | 2 +-
 1 file changed, 1 insertion(+), 1 deletion(-)

diff --git a/arch/arm/mach-zx/platsmp.c b/arch/arm/mach-zx/platsmp.c
index a369398..0297f92 100644
--- a/arch/arm/mach-zx/platsmp.c
+++ b/arch/arm/mach-zx/platsmp.c
@@ -176,7 +176,7 @@ static void zx_secondary_init(unsigned int cpu)
 	scu_power_mode(scu_base, SCU_PM_NORMAL);
 }
 
-struct smp_operations zx_smp_ops __initdata = {
+static const struct smp_operations zx_smp_ops __initconst = {
 	.smp_prepare_cpus	= zx_smp_prepare_cpus,
 	.smp_secondary_init	= zx_secondary_init,
 	.smp_boot_secondary	= zx_boot_secondary,
-- 
1.9.1



From eddie.huang at mediatek.com  Sun Aug 23 22:50:26 2015
From: eddie.huang at mediatek.com (Eddie Huang)
Date: Mon, 24 Aug 2015 13:50:26 +0800
Subject: [PATCH] soc: mediatek: add scpsys support active_wakeup
In-Reply-To: <1437631249-706-1-git-send-email-eddie.huang@mediatek.com>
References: <1437631249-706-1-git-send-email-eddie.huang@mediatek.com>
Message-ID: <1440395426.7245.2.camel@mtksdaap41>

On Thu, 2015-07-23 at 14:00 +0800, Eddie Huang wrote:
> Register gpd_dev_ops.active_wakeup function to support keep power
> during suspend state. And add flag to each power domain to
> decide whether keep power during suspend or not.
> 
> Signed-off-by: Chunfeng Yun <chunfeng.yun at mediatek.com>
> Signed-off-by: Eddie Huang <eddie.huang at mediatek.com>
> ---
>  drivers/soc/mediatek/mtk-scpsys.c | 28 ++++++++++++++++++++++++++++
>  1 file changed, 28 insertions(+)
> 
> diff --git a/drivers/soc/mediatek/mtk-scpsys.c b/drivers/soc/mediatek/mtk-scpsys.c
> index 43a79ed..fc78b70 100644
> --- a/drivers/soc/mediatek/mtk-scpsys.c
> +++ b/drivers/soc/mediatek/mtk-scpsys.c
> @@ -67,6 +67,7 @@ struct scp_domain_data {
>         u32 sram_pdn_ack_bits;
>         u32 bus_prot_mask;
>         enum clk_id clk_id;
> +       bool active_wakeup;
>  };
> 
>  static const struct scp_domain_data scp_domain_data[] __initconst = {
> @@ -77,6 +78,7 @@ static const struct scp_domain_data scp_domain_data[] __initconst = {
>                 .sram_pdn_bits = GENMASK(11, 8),
>                 .sram_pdn_ack_bits = GENMASK(12, 12),
>                 .clk_id = MT8173_CLK_MM,
> +               .active_wakeup = false,
>         },
>         [MT8173_POWER_DOMAIN_VENC] = {
>                 .name = "venc",
> @@ -85,6 +87,7 @@ static const struct scp_domain_data scp_domain_data[] __initconst = {
>                 .sram_pdn_bits = GENMASK(11, 8),
>                 .sram_pdn_ack_bits = GENMASK(15, 12),
>                 .clk_id = MT8173_CLK_MM,
> +               .active_wakeup = false,
>         },
>         [MT8173_POWER_DOMAIN_ISP] = {
>                 .name = "isp",
> @@ -93,6 +96,7 @@ static const struct scp_domain_data scp_domain_data[] __initconst = {
>                 .sram_pdn_bits = GENMASK(11, 8),
>                 .sram_pdn_ack_bits = GENMASK(13, 12),
>                 .clk_id = MT8173_CLK_MM,
> +               .active_wakeup = false,
>         },
>         [MT8173_POWER_DOMAIN_MM] = {
>                 .name = "mm",
> @@ -101,6 +105,7 @@ static const struct scp_domain_data scp_domain_data[] __initconst = {
>                 .sram_pdn_bits = GENMASK(11, 8),
>                 .sram_pdn_ack_bits = GENMASK(12, 12),
>                 .clk_id = MT8173_CLK_MM,
> +               .active_wakeup = false,
>                 .bus_prot_mask = MT8173_TOP_AXI_PROT_EN_MM_M0 |
>                         MT8173_TOP_AXI_PROT_EN_MM_M1,
>         },
> @@ -111,6 +116,7 @@ static const struct scp_domain_data scp_domain_data[] __initconst = {
>                 .sram_pdn_bits = GENMASK(11, 8),
>                 .sram_pdn_ack_bits = GENMASK(15, 12),
>                 .clk_id = MT8173_CLK_MM,
> +               .active_wakeup = false,
>         },
>         [MT8173_POWER_DOMAIN_AUDIO] = {
>                 .name = "audio",
> @@ -119,6 +125,7 @@ static const struct scp_domain_data scp_domain_data[] __initconst = {
>                 .sram_pdn_bits = GENMASK(11, 8),
>                 .sram_pdn_ack_bits = GENMASK(15, 12),
>                 .clk_id = MT8173_CLK_NONE,
> +               .active_wakeup = false,
>         },
>         [MT8173_POWER_DOMAIN_USB] = {
>                 .name = "usb",
> @@ -127,6 +134,7 @@ static const struct scp_domain_data scp_domain_data[] __initconst = {
>                 .sram_pdn_bits = GENMASK(11, 8),
>                 .sram_pdn_ack_bits = GENMASK(15, 12),
>                 .clk_id = MT8173_CLK_NONE,
> +               .active_wakeup = true,
>         },
>         [MT8173_POWER_DOMAIN_MFG_ASYNC] = {
>                 .name = "mfg_async",
> @@ -135,6 +143,7 @@ static const struct scp_domain_data scp_domain_data[] __initconst = {
>                 .sram_pdn_bits = GENMASK(11, 8),
>                 .sram_pdn_ack_bits = 0,
>                 .clk_id = MT8173_CLK_MFG,
> +               .active_wakeup = false,
>         },
>         [MT8173_POWER_DOMAIN_MFG_2D] = {
>                 .name = "mfg_2d",
> @@ -143,6 +152,7 @@ static const struct scp_domain_data scp_domain_data[] __initconst = {
>                 .sram_pdn_bits = GENMASK(11, 8),
>                 .sram_pdn_ack_bits = GENMASK(13, 12),
>                 .clk_id = MT8173_CLK_NONE,
> +               .active_wakeup = false,
>         },
>         [MT8173_POWER_DOMAIN_MFG] = {
>                 .name = "mfg",
> @@ -151,6 +161,7 @@ static const struct scp_domain_data scp_domain_data[] __initconst = {
>                 .sram_pdn_bits = GENMASK(13, 8),
>                 .sram_pdn_ack_bits = GENMASK(21, 16),
>                 .clk_id = MT8173_CLK_NONE,
> +               .active_wakeup = false,
>                 .bus_prot_mask = MT8173_TOP_AXI_PROT_EN_MFG_S |
>                         MT8173_TOP_AXI_PROT_EN_MFG_M0 |
>                         MT8173_TOP_AXI_PROT_EN_MFG_M1 |
> @@ -171,6 +182,7 @@ struct scp_domain {
>         u32 sram_pdn_bits;
>         u32 sram_pdn_ack_bits;
>         u32 bus_prot_mask;
> +       bool active_wakeup;
>  };
> 
>  struct scp {
> @@ -370,6 +382,20 @@ out:
>         return ret;
>  }
> 
> +static bool scpsys_active_wakeup(struct device *dev)
> +{
> +       struct generic_pm_domain *genpd;
> +       struct scp_domain *scpd;
> +
> +       if (IS_ERR_OR_NULL(dev->pm_domain))
> +               return false;
> +
> +       genpd = pd_to_genpd(dev->pm_domain);
> +       scpd = container_of(genpd, struct scp_domain, genpd);
> +
> +       return scpd->active_wakeup;
> +}
> +
>  static int __init scpsys_probe(struct platform_device *pdev)
>  {
>         struct genpd_onecell_data *pd_data;
> @@ -427,12 +453,14 @@ static int __init scpsys_probe(struct platform_device *pdev)
>                 scpd->sram_pdn_bits = data->sram_pdn_bits;
>                 scpd->sram_pdn_ack_bits = data->sram_pdn_ack_bits;
>                 scpd->bus_prot_mask = data->bus_prot_mask;
> +               scpd->active_wakeup = data->active_wakeup;
>                 if (data->clk_id != MT8173_CLK_NONE)
>                         scpd->clk = clk[data->clk_id];
> 
>                 genpd->name = data->name;
>                 genpd->power_off = scpsys_power_off;
>                 genpd->power_on = scpsys_power_on;
> +               genpd->dev_ops.active_wakeup = scpsys_active_wakeup;
> 
>                 /*
>                  * Initially turn on all domains to make the domains usable
> --
> 1.8.1.1.dirty
> 

Hi Sascha, Matthias,

Any comment about this patch ?

Eddie
Thanks





From vaibhav.hiremath at linaro.org  Sun Aug 23 22:59:33 2015
From: vaibhav.hiremath at linaro.org (Vaibhav Hiremath)
Date: Mon, 24 Aug 2015 11:29:33 +0530
Subject: [PATCH-v5 RESEND 0/5] i2c: pxa: Add support for PXA910 family of
 device
Message-ID: <1440395978-9065-1-git-send-email-vaibhav.hiremath@linaro.org>

Sorry for not following up on this aggressively, was quit busy with some
other stuff. Resending this patch with Robert's Tested-By.


This patch-series is subset of the original patch-series, submitted
on 14 Jul 2015.
Link to Original Patch-series - https://lkml.org/lkml/2015/7/14/80

The first six patches have been already queued up for upstream. So this
patch-series is respin of remaining 5 patches.

Testing:
  - Basic testing on PMIC device on I2C-0 interface
  - Boot tested on platform based on PXA1928
  - Read few registers of PMIC (RTC, ID, etc...) during boot

V4 => V5
=======
Link to V3: https://lkml.org/lkml/2015/7/14/80
  - Dropped First 6 patches as they are already accepted, queued for upstream
  - Fixed a bug in PATCH [5/5], where for non PXA910 devices it as resulting into
    NULL pointer dereference.


For the record, pasting all the details from original patch-series -

V3 => V4
=======
Link to V3: http://www.spinics.net/lists/devicetree/msg85904.html
  - [PATCH 06/11] Removed unnecessary dev_err on devm_kzalloc() check
  - [PATCH 06/11] Removed return check on platform_get_resource(), as 
    devm_ioremap_resource() does it for us.
    Also, brought up the devm_ioremap_resource() function call in the execution
    sequence, as no point in delaying it if we do not have resource.
    It make sense, after this change.
  - [PATCH 04/11] Typecast changed to 'enum pxa_i2c_types'
    Also updated the subject line "Removed ==> Fix"

V2 => V3
=======
Link to V2: http://www.spinics.net/lists/linux-i2c/msg20059.html
  - Removed PATCH [4/12] related to reset of I2C module.
    Suggested by "Robert Jarzmik"
  - Updated commit description for,
      PATCH [11/12]: Mentioned reasoning about moment of clk_get code.
      PATCH [12/12]: for DT property node.
  - Added Acked by "Robert Jarzmik" to patched which he acked.

V1 => V2:
========
Link to V1 - http://lists.infradead.org/pipermail/linux-arm-kernel/2015-May/347012.html
  - Fixed all comments from "Robert Jarzmik" and "Wolfram Sang"
 - Dropped Patch
     05/12: using core bus reset implementation - under work.
     08/12: NAKed and dropped
 - Separated DT binding patch from driver changes, for easy merge


Vaibhav Hiremath (4):
  Documentation: binding: add new property 'disable_after_xfer' to
    i2c-pxa
  i2c: pxa: Add support for pxa910/988 & new configuration features
  Documentation: binding: add sclk adjustment properties to i2c-pxa
  i2c: pxa: Add ILCR (tLow & tHigh) configuration support

Yi Zhang (1):
  i2c: pxa: enable/disable i2c module across msg xfer

 Documentation/devicetree/bindings/i2c/i2c-pxa.txt |  18 +++
 drivers/i2c/busses/i2c-pxa.c                      | 154 ++++++++++++++++++++--
 2 files changed, 163 insertions(+), 9 deletions(-)

-- 
1.9.1



From vaibhav.hiremath at linaro.org  Sun Aug 23 22:59:34 2015
From: vaibhav.hiremath at linaro.org (Vaibhav Hiremath)
Date: Mon, 24 Aug 2015 11:29:34 +0530
Subject: [PATCH-v5 RESEND 1/5] Documentation: binding: add new property
 'disable_after_xfer' to i2c-pxa
In-Reply-To: <1440395978-9065-1-git-send-email-vaibhav.hiremath@linaro.org>
References: <1440395978-9065-1-git-send-email-vaibhav.hiremath@linaro.org>
Message-ID: <1440395978-9065-2-git-send-email-vaibhav.hiremath@linaro.org>

Driver will now supports enable/disable across msg xfer, which user
can control it by new DT property -

i2c-disable-after-xfer : If set, driver will disable I2C module after msg
 xfer and enable it back before xfer.

Signed-off-by: Vaibhav Hiremath <vaibhav.hiremath at linaro.org>
---
 Documentation/devicetree/bindings/i2c/i2c-pxa.txt | 5 +++++
 1 file changed, 5 insertions(+)

diff --git a/Documentation/devicetree/bindings/i2c/i2c-pxa.txt b/Documentation/devicetree/bindings/i2c/i2c-pxa.txt
index 12b78ac..9657db5 100644
--- a/Documentation/devicetree/bindings/i2c/i2c-pxa.txt
+++ b/Documentation/devicetree/bindings/i2c/i2c-pxa.txt
@@ -18,6 +18,11 @@ Recommended properties :
    status register of i2c controller instead.
  - mrvl,i2c-fast-mode : Enable fast mode of i2c controller.
 
+Optional properties :
+
+ - i2c-disable-after-xfer : If set, driver will disable I2C module
+   after msg xfer and enable it again before xfer.
+
 Examples:
 	twsi1: i2c at d4011000 {
 		compatible = "mrvl,mmp-twsi";
-- 
1.9.1



From vaibhav.hiremath at linaro.org  Sun Aug 23 22:59:35 2015
From: vaibhav.hiremath at linaro.org (Vaibhav Hiremath)
Date: Mon, 24 Aug 2015 11:29:35 +0530
Subject: [PATCH-v5 RESEND 2/5] i2c: pxa: enable/disable i2c module across msg
 xfer
In-Reply-To: <1440395978-9065-1-git-send-email-vaibhav.hiremath@linaro.org>
References: <1440395978-9065-1-git-send-email-vaibhav.hiremath@linaro.org>
Message-ID: <1440395978-9065-3-git-send-email-vaibhav.hiremath@linaro.org>

From: Yi Zhang <yizhang at marvell.com>

Enable i2c module/unit before transmission and disable when it
finishes.

why?
It's because the i2c bus may be disturbed if the slave device,
typically a touch, powers on.

As we do not want to break slave mode support, this patch introduces
DT property to control disable of the I2C module after xfer in master
mode of operation.

i2c-disable-after-xfer : If set, driver will disable I2C module after
msg xfer

Signed-off-by: Yi Zhang <yizhang at marvell.com>
Signed-off-by: Vaibhav Hiremath <vaibhav.hiremath at linaro.org>
---
 drivers/i2c/busses/i2c-pxa.c | 43 +++++++++++++++++++++++++++++++++++++++++--
 1 file changed, 41 insertions(+), 2 deletions(-)

diff --git a/drivers/i2c/busses/i2c-pxa.c b/drivers/i2c/busses/i2c-pxa.c
index 66cf437..abf04f2 100644
--- a/drivers/i2c/busses/i2c-pxa.c
+++ b/drivers/i2c/busses/i2c-pxa.c
@@ -161,6 +161,7 @@ struct pxa_i2c {
 	unsigned char		master_code;
 	unsigned long		rate;
 	bool			highmode_enter;
+	bool			disable_after_xfer;
 };
 
 #define _IBMR(i2c)	((i2c)->reg_ibmr)
@@ -284,6 +285,24 @@ static void i2c_pxa_scream_blue_murder(struct pxa_i2c *i2c, const char *why)
 static void i2c_pxa_master_complete(struct pxa_i2c *i2c, int ret);
 static irqreturn_t i2c_pxa_handler(int this_irq, void *dev_id);
 
+/* enable/disable i2c unit */
+static inline int i2c_pxa_is_enabled(struct pxa_i2c *i2c)
+{
+	return (readl(_ICR(i2c)) & ICR_IUE);
+}
+
+static inline void i2c_pxa_enable(struct pxa_i2c *i2c, bool enable)
+{
+	if (enable) {
+		if (!i2c_pxa_is_enabled(i2c)) {
+			writel(readl(_ICR(i2c)) | ICR_IUE, _ICR(i2c));
+			udelay(100);
+		}
+	} else {
+		writel(readl(_ICR(i2c)) & ~ICR_IUE, _ICR(i2c));
+	}
+}
+
 static inline int i2c_pxa_is_slavemode(struct pxa_i2c *i2c)
 {
 	return !(readl(_ICR(i2c)) & ICR_SCLE);
@@ -480,8 +499,7 @@ static void i2c_pxa_reset(struct pxa_i2c *i2c)
 	i2c_pxa_set_slave(i2c, 0);
 
 	/* enable unit */
-	writel(readl(_ICR(i2c)) | ICR_IUE, _ICR(i2c));
-	udelay(100);
+	i2c_pxa_enable(i2c, true);
 }
 
 
@@ -832,6 +850,9 @@ static int i2c_pxa_pio_xfer(struct i2c_adapter *adap,
 	struct pxa_i2c *i2c = adap->algo_data;
 	int ret, i;
 
+	/* Enable i2c unit */
+	i2c_pxa_enable(i2c, true);
+
 	/* If the I2C controller is disabled we need to reset it
 	  (probably due to a suspend/resume destroying state). We do
 	  this here as we can then avoid worrying about resuming the
@@ -852,6 +873,11 @@ static int i2c_pxa_pio_xfer(struct i2c_adapter *adap,
 	ret = -EREMOTEIO;
  out:
 	i2c_pxa_set_slave(i2c, ret);
+
+	/* disable i2c unit */
+	if (i2c->disable_after_xfer)
+		i2c_pxa_enable(i2c, false);
+
 	return ret;
 }
 
@@ -1067,6 +1093,9 @@ static int i2c_pxa_xfer(struct i2c_adapter *adap, struct i2c_msg msgs[], int num
 	struct pxa_i2c *i2c = adap->algo_data;
 	int ret, i;
 
+	/* Enable i2c unit */
+	i2c_pxa_enable(i2c, true);
+
 	for (i = adap->retries; i >= 0; i--) {
 		ret = i2c_pxa_do_xfer(i2c, msgs, num);
 		if (ret != I2C_RETRY)
@@ -1080,6 +1109,10 @@ static int i2c_pxa_xfer(struct i2c_adapter *adap, struct i2c_msg msgs[], int num
 	ret = -EREMOTEIO;
  out:
 	i2c_pxa_set_slave(i2c, ret);
+	/* disable i2c unit */
+	if (i2c->disable_after_xfer)
+		i2c_pxa_enable(i2c, false);
+
 	return ret;
 }
 
@@ -1120,6 +1153,9 @@ static int i2c_pxa_probe_dt(struct platform_device *pdev, struct pxa_i2c *i2c,
 	/* For device tree we always use the dynamic or alias-assigned ID */
 	i2c->adap.nr = -1;
 
+	i2c->disable_after_xfer = of_property_read_bool(np,
+				"i2c-disable-after-xfer");
+
 	if (of_get_property(np, "mrvl,i2c-polling", NULL))
 		i2c->use_pio = 1;
 	if (of_get_property(np, "mrvl,i2c-fast-mode", NULL))
@@ -1264,6 +1300,9 @@ static int i2c_pxa_probe(struct platform_device *dev)
 
 	platform_set_drvdata(dev, i2c);
 
+	if (i2c->disable_after_xfer)
+		i2c_pxa_enable(i2c, false);
+
 #ifdef CONFIG_I2C_PXA_SLAVE
 	dev_info(&i2c->adap.dev, " PXA I2C adapter, slave address %d\n",
 		i2c->slave_addr);
-- 
1.9.1



From vaibhav.hiremath at linaro.org  Sun Aug 23 22:59:36 2015
From: vaibhav.hiremath at linaro.org (Vaibhav Hiremath)
Date: Mon, 24 Aug 2015 11:29:36 +0530
Subject: [PATCH-v5 RESEND 3/5] i2c: pxa: Add support for pxa910/988 & new
 configuration features
In-Reply-To: <1440395978-9065-1-git-send-email-vaibhav.hiremath@linaro.org>
References: <1440395978-9065-1-git-send-email-vaibhav.hiremath@linaro.org>
Message-ID: <1440395978-9065-4-git-send-email-vaibhav.hiremath@linaro.org>

TWSI_ILCR & TWSI_IWCR registers are used to adjust clock rate
of standard & fast mode in pxa910/988; so this patch adds these two new
entries to "struct pxa_reg_layout" and "struct pxa_i2c".

As discussed in the previous patch-series, the idea here is to add standard
DT properties for ilcr and iwcr configuration fields.
In case of Master ilcr is used for low/high time and in case of slave mode
of operation iwcr is used for setup/hold time.

Signed-off-by: Jett.Zhou <jtzhou at marvell.com>
Signed-off-by: Yi Zhang <yizhang at marvell.com>
Signed-off-by: Vaibhav Hiremath <vaibhav.hiremath at linaro.org>
Tested-by: Robert Jarzmik <robert.jarzmik at free.fr>
---
 drivers/i2c/busses/i2c-pxa.c | 42 +++++++++++++++++++++++++++++++++++++++++-
 1 file changed, 41 insertions(+), 1 deletion(-)

diff --git a/drivers/i2c/busses/i2c-pxa.c b/drivers/i2c/busses/i2c-pxa.c
index abf04f2..8d76197 100644
--- a/drivers/i2c/busses/i2c-pxa.c
+++ b/drivers/i2c/busses/i2c-pxa.c
@@ -46,12 +46,15 @@ struct pxa_reg_layout {
 	u32 icr;
 	u32 isr;
 	u32 isar;
+	u32 ilcr;
+	u32 iwcr;
 };
 
 enum pxa_i2c_types {
 	REGS_PXA2XX,
 	REGS_PXA3XX,
 	REGS_CE4100,
+	REGS_PXA910,
 };
 
 /*
@@ -79,12 +82,22 @@ static struct pxa_reg_layout pxa_reg_layout[] = {
 		.isr =	0x04,
 		/* no isar register */
 	},
+	[REGS_PXA910] = {
+		.ibmr = 0x00,
+		.idbr = 0x08,
+		.icr =	0x10,
+		.isr =	0x18,
+		.isar = 0x20,
+		.ilcr = 0x28,
+		.iwcr = 0x30,
+	},
 };
 
 static const struct platform_device_id i2c_pxa_id_table[] = {
 	{ "pxa2xx-i2c",		REGS_PXA2XX },
 	{ "pxa3xx-pwri2c",	REGS_PXA3XX },
 	{ "ce4100-i2c",		REGS_CE4100 },
+	{ "pxa910-i2c",		REGS_PXA910 },
 	{ },
 };
 MODULE_DEVICE_TABLE(platform, i2c_pxa_id_table);
@@ -124,6 +137,24 @@ MODULE_DEVICE_TABLE(platform, i2c_pxa_id_table);
 #define ISR_SAD		(1 << 9)	   /* slave address detected */
 #define ISR_BED		(1 << 10)	   /* bus error no ACK/NAK */
 
+/* bit field shift & mask */
+#define ILCR_SLV_SHIFT		0
+#define ILCR_SLV_MASK		(0x1FF << ILCR_SLV_SHIFT)
+#define ILCR_FLV_SHIFT		9
+#define ILCR_FLV_MASK		(0x1FF << ILCR_FLV_SHIFT)
+#define ILCR_HLVL_SHIFT		18
+#define ILCR_HLVL_MASK		(0x1FF << ILCR_HLVL_SHIFT)
+#define ILCR_HLVH_SHIFT		27
+#define ILCR_HLVH_MASK		(0x1F << ILCR_HLVH_SHIFT)
+
+#define IWCR_CNT_SHIFT		0
+#define IWCR_CNT_MASK		(0x1F << IWCR_CNT_SHIFT)
+#define IWCR_HS_CNT1_SHIFT	5
+#define IWCR_HS_CNT1_MASK	(0x1F << IWCR_HS_CNT1_SHIFT)
+#define IWCR_HS_CNT2_SHIFT	10
+#define IWCR_HS_CNT2_MASK	(0x1F << IWCR_HS_CNT2_SHIFT)
+
+
 struct pxa_i2c {
 	spinlock_t		lock;
 	wait_queue_head_t	wait;
@@ -150,6 +181,8 @@ struct pxa_i2c {
 	void __iomem		*reg_icr;
 	void __iomem		*reg_isr;
 	void __iomem		*reg_isar;
+	void __iomem		*reg_ilcr;
+	void __iomem		*reg_iwcr;
 
 	unsigned long		iobase;
 	unsigned long		iosize;
@@ -169,6 +202,8 @@ struct pxa_i2c {
 #define _ICR(i2c)	((i2c)->reg_icr)
 #define _ISR(i2c)	((i2c)->reg_isr)
 #define _ISAR(i2c)	((i2c)->reg_isar)
+#define _ILCR(i2c)	((i2c)->reg_ilcr)
+#define _IWCR(i2c)	((i2c)->reg_iwcr)
 
 /*
  * I2C Slave mode address
@@ -1135,7 +1170,7 @@ static const struct i2c_algorithm i2c_pxa_pio_algorithm = {
 static const struct of_device_id i2c_pxa_dt_ids[] = {
 	{ .compatible = "mrvl,pxa-i2c", .data = (void *)REGS_PXA2XX },
 	{ .compatible = "mrvl,pwri2c", .data = (void *)REGS_PXA3XX },
-	{ .compatible = "mrvl,mmp-twsi", .data = (void *)REGS_PXA2XX },
+	{ .compatible = "mrvl,mmp-twsi", .data = (void *)REGS_PXA910 },
 	{}
 };
 MODULE_DEVICE_TABLE(of, i2c_pxa_dt_ids);
@@ -1243,6 +1278,11 @@ static int i2c_pxa_probe(struct platform_device *dev)
 	if (i2c_type != REGS_CE4100)
 		i2c->reg_isar = i2c->reg_base + pxa_reg_layout[i2c_type].isar;
 
+	if (i2c_type == REGS_PXA910) {
+		i2c->reg_ilcr = i2c->reg_base + pxa_reg_layout[i2c_type].ilcr;
+		i2c->reg_iwcr = i2c->reg_base + pxa_reg_layout[i2c_type].iwcr;
+	}
+
 	i2c->iobase = res->start;
 	i2c->iosize = resource_size(res);
 
-- 
1.9.1



From vaibhav.hiremath at linaro.org  Sun Aug 23 22:59:37 2015
From: vaibhav.hiremath at linaro.org (Vaibhav Hiremath)
Date: Mon, 24 Aug 2015 11:29:37 +0530
Subject: [PATCH-v5 RESEND 4/5] Documentation: binding: add sclk adjustment
 properties to i2c-pxa
In-Reply-To: <1440395978-9065-1-git-send-email-vaibhav.hiremath@linaro.org>
References: <1440395978-9065-1-git-send-email-vaibhav.hiremath@linaro.org>
Message-ID: <1440395978-9065-5-git-send-email-vaibhav.hiremath@linaro.org>

With addition of PXA910 family of devices, the TWSI module supports
new feature which allows us to adjust SCLK. i2c-pxa driver takes input
configuration in nsec and converts it to respective bit-fields,

 - i2c-sclk-low-time-ns : SCLK low time (tlow)
   This property is used along with mode selection.
 - i2c-sclk-high-time-ns : SCLK high time (thigh)
 - i2c-start-hold-time-ns : Used in case of high speed mode for start bit
   hold/setup wait counter.
 - i2c-stop-hold-time-ns : Used in case of high speed mode for stop bit
   hold/setup wait counter.
 - i2c-sda-hold-time-ns : Used to calculate hold/setup wait counter for
   standard and fast mode.

Signed-off-by: Vaibhav Hiremath <vaibhav.hiremath at linaro.org>
---
 Documentation/devicetree/bindings/i2c/i2c-pxa.txt | 13 +++++++++++++
 1 file changed, 13 insertions(+)

diff --git a/Documentation/devicetree/bindings/i2c/i2c-pxa.txt b/Documentation/devicetree/bindings/i2c/i2c-pxa.txt
index 9657db5..bb4df60 100644
--- a/Documentation/devicetree/bindings/i2c/i2c-pxa.txt
+++ b/Documentation/devicetree/bindings/i2c/i2c-pxa.txt
@@ -23,12 +23,25 @@ Optional properties :
  - i2c-disable-after-xfer : If set, driver will disable I2C module
    after msg xfer and enable it again before xfer.
 
+   (Applicable to PXA910 family):
+
+ - i2c-sclk-low-time-ns : SCLK low time (tlow), for standard/fast/high
+   speed mode.
+   This property is used along with mode selection. Driver uses this property
+   to set low/high time for standard and fast speed mode, as HW counter
+   bit-field is same for both.
+ - i2c-sclk-high-time-ns : SCLK high time (thigh), Used in case of high speed
+   mode only.
+
 Examples:
 	twsi1: i2c at d4011000 {
 		compatible = "mrvl,mmp-twsi";
 		reg = <0xd4011000 0x1000>;
 		interrupts = <7>;
 		mrvl,i2c-fast-mode;
+
+		i2c-sclk-low-time-ns = <988>;
+		i2c-sclk-high-time-ns = <988>;
 	};
 	
 	twsi2: i2c at d4025000 {
-- 
1.9.1



From vaibhav.hiremath at linaro.org  Sun Aug 23 22:59:38 2015
From: vaibhav.hiremath at linaro.org (Vaibhav Hiremath)
Date: Mon, 24 Aug 2015 11:29:38 +0530
Subject: [PATCH-v5 RESEND 5/5] i2c: pxa: Add ILCR (tLow & tHigh) configuration
 support
In-Reply-To: <1440395978-9065-1-git-send-email-vaibhav.hiremath@linaro.org>
References: <1440395978-9065-1-git-send-email-vaibhav.hiremath@linaro.org>
Message-ID: <1440395978-9065-6-git-send-email-vaibhav.hiremath@linaro.org>

With addition of PXA910 family of devices, the TWSI module supports
SCL clock adjustment using ILCR register.

This patch enables the control and configuration of ICLR through DT
properties,

i2c-sclk-high-time-ns:
  SCLK high time (tHigh), for standard/fast/high speed mode
i2c-sclk-low-time-ns:
  SCLK low time (tLow), for standard/fast/high speed mode

Note that in case of standard and fast mod, the tLow and tHigh counters
are same, and software will use tLow value.

Also, brought up devm_clk_get() fn above i2c_pxa_probe_dt(), as it
uses clk rate for timing calculations.

Signed-off-by: Vaibhav Hiremath <vaibhav.hiremath at linaro.org>
Signed-off-by: Jett.Zhou <jtzhou at marvell.com>
Signed-off-by: Yi Zhang <yizhang at marvell.com>
Tested-by: Robert Jarzmik <robert.jarzmik at free.fr>
---
 drivers/i2c/busses/i2c-pxa.c | 69 ++++++++++++++++++++++++++++++++++++++++----
 1 file changed, 63 insertions(+), 6 deletions(-)

diff --git a/drivers/i2c/busses/i2c-pxa.c b/drivers/i2c/busses/i2c-pxa.c
index 8d76197..6012ae5 100644
--- a/drivers/i2c/busses/i2c-pxa.c
+++ b/drivers/i2c/busses/i2c-pxa.c
@@ -195,6 +195,9 @@ struct pxa_i2c {
 	unsigned long		rate;
 	bool			highmode_enter;
 	bool			disable_after_xfer;
+
+	unsigned int		sclk_thigh_load_cnt;
+	unsigned int		sclk_tlow_load_cnt;
 };
 
 #define _IBMR(i2c)	((i2c)->reg_ibmr)
@@ -507,6 +510,36 @@ static void i2c_pxa_set_slave(struct pxa_i2c *i2c, int errcode)
 #define i2c_pxa_set_slave(i2c, err)	do { } while (0)
 #endif
 
+static void i2c_pxa_do_sclk_adj(struct pxa_i2c *i2c)
+{
+	unsigned int reg_ilcr;
+
+	if (!i2c->reg_ilcr)
+		return;
+
+	reg_ilcr = readl(_ILCR(i2c));
+
+	/* For standard/fast mode tlow and thigh counters are same */
+	if (i2c->sclk_tlow_load_cnt) {
+		unsigned int mask, shift;
+
+		mask = i2c->high_mode ? ILCR_HLVL_MASK :
+			i2c->fast_mode ? ILCR_FLV_MASK : ILCR_SLV_MASK;
+		shift = i2c->high_mode ? ILCR_HLVL_SHIFT :
+			i2c->fast_mode ? ILCR_FLV_SHIFT : ILCR_SLV_SHIFT;
+
+		reg_ilcr &= ~mask;
+		reg_ilcr |= i2c->sclk_tlow_load_cnt << shift;
+	}
+
+	if (i2c->high_mode && i2c->sclk_thigh_load_cnt) {
+		reg_ilcr &= ~ILCR_HLVH_MASK;
+		reg_ilcr |= i2c->sclk_thigh_load_cnt << ILCR_HLVH_SHIFT;
+	}
+
+	writel(reg_ilcr, _ILCR(i2c));
+}
+
 static void i2c_pxa_reset(struct pxa_i2c *i2c)
 {
 	pr_debug("Resetting I2C Controller Unit\n");
@@ -526,6 +559,8 @@ static void i2c_pxa_reset(struct pxa_i2c *i2c)
 	writel(I2C_ICR_INIT | (i2c->fast_mode ? ICR_FM : 0), _ICR(i2c));
 	writel(readl(_ICR(i2c)) | (i2c->high_mode ? ICR_HS : 0), _ICR(i2c));
 
+	i2c_pxa_do_sclk_adj(i2c);
+
 #ifdef CONFIG_I2C_PXA_SLAVE
 	dev_info(&i2c->adap.dev, "Enabling slave mode\n");
 	writel(readl(_ICR(i2c)) | ICR_SADIE | ICR_ALDIE | ICR_SSDIE, _ICR(i2c));
@@ -1198,6 +1233,26 @@ static int i2c_pxa_probe_dt(struct platform_device *pdev, struct pxa_i2c *i2c,
 
 	*i2c_types = (enum pxa_i2c_types)(of_id->data);
 
+	/* optional properties */
+	if (of_device_is_compatible(np, "mrvl,mmp-twsi")) {
+		unsigned int tlow = 0, thigh = 0;
+		unsigned int clk_ns;
+
+		/* clock time in nsec */
+		clk_ns = 1000000 / (i2c->rate / 1000);
+
+		of_property_read_u32(np, "i2c-sclk-high-time-ns", &thigh);
+		i2c->sclk_thigh_load_cnt = thigh / clk_ns;
+
+		of_property_read_u32(np, "i2c-sclk-low-time-ns", &tlow);
+		i2c->sclk_tlow_load_cnt = tlow / clk_ns;
+
+		/* For std/fast mode tlow & thigh have same bit-fields */
+		if (!i2c->high_mode &&
+			(i2c->sclk_tlow_load_cnt != i2c->sclk_thigh_load_cnt))
+			dev_warn(&i2c->adap.dev,
+				"mismatch of tLow & tHigh values, using tLow\n");
+	}
 	return 0;
 }
 
@@ -1248,6 +1303,14 @@ static int i2c_pxa_probe(struct platform_device *dev)
 		return irq;
 	}
 
+	i2c->clk = devm_clk_get(&dev->dev, NULL);
+	if (IS_ERR(i2c->clk)) {
+		dev_err(&dev->dev, "failed to get the clk: %ld\n", PTR_ERR(i2c->clk));
+		return PTR_ERR(i2c->clk);
+	}
+
+	i2c->rate = clk_get_rate(i2c->clk);
+
 	/* Default adapter num to device id; i2c_pxa_probe_dt can override. */
 	i2c->adap.nr = dev->id;
 
@@ -1265,12 +1328,6 @@ static int i2c_pxa_probe(struct platform_device *dev)
 
 	strlcpy(i2c->adap.name, "pxa_i2c-i2c", sizeof(i2c->adap.name));
 
-	i2c->clk = devm_clk_get(&dev->dev, NULL);
-	if (IS_ERR(i2c->clk)) {
-		dev_err(&dev->dev, "failed to get the clk: %ld\n", PTR_ERR(i2c->clk));
-		return PTR_ERR(i2c->clk);
-	}
-
 	i2c->reg_ibmr = i2c->reg_base + pxa_reg_layout[i2c_type].ibmr;
 	i2c->reg_idbr = i2c->reg_base + pxa_reg_layout[i2c_type].idbr;
 	i2c->reg_icr = i2c->reg_base + pxa_reg_layout[i2c_type].icr;
-- 
1.9.1



From maxime.ripard at free-electrons.com  Sun Aug 23 23:22:55 2015
From: maxime.ripard at free-electrons.com (Maxime Ripard)
Date: Mon, 24 Aug 2015 08:22:55 +0200
Subject: [PATCH 14/18] ARM: sunxi: use const and __initconst for
 smp_operations
In-Reply-To: <1440390978-22796-15-git-send-email-yamada.masahiro@socionext.com>
References: <1440390978-22796-1-git-send-email-yamada.masahiro@socionext.com>
 <1440390978-22796-15-git-send-email-yamada.masahiro@socionext.com>
Message-ID: <20150824062255.GA2413@lukather>

On Mon, Aug 24, 2015 at 01:36:14PM +0900, Masahiro Yamada wrote:
> The smp_operations structure is not over-written, so add const
> qualifier and replace __initdata with __initconst.
> 
> Also, add static to sun8i_smp_ops.
> 
> Signed-off-by: Masahiro Yamada <yamada.masahiro at socionext.com>

Acked-by: Maxime Ripard <maxime.ripard at free-electrons.com>

Thanks!
Maxime

-- 
Maxime Ripard, Free Electrons
Embedded Linux, Kernel and Android engineering
http://free-electrons.com
-------------- next part --------------
A non-text attachment was scrubbed...
Name: signature.asc
Type: application/pgp-signature
Size: 819 bytes
Desc: Digital signature
URL: <http://lists.infradead.org/pipermail/linux-arm-kernel/attachments/20150824/9e349cd7/attachment.sig>

From wangzhou1 at hisilicon.com  Sun Aug 23 23:26:07 2015
From: wangzhou1 at hisilicon.com (Zhou Wang)
Date: Mon, 24 Aug 2015 14:26:07 +0800
Subject: [PATCH v7 3/6] PCI: designware: Add ARM64 support
In-Reply-To: <EE11001F9E5DDD47B7634E2F8A612F2E01D826BD@lhreml503-mbs>
References: <1439812554-180426-1-git-send-email-wangzhou1@hisilicon.com>
 <1439812554-180426-4-git-send-email-wangzhou1@hisilicon.com>
 <1439988852.31432.15.camel@pengutronix.de>
 <EE11001F9E5DDD47B7634E2F8A612F2E01D81315@lhreml503-mbs>
 <1439998622.31432.44.camel@pengutronix.de>
 <EE11001F9E5DDD47B7634E2F8A612F2E01D8139B@lhreml503-mbs>
 <1440059243.31432.59.camel@pengutronix.de>
 <EE11001F9E5DDD47B7634E2F8A612F2E01D81BAC@lhreml503-mbs>
 <20150821134230.GQ1020@e106497-lin.cambridge.arm.com>
 <EE11001F9E5DDD47B7634E2F8A612F2E01D826BD@lhreml503-mbs>
Message-ID: <55DAB8FF.70603@hisilicon.com>

On 2015/8/21 22:19, Gabriele Paoloni wrote:
> Hi Liviu
> 
> Many Thanks for reviewing
> 
>> -----Original Message-----
>> From: linux-pci-owner at vger.kernel.org [mailto:linux-pci-
>> owner at vger.kernel.org] On Behalf Of Liviu Dudau
>> Sent: Friday, August 21, 2015 2:43 PM
>> To: Gabriele Paoloni
>> Cc: Lucas Stach; Wangzhou (B); Bjorn Helgaas; jingoohan1 at gmail.com;
>> Pratyush Anand; Arnd Bergmann; linux at arm.linux.org.uk;
>> thomas.petazzoni at free-electrons.com; Lorenzo Pieralisi; James Morse;
>> jason at lakedaemon.net; robh at kernel.org; linux-pci at vger.kernel.org;
>> linux-arm-kernel at lists.infradead.org; devicetree at vger.kernel.org;
>> Yuanzhichang; Zhudacai; zhangjukuo; qiuzhenfa; liudongdong (C);
>> qiujiang; xuwei (O); Liguozhu (Kenneth)
>> Subject: Re: [PATCH v7 3/6] PCI: designware: Add ARM64 support
>>
>> On Thu, Aug 20, 2015 at 12:10:24PM +0100, Gabriele Paoloni wrote:
>>> Hi Lucas
>>>
>>> Again many thanks for explaining and for your time.
>>>
>>> I got your point now and I have dug a bit better in the PCI_DOMAINS
>> code.
>>>
>>> However I have a question...see inline below
>>>
>>>> -----Original Message-----
>>>> From: Lucas Stach [mailto:l.stach at pengutronix.de]
>>>> Sent: Thursday, August 20, 2015 9:27 AM
>>>> To: Gabriele Paoloni
>>>> Cc: Wangzhou (B); Bjorn Helgaas; jingoohan1 at gmail.com; Pratyush
>> Anand;
>>>> Arnd Bergmann; linux at arm.linux.org.uk; thomas.petazzoni at free-
>>>> electrons.com; lorenzo.pieralisi at arm.com; james.morse at arm.com;
>>>> Liviu.Dudau at arm.com; jason at lakedaemon.net; robh at kernel.org; linux-
>>>> pci at vger.kernel.org; linux-arm-kernel at lists.infradead.org;
>>>> devicetree at vger.kernel.org; Yuanzhichang; Zhudacai; zhangjukuo;
>>>> qiuzhenfa; liudongdong (C); qiujiang; xuwei (O); Liguozhu (Kenneth)
>>>> Subject: Re: [PATCH v7 3/6] PCI: designware: Add ARM64 support
>>>>
>>>> Hi Gab,
>>>>
>>>> Am Mittwoch, den 19.08.2015, 16:34 +0000 schrieb Gabriele Paoloni:
>>>>> Hi Lucas
>>>>>
>>>>> First of all many thanks for the quick reply, really appreciated
>>>>>
>>>>>> -----Original Message-----
>>>>>> From: Lucas Stach [mailto:l.stach at pengutronix.de]
>>>>>> Sent: Wednesday, August 19, 2015 4:37 PM
>>>>>> To: Gabriele Paoloni
>>>>>> Cc: Wangzhou (B); Bjorn Helgaas; jingoohan1 at gmail.com; Pratyush
>>>> Anand;
>>>>>> Arnd Bergmann; linux at arm.linux.org.uk; thomas.petazzoni at free-
>>>>>> electrons.com; lorenzo.pieralisi at arm.com; james.morse at arm.com;
>>>>>> Liviu.Dudau at arm.com; jason at lakedaemon.net; robh at kernel.org;
>> linux-
>>>>>> pci at vger.kernel.org; linux-arm-kernel at lists.infradead.org;
>>>>>> devicetree at vger.kernel.org; Yuanzhichang; Zhudacai; zhangjukuo;
>>>>>> qiuzhenfa; liudongdong (C); qiujiang; xuwei (O); Liguozhu
>> (Kenneth)
>>>>>> Subject: Re: [PATCH v7 3/6] PCI: designware: Add ARM64 support
>>>>>>
>>>>>> Hi Gab,
>>>>>>
>>>>>> Am Mittwoch, den 19.08.2015, 15:16 +0000 schrieb Gabriele
>> Paoloni:
>>>>>>> Hi Lucas
>>>>>>>
>>>>>>> I have rewritten the patch to take into account multiple
>>>> controllers.
>>>>>>>
>>>>>>> As you can see now there is a static var in
>> dw_pcie_host_init()
>>>> that
>>>>>> tracks
>>>>>>> the bus numbers used.
>>>>>>
>>>>>> This is wrong. The DT specifies the valid bus number range. You
>> can
>>>> not
>>>>>> just assign the next free bus number to the root bus.
>>>>>
>>>>> I think this is what is being done in
>>>>> http://lxr.free-
>> electrons.com/source/arch/arm/kernel/bios32.c#L495
>>>>> and currently designware assigns the root bus number in
>>>>> http://lxr.free-electrons.com/source/drivers/pci/host/pcie-
>>>> designware.c#L730
>>>>>
>>>> You found the right spot. It works a bit different than I remember,
>> but
>>>> is less broken than your current code. :)
>>>>
>>>> It actually assigns the next instance a root bus number behind the
>>>> current instances bus range. Please note the difference to your
>> code
>>>> which assigns the next free bus number, which may still lay within
>> the
>>>> current instances bus range.
>>
>> Hi Gabriele,
>>
>>>
>>> Mmmm here I have done a mistake: in the current designware the number
>> of hw
>>> controllers is always 1
>>> http://lxr.free-electrons.com/source/drivers/pci/host/pcie-
>> designware.c#L510
>>> So the loop in bios32.c does not work on multiple PCIe ports...
>>
>> Bios32.c is broken for multiple PCIe hosts for multiple reasons, this
>> is just
>> one of them. Hence the effort to get rid of it for maintained drivers.
> 
> As you can see we're pushing hard for this :)
>

How about we pass pp->busn->start to pci_create_root_bus as root bus number?
We get pp->busn->start from resource list(res) whose elements come from
of_pci_get_host_bridge_resources.

If there is a bus-range item in dts, root bus number will get from it.
Oppositely, root bus number will be default value(0x0).

Thanks,
Zhou

>>
>>> However your comment about PCI_DOMAINS enlightened my mind and now I
>> see
>>> that when CONFIG_PCI_DOMAINS is defined we have the domains numbers
>>> (tracked by __domain_nr).
>>
>> CONFIG_PCI_DOMAINS in itself doesn't do much without adding code to
>> your driver.
>> You could request a new domain for each controller with a special
>> property to
>> disable that behaviour in the dts, or you could enable
>> CONFIG_PCI_DOMAINS_GENERIC
>> which will give you a new domain automatically.
> 
> So far I see that for ARM and ARM64 CONFIG_PCI_DOMAINS_GENERIC defaults to 
> the same value as CONFIG_PCI_DOMAINS (see arch/arm/Kconfig, arch/arm64/Kconfig). 
> So I think this is how current designware based drivers get multiple PCIe 
> controller to work (they just enable CONFIG_PCI_DOMAINS)...
> 
>  
> 
>>
>>> So (correct me if I am wrong) if we have 2 PCIe ports that do not
>> specify
>>> the "bus-range" property, both root ports will enumerate starting
>> from
>>> root_bus_nr = 0 and everything will still work ok.
>>
>> Correct.
>>
>> Best regards,
>> Liviu
>>
>>>
>>> So if my assumption is correct, I do not see why the orginal patch
>> from Wang
>>> Zhou is wrong.
>>> The only point can be that assigning pp->root_bus_nr = 0 is not
>> required
>>> as pp memory is kzalloc'ed (an therefore init to zero).
>>>
>>>
>>>>
>>>>>
>>>>> In general I agree with you but if you look at all the current
>>>> drivers
>>>>> based on designware none of them define the "bus-range" dtb
>> property.
>>>>> Therefore doing as you say would break the current driver when we
>>>> have
>>>>> multiple controllers...am I right?
>>>>>
>>>> The current _code_ works fine for multiple controllers. It's just
>> that
>>>> you must define the bus range property in the DTB if you want to
>> enable
>>>> multiple instances of one controller and support a kernel without
>> PCI
>>>> domains support. As all current implementations have only a single
>>>> instance of the controller per SoC, or depend on PCI domain support,
>>>> it's totally fine for them to not define the bus ranges property,
>> as
>>>> it's an optional property and it is well defined how things behave
>> if
>>>> it
>>>> is absent. We absolutely need to keep that specified behavior.
>>>>
>>>>> If that is the case in order to fix this in the way you say I
>> would
>>>> need
>>>>> to assign "bus-range" for all the PCIe drivers with multiple
>>>> controllers:
>>>>> in this case I would split the default range evenly (that is, if
>> we
>>>> have
>>>>> two controllers I would define "bus-range"  0-127 and 128-255)
>>>>>
>>>>> If you think this solution is ok I can go for it. My only doubt
>> was
>>>> about
>>>>> touching other vendors DTBs....
>>>>>
>>>> You don't need to touch any of the current DTBs, as they are fine
>> with
>>>> the default bus range behavior. You need to keep the specified
>> behavior
>>>> of the bus range property with the new code.
>>>>
>>>> Regards,
>>>> Lucas
>>>>>
>>>>>>
>>>>>> It is perfectly valid to have a bus range of 0x00-0x10 assigned
>> to
>>>> one
>>>>>> instance and 0x50-0xff to the next instance. Additional with
>> PCIe
>>>>>> hotplug you may not use the full range of the bus numbers on
>> one
>>>>>> instance at the first scan, but only later populate more buses
>> when
>>>>>> more
>>>>>> bridges are added to the tree.
>>>>>>
>>>>>>> Drivers that do not specify the bus range in the DTB set pp-
>>>>>>> root_bus_nr = DW_ROOT_NR_UNDEFINED.
>>>>>>> Designware will check if the flag is set and will use the
>>>> automatic
>>>>>> bus range
>>>>>>> assignment.
>>>>>>
>>>>>> No, please lets get rid of this assignment altogether. The glue
>>>> drivers
>>>>>> have no business in assigning the bus range. Please remove the
>>>>>> pp->root_bus_nr assignment from all the glue drivers.
>>>>>>
>>>>>> "bus range" is a generic DW PCIe property, so just parse the
>> root
>>>> bus
>>>>>> number from the DT, it is handled the same way for all the DW
>> based
>>>>>> PCIe
>>>>>> drivers. The bindings specifies that if the bus range property
>> is
>>>>>> missing the range is 0x00-0xff, so you can default to 0 as the
>> root
>>>> bus
>>>>>> number in that case.
>>>>>>
>>>>>> Also I would think this conversion warrants a patch on its own
>> and
>>>>>> should not be mixed in the ARM64 support patch.
>>>>>>
>>>>>> Regards,
>>>>>> Lucas
>>>>>>
>>>>
>>>> --
>>>> Pengutronix e.K.             | Lucas Stach                 |
>>>> Industrial Linux Solutions   | http://www.pengutronix.de/  |
>>>
>>
>> --
>> ====================
>> | I would like to |
>> | fix the world,  |
>> | but they're not |
>> | giving me the   |
>>  \ source code!  /
>>   ---------------
>>     ?\_(?)_/?
>>
>> --
>> To unsubscribe from this list: send the line "unsubscribe linux-pci" in
>> the body of a message to majordomo at vger.kernel.org
>> More majordomo info at  http://vger.kernel.org/majordomo-info.html




From michal.simek at xilinx.com  Sun Aug 23 23:42:27 2015
From: michal.simek at xilinx.com (Michal Simek)
Date: Mon, 24 Aug 2015 08:42:27 +0200
Subject: [PATCH] doc: dt: Add interrupt parent to Xilinx AXI DMA
 instantation example.
In-Reply-To: <1440174775-14470-1-git-send-email-moritz.fischer@ettus.com>
References: <1440174775-14470-1-git-send-email-moritz.fischer@ettus.com>
Message-ID: <55DABCD3.60806@xilinx.com>

On 08/21/2015 06:32 PM, Moritz Fischer wrote:
> This patch adds 'interrupt-parent' properties to the instantation example in
> the docs for the devicetree bindings of the Xilinx AXI DMA driver.
> 
> Signed-off-by: Moritz Fischer <moritz.fischer at ettus.com>
> ---
>  Documentation/devicetree/bindings/dma/xilinx/xilinx_dma.txt | 3 +++
>  1 file changed, 3 insertions(+)
> 
> diff --git a/Documentation/devicetree/bindings/dma/xilinx/xilinx_dma.txt b/Documentation/devicetree/bindings/dma/xilinx/xilinx_dma.txt
> index 2291c40..7c956e9 100644
> --- a/Documentation/devicetree/bindings/dma/xilinx/xilinx_dma.txt
> +++ b/Documentation/devicetree/bindings/dma/xilinx/xilinx_dma.txt
> @@ -19,6 +19,7 @@ Required child node properties:
>  - compatible: It should be either "xlnx,axi-dma-mm2s-channel" or
>  	"xlnx,axi-dma-s2mm-channel".
>  - interrupts: Should contain per channel DMA interrupts.
> +- interrupt-parent: Should contain interrupt parent.
>  - xlnx,datawidth: Should contain the stream data width, take values
>  	{32,64...1024}.
>  
> @@ -36,11 +37,13 @@ axi_dma_0: axidma at 40400000 {
>  	dma-channel at 40400000 {
>  		compatible = "xlnx,axi-dma-mm2s-channel";
>  		interrupts = < 0 59 4 >;
> +		interrupt-parent = <&intc>;
>  		xlnx,datawidth = <0x40>;
>  	} ;
>  	dma-channel at 40400030 {
>  		compatible = "xlnx,axi-dma-s2mm-channel";
>  		interrupts = < 0 58 4 >;
> +		interrupt-parent = <&intc>;
>  		xlnx,datawidth = <0x40>;
>  	} ;
>  } ;
> 

Acked-by: Michal Simek <michal.simek at xilinx.com>

Thanks,
Michal


From vaibhav.hiremath at linaro.org  Sun Aug 23 23:43:34 2015
From: vaibhav.hiremath at linaro.org (Vaibhav Hiremath)
Date: Mon, 24 Aug 2015 12:13:34 +0530
Subject: [PATCH-v6 0/6] mfd: 88pm800: Add Device tree support
In-Reply-To: <55A40A32.8060901@linaro.org>
References: <1436358392-15449-1-git-send-email-vaibhav.hiremath@linaro.org>
 <55A40A32.8060901@linaro.org>
Message-ID: <55DABD16.8080309@linaro.org>



On Tuesday 14 July 2015 12:27 AM, Vaibhav Hiremath wrote:
>
>
> On Wednesday 08 July 2015 05:56 PM, Vaibhav Hiremath wrote:
>> This patch-series adds support for Device tree to 88PM800 mfd driver.
>> It also sets default configuration of irq clear method if board file
>> doesn't exist.
>>
>> Testing::
>>   - Boot tested on PXA1928 based platform.
>>   - probe of mfd, rtc and regulator function passing successfully.
>>   - Basic read operations on registers
>>   - irq clear configuration
>>
>> V5 => V6
>> =======
>
> I hope this will be queued for 4.2
>


Lee,

This patch-series is pending since long time, reviewed and acked.
Request to queue it up for next merge window.

Thanks,
Vaibhav


From lee.jones at linaro.org  Sun Aug 23 23:53:56 2015
From: lee.jones at linaro.org (Lee Jones)
Date: Mon, 24 Aug 2015 07:53:56 +0100
Subject: [PATCH v2 09/21] ARM: pxa: magician: Add OV9640 camera support
In-Reply-To: <1634812.ZDaECJ9ClW@wuerfel>
References: <cover.1439843482.git.petr.cvek@tul.cz>
 <2889798.x6xcIzdYMU@wuerfel> <55D65722.9030508@tul.cz>
 <1634812.ZDaECJ9ClW@wuerfel>
Message-ID: <20150824065356.GA3247@x1>

On Fri, 21 Aug 2015, Arnd Bergmann wrote:

> On Friday 21 August 2015 00:39:30 Petr Cvek wrote:
> > Dne 20.8.2015 v 22:26 Arnd Bergmann napsal(a):
> > > On Thursday 20 August 2015 21:48:20 Robert Jarzmik wrote:
> > >> Petr Cvek <petr.cvek at tul.cz> writes:
> > >>
> > >>> +     mdelay(3);
> > >> Okay, there are several mdelay(3) in this file.
> > >>
> > >> Could you please test if removing these mdelays prevents the camera from working
> > >> ? If not, I'd like to have them removed.
> > >>
> > >>
> > > 
> > > FWIW, it might be possible to replace some of them with msleep() calls,
> > > potentially after replacing spinlocks with mutexes where necessary.
> > > 
> > >       Arnd
> > > 
> > 
> > Datasheet says:
> > 
> >         tS:RESET        Setting time after software/hardware reset      1 ms
> > 
> > So at least one ~1 ms should be left there. Are msleep less than 20ms valid? 
> > 
> > (checkpatch: msleep < 20ms  can sleep for up to 20ms)
> 
> On most kernels, an msleep(1) will sleep somewhere between 1 and 3 milliseconds
> (but could be much longer), while an mdelay(1) tries to sleep around one
> millisecond, more or less.

If high-res timers are available I'd suggest using usleep_range()
instead.  By providing suitably divergent values usleep_range
de-restricts the kernel, allowing the scheduler to bundle your
wake-up along with others.

-- 
Lee Jones
Linaro STMicroelectronics Landing Team Lead
Linaro.org ? Open source software for ARM SoCs
Follow Linaro: Facebook | Twitter | Blog


From vaibhav.hiremath at linaro.org  Mon Aug 24 00:02:17 2015
From: vaibhav.hiremath at linaro.org (Vaibhav Hiremath)
Date: Mon, 24 Aug 2015 12:32:17 +0530
Subject: [PATCH-v3] mfd: 88pm80x: Add 88pm860 chip type support
In-Reply-To: <1437393151-5362-1-git-send-email-vaibhav.hiremath@linaro.org>
References: <1437393151-5362-1-git-send-email-vaibhav.hiremath@linaro.org>
Message-ID: <55DAC179.2060802@linaro.org>



On Monday 20 July 2015 05:22 PM, Vaibhav Hiremath wrote:
> Add chip identification support for 88PM860 device
> to the pm80x_chip_mapping table.
>
> Signed-off-by: Vaibhav Hiremath <vaibhav.hiremath at linaro.org>
> Reviewed-by: Krzysztof Kozlowski <k.kozlowski at samsung.com>
> ---
>   drivers/mfd/88pm80x.c       | 2 ++
>   include/linux/mfd/88pm80x.h | 1 +
>   2 files changed, 3 insertions(+)
>

Mark,

Last update/understanding which I have on this patch is,

Lee is OK with taking this patch from regulator tree.
Lee please let me know if you think otherwise.

With this patch in, the build dependency will go away.

Request to pick this patch into your topic/88pm800 branch and run build
test.

Thanks,
Vaibhav


From k.kozlowski at samsung.com  Mon Aug 24 00:17:18 2015
From: k.kozlowski at samsung.com (Krzysztof Kozlowski)
Date: Mon, 24 Aug 2015 16:17:18 +0900
Subject: [PATCH 07/18] ARM: EXYNOS: use const and __initconst for
 smp_operations
In-Reply-To: <1440390978-22796-8-git-send-email-yamada.masahiro@socionext.com>
References: <1440390978-22796-1-git-send-email-yamada.masahiro@socionext.com>
 <1440390978-22796-8-git-send-email-yamada.masahiro@socionext.com>
Message-ID: <55DAC4FE.9090305@samsung.com>

On 24.08.2015 13:36, Masahiro Yamada wrote:
> The smp_operations structure is not over-written, so add const
> qualifier and replace __initdata with __initconst.
> 
> Signed-off-by: Masahiro Yamada <yamada.masahiro at socionext.com>
> ---
> 
>  arch/arm/mach-exynos/common.h  | 2 +-
>  arch/arm/mach-exynos/platsmp.c | 2 +-
>  2 files changed, 2 insertions(+), 2 deletions(-)

Acked-by: Krzysztof Kozlowski <k.kozlowski at samsung.com>

Best regards,
Krzysztof



From maxime.ripard at free-electrons.com  Mon Aug 24 00:18:00 2015
From: maxime.ripard at free-electrons.com (maxime.ripard at free-electrons.com)
Date: Mon, 24 Aug 2015 09:18:00 +0200
Subject: [linux-sunxi][PATCH] ARM: sun7i: dt: Add new Olimex A20 EVB device
In-Reply-To: <CAEKpxBnQ+kCVYfE8JL5JzH5ZXb3azjwmjfAE5OXULaVm0bj2ew@mail.gmail.com>
References: <1440002596-2611-1-git-send-email-codekipper@gmail.com>
 <20150820154545.GF30520@lukather>
 <CAEKpxBnQ+kCVYfE8JL5JzH5ZXb3azjwmjfAE5OXULaVm0bj2ew@mail.gmail.com>
Message-ID: <20150824071800.GE2413@lukather>

On Fri, Aug 21, 2015 at 07:36:01AM +0200, Code Kipper wrote:
> On 20 August 2015 at 17:45, Maxime Ripard <maxime.ripard at free-electrons.com>
> wrote:
> 
> > Hi,
> >
> > On Wed, Aug 19, 2015 at 06:43:16PM +0200, codekipper at gmail.com wrote:
> > > From: Marcus Cooper <codekipper at gmail.com>
> > >
> > > The A20-SOM-EVB is a reference design of a 2-layer board for the
> > > A20-SOM.
> > > It expands the features of A20-SOM by adding VGA connector, HDMI
> > > connector, audio In/Out, LCD connector, 2 Mpix camera, gigabit
> > > Ethernet, SATA, USB-OTG and 2 USB hosts.
> > >
> > > This patch adds basic support for the device
> > > https://www.olimex.com/Products/SOM/A20/A20-SOM-EVB/
> > >
> > > More information on the SOM can be found here
> > > http://linux-sunxi.org/Olimex_A20-SOM.
> > >
> > > Signed-off-by: Marcus Cooper <codekipper at gmail.com>
> >
> > Is there any other SOM planned that could work with that baseboard? Or
> > any other baseboard for that SOM?
>
> I've seen neither. We could always create a som.dtsi later is one emerges.

Yep. The real pain would be if there's several SOM and several
base-boards that are created.

> > > ---
> > >  arch/arm/boot/dts/Makefile                    |   1 +
> > >  arch/arm/boot/dts/sun7i-a20-olinuxino-evb.dts | 233
> > ++++++++++++++++++++++++++
> > >  2 files changed, 234 insertions(+)
> > >  create mode 100644 arch/arm/boot/dts/sun7i-a20-olinuxino-evb.dts
> >
> Relooking at their website I can see that the device does not come under
> the olinuxino brand so maybe I should rename the dts to
> sun7i-a20-olimex-som-evb.dts

Looks good for me.

> 
> > >
> > > diff --git a/arch/arm/boot/dts/Makefile b/arch/arm/boot/dts/Makefile
> > > index 6d7cec1..fdbda9b 100644
> > > --- a/arch/arm/boot/dts/Makefile
> > > +++ b/arch/arm/boot/dts/Makefile
> > > @@ -613,6 +613,7 @@ dtb-$(CONFIG_MACH_SUN7I) += \
> > >       sun7i-a20-olinuxino-lime.dtb \
> > >       sun7i-a20-olinuxino-lime2.dtb \
> > >       sun7i-a20-olinuxino-micro.dtb \
> > > +     sun7i-a20-olinuxino-evb.dtb \
> > >       sun7i-a20-orangepi.dtb \
> > >       sun7i-a20-orangepi-mini.dtb \
> > >       sun7i-a20-pcduino3.dtb \
> > > diff --git a/arch/arm/boot/dts/sun7i-a20-olinuxino-evb.dts
> > b/arch/arm/boot/dts/sun7i-a20-olinuxino-evb.dts
> > > new file mode 100644
> > > index 0000000..a0071fa
> > > --- /dev/null
> > > +++ b/arch/arm/boot/dts/sun7i-a20-olinuxino-evb.dts
> > > @@ -0,0 +1,233 @@
> > > +/*
> > > + * Copyright 2015 - Marcus Cooper <codekipper at gmail.com>
> > > + *
> > > + * This file is dual-licensed: you can use it either under the terms
> > > + * of the GPL or the X11 license, at your option. Note that this dual
> > > + * licensing only applies to this file, and not this project as a
> > > + * whole.
> > > + *
> > > + *  a) This file is free software; you can redistribute it and/or
> > > + *     modify it under the terms of the GNU General Public License as
> > > + *     published by the Free Software Foundation; either version 2 of
> > the
> > > + *     License, or (at your option) any later version.
> > > + *
> > > + *     This file is distributed in the hope that it will be useful,
> > > + *     but WITHOUT ANY WARRANTY; without even the implied warranty of
> > > + *     MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
> > > + *     GNU General Public License for more details.
> > > + *
> > > + * Or, alternatively,
> > > + *
> > > + *  b) Permission is hereby granted, free of charge, to any person
> > > + *     obtaining a copy of this software and associated documentation
> > > + *     files (the "Software"), to deal in the Software without
> > > + *     restriction, including without limitation the rights to use,
> > > + *     copy, modify, merge, publish, distribute, sublicense, and/or
> > > + *     sell copies of the Software, and to permit persons to whom the
> > > + *     Software is furnished to do so, subject to the following
> > > + *     conditions:
> > > + *
> > > + *     The above copyright notice and this permission notice shall be
> > > + *     included in all copies or substantial portions of the Software.
> > > + *
> > > + *     THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
> > > + *     EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES
> > > + *     OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
> > > + *     NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT
> > > + *     HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY,
> > > + *     WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
> > > + *     FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR
> > > + *     OTHER DEALINGS IN THE SOFTWARE.
> > > + */
> > > +
> > > +/dts-v1/;
> > > +#include "sun7i-a20.dtsi"
> > > +#include "sunxi-common-regulators.dtsi"
> > > +
> > > +#include <dt-bindings/gpio/gpio.h>
> > > +#include <dt-bindings/interrupt-controller/irq.h>
> > > +#include <dt-bindings/pinctrl/sun4i-a10.h>
> > > +
> > > +/ {
> > > +     model = "Olimex A20-OLinuXino-EVB";
> > > +     compatible = "olimex,a20-olinuxino-evb", "allwinner,sun7i-a20";
> > > +
> > > +     aliases {
> > > +             serial0 = &uart0;
> > > +     };
> > > +
> > > +     chosen {
> > > +             stdout-path = "serial0:115200n8";
> > > +     };
> > > +
> > > +     leds {
> > > +             compatible = "gpio-leds";
> > > +             pinctrl-names = "default";
> > > +             pinctrl-0 = <&led_pins_olinuxinoevb>;
> > > +
> > > +             green {
> > > +                     label = "a20-olinuxino-evb:green:usr";
> > > +                     gpios = <&pio 7 2 GPIO_ACTIVE_HIGH>;
> > > +                     default-state = "on";
> > > +             };
> > > +     };
> > > +
> > > +     reg_axp_ipsout: axp_ipsout {
> > > +             compatible = "regulator-fixed";
> > > +             regulator-name = "axp-ipsout";
> > > +             regulator-min-microvolt = <5000000>;
> > > +             regulator-max-microvolt = <5000000>;
> > > +             regulator-always-on;
> > > +     };
> > > +};
> > > +
> > > +&ahci {
> > > +     target-supply = <&reg_ahci_5v>;
> > > +     status = "okay";
> > > +};
> > > +
> > > +&ehci0 {
> > > +     status = "okay";
> > > +};
> > > +
> > > +&ehci1 {
> > > +     status = "okay";
> > > +};
> > > +
> > > +&gmac {
> > > +     pinctrl-names = "default";
> > > +     pinctrl-0 = <&gmac_pins_rgmii_a>;
> > > +     phy = <&phy1>;
> > > +     phy-mode = "rgmii";
> > > +     status = "okay";
> > > +
> > > +     phy1: ethernet-phy at 1 {
> > > +             reg = <1>;
> > > +     };
> > > +};
> > > +
> > > +&i2c0 {
> > > +     pinctrl-names = "default";
> > > +     pinctrl-0 = <&i2c0_pins_a>;
> > > +     status = "okay";
> > > +
> > > +     axp209: pmic at 34 {
> > > +             compatible = "x-powers,axp209";
> > > +             reg = <0x34>;
> > > +             interrupt-parent = <&nmi_intc>;
> > > +             interrupts = <0 IRQ_TYPE_LEVEL_LOW>;
> > > +
> > > +             interrupt-controller;
> > > +             #interrupt-cells = <1>;
> > > +
> > > +             acin-supply = <&reg_axp_ipsout>;
> > > +             vin2-supply = <&reg_axp_ipsout>;
> > > +             vin3-supply = <&reg_axp_ipsout>;
> > > +             ldo24in-supply = <&reg_axp_ipsout>;
> > > +             ldo3in-supply = <&reg_axp_ipsout>;
> >
> > Please use the axp209 dtsi.
> >
> Will do
> 
> >
> > > +
> > > +             regulators {
> > > +                     vdd_rtc: ldo1 {
> > > +                             regulator-min-microvolt = <1300000>;
> > > +                             regulator-max-microvolt = <1300000>;
> > > +                             regulator-always-on;
> > > +                     };
> > > +
> > > +                     avcc: ldo2 {
> > > +                             regulator-min-microvolt = <1800000>;
> > > +                             regulator-max-microvolt = <3300000>;
> > > +                             regulator-always-on;
> > > +                     };
> > > +
> > > +                     vcc_csi0: ldo3 {
> > > +                             regulator-min-microvolt = <700000>;
> > > +                             regulator-max-microvolt = <3500000>;
> > > +                             regulator-always-on;
> > > +                     };
> > > +
> > > +                     vcc_csi1: ldo4 {
> > > +                             regulator-min-microvolt = <1250000>;
> > > +                             regulator-max-microvolt = <3300000>;
> > > +                             regulator-always-on;
> > > +                     };
> >
> > the csi regulators are always-on too? What function do they provide?
> >
> This was a c & p from the lime 2 dts as their fex files are very similar. I
> can remove this for now.

Please do. And if it does make the board unstable, then it's probably
not the CSI regulator.

> > > +                     vdd_cpu: dcdc2 {
> > > +                             regulator-min-microvolt = <700000>;
> > > +                             regulator-max-microvolt = <2275000>;
> >
> > This is way outside of the CPU operating range. Are you sure of your
> > constraints?
>
> ditto. I will check on this.

Remember, constraints are not the boundaries of what the PMIC can
provide, but what the components on the other end can accept.

Maxime

-- 
Maxime Ripard, Free Electrons
Embedded Linux, Kernel and Android engineering
http://free-electrons.com
-------------- next part --------------
A non-text attachment was scrubbed...
Name: signature.asc
Type: application/pgp-signature
Size: 819 bytes
Desc: Digital signature
URL: <http://lists.infradead.org/pipermail/linux-arm-kernel/attachments/20150824/fb181a7a/attachment-0001.sig>

From peter.ujfalusi at ti.com  Mon Aug 24 00:19:56 2015
From: peter.ujfalusi at ti.com (Peter Ujfalusi)
Date: Mon, 24 Aug 2015 10:19:56 +0300
Subject: [PATCH 00/11] ARM: OMAP/DTS: dra7/72-evm/beagle-x15: Audio support
Message-ID: <1440400807-32274-1-git-send-email-peter.ujfalusi@ti.com>

Hi,

this series will enable analog audio (via onboard aic310x codec) for dra7-evm,
dra72-evm and am57xx-beagle-x15 boards.
In these board McASP3 is connected to the codec and for the McASP3 we needed to
have the DMA crossbar in place since the request lines are not mapped by
default.

Regars,
Peter
---
Peter Ujfalusi (11):
  ARM: OMAP: DRA7: hwmod: Add data for McASP3
  ARM: DTS: dra7: Add McASP3 node
  ARM: DTS: dra7-evm: Rename mmc2_3v3 supply to evm_3v3_sw
  ARM: DTS: dra7-evm: Add fixed regulator to be used by aic3106's DVDD
  ARM: DTS: dra7-evm: Enable pcf8575 (0x26 address) on i2c2 bus
  ARM: DTS: dra7-evm: Audio support
  ARM: DTS: dra72-evm: Add fixed regulator representing DVDD supply for
    aic3106
  ARM: DTS: dra72-evm: Add gpio hog for vin6_sel_s0 to select audio
  ARM: DTS: dra72-evm: Audio support
  ARM: DTS: am57xx-beagle-x15: Add fixed regulator for aic3104's DVDD
  ARM: DTS: am57xx-beagle-x15: Enable analog audio support

 arch/arm/boot/dts/am57xx-beagle-x15.dts   |  95 ++++++++++++++++++++
 arch/arm/boot/dts/dra7-evm.dts            | 142 +++++++++++++++++++++++++++++-
 arch/arm/boot/dts/dra7.dtsi               |  15 ++++
 arch/arm/boot/dts/dra72-evm.dts           | 138 +++++++++++++++++++++++++++++
 arch/arm/mach-omap2/omap_hwmod_7xx_data.c |  41 +++++++++
 5 files changed, 428 insertions(+), 3 deletions(-)

-- 
2.5.0



From peter.ujfalusi at ti.com  Mon Aug 24 00:19:59 2015
From: peter.ujfalusi at ti.com (Peter Ujfalusi)
Date: Mon, 24 Aug 2015 10:19:59 +0300
Subject: [PATCH 03/11] ARM: DTS: dra7-evm: Rename mmc2_3v3 supply to evm_3v3_sw
In-Reply-To: <1440400807-32274-1-git-send-email-peter.ujfalusi@ti.com>
References: <1440400807-32274-1-git-send-email-peter.ujfalusi@ti.com>
Message-ID: <1440400807-32274-4-git-send-email-peter.ujfalusi@ti.com>

Use the name for the supply as it is in the schematics since the same
supply is used for other peripherals than MMC2, like audio.

Signed-off-by: Peter Ujfalusi <peter.ujfalusi at ti.com>
---
 arch/arm/boot/dts/dra7-evm.dts | 6 +++---
 1 file changed, 3 insertions(+), 3 deletions(-)

diff --git a/arch/arm/boot/dts/dra7-evm.dts b/arch/arm/boot/dts/dra7-evm.dts
index a6c82e5b64fe..de02cf5853a9 100644
--- a/arch/arm/boot/dts/dra7-evm.dts
+++ b/arch/arm/boot/dts/dra7-evm.dts
@@ -28,9 +28,9 @@
 		gpio = <&pcf_gpio_21 5 GPIO_ACTIVE_HIGH>;
 	};
 
-	mmc2_3v3: fixedregulator-mmc2 {
+	evm_3v3_sw: fixedregulator-evm_3v3_sw {
 		compatible = "regulator-fixed";
-		regulator-name = "mmc2_3v3";
+		regulator-name = "evm_3v3_sw";
 		regulator-min-microvolt = <3300000>;
 		regulator-max-microvolt = <3300000>;
 	};
@@ -484,7 +484,7 @@
 
 &mmc2 {
 	status = "okay";
-	vmmc-supply = <&mmc2_3v3>;
+	vmmc-supply = <&evm_3v3_sw>;
 	bus-width = <8>;
 };
 
-- 
2.5.0



From peter.ujfalusi at ti.com  Mon Aug 24 00:19:57 2015
From: peter.ujfalusi at ti.com (Peter Ujfalusi)
Date: Mon, 24 Aug 2015 10:19:57 +0300
Subject: [PATCH 01/11] ARM: OMAP: DRA7: hwmod: Add data for McASP3
In-Reply-To: <1440400807-32274-1-git-send-email-peter.ujfalusi@ti.com>
References: <1440400807-32274-1-git-send-email-peter.ujfalusi@ti.com>
Message-ID: <1440400807-32274-2-git-send-email-peter.ujfalusi@ti.com>

McASP3 is used by default on DRA7x based boards for audio.

Signed-off-by: Peter Ujfalusi <peter.ujfalusi at ti.com>
---
 arch/arm/mach-omap2/omap_hwmod_7xx_data.c | 41 +++++++++++++++++++++++++++++++
 1 file changed, 41 insertions(+)

diff --git a/arch/arm/mach-omap2/omap_hwmod_7xx_data.c b/arch/arm/mach-omap2/omap_hwmod_7xx_data.c
index 562247bced49..c38b7fa30c27 100644
--- a/arch/arm/mach-omap2/omap_hwmod_7xx_data.c
+++ b/arch/arm/mach-omap2/omap_hwmod_7xx_data.c
@@ -1298,6 +1298,38 @@ static struct omap_hwmod dra7xx_mcspi4_hwmod = {
 };
 
 /*
+ * 'mcasp' class
+ *
+ */
+static struct omap_hwmod_class_sysconfig dra7xx_mcasp_sysc = {
+	.sysc_offs	= 0x0004,
+	.sysc_flags	= SYSC_HAS_SIDLEMODE,
+	.idlemodes	= (SIDLE_FORCE | SIDLE_NO | SIDLE_SMART),
+	.sysc_fields	= &omap_hwmod_sysc_type3,
+};
+
+static struct omap_hwmod_class dra7xx_mcasp_hwmod_class = {
+	.name	= "mcasp",
+	.sysc	= &dra7xx_mcasp_sysc,
+};
+
+/* mcasp3 */
+static struct omap_hwmod dra7xx_mcasp3_hwmod = {
+	.name		= "mcasp3",
+	.class		= &dra7xx_mcasp_hwmod_class,
+	.clkdm_name	= "l4per2_clkdm",
+	.main_clk	= "mcasp3_ahclkx_mux",
+	.flags		= HWMOD_SWSUP_SIDLE,
+	.prcm = {
+		.omap4 = {
+			.clkctrl_offs = DRA7XX_CM_L4PER2_MCASP3_CLKCTRL_OFFSET,
+			.context_offs = DRA7XX_RM_L4PER2_MCASP3_CONTEXT_OFFSET,
+			.modulemode   = MODULEMODE_SWCTRL,
+		},
+	},
+};
+
+/*
  * 'mmc' class
  *
  */
@@ -2566,6 +2598,14 @@ static struct omap_hwmod_ocp_if dra7xx_l3_main_1__hdmi = {
 	.user		= OCP_USER_MPU | OCP_USER_SDMA,
 };
 
+/* l4_per2 -> mcasp3 */
+static struct omap_hwmod_ocp_if dra7xx_l4_per2__mcasp3 = {
+	.master		= &dra7xx_l4_per2_hwmod,
+	.slave		= &dra7xx_mcasp3_hwmod,
+	.clk		= "l3_iclk_div",
+	.user		= OCP_USER_MPU | OCP_USER_SDMA,
+};
+
 static struct omap_hwmod_addr_space dra7xx_elm_addrs[] = {
 	{
 		.pa_start	= 0x48078000,
@@ -3338,6 +3378,7 @@ static struct omap_hwmod_ocp_if *dra7xx_hwmod_ocp_ifs[] __initdata = {
 	&dra7xx_l4_wkup__dcan1,
 	&dra7xx_l4_per2__dcan2,
 	&dra7xx_l4_per2__cpgmac0,
+	&dra7xx_l4_per2__mcasp3,
 	&dra7xx_gmac__mdio,
 	&dra7xx_l4_cfg__dma_system,
 	&dra7xx_l3_main_1__dss,
-- 
2.5.0



From peter.ujfalusi at ti.com  Mon Aug 24 00:20:00 2015
From: peter.ujfalusi at ti.com (Peter Ujfalusi)
Date: Mon, 24 Aug 2015 10:20:00 +0300
Subject: [PATCH 04/11] ARM: DTS: dra7-evm: Add fixed regulator to be used by
 aic3106's DVDD
In-Reply-To: <1440400807-32274-1-git-send-email-peter.ujfalusi@ti.com>
References: <1440400807-32274-1-git-send-email-peter.ujfalusi@ti.com>
Message-ID: <1440400807-32274-5-git-send-email-peter.ujfalusi@ti.com>

TPS77018DBVT is used to create 1.8V from avm_3v3_sw's 3.3V connected to
aic3106's DVDD.

Signed-off-by: Peter Ujfalusi <peter.ujfalusi at ti.com>
---
 arch/arm/boot/dts/dra7-evm.dts | 9 +++++++++
 1 file changed, 9 insertions(+)

diff --git a/arch/arm/boot/dts/dra7-evm.dts b/arch/arm/boot/dts/dra7-evm.dts
index de02cf5853a9..add77ac4f302 100644
--- a/arch/arm/boot/dts/dra7-evm.dts
+++ b/arch/arm/boot/dts/dra7-evm.dts
@@ -35,6 +35,15 @@
 		regulator-max-microvolt = <3300000>;
 	};
 
+	aic_dvdd: fixedregulator-aic_dvdd {
+		/* TPS77018DBVT */
+		compatible = "regulator-fixed";
+		regulator-name = "aic_dvdd";
+		vin-supply = <&evm_3v3_sw>;
+		regulator-min-microvolt = <1800000>;
+		regulator-max-microvolt = <1800000>;
+	};
+
 	extcon_usb1: extcon_usb1 {
 		compatible = "linux,extcon-usb-gpio";
 		id-gpio = <&pcf_gpio_21 1 GPIO_ACTIVE_HIGH>;
-- 
2.5.0



From peter.ujfalusi at ti.com  Mon Aug 24 00:19:58 2015
From: peter.ujfalusi at ti.com (Peter Ujfalusi)
Date: Mon, 24 Aug 2015 10:19:58 +0300
Subject: [PATCH 02/11] ARM: DTS: dra7: Add McASP3 node
In-Reply-To: <1440400807-32274-1-git-send-email-peter.ujfalusi@ti.com>
References: <1440400807-32274-1-git-send-email-peter.ujfalusi@ti.com>
Message-ID: <1440400807-32274-3-git-send-email-peter.ujfalusi@ti.com>

Signed-off-by: Peter Ujfalusi <peter.ujfalusi at ti.com>
---
 arch/arm/boot/dts/dra7.dtsi | 15 +++++++++++++++
 1 file changed, 15 insertions(+)

diff --git a/arch/arm/boot/dts/dra7.dtsi b/arch/arm/boot/dts/dra7.dtsi
index 5d65db9ebc2b..07fa4ea5521a 100644
--- a/arch/arm/boot/dts/dra7.dtsi
+++ b/arch/arm/boot/dts/dra7.dtsi
@@ -1403,6 +1403,21 @@
 			status = "disabled";
 		};
 
+		mcasp3: mcasp at 48468000 {
+			compatible = "ti,dra7-mcasp-audio";
+			ti,hwmods = "mcasp3";
+			reg = <0x48468000 0x2000>;
+			reg-names = "mpu";
+			interrupts = <GIC_SPI 151 IRQ_TYPE_LEVEL_HIGH>,
+				     <GIC_SPI 150 IRQ_TYPE_LEVEL_HIGH>;
+			interrupt-names = "tx", "rx";
+			dmas = <&sdma_xbar 133>, <&sdma_xbar 132>;
+			dma-names = "tx", "rx";
+			clocks = <&mcasp3_ahclkx_mux>;
+			clock-names = "fck";
+			status = "disabled";
+		};
+
 		crossbar_mpu: crossbar at 4a002a48 {
 			compatible = "ti,irq-crossbar";
 			reg = <0x4a002a48 0x130>;
-- 
2.5.0



From peter.ujfalusi at ti.com  Mon Aug 24 00:20:01 2015
From: peter.ujfalusi at ti.com (Peter Ujfalusi)
Date: Mon, 24 Aug 2015 10:20:01 +0300
Subject: [PATCH 05/11] ARM: DTS: dra7-evm: Enable pcf8575 (0x26 address) on
 i2c2 bus
In-Reply-To: <1440400807-32274-1-git-send-email-peter.ujfalusi@ti.com>
References: <1440400807-32274-1-git-send-email-peter.ujfalusi@ti.com>
Message-ID: <1440400807-32274-6-git-send-email-peter.ujfalusi@ti.com>

This GPIO expander is used for controlling various muxes on the board.
By default select audio functionality over VIN6 by setting the P1
(vin6_sel_s0) pin to low.

Signed-off-by: Peter Ujfalusi <peter.ujfalusi at ti.com>
---
 arch/arm/boot/dts/dra7-evm.dts | 14 ++++++++++++++
 1 file changed, 14 insertions(+)

diff --git a/arch/arm/boot/dts/dra7-evm.dts b/arch/arm/boot/dts/dra7-evm.dts
index add77ac4f302..3694046c29eb 100644
--- a/arch/arm/boot/dts/dra7-evm.dts
+++ b/arch/arm/boot/dts/dra7-evm.dts
@@ -438,6 +438,20 @@
 	pinctrl-names = "default";
 	pinctrl-0 = <&i2c2_pins>;
 	clock-frequency = <400000>;
+
+	pcf_hdmi: gpio at 26 {
+		compatible = "nxp,pcf8575";
+		reg = <0x26>;
+		gpio-controller;
+		#gpio-cells = <2>;
+		p1 {
+			/* vin6_sel_s0: high: VIN6, low: audio */
+			gpio-hog;
+			gpios = <1 GPIO_ACTIVE_HIGH>;
+			output-low;
+			line-name = "vin6_sel_s0";
+		};
+	};
 };
 
 &i2c3 {
-- 
2.5.0



From peter.ujfalusi at ti.com  Mon Aug 24 00:20:05 2015
From: peter.ujfalusi at ti.com (Peter Ujfalusi)
Date: Mon, 24 Aug 2015 10:20:05 +0300
Subject: [PATCH 09/11] ARM: DTS: dra72-evm: Audio support
In-Reply-To: <1440400807-32274-1-git-send-email-peter.ujfalusi@ti.com>
References: <1440400807-32274-1-git-send-email-peter.ujfalusi@ti.com>
Message-ID: <1440400807-32274-10-git-send-email-peter.ujfalusi@ti.com>

The board uses tlv320aic3106 codec connected to McASP3. The master clock
for the codec and McASP3 is coming from ATL2.
McASP3 is the master on the I2S bus.

Signed-off-by: Peter Ujfalusi <peter.ujfalusi at ti.com>
---
 arch/arm/boot/dts/dra72-evm.dts | 114 ++++++++++++++++++++++++++++++++++++++++
 1 file changed, 114 insertions(+)

diff --git a/arch/arm/boot/dts/dra72-evm.dts b/arch/arm/boot/dts/dra72-evm.dts
index 33be5c64bda3..249000d50090 100644
--- a/arch/arm/boot/dts/dra72-evm.dts
+++ b/arch/arm/boot/dts/dra72-evm.dts
@@ -9,6 +9,7 @@
 
 #include "dra72x.dtsi"
 #include <dt-bindings/gpio/gpio.h>
+#include <dt-bindings/clk/ti-dra7-atl.h>
 
 / {
 	model = "TI DRA722";
@@ -102,6 +103,40 @@
 			};
 		};
 	};
+
+	sound0: sound at 0 {
+		compatible = "simple-audio-card";
+		simple-audio-card,name = "DRA7xx-EVM";
+		simple-audio-card,widgets =
+			"Headphone", "Headphone Jack",
+			"Line", "Line Out",
+			"Microphone", "Mic Jack",
+			"Line", "Line In";
+		simple-audio-card,routing =
+			"Headphone Jack",       "HPLOUT",
+			"Headphone Jack",       "HPROUT",
+			"Line Out",		"LLOUT",
+			"Line Out",		"RLOUT",
+			"MIC3L",		"Mic Jack",
+			"MIC3R",		"Mic Jack",
+			"Mic Jack",		"Mic Bias",
+			"LINE1L",               "Line In",
+			"LINE1R",               "Line In";
+		simple-audio-card,format = "dsp_b";
+		simple-audio-card,bitclock-master = <&sound0_master>;
+		simple-audio-card,frame-master = <&sound0_master>;
+		simple-audio-card,bitclock-inversion;
+
+		sound0_master: simple-audio-card,cpu {
+			sound-dai = <&mcasp3>;
+			system-clock-frequency = <5644800>;
+		};
+
+		simple-audio-card,codec {
+			sound-dai = <&tlv320aic3106>;
+			clocks = <&atl_clkin2_ck>;
+		};
+	};
 };
 
 &dra7_pmx_core {
@@ -236,6 +271,31 @@
 			0x3b8 (PIN_INPUT_PULLDOWN | MUX_MODE14) /* gpio7_12 HPD */
 		>;
 	};
+
+	atl_pins: pinmux_atl_pins {
+		pinctrl-single,pins = <
+			0x298 (PIN_OUTPUT | MUX_MODE5)	/* xref_clk1.atl_clk1 */
+			0x29c (PIN_OUTPUT | MUX_MODE5)	/* xref_clk2.atl_clk2 */
+		>;
+	};
+
+	mcasp3_pins: pinmux_mcasp3_pins {
+		pinctrl-single,pins = <
+			0x324 (PIN_OUTPUT_PULLDOWN | MUX_MODE0)	/* mcasp3_aclkx */
+			0x328 (PIN_OUTPUT_PULLDOWN | MUX_MODE0)	/* mcasp3_fsx */
+			0x32c (PIN_OUTPUT_PULLDOWN | MUX_MODE0)	/* mcasp3_axr0 */
+			0x330 (PIN_INPUT_PULLDOWN | MUX_MODE0)	/* mcasp3_axr1 */
+		>;
+	};
+
+	mcasp3_sleep_pins: pinmux_mcasp3_sleep_pins {
+		pinctrl-single,pins = <
+			0x324 (PIN_INPUT_PULLDOWN | MUX_MODE15)
+			0x328 (PIN_INPUT_PULLDOWN | MUX_MODE15)
+			0x32c (PIN_INPUT_PULLDOWN | MUX_MODE15)
+			0x330 (PIN_INPUT_PULLDOWN | MUX_MODE15)
+		>;
+	};
 };
 
 &i2c1 {
@@ -376,6 +436,21 @@
 			output-low;
 		};
 	};
+
+	tlv320aic3106: tlv320aic3106 at 19 {
+		#sound-dai-cells = <0>;
+		compatible = "ti,tlv320aic3106";
+		reg = <0x19>;
+		adc-settle-ms = <40>;
+		ai3x-micbias-vg = <1>;		/* 2.0V */
+		status = "okay";
+
+		/* Regulators */
+		AVDD-supply = <&evm_3v3>;
+		IOVDD-supply = <&evm_3v3>;
+		DRVDD-supply = <&evm_3v3>;
+		DVDD-supply = <&aic_dvdd>;
+	};
 };
 
 &i2c5 {
@@ -719,3 +794,42 @@
 		};
 	};
 };
+
+&atl {
+	pinctrl-names = "default";
+	pinctrl-0 = <&atl_pins>;
+
+	assigned-clocks = <&abe_dpll_sys_clk_mux>,
+			  <&atl_gfclk_mux>,
+			  <&dpll_abe_ck>,
+			  <&dpll_abe_m2x2_ck>,
+			  <&atl_clkin2_ck>;
+	assigned-clock-parents = <&sys_clkin2>, <&dpll_abe_m2_ck>;
+	assigned-clock-rates = <0>, <0>, <180633600>, <361267200>, <5644800>;
+
+	status = "okay";
+
+	atl2 {
+		bws = <DRA7_ATL_WS_MCASP2_FSX>;
+		aws = <DRA7_ATL_WS_MCASP3_FSX>;
+	};
+};
+
+&mcasp3 {
+	#sound-dai-cells = <0>;
+	pinctrl-names = "default", "sleep";
+	pinctrl-0 = <&mcasp3_pins>;
+	pinctrl-1 = <&mcasp3_sleep_pins>;
+
+	assigned-clocks = <&mcasp3_ahclkx_mux>;
+	assigned-clock-parents = <&atl_clkin2_ck>;
+
+	status = "okay";
+
+	op-mode = <0>;          /* MCASP_IIS_MODE */
+	tdm-slots = <2>;
+	/* 4 serializer */
+	serial-dir = <  /* 0: INACTIVE, 1: TX, 2: RX */
+		1 2 0 0
+	>;
+};
-- 
2.5.0



From peter.ujfalusi at ti.com  Mon Aug 24 00:20:04 2015
From: peter.ujfalusi at ti.com (Peter Ujfalusi)
Date: Mon, 24 Aug 2015 10:20:04 +0300
Subject: [PATCH 08/11] ARM: DTS: dra72-evm: Add gpio hog for vin6_sel_s0 to
 select audio
In-Reply-To: <1440400807-32274-1-git-send-email-peter.ujfalusi@ti.com>
References: <1440400807-32274-1-git-send-email-peter.ujfalusi@ti.com>
Message-ID: <1440400807-32274-9-git-send-email-peter.ujfalusi@ti.com>

The GPIO expander's p1 on i2c5 bus 0x26 address is used for selecting
between audio and VIN6 functionality. For VIN6 use an add on card is
needed while audio is present on the board itself.
Select the audio functionality over the VIN6 in the dts file.

Signed-off-by: Peter Ujfalusi <peter.ujfalusi at ti.com>
---
 arch/arm/boot/dts/dra72-evm.dts | 15 +++++++++++++++
 1 file changed, 15 insertions(+)

diff --git a/arch/arm/boot/dts/dra72-evm.dts b/arch/arm/boot/dts/dra72-evm.dts
index ac3a29483791..33be5c64bda3 100644
--- a/arch/arm/boot/dts/dra72-evm.dts
+++ b/arch/arm/boot/dts/dra72-evm.dts
@@ -119,6 +119,13 @@
 		>;
 	};
 
+	i2c5_pins: pinmux_i2c5_pins {
+		pinctrl-single,pins = <
+			0x2b4 (PIN_INPUT | MUX_MODE10) /* mcasp1_axr0.i2c5_sda */
+			0x2b8 (PIN_INPUT | MUX_MODE10) /* mcasp1_axr1.i2c5_scl */
+		>;
+	};
+
 	nand_default: nand_default {
 		pinctrl-single,pins = <
 			0x0	(PIN_INPUT  | MUX_MODE0) /* gpmc_ad0 */
@@ -389,6 +396,14 @@
 		 * VIN6_SEL_S0 is low, thus selecting McASP3 over VIN6
 		 */
 		lines-initial-states = <0x0f2b>;
+
+		p1 {
+			/* vin6_sel_s0: high: VIN6, low: audio */
+			gpio-hog;
+			gpios = <1 GPIO_ACTIVE_HIGH>;
+			output-low;
+			line-name = "vin6_sel_s0";
+		};
 	};
 };
 
-- 
2.5.0



From peter.ujfalusi at ti.com  Mon Aug 24 00:20:06 2015
From: peter.ujfalusi at ti.com (Peter Ujfalusi)
Date: Mon, 24 Aug 2015 10:20:06 +0300
Subject: [PATCH 10/11] ARM: DTS: am57xx-beagle-x15: Add fixed regulator for
 aic3104's DVDD
In-Reply-To: <1440400807-32274-1-git-send-email-peter.ujfalusi@ti.com>
References: <1440400807-32274-1-git-send-email-peter.ujfalusi@ti.com>
Message-ID: <1440400807-32274-11-git-send-email-peter.ujfalusi@ti.com>

The DVDD is supplied via TPS77018DBVT fixed regulator from vdd_3v3

Signed-off-by: Peter Ujfalusi <peter.ujfalusi at ti.com>
---
 arch/arm/boot/dts/am57xx-beagle-x15.dts | 8 ++++++++
 1 file changed, 8 insertions(+)

diff --git a/arch/arm/boot/dts/am57xx-beagle-x15.dts b/arch/arm/boot/dts/am57xx-beagle-x15.dts
index 3a05b94f59ed..485be19822f7 100644
--- a/arch/arm/boot/dts/am57xx-beagle-x15.dts
+++ b/arch/arm/boot/dts/am57xx-beagle-x15.dts
@@ -35,6 +35,14 @@
 		regulator-max-microvolt = <3300000>;
 	};
 
+	aic_dvdd: fixedregulator-aic_dvdd {
+		compatible = "regulator-fixed";
+		regulator-name = "aic_dvdd_fixed";
+		vin-supply = <&vdd_3v3>;
+		regulator-min-microvolt = <1800000>;
+		regulator-max-microvolt = <1800000>;
+	};
+
 	vtt_fixed: fixedregulator-vtt {
 		/* TPS51200 */
 		compatible = "regulator-fixed";
-- 
2.5.0



From peter.ujfalusi at ti.com  Mon Aug 24 00:20:02 2015
From: peter.ujfalusi at ti.com (Peter Ujfalusi)
Date: Mon, 24 Aug 2015 10:20:02 +0300
Subject: [PATCH 06/11] ARM: DTS: dra7-evm: Audio support
In-Reply-To: <1440400807-32274-1-git-send-email-peter.ujfalusi@ti.com>
References: <1440400807-32274-1-git-send-email-peter.ujfalusi@ti.com>
Message-ID: <1440400807-32274-7-git-send-email-peter.ujfalusi@ti.com>

The board uses tlv320aic3106 codec connected to McASP3. The master clock
for the codec and McASP3 is coming from ATL2.
McASP3 is the master on the I2S bus.

Signed-off-by: Peter Ujfalusi <peter.ujfalusi at ti.com>
---
 arch/arm/boot/dts/dra7-evm.dts | 113 +++++++++++++++++++++++++++++++++++++++++
 1 file changed, 113 insertions(+)

diff --git a/arch/arm/boot/dts/dra7-evm.dts b/arch/arm/boot/dts/dra7-evm.dts
index 3694046c29eb..1a66d359f3e3 100644
--- a/arch/arm/boot/dts/dra7-evm.dts
+++ b/arch/arm/boot/dts/dra7-evm.dts
@@ -9,6 +9,7 @@
 
 #include "dra74x.dtsi"
 #include <dt-bindings/gpio/gpio.h>
+#include <dt-bindings/clk/ti-dra7-atl.h>
 
 / {
 	model = "TI DRA742";
@@ -64,6 +65,40 @@
 		enable-active-high;
 		gpio = <&gpio7 11 GPIO_ACTIVE_HIGH>;
 	};
+
+	sound0: sound at 0 {
+		compatible = "simple-audio-card";
+		simple-audio-card,name = "DRA7xx-EVM";
+		simple-audio-card,widgets =
+			"Headphone", "Headphone Jack",
+			"Line", "Line Out",
+			"Microphone", "Mic Jack",
+			"Line", "Line In";
+		simple-audio-card,routing =
+			"Headphone Jack",	"HPLOUT",
+			"Headphone Jack",	"HPROUT",
+			"Line Out",		"LLOUT",
+			"Line Out",		"RLOUT",
+			"MIC3L",		"Mic Jack",
+			"MIC3R",		"Mic Jack",
+			"Mic Jack",		"Mic Bias",
+			"LINE1L",		"Line In",
+			"LINE1R",		"Line In";
+		simple-audio-card,format = "dsp_b";
+		simple-audio-card,bitclock-master = <&sound0_master>;
+		simple-audio-card,frame-master = <&sound0_master>;
+		simple-audio-card,bitclock-inversion;
+
+		sound0_master: simple-audio-card,cpu {
+			sound-dai = <&mcasp3>;
+			system-clock-frequency = <5644800>;
+		};
+
+		simple-audio-card,codec {
+			sound-dai = <&tlv320aic3106>;
+			clocks = <&atl_clkin2_ck>;
+		};
+	};
 };
 
 &dra7_pmx_core {
@@ -292,6 +327,31 @@
 			0x418   (MUX_MODE15 | PULL_UP)	/* wakeup0.off */
 		>;
 	};
+
+	atl_pins: pinmux_atl_pins {
+		pinctrl-single,pins = <
+			0x298 (PIN_OUTPUT | MUX_MODE5)	/* xref_clk1.atl_clk1 */
+			0x29c (PIN_OUTPUT | MUX_MODE5)	/* xref_clk2.atl_clk2 */
+		>;
+	};
+
+	mcasp3_pins: pinmux_mcasp3_pins {
+		pinctrl-single,pins = <
+			0x324 (PIN_OUTPUT_PULLDOWN | MUX_MODE0)	/* mcasp3_aclkx */
+			0x328 (PIN_OUTPUT_PULLDOWN | MUX_MODE0)	/* mcasp3_fsx */
+			0x32c (PIN_OUTPUT_PULLDOWN | MUX_MODE0)	/* mcasp3_axr0 */
+			0x330 (PIN_INPUT_PULLDOWN | MUX_MODE0)	/* mcasp3_axr1 */
+		>;
+	};
+
+	mcasp3_sleep_pins: pinmux_mcasp3_sleep_pins {
+		pinctrl-single,pins = <
+			0x324 (MUX_MODE15)
+			0x328 (MUX_MODE15)
+			0x32c (MUX_MODE15)
+			0x330 (MUX_MODE15)
+		>;
+	};
 };
 
 &i2c1 {
@@ -431,6 +491,20 @@
 		#interrupt-cells = <2>;
 	};
 
+	tlv320aic3106: tlv320aic3106 at 19 {
+		#sound-dai-cells = <0>;
+		compatible = "ti,tlv320aic3106";
+		reg = <0x19>;
+		adc-settle-ms = <40>;
+		ai3x-micbias-vg = <1>;		/* 2.0V */
+		status = "okay";
+
+		/* Regulators */
+		AVDD-supply = <&evm_3v3_sw>;
+		IOVDD-supply = <&evm_3v3_sw>;
+		DRVDD-supply = <&evm_3v3_sw>;
+		DVDD-supply = <&aic_dvdd>;
+	};
 };
 
 &i2c2 {
@@ -730,3 +804,42 @@
 	pinctrl-1 = <&dcan1_pins_sleep>;
 	pinctrl-2 = <&dcan1_pins_default>;
 };
+
+&atl {
+	pinctrl-names = "default";
+	pinctrl-0 = <&atl_pins>;
+
+	assigned-clocks = <&abe_dpll_sys_clk_mux>,
+			  <&atl_gfclk_mux>,
+			  <&dpll_abe_ck>,
+			  <&dpll_abe_m2x2_ck>,
+			  <&atl_clkin2_ck>;
+	assigned-clock-parents = <&sys_clkin2>, <&dpll_abe_m2_ck>;
+	assigned-clock-rates = <0>, <0>, <180633600>, <361267200>, <5644800>;
+
+	status = "okay";
+
+	atl2 {
+		bws = <DRA7_ATL_WS_MCASP2_FSX>;
+		aws = <DRA7_ATL_WS_MCASP3_FSX>;
+	};
+};
+
+&mcasp3 {
+	#sound-dai-cells = <0>;
+	pinctrl-names = "default", "sleep";
+	pinctrl-0 = <&mcasp3_pins>;
+	pinctrl-1 = <&mcasp3_sleep_pins>;
+
+	assigned-clocks = <&mcasp3_ahclkx_mux>;
+	assigned-clock-parents = <&atl_clkin2_ck>;
+
+	status = "okay";
+
+	op-mode = <0>;          /* MCASP_IIS_MODE */
+	tdm-slots = <2>;
+	/* 4 serializer */
+	serial-dir = <  /* 0: INACTIVE, 1: TX, 2: RX */
+		1 2 0 0
+	>;
+};
-- 
2.5.0



From peter.ujfalusi at ti.com  Mon Aug 24 00:20:03 2015
From: peter.ujfalusi at ti.com (Peter Ujfalusi)
Date: Mon, 24 Aug 2015 10:20:03 +0300
Subject: [PATCH 07/11] ARM: DTS: dra72-evm: Add fixed regulator representing
 DVDD supply for aic3106
In-Reply-To: <1440400807-32274-1-git-send-email-peter.ujfalusi@ti.com>
References: <1440400807-32274-1-git-send-email-peter.ujfalusi@ti.com>
Message-ID: <1440400807-32274-8-git-send-email-peter.ujfalusi@ti.com>

The DVDD is supplied via TPS77018DBVT fixed regulator from evm_3v3

Signed-off-by: Peter Ujfalusi <peter.ujfalusi at ti.com>
Signed-off-by: Darren Etheridge <detheridge at ti.com>
---
 arch/arm/boot/dts/dra72-evm.dts | 9 +++++++++
 1 file changed, 9 insertions(+)

diff --git a/arch/arm/boot/dts/dra72-evm.dts b/arch/arm/boot/dts/dra72-evm.dts
index 6f6bd98c98df..ac3a29483791 100644
--- a/arch/arm/boot/dts/dra72-evm.dts
+++ b/arch/arm/boot/dts/dra72-evm.dts
@@ -30,6 +30,15 @@
 		regulator-max-microvolt = <3300000>;
 	};
 
+	aic_dvdd: fixedregulator-aic_dvdd {
+		/* TPS77018DBVT */
+		compatible = "regulator-fixed";
+		regulator-name = "aic_dvdd";
+		vin-supply = <&evm_3v3>;
+		regulator-min-microvolt = <1800000>;
+		regulator-max-microvolt = <1800000>;
+	};
+
 	evm_3v3_sd: fixedregulator-sd {
 		compatible = "regulator-fixed";
 		regulator-name = "evm_3v3_sd";
-- 
2.5.0



From peter.ujfalusi at ti.com  Mon Aug 24 00:20:07 2015
From: peter.ujfalusi at ti.com (Peter Ujfalusi)
Date: Mon, 24 Aug 2015 10:20:07 +0300
Subject: [PATCH 11/11] ARM: DTS: am57xx-beagle-x15: Enable analog audio support
In-Reply-To: <1440400807-32274-1-git-send-email-peter.ujfalusi@ti.com>
References: <1440400807-32274-1-git-send-email-peter.ujfalusi@ti.com>
Message-ID: <1440400807-32274-12-git-send-email-peter.ujfalusi@ti.com>

The analog audio setup consists of:
McASP3 <-> tlv320aic3104 codec

Signed-off-by: Peter Ujfalusi <peter.ujfalusi at ti.com>
---
 arch/arm/boot/dts/am57xx-beagle-x15.dts | 87 +++++++++++++++++++++++++++++++++
 1 file changed, 87 insertions(+)

diff --git a/arch/arm/boot/dts/am57xx-beagle-x15.dts b/arch/arm/boot/dts/am57xx-beagle-x15.dts
index 485be19822f7..fd4c96ca8728 100644
--- a/arch/arm/boot/dts/am57xx-beagle-x15.dts
+++ b/arch/arm/boot/dts/am57xx-beagle-x15.dts
@@ -157,6 +157,32 @@
 			};
 		};
 	};
+
+	sound0: sound at 0 {
+		compatible = "simple-audio-card";
+		simple-audio-card,name = "BeagleBoard-X15";
+		simple-audio-card,widgets =
+			"Line", "Line Out",
+			"Line", "Line In";
+		simple-audio-card,routing =
+			"Line Out",	"LLOUT",
+			"Line Out",	"RLOUT",
+			"MIC2L",	"Line In",
+			"MIC2R",	"Line In";
+		simple-audio-card,format = "dsp_b";
+		simple-audio-card,bitclock-master = <&sound0_master>;
+		simple-audio-card,frame-master = <&sound0_master>;
+		simple-audio-card,bitclock-inversion;
+
+		simple-audio-card,cpu {
+			sound-dai = <&mcasp3>;
+		};
+
+		sound0_master: simple-audio-card,codec {
+			sound-dai = <&tlv320aic3104>;
+			clocks = <&clkout2_clk>;
+		};
+	};
 };
 
 &dra7_pmx_core {
@@ -347,6 +373,36 @@
 			0x370 (PIN_OUTPUT | MUX_MODE14)		/* gpio6_28 LS_OE */
 		>;
 	};
+
+	clkout2_pins_default: clkout2_pins_default {
+		pinctrl-single,pins = <
+			0x294 (PIN_OUTPUT_PULLDOWN | MUX_MODE9)	/* xref_clk0.clkout2 */
+		>;
+	};
+
+	clkout2_pins_sleep: clkout2_pins_sleep {
+		pinctrl-single,pins = <
+			0x294 (PIN_INPUT | MUX_MODE15)	/* xref_clk0.clkout2 */
+		>;
+	};
+
+	mcasp3_pins_default: mcasp3_pins_default {
+		pinctrl-single,pins = <
+			0x324 (PIN_INPUT_PULLDOWN | MUX_MODE0) /* mcasp3_aclkx.mcasp3_aclkx */
+			0x328 (PIN_INPUT_PULLDOWN | MUX_MODE0) /* mcasp3_fsx.mcasp3_fsx */
+			0x32c (PIN_OUTPUT_PULLDOWN | MUX_MODE0) /* mcasp3_axr0.mcasp3_axr0 */
+			0x330 (PIN_INPUT_PULLDOWN | MUX_MODE0) /* mcasp3_axr1.mcasp3_axr1 */
+		>;
+	};
+
+	mcasp3_pins_sleep: mcasp3_pins_sleep {
+		pinctrl-single,pins = <
+			0x324 (PIN_INPUT | MUX_MODE15)
+			0x328 (PIN_INPUT | MUX_MODE15)
+			0x32c (PIN_INPUT | MUX_MODE15)
+			0x330 (PIN_INPUT | MUX_MODE15)
+		>;
+	};
 };
 
 &i2c1 {
@@ -514,6 +570,22 @@
 		interrupts = <16 IRQ_TYPE_LEVEL_LOW>;
 		#thermal-sensor-cells = <1>;
 	};
+
+	tlv320aic3104: tlv320aic3104 at 18 {
+		#sound-dai-cells = <0>;
+		compatible = "ti,tlv320aic3104";
+		reg = <0x18>;
+		pinctrl-names = "default", "sleep";
+		pinctrl-0 = <&clkout2_pins_default>;
+		pinctrl-1 = <&clkout2_pins_sleep>;
+		status = "okay";
+		adc-settle-ms = <40>;
+
+		AVDD-supply = <&vdd_3v3>;
+		IOVDD-supply = <&vdd_3v3>;
+		DRVDD-supply = <&vdd_3v3>;
+		DVDD-supply = <&aic_dvdd>;
+	};
 };
 
 &i2c3 {
@@ -704,3 +776,18 @@
 &pcie1 {
 	gpios = <&gpio2 8 GPIO_ACTIVE_LOW>;
 };
+
+&mcasp3 {
+	#sound-dai-cells = <0>;
+	pinctrl-names = "default", "sleep";
+	pinctrl-0 = <&mcasp3_pins_default>;
+	pinctrl-1 = <&mcasp3_pins_sleep>;
+	status = "okay";
+
+	op-mode = <0>;	/* MCASP_IIS_MODE */
+	tdm-slots = <2>;
+	/* 4 serializers */
+	serial-dir = <	/* 0: INACTIVE, 1: TX, 2: RX */
+		1 2 0 0
+	>;
+};
-- 
2.5.0



From jingoohan1 at gmail.com  Mon Aug 24 00:40:41 2015
From: jingoohan1 at gmail.com (Jingoo Han)
Date: Mon, 24 Aug 2015 16:40:41 +0900
Subject: [PATCH v3 06/14] Documentation: drm/bridge: add document for
 analogix_dp
In-Reply-To: <CAJKOXPeEm8exg_UG0tDnaEGO40ejBKZ-ok=bKbVrwYvXnDaMdg@mail.gmail.com>
References: <1439995728-18046-1-git-send-email-ykk@rock-chips.com>
 <1439995834-18363-1-git-send-email-ykk@rock-chips.com>
 <CAL_JsqLz+8RtBucctUj4euXZ3Ac0DvB52N9ONpAerh5T9BiTJg@mail.gmail.com>
 <CAJKOXPeEm8exg_UG0tDnaEGO40ejBKZ-ok=bKbVrwYvXnDaMdg@mail.gmail.com>
Message-ID: <4CAFC1ED-400F-46E4-B61F-82BB1ED018EA@gmail.com>

On 2015. 8. 24., at AM 9:43, Krzysztof Kozlowski <k.kozlowski at samsung.com> wrote:
> 
> 2015-08-24 8:23 GMT+09:00 Rob Herring <robherring2 at gmail.com>:
>>> On Wed, Aug 19, 2015 at 9:50 AM, Yakir Yang <ykk at rock-chips.com> wrote:
>>> Analogix dp driver is split from exynos dp driver, so we just
>>> make an copy of exynos_dp.txt, and then simplify exynos_dp.txt
>>> 
>>> Beside update some exynos dtsi file with the latest change
>>> according to the devicetree binding documents.
>> 
>> You can't just change the exynos bindings and break compatibility. Is
>> there some agreement with exynos folks to do this?
> 
> No, there is no agreement. This wasn't even sent to Exynos maintainers.
> Additionally the patchset did not look interesting to me because of
> misleading subject - Documentation instead of "ARM: dts:".
> 
> Yakir, please:
> 1. Provide backward compatibility. Mark old properties as deprecated
> but still support them.
> 2. Separate all DTS changes to a separate patch, unless bisectability
> would be hurt. Anyway you should prepare it in a such way that
> separation would be possible without breaking bisectability.
> 3. Use proper subject for the patch changing DTS. This is not
> documentation change!
> 4. Please use script get_maintainers to obtain list of valid
> maintainers and CC-them with at least cover letter and patches
> requiring their attention.

To Yakir Yang,

Please be careful when you CC people.

I don't find the reason why you CC'ed the following people. Of course, they
look to be one of the talented developers. However, they look to be
unrelated to your patchset.

 Takashi Iwai
 Vincent Palatin
 Fabio Estevam
 Philipp Zabel


Also, please add Exynos Architecture maintainers to CC list. I don't understand
why you removed them from CC list.
 Kukjin Kim
 Krzysztof Kozlowski

Without their Ack, you will not change the codes of ARM Exynos Architecture.

Best regards,
Jingoo Han

> 
> Best regards,
> Krzysztof
> 
> 
>> 
>> 
>>> Signed-off-by: Yakir Yang <ykk at rock-chips.com>
>>> ---
>>> Changes in v3:
>>> - Take Heiko suggest, add devicetree binding documents.
>>> - Take Thierry Reding suggest, remove sync pol & colorimetry properies
>>>  from the new analogix dp driver devicetree binding.
>>> - Update the exist exynos dtsi file with the latest DP DT properies.
>>> 
>>> Changes in v2: None
>>> 
>>> .../devicetree/bindings/drm/bridge/analogix_dp.txt | 70 ++++++++++++++++++++++
>>> .../devicetree/bindings/video/exynos_dp.txt        | 50 ++++++----------
>>> arch/arm/boot/dts/exynos5250-arndale.dts           | 10 ++--
>>> arch/arm/boot/dts/exynos5250-smdk5250.dts          | 10 ++--
>>> arch/arm/boot/dts/exynos5250-snow.dts              | 12 ++--
>>> arch/arm/boot/dts/exynos5250-spring.dts            | 12 ++--
>>> arch/arm/boot/dts/exynos5420-peach-pit.dts         | 12 ++--
>>> arch/arm/boot/dts/exynos5420-smdk5420.dts          | 10 ++--
>>> arch/arm/boot/dts/exynos5800-peach-pi.dts          | 12 ++--
>>> 9 files changed, 119 insertions(+), 79 deletions(-)
>>> create mode 100644 Documentation/devicetree/bindings/drm/bridge/analogix_dp.txt
>>> 
>>> diff --git a/Documentation/devicetree/bindings/drm/bridge/analogix_dp.txt b/Documentation/devicetree/bindings/drm/bridge/analogix_dp.txt
>>> new file mode 100644
>>> index 0000000..6127018
>>> --- /dev/null
>>> +++ b/Documentation/devicetree/bindings/drm/bridge/analogix_dp.txt
>>> @@ -0,0 +1,70 @@
>>> +Analogix Display Port bridge bindings
>>> +
>>> +Required properties for dp-controller:
>>> +       -compatible:
>>> +               platform specific such as:
>>> +                * "samsung,exynos5-dp"
>>> +                * "rockchip,rk3288-dp"
>>> +       -reg:
>>> +               physical base address of the controller and length
>>> +               of memory mapped region.
>>> +       -interrupts:
>>> +               interrupt combiner values.
>>> +       -clocks:
>>> +               from common clock binding: handle to dp clock.
>>> +       -clock-names:
>>> +               from common clock binding: Shall be "dp".
>>> +       -interrupt-parent:
>>> +               phandle to Interrupt combiner node.
>>> +       -phys:
>>> +               from general PHY binding: the phandle for the PHY device.
>>> +       -phy-names:
>>> +               from general PHY binding: Should be "dp".
>>> +       -analogix,color-space:
>>> +               input video data format.
>>> +                       COLOR_RGB = 0, COLOR_YCBCR422 = 1, COLOR_YCBCR444 = 2
>>> +       -analogix,color-depth:
>>> +               number of bits per colour component.
>>> +                       COLOR_6 = 0, COLOR_8 = 1, COLOR_10 = 2, COLOR_12 = 3
>> 
>> This seems pretty generic. Just use 6, 8, 10, or 12 for values. And
>> drop the vendor prefix.
>> 
>>> +       -analogix,link-rate:
>>> +               max link rate supported by the eDP controller.
>>> +                       LINK_RATE_1_62GBPS = 0x6, LINK_RATE_2_70GBPS = 0x0A,
>>> +                       LINK_RATE_5_40GBPS = 0x14
>> 
>> Same here. I'd rather see something like "link-rate-mbps" and use the
>> actual rate.
>> 
>>> +       -analogix,lane-count:
>>> +               max number of lanes supported by the eDP contoller.
>>> +                       LANE_COUNT1 = 1, LANE_COUNT2 = 2, LANE_COUNT4 = 4
>> 
>> And drop the vendor prefix here.
>> 
>>> +       -port@[X]: SoC specific port nodes with endpoint definitions as defined
>>> +               in Documentation/devicetree/bindings/media/video-interfaces.txt,
>>> +               please refer to the SoC specific binding document:
>>> +               * Documentation/devicetree/bindings/video/exynos_dp.txt
>>> +               * Documentation/devicetree/bindings/video/analogix_dp-rockchip.txt
>>> +
>>> +Optional properties for dp-controller:
>>> +       -analogix,hpd-gpio:
>>> +               Hotplug detect GPIO.
>>> +                       Indicates which GPIO should be used for hotplug
>>> +                       detection
>> 
>> We should align with "hpd-gpios" used by HDMI connector binding. Or do
>> we need a DP connector binding that this should be defined in?
>> Probably so.
>> 
>> The DRM related bindings are such a cluster f*ck with everyone picking
>> their own way to do things. Just grep hpd in bindings for starters.
>> That is just the tip.
>> 
>>> +       -video interfaces: Device node can contain video interface port
>>> +                           nodes according to [1].
>> 
>> Isn't this the same as ports above? How are they optional? 0 ports
>> would be pretty useless.
>> 
>>> +
>>> +[1]: Documentation/devicetree/bindings/media/video-interfaces.txt
>>> +-------------------------------------------------------------------------------
>>> +
>>> +Example:
>>> +
>>> +       dp-controller {
>>> +               compatible = "samsung,exynos5-dp";
>>> +               reg = <0x145b0000 0x10000>;
>>> +               interrupts = <10 3>;
>>> +               interrupt-parent = <&combiner>;
>>> +               clocks = <&clock 342>;
>>> +               clock-names = "dp";
>>> +
>>> +               phys = <&dp_phy>;
>>> +               phy-names = "dp";
>>> +
>>> +               analogix,color-space = <0>;
>>> +               analogix,color-depth = <1>;
>>> +               analogix,link-rate = <0x0a>;
>>> +               analogix,lane-count = <4>;
>>> +       };
>>> diff --git a/Documentation/devicetree/bindings/video/exynos_dp.txt b/Documentation/devicetree/bindings/video/exynos_dp.txt
>>> index 7a3a9cd..177506f 100644
>>> --- a/Documentation/devicetree/bindings/video/exynos_dp.txt
>>> +++ b/Documentation/devicetree/bindings/video/exynos_dp.txt
>>> @@ -31,28 +31,10 @@ Required properties for dp-controller:
>>>                from general PHY binding: the phandle for the PHY device.
>>>        -phy-names:
>>>                from general PHY binding: Should be "dp".
>>> -       -samsung,color-space:
>>> -               input video data format.
>>> -                       COLOR_RGB = 0, COLOR_YCBCR422 = 1, COLOR_YCBCR444 = 2
>>> -       -samsung,dynamic-range:
>>> -               dynamic range for input video data.
>>> -                       VESA = 0, CEA = 1
>>> -       -samsung,ycbcr-coeff:
>>> -               YCbCr co-efficients for input video.
>>> -                       COLOR_YCBCR601 = 0, COLOR_YCBCR709 = 1
>>> -       -samsung,color-depth:
>>> -               number of bits per colour component.
>>> -                       COLOR_6 = 0, COLOR_8 = 1, COLOR_10 = 2, COLOR_12 = 3
>>> -       -samsung,link-rate:
>>> -               link rate supported by the panel.
>>> -                       LINK_RATE_1_62GBPS = 0x6, LINK_RATE_2_70GBPS = 0x0A
>>> -       -samsung,lane-count:
>>> -               number of lanes supported by the panel.
>>> -                       LANE_COUNT1 = 1, LANE_COUNT2 = 2, LANE_COUNT4 = 4
>>> -       - display-timings: timings for the connected panel as described by
>>> -               Documentation/devicetree/bindings/video/display-timing.txt
>>> 
>>> Optional properties for dp-controller:
>>> +       - display-timings: timings for the connected panel as described by
>>> +               Documentation/devicetree/bindings/video/display-timing.txt
>>>        -interlaced:
>>>                interlace scan mode.
>>>                        Progressive if defined, Interlaced if not defined
>>> @@ -62,14 +44,18 @@ Optional properties for dp-controller:
>>>        -hsync-active-high:
>>>                HSYNC polarity configuration.
>>>                        High if defined, Low if not defined
>>> -       -samsung,hpd-gpio:
>>> -               Hotplug detect GPIO.
>>> -                       Indicates which GPIO should be used for hotplug
>>> -                       detection
>>> -       -video interfaces: Device node can contain video interface port
>>> -                           nodes according to [1].
>>> 
>>> -[1]: Documentation/devicetree/bindings/media/video-interfaces.txt
>>> +For the below properties, please refer to Analogix DP binding document:
>>> + * Documentation/devicetree/bindings/drm/bridge/analogix_dp.txt
>>> +       -phys (required)
>>> +       -phy-names (required)
>>> +       -analogix,color-space (required)
>>> +       -analogix,color-depth (required)
>>> +       -analogix,link-rate (required)
>>> +       -analogix,lane-count (required)
>>> +       -analogix,hpd-gpio (optional)
>>> +       -video interfaces (optional)
>>> +-------------------------------------------------------------------------------
>>> 
>>> Example:
>>> 
>>> @@ -88,12 +74,10 @@ SOC specific portion:
>>> 
>>> Board Specific portion:
>>>        dp-controller {
>>> -               samsung,color-space = <0>;
>>> -               samsung,dynamic-range = <0>;
>>> -               samsung,ycbcr-coeff = <0>;
>>> -               samsung,color-depth = <1>;
>>> -               samsung,link-rate = <0x0a>;
>>> -               samsung,lane-count = <4>;
>>> +               analogix,color-space = <0>;
>>> +               analogix,color-depth = <1>;
>>> +               analogix,link-rate = <0x0a>;
>>> +               analogix,lane-count = <4>;
>>> 
>>>                display-timings {
>>>                        native-mode = <&lcd_timing>;
>>> diff --git a/arch/arm/boot/dts/exynos5250-arndale.dts b/arch/arm/boot/dts/exynos5250-arndale.dts
>>> index 7e728a1..e48798d 100644
>>> --- a/arch/arm/boot/dts/exynos5250-arndale.dts
>>> +++ b/arch/arm/boot/dts/exynos5250-arndale.dts
>>> @@ -119,12 +119,10 @@
>>> 
>>> &dp {
>>>        status = "okay";
>>> -       samsung,color-space = <0>;
>>> -       samsung,dynamic-range = <0>;
>>> -       samsung,ycbcr-coeff = <0>;
>>> -       samsung,color-depth = <1>;
>>> -       samsung,link-rate = <0x0a>;
>>> -       samsung,lane-count = <4>;
>>> +       analogix,color-space = <0>;
>>> +       analogix,color-depth = <1>;
>>> +       analogix,link-rate = <0x0a>;
>>> +       analogix,lane-count = <4>;
>>> };
>>> 
>>> &fimd {
>>> diff --git a/arch/arm/boot/dts/exynos5250-smdk5250.dts b/arch/arm/boot/dts/exynos5250-smdk5250.dts
>>> index 4fe186d..b8c6b8b 100644
>>> --- a/arch/arm/boot/dts/exynos5250-smdk5250.dts
>>> +++ b/arch/arm/boot/dts/exynos5250-smdk5250.dts
>>> @@ -75,12 +75,10 @@
>>> };
>>> 
>>> &dp {
>>> -       samsung,color-space = <0>;
>>> -       samsung,dynamic-range = <0>;
>>> -       samsung,ycbcr-coeff = <0>;
>>> -       samsung,color-depth = <1>;
>>> -       samsung,link-rate = <0x0a>;
>>> -       samsung,lane-count = <4>;
>>> +       analogix,color-space = <0>;
>>> +       analogix,color-depth = <1>;
>>> +       analogix,link-rate = <0x0a>;
>>> +       analogix,lane-count = <4>;
>>> 
>>>        pinctrl-names = "default";
>>>        pinctrl-0 = <&dp_hpd>;
>>> diff --git a/arch/arm/boot/dts/exynos5250-snow.dts b/arch/arm/boot/dts/exynos5250-snow.dts
>>> index b7f4122..9ce2b89 100644
>>> --- a/arch/arm/boot/dts/exynos5250-snow.dts
>>> +++ b/arch/arm/boot/dts/exynos5250-snow.dts
>>> @@ -239,13 +239,11 @@
>>>        status = "okay";
>>>        pinctrl-names = "default";
>>>        pinctrl-0 = <&dp_hpd>;
>>> -       samsung,color-space = <0>;
>>> -       samsung,dynamic-range = <0>;
>>> -       samsung,ycbcr-coeff = <0>;
>>> -       samsung,color-depth = <1>;
>>> -       samsung,link-rate = <0x0a>;
>>> -       samsung,lane-count = <2>;
>>> -       samsung,hpd-gpio = <&gpx0 7 GPIO_ACTIVE_HIGH>;
>>> +       analogix,color-space = <0>;
>>> +       analogix,color-depth = <1>;
>>> +       analogix,link-rate = <0x0a>;
>>> +       analogix,lane-count = <2>;
>>> +       analogix,hpd-gpio = <&gpx0 7 GPIO_ACTIVE_HIGH>;
>>> 
>>>        ports {
>>>                port at 0 {
>>> diff --git a/arch/arm/boot/dts/exynos5250-spring.dts b/arch/arm/boot/dts/exynos5250-spring.dts
>>> index d03f9b8..9288ae6 100644
>>> --- a/arch/arm/boot/dts/exynos5250-spring.dts
>>> +++ b/arch/arm/boot/dts/exynos5250-spring.dts
>>> @@ -69,13 +69,11 @@
>>>        status = "okay";
>>>        pinctrl-names = "default";
>>>        pinctrl-0 = <&dp_hpd_gpio>;
>>> -       samsung,color-space = <0>;
>>> -       samsung,dynamic-range = <0>;
>>> -       samsung,ycbcr-coeff = <0>;
>>> -       samsung,color-depth = <1>;
>>> -       samsung,link-rate = <0x0a>;
>>> -       samsung,lane-count = <1>;
>>> -       samsung,hpd-gpio = <&gpc3 0 GPIO_ACTIVE_HIGH>;
>>> +       analogix,color-space = <0>;
>>> +       analogix,color-depth = <1>;
>>> +       analogix,link-rate = <0x0a>;
>>> +       analogix,lane-count = <1>;
>>> +       analogix,hpd-gpio = <&gpc3 0 GPIO_ACTIVE_HIGH>;
>>> };
>>> 
>>> &ehci {
>>> diff --git a/arch/arm/boot/dts/exynos5420-peach-pit.dts b/arch/arm/boot/dts/exynos5420-peach-pit.dts
>>> index 8f4d76c..695a380 100644
>>> --- a/arch/arm/boot/dts/exynos5420-peach-pit.dts
>>> +++ b/arch/arm/boot/dts/exynos5420-peach-pit.dts
>>> @@ -147,13 +147,11 @@
>>>        status = "okay";
>>>        pinctrl-names = "default";
>>>        pinctrl-0 = <&dp_hpd_gpio>;
>>> -       samsung,color-space = <0>;
>>> -       samsung,dynamic-range = <0>;
>>> -       samsung,ycbcr-coeff = <0>;
>>> -       samsung,color-depth = <1>;
>>> -       samsung,link-rate = <0x06>;
>>> -       samsung,lane-count = <2>;
>>> -       samsung,hpd-gpio = <&gpx2 6 0>;
>>> +       analogix,color-space = <0>;
>>> +       analogix,color-depth = <1>;
>>> +       analogix,link-rate = <0x06>;
>>> +       analogix,lane-count = <2>;
>>> +       analogix,hpd-gpio = <&gpx2 6 0>;
>>> 
>>>        ports {
>>>                port at 0 {
>>> diff --git a/arch/arm/boot/dts/exynos5420-smdk5420.dts b/arch/arm/boot/dts/exynos5420-smdk5420.dts
>>> index 98871f9..fd46714 100644
>>> --- a/arch/arm/boot/dts/exynos5420-smdk5420.dts
>>> +++ b/arch/arm/boot/dts/exynos5420-smdk5420.dts
>>> @@ -91,12 +91,10 @@
>>> &dp {
>>>        pinctrl-names = "default";
>>>        pinctrl-0 = <&dp_hpd>;
>>> -       samsung,color-space = <0>;
>>> -       samsung,dynamic-range = <0>;
>>> -       samsung,ycbcr-coeff = <0>;
>>> -       samsung,color-depth = <1>;
>>> -       samsung,link-rate = <0x0a>;
>>> -       samsung,lane-count = <4>;
>>> +       analogix,color-space = <0>;
>>> +       analogix,color-depth = <1>;
>>> +       analogix,link-rate = <0x0a>;
>>> +       analogix,lane-count = <4>;
>>>        status = "okay";
>>> };
>>> 
>>> diff --git a/arch/arm/boot/dts/exynos5800-peach-pi.dts b/arch/arm/boot/dts/exynos5800-peach-pi.dts
>>> index 7d5b386..54b4c63 100644
>>> --- a/arch/arm/boot/dts/exynos5800-peach-pi.dts
>>> +++ b/arch/arm/boot/dts/exynos5800-peach-pi.dts
>>> @@ -141,13 +141,11 @@
>>>        status = "okay";
>>>        pinctrl-names = "default";
>>>        pinctrl-0 = <&dp_hpd_gpio>;
>>> -       samsung,color-space = <0>;
>>> -       samsung,dynamic-range = <0>;
>>> -       samsung,ycbcr-coeff = <0>;
>>> -       samsung,color-depth = <1>;
>>> -       samsung,link-rate = <0x0a>;
>>> -       samsung,lane-count = <2>;
>>> -       samsung,hpd-gpio = <&gpx2 6 0>;
>>> +       analogix,color-space = <0>;
>>> +       analogix,color-depth = <1>;
>>> +       analogix,link-rate = <0x0a>;
>>> +       analogix,lane-count = <2>;
>>> +       analogix,hpd-gpio = <&gpx2 6 0>;
>>>        panel = <&panel>;
>>> };
>>> 
>>> --
>>> 1.9.1
>>> 
>>> 
>>> 
>>> _______________________________________________
>>> linux-arm-kernel mailing list
>>> linux-arm-kernel at lists.infradead.org
>>> http://lists.infradead.org/mailman/listinfo/linux-arm-kernel
>> 
>> _______________________________________________
>> linux-arm-kernel mailing list
>> linux-arm-kernel at lists.infradead.org
>> http://lists.infradead.org/mailman/listinfo/linux-arm-kernel


From alexandre.belloni at free-electrons.com  Mon Aug 24 00:42:56 2015
From: alexandre.belloni at free-electrons.com (Alexandre Belloni)
Date: Mon, 24 Aug 2015 09:42:56 +0200
Subject: [PATCH v3 1/2] devicetree: bindings: rtc: add bindings for
 xilinx zynqmp rtc
In-Reply-To: <1439978002-12157-1-git-send-email-suneel.garapati@xilinx.com>
References: <1439978002-12157-1-git-send-email-suneel.garapati@xilinx.com>
Message-ID: <20150824074256.GE13155@piout.net>

On 19/08/2015 at 15:23:21 +0530, Suneel Garapati wrote :
> adds file for description on device node bindings for RTC
> found on Xilinx Zynq Ultrascale+ MPSoC.
> 
> Signed-off-by: Suneel Garapati <suneel.garapati at xilinx.com>
> ---
> Changes v3 
> - none 
> Changes v2 
> - add examples for interrupt-names 
> - change alm to alarm 
> ---
>  Documentation/devicetree/bindings/rtc/xlnx-rtc.txt | 25 ++++++++++++++++++++++
>  1 file changed, 25 insertions(+)
>  create mode 100644 Documentation/devicetree/bindings/rtc/xlnx-rtc.txt
> 
Applied, thanks.

-- 
Alexandre Belloni, Free Electrons
Embedded Linux, Kernel and Android engineering
http://free-electrons.com


From alexandre.belloni at free-electrons.com  Mon Aug 24 00:43:10 2015
From: alexandre.belloni at free-electrons.com (Alexandre Belloni)
Date: Mon, 24 Aug 2015 09:43:10 +0200
Subject: [PATCH v3 2/2] drivers: rtc: add xilinx zynqmp rtc driver
In-Reply-To: <1439978002-12157-2-git-send-email-suneel.garapati@xilinx.com>
References: <1439978002-12157-1-git-send-email-suneel.garapati@xilinx.com>
 <1439978002-12157-2-git-send-email-suneel.garapati@xilinx.com>
Message-ID: <20150824074310.GF13155@piout.net>

On 19/08/2015 at 15:23:22 +0530, Suneel Garapati wrote :
> adds support for RTC controller found on
> Xilinx Zynq Ultrascale+ MPSoC platform.
> 
> Signed-off-by: Suneel Garapati <suneel.garapati at xilinx.com>
> ---
> Changes v3 
> - fix checkpatch errors 
> - check time in secs arg against max sec val 
> - order header files 
> - use ptr_err_or_zero macro 
> - use time64 variants 
> Changes v2 
> - change alm to alarm 
> ---
>  drivers/rtc/Kconfig      |   7 ++
>  drivers/rtc/Makefile     |   1 +
>  drivers/rtc/rtc-zynqmp.c | 279 +++++++++++++++++++++++++++++++++++++++++++++++
>  3 files changed, 287 insertions(+)
>  create mode 100644 drivers/rtc/rtc-zynqmp.c
> 
Applied, thanks.

-- 
Alexandre Belloni, Free Electrons
Embedded Linux, Kernel and Android engineering
http://free-electrons.com


From maxime.ripard at free-electrons.com  Mon Aug 24 00:46:05 2015
From: maxime.ripard at free-electrons.com (Maxime Ripard)
Date: Mon, 24 Aug 2015 09:46:05 +0200
Subject: [PATCH] net: sun4i-emac: Claim emac sram
In-Reply-To: <1440354698-11144-1-git-send-email-hdegoede@redhat.com>
References: <1440354698-11144-1-git-send-email-hdegoede@redhat.com>
Message-ID: <20150824074605.GF2413@lukather>

Hi Hans,

On Sun, Aug 23, 2015 at 08:31:38PM +0200, Hans de Goede wrote:
> Claim the emac sram ourselves, rather then relying on the bootloader
> having mapped the sram to the emac controller during boot.
> 
> Signed-off-by: Hans de Goede <hdegoede at redhat.com>
> ---
>  drivers/net/ethernet/allwinner/sun4i-emac.c | 13 +++++++++++--
>  1 file changed, 11 insertions(+), 2 deletions(-)
> 
> diff --git a/drivers/net/ethernet/allwinner/sun4i-emac.c b/drivers/net/ethernet/allwinner/sun4i-emac.c
> index bab01c84..48ce83e 100644
> --- a/drivers/net/ethernet/allwinner/sun4i-emac.c
> +++ b/drivers/net/ethernet/allwinner/sun4i-emac.c
> @@ -28,6 +28,7 @@
>  #include <linux/of_platform.h>
>  #include <linux/platform_device.h>
>  #include <linux/phy.h>
> +#include <linux/soc/sunxi/sunxi_sram.h>
>  
>  #include "sun4i-emac.h"
>  
> @@ -857,11 +858,17 @@ static int emac_probe(struct platform_device *pdev)
>  
>  	clk_prepare_enable(db->clk);
>  
> +	ret = sunxi_sram_claim(&pdev->dev);
> +	if (ret) {
> +		dev_err(&pdev->dev, "Error couldn't map SRAM to device\n");
> +		goto out;

Shouldn't you disable you clock too?

Thanks,
Maxime

-- 
Maxime Ripard, Free Electrons
Embedded Linux, Kernel and Android engineering
http://free-electrons.com
-------------- next part --------------
A non-text attachment was scrubbed...
Name: signature.asc
Type: application/pgp-signature
Size: 819 bytes
Desc: Digital signature
URL: <http://lists.infradead.org/pipermail/linux-arm-kernel/attachments/20150824/2ab019ef/attachment.sig>

From michal.simek at xilinx.com  Mon Aug 24 00:48:42 2015
From: michal.simek at xilinx.com (Michal Simek)
Date: Mon, 24 Aug 2015 09:48:42 +0200
Subject: [PATCH v3 2/2] drivers: rtc: add xilinx zynqmp rtc driver
In-Reply-To: <20150824074310.GF13155@piout.net>
References: <1439978002-12157-1-git-send-email-suneel.garapati@xilinx.com>
 <1439978002-12157-2-git-send-email-suneel.garapati@xilinx.com>
 <20150824074310.GF13155@piout.net>
Message-ID: <55DACC5A.80707@xilinx.com>

On 08/24/2015 09:43 AM, Alexandre Belloni wrote:
> On 19/08/2015 at 15:23:22 +0530, Suneel Garapati wrote :
>> adds support for RTC controller found on
>> Xilinx Zynq Ultrascale+ MPSoC platform.
>>
>> Signed-off-by: Suneel Garapati <suneel.garapati at xilinx.com>
>> ---
>> Changes v3 
>> - fix checkpatch errors 
>> - check time in secs arg against max sec val 
>> - order header files 
>> - use ptr_err_or_zero macro 
>> - use time64 variants 
>> Changes v2 
>> - change alm to alarm 
>> ---
>>  drivers/rtc/Kconfig      |   7 ++
>>  drivers/rtc/Makefile     |   1 +
>>  drivers/rtc/rtc-zynqmp.c | 279 +++++++++++++++++++++++++++++++++++++++++++++++
>>  3 files changed, 287 insertions(+)
>>  create mode 100644 drivers/rtc/rtc-zynqmp.c
>>
> Applied, thanks.
> 

Thanks,
Michal



From daniel.lezcano at linaro.org  Mon Aug 24 00:51:11 2015
From: daniel.lezcano at linaro.org (Daniel Lezcano)
Date: Mon, 24 Aug 2015 09:51:11 +0200
Subject: [PATCH v2 1/5] clocksource: mediatek: do not enable GPT_CLK_EVT
 when setup
In-Reply-To: <1440167950.20169.29.camel@mtksdaap41>
References: <CAGS+omD8k_Cfxv3bYyjmjtLbiavo-WmJPn0Z-CBhN_nnv65Tag@mail.gmail.com>		
 <1437552878-3684-1-git-send-email-yingjoe.chen@mediatek.com>		
 <55CC56C4.8080201@linaro.org> <1439820602.3414.12.camel@mtksdaap41>	
 <55D5E40A.6080904@linaro.org> <1440167950.20169.29.camel@mtksdaap41>
Message-ID: <55DACCEF.8040004@linaro.org>

On 08/21/2015 04:39 PM, Yingjoe Chen wrote:

[ ... ]

>>    - Does the spurious interrupt occurs *every* time ? at each boot ?
>
> Yes. If you applied this series to enable mtk timer without this fix on
> mt8173 or mt8135 you can reproduce it. It occurs for every boot.
>
> It crash before uart driver is ready, so you'll have to use earlycon to
> see the crash log.

Can you give me the earlycon params ?

Thanks.

  -- Daniel

-- 
  <http://www.linaro.org/> Linaro.org ? Open source software for ARM SoCs

Follow Linaro:  <http://www.facebook.com/pages/Linaro> Facebook |
<http://twitter.com/#!/linaroorg> Twitter |
<http://www.linaro.org/linaro-blog/> Blog



From ard.biesheuvel at linaro.org  Mon Aug 24 01:00:43 2015
From: ard.biesheuvel at linaro.org (Ard Biesheuvel)
Date: Mon, 24 Aug 2015 10:00:43 +0200
Subject: [PATCH 0/2] arm64: ignore memory outside of the linear range
In-Reply-To: <CY1PR0301MB0748FC71E6866C8AFACAAFF687780@CY1PR0301MB0748.namprd03.prod.outlook.com>
References: <1439890482-20798-1-git-send-email-ard.biesheuvel@linaro.org>
 <CY1PR0301MB0748FC71E6866C8AFACAAFF687780@CY1PR0301MB0748.namprd03.prod.outlook.com>
Message-ID: <CAKv+Gu-OQ4VyCqe=mEDOrrfAtAWTfRtAiqXMGSVjJxOH6xi4Ow@mail.gmail.com>

On 18 August 2015 at 16:18, Stuart Yoder <stuart.yoder at freescale.com> wrote:
>
>
>> -----Original Message-----
>> From: Ard Biesheuvel [mailto:ard.biesheuvel at linaro.org]
>> Sent: Tuesday, August 18, 2015 4:35 AM
>> To: linux-arm-kernel at lists.infradead.org; mark.rutland at arm.com; catalin.marinas at arm.com; robh at kernel.org
>> Cc: grant.likely at linaro.org; Yoder Stuart-B08248; will.deacon at arm.com; Ard Biesheuvel
>> Subject: [PATCH 0/2] arm64: ignore memory outside of the linear range
>>
>> This is a followup to the single patch I posted on Aug 15th to ignore
>> RAM that cannot be covered by the linear mapping. Instead of clipping
>> the memory after the fact, this clips the memory before installing the
>> regions into the memblock memory table.
>>
>> This is basically the approach that Mark Rutland suggested here
>>
>> http://article.gmane.org/gmane.linux.ports.arm.kernel/430239
>>
>> but modified to correctly consider the base of the kernel image as the
>> start of the linear mapping.
>>
>> Ard Biesheuvel (2):
>>   of/fdt: make memblock maximum physical address arch configurable
>>   arm64: set MAX_MEMBLOCK_ADDR according to linear region size
>>
>>  arch/arm64/include/asm/memory.h |  8 ++++++++
>>  drivers/of/fdt.c                | 12 +++++++-----
>>  2 files changed, 15 insertions(+), 5 deletions(-)
>
> Tested on Freescale LS2085ARDB which has a split memory region
> that triggers the bug.
>
> Tested-by: Stuart Yoder <stuart.yoder at freescale.com>
>

Hi Will,

Will you be picking up this series for v4.3? If so, do you need me to
resend it with the tags added?

Thanks,
Ard.


From pankaj.dubey at samsung.com  Mon Aug 24 01:02:21 2015
From: pankaj.dubey at samsung.com (Pankaj Dubey)
Date: Mon, 24 Aug 2015 13:32:21 +0530
Subject: [PATCH v2 0/7] Add support for Exynos SROM Controller driver
Message-ID: <1440403348-8974-1-git-send-email-pankaj.dubey@samsung.com>

This patch set adds support for Exynos SROM controller DT based driver.
Currently SROM register sets are used only during S2R, so driver
basically added for taking care of S2R. It will help us in removing
static mapping from exynos.c and other extra code handline during S2R.

This patch set also updated exynos4 and exynos5 dtsi files for with device
node for srom, and added binding documentation for the same.

First two patches are some minor cleanup in mach-exynos.

Patchset v1 was posted here[1]
[1]: https://lkml.org/lkml/2015/4/29/98

Changes since v1:
 - Rebased to latest kgene tree.
 - Addressed review comments from Krzysztof Kozlowski.
 - Add two new patches for minor cleanup in exynos.c and map.h

Pankaj Dubey (7):
  ARM: EXYNOS: remove unused static mapping of CMU for exynos5
  ARM: EXYNOS: code cleanup in map.h
  drivers: soc: add support for exynos SROM driver
  ARM: EXYNOS: Remove SROM related register settings from mach-exynos
  ARM: dts: add SROM device node for exynos4
  ARM: dts: add SROM device node for exynos5
  Documentation: dt-bindings: add exynos-srom binding information

 .../bindings/arm/samsung/exynos-srom.txt           |  12 ++
 arch/arm/boot/dts/exynos4.dtsi                     |   5 +
 arch/arm/boot/dts/exynos5.dtsi                     |   5 +
 arch/arm/mach-exynos/Kconfig                       |   2 +
 arch/arm/mach-exynos/common.h                      |   2 -
 arch/arm/mach-exynos/exynos.c                      |  22 ----
 arch/arm/mach-exynos/include/mach/map.h            |   8 --
 arch/arm/mach-exynos/regs-srom.h                   |  53 --------
 arch/arm/mach-exynos/suspend.c                     |  20 +--
 arch/arm/plat-samsung/include/plat/map-s5p.h       |   1 -
 drivers/soc/Kconfig                                |   1 +
 drivers/soc/Makefile                               |   1 +
 drivers/soc/samsung/Kconfig                        |  13 ++
 drivers/soc/samsung/Makefile                       |   1 +
 drivers/soc/samsung/exynos-srom.c                  | 143 +++++++++++++++++++++
 drivers/soc/samsung/exynos-srom.h                  |  51 ++++++++
 16 files changed, 236 insertions(+), 104 deletions(-)
 create mode 100644 Documentation/devicetree/bindings/arm/samsung/exynos-srom.txt
 delete mode 100644 arch/arm/mach-exynos/regs-srom.h
 create mode 100644 drivers/soc/samsung/Kconfig
 create mode 100644 drivers/soc/samsung/Makefile
 create mode 100644 drivers/soc/samsung/exynos-srom.c
 create mode 100644 drivers/soc/samsung/exynos-srom.h

-- 
2.4.5



From pankaj.dubey at samsung.com  Mon Aug 24 01:02:22 2015
From: pankaj.dubey at samsung.com (Pankaj Dubey)
Date: Mon, 24 Aug 2015 13:32:22 +0530
Subject: [PATCH v2 1/7] ARM: EXYNOS: remove unused static mapping of CMU for
 exynos5
In-Reply-To: <1440403348-8974-1-git-send-email-pankaj.dubey@samsung.com>
References: <1440403348-8974-1-git-send-email-pankaj.dubey@samsung.com>
Message-ID: <1440403348-8974-2-git-send-email-pankaj.dubey@samsung.com>

Remove unused static mapping of exynos5 CMU and related code.

Signed-off-by: Pankaj Dubey <pankaj.dubey at samsung.com>
---
 arch/arm/mach-exynos/exynos.c           | 5 -----
 arch/arm/mach-exynos/include/mach/map.h | 1 -
 2 files changed, 6 deletions(-)

diff --git a/arch/arm/mach-exynos/exynos.c b/arch/arm/mach-exynos/exynos.c
index 1c47aee..524aa6f 100644
--- a/arch/arm/mach-exynos/exynos.c
+++ b/arch/arm/mach-exynos/exynos.c
@@ -70,11 +70,6 @@ static struct map_desc exynos5_iodesc[] __initdata = {
 		.pfn		= __phys_to_pfn(EXYNOS5_PA_SROMC),
 		.length		= SZ_4K,
 		.type		= MT_DEVICE,
-	}, {
-		.virtual	= (unsigned long)S5P_VA_CMU,
-		.pfn		= __phys_to_pfn(EXYNOS5_PA_CMU),
-		.length		= 144 * SZ_1K,
-		.type		= MT_DEVICE,
 	},
 };
 
diff --git a/arch/arm/mach-exynos/include/mach/map.h b/arch/arm/mach-exynos/include/mach/map.h
index de3ae59..a2acba3 100644
--- a/arch/arm/mach-exynos/include/mach/map.h
+++ b/arch/arm/mach-exynos/include/mach/map.h
@@ -25,7 +25,6 @@
 #define EXYNOS_PA_CHIPID		0x10000000
 
 #define EXYNOS4_PA_CMU			0x10030000
-#define EXYNOS5_PA_CMU			0x10010000
 
 #define EXYNOS4_PA_DMC0			0x10400000
 #define EXYNOS4_PA_DMC1			0x10410000
-- 
2.4.5



From pankaj.dubey at samsung.com  Mon Aug 24 01:02:23 2015
From: pankaj.dubey at samsung.com (Pankaj Dubey)
Date: Mon, 24 Aug 2015 13:32:23 +0530
Subject: [PATCH v2 2/7] ARM: EXYNOS: code cleanup in map.h
In-Reply-To: <1440403348-8974-1-git-send-email-pankaj.dubey@samsung.com>
References: <1440403348-8974-1-git-send-email-pankaj.dubey@samsung.com>
Message-ID: <1440403348-8974-3-git-send-email-pankaj.dubey@samsung.com>

Remove unused exynos5440 uart offset macro.

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

diff --git a/arch/arm/mach-exynos/include/mach/map.h b/arch/arm/mach-exynos/include/mach/map.h
index a2acba3..86d8085 100644
--- a/arch/arm/mach-exynos/include/mach/map.h
+++ b/arch/arm/mach-exynos/include/mach/map.h
@@ -35,8 +35,4 @@
 #define EXYNOS4_PA_SROMC		0x12570000
 #define EXYNOS5_PA_SROMC		0x12250000
 
-/* Compatibility UART */
-
-#define EXYNOS5440_PA_UART0		0x000B0000
-
 #endif /* __ASM_ARCH_MAP_H */
-- 
2.4.5



From pankaj.dubey at samsung.com  Mon Aug 24 01:02:24 2015
From: pankaj.dubey at samsung.com (Pankaj Dubey)
Date: Mon, 24 Aug 2015 13:32:24 +0530
Subject: [PATCH v2 3/7] drivers: soc: add support for exynos SROM driver
In-Reply-To: <1440403348-8974-1-git-send-email-pankaj.dubey@samsung.com>
References: <1440403348-8974-1-git-send-email-pankaj.dubey@samsung.com>
Message-ID: <1440403348-8974-4-git-send-email-pankaj.dubey@samsung.com>

This patch adds Exynos SROM controller driver which will handle
save restore of SROM registers during S2R.

Signed-off-by: Pankaj Dubey <pankaj.dubey at samsung.com>
---
 drivers/soc/Kconfig               |   1 +
 drivers/soc/Makefile              |   1 +
 drivers/soc/samsung/Kconfig       |  13 ++++
 drivers/soc/samsung/Makefile      |   1 +
 drivers/soc/samsung/exynos-srom.c | 143 ++++++++++++++++++++++++++++++++++++++
 drivers/soc/samsung/exynos-srom.h |  51 ++++++++++++++
 6 files changed, 210 insertions(+)
 create mode 100644 drivers/soc/samsung/Kconfig
 create mode 100644 drivers/soc/samsung/Makefile
 create mode 100644 drivers/soc/samsung/exynos-srom.c
 create mode 100644 drivers/soc/samsung/exynos-srom.h

diff --git a/drivers/soc/Kconfig b/drivers/soc/Kconfig
index 96ddecb..69107c9 100644
--- a/drivers/soc/Kconfig
+++ b/drivers/soc/Kconfig
@@ -2,6 +2,7 @@ menu "SOC (System On Chip) specific Drivers"
 
 source "drivers/soc/mediatek/Kconfig"
 source "drivers/soc/qcom/Kconfig"
+source "drivers/soc/samsung/Kconfig"
 source "drivers/soc/sunxi/Kconfig"
 source "drivers/soc/ti/Kconfig"
 source "drivers/soc/versatile/Kconfig"
diff --git a/drivers/soc/Makefile b/drivers/soc/Makefile
index 7dc7c0d..34c4398 100644
--- a/drivers/soc/Makefile
+++ b/drivers/soc/Makefile
@@ -4,6 +4,7 @@
 
 obj-$(CONFIG_ARCH_MEDIATEK)	+= mediatek/
 obj-$(CONFIG_ARCH_QCOM)		+= qcom/
+obj-$(CONFIG_SOC_SAMSUNG)	+= samsung/
 obj-$(CONFIG_ARCH_SUNXI)	+= sunxi/
 obj-$(CONFIG_ARCH_TEGRA)	+= tegra/
 obj-$(CONFIG_SOC_TI)		+= ti/
diff --git a/drivers/soc/samsung/Kconfig b/drivers/soc/samsung/Kconfig
new file mode 100644
index 0000000..ea4bc2a
--- /dev/null
+++ b/drivers/soc/samsung/Kconfig
@@ -0,0 +1,13 @@
+#
+# SAMSUNG SoC drivers
+#
+menu "Samsung SOC driver support"
+
+config SOC_SAMSUNG
+	bool
+
+config EXYNOS_SROM
+	bool
+	depends on ARM && ARCH_EXYNOS
+
+endmenu
diff --git a/drivers/soc/samsung/Makefile b/drivers/soc/samsung/Makefile
new file mode 100644
index 0000000..9c554d5
--- /dev/null
+++ b/drivers/soc/samsung/Makefile
@@ -0,0 +1 @@
+obj-$(CONFIG_EXYNOS_SROM)	+= exynos-srom.o
diff --git a/drivers/soc/samsung/exynos-srom.c b/drivers/soc/samsung/exynos-srom.c
new file mode 100644
index 0000000..d7c4aa7
--- /dev/null
+++ b/drivers/soc/samsung/exynos-srom.c
@@ -0,0 +1,143 @@
+/*
+ * Copyright (c) 2015 Samsung Electronics Co., Ltd.
+ *	      http://www.samsung.com/
+ *
+ * EXYNOS - SROM Controller support
+ * Author: Pankaj Dubey <pankaj.dubey at samsung.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.
+ */
+
+#include <linux/io.h>
+#include <linux/of.h>
+#include <linux/of_address.h>
+#include <linux/of_platform.h>
+#include <linux/platform_device.h>
+#include <linux/slab.h>
+#include "exynos-srom.h"
+
+static void __iomem *exynos_srom_base;
+
+static const unsigned long exynos_srom_offsets[] = {
+	/* SROM side */
+	EXYNOS_SROM_BW,
+	EXYNOS_SROM_BC0,
+	EXYNOS_SROM_BC1,
+	EXYNOS_SROM_BC2,
+	EXYNOS_SROM_BC3,
+};
+
+/**
+ * struct exynos_srom_reg_dump: register dump of SROM Controller registers.
+ * @offset: srom register offset from the controller base address.
+ * @value: the value of register under the offset.
+ */
+struct exynos_srom_reg_dump {
+	u32     offset;
+	u32     value;
+};
+
+static struct exynos_srom_reg_dump *exynos_srom_regs;
+
+static struct exynos_srom_reg_dump *exynos_srom_alloc_reg_dump(
+		const unsigned long *rdump,
+		unsigned long nr_rdump)
+{
+	struct exynos_srom_reg_dump *rd;
+	unsigned int i;
+
+	rd = kcalloc(nr_rdump, sizeof(*rd), GFP_KERNEL);
+	if (!rd)
+		return NULL;
+
+	for (i = 0; i < nr_rdump; ++i)
+		rd[i].offset = rdump[i];
+
+	return rd;
+}
+
+static const struct of_device_id of_exynos_srom_ids[] = {
+	{
+		.compatible	= "samsung,exynos-srom",
+	},
+	{},
+};
+
+static int exynos_srom_probe(struct platform_device *pdev)
+{
+	struct device_node *np;
+	struct device *dev = &pdev->dev;
+
+	np = dev->of_node;
+	exynos_srom_base = of_iomap(np, 0);
+
+	if (!exynos_srom_base) {
+		pr_err("iomap of exynos srom controller failed\n");
+		return -ENOMEM;
+	}
+
+	exynos_srom_regs = exynos_srom_alloc_reg_dump(exynos_srom_offsets,
+			sizeof(exynos_srom_offsets));
+
+	if (!exynos_srom_regs) {
+		iounmap(exynos_srom_regs);
+		return -ENOMEM;
+	}
+
+	return 0;
+}
+
+#ifdef CONFIG_PM_SLEEP
+static void exynos_srom_save(void __iomem *base,
+				    struct exynos_srom_reg_dump *rd,
+				    unsigned int num_regs)
+{
+	for (; num_regs > 0; --num_regs, ++rd)
+		rd->value = readl(base + rd->offset);
+
+}
+
+static void exynos_srom_restore(void __iomem *base,
+				      const struct exynos_srom_reg_dump *rd,
+				      unsigned int num_regs)
+{
+	for (; num_regs > 0; --num_regs, ++rd)
+		writel(rd->value, base + rd->offset);
+
+}
+
+static int exynos_srom_suspend(struct device *dev)
+{
+	exynos_srom_save(exynos_srom_base, exynos_srom_regs,
+				ARRAY_SIZE(exynos_srom_offsets));
+
+	return 0;
+}
+
+static int exynos_srom_resume(struct device *dev)
+{
+	exynos_srom_restore(exynos_srom_base, exynos_srom_regs,
+				ARRAY_SIZE(exynos_srom_offsets));
+
+	return 0;
+}
+#endif
+
+static SIMPLE_DEV_PM_OPS(exynos_srom_pm_ops, exynos_srom_suspend, exynos_srom_resume);
+
+static struct platform_driver exynos_srom_driver = {
+	.probe = exynos_srom_probe,
+	.driver = {
+		.name = "exynos-srom",
+		.of_match_table = of_exynos_srom_ids,
+		.pm = &exynos_srom_pm_ops,
+	},
+};
+
+static int __init exynos_srom_init(void)
+{
+	return platform_driver_register(&exynos_srom_driver);
+}
+device_initcall(exynos_srom_init);
diff --git a/drivers/soc/samsung/exynos-srom.h b/drivers/soc/samsung/exynos-srom.h
new file mode 100644
index 0000000..34660c6
--- /dev/null
+++ b/drivers/soc/samsung/exynos-srom.h
@@ -0,0 +1,51 @@
+/*
+ * Copyright (c) 2015 Samsung Electronics Co., Ltd.
+ *		http://www.samsung.com
+ *
+ * Exynos SROMC register definitions
+ *
+ * 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.
+*/
+
+#ifndef __EXYNOS_SROM_H
+#define __EXYNOS_SROM_H __FILE__
+
+#define EXYNOS_SROMREG(x)		(x)
+
+#define EXYNOS_SROM_BW		EXYNOS_SROMREG(0x0)
+#define EXYNOS_SROM_BC0		EXYNOS_SROMREG(0x4)
+#define EXYNOS_SROM_BC1		EXYNOS_SROMREG(0x8)
+#define EXYNOS_SROM_BC2		EXYNOS_SROMREG(0xc)
+#define EXYNOS_SROM_BC3		EXYNOS_SROMREG(0x10)
+#define EXYNOS_SROM_BC4		EXYNOS_SROMREG(0x14)
+#define EXYNOS_SROM_BC5		EXYNOS_SROMREG(0x18)
+
+/* one register BW holds 4 x 4-bit packed settings for NCS0 - NCS3 */
+
+#define EXYNOS_SROM_BW__DATAWIDTH__SHIFT	0
+#define EXYNOS_SROM_BW__ADDRMODE__SHIFT		1
+#define EXYNOS_SROM_BW__WAITENABLE__SHIFT	2
+#define EXYNOS_SROM_BW__BYTEENABLE__SHIFT	3
+
+#define EXYNOS_SROM_BW__CS_MASK			0xf
+
+#define EXYNOS_SROM_BW__NCS0__SHIFT		0
+#define EXYNOS_SROM_BW__NCS1__SHIFT		4
+#define EXYNOS_SROM_BW__NCS2__SHIFT		8
+#define EXYNOS_SROM_BW__NCS3__SHIFT		12
+#define EXYNOS_SROM_BW__NCS4__SHIFT		16
+#define EXYNOS_SROM_BW__NCS5__SHIFT		20
+
+/* applies to same to BCS0 - BCS3 */
+
+#define EXYNOS_SROM_BCX__PMC__SHIFT		0
+#define EXYNOS_SROM_BCX__TACP__SHIFT		4
+#define EXYNOS_SROM_BCX__TCAH__SHIFT		8
+#define EXYNOS_SROM_BCX__TCOH__SHIFT		12
+#define EXYNOS_SROM_BCX__TACC__SHIFT		16
+#define EXYNOS_SROM_BCX__TCOS__SHIFT		24
+#define EXYNOS_SROM_BCX__TACS__SHIFT		28
+
+#endif /* __EXYNOS_SROM_H */
-- 
2.4.5



From pankaj.dubey at samsung.com  Mon Aug 24 01:02:25 2015
From: pankaj.dubey at samsung.com (Pankaj Dubey)
Date: Mon, 24 Aug 2015 13:32:25 +0530
Subject: [PATCH v2 4/7] ARM: EXYNOS: Remove SROM related register settings from
 mach-exynos
In-Reply-To: <1440403348-8974-1-git-send-email-pankaj.dubey@samsung.com>
References: <1440403348-8974-1-git-send-email-pankaj.dubey@samsung.com>
Message-ID: <1440403348-8974-5-git-send-email-pankaj.dubey@samsung.com>

As now we have dedicated driver for SROM controller, it will take care
of saving register banks during S2R so we can safely remove these
settings from mach-exynos.

Signed-off-by: Pankaj Dubey <pankaj.dubey at samsung.com>
---
 arch/arm/mach-exynos/Kconfig                 |  2 ++
 arch/arm/mach-exynos/common.h                |  2 --
 arch/arm/mach-exynos/exynos.c                | 17 ---------
 arch/arm/mach-exynos/include/mach/map.h      |  3 --
 arch/arm/mach-exynos/regs-srom.h             | 53 ----------------------------
 arch/arm/mach-exynos/suspend.c               | 20 ++---------
 arch/arm/plat-samsung/include/plat/map-s5p.h |  1 -
 7 files changed, 4 insertions(+), 94 deletions(-)
 delete mode 100644 arch/arm/mach-exynos/regs-srom.h

diff --git a/arch/arm/mach-exynos/Kconfig b/arch/arm/mach-exynos/Kconfig
index 3a10f1a..7c917ef 100644
--- a/arch/arm/mach-exynos/Kconfig
+++ b/arch/arm/mach-exynos/Kconfig
@@ -27,6 +27,8 @@ menuconfig ARCH_EXYNOS
 	select SRAM
 	select THERMAL
 	select MFD_SYSCON
+	select SOC_SAMSUNG
+	select EXYNOS_SROM
 	help
 	  Support for SAMSUNG EXYNOS SoCs (EXYNOS4/5)
 
diff --git a/arch/arm/mach-exynos/common.h b/arch/arm/mach-exynos/common.h
index 1534925..1c04741 100644
--- a/arch/arm/mach-exynos/common.h
+++ b/arch/arm/mach-exynos/common.h
@@ -108,8 +108,6 @@ IS_SAMSUNG_CPU(exynos5800, EXYNOS5800_SOC_ID, EXYNOS5_SOC_MASK)
 
 #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;
diff --git a/arch/arm/mach-exynos/exynos.c b/arch/arm/mach-exynos/exynos.c
index 524aa6f..4ffb90e 100644
--- a/arch/arm/mach-exynos/exynos.c
+++ b/arch/arm/mach-exynos/exynos.c
@@ -37,11 +37,6 @@ void __iomem *pmu_base_addr;
 
 static struct map_desc exynos4_iodesc[] __initdata = {
 	{
-		.virtual	= (unsigned long)S5P_VA_SROMC,
-		.pfn		= __phys_to_pfn(EXYNOS4_PA_SROMC),
-		.length		= SZ_4K,
-		.type		= MT_DEVICE,
-	}, {
 		.virtual	= (unsigned long)S5P_VA_CMU,
 		.pfn		= __phys_to_pfn(EXYNOS4_PA_CMU),
 		.length		= SZ_128K,
@@ -64,15 +59,6 @@ static struct map_desc exynos4_iodesc[] __initdata = {
 	},
 };
 
-static struct map_desc exynos5_iodesc[] __initdata = {
-	{
-		.virtual	= (unsigned long)S5P_VA_SROMC,
-		.pfn		= __phys_to_pfn(EXYNOS5_PA_SROMC),
-		.length		= SZ_4K,
-		.type		= MT_DEVICE,
-	},
-};
-
 static struct platform_device exynos_cpuidle = {
 	.name              = "exynos_cpuidle",
 #ifdef CONFIG_ARM_EXYNOS_CPUIDLE
@@ -144,9 +130,6 @@ static void __init exynos_map_io(void)
 {
 	if (soc_is_exynos4())
 		iotable_init(exynos4_iodesc, ARRAY_SIZE(exynos4_iodesc));
-
-	if (soc_is_exynos5())
-		iotable_init(exynos5_iodesc, ARRAY_SIZE(exynos5_iodesc));
 }
 
 static void __init exynos_init_io(void)
diff --git a/arch/arm/mach-exynos/include/mach/map.h b/arch/arm/mach-exynos/include/mach/map.h
index 86d8085..351e839 100644
--- a/arch/arm/mach-exynos/include/mach/map.h
+++ b/arch/arm/mach-exynos/include/mach/map.h
@@ -32,7 +32,4 @@
 #define EXYNOS4_PA_COREPERI		0x10500000
 #define EXYNOS4_PA_L2CC			0x10502000
 
-#define EXYNOS4_PA_SROMC		0x12570000
-#define EXYNOS5_PA_SROMC		0x12250000
-
 #endif /* __ASM_ARCH_MAP_H */
diff --git a/arch/arm/mach-exynos/regs-srom.h b/arch/arm/mach-exynos/regs-srom.h
deleted file mode 100644
index 5c4d442..0000000
--- a/arch/arm/mach-exynos/regs-srom.h
+++ /dev/null
@@ -1,53 +0,0 @@
-/*
- * Copyright (c) 2010 Samsung Electronics Co., Ltd.
- *		http://www.samsung.com
- *
- * S5P SROMC register definitions
- *
- * 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.
-*/
-
-#ifndef __PLAT_SAMSUNG_REGS_SROM_H
-#define __PLAT_SAMSUNG_REGS_SROM_H __FILE__
-
-#include <mach/map.h>
-
-#define S5P_SROMREG(x)		(S5P_VA_SROMC + (x))
-
-#define S5P_SROM_BW		S5P_SROMREG(0x0)
-#define S5P_SROM_BC0		S5P_SROMREG(0x4)
-#define S5P_SROM_BC1		S5P_SROMREG(0x8)
-#define S5P_SROM_BC2		S5P_SROMREG(0xc)
-#define S5P_SROM_BC3		S5P_SROMREG(0x10)
-#define S5P_SROM_BC4		S5P_SROMREG(0x14)
-#define S5P_SROM_BC5		S5P_SROMREG(0x18)
-
-/* one register BW holds 4 x 4-bit packed settings for NCS0 - NCS3 */
-
-#define S5P_SROM_BW__DATAWIDTH__SHIFT		0
-#define S5P_SROM_BW__ADDRMODE__SHIFT		1
-#define S5P_SROM_BW__WAITENABLE__SHIFT		2
-#define S5P_SROM_BW__BYTEENABLE__SHIFT		3
-
-#define S5P_SROM_BW__CS_MASK			0xf
-
-#define S5P_SROM_BW__NCS0__SHIFT		0
-#define S5P_SROM_BW__NCS1__SHIFT		4
-#define S5P_SROM_BW__NCS2__SHIFT		8
-#define S5P_SROM_BW__NCS3__SHIFT		12
-#define S5P_SROM_BW__NCS4__SHIFT		16
-#define S5P_SROM_BW__NCS5__SHIFT		20
-
-/* applies to same to BCS0 - BCS3 */
-
-#define S5P_SROM_BCX__PMC__SHIFT		0
-#define S5P_SROM_BCX__TACP__SHIFT		4
-#define S5P_SROM_BCX__TCAH__SHIFT		8
-#define S5P_SROM_BCX__TCOH__SHIFT		12
-#define S5P_SROM_BCX__TACC__SHIFT		16
-#define S5P_SROM_BCX__TCOS__SHIFT		24
-#define S5P_SROM_BCX__TACS__SHIFT		28
-
-#endif /* __PLAT_SAMSUNG_REGS_SROM_H */
diff --git a/arch/arm/mach-exynos/suspend.c b/arch/arm/mach-exynos/suspend.c
index e00eb39..21abd9b 100644
--- a/arch/arm/mach-exynos/suspend.c
+++ b/arch/arm/mach-exynos/suspend.c
@@ -31,12 +31,13 @@
 #include <asm/smp_scu.h>
 #include <asm/suspend.h>
 
+#include <mach/map.h>
+
 #include <plat/pm-common.h>
 
 #include "common.h"
 #include "exynos-pmu.h"
 #include "regs-pmu.h"
-#include "regs-srom.h"
 
 #define REG_TABLE_END (-1U)
 
@@ -52,15 +53,6 @@ struct exynos_wkup_irq {
 	u32 mask;
 };
 
-static struct sleep_save exynos_core_save[] = {
-	/* SROM side */
-	SAVE_ITEM(S5P_SROM_BW),
-	SAVE_ITEM(S5P_SROM_BC0),
-	SAVE_ITEM(S5P_SROM_BC1),
-	SAVE_ITEM(S5P_SROM_BC2),
-	SAVE_ITEM(S5P_SROM_BC3),
-};
-
 struct exynos_pm_data {
 	const struct exynos_wkup_irq *wkup_irq;
 	unsigned int wake_disable_mask;
@@ -339,8 +331,6 @@ static void exynos_pm_prepare(void)
 	/* Set wake-up mask registers */
 	exynos_pm_set_wakeup_mask();
 
-	s3c_pm_do_save(exynos_core_save, ARRAY_SIZE(exynos_core_save));
-
 	exynos_pm_enter_sleep_mode();
 
 	/* ensure at least INFORM0 has the resume address */
@@ -371,8 +361,6 @@ static void exynos5420_pm_prepare(void)
 	/* Set wake-up mask registers */
 	exynos_pm_set_wakeup_mask();
 
-	s3c_pm_do_save(exynos_core_save, ARRAY_SIZE(exynos_core_save));
-
 	exynos_pmu_spare3 = pmu_raw_readl(S5P_PMU_SPARE3);
 	/*
 	 * The cpu state needs to be saved and restored so that the
@@ -463,8 +451,6 @@ static void exynos_pm_resume(void)
 	/* For release retention */
 	exynos_pm_release_retention();
 
-	s3c_pm_do_restore_core(exynos_core_save, ARRAY_SIZE(exynos_core_save));
-
 	if (cpuid == ARM_CPU_PART_CORTEX_A9)
 		scu_enable(S5P_VA_SCU);
 
@@ -531,8 +517,6 @@ static void exynos5420_pm_resume(void)
 
 	pmu_raw_writel(exynos_pmu_spare3, S5P_PMU_SPARE3);
 
-	s3c_pm_do_restore_core(exynos_core_save, ARRAY_SIZE(exynos_core_save));
-
 early_wakeup:
 
 	tmp = pmu_raw_readl(EXYNOS5420_SFR_AXI_CGDIS1);
diff --git a/arch/arm/plat-samsung/include/plat/map-s5p.h b/arch/arm/plat-samsung/include/plat/map-s5p.h
index f5cf2bd..e555769 100644
--- a/arch/arm/plat-samsung/include/plat/map-s5p.h
+++ b/arch/arm/plat-samsung/include/plat/map-s5p.h
@@ -18,7 +18,6 @@
 
 #define S5P_VA_DMC0		S3C_ADDR(0x02440000)
 #define S5P_VA_DMC1		S3C_ADDR(0x02480000)
-#define S5P_VA_SROMC		S3C_ADDR(0x024C0000)
 
 #define S5P_VA_COREPERI_BASE	S3C_ADDR(0x02800000)
 #define S5P_VA_COREPERI(x)	(S5P_VA_COREPERI_BASE + (x))
-- 
2.4.5



From pankaj.dubey at samsung.com  Mon Aug 24 01:02:26 2015
From: pankaj.dubey at samsung.com (Pankaj Dubey)
Date: Mon, 24 Aug 2015 13:32:26 +0530
Subject: [PATCH v2 5/7] ARM: dts: add SROM device node for exynos4
In-Reply-To: <1440403348-8974-1-git-send-email-pankaj.dubey@samsung.com>
References: <1440403348-8974-1-git-send-email-pankaj.dubey@samsung.com>
Message-ID: <1440403348-8974-6-git-send-email-pankaj.dubey@samsung.com>

Add device node of SROM controller for exynos4.

CC: Rob Herring <robh+dt at kernel.org>
CC: Mark Rutland <mark.rutland at arm.com>
CC: Ian Campbell <ijc+devicetree at hellion.org.uk>
Signed-off-by: Pankaj Dubey <pankaj.dubey at 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 98c0a36..b0732d7 100644
--- a/arch/arm/boot/dts/exynos4.dtsi
+++ b/arch/arm/boot/dts/exynos4.dtsi
@@ -76,6 +76,11 @@
 		reg = <0x10000000 0x100>;
 	};
 
+	sromc at 12570000 {
+		compatible = "samsung,exynos-srom";
+		reg = <0x12570000 0x10>;
+	};
+
 	mipi_phy: video-phy at 10020710 {
 		compatible = "samsung,s5pv210-mipi-video-phy";
 		#phy-cells = <1>;
-- 
2.4.5



From pankaj.dubey at samsung.com  Mon Aug 24 01:02:27 2015
From: pankaj.dubey at samsung.com (Pankaj Dubey)
Date: Mon, 24 Aug 2015 13:32:27 +0530
Subject: [PATCH v2 6/7] ARM: dts: add SROM device node for exynos5
In-Reply-To: <1440403348-8974-1-git-send-email-pankaj.dubey@samsung.com>
References: <1440403348-8974-1-git-send-email-pankaj.dubey@samsung.com>
Message-ID: <1440403348-8974-7-git-send-email-pankaj.dubey@samsung.com>

Add SROM controller device node for exynos5.

CC: Rob Herring <robh+dt at kernel.org>
CC: Mark Rutland <mark.rutland at arm.com>
CC: Ian Campbell <ijc+devicetree at hellion.org.uk>
Signed-off-by: Pankaj Dubey <pankaj.dubey at samsung.com>
---
 arch/arm/boot/dts/exynos5.dtsi | 5 +++++
 1 file changed, 5 insertions(+)

diff --git a/arch/arm/boot/dts/exynos5.dtsi b/arch/arm/boot/dts/exynos5.dtsi
index 110dbd4..b5d3437 100644
--- a/arch/arm/boot/dts/exynos5.dtsi
+++ b/arch/arm/boot/dts/exynos5.dtsi
@@ -30,6 +30,11 @@
 		reg = <0x10000000 0x100>;
 	};
 
+	sromc at 12250000 {
+		compatible = "samsung,exynos-srom";
+		reg = <0x12250000 0x10>;
+	};
+
 	combiner: interrupt-controller at 10440000 {
 		compatible = "samsung,exynos4210-combiner";
 		#interrupt-cells = <2>;
-- 
2.4.5



From alexandre.belloni at free-electrons.com  Mon Aug 24 01:08:00 2015
From: alexandre.belloni at free-electrons.com (Alexandre Belloni)
Date: Mon, 24 Aug 2015 10:08:00 +0200
Subject: [PATCH v3 2/2] drivers: rtc: add xilinx zynqmp rtc driver
In-Reply-To: <55DACC5A.80707@xilinx.com>
References: <1439978002-12157-1-git-send-email-suneel.garapati@xilinx.com>
 <1439978002-12157-2-git-send-email-suneel.garapati@xilinx.com>
 <20150824074310.GF13155@piout.net> <55DACC5A.80707@xilinx.com>
Message-ID: <20150824080800.GG13155@piout.net>

On 24/08/2015 at 09:48:42 +0200, Michal Simek wrote :
> On 08/24/2015 09:43 AM, Alexandre Belloni wrote:
> > On 19/08/2015 at 15:23:22 +0530, Suneel Garapati wrote :
> >> adds support for RTC controller found on
> >> Xilinx Zynq Ultrascale+ MPSoC platform.
> >>
> >> Signed-off-by: Suneel Garapati <suneel.garapati at xilinx.com>
> >> ---
> >> Changes v3 
> >> - fix checkpatch errors 
> >> - check time in secs arg against max sec val 
> >> - order header files 
> >> - use ptr_err_or_zero macro 
> >> - use time64 variants 
> >> Changes v2 
> >> - change alm to alarm 
> >> ---
> >>  drivers/rtc/Kconfig      |   7 ++
> >>  drivers/rtc/Makefile     |   1 +
> >>  drivers/rtc/rtc-zynqmp.c | 279 +++++++++++++++++++++++++++++++++++++++++++++++
> >>  3 files changed, 287 insertions(+)
> >>  create mode 100644 drivers/rtc/rtc-zynqmp.c
> >>
> > Applied, thanks.
> > 
> 

Actually, I got the following message:
A message that you sent could not be delivered to one or more of its
recipients. This is a permanent error. The following address(es) failed:

  suneel.garapati at xilinx.com
    Unknown User

I'm not fond of carrying patches with uncontactable authors. Is that a
permanent error?

-- 
Alexandre Belloni, Free Electrons
Embedded Linux, Kernel and Android engineering
http://free-electrons.com


From pankaj.dubey at samsung.com  Mon Aug 24 01:02:28 2015
From: pankaj.dubey at samsung.com (Pankaj Dubey)
Date: Mon, 24 Aug 2015 13:32:28 +0530
Subject: [PATCH v2 7/7] Documentation: dt-bindings: add exynos-srom binding
 information
In-Reply-To: <1440403348-8974-1-git-send-email-pankaj.dubey@samsung.com>
References: <1440403348-8974-1-git-send-email-pankaj.dubey@samsung.com>
Message-ID: <1440403348-8974-8-git-send-email-pankaj.dubey@samsung.com>

This patch adds exynos-srom binding information for SROM Controller
driver on Exynos SoCs.

CC: Rob Herring <robh+dt at kernel.org>
CC: Mark Rutland <mark.rutland at arm.com>
CC: Ian Campbell <ijc+devicetree at hellion.org.uk>
Signed-off-by: Pankaj Dubey <pankaj.dubey at samsung.com>
---
 .../devicetree/bindings/arm/samsung/exynos-srom.txt          | 12 ++++++++++++
 1 file changed, 12 insertions(+)
 create mode 100644 Documentation/devicetree/bindings/arm/samsung/exynos-srom.txt

diff --git a/Documentation/devicetree/bindings/arm/samsung/exynos-srom.txt b/Documentation/devicetree/bindings/arm/samsung/exynos-srom.txt
new file mode 100644
index 0000000..33886d5
--- /dev/null
+++ b/Documentation/devicetree/bindings/arm/samsung/exynos-srom.txt
@@ -0,0 +1,12 @@
+SAMSUNG Exynos SoCs SROM Controller driver.
+
+Required properties:
+- compatible : Should contain "samsung,exynos-srom".
+
+- reg: offset and length of the register set
+
+Example:
+	sromc at 12570000 {
+		compatible = "samsung,exynos-srom";
+		reg = <0x12570000 0x10>;
+	};
-- 
2.4.5



From shawn.lin at rock-chips.com  Mon Aug 24 01:12:26 2015
From: shawn.lin at rock-chips.com (Shawn Lin)
Date: Mon, 24 Aug 2015 16:12:26 +0800
Subject: [PATCH] clk: rockchip: disable init state before mmc card
 initialization
Message-ID: <1440403946-13266-1-git-send-email-shawn.lin@rock-chips.com>

mmc host controller's IO input/output timing is unpredictable if
bootloader execute tuning for HS200 mode. It might make kernel failed
to initialize mmc card in identification mode. The root cause is
tuning phase and degree setting for HS200 mode in bootloader aren't
applicable to that of identification mode in kernel stage. Anyway, we
can't force all bootloaders to disable tuning phase and degree setting
before into kernel. Simply disable it in rockchip_clk_register_mmc.

Signed-off-by: Shawn Lin <shawn.lin at rock-chips.com>
---

 drivers/clk/rockchip/clk-mmc-phase.c | 20 ++++++++++++++++++++
 1 file changed, 20 insertions(+)

diff --git a/drivers/clk/rockchip/clk-mmc-phase.c b/drivers/clk/rockchip/clk-mmc-phase.c
index e9f8df32..02b6f3d 100644
--- a/drivers/clk/rockchip/clk-mmc-phase.c
+++ b/drivers/clk/rockchip/clk-mmc-phase.c
@@ -38,6 +38,9 @@ static unsigned long rockchip_mmc_recalc(struct clk_hw *hw,
 #define ROCKCHIP_MMC_DEGREE_MASK 0x3
 #define ROCKCHIP_MMC_DELAYNUM_OFFSET 2
 #define ROCKCHIP_MMC_DELAYNUM_MASK (0xff << ROCKCHIP_MMC_DELAYNUM_OFFSET)
+#define ROCKCHIP_MMC_INIT_STATE_DISABLE (0x1)
+#define ROCKCHIP_MMC_INIT_STATE_SHIFT (0)
+#define ROCKCHIP_MMC_INIT_STATE_MASK  (0x1)
 
 #define PSECS_PER_SEC 1000000000000LL
 
@@ -119,6 +122,21 @@ static const struct clk_ops rockchip_mmc_clk_ops = {
 	.set_phase	= rockchip_mmc_set_phase,
 };
 
+static void rockchip_clk_mmc_disable_init(struct rockchip_mmc_clock *mmc_clock)
+{
+	if (mmc_clock->shift != ROCKCHIP_MMC_INIT_STATE_SHIFT)
+		return;
+
+	writel(HIWORD_UPDATE(ROCKCHIP_MMC_INIT_STATE_DISABLE,
+			     ROCKCHIP_MMC_INIT_STATE_MASK,
+			     mmc_clock->shift),
+	       mmc_clock->reg);
+
+	pr_debug("%s: clear mmc init state to %d", __func__,
+		 (readl(mmc_clock->reg) >> (mmc_clock->shift)) &
+		 ROCKCHIP_MMC_INIT_STATE_MASK);
+}
+
 struct clk *rockchip_clk_register_mmc(const char *name,
 				const char *const *parent_names, u8 num_parents,
 				void __iomem *reg, int shift)
@@ -139,6 +157,8 @@ struct clk *rockchip_clk_register_mmc(const char *name,
 	mmc_clock->reg = reg;
 	mmc_clock->shift = shift;
 
+	rockchip_clk_mmc_disable_init(mmc_clock);
+
 	if (name)
 		init.name = name;
 
-- 
2.3.7




From varada at codeaurora.org  Mon Aug 24 01:23:39 2015
From: varada at codeaurora.org (Varadarajan Narayanan)
Date: Mon, 24 Aug 2015 13:53:39 +0530
Subject: [PATCH v2] qcom: ipq40xx: Add basic board/dts support for
 IPQ40XX SoC
In-Reply-To: <20150821162133.GF13472@usrtlx11787.corpusers.net>
References: <20150821103253.GA27466@codeaurora.org>
 <20150821162133.GF13472@usrtlx11787.corpusers.net>
Message-ID: <20150824082339.GA329@codeaurora.org>

On Fri, Aug 21, 2015 at 09:21:33AM -0700, Bjorn Andersson wrote:

> On Fri 21 Aug 03:32 PDT 2015, Varadarajan Narayanan wrote:
>
> > Add initial dts files and SoC support for IPQ40XX
> >
> > Signed-off-by: Varadarajan Narayanan <varada at codeaurora.org>
> > ---
> > Changes in v2:
> >   - Added devicetree bindings documentation
> >
> >  .../devicetree/bindings/clock/qca,gcnt.txt         | 14 ++++
> >  Documentation/devicetree/bindings/ipq.txt          | 16 ++++
> >  arch/arm/boot/dts/Makefile                         |  3 +-
> >  arch/arm/boot/dts/qcom-ipq40xx-r3pc.dts            | 33 +++++++++
> >  arch/arm/boot/dts/qcom-ipq40xx.dtsi                | 86 ++++++++++++++++++++++
> >  arch/arm/configs/ipq_defconfig                     |  1 +
> >  arch/arm/mach-qcom/Kconfig                         |  4 +
> >  arch/arm/mach-qcom/board.c                         |  1 +
> >  8 files changed, 157 insertions(+), 1 deletion(-)
> >  create mode 100644 Documentation/devicetree/bindings/clock/qca,gcnt.txt
> >  create mode 100644 Documentation/devicetree/bindings/ipq.txt
> >  create mode 100644 arch/arm/boot/dts/qcom-ipq40xx-r3pc.dts
> >  create mode 100644 arch/arm/boot/dts/qcom-ipq40xx.dtsi
> >
> > diff --git a/Documentation/devicetree/bindings/clock/qca,gcnt.txt b/Documentation/devicetree/bindings/clock/qca,gcnt.txt
> > new file mode 100644
> > index 0000000..dd0d71e
> > --- /dev/null
> > +++ b/Documentation/devicetree/bindings/clock/qca,gcnt.txt
> > @@ -0,0 +1,14 @@
> > +QCA Global Counter
>
> I don't think I've seen the "global counter" blocks before, what is it?
> What does it do? Do you have a upcoming driver for it? (Have I just
> missed it?)

It is a 56-bit counter that supplies the count to the ARM arch timers.
An upcoming patch will use it.

> You add it to the dts below, but don't seem to reference it. What is
> its purpose?
>
> Also, you should split this definition into its own patch.

Sure. Will post a revised patch.

> > +------------------------------------------------
> > +
> > +Required properties :
> > +- compatible : "qcom,qca-gcnt"
> > +
> > +- reg : shall contain base register location and length
> > +
> > +Example:
> > +
> > +	counter {
> > +		compatible = "qcom,qca-gcnt";
> > +		reg = <0x004a1000 0x4>;
>
> Most of the time when there's a device consuming one register it turns
> out to be part of some larger hw block and down the road things get
> complicated from the fact that we mapped 4 bytes in the middle.
>
> Is this part of a larger block? Can we better implement that as a
> simple-mfd or syscon?

Sure. Will see if I can re-implement it.

> > +	};
> > diff --git a/Documentation/devicetree/bindings/ipq.txt b/Documentation/devicetree/bindings/ipq.txt
> > new file mode 100644
> > index 0000000..7d56bd0
> > --- /dev/null
> > +++ b/Documentation/devicetree/bindings/ipq.txt
>
> This doesn't really follow the general pattern of this directory. There
> are some files like this, but then you should probably name it
> qualcomm.txt.

Will rename.

> > @@ -0,0 +1,16 @@
> > +Qualcomm IPQ device tree bindings
> > +---------------------------------
> > +
> > +System on Chip
> > +
> > +Device tree must specify which SoC it uses, with one of the
> > +following compatible strings
> > +
> > +       "qcom,ipq40xx"
> > +
> > +Platform
> > +
> > +Device tree must specify which Platform it uses, with one of the
> > +following compatible strings
> > +
> > +       "qcom,ipq40xx-r3pc"
>
> I would expect an "ipq.txt" to contain "qcom,ipq8064-ap148" and
> "qcom,ipq8064" as well.
>
> > diff --git a/arch/arm/boot/dts/Makefile b/arch/arm/boot/dts/Makefile
> > index 246473a..6b4caee 100644
> > --- a/arch/arm/boot/dts/Makefile
> > +++ b/arch/arm/boot/dts/Makefile
> > @@ -477,7 +477,8 @@ dtb-$(CONFIG_ARCH_QCOM) += \
> >  	qcom-ipq8064-ap148.dtb \
> >  	qcom-msm8660-surf.dtb \
> >  	qcom-msm8960-cdp.dtb \
> > -	qcom-msm8974-sony-xperia-honami.dtb
> > +	qcom-msm8974-sony-xperia-honami.dtb \
> > +	qcom-ipq40xx-r3pc.dtb
>
> Please insert your entry alphabetically.

Sure.

> >  dtb-$(CONFIG_ARCH_REALVIEW) += \
> >  	arm-realview-pb1176.dtb
> >  dtb-$(CONFIG_ARCH_ROCKCHIP) += \
> > diff --git a/arch/arm/boot/dts/qcom-ipq40xx-r3pc.dts b/arch/arm/boot/dts/qcom-ipq40xx-r3pc.dts
> > new file mode 100644
> > index 0000000..7e4e629
> > --- /dev/null
> > +++ b/arch/arm/boot/dts/qcom-ipq40xx-r3pc.dts
> > @@ -0,0 +1,33 @@
> > +/* Copyright (c) 2014, The Linux Foundation. All rights reserved.
> > + *
> > + * This program is free software; you can redistribute it and/or modify
> > + * it under the terms of the GNU General Public License version 2 and
> > + * only 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 "qcom-ipq40xx.dtsi"
> > +
> > +/ {
> > +	model = "Qualcomm Technologies, Inc. IPQ40XX R3PC";
> > +	compatible = "qcom,ipq40xx-r3pc", "qcom,ipq40xx";
> > +
> > +	memory {
> > +		device_type = "memory";
> > +		reg = <0x80000000 0x20000000>; /* 512MB */
> > +	};
> > +
> > +	chosen {
> > +		bootargs = "root=/dev/ram rw init=/init console=ttyMSM0,115200n8 initrd=0x82000000,0x000E2246";
> > +	};
> > +
> > +	soc {
> > +		serial at 78b0000 {
> > +			status = "ok";
> > +		};
> > +	};
> > +};
>
> This part looks good.
>
> > diff --git a/arch/arm/boot/dts/qcom-ipq40xx.dtsi b/arch/arm/boot/dts/qcom-ipq40xx.dtsi
> > new file mode 100644
> > index 0000000..76c55a3
> > --- /dev/null
> > +++ b/arch/arm/boot/dts/qcom-ipq40xx.dtsi
> > @@ -0,0 +1,86 @@
> > +/*
> > + * Copyright (c) 2014, The Linux Foundation. All rights reserved.
> > + *
> > + * This program is free software; you can redistribute it and/or modify
> > + * it under the terms of the GNU General Public License version 2 and
> > + * only 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.
> > + */
> > +
> > +/dts-v1/;
> > +
> > +#include "skeleton.dtsi"
> > +
> > +/ {
> > +	model = "Qualcomm Technologies, Inc. IPQ40XX";
> > +	compatible = "qcom,ipq40xx";
> > +	interrupt-parent = <&intc>;
> > +
> > +	cpus {
> > +		#address-cells = <1>;
> > +		#size-cells = <0>;
> > +		cpu at 0 {
> > +			device_type = "cpu";
> > +			compatible = "arm,cortex-a7";
> > +			reg = <0x0>;
> > +		};
> > +
> > +		cpu at 1 {
> > +			device_type = "cpu";
> > +			compatible = "arm,cortex-a7";
> > +			reg = <0x1>;
> > +		};
> > +
> > +		cpu at 2 {
> > +			device_type = "cpu";
> > +			compatible = "arm,cortex-a7";
> > +			reg = <0x2>;
> > +		};
> > +
> > +		cpu at 3 {
> > +			device_type = "cpu";
> > +			compatible = "arm,cortex-a7";
> > +			reg = <0x3>;
> > +		};
> > +	};
> > +
> > +	soc {
> > +		#address-cells = <1>;
> > +		#size-cells = <1>;
> > +		ranges;
> > +		compatible = "simple-bus";
> > +
> > +		intc: interrupt-controller at b000000 {
> > +			compatible = "qcom,msm-qgic2";
> > +			interrupt-controller;
> > +			#interrupt-cells = <3>;
> > +			reg = <0x0b000000 0x1000>,
> > +			<0x0b002000 0x1000>;
> > +		};
> > +
> > +		counter {
> > +			compatible = "qcom,qca-gcnt";
> > +			reg = <0x004a1000 0x4>;
> > +		};
> > +
> > +		timer {
> > +			compatible = "arm,armv7-timer";
> > +			interrupts = <1 2 0xf08>,
> > +				     <1 3 0xf08>,
> > +				     <1 4 0xf08>,
> > +				     <1 1 0xf08>;
> > +			clock-frequency = <20833333>;
> > +		};
> > +
> > +		serial at 78b0000 {
> > +			compatible = "qcom,msm-uartdm-v1.4", "qcom,msm-uartdm";
> > +			reg = <0x78b0000 0x200>;
> > +			interrupts = <0 108 0>;
> > +			status = "disabled";
> > +		};
> > +	};
> > +};
>
> Unless the counter has a critical function I suggest you add that
> separately, otherwise this looks good.

Ok

> > diff --git a/arch/arm/configs/ipq_defconfig b/arch/arm/configs/ipq_defconfig
> > index 1cabd8b..054a159 100644
> > --- a/arch/arm/configs/ipq_defconfig
> > +++ b/arch/arm/configs/ipq_defconfig
> > @@ -22,6 +22,7 @@ CONFIG_ARCH_MSM8X60=y
> >  CONFIG_ARCH_MSM8960=y
> >  CONFIG_ARCH_MSM8974=y
> >  CONFIG_ARCH_IPQ8064=y
> > +CONFIG_ARCH_IPQ40XX=y
> >  CONFIG_SMP=y
> >  CONFIG_PREEMPT=y
> >  CONFIG_AEABI=y
> > diff --git a/arch/arm/mach-qcom/Kconfig b/arch/arm/mach-qcom/Kconfig
> > index fab49a2..3add9f9 100644
> > --- a/arch/arm/mach-qcom/Kconfig
> > +++ b/arch/arm/mach-qcom/Kconfig
> > @@ -26,4 +26,8 @@ config ARCH_IPQ8064
> >  	bool "Enable support for IPQ806x"
> >  	select CLKSRC_QCOM
> >
> > +config ARCH_IPQ40XX
> > +	bool "Enable support for IPQ40XX"
> > +	select HAVE_ARM_ARCH_TIMER
> > +
>
> Please insert your entry alphabetically.

Ok.

> >  endif
> > diff --git a/arch/arm/mach-qcom/board.c b/arch/arm/mach-qcom/board.c
> > index 6d8bbf7..566487d 100644
> > --- a/arch/arm/mach-qcom/board.c
> > +++ b/arch/arm/mach-qcom/board.c
> > @@ -22,6 +22,7 @@ static const char * const qcom_dt_match[] __initconst = {
> >  	"qcom,ipq8064",
> >  	"qcom,msm8660-surf",
> >  	"qcom,msm8960-cdp",
> > +	"qcom,ipq40xx-r3pc",
>
> Please add qcom,ipq40xx instead, so that we don't need to list every
> single device.
>
> Also, please keep the list alphabetically sorted.

Ok.

> >  	NULL
> >  };
>
> Regards,
> Bjorn

Thanks for your feedback Bjorn. Will re-work and post the patches.
Varada


From Haibo.Chen at freescale.com  Mon Aug 24 01:24:14 2015
From: Haibo.Chen at freescale.com (Chen Bough)
Date: Mon, 24 Aug 2015 08:24:14 +0000
Subject: [PATCH v2 1/5] input: touchscreen: add imx6ul_tsc driver support
In-Reply-To: <20150821092607.GA706@pengutronix.de>
References: <1438077521-12857-1-git-send-email-haibo.chen@freescale.com>
 <1438077521-12857-2-git-send-email-haibo.chen@freescale.com>
 <20150821092607.GA706@pengutronix.de>
Message-ID: <BY1PR03MB138872B8FDE6BB8E7553F2839A620@BY1PR03MB1388.namprd03.prod.outlook.com>

Hi Markus,



> -----Original Message-----
> From: Markus Pargmann [mailto:mpa at pengutronix.de]
> Sent: Friday, August 21, 2015 5:26 PM
> To: Chen Haibo-B51421
> Cc: robh+dt at kernel.org; pawel.moll at arm.com; mark.rutland at arm.com;
> ijc+devicetree at hellion.org.uk; galak at codeaurora.org; shawnguo at kernel.org;
> kernel at pengutronix.de; linux at arm.linux.org.uk; dmitry.torokhov at gmail.com;
> hans.verkuil at cisco.com; hadess at hadess.net; mchehab at osg.samsung.com;
> mamlinav at gmail.com; arnd at arndb.de; jonathar at broadcom.com;
> hdegoede at redhat.com; christian.gmeiner at gmail.com; scott.liu at emc.com.tw;
> geert at linux-m68k.org; benjamin.tissoires at redhat.com;
> sebastien.szymanski at armadeus.com; sbranden at broadcom.com;
> devicetree at vger.kernel.org; linux-kernel at vger.kernel.org; linux-arm-
> kernel at lists.infradead.org; linux-input at vger.kernel.org
> Subject: Re: [PATCH v2 1/5] input: touchscreen: add imx6ul_tsc driver
> support
> 
> On Tue, Jul 28, 2015 at 05:58:37PM +0800, Haibo Chen wrote:
> > Freescale i.MX6UL contains a internal touchscreen controller, this
> > patch add a driver to support this controller.
> >
> > Signed-off-by: Haibo Chen <haibo.chen at freescale.com>
> > ---
> >  drivers/input/touchscreen/Kconfig      |  12 +
> >  drivers/input/touchscreen/Makefile     |   1 +
> >  drivers/input/touchscreen/imx6ul_tsc.c | 504
> > +++++++++++++++++++++++++++++++++
> >  3 files changed, 517 insertions(+)
> >  create mode 100644 drivers/input/touchscreen/imx6ul_tsc.c
> >
> > diff --git a/drivers/input/touchscreen/Kconfig
> > b/drivers/input/touchscreen/Kconfig
> > index 5b272ba..32c300d 100644
> > --- a/drivers/input/touchscreen/Kconfig
> > +++ b/drivers/input/touchscreen/Kconfig
> > @@ -479,6 +479,18 @@ config TOUCHSCREEN_MTOUCH
> >  	  To compile this driver as a module, choose M here: the
> >  	  module will be called mtouch.
> >
> > +config TOUCHSCREEN_IMX6UL_TSC
> > +	tristate "Freescale i.MX6UL touchscreen controller"
> > +	depends on OF
> > +	help
> > +	  Say Y here if you have a Freescale i.MX6UL, and want to
> > +	  use the internal touchscreen controller.
> > +
> > +	  If unsure, say N.
> > +
> > +	  To compile this driver as a module, choose M here: the
> > +	  moduel will be called imx6ul_tsc.
> > +
> >  config TOUCHSCREEN_INEXIO
> >  	tristate "iNexio serial touchscreens"
> >  	select SERIO
> > diff --git a/drivers/input/touchscreen/Makefile
> > b/drivers/input/touchscreen/Makefile
> > index c85aae2..9379b32 100644
> > --- a/drivers/input/touchscreen/Makefile
> > +++ b/drivers/input/touchscreen/Makefile
> > @@ -38,6 +38,7 @@ obj-$(CONFIG_TOUCHSCREEN_EGALAX)	+= egalax_ts.o
> >  obj-$(CONFIG_TOUCHSCREEN_FUJITSU)	+= fujitsu_ts.o
> >  obj-$(CONFIG_TOUCHSCREEN_GOODIX)	+= goodix.o
> >  obj-$(CONFIG_TOUCHSCREEN_ILI210X)	+= ili210x.o
> > +obj-$(CONFIG_TOUCHSCREEN_IMX6UL_TSC)	+= imx6ul_tsc.o
> >  obj-$(CONFIG_TOUCHSCREEN_INEXIO)	+= inexio.o
> >  obj-$(CONFIG_TOUCHSCREEN_INTEL_MID)	+= intel-mid-touch.o
> >  obj-$(CONFIG_TOUCHSCREEN_IPROC)		+= bcm_iproc_tsc.o
> > diff --git a/drivers/input/touchscreen/imx6ul_tsc.c
> > b/drivers/input/touchscreen/imx6ul_tsc.c
> > new file mode 100644
> > index 0000000..807f1db
> > --- /dev/null
> > +++ b/drivers/input/touchscreen/imx6ul_tsc.c
> > @@ -0,0 +1,504 @@
> > +/*
> > + * Freescale i.MX6UL touchscreen controller driver
> > + *
> > + * Copyright (C) 2015 Freescale Semiconductor, Inc.
> > + *
> > + * This program is free software; you can redistribute it and/or
> > +modify
> > + * it under the terms of the GNU General Public License version 2 as
> > + * published by the Free Software Foundation.
> > + */
> > +
> > +#include <linux/errno.h>
> > +#include <linux/kernel.h>
> > +#include <linux/module.h>
> > +#include <linux/gpio.h>
> > +#include <linux/input.h>
> > +#include <linux/slab.h>
> > +#include <linux/completion.h>
> > +#include <linux/delay.h>
> > +#include <linux/of.h>
> > +#include <linux/of_device.h>
> > +#include <linux/of_gpio.h>
> > +#include <linux/of_irq.h>
> > +#include <linux/interrupt.h>
> > +#include <linux/platform_device.h>
> > +#include <linux/clk.h>
> > +#include <linux/io.h>
> > +
> > +/* ADC configuration registers field define */
> > +#define ADC_AIEN		(0x1 << 7)
> > +#define ADC_CONV_DISABLE	0x1F
> > +#define ADC_CAL			(0x1 << 7)
> > +#define ADC_CALF		0x2
> > +#define ADC_12BIT_MODE		(0x2 << 2)
> > +#define ADC_IPG_CLK		0x00
> > +#define ADC_CLK_DIV_8		(0x03 << 5)
> > +#define ADC_SHORT_SAMPLE_MODE	(0x0 << 4)
> > +#define ADC_HARDWARE_TRIGGER	(0x1 << 13)
> > +#define SELECT_CHANNEL_4	0x04
> > +#define SELECT_CHANNEL_1	0x01
> > +#define DISABLE_CONVERSION_INT	(0x0 << 7)
> > +
> > +/* ADC registers */
> > +#define REG_ADC_HC0		0x00
> > +#define REG_ADC_HC1		0x04
> > +#define REG_ADC_HC2		0x08
> > +#define REG_ADC_HC3		0x0C
> > +#define REG_ADC_HC4		0x10
> > +#define REG_ADC_HS		0x14
> > +#define REG_ADC_R0		0x18
> > +#define REG_ADC_CFG		0x2C
> > +#define REG_ADC_GC		0x30
> > +#define REG_ADC_GS		0x34
> > +
> > +#define ADC_TIMEOUT		msecs_to_jiffies(100)
> 
> These defines are in two drivers. Here and in drivers/iio/adc/vf610_adc.c

Actually, they are different. In the TSC driver, add REG_ADC_HC2/3/4, and the offset of the 
REG_ADC_HS~ REG_ADC_GS also changed.

For i.MX6UL, to support TSC, our IC team add some changes in ADC2, like add add REG_ADC_HC2/3/4,
so that we can config the channel of ADC2 to connect with X-/X+/Y+/Y- of touch screen.
And IC team suggest the ADC2 only used for TSC, should not work as a normal ADC. 
 

> 
> > +
> > +/* TSC registers */
> > +#define REG_TSC_BASIC_SETING	0x00
> > +#define REG_TSC_PRE_CHARGE_TIME	0x10
> > +#define REG_TSC_FLOW_CONTROL	0x20
> > +#define REG_TSC_MEASURE_VALUE	0x30
> > +#define REG_TSC_INT_EN		0x40
> > +#define REG_TSC_INT_SIG_EN	0x50
> > +#define REG_TSC_INT_STATUS	0x60
> > +#define REG_TSC_DEBUG_MODE	0x70
> > +#define REG_TSC_DEBUG_MODE2	0x80
> > +
> > +/* TSC configuration registers field define */
> > +#define DETECT_4_WIRE_MODE	(0x0 << 4)
> > +#define AUTO_MEASURE		0x1
> > +#define MEASURE_SIGNAL		0x1
> > +#define DETECT_SIGNAL		(0x1 << 4)
> > +#define VALID_SIGNAL		(0x1 << 8)
> > +#define MEASURE_INT_EN		0x1
> > +#define MEASURE_SIG_EN		0x1
> > +#define VALID_SIG_EN		(0x1 << 8)
> > +#define DE_GLITCH_2		(0x2 << 29)
> > +#define START_SENSE		(0x1 << 12)
> > +#define TSC_DISABLE		(0x1 << 16)
> > +#define DETECT_MODE		0x2
> > +
> > +struct imx6ul_tsc {
> > +	struct device *dev;
> > +	struct input_dev *input;
> > +	void __iomem *tsc_regs;
> > +	void __iomem *adc_regs;
> > +	struct clk *tsc_clk;
> > +	struct clk *adc_clk;
> > +
> > +	int xnur_gpio;
> > +	int measure_delay_time;
> > +	int pre_charge_time;
> > +
> > +	struct completion completion;
> > +};
> > +
> > +/*
> > + * TSC module need ADC to get the measure value. So
> > + * before config TSC, we should initialize ADC module.
> > + */
> > +static void imx6ul_adc_init(struct imx6ul_tsc *tsc) {
> > +	int adc_hc = 0;
> > +	int adc_gc;
> > +	int adc_gs;
> > +	int adc_cfg;
> > +	int timeout;
> > +
> > +	adc_cfg = readl(tsc->adc_regs + REG_ADC_CFG);
> > +	adc_cfg |= ADC_12BIT_MODE | ADC_IPG_CLK;
> > +	adc_cfg |= ADC_CLK_DIV_8 | ADC_SHORT_SAMPLE_MODE;
> > +	adc_cfg &= ~ADC_HARDWARE_TRIGGER;
> > +	writel(adc_cfg, tsc->adc_regs + REG_ADC_CFG);
> > +
> > +	/* enable calibration interrupt */
> > +	adc_hc |= ADC_AIEN;
> > +	adc_hc |= ADC_CONV_DISABLE;
> > +	writel(adc_hc, tsc->adc_regs + REG_ADC_HC0);
> > +
> > +	/* start ADC calibration */
> > +	adc_gc = readl(tsc->adc_regs + REG_ADC_GC);
> > +	adc_gc |= ADC_CAL;
> > +	writel(adc_gc, tsc->adc_regs + REG_ADC_GC);
> > +
> > +	timeout = wait_for_completion_timeout
> > +			(&tsc->completion, ADC_TIMEOUT);
> > +	if (timeout == 0)
> > +		dev_err(tsc->dev, "Timeout for adc calibration\n");
> > +
> > +	adc_gs = readl(tsc->adc_regs + REG_ADC_GS);
> > +	if (adc_gs & ADC_CALF)
> > +		dev_err(tsc->dev, "ADC calibration failed\n");
> > +
> > +	/* TSC need the ADC work in hardware trigger */
> > +	adc_cfg = readl(tsc->adc_regs + REG_ADC_CFG);
> > +	adc_cfg |= ADC_HARDWARE_TRIGGER;
> > +	writel(adc_cfg, tsc->adc_regs + REG_ADC_CFG); }
> > +
> > +/*
> > + * This is a TSC workaround. Currently TSC misconnect two
> > + * ADC channels, this function remap channel configure for
> > + * hardware trigger.
> > + */
> > +static void imx6ul_tsc_channel_config(struct imx6ul_tsc *tsc) {
> > +	int adc_hc0, adc_hc1, adc_hc2, adc_hc3, adc_hc4;
> > +
> > +	adc_hc0 = DISABLE_CONVERSION_INT;
> > +	writel(adc_hc0, tsc->adc_regs + REG_ADC_HC0);
> > +
> > +	adc_hc1 = DISABLE_CONVERSION_INT | SELECT_CHANNEL_4;
> > +	writel(adc_hc1, tsc->adc_regs + REG_ADC_HC1);
> > +
> > +	adc_hc2 = DISABLE_CONVERSION_INT;
> > +	writel(adc_hc2, tsc->adc_regs + REG_ADC_HC2);
> > +
> > +	adc_hc3 = DISABLE_CONVERSION_INT | SELECT_CHANNEL_1;
> > +	writel(adc_hc3, tsc->adc_regs + REG_ADC_HC3);
> > +
> > +	adc_hc4 = DISABLE_CONVERSION_INT;
> > +	writel(adc_hc4, tsc->adc_regs + REG_ADC_HC4); }
> 
> Is this code similar to initialization of the adc driver? Does it make
> sense to move this code to the ADC driver?
 
Our IC team misconnect the ADC's channel1 and channel3,  in the TSC logic,
ADC channel1  --->   Y-
ADC channel2  --->   Y+
ADC channel3  --->   X-
ADC channel4  --->   X+
The upper connection can make tsc work normal, but our IC team make a mistake,
in default,  ADC channel1  connect to X-, ADC channel3 connect to Y-.

So these code is just a software workaround, switch the ADC channel1 and channel3,
to make the TSC work normal.

So I think we should distinguish these code and the adc initialization.

Best regards,

haibo

> 
> Best regards,
> 
> Markus
> 
> > +
> > +/*
> > + * TSC setting, confige the pre-charge time and measure delay time.
> > + * different touch screen may need different pre-charge time and
> > + * measure delay time.
> > + */
> > +static void imx6ul_tsc_set(struct imx6ul_tsc *tsc) {
> > +	int basic_setting = 0;
> > +	int start;
> > +
> > +	basic_setting |= tsc->measure_delay_time << 8;
> > +	basic_setting |= DETECT_4_WIRE_MODE | AUTO_MEASURE;
> > +	writel(basic_setting, tsc->tsc_regs + REG_TSC_BASIC_SETING);
> > +
> > +	writel(DE_GLITCH_2, tsc->tsc_regs + REG_TSC_DEBUG_MODE2);
> > +
> > +	writel(tsc->pre_charge_time, tsc->tsc_regs +
> REG_TSC_PRE_CHARGE_TIME);
> > +	writel(MEASURE_INT_EN, tsc->tsc_regs + REG_TSC_INT_EN);
> > +	writel(MEASURE_SIG_EN | VALID_SIG_EN,
> > +		tsc->tsc_regs + REG_TSC_INT_SIG_EN);
> > +
> > +	/* start sense detection */
> > +	start = readl(tsc->tsc_regs + REG_TSC_FLOW_CONTROL);
> > +	start |= START_SENSE;
> > +	start &= ~TSC_DISABLE;
> > +	writel(start, tsc->tsc_regs + REG_TSC_FLOW_CONTROL); }
> > +
> > +static void imx6ul_tsc_init(struct imx6ul_tsc *tsc) {
> > +	imx6ul_adc_init(tsc);
> > +	imx6ul_tsc_channel_config(tsc);
> > +	imx6ul_tsc_set(tsc);
> > +}
> > +
> > +static irqreturn_t tsc_irq_fn(int irq, void *dev_id) {
> > +	struct imx6ul_tsc *tsc = (struct imx6ul_tsc *)dev_id;
> > +	int status;
> > +	int value;
> > +	int x, y;
> > +	int xnur;
> > +	int debug_mode2;
> > +	int state_machine;
> > +	int start;
> > +	unsigned long timeout;
> > +
> > +	status = readl(tsc->tsc_regs + REG_TSC_INT_STATUS);
> > +
> > +	/* write 1 to clear the bit measure-signal */
> > +	writel(MEASURE_SIGNAL | DETECT_SIGNAL,
> > +		tsc->tsc_regs + REG_TSC_INT_STATUS);
> > +
> > +	/* It's a HW self-clean bit. Set this bit and start sense detection
> */
> > +	start = readl(tsc->tsc_regs + REG_TSC_FLOW_CONTROL);
> > +	start |= START_SENSE;
> > +	writel(start, tsc->tsc_regs + REG_TSC_FLOW_CONTROL);
> > +
> > +	if (status & MEASURE_SIGNAL) {
> > +		value = readl(tsc->tsc_regs + REG_TSC_MEASURE_VALUE);
> > +		x = (value >> 16) & 0x0fff;
> > +		y = value & 0x0fff;
> > +
> > +		/*
> > +		 * Delay some time(max 2ms), wait the pre-charge done.
> > +		 * After the pre-change mode, TSC go into detect mode.
> > +		 * And in detect mode, we can get the xnur gpio value.
> > +		 * If xnur is low, this means the touch screen still
> > +		 * be touched. If xnur is high, this means finger leave
> > +		 * the touch screen.
> > +		 */
> > +		timeout = jiffies + HZ/500;
> > +		do {
> > +			if (time_after(jiffies, timeout)) {
> > +				xnur = 0;
> > +				goto touch_event;
> > +			}
> > +			usleep_range(200, 400);
> > +			debug_mode2 = readl(tsc->tsc_regs +
> REG_TSC_DEBUG_MODE2);
> > +			state_machine = (debug_mode2 >> 20) & 0x7;
> > +		} while (state_machine != DETECT_MODE);
> > +		usleep_range(200, 400);
> > +
> > +		xnur = gpio_get_value(tsc->xnur_gpio);
> > +touch_event:
> > +		if (xnur == 0) {
> > +			input_report_key(tsc->input, BTN_TOUCH, 1);
> > +			input_report_abs(tsc->input, ABS_X, x);
> > +			input_report_abs(tsc->input, ABS_Y, y);
> > +		} else
> > +			input_report_key(tsc->input, BTN_TOUCH, 0);
> > +
> > +		input_sync(tsc->input);
> > +	}
> > +
> > +	return IRQ_HANDLED;
> > +}
> > +
> > +static irqreturn_t adc_irq_fn(int irq, void *dev_id) {
> > +	struct imx6ul_tsc *tsc = (struct imx6ul_tsc *)dev_id;
> > +	int coco;
> > +	int value;
> > +
> > +	coco = readl(tsc->adc_regs + REG_ADC_HS);
> > +	if (coco & 0x01) {
> > +		value = readl(tsc->adc_regs + REG_ADC_R0);
> > +		complete(&tsc->completion);
> > +	}
> > +
> > +	return IRQ_HANDLED;
> > +}
> > +
> > +static const struct of_device_id imx6ul_tsc_match[] = {
> > +	{ .compatible = "fsl,imx6ul-tsc", },
> > +	{ /* sentinel */ }
> > +};
> > +MODULE_DEVICE_TABLE(of, imx6ul_tsc_match);
> > +
> > +static int imx6ul_tsc_probe(struct platform_device *pdev) {
> > +	struct imx6ul_tsc *tsc;
> > +	struct resource *tsc_mem;
> > +	struct resource *adc_mem;
> > +	struct input_dev *input_dev;
> > +	struct device_node *np = pdev->dev.of_node;
> > +	int err;
> > +	int tsc_irq;
> > +	int adc_irq;
> > +
> > +	tsc = devm_kzalloc(&pdev->dev, sizeof(struct imx6ul_tsc),
> GFP_KERNEL);
> > +	input_dev = devm_input_allocate_device(&pdev->dev);
> > +
> > +	tsc->dev = &pdev->dev;
> > +
> > +	tsc->input = input_dev;
> > +	tsc->input->evbit[0] = BIT_MASK(EV_KEY) | BIT_MASK(EV_ABS);
> > +	tsc->input->keybit[BIT_WORD(BTN_TOUCH)] = BIT_MASK(BTN_TOUCH);
> > +	input_set_abs_params(tsc->input, ABS_X, 0, 0xFFF, 0, 0);
> > +	input_set_abs_params(tsc->input, ABS_Y, 0, 0xFFF, 0, 0);
> > +
> > +	tsc->input->name = "iMX6UL TouchScreen Controller";
> > +
> > +	tsc->xnur_gpio = of_get_named_gpio(np, "xnur-gpio", 0);
> > +	err = gpio_request_one(tsc->xnur_gpio, GPIOF_IN, "tsc_X-");
> > +	if (err) {
> > +		dev_err(&pdev->dev, "failed to request GPIO tsc_X-\n");
> > +		return err;
> > +	}
> > +
> > +	tsc_mem = platform_get_resource(pdev, IORESOURCE_MEM, 0);
> > +	tsc->tsc_regs = devm_ioremap_resource(&pdev->dev, tsc_mem);
> > +	if (IS_ERR(tsc->tsc_regs)) {
> > +		dev_err(&pdev->dev, "failed to remap tsc memory\n");
> > +		err = PTR_ERR(tsc->tsc_regs);
> > +		return err;
> > +	}
> > +
> > +	adc_mem = platform_get_resource(pdev, IORESOURCE_MEM, 1);
> > +	tsc->adc_regs = devm_ioremap_resource(&pdev->dev, adc_mem);
> > +	if (IS_ERR(tsc->adc_regs)) {
> > +		dev_err(&pdev->dev, "failed to remap adc memory\n");
> > +		err = PTR_ERR(tsc->adc_regs);
> > +		return err;
> > +	}
> > +
> > +	tsc->tsc_clk = devm_clk_get(&pdev->dev, "tsc");
> > +	if (IS_ERR(tsc->tsc_clk)) {
> > +		dev_err(&pdev->dev, "failed getting tsc clock\n");
> > +		err = PTR_ERR(tsc->tsc_clk);
> > +		return err;
> > +	}
> > +
> > +	tsc->adc_clk = devm_clk_get(&pdev->dev, "adc");
> > +	if (IS_ERR(tsc->adc_clk)) {
> > +		dev_err(&pdev->dev, "failed getting adc clock\n");
> > +		err = PTR_ERR(tsc->adc_clk);
> > +		return err;
> > +	}
> > +
> > +	tsc_irq = platform_get_irq(pdev, 0);
> > +	if (tsc_irq < 0) {
> > +		dev_err(&pdev->dev, "no tsc irq resource?\n");
> > +		return tsc_irq;
> > +	}
> > +
> > +	adc_irq = platform_get_irq(pdev, 1);
> > +	if (adc_irq <= 0) {
> > +		dev_err(&pdev->dev, "no adc irq resource?\n");
> > +		return adc_irq;
> > +	}
> > +
> > +	err = devm_request_threaded_irq(tsc->dev, tsc_irq,
> > +					NULL, tsc_irq_fn,
> > +					IRQF_TRIGGER_HIGH | IRQF_ONESHOT,
> > +					dev_name(&pdev->dev), tsc);
> > +	if (err < 0) {
> > +		dev_err(&pdev->dev,
> > +			"failed requesting tsc irq %d\n",
> > +					    tsc_irq);
> > +		return err;
> > +	}
> > +
> > +	err = devm_request_irq(tsc->dev, adc_irq,
> > +				adc_irq_fn, 0,
> > +				dev_name(&pdev->dev), tsc);
> > +	if (err < 0) {
> > +		dev_err(&pdev->dev,
> > +			"failed requesting adc irq %d\n",
> > +					    adc_irq);
> > +		return err;
> > +	}
> > +
> > +	err = of_property_read_u32(np, "measure-delay-time",
> > +				&tsc->measure_delay_time);
> > +	if (err)
> > +		tsc->measure_delay_time = 0xffff;
> > +
> > +	err = of_property_read_u32(np, "pre-charge-time",
> > +				&tsc->pre_charge_time);
> > +	if (err)
> > +		tsc->pre_charge_time = 0xfff;
> > +
> > +	init_completion(&tsc->completion);
> > +
> > +	err = clk_prepare_enable(tsc->adc_clk);
> > +	if (err) {
> > +		dev_err(&pdev->dev,
> > +			"Could not prepare or enable the adc clock.\n");
> > +		return err;
> > +	}
> > +
> > +	err = clk_prepare_enable(tsc->tsc_clk);
> > +	if (err) {
> > +		dev_err(&pdev->dev,
> > +			"Could not prepare or enable the tsc clock.\n");
> > +		goto error_tsc_clk_enable;
> > +	}
> > +
> > +	err = input_register_device(tsc->input);
> > +	if (err < 0) {
> > +		dev_err(&pdev->dev, "failed to register input device\n");
> > +		err = -EIO;
> > +		goto err_input_register;
> > +	}
> > +
> > +	imx6ul_tsc_init(tsc);
> > +
> > +	platform_set_drvdata(pdev, tsc);
> > +	return 0;
> > +
> > +err_input_register:
> > +	clk_disable_unprepare(tsc->tsc_clk);
> > +error_tsc_clk_enable:
> > +	clk_disable_unprepare(tsc->adc_clk);
> > +
> > +	return err;
> > +}
> > +
> > +static void imx6ul_tsc_disable(struct imx6ul_tsc *tsc) {
> > +	int tsc_flow;
> > +	int adc_cfg;
> > +
> > +	/* TSC controller enters to idle status */
> > +	tsc_flow = readl(tsc->tsc_regs + REG_TSC_FLOW_CONTROL);
> > +	tsc_flow |= TSC_DISABLE;
> > +	writel(tsc_flow, tsc->tsc_regs + REG_TSC_FLOW_CONTROL);
> > +
> > +	/* ADC controller enters to stop mode */
> > +	adc_cfg = readl(tsc->adc_regs + REG_ADC_HC0);
> > +	adc_cfg |= ADC_CONV_DISABLE;
> > +	writel(adc_cfg, tsc->adc_regs + REG_ADC_HC0); }
> > +
> > +static int imx6ul_tsc_remove(struct platform_device *pdev) {
> > +	struct imx6ul_tsc *tsc = platform_get_drvdata(pdev);
> > +
> > +	imx6ul_tsc_disable(tsc);
> > +
> > +	clk_disable_unprepare(tsc->tsc_clk);
> > +	clk_disable_unprepare(tsc->adc_clk);
> > +	input_unregister_device(tsc->input);
> > +	kfree(tsc);
> > +
> > +	return 0;
> > +}
> > +
> > +static int __maybe_unused imx6ul_tsc_suspend(struct device *dev) {
> > +	struct platform_device *pdev = to_platform_device(dev);
> > +	struct imx6ul_tsc *tsc = platform_get_drvdata(pdev);
> > +
> > +	imx6ul_tsc_disable(tsc);
> > +
> > +	clk_disable_unprepare(tsc->tsc_clk);
> > +	clk_disable_unprepare(tsc->adc_clk);
> > +
> > +	return 0;
> > +}
> > +
> > +static int __maybe_unused imx6ul_tsc_resume(struct device *dev) {
> > +	struct platform_device *pdev = to_platform_device(dev);
> > +	struct imx6ul_tsc *tsc = platform_get_drvdata(pdev);
> > +	int err;
> > +
> > +	err = clk_prepare_enable(tsc->adc_clk);
> > +	if (err)
> > +		return err;
> > +
> > +	err = clk_prepare_enable(tsc->tsc_clk);
> > +	if (err) {
> > +		clk_disable_unprepare(tsc->adc_clk);
> > +		return err;
> > +	}
> > +
> > +	imx6ul_tsc_init(tsc);
> > +	return 0;
> > +}
> > +
> > +static SIMPLE_DEV_PM_OPS(imx6ul_tsc_pm_ops,
> > +			 imx6ul_tsc_suspend,
> > +			 imx6ul_tsc_resume);
> > +
> > +static struct platform_driver imx6ul_tsc_driver = {
> > +	.driver		= {
> > +		.name	= "imx6ul-tsc",
> > +		.owner	= THIS_MODULE,
> > +		.of_match_table	= imx6ul_tsc_match,
> > +		.pm	= &imx6ul_tsc_pm_ops,
> > +	},
> > +	.probe		= imx6ul_tsc_probe,
> > +	.remove		= imx6ul_tsc_remove,
> > +};
> > +module_platform_driver(imx6ul_tsc_driver);
> > +
> > +MODULE_AUTHOR("Haibo Chen <haibo.chen at freescale.com>");
> > +MODULE_DESCRIPTION("Freescale i.MX6UL Touchscreen controller
> > +driver"); MODULE_LICENSE("GPL v2");
> > --
> > 1.9.1
> >
> > --
> > To unsubscribe from this list: send the line "unsubscribe
> > linux-kernel" in the body of a message to majordomo at vger.kernel.org
> > More majordomo info at  http://vger.kernel.org/majordomo-info.html
> > Please read the FAQ at  http://www.tux.org/lkml/
> >
> 
> --
> Pengutronix e.K.                           |
> |
> Industrial Linux Solutions                 | http://www.pengutronix.de/
> |
> Peiner Str. 6-8, 31137 Hildesheim, Germany | Phone: +49-5121-206917-0
> |
> Amtsgericht Hildesheim, HRA 2686           | Fax:   +49-5121-206917-5555
> |

From p.zabel at pengutronix.de  Mon Aug 24 01:26:04 2015
From: p.zabel at pengutronix.de (Philipp Zabel)
Date: Mon, 24 Aug 2015 10:26:04 +0200
Subject: [PATCH v2 0/2] i.MX6 OCOTP NVMEM support
In-Reply-To: <1438940901-5779-1-git-send-email-p.zabel@pengutronix.de>
References: <1438940901-5779-1-git-send-email-p.zabel@pengutronix.de>
Message-ID: <1440404764.4444.2.camel@pengutronix.de>

Hi Greg,

Am Freitag, den 07.08.2015, 11:48 +0200 schrieb Philipp Zabel:
> Hi,
> 
> These patches add support for the i.MX On-Chip OTP (eFuse) Controller found
> in i.MX6Q/D, i.MX6S/DL, i.MX6SL, and i.MX6SX SoCs to the NVMEM framework.
> Greg, could you take them into the char-misc tree together with the NVMEM
> framework?

is anything blocking this?

best regards
Philipp

> Changes since v1:
>  - Dropped unneeded clk.h include
>  - Fixed MODULE_LICENSE
>  - Droped third patch (adding the clock to the device tree node can be done separately)
> 
> Philipp Zabel (2):
>   nvmem: Add i.MX6 OCOTP device tree binding documentation
>   nvmem: imx-ocotp: Add i.MX6 OCOTP driver
> 
>  .../devicetree/bindings/nvmem/imx-ocotp.txt        |  20 +++
>  drivers/nvmem/Kconfig                              |  11 ++
>  drivers/nvmem/Makefile                             |   2 +
>  drivers/nvmem/imx-ocotp.c                          | 154 +++++++++++++++++++++
>  4 files changed, 187 insertions(+)
>  create mode 100644 Documentation/devicetree/bindings/nvmem/imx-ocotp.txt
>  create mode 100644 drivers/nvmem/imx-ocotp.c




From shawn.lin at rock-chips.com  Mon Aug 24 01:27:43 2015
From: shawn.lin at rock-chips.com (Shawn Lin)
Date: Mon, 24 Aug 2015 16:27:43 +0800
Subject: [RESEND PATCH] clk: rockchip: disable init state before mmc card
 initialization
Message-ID: <1440404863-14350-1-git-send-email-shawn.lin@rock-chips.com>

mmc host controller's IO input/output timing is unpredictable if
bootloader execute tuning for HS200 mode. It might make kernel failed
to initialize mmc card in identification mode. The root cause is
tuning phase and degree setting for HS200 mode in bootloader aren't
applicable to that of identification mode in kernel stage. Anyway, we
can't force all bootloaders to disable tuning phase and degree setting
before into kernel. Simply disable it in rockchip_clk_register_mmc.

Signed-off-by: Shawn Lin <shawn.lin at rock-chips.com>

---

 drivers/clk/rockchip/clk-mmc-phase.c | 20 ++++++++++++++++++++
 1 file changed, 20 insertions(+)

diff --git a/drivers/clk/rockchip/clk-mmc-phase.c b/drivers/clk/rockchip/clk-mmc-phase.c
index e9f8df32..ae21592 100644
--- a/drivers/clk/rockchip/clk-mmc-phase.c
+++ b/drivers/clk/rockchip/clk-mmc-phase.c
@@ -38,6 +38,9 @@ static unsigned long rockchip_mmc_recalc(struct clk_hw *hw,
 #define ROCKCHIP_MMC_DEGREE_MASK 0x3
 #define ROCKCHIP_MMC_DELAYNUM_OFFSET 2
 #define ROCKCHIP_MMC_DELAYNUM_MASK (0xff << ROCKCHIP_MMC_DELAYNUM_OFFSET)
+#define ROCKCHIP_MMC_INIT_STATE_DISABLE (0x1)
+#define ROCKCHIP_MMC_INIT_STATE_SHIFT (1)
+#define ROCKCHIP_MMC_INIT_STATE_MASK  (0x1)
 
 #define PSECS_PER_SEC 1000000000000LL
 
@@ -119,6 +122,21 @@ static const struct clk_ops rockchip_mmc_clk_ops = {
 	.set_phase	= rockchip_mmc_set_phase,
 };
 
+static void rockchip_clk_mmc_disable_init(struct rockchip_mmc_clock *mmc_clock)
+{
+	if (mmc_clock->shift != ROCKCHIP_MMC_INIT_STATE_SHIFT)
+		return;
+
+	writel(HIWORD_UPDATE(ROCKCHIP_MMC_INIT_STATE_DISABLE,
+			     ROCKCHIP_MMC_INIT_STATE_MASK,
+			     mmc_clock->shift),
+	       mmc_clock->reg);
+
+	pr_debug("%s: clear mmc init state to %d", __func__,
+		 (readl(mmc_clock->reg) >> (mmc_clock->shift)) &
+		 ROCKCHIP_MMC_INIT_STATE_MASK);
+}
+
 struct clk *rockchip_clk_register_mmc(const char *name,
 				const char *const *parent_names, u8 num_parents,
 				void __iomem *reg, int shift)
@@ -139,6 +157,8 @@ struct clk *rockchip_clk_register_mmc(const char *name,
 	mmc_clock->reg = reg;
 	mmc_clock->shift = shift;
 
+	rockchip_clk_mmc_disable_init(mmc_clock);
+
 	if (name)
 		init.name = name;
 
-- 
2.3.7




From gabriele.paoloni at huawei.com  Mon Aug 24 01:28:38 2015
From: gabriele.paoloni at huawei.com (Gabriele Paoloni)
Date: Mon, 24 Aug 2015 08:28:38 +0000
Subject: [PATCH v7 3/6] PCI: designware: Add ARM64 support
In-Reply-To: <55DAB8FF.70603@hisilicon.com>
References: <1439812554-180426-1-git-send-email-wangzhou1@hisilicon.com>
 <1439812554-180426-4-git-send-email-wangzhou1@hisilicon.com>
 <1439988852.31432.15.camel@pengutronix.de>
 <EE11001F9E5DDD47B7634E2F8A612F2E01D81315@lhreml503-mbs>
 <1439998622.31432.44.camel@pengutronix.de>
 <EE11001F9E5DDD47B7634E2F8A612F2E01D8139B@lhreml503-mbs>
 <1440059243.31432.59.camel@pengutronix.de>
 <EE11001F9E5DDD47B7634E2F8A612F2E01D81BAC@lhreml503-mbs>
 <20150821134230.GQ1020@e106497-lin.cambridge.arm.com>
 <EE11001F9E5DDD47B7634E2F8A612F2E01D826BD@lhreml503-mbs>
 <55DAB8FF.70603@hisilicon.com>
Message-ID: <EE11001F9E5DDD47B7634E2F8A612F2E162019CA@lhreml503-mbs>



> -----Original Message-----
> From: Wangzhou (B)
> Sent: Monday, August 24, 2015 7:26 AM
> To: Gabriele Paoloni
> Cc: Liviu Dudau; Lucas Stach; Bjorn Helgaas; jingoohan1 at gmail.com;
> Pratyush Anand; Arnd Bergmann; linux at arm.linux.org.uk;
> thomas.petazzoni at free-electrons.com; Lorenzo Pieralisi; James Morse;
> jason at lakedaemon.net; robh at kernel.org; linux-pci at vger.kernel.org;
> linux-arm-kernel at lists.infradead.org; devicetree at vger.kernel.org;
> Yuanzhichang; Zhudacai; zhangjukuo; qiuzhenfa; liudongdong (C);
> qiujiang; xuwei (O); Liguozhu (Kenneth)
> Subject: Re: [PATCH v7 3/6] PCI: designware: Add ARM64 support
> 
> On 2015/8/21 22:19, Gabriele Paoloni wrote:
> > Hi Liviu
> >
> > Many Thanks for reviewing
> >
> >> -----Original Message-----
> >> From: linux-pci-owner at vger.kernel.org [mailto:linux-pci-
> >> owner at vger.kernel.org] On Behalf Of Liviu Dudau
> >> Sent: Friday, August 21, 2015 2:43 PM
> >> To: Gabriele Paoloni
> >> Cc: Lucas Stach; Wangzhou (B); Bjorn Helgaas; jingoohan1 at gmail.com;
> >> Pratyush Anand; Arnd Bergmann; linux at arm.linux.org.uk;
> >> thomas.petazzoni at free-electrons.com; Lorenzo Pieralisi; James Morse;
> >> jason at lakedaemon.net; robh at kernel.org; linux-pci at vger.kernel.org;
> >> linux-arm-kernel at lists.infradead.org; devicetree at vger.kernel.org;
> >> Yuanzhichang; Zhudacai; zhangjukuo; qiuzhenfa; liudongdong (C);
> >> qiujiang; xuwei (O); Liguozhu (Kenneth)
> >> Subject: Re: [PATCH v7 3/6] PCI: designware: Add ARM64 support
> >>
> >> On Thu, Aug 20, 2015 at 12:10:24PM +0100, Gabriele Paoloni wrote:
> >>> Hi Lucas
> >>>
> >>> Again many thanks for explaining and for your time.
> >>>
> >>> I got your point now and I have dug a bit better in the PCI_DOMAINS
> >> code.
> >>>
> >>> However I have a question...see inline below
> >>>
> >>>> -----Original Message-----
> >>>> From: Lucas Stach [mailto:l.stach at pengutronix.de]
> >>>> Sent: Thursday, August 20, 2015 9:27 AM
> >>>> To: Gabriele Paoloni
> >>>> Cc: Wangzhou (B); Bjorn Helgaas; jingoohan1 at gmail.com; Pratyush
> >> Anand;
> >>>> Arnd Bergmann; linux at arm.linux.org.uk; thomas.petazzoni at free-
> >>>> electrons.com; lorenzo.pieralisi at arm.com; james.morse at arm.com;
> >>>> Liviu.Dudau at arm.com; jason at lakedaemon.net; robh at kernel.org; linux-
> >>>> pci at vger.kernel.org; linux-arm-kernel at lists.infradead.org;
> >>>> devicetree at vger.kernel.org; Yuanzhichang; Zhudacai; zhangjukuo;
> >>>> qiuzhenfa; liudongdong (C); qiujiang; xuwei (O); Liguozhu (Kenneth)
> >>>> Subject: Re: [PATCH v7 3/6] PCI: designware: Add ARM64 support
> >>>>
> >>>> Hi Gab,
> >>>>
> >>>> Am Mittwoch, den 19.08.2015, 16:34 +0000 schrieb Gabriele Paoloni:
> >>>>> Hi Lucas
> >>>>>
> >>>>> First of all many thanks for the quick reply, really appreciated
> >>>>>
> >>>>>> -----Original Message-----
> >>>>>> From: Lucas Stach [mailto:l.stach at pengutronix.de]
> >>>>>> Sent: Wednesday, August 19, 2015 4:37 PM
> >>>>>> To: Gabriele Paoloni
> >>>>>> Cc: Wangzhou (B); Bjorn Helgaas; jingoohan1 at gmail.com; Pratyush
> >>>> Anand;
> >>>>>> Arnd Bergmann; linux at arm.linux.org.uk; thomas.petazzoni at free-
> >>>>>> electrons.com; lorenzo.pieralisi at arm.com; james.morse at arm.com;
> >>>>>> Liviu.Dudau at arm.com; jason at lakedaemon.net; robh at kernel.org;
> >> linux-
> >>>>>> pci at vger.kernel.org; linux-arm-kernel at lists.infradead.org;
> >>>>>> devicetree at vger.kernel.org; Yuanzhichang; Zhudacai; zhangjukuo;
> >>>>>> qiuzhenfa; liudongdong (C); qiujiang; xuwei (O); Liguozhu
> >> (Kenneth)
> >>>>>> Subject: Re: [PATCH v7 3/6] PCI: designware: Add ARM64 support
> >>>>>>
> >>>>>> Hi Gab,
> >>>>>>
> >>>>>> Am Mittwoch, den 19.08.2015, 15:16 +0000 schrieb Gabriele
> >> Paoloni:
> >>>>>>> Hi Lucas
> >>>>>>>
> >>>>>>> I have rewritten the patch to take into account multiple
> >>>> controllers.
> >>>>>>>
> >>>>>>> As you can see now there is a static var in
> >> dw_pcie_host_init()
> >>>> that
> >>>>>> tracks
> >>>>>>> the bus numbers used.
> >>>>>>
> >>>>>> This is wrong. The DT specifies the valid bus number range. You
> >> can
> >>>> not
> >>>>>> just assign the next free bus number to the root bus.
> >>>>>
> >>>>> I think this is what is being done in
> >>>>> http://lxr.free-
> >> electrons.com/source/arch/arm/kernel/bios32.c#L495
> >>>>> and currently designware assigns the root bus number in
> >>>>> http://lxr.free-electrons.com/source/drivers/pci/host/pcie-
> >>>> designware.c#L730
> >>>>>
> >>>> You found the right spot. It works a bit different than I remember,
> >> but
> >>>> is less broken than your current code. :)
> >>>>
> >>>> It actually assigns the next instance a root bus number behind the
> >>>> current instances bus range. Please note the difference to your
> >> code
> >>>> which assigns the next free bus number, which may still lay within
> >> the
> >>>> current instances bus range.
> >>
> >> Hi Gabriele,
> >>
> >>>
> >>> Mmmm here I have done a mistake: in the current designware the
> number
> >> of hw
> >>> controllers is always 1
> >>> http://lxr.free-electrons.com/source/drivers/pci/host/pcie-
> >> designware.c#L510
> >>> So the loop in bios32.c does not work on multiple PCIe ports...
> >>
> >> Bios32.c is broken for multiple PCIe hosts for multiple reasons,
> this
> >> is just
> >> one of them. Hence the effort to get rid of it for maintained
> drivers.
> >
> > As you can see we're pushing hard for this :)
> >
> 
> How about we pass pp->busn->start to pci_create_root_bus as root bus
> number?
> We get pp->busn->start from resource list(res) whose elements come from
> of_pci_get_host_bridge_resources.
> 
> If there is a bus-range item in dts, root bus number will get from it.
> Oppositely, root bus number will be default value(0x0).
> 
> Thanks,
> Zhou

Sounds good to me. So we can remove root_bus_nr

> 
> >>
> >>> However your comment about PCI_DOMAINS enlightened my mind and now
> I
> >> see
> >>> that when CONFIG_PCI_DOMAINS is defined we have the domains numbers
> >>> (tracked by __domain_nr).
> >>
> >> CONFIG_PCI_DOMAINS in itself doesn't do much without adding code to
> >> your driver.
> >> You could request a new domain for each controller with a special
> >> property to
> >> disable that behaviour in the dts, or you could enable
> >> CONFIG_PCI_DOMAINS_GENERIC
> >> which will give you a new domain automatically.
> >
> > So far I see that for ARM and ARM64 CONFIG_PCI_DOMAINS_GENERIC
> defaults to
> > the same value as CONFIG_PCI_DOMAINS (see arch/arm/Kconfig,
> arch/arm64/Kconfig).
> > So I think this is how current designware based drivers get multiple
> PCIe
> > controller to work (they just enable CONFIG_PCI_DOMAINS)...
> >
> >
> >
> >>
> >>> So (correct me if I am wrong) if we have 2 PCIe ports that do not
> >> specify
> >>> the "bus-range" property, both root ports will enumerate starting
> >> from
> >>> root_bus_nr = 0 and everything will still work ok.
> >>
> >> Correct.
> >>
> >> Best regards,
> >> Liviu
> >>
> >>>
> >>> So if my assumption is correct, I do not see why the orginal patch
> >> from Wang
> >>> Zhou is wrong.
> >>> The only point can be that assigning pp->root_bus_nr = 0 is not
> >> required
> >>> as pp memory is kzalloc'ed (an therefore init to zero).
> >>>
> >>>
> >>>>
> >>>>>
> >>>>> In general I agree with you but if you look at all the current
> >>>> drivers
> >>>>> based on designware none of them define the "bus-range" dtb
> >> property.
> >>>>> Therefore doing as you say would break the current driver when we
> >>>> have
> >>>>> multiple controllers...am I right?
> >>>>>
> >>>> The current _code_ works fine for multiple controllers. It's just
> >> that
> >>>> you must define the bus range property in the DTB if you want to
> >> enable
> >>>> multiple instances of one controller and support a kernel without
> >> PCI
> >>>> domains support. As all current implementations have only a single
> >>>> instance of the controller per SoC, or depend on PCI domain
> support,
> >>>> it's totally fine for them to not define the bus ranges property,
> >> as
> >>>> it's an optional property and it is well defined how things behave
> >> if
> >>>> it
> >>>> is absent. We absolutely need to keep that specified behavior.
> >>>>
> >>>>> If that is the case in order to fix this in the way you say I
> >> would
> >>>> need
> >>>>> to assign "bus-range" for all the PCIe drivers with multiple
> >>>> controllers:
> >>>>> in this case I would split the default range evenly (that is, if
> >> we
> >>>> have
> >>>>> two controllers I would define "bus-range"  0-127 and 128-255)
> >>>>>
> >>>>> If you think this solution is ok I can go for it. My only doubt
> >> was
> >>>> about
> >>>>> touching other vendors DTBs....
> >>>>>
> >>>> You don't need to touch any of the current DTBs, as they are fine
> >> with
> >>>> the default bus range behavior. You need to keep the specified
> >> behavior
> >>>> of the bus range property with the new code.
> >>>>
> >>>> Regards,
> >>>> Lucas
> >>>>>
> >>>>>>
> >>>>>> It is perfectly valid to have a bus range of 0x00-0x10 assigned
> >> to
> >>>> one
> >>>>>> instance and 0x50-0xff to the next instance. Additional with
> >> PCIe
> >>>>>> hotplug you may not use the full range of the bus numbers on
> >> one
> >>>>>> instance at the first scan, but only later populate more buses
> >> when
> >>>>>> more
> >>>>>> bridges are added to the tree.
> >>>>>>
> >>>>>>> Drivers that do not specify the bus range in the DTB set pp-
> >>>>>>> root_bus_nr = DW_ROOT_NR_UNDEFINED.
> >>>>>>> Designware will check if the flag is set and will use the
> >>>> automatic
> >>>>>> bus range
> >>>>>>> assignment.
> >>>>>>
> >>>>>> No, please lets get rid of this assignment altogether. The glue
> >>>> drivers
> >>>>>> have no business in assigning the bus range. Please remove the
> >>>>>> pp->root_bus_nr assignment from all the glue drivers.
> >>>>>>
> >>>>>> "bus range" is a generic DW PCIe property, so just parse the
> >> root
> >>>> bus
> >>>>>> number from the DT, it is handled the same way for all the DW
> >> based
> >>>>>> PCIe
> >>>>>> drivers. The bindings specifies that if the bus range property
> >> is
> >>>>>> missing the range is 0x00-0xff, so you can default to 0 as the
> >> root
> >>>> bus
> >>>>>> number in that case.
> >>>>>>
> >>>>>> Also I would think this conversion warrants a patch on its own
> >> and
> >>>>>> should not be mixed in the ARM64 support patch.
> >>>>>>
> >>>>>> Regards,
> >>>>>> Lucas
> >>>>>>
> >>>>
> >>>> --
> >>>> Pengutronix e.K.             | Lucas Stach                 |
> >>>> Industrial Linux Solutions   | http://www.pengutronix.de/  |
> >>>
> >>
> >> --
> >> ====================
> >> | I would like to |
> >> | fix the world,  |
> >> | but they're not |
> >> | giving me the   |
> >>  \ source code!  /
> >>   ---------------
> >>     ?\_(?)_/?
> >>
> >> --
> >> To unsubscribe from this list: send the line "unsubscribe linux-pci"
> in
> >> the body of a message to majordomo at vger.kernel.org
> >> More majordomo info at  http://vger.kernel.org/majordomo-info.html
> 


From robert.jarzmik at free.fr  Mon Aug 24 01:25:34 2015
From: robert.jarzmik at free.fr (Robert Jarzmik)
Date: Mon, 24 Aug 2015 10:25:34 +0200
Subject: [PATCH v2 16/21] ARM: pxa: magician: Add support for alternative
 LCD backlight
In-Reply-To: <55DA3357.6050304@tul.cz> (Petr Cvek's message of "Sun, 23 Aug
 2015 22:55:51 +0200")
References: <cover.1439843482.git.petr.cvek@tul.cz> <55D25A60.7000900@tul.cz>
 <878u95685t.fsf@belgarion.home> <55DA3357.6050304@tul.cz>
Message-ID: <87mvxh2iv5.fsf@belgarion.home>

Petr Cvek <petr.cvek at tul.cz> writes:

> Dne 20.8.2015 v 22:01 Robert Jarzmik napsal(a):
>> Petr Cvek <petr.cvek at tul.cz> writes:
>> 
>>> Add support for alternative LCD backlight with GPIO (no brightness).
>> Here, I don't understand, the commit message is too short.
>> 
>> Are there 2 brightness controls on magician, or are these 2 different magicians
>> (hardware wise), each having a different backlight control ? Or is it there is a
>> GPIO to light up the screen and a PWM backlight ?
>> 
>> I have to understand first.
>> 
> I have aimed for a configuration, where user can use PWM xor GPIO backlight.
You probably know that in a backlight case GPIO is just a subcase of PWM, with
frequency equal to either 0 or max_backlight_freq.

> As pin mux can set GPIO or PWM (or UART :-D) on PWM pin, you can choose if you
> spare few kB (as magician has only 64MB RAM and 64MB flash) on GPIO or will
> have smooth backlight with PWM.

I'm in front of the same dilemna for 5 years ago with the mioa701 (64MB RAM, 2 *
32MB flash). I chose PWM, judging the PWM stack was worth it.

Moreover, pwm can be a module, loaded or not : what memory do you spare in that
case if you don't load the module ?

> I have tested both (I think I have added the gpio backlight for debugging a regression in pwm_bl).
> Only ugly thing is the GPIO definition:
>
> #if IS_ENABLED(CONFIG_PWM_PXA)
> 	/* PWM 0 - LCD backlight */
> 	GPIO16_PWM0_OUT,
> #else
> 	/* Ensure static backlight without any driver */
> 	MFP_CFG_OUT(GPIO16, AF0, DRIVE_LOW),    /* Backlight enabled */
> #endif
>
> Hmmm.. I think I can do this better in pwm-backlight init/exit (same way as
> pxa_ficp). During init the pin mux will switch to Alternate Function (PWM) and
> during exit it will switch to GPIO (which can be used by gpio-backlight). This
> will remove ugly ifdef.

I don't like changing the muxing after initialization that much : the pin muxing
should represent what there is in hardware, and that is a backlight frequency
switched input pin. The one exception is for hardware workarounds such as the
AC97 reset pin.

I won't take an init/exit with a manipulation of an mfp. I'll let you choose one
way instead :
 - either the GPIO
 - or the PWM (module or not)
Don't forget that this init/exit thing won't be available for a devicetree
magician (if that happens).

Cheers.

-- 
Robert


From Haibo.Chen at freescale.com  Mon Aug 24 01:34:07 2015
From: Haibo.Chen at freescale.com (Chen Bough)
Date: Mon, 24 Aug 2015 08:34:07 +0000
Subject: [PATCH v2 2/5] Documentation: Detail permitted DT properties for
 the imx6ul_tsc
In-Reply-To: <20150821092725.GB706@pengutronix.de>
References: <1438077521-12857-1-git-send-email-haibo.chen@freescale.com>
 <1438077521-12857-3-git-send-email-haibo.chen@freescale.com>
 <20150819055434.GF11161@pengutronix.de>
 <BY1PR03MB1388BBEF576297D76E7E3F839A650@BY1PR03MB1388.namprd03.prod.outlook.com>
 <20150821092725.GB706@pengutronix.de>
Message-ID: <BY1PR03MB13889F047C4E1440D2F7554C9A620@BY1PR03MB1388.namprd03.prod.outlook.com>



> -----Original Message-----
> From: Markus Pargmann [mailto:mpa at pengutronix.de]
> Sent: Friday, August 21, 2015 5:27 PM
> To: Chen Haibo-B51421
> Cc: robh+dt at kernel.org; pawel.moll at arm.com; mark.rutland at arm.com;
> ijc+devicetree at hellion.org.uk; galak at codeaurora.org; shawnguo at kernel.org;
> kernel at pengutronix.de; linux at arm.linux.org.uk; dmitry.torokhov at gmail.com;
> devicetree at vger.kernel.org; sbranden at broadcom.com; arnd at arndb.de;
> mchehab at osg.samsung.com; christian.gmeiner at gmail.com;
> scott.liu at emc.com.tw; linux-kernel at vger.kernel.org; hdegoede at redhat.com;
> jonathar at broadcom.com; benjamin.tissoires at redhat.com;
> hans.verkuil at cisco.com; hadess at hadess.net; linux-input at vger.kernel.org;
> geert at linux-m68k.org; sebastien.szymanski at armadeus.com;
> mamlinav at gmail.com; linux-arm-kernel at lists.infradead.org
> Subject: Re: [PATCH v2 2/5] Documentation: Detail permitted DT properties
> for the imx6ul_tsc
> 
> On Fri, Aug 21, 2015 at 08:30:16AM +0000, Chen Bough wrote:
> > Hi Markus,
> >
> > > -----Original Message-----
> > > From: Markus Pargmann [mailto:mpa at pengutronix.de]
> > > Sent: Wednesday, August 19, 2015 1:55 PM
> > > To: Chen Haibo-B51421
> > > Cc: robh+dt at kernel.org; pawel.moll at arm.com; mark.rutland at arm.com;
> > > ijc+devicetree at hellion.org.uk; galak at codeaurora.org;
> > > ijc+shawnguo at kernel.org;
> > > kernel at pengutronix.de; linux at arm.linux.org.uk;
> > > dmitry.torokhov at gmail.com; devicetree at vger.kernel.org;
> > > sbranden at broadcom.com; arnd at arndb.de; mchehab at osg.samsung.com;
> > > christian.gmeiner at gmail.com; scott.liu at emc.com.tw;
> > > linux-kernel at vger.kernel.org; hdegoede at redhat.com;
> > > jonathar at broadcom.com; benjamin.tissoires at redhat.com;
> > > hans.verkuil at cisco.com; hadess at hadess.net;
> > > linux-input at vger.kernel.org; geert at linux-m68k.org;
> > > sebastien.szymanski at armadeus.com; mamlinav at gmail.com;
> > > linux-arm-kernel at lists.infradead.org
> > > Subject: Re: [PATCH v2 2/5] Documentation: Detail permitted DT
> > > properties for the imx6ul_tsc
> > >
> > > Hi,
> > >
> > > On Tue, Jul 28, 2015 at 05:58:38PM +0800, Haibo Chen wrote:
> > > > Here we apply required documentation for the imx6ul touch screen
> > > > controller driver which describe available properties and how to
> > > > use them.
> > > >
> > > > Signed-off-by: Haibo Chen <haibo.chen at freescale.com>
> > > > ---
> > > >  .../bindings/input/touchscreen/imx6ul_tsc.txt      | 36
> > > ++++++++++++++++++++++
> > > >  1 file changed, 36 insertions(+)
> > > >  create mode 100644
> > > > Documentation/devicetree/bindings/input/touchscreen/imx6ul_tsc.txt
> > > >
> > > > diff --git
> > > > a/Documentation/devicetree/bindings/input/touchscreen/imx6ul_tsc.t
> > > > xt
> > > > b/Documentation/devicetree/bindings/input/touchscreen/imx6ul_tsc.t
> > > > xt
> > > > new file mode 100644
> > > > index 0000000..ac41c32
> > > > --- /dev/null
> > > > +++ b/Documentation/devicetree/bindings/input/touchscreen/imx6ul_t
> > > > +++ sc.t
> > > > +++ xt
> > > > @@ -0,0 +1,36 @@
> > > > +* Freescale i.MX6UL Touch Controller
> > > > +
> > > > +Required properties:
> > > > +- compatible: must be "fsl,imx6ul-tsc".
> > > > +- reg: this touch controller address and the ADC2 address.
> > >
> > > This suggests that this driver is using a unit ADC2. Which also
> > > means that there are more than one ADC which are probably identical?
> > >
> > > Shouldn't these ADCs be properly described by their own device nodes
> > > instead of these two register ranges, two interrupts and two clocks?
> > >
> > > Is 'ADC2' usable without tsc? Then ADC1/ADC2 should perhaps get a
> > > proper IIO driver.
> >
> > For i.MX6UL, there are two ADC. ADC1 is a normal ADC, and ADC2 can
> > only works for TSC, the channels of ADC2 are connected to TSC
> > directly. TSC and ADC2 should work together as a touch screen
> controller.
> 
> But as I understand these are two different units. Wouldn't it be better
> to abstract it that way in the DT?

Since the ADC2 just work for TSC, no other use, why not bind ADC2 and TSC?
If separate, seems ADC2 can works as a normal ADC, but actually it can't.

Best regards,

Haibo

> 
> Best regards,
> 
> Markus
> 
> >
> > For ADC1, it share the driver vf610_adc.c (drivers/iio/adc/vf610_adc.c).
> >
> > Best Regards
> >
> > Haibo
> >
> > >
> > > Unfortunately I don't have the reference manual to have a look how
> > > this all works.
> > >
> > > Best regards,
> > >
> > > Markus
> > >
> > > > +- interrupts: the interrupt of this touch controller and ADC2.
> > > > +- clocks: the root clock of touch controller and ADC2.
> > > > +- clock-names; must be "tsc" and "adc".
> > > > +- xnur-gpio: the X- gpio this controller connect to.
> > > > +  This xnur-gpio returns to high once the finger leave the touch
> > > > +screen (The
> > > > +  last touch event the touch controller capture).
> > > > +
> > > > +Optional properties:
> > > > +- measure-delay-time: the value of measure delay time.
> > > > +  Before X-axis or Y-axis measurement, the screen need some time
> > > > +before
> > > > +  even potential distribution ready.
> > > > +  This value depends on the touch screen.
> > > > +- pre-charge-time: the touch screen need some time to precharge.
> > > > +  This value depends on the touch screen.
> > > > +
> > > > +Example:
> > > > +	tsc: tsc at 02040000 {
> > > > +		compatible = "fsl,imx6ul-tsc";
> > > > +		reg = <0x02040000 0x4000>, <0x0219c000 0x4000>;
> > > > +		interrupts = <GIC_SPI 3 IRQ_TYPE_LEVEL_HIGH>,
> > > > +			     <GIC_SPI 101 IRQ_TYPE_LEVEL_HIGH>;
> > > > +		clocks = <&clks IMX6UL_CLK_IPG>,
> > > > +			 <&clks IMX6UL_CLK_ADC2>;
> > > > +		clock-names = "tsc", "adc";
> > > > +		pinctrl-names = "default";
> > > > +		pinctrl-0 = <&pinctrl_tsc>;
> > > > +		xnur-gpio = <&gpio1 3 GPIO_ACTIVE_HIGH>;
> > > > +		measure-delay-time = <0xfff>;
> > > > +		pre-charge-time = <0xffff>;
> > > > +		status = "okay";
> > > > +	};
> > > > --
> > > > 1.9.1
> > > >
> > > >
> > > >
> > >
> > > --
> > > Pengutronix e.K.                           |
> > > |
> > > Industrial Linux Solutions                 |
> http://www.pengutronix.de/
> > > |
> > > Peiner Str. 6-8, 31137 Hildesheim, Germany | Phone:
> > > +49-5121-206917-0
> > > |
> > > Amtsgericht Hildesheim, HRA 2686           | Fax:   +49-5121-206917-
> 5555
> > > |
> 
> --
> Pengutronix e.K.                           |
> |
> Industrial Linux Solutions                 | http://www.pengutronix.de/
> |
> Peiner Str. 6-8, 31137 Hildesheim, Germany | Phone: +49-5121-206917-0
> |
> Amtsgericht Hildesheim, HRA 2686           | Fax:   +49-5121-206917-5555
> |

From maitysanchayan at gmail.com  Mon Aug 24 01:32:12 2015
From: maitysanchayan at gmail.com (maitysanchayan at gmail.com)
Date: Mon, 24 Aug 2015 14:02:12 +0530
Subject: [PATCH v9 0/4] Implement OCOTP driver for Vybrid using NVMEM
In-Reply-To: <cover.1439384645.git.maitysanchayan@gmail.com>
References: <cover.1439384645.git.maitysanchayan@gmail.com>
Message-ID: <20150824083212.GB2722@Sanchayan-Arch.toradex.int>

Hello,

Ping? Any feedback? Is this good to be merged?

Thanks.

- Sanchayan.

On 15-08-12 18:49:17, Sanchayan Maity wrote:
> Hello,
> 
> This patchset is based on top of v9 of Srinivas's NVMEM framework patches.
> Tested on Greg's tree char-misc-next branch along with Stefan's NAND driver
> patchset.
> 
> Sample output on Colibri VF50
> 
> root at colibri-vf:/sys/bus/nvmem/devices/ocotp0# uname -a
> Linux colibri-vf 4.2.0-rc6-00130-g24fcfdc #3 SMP Wed Aug 12 18:31:24 IST 2015 armv7l GNU/Linux
> 
> root at colibri-vf:/sys/bus/nvmem/devices/ocotp0# hexdump nvmem
> 0000000 0000 0000 0000 0000 0000 0000 0000 0000
> *
> 0000410 72a6 df64 0000 0000 0000 0000 0000 0000
> 0000420 11d4 2c14 0000 0000 0000 0000 0000 0000
> 0000430 0000 0000 0000 0000 0000 0000 0000 0000
> *
> 0000450 0280 0000 0000 0000 0000 0000 0000 0000
> 0000460 0000 0000 0000 0000 0000 0000 0000 0000
> *
> 0000880 8f01 0000 0000 0000 0000 0000 0000 0000
> 0000890 0000 0000 0000 0000 0000 0000 0000 0000
> *
> 00008c0 0000 1000 0000 0000 0000 0000 0000 0000
> 00008d0 3202 0800 0000 0000 0000 0000 0000 0000
> 00008e0 0000 e100 0000 0000 0000 0000 0000 0000
> 00008f0 0000 0000 0000 0000 0000 0000 0000 0000
> *
> 0000c80 bada bada 0000 0000 0000 0000 0000 0000
> *
> 0000cc0 0000 0000 0000 0000 0000 0000 0000 0000
> *
> 0000cf0
> 
> The driver has changed quite a bit from the first version
> relying on of_platform_populate in mach file, to using
> SoC driver under drivers/soc and finally to NVMEM.
> 
> Feedback and comments most welcome.
> 
> Version 8 patches can be found here
> https://lkml.org/lkml/2015/8/10/566
> 
> Version 7 patches can be found here
> https://lkml.org/lkml/2015/8/6/440
> 
> Version 6 RFC patches can be found here
> http://lkml.iu.edu/hypermail/linux/kernel/1506.2/05123.html
> 
> Version 5 of the patchset can be found here
> http://lkml.iu.edu/hypermail/linux/kernel/1506.0/03787.html
> 
> Version 4 of the patchset can be found here
> https://lkml.org/lkml/2015/5/26/199
> 
> Version 3 of the patchset can be found here
> http://www.spinics.net/lists/arm-kernel/msg420847.html
> 
> Version 2 of the patchset can be found here
> http://www.spinics.net/lists/devicetree/msg80654.html
> 
> Version 1 of the patchset can be found here
> http://www.spinics.net/lists/devicetree/msg80257.html
> 
> The RFC version can be found here
> https://lkml.org/lkml/2015/5/11/13
> 
> Changes since v8:
> 1. Fix three lines over 80 characters
> 2. Rebase on top of Greg's char-misc-next branch
> 
> Changes since v7:
> 1. Add COMPILE_TEST to Kconfig
> 2. Use GENMASK and BIT macros where applicable
> 3. Fix a code alignment issue
> 4. Get the max_register value for regmap config using
> resource_size()
> 5. Also add copyright info as the driver logic is based off
> on ocotp code in barebox
> 6. Add missing info related to clock in DT binding doc
> 
> Changes since v6:
> 1. Use the v9 of NVMEM framework patchset
> 2. Add a few comments
> 3. Initialise buffer address not part of the fuse map to 0
> instead of only handling buffer locations with valid fuse
> addresses.
> 
> Changes since v5:
> Use NVMEM framework by Srinivas and Maxime
> 
> Changes since v4:
> 1. Use devm_* family of functions and use a struct to get rid of
> global variables (suggested by Joachim Eastwood)
> 2. Make Kconfig govern the compilation with tristate, instead of
> earlier bool. Paul Bolle raised a valid point that perhaps this
> should have been built in with the bool, however I had not taken
> into consideration generic distro kernels and it makes sense to
> have this tristated. (comments from Paul Bolle and Andreas Farber)
> 
> Changes since v3:
> Instead of using the syscon_regmap_lookup_by_compatible function
> use a phandle in the device tree along with offsets specified in
> this phandle node and then read the offset along with the device
> node in the driver for reading from the required region.
> 
> Changes since v2:
> Implement the SoC bus code as a driver in drivers/soc
> by registering with fsl,mscm-cpucfg as per Arnd's feedback
> 
> Changes since v1:
> Sort the headers in alphabetical order
> 
> Changes since RFC:
> Use a DT entry for the ROM area while specifying it as syscon.
> 
> Thanks & Regards,
> Sanchayan Maity.
> 
> Sanchayan Maity (4):
>   clk: clk-vf610: Add clock for Vybrid OCOTP controller
>   ARM: dts: vfxxx: Add OCOTP node
>   drivers: nvmem: Add Vybrid OCOTP support
>   nvmem: Add DT binding documentation for Vybrid OCOTP driver
> 
>  .../devicetree/bindings/nvmem/vf610-ocotp.txt      |  21 ++
>  arch/arm/boot/dts/vfxxx.dtsi                       |   9 +
>  drivers/clk/imx/clk-vf610.c                        |   1 +
>  drivers/nvmem/Kconfig                              |  10 +
>  drivers/nvmem/Makefile                             |   2 +
>  drivers/nvmem/vf610-ocotp.c                        | 302 +++++++++++++++++++++
>  include/dt-bindings/clock/vf610-clock.h            |   3 +-
>  7 files changed, 347 insertions(+), 1 deletion(-)
>  create mode 100644 Documentation/devicetree/bindings/nvmem/vf610-ocotp.txt
>  create mode 100644 drivers/nvmem/vf610-ocotp.c
> 
> -- 
> 2.5.0
> 


From geert at linux-m68k.org  Mon Aug 24 01:36:04 2015
From: geert at linux-m68k.org (Geert Uytterhoeven)
Date: Mon, 24 Aug 2015 10:36:04 +0200
Subject: Build regressions/improvements in v4.2-rc8
In-Reply-To: <1440405251-9184-1-git-send-email-geert@linux-m68k.org>
References: <1440405251-9184-1-git-send-email-geert@linux-m68k.org>
Message-ID: <CAMuHMdVomabvJOLLJ-tJs6KjL05YpH3zLkyrPbyEghe=WvOVkA@mail.gmail.com>

On Mon, Aug 24, 2015 at 10:34 AM, Geert Uytterhoeven
<geert at linux-m68k.org> wrote:
> JFYI, when comparing v4.2-rc8[1] to v4.2-rc7[3], the summaries are:
>   - build errors: +4/-7

4 regressions:
  + /home/kisskb/slave/src/include/linux/kvm_host.h: error: array
subscript is above array bounds [-Werror=array-bounds]:  => 430:19
    (arch/powerpc/kvm/book3s_64_mmu.c: In function 'kvmppc_mmu
_book3s_64_tlbie':)

powerpc-randconfig (seen before in a v3.15-rc1 build?)

  + error: initramfs.c: undefined reference to `__stack_chk_guard':
=> .init.text+0x1cb0)
    (init/built-in.o: In function `parse_header':)

x86_64-randconfig

  + error: pci.c: undefined reference to `pci_ioremap_io':  => .init.text+0x3c4)
    (arch/arm/mach-versatile/built-in.o: In function `pci_versatile_setup')

arm-randconfig

> [1] http://kisskb.ellerman.id.au/kisskb/head/9289/ (253 out of 254 configs)
> [3] http://kisskb.ellerman.id.au/kisskb/head/9260/ (253 out of 254 configs)

Gr{oetje,eeting}s,

                        Geert

--
Geert Uytterhoeven -- There's lots of Linux beyond ia32 -- geert at linux-m68k.org

In personal conversations with technical people, I call myself a hacker. But
when I'm talking to journalists I just say "programmer" or something like that.
                                -- Linus Torvalds


From kernel at martin.sperl.org  Mon Aug 24 01:40:03 2015
From: kernel at martin.sperl.org (kernel at martin.sperl.org)
Date: Mon, 24 Aug 2015 08:40:03 +0000
Subject: [PATCH v4 0/5] bcm2835: auxiliar device support for spi
Message-ID: <1440405608-3995-1-git-send-email-kernel@martin.sperl.org>

From: Martin Sperl <kernel at martin.sperl.org>

The BCM2835 contains 3 auxiliar devices:
* spi1
* spi2
* uart1

All of those 3 devices are enabled/disabled via a shared register,
which is set by default to be disabled.

Access to this register needs to get serialized.

So fter several iterations of discussions with the following idea:
* syscon - device tree should describe HW not drivers to use -
           'compatiblity = "brcm,bcm2835-aux-enable", "syscon";'
           is not acceptable
* regulator - it is not necessarily a regulator or a power gate
              that is implemented in HW, so it is not valid to use
              this framework

The recommendation was made to create a new minimal API in soc
just for access to this shared enable/disable register.

This patch-series implements:
* the bcm2835-auxiliar device enable/disable api in soc.
* the bcm2835-auxiliar spi device driver

The uart1 device driver (ns16550 based) is not implemented so far
but should be using the same API.

Martin Sperl (5):
  soc: bcm2835: auxiliar devices enable infrastructure
  ARM: bcm2835: add DT for the bcm2835 auxiliar devices
  dt/bindings: bcm2835: add binding documentation for bcm2835-aux
  spi: bcm2835: new driver implementing auxiliar spi1/spi2 on the
    bcm2835 soc
  dt/bindings: bcm2835: Add binding documentation for auxiliar spi
    devices

 .../bindings/soc/bcm/brcm,bcm2835-aux.txt          |   27 ++
 .../bindings/spi/brcm,bcm2835-aux-spi.txt          |   61 +++
 arch/arm/boot/dts/bcm2835.dtsi                     |   37 ++
 arch/arm/configs/bcm2835_defconfig                 |    1 +
 drivers/soc/Kconfig                                |    1 +
 drivers/soc/Makefile                               |    1 +
 drivers/soc/bcm/Kconfig                            |   11 +
 drivers/soc/bcm/Makefile                           |    1 +
 drivers/soc/bcm/bcm2835-aux.c                      |  154 ++++++
 drivers/spi/Kconfig                                |   12 +
 drivers/spi/Makefile                               |    1 +
 drivers/spi/spi-bcm2835aux.c                       |  506 ++++++++++++++++++++
 include/linux/soc/bcm/bcm2835-aux.h                |   23 +
 13 files changed, 836 insertions(+)
 create mode 100644 Documentation/devicetree/bindings/soc/bcm/brcm,bcm2835-aux.txt
 create mode 100644 Documentation/devicetree/bindings/spi/brcm,bcm2835-aux-spi.txt
 create mode 100644 drivers/soc/bcm/Kconfig
 create mode 100644 drivers/soc/bcm/Makefile
 create mode 100644 drivers/soc/bcm/bcm2835-aux.c
 create mode 100644 drivers/spi/spi-bcm2835aux.c
 create mode 100644 include/linux/soc/bcm/bcm2835-aux.h

--
1.7.10.4



From kernel at martin.sperl.org  Mon Aug 24 01:40:04 2015
From: kernel at martin.sperl.org (kernel at martin.sperl.org)
Date: Mon, 24 Aug 2015 08:40:04 +0000
Subject: [PATCH v4 1/5] soc: bcm2835: auxiliar devices enable infrastructure
In-Reply-To: <1440405608-3995-1-git-send-email-kernel@martin.sperl.org>
References: <1440405608-3995-1-git-send-email-kernel@martin.sperl.org>
Message-ID: <1440405608-3995-2-git-send-email-kernel@martin.sperl.org>

From: Martin Sperl <kernel at martin.sperl.org>

The bcm2835 SOC contains 3 auxiliar devices (spi1, spi2 and uart1)
that all are enabled via a shared register.

To serialize access to this shared register this soc-driver
is created that implements:
  bcm2835aux_enable(struct device *dev, const char *property);
  bcm2835aux_disable(struct device *dev, const char *property);

Which will read the property from the device tree of the device
and enable/disable that specific device as per device tree.

First use of this api will be spi-bcm2835aux.

Signed-off-by: Martin Sperl <kernel at martin.sperl.org>
---
 drivers/soc/Kconfig                 |    1 +
 drivers/soc/Makefile                |    1 +
 drivers/soc/bcm/Kconfig             |   11 +++
 drivers/soc/bcm/Makefile            |    1 +
 drivers/soc/bcm/bcm2835-aux.c       |  154 +++++++++++++++++++++++++++++++++++
 include/linux/soc/bcm/bcm2835-aux.h |   23 ++++++
 6 files changed, 191 insertions(+)
 create mode 100644 drivers/soc/bcm/Kconfig
 create mode 100644 drivers/soc/bcm/Makefile
 create mode 100644 drivers/soc/bcm/bcm2835-aux.c
 create mode 100644 include/linux/soc/bcm/bcm2835-aux.h

diff --git a/drivers/soc/Kconfig b/drivers/soc/Kconfig
index 96ddecb..5506e39 100644
--- a/drivers/soc/Kconfig
+++ b/drivers/soc/Kconfig
@@ -1,5 +1,6 @@
 menu "SOC (System On Chip) specific Drivers"

+source "drivers/soc/bcm/Kconfig"
 source "drivers/soc/mediatek/Kconfig"
 source "drivers/soc/qcom/Kconfig"
 source "drivers/soc/sunxi/Kconfig"
diff --git a/drivers/soc/Makefile b/drivers/soc/Makefile
index 7dc7c0d..c5744e1 100644
--- a/drivers/soc/Makefile
+++ b/drivers/soc/Makefile
@@ -2,6 +2,7 @@
 # Makefile for the Linux Kernel SOC specific device drivers.
 #

+obj-$(CONFIG_ARCH_BCM)		+= bcm/
 obj-$(CONFIG_ARCH_MEDIATEK)	+= mediatek/
 obj-$(CONFIG_ARCH_QCOM)		+= qcom/
 obj-$(CONFIG_ARCH_SUNXI)	+= sunxi/
diff --git a/drivers/soc/bcm/Kconfig b/drivers/soc/bcm/Kconfig
new file mode 100644
index 0000000..b0af34b3
--- /dev/null
+++ b/drivers/soc/bcm/Kconfig
@@ -0,0 +1,11 @@
+#
+# Broadcom SoC drivers
+#
+config SOC_BCM2835_AUX
+	tristate "Broadcom BCM2835 aux"
+	depends on OF
+	depends on ARCH_BCM2835 || COMPILE_TEST
+
+	help
+	  Support to enable/disable the BCM2835 auxiliar
+	  devices spi1, spi2, uart1
diff --git a/drivers/soc/bcm/Makefile b/drivers/soc/bcm/Makefile
new file mode 100644
index 0000000..370a872
--- /dev/null
+++ b/drivers/soc/bcm/Makefile
@@ -0,0 +1 @@
+obj-$(CONFIG_SOC_BCM2835_AUX) += bcm2835-aux.o
diff --git a/drivers/soc/bcm/bcm2835-aux.c b/drivers/soc/bcm/bcm2835-aux.c
new file mode 100644
index 0000000..887508d
--- /dev/null
+++ b/drivers/soc/bcm/bcm2835-aux.c
@@ -0,0 +1,154 @@
+/*
+ * bcm2835-aux
+ *
+ * Copyright (C) 2015 Martin Sperl
+ *
+ * Author: Martin Sperl <kernel at martin.sperl.org>
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2 of the License, or
+ * (at your option) any later version.
+ */
+
+#include <linux/device.h>
+#include <linux/err.h>
+#include <linux/io.h>
+#include <linux/soc/bcm/bcm2835-aux.h>
+#include <linux/module.h>
+#include <linux/of.h>
+#include <linux/platform_device.h>
+#include <linux/slab.h>
+#include <linux/spinlock.h>
+
+static DEFINE_SPINLOCK(bcm2835aux_lock);
+
+static struct platform_driver bcm2835aux_driver;
+
+static int bcm2835aux_dev_match(struct device *dev, void *data)
+{
+	struct device_node *dn = data;
+
+	return (dev->of_node == dn) ? 1 : 0;
+}
+
+static void *bcm2835aux_find_base(struct device *dev, const char *property)
+{
+	struct device *found = NULL;
+	struct device_node *np;
+
+	/* get the phandle of the device */
+	np = of_parse_phandle(dev->of_node, property, 0);
+	if (!np) {
+		dev_err(dev, "missing property %s\n", property);
+		return ERR_PTR(-ENODEV);
+	}
+
+	/* now find the device it points to */
+	found = driver_find_device(&bcm2835aux_driver.driver, NULL,
+				   np, bcm2835aux_dev_match);
+	if (!found) {
+		dev_err(dev, "device for phandle of %s not found\n",
+			property);
+		return ERR_PTR(-ENODEV);
+	}
+
+	/* now we got the device, so return the pointer */
+	return dev_get_drvdata(found);
+}
+
+static u32 bcm2835aux_find_mask(struct device *dev, const char *property)
+{
+	int err;
+	u32 mask;
+
+	err = of_property_read_u32_index(dev->of_node, property, 1, &mask);
+	if (err) {
+		dev_err(dev, "missing argument to %s: %d\n",
+			property, err);
+		return 0;
+	}
+
+	return mask;
+}
+
+static int bcm2835aux_bitset(struct device *dev, const char *property,
+			     bool set)
+{
+	u32 v, mask;
+	unsigned long flags;
+	void __iomem *base;
+
+	/* find the device */
+	base = bcm2835aux_find_base(dev, property);
+	if (IS_ERR(base))
+		return PTR_ERR(base);
+
+	/* and extract the mask */
+	mask = bcm2835aux_find_mask(dev, property);
+	if (!mask)
+		return -ENOENT;
+
+	spin_lock_irqsave(&bcm2835aux_lock, flags);
+
+	v = readl(base);
+	if (set)
+		v |= mask;
+	else
+		v &= ~mask;
+
+	writel(v, base);
+
+	spin_unlock_irqrestore(&bcm2835aux_lock, flags);
+
+	return 0;
+}
+
+int bcm2835aux_enable(struct device *dev, const char *property)
+{
+	return bcm2835aux_bitset(dev, property, true);
+}
+EXPORT_SYMBOL_GPL(bcm2835aux_enable);
+
+int bcm2835aux_disable(struct device *dev, const char *property)
+{
+	return bcm2835aux_bitset(dev, property, false);
+}
+EXPORT_SYMBOL_GPL(bcm2835aux_disable);
+
+static int bcm2835aux_probe(struct platform_device *pdev)
+{
+	struct resource *res;
+	void __iomem *base;
+
+	res = platform_get_resource(pdev, IORESOURCE_MEM, 0);
+	if (!res)
+		return -ENOENT;
+
+	base = devm_ioremap_resource(&pdev->dev, res);
+	if (IS_ERR(base))
+		return PTR_ERR(base);
+
+	platform_set_drvdata(pdev, base);
+
+	return 0;
+}
+
+static const struct of_device_id bcm2835aux_match[] = {
+	{ .compatible = "brcm,bcm2835-aux", },
+	{}
+};
+MODULE_DEVICE_TABLE(of, bcm2835aux_match);
+
+static struct platform_driver bcm2835aux_driver = {
+	.driver = {
+		.name           = "bcm2835-aux",
+		.of_match_table	= bcm2835aux_match,
+	},
+	.probe			= bcm2835aux_probe,
+};
+module_platform_driver(bcm2835aux_driver);
+
+MODULE_DESCRIPTION("enable/disable driver for aux-spi1/spi2/uart1 on Broadcom BCM2835");
+MODULE_AUTHOR("Martin Sperl <kernel at martin.sperl.org>");
+MODULE_LICENSE("GPL v2");
diff --git a/include/linux/soc/bcm/bcm2835-aux.h b/include/linux/soc/bcm/bcm2835-aux.h
new file mode 100644
index 0000000..17a64c6
--- /dev/null
+++ b/include/linux/soc/bcm/bcm2835-aux.h
@@ -0,0 +1,23 @@
+/*
+ * Copyright (C) 2015 Martin Sperl
+ *
+ * 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 __BCM2835_AUX_H__
+#define __BCM2835_AUX_H__
+
+struct device;
+
+int bcm2835aux_enable(struct device *dev, const char *property);
+int bcm2835aux_disable(struct device *dev, const char *property);
+
+#endif
--
1.7.10.4



From kernel at martin.sperl.org  Mon Aug 24 01:40:05 2015
From: kernel at martin.sperl.org (kernel at martin.sperl.org)
Date: Mon, 24 Aug 2015 08:40:05 +0000
Subject: [PATCH v4 2/5] ARM: bcm2835: add DT for the bcm2835 auxiliar devices
In-Reply-To: <1440405608-3995-1-git-send-email-kernel@martin.sperl.org>
References: <1440405608-3995-1-git-send-email-kernel@martin.sperl.org>
Message-ID: <1440405608-3995-3-git-send-email-kernel@martin.sperl.org>

From: Martin Sperl <kernel at martin.sperl.org>

Add device tree definitions for auxiliar bcm2835 devices:
* spi1
* spi2
* uart1

This also include a device to get used by the relevant
device-drivers (via a shared register) to enable/disable
the HW-block.

Signed-off-by: Martin Sperl <kernel at martin.sperl.org>
---
 arch/arm/boot/dts/bcm2835.dtsi |   37 +++++++++++++++++++++++++++++++++++++
 1 file changed, 37 insertions(+)

diff --git a/arch/arm/boot/dts/bcm2835.dtsi b/arch/arm/boot/dts/bcm2835.dtsi
index 301c73f..4e6fc61 100644
--- a/arch/arm/boot/dts/bcm2835.dtsi
+++ b/arch/arm/boot/dts/bcm2835.dtsi
@@ -158,6 +158,43 @@
 		arm-pmu {
 			compatible = "arm,arm1176-pmu";
 		};
+
+		aux_enable: aux_enable at 0x7e215004 {
+			compatible = "brcm,bcm2835-aux";
+			reg = <0x7e215004 0x04>;
+			#address-cells = <1>;
+			#size-cells = <0>;
+		};
+
+		uart1: uart at 7e215040 {
+			compatible = "brcm,bcm2835-aux-uart";
+			reg = <0x7e215040 0x40>;
+			interrupts = <1 29>;
+			brcm,aux-enable = <&aux_enable 1>;
+			status = "disabled";
+		};
+
+		spi1: spi at 7e215080 {
+			compatible = "brcm,bcm2835-aux-spi";
+			reg = <0x7e215080 0x40>;
+			brcm,aux-enable = <&aux_enable 2>;
+			interrupts = <1 29>;
+			clocks = <&clk_spi>;
+			#address-cells = <1>;
+			#size-cells = <0>;
+			status = "disabled";
+		};
+
+		spi2: spi at 7e2150c0 {
+			compatible = "brcm,bcm2835-aux-spi";
+			reg = <0x7e2150c0 0x40>;
+			brcm,aux-enable = <&aux_enable 4>;
+			interrupts = <1 29>;
+			clocks = <&clk_spi>;
+			#address-cells = <1>;
+			#size-cells = <0>;
+			status = "disabled";
+		};
 	};

 	clocks {
--
1.7.10.4



From kernel at martin.sperl.org  Mon Aug 24 01:40:06 2015
From: kernel at martin.sperl.org (kernel at martin.sperl.org)
Date: Mon, 24 Aug 2015 08:40:06 +0000
Subject: [PATCH v4 3/5] dt/bindings: bcm2835: add binding documentation for
 bcm2835-aux
In-Reply-To: <1440405608-3995-1-git-send-email-kernel@martin.sperl.org>
References: <1440405608-3995-1-git-send-email-kernel@martin.sperl.org>
Message-ID: <1440405608-3995-4-git-send-email-kernel@martin.sperl.org>

From: Martin Sperl <kernel at martin.sperl.org>

Signed-off-by: Martin Sperl <kernel at martin.sperl.org>
---
 .../bindings/soc/bcm/brcm,bcm2835-aux.txt          |   27 ++++++++++++++++++++
 1 file changed, 27 insertions(+)
 create mode 100644 Documentation/devicetree/bindings/soc/bcm/brcm,bcm2835-aux.txt

diff --git a/Documentation/devicetree/bindings/soc/bcm/brcm,bcm2835-aux.txt b/Documentation/devicetree/bindings/soc/bcm/brcm,bcm2835-aux.txt
new file mode 100644
index 0000000..8b79cf3
--- /dev/null
+++ b/Documentation/devicetree/bindings/soc/bcm/brcm,bcm2835-aux.txt
@@ -0,0 +1,27 @@
+Broadcom BCM2835 auxiliar device enable register
+
+the BCM2835 contains 3 auxiliar devices (spi1/spi2/uart1)
+which need to get enabled via a shared register.
+
+Required properties:
+- compatible: Should be "brcm,bcm2835-aux".
+- reg: Should contain register location and length for the
+       enable register
+
+Example:
+
+aux_enable: aux_enable at 0x7e215004 {
+	compatible = "bcrm,bcm2835-aux";
+	reg = <0x7e215004 0x04>;
+};
+
+Typically used in the respective auxiliar device descriptions
+like this:
+
+uart1: uart at 7e215040 {
+	...
+	brcm,aux-enable = <&aux_enable 1>;
+	...
+};
+
+The name of the property can be device/driver specific.
--
1.7.10.4



From kernel at martin.sperl.org  Mon Aug 24 01:40:07 2015
From: kernel at martin.sperl.org (kernel at martin.sperl.org)
Date: Mon, 24 Aug 2015 08:40:07 +0000
Subject: [PATCH v4 4/5] spi: bcm2835: new driver implementing auxiliar
 spi1/spi2 on the bcm2835 soc
In-Reply-To: <1440405608-3995-1-git-send-email-kernel@martin.sperl.org>
References: <1440405608-3995-1-git-send-email-kernel@martin.sperl.org>
Message-ID: <1440405608-3995-5-git-send-email-kernel@martin.sperl.org>

From: Martin Sperl <kernel at martin.sperl.org>

Signed-off-by: Martin Sperl <kernel at martin.sperl.org>
---
 arch/arm/configs/bcm2835_defconfig |    1 +
 drivers/spi/Kconfig                |   12 +
 drivers/spi/Makefile               |    1 +
 drivers/spi/spi-bcm2835aux.c       |  506 ++++++++++++++++++++++++++++++++++++
 4 files changed, 520 insertions(+)
 create mode 100644 drivers/spi/spi-bcm2835aux.c

diff --git a/arch/arm/configs/bcm2835_defconfig b/arch/arm/configs/bcm2835_defconfig
index 31cb073..a205c8b 100644
--- a/arch/arm/configs/bcm2835_defconfig
+++ b/arch/arm/configs/bcm2835_defconfig
@@ -75,6 +75,7 @@ CONFIG_I2C_CHARDEV=y
 CONFIG_I2C_BCM2835=y
 CONFIG_SPI=y
 CONFIG_SPI_BCM2835=y
+CONFIG_SPI_BCM2835AUX=y
 CONFIG_GPIO_SYSFS=y
 # CONFIG_HWMON is not set
 CONFIG_FB=y
diff --git a/drivers/spi/Kconfig b/drivers/spi/Kconfig
index 43f6d3d..133f5ca 100644
--- a/drivers/spi/Kconfig
+++ b/drivers/spi/Kconfig
@@ -88,6 +88,18 @@ config SPI_BCM2835
 	  is for the regular SPI controller. Slave mode operation is not also
 	  not supported.

+config SPI_BCM2835AUX
+	tristate "BCM2835 SPI auxiliar controller"
+	depends on ARCH_BCM2835 || COMPILE_TEST
+	depends on GPIOLIB
+	select SOC_BCM2835AUX
+	help
+	  This selects a driver for the Broadcom BCM2835 SPI aux master.
+
+	  The BCM2835 contains two types of SPI master controller; the
+	  "universal SPI master", and the regular SPI controller.
+	  This driver is for the universal/auxiliar SPI controller.
+
 config SPI_BFIN5XX
 	tristate "SPI controller driver for ADI Blackfin5xx"
 	depends on BLACKFIN && !BF60x
diff --git a/drivers/spi/Makefile b/drivers/spi/Makefile
index 9746beb2..4e9cba3 100644
--- a/drivers/spi/Makefile
+++ b/drivers/spi/Makefile
@@ -15,6 +15,7 @@ obj-$(CONFIG_SPI_ATMEL)			+= spi-atmel.o
 obj-$(CONFIG_SPI_ATH79)			+= spi-ath79.o
 obj-$(CONFIG_SPI_AU1550)		+= spi-au1550.o
 obj-$(CONFIG_SPI_BCM2835)		+= spi-bcm2835.o
+obj-$(CONFIG_SPI_BCM2835AUX)		+= spi-bcm2835aux.o
 obj-$(CONFIG_SPI_BCM53XX)		+= spi-bcm53xx.o
 obj-$(CONFIG_SPI_BCM63XX)		+= spi-bcm63xx.o
 obj-$(CONFIG_SPI_BCM63XX_HSSPI)		+= spi-bcm63xx-hsspi.o
diff --git a/drivers/spi/spi-bcm2835aux.c b/drivers/spi/spi-bcm2835aux.c
new file mode 100644
index 0000000..9e056f6
--- /dev/null
+++ b/drivers/spi/spi-bcm2835aux.c
@@ -0,0 +1,506 @@
+/*
+ * Driver for Broadcom BCM2835 SPI Controllers
+ *
+ * the driver does not rely on the native chipselects at all
+ * but only uses the gpio type chipselects
+ *
+ * Based on: spi-bcm2835.c
+ *
+ * Copyright (C) 2015 Martin Sperl
+ *
+ * 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.h>
+#include <linux/completion.h>
+#include <linux/delay.h>
+#include <linux/err.h>
+#include <linux/interrupt.h>
+#include <linux/io.h>
+#include <linux/kernel.h>
+#include <linux/soc/bcm/bcm2835-aux.h>
+#include <linux/module.h>
+#include <linux/of.h>
+#include <linux/of_address.h>
+#include <linux/of_device.h>
+#include <linux/of_gpio.h>
+#include <linux/of_irq.h>
+#include <linux/regmap.h>
+#include <linux/spi/spi.h>
+#include <linux/spinlock.h>
+
+/*
+ * shared aux registers between spi1/spi2 and uart1
+ *
+ * these defines could go to a separate module if needed
+ * so that it can also get used with the uart1 implementation
+ * when it materializes.
+ */
+
+/* the AUX register offsets */
+#define BCM2835_AUX_IRQ		0x00
+#define BCM2835_AUX_ENABLE	0x04
+
+/* the AUX Bitfield identical for both register */
+#define BCM2835_AUX_BIT_UART	0x00000001
+#define BCM2835_AUX_BIT_SPI1	0x00000002
+#define BCM2835_AUX_BIT_SPI2	0x00000004
+
+/*
+ * spi register defines
+ *
+ * note there is garbage in the "official" documentation,
+ * so somedata taken from the file:
+ *   brcm_usrlib/dag/vmcsx/vcinclude/bcm2708_chip/aux_io.h
+ * inside of:
+ *   http://www.broadcom.com/docs/support/videocore/Brcm_Android_ICS_Graphics_Stack.tar.gz
+ */
+
+/* SPI register offsets */
+#define BCM2835_AUX_SPI_CNTL0	0x00
+#define BCM2835_AUX_SPI_CNTL1	0x04
+#define BCM2835_AUX_SPI_STAT	0x08
+#define BCM2835_AUX_SPI_PEEK	0x0C
+#define BCM2835_AUX_SPI_IO	0x20
+#define BCM2835_AUX_SPI_TXHOLD	0x30
+
+/* Bitfields in CNTL0 */
+#define BCM2835_AUX_SPI_CNTL0_SPEED	0xFFF00000
+#define BCM2835_AUX_SPI_CNTL0_SPEED_MAX	0xFFF
+#define BCM2835_AUX_SPI_CNTL0_SPEED_SHIFT	20
+#define BCM2835_AUX_SPI_CNTL0_CS	0x000E0000
+#define BCM2835_AUX_SPI_CNTL0_POSTINPUT	0x00010000
+#define BCM2835_AUX_SPI_CNTL0_VAR_CS	0x00008000
+#define BCM2835_AUX_SPI_CNTL0_VAR_WIDTH	0x00004000
+#define BCM2835_AUX_SPI_CNTL0_DOUTHOLD	0x00003000
+#define BCM2835_AUX_SPI_CNTL0_ENABLE	0x00000800
+#define BCM2835_AUX_SPI_CNTL0_CPHA_IN	0x00000400
+#define BCM2835_AUX_SPI_CNTL0_CLEARFIFO	0x00000200
+#define BCM2835_AUX_SPI_CNTL0_CPHA_OUT	0x00000100
+#define BCM2835_AUX_SPI_CNTL0_CPOL	0x00000080
+#define BCM2835_AUX_SPI_CNTL0_MSBF_OUT	0x00000040
+#define BCM2835_AUX_SPI_CNTL0_SHIFTLEN	0x0000003F
+
+/* Bitfields in CNTL1 */
+#define BCM2835_AUX_SPI_CNTL1_CSHIGH	0x00000700
+#define BCM2835_AUX_SPI_CNTL1_IDLE	0x00000080
+#define BCM2835_AUX_SPI_CNTL1_TXEMPTY	0x00000040
+#define BCM2835_AUX_SPI_CNTL1_MSBF_IN	0x00000002
+#define BCM2835_AUX_SPI_CNTL1_KEEP_IN	0x00000001
+
+/* Bitfields in STAT */
+#define BCM2835_AUX_SPI_STAT_TX_LVL	0xFF000000
+#define BCM2835_AUX_SPI_STAT_RX_LVL	0x00FF0000
+#define BCM2835_AUX_SPI_STAT_TX_FULL	0x00000400
+#define BCM2835_AUX_SPI_STAT_TX_EMPTY	0x00000200
+#define BCM2835_AUX_SPI_STAT_RX_FULL	0x00000100
+#define BCM2835_AUX_SPI_STAT_RX_EMPTY	0x00000080
+#define BCM2835_AUX_SPI_STAT_BUSY	0x00000040
+#define BCM2835_AUX_SPI_STAT_BITCOUNT	0x0000003F
+
+/* timeout values */
+#define BCM2835_AUX_SPI_POLLING_LIMIT_US	30
+#define BCM2835_AUX_SPI_POLLING_JIFFIES		2
+
+#define BCM2835_AUX_SPI_MODE_BITS (SPI_CPOL | SPI_CPHA | SPI_CS_HIGH \
+				  | SPI_NO_CS)
+
+#define DRV_NAME	"spi-bcm2835aux"
+#define ENABLE_PROPERTY "brcm,aux-enable"
+
+struct bcm2835aux_spi {
+	void __iomem *regs;
+	struct clk *clk;
+	int irq;
+	u32 cntl[2];
+	const u8 *tx_buf;
+	u8 *rx_buf;
+	int tx_len;
+	int rx_len;
+};
+
+static inline u32 bcm2835aux_rd(struct bcm2835aux_spi *bs, unsigned reg)
+{
+	return readl(bs->regs + reg);
+}
+
+static inline void bcm2835aux_wr(struct bcm2835aux_spi *bs, unsigned reg,
+				 u32 val)
+{
+	writel(val, bs->regs + reg);
+}
+
+static inline void bcm2835aux_rd_fifo(struct bcm2835aux_spi *bs)
+{
+	u32 data;
+	int i;
+	int count = min(bs->rx_len, 3);
+
+	data = bcm2835aux_rd(bs, BCM2835_AUX_SPI_IO);
+	if (bs->rx_buf) {
+		for (i = 0; i < count; i++)
+			*bs->rx_buf++ = (data >> (8 * (2 - i))) & 0xff;
+	}
+	bs->rx_len -= count;
+}
+
+static inline void bcm2835aux_wr_fifo(struct bcm2835aux_spi *bs)
+{
+	u32 data;
+	u8 byte;
+	int count;
+	int i;
+
+	/* gather up to 3 bytes to write to the FIFO */
+	count = min(bs->tx_len, 3);
+	data = 0;
+	for (i = 0; i < count; i++) {
+		byte = bs->tx_buf ? *bs->tx_buf++ : 0;
+		data |= byte << (8 * (2 - i));
+	}
+
+	/* and set the variable bit-length */
+	data |= (count * 8) << 24;
+
+	/* and decrement length */
+	bs->tx_len -= count;
+
+	/* write to the correct TX-register */
+	if (bs->tx_len)
+		bcm2835aux_wr(bs, BCM2835_AUX_SPI_TXHOLD, data);
+	else
+		bcm2835aux_wr(bs, BCM2835_AUX_SPI_IO, data);
+}
+
+static void bcm2835aux_spi_reset_hw(struct bcm2835aux_spi *bs)
+{
+	/* disable spi clearing fifo and interrupts */
+	bcm2835aux_wr(bs, BCM2835_AUX_SPI_CNTL1, 0);
+	bcm2835aux_wr(bs, BCM2835_AUX_SPI_CNTL0,
+		      BCM2835_AUX_SPI_CNTL0_CLEARFIFO);
+}
+
+static irqreturn_t bcm2835aux_spi_interrupt(int irq, void *dev_id)
+{
+	struct spi_master *master = dev_id;
+	struct bcm2835aux_spi *bs = spi_master_get_devdata(master);
+	irqreturn_t ret = IRQ_NONE;
+
+	/* check if we have data to read */
+	while (bs->rx_len &&
+	       (!(bcm2835aux_rd(bs, BCM2835_AUX_SPI_STAT) &
+		  BCM2835_AUX_SPI_STAT_RX_EMPTY))) {
+		bcm2835aux_rd_fifo(bs);
+		ret = IRQ_HANDLED;
+	}
+
+	/* check if we have data to write */
+	while (bs->tx_len &&
+	       (!(bcm2835aux_rd(bs, BCM2835_AUX_SPI_STAT) &
+		  BCM2835_AUX_SPI_STAT_TX_FULL))) {
+		bcm2835aux_wr_fifo(bs);
+		ret = IRQ_HANDLED;
+	}
+
+	/* and check if we have reached "done" */
+	while (bs->rx_len &&
+	       (!(bcm2835aux_rd(bs, BCM2835_AUX_SPI_STAT) &
+		  BCM2835_AUX_SPI_STAT_BUSY))) {
+		bcm2835aux_rd_fifo(bs);
+		ret = IRQ_HANDLED;
+	}
+
+	/* and if rx_len is 0 then wake up completion and disable spi */
+	if (!bs->rx_len) {
+		bcm2835aux_spi_reset_hw(bs);
+		complete(&master->xfer_completion);
+	}
+
+	/* and return */
+	return ret;
+}
+
+static int __bcm2835aux_spi_transfer_one_irq(struct spi_master *master,
+					     struct spi_device *spi,
+					     struct spi_transfer *tfr)
+{
+	struct bcm2835aux_spi *bs = spi_master_get_devdata(master);
+
+	/* enable interrupts */
+	bcm2835aux_wr(bs, BCM2835_AUX_SPI_CNTL1, bs->cntl[1] |
+		BCM2835_AUX_SPI_CNTL1_TXEMPTY |
+		BCM2835_AUX_SPI_CNTL1_IDLE);
+
+	/* and wait for finish... */
+	return 1;
+}
+
+static int bcm2835aux_spi_transfer_one_irq(struct spi_master *master,
+					   struct spi_device *spi,
+					   struct spi_transfer *tfr)
+{
+	struct bcm2835aux_spi *bs = spi_master_get_devdata(master);
+
+	/* fill in registers and fifos before enabling interrupts */
+	bcm2835aux_wr(bs, BCM2835_AUX_SPI_CNTL1, bs->cntl[1]);
+	bcm2835aux_wr(bs, BCM2835_AUX_SPI_CNTL0, bs->cntl[0]);
+
+	/* fill in tx fifo with data before enabling interrupts */
+	while ((bs->tx_len) &&
+	       (!(bcm2835aux_rd(bs, BCM2835_AUX_SPI_STAT) &
+		  BCM2835_AUX_SPI_STAT_TX_FULL))) {
+		bcm2835aux_wr_fifo(bs);
+	}
+
+	/* now run the interrupt mode */
+	return __bcm2835aux_spi_transfer_one_irq(master, spi, tfr);
+}
+
+static int bcm2835aux_spi_transfer_one_poll(struct spi_master *master,
+					    struct spi_device *spi,
+					    struct spi_transfer *tfr,
+					    unsigned long xfer_time_us)
+{
+	struct bcm2835aux_spi *bs = spi_master_get_devdata(master);
+	unsigned long timeout;
+	u32 stat;
+
+	/* configure spi */
+	bcm2835aux_wr(bs, BCM2835_AUX_SPI_CNTL1, bs->cntl[1]);
+	bcm2835aux_wr(bs, BCM2835_AUX_SPI_CNTL0, bs->cntl[0]);
+
+	/* set the timeout */
+	timeout = jiffies + BCM2835_AUX_SPI_POLLING_JIFFIES;
+
+	/* loop until finished the transfer */
+	while (bs->rx_len) {
+		/* read status */
+		stat = bcm2835aux_rd(bs, BCM2835_AUX_SPI_STAT);
+
+		/* fill in tx fifo with remaining data */
+		if ((bs->tx_len) && (!(stat & BCM2835_AUX_SPI_STAT_TX_FULL))) {
+			bcm2835aux_wr_fifo(bs);
+			continue;
+		}
+
+		/* read data from fifo for both cases */
+		if (!(stat & BCM2835_AUX_SPI_STAT_RX_EMPTY)) {
+			bcm2835aux_rd_fifo(bs);
+			continue;
+		}
+		if (!(stat & BCM2835_AUX_SPI_STAT_BUSY)) {
+			bcm2835aux_rd_fifo(bs);
+			continue;
+		}
+
+		/* there is still data pending to read check the timeout */
+		if (bs->rx_len && time_after(jiffies, timeout)) {
+			dev_dbg_ratelimited(&spi->dev,
+					    "timeout period reached: jiffies: %lu remaining tx/rx: %d/%d - falling back to interrupt mode\n",
+					    jiffies - timeout,
+					    bs->tx_len, bs->rx_len);
+			/* forward to interrupt handler */
+			return __bcm2835aux_spi_transfer_one_irq(master,
+							       spi, tfr);
+		}
+	}
+
+	/* Transfer complete - reset SPI HW */
+	bcm2835aux_spi_reset_hw(bs);
+
+	/* and return without waiting for completion */
+	return 0;
+}
+
+static int bcm2835aux_spi_transfer_one(struct spi_master *master,
+				       struct spi_device *spi,
+				       struct spi_transfer *tfr)
+{
+	struct bcm2835aux_spi *bs = spi_master_get_devdata(master);
+	unsigned long spi_hz, clk_hz, speed;
+	unsigned long spi_used_hz, xfer_time_us;
+
+	/* calculate the registers to handle
+	 *
+	 * note that we use the variable data mode, which
+	 * is not optimal for longer transfers as we waste registers
+	 * resulting (potentially) in more interrupts when transferring
+	 * more than 12 bytes
+	 */
+	bs->cntl[0] = BCM2835_AUX_SPI_CNTL0_ENABLE |
+		      BCM2835_AUX_SPI_CNTL0_VAR_WIDTH |
+		      BCM2835_AUX_SPI_CNTL0_MSBF_OUT;
+	bs->cntl[1] = BCM2835_AUX_SPI_CNTL1_MSBF_IN;
+
+	/* set clock */
+	spi_hz = tfr->speed_hz;
+	clk_hz = clk_get_rate(bs->clk);
+
+	if (spi_hz >= clk_hz / 2) {
+		speed = 0;
+	} else if (spi_hz) {
+		speed = DIV_ROUND_UP(clk_hz, 2 * spi_hz) - 1;
+		if (speed >  BCM2835_AUX_SPI_CNTL0_SPEED_MAX)
+			speed = BCM2835_AUX_SPI_CNTL0_SPEED_MAX;
+	} else { /* the slowest we can go */
+		speed = BCM2835_AUX_SPI_CNTL0_SPEED_MAX;
+	}
+	bs->cntl[0] |= speed << BCM2835_AUX_SPI_CNTL0_SPEED_SHIFT;
+	spi_used_hz = clk_hz / (2 * (speed + 1));
+
+	/* handle all the modes */
+	if (spi->mode & SPI_CPOL)
+		bs->cntl[0] |= BCM2835_AUX_SPI_CNTL0_CPOL;
+	if (spi->mode & SPI_CPHA)
+		bs->cntl[0] |= BCM2835_AUX_SPI_CNTL0_CPHA_OUT |
+			       BCM2835_AUX_SPI_CNTL0_CPHA_IN;
+
+	/* set transmit buffers and length */
+	bs->tx_buf = tfr->tx_buf;
+	bs->rx_buf = tfr->rx_buf;
+	bs->tx_len = tfr->len;
+	bs->rx_len = tfr->len;
+
+	/* calculate the estimated time in us the transfer runs */
+	xfer_time_us = tfr->len
+		* 9 /* clocks/byte - SPI-HW waits 1 clock after each byte */
+		* 1000000 / spi_used_hz;
+
+	/* run in polling mode for short transfers */
+	if (xfer_time_us < BCM2835_AUX_SPI_POLLING_LIMIT_US)
+		return bcm2835aux_spi_transfer_one_poll(master, spi, tfr,
+							xfer_time_us);
+
+	/* run in interrupt mode for all others */
+	return bcm2835aux_spi_transfer_one_irq(master, spi, tfr);
+}
+
+static void bcm2835aux_spi_handle_err(struct spi_master *master,
+				      struct spi_message *msg)
+{
+	struct bcm2835aux_spi *bs = spi_master_get_devdata(master);
+
+	bcm2835aux_spi_reset_hw(bs);
+}
+
+static int bcm2835aux_spi_probe(struct platform_device *pdev)
+{
+	struct spi_master *master;
+	struct bcm2835aux_spi *bs;
+	struct resource *res;
+	int err;
+
+	master = spi_alloc_master(&pdev->dev, sizeof(*bs));
+	if (!master) {
+		dev_err(&pdev->dev, "spi_alloc_master() failed\n");
+		return -ENOMEM;
+	}
+
+	platform_set_drvdata(pdev, master);
+	master->mode_bits = BCM2835_AUX_SPI_MODE_BITS;
+	master->bits_per_word_mask = SPI_BPW_MASK(8);
+	master->num_chipselect = -1;
+	master->transfer_one = bcm2835aux_spi_transfer_one;
+	master->handle_err = bcm2835aux_spi_handle_err;
+	master->dev.of_node = pdev->dev.of_node;
+
+	bs = spi_master_get_devdata(master);
+
+	/* the main area */
+	res = platform_get_resource(pdev, IORESOURCE_MEM, 0);
+	bs->regs = devm_ioremap_resource(&pdev->dev, res);
+	if (IS_ERR(bs->regs)) {
+		err = PTR_ERR(bs->regs);
+		goto out_master_put;
+	}
+
+	bs->clk = devm_clk_get(&pdev->dev, NULL);
+	if (IS_ERR(bs->clk)) {
+		err = PTR_ERR(bs->clk);
+		dev_err(&pdev->dev, "could not get clk: %d\n", err);
+		goto out_master_put;
+	}
+	bs->irq = irq_of_parse_and_map(pdev->dev.of_node, 0);
+	if (bs->irq <= 0) {
+		dev_err(&pdev->dev, "could not get IRQ: %d\n", bs->irq);
+		err = bs->irq ? bs->irq : -ENODEV;
+		goto out_master_put;
+	}
+
+	clk_prepare_enable(bs->clk);
+
+	err = devm_request_irq(&pdev->dev, bs->irq,
+			       bcm2835aux_spi_interrupt,
+			       IRQF_SHARED,
+			       dev_name(&pdev->dev), master);
+	if (err) {
+		dev_err(&pdev->dev, "could not request IRQ: %d\n", err);
+		goto out_clk_disable;
+	}
+
+	/* enable HW block */
+	bcm2835aux_enable(&pdev->dev, ENABLE_PROPERTY);
+
+	/* reset SPI-HW block */
+	bcm2835aux_spi_reset_hw(bs);
+
+	err = devm_spi_register_master(&pdev->dev, master);
+	if (err) {
+		dev_err(&pdev->dev, "could not register SPI master: %d\n", err);
+		goto out_hw_disable;
+	}
+
+	return 0;
+
+out_hw_disable:
+	bcm2835aux_disable(&pdev->dev, ENABLE_PROPERTY);
+out_clk_disable:
+	clk_disable_unprepare(bs->clk);
+out_master_put:
+	spi_master_put(master);
+	return err;
+}
+
+static int bcm2835aux_spi_remove(struct platform_device *pdev)
+{
+	struct spi_master *master = platform_get_drvdata(pdev);
+	struct bcm2835aux_spi *bs = spi_master_get_devdata(master);
+
+	/* Clear FIFOs, and disable the HW block */
+	clk_disable_unprepare(bs->clk);
+
+	bcm2835aux_spi_reset_hw(bs);
+
+	/* disable HW block */
+	bcm2835aux_disable(&pdev->dev, ENABLE_PROPERTY);
+
+	return 0;
+}
+
+static const struct of_device_id bcm2835aux_spi_match[] = {
+	{ .compatible = "brcm,bcm2835-aux-spi", },
+	{}
+};
+MODULE_DEVICE_TABLE(of, bcm2835aux_spi_match);
+
+static struct platform_driver bcm2835aux_spi_driver = {
+	.driver		= {
+		.name		= DRV_NAME,
+		.of_match_table	= bcm2835aux_spi_match,
+	},
+	.probe		= bcm2835aux_spi_probe,
+	.remove		= bcm2835aux_spi_remove,
+};
+module_platform_driver(bcm2835aux_spi_driver);
+
+MODULE_DESCRIPTION("SPI controller driver for Broadcom BCM2835 aux");
+MODULE_AUTHOR("Martin Sperl <kernel at martin.sperl.org>");
+MODULE_LICENSE("GPL v2");
--
1.7.10.4



From kernel at martin.sperl.org  Mon Aug 24 01:40:08 2015
From: kernel at martin.sperl.org (kernel at martin.sperl.org)
Date: Mon, 24 Aug 2015 08:40:08 +0000
Subject: [PATCH v4 5/5] dt/bindings: bcm2835: Add binding documentation for
 auxiliar spi devices
In-Reply-To: <1440405608-3995-1-git-send-email-kernel@martin.sperl.org>
References: <1440405608-3995-1-git-send-email-kernel@martin.sperl.org>
Message-ID: <1440405608-3995-6-git-send-email-kernel@martin.sperl.org>

From: Martin Sperl <kernel at martin.sperl.org>

Signed-off-by: Martin Sperl <kernel at martin.sperl.org>
---
 .../bindings/spi/brcm,bcm2835-aux-spi.txt          |   61 ++++++++++++++++++++
 1 file changed, 61 insertions(+)
 create mode 100644 Documentation/devicetree/bindings/spi/brcm,bcm2835-aux-spi.txt

diff --git a/Documentation/devicetree/bindings/spi/brcm,bcm2835-aux-spi.txt b/Documentation/devicetree/bindings/spi/brcm,bcm2835-aux-spi.txt
new file mode 100644
index 0000000..2a69a3b
--- /dev/null
+++ b/Documentation/devicetree/bindings/spi/brcm,bcm2835-aux-spi.txt
@@ -0,1 +1,61 @@
+Broadcom BCM2835 auxiliar SPI1/2 controller
+
+The BCM2835 contains two forms of SPI master controller, one known simply as
+SPI0, and the other known as the "Universal SPI Master"; part of the
+auxiliary block. This binding applies to the SPI1/2 controller.
+
+Required properties:
+- compatible: Should be "brcm,bcm2835-aux-spi".
+- reg: Should contain register location and length for the spi block
+       as well as for the common aux block control
+- interrupts: Should contain shared interrupt of the aux block
+- clocks: The clock feeding the SPI controller.
+- cs-gpios: the cs-gpios (native cs is NOT supported)
+	    see also spi-bus.txt
+- bcrm,aux-enable: the bcrm,bcm2835-aux-enable config entry to handle
+		  enabling/disabling of the spi1/spi2/uart1 HW block
+		  second "argument" is the mask to apply to the
+		  enable register
+
+Example:
+
+spi1 at 7e215080 {
+	compatible = "brcm,bcm2835-aux-spi";
+	reg = <0x7e215080 0x40>;
+	interrupts = <1 29>;
+	clocks = <&clk_spi>;
+	#address-cells = <1>;
+	#size-cells = <0>;
+	cs-gpios = <&gpio 18>, <&gpio 17>, <&gpio 16>;
+	bcrm,aux-enable = <&aux_enable 2>;
+};
+
+spi2 at 7e2150c0 {
+	compatible = "brcm,bcm2835-aux-spi";
+	reg = <0x7e2150c0 0x40>;
+	interrupts = <1 29>;
+	clocks = <&clk_spi>;
+	#address-cells = <1>;
+	#size-cells = <0>;
+	cs-gpios = <&gpio 43>, <&gpio 44>, <&gpio 45>;
+	bcrm,aux-enable = <&aux_enable 4>;
+};
+
+/* the necessary syscon config referenced above*/
+aux_enable: aux_enable at 0x7e215004 {
+	compatible = "bcrm,bcm2835-aux";
+	reg = <0x7e215004 0x04>;
+};
+
+Note that it also requires the GPIOs to be set up with the
+correct ALT-functions.
+
+For spi1 the following pins need to be set as:
+* ALT4: 19, 20, 21 (MISO, MOSI, SCK)
+
+For spi2 the following pins need to be set as:
+* ALT4: 40, 41, 42 (MISO, MOSI, SCK)
+
+CS-GPIOS need to get set as output - typically:
+* spi1: 18, 17, 16 (CS0, CS1, CS2)
+* spi2: 43, 44, 45 (CS0, CS1, CS2)
--
1.7.10.4



From javier at osg.samsung.com  Mon Aug 24 01:47:19 2015
From: javier at osg.samsung.com (Javier Martinez Canillas)
Date: Mon, 24 Aug 2015 10:47:19 +0200
Subject: [PATCH v4 2/4] mfd: max77686: Use a generic name for the PMIC node in
 the example
In-Reply-To: <1440406041-25071-1-git-send-email-javier@osg.samsung.com>
References: <1440406041-25071-1-git-send-email-javier@osg.samsung.com>
Message-ID: <1440406041-25071-3-git-send-email-javier@osg.samsung.com>

The ePAPR standard says that: "the name of a node should be somewhat
generic, reflecting the function of the device and not its precise
programming model."

So, change the max77686 binding document example to use a generic
node name instead of using the chip's name.

Suggested-by: Sergei Shtylyov <sergei.shtylyov at cogentembedded.com>
Signed-off-by: Javier Martinez Canillas <javier at osg.samsung.com>
Acked-by: Lee Jones <lee.jones at linaro.org>

---

Changes in v4:
- Add Lee Jones Acked-by tag to patch #2.

Changes in v3:
- Fix typo in ePAPR document name. Suggested by Sergei Shtylyov

Changes in v2: None

 Documentation/devicetree/bindings/mfd/max77686.txt | 2 +-
 1 file changed, 1 insertion(+), 1 deletion(-)

diff --git a/Documentation/devicetree/bindings/mfd/max77686.txt b/Documentation/devicetree/bindings/mfd/max77686.txt
index 8221102d3fc2..d2ed3c20a5c3 100644
--- a/Documentation/devicetree/bindings/mfd/max77686.txt
+++ b/Documentation/devicetree/bindings/mfd/max77686.txt
@@ -48,7 +48,7 @@ to get matched with their hardware counterparts as follow:
 
 Example:
 
-	max77686 at 09 {
+	max77686: pmic at 09 {
 		compatible = "maxim,max77686";
 		interrupt-parent = <&wakeup_eint>;
 		interrupts = <26 0>;
-- 
2.4.3



From javier at osg.samsung.com  Mon Aug 24 01:47:18 2015
From: javier at osg.samsung.com (Javier Martinez Canillas)
Date: Mon, 24 Aug 2015 10:47:18 +0200
Subject: [PATCH v4 1/4] mfd: max77686: Don't suggest in binding to use a
 deprecated property
In-Reply-To: <1440406041-25071-1-git-send-email-javier@osg.samsung.com>
References: <1440406041-25071-1-git-send-email-javier@osg.samsung.com>
Message-ID: <1440406041-25071-2-git-send-email-javier@osg.samsung.com>

The regulator-compatible property from the regulator DT binding was
deprecated. But the max77686 DT binding doc still suggest to use it
instead of the regulator node name's which is the correct approach.

Signed-off-by: Javier Martinez Canillas <javier at osg.samsung.com>
Reviewed-by: Krzysztof Kozlowski <k.kozlowski at samsung.com>
Acked-by: Lee Jones <lee.jones at linaro.org>

---

Changes in v4:
- Add Lee Jones Acked-by tag to patch #1.

Changes in v3: None
Changes in v2:
- Add Krzysztof Kozlowski Reviewed-by tag to patch #1.

 Documentation/devicetree/bindings/mfd/max77686.txt | 11 ++++-------
 1 file changed, 4 insertions(+), 7 deletions(-)

diff --git a/Documentation/devicetree/bindings/mfd/max77686.txt b/Documentation/devicetree/bindings/mfd/max77686.txt
index 163bd81a4607..8221102d3fc2 100644
--- a/Documentation/devicetree/bindings/mfd/max77686.txt
+++ b/Documentation/devicetree/bindings/mfd/max77686.txt
@@ -26,7 +26,7 @@ Optional node:
 	};
 	refer Documentation/devicetree/bindings/regulator/regulator.txt
 
-  The regulator-compatible property of regulator should initialized with string
+  The regulator node's name should be initialized with a string
 to get matched with their hardware counterparts as follow:
 
 	-LDOn 	:	for LDOs, where n can lie in range 1 to 26.
@@ -55,16 +55,14 @@ Example:
 		reg = <0x09>;
 
 		voltage-regulators {
-			ldo11_reg {
-				regulator-compatible = "LDO11";
+			ldo11_reg: LDO11 {
 				regulator-name = "vdd_ldo11";
 				regulator-min-microvolt = <1900000>;
 				regulator-max-microvolt = <1900000>;
 				regulator-always-on;
 			};
 
-			buck1_reg {
-				regulator-compatible = "BUCK1";
+			buck1_reg: BUCK1 {
 				regulator-name = "vdd_mif";
 				regulator-min-microvolt = <950000>;
 				regulator-max-microvolt = <1300000>;
@@ -72,8 +70,7 @@ Example:
 				regulator-boot-on;
 			};
 
-			buck9_reg {
-				regulator-compatible = "BUCK9";
+			buck9_reg: BUCK9 {
 				regulator-name = "CAM_ISP_CORE_1.2V";
 				regulator-min-microvolt = <1000000>;
 				regulator-max-microvolt = <1200000>;
-- 
2.4.3



From javier at osg.samsung.com  Mon Aug 24 01:47:17 2015
From: javier at osg.samsung.com (Javier Martinez Canillas)
Date: Mon, 24 Aug 2015 10:47:17 +0200
Subject: [PATCH v4 0/4] mfd: Improve DT binding docs for max77686 and max77802
Message-ID: <1440406041-25071-1-git-send-email-javier@osg.samsung.com>

Hello,

This series contains some improvements for the Device Tree bindings of
the Maxim MAX77686 and MAX77802 multi-function devices.

This is the fourth version of the series that addresses issues pointed
out by Lee Jones in v3.

Patch #1 changes the max77686 binding to not suggest using a deprecated
property of the regulator DT binding.

Patch #2 changes the max77686 example to use a generic node name instead
of the chip's name.

Patch #3 adds a DT binding for the mfd portion of the max77802 that was
missing.

Patch #4 moves the regulator portion of the max77686 to the regulator's
DT binding sub-directory since it is a better fit for this information.
Patch #4 needs to be acked by Mark Brown to get it through the mfd tree.

Changes in v4:
- Add Lee Jones Acked-by tag to patch #1.
- Add Lee Jones Acked-by tag to patch #2.
- Reword section about max77802 clock and regulator DT binding docs.
  Suggested by Lee Jones.
- Align max77802 mfd required properties. Suggested by Lee Jones.

Changes in v3:
- Fix typo in ePAPR document name. Suggested by Sergei Shtylyov
- Add Krzysztof Kozlowski Reviewed-by tag to patch #3.
- Capitalise all acronyms. Suggested by Lee Jones.
- Use relative path to refer other bindings. Suggested by Lee Jones.
- Use IRQ_TYPE_NONE instead of 0 in example. Suggested by Lee Jones.
- Add Krzysztof Kozlowski Reviewed-by tag to patch #4.
- Add Lee Jones Acked-by tag to patch #4.

Changes in v2:
- Add Krzysztof Kozlowski Reviewed-by tag to patch #1.
- Use the correct "maxim,max77802" compatible string.
  Suggested by Krzysztof Kozlowski
- Use a pmic generic node name for the max77802 node example.
  Suggested by Sergei Shtylyov.
- Use a generic name for the max77686 node in the regulator example.

Javier Martinez Canillas (4):
  mfd: max77686: Don't suggest in binding to use a deprecated property
  mfd: max77686: Use a generic name for the PMIC node in the example
  mfd: Add DT binding for Maxim MAX77802 IC
  mfd: max77686: Split out regulator part from the DT binding

 Documentation/devicetree/bindings/mfd/max77686.txt | 65 ++------------------
 Documentation/devicetree/bindings/mfd/max77802.txt | 26 ++++++++
 .../devicetree/bindings/regulator/max77686.txt     | 71 ++++++++++++++++++++++
 3 files changed, 102 insertions(+), 60 deletions(-)
 create mode 100644 Documentation/devicetree/bindings/mfd/max77802.txt
 create mode 100644 Documentation/devicetree/bindings/regulator/max77686.txt

-- 
2.4.3



From javier at osg.samsung.com  Mon Aug 24 01:47:20 2015
From: javier at osg.samsung.com (Javier Martinez Canillas)
Date: Mon, 24 Aug 2015 10:47:20 +0200
Subject: [PATCH v4 3/4] mfd: Add DT binding for Maxim MAX77802 IC
In-Reply-To: <1440406041-25071-1-git-send-email-javier@osg.samsung.com>
References: <1440406041-25071-1-git-send-email-javier@osg.samsung.com>
Message-ID: <1440406041-25071-4-git-send-email-javier@osg.samsung.com>

The MAX77802 is a chip that contains regulators, 2 32kHz clocks,
a RTC and an I2C interface to program the individual components.

The are already DT bindings for the regulators and clocks and
these reference to a bindings/mfd/max77802.txt file, that didn't
exist, for the details about the PMIC.

Signed-off-by: Javier Martinez Canillas <javier at osg.samsung.com>
Reviewed-by: Krzysztof Kozlowski <k.kozlowski at samsung.com>

---

Changes in v4:
- Reword section about max77802 clock and regulator DT binding docs.
  Suggested by Lee Jones.
- Align max77802 mfd required properties. Suggested by Lee Jones.

Changes in v3:
- Add Krzysztof Kozlowski Reviewed-by tag to patch #3.
- Capitalise all acronyms. Suggested by Lee Jones.
- Use relative path to refer other bindings. Suggested by Lee Jones.
- Use IRQ_TYPE_NONE instead of 0 in example. Suggested by Lee Jones.

Changes in v2:
- Use the correct "maxim,max77802" compatible string.
  Suggested by Krzysztof Kozlowski
- Use a pmic generic node name for the max77802 node example.
  Suggested by Sergei Shtylyov.

 Documentation/devicetree/bindings/mfd/max77802.txt | 26 ++++++++++++++++++++++
 1 file changed, 26 insertions(+)
 create mode 100644 Documentation/devicetree/bindings/mfd/max77802.txt

diff --git a/Documentation/devicetree/bindings/mfd/max77802.txt b/Documentation/devicetree/bindings/mfd/max77802.txt
new file mode 100644
index 000000000000..51fc1a60caa5
--- /dev/null
+++ b/Documentation/devicetree/bindings/mfd/max77802.txt
@@ -0,0 +1,26 @@
+Maxim MAX77802 multi-function device
+
+The Maxim MAX77802 is a Power Management IC (PMIC) that contains 10 high
+efficiency Buck regulators, 32 Low-DropOut (LDO) regulators used to power
+up application processors and peripherals, a 2-channel 32kHz clock outputs,
+a Real-Time-Clock (RTC) and a I2C interface to program the individual
+regulators, clocks outputs and the RTC.
+
+Bindings for the built-in 32k clock generator block and
+regulators are defined in ../clk/maxim,max77802.txt and
+../regulator/max77802.txt respectively.
+
+Required properties:
+- compatible		: Must be "maxim,max77802"
+- reg			: Specifies the I2C slave address of PMIC block.
+- interrupts		: I2C device IRQ line connected to the main SoC.
+- interrupt-parent	: The parent interrupt controller.
+
+Example:
+
+	max77802: pmic at 09 {
+		compatible = "maxim,max77802";
+		interrupt-parent = <&intc>;
+		interrupts = <26 IRQ_TYPE_NONE>;
+		reg = <0x09>;
+	};
-- 
2.4.3



From javier at osg.samsung.com  Mon Aug 24 01:47:21 2015
From: javier at osg.samsung.com (Javier Martinez Canillas)
Date: Mon, 24 Aug 2015 10:47:21 +0200
Subject: [PATCH v4 4/4] mfd: max77686: Split out regulator part from the DT
 binding
In-Reply-To: <1440406041-25071-1-git-send-email-javier@osg.samsung.com>
References: <1440406041-25071-1-git-send-email-javier@osg.samsung.com>
Message-ID: <1440406041-25071-5-git-send-email-javier@osg.samsung.com>

The Maxim MAX77686 PMIC is a multi-function device with regulators,
clocks and a RTC. The DT bindings for the clocks are in a separate
file but the bindings for the regulators are inside the mfd part.

To make it consistent with the clocks portion of the binding and
because is more natural to look for regulator bindings under the
bindings/regulator sub-directory, split the regulator portion of
the DT binding and add it as a separate file.

Signed-off-by: Javier Martinez Canillas <javier at osg.samsung.com>
Reviewed-by: Krzysztof Kozlowski <k.kozlowski at samsung.com>
Acked-by: Lee Jones <lee.jones at linaro.org>

---

Changes in v4: None
Changes in v3:
- Add Krzysztof Kozlowski Reviewed-by tag to patch #4.
- Add Lee Jones Acked-by tag to patch #4.

Changes in v2:
- Use a generic name for the max77686 node in the regulator example.

 Documentation/devicetree/bindings/mfd/max77686.txt | 60 ++----------------
 .../devicetree/bindings/regulator/max77686.txt     | 71 ++++++++++++++++++++++
 2 files changed, 75 insertions(+), 56 deletions(-)
 create mode 100644 Documentation/devicetree/bindings/regulator/max77686.txt

diff --git a/Documentation/devicetree/bindings/mfd/max77686.txt b/Documentation/devicetree/bindings/mfd/max77686.txt
index d2ed3c20a5c3..741e76688cf2 100644
--- a/Documentation/devicetree/bindings/mfd/max77686.txt
+++ b/Documentation/devicetree/bindings/mfd/max77686.txt
@@ -7,8 +7,9 @@ different i2c slave address,presently for which we are statically creating i2c
 client while probing.This document describes the binding for mfd device and
 PMIC submodule.
 
-Binding for the built-in 32k clock generator block is defined separately
-in bindings/clk/maxim,max77686.txt file.
+Bindings for the built-in 32k clock generator block and
+regulators are defined in ../clk/maxim,max77686.txt and
+../regulator/max77686.txt respectively.
 
 Required properties:
 - compatible : Must be "maxim,max77686";
@@ -16,36 +17,6 @@ Required properties:
 - interrupts : This i2c device has an IRQ line connected to the main SoC.
 - interrupt-parent : The parent interrupt controller.
 
-Optional node:
-- voltage-regulators : The regulators of max77686 have to be instantiated
-  under subnode named "voltage-regulators" using the following format.
-
-	regulator_name {
-		regulator-compatible = LDOn/BUCKn
-		standard regulator constraints....
-	};
-	refer Documentation/devicetree/bindings/regulator/regulator.txt
-
-  The regulator node's name should be initialized with a string
-to get matched with their hardware counterparts as follow:
-
-	-LDOn 	:	for LDOs, where n can lie in range 1 to 26.
-		 	example: LDO1, LDO2, LDO26.
-	-BUCKn 	:	for BUCKs, where n can lie in range 1 to 9.
-			example: BUCK1, BUCK5, BUCK9.
-
-  Regulators which can be turned off during system suspend:
-	-LDOn	:	2, 6-8, 10-12, 14-16,
-	-BUCKn	:	1-4.
-  Use standard regulator bindings for it ('regulator-off-in-suspend').
-
-  LDO20, LDO21, LDO22, BUCK8 and BUCK9 can be configured to GPIO enable
-  control. To turn this feature on this property must be added to the regulator
-  sub-node:
-	- maxim,ena-gpios :	one GPIO specifier enable control (the gpio
-				flags are actually ignored and always
-				ACTIVE_HIGH is used)
-
 Example:
 
 	max77686: pmic at 09 {
@@ -53,27 +24,4 @@ Example:
 		interrupt-parent = <&wakeup_eint>;
 		interrupts = <26 0>;
 		reg = <0x09>;
-
-		voltage-regulators {
-			ldo11_reg: LDO11 {
-				regulator-name = "vdd_ldo11";
-				regulator-min-microvolt = <1900000>;
-				regulator-max-microvolt = <1900000>;
-				regulator-always-on;
-			};
-
-			buck1_reg: BUCK1 {
-				regulator-name = "vdd_mif";
-				regulator-min-microvolt = <950000>;
-				regulator-max-microvolt = <1300000>;
-				regulator-always-on;
-				regulator-boot-on;
-			};
-
-			buck9_reg: BUCK9 {
-				regulator-name = "CAM_ISP_CORE_1.2V";
-				regulator-min-microvolt = <1000000>;
-				regulator-max-microvolt = <1200000>;
-				maxim,ena-gpios = <&gpm0 3 GPIO_ACTIVE_HIGH>;
-			};
-	}
+	};
diff --git a/Documentation/devicetree/bindings/regulator/max77686.txt b/Documentation/devicetree/bindings/regulator/max77686.txt
new file mode 100644
index 000000000000..0dded64d89d3
--- /dev/null
+++ b/Documentation/devicetree/bindings/regulator/max77686.txt
@@ -0,0 +1,71 @@
+Binding for Maxim MAX77686 regulators
+
+This is a part of the device tree bindings of MAX77686 multi-function device.
+More information can be found in ../mfd/max77686.txt file.
+
+The MAX77686 PMIC has 9 high-efficiency Buck and 26 Low-DropOut (LDO)
+regulators that can be controlled over I2C.
+
+Following properties should be present in main device node of the MFD chip.
+
+Optional node:
+- voltage-regulators : The regulators of max77686 have to be instantiated
+  under subnode named "voltage-regulators" using the following format.
+
+	regulator_name {
+		regulator-compatible = LDOn/BUCKn
+		standard regulator constraints....
+	};
+	refer Documentation/devicetree/bindings/regulator/regulator.txt
+
+  The regulator node's name should be initialized with a string
+to get matched with their hardware counterparts as follow:
+
+	-LDOn 	:	for LDOs, where n can lie in range 1 to 26.
+			example: LDO1, LDO2, LDO26.
+	-BUCKn 	:	for BUCKs, where n can lie in range 1 to 9.
+			example: BUCK1, BUCK5, BUCK9.
+
+  Regulators which can be turned off during system suspend:
+	-LDOn	:	2, 6-8, 10-12, 14-16,
+	-BUCKn	:	1-4.
+  Use standard regulator bindings for it ('regulator-off-in-suspend').
+
+  LDO20, LDO21, LDO22, BUCK8 and BUCK9 can be configured to GPIO enable
+  control. To turn this feature on this property must be added to the regulator
+  sub-node:
+	- maxim,ena-gpios :	one GPIO specifier enable control (the gpio
+				flags are actually ignored and always
+				ACTIVE_HIGH is used)
+
+Example:
+
+	max77686: pmic at 09 {
+		compatible = "maxim,max77686";
+		interrupt-parent = <&wakeup_eint>;
+		interrupts = <26 IRQ_TYPE_NONE>;
+		reg = <0x09>;
+
+		voltage-regulators {
+			ldo11_reg: LDO11 {
+				regulator-name = "vdd_ldo11";
+				regulator-min-microvolt = <1900000>;
+				regulator-max-microvolt = <1900000>;
+				regulator-always-on;
+			};
+
+			buck1_reg: BUCK1 {
+				regulator-name = "vdd_mif";
+				regulator-min-microvolt = <950000>;
+				regulator-max-microvolt = <1300000>;
+				regulator-always-on;
+				regulator-boot-on;
+			};
+
+			buck9_reg: BUCK9 {
+				regulator-name = "CAM_ISP_CORE_1.2V";
+				regulator-min-microvolt = <1000000>;
+				regulator-max-microvolt = <1200000>;
+				maxim,ena-gpios = <&gpm0 3 GPIO_ACTIVE_HIGH>;
+			};
+	};
-- 
2.4.3



From hdegoede at redhat.com  Mon Aug 24 02:17:43 2015
From: hdegoede at redhat.com (Hans de Goede)
Date: Mon, 24 Aug 2015 11:17:43 +0200
Subject: [linux-sunxi] Re: [PATCH] net: sun4i-emac: Claim emac sram
In-Reply-To: <20150824074605.GF2413@lukather>
References: <1440354698-11144-1-git-send-email-hdegoede@redhat.com>
 <20150824074605.GF2413@lukather>
Message-ID: <55DAE137.4040306@redhat.com>

Hi,

On 24-08-15 09:46, Maxime Ripard wrote:
> Hi Hans,
>
> On Sun, Aug 23, 2015 at 08:31:38PM +0200, Hans de Goede wrote:
>> Claim the emac sram ourselves, rather then relying on the bootloader
>> having mapped the sram to the emac controller during boot.
>>
>> Signed-off-by: Hans de Goede <hdegoede at redhat.com>
>> ---
>>   drivers/net/ethernet/allwinner/sun4i-emac.c | 13 +++++++++++--
>>   1 file changed, 11 insertions(+), 2 deletions(-)
>>
>> diff --git a/drivers/net/ethernet/allwinner/sun4i-emac.c b/drivers/net/ethernet/allwinner/sun4i-emac.c
>> index bab01c84..48ce83e 100644
>> --- a/drivers/net/ethernet/allwinner/sun4i-emac.c
>> +++ b/drivers/net/ethernet/allwinner/sun4i-emac.c
>> @@ -28,6 +28,7 @@
>>   #include <linux/of_platform.h>
>>   #include <linux/platform_device.h>
>>   #include <linux/phy.h>
>> +#include <linux/soc/sunxi/sunxi_sram.h>
>>
>>   #include "sun4i-emac.h"
>>
>> @@ -857,11 +858,17 @@ static int emac_probe(struct platform_device *pdev)
>>
>>   	clk_prepare_enable(db->clk);
>>
>> +	ret = sunxi_sram_claim(&pdev->dev);
>> +	if (ret) {
>> +		dev_err(&pdev->dev, "Error couldn't map SRAM to device\n");
>> +		goto out;
>
> Shouldn't you disable you clock too?

You're right, but that is a pre-existing problem, iow an unrelated issue.

I've put doing a follow-up patch for this on my todo list.

Regards,

Hans


From michal.simek at xilinx.com  Mon Aug 24 02:18:19 2015
From: michal.simek at xilinx.com (Michal Simek)
Date: Mon, 24 Aug 2015 11:18:19 +0200
Subject: [PATCH v3 2/2] drivers: rtc: add xilinx zynqmp rtc driver
In-Reply-To: <20150824080800.GG13155@piout.net>
References: <1439978002-12157-1-git-send-email-suneel.garapati@xilinx.com>
 <1439978002-12157-2-git-send-email-suneel.garapati@xilinx.com>
 <20150824074310.GF13155@piout.net> <55DACC5A.80707@xilinx.com>
 <20150824080800.GG13155@piout.net>
Message-ID: <55DAE15B.6090602@xilinx.com>

Hi,

On 08/24/2015 10:08 AM, Alexandre Belloni wrote:
> On 24/08/2015 at 09:48:42 +0200, Michal Simek wrote :
>> On 08/24/2015 09:43 AM, Alexandre Belloni wrote:
>>> On 19/08/2015 at 15:23:22 +0530, Suneel Garapati wrote :
>>>> adds support for RTC controller found on
>>>> Xilinx Zynq Ultrascale+ MPSoC platform.
>>>>
>>>> Signed-off-by: Suneel Garapati <suneel.garapati at xilinx.com>
>>>> ---
>>>> Changes v3 
>>>> - fix checkpatch errors 
>>>> - check time in secs arg against max sec val 
>>>> - order header files 
>>>> - use ptr_err_or_zero macro 
>>>> - use time64 variants 
>>>> Changes v2 
>>>> - change alm to alarm 
>>>> ---
>>>>  drivers/rtc/Kconfig      |   7 ++
>>>>  drivers/rtc/Makefile     |   1 +
>>>>  drivers/rtc/rtc-zynqmp.c | 279 +++++++++++++++++++++++++++++++++++++++++++++++
>>>>  3 files changed, 287 insertions(+)
>>>>  create mode 100644 drivers/rtc/rtc-zynqmp.c
>>>>
>>> Applied, thanks.
>>>
>>
> 
> Actually, I got the following message:
> A message that you sent could not be delivered to one or more of its
> recipients. This is a permanent error. The following address(es) failed:
> 
>   suneel.garapati at xilinx.com
>     Unknown User
> 
> I'm not fond of carrying patches with uncontactable authors. Is that a
> permanent error?

Unfortunately. That guy left Xilinx last week but don't be scared that
none will be responsible about this driver. I have well proven history
on Linux and others project and I am here if you need to do some testing
or ACK for changes. Just let me know when you need something.

get_maintainer returns me and Soren that's why you shouldn't have any
problem with it.

[linux]$ ./scripts/get_maintainer.pl -f drivers/rtc/rtc-zynqmp.c
Alessandro Zummo <a.zummo at towertech.it> (maintainer:REAL TIME CLOCK
(RTC) SUBSYSTEM)
Alexandre Belloni <alexandre.belloni at free-electrons.com>
(maintainer:REAL TIME CLOCK (RTC) SUBSYSTEM)
Michal Simek <michal.simek at xilinx.com> (supporter:ARM/ZYNQ ARCHITECTURE)
"S?ren Brinkmann" <soren.brinkmann at xilinx.com> (reviewer)
rtc-linux at googlegroups.com (open list:REAL TIME CLOCK (RTC) SUBSYSTEM)
linux-arm-kernel at lists.infradead.org (moderated list:ARM/ZYNQ ARCHITECTURE)
linux-kernel at vger.kernel.org (open list)

Thanks,
Michal


From leo.yan at linaro.org  Mon Aug 24 02:18:45 2015
From: leo.yan at linaro.org (Leo Yan)
Date: Mon, 24 Aug 2015 17:18:45 +0800
Subject: [PATCH v1 3/3] arm64: dts: add Hi6220 mailbox node
In-Reply-To: <20150821184059.GB2000@svinekod>
References: <1439977055-1747-1-git-send-email-leo.yan@linaro.org>
 <1439977055-1747-4-git-send-email-leo.yan@linaro.org>
 <20150821184059.GB2000@svinekod>
Message-ID: <20150824091845.GA28290@leoy-linaro>

Hi Mark,

On Fri, Aug 21, 2015 at 07:40:59PM +0100, Mark Rutland wrote:
> On Wed, Aug 19, 2015 at 10:37:35AM +0100, Leo Yan wrote:
> > On Hi6220, below memory regions in DDR have specific purpose:
> > 
> >   0x05e0,0000 - 0x05ef,ffff: For MCU firmware using at runtime;
> >   0x0740,f000 - 0x0740,ffff: For MCU firmware's section;
> >   0x06df,f000 - 0x06df,ffff: For mailbox message data.
> > 
> > This patch reserves these memory regions and add device node for
> > mailbox in dts.
> > 
> > Signed-off-by: Leo Yan <leo.yan at linaro.org>
> > ---
> >  arch/arm64/boot/dts/hisilicon/hi6220-hikey.dts | 20 +++++++++++++++++---
> >  arch/arm64/boot/dts/hisilicon/hi6220.dtsi      |  8 ++++++++
> >  2 files changed, 25 insertions(+), 3 deletions(-)
> > 
> > diff --git a/arch/arm64/boot/dts/hisilicon/hi6220-hikey.dts b/arch/arm64/boot/dts/hisilicon/hi6220-hikey.dts
> > index e36a539..d5470d3 100644
> > --- a/arch/arm64/boot/dts/hisilicon/hi6220-hikey.dts
> > +++ b/arch/arm64/boot/dts/hisilicon/hi6220-hikey.dts
> > @@ -7,9 +7,6 @@
> >  
> >  /dts-v1/;
> >  
> > -/*Reserved 1MB memory for MCU*/
> > -/memreserve/ 0x05e00000 0x00100000;
> > -
> >  #include "hi6220.dtsi"
> >  
> >  / {
> > @@ -28,4 +25,21 @@
> >  		device_type = "memory";
> >  		reg = <0x0 0x0 0x0 0x40000000>;
> >  	};
> > +
> > +	reserved-memory {
> > +		#address-cells = <2>;
> > +		#size-cells = <2>;
> > +		ranges;
> > +
> > +		mcu-buf at 05e00000 {
> > +			no-map;
> > +			reg = <0x0 0x05e00000 0x0 0x00100000>,	/* MCU firmware buffer */
> > +			      <0x0 0x0740f000 0x0 0x00001000>;	/* MCU firmware section */
> > +		};
> > +
> > +		mbox-buf at 06dff000 {
> > +			no-map;
> > +			reg = <0x0 0x06dff000 0x0 0x00001000>;	/* Mailbox message buf */
> > +		};
> > +	};
> 
> As far as I can see, it would be simpler to simply carve these out of the
> memory node.
> 
> I don't see why you need reserved-memory here, given you're not referring to
> these regions by phandle anyway.

- Now we have enabled EFI_STUB, so the memory node will be removed in
  kernel:
    efi_entry()
      \-> allocate_new_fdt_and_exit_boot()
            \-> update_fdt();

  Finally in kernel it cannot use memory node to carve out reseved
  memory regions.

- On the other hand, DTS's the memory node is to "describes the
  physical memory layout for the system"; so it's better to use it only
  to describe the hardware info for memory. We can use reserved-memory
  to help manage the memory regions which are reserved from software
  perspective.

According to upper info, we still need to use reserved-memory node to
depict the reserved memory regions. i have no knowledge about EFI_STUB,
so please confirm or correct as needed.

Thanks,
Leo Yan


From maxime.ripard at free-electrons.com  Mon Aug 24 02:21:15 2015
From: maxime.ripard at free-electrons.com (Maxime Ripard)
Date: Mon, 24 Aug 2015 11:21:15 +0200
Subject: [PATCH v3] dmaengine: hdmac: Add memset capabilities
Message-ID: <1440408075-26438-1-git-send-email-maxime.ripard@free-electrons.com>

Just like for the XDMAC, the SoCs that embed the HDMAC don't have any kind
of GPU, and need to accelerate a few framebuffer-related operations through
their DMA controller.

However, unlike the XDMAC, the HDMAC doesn't have the memset capability
built-in. That can be easily emulated though, by doing a transfer with a
fixed address on the variable that holds the value we want to set.

Signed-off-by: Maxime Ripard <maxime.ripard at free-electrons.com>

---
Changes from v2:
  - Rebased on top Cyril's patch

Changes from v1:
  - Replaced the dma_alloc_coherent calls by a dma_pool
---
 drivers/dma/at_hdmac.c      | 121 ++++++++++++++++++++++++++++++++++++++++++--
 drivers/dma/at_hdmac_regs.h |   6 +++
 2 files changed, 124 insertions(+), 3 deletions(-)

diff --git a/drivers/dma/at_hdmac.c b/drivers/dma/at_hdmac.c
index 1459c9f3165f..58d406230d89 100644
--- a/drivers/dma/at_hdmac.c
+++ b/drivers/dma/at_hdmac.c
@@ -448,6 +448,7 @@ static void
 atc_chain_complete(struct at_dma_chan *atchan, struct at_desc *desc)
 {
 	struct dma_async_tx_descriptor	*txd = &desc->txd;
+	struct at_dma			*atdma = to_at_dma(atchan->chan_common.device);
 
 	dev_vdbg(chan2dev(&atchan->chan_common),
 		"descriptor %u complete\n", txd->cookie);
@@ -456,6 +457,13 @@ atc_chain_complete(struct at_dma_chan *atchan, struct at_desc *desc)
 	if (!atc_chan_is_cyclic(atchan))
 		dma_cookie_complete(txd);
 
+	/* If the transfer was a memset, free our temporary buffer */
+	if (desc->memset) {
+		dma_pool_free(atdma->memset_pool, desc->memset_vaddr,
+			      desc->memset_paddr);
+		desc->memset = false;
+	}
+
 	/* move children to free_list */
 	list_splice_init(&desc->tx_list, &atchan->free_list);
 	/* move myself to free_list */
@@ -873,6 +881,93 @@ err_desc_get:
 	return NULL;
 }
 
+/**
+ * atc_prep_dma_memset - prepare a memcpy operation
+ * @chan: the channel to prepare operation on
+ * @dest: operation virtual destination address
+ * @value: value to set memory buffer to
+ * @len: operation length
+ * @flags: tx descriptor status flags
+ */
+static struct dma_async_tx_descriptor *
+atc_prep_dma_memset(struct dma_chan *chan, dma_addr_t dest, int value,
+		    size_t len, unsigned long flags)
+{
+	struct at_dma_chan	*atchan = to_at_dma_chan(chan);
+	struct at_dma		*atdma = to_at_dma(chan->device);
+	struct at_desc		*desc = NULL;
+	size_t			xfer_count;
+	u32			ctrla;
+	u32			ctrlb;
+
+	dev_vdbg(chan2dev(chan), "%s: d0x%x v0x%x l0x%zx f0x%lx\n", __func__,
+		dest, value, len, flags);
+
+	if (unlikely(!len)) {
+		dev_dbg(chan2dev(chan), "%s: length is zero!\n", __func__);
+		return NULL;
+	}
+
+	if (!is_dma_fill_aligned(chan->device, dest, 0, len)) {
+		dev_dbg(chan2dev(chan), "%s: buffer is not aligned\n",
+			__func__);
+		return NULL;
+	}
+
+	xfer_count = len >> 2;
+	if (xfer_count > ATC_BTSIZE_MAX) {
+		dev_err(chan2dev(chan), "%s: buffer is too big\n",
+			__func__);
+		return NULL;
+	}
+
+	ctrlb =   ATC_DEFAULT_CTRLB | ATC_IEN
+		| ATC_SRC_ADDR_MODE_FIXED
+		| ATC_DST_ADDR_MODE_INCR
+		| ATC_FC_MEM2MEM;
+
+	ctrla = ATC_SRC_WIDTH(2) |
+		ATC_DST_WIDTH(2);
+
+	desc = atc_desc_get(atchan);
+	if (!desc) {
+		dev_err(chan2dev(chan), "%s: can't get a descriptor\n",
+			__func__);
+		return NULL;
+	}
+
+	desc->memset_vaddr = dma_pool_alloc(atdma->memset_pool, GFP_ATOMIC,
+					    &desc->memset_paddr);
+	if (!desc->memset_vaddr) {
+		dev_err(chan2dev(chan), "%s: couldn't allocate buffer\n",
+			__func__);
+		goto err_put_desc;
+	}
+
+	*desc->memset_vaddr = value;
+	desc->memset = true;
+
+	desc->lli.saddr = desc->memset_paddr;
+	desc->lli.daddr = dest;
+	desc->lli.ctrla = ctrla | xfer_count;
+	desc->lli.ctrlb = ctrlb;
+
+	desc->txd.cookie = -EBUSY;
+	desc->len = len;
+	desc->total_len = len;
+
+	/* set end-of-link on the descriptor */
+	set_desc_eol(desc);
+
+	desc->txd.flags = flags;
+
+	return &desc->txd;
+
+err_put_desc:
+	atc_desc_put(atchan, desc);
+	return NULL;
+}
+
 
 /**
  * atc_prep_slave_sg - prepare descriptors for a DMA_SLAVE transaction
@@ -1755,6 +1850,8 @@ static int __init at_dma_probe(struct platform_device *pdev)
 	dma_cap_set(DMA_SG, at91sam9rl_config.cap_mask);
 	dma_cap_set(DMA_INTERLEAVE, at91sam9g45_config.cap_mask);
 	dma_cap_set(DMA_MEMCPY, at91sam9g45_config.cap_mask);
+	dma_cap_set(DMA_MEMSET, at91sam9g45_config.cap_mask);
+	dma_cap_set(DMA_PRIVATE, at91sam9g45_config.cap_mask);
 	dma_cap_set(DMA_SLAVE, at91sam9g45_config.cap_mask);
 	dma_cap_set(DMA_SG, at91sam9g45_config.cap_mask);
 
@@ -1818,7 +1915,16 @@ static int __init at_dma_probe(struct platform_device *pdev)
 	if (!atdma->dma_desc_pool) {
 		dev_err(&pdev->dev, "No memory for descriptors dma pool\n");
 		err = -ENOMEM;
-		goto err_pool_create;
+		goto err_desc_pool_create;
+	}
+
+	/* create a pool of consistent memory blocks for memset blocks */
+	atdma->memset_pool = dma_pool_create("at_hdmac_memset_pool",
+					     &pdev->dev, sizeof(int), 4, 0);
+	if (!atdma->memset_pool) {
+		dev_err(&pdev->dev, "No memory for memset dma pool\n");
+		err = -ENOMEM;
+		goto err_memset_pool_create;
 	}
 
 	/* clear any pending interrupt */
@@ -1864,6 +1970,11 @@ static int __init at_dma_probe(struct platform_device *pdev)
 	if (dma_has_cap(DMA_MEMCPY, atdma->dma_common.cap_mask))
 		atdma->dma_common.device_prep_dma_memcpy = atc_prep_dma_memcpy;
 
+	if (dma_has_cap(DMA_MEMSET, atdma->dma_common.cap_mask)) {
+		atdma->dma_common.device_prep_dma_memset = atc_prep_dma_memset;
+		atdma->dma_common.fill_align = DMAENGINE_ALIGN_4_BYTES;
+	}
+
 	if (dma_has_cap(DMA_SLAVE, atdma->dma_common.cap_mask)) {
 		atdma->dma_common.device_prep_slave_sg = atc_prep_slave_sg;
 		/* controller can do slave DMA: can trigger cyclic transfers */
@@ -1884,8 +1995,9 @@ static int __init at_dma_probe(struct platform_device *pdev)
 
 	dma_writel(atdma, EN, AT_DMA_ENABLE);
 
-	dev_info(&pdev->dev, "Atmel AHB DMA Controller ( %s%s%s), %d channels\n",
+	dev_info(&pdev->dev, "Atmel AHB DMA Controller ( %s%s%s%s), %d channels\n",
 	  dma_has_cap(DMA_MEMCPY, atdma->dma_common.cap_mask) ? "cpy " : "",
+	  dma_has_cap(DMA_MEMSET, atdma->dma_common.cap_mask) ? "set " : "",
 	  dma_has_cap(DMA_SLAVE, atdma->dma_common.cap_mask)  ? "slave " : "",
 	  dma_has_cap(DMA_SG, atdma->dma_common.cap_mask)  ? "sg-cpy " : "",
 	  plat_dat->nr_channels);
@@ -1910,8 +2022,10 @@ static int __init at_dma_probe(struct platform_device *pdev)
 
 err_of_dma_controller_register:
 	dma_async_device_unregister(&atdma->dma_common);
+	dma_pool_destroy(atdma->memset_pool);
+err_memset_pool_create:
 	dma_pool_destroy(atdma->dma_desc_pool);
-err_pool_create:
+err_desc_pool_create:
 	free_irq(platform_get_irq(pdev, 0), atdma);
 err_irq:
 	clk_disable_unprepare(atdma->clk);
@@ -1936,6 +2050,7 @@ static int at_dma_remove(struct platform_device *pdev)
 	at_dma_off(atdma);
 	dma_async_device_unregister(&atdma->dma_common);
 
+	dma_pool_destroy(atdma->memset_pool);
 	dma_pool_destroy(atdma->dma_desc_pool);
 	free_irq(platform_get_irq(pdev, 0), atdma);
 
diff --git a/drivers/dma/at_hdmac_regs.h b/drivers/dma/at_hdmac_regs.h
index 7f5a08230f76..c3bebbe899ac 100644
--- a/drivers/dma/at_hdmac_regs.h
+++ b/drivers/dma/at_hdmac_regs.h
@@ -200,6 +200,11 @@ struct at_desc {
 	size_t				boundary;
 	size_t				dst_hole;
 	size_t				src_hole;
+
+	/* Memset temporary buffer */
+	bool				memset;
+	dma_addr_t			memset_paddr;
+	int				*memset_vaddr;
 };
 
 static inline struct at_desc *
@@ -330,6 +335,7 @@ struct at_dma {
 	u8			all_chan_mask;
 
 	struct dma_pool		*dma_desc_pool;
+	struct dma_pool		*memset_pool;
 	/* AT THE END channels table */
 	struct at_dma_chan	chan[0];
 };
-- 
2.4.6



From will.deacon at arm.com  Mon Aug 24 02:22:56 2015
From: will.deacon at arm.com (Will Deacon)
Date: Mon, 24 Aug 2015 10:22:56 +0100
Subject: [PATCH 0/2] arm64: ignore memory outside of the linear range
In-Reply-To: <CAKv+Gu-OQ4VyCqe=mEDOrrfAtAWTfRtAiqXMGSVjJxOH6xi4Ow@mail.gmail.com>
References: <1439890482-20798-1-git-send-email-ard.biesheuvel@linaro.org>
 <CY1PR0301MB0748FC71E6866C8AFACAAFF687780@CY1PR0301MB0748.namprd03.prod.outlook.com>
 <CAKv+Gu-OQ4VyCqe=mEDOrrfAtAWTfRtAiqXMGSVjJxOH6xi4Ow@mail.gmail.com>
Message-ID: <20150824092256.GA11262@arm.com>

On Mon, Aug 24, 2015 at 09:00:43AM +0100, Ard Biesheuvel wrote:
> >> This is a followup to the single patch I posted on Aug 15th to ignore
> >> RAM that cannot be covered by the linear mapping. Instead of clipping
> >> the memory after the fact, this clips the memory before installing the
> >> regions into the memblock memory table.
> >>
> >> This is basically the approach that Mark Rutland suggested here
> >>
> >> http://article.gmane.org/gmane.linux.ports.arm.kernel/430239
> >>
> >> but modified to correctly consider the base of the kernel image as the
> >> start of the linear mapping.
> >>
> >> Ard Biesheuvel (2):
> >>   of/fdt: make memblock maximum physical address arch configurable
> >>   arm64: set MAX_MEMBLOCK_ADDR according to linear region size
> >>
> >>  arch/arm64/include/asm/memory.h |  8 ++++++++
> >>  drivers/of/fdt.c                | 12 +++++++-----
> >>  2 files changed, 15 insertions(+), 5 deletions(-)
> >
> > Tested on Freescale LS2085ARDB which has a split memory region
> > that triggers the bug.
> >
> > Tested-by: Stuart Yoder <stuart.yoder at freescale.com>
> >
> 
> Will you be picking up this series for v4.3? If so, do you need me to
> resend it with the tags added?

Sorry, I missed Rob's ack on the of/fdt.c change. I'll pick these up
later today, no need to resend.

Cheers,

Will


From wens at csie.org  Mon Aug 24 02:25:16 2015
From: wens at csie.org (Chen-Yu Tsai)
Date: Mon, 24 Aug 2015 17:25:16 +0800
Subject: [PATCH v2] watchdog: sunxi: fix activation of system reset
In-Reply-To: <20150726193238.GM2564@lukather>
References: <55B32BCE.5050506@gmail.com> <20150726193238.GM2564@lukather>
Message-ID: <CAGb2v66oZH_OifuUkzjJS3B5L-uBOaNMWZ7xhgF01EjrkuEq6g@mail.gmail.com>

Hi,

On Mon, Jul 27, 2015 at 3:32 AM, Maxime Ripard
<maxime.ripard at free-electrons.com> wrote:
> On Sat, Jul 25, 2015 at 08:25:18AM +0200, Francesco Lavra wrote:
>> Commit f2147de33470 ("watchdog: sunxi: support parameterized compatible
>> strings") introduced a regression in sunxi_wdt_start(), by which
>> the system reset function of the watchdog is not enabled upon
>> starting the watchdog. As a result, the system is not reset when the
>> watchdog expires. Fix it.
>>
>> Signed-off-by: Francesco Lavra <francescolavra.fl at gmail.com>
>> Reviewed-by: Guenter Roeck <linux at roeck-us.net>
>> Fixes: f2147de33470 ("watchdog: sunxi: support parameterized compatible strings")
>> Cc: stable at vger.kernel.org
>
> Acked-by: Maxime Ripard <maxime.ripard at free-electrons.com>

What tree should this go in through?
Guenter, are you still taking watchdog patches?


Thanks
ChenYu


From varada at codeaurora.org  Mon Aug 24 02:28:13 2015
From: varada at codeaurora.org (Varadarajan Narayanan)
Date: Mon, 24 Aug 2015 14:58:13 +0530
Subject: [PATCH v3] qcom: ipq40xx: Add basic board/dts support for IPQ40XX SoC
Message-ID: <20150824092813.GA15581@codeaurora.org>

Add initial dts files and SoC support for IPQ40XX

Signed-off-by: Varadarajan Narayanan <varada at codeaurora.org>
---
Changes in v2:
  - Added devicetree bindings documentation

Changes in v3:
  - Split 'gcnt' into a separate patch
  - Added the new entries to Makefiles, Kconfig & board.c in sorted order
  - Used "qcom,ipq40xx" instead of "qcom,ipq40xx-r3pc" in board.c

 Documentation/devicetree/bindings/qcom.txt | 16 ++++++
 arch/arm/boot/dts/Makefile                 |  1 +
 arch/arm/boot/dts/qcom-ipq40xx-r3pc.dts    | 33 ++++++++++++
 arch/arm/boot/dts/qcom-ipq40xx.dtsi        | 81 ++++++++++++++++++++++++++++++
 arch/arm/configs/ipq_defconfig             |  1 +
 arch/arm/mach-qcom/Kconfig                 |  4 ++
 arch/arm/mach-qcom/board.c                 |  1 +
 7 files changed, 137 insertions(+)
 create mode 100644 Documentation/devicetree/bindings/qcom.txt
 create mode 100644 arch/arm/boot/dts/qcom-ipq40xx-r3pc.dts
 create mode 100644 arch/arm/boot/dts/qcom-ipq40xx.dtsi

diff --git a/Documentation/devicetree/bindings/qcom.txt b/Documentation/devicetree/bindings/qcom.txt
new file mode 100644
index 0000000..7d56bd0
--- /dev/null
+++ b/Documentation/devicetree/bindings/qcom.txt
@@ -0,0 +1,16 @@
+Qualcomm IPQ device tree bindings
+---------------------------------
+
+System on Chip
+
+Device tree must specify which SoC it uses, with one of the
+following compatible strings
+
+       "qcom,ipq40xx"
+
+Platform
+
+Device tree must specify which Platform it uses, with one of the
+following compatible strings
+
+       "qcom,ipq40xx-r3pc"
diff --git a/arch/arm/boot/dts/Makefile b/arch/arm/boot/dts/Makefile
index 246473a..d20d49c 100644
--- a/arch/arm/boot/dts/Makefile
+++ b/arch/arm/boot/dts/Makefile
@@ -474,6 +474,7 @@ dtb-$(CONFIG_ARCH_QCOM) += \
 	qcom-apq8074-dragonboard.dtb \
 	qcom-apq8084-ifc6540.dtb \
 	qcom-apq8084-mtp.dtb \
+	qcom-ipq40xx-r3pc.dtb \
 	qcom-ipq8064-ap148.dtb \
 	qcom-msm8660-surf.dtb \
 	qcom-msm8960-cdp.dtb \
diff --git a/arch/arm/boot/dts/qcom-ipq40xx-r3pc.dts b/arch/arm/boot/dts/qcom-ipq40xx-r3pc.dts
new file mode 100644
index 0000000..7e4e629
--- /dev/null
+++ b/arch/arm/boot/dts/qcom-ipq40xx-r3pc.dts
@@ -0,0 +1,33 @@
+/* Copyright (c) 2014, The Linux Foundation. All rights reserved.
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License version 2 and
+ * only 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 "qcom-ipq40xx.dtsi"
+
+/ {
+	model = "Qualcomm Technologies, Inc. IPQ40XX R3PC";
+	compatible = "qcom,ipq40xx-r3pc", "qcom,ipq40xx";
+
+	memory {
+		device_type = "memory";
+		reg = <0x80000000 0x20000000>; /* 512MB */
+	};
+
+	chosen {
+		bootargs = "root=/dev/ram rw init=/init console=ttyMSM0,115200n8 initrd=0x82000000,0x000E2246";
+	};
+
+	soc {
+		serial at 78b0000 {
+			status = "ok";
+		};
+	};
+};
diff --git a/arch/arm/boot/dts/qcom-ipq40xx.dtsi b/arch/arm/boot/dts/qcom-ipq40xx.dtsi
new file mode 100644
index 0000000..f572f38
--- /dev/null
+++ b/arch/arm/boot/dts/qcom-ipq40xx.dtsi
@@ -0,0 +1,81 @@
+/*
+ * Copyright (c) 2014, The Linux Foundation. All rights reserved.
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License version 2 and
+ * only 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.
+ */
+
+/dts-v1/;
+
+#include "skeleton.dtsi"
+
+/ {
+	model = "Qualcomm Technologies, Inc. IPQ40XX";
+	compatible = "qcom,ipq40xx";
+	interrupt-parent = <&intc>;
+
+	cpus {
+		#address-cells = <1>;
+		#size-cells = <0>;
+		cpu at 0 {
+			device_type = "cpu";
+			compatible = "arm,cortex-a7";
+			reg = <0x0>;
+		};
+
+		cpu at 1 {
+			device_type = "cpu";
+			compatible = "arm,cortex-a7";
+			reg = <0x1>;
+		};
+
+		cpu at 2 {
+			device_type = "cpu";
+			compatible = "arm,cortex-a7";
+			reg = <0x2>;
+		};
+
+		cpu at 3 {
+			device_type = "cpu";
+			compatible = "arm,cortex-a7";
+			reg = <0x3>;
+		};
+	};
+
+	soc {
+		#address-cells = <1>;
+		#size-cells = <1>;
+		ranges;
+		compatible = "simple-bus";
+
+		intc: interrupt-controller at b000000 {
+			compatible = "qcom,msm-qgic2";
+			interrupt-controller;
+			#interrupt-cells = <3>;
+			reg = <0x0b000000 0x1000>,
+			<0x0b002000 0x1000>;
+		};
+
+		timer {
+			compatible = "arm,armv7-timer";
+			interrupts = <1 2 0xf08>,
+				     <1 3 0xf08>,
+				     <1 4 0xf08>,
+				     <1 1 0xf08>;
+			clock-frequency = <20833333>;
+		};
+
+		serial at 78b0000 {
+			compatible = "qcom,msm-uartdm-v1.4", "qcom,msm-uartdm";
+			reg = <0x78b0000 0x200>;
+			interrupts = <0 108 0>;
+			status = "disabled";
+		};
+	};
+};
diff --git a/arch/arm/configs/ipq_defconfig b/arch/arm/configs/ipq_defconfig
index 1cabd8b..89bf8ad 100644
--- a/arch/arm/configs/ipq_defconfig
+++ b/arch/arm/configs/ipq_defconfig
@@ -21,6 +21,7 @@ CONFIG_ARCH_QCOM=y
 CONFIG_ARCH_MSM8X60=y
 CONFIG_ARCH_MSM8960=y
 CONFIG_ARCH_MSM8974=y
+CONFIG_ARCH_IPQ40XX=y
 CONFIG_ARCH_IPQ8064=y
 CONFIG_SMP=y
 CONFIG_PREEMPT=y
diff --git a/arch/arm/mach-qcom/Kconfig b/arch/arm/mach-qcom/Kconfig
index fab49a2..70812aa 100644
--- a/arch/arm/mach-qcom/Kconfig
+++ b/arch/arm/mach-qcom/Kconfig
@@ -22,6 +22,10 @@ config ARCH_MSM8974
 	bool "Enable support for MSM8974"
 	select HAVE_ARM_ARCH_TIMER
 
+config ARCH_IPQ40XX
+	bool "Enable support for IPQ40XX"
+	select HAVE_ARM_ARCH_TIMER
+
 config ARCH_IPQ8064
 	bool "Enable support for IPQ806x"
 	select CLKSRC_QCOM
diff --git a/arch/arm/mach-qcom/board.c b/arch/arm/mach-qcom/board.c
index 6d8bbf7..af9e247 100644
--- a/arch/arm/mach-qcom/board.c
+++ b/arch/arm/mach-qcom/board.c
@@ -18,6 +18,7 @@ static const char * const qcom_dt_match[] __initconst = {
 	"qcom,apq8064",
 	"qcom,apq8074-dragonboard",
 	"qcom,apq8084",
+	"qcom,ipq40xx",
 	"qcom,ipq8062",
 	"qcom,ipq8064",
 	"qcom,msm8660-surf",
-- 
1.8.2.1



From varada at codeaurora.org  Mon Aug 24 02:39:34 2015
From: varada at codeaurora.org (Varadarajan Narayanan)
Date: Mon, 24 Aug 2015 15:09:34 +0530
Subject: [PATCH] dts: ipq40xx: Add the global counter node
Message-ID: <20150824093934.GA26409@codeaurora.org>

Adding the dt data for the 56 global counter which supplies
the count to the arm arch timers.

Signed-off-by: Varadarajan Narayanan <varada at codeaurora.org>
---

> Refer http://www.spinics.net/lists/linux-arm-msm/msg16660.html
>
> On Fri, Aug 21, 2015 at 09:21:33AM -0700, Bjorn Andersson
> wrote:
>
> Most of the time when there's a device consuming one
> register it turns out to be part of some larger hw block
> and down the road things get complicated from the fact
> that we mapped 4 bytes in the middle.
>
> Is this part of a larger block? Can we better implement
> that as a simple-mfd or syscon?

It is a part of larger block. However, we are ok with the
default settings of the other registers. In a subsequent
patch we will set a value in this register.

Please let me know if I should still go for mfd/syscon

 Documentation/devicetree/bindings/clock/qca,gcnt.txt | 15 +++++++++++++++
 arch/arm/boot/dts/qcom-ipq40xx.dtsi                  |  5 +++++
 2 files changed, 20 insertions(+)
 create mode 100644 Documentation/devicetree/bindings/clock/qca,gcnt.txt

diff --git a/Documentation/devicetree/bindings/clock/qca,gcnt.txt b/Documentation/devicetree/bindings/clock/qca,gcnt.txt
new file mode 100644
index 0000000..ccffc01
--- /dev/null
+++ b/Documentation/devicetree/bindings/clock/qca,gcnt.txt
@@ -0,0 +1,15 @@
+QCA Global Counter
+------------------------------------------------
+Enable 56-bit global counter which supplies the count to the arm arch timers.
+
+Required properties :
+- compatible : "qcom,qca-gcnt"
+
+- reg : shall contain base register location and length
+
+Example:
+
+	counter {
+		compatible = "qcom,qca-gcnt";
+		reg = <0x004a1000 0x4>;
+	};
diff --git a/arch/arm/boot/dts/qcom-ipq40xx.dtsi b/arch/arm/boot/dts/qcom-ipq40xx.dtsi
index f572f38..76c55a3 100644
--- a/arch/arm/boot/dts/qcom-ipq40xx.dtsi
+++ b/arch/arm/boot/dts/qcom-ipq40xx.dtsi
@@ -62,6 +62,11 @@
 			<0x0b002000 0x1000>;
 		};
 
+		counter {
+			compatible = "qcom,qca-gcnt";
+			reg = <0x004a1000 0x4>;
+		};
+
 		timer {
 			compatible = "arm,armv7-timer";
 			interrupts = <1 2 0xf08>,
-- 
1.8.2.1



From gabriel.fernandez at linaro.org  Mon Aug 24 02:40:04 2015
From: gabriel.fernandez at linaro.org (Gabriel Fernandez)
Date: Mon, 24 Aug 2015 11:40:04 +0200
Subject: [PATCH 1/1] ARM: DT: STi: STiH418: Fix mmc0 clock configuration
Message-ID: <1440409204-11108-1-git-send-email-gabriel.fernandez@linaro.org>

This patch configure correctly the MMC-0 clock for STiH418 platform.

Signed-off-by: Gabriel Fernandez <gabriel.fernandez at linaro.org>
---
 arch/arm/boot/dts/stih418-b2199.dts | 4 ++++
 1 file changed, 4 insertions(+)

diff --git a/arch/arm/boot/dts/stih418-b2199.dts b/arch/arm/boot/dts/stih418-b2199.dts
index 82eee39..7a03ca6 100644
--- a/arch/arm/boot/dts/stih418-b2199.dts
+++ b/arch/arm/boot/dts/stih418-b2199.dts
@@ -85,6 +85,10 @@
 			sd-uhs-sdr50;
 			sd-uhs-sdr104;
 			sd-uhs-ddr50;
+
+			assigned-clocks = <&clk_s_c0_flexgen CLK_MMC_0>;
+			assigned-clock-parents = <&clk_s_c0_pll1 0>;
+			assigned-clock-rates = <200000000>;
 		};
 
 		miphy28lp_phy: miphy28lp at 9b22000 {
-- 
1.9.1



From gabriel.fernandez at linaro.org  Mon Aug 24 02:40:47 2015
From: gabriel.fernandez at linaro.org (Gabriel Fernandez)
Date: Mon, 24 Aug 2015 11:40:47 +0200
Subject: [PATCH v2 0/4] ST PLL improvement
Message-ID: <1440409251-11166-1-git-send-email-gabriel.fernandez@linaro.org>

Changes in v2:
 - Add const for st_pll4600c28_418_a9 structure
 - Use readl_relaxed_poll_timeout macro instead Jiffies
 - Add patch to enable stih418 A9 pll via DT.

This patchset is based on '[PATCH 0/2] ST PLL fixes for 4.3'

Gabriel Fernandez (4):
  drivers: clk: st: Support for enable/disable in Clockgen PLLs
  drivers: clk: st: PLL rate change implementation for DVFS
  drivers: clk: st: Correct the pll-type for A9 for stih418
  ARM: STi: DT: Add support for stih418 A9 pll

 .../devicetree/bindings/clock/st/st,clkgen-pll.txt |   1 +
 arch/arm/boot/dts/stih418-clock.dtsi               |   2 +-
 drivers/clk/st/clkgen-mux.c                        |   3 +
 drivers/clk/st/clkgen-pll.c                        | 469 ++++++++++++++++++++-
 drivers/clk/st/clkgen.h                            |   2 +
 5 files changed, 468 insertions(+), 9 deletions(-)

-- 
1.9.1



From gabriel.fernandez at linaro.org  Mon Aug 24 02:40:48 2015
From: gabriel.fernandez at linaro.org (Gabriel Fernandez)
Date: Mon, 24 Aug 2015 11:40:48 +0200
Subject: [PATCH v2 1/4] drivers: clk: st: Support for enable/disable in
 Clockgen PLLs
In-Reply-To: <1440409251-11166-1-git-send-email-gabriel.fernandez@linaro.org>
References: <1440409251-11166-1-git-send-email-gabriel.fernandez@linaro.org>
Message-ID: <1440409251-11166-2-git-send-email-gabriel.fernandez@linaro.org>

The patch adds support for enable/disable of the Clockgen PLLs.
clkgen_pll_enable/clkgen_pll_disable added as generic function for all PLLs.

Signed-off-by: Pankaj Dev <pankaj.dev at st.com>
Signed-off-by: Gabriel Fernandez <gabriel.fernandez at linaro.org>
---
 drivers/clk/st/clkgen-pll.c | 92 ++++++++++++++++++++++++++++++++++++++++++++-
 1 file changed, 91 insertions(+), 1 deletion(-)

diff --git a/drivers/clk/st/clkgen-pll.c b/drivers/clk/st/clkgen-pll.c
index b2a332c..7ee485d 100644
--- a/drivers/clk/st/clkgen-pll.c
+++ b/drivers/clk/st/clkgen-pll.c
@@ -18,6 +18,7 @@
 #include <linux/of_address.h>
 #include <linux/clk.h>
 #include <linux/clk-provider.h>
+#include <linux/iopoll.h>
 
 #include "clkgen.h"
 
@@ -43,6 +44,7 @@ static DEFINE_SPINLOCK(clkgena_c32_odf_lock);
 
 struct clkgen_pll_data {
 	struct clkgen_field pdn_status;
+	struct clkgen_field pdn_ctrl;
 	struct clkgen_field locked_status;
 	struct clkgen_field mdiv;
 	struct clkgen_field ndiv;
@@ -62,6 +64,7 @@ static const struct clk_ops st_pll1200c32_ops;
 
 static const struct clkgen_pll_data st_pll1600c65_ax = {
 	.pdn_status	= CLKGEN_FIELD(0x0, 0x1,			19),
+	.pdn_ctrl	= CLKGEN_FIELD(0x10,	0x1,			0),
 	.locked_status	= CLKGEN_FIELD(0x0, 0x1,			31),
 	.mdiv		= CLKGEN_FIELD(0x0, C65_MDIV_PLL1600_MASK,	0),
 	.ndiv		= CLKGEN_FIELD(0x0, C65_NDIV_MASK,		8),
@@ -70,6 +73,7 @@ static const struct clkgen_pll_data st_pll1600c65_ax = {
 
 static const struct clkgen_pll_data st_pll800c65_ax = {
 	.pdn_status	= CLKGEN_FIELD(0x0,	0x1,			19),
+	.pdn_ctrl	= CLKGEN_FIELD(0xC,	0x1,			1),
 	.locked_status	= CLKGEN_FIELD(0x0,	0x1,			31),
 	.mdiv		= CLKGEN_FIELD(0x0,	C65_MDIV_PLL800_MASK,	0),
 	.ndiv		= CLKGEN_FIELD(0x0,	C65_NDIV_MASK,		8),
@@ -79,6 +83,7 @@ static const struct clkgen_pll_data st_pll800c65_ax = {
 
 static const struct clkgen_pll_data st_pll3200c32_a1x_0 = {
 	.pdn_status	= CLKGEN_FIELD(0x0,	0x1,			31),
+	.pdn_ctrl	= CLKGEN_FIELD(0x18,	0x1,			0),
 	.locked_status	= CLKGEN_FIELD(0x4,	0x1,			31),
 	.ndiv		= CLKGEN_FIELD(0x0,	C32_NDIV_MASK,		0x0),
 	.idf		= CLKGEN_FIELD(0x4,	C32_IDF_MASK,		0x0),
@@ -96,6 +101,7 @@ static const struct clkgen_pll_data st_pll3200c32_a1x_0 = {
 
 static const struct clkgen_pll_data st_pll3200c32_a1x_1 = {
 	.pdn_status	= CLKGEN_FIELD(0xC,	0x1,			31),
+	.pdn_ctrl	= CLKGEN_FIELD(0x18,	0x1,			1),
 	.locked_status	= CLKGEN_FIELD(0x10,	0x1,			31),
 	.ndiv		= CLKGEN_FIELD(0xC,	C32_NDIV_MASK,		0x0),
 	.idf		= CLKGEN_FIELD(0x10,	C32_IDF_MASK,		0x0),
@@ -114,6 +120,7 @@ static const struct clkgen_pll_data st_pll3200c32_a1x_1 = {
 /* 415 specific */
 static const struct clkgen_pll_data st_pll3200c32_a9_415 = {
 	.pdn_status	= CLKGEN_FIELD(0x0,	0x1,			0),
+	.pdn_ctrl	= CLKGEN_FIELD(0x0,	0x1,			0),
 	.locked_status	= CLKGEN_FIELD(0x6C,	0x1,			0),
 	.ndiv		= CLKGEN_FIELD(0x0,	C32_NDIV_MASK,		9),
 	.idf		= CLKGEN_FIELD(0x0,	C32_IDF_MASK,		22),
@@ -125,6 +132,7 @@ static const struct clkgen_pll_data st_pll3200c32_a9_415 = {
 
 static const struct clkgen_pll_data st_pll3200c32_ddr_415 = {
 	.pdn_status	= CLKGEN_FIELD(0x0,	0x1,			0),
+	.pdn_ctrl	= CLKGEN_FIELD(0x0,	0x1,			0),
 	.locked_status	= CLKGEN_FIELD(0x100,	0x1,			0),
 	.ndiv		= CLKGEN_FIELD(0x8,	C32_NDIV_MASK,		0),
 	.idf		= CLKGEN_FIELD(0x0,	C32_IDF_MASK,		25),
@@ -137,7 +145,8 @@ static const struct clkgen_pll_data st_pll3200c32_ddr_415 = {
 };
 
 static const struct clkgen_pll_data st_pll1200c32_gpu_415 = {
-	.pdn_status	= CLKGEN_FIELD(0x144,	0x1,			3),
+	.pdn_status	= CLKGEN_FIELD(0x4,	0x1,			0),
+	.pdn_ctrl	= CLKGEN_FIELD(0x4,	0x1,			0),
 	.locked_status	= CLKGEN_FIELD(0x168,	0x1,			0),
 	.ldf		= CLKGEN_FIELD(0x0,	C32_LDF_MASK,		3),
 	.idf		= CLKGEN_FIELD(0x0,	C32_IDF_MASK,		0),
@@ -149,6 +158,7 @@ static const struct clkgen_pll_data st_pll1200c32_gpu_415 = {
 /* 416 specific */
 static const struct clkgen_pll_data st_pll3200c32_a9_416 = {
 	.pdn_status	= CLKGEN_FIELD(0x0,	0x1,			0),
+	.pdn_ctrl	= CLKGEN_FIELD(0x0,	0x1,			0),
 	.locked_status	= CLKGEN_FIELD(0x6C,	0x1,			0),
 	.ndiv		= CLKGEN_FIELD(0x8,	C32_NDIV_MASK,		0),
 	.idf		= CLKGEN_FIELD(0x0,	C32_IDF_MASK,		25),
@@ -160,6 +170,7 @@ static const struct clkgen_pll_data st_pll3200c32_a9_416 = {
 
 static const struct clkgen_pll_data st_pll3200c32_ddr_416 = {
 	.pdn_status	= CLKGEN_FIELD(0x0,	0x1,			0),
+	.pdn_ctrl	= CLKGEN_FIELD(0x0,	0x1,			0),
 	.locked_status	= CLKGEN_FIELD(0x10C,	0x1,			0),
 	.ndiv		= CLKGEN_FIELD(0x8,	C32_NDIV_MASK,		0),
 	.idf		= CLKGEN_FIELD(0x0,	C32_IDF_MASK,		25),
@@ -173,6 +184,7 @@ static const struct clkgen_pll_data st_pll3200c32_ddr_416 = {
 
 static const struct clkgen_pll_data st_pll1200c32_gpu_416 = {
 	.pdn_status	= CLKGEN_FIELD(0x8E4,	0x1,			3),
+	.pdn_ctrl	= CLKGEN_FIELD(0x8E4,	0x1,			3),
 	.locked_status	= CLKGEN_FIELD(0x90C,	0x1,			0),
 	.ldf		= CLKGEN_FIELD(0x0,	C32_LDF_MASK,		3),
 	.idf		= CLKGEN_FIELD(0x0,	C32_IDF_MASK,		0),
@@ -184,6 +196,7 @@ static const struct clkgen_pll_data st_pll1200c32_gpu_416 = {
 static const struct clkgen_pll_data st_pll3200c32_407_a0 = {
 	/* 407 A0 */
 	.pdn_status	= CLKGEN_FIELD(0x2a0,	0x1,			8),
+	.pdn_ctrl	= CLKGEN_FIELD(0x2a0,	0x1,			8),
 	.locked_status	= CLKGEN_FIELD(0x2a0,	0x1,			24),
 	.ndiv		= CLKGEN_FIELD(0x2a4,	C32_NDIV_MASK,		16),
 	.idf		= CLKGEN_FIELD(0x2a4,	C32_IDF_MASK,		0x0),
@@ -196,6 +209,7 @@ static const struct clkgen_pll_data st_pll3200c32_407_a0 = {
 static const struct clkgen_pll_data st_pll3200c32_cx_0 = {
 	/* 407 C0 PLL0 */
 	.pdn_status	= CLKGEN_FIELD(0x2a0,	0x1,			8),
+	.pdn_ctrl	= CLKGEN_FIELD(0x2a0,	0x1,			8),
 	.locked_status	= CLKGEN_FIELD(0x2a0,	0x1,			24),
 	.ndiv		= CLKGEN_FIELD(0x2a4,	C32_NDIV_MASK,		16),
 	.idf		= CLKGEN_FIELD(0x2a4,	C32_IDF_MASK,		0x0),
@@ -208,6 +222,7 @@ static const struct clkgen_pll_data st_pll3200c32_cx_0 = {
 static const struct clkgen_pll_data st_pll3200c32_cx_1 = {
 	/* 407 C0 PLL1 */
 	.pdn_status	= CLKGEN_FIELD(0x2c8,	0x1,			8),
+	.pdn_ctrl	= CLKGEN_FIELD(0x2c8,	0x1,			8),
 	.locked_status	= CLKGEN_FIELD(0x2c8,	0x1,			24),
 	.ndiv		= CLKGEN_FIELD(0x2cc,	C32_NDIV_MASK,		16),
 	.idf		= CLKGEN_FIELD(0x2cc,	C32_IDF_MASK,		0x0),
@@ -220,6 +235,7 @@ static const struct clkgen_pll_data st_pll3200c32_cx_1 = {
 static const struct clkgen_pll_data st_pll3200c32_407_a9 = {
 	/* 407 A9 */
 	.pdn_status	= CLKGEN_FIELD(0x1a8,	0x1,			0),
+	.pdn_ctrl	= CLKGEN_FIELD(0x1a8,	0x1,			0),
 	.locked_status	= CLKGEN_FIELD(0x87c,	0x1,			0),
 	.ndiv		= CLKGEN_FIELD(0x1b0,	C32_NDIV_MASK,		0),
 	.idf		= CLKGEN_FIELD(0x1a8,	C32_IDF_MASK,		25),
@@ -271,6 +287,71 @@ static int clkgen_pll_is_enabled(struct clk_hw *hw)
 	return !poweroff;
 }
 
+static int __clkgen_pll_enable(struct clk_hw *hw)
+{
+	struct clkgen_pll *pll = to_clkgen_pll(hw);
+	void __iomem *base =  pll->regs_base;
+	struct clkgen_field *field = &pll->data->locked_status;
+	int ret = 0;
+	u32 reg;
+
+	if (clkgen_pll_is_enabled(hw))
+		return 0;
+
+	CLKGEN_WRITE(pll, pdn_ctrl, 0);
+
+	ret = readl_relaxed_poll_timeout(base + field->offset, reg,
+			!!((reg >> field->shift) & field->mask),  0, 10000);
+
+	if (!ret)
+		pr_debug("%s:%s enabled\n", __clk_get_name(hw->clk), __func__);
+
+	return ret;
+}
+
+static int clkgen_pll_enable(struct clk_hw *hw)
+{
+	struct clkgen_pll *pll = to_clkgen_pll(hw);
+	unsigned long flags = 0;
+	int ret = 0;
+
+	if (pll->lock)
+		spin_lock_irqsave(pll->lock, flags);
+
+	ret = __clkgen_pll_enable(hw);
+
+	if (pll->lock)
+		spin_unlock_irqrestore(pll->lock, flags);
+
+	return ret;
+}
+
+static void __clkgen_pll_disable(struct clk_hw *hw)
+{
+	struct clkgen_pll *pll = to_clkgen_pll(hw);
+
+	if (!clkgen_pll_is_enabled(hw))
+		return;
+
+	CLKGEN_WRITE(pll, pdn_ctrl, 1);
+
+	pr_debug("%s:%s disabled\n", __clk_get_name(hw->clk), __func__);
+}
+
+static void clkgen_pll_disable(struct clk_hw *hw)
+{
+	struct clkgen_pll *pll = to_clkgen_pll(hw);
+	unsigned long flags = 0;
+
+	if (pll->lock)
+		spin_lock_irqsave(pll->lock, flags);
+
+	__clkgen_pll_disable(hw);
+
+	if (pll->lock)
+		spin_unlock_irqrestore(pll->lock, flags);
+}
+
 static unsigned long recalc_stm_pll800c65(struct clk_hw *hw,
 		unsigned long parent_rate)
 {
@@ -372,21 +453,29 @@ static unsigned long recalc_stm_pll1200c32(struct clk_hw *hw,
 }
 
 static const struct clk_ops st_pll1600c65_ops = {
+	.enable		= clkgen_pll_enable,
+	.disable	= clkgen_pll_disable,
 	.is_enabled	= clkgen_pll_is_enabled,
 	.recalc_rate	= recalc_stm_pll1600c65,
 };
 
 static const struct clk_ops st_pll800c65_ops = {
+	.enable		= clkgen_pll_enable,
+	.disable	= clkgen_pll_disable,
 	.is_enabled	= clkgen_pll_is_enabled,
 	.recalc_rate	= recalc_stm_pll800c65,
 };
 
 static const struct clk_ops stm_pll3200c32_ops = {
+	.enable		= clkgen_pll_enable,
+	.disable	= clkgen_pll_disable,
 	.is_enabled	= clkgen_pll_is_enabled,
 	.recalc_rate	= recalc_stm_pll3200c32,
 };
 
 static const struct clk_ops st_pll1200c32_ops = {
+	.enable		= clkgen_pll_enable,
+	.disable	= clkgen_pll_disable,
 	.is_enabled	= clkgen_pll_is_enabled,
 	.recalc_rate	= recalc_stm_pll1200c32,
 };
@@ -414,6 +503,7 @@ static struct clk * __init clkgen_pll_register(const char *parent_name,
 	pll->data = pll_data;
 	pll->regs_base = reg;
 	pll->hw.init = &init;
+	pll->lock = lock;
 
 	clk = clk_register(NULL, &pll->hw);
 	if (IS_ERR(clk)) {
-- 
1.9.1



From gabriel.fernandez at linaro.org  Mon Aug 24 02:40:49 2015
From: gabriel.fernandez at linaro.org (Gabriel Fernandez)
Date: Mon, 24 Aug 2015 11:40:49 +0200
Subject: [PATCH v2 2/4] drivers: clk: st: PLL rate change implementation for
 DVFS
In-Reply-To: <1440409251-11166-1-git-send-email-gabriel.fernandez@linaro.org>
References: <1440409251-11166-1-git-send-email-gabriel.fernandez@linaro.org>
Message-ID: <1440409251-11166-3-git-send-email-gabriel.fernandez@linaro.org>

Change A9 PLL rate, as per requirement from the cpufreq framework,
for DVFS. For rate change, the A9 clock needs to be temporarily sourced
from PLL external to A9 and then sourced back to A9-PLL

Signed-off-by: Pankaj Dev <pankaj.dev at st.com>
Signed-off-by: Gabriel Fernandez <gabriel.fernandez at linaro.org>
---
 drivers/clk/st/clkgen-mux.c |   3 +
 drivers/clk/st/clkgen-pll.c | 185 ++++++++++++++++++++++++++++++++++++++++++--
 drivers/clk/st/clkgen.h     |   2 +
 3 files changed, 182 insertions(+), 8 deletions(-)

diff --git a/drivers/clk/st/clkgen-mux.c b/drivers/clk/st/clkgen-mux.c
index 4f7f6c0..5dc5ce2 100644
--- a/drivers/clk/st/clkgen-mux.c
+++ b/drivers/clk/st/clkgen-mux.c
@@ -17,6 +17,7 @@
 #include <linux/of_address.h>
 #include <linux/clk.h>
 #include <linux/clk-provider.h>
+#include "clkgen.h"
 
 static DEFINE_SPINLOCK(clkgena_divmux_lock);
 static DEFINE_SPINLOCK(clkgenf_lock);
@@ -576,6 +577,7 @@ static struct clkgen_mux_data stih415_a9_mux_data = {
 	.offset = 0,
 	.shift = 1,
 	.width = 2,
+	.lock = &clkgen_a9_lock,
 };
 static struct clkgen_mux_data stih416_a9_mux_data = {
 	.offset = 0,
@@ -586,6 +588,7 @@ static struct clkgen_mux_data stih407_a9_mux_data = {
 	.offset = 0x1a4,
 	.shift = 0,
 	.width = 2,
+	.lock = &clkgen_a9_lock,
 };
 
 static const struct of_device_id mux_of_match[] = {
diff --git a/drivers/clk/st/clkgen-pll.c b/drivers/clk/st/clkgen-pll.c
index 7ee485d..94e5a0b 100644
--- a/drivers/clk/st/clkgen-pll.c
+++ b/drivers/clk/st/clkgen-pll.c
@@ -23,6 +23,7 @@
 #include "clkgen.h"
 
 static DEFINE_SPINLOCK(clkgena_c32_odf_lock);
+DEFINE_SPINLOCK(clkgen_a9_lock);
 
 /*
  * Common PLL configuration register bits for PLL800 and PLL1600 C65
@@ -39,6 +40,7 @@ static DEFINE_SPINLOCK(clkgena_c32_odf_lock);
 #define C32_IDF_MASK (0x7)
 #define C32_ODF_MASK (0x3f)
 #define C32_LDF_MASK (0x7f)
+#define C32_CP_MASK (0x1f)
 
 #define C32_MAX_ODFS (4)
 
@@ -51,15 +53,20 @@ struct clkgen_pll_data {
 	struct clkgen_field pdiv;
 	struct clkgen_field idf;
 	struct clkgen_field ldf;
+	struct clkgen_field cp;
 	unsigned int num_odfs;
 	struct clkgen_field odf[C32_MAX_ODFS];
 	struct clkgen_field odf_gate[C32_MAX_ODFS];
+	bool switch2pll_en;
+	struct clkgen_field switch2pll;
+	spinlock_t *lock;
 	const struct clk_ops *ops;
 };
 
 static const struct clk_ops st_pll1600c65_ops;
 static const struct clk_ops st_pll800c65_ops;
 static const struct clk_ops stm_pll3200c32_ops;
+static const struct clk_ops stm_pll3200c32_a9_ops;
 static const struct clk_ops st_pll1200c32_ops;
 
 static const struct clkgen_pll_data st_pll1600c65_ax = {
@@ -242,7 +249,11 @@ static const struct clkgen_pll_data st_pll3200c32_407_a9 = {
 	.num_odfs = 1,
 	.odf		= { CLKGEN_FIELD(0x1b0, C32_ODF_MASK,		8) },
 	.odf_gate	= { CLKGEN_FIELD(0x1ac, 0x1,			28) },
-	.ops		= &stm_pll3200c32_ops,
+	.switch2pll_en	= true,
+	.cp		= CLKGEN_FIELD(0x1a8,	C32_CP_MASK,		1),
+	.switch2pll	= CLKGEN_FIELD(0x1a4,	0x1,			1),
+	.lock = &clkgen_a9_lock,
+	.ops		= &stm_pll3200c32_a9_ops,
 };
 
 /**
@@ -268,10 +279,26 @@ struct clkgen_pll {
 	struct clk_hw		hw;
 	struct clkgen_pll_data	*data;
 	void __iomem		*regs_base;
+	spinlock_t	*lock;
+
+	u32 ndiv;
+	u32 idf;
+	u32 odf;
+	u32 cp;
 };
 
 #define to_clkgen_pll(_hw) container_of(_hw, struct clkgen_pll, hw)
 
+struct stm_pll {
+	unsigned long mdiv;
+	unsigned long ndiv;
+	unsigned long pdiv;
+	unsigned long odf;
+	unsigned long idf;
+	unsigned long ldf;
+	unsigned long cp;
+};
+
 static int clkgen_pll_is_locked(struct clk_hw *hw)
 {
 	struct clkgen_pll *pll = to_clkgen_pll(hw);
@@ -303,8 +330,12 @@ static int __clkgen_pll_enable(struct clk_hw *hw)
 	ret = readl_relaxed_poll_timeout(base + field->offset, reg,
 			!!((reg >> field->shift) & field->mask),  0, 10000);
 
-	if (!ret)
+	if (!ret) {
+		if (pll->data->switch2pll_en)
+			CLKGEN_WRITE(pll, switch2pll, 0);
+
 		pr_debug("%s:%s enabled\n", __clk_get_name(hw->clk), __func__);
+	}
 
 	return ret;
 }
@@ -333,6 +364,9 @@ static void __clkgen_pll_disable(struct clk_hw *hw)
 	if (!clkgen_pll_is_enabled(hw))
 		return;
 
+	if (pll->data->switch2pll_en)
+		CLKGEN_WRITE(pll, switch2pll, 1);
+
 	CLKGEN_WRITE(pll, pdn_ctrl, 1);
 
 	pr_debug("%s:%s disabled\n", __clk_get_name(hw->clk), __func__);
@@ -403,6 +437,67 @@ static unsigned long recalc_stm_pll1600c65(struct clk_hw *hw,
 	return rate;
 }
 
+static int clk_pll3200c32_get_params(unsigned long input, unsigned long output,
+			  struct stm_pll *pll)
+{
+	unsigned long i, n;
+	unsigned long deviation = ~0;
+	unsigned long new_freq;
+	long new_deviation;
+	/* Charge pump table: highest ndiv value for cp=6 to 25 */
+	static const unsigned char cp_table[] = {
+		48, 56, 64, 72, 80, 88, 96, 104, 112, 120,
+		128, 136, 144, 152, 160, 168, 176, 184, 192
+	};
+
+	/* Output clock range: 800Mhz to 1600Mhz */
+	if (output < 800000000 || output > 1600000000)
+		return -EINVAL;
+
+	input /= 1000;
+	output /= 1000;
+
+	for (i = 1; i <= 7 && deviation; i++) {
+		n = i * output / (2 * input);
+
+		/* Checks */
+		if (n < 8)
+			continue;
+		if (n > 200)
+			break;
+
+		new_freq = (input * 2 * n) / i;
+
+		new_deviation = abs(new_freq - output);
+
+		if (!new_deviation || new_deviation < deviation) {
+			pll->idf  = i;
+			pll->ndiv = n;
+			deviation = new_deviation;
+		}
+	}
+
+	if (deviation == ~0) /* No solution found */
+		return -EINVAL;
+
+	/* Computing recommended charge pump value */
+	for (pll->cp = 6; pll->ndiv > cp_table[pll->cp-6]; (pll->cp)++)
+		;
+
+	return 0;
+}
+
+static int clk_pll3200c32_get_rate(unsigned long input, struct stm_pll *pll,
+			unsigned long *rate)
+{
+	if (!pll->idf)
+		pll->idf = 1;
+
+	*rate = ((2 * (input / 1000) * pll->ndiv) / pll->idf) * 1000;
+
+	return 0;
+}
+
 static unsigned long recalc_stm_pll3200c32(struct clk_hw *hw,
 		unsigned long parent_rate)
 {
@@ -425,6 +520,70 @@ static unsigned long recalc_stm_pll3200c32(struct clk_hw *hw,
 	return rate;
 }
 
+static long round_rate_stm_pll3200c32(struct clk_hw *hw, unsigned long rate,
+		unsigned long *prate)
+{
+	struct stm_pll params;
+
+	if (!clk_pll3200c32_get_params(*prate, rate, &params))
+		clk_pll3200c32_get_rate(*prate, &params, &rate);
+	else {
+		pr_debug("%s: %s rate %ld Invalid\n", __func__,
+			 __clk_get_name(hw->clk), rate);
+		return 0;
+	}
+
+	pr_debug("%s: %s new rate %ld [ndiv=%u] [idf=%u]\n",
+		 __func__, __clk_get_name(hw->clk),
+		 rate, (unsigned int)params.ndiv,
+		 (unsigned int)params.idf);
+
+	return rate;
+}
+
+static int set_rate_stm_pll3200c32(struct clk_hw *hw, unsigned long rate,
+				unsigned long parent_rate)
+{
+	struct clkgen_pll *pll = to_clkgen_pll(hw);
+	struct stm_pll params;
+	long hwrate = 0;
+	unsigned long flags = 0;
+
+	if (!rate || !parent_rate)
+		return -EINVAL;
+
+	if (!clk_pll3200c32_get_params(parent_rate, rate, &params))
+		clk_pll3200c32_get_rate(parent_rate, &params, &hwrate);
+
+	pr_debug("%s: %s new rate %ld [ndiv=0x%x] [idf=0x%x]\n",
+		 __func__, __clk_get_name(hw->clk),
+		 hwrate, (unsigned int)params.ndiv,
+		 (unsigned int)params.idf);
+
+	if (!hwrate)
+		return -EINVAL;
+
+	pll->ndiv = params.ndiv;
+	pll->idf = params.idf;
+	pll->cp = params.cp;
+
+	clkgen_pll_disable(hw);
+
+	if (pll->lock)
+		spin_lock_irqsave(pll->lock, flags);
+
+	CLKGEN_WRITE(pll, ndiv, pll->ndiv);
+	CLKGEN_WRITE(pll, idf, pll->idf);
+	CLKGEN_WRITE(pll, cp, pll->cp);
+
+	if (pll->lock)
+		spin_unlock_irqrestore(pll->lock, flags);
+
+	clkgen_pll_enable(hw);
+
+	return 0;
+}
+
 static unsigned long recalc_stm_pll1200c32(struct clk_hw *hw,
 		unsigned long parent_rate)
 {
@@ -473,6 +632,15 @@ static const struct clk_ops stm_pll3200c32_ops = {
 	.recalc_rate	= recalc_stm_pll3200c32,
 };
 
+static const struct clk_ops stm_pll3200c32_a9_ops = {
+	.enable		= clkgen_pll_enable,
+	.disable	= clkgen_pll_disable,
+	.is_enabled	= clkgen_pll_is_enabled,
+	.recalc_rate	= recalc_stm_pll3200c32,
+	.round_rate	= round_rate_stm_pll3200c32,
+	.set_rate	= set_rate_stm_pll3200c32,
+};
+
 static const struct clk_ops st_pll1200c32_ops = {
 	.enable		= clkgen_pll_enable,
 	.disable	= clkgen_pll_disable,
@@ -483,7 +651,7 @@ static const struct clk_ops st_pll1200c32_ops = {
 static struct clk * __init clkgen_pll_register(const char *parent_name,
 				struct clkgen_pll_data	*pll_data,
 				void __iomem *reg,
-				const char *clk_name)
+				const char *clk_name, spinlock_t *lock)
 {
 	struct clkgen_pll *pll;
 	struct clk *clk;
@@ -590,7 +758,7 @@ static void __init clkgena_c65_pll_setup(struct device_node *np)
 	 */
 	clk_data->clks[0] = clkgen_pll_register(parent_name,
 			(struct clkgen_pll_data *) &st_pll1600c65_ax,
-			reg + CLKGENAx_PLL0_OFFSET, clk_name);
+			reg + CLKGENAx_PLL0_OFFSET, clk_name, NULL);
 
 	if (IS_ERR(clk_data->clks[0]))
 		goto err;
@@ -619,7 +787,7 @@ static void __init clkgena_c65_pll_setup(struct device_node *np)
 	 */
 	clk_data->clks[2] = clkgen_pll_register(parent_name,
 			(struct clkgen_pll_data *) &st_pll800c65_ax,
-			reg + CLKGENAx_PLL1_OFFSET, clk_name);
+			reg + CLKGENAx_PLL1_OFFSET, clk_name, NULL);
 
 	if (IS_ERR(clk_data->clks[2]))
 		goto err;
@@ -646,7 +814,7 @@ static struct clk * __init clkgen_odf_register(const char *parent_name,
 	struct clk_gate *gate;
 	struct clk_divider *div;
 
-	flags = CLK_GET_RATE_NOCACHE | CLK_SET_RATE_GATE;
+	flags = CLK_GET_RATE_NOCACHE | CLK_SET_RATE_PARENT;
 
 	gate = kzalloc(sizeof(*gate), GFP_KERNEL);
 	if (!gate)
@@ -754,7 +922,8 @@ static void __init clkgen_c32_pll_setup(struct device_node *np)
 	if (!pll_base)
 		return;
 
-	clk = clkgen_pll_register(parent_name, data, pll_base, np->name);
+	clk = clkgen_pll_register(parent_name, data, pll_base, np->name,
+				  data->lock);
 	if (IS_ERR(clk))
 		return;
 
@@ -843,7 +1012,7 @@ static void __init clkgengpu_c32_pll_setup(struct device_node *np)
 	/*
 	 * PLL 1200MHz output
 	 */
-	clk = clkgen_pll_register(parent_name, data, reg, clk_name);
+	clk = clkgen_pll_register(parent_name, data, reg, clk_name, data->lock);
 
 	if (!IS_ERR(clk))
 		of_clk_add_provider(np, of_clk_src_simple_get, clk);
diff --git a/drivers/clk/st/clkgen.h b/drivers/clk/st/clkgen.h
index 35c8632..f7ec2d9 100644
--- a/drivers/clk/st/clkgen.h
+++ b/drivers/clk/st/clkgen.h
@@ -9,6 +9,8 @@ Copyright (C) 2014 STMicroelectronics
 #ifndef __CLKGEN_INFO_H
 #define __CLKGEN_INFO_H
 
+extern spinlock_t clkgen_a9_lock;
+
 struct clkgen_field {
 	unsigned int offset;
 	unsigned int mask;
-- 
1.9.1



From gabriel.fernandez at linaro.org  Mon Aug 24 02:40:50 2015
From: gabriel.fernandez at linaro.org (Gabriel Fernandez)
Date: Mon, 24 Aug 2015 11:40:50 +0200
Subject: [PATCH v2 3/4] drivers: clk: st: Correct the pll-type for A9 for
 stih418
In-Reply-To: <1440409251-11166-1-git-send-email-gabriel.fernandez@linaro.org>
References: <1440409251-11166-1-git-send-email-gabriel.fernandez@linaro.org>
Message-ID: <1440409251-11166-4-git-send-email-gabriel.fernandez@linaro.org>

Add support for new PLL-type for stih418 A9-PLL.
Currently the 407_A9_PLL type being used, it is corrected with this patch
4600c28 PLL allows to reach higher frequencies
so its programming algorithm is extended.

Signed-off-by: Pankaj Dev <pankaj.dev at st.com>
Signed-off-by: Gabriel Fernandez <gabriel.fernandez at linaro.org>
---
 .../devicetree/bindings/clock/st/st,clkgen-pll.txt |   1 +
 drivers/clk/st/clkgen-pll.c                        | 194 +++++++++++++++++++++
 2 files changed, 195 insertions(+)

diff --git a/Documentation/devicetree/bindings/clock/st/st,clkgen-pll.txt b/Documentation/devicetree/bindings/clock/st/st,clkgen-pll.txt
index e2c6db0..8f84c81 100644
--- a/Documentation/devicetree/bindings/clock/st/st,clkgen-pll.txt
+++ b/Documentation/devicetree/bindings/clock/st/st,clkgen-pll.txt
@@ -23,6 +23,7 @@ Required properties:
 	"st,stih407-plls-c32-a9",	"st,clkgen-plls-c32"
 	"st,plls-c32-cx_0",		"st,clkgen-plls-c32"
 	"st,plls-c32-cx_1",		"st,clkgen-plls-c32"
+	"st,stih418-plls-c28-a9",	"st,clkgen-plls-c32"
 
 	"st,stih415-gpu-pll-c32",	"st,clkgengpu-pll-c32"
 	"st,stih416-gpu-pll-c32",	"st,clkgengpu-pll-c32"
diff --git a/drivers/clk/st/clkgen-pll.c b/drivers/clk/st/clkgen-pll.c
index 94e5a0b..3eb4ffb 100644
--- a/drivers/clk/st/clkgen-pll.c
+++ b/drivers/clk/st/clkgen-pll.c
@@ -44,6 +44,13 @@ DEFINE_SPINLOCK(clkgen_a9_lock);
 
 #define C32_MAX_ODFS (4)
 
+/*
+ * PLL configuration register bits for PLL4600 C28
+ */
+#define C28_NDIV_MASK (0xff)
+#define C28_IDF_MASK (0x7)
+#define C28_ODF_MASK (0x3f)
+
 struct clkgen_pll_data {
 	struct clkgen_field pdn_status;
 	struct clkgen_field pdn_ctrl;
@@ -68,6 +75,7 @@ static const struct clk_ops st_pll800c65_ops;
 static const struct clk_ops stm_pll3200c32_ops;
 static const struct clk_ops stm_pll3200c32_a9_ops;
 static const struct clk_ops st_pll1200c32_ops;
+static const struct clk_ops stm_pll4600c28_ops;
 
 static const struct clkgen_pll_data st_pll1600c65_ax = {
 	.pdn_status	= CLKGEN_FIELD(0x0, 0x1,			19),
@@ -256,6 +264,22 @@ static const struct clkgen_pll_data st_pll3200c32_407_a9 = {
 	.ops		= &stm_pll3200c32_a9_ops,
 };
 
+static struct clkgen_pll_data st_pll4600c28_418_a9 = {
+	/* 418 A9 */
+	.pdn_status	= CLKGEN_FIELD(0x1a8,	0x1,			0),
+	.pdn_ctrl	= CLKGEN_FIELD(0x1a8,	0x1,			0),
+	.locked_status	= CLKGEN_FIELD(0x87c,	0x1,			0),
+	.ndiv		= CLKGEN_FIELD(0x1b0,	C28_NDIV_MASK,		0),
+	.idf		= CLKGEN_FIELD(0x1a8,	C28_IDF_MASK,		25),
+	.num_odfs = 1,
+	.odf		= { CLKGEN_FIELD(0x1b0, C28_ODF_MASK,		8) },
+	.odf_gate	= { CLKGEN_FIELD(0x1ac, 0x1,			28) },
+	.switch2pll_en	= true,
+	.switch2pll	= CLKGEN_FIELD(0x1a4,	0x1,			1),
+	.lock		= &clkgen_a9_lock,
+	.ops		= &stm_pll4600c28_ops,
+};
+
 /**
  * DOC: Clock Generated by PLL, rate set and enabled by bootloader
  *
@@ -611,6 +635,163 @@ static unsigned long recalc_stm_pll1200c32(struct clk_hw *hw,
 	return rate;
 }
 
+/* PLL output structure
+ * FVCO >> /2 >> FVCOBY2 (no output)
+ *                 |> Divider (ODF) >> PHI
+ *
+ * FVCOby2 output = (input * 2 * NDIV) / IDF (assuming FRAC_CONTROL==L)
+ *
+ * Rules:
+ *   4Mhz <= INFF input <= 350Mhz
+ *   4Mhz <= INFIN (INFF / IDF) <= 50Mhz
+ *   19.05Mhz <= FVCOby2 output (PHI w ODF=1) <= 3000Mhz
+ *   1 <= i (register/dec value for IDF) <= 7
+ *   8 <= n (register/dec value for NDIV) <= 246
+ */
+
+static int clk_pll4600c28_get_params(unsigned long input, unsigned long output,
+			  struct stm_pll *pll)
+{
+
+	unsigned long i, infin, n;
+	unsigned long deviation = ~0;
+	unsigned long new_freq, new_deviation;
+
+	/* Output clock range: 19Mhz to 3000Mhz */
+	if (output < 19000000 || output > 3000000000u)
+		return -EINVAL;
+
+	/* For better jitter, IDF should be smallest and NDIV must be maximum */
+	for (i = 1; i <= 7 && deviation; i++) {
+		/* INFIN checks */
+		infin = input / i;
+		if (infin < 4000000 || infin > 50000000)
+			continue;	/* Invalid case */
+
+		n = output / (infin * 2);
+		if (n < 8 || n > 246)
+			continue;	/* Invalid case */
+		if (n < 246)
+			n++;	/* To work around 'y' when n=x.y */
+
+		for (; n >= 8 && deviation; n--) {
+			new_freq = infin * 2 * n;
+			if (new_freq < output)
+				break;	/* Optimization: shorting loop */
+
+			new_deviation = new_freq - output;
+			if (!new_deviation || new_deviation < deviation) {
+				pll->idf  = i;
+				pll->ndiv = n;
+				deviation = new_deviation;
+			}
+		}
+	}
+
+	if (deviation == ~0) /* No solution found */
+		return -EINVAL;
+
+	return 0;
+}
+
+static int clk_pll4600c28_get_rate(unsigned long input, struct stm_pll *pll,
+			unsigned long *rate)
+{
+	if (!pll->idf)
+		pll->idf = 1;
+
+	*rate = (input / pll->idf) * 2 * pll->ndiv;
+
+	return 0;
+}
+
+static unsigned long recalc_stm_pll4600c28(struct clk_hw *hw,
+				    unsigned long parent_rate)
+{
+	struct clkgen_pll *pll = to_clkgen_pll(hw);
+	struct stm_pll params;
+	unsigned long rate;
+
+	if (!clkgen_pll_is_enabled(hw) || !clkgen_pll_is_locked(hw))
+		return 0;
+
+	params.ndiv = CLKGEN_READ(pll, ndiv);
+	params.idf = CLKGEN_READ(pll, idf);
+
+	clk_pll4600c28_get_rate(parent_rate, &params, &rate);
+
+	pr_debug("%s:%s rate %lu\n", __clk_get_name(hw->clk), __func__, rate);
+
+	return rate;
+}
+
+static long round_rate_stm_pll4600c28(struct clk_hw *hw, unsigned long rate,
+				      unsigned long *prate)
+{
+	struct stm_pll params;
+
+	if (!clk_pll4600c28_get_params(*prate, rate, &params)) {
+		clk_pll4600c28_get_rate(*prate, &params, &rate);
+	} else {
+		pr_debug("%s: %s rate %ld Invalid\n", __func__,
+			 __clk_get_name(hw->clk), rate);
+		return 0;
+	}
+
+	pr_debug("%s: %s new rate %ld [ndiv=%u] [idf=%u]\n",
+		 __func__, __clk_get_name(hw->clk),
+		 rate, (unsigned int)params.ndiv,
+		 (unsigned int)params.idf);
+
+	return rate;
+}
+
+static int set_rate_stm_pll4600c28(struct clk_hw *hw, unsigned long rate,
+				   unsigned long parent_rate)
+{
+	struct clkgen_pll *pll = to_clkgen_pll(hw);
+	struct stm_pll params;
+	long hwrate;
+	unsigned long flags = 0;
+
+	if (!rate || !parent_rate)
+		return -EINVAL;
+
+	if (!clk_pll4600c28_get_params(parent_rate, rate, &params)) {
+		clk_pll4600c28_get_rate(parent_rate, &params, &hwrate);
+	} else {
+		pr_debug("%s: %s rate %ld Invalid\n", __func__,
+			 __clk_get_name(hw->clk), rate);
+		return -EINVAL;
+	}
+
+	pr_debug("%s: %s new rate %ld [ndiv=0x%x] [idf=0x%x]\n",
+		 __func__, __clk_get_name(hw->clk),
+		 hwrate, (unsigned int)params.ndiv,
+		 (unsigned int)params.idf);
+
+	if (!hwrate)
+		return -EINVAL;
+
+	pll->ndiv = params.ndiv;
+	pll->idf = params.idf;
+
+	clkgen_pll_disable(hw);
+
+	if (pll->lock)
+		spin_lock_irqsave(pll->lock, flags);
+
+	CLKGEN_WRITE(pll, ndiv, pll->ndiv);
+	CLKGEN_WRITE(pll, idf, pll->idf);
+
+	if (pll->lock)
+		spin_unlock_irqrestore(pll->lock, flags);
+
+	clkgen_pll_enable(hw);
+
+	return 0;
+}
+
 static const struct clk_ops st_pll1600c65_ops = {
 	.enable		= clkgen_pll_enable,
 	.disable	= clkgen_pll_disable,
@@ -648,6 +829,15 @@ static const struct clk_ops st_pll1200c32_ops = {
 	.recalc_rate	= recalc_stm_pll1200c32,
 };
 
+static const struct clk_ops stm_pll4600c28_ops = {
+	.enable		= clkgen_pll_enable,
+	.disable	= clkgen_pll_disable,
+	.is_enabled	= clkgen_pll_is_enabled,
+	.recalc_rate	= recalc_stm_pll4600c28,
+	.round_rate	= round_rate_stm_pll4600c28,
+	.set_rate	= set_rate_stm_pll4600c28,
+};
+
 static struct clk * __init clkgen_pll_register(const char *parent_name,
 				struct clkgen_pll_data	*pll_data,
 				void __iomem *reg,
@@ -893,6 +1083,10 @@ static const struct of_device_id c32_pll_of_match[] = {
 		.compatible = "st,stih407-plls-c32-a9",
 		.data = &st_pll3200c32_407_a9,
 	},
+	{
+		.compatible = "st,stih418-plls-c28-a9",
+		.data = &st_pll4600c28_418_a9,
+	},
 	{}
 };
 
-- 
1.9.1



From gabriel.fernandez at linaro.org  Mon Aug 24 02:40:51 2015
From: gabriel.fernandez at linaro.org (Gabriel Fernandez)
Date: Mon, 24 Aug 2015 11:40:51 +0200
Subject: [PATCH v2 4/4] ARM: STi: DT: Add support for stih418 A9 pll
In-Reply-To: <1440409251-11166-1-git-send-email-gabriel.fernandez@linaro.org>
References: <1440409251-11166-1-git-send-email-gabriel.fernandez@linaro.org>
Message-ID: <1440409251-11166-5-git-send-email-gabriel.fernandez@linaro.org>

Add support for new PLL-type for stih418 A9-PLL.

Signed-off-by: Gabriel Fernandez <gabriel.fernandez at linaro.org>
---
 arch/arm/boot/dts/stih418-clock.dtsi | 2 +-
 1 file changed, 1 insertion(+), 1 deletion(-)

diff --git a/arch/arm/boot/dts/stih418-clock.dtsi b/arch/arm/boot/dts/stih418-clock.dtsi
index 148e177..ae6d997 100644
--- a/arch/arm/boot/dts/stih418-clock.dtsi
+++ b/arch/arm/boot/dts/stih418-clock.dtsi
@@ -44,7 +44,7 @@
 
 			clockgen_a9_pll: clockgen-a9-pll {
 				#clock-cells = <1>;
-				compatible = "st,stih407-plls-c32-a9", "st,clkgen-plls-c32";
+				compatible = "st,stih418-plls-c28-a9", "st,clkgen-plls-c32";
 
 				clocks = <&clk_sysin>;
 
-- 
1.9.1



From alexandre.belloni at free-electrons.com  Mon Aug 24 02:45:02 2015
From: alexandre.belloni at free-electrons.com (Alexandre Belloni)
Date: Mon, 24 Aug 2015 11:45:02 +0200
Subject: [PATCH v3 2/2] drivers: rtc: add xilinx zynqmp rtc driver
In-Reply-To: <55DAE15B.6090602@xilinx.com>
References: <1439978002-12157-1-git-send-email-suneel.garapati@xilinx.com>
 <1439978002-12157-2-git-send-email-suneel.garapati@xilinx.com>
 <20150824074310.GF13155@piout.net> <55DACC5A.80707@xilinx.com>
 <20150824080800.GG13155@piout.net> <55DAE15B.6090602@xilinx.com>
Message-ID: <20150824094502.GI13155@piout.net>

On 24/08/2015 at 11:18:19 +0200, Michal Simek wrote :
> > I'm not fond of carrying patches with uncontactable authors. Is that a
> > permanent error?
> 
> Unfortunately. That guy left Xilinx last week but don't be scared that
> none will be responsible about this driver. I have well proven history
> on Linux and others project and I am here if you need to do some testing
> or ACK for changes. Just let me know when you need something.
> 
> get_maintainer returns me and Soren that's why you shouldn't have any
> problem with it.
> 
> [linux]$ ./scripts/get_maintainer.pl -f drivers/rtc/rtc-zynqmp.c
> Alessandro Zummo <a.zummo at towertech.it> (maintainer:REAL TIME CLOCK
> (RTC) SUBSYSTEM)
> Alexandre Belloni <alexandre.belloni at free-electrons.com>
> (maintainer:REAL TIME CLOCK (RTC) SUBSYSTEM)
> Michal Simek <michal.simek at xilinx.com> (supporter:ARM/ZYNQ ARCHITECTURE)
> "S?ren Brinkmann" <soren.brinkmann at xilinx.com> (reviewer)
> rtc-linux at googlegroups.com (open list:REAL TIME CLOCK (RTC) SUBSYSTEM)
> linux-arm-kernel at lists.infradead.org (moderated list:ARM/ZYNQ ARCHITECTURE)
> linux-kernel at vger.kernel.org (open list)
> 

Perfect, thanks!


-- 
Alexandre Belloni, Free Electrons
Embedded Linux, Kernel and Android engineering
http://free-electrons.com


From mark.rutland at arm.com  Mon Aug 24 02:51:45 2015
From: mark.rutland at arm.com (Mark Rutland)
Date: Mon, 24 Aug 2015 10:51:45 +0100
Subject: [PATCH v1 3/3] arm64: dts: add Hi6220 mailbox node
In-Reply-To: <20150824091845.GA28290@leoy-linaro>
References: <1439977055-1747-1-git-send-email-leo.yan@linaro.org>
 <1439977055-1747-4-git-send-email-leo.yan@linaro.org>
 <20150821184059.GB2000@svinekod>
 <20150824091845.GA28290@leoy-linaro>
Message-ID: <20150824095144.GA7139@leverpostej>

On Mon, Aug 24, 2015 at 10:18:45AM +0100, Leo Yan wrote:
> Hi Mark,
> 
> On Fri, Aug 21, 2015 at 07:40:59PM +0100, Mark Rutland wrote:
> > On Wed, Aug 19, 2015 at 10:37:35AM +0100, Leo Yan wrote:
> > > On Hi6220, below memory regions in DDR have specific purpose:
> > > 
> > >   0x05e0,0000 - 0x05ef,ffff: For MCU firmware using at runtime;
> > >   0x0740,f000 - 0x0740,ffff: For MCU firmware's section;
> > >   0x06df,f000 - 0x06df,ffff: For mailbox message data.
> > > 
> > > This patch reserves these memory regions and add device node for
> > > mailbox in dts.
> > > 
> > > Signed-off-by: Leo Yan <leo.yan at linaro.org>
> > > ---
> > >  arch/arm64/boot/dts/hisilicon/hi6220-hikey.dts | 20 +++++++++++++++++---
> > >  arch/arm64/boot/dts/hisilicon/hi6220.dtsi      |  8 ++++++++
> > >  2 files changed, 25 insertions(+), 3 deletions(-)
> > > 
> > > diff --git a/arch/arm64/boot/dts/hisilicon/hi6220-hikey.dts b/arch/arm64/boot/dts/hisilicon/hi6220-hikey.dts
> > > index e36a539..d5470d3 100644
> > > --- a/arch/arm64/boot/dts/hisilicon/hi6220-hikey.dts
> > > +++ b/arch/arm64/boot/dts/hisilicon/hi6220-hikey.dts
> > > @@ -7,9 +7,6 @@
> > >  
> > >  /dts-v1/;
> > >  
> > > -/*Reserved 1MB memory for MCU*/
> > > -/memreserve/ 0x05e00000 0x00100000;
> > > -
> > >  #include "hi6220.dtsi"
> > >  
> > >  / {
> > > @@ -28,4 +25,21 @@
> > >  		device_type = "memory";
> > >  		reg = <0x0 0x0 0x0 0x40000000>;
> > >  	};
> > > +
> > > +	reserved-memory {
> > > +		#address-cells = <2>;
> > > +		#size-cells = <2>;
> > > +		ranges;
> > > +
> > > +		mcu-buf at 05e00000 {
> > > +			no-map;
> > > +			reg = <0x0 0x05e00000 0x0 0x00100000>,	/* MCU firmware buffer */
> > > +			      <0x0 0x0740f000 0x0 0x00001000>;	/* MCU firmware section */
> > > +		};
> > > +
> > > +		mbox-buf at 06dff000 {
> > > +			no-map;
> > > +			reg = <0x0 0x06dff000 0x0 0x00001000>;	/* Mailbox message buf */
> > > +		};
> > > +	};
> > 
> > As far as I can see, it would be simpler to simply carve these out of the
> > memory node.
> > 
> > I don't see why you need reserved-memory here, given you're not referring to
> > these regions by phandle anyway.
> 
> - Now we have enabled EFI_STUB, so the memory node will be removed in
>   kernel:
>     efi_entry()
>       \-> allocate_new_fdt_and_exit_boot()
>             \-> update_fdt();
> 
>   Finally in kernel it cannot use memory node to carve out reseved
>   memory regions.
> 
> - On the other hand, DTS's the memory node is to "describes the
>   physical memory layout for the system"; so it's better to use it only
>   to describe the hardware info for memory. We can use reserved-memory
>   to help manage the memory regions which are reserved from software
>   perspective.

The fact that you have no-map means that the memory should not be
described to the kernel as mappable in the first place. It's wrong to
place such memory in the memory node, even if listed in reserved-memory.

If your EFI memory map describes the memory as mappable, it is wrong.

> According to upper info, we still need to use reserved-memory node to
> depict the reserved memory regions. i have no knowledge about EFI_STUB,
> so please confirm or correct as needed.

If the memory shouldn't be mapped, it should neither be in the memory
node nor EFI memory map (with attributes allowing it to be mapped) to
begin with.

As far as I can see you do not need to use reserved-memory.

Thanks,
Mark.


From maxime.coquelin at st.com  Mon Aug 24 02:52:59 2015
From: maxime.coquelin at st.com (Maxime Coquelin)
Date: Mon, 24 Aug 2015 11:52:59 +0200
Subject: [PATCH 1/1] ARM: DT: STi: STiH418: Fix mmc0 clock configuration
In-Reply-To: <1440409204-11108-1-git-send-email-gabriel.fernandez@linaro.org>
References: <1440409204-11108-1-git-send-email-gabriel.fernandez@linaro.org>
Message-ID: <55DAE97B.6090000@st.com>

Hi Gabriel,

On 08/24/2015 11:40 AM, Gabriel Fernandez wrote:
> This patch configure correctly the MMC-0 clock for STiH418 platform.
>
> Signed-off-by: Gabriel Fernandez <gabriel.fernandez at linaro.org>
> ---
>   arch/arm/boot/dts/stih418-b2199.dts | 4 ++++
>   1 file changed, 4 insertions(+)
>
> diff --git a/arch/arm/boot/dts/stih418-b2199.dts b/arch/arm/boot/dts/stih418-b2199.dts
> index 82eee39..7a03ca6 100644
> --- a/arch/arm/boot/dts/stih418-b2199.dts
> +++ b/arch/arm/boot/dts/stih418-b2199.dts
> @@ -85,6 +85,10 @@
>   			sd-uhs-sdr50;
>   			sd-uhs-sdr104;
>   			sd-uhs-ddr50;
> +
> +			assigned-clocks = <&clk_s_c0_flexgen CLK_MMC_0>;
> +			assigned-clock-parents = <&clk_s_c0_pll1 0>;
> +			assigned-clock-rates = <200000000>;

Thanks for the fix, but I would rather define the parent and rate in the 
SoC dtsi file, i.e. stih418.dtsi.
If you agree to change, you can add:
Acked-by: Maxime Coquelin <maxime.coquelin at st.com>

Thanks!
Maxime


From mark.rutland at arm.com  Mon Aug 24 03:00:54 2015
From: mark.rutland at arm.com (Mark Rutland)
Date: Mon, 24 Aug 2015 11:00:54 +0100
Subject: [PATCH v2 3/3] arm64: dts: add Hi6220 mailbox node
In-Reply-To: <1440039239-8772-4-git-send-email-leo.yan@linaro.org>
References: <1440039239-8772-1-git-send-email-leo.yan@linaro.org>
 <1440039239-8772-4-git-send-email-leo.yan@linaro.org>
Message-ID: <20150824100054.GB7139@leverpostej>

On Thu, Aug 20, 2015 at 03:53:59AM +0100, Leo Yan wrote:
> On Hi6220, below memory regions in DDR have specific purpose:
> 
>   0x05e0,0000 - 0x05ef,ffff: For MCU firmware using at runtime;
>   0x0740,f000 - 0x0740,ffff: For MCU firmware's section;
>   0x06df,f000 - 0x06df,ffff: For mailbox message data.
> 
> This patch reserves these memory regions and add device node for
> mailbox in dts.
> 
> Signed-off-by: Leo Yan <leo.yan at linaro.org>
> ---
>  arch/arm64/boot/dts/hisilicon/hi6220-hikey.dts | 20 +++++++++++++++++---
>  arch/arm64/boot/dts/hisilicon/hi6220.dtsi      |  8 ++++++++
>  2 files changed, 25 insertions(+), 3 deletions(-)
> 
> diff --git a/arch/arm64/boot/dts/hisilicon/hi6220-hikey.dts b/arch/arm64/boot/dts/hisilicon/hi6220-hikey.dts
> index e36a539..d5470d3 100644
> --- a/arch/arm64/boot/dts/hisilicon/hi6220-hikey.dts
> +++ b/arch/arm64/boot/dts/hisilicon/hi6220-hikey.dts
> @@ -7,9 +7,6 @@
>  
>  /dts-v1/;
>  
> -/*Reserved 1MB memory for MCU*/
> -/memreserve/ 0x05e00000 0x00100000;
> -
>  #include "hi6220.dtsi"
>  
>  / {
> @@ -28,4 +25,21 @@
>  		device_type = "memory";
>  		reg = <0x0 0x0 0x0 0x40000000>;
>  	};
> +
> +	reserved-memory {
> +		#address-cells = <2>;
> +		#size-cells = <2>;
> +		ranges;
> +
> +		mcu-buf at 05e00000 {
> +			no-map;
> +			reg = <0x0 0x05e00000 0x0 0x00100000>,	/* MCU firmware buffer */
> +			      <0x0 0x0740f000 0x0 0x00001000>;	/* MCU firmware section */
> +		};
> +
> +		mbox-buf at 06dff000 {
> +			no-map;
> +			reg = <0x0 0x06dff000 0x0 0x00001000>;	/* Mailbox message buf */
> +		};
> +	};
>  };

As mentioned in my other reply [1], you should fix your EFI memory map
instead. There is no reason for this at all.

Mark.

[1] http://lists.infradead.org/pipermail/linux-arm-kernel/2015-August/365921.html


From heiko at sntech.de  Mon Aug 24 03:01:19 2015
From: heiko at sntech.de (Heiko Stuebner)
Date: Mon, 24 Aug 2015 12:01:19 +0200
Subject: [RESEND PATCH] clk: rockchip: disable init state before mmc card
 initialization
In-Reply-To: <1440404863-14350-1-git-send-email-shawn.lin@rock-chips.com>
References: <1440404863-14350-1-git-send-email-shawn.lin@rock-chips.com>
Message-ID: <120036049.vlT25D4un8@phil>

Hi Shawn,

Am Montag, 24. August 2015, 16:27:43 schrieb Shawn Lin:
> mmc host controller's IO input/output timing is unpredictable if
> bootloader execute tuning for HS200 mode. It might make kernel failed
> to initialize mmc card in identification mode. The root cause is
> tuning phase and degree setting for HS200 mode in bootloader aren't
> applicable to that of identification mode in kernel stage. Anyway, we
> can't force all bootloaders to disable tuning phase and degree setting
> before into kernel. Simply disable it in rockchip_clk_register_mmc.
> 
> Signed-off-by: Shawn Lin <shawn.lin at rock-chips.com>
> 
> ---
> 
>  drivers/clk/rockchip/clk-mmc-phase.c | 20 ++++++++++++++++++++
>  1 file changed, 20 insertions(+)
> 
> diff --git a/drivers/clk/rockchip/clk-mmc-phase.c
> b/drivers/clk/rockchip/clk-mmc-phase.c index e9f8df32..ae21592 100644
> --- a/drivers/clk/rockchip/clk-mmc-phase.c
> +++ b/drivers/clk/rockchip/clk-mmc-phase.c
> @@ -38,6 +38,9 @@ static unsigned long rockchip_mmc_recalc(struct clk_hw
> *hw, #define ROCKCHIP_MMC_DEGREE_MASK 0x3
>  #define ROCKCHIP_MMC_DELAYNUM_OFFSET 2
>  #define ROCKCHIP_MMC_DELAYNUM_MASK (0xff << ROCKCHIP_MMC_DELAYNUM_OFFSET)
> +#define ROCKCHIP_MMC_INIT_STATE_DISABLE (0x1)
> +#define ROCKCHIP_MMC_INIT_STATE_SHIFT (1)
> +#define ROCKCHIP_MMC_INIT_STATE_MASK  (0x1)

you don't need the "()" around primitive values. Also I don't think you need 
the second MASK attribute, doing
	writel(HIWORD_UPDATE(ROCKCHIP_MMC_INIT_STATE_DISABLE,
				     ROCKCHIP_MMC_INIT_STATE_DISABLE,
				     mmc_clock->shift),

should be enough. And thirdly I'm undecided about the naming of the constant. 
The manual describes the init_state as "Assert init_state to soft reset the 
CLKGEN.", so I guess I'd prefer

	ROCKCHIP_MMC_INIT_STATE_RESET

or so

> 
>  #define PSECS_PER_SEC 1000000000000LL
> 
> @@ -119,6 +122,21 @@ static const struct clk_ops rockchip_mmc_clk_ops = {
>  	.set_phase	= rockchip_mmc_set_phase,
>  };
> 
> +static void rockchip_clk_mmc_disable_init(struct rockchip_mmc_clock

I guess similar to the thoughts above, simply name this
	rockchip_clk_mmc_reset()

or alternatively just do the reset in rockchip_clk_register_mmc directly:

if (mmc_clock->shift == ROCKCHIP_MMC_INIT_STATE_SHIFT))
	writel(HIWORD_UPDATE(ROCKCHIP_MMC_INIT_STATE_DISABLE,
				     ROCKCHIP_MMC_INIT_STATE_MASK,
			     mmc_clock->shift),
	       mmc_clock->reg);

as the pr_debug does not really serve a purpose.


Heiko

> *mmc_clock) +{
> +	if (mmc_clock->shift != ROCKCHIP_MMC_INIT_STATE_SHIFT)
> +		return;
> +
> +	writel(HIWORD_UPDATE(ROCKCHIP_MMC_INIT_STATE_DISABLE,
> +			     ROCKCHIP_MMC_INIT_STATE_MASK,
> +			     mmc_clock->shift),
> +	       mmc_clock->reg);
> +
> +	pr_debug("%s: clear mmc init state to %d", __func__,
> +		 (readl(mmc_clock->reg) >> (mmc_clock->shift)) &
> +		 ROCKCHIP_MMC_INIT_STATE_MASK);
> +}
> +
>  struct clk *rockchip_clk_register_mmc(const char *name,
>  				const char *const *parent_names, u8 num_parents,
>  				void __iomem *reg, int shift)
> @@ -139,6 +157,8 @@ struct clk *rockchip_clk_register_mmc(const char *name,
>  	mmc_clock->reg = reg;
>  	mmc_clock->shift = shift;
> 
> +	rockchip_clk_mmc_disable_init(mmc_clock);
> +
>  	if (name)
>  		init.name = name;



From will.deacon at arm.com  Mon Aug 24 03:04:28 2015
From: will.deacon at arm.com (Will Deacon)
Date: Mon, 24 Aug 2015 11:04:28 +0100
Subject: [PATCH v2 2/5] ACPI / ARM64: remove usage of
 BAD_MADT_ENTRY/BAD_MADT_GICC_ENTRY
In-Reply-To: <55D606E1.4040804@redhat.com>
References: <1440022048-6285-1-git-send-email-al.stone@linaro.org>
 <1440022048-6285-3-git-send-email-al.stone@linaro.org>
 <20150820101322.GA19328@arm.com> <55D606E1.4040804@redhat.com>
Message-ID: <20150824100428.GB11262@arm.com>

On Thu, Aug 20, 2015 at 05:57:05PM +0100, Al Stone wrote:
> On 08/20/2015 04:13 AM, Will Deacon wrote:
> > On Wed, Aug 19, 2015 at 11:07:25PM +0100, Al Stone wrote:
> >> Now that we have introduced the bad_madt_entry() function, and that
> >> function is being invoked in acpi_table_parse_madt() for us, there
> >> is no longer any need to use the BAD_MADT_ENTRY macro, or in the case
> >> of arm64, the BAD_MADT_GICC_ENTRY, too.
> >>
> >> Signed-off-by: Al Stone <al.stone at linaro.org>
> >> Acked-by: Catalin Marinas <catalin.marinas at arm.com>
> >> Acked-by: Marc Zyngier <marc.zyngier at arm.com>
> >> Cc: Will Deacon <will.deacon at arm.com>
> >> Cc: Thomas Gleixner <tglx at linutronix.de>
> >> Cc: Jason Cooper <jason at lakedaemon.net>
> >> ---
> >>  arch/arm64/include/asm/acpi.h | 8 --------
> >>  arch/arm64/kernel/smp.c       | 2 --
> >>  drivers/irqchip/irq-gic.c     | 6 ------
> >>  3 files changed, 16 deletions(-)
> > 
> > How are you planning to merge this (and which kernel are you targetting?)
> > You've got Acks for both arm64 and irqchip, so I guess either of those
> > trees could take it.
> 
> Yeah, this is a little messy.  If I can get into 4.2, that would be nice,
> but not required -- arm64 already has a usable patch for now, and that's
> the only arch affected.  So, 4.3 was my primary target (which is why I
> worked with linux-next for these).
> 
> Which tree?  Yeesh.  1/5 and 5/5 are ACPI only and required for the rest
> to work properly; 2/5 is arm64, 3/5 is ia64, and 4/5 is x86.  ARM folks are
> the only ones to have provided acks or reviews, however.  I guess I was
> assuming this would have to go in via Rafael's ACPI tree since those are
> the key parts -- the arch-specific patches would remove safety checks on
> MADT subtables without replacing them, if they went in before the ACPI
> patches.
> 
> Does that make sense?  What do you think?

Yup, taking it all via Rafael is fine by me. I just didn't want to end
up in a situation where you thought something was going via the arm64
tree but I hadn't queued it.

Will


From boris.brezillon at free-electrons.com  Mon Aug 24 03:10:31 2015
From: boris.brezillon at free-electrons.com (Boris Brezillon)
Date: Mon, 24 Aug 2015 12:10:31 +0200
Subject: [PATCH v2] mtd: nand: sunxi: rely on nand_dt_init initialization
Message-ID: <1440411031-8910-1-git-send-email-boris.brezillon@free-electrons.com>

nand_dt_init(), called from nand_scan_ident(), is already parsing the
generic MTD/NAND DT properties, and initializing the nand_chip struct
accordingly.
Rely on this initialization instead of manually parsing those properties.

Signed-off-by: Boris Brezillon <boris.brezillon at free-electrons.com>
---
Changes since v1:
- drop unused strength and blk_size variables
---
 drivers/mtd/nand/sunxi_nand.c | 20 +++++---------------
 1 file changed, 5 insertions(+), 15 deletions(-)

diff --git a/drivers/mtd/nand/sunxi_nand.c b/drivers/mtd/nand/sunxi_nand.c
index 96dda70..92a2c58 100644
--- a/drivers/mtd/nand/sunxi_nand.c
+++ b/drivers/mtd/nand/sunxi_nand.c
@@ -1164,16 +1164,9 @@ static int sunxi_nand_ecc_init(struct mtd_info *mtd, struct nand_ecc_ctrl *ecc,
 			       struct device_node *np)
 {
 	struct nand_chip *nand = mtd->priv;
-	int strength;
-	int blk_size;
 	int ret;
 
-	blk_size = of_get_nand_ecc_step_size(np);
-	strength = of_get_nand_ecc_strength(np);
-	if (blk_size > 0 && strength > 0) {
-		ecc->size = blk_size;
-		ecc->strength = strength;
-	} else {
+	if (!ecc->size) {
 		ecc->size = nand->ecc_step_ds;
 		ecc->strength = nand->ecc_strength_ds;
 	}
@@ -1183,10 +1176,6 @@ static int sunxi_nand_ecc_init(struct mtd_info *mtd, struct nand_ecc_ctrl *ecc,
 
 	ecc->mode = NAND_ECC_HW;
 
-	ret = of_get_nand_ecc_mode(np);
-	if (ret >= 0)
-		ecc->mode = ret;
-
 	switch (ecc->mode) {
 	case NAND_ECC_SOFT_BCH:
 		break;
@@ -1312,15 +1301,13 @@ static int sunxi_nand_chip_init(struct device *dev, struct sunxi_nfc *nfc,
 	/* Default tR value specified in the ONFI spec (chapter 4.15.1) */
 	nand->chip_delay = 200;
 	nand->controller = &nfc->controller;
+	nand->dn = np;
 	nand->select_chip = sunxi_nfc_select_chip;
 	nand->cmd_ctrl = sunxi_nfc_cmd_ctrl;
 	nand->read_buf = sunxi_nfc_read_buf;
 	nand->write_buf = sunxi_nfc_write_buf;
 	nand->read_byte = sunxi_nfc_read_byte;
 
-	if (of_get_nand_on_flash_bbt(np))
-		nand->bbt_options |= NAND_BBT_USE_FLASH | NAND_BBT_NO_OOB;
-
 	mtd = &chip->mtd;
 	mtd->dev.parent = dev;
 	mtd->priv = nand;
@@ -1330,6 +1317,9 @@ static int sunxi_nand_chip_init(struct device *dev, struct sunxi_nfc *nfc,
 	if (ret)
 		return ret;
 
+	if (nand->bbt_options & NAND_BBT_USE_FLASH)
+		nand->bbt_options |= NAND_BBT_NO_OOB;
+
 	ret = sunxi_nand_chip_init_timings(chip, np);
 	if (ret) {
 		dev_err(dev, "could not configure chip timings: %d\n", ret);
-- 
1.9.1



From cyrille.pitchen at atmel.com  Mon Aug 24 03:13:55 2015
From: cyrille.pitchen at atmel.com (Cyrille Pitchen)
Date: Mon, 24 Aug 2015 12:13:55 +0200
Subject: [PATCH linux-next v4 0/5] add driver for Atmel QSPI controller
Message-ID: <cover.1440410236.git.cyrille.pitchen@atmel.com>

ChangeLog

v4:
- add "OF && HAS_DMA" dependency in Kconfig for Atmel Quad SPI driver.
- return -ENOMEM instead of the return code of dma_mapping_error() as this
  function returns a boolean on ARM achitecture.
- add "Acked-by: Nicolas Ferre <nicolas.ferre at atmel.com>" for Atmel Quad
  SPI driver and its DT binding documentation.

v3:
- reword the comment which explains that spi_nor_set_protocol() is used by
  the spi-nor framework to notify lower layers, especially the (Q)SPI
  controller about a protocol change.
- change the definitions of register/bitfield macros in the Atmel QSPI
  controller driver: get rid of concatenation operator and use BIT and
  GENMASK macros when possible.
- use #define[SPACE] instead of #define[TAB]

v2:
- remove the patches to set the "latency code" of Spansion QSPI memories
  (support of Spansion memories may be submitted in later series).
- rename "qspi" node into "spi" in the DT example to fit ePAPR standard.
- remove the useless "qspi0" label from the DT node example.
- remove the leading 0 from the size of the second memory region to make
  it consistent with the size of the first memory region.
- indent the DT bindings documentation to make it more readable.
- remove the useless ".bus	= &platform_bus_type," line from the
  platform driver definition.

v1:

This series of patches add support for the new Atmel QSPI controller
embedded inside sama5d2x SoCs.

These patches were first developped for linux-3.18-at91 and tested on a
sama5d27 Xplained ultra board, which embeds a Micron n25q128a13 QSPI NOR
flash memory. Then the series was adapted for mainline.

Cyrille Pitchen (5):
  mtd: spi-nor: notify (Q)SPI controller about protocol change
  Documentation: mtd: add a DT property to set the number of dummy
    cycles
  mtd: spi-nor: allow to tune the number of dummy cycles
  Documentation: atmel-quadspi: add binding file for Atmel QSPI driver
  mtd: atmel-quadspi: add driver for Atmel QSPI controller

 .../devicetree/bindings/mtd/atmel-quadspi.txt      |  29 +
 .../devicetree/bindings/mtd/jedec,spi-nor.txt      |   6 +
 drivers/mtd/spi-nor/Kconfig                        |   7 +
 drivers/mtd/spi-nor/Makefile                       |   1 +
 drivers/mtd/spi-nor/atmel-quadspi.c                | 876 +++++++++++++++++++++
 drivers/mtd/spi-nor/spi-nor.c                      | 118 ++-
 include/linux/mtd/spi-nor.h                        |  15 +
 7 files changed, 1033 insertions(+), 19 deletions(-)
 create mode 100644 Documentation/devicetree/bindings/mtd/atmel-quadspi.txt
 create mode 100644 drivers/mtd/spi-nor/atmel-quadspi.c

-- 
1.8.2.2



From cyrille.pitchen at atmel.com  Mon Aug 24 03:13:56 2015
From: cyrille.pitchen at atmel.com (Cyrille Pitchen)
Date: Mon, 24 Aug 2015 12:13:56 +0200
Subject: [PATCH linux-next v4 1/5] mtd: spi-nor: notify (Q)SPI controller
 about protocol change
In-Reply-To: <cover.1440410236.git.cyrille.pitchen@atmel.com>
References: <cover.1440410236.git.cyrille.pitchen@atmel.com>
Message-ID: <9649a13a50c33ef38045342353fc487a914ae337.1440410236.git.cyrille.pitchen@atmel.com>

Once the Quad SPI mode has been enabled on a Micron flash memory, this
device expects ALL the following commands to use the SPI 4-4-4 protocol.
The (Q)SPI controller needs to be notified about the protocol change so it
can adapt and keep on dialoging with the Micron memory.

Signed-off-by: Cyrille Pitchen <cyrille.pitchen at atmel.com>
---
 drivers/mtd/spi-nor/spi-nor.c | 21 +++++++++++++++++++++
 include/linux/mtd/spi-nor.h   | 13 +++++++++++++
 2 files changed, 34 insertions(+)

diff --git a/drivers/mtd/spi-nor/spi-nor.c b/drivers/mtd/spi-nor/spi-nor.c
index 47df4b5eae2f..e2a6029dc056 100644
--- a/drivers/mtd/spi-nor/spi-nor.c
+++ b/drivers/mtd/spi-nor/spi-nor.c
@@ -163,6 +163,22 @@ static inline int write_disable(struct spi_nor *nor)
 	return nor->write_reg(nor, SPINOR_OP_WRDI, NULL, 0, 0);
 }
 
+/*
+ * Let the spi-nor framework notify lower layers, especially the driver of the
+ * (Q)SPI controller, about the new protocol to be used. Indeed, once the
+ * spi-nor framework has sent manufacturer specific commands to a memory to
+ * enable its Quad SPI mode, it should immediately after tell the QSPI
+ * controller to use the very same Quad SPI protocol as expected by the memory.
+ */
+static inline int spi_nor_set_protocol(struct spi_nor *nor,
+				       enum spi_protocol proto)
+{
+	if (nor->set_protocol)
+		return nor->set_protocol(nor, proto);
+
+	return 0;
+}
+
 static inline struct spi_nor *mtd_to_spi_nor(struct mtd_info *mtd)
 {
 	return mtd->priv;
@@ -944,6 +960,11 @@ static int micron_quad_enable(struct spi_nor *nor)
 		return ret;
 	}
 
+	/* switch protocol to Quad CMD 4-4-4 */
+	ret = spi_nor_set_protocol(nor, SPI_PROTO_4_4_4);
+	if (ret)
+		return ret;
+
 	ret = spi_nor_wait_till_ready(nor);
 	if (ret)
 		return ret;
diff --git a/include/linux/mtd/spi-nor.h b/include/linux/mtd/spi-nor.h
index e5409524bb0a..1bf6f11310ef 100644
--- a/include/linux/mtd/spi-nor.h
+++ b/include/linux/mtd/spi-nor.h
@@ -87,6 +87,16 @@ enum read_mode {
 	SPI_NOR_QUAD,
 };
 
+enum spi_protocol {
+	SPI_PROTO_1_1_1,	/* SPI */
+	SPI_PROTO_1_1_2,	/* Dual Output */
+	SPI_PROTO_1_1_4,	/* Quad Output */
+	SPI_PROTO_1_2_2,	/* Dual IO */
+	SPI_PROTO_1_4_4,	/* Quad IO */
+	SPI_PROTO_2_2_2,	/* Dual Command */
+	SPI_PROTO_4_4_4,	/* Quad Command */
+};
+
 /**
  * struct spi_nor_xfer_cfg - Structure for defining a Serial Flash transfer
  * @wren:		command for "Write Enable", or 0x00 for not required
@@ -149,6 +159,7 @@ enum spi_nor_option_flags {
  *			read/write/erase/lock/unlock operations
  * @read_xfer:		[OPTIONAL] the read fundamental primitive
  * @write_xfer:		[OPTIONAL] the writefundamental primitive
+ * @set_protocol:	[OPTIONAL] notify about protocol change
  * @read_reg:		[DRIVER-SPECIFIC] read out the register
  * @write_reg:		[DRIVER-SPECIFIC] write data to the register
  * @read:		[DRIVER-SPECIFIC] read data from the SPI NOR
@@ -185,6 +196,8 @@ struct spi_nor {
 	int (*write_reg)(struct spi_nor *nor, u8 opcode, u8 *buf, int len,
 			int write_enable);
 
+	int (*set_protocol)(struct spi_nor *nor, enum spi_protocol proto);
+
 	int (*read)(struct spi_nor *nor, loff_t from,
 			size_t len, size_t *retlen, u_char *read_buf);
 	void (*write)(struct spi_nor *nor, loff_t to,
-- 
1.8.2.2



From cyrille.pitchen at atmel.com  Mon Aug 24 03:13:57 2015
From: cyrille.pitchen at atmel.com (Cyrille Pitchen)
Date: Mon, 24 Aug 2015 12:13:57 +0200
Subject: [PATCH linux-next v4 2/5] Documentation: mtd: add a DT property to
 set the number of dummy cycles
In-Reply-To: <cover.1440410236.git.cyrille.pitchen@atmel.com>
References: <cover.1440410236.git.cyrille.pitchen@atmel.com>
Message-ID: <22db2e7d5126fc182eb7e26ada9de390165cb2fc.1440410236.git.cyrille.pitchen@atmel.com>

Depending on the SPI clock frequency, the Fast Read op code and the
Single/Dual Data Rate mode, the number of dummy cycles can be tuned to
improve transfer speed.
The actual number of dummy cycles is specific for each memory model and is
provided by the manufacturer thanks to the memory datasheet.

Signed-off-by: Cyrille Pitchen <cyrille.pitchen at atmel.com>
---
 Documentation/devicetree/bindings/mtd/jedec,spi-nor.txt | 6 ++++++
 1 file changed, 6 insertions(+)

diff --git a/Documentation/devicetree/bindings/mtd/jedec,spi-nor.txt b/Documentation/devicetree/bindings/mtd/jedec,spi-nor.txt
index 2bee68103b01..4387567d8024 100644
--- a/Documentation/devicetree/bindings/mtd/jedec,spi-nor.txt
+++ b/Documentation/devicetree/bindings/mtd/jedec,spi-nor.txt
@@ -19,6 +19,11 @@ Optional properties:
                    all chips and support for it can not be detected at runtime.
                    Refer to your chips' datasheet to check if this is supported
                    by your chip.
+- m25p,num-dummy-cycles : Set the number of dummy cycles for Fast Read commands.
+                          Depending on the manufacturer additional dedicated
+                          commands are sent to the flash memory so the
+                          controller and the memory can agree on the number of
+                          dummy cycles to use.
 
 Example:
 
@@ -29,4 +34,5 @@ Example:
 		reg = <0>;
 		spi-max-frequency = <40000000>;
 		m25p,fast-read;
+		m25p,num-dummy-cycles = <8>;
 	};
-- 
1.8.2.2



From cyrille.pitchen at atmel.com  Mon Aug 24 03:13:58 2015
From: cyrille.pitchen at atmel.com (Cyrille Pitchen)
Date: Mon, 24 Aug 2015 12:13:58 +0200
Subject: [PATCH linux-next v4 3/5] mtd: spi-nor: allow to tune the number of
 dummy cycles
In-Reply-To: <cover.1440410236.git.cyrille.pitchen@atmel.com>
References: <cover.1440410236.git.cyrille.pitchen@atmel.com>
Message-ID: <b0d8470fdd46e89ef692e27dc2600b880c1d5dde.1440410236.git.cyrille.pitchen@atmel.com>

The number of dummy cycles used during Fast Read commands can be reduced
to improve transfer performances. Each manufacturer has a dedicated set of
registers to provide the memory with the exact number of dummy cycles it
should expect. Both the memory and the (Q)SPI controller must agree on
this number of dummy cycles.

The number of dummy cycles can be found into the memory datasheet and
mostly depends on the SPI clock frequency, the Fast Read op code and the
Single/Dual Data Rate mode.

Probing JEDEC Serial Flash Discoverable Parameters (SFDP) tables would
only provide the driver with a high enough number of dummy cycles for each
Fast Read command to be used for all clock frequencies: this solution
would not be optimized.

Signed-off-by: Cyrille Pitchen <cyrille.pitchen at atmel.com>
---
 drivers/mtd/spi-nor/spi-nor.c | 97 ++++++++++++++++++++++++++++++++++---------
 include/linux/mtd/spi-nor.h   |  2 +
 2 files changed, 80 insertions(+), 19 deletions(-)

diff --git a/drivers/mtd/spi-nor/spi-nor.c b/drivers/mtd/spi-nor/spi-nor.c
index e2a6029dc056..869e098a6841 100644
--- a/drivers/mtd/spi-nor/spi-nor.c
+++ b/drivers/mtd/spi-nor/spi-nor.c
@@ -119,24 +119,6 @@ static int read_cr(struct spi_nor *nor)
 }
 
 /*
- * Dummy Cycle calculation for different type of read.
- * It can be used to support more commands with
- * different dummy cycle requirements.
- */
-static inline int spi_nor_read_dummy_cycles(struct spi_nor *nor)
-{
-	switch (nor->flash_read) {
-	case SPI_NOR_FAST:
-	case SPI_NOR_DUAL:
-	case SPI_NOR_QUAD:
-		return 8;
-	case SPI_NOR_NORMAL:
-		return 0;
-	}
-	return 0;
-}
-
-/*
  * Write status register 1 byte
  * Returns negative if error occurred.
  */
@@ -1012,6 +994,81 @@ static int set_quad_mode(struct spi_nor *nor, struct flash_info *info)
 	}
 }
 
+static int micron_set_dummy_cycles(struct spi_nor *nor)
+{
+	int ret;
+	u8 val, mask;
+
+	/* read the Volatile Configuration Register (VCR) */
+	ret = nor->read_reg(nor, SPINOR_OP_RD_VCR, &val, 1);
+	if (ret < 0) {
+		dev_err(nor->dev, "error %d reading VCR\n", ret);
+		return ret;
+	}
+
+	write_enable(nor);
+
+	/* update the number of dummy into the VCR */
+	mask = GENMASK(7, 4);
+	val &= ~mask;
+	val |= (nor->read_dummy << 4) & mask;
+	ret = nor->write_reg(nor, SPINOR_OP_WR_VCR, &val, 1, 0);
+	if (ret < 0) {
+		dev_err(nor->dev, "error while writing VCR register\n");
+		return ret;
+	}
+
+	ret = spi_nor_wait_till_ready(nor);
+	if (ret)
+		return ret;
+
+	return 0;
+}
+
+/*
+ * Dummy Cycle calculation for different type of read.
+ * It can be used to support more commands with
+ * different dummy cycle requirements.
+ */
+static int spi_nor_read_dummy_cycles(struct spi_nor *nor,
+				     const struct flash_info *info)
+{
+	struct device_node *np = nor->dev->of_node;
+	u32 num_dummy_cycles;
+
+	if (np && !of_property_read_u32(np, "m25p,num-dummy-cycles",
+					&num_dummy_cycles)) {
+		nor->read_dummy = num_dummy_cycles;
+
+		/*
+		 * This switch block might be moved after the if...then...else
+		 * statement but it was not tested with all Spansion or Micron
+		 * memories.
+		 * Now the "m25p,num-dummy-cycles" property needs to be
+		 * explicitly set in the device tree so the switch statement is
+		 * executed. This should avoid unwanted side effects and keep
+		 * backward compatibility.
+		 */
+		switch (JEDEC_MFR(info)) {
+		case CFI_MFR_ST:
+			return micron_set_dummy_cycles(nor);
+		default:
+			break;
+		}
+	} else {
+		switch (nor->flash_read) {
+		case SPI_NOR_FAST:
+		case SPI_NOR_DUAL:
+		case SPI_NOR_QUAD:
+			nor->read_dummy = 8;
+		case SPI_NOR_NORMAL:
+			nor->read_dummy = 0;
+		}
+	}
+
+	return 0;
+}
+
 static int spi_nor_check(struct spi_nor *nor)
 {
 	if (!nor->dev || !nor->read || !nor->write ||
@@ -1216,7 +1273,9 @@ int spi_nor_scan(struct spi_nor *nor, const char *name, enum read_mode mode)
 		nor->addr_width = 3;
 	}
 
-	nor->read_dummy = spi_nor_read_dummy_cycles(nor);
+	ret = spi_nor_read_dummy_cycles(nor, info);
+	if (ret)
+		return ret;
 
 	dev_info(dev, "%s (%lld Kbytes)\n", id->name,
 			(long long)mtd->size >> 10);
diff --git a/include/linux/mtd/spi-nor.h b/include/linux/mtd/spi-nor.h
index 1bf6f11310ef..e03a4c4053d3 100644
--- a/include/linux/mtd/spi-nor.h
+++ b/include/linux/mtd/spi-nor.h
@@ -59,6 +59,8 @@
 /* Used for Micron flashes only. */
 #define SPINOR_OP_RD_EVCR      0x65    /* Read EVCR register */
 #define SPINOR_OP_WD_EVCR      0x61    /* Write EVCR register */
+#define SPINOR_OP_RD_VCR	0x85	/* Read VCR register */
+#define SPINOR_OP_WR_VCR	0x81	/* Write VCR register */
 
 /* Status Register bits. */
 #define SR_WIP			1	/* Write in progress */
-- 
1.8.2.2



From cyrille.pitchen at atmel.com  Mon Aug 24 03:13:59 2015
From: cyrille.pitchen at atmel.com (Cyrille Pitchen)
Date: Mon, 24 Aug 2015 12:13:59 +0200
Subject: [PATCH linux-next v4 4/5] Documentation: atmel-quadspi: add binding
 file for Atmel QSPI driver
In-Reply-To: <cover.1440410236.git.cyrille.pitchen@atmel.com>
References: <cover.1440410236.git.cyrille.pitchen@atmel.com>
Message-ID: <d45c21eab00863f379a0388b439a6ae5c44f7acc.1440410236.git.cyrille.pitchen@atmel.com>

This patch documents the DT bindings for the driver of the Atmel QSPI
controller embedded inside sama5d2x SoCs.

Signed-off-by: Cyrille Pitchen <cyrille.pitchen at atmel.com>
Acked-by: Nicolas Ferre <nicolas.ferre at atmel.com>
---
 .../devicetree/bindings/mtd/atmel-quadspi.txt      | 29 ++++++++++++++++++++++
 1 file changed, 29 insertions(+)
 create mode 100644 Documentation/devicetree/bindings/mtd/atmel-quadspi.txt

diff --git a/Documentation/devicetree/bindings/mtd/atmel-quadspi.txt b/Documentation/devicetree/bindings/mtd/atmel-quadspi.txt
new file mode 100644
index 000000000000..0b8d545bb198
--- /dev/null
+++ b/Documentation/devicetree/bindings/mtd/atmel-quadspi.txt
@@ -0,0 +1,29 @@
+* Atmel Quad Serial Peripheral Interface (QSPI)
+
+Required properties:
+- compatible:     should be "atmel,sama5d2-qspi"
+- reg:            the first contains the register location and length,
+                  the second contains the memory mapping address and length
+- interrupts:     should contain the interrupt for the device
+- clocks:         the phandle of the clock needed by the QSPI controller
+- #address-cells: should be <1>
+- #size-cells:    should be <0>
+
+Example:
+
+spi at f0020000 {
+	compatible = "atmel,sama5d2-qspi";
+	reg = <0xf0020000 0x100>,
+	      <0xd0000000 0x8000000>;
+	interrupts = <52 IRQ_TYPE_LEVEL_HIGH 7>;
+	clocks = <&spi0_clk>;
+	#address-cells = <1>;
+	#size-cells = <0>;
+	pinctrl-names = "default";
+	pinctrl-0 = <&pinctrl_spi0_default>;
+	status = "okay";
+
+	m25p80 at 0 {
+		...
+	};
+};
-- 
1.8.2.2



From cyrille.pitchen at atmel.com  Mon Aug 24 03:14:00 2015
From: cyrille.pitchen at atmel.com (Cyrille Pitchen)
Date: Mon, 24 Aug 2015 12:14:00 +0200
Subject: [PATCH linux-next v4 5/5] mtd: atmel-quadspi: add driver for Atmel
 QSPI controller
In-Reply-To: <cover.1440410236.git.cyrille.pitchen@atmel.com>
References: <cover.1440410236.git.cyrille.pitchen@atmel.com>
Message-ID: <bf368fc101f38db231131b69eff0863210f2b01c.1440410236.git.cyrille.pitchen@atmel.com>

This driver add support to the new Atmel QSPI controller embedded into
sama5d2x SoCs. It expects a NOR memory to be connected to the QSPI
controller.

Signed-off-by: Cyrille Pitchen <cyrille.pitchen at atmel.com>
Acked-by: Nicolas Ferre <nicolas.ferre at atmel.com>
---
 drivers/mtd/spi-nor/Kconfig         |   7 +
 drivers/mtd/spi-nor/Makefile        |   1 +
 drivers/mtd/spi-nor/atmel-quadspi.c | 876 ++++++++++++++++++++++++++++++++++++
 3 files changed, 884 insertions(+)
 create mode 100644 drivers/mtd/spi-nor/atmel-quadspi.c

diff --git a/drivers/mtd/spi-nor/Kconfig b/drivers/mtd/spi-nor/Kconfig
index 89bf4c1faa2b..7a3d55429550 100644
--- a/drivers/mtd/spi-nor/Kconfig
+++ b/drivers/mtd/spi-nor/Kconfig
@@ -29,6 +29,13 @@ config SPI_FSL_QUADSPI
 	  This controller does not support generic SPI. It only supports
 	  SPI NOR.
 
+config SPI_ATMEL_QUADSPI
+	tristate "Atmel Quad SPI Controller"
+	depends on OF && HAS_DMA && (ARCH_AT91 || COMPILE_TEST)
+	help
+	  This enables support for the Quad SPI controller in master mode.
+	  We only connect the NOR to this controller now.
+
 config SPI_NXP_SPIFI
 	tristate "NXP SPI Flash Interface (SPIFI)"
 	depends on OF && (ARCH_LPC18XX || COMPILE_TEST)
diff --git a/drivers/mtd/spi-nor/Makefile b/drivers/mtd/spi-nor/Makefile
index e53333ef8582..f5d23d7379bb 100644
--- a/drivers/mtd/spi-nor/Makefile
+++ b/drivers/mtd/spi-nor/Makefile
@@ -1,3 +1,4 @@
 obj-$(CONFIG_MTD_SPI_NOR)	+= spi-nor.o
 obj-$(CONFIG_SPI_FSL_QUADSPI)	+= fsl-quadspi.o
+obj-$(CONFIG_SPI_ATMEL_QUADSPI)	+= atmel-quadspi.o
 obj-$(CONFIG_SPI_NXP_SPIFI)	+= nxp-spifi.o
diff --git a/drivers/mtd/spi-nor/atmel-quadspi.c b/drivers/mtd/spi-nor/atmel-quadspi.c
new file mode 100644
index 000000000000..ada6f95782e4
--- /dev/null
+++ b/drivers/mtd/spi-nor/atmel-quadspi.c
@@ -0,0 +1,876 @@
+/*
+ * Driver for Atmel QSPI Controller
+ *
+ * Copyright (C) 2015 Atmel Corporation
+ *
+ * Author: Cyrille Pitchen <cyrille.pitchen at atmel.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.
+ *
+ * You should have received a copy of the GNU General Public License along with
+ * this program.  If not, see <http://www.gnu.org/licenses/>.
+ *
+ * This driver is based on drivers/mtd/spi-nor/fsl-quadspi.c from Freescale.
+ */
+
+#include <linux/kernel.h>
+#include <linux/clk.h>
+#include <linux/module.h>
+#include <linux/platform_device.h>
+#include <linux/delay.h>
+#include <linux/dma-mapping.h>
+#include <linux/dmaengine.h>
+#include <linux/err.h>
+#include <linux/interrupt.h>
+#include <linux/mtd/mtd.h>
+#include <linux/mtd/partitions.h>
+#include <linux/mtd/spi-nor.h>
+#include <linux/platform_data/atmel.h>
+#include <linux/platform_data/dma-atmel.h>
+#include <linux/of.h>
+
+#include <linux/io.h>
+#include <linux/gpio.h>
+#include <linux/pinctrl/consumer.h>
+
+/* QSPI register offsets */
+#define QSPI_CR      0x0000  /* Control Register */
+#define QSPI_MR      0x0004  /* Mode Register */
+#define QSPI_RD      0x0008  /* Receive Data Register */
+#define QSPI_TD      0x000c  /* Transmit Data Register */
+#define QSPI_SR      0x0010  /* Status Register */
+#define QSPI_IER     0x0014  /* Interrupt Enable Register */
+#define QSPI_IDR     0x0018  /* Interrupt Disable Register */
+#define QSPI_IMR     0x001c  /* Interrupt Mask Register */
+#define QSPI_SCR     0x0020  /* Serial Clock Register */
+
+#define QSPI_IAR     0x0030  /* Instruction Address Register */
+#define QSPI_ICR     0x0034  /* Instruction Code Register */
+#define QSPI_IFR     0x0038  /* Instruction Frame Register */
+
+#define QSPI_SMR     0x0040  /* Scrambling Mode Register */
+#define QSPI_SKR     0x0044  /* Scrambling Key Register */
+
+#define QSPI_WPMR    0x00E4  /* Write Protection Mode Register */
+#define QSPI_WPSR    0x00E8  /* Write Protection Status Register */
+
+#define QSPI_VERSION 0x00FC  /* Version Register */
+
+
+/* Bitfields in QSPI_CR (Control Register) */
+#define QSPI_CR_QSPIEN                  BIT(0)
+#define QSPI_CR_QSPIDIS                 BIT(1)
+#define QSPI_CR_SWRST                   BIT(7)
+#define QSPI_CR_LASTXFER                BIT(24)
+
+/* Bitfields in QSPI_MR (Mode Register) */
+#define QSPI_MR_SSM                     BIT(0)
+#define QSPI_MR_LLB                     BIT(1)
+#define QSPI_MR_WDRBT                   BIT(2)
+#define QSPI_MR_SMRM                    BIT(3)
+#define QSPI_MR_CSMODE_MASK             GENMASK(5, 4)
+#define QSPI_MR_CSMODE_NOT_RELOADED     (0 << 4)
+#define QSPI_MR_CSMODE_LASTXFER         (1 << 4)
+#define QSPI_MR_CSMODE_SYSTEMATICALLY   (2 << 4)
+#define QSPI_MR_NBBITS_MASK             GENMASK(11, 8)
+#define QSPI_MR_NBBITS(n)               ((((n) - 8) << 8) & QSPI_MR_NBBITS_MASK)
+#define QSPI_MR_DLYBCT_MASK             GENMASK(23, 16)
+#define QSPI_MR_DLYBCT(n)               (((n) << 16) & QSPI_MR_DLYBCT_MASK)
+#define QSPI_MR_DLYCS_MASK              GENMASK(31, 24)
+#define QSPI_MR_DLYCS(n)                (((n) << 24) & QSPI_MR_DLYCS_MASK)
+
+/* Bitfields in QSPI_SR/QSPI_IER/QSPI_IDR/QSPI_IMR  */
+#define QSPI_SR_RDRF                    BIT(0)
+#define QSPI_SR_TDRE                    BIT(1)
+#define QSPI_SR_TXEMPTY                 BIT(2)
+#define QSPI_SR_OVRES                   BIT(3)
+#define QSPI_SR_CSR                     BIT(8)
+#define QSPI_SR_CSS                     BIT(9)
+#define QSPI_SR_INSTRE                  BIT(10)
+#define QSPI_SR_QSPIENS                 BIT(24)
+
+/* Bitfields in QSPI_SCR (Serial Clock Register) */
+#define QSPI_SCR_CPOL                   BIT(0)
+#define QSPI_SCR_CPHA                   BIT(1)
+#define QSPI_SCR_SCBR_MASK              GENMASK(15, 8)
+#define QSPI_SCR_SCBR(n)                (((n) << 8) & QSPI_SCR_SCBR_MASK)
+#define QSPI_SCR_DLYBS_MASK             GENMASK(23, 16)
+#define QSPI_SCR_DLYBS(n)               (((n) << 16) & QSPI_SCR_DLYBS_MASK)
+
+/* Bitfields in QSPI_ICR (Instruction Code Register) */
+#define QSPI_ICR_INST_MASK              GENMASK(7, 0)
+#define QSPI_ICR_INST(inst)             (((inst) << 0) & QSPI_ICR_INST_MASK)
+#define QSPI_ICR_OPT_MASK               GENMASK(23, 16)
+#define QSPI_ICR_OPT(opt)               (((opt) << 16) & QSPI_ICR_OPT_MASK)
+
+/* Bitfields in QSPI_IFR (Instruction Frame Register) */
+#define QSPI_IFR_WIDTH_MASK             GENMASK(2, 0)
+#define QSPI_IFR_WIDTH_SINGLE_BIT_SPI   (0 << 0)
+#define QSPI_IFR_WIDTH_DUAL_OUTPUT      (1 << 0)
+#define QSPI_IFR_WIDTH_QUAD_OUTPUT      (2 << 0)
+#define QSPI_IFR_WIDTH_DUAL_IO          (3 << 0)
+#define QSPI_IFR_WIDTH_QUAD_IO          (4 << 0)
+#define QSPI_IFR_WIDTH_DUAL_CMD         (5 << 0)
+#define QSPI_IFR_WIDTH_QUAD_CMD         (6 << 0)
+#define QSPI_IFR_INSTEN                 BIT(4)
+#define QSPI_IFR_ADDREN                 BIT(5)
+#define QSPI_IFR_OPTEN                  BIT(6)
+#define QSPI_IFR_DATAEN                 BIT(7)
+#define QSPI_IFR_OPTL_MASK              GENMASK(9, 8)
+#define QSPI_IFR_OPTL_1BIT              (0 << 8)
+#define QSPI_IFR_OPTL_2BIT              (1 << 8)
+#define QSPI_IFR_OPTL_4BIT              (2 << 8)
+#define QSPI_IFR_OPTL_8BIT              (3 << 8)
+#define QSPI_IFR_ADDRL                  BIT(10)
+#define QSPI_IFR_TFRTYP_MASK            GENMASK(13, 12)
+#define QSPI_IFR_TFRTYP_TRSFR_READ      (0 << 12)
+#define QSPI_IFR_TFRTYP_TRSFR_READ_MEM  (1 << 12)
+#define QSPI_IFR_TFRTYP_TRSFR_WRITE     (2 << 12)
+#define QSPI_IFR_TFRTYP_TRSFR_WRITE_MEM (3 << 13)
+#define QSPI_IFR_CRM                    BIT(14)
+#define QSPI_IFR_NBDUM_MASK             GENMASK(20, 16)
+#define QSPI_IFR_NBDUM(n)               (((n) << 16) & QSPI_IFR_NBDUM_MASK)
+
+/* Bitfields in QSPI_SMR (Scrambling Mode Register) */
+#define QSPI_SMR_SCREN                  BIT(0)
+#define QSPI_SMR_RVDIS                  BIT(1)
+
+/* Bitfields in QSPI_WPMR (Write Protection Mode Register) */
+#define QSPI_WPMR_WPEN                  BIT(0)
+#define QSPI_WPMR_WPKEY_MASK            GENMASK(31, 8)
+#define QSPI_WPMR_WPKEY(wpkey)          (((wpkey) << 8) & QSPI_WPMR_WPKEY_MASK)
+
+/* Bitfields in QSPI_WPSR (Write Protection Status Register) */
+#define QSPI_WPSR_WPVS                  BIT(0)
+#define QSPI_WPSR_WPVSRC_MASK           GENMASK(15, 8)
+#define QSPI_WPSR_WPVSRC(src)           (((src) << 8) & QSPI_WPSR_WPVSRC)
+
+
+struct atmel_qspi {
+	void __iomem		*regs;
+	void __iomem		*mem;
+	dma_addr_t		phys_addr;
+	struct dma_chan		*chan;
+	struct clk		*clk;
+	struct platform_device	*pdev;
+	u32			ifr_width;
+	u32			pending;
+
+	struct mtd_info		mtd;
+	struct spi_nor		nor;
+	u32			clk_rate;
+	struct completion	completion;
+
+#ifdef DEBUG
+	u8			last_instruction;
+#endif
+};
+
+struct atmel_qspi_command {
+	u32	ifr_tfrtyp;
+	union {
+		struct {
+			u32	instruction:1;
+			u32	address:3;
+			u32	mode:1;
+			u32	dummy:1;
+			u32	data:1;
+			u32	dma:1;
+			u32	reserved:24;
+		}		bits;
+		u32	word;
+	}	enable;
+	u8	instruction;
+	u8	mode;
+	u8	num_mode_cycles;
+	u8	num_dummy_cycles;
+	u32	address;
+
+	size_t		buf_len;
+	const void	*tx_buf;
+	void		*rx_buf;
+};
+
+/* Register access macros */
+static inline u32 qspi_readl(struct atmel_qspi *aq, u32 reg)
+{
+	return readl_relaxed(aq->regs + reg);
+}
+
+static inline void qspi_writel(struct atmel_qspi *aq, u32 reg, u32 value)
+{
+	writel_relaxed(value, aq->regs + reg);
+}
+
+static inline u16 qspi_readw(struct atmel_qspi *aq, u32 reg)
+{
+	return readw_relaxed(aq->regs + reg);
+}
+
+static inline void qspi_writew(struct atmel_qspi *aq, u32 reg, u16 value)
+{
+	writew_relaxed(value, aq->regs + reg);
+}
+
+static inline u8 qspi_readb(struct atmel_qspi *aq, u32 reg)
+{
+	return readb_relaxed(aq->regs + reg);
+}
+
+static inline void qspi_writeb(struct atmel_qspi *aq, u32 reg, u8 value)
+{
+	writeb_relaxed(value, aq->regs + reg);
+}
+
+
+#define QSPI_DMA_THRESHOLD	32
+
+static void atmel_qspi_dma_callback(void *arg)
+{
+	struct completion *c = arg;
+
+	complete(c);
+}
+
+static int atmel_qspi_run_dma_transfer(struct atmel_qspi *aq,
+				       const struct atmel_qspi_command *cmd)
+{
+	u32 offset = (cmd->enable.bits.address) ? cmd->address : 0;
+	struct dma_chan *chan = aq->chan;
+	struct device *dev = &aq->pdev->dev;
+	enum dma_data_direction direction;
+	dma_addr_t phys_addr, dst, src;
+	struct dma_async_tx_descriptor *desc;
+	struct completion completion;
+	dma_cookie_t cookie;
+	int err = 0;
+
+	if (cmd->tx_buf) {
+		direction = DMA_TO_DEVICE;
+		phys_addr = dma_map_single(dev, (void *)cmd->tx_buf,
+					   cmd->buf_len, direction);
+		src = phys_addr;
+		dst = aq->phys_addr + offset;
+	} else {
+		direction = DMA_FROM_DEVICE;
+		phys_addr = dma_map_single(dev, (void *)cmd->rx_buf,
+					   cmd->buf_len, direction);
+		src = aq->phys_addr + offset;
+		dst = phys_addr;
+	}
+	if (dma_mapping_error(dev, phys_addr))
+		return -ENOMEM;
+
+	desc = chan->device->device_prep_dma_memcpy(chan, dst, src,
+						    cmd->buf_len,
+						    DMA_PREP_INTERRUPT);
+	if (!desc) {
+		err = -ENOMEM;
+		goto unmap_single;
+	}
+
+	init_completion(&completion);
+	desc->callback = atmel_qspi_dma_callback;
+	desc->callback_param = &completion;
+	cookie = dmaengine_submit(desc);
+	err = dma_submit_error(cookie);
+	if (err)
+		goto unmap_single;
+	dma_async_issue_pending(chan);
+
+	if (!wait_for_completion_timeout(&completion, msecs_to_jiffies(1000)))
+		err = -ETIMEDOUT;
+
+	if (dma_async_is_tx_complete(chan, cookie, NULL, NULL) != DMA_COMPLETE)
+		err = -ETIMEDOUT;
+
+	if (err)
+		dmaengine_terminate_all(chan);
+unmap_single:
+	dma_unmap_single(dev, phys_addr, cmd->buf_len, direction);
+
+	return err;
+}
+
+static int atmel_qspi_run_transfer(struct atmel_qspi *aq,
+				   const struct atmel_qspi_command *cmd)
+{
+	void __iomem *ahb_mem;
+
+	/* First try a DMA transfer */
+	if (aq->chan && cmd->enable.bits.dma &&
+	    cmd->buf_len >= QSPI_DMA_THRESHOLD)
+		return atmel_qspi_run_dma_transfer(aq, cmd);
+
+	/* Then fallback to a PIO transfer */
+	ahb_mem = aq->mem;
+	if (cmd->enable.bits.address)
+		ahb_mem += cmd->address;
+	if (cmd->tx_buf)
+		memcpy_toio(ahb_mem, cmd->tx_buf, cmd->buf_len);
+	else
+		memcpy_fromio(cmd->rx_buf, ahb_mem, cmd->buf_len);
+
+	return 0;
+}
+
+#ifdef DEBUG
+static void atmel_qspi_debug_command(struct atmel_qspi *aq,
+				     const struct atmel_qspi_command *cmd)
+{
+	u8 cmd_buf[SPI_NOR_MAX_CMD_SIZE];
+	size_t len = 0;
+	int i;
+
+	if (cmd->enable.bits.instruction) {
+		if (aq->last_instruction == cmd->instruction)
+			return;
+		aq->last_instruction = cmd->instruction;
+	}
+
+	if (cmd->enable.bits.instruction)
+		cmd_buf[len++] = cmd->instruction;
+
+	for (i = cmd->enable.bits.address-1; i >= 0; --i)
+		cmd_buf[len++] = (cmd->address >> (i << 3)) & 0xff;
+
+	if (cmd->enable.bits.mode)
+		cmd_buf[len++] = cmd->mode;
+
+	if (cmd->enable.bits.dummy) {
+		int num = cmd->num_dummy_cycles;
+
+		switch (aq->ifr_width) {
+		case QSPI_IFR_WIDTH_SINGLE_BIT_SPI:
+		case QSPI_IFR_WIDTH_DUAL_OUTPUT:
+		case QSPI_IFR_WIDTH_QUAD_OUTPUT:
+			num >>= 3;
+			break;
+		case QSPI_IFR_WIDTH_DUAL_IO:
+		case QSPI_IFR_WIDTH_DUAL_CMD:
+			num >>= 2;
+			break;
+		case QSPI_IFR_WIDTH_QUAD_IO:
+		case QSPI_IFR_WIDTH_QUAD_CMD:
+			num >>= 1;
+			break;
+		default:
+			return;
+		}
+
+		for (i = 0; i < num; ++i)
+			cmd_buf[len++] = 0;
+	}
+
+	/* Dump the SPI command */
+	print_hex_dump(KERN_DEBUG, "qspi cmd: ", DUMP_PREFIX_NONE,
+		       32, 1, cmd_buf, len, false);
+
+#ifdef VERBOSE_DEBUG
+	/* If verbose debug is enabled, also dump the TX data */
+	if (cmd->enable.bits.data && cmd->tx_buf)
+		print_hex_dump(KERN_DEBUG, "qspi tx : ", DUMP_PREFIX_NONE,
+			       32, 1, cmd->tx_buf, cmd->buf_len, false);
+#endif
+}
+#else
+#define atmel_qspi_debug_command(aq, cmd)
+#endif
+
+static int atmel_qspi_run_command(struct atmel_qspi *aq,
+				  const struct atmel_qspi_command *cmd)
+{
+	u32 iar, icr, ifr, sr;
+	int err = 0;
+
+	iar = 0;
+	icr = 0;
+	ifr = aq->ifr_width | cmd->ifr_tfrtyp;
+
+	/* Compute instruction parameters */
+	if (cmd->enable.bits.instruction) {
+		icr |= QSPI_ICR_INST(cmd->instruction);
+		ifr |= QSPI_IFR_INSTEN;
+	}
+
+	/* Compute address parameters */
+	switch (cmd->enable.bits.address) {
+	case 4:
+		ifr |= QSPI_IFR_ADDRL;
+		/*break;*/ /* fallback to the 24bit address case */
+	case 3:
+		iar = (cmd->enable.bits.data) ? 0 : cmd->address;
+		ifr |= QSPI_IFR_ADDREN;
+		break;
+	case 0:
+		break;
+	default:
+		return -EINVAL;
+	}
+
+	/* Compute option parameters */
+	if (cmd->enable.bits.mode && cmd->num_mode_cycles) {
+		u32 mode_cycle_bits, mode_bits;
+
+		icr |= QSPI_ICR_OPT(cmd->mode);
+		ifr |= QSPI_IFR_OPTEN;
+
+		switch (ifr & QSPI_IFR_WIDTH_MASK) {
+		case QSPI_IFR_WIDTH_SINGLE_BIT_SPI:
+		case QSPI_IFR_WIDTH_DUAL_OUTPUT:
+		case QSPI_IFR_WIDTH_QUAD_OUTPUT:
+			mode_cycle_bits = 1;
+			break;
+		case QSPI_IFR_WIDTH_DUAL_IO:
+		case QSPI_IFR_WIDTH_DUAL_CMD:
+			mode_cycle_bits = 2;
+			break;
+		case QSPI_IFR_WIDTH_QUAD_IO:
+		case QSPI_IFR_WIDTH_QUAD_CMD:
+			mode_cycle_bits = 4;
+			break;
+		default:
+			return -EINVAL;
+		}
+
+		mode_bits = cmd->num_mode_cycles * mode_cycle_bits;
+		switch (mode_bits) {
+		case 1:
+			ifr |= QSPI_IFR_OPTL_1BIT;
+			break;
+
+		case 2:
+			ifr |= QSPI_IFR_OPTL_2BIT;
+			break;
+
+		case 4:
+			ifr |= QSPI_IFR_OPTL_4BIT;
+			break;
+
+		case 8:
+			ifr |= QSPI_IFR_OPTL_8BIT;
+			break;
+
+		default:
+			return -EINVAL;
+		}
+	}
+
+	/* Set number of dummy cycles */
+	if (cmd->enable.bits.dummy)
+		ifr |= QSPI_IFR_NBDUM(cmd->num_dummy_cycles);
+
+	/* Set data enable */
+	if (cmd->enable.bits.data) {
+		ifr |= QSPI_IFR_DATAEN;
+
+		/* Special case for Continuous Read Mode */
+		if (!cmd->tx_buf && !cmd->rx_buf)
+			ifr |= QSPI_IFR_CRM;
+	}
+
+	/* Set QSPI Instruction Frame registers */
+	atmel_qspi_debug_command(aq, cmd);
+	qspi_writel(aq, QSPI_IAR, iar);
+	qspi_writel(aq, QSPI_ICR, icr);
+	qspi_writel(aq, QSPI_IFR, ifr);
+
+	/* Skip to the final steps if there is no data */
+	if (!cmd->enable.bits.data)
+		goto no_data;
+
+	/* Dummy read of QSPI_IFR to synchronize APB and AHB accesses */
+	(void)qspi_readl(aq, QSPI_IFR);
+
+	/* Stop here for continuous read */
+	if (!cmd->tx_buf && !cmd->rx_buf)
+		return 0;
+	/* Send/Receive data */
+	err = atmel_qspi_run_transfer(aq, cmd);
+
+	/* Release the chip-select */
+	qspi_writel(aq, QSPI_CR, QSPI_CR_LASTXFER);
+
+	if (err)
+		return err;
+
+#if defined(DEBUG) && defined(VERBOSE_DEBUG)
+	/*
+	 * If verbose debug is enabled, also dump the RX data in addition to
+	 * the SPI command previously dumped by atmel_qspi_debug_command()
+	 */
+	if (cmd->rx_buf)
+		print_hex_dump(KERN_DEBUG, "qspi rx : ", DUMP_PREFIX_NONE,
+			       32, 1, cmd->rx_buf, cmd->buf_len, false);
+#endif
+no_data:
+	/* Poll INSTRuction End status */
+	sr = qspi_readl(aq, QSPI_SR);
+	if (sr & QSPI_SR_INSTRE)
+		return err;
+
+	/* Wait for INSTRuction End interrupt */
+	init_completion(&aq->completion);
+	aq->pending = 0;
+	qspi_writel(aq, QSPI_IER, QSPI_SR_INSTRE);
+	if (!wait_for_completion_timeout(&aq->completion,
+					 msecs_to_jiffies(1000)))
+		err = -ETIMEDOUT;
+	qspi_writel(aq, QSPI_IDR, QSPI_SR_INSTRE);
+
+	return err;
+}
+
+static int atmel_qspi_read_reg(struct spi_nor *nor, u8 opcode,
+			       u8 *buf, int len)
+{
+	struct atmel_qspi *aq = nor->priv;
+	struct atmel_qspi_command cmd;
+
+	memset(&cmd, 0, sizeof(cmd));
+	cmd.ifr_tfrtyp = QSPI_IFR_TFRTYP_TRSFR_READ;
+	cmd.enable.bits.instruction = 1;
+	cmd.enable.bits.data = 1;
+	cmd.instruction = opcode;
+	cmd.rx_buf = buf;
+	cmd.buf_len = len;
+	return atmel_qspi_run_command(aq, &cmd);
+}
+
+static int atmel_qspi_write_reg(struct spi_nor *nor, u8 opcode,
+				u8 *buf, int len,
+				int write_enable)
+{
+	struct atmel_qspi *aq = nor->priv;
+	struct atmel_qspi_command cmd;
+
+	memset(&cmd, 0, sizeof(cmd));
+	cmd.ifr_tfrtyp = QSPI_IFR_TFRTYP_TRSFR_WRITE;
+	cmd.enable.bits.instruction = 1;
+	cmd.enable.bits.data = (buf != NULL && len > 0);
+	cmd.instruction = opcode;
+	cmd.tx_buf = buf;
+	cmd.buf_len = len;
+	return atmel_qspi_run_command(aq, &cmd);
+}
+
+static void atmel_qspi_write(struct spi_nor *nor, loff_t to, size_t len,
+			     size_t *retlen, const u_char *write_buf)
+{
+	struct atmel_qspi *aq = nor->priv;
+	struct atmel_qspi_command cmd;
+
+	memset(&cmd, 0, sizeof(cmd));
+	cmd.ifr_tfrtyp = QSPI_IFR_TFRTYP_TRSFR_WRITE_MEM;
+	cmd.enable.bits.instruction = 1;
+	cmd.enable.bits.address = nor->addr_width;
+	cmd.enable.bits.data = 1;
+	cmd.enable.bits.dma = 1;
+	cmd.instruction = nor->program_opcode;
+	cmd.address = (u32)to;
+	cmd.tx_buf = write_buf;
+	cmd.buf_len = len;
+	if (!atmel_qspi_run_command(aq, &cmd))
+		*retlen += len;
+}
+
+static int atmel_qspi_erase(struct spi_nor *nor, loff_t offs)
+{
+	struct atmel_qspi *aq = nor->priv;
+	struct atmel_qspi_command cmd;
+
+	dev_dbg(nor->dev, "%dKiB at 0x%08x\n",
+		aq->mtd.erasesize / 1024, (u32)offs);
+
+	memset(&cmd, 0, sizeof(cmd));
+	cmd.ifr_tfrtyp = QSPI_IFR_TFRTYP_TRSFR_WRITE;
+	cmd.enable.bits.instruction = 1;
+	cmd.enable.bits.address = nor->addr_width;
+	cmd.instruction = nor->erase_opcode;
+	cmd.address = (u32)offs;
+	return atmel_qspi_run_command(aq, &cmd);
+}
+
+static int atmel_qspi_read(struct spi_nor *nor, loff_t from, size_t len,
+			   size_t *retlen, u_char *read_buf)
+{
+	struct atmel_qspi *aq = nor->priv;
+	struct atmel_qspi_command cmd;
+	int err;
+
+	memset(&cmd, 0, sizeof(cmd));
+	cmd.ifr_tfrtyp = QSPI_IFR_TFRTYP_TRSFR_READ_MEM;
+	cmd.enable.bits.instruction = 1;
+	cmd.enable.bits.address = nor->addr_width;
+	cmd.enable.bits.dummy = (nor->read_dummy > 0);
+	cmd.enable.bits.data = 1;
+	cmd.enable.bits.dma = 1;
+	cmd.instruction = nor->read_opcode;
+	cmd.address = (u32)from;
+	cmd.num_dummy_cycles = nor->read_dummy;
+	cmd.rx_buf = read_buf;
+	cmd.buf_len = len;
+	err = atmel_qspi_run_command(aq, &cmd);
+	if (err)
+		return err;
+
+	*retlen += len;
+	return 0;
+}
+
+static int atmel_qspi_set_protocol(struct spi_nor *nor, enum spi_protocol proto)
+{
+	struct atmel_qspi *aq = nor->priv;
+
+	switch (proto) {
+	case SPI_PROTO_1_1_1:
+		aq->ifr_width = QSPI_IFR_WIDTH_SINGLE_BIT_SPI;
+		break;
+	case SPI_PROTO_1_1_2:
+		aq->ifr_width = QSPI_IFR_WIDTH_DUAL_OUTPUT;
+		break;
+	case SPI_PROTO_1_1_4:
+		aq->ifr_width = QSPI_IFR_WIDTH_QUAD_OUTPUT;
+		break;
+	case SPI_PROTO_1_2_2:
+		aq->ifr_width = QSPI_IFR_WIDTH_DUAL_IO;
+		break;
+	case SPI_PROTO_1_4_4:
+		aq->ifr_width = QSPI_IFR_WIDTH_QUAD_IO;
+		break;
+	case SPI_PROTO_2_2_2:
+		aq->ifr_width = QSPI_IFR_WIDTH_DUAL_CMD;
+		break;
+	case SPI_PROTO_4_4_4:
+		aq->ifr_width = QSPI_IFR_WIDTH_QUAD_CMD;
+		break;
+	default:
+		return -EINVAL;
+	}
+
+	return 0;
+}
+
+static int atmel_qspi_init(struct atmel_qspi *aq)
+{
+	unsigned long src_rate;
+	u32 mr, scr, scbr;
+
+	/* Reset the QSPI controller */
+	qspi_writel(aq, QSPI_CR, QSPI_CR_SWRST);
+
+	/* Set the QSPI controller in Serial Memory Mode */
+	mr = QSPI_MR_SSM | QSPI_MR_NBBITS(8);
+	qspi_writel(aq, QSPI_MR, mr);
+
+	src_rate = clk_get_rate(aq->clk);
+	if (!src_rate)
+		return -EINVAL;
+
+	/* Compute the QSPI baudrate */
+	scbr = DIV_ROUND_UP(src_rate, aq->clk_rate);
+	if (scbr > 0)
+		scbr--;
+	scr = QSPI_SCR_SCBR(scbr);
+	qspi_writel(aq, QSPI_SCR, scr);
+
+	/* Enable the QSPI controller */
+	qspi_writel(aq, QSPI_CR, QSPI_CR_QSPIEN);
+
+	return 0;
+}
+
+static irqreturn_t atmel_qspi_interrupt(int irq, void *dev_id)
+{
+	struct atmel_qspi *aq = (struct atmel_qspi *)dev_id;
+	u32 status, mask, pending;
+
+	status = qspi_readl(aq, QSPI_SR);
+	mask = qspi_readl(aq, QSPI_IMR);
+	pending = status & mask;
+
+	if (!pending)
+		return IRQ_NONE;
+
+	aq->pending |= pending;
+	if (pending & QSPI_SR_INSTRE)
+		complete(&aq->completion);
+
+	return IRQ_HANDLED;
+}
+
+static int atmel_qspi_probe(struct platform_device *pdev)
+{
+	struct device_node *child, *np = pdev->dev.of_node;
+	struct mtd_part_parser_data ppdata;
+	struct atmel_qspi *aq;
+	struct resource *res;
+	dma_cap_mask_t mask;
+	struct spi_nor *nor;
+	struct mtd_info *mtd;
+	char modalias[40];
+	int irq, err = 0;
+
+	if (of_get_child_count(np) != 1)
+		return -ENODEV;
+	child = of_get_next_child(np, NULL);
+
+	aq = devm_kzalloc(&pdev->dev, sizeof(*aq), GFP_KERNEL);
+	if (!aq) {
+		err = -ENOMEM;
+		goto exit;
+	}
+
+	platform_set_drvdata(pdev, aq);
+	aq->pdev = pdev;
+	/* Start in Extended SPI (1-1-1) */
+	aq->ifr_width = QSPI_IFR_WIDTH_SINGLE_BIT_SPI;
+
+	/* Map the registers */
+	res = platform_get_resource(pdev, IORESOURCE_MEM, 0);
+	aq->regs = devm_ioremap_resource(&pdev->dev, res);
+	if (IS_ERR(aq->regs)) {
+		dev_err(&pdev->dev, "missing registers\n");
+		err = PTR_ERR(aq->regs);
+		goto exit;
+	}
+
+	/* Map the AHB memory */
+	res = platform_get_resource(pdev, IORESOURCE_MEM, 1);
+	aq->mem = devm_ioremap_resource(&pdev->dev, res);
+	if (IS_ERR(aq->mem)) {
+		dev_err(&pdev->dev, "missing AHB memory\n");
+		err = PTR_ERR(aq->regs);
+		goto exit;
+	}
+	aq->phys_addr = (dma_addr_t)res->start;
+
+	/* Get the peripheral clock */
+	aq->clk = devm_clk_get(&pdev->dev, NULL);
+	if (IS_ERR(aq->clk)) {
+		dev_err(&pdev->dev, "missing peripheral clock\n");
+		err = PTR_ERR(aq->clk);
+		goto exit;
+	}
+
+	/* Enable the peripheral clock */
+	err = clk_prepare_enable(aq->clk);
+	if (err) {
+		dev_err(&pdev->dev, "failed to enable the peripheral clock\n");
+		goto exit;
+	}
+
+	/* Request the IRQ */
+	irq = platform_get_irq(pdev, 0);
+	if (irq < 0) {
+		dev_err(&pdev->dev, "missing IRQ\n");
+		err = irq;
+		goto disable_clk;
+	}
+	err = devm_request_irq(&pdev->dev, irq, atmel_qspi_interrupt,
+			       0, dev_name(&pdev->dev), aq);
+	if (err)
+		goto disable_clk;
+
+	/* Try to get a DMA channel for memcpy() operation */
+	dma_cap_zero(mask);
+	dma_cap_set(DMA_MEMCPY, mask);
+	aq->chan = dma_request_channel(mask, NULL, NULL);
+	if (!aq->chan)
+		dev_warn(&pdev->dev, "no available DMA channel\n");
+
+	/* Setup the spi-nor */
+	nor = &aq->nor;
+	mtd = &aq->mtd;
+
+	nor->mtd = mtd;
+	nor->dev = &pdev->dev;
+	nor->priv = aq;
+	mtd->priv = nor;
+
+	nor->read_reg = atmel_qspi_read_reg;
+	nor->write_reg = atmel_qspi_write_reg;
+	nor->read = atmel_qspi_read;
+	nor->write = atmel_qspi_write;
+	nor->erase = atmel_qspi_erase;
+	nor->set_protocol = atmel_qspi_set_protocol;
+
+	if (of_modalias_node(child, modalias, sizeof(modalias)) < 0) {
+		err = -ENODEV;
+		goto release_channel;
+	}
+
+	err = of_property_read_u32(child, "spi-max-frequency", &aq->clk_rate);
+	if (err < 0)
+		goto release_channel;
+
+	err = atmel_qspi_init(aq);
+	if (err)
+		goto release_channel;
+
+	nor->dev->of_node = child;
+	err = spi_nor_scan(nor, modalias, SPI_NOR_QUAD);
+	nor->dev->of_node = np;
+	if (err)
+		goto release_channel;
+
+	ppdata.of_node = child;
+	err = mtd_device_parse_register(mtd, NULL, &ppdata, NULL, 0);
+	if (err)
+		goto release_channel;
+
+	of_node_put(child);
+
+	return 0;
+
+release_channel:
+	if (aq->chan)
+		dma_release_channel(aq->chan);
+disable_clk:
+	clk_disable_unprepare(aq->clk);
+exit:
+	of_node_put(child);
+
+	return err;
+}
+
+static int atmel_qspi_remove(struct platform_device *pdev)
+{
+	struct atmel_qspi *aq = platform_get_drvdata(pdev);
+
+	mtd_device_unregister(&aq->mtd);
+	qspi_writel(aq, QSPI_CR, QSPI_CR_QSPIDIS);
+	if (aq->chan)
+		dma_release_channel(aq->chan);
+	clk_disable_unprepare(aq->clk);
+	return 0;
+}
+
+
+static const struct of_device_id atmel_qspi_dt_ids[] = {
+	{ .compatible = "atmel,sama5d2-qspi" },
+	{ /* sentinel */ }
+};
+
+MODULE_DEVICE_TABLE(of, atmel_qspi_dt_ids);
+
+static struct platform_driver atmel_qspi_driver = {
+	.driver = {
+		.name	= "atmel_qspi",
+		.of_match_table	= atmel_qspi_dt_ids,
+	},
+	.probe		= atmel_qspi_probe,
+	.remove		= atmel_qspi_remove,
+};
+module_platform_driver(atmel_qspi_driver);
+
+MODULE_AUTHOR("Cyrille Pitchen <cyrille.pitchen at atmel.com>");
+MODULE_DESCRIPTION("Atmel QSPI Controller driver");
+MODULE_LICENSE("GPL v2");
-- 
1.8.2.2



From marc.zyngier at arm.com  Mon Aug 24 03:17:32 2015
From: marc.zyngier at arm.com (Marc Zyngier)
Date: Mon, 24 Aug 2015 11:17:32 +0100
Subject: [PATCH] irqchip, gicv3-its, numa: Workaround for Cavium ThunderX
 erratum 23144
In-Reply-To: <20150822131050.GK1820@rric.localdomain>
References: <20150822131050.GK1820@rric.localdomain>
Message-ID: <55DAEF3C.5090303@arm.com>

Hi Robert,

Just came back from the Seattle madness, so picking up patches in
reverse order... ;-)

On 22/08/15 14:10, Robert Richter wrote:
> The patch below adds a workaround for gicv3 in a numa environment. It
> is on top of my recent gicv3 errata patch submission v4 and Ganapat's
> arm64 numa patches for devicetree v5.
> 
> Please comment.
> 
> Thanks,
> 
> -Robert
> 
> 
> 
> From c432820451a46b8d1e299b8bfbfcdcb3b75340e7 Mon Sep 17 00:00:00 2001
> From: Ganapatrao Kulkarni <gkulkarni at caviumnetworks.com>
> Date: Wed, 19 Aug 2015 23:40:05 +0530
> Subject: [PATCH] irqchip, gicv3-its, numa: Workaround for Cavium ThunderX erratum
>  23144
> 
> This implements a workaround for gicv3-its erratum 23144 applicable
> for Cavium's ThunderX multinode systems.
> 
> The erratum fixes the hang of ITS SYNC command by avoiding inter node
> io and collections/cpu mapping. This fix is only applicable for
> Cavium's ThunderX dual-socket platforms.

Can you please elaborate on this? I can't see any reference to the SYNC
command there. Is that a case of an ITS not being able to route LPIs to
cores on another socket?

I really need more details to understand this patch (please use short
sentences, I'm still in a different time zone).

> 
> Signed-off-by: Ganapatrao Kulkarni <gkulkarni at caviumnetworks.com>
> [ rric: Reworked errata code, added helper functions, updated commit
>   	message. ]
> 
> Signed-off-by: Robert Richter <rrichter at cavium.com>
> ---
>  arch/arm64/Kconfig               | 14 +++++++++++
>  drivers/irqchip/irq-gic-common.c |  5 ++--
>  drivers/irqchip/irq-gic-v3-its.c | 54 ++++++++++++++++++++++++++++++++++------
>  3 files changed, 64 insertions(+), 9 deletions(-)
> 
> diff --git a/arch/arm64/Kconfig b/arch/arm64/Kconfig
> index 3809187ed653..b92b7b70b29b 100644
> --- a/arch/arm64/Kconfig
> +++ b/arch/arm64/Kconfig
> @@ -421,6 +421,20 @@ config ARM64_ERRATUM_845719
>  
>  	  If unsure, say Y.
>  
> +config CAVIUM_ERRATUM_22375
> +	bool "Cavium erratum 22375, 24313"
> +	depends on NUMA
> +	default y
> +	help
> +		Enable workaround for erratum 22375, 24313.
> +
> +config CAVIUM_ERRATUM_23144
> +	bool "Cavium erratum 23144"
> +	depends on NUMA
> +	default y
> +	help
> +		Enable workaround for erratum 23144.
> +
>  config CAVIUM_ERRATUM_23154
>  	bool "Cavium erratum 23154: Access to ICC_IAR1_EL1 is not sync'ed"
>  	depends on ARCH_THUNDER
> diff --git a/drivers/irqchip/irq-gic-common.c b/drivers/irqchip/irq-gic-common.c
> index ee789b07f2d1..1dfce64dbdac 100644
> --- a/drivers/irqchip/irq-gic-common.c
> +++ b/drivers/irqchip/irq-gic-common.c
> @@ -24,11 +24,12 @@
>  void gic_check_capabilities(u32 iidr, const struct gic_capabilities *cap,
>  			void *data)
>  {
> -	for (; cap->desc; cap++) {
> +	for (; cap->init; cap++) {
>  		if (cap->iidr != (cap->mask & iidr))
>  			continue;
>  		cap->init(data);
> -		pr_info("%s\n", cap->desc);
> +		if (cap->desc)
> +			pr_info("%s\n", cap->desc);

No. I really want to see what errata are applied when I look at a kernel
log.

>  	}
>  }
>  
> diff --git a/drivers/irqchip/irq-gic-v3-its.c b/drivers/irqchip/irq-gic-v3-its.c
> index 4bb135721e72..666be39f13a9 100644
> --- a/drivers/irqchip/irq-gic-v3-its.c
> +++ b/drivers/irqchip/irq-gic-v3-its.c
> @@ -43,7 +43,8 @@
>  #include "irqchip.h"
>  
>  #define ITS_FLAGS_CMDQ_NEEDS_FLUSHING		(1ULL << 0)
> -#define ITS_FLAGS_CAVIUM_THUNDERX		(1ULL << 1)
> +#define ITS_WORKAROUND_CAVIUM_22375		(1ULL << 1)
> +#define ITS_WORKAROUND_CAVIUM_23144		(1ULL << 2)
>  
>  #define RDIST_FLAGS_PROPBASE_NEEDS_FLUSHING	(1 << 0)
>  
> @@ -76,6 +77,7 @@ struct its_node {
>  	struct list_head	its_device_list;
>  	u64			flags;
>  	u32			ite_size;
> +	int			numa_node;
>  };
>  
>  #define ITS_ITT_ALIGN		SZ_256
> @@ -609,11 +611,18 @@ static void its_eoi_irq(struct irq_data *d)
>  static int its_set_affinity(struct irq_data *d, const struct cpumask *mask_val,
>  			    bool force)
>  {
> -	unsigned int cpu = cpumask_any_and(mask_val, cpu_online_mask);
> +	unsigned int cpu;
>  	struct its_device *its_dev = irq_data_get_irq_chip_data(d);
>  	struct its_collection *target_col;
>  	u32 id = its_get_event_id(d);
>  
> +	if (its_dev->its->flags & ITS_WORKAROUND_CAVIUM_23144) {
> +		cpu = cpumask_any_and(mask_val,
> +				cpumask_of_node(its_dev->its->numa_node));

I suppose cpumask_of_node returns only the *online* cores of a given
node, right?

> +	} else {
> +		cpu = cpumask_any_and(mask_val, cpu_online_mask);
> +	}
> +
>  	if (cpu >= nr_cpu_ids)
>  		return -EINVAL;
>  
> @@ -845,7 +854,7 @@ static int its_alloc_tables(struct its_node *its)
>  	u64 typer;
>  	u32 ids;
>  
> -	if (its->flags & ITS_FLAGS_CAVIUM_THUNDERX) {
> +	if (its->flags & ITS_WORKAROUND_CAVIUM_22375) {
>  		/*
>  		 * erratum 22375: only alloc 8MB table size
>  		 * erratum 24313: ignore memory access type
> @@ -1093,6 +1102,11 @@ static void its_cpu_init_lpis(void)
>  	dsb(sy);
>  }
>  
> +static inline int numa_node_id_early(void)
> +{
> +	return MPIDR_AFFINITY_LEVEL(read_cpuid_mpidr(), 2);
> +}
> +
>  static void its_cpu_init_collection(void)
>  {
>  	struct its_node *its;
> @@ -1104,6 +1118,11 @@ static void its_cpu_init_collection(void)
>  	list_for_each_entry(its, &its_nodes, entry) {
>  		u64 target;
>  
> +		/* avoid cross node core and its mapping */
> +		if ((its->flags & ITS_WORKAROUND_CAVIUM_23144) &&
> +			its->numa_node != numa_node_id_early())
> +				continue;
> +

Argh. This is horrible. You really need some topology bindings to
describe your system instead of hardcoding some random level of
affinity. The next time someone is going to come up with a similarly
broken system, they will have to reinvent that wheel.

>  		/*
>  		 * We now have to bind each collection to its target
>  		 * redistributor.
> @@ -1372,9 +1391,15 @@ static void its_irq_domain_activate(struct irq_domain *domain,
>  {
>  	struct its_device *its_dev = irq_data_get_irq_chip_data(d);
>  	u32 event = its_get_event_id(d);
> +	unsigned int cpu;
> +
> +	if (its_dev->its->flags & ITS_WORKAROUND_CAVIUM_23144)
> +		cpu = cpumask_first(cpumask_of_node(its_dev->its->numa_node));
> +	else
> +		cpu = cpumask_first(cpu_online_mask);

Looks like this can be factored with the code you've added in set_affinity.

>  
>  	/* Bind the LPI to the first possible CPU */
> -	its_dev->event_map.col_map[event] = cpumask_first(cpu_online_mask);
> +	its_dev->event_map.col_map[event] = cpu;
>  
>  	/* Map the GIC IRQ and event to the device */
>  	its_send_mapvi(its_dev, d->hwirq, event);
> @@ -1457,16 +1482,31 @@ static int its_force_quiescent(void __iomem *base)
>  	}
>  }
>  
> +static inline int its_get_node_thunderx(struct its_node *its)
> +{
> +	return (its->phys_base >> 44) & 0x3;

Why 3? Is that because you have provision for 4 sockets or what?

> +}
> +
>  static void its_enable_cavium_thunderx(void *data)
>  {
> -	struct its_node *its = data;
> +	struct its_node __maybe_unused *its = data;
>  
> -	its->flags |= ITS_FLAGS_CAVIUM_THUNDERX;
> +#ifdef CONFIG_CAVIUM_ERRATUM_22375
> +	its->flags |= ITS_WORKAROUND_CAVIUM_22375;
> +	pr_info("ITS: Enabling workaround for 22375, 24313\n");
> +#endif
> +
> +#ifdef CONFIG_CAVIUM_ERRATUM_23144
> +	if (num_possible_nodes() > 1) {
> +		its->numa_node = its_get_node_thunderx(its);

I'd rather see numa_node being always initialized to something useful.
If you're adding numa support, why can't this be initialized via
standard topology bindings?

Also, you're mixing things coming from the address map and information
coming from the MPIDR. I must say this doesn't fill me with confidence.

> +		its->flags |= ITS_WORKAROUND_CAVIUM_23144;
> +		pr_info("ITS: Enabling workaround for 23144\n");
> +	}
> +#endif

It would probably make sense to split these in two function, each with
its own erratum entry.

>  }
>  
>  static const struct gic_capabilities its_errata[] = {
>  	{
> -		.desc	= "ITS: Cavium errata 22375, 24313",
>  		.iidr	= 0xa100034c,	/* ThunderX pass 1.x */
>  		.mask	= 0xffff0fff,
>  		.init	= its_enable_cavium_thunderx,
> 

Thanks,

	M.
-- 
Jazz is not dead. It just smells funny...


From mark.rutland at arm.com  Mon Aug 24 03:17:55 2015
From: mark.rutland at arm.com (Mark Rutland)
Date: Mon, 24 Aug 2015 11:17:55 +0100
Subject: [PATCH 1/3] Docs: dt: add generic MSI bindings
In-Reply-To: <20150805165120.GB28849@leverpostej>
References: <1437670365-20704-1-git-send-email-mark.rutland@arm.com>
 <1437670365-20704-2-git-send-email-mark.rutland@arm.com>
 <20150805165120.GB28849@leverpostej>
Message-ID: <20150824101755.GC7139@leverpostej>

On Wed, Aug 05, 2015 at 05:51:20PM +0100, Mark Rutland wrote:
> Rob,
> 
> Do you have any objections to this, or are you happy to take this patch?
> 
> There's a user of this binding (the GICv3 ITS) queued for v4.3 already in
> the tip tree, so either we either need to be ok with this binding or we
> need to rework that before v4.3.

Sorry to ping, but are you happy to take this? Marc's replied and
provided his ack.

I'm happy to resend if you prefer?

Thanks,
Mark.

> Marc, can I take it from your use of the binding that you are happy to
> provide your ack?
> 
> Thanks,
> Mark.
> 
> On Thu, Jul 23, 2015 at 05:52:43PM +0100, Mark Rutland wrote:
> > Currently msi-parent is used in a couple of drivers despite being fairly
> > underspecified. This patch adds a generic binding for MSIs (including
> > the existing msi-parent property) enabling the description of platform
> > devices capable of using MSIs.
> > 
> > While MSIs are primarily distinguished by doorbell and payload, some MSI
> > controllers (e.g. the GICv3 ITS) also use side-band information
> > accompanying the write to identify the master which originated the MSI,
> > to allow for sandboxing. This sideband information is non-probeable and
> > needs to be described in the DT. Other MSI controllers may have
> > additional configuration details which need to be described per-master.
> > 
> > This patch adds a generic msi-parent binding document, extending the
> > de-facto standard with a new (optional) #msi-cells which can be used to
> > express any per-master configuration and/or sideband data. This is
> > sufficient to describe non-hotpluggable devices.
> > 
> > For busses where sideband data may be derived from some bus-specific
> > master ID scheme, other properties will be required to describe the
> > mapping.
> > 
> > Signed-off-by: Mark Rutland <mark.rutland at arm.com>
> > ---
> >  .../bindings/interrupt-controller/msi.txt          | 135 +++++++++++++++++++++
> >  1 file changed, 135 insertions(+)
> >  create mode 100644 Documentation/devicetree/bindings/interrupt-controller/msi.txt
> > 
> > diff --git a/Documentation/devicetree/bindings/interrupt-controller/msi.txt b/Documentation/devicetree/bindings/interrupt-controller/msi.txt
> > new file mode 100644
> > index 0000000..c60c034
> > --- /dev/null
> > +++ b/Documentation/devicetree/bindings/interrupt-controller/msi.txt
> > @@ -0,0 +1,135 @@
> > +This document describes the generic device tree binding for MSI controllers and
> > +their master(s).
> > +
> > +Message Signaled Interrupts (MSIs) are a class of interrupts generated by a
> > +write to an MMIO address.
> > +
> > +MSIs were originally specified by PCI (and are used with PCIe), but may also be
> > +used with other busses, and hence a mechanism is required to relate devices on
> > +those busses to the MSI controllers which they are capable of using,
> > +potentially including additional information.
> > +
> > +MSIs are distinguished by some combination of:
> > +
> > +- The doorbell (the MMIO address written to).
> > +  
> > +  Devices may be configured by software to write to arbitrary doorbells which
> > +  they can address. An MSI controller may feature a number of doorbells.
> > +
> > +- The payload (the value written to the doorbell).
> > +  
> > +  Devices may be configured to write an arbitrary payload chosen by software.
> > +  MSI controllers may have restrictions on permitted payloads.
> > +
> > +- Sideband information accompanying the write.
> > +  
> > +  Typically this is neither configurable nor probeable, and depends on the path
> > +  taken through the memory system (i.e. it is a property of the combination of
> > +  MSI controller and device rather than a property of either in isolation).
> > +
> > +
> > +MSI controllers:
> > +================
> > +
> > +An MSI controller signals interrupts to a CPU when a write is made to an MMIO
> > +address by some master. An MSI controller may feature a number of doorbells.
> > +
> > +Required properties:
> > +--------------------
> > +
> > +- msi-controller: Identifies the node as an MSI controller.
> > +
> > +Optional properties:
> > +--------------------
> > +
> > +- #msi-cells: The number of cells in an msi-specifier, required if not zero.
> > +
> > +  Typically this will encode information related to sideband data, and will
> > +  not encode doorbells or payloads as these can be configured dynamically.
> > +
> > +  The meaning of the msi-specifier is defined by the device tree binding of
> > +  the specific MSI controller. 
> > +
> > +
> > +MSI clients
> > +===========
> > +
> > +MSI clients are devices which generate MSIs. For each MSI they wish to
> > +generate, the doorbell and payload may be configured, though sideband
> > +information may not be configurable.
> > +
> > +Required properties:
> > +--------------------
> > +
> > +- msi-parent: A list of phandle + msi-specifier pairs, one for each MSI
> > +  controller which the device is capable of using.
> > +
> > +  This property is unordered, and MSIs may be allocated from any combination of
> > +  MSI controllers listed in the msi-parent property.
> > +
> > +  If a device has restrictions on the allocation of MSIs, these restrictions
> > +  must be described with additional properties.
> > +
> > +  When #msi-cells is non-zero, busses with an msi-parent will require
> > +  additional properties to describe the relationship between devices on the bus
> > +  and the set of MSIs they can potentially generate.
> > +
> > +
> > +Example
> > +=======
> > +
> > +/ {
> > +	#address-cells = <1>;
> > +	#size-cells = <1>;
> > +
> > +	msi_a: msi-controller at a {
> > +		reg = <0xa 0xf00>;
> > +		compatible = "vendor-a,some-controller";
> > +		msi-controller;
> > +		/* No sideband data, so #msi-cells omitted */
> > +	};
> > +
> > +	msi_b: msi-controller at b {
> > +		reg = <0xb 0xf00>;
> > +		compatible = "vendor-b,another-controller";
> > +		msi-controller;
> > +		/* Each device has some unique ID */
> > +		#msi-cells = <1>;
> > +	};
> > +
> > +	msi_c: msi-controller at c {
> > +		reg = <0xb 0xf00>;
> > +		compatible = "vendor-b,another-controller";
> > +		msi-controller;
> > +		/* Each device has some unique ID */
> > +		#msi-cells = <1>;
> > +	};
> > +
> > +	dev at 0 {
> > +		reg = <0x0 0xf00>;
> > +		compatible = "vendor-c,some-device";
> > +
> > +		/* Can only generate MSIs to msi_a */
> > +		msi-parent = <&msi_a>;
> > +	};
> > +
> > +	dev at 1 {
> > +		reg = <0x1 0xf00>;
> > +		compatible = "vendor-c,some-device";
> > +
> > +		/* 
> > +		 * Can generate MSIs to either A or B.
> > +		 */
> > +		msi-parent = <&msi_a>, <&msi_b 0x17>;
> > +	};
> > +
> > +	dev at 2 {
> > +		reg = <0x2 0xf00>;
> > +		compatible = "vendor-c,some-device";
> > +		/*
> > +		 * Has different IDs at each MSI controller.
> > +		 * Can generate MSIs to all of the MSI controllers.
> > +		 */
> > +		msi-parent = <&msi_a>, <&msi_b 0x17>, <&msi_c 0x53>;
> > +	};
> > +};
> > -- 
> > 1.9.1
> > 
> --
> To unsubscribe from this list: send the line "unsubscribe devicetree" in
> the body of a message to majordomo at vger.kernel.org
> More majordomo info at  http://vger.kernel.org/majordomo-info.html
> 


From haojian.zhuang at linaro.org  Mon Aug 24 03:19:56 2015
From: haojian.zhuang at linaro.org (Haojian Zhuang)
Date: Mon, 24 Aug 2015 18:19:56 +0800
Subject: [PATCH v1 3/3] arm64: dts: add Hi6220 mailbox node
In-Reply-To: <20150824095144.GA7139@leverpostej>
References: <1439977055-1747-1-git-send-email-leo.yan@linaro.org>
 <1439977055-1747-4-git-send-email-leo.yan@linaro.org>
 <20150821184059.GB2000@svinekod> <20150824091845.GA28290@leoy-linaro>
 <20150824095144.GA7139@leverpostej>
Message-ID: <1440411596.3517.12.camel@linaro.org>

On Mon, 2015-08-24 at 10:51 +0100, Mark Rutland wrote:
> On Mon, Aug 24, 2015 at 10:18:45AM +0100, Leo Yan wrote:
> > Hi Mark,
> > 
> > On Fri, Aug 21, 2015 at 07:40:59PM +0100, Mark Rutland wrote:
> > > On Wed, Aug 19, 2015 at 10:37:35AM +0100, Leo Yan wrote:
> > > > On Hi6220, below memory regions in DDR have specific purpose:
> > > > 
> > > >   0x05e0,0000 - 0x05ef,ffff: For MCU firmware using at runtime;
> > > >   0x0740,f000 - 0x0740,ffff: For MCU firmware's section;
> > > >   0x06df,f000 - 0x06df,ffff: For mailbox message data.
> > > > 
> > > > This patch reserves these memory regions and add device node for
> > > > mailbox in dts.
> > > > 
> > > > Signed-off-by: Leo Yan <leo.yan at linaro.org>
> > > > ---
> > > >  arch/arm64/boot/dts/hisilicon/hi6220-hikey.dts | 20 +++++++++++++++++---
> > > >  arch/arm64/boot/dts/hisilicon/hi6220.dtsi      |  8 ++++++++
> > > >  2 files changed, 25 insertions(+), 3 deletions(-)
> > > > 
> > > > diff --git a/arch/arm64/boot/dts/hisilicon/hi6220-hikey.dts b/arch/arm64/boot/dts/hisilicon/hi6220-hikey.dts
> > > > index e36a539..d5470d3 100644
> > > > --- a/arch/arm64/boot/dts/hisilicon/hi6220-hikey.dts
> > > > +++ b/arch/arm64/boot/dts/hisilicon/hi6220-hikey.dts
> > > > @@ -7,9 +7,6 @@
> > > >  
> > > >  /dts-v1/;
> > > >  
> > > > -/*Reserved 1MB memory for MCU*/
> > > > -/memreserve/ 0x05e00000 0x00100000;
> > > > -
> > > >  #include "hi6220.dtsi"
> > > >  
> > > >  / {
> > > > @@ -28,4 +25,21 @@
> > > >  		device_type = "memory";
> > > >  		reg = <0x0 0x0 0x0 0x40000000>;
> > > >  	};
> > > > +
> > > > +	reserved-memory {
> > > > +		#address-cells = <2>;
> > > > +		#size-cells = <2>;
> > > > +		ranges;
> > > > +
> > > > +		mcu-buf at 05e00000 {
> > > > +			no-map;
> > > > +			reg = <0x0 0x05e00000 0x0 0x00100000>,	/* MCU firmware buffer */
> > > > +			      <0x0 0x0740f000 0x0 0x00001000>;	/* MCU firmware section */
> > > > +		};
> > > > +
> > > > +		mbox-buf at 06dff000 {
> > > > +			no-map;
> > > > +			reg = <0x0 0x06dff000 0x0 0x00001000>;	/* Mailbox message buf */
> > > > +		};
> > > > +	};
> > > 
> > > As far as I can see, it would be simpler to simply carve these out of the
> > > memory node.
> > > 
> > > I don't see why you need reserved-memory here, given you're not referring to
> > > these regions by phandle anyway.
> > 
> > - Now we have enabled EFI_STUB, so the memory node will be removed in
> >   kernel:
> >     efi_entry()
> >       \-> allocate_new_fdt_and_exit_boot()
> >             \-> update_fdt();
> > 
> >   Finally in kernel it cannot use memory node to carve out reseved
> >   memory regions.
> > 
> > - On the other hand, DTS's the memory node is to "describes the
> >   physical memory layout for the system"; so it's better to use it only
> >   to describe the hardware info for memory. We can use reserved-memory
> >   to help manage the memory regions which are reserved from software
> >   perspective.
> 
> The fact that you have no-map means that the memory should not be
> described to the kernel as mappable in the first place. It's wrong to
> place such memory in the memory node, even if listed in reserved-memory.
> 
> If your EFI memory map describes the memory as mappable, it is wrong.

When kernel is working, kernel will create its own page table based on
UEFI memory map. Since it's reserved in DTS file as Leo's patch, it'll
be moved to reserved memblock. Why is it wrong?

In the second, UEFI is firmware. When it's stable, nobody should change
it without any reason. These reserved memory are used in mailbox driver.
Look. It's driver, so it could be changed at any time. Why do you want
to UEFI knowing this memory range? Do you hope UEFI to change when
mailbox driver is changed?

> 
> > According to upper info, we still need to use reserved-memory node to
> > depict the reserved memory regions. i have no knowledge about EFI_STUB,
> > so please confirm or correct as needed.
> 
> If the memory shouldn't be mapped, it should neither be in the memory
> node nor EFI memory map (with attributes allowing it to be mapped) to
> begin with.

As I said above, kernel will create its own page table. When kernel's
page table is working, UEFI's page table is destroying. So the memory
won't be mapped twice at the same time. What's wrong?
> 
> As far as I can see you do not need to use reserved-memory.

1. Are we talking on the same thing? Leo already mentioned that all
memory node in DTB will be destroyed by kernel when EFI_STUB is enabled
on arm. Did you read the source code after his reply?
And you suggested that Leo to use discrete memory region in DTB. It is
really wrong. Kernel only gets memory map information from UEFI, not
DTB.

2. The working flow is in below.
   a. Kernel gets memory map information from UEFI.
   b. Kernel loads the memory reserved information from DTB.

3. Do you mean the reserved-memory is totally wrong? If it's wrong,
please submit patches to remove all reserved-memory in linux kernel
first.

4. Again and again. Memory node should be only used to describe the
RAM information.



From marex at denx.de  Mon Aug 24 03:22:08 2015
From: marex at denx.de (Marek Vasut)
Date: Mon, 24 Aug 2015 12:22:08 +0200
Subject: [PATCH linux-next v4 4/5] Documentation: atmel-quadspi: add
 binding file for Atmel QSPI driver
In-Reply-To: <d45c21eab00863f379a0388b439a6ae5c44f7acc.1440410236.git.cyrille.pitchen@atmel.com>
References: <cover.1440410236.git.cyrille.pitchen@atmel.com>
 <d45c21eab00863f379a0388b439a6ae5c44f7acc.1440410236.git.cyrille.pitchen@atmel.com>
Message-ID: <201508241222.09095.marex@denx.de>

On Monday, August 24, 2015 at 12:13:59 PM, Cyrille Pitchen wrote:
> This patch documents the DT bindings for the driver of the Atmel QSPI
> controller embedded inside sama5d2x SoCs.
> 
> Signed-off-by: Cyrille Pitchen <cyrille.pitchen at atmel.com>
> Acked-by: Nicolas Ferre <nicolas.ferre at atmel.com>

If my ack has any value in here, feel free to add it, the bindings look
pretty standard anyway:

Acked-by: Marek Vasut <marex at denx.de>

Best regards,
Marek Vasut


From marex at denx.de  Mon Aug 24 03:16:20 2015
From: marex at denx.de (Marek Vasut)
Date: Mon, 24 Aug 2015 12:16:20 +0200
Subject: [PATCH linux-next v4 1/5] mtd: spi-nor: notify (Q)SPI controller
 about protocol change
In-Reply-To: <9649a13a50c33ef38045342353fc487a914ae337.1440410236.git.cyrille.pitchen@atmel.com>
References: <cover.1440410236.git.cyrille.pitchen@atmel.com>
 <9649a13a50c33ef38045342353fc487a914ae337.1440410236.git.cyrille.pitchen@atmel.com>
Message-ID: <201508241216.20506.marex@denx.de>

On Monday, August 24, 2015 at 12:13:56 PM, Cyrille Pitchen wrote:
> Once the Quad SPI mode has been enabled on a Micron flash memory, this
> device expects ALL the following commands to use the SPI 4-4-4 protocol.
> The (Q)SPI controller needs to be notified about the protocol change so it
> can adapt and keep on dialoging with the Micron memory.
> 
> Signed-off-by: Cyrille Pitchen <cyrille.pitchen at atmel.com>

Awesome,

Acked-by: Marek Vasut <marex at denx.de>

If this could be applied separately (since I want to use the same functionality
for the Cadence QSPI driver), I'd be really happy too :)

Best regards,
Marek Vasut


From heiko at sntech.de  Mon Aug 24 03:40:50 2015
From: heiko at sntech.de (Heiko Stuebner)
Date: Mon, 24 Aug 2015 12:40:50 +0200
Subject: [PATCH] ARM: rockchip: pm: Fix PTR_ERR() argument
In-Reply-To: <1439520199-16076-1-git-send-email-festevam@gmail.com>
References: <1439520199-16076-1-git-send-email-festevam@gmail.com>
Message-ID: <1521265.IE7qZF2mhh@phil>

Am Donnerstag, 13. August 2015, 23:43:19 schrieb Fabio Estevam:
> From: Fabio Estevam <fabio.estevam at freescale.com>
> 
> PTR_ERR should access the value just tested by IS_ERR.
> 
> The semantic patch that makes this change is available
> in scripts/coccinelle/tests/odd_ptr_err.cocci.
> 
> Signed-off-by: Fabio Estevam <fabio.estevam at freescale.com>

applied to my soc branch.


Thanks for the catch
Heiko


From marex at denx.de  Mon Aug 24 03:48:17 2015
From: marex at denx.de (Marek Vasut)
Date: Mon, 24 Aug 2015 12:48:17 +0200
Subject: [PATCH linux-next v4 3/5] mtd: spi-nor: allow to tune the number
 of dummy cycles
In-Reply-To: <b0d8470fdd46e89ef692e27dc2600b880c1d5dde.1440410236.git.cyrille.pitchen@atmel.com>
References: <cover.1440410236.git.cyrille.pitchen@atmel.com>
 <b0d8470fdd46e89ef692e27dc2600b880c1d5dde.1440410236.git.cyrille.pitchen@atmel.com>
Message-ID: <201508241248.17466.marex@denx.de>

On Monday, August 24, 2015 at 12:13:58 PM, Cyrille Pitchen wrote:
> The number of dummy cycles used during Fast Read commands can be reduced
> to improve transfer performances. Each manufacturer has a dedicated set of
> registers to provide the memory with the exact number of dummy cycles it
> should expect. Both the memory and the (Q)SPI controller must agree on
> this number of dummy cycles.
> 
> The number of dummy cycles can be found into the memory datasheet and
> mostly depends on the SPI clock frequency, the Fast Read op code and the
> Single/Dual Data Rate mode.
> 
> Probing JEDEC Serial Flash Discoverable Parameters (SFDP) tables would
> only provide the driver with a high enough number of dummy cycles for each
> Fast Read command to be used for all clock frequencies: this solution
> would not be optimized.
> 
> Signed-off-by: Cyrille Pitchen <cyrille.pitchen at atmel.com>

Hi!

>  drivers/mtd/spi-nor/spi-nor.c | 97
> ++++++++++++++++++++++++++++++++++--------- include/linux/mtd/spi-nor.h  
> |  2 +
>  2 files changed, 80 insertions(+), 19 deletions(-)
> 
> diff --git a/drivers/mtd/spi-nor/spi-nor.c b/drivers/mtd/spi-nor/spi-nor.c
> index e2a6029dc056..869e098a6841 100644
> --- a/drivers/mtd/spi-nor/spi-nor.c
> +++ b/drivers/mtd/spi-nor/spi-nor.c
> @@ -119,24 +119,6 @@ static int read_cr(struct spi_nor *nor)
>  }
> 
>  /*
> - * Dummy Cycle calculation for different type of read.
> - * It can be used to support more commands with
> - * different dummy cycle requirements.
> - */
> -static inline int spi_nor_read_dummy_cycles(struct spi_nor *nor)
> -{
> -	switch (nor->flash_read) {
> -	case SPI_NOR_FAST:
> -	case SPI_NOR_DUAL:
> -	case SPI_NOR_QUAD:
> -		return 8;
> -	case SPI_NOR_NORMAL:
> -		return 0;
> -	}
> -	return 0;
> -}

You can probably just soup up this function so that it sets the
nor->read_dummy, no ?

> -/*
>   * Write status register 1 byte
>   * Returns negative if error occurred.
>   */
> @@ -1012,6 +994,81 @@ static int set_quad_mode(struct spi_nor *nor, struct
> flash_info *info) }
>  }
> 
> +static int micron_set_dummy_cycles(struct spi_nor *nor)
> +{
> +	int ret;
> +	u8 val, mask;
> +
> +	/* read the Volatile Configuration Register (VCR) */

NIT: If this is a sentence, start it with capital letter and end it with 
fullstop :)

> +	ret = nor->read_reg(nor, SPINOR_OP_RD_VCR, &val, 1);
> +	if (ret < 0) {
> +		dev_err(nor->dev, "error %d reading VCR\n", ret);
> +		return ret;
> +	}
> +
> +	write_enable(nor);
> +
> +	/* update the number of dummy into the VCR */

DTTO

> +	mask = GENMASK(7, 4);
> +	val &= ~mask;
> +	val |= (nor->read_dummy << 4) & mask;
> +	ret = nor->write_reg(nor, SPINOR_OP_WR_VCR, &val, 1, 0);
> +	if (ret < 0) {
> +		dev_err(nor->dev, "error while writing VCR register\n");
> +		return ret;
> +	}
> +
> +	ret = spi_nor_wait_till_ready(nor);
> +	if (ret)
> +		return ret;
> +
> +	return 0;
> +}
> +
> +/*
> + * Dummy Cycle calculation for different type of read.
> + * It can be used to support more commands with
> + * different dummy cycle requirements.
> + */
> +static int spi_nor_read_dummy_cycles(struct spi_nor *nor,
> +				     const struct flash_info *info)
> +{
> +	struct device_node *np = nor->dev->of_node;
> +	u32 num_dummy_cycles;
> +
> +	if (np && !of_property_read_u32(np, "m25p,num-dummy-cycles",
> +					&num_dummy_cycles)) {
> +		nor->read_dummy = num_dummy_cycles;
> +
> +		/*
> +		 * This switch block might be moved after the if...then...else
> +		 * statement but it was not tested with all Spansion or Micron
> +		 * memories.
> +		 * Now the "m25p,num-dummy-cycles" property needs to be
> +		 * explicitly set in the device tree so the switch statement is
> +		 * executed. This should avoid unwanted side effects and keep
> +		 * backward compatibility.
> +		 */
> +		switch (JEDEC_MFR(info)) {
> +		case CFI_MFR_ST:
> +			return micron_set_dummy_cycles(nor);
> +		default:

If you do have m25p,num-dummy-cycles set for non-micron flash, you have a 
problem here I believe.

> +			break;
> +		}
> +	} else {

The solution would be to drop this else {} bit here, so that if you fail in
the DT-based configuration, you fall back to this old behavior. What do you 
think please ? :)

> +		switch (nor->flash_read) {
> +		case SPI_NOR_FAST:
> +		case SPI_NOR_DUAL:
> +		case SPI_NOR_QUAD:
> +			nor->read_dummy = 8;
> +		case SPI_NOR_NORMAL:
> +			nor->read_dummy = 0;
> +		}
> +	}
> +
> +	return 0;
> +}

[...]


From linux at arm.linux.org.uk  Mon Aug 24 03:55:01 2015
From: linux at arm.linux.org.uk (Russell King - ARM Linux)
Date: Mon, 24 Aug 2015 11:55:01 +0100
Subject: ahci_imx: can read corrupted data successfully
Message-ID: <20150824105501.GX7557@n2100.arm.linux.org.uk>

I've no idea how this is happening, but it appears that it's possible
to read corrupted data over an eSATA link.

The setup is a Solid-run Cubox-i4pro connected to an external eSATA 2.5"
enclosure with a Corsair Neutron 128GB SSD.

While the issue seems to be the generally poor quality of eSATA cables
(I have two eSATA enclosures, the other enclosure's eSATA cable
interferes with a Logitech wireless receiver - I've had to wrap the
cable in aluminium foil.)  However, it shouldn't be possible to
successfully read faulty data in that condition - and this is what I
find most worrying.

What I've noticed is that at boot, the the SSD is sometimes properly
detected, other times it isn't:

[reboot at 10am]

ata1: softreset failed (device not ready)
ata1: SATA link up 3.0 Gbps (SStatus 123 SControl 300)
ata1.00: ATA-8: Corsair Neutron SSD, M311, max UDMA/133
ata1.00: 250069680 sectors, multi 1: LBA48 NCQ (depth 31/32)
ata1.00: configured for UDMA/133
scsi 0:0:0:0: Direct-Access     ATA      Corsair Neutron  M311 PQ: 0 ANSI: 5
sd 0:0:0:0: [sda] 250069680 512-byte logical blocks: (128 GB/119 GiB)
sd 0:0:0:0: [sda] Write Protect is off
sd 0:0:0:0: [sda] Mode Sense: 00 3a 00 00
sd 0:0:0:0: [sda] Write cache: enabled, read cache: enabled, doesn't support DPO
 sda: sda1 sda2 sda3
sd 0:0:0:0: [sda] Attached SCSI disk

[half an hour passes and a reboot later]

ata1: SATA link up 3.0 Gbps (SStatus 123 SControl 300)
ata1.00: ATA-8: , , max UDMA/133
ata1.00: 250069680 sectors, multi 1: LBA48
ata1.00: configured for UDMA/133
scsi 0:0:0:0: Direct-Access     ATA                       n/a  PQ: 0 ANSI: 5
sd 0:0:0:0: [sda] 250069680 512-byte logical blocks: (128 GB/119 GiB)
sd 0:0:0:0: [sda] Write Protect is off
sd 0:0:0:0: [sda] Mode Sense: 00 3a 00 00
sd 0:0:0:0: [sda] Write cache: enabled, read cache: enabled, doesn't support DPO
sd 0:0:0:0: [sda] Attached SCSI disk

[replugging the eSATA connector]

ata1: exception Emask 0x10 SAct 0x0 SErr 0x4050002 action 0xe frozen
ata1: irq_stat 0x00000040, connection status changed
ata1: SError: { RecovComm PHYRdyChg CommWake DevExch }
ata1: hard resetting link
ata1: SATA link up 3.0 Gbps (SStatus 123 SControl 300)
ata1.00: ATA-8: Corsair Neutron SSD, M311, max UDMA/133
ata1.00: 250069680 sectors, multi 1: LBA48 NCQ (depth 31/32)
ata1.00: configured for UDMA/133
ata1: EH complete
scsi 0:0:0:0: Direct-Access     ATA      Corsair Neutron  M311 PQ: 0 ANSI: 5
sd 0:0:0:0: [sda] 250069680 512-byte logical blocks: (128 GB/119 GiB)
sd 0:0:0:0: [sda] Write Protect is off
sd 0:0:0:0: [sda] Mode Sense: 00 3a 00 00
sd 0:0:0:0: [sda] Write cache: enabled, read cache: enabled, doesn't support DPO
 sda: sda1 sda2 sda3
sd 0:0:0:0: [sda] Attached SCSI disk

[another reboot]

ata1: SATA link up 3.0 Gbps (SStatus 123 SControl 300)
ata1.00: ATA-8: Corsair Neutron SSD, M311, max UDMA/133
ata1.00: 250069680 sectors, multi 1: LBA48 NCQ (depth 31/32)
ata1.00: configured for UDMA/133
scsi 0:0:0:0: Direct-Access     ATA      Corsair Neutron  M311 PQ: 0 ANSI: 5
sd 0:0:0:0: [sda] 250069680 512-byte logical blocks: (128 GB/119 GiB)
sd 0:0:0:0: [sda] Write Protect is off
sd 0:0:0:0: [sda] Mode Sense: 00 3a 00 00
sd 0:0:0:0: [sda] Write cache: enabled, read cache: enabled, doesn't support DPO
 sda: sda1 sda2 sda3
sd 0:0:0:0: [sda] Attached SCSI disk

When the SSD is mis-detected, as can be seen above, the partition table
isn't recognised.  Reading sector 0 shows:

00000000  18 f0 9f e5 18 f0 9f e5  18 f0 9f e5 18 f0 9f e5  |................|
00000010  18 f0 9f e5 00 00 a0 e1  14 f0 9f e5 14 f0 9f e5  |................|
00000020  f8 09 00 00 3c 00 00 00  40 00 00 00 1c f2 00 00  |....<... at .......|
00000030  04 f2 00 00 5c 12 00 00  90 12 00 00 fe ff ff ea  |....\...........|
00000040  fe ff ff ea 00 00 00 ea  da 0d 00 ea 28 00 8f e2  |............(...|
00000050  00 0c 90 e8 00 a0 8a e0  01 70 4a e2 00 b0 8b e0  |.........pJ.....|

which is some ARM code - it looks like early boot code, code which would
normally be found in the vector page.

What should be there is the partition table:

00000000  00 00 00 00 00 00 00 00  00 00 00 00 00 00 00 00  |................|
*
000001b0  00 00 00 00 00 00 00 00  bf 64 9b 0b 00 00 00 20  |.........d..... |
000001c0  21 00 83 53 09 0a 00 08  00 00 00 80 02 00 00 53  |!..S...........S|
000001d0  0a 0a 83 a8 0a 1e 00 88  02 00 00 00 00 01 00 a8  |................|
000001e0  0b 1e 83 1d 3f ce 00 88  02 01 b0 3a e5 0d 00 00  |....?......:....|
000001f0  00 00 00 00 00 00 00 00  00 00 00 00 00 00 55 aa  |..............U.|

The SSD has had no ARM executables copied on to it since it was
purchased.  It contains a DOS partition and swap space, so it's possible
that the swap space could have had ARM code swapped to it.  Grepping the
swap partition for the initial sequence of 8 bytes (18 f0 9f e5 18 f0 9f
e5) gives nothing.

Another possibility is we didn't actually read any data from the SSD at
all but ended up copying it from somewhere else.  As I say above, it
looks like what one would expect to find in the ARM vector page.  It
doesn't tie up with the iMX6 ROM nor the uboot image in the SD card.
It's not the kernel's vectors either.  It could be the SSD firmware (I
haven't checked, but I wouldn't be surprised if the SSD has an ARM CPU
on it) but that would point towards a very weird failure of the SSD -
though not if it's receiving corrupted commands and there was no
verification of those commands.  Without a firmware image of the SSD
(which isn't going to be possible to get hold of) it's impossible to
know.

What concerns me is that this incorrect data was successfully read
allegedly from the device.  What happens if a write were to occur -
what would we be writing to?

Also, clearly the identify information is definitely screwed, although
some of it does seem to be correct, such as the capacity, but the
device identifiers are broken.

How does SATA ensure command and data integrity over the link?  I'd
assume that there's a CRC present on the data, like UDMA on PATA.  How
are CRC errors supposed to be reported?  Is it possible that ahci_imx
and other layers are not properly checking for CRC errors?

Any ideas what to look at?

Anyone got any suggestions on where to get a good quality, but not
stupidly expensive eSATA cable from?

I'm waiting for it to happen again, and I'll dump out more of the drive's
"contents" when the cable is bad.  If it is the drive's firmware, it
should contain the manufacturer name/model somewhere in the image.

-- 
FTTC broadband for 0.8mile line: currently at 10.5Mbps down 400kbps up
according to speedtest.net.


From s.hauer at pengutronix.de  Mon Aug 24 03:59:56 2015
From: s.hauer at pengutronix.de (Sascha Hauer)
Date: Mon, 24 Aug 2015 12:59:56 +0200
Subject: [PATCH] soc: mediatek: add scpsys support active_wakeup
In-Reply-To: <1437631249-706-1-git-send-email-eddie.huang@mediatek.com>
References: <1437631249-706-1-git-send-email-eddie.huang@mediatek.com>
Message-ID: <20150824105956.GT5161@pengutronix.de>

On Thu, Jul 23, 2015 at 02:00:49PM +0800, Eddie Huang wrote:
> Register gpd_dev_ops.active_wakeup function to support keep power
> during suspend state. And add flag to each power domain to
> decide whether keep power during suspend or not.
> 
> Signed-off-by: Chunfeng Yun <chunfeng.yun at mediatek.com>
> Signed-off-by: Eddie Huang <eddie.huang at mediatek.com>
> ---
>  drivers/soc/mediatek/mtk-scpsys.c | 28 ++++++++++++++++++++++++++++
>  1 file changed, 28 insertions(+)
> 
> diff --git a/drivers/soc/mediatek/mtk-scpsys.c b/drivers/soc/mediatek/mtk-scpsys.c
> index 43a79ed..fc78b70 100644
> --- a/drivers/soc/mediatek/mtk-scpsys.c
> +++ b/drivers/soc/mediatek/mtk-scpsys.c
> @@ -67,6 +67,7 @@ struct scp_domain_data {
>  	u32 sram_pdn_ack_bits;
>  	u32 bus_prot_mask;
>  	enum clk_id clk_id;
> +	bool active_wakeup;
>  };
>  
>  static const struct scp_domain_data scp_domain_data[] __initconst = {
> @@ -77,6 +78,7 @@ static const struct scp_domain_data scp_domain_data[] __initconst = {
>  		.sram_pdn_bits = GENMASK(11, 8),
>  		.sram_pdn_ack_bits = GENMASK(12, 12),
>  		.clk_id = MT8173_CLK_MM,
> +		.active_wakeup = false,

You can drop the .active_wakeup = false lines.

Otherwise:

Acked-by: Sascha Hauer <s.hauer at pengutronix.de>

Sascha


-- 
Pengutronix e.K.                           |                             |
Industrial Linux Solutions                 | http://www.pengutronix.de/  |
Peiner Str. 6-8, 31137 Hildesheim, Germany | Phone: +49-5121-206917-0    |
Amtsgericht Hildesheim, HRA 2686           | Fax:   +49-5121-206917-5555 |


From marex at denx.de  Mon Aug 24 04:03:51 2015
From: marex at denx.de (Marek Vasut)
Date: Mon, 24 Aug 2015 13:03:51 +0200
Subject: [PATCH linux-next v4 5/5] mtd: atmel-quadspi: add driver for
 Atmel QSPI controller
In-Reply-To: <bf368fc101f38db231131b69eff0863210f2b01c.1440410236.git.cyrille.pitchen@atmel.com>
References: <cover.1440410236.git.cyrille.pitchen@atmel.com>
 <bf368fc101f38db231131b69eff0863210f2b01c.1440410236.git.cyrille.pitchen@atmel.com>
Message-ID: <201508241303.52066.marex@denx.de>

On Monday, August 24, 2015 at 12:14:00 PM, Cyrille Pitchen wrote:
> This driver add support to the new Atmel QSPI controller embedded into
> sama5d2x SoCs. It expects a NOR memory to be connected to the QSPI
> controller.
> 
> Signed-off-by: Cyrille Pitchen <cyrille.pitchen at atmel.com>
> Acked-by: Nicolas Ferre <nicolas.ferre at atmel.com>

Hi,

[...]

> +/* Register access macros */

These are functions, not macros :)

btw is there any reason for these ? I'd say, just put the read*() and
write*() functions directly into the code and be done with it, it is
much less confusing.

Also, why do you use the _relaxed() versions of the functions ?

> +static inline u32 qspi_readl(struct atmel_qspi *aq, u32 reg)
> +{
> +	return readl_relaxed(aq->regs + reg);
> +}
> +
> +static inline void qspi_writel(struct atmel_qspi *aq, u32 reg, u32 value)
> +{
> +	writel_relaxed(value, aq->regs + reg);
> +}
> +
> +static inline u16 qspi_readw(struct atmel_qspi *aq, u32 reg)
> +{
> +	return readw_relaxed(aq->regs + reg);
> +}
> +
> +static inline void qspi_writew(struct atmel_qspi *aq, u32 reg, u16 value)
> +{
> +	writew_relaxed(value, aq->regs + reg);
> +}
> +
> +static inline u8 qspi_readb(struct atmel_qspi *aq, u32 reg)
> +{
> +	return readb_relaxed(aq->regs + reg);
> +}
> +
> +static inline void qspi_writeb(struct atmel_qspi *aq, u32 reg, u8 value)
> +{
> +	writeb_relaxed(value, aq->regs + reg);
> +}

[...]

> +static int atmel_qspi_run_command(struct atmel_qspi *aq,
> +				  const struct atmel_qspi_command *cmd)
> +{
> +	u32 iar, icr, ifr, sr;
> +	int err = 0;
> +
> +	iar = 0;
> +	icr = 0;
> +	ifr = aq->ifr_width | cmd->ifr_tfrtyp;
> +
> +	/* Compute instruction parameters */
> +	if (cmd->enable.bits.instruction) {
> +		icr |= QSPI_ICR_INST(cmd->instruction);
> +		ifr |= QSPI_IFR_INSTEN;
> +	}
> +
> +	/* Compute address parameters */
> +	switch (cmd->enable.bits.address) {
> +	case 4:
> +		ifr |= QSPI_IFR_ADDRL;
> +		/*break;*/ /* fallback to the 24bit address case */

What's this commented out bit of code for ? :-)

> +	case 3:
> +		iar = (cmd->enable.bits.data) ? 0 : cmd->address;
> +		ifr |= QSPI_IFR_ADDREN;
> +		break;
> +	case 0:
> +		break;
> +	default:
> +		return -EINVAL;
> +	}

[...]

> +no_data:
> +	/* Poll INSTRuction End status */
> +	sr = qspi_readl(aq, QSPI_SR);
> +	if (sr & QSPI_SR_INSTRE)
> +		return err;
> +
> +	/* Wait for INSTRuction End interrupt */
> +	init_completion(&aq->completion);

You should use reinit_completion() in the code. init_completion()
should be used only in the probe() function and nowhere else.

> +	aq->pending = 0;
> +	qspi_writel(aq, QSPI_IER, QSPI_SR_INSTRE);
> +	if (!wait_for_completion_timeout(&aq->completion,
> +					 msecs_to_jiffies(1000)))
> +		err = -ETIMEDOUT;
> +	qspi_writel(aq, QSPI_IDR, QSPI_SR_INSTRE);
> +
> +	return err;
> +}

[...]

Hope this helps :)


From maxime.ripard at free-electrons.com  Mon Aug 24 04:16:58 2015
From: maxime.ripard at free-electrons.com (Maxime Ripard)
Date: Mon, 24 Aug 2015 13:16:58 +0200
Subject: [PATCH 1/3] ARM: dts: sun5i: Add support for the Auxtek-T003
 HDMI stick
In-Reply-To: <1438960955-6551-1-git-send-email-hdegoede@redhat.com>
References: <1438960955-6551-1-git-send-email-hdegoede@redhat.com>
Message-ID: <20150824111658.GJ2413@lukather>

On Fri, Aug 07, 2015 at 05:22:33PM +0200, Hans de Goede wrote:
> The Auxtek-T003 HDMI stick is an A10s based HDMI stick with USB wifi,
> and composite video out support.
> 
> Signed-off-by: Hans de Goede <hdegoede at redhat.com>

Applied, thanks!

Maxime

-- 
Maxime Ripard, Free Electrons
Embedded Linux, Kernel and Android engineering
http://free-electrons.com
-------------- next part --------------
A non-text attachment was scrubbed...
Name: signature.asc
Type: application/pgp-signature
Size: 819 bytes
Desc: Digital signature
URL: <http://lists.infradead.org/pipermail/linux-arm-kernel/attachments/20150824/ece8275d/attachment.sig>

From lee.jones at linaro.org  Mon Aug 24 04:48:33 2015
From: lee.jones at linaro.org (Lee Jones)
Date: Mon, 24 Aug 2015 12:48:33 +0100
Subject: [PATCH v4 1/4] mfd: max77686: Don't suggest in binding to use a
 deprecated property
In-Reply-To: <1440406041-25071-2-git-send-email-javier@osg.samsung.com>
References: <1440406041-25071-1-git-send-email-javier@osg.samsung.com>
 <1440406041-25071-2-git-send-email-javier@osg.samsung.com>
Message-ID: <20150824114833.GA3237@x1>

On Mon, 24 Aug 2015, Javier Martinez Canillas wrote:

> The regulator-compatible property from the regulator DT binding was
> deprecated. But the max77686 DT binding doc still suggest to use it
> instead of the regulator node name's which is the correct approach.
> 
> Signed-off-by: Javier Martinez Canillas <javier at osg.samsung.com>
> Reviewed-by: Krzysztof Kozlowski <k.kozlowski at samsung.com>
> Acked-by: Lee Jones <lee.jones at linaro.org>
> 
> ---
> 
> Changes in v4:
> - Add Lee Jones Acked-by tag to patch #1.
> 
> Changes in v3: None
> Changes in v2:
> - Add Krzysztof Kozlowski Reviewed-by tag to patch #1.
> 
>  Documentation/devicetree/bindings/mfd/max77686.txt | 11 ++++-------
>  1 file changed, 4 insertions(+), 7 deletions(-)

Applied, thanks.

> diff --git a/Documentation/devicetree/bindings/mfd/max77686.txt b/Documentation/devicetree/bindings/mfd/max77686.txt
> index 163bd81a4607..8221102d3fc2 100644
> --- a/Documentation/devicetree/bindings/mfd/max77686.txt
> +++ b/Documentation/devicetree/bindings/mfd/max77686.txt
> @@ -26,7 +26,7 @@ Optional node:
>  	};
>  	refer Documentation/devicetree/bindings/regulator/regulator.txt
>  
> -  The regulator-compatible property of regulator should initialized with string
> +  The regulator node's name should be initialized with a string
>  to get matched with their hardware counterparts as follow:
>  
>  	-LDOn 	:	for LDOs, where n can lie in range 1 to 26.
> @@ -55,16 +55,14 @@ Example:
>  		reg = <0x09>;
>  
>  		voltage-regulators {
> -			ldo11_reg {
> -				regulator-compatible = "LDO11";
> +			ldo11_reg: LDO11 {
>  				regulator-name = "vdd_ldo11";
>  				regulator-min-microvolt = <1900000>;
>  				regulator-max-microvolt = <1900000>;
>  				regulator-always-on;
>  			};
>  
> -			buck1_reg {
> -				regulator-compatible = "BUCK1";
> +			buck1_reg: BUCK1 {
>  				regulator-name = "vdd_mif";
>  				regulator-min-microvolt = <950000>;
>  				regulator-max-microvolt = <1300000>;
> @@ -72,8 +70,7 @@ Example:
>  				regulator-boot-on;
>  			};
>  
> -			buck9_reg {
> -				regulator-compatible = "BUCK9";
> +			buck9_reg: BUCK9 {
>  				regulator-name = "CAM_ISP_CORE_1.2V";
>  				regulator-min-microvolt = <1000000>;
>  				regulator-max-microvolt = <1200000>;

-- 
Lee Jones
Linaro STMicroelectronics Landing Team Lead
Linaro.org ? Open source software for ARM SoCs
Follow Linaro: Facebook | Twitter | Blog


From lee.jones at linaro.org  Mon Aug 24 04:48:48 2015
From: lee.jones at linaro.org (Lee Jones)
Date: Mon, 24 Aug 2015 12:48:48 +0100
Subject: [PATCH v4 2/4] mfd: max77686: Use a generic name for the PMIC
 node in the example
In-Reply-To: <1440406041-25071-3-git-send-email-javier@osg.samsung.com>
References: <1440406041-25071-1-git-send-email-javier@osg.samsung.com>
 <1440406041-25071-3-git-send-email-javier@osg.samsung.com>
Message-ID: <20150824114848.GB3237@x1>

On Mon, 24 Aug 2015, Javier Martinez Canillas wrote:

> The ePAPR standard says that: "the name of a node should be somewhat
> generic, reflecting the function of the device and not its precise
> programming model."
> 
> So, change the max77686 binding document example to use a generic
> node name instead of using the chip's name.
> 
> Suggested-by: Sergei Shtylyov <sergei.shtylyov at cogentembedded.com>
> Signed-off-by: Javier Martinez Canillas <javier at osg.samsung.com>
> Acked-by: Lee Jones <lee.jones at linaro.org>
> 
> ---
> 
> Changes in v4:
> - Add Lee Jones Acked-by tag to patch #2.
> 
> Changes in v3:
> - Fix typo in ePAPR document name. Suggested by Sergei Shtylyov
> 
> Changes in v2: None
> 
>  Documentation/devicetree/bindings/mfd/max77686.txt | 2 +-
>  1 file changed, 1 insertion(+), 1 deletion(-)

Applied, thanks.

> diff --git a/Documentation/devicetree/bindings/mfd/max77686.txt b/Documentation/devicetree/bindings/mfd/max77686.txt
> index 8221102d3fc2..d2ed3c20a5c3 100644
> --- a/Documentation/devicetree/bindings/mfd/max77686.txt
> +++ b/Documentation/devicetree/bindings/mfd/max77686.txt
> @@ -48,7 +48,7 @@ to get matched with their hardware counterparts as follow:
>  
>  Example:
>  
> -	max77686 at 09 {
> +	max77686: pmic at 09 {
>  		compatible = "maxim,max77686";
>  		interrupt-parent = <&wakeup_eint>;
>  		interrupts = <26 0>;

-- 
Lee Jones
Linaro STMicroelectronics Landing Team Lead
Linaro.org ? Open source software for ARM SoCs
Follow Linaro: Facebook | Twitter | Blog


From lee.jones at linaro.org  Mon Aug 24 04:49:01 2015
From: lee.jones at linaro.org (Lee Jones)
Date: Mon, 24 Aug 2015 12:49:01 +0100
Subject: [PATCH v4 3/4] mfd: Add DT binding for Maxim MAX77802 IC
In-Reply-To: <1440406041-25071-4-git-send-email-javier@osg.samsung.com>
References: <1440406041-25071-1-git-send-email-javier@osg.samsung.com>
 <1440406041-25071-4-git-send-email-javier@osg.samsung.com>
Message-ID: <20150824114901.GC3237@x1>

On Mon, 24 Aug 2015, Javier Martinez Canillas wrote:

> The MAX77802 is a chip that contains regulators, 2 32kHz clocks,
> a RTC and an I2C interface to program the individual components.
> 
> The are already DT bindings for the regulators and clocks and
> these reference to a bindings/mfd/max77802.txt file, that didn't
> exist, for the details about the PMIC.
> 
> Signed-off-by: Javier Martinez Canillas <javier at osg.samsung.com>
> Reviewed-by: Krzysztof Kozlowski <k.kozlowski at samsung.com>
> 
> ---
> 
> Changes in v4:
> - Reword section about max77802 clock and regulator DT binding docs.
>   Suggested by Lee Jones.
> - Align max77802 mfd required properties. Suggested by Lee Jones.
> 
> Changes in v3:
> - Add Krzysztof Kozlowski Reviewed-by tag to patch #3.
> - Capitalise all acronyms. Suggested by Lee Jones.
> - Use relative path to refer other bindings. Suggested by Lee Jones.
> - Use IRQ_TYPE_NONE instead of 0 in example. Suggested by Lee Jones.
> 
> Changes in v2:
> - Use the correct "maxim,max77802" compatible string.
>   Suggested by Krzysztof Kozlowski
> - Use a pmic generic node name for the max77802 node example.
>   Suggested by Sergei Shtylyov.
> 
>  Documentation/devicetree/bindings/mfd/max77802.txt | 26 ++++++++++++++++++++++
>  1 file changed, 26 insertions(+)
>  create mode 100644 Documentation/devicetree/bindings/mfd/max77802.txt

Applied, thanks.

> diff --git a/Documentation/devicetree/bindings/mfd/max77802.txt b/Documentation/devicetree/bindings/mfd/max77802.txt
> new file mode 100644
> index 000000000000..51fc1a60caa5
> --- /dev/null
> +++ b/Documentation/devicetree/bindings/mfd/max77802.txt
> @@ -0,0 +1,26 @@
> +Maxim MAX77802 multi-function device
> +
> +The Maxim MAX77802 is a Power Management IC (PMIC) that contains 10 high
> +efficiency Buck regulators, 32 Low-DropOut (LDO) regulators used to power
> +up application processors and peripherals, a 2-channel 32kHz clock outputs,
> +a Real-Time-Clock (RTC) and a I2C interface to program the individual
> +regulators, clocks outputs and the RTC.
> +
> +Bindings for the built-in 32k clock generator block and
> +regulators are defined in ../clk/maxim,max77802.txt and
> +../regulator/max77802.txt respectively.
> +
> +Required properties:
> +- compatible		: Must be "maxim,max77802"
> +- reg			: Specifies the I2C slave address of PMIC block.
> +- interrupts		: I2C device IRQ line connected to the main SoC.
> +- interrupt-parent	: The parent interrupt controller.
> +
> +Example:
> +
> +	max77802: pmic at 09 {
> +		compatible = "maxim,max77802";
> +		interrupt-parent = <&intc>;
> +		interrupts = <26 IRQ_TYPE_NONE>;
> +		reg = <0x09>;
> +	};

-- 
Lee Jones
Linaro STMicroelectronics Landing Team Lead
Linaro.org ? Open source software for ARM SoCs
Follow Linaro: Facebook | Twitter | Blog


From leif.lindholm at linaro.org  Mon Aug 24 04:49:03 2015
From: leif.lindholm at linaro.org (Leif Lindholm)
Date: Mon, 24 Aug 2015 12:49:03 +0100
Subject: [PATCH v1 3/3] arm64: dts: add Hi6220 mailbox node
In-Reply-To: <1440411596.3517.12.camel@linaro.org>
References: <1439977055-1747-1-git-send-email-leo.yan@linaro.org>
 <1439977055-1747-4-git-send-email-leo.yan@linaro.org>
 <20150821184059.GB2000@svinekod>
 <20150824091845.GA28290@leoy-linaro>
 <20150824095144.GA7139@leverpostej>
 <1440411596.3517.12.camel@linaro.org>
Message-ID: <20150824114903.GT10728@bivouac.eciton.net>

On Mon, Aug 24, 2015 at 06:19:56PM +0800, Haojian Zhuang wrote:
> > If your EFI memory map describes the memory as mappable, it is wrong.
> 
> When kernel is working, kernel will create its own page table based on
> UEFI memory map. Since it's reserved in DTS file as Leo's patch, it'll
> be moved to reserved memblock. Why is it wrong?
> 
> In the second, UEFI is firmware. When it's stable, nobody should change
> it without any reason.

Much like the memory map.

> These reserved memory are used in mailbox driver.
> Look. It's driver, so it could be changed at any time.

No, it is a set of regions of memory set aside for use by a different
master in the system as well as communications with that master.

The fact that there is a driver somewhere that is aware of this is
entirely beside the point. All agents in the system must adher to this
protocol.

> Why do you want
> to UEFI knowing this memory range? Do you hope UEFI to change when
> mailbox driver is changed?

Yes.

UEFI is a runtime environment. Having random magic areas not to be
touched will cause random pieces of software running under it to break
horribly or break other things horribly.
Unless you mark them as reserved in the UEFI memory map.
At which point the Linux kernel will automatically ignore them, and
the proposed patch is redundant.

So, yes, if you want a system that can boot reliably, run testsuites
(like SCT or FWTS), run applications (like fastboot ... or the EFI
stub kernel itself), then any memory regions that is reserved for
mailbox communication (or other masters in the system) _must_ be
marked in the EFI memory map.

/
    Leif


From lee.jones at linaro.org  Mon Aug 24 04:49:14 2015
From: lee.jones at linaro.org (Lee Jones)
Date: Mon, 24 Aug 2015 12:49:14 +0100
Subject: [PATCH v4 4/4] mfd: max77686: Split out regulator part from the
 DT binding
In-Reply-To: <1440406041-25071-5-git-send-email-javier@osg.samsung.com>
References: <1440406041-25071-1-git-send-email-javier@osg.samsung.com>
 <1440406041-25071-5-git-send-email-javier@osg.samsung.com>
Message-ID: <20150824114914.GD3237@x1>

On Mon, 24 Aug 2015, Javier Martinez Canillas wrote:

> The Maxim MAX77686 PMIC is a multi-function device with regulators,
> clocks and a RTC. The DT bindings for the clocks are in a separate
> file but the bindings for the regulators are inside the mfd part.
> 
> To make it consistent with the clocks portion of the binding and
> because is more natural to look for regulator bindings under the
> bindings/regulator sub-directory, split the regulator portion of
> the DT binding and add it as a separate file.
> 
> Signed-off-by: Javier Martinez Canillas <javier at osg.samsung.com>
> Reviewed-by: Krzysztof Kozlowski <k.kozlowski at samsung.com>
> Acked-by: Lee Jones <lee.jones at linaro.org>
> 
> ---
> 
> Changes in v4: None
> Changes in v3:
> - Add Krzysztof Kozlowski Reviewed-by tag to patch #4.
> - Add Lee Jones Acked-by tag to patch #4.
> 
> Changes in v2:
> - Use a generic name for the max77686 node in the regulator example.
> 
>  Documentation/devicetree/bindings/mfd/max77686.txt | 60 ++----------------
>  .../devicetree/bindings/regulator/max77686.txt     | 71 ++++++++++++++++++++++
>  2 files changed, 75 insertions(+), 56 deletions(-)
>  create mode 100644 Documentation/devicetree/bindings/regulator/max77686.txt

Applied, thanks.

> diff --git a/Documentation/devicetree/bindings/mfd/max77686.txt b/Documentation/devicetree/bindings/mfd/max77686.txt
> index d2ed3c20a5c3..741e76688cf2 100644
> --- a/Documentation/devicetree/bindings/mfd/max77686.txt
> +++ b/Documentation/devicetree/bindings/mfd/max77686.txt
> @@ -7,8 +7,9 @@ different i2c slave address,presently for which we are statically creating i2c
>  client while probing.This document describes the binding for mfd device and
>  PMIC submodule.
>  
> -Binding for the built-in 32k clock generator block is defined separately
> -in bindings/clk/maxim,max77686.txt file.
> +Bindings for the built-in 32k clock generator block and
> +regulators are defined in ../clk/maxim,max77686.txt and
> +../regulator/max77686.txt respectively.
>  
>  Required properties:
>  - compatible : Must be "maxim,max77686";
> @@ -16,36 +17,6 @@ Required properties:
>  - interrupts : This i2c device has an IRQ line connected to the main SoC.
>  - interrupt-parent : The parent interrupt controller.
>  
> -Optional node:
> -- voltage-regulators : The regulators of max77686 have to be instantiated
> -  under subnode named "voltage-regulators" using the following format.
> -
> -	regulator_name {
> -		regulator-compatible = LDOn/BUCKn
> -		standard regulator constraints....
> -	};
> -	refer Documentation/devicetree/bindings/regulator/regulator.txt
> -
> -  The regulator node's name should be initialized with a string
> -to get matched with their hardware counterparts as follow:
> -
> -	-LDOn 	:	for LDOs, where n can lie in range 1 to 26.
> -		 	example: LDO1, LDO2, LDO26.
> -	-BUCKn 	:	for BUCKs, where n can lie in range 1 to 9.
> -			example: BUCK1, BUCK5, BUCK9.
> -
> -  Regulators which can be turned off during system suspend:
> -	-LDOn	:	2, 6-8, 10-12, 14-16,
> -	-BUCKn	:	1-4.
> -  Use standard regulator bindings for it ('regulator-off-in-suspend').
> -
> -  LDO20, LDO21, LDO22, BUCK8 and BUCK9 can be configured to GPIO enable
> -  control. To turn this feature on this property must be added to the regulator
> -  sub-node:
> -	- maxim,ena-gpios :	one GPIO specifier enable control (the gpio
> -				flags are actually ignored and always
> -				ACTIVE_HIGH is used)
> -
>  Example:
>  
>  	max77686: pmic at 09 {
> @@ -53,27 +24,4 @@ Example:
>  		interrupt-parent = <&wakeup_eint>;
>  		interrupts = <26 0>;
>  		reg = <0x09>;
> -
> -		voltage-regulators {
> -			ldo11_reg: LDO11 {
> -				regulator-name = "vdd_ldo11";
> -				regulator-min-microvolt = <1900000>;
> -				regulator-max-microvolt = <1900000>;
> -				regulator-always-on;
> -			};
> -
> -			buck1_reg: BUCK1 {
> -				regulator-name = "vdd_mif";
> -				regulator-min-microvolt = <950000>;
> -				regulator-max-microvolt = <1300000>;
> -				regulator-always-on;
> -				regulator-boot-on;
> -			};
> -
> -			buck9_reg: BUCK9 {
> -				regulator-name = "CAM_ISP_CORE_1.2V";
> -				regulator-min-microvolt = <1000000>;
> -				regulator-max-microvolt = <1200000>;
> -				maxim,ena-gpios = <&gpm0 3 GPIO_ACTIVE_HIGH>;
> -			};
> -	}
> +	};
> diff --git a/Documentation/devicetree/bindings/regulator/max77686.txt b/Documentation/devicetree/bindings/regulator/max77686.txt
> new file mode 100644
> index 000000000000..0dded64d89d3
> --- /dev/null
> +++ b/Documentation/devicetree/bindings/regulator/max77686.txt
> @@ -0,0 +1,71 @@
> +Binding for Maxim MAX77686 regulators
> +
> +This is a part of the device tree bindings of MAX77686 multi-function device.
> +More information can be found in ../mfd/max77686.txt file.
> +
> +The MAX77686 PMIC has 9 high-efficiency Buck and 26 Low-DropOut (LDO)
> +regulators that can be controlled over I2C.
> +
> +Following properties should be present in main device node of the MFD chip.
> +
> +Optional node:
> +- voltage-regulators : The regulators of max77686 have to be instantiated
> +  under subnode named "voltage-regulators" using the following format.
> +
> +	regulator_name {
> +		regulator-compatible = LDOn/BUCKn
> +		standard regulator constraints....
> +	};
> +	refer Documentation/devicetree/bindings/regulator/regulator.txt
> +
> +  The regulator node's name should be initialized with a string
> +to get matched with their hardware counterparts as follow:
> +
> +	-LDOn 	:	for LDOs, where n can lie in range 1 to 26.
> +			example: LDO1, LDO2, LDO26.
> +	-BUCKn 	:	for BUCKs, where n can lie in range 1 to 9.
> +			example: BUCK1, BUCK5, BUCK9.
> +
> +  Regulators which can be turned off during system suspend:
> +	-LDOn	:	2, 6-8, 10-12, 14-16,
> +	-BUCKn	:	1-4.
> +  Use standard regulator bindings for it ('regulator-off-in-suspend').
> +
> +  LDO20, LDO21, LDO22, BUCK8 and BUCK9 can be configured to GPIO enable
> +  control. To turn this feature on this property must be added to the regulator
> +  sub-node:
> +	- maxim,ena-gpios :	one GPIO specifier enable control (the gpio
> +				flags are actually ignored and always
> +				ACTIVE_HIGH is used)
> +
> +Example:
> +
> +	max77686: pmic at 09 {
> +		compatible = "maxim,max77686";
> +		interrupt-parent = <&wakeup_eint>;
> +		interrupts = <26 IRQ_TYPE_NONE>;
> +		reg = <0x09>;
> +
> +		voltage-regulators {
> +			ldo11_reg: LDO11 {
> +				regulator-name = "vdd_ldo11";
> +				regulator-min-microvolt = <1900000>;
> +				regulator-max-microvolt = <1900000>;
> +				regulator-always-on;
> +			};
> +
> +			buck1_reg: BUCK1 {
> +				regulator-name = "vdd_mif";
> +				regulator-min-microvolt = <950000>;
> +				regulator-max-microvolt = <1300000>;
> +				regulator-always-on;
> +				regulator-boot-on;
> +			};
> +
> +			buck9_reg: BUCK9 {
> +				regulator-name = "CAM_ISP_CORE_1.2V";
> +				regulator-min-microvolt = <1000000>;
> +				regulator-max-microvolt = <1200000>;
> +				maxim,ena-gpios = <&gpm0 3 GPIO_ACTIVE_HIGH>;
> +			};
> +	};

-- 
Lee Jones
Linaro STMicroelectronics Landing Team Lead
Linaro.org ? Open source software for ARM SoCs
Follow Linaro: Facebook | Twitter | Blog


From linux at arm.linux.org.uk  Mon Aug 24 05:06:12 2015
From: linux at arm.linux.org.uk (Russell King - ARM Linux)
Date: Mon, 24 Aug 2015 13:06:12 +0100
Subject: Prevent list poison values from being mapped by userspace
 processes
In-Reply-To: <20150821173242.GD16410@e104818-lin.cambridge.arm.com>
References: <CABXk95C=CpeL4mNmS6-jJ-0bMJf6fawwfs6DM1-p8FctTEFbpw@mail.gmail.com>
 <20150821133043.GV7557@n2100.arm.linux.org.uk>
 <20150821173242.GD16410@e104818-lin.cambridge.arm.com>
Message-ID: <20150824120612.GY7557@n2100.arm.linux.org.uk>

On Fri, Aug 21, 2015 at 06:32:42PM +0100, Catalin Marinas wrote:
> On Fri, Aug 21, 2015 at 02:30:43PM +0100, Russell King - ARM Linux wrote:
> > On Tue, Aug 18, 2015 at 02:42:44PM -0700, Jeffrey Vander Stoep wrote:
> > > List poison pointer values point to memory that is mappable by
> > > userspace. i.e. LIST_POISON1 = 0x00100100 and LIST_POISON2 =
> > > 0x00200200. This means poison values can be valid pointers controlled
> > > by userspace and can be used to exploit the kernel as demonstrated in
> > > a recent blackhat talk:
> > > https://www.blackhat.com/docs/us-15/materials/us-15-Xu-Ah-Universal-Android-Rooting-Is-Back-wp.pdf
> > > 
> > > Can these poison values be moved to an area not mappable by userspace
> > > on 32 bit ARM?
> > 
> > As was discussed privately before your message, both Catalin and myself
> > agreed that this is not possible, and I proposed alternatives which were
> > feasible.
> 
> Nice to see these patches so quickly. However, I'll be away for the next
> ~12 days, so I won't be able to review them.

That'll be after the merge window opens, so I'll drop them into
linux-next now - they've already been through Olof's builder.  I've
already tweaked one patch to ensure that it doesn't cause build errors
with !MMU platforms.

I see that there's some boot failures reported via the mail interface
to kernelci.org, but I've no idea what they are as kernelci.org is not
elinks-compatible (kernelci.org makes use of javascript.)  So I'm not
going to care about them until someone reports the failures in a form
I can read.

In any case, kernelci.org seems to be random in terms of which platforms
get a boot test - two builds one after each other show initally 373
boots tested, and then only 195 despite the second build not failing
any ARM targets.

kernelci.org is not useful to me in this state, so I shall go purely
on Olof's build system which gave me a successful build and mostly
successful boot.  (Even with Olof's boot system, it's difficult to
tell what is a real failure and what is a transient failure - provoking
the build system to run the same build twice often results in different
boot results...)

-- 
FTTC broadband for 0.8mile line: currently at 10.5Mbps down 400kbps up
according to speedtest.net.


From hanjun.guo at linaro.org  Mon Aug 24 05:14:03 2015
From: hanjun.guo at linaro.org (Hanjun Guo)
Date: Mon, 24 Aug 2015 20:14:03 +0800
Subject: [PATCH v3 15/31] arm64: SMP support
In-Reply-To: <55D7559E.8080609@codeaurora.org>
References: <1347035226-18649-1-git-send-email-catalin.marinas@arm.com>
 <1347035226-18649-16-git-send-email-catalin.marinas@arm.com>
 <CAOZdJXVoDJM3y2mnKO+91yf2EHogKfMjumjhhi85REAfhcJM=Q@mail.gmail.com>
 <20150806095621.GB17691@e104818-lin.cambridge.arm.com>
 <55C8843D.8050600@linaro.org> <55C8D9DB.5080207@codeaurora.org>
 <55D7559E.8080609@codeaurora.org>
Message-ID: <55DB0A8B.3090700@linaro.org>

Hi Timur,

On 08/22/2015 12:45 AM, Timur Tabi wrote:
> On 08/10/2015 12:05 PM, Timur Tabi wrote:
>>>>
>>>> This code was inherited from arch/arm which initially was always
>>>> dumping
>>>> the stack but it later gained the system_state check. Unless it's
>>>> useful
>>>> to anyone for debugging purposes, I'm ok with removing it.
>>>
>>> Do you have patch for this one? My colleagues said that they met the
>>> same problem :)
>>
>> Dropping the call to dump_stack() would probably be sufficient.
>
> Actually, I think we need to keep it.  I just heard from another
> developer who does actually use it for debugging.

Hmm, could you please give a example for how it used?

>
> I think the real problem is that emergency_restart() should not be
> causing these outputs.  Shouldn't machine_restart() change the
> system_state to SYSTEM_RESTART before it calls smp_send_stop()?

The system_state is set to SYSTEM_RESTART in kernel_restart_prepare(),
and kernel_restart() will call kernel_restart_prepare() and
machine_restart(), so if we change the system_state to SYSTEM_RESTART
in machine_restart(), it seems duplicate.

Could we just wait longer than one second in the following function?

void smp_send_stop(void)
{
         unsigned long timeout;

         if (num_online_cpus() > 1) {
                 cpumask_t mask;

                 cpumask_copy(&mask, cpu_online_mask);
                 cpumask_clear_cpu(smp_processor_id(), &mask);

                 smp_cross_call(&mask, IPI_CPU_STOP);
         }

         /* Wait up to one second for other CPUs to stop */
         timeout = USEC_PER_SEC;
         while (num_online_cpus() > 1 && timeout--)
                 udelay(1);

If we have lots of CPUs, one second seems not enough as it
print lots dump message.

Thanks
Hanjun


From gpkulkarni at gmail.com  Mon Aug 24 05:30:35 2015
From: gpkulkarni at gmail.com (Ganapatrao Kulkarni)
Date: Mon, 24 Aug 2015 18:00:35 +0530
Subject: [PATCH] irqchip, gicv3-its, numa: Workaround for Cavium ThunderX
 erratum 23144
In-Reply-To: <55DAEF3C.5090303@arm.com>
References: <20150822131050.GK1820@rric.localdomain> <55DAEF3C.5090303@arm.com>
Message-ID: <CAFpQJXVVcdag7OQnCxqyEw601Y32eO2rHCmH1_bVzyvg+OPzRA@mail.gmail.com>

Hi Marc,

thanks for the review comments.

On Mon, Aug 24, 2015 at 3:47 PM, Marc Zyngier <marc.zyngier at arm.com> wrote:
> Hi Robert,
>
> Just came back from the Seattle madness, so picking up patches in
> reverse order... ;-)
>
> On 22/08/15 14:10, Robert Richter wrote:
>> The patch below adds a workaround for gicv3 in a numa environment. It
>> is on top of my recent gicv3 errata patch submission v4 and Ganapat's
>> arm64 numa patches for devicetree v5.
>>
>> Please comment.
>>
>> Thanks,
>>
>> -Robert
>>
>>
>>
>> From c432820451a46b8d1e299b8bfbfcdcb3b75340e7 Mon Sep 17 00:00:00 2001
>> From: Ganapatrao Kulkarni <gkulkarni at caviumnetworks.com>
>> Date: Wed, 19 Aug 2015 23:40:05 +0530
>> Subject: [PATCH] irqchip, gicv3-its, numa: Workaround for Cavium ThunderX erratum
>>  23144
>>
>> This implements a workaround for gicv3-its erratum 23144 applicable
>> for Cavium's ThunderX multinode systems.
>>
>> The erratum fixes the hang of ITS SYNC command by avoiding inter node
>> io and collections/cpu mapping. This fix is only applicable for
>> Cavium's ThunderX dual-socket platforms.
>
> Can you please elaborate on this? I can't see any reference to the SYNC
> command there. Is that a case of an ITS not being able to route LPIs to
> cores on another socket?
we were seeing mapc command failing when we were mapping its of node0
with collections of node1(vice-versa).
we found sync was timing out, which is issued post mapc(also for mapvi
and movi).
Yes this errata limits the routing of inter-node LPIs.

>
> I really need more details to understand this patch (please use short
> sentences, I'm still in a different time zone).
>
>>
>> Signed-off-by: Ganapatrao Kulkarni <gkulkarni at caviumnetworks.com>
>> [ rric: Reworked errata code, added helper functions, updated commit
>>       message. ]
>>
>> Signed-off-by: Robert Richter <rrichter at cavium.com>
>> ---
>>  arch/arm64/Kconfig               | 14 +++++++++++
>>  drivers/irqchip/irq-gic-common.c |  5 ++--
>>  drivers/irqchip/irq-gic-v3-its.c | 54 ++++++++++++++++++++++++++++++++++------
>>  3 files changed, 64 insertions(+), 9 deletions(-)
>>
>> diff --git a/arch/arm64/Kconfig b/arch/arm64/Kconfig
>> index 3809187ed653..b92b7b70b29b 100644
>> --- a/arch/arm64/Kconfig
>> +++ b/arch/arm64/Kconfig
>> @@ -421,6 +421,20 @@ config ARM64_ERRATUM_845719
>>
>>         If unsure, say Y.
>>
>> +config CAVIUM_ERRATUM_22375
>> +     bool "Cavium erratum 22375, 24313"
>> +     depends on NUMA
>> +     default y
>> +     help
>> +             Enable workaround for erratum 22375, 24313.
>> +
>> +config CAVIUM_ERRATUM_23144
>> +     bool "Cavium erratum 23144"
>> +     depends on NUMA
>> +     default y
>> +     help
>> +             Enable workaround for erratum 23144.
>> +
>>  config CAVIUM_ERRATUM_23154
>>       bool "Cavium erratum 23154: Access to ICC_IAR1_EL1 is not sync'ed"
>>       depends on ARCH_THUNDER
>> diff --git a/drivers/irqchip/irq-gic-common.c b/drivers/irqchip/irq-gic-common.c
>> index ee789b07f2d1..1dfce64dbdac 100644
>> --- a/drivers/irqchip/irq-gic-common.c
>> +++ b/drivers/irqchip/irq-gic-common.c
>> @@ -24,11 +24,12 @@
>>  void gic_check_capabilities(u32 iidr, const struct gic_capabilities *cap,
>>                       void *data)
>>  {
>> -     for (; cap->desc; cap++) {
>> +     for (; cap->init; cap++) {
>>               if (cap->iidr != (cap->mask & iidr))
>>                       continue;
>>               cap->init(data);
>> -             pr_info("%s\n", cap->desc);
>> +             if (cap->desc)
>> +                     pr_info("%s\n", cap->desc);
>
> No. I really want to see what errata are applied when I look at a kernel
> log.
sorry, did not understood your comment, it is still printed using cap->desc.
>
>>       }
>>  }
>>
>> diff --git a/drivers/irqchip/irq-gic-v3-its.c b/drivers/irqchip/irq-gic-v3-its.c
>> index 4bb135721e72..666be39f13a9 100644
>> --- a/drivers/irqchip/irq-gic-v3-its.c
>> +++ b/drivers/irqchip/irq-gic-v3-its.c
>> @@ -43,7 +43,8 @@
>>  #include "irqchip.h"
>>
>>  #define ITS_FLAGS_CMDQ_NEEDS_FLUSHING                (1ULL << 0)
>> -#define ITS_FLAGS_CAVIUM_THUNDERX            (1ULL << 1)
>> +#define ITS_WORKAROUND_CAVIUM_22375          (1ULL << 1)
>> +#define ITS_WORKAROUND_CAVIUM_23144          (1ULL << 2)
>>
>>  #define RDIST_FLAGS_PROPBASE_NEEDS_FLUSHING  (1 << 0)
>>
>> @@ -76,6 +77,7 @@ struct its_node {
>>       struct list_head        its_device_list;
>>       u64                     flags;
>>       u32                     ite_size;
>> +     int                     numa_node;
>>  };
>>
>>  #define ITS_ITT_ALIGN                SZ_256
>> @@ -609,11 +611,18 @@ static void its_eoi_irq(struct irq_data *d)
>>  static int its_set_affinity(struct irq_data *d, const struct cpumask *mask_val,
>>                           bool force)
>>  {
>> -     unsigned int cpu = cpumask_any_and(mask_val, cpu_online_mask);
>> +     unsigned int cpu;
>>       struct its_device *its_dev = irq_data_get_irq_chip_data(d);
>>       struct its_collection *target_col;
>>       u32 id = its_get_event_id(d);
>>
>> +     if (its_dev->its->flags & ITS_WORKAROUND_CAVIUM_23144) {
>> +             cpu = cpumask_any_and(mask_val,
>> +                             cpumask_of_node(its_dev->its->numa_node));
>
> I suppose cpumask_of_node returns only the *online* cores of a given
> node, right?
yes.
>
>> +     } else {
>> +             cpu = cpumask_any_and(mask_val, cpu_online_mask);
>> +     }
>> +
>>       if (cpu >= nr_cpu_ids)
>>               return -EINVAL;
>>
>> @@ -845,7 +854,7 @@ static int its_alloc_tables(struct its_node *its)
>>       u64 typer;
>>       u32 ids;
>>
>> -     if (its->flags & ITS_FLAGS_CAVIUM_THUNDERX) {
>> +     if (its->flags & ITS_WORKAROUND_CAVIUM_22375) {
>>               /*
>>                * erratum 22375: only alloc 8MB table size
>>                * erratum 24313: ignore memory access type
>> @@ -1093,6 +1102,11 @@ static void its_cpu_init_lpis(void)
>>       dsb(sy);
>>  }
>>
>> +static inline int numa_node_id_early(void)
>> +{
>> +     return MPIDR_AFFINITY_LEVEL(read_cpuid_mpidr(), 2);
>> +}
>> +
>>  static void its_cpu_init_collection(void)
>>  {
>>       struct its_node *its;
>> @@ -1104,6 +1118,11 @@ static void its_cpu_init_collection(void)
>>       list_for_each_entry(its, &its_nodes, entry) {
>>               u64 target;
>>
>> +             /* avoid cross node core and its mapping */
>> +             if ((its->flags & ITS_WORKAROUND_CAVIUM_23144) &&
>> +                     its->numa_node != numa_node_id_early())
>> +                             continue;
>> +
>
> Argh. This is horrible. You really need some topology bindings to
> describe your system instead of hardcoding some random level of
> affinity. The next time someone is going to come up with a similarly
> broken system, they will have to reinvent that wheel.
 thanks for the suggestion, we will use cpu_topology[cpuid].cluster_id
instead of  function numa_node_id_early()
>
>>               /*
>>                * We now have to bind each collection to its target
>>                * redistributor.
>> @@ -1372,9 +1391,15 @@ static void its_irq_domain_activate(struct irq_domain *domain,
>>  {
>>       struct its_device *its_dev = irq_data_get_irq_chip_data(d);
>>       u32 event = its_get_event_id(d);
>> +     unsigned int cpu;
>> +
>> +     if (its_dev->its->flags & ITS_WORKAROUND_CAVIUM_23144)
>> +             cpu = cpumask_first(cpumask_of_node(its_dev->its->numa_node));
>> +     else
>> +             cpu = cpumask_first(cpu_online_mask);
>
> Looks like this can be factored with the code you've added in set_affinity.
we cant issue mapvi with cross-node mapping.
>
>>
>>       /* Bind the LPI to the first possible CPU */
>> -     its_dev->event_map.col_map[event] = cpumask_first(cpu_online_mask);
>> +     its_dev->event_map.col_map[event] = cpu;
>>
>>       /* Map the GIC IRQ and event to the device */
>>       its_send_mapvi(its_dev, d->hwirq, event);
>> @@ -1457,16 +1482,31 @@ static int its_force_quiescent(void __iomem *base)
>>       }
>>  }
>>
>> +static inline int its_get_node_thunderx(struct its_node *its)
>> +{
>> +     return (its->phys_base >> 44) & 0x3;
>
> Why 3? Is that because you have provision for 4 sockets or what?
yes.
>
>> +}
>> +
>>  static void its_enable_cavium_thunderx(void *data)
>>  {
>> -     struct its_node *its = data;
>> +     struct its_node __maybe_unused *its = data;
>>
>> -     its->flags |= ITS_FLAGS_CAVIUM_THUNDERX;
>> +#ifdef CONFIG_CAVIUM_ERRATUM_22375
>> +     its->flags |= ITS_WORKAROUND_CAVIUM_22375;
>> +     pr_info("ITS: Enabling workaround for 22375, 24313\n");
>> +#endif
>> +
>> +#ifdef CONFIG_CAVIUM_ERRATUM_23144
>> +     if (num_possible_nodes() > 1) {
>> +             its->numa_node = its_get_node_thunderx(its);
>
> I'd rather see numa_node being always initialized to something useful.
> If you're adding numa support, why can't this be initialized via
> standard topology bindings?
IIUC, topology defines only cpu topology.
>
> Also, you're mixing things coming from the address map and information
> coming from the MPIDR. I must say this doesn't fill me with confidence.
>
>> +             its->flags |= ITS_WORKAROUND_CAVIUM_23144;
>> +             pr_info("ITS: Enabling workaround for 23144\n");
>> +     }
>> +#endif
>
> It would probably make sense to split these in two function, each with
> its own erratum entry.
sure will do.
>
>>  }
>>
>>  static const struct gic_capabilities its_errata[] = {
>>       {
>> -             .desc   = "ITS: Cavium errata 22375, 24313",
>>               .iidr   = 0xa100034c,   /* ThunderX pass 1.x */
>>               .mask   = 0xffff0fff,
>>               .init   = its_enable_cavium_thunderx,
>>
>
> Thanks,
>
>         M.
> --
> Jazz is not dead. It just smells funny...

thanks
Ganapat


>
> _______________________________________________
> linux-arm-kernel mailing list
> linux-arm-kernel at lists.infradead.org
> http://lists.infradead.org/mailman/listinfo/linux-arm-kernel


From alim.akhtar at samsung.com  Mon Aug 24 05:31:15 2015
From: alim.akhtar at samsung.com (Alim Akhtar)
Date: Mon, 24 Aug 2015 18:01:15 +0530
Subject: [PATCH] arm64: defconfig: Enable samsung serial and mmc
Message-ID: <1440419475-14411-1-git-send-email-alim.akhtar@samsung.com>

This patch update defconfig, adds samsung serial and
Synopsys Designware MMC configs related to exynos SoC

Signed-off-by: Alim Akhtar <alim.akhtar at samsung.com>
---
 arch/arm64/configs/defconfig |    8 ++++++++
 1 file changed, 8 insertions(+)

diff --git a/arch/arm64/configs/defconfig b/arch/arm64/configs/defconfig
index 34d71dd..c8ccda1 100644
--- a/arch/arm64/configs/defconfig
+++ b/arch/arm64/configs/defconfig
@@ -109,6 +109,10 @@ CONFIG_SERIAL_8250_DW=y
 CONFIG_SERIAL_8250_MT6577=y
 CONFIG_SERIAL_AMBA_PL011=y
 CONFIG_SERIAL_AMBA_PL011_CONSOLE=y
+CONFIG_SERIAL_SAMSUNG=y
+CONFIG_SERIAL_SAMSUNG_UARTS_4=y
+CONFIG_SERIAL_SAMSUNG_UARTS=4
+CONFIG_SERIAL_SAMSUNG_CONSOLE=y
 CONFIG_SERIAL_MSM=y
 CONFIG_SERIAL_MSM_CONSOLE=y
 CONFIG_SERIAL_OF_PLATFORM=y
@@ -145,6 +149,10 @@ CONFIG_MMC_ARMMMCI=y
 CONFIG_MMC_SDHCI=y
 CONFIG_MMC_SDHCI_PLTFM=y
 CONFIG_MMC_SPI=y
+CONFIG_MMC_DW=y
+CONFIG_MMC_DW_IDMAC=y
+CONFIG_MMC_DW_PLTFM=y
+CONFIG_MMC_DW_EXYNOS=y
 CONFIG_NEW_LEDS=y
 CONFIG_LEDS_CLASS=y
 CONFIG_LEDS_SYSCON=y
-- 
1.7.10.4



From vaibhav.hiremath at linaro.org  Mon Aug 24 05:40:04 2015
From: vaibhav.hiremath at linaro.org (Vaibhav Hiremath)
Date: Mon, 24 Aug 2015 18:10:04 +0530
Subject: [PATCH-v3 0/2] regulator: 88pm800: Add dual phase mode support on
 BUCK1
Message-ID: <1440420006-31556-1-git-send-email-vaibhav.hiremath@linaro.org>

88PM860 device supports dual phase mode on BUCK1 output.
In normal usecase, BUCK1A and BUCK1B operates independently with 3A
capacity. And they both can work as a dual phase providing 6A capacity.

This patch series is subset of earlier patch-series
Link to earlier series - https://lkml.org/lkml/2015/7/16/722

Except PATCH[5/5], all other patches in the series are accepted and
queued up for next merge window.
And based on discussion on the list, creating DT property to enable
dual-phase mode on BUCK1.

Testing:
 - Tested on 88PM860 based platform
 - Boot tested 
 - Tested with & without DT property being set
 - Read register value before and after probe to make sure that
   value has been set.

V2 => V3:
========
 - Based on discussion on earlier patch-series,
   (comments from Krzysztof Kozlowski)
   Dynamically controlled current capacity and registration of BUCK1B,
   in case of BUCK1 dual phase mode enabled.
   Now, if BUCK1 dual phase is enabled, current capacity is set to 6A,
   and, BUCK1B will not be registered to regulator framework.

V1 => V2:
========
 - This is new patch-series, where, all accepted patches dropped.
   Upgraded Patch version, to ease review.
 - Based on Mark Brown's comment, we should use DT property of its own.
   using set_current_limit() is not right way here.
   So, created DT property for Dual phase mode enable.
 - Updated binding for new DT property


Vaibhav Hiremath (2):
  mfd: devicetree: bindings: 88pm800: Add DT property for dual phase
    enable
  regulator: 88pm800: Add support for configuration of dual phase on
    BUCK1

 Documentation/devicetree/bindings/mfd/88pm800.txt |  6 ++++
 drivers/regulator/88pm800.c                       | 40 +++++++++++++++++++++++
 include/linux/mfd/88pm80x.h                       |  3 ++
 3 files changed, 49 insertions(+)

-- 
1.9.1



From vaibhav.hiremath at linaro.org  Mon Aug 24 05:40:05 2015
From: vaibhav.hiremath at linaro.org (Vaibhav Hiremath)
Date: Mon, 24 Aug 2015 18:10:05 +0530
Subject: [PATCH-v3 1/2] mfd: devicetree: bindings: 88pm800: Add DT property
 for dual phase enable
In-Reply-To: <1440420006-31556-1-git-send-email-vaibhav.hiremath@linaro.org>
References: <1440420006-31556-1-git-send-email-vaibhav.hiremath@linaro.org>
Message-ID: <1440420006-31556-2-git-send-email-vaibhav.hiremath@linaro.org>

88PM860 family of device supports dual phase mode on BUCK1 supply
providing total 6A capacity.
Note that by default they operate independently with 3A capacity.

This patch updates the devicetree binding with DT property
to enable dual-phase mode on BUCK1.

Signed-off-by: Vaibhav Hiremath <vaibhav.hiremath at linaro.org>
---
 Documentation/devicetree/bindings/mfd/88pm800.txt | 6 ++++++
 1 file changed, 6 insertions(+)

diff --git a/Documentation/devicetree/bindings/mfd/88pm800.txt b/Documentation/devicetree/bindings/mfd/88pm800.txt
index dec842f..2c82fcb 100644
--- a/Documentation/devicetree/bindings/mfd/88pm800.txt
+++ b/Documentation/devicetree/bindings/mfd/88pm800.txt
@@ -9,6 +9,12 @@ Required parent device properties:
 - #interrupt-cells 	: should be 1.
 			  The cell is the 88pm80x local IRQ number
 
+Optional properties :
+- marvell,88pm860-buck1-dualphase-en  : If set, enable dual phase on BUCK1,
+  providing 6A capacity.
+  Without this both BUCK1A and BUCK1B operates independently with 3A capacity.
+  (This property is only applicable to 88PM860)
+
 88pm80x family of devices consists of varied group of sub-devices:
 
 Device		 	Supply Names	 Description
-- 
1.9.1



From vaibhav.hiremath at linaro.org  Mon Aug 24 05:40:06 2015
From: vaibhav.hiremath at linaro.org (Vaibhav Hiremath)
Date: Mon, 24 Aug 2015 18:10:06 +0530
Subject: [PATCH-v3 2/2] regulator: 88pm800: Add support for configuration of
 dual phase on BUCK1
In-Reply-To: <1440420006-31556-1-git-send-email-vaibhav.hiremath@linaro.org>
References: <1440420006-31556-1-git-send-email-vaibhav.hiremath@linaro.org>
Message-ID: <1440420006-31556-3-git-send-email-vaibhav.hiremath@linaro.org>

88PM860 device supports dual phase mode on BUCK1 output.
In normal usecase, BUCK1A and BUCK1B operates independently with 3A
capacity. And they both can work as a dual phase providing 6A capacity.

This patch updates the regulator driver to read the respective
DT property and enable dual-phase mode on BUCK1.
Note that if dual phase mode is enabled, then BUCK1B will not be
registered to the regulator framework and the current capacity of
BUCK1(A) would be set to 6A [3A of BUCK1A + 3A of BUCK1B].

Signed-off-by: Vaibhav Hiremath <vaibhav.hiremath at linaro.org>
---
 drivers/regulator/88pm800.c | 40 ++++++++++++++++++++++++++++++++++++++++
 include/linux/mfd/88pm80x.h |  3 +++
 2 files changed, 43 insertions(+)

diff --git a/drivers/regulator/88pm800.c b/drivers/regulator/88pm800.c
index 365a154..7aca6d17 100644
--- a/drivers/regulator/88pm800.c
+++ b/drivers/regulator/88pm800.c
@@ -267,6 +267,37 @@ static struct pm800_regulator_info pm860_regulator_info[] = {
 	PM800_LDO(ldo20, LDO20, LDO_ENA1_3, 3, 10000, ldo_volt_table2),
 };
 
+static int pm800_regulator_init(struct platform_device *pdev,
+		struct pm800_regulator_info *info)
+{
+	struct pm800_regulators *pm800_data = platform_get_drvdata(pdev);
+	struct pm80x_chip *chip = pm800_data->chip;
+	int ret = 0;
+
+	/* Currently only supported on 88pm860 device */
+	if (chip->type != CHIP_PM860)
+		return 0;
+
+	if (of_property_read_bool(pdev->dev.of_node,
+				"marvell,88pm860-buck1-dualphase-en")) {
+		/* Update the constraint  to [3A (BUCK1A) + 3A (BUCK1B)] */
+		info[PM800_ID_BUCK1].max_ua = 6000000;
+		/* Remove BUCK1B from the list, as we are in dual phase mode */
+		memset(&info[PM800_ID_BUCK1B], 0, sizeof(*info));
+		/* Enable dual phase mode */
+		ret = regmap_update_bits(chip->subchip->regmap_power,
+					PM860_BUCK1_MISC,
+					BUCK1_DUAL_PHASE_SEL,
+					BUCK1_DUAL_PHASE_SEL);
+		if (ret) {
+			dev_err(chip->dev, "failed to set dual-pase mode %d\n", ret);
+			return ret;
+		}
+	}
+
+	return ret;
+}
+
 static int pm800_regulator_probe(struct platform_device *pdev)
 {
 	struct pm80x_chip *chip = dev_get_drvdata(pdev->dev.parent);
@@ -311,11 +342,20 @@ static int pm800_regulator_probe(struct platform_device *pdev)
 		return -ENODEV;
 	}
 
+	ret = pm800_regulator_init(pdev, info);
+	if (ret) {
+		dev_err(&pdev->dev, "failed to init 88pm800 regulator device\n");
+		return ret;
+	}
+
 	config.dev = chip->dev;
 	config.regmap = pm800_data->map;
 	for (i = 0; i < PM800_ID_RG_MAX; i++) {
 		struct regulator_dev *regulator;
 
+		if (!info[i].desc.name)
+			continue;
+
 		if (pdata && pdata->num_regulators) {
 			init_data = pdata->regulators[i];
 			if (!init_data)
diff --git a/include/linux/mfd/88pm80x.h b/include/linux/mfd/88pm80x.h
index a92d173..122cfd2 100644
--- a/include/linux/mfd/88pm80x.h
+++ b/include/linux/mfd/88pm80x.h
@@ -295,6 +295,9 @@ enum {
 #define PM860_BUCK4_MISC2		(0x82)
 #define PM860_BUCK4_FULL_DRV		BIT(2)
 
+#define PM860_BUCK1_MISC		0x8E
+#define BUCK1_DUAL_PHASE_SEL		BIT(2)
+
 struct pm80x_rtc_pdata {
 	int		vrtc;
 	int		rtc_wakeup;
-- 
1.9.1



From marc.zyngier at arm.com  Mon Aug 24 05:45:39 2015
From: marc.zyngier at arm.com (Marc Zyngier)
Date: Mon, 24 Aug 2015 13:45:39 +0100
Subject: [PATCH] irqchip, gicv3-its, numa: Workaround for Cavium ThunderX
 erratum 23144
In-Reply-To: <CAFpQJXVVcdag7OQnCxqyEw601Y32eO2rHCmH1_bVzyvg+OPzRA@mail.gmail.com>
References: <20150822131050.GK1820@rric.localdomain>	<55DAEF3C.5090303@arm.com>
 <CAFpQJXVVcdag7OQnCxqyEw601Y32eO2rHCmH1_bVzyvg+OPzRA@mail.gmail.com>
Message-ID: <55DB11F3.1070604@arm.com>

On 24/08/15 13:30, Ganapatrao Kulkarni wrote:
> Hi Marc,
> 
> thanks for the review comments.
> 
> On Mon, Aug 24, 2015 at 3:47 PM, Marc Zyngier <marc.zyngier at arm.com> wrote:
>> Hi Robert,
>>
>> Just came back from the Seattle madness, so picking up patches in
>> reverse order... ;-)
>>
>> On 22/08/15 14:10, Robert Richter wrote:
>>> The patch below adds a workaround for gicv3 in a numa environment. It
>>> is on top of my recent gicv3 errata patch submission v4 and Ganapat's
>>> arm64 numa patches for devicetree v5.
>>>
>>> Please comment.
>>>
>>> Thanks,
>>>
>>> -Robert
>>>
>>>
>>>
>>> From c432820451a46b8d1e299b8bfbfcdcb3b75340e7 Mon Sep 17 00:00:00 2001
>>> From: Ganapatrao Kulkarni <gkulkarni at caviumnetworks.com>
>>> Date: Wed, 19 Aug 2015 23:40:05 +0530
>>> Subject: [PATCH] irqchip, gicv3-its, numa: Workaround for Cavium ThunderX erratum
>>>  23144
>>>
>>> This implements a workaround for gicv3-its erratum 23144 applicable
>>> for Cavium's ThunderX multinode systems.
>>>
>>> The erratum fixes the hang of ITS SYNC command by avoiding inter node
>>> io and collections/cpu mapping. This fix is only applicable for
>>> Cavium's ThunderX dual-socket platforms.
>>
>> Can you please elaborate on this? I can't see any reference to the SYNC
>> command there. Is that a case of an ITS not being able to route LPIs to
>> cores on another socket?
> we were seeing mapc command failing when we were mapping its of node0
> with collections of node1(vice-versa).

There is no such thing as "collection of node1". There are collections
mapped to redistributors.

> we found sync was timing out, which is issued post mapc(also for mapvi
> and movi).
> Yes this errata limits the routing of inter-node LPIs.

Please update the commit message to reflect the actual issue.

> 
>>
>> I really need more details to understand this patch (please use short
>> sentences, I'm still in a different time zone).
>>
>>>
>>> Signed-off-by: Ganapatrao Kulkarni <gkulkarni at caviumnetworks.com>
>>> [ rric: Reworked errata code, added helper functions, updated commit
>>>       message. ]
>>>
>>> Signed-off-by: Robert Richter <rrichter at cavium.com>
>>> ---
>>>  arch/arm64/Kconfig               | 14 +++++++++++
>>>  drivers/irqchip/irq-gic-common.c |  5 ++--
>>>  drivers/irqchip/irq-gic-v3-its.c | 54 ++++++++++++++++++++++++++++++++++------
>>>  3 files changed, 64 insertions(+), 9 deletions(-)
>>>
>>> diff --git a/arch/arm64/Kconfig b/arch/arm64/Kconfig
>>> index 3809187ed653..b92b7b70b29b 100644
>>> --- a/arch/arm64/Kconfig
>>> +++ b/arch/arm64/Kconfig
>>> @@ -421,6 +421,20 @@ config ARM64_ERRATUM_845719
>>>
>>>         If unsure, say Y.
>>>
>>> +config CAVIUM_ERRATUM_22375
>>> +     bool "Cavium erratum 22375, 24313"
>>> +     depends on NUMA
>>> +     default y
>>> +     help
>>> +             Enable workaround for erratum 22375, 24313.
>>> +
>>> +config CAVIUM_ERRATUM_23144
>>> +     bool "Cavium erratum 23144"
>>> +     depends on NUMA
>>> +     default y
>>> +     help
>>> +             Enable workaround for erratum 23144.
>>> +
>>>  config CAVIUM_ERRATUM_23154
>>>       bool "Cavium erratum 23154: Access to ICC_IAR1_EL1 is not sync'ed"
>>>       depends on ARCH_THUNDER
>>> diff --git a/drivers/irqchip/irq-gic-common.c b/drivers/irqchip/irq-gic-common.c
>>> index ee789b07f2d1..1dfce64dbdac 100644
>>> --- a/drivers/irqchip/irq-gic-common.c
>>> +++ b/drivers/irqchip/irq-gic-common.c
>>> @@ -24,11 +24,12 @@
>>>  void gic_check_capabilities(u32 iidr, const struct gic_capabilities *cap,
>>>                       void *data)
>>>  {
>>> -     for (; cap->desc; cap++) {
>>> +     for (; cap->init; cap++) {
>>>               if (cap->iidr != (cap->mask & iidr))
>>>                       continue;
>>>               cap->init(data);
>>> -             pr_info("%s\n", cap->desc);
>>> +             if (cap->desc)
>>> +                     pr_info("%s\n", cap->desc);
>>
>> No. I really want to see what errata are applied when I look at a kernel
>> log.
> sorry, did not understood your comment, it is still printed using cap->desc.

Yes, but you are making desc optional, and I don't want it to be
optional. I want the kernel to scream that we're using an erratum
workaround so that we can understand what is happening when reading a
kernel log.

>>>       }
>>>  }
>>>
>>> diff --git a/drivers/irqchip/irq-gic-v3-its.c b/drivers/irqchip/irq-gic-v3-its.c
>>> index 4bb135721e72..666be39f13a9 100644
>>> --- a/drivers/irqchip/irq-gic-v3-its.c
>>> +++ b/drivers/irqchip/irq-gic-v3-its.c
>>> @@ -43,7 +43,8 @@
>>>  #include "irqchip.h"
>>>
>>>  #define ITS_FLAGS_CMDQ_NEEDS_FLUSHING                (1ULL << 0)
>>> -#define ITS_FLAGS_CAVIUM_THUNDERX            (1ULL << 1)
>>> +#define ITS_WORKAROUND_CAVIUM_22375          (1ULL << 1)
>>> +#define ITS_WORKAROUND_CAVIUM_23144          (1ULL << 2)
>>>
>>>  #define RDIST_FLAGS_PROPBASE_NEEDS_FLUSHING  (1 << 0)
>>>
>>> @@ -76,6 +77,7 @@ struct its_node {
>>>       struct list_head        its_device_list;
>>>       u64                     flags;
>>>       u32                     ite_size;
>>> +     int                     numa_node;
>>>  };
>>>
>>>  #define ITS_ITT_ALIGN                SZ_256
>>> @@ -609,11 +611,18 @@ static void its_eoi_irq(struct irq_data *d)
>>>  static int its_set_affinity(struct irq_data *d, const struct cpumask *mask_val,
>>>                           bool force)
>>>  {
>>> -     unsigned int cpu = cpumask_any_and(mask_val, cpu_online_mask);
>>> +     unsigned int cpu;
>>>       struct its_device *its_dev = irq_data_get_irq_chip_data(d);
>>>       struct its_collection *target_col;
>>>       u32 id = its_get_event_id(d);
>>>
>>> +     if (its_dev->its->flags & ITS_WORKAROUND_CAVIUM_23144) {
>>> +             cpu = cpumask_any_and(mask_val,
>>> +                             cpumask_of_node(its_dev->its->numa_node));
>>
>> I suppose cpumask_of_node returns only the *online* cores of a given
>> node, right?
> yes.
>>
>>> +     } else {
>>> +             cpu = cpumask_any_and(mask_val, cpu_online_mask);
>>> +     }
>>> +
>>>       if (cpu >= nr_cpu_ids)
>>>               return -EINVAL;
>>>
>>> @@ -845,7 +854,7 @@ static int its_alloc_tables(struct its_node *its)
>>>       u64 typer;
>>>       u32 ids;
>>>
>>> -     if (its->flags & ITS_FLAGS_CAVIUM_THUNDERX) {
>>> +     if (its->flags & ITS_WORKAROUND_CAVIUM_22375) {
>>>               /*
>>>                * erratum 22375: only alloc 8MB table size
>>>                * erratum 24313: ignore memory access type
>>> @@ -1093,6 +1102,11 @@ static void its_cpu_init_lpis(void)
>>>       dsb(sy);
>>>  }
>>>
>>> +static inline int numa_node_id_early(void)
>>> +{
>>> +     return MPIDR_AFFINITY_LEVEL(read_cpuid_mpidr(), 2);
>>> +}
>>> +
>>>  static void its_cpu_init_collection(void)
>>>  {
>>>       struct its_node *its;
>>> @@ -1104,6 +1118,11 @@ static void its_cpu_init_collection(void)
>>>       list_for_each_entry(its, &its_nodes, entry) {
>>>               u64 target;
>>>
>>> +             /* avoid cross node core and its mapping */
>>> +             if ((its->flags & ITS_WORKAROUND_CAVIUM_23144) &&
>>> +                     its->numa_node != numa_node_id_early())
>>> +                             continue;
>>> +
>>
>> Argh. This is horrible. You really need some topology bindings to
>> describe your system instead of hardcoding some random level of
>> affinity. The next time someone is going to come up with a similarly
>> broken system, they will have to reinvent that wheel.
>  thanks for the suggestion, we will use cpu_topology[cpuid].cluster_id
> instead of  function numa_node_id_early()

Make sure you can relate the ITS to it (have a way to find out which
node a given ITS belong to, without playing tricks with the memory map.

>>
>>>               /*
>>>                * We now have to bind each collection to its target
>>>                * redistributor.
>>> @@ -1372,9 +1391,15 @@ static void its_irq_domain_activate(struct irq_domain *domain,
>>>  {
>>>       struct its_device *its_dev = irq_data_get_irq_chip_data(d);
>>>       u32 event = its_get_event_id(d);
>>> +     unsigned int cpu;
>>> +
>>> +     if (its_dev->its->flags & ITS_WORKAROUND_CAVIUM_23144)
>>> +             cpu = cpumask_first(cpumask_of_node(its_dev->its->numa_node));
>>> +     else
>>> +             cpu = cpumask_first(cpu_online_mask);
>>
>> Looks like this can be factored with the code you've added in set_affinity.
> we cant issue mapvi with cross-node mapping.

And? You have almost the same code twice. Surely you can devise a single
helper that holds this code.

>>>
>>>       /* Bind the LPI to the first possible CPU */
>>> -     its_dev->event_map.col_map[event] = cpumask_first(cpu_online_mask);
>>> +     its_dev->event_map.col_map[event] = cpu;
>>>
>>>       /* Map the GIC IRQ and event to the device */
>>>       its_send_mapvi(its_dev, d->hwirq, event);
>>> @@ -1457,16 +1482,31 @@ static int its_force_quiescent(void __iomem *base)
>>>       }
>>>  }
>>>
>>> +static inline int its_get_node_thunderx(struct its_node *its)
>>> +{
>>> +     return (its->phys_base >> 44) & 0x3;
>>
>> Why 3? Is that because you have provision for 4 sockets or what?
> yes.
>>
>>> +}
>>> +
>>>  static void its_enable_cavium_thunderx(void *data)
>>>  {
>>> -     struct its_node *its = data;
>>> +     struct its_node __maybe_unused *its = data;
>>>
>>> -     its->flags |= ITS_FLAGS_CAVIUM_THUNDERX;
>>> +#ifdef CONFIG_CAVIUM_ERRATUM_22375
>>> +     its->flags |= ITS_WORKAROUND_CAVIUM_22375;
>>> +     pr_info("ITS: Enabling workaround for 22375, 24313\n");
>>> +#endif
>>> +
>>> +#ifdef CONFIG_CAVIUM_ERRATUM_23144
>>> +     if (num_possible_nodes() > 1) {
>>> +             its->numa_node = its_get_node_thunderx(its);
>>
>> I'd rather see numa_node being always initialized to something useful.
>> If you're adding numa support, why can't this be initialized via
>> standard topology bindings?
> IIUC, topology defines only cpu topology.

Well, welcome to a much more complex system where both your CPUs and
your IOs have some degree of affinity. This needs to be described
properly, and not hacked on the side.

Thanks,

	M.
-- 
Jazz is not dead. It just smells funny...


From mark.rutland at arm.com  Mon Aug 24 05:48:01 2015
From: mark.rutland at arm.com (Mark Rutland)
Date: Mon, 24 Aug 2015 13:48:01 +0100
Subject: [PATCH v1 3/3] arm64: dts: add Hi6220 mailbox node
In-Reply-To: <1440411596.3517.12.camel@linaro.org>
References: <1439977055-1747-1-git-send-email-leo.yan@linaro.org>
 <1439977055-1747-4-git-send-email-leo.yan@linaro.org>
 <20150821184059.GB2000@svinekod>
 <20150824091845.GA28290@leoy-linaro>
 <20150824095144.GA7139@leverpostej>
 <1440411596.3517.12.camel@linaro.org>
Message-ID: <20150824124800.GD7139@leverpostej>

> > > > I don't see why you need reserved-memory here, given you're not referring to
> > > > these regions by phandle anyway.
> > > 
> > > - Now we have enabled EFI_STUB, so the memory node will be removed in
> > >   kernel:
> > >     efi_entry()
> > >       \-> allocate_new_fdt_and_exit_boot()
> > >             \-> update_fdt();
> > > 
> > >   Finally in kernel it cannot use memory node to carve out reseved
> > >   memory regions.
> > > 
> > > - On the other hand, DTS's the memory node is to "describes the
> > >   physical memory layout for the system"; so it's better to use it only
> > >   to describe the hardware info for memory. We can use reserved-memory
> > >   to help manage the memory regions which are reserved from software
> > >   perspective.
> > 
> > The fact that you have no-map means that the memory should not be
> > described to the kernel as mappable in the first place. It's wrong to
> > place such memory in the memory node, even if listed in reserved-memory.
> > 
> > If your EFI memory map describes the memory as mappable, it is wrong.
> 
> When kernel is working, kernel will create its own page table based on
> UEFI memory map. Since it's reserved in DTS file as Leo's patch, it'll
> be moved to reserved memblock. Why is it wrong?

That is a _Linux_ detail, not a _UEFI_ detail.

Anything which only handles UEFI and knows nothing of reserved-memory
(e.g. GRUB) will be broken and/or break the Linux use of the region, as
it will happily try to allocate memory in the region (and could even
decide to reserve it permanently for its own usage).

If the memory is truly specific to the mailbox, then UEFI needs to know
that it is reserved as such. If it is not, then it need not be described
in the DT and can be allocated dynamically by the kernel.

> In the second, UEFI is firmware. When it's stable, nobody should change
> it without any reason. These reserved memory are used in mailbox driver.
> Look. It's driver, so it could be changed at any time. Why do you want
> to UEFI knowing this memory range? Do you hope UEFI to change when
> mailbox driver is changed?

It shouldn't need to change if that memory is truly reserved for the
sole use of the mailbox. If that's not the case then we have a different
issue.

If the memory range to use can be allocated by the driver, then I don't
see why it should be described in reserved-memory. It certainly should
not require a no-map attribute.

Additionally, the driver needs to ensure that the requisite cache
maintenance takes place prior to the use of the memory region given
prior agents may have ampped it as cacheable, leaving stale (perhaps
dirty) lines in the caches.

> > > According to upper info, we still need to use reserved-memory node to
> > > depict the reserved memory regions. i have no knowledge about EFI_STUB,
> > > so please confirm or correct as needed.
> > 
> > If the memory shouldn't be mapped, it should neither be in the memory
> > node nor EFI memory map (with attributes allowing it to be mapped) to
> > begin with.
> 
> As I said above, kernel will create its own page table. When kernel's
> page table is working, UEFI's page table is destroying. So the memory
> won't be mapped twice at the same time. What's wrong?
> > 
> > As far as I can see you do not need to use reserved-memory.
> 
> 1. Are we talking on the same thing? Leo already mentioned that all
> memory node in DTB will be destroyed by kernel when EFI_STUB is enabled
> on arm. Did you read the source code after his reply?
> And you suggested that Leo to use discrete memory region in DTB. It is
> really wrong. Kernel only gets memory map information from UEFI, not
> DTB.

I did _not_ suggest that Leo use discrete memory. I suggested that
reserved regions should not be described in the memory node (the same
premise applying to the UEFI memory map).

w.r.t. UEFI, please see my comments above. If you're using the UEFI
memory map, you have to use the UEFI memory map, not the UEFI memory map
with additional (non-UEFI) caveats applied atop.

> 2. The working flow is in below.
>    a. Kernel gets memory map information from UEFI.
>    b. Kernel loads the memory reserved information from DTB.

This relies on Linux, and ignores other UEFI clients.

> 3. Do you mean the reserved-memory is totally wrong? If it's wrong,
> please submit patches to remove all reserved-memory in linux kernel
> first.

I did not say that.

I said that describing some memory in a memory node, then also
describing that in reserved-memory with a no-map property was wrong. If
it's never meant to be mapped then there's no reason for it to be in the
memory node.

> 4. Again and again. Memory node should be only used to describe the
> RAM information.

The memory node describes the memory available to the OS. There are some
caveats w.r.t. /memreserve/, regions which may be mapped but remain
unused and so on, but the memory node does generally encode a policy
that the memory may be used.

Describing unusable memory in a memory node is pointless, and has an
adverse effect on clients which don't support reserved-memory. It's
doubly harmful when that memory should never be mapped.

Thanks,
Mark.


From ykk at rock-chips.com  Mon Aug 24 05:48:01 2015
From: ykk at rock-chips.com (Yakir Yang)
Date: Mon, 24 Aug 2015 20:48:01 +0800
Subject: [PATCH v3 06/14] Documentation: drm/bridge: add document for
 analogix_dp
In-Reply-To: <55DA9B72.1030804@samsung.com>
References: <1439995728-18046-1-git-send-email-ykk@rock-chips.com>
 <1439995834-18363-1-git-send-email-ykk@rock-chips.com>
 <CAL_JsqLz+8RtBucctUj4euXZ3Ac0DvB52N9ONpAerh5T9BiTJg@mail.gmail.com>
 <CAJKOXPeEm8exg_UG0tDnaEGO40ejBKZ-ok=bKbVrwYvXnDaMdg@mail.gmail.com>
 <55DA8486.1000803@rock-chips.com> <55DA9B72.1030804@samsung.com>
Message-ID: <55DB1281.9070502@rock-chips.com>

Hi Krzysztof,

? 08/24/2015 12:20 PM, Krzysztof Kozlowski ??:
> On 24.08.2015 11:42, Yakir Yang wrote:
>> Hi Krzysztof,
>>
>> ? 08/23/2015 07:43 PM, Krzysztof Kozlowski ??:
>>> 2015-08-24 8:23 GMT+09:00 Rob Herring <robherring2 at gmail.com>:
>>>> On Wed, Aug 19, 2015 at 9:50 AM, Yakir Yang <ykk at rock-chips.com> wrote:
>>>>> Analogix dp driver is split from exynos dp driver, so we just
>>>>> make an copy of exynos_dp.txt, and then simplify exynos_dp.txt
>>>>>
>>>>> Beside update some exynos dtsi file with the latest change
>>>>> according to the devicetree binding documents.
>>>> You can't just change the exynos bindings and break compatibility. Is
>>>> there some agreement with exynos folks to do this?
>>> No, there is no agreement. This wasn't even sent to Exynos maintainers.
>> Sorry about this one, actually I have add Exynos maintainers in version
>> 1 & version 2,
>> but lose some maintainers in version 3, I would fix it in bellow versions.
>>
>>> Additionally the patchset did not look interesting to me because of
>>> misleading subject - Documentation instead of "ARM: dts:".
>>>
>>> Yakir, please:
>>> 1. Provide backward compatibility. Mark old properties as deprecated
>>> but still support them.
>> Do you mean that I should keep the old properties declare in exynos-dp.txt,
>> but just mark them as deprecated flag.
> That is one of ways how to do this. However more important is that
> driver should still support old bindings so such code:
> -       if (of_property_read_u32(dp_node, "samsung,color-space",
> +       if (of_property_read_u32(dp_node, "analogix,color-space",
>
> is probably wrong. Will the driver support old DTB in the same way as it
> was supporting before the change?

Okay, I got your means. So document is not the focus, the most important 
is that
driver should support the old dts prop. If so the new analogix dp driver 
should keep
the "samsung,color-space", rather then just mark it with [DEPRECATED] flag.

But from your follow suggest, I think you agree to update driver code, 
and just mark
old prop with deprecated flag. If so I think such code would not be wrong

-       if (of_property_read_u32(dp_node, "samsung,color-space",
+      if (of_property_read_u32(dp_node, "analogix,color-space",

And actually @Rob have suggest me to remove the prefix, just use 
"color-space" here.

>
>> Let me show same examples, make
>> me understand your suggest rightly.
> exynos-dp already contains deprecated properties. Other ways of doing
> this would be:
> Documentation/devicetree/bindings/input/touchscreen/touchscreen.txt
> Documentation/devicetree/bindings/rtc/s3c-rtc.txt
>
> It depends up to you. The "touchscreen" looks good because it organizes
> old properties in a common section. In case of exynos-dp.txt you can add
> at beginning of file information about new bindings and mark everything
> deprecated.

Whoops, thanks for your remind, I prefer the "touchscreen" style.

>> 1. "samsung,ycbcr-coeff" is abandoned in latest analogix-dp driver,
>> absolutely
>>      I should not carry this to analogix-dp.txt document. But I should
>> keep this in
>>      exynos-dp.txt document, and mark them with an little "deprecated" flag.
>>
>> [Documentation/devicetree/bindings/video/exynos_dp.txt]
>> Required properties for dp-controller:
>>     [...]
>>      -samsung,ycbcr-coeff (DEPRECATED):
>>          YCbCr co-efficients for input video.
>>              COLOR_YCBCR601 = 0, COLOR_YCBCR709 = 1
>>
>> Is it right ?
> Yes, this is right.
>
>>> 2. Separate all DTS changes to a separate patch, unless bisectability
>>> would be hurt. Anyway you should prepare it in a such way that
>>> separation would be possible without breaking bisectability.
>> So I should separate this patch into two parts, one is name "Document:",
>> the other is "ARM: dts: ".
> Yes.
>
>> Honestly, I don't understand what the "bisectability" means in this case.
> I was referring to bisectability in general. The patchset should be
> fully bisectable which means that it does not introduce any issues
> during "git bisect". This effectively means that at each intermediate
> step (after applying each patch, one by one) every existing stuff works
> the same as previously without any regression. Including booting with
> old DTB.

Oh, thanks for your careful explain, so I guess your first comment is 
talking about
the "bisectability" that if I only apply the 01 - 05 patches, kernel 
could not bootup
normally, cause driver need "analogix,color-space" but DTB only have 
"samsung,color-space".

>
>>> 3. Use proper subject for the patch changing DTS. This is not
>>> documentation change!
>> Hmm... when I separate this patch into two parts, I though I can keep
>> "Documentation" proper subject in this patch, and the other is the "ARM:
>> dts"
>> proper subject. Am I right ?
> Yes, you're right.
>
>>> 4. Please use script get_maintainers to obtain list of valid
>>> maintainers and CC-them with at least cover letter and patches
>>> requiring their attention.
>> Yeah, thanks.
> Sure. Now I found older versions of the patchset but previously there
> were no changes to the bindings. Again the prefix in subject is
> important to easily filter out and find necessary emails.
>
> BTW, I like the patchset because I like in general works which merge
> code and reduce duplicate stuff.

Aha, thanks  :-D

Best regards,
- Yakir

> Best regards,
> Krzysztof
>
>
>
>
>




From linux at arm.linux.org.uk  Mon Aug 24 05:49:24 2015
From: linux at arm.linux.org.uk (Russell King - ARM Linux)
Date: Mon, 24 Aug 2015 13:49:24 +0100
Subject: [PATCH linux-next v4 5/5] mtd: atmel-quadspi: add driver for
 Atmel QSPI controller
In-Reply-To: <201508241303.52066.marex@denx.de>
References: <cover.1440410236.git.cyrille.pitchen@atmel.com>
 <bf368fc101f38db231131b69eff0863210f2b01c.1440410236.git.cyrille.pitchen@atmel.com>
 <201508241303.52066.marex@denx.de>
Message-ID: <20150824124924.GZ7557@n2100.arm.linux.org.uk>

On Mon, Aug 24, 2015 at 01:03:51PM +0200, Marek Vasut wrote:
> These are functions, not macros :)
> 
> btw is there any reason for these ? I'd say, just put the read*() and
> write*() functions directly into the code and be done with it, it is
> much less confusing.
> 
> Also, why do you use the _relaxed() versions of the functions ?

Now that the _relaxed() accessors are available throughout the kernel,
everyone should be using the _relaxed() versions unless they need the
properties of the non-relaxed versions.  Remember that the non-relaxed
versions are rather expensive on ARM due to the need to go all the way
out to the L2 cache - it at least doubles the number of accesses for
every read*/write*().

-- 
FTTC broadband for 0.8mile line: currently at 10.5Mbps down 400kbps up
according to speedtest.net.


From linux at roeck-us.net  Mon Aug 24 05:49:55 2015
From: linux at roeck-us.net (Guenter Roeck)
Date: Mon, 24 Aug 2015 05:49:55 -0700
Subject: [PATCH v2] watchdog: sunxi: fix activation of system reset
In-Reply-To: <CAGb2v66oZH_OifuUkzjJS3B5L-uBOaNMWZ7xhgF01EjrkuEq6g@mail.gmail.com>
References: <55B32BCE.5050506@gmail.com> <20150726193238.GM2564@lukather>
 <CAGb2v66oZH_OifuUkzjJS3B5L-uBOaNMWZ7xhgF01EjrkuEq6g@mail.gmail.com>
Message-ID: <55DB12F3.3020100@roeck-us.net>

On 08/24/2015 02:25 AM, Chen-Yu Tsai wrote:
> Hi,
>
> On Mon, Jul 27, 2015 at 3:32 AM, Maxime Ripard
> <maxime.ripard at free-electrons.com> wrote:
>> On Sat, Jul 25, 2015 at 08:25:18AM +0200, Francesco Lavra wrote:
>>> Commit f2147de33470 ("watchdog: sunxi: support parameterized compatible
>>> strings") introduced a regression in sunxi_wdt_start(), by which
>>> the system reset function of the watchdog is not enabled upon
>>> starting the watchdog. As a result, the system is not reset when the
>>> watchdog expires. Fix it.
>>>
>>> Signed-off-by: Francesco Lavra <francescolavra.fl at gmail.com>
>>> Reviewed-by: Guenter Roeck <linux at roeck-us.net>
>>> Fixes: f2147de33470 ("watchdog: sunxi: support parameterized compatible strings")
>>> Cc: stable at vger.kernel.org
>>
>> Acked-by: Maxime Ripard <maxime.ripard at free-electrons.com>
>
> What tree should this go in through?
> Guenter, are you still taking watchdog patches?
>

The patch is included in the pull request I sent to Wim last week [1].

Guenter

---
[1] http://www.spinics.net/lists/linux-watchdog/msg07219.html



From ykk at rock-chips.com  Mon Aug 24 05:55:14 2015
From: ykk at rock-chips.com (Yakir Yang)
Date: Mon, 24 Aug 2015 20:55:14 +0800
Subject: [PATCH v3 06/14] Documentation: drm/bridge: add document for
 analogix_dp
In-Reply-To: <4CAFC1ED-400F-46E4-B61F-82BB1ED018EA@gmail.com>
References: <1439995728-18046-1-git-send-email-ykk@rock-chips.com>
 <1439995834-18363-1-git-send-email-ykk@rock-chips.com>
 <CAL_JsqLz+8RtBucctUj4euXZ3Ac0DvB52N9ONpAerh5T9BiTJg@mail.gmail.com>
 <CAJKOXPeEm8exg_UG0tDnaEGO40ejBKZ-ok=bKbVrwYvXnDaMdg@mail.gmail.com>
 <4CAFC1ED-400F-46E4-B61F-82BB1ED018EA@gmail.com>
Message-ID: <55DB1432.7030309@rock-chips.com>

Hi Jingoo,

? 08/24/2015 03:40 PM, Jingoo Han ??:
> On 2015. 8. 24., at AM 9:43, Krzysztof Kozlowski <k.kozlowski at samsung.com> wrote:
>> 2015-08-24 8:23 GMT+09:00 Rob Herring <robherring2 at gmail.com>:
>>>> On Wed, Aug 19, 2015 at 9:50 AM, Yakir Yang <ykk at rock-chips.com> wrote:
>>>> Analogix dp driver is split from exynos dp driver, so we just
>>>> make an copy of exynos_dp.txt, and then simplify exynos_dp.txt
>>>>
>>>> Beside update some exynos dtsi file with the latest change
>>>> according to the devicetree binding documents.
>>> You can't just change the exynos bindings and break compatibility. Is
>>> there some agreement with exynos folks to do this?
>> No, there is no agreement. This wasn't even sent to Exynos maintainers.
>> Additionally the patchset did not look interesting to me because of
>> misleading subject - Documentation instead of "ARM: dts:".
>>
>> Yakir, please:
>> 1. Provide backward compatibility. Mark old properties as deprecated
>> but still support them.
>> 2. Separate all DTS changes to a separate patch, unless bisectability
>> would be hurt. Anyway you should prepare it in a such way that
>> separation would be possible without breaking bisectability.
>> 3. Use proper subject for the patch changing DTS. This is not
>> documentation change!
>> 4. Please use script get_maintainers to obtain list of valid
>> maintainers and CC-them with at least cover letter and patches
>> requiring their attention.
> To Yakir Yang,
>
> Please be careful when you CC people.
>
> I don't find the reason why you CC'ed the following people. Of course, they
> look to be one of the talented developers. However, they look to be
> unrelated to your patchset.
>
>   Takashi Iwai
>   Vincent Palatin
>   Fabio Estevam
>   Philipp Zabel

Yeah, actually I just got those people from patman tools. Thanks for your
remind, I would pay more attention in next version :-)

>
> Also, please add Exynos Architecture maintainers to CC list. I don't understand
> why you removed them from CC list.
>   Kukjin Kim
>   Krzysztof Kozlowski
>
> Without their Ack, you will not change the codes of ARM Exynos Architecture.

Wow, thanks a lot, it's a serious mistaken  ;)

Thanks,
- Yakir

> Best regards,
> Jingoo Han
>
>> Best regards,
>> Krzysztof
>>
>>
>>>
>>>> Signed-off-by: Yakir Yang <ykk at rock-chips.com>
>>>> ---
>>>> Changes in v3:
>>>> - Take Heiko suggest, add devicetree binding documents.
>>>> - Take Thierry Reding suggest, remove sync pol & colorimetry properies
>>>>   from the new analogix dp driver devicetree binding.
>>>> - Update the exist exynos dtsi file with the latest DP DT properies.
>>>>
>>>> Changes in v2: None
>>>>
>>>> .../devicetree/bindings/drm/bridge/analogix_dp.txt | 70 ++++++++++++++++++++++
>>>> .../devicetree/bindings/video/exynos_dp.txt        | 50 ++++++----------
>>>> arch/arm/boot/dts/exynos5250-arndale.dts           | 10 ++--
>>>> arch/arm/boot/dts/exynos5250-smdk5250.dts          | 10 ++--
>>>> arch/arm/boot/dts/exynos5250-snow.dts              | 12 ++--
>>>> arch/arm/boot/dts/exynos5250-spring.dts            | 12 ++--
>>>> arch/arm/boot/dts/exynos5420-peach-pit.dts         | 12 ++--
>>>> arch/arm/boot/dts/exynos5420-smdk5420.dts          | 10 ++--
>>>> arch/arm/boot/dts/exynos5800-peach-pi.dts          | 12 ++--
>>>> 9 files changed, 119 insertions(+), 79 deletions(-)
>>>> create mode 100644 Documentation/devicetree/bindings/drm/bridge/analogix_dp.txt
>>>>
>>>> diff --git a/Documentation/devicetree/bindings/drm/bridge/analogix_dp.txt b/Documentation/devicetree/bindings/drm/bridge/analogix_dp.txt
>>>> new file mode 100644
>>>> index 0000000..6127018
>>>> --- /dev/null
>>>> +++ b/Documentation/devicetree/bindings/drm/bridge/analogix_dp.txt
>>>> @@ -0,0 +1,70 @@
>>>> +Analogix Display Port bridge bindings
>>>> +
>>>> +Required properties for dp-controller:
>>>> +       -compatible:
>>>> +               platform specific such as:
>>>> +                * "samsung,exynos5-dp"
>>>> +                * "rockchip,rk3288-dp"
>>>> +       -reg:
>>>> +               physical base address of the controller and length
>>>> +               of memory mapped region.
>>>> +       -interrupts:
>>>> +               interrupt combiner values.
>>>> +       -clocks:
>>>> +               from common clock binding: handle to dp clock.
>>>> +       -clock-names:
>>>> +               from common clock binding: Shall be "dp".
>>>> +       -interrupt-parent:
>>>> +               phandle to Interrupt combiner node.
>>>> +       -phys:
>>>> +               from general PHY binding: the phandle for the PHY device.
>>>> +       -phy-names:
>>>> +               from general PHY binding: Should be "dp".
>>>> +       -analogix,color-space:
>>>> +               input video data format.
>>>> +                       COLOR_RGB = 0, COLOR_YCBCR422 = 1, COLOR_YCBCR444 = 2
>>>> +       -analogix,color-depth:
>>>> +               number of bits per colour component.
>>>> +                       COLOR_6 = 0, COLOR_8 = 1, COLOR_10 = 2, COLOR_12 = 3
>>> This seems pretty generic. Just use 6, 8, 10, or 12 for values. And
>>> drop the vendor prefix.
>>>
>>>> +       -analogix,link-rate:
>>>> +               max link rate supported by the eDP controller.
>>>> +                       LINK_RATE_1_62GBPS = 0x6, LINK_RATE_2_70GBPS = 0x0A,
>>>> +                       LINK_RATE_5_40GBPS = 0x14
>>> Same here. I'd rather see something like "link-rate-mbps" and use the
>>> actual rate.
>>>
>>>> +       -analogix,lane-count:
>>>> +               max number of lanes supported by the eDP contoller.
>>>> +                       LANE_COUNT1 = 1, LANE_COUNT2 = 2, LANE_COUNT4 = 4
>>> And drop the vendor prefix here.
>>>
>>>> +       -port@[X]: SoC specific port nodes with endpoint definitions as defined
>>>> +               in Documentation/devicetree/bindings/media/video-interfaces.txt,
>>>> +               please refer to the SoC specific binding document:
>>>> +               * Documentation/devicetree/bindings/video/exynos_dp.txt
>>>> +               * Documentation/devicetree/bindings/video/analogix_dp-rockchip.txt
>>>> +
>>>> +Optional properties for dp-controller:
>>>> +       -analogix,hpd-gpio:
>>>> +               Hotplug detect GPIO.
>>>> +                       Indicates which GPIO should be used for hotplug
>>>> +                       detection
>>> We should align with "hpd-gpios" used by HDMI connector binding. Or do
>>> we need a DP connector binding that this should be defined in?
>>> Probably so.
>>>
>>> The DRM related bindings are such a cluster f*ck with everyone picking
>>> their own way to do things. Just grep hpd in bindings for starters.
>>> That is just the tip.
>>>
>>>> +       -video interfaces: Device node can contain video interface port
>>>> +                           nodes according to [1].
>>> Isn't this the same as ports above? How are they optional? 0 ports
>>> would be pretty useless.
>>>
>>>> +
>>>> +[1]: Documentation/devicetree/bindings/media/video-interfaces.txt
>>>> +-------------------------------------------------------------------------------
>>>> +
>>>> +Example:
>>>> +
>>>> +       dp-controller {
>>>> +               compatible = "samsung,exynos5-dp";
>>>> +               reg = <0x145b0000 0x10000>;
>>>> +               interrupts = <10 3>;
>>>> +               interrupt-parent = <&combiner>;
>>>> +               clocks = <&clock 342>;
>>>> +               clock-names = "dp";
>>>> +
>>>> +               phys = <&dp_phy>;
>>>> +               phy-names = "dp";
>>>> +
>>>> +               analogix,color-space = <0>;
>>>> +               analogix,color-depth = <1>;
>>>> +               analogix,link-rate = <0x0a>;
>>>> +               analogix,lane-count = <4>;
>>>> +       };
>>>> diff --git a/Documentation/devicetree/bindings/video/exynos_dp.txt b/Documentation/devicetree/bindings/video/exynos_dp.txt
>>>> index 7a3a9cd..177506f 100644
>>>> --- a/Documentation/devicetree/bindings/video/exynos_dp.txt
>>>> +++ b/Documentation/devicetree/bindings/video/exynos_dp.txt
>>>> @@ -31,28 +31,10 @@ Required properties for dp-controller:
>>>>                 from general PHY binding: the phandle for the PHY device.
>>>>         -phy-names:
>>>>                 from general PHY binding: Should be "dp".
>>>> -       -samsung,color-space:
>>>> -               input video data format.
>>>> -                       COLOR_RGB = 0, COLOR_YCBCR422 = 1, COLOR_YCBCR444 = 2
>>>> -       -samsung,dynamic-range:
>>>> -               dynamic range for input video data.
>>>> -                       VESA = 0, CEA = 1
>>>> -       -samsung,ycbcr-coeff:
>>>> -               YCbCr co-efficients for input video.
>>>> -                       COLOR_YCBCR601 = 0, COLOR_YCBCR709 = 1
>>>> -       -samsung,color-depth:
>>>> -               number of bits per colour component.
>>>> -                       COLOR_6 = 0, COLOR_8 = 1, COLOR_10 = 2, COLOR_12 = 3
>>>> -       -samsung,link-rate:
>>>> -               link rate supported by the panel.
>>>> -                       LINK_RATE_1_62GBPS = 0x6, LINK_RATE_2_70GBPS = 0x0A
>>>> -       -samsung,lane-count:
>>>> -               number of lanes supported by the panel.
>>>> -                       LANE_COUNT1 = 1, LANE_COUNT2 = 2, LANE_COUNT4 = 4
>>>> -       - display-timings: timings for the connected panel as described by
>>>> -               Documentation/devicetree/bindings/video/display-timing.txt
>>>>
>>>> Optional properties for dp-controller:
>>>> +       - display-timings: timings for the connected panel as described by
>>>> +               Documentation/devicetree/bindings/video/display-timing.txt
>>>>         -interlaced:
>>>>                 interlace scan mode.
>>>>                         Progressive if defined, Interlaced if not defined
>>>> @@ -62,14 +44,18 @@ Optional properties for dp-controller:
>>>>         -hsync-active-high:
>>>>                 HSYNC polarity configuration.
>>>>                         High if defined, Low if not defined
>>>> -       -samsung,hpd-gpio:
>>>> -               Hotplug detect GPIO.
>>>> -                       Indicates which GPIO should be used for hotplug
>>>> -                       detection
>>>> -       -video interfaces: Device node can contain video interface port
>>>> -                           nodes according to [1].
>>>>
>>>> -[1]: Documentation/devicetree/bindings/media/video-interfaces.txt
>>>> +For the below properties, please refer to Analogix DP binding document:
>>>> + * Documentation/devicetree/bindings/drm/bridge/analogix_dp.txt
>>>> +       -phys (required)
>>>> +       -phy-names (required)
>>>> +       -analogix,color-space (required)
>>>> +       -analogix,color-depth (required)
>>>> +       -analogix,link-rate (required)
>>>> +       -analogix,lane-count (required)
>>>> +       -analogix,hpd-gpio (optional)
>>>> +       -video interfaces (optional)
>>>> +-------------------------------------------------------------------------------
>>>>
>>>> Example:
>>>>
>>>> @@ -88,12 +74,10 @@ SOC specific portion:
>>>>
>>>> Board Specific portion:
>>>>         dp-controller {
>>>> -               samsung,color-space = <0>;
>>>> -               samsung,dynamic-range = <0>;
>>>> -               samsung,ycbcr-coeff = <0>;
>>>> -               samsung,color-depth = <1>;
>>>> -               samsung,link-rate = <0x0a>;
>>>> -               samsung,lane-count = <4>;
>>>> +               analogix,color-space = <0>;
>>>> +               analogix,color-depth = <1>;
>>>> +               analogix,link-rate = <0x0a>;
>>>> +               analogix,lane-count = <4>;
>>>>
>>>>                 display-timings {
>>>>                         native-mode = <&lcd_timing>;
>>>> diff --git a/arch/arm/boot/dts/exynos5250-arndale.dts b/arch/arm/boot/dts/exynos5250-arndale.dts
>>>> index 7e728a1..e48798d 100644
>>>> --- a/arch/arm/boot/dts/exynos5250-arndale.dts
>>>> +++ b/arch/arm/boot/dts/exynos5250-arndale.dts
>>>> @@ -119,12 +119,10 @@
>>>>
>>>> &dp {
>>>>         status = "okay";
>>>> -       samsung,color-space = <0>;
>>>> -       samsung,dynamic-range = <0>;
>>>> -       samsung,ycbcr-coeff = <0>;
>>>> -       samsung,color-depth = <1>;
>>>> -       samsung,link-rate = <0x0a>;
>>>> -       samsung,lane-count = <4>;
>>>> +       analogix,color-space = <0>;
>>>> +       analogix,color-depth = <1>;
>>>> +       analogix,link-rate = <0x0a>;
>>>> +       analogix,lane-count = <4>;
>>>> };
>>>>
>>>> &fimd {
>>>> diff --git a/arch/arm/boot/dts/exynos5250-smdk5250.dts b/arch/arm/boot/dts/exynos5250-smdk5250.dts
>>>> index 4fe186d..b8c6b8b 100644
>>>> --- a/arch/arm/boot/dts/exynos5250-smdk5250.dts
>>>> +++ b/arch/arm/boot/dts/exynos5250-smdk5250.dts
>>>> @@ -75,12 +75,10 @@
>>>> };
>>>>
>>>> &dp {
>>>> -       samsung,color-space = <0>;
>>>> -       samsung,dynamic-range = <0>;
>>>> -       samsung,ycbcr-coeff = <0>;
>>>> -       samsung,color-depth = <1>;
>>>> -       samsung,link-rate = <0x0a>;
>>>> -       samsung,lane-count = <4>;
>>>> +       analogix,color-space = <0>;
>>>> +       analogix,color-depth = <1>;
>>>> +       analogix,link-rate = <0x0a>;
>>>> +       analogix,lane-count = <4>;
>>>>
>>>>         pinctrl-names = "default";
>>>>         pinctrl-0 = <&dp_hpd>;
>>>> diff --git a/arch/arm/boot/dts/exynos5250-snow.dts b/arch/arm/boot/dts/exynos5250-snow.dts
>>>> index b7f4122..9ce2b89 100644
>>>> --- a/arch/arm/boot/dts/exynos5250-snow.dts
>>>> +++ b/arch/arm/boot/dts/exynos5250-snow.dts
>>>> @@ -239,13 +239,11 @@
>>>>         status = "okay";
>>>>         pinctrl-names = "default";
>>>>         pinctrl-0 = <&dp_hpd>;
>>>> -       samsung,color-space = <0>;
>>>> -       samsung,dynamic-range = <0>;
>>>> -       samsung,ycbcr-coeff = <0>;
>>>> -       samsung,color-depth = <1>;
>>>> -       samsung,link-rate = <0x0a>;
>>>> -       samsung,lane-count = <2>;
>>>> -       samsung,hpd-gpio = <&gpx0 7 GPIO_ACTIVE_HIGH>;
>>>> +       analogix,color-space = <0>;
>>>> +       analogix,color-depth = <1>;
>>>> +       analogix,link-rate = <0x0a>;
>>>> +       analogix,lane-count = <2>;
>>>> +       analogix,hpd-gpio = <&gpx0 7 GPIO_ACTIVE_HIGH>;
>>>>
>>>>         ports {
>>>>                 port at 0 {
>>>> diff --git a/arch/arm/boot/dts/exynos5250-spring.dts b/arch/arm/boot/dts/exynos5250-spring.dts
>>>> index d03f9b8..9288ae6 100644
>>>> --- a/arch/arm/boot/dts/exynos5250-spring.dts
>>>> +++ b/arch/arm/boot/dts/exynos5250-spring.dts
>>>> @@ -69,13 +69,11 @@
>>>>         status = "okay";
>>>>         pinctrl-names = "default";
>>>>         pinctrl-0 = <&dp_hpd_gpio>;
>>>> -       samsung,color-space = <0>;
>>>> -       samsung,dynamic-range = <0>;
>>>> -       samsung,ycbcr-coeff = <0>;
>>>> -       samsung,color-depth = <1>;
>>>> -       samsung,link-rate = <0x0a>;
>>>> -       samsung,lane-count = <1>;
>>>> -       samsung,hpd-gpio = <&gpc3 0 GPIO_ACTIVE_HIGH>;
>>>> +       analogix,color-space = <0>;
>>>> +       analogix,color-depth = <1>;
>>>> +       analogix,link-rate = <0x0a>;
>>>> +       analogix,lane-count = <1>;
>>>> +       analogix,hpd-gpio = <&gpc3 0 GPIO_ACTIVE_HIGH>;
>>>> };
>>>>
>>>> &ehci {
>>>> diff --git a/arch/arm/boot/dts/exynos5420-peach-pit.dts b/arch/arm/boot/dts/exynos5420-peach-pit.dts
>>>> index 8f4d76c..695a380 100644
>>>> --- a/arch/arm/boot/dts/exynos5420-peach-pit.dts
>>>> +++ b/arch/arm/boot/dts/exynos5420-peach-pit.dts
>>>> @@ -147,13 +147,11 @@
>>>>         status = "okay";
>>>>         pinctrl-names = "default";
>>>>         pinctrl-0 = <&dp_hpd_gpio>;
>>>> -       samsung,color-space = <0>;
>>>> -       samsung,dynamic-range = <0>;
>>>> -       samsung,ycbcr-coeff = <0>;
>>>> -       samsung,color-depth = <1>;
>>>> -       samsung,link-rate = <0x06>;
>>>> -       samsung,lane-count = <2>;
>>>> -       samsung,hpd-gpio = <&gpx2 6 0>;
>>>> +       analogix,color-space = <0>;
>>>> +       analogix,color-depth = <1>;
>>>> +       analogix,link-rate = <0x06>;
>>>> +       analogix,lane-count = <2>;
>>>> +       analogix,hpd-gpio = <&gpx2 6 0>;
>>>>
>>>>         ports {
>>>>                 port at 0 {
>>>> diff --git a/arch/arm/boot/dts/exynos5420-smdk5420.dts b/arch/arm/boot/dts/exynos5420-smdk5420.dts
>>>> index 98871f9..fd46714 100644
>>>> --- a/arch/arm/boot/dts/exynos5420-smdk5420.dts
>>>> +++ b/arch/arm/boot/dts/exynos5420-smdk5420.dts
>>>> @@ -91,12 +91,10 @@
>>>> &dp {
>>>>         pinctrl-names = "default";
>>>>         pinctrl-0 = <&dp_hpd>;
>>>> -       samsung,color-space = <0>;
>>>> -       samsung,dynamic-range = <0>;
>>>> -       samsung,ycbcr-coeff = <0>;
>>>> -       samsung,color-depth = <1>;
>>>> -       samsung,link-rate = <0x0a>;
>>>> -       samsung,lane-count = <4>;
>>>> +       analogix,color-space = <0>;
>>>> +       analogix,color-depth = <1>;
>>>> +       analogix,link-rate = <0x0a>;
>>>> +       analogix,lane-count = <4>;
>>>>         status = "okay";
>>>> };
>>>>
>>>> diff --git a/arch/arm/boot/dts/exynos5800-peach-pi.dts b/arch/arm/boot/dts/exynos5800-peach-pi.dts
>>>> index 7d5b386..54b4c63 100644
>>>> --- a/arch/arm/boot/dts/exynos5800-peach-pi.dts
>>>> +++ b/arch/arm/boot/dts/exynos5800-peach-pi.dts
>>>> @@ -141,13 +141,11 @@
>>>>         status = "okay";
>>>>         pinctrl-names = "default";
>>>>         pinctrl-0 = <&dp_hpd_gpio>;
>>>> -       samsung,color-space = <0>;
>>>> -       samsung,dynamic-range = <0>;
>>>> -       samsung,ycbcr-coeff = <0>;
>>>> -       samsung,color-depth = <1>;
>>>> -       samsung,link-rate = <0x0a>;
>>>> -       samsung,lane-count = <2>;
>>>> -       samsung,hpd-gpio = <&gpx2 6 0>;
>>>> +       analogix,color-space = <0>;
>>>> +       analogix,color-depth = <1>;
>>>> +       analogix,link-rate = <0x0a>;
>>>> +       analogix,lane-count = <2>;
>>>> +       analogix,hpd-gpio = <&gpx2 6 0>;
>>>>         panel = <&panel>;
>>>> };
>>>>
>>>> --
>>>> 1.9.1
>>>>
>>>>
>>>>
>>>> _______________________________________________
>>>> linux-arm-kernel mailing list
>>>> linux-arm-kernel at lists.infradead.org
>>>> http://lists.infradead.org/mailman/listinfo/linux-arm-kernel
>>> _______________________________________________
>>> linux-arm-kernel mailing list
>>> linux-arm-kernel at lists.infradead.org
>>> http://lists.infradead.org/mailman/listinfo/linux-arm-kernel
>
>




From linux at arm.linux.org.uk  Mon Aug 24 05:57:58 2015
From: linux at arm.linux.org.uk (Russell King - ARM Linux)
Date: Mon, 24 Aug 2015 13:57:58 +0100
Subject: [PATCH v3 06/14] Documentation: drm/bridge: add document for
 analogix_dp
In-Reply-To: <CAL_JsqLz+8RtBucctUj4euXZ3Ac0DvB52N9ONpAerh5T9BiTJg@mail.gmail.com>
References: <1439995728-18046-1-git-send-email-ykk@rock-chips.com>
 <1439995834-18363-1-git-send-email-ykk@rock-chips.com>
 <CAL_JsqLz+8RtBucctUj4euXZ3Ac0DvB52N9ONpAerh5T9BiTJg@mail.gmail.com>
Message-ID: <20150824125758.GA7557@n2100.arm.linux.org.uk>

On Sun, Aug 23, 2015 at 06:23:14PM -0500, Rob Herring wrote:
> On Wed, Aug 19, 2015 at 9:50 AM, Yakir Yang <ykk at rock-chips.com> wrote:
> > +       -analogix,color-depth:
> > +               number of bits per colour component.
> > +                       COLOR_6 = 0, COLOR_8 = 1, COLOR_10 = 2, COLOR_12 = 3
> 
> This seems pretty generic. Just use 6, 8, 10, or 12 for values. And
> drop the vendor prefix.

Please think about this some more.  What does "color-depth" mean?  Does it
mean the number of bits per colour _component_, or does it mean the total
number of bits to represent a particular colour.  It's confusing as it
stands.

> > +Optional properties for dp-controller:
> > +       -analogix,hpd-gpio:
> > +               Hotplug detect GPIO.
> > +                       Indicates which GPIO should be used for hotplug
> > +                       detection
> 
> We should align with "hpd-gpios" used by HDMI connector binding. Or do
> we need a DP connector binding that this should be defined in?
> Probably so.
> 
> The DRM related bindings are such a cluster f*ck with everyone picking
> their own way to do things. Just grep hpd in bindings for starters.
> That is just the tip.

I'm not surprised one iota that DRM bindings are a mess.  There's no one
overlooking the adoption of DRM bindings, so surprise surprise, everyone
does their own thing.  This is exactly what happens every time in that
scenario.  It's not a new problem.

When we adopted the graph bindings for iMX DRM, I thought exactly at that
time "it would be nice if this could become the standard for binding DRM
components together" but I don't have the authority from either the DT
perspective or the DRM perspective to mandate that.  Neither does anyone
else.  That's the _real_ problem here.

I've seen several DRM bindings go by which don't use the of-graph stuff,
which means that they'll never be compatible with generic components
which do use the of-graph stuff.

Like you say, it's a mess, but it's a mess of our own making, because no
one has the authority to regulate this.

-- 
FTTC broadband for 0.8mile line: currently at 10.5Mbps down 400kbps up
according to speedtest.net.


From lee.jones at linaro.org  Mon Aug 24 06:02:05 2015
From: lee.jones at linaro.org (Lee Jones)
Date: Mon, 24 Aug 2015 14:02:05 +0100
Subject: [PATCH-v3 1/2] mfd: devicetree: bindings: 88pm800: Add DT
 property for dual phase enable
In-Reply-To: <1440420006-31556-2-git-send-email-vaibhav.hiremath@linaro.org>
References: <1440420006-31556-1-git-send-email-vaibhav.hiremath@linaro.org>
 <1440420006-31556-2-git-send-email-vaibhav.hiremath@linaro.org>
Message-ID: <20150824130205.GE3237@x1>

On Mon, 24 Aug 2015, Vaibhav Hiremath wrote:

> 88PM860 family of device supports dual phase mode on BUCK1 supply
> providing total 6A capacity.
> Note that by default they operate independently with 3A capacity.
> 
> This patch updates the devicetree binding with DT property
> to enable dual-phase mode on BUCK1.
> 
> Signed-off-by: Vaibhav Hiremath <vaibhav.hiremath at linaro.org>
> ---
>  Documentation/devicetree/bindings/mfd/88pm800.txt | 6 ++++++
>  1 file changed, 6 insertions(+)
> 
> diff --git a/Documentation/devicetree/bindings/mfd/88pm800.txt b/Documentation/devicetree/bindings/mfd/88pm800.txt
> index dec842f..2c82fcb 100644
> --- a/Documentation/devicetree/bindings/mfd/88pm800.txt
> +++ b/Documentation/devicetree/bindings/mfd/88pm800.txt
> @@ -9,6 +9,12 @@ Required parent device properties:
>  - #interrupt-cells 	: should be 1.
>  			  The cell is the 88pm80x local IRQ number
>  
> +Optional properties :
> +- marvell,88pm860-buck1-dualphase-en  : If set, enable dual phase on BUCK1,
> +  providing 6A capacity.
> +  Without this both BUCK1A and BUCK1B operates independently with 3A capacity.
> +  (This property is only applicable to 88PM860)

This will require a Regulator Ack.

My suggestion would be to remove the 'buck' number, as the same
property could be used on any Buck, and remove the '-en' part, as
this is implied.

>  88pm80x family of devices consists of varied group of sub-devices:
>  
>  Device		 	Supply Names	 Description

-- 
Lee Jones
Linaro STMicroelectronics Landing Team Lead
Linaro.org ? Open source software for ARM SoCs
Follow Linaro: Facebook | Twitter | Blog


From linus.walleij at linaro.org  Mon Aug 24 06:02:53 2015
From: linus.walleij at linaro.org (Linus Walleij)
Date: Mon, 24 Aug 2015 15:02:53 +0200
Subject: [PATCH v2 5/5] arm64: add KASan support
In-Reply-To: <55D497FC.9060506@gmail.com>
References: <1431698344-28054-1-git-send-email-a.ryabinin@samsung.com>
 <1431698344-28054-6-git-send-email-a.ryabinin@samsung.com>
 <CACRpkdaRJJjCXR=vK1M2YhR26JZfGoBB+jcqz8r2MhERfxRzqA@mail.gmail.com>
 <CAPAsAGy-r8Z2N09wKV+e0kLfbwxd-eWK6N5Xajsnqq9jfyWqcQ@mail.gmail.com>
 <CACRpkdZmHLMxosLXjyOPdkavo=UNzmTcHOLF5vV4cS1ULfbq6A@mail.gmail.com>
 <CAPAsAGw-iawTpjJh66rQN5fqBFT6UBZCcv2eKx7JTqCXzhzpsw@mail.gmail.com>
 <CACRpkdY2i2M27gP_fXawkFrC_GFgWaKr5rEn6d47refNPiEk=g@mail.gmail.com>
 <55AE56DB.4040607@samsung.com>
 <CACRpkdYaqK8upK-3b01JbO_y+sHnk4-Hm1MfvjSy0tKUkFREtQ@mail.gmail.com>
 <55AFD8D0.9020308@samsung.com>
 <CACRpkdaJVRuLTCh585rLEjua2TpnLsALhLdu0ma56TBA=C+EiQ@mail.gmail.com>
 <55D497FC.9060506@gmail.com>
Message-ID: <CACRpkdYL7R+WKfGZwmM7NGqvY8Arc_B3ekbUhkr7VPbQzAdZVg@mail.gmail.com>

On Wed, Aug 19, 2015 at 4:51 PM, Andrey Ryabinin <ryabinin.a.a at gmail.com> wrote:
> On 08/19/2015 03:14 PM, Linus Walleij wrote:

>> Integrator/AP (ARMv5):
>>
>> This one mounted with an ARMv5 ARM926 tile. It boots nicely
>> (but takes forever) with KASan and run all test cases (!) just like
>> for the other platforms but before reaching userspace this happens:
>
> THREAD_SIZE hardcoded in act_mm macro.
>
> This hack should help:
>
> diff --git a/arch/arm/mm/proc-macros.S b/arch/arm/mm/proc-macros.S
> index c671f34..b1765f2 100644
> --- a/arch/arm/mm/proc-macros.S
> +++ b/arch/arm/mm/proc-macros.S
> @@ -32,6 +32,9 @@
>         .macro  act_mm, rd
>         bic     \rd, sp, #8128
>         bic     \rd, \rd, #63
> +#ifdef CONFIG_KASAN
> +       bic     \rd, \rd, #8192
> +#endif
>         ldr     \rd, [\rd, #TI_TASK]
>         ldr     \rd, [\rd, #TSK_ACTIVE_MM]
>         .endm

Yes this work, thanks! I now get to userspace.
Tested-by: Linus Walleij <linus.walleij at linaro.org>

I have compiled Trinity and running some stress on different boards.
The ARMv7 seems to rather die from random nasty stuff from the
syscall or OOM rather than any KASan-detected bugs, but I'll
keep hammering at it a big.

I have some odd patch I'll pass along.

Yours,
Linus Walleij


From heiko at sntech.de  Mon Aug 24 06:03:05 2015
From: heiko at sntech.de (Heiko Stuebner)
Date: Mon, 24 Aug 2015 15:03:05 +0200
Subject: [PATCH v3 06/14] Documentation: drm/bridge: add document for
 analogix_dp
In-Reply-To: <55DB1281.9070502@rock-chips.com>
References: <1439995728-18046-1-git-send-email-ykk@rock-chips.com>
 <55DA9B72.1030804@samsung.com> <55DB1281.9070502@rock-chips.com>
Message-ID: <18468783.Lfl8UEMQ1s@phil>

Hi Yakir,

Am Montag, 24. August 2015, 20:48:01 schrieb Yakir Yang:
> ? 08/24/2015 12:20 PM, Krzysztof Kozlowski ??:
> > On 24.08.2015 11:42, Yakir Yang wrote:
> >> Hi Krzysztof,
> >> 
> >> ? 08/23/2015 07:43 PM, Krzysztof Kozlowski ??:
> >>> 2015-08-24 8:23 GMT+09:00 Rob Herring <robherring2 at gmail.com>:
> >>>> On Wed, Aug 19, 2015 at 9:50 AM, Yakir Yang <ykk at rock-chips.com> wrote:
> >>>>> Analogix dp driver is split from exynos dp driver, so we just
> >>>>> make an copy of exynos_dp.txt, and then simplify exynos_dp.txt
> >>>>> 
> >>>>> Beside update some exynos dtsi file with the latest change
> >>>>> according to the devicetree binding documents.
> >>>> 
> >>>> You can't just change the exynos bindings and break compatibility. Is
> >>>> there some agreement with exynos folks to do this?
> >>> 
> >>> No, there is no agreement. This wasn't even sent to Exynos maintainers.
> >> 
> >> Sorry about this one, actually I have add Exynos maintainers in version
> >> 1 & version 2,
> >> but lose some maintainers in version 3, I would fix it in bellow
> >> versions.
> >> 
> >>> Additionally the patchset did not look interesting to me because of
> >>> misleading subject - Documentation instead of "ARM: dts:".
> >>> 
> >>> Yakir, please:
> >>> 1. Provide backward compatibility. Mark old properties as deprecated
> >>> but still support them.
> >> 
> >> Do you mean that I should keep the old properties declare in
> >> exynos-dp.txt,
> >> but just mark them as deprecated flag.
> > 
> > That is one of ways how to do this. However more important is that
> > driver should still support old bindings so such code:
> > -       if (of_property_read_u32(dp_node, "samsung,color-space",
> > +       if (of_property_read_u32(dp_node, "analogix,color-space",
> > 
> > is probably wrong. Will the driver support old DTB in the same way as it
> > was supporting before the change?
> 
> Okay, I got your means. So document is not the focus, the most important
> is that
> driver should support the old dts prop. If so the new analogix dp driver
> should keep
> the "samsung,color-space", rather then just mark it with [DEPRECATED] flag.
> 
> But from your follow suggest, I think you agree to update driver code,
> and just mark
> old prop with deprecated flag. If so I think such code would not be wrong
> 
> -       if (of_property_read_u32(dp_node, "samsung,color-space",
> +      if (of_property_read_u32(dp_node, "analogix,color-space",

In a generic driver, the property should have either none, or the analogix 
prefix. But DT-properties need to be backwards compatible, meaning an older 
Exynos devicetree should run unmodified with a newer kernel.

So the common course of action is to mark the old one as deprecated but still 
test for both, so something like:

       if (of_property_read_u32(dp_node, "analogix,color-space",
                                 &dp_video_config->color_space))
	       if (of_property_read_u32(dp_node, "samsung,color-space",
                	                 &dp_video_config->color_space)) {

                	dev_err(dev, "failed to get color-space\n");
                	return ERR_PTR(-EINVAL);
        	}






From nschichan at freebox.fr  Mon Aug 24 06:05:51 2015
From: nschichan at freebox.fr (Nicolas Schichan)
Date: Mon, 24 Aug 2015 15:05:51 +0200
Subject: Prevent list poison values from being mapped by userspace
 processes
In-Reply-To: <20150821133043.GV7557@n2100.arm.linux.org.uk>
References: <CABXk95C=CpeL4mNmS6-jJ-0bMJf6fawwfs6DM1-p8FctTEFbpw@mail.gmail.com>
 <20150821133043.GV7557@n2100.arm.linux.org.uk>
Message-ID: <55DB16AF.7090607@freebox.fr>

On 08/21/2015 03:30 PM, Russell King - ARM Linux wrote:
> On Tue, Aug 18, 2015 at 02:42:44PM -0700, Jeffrey Vander Stoep wrote:
>> List poison pointer values point to memory that is mappable by
>> userspace. i.e. LIST_POISON1 = 0x00100100 and LIST_POISON2 =
>> 0x00200200. This means poison values can be valid pointers controlled
>> by userspace and can be used to exploit the kernel as demonstrated in
>> a recent blackhat talk:
>> https://www.blackhat.com/docs/us-15/materials/us-15-Xu-Ah-Universal-Android-Rooting-Is-Back-wp.pdf
>>
>> Can these poison values be moved to an area not mappable by userspace
>> on 32 bit ARM?
> 
> As was discussed privately before your message, both Catalin and myself
> agreed that this is not possible, and I proposed alternatives which were
> feasible.
> 
> I have now implemented the domain access alternative which I mentioned
> during that discussion, which is suitable for all non-LPAE setups, which
> has the effect of blocking almost all implicit kernel accesses to
> userspace, thereby substantially reducing the possibility for an attack
> similar to that given in the above paper.
> 
> It should be said that with the following patches applied, it won't stop
> the original bug being used to crash the system (that's already been
> fixed) but it will prevent userspace being able to mask the crash, and
> therefore prevent such use-after-free bugs being used to gain privileges.
> 
> This approach also covers low-vector CPUs as well, with one caveat: the
> lower 1MB of userspace will remain accessible to the kernel due to the
> need for the vectors to remain visible.  Doing otherwise crashes the
> machine on the first exception event.  So here, we offer a "best efforts"
> implementation rather than something which completely blocks userspace
> access from kernel space.
> 
> This is not a simple fix - it's quite involved, and it changes a fair
> number of places in the kernel.  It needs time to be proven before any
> thought can be given to backporting these changes to stable kernels.
> It would be good to get some testing of these changes.

Hello Russell,

I gave your patch serie a try on ARMv5/kirkwood (backported on a v4.1 kernel)
and at first I got the following panic just after the kernel transitioned
to userland (with CONFIG_CPU_SW_DOMAIN_PAN=y):

[   13.505419] Freeing unused kernel memory: 180K (c0813000 - c0840000)
[   13.535671] Unhandled fault: page domain fault (0x01b) at 0xb6ec605c
[   13.542056] pgd = df7c0000
[   13.544768] [b6ec605c] *pgd=1ec1f831, *pte=008b618f, *ppte=008b6aae
[   13.551085] Internal error: : 1b [#1] ARM
[   13.555109] Modules linked in:
[   13.558184] CPU: 0 PID: 1 Comm: init Not tainted 4.1.0-00341-gde5a42f-dirty #19
[   13.565522] Hardware name: FBXGW1R
[   13.572596] task: df442000 ti: df450000 task.ti: df450000
[   13.578026] PC is at not_thumb+0x0/0x1c
[   13.581879] LR is at __dabt_usr+0x4c/0x60
[   13.585904] pc : [<c0013f4c>]    lr : [<c000dbcc>]    psr: 40000093
[   13.585904] sp : df451fb0  ip : 00000051  fp : be860f18
[   13.597429] r10: b6f00920  r9 : b6ed83b3  r8 : 00053977
[   13.602671] r7 : 0005397f  r6 : ffffffff  r5 : 20000010  r4 : b6ec605c
[   13.609228] r3 : be860fdf  r2 : df451fb0  r1 : 00000017  r0 : b6ed83a2
[   13.615786] Flags: nZcv  IRQs off  FIQs on  Mode SVC_32  ISA ARM  Segment none
[   13.623040] Control: 0005397f  Table: 1f7c0000  DAC: 00000051
[   13.628811] Process init (pid: 1, stack limit = 0xdf450190)
[   13.634402] Stack: (0xdf451fb0 to 0xdf452000)
[   13.638773] 1fa0:                                     be860fdf b6ed83a2
00000010 00000048
[   13.646991] 1fc0: be860f14 be860e50 00000000 b6ed83a2 00000003 b6ed83b3
b6f00920 be860f18
[   13.655205] 1fe0: be860ee8 be860e38 b6ea1ee4 b6ec605c 20000010 ffffffff
29211822 602a0511
[   13.663425] [<c0013f4c>] (not_thumb) from [<00000048>] (0x48)
[   13.669200] Code: 03833b02 e3130b02 03811b02 eaffd4a2 (05943000)
[   13.675317] ---[ end trace f412d29360772faf ]---
[   13.684219] Kernel panic - not syncing: Fatal exception
[   13.696487] Rebooting in 10 seconds..

I have tracked this to the attempt made by the code in
arch/arm/mm/abort-ev5t.S to read the fault instruction which in this
case is in unserspace:

	ldreq	r3, [r4]			@ read aborted ARM instruction

The following (crude) changes seemed to fix it:

diff --git a/arch/arm/mm/abort-ev5t.S b/arch/arm/mm/abort-ev5t.S
index a0908d4..fc3a219 100644
--- a/arch/arm/mm/abort-ev5t.S
+++ b/arch/arm/mm/abort-ev5t.S
@@ -15,12 +15,33 @@
  * abort here if the I-TLB and D-TLB aren't seeing the same
  * picture.  Unfortunately, this does happen.  We live with it.
  */
+
+        .macro  uaccess_disable, tmp
+#ifdef CONFIG_CPU_SW_DOMAIN_PAN
+       /*
+        * Whenever we re-enter userspace, the domains should always be
+        * set appropriately.
+        */
+       mov     \tmp, #DACR_UACCESS_DISABLE
+       mcr     p15, 0, \tmp, c3, c0, 0         @ Set domain register
+#endif
+        .endm
+
+       .macro uaccess_enable, tmp
+#ifdef CONFIG_CPU_SW_DOMAIN_PAN
+       mov     \tmp, #DACR_UACCESS_ENABLE
+       mcr     p15, 0, \tmp, c3, c0, 0         @ set domain register
+#endif
+       .endm
+
        .align  5
 ENTRY(v5t_early_abort)
        mrc     p15, 0, r1, c5, c0, 0           @ get FSR
        mrc     p15, 0, r0, c6, c0, 0           @ get FAR
        do_thumb_abort fsr=r1, pc=r4, psr=r5, tmp=r3
+       uaccess_enable ip
        ldreq   r3, [r4]                        @ read aborted ARM instruction
+       uaccess_disable ip
        bic     r1, r1, #1 << 11                @ clear bits 11 of FSR
        do_ldrd_abort tmp=ip, insn=r3
        tst     r3, #1 << 20                    @ check write

It looks like ARMv6 with CONFIG_ARM_ERRATA_326103 enabled will suffer
from the same issue as it reads the faulty ARM instruction, possibly from
userland (see arch/arm/mm/abort-ev6.S).

With the changes above, userland boots fine and attempts to
dereference LIST_POISON1 from the kernel results the expected "page
domain fault".

To test that I mapped LIST_POISON1 from user space via mmap() and
triggered the fault by reading from /proc/cpu/alignment. I modified the
code showing /proc/cpu/alignment to access LIST_POISON1. Without your
patch serie the access to LIST_POISON1 goes through without a hitch.

Also, when CONFIG_CPU_SW_DOMAIN_PAN is not set, the DACR_INIT constant is
setup with (domain_val(DOMAIN_USER, DOMAIN_NOACCESS) which will cause the
kernel to die with a "page domain fault" when running init.

The following (crude patch) works around that:

diff --git a/arch/arm/include/asm/domain.h b/arch/arm/include/asm/domain.h
index 0c37397..e878129 100644
--- a/arch/arm/include/asm/domain.h
+++ b/arch/arm/include/asm/domain.h
@@ -57,11 +57,19 @@
 #define domain_mask(dom)       ((3) << (2 * (dom)))
 #define domain_val(dom,type)   ((type) << (2 * (dom)))

+#ifdef CONFIG_CPU_SW_DOMAIN_PAN
 #define DACR_INIT \
        (domain_val(DOMAIN_USER, DOMAIN_NOACCESS) | \
         domain_val(DOMAIN_KERNEL, DOMAIN_MANAGER) | \
         domain_val(DOMAIN_IO, DOMAIN_CLIENT) | \
         domain_val(DOMAIN_VECTORS, DOMAIN_CLIENT))
+#else
+#define DACR_INIT \
+       (domain_val(DOMAIN_USER, DOMAIN_CLIENT) | \
+        domain_val(DOMAIN_KERNEL, DOMAIN_MANAGER) | \
+        domain_val(DOMAIN_IO, DOMAIN_CLIENT) | \
+        domain_val(DOMAIN_VECTORS, DOMAIN_CLIENT))
+#endif

 #define __DACR_DEFAULT \
        domain_val(DOMAIN_KERNEL, DOMAIN_CLIENT) | \


Thanks,

-- 
Nicolas Schichan



From marex at denx.de  Mon Aug 24 06:15:44 2015
From: marex at denx.de (Marek Vasut)
Date: Mon, 24 Aug 2015 15:15:44 +0200
Subject: [PATCH linux-next v4 5/5] mtd: atmel-quadspi: add driver for
 Atmel QSPI controller
In-Reply-To: <20150824124924.GZ7557@n2100.arm.linux.org.uk>
References: <cover.1440410236.git.cyrille.pitchen@atmel.com>
 <201508241303.52066.marex@denx.de>
 <20150824124924.GZ7557@n2100.arm.linux.org.uk>
Message-ID: <201508241515.45036.marex@denx.de>

On Monday, August 24, 2015 at 02:49:24 PM, Russell King - ARM Linux wrote:

Hi Russell,

> On Mon, Aug 24, 2015 at 01:03:51PM +0200, Marek Vasut wrote:
> > These are functions, not macros :)
> > 
> > btw is there any reason for these ? I'd say, just put the read*() and
> > write*() functions directly into the code and be done with it, it is
> > much less confusing.
> > 
> > Also, why do you use the _relaxed() versions of the functions ?
> 
> Now that the _relaxed() accessors are available throughout the kernel,
> everyone should be using the _relaxed() versions unless they need the
> properties of the non-relaxed versions.

You mean the memory barrier, right ?

> Remember that the non-relaxed
> versions are rather expensive on ARM due to the need to go all the way
> out to the L2 cache - it at least doubles the number of accesses for
> every read*/write*().

I think in case of this driver, we don't need the non-relaxed version
anywhere, right ? Thanks for the educational writeup :)

btw. is [1] still the current study material on the I/O accessor best
practices please ?

[1] http://permalink.gmane.org/gmane.linux.ports.arm.kernel/117644

Best regards,
Marek Vasut


From linux at arm.linux.org.uk  Mon Aug 24 06:15:57 2015
From: linux at arm.linux.org.uk (Russell King - ARM Linux)
Date: Mon, 24 Aug 2015 14:15:57 +0100
Subject: [PATCH v2 5/5] arm64: add KASan support
In-Reply-To: <CACRpkdYaqK8upK-3b01JbO_y+sHnk4-Hm1MfvjSy0tKUkFREtQ@mail.gmail.com>
References: <1431698344-28054-1-git-send-email-a.ryabinin@samsung.com>
 <1431698344-28054-6-git-send-email-a.ryabinin@samsung.com>
 <CACRpkdaRJJjCXR=vK1M2YhR26JZfGoBB+jcqz8r2MhERfxRzqA@mail.gmail.com>
 <CAPAsAGy-r8Z2N09wKV+e0kLfbwxd-eWK6N5Xajsnqq9jfyWqcQ@mail.gmail.com>
 <CACRpkdZmHLMxosLXjyOPdkavo=UNzmTcHOLF5vV4cS1ULfbq6A@mail.gmail.com>
 <CAPAsAGw-iawTpjJh66rQN5fqBFT6UBZCcv2eKx7JTqCXzhzpsw@mail.gmail.com>
 <CACRpkdY2i2M27gP_fXawkFrC_GFgWaKr5rEn6d47refNPiEk=g@mail.gmail.com>
 <55AE56DB.4040607@samsung.com>
 <CACRpkdYaqK8upK-3b01JbO_y+sHnk4-Hm1MfvjSy0tKUkFREtQ@mail.gmail.com>
Message-ID: <20150824131557.GB7557@n2100.arm.linux.org.uk>

On Tue, Jul 21, 2015 at 11:27:56PM +0200, Linus Walleij wrote:
> On Tue, Jul 21, 2015 at 4:27 PM, Andrey Ryabinin <a.ryabinin at samsung.com> wrote:
> 
> > I used vexpress. Anyway, it doesn't matter now, since I have an update
> > with a lot of stuff fixed, and it works on hardware.
> > I still need to do some work on it and tomorrow, probably, I will share.
> 
> Ah awesome. I have a stash of ARM boards so I can test it on a
> range of hardware once you feel it's ready.
> 
> Sorry for pulling stuff out of your hands, people are excited about
> KASan ARM32 as it turns out.

People may be excited about it because it's a new feature, but we really
need to consider whether gobbling up 512MB of userspace for it is a good
idea or not.  There are programs around which like to map large amounts
of memory into their process space, and the more we steal from them, the
more likely these programs are to fail.

The other thing which I'm not happy about is having a 16K allocation per
thread - the 16K allocation for the PGD is already prone to invoking the
OOM killer after memory fragmentation has set in, we don't need another
16K allocation.  We're going from one 16K allocation per process to that
_and_ one 16K allocation per thread.

-- 
FTTC broadband for 0.8mile line: currently at 10.5Mbps down 400kbps up
according to speedtest.net.


From gpkulkarni at gmail.com  Mon Aug 24 06:27:38 2015
From: gpkulkarni at gmail.com (Ganapatrao Kulkarni)
Date: Mon, 24 Aug 2015 18:57:38 +0530
Subject: [PATCH] irqchip, gicv3-its, numa: Workaround for Cavium ThunderX
 erratum 23144
In-Reply-To: <55DB11F3.1070604@arm.com>
References: <20150822131050.GK1820@rric.localdomain> <55DAEF3C.5090303@arm.com>
 <CAFpQJXVVcdag7OQnCxqyEw601Y32eO2rHCmH1_bVzyvg+OPzRA@mail.gmail.com>
 <55DB11F3.1070604@arm.com>
Message-ID: <CAFpQJXUTNss=u2x7Ynd9wOObZn_ZHkcMz2+F4MKooy5jrvZ02w@mail.gmail.com>

On Mon, Aug 24, 2015 at 6:15 PM, Marc Zyngier <marc.zyngier at arm.com> wrote:
> On 24/08/15 13:30, Ganapatrao Kulkarni wrote:
>> Hi Marc,
>>
>> thanks for the review comments.
>>
>> On Mon, Aug 24, 2015 at 3:47 PM, Marc Zyngier <marc.zyngier at arm.com> wrote:
>>> Hi Robert,
>>>
>>> Just came back from the Seattle madness, so picking up patches in
>>> reverse order... ;-)
>>>
>>> On 22/08/15 14:10, Robert Richter wrote:
>>>> The patch below adds a workaround for gicv3 in a numa environment. It
>>>> is on top of my recent gicv3 errata patch submission v4 and Ganapat's
>>>> arm64 numa patches for devicetree v5.
>>>>
>>>> Please comment.
>>>>
>>>> Thanks,
>>>>
>>>> -Robert
>>>>
>>>>
>>>>
>>>> From c432820451a46b8d1e299b8bfbfcdcb3b75340e7 Mon Sep 17 00:00:00 2001
>>>> From: Ganapatrao Kulkarni <gkulkarni at caviumnetworks.com>
>>>> Date: Wed, 19 Aug 2015 23:40:05 +0530
>>>> Subject: [PATCH] irqchip, gicv3-its, numa: Workaround for Cavium ThunderX erratum
>>>>  23144
>>>>
>>>> This implements a workaround for gicv3-its erratum 23144 applicable
>>>> for Cavium's ThunderX multinode systems.
>>>>
>>>> The erratum fixes the hang of ITS SYNC command by avoiding inter node
>>>> io and collections/cpu mapping. This fix is only applicable for
>>>> Cavium's ThunderX dual-socket platforms.
>>>
>>> Can you please elaborate on this? I can't see any reference to the SYNC
>>> command there. Is that a case of an ITS not being able to route LPIs to
>>> cores on another socket?
>> we were seeing mapc command failing when we were mapping its of node0
>> with collections of node1(vice-versa).
>
> There is no such thing as "collection of node1". There are collections
> mapped to redistributors.
ok.
>
>> we found sync was timing out, which is issued post mapc(also for mapvi
>> and movi).
>> Yes this errata limits the routing of inter-node LPIs.
>
> Please update the commit message to reflect the actual issue.
sure.
>
>>
>>>
>>> I really need more details to understand this patch (please use short
>>> sentences, I'm still in a different time zone).
>>>
>>>>
>>>> Signed-off-by: Ganapatrao Kulkarni <gkulkarni at caviumnetworks.com>
>>>> [ rric: Reworked errata code, added helper functions, updated commit
>>>>       message. ]
>>>>
>>>> Signed-off-by: Robert Richter <rrichter at cavium.com>
>>>> ---
>>>>  arch/arm64/Kconfig               | 14 +++++++++++
>>>>  drivers/irqchip/irq-gic-common.c |  5 ++--
>>>>  drivers/irqchip/irq-gic-v3-its.c | 54 ++++++++++++++++++++++++++++++++++------
>>>>  3 files changed, 64 insertions(+), 9 deletions(-)
>>>>
>>>> diff --git a/arch/arm64/Kconfig b/arch/arm64/Kconfig
>>>> index 3809187ed653..b92b7b70b29b 100644
>>>> --- a/arch/arm64/Kconfig
>>>> +++ b/arch/arm64/Kconfig
>>>> @@ -421,6 +421,20 @@ config ARM64_ERRATUM_845719
>>>>
>>>>         If unsure, say Y.
>>>>
>>>> +config CAVIUM_ERRATUM_22375
>>>> +     bool "Cavium erratum 22375, 24313"
>>>> +     depends on NUMA
>>>> +     default y
>>>> +     help
>>>> +             Enable workaround for erratum 22375, 24313.
>>>> +
>>>> +config CAVIUM_ERRATUM_23144
>>>> +     bool "Cavium erratum 23144"
>>>> +     depends on NUMA
>>>> +     default y
>>>> +     help
>>>> +             Enable workaround for erratum 23144.
>>>> +
>>>>  config CAVIUM_ERRATUM_23154
>>>>       bool "Cavium erratum 23154: Access to ICC_IAR1_EL1 is not sync'ed"
>>>>       depends on ARCH_THUNDER
>>>> diff --git a/drivers/irqchip/irq-gic-common.c b/drivers/irqchip/irq-gic-common.c
>>>> index ee789b07f2d1..1dfce64dbdac 100644
>>>> --- a/drivers/irqchip/irq-gic-common.c
>>>> +++ b/drivers/irqchip/irq-gic-common.c
>>>> @@ -24,11 +24,12 @@
>>>>  void gic_check_capabilities(u32 iidr, const struct gic_capabilities *cap,
>>>>                       void *data)
>>>>  {
>>>> -     for (; cap->desc; cap++) {
>>>> +     for (; cap->init; cap++) {
>>>>               if (cap->iidr != (cap->mask & iidr))
>>>>                       continue;
>>>>               cap->init(data);
>>>> -             pr_info("%s\n", cap->desc);
>>>> +             if (cap->desc)
>>>> +                     pr_info("%s\n", cap->desc);
>>>
>>> No. I really want to see what errata are applied when I look at a kernel
>>> log.
>> sorry, did not understood your comment, it is still printed using cap->desc.
>
> Yes, but you are making desc optional, and I don't want it to be
> optional. I want the kernel to scream that we're using an erratum
> workaround so that we can understand what is happening when reading a
> kernel log.
sure, will add desc string.
>
>>>>       }
>>>>  }
>>>>
>>>> diff --git a/drivers/irqchip/irq-gic-v3-its.c b/drivers/irqchip/irq-gic-v3-its.c
>>>> index 4bb135721e72..666be39f13a9 100644
>>>> --- a/drivers/irqchip/irq-gic-v3-its.c
>>>> +++ b/drivers/irqchip/irq-gic-v3-its.c
>>>> @@ -43,7 +43,8 @@
>>>>  #include "irqchip.h"
>>>>
>>>>  #define ITS_FLAGS_CMDQ_NEEDS_FLUSHING                (1ULL << 0)
>>>> -#define ITS_FLAGS_CAVIUM_THUNDERX            (1ULL << 1)
>>>> +#define ITS_WORKAROUND_CAVIUM_22375          (1ULL << 1)
>>>> +#define ITS_WORKAROUND_CAVIUM_23144          (1ULL << 2)
>>>>
>>>>  #define RDIST_FLAGS_PROPBASE_NEEDS_FLUSHING  (1 << 0)
>>>>
>>>> @@ -76,6 +77,7 @@ struct its_node {
>>>>       struct list_head        its_device_list;
>>>>       u64                     flags;
>>>>       u32                     ite_size;
>>>> +     int                     numa_node;
>>>>  };
>>>>
>>>>  #define ITS_ITT_ALIGN                SZ_256
>>>> @@ -609,11 +611,18 @@ static void its_eoi_irq(struct irq_data *d)
>>>>  static int its_set_affinity(struct irq_data *d, const struct cpumask *mask_val,
>>>>                           bool force)
>>>>  {
>>>> -     unsigned int cpu = cpumask_any_and(mask_val, cpu_online_mask);
>>>> +     unsigned int cpu;
>>>>       struct its_device *its_dev = irq_data_get_irq_chip_data(d);
>>>>       struct its_collection *target_col;
>>>>       u32 id = its_get_event_id(d);
>>>>
>>>> +     if (its_dev->its->flags & ITS_WORKAROUND_CAVIUM_23144) {
>>>> +             cpu = cpumask_any_and(mask_val,
>>>> +                             cpumask_of_node(its_dev->its->numa_node));
>>>
>>> I suppose cpumask_of_node returns only the *online* cores of a given
>>> node, right?
>> yes.
>>>
>>>> +     } else {
>>>> +             cpu = cpumask_any_and(mask_val, cpu_online_mask);
>>>> +     }
>>>> +
>>>>       if (cpu >= nr_cpu_ids)
>>>>               return -EINVAL;
>>>>
>>>> @@ -845,7 +854,7 @@ static int its_alloc_tables(struct its_node *its)
>>>>       u64 typer;
>>>>       u32 ids;
>>>>
>>>> -     if (its->flags & ITS_FLAGS_CAVIUM_THUNDERX) {
>>>> +     if (its->flags & ITS_WORKAROUND_CAVIUM_22375) {
>>>>               /*
>>>>                * erratum 22375: only alloc 8MB table size
>>>>                * erratum 24313: ignore memory access type
>>>> @@ -1093,6 +1102,11 @@ static void its_cpu_init_lpis(void)
>>>>       dsb(sy);
>>>>  }
>>>>
>>>> +static inline int numa_node_id_early(void)
>>>> +{
>>>> +     return MPIDR_AFFINITY_LEVEL(read_cpuid_mpidr(), 2);
>>>> +}
>>>> +
>>>>  static void its_cpu_init_collection(void)
>>>>  {
>>>>       struct its_node *its;
>>>> @@ -1104,6 +1118,11 @@ static void its_cpu_init_collection(void)
>>>>       list_for_each_entry(its, &its_nodes, entry) {
>>>>               u64 target;
>>>>
>>>> +             /* avoid cross node core and its mapping */
>>>> +             if ((its->flags & ITS_WORKAROUND_CAVIUM_23144) &&
>>>> +                     its->numa_node != numa_node_id_early())
>>>> +                             continue;
>>>> +
>>>
>>> Argh. This is horrible. You really need some topology bindings to
>>> describe your system instead of hardcoding some random level of
>>> affinity. The next time someone is going to come up with a similarly
>>> broken system, they will have to reinvent that wheel.
>>  thanks for the suggestion, we will use cpu_topology[cpuid].cluster_id
>> instead of  function numa_node_id_early()
>
> Make sure you can relate the ITS to it (have a way to find out which
> node a given ITS belong to, without playing tricks with the memory map.
ok
>
>>>
>>>>               /*
>>>>                * We now have to bind each collection to its target
>>>>                * redistributor.
>>>> @@ -1372,9 +1391,15 @@ static void its_irq_domain_activate(struct irq_domain *domain,
>>>>  {
>>>>       struct its_device *its_dev = irq_data_get_irq_chip_data(d);
>>>>       u32 event = its_get_event_id(d);
>>>> +     unsigned int cpu;
>>>> +
>>>> +     if (its_dev->its->flags & ITS_WORKAROUND_CAVIUM_23144)
>>>> +             cpu = cpumask_first(cpumask_of_node(its_dev->its->numa_node));
>>>> +     else
>>>> +             cpu = cpumask_first(cpu_online_mask);
>>>
>>> Looks like this can be factored with the code you've added in set_affinity.
>> we cant issue mapvi with cross-node mapping.
>
> And? You have almost the same code twice. Surely you can devise a single
> helper that holds this code.
sure will do.
>
>>>>
>>>>       /* Bind the LPI to the first possible CPU */
>>>> -     its_dev->event_map.col_map[event] = cpumask_first(cpu_online_mask);
>>>> +     its_dev->event_map.col_map[event] = cpu;
>>>>
>>>>       /* Map the GIC IRQ and event to the device */
>>>>       its_send_mapvi(its_dev, d->hwirq, event);
>>>> @@ -1457,16 +1482,31 @@ static int its_force_quiescent(void __iomem *base)
>>>>       }
>>>>  }
>>>>
>>>> +static inline int its_get_node_thunderx(struct its_node *its)
>>>> +{
>>>> +     return (its->phys_base >> 44) & 0x3;
>>>
>>> Why 3? Is that because you have provision for 4 sockets or what?
>> yes.
>>>
>>>> +}
>>>> +
>>>>  static void its_enable_cavium_thunderx(void *data)
>>>>  {
>>>> -     struct its_node *its = data;
>>>> +     struct its_node __maybe_unused *its = data;
>>>>
>>>> -     its->flags |= ITS_FLAGS_CAVIUM_THUNDERX;
>>>> +#ifdef CONFIG_CAVIUM_ERRATUM_22375
>>>> +     its->flags |= ITS_WORKAROUND_CAVIUM_22375;
>>>> +     pr_info("ITS: Enabling workaround for 22375, 24313\n");
>>>> +#endif
>>>> +
>>>> +#ifdef CONFIG_CAVIUM_ERRATUM_23144
>>>> +     if (num_possible_nodes() > 1) {
>>>> +             its->numa_node = its_get_node_thunderx(its);
>>>
>>> I'd rather see numa_node being always initialized to something useful.
>>> If you're adding numa support, why can't this be initialized via
>>> standard topology bindings?
>> IIUC, topology defines only cpu topology.
>
> Well, welcome to a much more complex system where both your CPUs and
> your IOs have some degree of affinity. This needs to be described
> properly, and not hacked on the side.
ok, will add description for the function.
>
> Thanks,
>
>         M.
> --
> Jazz is not dead. It just smells funny...

thanks
Ganapat


From daniel.lezcano at linaro.org  Mon Aug 24 06:30:44 2015
From: daniel.lezcano at linaro.org (Daniel Lezcano)
Date: Mon, 24 Aug 2015 15:30:44 +0200
Subject: [PATCH] clockevents/drivers/mtk: Fix spurious interrupt leading to
 crash
In-Reply-To: <1440167950.20169.29.camel@mtksdaap41>
References: <1440167950.20169.29.camel@mtksdaap41>
Message-ID: <1440423045-7883-1-git-send-email-daniel.lezcano@linaro.org>

After analysis done by Yingjoe Chen, the timer appears to have a pending
interrupt when it is enabled.

Fix this by acknowledging the pending interrupt when enabling the timer
interrupt.

Signed-off-by: Daniel Lezcano <daniel.lezcano at linaro.org>
---
 drivers/clocksource/mtk_timer.c | 13 +++----------
 1 file changed, 3 insertions(+), 10 deletions(-)

diff --git a/drivers/clocksource/mtk_timer.c b/drivers/clocksource/mtk_timer.c
index 4cd16fb..13543a8 100644
--- a/drivers/clocksource/mtk_timer.c
+++ b/drivers/clocksource/mtk_timer.c
@@ -156,14 +156,6 @@ static irqreturn_t mtk_timer_interrupt(int irq, void *dev_id)
 	return IRQ_HANDLED;
 }
 
-static void mtk_timer_global_reset(struct mtk_clock_event_device *evt)
-{
-	/* Disable all interrupts */
-	writel(0x0, evt->gpt_base + GPT_IRQ_EN_REG);
-	/* Acknowledge all interrupts */
-	writel(0x3f, evt->gpt_base + GPT_IRQ_ACK_REG);
-}
-
 static void
 mtk_timer_setup(struct mtk_clock_event_device *evt, u8 timer, u8 option)
 {
@@ -183,6 +175,9 @@ static void mtk_timer_enable_irq(struct mtk_clock_event_device *evt, u8 timer)
 {
 	u32 val;
 
+        /* Acknowledge all spurious pending interrupts */
+        writel(0x3f, evt->gpt_base + GPT_IRQ_ACK_REG);
+
 	val = readl(evt->gpt_base + GPT_IRQ_EN_REG);
 	writel(val | GPT_IRQ_ENABLE(timer),
 			evt->gpt_base + GPT_IRQ_EN_REG);
@@ -232,8 +227,6 @@ static void __init mtk_timer_init(struct device_node *node)
 	}
 	rate = clk_get_rate(clk);
 
-	mtk_timer_global_reset(evt);
-
 	if (request_irq(evt->dev.irq, mtk_timer_interrupt,
 			IRQF_TIMER | IRQF_IRQPOLL, "mtk_timer", evt)) {
 		pr_warn("failed to setup irq %d\n", evt->dev.irq);
-- 
1.9.1



From maxime.ripard at free-electrons.com  Mon Aug 24 06:35:18 2015
From: maxime.ripard at free-electrons.com (Maxime Ripard)
Date: Mon, 24 Aug 2015 15:35:18 +0200
Subject: [PATCH 1/5] ARM: dts: sun4i: inet97fv2: Disable unused usb
 controllers
In-Reply-To: <1440369446-22195-1-git-send-email-hdegoede@redhat.com>
References: <1440369446-22195-1-git-send-email-hdegoede@redhat.com>
Message-ID: <20150824133518.GL2413@lukather>

On Mon, Aug 24, 2015 at 12:37:22AM +0200, Hans de Goede wrote:
> The inet97fv2 tablet only has a usb-2 wifi device connected to the second
> ehci controller, disable the first ehci controller and both ohci
> controllers.
> 
> Signed-off-by: Hans de Goede <hdegoede at redhat.com>

Queued, thanks.

Maxime

-- 
Maxime Ripard, Free Electrons
Embedded Linux, Kernel and Android engineering
http://free-electrons.com
-------------- next part --------------
A non-text attachment was scrubbed...
Name: signature.asc
Type: application/pgp-signature
Size: 819 bytes
Desc: Digital signature
URL: <http://lists.infradead.org/pipermail/linux-arm-kernel/attachments/20150824/c7703755/attachment-0001.sig>

From maxime.ripard at free-electrons.com  Mon Aug 24 06:35:47 2015
From: maxime.ripard at free-electrons.com (Maxime Ripard)
Date: Mon, 24 Aug 2015 15:35:47 +0200
Subject: [PATCH 2/5] ARM: dts: sun4i: inet97fv2: Add regulator nodes
In-Reply-To: <1440369446-22195-2-git-send-email-hdegoede@redhat.com>
References: <1440369446-22195-1-git-send-email-hdegoede@redhat.com>
 <1440369446-22195-2-git-send-email-hdegoede@redhat.com>
Message-ID: <20150824133547.GM2413@lukather>

On Mon, Aug 24, 2015 at 12:37:23AM +0200, Hans de Goede wrote:
> Use axp209.dtsi and add regulator nodes for the regulators used on the
> inet97fv2 tablet.
> 
> Signed-off-by: Hans de Goede <hdegoede at redhat.com>

Queued, thanks!

Maxime

-- 
Maxime Ripard, Free Electrons
Embedded Linux, Kernel and Android engineering
http://free-electrons.com
-------------- next part --------------
A non-text attachment was scrubbed...
Name: signature.asc
Type: application/pgp-signature
Size: 819 bytes
Desc: Digital signature
URL: <http://lists.infradead.org/pipermail/linux-arm-kernel/attachments/20150824/7bec9e62/attachment.sig>

From maxime.ripard at free-electrons.com  Mon Aug 24 06:36:27 2015
From: maxime.ripard at free-electrons.com (Maxime Ripard)
Date: Mon, 24 Aug 2015 15:36:27 +0200
Subject: [PATCH 3/5] ARM: dts: sun4i: inet97fv2: Enable otg controller
In-Reply-To: <1440369446-22195-3-git-send-email-hdegoede@redhat.com>
References: <1440369446-22195-1-git-send-email-hdegoede@redhat.com>
 <1440369446-22195-3-git-send-email-hdegoede@redhat.com>
Message-ID: <20150824133627.GN2413@lukather>

On Mon, Aug 24, 2015 at 12:37:24AM +0200, Hans de Goede wrote:
> Enable the otg controller on the inet97fv2 tablet.
> 
> Signed-off-by: Hans de Goede <hdegoede at redhat.com>

Queued, thanks!

Maxime

-- 
Maxime Ripard, Free Electrons
Embedded Linux, Kernel and Android engineering
http://free-electrons.com
-------------- next part --------------
A non-text attachment was scrubbed...
Name: signature.asc
Type: application/pgp-signature
Size: 819 bytes
Desc: Digital signature
URL: <http://lists.infradead.org/pipermail/linux-arm-kernel/attachments/20150824/da8cafe4/attachment.sig>

From fcooper at ti.com  Mon Aug 24 06:36:05 2015
From: fcooper at ti.com (Franklin S Cooper Jr.)
Date: Mon, 24 Aug 2015 08:36:05 -0500
Subject: [RESEND][PATCH 4/4] ARM: dts: keystone: Add ti,keystone-spi for
 SPI
In-Reply-To: <55AFC207.3050100@oracle.com>
References: <1437568344-18889-1-git-send-email-fcooper@ti.com>
 <1437568344-18889-5-git-send-email-fcooper@ti.com>
 <55AFC207.3050100@oracle.com>
Message-ID: <55DB1DC5.7060607@ti.com>

Hi Santosh,

All the patches except this one are in linux-next.

On 07/22/2015 11:17 AM, santosh shilimkar wrote:
> On 7/22/2015 5:32 AM, Franklin S Cooper Jr wrote:
>> Add ti,keystone-spi to the compatible field for the SPI node. This new
>> entry insures that the proper prescaler limit is used for keystone devices
>>
>> Signed-off-by: Franklin S Cooper Jr <fcooper at ti.com>
>> ---
> Once the binding and driver makes it, I can pick this up.
> Keep me posted. Thanks !!
>
> Regards,
> Santosh
>



From maxime.ripard at free-electrons.com  Mon Aug 24 06:37:29 2015
From: maxime.ripard at free-electrons.com (Maxime Ripard)
Date: Mon, 24 Aug 2015 15:37:29 +0200
Subject: [PATCH 4/5] ARM: dts: sun4i: inet97fv2: Enable support for
 tablet keys
In-Reply-To: <1440369446-22195-4-git-send-email-hdegoede@redhat.com>
References: <1440369446-22195-1-git-send-email-hdegoede@redhat.com>
 <1440369446-22195-4-git-send-email-hdegoede@redhat.com>
Message-ID: <20150824133729.GO2413@lukather>

On Mon, Aug 24, 2015 at 12:37:25AM +0200, Hans de Goede wrote:
> Enable support for the tablet keys which are connected via the lradc.
> 
> Signed-off-by: Hans de Goede <hdegoede at redhat.com>

Queued, thanks!
Maxime

-- 
Maxime Ripard, Free Electrons
Embedded Linux, Kernel and Android engineering
http://free-electrons.com
-------------- next part --------------
A non-text attachment was scrubbed...
Name: signature.asc
Type: application/pgp-signature
Size: 819 bytes
Desc: Digital signature
URL: <http://lists.infradead.org/pipermail/linux-arm-kernel/attachments/20150824/9c2fdc87/attachment.sig>

From robherring2 at gmail.com  Mon Aug 24 06:37:59 2015
From: robherring2 at gmail.com (Rob Herring)
Date: Mon, 24 Aug 2015 08:37:59 -0500
Subject: [PATCH 1/3] Docs: dt: add generic MSI bindings
In-Reply-To: <20150824101755.GC7139@leverpostej>
References: <1437670365-20704-1-git-send-email-mark.rutland@arm.com>
 <1437670365-20704-2-git-send-email-mark.rutland@arm.com>
 <20150805165120.GB28849@leverpostej>
 <20150824101755.GC7139@leverpostej>
Message-ID: <CAL_Jsq+-xKsfBwqjHnSKPxtO1muu-NLEHZTTLpSqw=sBuU1Gjw@mail.gmail.com>

On Mon, Aug 24, 2015 at 5:17 AM, Mark Rutland <mark.rutland at arm.com> wrote:
> On Wed, Aug 05, 2015 at 05:51:20PM +0100, Mark Rutland wrote:
>> Rob,
>>
>> Do you have any objections to this, or are you happy to take this patch?
>>
>> There's a user of this binding (the GICv3 ITS) queued for v4.3 already in
>> the tip tree, so either we either need to be ok with this binding or we
>> need to rework that before v4.3.
>
> Sorry to ping, but are you happy to take this? Marc's replied and
> provided his ack.

Sorry. Looks fine to me, so I'll apply.

> I'm happy to resend if you prefer?

What about patch 2 and 3? I can't find patch 3 in my mail.

Rob

>
> Thanks,
> Mark.
>
>> Marc, can I take it from your use of the binding that you are happy to
>> provide your ack?
>>
>> Thanks,
>> Mark.
>>
>> On Thu, Jul 23, 2015 at 05:52:43PM +0100, Mark Rutland wrote:
>> > Currently msi-parent is used in a couple of drivers despite being fairly
>> > underspecified. This patch adds a generic binding for MSIs (including
>> > the existing msi-parent property) enabling the description of platform
>> > devices capable of using MSIs.
>> >
>> > While MSIs are primarily distinguished by doorbell and payload, some MSI
>> > controllers (e.g. the GICv3 ITS) also use side-band information
>> > accompanying the write to identify the master which originated the MSI,
>> > to allow for sandboxing. This sideband information is non-probeable and
>> > needs to be described in the DT. Other MSI controllers may have
>> > additional configuration details which need to be described per-master.
>> >
>> > This patch adds a generic msi-parent binding document, extending the
>> > de-facto standard with a new (optional) #msi-cells which can be used to
>> > express any per-master configuration and/or sideband data. This is
>> > sufficient to describe non-hotpluggable devices.
>> >
>> > For busses where sideband data may be derived from some bus-specific
>> > master ID scheme, other properties will be required to describe the
>> > mapping.
>> >
>> > Signed-off-by: Mark Rutland <mark.rutland at arm.com>
>> > ---
>> >  .../bindings/interrupt-controller/msi.txt          | 135 +++++++++++++++++++++
>> >  1 file changed, 135 insertions(+)
>> >  create mode 100644 Documentation/devicetree/bindings/interrupt-controller/msi.txt
>> >
>> > diff --git a/Documentation/devicetree/bindings/interrupt-controller/msi.txt b/Documentation/devicetree/bindings/interrupt-controller/msi.txt
>> > new file mode 100644
>> > index 0000000..c60c034
>> > --- /dev/null
>> > +++ b/Documentation/devicetree/bindings/interrupt-controller/msi.txt
>> > @@ -0,0 +1,135 @@
>> > +This document describes the generic device tree binding for MSI controllers and
>> > +their master(s).
>> > +
>> > +Message Signaled Interrupts (MSIs) are a class of interrupts generated by a
>> > +write to an MMIO address.
>> > +
>> > +MSIs were originally specified by PCI (and are used with PCIe), but may also be
>> > +used with other busses, and hence a mechanism is required to relate devices on
>> > +those busses to the MSI controllers which they are capable of using,
>> > +potentially including additional information.
>> > +
>> > +MSIs are distinguished by some combination of:
>> > +
>> > +- The doorbell (the MMIO address written to).
>> > +
>> > +  Devices may be configured by software to write to arbitrary doorbells which
>> > +  they can address. An MSI controller may feature a number of doorbells.
>> > +
>> > +- The payload (the value written to the doorbell).
>> > +
>> > +  Devices may be configured to write an arbitrary payload chosen by software.
>> > +  MSI controllers may have restrictions on permitted payloads.
>> > +
>> > +- Sideband information accompanying the write.
>> > +
>> > +  Typically this is neither configurable nor probeable, and depends on the path
>> > +  taken through the memory system (i.e. it is a property of the combination of
>> > +  MSI controller and device rather than a property of either in isolation).
>> > +
>> > +
>> > +MSI controllers:
>> > +================
>> > +
>> > +An MSI controller signals interrupts to a CPU when a write is made to an MMIO
>> > +address by some master. An MSI controller may feature a number of doorbells.
>> > +
>> > +Required properties:
>> > +--------------------
>> > +
>> > +- msi-controller: Identifies the node as an MSI controller.
>> > +
>> > +Optional properties:
>> > +--------------------
>> > +
>> > +- #msi-cells: The number of cells in an msi-specifier, required if not zero.
>> > +
>> > +  Typically this will encode information related to sideband data, and will
>> > +  not encode doorbells or payloads as these can be configured dynamically.
>> > +
>> > +  The meaning of the msi-specifier is defined by the device tree binding of
>> > +  the specific MSI controller.
>> > +
>> > +
>> > +MSI clients
>> > +===========
>> > +
>> > +MSI clients are devices which generate MSIs. For each MSI they wish to
>> > +generate, the doorbell and payload may be configured, though sideband
>> > +information may not be configurable.
>> > +
>> > +Required properties:
>> > +--------------------
>> > +
>> > +- msi-parent: A list of phandle + msi-specifier pairs, one for each MSI
>> > +  controller which the device is capable of using.
>> > +
>> > +  This property is unordered, and MSIs may be allocated from any combination of
>> > +  MSI controllers listed in the msi-parent property.
>> > +
>> > +  If a device has restrictions on the allocation of MSIs, these restrictions
>> > +  must be described with additional properties.
>> > +
>> > +  When #msi-cells is non-zero, busses with an msi-parent will require
>> > +  additional properties to describe the relationship between devices on the bus
>> > +  and the set of MSIs they can potentially generate.
>> > +
>> > +
>> > +Example
>> > +=======
>> > +
>> > +/ {
>> > +   #address-cells = <1>;
>> > +   #size-cells = <1>;
>> > +
>> > +   msi_a: msi-controller at a {
>> > +           reg = <0xa 0xf00>;
>> > +           compatible = "vendor-a,some-controller";
>> > +           msi-controller;
>> > +           /* No sideband data, so #msi-cells omitted */
>> > +   };
>> > +
>> > +   msi_b: msi-controller at b {
>> > +           reg = <0xb 0xf00>;
>> > +           compatible = "vendor-b,another-controller";
>> > +           msi-controller;
>> > +           /* Each device has some unique ID */
>> > +           #msi-cells = <1>;
>> > +   };
>> > +
>> > +   msi_c: msi-controller at c {
>> > +           reg = <0xb 0xf00>;
>> > +           compatible = "vendor-b,another-controller";
>> > +           msi-controller;
>> > +           /* Each device has some unique ID */
>> > +           #msi-cells = <1>;
>> > +   };
>> > +
>> > +   dev at 0 {
>> > +           reg = <0x0 0xf00>;
>> > +           compatible = "vendor-c,some-device";
>> > +
>> > +           /* Can only generate MSIs to msi_a */
>> > +           msi-parent = <&msi_a>;
>> > +   };
>> > +
>> > +   dev at 1 {
>> > +           reg = <0x1 0xf00>;
>> > +           compatible = "vendor-c,some-device";
>> > +
>> > +           /*
>> > +            * Can generate MSIs to either A or B.
>> > +            */
>> > +           msi-parent = <&msi_a>, <&msi_b 0x17>;
>> > +   };
>> > +
>> > +   dev at 2 {
>> > +           reg = <0x2 0xf00>;
>> > +           compatible = "vendor-c,some-device";
>> > +           /*
>> > +            * Has different IDs at each MSI controller.
>> > +            * Can generate MSIs to all of the MSI controllers.
>> > +            */
>> > +           msi-parent = <&msi_a>, <&msi_b 0x17>, <&msi_c 0x53>;
>> > +   };
>> > +};
>> > --
>> > 1.9.1
>> >
>> --
>> To unsubscribe from this list: send the line "unsubscribe devicetree" in
>> the body of a message to majordomo at vger.kernel.org
>> More majordomo info at  http://vger.kernel.org/majordomo-info.html
>>


From maxime.ripard at free-electrons.com  Mon Aug 24 06:38:30 2015
From: maxime.ripard at free-electrons.com (Maxime Ripard)
Date: Mon, 24 Aug 2015 15:38:30 +0200
Subject: [PATCH 5/5] ARM: dts: sun4i: inet97fv2: Enable i2c1 and i2c2
 controllers
In-Reply-To: <1440369446-22195-5-git-send-email-hdegoede@redhat.com>
References: <1440369446-22195-1-git-send-email-hdegoede@redhat.com>
 <1440369446-22195-5-git-send-email-hdegoede@redhat.com>
Message-ID: <20150824133830.GP2413@lukather>

On Mon, Aug 24, 2015 at 12:37:26AM +0200, Hans de Goede wrote:
> Enable i2c1 and i2c2 controllers, these are used for the touchscreen resp.
> the accelerometer.
> 
> Signed-off-by: Hans de Goede <hdegoede at redhat.com>

Queued, thanks!
Maxime

-- 
Maxime Ripard, Free Electrons
Embedded Linux, Kernel and Android engineering
http://free-electrons.com
-------------- next part --------------
A non-text attachment was scrubbed...
Name: signature.asc
Type: application/pgp-signature
Size: 819 bytes
Desc: Digital signature
URL: <http://lists.infradead.org/pipermail/linux-arm-kernel/attachments/20150824/4c873b8e/attachment-0001.sig>

From maxime.ripard at free-electrons.com  Mon Aug 24 06:39:02 2015
From: maxime.ripard at free-electrons.com (Maxime Ripard)
Date: Mon, 24 Aug 2015 15:39:02 +0200
Subject: [linux-sunxi] Re: [PATCH] net: sun4i-emac: Claim emac sram
In-Reply-To: <55DAE137.4040306@redhat.com>
References: <1440354698-11144-1-git-send-email-hdegoede@redhat.com>
 <20150824074605.GF2413@lukather> <55DAE137.4040306@redhat.com>
Message-ID: <20150824133902.GQ2413@lukather>

On Mon, Aug 24, 2015 at 11:17:43AM +0200, Hans de Goede wrote:
> Hi,
> 
> On 24-08-15 09:46, Maxime Ripard wrote:
> >Hi Hans,
> >
> >On Sun, Aug 23, 2015 at 08:31:38PM +0200, Hans de Goede wrote:
> >>Claim the emac sram ourselves, rather then relying on the bootloader
> >>having mapped the sram to the emac controller during boot.
> >>
> >>Signed-off-by: Hans de Goede <hdegoede at redhat.com>
> >>---
> >>  drivers/net/ethernet/allwinner/sun4i-emac.c | 13 +++++++++++--
> >>  1 file changed, 11 insertions(+), 2 deletions(-)
> >>
> >>diff --git a/drivers/net/ethernet/allwinner/sun4i-emac.c b/drivers/net/ethernet/allwinner/sun4i-emac.c
> >>index bab01c84..48ce83e 100644
> >>--- a/drivers/net/ethernet/allwinner/sun4i-emac.c
> >>+++ b/drivers/net/ethernet/allwinner/sun4i-emac.c
> >>@@ -28,6 +28,7 @@
> >>  #include <linux/of_platform.h>
> >>  #include <linux/platform_device.h>
> >>  #include <linux/phy.h>
> >>+#include <linux/soc/sunxi/sunxi_sram.h>
> >>
> >>  #include "sun4i-emac.h"
> >>
> >>@@ -857,11 +858,17 @@ static int emac_probe(struct platform_device *pdev)
> >>
> >>  	clk_prepare_enable(db->clk);
> >>
> >>+	ret = sunxi_sram_claim(&pdev->dev);
> >>+	if (ret) {
> >>+		dev_err(&pdev->dev, "Error couldn't map SRAM to device\n");
> >>+		goto out;
> >
> >Shouldn't you disable you clock too?
> 
> You're right, but that is a pre-existing problem, iow an unrelated
> issue.
> 
> I've put doing a follow-up patch for this on my todo list.

Thanks.

Maxime

-- 
Maxime Ripard, Free Electrons
Embedded Linux, Kernel and Android engineering
http://free-electrons.com
-------------- next part --------------
A non-text attachment was scrubbed...
Name: signature.asc
Type: application/pgp-signature
Size: 819 bytes
Desc: Digital signature
URL: <http://lists.infradead.org/pipermail/linux-arm-kernel/attachments/20150824/54747424/attachment.sig>

From mark.rutland at arm.com  Mon Aug 24 06:42:05 2015
From: mark.rutland at arm.com (Mark Rutland)
Date: Mon, 24 Aug 2015 14:42:05 +0100
Subject: [PATCH] arm64/kvm: set {v,}TCR_EL2 RES1 bits
Message-ID: <1440423725-31700-1-git-send-email-mark.rutland@arm.com>

Currently we don't set the RES1 bits of TCR_EL2 and VTCR_EL2 when
configuring them, which could lead to unexpected behaviour when an
architectural meaning is defined for those bits.

Set the RES1 bits to avoid issues.

Signed-off-by: Mark Rutland <mark.rutland at arm.com>
Cc: Catalin Marinas <catalin.marinas at arm.com>
Cc: Christoffer Dall <christoffer.dall at linaro.org>
Cc: Marc Zyngier <marc.zyngier at arm.com>
Cc: Suzuki Poulose <suzuki.poulose at arm.com>
Cc: Will Deacon <will.deacon at arm.com>
---
 arch/arm64/include/asm/kvm_arm.h | 10 +++++++---
 1 file changed, 7 insertions(+), 3 deletions(-)

diff --git a/arch/arm64/include/asm/kvm_arm.h b/arch/arm64/include/asm/kvm_arm.h
index ac6fafb..d0dac88 100644
--- a/arch/arm64/include/asm/kvm_arm.h
+++ b/arch/arm64/include/asm/kvm_arm.h
@@ -95,6 +95,7 @@
 			 SCTLR_EL2_SA | SCTLR_EL2_I)
 
 /* TCR_EL2 Registers bits */
+#define TCR_EL2_RES1	((1 << 31) | (1 << 23))
 #define TCR_EL2_TBI	(1 << 20)
 #define TCR_EL2_PS	(7 << 16)
 #define TCR_EL2_PS_40B	(2 << 16)
@@ -106,9 +107,10 @@
 #define TCR_EL2_MASK	(TCR_EL2_TG0 | TCR_EL2_SH0 | \
 			 TCR_EL2_ORGN0 | TCR_EL2_IRGN0 | TCR_EL2_T0SZ)
 
-#define TCR_EL2_FLAGS	(TCR_EL2_PS_40B)
+#define TCR_EL2_FLAGS	(TCR_EL2_RES1 | TCR_EL2_PS_40B)
 
 /* VTCR_EL2 Registers bits */
+#define VTCR_EL2_RES1		(1 << 31)
 #define VTCR_EL2_PS_MASK	(7 << 16)
 #define VTCR_EL2_TG0_MASK	(1 << 14)
 #define VTCR_EL2_TG0_4K		(0 << 14)
@@ -147,7 +149,8 @@
  */
 #define VTCR_EL2_FLAGS		(VTCR_EL2_TG0_64K | VTCR_EL2_SH0_INNER | \
 				 VTCR_EL2_ORGN0_WBWA | VTCR_EL2_IRGN0_WBWA | \
-				 VTCR_EL2_SL0_LVL1 | VTCR_EL2_T0SZ_40B)
+				 VTCR_EL2_SL0_LVL1 | VTCR_EL2_T0SZ_40B | \
+				 VTCR_EL2_RES1)
 #define VTTBR_X		(38 - VTCR_EL2_T0SZ_40B)
 #else
 /*
@@ -158,7 +161,8 @@
  */
 #define VTCR_EL2_FLAGS		(VTCR_EL2_TG0_4K | VTCR_EL2_SH0_INNER | \
 				 VTCR_EL2_ORGN0_WBWA | VTCR_EL2_IRGN0_WBWA | \
-				 VTCR_EL2_SL0_LVL1 | VTCR_EL2_T0SZ_40B)
+				 VTCR_EL2_SL0_LVL1 | VTCR_EL2_T0SZ_40B | \
+				 VTCR_EL2_RES1)
 #define VTTBR_X		(37 - VTCR_EL2_T0SZ_40B)
 #endif
 
-- 
1.9.1



From linus.walleij at linaro.org  Mon Aug 24 06:45:18 2015
From: linus.walleij at linaro.org (Linus Walleij)
Date: Mon, 24 Aug 2015 15:45:18 +0200
Subject: [PATCH v2 5/5] arm64: add KASan support
In-Reply-To: <20150824131557.GB7557@n2100.arm.linux.org.uk>
References: <1431698344-28054-1-git-send-email-a.ryabinin@samsung.com>
 <1431698344-28054-6-git-send-email-a.ryabinin@samsung.com>
 <CACRpkdaRJJjCXR=vK1M2YhR26JZfGoBB+jcqz8r2MhERfxRzqA@mail.gmail.com>
 <CAPAsAGy-r8Z2N09wKV+e0kLfbwxd-eWK6N5Xajsnqq9jfyWqcQ@mail.gmail.com>
 <CACRpkdZmHLMxosLXjyOPdkavo=UNzmTcHOLF5vV4cS1ULfbq6A@mail.gmail.com>
 <CAPAsAGw-iawTpjJh66rQN5fqBFT6UBZCcv2eKx7JTqCXzhzpsw@mail.gmail.com>
 <CACRpkdY2i2M27gP_fXawkFrC_GFgWaKr5rEn6d47refNPiEk=g@mail.gmail.com>
 <55AE56DB.4040607@samsung.com>
 <CACRpkdYaqK8upK-3b01JbO_y+sHnk4-Hm1MfvjSy0tKUkFREtQ@mail.gmail.com>
 <20150824131557.GB7557@n2100.arm.linux.org.uk>
Message-ID: <CACRpkdYwpucRiXM05y00RQY=gKv8W6YjCNspYFRMGaM605cU0w@mail.gmail.com>

On Mon, Aug 24, 2015 at 3:15 PM, Russell King - ARM Linux
<linux at arm.linux.org.uk> wrote:
> On Tue, Jul 21, 2015 at 11:27:56PM +0200, Linus Walleij wrote:
>> On Tue, Jul 21, 2015 at 4:27 PM, Andrey Ryabinin <a.ryabinin at samsung.com> wrote:
>>
>> > I used vexpress. Anyway, it doesn't matter now, since I have an update
>> > with a lot of stuff fixed, and it works on hardware.
>> > I still need to do some work on it and tomorrow, probably, I will share.
>>
>> Ah awesome. I have a stash of ARM boards so I can test it on a
>> range of hardware once you feel it's ready.
>>
>> Sorry for pulling stuff out of your hands, people are excited about
>> KASan ARM32 as it turns out.
>
> People may be excited about it because it's a new feature, but we really
> need to consider whether gobbling up 512MB of userspace for it is a good
> idea or not.  There are programs around which like to map large amounts
> of memory into their process space, and the more we steal from them, the
> more likely these programs are to fail.

I looked at some different approaches over the last weeks for this
when playing around with KASan.

It seems since KASan was developed on 64bit systems, this was
not much of an issue for them as they could take their shadow
memory from the vmalloc space.

I think it is possible to actually just steal as much memory as is
needed to cover the kernel, and not 1/8 of the entire addressable
32bit space. So instead of covering all from 0x0-0xffffffff
at least just MODULES_VADDR thru 0xffffffff should be enough.
So if that is 0xbf000000-0xffffffff in most cases, 0x41000000
bytes, then 1/8 of that, 0x8200000, 130MB should be enough.
(Andrey need to say if this is possible.)

That will probably miss some usecases I'm not familiar with, where
the kernel is actually executing something below 0xbf000000...

I looked at taking memory from vmalloc instead, but ran into
problems since this is subject to the highmem split and KASan
need to have it's address offset at compile time. On
Ux500 I managed to remove all the static maps and steal memory
from the top of the vmalloc area instead of the beginning, but
that is probably not generally feasible.

I suspect you have better ideas than what I can come up
with though.

Yours,
Linus Walleij


From marc.zyngier at arm.com  Mon Aug 24 06:47:10 2015
From: marc.zyngier at arm.com (Marc Zyngier)
Date: Mon, 24 Aug 2015 14:47:10 +0100
Subject: [PATCH] irqchip, gicv3-its, numa: Workaround for Cavium ThunderX
 erratum 23144
In-Reply-To: <CAFpQJXUTNss=u2x7Ynd9wOObZn_ZHkcMz2+F4MKooy5jrvZ02w@mail.gmail.com>
References: <20150822131050.GK1820@rric.localdomain>	<55DAEF3C.5090303@arm.com>	<CAFpQJXVVcdag7OQnCxqyEw601Y32eO2rHCmH1_bVzyvg+OPzRA@mail.gmail.com>	<55DB11F3.1070604@arm.com>
 <CAFpQJXUTNss=u2x7Ynd9wOObZn_ZHkcMz2+F4MKooy5jrvZ02w@mail.gmail.com>
Message-ID: <55DB205E.9070205@arm.com>

On 24/08/15 14:27, Ganapatrao Kulkarni wrote:
> On Mon, Aug 24, 2015 at 6:15 PM, Marc Zyngier <marc.zyngier at arm.com> wrote:

>>>>>  static void its_enable_cavium_thunderx(void *data)
>>>>>  {
>>>>> -     struct its_node *its = data;
>>>>> +     struct its_node __maybe_unused *its = data;
>>>>>
>>>>> -     its->flags |= ITS_FLAGS_CAVIUM_THUNDERX;
>>>>> +#ifdef CONFIG_CAVIUM_ERRATUM_22375
>>>>> +     its->flags |= ITS_WORKAROUND_CAVIUM_22375;
>>>>> +     pr_info("ITS: Enabling workaround for 22375, 24313\n");
>>>>> +#endif
>>>>> +
>>>>> +#ifdef CONFIG_CAVIUM_ERRATUM_23144
>>>>> +     if (num_possible_nodes() > 1) {
>>>>> +             its->numa_node = its_get_node_thunderx(its);
>>>>
>>>> I'd rather see numa_node being always initialized to something useful.
>>>> If you're adding numa support, why can't this be initialized via
>>>> standard topology bindings?
>>> IIUC, topology defines only cpu topology.
>>
>> Well, welcome to a much more complex system where both your CPUs and
>> your IOs have some degree of affinity. This needs to be described
>> properly, and not hacked on the side.
> ok, will add description for the function.

I sense that you misunderstood what I meant. What I'd like to see is
some topology information coming from DT, showing the relationship
between a device (your ITS) and a given node (your socket). This can
then be used from two purposes:

- find the optimal affinity for a MSI so that it doesn't default to a
foreign node (a reasonable performance expectation),
- work around implementation bugs where an LPI cannot be routed to a
redistributor that is on a foreign node.

I really don't feel like adding a hack just for the second point, and
I'd rather get the big picture right so that your workaround is just a
special case of the generic one.

Thanks,

	M.
-- 
Jazz is not dead. It just smells funny...


From robherring2 at gmail.com  Mon Aug 24 06:47:00 2015
From: robherring2 at gmail.com (Rob Herring)
Date: Mon, 24 Aug 2015 08:47:00 -0500
Subject: [PATCH 1/7] drm/vc4: Add devicetree bindings for VC4.
In-Reply-To: <874mjxwyx5.fsf@eliezer.anholt.net>
References: <1439427380-2436-1-git-send-email-eric@anholt.net>
 <1439427380-2436-2-git-send-email-eric@anholt.net>
 <55CEC25E.7070303@wwwdotorg.org>
 <874mjxwyx5.fsf@eliezer.anholt.net>
Message-ID: <CAL_JsqJxiGUR5BxBPyR3-0NxqWsOxMGrWQA6cMXe2pjTom__nw@mail.gmail.com>

On Mon, Aug 17, 2015 at 1:30 PM, Eric Anholt <eric at anholt.net> wrote:
> Stephen Warren <swarren at wwwdotorg.org> writes:
>
>> On 08/12/2015 06:56 PM, Eric Anholt wrote:
>>> Signed-off-by: Eric Anholt <eric at anholt.net>
>>
>> This one definitely needs a patch description, since someone might not
>> know what a VC4 is, and "git log" won't show the text from the binding
>> doc itself. I'd suggest adding the initial paragraph of the binding doc
>> as the patch description, or more.
>>
>>> diff --git a/Documentation/devicetree/bindings/gpu/brcm,bcm-vc4.txt b/Documentation/devicetree/bindings/gpu/brcm,bcm-vc4.txt
>
>>> +- hvss:             List of references to HVS video scalers
>>> +- encoders: List of references to output encoders (HDMI, SDTV)
>>
>> Would it make sense to make all those nodes child node of the vc4
>> object. That way, there's no need to have these lists of objects; they
>> can be automatically built up as the DT is enumerated. I know that e.g.
>> the NVIDIA Tegra host1x binding works this way, and I think it may have
>> been inspired by other similar cases.
>
> I've looked at tegra, and the component system used by msm appears to be
> nicer than it.  To follow tegra's model, it looks like I need to build
> this extra bus thing corresponding to host1x that is effectively the
> drivers/base/component.c code, so that I can get at vc4's structure from
> the component drivers.
>
>> Of course, this is only appropriate if the HW modules really are
>> logically children of the VC4 HW module. Perhaps they aren't. If they
>> aren't though, I wonder what this "vc4" module actually represents in HW?
>
> It's the subsystem, same as we use a subsystem node for msm, sti,
> rockchip, imx, and exynos.  This appears to be the common model of how
> the collection of graphics-related components is represented in the DT.

I think most of these bindings are wrong. They are grouped together
because that is what DRM wants not because that reflects the h/w. So
convince me this is one block, not that it is what other people do.

Rob


From mark.rutland at arm.com  Mon Aug 24 06:47:31 2015
From: mark.rutland at arm.com (Mark Rutland)
Date: Mon, 24 Aug 2015 14:47:31 +0100
Subject: [PATCH 1/3] Docs: dt: add generic MSI bindings
In-Reply-To: <CAL_Jsq+-xKsfBwqjHnSKPxtO1muu-NLEHZTTLpSqw=sBuU1Gjw@mail.gmail.com>
References: <1437670365-20704-1-git-send-email-mark.rutland@arm.com>
 <1437670365-20704-2-git-send-email-mark.rutland@arm.com>
 <20150805165120.GB28849@leverpostej>
 <20150824101755.GC7139@leverpostej>
 <CAL_Jsq+-xKsfBwqjHnSKPxtO1muu-NLEHZTTLpSqw=sBuU1Gjw@mail.gmail.com>
Message-ID: <20150824134731.GA31344@leverpostej>

On Mon, Aug 24, 2015 at 02:37:59PM +0100, Rob Herring wrote:
> On Mon, Aug 24, 2015 at 5:17 AM, Mark Rutland <mark.rutland at arm.com> wrote:
> > On Wed, Aug 05, 2015 at 05:51:20PM +0100, Mark Rutland wrote:
> >> Rob,
> >>
> >> Do you have any objections to this, or are you happy to take this patch?
> >>
> >> There's a user of this binding (the GICv3 ITS) queued for v4.3 already in
> >> the tip tree, so either we either need to be ok with this binding or we
> >> need to rework that before v4.3.
> >
> > Sorry to ping, but are you happy to take this? Marc's replied and
> > provided his ack.
> 
> Sorry. Looks fine to me, so I'll apply.

Cheers!

> What about patch 2 and 3? I can't find patch 3 in my mail.

Those should wait for now.

We don't yet have a user and there's ongoing discussion w.r.t. the PCI
parts that I expect will pick up again as people return from LPC.

Thanks,
Mark.


From lars at metafoo.de  Mon Aug 24 06:47:09 2015
From: lars at metafoo.de (Lars-Peter Clausen)
Date: Mon, 24 Aug 2015 15:47:09 +0200
Subject: [PATCH v4 1/2] Documentation: dt: Add Xilinx zynqmp dma device
 tree binding documentation
In-Reply-To: <1438831173-8761-1-git-send-email-punnaia@xilinx.com>
References: <1438831173-8761-1-git-send-email-punnaia@xilinx.com>
Message-ID: <55DB205D.7090802@metafoo.de>

On 08/06/2015 05:19 AM, Punnaiah Choudary Kalluri wrote:
[...]
> +Optional properties:
> +- xlnx,include-sg: Indicates the controller to operate in simple or scatter
> +		   gather dma mode
> +- xlnx,ratectrl: Scheduling interval in terms of clock cycles for
> +		 source AXI transaction
> +- xlnx,overfetch: Tells whether the channel is allowed to over fetch the data
> +- xlnx,src-issue: Number of AXI outstanding transactions on source side
> +- xlnx,desc-axi-cohrnt: Tells whether the AXI transactions generated for the
> +			descriptor read are marked Non-coherent
> +- xlnx,src-axi-cohrnt: Tells whether the AXI transactions generated for the
> +			source descriptor payload are marked Non-coherent
> +- xlnx,dst-axi-cohrnt: Tells whether the AXI transactions generated for the
> +			dst descriptor payload are marked Non-coherent
> +- xlnx,desc-axi-qos: AXI QOS bits to be used for descriptor fetch
> +- xlnx,src-axi-qos: AXI QOS bits to be used for data read
> +- xlnx,dst-axi-qos: AXI QOS bits to be used for data write
> +- xlnx,desc-axi-cache: AXI cache bits to be used for descriptor fetch.
> +- xlnx,desc-axi-cache: AXI cache bits to be used for data read
> +- xlnx,desc-axi-cache: AXI cache bits to be used for data write
> +- xlnx,src-burst-len: AXI length for data read. Support only power of 2 values
> +		      i.e 1,2,4,8 and 16
> +- xlnx,dst-burst-len: AXI length for data write. Support only power of 2 values
> +		      i.e 1,2,4,8 and 16

None of these really belong into the devicetree. This is all runtime
configuration data.

- Lars


From lee.jones at linaro.org  Mon Aug 24 06:54:22 2015
From: lee.jones at linaro.org (Lee Jones)
Date: Mon, 24 Aug 2015 14:54:22 +0100
Subject: [PATCH-v6 5/6] mfd: 88pm800: Set default interrupt clear method
In-Reply-To: <1436358392-15449-6-git-send-email-vaibhav.hiremath@linaro.org>
References: <1436358392-15449-1-git-send-email-vaibhav.hiremath@linaro.org>
 <1436358392-15449-6-git-send-email-vaibhav.hiremath@linaro.org>
Message-ID: <20150824135422.GF3237@x1>

On Wed, 08 Jul 2015, Vaibhav Hiremath wrote:

> As per the spec, bit 1 (INT_CLEAR_MODE) of reg addr 0xe
> (page 0) controls the method of clearing interrupt
> status of 88pm800 family of devices;
> 
>   0: clear on read
>   1: clear on write
> 
> If pdata is not coming from board file, then set the
> default irq clear method to "irq clear on write"
> 
> Also, as suggested by "Lee Jones" renaming variable field
> to appropriate name and removed unnecessary field
> pm80x_chip.irq_mode, using platform_data.irq_clr_method.
> 
> Signed-off-by: Zhao Ye <zhaoy at marvell.com>
> Signed-off-by: Vaibhav Hiremath <vaibhav.hiremath at linaro.org>
> Reviewed-by: Krzysztof Kozlowski <k.kozlowski at samsung.com>
> ---
>  drivers/mfd/88pm800.c       | 15 ++++++++++-----
>  include/linux/mfd/88pm80x.h |  9 +++++++--
>  2 files changed, 17 insertions(+), 7 deletions(-)

[...]

> +#define PM800_WAKEUP2_INT_READ_CLEAR	(0 << 1)
> +#define PM800_WAKEUP2_INT_WRITE_CLEAR	(1 << 1)

Use BIT().

> +/* Used by irq_clr_method */
> +#define PM800_IRQ_CLR_ON_READ	0
> +#define PM800_IRQ_CLR_ON_WRITE	1

> -	int irq_mode;		/* Clear interrupt by read/write(0/1) */
> +	bool irq_clr_method;		/* Clear interrupt by read/write(0/1) */

> +	irq_clr_mode = pdata->irq_clr_method == PM800_IRQ_CLR_ON_WRITE ?
> +		PM800_WAKEUP2_INT_WRITE_CLEAR : PM800_WAKEUP2_INT_READ_CLEAR;
> +	ret = regmap_update_bits(map, PM800_WAKEUP2, mask, irq_clr_mode);

This is pretty convoluted.

For starters you're abusing the 'bool' type here.  Bool is either
'true' or 'false', so at the very least you should rename
'irq_clr_method' to 'irq_clr_on_write'.

Then you can do: 

	irq_clr_mode = pdata->irq_clr_on_write ?
		PM800_WAKEUP2_INT_WRITE_CLEAR : PM800_WAKEUP2_INT_READ_CLEAR;

However, what I suggest you really do is share
PM800_WAKEUP2_INT_{READ,WRITE}_CLEAR with platform data and just pass
the value through directly.

-- 
Lee Jones
Linaro STMicroelectronics Landing Team Lead
Linaro.org ? Open source software for ARM SoCs
Follow Linaro: Facebook | Twitter | Blog


From lee.jones at linaro.org  Mon Aug 24 06:54:37 2015
From: lee.jones at linaro.org (Lee Jones)
Date: Mon, 24 Aug 2015 14:54:37 +0100
Subject: [PATCH-v6 3/6] mfd: 88pm800: Get pdata from 'device' rather than
 passing as a parameter
In-Reply-To: <1436358392-15449-4-git-send-email-vaibhav.hiremath@linaro.org>
References: <1436358392-15449-1-git-send-email-vaibhav.hiremath@linaro.org>
 <1436358392-15449-4-git-send-email-vaibhav.hiremath@linaro.org>
Message-ID: <20150824135437.GG3237@x1>

On Wed, 08 Jul 2015, Vaibhav Hiremath wrote:

> Currently the device_xxx_init() fns take pdata as an input parameter to
> the fn, but the cleaner approach would be to use dev_get_platdata() to
> get the pdata.
> So this patch changes the code accordingly.
> 
> Signed-off-by: Vaibhav Hiremath <vaibhav.hiremath at linaro.org>
> ---
>  drivers/mfd/88pm800.c | 29 ++++++++++++++---------------
>  1 file changed, 14 insertions(+), 15 deletions(-)

Acked-by: Lee Jones <lee.jones at linaro.org>

> diff --git a/drivers/mfd/88pm800.c b/drivers/mfd/88pm800.c
> index 95c418c..af8232f 100644
> --- a/drivers/mfd/88pm800.c
> +++ b/drivers/mfd/88pm800.c
> @@ -254,11 +254,11 @@ static const struct regmap_irq pm800_irqs[] = {
>  	},
>  };
>  
> -static int device_gpadc_init(struct pm80x_chip *chip,
> -				       struct pm80x_platform_data *pdata)
> +static int device_gpadc_init(struct pm80x_chip *chip)
>  {
>  	struct pm80x_subchip *subchip = chip->subchip;
>  	struct regmap *map = subchip->regmap_gpadc;
> +	struct pm80x_platform_data *pdata = dev_get_platdata(chip->dev);
>  	int data = 0, mask = 0, ret = 0;
>  
>  	if (!map) {
> @@ -320,17 +320,17 @@ out:
>  	return ret;
>  }
>  
> -static int device_onkey_init(struct pm80x_chip *chip,
> -				struct pm80x_platform_data *pdata)
> +static int device_onkey_init(struct pm80x_chip *chip)
>  {
>  	return mfd_add_devices(chip->dev, 0, &onkey_devs[0],
>  			      ARRAY_SIZE(onkey_devs), &onkey_resources[0], 0,
>  			      NULL);
>  }
>  
> -static int device_rtc_init(struct pm80x_chip *chip,
> -				struct pm80x_platform_data *pdata)
> +static int device_rtc_init(struct pm80x_chip *chip)
>  {
> +	struct pm80x_platform_data *pdata = dev_get_platdata(chip->dev);
> +
>  	if (pdata) {
>  		rtc_devs[0].platform_data = pdata->rtc;
>  		rtc_devs[0].pdata_size =
> @@ -341,8 +341,7 @@ static int device_rtc_init(struct pm80x_chip *chip,
>  			      ARRAY_SIZE(rtc_devs), NULL, 0, NULL);
>  }
>  
> -static int device_regulator_init(struct pm80x_chip *chip,
> -					   struct pm80x_platform_data *pdata)
> +static int device_regulator_init(struct pm80x_chip *chip)
>  {
>  	return mfd_add_devices(chip->dev, 0, &regulator_devs[0],
>  			      ARRAY_SIZE(regulator_devs), NULL, 0, NULL);
> @@ -463,11 +462,11 @@ static void pm800_pages_exit(struct pm80x_chip *chip)
>  		i2c_unregister_device(subchip->gpadc_page);
>  }
>  
> -static int device_800_init(struct pm80x_chip *chip,
> -				     struct pm80x_platform_data *pdata)
> +static int device_800_init(struct pm80x_chip *chip)
>  {
>  	int ret;
>  	unsigned int val;
> +	struct pm80x_platform_data *pdata = dev_get_platdata(chip->dev);
>  
>  	/*
>  	 * alarm wake up bit will be clear in device_irq_init(),
> @@ -483,7 +482,7 @@ static int device_800_init(struct pm80x_chip *chip,
>  			pdata->rtc->rtc_wakeup = 1;
>  	}
>  
> -	ret = device_gpadc_init(chip, pdata);
> +	ret = device_gpadc_init(chip);
>  	if (ret < 0) {
>  		dev_err(chip->dev, "[%s]Failed to init gpadc\n", __func__);
>  		goto out;
> @@ -497,19 +496,19 @@ static int device_800_init(struct pm80x_chip *chip,
>  		goto out;
>  	}
>  
> -	ret = device_onkey_init(chip, pdata);
> +	ret = device_onkey_init(chip);
>  	if (ret) {
>  		dev_err(chip->dev, "Failed to add onkey subdev\n");
>  		goto out_dev;
>  	}
>  
> -	ret = device_rtc_init(chip, pdata);
> +	ret = device_rtc_init(chip);
>  	if (ret) {
>  		dev_err(chip->dev, "Failed to add rtc subdev\n");
>  		goto out;
>  	}
>  
> -	ret = device_regulator_init(chip, pdata);
> +	ret = device_regulator_init(chip);
>  	if (ret) {
>  		dev_err(chip->dev, "Failed to add regulators subdev\n");
>  		goto out;
> @@ -575,7 +574,7 @@ static int pm800_probe(struct i2c_client *client,
>  		goto err_device_init;
>  	}
>  
> -	ret = device_800_init(chip, pdata);
> +	ret = device_800_init(chip);
>  	if (ret) {
>  		dev_err(chip->dev, "Failed to initialize 88pm800 devices\n");
>  		goto err_device_init;

-- 
Lee Jones
Linaro STMicroelectronics Landing Team Lead
Linaro.org ? Open source software for ARM SoCs
Follow Linaro: Facebook | Twitter | Blog


From lee.jones at linaro.org  Mon Aug 24 06:54:50 2015
From: lee.jones at linaro.org (Lee Jones)
Date: Mon, 24 Aug 2015 14:54:50 +0100
Subject: [PATCH-v6 1/6] mfd: 88pm800: remove duplicate dev_err calls
 during probe
In-Reply-To: <1436358392-15449-2-git-send-email-vaibhav.hiremath@linaro.org>
References: <1436358392-15449-1-git-send-email-vaibhav.hiremath@linaro.org>
 <1436358392-15449-2-git-send-email-vaibhav.hiremath@linaro.org>
Message-ID: <20150824135450.GH3237@x1>

On Wed, 08 Jul 2015, Vaibhav Hiremath wrote:

> During probe, inside fn device_800_init(), submodule init is
> happening and the same error message is getting printed in both
> the places, <subdev>_init() and inside device_800_init().
> 
> So this patch gets rid of dev_err from <subdev>_init() fns.
> 
> Signed-off-by: Vaibhav Hiremath <vaibhav.hiremath at linaro.org>
> ---
>  drivers/mfd/88pm800.c | 32 ++++----------------------------
>  1 file changed, 4 insertions(+), 28 deletions(-)

Acked-by: Lee Jones <lee.jones at linaro.org>

> diff --git a/drivers/mfd/88pm800.c b/drivers/mfd/88pm800.c
> index 841717a..0c5470e 100644
> --- a/drivers/mfd/88pm800.c
> +++ b/drivers/mfd/88pm800.c
> @@ -308,59 +308,35 @@ static int device_gpadc_init(struct pm80x_chip *chip,
>  	return 0;
>  
>  out:
> -	dev_info(chip->dev, "pm800 device_gpadc_init: Failed!\n");
>  	return ret;
>  }
>  
>  static int device_onkey_init(struct pm80x_chip *chip,
>  				struct pm80x_platform_data *pdata)
>  {
> -	int ret;
> -
> -	ret = mfd_add_devices(chip->dev, 0, &onkey_devs[0],
> +	return mfd_add_devices(chip->dev, 0, &onkey_devs[0],
>  			      ARRAY_SIZE(onkey_devs), &onkey_resources[0], 0,
>  			      NULL);
> -	if (ret) {
> -		dev_err(chip->dev, "Failed to add onkey subdev\n");
> -		return ret;
> -	}
> -
> -	return 0;
>  }
>  
>  static int device_rtc_init(struct pm80x_chip *chip,
>  				struct pm80x_platform_data *pdata)
>  {
> -	int ret;
> -
>  	if (pdata) {
>  		rtc_devs[0].platform_data = pdata->rtc;
>  		rtc_devs[0].pdata_size =
>  				pdata->rtc ? sizeof(struct pm80x_rtc_pdata) : 0;
>  	}
> -	ret = mfd_add_devices(chip->dev, 0, &rtc_devs[0],
> -			      ARRAY_SIZE(rtc_devs), NULL, 0, NULL);
> -	if (ret) {
> -		dev_err(chip->dev, "Failed to add rtc subdev\n");
> -		return ret;
> -	}
>  
> -	return 0;
> +	return mfd_add_devices(chip->dev, 0, &rtc_devs[0],
> +			      ARRAY_SIZE(rtc_devs), NULL, 0, NULL);
>  }
>  
>  static int device_regulator_init(struct pm80x_chip *chip,
>  					   struct pm80x_platform_data *pdata)
>  {
> -	int ret;
> -
> -	ret = mfd_add_devices(chip->dev, 0, &regulator_devs[0],
> +	return mfd_add_devices(chip->dev, 0, &regulator_devs[0],
>  			      ARRAY_SIZE(regulator_devs), NULL, 0, NULL);
> -	if (ret) {
> -		dev_err(chip->dev, "Failed to add regulator subdev\n");
> -		return ret;
> -	}
> -
> -	return 0;
>  }
>  
>  static int device_irq_init_800(struct pm80x_chip *chip)

-- 
Lee Jones
Linaro STMicroelectronics Landing Team Lead
Linaro.org ? Open source software for ARM SoCs
Follow Linaro: Facebook | Twitter | Blog


From robherring2 at gmail.com  Mon Aug 24 06:56:14 2015
From: robherring2 at gmail.com (Rob Herring)
Date: Mon, 24 Aug 2015 08:56:14 -0500
Subject: [PATCH 1/7] drm/vc4: Add devicetree bindings for VC4.
In-Reply-To: <1439427380-2436-2-git-send-email-eric@anholt.net>
References: <1439427380-2436-1-git-send-email-eric@anholt.net>
 <1439427380-2436-2-git-send-email-eric@anholt.net>
Message-ID: <CAL_JsqKhfQS46NwbTq0PNDpnNuztnRkcK+WDhFMaayE_8dDt3Q@mail.gmail.com>

On Wed, Aug 12, 2015 at 7:56 PM, Eric Anholt <eric at anholt.net> wrote:
> Signed-off-by: Eric Anholt <eric at anholt.net>
> ---
>  .../devicetree/bindings/gpu/brcm,bcm-vc4.txt       | 83 ++++++++++++++++++++++
>  1 file changed, 83 insertions(+)
>  create mode 100644 Documentation/devicetree/bindings/gpu/brcm,bcm-vc4.txt
>
> diff --git a/Documentation/devicetree/bindings/gpu/brcm,bcm-vc4.txt b/Documentation/devicetree/bindings/gpu/brcm,bcm-vc4.txt
> new file mode 100644
> index 0000000..2b13e61
> --- /dev/null
> +++ b/Documentation/devicetree/bindings/gpu/brcm,bcm-vc4.txt
> @@ -0,0 +1,83 @@
> +Broadcom VC4 GPU
> +
> +The VC4 device present on the Raspberry Pi includes a display system
> +with HDMI output and the HVS scaler for compositing display planes.
> +
> +Required properties for VC4:
> +- compatible:  Should be "brcm,vc4"
> +- crtcs:       List of references to pixelvalve scanout engines
> +- hvss:                List of references to HVS video scalers
> +- encoders:    List of references to output encoders (HDMI, SDTV)

Creating these links is what the OF graph binding is for. Please use
it. Plus this is a DRMism in the binding.

> +
> +Required properties for Pixel Valve:
> +- compatible:  Should be "brcm,vc4-pixelvalve"

There's only one version of IP and all chips have the same bugs? You
should have chip names in the compatible strings.

> +- reg:         Physical base address and length of the PV's registers
> +- interrupts:  The interrupt number
> +                 See bindings/interrupt-controller/brcm,bcm2835-armctrl-ic.txt
> +
> +Required properties for HVS:
> +- compatible:  Should be "brcm,vc4-hvs"
> +- reg:         Physical base address and length of the HVS's registers
> +- interrupts:  The interrupt number
> +                 See bindings/interrupt-controller/brcm,bcm2835-armctrl-ic.txt
> +
> +Required properties for HDMI
> +- compatible:  Should be "brcm,vc4-hdmi"
> +- reg:         Physical base address and length of the two register ranges
> +                 ("HDMI" and "HD")
> +- interrupts:  The interrupt numbers
> +                 See bindings/interrupt-controller/brcm,bcm2835-armctrl-ic.txt
> +- ddc:         phandle of the I2C controller used for DDC EDID probing
> +- crtc:                phandle to the pixelvalve CRTC the HDMI encoder is attached to

Same comment about OF graph.

> +
> +Optional properties for HDMI:
> +- hpd-gpio:    The GPIO pin for HDMI hotplug detect (if it doesn't appear
> +                 as an interrupt/status bit in the HDMI controller
> +                 itself).  See bindings/pinctrl/brcm,bcm2835-gpio.txt

Use the hdmi-connector binding. This doesn't belong here. The clue is
your comment in parenthesis.

Rob


From stuart.yoder at freescale.com  Mon Aug 24 06:58:26 2015
From: stuart.yoder at freescale.com (Stuart Yoder)
Date: Mon, 24 Aug 2015 13:58:26 +0000
Subject: [PATCH 0/2] arm64: ignore memory outside of the linear range
In-Reply-To: <20150824092256.GA11262@arm.com>
References: <1439890482-20798-1-git-send-email-ard.biesheuvel@linaro.org>
 <CY1PR0301MB0748FC71E6866C8AFACAAFF687780@CY1PR0301MB0748.namprd03.prod.outlook.com>
 <CAKv+Gu-OQ4VyCqe=mEDOrrfAtAWTfRtAiqXMGSVjJxOH6xi4Ow@mail.gmail.com>
 <20150824092256.GA11262@arm.com>
Message-ID: <CY1PR0301MB0748EAE8103DDF771A37785787620@CY1PR0301MB0748.namprd03.prod.outlook.com>



> -----Original Message-----
> From: Will Deacon [mailto:will.deacon at arm.com]
> Sent: Monday, August 24, 2015 4:23 AM
> To: Ard Biesheuvel
> Cc: linux-arm-kernel at lists.infradead.org; Mark Rutland; Catalin Marinas; robh at kernel.org; Yoder Stuart-B08248
> Subject: Re: [PATCH 0/2] arm64: ignore memory outside of the linear range
> 
> On Mon, Aug 24, 2015 at 09:00:43AM +0100, Ard Biesheuvel wrote:
> > >> This is a followup to the single patch I posted on Aug 15th to ignore
> > >> RAM that cannot be covered by the linear mapping. Instead of clipping
> > >> the memory after the fact, this clips the memory before installing the
> > >> regions into the memblock memory table.
> > >>
> > >> This is basically the approach that Mark Rutland suggested here
> > >>
> > >> http://article.gmane.org/gmane.linux.ports.arm.kernel/430239
> > >>
> > >> but modified to correctly consider the base of the kernel image as the
> > >> start of the linear mapping.
> > >>
> > >> Ard Biesheuvel (2):
> > >>   of/fdt: make memblock maximum physical address arch configurable
> > >>   arm64: set MAX_MEMBLOCK_ADDR according to linear region size
> > >>
> > >>  arch/arm64/include/asm/memory.h |  8 ++++++++
> > >>  drivers/of/fdt.c                | 12 +++++++-----
> > >>  2 files changed, 15 insertions(+), 5 deletions(-)
> > >
> > > Tested on Freescale LS2085ARDB which has a split memory region
> > > that triggers the bug.
> > >
> > > Tested-by: Stuart Yoder <stuart.yoder at freescale.com>
> > >
> >
> > Will you be picking up this series for v4.3? If so, do you need me to
> > resend it with the tags added?
> 
> Sorry, I missed Rob's ack on the of/fdt.c change. I'll pick these up
> later today, no need to resend.

Are we sending to stable as well?

Stuart


From cov at codeaurora.org  Mon Aug 24 06:55:26 2015
From: cov at codeaurora.org (Christopher Covington)
Date: Mon, 24 Aug 2015 09:55:26 -0400
Subject: [PATCH] arm: Handle starting up in secure mode
Message-ID: <1440424572-27116-1-git-send-email-cov@codeaurora.org>

ARM Linux appears to have never been made aware of the ARMv7 security
extensions. When CONFIG_ARM_SEC_EXT=y, have it probe for its security
state by checking whether CNTFRQ is writeable and potentially make
mode changes based on the information. The most features are available
from hypervisor (HYP) mode, so switch to it possible. Failing that,
prefer non-secure supervisor (SVC) mode to secure supervisor mode.

Signed-off-by: Christopher Covington <cov at codeaurora.org>
---
 arch/arm/include/asm/sec.h         |  27 +++++++
 arch/arm/include/uapi/asm/ptrace.h |   1 +
 arch/arm/kernel/Makefile           |   1 +
 arch/arm/kernel/head.S             |   3 +
 arch/arm/kernel/mon-stub.S         | 158 +++++++++++++++++++++++++++++++++++++
 arch/arm/mm/Kconfig                |  20 ++++-
 6 files changed, 206 insertions(+), 4 deletions(-)
 create mode 100644 arch/arm/include/asm/sec.h
 create mode 100644 arch/arm/kernel/mon-stub.S

diff --git a/arch/arm/include/asm/sec.h b/arch/arm/include/asm/sec.h
new file mode 100644
index 0000000..4a9a573
--- /dev/null
+++ b/arch/arm/include/asm/sec.h
@@ -0,0 +1,27 @@
+/*
+ * Copyright (c) 2014, The Linux Foundation. All rights reserved.
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License version 2 and
+ * only 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.
+ */
+
+#ifndef SEC_H
+#define SEC_H
+
+#ifndef __ASSEMBLY__
+
+#ifdef CONFIG_ARM_SEC_EXT
+extern int __boot_cpu_secure;
+#else
+#define __boot_cpu_secure 0
+#endif
+
+#endif /* ! __ASSEMBLY__ */
+
+#endif /* SEC_H */
diff --git a/arch/arm/include/uapi/asm/ptrace.h b/arch/arm/include/uapi/asm/ptrace.h
index 5af0ed1..70ff6bf 100644
--- a/arch/arm/include/uapi/asm/ptrace.h
+++ b/arch/arm/include/uapi/asm/ptrace.h
@@ -53,6 +53,7 @@
 #endif
 #define FIQ_MODE	0x00000011
 #define IRQ_MODE	0x00000012
+#define MON_MODE	0x00000016
 #define ABT_MODE	0x00000017
 #define HYP_MODE	0x0000001a
 #define UND_MODE	0x0000001b
diff --git a/arch/arm/kernel/Makefile b/arch/arm/kernel/Makefile
index e69f7a1..a60a0f7 100644
--- a/arch/arm/kernel/Makefile
+++ b/arch/arm/kernel/Makefile
@@ -87,6 +87,7 @@ head-y			:= head$(MMUEXT).o
 obj-$(CONFIG_DEBUG_LL)	+= debug.o
 obj-$(CONFIG_EARLY_PRINTK)	+= early_printk.o
 
+obj-$(CONFIG_ARM_SEC_EXT)	+= mon-stub.o
 obj-$(CONFIG_ARM_VIRT_EXT)	+= hyp-stub.o
 ifeq ($(CONFIG_ARM_PSCI),y)
 obj-y				+= psci.o psci-call.o
diff --git a/arch/arm/kernel/head.S b/arch/arm/kernel/head.S
index 29e2991..d137ba4 100644
--- a/arch/arm/kernel/head.S
+++ b/arch/arm/kernel/head.S
@@ -85,6 +85,9 @@ ENTRY(stext)
  THUMB(	.thumb			)	@ switch to Thumb now.
  THUMB(1:			)
 
+#ifdef CONFIG_ARM_SEC_EXT
+	bl	__mon_stub_install
+#endif
 #ifdef CONFIG_ARM_VIRT_EXT
 	bl	__hyp_stub_install
 #endif
diff --git a/arch/arm/kernel/mon-stub.S b/arch/arm/kernel/mon-stub.S
new file mode 100644
index 0000000..ab1a361
--- /dev/null
+++ b/arch/arm/kernel/mon-stub.S
@@ -0,0 +1,158 @@
+/*
+ * Copyright (c) 2014, The Linux Foundation. All rights reserved.
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License version 2 and
+ * only 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/linkage.h>
+#include <asm/assembler.h>
+#include <asm/sec.h>
+
+.data
+ENTRY(__boot_cpu_secure)
+	.long	0
+.text
+
+/*
+ * ARM Linux has the most features available in hypervisor mode and
+ * running in non-secure mode is recommended. Thus, try to get into
+ * hypervisor mode if we're not already there, or failing that, try
+ * to get into non-secure supervisor mode.
+ */
+ENTRY(__mon_stub_install)
+	/*
+	 * Store the mode field of the CPSR in r4 and return early if we're
+	 * already in hypervisor mode.
+	 */
+	mrs	r4, cpsr
+	and	r4, r4, #MODE_MASK
+	cmp	r4, #HYP_MODE
+	reteq	lr
+
+	/*
+	 * Save the link register in a non-banked register, r5, so that we
+	 * still have access to it after mode switches.
+	 */
+	mov	r5, lr
+
+	/*
+	 * Read ID_PFR1 and store the value in r6. This register indicates
+	 * the presence of the security and virtualization extensions. The
+	 * former is interesting because we must traverse secure monitor mode
+	 * to get to hypervisor mode and it allows easy manipulation of
+	 * exception vectors via the Vector Base Address Register (VBAR).
+	 *
+	 * ID_PFR1 also indicates whether the generic timer is present, which
+	 * has a handy register for our purposes, CNTFRQ. Accesses won't trap
+	 * even with higher exception levels in AArch64 and writes will only
+	 * succeed from the highest exception level on a system (the undefined
+	 * exception from a failed write is used as a branch).
+	 */
+
+	mrc   p15, 0, r6, c0, c1, 1	@ ID_PFR1
+
+	/*
+	 * If we're in monitor mode then we know the security setting and can
+	 * begin the transition to hypervisor or non-secure supervisor mode
+	 * immediately.
+	 */
+
+	cmp	r4, #MON_MODE
+	beq	monitor
+
+	/*
+	 * Check that the security extensions and generic timer are present.
+	 */
+	and	r7, r6, #0xf0
+	cmp	r7, #0x10
+	cmpne	r7, #0x20
+	retne	lr
+	and	r8, r6, #0xf0000
+	cmp	r8, #0x10000
+	retne	lr
+
+	/*
+	 * Set things up so that if a CNTFRQ access causes an undefined
+	 * instruction exception, we return to the address indicated in r5
+	 * in the mode indicated in r4.
+	 */
+	adr	r7, __mon_stub_vectors
+	mcr	p15, 0, r7, c12, c0, 0	@ set vector base address (VBAR)
+
+	mrc	p15, 0, r7, c14, c0, 0	@ CNTFRQ
+	mcr	p15, 0, r7, c14, c0, 0	@ CNTFRQ
+
+	/*
+	 * If we got this far, switch to monitor mode and prepare for further
+	 * switching.
+	 */
+	cps	#MON_MODE
+
+monitor:
+	/*
+	 * TODO: Handle SIF and separate secure physical memory in general
+	 */
+	mrc	p15, 0, r8, c1, c1, 0	@ get secure configuration (SCR)
+	orr	r8, r8, #1		@ non-secure (NS)
+
+	mov	r8, #1
+	ldr	r7, =__boot_cpu_secure
+	str	r8, [r7]
+
+	/*
+	 * See whether the switch will be to hypervisor or supervisor.
+	 */
+	and	r7, r6, #0xf000
+	cmp	r7, #0x1000
+	mcrne	p15, 0, r8, c1, c1, 0	@ set secure configuration (SCR)
+	bne	supervise
+
+	orr	r8, r8, #0x100		@ hypercall enable (HCE)
+	mcr	p15, 0, r8, c1, c1, 0	@ set secure configuration (SCR)
+
+	mov	lr, r5
+	msr	spsr, #HYP_MODE
+	__ERET
+
+supervise:
+	/*
+	 * Switch to supervisor mode and return using a non-banked register,
+	 * in case we're not in the mode we started out in.
+	 */
+	cps	#SVC_MODE
+	ret	r5
+ENDPROC(__mon_stub_install)
+
+ENTRY(__mon_stub_do_undef)
+	/*
+	 * Return to the address at r5 with the mode in r4. If there is an
+	 * illegal or unimplemented mode in r4 the cpsr write will cause an
+	 * undefined exception, recursing. To avoid that, put the current
+	 * mode in r4 before performing the write.
+	 */
+	mrs	r6, cpsr
+	bic	r7, r6, #MODE_MASK
+	orr	r7, r7, r4
+	and	r4, r6, #MODE_MASK
+	msr	cpsr, r7
+	ret	r5
+ENDPROC(__mon_stub_do_undef)
+
+.align 5
+__mon_stub_vectors:
+__mon_stub_reset:	W(b)	.
+__mon_stub_und:		W(b)	__mon_stub_do_undef
+__mon_stub_call:	W(b)	.
+__mon_stub_pabort:	W(b)	.
+__mon_stub_dabort:	W(b)	.
+__mon_stub_trap:	W(b)	.
+__mon_stub_irq:		W(b)	.
+__mon_stub_fiq:		W(b)	.
+ENDPROC(__mon_stub_vectors)
diff --git a/arch/arm/mm/Kconfig b/arch/arm/mm/Kconfig
index 7c6b976..32fa451 100644
--- a/arch/arm/mm/Kconfig
+++ b/arch/arm/mm/Kconfig
@@ -676,7 +676,7 @@ config ARM_THUMBEE
 	  make use of it. Say N for code that can run on CPUs without ThumbEE.
 
 config ARM_VIRT_EXT
-	bool
+	bool "Support for Virtualization Extensions"
 	depends on MMU
 	default y if CPU_V7
 	help
@@ -684,9 +684,21 @@ config ARM_VIRT_EXT
 	  Extensions to install hypervisors without run-time firmware
 	  assistance.
 
-	  A compliant bootloader is required in order to make maximum
-	  use of this feature.  Refer to Documentation/arm/Booting for
-	  details.
+	  A compliant bootloader or enabling ARM_SEC_EXT is required in
+	  order to make maximum use of this feature. Refer to
+	  Documentation/arm/Booting for details.
+
+config ARM_SEC_EXT
+	bool "Support for Security Extensions"
+	depends on MMU
+	default n
+	help
+	  Say Y to have the kernel check for the presence of the ARM Security
+	  Extensions and where possible, use them to switch to preferred
+	  security and mode settings. This decreases the kernel's dependency
+	  on bootloaders.
+
+	  If unsure, say N.
 
 config SWP_EMULATE
 	bool "Emulate SWP/SWPB instructions" if !SMP
-- 
Qualcomm Innovation Center, Inc.
The Qualcomm Innovation Center, Inc. is a member of the Code Aurora Forum,
a Linux Foundation Collaborative Project



From shawn.lin at rock-chips.com  Mon Aug 24 07:02:32 2015
From: shawn.lin at rock-chips.com (Shawn Lin)
Date: Mon, 24 Aug 2015 22:02:32 +0800
Subject: [RESEND PATCH] clk: rockchip: disable init state before mmc card
 initialization
In-Reply-To: <120036049.vlT25D4un8@phil>
References: <1440404863-14350-1-git-send-email-shawn.lin@rock-chips.com>
 <120036049.vlT25D4un8@phil>
Message-ID: <55DB23F8.1000704@rock-chips.com>

On 2015/8/24 18:01, Heiko Stuebner wrote:
> Hi Shawn,
>
> Am Montag, 24. August 2015, 16:27:43 schrieb Shawn Lin:
>> mmc host controller's IO input/output timing is unpredictable if
>> bootloader execute tuning for HS200 mode. It might make kernel failed
>> to initialize mmc card in identification mode. The root cause is
>> tuning phase and degree setting for HS200 mode in bootloader aren't
>> applicable to that of identification mode in kernel stage. Anyway, we
>> can't force all bootloaders to disable tuning phase and degree setting
>> before into kernel. Simply disable it in rockchip_clk_register_mmc.
>>
>> Signed-off-by: Shawn Lin <shawn.lin at rock-chips.com>
>>
>> ---
>>
>>   drivers/clk/rockchip/clk-mmc-phase.c | 20 ++++++++++++++++++++
>>   1 file changed, 20 insertions(+)
>>
>> diff --git a/drivers/clk/rockchip/clk-mmc-phase.c
>> b/drivers/clk/rockchip/clk-mmc-phase.c index e9f8df32..ae21592 100644
>> --- a/drivers/clk/rockchip/clk-mmc-phase.c
>> +++ b/drivers/clk/rockchip/clk-mmc-phase.c
>> @@ -38,6 +38,9 @@ static unsigned long rockchip_mmc_recalc(struct clk_hw
>> *hw, #define ROCKCHIP_MMC_DEGREE_MASK 0x3
>>   #define ROCKCHIP_MMC_DELAYNUM_OFFSET 2
>>   #define ROCKCHIP_MMC_DELAYNUM_MASK (0xff << ROCKCHIP_MMC_DELAYNUM_OFFSET)
>> +#define ROCKCHIP_MMC_INIT_STATE_DISABLE (0x1)
>> +#define ROCKCHIP_MMC_INIT_STATE_SHIFT (1)
>> +#define ROCKCHIP_MMC_INIT_STATE_MASK  (0x1)
>
> you don't need the "()" around primitive values. Also I don't think you need
> the second MASK attribute, doing
> 	writel(HIWORD_UPDATE(ROCKCHIP_MMC_INIT_STATE_DISABLE,
> 				     ROCKCHIP_MMC_INIT_STATE_DISABLE,
> 				     mmc_clock->shift),
>
> should be enough. And thirdly I'm undecided about the naming of the constant.
> The manual describes the init_state as "Assert init_state to soft reset the
> CLKGEN.", so I guess I'd prefer
>
> 	ROCKCHIP_MMC_INIT_STATE_RESET

Thanks, Heiko.

Actually, I'm either not so sure how to naming this bit since if we are 
used to calling a bit, reset bit, which I thought it should at least do 
some reset either to state machine or to register value. But obvious it 
doesn't. Moreover, Assert/Dis-assert seems like disable/enable from my 
point. Anyway, ROCKCHIP_MMC_INIT_STATE_RESET is okay for me, but I think 
I should add some comments for these code.

>
> or so
>
>>
>>   #define PSECS_PER_SEC 1000000000000LL
>>
>> @@ -119,6 +122,21 @@ static const struct clk_ops rockchip_mmc_clk_ops = {
>>   	.set_phase	= rockchip_mmc_set_phase,
>>   };
>>
>> +static void rockchip_clk_mmc_disable_init(struct rockchip_mmc_clock
>
> I guess similar to the thoughts above, simply name this
> 	rockchip_clk_mmc_reset()
>
> or alternatively just do the reset in rockchip_clk_register_mmc directly:
>
> if (mmc_clock->shift == ROCKCHIP_MMC_INIT_STATE_SHIFT))
> 	writel(HIWORD_UPDATE(ROCKCHIP_MMC_INIT_STATE_DISABLE,
> 				     ROCKCHIP_MMC_INIT_STATE_MASK,
> 			     mmc_clock->shift),
> 	       mmc_clock->reg);
>
> as the pr_debug does not really serve a purpose.
>

Okay, rockchip_clk_mmc_reset is coming in v2 :)

>
> Heiko
>
>> *mmc_clock) +{
>> +	if (mmc_clock->shift != ROCKCHIP_MMC_INIT_STATE_SHIFT)
>> +		return;
>> +
>> +	writel(HIWORD_UPDATE(ROCKCHIP_MMC_INIT_STATE_DISABLE,
>> +			     ROCKCHIP_MMC_INIT_STATE_MASK,
>> +			     mmc_clock->shift),
>> +	       mmc_clock->reg);
>> +
>> +	pr_debug("%s: clear mmc init state to %d", __func__,
>> +		 (readl(mmc_clock->reg) >> (mmc_clock->shift)) &
>> +		 ROCKCHIP_MMC_INIT_STATE_MASK);
>> +}
>> +
>>   struct clk *rockchip_clk_register_mmc(const char *name,
>>   				const char *const *parent_names, u8 num_parents,
>>   				void __iomem *reg, int shift)
>> @@ -139,6 +157,8 @@ struct clk *rockchip_clk_register_mmc(const char *name,
>>   	mmc_clock->reg = reg;
>>   	mmc_clock->shift = shift;
>>
>> +	rockchip_clk_mmc_disable_init(mmc_clock);
>> +
>>   	if (name)
>>   		init.name = name;
>
>
>
>


-- 
Best Regards
Shawn Lin



From will.deacon at arm.com  Mon Aug 24 07:08:28 2015
From: will.deacon at arm.com (Will Deacon)
Date: Mon, 24 Aug 2015 15:08:28 +0100
Subject: [PATCH 0/2] arm64: ignore memory outside of the linear range
In-Reply-To: <CY1PR0301MB0748EAE8103DDF771A37785787620@CY1PR0301MB0748.namprd03.prod.outlook.com>
References: <1439890482-20798-1-git-send-email-ard.biesheuvel@linaro.org>
 <CY1PR0301MB0748FC71E6866C8AFACAAFF687780@CY1PR0301MB0748.namprd03.prod.outlook.com>
 <CAKv+Gu-OQ4VyCqe=mEDOrrfAtAWTfRtAiqXMGSVjJxOH6xi4Ow@mail.gmail.com>
 <20150824092256.GA11262@arm.com>
 <CY1PR0301MB0748EAE8103DDF771A37785787620@CY1PR0301MB0748.namprd03.prod.outlook.com>
Message-ID: <20150824140828.GB20147@arm.com>

On Mon, Aug 24, 2015 at 02:58:26PM +0100, Stuart Yoder wrote:
> > On Mon, Aug 24, 2015 at 09:00:43AM +0100, Ard Biesheuvel wrote:
> > > >> This is a followup to the single patch I posted on Aug 15th to ignore
> > > >> RAM that cannot be covered by the linear mapping. Instead of clipping
> > > >> the memory after the fact, this clips the memory before installing the
> > > >> regions into the memblock memory table.
> > > >>
> > > >> This is basically the approach that Mark Rutland suggested here
> > > >>
> > > >> http://article.gmane.org/gmane.linux.ports.arm.kernel/430239
> > > >>
> > > >> but modified to correctly consider the base of the kernel image as the
> > > >> start of the linear mapping.
> > > >>
> > > >> Ard Biesheuvel (2):
> > > >>   of/fdt: make memblock maximum physical address arch configurable
> > > >>   arm64: set MAX_MEMBLOCK_ADDR according to linear region size
> > > >>
> > > >>  arch/arm64/include/asm/memory.h |  8 ++++++++
> > > >>  drivers/of/fdt.c                | 12 +++++++-----
> > > >>  2 files changed, 15 insertions(+), 5 deletions(-)
> > > >
> > > > Tested on Freescale LS2085ARDB which has a split memory region
> > > > that triggers the bug.
> > > >
> > > > Tested-by: Stuart Yoder <stuart.yoder at freescale.com>
> > > >
> > >
> > > Will you be picking up this series for v4.3? If so, do you need me to
> > > resend it with the tags added?
> > 
> > Sorry, I missed Rob's ack on the of/fdt.c change. I'll pick these up
> > later today, no need to resend.
> 
> Are we sending to stable as well?

I've already pushed the patch out without a Cc stable (it's not a
regression afaict), so if you want it backported then you'll need to send
it to stable separately.

Will


From andre.przywara at arm.com  Mon Aug 24 07:14:19 2015
From: andre.przywara at arm.com (Andre Przywara)
Date: Mon, 24 Aug 2015 15:14:19 +0100
Subject: [PATCH v2 14/15] KVM: arm64: implement MSI injection in ITS
 emulation
In-Reply-To: <55BF9FB0.6070804@arm.com>
References: <1436538111-4294-1-git-send-email-andre.przywara@arm.com>
 <1436538111-4294-15-git-send-email-andre.przywara@arm.com>
 <55BB7678.5080105@linaro.org> <55BE7BA1.40403@arm.com>
 <00a201d0cdb7$70a623f0$51f26bd0$@samsung.com> <55BF2F51.6020701@linaro.org>
 <00f101d0cdcd$146a6090$3d3f21b0$@samsung.com> <55BF8AB8.5050408@linaro.org>
 <55BF9FB0.6070804@arm.com>
Message-ID: <55DB26BB.7090703@arm.com>

Hi,

On 03/08/15 18:06, Marc Zyngier wrote:
> On 03/08/15 16:37, Eric Auger wrote:
>> Andre, Pavel,
>> On 08/03/2015 11:16 AM, Pavel Fedin wrote:
>>>  Hello!
>>>
>>>> Again the case that leaves me uncomfortable is the one where the
>>>> userspace does not provide the devid whereas it must (GICv3 ITS case).
>>>
>>>  Hypothetical broken userland which does not exist for now ?
>> Yes but that's the rule to be not confident in *any* userspace, isn't it?

Well, that's only regarding safety, not regarding functionality, right?
So if we could break the kernel by not providing the flag and/or devid,
this needs to be fixed. But if it just doesn't work, that's OK.

>>
>> As of now I prefer keeping the flags at uapi level and propagate it
>> downto the kernel, as long as I don't have any answer for the unset
>> devid discrimination question. Please apologize for my stubbornness ;-)
> 
> I think this flag should be kept, as it really indicates what is valid
> in the MSI structure. It also has other benefits such as making obvious
> what userspace expects, which can then be checked against the kernel's
> own expectations.

I agree on this. Usually this kind of redundancy leads to strange code,
but this does not seem to apply here, since we can at least still guard
the assignments to demonstrate that the devid field needs to go along
with the flag.

Cheers,
Andre.


From ryabinin.a.a at gmail.com  Mon Aug 24 07:15:22 2015
From: ryabinin.a.a at gmail.com (Andrey Ryabinin)
Date: Mon, 24 Aug 2015 17:15:22 +0300
Subject: [PATCH v2 5/5] arm64: add KASan support
In-Reply-To: <CACRpkdYwpucRiXM05y00RQY=gKv8W6YjCNspYFRMGaM605cU0w@mail.gmail.com>
References: <1431698344-28054-1-git-send-email-a.ryabinin@samsung.com>
 <1431698344-28054-6-git-send-email-a.ryabinin@samsung.com>
 <CACRpkdaRJJjCXR=vK1M2YhR26JZfGoBB+jcqz8r2MhERfxRzqA@mail.gmail.com>
 <CAPAsAGy-r8Z2N09wKV+e0kLfbwxd-eWK6N5Xajsnqq9jfyWqcQ@mail.gmail.com>
 <CACRpkdZmHLMxosLXjyOPdkavo=UNzmTcHOLF5vV4cS1ULfbq6A@mail.gmail.com>
 <CAPAsAGw-iawTpjJh66rQN5fqBFT6UBZCcv2eKx7JTqCXzhzpsw@mail.gmail.com>
 <CACRpkdY2i2M27gP_fXawkFrC_GFgWaKr5rEn6d47refNPiEk=g@mail.gmail.com>
 <55AE56DB.4040607@samsung.com>
 <CACRpkdYaqK8upK-3b01JbO_y+sHnk4-Hm1MfvjSy0tKUkFREtQ@mail.gmail.com>
 <20150824131557.GB7557@n2100.arm.linux.org.uk>
 <CACRpkdYwpucRiXM05y00RQY=gKv8W6YjCNspYFRMGaM605cU0w@mail.gmail.com>
Message-ID: <CAPAsAGwji7FpUJK9O=FWYN15-rJkYMQyOt9W9ncdY9uLybxkiA@mail.gmail.com>

2015-08-24 16:45 GMT+03:00 Linus Walleij <linus.walleij at linaro.org>:
> On Mon, Aug 24, 2015 at 3:15 PM, Russell King - ARM Linux
> <linux at arm.linux.org.uk> wrote:
>> On Tue, Jul 21, 2015 at 11:27:56PM +0200, Linus Walleij wrote:
>>> On Tue, Jul 21, 2015 at 4:27 PM, Andrey Ryabinin <a.ryabinin at samsung.com> wrote:
>>>
>>> > I used vexpress. Anyway, it doesn't matter now, since I have an update
>>> > with a lot of stuff fixed, and it works on hardware.
>>> > I still need to do some work on it and tomorrow, probably, I will share.
>>>
>>> Ah awesome. I have a stash of ARM boards so I can test it on a
>>> range of hardware once you feel it's ready.
>>>
>>> Sorry for pulling stuff out of your hands, people are excited about
>>> KASan ARM32 as it turns out.
>>
>> People may be excited about it because it's a new feature, but we really
>> need to consider whether gobbling up 512MB of userspace for it is a good
>> idea or not.  There are programs around which like to map large amounts
>> of memory into their process space, and the more we steal from them, the
>> more likely these programs are to fail.
>
> I looked at some different approaches over the last weeks for this
> when playing around with KASan.
>
> It seems since KASan was developed on 64bit systems, this was
> not much of an issue for them as they could take their shadow
> memory from the vmalloc space.
>
> I think it is possible to actually just steal as much memory as is
> needed to cover the kernel, and not 1/8 of the entire addressable
> 32bit space. So instead of covering all from 0x0-0xffffffff
> at least just MODULES_VADDR thru 0xffffffff should be enough.
> So if that is 0xbf000000-0xffffffff in most cases, 0x41000000
> bytes, then 1/8 of that, 0x8200000, 130MB should be enough.
> (Andrey need to say if this is possible.)
>

Yes, ~130Mb (3G/1G split) should work. 512Mb shadow is optional.
The only advantage of 512Mb shadow is better handling of user memory
accesses bugs
(access to user memory without copy_from_user/copy_to_user/strlen_user etc API).
In case of 512Mb shadow we could to not map anything in shadow for
user addresses, so such bug will
guarantee  to crash the kernel.
In case of 130Mb, the behavior will depend on memory layout of the
current process.
So, I think it's fine to keep shadow only for kernel addresses.

> That will probably miss some usecases I'm not familiar with, where
> the kernel is actually executing something below 0xbf000000...
>
> I looked at taking memory from vmalloc instead, but ran into
> problems since this is subject to the highmem split and KASan
> need to have it's address offset at compile time. On
> Ux500 I managed to remove all the static maps and steal memory
> from the top of the vmalloc area instead of the beginning, but
> that is probably not generally feasible.
>
> I suspect you have better ideas than what I can come up
> with though.
>
> Yours,
> Linus Walleij


From vinod.koul at intel.com  Mon Aug 24 07:24:25 2015
From: vinod.koul at intel.com (Vinod Koul)
Date: Mon, 24 Aug 2015 19:54:25 +0530
Subject: [PATCH v3] dmaengine: hdmac: Add memset capabilities
In-Reply-To: <1440408075-26438-1-git-send-email-maxime.ripard@free-electrons.com>
References: <1440408075-26438-1-git-send-email-maxime.ripard@free-electrons.com>
Message-ID: <20150824142425.GL13546@localhost>

On Mon, Aug 24, 2015 at 11:21:15AM +0200, Maxime Ripard wrote:
> Just like for the XDMAC, the SoCs that embed the HDMAC don't have any kind
> of GPU, and need to accelerate a few framebuffer-related operations through
> their DMA controller.
> 
> However, unlike the XDMAC, the HDMAC doesn't have the memset capability
> built-in. That can be easily emulated though, by doing a transfer with a
> fixed address on the variable that holds the value we want to set.

Applied, thanks

-- 
~Vinod



From yingjoe.chen at mediatek.com  Mon Aug 24 07:22:20 2015
From: yingjoe.chen at mediatek.com (Yingjoe Chen)
Date: Mon, 24 Aug 2015 22:22:20 +0800
Subject: [PATCH v2 1/5] clocksource: mediatek: do not enable GPT_CLK_EVT
 when setup
In-Reply-To: <55DACCEF.8040004@linaro.org>
References: <CAGS+omD8k_Cfxv3bYyjmjtLbiavo-WmJPn0Z-CBhN_nnv65Tag@mail.gmail.com>
 <1437552878-3684-1-git-send-email-yingjoe.chen@mediatek.com>
 <55CC56C4.8080201@linaro.org> <1439820602.3414.12.camel@mtksdaap41>
 <55D5E40A.6080904@linaro.org> <1440167950.20169.29.camel@mtksdaap41>
 <55DACCEF.8040004@linaro.org>
Message-ID: <1440426140.17418.1.camel@mtksdaap41>

On Mon, 2015-08-24 at 09:51 +0200, Daniel Lezcano wrote:
> On 08/21/2015 04:39 PM, Yingjoe Chen wrote:
> 
> [ ... ]
> 
> >>    - Does the spurious interrupt occurs *every* time ? at each boot ?
> >
> > Yes. If you applied this series to enable mtk timer without this fix on
> > mt8173 or mt8135 you can reproduce it. It occurs for every boot.
> >
> > It crash before uart driver is ready, so you'll have to use earlycon to
> > see the crash log.
> 
> Can you give me the earlycon params ?

Hi Daniel,

You probably already figure this out. anyway I'm using this to enable
earlycon:

Add 'earlycon' in bootargs, and in device tree chosen part, add
"linux,stdout-path=&uart0;"

Joe.C





From gabriel.fernandez at linaro.org  Mon Aug 24 07:23:21 2015
From: gabriel.fernandez at linaro.org (Gabriel Fernandez)
Date: Mon, 24 Aug 2015 16:23:21 +0200
Subject: [PATCH v2] ARM: DT: STi: STiH418: Fix mmc0 clock configuration
Message-ID: <1440426201-23201-1-git-send-email-gabriel.fernandez@linaro.org>

This patch configure correctly the MMC-0 clock for STiH418 platform.

Signed-off-by: Gabriel Fernandez <gabriel.fernandez at linaro.org>
Acked-by: Maxime Coquelin <maxime.coquelin at st.com>
---
 arch/arm/boot/dts/stih418.dtsi | 6 ++++++
 1 file changed, 6 insertions(+)

diff --git a/arch/arm/boot/dts/stih418.dtsi b/arch/arm/boot/dts/stih418.dtsi
index 8160a75..965f881 100644
--- a/arch/arm/boot/dts/stih418.dtsi
+++ b/arch/arm/boot/dts/stih418.dtsi
@@ -99,5 +99,11 @@
 			phys = <&usb2_picophy2>;
 			phy-names = "usb";
 		};
+
+		mmc0: sdhci at 09060000 {
+			assigned-clocks = <&clk_s_c0_flexgen CLK_MMC_0>;
+			assigned-clock-parents = <&clk_s_c0_pll1 0>;
+			assigned-clock-rates = <200000000>;
+		};
 	};
 };
-- 
1.9.1



From yingjoe.chen at mediatek.com  Mon Aug 24 07:35:24 2015
From: yingjoe.chen at mediatek.com (Yingjoe Chen)
Date: Mon, 24 Aug 2015 22:35:24 +0800
Subject: [PATCH] clockevents/drivers/mtk: Fix spurious interrupt leading
 to crash
In-Reply-To: <1440423045-7883-1-git-send-email-daniel.lezcano@linaro.org>
References: <1440167950.20169.29.camel@mtksdaap41>
 <1440423045-7883-1-git-send-email-daniel.lezcano@linaro.org>
Message-ID: <1440426924.17418.11.camel@mtksdaap41>

On Mon, 2015-08-24 at 15:30 +0200, Daniel Lezcano wrote:
> After analysis done by Yingjoe Chen, the timer appears to have a pending
> interrupt when it is enabled.
>
> Fix this by acknowledging the pending interrupt when enabling the timer
> interrupt.
>
> Signed-off-by: Daniel Lezcano <daniel.lezcano at linaro.org>

Hi Daniel,


Thanks for your patch, this can fix the boot issue.
Tested-by: Yingjoe Chen <yingjoe.chen at mediatek.com>

> ---
>  drivers/clocksource/mtk_timer.c | 13 +++----------
>  1 file changed, 3 insertions(+), 10 deletions(-)
> 
> diff --git a/drivers/clocksource/mtk_timer.c b/drivers/clocksource/mtk_timer.c
> index 4cd16fb..13543a8 100644
> --- a/drivers/clocksource/mtk_timer.c
> +++ b/drivers/clocksource/mtk_timer.c
> @@ -156,14 +156,6 @@ static irqreturn_t mtk_timer_interrupt(int irq, void *dev_id)
>  	return IRQ_HANDLED;
>  }
>  
> -static void mtk_timer_global_reset(struct mtk_clock_event_device *evt)
> -{
> -	/* Disable all interrupts */
> -	writel(0x0, evt->gpt_base + GPT_IRQ_EN_REG);
> -	/* Acknowledge all interrupts */
> -	writel(0x3f, evt->gpt_base + GPT_IRQ_ACK_REG);
> -}
> -
>  static void
>  mtk_timer_setup(struct mtk_clock_event_device *evt, u8 timer, u8 option)
>  {
> @@ -183,6 +175,9 @@ static void mtk_timer_enable_irq(struct mtk_clock_event_device *evt, u8 timer)
>  {
>  	u32 val;
>  
> +        /* Acknowledge all spurious pending interrupts */
> +        writel(0x3f, evt->gpt_base + GPT_IRQ_ACK_REG);

This should use tab to indent.

> +
>  	val = readl(evt->gpt_base + GPT_IRQ_EN_REG);
>  	writel(val | GPT_IRQ_ENABLE(timer),
>  			evt->gpt_base + GPT_IRQ_EN_REG);
> @@ -232,8 +227,6 @@ static void __init mtk_timer_init(struct device_node *node)
>  	}
>  	rate = clk_get_rate(clk);
>  
> -	mtk_timer_global_reset(evt);
> -

I think we should keep this one, or at least disable irq first in
mtk_timer_enable_irq. MT8173 firmware didn't use this GPT, but I think
it is a good ideat to do it just in case firmware in some other platform
use it.

Joe.C




From will.deacon at arm.com  Mon Aug 24 07:36:20 2015
From: will.deacon at arm.com (Will Deacon)
Date: Mon, 24 Aug 2015 15:36:20 +0100
Subject: [PATCH 0/4] Efficiency cleanups
In-Reply-To: <20150821134630.GW7557@n2100.arm.linux.org.uk>
References: <CABXk95C=CpeL4mNmS6-jJ-0bMJf6fawwfs6DM1-p8FctTEFbpw@mail.gmail.com>
 <20150821133043.GV7557@n2100.arm.linux.org.uk>
 <20150821134630.GW7557@n2100.arm.linux.org.uk>
Message-ID: <20150824143619.GD20147@arm.com>

On Fri, Aug 21, 2015 at 02:46:30PM +0100, Russell King - ARM Linux wrote:
> While developing the previous patch set, I noticed that the kernel's
> "fast" exit path efficiency was not what it's supposed to be due to the
> addition of trace and context tracking.
> 
> These add several instances of register stacking and unstacking around
> various function calls, several of which we can avoid.  Many of these
> instances don't need to stack any register other than r0.
> 
> Moreover, we can avoid stacking and unstacking r0 if these features are
> enabled by storing r0 in the pt_regs as we would do in our slow return
> path.
> 
> Various other cleanups are included in this set as well.  Acks welcome.

All four patches look fine to me:

  Acked-by: Will Deacon <will.deacon at arm.com>

For some reason, I thought the numbering of the TIF_ flags was important
for some immediate construction in asm code, but either I'm mistaken or
it's no longer the case.

Will


From robherring2 at gmail.com  Mon Aug 24 07:48:27 2015
From: robherring2 at gmail.com (Rob Herring)
Date: Mon, 24 Aug 2015 09:48:27 -0500
Subject: [PATCH v3 06/14] Documentation: drm/bridge: add document for
 analogix_dp
In-Reply-To: <20150824125758.GA7557@n2100.arm.linux.org.uk>
References: <1439995728-18046-1-git-send-email-ykk@rock-chips.com>
 <1439995834-18363-1-git-send-email-ykk@rock-chips.com>
 <CAL_JsqLz+8RtBucctUj4euXZ3Ac0DvB52N9ONpAerh5T9BiTJg@mail.gmail.com>
 <20150824125758.GA7557@n2100.arm.linux.org.uk>
Message-ID: <CAL_JsqKZYMMzV9Sc2r3K_rnM0FNuyb1TyJEhjGq1Hf7dTiWFKQ@mail.gmail.com>

On Mon, Aug 24, 2015 at 7:57 AM, Russell King - ARM Linux
<linux at arm.linux.org.uk> wrote:
> On Sun, Aug 23, 2015 at 06:23:14PM -0500, Rob Herring wrote:
>> On Wed, Aug 19, 2015 at 9:50 AM, Yakir Yang <ykk at rock-chips.com> wrote:
>> > +       -analogix,color-depth:
>> > +               number of bits per colour component.
>> > +                       COLOR_6 = 0, COLOR_8 = 1, COLOR_10 = 2, COLOR_12 = 3
>>
>> This seems pretty generic. Just use 6, 8, 10, or 12 for values. And
>> drop the vendor prefix.
>
> Please think about this some more.  What does "color-depth" mean?  Does it
> mean the number of bits per colour _component_, or does it mean the total
> number of bits to represent a particular colour.  It's confusing as it
> stands.

Then "component-color-bpp" perhaps?

>
>> > +Optional properties for dp-controller:
>> > +       -analogix,hpd-gpio:
>> > +               Hotplug detect GPIO.
>> > +                       Indicates which GPIO should be used for hotplug
>> > +                       detection
>>
>> We should align with "hpd-gpios" used by HDMI connector binding. Or do
>> we need a DP connector binding that this should be defined in?
>> Probably so.
>>
>> The DRM related bindings are such a cluster f*ck with everyone picking
>> their own way to do things. Just grep hpd in bindings for starters.
>> That is just the tip.
>
> I'm not surprised one iota that DRM bindings are a mess.  There's no one
> overlooking the adoption of DRM bindings, so surprise surprise, everyone
> does their own thing.  This is exactly what happens every time in that
> scenario.  It's not a new problem.

True.

> When we adopted the graph bindings for iMX DRM, I thought exactly at that
> time "it would be nice if this could become the standard for binding DRM
> components together" but I don't have the authority from either the DT
> perspective or the DRM perspective to mandate that.  Neither does anyone
> else.  That's the _real_ problem here.
>
> I've seen several DRM bindings go by which don't use the of-graph stuff,
> which means that they'll never be compatible with generic components
> which do use the of-graph stuff.

It goes beyond bindings IMO. The use of the component framework or not
has been at the whim of driver writers as well. It is either used or
private APIs are created. I'm using components and my need for it
boils down to passing the struct drm_device pointer to the encoder.
Other components like panels and bridges have different ways to attach
to the DRM driver.

> Like you say, it's a mess, but it's a mess of our own making, because no
> one has the authority to regulate this.

Certainly, and I will take some blame here. We deferred a lot of
binding review to subsystem maintainers with the directive to ask for
help when needed. The latter has not happened. We need to improve the
situation here before we end up with a bigger mess. The momentum to
use DRM on Android is growing, so the problem is only going to get
worse if we do nothing.

Rob


From vaibhav.hiremath at linaro.org  Mon Aug 24 07:54:10 2015
From: vaibhav.hiremath at linaro.org (Vaibhav Hiremath)
Date: Mon, 24 Aug 2015 20:24:10 +0530
Subject: [PATCH-v3 1/2] mfd: devicetree: bindings: 88pm800: Add DT property
 for dual phase enable
In-Reply-To: <20150824130205.GE3237@x1>
References: <1440420006-31556-1-git-send-email-vaibhav.hiremath@linaro.org>
 <1440420006-31556-2-git-send-email-vaibhav.hiremath@linaro.org>
 <20150824130205.GE3237@x1>
Message-ID: <55DB3012.6010904@linaro.org>



On Monday 24 August 2015 06:32 PM, Lee Jones wrote:
> On Mon, 24 Aug 2015, Vaibhav Hiremath wrote:
>
>> 88PM860 family of device supports dual phase mode on BUCK1 supply
>> providing total 6A capacity.
>> Note that by default they operate independently with 3A capacity.
>>
>> This patch updates the devicetree binding with DT property
>> to enable dual-phase mode on BUCK1.
>>
>> Signed-off-by: Vaibhav Hiremath <vaibhav.hiremath at linaro.org>
>> ---
>>   Documentation/devicetree/bindings/mfd/88pm800.txt | 6 ++++++
>>   1 file changed, 6 insertions(+)
>>
>> diff --git a/Documentation/devicetree/bindings/mfd/88pm800.txt b/Documentation/devicetree/bindings/mfd/88pm800.txt
>> index dec842f..2c82fcb 100644
>> --- a/Documentation/devicetree/bindings/mfd/88pm800.txt
>> +++ b/Documentation/devicetree/bindings/mfd/88pm800.txt
>> @@ -9,6 +9,12 @@ Required parent device properties:
>>   - #interrupt-cells 	: should be 1.
>>   			  The cell is the 88pm80x local IRQ number
>>
>> +Optional properties :
>> +- marvell,88pm860-buck1-dualphase-en  : If set, enable dual phase on BUCK1,
>> +  providing 6A capacity.
>> +  Without this both BUCK1A and BUCK1B operates independently with 3A capacity.
>> +  (This property is only applicable to 88PM860)
>
> This will require a Regulator Ack.
>
> My suggestion would be to remove the 'buck' number, as the same
> property could be used on any Buck, and remove the '-en' part, as
> this is implied.
>

Ok, Will do it in next version.

Mark,

Any comments here before I spin V4.

Thanks,
Vaibhav


From linux at arm.linux.org.uk  Mon Aug 24 08:00:31 2015
From: linux at arm.linux.org.uk (Russell King - ARM Linux)
Date: Mon, 24 Aug 2015 16:00:31 +0100
Subject: [PATCH 0/4] Efficiency cleanups
In-Reply-To: <20150824143619.GD20147@arm.com>
References: <CABXk95C=CpeL4mNmS6-jJ-0bMJf6fawwfs6DM1-p8FctTEFbpw@mail.gmail.com>
 <20150821133043.GV7557@n2100.arm.linux.org.uk>
 <20150821134630.GW7557@n2100.arm.linux.org.uk>
 <20150824143619.GD20147@arm.com>
Message-ID: <20150824150031.GC7557@n2100.arm.linux.org.uk>

On Mon, Aug 24, 2015 at 03:36:20PM +0100, Will Deacon wrote:
> On Fri, Aug 21, 2015 at 02:46:30PM +0100, Russell King - ARM Linux wrote:
> > While developing the previous patch set, I noticed that the kernel's
> > "fast" exit path efficiency was not what it's supposed to be due to the
> > addition of trace and context tracking.
> > 
> > These add several instances of register stacking and unstacking around
> > various function calls, several of which we can avoid.  Many of these
> > instances don't need to stack any register other than r0.
> > 
> > Moreover, we can avoid stacking and unstacking r0 if these features are
> > enabled by storing r0 in the pt_regs as we would do in our slow return
> > path.
> > 
> > Various other cleanups are included in this set as well.  Acks welcome.
> 
> All four patches look fine to me:
> 
>   Acked-by: Will Deacon <will.deacon at arm.com>
> 
> For some reason, I thought the numbering of the TIF_ flags was important
> for some immediate construction in asm code, but either I'm mistaken or
> it's no longer the case.

The only reason they're important is to ensure that the bits are close
enough together - we use the definitions directly in the asm code.

Over the years, I think we've deleted a number of flags, and grown some
others, and we've left holes in the bit allocation.  By compressing them,
we can change the assembly code to check for "is there _any_ work at all
that needs to be done" as opposed to the two-step approach we've been
doing up to now.

-- 
FTTC broadband for 0.8mile line: currently at 10.5Mbps down 400kbps up
according to speedtest.net.


From vaibhav.hiremath at linaro.org  Mon Aug 24 08:20:07 2015
From: vaibhav.hiremath at linaro.org (Vaibhav Hiremath)
Date: Mon, 24 Aug 2015 20:50:07 +0530
Subject: [PATCH-v6 5/6] mfd: 88pm800: Set default interrupt clear method
In-Reply-To: <20150824135422.GF3237@x1>
References: <1436358392-15449-1-git-send-email-vaibhav.hiremath@linaro.org>
 <1436358392-15449-6-git-send-email-vaibhav.hiremath@linaro.org>
 <20150824135422.GF3237@x1>
Message-ID: <55DB3627.2030503@linaro.org>



On Monday 24 August 2015 07:24 PM, Lee Jones wrote:
> On Wed, 08 Jul 2015, Vaibhav Hiremath wrote:
>
>> As per the spec, bit 1 (INT_CLEAR_MODE) of reg addr 0xe
>> (page 0) controls the method of clearing interrupt
>> status of 88pm800 family of devices;
>>
>>    0: clear on read
>>    1: clear on write
>>
>> If pdata is not coming from board file, then set the
>> default irq clear method to "irq clear on write"
>>
>> Also, as suggested by "Lee Jones" renaming variable field
>> to appropriate name and removed unnecessary field
>> pm80x_chip.irq_mode, using platform_data.irq_clr_method.
>>
>> Signed-off-by: Zhao Ye <zhaoy at marvell.com>
>> Signed-off-by: Vaibhav Hiremath <vaibhav.hiremath at linaro.org>
>> Reviewed-by: Krzysztof Kozlowski <k.kozlowski at samsung.com>
>> ---
>>   drivers/mfd/88pm800.c       | 15 ++++++++++-----
>>   include/linux/mfd/88pm80x.h |  9 +++++++--
>>   2 files changed, 17 insertions(+), 7 deletions(-)
>
> [...]
>
>> +#define PM800_WAKEUP2_INT_READ_CLEAR	(0 << 1)
>> +#define PM800_WAKEUP2_INT_WRITE_CLEAR	(1 << 1)
>
> Use BIT().
>
>> +/* Used by irq_clr_method */
>> +#define PM800_IRQ_CLR_ON_READ	0
>> +#define PM800_IRQ_CLR_ON_WRITE	1
>
>> -	int irq_mode;		/* Clear interrupt by read/write(0/1) */
>> +	bool irq_clr_method;		/* Clear interrupt by read/write(0/1) */
>
>> +	irq_clr_mode = pdata->irq_clr_method == PM800_IRQ_CLR_ON_WRITE ?
>> +		PM800_WAKEUP2_INT_WRITE_CLEAR : PM800_WAKEUP2_INT_READ_CLEAR;
>> +	ret = regmap_update_bits(map, PM800_WAKEUP2, mask, irq_clr_mode);
>
> This is pretty convoluted.
>
> For starters you're abusing the 'bool' type here.  Bool is either
> 'true' or 'false', so at the very least you should rename
> 'irq_clr_method' to 'irq_clr_on_write'.
>
> Then you can do:
>
> 	irq_clr_mode = pdata->irq_clr_on_write ?
> 		PM800_WAKEUP2_INT_WRITE_CLEAR : PM800_WAKEUP2_INT_READ_CLEAR;
>

We have discussed on this, and went back-n-forth.
I think if I remember correctly, one of the version was using
true/false then we decided to rename it to relevant macro.

If I am not wrong V4 version of this series is exactly same as what you
are referring to.


> However, what I suggest you really do is share
> PM800_WAKEUP2_INT_{READ,WRITE}_CLEAR with platform data and just pass
> the value through directly.
>

I think we discussed about this also, and the reason I recall here is,

we may need to control this from DT in the future so we decided to keep
it boolean in platform_data and have simple check before writing to
register.

And I think that was also another reason we introduced

/* Used by irq_clr_method */
#define PM800_IRQ_CLR_ON_READ   0
#define PM800_IRQ_CLR_ON_WRITE  1

(Earlier it was true/false in V4)

Thanks,
Vaibhav


From vladimir.murzin at arm.com  Mon Aug 24 08:44:19 2015
From: vladimir.murzin at arm.com (Vladimir Murzin)
Date: Mon, 24 Aug 2015 16:44:19 +0100
Subject: [PATCH v2 5/5] arm64: add KASan support
In-Reply-To: <CAPAsAGwji7FpUJK9O=FWYN15-rJkYMQyOt9W9ncdY9uLybxkiA@mail.gmail.com>
References: <1431698344-28054-1-git-send-email-a.ryabinin@samsung.com>	<1431698344-28054-6-git-send-email-a.ryabinin@samsung.com>	<CACRpkdaRJJjCXR=vK1M2YhR26JZfGoBB+jcqz8r2MhERfxRzqA@mail.gmail.com>	<CAPAsAGy-r8Z2N09wKV+e0kLfbwxd-eWK6N5Xajsnqq9jfyWqcQ@mail.gmail.com>	<CACRpkdZmHLMxosLXjyOPdkavo=UNzmTcHOLF5vV4cS1ULfbq6A@mail.gmail.com>	<CAPAsAGw-iawTpjJh66rQN5fqBFT6UBZCcv2eKx7JTqCXzhzpsw@mail.gmail.com>	<CACRpkdY2i2M27gP_fXawkFrC_GFgWaKr5rEn6d47refNPiEk=g@mail.gmail.com>	<55AE56DB.4040607@samsung.com>	<CACRpkdYaqK8upK-3b01JbO_y+sHnk4-Hm1MfvjSy0tKUkFREtQ@mail.gmail.com>	<20150824131557.GB7557@n2100.arm.linux.org.uk>	<CACRpkdYwpucRiXM05y00RQY=gKv8W6YjCNspYFRMGaM605cU0w@mail.gmail.com>
 <CAPAsAGwji7FpUJK9O=FWYN15-rJkYMQyOt9W9ncdY9uLybxkiA@mail.gmail.com>
Message-ID: <55DB3BD3.7030202@arm.com>

On 24/08/15 15:15, Andrey Ryabinin wrote:
> 2015-08-24 16:45 GMT+03:00 Linus Walleij <linus.walleij at linaro.org>:
>> On Mon, Aug 24, 2015 at 3:15 PM, Russell King - ARM Linux
>> <linux at arm.linux.org.uk> wrote:
>>> On Tue, Jul 21, 2015 at 11:27:56PM +0200, Linus Walleij wrote:
>>>> On Tue, Jul 21, 2015 at 4:27 PM, Andrey Ryabinin <a.ryabinin at samsung.com> wrote:
>>>>
>>>>> I used vexpress. Anyway, it doesn't matter now, since I have an update
>>>>> with a lot of stuff fixed, and it works on hardware.
>>>>> I still need to do some work on it and tomorrow, probably, I will share.
>>>>
>>>> Ah awesome. I have a stash of ARM boards so I can test it on a
>>>> range of hardware once you feel it's ready.
>>>>
>>>> Sorry for pulling stuff out of your hands, people are excited about
>>>> KASan ARM32 as it turns out.
>>>
>>> People may be excited about it because it's a new feature, but we really
>>> need to consider whether gobbling up 512MB of userspace for it is a good
>>> idea or not.  There are programs around which like to map large amounts
>>> of memory into their process space, and the more we steal from them, the
>>> more likely these programs are to fail.
>>
>> I looked at some different approaches over the last weeks for this
>> when playing around with KASan.
>>
>> It seems since KASan was developed on 64bit systems, this was
>> not much of an issue for them as they could take their shadow
>> memory from the vmalloc space.
>>
>> I think it is possible to actually just steal as much memory as is
>> needed to cover the kernel, and not 1/8 of the entire addressable
>> 32bit space. So instead of covering all from 0x0-0xffffffff
>> at least just MODULES_VADDR thru 0xffffffff should be enough.
>> So if that is 0xbf000000-0xffffffff in most cases, 0x41000000
>> bytes, then 1/8 of that, 0x8200000, 130MB should be enough.
>> (Andrey need to say if this is possible.)
>>
> 
> Yes, ~130Mb (3G/1G split) should work. 512Mb shadow is optional.
> The only advantage of 512Mb shadow is better handling of user memory
> accesses bugs
> (access to user memory without copy_from_user/copy_to_user/strlen_user etc API).
> In case of 512Mb shadow we could to not map anything in shadow for
> user addresses, so such bug will
> guarantee  to crash the kernel.
> In case of 130Mb, the behavior will depend on memory layout of the
> current process.
> So, I think it's fine to keep shadow only for kernel addresses.

Another option would be having "sparse" shadow memory based on page
extension. I did play with that some time ago based on ideas from
original v1 KASan support for x86/arm - it is how 614be38 "irqchip:
gic-v3: Fix out of bounds access to cpu_logical_map" was caught.
It doesn't require any VA reservations, only some contiguous memory for
the page_ext itself, which serves as indirection level for the 0-order
shadow pages.
In theory such design can be reused by others 32-bit arches and, I
think, nommu too. Additionally, the shadow pages might be movable with
help of driver-page migration patch series [1].
The cost is obvious - performance drop, although I didn't bother
measuring it.

[1] https://lwn.net/Articles/650917/

Cheers
Vladimir

> 
>> That will probably miss some usecases I'm not familiar with, where
>> the kernel is actually executing something below 0xbf000000...
>>
>> I looked at taking memory from vmalloc instead, but ran into
>> problems since this is subject to the highmem split and KASan
>> need to have it's address offset at compile time. On
>> Ux500 I managed to remove all the static maps and steal memory
>> from the top of the vmalloc area instead of the beginning, but
>> that is probably not generally feasible.
>>
>> I suspect you have better ideas than what I can come up
>> with though.
>>
>> Yours,
>> Linus Walleij
> 
> --
> To unsubscribe, send a message with 'unsubscribe linux-mm' in
> the body to majordomo at kvack.org.  For more info on Linux MM,
> see: http://www.linux-mm.org/ .
> Don't email: <a href=mailto:"dont at kvack.org"> email at kvack.org </a>
> 



From lee.jones at linaro.org  Mon Aug 24 08:51:29 2015
From: lee.jones at linaro.org (Lee Jones)
Date: Mon, 24 Aug 2015 16:51:29 +0100
Subject: [PATCH-v6 5/6] mfd: 88pm800: Set default interrupt clear method
In-Reply-To: <55DB3627.2030503@linaro.org>
References: <1436358392-15449-1-git-send-email-vaibhav.hiremath@linaro.org>
 <1436358392-15449-6-git-send-email-vaibhav.hiremath@linaro.org>
 <20150824135422.GF3237@x1> <55DB3627.2030503@linaro.org>
Message-ID: <20150824155129.GA19409@x1>

On Mon, 24 Aug 2015, Vaibhav Hiremath wrote:

> 
> 
> On Monday 24 August 2015 07:24 PM, Lee Jones wrote:
> >On Wed, 08 Jul 2015, Vaibhav Hiremath wrote:
> >
> >>As per the spec, bit 1 (INT_CLEAR_MODE) of reg addr 0xe
> >>(page 0) controls the method of clearing interrupt
> >>status of 88pm800 family of devices;
> >>
> >>   0: clear on read
> >>   1: clear on write
> >>
> >>If pdata is not coming from board file, then set the
> >>default irq clear method to "irq clear on write"
> >>
> >>Also, as suggested by "Lee Jones" renaming variable field
> >>to appropriate name and removed unnecessary field
> >>pm80x_chip.irq_mode, using platform_data.irq_clr_method.
> >>
> >>Signed-off-by: Zhao Ye <zhaoy at marvell.com>
> >>Signed-off-by: Vaibhav Hiremath <vaibhav.hiremath at linaro.org>
> >>Reviewed-by: Krzysztof Kozlowski <k.kozlowski at samsung.com>
> >>---
> >>  drivers/mfd/88pm800.c       | 15 ++++++++++-----
> >>  include/linux/mfd/88pm80x.h |  9 +++++++--
> >>  2 files changed, 17 insertions(+), 7 deletions(-)
> >
> >[...]
> >
> >>+#define PM800_WAKEUP2_INT_READ_CLEAR	(0 << 1)
> >>+#define PM800_WAKEUP2_INT_WRITE_CLEAR	(1 << 1)
> >
> >Use BIT().
> >
> >>+/* Used by irq_clr_method */
> >>+#define PM800_IRQ_CLR_ON_READ	0
> >>+#define PM800_IRQ_CLR_ON_WRITE	1
> >
> >>-	int irq_mode;		/* Clear interrupt by read/write(0/1) */
> >>+	bool irq_clr_method;		/* Clear interrupt by read/write(0/1) */
> >
> >>+	irq_clr_mode = pdata->irq_clr_method == PM800_IRQ_CLR_ON_WRITE ?
> >>+		PM800_WAKEUP2_INT_WRITE_CLEAR : PM800_WAKEUP2_INT_READ_CLEAR;
> >>+	ret = regmap_update_bits(map, PM800_WAKEUP2, mask, irq_clr_mode);
> >
> >This is pretty convoluted.
> >
> >For starters you're abusing the 'bool' type here.  Bool is either
> >'true' or 'false', so at the very least you should rename
> >'irq_clr_method' to 'irq_clr_on_write'.
> >
> >Then you can do:
> >
> >	irq_clr_mode = pdata->irq_clr_on_write ?
> >		PM800_WAKEUP2_INT_WRITE_CLEAR : PM800_WAKEUP2_INT_READ_CLEAR;
> >
> 
> We have discussed on this, and went back-n-forth.
> I think if I remember correctly, one of the version was using
> true/false then we decided to rename it to relevant macro.
> 
> If I am not wrong V4 version of this series is exactly same as what you
> are referring to.

Right.  I made a few suggestions which vary in usefulness depending on
how you plan to implement all of this.  Unfortunately this is a bit of
a bastardised version where some of it make sense and other parts
could do with some improvement.

> >However, what I suggest you really do is share
> >PM800_WAKEUP2_INT_{READ,WRITE}_CLEAR with platform data and just pass
> >the value through directly.
> >
> 
> I think we discussed about this also, and the reason I recall here is,
> 
> we may need to control this from DT in the future so we decided to keep
> it boolean in platform_data and have simple check before writing to
> register.
> 
> And I think that was also another reason we introduced
> 
> /* Used by irq_clr_method */
> #define PM800_IRQ_CLR_ON_READ   0
> #define PM800_IRQ_CLR_ON_WRITE  1

I think these are still required.  So it would look like this:

== Platform data ==

struct pdata {
  bool clear_irq_on_write;
};

pdata->clear_irq_on_write = PM800_IRQ_CLR_ON_{READ,WRITE};

== Driver ==

irq_clr_mode = pdata->clear_irq_on_write ?
                 PM800_WAKEUP2_INT_WRITE_CLEAR : PM800_WAKEUP2_INT_READ_CLEAR;
regmap_update_bits(map, PM800_WAKEUP2, mask, irq_clr_mode);

-- 
Lee Jones
Linaro STMicroelectronics Landing Team Lead
Linaro.org ? Open source software for ARM SoCs
Follow Linaro: Facebook | Twitter | Blog


From ryabinin.a.a at gmail.com  Mon Aug 24 09:00:19 2015
From: ryabinin.a.a at gmail.com (Andrey Ryabinin)
Date: Mon, 24 Aug 2015 19:00:19 +0300
Subject: [PATCH v2 5/5] arm64: add KASan support
In-Reply-To: <55DB3BD3.7030202@arm.com>
References: <1431698344-28054-1-git-send-email-a.ryabinin@samsung.com>
 <1431698344-28054-6-git-send-email-a.ryabinin@samsung.com>
 <CACRpkdaRJJjCXR=vK1M2YhR26JZfGoBB+jcqz8r2MhERfxRzqA@mail.gmail.com>
 <CAPAsAGy-r8Z2N09wKV+e0kLfbwxd-eWK6N5Xajsnqq9jfyWqcQ@mail.gmail.com>
 <CACRpkdZmHLMxosLXjyOPdkavo=UNzmTcHOLF5vV4cS1ULfbq6A@mail.gmail.com>
 <CAPAsAGw-iawTpjJh66rQN5fqBFT6UBZCcv2eKx7JTqCXzhzpsw@mail.gmail.com>
 <CACRpkdY2i2M27gP_fXawkFrC_GFgWaKr5rEn6d47refNPiEk=g@mail.gmail.com>
 <55AE56DB.4040607@samsung.com>
 <CACRpkdYaqK8upK-3b01JbO_y+sHnk4-Hm1MfvjSy0tKUkFREtQ@mail.gmail.com>
 <20150824131557.GB7557@n2100.arm.linux.org.uk>
 <CACRpkdYwpucRiXM05y00RQY=gKv8W6YjCNspYFRMGaM605cU0w@mail.gmail.com>
 <CAPAsAGwji7FpUJK9O=FWYN15-rJkYMQyOt9W9ncdY9uLybxkiA@mail.gmail.com>
 <55DB3BD3.7030202@arm.com>
Message-ID: <CAPAsAGyg_oUvUrfSSQccVMcGtY_bwR8n6tf3tFsnh43YT6-b4w@mail.gmail.com>

2015-08-24 18:44 GMT+03:00 Vladimir Murzin <vladimir.murzin at arm.com>:
>
> Another option would be having "sparse" shadow memory based on page
> extension. I did play with that some time ago based on ideas from
> original v1 KASan support for x86/arm - it is how 614be38 "irqchip:
> gic-v3: Fix out of bounds access to cpu_logical_map" was caught.
> It doesn't require any VA reservations, only some contiguous memory for
> the page_ext itself, which serves as indirection level for the 0-order
> shadow pages.

We won't be able to use inline instrumentation (I could live with that),
and most importantly, we won't be able to use stack instrumentation.
GCC needs to know shadow address for inline and/or stack instrumentation
to generate correct code.

> In theory such design can be reused by others 32-bit arches and, I
> think, nommu too. Additionally, the shadow pages might be movable with
> help of driver-page migration patch series [1].
> The cost is obvious - performance drop, although I didn't bother
> measuring it.
>
> [1] https://lwn.net/Articles/650917/
>
> Cheers
> Vladimir
>


From romain.perier at gmail.com  Mon Aug 24 09:04:41 2015
From: romain.perier at gmail.com (Romain Perier)
Date: Mon, 24 Aug 2015 18:04:41 +0200
Subject: [PATCH] ARM: dts: rockchip: Add support for SD/MMC on MarsBoard-RK3066
Message-ID: <1440432281-491-1-git-send-email-romain.perier@gmail.com>

This enables SDMMC0 on the board and gives a basic support for SD cards.

Signed-off-by: Romain Perier <romain.perier at gmail.com>
---
 arch/arm/boot/dts/rk3066a-marsboard.dts | 8 ++++++++
 1 file changed, 8 insertions(+)

diff --git a/arch/arm/boot/dts/rk3066a-marsboard.dts b/arch/arm/boot/dts/rk3066a-marsboard.dts
index bae965c..7189d90 100644
--- a/arch/arm/boot/dts/rk3066a-marsboard.dts
+++ b/arch/arm/boot/dts/rk3066a-marsboard.dts
@@ -186,6 +186,14 @@
 	};
 };
 
+&mmc0 {
+	status = "okay";
+
+	pinctrl-names = "default";
+	pinctrl-0 = <&sd0_clk>, <&sd0_cmd>, <&sd0_cd>, <&sd0_bus4>;
+	vmmc-supply = <&vcc_sd0>;
+};
+
 &uart0 {
 	status = "okay";
 };
-- 
2.1.4



From Shenwei.Wang at freescale.com  Mon Aug 24 09:09:09 2015
From: Shenwei.Wang at freescale.com (Shenwei Wang)
Date: Mon, 24 Aug 2015 16:09:09 +0000
Subject: [PATCH v8 1/2] irqchip: imx-gpcv2: IMX GPCv2 driver for wakeup
 sources
In-Reply-To: <alpine.DEB.2.11.1508231251040.3873@nanos>
References: <1438378439-11569-1-git-send-email-shenwei.wang@freescale.com>
 <1438378439-11569-2-git-send-email-shenwei.wang@freescale.com>
 <alpine.DEB.2.11.1508231251040.3873@nanos>
Message-ID: <CY1PR0301MB084328829F8128A8FBFA6A9283620@CY1PR0301MB0843.namprd03.prod.outlook.com>



> -----Original Message-----
> From: Thomas Gleixner [mailto:tglx at linutronix.de]
> Sent: 2015?8?23? 5:58
> To: Wang Shenwei-B38339
> Cc: shawn.guo at linaro.org; jason at lakedaemon.net;
> linux-arm-kernel at lists.infradead.org; linux-kernel at vger.kernel.org; Huang
> Yongcai-B20788
> Subject: Re: [PATCH v8 1/2] irqchip: imx-gpcv2: IMX GPCv2 driver for wakeup
> sources
> 
> On Fri, 31 Jul 2015, Shenwei Wang wrote:
> > +struct gpcv2_irqchip_data {
> > +	struct raw_spinlock rlock;
> > +	void __iomem *gpc_base;
> > +	u32 wakeup_sources[IMR_NUM];
> > +	u32 enabled_irqs[IMR_NUM];
> > +	u32 cpu2wakeup;
> 
> Can you please format that in a readable way?
> 
>       struct raw_spinlock    rlock;
>       void __iomem	     *gpc_base;
>       ....

I did try to be careful about the format, but did not notice this one. Will change it in the new version.:)
 
> > +};
> > +
> > +static struct gpcv2_irqchip_data *imx_gpcv2_instance;
> > +
> > +u32 imx_gpcv2_get_wakeup_source(u32 **sources) {
> > +	if (!imx_gpcv2_instance)
> > +		return 0;
> > +
> > +	if (sources)
> > +		*sources = imx_gpcv2_instance->wakeup_sources;
> > +
> > +	return IMR_NUM;
> > +}
> > +
> > +static int gpcv2_wakeup_source_save(void) {
> > +	struct gpcv2_irqchip_data *cd;
> > +	void __iomem *reg;
> > +	int i;
> > +
> > +	cd = imx_gpcv2_instance;
> > +	if (!cd)
> > +		return 0;
> > +
> > +	for (i = 0; i < IMR_NUM; i++) {
> > +		reg = cd->gpc_base + cd->cpu2wakeup + i * 4;
> > +		cd->enabled_irqs[i] = readl_relaxed(reg);
> 
> You read the full state of the register and restore the full state. So why
> enabled_irqs?

There are two user scenarios: 
In CPU Idle state, the system need to be woke up by any enabled irqs, not just the ones that marked as wakeup sources.
In Suspend State, they system will only be woke up by the one that marked as a wakeup source. 
Enabled_irqs are used to save the values before suspend, and restore them after resume.

> > +		writel_relaxed(cd->wakeup_sources[i], reg);
> > +	}
> > +
> > +	return 0;
> > +}
> > +
> > +static void gpcv2_wakeup_source_restore(void) {
> > +	struct gpcv2_irqchip_data *cd;
> > +	void __iomem *reg;
> > +	int i;
> > +
> > +	cd = imx_gpcv2_instance;
> > +	if (!cd)
> > +		return;
> > +
> > +	for (i = 0; i < IMR_NUM; i++) {
> > +		reg = cd->gpc_base + cd->cpu2wakeup + i * 4;
> > +		writel_relaxed(cd->enabled_irqs[i], reg);
> > +		cd->wakeup_sources[i] = ~0;
> 
> Why are you clearing that info on resume? Drivers will clear that via
> set_wake() or leave it when they want to have resume functionality?
> 
Each time system goes into the suspend state, it will call set_wake (ON) again to configure
the wakeup sources. Clearing wakeup_sources here can make sure the system work as
expected no matter that a driver calls set_wake (OFF) during resume stage.

> > +static int __init imx_gpcv2_irqchip_init(struct device_node *node,
> > +			       struct device_node *parent) {
> > +	struct irq_domain *parent_domain, *domain;
> > +	struct gpcv2_irqchip_data *cd;
> > +	int i;
> > +
> > +	if (!parent) {
> > +		pr_err("%s: no parent, giving up\n", node->full_name);
> > +		return -ENODEV;
> > +	}
> > +
> > +	parent_domain = irq_find_host(parent);
> > +	if (!parent_domain) {
> > +		pr_err("%s: unable to get parent domain\n", node->full_name);
> > +		return -ENXIO;
> > +	}
> > +
> > +	cd = kzalloc(sizeof(struct gpcv2_irqchip_data), GFP_KERNEL);
> > +	BUG_ON(!cd);
> 
> You return an error code for all other failures. Why BUG here?

Good point. To be consistent, I will change it to return an error code.

Thanks,
Shenwei
> 
> Otherwise this looks very clean now. Can you please resend ASAP with these
> minor points addressed?
> 
> Thanks,
> 
> 	tglx
> 


From appana.durga.rao at xilinx.com  Mon Aug 24 09:11:06 2015
From: appana.durga.rao at xilinx.com (Kedareswara rao Appana)
Date: Mon, 24 Aug 2015 21:41:06 +0530
Subject: [PATCH v9] dmaengine: Add Xilinx AXI Direct Memory Access Engine
 driver support
Message-ID: <1440432666-10310-1-git-send-email-appanad@xilinx.com>

This is the driver for the AXI Direct Memory Access (AXI DMA)
core, which is a soft Xilinx IP core that provides high-
bandwidth direct memory access between memory and AXI4-Stream
type target peripherals.

Signed-off-by: Kedareswara rao Appana <appanad at xilinx.com>
---
The deivce tree doc got applied in the slave-dmaengine.git.

Changes in v9:
- Used the readl_poll_timeout instead of do while loops
  in the driver as suggested by Moritz Fischer.
- Intialize the residue variable to get rid of compilation warining.
Changes in v8:
- Updated the SG handling as suggested by Nicolae Rosia.
- Removed the unnecessary xilinx_dma_channel_set_config API the properties
  in this API is not being used by the driver.
Changes in v7:
- Updated license in the driver as suggested by Paul.
- Corrected return value in is_idle funtion.
Changes in v6:
- Fixed Odd indention in the Kconfig.
- used GFP_NOWAIT instead of GFP_KERNEL during the desc allocation
- Calculated residue in the tx_status instead of complete_descriptor.
- Update copy right to 2015.
- Modified spin_lock handling moved the spin_lock to the appropriate functions
(instead of xilinx_dma_start_transfer doing it xilinx_dma_issue_pending api).
- device_control and declare slave caps updated as per newer APi's.
Changes in v5:
- Modified the xilinx_dma.h header file location to the 
  include/linux/dma/xilinx_dma.h
Changes in v4:
- Add direction field to DMA descriptor structure and removed from
  channel structure to avoid duplication.
- Check for DMA idle condition before changing the configuration.
- Residue is being calculated in complete_descriptor() and is reported
  to slave driver.
Changes in v3:
- Rebased on 3.16-rc7
Changes in v2:
- Simplified the logic to set SOP and APP words in prep_slave_sg().
- Corrected function description comments to match the return type.
- Fixed some minor comments as suggested by Andy.
---
 drivers/dma/Kconfig             |   13 +
 drivers/dma/xilinx/Makefile     |    1 +
 drivers/dma/xilinx/xilinx_dma.c | 1178 +++++++++++++++++++++++++++++++++++++++
 3 files changed, 1192 insertions(+)
 create mode 100644 drivers/dma/xilinx/xilinx_dma.c

diff --git a/drivers/dma/Kconfig b/drivers/dma/Kconfig
index 88d474b..5e95f07 100644
--- a/drivers/dma/Kconfig
+++ b/drivers/dma/Kconfig
@@ -507,4 +507,17 @@ config QCOM_BAM_DMA
 	  Enable support for the QCOM BAM DMA controller.  This controller
 	  provides DMA capabilities for a variety of on-chip devices.
 
+config XILINX_DMA
+        tristate "Xilinx AXI DMA Engine"
+        depends on (ARCH_ZYNQ || MICROBLAZE)
+        select DMA_ENGINE
+        help
+          Enable support for Xilinx AXI DMA Soft IP.
+
+          This engine provides high-bandwidth direct memory access
+          between memory and AXI4-Stream type target peripherals.
+          It has two stream interfaces/channels, Memory Mapped to
+          Stream (MM2S) and Stream to Memory Mapped (S2MM) for the
+          data transfers.
+
 endif
diff --git a/drivers/dma/xilinx/Makefile b/drivers/dma/xilinx/Makefile
index 3c4e9f2..6224a49 100644
--- a/drivers/dma/xilinx/Makefile
+++ b/drivers/dma/xilinx/Makefile
@@ -1 +1,2 @@
 obj-$(CONFIG_XILINX_VDMA) += xilinx_vdma.o
+obj-$(CONFIG_XILINX_DMA) += xilinx_dma.o
diff --git a/drivers/dma/xilinx/xilinx_dma.c b/drivers/dma/xilinx/xilinx_dma.c
new file mode 100644
index 0000000..d19009e
--- /dev/null
+++ b/drivers/dma/xilinx/xilinx_dma.c
@@ -0,0 +1,1178 @@
+/*
+ * DMA driver for Xilinx DMA Engine
+ *
+ * Copyright (C) 2010 - 2015 Xilinx, Inc. All rights reserved.
+ *
+ * Based on the Freescale DMA driver.
+ *
+ * Description:
+ *  The AXI DMA, is a soft IP, which provides high-bandwidth Direct Memory
+ *  Access between memory and AXI4-Stream-type target peripherals. It can be
+ *  configured to have one channel or two channels and if configured as two
+ *  channels, one is to transmit data from memory to a device and another is
+ *  to receive from a device.
+ *
+ * This 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.
+ */
+
+#include <linux/bitops.h>
+#include <linux/dma/xilinx_dma.h>
+#include <linux/init.h>
+#include <linux/interrupt.h>
+#include <linux/io.h>
+#include <linux/iopoll.h>
+#include <linux/module.h>
+#include <linux/of_address.h>
+#include <linux/of_dma.h>
+#include <linux/of_irq.h>
+#include <linux/of_platform.h>
+#include <linux/slab.h>
+
+#include "../dmaengine.h"
+
+/* Register Offsets */
+#define XILINX_DMA_REG_CONTROL		0x00
+#define XILINX_DMA_REG_STATUS		0x04
+#define XILINX_DMA_REG_CURDESC		0x08
+#define XILINX_DMA_REG_TAILDESC		0x10
+#define XILINX_DMA_REG_SRCADDR		0x18
+#define XILINX_DMA_REG_DSTADDR		0x20
+#define XILINX_DMA_REG_BTT		0x28
+
+/* Channel/Descriptor Offsets */
+#define XILINX_DMA_MM2S_CTRL_OFFSET	0x00
+#define XILINX_DMA_S2MM_CTRL_OFFSET	0x30
+
+/* General register bits definitions */
+#define XILINX_DMA_CR_RUNSTOP_MASK	BIT(0)
+#define XILINX_DMA_CR_RESET_MASK	BIT(2)
+
+#define XILINX_DMA_CR_DELAY_SHIFT	24
+#define XILINX_DMA_CR_COALESCE_SHIFT	16
+
+#define XILINX_DMA_CR_DELAY_MAX		GENMASK(7, 0)
+#define XILINX_DMA_CR_COALESCE_MAX	GENMASK(7, 0)
+
+#define XILINX_DMA_SR_HALTED_MASK	BIT(0)
+#define XILINX_DMA_SR_IDLE_MASK		BIT(1)
+
+#define XILINX_DMA_XR_IRQ_IOC_MASK	BIT(12)
+#define XILINX_DMA_XR_IRQ_DELAY_MASK	BIT(13)
+#define XILINX_DMA_XR_IRQ_ERROR_MASK	BIT(14)
+#define XILINX_DMA_XR_IRQ_ALL_MASK	GENMASK(14, 12)
+
+/* BD definitions */
+#define XILINX_DMA_BD_STS_ALL_MASK	GENMASK(31, 28)
+#define XILINX_DMA_BD_SOP		BIT(27)
+#define XILINX_DMA_BD_EOP		BIT(26)
+
+/* Hw specific definitions */
+#define XILINX_DMA_MAX_CHANS_PER_DEVICE	0x2
+#define XILINX_DMA_MAX_TRANS_LEN	GENMASK(22, 0)
+
+/* Delay loop counter to prevent hardware failure */
+#define XILINX_DMA_LOOP_COUNT		1000000
+
+/* Maximum number of Descriptors */
+#define XILINX_DMA_NUM_DESCS		255
+#define XILINX_DMA_COALESCE_MAX		255
+#define XILINX_DMA_NUM_APP_WORDS	5
+
+#define xilinx_dma_poll_timeout(chan, reg, val, cond, delay_us, timeout_us) \
+	readl_poll_timeout(chan->xdev->regs + chan->ctrl_offset + reg, val, \
+			   cond, delay_us, timeout_us)
+
+/**
+ * struct xilinx_dma_desc_hw - Hardware Descriptor
+ * @next_desc: Next Descriptor Pointer @0x00
+ * @pad1: Reserved @0x04
+ * @buf_addr: Buffer address @0x08
+ * @pad2: Reserved @0x0C
+ * @pad3: Reserved @0x10
+ * @pad4: Reserved @0x14
+ * @control: Control field @0x18
+ * @status: Status field @0x1C
+ * @app: APP Fields @0x20 - 0x30
+ */
+struct xilinx_dma_desc_hw {
+	u32 next_desc;
+	u32 pad1;
+	u32 buf_addr;
+	u32 pad2;
+	u32 pad3;
+	u32 pad4;
+	u32 control;
+	u32 status;
+	u32 app[XILINX_DMA_NUM_APP_WORDS];
+} __aligned(64);
+
+/**
+ * struct xilinx_dma_tx_segment - Descriptor segment
+ * @hw: Hardware descriptor
+ * @node: Node in the descriptor segments list
+ * @phys: Physical address of segment
+ */
+struct xilinx_dma_tx_segment {
+	struct xilinx_dma_desc_hw hw;
+	struct list_head node;
+	dma_addr_t phys;
+} __aligned(64);
+
+/**
+ * struct xilinx_dma_tx_descriptor - Per Transaction structure
+ * @async_tx: Async transaction descriptor
+ * @segments: TX segments list
+ * @node: Node in the channel descriptors list
+ * @direction: Transfer direction
+ */
+struct xilinx_dma_tx_descriptor {
+	struct dma_async_tx_descriptor async_tx;
+	struct list_head segments;
+	struct list_head node;
+	enum dma_transfer_direction direction;
+};
+
+/**
+ * struct xilinx_dma_chan - Driver specific DMA channel structure
+ * @xdev: Driver specific device structure
+ * @ctrl_offset: Control registers offset
+ * @ctrl_reg: Control register value
+ * @lock: Descriptor operation lock
+ * @pending_list: Descriptors waiting
+ * @active_list: Descriptors ready to submit
+ * @done_list: Complete descriptors
+ * @free_seg_list: Free descriptors
+ * @common: DMA common channel
+ * @seg_v: Statically allocated segments base
+ * @seg_p: Physical allocated segments base
+ * @dev: The dma device
+ * @irq: Channel IRQ
+ * @id: Channel ID
+ * @has_sg: Support scatter transfers
+ * @idle: Check for channel idle
+ * @err: Channel has errors
+ * @tasklet: Cleanup work after irq
+ * @residue: Residue
+ * @desc_pendingcount: Descriptor pending count
+ */
+struct xilinx_dma_chan {
+	struct xilinx_dma_device *xdev;
+	u32 ctrl_offset;
+	u32 ctrl_reg;
+	spinlock_t lock;
+	struct list_head pending_list;
+	struct list_head done_list;
+	struct list_head active_list;
+	struct list_head free_seg_list;
+	struct dma_chan common;
+	struct xilinx_dma_tx_segment *seg_v;
+	dma_addr_t seg_p;
+	struct device *dev;
+	int irq;
+	int id;
+	bool has_sg;
+	bool idle;
+	int err;
+	struct tasklet_struct tasklet;
+	u32 residue;
+	u32 desc_pendingcount;
+};
+
+/**
+ * struct xilinx_dma_device - DMA device structure
+ * @regs: I/O mapped base address
+ * @dev: Device Structure
+ * @common: DMA device structure
+ * @chan: Driver specific DMA channel
+ * @has_sg: Specifies whether Scatter-Gather is present or not
+ */
+struct xilinx_dma_device {
+	void __iomem *regs;
+	struct device *dev;
+	struct dma_device common;
+	struct xilinx_dma_chan *chan[XILINX_DMA_MAX_CHANS_PER_DEVICE];
+	bool has_sg;
+};
+
+/* Macros */
+#define to_xilinx_chan(chan) \
+	container_of(chan, struct xilinx_dma_chan, common)
+#define to_dma_tx_descriptor(tx) \
+	container_of(tx, struct xilinx_dma_tx_descriptor, async_tx)
+
+/* IO accessors */
+static inline void dma_write(struct xilinx_dma_chan *chan, u32 reg, u32 value)
+{
+	iowrite32(value, chan->xdev->regs + reg);
+}
+
+static inline u32 dma_read(struct xilinx_dma_chan *chan, u32 reg)
+{
+	return ioread32(chan->xdev->regs + reg);
+}
+
+static inline u32 dma_ctrl_read(struct xilinx_dma_chan *chan, u32 reg)
+{
+	return dma_read(chan, chan->ctrl_offset + reg);
+}
+
+static inline void dma_ctrl_write(struct xilinx_dma_chan *chan, u32 reg,
+				  u32 value)
+{
+	dma_write(chan, chan->ctrl_offset + reg, value);
+}
+
+/* -----------------------------------------------------------------------------
+ * Descriptors and segments alloc and free
+ */
+
+/**
+ * xilinx_dma_alloc_tx_segment - Allocate transaction segment
+ * @chan: Driver specific dma channel
+ *
+ * Return: The allocated segment on success and NULL on failure.
+ */
+static struct xilinx_dma_tx_segment *
+xilinx_dma_alloc_tx_segment(struct xilinx_dma_chan *chan)
+{
+	struct xilinx_dma_tx_segment *segment = NULL;
+	unsigned long flags;
+
+	spin_lock_irqsave(&chan->lock, flags);
+	if (!list_empty(&chan->free_seg_list)) {
+		segment = list_first_entry(&chan->free_seg_list,
+					   struct xilinx_dma_tx_segment,
+					   node);
+		list_del(&segment->node);
+	}
+	spin_unlock_irqrestore(&chan->lock, flags);
+
+	return segment;
+}
+
+/**
+ * xilinx_dma_clean_hw_desc - Clean hardware descriptor
+ * @hw: HW descriptor to clean
+ */
+static void xilinx_dma_clean_hw_desc(struct xilinx_dma_desc_hw *hw)
+{
+	u32 next_desc = hw->next_desc;
+
+	memset(hw, 0, sizeof(struct xilinx_dma_desc_hw));
+
+	hw->next_desc = next_desc;
+}
+
+/**
+ * xilinx_dma_free_tx_segment - Free transaction segment
+ * @chan: Driver specific dma channel
+ * @segment: dma transaction segment
+ */
+static void xilinx_dma_free_tx_segment(struct xilinx_dma_chan *chan,
+				       struct xilinx_dma_tx_segment *segment)
+{
+	xilinx_dma_clean_hw_desc(&segment->hw);
+
+	list_add_tail(&segment->node, &chan->free_seg_list);
+}
+
+/**
+ * xilinx_dma_tx_descriptor - Allocate transaction descriptor
+ * @chan: Driver specific dma channel
+ *
+ * Return: The allocated descriptor on success and NULL on failure.
+ */
+static struct xilinx_dma_tx_descriptor *
+xilinx_dma_alloc_tx_descriptor(struct xilinx_dma_chan *chan)
+{
+	struct xilinx_dma_tx_descriptor *desc;
+
+	desc = kzalloc(sizeof(*desc), GFP_NOWAIT);
+	if (!desc)
+		return NULL;
+
+	INIT_LIST_HEAD(&desc->segments);
+
+	return desc;
+}
+
+/**
+ * xilinx_dma_free_tx_descriptor - Free transaction descriptor
+ * @chan: Driver specific dma channel
+ * @desc: dma transaction descriptor
+ */
+static void
+xilinx_dma_free_tx_descriptor(struct xilinx_dma_chan *chan,
+			      struct xilinx_dma_tx_descriptor *desc)
+{
+	struct xilinx_dma_tx_segment *segment, *next;
+
+	if (!desc)
+		return;
+
+	list_for_each_entry_safe(segment, next, &desc->segments, node) {
+		list_del(&segment->node);
+		xilinx_dma_free_tx_segment(chan, segment);
+	}
+
+	kfree(desc);
+}
+
+/**
+ * xilinx_dma_alloc_chan_resources - Allocate channel resources
+ * @dchan: DMA channel
+ *
+ * Return: '0' on success and failure value on error
+ */
+static int xilinx_dma_alloc_chan_resources(struct dma_chan *dchan)
+{
+	struct xilinx_dma_chan *chan = to_xilinx_chan(dchan);
+	int i;
+
+	/* Allocate the buffer descriptors. */
+	chan->seg_v = dma_zalloc_coherent(chan->dev,
+					  sizeof(*chan->seg_v) *
+					  XILINX_DMA_NUM_DESCS,
+					  &chan->seg_p, GFP_KERNEL);
+	if (!chan->seg_v) {
+		dev_err(chan->dev,
+			"unable to allocate channel %d descriptors\n",
+			chan->id);
+		return -ENOMEM;
+	}
+
+	for (i = 0; i < XILINX_DMA_NUM_DESCS; i++) {
+		chan->seg_v[i].hw.next_desc =
+				chan->seg_p + sizeof(*chan->seg_v) *
+				((i + 1) % XILINX_DMA_NUM_DESCS);
+		chan->seg_v[i].phys =
+				chan->seg_p + sizeof(*chan->seg_v) * i;
+		list_add_tail(&chan->seg_v[i].node, &chan->free_seg_list);
+	}
+
+	dma_cookie_init(dchan);
+
+	/* Enable interrupts */
+	chan->ctrl_reg |= XILINX_DMA_XR_IRQ_ALL_MASK;
+	dma_ctrl_write(chan, XILINX_DMA_REG_CONTROL, chan->ctrl_reg);
+
+	return 0;
+}
+
+/**
+ * xilinx_dma_free_desc_list - Free descriptors list
+ * @chan: Driver specific dma channel
+ * @list: List to parse and delete the descriptor
+ */
+static void xilinx_dma_free_desc_list(struct xilinx_dma_chan *chan,
+				      struct list_head *list)
+{
+	struct xilinx_dma_tx_descriptor *desc, *next;
+
+	list_for_each_entry_safe(desc, next, list, node) {
+		list_del(&desc->node);
+		xilinx_dma_free_tx_descriptor(chan, desc);
+	}
+}
+
+/**
+ * xilinx_dma_free_descriptors - Free channel descriptors
+ * @chan: Driver specific dma channel
+ */
+static void xilinx_dma_free_descriptors(struct xilinx_dma_chan *chan)
+{
+	unsigned long flags;
+
+	spin_lock_irqsave(&chan->lock, flags);
+
+	xilinx_dma_free_desc_list(chan, &chan->pending_list);
+	xilinx_dma_free_desc_list(chan, &chan->done_list);
+	xilinx_dma_free_desc_list(chan, &chan->active_list);
+
+	spin_unlock_irqrestore(&chan->lock, flags);
+}
+
+/**
+ * xilinx_dma_free_chan_resources - Free channel resources
+ * @dchan: DMA channel
+ */
+static void xilinx_dma_free_chan_resources(struct dma_chan *dchan)
+{
+	struct xilinx_dma_chan *chan = to_xilinx_chan(dchan);
+
+	xilinx_dma_free_descriptors(chan);
+
+	dma_free_coherent(chan->dev,
+			  sizeof(*chan->seg_v) * XILINX_DMA_NUM_DESCS,
+			  chan->seg_v, chan->seg_p);
+}
+
+/**
+ * xilinx_dma_chan_desc_cleanup - Clean channel descriptors
+ * @chan: Driver specific dma channel
+ */
+static void xilinx_dma_chan_desc_cleanup(struct xilinx_dma_chan *chan)
+{
+	struct xilinx_dma_tx_descriptor *desc;
+	unsigned long flags;
+
+	spin_lock_irqsave(&chan->lock, flags);
+
+	while (!list_empty(&chan->done_list)) {
+		dma_async_tx_callback callback;
+		void *callback_param;
+
+		desc = list_first_entry(&chan->done_list,
+			struct xilinx_dma_tx_descriptor, node);
+
+		/* Remove from the list of running transactions */
+		list_del(&desc->node);
+
+		/* Run the link descriptor callback function */
+		callback = desc->async_tx.callback;
+		callback_param = desc->async_tx.callback_param;
+		if (callback) {
+			spin_unlock_irqrestore(&chan->lock, flags);
+			callback(callback_param);
+			spin_lock_irqsave(&chan->lock, flags);
+		}
+
+		/* Run any dependencies, then free the descriptor */
+		dma_run_dependencies(&desc->async_tx);
+		xilinx_dma_free_tx_descriptor(chan, desc);
+	}
+
+	spin_unlock_irqrestore(&chan->lock, flags);
+}
+
+/**
+ * xilinx_dma_tx_status - Get dma transaction status
+ * @dchan: DMA channel
+ * @cookie: Transaction identifier
+ * @txstate: Transaction state
+ *
+ * Return: DMA transaction status
+ */
+static enum dma_status xilinx_dma_tx_status(struct dma_chan *dchan,
+					    dma_cookie_t cookie,
+					    struct dma_tx_state *txstate)
+{
+	struct xilinx_dma_chan *chan = to_xilinx_chan(dchan);
+	struct xilinx_dma_tx_descriptor *desc;
+	struct xilinx_dma_tx_segment *segment;
+	struct xilinx_dma_desc_hw *hw;
+	enum dma_status ret;
+	unsigned long flags;
+	u32 residue = 0;
+
+	ret = dma_cookie_status(dchan, cookie, txstate);
+	if (ret == DMA_COMPLETE || !txstate)
+		return ret;
+
+	desc = list_last_entry(&chan->active_list,
+			       struct xilinx_dma_tx_descriptor, node);
+
+	spin_lock_irqsave(&chan->lock, flags);
+	if (chan->has_sg) {
+		while (!list_empty(&desc->segments)) {
+			segment = list_first_entry(&desc->segments,
+					struct xilinx_dma_tx_segment, node);
+			hw = &segment->hw;
+			residue += (hw->control - hw->status) &
+				   XILINX_DMA_MAX_TRANS_LEN;
+		}
+	}
+
+	chan->residue = residue;
+	dma_set_residue(txstate, chan->residue);
+	spin_unlock_irqrestore(&chan->lock, flags);
+
+	return ret;
+}
+
+/**
+ * xilinx_dma_halt - Halt DMA channel
+ * @chan: Driver specific DMA channel
+ */
+static void xilinx_dma_halt(struct xilinx_dma_chan *chan)
+{
+	int err = 0;
+	u32 val;
+
+	chan->ctrl_reg &= ~XILINX_DMA_CR_RUNSTOP_MASK;
+	dma_ctrl_write(chan, XILINX_DMA_REG_CONTROL, chan->ctrl_reg);
+
+	/* Wait for the hardware to halt */
+	err = xilinx_dma_poll_timeout(chan, XILINX_DMA_REG_STATUS, val,
+				      (val & XILINX_DMA_SR_HALTED_MASK), 10,
+				      XILINX_DMA_LOOP_COUNT);
+
+	if (err) {
+		dev_err(chan->dev, "Cannot stop channel %p: %x\n",
+			chan, dma_ctrl_read(chan, XILINX_DMA_REG_STATUS));
+		chan->err = true;
+	}
+}
+
+/**
+ * xilinx_dma_start - Start DMA channel
+ * @chan: Driver specific DMA channel
+ */
+static void xilinx_dma_start(struct xilinx_dma_chan *chan)
+{
+	int err = 0;
+	u32 val;
+
+	chan->ctrl_reg |= XILINX_DMA_CR_RUNSTOP_MASK;
+	dma_ctrl_write(chan, XILINX_DMA_REG_CONTROL, chan->ctrl_reg);
+
+	/* Wait for the hardware to start */
+	err = xilinx_dma_poll_timeout(chan, XILINX_DMA_REG_STATUS, val,
+				      !(val & XILINX_DMA_SR_HALTED_MASK), 10,
+				      XILINX_DMA_LOOP_COUNT);
+
+	if (err) {
+		dev_err(chan->dev, "Cannot start channel %p: %x\n",
+			 chan, dma_ctrl_read(chan, XILINX_DMA_REG_STATUS));
+		chan->err = true;
+	}
+}
+
+/**
+ * xilinx_dma_start_transfer - Starts DMA transfer
+ * @chan: Driver specific channel struct pointer
+ */
+static void xilinx_dma_start_transfer(struct xilinx_dma_chan *chan)
+{
+	struct xilinx_dma_tx_descriptor *head_desc, *tail_desc;
+	struct xilinx_dma_tx_segment *tail_segment;
+
+	if (chan->err)
+		return;
+
+	if (list_empty(&chan->pending_list))
+		return;
+
+	if (!chan->idle)
+		return;
+
+	head_desc = list_first_entry(&chan->pending_list,
+				     struct xilinx_dma_tx_descriptor, node);
+	tail_desc = list_last_entry(&chan->pending_list,
+				    struct xilinx_dma_tx_descriptor, node);
+	tail_segment = list_last_entry(&tail_desc->segments,
+				       struct xilinx_dma_tx_segment, node);
+
+	if (chan->desc_pendingcount <= XILINX_DMA_COALESCE_MAX) {
+		chan->ctrl_reg &= ~XILINX_DMA_CR_COALESCE_MAX;
+		chan->ctrl_reg |= chan->desc_pendingcount <<
+				  XILINX_DMA_CR_COALESCE_SHIFT;
+		dma_ctrl_write(chan, XILINX_DMA_REG_CONTROL, chan->ctrl_reg);
+	}
+
+	if (chan->has_sg)
+		dma_ctrl_write(chan, XILINX_DMA_REG_CURDESC,
+			       head_desc->async_tx.phys);
+
+	xilinx_dma_start(chan);
+
+	if (chan->err)
+		return;
+
+	/* Start the transfer */
+	if (chan->has_sg) {
+		dma_ctrl_write(chan, XILINX_DMA_REG_TAILDESC,
+			       tail_segment->phys);
+	} else {
+		struct xilinx_dma_tx_segment *segment;
+		struct xilinx_dma_desc_hw *hw;
+
+		segment = list_first_entry(&head_desc->segments,
+					   struct xilinx_dma_tx_segment, node);
+		hw = &segment->hw;
+
+		if (head_desc->direction == DMA_MEM_TO_DEV)
+			dma_ctrl_write(chan, XILINX_DMA_REG_SRCADDR,
+				       hw->buf_addr);
+		else
+			dma_ctrl_write(chan, XILINX_DMA_REG_DSTADDR,
+				       hw->buf_addr);
+
+		/* Start the transfer */
+		dma_ctrl_write(chan, XILINX_DMA_REG_BTT,
+			       hw->control & XILINX_DMA_MAX_TRANS_LEN);
+	}
+
+	list_splice_tail_init(&chan->pending_list, &chan->active_list);
+	chan->desc_pendingcount = 0;
+	chan->idle = false;
+}
+
+/**
+ * xilinx_dma_issue_pending - Issue pending transactions
+ * @dchan: DMA channel
+ */
+static void xilinx_dma_issue_pending(struct dma_chan *dchan)
+{
+	struct xilinx_dma_chan *chan = to_xilinx_chan(dchan);
+	unsigned long flags;
+
+	spin_lock_irqsave(&chan->lock, flags);
+	xilinx_dma_start_transfer(chan);
+	spin_unlock_irqrestore(&chan->lock, flags);
+}
+
+/**
+ * xilinx_dma_complete_descriptor - Mark the active descriptor as complete
+ * @chan : xilinx DMA channel
+ */
+static void xilinx_dma_complete_descriptor(struct xilinx_dma_chan *chan)
+{
+	struct xilinx_dma_tx_descriptor *desc, *next;
+
+	if (list_empty(&chan->active_list))
+		return;
+
+	list_for_each_entry_safe(desc, next, &chan->active_list, node) {
+		list_del(&desc->node);
+		dma_cookie_complete(&desc->async_tx);
+		list_add_tail(&desc->node, &chan->done_list);
+	}
+}
+
+/**
+ * xilinx_dma_chan_reset - Reset DMA channel
+ * @chan: Driver specific DMA channel
+ *
+ * Return: '0' on success and failure value on error
+ */
+static int xilinx_dma_chan_reset(struct xilinx_dma_chan *chan)
+{
+	int err = 0;
+	u32 val;
+
+	chan->ctrl_reg = dma_ctrl_read(chan, XILINX_DMA_REG_CONTROL);
+	dma_ctrl_write(chan, XILINX_DMA_REG_CONTROL, chan->ctrl_reg |
+		       XILINX_DMA_CR_RESET_MASK);
+
+	/* Wait for the hardware to finish reset */
+	err = xilinx_dma_poll_timeout(chan, XILINX_DMA_REG_CONTROL, val,
+				      !(val & XILINX_DMA_CR_RESET_MASK), 10,
+				      XILINX_DMA_LOOP_COUNT);
+
+	if (err) {
+		dev_err(chan->dev, "reset timeout, cr %x, sr %x\n",
+			dma_ctrl_read(chan, XILINX_DMA_REG_CONTROL),
+			dma_ctrl_read(chan, XILINX_DMA_REG_STATUS));
+		return -EBUSY;
+	}
+
+	chan->err = false;
+
+	return err;
+}
+
+/**
+ * xilinx_dma_irq_handler - DMA Interrupt handler
+ * @irq: IRQ number
+ * @data: Pointer to the Xilinx DMA channel structure
+ *
+ * Return: IRQ_HANDLED/IRQ_NONE
+ */
+static irqreturn_t xilinx_dma_irq_handler(int irq, void *data)
+{
+	struct xilinx_dma_chan *chan = data;
+	u32 status;
+
+	/* Read the status and ack the interrupts. */
+	status = dma_ctrl_read(chan, XILINX_DMA_REG_STATUS);
+	if (!(status & XILINX_DMA_XR_IRQ_ALL_MASK))
+		return IRQ_NONE;
+
+	dma_ctrl_write(chan, XILINX_DMA_REG_STATUS,
+		       status & XILINX_DMA_XR_IRQ_ALL_MASK);
+
+	if (status & XILINX_DMA_XR_IRQ_ERROR_MASK) {
+		dev_err(chan->dev,
+			"Channel %p has errors %x, cdr %x tdr %x\n",
+			chan, dma_ctrl_read(chan, XILINX_DMA_REG_STATUS),
+			dma_ctrl_read(chan, XILINX_DMA_REG_CURDESC),
+			dma_ctrl_read(chan, XILINX_DMA_REG_TAILDESC));
+		chan->err = true;
+	}
+
+	/*
+	 * Device takes too long to do the transfer when user requires
+	 * responsiveness
+	 */
+	if (status & XILINX_DMA_XR_IRQ_DELAY_MASK)
+		dev_dbg(chan->dev, "Inter-packet latency too long\n");
+
+	if (status & XILINX_DMA_XR_IRQ_IOC_MASK) {
+		spin_lock(&chan->lock);
+		xilinx_dma_complete_descriptor(chan);
+		chan->idle = true;
+		xilinx_dma_start_transfer(chan);
+		spin_unlock(&chan->lock);
+	}
+
+	tasklet_schedule(&chan->tasklet);
+	return IRQ_HANDLED;
+}
+
+/**
+ * xilinx_dma_do_tasklet - Schedule completion tasklet
+ * @data: Pointer to the Xilinx dma channel structure
+ */
+static void xilinx_dma_do_tasklet(unsigned long data)
+{
+	struct xilinx_dma_chan *chan = (struct xilinx_dma_chan *)data;
+
+	xilinx_dma_chan_desc_cleanup(chan);
+}
+
+/**
+ * append_desc_queue - Queuing descriptor
+ * @chan: Driver specific dma channel
+ * @desc: dma transaction descriptor
+ */
+static void append_desc_queue(struct xilinx_dma_chan *chan,
+			      struct xilinx_dma_tx_descriptor *desc)
+{
+	struct xilinx_dma_tx_segment *tail_segment;
+	struct xilinx_dma_tx_descriptor *tail_desc;
+
+	if (list_empty(&chan->pending_list))
+		goto append;
+
+	/*
+	 * Add the hardware descriptor to the chain of hardware descriptors
+	 * that already exists in memory.
+	 */
+	tail_desc = list_last_entry(&chan->pending_list,
+				    struct xilinx_dma_tx_descriptor, node);
+	tail_segment = list_last_entry(&tail_desc->segments,
+				       struct xilinx_dma_tx_segment, node);
+	tail_segment->hw.next_desc = (u32)desc->async_tx.phys;
+
+	/*
+	 * Add the software descriptor and all children to the list
+	 * of pending transactions
+	 */
+append:
+	list_add_tail(&desc->node, &chan->pending_list);
+	chan->desc_pendingcount++;
+
+	if (unlikely(chan->desc_pendingcount > XILINX_DMA_COALESCE_MAX)) {
+		dev_dbg(chan->dev, "desc pendingcount is too high\n");
+		chan->desc_pendingcount = XILINX_DMA_COALESCE_MAX;
+		BUG();
+	}
+}
+
+/**
+ * xilinx_dma_tx_submit - Submit DMA transaction
+ * @tx: Async transaction descriptor
+ *
+ * Return: cookie value on success and failure value on error
+ */
+static dma_cookie_t xilinx_dma_tx_submit(struct dma_async_tx_descriptor *tx)
+{
+	struct xilinx_dma_tx_descriptor *desc = to_dma_tx_descriptor(tx);
+	struct xilinx_dma_chan *chan = to_xilinx_chan(tx->chan);
+	dma_cookie_t cookie;
+	unsigned long flags;
+	int err;
+
+	if (chan->err) {
+		/*
+		 * If reset fails, need to hard reset the system.
+		 * Channel is no longer functional
+		 */
+		err = xilinx_dma_chan_reset(chan);
+		if (err < 0)
+			return err;
+	}
+
+	spin_lock_irqsave(&chan->lock, flags);
+
+	cookie = dma_cookie_assign(tx);
+
+	/* Put this transaction onto the tail of the pending queue */
+	append_desc_queue(chan, desc);
+
+	spin_unlock_irqrestore(&chan->lock, flags);
+
+	return cookie;
+}
+
+/**
+ * xilinx_dma_prep_slave_sg - prepare descriptors for a DMA_SLAVE transaction
+ * @dchan: DMA channel
+ * @sgl: scatterlist to transfer to/from
+ * @sg_len: number of entries in @scatterlist
+ * @direction: DMA direction
+ * @flags: transfer ack flags
+ * @context: APP words of the descriptor
+ *
+ * Return: Async transaction descriptor on success and NULL on failure
+ */
+static struct dma_async_tx_descriptor *xilinx_dma_prep_slave_sg(
+	struct dma_chan *dchan, struct scatterlist *sgl, unsigned int sg_len,
+	enum dma_transfer_direction direction, unsigned long flags,
+	void *context)
+{
+	struct xilinx_dma_chan *chan = to_xilinx_chan(dchan);
+	struct xilinx_dma_tx_descriptor *desc;
+	struct xilinx_dma_tx_segment *segment;
+	u32 *app_w = (u32 *)context;
+	struct scatterlist *sg;
+	size_t copy, sg_used;
+	int i;
+
+	if (!is_slave_direction(direction))
+		return NULL;
+
+	/* Allocate a transaction descriptor. */
+	desc = xilinx_dma_alloc_tx_descriptor(chan);
+	if (!desc)
+		return NULL;
+
+	desc->direction = direction;
+	dma_async_tx_descriptor_init(&desc->async_tx, &chan->common);
+	desc->async_tx.tx_submit = xilinx_dma_tx_submit;
+
+	/* Build transactions using information in the scatter gather list */
+	for_each_sg(sgl, sg, sg_len, i) {
+		sg_used = 0;
+
+		/* Loop until the entire scatterlist entry is used */
+		while (sg_used < sg_dma_len(sg)) {
+			struct xilinx_dma_desc_hw *hw;
+
+			/* Get a free segment */
+			segment = xilinx_dma_alloc_tx_segment(chan);
+			if (!segment)
+				goto error;
+
+			/*
+			 * Calculate the maximum number of bytes to transfer,
+			 * making sure it is less than the hw limit
+			 */
+			copy = min_t(size_t, sg_dma_len(sg) - sg_used,
+				     XILINX_DMA_MAX_TRANS_LEN);
+			hw = &segment->hw;
+
+			/* Fill in the descriptor */
+			hw->buf_addr = sg_dma_address(sg) + sg_used;
+
+			hw->control = copy;
+
+			if (direction == DMA_MEM_TO_DEV) {
+				if (app_w)
+					memcpy(hw->app, app_w, sizeof(u32) *
+					       XILINX_DMA_NUM_APP_WORDS);
+			}
+
+			sg_used += copy;
+
+			/*
+			 * Insert the segment into the descriptor segments
+			 * list.
+			 */
+			list_add_tail(&segment->node, &desc->segments);
+		}
+	}
+
+	segment = list_first_entry(&desc->segments,
+				   struct xilinx_dma_tx_segment, node);
+	desc->async_tx.phys = segment->phys;
+
+	/* For the last DMA_MEM_TO_DEV transfer, set EOP */
+	if (direction == DMA_MEM_TO_DEV) {
+		segment->hw.control |= XILINX_DMA_BD_SOP;
+		segment = list_last_entry(&desc->segments,
+					  struct xilinx_dma_tx_segment,
+					  node);
+		segment->hw.control |= XILINX_DMA_BD_EOP;
+	}
+
+	return &desc->async_tx;
+
+error:
+	xilinx_dma_free_tx_descriptor(chan, desc);
+	return NULL;
+}
+
+/**
+ * xilinx_dma_terminate_all - Halt the channel and free descriptors
+ * @dchan: DMA Channel pointer
+ *
+ * Return: '0' always
+ */
+static int xilinx_dma_terminate_all(struct dma_chan *dchan)
+{
+	struct xilinx_dma_chan *chan = to_xilinx_chan(dchan);
+
+	/* Halt the DMA engine */
+	xilinx_dma_halt(chan);
+
+	/* Remove and free all of the descriptors in the lists */
+	xilinx_dma_free_descriptors(chan);
+
+	return 0;
+}
+
+/**
+ * xilinx_dma_chan_remove - Per Channel remove function
+ * @chan: Driver specific DMA channel
+ */
+static void xilinx_dma_chan_remove(struct xilinx_dma_chan *chan)
+{
+	/* Disable interrupts */
+	chan->ctrl_reg &= ~XILINX_DMA_XR_IRQ_ALL_MASK;
+	dma_ctrl_write(chan, XILINX_DMA_REG_CONTROL, chan->ctrl_reg);
+
+	if (chan->irq > 0)
+		free_irq(chan->irq, chan);
+
+	tasklet_kill(&chan->tasklet);
+
+	list_del(&chan->common.device_node);
+}
+
+/**
+ * xilinx_dma_chan_probe - Per Channel Probing
+ * It get channel features from the device tree entry and
+ * initialize special channel handling routines
+ *
+ * @xdev: Driver specific device structure
+ * @node: Device node
+ *
+ * Return: '0' on success and failure value on error
+ */
+static int xilinx_dma_chan_probe(struct xilinx_dma_device *xdev,
+				 struct device_node *node)
+{
+	struct xilinx_dma_chan *chan;
+	int err;
+	bool has_dre;
+	u32 value, width = 0;
+
+	/* alloc channel */
+	chan = devm_kzalloc(xdev->dev, sizeof(*chan), GFP_KERNEL);
+	if (!chan)
+		return -ENOMEM;
+
+	chan->dev = xdev->dev;
+	chan->xdev = xdev;
+	chan->has_sg = xdev->has_sg;
+	chan->desc_pendingcount = 0x0;
+
+	has_dre = of_property_read_bool(node, "xlnx,include-dre");
+
+	err = of_property_read_u32(node, "xlnx,datawidth", &value);
+	if (err) {
+		dev_err(xdev->dev, "unable to read datawidth property");
+		return err;
+	}
+
+	width = value >> 3; /* Convert bits to bytes */
+
+	/* If data width is greater than 8 bytes, DRE is not in hw */
+	if (width > 8)
+		has_dre = false;
+
+	if (!has_dre)
+		xdev->common.copy_align = fls(width - 1);
+
+	if (of_device_is_compatible(node, "xlnx,axi-dma-mm2s-channel")) {
+		chan->id = 0;
+		chan->ctrl_offset = XILINX_DMA_MM2S_CTRL_OFFSET;
+	} else if (of_device_is_compatible(node, "xlnx,axi-dma-s2mm-channel")) {
+		chan->id = 1;
+		chan->ctrl_offset = XILINX_DMA_S2MM_CTRL_OFFSET;
+	} else {
+		dev_err(xdev->dev, "Invalid channel compatible node\n");
+		return -EINVAL;
+	}
+
+	xdev->chan[chan->id] = chan;
+
+	/* Initialize the channel */
+	err = xilinx_dma_chan_reset(chan);
+	if (err) {
+		dev_err(xdev->dev, "Reset channel failed\n");
+		return err;
+	}
+
+	spin_lock_init(&chan->lock);
+	INIT_LIST_HEAD(&chan->pending_list);
+	INIT_LIST_HEAD(&chan->done_list);
+	INIT_LIST_HEAD(&chan->active_list);
+	INIT_LIST_HEAD(&chan->free_seg_list);
+
+	chan->common.device = &xdev->common;
+
+	/* find the IRQ line, if it exists in the device tree */
+	chan->irq = irq_of_parse_and_map(node, 0);
+	err = request_irq(chan->irq, xilinx_dma_irq_handler,
+			  IRQF_SHARED,
+			  "xilinx-dma-controller", chan);
+	if (err) {
+		dev_err(xdev->dev, "unable to request IRQ %d\n", chan->irq);
+		return err;
+	}
+
+	/* Initialize the tasklet */
+	tasklet_init(&chan->tasklet, xilinx_dma_do_tasklet,
+		     (unsigned long)chan);
+
+	/* Add the channel to DMA device channel list */
+	list_add_tail(&chan->common.device_node, &xdev->common.channels);
+
+	chan->idle = true;
+
+	return 0;
+}
+
+/**
+ * of_dma_xilinx_xlate - Translation function
+ * @dma_spec: Pointer to DMA specifier as found in the device tree
+ * @ofdma: Pointer to DMA controller data
+ *
+ * Return: DMA channel pointer on success and NULL on error
+ */
+static struct dma_chan *of_dma_xilinx_xlate(struct of_phandle_args *dma_spec,
+					    struct of_dma *ofdma)
+{
+	struct xilinx_dma_device *xdev = ofdma->of_dma_data;
+	int chan_id = dma_spec->args[0];
+
+	if (chan_id >= XILINX_DMA_MAX_CHANS_PER_DEVICE)
+		return NULL;
+
+	return dma_get_slave_channel(&xdev->chan[chan_id]->common);
+}
+
+/**
+ * xilinx_dma_probe - Driver probe function
+ * @pdev: Pointer to the platform_device structure
+ *
+ * Return: '0' on success and failure value on error
+ */
+static int xilinx_dma_probe(struct platform_device *pdev)
+{
+	struct xilinx_dma_device *xdev;
+	struct device_node *child, *node;
+	struct resource *res;
+	int i, ret;
+
+	xdev = devm_kzalloc(&pdev->dev, sizeof(*xdev), GFP_KERNEL);
+	if (!xdev)
+		return -ENOMEM;
+
+	xdev->dev = &(pdev->dev);
+	INIT_LIST_HEAD(&xdev->common.channels);
+
+	node = pdev->dev.of_node;
+
+	/* Map the registers */
+	res = platform_get_resource(pdev, IORESOURCE_MEM, 0);
+	xdev->regs = devm_ioremap_resource(&pdev->dev, res);
+	if (IS_ERR(xdev->regs))
+		return PTR_ERR(xdev->regs);
+
+	/* Check if SG is enabled */
+	xdev->has_sg = of_property_read_bool(node, "xlnx,include-sg");
+
+	/* Axi DMA only do slave transfers */
+	dma_cap_set(DMA_SLAVE, xdev->common.cap_mask);
+	dma_cap_set(DMA_PRIVATE, xdev->common.cap_mask);
+	xdev->common.device_prep_slave_sg = xilinx_dma_prep_slave_sg;
+	xdev->common.device_terminate_all = xilinx_dma_terminate_all;
+	xdev->common.device_issue_pending = xilinx_dma_issue_pending;
+	xdev->common.device_alloc_chan_resources =
+		xilinx_dma_alloc_chan_resources;
+	xdev->common.device_free_chan_resources =
+		xilinx_dma_free_chan_resources;
+	xdev->common.device_tx_status = xilinx_dma_tx_status;
+	xdev->common.directions = BIT(DMA_DEV_TO_MEM) | BIT(DMA_MEM_TO_DEV);
+	xdev->common.residue_granularity = DMA_RESIDUE_GRANULARITY_SEGMENT;
+	xdev->common.dev = &pdev->dev;
+
+	platform_set_drvdata(pdev, xdev);
+
+	for_each_child_of_node(node, child) {
+		ret = xilinx_dma_chan_probe(xdev, child);
+		if (ret) {
+			dev_err(&pdev->dev, "Probing channels failed\n");
+			goto free_chan_resources;
+		}
+	}
+
+	dma_async_device_register(&xdev->common);
+
+	ret = of_dma_controller_register(node, of_dma_xilinx_xlate, xdev);
+	if (ret) {
+		dev_err(&pdev->dev, "Unable to register DMA to DT\n");
+		dma_async_device_unregister(&xdev->common);
+		goto free_chan_resources;
+	}
+
+	dev_info(&pdev->dev, "Xilinx AXI DMA Engine driver Probed!!\n");
+
+	return 0;
+
+free_chan_resources:
+	for (i = 0; i < XILINX_DMA_MAX_CHANS_PER_DEVICE; i++)
+		if (xdev->chan[i])
+			xilinx_dma_chan_remove(xdev->chan[i]);
+
+	return ret;
+}
+
+/**
+ * xilinx_dma_remove - Driver remove function
+ * @pdev: Pointer to the platform_device structure
+ *
+ * Return: Always '0'
+ */
+static int xilinx_dma_remove(struct platform_device *pdev)
+{
+	struct xilinx_dma_device *xdev = platform_get_drvdata(pdev);
+	int i;
+
+	of_dma_controller_free(pdev->dev.of_node);
+	dma_async_device_unregister(&xdev->common);
+
+	for (i = 0; i < XILINX_DMA_MAX_CHANS_PER_DEVICE; i++)
+		if (xdev->chan[i])
+			xilinx_dma_chan_remove(xdev->chan[i]);
+
+	return 0;
+}
+
+static const struct of_device_id xilinx_dma_of_match[] = {
+	{ .compatible = "xlnx,axi-dma-1.00.a",},
+	{}
+};
+MODULE_DEVICE_TABLE(of, xilinx_dma_of_match);
+
+static struct platform_driver xilinx_dma_driver = {
+	.driver = {
+		.name = "xilinx-dma",
+		.of_match_table = xilinx_dma_of_match,
+	},
+	.probe = xilinx_dma_probe,
+	.remove = xilinx_dma_remove,
+};
+
+module_platform_driver(xilinx_dma_driver);
+
+MODULE_AUTHOR("Xilinx, Inc.");
+MODULE_DESCRIPTION("Xilinx DMA driver");
+MODULE_LICENSE("GPL");
-- 
2.1.2



From santosh.shilimkar at oracle.com  Mon Aug 24 09:15:08 2015
From: santosh.shilimkar at oracle.com (santosh shilimkar)
Date: Mon, 24 Aug 2015 09:15:08 -0700
Subject: [RESEND][PATCH 4/4] ARM: dts: keystone: Add ti,keystone-spi for
 SPI
In-Reply-To: <55DB1DC5.7060607@ti.com>
References: <1437568344-18889-1-git-send-email-fcooper@ti.com>
 <1437568344-18889-5-git-send-email-fcooper@ti.com>
 <55AFC207.3050100@oracle.com> <55DB1DC5.7060607@ti.com>
Message-ID: <55DB430C.5050303@oracle.com>

On 8/24/2015 6:36 AM, Franklin S Cooper Jr. wrote:
> Hi Santosh,
>
> All the patches except this one are in linux-next.
>
Yes I noticed it. I will queue this up for next merge window.
Thanks for reminder.

Regards,
Santosh


From vladimir.murzin at arm.com  Mon Aug 24 09:16:50 2015
From: vladimir.murzin at arm.com (Vladimir Murzin)
Date: Mon, 24 Aug 2015 17:16:50 +0100
Subject: [PATCH v2 5/5] arm64: add KASan support
In-Reply-To: <CAPAsAGyg_oUvUrfSSQccVMcGtY_bwR8n6tf3tFsnh43YT6-b4w@mail.gmail.com>
References: <1431698344-28054-1-git-send-email-a.ryabinin@samsung.com>	<1431698344-28054-6-git-send-email-a.ryabinin@samsung.com>	<CACRpkdaRJJjCXR=vK1M2YhR26JZfGoBB+jcqz8r2MhERfxRzqA@mail.gmail.com>	<CAPAsAGy-r8Z2N09wKV+e0kLfbwxd-eWK6N5Xajsnqq9jfyWqcQ@mail.gmail.com>	<CACRpkdZmHLMxosLXjyOPdkavo=UNzmTcHOLF5vV4cS1ULfbq6A@mail.gmail.com>	<CAPAsAGw-iawTpjJh66rQN5fqBFT6UBZCcv2eKx7JTqCXzhzpsw@mail.gmail.com>	<CACRpkdY2i2M27gP_fXawkFrC_GFgWaKr5rEn6d47refNPiEk=g@mail.gmail.com>	<55AE56DB.4040607@samsung.com>	<CACRpkdYaqK8upK-3b01JbO_y+sHnk4-Hm1MfvjSy0tKUkFREtQ@mail.gmail.com>	<20150824131557.GB7557@n2100.arm.linux.org.uk>	<CACRpkdYwpucRiXM05y00RQY=gKv8W6YjCNspYFRMGaM605cU0w@mail.gmail.com>	<CAPAsAGwji7FpUJK9O=FWYN15-rJkYMQyOt9W9ncdY9uLybxkiA@mail.gmail.com>	<55DB3BD3.7030202@arm.com>
 <CAPAsAGyg_oUvUrfSSQccVMcGtY_bwR8n6tf3tFsnh43YT6-b4w@mail.gmail.com>
Message-ID: <55DB4372.5010406@arm.com>

On 24/08/15 17:00, Andrey Ryabinin wrote:
> 2015-08-24 18:44 GMT+03:00 Vladimir Murzin <vladimir.murzin at arm.com>:
>>
>> Another option would be having "sparse" shadow memory based on page
>> extension. I did play with that some time ago based on ideas from
>> original v1 KASan support for x86/arm - it is how 614be38 "irqchip:
>> gic-v3: Fix out of bounds access to cpu_logical_map" was caught.
>> It doesn't require any VA reservations, only some contiguous memory for
>> the page_ext itself, which serves as indirection level for the 0-order
>> shadow pages.
> 
> We won't be able to use inline instrumentation (I could live with that),
> and most importantly, we won't be able to use stack instrumentation.
> GCC needs to know shadow address for inline and/or stack instrumentation
> to generate correct code.

It's definitely a trade-off ;)

Just for my understanding does that stack instrumentation is controlled
via -asan-stack?

Thanks
Vladimir

> 
>> In theory such design can be reused by others 32-bit arches and, I
>> think, nommu too. Additionally, the shadow pages might be movable with
>> help of driver-page migration patch series [1].
>> The cost is obvious - performance drop, although I didn't bother
>> measuring it.
>>
>> [1] https://lwn.net/Articles/650917/
>>
>> Cheers
>> Vladimir
>>
> 



From heiko at sntech.de  Mon Aug 24 09:16:39 2015
From: heiko at sntech.de (Heiko Stuebner)
Date: Mon, 24 Aug 2015 18:16:39 +0200
Subject: [PATCH v3 06/14] Documentation: drm/bridge: add document for
 analogix_dp
In-Reply-To: <CAL_JsqKZYMMzV9Sc2r3K_rnM0FNuyb1TyJEhjGq1Hf7dTiWFKQ@mail.gmail.com>
References: <1439995728-18046-1-git-send-email-ykk@rock-chips.com>
 <20150824125758.GA7557@n2100.arm.linux.org.uk>
 <CAL_JsqKZYMMzV9Sc2r3K_rnM0FNuyb1TyJEhjGq1Hf7dTiWFKQ@mail.gmail.com>
Message-ID: <1749941.uaVRIcm7Pc@phil>

Am Montag, 24. August 2015, 09:48:27 schrieb Rob Herring:
> On Mon, Aug 24, 2015 at 7:57 AM, Russell King - ARM Linux
> > When we adopted the graph bindings for iMX DRM, I thought exactly at that
> > time "it would be nice if this could become the standard for binding DRM
> > components together" but I don't have the authority from either the DT
> > perspective or the DRM perspective to mandate that.  Neither does anyone
> > else.  That's the _real_ problem here.
> > 
> > I've seen several DRM bindings go by which don't use the of-graph stuff,
> > which means that they'll never be compatible with generic components
> > which do use the of-graph stuff.
> 
> It goes beyond bindings IMO. The use of the component framework or not
> has been at the whim of driver writers as well. It is either used or
> private APIs are created. I'm using components and my need for it
> boils down to passing the struct drm_device pointer to the encoder.
> Other components like panels and bridges have different ways to attach
> to the DRM driver.

but that is then simply implementation specific. Panels and bridges can very 
well be part of and created from an of_graph description without needing to be 
a (linux-)component - see patch 7.


From ryabinin.a.a at gmail.com  Mon Aug 24 09:18:33 2015
From: ryabinin.a.a at gmail.com (Andrey Ryabinin)
Date: Mon, 24 Aug 2015 19:18:33 +0300
Subject: [PATCH v2 5/5] arm64: add KASan support
In-Reply-To: <55DB4372.5010406@arm.com>
References: <1431698344-28054-1-git-send-email-a.ryabinin@samsung.com>
 <1431698344-28054-6-git-send-email-a.ryabinin@samsung.com>
 <CACRpkdaRJJjCXR=vK1M2YhR26JZfGoBB+jcqz8r2MhERfxRzqA@mail.gmail.com>
 <CAPAsAGy-r8Z2N09wKV+e0kLfbwxd-eWK6N5Xajsnqq9jfyWqcQ@mail.gmail.com>
 <CACRpkdZmHLMxosLXjyOPdkavo=UNzmTcHOLF5vV4cS1ULfbq6A@mail.gmail.com>
 <CAPAsAGw-iawTpjJh66rQN5fqBFT6UBZCcv2eKx7JTqCXzhzpsw@mail.gmail.com>
 <CACRpkdY2i2M27gP_fXawkFrC_GFgWaKr5rEn6d47refNPiEk=g@mail.gmail.com>
 <55AE56DB.4040607@samsung.com>
 <CACRpkdYaqK8upK-3b01JbO_y+sHnk4-Hm1MfvjSy0tKUkFREtQ@mail.gmail.com>
 <20150824131557.GB7557@n2100.arm.linux.org.uk>
 <CACRpkdYwpucRiXM05y00RQY=gKv8W6YjCNspYFRMGaM605cU0w@mail.gmail.com>
 <CAPAsAGwji7FpUJK9O=FWYN15-rJkYMQyOt9W9ncdY9uLybxkiA@mail.gmail.com>
 <55DB3BD3.7030202@arm.com>
 <CAPAsAGyg_oUvUrfSSQccVMcGtY_bwR8n6tf3tFsnh43YT6-b4w@mail.gmail.com>
 <55DB4372.5010406@arm.com>
Message-ID: <CAPAsAGwwEpKVVk4bxKhrGSQ-YBi74CrjTsn8Xmy4YpRB8c84VA@mail.gmail.com>

2015-08-24 19:16 GMT+03:00 Vladimir Murzin <vladimir.murzin at arm.com>:
> On 24/08/15 17:00, Andrey Ryabinin wrote:
>> 2015-08-24 18:44 GMT+03:00 Vladimir Murzin <vladimir.murzin at arm.com>:
>>>
>>> Another option would be having "sparse" shadow memory based on page
>>> extension. I did play with that some time ago based on ideas from
>>> original v1 KASan support for x86/arm - it is how 614be38 "irqchip:
>>> gic-v3: Fix out of bounds access to cpu_logical_map" was caught.
>>> It doesn't require any VA reservations, only some contiguous memory for
>>> the page_ext itself, which serves as indirection level for the 0-order
>>> shadow pages.
>>
>> We won't be able to use inline instrumentation (I could live with that),
>> and most importantly, we won't be able to use stack instrumentation.
>> GCC needs to know shadow address for inline and/or stack instrumentation
>> to generate correct code.
>
> It's definitely a trade-off ;)
>
> Just for my understanding does that stack instrumentation is controlled
> via -asan-stack?
>

Yup.


From sudeep.holla at arm.com  Mon Aug 24 09:27:53 2015
From: sudeep.holla at arm.com (Sudeep Holla)
Date: Mon, 24 Aug 2015 17:27:53 +0100
Subject: [PATCH v4] pinctrl: mediatek: Implement wake handler and suspend
 resume
In-Reply-To: <1439541486-22203-1-git-send-email-maoguang.meng@mediatek.com>
References: <1439541486-22203-1-git-send-email-maoguang.meng@mediatek.com>
Message-ID: <55DB4609.5040904@arm.com>



On 14/08/15 09:38, maoguang.meng at mediatek.com wrote:
> From: Maoguang Meng <maoguang.meng at mediatek.com>
>
> This patch implement irq_set_wake to get who is wakeup source and
> setup on suspend resume.
>
> Signed-off-by: Maoguang Meng <maoguang.meng at mediatek.com>
>
> ---
> changes since v3:
> -add a comment in mtk_eint_chip_read_mask.
> -delete ALIGN when allocate eint_offsets.ports.
> -fix unrelated change.
>
> changes since v2:
> -modify irq_wake to handle irq wakeup source.
> -allocate two buffers separately.
> -fix some codestyle.
>
> Changes since v1:
> -implement irq_wake handler.
> ---
>
>   drivers/pinctrl/mediatek/pinctrl-mt8173.c     |  1 +
>   drivers/pinctrl/mediatek/pinctrl-mtk-common.c | 91 ++++++++++++++++++++++++++-
>   drivers/pinctrl/mediatek/pinctrl-mtk-common.h |  4 ++
>   3 files changed, 95 insertions(+), 1 deletion(-)
>
> diff --git a/drivers/pinctrl/mediatek/pinctrl-mt8173.c b/drivers/pinctrl/mediatek/pinctrl-mt8173.c
> index d0c811d..ad27184 100644
> --- a/drivers/pinctrl/mediatek/pinctrl-mt8173.c
> +++ b/drivers/pinctrl/mediatek/pinctrl-mt8173.c
> @@ -385,6 +385,7 @@ static struct platform_driver mtk_pinctrl_driver = {
>   	.driver = {
>   		.name = "mediatek-mt8173-pinctrl",
>   		.of_match_table = mt8173_pctrl_match,
> +		.pm = &mtk_eint_pm_ops,
>   	},
>   };
>
> diff --git a/drivers/pinctrl/mediatek/pinctrl-mtk-common.c b/drivers/pinctrl/mediatek/pinctrl-mtk-common.c
> index ad1ea16..fe34ce9 100644
> --- a/drivers/pinctrl/mediatek/pinctrl-mtk-common.c
> +++ b/drivers/pinctrl/mediatek/pinctrl-mtk-common.c
> @@ -33,6 +33,7 @@
>   #include <linux/mfd/syscon.h>
>   #include <linux/delay.h>
>   #include <linux/interrupt.h>
> +#include <linux/pm.h>
>   #include <dt-bindings/pinctrl/mt65xx.h>
>
>   #include "../core.h"
> @@ -1062,6 +1063,77 @@ static int mtk_eint_set_type(struct irq_data *d,
>   	return 0;
>   }
>
> +static int mtk_eint_irq_set_wake(struct irq_data *d, unsigned int on)
> +{
> +	struct mtk_pinctrl *pctl = irq_data_get_irq_chip_data(d);
> +	int shift = d->hwirq & 0x1f;
> +	int reg = d->hwirq >> 5;
> +
> +	if (on)
> +		pctl->wake_mask[reg] |= BIT(shift);
> +	else
> +		pctl->wake_mask[reg] &= ~BIT(shift);
> +
> +	return 0;
> +}

Does this pinmux controller:

1. Support wake-up configuration ? If not, you need to use
    IRQCHIP_SKIP_SET_WAKE. I don't see any value in writing the
    mask_{set,clear} if the same registers are used for {en,dis}able

2. Is in always on domain ? If not, you need save/restore only to
    resume back the functionality. Generally we can set 	
    IRQCHIP_MASK_ON_SUSPEND to ensure non-wake-up interrupts are
    disabled during suspend and re-enabled in resume path. You just
    save/restore raw values without tracking the wake-up source.

Also I see that no care is taken to set the port irq as wake enable
source. It may work with current mainline, but won't with -next. Please
ensure the port irq to the parent interrupt controller remains
enabled(i.e set as wake).

Regards,
Sudeep


From gpkulkarni at gmail.com  Mon Aug 24 09:28:53 2015
From: gpkulkarni at gmail.com (Ganapatrao Kulkarni)
Date: Mon, 24 Aug 2015 21:58:53 +0530
Subject: [PATCH] irqchip, gicv3-its, numa: Workaround for Cavium ThunderX
 erratum 23144
In-Reply-To: <55DB205E.9070205@arm.com>
References: <20150822131050.GK1820@rric.localdomain> <55DAEF3C.5090303@arm.com>
 <CAFpQJXVVcdag7OQnCxqyEw601Y32eO2rHCmH1_bVzyvg+OPzRA@mail.gmail.com>
 <55DB11F3.1070604@arm.com>
 <CAFpQJXUTNss=u2x7Ynd9wOObZn_ZHkcMz2+F4MKooy5jrvZ02w@mail.gmail.com>
 <55DB205E.9070205@arm.com>
Message-ID: <CAFpQJXV62o5hmn7GpSGpsnWfUMGCXjgVJDE6PAQVJwhRC5XAJA@mail.gmail.com>

Hi Marc,

thanks for the suggestions.

On Mon, Aug 24, 2015 at 7:17 PM, Marc Zyngier <marc.zyngier at arm.com> wrote:
> On 24/08/15 14:27, Ganapatrao Kulkarni wrote:
>> On Mon, Aug 24, 2015 at 6:15 PM, Marc Zyngier <marc.zyngier at arm.com> wrote:
>
>>>>>>  static void its_enable_cavium_thunderx(void *data)
>>>>>>  {
>>>>>> -     struct its_node *its = data;
>>>>>> +     struct its_node __maybe_unused *its = data;
>>>>>>
>>>>>> -     its->flags |= ITS_FLAGS_CAVIUM_THUNDERX;
>>>>>> +#ifdef CONFIG_CAVIUM_ERRATUM_22375
>>>>>> +     its->flags |= ITS_WORKAROUND_CAVIUM_22375;
>>>>>> +     pr_info("ITS: Enabling workaround for 22375, 24313\n");
>>>>>> +#endif
>>>>>> +
>>>>>> +#ifdef CONFIG_CAVIUM_ERRATUM_23144
>>>>>> +     if (num_possible_nodes() > 1) {
>>>>>> +             its->numa_node = its_get_node_thunderx(its);
>>>>>
>>>>> I'd rather see numa_node being always initialized to something useful.
>>>>> If you're adding numa support, why can't this be initialized via
>>>>> standard topology bindings?
>>>> IIUC, topology defines only cpu topology.
>>>
>>> Well, welcome to a much more complex system where both your CPUs and
>>> your IOs have some degree of affinity. This needs to be described
>>> properly, and not hacked on the side.
>> ok, will add description for the function.
>
> I sense that you misunderstood what I meant. What I'd like to see is
> some topology information coming from DT, showing the relationship
> between a device (your ITS) and a given node (your socket). This can
> then be used from two purposes:
sure will post next version with changes as per you comments.
>
> - find the optimal affinity for a MSI so that it doesn't default to a
> foreign node (a reasonable performance expectation),
this can be done by adding dt associativity property to its node.
 i can send in next version of patch.
> - work around implementation bugs where an LPI cannot be routed to a
> redistributor that is on a foreign node.


>
> I really don't feel like adding a hack just for the second point, and
> I'd rather get the big picture right so that your workaround is just a
> special case of the generic one.
>
> Thanks,
>
>         M.
> --
> Jazz is not dead. It just smells funny...

thanks
Ganapat


From andre.przywara at arm.com  Mon Aug 24 09:33:19 2015
From: andre.przywara at arm.com (Andre Przywara)
Date: Mon, 24 Aug 2015 17:33:19 +0100
Subject: [PATCH v2 01/15] KVM: arm/arm64: VGIC: don't track used LRs in
 the distributor
In-Reply-To: <55CB0B80.5040508@linaro.org>
References: <1436538111-4294-1-git-send-email-andre.przywara@arm.com>
 <1436538111-4294-2-git-send-email-andre.przywara@arm.com>
 <55CB0B80.5040508@linaro.org>
Message-ID: <55DB474F.7010202@arm.com>

Hi Eric,

On 12/08/15 10:01, Eric Auger wrote:
....
>> diff --git a/virt/kvm/arm/vgic.c b/virt/kvm/arm/vgic.c
>> index bc40137..394622c 100644
>> --- a/virt/kvm/arm/vgic.c
>> +++ b/virt/kvm/arm/vgic.c
>> @@ -79,7 +79,6 @@
>>  #include "vgic.h"
>>  
>>  static void vgic_retire_disabled_irqs(struct kvm_vcpu *vcpu);
>> -static void vgic_retire_lr(int lr_nr, int irq, struct kvm_vcpu *vcpu);
>>  static struct vgic_lr vgic_get_lr(const struct kvm_vcpu *vcpu, int lr);
>>  static void vgic_set_lr(struct kvm_vcpu *vcpu, int lr, struct vgic_lr lr_desc);
>>  
>> @@ -647,6 +646,17 @@ bool vgic_handle_cfg_reg(u32 *reg, struct kvm_exit_mmio *mmio,
>>  	return false;
>>  }
>>  
>> +static void vgic_sync_lr_elrsr(struct kvm_vcpu *vcpu, int lr,
>> +			       struct vgic_lr vlr)
>> +{
>> +	vgic_ops->sync_lr_elrsr(vcpu, lr, vlr);
>> +}
> why not renaming this into vgic_set_elrsr. This would be homogeneous
> with other virtual interface control register setters?

But that would involve renaming the vgic_ops members as well to be
consistent, right? As there is no change in the behaviour, a naming
change sounds unmotivated to me. And _set_ wouldn't be exact, as this
function deals only with only one bit at a time and allows to clear it
as well.

>> +
>> +static inline u64 vgic_get_elrsr(struct kvm_vcpu *vcpu)
>> +{
>> +	return vgic_ops->get_elrsr(vcpu);
>> +}
> If I am not wrong, each time you manipulate the elrsr you handle the
> bitmap. why not directly returning an unsigned long * then (elrsr_ptr)?

Because the pointer needs to point somewhere, and that storage is
currently located on the caller's stack. Directly returning a pointer
would require the caller to provide some memory for the u64, which does
not save you so much in terms on LOC:

-	u64 elrsr = vgic_get_elrsr(vcpu);
-	unsigned long *elrsr_ptr = u64_to_bitmask(&elrsr);
+	u64 elrsr;
+	unsigned long *elrsr_ptr = vgic_get_elrsr_bm(vcpu, &elrsr);

Also we need u64_to_bitmask() in one case when converting the EISR
value, so we cannot get lost of that function.

>> +
>>  /**
>>   * vgic_unqueue_irqs - move pending/active IRQs from LRs to the distributor
>>   * @vgic_cpu: Pointer to the vgic_cpu struct holding the LRs
>> @@ -658,9 +668,11 @@ bool vgic_handle_cfg_reg(u32 *reg, struct kvm_exit_mmio *mmio,
>>  void vgic_unqueue_irqs(struct kvm_vcpu *vcpu)
>>  {
>>  	struct vgic_cpu *vgic_cpu = &vcpu->arch.vgic_cpu;
>> +	u64 elrsr = vgic_get_elrsr(vcpu);
>> +	unsigned long *elrsr_ptr = u64_to_bitmask(&elrsr);
>>  	int i;
>>  
>> -	for_each_set_bit(i, vgic_cpu->lr_used, vgic_cpu->nr_lr) {
>> +	for_each_clear_bit(i, elrsr_ptr, vgic_cpu->nr_lr) {
>>  		struct vgic_lr lr = vgic_get_lr(vcpu, i);
>>  
>>  		/*
>> @@ -703,7 +715,7 @@ void vgic_unqueue_irqs(struct kvm_vcpu *vcpu)
>>  		 * Mark the LR as free for other use.
>>  		 */
>>  		BUG_ON(lr.state & LR_STATE_MASK);
>> -		vgic_retire_lr(i, lr.irq, vcpu);
>> +		vgic_sync_lr_elrsr(vcpu, i, lr);
>>  		vgic_irq_clear_queued(vcpu, lr.irq);
>>  
>>  		/* Finally update the VGIC state. */
>> @@ -1011,17 +1023,6 @@ static void vgic_set_lr(struct kvm_vcpu *vcpu, int lr,
>>  	vgic_ops->set_lr(vcpu, lr, vlr);
>>  }
>>  
>> -static void vgic_sync_lr_elrsr(struct kvm_vcpu *vcpu, int lr,
>> -			       struct vgic_lr vlr)
>> -{
>> -	vgic_ops->sync_lr_elrsr(vcpu, lr, vlr);
>> -}
>> -
>> -static inline u64 vgic_get_elrsr(struct kvm_vcpu *vcpu)
>> -{
>> -	return vgic_ops->get_elrsr(vcpu);
>> -}
>> -
>>  static inline u64 vgic_get_eisr(struct kvm_vcpu *vcpu)
>>  {
>>  	return vgic_ops->get_eisr(vcpu);
>> @@ -1062,18 +1063,6 @@ static inline void vgic_enable(struct kvm_vcpu *vcpu)
>>  	vgic_ops->enable(vcpu);
>>  }
>>  
>> -static void vgic_retire_lr(int lr_nr, int irq, struct kvm_vcpu *vcpu)
>> -{
>> -	struct vgic_cpu *vgic_cpu = &vcpu->arch.vgic_cpu;
>> -	struct vgic_lr vlr = vgic_get_lr(vcpu, lr_nr);
>> -
>> -	vlr.state = 0;
>> -	vgic_set_lr(vcpu, lr_nr, vlr);
>> -	clear_bit(lr_nr, vgic_cpu->lr_used);
>> -	vgic_cpu->vgic_irq_lr_map[irq] = LR_EMPTY;
>> -	vgic_sync_lr_elrsr(vcpu, lr_nr, vlr);
>> -}
>> -
>>  /*
>>   * An interrupt may have been disabled after being made pending on the
>>   * CPU interface (the classic case is a timer running while we're
>> @@ -1085,23 +1074,32 @@ static void vgic_retire_lr(int lr_nr, int irq, struct kvm_vcpu *vcpu)
>>   */
>>  static void vgic_retire_disabled_irqs(struct kvm_vcpu *vcpu)
>>  {
>> -	struct vgic_cpu *vgic_cpu = &vcpu->arch.vgic_cpu;
>> +	u64 elrsr = vgic_get_elrsr(vcpu);
>> +	unsigned long *elrsr_ptr = u64_to_bitmask(&elrsr);
> if you agree with above modif I would simply rename elrsr_ptr into elrsr.
>>  	int lr;
>> +	struct vgic_lr vlr;
> why moving this declaration here. I think this can remain in the block.

Possibly. Don't remember the reason of this move, I think it was due to
some other changes I later removed. I will revert it.

>>  
>> -	for_each_set_bit(lr, vgic_cpu->lr_used, vgic->nr_lr) {
>> -		struct vgic_lr vlr = vgic_get_lr(vcpu, lr);
>> +	for_each_clear_bit(lr, elrsr_ptr, vgic->nr_lr) {
>> +		vlr = vgic_get_lr(vcpu, lr);
>>  
>>  		if (!vgic_irq_is_enabled(vcpu, vlr.irq)) {
>> -			vgic_retire_lr(lr, vlr.irq, vcpu);
>> -			if (vgic_irq_is_queued(vcpu, vlr.irq))
>> -				vgic_irq_clear_queued(vcpu, vlr.irq);
>> +			vlr.state = 0;
>> +			vgic_set_lr(vcpu, lr, vlr);
>> +			vgic_sync_lr_elrsr(vcpu, lr, vlr);
> vgic_set_elrsr?
> 
> the "if (vgic_irq_is_queued(vcpu, vlr.irq))" check disappeared. This
> change might be introduced separately.

OK, this is an admittedly independent optimization to avoid the needless
check for "clear only set bits". I didn't find it useful to spin a
separate patch for this, so just fixed this while reworking this code
anyway.

>> +			vgic_irq_clear_queued(vcpu, vlr.irq);
>>  		}
>>  	}
>>  }
>>  
>>  static void vgic_queue_irq_to_lr(struct kvm_vcpu *vcpu, int irq,
>> -				 int lr_nr, struct vgic_lr vlr)
> I don't think this change of proto is compatible with Marc's "KVM:
> arm/arm64: vgic: Allow HW interrupts to be queued to a guest".
> I think we need to keep former signature.

I will need to rebase my series on top of the 4.3 pull request anyway,
so: yes, I will adapt to Marc's series.

>> +				 int lr_nr, int sgi_source_id)
>>  {
>> +	struct vgic_lr vlr;
>> +
>> +	vlr.state = 0;
>> +	vlr.irq = irq;
>> +	vlr.source = sgi_source_id;
>> +
>>  	if (vgic_irq_is_active(vcpu, irq)) {
>>  		vlr.state |= LR_STATE_ACTIVE;
>>  		kvm_debug("Set active, clear distributor: 0x%x\n", vlr.state);
>> @@ -1126,9 +1124,9 @@ static void vgic_queue_irq_to_lr(struct kvm_vcpu *vcpu, int irq,
>>   */
>>  bool vgic_queue_irq(struct kvm_vcpu *vcpu, u8 sgi_source_id, int irq)
>>  {
>> -	struct vgic_cpu *vgic_cpu = &vcpu->arch.vgic_cpu;
>>  	struct vgic_dist *dist = &vcpu->kvm->arch.vgic;
>> -	struct vgic_lr vlr;
>> +	u64 elrsr = vgic_get_elrsr(vcpu);
>> +	unsigned long *elrsr_ptr = u64_to_bitmask(&elrsr);
>>  	int lr;
>>  
>>  	/* Sanitize the input... */
>> @@ -1138,42 +1136,20 @@ bool vgic_queue_irq(struct kvm_vcpu *vcpu, u8 sgi_source_id, int irq)
>>  
>>  	kvm_debug("Queue IRQ%d\n", irq);
>>  
>> -	lr = vgic_cpu->vgic_irq_lr_map[irq];
>> -
>> -	/* Do we have an active interrupt for the same CPUID? */
>> -	if (lr != LR_EMPTY) {
>> -		vlr = vgic_get_lr(vcpu, lr);
>> -		if (vlr.source == sgi_source_id) {
>> -			kvm_debug("LR%d piggyback for IRQ%d\n", lr, vlr.irq);
>> -			BUG_ON(!test_bit(lr, vgic_cpu->lr_used));
>> -			vgic_queue_irq_to_lr(vcpu, irq, lr, vlr);
>> -			return true;
>> -		}
>> -	}
>> +	lr = find_first_bit(elrsr_ptr, vgic->nr_lr);
>>  
>> -	/* Try to use another LR for this interrupt */
>> -	lr = find_first_zero_bit((unsigned long *)vgic_cpu->lr_used,
>> -			       vgic->nr_lr);
>>  	if (lr >= vgic->nr_lr)
>>  		return false;
>>  
>>  	kvm_debug("LR%d allocated for IRQ%d %x\n", lr, irq, sgi_source_id);
>> -	vgic_cpu->vgic_irq_lr_map[irq] = lr;
>> -	set_bit(lr, vgic_cpu->lr_used);
>>  
>> -	vlr.irq = irq;
>> -	vlr.source = sgi_source_id;
>> -	vlr.state = 0;
>> -	vgic_queue_irq_to_lr(vcpu, irq, lr, vlr);
>> +	vgic_queue_irq_to_lr(vcpu, irq, lr, sgi_source_id);
>>  
>>  	return true;
>>  }
>>  
>>  static bool vgic_queue_hwirq(struct kvm_vcpu *vcpu, int irq)
>>  {
>> -	if (!vgic_can_sample_irq(vcpu, irq))
>> -		return true; /* level interrupt, already queued */
>> -
> I think that change needs to be introduced in a separate patch as the
> other one mentioned above and justified since it affects the state machine.

But this change is dependent on this patch: it will not work without
this patch and this patch will not work without that change.
So the idea is that on returning from the guest we now harvest all
_used_ LRs by copying their state back into the distributor. The
previous behaviour was to just check _unused_ LRs for completed IRQs.
So now all IRQs need to be re-inserted into the LRs before the next
guest run, that's why we have to remove the test which skipped this for
IRQs where the code knew that they were still in the LRs.
Does that make sense?

Cheers,
Andre.


From Suravee.Suthikulpanit at amd.com  Mon Aug 24 09:41:29 2015
From: Suravee.Suthikulpanit at amd.com (Suravee Suthikulpanit)
Date: Mon, 24 Aug 2015 23:41:29 +0700
Subject: [PATCH] pci: acpi: Generic function for setting up PCI device DMA
 coherency
In-Reply-To: <1439459925-2361-1-git-send-email-Suravee.Suthikulpanit@amd.com>
References: <1439459925-2361-1-git-send-email-Suravee.Suthikulpanit@amd.com>
Message-ID: <55DB4939.5070605@amd.com>

Hi,

Ping. Does anyone have any comments or suggestions?

Thanks,
Suravee

On 8/13/15 16:58, Suravee Suthikulpanit wrote:
> This patch refactors of_pci_dma_configure() into a more generic
> pci_dma_configure(), which can be reused by non-OF code.
> Then, it adds support for setting up PCI device DMA coherency from
> ACPI _CCA object that should normally be specified in the DSDT node
> of its PCI host bridge..
>
> Signed-off-by: Suravee Suthikulpanit <Suravee.Suthikulpanit at amd.com>
> CC: Bjorn Helgaas <bhelgaas at google.com>
> CC: Catalin Marinas <catalin.marinas at arm.com>
> CC: Will Deacon <will.deacon at arm.com>
> CC: Rafael J. Wysocki <rjw at rjwysocki.net>
> CC: Rob Herring <robh+dt at kernel.org>
> CC: Murali Karicheri <m-karicheri2 at ti.com>
> ---
> Note: According to the ACPI spec, the _CCA attribute is required
>        for ARM64. Therefore, this patch is a pre-req for ACPI PCI
>        support for ARM64 which is currently in development.
>
>        Also, this should not affect other architectures since
>        if CCA is not required, the default value is coherent.
>        Please see include/acpi/acpi_bus.h: acpi_check_dma() and
>        drivers/acpi/scan.c: acpi_init_coherency() for more information
>
>   drivers/of/of_pci.c    | 20 --------------------
>   drivers/pci/probe.c    | 35 +++++++++++++++++++++++++++++++++--
>   include/linux/of_pci.h |  3 ---
>   3 files changed, 33 insertions(+), 25 deletions(-)
>
> diff --git a/drivers/of/of_pci.c b/drivers/of/of_pci.c
> index 5751dc5..b66ee4e 100644
> --- a/drivers/of/of_pci.c
> +++ b/drivers/of/of_pci.c
> @@ -117,26 +117,6 @@ int of_get_pci_domain_nr(struct device_node *node)
>   }
>   EXPORT_SYMBOL_GPL(of_get_pci_domain_nr);
>
> -/**
> - * of_pci_dma_configure - Setup DMA configuration
> - * @dev: ptr to pci_dev struct of the PCI device
> - *
> - * Function to update PCI devices's DMA configuration using the same
> - * info from the OF node of host bridge's parent (if any).
> - */
> -void of_pci_dma_configure(struct pci_dev *pci_dev)
> -{
> -	struct device *dev = &pci_dev->dev;
> -	struct device *bridge = pci_get_host_bridge_device(pci_dev);
> -
> -	if (!bridge->parent)
> -		return;
> -
> -	of_dma_configure(dev, bridge->parent->of_node);
> -	pci_put_host_bridge_device(bridge);
> -}
> -EXPORT_SYMBOL_GPL(of_pci_dma_configure);
> -
>   #if defined(CONFIG_OF_ADDRESS)
>   /**
>    * of_pci_get_host_bridge_resources - Parse PCI host bridge resources from DT
> diff --git a/drivers/pci/probe.c b/drivers/pci/probe.c
> index cefd636..e2fcd3b 100644
> --- a/drivers/pci/probe.c
> +++ b/drivers/pci/probe.c
> @@ -6,12 +6,14 @@
>   #include <linux/delay.h>
>   #include <linux/init.h>
>   #include <linux/pci.h>
> -#include <linux/of_pci.h>
> +#include <linux/of_device.h>
>   #include <linux/pci_hotplug.h>
>   #include <linux/slab.h>
>   #include <linux/module.h>
>   #include <linux/cpumask.h>
>   #include <linux/pci-aspm.h>
> +#include <linux/acpi.h>
> +#include <linux/property.h>
>   #include <asm-generic/pci-bridge.h>
>   #include "pci.h"
>
> @@ -1544,6 +1546,35 @@ static void pci_init_capabilities(struct pci_dev *dev)
>   	pci_enable_acs(dev);
>   }
>
> +/**
> + * pci_dma_configure - Setup DMA configuration
> + * @pci_dev: ptr to pci_dev struct of the PCI device
> + *
> + * Function to update PCI devices's DMA configuration using the same
> + * info from the OF node or ACPI node of host bridge's parent (if any).
> + */
> +static void pci_dma_configure(struct pci_dev *pci_dev)
> +{
> +	struct device *dev = &pci_dev->dev;
> +	struct device *bridge = pci_get_host_bridge_device(pci_dev);
> +	struct acpi_device *adev;
> +	bool coherent;
> +
> +	if (has_acpi_companion(bridge)) {
> +		adev = to_acpi_node(bridge->fwnode);
> +		if (acpi_check_dma(adev, &coherent))
> +			arch_setup_dma_ops(dev, 0, 0, NULL, coherent);
> +	} else {
> +		struct device *host = bridge->parent;
> +		if (!host)
> +			return;
> +
> +		of_dma_configure(dev, host->of_node);
> +	}
> +
> +	pci_put_host_bridge_device(bridge);
> +}
> +
>   void pci_device_add(struct pci_dev *dev, struct pci_bus *bus)
>   {
>   	int ret;
> @@ -1557,7 +1588,7 @@ void pci_device_add(struct pci_dev *dev, struct pci_bus *bus)
>   	dev->dev.dma_mask = &dev->dma_mask;
>   	dev->dev.dma_parms = &dev->dma_parms;
>   	dev->dev.coherent_dma_mask = 0xffffffffull;
> -	of_pci_dma_configure(dev);
> +	pci_dma_configure(dev);
>
>   	pci_set_dma_max_seg_size(dev, 65536);
>   	pci_set_dma_seg_boundary(dev, 0xffffffff);
> diff --git a/include/linux/of_pci.h b/include/linux/of_pci.h
> index 29fd3fe..ce0e5ab 100644
> --- a/include/linux/of_pci.h
> +++ b/include/linux/of_pci.h
> @@ -16,7 +16,6 @@ int of_pci_get_devfn(struct device_node *np);
>   int of_irq_parse_and_map_pci(const struct pci_dev *dev, u8 slot, u8 pin);
>   int of_pci_parse_bus_range(struct device_node *node, struct resource *res);
>   int of_get_pci_domain_nr(struct device_node *node);
> -void of_pci_dma_configure(struct pci_dev *pci_dev);
>   #else
>   static inline int of_irq_parse_pci(const struct pci_dev *pdev, struct of_phandle_args *out_irq)
>   {
> @@ -51,8 +50,6 @@ of_get_pci_domain_nr(struct device_node *node)
>   {
>   	return -1;
>   }
> -
> -static inline void of_pci_dma_configure(struct pci_dev *pci_dev) { }
>   #endif
>
>   #if defined(CONFIG_OF_ADDRESS)
>


From cyrille.pitchen at atmel.com  Mon Aug 24 09:42:46 2015
From: cyrille.pitchen at atmel.com (Cyrille Pitchen)
Date: Mon, 24 Aug 2015 18:42:46 +0200
Subject: [PATCH linux-next v4 3/5] mtd: spi-nor: allow to tune the number
 of dummy cycles
In-Reply-To: <201508241248.17466.marex@denx.de>
References: <cover.1440410236.git.cyrille.pitchen@atmel.com>
 <b0d8470fdd46e89ef692e27dc2600b880c1d5dde.1440410236.git.cyrille.pitchen@atmel.com>
 <201508241248.17466.marex@denx.de>
Message-ID: <55DB4986.1000207@atmel.com>

Hi Marek,

Le 24/08/2015 12:48, Marek Vasut a ?crit :
> On Monday, August 24, 2015 at 12:13:58 PM, Cyrille Pitchen wrote:
>> The number of dummy cycles used during Fast Read commands can be reduced
>> to improve transfer performances. Each manufacturer has a dedicated set of
>> registers to provide the memory with the exact number of dummy cycles it
>> should expect. Both the memory and the (Q)SPI controller must agree on
>> this number of dummy cycles.
>>
>> The number of dummy cycles can be found into the memory datasheet and
>> mostly depends on the SPI clock frequency, the Fast Read op code and the
>> Single/Dual Data Rate mode.
>>
>> Probing JEDEC Serial Flash Discoverable Parameters (SFDP) tables would
>> only provide the driver with a high enough number of dummy cycles for each
>> Fast Read command to be used for all clock frequencies: this solution
>> would not be optimized.
>>
>> Signed-off-by: Cyrille Pitchen <cyrille.pitchen at atmel.com>
> 
> Hi!
> 
>>  drivers/mtd/spi-nor/spi-nor.c | 97
>> ++++++++++++++++++++++++++++++++++--------- include/linux/mtd/spi-nor.h  
>> |  2 +
>>  2 files changed, 80 insertions(+), 19 deletions(-)
>>
>> diff --git a/drivers/mtd/spi-nor/spi-nor.c b/drivers/mtd/spi-nor/spi-nor.c
>> index e2a6029dc056..869e098a6841 100644
>> --- a/drivers/mtd/spi-nor/spi-nor.c
>> +++ b/drivers/mtd/spi-nor/spi-nor.c
>> @@ -119,24 +119,6 @@ static int read_cr(struct spi_nor *nor)
>>  }
>>
>>  /*
>> - * Dummy Cycle calculation for different type of read.
>> - * It can be used to support more commands with
>> - * different dummy cycle requirements.
>> - */
>> -static inline int spi_nor_read_dummy_cycles(struct spi_nor *nor)
>> -{
>> -	switch (nor->flash_read) {
>> -	case SPI_NOR_FAST:
>> -	case SPI_NOR_DUAL:
>> -	case SPI_NOR_QUAD:
>> -		return 8;
>> -	case SPI_NOR_NORMAL:
>> -		return 0;
>> -	}
>> -	return 0;
>> -}
> 
> You can probably just soup up this function so that it sets the
> nor->read_dummy, no ?
>

Actually, this is what the patch does: spi_nor_read_dummy_cycles() was reused
and enhanced few lines below where you've pointed out the 
"switch (nor->flash_read)" block should be move after the else block.

I think when I wrote the code I've chosen to move the definition of this
function instead of adding forward declarations of functions such as read_cr()
or write_sr_cr(), which are now called by micron_set_dummy_cycles().

>> -/*
>>   * Write status register 1 byte
>>   * Returns negative if error occurred.
>>   */
>> @@ -1012,6 +994,81 @@ static int set_quad_mode(struct spi_nor *nor, struct
>> flash_info *info) }
>>  }
>>
>> +static int micron_set_dummy_cycles(struct spi_nor *nor)
>> +{
>> +	int ret;
>> +	u8 val, mask;
>> +
>> +	/* read the Volatile Configuration Register (VCR) */
> 
> NIT: If this is a sentence, start it with capital letter and end it with 
> fullstop :)
> 

done for the next version

>> +	ret = nor->read_reg(nor, SPINOR_OP_RD_VCR, &val, 1);
>> +	if (ret < 0) {
>> +		dev_err(nor->dev, "error %d reading VCR\n", ret);
>> +		return ret;
>> +	}
>> +
>> +	write_enable(nor);
>> +
>> +	/* update the number of dummy into the VCR */
> 
> DTTO
> 

done for the next version

>> +	mask = GENMASK(7, 4);
>> +	val &= ~mask;
>> +	val |= (nor->read_dummy << 4) & mask;
>> +	ret = nor->write_reg(nor, SPINOR_OP_WR_VCR, &val, 1, 0);
>> +	if (ret < 0) {
>> +		dev_err(nor->dev, "error while writing VCR register\n");
>> +		return ret;
>> +	}
>> +
>> +	ret = spi_nor_wait_till_ready(nor);
>> +	if (ret)
>> +		return ret;
>> +
>> +	return 0;
>> +}
>> +
>> +/*
>> + * Dummy Cycle calculation for different type of read.
>> + * It can be used to support more commands with
>> + * different dummy cycle requirements.
>> + */
>> +static int spi_nor_read_dummy_cycles(struct spi_nor *nor,
>> +				     const struct flash_info *info)
>> +{
>> +	struct device_node *np = nor->dev->of_node;
>> +	u32 num_dummy_cycles;
>> +
>> +	if (np && !of_property_read_u32(np, "m25p,num-dummy-cycles",
>> +					&num_dummy_cycles)) {
>> +		nor->read_dummy = num_dummy_cycles;
>> +
>> +		/*
>> +		 * This switch block might be moved after the if...then...else
>> +		 * statement but it was not tested with all Spansion or Micron
>> +		 * memories.
>> +		 * Now the "m25p,num-dummy-cycles" property needs to be
>> +		 * explicitly set in the device tree so the switch statement is
>> +		 * executed. This should avoid unwanted side effects and keep
>> +		 * backward compatibility.
>> +		 */
>> +		switch (JEDEC_MFR(info)) {
>> +		case CFI_MFR_ST:
>> +			return micron_set_dummy_cycles(nor);
>> +		default:
> 
> If you do have m25p,num-dummy-cycles set for non-micron flash, you have a 
> problem here I believe.
> 
>> +			break;
>> +		}
>> +	} else {
> 
> The solution would be to drop this else {} bit here, so that if you fail in
> the DT-based configuration, you fall back to this old behavior. What do you 
> think please ? :)
> 

Good idea!
I also add a trace for the default case of "switch (JEDEC_MFR(info))":

dev_warn(dev, "can't set the number of dummy cycles\n");

So the user is notified that the driver could not use the value of
"m25p,num-dummy-cycles" from the DT before falling back to the legacy
code.

>> +		switch (nor->flash_read) {
>> +		case SPI_NOR_FAST:
>> +		case SPI_NOR_DUAL:
>> +		case SPI_NOR_QUAD:
>> +			nor->read_dummy = 8;
>> +		case SPI_NOR_NORMAL:
>> +			nor->read_dummy = 0;
>> +		}
>> +	}
>> +
>> +	return 0;
>> +}
> 
> [...]
> 

thanks for the review!

Best regards,

Cyrille


From vaibhav.hiremath at linaro.org  Mon Aug 24 09:47:13 2015
From: vaibhav.hiremath at linaro.org (Vaibhav Hiremath)
Date: Mon, 24 Aug 2015 22:17:13 +0530
Subject: [PATCH-v6 5/6] mfd: 88pm800: Set default interrupt clear method
In-Reply-To: <20150824155129.GA19409@x1>
References: <1436358392-15449-1-git-send-email-vaibhav.hiremath@linaro.org>
 <1436358392-15449-6-git-send-email-vaibhav.hiremath@linaro.org>
 <20150824135422.GF3237@x1> <55DB3627.2030503@linaro.org>
 <20150824155129.GA19409@x1>
Message-ID: <55DB4A91.9000702@linaro.org>



On Monday 24 August 2015 09:21 PM, Lee Jones wrote:
> On Mon, 24 Aug 2015, Vaibhav Hiremath wrote:
>
>>
>>
>> On Monday 24 August 2015 07:24 PM, Lee Jones wrote:
>>> On Wed, 08 Jul 2015, Vaibhav Hiremath wrote:
>>>
>>>> As per the spec, bit 1 (INT_CLEAR_MODE) of reg addr 0xe
>>>> (page 0) controls the method of clearing interrupt
>>>> status of 88pm800 family of devices;
>>>>
>>>>    0: clear on read
>>>>    1: clear on write
>>>>
>>>> If pdata is not coming from board file, then set the
>>>> default irq clear method to "irq clear on write"
>>>>
>>>> Also, as suggested by "Lee Jones" renaming variable field
>>>> to appropriate name and removed unnecessary field
>>>> pm80x_chip.irq_mode, using platform_data.irq_clr_method.
>>>>
>>>> Signed-off-by: Zhao Ye <zhaoy at marvell.com>
>>>> Signed-off-by: Vaibhav Hiremath <vaibhav.hiremath at linaro.org>
>>>> Reviewed-by: Krzysztof Kozlowski <k.kozlowski at samsung.com>
>>>> ---
>>>>   drivers/mfd/88pm800.c       | 15 ++++++++++-----
>>>>   include/linux/mfd/88pm80x.h |  9 +++++++--
>>>>   2 files changed, 17 insertions(+), 7 deletions(-)
>>>
>>> [...]
>>>
>>>> +#define PM800_WAKEUP2_INT_READ_CLEAR	(0 << 1)
>>>> +#define PM800_WAKEUP2_INT_WRITE_CLEAR	(1 << 1)
>>>
>>> Use BIT().
>>>
>>>> +/* Used by irq_clr_method */
>>>> +#define PM800_IRQ_CLR_ON_READ	0
>>>> +#define PM800_IRQ_CLR_ON_WRITE	1
>>>
>>>> -	int irq_mode;		/* Clear interrupt by read/write(0/1) */
>>>> +	bool irq_clr_method;		/* Clear interrupt by read/write(0/1) */
>>>
>>>> +	irq_clr_mode = pdata->irq_clr_method == PM800_IRQ_CLR_ON_WRITE ?
>>>> +		PM800_WAKEUP2_INT_WRITE_CLEAR : PM800_WAKEUP2_INT_READ_CLEAR;
>>>> +	ret = regmap_update_bits(map, PM800_WAKEUP2, mask, irq_clr_mode);
>>>
>>> This is pretty convoluted.
>>>
>>> For starters you're abusing the 'bool' type here.  Bool is either
>>> 'true' or 'false', so at the very least you should rename
>>> 'irq_clr_method' to 'irq_clr_on_write'.
>>>
>>> Then you can do:
>>>
>>> 	irq_clr_mode = pdata->irq_clr_on_write ?
>>> 		PM800_WAKEUP2_INT_WRITE_CLEAR : PM800_WAKEUP2_INT_READ_CLEAR;
>>>
>>
>> We have discussed on this, and went back-n-forth.
>> I think if I remember correctly, one of the version was using
>> true/false then we decided to rename it to relevant macro.
>>
>> If I am not wrong V4 version of this series is exactly same as what you
>> are referring to.
>
> Right.  I made a few suggestions which vary in usefulness depending on
> how you plan to implement all of this.  Unfortunately this is a bit of
> a bastardised version where some of it make sense and other parts
> could do with some improvement.
>

This so called "basterdised version could have been avoided :)

V2 version itself was clean and ready. It just got dragged into
multiple iterations.

>>> However, what I suggest you really do is share
>>> PM800_WAKEUP2_INT_{READ,WRITE}_CLEAR with platform data and just pass
>>> the value through directly.
>>>
>>
>> I think we discussed about this also, and the reason I recall here is,
>>
>> we may need to control this from DT in the future so we decided to keep
>> it boolean in platform_data and have simple check before writing to
>> register.
>>
>> And I think that was also another reason we introduced
>>
>> /* Used by irq_clr_method */
>> #define PM800_IRQ_CLR_ON_READ   0
>> #define PM800_IRQ_CLR_ON_WRITE  1
>
> I think these are still required.  So it would look like this:
>

NO. I think you are confused here,
We have two different macros playing around here,


+/* Used by irq_clr_method */
+#define PM800_IRQ_CLR_ON_READ	0
+#define PM800_IRQ_CLR_ON_WRITE	1

/* Used to write to register */
+#define PM800_WAKEUP2_INT_READ_CLEAR		(0 << 1)
+#define PM800_WAKEUP2_INT_WRITE_CLEAR		(1 << 1)



> == Platform data ==
>
> struct pdata {
>    bool clear_irq_on_write;
> };
>
> pdata->clear_irq_on_write = PM800_IRQ_CLR_ON_{READ,WRITE};
>
> == Driver ==
>
> irq_clr_mode = pdata->clear_irq_on_write ?
>                   PM800_WAKEUP2_INT_WRITE_CLEAR : PM800_WAKEUP2_INT_READ_CLEAR;
> regmap_update_bits(map, PM800_WAKEUP2, mask, irq_clr_mode);
>

Please check V2, which is exactly same as above.

https://patchwork.kernel.org/patch/6627781/


If you are OK with it, I will spin another version and submit it.

Thanks,
Vaibhav


From marex at denx.de  Mon Aug 24 09:48:50 2015
From: marex at denx.de (Marek Vasut)
Date: Mon, 24 Aug 2015 18:48:50 +0200
Subject: [PATCH linux-next v4 3/5] mtd: spi-nor: allow to tune the number
 of dummy cycles
In-Reply-To: <55DB4986.1000207@atmel.com>
References: <cover.1440410236.git.cyrille.pitchen@atmel.com>
 <201508241248.17466.marex@denx.de> <55DB4986.1000207@atmel.com>
Message-ID: <201508241848.50974.marex@denx.de>

On Monday, August 24, 2015 at 06:42:46 PM, Cyrille Pitchen wrote:
> Hi Marek,

Hi!

[...]

> >> - * Dummy Cycle calculation for different type of read.
> >> - * It can be used to support more commands with
> >> - * different dummy cycle requirements.
> >> - */
> >> -static inline int spi_nor_read_dummy_cycles(struct spi_nor *nor)
> >> -{
> >> -	switch (nor->flash_read) {
> >> -	case SPI_NOR_FAST:
> >> -	case SPI_NOR_DUAL:
> >> -	case SPI_NOR_QUAD:
> >> -		return 8;
> >> -	case SPI_NOR_NORMAL:
> >> -		return 0;
> >> -	}
> >> -	return 0;
> >> -}
> > 
> > You can probably just soup up this function so that it sets the
> > nor->read_dummy, no ?
> 
> Actually, this is what the patch does: spi_nor_read_dummy_cycles() was
> reused and enhanced few lines below where you've pointed out the
> "switch (nor->flash_read)" block should be move after the else block.

You know what? I'll go get some sleep, coffee doesn't cut it anymore :)

> I think when I wrote the code I've chosen to move the definition of this
> function instead of adding forward declarations of functions such as
> read_cr() or write_sr_cr(), which are now called by
> micron_set_dummy_cycles().

Yep, that's all right, sorry for the confusion.

> >> -/*
> >> 
> >>   * Write status register 1 byte
> >>   * Returns negative if error occurred.
> >>   */
> >> 
> >> @@ -1012,6 +994,81 @@ static int set_quad_mode(struct spi_nor *nor,
> >> struct flash_info *info) }
> >> 
> >>  }

[...]

> >> +/*
> >> + * Dummy Cycle calculation for different type of read.
> >> + * It can be used to support more commands with
> >> + * different dummy cycle requirements.
> >> + */
> >> +static int spi_nor_read_dummy_cycles(struct spi_nor *nor,
> >> +				     const struct flash_info *info)
> >> +{
> >> +	struct device_node *np = nor->dev->of_node;
> >> +	u32 num_dummy_cycles;
> >> +
> >> +	if (np && !of_property_read_u32(np, "m25p,num-dummy-cycles",
> >> +					&num_dummy_cycles)) {
> >> +		nor->read_dummy = num_dummy_cycles;
> >> +
> >> +		/*
> >> +		 * This switch block might be moved after the if...then...else
> >> +		 * statement but it was not tested with all Spansion or Micron
> >> +		 * memories.
> >> +		 * Now the "m25p,num-dummy-cycles" property needs to be
> >> +		 * explicitly set in the device tree so the switch statement is
> >> +		 * executed. This should avoid unwanted side effects and keep
> >> +		 * backward compatibility.
> >> +		 */
> >> +		switch (JEDEC_MFR(info)) {
> >> +		case CFI_MFR_ST:
> >> +			return micron_set_dummy_cycles(nor);
> > 
> >> +		default:
> > If you do have m25p,num-dummy-cycles set for non-micron flash, you have a
> > problem here I believe.
> > 
> >> +			break;
> >> +		}
> >> +	} else {
> > 
> > The solution would be to drop this else {} bit here, so that if you fail
> > in the DT-based configuration, you fall back to this old behavior. What
> > do you think please ? :)
> 
> Good idea!
> I also add a trace for the default case of "switch (JEDEC_MFR(info))":
> 
> dev_warn(dev, "can't set the number of dummy cycles\n");

Maybe change this to "setting the number of dummy cycles not supported by chip, 
ignoring" or something, to be explicit about the fallback and that this is not
supported by the chip. But this is just an idea, feel free to ignore it.

> So the user is notified that the driver could not use the value of
> "m25p,num-dummy-cycles" from the DT before falling back to the legacy
> code.

Yup.

> >> +		switch (nor->flash_read) {
> >> +		case SPI_NOR_FAST:
> >> +		case SPI_NOR_DUAL:
> >> +		case SPI_NOR_QUAD:
> >> +			nor->read_dummy = 8;
> >> +		case SPI_NOR_NORMAL:
> >> +			nor->read_dummy = 0;
> >> +		}
> >> +	}
> >> +
> >> +	return 0;
> >> +}
> > 
> > [...]
> 
> thanks for the review!

Im glad it helped ;-)


From heiko at sntech.de  Mon Aug 24 10:04:07 2015
From: heiko at sntech.de (Heiko Stuebner)
Date: Mon, 24 Aug 2015 19:04:07 +0200
Subject: [PATCH v2 2/3] ARM: dts: rockchip: correct regulator PM properties
In-Reply-To: <1440022721-73712-2-git-send-email-briannorris@chromium.org>
References: <1440022721-73712-1-git-send-email-briannorris@chromium.org>
 <1440022721-73712-2-git-send-email-briannorris@chromium.org>
Message-ID: <6403780.zCWLY3Bai8@phil>

Am Mittwoch, 19. August 2015, 15:18:40 schrieb Brian Norris:
> This DTS file was submitted with non-upstream bindings. I happened
> across this while reviewing the jaq DTS.
> 
> Signed-off-by: Brian Norris <briannorris at chromium.org>
> Cc: Alexandru M Stan <amstan at chromium.org>
> Cc: Douglas Anderson <dianders at chromium.org>
> ---

applied to my dts branch for 4.3


From heiko at sntech.de  Mon Aug 24 10:04:29 2015
From: heiko at sntech.de (Heiko Stuebner)
Date: Mon, 24 Aug 2015 19:04:29 +0200
Subject: [PATCH v2 3/3] ARM: dts: rockchip: correct regulator power states
 for suspend
In-Reply-To: <1440022721-73712-3-git-send-email-briannorris@chromium.org>
References: <1440022721-73712-1-git-send-email-briannorris@chromium.org>
 <1440022721-73712-3-git-send-email-briannorris@chromium.org>
Message-ID: <2616064.1Av4bHmkNF@phil>

Am Mittwoch, 19. August 2015, 15:18:41 schrieb Brian Norris:
> When getting translated from a downstream device tree that used slightly
> different DT bindings, these regulators got labeled with the
> "on-in-suspend" state, when they were actually supposed to be turned off
> for S3 suspend. This was harmless, but not intentional, AFAICT.
> 
> Let's turn them off to get the optimal power state.
> 
> Signed-off-by: Brian Norris <briannorris at chromium.org>
> Cc: Alexandru M Stan <amstan at chromium.org>
> Cc: Douglas Anderson <dianders at chromium.org>
> ---

applied to my dts branch for 4.3


From cyrille.pitchen at atmel.com  Mon Aug 24 10:04:38 2015
From: cyrille.pitchen at atmel.com (Cyrille Pitchen)
Date: Mon, 24 Aug 2015 19:04:38 +0200
Subject: [PATCH linux-next v4 5/5] mtd: atmel-quadspi: add driver for
 Atmel QSPI controller
In-Reply-To: <201508241303.52066.marex@denx.de>
References: <cover.1440410236.git.cyrille.pitchen@atmel.com>
 <bf368fc101f38db231131b69eff0863210f2b01c.1440410236.git.cyrille.pitchen@atmel.com>
 <201508241303.52066.marex@denx.de>
Message-ID: <55DB4EA6.9090807@atmel.com>

Hi Marek,

Le 24/08/2015 13:03, Marek Vasut a ?crit :
> On Monday, August 24, 2015 at 12:14:00 PM, Cyrille Pitchen wrote:
>> This driver add support to the new Atmel QSPI controller embedded into
>> sama5d2x SoCs. It expects a NOR memory to be connected to the QSPI
>> controller.
>>
>> Signed-off-by: Cyrille Pitchen <cyrille.pitchen at atmel.com>
>> Acked-by: Nicolas Ferre <nicolas.ferre at atmel.com>
> 
> Hi,
> 
> [...]
> 
>> +/* Register access macros */
> 
> These are functions, not macros :)
> 
> btw is there any reason for these ? I'd say, just put the read*() and
> write*() functions directly into the code and be done with it, it is
> much less confusing.
> 
> Also, why do you use the _relaxed() versions of the functions ?
> 
>> +static inline u32 qspi_readl(struct atmel_qspi *aq, u32 reg)
>> +{
>> +	return readl_relaxed(aq->regs + reg);
>> +}
>> +
>> +static inline void qspi_writel(struct atmel_qspi *aq, u32 reg, u32 value)
>> +{
>> +	writel_relaxed(value, aq->regs + reg);
>> +}
>> +
>> +static inline u16 qspi_readw(struct atmel_qspi *aq, u32 reg)
>> +{
>> +	return readw_relaxed(aq->regs + reg);
>> +}
>> +
>> +static inline void qspi_writew(struct atmel_qspi *aq, u32 reg, u16 value)
>> +{
>> +	writew_relaxed(value, aq->regs + reg);
>> +}
>> +
>> +static inline u8 qspi_readb(struct atmel_qspi *aq, u32 reg)
>> +{
>> +	return readb_relaxed(aq->regs + reg);
>> +}
>> +
>> +static inline void qspi_writeb(struct atmel_qspi *aq, u32 reg, u8 value)
>> +{
>> +	writeb_relaxed(value, aq->regs + reg);
>> +}
> 
> [...]
> 
>> +static int atmel_qspi_run_command(struct atmel_qspi *aq,
>> +				  const struct atmel_qspi_command *cmd)
>> +{
>> +	u32 iar, icr, ifr, sr;
>> +	int err = 0;
>> +
>> +	iar = 0;
>> +	icr = 0;
>> +	ifr = aq->ifr_width | cmd->ifr_tfrtyp;
>> +
>> +	/* Compute instruction parameters */
>> +	if (cmd->enable.bits.instruction) {
>> +		icr |= QSPI_ICR_INST(cmd->instruction);
>> +		ifr |= QSPI_IFR_INSTEN;
>> +	}
>> +
>> +	/* Compute address parameters */
>> +	switch (cmd->enable.bits.address) {
>> +	case 4:
>> +		ifr |= QSPI_IFR_ADDRL;
>> +		/*break;*/ /* fallback to the 24bit address case */
> 
> What's this commented out bit of code for ? :-)

I just wanted to stress out there was no missing "break;".
I've reworded the comment to:
/* No "break" on purpose: fallback to the 24bit address case. */

> 
>> +	case 3:
>> +		iar = (cmd->enable.bits.data) ? 0 : cmd->address;
>> +		ifr |= QSPI_IFR_ADDREN;
>> +		break;
>> +	case 0:
>> +		break;
>> +	default:
>> +		return -EINVAL;
>> +	}
> 
> [...]
> 
>> +no_data:
>> +	/* Poll INSTRuction End status */
>> +	sr = qspi_readl(aq, QSPI_SR);
>> +	if (sr & QSPI_SR_INSTRE)
>> +		return err;
>> +
>> +	/* Wait for INSTRuction End interrupt */
>> +	init_completion(&aq->completion);
> 
> You should use reinit_completion() in the code. init_completion()
> should be used only in the probe() function and nowhere else.

Alright. In the next version I'll rename the "completion" member of
struct atmel_qspi into "cmd_completion". Also I'll add another dma_completion
member in this very same structure to replace the local
"struct completion completion" in atmel_qspi_run_dma_transfer().

Then I'll call init_completion() on both cmd_completion and dma_completion only
from atmel_qspi_probe() and reinit_completion() elsewhere.

> 
>> +	aq->pending = 0;
>> +	qspi_writel(aq, QSPI_IER, QSPI_SR_INSTRE);
>> +	if (!wait_for_completion_timeout(&aq->completion,
>> +					 msecs_to_jiffies(1000)))
>> +		err = -ETIMEDOUT;
>> +	qspi_writel(aq, QSPI_IDR, QSPI_SR_INSTRE);
>> +
>> +	return err;
>> +}
> 
> [...]
> 
> Hope this helps :)
> 

Indeed, it does! I still work on the next version of this series to take all your
comments into account.

Best regards,

Cyrille


From boris.brezillon at free-electrons.com  Mon Aug 24 10:10:19 2015
From: boris.brezillon at free-electrons.com (Boris Brezillon)
Date: Mon, 24 Aug 2015 19:10:19 +0200
Subject: [PATCH] mtd: nand: pass page number to ecc->write_xxx() methods
Message-ID: <1440436219-31625-1-git-send-email-boris.brezillon@free-electrons.com>

The ->read_xxx() methods are all passed the page number the NAND controller
is supposed to read, but ->write_xxx() do not have such a parameter.

This is a problem if we want to properly implement data
scrambling/randomization in order to mitigate MLC sensibility to repeated
pattern: to prevent bitflips in adjacent pages in the same block we need
to avoid repeating the same pattern at the same offset in those pages,
hence the randomizer/scrambler engine need to be passed the page value
in order to adapt its seed accordingly.

Moreover, adding the page parameter the ->write_xxx() methods add some
consistency to the current model.

Signed-off-by: Boris Brezillon <boris.brezillon at free-electrons.com>
CC: Josh Wu <josh.wu at atmel.com>
CC: Ezequiel Garcia <ezequiel.garcia at free-electrons.com>
CC: Maxime Ripard <maxime.ripard at free-electrons.com>
CC: Greg Kroah-Hartman <gregkh at linuxfoundation.org>
CC: Huang Shijie <shijie.huang at intel.com>
CC: Bryan Wu <bryan.wu at analog.com>
CC: devel at driverdev.osuosl.org
CC: linux-arm-kernel at lists.infradead.org
CC: linux-kernel at vger.kernel.org

---
 drivers/mtd/nand/atmel_nand.c                 |  6 ++++--
 drivers/mtd/nand/bf5xx_nand.c                 |  3 ++-
 drivers/mtd/nand/brcmnand/brcmnand.c          |  4 ++--
 drivers/mtd/nand/cafe_nand.c                  |  3 ++-
 drivers/mtd/nand/denali.c                     |  5 +++--
 drivers/mtd/nand/docg4.c                      |  4 ++--
 drivers/mtd/nand/fsl_elbc_nand.c              |  4 ++--
 drivers/mtd/nand/fsl_ifc_nand.c               |  2 +-
 drivers/mtd/nand/gpmi-nand/gpmi-nand.c        |  6 +++---
 drivers/mtd/nand/hisi504_nand.c               |  3 ++-
 drivers/mtd/nand/lpc32xx_mlc.c                |  3 ++-
 drivers/mtd/nand/lpc32xx_slc.c                |  5 +++--
 drivers/mtd/nand/nand_base.c                  | 31 ++++++++++++++++++---------
 drivers/mtd/nand/omap2.c                      |  3 ++-
 drivers/mtd/nand/pxa3xx_nand.c                |  3 ++-
 drivers/mtd/nand/sh_flctl.c                   |  3 ++-
 drivers/mtd/nand/sunxi_nand.c                 |  5 +++--
 drivers/staging/mt29f_spinand/mt29f_spinand.c |  3 ++-
 include/linux/mtd/nand.h                      |  6 +++---
 19 files changed, 63 insertions(+), 39 deletions(-)

diff --git a/drivers/mtd/nand/atmel_nand.c b/drivers/mtd/nand/atmel_nand.c
index 46010bd..d0f50c9 100644
--- a/drivers/mtd/nand/atmel_nand.c
+++ b/drivers/mtd/nand/atmel_nand.c
@@ -954,7 +954,8 @@ static int atmel_nand_pmecc_read_page(struct mtd_info *mtd,
 }
 
 static int atmel_nand_pmecc_write_page(struct mtd_info *mtd,
-		struct nand_chip *chip, const uint8_t *buf, int oob_required)
+		struct nand_chip *chip, const uint8_t *buf, int oob_required,
+		int page)
 {
 	struct atmel_nand_host *host = chip->priv;
 	uint32_t *eccpos = chip->ecc.layout->eccpos;
@@ -2005,7 +2006,8 @@ static int nfc_sram_write_page(struct mtd_info *mtd, struct nand_chip *chip,
 
 	if (likely(!raw))
 		/* Need to write ecc into oob */
-		status = chip->ecc.write_page(mtd, chip, buf, oob_required);
+		status = chip->ecc.write_page(mtd, chip, buf, oob_required,
+					      page);
 
 	if (status < 0)
 		return status;
diff --git a/drivers/mtd/nand/bf5xx_nand.c b/drivers/mtd/nand/bf5xx_nand.c
index 4d8d4ba..17b3727 100644
--- a/drivers/mtd/nand/bf5xx_nand.c
+++ b/drivers/mtd/nand/bf5xx_nand.c
@@ -566,7 +566,8 @@ static int bf5xx_nand_read_page_raw(struct mtd_info *mtd, struct nand_chip *chip
 }
 
 static int bf5xx_nand_write_page_raw(struct mtd_info *mtd,
-		struct nand_chip *chip,	const uint8_t *buf, int oob_required)
+		struct nand_chip *chip,	const uint8_t *buf, int oob_required,
+		int page)
 {
 	bf5xx_nand_write_buf(mtd, buf, mtd->writesize);
 	bf5xx_nand_write_buf(mtd, chip->oob_poi, mtd->oobsize);
diff --git a/drivers/mtd/nand/brcmnand/brcmnand.c b/drivers/mtd/nand/brcmnand/brcmnand.c
index fddb795..9a4e345 100644
--- a/drivers/mtd/nand/brcmnand/brcmnand.c
+++ b/drivers/mtd/nand/brcmnand/brcmnand.c
@@ -1606,7 +1606,7 @@ out:
 }
 
 static int brcmnand_write_page(struct mtd_info *mtd, struct nand_chip *chip,
-			       const uint8_t *buf, int oob_required)
+			       const uint8_t *buf, int oob_required, int page)
 {
 	struct brcmnand_host *host = chip->priv;
 	void *oob = oob_required ? chip->oob_poi : NULL;
@@ -1617,7 +1617,7 @@ static int brcmnand_write_page(struct mtd_info *mtd, struct nand_chip *chip,
 
 static int brcmnand_write_page_raw(struct mtd_info *mtd,
 				   struct nand_chip *chip, const uint8_t *buf,
-				   int oob_required)
+				   int oob_required, int page)
 {
 	struct brcmnand_host *host = chip->priv;
 	void *oob = oob_required ? chip->oob_poi : NULL;
diff --git a/drivers/mtd/nand/cafe_nand.c b/drivers/mtd/nand/cafe_nand.c
index 9a0f45f..d6854be 100644
--- a/drivers/mtd/nand/cafe_nand.c
+++ b/drivers/mtd/nand/cafe_nand.c
@@ -516,7 +516,8 @@ static struct nand_bbt_descr cafe_bbt_mirror_descr_512 = {
 
 static int cafe_nand_write_page_lowlevel(struct mtd_info *mtd,
 					  struct nand_chip *chip,
-					  const uint8_t *buf, int oob_required)
+					  const uint8_t *buf, int oob_required,
+					  int page)
 {
 	struct cafe_priv *cafe = mtd->priv;
 
diff --git a/drivers/mtd/nand/denali.c b/drivers/mtd/nand/denali.c
index 870c7fc..88aadc4 100644
--- a/drivers/mtd/nand/denali.c
+++ b/drivers/mtd/nand/denali.c
@@ -1105,7 +1105,7 @@ static int write_page(struct mtd_info *mtd, struct nand_chip *chip,
  * by write_page above.
  */
 static int denali_write_page(struct mtd_info *mtd, struct nand_chip *chip,
-				const uint8_t *buf, int oob_required)
+				const uint8_t *buf, int oob_required, int page)
 {
 	/*
 	 * for regular page writes, we let HW handle all the ECC
@@ -1120,7 +1120,8 @@ static int denali_write_page(struct mtd_info *mtd, struct nand_chip *chip,
  * write_page() function above.
  */
 static int denali_write_page_raw(struct mtd_info *mtd, struct nand_chip *chip,
-					const uint8_t *buf, int oob_required)
+				 const uint8_t *buf, int oob_required,
+				 int page)
 {
 	/*
 	 * for raw page writes, we want to disable ECC and simply write
diff --git a/drivers/mtd/nand/docg4.c b/drivers/mtd/nand/docg4.c
index e5d7bca..aaaf3d2 100644
--- a/drivers/mtd/nand/docg4.c
+++ b/drivers/mtd/nand/docg4.c
@@ -977,13 +977,13 @@ static int write_page(struct mtd_info *mtd, struct nand_chip *nand,
 }
 
 static int docg4_write_page_raw(struct mtd_info *mtd, struct nand_chip *nand,
-				 const uint8_t *buf, int oob_required)
+				const uint8_t *buf, int oob_required, int page)
 {
 	return write_page(mtd, nand, buf, false);
 }
 
 static int docg4_write_page(struct mtd_info *mtd, struct nand_chip *nand,
-			     const uint8_t *buf, int oob_required)
+			     const uint8_t *buf, int oob_required, int page)
 {
 	return write_page(mtd, nand, buf, true);
 }
diff --git a/drivers/mtd/nand/fsl_elbc_nand.c b/drivers/mtd/nand/fsl_elbc_nand.c
index 04b22fd..e1a8c95 100644
--- a/drivers/mtd/nand/fsl_elbc_nand.c
+++ b/drivers/mtd/nand/fsl_elbc_nand.c
@@ -715,7 +715,7 @@ static int fsl_elbc_read_page(struct mtd_info *mtd, struct nand_chip *chip,
  * waitfunc.
  */
 static int fsl_elbc_write_page(struct mtd_info *mtd, struct nand_chip *chip,
-				const uint8_t *buf, int oob_required)
+				const uint8_t *buf, int oob_required, int page)
 {
 	fsl_elbc_write_buf(mtd, buf, mtd->writesize);
 	fsl_elbc_write_buf(mtd, chip->oob_poi, mtd->oobsize);
@@ -728,7 +728,7 @@ static int fsl_elbc_write_page(struct mtd_info *mtd, struct nand_chip *chip,
  */
 static int fsl_elbc_write_subpage(struct mtd_info *mtd, struct nand_chip *chip,
 				uint32_t offset, uint32_t data_len,
-				const uint8_t *buf, int oob_required)
+				const uint8_t *buf, int oob_required, int page)
 {
 	fsl_elbc_write_buf(mtd, buf, mtd->writesize);
 	fsl_elbc_write_buf(mtd, chip->oob_poi, mtd->oobsize);
diff --git a/drivers/mtd/nand/fsl_ifc_nand.c b/drivers/mtd/nand/fsl_ifc_nand.c
index 51394e5..795b8a9 100644
--- a/drivers/mtd/nand/fsl_ifc_nand.c
+++ b/drivers/mtd/nand/fsl_ifc_nand.c
@@ -770,7 +770,7 @@ static int fsl_ifc_read_page(struct mtd_info *mtd, struct nand_chip *chip,
  * waitfunc.
  */
 static int fsl_ifc_write_page(struct mtd_info *mtd, struct nand_chip *chip,
-			       const uint8_t *buf, int oob_required)
+			       const uint8_t *buf, int oob_required, int page)
 {
 	fsl_ifc_write_buf(mtd, buf, mtd->writesize);
 	fsl_ifc_write_buf(mtd, chip->oob_poi, mtd->oobsize);
diff --git a/drivers/mtd/nand/gpmi-nand/gpmi-nand.c b/drivers/mtd/nand/gpmi-nand/gpmi-nand.c
index 1b8f350..b07499f 100644
--- a/drivers/mtd/nand/gpmi-nand/gpmi-nand.c
+++ b/drivers/mtd/nand/gpmi-nand/gpmi-nand.c
@@ -1160,7 +1160,7 @@ static int gpmi_ecc_read_subpage(struct mtd_info *mtd, struct nand_chip *chip,
 }
 
 static int gpmi_ecc_write_page(struct mtd_info *mtd, struct nand_chip *chip,
-				const uint8_t *buf, int oob_required)
+				const uint8_t *buf, int oob_required, int page)
 {
 	struct gpmi_nand_data *this = chip->priv;
 	struct bch_geometry *nfc_geo = &this->bch_geometry;
@@ -1446,7 +1446,7 @@ static int gpmi_ecc_read_page_raw(struct mtd_info *mtd,
 static int gpmi_ecc_write_page_raw(struct mtd_info *mtd,
 				   struct nand_chip *chip,
 				   const uint8_t *buf,
-				   int oob_required)
+				   int oob_required, int page)
 {
 	struct gpmi_nand_data *this = chip->priv;
 	struct bch_geometry *nfc_geo = &this->bch_geometry;
@@ -1717,7 +1717,7 @@ static int mx23_write_transcription_stamp(struct gpmi_nand_data *this)
 		/* Write the first page of the current stride. */
 		dev_dbg(dev, "Writing an NCB fingerprint in page 0x%x\n", page);
 		chip->cmdfunc(mtd, NAND_CMD_SEQIN, 0x00, page);
-		chip->ecc.write_page_raw(mtd, chip, buffer, 0);
+		chip->ecc.write_page_raw(mtd, chip, buffer, 0, page);
 		chip->cmdfunc(mtd, NAND_CMD_PAGEPROG, -1, -1);
 
 		/* Wait for the write to finish. */
diff --git a/drivers/mtd/nand/hisi504_nand.c b/drivers/mtd/nand/hisi504_nand.c
index 8dcc7b8..04b9c3d 100644
--- a/drivers/mtd/nand/hisi504_nand.c
+++ b/drivers/mtd/nand/hisi504_nand.c
@@ -590,7 +590,8 @@ static int hisi_nand_read_oob(struct mtd_info *mtd, struct nand_chip *chip,
 }
 
 static int hisi_nand_write_page_hwecc(struct mtd_info *mtd,
-		struct nand_chip *chip, const uint8_t *buf, int oob_required)
+		struct nand_chip *chip, const uint8_t *buf, int oob_required,
+		int page)
 {
 	chip->write_buf(mtd, buf, mtd->writesize);
 	if (oob_required)
diff --git a/drivers/mtd/nand/lpc32xx_mlc.c b/drivers/mtd/nand/lpc32xx_mlc.c
index 79c3b78..510cb49 100644
--- a/drivers/mtd/nand/lpc32xx_mlc.c
+++ b/drivers/mtd/nand/lpc32xx_mlc.c
@@ -495,7 +495,8 @@ static int lpc32xx_read_page(struct mtd_info *mtd, struct nand_chip *chip,
 
 static int lpc32xx_write_page_lowlevel(struct mtd_info *mtd,
 				       struct nand_chip *chip,
-				       const uint8_t *buf, int oob_required)
+				       const uint8_t *buf, int oob_required,
+				       int page)
 {
 	struct lpc32xx_nand_host *host = chip->priv;
 	const uint8_t *oobbuf = chip->oob_poi;
diff --git a/drivers/mtd/nand/lpc32xx_slc.c b/drivers/mtd/nand/lpc32xx_slc.c
index abfec13..1d80995 100644
--- a/drivers/mtd/nand/lpc32xx_slc.c
+++ b/drivers/mtd/nand/lpc32xx_slc.c
@@ -660,7 +660,8 @@ static int lpc32xx_nand_read_page_raw_syndrome(struct mtd_info *mtd,
  */
 static int lpc32xx_nand_write_page_syndrome(struct mtd_info *mtd,
 					    struct nand_chip *chip,
-					    const uint8_t *buf, int oob_required)
+					    const uint8_t *buf,
+					    int oob_required, int page)
 {
 	struct lpc32xx_nand_host *host = chip->priv;
 	uint8_t *pb = chip->oob_poi + chip->ecc.layout->eccpos[0];
@@ -689,7 +690,7 @@ static int lpc32xx_nand_write_page_syndrome(struct mtd_info *mtd,
 static int lpc32xx_nand_write_page_raw_syndrome(struct mtd_info *mtd,
 						struct nand_chip *chip,
 						const uint8_t *buf,
-						int oob_required)
+						int oob_required, int page)
 {
 	/* Raw writes can just use the FIFO interface */
 	chip->write_buf(mtd, buf, chip->ecc.size * chip->ecc.steps);
diff --git a/drivers/mtd/nand/nand_base.c b/drivers/mtd/nand/nand_base.c
index e095d86..c09a2d2 100644
--- a/drivers/mtd/nand/nand_base.c
+++ b/drivers/mtd/nand/nand_base.c
@@ -2183,11 +2183,12 @@ out:
  * @chip: nand chip info structure
  * @buf: data buffer
  * @oob_required: must write chip->oob_poi to OOB
+ * @page: page number to write
  *
  * Not for syndrome calculating ECC controllers, which use a special oob layout.
  */
 static int nand_write_page_raw(struct mtd_info *mtd, struct nand_chip *chip,
-				const uint8_t *buf, int oob_required)
+			       const uint8_t *buf, int oob_required, int page)
 {
 	chip->write_buf(mtd, buf, mtd->writesize);
 	if (oob_required)
@@ -2202,12 +2203,14 @@ static int nand_write_page_raw(struct mtd_info *mtd, struct nand_chip *chip,
  * @chip: nand chip info structure
  * @buf: data buffer
  * @oob_required: must write chip->oob_poi to OOB
+ * @page: page number to write
  *
  * We need a special oob layout and handling even when ECC isn't checked.
  */
 static int nand_write_page_raw_syndrome(struct mtd_info *mtd,
 					struct nand_chip *chip,
-					const uint8_t *buf, int oob_required)
+					const uint8_t *buf, int oob_required,
+					int page)
 {
 	int eccsize = chip->ecc.size;
 	int eccbytes = chip->ecc.bytes;
@@ -2244,9 +2247,11 @@ static int nand_write_page_raw_syndrome(struct mtd_info *mtd,
  * @chip: nand chip info structure
  * @buf: data buffer
  * @oob_required: must write chip->oob_poi to OOB
+ * @page: page number to write
  */
 static int nand_write_page_swecc(struct mtd_info *mtd, struct nand_chip *chip,
-				  const uint8_t *buf, int oob_required)
+				 const uint8_t *buf, int oob_required,
+				 int page)
 {
 	int i, eccsize = chip->ecc.size;
 	int eccbytes = chip->ecc.bytes;
@@ -2262,7 +2267,7 @@ static int nand_write_page_swecc(struct mtd_info *mtd, struct nand_chip *chip,
 	for (i = 0; i < chip->ecc.total; i++)
 		chip->oob_poi[eccpos[i]] = ecc_calc[i];
 
-	return chip->ecc.write_page_raw(mtd, chip, buf, 1);
+	return chip->ecc.write_page_raw(mtd, chip, buf, 1, page);
 }
 
 /**
@@ -2271,9 +2276,11 @@ static int nand_write_page_swecc(struct mtd_info *mtd, struct nand_chip *chip,
  * @chip: nand chip info structure
  * @buf: data buffer
  * @oob_required: must write chip->oob_poi to OOB
+ * @page: page number to write
  */
 static int nand_write_page_hwecc(struct mtd_info *mtd, struct nand_chip *chip,
-				  const uint8_t *buf, int oob_required)
+				  const uint8_t *buf, int oob_required,
+				  int page)
 {
 	int i, eccsize = chip->ecc.size;
 	int eccbytes = chip->ecc.bytes;
@@ -2305,11 +2312,12 @@ static int nand_write_page_hwecc(struct mtd_info *mtd, struct nand_chip *chip,
  * @data_len:	data length
  * @buf:	data buffer
  * @oob_required: must write chip->oob_poi to OOB
+ * @page: page number to write
  */
 static int nand_write_subpage_hwecc(struct mtd_info *mtd,
 				struct nand_chip *chip, uint32_t offset,
 				uint32_t data_len, const uint8_t *buf,
-				int oob_required)
+				int oob_required, int page)
 {
 	uint8_t *oob_buf  = chip->oob_poi;
 	uint8_t *ecc_calc = chip->buffers->ecccalc;
@@ -2364,13 +2372,15 @@ static int nand_write_subpage_hwecc(struct mtd_info *mtd,
  * @chip: nand chip info structure
  * @buf: data buffer
  * @oob_required: must write chip->oob_poi to OOB
+ * @page: page number to write
  *
  * The hw generator calculates the error syndrome automatically. Therefore we
  * need a special oob layout and handling.
  */
 static int nand_write_page_syndrome(struct mtd_info *mtd,
 				    struct nand_chip *chip,
-				    const uint8_t *buf, int oob_required)
+				    const uint8_t *buf, int oob_required,
+				    int page)
 {
 	int i, eccsize = chip->ecc.size;
 	int eccbytes = chip->ecc.bytes;
@@ -2434,12 +2444,13 @@ static int nand_write_page(struct mtd_info *mtd, struct nand_chip *chip,
 
 	if (unlikely(raw))
 		status = chip->ecc.write_page_raw(mtd, chip, buf,
-							oob_required);
+						  oob_required, page);
 	else if (subpage)
 		status = chip->ecc.write_subpage(mtd, chip, offset, data_len,
-							 buf, oob_required);
+						 buf, oob_required, page);
 	else
-		status = chip->ecc.write_page(mtd, chip, buf, oob_required);
+		status = chip->ecc.write_page(mtd, chip, buf, oob_required,
+					      page);
 
 	if (status < 0)
 		return status;
diff --git a/drivers/mtd/nand/omap2.c b/drivers/mtd/nand/omap2.c
index 60fa899..b85696f 100644
--- a/drivers/mtd/nand/omap2.c
+++ b/drivers/mtd/nand/omap2.c
@@ -1500,11 +1500,12 @@ static int omap_elm_correct_data(struct mtd_info *mtd, u_char *data,
  * @chip:		nand chip info structure
  * @buf:		data buffer
  * @oob_required:	must write chip->oob_poi to OOB
+ * @page:		page
  *
  * Custom write page method evolved to support multi sector writing in one shot
  */
 static int omap_write_page_bch(struct mtd_info *mtd, struct nand_chip *chip,
-				  const uint8_t *buf, int oob_required)
+			       const uint8_t *buf, int oob_required, int page)
 {
 	int i;
 	uint8_t *ecc_calc = chip->buffers->ecccalc;
diff --git a/drivers/mtd/nand/pxa3xx_nand.c b/drivers/mtd/nand/pxa3xx_nand.c
index 1259cc5..5f531b1 100644
--- a/drivers/mtd/nand/pxa3xx_nand.c
+++ b/drivers/mtd/nand/pxa3xx_nand.c
@@ -1116,7 +1116,8 @@ static void nand_cmdfunc_extended(struct mtd_info *mtd,
 }
 
 static int pxa3xx_nand_write_page_hwecc(struct mtd_info *mtd,
-		struct nand_chip *chip, const uint8_t *buf, int oob_required)
+		struct nand_chip *chip, const uint8_t *buf, int oob_required,
+		int page)
 {
 	chip->write_buf(mtd, buf, mtd->writesize);
 	chip->write_buf(mtd, chip->oob_poi, mtd->oobsize);
diff --git a/drivers/mtd/nand/sh_flctl.c b/drivers/mtd/nand/sh_flctl.c
index c3ce81c..f6c059d 100644
--- a/drivers/mtd/nand/sh_flctl.c
+++ b/drivers/mtd/nand/sh_flctl.c
@@ -569,7 +569,8 @@ static int flctl_read_page_hwecc(struct mtd_info *mtd, struct nand_chip *chip,
 }
 
 static int flctl_write_page_hwecc(struct mtd_info *mtd, struct nand_chip *chip,
-				   const uint8_t *buf, int oob_required)
+				  const uint8_t *buf, int oob_required,
+				  int page)
 {
 	chip->write_buf(mtd, buf, mtd->writesize);
 	chip->write_buf(mtd, chip->oob_poi, mtd->oobsize);
diff --git a/drivers/mtd/nand/sunxi_nand.c b/drivers/mtd/nand/sunxi_nand.c
index 4a39ac5..f9861e7 100644
--- a/drivers/mtd/nand/sunxi_nand.c
+++ b/drivers/mtd/nand/sunxi_nand.c
@@ -619,7 +619,8 @@ static int sunxi_nfc_hw_ecc_read_page(struct mtd_info *mtd,
 
 static int sunxi_nfc_hw_ecc_write_page(struct mtd_info *mtd,
 				       struct nand_chip *chip,
-				       const uint8_t *buf, int oob_required)
+				       const uint8_t *buf, int oob_required,
+				       int page)
 {
 	struct sunxi_nfc *nfc = to_sunxi_nfc(chip->controller);
 	struct nand_ecc_ctrl *ecc = &chip->ecc;
@@ -767,7 +768,7 @@ static int sunxi_nfc_hw_syndrome_ecc_read_page(struct mtd_info *mtd,
 static int sunxi_nfc_hw_syndrome_ecc_write_page(struct mtd_info *mtd,
 						struct nand_chip *chip,
 						const uint8_t *buf,
-						int oob_required)
+						int oob_required, int page)
 {
 	struct sunxi_nfc *nfc = to_sunxi_nfc(chip->controller);
 	struct nand_ecc_ctrl *ecc = &chip->ecc;
diff --git a/drivers/staging/mt29f_spinand/mt29f_spinand.c b/drivers/staging/mt29f_spinand/mt29f_spinand.c
index 7285c64..11508d0 100644
--- a/drivers/staging/mt29f_spinand/mt29f_spinand.c
+++ b/drivers/staging/mt29f_spinand/mt29f_spinand.c
@@ -612,7 +612,8 @@ static int spinand_erase_block(struct spi_device *spi_nand, u16 block_id)
 
 #ifdef CONFIG_MTD_SPINAND_ONDIEECC
 static int spinand_write_page_hwecc(struct mtd_info *mtd,
-		struct nand_chip *chip, const uint8_t *buf, int oob_required)
+		struct nand_chip *chip, const uint8_t *buf, int oob_required,
+		int page)
 {
 	const uint8_t *p = buf;
 	int eccsize = chip->ecc.size;
diff --git a/include/linux/mtd/nand.h b/include/linux/mtd/nand.h
index b307075..371afd4 100644
--- a/include/linux/mtd/nand.h
+++ b/include/linux/mtd/nand.h
@@ -504,16 +504,16 @@ struct nand_ecc_ctrl {
 	int (*read_page_raw)(struct mtd_info *mtd, struct nand_chip *chip,
 			uint8_t *buf, int oob_required, int page);
 	int (*write_page_raw)(struct mtd_info *mtd, struct nand_chip *chip,
-			const uint8_t *buf, int oob_required);
+			const uint8_t *buf, int oob_required, int page);
 	int (*read_page)(struct mtd_info *mtd, struct nand_chip *chip,
 			uint8_t *buf, int oob_required, int page);
 	int (*read_subpage)(struct mtd_info *mtd, struct nand_chip *chip,
 			uint32_t offs, uint32_t len, uint8_t *buf, int page);
 	int (*write_subpage)(struct mtd_info *mtd, struct nand_chip *chip,
 			uint32_t offset, uint32_t data_len,
-			const uint8_t *data_buf, int oob_required);
+			const uint8_t *data_buf, int oob_required, int page);
 	int (*write_page)(struct mtd_info *mtd, struct nand_chip *chip,
-			const uint8_t *buf, int oob_required);
+			const uint8_t *buf, int oob_required, int page);
 	int (*write_oob_raw)(struct mtd_info *mtd, struct nand_chip *chip,
 			int page);
 	int (*read_oob_raw)(struct mtd_info *mtd, struct nand_chip *chip,
-- 
1.9.1



From lorenzo.pieralisi at arm.com  Mon Aug 24 10:13:59 2015
From: lorenzo.pieralisi at arm.com (Lorenzo Pieralisi)
Date: Mon, 24 Aug 2015 18:13:59 +0100
Subject: [PATCH] ARM64: kernel: implement ACPI parking protocol
In-Reply-To: <1437071026.21160.1.camel@redhat.com>
References: <1436959990-32054-1-git-send-email-lorenzo.pieralisi@arm.com>
 <1437063431.3583.2.camel@redhat.com>
 <20150716171221.GB18582@red-moon> <55A7F24D.2000100@redhat.com>
 <1437071026.21160.1.camel@redhat.com>
Message-ID: <20150824171345.GA4981@red-moon>

Hi Mark,

On Thu, Jul 16, 2015 at 07:23:46PM +0100, Mark Salter wrote:
> On Thu, 2015-07-16 at 12:05 -0600, Al Stone wrote:
> 
> > On 07/16/2015 11:12 AM, Lorenzo Pieralisi wrote:
> 
> > > On Thu, Jul 16, 2015 at 05:17:11PM +0100, Mark Salter wrote:
> 
> > > > On Wed, 2015-07-15 at 12:33 +0100, Lorenzo Pieralisi wrote:
> > > > 
> 
> > > > > The SBBR and ACPI specifications allow ACPI based systems that do not
> > > > > implement PSCI (eg systems with no EL3) to boot through the ACPI parking
> > > > > protocol specification[1].
> > > > > 
> > > > > This patch implements the ACPI parking protocol CPU operations, and adds
> > > > > code that eases parsing the parking protocol data structures to the
> > > > > ARM64 SMP initializion carried out at the same time as cpus enumeration.
> > > > > 
> > > > > To wake-up the CPUs from the parked state, this patch implements a
> > > > > wakeup IPI for ARM64 (ie arch_send_wakeup_ipi_mask()) that mirrors the
> > > > > ARM one, so that a specific IPI is sent for wake-up purpose in order
> > > > > to distinguish it from other IPI sources.
> > > > > 
> > > > > Given the current ACPI MADT parsing API, the patch implements a glue
> > > > > layer that helps passing MADT GICC data structure from SMP initialization
> > > > 
> > > > Somewhat off topic, but this reminds once again, that it might be
> > > > better to generalize the ACPI_MADT_TYPE_GENERIC_INTERRUPT so that it
> > > > could be done in one pass. Currently, the SMP code and the GIC code
> > > > need boot-time info from ACPI_MADT_TYPE_GENERIC_INTERRUPT tables. This
> > > > patch adds parking protocol, and this patch:
> > > > 
> > > >  https://lkml.org/lkml/2015/5/1/203
> > > > 
> > > > need to get the PMU irq from the same table. I've been thinking of
> > > > something like a single loop through the table in setup.c with
> > > > callouts to registered users of the various bits of data.
> > > 
> > > It is not off topic at all, it is bang on topic. I hate the code
> > > as it stands forcing parsing the MADT in multiple places at different
> > > times, that's why I added hooks to set the parking protocol entries
> > > from smp.c and I know that's ugly, I posted it like this on purpose
> > > to get feedback.
> > > 
> 
> > > > Those users could register a handler function with something like an
> > > > ACPI_MADT_GIC_DECLARE() macro which would add a handler to a
> > > > special linker section.
> > > > 
> > > > I could work up a separate patch if others think it a worthwhile
> > > > thing to do.
> > > 
> > > Something simpler ? Like stashing the GICC entries (I know we need
> > > permanent table mappings for that to work unless we create data
> > > structures out of the MADT entries with the fields we are interested in)
> > > for possible CPUS ?
> > 
> > Right -- it seems like it would be pretty straightforward to traverse
> > the MADT once, and capture all the GICC subtables in a list of pointers,
> > or even make a copy of the contents of all of them.  Each user of the
> > content would still have to traverse the list, though, unless data is
> > reduced to only those things that are needed and the rest tossed.  Even
> > if only keep the info needed, I've still got a list of entries, one for
> > each CPU, I think, that I would still have to traverse.
> > 
> > If I have to register a handler to gather a specific bit of data needed,
> > I'm not understanding how that's any less complicated than what I need
> > to do today -- call acpi_parse_table_madt() with my GICC handler.  Wouldn't
> > both GICC subtable handlers be just about the same code?
> > 
> > I'm probably missing something obvious, but I'm not understanding what problem
> > is being solved....
> > 
> 
> The difference is that GIC code and SMP code each loop
> through the tables getting the info they need. If they
> registered a handler, there is only one loop through
> the tables regardless of how many handlers get registered.
> Having each loop through as currently done isn't really
> a performance issue (its boot-time only right now), but
> there is duplicated code wrt validating the table entry
> and calling the acpi API to do it. All of that could be
> done in one place instead of duplicating it in different
> places.

Did you have time to put the patch together ? I would like
to post a v2 for this set soon.

Thank you !
Lorenzo


From heiko at sntech.de  Mon Aug 24 10:21:53 2015
From: heiko at sntech.de (Heiko Stuebner)
Date: Mon, 24 Aug 2015 19:21:53 +0200
Subject: [PATCH] ARM: dts: rockchip: Add support for SD/MMC on
 MarsBoard-RK3066
In-Reply-To: <1440432281-491-1-git-send-email-romain.perier@gmail.com>
References: <1440432281-491-1-git-send-email-romain.perier@gmail.com>
Message-ID: <110804682.VHnft3L4vc@phil>

Am Montag, 24. August 2015, 18:04:41 schrieb Romain Perier:
> This enables SDMMC0 on the board and gives a basic support for SD cards.
> 
> Signed-off-by: Romain Perier <romain.perier at gmail.com>

applied to my dts branch, after moving it above the "&pinctrl" node


Heiko


From andre.przywara at arm.com  Mon Aug 24 10:24:28 2015
From: andre.przywara at arm.com (Andre Przywara)
Date: Mon, 24 Aug 2015 18:24:28 +0100
Subject: [PATCH v2 05/15] KVM: arm/arm64: make GIC frame address
 initialization model specific
In-Reply-To: <55CB43FB.4070400@linaro.org>
References: <1436538111-4294-1-git-send-email-andre.przywara@arm.com>
 <1436538111-4294-6-git-send-email-andre.przywara@arm.com>
 <55CB43FB.4070400@linaro.org>
Message-ID: <55DB534C.8040207@arm.com>

Hi,

On 12/08/15 14:02, Eric Auger wrote:
> On 07/10/2015 04:21 PM, Andre Przywara wrote:
>> Currently we initialize all the possible GIC frame addresses in one
>> function, without looking at the specific GIC model we instantiate
>> for the guest.
>> As this gets confusing when adding another VGIC model later, lets
>> move these initializations into the respective model's init 
> nit: tobe more precise the init emulation function (not the
> vgic_v2/v3_init_model model's init function). pfouh?! ;-)
> functions.

OK, will try to find a wording that is not completely confusing.

>>
>> Signed-off-by: Andre Przywara <andre.przywara at arm.com>
>> ---
>>  virt/kvm/arm/vgic-v2-emul.c | 3 +++
>>  virt/kvm/arm/vgic-v3-emul.c | 3 +++
>>  virt/kvm/arm/vgic.c         | 3 ---
>>  3 files changed, 6 insertions(+), 3 deletions(-)
>>
>> diff --git a/virt/kvm/arm/vgic-v2-emul.c b/virt/kvm/arm/vgic-v2-emul.c
>> index 1390797..8faa28c 100644
>> --- a/virt/kvm/arm/vgic-v2-emul.c
>> +++ b/virt/kvm/arm/vgic-v2-emul.c
>> @@ -567,6 +567,9 @@ void vgic_v2_init_emulation(struct kvm *kvm)
>>  	dist->vm_ops.init_model = vgic_v2_init_model;
>>  	dist->vm_ops.map_resources = vgic_v2_map_resources;
>>  
>> +	dist->vgic_cpu_base = VGIC_ADDR_UNDEF;
>> +	dist->vgic_dist_base = VGIC_ADDR_UNDEF;
> Looks strange to see the common dist_base here. Why don't you leave it
> in common part, kvm_vgic_create; all the more so you left
> kvm->arch.vgic.vctrl_base = vgic->vctrl_base in kvm_vgic_create.

The idea behind this is that dist_base refers to similar, but not
identical distributors (v2 vs. v3), so I found it a good idea to
initialize it in here. Also vctrl_base is host facing and not set by
userland, so this doesn't really compare here.

Cheers,
Andre.

>> +
>>  	kvm->arch.max_vcpus = VGIC_V2_MAX_CPUS;
>>  }
>>  
>> diff --git a/virt/kvm/arm/vgic-v3-emul.c b/virt/kvm/arm/vgic-v3-emul.c
>> index d2eeb20..1f42348 100644
>> --- a/virt/kvm/arm/vgic-v3-emul.c
>> +++ b/virt/kvm/arm/vgic-v3-emul.c
>> @@ -885,6 +885,9 @@ void vgic_v3_init_emulation(struct kvm *kvm)
>>  	dist->vm_ops.destroy_model = vgic_v3_destroy_model;
>>  	dist->vm_ops.map_resources = vgic_v3_map_resources;
>>  
>> +	dist->vgic_dist_base = VGIC_ADDR_UNDEF;
>> +	dist->vgic_redist_base = VGIC_ADDR_UNDEF;
>> +
>>  	kvm->arch.max_vcpus = KVM_MAX_VCPUS;
>>  }
>>  
>> diff --git a/virt/kvm/arm/vgic.c b/virt/kvm/arm/vgic.c
>> index cc8f5ed..59f1801 100644
>> --- a/virt/kvm/arm/vgic.c
>> +++ b/virt/kvm/arm/vgic.c
>> @@ -1830,9 +1830,6 @@ int kvm_vgic_create(struct kvm *kvm, u32 type)
>>  	kvm->arch.vgic.in_kernel = true;
>>  	kvm->arch.vgic.vgic_model = type;
>>  	kvm->arch.vgic.vctrl_base = vgic->vctrl_base;
>> -	kvm->arch.vgic.vgic_dist_base = VGIC_ADDR_UNDEF;
>> -	kvm->arch.vgic.vgic_cpu_base = VGIC_ADDR_UNDEF;
>> -	kvm->arch.vgic.vgic_redist_base = VGIC_ADDR_UNDEF;
>>  
>>  out_unlock:
>>  	for (; vcpu_lock_idx >= 0; vcpu_lock_idx--) {
>>
> 


From bhelgaas at google.com  Mon Aug 24 10:32:00 2015
From: bhelgaas at google.com (Bjorn Helgaas)
Date: Mon, 24 Aug 2015 10:32:00 -0700
Subject: [PATCH] pci: acpi: Generic function for setting up PCI device DMA
 coherency
In-Reply-To: <55DB4939.5070605@amd.com>
References: <1439459925-2361-1-git-send-email-Suravee.Suthikulpanit@amd.com>
 <55DB4939.5070605@amd.com>
Message-ID: <CAErSpo4BzNgvVyEbFZWmQPR4KQsvMT1tRpT1mxPL=TymYSM3DQ@mail.gmail.com>

On Mon, Aug 24, 2015 at 9:41 AM, Suravee Suthikulpanit
<Suravee.Suthikulpanit at amd.com> wrote:
> Hi,
>
> Ping. Does anyone have any comments or suggestions?

Yes, I sent you some ideas a couple weeks ago.  I'll resend them.

> On 8/13/15 16:58, Suravee Suthikulpanit wrote:
>>
>> This patch refactors of_pci_dma_configure() into a more generic
>> pci_dma_configure(), which can be reused by non-OF code.
>> Then, it adds support for setting up PCI device DMA coherency from
>> ACPI _CCA object that should normally be specified in the DSDT node
>> of its PCI host bridge..
>>
>> Signed-off-by: Suravee Suthikulpanit <Suravee.Suthikulpanit at amd.com>
>> CC: Bjorn Helgaas <bhelgaas at google.com>
>> CC: Catalin Marinas <catalin.marinas at arm.com>
>> CC: Will Deacon <will.deacon at arm.com>
>> CC: Rafael J. Wysocki <rjw at rjwysocki.net>
>> CC: Rob Herring <robh+dt at kernel.org>
>> CC: Murali Karicheri <m-karicheri2 at ti.com>
>> ---
>> Note: According to the ACPI spec, the _CCA attribute is required
>>        for ARM64. Therefore, this patch is a pre-req for ACPI PCI
>>        support for ARM64 which is currently in development.
>>
>>        Also, this should not affect other architectures since
>>        if CCA is not required, the default value is coherent.
>>        Please see include/acpi/acpi_bus.h: acpi_check_dma() and
>>        drivers/acpi/scan.c: acpi_init_coherency() for more information
>>
>>   drivers/of/of_pci.c    | 20 --------------------
>>   drivers/pci/probe.c    | 35 +++++++++++++++++++++++++++++++++--
>>   include/linux/of_pci.h |  3 ---
>>   3 files changed, 33 insertions(+), 25 deletions(-)
>>
>> diff --git a/drivers/of/of_pci.c b/drivers/of/of_pci.c
>> index 5751dc5..b66ee4e 100644
>> --- a/drivers/of/of_pci.c
>> +++ b/drivers/of/of_pci.c
>> @@ -117,26 +117,6 @@ int of_get_pci_domain_nr(struct device_node *node)
>>   }
>>   EXPORT_SYMBOL_GPL(of_get_pci_domain_nr);
>>
>> -/**
>> - * of_pci_dma_configure - Setup DMA configuration
>> - * @dev: ptr to pci_dev struct of the PCI device
>> - *
>> - * Function to update PCI devices's DMA configuration using the same
>> - * info from the OF node of host bridge's parent (if any).
>> - */
>> -void of_pci_dma_configure(struct pci_dev *pci_dev)
>> -{
>> -       struct device *dev = &pci_dev->dev;
>> -       struct device *bridge = pci_get_host_bridge_device(pci_dev);
>> -
>> -       if (!bridge->parent)
>> -               return;
>> -
>> -       of_dma_configure(dev, bridge->parent->of_node);
>> -       pci_put_host_bridge_device(bridge);
>> -}
>> -EXPORT_SYMBOL_GPL(of_pci_dma_configure);
>> -
>>   #if defined(CONFIG_OF_ADDRESS)
>>   /**
>>    * of_pci_get_host_bridge_resources - Parse PCI host bridge resources
>> from DT
>> diff --git a/drivers/pci/probe.c b/drivers/pci/probe.c
>> index cefd636..e2fcd3b 100644
>> --- a/drivers/pci/probe.c
>> +++ b/drivers/pci/probe.c
>> @@ -6,12 +6,14 @@
>>   #include <linux/delay.h>
>>   #include <linux/init.h>
>>   #include <linux/pci.h>
>> -#include <linux/of_pci.h>
>> +#include <linux/of_device.h>
>>   #include <linux/pci_hotplug.h>
>>   #include <linux/slab.h>
>>   #include <linux/module.h>
>>   #include <linux/cpumask.h>
>>   #include <linux/pci-aspm.h>
>> +#include <linux/acpi.h>
>> +#include <linux/property.h>
>>   #include <asm-generic/pci-bridge.h>
>>   #include "pci.h"
>>
>> @@ -1544,6 +1546,35 @@ static void pci_init_capabilities(struct pci_dev
>> *dev)
>>         pci_enable_acs(dev);
>>   }
>>
>> +/**
>> + * pci_dma_configure - Setup DMA configuration
>> + * @pci_dev: ptr to pci_dev struct of the PCI device
>> + *
>> + * Function to update PCI devices's DMA configuration using the same
>> + * info from the OF node or ACPI node of host bridge's parent (if any).
>> + */
>> +static void pci_dma_configure(struct pci_dev *pci_dev)
>> +{
>> +       struct device *dev = &pci_dev->dev;
>> +       struct device *bridge = pci_get_host_bridge_device(pci_dev);
>> +       struct acpi_device *adev;
>> +       bool coherent;
>> +
>> +       if (has_acpi_companion(bridge)) {
>> +               adev = to_acpi_node(bridge->fwnode);
>> +               if (acpi_check_dma(adev, &coherent))
>> +                       arch_setup_dma_ops(dev, 0, 0, NULL, coherent);
>> +       } else {
>> +               struct device *host = bridge->parent;
>> +               if (!host)
>> +                       return;
>> +
>> +               of_dma_configure(dev, host->of_node);
>> +       }
>> +
>> +       pci_put_host_bridge_device(bridge);
>> +}
>> +
>>   void pci_device_add(struct pci_dev *dev, struct pci_bus *bus)
>>   {
>>         int ret;
>> @@ -1557,7 +1588,7 @@ void pci_device_add(struct pci_dev *dev, struct
>> pci_bus *bus)
>>         dev->dev.dma_mask = &dev->dma_mask;
>>         dev->dev.dma_parms = &dev->dma_parms;
>>         dev->dev.coherent_dma_mask = 0xffffffffull;
>> -       of_pci_dma_configure(dev);
>> +       pci_dma_configure(dev);
>>
>>         pci_set_dma_max_seg_size(dev, 65536);
>>         pci_set_dma_seg_boundary(dev, 0xffffffff);
>> diff --git a/include/linux/of_pci.h b/include/linux/of_pci.h
>> index 29fd3fe..ce0e5ab 100644
>> --- a/include/linux/of_pci.h
>> +++ b/include/linux/of_pci.h
>> @@ -16,7 +16,6 @@ int of_pci_get_devfn(struct device_node *np);
>>   int of_irq_parse_and_map_pci(const struct pci_dev *dev, u8 slot, u8
>> pin);
>>   int of_pci_parse_bus_range(struct device_node *node, struct resource
>> *res);
>>   int of_get_pci_domain_nr(struct device_node *node);
>> -void of_pci_dma_configure(struct pci_dev *pci_dev);
>>   #else
>>   static inline int of_irq_parse_pci(const struct pci_dev *pdev, struct
>> of_phandle_args *out_irq)
>>   {
>> @@ -51,8 +50,6 @@ of_get_pci_domain_nr(struct device_node *node)
>>   {
>>         return -1;
>>   }
>> -
>> -static inline void of_pci_dma_configure(struct pci_dev *pci_dev) { }
>>   #endif
>>
>>   #if defined(CONFIG_OF_ADDRESS)
>>
>


From bhelgaas at google.com  Mon Aug 24 10:32:24 2015
From: bhelgaas at google.com (Bjorn Helgaas)
Date: Mon, 24 Aug 2015 10:32:24 -0700
Subject: [PATCH] pci: acpi: Generic function for setting up PCI device DMA
 coherency
In-Reply-To: <20150814015004.GA26431@google.com>
References: <1439459925-2361-1-git-send-email-Suravee.Suthikulpanit@amd.com>
 <20150814015004.GA26431@google.com>
Message-ID: <CAErSpo7yN08tKyo-yyyVG58vUptbHGN=L+MEZ8TQy1gm5a1_0Q@mail.gmail.com>

Here it is again.

On Thu, Aug 13, 2015 at 6:50 PM, Bjorn Helgaas <bhelgaas at google.com> wrote:
> Hi Suravee,
>
> On Thu, Aug 13, 2015 at 04:58:45PM +0700, Suravee Suthikulpanit wrote:
>> This patch refactors of_pci_dma_configure() into a more generic
>> pci_dma_configure(), which can be reused by non-OF code.
>> Then, it adds support for setting up PCI device DMA coherency from
>> ACPI _CCA object that should normally be specified in the DSDT node
>> of its PCI host bridge..
>
> Since this does two things:
>   1) Rename of_pci_dma_configure() and move it to PCI
>   2) Add _CCA support,
> maybe it should be split into two patches?
>
> There are a couple more comments below.
>
> While looking at this, I thought some of the existing code could be
> made simpler and easier to follow.  I appended a couple possible patches;
> you can incorporate them or ignore them, whatever seems best to you.
>
> Bjorn
>
>> Signed-off-by: Suravee Suthikulpanit <Suravee.Suthikulpanit at amd.com>
>> CC: Bjorn Helgaas <bhelgaas at google.com>
>> CC: Catalin Marinas <catalin.marinas at arm.com>
>> CC: Will Deacon <will.deacon at arm.com>
>> CC: Rafael J. Wysocki <rjw at rjwysocki.net>
>> CC: Rob Herring <robh+dt at kernel.org>
>> CC: Murali Karicheri <m-karicheri2 at ti.com>
>> ---
>> Note: According to the ACPI spec, the _CCA attribute is required
>>       for ARM64. Therefore, this patch is a pre-req for ACPI PCI
>>       support for ARM64 which is currently in development.
>>
>>       Also, this should not affect other architectures since
>>       if CCA is not required, the default value is coherent.
>>       Please see include/acpi/acpi_bus.h: acpi_check_dma() and
>>       drivers/acpi/scan.c: acpi_init_coherency() for more information
>>
>>  drivers/of/of_pci.c    | 20 --------------------
>>  drivers/pci/probe.c    | 35 +++++++++++++++++++++++++++++++++--
>>  include/linux/of_pci.h |  3 ---
>>  3 files changed, 33 insertions(+), 25 deletions(-)
>>
>> diff --git a/drivers/of/of_pci.c b/drivers/of/of_pci.c
>> index 5751dc5..b66ee4e 100644
>> --- a/drivers/of/of_pci.c
>> +++ b/drivers/of/of_pci.c
>> @@ -117,26 +117,6 @@ int of_get_pci_domain_nr(struct device_node *node)
>>  }
>>  EXPORT_SYMBOL_GPL(of_get_pci_domain_nr);
>>
>> -/**
>> - * of_pci_dma_configure - Setup DMA configuration
>> - * @dev: ptr to pci_dev struct of the PCI device
>> - *
>> - * Function to update PCI devices's DMA configuration using the same
>> - * info from the OF node of host bridge's parent (if any).
>> - */
>> -void of_pci_dma_configure(struct pci_dev *pci_dev)
>> -{
>> -     struct device *dev = &pci_dev->dev;
>> -     struct device *bridge = pci_get_host_bridge_device(pci_dev);
>> -
>> -     if (!bridge->parent)
>> -             return;
>> -
>> -     of_dma_configure(dev, bridge->parent->of_node);
>> -     pci_put_host_bridge_device(bridge);
>> -}
>> -EXPORT_SYMBOL_GPL(of_pci_dma_configure);
>> -
>>  #if defined(CONFIG_OF_ADDRESS)
>>  /**
>>   * of_pci_get_host_bridge_resources - Parse PCI host bridge resources from DT
>> diff --git a/drivers/pci/probe.c b/drivers/pci/probe.c
>> index cefd636..e2fcd3b 100644
>> --- a/drivers/pci/probe.c
>> +++ b/drivers/pci/probe.c
>> @@ -6,12 +6,14 @@
>>  #include <linux/delay.h>
>>  #include <linux/init.h>
>>  #include <linux/pci.h>
>> -#include <linux/of_pci.h>
>> +#include <linux/of_device.h>
>>  #include <linux/pci_hotplug.h>
>>  #include <linux/slab.h>
>>  #include <linux/module.h>
>>  #include <linux/cpumask.h>
>>  #include <linux/pci-aspm.h>
>> +#include <linux/acpi.h>
>> +#include <linux/property.h>
>>  #include <asm-generic/pci-bridge.h>
>>  #include "pci.h"
>>
>> @@ -1544,6 +1546,35 @@ static void pci_init_capabilities(struct pci_dev *dev)
>>       pci_enable_acs(dev);
>>  }
>>
>> +/**
>> + * pci_dma_configure - Setup DMA configuration
>> + * @pci_dev: ptr to pci_dev struct of the PCI device
>> + *
>> + * Function to update PCI devices's DMA configuration using the same
>> + * info from the OF node or ACPI node of host bridge's parent (if any).
>> + */
>> +static void pci_dma_configure(struct pci_dev *pci_dev)
>
> Almost all pci_dev pointers in probe.c are named "dev", so I would use
> that for this one, too.  I probably would just drop the "struct device
> *dev" below and use "&dev->dev" the two places you need it.  That's a
> common idiom in PCI.
>
>> +{
>> +     struct device *dev = &pci_dev->dev;
>> +     struct device *bridge = pci_get_host_bridge_device(pci_dev);
>> +     struct acpi_device *adev;
>> +     bool coherent;
>> +
>> +     if (has_acpi_companion(bridge)) {
>> +             adev = to_acpi_node(bridge->fwnode);
>> +             if (acpi_check_dma(adev, &coherent))
>> +                     arch_setup_dma_ops(dev, 0, 0, NULL, coherent);
>> +     } else {
>> +             struct device *host = bridge->parent;
>> +             if (!host)
>> +                     return;
>> +
>> +             of_dma_configure(dev, host->of_node);
>> +     }
>
> Why is this check reversed with respect to device_dma_is_coherent()?
> In device_dma_is_coherent(), we first look for an OF property, then look
> for ACPI _CCA.  But here we check for _CCA, then for OF.
>
>> +
>> +     pci_put_host_bridge_device(bridge);
>> +}
>> +
>>  void pci_device_add(struct pci_dev *dev, struct pci_bus *bus)
>>  {
>>       int ret;
>> @@ -1557,7 +1588,7 @@ void pci_device_add(struct pci_dev *dev, struct pci_bus *bus)
>>       dev->dev.dma_mask = &dev->dma_mask;
>>       dev->dev.dma_parms = &dev->dma_parms;
>>       dev->dev.coherent_dma_mask = 0xffffffffull;
>> -     of_pci_dma_configure(dev);
>> +     pci_dma_configure(dev);
>>
>>       pci_set_dma_max_seg_size(dev, 65536);
>>       pci_set_dma_seg_boundary(dev, 0xffffffff);
>> diff --git a/include/linux/of_pci.h b/include/linux/of_pci.h
>> index 29fd3fe..ce0e5ab 100644
>> --- a/include/linux/of_pci.h
>> +++ b/include/linux/of_pci.h
>> @@ -16,7 +16,6 @@ int of_pci_get_devfn(struct device_node *np);
>>  int of_irq_parse_and_map_pci(const struct pci_dev *dev, u8 slot, u8 pin);
>>  int of_pci_parse_bus_range(struct device_node *node, struct resource *res);
>>  int of_get_pci_domain_nr(struct device_node *node);
>> -void of_pci_dma_configure(struct pci_dev *pci_dev);
>>  #else
>>  static inline int of_irq_parse_pci(const struct pci_dev *pdev, struct of_phandle_args *out_irq)
>>  {
>> @@ -51,8 +50,6 @@ of_get_pci_domain_nr(struct device_node *node)
>>  {
>>       return -1;
>>  }
>> -
>> -static inline void of_pci_dma_configure(struct pci_dev *pci_dev) { }
>>  #endif
>>
>>  #if defined(CONFIG_OF_ADDRESS)
>> --
>> 2.1.0
>>
> commit 18183957888f601807ca0e166516ae60f682eb62
> Author: Bjorn Helgaas <bhelgaas at google.com>
> Date:   Thu Aug 13 20:01:21 2015 -0500
>
>     ACPI / scan: Move _CCA comments to acpi_init_coherency()
>
>     Move the comments about how we handle _CCA to the code that looks at _CCA,
>     and fix a couple typos.
>
>     No functional change.
>
>     Signed-off-by: Bjorn Helgaas <bhelgaas at google.com>
>
> diff --git a/drivers/acpi/scan.c b/drivers/acpi/scan.c
> index ec25635..a12e522 100644
> --- a/drivers/acpi/scan.c
> +++ b/drivers/acpi/scan.c
> @@ -2188,6 +2188,22 @@ static void acpi_init_coherency(struct acpi_device *adev)
>         acpi_status status;
>         struct acpi_device *parent = adev->parent;
>
> +       /**
> +        * Currently, we only support _CCA=1 (i.e. coherent_dma=1)
> +        * This should be equivalent to specifying dma-coherent for
> +        * a device in OF.
> +        *
> +        * For the case when _CCA=0 (i.e. coherent_dma=0 && cca_seen=1),
> +        * we have two choices:
> +        * case 1. Do not support and disable DMA.
> +        * case 2. Support but rely on arch-specific cache maintenance for
> +        *         non-coherent DMA operations.
> +        * Currently, we implement case 1 above.
> +        *
> +        * For the case when _CCA is missing (i.e. cca_seen=0) and
> +        * platform specifies ACPI_CCA_REQUIRED, we do not support DMA,
> +        * and fallback to arch-specific default handling.
> +        */
>         if (parent && parent->flags.cca_seen) {
>                 /*
>                  * From ACPI spec, OSPM will ignore _CCA if an ancestor
> diff --git a/include/acpi/acpi_bus.h b/include/acpi/acpi_bus.h
> index 83061ca..718942b 100644
> --- a/include/acpi/acpi_bus.h
> +++ b/include/acpi/acpi_bus.h
> @@ -389,24 +389,6 @@ static inline bool acpi_check_dma(struct acpi_device *adev, bool *coherent)
>         if (!adev)
>                 return ret;
>
> -       /**
> -        * Currently, we only support _CCA=1 (i.e. coherent_dma=1)
> -        * This should be equivalent to specifyig dma-coherent for
> -        * a device in OF.
> -        *
> -        * For the case when _CCA=0 (i.e. coherent_dma=0 && cca_seen=1),
> -        * There are two cases:
> -        * case 1. Do not support and disable DMA.
> -        * case 2. Support but rely on arch-specific cache maintenance for
> -        *         non-coherence DMA operations.
> -        * Currently, we implement case 1 above.
> -        *
> -        * For the case when _CCA is missing (i.e. cca_seen=0) and
> -        * platform specifies ACPI_CCA_REQUIRED, we do not support DMA,
> -        * and fallback to arch-specific default handling.
> -        *
> -        * See acpi_init_coherency() for more info.
> -        */
>         if (adev->flags.coherent_dma) {
>                 ret = true;
>                 if (coherent)
>
> commit 84cfb2213cd400fef227ec0d7829ec4e12895da9
> Author: Bjorn Helgaas <bhelgaas at google.com>
> Date:   Thu Aug 13 19:49:52 2015 -0500
>
>     ACPI / scan: Rename acpi_check_dma() to acpi_dma_is_coherent()
>
>     The name "acpi_check_dma()" doesn't give any much indication about what
>     exactly it checks.  The function also returns information both as a normal
>     return value and as the "bool *coherent" return parameter.  But "*coherent"
>     doesn't actually give any extra information: it is unchanged when returning
>     false and set to true when returning true.
>
>     Rename acpi_check_dma() to acpi_dma_is_coherent() so the callers read more
>     naturally.  Drop the return parameter and just use the function return
>     value.
>
>     Signed-off-by: Bjorn Helgaas <bhelgaas at google.com>
>
> diff --git a/drivers/acpi/acpi_platform.c b/drivers/acpi/acpi_platform.c
> index 06a67d5..fc6138d 100644
> --- a/drivers/acpi/acpi_platform.c
> +++ b/drivers/acpi/acpi_platform.c
> @@ -103,7 +103,7 @@ struct platform_device *acpi_create_platform_device(struct acpi_device *adev)
>         pdevinfo.res = resources;
>         pdevinfo.num_res = count;
>         pdevinfo.fwnode = acpi_fwnode_handle(adev);
> -       pdevinfo.dma_mask = acpi_check_dma(adev, NULL) ? DMA_BIT_MASK(32) : 0;
> +       pdevinfo.dma_mask = acpi_dma_is_coherent(adev) ? DMA_BIT_MASK(32) : 0;
>         pdev = platform_device_register_full(&pdevinfo);
>         if (IS_ERR(pdev))
>                 dev_err(&adev->dev, "platform device creation failed: %ld\n",
> diff --git a/drivers/acpi/glue.c b/drivers/acpi/glue.c
> index b9657af..89b1cf8 100644
> --- a/drivers/acpi/glue.c
> +++ b/drivers/acpi/glue.c
> @@ -168,7 +168,6 @@ int acpi_bind_one(struct device *dev, struct acpi_device *acpi_dev)
>         struct list_head *physnode_list;
>         unsigned int node_id;
>         int retval = -EINVAL;
> -       bool coherent;
>
>         if (has_acpi_companion(dev)) {
>                 if (acpi_dev) {
> @@ -225,8 +224,8 @@ int acpi_bind_one(struct device *dev, struct acpi_device *acpi_dev)
>         if (!has_acpi_companion(dev))
>                 ACPI_COMPANION_SET(dev, acpi_dev);
>
> -       if (acpi_check_dma(acpi_dev, &coherent))
> -               arch_setup_dma_ops(dev, 0, 0, NULL, coherent);
> +       if (acpi_dma_is_coherent(acpi_dev))
> +               arch_setup_dma_ops(dev, 0, 0, NULL, true);
>
>         acpi_physnode_link_name(physical_node_name, node_id);
>         retval = sysfs_create_link(&acpi_dev->dev.kobj, &dev->kobj,
> diff --git a/drivers/base/property.c b/drivers/base/property.c
> index f3f6d16..1124130 100644
> --- a/drivers/base/property.c
> +++ b/drivers/base/property.c
> @@ -523,13 +523,9 @@ EXPORT_SYMBOL_GPL(device_get_child_node_count);
>
>  bool device_dma_is_coherent(struct device *dev)
>  {
> -       bool coherent = false;
> -
>         if (IS_ENABLED(CONFIG_OF) && dev->of_node)
> -               coherent = of_dma_is_coherent(dev->of_node);
> -       else
> -               acpi_check_dma(ACPI_COMPANION(dev), &coherent);
> +               return of_dma_is_coherent(dev->of_node);
>
> -       return coherent;
> +       return acpi_dma_is_coherent(ACPI_COMPANION(dev));
>  }
>  EXPORT_SYMBOL_GPL(device_dma_is_coherent);
> diff --git a/include/acpi/acpi_bus.h b/include/acpi/acpi_bus.h
> index 718942b..39f1be6 100644
> --- a/include/acpi/acpi_bus.h
> +++ b/include/acpi/acpi_bus.h
> @@ -382,19 +382,12 @@ struct acpi_device {
>         void (*remove)(struct acpi_device *);
>  };
>
> -static inline bool acpi_check_dma(struct acpi_device *adev, bool *coherent)
> +static inline bool acpi_dma_is_coherent(struct acpi_device *adev)
>  {
> -       bool ret = false;
> +       if (adev && adev->flags.coherent_dma)
> +               return true;
>
> -       if (!adev)
> -               return ret;
> -
> -       if (adev->flags.coherent_dma) {
> -               ret = true;
> -               if (coherent)
> -                       *coherent = adev->flags.coherent_dma;
> -       }
> -       return ret;
> +       return false;
>  }
>
>  static inline bool is_acpi_node(struct fwnode_handle *fwnode)
> diff --git a/include/linux/acpi.h b/include/linux/acpi.h
> index d2445fa..f29b8b5 100644
> --- a/include/linux/acpi.h
> +++ b/include/linux/acpi.h
> @@ -562,7 +562,7 @@ static inline int acpi_device_modalias(struct device *dev,
>         return -ENODEV;
>  }
>
> -static inline bool acpi_check_dma(struct acpi_device *adev, bool *coherent)
> +static inline bool acpi_dma_is_coherent(struct acpi_device *adev)
>  {
>         return false;
>  }


From tglx at linutronix.de  Mon Aug 24 10:37:00 2015
From: tglx at linutronix.de (Thomas Gleixner)
Date: Mon, 24 Aug 2015 19:37:00 +0200 (CEST)
Subject: [PATCH v8 1/2] irqchip: imx-gpcv2: IMX GPCv2 driver for wakeup
 sources
In-Reply-To: <CY1PR0301MB084328829F8128A8FBFA6A9283620@CY1PR0301MB0843.namprd03.prod.outlook.com>
References: <1438378439-11569-1-git-send-email-shenwei.wang@freescale.com>
 <1438378439-11569-2-git-send-email-shenwei.wang@freescale.com>
 <alpine.DEB.2.11.1508231251040.3873@nanos>
 <CY1PR0301MB084328829F8128A8FBFA6A9283620@CY1PR0301MB0843.namprd03.prod.outlook.com>
Message-ID: <alpine.DEB.2.11.1508241933150.3873@nanos>

On Mon, 24 Aug 2015, Shenwei Wang wrote:
> > > +static int gpcv2_wakeup_source_save(void) {
> > > +	struct gpcv2_irqchip_data *cd;
> > > +	void __iomem *reg;
> > > +	int i;
> > > +
> > > +	cd = imx_gpcv2_instance;
> > > +	if (!cd)
> > > +		return 0;
> > > +
> > > +	for (i = 0; i < IMR_NUM; i++) {
> > > +		reg = cd->gpc_base + cd->cpu2wakeup + i * 4;
> > > +		cd->enabled_irqs[i] = readl_relaxed(reg);
> > 
> > You read the full state of the register and restore the full state. So why
> > enabled_irqs?
> 
> There are two user scenarios: 
> In CPU Idle state, the system need to be woke up by any enabled
> irqs, not just the ones that marked as wakeup sources.
> In Suspend State, they system will only be woke up by the one that
> marked as a wakeup source.  Enabled_irqs are used to save the values
> before suspend, and restore them after resume.

That's what you want achieve. Still you save the full content of the
registers and restore the full content. That saves/restores the
enabled and disabled interrupts. So enabled_irqs is a misnomer as you
save the full state.

> > > +		writel_relaxed(cd->wakeup_sources[i], reg);
> > > +	}
> > > +
> > > +	return 0;
> > > +}
> > > +
> > > +static void gpcv2_wakeup_source_restore(void) {
> > > +	struct gpcv2_irqchip_data *cd;
> > > +	void __iomem *reg;
> > > +	int i;
> > > +
> > > +	cd = imx_gpcv2_instance;
> > > +	if (!cd)
> > > +		return;
> > > +
> > > +	for (i = 0; i < IMR_NUM; i++) {
> > > +		reg = cd->gpc_base + cd->cpu2wakeup + i * 4;
> > > +		writel_relaxed(cd->enabled_irqs[i], reg);
> > > +		cd->wakeup_sources[i] = ~0;
> > 
> > Why are you clearing that info on resume? Drivers will clear that via
> > set_wake() or leave it when they want to have resume functionality?
> > 
> Each time system goes into the suspend state, it will call set_wake
> (ON) again to configure the wakeup sources. Clearing wakeup_sources
> here can make sure the system work as expected no matter that a
> driver calls set_wake (OFF) during resume stage.

We rather make sure that the drivers call set_wake(OFF) as they are
supposed to, because if they do not then the set_wake(ON) logic in the
core code will see the counter != 0 and not invoke the irq callback.

Thanks,

	tglx


From marex at denx.de  Mon Aug 24 10:45:33 2015
From: marex at denx.de (Marek Vasut)
Date: Mon, 24 Aug 2015 19:45:33 +0200
Subject: [PATCH linux-next v4 5/5] mtd: atmel-quadspi: add driver for
 Atmel QSPI controller
In-Reply-To: <55DB4EA6.9090807@atmel.com>
References: <cover.1440410236.git.cyrille.pitchen@atmel.com>
 <201508241303.52066.marex@denx.de> <55DB4EA6.9090807@atmel.com>
Message-ID: <201508241945.33577.marex@denx.de>

On Monday, August 24, 2015 at 07:04:38 PM, Cyrille Pitchen wrote:
> Hi Marek,

Hi!

> Le 24/08/2015 13:03, Marek Vasut a ?crit :
> > On Monday, August 24, 2015 at 12:14:00 PM, Cyrille Pitchen wrote:
> >> This driver add support to the new Atmel QSPI controller embedded into
> >> sama5d2x SoCs. It expects a NOR memory to be connected to the QSPI
> >> controller.

[...]

> >> +	/* Compute address parameters */
> >> +	switch (cmd->enable.bits.address) {
> >> +	case 4:
> >> +		ifr |= QSPI_IFR_ADDRL;
> >> +		/*break;*/ /* fallback to the 24bit address case */
> > 
> > What's this commented out bit of code for ? :-)
> 
> I just wanted to stress out there was no missing "break;".
> I've reworded the comment to:
> /* No "break" on purpose: fallback to the 24bit address case. */

Oh, the address is in bytes . I see, yes, it makes sense to be more
explicit here about the purpose of the fallback. I think this change
in the comment will make it easier for everyone who comes back in a
few years and reads this code.

> >> +	case 3:
> >> +		iar = (cmd->enable.bits.data) ? 0 : cmd->address;
> >> +		ifr |= QSPI_IFR_ADDREN;
> >> +		break;
> >> +	case 0:
> >> +		break;
> >> +	default:
> >> +		return -EINVAL;
> >> +	}
> > 
> > [...]
> > 
> >> +no_data:
> >> +	/* Poll INSTRuction End status */
> >> +	sr = qspi_readl(aq, QSPI_SR);
> >> +	if (sr & QSPI_SR_INSTRE)
> >> +		return err;
> >> +
> >> +	/* Wait for INSTRuction End interrupt */
> >> +	init_completion(&aq->completion);
> > 
> > You should use reinit_completion() in the code. init_completion()
> > should be used only in the probe() function and nowhere else.
> 
> Alright. In the next version I'll rename the "completion" member of
> struct atmel_qspi into "cmd_completion". Also I'll add another
> dma_completion member in this very same structure to replace the local
> "struct completion completion" in atmel_qspi_run_dma_transfer().
> 
> Then I'll call init_completion() on both cmd_completion and dma_completion
> only from atmel_qspi_probe() and reinit_completion() elsewhere.
> 
> >> +	aq->pending = 0;
> >> +	qspi_writel(aq, QSPI_IER, QSPI_SR_INSTRE);
> >> +	if (!wait_for_completion_timeout(&aq->completion,
> >> +					 msecs_to_jiffies(1000)))
> >> +		err = -ETIMEDOUT;
> >> +	qspi_writel(aq, QSPI_IDR, QSPI_SR_INSTRE);
> >> +
> >> +	return err;
> >> +}
> > 
> > [...]
> > 
> > Hope this helps :)
> 
> Indeed, it does! I still work on the next version of this series to take
> all your comments into account.

Thanks :)


From keescook at chromium.org  Mon Aug 24 10:46:38 2015
From: keescook at chromium.org (Kees Cook)
Date: Mon, 24 Aug 2015 10:46:38 -0700
Subject: [BUG] arm: kgdb: patch_text() in kgdb_arch_set_breakpoint() may
 sleep
In-Reply-To: <CAD=FV=V_E+YMQuW5kvn+52Ugc_5hZsyXKKQ9Ywo_emoqK-N+Qw@mail.gmail.com>
References: <55C230C7.2000909@nvidia.com>
 <CAD=FV=V_E+YMQuW5kvn+52Ugc_5hZsyXKKQ9Ywo_emoqK-N+Qw@mail.gmail.com>
Message-ID: <CAGXu5j+P=LtTAVQbkn4w6Y9pTVouvRgAhwfS+rAmKfqTXC8pyg@mail.gmail.com>

On Sun, Aug 23, 2015 at 7:45 PM, Doug Anderson <dianders at chromium.org> wrote:
> On Wed, Aug 5, 2015 at 8:50 AM, Aapo Vienamo <avienamo at nvidia.com> wrote:
>> Hi,
>>
>> The breakpoint setting code in arch/arm/kernel/kgdb.c calls
>> patch_text(), which ends up trying to sleep while in interrupt context.
>> The bug was introduced by commit: 23a4e40 arm: kgdb: Handle read-only
>> text / modules. The resulting behavior is "BUG: scheduling while
>> atomic..." when setting a breakpoint in kgdb. This was tested on an
>> Nvidia Jetson TK1 board with 4.2.0-rc5-next-20150805 kernel.
>>
>> Regards,
>> Aapo Vienamo
>
> Aapo,
>
> Including the stack trace with this would have been helpful, though
> it's not too hard to reproduce.  Here it is:
>
> [  416.510559] BUG: scheduling while atomic: swapper/0/0/0x00010007
> [  416.516554] Modules linked in:
> [  416.519614] CPU: 0 PID: 0 Comm: swapper/0 Not tainted
> 4.2.0-rc7-00133-geb63b34 #1073
> [  416.527341] Hardware name: Rockchip (Device Tree)
> [  416.532042] [<c0017a4c>] (unwind_backtrace) from [<c00133d4>]
> (show_stack+0x20/0x24)
> [  416.539772] [<c00133d4>] (show_stack) from [<c05400e8>]
> (dump_stack+0x84/0xb8)
> [  416.546983] [<c05400e8>] (dump_stack) from [<c004913c>]
> (__schedule_bug+0x54/0x6c)
> [  416.554540] [<c004913c>] (__schedule_bug) from [<c054065c>]
> (__schedule+0x80/0x668)
> [  416.562183] [<c054065c>] (__schedule) from [<c0540cfc>] (schedule+0xb8/0xd4)
> [  416.569219] [<c0540cfc>] (schedule) from [<c0543a3c>]
> (schedule_timeout+0x2c/0x234)
> [  416.576861] [<c0543a3c>] (schedule_timeout) from [<c05417c0>]
> (wait_for_common+0xf4/0x188)
> [  416.585109] [<c05417c0>] (wait_for_common) from [<c0541874>]
> (wait_for_completion+0x20/0x24)
> [  416.593531] [<c0541874>] (wait_for_completion) from [<c00a0104>]
> (__stop_cpus+0x58/0x70)
> [  416.601608] [<c00a0104>] (__stop_cpus) from [<c00a0580>]
> (stop_cpus+0x3c/0x54)
> [  416.608817] [<c00a0580>] (stop_cpus) from [<c00a06c4>]
> (__stop_machine+0xcc/0xe8)
> [  416.616286] [<c00a06c4>] (__stop_machine) from [<c00a0714>]
> (stop_machine+0x34/0x44)
> [  416.624016] [<c00a0714>] (stop_machine) from [<c00173e8>]
> (patch_text+0x28/0x34)
> [  416.631399] [<c00173e8>] (patch_text) from [<c001733c>]
> (kgdb_arch_set_breakpoint+0x40/0x4c)
> [  416.639823] [<c001733c>] (kgdb_arch_set_breakpoint) from
> [<c00a0d68>] (kgdb_validate_break_address+0x2c/0x60)
> [  416.649719] [<c00a0d68>] (kgdb_validate_break_address) from
> [<c00a0e90>] (dbg_set_sw_break+0x1c/0xdc)
> [  416.658922] [<c00a0e90>] (dbg_set_sw_break) from [<c00a2e88>]
> (gdb_serial_stub+0x9c4/0xba4)
> [  416.667259] [<c00a2e88>] (gdb_serial_stub) from [<c00a11cc>]
> (kgdb_cpu_enter+0x1f8/0x60c)
> [  416.675423] [<c00a11cc>] (kgdb_cpu_enter) from [<c00a18cc>]
> (kgdb_handle_exception+0x19c/0x1d0)
> [  416.684106] [<c00a18cc>] (kgdb_handle_exception) from [<c0016f7c>]
> (kgdb_compiled_brk_fn+0x30/0x3c)
> [  416.693135] [<c0016f7c>] (kgdb_compiled_brk_fn) from [<c00091a4>]
> (do_undefinstr+0x1a4/0x20c)
> [  416.701643] [<c00091a4>] (do_undefinstr) from [<c001400c>]
> (__und_svc_finish+0x0/0x34)
> [  416.709543] Exception stack(0xc07c1ce8 to 0xc07c1d30)
> [  416.714584] 1ce0:                   00000000 c07c6504 c086e290
> c086e294 c086e294 c086e290
> [  416.722745] 1d00: c07c6504 00000067 00000001 c07c2100 00000027
> c07c1d4c c07c1d50 c07c1d30
> [  416.730905] 1d20: c00a0990 c00a08d0 60000193 ffffffff
> [  416.735947] [<c001400c>] (__und_svc_finish) from [<c00a08d0>]
> (kgdb_breakpoint+0x58/0x94)
> [  416.744110] [<c00a08d0>] (kgdb_breakpoint) from [<c00a0990>]
> (sysrq_handle_dbg+0x58/0x6c)
> [  416.752273] [<c00a0990>] (sysrq_handle_dbg) from [<c02c230c>]
> (__handle_sysrq+0xac/0x15c)
> [  416.760437] [<c02c230c>] (__handle_sysrq) from [<c02c23ec>]
> (handle_sysrq+0x30/0x34)
>
>
> Kees: I think you've dealt with a lot more of these types of issues
> than I have.  Any quick thoughts?  If not I can put it on my long-term
> list of things to do, but until then we could always just post a
> Revert...

I don't think a revert is in order here. CONFIG_DEBUG_RODATA could be
turned off for builds where you need kgdb while this bug gets found. I
don't actually see where we've gone wrong, though. Looks like
scheduling happened while waiting for CPUs to stop? Where did we enter
atomic?

Perhaps we need to test if we're already atomic in patch_text, and
only call stop_machine if we need to?

Untested (and likely mangled by gmail):

diff --git a/arch/arm/kernel/patch.c b/arch/arm/kernel/patch.c
index 69bda1a5707e..855696bfe072 100644
--- a/arch/arm/kernel/patch.c
+++ b/arch/arm/kernel/patch.c
@@ -124,5 +124,8 @@ void __kprobes patch_text(void *addr, unsigned int insn)
                .insn = insn,
        };

-       stop_machine(patch_text_stop_machine, &patch, NULL);
+       if (unlikely(in_atomic_preempt_off()))
+               patch_text_stop_machine(&patch);
+       else
+               stop_machine(patch_text_stop_machine, &patch, NULL);
 }


-Kees

-- 
Kees Cook
Chrome OS Security


From linux at arm.linux.org.uk  Mon Aug 24 10:47:36 2015
From: linux at arm.linux.org.uk (Russell King - ARM Linux)
Date: Mon, 24 Aug 2015 18:47:36 +0100
Subject: [PATCH v2 5/5] arm64: add KASan support
In-Reply-To: <CAPAsAGwji7FpUJK9O=FWYN15-rJkYMQyOt9W9ncdY9uLybxkiA@mail.gmail.com>
References: <CACRpkdaRJJjCXR=vK1M2YhR26JZfGoBB+jcqz8r2MhERfxRzqA@mail.gmail.com>
 <CAPAsAGy-r8Z2N09wKV+e0kLfbwxd-eWK6N5Xajsnqq9jfyWqcQ@mail.gmail.com>
 <CACRpkdZmHLMxosLXjyOPdkavo=UNzmTcHOLF5vV4cS1ULfbq6A@mail.gmail.com>
 <CAPAsAGw-iawTpjJh66rQN5fqBFT6UBZCcv2eKx7JTqCXzhzpsw@mail.gmail.com>
 <CACRpkdY2i2M27gP_fXawkFrC_GFgWaKr5rEn6d47refNPiEk=g@mail.gmail.com>
 <55AE56DB.4040607@samsung.com>
 <CACRpkdYaqK8upK-3b01JbO_y+sHnk4-Hm1MfvjSy0tKUkFREtQ@mail.gmail.com>
 <20150824131557.GB7557@n2100.arm.linux.org.uk>
 <CACRpkdYwpucRiXM05y00RQY=gKv8W6YjCNspYFRMGaM605cU0w@mail.gmail.com>
 <CAPAsAGwji7FpUJK9O=FWYN15-rJkYMQyOt9W9ncdY9uLybxkiA@mail.gmail.com>
Message-ID: <20150824174736.GD7557@n2100.arm.linux.org.uk>

On Mon, Aug 24, 2015 at 05:15:22PM +0300, Andrey Ryabinin wrote:
> Yes, ~130Mb (3G/1G split) should work. 512Mb shadow is optional.
> The only advantage of 512Mb shadow is better handling of user memory
> accesses bugs
> (access to user memory without copy_from_user/copy_to_user/strlen_user etc API).

No need for that to be handed by KASan.  I have patches in linux-next,
now acked by Will, which prevent the kernel accessing userspace with
zero memory footprint.  No need for remapping, we have a way to quickly
turn off access to userspace mapped pages on non-LPAE 32-bit CPUs.
(LPAE is not supported yet - Catalin will be working on that using the
hooks I'm providing once he returns.)

This isn't a debugging thing, it's a security hardening thing.  Some
use-after-free bugs are potentially exploitable from userspace.  See
the recent blackhat conference paper.

-- 
FTTC broadband for 0.8mile line: currently at 10.5Mbps down 400kbps up
according to speedtest.net.


From briannorris at chromium.org  Mon Aug 24 10:53:15 2015
From: briannorris at chromium.org (Brian Norris)
Date: Mon, 24 Aug 2015 10:53:15 -0700
Subject: [PATCH v2 1/3] ARM: dts: rockchip: add veyron-jaq board
In-Reply-To: <CABxcv=nQAfCzj_bQ9N-XYEPCNuihyrkUOz7=ogetKzye4KKNng@mail.gmail.com>
References: <1440022721-73712-1-git-send-email-briannorris@chromium.org>
 <CABxcv=nQAfCzj_bQ9N-XYEPCNuihyrkUOz7=ogetKzye4KKNng@mail.gmail.com>
Message-ID: <20150824175315.GA81574@google.com>

On Thu, Aug 20, 2015 at 01:29:40AM +0200, Javier Martinez Canillas wrote:
> Hello Brian,
> 
> [...]
> 
> > +
> > +&rk808 {
> > +       pinctrl-names = "default";
> > +       pinctrl-0 = <&pmic_int_l &dvs_1 &dvs_2>;
> > +       dvs-gpios = <&gpio7 12 GPIO_ACTIVE_HIGH>,
> > +                   <&gpio7 15 GPIO_ACTIVE_HIGH>;
> 
> I see the dvs-gpios DT property is documented in the downstream
> ChromiumOS 3.18 tree [0] but I don't see it neither mentioned in
> Documentation/devicetree/bindings/mfd/rk808.txt in mainline nor code
> that parses it in the drivers/regulator/rk808-regulator.c driver.

Good catch.

> So I think this should be removed and also the dvs_{1,2} pinctrl
> lines.

OK, will do. I see that jerry, minnie, and speedy also have the pinctrl
lines. Should they be killed as well?

> The rest of the patch looks good to me though so with these
> removed feel free to add:
> 
> Reviewed-by: Javier Martinez Canillas <javier at osg.samsung.com>

Thanks.

> [0]: https://chromium.googlesource.com/chromiumos/third_party/kernel/+/chromeos-3.14/Documentation/devicetree/bindings/mfd/rk808.txt

Brian


From heiko at sntech.de  Mon Aug 24 10:58:33 2015
From: heiko at sntech.de (Heiko Stuebner)
Date: Mon, 24 Aug 2015 19:58:33 +0200
Subject: [PATCH v2 1/3] ARM: dts: rockchip: add veyron-jaq board
In-Reply-To: <20150824175315.GA81574@google.com>
References: <1440022721-73712-1-git-send-email-briannorris@chromium.org>
 <CABxcv=nQAfCzj_bQ9N-XYEPCNuihyrkUOz7=ogetKzye4KKNng@mail.gmail.com>
 <20150824175315.GA81574@google.com>
Message-ID: <7504130.baa3QaVrQb@phil>

Am Montag, 24. August 2015, 10:53:15 schrieb Brian Norris:
> On Thu, Aug 20, 2015 at 01:29:40AM +0200, Javier Martinez Canillas wrote:
> > Hello Brian,
> > 
> > [...]
> > 
> > > +
> > > +&rk808 {
> > > +       pinctrl-names = "default";
> > > +       pinctrl-0 = <&pmic_int_l &dvs_1 &dvs_2>;
> > > +       dvs-gpios = <&gpio7 12 GPIO_ACTIVE_HIGH>,
> > > +                   <&gpio7 15 GPIO_ACTIVE_HIGH>;
> > 
> > I see the dvs-gpios DT property is documented in the downstream
> > ChromiumOS 3.18 tree [0] but I don't see it neither mentioned in
> > Documentation/devicetree/bindings/mfd/rk808.txt in mainline nor code
> > that parses it in the drivers/regulator/rk808-regulator.c driver.
> 
> Good catch.
> 
> > So I think this should be removed and also the dvs_{1,2} pinctrl
> > lines.
> 
> OK, will do. I see that jerry, minnie, and speedy also have the pinctrl
> lines. Should they be killed as well?

Personally I think the pinctrl settings can stay. Their configuration is part 
of the hardware and not subject to the binding of the device using them.

And of course, the change to support them is already pending, with the binding 
itself already in the mfd tree.


So it doesn't matter to much if they're in there already or not, as we'll 
hopefully soon make use of them anyway.

> 
> > The rest of the patch looks good to me though so with these
> > removed feel free to add:
> > 
> > Reviewed-by: Javier Martinez Canillas <javier at osg.samsung.com>
> 
> Thanks.
> 
> > [0]:
> > https://chromium.googlesource.com/chromiumos/third_party/kernel/+/chromeo
> > s-3.14/Documentation/devicetree/bindings/mfd/rk808.txt
> Brian



From javier at dowhile0.org  Mon Aug 24 11:01:29 2015
From: javier at dowhile0.org (Javier Martinez Canillas)
Date: Mon, 24 Aug 2015 20:01:29 +0200
Subject: [PATCH v2 1/3] ARM: dts: rockchip: add veyron-jaq board
In-Reply-To: <7504130.baa3QaVrQb@phil>
References: <1440022721-73712-1-git-send-email-briannorris@chromium.org>
 <CABxcv=nQAfCzj_bQ9N-XYEPCNuihyrkUOz7=ogetKzye4KKNng@mail.gmail.com>
 <20150824175315.GA81574@google.com> <7504130.baa3QaVrQb@phil>
Message-ID: <CABxcv=nXwL6LV0vnjffA0JV4NB-_mCufe3-0c7fsRKW3DE+-_g@mail.gmail.com>

Hello Heiko,

On Mon, Aug 24, 2015 at 7:58 PM, Heiko Stuebner <heiko at sntech.de> wrote:
> Am Montag, 24. August 2015, 10:53:15 schrieb Brian Norris:
>> On Thu, Aug 20, 2015 at 01:29:40AM +0200, Javier Martinez Canillas wrote:
>> > Hello Brian,
>> >
>> > [...]
>> >
>> > > +
>> > > +&rk808 {
>> > > +       pinctrl-names = "default";
>> > > +       pinctrl-0 = <&pmic_int_l &dvs_1 &dvs_2>;
>> > > +       dvs-gpios = <&gpio7 12 GPIO_ACTIVE_HIGH>,
>> > > +                   <&gpio7 15 GPIO_ACTIVE_HIGH>;
>> >
>> > I see the dvs-gpios DT property is documented in the downstream
>> > ChromiumOS 3.18 tree [0] but I don't see it neither mentioned in
>> > Documentation/devicetree/bindings/mfd/rk808.txt in mainline nor code
>> > that parses it in the drivers/regulator/rk808-regulator.c driver.
>>
>> Good catch.
>>
>> > So I think this should be removed and also the dvs_{1,2} pinctrl
>> > lines.
>>
>> OK, will do. I see that jerry, minnie, and speedy also have the pinctrl
>> lines. Should they be killed as well?
>
> Personally I think the pinctrl settings can stay. Their configuration is part
> of the hardware and not subject to the binding of the device using them.
>
> And of course, the change to support them is already pending, with the binding
> itself already in the mfd tree.
>

I missed that the change to add support for this is already in the mfd tree.

>
> So it doesn't matter to much if they're in there already or not, as we'll
> hopefully soon make use of them anyway.
>

Agreed.

Best regards,
Javier


From Suravee.Suthikulpanit at amd.com  Mon Aug 24 11:02:31 2015
From: Suravee.Suthikulpanit at amd.com (Suravee Suthikulpanit)
Date: Tue, 25 Aug 2015 01:02:31 +0700
Subject: [PATCH] pci: acpi: Generic function for setting up PCI device DMA
 coherency
In-Reply-To: <CAErSpo4BzNgvVyEbFZWmQPR4KQsvMT1tRpT1mxPL=TymYSM3DQ@mail.gmail.com>
References: <1439459925-2361-1-git-send-email-Suravee.Suthikulpanit@amd.com>
 <55DB4939.5070605@amd.com>
 <CAErSpo4BzNgvVyEbFZWmQPR4KQsvMT1tRpT1mxPL=TymYSM3DQ@mail.gmail.com>
Message-ID: <55DB5C37.9020700@amd.com>

Hi,

On 8/25/15 00:32, Bjorn Helgaas wrote:
> On Mon, Aug 24, 2015 at 9:41 AM, Suravee Suthikulpanit
> <Suravee.Suthikulpanit at amd.com>  wrote:
>> >Hi,
>> >
>> >Ping. Does anyone have any comments or suggestions?
> Yes, I sent you some ideas a couple weeks ago.  I'll resend them.
>

Not sure how I missed that one. Sorry.

Thanks again,

Suravee


From briannorris at chromium.org  Mon Aug 24 11:06:23 2015
From: briannorris at chromium.org (Brian Norris)
Date: Mon, 24 Aug 2015 11:06:23 -0700
Subject: [PATCH v2 1/3] ARM: dts: rockchip: add veyron-jaq board
In-Reply-To: <CABxcv=nXwL6LV0vnjffA0JV4NB-_mCufe3-0c7fsRKW3DE+-_g@mail.gmail.com>
References: <1440022721-73712-1-git-send-email-briannorris@chromium.org>
 <CABxcv=nQAfCzj_bQ9N-XYEPCNuihyrkUOz7=ogetKzye4KKNng@mail.gmail.com>
 <20150824175315.GA81574@google.com> <7504130.baa3QaVrQb@phil>
 <CABxcv=nXwL6LV0vnjffA0JV4NB-_mCufe3-0c7fsRKW3DE+-_g@mail.gmail.com>
Message-ID: <20150824180623.GA84867@google.com>

On Mon, Aug 24, 2015 at 08:01:29PM +0200, Javier Martinez Canillas wrote:
> On Mon, Aug 24, 2015 at 7:58 PM, Heiko Stuebner <heiko at sntech.de> wrote:
> > Am Montag, 24. August 2015, 10:53:15 schrieb Brian Norris:
> >> On Thu, Aug 20, 2015 at 01:29:40AM +0200, Javier Martinez Canillas wrote:
> >> > [...]
> >> >
> >> > > +
> >> > > +&rk808 {
> >> > > +       pinctrl-names = "default";
> >> > > +       pinctrl-0 = <&pmic_int_l &dvs_1 &dvs_2>;
> >> > > +       dvs-gpios = <&gpio7 12 GPIO_ACTIVE_HIGH>,
> >> > > +                   <&gpio7 15 GPIO_ACTIVE_HIGH>;
> >> >
> >> > I see the dvs-gpios DT property is documented in the downstream
> >> > ChromiumOS 3.18 tree [0] but I don't see it neither mentioned in
> >> > Documentation/devicetree/bindings/mfd/rk808.txt in mainline nor code
> >> > that parses it in the drivers/regulator/rk808-regulator.c driver.
> >>
> >> Good catch.
> >>
> >> > So I think this should be removed and also the dvs_{1,2} pinctrl
> >> > lines.
> >>
> >> OK, will do. I see that jerry, minnie, and speedy also have the pinctrl
> >> lines. Should they be killed as well?
> >
> > Personally I think the pinctrl settings can stay. Their configuration is part
> > of the hardware and not subject to the binding of the device using them.
> >
> > And of course, the change to support them is already pending, with the binding
> > itself already in the mfd tree.
> >
> 
> I missed that the change to add support for this is already in the mfd tree.

Me too. So I'll leave all the dvs-* stuff as-is, then. This makes the
v2->v3 delta very small...

> >
> > So it doesn't matter to much if they're in there already or not, as we'll
> > hopefully soon make use of them anyway.
> >
> 
> Agreed.

Brian


From keescook at chromium.org  Mon Aug 24 11:06:52 2015
From: keescook at chromium.org (Kees Cook)
Date: Mon, 24 Aug 2015 11:06:52 -0700
Subject: Prevent list poison values from being mapped by userspace
 processes
In-Reply-To: <20150821133043.GV7557@n2100.arm.linux.org.uk>
References: <CABXk95C=CpeL4mNmS6-jJ-0bMJf6fawwfs6DM1-p8FctTEFbpw@mail.gmail.com>
 <20150821133043.GV7557@n2100.arm.linux.org.uk>
Message-ID: <CAGXu5jJ8KOoVkx99rrajEEx77Z6zO4TzCXaXkB74zv9QQFuJFw@mail.gmail.com>

On Fri, Aug 21, 2015 at 6:30 AM, Russell King - ARM Linux
<linux at arm.linux.org.uk> wrote:
> On Tue, Aug 18, 2015 at 02:42:44PM -0700, Jeffrey Vander Stoep wrote:
>> List poison pointer values point to memory that is mappable by
>> userspace. i.e. LIST_POISON1 = 0x00100100 and LIST_POISON2 =
>> 0x00200200. This means poison values can be valid pointers controlled
>> by userspace and can be used to exploit the kernel as demonstrated in
>> a recent blackhat talk:
>> https://www.blackhat.com/docs/us-15/materials/us-15-Xu-Ah-Universal-Android-Rooting-Is-Back-wp.pdf
>>
>> Can these poison values be moved to an area not mappable by userspace
>> on 32 bit ARM?
>
> As was discussed privately before your message, both Catalin and myself
> agreed that this is not possible, and I proposed alternatives which were
> feasible.
>
> I have now implemented the domain access alternative which I mentioned
> during that discussion, which is suitable for all non-LPAE setups, which
> has the effect of blocking almost all implicit kernel accesses to
> userspace, thereby substantially reducing the possibility for an attack
> similar to that given in the above paper.

What's the right solution for LPAE setups?

-Kees

>
> It should be said that with the following patches applied, it won't stop
> the original bug being used to crash the system (that's already been
> fixed) but it will prevent userspace being able to mask the crash, and
> therefore prevent such use-after-free bugs being used to gain privileges.
>
> This approach also covers low-vector CPUs as well, with one caveat: the
> lower 1MB of userspace will remain accessible to the kernel due to the
> need for the vectors to remain visible.  Doing otherwise crashes the
> machine on the first exception event.  So here, we offer a "best efforts"
> implementation rather than something which completely blocks userspace
> access from kernel space.
>
> This is not a simple fix - it's quite involved, and it changes a fair
> number of places in the kernel.  It needs time to be proven before any
> thought can be given to backporting these changes to stable kernels.
> It would be good to get some testing of these changes.
>
>  arch/arm/Kconfig                            | 15 +++++
>  arch/arm/include/asm/domain.h               | 45 +++++++++++----
>  arch/arm/include/asm/futex.h                | 19 ++++++-
>  arch/arm/include/asm/pgtable-2level-hwdef.h |  1 +
>  arch/arm/include/asm/thread_info.h          |  3 -
>  arch/arm/include/asm/uaccess.h              | 85 +++++++++++++++++++++++++++--
>  arch/arm/kernel/armksyms.c                  |  6 +-
>  arch/arm/kernel/entry-armv.S                | 27 ++++++---
>  arch/arm/kernel/entry-common.S              |  2 +
>  arch/arm/kernel/entry-header.S              | 42 ++++++++++++++
>  arch/arm/kernel/head.S                      |  5 +-
>  arch/arm/kernel/process.c                   | 37 ++++++++++---
>  arch/arm/kernel/traps.c                     |  1 -
>  arch/arm/lib/clear_user.S                   |  6 +-
>  arch/arm/lib/copy_from_user.S               |  6 +-
>  arch/arm/lib/copy_to_user.S                 |  6 +-
>  arch/arm/lib/uaccess_with_memcpy.c          |  4 +-
>  arch/arm/mm/mmu.c                           |  4 +-
>  arch/arm/mm/pgd.c                           | 10 ++++
>  19 files changed, 267 insertions(+), 57 deletions(-)
>
> --
> FTTC broadband for 0.8mile line: currently at 10.5Mbps down 400kbps up
> according to speedtest.net.
>
> _______________________________________________
> linux-arm-kernel mailing list
> linux-arm-kernel at lists.infradead.org
> http://lists.infradead.org/mailman/listinfo/linux-arm-kernel



-- 
Kees Cook
Chrome OS Security


From andre.przywara at arm.com  Mon Aug 24 11:08:19 2015
From: andre.przywara at arm.com (Andre Przywara)
Date: Mon, 24 Aug 2015 19:08:19 +0100
Subject: [PATCH v2 07/15] KVM: arm64: handle ITS related GICv3
 redistributor registers
In-Reply-To: <55CC8AE2.2070807@linaro.org>
References: <1436538111-4294-1-git-send-email-andre.przywara@arm.com>
 <1436538111-4294-8-git-send-email-andre.przywara@arm.com>
 <55CC8AE2.2070807@linaro.org>
Message-ID: <55DB5D93.3090007@arm.com>

Hi Eric,

On 13/08/15 13:17, Eric Auger wrote:
> On 07/10/2015 04:21 PM, Andre Przywara wrote:
>> In the GICv3 redistributor there are the PENDBASER and PROPBASER
>> registers which we did not emulate so far, as they only make sense
>> when having an ITS. In preparation for that emulate those MMIO
>> accesses by storing the 64-bit data written into it into a variable
>> which we later read in the ITS emulation.
>>
>> Signed-off-by: Andre Przywara <andre.przywara at arm.com>
>> ---
>>  include/kvm/arm_vgic.h      |  8 ++++++++
>>  virt/kvm/arm/vgic-v3-emul.c | 44 ++++++++++++++++++++++++++++++++++++++++++++
>>  virt/kvm/arm/vgic.c         | 35 +++++++++++++++++++++++++++++++++++
>>  virt/kvm/arm/vgic.h         |  4 ++++
>>  4 files changed, 91 insertions(+)
>>
>> diff --git a/include/kvm/arm_vgic.h b/include/kvm/arm_vgic.h
>> index 3ee063b..8c6cb0e 100644
>> --- a/include/kvm/arm_vgic.h
>> +++ b/include/kvm/arm_vgic.h
>> @@ -256,6 +256,14 @@ struct vgic_dist {
>>  	struct vgic_vm_ops	vm_ops;
>>  	struct vgic_io_device	dist_iodev;
>>  	struct vgic_io_device	*redist_iodevs;
>> +
>> +	/* Address of LPI configuration table shared by all redistributors */
>> +	u64			propbaser;
>> +
>> +	/* Addresses of LPI pending tables per redistributor */
>> +	u64			*pendbaser;
>> +
>> +	bool			lpis_enabled;
>>  };
>>  
>>  struct vgic_v2_cpu_if {
>> diff --git a/virt/kvm/arm/vgic-v3-emul.c b/virt/kvm/arm/vgic-v3-emul.c
>> index a8cf669..5269ad1 100644
>> --- a/virt/kvm/arm/vgic-v3-emul.c
>> +++ b/virt/kvm/arm/vgic-v3-emul.c
>> @@ -651,6 +651,38 @@ static bool handle_mmio_cfg_reg_redist(struct kvm_vcpu *vcpu,
>>  	return vgic_handle_cfg_reg(reg, mmio, offset);
>>  }
>>  
>> +/* We don't trigger any actions here, just store the register value */
>> +static bool handle_mmio_propbaser_redist(struct kvm_vcpu *vcpu,
>> +					 struct kvm_exit_mmio *mmio,
>> +					 phys_addr_t offset)
>> +{
>> +	struct vgic_dist *dist = &vcpu->kvm->arch.vgic;
>> +	int mode = ACCESS_READ_VALUE;
>> +
>> +	/* Storing a value with LPIs already enabled is undefined */
>> +	mode |= dist->lpis_enabled ? ACCESS_WRITE_IGNORED : ACCESS_WRITE_VALUE;
>> +	vgic_handle_base_register(vcpu, mmio, offset, &dist->propbaser, mode);
>> +
>> +	return false;
>> +}
>> +
>> +/* We don't trigger any actions here, just store the register value */
>> +static bool handle_mmio_pendbaser_redist(struct kvm_vcpu *vcpu,
>> +					 struct kvm_exit_mmio *mmio,
>> +					 phys_addr_t offset)
>> +{
>> +	struct kvm_vcpu *rdvcpu = mmio->private;
>> +	struct vgic_dist *dist = &vcpu->kvm->arch.vgic;
>> +	int mode = ACCESS_READ_VALUE;
>> +
>> +	/* Storing a value with LPIs already enabled is undefined */
>> +	mode |= dist->lpis_enabled ? ACCESS_WRITE_IGNORED : ACCESS_WRITE_VALUE;
>> +	vgic_handle_base_register(vcpu, mmio, offset,
>> +				  &dist->pendbaser[rdvcpu->vcpu_id], mode);
>> +
>> +	return false;
>> +}
>> +
>>  #define SGI_base(x) ((x) + SZ_64K)
>>  
>>  static const struct vgic_io_range vgic_redist_ranges[] = {
>> @@ -679,6 +711,18 @@ static const struct vgic_io_range vgic_redist_ranges[] = {
>>  		.handle_mmio    = handle_mmio_raz_wi,
>>  	},
>>  	{
>> +		.base		= GICR_PENDBASER,
>> +		.len		= 0x08,
>> +		.bits_per_irq	= 0,
>> +		.handle_mmio	= handle_mmio_pendbaser_redist,
>> +	},
>> +	{
>> +		.base		= GICR_PROPBASER,
>> +		.len		= 0x08,
>> +		.bits_per_irq	= 0,
>> +		.handle_mmio	= handle_mmio_propbaser_redist,
>> +	},
>> +	{
>>  		.base           = GICR_IDREGS,
>>  		.len            = 0x30,
>>  		.bits_per_irq   = 0,
>> diff --git a/virt/kvm/arm/vgic.c b/virt/kvm/arm/vgic.c
>> index 15e447f..49ee92b 100644
>> --- a/virt/kvm/arm/vgic.c
>> +++ b/virt/kvm/arm/vgic.c
>> @@ -446,6 +446,41 @@ void vgic_reg_access(struct kvm_exit_mmio *mmio, u32 *reg,
>>  	}
>>  }
>>  
>> +/* handle a 64-bit register access */
>> +void vgic_handle_base_register(struct kvm_vcpu *vcpu,
>> +			       struct kvm_exit_mmio *mmio,
>> +			       phys_addr_t offset, u64 *basereg,
>> +			       int mode)
>> +{
> why do we have vcpu in the proto? I don't see it used. Also if it were
> can't we fetch it from mmio->private?
> 
> why not renaming this into something like vgic_reg64_access as par
> vgic_reg_access 32b flavor above. vgic_handle* usually is the name of
> the region handler returning bool?

Makes sense, I both renamed the function and removed the vcpu parameter.
I need to check whether we need the vcpu to do some endianness checks in
the future, though. Using mmio->private would be a hack, then.

Cheers,
Andre.

> 
>> +	u32 reg;
>> +	u64 breg;
>> +
>> +	switch (offset & ~3) {
>> +	case 0x00:
>> +		breg = *basereg;
>> +		reg = lower_32_bits(breg);
>> +		vgic_reg_access(mmio, &reg, offset & 3, mode);
>> +		if (mmio->is_write && (mode & ACCESS_WRITE_VALUE)) {
>> +			breg &= GENMASK_ULL(63, 32);
>> +			breg |= reg;
>> +			*basereg = breg;
>> +		}
>> +		break;
>> +	case 0x04:
>> +		breg = *basereg;
>> +		reg = upper_32_bits(breg);
>> +		vgic_reg_access(mmio, &reg, offset & 3, mode);
>> +		if (mmio->is_write && (mode & ACCESS_WRITE_VALUE)) {
>> +			breg  = lower_32_bits(breg);
>> +			breg |= (u64)reg << 32;
>> +			*basereg = breg;
>> +		}
>> +		break;
>> +	}
>> +}
>> +
>> +
>> +
> some spare white lines
> 
> Best Regards
> 
> Eric
>>  bool handle_mmio_raz_wi(struct kvm_vcpu *vcpu, struct kvm_exit_mmio *mmio,
>>  			phys_addr_t offset)
>>  {
>> diff --git a/virt/kvm/arm/vgic.h b/virt/kvm/arm/vgic.h
>> index a093f5c..b2d791c 100644
>> --- a/virt/kvm/arm/vgic.h
>> +++ b/virt/kvm/arm/vgic.h
>> @@ -71,6 +71,10 @@ void vgic_reg_access(struct kvm_exit_mmio *mmio, u32 *reg,
>>  		     phys_addr_t offset, int mode);
>>  bool handle_mmio_raz_wi(struct kvm_vcpu *vcpu, struct kvm_exit_mmio *mmio,
>>  			phys_addr_t offset);
>> +void vgic_handle_base_register(struct kvm_vcpu *vcpu,
>> +			       struct kvm_exit_mmio *mmio,
>> +			       phys_addr_t offset, u64 *basereg,
>> +			       int mode);
>>  
>>  static inline
>>  u32 mmio_data_read(struct kvm_exit_mmio *mmio, u32 mask)
>>
> 


From Shenwei.Wang at freescale.com  Mon Aug 24 11:25:07 2015
From: Shenwei.Wang at freescale.com (Shenwei Wang)
Date: Mon, 24 Aug 2015 18:25:07 +0000
Subject: [PATCH v8 1/2] irqchip: imx-gpcv2: IMX GPCv2 driver for wakeup
 sources
In-Reply-To: <alpine.DEB.2.11.1508241933150.3873@nanos>
References: <1438378439-11569-1-git-send-email-shenwei.wang@freescale.com>
 <1438378439-11569-2-git-send-email-shenwei.wang@freescale.com>
 <alpine.DEB.2.11.1508231251040.3873@nanos>
 <CY1PR0301MB084328829F8128A8FBFA6A9283620@CY1PR0301MB0843.namprd03.prod.outlook.com>
 <alpine.DEB.2.11.1508241933150.3873@nanos>
Message-ID: <BY1PR0301MB0839B8F390ABA092FB80362083620@BY1PR0301MB0839.namprd03.prod.outlook.com>



> -----Original Message-----
> From: Thomas Gleixner [mailto:tglx at linutronix.de]
> > > > +static int gpcv2_wakeup_source_save(void) {
> > > > +	struct gpcv2_irqchip_data *cd;
> > > > +	void __iomem *reg;
> > > > +	int i;
> > > > +
> > > > +	cd = imx_gpcv2_instance;
> > > > +	if (!cd)
> > > > +		return 0;
> > > > +
> > > > +	for (i = 0; i < IMR_NUM; i++) {
> > > > +		reg = cd->gpc_base + cd->cpu2wakeup + i * 4;
> > > > +		cd->enabled_irqs[i] = readl_relaxed(reg);
> > >
> > > You read the full state of the register and restore the full state.
> > > So why enabled_irqs?
> >
> > There are two user scenarios:
> > In CPU Idle state, the system need to be woke up by any enabled irqs,
> > not just the ones that marked as wakeup sources.
> > In Suspend State, they system will only be woke up by the one that
> > marked as a wakeup source.  Enabled_irqs are used to save the values
> > before suspend, and restore them after resume.
> 
> That's what you want achieve. Still you save the full content of the registers and
> restore the full content. That saves/restores the enabled and disabled interrupts.
> So enabled_irqs is a misnomer as you save the full state.

How about change its name to "saved_irq_mask"?

> > > set_wake() or leave it when they want to have resume functionality?
> > >
> > Each time system goes into the suspend state, it will call set_wake
> > (ON) again to configure the wakeup sources. Clearing wakeup_sources
> > here can make sure the system work as expected no matter that a driver
> > calls set_wake (OFF) during resume stage.
> 
> We rather make sure that the drivers call set_wake(OFF) as they are supposed to,
> because if they do not then the set_wake(ON) logic in the core code will see the
> counter != 0 and not invoke the irq callback.

Sounds reasonable. Then I will remove this line in new patch.

Thanks,
Shenwei

> Thanks,
> 
> 	tglx


From tglx at linutronix.de  Mon Aug 24 11:31:42 2015
From: tglx at linutronix.de (Thomas Gleixner)
Date: Mon, 24 Aug 2015 20:31:42 +0200 (CEST)
Subject: [PATCH v8 1/2] irqchip: imx-gpcv2: IMX GPCv2 driver for wakeup
 sources
In-Reply-To: <BY1PR0301MB0839B8F390ABA092FB80362083620@BY1PR0301MB0839.namprd03.prod.outlook.com>
References: <1438378439-11569-1-git-send-email-shenwei.wang@freescale.com>
 <1438378439-11569-2-git-send-email-shenwei.wang@freescale.com>
 <alpine.DEB.2.11.1508231251040.3873@nanos>
 <CY1PR0301MB084328829F8128A8FBFA6A9283620@CY1PR0301MB0843.namprd03.prod.outlook.com>
 <alpine.DEB.2.11.1508241933150.3873@nanos>
 <BY1PR0301MB0839B8F390ABA092FB80362083620@BY1PR0301MB0839.namprd03.prod.outlook.com>
Message-ID: <alpine.DEB.2.11.1508242031050.15006@nanos>

On Mon, 24 Aug 2015, Shenwei Wang wrote:
> > That's what you want achieve. Still you save the full content of the registers and
> > restore the full content. That saves/restores the enabled and disabled interrupts.
> > So enabled_irqs is a misnomer as you save the full state.
> 
> How about change its name to "saved_irq_mask"?

Way better.
 
Thanks,
 
 	tglx



From f.fainelli at gmail.com  Mon Aug 24 11:33:29 2015
From: f.fainelli at gmail.com (Florian Fainelli)
Date: Mon, 24 Aug 2015 11:33:29 -0700
Subject: [PATCH 05/18] ARM: BCM: use const and __initconst for
 smp_operations
In-Reply-To: <1440390978-22796-6-git-send-email-yamada.masahiro@socionext.com>
References: <1440390978-22796-1-git-send-email-yamada.masahiro@socionext.com>
 <1440390978-22796-6-git-send-email-yamada.masahiro@socionext.com>
Message-ID: <55DB6379.7040009@gmail.com>

On 23/08/15 21:36, Masahiro Yamada wrote:
> The smp_operations structure is not over-written, so add const
> qualifier and replace __initdata with __initconst.
> 
> Also, add static to bcm63138_smp_ops.
> 
> Signed-off-by: Masahiro Yamada <yamada.masahiro at socionext.com>

For bcm63xx and brcmstb:

Reviewed-by: Florian Fainelli <f.fainelli at gmail.com>

> ---
> 
>  arch/arm/mach-bcm/bcm63xx_smp.c     | 2 +-
>  arch/arm/mach-bcm/kona_smp.c        | 2 +-
>  arch/arm/mach-bcm/platsmp-brcmstb.c | 2 +-
>  3 files changed, 3 insertions(+), 3 deletions(-)
> 
> diff --git a/arch/arm/mach-bcm/bcm63xx_smp.c b/arch/arm/mach-bcm/bcm63xx_smp.c
> index 19be904..9b6727e 100644
> --- a/arch/arm/mach-bcm/bcm63xx_smp.c
> +++ b/arch/arm/mach-bcm/bcm63xx_smp.c
> @@ -161,7 +161,7 @@ static void __init bcm63138_smp_prepare_cpus(unsigned int max_cpus)
>  	}
>  }
>  
> -struct smp_operations bcm63138_smp_ops __initdata = {
> +static const struct smp_operations bcm63138_smp_ops __initconst = {
>  	.smp_prepare_cpus	= bcm63138_smp_prepare_cpus,
>  	.smp_boot_secondary	= bcm63138_smp_boot_secondary,
>  };
> diff --git a/arch/arm/mach-bcm/kona_smp.c b/arch/arm/mach-bcm/kona_smp.c
> index 66a0465..da8328b 100644
> --- a/arch/arm/mach-bcm/kona_smp.c
> +++ b/arch/arm/mach-bcm/kona_smp.c
> @@ -194,7 +194,7 @@ static int bcm_boot_secondary(unsigned int cpu, struct task_struct *idle)
>  	return -ENOSYS;
>  }
>  
> -static struct smp_operations bcm_smp_ops __initdata = {
> +static const struct smp_operations bcm_smp_ops __initconst = {
>  	.smp_prepare_cpus	= bcm_smp_prepare_cpus,
>  	.smp_boot_secondary	= bcm_boot_secondary,
>  };
> diff --git a/arch/arm/mach-bcm/platsmp-brcmstb.c b/arch/arm/mach-bcm/platsmp-brcmstb.c
> index 44d6bddf..40dc844 100644
> --- a/arch/arm/mach-bcm/platsmp-brcmstb.c
> +++ b/arch/arm/mach-bcm/platsmp-brcmstb.c
> @@ -356,7 +356,7 @@ static int brcmstb_boot_secondary(unsigned int cpu, struct task_struct *idle)
>  	return 0;
>  }
>  
> -static struct smp_operations brcmstb_smp_ops __initdata = {
> +static const struct smp_operations brcmstb_smp_ops __initconst = {
>  	.smp_prepare_cpus	= brcmstb_cpu_ctrl_setup,
>  	.smp_boot_secondary	= brcmstb_boot_secondary,
>  #ifdef CONFIG_HOTPLUG_CPU
> 


-- 
Florian


From punnaia at xilinx.com  Mon Aug 24 11:39:16 2015
From: punnaia at xilinx.com (punnaiah choudary kalluri)
Date: Tue, 25 Aug 2015 00:09:16 +0530
Subject: [PATCH v4 1/2] Documentation: dt: Add Xilinx zynqmp dma device
 tree binding documentation
In-Reply-To: <55DB205D.7090802@metafoo.de>
References: <1438831173-8761-1-git-send-email-punnaia@xilinx.com>
 <55DB205D.7090802@metafoo.de>
Message-ID: <CAGnW=Bb-vwvwAm7ztH1XLqRHbVx+5MWZJd=fDgOoqJ7Qtyo=nw@mail.gmail.com>

On Mon, Aug 24, 2015 at 7:17 PM, Lars-Peter Clausen <lars at metafoo.de> wrote:
> On 08/06/2015 05:19 AM, Punnaiah Choudary Kalluri wrote:
> [...]
>> +Optional properties:
>> +- xlnx,include-sg: Indicates the controller to operate in simple or scatter
>> +                gather dma mode
>> +- xlnx,ratectrl: Scheduling interval in terms of clock cycles for
>> +              source AXI transaction
>> +- xlnx,overfetch: Tells whether the channel is allowed to over fetch the data
>> +- xlnx,src-issue: Number of AXI outstanding transactions on source side
>> +- xlnx,desc-axi-cohrnt: Tells whether the AXI transactions generated for the
>> +                     descriptor read are marked Non-coherent
>> +- xlnx,src-axi-cohrnt: Tells whether the AXI transactions generated for the
>> +                     source descriptor payload are marked Non-coherent
>> +- xlnx,dst-axi-cohrnt: Tells whether the AXI transactions generated for the
>> +                     dst descriptor payload are marked Non-coherent
>> +- xlnx,desc-axi-qos: AXI QOS bits to be used for descriptor fetch
>> +- xlnx,src-axi-qos: AXI QOS bits to be used for data read
>> +- xlnx,dst-axi-qos: AXI QOS bits to be used for data write
>> +- xlnx,desc-axi-cache: AXI cache bits to be used for descriptor fetch.
>> +- xlnx,desc-axi-cache: AXI cache bits to be used for data read
>> +- xlnx,desc-axi-cache: AXI cache bits to be used for data write
>> +- xlnx,src-burst-len: AXI length for data read. Support only power of 2 values
>> +                   i.e 1,2,4,8 and 16
>> +- xlnx,dst-burst-len: AXI length for data write. Support only power of 2 values
>> +                   i.e 1,2,4,8 and 16
>
> None of these really belong into the devicetree. This is all runtime
> configuration data.

This is a general purpose dma and provides more flexibility to the
user for configuring the
descriptor, data and bus parameters. one way is as you said these
parameters can be
configured at runtime but i didn't find a way configuring the channel
at runtime for mem to
mem transfers. I have checked the  device_config function description
and it is strictly
meant for slave operations only. So, i didn't see anything wrong
having these parameter values
from the device tree as these all are hw parameters.

Regards,
Punnaiah

>
> - Lars


From linux at arm.linux.org.uk  Mon Aug 24 11:47:10 2015
From: linux at arm.linux.org.uk (Russell King - ARM Linux)
Date: Mon, 24 Aug 2015 19:47:10 +0100
Subject: Prevent list poison values from being mapped by userspace
 processes
In-Reply-To: <CAGXu5jJ8KOoVkx99rrajEEx77Z6zO4TzCXaXkB74zv9QQFuJFw@mail.gmail.com>
References: <CABXk95C=CpeL4mNmS6-jJ-0bMJf6fawwfs6DM1-p8FctTEFbpw@mail.gmail.com>
 <20150821133043.GV7557@n2100.arm.linux.org.uk>
 <CAGXu5jJ8KOoVkx99rrajEEx77Z6zO4TzCXaXkB74zv9QQFuJFw@mail.gmail.com>
Message-ID: <20150824184709.GE7557@n2100.arm.linux.org.uk>

On Mon, Aug 24, 2015 at 11:06:52AM -0700, Kees Cook wrote:
> On Fri, Aug 21, 2015 at 6:30 AM, Russell King - ARM Linux
> <linux at arm.linux.org.uk> wrote:
> > On Tue, Aug 18, 2015 at 02:42:44PM -0700, Jeffrey Vander Stoep wrote:
> >> List poison pointer values point to memory that is mappable by
> >> userspace. i.e. LIST_POISON1 = 0x00100100 and LIST_POISON2 =
> >> 0x00200200. This means poison values can be valid pointers controlled
> >> by userspace and can be used to exploit the kernel as demonstrated in
> >> a recent blackhat talk:
> >> https://www.blackhat.com/docs/us-15/materials/us-15-Xu-Ah-Universal-Android-Rooting-Is-Back-wp.pdf
> >>
> >> Can these poison values be moved to an area not mappable by userspace
> >> on 32 bit ARM?
> >
> > As was discussed privately before your message, both Catalin and myself
> > agreed that this is not possible, and I proposed alternatives which were
> > feasible.
> >
> > I have now implemented the domain access alternative which I mentioned
> > during that discussion, which is suitable for all non-LPAE setups, which
> > has the effect of blocking almost all implicit kernel accesses to
> > userspace, thereby substantially reducing the possibility for an attack
> > similar to that given in the above paper.
> 
> What's the right solution for LPAE setups?

That's something which Catalin indicated that he'll work on.  However,
he said in a public email last week that he won't be around for a while.

So, I have no immediate solution for LPAE - it looks like LPAE will
require switching the page tables on kernel entry or exit, and again
each and every time we want to perform a userspace access.  How this
is done is not something that has been discussed, and neither do we
yet know how expensive this will be.  There are a number of places in
the kernel where a large number of get_user()s or put_user()s follow
one after each other, which necessitates switching back and forth
multiple times.  We may need to address some of those areas by
converting them to copy_(to|from)_user().

-- 
FTTC broadband for 0.8mile line: currently at 10.5Mbps down 400kbps up
according to speedtest.net.


From keescook at chromium.org  Mon Aug 24 11:51:04 2015
From: keescook at chromium.org (Kees Cook)
Date: Mon, 24 Aug 2015 11:51:04 -0700
Subject: Prevent list poison values from being mapped by userspace
 processes
In-Reply-To: <20150824184709.GE7557@n2100.arm.linux.org.uk>
References: <CABXk95C=CpeL4mNmS6-jJ-0bMJf6fawwfs6DM1-p8FctTEFbpw@mail.gmail.com>
 <20150821133043.GV7557@n2100.arm.linux.org.uk>
 <CAGXu5jJ8KOoVkx99rrajEEx77Z6zO4TzCXaXkB74zv9QQFuJFw@mail.gmail.com>
 <20150824184709.GE7557@n2100.arm.linux.org.uk>
Message-ID: <CAGXu5jJFf+9OgnGt_Cx5Q-Pht7LAT7M-sSXftTDORybrr+SECg@mail.gmail.com>

On Mon, Aug 24, 2015 at 11:47 AM, Russell King - ARM Linux
<linux at arm.linux.org.uk> wrote:
> On Mon, Aug 24, 2015 at 11:06:52AM -0700, Kees Cook wrote:
>> On Fri, Aug 21, 2015 at 6:30 AM, Russell King - ARM Linux
>> <linux at arm.linux.org.uk> wrote:
>> > On Tue, Aug 18, 2015 at 02:42:44PM -0700, Jeffrey Vander Stoep wrote:
>> >> List poison pointer values point to memory that is mappable by
>> >> userspace. i.e. LIST_POISON1 = 0x00100100 and LIST_POISON2 =
>> >> 0x00200200. This means poison values can be valid pointers controlled
>> >> by userspace and can be used to exploit the kernel as demonstrated in
>> >> a recent blackhat talk:
>> >> https://www.blackhat.com/docs/us-15/materials/us-15-Xu-Ah-Universal-Android-Rooting-Is-Back-wp.pdf
>> >>
>> >> Can these poison values be moved to an area not mappable by userspace
>> >> on 32 bit ARM?
>> >
>> > As was discussed privately before your message, both Catalin and myself
>> > agreed that this is not possible, and I proposed alternatives which were
>> > feasible.
>> >
>> > I have now implemented the domain access alternative which I mentioned
>> > during that discussion, which is suitable for all non-LPAE setups, which
>> > has the effect of blocking almost all implicit kernel accesses to
>> > userspace, thereby substantially reducing the possibility for an attack
>> > similar to that given in the above paper.
>>
>> What's the right solution for LPAE setups?
>
> That's something which Catalin indicated that he'll work on.  However,
> he said in a public email last week that he won't be around for a while.
>
> So, I have no immediate solution for LPAE - it looks like LPAE will
> require switching the page tables on kernel entry or exit, and again
> each and every time we want to perform a userspace access.  How this
> is done is not something that has been discussed, and neither do we
> yet know how expensive this will be.  There are a number of places in
> the kernel where a large number of get_user()s or put_user()s follow
> one after each other, which necessitates switching back and forth
> multiple times.  We may need to address some of those areas by
> converting them to copy_(to|from)_user().

By the way, have you looked at grsecurity's implementation of these
protections? They've been using domains for a while now, and I think
have an LPAE solution as well.

The original description of the work was here:
https://forums.grsecurity.net/viewtopic.php?f=7&t=3292

-Kees

-- 
Kees Cook
Chrome OS Security


From robherring2 at gmail.com  Mon Aug 24 11:53:38 2015
From: robherring2 at gmail.com (Rob Herring)
Date: Mon, 24 Aug 2015 13:53:38 -0500
Subject: [PATCH v4 1/2] Documentation: dt: Add Xilinx zynqmp dma device
 tree binding documentation
In-Reply-To: <1438831173-8761-1-git-send-email-punnaia@xilinx.com>
References: <1438831173-8761-1-git-send-email-punnaia@xilinx.com>
Message-ID: <CAL_Jsq+261JzSorbgEyQ4BFCHbsFsBaJQnpWJX-G=SX3yhqZJw@mail.gmail.com>

On Wed, Aug 5, 2015 at 10:19 PM, Punnaiah Choudary Kalluri
<punnaiah.choudary.kalluri at xilinx.com> wrote:
> Device-tree binding documentation for Xilinx zynqmp dma engine used in
> Zynq UltraScale+ MPSoC.
>
> Signed-off-by: Punnaiah Choudary Kalluri <punnaia at xilinx.com>
> ---
> Changes in v4:
> - None
> Changes in v3:
> - None
> Changes in v2:
> - None
> ---
>  .../devicetree/bindings/dma/xilinx/zynqmp_dma.txt  |   61 ++++++++++++++++++++
>  1 files changed, 61 insertions(+), 0 deletions(-)
>  create mode 100644 Documentation/devicetree/bindings/dma/xilinx/zynqmp_dma.txt
>
> diff --git a/Documentation/devicetree/bindings/dma/xilinx/zynqmp_dma.txt b/Documentation/devicetree/bindings/dma/xilinx/zynqmp_dma.txt
> new file mode 100644
> index 0000000..e4f92b9
> --- /dev/null
> +++ b/Documentation/devicetree/bindings/dma/xilinx/zynqmp_dma.txt
> @@ -0,0 +1,61 @@
> +Xilinx ZynqMP DMA engine, it does support memory to memory transfers,
> +memory to device and device to memory transfers. It also has flow
> +control and rate control support for slave/peripheral dma access.
> +
> +Required properties:
> +- compatible: Should be "xlnx,zynqmp-dma-1.0"
> +- #dma-cells: Should be <1>, a single cell holding a line request number
> +- reg: Memory map for module access
> +- interrupt-parent: Interrupt controller the interrupt is routed through
> +- interrupts: Should contain DMA channel interrupt
> +- xlnx,bus-width: AXI buswidth in bits. Should contain 128 or 64
> +
> +Optional properties:
> +- xlnx,include-sg: Indicates the controller to operate in simple or scatter
> +                  gather dma mode
> +- xlnx,ratectrl: Scheduling interval in terms of clock cycles for
> +                source AXI transaction
> +- xlnx,overfetch: Tells whether the channel is allowed to over fetch the data
> +- xlnx,src-issue: Number of AXI outstanding transactions on source side
> +- xlnx,desc-axi-cohrnt: Tells whether the AXI transactions generated for the
> +                       descriptor read are marked Non-coherent
> +- xlnx,src-axi-cohrnt: Tells whether the AXI transactions generated for the
> +                       source descriptor payload are marked Non-coherent
> +- xlnx,dst-axi-cohrnt: Tells whether the AXI transactions generated for the
> +                       dst descriptor payload are marked Non-coherent

Do you really need 3? dma-coherent property doesn't work for you?

Not that it should dictate the binding, but the kernel doesn't support
a device needing both coherent and non-coherent DMA ops.

> +- xlnx,desc-axi-qos: AXI QOS bits to be used for descriptor fetch
> +- xlnx,src-axi-qos: AXI QOS bits to be used for data read
> +- xlnx,dst-axi-qos: AXI QOS bits to be used for data write
> +- xlnx,desc-axi-cache: AXI cache bits to be used for descriptor fetch.
> +- xlnx,desc-axi-cache: AXI cache bits to be used for data read
> +- xlnx,desc-axi-cache: AXI cache bits to be used for data write

These signals are generally part of the coherent or not setting. This
allows for potentially invalid combinations.

Plus you have a copy/paste error.

> +- xlnx,src-burst-len: AXI length for data read. Support only power of 2 values
> +                     i.e 1,2,4,8 and 16
> +- xlnx,dst-burst-len: AXI length for data write. Support only power of 2 values
> +                     i.e 1,2,4,8 and 16
> +
> +Example:
> +++++++++
> +fpd_dma_chan1: dma at FD500000 {
> +       compatible = "xlnx,zynqmp-dma-1.0";
> +       reg = <0x0 0xFD500000 0x1000>;
> +       #dma_cells = <1>;
> +       interrupt-parent = <&gic>;
> +       interrupts = <0 117 4>;
> +       xlnx,bus-width = <128>;
> +       xlnx,include-sg;
> +       xlnx,overfetch;
> +       xlnx,ratectrl = <0>;
> +       xlnx,src-issue = <16>;
> +       xlnx,desc-axi-cohrnt;
> +       xlnx,src-axi-cohrnt;
> +       xlnx,dst-axi-cohrnt;
> +       xlnx,desc-axi-qos = <0>;
> +       xlnx,desc-axi-cache = <0>;
> +       xlnx,src-axi-qos = <0>;
> +       xlnx,src-axi-cache = <2>;
> +       xlnx,dst-axi-qos = <0>;
> +       xlnx,dst-axi-cache = <2>;
> +       xlnx,src-burst-len = <4>;
> +       xlnx,dst-burst-len = <4>;
> +};
> --
> 1.7.4
>
>
> _______________________________________________
> linux-arm-kernel mailing list
> linux-arm-kernel at lists.infradead.org
> http://lists.infradead.org/mailman/listinfo/linux-arm-kernel


From vaibhav.hiremath at linaro.org  Mon Aug 24 11:56:28 2015
From: vaibhav.hiremath at linaro.org (Vaibhav Hiremath)
Date: Tue, 25 Aug 2015 00:26:28 +0530
Subject: [PATCH-v2 0/5] clk: 88pm800: Add new clk provider driver for 88PM800
 MFD
Message-ID: <1440442594-3102-1-git-send-email-vaibhav.hiremath@linaro.org>

88PM800 family of devices provides multiple buffered 32.768 KHz clock
output.
88PM800 : CLK32k_1, CLK32k_2 and CLK32k_3
88PM860 : CLK32k_1 and CLK32k_2

This patch-series adds new clock provider driver for enabling/disabling
buffered 32Khz clock output from 88PM800 family of device. Adds clock device to
MFD and updates the binding documentation.

The PATCH [1/4], created separately, as it would be easy between maintainers to
queue it.


Note that, I have access to only 88PM800 and 88PM860 datasheet,
so enabling support for only above two devices.

Testing:
  - Boot tested on 88PM860 based platform
  - Clock enable/disable
  - Non PM860, to make sure that it won't lead to any issues

V1 => V2:
========
Link to  V1: https://lkml.org/lkml/2015/7/21/298

  - Added new patch to the series [1/5], fixing tabbing issue in the file
  - Removed unnecessary brackets around macro value
  - Used devm_kcalloc variants for array allocation instead of kzalloc.
  - Fixed all other trivial issues.

Vaibhav Hiremath (5):
  mfd: 88pm800: Fix tabbing issue
  mfd: 88pm800: Update the header file with 32K clk related macros
  mfd: devicetree: bindings: Add clock subdevice node information
  clk: 88pm800: Add clk provider driver for 88pm800 family of devices
  mfd: 88pm800: Add support for clk subdevice

 Documentation/devicetree/bindings/mfd/88pm800.txt |  27 ++
 drivers/clk/Kconfig                               |   8 +
 drivers/clk/Makefile                              |   1 +
 drivers/clk/clk-88pm800.c                         | 341 ++++++++++++++++++++++
 drivers/mfd/88pm800.c                             | 150 ++++++----
 include/linux/mfd/88pm80x.h                       |  12 +
 6 files changed, 475 insertions(+), 64 deletions(-)
 create mode 100644 drivers/clk/clk-88pm800.c

-- 
1.9.1



From vaibhav.hiremath at linaro.org  Mon Aug 24 11:56:29 2015
From: vaibhav.hiremath at linaro.org (Vaibhav Hiremath)
Date: Tue, 25 Aug 2015 00:26:29 +0530
Subject: [PATCH-v2 1/5] mfd: 88pm800: Fix tabbing issue
In-Reply-To: <1440442594-3102-1-git-send-email-vaibhav.hiremath@linaro.org>
References: <1440442594-3102-1-git-send-email-vaibhav.hiremath@linaro.org>
Message-ID: <1440442594-3102-2-git-send-email-vaibhav.hiremath@linaro.org>

Driver had coding style issues where spaces were used instead
of tabs. This patch fixes them all.

Signed-off-by: Vaibhav Hiremath <vaibhav.hiremath at linaro.org>
---
 drivers/mfd/88pm800.c | 125 ++++++++++++++++++++++++--------------------------
 1 file changed, 61 insertions(+), 64 deletions(-)

diff --git a/drivers/mfd/88pm800.c b/drivers/mfd/88pm800.c
index f104a32..c4e097d 100644
--- a/drivers/mfd/88pm800.c
+++ b/drivers/mfd/88pm800.c
@@ -30,55 +30,55 @@
 #include <linux/of_device.h>
 
 /* Interrupt Registers */
-#define PM800_INT_STATUS1		(0x05)
+#define PM800_INT_STATUS1		0x05
 #define PM800_ONKEY_INT_STS1		(1 << 0)
 #define PM800_EXTON_INT_STS1		(1 << 1)
-#define PM800_CHG_INT_STS1			(1 << 2)
-#define PM800_BAT_INT_STS1			(1 << 3)
-#define PM800_RTC_INT_STS1			(1 << 4)
+#define PM800_CHG_INT_STS1		(1 << 2)
+#define PM800_BAT_INT_STS1		(1 << 3)
+#define PM800_RTC_INT_STS1		(1 << 4)
 #define PM800_CLASSD_OC_INT_STS1	(1 << 5)
 
-#define PM800_INT_STATUS2		(0x06)
+#define PM800_INT_STATUS2		0x06
 #define PM800_VBAT_INT_STS2		(1 << 0)
 #define PM800_VSYS_INT_STS2		(1 << 1)
 #define PM800_VCHG_INT_STS2		(1 << 2)
 #define PM800_TINT_INT_STS2		(1 << 3)
-#define PM800_GPADC0_INT_STS2	(1 << 4)
+#define PM800_GPADC0_INT_STS2		(1 << 4)
 #define PM800_TBAT_INT_STS2		(1 << 5)
-#define PM800_GPADC2_INT_STS2	(1 << 6)
-#define PM800_GPADC3_INT_STS2	(1 << 7)
+#define PM800_GPADC2_INT_STS2		(1 << 6)
+#define PM800_GPADC3_INT_STS2		(1 << 7)
 
-#define PM800_INT_STATUS3		(0x07)
+#define PM800_INT_STATUS3		0x07
 
-#define PM800_INT_STATUS4		(0x08)
+#define PM800_INT_STATUS4		0x08
 #define PM800_GPIO0_INT_STS4		(1 << 0)
 #define PM800_GPIO1_INT_STS4		(1 << 1)
 #define PM800_GPIO2_INT_STS4		(1 << 2)
 #define PM800_GPIO3_INT_STS4		(1 << 3)
 #define PM800_GPIO4_INT_STS4		(1 << 4)
 
-#define PM800_INT_ENA_1		(0x09)
+#define PM800_INT_ENA_1			0x09
 #define PM800_ONKEY_INT_ENA1		(1 << 0)
 #define PM800_EXTON_INT_ENA1		(1 << 1)
-#define PM800_CHG_INT_ENA1			(1 << 2)
-#define PM800_BAT_INT_ENA1			(1 << 3)
-#define PM800_RTC_INT_ENA1			(1 << 4)
+#define PM800_CHG_INT_ENA1		(1 << 2)
+#define PM800_BAT_INT_ENA1		(1 << 3)
+#define PM800_RTC_INT_ENA1		(1 << 4)
 #define PM800_CLASSD_OC_INT_ENA1	(1 << 5)
 
-#define PM800_INT_ENA_2		(0x0A)
+#define PM800_INT_ENA_2			0x0A
 #define PM800_VBAT_INT_ENA2		(1 << 0)
 #define PM800_VSYS_INT_ENA2		(1 << 1)
 #define PM800_VCHG_INT_ENA2		(1 << 2)
 #define PM800_TINT_INT_ENA2		(1 << 3)
 
-#define PM800_INT_ENA_3		(0x0B)
+#define PM800_INT_ENA_3			0x0B
 #define PM800_GPADC0_INT_ENA3		(1 << 0)
 #define PM800_GPADC1_INT_ENA3		(1 << 1)
 #define PM800_GPADC2_INT_ENA3		(1 << 2)
 #define PM800_GPADC3_INT_ENA3		(1 << 3)
 #define PM800_GPADC4_INT_ENA3		(1 << 4)
 
-#define PM800_INT_ENA_4		(0x0C)
+#define PM800_INT_ENA_4			0x0C
 #define PM800_GPIO0_INT_ENA4		(1 << 0)
 #define PM800_GPIO1_INT_ENA4		(1 << 1)
 #define PM800_GPIO2_INT_ENA4		(1 << 2)
@@ -86,7 +86,7 @@
 #define PM800_GPIO4_INT_ENA4		(1 << 4)
 
 /* number of INT_ENA & INT_STATUS regs */
-#define PM800_INT_REG_NUM			(4)
+#define PM800_INT_REG_NUM		4
 
 /* Interrupt Number in 88PM800 */
 enum {
@@ -114,7 +114,7 @@ enum {
 };
 
 /* PM800: generation identification number */
-#define PM800_CHIP_GEN_ID_NUM	0x3
+#define PM800_CHIP_GEN_ID_NUM		0x3
 
 static const struct i2c_device_id pm80x_id_table[] = {
 	{"88PM800", 0},
@@ -129,47 +129,47 @@ static const struct of_device_id pm80x_of_match_table[] = {
 
 static struct resource rtc_resources[] = {
 	{
-	 .name = "88pm80x-rtc",
-	 .start = PM800_IRQ_RTC,
-	 .end = PM800_IRQ_RTC,
-	 .flags = IORESOURCE_IRQ,
-	 },
+		.name = "88pm80x-rtc",
+		.start = PM800_IRQ_RTC,
+		.end = PM800_IRQ_RTC,
+		.flags = IORESOURCE_IRQ,
+	},
 };
 
 static struct mfd_cell rtc_devs[] = {
 	{
-	 .name = "88pm80x-rtc",
-	 .of_compatible = "marvell,88pm80x-rtc",
-	 .num_resources = ARRAY_SIZE(rtc_resources),
-	 .resources = &rtc_resources[0],
-	 .id = -1,
-	 },
+		.name = "88pm80x-rtc",
+		.of_compatible = "marvell,88pm80x-rtc",
+		.num_resources = ARRAY_SIZE(rtc_resources),
+		.resources = &rtc_resources[0],
+		.id = -1,
+	},
 };
 
 static struct resource onkey_resources[] = {
 	{
-	 .name = "88pm80x-onkey",
-	 .start = PM800_IRQ_ONKEY,
-	 .end = PM800_IRQ_ONKEY,
-	 .flags = IORESOURCE_IRQ,
-	 },
+		.name = "88pm80x-onkey",
+		.start = PM800_IRQ_ONKEY,
+		.end = PM800_IRQ_ONKEY,
+		.flags = IORESOURCE_IRQ,
+	},
 };
 
 static const struct mfd_cell onkey_devs[] = {
 	{
-	 .name = "88pm80x-onkey",
-	 .of_compatible = "marvell,88pm80x-onkey",
-	 .num_resources = 1,
-	 .resources = &onkey_resources[0],
-	 .id = -1,
-	 },
+		.name = "88pm80x-onkey",
+		.of_compatible = "marvell,88pm80x-onkey",
+		.num_resources = 1,
+		.resources = &onkey_resources[0],
+		.id = -1,
+	},
 };
 
 static const struct mfd_cell regulator_devs[] = {
 	{
-	 .name = "88pm80x-regulator",
-	 .of_compatible = "marvell,88pm80x-regulator",
-	 .id = -1,
+		.name = "88pm80x-regulator",
+		.of_compatible = "marvell,88pm80x-regulator",
+		.id = -1,
 	},
 };
 
@@ -323,8 +323,8 @@ out:
 static int device_onkey_init(struct pm80x_chip *chip)
 {
 	return mfd_add_devices(chip->dev, 0, &onkey_devs[0],
-			      ARRAY_SIZE(onkey_devs), &onkey_resources[0], 0,
-			      NULL);
+			ARRAY_SIZE(onkey_devs), &onkey_resources[0], 0,
+			NULL);
 }
 
 static int device_rtc_init(struct pm80x_chip *chip)
@@ -335,13 +335,13 @@ static int device_rtc_init(struct pm80x_chip *chip)
 	rtc_devs[0].pdata_size = pdata->rtc ? sizeof(struct pm80x_rtc_pdata) : 0;
 
 	return mfd_add_devices(chip->dev, 0, &rtc_devs[0],
-			      ARRAY_SIZE(rtc_devs), NULL, 0, NULL);
+			ARRAY_SIZE(rtc_devs), NULL, 0, NULL);
 }
 
 static int device_regulator_init(struct pm80x_chip *chip)
 {
 	return mfd_add_devices(chip->dev, 0, &regulator_devs[0],
-			      ARRAY_SIZE(regulator_devs), NULL, 0, NULL);
+			ARRAY_SIZE(regulator_devs), NULL, 0, NULL);
 }
 
 static int device_irq_init_800(struct pm80x_chip *chip)
@@ -358,11 +358,10 @@ static int device_irq_init_800(struct pm80x_chip *chip)
 
 	/*
 	 * irq_clr_on_wr defines the way of clearing interrupt by
-	 * read/write(0/1).  It's read-clear by default.
+	 * read/write(0/1). It's read-clear by default.
 	 */
-	mask =
-	    PM800_WAKEUP2_INV_INT | PM800_WAKEUP2_INT_CLEAR |
-	    PM800_WAKEUP2_INT_MASK;
+	mask = PM800_WAKEUP2_INV_INT | PM800_WAKEUP2_INT_CLEAR |
+		PM800_WAKEUP2_INT_MASK;
 
 	irq_clr_mode = pdata->irq_clr_method == PM800_IRQ_CLR_ON_WRITE ?
 		PM800_WAKEUP2_INT_WRITE_CLEAR : PM800_WAKEUP2_INT_READ_CLEAR;
@@ -371,9 +370,8 @@ static int device_irq_init_800(struct pm80x_chip *chip)
 	if (ret < 0)
 		goto out;
 
-	ret =
-	    regmap_add_irq_chip(chip->regmap, chip->irq, flags, -1,
-				chip->regmap_irq_chip, &chip->irq_data);
+	ret = regmap_add_irq_chip(chip->regmap, chip->irq, flags, -1,
+			chip->regmap_irq_chip, &chip->irq_data);
 
 out:
 	return ret;
@@ -409,18 +407,18 @@ static int pm800_pages_init(struct pm80x_chip *chip)
 
 	/* PM800 block power page */
 	subchip->power_page = i2c_new_dummy(client->adapter,
-					    subchip->power_page_addr);
+					subchip->power_page_addr);
 	if (subchip->power_page == NULL) {
 		ret = -ENODEV;
 		goto out;
 	}
 
 	subchip->regmap_power = devm_regmap_init_i2c(subchip->power_page,
-						     &pm80x_regmap_config);
+				&pm80x_regmap_config);
 	if (IS_ERR(subchip->regmap_power)) {
 		ret = PTR_ERR(subchip->regmap_power);
 		dev_err(chip->dev,
-			"Failed to allocate regmap_power: %d\n", ret);
+				"Failed to allocate regmap_power: %d\n", ret);
 		goto out;
 	}
 
@@ -428,18 +426,18 @@ static int pm800_pages_init(struct pm80x_chip *chip)
 
 	/* PM800 block GPADC */
 	subchip->gpadc_page = i2c_new_dummy(client->adapter,
-					    subchip->gpadc_page_addr);
+				subchip->gpadc_page_addr);
 	if (subchip->gpadc_page == NULL) {
 		ret = -ENODEV;
 		goto out;
 	}
 
 	subchip->regmap_gpadc = devm_regmap_init_i2c(subchip->gpadc_page,
-						     &pm80x_regmap_config);
+				&pm80x_regmap_config);
 	if (IS_ERR(subchip->regmap_gpadc)) {
 		ret = PTR_ERR(subchip->regmap_gpadc);
 		dev_err(chip->dev,
-			"Failed to allocate regmap_gpadc: %d\n", ret);
+				"Failed to allocate regmap_gpadc: %d\n", ret);
 		goto out;
 	}
 	i2c_set_clientdata(subchip->gpadc_page, chip);
@@ -620,8 +618,7 @@ static int pm800_probe(struct i2c_client *client,
 	chip = i2c_get_clientdata(client);
 
 	/* init subchip for PM800 */
-	subchip =
-	    devm_kzalloc(&client->dev, sizeof(struct pm80x_subchip),
+	subchip = devm_kzalloc(&client->dev, sizeof(struct pm80x_subchip),
 			 GFP_KERNEL);
 	if (!subchip) {
 		ret = -ENOMEM;
@@ -684,7 +681,7 @@ static struct i2c_driver pm800_driver = {
 		.owner = THIS_MODULE,
 		.pm = &pm80x_pm_ops,
 		.of_match_table	= pm80x_of_match_table,
-		},
+	},
 	.probe = pm800_probe,
 	.remove = pm800_remove,
 	.id_table = pm80x_id_table,
-- 
1.9.1



From vaibhav.hiremath at linaro.org  Mon Aug 24 11:56:30 2015
From: vaibhav.hiremath at linaro.org (Vaibhav Hiremath)
Date: Tue, 25 Aug 2015 00:26:30 +0530
Subject: [PATCH-v2 1/5] mfd: 88pm800: Fix tabbing issue
In-Reply-To: <1440442594-3102-1-git-send-email-vaibhav.hiremath@linaro.org>
References: <1440442594-3102-1-git-send-email-vaibhav.hiremath@linaro.org>
Message-ID: <1440442594-3102-3-git-send-email-vaibhav.hiremath@linaro.org>

Driver had coding style issues where spaces were used instead
of tabs. This patch fixes them all.

Signed-off-by: Vaibhav Hiremath <vaibhav.hiremath at linaro.org>
---
 drivers/mfd/88pm800.c | 125 ++++++++++++++++++++++++--------------------------
 1 file changed, 61 insertions(+), 64 deletions(-)

diff --git a/drivers/mfd/88pm800.c b/drivers/mfd/88pm800.c
index f104a32..c4e097d 100644
--- a/drivers/mfd/88pm800.c
+++ b/drivers/mfd/88pm800.c
@@ -30,55 +30,55 @@
 #include <linux/of_device.h>
 
 /* Interrupt Registers */
-#define PM800_INT_STATUS1		(0x05)
+#define PM800_INT_STATUS1		0x05
 #define PM800_ONKEY_INT_STS1		(1 << 0)
 #define PM800_EXTON_INT_STS1		(1 << 1)
-#define PM800_CHG_INT_STS1			(1 << 2)
-#define PM800_BAT_INT_STS1			(1 << 3)
-#define PM800_RTC_INT_STS1			(1 << 4)
+#define PM800_CHG_INT_STS1		(1 << 2)
+#define PM800_BAT_INT_STS1		(1 << 3)
+#define PM800_RTC_INT_STS1		(1 << 4)
 #define PM800_CLASSD_OC_INT_STS1	(1 << 5)
 
-#define PM800_INT_STATUS2		(0x06)
+#define PM800_INT_STATUS2		0x06
 #define PM800_VBAT_INT_STS2		(1 << 0)
 #define PM800_VSYS_INT_STS2		(1 << 1)
 #define PM800_VCHG_INT_STS2		(1 << 2)
 #define PM800_TINT_INT_STS2		(1 << 3)
-#define PM800_GPADC0_INT_STS2	(1 << 4)
+#define PM800_GPADC0_INT_STS2		(1 << 4)
 #define PM800_TBAT_INT_STS2		(1 << 5)
-#define PM800_GPADC2_INT_STS2	(1 << 6)
-#define PM800_GPADC3_INT_STS2	(1 << 7)
+#define PM800_GPADC2_INT_STS2		(1 << 6)
+#define PM800_GPADC3_INT_STS2		(1 << 7)
 
-#define PM800_INT_STATUS3		(0x07)
+#define PM800_INT_STATUS3		0x07
 
-#define PM800_INT_STATUS4		(0x08)
+#define PM800_INT_STATUS4		0x08
 #define PM800_GPIO0_INT_STS4		(1 << 0)
 #define PM800_GPIO1_INT_STS4		(1 << 1)
 #define PM800_GPIO2_INT_STS4		(1 << 2)
 #define PM800_GPIO3_INT_STS4		(1 << 3)
 #define PM800_GPIO4_INT_STS4		(1 << 4)
 
-#define PM800_INT_ENA_1		(0x09)
+#define PM800_INT_ENA_1			0x09
 #define PM800_ONKEY_INT_ENA1		(1 << 0)
 #define PM800_EXTON_INT_ENA1		(1 << 1)
-#define PM800_CHG_INT_ENA1			(1 << 2)
-#define PM800_BAT_INT_ENA1			(1 << 3)
-#define PM800_RTC_INT_ENA1			(1 << 4)
+#define PM800_CHG_INT_ENA1		(1 << 2)
+#define PM800_BAT_INT_ENA1		(1 << 3)
+#define PM800_RTC_INT_ENA1		(1 << 4)
 #define PM800_CLASSD_OC_INT_ENA1	(1 << 5)
 
-#define PM800_INT_ENA_2		(0x0A)
+#define PM800_INT_ENA_2			0x0A
 #define PM800_VBAT_INT_ENA2		(1 << 0)
 #define PM800_VSYS_INT_ENA2		(1 << 1)
 #define PM800_VCHG_INT_ENA2		(1 << 2)
 #define PM800_TINT_INT_ENA2		(1 << 3)
 
-#define PM800_INT_ENA_3		(0x0B)
+#define PM800_INT_ENA_3			0x0B
 #define PM800_GPADC0_INT_ENA3		(1 << 0)
 #define PM800_GPADC1_INT_ENA3		(1 << 1)
 #define PM800_GPADC2_INT_ENA3		(1 << 2)
 #define PM800_GPADC3_INT_ENA3		(1 << 3)
 #define PM800_GPADC4_INT_ENA3		(1 << 4)
 
-#define PM800_INT_ENA_4		(0x0C)
+#define PM800_INT_ENA_4			0x0C
 #define PM800_GPIO0_INT_ENA4		(1 << 0)
 #define PM800_GPIO1_INT_ENA4		(1 << 1)
 #define PM800_GPIO2_INT_ENA4		(1 << 2)
@@ -86,7 +86,7 @@
 #define PM800_GPIO4_INT_ENA4		(1 << 4)
 
 /* number of INT_ENA & INT_STATUS regs */
-#define PM800_INT_REG_NUM			(4)
+#define PM800_INT_REG_NUM		4
 
 /* Interrupt Number in 88PM800 */
 enum {
@@ -114,7 +114,7 @@ enum {
 };
 
 /* PM800: generation identification number */
-#define PM800_CHIP_GEN_ID_NUM	0x3
+#define PM800_CHIP_GEN_ID_NUM		0x3
 
 static const struct i2c_device_id pm80x_id_table[] = {
 	{"88PM800", 0},
@@ -129,47 +129,47 @@ static const struct of_device_id pm80x_of_match_table[] = {
 
 static struct resource rtc_resources[] = {
 	{
-	 .name = "88pm80x-rtc",
-	 .start = PM800_IRQ_RTC,
-	 .end = PM800_IRQ_RTC,
-	 .flags = IORESOURCE_IRQ,
-	 },
+		.name = "88pm80x-rtc",
+		.start = PM800_IRQ_RTC,
+		.end = PM800_IRQ_RTC,
+		.flags = IORESOURCE_IRQ,
+	},
 };
 
 static struct mfd_cell rtc_devs[] = {
 	{
-	 .name = "88pm80x-rtc",
-	 .of_compatible = "marvell,88pm80x-rtc",
-	 .num_resources = ARRAY_SIZE(rtc_resources),
-	 .resources = &rtc_resources[0],
-	 .id = -1,
-	 },
+		.name = "88pm80x-rtc",
+		.of_compatible = "marvell,88pm80x-rtc",
+		.num_resources = ARRAY_SIZE(rtc_resources),
+		.resources = &rtc_resources[0],
+		.id = -1,
+	},
 };
 
 static struct resource onkey_resources[] = {
 	{
-	 .name = "88pm80x-onkey",
-	 .start = PM800_IRQ_ONKEY,
-	 .end = PM800_IRQ_ONKEY,
-	 .flags = IORESOURCE_IRQ,
-	 },
+		.name = "88pm80x-onkey",
+		.start = PM800_IRQ_ONKEY,
+		.end = PM800_IRQ_ONKEY,
+		.flags = IORESOURCE_IRQ,
+	},
 };
 
 static const struct mfd_cell onkey_devs[] = {
 	{
-	 .name = "88pm80x-onkey",
-	 .of_compatible = "marvell,88pm80x-onkey",
-	 .num_resources = 1,
-	 .resources = &onkey_resources[0],
-	 .id = -1,
-	 },
+		.name = "88pm80x-onkey",
+		.of_compatible = "marvell,88pm80x-onkey",
+		.num_resources = 1,
+		.resources = &onkey_resources[0],
+		.id = -1,
+	},
 };
 
 static const struct mfd_cell regulator_devs[] = {
 	{
-	 .name = "88pm80x-regulator",
-	 .of_compatible = "marvell,88pm80x-regulator",
-	 .id = -1,
+		.name = "88pm80x-regulator",
+		.of_compatible = "marvell,88pm80x-regulator",
+		.id = -1,
 	},
 };
 
@@ -323,8 +323,8 @@ out:
 static int device_onkey_init(struct pm80x_chip *chip)
 {
 	return mfd_add_devices(chip->dev, 0, &onkey_devs[0],
-			      ARRAY_SIZE(onkey_devs), &onkey_resources[0], 0,
-			      NULL);
+			ARRAY_SIZE(onkey_devs), &onkey_resources[0], 0,
+			NULL);
 }
 
 static int device_rtc_init(struct pm80x_chip *chip)
@@ -335,13 +335,13 @@ static int device_rtc_init(struct pm80x_chip *chip)
 	rtc_devs[0].pdata_size = pdata->rtc ? sizeof(struct pm80x_rtc_pdata) : 0;
 
 	return mfd_add_devices(chip->dev, 0, &rtc_devs[0],
-			      ARRAY_SIZE(rtc_devs), NULL, 0, NULL);
+			ARRAY_SIZE(rtc_devs), NULL, 0, NULL);
 }
 
 static int device_regulator_init(struct pm80x_chip *chip)
 {
 	return mfd_add_devices(chip->dev, 0, &regulator_devs[0],
-			      ARRAY_SIZE(regulator_devs), NULL, 0, NULL);
+			ARRAY_SIZE(regulator_devs), NULL, 0, NULL);
 }
 
 static int device_irq_init_800(struct pm80x_chip *chip)
@@ -358,11 +358,10 @@ static int device_irq_init_800(struct pm80x_chip *chip)
 
 	/*
 	 * irq_clr_on_wr defines the way of clearing interrupt by
-	 * read/write(0/1).  It's read-clear by default.
+	 * read/write(0/1). It's read-clear by default.
 	 */
-	mask =
-	    PM800_WAKEUP2_INV_INT | PM800_WAKEUP2_INT_CLEAR |
-	    PM800_WAKEUP2_INT_MASK;
+	mask = PM800_WAKEUP2_INV_INT | PM800_WAKEUP2_INT_CLEAR |
+		PM800_WAKEUP2_INT_MASK;
 
 	irq_clr_mode = pdata->irq_clr_method == PM800_IRQ_CLR_ON_WRITE ?
 		PM800_WAKEUP2_INT_WRITE_CLEAR : PM800_WAKEUP2_INT_READ_CLEAR;
@@ -371,9 +370,8 @@ static int device_irq_init_800(struct pm80x_chip *chip)
 	if (ret < 0)
 		goto out;
 
-	ret =
-	    regmap_add_irq_chip(chip->regmap, chip->irq, flags, -1,
-				chip->regmap_irq_chip, &chip->irq_data);
+	ret = regmap_add_irq_chip(chip->regmap, chip->irq, flags, -1,
+			chip->regmap_irq_chip, &chip->irq_data);
 
 out:
 	return ret;
@@ -409,18 +407,18 @@ static int pm800_pages_init(struct pm80x_chip *chip)
 
 	/* PM800 block power page */
 	subchip->power_page = i2c_new_dummy(client->adapter,
-					    subchip->power_page_addr);
+					subchip->power_page_addr);
 	if (subchip->power_page == NULL) {
 		ret = -ENODEV;
 		goto out;
 	}
 
 	subchip->regmap_power = devm_regmap_init_i2c(subchip->power_page,
-						     &pm80x_regmap_config);
+				&pm80x_regmap_config);
 	if (IS_ERR(subchip->regmap_power)) {
 		ret = PTR_ERR(subchip->regmap_power);
 		dev_err(chip->dev,
-			"Failed to allocate regmap_power: %d\n", ret);
+				"Failed to allocate regmap_power: %d\n", ret);
 		goto out;
 	}
 
@@ -428,18 +426,18 @@ static int pm800_pages_init(struct pm80x_chip *chip)
 
 	/* PM800 block GPADC */
 	subchip->gpadc_page = i2c_new_dummy(client->adapter,
-					    subchip->gpadc_page_addr);
+				subchip->gpadc_page_addr);
 	if (subchip->gpadc_page == NULL) {
 		ret = -ENODEV;
 		goto out;
 	}
 
 	subchip->regmap_gpadc = devm_regmap_init_i2c(subchip->gpadc_page,
-						     &pm80x_regmap_config);
+				&pm80x_regmap_config);
 	if (IS_ERR(subchip->regmap_gpadc)) {
 		ret = PTR_ERR(subchip->regmap_gpadc);
 		dev_err(chip->dev,
-			"Failed to allocate regmap_gpadc: %d\n", ret);
+				"Failed to allocate regmap_gpadc: %d\n", ret);
 		goto out;
 	}
 	i2c_set_clientdata(subchip->gpadc_page, chip);
@@ -620,8 +618,7 @@ static int pm800_probe(struct i2c_client *client,
 	chip = i2c_get_clientdata(client);
 
 	/* init subchip for PM800 */
-	subchip =
-	    devm_kzalloc(&client->dev, sizeof(struct pm80x_subchip),
+	subchip = devm_kzalloc(&client->dev, sizeof(struct pm80x_subchip),
 			 GFP_KERNEL);
 	if (!subchip) {
 		ret = -ENOMEM;
@@ -684,7 +681,7 @@ static struct i2c_driver pm800_driver = {
 		.owner = THIS_MODULE,
 		.pm = &pm80x_pm_ops,
 		.of_match_table	= pm80x_of_match_table,
-		},
+	},
 	.probe = pm800_probe,
 	.remove = pm800_remove,
 	.id_table = pm80x_id_table,
-- 
1.9.1



From vaibhav.hiremath at linaro.org  Mon Aug 24 11:56:31 2015
From: vaibhav.hiremath at linaro.org (Vaibhav Hiremath)
Date: Tue, 25 Aug 2015 00:26:31 +0530
Subject: [PATCH-v2 2/5] mfd: 88pm800: Update the header file with 32K clk
 related macros
In-Reply-To: <1440442594-3102-1-git-send-email-vaibhav.hiremath@linaro.org>
References: <1440442594-3102-1-git-send-email-vaibhav.hiremath@linaro.org>
Message-ID: <1440442594-3102-4-git-send-email-vaibhav.hiremath@linaro.org>

Update header file with required macros for 32KHz buffered clock
output of 88PM800 family of device.
These macros will be used in clk provider driver.

Signed-off-by: Vaibhav Hiremath <vaibhav.hiremath at linaro.org>
---
 include/linux/mfd/88pm80x.h | 12 ++++++++++++
 1 file changed, 12 insertions(+)

diff --git a/include/linux/mfd/88pm80x.h b/include/linux/mfd/88pm80x.h
index 122cfd2..0215d5f 100644
--- a/include/linux/mfd/88pm80x.h
+++ b/include/linux/mfd/88pm80x.h
@@ -91,6 +91,7 @@ enum {
 /* Referance and low power registers */
 #define PM800_LOW_POWER1		(0x20)
 #define PM800_LOW_POWER2		(0x21)
+#define PM800_LOW_POWER2_XO_LJ_EN	BIT(5)
 
 #define PM800_LOW_POWER_CONFIG3		(0x22)
 #define PM800_LDOBK_FREEZE		BIT(7)
@@ -138,6 +139,13 @@ enum {
 #define PM800_ALARM			BIT(5)
 #define PM800_RTC1_USE_XO		BIT(7)
 
+#define PM800_32K_OUTX_SEL_MASK		0x3
+/* 32KHz clk output sel mode */
+#define PM800_32K_OUTX_SEL_ZERO		0x0
+#define PM800_32K_OUTX_SEL_INT_32KHZ	0x1
+#define PM800_32K_OUTX_SEL_XO_32KHZ	0x2
+#define PM800_32K_OUTX_SEL_HIZ		0x3
+
 /* Regulator Control Registers: BUCK1,BUCK5,LDO1 have DVC */
 
 /* buck registers */
@@ -208,6 +216,10 @@ enum {
 #define PM800_PMOD_MEAS1		0x52
 #define PM800_PMOD_MEAS2		0x53
 
+/* Oscillator control */
+#define PM800_OSC_CNTRL1		0x50
+#define PM800_OSC_CNTRL1_OSC_FREERUN_EN	BIT(1)
+
 #define PM800_GPADC0_MEAS1		0x54
 #define PM800_GPADC0_MEAS2		0x55
 #define PM800_GPADC1_MEAS1		0x56
-- 
1.9.1



From vaibhav.hiremath at linaro.org  Mon Aug 24 11:56:33 2015
From: vaibhav.hiremath at linaro.org (Vaibhav Hiremath)
Date: Tue, 25 Aug 2015 00:26:33 +0530
Subject: [PATCH-v2 4/5] clk: 88pm800: Add clk provider driver for 88pm800
 family of devices
In-Reply-To: <1440442594-3102-1-git-send-email-vaibhav.hiremath@linaro.org>
References: <1440442594-3102-1-git-send-email-vaibhav.hiremath@linaro.org>
Message-ID: <1440442594-3102-6-git-send-email-vaibhav.hiremath@linaro.org>

88PM800 family of devices supports buffered 32KHz clock output,
for example,

88PM800: CLK32k_1, CLK32k_2 and CLK32k_3
88PM860: CLK32K_1 and CLK32K_2

This patch adds new clk provider driver to support enable/disable
of the 32KHz clock output from 88PM800 family of devices.

Signed-off-by: Vaibhav Hiremath <vaibhav.hiremath at linaro.org>
---
 drivers/clk/Kconfig       |   8 ++
 drivers/clk/Makefile      |   1 +
 drivers/clk/clk-88pm800.c | 341 ++++++++++++++++++++++++++++++++++++++++++++++
 3 files changed, 350 insertions(+)
 create mode 100644 drivers/clk/clk-88pm800.c

diff --git a/drivers/clk/Kconfig b/drivers/clk/Kconfig
index 42f7120..c34c14d 100644
--- a/drivers/clk/Kconfig
+++ b/drivers/clk/Kconfig
@@ -167,6 +167,14 @@ config COMMON_CLK_CDCE706
 	---help---
 	  This driver supports TI CDCE706 programmable 3-PLL clock synthesizer.
 
+config COMMON_CLK_88PM800
+	tristate "Clock driver for 88PM800 MFD"
+	depends on MFD_88PM800
+	---help---
+	  This driver supports 88PM800 & 88PM860 crystal oscillator
+	  clock. These multi-function devices have two (88PM860) or three
+	  (88PM800) fixed-rate output, clocked at 32KHz each.
+
 source "drivers/clk/bcm/Kconfig"
 source "drivers/clk/hisilicon/Kconfig"
 source "drivers/clk/qcom/Kconfig"
diff --git a/drivers/clk/Makefile b/drivers/clk/Makefile
index c4cf075..5248cd3 100644
--- a/drivers/clk/Makefile
+++ b/drivers/clk/Makefile
@@ -80,3 +80,4 @@ obj-$(CONFIG_X86)			+= x86/
 obj-$(CONFIG_ARCH_ZX)			+= zte/
 obj-$(CONFIG_ARCH_ZYNQ)			+= zynq/
 obj-$(CONFIG_H8300)		+= h8300/
+obj-$(CONFIG_COMMON_CLK_88PM800)	+= clk-88pm800.o
diff --git a/drivers/clk/clk-88pm800.c b/drivers/clk/clk-88pm800.c
new file mode 100644
index 0000000..4c045e1
--- /dev/null
+++ b/drivers/clk/clk-88pm800.c
@@ -0,0 +1,341 @@
+/*
+ * clk-88pm800.c - Clock driver for 88PM800 family of devices
+ *
+ * This driver is created based on clk-s2mps11.c
+ *
+ * Copyright (C) 2015 Linaro Ltd.
+ *
+ * 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/module.h>
+#include <linux/err.h>
+#include <linux/of.h>
+#include <linux/clkdev.h>
+#include <linux/regmap.h>
+#include <linux/clk-provider.h>
+#include <linux/platform_device.h>
+#include <linux/mfd/88pm80x.h>
+
+/* Number of clocks output from 88pm800 family of device */
+enum {
+	PM800_CLK32K_1 = 0,
+	PM800_CLK32K_2,
+	PM800_CLK32K_3,
+	PM800_CLKS_NUM,
+};
+
+struct pm800_clk {
+	struct pm80x_chip *chip;
+	struct device_node *clk_np;
+	struct clk_hw hw;
+	struct clk *clk;
+	struct clk_lookup *lookup;
+	u32 mask;
+	u32 shift;
+	unsigned int reg;
+};
+
+static struct pm800_clk *to_pm800_clk(struct clk_hw *hw)
+{
+	return container_of(hw, struct pm800_clk, hw);
+}
+
+static int pm800_clk_prepare(struct clk_hw *hw)
+{
+	struct pm800_clk *pm800 = to_pm800_clk(hw);
+
+	/* We always want to use XO clock */
+	return regmap_update_bits(pm800->chip->regmap,
+				 pm800->reg,
+				 pm800->mask,
+				 PM800_32K_OUTX_SEL_XO_32KHZ << pm800->shift);
+}
+
+static void pm800_clk_unprepare(struct clk_hw *hw)
+{
+	struct pm800_clk *pm800 = to_pm800_clk(hw);
+
+	regmap_update_bits(pm800->chip->regmap, pm800->reg,
+				pm800->mask, ~pm800->mask);
+}
+
+static int pm800_clk_is_prepared(struct clk_hw *hw)
+{
+	int ret;
+	u32 val;
+	struct pm800_clk *pm800 = to_pm800_clk(hw);
+
+	ret = regmap_read(pm800->chip->regmap,
+				pm800->reg, &val);
+	if (ret < 0)
+		return -EINVAL;
+
+	return (val & pm800->mask) >> pm800->shift;
+}
+
+static unsigned long pm800_clk_recalc_rate(struct clk_hw *hw,
+					     unsigned long parent_rate)
+{
+	return 32768;
+}
+
+static const struct clk_ops pm800_clk_ops = {
+	.prepare	= pm800_clk_prepare,
+	.unprepare	= pm800_clk_unprepare,
+	.is_prepared	= pm800_clk_is_prepared,
+	.recalc_rate	= pm800_clk_recalc_rate,
+};
+
+static struct clk_init_data pm800_clks_init[PM800_CLKS_NUM] = {
+	[PM800_CLK32K_1] = {
+		.name	= "pm800_clk32k_1",
+		.ops	= &pm800_clk_ops,
+		.flags	= CLK_IS_ROOT,
+	},
+	[PM800_CLK32K_2] = {
+		.name	= "pm800_clk32k_2",
+		.ops	= &pm800_clk_ops,
+		.flags	= CLK_IS_ROOT,
+	},
+	[PM800_CLK32K_3] = {
+		.name	= "pm800_clk32k_3",
+		.ops	= &pm800_clk_ops,
+		.flags	= CLK_IS_ROOT,
+	},
+};
+
+static struct clk_init_data pm860_clks_init[PM800_CLKS_NUM] = {
+	[PM800_CLK32K_1] = {
+		.name	= "pm800_clk32k_1",
+		.ops	= &pm800_clk_ops,
+		.flags	= CLK_IS_ROOT,
+	},
+	[PM800_CLK32K_2] = {
+		.name	= "pm800_clk32k_2",
+		.ops	= &pm800_clk_ops,
+		.flags	= CLK_IS_ROOT,
+	},
+};
+
+static int pm800_init_clk(struct pm800_clk *pm800_clks)
+{
+	int ret;
+
+	/* Enable XO_LJ : Low jitter clock of 32KHz from XO */
+	ret = regmap_update_bits(pm800_clks->chip->regmap, PM800_LOW_POWER2,
+			PM800_LOW_POWER2_XO_LJ_EN, PM800_LOW_POWER2_XO_LJ_EN);
+	if (ret)
+		return ret;
+
+	/* Enable USE_XO : Use XO clock for all internal timing reference */
+	ret = regmap_update_bits(pm800_clks->chip->regmap, PM800_RTC_CONTROL,
+			PM800_RTC1_USE_XO, PM800_RTC1_USE_XO);
+	if (ret)
+		return ret;
+
+	/* OSC_FREERUN: Enable Osc free running mode by clearing the bit */
+	ret = regmap_update_bits(pm800_clks->chip->regmap, PM800_OSC_CNTRL1,
+			PM800_OSC_CNTRL1_OSC_FREERUN_EN, 0);
+	if (ret)
+		return ret;
+
+	return 0;
+}
+
+static struct device_node *pm800_clk_parse_dt(struct platform_device *pdev,
+		struct clk_init_data *clks_init)
+{
+	struct pm80x_chip *chip = dev_get_drvdata(pdev->dev.parent);
+	struct device_node *clk_np;
+	int i;
+
+	if (!chip->dev->of_node)
+		return ERR_PTR(-EINVAL);
+
+	clk_np = of_get_child_by_name(chip->dev->of_node, "clocks");
+	if (!clk_np) {
+		dev_err(&pdev->dev, "could not find clock sub-node\n");
+		return ERR_PTR(-EINVAL);
+	}
+
+	for (i = 0; i < PM800_CLKS_NUM; i++) {
+		if (!clks_init[i].name)
+			continue; /* Skip clocks not present in some devices */
+
+		of_property_read_string_index(clk_np, "clock-output-names", i,
+				&clks_init[i].name);
+	}
+
+	return clk_np;
+}
+
+static int pm800_clk_probe(struct platform_device *pdev)
+{
+	struct pm80x_chip *chip = dev_get_drvdata(pdev->dev.parent);
+	struct pm800_clk *pm800_clks;
+	struct clk_init_data *clks_init;
+	static struct clk **clk_table;
+	static struct clk_onecell_data *of_clk_data;
+	int i, ret;
+
+	pm800_clks = devm_kcalloc(&pdev->dev, PM800_CLKS_NUM,
+				sizeof(*pm800_clks), GFP_KERNEL);
+	if (!pm800_clks)
+		return -ENOMEM;
+
+	clk_table = devm_kcalloc(&pdev->dev, PM800_CLKS_NUM,
+				sizeof(struct clk *), GFP_KERNEL);
+	if (!clk_table)
+		return -ENOMEM;
+
+	switch (platform_get_device_id(pdev)->driver_data) {
+	case CHIP_PM800:
+		clks_init = pm800_clks_init;
+		break;
+	case CHIP_PM860:
+		clks_init = pm860_clks_init;
+		break;
+	default:
+		dev_err(&pdev->dev, "Invalid device type\n");
+		return -EINVAL;
+	}
+
+	/* Store clocks of_node in first element of pm800_clks array */
+	pm800_clks->clk_np = pm800_clk_parse_dt(pdev, clks_init);
+	if (IS_ERR(pm800_clks->clk_np))
+		return PTR_ERR(pm800_clks->clk_np);
+
+	of_clk_data = devm_kzalloc(&pdev->dev, sizeof(*of_clk_data), GFP_KERNEL);
+	if (!of_clk_data) {
+		ret = -ENOMEM;
+		goto err_clk_np;
+	}
+
+	for (i = 0; i < PM800_CLKS_NUM; i++) {
+		if (!clks_init[i].name)
+			continue; /* Skip clocks not present in some devices */
+
+		pm800_clks[i].chip = chip;
+		pm800_clks[i].hw.init = &clks_init[i];
+		/*
+		 * As of now, mask and shift formula below works for both
+		 * 88PM800 and it's family of devices,
+		 *
+		 *  PM800_RTC_MISC2:
+		 *      1:0	= CK_32K_OUT1_SEL
+		 *      3:2	= CK_32K_OUT2_SEL
+		 *      5:4	= CK_32K_OUT3_SEL
+		 */
+		pm800_clks[i].shift = i * 2;
+		pm800_clks[i].mask = PM800_32K_OUTX_SEL_MASK << pm800_clks[i].shift;
+		pm800_clks[i].reg = PM800_RTC_MISC2;
+
+		pm800_clks[i].clk = devm_clk_register(&pdev->dev,
+							&pm800_clks[i].hw);
+		if (IS_ERR(pm800_clks[i].clk)) {
+			dev_err(&pdev->dev, "Fail to register : %s\n",
+						clks_init[i].name);
+			ret = PTR_ERR(pm800_clks[i].clk);
+			goto err;
+		}
+
+		pm800_clks[i].lookup = clkdev_create(pm800_clks[i].clk,
+					clks_init[i].name, NULL);
+		if (!pm800_clks[i].lookup) {
+			ret = -ENOMEM;
+			goto err;
+		}
+
+		clk_table[i] = pm800_clks[i].clk;
+	}
+
+	of_clk_data->clks = clk_table;
+	of_clk_data->clk_num = PM800_CLKS_NUM;
+	ret = of_clk_add_provider(pm800_clks->clk_np, of_clk_src_onecell_get,
+			of_clk_data);
+	if (ret) {
+		dev_err(&pdev->dev, "Fail to add OF clk provider : %d\n", ret);
+		goto err;
+	}
+
+	/* Common for all 32KHz clock output */
+	ret = pm800_init_clk(&pm800_clks[0]);
+	if (ret) {
+		dev_err(&pdev->dev, "Failed to initialize clk : %d\n", ret);
+		goto err;
+	}
+
+	platform_set_drvdata(pdev, pm800_clks);
+
+	return 0;
+
+err:
+	for (i = 0; i < PM800_CLKS_NUM; i++) {
+		if (pm800_clks[i].lookup)
+			clkdev_drop(pm800_clks[i].lookup);
+	}
+err_clk_np:
+	/* Drop the reference obtained in pm800_clk_parse_dt */
+	of_node_put(pm800_clks[0].clk_np);
+
+	return ret;
+}
+
+static int pm800_clk_remove(struct platform_device *pdev)
+{
+	struct pm800_clk *pm800_clks = platform_get_drvdata(pdev);
+	int i;
+
+	of_clk_del_provider(pm800_clks[0].clk_np);
+	/* Drop the reference obtained in pm800_clk_parse_dt */
+	of_node_put(pm800_clks[0].clk_np);
+
+	for (i = 0; i < PM800_CLKS_NUM; i++) {
+		if (pm800_clks[i].lookup)
+			clkdev_drop(pm800_clks[i].lookup);
+	}
+
+	return 0;
+}
+
+static const struct platform_device_id pm800_clk_id[] = {
+	{ "88pm800-clk", CHIP_PM800},
+	{ "88pm860-clk", CHIP_PM860},
+	{ },
+};
+MODULE_DEVICE_TABLE(platform, pm800_clk_id);
+
+static struct platform_driver pm800_clk_driver = {
+	.driver = {
+		.name  = "88pm80x-clk",
+	},
+	.probe = pm800_clk_probe,
+	.remove = pm800_clk_remove,
+	.id_table = pm800_clk_id,
+};
+
+static int __init pm800_clk_init(void)
+{
+	return platform_driver_register(&pm800_clk_driver);
+}
+subsys_initcall(pm800_clk_init);
+
+static void __exit pm800_clk_cleanup(void)
+{
+	platform_driver_unregister(&pm800_clk_driver);
+}
+module_exit(pm800_clk_cleanup);
+
+MODULE_DESCRIPTION("88PM800 Clock Driver");
+MODULE_AUTHOR("Vaibhav Hiremath <vaibhav.hiremath at linaro.org>");
+MODULE_LICENSE("GPL");
-- 
1.9.1



From vaibhav.hiremath at linaro.org  Mon Aug 24 11:56:32 2015
From: vaibhav.hiremath at linaro.org (Vaibhav Hiremath)
Date: Tue, 25 Aug 2015 00:26:32 +0530
Subject: [PATCH-v2 3/5] mfd: devicetree: bindings: Add clock subdevice node
 information
In-Reply-To: <1440442594-3102-1-git-send-email-vaibhav.hiremath@linaro.org>
References: <1440442594-3102-1-git-send-email-vaibhav.hiremath@linaro.org>
Message-ID: <1440442594-3102-5-git-send-email-vaibhav.hiremath@linaro.org>

This patch updates the binding documentation for optional
clocks node and related information for buffered 32KHz clock.

Signed-off-by: Vaibhav Hiremath <vaibhav.hiremath at linaro.org>
Reviewed-by: Krzysztof Kozlowski <k.kozlowski at samsung.com>
Acked-by: Rob Herring <robh at kernel.org>
---
 Documentation/devicetree/bindings/mfd/88pm800.txt | 27 +++++++++++++++++++++++
 1 file changed, 27 insertions(+)

diff --git a/Documentation/devicetree/bindings/mfd/88pm800.txt b/Documentation/devicetree/bindings/mfd/88pm800.txt
index 2c82fcb..bc6cb02 100644
--- a/Documentation/devicetree/bindings/mfd/88pm800.txt
+++ b/Documentation/devicetree/bindings/mfd/88pm800.txt
@@ -15,6 +15,26 @@ Optional properties :
   Without this both BUCK1A and BUCK1B operates independently with 3A capacity.
   (This property is only applicable to 88PM860)
 
+Optional nodes:
+- clocks: 88pm800 family of devices provide multiple buffered 32.768
+  KHz outputs, so to register these as clocks with common clock framework
+  instantiate a sub-node named "clocks". It uses the common clock binding
+  documented in :
+  [Documentation/devicetree/bindings/clock/clock-bindings.txt]
+
+  - #clock-cells: should be 1.
+
+  - The following is the list of clocks generated by the controller. Each clock
+    is assigned an identifier and client nodes use this identifier to specify
+    the clock which they consume.
+    Clock		ID           	Devices
+    ----------------------------------------------------------
+    pm800_clk32k_1	0		88PM800 and 88PM860
+    pm800_clk32k_2	1		88PM800 and 88PM860
+    pm800_clk32k_3	2		88PM800
+
+  - compatible: Should be : "marvell,88pm800-clk"
+
 88pm80x family of devices consists of varied group of sub-devices:
 
 Device		 	Supply Names	 Description
@@ -22,6 +42,7 @@ Device		 	Supply Names	 Description
 88pm80x-onkey		:		: On key
 88pm80x-rtc		:		: RTC
 88pm80x-regulator	:		: Regulators
+88pm80x-clk		:		: 32KHz Clk provider
 
 Example:
 
@@ -33,6 +54,12 @@ Example:
 		interrupt-controller;
 		#interrupt-cells = <1>;
 
+		pm800clk: clocks {
+			compatible = "marvell,88pm800-clk";
+			#clock-cells = <1>;
+			clock-output-names = "xx", "yy", "zz";
+		};
+
 		regulators {
 			compatible = "marvell,88pm80x-regulator";
 
-- 
1.9.1



From vaibhav.hiremath at linaro.org  Mon Aug 24 11:56:34 2015
From: vaibhav.hiremath at linaro.org (Vaibhav Hiremath)
Date: Tue, 25 Aug 2015 00:26:34 +0530
Subject: [PATCH-v2 5/5] mfd: 88pm800: Add support for clk subdevice
In-Reply-To: <1440442594-3102-1-git-send-email-vaibhav.hiremath@linaro.org>
References: <1440442594-3102-1-git-send-email-vaibhav.hiremath@linaro.org>
Message-ID: <1440442594-3102-7-git-send-email-vaibhav.hiremath@linaro.org>

This patch adds mfd_cell/clk-subdevice for 88PM800 MFD
(and family of devices).

Signed-off-by: Vaibhav Hiremath <vaibhav.hiremath at linaro.org>
---
 drivers/mfd/88pm800.c | 25 +++++++++++++++++++++++++
 1 file changed, 25 insertions(+)

diff --git a/drivers/mfd/88pm800.c b/drivers/mfd/88pm800.c
index c4e097d..a928eed 100644
--- a/drivers/mfd/88pm800.c
+++ b/drivers/mfd/88pm800.c
@@ -173,6 +173,14 @@ static const struct mfd_cell regulator_devs[] = {
 	},
 };
 
+static struct mfd_cell clk_devs[] = {
+	{
+		.name = "88pm80x-clk",
+		.of_compatible = "marvell,88pm800-clk",
+		.id = -1,
+	},
+};
+
 static const struct regmap_irq pm800_irqs[] = {
 	/* INT0 */
 	[PM800_IRQ_ONKEY] = {
@@ -344,6 +352,17 @@ static int device_regulator_init(struct pm80x_chip *chip)
 			ARRAY_SIZE(regulator_devs), NULL, 0, NULL);
 }
 
+static int device_clk_init(struct pm80x_chip *chip)
+{
+	if (chip->type == CHIP_PM800)
+		clk_devs[0].name = "88pm800-clk";
+	else if (chip->type == CHIP_PM860)
+		clk_devs[0].name = "88pm860-clk";
+
+	return mfd_add_devices(chip->dev, 0, &clk_devs[0],
+			ARRAY_SIZE(clk_devs), NULL, 0, NULL);
+}
+
 static int device_irq_init_800(struct pm80x_chip *chip)
 {
 	struct regmap *map = chip->regmap;
@@ -511,6 +530,12 @@ static int device_800_init(struct pm80x_chip *chip)
 		goto out;
 	}
 
+	ret = device_clk_init(chip);
+	if (ret) {
+		dev_err(chip->dev, "Failed to add clk subdev\n");
+		goto out;
+	}
+
 	return 0;
 out_dev:
 	mfd_remove_devices(chip->dev);
-- 
1.9.1



From shenwei.wang at freescale.com  Mon Aug 24 12:04:15 2015
From: shenwei.wang at freescale.com (Shenwei Wang)
Date: Mon, 24 Aug 2015 14:04:15 -0500
Subject: [PATCH v9 1/1] irqchip: imx-gpcv2: IMX GPCv2 driver for wakeup sources
Message-ID: <1440443055-7291-1-git-send-email-shenwei.wang@freescale.com>

IMX7D contains a new version of GPC IP block (GPCv2). It has two
major functions: power management and wakeup source management.
This patch adds a new irqchip driver to manage the interrupt wakeup
sources on IMX7D.
When the system is in WFI (wait for interrupt) mode, this GPC block
will be the first block on the platform to be activated and signaled.
Under normal wait mode during cpu idle, the system can be woke up
by any enabled interrupts. Under standby or suspend mode, the system
can only be woke up by the pre-defined wakeup sources.

Signed-off-by: Shenwei Wang <shenwei.wang at freescale.com>
Signed-off-by: Anson Huang <b20788 at freescale.com>
---
Change log:
	Renamed the enabled_irqs to saved_irq_mask in struct gpcv2_irqchip_data
	Removed "BUG_ON()" in imx_gpcv2_irqchip_init to unify the error handling codes.

 drivers/irqchip/Kconfig         |   7 +
 drivers/irqchip/Makefile        |   1 +
 drivers/irqchip/irq-imx-gpcv2.c | 275 ++++++++++++++++++++++++++++++++++++++++
 3 files changed, 283 insertions(+)
 create mode 100644 drivers/irqchip/irq-imx-gpcv2.c

diff --git a/drivers/irqchip/Kconfig b/drivers/irqchip/Kconfig
index 120d815..3fc0fac 100644
--- a/drivers/irqchip/Kconfig
+++ b/drivers/irqchip/Kconfig
@@ -177,3 +177,10 @@ config RENESAS_H8300H_INTC
 config RENESAS_H8S_INTC
         bool
 	select IRQ_DOMAIN
+
+config IMX_GPCV2
+	bool
+	select IRQ_DOMAIN
+	help
+	  Enables the wakeup IRQs for IMX platforms with GPCv2 block
+
diff --git a/drivers/irqchip/Makefile b/drivers/irqchip/Makefile
index b8d4e96..8eb5f60 100644
--- a/drivers/irqchip/Makefile
+++ b/drivers/irqchip/Makefile
@@ -52,3 +52,4 @@ obj-$(CONFIG_RENESAS_H8300H_INTC)	+= irq-renesas-h8300h.o
 obj-$(CONFIG_RENESAS_H8S_INTC)		+= irq-renesas-h8s.o
 obj-$(CONFIG_ARCH_SA1100)		+= irq-sa11x0.o
 obj-$(CONFIG_INGENIC_IRQ)		+= irq-ingenic.o
+obj-$(CONFIG_IMX_GPCV2)			+= irq-imx-gpcv2.o
diff --git a/drivers/irqchip/irq-imx-gpcv2.c b/drivers/irqchip/irq-imx-gpcv2.c
new file mode 100644
index 0000000..4a97afa
--- /dev/null
+++ b/drivers/irqchip/irq-imx-gpcv2.c
@@ -0,0 +1,275 @@
+/*
+ * Copyright (C) 2015 Freescale Semiconductor, Inc.
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License version 2 as
+ * published by the Free Software Foundation.
+ */
+
+#include <linux/of_address.h>
+#include <linux/of_irq.h>
+#include <linux/slab.h>
+#include <linux/irqchip.h>
+#include <linux/syscore_ops.h>
+
+#define IMR_NUM			4
+#define GPC_MAX_IRQS            (IMR_NUM * 32)
+
+#define GPC_IMR1_CORE0		0x30
+#define GPC_IMR1_CORE1		0x40
+
+struct gpcv2_irqchip_data {
+	struct raw_spinlock    rlock;
+	void __iomem       *gpc_base;
+	u32 wakeup_sources[IMR_NUM];
+	u32 saved_irq_mask[IMR_NUM];
+	u32 cpu2wakeup;
+};
+
+static struct gpcv2_irqchip_data *imx_gpcv2_instance;
+
+u32 imx_gpcv2_get_wakeup_source(u32 **sources)
+{
+	if (!imx_gpcv2_instance)
+		return 0;
+
+	if (sources)
+		*sources = imx_gpcv2_instance->wakeup_sources;
+
+	return IMR_NUM;
+}
+
+static int gpcv2_wakeup_source_save(void)
+{
+	struct gpcv2_irqchip_data *cd;
+	void __iomem *reg;
+	int i;
+
+	cd = imx_gpcv2_instance;
+	if (!cd)
+		return 0;
+
+	for (i = 0; i < IMR_NUM; i++) {
+		reg = cd->gpc_base + cd->cpu2wakeup + i * 4;
+		cd->saved_irq_mask[i] = readl_relaxed(reg);
+		writel_relaxed(cd->wakeup_sources[i], reg);
+	}
+
+	return 0;
+}
+
+static void gpcv2_wakeup_source_restore(void)
+{
+	struct gpcv2_irqchip_data *cd;
+	void __iomem *reg;
+	int i;
+
+	cd = imx_gpcv2_instance;
+	if (!cd)
+		return;
+
+	for (i = 0; i < IMR_NUM; i++) {
+		reg = cd->gpc_base + cd->cpu2wakeup + i * 4;
+		writel_relaxed(cd->saved_irq_mask[i], reg);
+	}
+}
+
+static struct syscore_ops imx_gpcv2_syscore_ops = {
+	.suspend	= gpcv2_wakeup_source_save,
+	.resume		= gpcv2_wakeup_source_restore,
+};
+
+static int imx_gpcv2_irq_set_wake(struct irq_data *d, unsigned int on)
+{
+	struct gpcv2_irqchip_data *cd = d->chip_data;
+	unsigned int idx = d->hwirq / 32;
+	unsigned long flags;
+	void __iomem *reg;
+	u32 mask, val;
+
+	raw_spin_lock_irqsave(&cd->rlock, flags);
+	reg = cd->gpc_base + cd->cpu2wakeup + idx * 4;
+	mask = 1 << d->hwirq % 32;
+	val = cd->wakeup_sources[idx];
+
+	cd->wakeup_sources[idx] = on ? (val & ~mask) : (val | mask);
+	raw_spin_unlock_irqrestore(&cd->rlock, flags);
+
+	/*
+	 * Do *not* call into the parent, as the GIC doesn't have any
+	 * wake-up facility...
+	 */
+
+	return 0;
+}
+
+static void imx_gpcv2_irq_unmask(struct irq_data *d)
+{
+	struct gpcv2_irqchip_data *cd = d->chip_data;
+	void __iomem *reg;
+	u32 val;
+
+	raw_spin_lock(&cd->rlock);
+	reg = cd->gpc_base + cd->cpu2wakeup + d->hwirq / 32 * 4;
+	val = readl_relaxed(reg);
+	val &= ~(1 << d->hwirq % 32);
+	writel_relaxed(val, reg);
+	raw_spin_unlock(&cd->rlock);
+
+	irq_chip_unmask_parent(d);
+}
+
+static void imx_gpcv2_irq_mask(struct irq_data *d)
+{
+	struct gpcv2_irqchip_data *cd = d->chip_data;
+	void __iomem *reg;
+	u32 val;
+
+	raw_spin_lock(&cd->rlock);
+	reg = cd->gpc_base + cd->cpu2wakeup + d->hwirq / 32 * 4;
+	val = readl_relaxed(reg);
+	val |= 1 << (d->hwirq % 32);
+	writel_relaxed(val, reg);
+	raw_spin_unlock(&cd->rlock);
+
+	irq_chip_mask_parent(d);
+}
+
+static struct irq_chip gpcv2_irqchip_data_chip = {
+	.name			= "GPCv2",
+	.irq_eoi		= irq_chip_eoi_parent,
+	.irq_mask		= imx_gpcv2_irq_mask,
+	.irq_unmask		= imx_gpcv2_irq_unmask,
+	.irq_set_wake		= imx_gpcv2_irq_set_wake,
+	.irq_retrigger		= irq_chip_retrigger_hierarchy,
+#ifdef CONFIG_SMP
+	.irq_set_affinity	= irq_chip_set_affinity_parent,
+#endif
+};
+
+static int imx_gpcv2_domain_xlate(struct irq_domain *domain,
+				struct device_node *controller,
+				const u32 *intspec,
+				unsigned int intsize,
+				unsigned long *out_hwirq,
+				unsigned int *out_type)
+{
+	/* Shouldn't happen, really... */
+	if (domain->of_node != controller)
+		return -EINVAL;
+
+	/* Not GIC compliant */
+	if (intsize != 3)
+		return -EINVAL;
+
+	/* No PPI should point to this domain */
+	if (intspec[0] != 0)
+		return -EINVAL;
+
+	*out_hwirq = intspec[1];
+	*out_type = intspec[2];
+	return 0;
+}
+
+static int imx_gpcv2_domain_alloc(struct irq_domain *domain,
+				  unsigned int irq, unsigned int nr_irqs,
+				  void *data)
+{
+	struct of_phandle_args *args = data;
+	struct of_phandle_args parent_args;
+	irq_hw_number_t hwirq;
+	int i;
+
+	/* Not GIC compliant */
+	if (args->args_count != 3)
+		return -EINVAL;
+
+	/* No PPI should point to this domain */
+	if (args->args[0] != 0)
+		return -EINVAL;
+
+	/* Can't deal with this */
+	hwirq = args->args[1];
+	if (hwirq >= GPC_MAX_IRQS)
+		return -EINVAL;
+
+	for (i = 0; i < nr_irqs; i++) {
+		irq_domain_set_hwirq_and_chip(domain, irq + i, hwirq + i,
+				&gpcv2_irqchip_data_chip, domain->host_data);
+	}
+
+	parent_args = *args;
+	parent_args.np = domain->parent->of_node;
+	return irq_domain_alloc_irqs_parent(domain, irq, nr_irqs, &parent_args);
+}
+
+static struct irq_domain_ops gpcv2_irqchip_data_domain_ops = {
+	.xlate	= imx_gpcv2_domain_xlate,
+	.alloc	= imx_gpcv2_domain_alloc,
+	.free	= irq_domain_free_irqs_common,
+};
+
+static int __init imx_gpcv2_irqchip_init(struct device_node *node,
+			       struct device_node *parent)
+{
+	struct irq_domain *parent_domain, *domain;
+	struct gpcv2_irqchip_data *cd;
+	int i;
+
+	if (!parent) {
+		pr_err("%s: no parent, giving up\n", node->full_name);
+		return -ENODEV;
+	}
+
+	parent_domain = irq_find_host(parent);
+	if (!parent_domain) {
+		pr_err("%s: unable to get parent domain\n", node->full_name);
+		return -ENXIO;
+	}
+
+	cd = kzalloc(sizeof(struct gpcv2_irqchip_data), GFP_KERNEL);
+	if (!cd) {
+		pr_err("kzalloc failed!\n");
+		return -ENOMEM;
+	}
+
+	cd->gpc_base = of_iomap(node, 0);
+	if (!cd->gpc_base) {
+		pr_err("fsl-gpcv2: unable to map gpc registers\n");
+		kfree(cd);
+		return -ENOMEM;
+	}
+
+	domain = irq_domain_add_hierarchy(parent_domain, 0, GPC_MAX_IRQS,
+				node, &gpcv2_irqchip_data_domain_ops, cd);
+	if (!domain) {
+		iounmap(cd->gpc_base);
+		kfree(cd);
+		return -ENOMEM;
+	}
+	irq_set_default_host(domain);
+
+	/* Initially mask all interrupts */
+	for (i = 0; i < IMR_NUM; i++) {
+		writel_relaxed(~0, cd->gpc_base + GPC_IMR1_CORE0 + i * 4);
+		writel_relaxed(~0, cd->gpc_base + GPC_IMR1_CORE1 + i * 4);
+		cd->wakeup_sources[i] = ~0;
+	}
+
+	/* Let CORE0 as the default CPU to wake up by GPC */
+	cd->cpu2wakeup = GPC_IMR1_CORE0;
+
+	/*
+	 * Due to hardware design failure, need to make sure GPR
+	 * interrupt(#32) is unmasked during RUN mode to avoid entering
+	 * DSM by mistake.
+	 */
+	writel_relaxed(~0x1, cd->gpc_base + cd->cpu2wakeup);
+
+	imx_gpcv2_instance = cd;
+	register_syscore_ops(&imx_gpcv2_syscore_ops);
+
+	return 0;
+}
+
+IRQCHIP_DECLARE(imx_gpcv2, "fsl,imx7d-gpc", imx_gpcv2_irqchip_init);
--
2.5.0.rc2




From Suravee.Suthikulpanit at amd.com  Mon Aug 24 12:09:42 2015
From: Suravee.Suthikulpanit at amd.com (Suravee Suthikulpanit)
Date: Tue, 25 Aug 2015 02:09:42 +0700
Subject: [PATCH] pci: acpi: Generic function for setting up PCI device DMA
 coherency
In-Reply-To: <CAErSpo7yN08tKyo-yyyVG58vUptbHGN=L+MEZ8TQy1gm5a1_0Q@mail.gmail.com>
References: <1439459925-2361-1-git-send-email-Suravee.Suthikulpanit@amd.com>
 <20150814015004.GA26431@google.com>
 <CAErSpo7yN08tKyo-yyyVG58vUptbHGN=L+MEZ8TQy1gm5a1_0Q@mail.gmail.com>
Message-ID: <55DB6BF6.1030206@amd.com>

Hi Bjorn,

On 8/25/15 00:32, Bjorn Helgaas wrote:
> Here it is again.
>
> On Thu, Aug 13, 2015 at 6:50 PM, Bjorn Helgaas <bhelgaas at google.com> wrote:
>> Hi Suravee,
>>
>> On Thu, Aug 13, 2015 at 04:58:45PM +0700, Suravee Suthikulpanit wrote:
>>> This patch refactors of_pci_dma_configure() into a more generic
>>> pci_dma_configure(), which can be reused by non-OF code.
>>> Then, it adds support for setting up PCI device DMA coherency from
>>> ACPI _CCA object that should normally be specified in the DSDT node
>>> of its PCI host bridge..
>>
>> Since this does two things:
>>    1) Rename of_pci_dma_configure() and move it to PCI
>>    2) Add _CCA support,
>> maybe it should be split into two patches?

Sure, I can take care of that and separate them into two patches.

>> There are a couple more comments below.
>>
>> While looking at this, I thought some of the existing code could be
>> made simpler and easier to follow.  I appended a couple possible patches;
>> you can incorporate them or ignore them, whatever seems best to you.
>>
>> Bjorn

Please see my response below.

>> [...]
>>> diff --git a/drivers/pci/probe.c b/drivers/pci/probe.c
>>> index cefd636..e2fcd3b 100644
>>> --- a/drivers/pci/probe.c
>>> +++ b/drivers/pci/probe.c
>>> @@ -6,12 +6,14 @@
>>>   #include <linux/delay.h>
>>>   #include <linux/init.h>
>>>   #include <linux/pci.h>
>>> -#include <linux/of_pci.h>
>>> +#include <linux/of_device.h>
>>>   #include <linux/pci_hotplug.h>
>>>   #include <linux/slab.h>
>>>   #include <linux/module.h>
>>>   #include <linux/cpumask.h>
>>>   #include <linux/pci-aspm.h>
>>> +#include <linux/acpi.h>
>>> +#include <linux/property.h>
>>>   #include <asm-generic/pci-bridge.h>
>>>   #include "pci.h"
>>>
>>> @@ -1544,6 +1546,35 @@ static void pci_init_capabilities(struct pci_dev *dev)
>>>        pci_enable_acs(dev);
>>>   }
>>>
>>> +/**
>>> + * pci_dma_configure - Setup DMA configuration
>>> + * @pci_dev: ptr to pci_dev struct of the PCI device
>>> + *
>>> + * Function to update PCI devices's DMA configuration using the same
>>> + * info from the OF node or ACPI node of host bridge's parent (if any).
>>> + */
>>> +static void pci_dma_configure(struct pci_dev *pci_dev)
>>
>> Almost all pci_dev pointers in probe.c are named "dev", so I would use
>> that for this one, too.  I probably would just drop the "struct device
>> *dev" below and use "&dev->dev" the two places you need it.  That's a
>> common idiom in PCI.
>>
I'll take care of this.

>>> +{
>>> +     struct device *dev = &pci_dev->dev;
>>> +     struct device *bridge = pci_get_host_bridge_device(pci_dev);
>>> +     struct acpi_device *adev;
>>> +     bool coherent;
>>> +
>>> +     if (has_acpi_companion(bridge)) {
>>> +             adev = to_acpi_node(bridge->fwnode);
>>> +             if (acpi_check_dma(adev, &coherent))
>>> +                     arch_setup_dma_ops(dev, 0, 0, NULL, coherent);
>>> +     } else {
>>> +             struct device *host = bridge->parent;
>>> +             if (!host)
>>> +                     return;
>>> +
>>> +             of_dma_configure(dev, host->of_node);
>>> +     }
>>
>> Why is this check reversed with respect to device_dma_is_coherent()?
>> In device_dma_is_coherent(), we first look for an OF property, then look
>> for ACPI _CCA.  But here we check for _CCA, then for OF.
>>
I was trying to save some additional logic. But, think again I should 
not have done so. I'll fix this.

>> [...]
>> commit 18183957888f601807ca0e166516ae60f682eb62
>> Author: Bjorn Helgaas <bhelgaas at google.com>
>> Date:   Thu Aug 13 20:01:21 2015 -0500
>>
>>      ACPI / scan: Move _CCA comments to acpi_init_coherency()
>>
>>      Move the comments about how we handle _CCA to the code that looks at _CCA,
>>      and fix a couple typos.
>>
>>      No functional change.
>>
>>      Signed-off-by: Bjorn Helgaas <bhelgaas at google.com>
>>
>> diff --git a/drivers/acpi/scan.c b/drivers/acpi/scan.c
>> index ec25635..a12e522 100644
>> --- a/drivers/acpi/scan.c
>> +++ b/drivers/acpi/scan.c
>> @@ -2188,6 +2188,22 @@ static void acpi_init_coherency(struct acpi_device *adev)
>>          acpi_status status;
>>          struct acpi_device *parent = adev->parent;
>>
>> +       /**
>> +        * Currently, we only support _CCA=1 (i.e. coherent_dma=1)
>> +        * This should be equivalent to specifying dma-coherent for
>> +        * a device in OF.
>> +        *
>> +        * For the case when _CCA=0 (i.e. coherent_dma=0 && cca_seen=1),
>> +        * we have two choices:
>> +        * case 1. Do not support and disable DMA.
>> +        * case 2. Support but rely on arch-specific cache maintenance for
>> +        *         non-coherent DMA operations.
>> +        * Currently, we implement case 1 above.
>> +        *
>> +        * For the case when _CCA is missing (i.e. cca_seen=0) and
>> +        * platform specifies ACPI_CCA_REQUIRED, we do not support DMA,
>> +        * and fallback to arch-specific default handling.
>> +        */
>>          if (parent && parent->flags.cca_seen) {
>>                  /*
>>                   * From ACPI spec, OSPM will ignore _CCA if an ancestor
>> diff --git a/include/acpi/acpi_bus.h b/include/acpi/acpi_bus.h
>> index 83061ca..718942b 100644
>> --- a/include/acpi/acpi_bus.h
>> +++ b/include/acpi/acpi_bus.h
>> @@ -389,24 +389,6 @@ static inline bool acpi_check_dma(struct acpi_device *adev, bool *coherent)
>>          if (!adev)
>>                  return ret;
>>
>> -       /**
>> -        * Currently, we only support _CCA=1 (i.e. coherent_dma=1)
>> -        * This should be equivalent to specifyig dma-coherent for
>> -        * a device in OF.
>> -        *
>> -        * For the case when _CCA=0 (i.e. coherent_dma=0 && cca_seen=1),
>> -        * There are two cases:
>> -        * case 1. Do not support and disable DMA.
>> -        * case 2. Support but rely on arch-specific cache maintenance for
>> -        *         non-coherence DMA operations.
>> -        * Currently, we implement case 1 above.
>> -        *
>> -        * For the case when _CCA is missing (i.e. cca_seen=0) and
>> -        * platform specifies ACPI_CCA_REQUIRED, we do not support DMA,
>> -        * and fallback to arch-specific default handling.
>> -        *
>> -        * See acpi_init_coherency() for more info.
>> -        */
>>          if (adev->flags.coherent_dma) {
>>                  ret = true;
>>                  if (coherent)
>>

Actually, the reason I put the comment in the acpi_check_dma() is 
because the logic for determining the coherency is in this function, 
which is separate from the CCA parsing/detection logic.

I can probably just get rid of the inline and move the whole function 
into /driver/acpi/scan.c to make it more readable, and fix the typos.

>> commit 84cfb2213cd400fef227ec0d7829ec4e12895da9
>> Author: Bjorn Helgaas <bhelgaas at google.com>
>> Date:   Thu Aug 13 19:49:52 2015 -0500
>>
>>      ACPI / scan: Rename acpi_check_dma() to acpi_dma_is_coherent()
>>
>>      The name "acpi_check_dma()" doesn't give any much indication about what
>>      exactly it checks.  The function also returns information both as a normal
>>      return value and as the "bool *coherent" return parameter.  But "*coherent"
>>      doesn't actually give any extra information: it is unchanged when returning
>>      false and set to true when returning true.
>>
>>      Rename acpi_check_dma() to acpi_dma_is_coherent() so the callers read more
>>      naturally.  Drop the return parameter and just use the function return
>>      value.
>>
>>      Signed-off-by: Bjorn Helgaas <bhelgaas at google.com>

This was because, at one point, we wanted to be able to differentiate 
between the case _CCA=0 and missing _CCA in ARM64, where we would 
support DMA (using arch-specific cache maintenance) if _CCA=0, and 
disable DMA when missing _CCA on ARM64.

It seems like the logic is now required (please see 
https://www.mail-archive.com/linux-usb at vger.kernel.org/msg62735.html). 
So, we would need the true/false return, and the coherent variable to be 
able to differentiate between the two cases.

Please let me know what you think.

Thanks,
Suravee



From linux at arm.linux.org.uk  Mon Aug 24 12:14:28 2015
From: linux at arm.linux.org.uk (Russell King - ARM Linux)
Date: Mon, 24 Aug 2015 20:14:28 +0100
Subject: Prevent list poison values from being mapped by userspace
 processes
In-Reply-To: <CAGXu5jJFf+9OgnGt_Cx5Q-Pht7LAT7M-sSXftTDORybrr+SECg@mail.gmail.com>
References: <CABXk95C=CpeL4mNmS6-jJ-0bMJf6fawwfs6DM1-p8FctTEFbpw@mail.gmail.com>
 <20150821133043.GV7557@n2100.arm.linux.org.uk>
 <CAGXu5jJ8KOoVkx99rrajEEx77Z6zO4TzCXaXkB74zv9QQFuJFw@mail.gmail.com>
 <20150824184709.GE7557@n2100.arm.linux.org.uk>
 <CAGXu5jJFf+9OgnGt_Cx5Q-Pht7LAT7M-sSXftTDORybrr+SECg@mail.gmail.com>
Message-ID: <20150824191427.GF7557@n2100.arm.linux.org.uk>

On Mon, Aug 24, 2015 at 11:51:04AM -0700, Kees Cook wrote:
> On Mon, Aug 24, 2015 at 11:47 AM, Russell King - ARM Linux
> <linux at arm.linux.org.uk> wrote:
> > That's something which Catalin indicated that he'll work on.  However,
> > he said in a public email last week that he won't be around for a while.
> >
> > So, I have no immediate solution for LPAE - it looks like LPAE will
> > require switching the page tables on kernel entry or exit, and again
> > each and every time we want to perform a userspace access.  How this
> > is done is not something that has been discussed, and neither do we
> > yet know how expensive this will be.  There are a number of places in
> > the kernel where a large number of get_user()s or put_user()s follow
> > one after each other, which necessitates switching back and forth
> > multiple times.  We may need to address some of those areas by
> > converting them to copy_(to|from)_user().
> 
> By the way, have you looked at grsecurity's implementation of these
> protections? They've been using domains for a while now, and I think
> have an LPAE solution as well.

*Sigh*.

No, and I really don't care - if people want to do development work out
of the mainline kernel and not bother to talk about getting it upstream,
it's their loss.  As far as I'm concerned, such external work doesn't
exist.

-- 
FTTC broadband for 0.8mile line: currently at 10.5Mbps down 400kbps up
according to speedtest.net.


From tglx at linutronix.de  Mon Aug 24 12:14:59 2015
From: tglx at linutronix.de (Thomas Gleixner)
Date: Mon, 24 Aug 2015 21:14:59 +0200 (CEST)
Subject: [PATCH v9 1/1] irqchip: imx-gpcv2: IMX GPCv2 driver for wakeup
 sources
In-Reply-To: <1440443055-7291-1-git-send-email-shenwei.wang@freescale.com>
References: <1440443055-7291-1-git-send-email-shenwei.wang@freescale.com>
Message-ID: <alpine.DEB.2.11.1508242112450.15006@nanos>

On Mon, 24 Aug 2015, Shenwei Wang wrote:
> 
> Signed-off-by: Shenwei Wang <shenwei.wang at freescale.com>
> Signed-off-by: Anson Huang <b20788 at freescale.com>

Ok, last question. How is Anson related to this? He did not convey
your patch and in the first posted versions his SOB was never there.

Thanks,

	tglx


From Shenwei.Wang at freescale.com  Mon Aug 24 12:20:51 2015
From: Shenwei.Wang at freescale.com (Shenwei Wang)
Date: Mon, 24 Aug 2015 19:20:51 +0000
Subject: [PATCH v9 1/1] irqchip: imx-gpcv2: IMX GPCv2 driver for wakeup
 sources
In-Reply-To: <alpine.DEB.2.11.1508242112450.15006@nanos>
References: <1440443055-7291-1-git-send-email-shenwei.wang@freescale.com>
 <alpine.DEB.2.11.1508242112450.15006@nanos>
Message-ID: <BY1PR0301MB0839B96E88B2CCFF8A9D794783620@BY1PR0301MB0839.namprd03.prod.outlook.com>


> -----Original Message-----
> From: Thomas Gleixner [mailto:tglx at linutronix.de]
> Sent: 2015?8?24? 14:15
> To: Wang Shenwei-B38339
> Cc: shawn.guo at linaro.org; jason at lakedaemon.net;
> linux-arm-kernel at lists.infradead.org; linux-kernel at vger.kernel.org; Huang
> Yongcai-B20788
> Subject: Re: [PATCH v9 1/1] irqchip: imx-gpcv2: IMX GPCv2 driver for wakeup
> sources
> 
> On Mon, 24 Aug 2015, Shenwei Wang wrote:
> >
> > Signed-off-by: Shenwei Wang <shenwei.wang at freescale.com>
> > Signed-off-by: Anson Huang <b20788 at freescale.com>
> 
> Ok, last question. How is Anson related to this? He did not convey your patch and
> in the first posted versions his SOB was never there.

This patch was based on his internal version of GPCv2 driver. I reused some of his
implementation and ported it to latest linux kernel. Adding his name here to give 
the credits to him.

Thanks,
Shenwei
 

> Thanks,
> 
> 	tglx

From keescook at chromium.org  Mon Aug 24 12:22:33 2015
From: keescook at chromium.org (Kees Cook)
Date: Mon, 24 Aug 2015 12:22:33 -0700
Subject: Prevent list poison values from being mapped by userspace
 processes
In-Reply-To: <20150824191427.GF7557@n2100.arm.linux.org.uk>
References: <CABXk95C=CpeL4mNmS6-jJ-0bMJf6fawwfs6DM1-p8FctTEFbpw@mail.gmail.com>
 <20150821133043.GV7557@n2100.arm.linux.org.uk>
 <CAGXu5jJ8KOoVkx99rrajEEx77Z6zO4TzCXaXkB74zv9QQFuJFw@mail.gmail.com>
 <20150824184709.GE7557@n2100.arm.linux.org.uk>
 <CAGXu5jJFf+9OgnGt_Cx5Q-Pht7LAT7M-sSXftTDORybrr+SECg@mail.gmail.com>
 <20150824191427.GF7557@n2100.arm.linux.org.uk>
Message-ID: <CAGXu5jLW-nfUr40cit25_GsBrPJ6e0topdBQ1RY6vSm2dBFyDA@mail.gmail.com>

On Mon, Aug 24, 2015 at 12:14 PM, Russell King - ARM Linux
<linux at arm.linux.org.uk> wrote:
> On Mon, Aug 24, 2015 at 11:51:04AM -0700, Kees Cook wrote:
>> On Mon, Aug 24, 2015 at 11:47 AM, Russell King - ARM Linux
>> <linux at arm.linux.org.uk> wrote:
>> > That's something which Catalin indicated that he'll work on.  However,
>> > he said in a public email last week that he won't be around for a while.
>> >
>> > So, I have no immediate solution for LPAE - it looks like LPAE will
>> > require switching the page tables on kernel entry or exit, and again
>> > each and every time we want to perform a userspace access.  How this
>> > is done is not something that has been discussed, and neither do we
>> > yet know how expensive this will be.  There are a number of places in
>> > the kernel where a large number of get_user()s or put_user()s follow
>> > one after each other, which necessitates switching back and forth
>> > multiple times.  We may need to address some of those areas by
>> > converting them to copy_(to|from)_user().
>>
>> By the way, have you looked at grsecurity's implementation of these
>> protections? They've been using domains for a while now, and I think
>> have an LPAE solution as well.
>
> *Sigh*.
>
> No, and I really don't care - if people want to do development work out
> of the mainline kernel and not bother to talk about getting it upstream,
> it's their loss.  As far as I'm concerned, such external work doesn't
> exist.

Sure, I understand, but it's worth at least looking at to compare
feature sets. For example, when doing the W^X kernel memory work, I
looked at both qcom and spender's work, trying to get the best of both
into upstreamable shape.

-Kees

-- 
Kees Cook
Chrome OS Security


From tj at kernel.org  Mon Aug 24 12:24:53 2015
From: tj at kernel.org (Tejun Heo)
Date: Mon, 24 Aug 2015 15:24:53 -0400
Subject: ahci_imx: can read corrupted data successfully
In-Reply-To: <20150824105501.GX7557@n2100.arm.linux.org.uk>
References: <20150824105501.GX7557@n2100.arm.linux.org.uk>
Message-ID: <20150824192453.GD28944@mtj.duckdns.org>

Hello, Russell.

On Mon, Aug 24, 2015 at 11:55:01AM +0100, Russell King - ARM Linux wrote:
> I've no idea how this is happening, but it appears that it's possible
> to read corrupted data over an eSATA link.
> 
> The setup is a Solid-run Cubox-i4pro connected to an external eSATA 2.5"
> enclosure with a Corsair Neutron 128GB SSD.
> 
> While the issue seems to be the generally poor quality of eSATA cables
> (I have two eSATA enclosures, the other enclosure's eSATA cable
> interferes with a Logitech wireless receiver - I've had to wrap the
> cable in aluminium foil.)  However, it shouldn't be possible to
> successfully read faulty data in that condition - and this is what I
> find most worrying.
> 
> What I've noticed is that at boot, the the SSD is sometimes properly
> detected, other times it isn't:
...
> ata1.00: ATA-8: Corsair Neutron SSD, M311, max UDMA/133
> ata1.00: 250069680 sectors, multi 1: LBA48 NCQ (depth 31/32)
...
> ata1: SATA link up 3.0 Gbps (SStatus 123 SControl 300)
> ata1.00: ATA-8: , , max UDMA/133
> ata1.00: 250069680 sectors, multi 1: LBA48
...

It'd be interesting to see the ID data being returned.
"libata.force=dump_id" should do it but bit flips during transfer or
outright incorrect DMA won't lead to the above result.  Looks more
like the firmware on the drive side getting terminally confused.

...
> How does SATA ensure command and data integrity over the link?  I'd
> assume that there's a CRC present on the data, like UDMA on PATA.  How
> are CRC errors supposed to be reported?  Is it possible that ahci_imx
> and other layers are not properly checking for CRC errors?

IIRC, the 8/10b encoding does running parity and there's per-frame
(packet) CRC too.  Link and frame integrity is always checked by
hardware.  Reporting and handling can be different depending on which
party detects the error tho.

> Any ideas what to look at?
> 
> Anyone got any suggestions on where to get a good quality, but not
> stupidly expensive eSATA cable from?
> 
> I'm waiting for it to happen again, and I'll dump out more of the drive's
> "contents" when the cable is bad.  If it is the drive's firmware, it
> should contain the manufacturer name/model somewhere in the image.

I highly doubt this is something happening on the controller / link
side.  Looks like a messed up drive firmware to me.

Thanks.

-- 
tejun


From tglx at linutronix.de  Mon Aug 24 12:30:20 2015
From: tglx at linutronix.de (Thomas Gleixner)
Date: Mon, 24 Aug 2015 21:30:20 +0200 (CEST)
Subject: [PATCH v9 1/1] irqchip: imx-gpcv2: IMX GPCv2 driver for wakeup
 sources
In-Reply-To: <BY1PR0301MB0839B96E88B2CCFF8A9D794783620@BY1PR0301MB0839.namprd03.prod.outlook.com>
References: <1440443055-7291-1-git-send-email-shenwei.wang@freescale.com>
 <alpine.DEB.2.11.1508242112450.15006@nanos>
 <BY1PR0301MB0839B96E88B2CCFF8A9D794783620@BY1PR0301MB0839.namprd03.prod.outlook.com>
Message-ID: <alpine.DEB.2.11.1508242127230.15006@nanos>

On Mon, 24 Aug 2015, Shenwei Wang wrote:
> > Ok, last question. How is Anson related to this? He did not convey your patch and
> > in the first posted versions his SOB was never there.
> 
> This patch was based on his internal version of GPCv2 driver. I reused some of his
> implementation and ported it to latest linux kernel. Adding his name here to give 
> the credits to him.

So the proper way to express this is:

Based-on-a-patch-by: Anson
Signed-off-by: You

The way you did it suggests that you wrote it and Anson conveyed it,
which is not the case.

I'll change it that way then.

Thanks,

	tglx



From Shenwei.Wang at freescale.com  Mon Aug 24 12:32:53 2015
From: Shenwei.Wang at freescale.com (Shenwei Wang)
Date: Mon, 24 Aug 2015 19:32:53 +0000
Subject: [PATCH v9 1/1] irqchip: imx-gpcv2: IMX GPCv2 driver for wakeup
 sources
In-Reply-To: <alpine.DEB.2.11.1508242127230.15006@nanos>
References: <1440443055-7291-1-git-send-email-shenwei.wang@freescale.com>
 <alpine.DEB.2.11.1508242112450.15006@nanos>
 <BY1PR0301MB0839B96E88B2CCFF8A9D794783620@BY1PR0301MB0839.namprd03.prod.outlook.com>
 <alpine.DEB.2.11.1508242127230.15006@nanos>
Message-ID: <BY1PR0301MB083938F8FF90B12466F9F64883620@BY1PR0301MB0839.namprd03.prod.outlook.com>

Thank you, Thomas!

Shenwei

> -----Original Message-----
> From: Thomas Gleixner [mailto:tglx at linutronix.de]
> Sent: 2015?8?24? 14:30
> To: Wang Shenwei-B38339
> Cc: shawn.guo at linaro.org; jason at lakedaemon.net;
> linux-arm-kernel at lists.infradead.org; linux-kernel at vger.kernel.org; Huang
> Yongcai-B20788
> Subject: RE: [PATCH v9 1/1] irqchip: imx-gpcv2: IMX GPCv2 driver for wakeup
> sources
> 
> On Mon, 24 Aug 2015, Shenwei Wang wrote:
> > > Ok, last question. How is Anson related to this? He did not convey
> > > your patch and in the first posted versions his SOB was never there.
> >
> > This patch was based on his internal version of GPCv2 driver. I reused
> > some of his implementation and ported it to latest linux kernel.
> > Adding his name here to give the credits to him.
> 
> So the proper way to express this is:
> 
> Based-on-a-patch-by: Anson
> Signed-off-by: You
> 
> The way you did it suggests that you wrote it and Anson conveyed it, which is not
> the case.
> 
> I'll change it that way then.
> 
> Thanks,
> 
> 	tglx


From linux at arm.linux.org.uk  Mon Aug 24 12:32:56 2015
From: linux at arm.linux.org.uk (Russell King - ARM Linux)
Date: Mon, 24 Aug 2015 20:32:56 +0100
Subject: Prevent list poison values from being mapped by userspace
 processes
In-Reply-To: <CAGXu5jLW-nfUr40cit25_GsBrPJ6e0topdBQ1RY6vSm2dBFyDA@mail.gmail.com>
References: <CABXk95C=CpeL4mNmS6-jJ-0bMJf6fawwfs6DM1-p8FctTEFbpw@mail.gmail.com>
 <20150821133043.GV7557@n2100.arm.linux.org.uk>
 <CAGXu5jJ8KOoVkx99rrajEEx77Z6zO4TzCXaXkB74zv9QQFuJFw@mail.gmail.com>
 <20150824184709.GE7557@n2100.arm.linux.org.uk>
 <CAGXu5jJFf+9OgnGt_Cx5Q-Pht7LAT7M-sSXftTDORybrr+SECg@mail.gmail.com>
 <20150824191427.GF7557@n2100.arm.linux.org.uk>
 <CAGXu5jLW-nfUr40cit25_GsBrPJ6e0topdBQ1RY6vSm2dBFyDA@mail.gmail.com>
Message-ID: <20150824193256.GG7557@n2100.arm.linux.org.uk>

On Mon, Aug 24, 2015 at 12:22:33PM -0700, Kees Cook wrote:
> On Mon, Aug 24, 2015 at 12:14 PM, Russell King - ARM Linux
> <linux at arm.linux.org.uk> wrote:
> > On Mon, Aug 24, 2015 at 11:51:04AM -0700, Kees Cook wrote:
> >> On Mon, Aug 24, 2015 at 11:47 AM, Russell King - ARM Linux
> >> <linux at arm.linux.org.uk> wrote:
> >> > That's something which Catalin indicated that he'll work on.  However,
> >> > he said in a public email last week that he won't be around for a while.
> >> >
> >> > So, I have no immediate solution for LPAE - it looks like LPAE will
> >> > require switching the page tables on kernel entry or exit, and again
> >> > each and every time we want to perform a userspace access.  How this
> >> > is done is not something that has been discussed, and neither do we
> >> > yet know how expensive this will be.  There are a number of places in
> >> > the kernel where a large number of get_user()s or put_user()s follow
> >> > one after each other, which necessitates switching back and forth
> >> > multiple times.  We may need to address some of those areas by
> >> > converting them to copy_(to|from)_user().
> >>
> >> By the way, have you looked at grsecurity's implementation of these
> >> protections? They've been using domains for a while now, and I think
> >> have an LPAE solution as well.
> >
> > *Sigh*.
> >
> > No, and I really don't care - if people want to do development work out
> > of the mainline kernel and not bother to talk about getting it upstream,
> > it's their loss.  As far as I'm concerned, such external work doesn't
> > exist.
> 
> Sure, I understand, but it's worth at least looking at to compare
> feature sets. For example, when doing the W^X kernel memory work, I
> looked at both qcom and spender's work, trying to get the best of both
> into upstreamable shape.

That's one way of looking at it.

Another way of looking at it is that by looking at their work, and
merging their ideas into your own, it becomes an encouragement for
working outside of mainline - not only do they get the kernel itself
free, but they get their feature merged without themselves doing any
work - while some other bugger has to sort out making their code
mergable.

Therefore, my standard point of view is that if people can't be
bothered to talk about their ARM specific kernel features here with
a view to having them merged, they are leeching off the efforts of
the upstream kernel community, and their code just isn't worth
looking at.

I hold the same view on "community" kernel trees which don't bother
pushing their code upstream as well.

Sorry, I'm *not* supporting leeches.

I've already been accused this year by one very mistaken individual
for not pushing _my_ iMX6 work into community kernel trees - when
the work that I do is solely targetted at mainline kernels.  The
leeches are going mad, and I'm saying no more to this crap.  If it's
not talked about on a recognised mainline kernel mailing list, it
doesn't exist, and deserves to be rewritten.

-- 
FTTC broadband for 0.8mile line: currently at 10.5Mbps down 400kbps up
according to speedtest.net.


From agross at codeaurora.org  Mon Aug 24 12:36:14 2015
From: agross at codeaurora.org (Andy Gross)
Date: Mon, 24 Aug 2015 14:36:14 -0500
Subject: [PATCH 11/18] ARM: qcom: use const and __initconst for
 smp_operations
In-Reply-To: <1440390978-22796-12-git-send-email-yamada.masahiro@socionext.com>
References: <1440390978-22796-1-git-send-email-yamada.masahiro@socionext.com>
 <1440390978-22796-12-git-send-email-yamada.masahiro@socionext.com>
Message-ID: <20150824193614.GA16922@qualcomm.com>

On Mon, Aug 24, 2015 at 01:36:11PM +0900, Masahiro Yamada wrote:
> The smp_operations structure is not over-written, so add const
> qualifier and replace __initdata with __initconst.
> 
> Signed-off-by: Masahiro Yamada <yamada.masahiro at socionext.com>
> ---

Thanks!

Reviewed-by: Andy Gross <agross at codeaurora.org>

-- 
Qualcomm Innovation Center, Inc.
The Qualcomm Innovation Center, Inc. is a member of the Code Aurora Forum,
a Linux Foundation Collaborative Project



From lina.iyer at linaro.org  Mon Aug 24 12:50:32 2015
From: lina.iyer at linaro.org (Lina Iyer)
Date: Mon, 24 Aug 2015 13:50:32 -0600
Subject: [PATCH 2/9] PM / Domains: Remove dev->driver check for runtime PM
In-Reply-To: <7hio88gxpn.fsf@deeprootsystems.com>
References: <1438731339-58317-1-git-send-email-lina.iyer@linaro.org>
 <1438731339-58317-3-git-send-email-lina.iyer@linaro.org>
 <7hfv3onv5c.fsf@deeprootsystems.com>
 <CAMuHMdVeffa-jgXuSjDQBKTrhgW-d87OKzs1iXX+4y-9U_AJbg@mail.gmail.com>
 <7hwpwylepx.fsf@deeprootsystems.com>
 <CAMuHMdW-T9rUWXsQeffwtXspHbjfGqo_0G4QMB1o0TwTLJAQAg@mail.gmail.com>
 <CAMAWPa-0R42thqBo0omn0KK7y0wyxoyaP+wsfoRvXBmWhBytKg@mail.gmail.com>
 <CAMuHMdV2gDBaPRb3yE=tVPO_pr7PFA6bwhyQE5raumCh_qPXww@mail.gmail.com>
 <7hio88gxpn.fsf@deeprootsystems.com>
Message-ID: <20150824195032.GA1384@linaro.org>

On Fri, Aug 21 2015 at 15:04 -0600, Kevin Hilman wrote:
>Geert Uytterhoeven <geert at linux-m68k.org> writes:
>
>> Hi Kevin,
>>
>> On Fri, Aug 14, 2015 at 7:19 PM, Kevin Hilman <khilman at kernel.org> wrote:
>>> On Fri, Aug 14, 2015 at 12:24 AM, Geert Uytterhoeven
>>> <geert at linux-m68k.org> wrote:
>>>> On Fri, Aug 14, 2015 at 5:40 AM, Kevin Hilman <khilman at kernel.org> wrote:
>>>>> Geert Uytterhoeven <geert at linux-m68k.org> writes:
>>>>>> On Wed, Aug 12, 2015 at 9:50 PM, Kevin Hilman <khilman at kernel.org> wrote:
>>>>>>> This check might have made sense before PM domains, but with PM domains,
>>>>>>> it's entirely possible to have a simple device without a driver and the
>>>>>>> PM domain handles all the necesary PM, so I think this check
>>>>>>> could/should be removed.
>>>>>>>
>>>>>>> Thoughts?
>>>>>>
>>>>>> Simple devices without a driver aren't handled automatically.
>>>>>> At minimum, the driver should call pm_runtime_enable(), cfr.
>>>>>> drivers/bus/simple-pm-bus.c.
>>>>>
>>>>> That's correct, and in the proof-of-concept stuff I hacked up and in
>>>>> Lina's series, the CPU "devices" do indeed to this.  Without that, they
>>>>> wouldn't end up ever taking this codepath through genpd's
>>>>> runtime_suspend and power_off hooks.
>>>>>
>>>>> Also, I'm not sure if your comment was meant to be an objection to the
>>>>> patch?  or if you're OK with it.
>>>>
>>>> My comment was purely meant as a response to "it's entirely possible to have a
>>>> simple device without a driver and the PM domain handles all the necesary PM".
>>>
>>> Right, so if the PM domain does the pm_runtime_enable() for these
>>> "simple" devices without drivers, they can still exist without a
>>> driver, and the PM domain doing all the magic.
>>
>> Is it possible to let the PM Domain do the pm_runtime_enable() itself in
>> the absence of a driver?
>
>Well, I suppose it's possible, not sure it's recommended. :)
>
>> If yes, I wouldn't have needed simple-pm-bus.c.
>> What if a driver is bound later?
>
>Yeah, you're approach is better.
>
I am not sure I understand the approach? Initialize the CPU devices as
"simple-pm-bus" compatible?

Thanks,
Lina


From moritz.fischer at ettus.com  Mon Aug 24 12:58:40 2015
From: moritz.fischer at ettus.com (Moritz Fischer)
Date: Mon, 24 Aug 2015 15:58:40 -0400
Subject: [PATCH 17/18] ARM: zynq: use const and __initconst for
 smp_operations
In-Reply-To: <1440390978-22796-18-git-send-email-yamada.masahiro@socionext.com>
References: <1440390978-22796-1-git-send-email-yamada.masahiro@socionext.com>
 <1440390978-22796-18-git-send-email-yamada.masahiro@socionext.com>
Message-ID: <CAAtXAHcAVxcCdkh-ne9W=2vORwi6o3WH6-yADn7mtgM4aaGpxw@mail.gmail.com>

Acked-by: Moritz Fischer <moritz.fischer at ettus.com>

Thanks,

Moritz

On Mon, Aug 24, 2015 at 12:36 AM, Masahiro Yamada
<yamada.masahiro at socionext.com> wrote:
> The smp_operations structure is not over-written, so add const
> qualifier and replace __initdata with __initconst.
>
> Signed-off-by: Masahiro Yamada <yamada.masahiro at socionext.com>
> ---
>
>  arch/arm/mach-zynq/common.h  | 2 +-
>  arch/arm/mach-zynq/platsmp.c | 2 +-
>  2 files changed, 2 insertions(+), 2 deletions(-)
>
> diff --git a/arch/arm/mach-zynq/common.h b/arch/arm/mach-zynq/common.h
> index 79cda2e..e771933 100644
> --- a/arch/arm/mach-zynq/common.h
> +++ b/arch/arm/mach-zynq/common.h
> @@ -30,7 +30,7 @@ extern char zynq_secondary_trampoline;
>  extern char zynq_secondary_trampoline_jump;
>  extern char zynq_secondary_trampoline_end;
>  extern int zynq_cpun_start(u32 address, int cpu);
> -extern struct smp_operations zynq_smp_ops __initdata;
> +extern const struct smp_operations zynq_smp_ops;
>  #endif
>
>  extern void __iomem *zynq_scu_base;
> diff --git a/arch/arm/mach-zynq/platsmp.c b/arch/arm/mach-zynq/platsmp.c
> index f66816c..7cd9865 100644
> --- a/arch/arm/mach-zynq/platsmp.c
> +++ b/arch/arm/mach-zynq/platsmp.c
> @@ -157,7 +157,7 @@ static void zynq_cpu_die(unsigned int cpu)
>  }
>  #endif
>
> -struct smp_operations zynq_smp_ops __initdata = {
> +const struct smp_operations zynq_smp_ops __initconst = {
>         .smp_init_cpus          = zynq_smp_init_cpus,
>         .smp_prepare_cpus       = zynq_smp_prepare_cpus,
>         .smp_boot_secondary     = zynq_boot_secondary,
> --
> 1.9.1
>
>
> _______________________________________________
> linux-arm-kernel mailing list
> linux-arm-kernel at lists.infradead.org
> http://lists.infradead.org/mailman/listinfo/linux-arm-kernel


From arnd at arndb.de  Mon Aug 24 12:59:51 2015
From: arnd at arndb.de (Arnd Bergmann)
Date: Mon, 24 Aug 2015 21:59:51 +0200
Subject: [PATCH 1/3] ARM: uniphier: add outer cache support
In-Reply-To: <1440382692-3855-2-git-send-email-yamada.masahiro@socionext.com>
References: <1440382692-3855-1-git-send-email-yamada.masahiro@socionext.com>
 <1440382692-3855-2-git-send-email-yamada.masahiro@socionext.com>
Message-ID: <2021253.vgeYqalDfp@wuerfel>

On Monday 24 August 2015 11:18:10 Masahiro Yamada wrote:
> diff --git a/Documentation/devicetree/bindings/arm/uniphier/cache-uniphier.txt b/Documentation/devicetree/bindings/arm/uniphier/cache-uniphier.txt
> new file mode 100644
> index 0000000..6428289
> --- /dev/null
> +++ b/Documentation/devicetree/bindings/arm/uniphier/cache-uniphier.txt
> @@ -0,0 +1,30 @@
> +UniPhier outer cache controller
> +
> +UniPhier SoCs are integrated with a level 2 cache controller that resides
> +outside of the ARM cores, some of them also have a level 3 cache controller.
> +
> +Required properties:
> +- compatible: should be one of the followings:
> +       "socionext,uniphier-l2-cache"   (L2 cache)
> +       "socionext,uniphier-l3-cache"   (L3 cache)
> +- reg: offsets and lengths of the register sets for the device.  It should
> +  contain 3 regions: control registers, revision registers, operation
> +  registers, in this order.
> +
> +The L2 cache must exist to use the L3 cache; adding only an L3 cache device
> +node to the device tree causes the initialization failure of the whole outer
> +cache system.
> 

How much does this outer cache have in common with the l2x0/pl310 cache
controller model? Would it make sense to at least share the
common entry point at l2x0_of_init() so you don't need to call it from
the platform file?

	Arnd


From bhelgaas at google.com  Mon Aug 24 13:14:59 2015
From: bhelgaas at google.com (Bjorn Helgaas)
Date: Mon, 24 Aug 2015 13:14:59 -0700
Subject: [PATCH] pci: acpi: Generic function for setting up PCI device DMA
 coherency
In-Reply-To: <55DB6BF6.1030206@amd.com>
References: <1439459925-2361-1-git-send-email-Suravee.Suthikulpanit@amd.com>
 <20150814015004.GA26431@google.com>
 <CAErSpo7yN08tKyo-yyyVG58vUptbHGN=L+MEZ8TQy1gm5a1_0Q@mail.gmail.com>
 <55DB6BF6.1030206@amd.com>
Message-ID: <CAErSpo6TcwVH+TT5wZnLjOPMTa1NBoN=qJCev1rg1n_xFbggBQ@mail.gmail.com>

On Mon, Aug 24, 2015 at 12:09 PM, Suravee Suthikulpanit
<Suravee.Suthikulpanit at amd.com> wrote:

>>> commit 84cfb2213cd400fef227ec0d7829ec4e12895da9
>>> Author: Bjorn Helgaas <bhelgaas at google.com>
>>> Date:   Thu Aug 13 19:49:52 2015 -0500
>>>
>>>      ACPI / scan: Rename acpi_check_dma() to acpi_dma_is_coherent()
>>>
>>>      The name "acpi_check_dma()" doesn't give any much indication about
>>> what
>>>      exactly it checks.  The function also returns information both as a
>>> normal
>>>      return value and as the "bool *coherent" return parameter.  But
>>> "*coherent"
>>>      doesn't actually give any extra information: it is unchanged when
>>> returning
>>>      false and set to true when returning true.
>>>
>>>      Rename acpi_check_dma() to acpi_dma_is_coherent() so the callers
>>> read more
>>>      naturally.  Drop the return parameter and just use the function
>>> return
>>>      value.
>>>
>>>      Signed-off-by: Bjorn Helgaas <bhelgaas at google.com>
>
>
> This was because, at one point, we wanted to be able to differentiate
> between the case _CCA=0 and missing _CCA in ARM64, where we would support
> DMA (using arch-specific cache maintenance) if _CCA=0, and disable DMA when
> missing _CCA on ARM64.
>
> It seems like the logic is now required (please see
> https://www.mail-archive.com/linux-usb at vger.kernel.org/msg62735.html). So,
> we would need the true/false return, and the coherent variable to be able to
> differentiate between the two cases.
>
> Please let me know what you think.

It's hard for me to comment without seeing the actual patches.  I
think returning two values (_CCA-seen and coherent) is a confusing
interface.


From rjui at broadcom.com  Mon Aug 24 13:24:26 2015
From: rjui at broadcom.com (Ray Jui)
Date: Mon, 24 Aug 2015 13:24:26 -0700
Subject: [PATCH 05/18] ARM: BCM: use const and __initconst for
 smp_operations
In-Reply-To: <55DB6379.7040009@gmail.com>
References: <1440390978-22796-1-git-send-email-yamada.masahiro@socionext.com>
 <1440390978-22796-6-git-send-email-yamada.masahiro@socionext.com>
 <55DB6379.7040009@gmail.com>
Message-ID: <55DB7D7A.5070704@broadcom.com>



On 8/24/2015 11:33 AM, Florian Fainelli wrote:
> On 23/08/15 21:36, Masahiro Yamada wrote:
>> The smp_operations structure is not over-written, so add const
>> qualifier and replace __initdata with __initconst.
>>
>> Also, add static to bcm63138_smp_ops.
>>
>> Signed-off-by: Masahiro Yamada <yamada.masahiro at socionext.com>
> 
> For bcm63xx and brcmstb:
> 
> Reviewed-by: Florian Fainelli <f.fainelli at gmail.com>
> 
>> ---
>>
>>  arch/arm/mach-bcm/bcm63xx_smp.c     | 2 +-
>>  arch/arm/mach-bcm/kona_smp.c        | 2 +-
>>  arch/arm/mach-bcm/platsmp-brcmstb.c | 2 +-
>>  3 files changed, 3 insertions(+), 3 deletions(-)
>>
>> diff --git a/arch/arm/mach-bcm/bcm63xx_smp.c b/arch/arm/mach-bcm/bcm63xx_smp.c
>> index 19be904..9b6727e 100644
>> --- a/arch/arm/mach-bcm/bcm63xx_smp.c
>> +++ b/arch/arm/mach-bcm/bcm63xx_smp.c
>> @@ -161,7 +161,7 @@ static void __init bcm63138_smp_prepare_cpus(unsigned int max_cpus)
>>  	}
>>  }
>>  
>> -struct smp_operations bcm63138_smp_ops __initdata = {
>> +static const struct smp_operations bcm63138_smp_ops __initconst = {
>>  	.smp_prepare_cpus	= bcm63138_smp_prepare_cpus,
>>  	.smp_boot_secondary	= bcm63138_smp_boot_secondary,
>>  };
>> diff --git a/arch/arm/mach-bcm/kona_smp.c b/arch/arm/mach-bcm/kona_smp.c
>> index 66a0465..da8328b 100644
>> --- a/arch/arm/mach-bcm/kona_smp.c
>> +++ b/arch/arm/mach-bcm/kona_smp.c
>> @@ -194,7 +194,7 @@ static int bcm_boot_secondary(unsigned int cpu, struct task_struct *idle)
>>  	return -ENOSYS;
>>  }
>>  
>> -static struct smp_operations bcm_smp_ops __initdata = {
>> +static const struct smp_operations bcm_smp_ops __initconst = {
>>  	.smp_prepare_cpus	= bcm_smp_prepare_cpus,
>>  	.smp_boot_secondary	= bcm_boot_secondary,
>>  };

The change to kona_smp.c looks fine to me.

Signed-off-by: Ray Jui <rjui at broadcom.com>

Thanks,

Ray


From Shenwei.Wang at freescale.com  Mon Aug 24 13:26:12 2015
From: Shenwei.Wang at freescale.com (Shenwei Wang)
Date: Mon, 24 Aug 2015 20:26:12 +0000
Subject: [PATCH v3 1/1] misc: sram: add dev_pm_ops to support module power
 gate
In-Reply-To: <1438272681-29338-1-git-send-email-shenwei.wang@freescale.com>
References: <1438272681-29338-1-git-send-email-shenwei.wang@freescale.com>
Message-ID: <BY1PR0301MB0839FD550FAFB2F0C04B601183620@BY1PR0301MB0839.namprd03.prod.outlook.com>

Hi GregKH,

Can you please take a look at this patch? 

Thanks,
Shenwei

> -----Original Message-----
> From: linux-arm-kernel [mailto:linux-arm-kernel-bounces at lists.infradead.org] On
> Behalf Of Shenwei Wang
> Sent: 2015?7?30? 11:11
> To: gregkh at linuxfoundation.org; arnd at arndb.de
> Cc: Huang Yongcai-B20788; linux-arm-kernel at lists.infradead.org
> Subject: [PATCH v3 1/1] misc: sram: add dev_pm_ops to support module power
> gate
> 
> When system goes into low power states like SUSPEND_MEM and HIBERNATION,
> the hardware IP block may be powered off to reduce the power consumption.
> This power down will lost all the data inside the ram. This patch added the
> dev_pm_ops and implemented two callbacks: suspend_noirq and resume_noirq,
> which will save the data in the on-chip-ram right before power down and restore
> it after system resumes.
> 
> A new property string named "can-power-gate" is added to the devicetree
> bindings too.
> 
> Signed-off-by: Shenwei Wang <shenwei.wang at freescale.com>
> Signed-off-by: Anson Huang <b20788 at freescale.com>
> ---
> Change log:
> 
> PATCH v3
> 	Removed the unnecessary clk_enable/clk_disable.
> 
> PATCH v2
> 	Use vmalloc to allocate the SRAM backup memory.
> 	Code clean up.
> 
>  Documentation/devicetree/bindings/misc/sram.txt |  2 ++
>  drivers/misc/sram.c                             | 42
> +++++++++++++++++++++++++
>  2 files changed, 44 insertions(+)
> 
> diff --git a/Documentation/devicetree/bindings/misc/sram.txt
> b/Documentation/devicetree/bindings/misc/sram.txt
> index 36cbe5a..1170086 100644
> --- a/Documentation/devicetree/bindings/misc/sram.txt
> +++ b/Documentation/devicetree/bindings/misc/sram.txt
> @@ -33,6 +33,8 @@ Optional properties in the area nodes:
> 
>  - compatible : standard definition, should contain a vendor specific string
>                 in the form <vendor>,[<device>-]<usage>
> +- can-power-gate: a property to tell the driver that the sram can support
> +		power gate
> 
>  Example:
> 
> diff --git a/drivers/misc/sram.c b/drivers/misc/sram.c index 15c33cc..db9f1fa
> 100644
> --- a/drivers/misc/sram.c
> +++ b/drivers/misc/sram.c
> @@ -30,7 +30,9 @@
> 
>  struct sram_dev {
>  	struct device *dev;
> +	void *power_off_save;
>  	void __iomem *virt_base;
> +	u32 size;
> 
>  	struct gen_pool *pool;
>  	struct clk *clk;
> @@ -156,6 +158,33 @@ static int sram_reserve_regions(struct sram_dev
> *sram, struct resource *res)
>  	return ret;
>  }
> 
> +static int sram_suspend_noirq(struct device *dev) {
> +	struct platform_device *pdev = to_platform_device(dev);
> +	struct sram_dev *sram = platform_get_drvdata(pdev);
> +
> +	if (!sram->power_off_save)
> +		return 0;
> +
> +	/* Save necessary regs */
> +	memcpy(sram->power_off_save, sram->virt_base, sram->size);
> +
> +	return 0;
> +}
> +
> +static int sram_resume_noirq(struct device *dev) {
> +	struct platform_device *pdev = to_platform_device(dev);
> +	struct sram_dev *sram = platform_get_drvdata(pdev);
> +
> +	if (!sram->power_off_save)
> +		return 0;
> +
> +	memcpy(sram->virt_base, sram->power_off_save, sram->size);
> +
> +	return 0;
> +}
> +
>  static int sram_probe(struct platform_device *pdev)  {
>  	struct sram_dev *sram;
> @@ -176,6 +205,7 @@ static int sram_probe(struct platform_device *pdev)
>  	}
> 
>  	size = resource_size(res);
> +	sram->size = size;
> 
>  	if (!devm_request_mem_region(sram->dev, res->start, size, pdev->name)) {
>  		dev_err(sram->dev, "could not request region for resource\n"); @@
> -203,6 +233,9 @@ static int sram_probe(struct platform_device *pdev)
> 
>  	platform_set_drvdata(pdev, sram);
> 
> +	if (of_property_read_bool(pdev->dev.of_node, "can-power-gate"))
> +		sram->power_off_save = vmalloc(size);
> +
>  	dev_dbg(sram->dev, "SRAM pool: %zu KiB @ 0x%p\n",
>  		gen_pool_size(sram->pool) / 1024, sram->virt_base);
> 
> @@ -219,6 +252,9 @@ static int sram_remove(struct platform_device *pdev)
>  	if (sram->clk)
>  		clk_disable_unprepare(sram->clk);
> 
> +	if (sram->power_off_save)
> +		vfree(sram->power_off_save);
> +
>  	return 0;
>  }
> 
> @@ -229,10 +265,16 @@ static const struct of_device_id sram_dt_ids[] = {  };
> #endif
> 
> +static const struct dev_pm_ops sram_pm_ops = {
> +	.suspend_noirq = sram_suspend_noirq,
> +	.resume_noirq = sram_resume_noirq,
> +};
> +
>  static struct platform_driver sram_driver = {
>  	.driver = {
>  		.name = "sram",
>  		.of_match_table = of_match_ptr(sram_dt_ids),
> +		.pm	= &sram_pm_ops,
>  	},
>  	.probe = sram_probe,
>  	.remove = sram_remove,
> --
> 2.5.0.rc2
> 
> 
> 
> _______________________________________________
> linux-arm-kernel mailing list
> linux-arm-kernel at lists.infradead.org
> http://lists.infradead.org/mailman/listinfo/linux-arm-kernel

From sboyd at codeaurora.org  Mon Aug 24 13:33:18 2015
From: sboyd at codeaurora.org (Stephen Boyd)
Date: Mon, 24 Aug 2015 13:33:18 -0700
Subject: [PATCH 01/18] ARM: add const qualifier to the argument of
 smp_set_ops()
In-Reply-To: <1440390978-22796-2-git-send-email-yamada.masahiro@socionext.com>
References: <1440390978-22796-1-git-send-email-yamada.masahiro@socionext.com>
 <1440390978-22796-2-git-send-email-yamada.masahiro@socionext.com>
Message-ID: <20150824203318.GB14330@codeaurora.org>

On 08/24, Masahiro Yamada wrote:
> This function just copies '*ops' to 'smp_ops', so the given
> structure '*ops' is not modified at all.
> 
> Signed-off-by: Masahiro Yamada <yamada.masahiro at socionext.com>
> ---

Acked-by: Stephen Boyd <sboyd at codeaurora.org>

-- 
Qualcomm Innovation Center, Inc. is a member of Code Aurora Forum,
a Linux Foundation Collaborative Project


From robherring2 at gmail.com  Mon Aug 24 13:58:29 2015
From: robherring2 at gmail.com (Rob Herring)
Date: Mon, 24 Aug 2015 15:58:29 -0500
Subject: [PATCH v5] dtb: Create a common home for cross-architecture dtsi
 files.
In-Reply-To: <CAOesGMigmaEviCDBAncomkq+uowr18B5FTOmOyBHsNz4p6F6Dw@mail.gmail.com>
References: <1438618000-1091-1-git-send-email-ian.campbell@citrix.com>
 <1439287646.9747.212.camel@citrix.com>
 <CAL_JsqKv2aOEM-U7JNZnaHomA6HFBSFhSLZ-zhp7c20s6gQBaQ@mail.gmail.com>
 <CAOesGMj46mvbdya1OQnZzL8VrxVwxAV3KoZZRtk3c0CTVx7d5w@mail.gmail.com>
 <CAL_Jsq+tUmRfvKE6vf+za6TsG_fhMWn5M2DDDLcCfkDt=KJGVg@mail.gmail.com>
 <CAOesGMigmaEviCDBAncomkq+uowr18B5FTOmOyBHsNz4p6F6Dw@mail.gmail.com>
Message-ID: <CAL_JsqKu6B1Q1q38GFSkdAT+Gxg3=87uk8ZOGPH96Eni0cer_g@mail.gmail.com>

On Sun, Aug 23, 2015 at 6:52 PM, Olof Johansson <olof at lixom.net> wrote:
> On Sun, Aug 23, 2015 at 4:42 PM, Rob Herring <robherring2 at gmail.com> wrote:
>> On Sun, Aug 23, 2015 at 6:13 PM, Olof Johansson <olof at lixom.net> wrote:
>>> On Fri, Aug 14, 2015 at 2:21 PM, Rob Herring <robherring2 at gmail.com> wrote:
>>>> +arm-soc
>>>>
>>>> On Tue, Aug 11, 2015 at 5:07 AM, Ian Campbell <ian.campbell at citrix.com> wrote:
>>>>> On Mon, 2015-08-03 at 17:06 +0100, Ian Campbell wrote:
>>>>>> Commit 9ccd608070b6 ("arm64: dts: add device tree for ARM SMM-A53x2 on
>>>>>> LogicTile Express 20MG") added a new dts file to arch/arm64 which
>>>>>> included "../../../../arm/boot/dts/vexpress-v2m-rs1.dtsi", i.e. a
>>>>>> .dtsi supplied by arch/arm.
>>>>>>
>>>>>> Unfortunately this causes some issues for the split device tree
>>>>>> repository[0], since things get moved around there. In that context
>>>>>> the new .dts ends up at src/arm64/arm/vexpress-v2f-1xv7-ca53x2.dts
>>>>>> while the include is at src/arm/vexpress-v2m-rs1.dtsi.
>>>>>
>>>>> Hi Grant,
>>>>>
>>>>> Do you think there is any chance of getting this into 4.2-rc$NEXT or shall
>>>>> we wait until 4.3? I'm assuming this should go via the DT tree, but maybe
>>>>> it should go via an ARM tree?
>>>>
>>>> I was assuming this would go thru the arm-soc tree which is why I
>>>> acked it. It is getting a bit late for 4.2 at this point, but I guess
>>>> the standalone tree remains broken for these platforms until this is
>>>> done. Probably not such a big deal in grand scheme of things.
>>>
>>> I'm cc:d in the far tail of a thread, so I'll just comment here
>>> instead of further up:
>>>
>>> I'm not a fan at all of creating kernel/dts/<arch>/*, at least if
>>> there's expected to be contents in there.
>>>
>>> We don't have include/linux/asm-<arch>/ in the common tree either.
>>> Let's not create that for dts.
>>
>> I'd really like to move ALL dts files from arch/*. There's nothing
>> really tied to the architecture. They may happen to use some bindings
>> that only apply to an architecture, but fundamentally they don't
>> depend on the arch. Also, I'd like to be able to do "make all-dtbs"
>> and build every dtb in the tree.
>
> The main benefit of keeping it per architecture and platform is that
> it partitions the maintainer and review space a bit.

Except we have a fire hose and a bunch of dripping faucets.

> Right now it's not possible to do even per-arch "all-dtbs" since only
> the currently configured platforms will get their dtbs compiled.

I know. It's been on my todo list for a while. Having that per arch at
least would be an improvement. Having it arch independent would mean I
don't even need a cross-compiler (probably).

>> That said, I'm not crazy enough to propose this re-org in the kernel
>> tree, but would like to do that if/when we moved dts files out of the
>> kernel.
>
> I believe this is currently still quite firmly in the "if" stage. :(

There's some renewed discussion around it recently, but still no one
to step up and do it.

>>> So, while I'm all for a prefix-based sharing of DTSI files, I don't
>>> want them to go in a common kernel/dts directory.
>>>
>>> Besides sharing some snippets between arm and arm64, what else is
>>> expected to need to go into such a shared location today?
>>
>> Overlays. You easily have the same sharing of common boards. There are
>> also usecases of overlays on architectures that don't generally use DT
>> (x86).
>
> Ok, overlays might make sense if they can be made to work generically
> enough and not be tied to expectations of the base board platform.

That's the goal at least.

> Still, even then I don't see dts as a core kernel feature (kernel/*),
> lib/* might make more sense. And I don't want to see things like
> vexpress stuff in there.

How's it any different than vexpress board stuff under drivers/.

The original suggestion was under include/dt-bindings/. Not sure if
you saw or like that?

>> We could also see sharing between PPC and ARM on FSL networking parts,
>> but I've not heard if they actually have that problem.
>
> Yeah, there could potentially be some sharing between MIPS and
> ARM{,64} too, but I don't know if we'll actually see it done.

Yep, hard to say.

Rob


From olof at lixom.net  Mon Aug 24 14:12:06 2015
From: olof at lixom.net (Olof Johansson)
Date: Mon, 24 Aug 2015 14:12:06 -0700
Subject: [PATCH 00/18] ARM: use const and __initconst for smp_operations
In-Reply-To: <1440390978-22796-1-git-send-email-yamada.masahiro@socionext.com>
References: <1440390978-22796-1-git-send-email-yamada.masahiro@socionext.com>
Message-ID: <CAOesGMjku09wsUmwooq2ZXLyV7CPfioi0oAV5EgvW_wE98VYeg@mail.gmail.com>

On Sun, Aug 23, 2015 at 9:36 PM, Masahiro Yamada
<yamada.masahiro at socionext.com> wrote:
>
> Currently, SoC code can not add const qualifier to smp_operations
> structures although they are never over-written.
>
> 01/18 and 02/18 add small changes to the ARM core to fix that.
> The rest of this series replace "__initdata" with "const ... __initconst"
> for each of SoC code.
>
> I split this series into per-SoC so that each sub-arch maintainer
> can easily give their Acked-by.  (Is this better?)

When you split, chances are each sub-arch maintainer will apply
instead of ack. If that's what you want, that's fine.

> Russell, Olof, and Arnd:
>
> How should this series be applied (if it looks good)?
> The first two are ARM-tree wide and looks like in the field of Russell.
> The rest are highly SoC-related.

Easiest of all would probably be to get the sub-arch patches into one
release, then switch the prototypes and function definitions in the
next. If you switch prototypes first you'll get a bunch of warnings,
right?


-Olof


From linux at arm.linux.org.uk  Mon Aug 24 14:21:27 2015
From: linux at arm.linux.org.uk (Russell King - ARM Linux)
Date: Mon, 24 Aug 2015 22:21:27 +0100
Subject: [PATCH 00/18] ARM: use const and __initconst for smp_operations
In-Reply-To: <CAOesGMjku09wsUmwooq2ZXLyV7CPfioi0oAV5EgvW_wE98VYeg@mail.gmail.com>
References: <1440390978-22796-1-git-send-email-yamada.masahiro@socionext.com>
 <CAOesGMjku09wsUmwooq2ZXLyV7CPfioi0oAV5EgvW_wE98VYeg@mail.gmail.com>
Message-ID: <20150824212127.GH7557@n2100.arm.linux.org.uk>

On Mon, Aug 24, 2015 at 02:12:06PM -0700, Olof Johansson wrote:
> Easiest of all would probably be to get the sub-arch patches into one
> release, then switch the prototypes and function definitions in the
> next. If you switch prototypes first you'll get a bunch of warnings,
> right?

Wrong way around. :)

If you change the sub-arches to declare the smp operations as const,
and try and pass them into a function which doesn't take a const-pointer,
you'll get a warning.  The core bits need to go in first before the
sub-arch patches.

I think the series has limited value - it allows us to (a) check that a
small quantity of code doesn't write to these things, and (b) allows us
to move the SMP operations structure from __initdata to __initconstdata.
It's still going to end up in the init region which is read/write in any
case, and still gets thrown away.

Given where we are, I don't think we need to rush this in during the
last week before the merge window opens, even though it's trivial.

-- 
FTTC broadband for 0.8mile line: currently at 10.5Mbps down 400kbps up
according to speedtest.net.


From Julia.Lawall at lip6.fr  Mon Aug 24 14:12:25 2015
From: Julia.Lawall at lip6.fr (Julia Lawall)
Date: Mon, 24 Aug 2015 23:12:25 +0200
Subject: [PATCH 0/2] convert null test to IS_ERR test
Message-ID: <1440450747-10080-1-git-send-email-Julia.Lawall@lip6.fr>

Since commit 323de9efdf3e ("pinctrl: make pinctrl_register() return proper
error code"), pinctrl_register returns an error code rather than NULL on
failure.  Most drivers were updated at that time.  Update some drivers that
were introduced more recently.



From Julia.Lawall at lip6.fr  Mon Aug 24 14:12:27 2015
From: Julia.Lawall at lip6.fr (Julia Lawall)
Date: Mon, 24 Aug 2015 23:12:27 +0200
Subject: [PATCH 2/2] pinctrl: digicolor: convert null test to IS_ERR test
In-Reply-To: <1440450747-10080-1-git-send-email-Julia.Lawall@lip6.fr>
References: <1440450747-10080-1-git-send-email-Julia.Lawall@lip6.fr>
Message-ID: <1440450747-10080-3-git-send-email-Julia.Lawall@lip6.fr>

Since commit 323de9efdf3e ("pinctrl: make pinctrl_register() return proper
error code"), pinctrl_register returns an error code rather than NULL on
failure.  Update a driver that was introduced more recently.

The semantic patch that makes this change is as follows:
(http://coccinelle.lip6.fr/)

// <smpl>
@@
expression e,e1,e2;
@@

e = pinctrl_register(...)
... when != e = e1
if (
-   e == NULL
+   IS_ERR(e)
   ) {
     ...
     return
-      e2
+      PTR_ERR(e)
     ;
     }
// </smpl>

Signed-off-by: Julia Lawall <Julia.Lawall at lip6.fr>

---
 drivers/pinctrl/pinctrl-digicolor.c |    4 ++--
 1 file changed, 2 insertions(+), 2 deletions(-)

diff --git a/drivers/pinctrl/pinctrl-digicolor.c b/drivers/pinctrl/pinctrl-digicolor.c
index 461fffc..11f8b83 100644
--- a/drivers/pinctrl/pinctrl-digicolor.c
+++ b/drivers/pinctrl/pinctrl-digicolor.c
@@ -337,9 +337,9 @@ static int dc_pinctrl_probe(struct platform_device *pdev)
 	pmap->dev = &pdev->dev;
 
 	pmap->pctl = pinctrl_register(pctl_desc, &pdev->dev, pmap);
-	if (!pmap->pctl) {
+	if (IS_ERR(pmap->pctl)) {
 		dev_err(&pdev->dev, "pinctrl driver registration failed\n");
-		return -EINVAL;
+		return PTR_ERR(pmap->pctl);
 	}
 
 	ret = dc_gpiochip_add(pmap, pdev->dev.of_node);



From olof at lixom.net  Mon Aug 24 14:44:21 2015
From: olof at lixom.net (Olof Johansson)
Date: Mon, 24 Aug 2015 14:44:21 -0700
Subject: [PATCH 00/18] ARM: use const and __initconst for smp_operations
In-Reply-To: <20150824212127.GH7557@n2100.arm.linux.org.uk>
References: <1440390978-22796-1-git-send-email-yamada.masahiro@socionext.com>
 <CAOesGMjku09wsUmwooq2ZXLyV7CPfioi0oAV5EgvW_wE98VYeg@mail.gmail.com>
 <20150824212127.GH7557@n2100.arm.linux.org.uk>
Message-ID: <CAOesGMgayep0EgCAdDWSujmiycDqtFUb0iKg-aioJqyzHRectA@mail.gmail.com>

On Mon, Aug 24, 2015 at 2:21 PM, Russell King - ARM Linux
<linux at arm.linux.org.uk> wrote:
> On Mon, Aug 24, 2015 at 02:12:06PM -0700, Olof Johansson wrote:
>> Easiest of all would probably be to get the sub-arch patches into one
>> release, then switch the prototypes and function definitions in the
>> next. If you switch prototypes first you'll get a bunch of warnings,
>> right?
>
> Wrong way around. :)
>
> If you change the sub-arches to declare the smp operations as const,
> and try and pass them into a function which doesn't take a const-pointer,
> you'll get a warning.  The core bits need to go in first before the
> sub-arch patches.

Ah yes, my bad.

> I think the series has limited value - it allows us to (a) check that a
> small quantity of code doesn't write to these things, and (b) allows us
> to move the SMP operations structure from __initdata to __initconstdata.
> It's still going to end up in the init region which is read/write in any
> case, and still gets thrown away.
>
> Given where we are, I don't think we need to rush this in during the
> last week before the merge window opens, even though it's trivial.

Agreed. So if you pick it up for 4.4, we'll get the rest for 4.5.


-Olof


From olof at lixom.net  Mon Aug 24 14:47:45 2015
From: olof at lixom.net (Olof Johansson)
Date: Mon, 24 Aug 2015 14:47:45 -0700
Subject: [PATCH 0/3] ARM: uniphier: add outer cache support and rework SMP
 operations
In-Reply-To: <1440382692-3855-1-git-send-email-yamada.masahiro@socionext.com>
References: <1440382692-3855-1-git-send-email-yamada.masahiro@socionext.com>
Message-ID: <CAOesGMgL3bNH_wG3igSJhNOkV0uUfNWEi0t-Gny2A1oNnGKu=w@mail.gmail.com>

Hi,

On Sun, Aug 23, 2015 at 7:18 PM, Masahiro Yamada
<yamada.masahiro at socionext.com> wrote:
> 1/3: add outer cache support
> 2/3: rework SMP operations
> 3/3: add device tree nodes

Timing of this is unfortunate, please resend after 4.3-rc1 is out and
we can queue it up.

> Because 2/3 highly depends on 1/3, I hope whole of this series
> is applied to ARM-SOC tree.

Review or acked-by from Russell would be appreciated in that case.

> Olof,
> From this series, I am using "ARM: uniphier:" rather than "ARM: UniPhier:"
> for the subject prefixes because I noticed you often rephased so when you
> applied my patches.
> Are sub-arch names in lower cases preferable in subject prefixes?

If you look at "git log --no-merges --oneline arch/arm/mach-*" you'll
see that most platforms use either all-caps or all-lowercase.


-Olof


From daniel.lezcano at linaro.org  Mon Aug 24 14:57:30 2015
From: daniel.lezcano at linaro.org (Daniel Lezcano)
Date: Mon, 24 Aug 2015 23:57:30 +0200
Subject: [PATCH V2] clockevents/drivers/mtk: Fix spurious interrupt leading to
 crash
In-Reply-To: <1440426924.17418.11.camel@mtksdaap41>
References: <1440426924.17418.11.camel@mtksdaap41>
Message-ID: <1440453450-21203-1-git-send-email-daniel.lezcano@linaro.org>

After analysis done by Yingjoe Chen, the timer appears to have a pending
interrupt when it is enabled.

Fix this by acknowledging the pending interrupt when enabling the timer
interrupt.

Signed-off-by: Daniel Lezcano <daniel.lezcano at linaro.org>
---
 drivers/clocksource/mtk_timer.c | 16 ++++++----------
 1 file changed, 6 insertions(+), 10 deletions(-)

diff --git a/drivers/clocksource/mtk_timer.c b/drivers/clocksource/mtk_timer.c
index 4cd16fb..505f53d 100644
--- a/drivers/clocksource/mtk_timer.c
+++ b/drivers/clocksource/mtk_timer.c
@@ -156,14 +156,6 @@ static irqreturn_t mtk_timer_interrupt(int irq, void *dev_id)
 	return IRQ_HANDLED;
 }
 
-static void mtk_timer_global_reset(struct mtk_clock_event_device *evt)
-{
-	/* Disable all interrupts */
-	writel(0x0, evt->gpt_base + GPT_IRQ_EN_REG);
-	/* Acknowledge all interrupts */
-	writel(0x3f, evt->gpt_base + GPT_IRQ_ACK_REG);
-}
-
 static void
 mtk_timer_setup(struct mtk_clock_event_device *evt, u8 timer, u8 option)
 {
@@ -183,6 +175,12 @@ static void mtk_timer_enable_irq(struct mtk_clock_event_device *evt, u8 timer)
 {
 	u32 val;
 
+	/* Disable all interrupts */
+	writel(0x0, evt->gpt_base + GPT_IRQ_EN_REG);
+
+	/* Acknowledge all spurious pending interrupts */
+	writel(0x3f, evt->gpt_base + GPT_IRQ_ACK_REG);
+
 	val = readl(evt->gpt_base + GPT_IRQ_EN_REG);
 	writel(val | GPT_IRQ_ENABLE(timer),
 			evt->gpt_base + GPT_IRQ_EN_REG);
@@ -232,8 +230,6 @@ static void __init mtk_timer_init(struct device_node *node)
 	}
 	rate = clk_get_rate(clk);
 
-	mtk_timer_global_reset(evt);
-
 	if (request_irq(evt->dev.irq, mtk_timer_interrupt,
 			IRQF_TIMER | IRQF_IRQPOLL, "mtk_timer", evt)) {
 		pr_warn("failed to setup irq %d\n", evt->dev.irq);
-- 
1.9.1



From keescook at chromium.org  Mon Aug 24 15:01:06 2015
From: keescook at chromium.org (Kees Cook)
Date: Mon, 24 Aug 2015 15:01:06 -0700
Subject: Prevent list poison values from being mapped by userspace
 processes
In-Reply-To: <20150824193256.GG7557@n2100.arm.linux.org.uk>
References: <CABXk95C=CpeL4mNmS6-jJ-0bMJf6fawwfs6DM1-p8FctTEFbpw@mail.gmail.com>
 <20150821133043.GV7557@n2100.arm.linux.org.uk>
 <CAGXu5jJ8KOoVkx99rrajEEx77Z6zO4TzCXaXkB74zv9QQFuJFw@mail.gmail.com>
 <20150824184709.GE7557@n2100.arm.linux.org.uk>
 <CAGXu5jJFf+9OgnGt_Cx5Q-Pht7LAT7M-sSXftTDORybrr+SECg@mail.gmail.com>
 <20150824191427.GF7557@n2100.arm.linux.org.uk>
 <CAGXu5jLW-nfUr40cit25_GsBrPJ6e0topdBQ1RY6vSm2dBFyDA@mail.gmail.com>
 <20150824193256.GG7557@n2100.arm.linux.org.uk>
Message-ID: <CAGXu5jK=xfSpJFk9owMoNg7dybdaap+DWzGy+TPTYDHNb+V1Mg@mail.gmail.com>

On Mon, Aug 24, 2015 at 12:32 PM, Russell King - ARM Linux
<linux at arm.linux.org.uk> wrote:
> On Mon, Aug 24, 2015 at 12:22:33PM -0700, Kees Cook wrote:
>> On Mon, Aug 24, 2015 at 12:14 PM, Russell King - ARM Linux
>> <linux at arm.linux.org.uk> wrote:
>> > On Mon, Aug 24, 2015 at 11:51:04AM -0700, Kees Cook wrote:
>> >> On Mon, Aug 24, 2015 at 11:47 AM, Russell King - ARM Linux
>> >> <linux at arm.linux.org.uk> wrote:
>> >> > That's something which Catalin indicated that he'll work on.  However,
>> >> > he said in a public email last week that he won't be around for a while.
>> >> >
>> >> > So, I have no immediate solution for LPAE - it looks like LPAE will
>> >> > require switching the page tables on kernel entry or exit, and again
>> >> > each and every time we want to perform a userspace access.  How this
>> >> > is done is not something that has been discussed, and neither do we
>> >> > yet know how expensive this will be.  There are a number of places in
>> >> > the kernel where a large number of get_user()s or put_user()s follow
>> >> > one after each other, which necessitates switching back and forth
>> >> > multiple times.  We may need to address some of those areas by
>> >> > converting them to copy_(to|from)_user().
>> >>
>> >> By the way, have you looked at grsecurity's implementation of these
>> >> protections? They've been using domains for a while now, and I think
>> >> have an LPAE solution as well.
>> >
>> > *Sigh*.
>> >
>> > No, and I really don't care - if people want to do development work out
>> > of the mainline kernel and not bother to talk about getting it upstream,
>> > it's their loss.  As far as I'm concerned, such external work doesn't
>> > exist.
>>
>> Sure, I understand, but it's worth at least looking at to compare
>> feature sets. For example, when doing the W^X kernel memory work, I
>> looked at both qcom and spender's work, trying to get the best of both
>> into upstreamable shape.
>
> That's one way of looking at it.
>
> Another way of looking at it is that by looking at their work, and
> merging their ideas into your own, it becomes an encouragement for
> working outside of mainline - not only do they get the kernel itself
> free, but they get their feature merged without themselves doing any
> work - while some other bugger has to sort out making their code
> mergable.
>
> Therefore, my standard point of view is that if people can't be
> bothered to talk about their ARM specific kernel features here with
> a view to having them merged, they are leeching off the efforts of
> the upstream kernel community, and their code just isn't worth
> looking at.
>
> I hold the same view on "community" kernel trees which don't bother
> pushing their code upstream as well.
>
> Sorry, I'm *not* supporting leeches.
>
> I've already been accused this year by one very mistaken individual
> for not pushing _my_ iMX6 work into community kernel trees - when
> the work that I do is solely targetted at mainline kernels.  The
> leeches are going mad, and I'm saying no more to this crap.  If it's
> not talked about on a recognised mainline kernel mailing list, it
> doesn't exist, and deserves to be rewritten.

I certainly see your point, but I'm not sure it serves end users best
to ignore proven technologies. I am trying to bring up the discussion
on a mainline list, and it seemed redundant to paste the entire grsec
forum post here as a starting point. :)

Anyway, I just want to see stuff as secure as possible. We're all
working toward the same goal.

-Kees

-- 
Kees Cook
Chrome OS Security


From olof at lixom.net  Mon Aug 24 15:22:23 2015
From: olof at lixom.net (Olof Johansson)
Date: Mon, 24 Aug 2015 15:22:23 -0700
Subject: [PATCH v5] dtb: Create a common home for cross-architecture dtsi
 files.
In-Reply-To: <CAL_JsqKu6B1Q1q38GFSkdAT+Gxg3=87uk8ZOGPH96Eni0cer_g@mail.gmail.com>
References: <1438618000-1091-1-git-send-email-ian.campbell@citrix.com>
 <1439287646.9747.212.camel@citrix.com>
 <CAL_JsqKv2aOEM-U7JNZnaHomA6HFBSFhSLZ-zhp7c20s6gQBaQ@mail.gmail.com>
 <CAOesGMj46mvbdya1OQnZzL8VrxVwxAV3KoZZRtk3c0CTVx7d5w@mail.gmail.com>
 <CAL_Jsq+tUmRfvKE6vf+za6TsG_fhMWn5M2DDDLcCfkDt=KJGVg@mail.gmail.com>
 <CAOesGMigmaEviCDBAncomkq+uowr18B5FTOmOyBHsNz4p6F6Dw@mail.gmail.com>
 <CAL_JsqKu6B1Q1q38GFSkdAT+Gxg3=87uk8ZOGPH96Eni0cer_g@mail.gmail.com>
Message-ID: <CAOesGMhj50wg5WyByC7kHp3joo-ahfYWWDLLudp=kyKMpxauhg@mail.gmail.com>

Hi,

On Mon, Aug 24, 2015 at 1:58 PM, Rob Herring <robherring2 at gmail.com> wrote:
> On Sun, Aug 23, 2015 at 6:52 PM, Olof Johansson <olof at lixom.net> wrote:
>> On Sun, Aug 23, 2015 at 4:42 PM, Rob Herring <robherring2 at gmail.com> wrote:
>>> On Sun, Aug 23, 2015 at 6:13 PM, Olof Johansson <olof at lixom.net> wrote:
>>>> On Fri, Aug 14, 2015 at 2:21 PM, Rob Herring <robherring2 at gmail.com> wrote:
>>>>> +arm-soc
>>>>>
>>>>> On Tue, Aug 11, 2015 at 5:07 AM, Ian Campbell <ian.campbell at citrix.com> wrote:
>>>>>> On Mon, 2015-08-03 at 17:06 +0100, Ian Campbell wrote:
>>>>>>> Commit 9ccd608070b6 ("arm64: dts: add device tree for ARM SMM-A53x2 on
>>>>>>> LogicTile Express 20MG") added a new dts file to arch/arm64 which
>>>>>>> included "../../../../arm/boot/dts/vexpress-v2m-rs1.dtsi", i.e. a
>>>>>>> .dtsi supplied by arch/arm.
>>>>>>>
>>>>>>> Unfortunately this causes some issues for the split device tree
>>>>>>> repository[0], since things get moved around there. In that context
>>>>>>> the new .dts ends up at src/arm64/arm/vexpress-v2f-1xv7-ca53x2.dts
>>>>>>> while the include is at src/arm/vexpress-v2m-rs1.dtsi.
>>>>>>
>>>>>> Hi Grant,
>>>>>>
>>>>>> Do you think there is any chance of getting this into 4.2-rc$NEXT or shall
>>>>>> we wait until 4.3? I'm assuming this should go via the DT tree, but maybe
>>>>>> it should go via an ARM tree?
>>>>>
>>>>> I was assuming this would go thru the arm-soc tree which is why I
>>>>> acked it. It is getting a bit late for 4.2 at this point, but I guess
>>>>> the standalone tree remains broken for these platforms until this is
>>>>> done. Probably not such a big deal in grand scheme of things.
>>>>
>>>> I'm cc:d in the far tail of a thread, so I'll just comment here
>>>> instead of further up:
>>>>
>>>> I'm not a fan at all of creating kernel/dts/<arch>/*, at least if
>>>> there's expected to be contents in there.
>>>>
>>>> We don't have include/linux/asm-<arch>/ in the common tree either.
>>>> Let's not create that for dts.
>>>
>>> I'd really like to move ALL dts files from arch/*. There's nothing
>>> really tied to the architecture. They may happen to use some bindings
>>> that only apply to an architecture, but fundamentally they don't
>>> depend on the arch. Also, I'd like to be able to do "make all-dtbs"
>>> and build every dtb in the tree.
>>
>> The main benefit of keeping it per architecture and platform is that
>> it partitions the maintainer and review space a bit.
>
> Except we have a fire hose and a bunch of dripping faucets.
>
>> Right now it's not possible to do even per-arch "all-dtbs" since only
>> the currently configured platforms will get their dtbs compiled.
>
> I know. It's been on my todo list for a while. Having that per arch at
> least would be an improvement. Having it arch independent would mean I
> don't even need a cross-compiler (probably).

Yeah, seems like something that should work quite well in the scope of
Ian's tree if nothing else.

Maybe we should build both dtb-y and dtb-n when COMPILE_TEST is set? :)

>>> That said, I'm not crazy enough to propose this re-org in the kernel
>>> tree, but would like to do that if/when we moved dts files out of the
>>> kernel.
>>
>> I believe this is currently still quite firmly in the "if" stage. :(
>
> There's some renewed discussion around it recently, but still no one
> to step up and do it.

And I believe there are still major concerns from platform maintainers
that it will make development much more complicated.

>>>> So, while I'm all for a prefix-based sharing of DTSI files, I don't
>>>> want them to go in a common kernel/dts directory.
>>>>
>>>> Besides sharing some snippets between arm and arm64, what else is
>>>> expected to need to go into such a shared location today?
>>>
>>> Overlays. You easily have the same sharing of common boards. There are
>>> also usecases of overlays on architectures that don't generally use DT
>>> (x86).
>>
>> Ok, overlays might make sense if they can be made to work generically
>> enough and not be tied to expectations of the base board platform.
>
> That's the goal at least.
>
>> Still, even then I don't see dts as a core kernel feature (kernel/*),
>> lib/* might make more sense. And I don't want to see things like
>> vexpress stuff in there.
>
> How's it any different than vexpress board stuff under drivers/.

I'm not sure how to interpret this argument. We don't have vexpress
board stuff under kernel/boards/, so we shouldn't have the
corresponding DT contents under kernel/dts.

> The original suggestion was under include/dt-bindings/. Not sure if
> you saw or like that?

We don't store driver code in include/, so I don't see why we should
store machine descriptions there.

Something like lib/ seems more appropriate. Or drivers/..., but I
suspect that could cause further confusion on the expected separation
of binding/hardware description and the consuming drivers.

>>> We could also see sharing between PPC and ARM on FSL networking parts,
>>> but I've not heard if they actually have that problem.
>>
>> Yeah, there could potentially be some sharing between MIPS and
>> ARM{,64} too, but I don't know if we'll actually see it done.
>
> Yep, hard to say.
>
> Rob


From stuart.yoder at freescale.com  Mon Aug 24 15:34:54 2015
From: stuart.yoder at freescale.com (Stuart Yoder)
Date: Mon, 24 Aug 2015 22:34:54 +0000
Subject: [PATCH 0/2] arm64: ignore memory outside of the linear range
In-Reply-To: <20150824140828.GB20147@arm.com>
References: <1439890482-20798-1-git-send-email-ard.biesheuvel@linaro.org>
 <CY1PR0301MB0748FC71E6866C8AFACAAFF687780@CY1PR0301MB0748.namprd03.prod.outlook.com>
 <CAKv+Gu-OQ4VyCqe=mEDOrrfAtAWTfRtAiqXMGSVjJxOH6xi4Ow@mail.gmail.com>
 <20150824092256.GA11262@arm.com>
 <CY1PR0301MB0748EAE8103DDF771A37785787620@CY1PR0301MB0748.namprd03.prod.outlook.com>
 <20150824140828.GB20147@arm.com>
Message-ID: <CY1PR0301MB07481C5861695902A75CD23D87620@CY1PR0301MB0748.namprd03.prod.outlook.com>



> -----Original Message-----
> From: Will Deacon [mailto:will.deacon at arm.com]
> Sent: Monday, August 24, 2015 9:08 AM
> To: Yoder Stuart-B08248
> Cc: Ard Biesheuvel; linux-arm-kernel at lists.infradead.org; Mark Rutland; Catalin Marinas; robh at kernel.org
> Subject: Re: [PATCH 0/2] arm64: ignore memory outside of the linear range
> 
> On Mon, Aug 24, 2015 at 02:58:26PM +0100, Stuart Yoder wrote:
> > > On Mon, Aug 24, 2015 at 09:00:43AM +0100, Ard Biesheuvel wrote:
> > > > >> This is a followup to the single patch I posted on Aug 15th to ignore
> > > > >> RAM that cannot be covered by the linear mapping. Instead of clipping
> > > > >> the memory after the fact, this clips the memory before installing the
> > > > >> regions into the memblock memory table.
> > > > >>
> > > > >> This is basically the approach that Mark Rutland suggested here
> > > > >>
> > > > >> http://article.gmane.org/gmane.linux.ports.arm.kernel/430239
> > > > >>
> > > > >> but modified to correctly consider the base of the kernel image as the
> > > > >> start of the linear mapping.
> > > > >>
> > > > >> Ard Biesheuvel (2):
> > > > >>   of/fdt: make memblock maximum physical address arch configurable
> > > > >>   arm64: set MAX_MEMBLOCK_ADDR according to linear region size
> > > > >>
> > > > >>  arch/arm64/include/asm/memory.h |  8 ++++++++
> > > > >>  drivers/of/fdt.c                | 12 +++++++-----
> > > > >>  2 files changed, 15 insertions(+), 5 deletions(-)
> > > > >
> > > > > Tested on Freescale LS2085ARDB which has a split memory region
> > > > > that triggers the bug.
> > > > >
> > > > > Tested-by: Stuart Yoder <stuart.yoder at freescale.com>
> > > > >
> > > >
> > > > Will you be picking up this series for v4.3? If so, do you need me to
> > > > resend it with the tags added?
> > >
> > > Sorry, I missed Rob's ack on the of/fdt.c change. I'll pick these up
> > > later today, no need to resend.
> >
> > Are we sending to stable as well?
> 
> I've already pushed the patch out without a Cc stable (it's not a
> regression afaict), so if you want it backported then you'll need to send
> it to stable separately.

Ok, was asking because of Catalin's previous comment:

 > Even though it is not a regression, I think it is a bug fix and it's
 > worth cc'ing stable (though we could push it after 4.3-rc1).

Ard, are you going to send to stable?

Thanks,
Stuart


From sboyd at codeaurora.org  Mon Aug 24 15:49:28 2015
From: sboyd at codeaurora.org (Stephen Boyd)
Date: Mon, 24 Aug 2015 15:49:28 -0700
Subject: [PATCH v3] qcom: ipq40xx: Add basic board/dts support for
 IPQ40XX SoC
In-Reply-To: <20150824092813.GA15581@codeaurora.org>
References: <20150824092813.GA15581@codeaurora.org>
Message-ID: <20150824224928.GE14330@codeaurora.org>

On 08/24, Varadarajan Narayanan wrote:
> Add initial dts files and SoC support for IPQ40XX
> 

So far we haven't added any Xs in the model names for our SoC
support. Even for IPQ806X, we have it as IPQ8064 as the config
name with IPQ806x in the help text because there's IPQ8062 out
there. So I guess it should be IPQ4019 or something?

> Signed-off-by: Varadarajan Narayanan <varada at codeaurora.org>
> ---
> diff --git a/Documentation/devicetree/bindings/qcom.txt b/Documentation/devicetree/bindings/qcom.txt
> new file mode 100644
> index 0000000..7d56bd0
> --- /dev/null
> +++ b/Documentation/devicetree/bindings/qcom.txt
> @@ -0,0 +1,16 @@
> +Qualcomm IPQ device tree bindings
> +---------------------------------
> +
> +System on Chip
> +
> +Device tree must specify which SoC it uses, with one of the
> +following compatible strings
> +
> +       "qcom,ipq40xx"
> +
> +Platform
> +
> +Device tree must specify which Platform it uses, with one of the
> +following compatible strings
> +
> +       "qcom,ipq40xx-r3pc"

This file is not complete and I don't see any other silicon
vendors doing this, so please drop the entire file.

> diff --git a/arch/arm/boot/dts/qcom-ipq40xx-r3pc.dts b/arch/arm/boot/dts/qcom-ipq40xx-r3pc.dts
> new file mode 100644
> index 0000000..7e4e629
> --- /dev/null
> +++ b/arch/arm/boot/dts/qcom-ipq40xx-r3pc.dts
> @@ -0,0 +1,33 @@
> +/* Copyright (c) 2014, The Linux Foundation. All rights reserved.
> + *
> + * This program is free software; you can redistribute it and/or modify
> + * it under the terms of the GNU General Public License version 2 and
> + * only 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 "qcom-ipq40xx.dtsi"
> +
> +/ {
> +	model = "Qualcomm Technologies, Inc. IPQ40XX R3PC";

Same here, we should know what model number is on the board.

> +	compatible = "qcom,ipq40xx-r3pc", "qcom,ipq40xx";
> +
> +	memory {
> +		device_type = "memory";
> +		reg = <0x80000000 0x20000000>; /* 512MB */
> +	};

Doesn't the bootloader fill the memory node for us? Why do we
need this?

> +
> +	chosen {
> +		bootargs = "root=/dev/ram rw init=/init console=ttyMSM0,115200n8 initrd=0x82000000,0x000E2246";
> +	};

Please don't add bootargs. Use stdout-path for the console part
and everything else should be done by the bootloader or is the
defaults.

> +
> +	soc {
> +		serial at 78b0000 {
> +			status = "ok";
> +		};
> +	};
> +};
> diff --git a/arch/arm/boot/dts/qcom-ipq40xx.dtsi b/arch/arm/boot/dts/qcom-ipq40xx.dtsi
> new file mode 100644
> index 0000000..f572f38
> --- /dev/null
> +++ b/arch/arm/boot/dts/qcom-ipq40xx.dtsi
> @@ -0,0 +1,81 @@
> +/*
> + * Copyright (c) 2014, The Linux Foundation. All rights reserved.
> + *
> + * This program is free software; you can redistribute it and/or modify
> + * it under the terms of the GNU General Public License version 2 and
> + * only 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.
> + */
> +
> +/dts-v1/;
> +
> +#include "skeleton.dtsi"
> +
> +/ {
> +	model = "Qualcomm Technologies, Inc. IPQ40XX";
> +	compatible = "qcom,ipq40xx";

These two should also be specific and drop the Xs. Same goes for
the file name.

> +	interrupt-parent = <&intc>;
> +
> +	cpus {
> +		#address-cells = <1>;
> +		#size-cells = <0>;
> +		cpu at 0 {
> +			device_type = "cpu";
> +			compatible = "arm,cortex-a7";
> +			reg = <0x0>;
> +		};
> +
> +		cpu at 1 {
> +			device_type = "cpu";
> +			compatible = "arm,cortex-a7";
> +			reg = <0x1>;
> +		};
> +
> +		cpu at 2 {
> +			device_type = "cpu";
> +			compatible = "arm,cortex-a7";
> +			reg = <0x2>;
> +		};
> +
> +		cpu at 3 {
> +			device_type = "cpu";
> +			compatible = "arm,cortex-a7";
> +			reg = <0x3>;
> +		};
> +	};
> +
> +	soc {
> +		#address-cells = <1>;
> +		#size-cells = <1>;
> +		ranges;
> +		compatible = "simple-bus";
> +
> +		intc: interrupt-controller at b000000 {
> +			compatible = "qcom,msm-qgic2";
> +			interrupt-controller;
> +			#interrupt-cells = <3>;
> +			reg = <0x0b000000 0x1000>,
> +			<0x0b002000 0x1000>;
> +		};
> +
> +		timer {

This node is not a child of the SoC node. It should be at the
root level.

> +			compatible = "arm,armv7-timer";
> +			interrupts = <1 2 0xf08>,
> +				     <1 3 0xf08>,
> +				     <1 4 0xf08>,
> +				     <1 1 0xf08>;
> +			clock-frequency = <20833333>;

Drop this clock-frequency part if you can. The hardware should
properly report the frequency.

> +		};
> +
> +		serial at 78b0000 {
> +			compatible = "qcom,msm-uartdm-v1.4", "qcom,msm-uartdm";
> +			reg = <0x78b0000 0x200>;
> +			interrupts = <0 108 0>;
> +			status = "disabled";

Don't you need some clocks here?

> +		};
> +	};
> +};
> diff --git a/arch/arm/configs/ipq_defconfig b/arch/arm/configs/ipq_defconfig
> index 1cabd8b..89bf8ad 100644
> --- a/arch/arm/configs/ipq_defconfig
> +++ b/arch/arm/configs/ipq_defconfig
> @@ -21,6 +21,7 @@ CONFIG_ARCH_QCOM=y
>  CONFIG_ARCH_MSM8X60=y
>  CONFIG_ARCH_MSM8960=y
>  CONFIG_ARCH_MSM8974=y
> +CONFIG_ARCH_IPQ40XX=y
>  CONFIG_ARCH_IPQ8064=y
>  CONFIG_SMP=y
>  CONFIG_PREEMPT=y

This hunk should be in a separate patch.

> diff --git a/arch/arm/mach-qcom/Kconfig b/arch/arm/mach-qcom/Kconfig
> index fab49a2..70812aa 100644
> --- a/arch/arm/mach-qcom/Kconfig
> +++ b/arch/arm/mach-qcom/Kconfig
> @@ -22,6 +22,10 @@ config ARCH_MSM8974
>  	bool "Enable support for MSM8974"
>  	select HAVE_ARM_ARCH_TIMER
>  
> +config ARCH_IPQ40XX
> +	bool "Enable support for IPQ40XX"
> +	select HAVE_ARM_ARCH_TIMER
> +
>  config ARCH_IPQ8064
>  	bool "Enable support for IPQ806x"
>  	select CLKSRC_QCOM
> diff --git a/arch/arm/mach-qcom/board.c b/arch/arm/mach-qcom/board.c
> index 6d8bbf7..af9e247 100644
> --- a/arch/arm/mach-qcom/board.c
> +++ b/arch/arm/mach-qcom/board.c
> @@ -18,6 +18,7 @@ static const char * const qcom_dt_match[] __initconst = {
>  	"qcom,apq8064",
>  	"qcom,apq8074-dragonboard",
>  	"qcom,apq8084",
> +	"qcom,ipq40xx",
>  	"qcom,ipq8062",
>  	"qcom,ipq8064",
>  	"qcom,msm8660-surf",
> 

And these two should also go as a separate patch.

-- 
Qualcomm Innovation Center, Inc. is a member of Code Aurora Forum,
a Linux Foundation Collaborative Project


From briannorris at chromium.org  Mon Aug 24 15:58:03 2015
From: briannorris at chromium.org (Brian Norris)
Date: Mon, 24 Aug 2015 15:58:03 -0700
Subject: [PATCH v3] ARM: dts: rockchip: add veyron-jaq board
Message-ID: <1440457083-77519-1-git-send-email-briannorris@chromium.org>

a.k.a. Haier Chromebook 11, and others

Signed-off-by: Brian Norris <briannorris at chromium.org>
Cc: Alexandru M Stan <amstan at chromium.org>
Cc: Douglas Anderson <dianders at chromium.org>
Reviewed-by: Javier Martinez Canillas <javier at osg.samsung.com>
---
v2 -> v3:
 - add "and others" language
 - drop other patches from series (picked up already by Heiko)

v1 -> v2:
 - add overlooked DT binding doc
 - fixup regulator suspend state for LDO_REG2


 Documentation/devicetree/bindings/arm/rockchip.txt |   7 +
 arch/arm/boot/dts/Makefile                         |   1 +
 arch/arm/boot/dts/rk3288-veyron-jaq.dts            | 176 +++++++++++++++++++++
 3 files changed, 184 insertions(+)
 create mode 100644 arch/arm/boot/dts/rk3288-veyron-jaq.dts

diff --git a/Documentation/devicetree/bindings/arm/rockchip.txt b/Documentation/devicetree/bindings/arm/rockchip.txt
index af58cd74aeff..cc421ed530e7 100644
--- a/Documentation/devicetree/bindings/arm/rockchip.txt
+++ b/Documentation/devicetree/bindings/arm/rockchip.txt
@@ -31,6 +31,13 @@ Rockchip platforms device tree bindings
     Required root node properties:
       - compatible = "netxeon,r89", "rockchip,rk3288";
 
+- Google Jaq (Haier Chromebook 11 and more):
+    Required root node properties:
+      - compatible = "google,veyron-jaq-rev5", "google,veyron-jaq-rev4",
+		     "google,veyron-jaq-rev3", "google,veyron-jaq-rev2",
+		     "google,veyron-jaq-rev1", "google,veyron-jaq",
+		     "google,veyron", "rockchip,rk3288";
+
 - Google Jerry (Hisense Chromebook C11 and more):
     Required root node properties:
       - compatible = "google,veyron-jerry-rev7", "google,veyron-jerry-rev6",
diff --git a/arch/arm/boot/dts/Makefile b/arch/arm/boot/dts/Makefile
index 7805a6541a38..a08ca6c3d76e 100644
--- a/arch/arm/boot/dts/Makefile
+++ b/arch/arm/boot/dts/Makefile
@@ -490,6 +490,7 @@ dtb-$(CONFIG_ARCH_ROCKCHIP) += \
 	rk3288-firefly-beta.dtb \
 	rk3288-firefly.dtb \
 	rk3288-r89.dtb \
+	rk3288-veyron-jaq.dtb \
 	rk3288-veyron-jerry.dtb \
 	rk3288-veyron-minnie.dtb \
 	rk3288-veyron-pinky.dtb \
diff --git a/arch/arm/boot/dts/rk3288-veyron-jaq.dts b/arch/arm/boot/dts/rk3288-veyron-jaq.dts
new file mode 100644
index 000000000000..c2f52cfb4d06
--- /dev/null
+++ b/arch/arm/boot/dts/rk3288-veyron-jaq.dts
@@ -0,0 +1,176 @@
+/*
+ * Google Veyron Jaq Rev 1+ board device tree source
+ *
+ * Copyright 2015 Google, Inc
+ *
+ * This file is dual-licensed: you can use it either under the terms
+ * of the GPL or the X11 license, at your option. Note that this dual
+ * licensing only applies to this file, and not this project as a
+ * whole.
+ *
+ *  a) This file is free software; you can redistribute it and/or
+ *     modify it under the terms of the GNU General Public License as
+ *     published by the Free Software Foundation; either version 2 of the
+ *     License, or (at your option) any later version.
+ *
+ *     This file is distributed in the hope that it will be useful,
+ *     but WITHOUT ANY WARRANTY; without even the implied warranty of
+ *     MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ *     GNU General Public License for more details.
+ *
+ *  Or, alternatively,
+ *
+ *  b) Permission is hereby granted, free of charge, to any person
+ *     obtaining a copy of this software and associated documentation
+ *     files (the "Software"), to deal in the Software without
+ *     restriction, including without limitation the rights to use,
+ *     copy, modify, merge, publish, distribute, sublicense, and/or
+ *     sell copies of the Software, and to permit persons to whom the
+ *     Software is furnished to do so, subject to the following
+ *     conditions:
+ *
+ *     The above copyright notice and this permission notice shall be
+ *     included in all copies or substantial portions of the Software.
+ *
+ *     THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
+ *     EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES
+ *     OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
+ *     NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT
+ *     HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY,
+ *     WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
+ *     FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR
+ *     OTHER DEALINGS IN THE SOFTWARE.
+ */
+
+/dts-v1/;
+
+#include "rk3288-veyron-chromebook.dtsi"
+#include "cros-ec-sbs.dtsi"
+
+/ {
+	model = "Google Jaq";
+	compatible = "google,veyron-jaq-rev5", "google,veyron-jaq-rev4",
+		     "google,veyron-jaq-rev3", "google,veyron-jaq-rev2",
+		     "google,veyron-jaq-rev1", "google,veyron-jaq",
+		     "google,veyron", "rockchip,rk3288";
+
+	panel_regulator: panel-regulator {
+		compatible = "regulator-fixed";
+		enable-active-high;
+		gpio = <&gpio7 14 GPIO_ACTIVE_HIGH>;
+		pinctrl-names = "default";
+		pinctrl-0 = <&lcd_enable_h>;
+		regulator-name = "panel_regulator";
+		vin-supply = <&vcc33_sys>;
+	};
+
+	vcc18_lcd: vcc18-lcd {
+		compatible = "regulator-fixed";
+		enable-active-high;
+		gpio = <&gpio2 13 GPIO_ACTIVE_HIGH>;
+		pinctrl-names = "default";
+		pinctrl-0 = <&avdd_1v8_disp_en>;
+		regulator-name = "vcc18_lcd";
+		regulator-always-on;
+		regulator-boot-on;
+		vin-supply = <&vcc18_wl>;
+	};
+
+	backlight_regulator: backlight-regulator {
+		compatible = "regulator-fixed";
+		enable-active-high;
+		gpio = <&gpio2 12 GPIO_ACTIVE_HIGH>;
+		pinctrl-names = "default";
+		pinctrl-0 = <&bl_pwr_en>;
+		regulator-name = "backlight_regulator";
+		vin-supply = <&vcc33_sys>;
+		startup-delay-us = <15000>;
+	};
+};
+
+&rk808 {
+	pinctrl-names = "default";
+	pinctrl-0 = <&pmic_int_l &dvs_1 &dvs_2>;
+	dvs-gpios = <&gpio7 12 GPIO_ACTIVE_HIGH>,
+		    <&gpio7 15 GPIO_ACTIVE_HIGH>;
+
+	regulators {
+		mic_vcc: LDO_REG2 {
+			regulator-name = "mic_vcc";
+			regulator-always-on;
+			regulator-boot-on;
+			regulator-min-microvolt = <1800000>;
+			regulator-max-microvolt = <1800000>;
+			regulator-state-mem {
+				regulator-off-in-suspend;
+			};
+		};
+	};
+};
+
+&sdmmc {
+	disable-wp;
+	pinctrl-names = "default";
+	pinctrl-0 = <&sdmmc_clk &sdmmc_cmd &sdmmc_cd_disabled &sdmmc_cd_gpio
+			&sdmmc_bus4>;
+};
+
+&vcc_5v {
+	enable-active-high;
+	gpio = <&gpio7 21 GPIO_ACTIVE_HIGH>;
+	pinctrl-names = "default";
+	pinctrl-0 = <&drv_5v>;
+};
+
+&vcc50_hdmi {
+	enable-active-high;
+	gpio = <&gpio5 19 GPIO_ACTIVE_HIGH>;
+	pinctrl-names = "default";
+	pinctrl-0 = <&vcc50_hdmi_en>;
+};
+
+&pinctrl {
+	backlight {
+		bl_pwr_en: bl_pwr_en {
+			rockchip,pins = <2 12 RK_FUNC_GPIO &pcfg_pull_none>;
+		};
+	};
+
+	buck-5v {
+		drv_5v: drv-5v {
+			rockchip,pins = <7 21 RK_FUNC_GPIO &pcfg_pull_none>;
+		};
+	};
+
+	edp {
+		edp_hpd: edp_hpd {
+			rockchip,pins = <7 11 RK_FUNC_2 &pcfg_pull_down>;
+		};
+	};
+
+	hdmi {
+		vcc50_hdmi_en: vcc50-hdmi-en {
+			rockchip,pins = <5 19 RK_FUNC_GPIO &pcfg_pull_none>;
+		};
+	};
+
+	lcd {
+		lcd_enable_h: lcd-en {
+			rockchip,pins = <7 14 RK_FUNC_GPIO &pcfg_pull_none>;
+		};
+
+		avdd_1v8_disp_en: avdd-1v8-disp-en {
+			rockchip,pins = <2 13 RK_FUNC_GPIO &pcfg_pull_none>;
+		};
+	};
+
+	pmic {
+		dvs_1: dvs-1 {
+			rockchip,pins = <7 12 RK_FUNC_GPIO &pcfg_pull_down>;
+		};
+
+		dvs_2: dvs-2 {
+			rockchip,pins = <7 15 RK_FUNC_GPIO &pcfg_pull_down>;
+		};
+	};
+};
-- 
2.5.0.457.gab17608



From dianders at chromium.org  Mon Aug 24 16:03:23 2015
From: dianders at chromium.org (Doug Anderson)
Date: Mon, 24 Aug 2015 16:03:23 -0700
Subject: [PATCH] clk: rockchip: register pll mux before pll itself
In-Reply-To: <7060610.CC2Q1RMG2L@phil>
References: <7060610.CC2Q1RMG2L@phil>
Message-ID: <CAD=FV=UG_QkU0W5tpb3Y7zxuq6X7dtQmC4m5_j9vMtJgjdiquQ@mail.gmail.com>

Heiko

On Wed, Aug 19, 2015 at 6:06 AM, Heiko Stuebner <heiko at sntech.de> wrote:
> The structure is xin24m -> pll -> pll-mux (xin24m,pll,xin32k). The pll
> does have an init callback to make sure the boot-selected frequency is
> using the expected pll settings and resets the same frequency using
> the values provided in the driver if necessary.
>
> The setting itself also involves remuxing the pll-mux temporarily to
> the xin24m source to let the new pll rate settle. Until now this worked
> flawlessly, even when it had the flaw of accessing the mux settings
> before the mux actually got registered.
>
> With the recent clock-core conversions this flaw became apparent in
> null pointer dereference in
> [<c03fc400>] (clk_hw_get_num_parents) from [<c0400df0>] (clk_mux_get_parent+0x14/0xc8)
> [<c0400ddc>] (clk_mux_get_parent) from [<c040246c>] (rockchip_rk3066_pll_set_rate+0xd8/0x320)
>
> So to fix that, simply register the pll-mux before the pll, so that
> it will be fully initialized when the pll clock executes its init-
> callback and possibly touches the pll-mux clock.
>
> Signed-off-by: Heiko Stuebner <heiko at sntech.de>
> ---
> This only surfaced with the clk_core changes for 4.3, so should
> probably just go on top.
>
>  drivers/clk/rockchip/clk-pll.c | 63 +++++++++++++++++++++---------------------
>  1 file changed, 32 insertions(+), 31 deletions(-)

Fixes boot crash on rk3288-veyron-jerry on next-20150824.  It'd be
super great to get this landed somewhere so that we can boot linuxnext
again.  :)

Tested-by: Douglas Anderson <dianders at chromium.org>


From sboyd at codeaurora.org  Mon Aug 24 16:43:19 2015
From: sboyd at codeaurora.org (Stephen Boyd)
Date: Mon, 24 Aug 2015 16:43:19 -0700
Subject: [PATCH] clk: rockchip: register pll mux before pll itself
In-Reply-To: <CAD=FV=UG_QkU0W5tpb3Y7zxuq6X7dtQmC4m5_j9vMtJgjdiquQ@mail.gmail.com>
References: <7060610.CC2Q1RMG2L@phil>
 <CAD=FV=UG_QkU0W5tpb3Y7zxuq6X7dtQmC4m5_j9vMtJgjdiquQ@mail.gmail.com>
Message-ID: <20150824234319.GG14330@codeaurora.org>

On 08/24, Doug Anderson wrote:
> Heiko
> 
> On Wed, Aug 19, 2015 at 6:06 AM, Heiko Stuebner <heiko at sntech.de> wrote:
> > The structure is xin24m -> pll -> pll-mux (xin24m,pll,xin32k). The pll
> > does have an init callback to make sure the boot-selected frequency is
> > using the expected pll settings and resets the same frequency using
> > the values provided in the driver if necessary.
> >
> > The setting itself also involves remuxing the pll-mux temporarily to
> > the xin24m source to let the new pll rate settle. Until now this worked
> > flawlessly, even when it had the flaw of accessing the mux settings
> > before the mux actually got registered.
> >
> > With the recent clock-core conversions this flaw became apparent in
> > null pointer dereference in
> > [<c03fc400>] (clk_hw_get_num_parents) from [<c0400df0>] (clk_mux_get_parent+0x14/0xc8)
> > [<c0400ddc>] (clk_mux_get_parent) from [<c040246c>] (rockchip_rk3066_pll_set_rate+0xd8/0x320)
> >
> > So to fix that, simply register the pll-mux before the pll, so that
> > it will be fully initialized when the pll clock executes its init-
> > callback and possibly touches the pll-mux clock.
> >
> > Signed-off-by: Heiko Stuebner <heiko at sntech.de>
> > ---
> > This only surfaced with the clk_core changes for 4.3, so should
> > probably just go on top.
> >
> >  drivers/clk/rockchip/clk-pll.c | 63 +++++++++++++++++++++---------------------
> >  1 file changed, 32 insertions(+), 31 deletions(-)
> 
> Fixes boot crash on rk3288-veyron-jerry on next-20150824.  It'd be
> super great to get this landed somewhere so that we can boot linuxnext
> again.  :)
> 
> Tested-by: Douglas Anderson <dianders at chromium.org>

So I understand the fix, but how could it have ever possibly
worked flawlessly? clk_mux_get_parent() should have returned
-EINVAL through that u8 which would have meant that the check in
rockchip_rk3066_pll_set_rate() for cur_parent == PLL_MODE_NORM
would never have been true, and we would never have switched the
PLL mux over. I guess we've been getting away with this because
we don't need to actually switch the mux at this time?

-- 
Qualcomm Innovation Center, Inc. is a member of Code Aurora Forum,
a Linux Foundation Collaborative Project


From k.kozlowski at samsung.com  Mon Aug 24 16:49:36 2015
From: k.kozlowski at samsung.com (Krzysztof Kozlowski)
Date: Tue, 25 Aug 2015 08:49:36 +0900
Subject: [PATCH v3 06/14] Documentation: drm/bridge: add document for
 analogix_dp
In-Reply-To: <55DB1281.9070502@rock-chips.com>
References: <1439995728-18046-1-git-send-email-ykk@rock-chips.com>
 <1439995834-18363-1-git-send-email-ykk@rock-chips.com>
 <CAL_JsqLz+8RtBucctUj4euXZ3Ac0DvB52N9ONpAerh5T9BiTJg@mail.gmail.com>
 <CAJKOXPeEm8exg_UG0tDnaEGO40ejBKZ-ok=bKbVrwYvXnDaMdg@mail.gmail.com>
 <55DA8486.1000803@rock-chips.com> <55DA9B72.1030804@samsung.com>
 <55DB1281.9070502@rock-chips.com>
Message-ID: <55DBAD90.3040901@samsung.com>

On 24.08.2015 21:48, Yakir Yang wrote:
> Hi Krzysztof,
> 
> ? 08/24/2015 12:20 PM, Krzysztof Kozlowski ??:
>> On 24.08.2015 11:42, Yakir Yang wrote:
>>> Hi Krzysztof,
>>>
>>> ? 08/23/2015 07:43 PM, Krzysztof Kozlowski ??:
>>>> 2015-08-24 8:23 GMT+09:00 Rob Herring <robherring2 at gmail.com>:
>>>>> On Wed, Aug 19, 2015 at 9:50 AM, Yakir Yang <ykk at rock-chips.com>
>>>>> wrote:
>>>>>> Analogix dp driver is split from exynos dp driver, so we just
>>>>>> make an copy of exynos_dp.txt, and then simplify exynos_dp.txt
>>>>>>
>>>>>> Beside update some exynos dtsi file with the latest change
>>>>>> according to the devicetree binding documents.
>>>>> You can't just change the exynos bindings and break compatibility. Is
>>>>> there some agreement with exynos folks to do this?
>>>> No, there is no agreement. This wasn't even sent to Exynos maintainers.
>>> Sorry about this one, actually I have add Exynos maintainers in version
>>> 1 & version 2,
>>> but lose some maintainers in version 3, I would fix it in bellow
>>> versions.
>>>
>>>> Additionally the patchset did not look interesting to me because of
>>>> misleading subject - Documentation instead of "ARM: dts:".
>>>>
>>>> Yakir, please:
>>>> 1. Provide backward compatibility. Mark old properties as deprecated
>>>> but still support them.
>>> Do you mean that I should keep the old properties declare in
>>> exynos-dp.txt,
>>> but just mark them as deprecated flag.
>> That is one of ways how to do this. However more important is that
>> driver should still support old bindings so such code:
>> -       if (of_property_read_u32(dp_node, "samsung,color-space",
>> +       if (of_property_read_u32(dp_node, "analogix,color-space",
>>
>> is probably wrong. Will the driver support old DTB in the same way as it
>> was supporting before the change?
> 
> Okay, I got your means. So document is not the focus, the most important
> is that
> driver should support the old dts prop.

Right, the focus is on the driver.

> If so the new analogix dp driver
> should keep
> the "samsung,color-space", rather then just mark it with [DEPRECATED] flag.

If you are replacing a binding/property then it should be marked
deprecated. This means that the old property is still working but new
users of it should not be added.

> 
> But from your follow suggest, I think you agree to update driver code,
> and just mark
> old prop with deprecated flag. If so I think such code would not be wrong
> 
> -       if (of_property_read_u32(dp_node, "samsung,color-space",
> +      if (of_property_read_u32(dp_node, "analogix,color-space",

It looks wrong because it breaks backward compatibility with existing
DTB. As I said before:
>>> 1. Provide backward compatibility. Mark old properties
>>> as deprecated but still support them.


> And actually @Rob have suggest me to remove the prefix, just use
> "color-space" here.

For new bindings I don't mind. But please remember about existing users,
existing DTB and bisectability.

> 
>>
>>> Let me show same examples, make
>>> me understand your suggest rightly.
>> exynos-dp already contains deprecated properties. Other ways of doing
>> this would be:
>> Documentation/devicetree/bindings/input/touchscreen/touchscreen.txt
>> Documentation/devicetree/bindings/rtc/s3c-rtc.txt
>>
>> It depends up to you. The "touchscreen" looks good because it organizes
>> old properties in a common section. In case of exynos-dp.txt you can add
>> at beginning of file information about new bindings and mark everything
>> deprecated.
> 
> Whoops, thanks for your remind, I prefer the "touchscreen" style.
> 
>>> 1. "samsung,ycbcr-coeff" is abandoned in latest analogix-dp driver,
>>> absolutely
>>>      I should not carry this to analogix-dp.txt document. But I should
>>> keep this in
>>>      exynos-dp.txt document, and mark them with an little
>>> "deprecated" flag.
>>>
>>> [Documentation/devicetree/bindings/video/exynos_dp.txt]
>>> Required properties for dp-controller:
>>>     [...]
>>>      -samsung,ycbcr-coeff (DEPRECATED):
>>>          YCbCr co-efficients for input video.
>>>              COLOR_YCBCR601 = 0, COLOR_YCBCR709 = 1
>>>
>>> Is it right ?
>> Yes, this is right.
>>
>>>> 2. Separate all DTS changes to a separate patch, unless bisectability
>>>> would be hurt. Anyway you should prepare it in a such way that
>>>> separation would be possible without breaking bisectability.
>>> So I should separate this patch into two parts, one is name "Document:",
>>> the other is "ARM: dts: ".
>> Yes.
>>
>>> Honestly, I don't understand what the "bisectability" means in this
>>> case.
>> I was referring to bisectability in general. The patchset should be
>> fully bisectable which means that it does not introduce any issues
>> during "git bisect". This effectively means that at each intermediate
>> step (after applying each patch, one by one) every existing stuff works
>> the same as previously without any regression. Including booting with
>> old DTB.
> 
> Oh, thanks for your careful explain, so I guess your first comment is
> talking about
> the "bisectability" that if I only apply the 01 - 05 patches, kernel
> could not bootup
> normally, cause driver need "analogix,color-space" but DTB only have
> "samsung,color-space".

Right. In the same time please remember that kernel may be booted with
old DTB.

Best regards,
Krzysztof


From sboyd at codeaurora.org  Mon Aug 24 16:51:44 2015
From: sboyd at codeaurora.org (sboyd at codeaurora.org)
Date: Mon, 24 Aug 2015 16:51:44 -0700
Subject: [PATCH 2/3] [v4] ARM64: TTY: hvc_dcc: Add support for ARM64 dcc
In-Reply-To: <20150819163736.GC6281@e103592.cambridge.arm.com>
References: <1438992995-22610-1-git-send-email-timur@codeaurora.org>
 <1438992995-22610-2-git-send-email-timur@codeaurora.org>
 <20150810094008.GD1604@arm.com> <55D2749A.401@codeaurora.org>
 <20150818082141.GA6281@e103592.cambridge.arm.com>
 <55D3825D.6020105@codeaurora.org>
 <20150819101426.GB6281@e103592.cambridge.arm.com>
 <55D4ABF4.5020600@codeaurora.org>
 <20150819163736.GC6281@e103592.cambridge.arm.com>
Message-ID: <20150824235144.GH14330@codeaurora.org>

On 08/19, Dave Martin wrote:
> On Wed, Aug 19, 2015 at 11:16:52AM -0500, Timur Tabi wrote:
> > On 08/19/2015 05:14 AM, Dave Martin wrote:
> > >>>So does that mean that ldrb will zero-extend the byte to all 64 bits of x3?
> > >Yes.  No extra operation is required.
> > 
> > So my patch is actually correct as-is?
> 
> +static inline void __dcc_putchar(char c)
> +{
> +	asm volatile("msr dbgdtrtx_el0, %0"
> +			: /* No output register */
> +			: "r" (c));
> 
> For safety, you still need to make sure that c is appropriately masked
> before passing it to the asm.  Something like this should definitely be
> safe:
> 
> 			: "r" ((unsigned long)(unsigned char)c)
> 
> GCC can then emit uxtb or not, depending on whether it's needed in each
> context where the asm is inlined.

Does this mean we ought to do the same thing in the arm header
file too?

-- 
Qualcomm Innovation Center, Inc. is a member of Code Aurora Forum,
a Linux Foundation Collaborative Project


From dianders at chromium.org  Mon Aug 24 16:56:38 2015
From: dianders at chromium.org (Doug Anderson)
Date: Mon, 24 Aug 2015 16:56:38 -0700
Subject: [BUG] arm: kgdb: patch_text() in kgdb_arch_set_breakpoint() may
 sleep
In-Reply-To: <CAGXu5j+P=LtTAVQbkn4w6Y9pTVouvRgAhwfS+rAmKfqTXC8pyg@mail.gmail.com>
References: <55C230C7.2000909@nvidia.com>
 <CAD=FV=V_E+YMQuW5kvn+52Ugc_5hZsyXKKQ9Ywo_emoqK-N+Qw@mail.gmail.com>
 <CAGXu5j+P=LtTAVQbkn4w6Y9pTVouvRgAhwfS+rAmKfqTXC8pyg@mail.gmail.com>
Message-ID: <CAD=FV=Xkye3_e-ZvpUfXyQJ7VFz2s6bTPSuty4-x7Fpa72UW2g@mail.gmail.com>

Kees,

On Mon, Aug 24, 2015 at 10:46 AM, Kees Cook <keescook at chromium.org> wrote:
> On Sun, Aug 23, 2015 at 7:45 PM, Doug Anderson <dianders at chromium.org> wrote:
>> On Wed, Aug 5, 2015 at 8:50 AM, Aapo Vienamo <avienamo at nvidia.com> wrote:
>>> Hi,
>>>
>>> The breakpoint setting code in arch/arm/kernel/kgdb.c calls
>>> patch_text(), which ends up trying to sleep while in interrupt context.
>>> The bug was introduced by commit: 23a4e40 arm: kgdb: Handle read-only
>>> text / modules. The resulting behavior is "BUG: scheduling while
>>> atomic..." when setting a breakpoint in kgdb. This was tested on an
>>> Nvidia Jetson TK1 board with 4.2.0-rc5-next-20150805 kernel.
>>>
>>> Regards,
>>> Aapo Vienamo
>>
>> Aapo,
>>
>> Including the stack trace with this would have been helpful, though
>> it's not too hard to reproduce.  Here it is:
>>
>> [  416.510559] BUG: scheduling while atomic: swapper/0/0/0x00010007
>> [  416.516554] Modules linked in:
>> [  416.519614] CPU: 0 PID: 0 Comm: swapper/0 Not tainted
>> 4.2.0-rc7-00133-geb63b34 #1073
>> [  416.527341] Hardware name: Rockchip (Device Tree)
>> [  416.532042] [<c0017a4c>] (unwind_backtrace) from [<c00133d4>]
>> (show_stack+0x20/0x24)
>> [  416.539772] [<c00133d4>] (show_stack) from [<c05400e8>]
>> (dump_stack+0x84/0xb8)
>> [  416.546983] [<c05400e8>] (dump_stack) from [<c004913c>]
>> (__schedule_bug+0x54/0x6c)
>> [  416.554540] [<c004913c>] (__schedule_bug) from [<c054065c>]
>> (__schedule+0x80/0x668)
>> [  416.562183] [<c054065c>] (__schedule) from [<c0540cfc>] (schedule+0xb8/0xd4)
>> [  416.569219] [<c0540cfc>] (schedule) from [<c0543a3c>]
>> (schedule_timeout+0x2c/0x234)
>> [  416.576861] [<c0543a3c>] (schedule_timeout) from [<c05417c0>]
>> (wait_for_common+0xf4/0x188)
>> [  416.585109] [<c05417c0>] (wait_for_common) from [<c0541874>]
>> (wait_for_completion+0x20/0x24)
>> [  416.593531] [<c0541874>] (wait_for_completion) from [<c00a0104>]
>> (__stop_cpus+0x58/0x70)
>> [  416.601608] [<c00a0104>] (__stop_cpus) from [<c00a0580>]
>> (stop_cpus+0x3c/0x54)
>> [  416.608817] [<c00a0580>] (stop_cpus) from [<c00a06c4>]
>> (__stop_machine+0xcc/0xe8)
>> [  416.616286] [<c00a06c4>] (__stop_machine) from [<c00a0714>]
>> (stop_machine+0x34/0x44)
>> [  416.624016] [<c00a0714>] (stop_machine) from [<c00173e8>]
>> (patch_text+0x28/0x34)
>> [  416.631399] [<c00173e8>] (patch_text) from [<c001733c>]
>> (kgdb_arch_set_breakpoint+0x40/0x4c)
>> [  416.639823] [<c001733c>] (kgdb_arch_set_breakpoint) from
>> [<c00a0d68>] (kgdb_validate_break_address+0x2c/0x60)
>> [  416.649719] [<c00a0d68>] (kgdb_validate_break_address) from
>> [<c00a0e90>] (dbg_set_sw_break+0x1c/0xdc)
>> [  416.658922] [<c00a0e90>] (dbg_set_sw_break) from [<c00a2e88>]
>> (gdb_serial_stub+0x9c4/0xba4)
>> [  416.667259] [<c00a2e88>] (gdb_serial_stub) from [<c00a11cc>]
>> (kgdb_cpu_enter+0x1f8/0x60c)
>> [  416.675423] [<c00a11cc>] (kgdb_cpu_enter) from [<c00a18cc>]
>> (kgdb_handle_exception+0x19c/0x1d0)
>> [  416.684106] [<c00a18cc>] (kgdb_handle_exception) from [<c0016f7c>]
>> (kgdb_compiled_brk_fn+0x30/0x3c)
>> [  416.693135] [<c0016f7c>] (kgdb_compiled_brk_fn) from [<c00091a4>]
>> (do_undefinstr+0x1a4/0x20c)
>> [  416.701643] [<c00091a4>] (do_undefinstr) from [<c001400c>]
>> (__und_svc_finish+0x0/0x34)
>> [  416.709543] Exception stack(0xc07c1ce8 to 0xc07c1d30)
>> [  416.714584] 1ce0:                   00000000 c07c6504 c086e290
>> c086e294 c086e294 c086e290
>> [  416.722745] 1d00: c07c6504 00000067 00000001 c07c2100 00000027
>> c07c1d4c c07c1d50 c07c1d30
>> [  416.730905] 1d20: c00a0990 c00a08d0 60000193 ffffffff
>> [  416.735947] [<c001400c>] (__und_svc_finish) from [<c00a08d0>]
>> (kgdb_breakpoint+0x58/0x94)
>> [  416.744110] [<c00a08d0>] (kgdb_breakpoint) from [<c00a0990>]
>> (sysrq_handle_dbg+0x58/0x6c)
>> [  416.752273] [<c00a0990>] (sysrq_handle_dbg) from [<c02c230c>]
>> (__handle_sysrq+0xac/0x15c)
>> [  416.760437] [<c02c230c>] (__handle_sysrq) from [<c02c23ec>]
>> (handle_sysrq+0x30/0x34)
>>
>>
>> Kees: I think you've dealt with a lot more of these types of issues
>> than I have.  Any quick thoughts?  If not I can put it on my long-term
>> list of things to do, but until then we could always just post a
>> Revert...
>
> I don't think a revert is in order here. CONFIG_DEBUG_RODATA could be
> turned off for builds where you need kgdb while this bug gets found.

I don't think that's right.  In my testing I don't have
CONFIG_DEBUG_RODATA.  I think I did the right grep:

$ grep ARM_KERNMEM_PERMS .config
# CONFIG_ARM_KERNMEM_PERMS is not set

Basically no matter what we'll call:
- kgdb_arch_set_breakpoint
-- patch_text
--- stop_machine

...no dependencies on RODATA.

> I
> don't actually see where we've gone wrong, though. Looks like
> scheduling happened while waiting for CPUs to stop? Where did we enter
> atomic?

We're in kdb.  That's a stop mode debugger.  No sleeping allowed while
in the debugger.


> Perhaps we need to test if we're already atomic in patch_text, and
> only call stop_machine if we need to?
>
> Untested (and likely mangled by gmail):
>
> diff --git a/arch/arm/kernel/patch.c b/arch/arm/kernel/patch.c
> index 69bda1a5707e..855696bfe072 100644
> --- a/arch/arm/kernel/patch.c
> +++ b/arch/arm/kernel/patch.c
> @@ -124,5 +124,8 @@ void __kprobes patch_text(void *addr, unsigned int insn)
>                 .insn = insn,
>         };
>
> -       stop_machine(patch_text_stop_machine, &patch, NULL);
> +       if (unlikely(in_atomic_preempt_off()))
> +               patch_text_stop_machine(&patch);
> +       else
> +               stop_machine(patch_text_stop_machine, &patch, NULL);

Ah, right.  We're already stopped, so just not stopping again seems
reasonable.  I think I'd rather just use in_dbg_master() as the test
since that's a case where I _know_ all the CPUs are stopped.  Doesn't
in_atomic_preempt_off() just check if preemption is off for this
single CPU?

Anyway, I'll throw a patch up now.  It fixes it for me.  :)

-Doug


From dianders at chromium.org  Mon Aug 24 16:58:59 2015
From: dianders at chromium.org (Douglas Anderson)
Date: Mon, 24 Aug 2015 16:58:59 -0700
Subject: [PATCH] ARM: probes: Don't stop the machine if we're in the debugger
Message-ID: <1440460739-19522-1-git-send-email-dianders@chromium.org>

If we're in kgdb then the machine is already stopped.  Trying to stop
it again will cause us to try to sleep, which is not allowed while in
kgdb.  To avoid this problem, only stop the machine when we're not in
kgdb.

Reported-by: Aapo Vienamo <avienamo at nvidia.com>
Suggested-by: Kees Cook <keescook at chromium.org>
Signed-off-by: Douglas Anderson <dianders at chromium.org>
---
 arch/arm/kernel/patch.c | 7 ++++++-
 1 file changed, 6 insertions(+), 1 deletion(-)

diff --git a/arch/arm/kernel/patch.c b/arch/arm/kernel/patch.c
index 69bda1a..abf30ec 100644
--- a/arch/arm/kernel/patch.c
+++ b/arch/arm/kernel/patch.c
@@ -1,5 +1,6 @@
 #include <linux/kernel.h>
 #include <linux/spinlock.h>
+#include <linux/kgdb.h>
 #include <linux/kprobes.h>
 #include <linux/mm.h>
 #include <linux/stop_machine.h>
@@ -124,6 +125,9 @@ void __kprobes patch_text(void *addr, unsigned int insn)
 		.insn = insn,
 	};
 
-	stop_machine(patch_text_stop_machine, &patch, NULL);
+	/* Stop machine before patching; but not if in the debugger */
+	if (unlikely(in_dbg_master()))
+		patch_text_stop_machine(&patch);
+	else
+		stop_machine(patch_text_stop_machine, &patch, NULL);
 }
-- 
2.5.0.457.gab17608



From sboyd at codeaurora.org  Mon Aug 24 17:19:26 2015
From: sboyd at codeaurora.org (Stephen Boyd)
Date: Mon, 24 Aug 2015 17:19:26 -0700
Subject: [PATCH] ARM: probes: Don't stop the machine if we're in the
 debugger
In-Reply-To: <1440460739-19522-1-git-send-email-dianders@chromium.org>
References: <1440460739-19522-1-git-send-email-dianders@chromium.org>
Message-ID: <55DBB48E.7040508@codeaurora.org>

On 08/24/2015 04:58 PM, Douglas Anderson wrote:
> If we're in kgdb then the machine is already stopped.  Trying to stop
> it again will cause us to try to sleep, which is not allowed while in
> kgdb.  To avoid this problem, only stop the machine when we're not in
> kgdb.
>
> Reported-by: Aapo Vienamo <avienamo at nvidia.com>
> Suggested-by: Kees Cook <keescook at chromium.org>
> Signed-off-by: Douglas Anderson <dianders at chromium.org>
> ---

Can you add the backtrace?

>   arch/arm/kernel/patch.c | 7 ++++++-
>   1 file changed, 6 insertions(+), 1 deletion(-)
>
> diff --git a/arch/arm/kernel/patch.c b/arch/arm/kernel/patch.c
> index 69bda1a..abf30ec 100644
> --- a/arch/arm/kernel/patch.c
> +++ b/arch/arm/kernel/patch.c
> @@ -1,5 +1,6 @@
>   #include <linux/kernel.h>
>   #include <linux/spinlock.h>
> +#include <linux/kgdb.h>
>   #include <linux/kprobes.h>
>   #include <linux/mm.h>
>   #include <linux/stop_machine.h>
> @@ -124,6 +125,9 @@ void __kprobes patch_text(void *addr, unsigned int insn)
>   		.insn = insn,
>   	};
>   
> -	stop_machine(patch_text_stop_machine, &patch, NULL);
> +	/* Stop machine before patching; but not if in the debugger */
> +	if (unlikely(in_dbg_master()))
> +		patch_text_stop_machine(&patch);
> +	else
> +		stop_machine(patch_text_stop_machine, &patch, NULL);
>   }

Perhaps it would be better to add a different function for the kgdb call 
site? Then it's explicit what's going on without us having to figure out 
when in_dbg_master() is true.

-- 
Qualcomm Innovation Center, Inc. is a member of Code Aurora Forum,
a Linux Foundation Collaborative Project



From sboyd at codeaurora.org  Mon Aug 24 17:22:57 2015
From: sboyd at codeaurora.org (Stephen Boyd)
Date: Mon, 24 Aug 2015 17:22:57 -0700
Subject: [PATCH 1/2] ARM: qcom: add mdio bus on IPQ806x/AP148
In-Reply-To: <1440006802-2415-1-git-send-email-mathieu@codeaurora.org>
References: <1440006802-2415-1-git-send-email-mathieu@codeaurora.org>
Message-ID: <20150825002257.GA19120@codeaurora.org>

On 08/19, Mathieu Olivari wrote:
> diff --git a/arch/arm/boot/dts/qcom-ipq8064-ap148.dts b/arch/arm/boot/dts/qcom-ipq8064-ap148.dts
> index 6886d09..d73df24 100644
> --- a/arch/arm/boot/dts/qcom-ipq8064-ap148.dts
> +++ b/arch/arm/boot/dts/qcom-ipq8064-ap148.dts
> @@ -19,8 +19,9 @@
>  		};
>  	};
>  
> -	alias {
> +	aliases {

Good catch!

>  		serial0 = &uart4;
> +		mdio-gpio0 = &mdio0;
>  	};
>  
>  	chosen {
> @@ -93,5 +103,24 @@
>  		sata at 29000000 {
>  			status = "ok";
>  		};
> +
> +		mdio0: mdio {

This node should be at the root level, not inside the soc node.

> +			compatible = "virtual,mdio-gpio";
> +			#address-cells = <1>;
> +			#size-cells = <0>;
> +			gpios = <&qcom_pinmux 1 0 &qcom_pinmux 0 0>;
> +			pinctrl-0 = <&mdio0_pins>;
> +			pinctrl-names = "default";
> +
> +			phy0: ethernet-phy at 0 {
> +				device_type = "ethernet-phy";
> +				reg = <0>;
> +			};
> +
> +			phy4: ethernet-phy at 4 {
> +				device_type = "ethernet-phy";
> +				reg = <4>;
> +			};
> +		};
>  	};
>  };

-- 
Qualcomm Innovation Center, Inc. is a member of Code Aurora Forum,
a Linux Foundation Collaborative Project


From sboyd at codeaurora.org  Mon Aug 24 17:24:42 2015
From: sboyd at codeaurora.org (Stephen Boyd)
Date: Mon, 24 Aug 2015 17:24:42 -0700
Subject: [PATCH v4 1/3] ARM: qcom: add SFPB nodes to IPQ806x dts
In-Reply-To: <1439931860-7473-2-git-send-email-mathieu@codeaurora.org>
References: <1439931860-7473-1-git-send-email-mathieu@codeaurora.org>
 <1439931860-7473-2-git-send-email-mathieu@codeaurora.org>
Message-ID: <20150825002442.GB19120@codeaurora.org>

On 08/18, Mathieu Olivari wrote:
> Add one new node to the ipq806x.dtsi file to declare & register the
> hardware spinlock devices. This mechanism is required to be used by
> other drivers such as SMEM.
> 
> Signed-off-by: Mathieu Olivari <mathieu at codeaurora.org>
> ---

Reviewed-by: Stephen Boyd <sboyd at codeaurora.org>

-- 
Qualcomm Innovation Center, Inc. is a member of Code Aurora Forum,
a Linux Foundation Collaborative Project


From sboyd at codeaurora.org  Mon Aug 24 17:25:04 2015
From: sboyd at codeaurora.org (Stephen Boyd)
Date: Mon, 24 Aug 2015 17:25:04 -0700
Subject: [PATCH v4 2/3] ARM: qcom: add SMEM device node to IPQ806x dts
In-Reply-To: <1439931860-7473-3-git-send-email-mathieu@codeaurora.org>
References: <1439931860-7473-1-git-send-email-mathieu@codeaurora.org>
 <1439931860-7473-3-git-send-email-mathieu@codeaurora.org>
Message-ID: <20150825002504.GC19120@codeaurora.org>

On 08/18, Mathieu Olivari wrote:
> SMEM is used on IPQ806x to store various board related information such
> as boot device and flash partition layout. We'll declare it as a device
> so we can make use of it thanks to the new SMEM soc driver.
> 
> Signed-off-by: Mathieu Olivari <mathieu at codeaurora.org>
> ---

Reviewed-by: Stephen Boyd <sboyd at codeaurora.org>

-- 
Qualcomm Innovation Center, Inc. is a member of Code Aurora Forum,
a Linux Foundation Collaborative Project


From eric at anholt.net  Mon Aug 24 17:31:38 2015
From: eric at anholt.net (Eric Anholt)
Date: Mon, 24 Aug 2015 17:31:38 -0700
Subject: [PATCH v5 1/3] clk: bcm2835: Add binding docs for the Raspberry
 Pi clock provider
In-Reply-To: <1439507142-2965-2-git-send-email-eric@anholt.net>
References: <1439507142-2965-1-git-send-email-eric@anholt.net>
 <1439507142-2965-2-git-send-email-eric@anholt.net>
Message-ID: <87vbc4us2d.fsf@eliezer.anholt.net>

Eric Anholt <eric at anholt.net> writes:

> The hardware clocks are not controllable by the ARM, so we have to
> make requests to the firmware to do so from the VPU side.  This will
> let us replace fixed clocks in our DT with actual clock control (and
> correct frequency information).

Gordon from the Raspberry Pi Foundation just asked me "what do you mean,
you can't access the clocks from the ARM?"  I'd been assured I couldn't
by another developer (who was originally going to write a Linux driver
for this), and my own testing had also indicated I couldn't, but after a
new round of hacking together some tests, I see things that look a lot
like clockman registers.

Looks like we're going to get a native driver, instead.
-------------- next part --------------
A non-text attachment was scrubbed...
Name: signature.asc
Type: application/pgp-signature
Size: 818 bytes
Desc: not available
URL: <http://lists.infradead.org/pipermail/linux-arm-kernel/attachments/20150824/8ff89ce0/attachment.sig>

From sboyd at codeaurora.org  Mon Aug 24 17:35:21 2015
From: sboyd at codeaurora.org (Stephen Boyd)
Date: Mon, 24 Aug 2015 17:35:21 -0700
Subject: [PATCH v4 3/3] mtd: add SMEM parser for QCOM platforms
In-Reply-To: <1439931860-7473-4-git-send-email-mathieu@codeaurora.org>
References: <1439931860-7473-1-git-send-email-mathieu@codeaurora.org>
 <1439931860-7473-4-git-send-email-mathieu@codeaurora.org>
Message-ID: <20150825003521.GD19120@codeaurora.org>

On 08/18, Mathieu Olivari wrote:
> On QCOM platforms using MTD devices storage (such as IPQ806x), SMEM is
> used to store partition layout. This new parser can now be used to read
> SMEM and use it to register an MTD layout according to its content.
> 
> Signed-off-by: Mathieu Olivari <mathieu at codeaurora.org>
> ---

Reviewed-by: Stephen Boyd <sboyd at codeaurora.org>

-- 
Qualcomm Innovation Center, Inc. is a member of Code Aurora Forum,
a Linux Foundation Collaborative Project


From shawn.lin at rock-chips.com  Mon Aug 24 17:34:36 2015
From: shawn.lin at rock-chips.com (Shawn Lin)
Date: Tue, 25 Aug 2015 08:34:36 +0800
Subject: [PATCH v2] clk: rockchip: reset init state before mmc card
 initialization
Message-ID: <1440462876-5457-1-git-send-email-shawn.lin@rock-chips.com>

mmc host controller's IO input/output timing is unpredictable if
bootloader execute tuning for HS200 mode. It might make kernel failed
to initialize mmc card in identification mode. The root cause is
tuning phase and degree setting for HS200 mode in bootloader aren't
applicable to that of identification mode in kernel stage. Anyway, we
can't force all bootloaders to reset tuning phase and degree setting
before into kernel. Simply reset it in rockchip_clk_register_mmc.

Signed-off-by: Shawn Lin <shawn.lin at rock-chips.com>

---

Changes in v2:
- rename to rockchip_clk_mmc_reset
- simplifying the code

 drivers/clk/rockchip/clk-mmc-phase.c | 16 ++++++++++++++++
 1 file changed, 16 insertions(+)

diff --git a/drivers/clk/rockchip/clk-mmc-phase.c b/drivers/clk/rockchip/clk-mmc-phase.c
index e9f8df32..1d3e8fe6 100644
--- a/drivers/clk/rockchip/clk-mmc-phase.c
+++ b/drivers/clk/rockchip/clk-mmc-phase.c
@@ -38,6 +38,8 @@ static unsigned long rockchip_mmc_recalc(struct clk_hw *hw,
 #define ROCKCHIP_MMC_DEGREE_MASK 0x3
 #define ROCKCHIP_MMC_DELAYNUM_OFFSET 2
 #define ROCKCHIP_MMC_DELAYNUM_MASK (0xff << ROCKCHIP_MMC_DELAYNUM_OFFSET)
+#define ROCKCHIP_MMC_INIT_STATE_RESET 0x1
+#define ROCKCHIP_MMC_INIT_STATE_SHIFT 1
 
 #define PSECS_PER_SEC 1000000000000LL
 
@@ -119,6 +121,14 @@ static const struct clk_ops rockchip_mmc_clk_ops = {
 	.set_phase	= rockchip_mmc_set_phase,
 };
 
+static void rockchip_clk_mmc_reset(struct rockchip_mmc_clock *mmc_clock)
+{
+	if (mmc_clock->shift == ROCKCHIP_MMC_INIT_STATE_SHIFT)
+		writel(HIWORD_UPDATE(ROCKCHIP_MMC_INIT_STATE_RESET,
+				     ROCKCHIP_MMC_INIT_STATE_RESET,
+				     mmc_clock->shift), mmc_clock->reg);
+}
+
 struct clk *rockchip_clk_register_mmc(const char *name,
 				const char *const *parent_names, u8 num_parents,
 				void __iomem *reg, int shift)
@@ -139,6 +149,12 @@ struct clk *rockchip_clk_register_mmc(const char *name,
 	mmc_clock->reg = reg;
 	mmc_clock->shift = shift;
 
+	/*
+	* Assert init_state to soft reset the CLKGEN
+	* for mmc tuning phase and degree
+	*/
+	rockchip_clk_mmc_reset(mmc_clock);
+
 	if (name)
 		init.name = name;
 
-- 
2.3.7




From k.kozlowski at samsung.com  Mon Aug 24 17:55:38 2015
From: k.kozlowski at samsung.com (Krzysztof Kozlowski)
Date: Tue, 25 Aug 2015 09:55:38 +0900
Subject: [PATCH v2 1/7] ARM: EXYNOS: remove unused static mapping of CMU
 for exynos5
In-Reply-To: <1440403348-8974-2-git-send-email-pankaj.dubey@samsung.com>
References: <1440403348-8974-1-git-send-email-pankaj.dubey@samsung.com>
 <1440403348-8974-2-git-send-email-pankaj.dubey@samsung.com>
Message-ID: <55DBBD0A.1020805@samsung.com>

On 24.08.2015 17:02, Pankaj Dubey wrote:
> Remove unused static mapping of exynos5 CMU and related code.
> 
> Signed-off-by: Pankaj Dubey <pankaj.dubey at samsung.com>
> ---
>  arch/arm/mach-exynos/exynos.c           | 5 -----
>  arch/arm/mach-exynos/include/mach/map.h | 1 -
>  2 files changed, 6 deletions(-)

Looks good:

Reviewed-by: Krzysztof Kozlowski <k.kozlowski at samsung.com>

Best regards,
Krzysztof




From k.kozlowski at samsung.com  Mon Aug 24 17:56:32 2015
From: k.kozlowski at samsung.com (Krzysztof Kozlowski)
Date: Tue, 25 Aug 2015 09:56:32 +0900
Subject: [PATCH v2 2/7] ARM: EXYNOS: code cleanup in map.h
In-Reply-To: <1440403348-8974-3-git-send-email-pankaj.dubey@samsung.com>
References: <1440403348-8974-1-git-send-email-pankaj.dubey@samsung.com>
 <1440403348-8974-3-git-send-email-pankaj.dubey@samsung.com>
Message-ID: <55DBBD40.3050704@samsung.com>

On 24.08.2015 17:02, Pankaj Dubey wrote:
> Remove unused exynos5440 uart offset macro.
> 
> Signed-off-by: Pankaj Dubey <pankaj.dubey at samsung.com>
> ---
>  arch/arm/mach-exynos/include/mach/map.h | 4 ----
>  1 file changed, 4 deletions(-)

Reviewed-by: Krzysztof Kozlowski <k.kozlowski at samsung.com>

Best regards,
Krzysztof




From ykk at rock-chips.com  Mon Aug 24 18:21:51 2015
From: ykk at rock-chips.com (Yakir Yang)
Date: Tue, 25 Aug 2015 09:21:51 +0800
Subject: [PATCH v3 06/14] Documentation: drm/bridge: add document for
 analogix_dp
In-Reply-To: <CAL_JsqKZYMMzV9Sc2r3K_rnM0FNuyb1TyJEhjGq1Hf7dTiWFKQ@mail.gmail.com>
References: <1439995728-18046-1-git-send-email-ykk@rock-chips.com>
 <1439995834-18363-1-git-send-email-ykk@rock-chips.com>
 <CAL_JsqLz+8RtBucctUj4euXZ3Ac0DvB52N9ONpAerh5T9BiTJg@mail.gmail.com>
 <20150824125758.GA7557@n2100.arm.linux.org.uk>
 <CAL_JsqKZYMMzV9Sc2r3K_rnM0FNuyb1TyJEhjGq1Hf7dTiWFKQ@mail.gmail.com>
Message-ID: <55DBC32F.4040607@rock-chips.com>



? 2015/8/24 22:48, Rob Herring ??:
> On Mon, Aug 24, 2015 at 7:57 AM, Russell King - ARM Linux
> <linux at arm.linux.org.uk> wrote:
>> On Sun, Aug 23, 2015 at 06:23:14PM -0500, Rob Herring wrote:
>>> On Wed, Aug 19, 2015 at 9:50 AM, Yakir Yang <ykk at rock-chips.com> wrote:
>>>> +       -analogix,color-depth:
>>>> +               number of bits per colour component.
>>>> +                       COLOR_6 = 0, COLOR_8 = 1, COLOR_10 = 2, COLOR_12 = 3
>>> This seems pretty generic. Just use 6, 8, 10, or 12 for values. And
>>> drop the vendor prefix.
>> Please think about this some more.  What does "color-depth" mean?  Does it
>> mean the number of bits per colour _component_, or does it mean the total
>> number of bits to represent a particular colour.  It's confusing as it
>> stands.
> Then "component-color-bpp" perhaps?

Actually this "color-bpp" should come from crtc driver, maybe should 
come from
"struct drm_crtc {".

Like rockchip stuffs, analogix_dp-rockchip call an mode_config from 
rockchip_drm_vop
driver and set output mode to RGB[10:10:10], then vop driver just store 
the output mode
type to the private struct "vop->connecot_out_mode". do think that this 
outmode should
store into crtc, not just come from DT prop.

- Yakir



From k.kozlowski at samsung.com  Mon Aug 24 18:26:50 2015
From: k.kozlowski at samsung.com (Krzysztof Kozlowski)
Date: Tue, 25 Aug 2015 10:26:50 +0900
Subject: [PATCH v2 3/7] drivers: soc: add support for exynos SROM driver
In-Reply-To: <1440403348-8974-4-git-send-email-pankaj.dubey@samsung.com>
References: <1440403348-8974-1-git-send-email-pankaj.dubey@samsung.com>
 <1440403348-8974-4-git-send-email-pankaj.dubey@samsung.com>
Message-ID: <55DBC45A.9030706@samsung.com>

On 24.08.2015 17:02, Pankaj Dubey wrote:
> This patch adds Exynos SROM controller driver which will handle
> save restore of SROM registers during S2R.
> 
> Signed-off-by: Pankaj Dubey <pankaj.dubey at samsung.com>

Hi,

Thanks for the fixes. I got some more questions. Sorry that I did not
bring up them before.


> ---
>  drivers/soc/Kconfig               |   1 +
>  drivers/soc/Makefile              |   1 +
>  drivers/soc/samsung/Kconfig       |  13 ++++
>  drivers/soc/samsung/Makefile      |   1 +
>  drivers/soc/samsung/exynos-srom.c | 143 ++++++++++++++++++++++++++++++++++++++
>  drivers/soc/samsung/exynos-srom.h |  51 ++++++++++++++
>  6 files changed, 210 insertions(+)
>  create mode 100644 drivers/soc/samsung/Kconfig
>  create mode 100644 drivers/soc/samsung/Makefile
>  create mode 100644 drivers/soc/samsung/exynos-srom.c
>  create mode 100644 drivers/soc/samsung/exynos-srom.h
> 
> diff --git a/drivers/soc/Kconfig b/drivers/soc/Kconfig
> index 96ddecb..69107c9 100644
> --- a/drivers/soc/Kconfig
> +++ b/drivers/soc/Kconfig
> @@ -2,6 +2,7 @@ menu "SOC (System On Chip) specific Drivers"
>  
>  source "drivers/soc/mediatek/Kconfig"
>  source "drivers/soc/qcom/Kconfig"
> +source "drivers/soc/samsung/Kconfig"
>  source "drivers/soc/sunxi/Kconfig"
>  source "drivers/soc/ti/Kconfig"
>  source "drivers/soc/versatile/Kconfig"
> diff --git a/drivers/soc/Makefile b/drivers/soc/Makefile
> index 7dc7c0d..34c4398 100644
> --- a/drivers/soc/Makefile
> +++ b/drivers/soc/Makefile
> @@ -4,6 +4,7 @@
>  
>  obj-$(CONFIG_ARCH_MEDIATEK)	+= mediatek/
>  obj-$(CONFIG_ARCH_QCOM)		+= qcom/
> +obj-$(CONFIG_SOC_SAMSUNG)	+= samsung/
>  obj-$(CONFIG_ARCH_SUNXI)	+= sunxi/
>  obj-$(CONFIG_ARCH_TEGRA)	+= tegra/
>  obj-$(CONFIG_SOC_TI)		+= ti/
> diff --git a/drivers/soc/samsung/Kconfig b/drivers/soc/samsung/Kconfig
> new file mode 100644
> index 0000000..ea4bc2a
> --- /dev/null
> +++ b/drivers/soc/samsung/Kconfig
> @@ -0,0 +1,13 @@
> +#
> +# SAMSUNG SoC drivers
> +#
> +menu "Samsung SOC driver support"
> +
> +config SOC_SAMSUNG
> +	bool
> +
> +config EXYNOS_SROM
> +	bool
> +	depends on ARM && ARCH_EXYNOS
> +
> +endmenu
> diff --git a/drivers/soc/samsung/Makefile b/drivers/soc/samsung/Makefile
> new file mode 100644
> index 0000000..9c554d5
> --- /dev/null
> +++ b/drivers/soc/samsung/Makefile
> @@ -0,0 +1 @@
> +obj-$(CONFIG_EXYNOS_SROM)	+= exynos-srom.o
> diff --git a/drivers/soc/samsung/exynos-srom.c b/drivers/soc/samsung/exynos-srom.c
> new file mode 100644
> index 0000000..d7c4aa7
> --- /dev/null
> +++ b/drivers/soc/samsung/exynos-srom.c
> @@ -0,0 +1,143 @@
> +/*
> + * Copyright (c) 2015 Samsung Electronics Co., Ltd.
> + *	      http://www.samsung.com/
> + *
> + * EXYNOS - SROM Controller support
> + * Author: Pankaj Dubey <pankaj.dubey at samsung.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.
> + */
> +
> +#include <linux/io.h>
> +#include <linux/of.h>
> +#include <linux/of_address.h>
> +#include <linux/of_platform.h>
> +#include <linux/platform_device.h>
> +#include <linux/slab.h>
> +#include "exynos-srom.h"
> +
> +static void __iomem *exynos_srom_base;
> +
> +static const unsigned long exynos_srom_offsets[] = {
> +	/* SROM side */
> +	EXYNOS_SROM_BW,
> +	EXYNOS_SROM_BC0,
> +	EXYNOS_SROM_BC1,
> +	EXYNOS_SROM_BC2,
> +	EXYNOS_SROM_BC3,
> +};
> +
> +/**
> + * struct exynos_srom_reg_dump: register dump of SROM Controller registers.
> + * @offset: srom register offset from the controller base address.
> + * @value: the value of register under the offset.
> + */
> +struct exynos_srom_reg_dump {
> +	u32     offset;
> +	u32     value;
> +};
> +
> +static struct exynos_srom_reg_dump *exynos_srom_regs;
> +
> +static struct exynos_srom_reg_dump *exynos_srom_alloc_reg_dump(
> +		const unsigned long *rdump,
> +		unsigned long nr_rdump)
> +{
> +	struct exynos_srom_reg_dump *rd;
> +	unsigned int i;
> +
> +	rd = kcalloc(nr_rdump, sizeof(*rd), GFP_KERNEL);
> +	if (!rd)
> +		return NULL;
> +
> +	for (i = 0; i < nr_rdump; ++i)
> +		rd[i].offset = rdump[i];
> +
> +	return rd;
> +}
> +
> +static const struct of_device_id of_exynos_srom_ids[] = {
> +	{
> +		.compatible	= "samsung,exynos-srom",
> +	},
> +	{},
> +};
> +
> +static int exynos_srom_probe(struct platform_device *pdev)
> +{
> +	struct device_node *np;
> +	struct device *dev = &pdev->dev;
> +
> +	np = dev->of_node;
> +	exynos_srom_base = of_iomap(np, 0);

The existing file-scope "exynos_srom_base" would be overwritten for any
consecutive device bind. There shouldn't be more binds than one (there
is only one SROM on board) but still someone may create such DTB. By
mistake or by booting with some newer DTB (where for example two SROMs
would be allowed) with older kernel.

The question is should we handle such case?
E.g.
	if (exynos_srom_base)
		return -EINVAL; /* Doubled bind */
	exynos_srom_base = of_iomap(np, 0);

I see that other drivers don't do that... so I am not convinced. It may
be an useless protection. What do you think?


> +
> +	if (!exynos_srom_base) {
> +		pr_err("iomap of exynos srom controller failed\n");
> +		return -ENOMEM;
> +	}
> +
> +	exynos_srom_regs = exynos_srom_alloc_reg_dump(exynos_srom_offsets,
> +			sizeof(exynos_srom_offsets));
> +
> +	if (!exynos_srom_regs) {
> +		iounmap(exynos_srom_regs);
> +		return -ENOMEM;
> +	}
> +
> +	return 0;
> +}
> +
> +#ifdef CONFIG_PM_SLEEP
> +static void exynos_srom_save(void __iomem *base,
> +				    struct exynos_srom_reg_dump *rd,
> +				    unsigned int num_regs)
> +{
> +	for (; num_regs > 0; --num_regs, ++rd)
> +		rd->value = readl(base + rd->offset);
> +
> +}
> +
> +static void exynos_srom_restore(void __iomem *base,
> +				      const struct exynos_srom_reg_dump *rd,
> +				      unsigned int num_regs)
> +{
> +	for (; num_regs > 0; --num_regs, ++rd)
> +		writel(rd->value, base + rd->offset);
> +
> +}
> +
> +static int exynos_srom_suspend(struct device *dev)
> +{
> +	exynos_srom_save(exynos_srom_base, exynos_srom_regs,
> +				ARRAY_SIZE(exynos_srom_offsets));
> +
> +	return 0;
> +}
> +
> +static int exynos_srom_resume(struct device *dev)
> +{
> +	exynos_srom_restore(exynos_srom_base, exynos_srom_regs,
> +				ARRAY_SIZE(exynos_srom_offsets));
> +
> +	return 0;
> +}
> +#endif
> +
> +static SIMPLE_DEV_PM_OPS(exynos_srom_pm_ops, exynos_srom_suspend, exynos_srom_resume);
> +
> +static struct platform_driver exynos_srom_driver = {
> +	.probe = exynos_srom_probe,
> +	.driver = {
> +		.name = "exynos-srom",
> +		.of_match_table = of_exynos_srom_ids,
> +		.pm = &exynos_srom_pm_ops,
> +	},
> +};
> +
> +static int __init exynos_srom_init(void)
> +{
> +	return platform_driver_register(&exynos_srom_driver);
> +}
> +device_initcall(exynos_srom_init);

1. Any reason for using device_initcall() instead of
builtin/module_platform_driver()?

2. There is no device removal callback which would clean up
(kfree+iounmap). Device is not crucial for the system so I suspect it
could be removed (unbind).

Best regards,
Krzysztof




From ykk at rock-chips.com  Mon Aug 24 18:33:53 2015
From: ykk at rock-chips.com (Yakir Yang)
Date: Tue, 25 Aug 2015 09:33:53 +0800
Subject: [PATCH v3 06/14] Documentation: drm/bridge: add document for
 analogix_dp
In-Reply-To: <55DBAD90.3040901@samsung.com>
References: <1439995728-18046-1-git-send-email-ykk@rock-chips.com>
 <1439995834-18363-1-git-send-email-ykk@rock-chips.com>
 <CAL_JsqLz+8RtBucctUj4euXZ3Ac0DvB52N9ONpAerh5T9BiTJg@mail.gmail.com>
 <CAJKOXPeEm8exg_UG0tDnaEGO40ejBKZ-ok=bKbVrwYvXnDaMdg@mail.gmail.com>
 <55DA8486.1000803@rock-chips.com> <55DA9B72.1030804@samsung.com>
 <55DB1281.9070502@rock-chips.com> <55DBAD90.3040901@samsung.com>
Message-ID: <55DBC601.5090107@rock-chips.com>

Hi Krzysztof,

? 2015/8/25 7:49, Krzysztof Kozlowski ??:
> On 24.08.2015 21:48, Yakir Yang wrote:
>> Hi Krzysztof,
>>
>> ? 08/24/2015 12:20 PM, Krzysztof Kozlowski ??:
>>> On 24.08.2015 11:42, Yakir Yang wrote:
>>>> Hi Krzysztof,
>>>>
>>>> ? 08/23/2015 07:43 PM, Krzysztof Kozlowski ??:
>>>>> 2015-08-24 8:23 GMT+09:00 Rob Herring <robherring2 at gmail.com>:
>>>>>> On Wed, Aug 19, 2015 at 9:50 AM, Yakir Yang <ykk at rock-chips.com>
>>>>>> wrote:
>>>>>>> Analogix dp driver is split from exynos dp driver, so we just
>>>>>>> make an copy of exynos_dp.txt, and then simplify exynos_dp.txt
>>>>>>>
>>>>>>> Beside update some exynos dtsi file with the latest change
>>>>>>> according to the devicetree binding documents.
>>>>>> You can't just change the exynos bindings and break compatibility. Is
>>>>>> there some agreement with exynos folks to do this?
>>>>> No, there is no agreement. This wasn't even sent to Exynos maintainers.
>>>> Sorry about this one, actually I have add Exynos maintainers in version
>>>> 1 & version 2,
>>>> but lose some maintainers in version 3, I would fix it in bellow
>>>> versions.
>>>>
>>>>> Additionally the patchset did not look interesting to me because of
>>>>> misleading subject - Documentation instead of "ARM: dts:".
>>>>>
>>>>> Yakir, please:
>>>>> 1. Provide backward compatibility. Mark old properties as deprecated
>>>>> but still support them.
>>>> Do you mean that I should keep the old properties declare in
>>>> exynos-dp.txt,
>>>> but just mark them as deprecated flag.
>>> That is one of ways how to do this. However more important is that
>>> driver should still support old bindings so such code:
>>> -       if (of_property_read_u32(dp_node, "samsung,color-space",
>>> +       if (of_property_read_u32(dp_node, "analogix,color-space",
>>>
>>> is probably wrong. Will the driver support old DTB in the same way as it
>>> was supporting before the change?
>> Okay, I got your means. So document is not the focus, the most important
>> is that
>> driver should support the old dts prop.
> Right, the focus is on the driver.
>
>> If so the new analogix dp driver
>> should keep
>> the "samsung,color-space", rather then just mark it with [DEPRECATED] flag.
> If you are replacing a binding/property then it should be marked
> deprecated. This means that the old property is still working but new
> users of it should not be added.

Okay, so just quote Heiko's reply, such code would be need in analogix 
dp driver.

        if (of_property_read_u32(dp_node, "analogix,color-space",
                                  &dp_video_config->color_space))
	       if (of_property_read_u32(dp_node, "samsung,color-space",
                 	                 &dp_video_config->color_space)) {

                 	dev_err(dev, "failed to get color-space\n");
                 	return ERR_PTR(-EINVAL);
         	}


>> But from your follow suggest, I think you agree to update driver code,
>> and just mark
>> old prop with deprecated flag. If so I think such code would not be wrong
>>
>> -       if (of_property_read_u32(dp_node, "samsung,color-space",
>> +      if (of_property_read_u32(dp_node, "analogix,color-space",
> It looks wrong because it breaks backward compatibility with existing
> DTB. As I said before:
>>>> 1. Provide backward compatibility. Mark old properties
>>>> as deprecated but still support them.
>
>> And actually @Rob have suggest me to remove the prefix, just use
>> "color-space" here.
> For new bindings I don't mind. But please remember about existing users,
> existing DTB and bisectability.
>
>>>> Let me show same examples, make
>>>> me understand your suggest rightly.
>>> exynos-dp already contains deprecated properties. Other ways of doing
>>> this would be:
>>> Documentation/devicetree/bindings/input/touchscreen/touchscreen.txt
>>> Documentation/devicetree/bindings/rtc/s3c-rtc.txt
>>>
>>> It depends up to you. The "touchscreen" looks good because it organizes
>>> old properties in a common section. In case of exynos-dp.txt you can add
>>> at beginning of file information about new bindings and mark everything
>>> deprecated.
>> Whoops, thanks for your remind, I prefer the "touchscreen" style.
>>
>>>> 1. "samsung,ycbcr-coeff" is abandoned in latest analogix-dp driver,
>>>> absolutely
>>>>       I should not carry this to analogix-dp.txt document. But I should
>>>> keep this in
>>>>       exynos-dp.txt document, and mark them with an little
>>>> "deprecated" flag.
>>>>
>>>> [Documentation/devicetree/bindings/video/exynos_dp.txt]
>>>> Required properties for dp-controller:
>>>>      [...]
>>>>       -samsung,ycbcr-coeff (DEPRECATED):
>>>>           YCbCr co-efficients for input video.
>>>>               COLOR_YCBCR601 = 0, COLOR_YCBCR709 = 1
>>>>
>>>> Is it right ?
>>> Yes, this is right.
>>>
>>>>> 2. Separate all DTS changes to a separate patch, unless bisectability
>>>>> would be hurt. Anyway you should prepare it in a such way that
>>>>> separation would be possible without breaking bisectability.
>>>> So I should separate this patch into two parts, one is name "Document:",
>>>> the other is "ARM: dts: ".
>>> Yes.
>>>
>>>> Honestly, I don't understand what the "bisectability" means in this
>>>> case.
>>> I was referring to bisectability in general. The patchset should be
>>> fully bisectable which means that it does not introduce any issues
>>> during "git bisect". This effectively means that at each intermediate
>>> step (after applying each patch, one by one) every existing stuff works
>>> the same as previously without any regression. Including booting with
>>> old DTB.
>> Oh, thanks for your careful explain, so I guess your first comment is
>> talking about
>> the "bisectability" that if I only apply the 01 - 05 patches, kernel
>> could not bootup
>> normally, cause driver need "analogix,color-space" but DTB only have
>> "samsung,color-space".
> Right. In the same time please remember that kernel may be booted with
> old DTB.

Okay, thanks a lot  ;)

- Yakir

> Best regards,
> Krzysztof
>
>
>




From k.kozlowski at samsung.com  Mon Aug 24 18:35:19 2015
From: k.kozlowski at samsung.com (Krzysztof Kozlowski)
Date: Tue, 25 Aug 2015 10:35:19 +0900
Subject: [PATCH v3 06/14] Documentation: drm/bridge: add document for
 analogix_dp
In-Reply-To: <55DBC601.5090107@rock-chips.com>
References: <1439995728-18046-1-git-send-email-ykk@rock-chips.com>
 <1439995834-18363-1-git-send-email-ykk@rock-chips.com>
 <CAL_JsqLz+8RtBucctUj4euXZ3Ac0DvB52N9ONpAerh5T9BiTJg@mail.gmail.com>
 <CAJKOXPeEm8exg_UG0tDnaEGO40ejBKZ-ok=bKbVrwYvXnDaMdg@mail.gmail.com>
 <55DA8486.1000803@rock-chips.com> <55DA9B72.1030804@samsung.com>
 <55DB1281.9070502@rock-chips.com> <55DBAD90.3040901@samsung.com>
 <55DBC601.5090107@rock-chips.com>
Message-ID: <55DBC657.6060409@samsung.com>

On 25.08.2015 10:33, Yakir Yang wrote:
> Hi Krzysztof,
> 
> ? 2015/8/25 7:49, Krzysztof Kozlowski ??:
>> On 24.08.2015 21:48, Yakir Yang wrote:
>>> Hi Krzysztof,
>>>
>>> ? 08/24/2015 12:20 PM, Krzysztof Kozlowski ??:
>>>> On 24.08.2015 11:42, Yakir Yang wrote:
>>>>> Hi Krzysztof,
>>>>>
>>>>> ? 08/23/2015 07:43 PM, Krzysztof Kozlowski ??:
>>>>>> 2015-08-24 8:23 GMT+09:00 Rob Herring <robherring2 at gmail.com>:
>>>>>>> On Wed, Aug 19, 2015 at 9:50 AM, Yakir Yang <ykk at rock-chips.com>
>>>>>>> wrote:
>>>>>>>> Analogix dp driver is split from exynos dp driver, so we just
>>>>>>>> make an copy of exynos_dp.txt, and then simplify exynos_dp.txt
>>>>>>>>
>>>>>>>> Beside update some exynos dtsi file with the latest change
>>>>>>>> according to the devicetree binding documents.
>>>>>>> You can't just change the exynos bindings and break
>>>>>>> compatibility. Is
>>>>>>> there some agreement with exynos folks to do this?
>>>>>> No, there is no agreement. This wasn't even sent to Exynos
>>>>>> maintainers.
>>>>> Sorry about this one, actually I have add Exynos maintainers in
>>>>> version
>>>>> 1 & version 2,
>>>>> but lose some maintainers in version 3, I would fix it in bellow
>>>>> versions.
>>>>>
>>>>>> Additionally the patchset did not look interesting to me because of
>>>>>> misleading subject - Documentation instead of "ARM: dts:".
>>>>>>
>>>>>> Yakir, please:
>>>>>> 1. Provide backward compatibility. Mark old properties as deprecated
>>>>>> but still support them.
>>>>> Do you mean that I should keep the old properties declare in
>>>>> exynos-dp.txt,
>>>>> but just mark them as deprecated flag.
>>>> That is one of ways how to do this. However more important is that
>>>> driver should still support old bindings so such code:
>>>> -       if (of_property_read_u32(dp_node, "samsung,color-space",
>>>> +       if (of_property_read_u32(dp_node, "analogix,color-space",
>>>>
>>>> is probably wrong. Will the driver support old DTB in the same way
>>>> as it
>>>> was supporting before the change?
>>> Okay, I got your means. So document is not the focus, the most important
>>> is that
>>> driver should support the old dts prop.
>> Right, the focus is on the driver.
>>
>>> If so the new analogix dp driver
>>> should keep
>>> the "samsung,color-space", rather then just mark it with [DEPRECATED]
>>> flag.
>> If you are replacing a binding/property then it should be marked
>> deprecated. This means that the old property is still working but new
>> users of it should not be added.
> 
> Okay, so just quote Heiko's reply, such code would be need in analogix
> dp driver.
> 
>        if (of_property_read_u32(dp_node, "analogix,color-space",
>                                  &dp_video_config->color_space))
>            if (of_property_read_u32(dp_node, "samsung,color-space",
>                                      &dp_video_config->color_space)) {
> 
>                     dev_err(dev, "failed to get color-space\n");
>                     return ERR_PTR(-EINVAL);
>             }

Yes. It does not look pretty but something like this is needed.

Best regards,
Krzysztof



From yamada.masahiro at socionext.com  Mon Aug 24 18:37:15 2015
From: yamada.masahiro at socionext.com (Masahiro Yamada)
Date: Tue, 25 Aug 2015 10:37:15 +0900
Subject: [PATCH 00/18] ARM: use const and __initconst for smp_operations
In-Reply-To: <CAOesGMgayep0EgCAdDWSujmiycDqtFUb0iKg-aioJqyzHRectA@mail.gmail.com>
References: <1440390978-22796-1-git-send-email-yamada.masahiro@socionext.com>
 <CAOesGMjku09wsUmwooq2ZXLyV7CPfioi0oAV5EgvW_wE98VYeg@mail.gmail.com>
 <20150824212127.GH7557@n2100.arm.linux.org.uk>
 <CAOesGMgayep0EgCAdDWSujmiycDqtFUb0iKg-aioJqyzHRectA@mail.gmail.com>
Message-ID: <CAK7LNATD0559Yh5E2pkGpcEOFUboK=5hR37QfLwNBRt+7aJHGg@mail.gmail.com>

Hi Russell, Olof,

2015-08-25 6:44 GMT+09:00 Olof Johansson <olof at lixom.net>:
> On Mon, Aug 24, 2015 at 2:21 PM, Russell King - ARM Linux
> <linux at arm.linux.org.uk> wrote:
>> On Mon, Aug 24, 2015 at 02:12:06PM -0700, Olof Johansson wrote:
>>> Easiest of all would probably be to get the sub-arch patches into one
>>> release, then switch the prototypes and function definitions in the
>>> next. If you switch prototypes first you'll get a bunch of warnings,
>>> right?
>>
>> Wrong way around. :)
>>
>> If you change the sub-arches to declare the smp operations as const,
>> and try and pass them into a function which doesn't take a const-pointer,
>> you'll get a warning.  The core bits need to go in first before the
>> sub-arch patches.
>
> Ah yes, my bad.
>
>> I think the series has limited value - it allows us to (a) check that a
>> small quantity of code doesn't write to these things, and (b) allows us
>> to move the SMP operations structure from __initdata to __initconstdata.
>> It's still going to end up in the init region which is read/write in any
>> case, and still gets thrown away.
>>
>> Given where we are, I don't think we need to rush this in during the
>> last week before the merge window opens, even though it's trivial.
>
> Agreed. So if you pick it up for 4.4, we'll get the rest for 4.5.
>

OK.

I will put 01 and 02 to Russell's patch tracker
(after waiting for a bit more comments just in case).

I will do the rest later.





-- 
Best Regards
Masahiro Yamada


From ykk at rock-chips.com  Mon Aug 24 18:37:13 2015
From: ykk at rock-chips.com (Yakir Yang)
Date: Tue, 25 Aug 2015 09:37:13 +0800
Subject: [PATCH v3 06/14] Documentation: drm/bridge: add document for
 analogix_dp
In-Reply-To: <18468783.Lfl8UEMQ1s@phil>
References: <1439995728-18046-1-git-send-email-ykk@rock-chips.com>
 <55DA9B72.1030804@samsung.com> <55DB1281.9070502@rock-chips.com>
 <18468783.Lfl8UEMQ1s@phil>
Message-ID: <55DBC6C9.8030705@rock-chips.com>

Hi Heiko,

? 2015/8/24 21:03, Heiko Stuebner ??:
> Hi Yakir,
>
> Am Montag, 24. August 2015, 20:48:01 schrieb Yakir Yang:
>> ? 08/24/2015 12:20 PM, Krzysztof Kozlowski ??:
>>> On 24.08.2015 11:42, Yakir Yang wrote:
>>>> Hi Krzysztof,
>>>>
>>>> ? 08/23/2015 07:43 PM, Krzysztof Kozlowski ??:
>>>>> 2015-08-24 8:23 GMT+09:00 Rob Herring <robherring2 at gmail.com>:
>>>>>> On Wed, Aug 19, 2015 at 9:50 AM, Yakir Yang <ykk at rock-chips.com> wrote:
>>>>>>> Analogix dp driver is split from exynos dp driver, so we just
>>>>>>> make an copy of exynos_dp.txt, and then simplify exynos_dp.txt
>>>>>>>
>>>>>>> Beside update some exynos dtsi file with the latest change
>>>>>>> according to the devicetree binding documents.
>>>>>> You can't just change the exynos bindings and break compatibility. Is
>>>>>> there some agreement with exynos folks to do this?
>>>>> No, there is no agreement. This wasn't even sent to Exynos maintainers.
>>>> Sorry about this one, actually I have add Exynos maintainers in version
>>>> 1 & version 2,
>>>> but lose some maintainers in version 3, I would fix it in bellow
>>>> versions.
>>>>
>>>>> Additionally the patchset did not look interesting to me because of
>>>>> misleading subject - Documentation instead of "ARM: dts:".
>>>>>
>>>>> Yakir, please:
>>>>> 1. Provide backward compatibility. Mark old properties as deprecated
>>>>> but still support them.
>>>> Do you mean that I should keep the old properties declare in
>>>> exynos-dp.txt,
>>>> but just mark them as deprecated flag.
>>> That is one of ways how to do this. However more important is that
>>> driver should still support old bindings so such code:
>>> -       if (of_property_read_u32(dp_node, "samsung,color-space",
>>> +       if (of_property_read_u32(dp_node, "analogix,color-space",
>>>
>>> is probably wrong. Will the driver support old DTB in the same way as it
>>> was supporting before the change?
>> Okay, I got your means. So document is not the focus, the most important
>> is that
>> driver should support the old dts prop. If so the new analogix dp driver
>> should keep
>> the "samsung,color-space", rather then just mark it with [DEPRECATED] flag.
>>
>> But from your follow suggest, I think you agree to update driver code,
>> and just mark
>> old prop with deprecated flag. If so I think such code would not be wrong
>>
>> -       if (of_property_read_u32(dp_node, "samsung,color-space",
>> +      if (of_property_read_u32(dp_node, "analogix,color-space",
> In a generic driver, the property should have either none, or the analogix
> prefix. But DT-properties need to be backwards compatible, meaning an older
> Exynos devicetree should run unmodified with a newer kernel.
>
> So the common course of action is to mark the old one as deprecated but still
> test for both, so something like:
>
>         if (of_property_read_u32(dp_node, "analogix,color-space",
>                                   &dp_video_config->color_space))
> 	       if (of_property_read_u32(dp_node, "samsung,color-space",
>                  	                 &dp_video_config->color_space)) {
>
>                  	dev_err(dev, "failed to get color-space\n");
>                  	return ERR_PTR(-EINVAL);
>          	}
>

Wow, thanks a lot for your explain and code, it do help me to understand
this suggest rightly  :-)

Thanks,
- Yakir

>
>
>
>
>




From beanhuo at micron.com  Mon Aug 24 18:44:57 2015
From: beanhuo at micron.com (=?iso-2022-jp?B?QmVhbiBIdW8gGyRCcDlJTElMGyhCIChiZWFuaHVvKQ==?=)
Date: Tue, 25 Aug 2015 01:44:57 +0000
Subject: [PATCH linux-next v4 5/5] mtd: atmel-quadspi: add driver for
 Atmel QSPI controller
In-Reply-To: <bf368fc101f38db231131b69eff0863210f2b01c.1440410236.git.cyrille.pitchen@atmel.com>
References: <cover.1440410236.git.cyrille.pitchen@atmel.com>
 <bf368fc101f38db231131b69eff0863210f2b01c.1440410236.git.cyrille.pitchen@atmel.com>
Message-ID: <A765B125120D1346A63912DDE6D8B6310BF47A26@NTXXIAMBX02.xacn.micron.com>


>+	nor->read_reg = atmel_qspi_read_reg;
>+	nor->write_reg = atmel_qspi_write_reg;
>+	nor->read = atmel_qspi_read;
>+	nor->write = atmel_qspi_write;
>+	nor->erase = atmel_qspi_erase;
>+	nor->set_protocol = atmel_qspi_set_protocol;

This is very good, the structure of spi_nor should add a hook function to notify spi controller 
That spi nor transfer protocol already changed.

>+
>+	if (of_modalias_node(child, modalias, sizeof(modalias)) < 0) {
>+		err = -ENODEV;
>+		goto release_channel;
>+	}
>+
>+	err = of_property_read_u32(child, "spi-max-frequency", &aq->clk_rate);
>+	if (err < 0)
>+		goto release_channel;
>+
>+	err = atmel_qspi_init(aq);
>+	if (err)
>+		goto release_channel;
>+
>+	nor->dev->of_node = child;
>+	err = spi_nor_scan(nor, modalias, SPI_NOR_QUAD);
>		goto release_channel;
>+


.......

>static inline struct spi_nor *mtd_to_spi_nor(struct mtd_info *mtd)  {
 	return mtd->priv;
>@@ -944,6 +960,11 @@ static int micron_quad_enable(struct spi_nor *nor)
>		return ret;
> 	}
> 
>+	/* switch protocol to Quad CMD 4-4-4 */
>+	ret = spi_nor_set_protocol(nor, SPI_PROTO_4_4_4);
>+	if (ret)
>+		return ret;
>+

This make sense,from spi nor side,once its protocol being changed,
Mtd layer must notify this status to spi nor controller immediately,
And spi nor controller also should re-adjust its protocol.
Otherwise, following reading SR operation will fail. 

>
> 	ret = spi_nor_wait_till_ready(nor);
> 	if (ret)
> 		return ret;

If my ack has any value in here, feel free to add it.

Acked-by: Bean Huo <beanhuo at micron.com>


From yamada.masahiro at socionext.com  Mon Aug 24 18:50:00 2015
From: yamada.masahiro at socionext.com (Masahiro Yamada)
Date: Tue, 25 Aug 2015 10:50:00 +0900
Subject: [PATCH 0/3] ARM: uniphier: add outer cache support and rework SMP
 operations
In-Reply-To: <CAOesGMgL3bNH_wG3igSJhNOkV0uUfNWEi0t-Gny2A1oNnGKu=w@mail.gmail.com>
References: <1440382692-3855-1-git-send-email-yamada.masahiro@socionext.com>
 <CAOesGMgL3bNH_wG3igSJhNOkV0uUfNWEi0t-Gny2A1oNnGKu=w@mail.gmail.com>
Message-ID: <CAK7LNAQk4aEgZV3y90zBVMeq=jA45v683sCR1e5BBYtg5AcDOA@mail.gmail.com>

Hi Olof,


2015-08-25 6:47 GMT+09:00 Olof Johansson <olof at lixom.net>:
> Hi,
>
> On Sun, Aug 23, 2015 at 7:18 PM, Masahiro Yamada
> <yamada.masahiro at socionext.com> wrote:
>> 1/3: add outer cache support
>> 2/3: rework SMP operations
>> 3/3: add device tree nodes
>
> Timing of this is unfortunate, please resend after 4.3-rc1 is out and
> we can queue it up.

Given that rc8 is out and the merge window has been delayed,
is it still too late for 4.3-rc1?



>> Because 2/3 highly depends on 1/3, I hope whole of this series
>> is applied to ARM-SOC tree.
>
> Review or acked-by from Russell would be appreciated in that case.
>
>> Olof,
>> From this series, I am using "ARM: uniphier:" rather than "ARM: UniPhier:"
>> for the subject prefixes because I noticed you often rephased so when you
>> applied my patches.
>> Are sub-arch names in lower cases preferable in subject prefixes?
>
> If you look at "git log --no-merges --oneline arch/arm/mach-*" you'll
> see that most platforms use either all-caps or all-lowercase.

I see.

But, we use "UniPhier" (with only U and P capitalized) in our official
documents.



-- 
Best Regards
Masahiro Yamada


From k.kozlowski at samsung.com  Mon Aug 24 18:53:08 2015
From: k.kozlowski at samsung.com (Krzysztof Kozlowski)
Date: Tue, 25 Aug 2015 10:53:08 +0900
Subject: [PATCH v2 4/7] ARM: EXYNOS: Remove SROM related register settings
 from mach-exynos
In-Reply-To: <1440403348-8974-5-git-send-email-pankaj.dubey@samsung.com>
References: <1440403348-8974-1-git-send-email-pankaj.dubey@samsung.com>
 <1440403348-8974-5-git-send-email-pankaj.dubey@samsung.com>
Message-ID: <55DBCA84.2070506@samsung.com>

On 24.08.2015 17:02, Pankaj Dubey wrote:
> As now we have dedicated driver for SROM controller, it will take care
> of saving register banks during S2R so we can safely remove these
> settings from mach-exynos.
> 
> Signed-off-by: Pankaj Dubey <pankaj.dubey at samsung.com>
> ---
>  arch/arm/mach-exynos/Kconfig                 |  2 ++
>  arch/arm/mach-exynos/common.h                |  2 --
>  arch/arm/mach-exynos/exynos.c                | 17 ---------
>  arch/arm/mach-exynos/include/mach/map.h      |  3 --
>  arch/arm/mach-exynos/regs-srom.h             | 53 ----------------------------
>  arch/arm/mach-exynos/suspend.c               | 20 ++---------
>  arch/arm/plat-samsung/include/plat/map-s5p.h |  1 -
>  7 files changed, 4 insertions(+), 94 deletions(-)
>  delete mode 100644 arch/arm/mach-exynos/regs-srom.h

The order of patches looks wrong. Is this fully bisectable? You are
removing here support for SROM but DTS bindings are not added yet.

> 
> diff --git a/arch/arm/mach-exynos/Kconfig b/arch/arm/mach-exynos/Kconfig
> index 3a10f1a..7c917ef 100644
> --- a/arch/arm/mach-exynos/Kconfig
> +++ b/arch/arm/mach-exynos/Kconfig
> @@ -27,6 +27,8 @@ menuconfig ARCH_EXYNOS
>  	select SRAM
>  	select THERMAL
>  	select MFD_SYSCON
> +	select SOC_SAMSUNG
> +	select EXYNOS_SROM
>  	help
>  	  Support for SAMSUNG EXYNOS SoCs (EXYNOS4/5)
>  
> diff --git a/arch/arm/mach-exynos/common.h b/arch/arm/mach-exynos/common.h
> index 1534925..1c04741 100644
> --- a/arch/arm/mach-exynos/common.h
> +++ b/arch/arm/mach-exynos/common.h
> @@ -108,8 +108,6 @@ IS_SAMSUNG_CPU(exynos5800, EXYNOS5800_SOC_ID, EXYNOS5_SOC_MASK)
>  
>  #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())

That wasn't here in v1. I see that it is not used any more and
of_machine_is_compatible is preferred but I would prefer to leave it. In
certain cases you cannot use of_machine_is_compatible (e.g. in
platform_do_lowpower).

Rest looks good.

Best regards,
Krzysztof



From k.kozlowski at samsung.com  Mon Aug 24 18:57:00 2015
From: k.kozlowski at samsung.com (Krzysztof Kozlowski)
Date: Tue, 25 Aug 2015 10:57:00 +0900
Subject: [PATCH v2 5/7] ARM: dts: add SROM device node for exynos4
In-Reply-To: <1440403348-8974-6-git-send-email-pankaj.dubey@samsung.com>
References: <1440403348-8974-1-git-send-email-pankaj.dubey@samsung.com>
 <1440403348-8974-6-git-send-email-pankaj.dubey@samsung.com>
Message-ID: <55DBCB6C.9000201@samsung.com>

On 24.08.2015 17:02, Pankaj Dubey wrote:
> Add device node of SROM controller for exynos4.
> 
> CC: Rob Herring <robh+dt at kernel.org>
> CC: Mark Rutland <mark.rutland at arm.com>
> CC: Ian Campbell <ijc+devicetree at hellion.org.uk>
> Signed-off-by: Pankaj Dubey <pankaj.dubey at samsung.com>
> ---
>  arch/arm/boot/dts/exynos4.dtsi | 5 +++++
>  1 file changed, 5 insertions(+)
> 
Reviewed-by: Krzysztof Kozlowski <k.kozlowski at samsung.com>

Best regards,
Krzysztof



From k.kozlowski at samsung.com  Mon Aug 24 19:03:05 2015
From: k.kozlowski at samsung.com (Krzysztof Kozlowski)
Date: Tue, 25 Aug 2015 11:03:05 +0900
Subject: [PATCH v2 6/7] ARM: dts: add SROM device node for exynos5
In-Reply-To: <1440403348-8974-7-git-send-email-pankaj.dubey@samsung.com>
References: <1440403348-8974-1-git-send-email-pankaj.dubey@samsung.com>
 <1440403348-8974-7-git-send-email-pankaj.dubey@samsung.com>
Message-ID: <55DBCCD9.80204@samsung.com>

On 24.08.2015 17:02, Pankaj Dubey wrote:
> Add SROM controller device node for exynos5.
> 
> CC: Rob Herring <robh+dt at kernel.org>
> CC: Mark Rutland <mark.rutland at arm.com>
> CC: Ian Campbell <ijc+devicetree at hellion.org.uk>
> Signed-off-by: Pankaj Dubey <pankaj.dubey at samsung.com>
> ---
>  arch/arm/boot/dts/exynos5.dtsi | 5 +++++
>  1 file changed, 5 insertions(+)

Reviewed-by: Krzysztof Kozlowski <k.kozlowski at samsung.com>

Best regards,
Krzysztof



From k.kozlowski at samsung.com  Mon Aug 24 19:03:42 2015
From: k.kozlowski at samsung.com (Krzysztof Kozlowski)
Date: Tue, 25 Aug 2015 11:03:42 +0900
Subject: [PATCH v2 7/7] Documentation: dt-bindings: add exynos-srom binding
 information
In-Reply-To: <1440403348-8974-8-git-send-email-pankaj.dubey@samsung.com>
References: <1440403348-8974-1-git-send-email-pankaj.dubey@samsung.com>
 <1440403348-8974-8-git-send-email-pankaj.dubey@samsung.com>
Message-ID: <55DBCCFE.80803@samsung.com>

On 24.08.2015 17:02, Pankaj Dubey wrote:
> This patch adds exynos-srom binding information for SROM Controller
> driver on Exynos SoCs.
> 
> CC: Rob Herring <robh+dt at kernel.org>
> CC: Mark Rutland <mark.rutland at arm.com>
> CC: Ian Campbell <ijc+devicetree at hellion.org.uk>
> Signed-off-by: Pankaj Dubey <pankaj.dubey at samsung.com>
> ---
>  .../devicetree/bindings/arm/samsung/exynos-srom.txt          | 12 ++++++++++++
>  1 file changed, 12 insertions(+)
>  create mode 100644 Documentation/devicetree/bindings/arm/samsung/exynos-srom.txt

Reviewed-by: Krzysztof Kozlowski <k.kozlowski at samsung.com>

Best regards,
Krzysztof




From pi-cheng.chen at linaro.org  Mon Aug 24 19:10:44 2015
From: pi-cheng.chen at linaro.org (Pi-Cheng Chen)
Date: Tue, 25 Aug 2015 10:10:44 +0800
Subject: [RESEND PATCH 0/3 v6] Add Mediatek MT8173 cpufreq driver
In-Reply-To: <1439803465-19683-1-git-send-email-pi-cheng.chen@linaro.org>
References: <1439803465-19683-1-git-send-email-pi-cheng.chen@linaro.org>
Message-ID: <CALx668VWg2xVxzy8P7f5QFWRzm+TDJXUghL-_rbvRLsLYjtnng@mail.gmail.com>

On Mon, Aug 17, 2015 at 5:24 PM, Pi-Cheng Chen <pi-cheng.chen at linaro.org> wrote:
> MT8173 is a ARMv8 based SoC with 2 clusters. All CPUs in a single cluster
> share the same power and clock domain. This series tries to add cpufreq support
> for MT8173 SoC. The v6 of this series is resent with Acks added.

Hi Rafael,

Not sure if I has missed the merge window.
Do I have chance to have this series merged for 4.3?
Would you please take [1,2] of this series?
Thanks.

Best Regards,
Pi-Cheng

>
> changes in v6:
> - Move clock and regulator consumer properties document to the device tree
>   bindings documents of MT8173 CPU DVFS clock driver
> - Add change log to describe what is implemented in the MT8173 cpufreq driver
> - Add missed rcu_read_unlock() in the error path
> - Move of_init_opp_table() call to make sure all required hardware resources
>   are already there before it is called
> - Add comments to describe why both platform driver and deivce registration
>   codes are put in the initcall function
> - Use the term "voltage tracking" instead of "voltage trace" according to an
>   internal SoC document
>
> changes in v5:
> - Move resource allocation code from init() into probe() and remove some unused
>   functions due to this change
> - Fix descriptions for device tree binding document
> - Address review comments for last version
> - Register CPU cooling device
>
> Changes in v4:
> - Add bindings for MT8173 cpufreq driver
> - Move OPP table back into device tree
> - Address comments for last version
>
> Changes in v3:
> - Implement MT8173 specific standalone cpufreq driver instead of using
>   cpufreq-dt driver
> - Define OPP table in the driver source code until new OPP binding is ready
>
> Changes in v2:
> - Add intermediate frequency support in cpufreq-dt driver
> - Use voltage scaling code of cpufreq-dt for little cluster instead of
>   implementaion in notifier of mtk-cpufreq driver
> - Code refinement for mtk-cpufreq driver
>
> Pi-Cheng Chen (3):
>   dt-bindings: mediatek: Add MT8173 CPU DVFS clock bindings
>   cpufreq: mediatek: Add MT8173 cpufreq driver
>   arm64: dts: mt8173: Add mt8173 cpufreq driver support
>
>  .../devicetree/bindings/clock/mt8173-cpu-dvfs.txt  |  83 ++++
>  arch/arm64/boot/dts/mediatek/mt8173-evb.dts        |  18 +
>  arch/arm64/boot/dts/mediatek/mt8173.dtsi           |  64 +++
>  drivers/cpufreq/Kconfig.arm                        |   7 +
>  drivers/cpufreq/Makefile                           |   1 +
>  drivers/cpufreq/mt8173-cpufreq.c                   | 524 +++++++++++++++++++++
>  6 files changed, 697 insertions(+)
>  create mode 100644 Documentation/devicetree/bindings/clock/mt8173-cpu-dvfs.txt
>  create mode 100644 drivers/cpufreq/mt8173-cpufreq.c
>
> --
> 1.9.1
>


From k.kozlowski at samsung.com  Mon Aug 24 19:18:11 2015
From: k.kozlowski at samsung.com (Krzysztof Kozlowski)
Date: Tue, 25 Aug 2015 11:18:11 +0900
Subject: [PATCH v2 0/7] Add support for Exynos SROM Controller driver
In-Reply-To: <1440403348-8974-1-git-send-email-pankaj.dubey@samsung.com>
References: <1440403348-8974-1-git-send-email-pankaj.dubey@samsung.com>
Message-ID: <55DBD063.5040703@samsung.com>

On 24.08.2015 17:02, Pankaj Dubey wrote:
> This patch set adds support for Exynos SROM controller DT based driver.
> Currently SROM register sets are used only during S2R, so driver
> basically added for taking care of S2R. It will help us in removing
> static mapping from exynos.c and other extra code handline during S2R.
> 
> This patch set also updated exynos4 and exynos5 dtsi files for with device
> node for srom, and added binding documentation for the same.
> 
> First two patches are some minor cleanup in mach-exynos.
> 
> Patchset v1 was posted here[1]
> [1]: https://lkml.org/lkml/2015/4/29/98
> 
> Changes since v1:
>  - Rebased to latest kgene tree.
>  - Addressed review comments from Krzysztof Kozlowski.
>  - Add two new patches for minor cleanup in exynos.c and map.h
> 
> Pankaj Dubey (7):
>   ARM: EXYNOS: remove unused static mapping of CMU for exynos5
>   ARM: EXYNOS: code cleanup in map.h
>   drivers: soc: add support for exynos SROM driver
>   ARM: EXYNOS: Remove SROM related register settings from mach-exynos
>   ARM: dts: add SROM device node for exynos4
>   ARM: dts: add SROM device node for exynos5
>   Documentation: dt-bindings: add exynos-srom binding information

One more thing: please update the existing Exynos entry in maintainers
so it would cover drivers/soc/samsung.

Best regards,
Krzysztof

> 
>  .../bindings/arm/samsung/exynos-srom.txt           |  12 ++
>  arch/arm/boot/dts/exynos4.dtsi                     |   5 +
>  arch/arm/boot/dts/exynos5.dtsi                     |   5 +
>  arch/arm/mach-exynos/Kconfig                       |   2 +
>  arch/arm/mach-exynos/common.h                      |   2 -
>  arch/arm/mach-exynos/exynos.c                      |  22 ----
>  arch/arm/mach-exynos/include/mach/map.h            |   8 --
>  arch/arm/mach-exynos/regs-srom.h                   |  53 --------
>  arch/arm/mach-exynos/suspend.c                     |  20 +--
>  arch/arm/plat-samsung/include/plat/map-s5p.h       |   1 -
>  drivers/soc/Kconfig                                |   1 +
>  drivers/soc/Makefile                               |   1 +
>  drivers/soc/samsung/Kconfig                        |  13 ++
>  drivers/soc/samsung/Makefile                       |   1 +
>  drivers/soc/samsung/exynos-srom.c                  | 143 +++++++++++++++++++++
>  drivers/soc/samsung/exynos-srom.h                  |  51 ++++++++
>  16 files changed, 236 insertions(+), 104 deletions(-)
>  create mode 100644 Documentation/devicetree/bindings/arm/samsung/exynos-srom.txt
>  delete mode 100644 arch/arm/mach-exynos/regs-srom.h
>  create mode 100644 drivers/soc/samsung/Kconfig
>  create mode 100644 drivers/soc/samsung/Makefile
>  create mode 100644 drivers/soc/samsung/exynos-srom.c
>  create mode 100644 drivers/soc/samsung/exynos-srom.h
> 



From olof at lixom.net  Mon Aug 24 20:05:45 2015
From: olof at lixom.net (Olof Johansson)
Date: Mon, 24 Aug 2015 20:05:45 -0700
Subject: [PATCH 0/3] ARM: uniphier: add outer cache support and rework SMP
 operations
In-Reply-To: <CAK7LNAQk4aEgZV3y90zBVMeq=jA45v683sCR1e5BBYtg5AcDOA@mail.gmail.com>
References: <1440382692-3855-1-git-send-email-yamada.masahiro@socionext.com>
 <CAOesGMgL3bNH_wG3igSJhNOkV0uUfNWEi0t-Gny2A1oNnGKu=w@mail.gmail.com>
 <CAK7LNAQk4aEgZV3y90zBVMeq=jA45v683sCR1e5BBYtg5AcDOA@mail.gmail.com>
Message-ID: <CAOesGMj2M2GBE+KgkUw1PeWQEbzv0spkx58WfVDoGyPYDQGC4g@mail.gmail.com>

On Mon, Aug 24, 2015 at 6:50 PM, Masahiro Yamada
<yamada.masahiro at socionext.com> wrote:
> Hi Olof,
>
>
> 2015-08-25 6:47 GMT+09:00 Olof Johansson <olof at lixom.net>:
>> Hi,
>>
>> On Sun, Aug 23, 2015 at 7:18 PM, Masahiro Yamada
>> <yamada.masahiro at socionext.com> wrote:
>>> 1/3: add outer cache support
>>> 2/3: rework SMP operations
>>> 3/3: add device tree nodes
>>
>> Timing of this is unfortunate, please resend after 4.3-rc1 is out and
>> we can queue it up.
>
> Given that rc8 is out and the merge window has been delayed,
> is it still too late for 4.3-rc1?

Yes.

>>> Because 2/3 highly depends on 1/3, I hope whole of this series
>>> is applied to ARM-SOC tree.
>>
>> Review or acked-by from Russell would be appreciated in that case.
>>
>>> Olof,
>>> From this series, I am using "ARM: uniphier:" rather than "ARM: UniPhier:"
>>> for the subject prefixes because I noticed you often rephased so when you
>>> applied my patches.
>>> Are sub-arch names in lower cases preferable in subject prefixes?
>>
>> If you look at "git log --no-merges --oneline arch/arm/mach-*" you'll
>> see that most platforms use either all-caps or all-lowercase.
>
> I see.
>
> But, we use "UniPhier" (with only U and P capitalized) in our official
> documents.

That's OK, others surely capitalize their platform names too in
documentation. Some of them even have funkier capitalization than
that, such as "SPEAr".


-Olof


From viresh.kumar at linaro.org  Mon Aug 24 20:19:15 2015
From: viresh.kumar at linaro.org (Viresh Kumar)
Date: Tue, 25 Aug 2015 08:49:15 +0530
Subject: [PATCH 0/3] ARM: uniphier: add outer cache support and rework SMP
 operations
In-Reply-To: <CAOesGMj2M2GBE+KgkUw1PeWQEbzv0spkx58WfVDoGyPYDQGC4g@mail.gmail.com>
References: <1440382692-3855-1-git-send-email-yamada.masahiro@socionext.com>
 <CAOesGMgL3bNH_wG3igSJhNOkV0uUfNWEi0t-Gny2A1oNnGKu=w@mail.gmail.com>
 <CAK7LNAQk4aEgZV3y90zBVMeq=jA45v683sCR1e5BBYtg5AcDOA@mail.gmail.com>
 <CAOesGMj2M2GBE+KgkUw1PeWQEbzv0spkx58WfVDoGyPYDQGC4g@mail.gmail.com>
Message-ID: <CAOh2x==pfoPniMWZ5zjdeRufx47VNj_NzTM_z0+NaAJFFCzW6g@mail.gmail.com>

On Tue, Aug 25, 2015 at 8:35 AM, Olof Johansson <olof at lixom.net> wrote:
> That's OK, others surely capitalize their platform names too in
> documentation. Some of them even have funkier capitalization than
> that, such as "SPEAr".

That's how the company projected it :(

www.st.com/spear


From haibo.chen at freescale.com  Mon Aug 24 20:34:19 2015
From: haibo.chen at freescale.com (Haibo Chen)
Date: Tue, 25 Aug 2015 11:34:19 +0800
Subject: [PATCH v6 0/6] mmc: imx: a few fixes and new feature
In-Reply-To: <20150813085854.GA19166@shlinux1.ap.freescale.net>
References: <1439293111-21077-1-git-send-email-haibo.chen@freescale.com>
 <20150813085854.GA19166@shlinux1.ap.freescale.net>
Message-ID: <20150825033418.GA15468@b51421-server.ap.freescale.net>

On Thu, Aug 13, 2015 at 04:58:56PM +0800, Dong Aisheng wrote:
> On Tue, Aug 11, 2015 at 07:38:25PM +0800, Haibo Chen wrote:
> > Changes for v6:
> > -remove duplicate code in esdhc_set_uhs_signaling().
> > -fix a typo for patch-2.
> > -make commit log of patch-3 more specific.
> > 
> > Haibo Chen (6):
> >   mmc: sdhci-esdhc-imx: add imx7d support and support HS400
> >   mmc: sdhci-esdhc-imx: add tuning-step setting support
> >   mmc: sdhci-esdhc-imx: add imx7d support in bingding doc
> >   ARM: dts: imx7d-sdb: add eMMC5.0 support
> >   mmc: sdhci-esdhc-imx: set back the burst_length_enable bit to 1
> >   mmc: sdhci-esdhc-imx: change default watermark level and burst length
> > 
> >  .../devicetree/bindings/mmc/fsl-imx-esdhc.txt      |   6 ++
> >  arch/arm/boot/dts/imx7d-sdb.dts                    |  13 +++
> >  drivers/mmc/host/sdhci-esdhc-imx.c                 | 114 ++++++++++++++++++++-
> >  include/linux/platform_data/mmc-esdhc-imx.h        |   1 +
> >  4 files changed, 130 insertions(+), 4 deletions(-)
> > 
> > -- 
> > 1.9.1
> > 
> 
> The patch set looks good to me.
> 
> Acked-by: Dong Aisheng <aisheng.dong at freescale.com>
> 
> Regards
> Dong Aisheng

Hi Ulf,

Can you help pull these patches into your branch?


Best regards

Haibo
-- 


From baruch at tkos.co.il  Mon Aug 24 21:33:48 2015
From: baruch at tkos.co.il (Baruch Siach)
Date: Tue, 25 Aug 2015 07:33:48 +0300
Subject: [PATCH 2/2] pinctrl: digicolor: convert null test to IS_ERR test
In-Reply-To: <1440450747-10080-3-git-send-email-Julia.Lawall@lip6.fr>
References: <1440450747-10080-1-git-send-email-Julia.Lawall@lip6.fr>
 <1440450747-10080-3-git-send-email-Julia.Lawall@lip6.fr>
Message-ID: <20150825043348.GX2619@sapphire.tkos.co.il>

Hi Julia,

On Mon, Aug 24, 2015 at 11:12:27PM +0200, Julia Lawall wrote:
> Since commit 323de9efdf3e ("pinctrl: make pinctrl_register() return proper
> error code"), pinctrl_register returns an error code rather than NULL on
> failure.  Update a driver that was introduced more recently.
> 
> The semantic patch that makes this change is as follows:
> (http://coccinelle.lip6.fr/)
> 
> // <smpl>
> @@
> expression e,e1,e2;
> @@
> 
> e = pinctrl_register(...)
> ... when != e = e1
> if (
> -   e == NULL
> +   IS_ERR(e)
>    ) {
>      ...
>      return
> -      e2
> +      PTR_ERR(e)
>      ;
>      }
> // </smpl>
> 
> Signed-off-by: Julia Lawall <Julia.Lawall at lip6.fr>

Acked-by: Baruch Siach <baruch at tkos.co.il>

Thanks,
baruch

>  drivers/pinctrl/pinctrl-digicolor.c |    4 ++--
>  1 file changed, 2 insertions(+), 2 deletions(-)
> 
> diff --git a/drivers/pinctrl/pinctrl-digicolor.c b/drivers/pinctrl/pinctrl-digicolor.c
> index 461fffc..11f8b83 100644
> --- a/drivers/pinctrl/pinctrl-digicolor.c
> +++ b/drivers/pinctrl/pinctrl-digicolor.c
> @@ -337,9 +337,9 @@ static int dc_pinctrl_probe(struct platform_device *pdev)
>  	pmap->dev = &pdev->dev;
>  
>  	pmap->pctl = pinctrl_register(pctl_desc, &pdev->dev, pmap);
> -	if (!pmap->pctl) {
> +	if (IS_ERR(pmap->pctl)) {
>  		dev_err(&pdev->dev, "pinctrl driver registration failed\n");
> -		return -EINVAL;
> +		return PTR_ERR(pmap->pctl);
>  	}
>  
>  	ret = dc_gpiochip_add(pmap, pdev->dev.of_node);

-- 
     http://baruch.siach.name/blog/                  ~. .~   Tk Open Systems
=}------------------------------------------------ooO--U--Ooo------------{=
   - baruch at tkos.co.il - tel: +972.2.679.5364, http://www.tkos.co.il -


From k.kozlowski at samsung.com  Mon Aug 24 21:48:57 2015
From: k.kozlowski at samsung.com (Krzysztof Kozlowski)
Date: Tue, 25 Aug 2015 13:48:57 +0900
Subject: [PATCH-v3 2/2] regulator: 88pm800: Add support for configuration
 of dual phase on BUCK1
In-Reply-To: <1440420006-31556-3-git-send-email-vaibhav.hiremath@linaro.org>
References: <1440420006-31556-1-git-send-email-vaibhav.hiremath@linaro.org>
 <1440420006-31556-3-git-send-email-vaibhav.hiremath@linaro.org>
Message-ID: <55DBF3B9.4060602@samsung.com>

On 24.08.2015 21:40, Vaibhav Hiremath wrote:
> 88PM860 device supports dual phase mode on BUCK1 output.
> In normal usecase, BUCK1A and BUCK1B operates independently with 3A
> capacity. And they both can work as a dual phase providing 6A capacity.
> 
> This patch updates the regulator driver to read the respective
> DT property and enable dual-phase mode on BUCK1.
> Note that if dual phase mode is enabled, then BUCK1B will not be
> registered to the regulator framework and the current capacity of
> BUCK1(A) would be set to 6A [3A of BUCK1A + 3A of BUCK1B].
> 
> Signed-off-by: Vaibhav Hiremath <vaibhav.hiremath at linaro.org>
> ---
>  drivers/regulator/88pm800.c | 40 ++++++++++++++++++++++++++++++++++++++++
>  include/linux/mfd/88pm80x.h |  3 +++
>  2 files changed, 43 insertions(+)
> 
> diff --git a/drivers/regulator/88pm800.c b/drivers/regulator/88pm800.c
> index 365a154..7aca6d17 100644
> --- a/drivers/regulator/88pm800.c
> +++ b/drivers/regulator/88pm800.c
> @@ -267,6 +267,37 @@ static struct pm800_regulator_info pm860_regulator_info[] = {
>  	PM800_LDO(ldo20, LDO20, LDO_ENA1_3, 3, 10000, ldo_volt_table2),
>  };
>  
> +static int pm800_regulator_init(struct platform_device *pdev,
> +		struct pm800_regulator_info *info)
> +{
> +	struct pm800_regulators *pm800_data = platform_get_drvdata(pdev);
> +	struct pm80x_chip *chip = pm800_data->chip;
> +	int ret = 0;
> +
> +	/* Currently only supported on 88pm860 device */
> +	if (chip->type != CHIP_PM860)
> +		return 0;
> +
> +	if (of_property_read_bool(pdev->dev.of_node,
> +				"marvell,88pm860-buck1-dualphase-en")) {
> +		/* Update the constraint  to [3A (BUCK1A) + 3A (BUCK1B)] */
> +		info[PM800_ID_BUCK1].max_ua = 6000000;
> +		/* Remove BUCK1B from the list, as we are in dual phase mode */
> +		memset(&info[PM800_ID_BUCK1B], 0, sizeof(*info));
> +		/* Enable dual phase mode */
> +		ret = regmap_update_bits(chip->subchip->regmap_power,
> +					PM860_BUCK1_MISC,
> +					BUCK1_DUAL_PHASE_SEL,
> +					BUCK1_DUAL_PHASE_SEL);
> +		if (ret) {
> +			dev_err(chip->dev, "failed to set dual-pase mode %d\n", ret);
> +			return ret;
> +		}
> +	}
> +
> +	return ret;
> +}
> +
>  static int pm800_regulator_probe(struct platform_device *pdev)
>  {
>  	struct pm80x_chip *chip = dev_get_drvdata(pdev->dev.parent);
> @@ -311,11 +342,20 @@ static int pm800_regulator_probe(struct platform_device *pdev)
>  		return -ENODEV;
>  	}
>  
> +	ret = pm800_regulator_init(pdev, info);
> +	if (ret) {
> +		dev_err(&pdev->dev, "failed to init 88pm800 regulator device\n");
> +		return ret;
> +	}
> +
>  	config.dev = chip->dev;
>  	config.regmap = pm800_data->map;
>  	for (i = 0; i < PM800_ID_RG_MAX; i++) {
>  		struct regulator_dev *regulator;
>  
> +		if (!info[i].desc.name)
> +			continue;

How the driver was working without this on 88PM800? There is a gap in
pm800_regulator_info - three regulators are not set.

The patch itself looks good
Reviewed-by: Krzysztof Kozlowski <k.kozlowski at samsung.com>

Best regards,
Krzysztof



From k.kozlowski at samsung.com  Mon Aug 24 22:08:21 2015
From: k.kozlowski at samsung.com (Krzysztof Kozlowski)
Date: Tue, 25 Aug 2015 14:08:21 +0900
Subject: [PATCH-v2 4/5] clk: 88pm800: Add clk provider driver for 88pm800
 family of devices
In-Reply-To: <1440442594-3102-6-git-send-email-vaibhav.hiremath@linaro.org>
References: <1440442594-3102-1-git-send-email-vaibhav.hiremath@linaro.org>
 <1440442594-3102-6-git-send-email-vaibhav.hiremath@linaro.org>
Message-ID: <55DBF845.4070700@samsung.com>

On 25.08.2015 03:56, Vaibhav Hiremath wrote:
> 88PM800 family of devices supports buffered 32KHz clock output,
> for example,
> 
> 88PM800: CLK32k_1, CLK32k_2 and CLK32k_3
> 88PM860: CLK32K_1 and CLK32K_2
> 
> This patch adds new clk provider driver to support enable/disable
> of the 32KHz clock output from 88PM800 family of devices.
> 
> Signed-off-by: Vaibhav Hiremath <vaibhav.hiremath at linaro.org>
> ---
>  drivers/clk/Kconfig       |   8 ++
>  drivers/clk/Makefile      |   1 +
>  drivers/clk/clk-88pm800.c | 341 ++++++++++++++++++++++++++++++++++++++++++++++
>  3 files changed, 350 insertions(+)
>  create mode 100644 drivers/clk/clk-88pm800.c
> 
> diff --git a/drivers/clk/Kconfig b/drivers/clk/Kconfig
> index 42f7120..c34c14d 100644
> --- a/drivers/clk/Kconfig
> +++ b/drivers/clk/Kconfig
> @@ -167,6 +167,14 @@ config COMMON_CLK_CDCE706
>  	---help---
>  	  This driver supports TI CDCE706 programmable 3-PLL clock synthesizer.
>  
> +config COMMON_CLK_88PM800
> +	tristate "Clock driver for 88PM800 MFD"
> +	depends on MFD_88PM800
> +	---help---
> +	  This driver supports 88PM800 & 88PM860 crystal oscillator
> +	  clock. These multi-function devices have two (88PM860) or three
> +	  (88PM800) fixed-rate output, clocked at 32KHz each.
> +
>  source "drivers/clk/bcm/Kconfig"
>  source "drivers/clk/hisilicon/Kconfig"
>  source "drivers/clk/qcom/Kconfig"
> diff --git a/drivers/clk/Makefile b/drivers/clk/Makefile
> index c4cf075..5248cd3 100644
> --- a/drivers/clk/Makefile
> +++ b/drivers/clk/Makefile
> @@ -80,3 +80,4 @@ obj-$(CONFIG_X86)			+= x86/
>  obj-$(CONFIG_ARCH_ZX)			+= zte/
>  obj-$(CONFIG_ARCH_ZYNQ)			+= zynq/
>  obj-$(CONFIG_H8300)		+= h8300/
> +obj-$(CONFIG_COMMON_CLK_88PM800)	+= clk-88pm800.o
> diff --git a/drivers/clk/clk-88pm800.c b/drivers/clk/clk-88pm800.c
> new file mode 100644
> index 0000000..4c045e1
> --- /dev/null
> +++ b/drivers/clk/clk-88pm800.c
> @@ -0,0 +1,341 @@
> +/*
> + * clk-88pm800.c - Clock driver for 88PM800 family of devices
> + *
> + * This driver is created based on clk-s2mps11.c
> + *
> + * Copyright (C) 2015 Linaro Ltd.
> + *
> + * 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/module.h>
> +#include <linux/err.h>
> +#include <linux/of.h>
> +#include <linux/clkdev.h>
> +#include <linux/regmap.h>
> +#include <linux/clk-provider.h>
> +#include <linux/platform_device.h>
> +#include <linux/mfd/88pm80x.h>
> +
> +/* Number of clocks output from 88pm800 family of device */
> +enum {
> +	PM800_CLK32K_1 = 0,
> +	PM800_CLK32K_2,
> +	PM800_CLK32K_3,
> +	PM800_CLKS_NUM,
> +};
> +
> +struct pm800_clk {
> +	struct pm80x_chip *chip;
> +	struct device_node *clk_np;
> +	struct clk_hw hw;
> +	struct clk *clk;
> +	struct clk_lookup *lookup;
> +	u32 mask;
> +	u32 shift;
> +	unsigned int reg;
> +};
> +
> +static struct pm800_clk *to_pm800_clk(struct clk_hw *hw)
> +{
> +	return container_of(hw, struct pm800_clk, hw);
> +}
> +
> +static int pm800_clk_prepare(struct clk_hw *hw)
> +{
> +	struct pm800_clk *pm800 = to_pm800_clk(hw);
> +
> +	/* We always want to use XO clock */
> +	return regmap_update_bits(pm800->chip->regmap,
> +				 pm800->reg,
> +				 pm800->mask,
> +				 PM800_32K_OUTX_SEL_XO_32KHZ << pm800->shift);
> +}
> +
> +static void pm800_clk_unprepare(struct clk_hw *hw)
> +{
> +	struct pm800_clk *pm800 = to_pm800_clk(hw);
> +
> +	regmap_update_bits(pm800->chip->regmap, pm800->reg,
> +				pm800->mask, ~pm800->mask);
> +}
> +
> +static int pm800_clk_is_prepared(struct clk_hw *hw)
> +{
> +	int ret;
> +	u32 val;
> +	struct pm800_clk *pm800 = to_pm800_clk(hw);
> +
> +	ret = regmap_read(pm800->chip->regmap,
> +				pm800->reg, &val);
> +	if (ret < 0)
> +		return -EINVAL;
> +
> +	return (val & pm800->mask) >> pm800->shift;
> +}
> +
> +static unsigned long pm800_clk_recalc_rate(struct clk_hw *hw,
> +					     unsigned long parent_rate)
> +{
> +	return 32768;
> +}
> +
> +static const struct clk_ops pm800_clk_ops = {
> +	.prepare	= pm800_clk_prepare,
> +	.unprepare	= pm800_clk_unprepare,
> +	.is_prepared	= pm800_clk_is_prepared,
> +	.recalc_rate	= pm800_clk_recalc_rate,
> +};
> +
> +static struct clk_init_data pm800_clks_init[PM800_CLKS_NUM] = {
> +	[PM800_CLK32K_1] = {
> +		.name	= "pm800_clk32k_1",
> +		.ops	= &pm800_clk_ops,
> +		.flags	= CLK_IS_ROOT,
> +	},
> +	[PM800_CLK32K_2] = {
> +		.name	= "pm800_clk32k_2",
> +		.ops	= &pm800_clk_ops,
> +		.flags	= CLK_IS_ROOT,
> +	},
> +	[PM800_CLK32K_3] = {
> +		.name	= "pm800_clk32k_3",
> +		.ops	= &pm800_clk_ops,
> +		.flags	= CLK_IS_ROOT,
> +	},
> +};
> +
> +static struct clk_init_data pm860_clks_init[PM800_CLKS_NUM] = {
> +	[PM800_CLK32K_1] = {
> +		.name	= "pm800_clk32k_1",
> +		.ops	= &pm800_clk_ops,
> +		.flags	= CLK_IS_ROOT,
> +	},
> +	[PM800_CLK32K_2] = {
> +		.name	= "pm800_clk32k_2",
> +		.ops	= &pm800_clk_ops,
> +		.flags	= CLK_IS_ROOT,
> +	},
> +};
> +
> +static int pm800_init_clk(struct pm800_clk *pm800_clks)
> +{
> +	int ret;
> +
> +	/* Enable XO_LJ : Low jitter clock of 32KHz from XO */
> +	ret = regmap_update_bits(pm800_clks->chip->regmap, PM800_LOW_POWER2,
> +			PM800_LOW_POWER2_XO_LJ_EN, PM800_LOW_POWER2_XO_LJ_EN);
> +	if (ret)
> +		return ret;
> +
> +	/* Enable USE_XO : Use XO clock for all internal timing reference */
> +	ret = regmap_update_bits(pm800_clks->chip->regmap, PM800_RTC_CONTROL,
> +			PM800_RTC1_USE_XO, PM800_RTC1_USE_XO);
> +	if (ret)
> +		return ret;
> +
> +	/* OSC_FREERUN: Enable Osc free running mode by clearing the bit */
> +	ret = regmap_update_bits(pm800_clks->chip->regmap, PM800_OSC_CNTRL1,
> +			PM800_OSC_CNTRL1_OSC_FREERUN_EN, 0);
> +	if (ret)
> +		return ret;
> +
> +	return 0;
> +}
> +
> +static struct device_node *pm800_clk_parse_dt(struct platform_device *pdev,
> +		struct clk_init_data *clks_init)
> +{
> +	struct pm80x_chip *chip = dev_get_drvdata(pdev->dev.parent);
> +	struct device_node *clk_np;
> +	int i;
> +
> +	if (!chip->dev->of_node)
> +		return ERR_PTR(-EINVAL);
> +
> +	clk_np = of_get_child_by_name(chip->dev->of_node, "clocks");
> +	if (!clk_np) {
> +		dev_err(&pdev->dev, "could not find clock sub-node\n");
> +		return ERR_PTR(-EINVAL);
> +	}
> +
> +	for (i = 0; i < PM800_CLKS_NUM; i++) {
> +		if (!clks_init[i].name)
> +			continue; /* Skip clocks not present in some devices */
> +
> +		of_property_read_string_index(clk_np, "clock-output-names", i,
> +				&clks_init[i].name);
> +	}
> +
> +	return clk_np;
> +}
> +
> +static int pm800_clk_probe(struct platform_device *pdev)
> +{
> +	struct pm80x_chip *chip = dev_get_drvdata(pdev->dev.parent);
> +	struct pm800_clk *pm800_clks;
> +	struct clk_init_data *clks_init;
> +	static struct clk **clk_table;
> +	static struct clk_onecell_data *of_clk_data;
> +	int i, ret;
> +
> +	pm800_clks = devm_kcalloc(&pdev->dev, PM800_CLKS_NUM,
> +				sizeof(*pm800_clks), GFP_KERNEL);
> +	if (!pm800_clks)
> +		return -ENOMEM;
> +
> +	clk_table = devm_kcalloc(&pdev->dev, PM800_CLKS_NUM,
> +				sizeof(struct clk *), GFP_KERNEL);
> +	if (!clk_table)
> +		return -ENOMEM;
> +
> +	switch (platform_get_device_id(pdev)->driver_data) {
> +	case CHIP_PM800:
> +		clks_init = pm800_clks_init;
> +		break;
> +	case CHIP_PM860:
> +		clks_init = pm860_clks_init;
> +		break;
> +	default:
> +		dev_err(&pdev->dev, "Invalid device type\n");
> +		return -EINVAL;
> +	}
> +
> +	/* Store clocks of_node in first element of pm800_clks array */
> +	pm800_clks->clk_np = pm800_clk_parse_dt(pdev, clks_init);
> +	if (IS_ERR(pm800_clks->clk_np))
> +		return PTR_ERR(pm800_clks->clk_np);
> +
> +	of_clk_data = devm_kzalloc(&pdev->dev, sizeof(*of_clk_data), GFP_KERNEL);
> +	if (!of_clk_data) {
> +		ret = -ENOMEM;
> +		goto err_clk_np;
> +	}
> +
> +	for (i = 0; i < PM800_CLKS_NUM; i++) {
> +		if (!clks_init[i].name)
> +			continue; /* Skip clocks not present in some devices */
> +
> +		pm800_clks[i].chip = chip;
> +		pm800_clks[i].hw.init = &clks_init[i];
> +		/*
> +		 * As of now, mask and shift formula below works for both
> +		 * 88PM800 and it's family of devices,
> +		 *
> +		 *  PM800_RTC_MISC2:
> +		 *      1:0	= CK_32K_OUT1_SEL
> +		 *      3:2	= CK_32K_OUT2_SEL
> +		 *      5:4	= CK_32K_OUT3_SEL
> +		 */
> +		pm800_clks[i].shift = i * 2;
> +		pm800_clks[i].mask = PM800_32K_OUTX_SEL_MASK << pm800_clks[i].shift;
> +		pm800_clks[i].reg = PM800_RTC_MISC2;
> +
> +		pm800_clks[i].clk = devm_clk_register(&pdev->dev,
> +							&pm800_clks[i].hw);
> +		if (IS_ERR(pm800_clks[i].clk)) {
> +			dev_err(&pdev->dev, "Fail to register : %s\n",
> +						clks_init[i].name);
> +			ret = PTR_ERR(pm800_clks[i].clk);
> +			goto err;
> +		}
> +
> +		pm800_clks[i].lookup = clkdev_create(pm800_clks[i].clk,
> +					clks_init[i].name, NULL);
> +		if (!pm800_clks[i].lookup) {
> +			ret = -ENOMEM;
> +			goto err;
> +		}
> +
> +		clk_table[i] = pm800_clks[i].clk;
> +	}
> +
> +	of_clk_data->clks = clk_table;
> +	of_clk_data->clk_num = PM800_CLKS_NUM;
> +	ret = of_clk_add_provider(pm800_clks->clk_np, of_clk_src_onecell_get,
> +			of_clk_data);
> +	if (ret) {
> +		dev_err(&pdev->dev, "Fail to add OF clk provider : %d\n", ret);
> +		goto err;
> +	}
> +
> +	/* Common for all 32KHz clock output */
> +	ret = pm800_init_clk(&pm800_clks[0]);
> +	if (ret) {
> +		dev_err(&pdev->dev, "Failed to initialize clk : %d\n", ret);
> +		goto err;

You're missing here of_clk_del_provider().

> +	}
> +
> +	platform_set_drvdata(pdev, pm800_clks);
> +
> +	return 0;
> +
> +err:
> +	for (i = 0; i < PM800_CLKS_NUM; i++) {
> +		if (pm800_clks[i].lookup)
> +			clkdev_drop(pm800_clks[i].lookup);
> +	}
> +err_clk_np:
> +	/* Drop the reference obtained in pm800_clk_parse_dt */
> +	of_node_put(pm800_clks[0].clk_np);
> +
> +	return ret;
> +}
> +
> +static int pm800_clk_remove(struct platform_device *pdev)
> +{
> +	struct pm800_clk *pm800_clks = platform_get_drvdata(pdev);
> +	int i;
> +
> +	of_clk_del_provider(pm800_clks[0].clk_np);
> +	/* Drop the reference obtained in pm800_clk_parse_dt */
> +	of_node_put(pm800_clks[0].clk_np);
> +
> +	for (i = 0; i < PM800_CLKS_NUM; i++) {
> +		if (pm800_clks[i].lookup)
> +			clkdev_drop(pm800_clks[i].lookup);
> +	}
> +
> +	return 0;
> +}
> +
> +static const struct platform_device_id pm800_clk_id[] = {
> +	{ "88pm800-clk", CHIP_PM800},
> +	{ "88pm860-clk", CHIP_PM860},
> +	{ },
> +};
> +MODULE_DEVICE_TABLE(platform, pm800_clk_id);
> +
> +static struct platform_driver pm800_clk_driver = {
> +	.driver = {
> +		.name  = "88pm80x-clk",
> +	},
> +	.probe = pm800_clk_probe,
> +	.remove = pm800_clk_remove,
> +	.id_table = pm800_clk_id,
> +};
> +
> +static int __init pm800_clk_init(void)
> +{
> +	return platform_driver_register(&pm800_clk_driver);
> +}
> +subsys_initcall(pm800_clk_init);

Does it have to be subsys_initcall instead of regular
module_platform_driver? Strict ordering of modules should be avoided. Do
you require it?

Rest looks fine (actually Stephen pointed some issue during previous
review so I had easier job).

Best regards,
Krzysztof



From maxime.ripard at free-electrons.com  Mon Aug 24 22:15:43 2015
From: maxime.ripard at free-electrons.com (Maxime Ripard)
Date: Tue, 25 Aug 2015 07:15:43 +0200
Subject: [PATCH v3] dmaengine: hdmac: Add memset capabilities
In-Reply-To: <20150824142425.GL13546@localhost>
References: <1440408075-26438-1-git-send-email-maxime.ripard@free-electrons.com>
 <20150824142425.GL13546@localhost>
Message-ID: <20150825051543.GZ2413@lukather>

On Mon, Aug 24, 2015 at 07:54:25PM +0530, Vinod Koul wrote:
> On Mon, Aug 24, 2015 at 11:21:15AM +0200, Maxime Ripard wrote:
> > Just like for the XDMAC, the SoCs that embed the HDMAC don't have any kind
> > of GPU, and need to accelerate a few framebuffer-related operations through
> > their DMA controller.
> > 
> > However, unlike the XDMAC, the HDMAC doesn't have the memset capability
> > built-in. That can be easily emulated though, by doing a transfer with a
> > fixed address on the variable that holds the value we want to set.
> 
> Applied, thanks

Thanks for merging it so quickly, and sorry for the silent conflict.

Maxime

-- 
Maxime Ripard, Free Electrons
Embedded Linux, Kernel and Android engineering
http://free-electrons.com
-------------- next part --------------
A non-text attachment was scrubbed...
Name: signature.asc
Type: application/pgp-signature
Size: 819 bytes
Desc: Digital signature
URL: <http://lists.infradead.org/pipermail/linux-arm-kernel/attachments/20150825/d7122093/attachment.sig>

From keescook at chromium.org  Mon Aug 24 22:20:03 2015
From: keescook at chromium.org (Kees Cook)
Date: Mon, 24 Aug 2015 22:20:03 -0700
Subject: [BUG] arm: kgdb: patch_text() in kgdb_arch_set_breakpoint() may
 sleep
In-Reply-To: <CAD=FV=Xkye3_e-ZvpUfXyQJ7VFz2s6bTPSuty4-x7Fpa72UW2g@mail.gmail.com>
References: <55C230C7.2000909@nvidia.com>
 <CAD=FV=V_E+YMQuW5kvn+52Ugc_5hZsyXKKQ9Ywo_emoqK-N+Qw@mail.gmail.com>
 <CAGXu5j+P=LtTAVQbkn4w6Y9pTVouvRgAhwfS+rAmKfqTXC8pyg@mail.gmail.com>
 <CAD=FV=Xkye3_e-ZvpUfXyQJ7VFz2s6bTPSuty4-x7Fpa72UW2g@mail.gmail.com>
Message-ID: <CAGXu5jKduNfz0-zhM+LvA=jHFs51kxoBegdHOFaE5YdJZ3xkrw@mail.gmail.com>

On Mon, Aug 24, 2015 at 4:56 PM, Doug Anderson <dianders at chromium.org> wrote:
> Kees,
>
> On Mon, Aug 24, 2015 at 10:46 AM, Kees Cook <keescook at chromium.org> wrote:
>> On Sun, Aug 23, 2015 at 7:45 PM, Doug Anderson <dianders at chromium.org> wrote:
>>> On Wed, Aug 5, 2015 at 8:50 AM, Aapo Vienamo <avienamo at nvidia.com> wrote:
>>>> Hi,
>>>>
>>>> The breakpoint setting code in arch/arm/kernel/kgdb.c calls
>>>> patch_text(), which ends up trying to sleep while in interrupt context.
>>>> The bug was introduced by commit: 23a4e40 arm: kgdb: Handle read-only
>>>> text / modules. The resulting behavior is "BUG: scheduling while
>>>> atomic..." when setting a breakpoint in kgdb. This was tested on an
>>>> Nvidia Jetson TK1 board with 4.2.0-rc5-next-20150805 kernel.
>>>>
>>>> Regards,
>>>> Aapo Vienamo
>>>
>>> Aapo,
>>>
>>> Including the stack trace with this would have been helpful, though
>>> it's not too hard to reproduce.  Here it is:
>>>
>>> [  416.510559] BUG: scheduling while atomic: swapper/0/0/0x00010007
>>> [  416.516554] Modules linked in:
>>> [  416.519614] CPU: 0 PID: 0 Comm: swapper/0 Not tainted
>>> 4.2.0-rc7-00133-geb63b34 #1073
>>> [  416.527341] Hardware name: Rockchip (Device Tree)
>>> [  416.532042] [<c0017a4c>] (unwind_backtrace) from [<c00133d4>]
>>> (show_stack+0x20/0x24)
>>> [  416.539772] [<c00133d4>] (show_stack) from [<c05400e8>]
>>> (dump_stack+0x84/0xb8)
>>> [  416.546983] [<c05400e8>] (dump_stack) from [<c004913c>]
>>> (__schedule_bug+0x54/0x6c)
>>> [  416.554540] [<c004913c>] (__schedule_bug) from [<c054065c>]
>>> (__schedule+0x80/0x668)
>>> [  416.562183] [<c054065c>] (__schedule) from [<c0540cfc>] (schedule+0xb8/0xd4)
>>> [  416.569219] [<c0540cfc>] (schedule) from [<c0543a3c>]
>>> (schedule_timeout+0x2c/0x234)
>>> [  416.576861] [<c0543a3c>] (schedule_timeout) from [<c05417c0>]
>>> (wait_for_common+0xf4/0x188)
>>> [  416.585109] [<c05417c0>] (wait_for_common) from [<c0541874>]
>>> (wait_for_completion+0x20/0x24)
>>> [  416.593531] [<c0541874>] (wait_for_completion) from [<c00a0104>]
>>> (__stop_cpus+0x58/0x70)
>>> [  416.601608] [<c00a0104>] (__stop_cpus) from [<c00a0580>]
>>> (stop_cpus+0x3c/0x54)
>>> [  416.608817] [<c00a0580>] (stop_cpus) from [<c00a06c4>]
>>> (__stop_machine+0xcc/0xe8)
>>> [  416.616286] [<c00a06c4>] (__stop_machine) from [<c00a0714>]
>>> (stop_machine+0x34/0x44)
>>> [  416.624016] [<c00a0714>] (stop_machine) from [<c00173e8>]
>>> (patch_text+0x28/0x34)
>>> [  416.631399] [<c00173e8>] (patch_text) from [<c001733c>]
>>> (kgdb_arch_set_breakpoint+0x40/0x4c)
>>> [  416.639823] [<c001733c>] (kgdb_arch_set_breakpoint) from
>>> [<c00a0d68>] (kgdb_validate_break_address+0x2c/0x60)
>>> [  416.649719] [<c00a0d68>] (kgdb_validate_break_address) from
>>> [<c00a0e90>] (dbg_set_sw_break+0x1c/0xdc)
>>> [  416.658922] [<c00a0e90>] (dbg_set_sw_break) from [<c00a2e88>]
>>> (gdb_serial_stub+0x9c4/0xba4)
>>> [  416.667259] [<c00a2e88>] (gdb_serial_stub) from [<c00a11cc>]
>>> (kgdb_cpu_enter+0x1f8/0x60c)
>>> [  416.675423] [<c00a11cc>] (kgdb_cpu_enter) from [<c00a18cc>]
>>> (kgdb_handle_exception+0x19c/0x1d0)
>>> [  416.684106] [<c00a18cc>] (kgdb_handle_exception) from [<c0016f7c>]
>>> (kgdb_compiled_brk_fn+0x30/0x3c)
>>> [  416.693135] [<c0016f7c>] (kgdb_compiled_brk_fn) from [<c00091a4>]
>>> (do_undefinstr+0x1a4/0x20c)
>>> [  416.701643] [<c00091a4>] (do_undefinstr) from [<c001400c>]
>>> (__und_svc_finish+0x0/0x34)
>>> [  416.709543] Exception stack(0xc07c1ce8 to 0xc07c1d30)
>>> [  416.714584] 1ce0:                   00000000 c07c6504 c086e290
>>> c086e294 c086e294 c086e290
>>> [  416.722745] 1d00: c07c6504 00000067 00000001 c07c2100 00000027
>>> c07c1d4c c07c1d50 c07c1d30
>>> [  416.730905] 1d20: c00a0990 c00a08d0 60000193 ffffffff
>>> [  416.735947] [<c001400c>] (__und_svc_finish) from [<c00a08d0>]
>>> (kgdb_breakpoint+0x58/0x94)
>>> [  416.744110] [<c00a08d0>] (kgdb_breakpoint) from [<c00a0990>]
>>> (sysrq_handle_dbg+0x58/0x6c)
>>> [  416.752273] [<c00a0990>] (sysrq_handle_dbg) from [<c02c230c>]
>>> (__handle_sysrq+0xac/0x15c)
>>> [  416.760437] [<c02c230c>] (__handle_sysrq) from [<c02c23ec>]
>>> (handle_sysrq+0x30/0x34)
>>>
>>>
>>> Kees: I think you've dealt with a lot more of these types of issues
>>> than I have.  Any quick thoughts?  If not I can put it on my long-term
>>> list of things to do, but until then we could always just post a
>>> Revert...
>>
>> I don't think a revert is in order here. CONFIG_DEBUG_RODATA could be
>> turned off for builds where you need kgdb while this bug gets found.
>
> I don't think that's right.  In my testing I don't have
> CONFIG_DEBUG_RODATA.  I think I did the right grep:
>
> $ grep ARM_KERNMEM_PERMS .config
> # CONFIG_ARM_KERNMEM_PERMS is not set
>
> Basically no matter what we'll call:
> - kgdb_arch_set_breakpoint
> -- patch_text
> --- stop_machine
>
> ...no dependencies on RODATA.

I said DEBUG_RODATA since that's the stricter of the options (it
requires KERNMEM_PERMS). But yes, I see now that patch.c doesn't test
for this feature at all (which probably makes sense).

>> I
>> don't actually see where we've gone wrong, though. Looks like
>> scheduling happened while waiting for CPUs to stop? Where did we enter
>> atomic?
>
> We're in kdb.  That's a stop mode debugger.  No sleeping allowed while
> in the debugger.
>
>
>> Perhaps we need to test if we're already atomic in patch_text, and
>> only call stop_machine if we need to?
>>
>> Untested (and likely mangled by gmail):
>>
>> diff --git a/arch/arm/kernel/patch.c b/arch/arm/kernel/patch.c
>> index 69bda1a5707e..855696bfe072 100644
>> --- a/arch/arm/kernel/patch.c
>> +++ b/arch/arm/kernel/patch.c
>> @@ -124,5 +124,8 @@ void __kprobes patch_text(void *addr, unsigned int insn)
>>                 .insn = insn,
>>         };
>>
>> -       stop_machine(patch_text_stop_machine, &patch, NULL);
>> +       if (unlikely(in_atomic_preempt_off()))
>> +               patch_text_stop_machine(&patch);
>> +       else
>> +               stop_machine(patch_text_stop_machine, &patch, NULL);
>
> Ah, right.  We're already stopped, so just not stopping again seems
> reasonable.  I think I'd rather just use in_dbg_master() as the test
> since that's a case where I _know_ all the CPUs are stopped.  Doesn't
> in_atomic_preempt_off() just check if preemption is off for this
> single CPU?
>
> Anyway, I'll throw a patch up now.  It fixes it for me.  :)

The in_atomic_preempt_off is what the schedule is using for this test,
so it seemed the best generic fix (in the case that some other caller
in the future tries to call patch_text also, not just kgdb).

Thanks for testing! Feel free to add my S-o-b or Acked-by, as appropriate. :)

-Kees

-- 
Kees Cook
Chrome OS Security


From k.kozlowski at samsung.com  Mon Aug 24 22:25:20 2015
From: k.kozlowski at samsung.com (Krzysztof Kozlowski)
Date: Tue, 25 Aug 2015 14:25:20 +0900
Subject: [PATCH-v2 5/5] mfd: 88pm800: Add support for clk subdevice
In-Reply-To: <1440442594-3102-7-git-send-email-vaibhav.hiremath@linaro.org>
References: <1440442594-3102-1-git-send-email-vaibhav.hiremath@linaro.org>
 <1440442594-3102-7-git-send-email-vaibhav.hiremath@linaro.org>
Message-ID: <55DBFC40.3010603@samsung.com>

On 25.08.2015 03:56, Vaibhav Hiremath wrote:
> This patch adds mfd_cell/clk-subdevice for 88PM800 MFD
> (and family of devices).
> 
> Signed-off-by: Vaibhav Hiremath <vaibhav.hiremath at linaro.org>
> ---
>  drivers/mfd/88pm800.c | 25 +++++++++++++++++++++++++
>  1 file changed, 25 insertions(+)
> 
> diff --git a/drivers/mfd/88pm800.c b/drivers/mfd/88pm800.c
> index c4e097d..a928eed 100644
> --- a/drivers/mfd/88pm800.c
> +++ b/drivers/mfd/88pm800.c
> @@ -173,6 +173,14 @@ static const struct mfd_cell regulator_devs[] = {
>  	},
>  };
>  
> +static struct mfd_cell clk_devs[] = {
> +	{
> +		.name = "88pm80x-clk",
> +		.of_compatible = "marvell,88pm800-clk",
> +		.id = -1,

The "-1" here stands for PLATFORM_DEVID_NONE?

Best regards,
Krzysztof

> +	},
> +};
> +
>  static const struct regmap_irq pm800_irqs[] = {
>  	/* INT0 */
>  	[PM800_IRQ_ONKEY] = {
> @@ -344,6 +352,17 @@ static int device_regulator_init(struct pm80x_chip *chip)
>  			ARRAY_SIZE(regulator_devs), NULL, 0, NULL);
>  }
>  
> +static int device_clk_init(struct pm80x_chip *chip)
> +{
> +	if (chip->type == CHIP_PM800)
> +		clk_devs[0].name = "88pm800-clk";
> +	else if (chip->type == CHIP_PM860)
> +		clk_devs[0].name = "88pm860-clk";
> +
> +	return mfd_add_devices(chip->dev, 0, &clk_devs[0],
> +			ARRAY_SIZE(clk_devs), NULL, 0, NULL);
> +}
> +
>  static int device_irq_init_800(struct pm80x_chip *chip)
>  {
>  	struct regmap *map = chip->regmap;
> @@ -511,6 +530,12 @@ static int device_800_init(struct pm80x_chip *chip)
>  		goto out;
>  	}
>  
> +	ret = device_clk_init(chip);
> +	if (ret) {
> +		dev_err(chip->dev, "Failed to add clk subdev\n");
> +		goto out;
> +	}
> +
>  	return 0;
>  out_dev:
>  	mfd_remove_devices(chip->dev);
> 



From eddie.huang at mediatek.com  Mon Aug 24 23:00:40 2015
From: eddie.huang at mediatek.com (Eddie Huang)
Date: Tue, 25 Aug 2015 14:00:40 +0800
Subject: [PATCH v2] soc: mediatek: add scpsys support active_wakeup
Message-ID: <1440482440-28700-1-git-send-email-eddie.huang@mediatek.com>

Register gpd_dev_ops.active_wakeup function to support keep power
during suspend state. And add flag to each power domain to
decide whether keep power during suspend or not.

Signed-off-by: Chunfeng Yun <chunfeng.yun at mediatek.com>
Signed-off-by: Eddie Huang <eddie.huang at mediatek.com>
Acked-by: Sascha Hauer <s.hauer at pengutronix.de>

---
Change in v2:
Drop .active_wakeup = false lines in scp_domain_data[] array

---
 drivers/soc/mediatek/mtk-scpsys.c | 19 +++++++++++++++++++
 1 file changed, 19 insertions(+)

diff --git a/drivers/soc/mediatek/mtk-scpsys.c b/drivers/soc/mediatek/mtk-scpsys.c
index 43a79ed..df2f288 100644
--- a/drivers/soc/mediatek/mtk-scpsys.c
+++ b/drivers/soc/mediatek/mtk-scpsys.c
@@ -67,6 +67,7 @@ struct scp_domain_data {
 	u32 sram_pdn_ack_bits;
 	u32 bus_prot_mask;
 	enum clk_id clk_id;
+	bool active_wakeup;
 };
 
 static const struct scp_domain_data scp_domain_data[] __initconst = {
@@ -127,6 +128,7 @@ static const struct scp_domain_data scp_domain_data[] __initconst = {
 		.sram_pdn_bits = GENMASK(11, 8),
 		.sram_pdn_ack_bits = GENMASK(15, 12),
 		.clk_id = MT8173_CLK_NONE,
+		.active_wakeup = true,
 	},
 	[MT8173_POWER_DOMAIN_MFG_ASYNC] = {
 		.name = "mfg_async",
@@ -171,6 +173,7 @@ struct scp_domain {
 	u32 sram_pdn_bits;
 	u32 sram_pdn_ack_bits;
 	u32 bus_prot_mask;
+	bool active_wakeup;
 };
 
 struct scp {
@@ -370,6 +373,20 @@ out:
 	return ret;
 }
 
+static bool scpsys_active_wakeup(struct device *dev)
+{
+	struct generic_pm_domain *genpd;
+	struct scp_domain *scpd;
+
+	if (IS_ERR_OR_NULL(dev->pm_domain))
+		return false;
+
+	genpd = pd_to_genpd(dev->pm_domain);
+	scpd = container_of(genpd, struct scp_domain, genpd);
+
+	return scpd->active_wakeup;
+}
+
 static int __init scpsys_probe(struct platform_device *pdev)
 {
 	struct genpd_onecell_data *pd_data;
@@ -427,12 +444,14 @@ static int __init scpsys_probe(struct platform_device *pdev)
 		scpd->sram_pdn_bits = data->sram_pdn_bits;
 		scpd->sram_pdn_ack_bits = data->sram_pdn_ack_bits;
 		scpd->bus_prot_mask = data->bus_prot_mask;
+		scpd->active_wakeup = data->active_wakeup;
 		if (data->clk_id != MT8173_CLK_NONE)
 			scpd->clk = clk[data->clk_id];
 
 		genpd->name = data->name;
 		genpd->power_off = scpsys_power_off;
 		genpd->power_on = scpsys_power_on;
+		genpd->dev_ops.active_wakeup = scpsys_active_wakeup;
 
 		/*
 		 * Initially turn on all domains to make the domains usable
-- 
1.9.1



From vaibhav.hiremath at linaro.org  Mon Aug 24 23:23:44 2015
From: vaibhav.hiremath at linaro.org (Vaibhav Hiremath)
Date: Tue, 25 Aug 2015 11:53:44 +0530
Subject: [PATCH-v3 2/2] regulator: 88pm800: Add support for configuration
 of dual phase on BUCK1
In-Reply-To: <55DBF3B9.4060602@samsung.com>
References: <1440420006-31556-1-git-send-email-vaibhav.hiremath@linaro.org>
 <1440420006-31556-3-git-send-email-vaibhav.hiremath@linaro.org>
 <55DBF3B9.4060602@samsung.com>
Message-ID: <55DC09F0.6010109@linaro.org>



On Tuesday 25 August 2015 10:18 AM, Krzysztof Kozlowski wrote:
> On 24.08.2015 21:40, Vaibhav Hiremath wrote:
>> 88PM860 device supports dual phase mode on BUCK1 output.
>> In normal usecase, BUCK1A and BUCK1B operates independently with 3A
>> capacity. And they both can work as a dual phase providing 6A capacity.
>>
>> This patch updates the regulator driver to read the respective
>> DT property and enable dual-phase mode on BUCK1.
>> Note that if dual phase mode is enabled, then BUCK1B will not be
>> registered to the regulator framework and the current capacity of
>> BUCK1(A) would be set to 6A [3A of BUCK1A + 3A of BUCK1B].
>>
>> Signed-off-by: Vaibhav Hiremath <vaibhav.hiremath at linaro.org>
>> ---
>>   drivers/regulator/88pm800.c | 40 ++++++++++++++++++++++++++++++++++++++++
>>   include/linux/mfd/88pm80x.h |  3 +++
>>   2 files changed, 43 insertions(+)
>>
>> diff --git a/drivers/regulator/88pm800.c b/drivers/regulator/88pm800.c
>> index 365a154..7aca6d17 100644
>> --- a/drivers/regulator/88pm800.c
>> +++ b/drivers/regulator/88pm800.c
>> @@ -267,6 +267,37 @@ static struct pm800_regulator_info pm860_regulator_info[] = {
>>   	PM800_LDO(ldo20, LDO20, LDO_ENA1_3, 3, 10000, ldo_volt_table2),
>>   };
>>
>> +static int pm800_regulator_init(struct platform_device *pdev,
>> +		struct pm800_regulator_info *info)
>> +{
>> +	struct pm800_regulators *pm800_data = platform_get_drvdata(pdev);
>> +	struct pm80x_chip *chip = pm800_data->chip;
>> +	int ret = 0;
>> +
>> +	/* Currently only supported on 88pm860 device */
>> +	if (chip->type != CHIP_PM860)
>> +		return 0;
>> +
>> +	if (of_property_read_bool(pdev->dev.of_node,
>> +				"marvell,88pm860-buck1-dualphase-en")) {
>> +		/* Update the constraint  to [3A (BUCK1A) + 3A (BUCK1B)] */
>> +		info[PM800_ID_BUCK1].max_ua = 6000000;
>> +		/* Remove BUCK1B from the list, as we are in dual phase mode */
>> +		memset(&info[PM800_ID_BUCK1B], 0, sizeof(*info));
>> +		/* Enable dual phase mode */
>> +		ret = regmap_update_bits(chip->subchip->regmap_power,
>> +					PM860_BUCK1_MISC,
>> +					BUCK1_DUAL_PHASE_SEL,
>> +					BUCK1_DUAL_PHASE_SEL);
>> +		if (ret) {
>> +			dev_err(chip->dev, "failed to set dual-pase mode %d\n", ret);
>> +			return ret;
>> +		}
>> +	}
>> +
>> +	return ret;
>> +}
>> +
>>   static int pm800_regulator_probe(struct platform_device *pdev)
>>   {
>>   	struct pm80x_chip *chip = dev_get_drvdata(pdev->dev.parent);
>> @@ -311,11 +342,20 @@ static int pm800_regulator_probe(struct platform_device *pdev)
>>   		return -ENODEV;
>>   	}
>>
>> +	ret = pm800_regulator_init(pdev, info);
>> +	if (ret) {
>> +		dev_err(&pdev->dev, "failed to init 88pm800 regulator device\n");
>> +		return ret;
>> +	}
>> +
>>   	config.dev = chip->dev;
>>   	config.regmap = pm800_data->map;
>>   	for (i = 0; i < PM800_ID_RG_MAX; i++) {
>>   		struct regulator_dev *regulator;
>>
>> +		if (!info[i].desc.name)
>> +			continue;
>
> How the driver was working without this on 88PM800? There is a gap in
> pm800_regulator_info - three regulators are not set.
>

I have 88PM860 based board, where the whole array will be filled up.
So it was missed I guess :)

But when I introduced logic for skipping BUCK1B, I hit this.
And here is the fix.


> The patch itself looks good
> Reviewed-by: Krzysztof Kozlowski <k.kozlowski at samsung.com>
>

Thanks for your review.

Thanks,
Vaibhav


From kishon at ti.com  Mon Aug 24 23:36:55 2015
From: kishon at ti.com (Kishon Vijay Abraham I)
Date: Tue, 25 Aug 2015 12:06:55 +0530
Subject: [PATCH 12/17] ARM: dts: am57xx-beagle-x15: Fix regulator populated
 in MMC1 dt node
In-Reply-To: <55B92B88.1080409@ti.com>
References: <1438168187-1614-1-git-send-email-kishon@ti.com>
 <1438168187-1614-13-git-send-email-kishon@ti.com> <55B92B88.1080409@ti.com>
Message-ID: <55DC0D07.7030504@ti.com>

Hi Tony,

On Thursday 30 July 2015 01:07 AM, Nishanth Menon wrote:
> On 07/29/2015 06:09 AM, Kishon Vijay Abraham I wrote:
>> For beagle x15, both the vdd and io lines are connected to the
>> same regulator (ldo1_reg). However vmmc_aux is populated to vdd_3v3.
>> Remove it.
>>
>> Signed-off-by: Kishon Vijay Abraham I <kishon at ti.com>
>> ---
>>  arch/arm/boot/dts/am57xx-beagle-x15.dts |    1 -
>>  1 file changed, 1 deletion(-)
>>
>> diff --git a/arch/arm/boot/dts/am57xx-beagle-x15.dts b/arch/arm/boot/dts/am57xx-beagle-x15.dts
>> index a63bf78..d0db5c5 100644
>> --- a/arch/arm/boot/dts/am57xx-beagle-x15.dts
>> +++ b/arch/arm/boot/dts/am57xx-beagle-x15.dts
>> @@ -579,7 +579,6 @@
>>  	pinctrl-0 = <&mmc1_pins_default>;
>>  
>>  	vmmc-supply = <&ldo1_reg>;
>> -	vmmc_aux-supply = <&vdd_3v3>;
>>  	pbias-supply = <&pbias_mmc_reg>;
>>  	bus-width = <4>;
>>  	cd-gpios = <&gpio6 27 0>; /* gpio 219 */
>>
> Acked-by: Nishanth Menon <nm at ti.com>

Can you pick this one or you want me to resend it?

Thanks
Kishon


From hverkuil at xs4all.nl  Mon Aug 24 23:36:56 2015
From: hverkuil at xs4all.nl (Hans Verkuil)
Date: Tue, 25 Aug 2015 08:36:56 +0200
Subject: [PATCH v7 11/44] [media] media: use entity.graph_obj.mdev instead
 of .parent
In-Reply-To: <dc1be98277c46ddd87e431148fc7e332176828ab.1440359643.git.mchehab@osg.samsung.com>
References: <cover.1440359643.git.mchehab@osg.samsung.com>
 <dc1be98277c46ddd87e431148fc7e332176828ab.1440359643.git.mchehab@osg.samsung.com>
Message-ID: <55DC0D08.10504@xs4all.nl>

On 08/23/2015 10:17 PM, Mauro Carvalho Chehab wrote:
> From: Javier Martinez Canillas <javier at osg.samsung.com>
> 
> The struct media_entity has a .parent field that stores a pointer
> to the parent struct media_device. But recently a media_gobj was
> embedded into the entities and since struct media_gojb already has
> a pointer to a struct media_device in the .mdev field, the .parent
> field becomes redundant and can be removed.
> 
> This patch replaces all the usage of .parent by .graph_obj.mdev so
> that field will become unused and can be removed on a later patch.
> 
> No functional changes.
> 
> The transformation was made using the following coccinelle spatch:
> 
> @@
> struct media_entity *me;
> @@
> 
> - me->parent
> + me->graph_obj.mdev
> 
> @@
> struct media_entity *link;
> @@
> 
> - link->source->entity->parent
> + link->source->entity->graph_obj.mdev
> 
> @@
> struct exynos_video_entity *ve;
> @@
> 
> - ve->vdev.entity.parent
> + ve->vdev.entity.graph_obj.mdev
> 
> Suggested-by: Mauro Carvalho Chehab <mchehab at osg.samsung.com>
> 
> Signed-off-by: Javier Martinez Canillas <javier at osg.samsung.com>
> Signed-off-by: Mauro Carvalho Chehab <mchehab at osg.samsung.com>

Acked-by: Hans Verkuil <hans.verkuil at cisco.com>


From broonie at kernel.org  Mon Aug 24 23:38:25 2015
From: broonie at kernel.org (Mark Brown)
Date: Tue, 25 Aug 2015 07:38:25 +0100
Subject: [PATCH-v3] mfd: 88pm80x: Add 88pm860 chip type support
In-Reply-To: <55DAC179.2060802@linaro.org>
References: <1437393151-5362-1-git-send-email-vaibhav.hiremath@linaro.org>
 <55DAC179.2060802@linaro.org>
Message-ID: <20150825063825.GE27431@sirena.org.uk>

On Mon, Aug 24, 2015 at 12:32:17PM +0530, Vaibhav Hiremath wrote:
> On Monday 20 July 2015 05:22 PM, Vaibhav Hiremath wrote:
> >Add chip identification support for 88PM860 device
> >to the pm80x_chip_mapping table.

> Last update/understanding which I have on this patch is,
> 
> Lee is OK with taking this patch from regulator tree.
> Lee please let me know if you think otherwise.
> 
> With this patch in, the build dependency will go away.
> 
> Request to pick this patch into your topic/88pm800 branch and run build
> test.

Please don't send content free pings, they just waste time.  I can't
review or apply content free pings.  Please submit patches following the
process in SubmittingPatches.

The chances are I deleted this mail unread since it is a MFD patch...
-------------- next part --------------
A non-text attachment was scrubbed...
Name: signature.asc
Type: application/pgp-signature
Size: 473 bytes
Desc: Digital signature
URL: <http://lists.infradead.org/pipermail/linux-arm-kernel/attachments/20150825/abcce420/attachment-0001.sig>

From punnaia at xilinx.com  Mon Aug 24 23:46:38 2015
From: punnaia at xilinx.com (punnaiah choudary kalluri)
Date: Tue, 25 Aug 2015 12:16:38 +0530
Subject: [PATCH v4 1/2] Documentation: dt: Add Xilinx zynqmp dma device
 tree binding documentation
In-Reply-To: <CAL_Jsq+261JzSorbgEyQ4BFCHbsFsBaJQnpWJX-G=SX3yhqZJw@mail.gmail.com>
References: <1438831173-8761-1-git-send-email-punnaia@xilinx.com>
 <CAL_Jsq+261JzSorbgEyQ4BFCHbsFsBaJQnpWJX-G=SX3yhqZJw@mail.gmail.com>
Message-ID: <CAGnW=BbS0V-avm+oV-V5J0995YUXwP9v0uZFwc4i9587u1SDTg@mail.gmail.com>

Hi Rob,

On Tue, Aug 25, 2015 at 12:23 AM, Rob Herring <robherring2 at gmail.com> wrote:
> On Wed, Aug 5, 2015 at 10:19 PM, Punnaiah Choudary Kalluri
> <punnaiah.choudary.kalluri at xilinx.com> wrote:
>> Device-tree binding documentation for Xilinx zynqmp dma engine used in
>> Zynq UltraScale+ MPSoC.
>>
>> Signed-off-by: Punnaiah Choudary Kalluri <punnaia at xilinx.com>
>> ---
>> Changes in v4:
>> - None
>> Changes in v3:
>> - None
>> Changes in v2:
>> - None
>> ---
>>  .../devicetree/bindings/dma/xilinx/zynqmp_dma.txt  |   61 ++++++++++++++++++++
>>  1 files changed, 61 insertions(+), 0 deletions(-)
>>  create mode 100644 Documentation/devicetree/bindings/dma/xilinx/zynqmp_dma.txt
>>
>> diff --git a/Documentation/devicetree/bindings/dma/xilinx/zynqmp_dma.txt b/Documentation/devicetree/bindings/dma/xilinx/zynqmp_dma.txt
>> new file mode 100644
>> index 0000000..e4f92b9
>> --- /dev/null
>> +++ b/Documentation/devicetree/bindings/dma/xilinx/zynqmp_dma.txt
>> @@ -0,0 +1,61 @@
>> +Xilinx ZynqMP DMA engine, it does support memory to memory transfers,
>> +memory to device and device to memory transfers. It also has flow
>> +control and rate control support for slave/peripheral dma access.
>> +
>> +Required properties:
>> +- compatible: Should be "xlnx,zynqmp-dma-1.0"
>> +- #dma-cells: Should be <1>, a single cell holding a line request number
>> +- reg: Memory map for module access
>> +- interrupt-parent: Interrupt controller the interrupt is routed through
>> +- interrupts: Should contain DMA channel interrupt
>> +- xlnx,bus-width: AXI buswidth in bits. Should contain 128 or 64
>> +
>> +Optional properties:
>> +- xlnx,include-sg: Indicates the controller to operate in simple or scatter
>> +                  gather dma mode
>> +- xlnx,ratectrl: Scheduling interval in terms of clock cycles for
>> +                source AXI transaction
>> +- xlnx,overfetch: Tells whether the channel is allowed to over fetch the data
>> +- xlnx,src-issue: Number of AXI outstanding transactions on source side
>> +- xlnx,desc-axi-cohrnt: Tells whether the AXI transactions generated for the
>> +                       descriptor read are marked Non-coherent
>> +- xlnx,src-axi-cohrnt: Tells whether the AXI transactions generated for the
>> +                       source descriptor payload are marked Non-coherent
>> +- xlnx,dst-axi-cohrnt: Tells whether the AXI transactions generated for the
>> +                       dst descriptor payload are marked Non-coherent
>
> Do you really need 3? dma-coherent property doesn't work for you?
>
> Not that it should dictate the binding, but the kernel doesn't support
> a device needing both coherent and non-coherent DMA ops.

I will get back to you shortly on this

>
>> +- xlnx,desc-axi-qos: AXI QOS bits to be used for descriptor fetch
>> +- xlnx,src-axi-qos: AXI QOS bits to be used for data read
>> +- xlnx,dst-axi-qos: AXI QOS bits to be used for data write
>> +- xlnx,desc-axi-cache: AXI cache bits to be used for descriptor fetch.
>> +- xlnx,desc-axi-cache: AXI cache bits to be used for data read
>> +- xlnx,desc-axi-cache: AXI cache bits to be used for data write
>
> These signals are generally part of the coherent or not setting. This
> allows for potentially invalid combinations.
>
> Plus you have a copy/paste error.

I will fix this.

Thanks,
Punnaiah
>
>> +- xlnx,src-burst-len: AXI length for data read. Support only power of 2 values
>> +                     i.e 1,2,4,8 and 16
>> +- xlnx,dst-burst-len: AXI length for data write. Support only power of 2 values
>> +                     i.e 1,2,4,8 and 16
>> +
>> +Example:
>> +++++++++
>> +fpd_dma_chan1: dma at FD500000 {
>> +       compatible = "xlnx,zynqmp-dma-1.0";
>> +       reg = <0x0 0xFD500000 0x1000>;
>> +       #dma_cells = <1>;
>> +       interrupt-parent = <&gic>;
>> +       interrupts = <0 117 4>;
>> +       xlnx,bus-width = <128>;
>> +       xlnx,include-sg;
>> +       xlnx,overfetch;
>> +       xlnx,ratectrl = <0>;
>> +       xlnx,src-issue = <16>;
>> +       xlnx,desc-axi-cohrnt;
>> +       xlnx,src-axi-cohrnt;
>> +       xlnx,dst-axi-cohrnt;
>> +       xlnx,desc-axi-qos = <0>;
>> +       xlnx,desc-axi-cache = <0>;
>> +       xlnx,src-axi-qos = <0>;
>> +       xlnx,src-axi-cache = <2>;
>> +       xlnx,dst-axi-qos = <0>;
>> +       xlnx,dst-axi-cache = <2>;
>> +       xlnx,src-burst-len = <4>;
>> +       xlnx,dst-burst-len = <4>;
>> +};
>> --
>> 1.7.4
>>
>>
>> _______________________________________________
>> linux-arm-kernel mailing list
>> linux-arm-kernel at lists.infradead.org
>> http://lists.infradead.org/mailman/listinfo/linux-arm-kernel


From broonie at kernel.org  Mon Aug 24 23:52:22 2015
From: broonie at kernel.org (Mark Brown)
Date: Tue, 25 Aug 2015 07:52:22 +0100
Subject: [PATCH v5 4/6] drm: bridge/dw_hdmi-i2s-audio: add audio driver
In-Reply-To: <20150808153540.GL7557@n2100.arm.linux.org.uk>
References: <1434730417-10629-1-git-send-email-ykk@rock-chips.com>
 <1434731295-11060-1-git-send-email-ykk@rock-chips.com>
 <20150808153540.GL7557@n2100.arm.linux.org.uk>
Message-ID: <20150825065222.GG27431@sirena.org.uk>

On Sat, Aug 08, 2015 at 04:35:41PM +0100, Russell King - ARM Linux wrote:
> On Sat, Jun 20, 2015 at 12:28:15AM +0800, Yakir Yang wrote:
> > Add ALSA based HDMI I2S audio driver for dw_hdmi. Sound card
> > driver could connect to this codec through the codec dai name
> > "dw-hdmi-i2s-audio".

> I'm applying this patch to my tree with some changes.  I haven't seen
> anyone ack it, nor review it any further.  I'm hoping someone can ack
> this patch with the following changes below - I'll be posting it as
> part of my dw-hdmi devel updates later today.

I'm pretty sure I deleted this patch unread because what shows up in my
inbox is:

->  197   C 08/08 Russell King -  (1.1K) ? ??>Re: [PATCH v5 4/6] drm: bridge/dw_

so there's no indication that it's anything to do with audio :(
-------------- next part --------------
A non-text attachment was scrubbed...
Name: signature.asc
Type: application/pgp-signature
Size: 473 bytes
Desc: Digital signature
URL: <http://lists.infradead.org/pipermail/linux-arm-kernel/attachments/20150825/9c435d3b/attachment.sig>

From heiko at sntech.de  Mon Aug 24 23:53:15 2015
From: heiko at sntech.de (Heiko Stuebner)
Date: Tue, 25 Aug 2015 08:53:15 +0200
Subject: [PATCH] clk: rockchip: register pll mux before pll itself
In-Reply-To: <20150824234319.GG14330@codeaurora.org>
References: <7060610.CC2Q1RMG2L@phil>
 <CAD=FV=UG_QkU0W5tpb3Y7zxuq6X7dtQmC4m5_j9vMtJgjdiquQ@mail.gmail.com>
 <20150824234319.GG14330@codeaurora.org>
Message-ID: <2414716.nTJ39zAhgn@phil>

Am Montag, 24. August 2015, 16:43:19 schrieb Stephen Boyd:
> On 08/24, Doug Anderson wrote:
> > Heiko
> > 
> > On Wed, Aug 19, 2015 at 6:06 AM, Heiko Stuebner <heiko at sntech.de> wrote:
> > > The structure is xin24m -> pll -> pll-mux (xin24m,pll,xin32k). The pll
> > > does have an init callback to make sure the boot-selected frequency is
> > > using the expected pll settings and resets the same frequency using
> > > the values provided in the driver if necessary.
> > > 
> > > The setting itself also involves remuxing the pll-mux temporarily to
> > > the xin24m source to let the new pll rate settle. Until now this worked
> > > flawlessly, even when it had the flaw of accessing the mux settings
> > > before the mux actually got registered.
> > > 
> > > With the recent clock-core conversions this flaw became apparent in
> > > null pointer dereference in
> > > [<c03fc400>] (clk_hw_get_num_parents) from [<c0400df0>]
> > > (clk_mux_get_parent+0x14/0xc8) [<c0400ddc>] (clk_mux_get_parent) from
> > > [<c040246c>] (rockchip_rk3066_pll_set_rate+0xd8/0x320)
> > > 
> > > So to fix that, simply register the pll-mux before the pll, so that
> > > it will be fully initialized when the pll clock executes its init-
> > > callback and possibly touches the pll-mux clock.
> > > 
> > > Signed-off-by: Heiko Stuebner <heiko at sntech.de>
> > > ---
> > > This only surfaced with the clk_core changes for 4.3, so should
> > > probably just go on top.
> > > 
> > >  drivers/clk/rockchip/clk-pll.c | 63
> > >  +++++++++++++++++++++--------------------- 1 file changed, 32
> > >  insertions(+), 31 deletions(-)
> > 
> > Fixes boot crash on rk3288-veyron-jerry on next-20150824.  It'd be
> > super great to get this landed somewhere so that we can boot linuxnext
> > again.  :)
> > 
> > Tested-by: Douglas Anderson <dianders at chromium.org>
> 
> So I understand the fix, but how could it have ever possibly
> worked flawlessly? clk_mux_get_parent() should have returned
> -EINVAL through that u8 which would have meant that the check in
> rockchip_rk3066_pll_set_rate() for cur_parent == PLL_MODE_NORM
> would never have been true, and we would never have switched the
> PLL mux over. I guess we've been getting away with this because
> we don't need to actually switch the mux at this time?

The manual mandates the switch away from the pll source before touching the 
pll settings, aka to the slow mode from the 24MHz source. I guess we were 
lucky it simply still worked nevertheless.

In normal rate changes both clocks will have been registered already, so only 
the init callback is affected and also only runs on plls that generate the rate 
from a different settings-touple that what we have in the rate-table, so not 
even all plls normally.


From wxt at rock-chips.com  Tue Aug 25 00:24:42 2015
From: wxt at rock-chips.com (Caesar Wang)
Date: Tue, 25 Aug 2015 15:24:42 +0800
Subject: [RESEND PATCH v16 0/4] ARM: rk3288: Add PM Domain support
Message-ID: <1440487486-6154-1-git-send-email-wxt@rock-chips.com>

Add power domain drivers based on generic power domain for
Rockchip platform, and support RK3288 SoCs.

Verified on url =
    https://chromium.googlesource.com/chromiumos/third_party/kernel/+/v3.14
    localhost / # cat /sys/kernel/debug/pm_genpd/pm_genpd_summary
    domain                      status         slaves
    /device                      runtime        status
    ----------------------------------------------------------------------
    pd_video                        off
    /devices/ff9a0800.iommu                     suspended
    /devices/ff9a0000.video-codec               suspended
    pd_vio                          on
    /devices/ff930300.iommu                     suspended
    /devices/ff940300.iommu                     suspended
    /devices/ff930000.vop                       suspended
    /devices/ff940000.vop                       suspended
    /devices/ff980000.hdmi                      unsupported
    /devices/rockchip-edp                       unsupported
    pd_hevc                         off
    pd_gpu                          off
    /devices/ffa30000.gpu                       suspended

    The following is the easy example.

    vopb: vop at ff930000 {
        compatible = "rockchip,rk3288-vop";
        ...
        iommus = <&vopb_mmu>;
        power-domains = <&power RK3288_PD_VIO>;
        status = "disabled";
        ...
    };

    vopb_mmu: iommu at ff930300 {
        compatible = "rockchip,iommu";
        ...
        interrupt-names = "vopb_mmu";
        power-domains = <&power RK3288_PD_VIO>;
        #iommu-cells = <0>;
        status = "disabled";
        ...
    };

    vopl: vop at ff940000 {
        compatible = "rockchip,rk3288-vop";
        reg = <0xff940000 0x19c>;
        ...
        iommus = <&vopl_mmu>;
        power-domains = <&power RK3288_PD_VIO>;
        status = "disabled";
        ...
    };

    vopl_mmu: iommu at ff940300 {
        compatible = "rockchip,iommu";
        ...
        interrupt-names = "vopl_mmu";
        power-domains = <&power RK3288_PD_VIO>;
        #iommu-cells = <0>;
        status = "disabled";
    };

    Others, we can verify this driver for the EDP.
    We can apply the following these patchs.

    6967631 New          [v2,1/8] drm: exynos/dp: fix code style
    6967741 New          [v2,2/8] drm: exynos/dp: convert to drm bridge mode
    6967801 New          [v2,3/8] drm: bridge: analogix_dp: split exynos dp driver to bridge dir
    6967791 New          [v2,4/8] drm: rockchip/dp: add rockchip platform dp driver
    6968031 New          [v2,5/8] drm: bridge/analogix_dp: add platform device type support
    6968141 New          [v2,6/8] drm: bridge: analogix_dp: add some rk3288 special registers setting
    6967941 New          [v2,7/8] drm: bridge: analogix_dp: try force hpd after plug in lookup failed
    6967971 New          [v2,8/8] drm: bridge/analogix_dp: expand the delay time for hpd detect

    There is a recent addition from Linus Walleij,
    called simple-mfd [a] that is supposed to get added real early for kernel 4.2

    [a]:
    https://git.kernel.org/cgit/linux/kernel/git/linusw/linux-integrator.git/commit/?id=fcf294c020ff7ee4e3b1e96159e4dc7a17ad5

    Here is my branch, Tested by chromeos-3.14 and next-kernel.

    2b82899 ARM: dts: add RK3288 power-domain node
    69d0b5b soc: rockchip: power-domain: support power domain driver for RK3288 SoCs
    66f8758 ARM: power-domain: rockchip: add all the domain type on RK3288 SoCs
    c5f12a3 dt-bindings: add document of Rockchip power domain
    7a834ba Merge branch 'for-linus' of git://git.kernel.org/pub/scm/linux/kernel/git/jikos/hid
    0be0171 HID: wacom: Report correct device resolution when using the wireless adapater
    2b9bea0 Merge tag 'mfd-fixes-4.2' of git://git.kernel.org/pub/scm/linux/kernel/git/lee/mfd
    016a9f5 Merge tag 'ntb-4.2-rc7' of git://github.com/jonmason/ntb
    a3ca013 Merge branch 'for-linus' of
    git://git.kernel.org/pub/scm/linux/kernel/git/viro/vfs
    ......


Changes in v16:
- remove the pmu node.
- Add more domain decription.
- the driver type from tristate to bool.
- Letter misspelled.
- As Ulf suggestion, remove #include <linux/clk-provider.h>,
  use "%pC" as the formatting string for the dev_dbg().
- As the Ulf suggestion, set the genpd->flags to assign the
  ->stop|start() callbacks.
- Manually copy the problem in patch v15.
- rebase the description.

Changes in v15:
- change the comment.
- As the kevin suggestion, put the power-domain driver into driver/soc/vendor.
- As Heiko suggestion, Patch 1: binding doc, 2: binding-header, 3: driver,
  4: dts-changes.
- return -ENXIO --> return -ENODEV.
- As Tomasz remarked previously the dts should represent the hardware
  and the power-domains are part of the pmu.

Changes in v14:
- does not need to set an owner,remove the "THIS_MODULE".
- Remove essential clocks from rk3288 PD_VIO domain, Some clocks are
  essential for the system health and should not be turned down.
  However there is no owner for them so if they listed as belonging to power
  domain we'll try toggling them up and down during power domain transition.
  As a result we either fail to suspend or resume the system.

Changes in v13:
- Remove essential clocks from rk3288 PD_VIO domain Some clocks are essential
  for the system health and should not be turned down. However there is no owner
  for them so if they listed as belonging to power domain we'll try toggling them
  up and down during power domain.
- Device drivers expect their devices to be powered on before their
  probing code is invoked. To achieve that we should start with
  power domains powered on (we may turn them off later once all devices enable
  runtime powermanagment and go idle).
- This change switches Rockchip power domain driver to use updated
  device_attach and device_detach API.
- set the gpu/core power domain power delay time.
- fix enumerating PM clocks for devices.
- fix use after free We can't use clk after we did clk_put(clk).

Changes in v12:
- fix the title doamin->domain.
- updated device_attach and device_detach API,otherwise it will
  compile fail on next kernel.

Changes in v11:
- fix pm_genpd_init(&pd->genpd, NULL, false).

Changes in v10:
- this switches over domain infos to use masks instead of recomputing
  them each time and also gets rid of custom domain translator and
  uses standard onecell on.
- fix missing the #include <dt-bindings/power-domain/rk3288.h>.
- remove the notes.

Changes in v9:
- add document decription.
- fix v8 changes as follows:
- This reconciles the v2 and v7 code so that we power domain have lists of clocks
  they trigger on and off during power transitions and independently from power
  domains clocks. We attach clocks to devices comprising power domain and prepare
  them so they are turn on and off by runtime PM.
- add rockchip_pm_add_one_domain() to control domains.
- add pd_start/pd_stop interface to control clocks.
- add decription for power-doamin node.

Changes in v8:
- document go back to v2.
- This reconciles the v2 and v7 code so that we power domain have
  lists of clocks they toggle on and off during power transitions
  and independently from power domains clocks we attach clocks to
  devices comprising power domain and prepare them so they are
  turn on and off by runtime PM.
- DTS go back to v2.

Changes in v7:
 - Delete unused variables

Changes in v6:
- delete pmu_lock.
- modify dev_lock using mutex.
- pm_clk_resume(pd->dev) change to pm_clk_resume(ed->dev).
- pm_clk_suspend(pd->dev) change to pm_clk_suspend(ed->dev).
- add devm_kfree(pd->dev, de) in rockchip_pm_domain_detach_dev.

Changes in v5:
- delete idle_lock.
- add timeout in rockchip_pmu_set_idle_request().

Changes in v4:
- use list storage dev.

Changes in v3:
- DT structure has changed.
- change use pm_clk_resume() and pm_clk_suspend().
- Decomposition power-controller, changed to multiple controller
  (gpu-power-controller, hevc-power-controller).

Changes in v2:
- move clocks to "optional".
- remove the "pd->pd.of_node = np".
- make pd_vio clocks all one entry per line and alphabetize.
- power: power-controller move back to pinctrl: pinctrl.

Caesar Wang (4):
  dt-bindings: add document of Rockchip power domain
  ARM: power-domain: rockchip: add all the domain type on RK3288 SoCs
  soc: rockchip: power-domain: Add power domain driver
  ARM: dts: add the support power-domain node on RK3288 SoCs

 .../bindings/soc/rockchip/power_domain.txt         |  46 ++
 arch/arm/boot/dts/rk3288.dtsi                      |  60 ++-
 drivers/soc/Kconfig                                |   1 +
 drivers/soc/Makefile                               |   1 +
 drivers/soc/rockchip/Kconfig                       |  13 +
 drivers/soc/rockchip/Makefile                      |   4 +
 drivers/soc/rockchip/pm_domains.c                  | 485 +++++++++++++++++++++
 include/dt-bindings/power-domain/rk3288.h          |  31 ++
 8 files changed, 640 insertions(+), 1 deletion(-)
 create mode 100644 Documentation/devicetree/bindings/soc/rockchip/power_domain.txt
 create mode 100644 drivers/soc/rockchip/Kconfig
 create mode 100644 drivers/soc/rockchip/Makefile
 create mode 100644 drivers/soc/rockchip/pm_domains.c
 create mode 100644 include/dt-bindings/power-domain/rk3288.h

-- 
1.9.1



From wxt at rock-chips.com  Tue Aug 25 00:24:43 2015
From: wxt at rock-chips.com (Caesar Wang)
Date: Tue, 25 Aug 2015 15:24:43 +0800
Subject: [RESEND PATCH v16 1/4] dt-bindings: add document of Rockchip power
 domain
In-Reply-To: <1440487486-6154-1-git-send-email-wxt@rock-chips.com>
References: <1440487486-6154-1-git-send-email-wxt@rock-chips.com>
Message-ID: <1440487486-6154-2-git-send-email-wxt@rock-chips.com>

This add the necessary binding documentation for the power domain
found on Rockchip Socs.

Signed-off-by: jinkun.hong <jinkun.hong at rock-chips.com>
Signed-off-by: Caesar Wang <wxt at rock-chips.com>

---

Changes in v16:
- remove the pmu node.

Changes in v15: None
Changes in v14: None
Changes in v13: None
Changes in v12: None
Changes in v11: None
Changes in v10: None
Changes in v9:
- add document decription.

Changes in v8:
- document go back to v2.

Changes in v7: None
Changes in v6: None
Changes in v5: None
Changes in v4: None
Changes in v3:
- DT structure has changed.

Changes in v2:
- move clocks to "optional".

 .../bindings/soc/rockchip/power_domain.txt         | 46 ++++++++++++++++++++++
 1 file changed, 46 insertions(+)
 create mode 100644 Documentation/devicetree/bindings/soc/rockchip/power_domain.txt

diff --git a/Documentation/devicetree/bindings/soc/rockchip/power_domain.txt b/Documentation/devicetree/bindings/soc/rockchip/power_domain.txt
new file mode 100644
index 0000000..138754d
--- /dev/null
+++ b/Documentation/devicetree/bindings/soc/rockchip/power_domain.txt
@@ -0,0 +1,46 @@
+* Rockchip Power Domains
+
+Rockchip processors include support for multiple power domains which can be
+powered up/down by software based on different application scenes to save power.
+
+Required properties for power domain controller:
+- compatible: Should be one of the following.
+	"rockchip,rk3288-power-controller" - for RK3288 SoCs.
+- #power-domain-cells: Number of cells in a power-domain specifier.
+	Should be 1 for multiple PM domains.
+- #address-cells: Should be 1.
+- #size-cells: Should be 0.
+
+Required properties for power domain sub nodes:
+- reg: index of the power domain, should use macros in:
+	"include/dt-bindings/power-domain/rk3288.h" - for rk3288 type power domain.
+- clocks (optional): phandles to clocks which need to be enabled while power domain
+	switches state.
+
+Example:
+
+	power: power-controller {
+		compatible = "rockchip,rk3288-power-controller";
+		#power-domain-cells = <1>;
+		#address-cells = <1>;
+		#size-cells = <0>;
+
+		pd_gpu {
+			reg = <RK3288_PD_GPU>;
+			clocks = <&cru ACLK_GPU>;
+		};
+	};
+
+Node of a device using power domains must have a power-domains property,
+containing a phandle to the power device node and an index specifying which
+power domain to use.
+The index should use macros in:
+	"include/dt-bindings/power-domain/rk3288.h" - for rk3288 type power domain.
+
+Example of the node using power domain:
+
+	node {
+		/* ... */
+		power-domains = <&power RK3288_PD_GPU>;
+		/* ... */
+	};
-- 
1.9.1



From wxt at rock-chips.com  Tue Aug 25 00:24:44 2015
From: wxt at rock-chips.com (Caesar Wang)
Date: Tue, 25 Aug 2015 15:24:44 +0800
Subject: [RESEND PATCH v16 2/4] ARM: power-domain: rockchip: add all the
 domain type on RK3288 SoCs
In-Reply-To: <1440487486-6154-1-git-send-email-wxt@rock-chips.com>
References: <1440487486-6154-1-git-send-email-wxt@rock-chips.com>
Message-ID: <1440487486-6154-3-git-send-email-wxt@rock-chips.com>

According to a description from TRM, the following table lists
all the power domains.

------------------------   -------------------------
|VD_CORE               |   |VD_LOGIC    |  PD_VIO  |
|xxxxxxxxxxxxxxxxxxxx  |   |xxxxxxxx    -----------|
|xxxxxxxxxxxxxxxxxxxx  |   |xxxxxxxx               |
|xxxxxxxxxxxxxxxxxxxx  |   |                       |
|xxxxxxxxxxxxxxxxxxxx  |   |---------   -----------|
|                      |   |PD_PERI  |  | PD_VIDEO |
|                      |   |---------   -----------|
|                      |   |---------   -----------|
|                      |   |PD_ALIVE |  | PD_HEVC  |
|---------- ---------- |   |---------   -----------|
||PD_A17_1| |PD_A17_2| |   -------------------------
|---------- ---------- |   |VD_GPU      |PD_GPU    |
|---------- ---------- |   -------------------------
||PD_A17_3| |PD_DEBUG| |   -------------------------
|---------- ---------- |   |VD_PMU      |PD_PMU    |
------------------------   -------------------------

VD_* :  voltage domain
PD_* :  power domain

At the moment, we can support some power-domain type on RK3288.
We can add more types on RK3288 in the future, that's need to do.

Signed-off-by: Caesar Wang <wxt at rock-chips.com>

---

Changes in v16:
- Add more domain decription.

Changes in v15:
- change the comment.

Changes in v14: None
Changes in v13: None
Changes in v12: None
Changes in v11: None
Changes in v10: None
Changes in v9: None
Changes in v8: None
Changes in v7: None
Changes in v6: None
Changes in v5: None
Changes in v4: None
Changes in v3: None
Changes in v2: None

 include/dt-bindings/power-domain/rk3288.h | 31 +++++++++++++++++++++++++++++++
 1 file changed, 31 insertions(+)
 create mode 100644 include/dt-bindings/power-domain/rk3288.h

diff --git a/include/dt-bindings/power-domain/rk3288.h b/include/dt-bindings/power-domain/rk3288.h
new file mode 100644
index 0000000..db5e810
--- /dev/null
+++ b/include/dt-bindings/power-domain/rk3288.h
@@ -0,0 +1,31 @@
+#ifndef __DT_BINDINGS_POWER_DOMAIN_RK3288_H__
+#define __DT_BINDINGS_POWER_DOMAIN_RK3288_H__
+
+/**
+ * RK3288 Power Domain and Voltage Domain Summary.
+ */
+
+/* VD_CORE */
+#define RK3288_PD_A17_0		0
+#define RK3288_PD_A17_1		1
+#define RK3288_PD_A17_2		2
+#define RK3288_PD_A17_3		3
+#define RK3288_PD_SCU		4
+#define RK3288_PD_DEBUG		5
+#define RK3288_PD_MEM		6
+
+/* VD_LOGIC */
+#define RK3288_PD_BUS		7
+#define RK3288_PD_PERI		8
+#define RK3288_PD_VIO		9
+#define RK3288_PD_ALIVE		10
+#define RK3288_PD_HEVC		11
+#define RK3288_PD_VIDEO		12
+
+/* VD_GPU */
+#define RK3288_PD_GPU		13
+
+/* VD_PMU */
+#define RK3288_PD_PMU		14
+
+#endif
-- 
1.9.1



From wxt at rock-chips.com  Tue Aug 25 00:24:45 2015
From: wxt at rock-chips.com (Caesar Wang)
Date: Tue, 25 Aug 2015 15:24:45 +0800
Subject: [RESEND PATCH v16 3/4] soc: rockchip: power-domain: Add power domain
 driver
In-Reply-To: <1440487486-6154-1-git-send-email-wxt@rock-chips.com>
References: <1440487486-6154-1-git-send-email-wxt@rock-chips.com>
Message-ID: <1440487486-6154-4-git-send-email-wxt@rock-chips.com>

This driver is found on RK3288 SoCs.

In order to meet high performance and low power requirements, a power
management unit is designed or saving power when RK3288 in low power
mode.
The RK3288 PMU is dedicated for managing the power of the whole chip.

PMU can work in the Low Power Mode by setting bit[0] of PMU_PWRMODE_CON
register. After setting the register, PMU would enter the Low Power mode.
In the low power mode, pmu will auto power on/off the specified power
domain, send idle req to specified power domain, shut down/up pll and
so on. All of above are configurable by setting corresponding registers.

Signed-off-by: jinkun.hong <jinkun.hong at rock-chips.com>
Signed-off-by: Caesar Wang <wxt at rock-chips.com>

---

Changes in v16:
- the driver type from tristate to bool.
- Letter misspelled.
- As Ulf suggestion, remove #include <linux/clk-provider.h>,
  use "%pC" as the formatting string for the dev_dbg().
- As the Ulf suggestion, set the genpd->flags to assign the
  ->stop|start() callbacks.

Changes in v15:
- As the kevin suggestion, put the power-domain driver into driver/soc/vendor.
- As Heiko suggestion, Patch 1: binding doc, 2: binding-header, 3: driver,
  4: dts-changes.
- return -ENXIO --> return -ENODEV.

Changes in v14:
- does not need to set an owner,remove the "THIS_MODULE".

Changes in v13:
- Remove essential clocks from rk3288 PD_VIO domain Some clocks are essential
  for the system health and should not be turned down. However there is no owner
  for them so if they listed as belonging to power domain we'll try toggling them
  up and down during power domain.
- Device drivers expect their devices to be powered on before their
  probing code is invoked. To achieve that we should start with
  power domains powered on (we may turn them off later once all devices enable
  runtime powermanagment and go idle).
- This change switches Rockchip power domain driver to use updated
  device_attach and device_detach API.
- set the gpu/core power domain power delay time.
- fix enumerating PM clocks for devices.
- fix use after free We can't use clk after we did clk_put(clk).

Changes in v12:
- fix the title doamin->domain.
- updated device_attach and device_detach API,otherwise it will
  compile fail on next kernel.

Changes in v11:
- fix pm_genpd_init(&pd->genpd, NULL, false).

Changes in v10:
- this switches over domain infos to use masks instead of recomputing
  them each time and also gets rid of custom domain translator and
  uses standard onecell on.

Changes in v9:
- fix v8 changes as follows:
- This reconciles the v2 and v7 code so that we power domain have lists of clocks
  they trigger on and off during power transitions and independently from power
  domains clocks. We attach clocks to devices comprising power domain and prepare
  them so they are turn on and off by runtime PM.
- add rockchip_pm_add_one_domain() to control domains.
- add pd_start/pd_stop interface to control clocks.

Changes in v8:
- This reconciles the v2 and v7 code so that we power domain have
  lists of clocks they toggle on and off during power transitions
  and independently from power domains clocks we attach clocks to
  devices comprising power domain and prepare them so they are
  turn on and off by runtime PM.

Changes in v7:
 - Delete unused variables

Changes in v6:
- delete pmu_lock.
- modify dev_lock using mutex.
- pm_clk_resume(pd->dev) change to pm_clk_resume(ed->dev).
- pm_clk_suspend(pd->dev) change to pm_clk_suspend(ed->dev).
- add devm_kfree(pd->dev, de) in rockchip_pm_domain_detach_dev.

Changes in v5:
- delete idle_lock.
- add timeout in rockchip_pmu_set_idle_request().

Changes in v4:
- use list storage dev.

Changes in v3:
- change use pm_clk_resume() and pm_clk_suspend().

Changes in v2:
- remove the "pd->pd.of_node = np".

 drivers/soc/Kconfig               |   1 +
 drivers/soc/Makefile              |   1 +
 drivers/soc/rockchip/Kconfig      |  13 +
 drivers/soc/rockchip/Makefile     |   4 +
 drivers/soc/rockchip/pm_domains.c | 485 ++++++++++++++++++++++++++++++++++++++
 5 files changed, 504 insertions(+)
 create mode 100644 drivers/soc/rockchip/Kconfig
 create mode 100644 drivers/soc/rockchip/Makefile
 create mode 100644 drivers/soc/rockchip/pm_domains.c

diff --git a/drivers/soc/Kconfig b/drivers/soc/Kconfig
index 96ddecb..ecb1a6c 100644
--- a/drivers/soc/Kconfig
+++ b/drivers/soc/Kconfig
@@ -2,6 +2,7 @@ menu "SOC (System On Chip) specific Drivers"
 
 source "drivers/soc/mediatek/Kconfig"
 source "drivers/soc/qcom/Kconfig"
+source "drivers/soc/rockchip/Kconfig"
 source "drivers/soc/sunxi/Kconfig"
 source "drivers/soc/ti/Kconfig"
 source "drivers/soc/versatile/Kconfig"
diff --git a/drivers/soc/Makefile b/drivers/soc/Makefile
index 7dc7c0d..ff8bbfb 100644
--- a/drivers/soc/Makefile
+++ b/drivers/soc/Makefile
@@ -4,6 +4,7 @@
 
 obj-$(CONFIG_ARCH_MEDIATEK)	+= mediatek/
 obj-$(CONFIG_ARCH_QCOM)		+= qcom/
+obj-$(CONFIG_ARCH_ROCKCHIP)		+= rockchip/
 obj-$(CONFIG_ARCH_SUNXI)	+= sunxi/
 obj-$(CONFIG_ARCH_TEGRA)	+= tegra/
 obj-$(CONFIG_SOC_TI)		+= ti/
diff --git a/drivers/soc/rockchip/Kconfig b/drivers/soc/rockchip/Kconfig
new file mode 100644
index 0000000..87a09c3
--- /dev/null
+++ b/drivers/soc/rockchip/Kconfig
@@ -0,0 +1,13 @@
+#
+# Rockchip Soc drivers
+#
+config PM_GENERIC_DOMAINS
+        bool "Rockchip generic power domain"
+        depends on PM
+        help
+          Say y here to enable power domain support.
+          In order to meet high performance and low power requirements, a power
+          management unit is designed or saving power when RK3288 in low power
+          mode. The RK3288 PMU is dedicated for managing the power of the whole chip.
+
+          If unsure, say N.
diff --git a/drivers/soc/rockchip/Makefile b/drivers/soc/rockchip/Makefile
new file mode 100644
index 0000000..1c0fd91
--- /dev/null
+++ b/drivers/soc/rockchip/Makefile
@@ -0,0 +1,4 @@
+#
+# Rockchip Soc drivers
+#
+obj-$(CONFIG_PM_GENERIC_DOMAINS) += pm_domains.o
diff --git a/drivers/soc/rockchip/pm_domains.c b/drivers/soc/rockchip/pm_domains.c
new file mode 100644
index 0000000..fd772d2
--- /dev/null
+++ b/drivers/soc/rockchip/pm_domains.c
@@ -0,0 +1,485 @@
+/*
+ * Rockchip Generic power domain support.
+ *
+ * Copyright (c) 2015 ROCKCHIP, Co. Ltd.
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License version 2 as
+ * published by the Free Software Foundation.
+ */
+
+#include <linux/io.h>
+#include <linux/err.h>
+#include <linux/pm_clock.h>
+#include <linux/pm_domain.h>
+#include <linux/of_address.h>
+#include <linux/of_platform.h>
+#include <linux/clk.h>
+#include <linux/regmap.h>
+#include <linux/mfd/syscon.h>
+#include <dt-bindings/power-domain/rk3288.h>
+
+struct rockchip_domain_info {
+	int pwr_mask;
+	int status_mask;
+	int req_mask;
+	int idle_mask;
+	int ack_mask;
+};
+
+struct rockchip_pmu_info {
+	u32 pwr_offset;
+	u32 status_offset;
+	u32 req_offset;
+	u32 idle_offset;
+	u32 ack_offset;
+
+	u32 core_pwrcnt_offset;
+	u32 gpu_pwrcnt_offset;
+
+	unsigned int core_power_transition_time;
+	unsigned int gpu_power_transition_time;
+
+	int num_domains;
+	const struct rockchip_domain_info *domain_info;
+};
+
+struct rockchip_pm_domain {
+	struct generic_pm_domain genpd;
+	const struct rockchip_domain_info *info;
+	struct rockchip_pmu *pmu;
+	int num_clks;
+	struct clk *clks[];
+};
+
+struct rockchip_pmu {
+	struct device *dev;
+	struct regmap *regmap;
+	const struct rockchip_pmu_info *info;
+	struct mutex mutex; /* mutex lock for pmu */
+	struct genpd_onecell_data genpd_data;
+	struct generic_pm_domain *domains[];
+};
+
+#define to_rockchip_pd(gpd) container_of(gpd, struct rockchip_pm_domain, genpd)
+
+#define DOMAIN(pwr, status, req, idle, ack)	\
+{						\
+	.pwr_mask = BIT(pwr),			\
+	.status_mask = BIT(status),		\
+	.req_mask = BIT(req),			\
+	.idle_mask = BIT(idle),			\
+	.ack_mask = BIT(ack),			\
+}
+
+#define DOMAIN_RK3288(pwr, status, req)		\
+	DOMAIN(pwr, status, req, req, (req) + 16)
+
+static bool rockchip_pmu_domain_is_idle(struct rockchip_pm_domain *pd)
+{
+	struct rockchip_pmu *pmu = pd->pmu;
+	const struct rockchip_domain_info *pd_info = pd->info;
+	unsigned int val;
+
+	regmap_read(pmu->regmap, pmu->info->idle_offset, &val);
+	return (val & pd_info->idle_mask) == pd_info->idle_mask;
+}
+
+static int rockchip_pmu_set_idle_request(struct rockchip_pm_domain *pd,
+					 bool idle)
+{
+	const struct rockchip_domain_info *pd_info = pd->info;
+	struct rockchip_pmu *pmu = pd->pmu;
+	unsigned int val;
+
+	regmap_update_bits(pmu->regmap, pmu->info->req_offset,
+			   pd_info->req_mask, idle ? -1U : 0);
+
+	dsb();
+
+	do {
+		regmap_read(pmu->regmap, pmu->info->ack_offset, &val);
+	} while ((val & pd_info->ack_mask) != (idle ? pd_info->ack_mask : 0));
+
+	while (rockchip_pmu_domain_is_idle(pd) != idle)
+		cpu_relax();
+
+	return 0;
+}
+
+static bool rockchip_pmu_domain_is_on(struct rockchip_pm_domain *pd)
+{
+	struct rockchip_pmu *pmu = pd->pmu;
+	unsigned int val;
+
+	regmap_read(pmu->regmap, pmu->info->status_offset, &val);
+
+	/* 1'b0: power on, 1'b1: power off */
+	return !(val & pd->info->status_mask);
+}
+
+static void rockchip_do_pmu_set_power_domain(struct rockchip_pm_domain *pd,
+					     bool on)
+{
+	struct rockchip_pmu *pmu = pd->pmu;
+
+	regmap_update_bits(pmu->regmap, pmu->info->pwr_offset,
+			   pd->info->pwr_mask, on ? 0 : -1U);
+
+	dsb();
+
+	while (rockchip_pmu_domain_is_on(pd) != on)
+		cpu_relax();
+}
+
+static int rockchip_pd_power(struct rockchip_pm_domain *pd, bool power_on)
+{
+	int i;
+
+	mutex_lock(&pd->pmu->mutex);
+
+	if (rockchip_pmu_domain_is_on(pd) != power_on) {
+		for (i = 0; i < pd->num_clks; i++)
+			clk_enable(pd->clks[i]);
+
+		if (!power_on) {
+			/* FIXME: add code to save AXI_QOS */
+
+			/* if powering down, idle request to NIU first */
+			rockchip_pmu_set_idle_request(pd, true);
+		}
+
+		rockchip_do_pmu_set_power_domain(pd, power_on);
+
+		if (power_on) {
+			/* if powering up, leave idle mode */
+			rockchip_pmu_set_idle_request(pd, false);
+
+			/* FIXME: add code to restore AXI_QOS */
+		}
+
+		for (i = pd->num_clks - 1; i >= 0; i--)
+			clk_disable(pd->clks[i]);
+	}
+
+	mutex_unlock(&pd->pmu->mutex);
+	return 0;
+}
+
+static int rockchip_pd_power_on(struct generic_pm_domain *domain)
+{
+	struct rockchip_pm_domain *pd = to_rockchip_pd(domain);
+
+	return rockchip_pd_power(pd, true);
+}
+
+static int rockchip_pd_power_off(struct generic_pm_domain *domain)
+{
+	struct rockchip_pm_domain *pd = to_rockchip_pd(domain);
+
+	return rockchip_pd_power(pd, false);
+}
+
+static int rockchip_pd_attach_dev(struct generic_pm_domain *genpd,
+				  struct device *dev)
+{
+	struct clk *clk;
+	int i;
+	int error;
+
+	dev_dbg(dev, "attaching to power domain '%s'\n", genpd->name);
+
+	error = pm_clk_create(dev);
+	if (error) {
+		dev_err(dev, "pm_clk_create failed %d\n", error);
+		return error;
+	}
+
+	i = 0;
+	while ((clk = of_clk_get(dev->of_node, i++)) && !IS_ERR(clk)) {
+		dev_dbg(dev, "adding clock '%pC' to list of PM clocks\n", clk);
+		error = pm_clk_add_clk(dev, clk);
+		clk_put(clk);
+		if (error) {
+			dev_err(dev, "pm_clk_add_clk failed %d\n", error);
+			pm_clk_destroy(dev);
+			return error;
+		}
+	}
+
+	return 0;
+}
+
+static void rockchip_pd_detach_dev(struct generic_pm_domain *genpd,
+				   struct device *dev)
+{
+	dev_dbg(dev, "detaching from power domain '%s'\n", genpd->name);
+
+	pm_clk_destroy(dev);
+}
+
+static int rockchip_pm_add_one_domain(struct rockchip_pmu *pmu,
+				      struct device_node *node)
+{
+	const struct rockchip_domain_info *pd_info;
+	struct rockchip_pm_domain *pd;
+	struct clk *clk;
+	int clk_cnt;
+	int i;
+	u32 id;
+	int error;
+
+	error = of_property_read_u32(node, "reg", &id);
+	if (error) {
+		dev_err(pmu->dev,
+			"%s: failed to retrieve domain id (reg): %d\n",
+			node->name, error);
+		return -EINVAL;
+	}
+
+	if (id >= pmu->info->num_domains) {
+		dev_err(pmu->dev, "%s: invalid domain id %d\n",
+			node->name, id);
+		return -EINVAL;
+	}
+
+	pd_info = &pmu->info->domain_info[id];
+	if (!pd_info) {
+		dev_err(pmu->dev, "%s: undefined domain id %d\n",
+			node->name, id);
+		return -EINVAL;
+	}
+
+	clk_cnt = of_count_phandle_with_args(node, "clocks", "#clock-cells");
+	pd = devm_kzalloc(pmu->dev,
+			  sizeof(*pd) + clk_cnt * sizeof(pd->clks[0]),
+			  GFP_KERNEL);
+	if (!pd)
+		return -ENOMEM;
+
+	pd->info = pd_info;
+	pd->pmu = pmu;
+
+	for (i = 0; i < clk_cnt; i++) {
+		clk = of_clk_get(node, i);
+		if (IS_ERR(clk)) {
+			error = PTR_ERR(clk);
+			dev_err(pmu->dev,
+				"%s: failed to get clk %pC (index %d): %d\n",
+				node->name, clk, i, error);
+			goto err_out;
+		}
+
+		error = clk_prepare(clk);
+		if (error) {
+			dev_err(pmu->dev,
+				"%s: failed to prepare clk %pC (index %d): %d\n",
+				node->name, clk, i, error);
+			clk_put(clk);
+			goto err_out;
+		}
+
+		pd->clks[pd->num_clks++] = clk;
+
+		dev_dbg(pmu->dev, "added clock '%pC' to domain '%s'\n",
+			clk, node->name);
+	}
+
+	error = rockchip_pd_power(pd, true);
+	if (error) {
+		dev_err(pmu->dev,
+			"failed to power on domain '%s': %d\n",
+			node->name, error);
+		goto err_out;
+	}
+
+	pd->genpd.name = node->name;
+	pd->genpd.power_off = rockchip_pd_power_off;
+	pd->genpd.power_on = rockchip_pd_power_on;
+	pd->genpd.attach_dev = rockchip_pd_attach_dev;
+	pd->genpd.detach_dev = rockchip_pd_detach_dev;
+	pd->genpd.flags = GENPD_FLAG_PM_CLK;
+	pm_genpd_init(&pd->genpd, NULL, false);
+
+	pmu->genpd_data.domains[id] = &pd->genpd;
+	return 0;
+
+err_out:
+	while (--i >= 0) {
+		clk_unprepare(pd->clks[i]);
+		clk_put(pd->clks[i]);
+	}
+	return error;
+}
+
+static void rockchip_pm_remove_one_domain(struct rockchip_pm_domain *pd)
+{
+	int i;
+
+	for (i = 0; i < pd->num_clks; i++) {
+		clk_unprepare(pd->clks[i]);
+		clk_put(pd->clks[i]);
+	}
+
+	/* devm will free our memory */
+}
+
+static void rockchip_pm_domain_cleanup(struct rockchip_pmu *pmu)
+{
+	struct generic_pm_domain *genpd;
+	struct rockchip_pm_domain *pd;
+	int i;
+
+	for (i = 0; i < pmu->genpd_data.num_domains; i++) {
+		genpd = pmu->genpd_data.domains[i];
+		if (genpd) {
+			pd = to_rockchip_pd(genpd);
+			rockchip_pm_remove_one_domain(pd);
+		}
+	}
+
+	/* devm will free our memory */
+}
+
+static void rockchip_configure_pd_cnt(struct rockchip_pmu *pmu,
+				      u32 domain_reg_offset,
+				      unsigned int count)
+{
+	/* First configure domain power down transition count ... */
+	regmap_write(pmu->regmap, domain_reg_offset, count);
+	/* ... and then power up count. */
+	regmap_write(pmu->regmap, domain_reg_offset + 4, count);
+}
+
+static int rockchip_pm_domain_probe(struct platform_device *pdev)
+{
+	struct device *dev = &pdev->dev;
+	struct device_node *np = dev->of_node;
+	struct device_node *node;
+	struct device *parent;
+	struct rockchip_pmu *pmu;
+	const struct of_device_id *match;
+	const struct rockchip_pmu_info *pmu_info;
+	int error;
+
+	if (!np) {
+		dev_err(dev, "device tree node not found\n");
+		return -ENODEV;
+	}
+
+	match = of_match_device(dev->driver->of_match_table, dev);
+	if (!match || !match->data) {
+		dev_err(dev, "missing pmu data\n");
+		return -EINVAL;
+	}
+
+	pmu_info = match->data;
+
+	pmu = devm_kzalloc(dev,
+			   sizeof(*pmu) +
+				pmu_info->num_domains * sizeof(pmu->domains[0]),
+			   GFP_KERNEL);
+	if (!pmu)
+		return -ENOMEM;
+
+	pmu->dev = &pdev->dev;
+	mutex_init(&pmu->mutex);
+
+	pmu->info = pmu_info;
+
+	pmu->genpd_data.domains = pmu->domains;
+	pmu->genpd_data.num_domains = pmu_info->num_domains;
+
+	parent = dev->parent;
+	if (!parent) {
+		dev_err(dev, "no parent for syscon devices\n");
+		return -ENODEV;
+	}
+
+	pmu->regmap = syscon_node_to_regmap(parent->of_node);
+
+	/*
+	 * Configure power up and down transition delays for CORE
+	 * and GPU domains.
+	 */
+	rockchip_configure_pd_cnt(pmu, pmu_info->core_pwrcnt_offset,
+				  pmu_info->core_power_transition_time);
+	rockchip_configure_pd_cnt(pmu, pmu_info->gpu_pwrcnt_offset,
+				  pmu_info->gpu_power_transition_time);
+
+	error = -ENODEV;
+
+	for_each_available_child_of_node(np, node) {
+		error = rockchip_pm_add_one_domain(pmu, node);
+		if (error) {
+			dev_err(dev, "failed to handle node %s: %d\n",
+				node->name, error);
+			goto err_out;
+		}
+	}
+
+	if (error) {
+		dev_dbg(dev, "no power domains defined\n");
+		goto err_out;
+	}
+
+	of_genpd_add_provider_onecell(np, &pmu->genpd_data);
+
+	return 0;
+
+err_out:
+	rockchip_pm_domain_cleanup(pmu);
+	return error;
+}
+
+static const struct rockchip_domain_info rk3288_pm_domains[] = {
+	[RK3288_PD_GPU]		= DOMAIN_RK3288(9, 9, 2),
+	[RK3288_PD_VIO]		= DOMAIN_RK3288(7, 7, 4),
+	[RK3288_PD_VIDEO]	= DOMAIN_RK3288(8, 8, 3),
+	[RK3288_PD_HEVC]	= DOMAIN_RK3288(14, 10, 9),
+};
+
+static const struct rockchip_pmu_info rk3288_pmu = {
+	.pwr_offset = 0x08,
+	.status_offset = 0x0c,
+	.req_offset = 0x10,
+	.idle_offset = 0x14,
+	.ack_offset = 0x14,
+
+	.core_pwrcnt_offset = 0x34,
+	.gpu_pwrcnt_offset = 0x3c,
+
+	.core_power_transition_time = 24, /* 1us */
+	.gpu_power_transition_time = 24, /* 1us */
+
+	.num_domains = ARRAY_SIZE(rk3288_pm_domains),
+	.domain_info = rk3288_pm_domains,
+};
+
+static const struct of_device_id rockchip_pm_domain_dt_match[] = {
+	{
+		.compatible = "rockchip,rk3288-power-controller",
+		.data = (void *)&rk3288_pmu,
+	},
+	{ /* sentinel */ },
+};
+
+static struct platform_driver rockchip_pm_domain_driver = {
+	.probe = rockchip_pm_domain_probe,
+	.driver = {
+		.name   = "rockchip-pm-domain",
+		.of_match_table = rockchip_pm_domain_dt_match,
+		/*
+		 * We can't forcibly eject devices form power domain,
+		 * so we can't really remove power domains once they
+		 * were added.
+		 */
+		.suppress_bind_attrs = true,
+	},
+};
+
+static int __init rockchip_pm_domain_drv_register(void)
+{
+	return platform_driver_register(&rockchip_pm_domain_driver);
+}
+postcore_initcall(rockchip_pm_domain_drv_register);
-- 
1.9.1



From wxt at rock-chips.com  Tue Aug 25 00:24:46 2015
From: wxt at rock-chips.com (Caesar Wang)
Date: Tue, 25 Aug 2015 15:24:46 +0800
Subject: [RESEND PATCH v16 4/4] ARM: dts: add the support power-domain node on
 RK3288 SoCs
In-Reply-To: <1440487486-6154-1-git-send-email-wxt@rock-chips.com>
References: <1440487486-6154-1-git-send-email-wxt@rock-chips.com>
Message-ID: <1440487486-6154-5-git-send-email-wxt@rock-chips.com>

We can add more domains node in the future.
This patch add the needed clocks into power-controller.
As the discuess about all the device clocks being listed in
the power-domains itself.

There are several reasons as follows:

Firstly, the clocks need be turned off to save power when
the system enter the suspend state. So we need to enumerate
the clocks in the dts. In order to power domain can turn on and off.

Secondly, the reset-circuit should reset be synchronous on RK3288,
then sync revoked. So we need to enable clocks of all devices.
In other words, we have to enable the clocks before you operate them
if all the device clocks are included in someone domians.

Someone wish was to get the clocks by reading the clocks from the
device nodes, We can do that but we can solve the above issues.

Anyway, the best ideas we can fix it in the future SoCs.

Signed-off-by: jinkun.hong <jinkun.hong at rock-chips.com>
Signed-off-by: Caesar Wang <wxt at rock-chips.com>

---

Changes in v16:
- Manually copy the problem in patch v15.
- rebase the description.

Changes in v15:
- As Tomasz remarked previously the dts should represent the hardware
  and the power-domains are part of the pmu.

Changes in v14:
- Remove essential clocks from rk3288 PD_VIO domain, Some clocks are
  essential for the system health and should not be turned down.
  However there is no owner for them so if they listed as belonging to power
  domain we'll try toggling them up and down during power domain transition.
  As a result we either fail to suspend or resume the system.

Changes in v13: None
Changes in v12: None
Changes in v11: None
Changes in v10:
- fix missing the #include <dt-bindings/power-domain/rk3288.h>.
- remove the notes.

Changes in v9:
- add decription for power-doamin node.

Changes in v8:
- DTS go back to v2.

Changes in v7: None
Changes in v6: None
Changes in v5: None
Changes in v4: None
Changes in v3:
- Decomposition power-controller, changed to multiple controller
  (gpu-power-controller, hevc-power-controller).

Changes in v2:
- make pd_vio clocks all one entry per line and alphabetize.
- power: power-controller move back to pinctrl: pinctrl.

 arch/arm/boot/dts/rk3288.dtsi | 60 ++++++++++++++++++++++++++++++++++++++++++-
 1 file changed, 59 insertions(+), 1 deletion(-)

diff --git a/arch/arm/boot/dts/rk3288.dtsi b/arch/arm/boot/dts/rk3288.dtsi
index 22316d0..161931d 100644
--- a/arch/arm/boot/dts/rk3288.dtsi
+++ b/arch/arm/boot/dts/rk3288.dtsi
@@ -44,6 +44,7 @@
 #include <dt-bindings/pinctrl/rockchip.h>
 #include <dt-bindings/clock/rk3288-cru.h>
 #include <dt-bindings/thermal/thermal.h>
+#include <dt-bindings/power-domain/rk3288.h>
 #include "skeleton.dtsi"
 
 / {
@@ -590,8 +591,65 @@
 	};
 
 	pmu: power-management at ff730000 {
-		compatible = "rockchip,rk3288-pmu", "syscon";
+		compatible = "rockchip,rk3288-pmu", "syscon", "simple-mfd";
 		reg = <0xff730000 0x100>;
+
+		power: power-controller {
+			compatible = "rockchip,rk3288-power-controller";
+			#power-domain-cells = <1>;
+			#address-cells = <1>;
+			#size-cells = <0>;
+
+			pd_gpu {
+				reg = <RK3288_PD_GPU>;
+				clocks = <&cru ACLK_GPU>;
+			};
+
+			pd_hevc {
+				reg = <RK3288_PD_HEVC>;
+				clocks = <&cru ACLK_HEVC>,
+					 <&cru SCLK_HEVC_CABAC>,
+					 <&cru SCLK_HEVC_CORE>,
+					 <&cru HCLK_HEVC>;
+			};
+
+			pd_vio {
+				reg = <RK3288_PD_VIO>;
+				clocks = <&cru ACLK_IEP>,
+					 <&cru ACLK_ISP>,
+					 <&cru ACLK_RGA>,
+					 <&cru ACLK_VIP>,
+					 <&cru ACLK_VOP0>,
+					 <&cru ACLK_VOP1>,
+					 <&cru DCLK_VOP0>,
+					 <&cru DCLK_VOP1>,
+					 <&cru HCLK_IEP>,
+					 <&cru HCLK_ISP>,
+					 <&cru HCLK_RGA>,
+					 <&cru HCLK_VIP>,
+					 <&cru HCLK_VOP0>,
+					 <&cru HCLK_VOP1>,
+					 <&cru PCLK_EDP_CTRL>,
+					 <&cru PCLK_HDMI_CTRL>,
+					 <&cru PCLK_LVDS_PHY>,
+					 <&cru PCLK_MIPI_CSI>,
+					 <&cru PCLK_MIPI_DSI0>,
+					 <&cru PCLK_MIPI_DSI1>,
+					 <&cru SCLK_EDP_24M>,
+					 <&cru SCLK_EDP>,
+					 <&cru SCLK_HDMI_CEC>,
+					 <&cru SCLK_HDMI_HDCP>,
+					 <&cru SCLK_ISP_JPE>,
+					 <&cru SCLK_ISP>,
+					 <&cru SCLK_RGA>;
+			};
+
+			pd_video {
+				reg = <RK3288_PD_VIDEO>;
+				clocks = <&cru ACLK_VCODEC>,
+					 <&cru HCLK_VCODEC>;
+			};
+		};
 	};
 
 	sgrf: syscon at ff740000 {
-- 
1.9.1



From yalin.wang2010 at gmail.com  Tue Aug 25 00:36:13 2015
From: yalin.wang2010 at gmail.com (yalin wang)
Date: Tue, 25 Aug 2015 15:36:13 +0800
Subject: [RFC] arm: change some function and data to init section
Message-ID: <1440488173-28825-1-git-send-email-yalin.wang2010@gmail.com>

This patch change some function and the related data to init section,
they are only called by free_initmem(), can be freed safely after
boot up.

Signed-off-by: yalin wang <yalin.wang2010 at gmail.com>
---
 arch/arm/mm/init.c | 12 ++++++------
 1 file changed, 6 insertions(+), 6 deletions(-)

diff --git a/arch/arm/mm/init.c b/arch/arm/mm/init.c
index 8a63b4c..7b505de 100644
--- a/arch/arm/mm/init.c
+++ b/arch/arm/mm/init.c
@@ -577,7 +577,7 @@ struct section_perm {
 	pmdval_t clear;
 };
 
-static struct section_perm nx_perms[] = {
+static struct section_perm nx_perms[] __initdata = {
 	/* Make pages tables, etc before _stext RW (set NX). */
 	{
 		.start	= PAGE_OFFSET,
@@ -680,7 +680,7 @@ static inline bool arch_has_strict_perms(void)
 	}								\
 }
 
-static inline void fix_kernmem_perms(void)
+static void __init fix_kernmem_perms(void)
 {
 	set_section_perms(nx_perms, prot);
 }
@@ -706,7 +706,7 @@ void set_kernel_text_ro(void)
 static inline void fix_kernmem_perms(void) { }
 #endif /* CONFIG_ARM_KERNMEM_PERMS */
 
-void free_tcmmem(void)
+static void __init free_tcmmem(void)
 {
 #ifdef CONFIG_HAVE_TCM
 	extern char __tcm_start, __tcm_end;
@@ -716,7 +716,7 @@ void free_tcmmem(void)
 #endif
 }
 
-void free_initmem(void)
+void __init_refok free_initmem(void)
 {
 	fix_kernmem_perms();
 	free_tcmmem();
@@ -728,9 +728,9 @@ void free_initmem(void)
 
 #ifdef CONFIG_BLK_DEV_INITRD
 
-static int keep_initrd;
+static int keep_initrd __initdata;
 
-void free_initrd_mem(unsigned long start, unsigned long end)
+void __init free_initrd_mem(unsigned long start, unsigned long end)
 {
 	if (!keep_initrd) {
 		if (start == initrd_start)
-- 
1.9.1



From lee.jones at linaro.org  Tue Aug 25 00:49:24 2015
From: lee.jones at linaro.org (Lee Jones)
Date: Tue, 25 Aug 2015 08:49:24 +0100
Subject: [PATCH-v2 5/5] mfd: 88pm800: Add support for clk subdevice
In-Reply-To: <55DBFC40.3010603@samsung.com>
References: <1440442594-3102-1-git-send-email-vaibhav.hiremath@linaro.org>
 <1440442594-3102-7-git-send-email-vaibhav.hiremath@linaro.org>
 <55DBFC40.3010603@samsung.com>
Message-ID: <20150825074924.GD19409@x1>

On Tue, 25 Aug 2015, Krzysztof Kozlowski wrote:

> On 25.08.2015 03:56, Vaibhav Hiremath wrote:
> > This patch adds mfd_cell/clk-subdevice for 88PM800 MFD
> > (and family of devices).
> > 
> > Signed-off-by: Vaibhav Hiremath <vaibhav.hiremath at linaro.org>
> > ---
> >  drivers/mfd/88pm800.c | 25 +++++++++++++++++++++++++
> >  1 file changed, 25 insertions(+)
> > 
> > diff --git a/drivers/mfd/88pm800.c b/drivers/mfd/88pm800.c
> > index c4e097d..a928eed 100644
> > --- a/drivers/mfd/88pm800.c
> > +++ b/drivers/mfd/88pm800.c
> > @@ -173,6 +173,14 @@ static const struct mfd_cell regulator_devs[] = {
> >  	},
> >  };
> >  
> > +static struct mfd_cell clk_devs[] = {
> > +	{
> > +		.name = "88pm80x-clk",
> > +		.of_compatible = "marvell,88pm800-clk",
> > +		.id = -1,
> 
> The "-1" here stands for PLATFORM_DEVID_NONE?

Right.  Please use the define, but use it in the mfd_add_devices()
call, rather than individual cells.

> > +	},
> > +};
> > +
> >  static const struct regmap_irq pm800_irqs[] = {
> >  	/* INT0 */
> >  	[PM800_IRQ_ONKEY] = {
> > @@ -344,6 +352,17 @@ static int device_regulator_init(struct pm80x_chip *chip)
> >  			ARRAY_SIZE(regulator_devs), NULL, 0, NULL);
> >  }
> >  
> > +static int device_clk_init(struct pm80x_chip *chip)
> > +{
> > +	if (chip->type == CHIP_PM800)
> > +		clk_devs[0].name = "88pm800-clk";
> > +	else if (chip->type == CHIP_PM860)
> > +		clk_devs[0].name = "88pm860-clk";
> > +
> > +	return mfd_add_devices(chip->dev, 0, &clk_devs[0],
> > +			ARRAY_SIZE(clk_devs), NULL, 0, NULL);
> > +}
> > +
> >  static int device_irq_init_800(struct pm80x_chip *chip)
> >  {
> >  	struct regmap *map = chip->regmap;
> > @@ -511,6 +530,12 @@ static int device_800_init(struct pm80x_chip *chip)
> >  		goto out;
> >  	}
> >  
> > +	ret = device_clk_init(chip);
> > +	if (ret) {
> > +		dev_err(chip->dev, "Failed to add clk subdev\n");
> > +		goto out;
> > +	}
> > +
> >  	return 0;
> >  out_dev:
> >  	mfd_remove_devices(chip->dev);
> > 
> 

-- 
Lee Jones
Linaro STMicroelectronics Landing Team Lead
Linaro.org ? Open source software for ARM SoCs
Follow Linaro: Facebook | Twitter | Blog


From lee.jones at linaro.org  Tue Aug 25 00:51:21 2015
From: lee.jones at linaro.org (Lee Jones)
Date: Tue, 25 Aug 2015 08:51:21 +0100
Subject: [PATCH-v2 1/5] mfd: 88pm800: Fix tabbing issue
In-Reply-To: <1440442594-3102-2-git-send-email-vaibhav.hiremath@linaro.org>
References: <1440442594-3102-1-git-send-email-vaibhav.hiremath@linaro.org>
 <1440442594-3102-2-git-send-email-vaibhav.hiremath@linaro.org>
Message-ID: <20150825075121.GE19409@x1>

On Tue, 25 Aug 2015, Vaibhav Hiremath wrote:

> Driver had coding style issues where spaces were used instead
> of tabs. This patch fixes them all.

That's not all it's doing though is it?

Please describe all of your changes.

> Signed-off-by: Vaibhav Hiremath <vaibhav.hiremath at linaro.org>
> ---
>  drivers/mfd/88pm800.c | 125 ++++++++++++++++++++++++--------------------------
>  1 file changed, 61 insertions(+), 64 deletions(-)
> 
> diff --git a/drivers/mfd/88pm800.c b/drivers/mfd/88pm800.c
> index f104a32..c4e097d 100644
> --- a/drivers/mfd/88pm800.c
> +++ b/drivers/mfd/88pm800.c
> @@ -30,55 +30,55 @@
>  #include <linux/of_device.h>
>  
>  /* Interrupt Registers */
> -#define PM800_INT_STATUS1		(0x05)
> +#define PM800_INT_STATUS1		0x05
>  #define PM800_ONKEY_INT_STS1		(1 << 0)
>  #define PM800_EXTON_INT_STS1		(1 << 1)
> -#define PM800_CHG_INT_STS1			(1 << 2)
> -#define PM800_BAT_INT_STS1			(1 << 3)
> -#define PM800_RTC_INT_STS1			(1 << 4)
> +#define PM800_CHG_INT_STS1		(1 << 2)
> +#define PM800_BAT_INT_STS1		(1 << 3)
> +#define PM800_RTC_INT_STS1		(1 << 4)
>  #define PM800_CLASSD_OC_INT_STS1	(1 << 5)

These should all be replaced by BIT().

Please fix the whole file.

> -#define PM800_INT_STATUS2		(0x06)
> +#define PM800_INT_STATUS2		0x06
>  #define PM800_VBAT_INT_STS2		(1 << 0)
>  #define PM800_VSYS_INT_STS2		(1 << 1)
>  #define PM800_VCHG_INT_STS2		(1 << 2)
>  #define PM800_TINT_INT_STS2		(1 << 3)
> -#define PM800_GPADC0_INT_STS2	(1 << 4)
> +#define PM800_GPADC0_INT_STS2		(1 << 4)
>  #define PM800_TBAT_INT_STS2		(1 << 5)
> -#define PM800_GPADC2_INT_STS2	(1 << 6)
> -#define PM800_GPADC3_INT_STS2	(1 << 7)
> +#define PM800_GPADC2_INT_STS2		(1 << 6)
> +#define PM800_GPADC3_INT_STS2		(1 << 7)
>  
> -#define PM800_INT_STATUS3		(0x07)
> +#define PM800_INT_STATUS3		0x07
>  
> -#define PM800_INT_STATUS4		(0x08)
> +#define PM800_INT_STATUS4		0x08
>  #define PM800_GPIO0_INT_STS4		(1 << 0)
>  #define PM800_GPIO1_INT_STS4		(1 << 1)
>  #define PM800_GPIO2_INT_STS4		(1 << 2)
>  #define PM800_GPIO3_INT_STS4		(1 << 3)
>  #define PM800_GPIO4_INT_STS4		(1 << 4)
>  
> -#define PM800_INT_ENA_1		(0x09)
> +#define PM800_INT_ENA_1			0x09
>  #define PM800_ONKEY_INT_ENA1		(1 << 0)
>  #define PM800_EXTON_INT_ENA1		(1 << 1)
> -#define PM800_CHG_INT_ENA1			(1 << 2)
> -#define PM800_BAT_INT_ENA1			(1 << 3)
> -#define PM800_RTC_INT_ENA1			(1 << 4)
> +#define PM800_CHG_INT_ENA1		(1 << 2)
> +#define PM800_BAT_INT_ENA1		(1 << 3)
> +#define PM800_RTC_INT_ENA1		(1 << 4)
>  #define PM800_CLASSD_OC_INT_ENA1	(1 << 5)
>  
> -#define PM800_INT_ENA_2		(0x0A)
> +#define PM800_INT_ENA_2			0x0A
>  #define PM800_VBAT_INT_ENA2		(1 << 0)
>  #define PM800_VSYS_INT_ENA2		(1 << 1)
>  #define PM800_VCHG_INT_ENA2		(1 << 2)
>  #define PM800_TINT_INT_ENA2		(1 << 3)
>  
> -#define PM800_INT_ENA_3		(0x0B)
> +#define PM800_INT_ENA_3			0x0B
>  #define PM800_GPADC0_INT_ENA3		(1 << 0)
>  #define PM800_GPADC1_INT_ENA3		(1 << 1)
>  #define PM800_GPADC2_INT_ENA3		(1 << 2)
>  #define PM800_GPADC3_INT_ENA3		(1 << 3)
>  #define PM800_GPADC4_INT_ENA3		(1 << 4)
>  
> -#define PM800_INT_ENA_4		(0x0C)
> +#define PM800_INT_ENA_4			0x0C
>  #define PM800_GPIO0_INT_ENA4		(1 << 0)
>  #define PM800_GPIO1_INT_ENA4		(1 << 1)
>  #define PM800_GPIO2_INT_ENA4		(1 << 2)
> @@ -86,7 +86,7 @@
>  #define PM800_GPIO4_INT_ENA4		(1 << 4)
>  
>  /* number of INT_ENA & INT_STATUS regs */
> -#define PM800_INT_REG_NUM			(4)
> +#define PM800_INT_REG_NUM		4
>  
>  /* Interrupt Number in 88PM800 */
>  enum {
> @@ -114,7 +114,7 @@ enum {
>  };
>  
>  /* PM800: generation identification number */
> -#define PM800_CHIP_GEN_ID_NUM	0x3
> +#define PM800_CHIP_GEN_ID_NUM		0x3
>  
>  static const struct i2c_device_id pm80x_id_table[] = {
>  	{"88PM800", 0},
> @@ -129,47 +129,47 @@ static const struct of_device_id pm80x_of_match_table[] = {
>  
>  static struct resource rtc_resources[] = {
>  	{
> -	 .name = "88pm80x-rtc",
> -	 .start = PM800_IRQ_RTC,
> -	 .end = PM800_IRQ_RTC,
> -	 .flags = IORESOURCE_IRQ,
> -	 },
> +		.name = "88pm80x-rtc",
> +		.start = PM800_IRQ_RTC,
> +		.end = PM800_IRQ_RTC,
> +		.flags = IORESOURCE_IRQ,
> +	},
>  };
>  
>  static struct mfd_cell rtc_devs[] = {
>  	{
> -	 .name = "88pm80x-rtc",
> -	 .of_compatible = "marvell,88pm80x-rtc",
> -	 .num_resources = ARRAY_SIZE(rtc_resources),
> -	 .resources = &rtc_resources[0],
> -	 .id = -1,
> -	 },
> +		.name = "88pm80x-rtc",
> +		.of_compatible = "marvell,88pm80x-rtc",
> +		.num_resources = ARRAY_SIZE(rtc_resources),
> +		.resources = &rtc_resources[0],
> +		.id = -1,
> +	},
>  };
>  
>  static struct resource onkey_resources[] = {
>  	{
> -	 .name = "88pm80x-onkey",
> -	 .start = PM800_IRQ_ONKEY,
> -	 .end = PM800_IRQ_ONKEY,
> -	 .flags = IORESOURCE_IRQ,
> -	 },
> +		.name = "88pm80x-onkey",
> +		.start = PM800_IRQ_ONKEY,
> +		.end = PM800_IRQ_ONKEY,
> +		.flags = IORESOURCE_IRQ,
> +	},
>  };
>  
>  static const struct mfd_cell onkey_devs[] = {
>  	{
> -	 .name = "88pm80x-onkey",
> -	 .of_compatible = "marvell,88pm80x-onkey",
> -	 .num_resources = 1,
> -	 .resources = &onkey_resources[0],
> -	 .id = -1,
> -	 },
> +		.name = "88pm80x-onkey",
> +		.of_compatible = "marvell,88pm80x-onkey",
> +		.num_resources = 1,
> +		.resources = &onkey_resources[0],
> +		.id = -1,
> +	},
>  };
>  
>  static const struct mfd_cell regulator_devs[] = {
>  	{
> -	 .name = "88pm80x-regulator",
> -	 .of_compatible = "marvell,88pm80x-regulator",
> -	 .id = -1,
> +		.name = "88pm80x-regulator",
> +		.of_compatible = "marvell,88pm80x-regulator",
> +		.id = -1,
>  	},
>  };
>  
> @@ -323,8 +323,8 @@ out:
>  static int device_onkey_init(struct pm80x_chip *chip)
>  {
>  	return mfd_add_devices(chip->dev, 0, &onkey_devs[0],
> -			      ARRAY_SIZE(onkey_devs), &onkey_resources[0], 0,
> -			      NULL);
> +			ARRAY_SIZE(onkey_devs), &onkey_resources[0], 0,
> +			NULL);
>  }
>  
>  static int device_rtc_init(struct pm80x_chip *chip)
> @@ -335,13 +335,13 @@ static int device_rtc_init(struct pm80x_chip *chip)
>  	rtc_devs[0].pdata_size = pdata->rtc ? sizeof(struct pm80x_rtc_pdata) : 0;
>  
>  	return mfd_add_devices(chip->dev, 0, &rtc_devs[0],
> -			      ARRAY_SIZE(rtc_devs), NULL, 0, NULL);
> +			ARRAY_SIZE(rtc_devs), NULL, 0, NULL);
>  }
>  
>  static int device_regulator_init(struct pm80x_chip *chip)
>  {
>  	return mfd_add_devices(chip->dev, 0, &regulator_devs[0],
> -			      ARRAY_SIZE(regulator_devs), NULL, 0, NULL);
> +			ARRAY_SIZE(regulator_devs), NULL, 0, NULL);
>  }
>  
>  static int device_irq_init_800(struct pm80x_chip *chip)
> @@ -358,11 +358,10 @@ static int device_irq_init_800(struct pm80x_chip *chip)
>  
>  	/*
>  	 * irq_clr_on_wr defines the way of clearing interrupt by
> -	 * read/write(0/1).  It's read-clear by default.
> +	 * read/write(0/1). It's read-clear by default.
>  	 */
> -	mask =
> -	    PM800_WAKEUP2_INV_INT | PM800_WAKEUP2_INT_CLEAR |
> -	    PM800_WAKEUP2_INT_MASK;
> +	mask = PM800_WAKEUP2_INV_INT | PM800_WAKEUP2_INT_CLEAR |
> +		PM800_WAKEUP2_INT_MASK;
>  
>  	irq_clr_mode = pdata->irq_clr_method == PM800_IRQ_CLR_ON_WRITE ?
>  		PM800_WAKEUP2_INT_WRITE_CLEAR : PM800_WAKEUP2_INT_READ_CLEAR;
> @@ -371,9 +370,8 @@ static int device_irq_init_800(struct pm80x_chip *chip)
>  	if (ret < 0)
>  		goto out;
>  
> -	ret =
> -	    regmap_add_irq_chip(chip->regmap, chip->irq, flags, -1,
> -				chip->regmap_irq_chip, &chip->irq_data);
> +	ret = regmap_add_irq_chip(chip->regmap, chip->irq, flags, -1,
> +			chip->regmap_irq_chip, &chip->irq_data);
>  
>  out:
>  	return ret;
> @@ -409,18 +407,18 @@ static int pm800_pages_init(struct pm80x_chip *chip)
>  
>  	/* PM800 block power page */
>  	subchip->power_page = i2c_new_dummy(client->adapter,
> -					    subchip->power_page_addr);
> +					subchip->power_page_addr);
>  	if (subchip->power_page == NULL) {
>  		ret = -ENODEV;
>  		goto out;
>  	}
>  
>  	subchip->regmap_power = devm_regmap_init_i2c(subchip->power_page,
> -						     &pm80x_regmap_config);
> +				&pm80x_regmap_config);
>  	if (IS_ERR(subchip->regmap_power)) {
>  		ret = PTR_ERR(subchip->regmap_power);
>  		dev_err(chip->dev,
> -			"Failed to allocate regmap_power: %d\n", ret);
> +				"Failed to allocate regmap_power: %d\n", ret);
>  		goto out;
>  	}
>  
> @@ -428,18 +426,18 @@ static int pm800_pages_init(struct pm80x_chip *chip)
>  
>  	/* PM800 block GPADC */
>  	subchip->gpadc_page = i2c_new_dummy(client->adapter,
> -					    subchip->gpadc_page_addr);
> +				subchip->gpadc_page_addr);
>  	if (subchip->gpadc_page == NULL) {
>  		ret = -ENODEV;
>  		goto out;
>  	}
>  
>  	subchip->regmap_gpadc = devm_regmap_init_i2c(subchip->gpadc_page,
> -						     &pm80x_regmap_config);
> +				&pm80x_regmap_config);
>  	if (IS_ERR(subchip->regmap_gpadc)) {
>  		ret = PTR_ERR(subchip->regmap_gpadc);
>  		dev_err(chip->dev,
> -			"Failed to allocate regmap_gpadc: %d\n", ret);
> +				"Failed to allocate regmap_gpadc: %d\n", ret);
>  		goto out;
>  	}
>  	i2c_set_clientdata(subchip->gpadc_page, chip);
> @@ -620,8 +618,7 @@ static int pm800_probe(struct i2c_client *client,
>  	chip = i2c_get_clientdata(client);
>  
>  	/* init subchip for PM800 */
> -	subchip =
> -	    devm_kzalloc(&client->dev, sizeof(struct pm80x_subchip),
> +	subchip = devm_kzalloc(&client->dev, sizeof(struct pm80x_subchip),
>  			 GFP_KERNEL);
>  	if (!subchip) {
>  		ret = -ENOMEM;
> @@ -684,7 +681,7 @@ static struct i2c_driver pm800_driver = {
>  		.owner = THIS_MODULE,
>  		.pm = &pm80x_pm_ops,
>  		.of_match_table	= pm80x_of_match_table,
> -		},
> +	},
>  	.probe = pm800_probe,
>  	.remove = pm800_remove,
>  	.id_table = pm80x_id_table,

-- 
Lee Jones
Linaro STMicroelectronics Landing Team Lead
Linaro.org ? Open source software for ARM SoCs
Follow Linaro: Facebook | Twitter | Blog


From lee.jones at linaro.org  Tue Aug 25 00:52:46 2015
From: lee.jones at linaro.org (Lee Jones)
Date: Tue, 25 Aug 2015 08:52:46 +0100
Subject: [PATCH-v2 1/5] mfd: 88pm800: Fix tabbing issue
In-Reply-To: <1440442594-3102-3-git-send-email-vaibhav.hiremath@linaro.org>
References: <1440442594-3102-1-git-send-email-vaibhav.hiremath@linaro.org>
 <1440442594-3102-3-git-send-email-vaibhav.hiremath@linaro.org>
Message-ID: <20150825075246.GF19409@x1>

On Tue, 25 Aug 2015, Vaibhav Hiremath wrote:

> Driver had coding style issues where spaces were used instead
> of tabs. This patch fixes them all.
> 
> Signed-off-by: Vaibhav Hiremath <vaibhav.hiremath at linaro.org>
> ---
>  drivers/mfd/88pm800.c | 125 ++++++++++++++++++++++++--------------------------
>  1 file changed, 61 insertions(+), 64 deletions(-)

Same comment as before.

How similar is this file to the other one?

Can you reduce the size by having shared register defines?

> diff --git a/drivers/mfd/88pm800.c b/drivers/mfd/88pm800.c
> index f104a32..c4e097d 100644
> --- a/drivers/mfd/88pm800.c
> +++ b/drivers/mfd/88pm800.c
> @@ -30,55 +30,55 @@
>  #include <linux/of_device.h>
>  
>  /* Interrupt Registers */
> -#define PM800_INT_STATUS1		(0x05)
> +#define PM800_INT_STATUS1		0x05
>  #define PM800_ONKEY_INT_STS1		(1 << 0)
>  #define PM800_EXTON_INT_STS1		(1 << 1)
> -#define PM800_CHG_INT_STS1			(1 << 2)
> -#define PM800_BAT_INT_STS1			(1 << 3)
> -#define PM800_RTC_INT_STS1			(1 << 4)
> +#define PM800_CHG_INT_STS1		(1 << 2)
> +#define PM800_BAT_INT_STS1		(1 << 3)
> +#define PM800_RTC_INT_STS1		(1 << 4)
>  #define PM800_CLASSD_OC_INT_STS1	(1 << 5)
>  
> -#define PM800_INT_STATUS2		(0x06)
> +#define PM800_INT_STATUS2		0x06
>  #define PM800_VBAT_INT_STS2		(1 << 0)
>  #define PM800_VSYS_INT_STS2		(1 << 1)
>  #define PM800_VCHG_INT_STS2		(1 << 2)
>  #define PM800_TINT_INT_STS2		(1 << 3)
> -#define PM800_GPADC0_INT_STS2	(1 << 4)
> +#define PM800_GPADC0_INT_STS2		(1 << 4)
>  #define PM800_TBAT_INT_STS2		(1 << 5)
> -#define PM800_GPADC2_INT_STS2	(1 << 6)
> -#define PM800_GPADC3_INT_STS2	(1 << 7)
> +#define PM800_GPADC2_INT_STS2		(1 << 6)
> +#define PM800_GPADC3_INT_STS2		(1 << 7)
>  
> -#define PM800_INT_STATUS3		(0x07)
> +#define PM800_INT_STATUS3		0x07
>  
> -#define PM800_INT_STATUS4		(0x08)
> +#define PM800_INT_STATUS4		0x08
>  #define PM800_GPIO0_INT_STS4		(1 << 0)
>  #define PM800_GPIO1_INT_STS4		(1 << 1)
>  #define PM800_GPIO2_INT_STS4		(1 << 2)
>  #define PM800_GPIO3_INT_STS4		(1 << 3)
>  #define PM800_GPIO4_INT_STS4		(1 << 4)
>  
> -#define PM800_INT_ENA_1		(0x09)
> +#define PM800_INT_ENA_1			0x09
>  #define PM800_ONKEY_INT_ENA1		(1 << 0)
>  #define PM800_EXTON_INT_ENA1		(1 << 1)
> -#define PM800_CHG_INT_ENA1			(1 << 2)
> -#define PM800_BAT_INT_ENA1			(1 << 3)
> -#define PM800_RTC_INT_ENA1			(1 << 4)
> +#define PM800_CHG_INT_ENA1		(1 << 2)
> +#define PM800_BAT_INT_ENA1		(1 << 3)
> +#define PM800_RTC_INT_ENA1		(1 << 4)
>  #define PM800_CLASSD_OC_INT_ENA1	(1 << 5)
>  
> -#define PM800_INT_ENA_2		(0x0A)
> +#define PM800_INT_ENA_2			0x0A
>  #define PM800_VBAT_INT_ENA2		(1 << 0)
>  #define PM800_VSYS_INT_ENA2		(1 << 1)
>  #define PM800_VCHG_INT_ENA2		(1 << 2)
>  #define PM800_TINT_INT_ENA2		(1 << 3)
>  
> -#define PM800_INT_ENA_3		(0x0B)
> +#define PM800_INT_ENA_3			0x0B
>  #define PM800_GPADC0_INT_ENA3		(1 << 0)
>  #define PM800_GPADC1_INT_ENA3		(1 << 1)
>  #define PM800_GPADC2_INT_ENA3		(1 << 2)
>  #define PM800_GPADC3_INT_ENA3		(1 << 3)
>  #define PM800_GPADC4_INT_ENA3		(1 << 4)
>  
> -#define PM800_INT_ENA_4		(0x0C)
> +#define PM800_INT_ENA_4			0x0C
>  #define PM800_GPIO0_INT_ENA4		(1 << 0)
>  #define PM800_GPIO1_INT_ENA4		(1 << 1)
>  #define PM800_GPIO2_INT_ENA4		(1 << 2)
> @@ -86,7 +86,7 @@
>  #define PM800_GPIO4_INT_ENA4		(1 << 4)
>  
>  /* number of INT_ENA & INT_STATUS regs */
> -#define PM800_INT_REG_NUM			(4)
> +#define PM800_INT_REG_NUM		4
>  
>  /* Interrupt Number in 88PM800 */
>  enum {
> @@ -114,7 +114,7 @@ enum {
>  };
>  
>  /* PM800: generation identification number */
> -#define PM800_CHIP_GEN_ID_NUM	0x3
> +#define PM800_CHIP_GEN_ID_NUM		0x3
>  
>  static const struct i2c_device_id pm80x_id_table[] = {
>  	{"88PM800", 0},
> @@ -129,47 +129,47 @@ static const struct of_device_id pm80x_of_match_table[] = {
>  
>  static struct resource rtc_resources[] = {
>  	{
> -	 .name = "88pm80x-rtc",
> -	 .start = PM800_IRQ_RTC,
> -	 .end = PM800_IRQ_RTC,
> -	 .flags = IORESOURCE_IRQ,
> -	 },
> +		.name = "88pm80x-rtc",
> +		.start = PM800_IRQ_RTC,
> +		.end = PM800_IRQ_RTC,
> +		.flags = IORESOURCE_IRQ,
> +	},
>  };
>  
>  static struct mfd_cell rtc_devs[] = {
>  	{
> -	 .name = "88pm80x-rtc",
> -	 .of_compatible = "marvell,88pm80x-rtc",
> -	 .num_resources = ARRAY_SIZE(rtc_resources),
> -	 .resources = &rtc_resources[0],
> -	 .id = -1,
> -	 },
> +		.name = "88pm80x-rtc",
> +		.of_compatible = "marvell,88pm80x-rtc",
> +		.num_resources = ARRAY_SIZE(rtc_resources),
> +		.resources = &rtc_resources[0],
> +		.id = -1,
> +	},
>  };
>  
>  static struct resource onkey_resources[] = {
>  	{
> -	 .name = "88pm80x-onkey",
> -	 .start = PM800_IRQ_ONKEY,
> -	 .end = PM800_IRQ_ONKEY,
> -	 .flags = IORESOURCE_IRQ,
> -	 },
> +		.name = "88pm80x-onkey",
> +		.start = PM800_IRQ_ONKEY,
> +		.end = PM800_IRQ_ONKEY,
> +		.flags = IORESOURCE_IRQ,
> +	},
>  };
>  
>  static const struct mfd_cell onkey_devs[] = {
>  	{
> -	 .name = "88pm80x-onkey",
> -	 .of_compatible = "marvell,88pm80x-onkey",
> -	 .num_resources = 1,
> -	 .resources = &onkey_resources[0],
> -	 .id = -1,
> -	 },
> +		.name = "88pm80x-onkey",
> +		.of_compatible = "marvell,88pm80x-onkey",
> +		.num_resources = 1,
> +		.resources = &onkey_resources[0],
> +		.id = -1,
> +	},
>  };
>  
>  static const struct mfd_cell regulator_devs[] = {
>  	{
> -	 .name = "88pm80x-regulator",
> -	 .of_compatible = "marvell,88pm80x-regulator",
> -	 .id = -1,
> +		.name = "88pm80x-regulator",
> +		.of_compatible = "marvell,88pm80x-regulator",
> +		.id = -1,
>  	},
>  };
>  
> @@ -323,8 +323,8 @@ out:
>  static int device_onkey_init(struct pm80x_chip *chip)
>  {
>  	return mfd_add_devices(chip->dev, 0, &onkey_devs[0],
> -			      ARRAY_SIZE(onkey_devs), &onkey_resources[0], 0,
> -			      NULL);
> +			ARRAY_SIZE(onkey_devs), &onkey_resources[0], 0,
> +			NULL);
>  }
>  
>  static int device_rtc_init(struct pm80x_chip *chip)
> @@ -335,13 +335,13 @@ static int device_rtc_init(struct pm80x_chip *chip)
>  	rtc_devs[0].pdata_size = pdata->rtc ? sizeof(struct pm80x_rtc_pdata) : 0;
>  
>  	return mfd_add_devices(chip->dev, 0, &rtc_devs[0],
> -			      ARRAY_SIZE(rtc_devs), NULL, 0, NULL);
> +			ARRAY_SIZE(rtc_devs), NULL, 0, NULL);
>  }
>  
>  static int device_regulator_init(struct pm80x_chip *chip)
>  {
>  	return mfd_add_devices(chip->dev, 0, &regulator_devs[0],
> -			      ARRAY_SIZE(regulator_devs), NULL, 0, NULL);
> +			ARRAY_SIZE(regulator_devs), NULL, 0, NULL);
>  }
>  
>  static int device_irq_init_800(struct pm80x_chip *chip)
> @@ -358,11 +358,10 @@ static int device_irq_init_800(struct pm80x_chip *chip)
>  
>  	/*
>  	 * irq_clr_on_wr defines the way of clearing interrupt by
> -	 * read/write(0/1).  It's read-clear by default.
> +	 * read/write(0/1). It's read-clear by default.
>  	 */
> -	mask =
> -	    PM800_WAKEUP2_INV_INT | PM800_WAKEUP2_INT_CLEAR |
> -	    PM800_WAKEUP2_INT_MASK;
> +	mask = PM800_WAKEUP2_INV_INT | PM800_WAKEUP2_INT_CLEAR |
> +		PM800_WAKEUP2_INT_MASK;
>  
>  	irq_clr_mode = pdata->irq_clr_method == PM800_IRQ_CLR_ON_WRITE ?
>  		PM800_WAKEUP2_INT_WRITE_CLEAR : PM800_WAKEUP2_INT_READ_CLEAR;
> @@ -371,9 +370,8 @@ static int device_irq_init_800(struct pm80x_chip *chip)
>  	if (ret < 0)
>  		goto out;
>  
> -	ret =
> -	    regmap_add_irq_chip(chip->regmap, chip->irq, flags, -1,
> -				chip->regmap_irq_chip, &chip->irq_data);
> +	ret = regmap_add_irq_chip(chip->regmap, chip->irq, flags, -1,
> +			chip->regmap_irq_chip, &chip->irq_data);
>  
>  out:
>  	return ret;
> @@ -409,18 +407,18 @@ static int pm800_pages_init(struct pm80x_chip *chip)
>  
>  	/* PM800 block power page */
>  	subchip->power_page = i2c_new_dummy(client->adapter,
> -					    subchip->power_page_addr);
> +					subchip->power_page_addr);
>  	if (subchip->power_page == NULL) {
>  		ret = -ENODEV;
>  		goto out;
>  	}
>  
>  	subchip->regmap_power = devm_regmap_init_i2c(subchip->power_page,
> -						     &pm80x_regmap_config);
> +				&pm80x_regmap_config);
>  	if (IS_ERR(subchip->regmap_power)) {
>  		ret = PTR_ERR(subchip->regmap_power);
>  		dev_err(chip->dev,
> -			"Failed to allocate regmap_power: %d\n", ret);
> +				"Failed to allocate regmap_power: %d\n", ret);
>  		goto out;
>  	}
>  
> @@ -428,18 +426,18 @@ static int pm800_pages_init(struct pm80x_chip *chip)
>  
>  	/* PM800 block GPADC */
>  	subchip->gpadc_page = i2c_new_dummy(client->adapter,
> -					    subchip->gpadc_page_addr);
> +				subchip->gpadc_page_addr);
>  	if (subchip->gpadc_page == NULL) {
>  		ret = -ENODEV;
>  		goto out;
>  	}
>  
>  	subchip->regmap_gpadc = devm_regmap_init_i2c(subchip->gpadc_page,
> -						     &pm80x_regmap_config);
> +				&pm80x_regmap_config);
>  	if (IS_ERR(subchip->regmap_gpadc)) {
>  		ret = PTR_ERR(subchip->regmap_gpadc);
>  		dev_err(chip->dev,
> -			"Failed to allocate regmap_gpadc: %d\n", ret);
> +				"Failed to allocate regmap_gpadc: %d\n", ret);
>  		goto out;
>  	}
>  	i2c_set_clientdata(subchip->gpadc_page, chip);
> @@ -620,8 +618,7 @@ static int pm800_probe(struct i2c_client *client,
>  	chip = i2c_get_clientdata(client);
>  
>  	/* init subchip for PM800 */
> -	subchip =
> -	    devm_kzalloc(&client->dev, sizeof(struct pm80x_subchip),
> +	subchip = devm_kzalloc(&client->dev, sizeof(struct pm80x_subchip),
>  			 GFP_KERNEL);
>  	if (!subchip) {
>  		ret = -ENOMEM;
> @@ -684,7 +681,7 @@ static struct i2c_driver pm800_driver = {
>  		.owner = THIS_MODULE,
>  		.pm = &pm80x_pm_ops,
>  		.of_match_table	= pm80x_of_match_table,
> -		},
> +	},
>  	.probe = pm800_probe,
>  	.remove = pm800_remove,
>  	.id_table = pm80x_id_table,

-- 
Lee Jones
Linaro STMicroelectronics Landing Team Lead
Linaro.org ? Open source software for ARM SoCs
Follow Linaro: Facebook | Twitter | Blog


From anders.roxell at linaro.org  Tue Aug 25 00:52:05 2015
From: anders.roxell at linaro.org (Anders Roxell)
Date: Tue, 25 Aug 2015 09:52:05 +0200
Subject: [PATCH] drivers: i2c: exynos5: irq spinlock rt-safe
Message-ID: <1440489125-20082-1-git-send-email-anders.roxell@linaro.org>

The exynos5_i2c_message_start enables interrupts while holding the i2c
lock which is sought by the irq handler. If an IRQ is received before
this lock is released then a deadlock occurs.

This is only seen on an RT patched kernel, due to the transformation of
spinlocks into sleeping locks. By using raw_spinlocks here the same code
can run in mainline or an RT patched kernel. No change for !RT kenrels

[   10.992238] kernel BUG at ../kernel/locking/rtmutex.c:998!
[   10.992243] Internal error: Oops - BUG: 0 [#1] PREEMPT SMP ARM
[   10.992250] Modules linked in:
[   10.992258] CPU: 0 PID: 1 Comm: swapper/0 Not tainted 4.1.5-rt5
[   10.992263] Hardware name: SAMSUNG EXYNOS (Flattened Device Tree)
[   10.992268] task: ed880000 ti: ed888000 task.ti: ed888000
[   10.992281] PC is at rt_spin_lock_slowlock+0xa4/0x2ec
[   10.992288] LR is at rt_spin_lock_slowlock+0x54/0x2ec
[   10.992296] pc : [<c099e1bc>]    lr : [<c099e16c>]    psr: 60000193
[   10.992296] sp : ed889a28  ip : ed880001  fp : 00000089
[   10.992300] r10: ed889a28  r9 : c0f55654  r8 : 00000060
[   10.992305] r7 : ed880000  r6 : 00000000  r5 : 00000001  r4 : ed9f7288
[   10.992310] r3 : ed880000  r2 : 00000000  r1 : ed880000  r0 : 00000000
[   10.992316] Flags: nZCv  IRQs off  FIQs on  Mode SVC_32  ISA ARM
Segment kernel
...
...
[   10.992662] [<c099e1bc>] (rt_spin_lock_slowlock) from [<c07bc794>]
(exynos5_i2c_irq+0x20/0x2b0)
[   10.992678] [<c07bc794>] (exynos5_i2c_irq) from [<c028c8b4>]
(handle_irq_event_percpu+0x68/0x158)
[   10.992690] [<c028c8b4>] (handle_irq_event_percpu) from [<c028ca0c>]
(handle_irq_event+0x68/0xa8)
[   10.992702] [<c028ca0c>] (handle_irq_event) from [<c028f9c4>]
(handle_fasteoi_irq+0x11c/0x1d4)
[   10.992713] [<c028f9c4>] (handle_fasteoi_irq) from [<c028c17c>]
(generic_handle_irq+0x20/0x30)
[   10.992724] [<c028c17c>] (generic_handle_irq) from [<c028c290>]
(__handle_domain_irq+0x6c/0xe4)
[   10.992734] [<c028c290>] (__handle_domain_irq) from [<c020a71c>]
(gic_handle_irq+0x2c/0x68)
[   10.992744] [<c020a71c>] (gic_handle_irq) from [<c0214140>]
(__irq_svc+0x40/0x88)
[   10.992749] Exception stack(0xed889b28 to 0xed889b70)
...
...

Signed-off-by: Anders Roxell <anders.roxell at linaro.org>
---
 drivers/i2c/busses/i2c-exynos5.c | 12 ++++++------
 1 file changed, 6 insertions(+), 6 deletions(-)

diff --git a/drivers/i2c/busses/i2c-exynos5.c b/drivers/i2c/busses/i2c-exynos5.c
index b29c750..b12e77e 100644
--- a/drivers/i2c/busses/i2c-exynos5.c
+++ b/drivers/i2c/busses/i2c-exynos5.c
@@ -170,7 +170,7 @@ struct exynos5_i2c {
 	struct device		*dev;
 	int			state;
 
-	spinlock_t		lock;		/* IRQ synchronization */
+	raw_spinlock_t		lock;		/* IRQ synchronization */
 
 	/*
 	 * Since the TRANS_DONE bit is cleared on read, and we may read it
@@ -433,7 +433,7 @@ static irqreturn_t exynos5_i2c_irq(int irqno, void *dev_id)
 
 	i2c->state = -EINVAL;
 
-	spin_lock(&i2c->lock);
+	raw_spin_lock(&i2c->lock);
 
 	int_status = readl(i2c->regs + HSI2C_INT_STATUS);
 	writel(int_status, i2c->regs + HSI2C_INT_STATUS);
@@ -521,7 +521,7 @@ static irqreturn_t exynos5_i2c_irq(int irqno, void *dev_id)
 		complete(&i2c->msg_complete);
 	}
 
-	spin_unlock(&i2c->lock);
+	raw_spin_unlock(&i2c->lock);
 
 	return IRQ_HANDLED;
 }
@@ -610,7 +610,7 @@ static void exynos5_i2c_message_start(struct exynos5_i2c *i2c, int stop)
 	 * Enable interrupts before starting the transfer so that we don't
 	 * miss any INT_I2C interrupts.
 	 */
-	spin_lock_irqsave(&i2c->lock, flags);
+	raw_spin_lock_irqsave(&i2c->lock, flags);
 	writel(int_en, i2c->regs + HSI2C_INT_ENABLE);
 
 	if (stop == 1)
@@ -618,7 +618,7 @@ static void exynos5_i2c_message_start(struct exynos5_i2c *i2c, int stop)
 	i2c_auto_conf |= i2c->msg->len;
 	i2c_auto_conf |= HSI2C_MASTER_RUN;
 	writel(i2c_auto_conf, i2c->regs + HSI2C_AUTO_CONF);
-	spin_unlock_irqrestore(&i2c->lock, flags);
+	raw_spin_unlock_irqrestore(&i2c->lock, flags);
 }
 
 static int exynos5_i2c_xfer_msg(struct exynos5_i2c *i2c,
@@ -763,7 +763,7 @@ static int exynos5_i2c_probe(struct platform_device *pdev)
 	/* Clear pending interrupts from u-boot or misc causes */
 	exynos5_i2c_clr_pend_irq(i2c);
 
-	spin_lock_init(&i2c->lock);
+	raw_spin_lock_init(&i2c->lock);
 	init_completion(&i2c->msg_complete);
 
 	i2c->irq = ret = platform_get_irq(pdev, 0);
-- 
2.1.4



From lee.jones at linaro.org  Tue Aug 25 00:55:56 2015
From: lee.jones at linaro.org (Lee Jones)
Date: Tue, 25 Aug 2015 08:55:56 +0100
Subject: [PATCH-v2 2/5] mfd: 88pm800: Update the header file with 32K clk
 related macros
In-Reply-To: <1440442594-3102-4-git-send-email-vaibhav.hiremath@linaro.org>
References: <1440442594-3102-1-git-send-email-vaibhav.hiremath@linaro.org>
 <1440442594-3102-4-git-send-email-vaibhav.hiremath@linaro.org>
Message-ID: <20150825075556.GG19409@x1>

On Tue, 25 Aug 2015, Vaibhav Hiremath wrote:

> Update header file with required macros for 32KHz buffered clock
> output of 88PM800 family of device.
> These macros will be used in clk provider driver.
> 
> Signed-off-by: Vaibhav Hiremath <vaibhav.hiremath at linaro.org>
> ---
>  include/linux/mfd/88pm80x.h | 12 ++++++++++++
>  1 file changed, 12 insertions(+)
> 
> diff --git a/include/linux/mfd/88pm80x.h b/include/linux/mfd/88pm80x.h
> index 122cfd2..0215d5f 100644
> --- a/include/linux/mfd/88pm80x.h
> +++ b/include/linux/mfd/88pm80x.h
> @@ -91,6 +91,7 @@ enum {
>  /* Referance and low power registers */
>  #define PM800_LOW_POWER1		(0x20)
>  #define PM800_LOW_POWER2		(0x21)
> +#define PM800_LOW_POWER2_XO_LJ_EN	BIT(5)

Some people add an extra space for register bits, which I quite like.

So:

#define SOME_REGISTER_ADDRESS	0x123
#define  SOME_BIT_VALUE		BIT(4)

Feel free to use it, or not.

>  #define PM800_LOW_POWER_CONFIG3		(0x22)
>  #define PM800_LDOBK_FREEZE		BIT(7)
> @@ -138,6 +139,13 @@ enum {
>  #define PM800_ALARM			BIT(5)
>  #define PM800_RTC1_USE_XO		BIT(7)
>  
> +#define PM800_32K_OUTX_SEL_MASK		0x3
> +/* 32KHz clk output sel mode */
> +#define PM800_32K_OUTX_SEL_ZERO		0x0
> +#define PM800_32K_OUTX_SEL_INT_32KHZ	0x1
> +#define PM800_32K_OUTX_SEL_XO_32KHZ	0x2
> +#define PM800_32K_OUTX_SEL_HIZ		0x3
> +
>  /* Regulator Control Registers: BUCK1,BUCK5,LDO1 have DVC */
>  
>  /* buck registers */
> @@ -208,6 +216,10 @@ enum {
>  #define PM800_PMOD_MEAS1		0x52
>  #define PM800_PMOD_MEAS2		0x53
>  
> +/* Oscillator control */
> +#define PM800_OSC_CNTRL1		0x50
> +#define PM800_OSC_CNTRL1_OSC_FREERUN_EN	BIT(1)

0x50 goes before 0x52 (and 0x51 if it's there).

>  #define PM800_GPADC0_MEAS1		0x54
>  #define PM800_GPADC0_MEAS2		0x55
>  #define PM800_GPADC1_MEAS1		0x56

-- 
Lee Jones
Linaro STMicroelectronics Landing Team Lead
Linaro.org ? Open source software for ARM SoCs
Follow Linaro: Facebook | Twitter | Blog


From lee.jones at linaro.org  Tue Aug 25 00:58:58 2015
From: lee.jones at linaro.org (Lee Jones)
Date: Tue, 25 Aug 2015 08:58:58 +0100
Subject: [PATCH-v2 3/5] mfd: devicetree: bindings: Add clock subdevice
 node information
In-Reply-To: <1440442594-3102-5-git-send-email-vaibhav.hiremath@linaro.org>
References: <1440442594-3102-1-git-send-email-vaibhav.hiremath@linaro.org>
 <1440442594-3102-5-git-send-email-vaibhav.hiremath@linaro.org>
Message-ID: <20150825075858.GH19409@x1>

On Tue, 25 Aug 2015, Vaibhav Hiremath wrote:

> This patch updates the binding documentation for optional
> clocks node and related information for buffered 32KHz clock.
> 
> Signed-off-by: Vaibhav Hiremath <vaibhav.hiremath at linaro.org>
> Reviewed-by: Krzysztof Kozlowski <k.kozlowski at samsung.com>
> Acked-by: Rob Herring <robh at kernel.org>
> ---
>  Documentation/devicetree/bindings/mfd/88pm800.txt | 27 +++++++++++++++++++++++
>  1 file changed, 27 insertions(+)
> 
> diff --git a/Documentation/devicetree/bindings/mfd/88pm800.txt b/Documentation/devicetree/bindings/mfd/88pm800.txt
> index 2c82fcb..bc6cb02 100644
> --- a/Documentation/devicetree/bindings/mfd/88pm800.txt
> +++ b/Documentation/devicetree/bindings/mfd/88pm800.txt
> @@ -15,6 +15,26 @@ Optional properties :
>    Without this both BUCK1A and BUCK1B operates independently with 3A capacity.
>    (This property is only applicable to 88PM860)
>  
> +Optional nodes:
> +- clocks: 88pm800 family of devices provide multiple buffered 32.768
> +  KHz outputs, so to register these as clocks with common clock framework
> +  instantiate a sub-node named "clocks". It uses the common clock binding
> +  documented in :
> +  [Documentation/devicetree/bindings/clock/clock-bindings.txt]

I tend to prefer relative paths.  Firstly because they're shorter and
more succinct and secondly because if we do eventually move DT out of
the kernel, it will be less hassle to rename each of them.

> +  - #clock-cells: should be 1.
> +
> +  - The following is the list of clocks generated by the controller. Each clock
> +    is assigned an identifier and client nodes use this identifier to specify
> +    the clock which they consume.
> +    Clock		ID           	Devices
> +    ----------------------------------------------------------
> +    pm800_clk32k_1	0		88PM800 and 88PM860
> +    pm800_clk32k_2	1		88PM800 and 88PM860
> +    pm800_clk32k_3	2		88PM800
> +
> +  - compatible: Should be : "marvell,88pm800-clk"
> +
>  88pm80x family of devices consists of varied group of sub-devices:
>  
>  Device		 	Supply Names	 Description
> @@ -22,6 +42,7 @@ Device		 	Supply Names	 Description
>  88pm80x-onkey		:		: On key
>  88pm80x-rtc		:		: RTC
>  88pm80x-regulator	:		: Regulators
> +88pm80x-clk		:		: 32KHz Clk provider

Nit: Alphabetical?

>  Example:
>  
> @@ -33,6 +54,12 @@ Example:
>  		interrupt-controller;
>  		#interrupt-cells = <1>;
>  
> +		pm800clk: clocks {
> +			compatible = "marvell,88pm800-clk";
> +			#clock-cells = <1>;
> +			clock-output-names = "xx", "yy", "zz";
> +		};
> +
>  		regulators {
>  			compatible = "marvell,88pm80x-regulator";
>  

-- 
Lee Jones
Linaro STMicroelectronics Landing Team Lead
Linaro.org ? Open source software for ARM SoCs
Follow Linaro: Facebook | Twitter | Blog


From haojian.zhuang at linaro.org  Tue Aug 25 01:04:45 2015
From: haojian.zhuang at linaro.org (Haojian Zhuang)
Date: Tue, 25 Aug 2015 16:04:45 +0800
Subject: [PATCH v1 3/3] arm64: dts: add Hi6220 mailbox node
In-Reply-To: <20150824124800.GD7139@leverpostej>
References: <1439977055-1747-1-git-send-email-leo.yan@linaro.org>
 <1439977055-1747-4-git-send-email-leo.yan@linaro.org>
 <20150821184059.GB2000@svinekod> <20150824091845.GA28290@leoy-linaro>
 <20150824095144.GA7139@leverpostej> <1440411596.3517.12.camel@linaro.org>
 <20150824124800.GD7139@leverpostej>
Message-ID: <1440489885.10987.26.camel@linaro.org>

On Mon, 2015-08-24 at 13:48 +0100, Mark Rutland wrote:
> > > > > I don't see why you need reserved-memory here, given you're not referring to
> > > > > these regions by phandle anyway.
> > > > 
> > > > - Now we have enabled EFI_STUB, so the memory node will be removed in
> > > >   kernel:
> > > >     efi_entry()
> > > >       \-> allocate_new_fdt_and_exit_boot()
> > > >             \-> update_fdt();
> > > > 
> > > >   Finally in kernel it cannot use memory node to carve out reseved
> > > >   memory regions.
> > > > 
> > > > - On the other hand, DTS's the memory node is to "describes the
> > > >   physical memory layout for the system"; so it's better to use it only
> > > >   to describe the hardware info for memory. We can use reserved-memory
> > > >   to help manage the memory regions which are reserved from software
> > > >   perspective.
> > > 
> > > The fact that you have no-map means that the memory should not be
> > > described to the kernel as mappable in the first place. It's wrong to
> > > place such memory in the memory node, even if listed in reserved-memory.
> > > 
> > > If your EFI memory map describes the memory as mappable, it is wrong.
> > 
> > When kernel is working, kernel will create its own page table based on
> > UEFI memory map. Since it's reserved in DTS file as Leo's patch, it'll
> > be moved to reserved memblock. Why is it wrong?
> 
> That is a _Linux_ detail, not a _UEFI_ detail.
> 
> Anything which only handles UEFI and knows nothing of reserved-memory
> (e.g. GRUB) will be broken and/or break the Linux use of the region, as
> it will happily try to allocate memory in the region (and could even
> decide to reserve it permanently for its own usage).
> 
> If the memory is truly specific to the mailbox, then UEFI needs to know
> that it is reserved as such. If it is not, then it need not be described
> in the DT and can be allocated dynamically by the kernel.

No. We support both UEFI and uboot on hikey. We must reserve these
mailbox buffer in DT. Otherwise, it's a problem to support uboot.
We should only deliver one kernel and one DTB to support both UEFI and
uboot.

And mailbox driver is already upgraded from beginning. Nobody can say
that it won't be upgraded again in the future.

By the way, UEFI is loaded in the upper memory region of hikey. It won't
break anything in linux kernel.
> 
> > In the second, UEFI is firmware. When it's stable, nobody should change
> > it without any reason. These reserved memory are used in mailbox driver.
> > Look. It's driver, so it could be changed at any time. Why do you want
> > to UEFI knowing this memory range? Do you hope UEFI to change when
> > mailbox driver is changed?
> 
> It shouldn't need to change if that memory is truly reserved for the
> sole use of the mailbox. If that's not the case then we have a different
> issue.
> 
> If the memory range to use can be allocated by the driver, then I don't
> see why it should be described in reserved-memory. It certainly should
> not require a no-map attribute.
> 
> Additionally, the driver needs to ensure that the requisite cache
> maintenance takes place prior to the use of the memory region given
> prior agents may have ampped it as cacheable, leaving stale (perhaps
> dirty) lines in the caches.
> 

Since those mailbox buffer is declared as reserved with "no-map"
property, it means that linux kernel won't create the page table of
them.

The meaning of "no-map" is removing it from memory memblock.
setup_arch()
  |
  ---> efi_init() -- Get memory map information from UEFI
  |
  ---> arm64_memblock_init()
  |      |
  |      ---> early_init_fdt_scan_reserved_mem()
  |           Get reserved memory buffer from DT. Split memory
  |           memblock according to reserved buffer.
  ---> paging_init()
         |--> map_mem()
              _Only_ map the discrete memory memblock into kernel
              page table.

>From this working flow, we could know that those mailbox buffers
won't be mapped into kernel page table. So there's no concern on
cache maintenance.
              
> > > > According to upper info, we still need to use reserved-memory node to
> > > > depict the reserved memory regions. i have no knowledge about EFI_STUB,
> > > > so please confirm or correct as needed.
> > > 
> > > If the memory shouldn't be mapped, it should neither be in the memory
> > > node nor EFI memory map (with attributes allowing it to be mapped) to
> > > begin with.
> > 
> > As I said above, kernel will create its own page table. When kernel's
> > page table is working, UEFI's page table is destroying. So the memory
> > won't be mapped twice at the same time. What's wrong?
> > > 
> > > As far as I can see you do not need to use reserved-memory.
> > 
> > 1. Are we talking on the same thing? Leo already mentioned that all
> > memory node in DTB will be destroyed by kernel when EFI_STUB is enabled
> > on arm. Did you read the source code after his reply?
> > And you suggested that Leo to use discrete memory region in DTB. It is
> > really wrong. Kernel only gets memory map information from UEFI, not
> > DTB.
> 
> I did _not_ suggest that Leo use discrete memory. I suggested that
> reserved regions should not be described in the memory node (the same
> premise applying to the UEFI memory map).

I agree that reserved region shouldn't be described in the memory node.
And Leo didn't describe reserved region in memory node too.

> 
> w.r.t. UEFI, please see my comments above. If you're using the UEFI
> memory map, you have to use the UEFI memory map, not the UEFI memory map
> with additional (non-UEFI) caveats applied atop.

The main concern is that we're supporting both UEFI and uboot.
Declaring these reserved buffer in DTB will be a better choice.

> 
> > 2. The working flow is in below.
> >    a. Kernel gets memory map information from UEFI.
> >    b. Kernel loads the memory reserved information from DTB.
> 
> This relies on Linux, and ignores other UEFI clients.

Yes, it's depend on CONFIG_EFI_STUB.

> 
> > 3. Do you mean the reserved-memory is totally wrong? If it's wrong,
> > please submit patches to remove all reserved-memory in linux kernel
> > first.
> 
> I did not say that.
> 
> I said that describing some memory in a memory node, then also
> describing that in reserved-memory with a no-map property was wrong. If
> it's never meant to be mapped then there's no reason for it to be in the
> memory node.

No, it's not never mapped. Leo just wants it to be mapped as
uncacheable in mailbox driver.

If we look at his mailbox node in DT, Leo used these memory regions
in reg property. He wants to use ioremap() in mailbox driver.

> 
> > 4. Again and again. Memory node should be only used to describe the
> > RAM information.
> 
> The memory node describes the memory available to the OS. There are some
> caveats w.r.t. /memreserve/, regions which may be mapped but remain
> unused and so on, but the memory node does generally encode a policy
> that the memory may be used.
> 
> Describing unusable memory in a memory node is pointless, and has an
> adverse effect on clients which don't support reserved-memory. It's
> doubly harmful when that memory should never be mapped.
> 

He didn't declare those buffer in memory node. He only declared it
in reserved-memory node. And it's not never be mapped. He use ioremap()
in the driver.

And I think that Leo could use phandle to reference the reserved buffer
in mailbox node. Then it could be more clear.



From varada at codeaurora.org  Tue Aug 25 01:10:42 2015
From: varada at codeaurora.org (Varadarajan Narayanan)
Date: Tue, 25 Aug 2015 13:40:42 +0530
Subject: [PATCH v3] qcom: ipq40xx: Add basic board/dts support for
 IPQ40XX SoC
In-Reply-To: <20150824224928.GE14330@codeaurora.org>
References: <20150824092813.GA15581@codeaurora.org>
 <20150824224928.GE14330@codeaurora.org>
Message-ID: <20150825081042.GA14028@codeaurora.org>

On Mon, Aug 24, 2015 at 03:49:28PM -0700, Stephen Boyd wrote:
> On 08/24, Varadarajan Narayanan wrote:
> > Add initial dts files and SoC support for IPQ40XX
> >
>
> So far we haven't added any Xs in the model names for our SoC
> support. Even for IPQ806X, we have it as IPQ8064 as the config
> name with IPQ806x in the help text because there's IPQ8062 out
> there. So I guess it should be IPQ4019 or something?

Will rename it as IPQ4019

> > Signed-off-by: Varadarajan Narayanan <varada at codeaurora.org>
> > ---
> > diff --git a/Documentation/devicetree/bindings/qcom.txt b/Documentation/devicetree/bindings/qcom.txt
> > new file mode 100644
> > index 0000000..7d56bd0
> > --- /dev/null
> > +++ b/Documentation/devicetree/bindings/qcom.txt
> > @@ -0,0 +1,16 @@
> > +Qualcomm IPQ device tree bindings
> > +---------------------------------
> > +
> > +System on Chip
> > +
> > +Device tree must specify which SoC it uses, with one of the
> > +following compatible strings
> > +
> > +       "qcom,ipq40xx"
> > +
> > +Platform
> > +
> > +Device tree must specify which Platform it uses, with one of the
> > +following compatible strings
> > +
> > +       "qcom,ipq40xx-r3pc"
>
> This file is not complete and I don't see any other silicon
> vendors doing this, so please drop the entire file.

Ok.

> > diff --git a/arch/arm/boot/dts/qcom-ipq40xx-r3pc.dts b/arch/arm/boot/dts/qcom-ipq40xx-r3pc.dts
> > new file mode 100644
> > index 0000000..7e4e629
> > --- /dev/null
> > +++ b/arch/arm/boot/dts/qcom-ipq40xx-r3pc.dts
> > @@ -0,0 +1,33 @@
> > +/* Copyright (c) 2014, The Linux Foundation. All rights reserved.
> > + *
> > + * This program is free software; you can redistribute it and/or modify
> > + * it under the terms of the GNU General Public License version 2 and
> > + * only 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 "qcom-ipq40xx.dtsi"
> > +
> > +/ {
> > +	model = "Qualcomm Technologies, Inc. IPQ40XX R3PC";
>
> Same here, we should know what model number is on the board.

Ok.

> > +	compatible = "qcom,ipq40xx-r3pc", "qcom,ipq40xx";
> > +
> > +	memory {
> > +		device_type = "memory";
> > +		reg = <0x80000000 0x20000000>; /* 512MB */
> > +	};
>
> Doesn't the bootloader fill the memory node for us? Why do we
> need this?
>
> > +
> > +	chosen {
> > +		bootargs = "root=/dev/ram rw init=/init console=ttyMSM0,115200n8 initrd=0x82000000,0x000E2246";
> > +	};
>
> Please don't add bootargs. Use stdout-path for the console part
> and everything else should be done by the bootloader or is the
> defaults.

Since this is for the emulation platform, we don't have the bootloader.

> > +
> > +	soc {
> > +		serial at 78b0000 {
> > +			status = "ok";
> > +		};
> > +	};
> > +};
> > diff --git a/arch/arm/boot/dts/qcom-ipq40xx.dtsi b/arch/arm/boot/dts/qcom-ipq40xx.dtsi
> > new file mode 100644
> > index 0000000..f572f38
> > --- /dev/null
> > +++ b/arch/arm/boot/dts/qcom-ipq40xx.dtsi
> > @@ -0,0 +1,81 @@
> > +/*
> > + * Copyright (c) 2014, The Linux Foundation. All rights reserved.
> > + *
> > + * This program is free software; you can redistribute it and/or modify
> > + * it under the terms of the GNU General Public License version 2 and
> > + * only 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.
> > + */
> > +
> > +/dts-v1/;
> > +
> > +#include "skeleton.dtsi"
> > +
> > +/ {
> > +	model = "Qualcomm Technologies, Inc. IPQ40XX";
> > +	compatible = "qcom,ipq40xx";
>
> These two should also be specific and drop the Xs. Same goes for
> the file name.

Ok.

> > +	interrupt-parent = <&intc>;
> > +
> > +	cpus {
> > +		#address-cells = <1>;
> > +		#size-cells = <0>;
> > +		cpu at 0 {
> > +			device_type = "cpu";
> > +			compatible = "arm,cortex-a7";
> > +			reg = <0x0>;
> > +		};
> > +
> > +		cpu at 1 {
> > +			device_type = "cpu";
> > +			compatible = "arm,cortex-a7";
> > +			reg = <0x1>;
> > +		};
> > +
> > +		cpu at 2 {
> > +			device_type = "cpu";
> > +			compatible = "arm,cortex-a7";
> > +			reg = <0x2>;
> > +		};
> > +
> > +		cpu at 3 {
> > +			device_type = "cpu";
> > +			compatible = "arm,cortex-a7";
> > +			reg = <0x3>;
> > +		};
> > +	};
> > +
> > +	soc {
> > +		#address-cells = <1>;
> > +		#size-cells = <1>;
> > +		ranges;
> > +		compatible = "simple-bus";
> > +
> > +		intc: interrupt-controller at b000000 {
> > +			compatible = "qcom,msm-qgic2";
> > +			interrupt-controller;
> > +			#interrupt-cells = <3>;
> > +			reg = <0x0b000000 0x1000>,
> > +			<0x0b002000 0x1000>;
> > +		};
> > +
> > +		timer {
>
> This node is not a child of the SoC node. It should be at the
> root level.

Ok.

> > +			compatible = "arm,armv7-timer";
> > +			interrupts = <1 2 0xf08>,
> > +				     <1 3 0xf08>,
> > +				     <1 4 0xf08>,
> > +				     <1 1 0xf08>;
> > +			clock-frequency = <20833333>;
>
> Drop this clock-frequency part if you can. The hardware should
> properly report the frequency.

Cannot drop this. This is the ref-clock frequency. For the
chip it is 48MHz, for emulation is ~20MHz. Similar to
https://git.kernel.org/cgit/linux/kernel/git/torvalds/linux.git/tree/arch/arm/boot/dts/qcom-msm8974.dtsi#n89

> > +		};
> > +
> > +		serial at 78b0000 {
> > +			compatible = "qcom,msm-uartdm-v1.4", "qcom,msm-uartdm";
> > +			reg = <0x78b0000 0x200>;
> > +			interrupts = <0 108 0>;
> > +			status = "disabled";
>
> Don't you need some clocks here?

Yes, will get updated in subsequent patches.

> > +		};
> > +	};
> > +};
> > diff --git a/arch/arm/configs/ipq_defconfig b/arch/arm/configs/ipq_defconfig
> > index 1cabd8b..89bf8ad 100644
> > --- a/arch/arm/configs/ipq_defconfig
> > +++ b/arch/arm/configs/ipq_defconfig
> > @@ -21,6 +21,7 @@ CONFIG_ARCH_QCOM=y
> >  CONFIG_ARCH_MSM8X60=y
> >  CONFIG_ARCH_MSM8960=y
> >  CONFIG_ARCH_MSM8974=y
> > +CONFIG_ARCH_IPQ40XX=y
> >  CONFIG_ARCH_IPQ8064=y
> >  CONFIG_SMP=y
> >  CONFIG_PREEMPT=y
>
> This hunk should be in a separate patch.

Ok.

> > diff --git a/arch/arm/mach-qcom/Kconfig b/arch/arm/mach-qcom/Kconfig
> > index fab49a2..70812aa 100644
> > --- a/arch/arm/mach-qcom/Kconfig
> > +++ b/arch/arm/mach-qcom/Kconfig
> > @@ -22,6 +22,10 @@ config ARCH_MSM8974
> >  	bool "Enable support for MSM8974"
> >  	select HAVE_ARM_ARCH_TIMER
> >
> > +config ARCH_IPQ40XX
> > +	bool "Enable support for IPQ40XX"
> > +	select HAVE_ARM_ARCH_TIMER
> > +
> >  config ARCH_IPQ8064
> >  	bool "Enable support for IPQ806x"
> >  	select CLKSRC_QCOM
> > diff --git a/arch/arm/mach-qcom/board.c b/arch/arm/mach-qcom/board.c
> > index 6d8bbf7..af9e247 100644
> > --- a/arch/arm/mach-qcom/board.c
> > +++ b/arch/arm/mach-qcom/board.c
> > @@ -18,6 +18,7 @@ static const char * const qcom_dt_match[] __initconst = {
> >  	"qcom,apq8064",
> >  	"qcom,apq8074-dragonboard",
> >  	"qcom,apq8084",
> > +	"qcom,ipq40xx",
> >  	"qcom,ipq8062",
> >  	"qcom,ipq8064",
> >  	"qcom,msm8660-surf",
> >
>
> And these two should also go as a separate patch.

Ok.

Thanks
Varada

>
> --
> Qualcomm Innovation Center, Inc. is a member of Code Aurora Forum,
> a Linux Foundation Collaborative Project
>
> _______________________________________________
> linux-arm-kernel mailing list
> linux-arm-kernel at lists.infradead.org
> http://lists.infradead.org/mailman/listinfo/linux-arm-kernel


From haojian.zhuang at linaro.org  Tue Aug 25 01:13:47 2015
From: haojian.zhuang at linaro.org (Haojian Zhuang)
Date: Tue, 25 Aug 2015 16:13:47 +0800
Subject: [PATCH v1 3/3] arm64: dts: add Hi6220 mailbox node
In-Reply-To: <20150824114903.GT10728@bivouac.eciton.net>
References: <1439977055-1747-1-git-send-email-leo.yan@linaro.org>
 <1439977055-1747-4-git-send-email-leo.yan@linaro.org>
 <20150821184059.GB2000@svinekod> <20150824091845.GA28290@leoy-linaro>
 <20150824095144.GA7139@leverpostej> <1440411596.3517.12.camel@linaro.org>
 <20150824114903.GT10728@bivouac.eciton.net>
Message-ID: <1440490427.10987.29.camel@linaro.org>

On Mon, 2015-08-24 at 12:49 +0100, Leif Lindholm wrote:
> On Mon, Aug 24, 2015 at 06:19:56PM +0800, Haojian Zhuang wrote:
> > > If your EFI memory map describes the memory as mappable, it is wrong.
> > 
> > When kernel is working, kernel will create its own page table based on
> > UEFI memory map. Since it's reserved in DTS file as Leo's patch, it'll
> > be moved to reserved memblock. Why is it wrong?
> > 
> > In the second, UEFI is firmware. When it's stable, nobody should change
> > it without any reason.
> 
> Much like the memory map.
> 
> > These reserved memory are used in mailbox driver.
> > Look. It's driver, so it could be changed at any time.
> 
> No, it is a set of regions of memory set aside for use by a different
> master in the system as well as communications with that master.
> 
> The fact that there is a driver somewhere that is aware of this is
> entirely beside the point. All agents in the system must adher to this
> protocol.
> 
> > Why do you want
> > to UEFI knowing this memory range? Do you hope UEFI to change when
> > mailbox driver is changed?
> 
> Yes.
> 
> UEFI is a runtime environment. Having random magic areas not to be
> touched will cause random pieces of software running under it to break
> horribly or break other things horribly.
> Unless you mark them as reserved in the UEFI memory map.
> At which point the Linux kernel will automatically ignore them, and
> the proposed patch is redundant.
> 
> So, yes, if you want a system that can boot reliably, run testsuites
> (like SCT or FWTS), run applications (like fastboot ... or the EFI
> stub kernel itself), then any memory regions that is reserved for
> mailbox communication (or other masters in the system) _must_ be
> marked in the EFI memory map.

1. We need support both UEFI and uboot. So the reserved buffer have to
be declared in DTB since they are used by kernel driver, not UEFI.

2. UEFI just loads grub. It's no time to run any other custom EFI
application.

Regards
Haojian



From linux at arm.linux.org.uk  Tue Aug 25 01:15:56 2015
From: linux at arm.linux.org.uk (Russell King - ARM Linux)
Date: Tue, 25 Aug 2015 09:15:56 +0100
Subject: Prevent list poison values from being mapped by userspace
 processes
In-Reply-To: <55DB16AF.7090607@freebox.fr>
References: <CABXk95C=CpeL4mNmS6-jJ-0bMJf6fawwfs6DM1-p8FctTEFbpw@mail.gmail.com>
 <20150821133043.GV7557@n2100.arm.linux.org.uk>
 <55DB16AF.7090607@freebox.fr>
Message-ID: <20150825081556.GL7557@n2100.arm.linux.org.uk>

On Mon, Aug 24, 2015 at 03:05:51PM +0200, Nicolas Schichan wrote:
> I gave your patch serie a try on ARMv5/kirkwood (backported on a v4.1 kernel)
> and at first I got the following panic just after the kernel transitioned
> to userland (with CONFIG_CPU_SW_DOMAIN_PAN=y):

Ah, damn.  Thanks for testing.  I really need to add some non-ARMv7
platforms to my nightly test rig, but I'm out of physical space to
do that. :p

> I have tracked this to the attempt made by the code in
> arch/arm/mm/abort-ev5t.S to read the fault instruction which in this
> case is in unserspace:
> 
> 	ldreq	r3, [r4]			@ read aborted ARM instruction

There's going to be many more of these... it may be better if I left
the domain enabled when calling into these handlers, and had every
handler do the turn-off itself when it's ready to do so - there's
no point turning off userspace access only to then immediately
re-enable it.

> With the changes above, userland boots fine and attempts to
> dereference LIST_POISON1 from the kernel results the expected "page
> domain fault".
> 
> To test that I mapped LIST_POISON1 from user space via mmap() and
> triggered the fault by reading from /proc/cpu/alignment. I modified the
> code showing /proc/cpu/alignment to access LIST_POISON1. Without your
> patch serie the access to LIST_POISON1 goes through without a hitch.

Great, thanks for the independent testing of its effectiveness.

> Also, when CONFIG_CPU_SW_DOMAIN_PAN is not set, the DACR_INIT constant is
> setup with (domain_val(DOMAIN_USER, DOMAIN_NOACCESS) which will cause the
> kernel to die with a "page domain fault" when running init.

If you don't mind, I'll merge that into the patch adding this so it
doesn't introduce a regression there.

Once I've fixed the abort handler issue, would you mind re-testing
and giving a tested-by attributation please?

-- 
FTTC broadband for 0.8mile line: currently at 10.5Mbps down 400kbps up
according to speedtest.net.


From jonathanh at nvidia.com  Tue Aug 25 01:17:32 2015
From: jonathanh at nvidia.com (Jon Hunter)
Date: Tue, 25 Aug 2015 09:17:32 +0100
Subject: Tegra baseline test results for v4.2-rc8
Message-ID: <55DC249C.5070808@nvidia.com>

Here are some basic Tegra test results for Linux v4.2-rc8.
Logs and other details at:

    https://nvtb.github.io//linux/test_v4.2-rc8/20150823213103/


Test summary
------------

Build: zImage:
    Pass: ( 2/ 2): multi_v7_defconfig, tegra_defconfig

Build: Image:
    Pass: ( 1/ 1): defconfig

Boot to userspace: defconfig:
    Pass: ( 1/ 1): qemu-vexpress64

Boot to userspace: multi_v7_defconfig:
    Pass: ( 4/ 4): tegra114-dalmore-a04, tegra124-jetson-tk1,
		   tegra20-trimslice, tegra30-beaver

Boot to userspace: tegra_defconfig:
    Pass: ( 4/ 4): tegra114-dalmore-a04, tegra124-jetson-tk1,
		   tegra20-trimslice, tegra30-beaver


vmlinux object size
(delta in bytes from test_v4.2-rc7 (2c6625cd545bdd66acff14f3394865d43920a5c7)):
   text     data      bss    total  kernel
     -3        0        0       -3  defconfig
   text     data      bss    total  kernel
  -1151        0        0    -1151  multi_v7_defconfig
 -14778      -64        0   -14842  tegra_defconfig


Boot-time memory difference
(delta in bytes from test_v4.2-rc7 (2c6625cd545bdd66acff14f3394865d43920a5c7))
    avail    rsrvd     high    freed                board              kconfig                  dtb
        .        .        .        .      qemu-vexpress64            defconfig           __internal
        .        .        .       4k tegra114-dalmore-a04   multi_v7_defconfig     tegra114-dalmore
      16k     -16k        .        . tegra114-dalmore-a04      tegra_defconfig     tegra114-dalmore
        .        .        .       4k  tegra124-jetson-tk1   multi_v7_defconfig  tegra124-jetson-tk1
      16k     -16k        .        .  tegra124-jetson-tk1      tegra_defconfig  tegra124-jetson-tk1
        .        .        .       4k    tegra20-trimslice   multi_v7_defconfig    tegra20-trimslice
      16k     -16k        .        .    tegra20-trimslice      tegra_defconfig    tegra20-trimslice
        .        .        .       4k       tegra30-beaver   multi_v7_defconfig       tegra30-beaver
      16k     -16k        .        .       tegra30-beaver      tegra_defconfig       tegra30-beaver


From lee.jones at linaro.org  Tue Aug 25 01:30:33 2015
From: lee.jones at linaro.org (Lee Jones)
Date: Tue, 25 Aug 2015 09:30:33 +0100
Subject: [PATCH-v6 5/6] mfd: 88pm800: Set default interrupt clear method
In-Reply-To: <55DB4A91.9000702@linaro.org>
References: <1436358392-15449-1-git-send-email-vaibhav.hiremath@linaro.org>
 <1436358392-15449-6-git-send-email-vaibhav.hiremath@linaro.org>
 <20150824135422.GF3237@x1> <55DB3627.2030503@linaro.org>
 <20150824155129.GA19409@x1> <55DB4A91.9000702@linaro.org>
Message-ID: <20150825083033.GJ19409@x1>

On Mon, 24 Aug 2015, Vaibhav Hiremath wrote:

> 
> 
> On Monday 24 August 2015 09:21 PM, Lee Jones wrote:
> >On Mon, 24 Aug 2015, Vaibhav Hiremath wrote:
> >
> >>
> >>
> >>On Monday 24 August 2015 07:24 PM, Lee Jones wrote:
> >>>On Wed, 08 Jul 2015, Vaibhav Hiremath wrote:
> >>>
> >>>>As per the spec, bit 1 (INT_CLEAR_MODE) of reg addr 0xe
> >>>>(page 0) controls the method of clearing interrupt
> >>>>status of 88pm800 family of devices;
> >>>>
> >>>>   0: clear on read
> >>>>   1: clear on write
> >>>>
> >>>>If pdata is not coming from board file, then set the
> >>>>default irq clear method to "irq clear on write"
> >>>>
> >>>>Also, as suggested by "Lee Jones" renaming variable field
> >>>>to appropriate name and removed unnecessary field
> >>>>pm80x_chip.irq_mode, using platform_data.irq_clr_method.
> >>>>
> >>>>Signed-off-by: Zhao Ye <zhaoy at marvell.com>
> >>>>Signed-off-by: Vaibhav Hiremath <vaibhav.hiremath at linaro.org>
> >>>>Reviewed-by: Krzysztof Kozlowski <k.kozlowski at samsung.com>
> >>>>---
> >>>>  drivers/mfd/88pm800.c       | 15 ++++++++++-----
> >>>>  include/linux/mfd/88pm80x.h |  9 +++++++--
> >>>>  2 files changed, 17 insertions(+), 7 deletions(-)
> >>>
> >>>[...]
> >>>
> >>>>+#define PM800_WAKEUP2_INT_READ_CLEAR	(0 << 1)
> >>>>+#define PM800_WAKEUP2_INT_WRITE_CLEAR	(1 << 1)
> >>>
> >>>Use BIT().
> >>>
> >>>>+/* Used by irq_clr_method */
> >>>>+#define PM800_IRQ_CLR_ON_READ	0
> >>>>+#define PM800_IRQ_CLR_ON_WRITE	1
> >>>
> >>>>-	int irq_mode;		/* Clear interrupt by read/write(0/1) */
> >>>>+	bool irq_clr_method;		/* Clear interrupt by read/write(0/1) */
> >>>
> >>>>+	irq_clr_mode = pdata->irq_clr_method == PM800_IRQ_CLR_ON_WRITE ?
> >>>>+		PM800_WAKEUP2_INT_WRITE_CLEAR : PM800_WAKEUP2_INT_READ_CLEAR;
> >>>>+	ret = regmap_update_bits(map, PM800_WAKEUP2, mask, irq_clr_mode);
> >>>
> >>>This is pretty convoluted.
> >>>
> >>>For starters you're abusing the 'bool' type here.  Bool is either
> >>>'true' or 'false', so at the very least you should rename
> >>>'irq_clr_method' to 'irq_clr_on_write'.
> >>>
> >>>Then you can do:
> >>>
> >>>	irq_clr_mode = pdata->irq_clr_on_write ?
> >>>		PM800_WAKEUP2_INT_WRITE_CLEAR : PM800_WAKEUP2_INT_READ_CLEAR;
> >>>
> >>
> >>We have discussed on this, and went back-n-forth.
> >>I think if I remember correctly, one of the version was using
> >>true/false then we decided to rename it to relevant macro.
> >>
> >>If I am not wrong V4 version of this series is exactly same as what you
> >>are referring to.
> >
> >Right.  I made a few suggestions which vary in usefulness depending on
> >how you plan to implement all of this.  Unfortunately this is a bit of
> >a bastardised version where some of it make sense and other parts
> >could do with some improvement.
> >
> 
> This so called "basterdised version could have been avoided :)
> 
> V2 version itself was clean and ready. It just got dragged into
> multiple iterations.

Don't kid yourself.  There were still improvements to be made.

> >>>However, what I suggest you really do is share
> >>>PM800_WAKEUP2_INT_{READ,WRITE}_CLEAR with platform data and just pass
> >>>the value through directly.
> >>>
> >>
> >>I think we discussed about this also, and the reason I recall here is,
> >>
> >>we may need to control this from DT in the future so we decided to keep
> >>it boolean in platform_data and have simple check before writing to
> >>register.
> >>
> >>And I think that was also another reason we introduced
> >>
> >>/* Used by irq_clr_method */
> >>#define PM800_IRQ_CLR_ON_READ   0
> >>#define PM800_IRQ_CLR_ON_WRITE  1
> >
> >I think these are still required.  So it would look like this:
> >
> 
> NO. I think you are confused here,
> We have two different macros playing around here,
> 
> 
> +/* Used by irq_clr_method */
> +#define PM800_IRQ_CLR_ON_READ	0
> +#define PM800_IRQ_CLR_ON_WRITE	1
> 
> /* Used to write to register */
> +#define PM800_WAKEUP2_INT_READ_CLEAR		(0 << 1)
> +#define PM800_WAKEUP2_INT_WRITE_CLEAR		(1 << 1)

I know.  I used both of them *correctly* in my example below.  No
confusion here.

> >== Platform data ==
> >
> >struct pdata {
> >   bool clear_irq_on_write;
> >};
> >
> >pdata->clear_irq_on_write = PM800_IRQ_CLR_ON_{READ,WRITE};
> >
> >== Driver ==
> >
> >irq_clr_mode = pdata->clear_irq_on_write ?
> >                  PM800_WAKEUP2_INT_WRITE_CLEAR : PM800_WAKEUP2_INT_READ_CLEAR;
> >regmap_update_bits(map, PM800_WAKEUP2, mask, irq_clr_mode);
> >
> 
> Please check V2, which is exactly same as above.
> 
> https://patchwork.kernel.org/patch/6627781/
> 
> 
> If you are OK with it, I will spin another version and submit it.

If you can't use the value directly, which if you want to pull the
value from DT you can't, then either use the method above, or
something like this might be better:

int clear_on_write = 0;

if (pdata->clear_irq_on_write)
   clear_on_write = PM800_WAKEUP2_INT_WRITE_CLEAR;

.. this way you only need to add one new define and you can drop
PM800_WAKEUP2_INT_READ_CLEAR altogether.  This is better, because it
will aid you to move to the BIT() macro easier (there is no BIT()
value for shifting 0's).

-- 
Lee Jones
Linaro STMicroelectronics Landing Team Lead
Linaro.org ? Open source software for ARM SoCs
Follow Linaro: Facebook | Twitter | Blog


From vaibhav.hiremath at linaro.org  Tue Aug 25 01:31:02 2015
From: vaibhav.hiremath at linaro.org (Vaibhav Hiremath)
Date: Tue, 25 Aug 2015 14:01:02 +0530
Subject: [PATCH-v2 5/5] mfd: 88pm800: Add support for clk subdevice
In-Reply-To: <55DBFC40.3010603@samsung.com>
References: <1440442594-3102-1-git-send-email-vaibhav.hiremath@linaro.org>
 <1440442594-3102-7-git-send-email-vaibhav.hiremath@linaro.org>
 <55DBFC40.3010603@samsung.com>
Message-ID: <55DC27C6.3020500@linaro.org>



On Tuesday 25 August 2015 10:55 AM, Krzysztof Kozlowski wrote:
> On 25.08.2015 03:56, Vaibhav Hiremath wrote:
>> This patch adds mfd_cell/clk-subdevice for 88PM800 MFD
>> (and family of devices).
>>
>> Signed-off-by: Vaibhav Hiremath <vaibhav.hiremath at linaro.org>
>> ---
>>   drivers/mfd/88pm800.c | 25 +++++++++++++++++++++++++
>>   1 file changed, 25 insertions(+)
>>
>> diff --git a/drivers/mfd/88pm800.c b/drivers/mfd/88pm800.c
>> index c4e097d..a928eed 100644
>> --- a/drivers/mfd/88pm800.c
>> +++ b/drivers/mfd/88pm800.c
>> @@ -173,6 +173,14 @@ static const struct mfd_cell regulator_devs[] = {
>>   	},
>>   };
>>
>> +static struct mfd_cell clk_devs[] = {
>> +	{
>> +		.name = "88pm80x-clk",
>> +		.of_compatible = "marvell,88pm800-clk",
>> +		.id = -1,
>
> The "-1" here stands for PLATFORM_DEVID_NONE?
>

Yes,

But it is rarely used in the kernel. so was reluctant to use and
decided to follow existing implementation.

Thanks,
Vaibhav


From vaibhav.hiremath at linaro.org  Tue Aug 25 01:32:07 2015
From: vaibhav.hiremath at linaro.org (Vaibhav Hiremath)
Date: Tue, 25 Aug 2015 14:02:07 +0530
Subject: [PATCH-v3] mfd: 88pm80x: Add 88pm860 chip type support
In-Reply-To: <20150825063825.GE27431@sirena.org.uk>
References: <1437393151-5362-1-git-send-email-vaibhav.hiremath@linaro.org>
 <55DAC179.2060802@linaro.org> <20150825063825.GE27431@sirena.org.uk>
Message-ID: <55DC2807.5020202@linaro.org>



On Tuesday 25 August 2015 12:08 PM, Mark Brown wrote:
> On Mon, Aug 24, 2015 at 12:32:17PM +0530, Vaibhav Hiremath wrote:
>> On Monday 20 July 2015 05:22 PM, Vaibhav Hiremath wrote:
>>> Add chip identification support for 88PM860 device
>>> to the pm80x_chip_mapping table.
>
>> Last update/understanding which I have on this patch is,
>>
>> Lee is OK with taking this patch from regulator tree.
>> Lee please let me know if you think otherwise.
>>
>> With this patch in, the build dependency will go away.
>>
>> Request to pick this patch into your topic/88pm800 branch and run build
>> test.
>
> Please don't send content free pings, they just waste time.  I can't
> review or apply content free pings.  Please submit patches following the
> process in SubmittingPatches.
>
> The chances are I deleted this mail unread since it is a MFD patch...
>

Hmmm Ok,

Resending now...

Thanks,
Vaibhav


From vaibhav.hiremath at linaro.org  Tue Aug 25 01:38:26 2015
From: vaibhav.hiremath at linaro.org (Vaibhav Hiremath)
Date: Tue, 25 Aug 2015 14:08:26 +0530
Subject: [PATCH-v2 5/5] mfd: 88pm800: Add support for clk subdevice
In-Reply-To: <20150825074924.GD19409@x1>
References: <1440442594-3102-1-git-send-email-vaibhav.hiremath@linaro.org>
 <1440442594-3102-7-git-send-email-vaibhav.hiremath@linaro.org>
 <55DBFC40.3010603@samsung.com> <20150825074924.GD19409@x1>
Message-ID: <55DC2982.5010906@linaro.org>



On Tuesday 25 August 2015 01:19 PM, Lee Jones wrote:
> On Tue, 25 Aug 2015, Krzysztof Kozlowski wrote:
>
>> On 25.08.2015 03:56, Vaibhav Hiremath wrote:
>>> This patch adds mfd_cell/clk-subdevice for 88PM800 MFD
>>> (and family of devices).
>>>
>>> Signed-off-by: Vaibhav Hiremath <vaibhav.hiremath at linaro.org>
>>> ---
>>>   drivers/mfd/88pm800.c | 25 +++++++++++++++++++++++++
>>>   1 file changed, 25 insertions(+)
>>>
>>> diff --git a/drivers/mfd/88pm800.c b/drivers/mfd/88pm800.c
>>> index c4e097d..a928eed 100644
>>> --- a/drivers/mfd/88pm800.c
>>> +++ b/drivers/mfd/88pm800.c
>>> @@ -173,6 +173,14 @@ static const struct mfd_cell regulator_devs[] = {
>>>   	},
>>>   };
>>>
>>> +static struct mfd_cell clk_devs[] = {
>>> +	{
>>> +		.name = "88pm80x-clk",
>>> +		.of_compatible = "marvell,88pm800-clk",
>>> +		.id = -1,
>>
>> The "-1" here stands for PLATFORM_DEVID_NONE?
>
> Right.  Please use the define, but use it in the mfd_add_devices()
> call, rather than individual cells.
>

Ok,

Thanks,
Vaibhav


From vaibhav.hiremath at linaro.org  Tue Aug 25 01:41:53 2015
From: vaibhav.hiremath at linaro.org (Vaibhav Hiremath)
Date: Tue, 25 Aug 2015 14:11:53 +0530
Subject: [PATCH-v2 1/5] mfd: 88pm800: Fix tabbing issue
In-Reply-To: <20150825075121.GE19409@x1>
References: <1440442594-3102-1-git-send-email-vaibhav.hiremath@linaro.org>
 <1440442594-3102-2-git-send-email-vaibhav.hiremath@linaro.org>
 <20150825075121.GE19409@x1>
Message-ID: <55DC2A51.6090008@linaro.org>



On Tuesday 25 August 2015 01:21 PM, Lee Jones wrote:
> On Tue, 25 Aug 2015, Vaibhav Hiremath wrote:
>
>> Driver had coding style issues where spaces were used instead
>> of tabs. This patch fixes them all.
>
> That's not all it's doing though is it?
>

Yes, its just tabbing related fixes.


> Please describe all of your changes.
>
>> Signed-off-by: Vaibhav Hiremath <vaibhav.hiremath at linaro.org>
>> ---
>>   drivers/mfd/88pm800.c | 125 ++++++++++++++++++++++++--------------------------
>>   1 file changed, 61 insertions(+), 64 deletions(-)
>>
>> diff --git a/drivers/mfd/88pm800.c b/drivers/mfd/88pm800.c
>> index f104a32..c4e097d 100644
>> --- a/drivers/mfd/88pm800.c
>> +++ b/drivers/mfd/88pm800.c
>> @@ -30,55 +30,55 @@
>>   #include <linux/of_device.h>
>>
>>   /* Interrupt Registers */
>> -#define PM800_INT_STATUS1		(0x05)
>> +#define PM800_INT_STATUS1		0x05
>>   #define PM800_ONKEY_INT_STS1		(1 << 0)
>>   #define PM800_EXTON_INT_STS1		(1 << 1)
>> -#define PM800_CHG_INT_STS1			(1 << 2)
>> -#define PM800_BAT_INT_STS1			(1 << 3)
>> -#define PM800_RTC_INT_STS1			(1 << 4)
>> +#define PM800_CHG_INT_STS1		(1 << 2)
>> +#define PM800_BAT_INT_STS1		(1 << 3)
>> +#define PM800_RTC_INT_STS1		(1 << 4)
>>   #define PM800_CLASSD_OC_INT_STS1	(1 << 5)
>
> These should all be replaced by BIT().
>
> Please fix the whole file.

Will do.

Thanks,
Vaibhav


From daniel at ffwll.ch  Tue Aug 25 01:44:23 2015
From: daniel at ffwll.ch (Daniel Vetter)
Date: Tue, 25 Aug 2015 10:44:23 +0200
Subject: [PATCH v2 3/7] drm/vc4: Add KMS support for Raspberry Pi.
In-Reply-To: <1439934848-7196-4-git-send-email-eric@anholt.net>
References: <1439934848-7196-1-git-send-email-eric@anholt.net>
 <1439934848-7196-4-git-send-email-eric@anholt.net>
Message-ID: <20150825084423.GU20434@phenom.ffwll.local>

On Tue, Aug 18, 2015 at 02:54:04PM -0700, Eric Anholt wrote:
> This is the start of a full VC4 driver.  Right now this just supports
> configuring the display using a pre-existing video mode (because
> changing the pixel clock isn't available yet, and doesn't work when it
> is).  However, this is enough for fbcon and bringing up X using
> xf86-video-modesetting.
> 
> Signed-off-by: Eric Anholt <eric at anholt.net>
> ---
> 
> v2: Drop FB_HELPER select thanks to Archit's patches.  Do manual init
>     ordering instead of using the .load hook.  Structure registration
>     more like tegra's, but still using the typical "component" code.
>     Drop no-op hooks for atomic_begin and mode_fixup() now that
>     they're optional.  Drop sentinel in Makefile.  Fix minor style
>     nits I noticed on another reread.

fwiw Acked-by: Daniel Vetter <daniel.vetter at ffwll.ch> since Eric has done
all the changes I requested - simply forgot to add that in my earlier
review.

No full r-b since I don't have a clue about the hw (and didn't take a
close look at the hw touching code hence).

Cheers, Daniel

> 
>  drivers/gpu/drm/Kconfig           |   2 +
>  drivers/gpu/drm/Makefile          |   1 +
>  drivers/gpu/drm/vc4/Kconfig       |  13 +
>  drivers/gpu/drm/vc4/Makefile      |  17 +
>  drivers/gpu/drm/vc4/vc4_bo.c      |  52 ++++
>  drivers/gpu/drm/vc4/vc4_crtc.c    | 565 ++++++++++++++++++++++++++++++++++
>  drivers/gpu/drm/vc4/vc4_debugfs.c |  38 +++
>  drivers/gpu/drm/vc4/vc4_drv.c     | 271 ++++++++++++++++
>  drivers/gpu/drm/vc4/vc4_drv.h     | 120 ++++++++
>  drivers/gpu/drm/vc4/vc4_hdmi.c    | 633 ++++++++++++++++++++++++++++++++++++++
>  drivers/gpu/drm/vc4/vc4_hvs.c     | 161 ++++++++++
>  drivers/gpu/drm/vc4/vc4_kms.c     |  84 +++++
>  drivers/gpu/drm/vc4/vc4_plane.c   | 320 +++++++++++++++++++
>  drivers/gpu/drm/vc4/vc4_regs.h    | 562 +++++++++++++++++++++++++++++++++
>  14 files changed, 2839 insertions(+)
>  create mode 100644 drivers/gpu/drm/vc4/Kconfig
>  create mode 100644 drivers/gpu/drm/vc4/Makefile
>  create mode 100644 drivers/gpu/drm/vc4/vc4_bo.c
>  create mode 100644 drivers/gpu/drm/vc4/vc4_crtc.c
>  create mode 100644 drivers/gpu/drm/vc4/vc4_debugfs.c
>  create mode 100644 drivers/gpu/drm/vc4/vc4_drv.c
>  create mode 100644 drivers/gpu/drm/vc4/vc4_drv.h
>  create mode 100644 drivers/gpu/drm/vc4/vc4_hdmi.c
>  create mode 100644 drivers/gpu/drm/vc4/vc4_hvs.c
>  create mode 100644 drivers/gpu/drm/vc4/vc4_kms.c
>  create mode 100644 drivers/gpu/drm/vc4/vc4_plane.c
>  create mode 100644 drivers/gpu/drm/vc4/vc4_regs.h
> 
> diff --git a/drivers/gpu/drm/Kconfig b/drivers/gpu/drm/Kconfig
> index 06ae500..19bb0db 100644
> --- a/drivers/gpu/drm/Kconfig
> +++ b/drivers/gpu/drm/Kconfig
> @@ -260,3 +260,5 @@ source "drivers/gpu/drm/sti/Kconfig"
>  source "drivers/gpu/drm/amd/amdkfd/Kconfig"
>  
>  source "drivers/gpu/drm/imx/Kconfig"
> +
> +source "drivers/gpu/drm/vc4/Kconfig"
> diff --git a/drivers/gpu/drm/Makefile b/drivers/gpu/drm/Makefile
> index 8858510..283ed8e 100644
> --- a/drivers/gpu/drm/Makefile
> +++ b/drivers/gpu/drm/Makefile
> @@ -42,6 +42,7 @@ obj-$(CONFIG_DRM_MGA)	+= mga/
>  obj-$(CONFIG_DRM_I810)	+= i810/
>  obj-$(CONFIG_DRM_I915)  += i915/
>  obj-$(CONFIG_DRM_MGAG200) += mgag200/
> +obj-$(CONFIG_DRM_VC4)  += vc4/
>  obj-$(CONFIG_DRM_CIRRUS_QEMU) += cirrus/
>  obj-$(CONFIG_DRM_SIS)   += sis/
>  obj-$(CONFIG_DRM_SAVAGE)+= savage/
> diff --git a/drivers/gpu/drm/vc4/Kconfig b/drivers/gpu/drm/vc4/Kconfig
> new file mode 100644
> index 0000000..e810ef7
> --- /dev/null
> +++ b/drivers/gpu/drm/vc4/Kconfig
> @@ -0,0 +1,13 @@
> +config DRM_VC4
> +	tristate "Broadcom VC4 Graphics"
> +	depends on ARCH_BCM2835
> +	depends on DRM
> +	select DRM_KMS_HELPER
> +	select DRM_KMS_CMA_HELPER
> +	help
> +	  Choose this option if you have a system that has a Broadcom
> +	  VC4 GPU, such as the Raspberry Pi or other BCM2708/BCM2835.
> +
> +	  This driver requires that "avoid_warnings=2" be present in
> +	  the config.txt for the firmware, to keep it from smashing
> +	  our display setup.
> diff --git a/drivers/gpu/drm/vc4/Makefile b/drivers/gpu/drm/vc4/Makefile
> new file mode 100644
> index 0000000..32b4f9c
> --- /dev/null
> +++ b/drivers/gpu/drm/vc4/Makefile
> @@ -0,0 +1,17 @@
> +ccflags-y := -Iinclude/drm
> +
> +# Please keep these build lists sorted!
> +
> +# core driver code
> +vc4-y := \
> +	vc4_bo.o \
> +	vc4_crtc.o \
> +	vc4_drv.o \
> +	vc4_kms.o \
> +	vc4_hdmi.o \
> +	vc4_hvs.o \
> +	vc4_plane.o
> +
> +vc4-$(CONFIG_DEBUG_FS) += vc4_debugfs.o
> +
> +obj-$(CONFIG_DRM_VC4)  += vc4.o
> diff --git a/drivers/gpu/drm/vc4/vc4_bo.c b/drivers/gpu/drm/vc4/vc4_bo.c
> new file mode 100644
> index 0000000..ab9f510
> --- /dev/null
> +++ b/drivers/gpu/drm/vc4/vc4_bo.c
> @@ -0,0 +1,52 @@
> +/*
> + *  Copyright ? 2015 Broadcom
> + *
> + * 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.
> + */
> +
> +/* DOC: VC4 GEM BO management support.
> + *
> + * The VC4 GPU architecture (both scanout and rendering) has direct
> + * access to system memory with no MMU in between.  To support it, we
> + * use the GEM CMA helper functions to allocate contiguous ranges of
> + * physical memory for our BOs.
> + */
> +
> +#include "vc4_drv.h"
> +
> +struct vc4_bo *vc4_bo_create(struct drm_device *dev, size_t size)
> +{
> +	struct drm_gem_cma_object *cma_obj;
> +
> +	cma_obj = drm_gem_cma_create(dev, size);
> +	if (IS_ERR(cma_obj))
> +		return NULL;
> +	else
> +		return to_vc4_bo(&cma_obj->base);
> +}
> +
> +int vc4_dumb_create(struct drm_file *file_priv,
> +		    struct drm_device *dev,
> +		    struct drm_mode_create_dumb *args)
> +{
> +	int min_pitch = DIV_ROUND_UP(args->width * args->bpp, 8);
> +	struct vc4_bo *bo = NULL;
> +	int ret;
> +
> +	if (args->pitch < min_pitch)
> +		args->pitch = min_pitch;
> +
> +	if (args->size < args->pitch * args->height)
> +		args->size = args->pitch * args->height;
> +
> +	bo = vc4_bo_create(dev, roundup(args->size, PAGE_SIZE));
> +	if (!bo)
> +		return -ENOMEM;
> +
> +	ret = drm_gem_handle_create(file_priv, &bo->base.base, &args->handle);
> +	drm_gem_object_unreference_unlocked(&bo->base.base);
> +
> +	return ret;
> +}
> diff --git a/drivers/gpu/drm/vc4/vc4_crtc.c b/drivers/gpu/drm/vc4/vc4_crtc.c
> new file mode 100644
> index 0000000..2c70faf
> --- /dev/null
> +++ b/drivers/gpu/drm/vc4/vc4_crtc.c
> @@ -0,0 +1,565 @@
> +/*
> + * Copyright (C) 2015 Broadcom
> + *
> + * 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.
> + */
> +
> +/**
> + * DOC: VC4 CRTC module
> + *
> + * In VC4, the Pixel Valve is what most closely corresponds to the
> + * DRM's concept of a CRTC.  The PV generates video timings from the
> + * pixel clock and its configuration.
> + *
> + * However, the DRM CRTC also collects the configuration of all the
> + * DRM planes attached to it.  As a result, this file also manages
> + * setup of the VC4 HVS's display elements on the CRTC.
> + */
> +
> +#include "drm_atomic_helper.h"
> +#include "drm_crtc_helper.h"
> +#include "linux/clk.h"
> +#include "linux/component.h"
> +#include "vc4_drv.h"
> +#include "vc4_regs.h"
> +
> +#define CRTC_WRITE(offset, val) writel(val, vc4_crtc->regs + (offset))
> +#define CRTC_READ(offset) readl(vc4_crtc->regs + (offset))
> +
> +#define CRTC_REG(reg) { reg, #reg }
> +static const struct {
> +	u32 reg;
> +	const char *name;
> +} crtc_regs[] = {
> +	CRTC_REG(PV_CONTROL),
> +	CRTC_REG(PV_V_CONTROL),
> +	CRTC_REG(PV_VSYNCD),
> +	CRTC_REG(PV_HORZA),
> +	CRTC_REG(PV_HORZB),
> +	CRTC_REG(PV_VERTA),
> +	CRTC_REG(PV_VERTB),
> +	CRTC_REG(PV_VERTA_EVEN),
> +	CRTC_REG(PV_VERTB_EVEN),
> +	CRTC_REG(PV_INTEN),
> +	CRTC_REG(PV_INTSTAT),
> +	CRTC_REG(PV_STAT),
> +	CRTC_REG(PV_HACT_ACT),
> +};
> +
> +static void vc4_crtc_dump_regs(struct vc4_crtc *vc4_crtc)
> +{
> +	int i;
> +
> +	for (i = 0; i < ARRAY_SIZE(crtc_regs); i++) {
> +		DRM_INFO("0x%04x (%s): 0x%08x\n",
> +			 crtc_regs[i].reg, crtc_regs[i].name,
> +			 CRTC_READ(crtc_regs[i].reg));
> +	}
> +}
> +
> +#ifdef CONFIG_DEBUG_FS
> +int vc4_crtc_debugfs_regs(struct seq_file *m, void *unused)
> +{
> +	struct drm_info_node *node = (struct drm_info_node *) m->private;
> +	struct drm_device *dev = node->minor->dev;
> +	int crtc_index = (uintptr_t)node->info_ent->data;
> +	struct drm_crtc *crtc;
> +	struct vc4_crtc *vc4_crtc;
> +	int i;
> +
> +	i = 0;
> +	list_for_each_entry(crtc, &dev->mode_config.crtc_list, head) {
> +		if (i == crtc_index)
> +			break;
> +		i++;
> +	}
> +	if (!crtc)
> +		return 0;
> +	vc4_crtc = to_vc4_crtc(crtc);
> +
> +	for (i = 0; i < ARRAY_SIZE(crtc_regs); i++) {
> +		seq_printf(m, "%s (0x%04x): 0x%08x\n",
> +			   crtc_regs[i].name, crtc_regs[i].reg,
> +			   CRTC_READ(crtc_regs[i].reg));
> +	}
> +
> +	return 0;
> +}
> +#endif
> +
> +static void vc4_crtc_destroy(struct drm_crtc *crtc)
> +{
> +	drm_crtc_cleanup(crtc);
> +}
> +
> +static u32 vc4_get_fifo_full_level(u32 format)
> +{
> +	static const u32 fifo_len_bytes = 64;
> +	static const u32 hvs_latency_pix = 6;
> +
> +	switch (format) {
> +	case PV_CONTROL_FORMAT_DSIV_16:
> +	case PV_CONTROL_FORMAT_DSIC_16:
> +		return fifo_len_bytes - 2 * hvs_latency_pix;
> +	case PV_CONTROL_FORMAT_DSIV_18:
> +		return fifo_len_bytes - 14;
> +	case PV_CONTROL_FORMAT_24:
> +	case PV_CONTROL_FORMAT_DSIV_24:
> +	default:
> +		return fifo_len_bytes - 3 * hvs_latency_pix;
> +	}
> +}
> +
> +static void vc4_crtc_mode_set_nofb(struct drm_crtc *crtc)
> +{
> +	struct vc4_crtc *vc4_crtc = to_vc4_crtc(crtc);
> +	struct drm_crtc_state *state = crtc->state;
> +	struct drm_display_mode *mode = &state->adjusted_mode;
> +	u32 vactive = (mode->vdisplay >>
> +		       ((mode->flags & DRM_MODE_FLAG_INTERLACE) ? 1 : 0));
> +	u32 format = PV_CONTROL_FORMAT_24;
> +	bool debug_dump_regs = false;
> +
> +	if (debug_dump_regs) {
> +		DRM_INFO("CRTC %d regs before:\n", drm_crtc_index(crtc));
> +		vc4_crtc_dump_regs(vc4_crtc);
> +	}
> +
> +	/* This is where we would set the pixel clock. */
> +
> +	/* Reset the PV fifo. */
> +	CRTC_WRITE(PV_CONTROL, 0);
> +	CRTC_WRITE(PV_CONTROL, PV_CONTROL_FIFO_CLR | PV_CONTROL_EN);
> +	CRTC_WRITE(PV_CONTROL, 0);
> +
> +	CRTC_WRITE(PV_HORZA,
> +		   VC4_SET_FIELD(mode->htotal - mode->hsync_end,
> +				 PV_HORZA_HBP) |
> +		   VC4_SET_FIELD(mode->hsync_end - mode->hsync_start,
> +				 PV_HORZA_HSYNC));
> +	CRTC_WRITE(PV_HORZB,
> +		   VC4_SET_FIELD(mode->hsync_start - mode->hdisplay,
> +				 PV_HORZB_HFP) |
> +		   VC4_SET_FIELD(mode->hdisplay, PV_HORZB_HACTIVE));
> +
> +	CRTC_WRITE(PV_VERTA,
> +		   VC4_SET_FIELD(mode->vtotal - mode->vsync_end,
> +				 PV_VERTA_VBP) |
> +		   VC4_SET_FIELD(mode->vsync_end - mode->vsync_start,
> +				 PV_VERTA_VSYNC));
> +	CRTC_WRITE(PV_VERTB,
> +		   VC4_SET_FIELD(mode->vsync_start - mode->vdisplay,
> +				 PV_VERTB_VFP) |
> +		   VC4_SET_FIELD(vactive, PV_VERTB_VACTIVE));
> +	if (mode->flags & DRM_MODE_FLAG_INTERLACE) {
> +		/* Write PV_VERTA_EVEN/VERTB_EVEN */
> +	}
> +
> +	CRTC_WRITE(PV_HACT_ACT, mode->hdisplay);
> +
> +	CRTC_WRITE(PV_V_CONTROL,
> +		   PV_VCONTROL_CONTINUOUS);
> +
> +	CRTC_WRITE(PV_CONTROL,
> +		   VC4_SET_FIELD(format, PV_CONTROL_FORMAT) |
> +		   VC4_SET_FIELD(vc4_get_fifo_full_level(format),
> +				 PV_CONTROL_FIFO_LEVEL) |
> +		   PV_CONTROL_CLR_AT_START |
> +		   PV_CONTROL_TRIGGER_UNDERFLOW |
> +		   PV_CONTROL_WAIT_HSTART |
> +		   VC4_SET_FIELD(PV_CONTROL_CLK_SELECT_DPI_SMI_HDMI,
> +				 PV_CONTROL_CLK_SELECT) |
> +		   PV_CONTROL_FIFO_CLR |
> +		   PV_CONTROL_EN);
> +
> +	if (debug_dump_regs) {
> +		DRM_INFO("CRTC %d regs after:\n", drm_crtc_index(crtc));
> +		vc4_crtc_dump_regs(vc4_crtc);
> +	}
> +}
> +
> +static void require_hvs_enabled(struct drm_device *dev)
> +{
> +	struct vc4_dev *vc4 = to_vc4_dev(dev);
> +
> +	WARN_ON_ONCE((HVS_READ(SCALER_DISPCTRL) & SCALER_DISPCTRL_ENABLE) !=
> +		     SCALER_DISPCTRL_ENABLE);
> +}
> +
> +static void vc4_crtc_disable(struct drm_crtc *crtc)
> +{
> +	struct drm_device *dev = crtc->dev;
> +	struct vc4_dev *vc4 = to_vc4_dev(dev);
> +	struct vc4_crtc *vc4_crtc = to_vc4_crtc(crtc);
> +
> +	require_hvs_enabled(dev);
> +
> +	CRTC_WRITE(PV_V_CONTROL,
> +		   CRTC_READ(PV_V_CONTROL) & ~PV_VCONTROL_VIDEN);
> +	while (CRTC_READ(PV_V_CONTROL) & PV_VCONTROL_VIDEN)
> +		cpu_relax();
> +
> +	/* Without a wait here, we end up with a black screen. */
> +	msleep(30);
> +
> +	if (HVS_READ(SCALER_DISPCTRLX(vc4_crtc->channel)) &
> +	    SCALER_DISPCTRLX_ENABLE) {
> +		HVS_WRITE(SCALER_DISPCTRLX(vc4_crtc->channel),
> +			  SCALER_DISPCTRLX_RESET);
> +
> +		/* While the docs say that reset is self-clearing, it
> +		 * seems it doesn't actually.
> +		 */
> +		HVS_WRITE(SCALER_DISPCTRLX(vc4_crtc->channel), 0);
> +	}
> +
> +	/* Once we leave, the scaler should be disabled and its fifo empty. */
> +
> +	WARN_ON_ONCE(HVS_READ(SCALER_DISPCTRLX(vc4_crtc->channel)) &
> +		     SCALER_DISPCTRLX_RESET);
> +
> +	WARN_ON_ONCE(VC4_GET_FIELD(HVS_READ(SCALER_DISPSTATX(vc4_crtc->channel)),
> +				   SCALER_DISPSTATX_MODE) !=
> +		     SCALER_DISPSTATX_MODE_DISABLED);
> +
> +	WARN_ON_ONCE((HVS_READ(SCALER_DISPSTATX(vc4_crtc->channel)) &
> +		      (SCALER_DISPSTATX_FULL | SCALER_DISPSTATX_EMPTY)) !=
> +		     SCALER_DISPSTATX_EMPTY);
> +}
> +
> +static void vc4_crtc_enable(struct drm_crtc *crtc)
> +{
> +	struct drm_device *dev = crtc->dev;
> +	struct vc4_dev *vc4 = to_vc4_dev(dev);
> +	struct vc4_crtc *vc4_crtc = to_vc4_crtc(crtc);
> +	struct drm_crtc_state *state = crtc->state;
> +	struct drm_display_mode *mode = &state->adjusted_mode;
> +
> +	require_hvs_enabled(dev);
> +
> +	/* Turn on the scaler, which will wait for vstart to start
> +	 * compositing.
> +	 */
> +	HVS_WRITE(SCALER_DISPCTRLX(vc4_crtc->channel),
> +		  VC4_SET_FIELD(mode->hdisplay, SCALER_DISPCTRLX_WIDTH) |
> +		  VC4_SET_FIELD(mode->vdisplay, SCALER_DISPCTRLX_HEIGHT) |
> +		  SCALER_DISPCTRLX_ENABLE);
> +
> +	/* Turn on the pixel valve, which will emit the vstart signal. */
> +	CRTC_WRITE(PV_V_CONTROL,
> +		   CRTC_READ(PV_V_CONTROL) | PV_VCONTROL_VIDEN);
> +}
> +
> +static int vc4_crtc_atomic_check(struct drm_crtc *crtc,
> +				 struct drm_crtc_state *state)
> +{
> +	struct drm_device *dev = crtc->dev;
> +	struct vc4_dev *vc4 = to_vc4_dev(dev);
> +	struct drm_plane *plane;
> +	struct vc4_crtc *vc4_crtc = to_vc4_crtc(crtc);
> +	u32 dlist_count = 0;
> +
> +	drm_atomic_crtc_state_for_each_plane(plane, state) {
> +		struct drm_plane_state *plane_state =
> +			state->state->plane_states[drm_plane_index(plane)];
> +
> +		/* plane might not have changed, in which case take
> +		 * current state:
> +		 */
> +		if (!plane_state)
> +			plane_state = plane->state;
> +
> +		dlist_count += vc4_plane_dlist_size(plane_state);
> +	}
> +
> +	dlist_count++; /* Account for SCALER_CTL0_END. */
> +
> +	if (!vc4_crtc->dlist || dlist_count > vc4_crtc->dlist_size) {
> +		vc4_crtc->dlist = ((u32 __iomem *)vc4->hvs->dlist +
> +				   HVS_BOOTLOADER_DLIST_END);
> +		vc4_crtc->dlist_size = ((SCALER_DLIST_SIZE >> 2) -
> +					HVS_BOOTLOADER_DLIST_END);
> +
> +		if (dlist_count > vc4_crtc->dlist_size) {
> +			DRM_DEBUG_KMS("dlist too large for CRTC (%d > %d).\n",
> +				      dlist_count, vc4_crtc->dlist_size);
> +			return -EINVAL;
> +		}
> +	}
> +
> +	return 0;
> +}
> +
> +static void vc4_crtc_atomic_flush(struct drm_crtc *crtc,
> +				  struct drm_crtc_state *old_state)
> +{
> +	struct drm_device *dev = crtc->dev;
> +	struct vc4_dev *vc4 = to_vc4_dev(dev);
> +	struct vc4_crtc *vc4_crtc = to_vc4_crtc(crtc);
> +	struct drm_plane *plane;
> +	bool debug_dump_regs = false;
> +	u32 __iomem *dlist_next = vc4_crtc->dlist;
> +
> +	if (debug_dump_regs) {
> +		DRM_INFO("CRTC %d HVS before:\n", drm_crtc_index(crtc));
> +		vc4_hvs_dump_state(dev);
> +	}
> +
> +	/* Copy all the active planes' dlist contents to the hardware dlist.
> +	 *
> +	 * XXX: If the new display list was large enough that it
> +	 * overlapped a currently-read display list, we need to do
> +	 * something like disable scanout before putting in the new
> +	 * list.  For now, we're safe because we only have the two
> +	 * planes.
> +	 */
> +	drm_atomic_crtc_for_each_plane(plane, crtc) {
> +		dlist_next += vc4_plane_write_dlist(plane, dlist_next);
> +	}
> +
> +	if (dlist_next == vc4_crtc->dlist) {
> +		/* If no planes were enabled, use the SCALER_CTL0_END
> +		 * at the start of the display list memory (in the
> +		 * bootloader section).  We'll rewrite that
> +		 * SCALER_CTL0_END, just in case, though.
> +		 */
> +		writel(SCALER_CTL0_END, vc4->hvs->dlist);
> +		HVS_WRITE(SCALER_DISPLISTX(vc4_crtc->channel), 0);
> +	} else {
> +		writel(SCALER_CTL0_END, dlist_next);
> +		dlist_next++;
> +
> +		HVS_WRITE(SCALER_DISPLISTX(vc4_crtc->channel),
> +			  (u32 *)vc4_crtc->dlist - (u32 *)vc4->hvs->dlist);
> +
> +		/* Make the next display list start after ours. */
> +		vc4_crtc->dlist_size -= (dlist_next - vc4_crtc->dlist);
> +		vc4_crtc->dlist = dlist_next;
> +	}
> +
> +	if (debug_dump_regs) {
> +		DRM_INFO("CRTC %d HVS after:\n", drm_crtc_index(crtc));
> +		vc4_hvs_dump_state(dev);
> +	}
> +
> +	if (crtc->state->event) {
> +		unsigned long flags;
> +
> +		crtc->state->event->pipe = drm_crtc_index(crtc);
> +
> +		WARN_ON(drm_crtc_vblank_get(crtc) != 0);
> +
> +		spin_lock_irqsave(&dev->event_lock, flags);
> +		vc4_crtc->event = crtc->state->event;
> +		spin_unlock_irqrestore(&dev->event_lock, flags);
> +		crtc->state->event = NULL;
> +	}
> +}
> +
> +int vc4_enable_vblank(struct drm_device *dev, int crtc_id)
> +{
> +	struct vc4_dev *vc4 = to_vc4_dev(dev);
> +	struct vc4_crtc *vc4_crtc = vc4->crtc[crtc_id];
> +
> +	CRTC_WRITE(PV_INTEN, PV_INT_VFP_START);
> +
> +	return 0;
> +}
> +
> +void vc4_disable_vblank(struct drm_device *dev, int crtc_id)
> +{
> +	struct vc4_dev *vc4 = to_vc4_dev(dev);
> +	struct vc4_crtc *vc4_crtc = vc4->crtc[crtc_id];
> +
> +	CRTC_WRITE(PV_INTEN, 0);
> +}
> +
> +static void vc4_crtc_handle_page_flip(struct vc4_crtc *vc4_crtc)
> +{
> +	struct drm_crtc *crtc = &vc4_crtc->base;
> +	struct drm_device *dev = crtc->dev;
> +	unsigned long flags;
> +
> +	spin_lock_irqsave(&dev->event_lock, flags);
> +	if (vc4_crtc->event) {
> +		drm_crtc_send_vblank_event(crtc, vc4_crtc->event);
> +		vc4_crtc->event = NULL;
> +	}
> +	spin_unlock_irqrestore(&dev->event_lock, flags);
> +}
> +
> +static irqreturn_t vc4_crtc_irq_handler(int irq, void *data)
> +{
> +	struct vc4_crtc *vc4_crtc = data;
> +	u32 stat = CRTC_READ(PV_INTSTAT);
> +	irqreturn_t ret = IRQ_NONE;
> +
> +	if (stat & PV_INT_VFP_START) {
> +		CRTC_WRITE(PV_INTSTAT, PV_INT_VFP_START);
> +		drm_crtc_handle_vblank(&vc4_crtc->base);
> +		vc4_crtc_handle_page_flip(vc4_crtc);
> +		ret = IRQ_HANDLED;
> +	}
> +
> +	return ret;
> +}
> +
> +static const struct drm_crtc_funcs vc4_crtc_funcs = {
> +	.set_config = drm_atomic_helper_set_config,
> +	.destroy = vc4_crtc_destroy,
> +	.page_flip = drm_atomic_helper_page_flip,
> +	.set_property = NULL,
> +	.cursor_set = NULL, /* handled by drm_mode_cursor_universal */
> +	.cursor_move = NULL, /* handled by drm_mode_cursor_universal */
> +	.reset = drm_atomic_helper_crtc_reset,
> +	.atomic_duplicate_state = drm_atomic_helper_crtc_duplicate_state,
> +	.atomic_destroy_state = drm_atomic_helper_crtc_destroy_state,
> +};
> +
> +static const struct drm_crtc_helper_funcs vc4_crtc_helper_funcs = {
> +	.mode_set_nofb = vc4_crtc_mode_set_nofb,
> +	.disable = vc4_crtc_disable,
> +	.enable = vc4_crtc_enable,
> +	.atomic_check = vc4_crtc_atomic_check,
> +	.atomic_flush = vc4_crtc_atomic_flush,
> +};
> +
> +/* Frees the page flip event when the DRM device is closed with the
> + * event still outstanding.
> + */
> +void vc4_cancel_page_flip(struct drm_crtc *crtc, struct drm_file *file)
> +{
> +	struct vc4_crtc *vc4_crtc = to_vc4_crtc(crtc);
> +	struct drm_device *dev = crtc->dev;
> +	unsigned long flags;
> +
> +	spin_lock_irqsave(&dev->event_lock, flags);
> +
> +	if (vc4_crtc->event && vc4_crtc->event->base.file_priv == file) {
> +		vc4_crtc->event->base.destroy(&vc4_crtc->event->base);
> +		drm_crtc_vblank_put(crtc);
> +		vc4_crtc->event = NULL;
> +	}
> +
> +	spin_unlock_irqrestore(&dev->event_lock, flags);
> +}
> +
> +static int vc4_crtc_bind(struct device *dev, struct device *master, void *data)
> +{
> +	struct platform_device *pdev = to_platform_device(dev);
> +	struct drm_device *drm = dev_get_drvdata(master);
> +	struct vc4_dev *vc4 = to_vc4_dev(drm);
> +	struct vc4_crtc *vc4_crtc;
> +	struct drm_crtc *crtc;
> +	struct drm_plane *primary_plane, *cursor_plane;
> +	int ret;
> +
> +	/* For now, we create just the primary and the legacy cursor
> +	 * planes.  We should be able to stack more planes on easily,
> +	 * but to do that we would need to compute the bandwidth
> +	 * requirement of the plane configuration, and reject ones
> +	 * that will take too much.
> +	 */
> +	primary_plane = vc4_plane_init(drm, DRM_PLANE_TYPE_PRIMARY);
> +	if (!primary_plane) {
> +		dev_err(dev, "failed to construct primary plane\n");
> +		ret = PTR_ERR(primary_plane);
> +		goto fail;
> +	}
> +
> +	cursor_plane = vc4_plane_init(drm, DRM_PLANE_TYPE_CURSOR);
> +	if (!cursor_plane) {
> +		dev_err(dev, "failed to construct cursor plane\n");
> +		ret = PTR_ERR(cursor_plane);
> +		goto fail;
> +	}
> +
> +	vc4_crtc = devm_kzalloc(dev, sizeof(*vc4_crtc), GFP_KERNEL);
> +	if (!vc4_crtc)
> +		return -ENOMEM;
> +	crtc = &vc4_crtc->base;
> +
> +	vc4_crtc->regs = vc4_ioremap_regs(pdev, 0);
> +	if (IS_ERR(vc4_crtc->regs))
> +		return PTR_ERR(vc4_crtc->regs);
> +
> +	drm_crtc_init_with_planes(drm, crtc, primary_plane, cursor_plane,
> +				  &vc4_crtc_funcs);
> +	drm_crtc_helper_add(crtc, &vc4_crtc_helper_funcs);
> +	primary_plane->crtc = crtc;
> +	cursor_plane->crtc = crtc;
> +	vc4->crtc[drm_crtc_index(crtc)] = vc4_crtc;
> +
> +	/* Until we have full scanout setup to route things through to
> +	 * encoders, line things up like the firmware did.
> +	 */
> +	switch (drm_crtc_index(crtc)) {
> +	case 0:
> +		vc4_crtc->channel = 0;
> +		break;
> +	case 1:
> +		vc4_crtc->channel = 2;
> +		break;
> +	default:
> +	case 2:
> +		vc4_crtc->channel = 1;
> +		break;
> +	}
> +
> +	CRTC_WRITE(PV_INTEN, 0);
> +	CRTC_WRITE(PV_INTSTAT, PV_INT_VFP_START);
> +	ret = devm_request_irq(dev, platform_get_irq(pdev, 0),
> +			       vc4_crtc_irq_handler, 0, "vc4 crtc", vc4_crtc);
> +
> +	platform_set_drvdata(pdev, vc4_crtc);
> +
> +	return 0;
> +
> +fail:
> +	return ret;
> +}
> +
> +static void vc4_crtc_unbind(struct device *dev, struct device *master,
> +			    void *data)
> +{
> +	struct platform_device *pdev = to_platform_device(dev);
> +	struct vc4_crtc *vc4_crtc = dev_get_drvdata(dev);
> +
> +	vc4_crtc_destroy(&vc4_crtc->base);
> +
> +	CRTC_WRITE(PV_INTEN, 0);
> +
> +	platform_set_drvdata(pdev, NULL);
> +}
> +
> +static const struct component_ops vc4_crtc_ops = {
> +	.bind   = vc4_crtc_bind,
> +	.unbind = vc4_crtc_unbind,
> +};
> +
> +static int vc4_crtc_dev_probe(struct platform_device *pdev)
> +{
> +	return component_add(&pdev->dev, &vc4_crtc_ops);
> +}
> +
> +static int vc4_crtc_dev_remove(struct platform_device *pdev)
> +{
> +	component_del(&pdev->dev, &vc4_crtc_ops);
> +	return 0;
> +}
> +
> +static const struct of_device_id vc4_crtc_dt_match[] = {
> +	{ .compatible = "brcm,vc4-pixelvalve" },
> +	{}
> +};
> +
> +struct platform_driver vc4_crtc_driver = {
> +	.probe = vc4_crtc_dev_probe,
> +	.remove = vc4_crtc_dev_remove,
> +	.driver = {
> +		.name = "vc4_crtc",
> +		.of_match_table = vc4_crtc_dt_match,
> +	},
> +};
> diff --git a/drivers/gpu/drm/vc4/vc4_debugfs.c b/drivers/gpu/drm/vc4/vc4_debugfs.c
> new file mode 100644
> index 0000000..c557039
> --- /dev/null
> +++ b/drivers/gpu/drm/vc4/vc4_debugfs.c
> @@ -0,0 +1,38 @@
> +/*
> + *  Copyright ? 2014 Broadcom
> + *
> + * This program is free software; you can redistribute it and/or modify
> + * it under the terms of the GNU General Public License version 2 as
> + * published by the Free Software Foundation.
> + */
> +
> +#include <linux/seq_file.h>
> +#include <linux/circ_buf.h>
> +#include <linux/ctype.h>
> +#include <linux/debugfs.h>
> +#include <drm/drmP.h>
> +
> +#include "vc4_drv.h"
> +#include "vc4_regs.h"
> +
> +static const struct drm_info_list vc4_debugfs_list[] = {
> +	{"hdmi_regs", vc4_hdmi_debugfs_regs, 0},
> +	{"hvs_regs", vc4_hvs_debugfs_regs, 0},
> +	{"crtc0_regs", vc4_crtc_debugfs_regs, 0, (void *)(uintptr_t)0},
> +	{"crtc1_regs", vc4_crtc_debugfs_regs, 0, (void *)(uintptr_t)1},
> +	{"crtc2_regs", vc4_crtc_debugfs_regs, 0, (void *)(uintptr_t)2},
> +};
> +#define VC4_DEBUGFS_ENTRIES ARRAY_SIZE(vc4_debugfs_list)
> +
> +int
> +vc4_debugfs_init(struct drm_minor *minor)
> +{
> +	return drm_debugfs_create_files(vc4_debugfs_list, VC4_DEBUGFS_ENTRIES,
> +					minor->debugfs_root, minor);
> +}
> +
> +void
> +vc4_debugfs_cleanup(struct drm_minor *minor)
> +{
> +	drm_debugfs_remove_files(vc4_debugfs_list, VC4_DEBUGFS_ENTRIES, minor);
> +}
> diff --git a/drivers/gpu/drm/vc4/vc4_drv.c b/drivers/gpu/drm/vc4/vc4_drv.c
> new file mode 100644
> index 0000000..d30aefa
> --- /dev/null
> +++ b/drivers/gpu/drm/vc4/vc4_drv.c
> @@ -0,0 +1,271 @@
> +/*
> + * Copyright (C) 2014-2015 Broadcom
> + * Copyright (C) 2013 Red Hat
> + *
> + * This program is free software; you can redistribute it and/or modify
> + * it under the terms of the GNU General Public License version 2 as
> + * published by the Free Software Foundation.
> + */
> +
> +#include <linux/clk.h>
> +#include <linux/component.h>
> +#include <linux/device.h>
> +#include <linux/io.h>
> +#include <linux/module.h>
> +#include <linux/of_platform.h>
> +#include <linux/platform_device.h>
> +
> +#include "vc4_drv.h"
> +#include "vc4_regs.h"
> +
> +#define DRIVER_NAME "vc4"
> +#define DRIVER_DESC "Broadcom VC4 graphics"
> +#define DRIVER_DATE "20140616"
> +#define DRIVER_MAJOR 0
> +#define DRIVER_MINOR 0
> +#define DRIVER_PATCHLEVEL 0
> +
> +/* Helper function for mapping the regs on a platform device. */
> +void __iomem *vc4_ioremap_regs(struct platform_device *dev, int index)
> +{
> +	struct resource *res;
> +	void __iomem *map;
> +
> +	res = platform_get_resource(dev, IORESOURCE_MEM, index);
> +	map = devm_ioremap_resource(&dev->dev, res);
> +	if (IS_ERR(map)) {
> +		DRM_ERROR("Failed to map registers: %ld\n", PTR_ERR(map));
> +		return map;
> +	}
> +
> +	return map;
> +}
> +
> +static void vc4_drm_preclose(struct drm_device *dev, struct drm_file *file)
> +{
> +	struct drm_crtc *crtc;
> +
> +	list_for_each_entry(crtc, &dev->mode_config.crtc_list, head)
> +		vc4_cancel_page_flip(crtc, file);
> +}
> +
> +static const struct file_operations vc4_drm_fops = {
> +	.owner = THIS_MODULE,
> +	.open = drm_open,
> +	.release = drm_release,
> +	.unlocked_ioctl = drm_ioctl,
> +	.mmap = drm_gem_cma_mmap,
> +	.poll = drm_poll,
> +	.read = drm_read,
> +#ifdef CONFIG_COMPAT
> +	.compat_ioctl = drm_compat_ioctl,
> +#endif
> +	.llseek = noop_llseek,
> +};
> +
> +static const struct drm_ioctl_desc vc4_drm_ioctls[] = {
> +};
> +
> +static struct drm_driver vc4_drm_driver = {
> +	.driver_features = (DRIVER_MODESET |
> +			    DRIVER_ATOMIC |
> +			    DRIVER_GEM |
> +			    DRIVER_PRIME),
> +	.preclose = vc4_drm_preclose,
> +
> +	.enable_vblank = vc4_enable_vblank,
> +	.disable_vblank = vc4_disable_vblank,
> +	.get_vblank_counter = drm_vblank_count,
> +
> +#if defined(CONFIG_DEBUG_FS)
> +	.debugfs_init = vc4_debugfs_init,
> +	.debugfs_cleanup = vc4_debugfs_cleanup,
> +#endif
> +
> +	.gem_free_object = drm_gem_cma_free_object,
> +	.gem_vm_ops = &drm_gem_cma_vm_ops,
> +
> +	.prime_handle_to_fd = drm_gem_prime_handle_to_fd,
> +	.prime_fd_to_handle = drm_gem_prime_fd_to_handle,
> +	.gem_prime_import = drm_gem_prime_import,
> +	.gem_prime_export = drm_gem_prime_export,
> +	.gem_prime_get_sg_table	= drm_gem_cma_prime_get_sg_table,
> +	.gem_prime_import_sg_table = drm_gem_cma_prime_import_sg_table,
> +	.gem_prime_vmap = drm_gem_cma_prime_vmap,
> +	.gem_prime_vunmap = drm_gem_cma_prime_vunmap,
> +	.gem_prime_mmap = drm_gem_cma_prime_mmap,
> +
> +	.dumb_create = vc4_dumb_create,
> +	.dumb_map_offset = drm_gem_cma_dumb_map_offset,
> +	.dumb_destroy = drm_gem_dumb_destroy,
> +
> +	.ioctls = vc4_drm_ioctls,
> +	.num_ioctls = ARRAY_SIZE(vc4_drm_ioctls),
> +	.fops = &vc4_drm_fops,
> +
> +	.name = DRIVER_NAME,
> +	.desc = DRIVER_DESC,
> +	.date = DRIVER_DATE,
> +	.major = DRIVER_MAJOR,
> +	.minor = DRIVER_MINOR,
> +	.patchlevel = DRIVER_PATCHLEVEL,
> +};
> +
> +static int vc4_drm_bind(struct device *dev)
> +{
> +	struct platform_device *pdev = to_platform_device(dev);
> +	struct drm_device *drm;
> +	struct vc4_dev *vc4;
> +	int ret = 0;
> +
> +	dev->coherent_dma_mask = DMA_BIT_MASK(32);
> +
> +	vc4 = devm_kzalloc(dev, sizeof(*vc4), GFP_KERNEL);
> +	if (!vc4)
> +		return -ENOMEM;
> +
> +	drm = drm_dev_alloc(&vc4_drm_driver, dev);
> +	if (!drm)
> +		return -ENOMEM;
> +	platform_set_drvdata(pdev, drm);
> +	vc4->dev = drm;
> +	drm->dev_private = vc4;
> +
> +	drm_dev_set_unique(drm, dev_name(dev));
> +
> +	drm_mode_config_init(drm);
> +	if (ret)
> +		goto unref;
> +
> +	ret = component_bind_all(dev, drm);
> +	if (ret)
> +		goto unref;
> +
> +	ret = drm_dev_register(drm, 0);
> +	if (ret < 0)
> +		goto unbind_all;
> +
> +	vc4_kms_load(drm);
> +
> +	return 0;
> +unbind_all:
> +	component_unbind_all(dev, drm);
> +unref:
> +	drm_dev_unref(drm);
> +	return ret;
> +
> +	return 0;
> +}
> +
> +static void vc4_drm_unbind(struct device *dev)
> +{
> +	struct platform_device *pdev = to_platform_device(dev);
> +	struct drm_device *drm = platform_get_drvdata(pdev);
> +
> +	drm_mode_config_cleanup(drm);
> +
> +	drm_put_dev(drm);
> +}
> +
> +static const struct component_master_ops vc4_drm_ops = {
> +	.bind = vc4_drm_bind,
> +	.unbind = vc4_drm_unbind,
> +};
> +
> +static int compare_of(struct device *dev, void *data)
> +{
> +	return dev->of_node == data;
> +}
> +
> +static int add_components(struct device *dev, struct component_match **matchptr,
> +			  const char *name)
> +{
> +	struct device_node *np = dev->of_node;
> +	unsigned i;
> +
> +	for (i = 0; ; i++) {
> +		struct device_node *node;
> +
> +		node = of_parse_phandle(np, name, i);
> +		if (!node)
> +			break;
> +
> +		component_match_add(dev, matchptr, compare_of, node);
> +	}
> +
> +	return 0;
> +}
> +
> +static int vc4_platform_drm_probe(struct platform_device *pdev)
> +{
> +	struct component_match *match = NULL;
> +	struct device *dev = &pdev->dev;
> +
> +	add_components(dev, &match, "crtcs");
> +	add_components(dev, &match, "encoders");
> +	add_components(dev, &match, "hvss");
> +
> +	return component_master_add_with_match(dev, &vc4_drm_ops, match);
> +}
> +
> +static int vc4_platform_drm_remove(struct platform_device *pdev)
> +{
> +	component_master_del(&pdev->dev, &vc4_drm_ops);
> +
> +	return 0;
> +}
> +
> +static const struct of_device_id vc4_of_match[] = {
> +	{ .compatible = "brcm,vc4", },
> +	{},
> +};
> +MODULE_DEVICE_TABLE(of, vc4_of_match);
> +
> +static struct platform_driver vc4_platform_driver = {
> +	.probe		= vc4_platform_drm_probe,
> +	.remove		= vc4_platform_drm_remove,
> +	.driver		= {
> +		.name	= "vc4-drm",
> +		.owner	= THIS_MODULE,
> +		.of_match_table = vc4_of_match,
> +	},
> +};
> +
> +static struct platform_driver *component_drivers[] = {
> +	&vc4_hdmi_driver,
> +	&vc4_crtc_driver,
> +	&vc4_hvs_driver,
> +};
> +
> +static int __init vc4_drm_register(void)
> +{
> +	int i;
> +
> +	for (i = 0; i < ARRAY_SIZE(component_drivers); i++) {
> +		int ret = platform_driver_register(component_drivers[i]);
> +		if (ret) {
> +			while (--i >= 0)
> +				platform_driver_unregister(component_drivers[i]);
> +			return ret;
> +		}
> +	}
> +	return platform_driver_register(&vc4_platform_driver);
> +}
> +
> +static void __exit vc4_drm_unregister(void)
> +{
> +	int i;
> +
> +	for (i = ARRAY_SIZE(component_drivers) - 1; i >= 0; i--)
> +		platform_driver_unregister(component_drivers[i]);
> +
> +	platform_driver_unregister(&vc4_platform_driver);
> +}
> +
> +module_init(vc4_drm_register);
> +module_exit(vc4_drm_unregister);
> +
> +MODULE_ALIAS("platform:vc4-drm");
> +MODULE_DESCRIPTION("Broadcom VC4 DRM Driver");
> +MODULE_AUTHOR("Eric Anholt <eric at anholt.net>");
> +MODULE_LICENSE("GPL v2");
> diff --git a/drivers/gpu/drm/vc4/vc4_drv.h b/drivers/gpu/drm/vc4/vc4_drv.h
> new file mode 100644
> index 0000000..282ce0b
> --- /dev/null
> +++ b/drivers/gpu/drm/vc4/vc4_drv.h
> @@ -0,0 +1,120 @@
> +/*
> + * Copyright (C) 2015 Broadcom
> + *
> + * This program is free software; you can redistribute it and/or modify
> + * it under the terms of the GNU General Public License version 2 as
> + * published by the Free Software Foundation.
> + */
> +
> +#include "drmP.h"
> +#include "drm_gem_cma_helper.h"
> +
> +struct vc4_dev {
> +	struct drm_device *dev;
> +
> +	struct vc4_hdmi *hdmi;
> +	struct vc4_hvs *hvs;
> +	struct vc4_crtc *crtc[3];
> +};
> +
> +static inline struct vc4_dev *
> +to_vc4_dev(struct drm_device *dev)
> +{
> +	return (struct vc4_dev *)dev->dev_private;
> +}
> +
> +struct vc4_bo {
> +	struct drm_gem_cma_object base;
> +};
> +
> +static inline struct vc4_bo *
> +to_vc4_bo(struct drm_gem_object *bo)
> +{
> +	return (struct vc4_bo *)bo;
> +}
> +
> +struct vc4_hvs {
> +	struct platform_device *pdev;
> +	void __iomem *regs;
> +	void __iomem *dlist;
> +};
> +
> +struct vc4_crtc {
> +	struct drm_crtc base;
> +	void __iomem *regs;
> +
> +	/* Which HVS channel we're using for our CRTC. */
> +	int channel;
> +
> +	/* Pointer to the actual hardware display list memory for the
> +	 * crtc.
> +	 */
> +	u32 __iomem *dlist;
> +
> +	u32 dlist_size; /* in dwords */
> +
> +	struct drm_pending_vblank_event *event;
> +};
> +
> +static inline struct vc4_crtc *
> +to_vc4_crtc(struct drm_crtc *crtc)
> +{
> +	return (struct vc4_crtc *)crtc;
> +}
> +
> +struct vc4_plane {
> +	struct drm_plane base;
> +};
> +
> +static inline struct vc4_plane *
> +to_vc4_plane(struct drm_plane *plane)
> +{
> +	return (struct vc4_plane *)plane;
> +}
> +
> +#define HVS_READ(offset) readl(vc4->hvs->regs + offset)
> +#define HVS_WRITE(offset, val) writel(val, vc4->hvs->regs + offset)
> +
> +/* vc4_bo.c */
> +void vc4_free_object(struct drm_gem_object *gem_obj);
> +struct vc4_bo *vc4_bo_create(struct drm_device *dev, size_t size);
> +int vc4_dumb_create(struct drm_file *file_priv,
> +		    struct drm_device *dev,
> +		    struct drm_mode_create_dumb *args);
> +struct dma_buf *vc4_prime_export(struct drm_device *dev,
> +				 struct drm_gem_object *obj, int flags);
> +
> +/* vc4_crtc.c */
> +extern struct platform_driver vc4_crtc_driver;
> +int vc4_enable_vblank(struct drm_device *dev, int crtc_id);
> +void vc4_disable_vblank(struct drm_device *dev, int crtc_id);
> +void vc4_cancel_page_flip(struct drm_crtc *crtc, struct drm_file *file);
> +int vc4_crtc_debugfs_regs(struct seq_file *m, void *arg);
> +
> +/* vc4_debugfs.c */
> +int vc4_debugfs_init(struct drm_minor *minor);
> +void vc4_debugfs_cleanup(struct drm_minor *minor);
> +
> +/* vc4_drv.c */
> +void __iomem *vc4_ioremap_regs(struct platform_device *dev, int index);
> +
> +/* vc4_hdmi.c */
> +extern struct platform_driver vc4_hdmi_driver;
> +struct drm_encoder *vc4_hdmi_encoder_init(struct drm_device *dev);
> +struct drm_connector *vc4_hdmi_connector_init(struct drm_device *dev,
> +					      struct drm_encoder *encoder);
> +int vc4_hdmi_debugfs_regs(struct seq_file *m, void *unused);
> +
> +/* vc4_hvs.c */
> +extern struct platform_driver vc4_hvs_driver;
> +void vc4_hvs_dump_state(struct drm_device *dev);
> +int vc4_hvs_debugfs_regs(struct seq_file *m, void *unused);
> +
> +/* vc4_kms.c */
> +int vc4_kms_load(struct drm_device *dev);
> +
> +/* vc4_plane.c */
> +struct drm_plane *vc4_plane_init(struct drm_device *dev,
> +				 enum drm_plane_type type);
> +u32 vc4_plane_write_dlist(struct drm_plane *plane, u32 __iomem *dlist);
> +u32 vc4_plane_dlist_size(struct drm_plane_state *state);
> diff --git a/drivers/gpu/drm/vc4/vc4_hdmi.c b/drivers/gpu/drm/vc4/vc4_hdmi.c
> new file mode 100644
> index 0000000..cd3301b
> --- /dev/null
> +++ b/drivers/gpu/drm/vc4/vc4_hdmi.c
> @@ -0,0 +1,633 @@
> +/*
> + * Copyright (c) 2014 The Linux Foundation. All rights reserved.
> + * Copyright (C) 2013 Red Hat
> + * Author: Rob Clark <robdclark at gmail.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.
> + *
> + * You should have received a copy of the GNU General Public License along with
> + * this program.  If not, see <http://www.gnu.org/licenses/>.
> + */
> +
> +#include "drm_atomic_helper.h"
> +#include "drm_crtc_helper.h"
> +#include "drm_edid.h"
> +#include "linux/clk.h"
> +#include "linux/component.h"
> +#include "linux/of_gpio.h"
> +#include "linux/of_platform.h"
> +#include "vc4_drv.h"
> +#include "vc4_regs.h"
> +
> +/* General HDMI hardware state. */
> +struct vc4_hdmi {
> +	struct platform_device *pdev;
> +	struct i2c_adapter *ddc;
> +	void __iomem *hdmicore_regs;
> +	void __iomem *hd_regs;
> +	int hpd_gpio;
> +
> +	/* Probed video mode at boot time, used to filter display
> +	 * modes to only allow equivalent ones (since we can't set the
> +	 * pixel clock yet).
> +	 */
> +	struct drm_display_mode boot_mode;
> +};
> +#define HDMI_READ(offset) readl(vc4->hdmi->hdmicore_regs + offset)
> +#define HDMI_WRITE(offset, val) writel(val, vc4->hdmi->hdmicore_regs + offset)
> +#define HD_READ(offset) readl(vc4->hdmi->hd_regs + offset)
> +#define HD_WRITE(offset, val) writel(val, vc4->hdmi->hd_regs + offset)
> +
> +/* VC4 HDMI encoder KMS struct */
> +struct vc4_hdmi_encoder {
> +	struct drm_encoder base;
> +	bool hdmi_monitor;
> +};
> +static inline struct vc4_hdmi_encoder *
> +to_vc4_hdmi_encoder(struct drm_encoder *encoder)
> +{
> +	return container_of(encoder, struct vc4_hdmi_encoder, base);
> +}
> +
> +/* VC4 HDMI connector KMS struct */
> +struct vc4_hdmi_connector {
> +	struct drm_connector base;
> +
> +	/* Since the connector is attached to just the one encoder,
> +	 * this is the reference to it so we can do the best_encoder()
> +	 * hook.
> +	 */
> +	struct drm_encoder *encoder;
> +};
> +static inline struct vc4_hdmi_connector *
> +to_vc4_hdmi_connector(struct drm_connector *connector)
> +{
> +	return container_of(connector, struct vc4_hdmi_connector, base);
> +}
> +
> +#define HDMI_REG(reg) { reg, #reg }
> +static const struct {
> +	u32 reg;
> +	const char *name;
> +} hdmi_regs[] = {
> +	HDMI_REG(VC4_HDMI_CORE_REV),
> +	HDMI_REG(VC4_HDMI_SW_RESET_CONTROL),
> +	HDMI_REG(VC4_HDMI_HOTPLUG_INT),
> +	HDMI_REG(VC4_HDMI_HOTPLUG),
> +	HDMI_REG(VC4_HDMI_HORZA),
> +	HDMI_REG(VC4_HDMI_HORZB),
> +	HDMI_REG(VC4_HDMI_FIFO_CTL),
> +	HDMI_REG(VC4_HDMI_SCHEDULER_CONTROL),
> +	HDMI_REG(VC4_HDMI_VERTA0),
> +	HDMI_REG(VC4_HDMI_VERTA1),
> +	HDMI_REG(VC4_HDMI_VERTB0),
> +	HDMI_REG(VC4_HDMI_VERTB1),
> +	HDMI_REG(VC4_HDMI_TX_PHY_RESET_CTL),
> +};
> +static const struct {
> +	u32 reg;
> +	const char *name;
> +} hd_regs[] = {
> +	HDMI_REG(VC4_HD_M_CTL),
> +	HDMI_REG(VC4_HD_MAI_CTL),
> +	HDMI_REG(VC4_HD_VID_CTL),
> +	HDMI_REG(VC4_HD_CSC_CTL),
> +	HDMI_REG(VC4_HD_FRAME_COUNT),
> +};
> +
> +#ifdef CONFIG_DEBUG_FS
> +int vc4_hdmi_debugfs_regs(struct seq_file *m, void *unused)
> +{
> +	struct drm_info_node *node = (struct drm_info_node *) m->private;
> +	struct drm_device *dev = node->minor->dev;
> +	struct vc4_dev *vc4 = to_vc4_dev(dev);
> +	int i;
> +
> +	for (i = 0; i < ARRAY_SIZE(hdmi_regs); i++) {
> +		seq_printf(m, "%s (0x%04x): 0x%08x\n",
> +			   hdmi_regs[i].name, hdmi_regs[i].reg,
> +			   HDMI_READ(hdmi_regs[i].reg));
> +	}
> +
> +	for (i = 0; i < ARRAY_SIZE(hd_regs); i++) {
> +		seq_printf(m, "%s (0x%04x): 0x%08x\n",
> +			   hd_regs[i].name, hd_regs[i].reg,
> +			   HD_READ(hd_regs[i].reg));
> +	}
> +
> +	return 0;
> +}
> +#endif /* CONFIG_DEBUG_FS */
> +
> +static void vc4_hdmi_dump_regs(struct drm_device *dev)
> +{
> +	struct vc4_dev *vc4 = to_vc4_dev(dev);
> +	int i;
> +
> +	for (i = 0; i < ARRAY_SIZE(hdmi_regs); i++) {
> +		DRM_INFO("0x%04x (%s): 0x%08x\n",
> +			 hdmi_regs[i].reg, hdmi_regs[i].name,
> +			 HDMI_READ(hdmi_regs[i].reg));
> +	}
> +	for (i = 0; i < ARRAY_SIZE(hd_regs); i++) {
> +		DRM_INFO("0x%04x (%s): 0x%08x\n",
> +			 hd_regs[i].reg, hd_regs[i].name,
> +			 HD_READ(hd_regs[i].reg));
> +	}
> +}
> +
> +static enum drm_connector_status
> +vc4_hdmi_connector_detect(struct drm_connector *connector, bool force)
> +{
> +	struct drm_device *dev = connector->dev;
> +	struct vc4_dev *vc4 = to_vc4_dev(dev);
> +
> +	if (vc4->hdmi->hpd_gpio) {
> +		if (gpio_get_value(vc4->hdmi->hpd_gpio))
> +			return connector_status_connected;
> +		else
> +			return connector_status_disconnected;
> +	}
> +
> +	if (HDMI_READ(VC4_HDMI_HOTPLUG) & VC4_HDMI_HOTPLUG_CONNECTED)
> +		return connector_status_connected;
> +	else
> +		return connector_status_disconnected;
> +}
> +
> +static void vc4_hdmi_connector_destroy(struct drm_connector *connector)
> +{
> +	drm_connector_unregister(connector);
> +	drm_connector_cleanup(connector);
> +}
> +
> +static int vc4_hdmi_connector_get_modes(struct drm_connector *connector)
> +{
> +	struct vc4_hdmi_connector *vc4_connector =
> +		to_vc4_hdmi_connector(connector);
> +	struct drm_encoder *encoder = vc4_connector->encoder;
> +	struct vc4_hdmi_encoder *vc4_encoder = to_vc4_hdmi_encoder(encoder);
> +	struct drm_device *dev = connector->dev;
> +	struct vc4_dev *vc4 = to_vc4_dev(dev);
> +	int ret = 0;
> +	struct edid *edid;
> +
> +	edid = drm_get_edid(connector, vc4->hdmi->ddc);
> +	if (!edid)
> +		return -ENODEV;
> +
> +	vc4_encoder->hdmi_monitor = drm_detect_hdmi_monitor(edid);
> +	drm_mode_connector_update_edid_property(connector, edid);
> +	ret = drm_add_edid_modes(connector, edid);
> +
> +	return ret;
> +}
> +
> +/* Since we can't set the pixel clock yet, filter out all the EDID
> + * modes that don't match what was set up by the firmware.
> + */
> +int vc4_hdmi_mode_valid(struct drm_connector *connector,
> +			struct drm_display_mode *mode)
> +{
> +	struct drm_device *dev = connector->dev;
> +	struct vc4_dev *vc4 = to_vc4_dev(dev);
> +	struct drm_display_mode *boot_mode = &vc4->hdmi->boot_mode;
> +
> +	if (mode->hdisplay != boot_mode->hdisplay ||
> +	    mode->hsync_start != boot_mode->hsync_start ||
> +	    mode->hsync_end != boot_mode->hsync_end ||
> +	    mode->htotal != boot_mode->htotal) {
> +		return MODE_ERROR;
> +	}
> +
> +	return MODE_OK;
> +}
> +
> +static struct drm_encoder *
> +vc4_hdmi_connector_best_encoder(struct drm_connector *connector)
> +{
> +	struct vc4_hdmi_connector *hdmi_connector =
> +		to_vc4_hdmi_connector(connector);
> +	return hdmi_connector->encoder;
> +}
> +
> +static const struct drm_connector_funcs vc4_hdmi_connector_funcs = {
> +	.dpms = drm_atomic_helper_connector_dpms,
> +	.detect = vc4_hdmi_connector_detect,
> +	.fill_modes = drm_helper_probe_single_connector_modes,
> +	.destroy = vc4_hdmi_connector_destroy,
> +	.reset = drm_atomic_helper_connector_reset,
> +	.atomic_duplicate_state = drm_atomic_helper_connector_duplicate_state,
> +	.atomic_destroy_state = drm_atomic_helper_connector_destroy_state,
> +};
> +
> +static const struct drm_connector_helper_funcs vc4_hdmi_connector_helper_funcs = {
> +	.get_modes = vc4_hdmi_connector_get_modes,
> +	.mode_valid = vc4_hdmi_mode_valid,
> +	.best_encoder = vc4_hdmi_connector_best_encoder,
> +};
> +
> +struct drm_connector *vc4_hdmi_connector_init(struct drm_device *dev,
> +					      struct drm_encoder *encoder)
> +{
> +	struct drm_connector *connector = NULL;
> +	struct vc4_hdmi_connector *hdmi_connector;
> +	int ret = 0;
> +
> +	hdmi_connector = devm_kzalloc(dev->dev, sizeof(*hdmi_connector),
> +				      GFP_KERNEL);
> +	if (!hdmi_connector) {
> +		ret = -ENOMEM;
> +		goto fail;
> +	}
> +	connector = &hdmi_connector->base;
> +
> +	hdmi_connector->encoder = encoder;
> +
> +	drm_connector_init(dev, connector, &vc4_hdmi_connector_funcs,
> +			   DRM_MODE_CONNECTOR_HDMIA);
> +	drm_connector_helper_add(connector, &vc4_hdmi_connector_helper_funcs);
> +
> +	connector->polled = (DRM_CONNECTOR_POLL_CONNECT |
> +			     DRM_CONNECTOR_POLL_DISCONNECT);
> +
> +	connector->interlace_allowed = 0;
> +	connector->doublescan_allowed = 0;
> +
> +	drm_connector_register(connector);
> +
> +	drm_mode_connector_attach_encoder(connector, encoder);
> +
> +	return connector;
> +
> + fail:
> +	if (connector)
> +		vc4_hdmi_connector_destroy(connector);
> +
> +	return ERR_PTR(ret);
> +}
> +
> +static void vc4_encoder_destroy(struct drm_encoder *encoder)
> +{
> +	drm_encoder_cleanup(encoder);
> +}
> +
> +static const struct drm_encoder_funcs vc4_hdmi_encoder_funcs = {
> +	.destroy = vc4_encoder_destroy,
> +};
> +
> +static void vc4_hdmi_encoder_mode_set(struct drm_encoder *encoder,
> +				      struct drm_display_mode *unadjusted_mode,
> +				      struct drm_display_mode *mode)
> +{
> +	struct drm_device *dev = encoder->dev;
> +	struct vc4_dev *vc4 = to_vc4_dev(dev);
> +	bool debug_dump_regs = false;
> +	bool hsync_pos = !(mode->flags & DRM_MODE_FLAG_NHSYNC);
> +	bool vsync_pos = !(mode->flags & DRM_MODE_FLAG_NVSYNC);
> +	u32 vactive = (mode->vdisplay >>
> +		       ((mode->flags & DRM_MODE_FLAG_INTERLACE) ? 1 : 0));
> +	u32 verta = (VC4_SET_FIELD(mode->vsync_end - mode->vsync_start,
> +				   VC4_HDMI_VERTA_VSP) |
> +		     VC4_SET_FIELD(mode->vsync_start - mode->vdisplay,
> +				   VC4_HDMI_VERTA_VFP) |
> +		     VC4_SET_FIELD(vactive, VC4_HDMI_VERTA_VAL));
> +	u32 vertb = (VC4_SET_FIELD(0, VC4_HDMI_VERTB_VSPO) |
> +		     VC4_SET_FIELD(mode->vtotal - mode->vsync_end,
> +				   VC4_HDMI_VERTB_VBP));
> +
> +	if (debug_dump_regs) {
> +		DRM_INFO("HDMI regs before:\n");
> +		vc4_hdmi_dump_regs(dev);
> +	}
> +
> +	HD_WRITE(VC4_HD_VID_CTL, 0);
> +
> +	/* XXX: This is where we would set the HDMI state machine
> +	 * clock, if we had an interface for it.
> +	 */
> +
> +	HDMI_WRITE(VC4_HDMI_SCHEDULER_CONTROL,
> +		   HDMI_READ(VC4_HDMI_SCHEDULER_CONTROL) |
> +		   VC4_HDMI_SCHEDULER_CONTROL_MANUAL_FORMAT |
> +		   VC4_HDMI_SCHEDULER_CONTROL_IGNORE_VSYNC_PREDICTS);
> +
> +	HDMI_WRITE(VC4_HDMI_HORZA,
> +		   (vsync_pos ? VC4_HDMI_HORZA_VPOS : 0) |
> +		   (hsync_pos ? VC4_HDMI_HORZA_HPOS : 0) |
> +		   VC4_SET_FIELD(mode->hdisplay, VC4_HDMI_HORZA_HAP));
> +
> +	HDMI_WRITE(VC4_HDMI_HORZB,
> +		   VC4_SET_FIELD(mode->htotal - mode->hsync_end,
> +				 VC4_HDMI_HORZB_HBP) |
> +		   VC4_SET_FIELD(mode->hsync_end - mode->hsync_start,
> +				 VC4_HDMI_HORZB_HSP) |
> +		   VC4_SET_FIELD(mode->hsync_start - mode->hdisplay,
> +				 VC4_HDMI_HORZB_HFP));
> +
> +	HDMI_WRITE(VC4_HDMI_VERTA0, verta);
> +	HDMI_WRITE(VC4_HDMI_VERTA1, verta);
> +
> +	HDMI_WRITE(VC4_HDMI_VERTB0, vertb);
> +	HDMI_WRITE(VC4_HDMI_VERTB1, vertb);
> +
> +	HD_WRITE(VC4_HD_VID_CTL,
> +		 (vsync_pos ? 0 : VC4_HD_VID_CTL_VSYNC_LOW) |
> +		 (hsync_pos ? 0 : VC4_HD_VID_CTL_HSYNC_LOW));
> +
> +	/* The RGB order applies even when CSC is disabled. */
> +	HD_WRITE(VC4_HD_CSC_CTL, VC4_SET_FIELD(VC4_HD_CSC_CTL_ORDER_BGR,
> +					       VC4_HD_CSC_CTL_ORDER));
> +
> +	HDMI_WRITE(VC4_HDMI_FIFO_CTL, VC4_HDMI_FIFO_CTL_MASTER_SLAVE_N);
> +
> +	if (debug_dump_regs) {
> +		DRM_INFO("HDMI regs after:\n");
> +		vc4_hdmi_dump_regs(dev);
> +	}
> +}
> +
> +static void vc4_hdmi_encoder_disable(struct drm_encoder *encoder)
> +{
> +	struct drm_device *dev = encoder->dev;
> +	struct vc4_dev *vc4 = to_vc4_dev(dev);
> +
> +	HDMI_WRITE(VC4_HDMI_TX_PHY_RESET_CTL, 0xf << 16);
> +	HD_WRITE(VC4_HD_VID_CTL,
> +		 HD_READ(VC4_HD_VID_CTL) & ~VC4_HD_VID_CTL_ENABLE);
> +}
> +
> +static void vc4_hdmi_encoder_enable(struct drm_encoder *encoder)
> +{
> +	struct vc4_hdmi_encoder *vc4_encoder = to_vc4_hdmi_encoder(encoder);
> +	struct drm_device *dev = encoder->dev;
> +	struct vc4_dev *vc4 = to_vc4_dev(dev);
> +
> +	HDMI_WRITE(VC4_HDMI_TX_PHY_RESET_CTL, 0);
> +
> +	HD_WRITE(VC4_HD_VID_CTL,
> +		 HD_READ(VC4_HD_VID_CTL) |
> +		 VC4_HD_VID_CTL_ENABLE |
> +		 VC4_HD_VID_CTL_UNDERFLOW_ENABLE |
> +		 VC4_HD_VID_CTL_FRAME_COUNTER_RESET);
> +
> +	if (vc4_encoder->hdmi_monitor) {
> +		HDMI_WRITE(VC4_HDMI_SCHEDULER_CONTROL,
> +			   HDMI_READ(VC4_HDMI_SCHEDULER_CONTROL) |
> +			   VC4_HDMI_SCHEDULER_CONTROL_MODE_HDMI);
> +
> +		while (!(HDMI_READ(VC4_HDMI_SCHEDULER_CONTROL) &
> +			 VC4_HDMI_SCHEDULER_CONTROL_HDMI_ACTIVE)) {
> +			cpu_relax();
> +		}
> +	} else {
> +		HDMI_WRITE(VC4_HDMI_RAM_PACKET_CONFIG,
> +			   HDMI_READ(VC4_HDMI_RAM_PACKET_CONFIG) &
> +			   ~(VC4_HDMI_RAM_PACKET_ENABLE));
> +		HDMI_WRITE(VC4_HDMI_SCHEDULER_CONTROL,
> +			   HDMI_READ(VC4_HDMI_SCHEDULER_CONTROL) &
> +			   ~VC4_HDMI_SCHEDULER_CONTROL_MODE_HDMI);
> +
> +		while (HDMI_READ(VC4_HDMI_SCHEDULER_CONTROL) &
> +		       VC4_HDMI_SCHEDULER_CONTROL_HDMI_ACTIVE) {
> +			cpu_relax();
> +		}
> +	}
> +
> +	if (vc4_encoder->hdmi_monitor) {
> +		u32 drift;
> +
> +		WARN_ON(!(HDMI_READ(VC4_HDMI_SCHEDULER_CONTROL) &
> +			  VC4_HDMI_SCHEDULER_CONTROL_HDMI_ACTIVE));
> +		HDMI_WRITE(VC4_HDMI_SCHEDULER_CONTROL,
> +			   HDMI_READ(VC4_HDMI_SCHEDULER_CONTROL) |
> +			   VC4_HDMI_SCHEDULER_CONTROL_VERT_ALWAYS_KEEPOUT);
> +
> +		/* XXX: Set HDMI_RAM_PACKET_CONFIG (1 << 16) and set
> +		 * up the infoframe.
> +		 */
> +
> +		drift = HDMI_READ(VC4_HDMI_FIFO_CTL);
> +		drift &= VC4_HDMI_FIFO_VALID_WRITE_MASK;
> +
> +		HDMI_WRITE(VC4_HDMI_FIFO_CTL,
> +			   drift & ~VC4_HDMI_FIFO_CTL_RECENTER);
> +		HDMI_WRITE(VC4_HDMI_FIFO_CTL,
> +			   drift | VC4_HDMI_FIFO_CTL_RECENTER);
> +		udelay(1000);
> +		HDMI_WRITE(VC4_HDMI_FIFO_CTL,
> +			   drift & ~VC4_HDMI_FIFO_CTL_RECENTER);
> +		HDMI_WRITE(VC4_HDMI_FIFO_CTL,
> +			   drift | VC4_HDMI_FIFO_CTL_RECENTER);
> +
> +		while ((HDMI_READ(VC4_HDMI_FIFO_CTL) &
> +			VC4_HDMI_FIFO_CTL_RECENTER_DONE) == 0) {
> +			cpu_relax();
> +		}
> +	}
> +}
> +
> +static const struct drm_encoder_helper_funcs vc4_hdmi_encoder_helper_funcs = {
> +	.mode_set = vc4_hdmi_encoder_mode_set,
> +	.disable = vc4_hdmi_encoder_disable,
> +	.enable = vc4_hdmi_encoder_enable,
> +};
> +
> +static struct drm_crtc *
> +vc4_get_crtc_node(struct platform_device *pdev)
> +{
> +	struct device_node *crtc_node;
> +	struct platform_device *crtc_pdev;
> +
> +	crtc_node = of_parse_phandle(pdev->dev.of_node, "crtc", 0);
> +	if (!crtc_node) {
> +		DRM_ERROR("No CRTC for hdmi in DT\n");
> +		return ERR_PTR(-EINVAL);
> +	}
> +
> +	crtc_pdev = of_find_device_by_node(crtc_node);
> +	if (!crtc_pdev) {
> +		DRM_ERROR("No CRTC device attached to OF node\n");
> +		return ERR_PTR(-EINVAL);
> +	}
> +
> +	return platform_get_drvdata(crtc_pdev);
> +}
> +
> +struct drm_encoder *vc4_hdmi_encoder_init(struct drm_device *dev)
> +{
> +	struct vc4_dev *vc4 = to_vc4_dev(dev);
> +	struct drm_encoder *encoder = NULL;
> +	struct vc4_hdmi_encoder *vc4_hdmi_encoder;
> +	struct drm_crtc *crtc;
> +	int ret;
> +
> +	vc4_hdmi_encoder = devm_kzalloc(dev->dev, sizeof(*vc4_hdmi_encoder),
> +					GFP_KERNEL);
> +	if (!vc4_hdmi_encoder) {
> +		ret = -ENOMEM;
> +		goto fail;
> +	}
> +	encoder = &vc4_hdmi_encoder->base;
> +
> +	crtc = vc4_get_crtc_node(vc4->hdmi->pdev);
> +	if (IS_ERR(crtc)) {
> +		ret = PTR_ERR(crtc);
> +		goto fail;
> +	}
> +
> +	drm_encoder_init(dev, encoder, &vc4_hdmi_encoder_funcs,
> +			 DRM_MODE_ENCODER_TMDS);
> +	drm_encoder_helper_add(encoder, &vc4_hdmi_encoder_helper_funcs);
> +
> +	encoder->possible_crtcs = drm_crtc_mask(crtc);
> +
> +	return encoder;
> +
> +fail:
> +	if (encoder)
> +		vc4_encoder_destroy(encoder);
> +
> +	return ERR_PTR(ret);
> +}
> +
> +/* Reads out the current HDMI mode progreamming at driver load time.
> + *
> + * This is currently used for later filtering out of the DDC-probed
> + * video modes, since we can't actually change modes due to not having
> + * control of the necessary clocks.  Later on, we may end up reusing
> + * this for skipping modesets at boot time.
> + */
> +static void
> +vc4_hdmi_get_boot_display_mode(struct vc4_dev *vc4)
> +{
> +	struct drm_display_mode *mode = &vc4->hdmi->boot_mode;
> +	u32 horza = HDMI_READ(VC4_HDMI_HORZA);
> +	u32 horzb = HDMI_READ(VC4_HDMI_HORZB);
> +	u32 verta = HDMI_READ(VC4_HDMI_VERTA0);
> +	u32 vertb = HDMI_READ(VC4_HDMI_VERTB0);
> +
> +	memset(mode, 0, sizeof(*mode));
> +
> +	if (!(horza & VC4_HDMI_HORZA_VPOS))
> +		mode->flags |= DRM_MODE_FLAG_NVSYNC;
> +	if (!(horza & VC4_HDMI_HORZA_HPOS))
> +		mode->flags |= DRM_MODE_FLAG_NHSYNC;
> +	mode->hdisplay = VC4_GET_FIELD(horza, VC4_HDMI_HORZA_HAP);
> +	mode->hsync_start = (mode->hdisplay +
> +			     VC4_GET_FIELD(horzb, VC4_HDMI_HORZB_HFP));
> +	mode->hsync_end = (mode->hsync_start +
> +			   VC4_GET_FIELD(horzb, VC4_HDMI_HORZB_HSP));
> +	mode->htotal = (mode->hsync_end +
> +			VC4_GET_FIELD(horzb, VC4_HDMI_HORZB_HBP));
> +
> +	mode->vdisplay = VC4_GET_FIELD(verta, VC4_HDMI_VERTA_VAL);
> +	mode->vsync_start = (mode->vdisplay +
> +			     VC4_GET_FIELD(verta, VC4_HDMI_VERTA_VFP));
> +	mode->vsync_end = (mode->vsync_start +
> +			   VC4_GET_FIELD(verta, VC4_HDMI_VERTA_VSP));
> +	mode->vtotal = (mode->vsync_end +
> +			VC4_GET_FIELD(vertb, VC4_HDMI_VERTB_VBP));
> +}
> +
> +static int vc4_hdmi_bind(struct device *dev, struct device *master, void *data)
> +{
> +	struct platform_device *pdev = to_platform_device(dev);
> +	struct drm_device *drm = dev_get_drvdata(master);
> +	struct vc4_dev *vc4 = drm->dev_private;
> +	struct vc4_hdmi *hdmi;
> +	struct device_node *ddc_node;
> +	u32 value;
> +
> +	hdmi = devm_kzalloc(dev, sizeof(*hdmi), GFP_KERNEL);
> +	if (!hdmi)
> +		return -ENOMEM;
> +
> +	hdmi->pdev = pdev;
> +	hdmi->hdmicore_regs = vc4_ioremap_regs(pdev, 0);
> +	if (IS_ERR(hdmi->hdmicore_regs))
> +		return PTR_ERR(hdmi->hdmicore_regs);
> +
> +	hdmi->hd_regs = vc4_ioremap_regs(pdev, 1);
> +	if (IS_ERR(hdmi->hd_regs))
> +		return PTR_ERR(hdmi->hd_regs);
> +
> +	/* DDC i2c driver */
> +	ddc_node = of_parse_phandle(dev->of_node, "ddc", 0);
> +	if (!ddc_node) {
> +		DRM_ERROR("Failed to find ddc node in device tree\n");
> +		return -ENODEV;
> +	}
> +
> +	hdmi->ddc = of_find_i2c_adapter_by_node(ddc_node);
> +	if (!hdmi->ddc) {
> +		DRM_ERROR("Failed to get ddc i2c adapter by node\n");
> +		return -EPROBE_DEFER;
> +	}
> +
> +	/* Only use the GPIO HPD pin if present in the DT, otherwise
> +	 * we'll use the HDMI core's register.
> +	 */
> +	if (of_find_property(dev->of_node, "hpd-gpio", &value)) {
> +		hdmi->hpd_gpio = of_get_named_gpio(dev->of_node, "hpd-gpio", 0);
> +		if (hdmi->hpd_gpio < 0)
> +			return hdmi->hpd_gpio;
> +	}
> +
> +	vc4->hdmi = hdmi;
> +
> +	/* HDMI core must be enabled. */
> +	WARN_ON_ONCE((HD_READ(VC4_HD_M_CTL) & VC4_HD_M_ENABLE) == 0);
> +
> +	vc4_hdmi_get_boot_display_mode(vc4);
> +
> +	return 0;
> +}
> +
> +static void vc4_hdmi_unbind(struct device *dev, struct device *master,
> +			    void *data)
> +{
> +	struct drm_device *drm = dev_get_drvdata(master);
> +	struct vc4_dev *vc4 = drm->dev_private;
> +
> +	put_device(&vc4->hdmi->ddc->dev);
> +
> +	vc4->hdmi = NULL;
> +}
> +
> +static const struct component_ops vc4_hdmi_ops = {
> +	.bind   = vc4_hdmi_bind,
> +	.unbind = vc4_hdmi_unbind,
> +};
> +
> +static int vc4_hdmi_dev_probe(struct platform_device *pdev)
> +{
> +	return component_add(&pdev->dev, &vc4_hdmi_ops);
> +}
> +
> +static int vc4_hdmi_dev_remove(struct platform_device *pdev)
> +{
> +	component_del(&pdev->dev, &vc4_hdmi_ops);
> +	return 0;
> +}
> +
> +static const struct of_device_id vc4_hdmi_dt_match[] = {
> +	{ .compatible = "brcm,vc4-hdmi" },
> +	{}
> +};
> +
> +struct platform_driver vc4_hdmi_driver = {
> +	.probe = vc4_hdmi_dev_probe,
> +	.remove = vc4_hdmi_dev_remove,
> +	.driver = {
> +		.name = "vc4_hdmi",
> +		.of_match_table = vc4_hdmi_dt_match,
> +	},
> +};
> diff --git a/drivers/gpu/drm/vc4/vc4_hvs.c b/drivers/gpu/drm/vc4/vc4_hvs.c
> new file mode 100644
> index 0000000..34906fd
> --- /dev/null
> +++ b/drivers/gpu/drm/vc4/vc4_hvs.c
> @@ -0,0 +1,161 @@
> +/*
> + * Copyright (C) 2015 Broadcom
> + *
> + * 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.
> + */
> +
> +/**
> + * DOC: VC4 HVS module.
> + *
> + * The HVS is the piece of hardware that does translation, scaling,
> + * colorspace conversion, and compositing of pixels stored in
> + * framebuffers into a FIFO of pixels going out to the Pixel Valve
> + * (CRTC).
> + *
> + * There is a single global HVS, with multiple output FIFOs that can
> + * be consumed by the PVs.  This file just manages the resources for
> + * the HVS, while the vc4_crtc.c code actually drives HVS setup for
> + * each CRTC.
> + */
> +
> +#include "linux/component.h"
> +#include "vc4_drv.h"
> +#include "vc4_regs.h"
> +
> +#define HVS_REG(reg) { reg, #reg }
> +static const struct {
> +	u32 reg;
> +	const char *name;
> +} hvs_regs[] = {
> +	HVS_REG(SCALER_DISPCTRL),
> +	HVS_REG(SCALER_DISPSTAT),
> +	HVS_REG(SCALER_DISPID),
> +	HVS_REG(SCALER_DISPECTRL),
> +	HVS_REG(SCALER_DISPPROF),
> +	HVS_REG(SCALER_DISPDITHER),
> +	HVS_REG(SCALER_DISPEOLN),
> +	HVS_REG(SCALER_DISPLIST0),
> +	HVS_REG(SCALER_DISPLIST1),
> +	HVS_REG(SCALER_DISPLIST2),
> +	HVS_REG(SCALER_DISPLSTAT),
> +	HVS_REG(SCALER_DISPLACT0),
> +	HVS_REG(SCALER_DISPLACT1),
> +	HVS_REG(SCALER_DISPLACT2),
> +	HVS_REG(SCALER_DISPCTRL0),
> +	HVS_REG(SCALER_DISPBKGND0),
> +	HVS_REG(SCALER_DISPSTAT0),
> +	HVS_REG(SCALER_DISPBASE0),
> +	HVS_REG(SCALER_DISPCTRL1),
> +	HVS_REG(SCALER_DISPBKGND1),
> +	HVS_REG(SCALER_DISPSTAT1),
> +	HVS_REG(SCALER_DISPBASE1),
> +	HVS_REG(SCALER_DISPCTRL2),
> +	HVS_REG(SCALER_DISPBKGND2),
> +	HVS_REG(SCALER_DISPSTAT2),
> +	HVS_REG(SCALER_DISPBASE2),
> +	HVS_REG(SCALER_DISPALPHA2),
> +};
> +
> +void vc4_hvs_dump_state(struct drm_device *dev)
> +{
> +	struct vc4_dev *vc4 = to_vc4_dev(dev);
> +	int i;
> +
> +	for (i = 0; i < ARRAY_SIZE(hvs_regs); i++) {
> +		DRM_INFO("0x%04x (%s): 0x%08x\n",
> +			 hvs_regs[i].reg, hvs_regs[i].name,
> +			 HVS_READ(hvs_regs[i].reg));
> +	}
> +
> +	DRM_INFO("HVS ctx:\n");
> +	for (i = 0; i < 64; i += 4) {
> +		DRM_INFO("0x%08x (%s): 0x%08x 0x%08x 0x%08x 0x%08x\n",
> +			 i * 4, i < HVS_BOOTLOADER_DLIST_END ? "B" : "D",
> +			 ((uint32_t *)vc4->hvs->dlist)[i + 0],
> +			 ((uint32_t *)vc4->hvs->dlist)[i + 1],
> +			 ((uint32_t *)vc4->hvs->dlist)[i + 2],
> +			 ((uint32_t *)vc4->hvs->dlist)[i + 3]);
> +	}
> +}
> +
> +#ifdef CONFIG_DEBUG_FS
> +int vc4_hvs_debugfs_regs(struct seq_file *m, void *unused)
> +{
> +	struct drm_info_node *node = (struct drm_info_node *) m->private;
> +	struct drm_device *dev = node->minor->dev;
> +	struct vc4_dev *vc4 = to_vc4_dev(dev);
> +	int i;
> +
> +	for (i = 0; i < ARRAY_SIZE(hvs_regs); i++) {
> +		seq_printf(m, "%s (0x%04x): 0x%08x\n",
> +			   hvs_regs[i].name, hvs_regs[i].reg,
> +			   HVS_READ(hvs_regs[i].reg));
> +	}
> +
> +	return 0;
> +}
> +#endif
> +
> +static int vc4_hvs_bind(struct device *dev, struct device *master, void *data)
> +{
> +	struct platform_device *pdev = to_platform_device(dev);
> +	struct drm_device *drm = dev_get_drvdata(master);
> +	struct vc4_dev *vc4 = drm->dev_private;
> +	struct vc4_hvs *hvs = NULL;
> +
> +	hvs = devm_kzalloc(&pdev->dev, sizeof(*hvs), GFP_KERNEL);
> +	if (!hvs)
> +		return -ENOMEM;
> +
> +	hvs->pdev = pdev;
> +
> +	hvs->regs = vc4_ioremap_regs(pdev, 0);
> +	if (IS_ERR(hvs->regs))
> +		return PTR_ERR(hvs->regs);
> +
> +	hvs->dlist = hvs->regs + SCALER_DLIST_START;
> +
> +	vc4->hvs = hvs;
> +	return 0;
> +}
> +
> +static void vc4_hvs_unbind(struct device *dev, struct device *master,
> +			   void *data)
> +{
> +	struct drm_device *drm = dev_get_drvdata(master);
> +	struct vc4_dev *vc4 = drm->dev_private;
> +
> +	vc4->hvs = NULL;
> +}
> +
> +static const struct component_ops vc4_hvs_ops = {
> +	.bind   = vc4_hvs_bind,
> +	.unbind = vc4_hvs_unbind,
> +};
> +
> +static int vc4_hvs_dev_probe(struct platform_device *pdev)
> +{
> +	return component_add(&pdev->dev, &vc4_hvs_ops);
> +}
> +
> +static int vc4_hvs_dev_remove(struct platform_device *pdev)
> +{
> +	component_del(&pdev->dev, &vc4_hvs_ops);
> +	return 0;
> +}
> +
> +static const struct of_device_id vc4_hvs_dt_match[] = {
> +	{ .compatible = "brcm,vc4-hvs" },
> +	{}
> +};
> +
> +struct platform_driver vc4_hvs_driver = {
> +	.probe = vc4_hvs_dev_probe,
> +	.remove = vc4_hvs_dev_remove,
> +	.driver = {
> +		.name = "vc4_hvs",
> +		.of_match_table = vc4_hvs_dt_match,
> +	},
> +};
> diff --git a/drivers/gpu/drm/vc4/vc4_kms.c b/drivers/gpu/drm/vc4/vc4_kms.c
> new file mode 100644
> index 0000000..e5e96bc
> --- /dev/null
> +++ b/drivers/gpu/drm/vc4/vc4_kms.c
> @@ -0,0 +1,84 @@
> +/*
> + * Copyright (C) 2015 Broadcom
> + *
> + * 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.
> + */
> +
> +/**
> + * DOC: VC4 KMS
> + *
> + * This is the general code for implementing KMS mode setting that
> + * doesn't clearly associate with any of the other objects (plane,
> + * crtc, HDMI encoder).
> + */
> +
> +#include "drm_crtc.h"
> +#include "drm_atomic_helper.h"
> +#include "drm_crtc_helper.h"
> +#include "drm_plane_helper.h"
> +#include "drm_fb_cma_helper.h"
> +#include "vc4_drv.h"
> +
> +static const struct drm_mode_config_funcs vc4_mode_funcs = {
> +	.atomic_check = drm_atomic_helper_check,
> +	.atomic_commit = drm_atomic_helper_commit,
> +	.fb_create = drm_fb_cma_create,
> +};
> +
> +/* Calls out to initialize all of the VC4 KMS objects. */
> +static int vc4_init_modeset_objects(struct drm_device *dev)
> +{
> +	struct drm_encoder *encoder;
> +	struct drm_connector *connector;
> +	int ret = 0;
> +
> +	encoder = vc4_hdmi_encoder_init(dev);
> +	if (IS_ERR(encoder)) {
> +		dev_err(dev->dev, "failed to construct HDMI encoder\n");
> +		ret = PTR_ERR(encoder);
> +		goto fail;
> +	}
> +
> +	connector = vc4_hdmi_connector_init(dev, encoder);
> +	if (IS_ERR(connector)) {
> +		ret = PTR_ERR(connector);
> +		dev_err(dev->dev, "failed to initialize HDMI connector\n");
> +		goto fail;
> +	}
> +
> +fail:
> +	return ret;
> +}
> +
> +int vc4_kms_load(struct drm_device *dev)
> +{
> +	int ret;
> +
> +	ret = drm_vblank_init(dev, dev->mode_config.num_crtc);
> +	if (ret < 0) {
> +		dev_err(dev->dev, "failed to initialize vblank\n");
> +		return ret;
> +	}
> +
> +	dev->mode_config.max_width = 2048;
> +	dev->mode_config.max_height = 2048;
> +	dev->mode_config.funcs = &vc4_mode_funcs;
> +	dev->mode_config.preferred_depth = 24;
> +
> +	ret = vc4_init_modeset_objects(dev);
> +	if (ret)
> +		goto fail;
> +
> +	drm_mode_config_reset(dev);
> +
> +	drm_fbdev_cma_init(dev, 32,
> +			   dev->mode_config.num_crtc,
> +			   dev->mode_config.num_connector);
> +
> +	drm_kms_helper_poll_init(dev);
> +
> +fail:
> +	return ret;
> +}
> diff --git a/drivers/gpu/drm/vc4/vc4_plane.c b/drivers/gpu/drm/vc4/vc4_plane.c
> new file mode 100644
> index 0000000..cdd8b10
> --- /dev/null
> +++ b/drivers/gpu/drm/vc4/vc4_plane.c
> @@ -0,0 +1,320 @@
> +/*
> + * Copyright (C) 2015 Broadcom
> + *
> + * 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.
> + */
> +
> +/**
> + * DOC: VC4 plane module
> + *
> + * Each DRM plane is a layer of pixels being scanned out by the HVS.
> + *
> + * At atomic modeset check time, we compute the HVS display element
> + * state that would be necessary for displaying the plane (giving us a
> + * chance to figure out if a plane configuration is invalid), then at
> + * atomic flush time the CRTC will ask us to write our element state
> + * into the region of the HVS that it has allocated for us.
> + */
> +
> +#include "vc4_drv.h"
> +#include "vc4_regs.h"
> +#include "drm_atomic_helper.h"
> +#include "drm_fb_cma_helper.h"
> +#include "drm_plane_helper.h"
> +
> +struct vc4_plane_state {
> +	struct drm_plane_state base;
> +	u32 *dlist;
> +	u32 dlist_size; /* Number of dwords in allocated for the display list */
> +	u32 dlist_count; /* Number of used dwords in the display list. */
> +};
> +
> +static inline struct vc4_plane_state *
> +to_vc4_plane_state(struct drm_plane_state *state)
> +{
> +	return (struct vc4_plane_state *)state;
> +}
> +
> +static const struct hvs_format {
> +	u32 drm; /* DRM_FORMAT_* */
> +	u32 hvs; /* HVS_FORMAT_* */
> +	u32 pixel_order;
> +	bool has_alpha;
> +} hvs_formats[] = {
> +	{
> +		.drm = DRM_FORMAT_XRGB8888, .hvs = HVS_PIXEL_FORMAT_RGBA8888,
> +		.pixel_order = HVS_PIXEL_ORDER_ABGR, .has_alpha = false,
> +	},
> +	{
> +		.drm = DRM_FORMAT_ARGB8888, .hvs = HVS_PIXEL_FORMAT_RGBA8888,
> +		.pixel_order = HVS_PIXEL_ORDER_ABGR, .has_alpha = true,
> +	},
> +};
> +
> +static const struct hvs_format *vc4_get_hvs_format(u32 drm_format)
> +{
> +	unsigned i;
> +
> +	for (i = 0; i < ARRAY_SIZE(hvs_formats); i++) {
> +		if (hvs_formats[i].drm == drm_format)
> +			return &hvs_formats[i];
> +	}
> +
> +	return NULL;
> +}
> +
> +static bool plane_enabled(struct drm_plane_state *state)
> +{
> +	return state->fb && state->crtc;
> +}
> +
> +struct drm_plane_state *vc4_plane_duplicate_state(struct drm_plane *plane)
> +{
> +	struct vc4_plane_state *vc4_state;
> +
> +	if (WARN_ON(!plane->state))
> +		return NULL;
> +
> +	vc4_state = kmemdup(plane->state, sizeof(*vc4_state), GFP_KERNEL);
> +	if (!vc4_state)
> +		return NULL;
> +
> +	__drm_atomic_helper_plane_duplicate_state(plane, &vc4_state->base);
> +
> +	if (vc4_state->dlist) {
> +		vc4_state->dlist = kmemdup(vc4_state->dlist,
> +					   vc4_state->dlist_count * 4,
> +					   GFP_KERNEL);
> +		if (!vc4_state->dlist) {
> +			kfree(vc4_state);
> +			return NULL;
> +		}
> +		vc4_state->dlist_size = vc4_state->dlist_count;
> +	}
> +
> +	return &vc4_state->base;
> +}
> +
> +void vc4_plane_destroy_state(struct drm_plane *plane,
> +			     struct drm_plane_state *state)
> +{
> +	struct vc4_plane_state *vc4_state = to_vc4_plane_state(state);
> +
> +	kfree(vc4_state->dlist);
> +	__drm_atomic_helper_plane_destroy_state(plane, &vc4_state->base);
> +	kfree(state);
> +}
> +
> +/* Called during init to allocate the plane's atomic state. */
> +void vc4_plane_reset(struct drm_plane *plane)
> +{
> +	struct vc4_plane_state *vc4_state;
> +
> +	WARN_ON(plane->state);
> +
> +	vc4_state = kzalloc(sizeof(*vc4_state), GFP_KERNEL);
> +	if (!vc4_state)
> +		return;
> +
> +	plane->state = &vc4_state->base;
> +	vc4_state->base.plane = plane;
> +}
> +
> +static void vc4_dlist_write(struct vc4_plane_state *vc4_state, u32 val)
> +{
> +	if (vc4_state->dlist_count == vc4_state->dlist_size) {
> +		u32 new_size = max(4u, vc4_state->dlist_count * 2);
> +		u32 *new_dlist = kmalloc(new_size * 4, GFP_KERNEL);
> +
> +		if (!new_dlist)
> +			return;
> +		memcpy(new_dlist, vc4_state->dlist, vc4_state->dlist_count * 4);
> +
> +		kfree(vc4_state->dlist);
> +		vc4_state->dlist = new_dlist;
> +		vc4_state->dlist_size = new_size;
> +	}
> +
> +	vc4_state->dlist[vc4_state->dlist_count++] = val;
> +}
> +
> +/* Writes out a full display list for an active plane to the plane's
> + * private dlist state.
> + */
> +static int vc4_plane_mode_set(struct drm_plane *plane,
> +			      struct drm_plane_state *state)
> +{
> +	struct vc4_plane_state *vc4_state = to_vc4_plane_state(state);
> +	struct drm_framebuffer *fb = state->fb;
> +	struct drm_gem_cma_object *bo = drm_fb_cma_get_gem_obj(fb, 0);
> +	u32 ctl0_offset = vc4_state->dlist_count;
> +	const struct hvs_format *format = vc4_get_hvs_format(fb->pixel_format);
> +	uint32_t offset = fb->offsets[0];
> +	int crtc_x = state->crtc_x;
> +	int crtc_y = state->crtc_y;
> +	int crtc_w = state->crtc_w;
> +	int crtc_h = state->crtc_h;
> +
> +	if (crtc_x < 0) {
> +		offset += drm_format_plane_cpp(fb->pixel_format, 0) * -crtc_x;
> +		crtc_w += crtc_x;
> +		crtc_x = 0;
> +	}
> +
> +	if (crtc_y < 0) {
> +		offset += fb->pitches[0] * -crtc_y;
> +		crtc_h += crtc_y;
> +		crtc_y = 0;
> +	}
> +
> +	vc4_dlist_write(vc4_state,
> +			SCALER_CTL0_VALID |
> +			(format->pixel_order << SCALER_CTL0_ORDER_SHIFT) |
> +			(format->hvs << SCALER_CTL0_PIXEL_FORMAT_SHIFT) |
> +			SCALER_CTL0_UNITY);
> +
> +	/* Position Word 0: Image Positions and Alpha Value */
> +	vc4_dlist_write(vc4_state,
> +			VC4_SET_FIELD(0xff, SCALER_POS0_FIXED_ALPHA) |
> +			VC4_SET_FIELD(crtc_x, SCALER_POS0_START_X) |
> +			VC4_SET_FIELD(crtc_y, SCALER_POS0_START_Y));
> +
> +	/* Position Word 1: Scaled Image Dimensions.
> +	 * Skipped due to SCALER_CTL0_UNITY scaling.
> +	 */
> +
> +	/* Position Word 2: Source Image Size, Alpha Mode */
> +	vc4_dlist_write(vc4_state,
> +			VC4_SET_FIELD(format->has_alpha ?
> +				      SCALER_POS2_ALPHA_MODE_PIPELINE :
> +				      SCALER_POS2_ALPHA_MODE_FIXED,
> +				      SCALER_POS2_ALPHA_MODE) |
> +			VC4_SET_FIELD(crtc_w, SCALER_POS2_WIDTH) |
> +			VC4_SET_FIELD(crtc_h, SCALER_POS2_HEIGHT));
> +
> +	/* Position Word 3: Context.  Written by the HVS. */
> +	vc4_dlist_write(vc4_state, 0xc0c0c0c0);
> +
> +	/* Pointer Word 0: RGB / Y Pointer */
> +	vc4_dlist_write(vc4_state, bo->paddr + offset);
> +
> +	/* Pointer Context Word 0: Written by the HVS */
> +	vc4_dlist_write(vc4_state, 0xc0c0c0c0);
> +
> +	/* Pitch word 0: Pointer 0 Pitch */
> +	vc4_dlist_write(vc4_state,
> +			VC4_SET_FIELD(fb->pitches[0], SCALER_SRC_PITCH));
> +
> +	vc4_state->dlist[ctl0_offset] |=
> +		VC4_SET_FIELD(vc4_state->dlist_count, SCALER_CTL0_SIZE);
> +
> +	return 0;
> +}
> +
> +/* If a modeset involves changing the setup of a plane, the atomic
> + * infrastructure will call this to validate a proposed plane setup.
> + * However, if a plane isn't getting updated, this (and the
> + * corresponding vc4_plane_atomic_update) won't get called.  Thus, we
> + * compute the dlist here and have all active plane dlists get updated
> + * in the CRTC's flush.
> + */
> +static int vc4_plane_atomic_check(struct drm_plane *plane,
> +				  struct drm_plane_state *state)
> +{
> +	struct vc4_plane_state *vc4_state = to_vc4_plane_state(state);
> +
> +	vc4_state->dlist_count = 0;
> +
> +	if (plane_enabled(state))
> +		return vc4_plane_mode_set(plane, state);
> +	else
> +		return 0;
> +}
> +
> +static void vc4_plane_atomic_update(struct drm_plane *plane,
> +				    struct drm_plane_state *old_state)
> +{
> +	/* No contents here.  Since we don't know where in the CRTC's
> +	 * dlist we should be stored, our dlist is uploaded to the
> +	 * hardware with vc4_plane_write_dlist() at CRTC atomic_flush
> +	 * time.
> +	 */
> +}
> +
> +u32 vc4_plane_write_dlist(struct drm_plane *plane, u32 __iomem *dlist)
> +{
> +	struct vc4_plane_state *vc4_state = to_vc4_plane_state(plane->state);
> +	int i;
> +
> +	/* Can't memcpy_toio() because it needs to be 32-bit writes. */
> +	for (i = 0; i < vc4_state->dlist_count; i++)
> +		writel(vc4_state->dlist[i], &dlist[i]);
> +
> +	return vc4_state->dlist_count;
> +}
> +
> +u32 vc4_plane_dlist_size(struct drm_plane_state *state)
> +{
> +	struct vc4_plane_state *vc4_state = to_vc4_plane_state(state);
> +
> +	return vc4_state->dlist_count;
> +}
> +
> +static const struct drm_plane_helper_funcs vc4_plane_helper_funcs = {
> +	.prepare_fb = NULL,
> +	.cleanup_fb = NULL,
> +	.atomic_check = vc4_plane_atomic_check,
> +	.atomic_update = vc4_plane_atomic_update,
> +};
> +
> +static void vc4_plane_destroy(struct drm_plane *plane)
> +{
> +	drm_plane_helper_disable(plane);
> +	drm_plane_cleanup(plane);
> +}
> +
> +static const struct drm_plane_funcs vc4_plane_funcs = {
> +	.update_plane = drm_atomic_helper_update_plane,
> +	.disable_plane = drm_atomic_helper_disable_plane,
> +	.destroy = vc4_plane_destroy,
> +	.set_property = NULL,
> +	.reset = vc4_plane_reset,
> +	.atomic_duplicate_state = vc4_plane_duplicate_state,
> +	.atomic_destroy_state = vc4_plane_destroy_state,
> +};
> +
> +struct drm_plane *vc4_plane_init(struct drm_device *dev,
> +				 enum drm_plane_type type)
> +{
> +	struct drm_plane *plane = NULL;
> +	struct vc4_plane *vc4_plane;
> +	u32 formats[ARRAY_SIZE(hvs_formats)];
> +	int ret = 0;
> +	unsigned i;
> +
> +	vc4_plane = devm_kzalloc(dev->dev, sizeof(*vc4_plane),
> +				 GFP_KERNEL);
> +	if (!vc4_plane) {
> +		ret = -ENOMEM;
> +		goto fail;
> +	}
> +
> +	for (i = 0; i < ARRAY_SIZE(hvs_formats); i++)
> +		formats[i] = hvs_formats[i].drm;
> +	plane = &vc4_plane->base;
> +	ret = drm_universal_plane_init(dev, plane, 0xff,
> +				       &vc4_plane_funcs,
> +				       formats, ARRAY_SIZE(formats),
> +				       type);
> +
> +	drm_plane_helper_add(plane, &vc4_plane_helper_funcs);
> +
> +	return plane;
> +fail:
> +	if (plane)
> +		vc4_plane_destroy(plane);
> +
> +	return ERR_PTR(ret);
> +}
> diff --git a/drivers/gpu/drm/vc4/vc4_regs.h b/drivers/gpu/drm/vc4/vc4_regs.h
> new file mode 100644
> index 0000000..0eff631
> --- /dev/null
> +++ b/drivers/gpu/drm/vc4/vc4_regs.h
> @@ -0,0 +1,562 @@
> +/*
> + *  Copyright ? 2014-2015 Broadcom
> + *
> + * 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.
> + */
> +
> +#define VC4_MASK(high, low) (((1 << ((high) - (low) + 1)) - 1) << (low))
> +/* Using the GNU statement expression extension */
> +#define VC4_SET_FIELD(value, field)					\
> +	({								\
> +		uint32_t fieldval = (value) << field##_SHIFT;		\
> +		WARN_ON((fieldval & ~field##_MASK) != 0);		\
> +		fieldval & field##_MASK;				\
> +	 })
> +
> +#define VC4_GET_FIELD(word, field) (((word) & field##_MASK) >>		\
> +				    field##_SHIFT)
> +
> +#define V3D_IDENT0   0x00000
> +# define V3D_EXPECTED_IDENT0 \
> +	((2 << 24) | \
> +	('V' << 0) | \
> +	('3' << 8) | \
> +	 ('D' << 16))
> +
> +#define V3D_IDENT1   0x00004
> +/* Multiples of 1kb */
> +# define V3D_IDENT1_VPM_SIZE_MASK                      VC4_MASK(31, 28)
> +# define V3D_IDENT1_VPM_SIZE_SHIFT                     28
> +# define V3D_IDENT1_NSEM_MASK                          VC4_MASK(23, 16)
> +# define V3D_IDENT1_NSEM_SHIFT                         16
> +# define V3D_IDENT1_TUPS_MASK                          VC4_MASK(15, 12)
> +# define V3D_IDENT1_TUPS_SHIFT                         12
> +# define V3D_IDENT1_QUPS_MASK                          VC4_MASK(11, 8)
> +# define V3D_IDENT1_QUPS_SHIFT                         8
> +# define V3D_IDENT1_NSLC_MASK                          VC4_MASK(7, 4)
> +# define V3D_IDENT1_NSLC_SHIFT                         4
> +# define V3D_IDENT1_REV_MASK                           VC4_MASK(3, 0)
> +# define V3D_IDENT1_REV_SHIFT                          0
> +
> +#define V3D_IDENT2   0x00008
> +#define V3D_SCRATCH  0x00010
> +#define V3D_L2CACTL  0x00020
> +# define V3D_L2CACTL_L2CCLR                            (1 << 2)
> +# define V3D_L2CACTL_L2CDIS                            (1 << 1)
> +# define V3D_L2CACTL_L2CENA                            (1 << 0)
> +
> +#define V3D_SLCACTL  0x00024
> +# define V3D_SLCACTL_T1CC_MASK                         VC4_MASK(27, 24)
> +# define V3D_SLCACTL_T1CC_SHIFT                        24
> +# define V3D_SLCACTL_T0CC_MASK                         VC4_MASK(19, 16)
> +# define V3D_SLCACTL_T0CC_SHIFT                        16
> +# define V3D_SLCACTL_UCC_MASK                          VC4_MASK(11, 8)
> +# define V3D_SLCACTL_UCC_SHIFT                         8
> +# define V3D_SLCACTL_ICC_MASK                          VC4_MASK(3, 0)
> +# define V3D_SLCACTL_ICC_SHIFT                         0
> +
> +#define V3D_INTCTL   0x00030
> +#define V3D_INTENA   0x00034
> +#define V3D_INTDIS   0x00038
> +# define V3D_INT_SPILLUSE                              (1 << 3)
> +# define V3D_INT_OUTOMEM                               (1 << 2)
> +# define V3D_INT_FLDONE                                (1 << 1)
> +# define V3D_INT_FRDONE                                (1 << 0)
> +
> +#define V3D_CT0CS    0x00100
> +#define V3D_CT1CS    0x00104
> +#define V3D_CTNCS(n) (V3D_CT0CS + 4 * n)
> +# define V3D_CTRSTA      (1 << 15)
> +# define V3D_CTSEMA      (1 << 12)
> +# define V3D_CTRTSD      (1 << 8)
> +# define V3D_CTRUN       (1 << 5)
> +# define V3D_CTSUBS      (1 << 4)
> +# define V3D_CTERR       (1 << 3)
> +# define V3D_CTMODE      (1 << 0)
> +
> +#define V3D_CT0EA    0x00108
> +#define V3D_CT1EA    0x0010c
> +#define V3D_CTNEA(n) (V3D_CT0EA + 4 * (n))
> +#define V3D_CT0CA    0x00110
> +#define V3D_CT1CA    0x00114
> +#define V3D_CTNCA(n) (V3D_CT0CA + 4 * (n))
> +#define V3D_CT00RA0  0x00118
> +#define V3D_CT01RA0  0x0011c
> +#define V3D_CTNRA0(n) (V3D_CT00RA0 + 4 * (n))
> +#define V3D_CT0LC    0x00120
> +#define V3D_CT1LC    0x00124
> +#define V3D_CTNLC(n) (V3D_CT0LC + 4 * (n))
> +#define V3D_CT0PC    0x00128
> +#define V3D_CT1PC    0x0012c
> +#define V3D_CTNPC(n) (V3D_CT0PC + 4 * (n))
> +
> +#define V3D_PCS      0x00130
> +# define V3D_BMOOM       (1 << 8)
> +# define V3D_RMBUSY      (1 << 3)
> +# define V3D_RMACTIVE    (1 << 2)
> +# define V3D_BMBUSY      (1 << 1)
> +# define V3D_BMACTIVE    (1 << 0)
> +
> +#define V3D_BFC      0x00134
> +#define V3D_RFC      0x00138
> +#define V3D_BPCA     0x00300
> +#define V3D_BPCS     0x00304
> +#define V3D_BPOA     0x00308
> +#define V3D_BPOS     0x0030c
> +#define V3D_BXCF     0x00310
> +#define V3D_SQRSV0   0x00410
> +#define V3D_SQRSV1   0x00414
> +#define V3D_SQCNTL   0x00418
> +#define V3D_SRQPC    0x00430
> +#define V3D_SRQUA    0x00434
> +#define V3D_SRQUL    0x00438
> +#define V3D_SRQCS    0x0043c
> +#define V3D_VPACNTL  0x00500
> +#define V3D_VPMBASE  0x00504
> +#define V3D_PCTRC    0x00670
> +#define V3D_PCTRE    0x00674
> +#define V3D_PCTR0    0x00680
> +#define V3D_PCTRS0   0x00684
> +#define V3D_PCTR1    0x00688
> +#define V3D_PCTRS1   0x0068c
> +#define V3D_PCTR2    0x00690
> +#define V3D_PCTRS2   0x00694
> +#define V3D_PCTR3    0x00698
> +#define V3D_PCTRS3   0x0069c
> +#define V3D_PCTR4    0x006a0
> +#define V3D_PCTRS4   0x006a4
> +#define V3D_PCTR5    0x006a8
> +#define V3D_PCTRS5   0x006ac
> +#define V3D_PCTR6    0x006b0
> +#define V3D_PCTRS6   0x006b4
> +#define V3D_PCTR7    0x006b8
> +#define V3D_PCTRS7   0x006bc
> +#define V3D_PCTR8    0x006c0
> +#define V3D_PCTRS8   0x006c4
> +#define V3D_PCTR9    0x006c8
> +#define V3D_PCTRS9   0x006cc
> +#define V3D_PCTR10   0x006d0
> +#define V3D_PCTRS10  0x006d4
> +#define V3D_PCTR11   0x006d8
> +#define V3D_PCTRS11  0x006dc
> +#define V3D_PCTR12   0x006e0
> +#define V3D_PCTRS12  0x006e4
> +#define V3D_PCTR13   0x006e8
> +#define V3D_PCTRS13  0x006ec
> +#define V3D_PCTR14   0x006f0
> +#define V3D_PCTRS14  0x006f4
> +#define V3D_PCTR15   0x006f8
> +#define V3D_PCTRS15  0x006fc
> +#define V3D_BGE      0x00f00
> +#define V3D_FDBGO    0x00f04
> +#define V3D_FDBGB    0x00f08
> +#define V3D_FDBGR    0x00f0c
> +#define V3D_FDBGS    0x00f10
> +#define V3D_ERRSTAT  0x00f20
> +
> +#define PV_CONTROL				0x00
> +# define PV_CONTROL_FORMAT_MASK			VC4_MASK(23, 21)
> +# define PV_CONTROL_FORMAT_SHIFT		21
> +# define PV_CONTROL_FORMAT_24			0
> +# define PV_CONTROL_FORMAT_DSIV_16		1
> +# define PV_CONTROL_FORMAT_DSIC_16		2
> +# define PV_CONTROL_FORMAT_DSIV_18		3
> +# define PV_CONTROL_FORMAT_DSIV_24		4
> +
> +# define PV_CONTROL_FIFO_LEVEL_MASK		VC4_MASK(20, 15)
> +# define PV_CONTROL_FIFO_LEVEL_SHIFT		15
> +# define PV_CONTROL_CLR_AT_START		(1 << 14)
> +# define PV_CONTROL_TRIGGER_UNDERFLOW		(1 << 13)
> +# define PV_CONTROL_WAIT_HSTART			(1 << 12)
> +# define PV_CONTROL_CLK_SELECT_DSI		0
> +# define PV_CONTROL_CLK_SELECT_DPI_SMI_HDMI	1
> +# define PV_CONTROL_CLK_SELECT_MASK		VC4_MASK(3, 2)
> +# define PV_CONTROL_CLK_SELECT_SHIFT		2
> +# define PV_CONTROL_FIFO_CLR			(1 << 1)
> +# define PV_CONTROL_EN				(1 << 0)
> +
> +#define PV_V_CONTROL				0x04
> +# define PV_VCONTROL_CONTINUOUS			(1 << 1)
> +# define PV_VCONTROL_VIDEN			(1 << 0)
> +
> +#define PV_VSYNCD				0x08
> +
> +#define PV_HORZA				0x0c
> +# define PV_HORZA_HBP_MASK			VC4_MASK(31, 16)
> +# define PV_HORZA_HBP_SHIFT			16
> +# define PV_HORZA_HSYNC_MASK			VC4_MASK(15, 0)
> +# define PV_HORZA_HSYNC_SHIFT			0
> +
> +#define PV_HORZB				0x10
> +# define PV_HORZB_HFP_MASK			VC4_MASK(31, 16)
> +# define PV_HORZB_HFP_SHIFT			16
> +# define PV_HORZB_HACTIVE_MASK			VC4_MASK(15, 0)
> +# define PV_HORZB_HACTIVE_SHIFT			0
> +
> +#define PV_VERTA				0x14
> +# define PV_VERTA_VBP_MASK			VC4_MASK(31, 16)
> +# define PV_VERTA_VBP_SHIFT			16
> +# define PV_VERTA_VSYNC_MASK			VC4_MASK(15, 0)
> +# define PV_VERTA_VSYNC_SHIFT			0
> +
> +#define PV_VERTB				0x18
> +# define PV_VERTB_VFP_MASK			VC4_MASK(31, 16)
> +# define PV_VERTB_VFP_SHIFT			16
> +# define PV_VERTB_VACTIVE_MASK			VC4_MASK(15, 0)
> +# define PV_VERTB_VACTIVE_SHIFT			0
> +
> +#define PV_VERTA_EVEN				0x1c
> +#define PV_VERTB_EVEN				0x20
> +
> +#define PV_INTEN				0x24
> +#define PV_INTSTAT				0x28
> +# define PV_INT_VID_IDLE			(1 << 9)
> +# define PV_INT_VFP_END				(1 << 8)
> +# define PV_INT_VFP_START			(1 << 7)
> +# define PV_INT_VACT_START			(1 << 6)
> +# define PV_INT_VBP_START			(1 << 5)
> +# define PV_INT_VSYNC_START			(1 << 4)
> +# define PV_INT_HFP_START			(1 << 3)
> +# define PV_INT_HACT_START			(1 << 2)
> +# define PV_INT_HBP_START			(1 << 1)
> +# define PV_INT_HSYNC_START			(1 << 0)
> +
> +#define PV_STAT					0x2c
> +
> +#define PV_HACT_ACT				0x30
> +
> +#define SCALER_DISPCTRL                         0x00000000
> +/* Global register for clock gating the HVS */
> +# define SCALER_DISPCTRL_ENABLE			(1 << 31)
> +# define SCALER_DISPCTRL_DSP2EISLUR		(1 << 15)
> +# define SCALER_DISPCTRL_DSP1EISLUR		(1 << 14)
> +/* Enables Display 0 short line and underrun contribution to
> + * SCALER_DISPSTAT_IRQDISP0.  Note that short frame contributions are
> + * always enabled.
> + */
> +# define SCALER_DISPCTRL_DSP0EISLUR		(1 << 13)
> +# define SCALER_DISPCTRL_DSP2EIEOLN		(1 << 12)
> +# define SCALER_DISPCTRL_DSP2EIEOF		(1 << 11)
> +# define SCALER_DISPCTRL_DSP1EIEOLN		(1 << 10)
> +# define SCALER_DISPCTRL_DSP1EIEOF		(1 << 9)
> +/* Enables Display 0 end-of-line-N contribution to
> + * SCALER_DISPSTAT_IRQDISP0
> + */
> +# define SCALER_DISPCTRL_DSP0EIEOLN		(1 << 8)
> +/* Enables Display 0 EOF contribution to SCALER_DISPSTAT_IRQDISP0 */
> +# define SCALER_DISPCTRL_DSP0EIEOF		(1 << 7)
> +
> +# define SCALER_DISPCTRL_SLVRDEIRQ		(1 << 6)
> +# define SCALER_DISPCTRL_SLVWREIRQ		(1 << 5)
> +# define SCALER_DISPCTRL_DMAEIRQ		(1 << 4)
> +# define SCALER_DISPCTRL_DISP2EIRQ		(1 << 3)
> +# define SCALER_DISPCTRL_DISP1EIRQ		(1 << 2)
> +/* Enables interrupt generation on the enabled EOF/EOLN/EISLUR
> + * bits and short frames..
> + */
> +# define SCALER_DISPCTRL_DISP0EIRQ		(1 << 1)
> +/* Enables interrupt generation on scaler profiler interrupt. */
> +# define SCALER_DISPCTRL_SCLEIRQ		(1 << 0)
> +
> +#define SCALER_DISPSTAT                         0x00000004
> +# define SCALER_DISPSTAT_COBLOW2		(1 << 29)
> +# define SCALER_DISPSTAT_EOLN2			(1 << 28)
> +# define SCALER_DISPSTAT_ESFRAME2		(1 << 27)
> +# define SCALER_DISPSTAT_ESLINE2		(1 << 26)
> +# define SCALER_DISPSTAT_EUFLOW2		(1 << 25)
> +# define SCALER_DISPSTAT_EOF2			(1 << 24)
> +
> +# define SCALER_DISPSTAT_COBLOW1		(1 << 21)
> +# define SCALER_DISPSTAT_EOLN1			(1 << 20)
> +# define SCALER_DISPSTAT_ESFRAME1		(1 << 19)
> +# define SCALER_DISPSTAT_ESLINE1		(1 << 18)
> +# define SCALER_DISPSTAT_EUFLOW1		(1 << 17)
> +# define SCALER_DISPSTAT_EOF1			(1 << 16)
> +
> +# define SCALER_DISPSTAT_RESP_MASK		VC4_MASK(15, 14)
> +# define SCALER_DISPSTAT_RESP_SHIFT		14
> +# define SCALER_DISPSTAT_RESP_OKAY		0
> +# define SCALER_DISPSTAT_RESP_EXOKAY		1
> +# define SCALER_DISPSTAT_RESP_SLVERR		2
> +# define SCALER_DISPSTAT_RESP_DECERR		3
> +
> +# define SCALER_DISPSTAT_COBLOW0		(1 << 13)
> +/* Set when the DISPEOLN line is done compositing. */
> +# define SCALER_DISPSTAT_EOLN0			(1 << 12)
> +/* Set when VSTART is seen but there are still pixels in the current
> + * output line.
> + */
> +# define SCALER_DISPSTAT_ESFRAME0		(1 << 11)
> +/* Set when HSTART is seen but there are still pixels in the current
> + * output line.
> + */
> +# define SCALER_DISPSTAT_ESLINE0		(1 << 10)
> +/* Set when the the downstream tries to read from the display FIFO
> + * while it's empty.
> + */
> +# define SCALER_DISPSTAT_EUFLOW0		(1 << 9)
> +/* Set when the display mode changes from RUN to EOF */
> +# define SCALER_DISPSTAT_EOF0			(1 << 8)
> +
> +/* Set on AXI invalid DMA ID error. */
> +# define SCALER_DISPSTAT_DMA_ERROR		(1 << 7)
> +/* Set on AXI slave read decode error */
> +# define SCALER_DISPSTAT_IRQSLVRD		(1 << 6)
> +/* Set on AXI slave write decode error */
> +# define SCALER_DISPSTAT_IRQSLVWR		(1 << 5)
> +/* Set when SCALER_DISPSTAT_DMA_ERROR is set, or
> + * SCALER_DISPSTAT_RESP_ERROR is not SCALER_DISPSTAT_RESP_OKAY.
> + */
> +# define SCALER_DISPSTAT_IRQDMA			(1 << 4)
> +# define SCALER_DISPSTAT_IRQDISP2		(1 << 3)
> +# define SCALER_DISPSTAT_IRQDISP1		(1 << 2)
> +/* Set when any of the EOF/EOLN/ESFRAME/ESLINE bits are set and their
> + * corresponding interrupt bit is enabled in DISPCTRL.
> + */
> +# define SCALER_DISPSTAT_IRQDISP0		(1 << 1)
> +/* On read, the profiler interrupt.  On write, clear *all* interrupt bits. */
> +# define SCALER_DISPSTAT_IRQSCL			(1 << 0)
> +
> +#define SCALER_DISPID                           0x00000008
> +#define SCALER_DISPECTRL                        0x0000000c
> +#define SCALER_DISPPROF                         0x00000010
> +#define SCALER_DISPDITHER                       0x00000014
> +#define SCALER_DISPEOLN                         0x00000018
> +#define SCALER_DISPLIST0                        0x00000020
> +#define SCALER_DISPLIST1                        0x00000024
> +#define SCALER_DISPLIST2                        0x00000028
> +#define SCALER_DISPLSTAT                        0x0000002c
> +#define SCALER_DISPLISTX(x)			(SCALER_DISPLIST0 +	\
> +						 (x) * (SCALER_DISPLIST1 - \
> +							SCALER_DISPLIST0))
> +
> +#define SCALER_DISPLACT0                        0x00000030
> +#define SCALER_DISPLACT1                        0x00000034
> +#define SCALER_DISPLACT2                        0x00000038
> +#define SCALER_DISPCTRL0                        0x00000040
> +# define SCALER_DISPCTRLX_ENABLE		(1 << 31)
> +# define SCALER_DISPCTRLX_RESET			(1 << 30)
> +# define SCALER_DISPCTRLX_WIDTH_MASK		VC4_MASK(23, 12)
> +# define SCALER_DISPCTRLX_WIDTH_SHIFT		12
> +# define SCALER_DISPCTRLX_HEIGHT_MASK		VC4_MASK(11, 0)
> +# define SCALER_DISPCTRLX_HEIGHT_SHIFT		0
> +
> +#define SCALER_DISPBKGND0                       0x00000044
> +#define SCALER_DISPSTAT0                        0x00000048
> +#define SCALER_DISPBASE0                        0x0000004c
> +# define SCALER_DISPSTATX_MODE_MASK		VC4_MASK(31, 30)
> +# define SCALER_DISPSTATX_MODE_SHIFT		30
> +# define SCALER_DISPSTATX_MODE_DISABLED		0
> +# define SCALER_DISPSTATX_MODE_INIT		1
> +# define SCALER_DISPSTATX_MODE_RUN		2
> +# define SCALER_DISPSTATX_MODE_EOF		3
> +# define SCALER_DISPSTATX_FULL			(1 << 29)
> +# define SCALER_DISPSTATX_EMPTY			(1 << 28)
> +#define SCALER_DISPCTRL1                        0x00000050
> +#define SCALER_DISPBKGND1                       0x00000054
> +#define SCALER_DISPSTAT1                        0x00000058
> +#define SCALER_DISPSTATX(x)			(SCALER_DISPSTAT0 +        \
> +						 (x) * (SCALER_DISPSTAT1 - \
> +							SCALER_DISPSTAT0))
> +#define SCALER_DISPBASE1                        0x0000005c
> +#define SCALER_DISPCTRL2                        0x00000060
> +#define SCALER_DISPCTRLX(x)			(SCALER_DISPCTRL0 +        \
> +						 (x) * (SCALER_DISPCTRL1 - \
> +							SCALER_DISPCTRL0))
> +#define SCALER_DISPBKGND2                       0x00000064
> +#define SCALER_DISPSTAT2                        0x00000068
> +#define SCALER_DISPBASE2                        0x0000006c
> +#define SCALER_DISPALPHA2                       0x00000070
> +#define SCALER_GAMADDR                          0x00000078
> +#define SCALER_GAMDATA                          0x000000e0
> +#define SCALER_DLIST_START                      0x00002000
> +#define SCALER_DLIST_SIZE                       0x00004000
> +
> +#define VC4_HDMI_CORE_REV			0x000
> +
> +#define VC4_HDMI_SW_RESET_CONTROL		0x004
> +# define VC4_HDMI_SW_RESET_FORMAT_DETECT	(1 << 1)
> +# define VC4_HDMI_SW_RESET_HDMI			(1 << 0)
> +
> +#define VC4_HDMI_HOTPLUG_INT			0x008
> +
> +#define VC4_HDMI_HOTPLUG			0x00c
> +# define VC4_HDMI_HOTPLUG_CONNECTED		(1 << 0)
> +
> +#define VC4_HDMI_RAM_PACKET_CONFIG		0x0a0
> +# define VC4_HDMI_RAM_PACKET_ENABLE		(1 << 16)
> +
> +#define VC4_HDMI_HORZA				0x0c4
> +# define VC4_HDMI_HORZA_VPOS			(1 << 14)
> +# define VC4_HDMI_HORZA_HPOS			(1 << 13)
> +/* Horizontal active pixels (hdisplay). */
> +# define VC4_HDMI_HORZA_HAP_MASK		VC4_MASK(12, 0)
> +# define VC4_HDMI_HORZA_HAP_SHIFT		0
> +
> +#define VC4_HDMI_HORZB				0x0c8
> +/* Horizontal pack porch (htotal - hsync_end). */
> +# define VC4_HDMI_HORZB_HBP_MASK		VC4_MASK(29, 20)
> +# define VC4_HDMI_HORZB_HBP_SHIFT		20
> +/* Horizontal sync pulse (hsync_end - hsync_start). */
> +# define VC4_HDMI_HORZB_HSP_MASK		VC4_MASK(19, 10)
> +# define VC4_HDMI_HORZB_HSP_SHIFT		10
> +/* Horizontal front porch (hsync_start - hdisplay). */
> +# define VC4_HDMI_HORZB_HFP_MASK		VC4_MASK(9, 0)
> +# define VC4_HDMI_HORZB_HFP_SHIFT		0
> +
> +#define VC4_HDMI_FIFO_CTL			0x05c
> +# define VC4_HDMI_FIFO_CTL_RECENTER_DONE	(1 << 14)
> +# define VC4_HDMI_FIFO_CTL_USE_EMPTY		(1 << 13)
> +# define VC4_HDMI_FIFO_CTL_ON_VB		(1 << 7)
> +# define VC4_HDMI_FIFO_CTL_RECENTER		(1 << 6)
> +# define VC4_HDMI_FIFO_CTL_FIFO_RESET		(1 << 5)
> +# define VC4_HDMI_FIFO_CTL_USE_PLL_LOCK		(1 << 4)
> +# define VC4_HDMI_FIFO_CTL_INV_CLK_XFR		(1 << 3)
> +# define VC4_HDMI_FIFO_CTL_CAPTURE_PTR		(1 << 2)
> +# define VC4_HDMI_FIFO_CTL_USE_FULL		(1 << 1)
> +# define VC4_HDMI_FIFO_CTL_MASTER_SLAVE_N	(1 << 0)
> +# define VC4_HDMI_FIFO_VALID_WRITE_MASK		0xefff
> +
> +#define VC4_HDMI_SCHEDULER_CONTROL		0x0c0
> +# define VC4_HDMI_SCHEDULER_CONTROL_MANUAL_FORMAT (1 << 15)
> +# define VC4_HDMI_SCHEDULER_CONTROL_IGNORE_VSYNC_PREDICTS (1 << 5)
> +# define VC4_HDMI_SCHEDULER_CONTROL_VERT_ALWAYS_KEEPOUT	(1 << 3)
> +# define VC4_HDMI_SCHEDULER_CONTROL_HDMI_ACTIVE	(1 << 1)
> +# define VC4_HDMI_SCHEDULER_CONTROL_MODE_HDMI	(1 << 0)
> +
> +#define VC4_HDMI_VERTA0				0x0cc
> +#define VC4_HDMI_VERTA1				0x0d4
> +/* Vertical sync pulse (vsync_end - vsync_start). */
> +# define VC4_HDMI_VERTA_VSP_MASK		VC4_MASK(24, 20)
> +# define VC4_HDMI_VERTA_VSP_SHIFT		20
> +/* Vertical front porch (vsync_start - vdisplay). */
> +# define VC4_HDMI_VERTA_VFP_MASK		VC4_MASK(19, 13)
> +# define VC4_HDMI_VERTA_VFP_SHIFT		13
> +/* Vertical active lines (vdisplay). */
> +# define VC4_HDMI_VERTA_VAL_MASK		VC4_MASK(12, 0)
> +# define VC4_HDMI_VERTA_VAL_SHIFT		0
> +
> +#define VC4_HDMI_VERTB0				0x0d0
> +#define VC4_HDMI_VERTB1				0x0d8
> +/* Vertical sync pulse offset (for interlaced) */
> +# define VC4_HDMI_VERTB_VSPO_MASK		VC4_MASK(21, 9)
> +# define VC4_HDMI_VERTB_VSPO_SHIFT		9
> +/* Vertical pack porch (vtotal - vsync_end). */
> +# define VC4_HDMI_VERTB_VBP_MASK		VC4_MASK(8, 0)
> +# define VC4_HDMI_VERTB_VBP_SHIFT		0
> +
> +#define VC4_HDMI_TX_PHY_RESET_CTL		0x2c0
> +
> +#define VC4_HD_M_CTL				0x00c
> +# define VC4_HD_M_SW_RST			(1 << 2)
> +# define VC4_HD_M_ENABLE			(1 << 0)
> +
> +#define VC4_HD_MAI_CTL				0x014
> +
> +#define VC4_HD_VID_CTL				0x038
> +# define VC4_HD_VID_CTL_ENABLE			(1 << 31)
> +# define VC4_HD_VID_CTL_UNDERFLOW_ENABLE	(1 << 30)
> +# define VC4_HD_VID_CTL_FRAME_COUNTER_RESET	(1 << 29)
> +# define VC4_HD_VID_CTL_VSYNC_LOW		(1 << 28)
> +# define VC4_HD_VID_CTL_HSYNC_LOW		(1 << 27)
> +
> +#define VC4_HD_CSC_CTL				0x040
> +# define VC4_HD_CSC_CTL_ORDER_MASK		VC4_MASK(7, 5)
> +# define VC4_HD_CSC_CTL_ORDER_SHIFT		5
> +# define VC4_HD_CSC_CTL_ORDER_RGB		0
> +# define VC4_HD_CSC_CTL_ORDER_BGR		1
> +# define VC4_HD_CSC_CTL_ORDER_BRG		2
> +# define VC4_HD_CSC_CTL_ORDER_GRB		3
> +# define VC4_HD_CSC_CTL_ORDER_GBR		4
> +# define VC4_HD_CSC_CTL_ORDER_RBG		5
> +# define VC4_HD_CSC_CTL_PADMSB			(1 << 4)
> +# define VC4_HD_CSC_CTL_MODE_MASK		VC4_MASK(3, 2)
> +# define VC4_HD_CSC_CTL_MODE_SHIFT		2
> +# define VC4_HD_CSC_CTL_MODE_RGB_TO_SD_YPRPB	0
> +# define VC4_HD_CSC_CTL_MODE_RGB_TO_HD_YPRPB	1
> +# define VC4_HD_CSC_CTL_MODE_CUSTOM		2
> +# define VC4_HD_CSC_CTL_RGB2YCC			(1 << 1)
> +# define VC4_HD_CSC_CTL_ENABLE			(1 << 0)
> +
> +#define VC4_HD_FRAME_COUNT			0x068
> +
> +/* HVS display list information. */
> +#define HVS_BOOTLOADER_DLIST_END                32
> +
> +enum hvs_pixel_format {
> +	/* 8bpp */
> +	HVS_PIXEL_FORMAT_RGB332 = 0,
> +	/* 16bpp */
> +	HVS_PIXEL_FORMAT_RGBA4444 = 1,
> +	HVS_PIXEL_FORMAT_RGB555 = 2,
> +	HVS_PIXEL_FORMAT_RGBA5551 = 3,
> +	HVS_PIXEL_FORMAT_RGB565 = 4,
> +	/* 24bpp */
> +	HVS_PIXEL_FORMAT_RGB888 = 5,
> +	HVS_PIXEL_FORMAT_RGBA6666 = 6,
> +	/* 32bpp */
> +	HVS_PIXEL_FORMAT_RGBA8888 = 7
> +};
> +
> +/* Note: the LSB is the rightmost character shown.  Only valid for
> + * HVS_PIXEL_FORMAT_RGB8888, not RGB888.
> + */
> +#define HVS_PIXEL_ORDER_RGBA			0
> +#define HVS_PIXEL_ORDER_BGRA			1
> +#define HVS_PIXEL_ORDER_ARGB			2
> +#define HVS_PIXEL_ORDER_ABGR			3
> +
> +#define HVS_PIXEL_ORDER_XBRG			0
> +#define HVS_PIXEL_ORDER_XRBG			1
> +#define HVS_PIXEL_ORDER_XRGB			2
> +#define HVS_PIXEL_ORDER_XBGR			3
> +
> +#define HVS_PIXEL_ORDER_XYCBCR			0
> +#define HVS_PIXEL_ORDER_XYCRCB			1
> +#define HVS_PIXEL_ORDER_YXCBCR			2
> +#define HVS_PIXEL_ORDER_YXCRCB			3
> +
> +#define SCALER_CTL0_END				(1 << 31)
> +#define SCALER_CTL0_VALID			(1 << 30)
> +
> +#define SCALER_CTL0_SIZE_MASK			VC4_MASK(29, 24)
> +#define SCALER_CTL0_SIZE_SHIFT			24
> +
> +#define SCALER_CTL0_HFLIP                       (1 << 16)
> +#define SCALER_CTL0_VFLIP                       (1 << 15)
> +
> +#define SCALER_CTL0_ORDER_MASK			VC4_MASK(14, 13)
> +#define SCALER_CTL0_ORDER_SHIFT			13
> +
> +/* Set to indicate no scaling. */
> +#define SCALER_CTL0_UNITY			(1 << 4)
> +
> +#define SCALER_CTL0_PIXEL_FORMAT_MASK		VC4_MASK(3, 0)
> +#define SCALER_CTL0_PIXEL_FORMAT_SHIFT		0
> +
> +#define SCALER_POS0_FIXED_ALPHA_MASK		VC4_MASK(31, 24)
> +#define SCALER_POS0_FIXED_ALPHA_SHIFT		24
> +
> +#define SCALER_POS0_START_Y_MASK		VC4_MASK(23, 12)
> +#define SCALER_POS0_START_Y_SHIFT		12
> +
> +#define SCALER_POS0_START_X_MASK		VC4_MASK(11, 0)
> +#define SCALER_POS0_START_X_SHIFT		0
> +
> +#define SCALER_POS2_ALPHA_MODE_MASK		VC4_MASK(31, 30)
> +#define SCALER_POS2_ALPHA_MODE_SHIFT		30
> +#define SCALER_POS2_ALPHA_MODE_PIPELINE		0
> +#define SCALER_POS2_ALPHA_MODE_FIXED		1
> +#define SCALER_POS2_ALPHA_MODE_FIXED_NONZERO	2
> +#define SCALER_POS2_ALPHA_MODE_FIXED_OVER_0x07	3
> +
> +#define SCALER_POS2_HEIGHT_MASK			VC4_MASK(27, 16)
> +#define SCALER_POS2_HEIGHT_SHIFT		16
> +
> +#define SCALER_POS2_WIDTH_MASK			VC4_MASK(11, 0)
> +#define SCALER_POS2_WIDTH_SHIFT			0
> +
> +#define SCALER_SRC_PITCH_MASK			VC4_MASK(15, 0)
> +#define SCALER_SRC_PITCH_SHIFT			0
> -- 
> 2.1.4
> 
> _______________________________________________
> dri-devel mailing list
> dri-devel at lists.freedesktop.org
> http://lists.freedesktop.org/mailman/listinfo/dri-devel

-- 
Daniel Vetter
Software Engineer, Intel Corporation
http://blog.ffwll.ch


From vaibhav.hiremath at linaro.org  Tue Aug 25 01:45:04 2015
From: vaibhav.hiremath at linaro.org (Vaibhav Hiremath)
Date: Tue, 25 Aug 2015 14:15:04 +0530
Subject: [PATCH-v2 2/5] mfd: 88pm800: Update the header file with 32K
 clk related macros
In-Reply-To: <20150825075556.GG19409@x1>
References: <1440442594-3102-1-git-send-email-vaibhav.hiremath@linaro.org>
 <1440442594-3102-4-git-send-email-vaibhav.hiremath@linaro.org>
 <20150825075556.GG19409@x1>
Message-ID: <55DC2B10.3080200@linaro.org>



On Tuesday 25 August 2015 01:25 PM, Lee Jones wrote:
> On Tue, 25 Aug 2015, Vaibhav Hiremath wrote:
>
>> Update header file with required macros for 32KHz buffered clock
>> output of 88PM800 family of device.
>> These macros will be used in clk provider driver.
>>
>> Signed-off-by: Vaibhav Hiremath <vaibhav.hiremath at linaro.org>
>> ---
>>   include/linux/mfd/88pm80x.h | 12 ++++++++++++
>>   1 file changed, 12 insertions(+)
>>
>> diff --git a/include/linux/mfd/88pm80x.h b/include/linux/mfd/88pm80x.h
>> index 122cfd2..0215d5f 100644
>> --- a/include/linux/mfd/88pm80x.h
>> +++ b/include/linux/mfd/88pm80x.h
>> @@ -91,6 +91,7 @@ enum {
>>   /* Referance and low power registers */
>>   #define PM800_LOW_POWER1		(0x20)
>>   #define PM800_LOW_POWER2		(0x21)
>> +#define PM800_LOW_POWER2_XO_LJ_EN	BIT(5)
>
> Some people add an extra space for register bits, which I quite like.
>
> So:
>
> #define SOME_REGISTER_ADDRESS	0x123
> #define  SOME_BIT_VALUE		BIT(4)
>
> Feel free to use it, or not.
>
>>   #define PM800_LOW_POWER_CONFIG3		(0x22)
>>   #define PM800_LDOBK_FREEZE		BIT(7)
>> @@ -138,6 +139,13 @@ enum {
>>   #define PM800_ALARM			BIT(5)
>>   #define PM800_RTC1_USE_XO		BIT(7)
>>
>> +#define PM800_32K_OUTX_SEL_MASK		0x3
>> +/* 32KHz clk output sel mode */
>> +#define PM800_32K_OUTX_SEL_ZERO		0x0
>> +#define PM800_32K_OUTX_SEL_INT_32KHZ	0x1
>> +#define PM800_32K_OUTX_SEL_XO_32KHZ	0x2
>> +#define PM800_32K_OUTX_SEL_HIZ		0x3
>> +
>>   /* Regulator Control Registers: BUCK1,BUCK5,LDO1 have DVC */
>>
>>   /* buck registers */
>> @@ -208,6 +216,10 @@ enum {
>>   #define PM800_PMOD_MEAS1		0x52
>>   #define PM800_PMOD_MEAS2		0x53
>>
>> +/* Oscillator control */
>> +#define PM800_OSC_CNTRL1		0x50
>> +#define PM800_OSC_CNTRL1_OSC_FREERUN_EN	BIT(1)
>
> 0x50 goes before 0x52 (and 0x51 if it's there).

Will reorder in next version.

Thanks,
Vaibhav


From vaibhav.hiremath at linaro.org  Tue Aug 25 01:50:21 2015
From: vaibhav.hiremath at linaro.org (Vaibhav Hiremath)
Date: Tue, 25 Aug 2015 14:20:21 +0530
Subject: [PATCH-v2 1/5] mfd: 88pm800: Fix tabbing issue
In-Reply-To: <20150825075246.GF19409@x1>
References: <1440442594-3102-1-git-send-email-vaibhav.hiremath@linaro.org>
 <1440442594-3102-3-git-send-email-vaibhav.hiremath@linaro.org>
 <20150825075246.GF19409@x1>
Message-ID: <55DC2C4D.1040304@linaro.org>



On Tuesday 25 August 2015 01:22 PM, Lee Jones wrote:
> On Tue, 25 Aug 2015, Vaibhav Hiremath wrote:
>
>> Driver had coding style issues where spaces were used instead
>> of tabs. This patch fixes them all.
>>
>> Signed-off-by: Vaibhav Hiremath <vaibhav.hiremath at linaro.org>
>> ---
>>   drivers/mfd/88pm800.c | 125 ++++++++++++++++++++++++--------------------------
>>   1 file changed, 61 insertions(+), 64 deletions(-)
>
> Same comment as before.
>
> How similar is this file to the other one?

I believe you are referring to include/linux/mfd/88pm80x.h

>
> Can you reduce the size by having shared register defines?
>

Not sure whether I understand your comment here,
They are common defines.

PM860 only defines are named as

PM860_XXXX

Similarly,
PM805 only defines are named as

PM805_XXXX


and PM800_xxx should be common.

Thanks,
Vaibhav


From vaibhav.hiremath at linaro.org  Tue Aug 25 01:51:43 2015
From: vaibhav.hiremath at linaro.org (Vaibhav Hiremath)
Date: Tue, 25 Aug 2015 14:21:43 +0530
Subject: [PATCH-v2 3/5] mfd: devicetree: bindings: Add clock subdevice
 node information
In-Reply-To: <20150825075858.GH19409@x1>
References: <1440442594-3102-1-git-send-email-vaibhav.hiremath@linaro.org>
 <1440442594-3102-5-git-send-email-vaibhav.hiremath@linaro.org>
 <20150825075858.GH19409@x1>
Message-ID: <55DC2C9F.8000203@linaro.org>



On Tuesday 25 August 2015 01:28 PM, Lee Jones wrote:
> On Tue, 25 Aug 2015, Vaibhav Hiremath wrote:
>
>> This patch updates the binding documentation for optional
>> clocks node and related information for buffered 32KHz clock.
>>
>> Signed-off-by: Vaibhav Hiremath <vaibhav.hiremath at linaro.org>
>> Reviewed-by: Krzysztof Kozlowski <k.kozlowski at samsung.com>
>> Acked-by: Rob Herring <robh at kernel.org>
>> ---
>>   Documentation/devicetree/bindings/mfd/88pm800.txt | 27 +++++++++++++++++++++++
>>   1 file changed, 27 insertions(+)
>>
>> diff --git a/Documentation/devicetree/bindings/mfd/88pm800.txt b/Documentation/devicetree/bindings/mfd/88pm800.txt
>> index 2c82fcb..bc6cb02 100644
>> --- a/Documentation/devicetree/bindings/mfd/88pm800.txt
>> +++ b/Documentation/devicetree/bindings/mfd/88pm800.txt
>> @@ -15,6 +15,26 @@ Optional properties :
>>     Without this both BUCK1A and BUCK1B operates independently with 3A capacity.
>>     (This property is only applicable to 88PM860)
>>
>> +Optional nodes:
>> +- clocks: 88pm800 family of devices provide multiple buffered 32.768
>> +  KHz outputs, so to register these as clocks with common clock framework
>> +  instantiate a sub-node named "clocks". It uses the common clock binding
>> +  documented in :
>> +  [Documentation/devicetree/bindings/clock/clock-bindings.txt]
>
> I tend to prefer relative paths.  Firstly because they're shorter and
> more succinct and secondly because if we do eventually move DT out of
> the kernel, it will be less hassle to rename each of them.
>
>> +  - #clock-cells: should be 1.
>> +
>> +  - The following is the list of clocks generated by the controller. Each clock
>> +    is assigned an identifier and client nodes use this identifier to specify
>> +    the clock which they consume.
>> +    Clock		ID           	Devices
>> +    ----------------------------------------------------------
>> +    pm800_clk32k_1	0		88PM800 and 88PM860
>> +    pm800_clk32k_2	1		88PM800 and 88PM860
>> +    pm800_clk32k_3	2		88PM800
>> +
>> +  - compatible: Should be : "marvell,88pm800-clk"
>> +
>>   88pm80x family of devices consists of varied group of sub-devices:
>>
>>   Device		 	Supply Names	 Description
>> @@ -22,6 +42,7 @@ Device		 	Supply Names	 Description
>>   88pm80x-onkey		:		: On key
>>   88pm80x-rtc		:		: RTC
>>   88pm80x-regulator	:		: Regulators
>> +88pm80x-clk		:		: 32KHz Clk provider
>
> Nit: Alphabetical?
>

Will correct both comments.

Thanks,
Vaibhav




From vaibhav.hiremath at linaro.org  Tue Aug 25 02:02:46 2015
From: vaibhav.hiremath at linaro.org (Vaibhav Hiremath)
Date: Tue, 25 Aug 2015 14:32:46 +0530
Subject: [PATCH-v6 5/6] mfd: 88pm800: Set default interrupt clear method
In-Reply-To: <20150825083033.GJ19409@x1>
References: <1436358392-15449-1-git-send-email-vaibhav.hiremath@linaro.org>
 <1436358392-15449-6-git-send-email-vaibhav.hiremath@linaro.org>
 <20150824135422.GF3237@x1> <55DB3627.2030503@linaro.org>
 <20150824155129.GA19409@x1> <55DB4A91.9000702@linaro.org>
 <20150825083033.GJ19409@x1>
Message-ID: <55DC2F36.50305@linaro.org>



On Tuesday 25 August 2015 02:00 PM, Lee Jones wrote:
> On Mon, 24 Aug 2015, Vaibhav Hiremath wrote:
>
>>
>>
>> On Monday 24 August 2015 09:21 PM, Lee Jones wrote:
>>> On Mon, 24 Aug 2015, Vaibhav Hiremath wrote:
>>>
>>>>
>>>>
>>>> On Monday 24 August 2015 07:24 PM, Lee Jones wrote:
>>>>> On Wed, 08 Jul 2015, Vaibhav Hiremath wrote:
>>>>>
>>>>>> As per the spec, bit 1 (INT_CLEAR_MODE) of reg addr 0xe
>>>>>> (page 0) controls the method of clearing interrupt
>>>>>> status of 88pm800 family of devices;
>>>>>>
>>>>>>    0: clear on read
>>>>>>    1: clear on write
>>>>>>
>>>>>> If pdata is not coming from board file, then set the
>>>>>> default irq clear method to "irq clear on write"
>>>>>>
>>>>>> Also, as suggested by "Lee Jones" renaming variable field
>>>>>> to appropriate name and removed unnecessary field
>>>>>> pm80x_chip.irq_mode, using platform_data.irq_clr_method.
>>>>>>
>>>>>> Signed-off-by: Zhao Ye <zhaoy at marvell.com>
>>>>>> Signed-off-by: Vaibhav Hiremath <vaibhav.hiremath at linaro.org>
>>>>>> Reviewed-by: Krzysztof Kozlowski <k.kozlowski at samsung.com>
>>>>>> ---
>>>>>>   drivers/mfd/88pm800.c       | 15 ++++++++++-----
>>>>>>   include/linux/mfd/88pm80x.h |  9 +++++++--
>>>>>>   2 files changed, 17 insertions(+), 7 deletions(-)
>>>>>
>>>>> [...]
>>>>>
>>>>>> +#define PM800_WAKEUP2_INT_READ_CLEAR	(0 << 1)
>>>>>> +#define PM800_WAKEUP2_INT_WRITE_CLEAR	(1 << 1)
>>>>>
>>>>> Use BIT().
>>>>>
>>>>>> +/* Used by irq_clr_method */
>>>>>> +#define PM800_IRQ_CLR_ON_READ	0
>>>>>> +#define PM800_IRQ_CLR_ON_WRITE	1
>>>>>
>>>>>> -	int irq_mode;		/* Clear interrupt by read/write(0/1) */
>>>>>> +	bool irq_clr_method;		/* Clear interrupt by read/write(0/1) */
>>>>>
>>>>>> +	irq_clr_mode = pdata->irq_clr_method == PM800_IRQ_CLR_ON_WRITE ?
>>>>>> +		PM800_WAKEUP2_INT_WRITE_CLEAR : PM800_WAKEUP2_INT_READ_CLEAR;
>>>>>> +	ret = regmap_update_bits(map, PM800_WAKEUP2, mask, irq_clr_mode);
>>>>>
>>>>> This is pretty convoluted.
>>>>>
>>>>> For starters you're abusing the 'bool' type here.  Bool is either
>>>>> 'true' or 'false', so at the very least you should rename
>>>>> 'irq_clr_method' to 'irq_clr_on_write'.
>>>>>
>>>>> Then you can do:
>>>>>
>>>>> 	irq_clr_mode = pdata->irq_clr_on_write ?
>>>>> 		PM800_WAKEUP2_INT_WRITE_CLEAR : PM800_WAKEUP2_INT_READ_CLEAR;
>>>>>
>>>>
>>>> We have discussed on this, and went back-n-forth.
>>>> I think if I remember correctly, one of the version was using
>>>> true/false then we decided to rename it to relevant macro.
>>>>
>>>> If I am not wrong V4 version of this series is exactly same as what you
>>>> are referring to.
>>>
>>> Right.  I made a few suggestions which vary in usefulness depending on
>>> how you plan to implement all of this.  Unfortunately this is a bit of
>>> a bastardised version where some of it make sense and other parts
>>> could do with some improvement.
>>>
>>
>> This so called "basterdised version could have been avoided :)
>>
>> V2 version itself was clean and ready. It just got dragged into
>> multiple iterations.
>
> Don't kid yourself.  There were still improvements to be made.
>

Yes indeed,
Moving to pdata was required. I was referring to logic part of it.

>>>>> However, what I suggest you really do is share
>>>>> PM800_WAKEUP2_INT_{READ,WRITE}_CLEAR with platform data and just pass
>>>>> the value through directly.
>>>>>
>>>>
>>>> I think we discussed about this also, and the reason I recall here is,
>>>>
>>>> we may need to control this from DT in the future so we decided to keep
>>>> it boolean in platform_data and have simple check before writing to
>>>> register.
>>>>
>>>> And I think that was also another reason we introduced
>>>>
>>>> /* Used by irq_clr_method */
>>>> #define PM800_IRQ_CLR_ON_READ   0
>>>> #define PM800_IRQ_CLR_ON_WRITE  1
>>>
>>> I think these are still required.  So it would look like this:
>>>
>>
>> NO. I think you are confused here,
>> We have two different macros playing around here,
>>
>>
>> +/* Used by irq_clr_method */
>> +#define PM800_IRQ_CLR_ON_READ	0
>> +#define PM800_IRQ_CLR_ON_WRITE	1
>>
>> /* Used to write to register */
>> +#define PM800_WAKEUP2_INT_READ_CLEAR		(0 << 1)
>> +#define PM800_WAKEUP2_INT_WRITE_CLEAR		(1 << 1)
>
> I know.  I used both of them *correctly* in my example below.  No
> confusion here.
>
>>> == Platform data ==
>>>
>>> struct pdata {
>>>    bool clear_irq_on_write;
>>> };
>>>
>>> pdata->clear_irq_on_write = PM800_IRQ_CLR_ON_{READ,WRITE};
>>>
>>> == Driver ==
>>>
>>> irq_clr_mode = pdata->clear_irq_on_write ?
>>>                   PM800_WAKEUP2_INT_WRITE_CLEAR : PM800_WAKEUP2_INT_READ_CLEAR;
>>> regmap_update_bits(map, PM800_WAKEUP2, mask, irq_clr_mode);
>>>
>>


The V2 version had


	irq_clr_mode = (chip->irq_clr_on_wr) ?
		PM800_WAKEUP2_INT_WRITE_CLEAR :
		PM800_WAKEUP2_INT_READ_CLEAR;
	ret = regmap_update_bits(map, PM800_WAKEUP2, mask,
						irq_clr_mode);

Which is exactly same as your example above, except pdata moment.

Lets not discuss too much on this, I think its time for conclusion :)


Your below example looks even better to me. So I will adopt below
example and resubmit the series.

>> Please check V2, which is exactly same as above.
>>
>> https://patchwork.kernel.org/patch/6627781/
>>
>>
>> If you are OK with it, I will spin another version and submit it.
>
> If you can't use the value directly, which if you want to pull the
> value from DT you can't, then either use the method above, or
> something like this might be better:
>
> int clear_on_write = 0;
>
> if (pdata->clear_irq_on_write)
>     clear_on_write = PM800_WAKEUP2_INT_WRITE_CLEAR;
>
> .. this way you only need to add one new define and you can drop
> PM800_WAKEUP2_INT_READ_CLEAR altogether.  This is better, because it
> will aid you to move to the BIT() macro easier (there is no BIT()
> value for shifting 0's).
>

Just to clarify, I will adopt this implementation.

Thanks,
Vaibhav


From vaibhav.hiremath at linaro.org  Tue Aug 25 02:04:28 2015
From: vaibhav.hiremath at linaro.org (Vaibhav Hiremath)
Date: Tue, 25 Aug 2015 14:34:28 +0530
Subject: [PATCH-v3 RESEND] mfd: 88pm80x: Add 88pm860 chip type support
Message-ID: <1440493468-5471-1-git-send-email-vaibhav.hiremath@linaro.org>

Add chip identification support for 88PM860 device
to the pm80x_chip_mapping table.

Signed-off-by: Vaibhav Hiremath <vaibhav.hiremath at linaro.org>
Reviewed-by: Krzysztof Kozlowski <k.kozlowski at samsung.com>
Acked-by: Lee Jones <lee.jones at linaro.org>
---
 drivers/mfd/88pm80x.c       | 2 ++
 include/linux/mfd/88pm80x.h | 1 +
 2 files changed, 3 insertions(+)

diff --git a/drivers/mfd/88pm80x.c b/drivers/mfd/88pm80x.c
index 5e72f65..63445ea 100644
--- a/drivers/mfd/88pm80x.c
+++ b/drivers/mfd/88pm80x.c
@@ -33,6 +33,8 @@ static struct pm80x_chip_mapping chip_mapping[] = {
 	{0x3,	CHIP_PM800},
 	/* 88PM805 chip id number */
 	{0x0,	CHIP_PM805},
+	/* 88PM860 chip id number */
+	{0x4,	CHIP_PM860},
 };
 
 /*
diff --git a/include/linux/mfd/88pm80x.h b/include/linux/mfd/88pm80x.h
index 8fcad63..d409ceb 100644
--- a/include/linux/mfd/88pm80x.h
+++ b/include/linux/mfd/88pm80x.h
@@ -21,6 +21,7 @@ enum {
 	CHIP_INVALID = 0,
 	CHIP_PM800,
 	CHIP_PM805,
+	CHIP_PM860,
 	CHIP_MAX,
 };
 
-- 
1.9.1



From treding at nvidia.com  Tue Aug 25 02:12:48 2015
From: treding at nvidia.com (Thierry Reding)
Date: Tue, 25 Aug 2015 11:12:48 +0200
Subject: [PATCH v3 06/14] Documentation: drm/bridge: add document for
 analogix_dp
In-Reply-To: <CAL_JsqKZYMMzV9Sc2r3K_rnM0FNuyb1TyJEhjGq1Hf7dTiWFKQ@mail.gmail.com>
References: <1439995728-18046-1-git-send-email-ykk@rock-chips.com>
 <1439995834-18363-1-git-send-email-ykk@rock-chips.com>
 <CAL_JsqLz+8RtBucctUj4euXZ3Ac0DvB52N9ONpAerh5T9BiTJg@mail.gmail.com>
 <20150824125758.GA7557@n2100.arm.linux.org.uk>
 <CAL_JsqKZYMMzV9Sc2r3K_rnM0FNuyb1TyJEhjGq1Hf7dTiWFKQ@mail.gmail.com>
Message-ID: <20150825091246.GA14034@ulmo.nvidia.com>

On Mon, Aug 24, 2015 at 09:48:27AM -0500, Rob Herring wrote:
> On Mon, Aug 24, 2015 at 7:57 AM, Russell King - ARM Linux
> <linux at arm.linux.org.uk> wrote:
> > On Sun, Aug 23, 2015 at 06:23:14PM -0500, Rob Herring wrote:
> >> On Wed, Aug 19, 2015 at 9:50 AM, Yakir Yang <ykk at rock-chips.com> wrote:
> >> > +       -analogix,color-depth:
> >> > +               number of bits per colour component.
> >> > +                       COLOR_6 = 0, COLOR_8 = 1, COLOR_10 = 2, COLOR_12 = 3
> >>
> >> This seems pretty generic. Just use 6, 8, 10, or 12 for values. And
> >> drop the vendor prefix.
> >
> > Please think about this some more.  What does "color-depth" mean?  Does it
> > mean the number of bits per colour _component_, or does it mean the total
> > number of bits to represent a particular colour.  It's confusing as it
> > stands.
> 
> Then "component-color-bpp" perhaps?

There should be no need to have this in DT at all. The BPC is a property
of the attached panel and it should come from the panel (either the
panel driver or parsed from EDID if available).

> > When we adopted the graph bindings for iMX DRM, I thought exactly at that
> > time "it would be nice if this could become the standard for binding DRM
> > components together" but I don't have the authority from either the DT
> > perspective or the DRM perspective to mandate that.  Neither does anyone
> > else.  That's the _real_ problem here.
> >
> > I've seen several DRM bindings go by which don't use the of-graph stuff,
> > which means that they'll never be compatible with generic components
> > which do use the of-graph stuff.
> 
> It goes beyond bindings IMO. The use of the component framework or not
> has been at the whim of driver writers as well. It is either used or
> private APIs are created. I'm using components and my need for it
> boils down to passing the struct drm_device pointer to the encoder.
> Other components like panels and bridges have different ways to attach
> to the DRM driver.

I certainly support unification, but it needs to be reasonable. There
are cases where a different structure for the binding work better than
another and I think this always needs to be evaluated on a case by case
basis.

Because of that I think it makes sense to make all these framework bits
opt-in, otherwise we could easily end up in a situation where drivers
have to be rearchitected (or even DT bindings altered!) in order to be
able to reuse code.

Thierry
-------------- next part --------------
A non-text attachment was scrubbed...
Name: signature.asc
Type: application/pgp-signature
Size: 819 bytes
Desc: not available
URL: <http://lists.infradead.org/pipermail/linux-arm-kernel/attachments/20150825/6154bc96/attachment.sig>

From will.deacon at arm.com  Tue Aug 25 02:15:47 2015
From: will.deacon at arm.com (Will Deacon)
Date: Tue, 25 Aug 2015 10:15:47 +0100
Subject: [PATCH v2 5/5] arm64: add KASan support
In-Reply-To: <20150824174736.GD7557@n2100.arm.linux.org.uk>
References: <CAPAsAGy-r8Z2N09wKV+e0kLfbwxd-eWK6N5Xajsnqq9jfyWqcQ@mail.gmail.com>
 <CACRpkdZmHLMxosLXjyOPdkavo=UNzmTcHOLF5vV4cS1ULfbq6A@mail.gmail.com>
 <CAPAsAGw-iawTpjJh66rQN5fqBFT6UBZCcv2eKx7JTqCXzhzpsw@mail.gmail.com>
 <CACRpkdY2i2M27gP_fXawkFrC_GFgWaKr5rEn6d47refNPiEk=g@mail.gmail.com>
 <55AE56DB.4040607@samsung.com>
 <CACRpkdYaqK8upK-3b01JbO_y+sHnk4-Hm1MfvjSy0tKUkFREtQ@mail.gmail.com>
 <20150824131557.GB7557@n2100.arm.linux.org.uk>
 <CACRpkdYwpucRiXM05y00RQY=gKv8W6YjCNspYFRMGaM605cU0w@mail.gmail.com>
 <CAPAsAGwji7FpUJK9O=FWYN15-rJkYMQyOt9W9ncdY9uLybxkiA@mail.gmail.com>
 <20150824174736.GD7557@n2100.arm.linux.org.uk>
Message-ID: <20150825091547.GA21300@arm.com>

On Mon, Aug 24, 2015 at 06:47:36PM +0100, Russell King - ARM Linux wrote:
> On Mon, Aug 24, 2015 at 05:15:22PM +0300, Andrey Ryabinin wrote:
> > Yes, ~130Mb (3G/1G split) should work. 512Mb shadow is optional.
> > The only advantage of 512Mb shadow is better handling of user memory
> > accesses bugs
> > (access to user memory without copy_from_user/copy_to_user/strlen_user etc API).
> 
> No need for that to be handed by KASan.  I have patches in linux-next,
> now acked by Will, which prevent the kernel accessing userspace with
> zero memory footprint.  No need for remapping, we have a way to quickly
> turn off access to userspace mapped pages on non-LPAE 32-bit CPUs.
> (LPAE is not supported yet - Catalin will be working on that using the
> hooks I'm providing once he returns.)

Hey, I only acked the "Efficiency cleanups" series so far! The PAN emulation
is still on my list.

Will


From treding at nvidia.com  Tue Aug 25 02:15:36 2015
From: treding at nvidia.com (Thierry Reding)
Date: Tue, 25 Aug 2015 11:15:36 +0200
Subject: [PATCH v3 06/14] Documentation: drm/bridge: add document for
 analogix_dp
In-Reply-To: <CAL_JsqLz+8RtBucctUj4euXZ3Ac0DvB52N9ONpAerh5T9BiTJg@mail.gmail.com>
References: <1439995728-18046-1-git-send-email-ykk@rock-chips.com>
 <1439995834-18363-1-git-send-email-ykk@rock-chips.com>
 <CAL_JsqLz+8RtBucctUj4euXZ3Ac0DvB52N9ONpAerh5T9BiTJg@mail.gmail.com>
Message-ID: <20150825091534.GB14034@ulmo.nvidia.com>

On Sun, Aug 23, 2015 at 06:23:14PM -0500, Rob Herring wrote:
> On Wed, Aug 19, 2015 at 9:50 AM, Yakir Yang <ykk at rock-chips.com> wrote:
[...]
> > +       -analogix,link-rate:
> > +               max link rate supported by the eDP controller.
> > +                       LINK_RATE_1_62GBPS = 0x6, LINK_RATE_2_70GBPS = 0x0A,
> > +                       LINK_RATE_5_40GBPS = 0x14
> 
> Same here. I'd rather see something like "link-rate-mbps" and use the
> actual rate.

There is no need whatsoever to hard-code this in DT. (e)DP provides the
means to detect what rate the link supports and the specification
provides guidance on how to select an appropriate one.

> 
> > +       -analogix,lane-count:
> > +               max number of lanes supported by the eDP contoller.
> > +                       LANE_COUNT1 = 1, LANE_COUNT2 = 2, LANE_COUNT4 = 4
> 
> And drop the vendor prefix here.

Same as for the link rate.

Thierry
-------------- next part --------------
A non-text attachment was scrubbed...
Name: signature.asc
Type: application/pgp-signature
Size: 819 bytes
Desc: not available
URL: <http://lists.infradead.org/pipermail/linux-arm-kernel/attachments/20150825/6f34dcce/attachment.sig>

From geert at linux-m68k.org  Tue Aug 25 02:24:13 2015
From: geert at linux-m68k.org (Geert Uytterhoeven)
Date: Tue, 25 Aug 2015 11:24:13 +0200
Subject: [PATCH 2/9] PM / Domains: Remove dev->driver check for runtime PM
In-Reply-To: <20150824195032.GA1384@linaro.org>
References: <1438731339-58317-1-git-send-email-lina.iyer@linaro.org>
 <1438731339-58317-3-git-send-email-lina.iyer@linaro.org>
 <7hfv3onv5c.fsf@deeprootsystems.com>
 <CAMuHMdVeffa-jgXuSjDQBKTrhgW-d87OKzs1iXX+4y-9U_AJbg@mail.gmail.com>
 <7hwpwylepx.fsf@deeprootsystems.com>
 <CAMuHMdW-T9rUWXsQeffwtXspHbjfGqo_0G4QMB1o0TwTLJAQAg@mail.gmail.com>
 <CAMAWPa-0R42thqBo0omn0KK7y0wyxoyaP+wsfoRvXBmWhBytKg@mail.gmail.com>
 <CAMuHMdV2gDBaPRb3yE=tVPO_pr7PFA6bwhyQE5raumCh_qPXww@mail.gmail.com>
 <7hio88gxpn.fsf@deeprootsystems.com>
 <20150824195032.GA1384@linaro.org>
Message-ID: <CAMuHMdV9bRhGR6TarfWpv40TpZW1ntC4rpfn8snm8dTt_wg71g@mail.gmail.com>

Hi Lina,

On Mon, Aug 24, 2015 at 9:50 PM, Lina Iyer <lina.iyer at linaro.org> wrote:
> On Fri, Aug 21 2015 at 15:04 -0600, Kevin Hilman wrote:
>> Geert Uytterhoeven <geert at linux-m68k.org> writes:
>>> On Fri, Aug 14, 2015 at 7:19 PM, Kevin Hilman <khilman at kernel.org> wrote:
>>>> On Fri, Aug 14, 2015 at 12:24 AM, Geert Uytterhoeven
>>>> <geert at linux-m68k.org> wrote:
>>>>> On Fri, Aug 14, 2015 at 5:40 AM, Kevin Hilman <khilman at kernel.org>
>>>>> wrote:
>>>>>> Geert Uytterhoeven <geert at linux-m68k.org> writes:
>>>>>>> On Wed, Aug 12, 2015 at 9:50 PM, Kevin Hilman <khilman at kernel.org>
>>>>>>> wrote:
>>>>>>>> This check might have made sense before PM domains, but with PM
>>>>>>>> domains,
>>>>>>>> it's entirely possible to have a simple device without a driver and
>>>>>>>> the
>>>>>>>> PM domain handles all the necesary PM, so I think this check
>>>>>>>> could/should be removed.
>>>>>>>>
>>>>>>>> Thoughts?
>>>>>>>
>>>>>>> Simple devices without a driver aren't handled automatically.
>>>>>>> At minimum, the driver should call pm_runtime_enable(), cfr.
>>>>>>> drivers/bus/simple-pm-bus.c.
>>>>>>
>>>>>> That's correct, and in the proof-of-concept stuff I hacked up and in
>>>>>> Lina's series, the CPU "devices" do indeed to this.  Without that,
>>>>>> they
>>>>>> wouldn't end up ever taking this codepath through genpd's
>>>>>> runtime_suspend and power_off hooks.
>>>>>>
>>>>>> Also, I'm not sure if your comment was meant to be an objection to the
>>>>>> patch?  or if you're OK with it.
>>>>>
>>>>> My comment was purely meant as a response to "it's entirely possible to
>>>>> have a
>>>>> simple device without a driver and the PM domain handles all the
>>>>> necesary PM".
>>>>
>>>> Right, so if the PM domain does the pm_runtime_enable() for these
>>>> "simple" devices without drivers, they can still exist without a
>>>> driver, and the PM domain doing all the magic.
>>>
>>> Is it possible to let the PM Domain do the pm_runtime_enable() itself in
>>> the absence of a driver?
>>
>> Well, I suppose it's possible, not sure it's recommended. :)
>>
>>> If yes, I wouldn't have needed simple-pm-bus.c.
>>> What if a driver is bound later?
>>
>> Yeah, you're approach is better.
>>
> I am not sure I understand the approach? Initialize the CPU devices as
> "simple-pm-bus" compatible?

No, Kevin and I are discussing about transparent buses that need power
management, not about CPU devices.

Cfr. commit 89d463ea106dba53 ("drivers: bus: Add Simple Power-Managed Bus
Driver").

Sorry for the confusion...

Gr{oetje,eeting}s,

                        Geert

--
Geert Uytterhoeven -- There's lots of Linux beyond ia32 -- geert at linux-m68k.org

In personal conversations with technical people, I call myself a hacker. But
when I'm talking to journalists I just say "programmer" or something like that.
                                -- Linus Torvalds


From sudeep.holla at arm.com  Tue Aug 25 02:24:34 2015
From: sudeep.holla at arm.com (Sudeep Holla)
Date: Tue, 25 Aug 2015 10:24:34 +0100
Subject: [PATCH v9 1/1] irqchip: imx-gpcv2: IMX GPCv2 driver for wakeup
 sources
In-Reply-To: <1440443055-7291-1-git-send-email-shenwei.wang@freescale.com>
References: <1440443055-7291-1-git-send-email-shenwei.wang@freescale.com>
Message-ID: <55DC3452.3070205@arm.com>



On 24/08/15 20:04, Shenwei Wang wrote:
> IMX7D contains a new version of GPC IP block (GPCv2). It has two
> major functions: power management and wakeup source management.
> This patch adds a new irqchip driver to manage the interrupt wakeup
> sources on IMX7D.

Interesting, you mention that this IP block has mainly power management
and it itself requires save/restore. Is it not in always on domain ?

> When the system is in WFI (wait for interrupt) mode, this GPC block
> will be the first block on the platform to be activated and signaled.
> Under normal wait mode during cpu idle, the system can be woke up
> by any enabled interrupts. Under standby or suspend mode, the system
> can only be woke up by the pre-defined wakeup sources.
>
> Signed-off-by: Shenwei Wang <shenwei.wang at freescale.com>
> Signed-off-by: Anson Huang <b20788 at freescale.com>
> ---
> Change log:
> 	Renamed the enabled_irqs to saved_irq_mask in struct gpcv2_irqchip_data
> 	Removed "BUG_ON()" in imx_gpcv2_irqchip_init to unify the error handling codes.
>
>   drivers/irqchip/Kconfig         |   7 +
>   drivers/irqchip/Makefile        |   1 +
>   drivers/irqchip/irq-imx-gpcv2.c | 275 ++++++++++++++++++++++++++++++++++++++++
>   3 files changed, 283 insertions(+)
>   create mode 100644 drivers/irqchip/irq-imx-gpcv2.c
>
> diff --git a/drivers/irqchip/Kconfig b/drivers/irqchip/Kconfig
> index 120d815..3fc0fac 100644
> --- a/drivers/irqchip/Kconfig
> +++ b/drivers/irqchip/Kconfig
> @@ -177,3 +177,10 @@ config RENESAS_H8300H_INTC
>   config RENESAS_H8S_INTC
>           bool
>   	select IRQ_DOMAIN
> +
> +config IMX_GPCV2
> +	bool
> +	select IRQ_DOMAIN
> +	help
> +	  Enables the wakeup IRQs for IMX platforms with GPCv2 block
> +
> diff --git a/drivers/irqchip/Makefile b/drivers/irqchip/Makefile
> index b8d4e96..8eb5f60 100644
> --- a/drivers/irqchip/Makefile
> +++ b/drivers/irqchip/Makefile
> @@ -52,3 +52,4 @@ obj-$(CONFIG_RENESAS_H8300H_INTC)	+= irq-renesas-h8300h.o
>   obj-$(CONFIG_RENESAS_H8S_INTC)		+= irq-renesas-h8s.o
>   obj-$(CONFIG_ARCH_SA1100)		+= irq-sa11x0.o
>   obj-$(CONFIG_INGENIC_IRQ)		+= irq-ingenic.o
> +obj-$(CONFIG_IMX_GPCV2)			+= irq-imx-gpcv2.o
> diff --git a/drivers/irqchip/irq-imx-gpcv2.c b/drivers/irqchip/irq-imx-gpcv2.c
> new file mode 100644
> index 0000000..4a97afa
> --- /dev/null
> +++ b/drivers/irqchip/irq-imx-gpcv2.c
> @@ -0,0 +1,275 @@
> +/*
> + * Copyright (C) 2015 Freescale Semiconductor, Inc.
> + *
> + * This program is free software; you can redistribute it and/or modify
> + * it under the terms of the GNU General Public License version 2 as
> + * published by the Free Software Foundation.
> + */
> +
> +#include <linux/of_address.h>
> +#include <linux/of_irq.h>
> +#include <linux/slab.h>
> +#include <linux/irqchip.h>
> +#include <linux/syscore_ops.h>
> +
> +#define IMR_NUM			4
> +#define GPC_MAX_IRQS            (IMR_NUM * 32)
> +
> +#define GPC_IMR1_CORE0		0x30
> +#define GPC_IMR1_CORE1		0x40
> +
> +struct gpcv2_irqchip_data {
> +	struct raw_spinlock    rlock;
> +	void __iomem       *gpc_base;
> +	u32 wakeup_sources[IMR_NUM];
> +	u32 saved_irq_mask[IMR_NUM];
> +	u32 cpu2wakeup;
> +};
> +
> +static struct gpcv2_irqchip_data *imx_gpcv2_instance;
> +
> +u32 imx_gpcv2_get_wakeup_source(u32 **sources)
> +{
> +	if (!imx_gpcv2_instance)
> +		return 0;
> +
> +	if (sources)
> +		*sources = imx_gpcv2_instance->wakeup_sources;
> +
> +	return IMR_NUM;
> +}
> +
> +static int gpcv2_wakeup_source_save(void)
> +{
> +	struct gpcv2_irqchip_data *cd;
> +	void __iomem *reg;
> +	int i;
> +
> +	cd = imx_gpcv2_instance;
> +	if (!cd)
> +		return 0;
> +
> +	for (i = 0; i < IMR_NUM; i++) {
> +		reg = cd->gpc_base + cd->cpu2wakeup + i * 4;
> +		cd->saved_irq_mask[i] = readl_relaxed(reg);
> +		writel_relaxed(cd->wakeup_sources[i], reg);
> +	}
> +
> +	return 0;
> +}
> +
> +static void gpcv2_wakeup_source_restore(void)
> +{
> +	struct gpcv2_irqchip_data *cd;
> +	void __iomem *reg;
> +	int i;
> +
> +	cd = imx_gpcv2_instance;
> +	if (!cd)
> +		return;
> +
> +	for (i = 0; i < IMR_NUM; i++) {
> +		reg = cd->gpc_base + cd->cpu2wakeup + i * 4;
> +		writel_relaxed(cd->saved_irq_mask[i], reg);

Instead of saving all the non-wakeup sources, can't you use raw
save/restore of these registers and mask all the non-wakeup sources
by setting MASK_ON_SUSPEND ?

Also your interrupt controller seems like has no special way to
configure wakeups, you are just leaving them enabled. i.e. I see
cpu2wakeup used for both {un,}masking and wakeup enable. So you can just
use IRQCHIP_SKIP_SET_WAKE. Correct me if my understanding is wrong.

Regards,
Sudeep


From heiko at sntech.de  Tue Aug 25 02:25:42 2015
From: heiko at sntech.de (Heiko Stuebner)
Date: Tue, 25 Aug 2015 11:25:42 +0200
Subject: [GIT PULL 1/2] Rockchip dts fixes for 4.3
Message-ID: <1879932.6Bpqy7C2KO@phil>

Hi Arnd, Kevin, Olof

Brian found two issues with regulator suspend-properties of the newly
added veyron boards, so please pull these fixes on top.


Thanks
Heiko

The following changes since commit 378abcdf3297613f6712343ce3a79b7d6abdf955:

  ARM: dts: rockchip: add veyron-minnie board (2015-08-08 12:31:27 +0200)

are available in the git repository at:

  git://git.kernel.org/pub/scm/linux/kernel/git/mmind/linux-rockchip.git tags/v4.3-rockchip32-dts3

for you to fetch changes up to 467fb18a8d538be6548ef4093003b63aebbb07b9:

  ARM: dts: rockchip: correct regulator power states for suspend (2015-08-21 01:40:35 +0200)

----------------------------------------------------------------
Fixes for non-standard and inverted regulator-suspend-properties
on veyron boards.

----------------------------------------------------------------
Brian Norris (2):
      ARM: dts: rockchip: correct regulator PM properties
      ARM: dts: rockchip: correct regulator power states for suspend

 arch/arm/boot/dts/rk3288-veyron-jerry.dts  | 2 +-
 arch/arm/boot/dts/rk3288-veyron-minnie.dts | 8 ++++++--
 arch/arm/boot/dts/rk3288-veyron-pinky.dts  | 2 +-
 arch/arm/boot/dts/rk3288-veyron-sdmmc.dtsi | 4 ++--
 4 files changed, 10 insertions(+), 6 deletions(-)



From hverkuil at xs4all.nl  Tue Aug 25 02:23:24 2015
From: hverkuil at xs4all.nl (Hans Verkuil)
Date: Tue, 25 Aug 2015 11:23:24 +0200
Subject: [PATCH v7 25/44] [media] replace all occurrences of
 MEDIA_ENT_T_DEVNODE_V4L
In-Reply-To: <23e2f9440a259e1162e15dba7e6261dbc4c521c6.1440359643.git.mchehab@osg.samsung.com>
References: <cover.1440359643.git.mchehab@osg.samsung.com>
 <23e2f9440a259e1162e15dba7e6261dbc4c521c6.1440359643.git.mchehab@osg.samsung.com>
Message-ID: <55DC340C.8030503@xs4all.nl>

On 08/23/15 22:17, Mauro Carvalho Chehab wrote:
> Now that interfaces and entities are distinct, it makes no sense
> of keeping something named as MEDIA_ENT_T_DEVNODE.
> 
> This change was done with this script:
> 
> 	for i in $(git grep -l MEDIA_ENT_T|grep -v uapi/linux/media.h); do sed s,MEDIA_ENT_T_DEVNODE_V4L,MEDIA_ENT_T_V4L2_VIDEO, <$i >a && mv a $i; done
> 
> Signed-off-by: Mauro Carvalho Chehab <mchehab at osg.samsung.com>
> 
> diff --git a/Documentation/DocBook/media/v4l/media-ioc-enum-entities.xml b/Documentation/DocBook/media/v4l/media-ioc-enum-entities.xml
> index 5872f8bbf774..910243d4edb8 100644
> --- a/Documentation/DocBook/media/v4l/media-ioc-enum-entities.xml
> +++ b/Documentation/DocBook/media/v4l/media-ioc-enum-entities.xml
> @@ -183,7 +183,7 @@
>  	    <entry>Unknown device node</entry>
>  	  </row>
>  	  <row>
> -	    <entry><constant>MEDIA_ENT_T_DEVNODE_V4L</constant></entry>
> +	    <entry><constant>MEDIA_ENT_T_V4L2_VIDEO</constant></entry>
>  	    <entry>V4L video, radio or vbi device node</entry>
>  	  </row>

OK, this makes no sense and that ties in with my confusion of the previous patch.

These are not device nodes, in the new scheme these are DMA entities (I know,
naming TDB) that have an associated interface.

I think a much better approach would be to add entity type(s) for such DMA
engines in patch 24, then use that new name in existing drivers and split
up the existing DEVNODE_V4L media_entity into a media_entity and a
media_intf_devnode:

The current media_entity defined in struct video_device has to be replaced
by media_intf_devnode, and the DMA entity has to be added as a new entity
to these drivers.

This reflects these two action items from our meeting:

Migration: add v4l-subdev media_interface: Laurent
Migration: add explicit DMA Engine entity: Laurent

Unless Laurent says differently I think this is something you'll have to
do given Laurent's workload.

I think doing this at this stage of the patch series is crucial, otherwise
the remaining patches really make no sense.

I'll skip reviewing patches 26-38 for now.

Regards,

	Hans

>  	  <row>
> diff --git a/drivers/media/platform/xilinx/xilinx-dma.c b/drivers/media/platform/xilinx/xilinx-dma.c
> index 92e8116dc28f..88cd789cdaf7 100644
> --- a/drivers/media/platform/xilinx/xilinx-dma.c
> +++ b/drivers/media/platform/xilinx/xilinx-dma.c
> @@ -193,7 +193,7 @@ static int xvip_pipeline_validate(struct xvip_pipeline *pipe,
>  	while ((entity = media_entity_graph_walk_next(&graph))) {
>  		struct xvip_dma *dma;
>  
> -		if (entity->type != MEDIA_ENT_T_DEVNODE_V4L)
> +		if (entity->type != MEDIA_ENT_T_V4L2_VIDEO)
>  			continue;
>  
>  		dma = to_xvip_dma(media_entity_to_video_device(entity));
> diff --git a/drivers/media/v4l2-core/v4l2-dev.c b/drivers/media/v4l2-core/v4l2-dev.c
> index 71a1b93b0790..44b330589787 100644
> --- a/drivers/media/v4l2-core/v4l2-dev.c
> +++ b/drivers/media/v4l2-core/v4l2-dev.c
> @@ -912,7 +912,7 @@ int __video_register_device(struct video_device *vdev, int type, int nr,
>  	/* Part 5: Register the entity. */
>  	if (vdev->v4l2_dev->mdev &&
>  	    vdev->vfl_type != VFL_TYPE_SUBDEV) {
> -		vdev->entity.type = MEDIA_ENT_T_DEVNODE_V4L;
> +		vdev->entity.type = MEDIA_ENT_T_V4L2_VIDEO;
>  		vdev->entity.name = vdev->name;
>  		vdev->entity.info.dev.major = VIDEO_MAJOR;
>  		vdev->entity.info.dev.minor = vdev->minor;
> diff --git a/drivers/media/v4l2-core/v4l2-subdev.c b/drivers/media/v4l2-core/v4l2-subdev.c
> index 83615b8fb46a..e6e1115d8215 100644
> --- a/drivers/media/v4l2-core/v4l2-subdev.c
> +++ b/drivers/media/v4l2-core/v4l2-subdev.c
> @@ -535,7 +535,7 @@ v4l2_subdev_link_validate_get_format(struct media_pad *pad,
>  		return v4l2_subdev_call(sd, pad, get_fmt, NULL, fmt);
>  	}
>  
> -	WARN(pad->entity->type != MEDIA_ENT_T_DEVNODE_V4L,
> +	WARN(pad->entity->type != MEDIA_ENT_T_V4L2_VIDEO,
>  	     "Driver bug! Wrong media entity type 0x%08x, entity %s\n",
>  	     pad->entity->type, pad->entity->name);
>  
> 


From lee.jones at linaro.org  Tue Aug 25 02:27:05 2015
From: lee.jones at linaro.org (Lee Jones)
Date: Tue, 25 Aug 2015 10:27:05 +0100
Subject: [PATCH-v3 RESEND] mfd: 88pm80x: Add 88pm860 chip type support
In-Reply-To: <1440493468-5471-1-git-send-email-vaibhav.hiremath@linaro.org>
References: <1440493468-5471-1-git-send-email-vaibhav.hiremath@linaro.org>
Message-ID: <20150825092705.GN19409@x1>

On Tue, 25 Aug 2015, Vaibhav Hiremath wrote:

> Add chip identification support for 88PM860 device
> to the pm80x_chip_mapping table.
> 
> Signed-off-by: Vaibhav Hiremath <vaibhav.hiremath at linaro.org>
> Reviewed-by: Krzysztof Kozlowski <k.kozlowski at samsung.com>
> Acked-by: Lee Jones <lee.jones at linaro.org>
> ---
>  drivers/mfd/88pm80x.c       | 2 ++
>  include/linux/mfd/88pm80x.h | 1 +
>  2 files changed, 3 insertions(+)

Applied, thanks.

> diff --git a/drivers/mfd/88pm80x.c b/drivers/mfd/88pm80x.c
> index 5e72f65..63445ea 100644
> --- a/drivers/mfd/88pm80x.c
> +++ b/drivers/mfd/88pm80x.c
> @@ -33,6 +33,8 @@ static struct pm80x_chip_mapping chip_mapping[] = {
>  	{0x3,	CHIP_PM800},
>  	/* 88PM805 chip id number */
>  	{0x0,	CHIP_PM805},
> +	/* 88PM860 chip id number */
> +	{0x4,	CHIP_PM860},
>  };
>  
>  /*
> diff --git a/include/linux/mfd/88pm80x.h b/include/linux/mfd/88pm80x.h
> index 8fcad63..d409ceb 100644
> --- a/include/linux/mfd/88pm80x.h
> +++ b/include/linux/mfd/88pm80x.h
> @@ -21,6 +21,7 @@ enum {
>  	CHIP_INVALID = 0,
>  	CHIP_PM800,
>  	CHIP_PM805,
> +	CHIP_PM860,
>  	CHIP_MAX,
>  };
>  

-- 
Lee Jones
Linaro STMicroelectronics Landing Team Lead
Linaro.org ? Open source software for ARM SoCs
Follow Linaro: Facebook | Twitter | Blog


From linux at arm.linux.org.uk  Tue Aug 25 02:29:39 2015
From: linux at arm.linux.org.uk (Russell King - ARM Linux)
Date: Tue, 25 Aug 2015 10:29:39 +0100
Subject: [PATCH v3 06/14] Documentation: drm/bridge: add document for
 analogix_dp
In-Reply-To: <20150825091246.GA14034@ulmo.nvidia.com>
References: <1439995728-18046-1-git-send-email-ykk@rock-chips.com>
 <1439995834-18363-1-git-send-email-ykk@rock-chips.com>
 <CAL_JsqLz+8RtBucctUj4euXZ3Ac0DvB52N9ONpAerh5T9BiTJg@mail.gmail.com>
 <20150824125758.GA7557@n2100.arm.linux.org.uk>
 <CAL_JsqKZYMMzV9Sc2r3K_rnM0FNuyb1TyJEhjGq1Hf7dTiWFKQ@mail.gmail.com>
 <20150825091246.GA14034@ulmo.nvidia.com>
Message-ID: <20150825092939.GM7557@n2100.arm.linux.org.uk>

On Tue, Aug 25, 2015 at 11:12:48AM +0200, Thierry Reding wrote:
> On Mon, Aug 24, 2015 at 09:48:27AM -0500, Rob Herring wrote:
> > It goes beyond bindings IMO. The use of the component framework or not
> > has been at the whim of driver writers as well. It is either used or
> > private APIs are created. I'm using components and my need for it
> > boils down to passing the struct drm_device pointer to the encoder.
> > Other components like panels and bridges have different ways to attach
> > to the DRM driver.
> 
> I certainly support unification, but it needs to be reasonable. There
> are cases where a different structure for the binding work better than
> another and I think this always needs to be evaluated on a case by case
> basis.

It can't be a case-by-case basis.

The TDA998x encoder/connector is going to be component only.  This is
a generic chip, which can be attached to the output of any parallel
RGB+sync+clock bus.  In other words, it could appear anywhere.

Are you really saying that we need to support multiple schemes of
attaching the driver to DRM?  That's totally insane IMHO.

The problem with the drm_encoder_slave stuff is that you can't sanely
attach of-nodes to the drm-created i2c device.  Yes, you can parse
them from the DT file as a sub-node of the upper device, but that
then goes against the principle of the I2C bindings, which is to
list the I2C devices as a child below the I2C adapter node.  If you
try and put the DT node there, then the OF code will create the I2C
device for you, and the drm_encoder_slave stuff won't have the
control it needs to communicate through the wrapped i2c_driver
stuff.

So, tda998x is going component-only, as that's the _only_ sane solution
for it.

Now, what happens when some other DRM driver wants to use the tda998x
driver, and its bindings are not compatible with the component helpers?
They're pretty much stuck up the creek without a paddle.

Case by case doesn't work unless you're talking about truely isolated
hardware where no one shares anything.

-- 
FTTC broadband for 0.8mile line: currently at 10.5Mbps down 400kbps up
according to speedtest.net.


From heiko at sntech.de  Tue Aug 25 02:30:08 2015
From: heiko at sntech.de (Heiko Stuebner)
Date: Tue, 25 Aug 2015 11:30:08 +0200
Subject: [GIT PULL 2/2] Rockchip soc fix for 4.3
In-Reply-To: <1879932.6Bpqy7C2KO@phil>
References: <1879932.6Bpqy7C2KO@phil>
Message-ID: <9416843.VhjrryKIms@phil>

Hi Arnd, Kevin, Olof,

Fabio did find an error in what is returned as error codes in the init of
the suspend code. Nobody complained about this actually breaking stuff
but it would be nice to have this fixed nevertheless, so please pull.


Thanks
Heiko


The following changes since commit 9bb91ae970dd004393a3d7d09bdcc30dfe2f8693:

  ARM: rockchip: enable PMU_GPIOINT_WAKEUP_EN when entering shallow suspend (2015-08-06 13:05:14 +0200)

are available in the git repository at:

  git://git.kernel.org/pub/scm/linux/kernel/git/mmind/linux-rockchip.git tags/v4.3-rockchip32-soc3

for you to fetch changes up to 2a03c025fdea25a491c359b31d8a8c8d452b06d0:

  ARM: rockchip: pm: Fix PTR_ERR() argument (2015-08-24 12:39:14 +0200)

----------------------------------------------------------------
Fix for wrong error-codes in rk3288 suspend code.

----------------------------------------------------------------
Fabio Estevam (1):
      ARM: rockchip: pm: Fix PTR_ERR() argument

 arch/arm/mach-rockchip/pm.c | 4 ++--
 1 file changed, 2 insertions(+), 2 deletions(-)



From lee.jones at linaro.org  Tue Aug 25 02:30:47 2015
From: lee.jones at linaro.org (Lee Jones)
Date: Tue, 25 Aug 2015 10:30:47 +0100
Subject: [PATCH-v6 5/6] mfd: 88pm800: Set default interrupt clear method
In-Reply-To: <55DC2F36.50305@linaro.org>
References: <1436358392-15449-1-git-send-email-vaibhav.hiremath@linaro.org>
 <1436358392-15449-6-git-send-email-vaibhav.hiremath@linaro.org>
 <20150824135422.GF3237@x1> <55DB3627.2030503@linaro.org>
 <20150824155129.GA19409@x1> <55DB4A91.9000702@linaro.org>
 <20150825083033.GJ19409@x1> <55DC2F36.50305@linaro.org>
Message-ID: <20150825093047.GO19409@x1>

On Tue, 25 Aug 2015, Vaibhav Hiremath wrote:
> On Tuesday 25 August 2015 02:00 PM, Lee Jones wrote:
> >On Mon, 24 Aug 2015, Vaibhav Hiremath wrote:
> >>On Monday 24 August 2015 09:21 PM, Lee Jones wrote:
> >>>On Mon, 24 Aug 2015, Vaibhav Hiremath wrote:
> >>>>On Monday 24 August 2015 07:24 PM, Lee Jones wrote:
> >>>>>On Wed, 08 Jul 2015, Vaibhav Hiremath wrote:
> >>>>>
> >>>>>>As per the spec, bit 1 (INT_CLEAR_MODE) of reg addr 0xe
> >>>>>>(page 0) controls the method of clearing interrupt
> >>>>>>status of 88pm800 family of devices;
> >>>>>>
> >>>>>>   0: clear on read
> >>>>>>   1: clear on write
> >>>>>>
> >>>>>>If pdata is not coming from board file, then set the
> >>>>>>default irq clear method to "irq clear on write"
> >>>>>>
> >>>>>>Also, as suggested by "Lee Jones" renaming variable field
> >>>>>>to appropriate name and removed unnecessary field
> >>>>>>pm80x_chip.irq_mode, using platform_data.irq_clr_method.
> >>>>>>
> >>>>>>Signed-off-by: Zhao Ye <zhaoy at marvell.com>
> >>>>>>Signed-off-by: Vaibhav Hiremath <vaibhav.hiremath at linaro.org>
> >>>>>>Reviewed-by: Krzysztof Kozlowski <k.kozlowski at samsung.com>
> >>>>>>---
> >>>>>>  drivers/mfd/88pm800.c       | 15 ++++++++++-----
> >>>>>>  include/linux/mfd/88pm80x.h |  9 +++++++--
> >>>>>>  2 files changed, 17 insertions(+), 7 deletions(-)

[...]

> >>If you are OK with it, I will spin another version and submit it.
> >
> >If you can't use the value directly, which if you want to pull the
> >value from DT you can't, then either use the method above, or
> >something like this might be better:
> >
> >int clear_on_write = 0;
> >
> >if (pdata->clear_irq_on_write)
> >    clear_on_write = PM800_WAKEUP2_INT_WRITE_CLEAR;
> >
> >.. this way you only need to add one new define and you can drop
> >PM800_WAKEUP2_INT_READ_CLEAR altogether.  This is better, because it
> >will aid you to move to the BIT() macro easier (there is no BIT()
> >value for shifting 0's).
> >
> 
> Just to clarify, I will adopt this implementation.

Sounds good.  Although, I would suggest just using 'val' as the local
variable.  It makes it more clear that PM800_WAKEUP2_INT_WRITE_CLEAR
is a bit value.

-- 
Lee Jones
Linaro STMicroelectronics Landing Team Lead
Linaro.org ? Open source software for ARM SoCs
Follow Linaro: Facebook | Twitter | Blog


From lftan at altera.com  Tue Aug 25 02:35:43 2015
From: lftan at altera.com (Ley Foon Tan)
Date: Tue, 25 Aug 2015 17:35:43 +0800
Subject: [PATCH v5 0/5] Altera PCIe host controller driver with MSI support
Message-ID: <1440495348-2666-1-git-send-email-lftan@altera.com>

This is the 5th version of patch set to add support for Altera PCIe host
controller with MSI feature on Altera FPGA device families. This patchset
mainly resolve comments from Dinh Nguyen in v5 and some fixes.

It is based on patch series from Marc Zyngier "Per-device MSI domain &
platform MSI" [1] to get rid of struct msi_controller.

v4->v5 changes:
- pcie-altera: check error for tlp_read_packet
- pcie-altera: remove unused txs from altera_pcie struct
- doc: update pcie and msi binding doc
- fix aligned and unaligned qword in tlp_cfg_dword_write
- add altera_pcie_fixup_res

History:
-------
[v1]: https://lkml.org/lkml/2015/7/28/395
[v2]: https://lkml.org/lkml/2015/7/31/267
[v3]: http://www.kernelhub.org/?msg=811940&p=2
[v4]: https://lkml.org/lkml/2015/8/17/141

Ley Foon Tan (5):
  arm: add msi.h to Kbuild
  pci:host: Add Altera PCIe host controller driver
  pci: altera: Add Altera PCIe MSI driver
  Documentation: dt-bindings: pci: altera pcie device tree binding
  MAINTAINERS: Add Altera PCIe and MSI drivers maintainer

 .../devicetree/bindings/pci/altera-pcie-msi.txt    |  28 +
 .../devicetree/bindings/pci/altera-pcie.txt        |  49 ++
 MAINTAINERS                                        |  16 +
 arch/arm/include/asm/Kbuild                        |   1 +
 drivers/pci/host/Kconfig                           |  15 +
 drivers/pci/host/Makefile                          |   2 +
 drivers/pci/host/pcie-altera-msi.c                 | 322 +++++++++++
 drivers/pci/host/pcie-altera.c                     | 588 +++++++++++++++++++++
 8 files changed, 1021 insertions(+)
 create mode 100644 Documentation/devicetree/bindings/pci/altera-pcie-msi.txt
 create mode 100644 Documentation/devicetree/bindings/pci/altera-pcie.txt
 create mode 100644 drivers/pci/host/pcie-altera-msi.c
 create mode 100644 drivers/pci/host/pcie-altera.c

-- 
1.8.2.1



From lftan at altera.com  Tue Aug 25 02:35:44 2015
From: lftan at altera.com (Ley Foon Tan)
Date: Tue, 25 Aug 2015 17:35:44 +0800
Subject: [PATCH v5 1/5] arm: add msi.h to Kbuild
In-Reply-To: <1440495348-2666-1-git-send-email-lftan@altera.com>
References: <1440495348-2666-1-git-send-email-lftan@altera.com>
Message-ID: <1440495348-2666-2-git-send-email-lftan@altera.com>

Include asm-generic/msi.h to support CONFIG_GENERIC_MSI_IRQ_DOMAIN.
This to fix compilation error:
"include/linux/msi.h:123:21: fatal error: asm/msi.h:
No such file or directory"

Signed-off-by: Ley Foon Tan <lftan at altera.com>
---
 arch/arm/include/asm/Kbuild | 1 +
 1 file changed, 1 insertion(+)

diff --git a/arch/arm/include/asm/Kbuild b/arch/arm/include/asm/Kbuild
index 30b3bc1..362b053 100644
--- a/arch/arm/include/asm/Kbuild
+++ b/arch/arm/include/asm/Kbuild
@@ -15,6 +15,7 @@ generic-y += local64.h
 generic-y += mcs_spinlock.h
 generic-y += mm-arch-hooks.h
 generic-y += msgbuf.h
+generic-y += msi.h
 generic-y += param.h
 generic-y += parport.h
 generic-y += poll.h
-- 
1.8.2.1



From lftan at altera.com  Tue Aug 25 02:35:45 2015
From: lftan at altera.com (Ley Foon Tan)
Date: Tue, 25 Aug 2015 17:35:45 +0800
Subject: [PATCH v5 2/5] pci:host: Add Altera PCIe host controller driver
In-Reply-To: <1440495348-2666-1-git-send-email-lftan@altera.com>
References: <1440495348-2666-1-git-send-email-lftan@altera.com>
Message-ID: <1440495348-2666-3-git-send-email-lftan@altera.com>

This patch adds the Altera PCIe host controller driver.

Signed-off-by: Ley Foon Tan <lftan at altera.com>
---
 drivers/pci/host/Kconfig       |   7 +
 drivers/pci/host/Makefile      |   1 +
 drivers/pci/host/pcie-altera.c | 588 +++++++++++++++++++++++++++++++++++++++++
 3 files changed, 596 insertions(+)
 create mode 100644 drivers/pci/host/pcie-altera.c

diff --git a/drivers/pci/host/Kconfig b/drivers/pci/host/Kconfig
index 675c2d1..4b4754a 100644
--- a/drivers/pci/host/Kconfig
+++ b/drivers/pci/host/Kconfig
@@ -145,4 +145,11 @@ config PCIE_IPROC_BCMA
 	  Say Y here if you want to use the Broadcom iProc PCIe controller
 	  through the BCMA bus interface
 
+config PCIE_ALTERA
+	tristate "Altera PCIe controller"
+	depends on ARCH_SOCFPGA
+	help
+	  Say Y here if you want to enable PCIe controller support for Altera
+	  SoCFPGA family of SoCs.
+
 endmenu
diff --git a/drivers/pci/host/Makefile b/drivers/pci/host/Makefile
index 140d66f..6954f76 100644
--- a/drivers/pci/host/Makefile
+++ b/drivers/pci/host/Makefile
@@ -17,3 +17,4 @@ obj-$(CONFIG_PCI_VERSATILE) += pci-versatile.o
 obj-$(CONFIG_PCIE_IPROC) += pcie-iproc.o
 obj-$(CONFIG_PCIE_IPROC_PLATFORM) += pcie-iproc-platform.o
 obj-$(CONFIG_PCIE_IPROC_BCMA) += pcie-iproc-bcma.o
+obj-$(CONFIG_PCIE_ALTERA) += pcie-altera.o
diff --git a/drivers/pci/host/pcie-altera.c b/drivers/pci/host/pcie-altera.c
new file mode 100644
index 0000000..c168ec7
--- /dev/null
+++ b/drivers/pci/host/pcie-altera.c
@@ -0,0 +1,588 @@
+/*
+ * Copyright Altera Corporation (C) 2013-2015. All rights reserved
+ *
+ * This program is free software; you can redistribute it and/or modify it
+ * under the terms and conditions of the GNU General Public License,
+ * version 2, as published by the Free Software Foundation.
+ *
+ * This program is distributed in the hope 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.
+ *
+ * You should have received a copy of the GNU General Public License along with
+ * this program.  If not, see <http://www.gnu.org/licenses/>.
+ */
+#include <linux/delay.h>
+#include <linux/interrupt.h>
+#include <linux/irqchip/chained_irq.h>
+#include <linux/module.h>
+#include <linux/of_address.h>
+#include <linux/of_irq.h>
+#include <linux/of_pci.h>
+#include <linux/pci.h>
+#include <linux/platform_device.h>
+#include <linux/slab.h>
+
+#define A2P_ADDR_MAP_LO0		0x1000
+#define A2P_ADDR_MAP_HI0		0x1004
+#define RP_TX_REG0			0x2000
+#define RP_TX_REG1			0x2004
+#define RP_TX_CNTRL			0x2008
+#define RP_TX_EOP			0x2
+#define RP_TX_SOP			0x1
+#define RP_RXCPL_STATUS		0x2010
+#define RP_RXCPL_EOP			0x2
+#define RP_RXCPL_SOP			0x1
+#define RP_RXCPL_REG0			0x2014
+#define RP_RXCPL_REG1			0x2018
+#define P2A_INT_STATUS			0x3060
+#define P2A_INT_STS_ALL			0xF
+#define P2A_INT_ENABLE			0x3070
+#define P2A_INT_ENA_ALL			0xF
+#define RP_LTSSM			0x3C64
+#define LTSSM_L0			0xF
+
+/* TLP configuration type 0 and 1 */
+#define TLP_FMTTYPE_CFGRD0		0x04	/* Configuration Read Type 0 */
+#define TLP_FMTTYPE_CFGWR0		0x44	/* Configuration Write Type 0 */
+#define TLP_FMTTYPE_CFGRD1		0x05	/* Configuration Read Type 1 */
+#define TLP_FMTTYPE_CFGWR1		0x45	/* Configuration Write Type 1 */
+#define TLP_PAYLOAD_SIZE		0x01
+#define TLP_READ_TAG			0x1D
+#define TLP_WRITE_TAG			0x10
+#define TLP_CFG_DW0(fmttype)		(((fmttype) << 24) | TLP_PAYLOAD_SIZE)
+#define TLP_CFG_DW1(reqid, tag)		(((reqid) << 16) | (tag << 8) | 0xF)
+#define TLP_CFG_DW2(bus, devfn, offset)	\
+				(((bus) << 24) | ((devfn) << 16) | (offset))
+#define TLP_REQ_ID(bus, devfn)		(((bus) << 8) | (devfn))
+#define TLP_COMPL_STATUS(hdr)		(((hdr) & 0xE0) >> 13)
+#define TLP_HDR_SIZE			3
+#define TLP_LOOP			10
+
+#define INTX_NUM		4
+
+/* Address translation table entry size */
+#define ATT_ENTRY_SIZE		8
+
+#define DWORD_MASK		3
+
+struct altera_pcie {
+	struct platform_device	*pdev;
+	void __iomem		*cra_base;
+	int			irq;
+	u8			root_bus_nr;
+	struct irq_domain		*irq_domain;
+	struct resource		bus_range;
+	struct list_head		resources;
+};
+
+struct tlp_rp_regpair_t {
+	u32 ctrl;
+	u32 reg0;
+	u32 reg1;
+};
+
+static void altera_pcie_retrain(struct pci_dev *dev)
+{
+	u16 linkcap, linkstat;
+
+	/*
+	 * Set the retrain bit if the PCIe rootport support > 2.5GB/s, but
+	 * current speed is 2.5 GB/s.
+	 */
+	pcie_capability_read_word(dev, PCI_EXP_LNKCAP, &linkcap);
+
+	if ((linkcap & PCI_EXP_LNKCAP_SLS) <= PCI_EXP_LNKCAP_SLS_2_5GB)
+		return;
+
+	pcie_capability_read_word(dev, PCI_EXP_LNKSTA, &linkstat);
+	if ((linkstat & PCI_EXP_LNKSTA_CLS) == PCI_EXP_LNKSTA_CLS_2_5GB)
+		pcie_capability_set_word(dev, PCI_EXP_LNKCTL,
+					 PCI_EXP_LNKCTL_RL);
+}
+DECLARE_PCI_FIXUP_EARLY(PCI_ANY_ID, PCI_ANY_ID, altera_pcie_retrain);
+
+static void altera_pcie_fixup_res(struct pci_dev *dev)
+{
+	/*
+	 * Prevent enumeration of root port.
+	 */
+	if (!dev->bus->parent && dev->devfn == 0) {
+		int i;
+
+		for (i = 0; i < PCI_NUM_RESOURCES; i++) {
+			dev->resource[i].start = 0;
+			dev->resource[i].end   = 0;
+			dev->resource[i].flags   = 0;
+		}
+	}
+}
+DECLARE_PCI_FIXUP_HEADER(PCI_ANY_ID, PCI_ANY_ID, altera_pcie_fixup_res);
+
+static inline void cra_writel(struct altera_pcie *pcie, u32 value, u32 reg)
+{
+	writel_relaxed(value, pcie->cra_base + reg);
+}
+
+static inline u32 cra_readl(struct altera_pcie *pcie, u32 reg)
+{
+	return readl_relaxed(pcie->cra_base + reg);
+}
+
+static void tlp_read_rx(struct altera_pcie *pcie,
+			struct tlp_rp_regpair_t *tlp_rp_regdata)
+{
+	tlp_rp_regdata->ctrl = cra_readl(pcie, RP_RXCPL_STATUS);
+	tlp_rp_regdata->reg0 = cra_readl(pcie, RP_RXCPL_REG0);
+	tlp_rp_regdata->reg1 = cra_readl(pcie, RP_RXCPL_REG1);
+}
+
+static void tlp_write_tx(struct altera_pcie *pcie,
+			 struct tlp_rp_regpair_t *tlp_rp_regdata)
+{
+	cra_writel(pcie, tlp_rp_regdata->reg0, RP_TX_REG0);
+	cra_writel(pcie, tlp_rp_regdata->reg1, RP_TX_REG1);
+	cra_writel(pcie, tlp_rp_regdata->ctrl, RP_TX_CNTRL);
+}
+
+static bool altera_pcie_link_is_up(struct altera_pcie *pcie)
+{
+	return !!(cra_readl(pcie, RP_LTSSM) & LTSSM_L0);
+}
+
+static bool altera_pcie_valid_config(struct altera_pcie *pcie,
+				     struct pci_bus *bus, int dev)
+{
+	/* If there is no link, then there is no device */
+	if (bus->number != pcie->root_bus_nr) {
+		if (!altera_pcie_link_is_up(pcie))
+			return false;
+	}
+
+	/* access only one slot on each root port */
+	if (bus->number == pcie->root_bus_nr && dev > 0)
+		return false;
+
+	/*
+	 * Do not read more than one device on the bus directly attached
+	 * to RC.
+	 */
+	if (bus->primary == pcie->root_bus_nr && dev > 0)
+		return false;
+
+	 return true;
+}
+
+static int tlp_read_packet(struct altera_pcie *pcie, u32 *value)
+{
+	u8 loop;
+	struct tlp_rp_regpair_t tlp_rp_regdata;
+
+	for (loop = 0; loop < TLP_LOOP; loop++) {
+		tlp_read_rx(pcie, &tlp_rp_regdata);
+		if (tlp_rp_regdata.ctrl & RP_RXCPL_EOP) {
+			if (value)
+				*value = tlp_rp_regdata.reg0;
+			return PCIBIOS_SUCCESSFUL;
+		}
+		udelay(5);
+	}
+
+	return -ENOENT;
+}
+
+static void tlp_write_packet_unaligned(struct altera_pcie *pcie, u32 *headers,
+				       u32 data)
+{
+	struct tlp_rp_regpair_t tlp_rp_regdata;
+
+	tlp_rp_regdata.reg0 = headers[0];
+	tlp_rp_regdata.reg1 = headers[1];
+	tlp_rp_regdata.ctrl = RP_TX_SOP;
+	tlp_write_tx(pcie, &tlp_rp_regdata);
+
+	tlp_rp_regdata.reg0 = headers[2];
+	tlp_rp_regdata.reg1 = data;
+	tlp_rp_regdata.ctrl = RP_TX_EOP;
+	tlp_write_tx(pcie, &tlp_rp_regdata);
+}
+
+static void tlp_write_packet_aligned(struct altera_pcie *pcie, u32 *headers,
+				     u32 data)
+{
+	struct tlp_rp_regpair_t tlp_rp_regdata;
+
+	tlp_rp_regdata.reg0 = headers[0];
+	tlp_rp_regdata.reg1 = headers[1];
+	tlp_rp_regdata.ctrl = RP_TX_SOP;
+	tlp_write_tx(pcie, &tlp_rp_regdata);
+
+	tlp_rp_regdata.reg0 = headers[2];
+	tlp_rp_regdata.reg1 = 0;
+	tlp_rp_regdata.ctrl = 0;
+	tlp_write_tx(pcie, &tlp_rp_regdata);
+
+	tlp_rp_regdata.reg0 = data;
+	tlp_rp_regdata.reg1 = 0;
+	tlp_rp_regdata.ctrl = RP_TX_EOP;
+	tlp_write_tx(pcie, &tlp_rp_regdata);
+}
+
+static int tlp_cfg_dword_read(struct altera_pcie *pcie, u8 bus, u32 devfn,
+			      int where, u32 *value)
+{
+	int ret;
+	u32 headers[TLP_HDR_SIZE];
+
+	if (bus == pcie->root_bus_nr)
+		headers[0] = TLP_CFG_DW0(TLP_FMTTYPE_CFGRD0);
+	else
+		headers[0] = TLP_CFG_DW0(TLP_FMTTYPE_CFGRD1);
+
+	headers[1] = TLP_CFG_DW1(TLP_REQ_ID(pcie->root_bus_nr, devfn),
+					TLP_READ_TAG);
+	headers[2] = TLP_CFG_DW2(bus, devfn, where);
+
+	tlp_write_packet_unaligned(pcie, headers, 0);
+
+	ret = tlp_read_packet(pcie, value);
+	if (ret != PCIBIOS_SUCCESSFUL)
+		*value = ~0UL;	/* return 0xFFFFFFFF if error */
+
+	return ret;
+}
+
+static int tlp_cfg_dword_write(struct altera_pcie *pcie, u8 bus, u32 devfn,
+			       int where, u32 value)
+{
+	u32 headers[TLP_HDR_SIZE];
+	int ret;
+
+	if (bus == pcie->root_bus_nr)
+		headers[0] = TLP_CFG_DW0(TLP_FMTTYPE_CFGWR0);
+	else
+		headers[0] = TLP_CFG_DW0(TLP_FMTTYPE_CFGWR1);
+
+	headers[1] = TLP_CFG_DW1(TLP_REQ_ID(pcie->root_bus_nr, devfn),
+					TLP_WRITE_TAG);
+	headers[2] = TLP_CFG_DW2(bus, devfn, where);
+
+	/* check alignment to Qword */
+	if ((where & 0x7) == 0)
+		tlp_write_packet_aligned(pcie, headers, value);
+	else
+		tlp_write_packet_unaligned(pcie, headers, value);
+
+	ret = tlp_read_packet(pcie, NULL);
+	if (ret != PCIBIOS_SUCCESSFUL)
+		return ret;
+
+	/* Keep an eye out for changes to the root bus number */
+	if ((bus == pcie->root_bus_nr) && (where == PCI_PRIMARY_BUS))
+		pcie->root_bus_nr = (u8)(value);
+
+	return PCIBIOS_SUCCESSFUL;
+}
+
+static int altera_pcie_cfg_read(struct pci_bus *bus, unsigned int devfn,
+				int where, int size, u32 *value)
+{
+	struct altera_pcie *pcie = bus->sysdata;
+	int ret;
+
+	if (!altera_pcie_valid_config(pcie, bus, PCI_SLOT(devfn))) {
+		*value = ~0UL;
+		return PCIBIOS_DEVICE_NOT_FOUND;
+	}
+
+	ret = tlp_cfg_dword_read(pcie, bus->number, devfn,
+				 (where & ~DWORD_MASK), value);
+	if (ret != PCIBIOS_SUCCESSFUL)
+		return ret;
+
+	if (size == 1)
+		*value = (*value >> (8 * (where & 0x3))) & 0xff;
+	else if (size == 2)
+		*value = (*value >> (8 * (where & 0x2))) & 0xffff;
+
+	return PCIBIOS_SUCCESSFUL;
+}
+
+static int altera_pcie_cfg_write(struct pci_bus *bus, unsigned int devfn,
+				 int where, int size, u32 value)
+{
+	struct altera_pcie *pcie = bus->sysdata;
+	u32 data32 = value;
+	u32 shift = 8 * (where & 3);
+	int ret;
+
+	if (!altera_pcie_valid_config(pcie, bus, PCI_SLOT(devfn)))
+		return PCIBIOS_DEVICE_NOT_FOUND;
+
+	/* write partial */
+	if (size != sizeof(u32)) {
+		ret = tlp_cfg_dword_read(pcie, bus->number, devfn,
+					 where & ~DWORD_MASK, &data32);
+		if (ret)
+			return ret;
+
+		if (size == 2)
+			data32 = (data32 & ~(0xffff << shift)) |
+					((value & 0xffff) << shift);
+		 else if (size == 1)
+			data32 = (data32 & ~(0xff << shift)) |
+					((value & 0xff) << shift);
+	}
+
+	return tlp_cfg_dword_write(pcie, bus->number, devfn,
+		(where & ~DWORD_MASK), data32);
+}
+
+static struct pci_ops altera_pcie_ops = {
+	.read = altera_pcie_cfg_read,
+	.write = altera_pcie_cfg_write,
+};
+
+static int altera_pcie_intx_map(struct irq_domain *domain, unsigned int irq,
+				irq_hw_number_t hwirq)
+{
+	irq_set_chip_and_handler(irq, &dummy_irq_chip, handle_simple_irq);
+	irq_set_chip_data(irq, domain->host_data);
+	set_irq_flags(irq, IRQF_VALID);
+
+	return 0;
+}
+
+static const struct irq_domain_ops intx_domain_ops = {
+	.map = altera_pcie_intx_map,
+};
+
+static void altera_pcie_isr(unsigned int irq, struct irq_desc *desc)
+{
+	struct irq_chip *chip = irq_desc_get_chip(desc);
+	struct altera_pcie *pcie;
+	unsigned long status;
+	u32 bit;
+	u32 virq;
+
+	chained_irq_enter(chip, desc);
+	pcie = irq_desc_get_handler_data(desc);
+
+	do {
+		status = cra_readl(pcie, P2A_INT_STATUS) & P2A_INT_STS_ALL;
+		if (!status)
+			break;
+
+		do {
+			bit = find_first_bit(&status, INTX_NUM);
+			/* clear interrupts */
+			cra_writel(pcie, 1 << bit, P2A_INT_STATUS);
+
+			virq = irq_find_mapping(pcie->irq_domain, bit + 1);
+			if (virq)
+				generic_handle_irq(virq);
+			else
+				dev_info(&pcie->pdev->dev, "unexpected IRQ\n");
+
+			/* Clear the bit from status and repeat without reading
+			 * again status register. */
+			__clear_bit(bit, &status);
+		} while (status);
+	} while (1);
+
+	chained_irq_exit(chip, desc);
+}
+
+static void altera_pcie_release_of_pci_ranges(struct altera_pcie *pcie)
+{
+	pci_free_resource_list(&pcie->resources);
+}
+
+static int altera_pcie_parse_request_of_pci_ranges(struct altera_pcie *pcie)
+{
+	int err, res_valid = 0;
+	struct device *dev = &pcie->pdev->dev;
+	struct device_node *np = dev->of_node;
+	resource_size_t iobase;
+	struct resource_entry *win;
+
+	err = of_pci_get_host_bridge_resources(np, 0, 0xff, &pcie->resources,
+					       &iobase);
+	if (err)
+		return err;
+
+	resource_list_for_each_entry(win, &pcie->resources) {
+		struct resource *parent, *res = win->res;
+
+		switch (resource_type(res)) {
+		case IORESOURCE_MEM:
+			parent = &iomem_resource;
+			res_valid |= !(res->flags & IORESOURCE_PREFETCH);
+			break;
+		default:
+			continue;
+		}
+
+		err = devm_request_resource(dev, parent, res);
+		if (err)
+			goto out_release_res;
+	}
+
+	if (!res_valid) {
+		dev_err(dev, "non-prefetchable memory resource required\n");
+		err = -EINVAL;
+		goto out_release_res;
+	}
+
+	return 0;
+
+out_release_res:
+	altera_pcie_release_of_pci_ranges(pcie);
+	return err;
+}
+
+static void altera_pcie_free_irq_domain(struct altera_pcie *pcie)
+{
+	int i;
+	u32 irq;
+
+	for (i = 0; i < INTX_NUM; i++) {
+		irq = irq_find_mapping(pcie->irq_domain, i);
+		if (irq > 0)
+			irq_dispose_mapping(irq);
+	}
+
+	irq_domain_remove(pcie->irq_domain);
+}
+
+static int altera_pcie_init_irq_domain(struct altera_pcie *pcie)
+{
+	struct device *dev = &pcie->pdev->dev;
+	struct device_node *node = dev->of_node;
+
+	/* Setup INTx */
+	pcie->irq_domain = irq_domain_add_linear(node, INTX_NUM,
+					&intx_domain_ops, pcie);
+	if (!pcie->irq_domain) {
+		dev_err(dev, "Failed to get a INTx IRQ domain\n");
+		return -ENOMEM;
+	}
+
+	return 0;
+}
+
+static int altera_pcie_parse_dt(struct altera_pcie *pcie)
+{
+	struct resource *cra;
+	struct platform_device *pdev = pcie->pdev;
+
+	cra = platform_get_resource_byname(pdev, IORESOURCE_MEM, "Cra");
+	if (!cra) {
+		cra = platform_get_resource_byname(pdev, IORESOURCE_MEM, "cra");
+		if (!cra) {
+			dev_err(&pdev->dev,
+				"no cra memory resource defined\n");
+			return -ENODEV;
+		}
+	}
+
+	pcie->cra_base = devm_ioremap_resource(&pdev->dev, cra);
+	if (IS_ERR(pcie->cra_base)) {
+		dev_err(&pdev->dev, "failed to map cra memory\n");
+		return PTR_ERR(pcie->cra_base);
+	}
+
+	/* setup IRQ */
+	pcie->irq = platform_get_irq(pdev, 0);
+	if (pcie->irq <= 0) {
+		dev_err(&pdev->dev, "failed to get IRQ: %d\n", pcie->irq);
+		return -EINVAL;
+	}
+
+	irq_set_chained_handler_and_data(pcie->irq, altera_pcie_isr, pcie);
+
+	return 0;
+}
+
+static int altera_pcie_probe(struct platform_device *pdev)
+{
+	struct altera_pcie *pcie;
+	struct pci_bus *bus;
+	int ret;
+
+	pcie = devm_kzalloc(&pdev->dev, sizeof(*pcie), GFP_KERNEL);
+	if (!pcie)
+		return -ENOMEM;
+
+	pcie->pdev = pdev;
+
+	ret = altera_pcie_parse_dt(pcie);
+	if (ret) {
+		dev_err(&pdev->dev, "Parsing DT failed\n");
+		return ret;
+	}
+
+	INIT_LIST_HEAD(&pcie->resources);
+
+	ret = altera_pcie_parse_request_of_pci_ranges(pcie);
+	if (ret) {
+		dev_err(&pdev->dev, "Failed add resources\n");
+		return ret;
+	}
+
+	ret = altera_pcie_init_irq_domain(pcie);
+	if (ret) {
+		dev_err(&pdev->dev, "Failed creating IRQ Domain\n");
+		return ret;
+	}
+
+	pcie->root_bus_nr = 0;
+
+	/* clear all interrupts */
+	cra_writel(pcie, P2A_INT_STS_ALL, P2A_INT_STATUS);
+	/* enable all interrupts */
+	cra_writel(pcie, P2A_INT_ENA_ALL, P2A_INT_ENABLE);
+
+	bus = pci_scan_root_bus(&pdev->dev, pcie->root_bus_nr, &altera_pcie_ops,
+				pcie, &pcie->resources);
+	if (!bus)
+		return -ENOMEM;
+
+	pci_fixup_irqs(pci_common_swizzle, of_irq_parse_and_map_pci);
+	pci_assign_unassigned_bus_resources(bus);
+	pci_bus_add_devices(bus);
+
+	platform_set_drvdata(pdev, pcie);
+	return ret;
+}
+
+static int __exit altera_pcie_remove(struct platform_device *pdev)
+{
+	struct altera_pcie *pcie = platform_get_drvdata(pdev);
+
+	altera_pcie_free_irq_domain(pcie);
+	platform_set_drvdata(pdev, NULL);
+	return 0;
+}
+
+static const struct of_device_id altera_pcie_of_match[] = {
+	{ .compatible = "altr,pcie-root-port-1.0", },
+	{},
+};
+MODULE_DEVICE_TABLE(of, altera_pcie_of_match);
+
+static struct platform_driver altera_pcie_driver = {
+	.probe		= altera_pcie_probe,
+	.remove		= altera_pcie_remove,
+	.driver = {
+		.name	= "altera-pcie",
+		.of_match_table = altera_pcie_of_match,
+	},
+};
+
+module_platform_driver(altera_pcie_driver);
+
+MODULE_AUTHOR("Ley Foon Tan <lftan at altera.com>");
+MODULE_DESCRIPTION("Altera PCIe host controller driver");
+MODULE_LICENSE("GPL v2");
-- 
1.8.2.1



From lftan at altera.com  Tue Aug 25 02:35:46 2015
From: lftan at altera.com (Ley Foon Tan)
Date: Tue, 25 Aug 2015 17:35:46 +0800
Subject: [PATCH v5 3/5] pci: altera: Add Altera PCIe MSI driver
In-Reply-To: <1440495348-2666-1-git-send-email-lftan@altera.com>
References: <1440495348-2666-1-git-send-email-lftan@altera.com>
Message-ID: <1440495348-2666-4-git-send-email-lftan@altera.com>

This patch adds Altera PCIe MSI driver. This soft IP supports configurable
number of vectors, which is a dts parameter.

Signed-off-by: Ley Foon Tan <lftan at altera.com>
---
 drivers/pci/host/Kconfig           |   8 +
 drivers/pci/host/Makefile          |   1 +
 drivers/pci/host/pcie-altera-msi.c | 322 +++++++++++++++++++++++++++++++++++++
 3 files changed, 331 insertions(+)
 create mode 100644 drivers/pci/host/pcie-altera-msi.c

diff --git a/drivers/pci/host/Kconfig b/drivers/pci/host/Kconfig
index 4b4754a..d28cc6d 100644
--- a/drivers/pci/host/Kconfig
+++ b/drivers/pci/host/Kconfig
@@ -152,4 +152,12 @@ config PCIE_ALTERA
 	  Say Y here if you want to enable PCIe controller support for Altera
 	  SoCFPGA family of SoCs.
 
+config PCIE_ALTERA_MSI
+	bool "Altera PCIe MSI feature"
+	depends on PCI_MSI
+	select PCI_MSI_IRQ_DOMAIN
+	help
+	  Say Y here if you want PCIe MSI support for the Altera SocFPGA SoC.
+	  This MSI driver supports Altera MSI to GIC controller IP.
+
 endmenu
diff --git a/drivers/pci/host/Makefile b/drivers/pci/host/Makefile
index 6954f76..6c4913d 100644
--- a/drivers/pci/host/Makefile
+++ b/drivers/pci/host/Makefile
@@ -18,3 +18,4 @@ obj-$(CONFIG_PCIE_IPROC) += pcie-iproc.o
 obj-$(CONFIG_PCIE_IPROC_PLATFORM) += pcie-iproc-platform.o
 obj-$(CONFIG_PCIE_IPROC_BCMA) += pcie-iproc-bcma.o
 obj-$(CONFIG_PCIE_ALTERA) += pcie-altera.o
+obj-$(CONFIG_PCIE_ALTERA_MSI) += pcie-altera-msi.o
diff --git a/drivers/pci/host/pcie-altera-msi.c b/drivers/pci/host/pcie-altera-msi.c
new file mode 100644
index 0000000..d3ad96f
--- /dev/null
+++ b/drivers/pci/host/pcie-altera-msi.c
@@ -0,0 +1,322 @@
+/*
+ * Copyright Altera Corporation (C) 2013-2015. All rights reserved
+ *
+ * This program is free software; you can redistribute it and/or modify it
+ * under the terms and conditions of the GNU General Public License,
+ * version 2, as published by the Free Software Foundation.
+ *
+ * This program is distributed in the hope 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.
+ *
+ * You should have received a copy of the GNU General Public License along with
+ * this program.  If not, see <http://www.gnu.org/licenses/>.
+ */
+#include <linux/interrupt.h>
+#include <linux/irqchip/chained_irq.h>
+#include <linux/module.h>
+#include <linux/msi.h>
+#include <linux/of_address.h>
+#include <linux/of_irq.h>
+#include <linux/of_pci.h>
+#include <linux/pci.h>
+#include <linux/platform_device.h>
+#include <linux/slab.h>
+
+#define MSI_STATUS		0x0
+#define MSI_ERROR		0x4
+#define MSI_INTMASK		0x8
+
+#define MAX_MSI_VECTORS		32
+struct altera_msi {
+	DECLARE_BITMAP(used, MAX_MSI_VECTORS);
+	struct mutex		lock;	/* proctect used variable */
+	struct platform_device	*pdev;
+	struct irq_domain		*msi_domain;
+	struct irq_domain		*inner_domain;
+	void __iomem		*csr_base;
+	void __iomem		*vector_base;
+	phys_addr_t		vector_phy;
+	u32			num_of_vectors;
+	int			irq;
+};
+
+static inline void msi_writel(struct altera_msi *msi, u32 value, u32 reg)
+{
+	writel_relaxed(value, msi->csr_base + reg);
+}
+
+static inline u32 msi_readl(struct altera_msi *msi, u32 reg)
+{
+	return readl_relaxed(msi->csr_base + reg);
+}
+
+static void altera_msi_isr(unsigned int irq, struct irq_desc *desc)
+{
+	struct irq_chip *chip = irq_desc_get_chip(desc);
+	struct altera_msi *msi;
+	unsigned long status;
+	u32 num_of_vectors;
+	u32 bit;
+	u32 virq;
+
+	chained_irq_enter(chip, desc);
+	msi = irq_desc_get_handler_data(desc);
+	num_of_vectors = msi->num_of_vectors;
+
+	do {
+		status = msi_readl(msi, MSI_STATUS);
+		if (!status)
+			break;
+
+		do {
+			bit = find_first_bit(&status, num_of_vectors);
+			/* Dummy read from vector to clear the interrupt */
+			readl_relaxed(msi->vector_base + (bit * sizeof(u32)));
+
+			virq = irq_find_mapping(msi->inner_domain, bit);
+			if (virq && test_bit(bit, msi->used))
+				generic_handle_irq(virq);
+			else
+				dev_err(&msi->pdev->dev, "unexpected MSI\n");
+
+			/* Clear the bit from status and repeat without reading
+			 * again status register. */
+			__clear_bit(bit, &status);
+		} while (status);
+	} while (1);
+
+	chained_irq_exit(chip, desc);
+}
+
+static struct irq_chip altera_msi_irq_chip = {
+	.name = "Altera PCIe MSI",
+	.irq_enable = pci_msi_unmask_irq,
+	.irq_disable = pci_msi_mask_irq,
+	.irq_mask = pci_msi_mask_irq,
+	.irq_unmask = pci_msi_unmask_irq,
+};
+
+static struct msi_domain_info altera_msi_domain_info = {
+	.flags	= (MSI_FLAG_USE_DEF_DOM_OPS | MSI_FLAG_USE_DEF_CHIP_OPS |
+		     MSI_FLAG_PCI_MSIX),
+	.chip	= &altera_msi_irq_chip,
+};
+
+static void altera_compose_msi_msg(struct irq_data *data, struct msi_msg *msg)
+{
+	struct altera_msi *msi = irq_data_get_irq_chip_data(data);
+	phys_addr_t addr = msi->vector_phy + (data->hwirq * sizeof(u32));
+
+	msg->address_lo = lower_32_bits(addr);
+	msg->address_hi = upper_32_bits(addr);
+	msg->data = data->hwirq;
+
+	dev_dbg(&msi->pdev->dev, "msi#%d address_lo 0x%x address_hi 0x%x\n",
+		(int)data->hwirq, msg->address_hi, msg->address_lo);
+}
+
+static int altera_msi_set_affinity(struct irq_data *irq_data,
+				   const struct cpumask *mask, bool force)
+{
+	 return -EINVAL;
+}
+
+static struct irq_chip altera_msi_bottom_irq_chip = {
+	.name			= "Altera MSI",
+	.irq_compose_msi_msg	= altera_compose_msi_msg,
+	.irq_set_affinity	= altera_msi_set_affinity,
+};
+
+static int altera_irq_domain_alloc(struct irq_domain *domain, unsigned int virq,
+				   unsigned int nr_irqs, void *args)
+{
+	struct altera_msi *msi = domain->host_data;
+	unsigned long bit;
+	u32 mask;
+
+	WARN_ON(nr_irqs != 1);
+	mutex_lock(&msi->lock);
+
+	bit = find_first_zero_bit(msi->used, msi->num_of_vectors);
+	if (bit >= msi->num_of_vectors)
+		return -ENOSPC;
+
+	set_bit(bit, msi->used);
+
+	mutex_unlock(&msi->lock);
+
+	irq_domain_set_info(domain, virq, bit, &altera_msi_bottom_irq_chip,
+			    domain->host_data, handle_simple_irq,
+			    NULL, NULL);
+	set_irq_flags(virq, IRQF_VALID);
+
+	mask = msi_readl(msi, MSI_INTMASK);
+	mask |= 1 << bit;
+	msi_writel(msi, mask, MSI_INTMASK);
+
+	return 0;
+}
+
+static void altera_irq_domain_free(struct irq_domain *domain,
+				   unsigned int virq, unsigned int nr_irqs)
+{
+	struct irq_data *d = irq_domain_get_irq_data(domain, virq);
+	struct altera_msi *msi = irq_data_get_irq_chip_data(d);
+	u32 mask;
+
+	mutex_lock(&msi->lock);
+
+	if (!test_bit(d->hwirq, msi->used)) {
+		dev_err(&msi->pdev->dev, "trying to free unused MSI#%lu\n",
+			d->hwirq);
+	} else {
+		__clear_bit(d->hwirq, msi->used);
+		mask = msi_readl(msi, MSI_INTMASK);
+		mask &= ~(1 << d->hwirq);
+		msi_writel(msi, mask, MSI_INTMASK);
+	}
+
+	mutex_unlock(&msi->lock);
+}
+
+static const struct irq_domain_ops msi_domain_ops = {
+	.alloc	= altera_irq_domain_alloc,
+	.free	= altera_irq_domain_free,
+};
+
+static int altera_allocate_domains(struct altera_msi *msi)
+{
+	msi->inner_domain = irq_domain_add_linear(NULL, msi->num_of_vectors,
+					     &msi_domain_ops, msi);
+	if (!msi->inner_domain) {
+		dev_err(&msi->pdev->dev, "failed to create IRQ domain\n");
+		return -ENOMEM;
+	}
+
+	msi->msi_domain = pci_msi_create_irq_domain(msi->pdev->dev.of_node,
+				&altera_msi_domain_info, msi->inner_domain);
+	if (!msi->msi_domain) {
+		dev_err(&msi->pdev->dev, "failed to create MSI domain\n");
+		irq_domain_remove(msi->inner_domain);
+		return -ENOMEM;
+	}
+
+	return 0;
+}
+
+static void altera_free_domains(struct altera_msi *msi)
+{
+	irq_domain_remove(msi->msi_domain);
+	irq_domain_remove(msi->inner_domain);
+}
+
+static int altera_msi_remove(struct platform_device *pdev)
+{
+	struct altera_msi *msi = platform_get_drvdata(pdev);
+
+	msi_writel(msi, 0, MSI_INTMASK);
+	irq_set_chained_handler(msi->irq, NULL);
+	irq_set_handler_data(msi->irq, NULL);
+
+	altera_free_domains(msi);
+
+	platform_set_drvdata(pdev, NULL);
+	return 0;
+}
+
+static int altera_msi_probe(struct platform_device *pdev)
+{
+	struct altera_msi *msi;
+	struct device_node *np = pdev->dev.of_node;
+	struct resource *res;
+	int ret;
+
+	msi = devm_kzalloc(&pdev->dev, sizeof(struct altera_msi),
+			   GFP_KERNEL);
+	if (!msi)
+		return -ENOMEM;
+
+	mutex_init(&msi->lock);
+	msi->pdev = pdev;
+
+	res = platform_get_resource_byname(pdev, IORESOURCE_MEM, "csr");
+	if (!res) {
+		dev_err(&pdev->dev,
+			"no csr memory resource defined\n");
+		return -ENODEV;
+	}
+
+	msi->csr_base = devm_ioremap_resource(&pdev->dev, res);
+	if (IS_ERR(msi->csr_base)) {
+		dev_err(&pdev->dev, "failed to map csr memory\n");
+		return PTR_ERR(msi->csr_base);
+	}
+
+	res = platform_get_resource_byname(pdev, IORESOURCE_MEM,
+					   "vector_slave");
+	if (!res) {
+		dev_err(&pdev->dev,
+			"no vector_slave memory resource defined\n");
+		return -ENODEV;
+	}
+
+	msi->vector_base = devm_ioremap_resource(&pdev->dev, res);
+	if (IS_ERR(msi->vector_base)) {
+		dev_err(&pdev->dev, "failed to map vector_slave memory\n");
+		return PTR_ERR(msi->vector_base);
+	}
+
+	msi->vector_phy = res->start;
+
+	if (of_property_read_u32(np, "num-vectors", &msi->num_of_vectors)) {
+		dev_err(&pdev->dev, "failed to parse the number of vectors\n");
+		return -EINVAL;
+	}
+
+	ret = altera_allocate_domains(msi);
+	if (ret)
+		return ret;
+
+	msi->irq = platform_get_irq(pdev, 0);
+	if (msi->irq <= 0) {
+		dev_err(&pdev->dev, "failed to map IRQ: %d\n", msi->irq);
+		ret = -ENODEV;
+		goto err;
+	}
+
+	irq_set_chained_handler_and_data(msi->irq, altera_msi_isr, msi);
+	platform_set_drvdata(pdev, msi);
+
+	return 0;
+
+err:
+	altera_msi_remove(pdev);
+	return ret;
+}
+
+static const struct of_device_id altera_msi_of_match[] = {
+	{ .compatible = "altr,msi-1.0", NULL },
+	{ },
+};
+
+static struct platform_driver altera_msi_driver = {
+	.driver = {
+		.name = "altera-msi",
+		.of_match_table = altera_msi_of_match,
+	},
+	.probe = altera_msi_probe,
+	.remove = altera_msi_remove,
+};
+
+static int __init altera_msi_init(void)
+{
+	return platform_driver_register(&altera_msi_driver);
+}
+
+subsys_initcall(altera_msi_init);
+
+MODULE_AUTHOR("Ley Foon Tan <lftan at altera.com>");
+MODULE_DESCRIPTION("Altera PCIe MSI support");
+MODULE_LICENSE("GPL v2");
-- 
1.8.2.1



From lftan at altera.com  Tue Aug 25 02:35:47 2015
From: lftan at altera.com (Ley Foon Tan)
Date: Tue, 25 Aug 2015 17:35:47 +0800
Subject: [PATCH v5 4/5] Documentation: dt-bindings: pci: altera pcie device
 tree binding
In-Reply-To: <1440495348-2666-1-git-send-email-lftan@altera.com>
References: <1440495348-2666-1-git-send-email-lftan@altera.com>
Message-ID: <1440495348-2666-5-git-send-email-lftan@altera.com>

This patch adds the bindings for Altera PCIe host controller driver and
Altera PCIe MSI driver.

Signed-off-by: Ley Foon Tan <lftan at altera.com>
---
 .../devicetree/bindings/pci/altera-pcie-msi.txt    | 28 +++++++++++++
 .../devicetree/bindings/pci/altera-pcie.txt        | 49 ++++++++++++++++++++++
 2 files changed, 77 insertions(+)
 create mode 100644 Documentation/devicetree/bindings/pci/altera-pcie-msi.txt
 create mode 100644 Documentation/devicetree/bindings/pci/altera-pcie.txt

diff --git a/Documentation/devicetree/bindings/pci/altera-pcie-msi.txt b/Documentation/devicetree/bindings/pci/altera-pcie-msi.txt
new file mode 100644
index 0000000..53ad2388
--- /dev/null
+++ b/Documentation/devicetree/bindings/pci/altera-pcie-msi.txt
@@ -0,0 +1,28 @@
+* Altera PCIe MSI controller
+
+Required properties:
+- compatible:	should contain "altr,msi-1.0"
+- reg:		specifies the physical base address of the controller and
+		the length of the memory mapped region.
+- reg-names:	must include the following entries:
+		"csr": CSR registers
+		"vector_slave": vectors slave port region
+- interrupt-parent:	interrupt source phandle.
+- interrupts:	specifies the interrupt source of the parent interrupt
+		controller. The format of the interrupt specifier depends on the
+		parent interrupt controller.
+- num-vectors:	number of vectors, range 1 to 32.
+- msi-controller:	indicates that this is MSI controller node
+
+
+Example
+msi0: msi at 0xFF200000 {
+	compatible = "altr,msi-1.0";
+	reg = <0xFF200000 0x00000010
+		0xFF200010 0x00000080>;
+	reg-names = "csr", "vector_slave";
+	interrupt-parent = <&hps_0_arm_gic_0>;
+	interrupts = <0 42 4>;
+	msi-controller = <1>;
+	num-vectors = <32>;
+};
diff --git a/Documentation/devicetree/bindings/pci/altera-pcie.txt b/Documentation/devicetree/bindings/pci/altera-pcie.txt
new file mode 100644
index 0000000..4440db1
--- /dev/null
+++ b/Documentation/devicetree/bindings/pci/altera-pcie.txt
@@ -0,0 +1,49 @@
+* Altera PCIe controller
+
+Required properties:
+- compatible :	should contain "altr,pcie-root-port-1.0"
+- reg:		a list of physical base address and length for TXS and CRA.
+- reg-names:	must include the following entries:
+		"Txs" or "txs": TX slave port region
+		"Cra" or "cra": Control register access region
+- interrupt-parent:	interrupt source phandle.
+- interrupts:	specifies the interrupt source of the parent interrupt controller.
+		The format of the interrupt specifier depends on the parent interrupt
+		controller.
+- device_type:	must be "pci"
+- #address-cells:	set to <3>
+- #size-cells:	set to <2>
+- #interrupt-cells:	set to <1>
+- ranges:		describes the translation of addresses for root ports and standard
+		PCI regions.
+- interrupt-map-mask and interrupt-map: standard PCI properties to define the
+		mapping of the PCIe interface to interrupt numbers.
+
+Optional properties:
+- msi-parent:	Link to the hardware entity that serves as the MSI controller for this PCIe
+		controller.
+- bus-range:	PCI bus numbers covered
+
+Example
+	pcie_0: pcie at 0xc00000000 {
+		compatible = "altr,pcie-root-port-1.0";
+		reg = <0xc0000000 0x20000000>,
+			<0xff220000 0x00004000>;
+		reg-names = "Txs", "Cra";
+		interrupt-parent = <&hps_0_arm_gic_0>;
+		interrupts = <0 40 4>;
+		interrupt-controller;
+		#interrupt-cells = <1>;
+		bus-range = <0x0 0xFF>;
+		device_type = "pci";
+		msi-parent = <&msi_to_gic_gen_0>;
+		#address-cells = <3>;
+		#size-cells = <2>;
+		interrupt-map-mask = <0 0 0 7>;
+		interrupt-map = <0 0 0 1 &pcie_0 1>,
+			            <0 0 0 2 &pcie_0 2>,
+			            <0 0 0 3 &pcie_0 3>,
+			            <0 0 0 4 &pcie_0 4>;
+		ranges = <0x82000000 0x00000000 0x00000000 0xc0000000 0x00000000 0x10000000
+			    0x82000000 0x00000000 0x10000000 0xd0000000 0x00000000 0x10000000>;
+	};
-- 
1.8.2.1



From lftan at altera.com  Tue Aug 25 02:35:48 2015
From: lftan at altera.com (Ley Foon Tan)
Date: Tue, 25 Aug 2015 17:35:48 +0800
Subject: [PATCH v5 5/5] MAINTAINERS: Add Altera PCIe and MSI drivers maintainer
In-Reply-To: <1440495348-2666-1-git-send-email-lftan@altera.com>
References: <1440495348-2666-1-git-send-email-lftan@altera.com>
Message-ID: <1440495348-2666-6-git-send-email-lftan@altera.com>

Signed-off-by: Ley Foon Tan <lftan at altera.com>
---
 MAINTAINERS | 16 ++++++++++++++++
 1 file changed, 16 insertions(+)

diff --git a/MAINTAINERS b/MAINTAINERS
index 569568f..c87e451 100644
--- a/MAINTAINERS
+++ b/MAINTAINERS
@@ -7779,6 +7779,14 @@ F:	include/linux/pci*
 F:	arch/x86/pci/
 F:	arch/x86/kernel/quirks.c
 
+PCI DRIVER FOR ALTERA PCIE IP
+M:	Ley Foon Tan <lftan at altera.com>
+L:	rfi at lists.rocketboards.org (moderated for non-subscribers)
+L:	linux-pci at vger.kernel.org
+S:	Supported
+F:	Documentation/devicetree/bindings/pci/altera-pcie.txt
+F:	drivers/pci/host/pcie-altera.c
+
 PCI DRIVER FOR ARM VERSATILE PLATFORM
 M:	Rob Herring <robh at kernel.org>
 L:	linux-pci at vger.kernel.org
@@ -7880,6 +7888,14 @@ L:	linux-pci at vger.kernel.org
 S:	Maintained
 F:	drivers/pci/host/*spear*
 
+PCI MSI DRIVER FOR ALTERA MSI IP
+M:	Ley Foon Tan <lftan at altera.com>
+L:	rfi at lists.rocketboards.org (moderated for non-subscribers)
+L:	linux-pci at vger.kernel.org
+S:	Supported
+F:	Documentation/devicetree/bindings/pci/altera-pcie-msi.txt
+F:	drivers/pci/host/pcie-altera-msi.c
+
 PCI MSI DRIVER FOR APPLIEDMICRO XGENE
 M:	Duc Dang <dhdang at apm.com>
 L:	linux-pci at vger.kernel.org
-- 
1.8.2.1



From andre.przywara at arm.com  Tue Aug 25 02:39:45 2015
From: andre.przywara at arm.com (Andre Przywara)
Date: Tue, 25 Aug 2015 10:39:45 +0100
Subject: [PATCH v2 08/15] KVM: arm64: introduce ITS emulation file with
 stub functions
In-Reply-To: <55CC921B.503@linaro.org>
References: <1436538111-4294-1-git-send-email-andre.przywara@arm.com>
 <1436538111-4294-9-git-send-email-andre.przywara@arm.com>
 <55CC921B.503@linaro.org>
Message-ID: <55DC37E1.6060401@arm.com>

Salut Eric,

....

>> diff --git a/virt/kvm/arm/vgic-v3-emul.c b/virt/kvm/arm/vgic-v3-emul.c
>> index 5269ad1..f5865e7 100644
>> --- a/virt/kvm/arm/vgic-v3-emul.c
>> +++ b/virt/kvm/arm/vgic-v3-emul.c
>> @@ -48,6 +48,7 @@
>>  #include <asm/kvm_mmu.h>
>>  
>>  #include "vgic.h"
>> +#include "its-emul.h"
>>  
>>  static bool handle_mmio_rao_wi(struct kvm_vcpu *vcpu,
>>  			       struct kvm_exit_mmio *mmio, phys_addr_t offset)
>> @@ -530,9 +531,20 @@ static bool handle_mmio_ctlr_redist(struct kvm_vcpu *vcpu,
>>  				    struct kvm_exit_mmio *mmio,
>>  				    phys_addr_t offset)
>>  {
>> -	/* since we don't support LPIs, this register is zero for now */
>> -	vgic_reg_access(mmio, NULL, offset,
>> -			ACCESS_READ_RAZ | ACCESS_WRITE_IGNORED);
>> +	struct vgic_dist *dist = &vcpu->kvm->arch.vgic;
>> +	u32 reg;
>> +
>> +	if (!vgic_has_its(vcpu->kvm)) {
>> +		vgic_reg_access(mmio, NULL, offset,
>> +				ACCESS_READ_RAZ | ACCESS_WRITE_IGNORED);
>> +		return false;
>> +	}
> can't we remove above block and ...
>> +	reg = dist->lpis_enabled ? GICR_CTLR_ENABLE_LPIS : 0;
>> +	vgic_reg_access(mmio, &reg, offset,
>> +			ACCESS_READ_VALUE | ACCESS_WRITE_VALUE);
>> +	if (!dist->lpis_enabled && (reg & GICR_CTLR_ENABLE_LPIS
> add vgic_has_its(vcpu->kvm) && above?

Yeah, makes some sense. Changed that.
> 
> Besides Reviewed-by: Eric Auger <eric.auger at linaro.org>

Merci!

Andr?

> 
> Eric
> )) {
>> +		/* Eventually do something */
>> +	}
>>  	return false;
>>  }
>>  
>> @@ -861,6 +873,12 @@ static int vgic_v3_map_resources(struct kvm *kvm,
>>  		rdbase += GIC_V3_REDIST_SIZE;
>>  	}
>>  
>> +	if (vgic_has_its(kvm)) {
>> +		ret = vits_init(kvm);
>> +		if (ret)
>> +			goto out_unregister;
>> +	}
>> +
>>  	dist->redist_iodevs = iodevs;
>>  	dist->ready = true;
>>  	goto out;
>>
> 


From ard.biesheuvel at linaro.org  Tue Aug 25 02:45:01 2015
From: ard.biesheuvel at linaro.org (Ard Biesheuvel)
Date: Tue, 25 Aug 2015 11:45:01 +0200
Subject: [PATCH 0/2] arm64: ignore memory outside of the linear range
In-Reply-To: <CY1PR0301MB07481C5861695902A75CD23D87620@CY1PR0301MB0748.namprd03.prod.outlook.com>
References: <1439890482-20798-1-git-send-email-ard.biesheuvel@linaro.org>
 <CY1PR0301MB0748FC71E6866C8AFACAAFF687780@CY1PR0301MB0748.namprd03.prod.outlook.com>
 <CAKv+Gu-OQ4VyCqe=mEDOrrfAtAWTfRtAiqXMGSVjJxOH6xi4Ow@mail.gmail.com>
 <20150824092256.GA11262@arm.com>
 <CY1PR0301MB0748EAE8103DDF771A37785787620@CY1PR0301MB0748.namprd03.prod.outlook.com>
 <20150824140828.GB20147@arm.com>
 <CY1PR0301MB07481C5861695902A75CD23D87620@CY1PR0301MB0748.namprd03.prod.outlook.com>
Message-ID: <CAKv+Gu-d77ab78WfT8r9YovrNXwFtpq4K9uKmSq5E1jOmRitYw@mail.gmail.com>

On 25 August 2015 at 00:34, Stuart Yoder <stuart.yoder at freescale.com> wrote:
>
>
>> -----Original Message-----
>> From: Will Deacon [mailto:will.deacon at arm.com]
>> Sent: Monday, August 24, 2015 9:08 AM
>> To: Yoder Stuart-B08248
>> Cc: Ard Biesheuvel; linux-arm-kernel at lists.infradead.org; Mark Rutland; Catalin Marinas; robh at kernel.org
>> Subject: Re: [PATCH 0/2] arm64: ignore memory outside of the linear range
>>
>> On Mon, Aug 24, 2015 at 02:58:26PM +0100, Stuart Yoder wrote:
>> > > On Mon, Aug 24, 2015 at 09:00:43AM +0100, Ard Biesheuvel wrote:
>> > > > >> This is a followup to the single patch I posted on Aug 15th to ignore
>> > > > >> RAM that cannot be covered by the linear mapping. Instead of clipping
>> > > > >> the memory after the fact, this clips the memory before installing the
>> > > > >> regions into the memblock memory table.
>> > > > >>
>> > > > >> This is basically the approach that Mark Rutland suggested here
>> > > > >>
>> > > > >> http://article.gmane.org/gmane.linux.ports.arm.kernel/430239
>> > > > >>
>> > > > >> but modified to correctly consider the base of the kernel image as the
>> > > > >> start of the linear mapping.
>> > > > >>
>> > > > >> Ard Biesheuvel (2):
>> > > > >>   of/fdt: make memblock maximum physical address arch configurable
>> > > > >>   arm64: set MAX_MEMBLOCK_ADDR according to linear region size
>> > > > >>
>> > > > >>  arch/arm64/include/asm/memory.h |  8 ++++++++
>> > > > >>  drivers/of/fdt.c                | 12 +++++++-----
>> > > > >>  2 files changed, 15 insertions(+), 5 deletions(-)
>> > > > >
>> > > > > Tested on Freescale LS2085ARDB which has a split memory region
>> > > > > that triggers the bug.
>> > > > >
>> > > > > Tested-by: Stuart Yoder <stuart.yoder at freescale.com>
>> > > > >
>> > > >
>> > > > Will you be picking up this series for v4.3? If so, do you need me to
>> > > > resend it with the tags added?
>> > >
>> > > Sorry, I missed Rob's ack on the of/fdt.c change. I'll pick these up
>> > > later today, no need to resend.
>> >
>> > Are we sending to stable as well?
>>
>> I've already pushed the patch out without a Cc stable (it's not a
>> regression afaict), so if you want it backported then you'll need to send
>> it to stable separately.
>
> Ok, was asking because of Catalin's previous comment:
>
>  > Even though it is not a regression, I think it is a bug fix and it's
>  > worth cc'ing stable (though we could push it after 4.3-rc1).
>

Indeed. Catalin also mentioned that you and he discussed a minimal fix
with a cc to stable, only the fix itself was flawed. So let's not make
this Stuart's problem, considering that this issue breaks all arm64
systems with 32+ GB of RAM if they follow ARM's own recommendation
regarding the physical layout of memory.

> Ard, are you going to send to stable?
>

We'll have to wait until the merge window closes, of course, but yes,
we should propose it.

@Will: what do you think? It would be nice to have you on record with
an opinion rather than leaving it up to Stuart.

-- 
Ard.


From leif.lindholm at linaro.org  Tue Aug 25 02:46:30 2015
From: leif.lindholm at linaro.org (Leif Lindholm)
Date: Tue, 25 Aug 2015 10:46:30 +0100
Subject: [PATCH v1 3/3] arm64: dts: add Hi6220 mailbox node
In-Reply-To: <1440490427.10987.29.camel@linaro.org>
References: <1439977055-1747-1-git-send-email-leo.yan@linaro.org>
 <1439977055-1747-4-git-send-email-leo.yan@linaro.org>
 <20150821184059.GB2000@svinekod>
 <20150824091845.GA28290@leoy-linaro>
 <20150824095144.GA7139@leverpostej>
 <1440411596.3517.12.camel@linaro.org>
 <20150824114903.GT10728@bivouac.eciton.net>
 <1440490427.10987.29.camel@linaro.org>
Message-ID: <20150825094630.GU10728@bivouac.eciton.net>

On Tue, Aug 25, 2015 at 04:13:47PM +0800, Haojian Zhuang wrote:
> On Mon, 2015-08-24 at 12:49 +0100, Leif Lindholm wrote:
> > On Mon, Aug 24, 2015 at 06:19:56PM +0800, Haojian Zhuang wrote:
> > > > If your EFI memory map describes the memory as mappable, it is wrong.
> > > 
> > > When kernel is working, kernel will create its own page table based on
> > > UEFI memory map. Since it's reserved in DTS file as Leo's patch, it'll
> > > be moved to reserved memblock. Why is it wrong?
> > > 
> > > In the second, UEFI is firmware. When it's stable, nobody should change
> > > it without any reason.
> > 
> > Much like the memory map.
> > 
> > > These reserved memory are used in mailbox driver.
> > > Look. It's driver, so it could be changed at any time.
> > 
> > No, it is a set of regions of memory set aside for use by a different
> > master in the system as well as communications with that master.
> > 
> > The fact that there is a driver somewhere that is aware of this is
> > entirely beside the point. All agents in the system must adher to this
> > protocol.
> > 
> > > Why do you want
> > > to UEFI knowing this memory range? Do you hope UEFI to change when
> > > mailbox driver is changed?
> > 
> > Yes.
> > 
> > UEFI is a runtime environment. Having random magic areas not to be
> > touched will cause random pieces of software running under it to break
> > horribly or break other things horribly.
> > Unless you mark them as reserved in the UEFI memory map.
> > At which point the Linux kernel will automatically ignore them, and
> > the proposed patch is redundant.
> > 
> > So, yes, if you want a system that can boot reliably, run testsuites
> > (like SCT or FWTS), run applications (like fastboot ... or the EFI
> > stub kernel itself), then any memory regions that is reserved for
> > mailbox communication (or other masters in the system) _must_ be
> > marked in the EFI memory map.
> 
> 1. We need support both UEFI and uboot. So the reserved buffer have to
> be declared in DTB since they are used by kernel driver, not UEFI.

The buffer may need to be declared in DTB also, but it most certanily
needs to be declared in UEFI.

And for the U-Boot case, since it is not memory available to Linux, it
should not be declared as "memory".

> 2. UEFI just loads grub. It's no time to run any other custom EFI
> application.

Apart from being completely irrelevant, how are you intending to
validate that GRUB never touches these memory regions?

Build a version once, test it, and hope the results remain valid
forever? And then when you move the regions and the previously working
GRUB now tramples all over them? Or when something changes in upstream
GRUB and its memory allocations drifts into the secretly untouchable
regions?

Are you then going to hack GRUB, release a special HiKey version of
GRUB, not support any other versions, and still can your firmware
UEFI?

Repeat again and again for any other UEFI applications - including
fastboot, SCT, FWTS and the UEFI stub kernel.

/
    Leif


From jogo at openwrt.org  Tue Aug 25 02:46:08 2015
From: jogo at openwrt.org (Jonas Gorski)
Date: Tue, 25 Aug 2015 11:46:08 +0200
Subject: [PATCH linux-next v4 5/5] mtd: atmel-quadspi: add driver for
 Atmel QSPI controller
In-Reply-To: <201508241945.33577.marex@denx.de>
References: <cover.1440410236.git.cyrille.pitchen@atmel.com>
 <201508241303.52066.marex@denx.de> <55DB4EA6.9090807@atmel.com>
 <201508241945.33577.marex@denx.de>
Message-ID: <CAOiHx=kExyKAoGW4ciWHHxGNosNR0VdvHHrSqeo7RH1rNOXgig@mail.gmail.com>

On Mon, Aug 24, 2015 at 7:45 PM, Marek Vasut <marex at denx.de> wrote:
> On Monday, August 24, 2015 at 07:04:38 PM, Cyrille Pitchen wrote:
>> Hi Marek,
>
> Hi!
>
>> Le 24/08/2015 13:03, Marek Vasut a ?crit :
>> > On Monday, August 24, 2015 at 12:14:00 PM, Cyrille Pitchen wrote:
>> >> This driver add support to the new Atmel QSPI controller embedded into
>> >> sama5d2x SoCs. It expects a NOR memory to be connected to the QSPI
>> >> controller.
>
> [...]
>
>> >> +  /* Compute address parameters */
>> >> +  switch (cmd->enable.bits.address) {
>> >> +  case 4:
>> >> +          ifr |= QSPI_IFR_ADDRL;
>> >> +          /*break;*/ /* fallback to the 24bit address case */
>> >
>> > What's this commented out bit of code for ? :-)
>>
>> I just wanted to stress out there was no missing "break;".
>> I've reworded the comment to:
>> /* No "break" on purpose: fallback to the 24bit address case. */
>
> Oh, the address is in bytes . I see, yes, it makes sense to be more
> explicit here about the purpose of the fallback. I think this change
> in the comment will make it easier for everyone who comes back in a
> few years and reads this code.

I think you are looking for the term "(switch case) fallthrough", not
"fallback". "Fallback" makes it sound like there is something missing,
or an invalid state.


Jonas


From linux at arm.linux.org.uk  Tue Aug 25 02:54:07 2015
From: linux at arm.linux.org.uk (Russell King - ARM Linux)
Date: Tue, 25 Aug 2015 10:54:07 +0100
Subject: [PATCH 0/2] arm64: ignore memory outside of the linear range
In-Reply-To: <CAKv+Gu-d77ab78WfT8r9YovrNXwFtpq4K9uKmSq5E1jOmRitYw@mail.gmail.com>
References: <1439890482-20798-1-git-send-email-ard.biesheuvel@linaro.org>
 <CY1PR0301MB0748FC71E6866C8AFACAAFF687780@CY1PR0301MB0748.namprd03.prod.outlook.com>
 <CAKv+Gu-OQ4VyCqe=mEDOrrfAtAWTfRtAiqXMGSVjJxOH6xi4Ow@mail.gmail.com>
 <20150824092256.GA11262@arm.com>
 <CY1PR0301MB0748EAE8103DDF771A37785787620@CY1PR0301MB0748.namprd03.prod.outlook.com>
 <20150824140828.GB20147@arm.com>
 <CY1PR0301MB07481C5861695902A75CD23D87620@CY1PR0301MB0748.namprd03.prod.outlook.com>
 <CAKv+Gu-d77ab78WfT8r9YovrNXwFtpq4K9uKmSq5E1jOmRitYw@mail.gmail.com>
Message-ID: <20150825095407.GN7557@n2100.arm.linux.org.uk>

On Tue, Aug 25, 2015 at 11:45:01AM +0200, Ard Biesheuvel wrote:
> On 25 August 2015 at 00:34, Stuart Yoder <stuart.yoder at freescale.com> wrote:
> > Ard, are you going to send to stable?
> >
> 
> We'll have to wait until the merge window closes, of course, but yes,
> we should propose it.

If it's important enough for stable, then it's important enough to go in
at _any_ time, merge window or not.  Fixes are _important_.

https://lwn.net/Articles/608917/

paragraph 3.

-- 
FTTC broadband for 0.8mile line: currently at 10.5Mbps down 400kbps up
according to speedtest.net.


From wangzhou1 at hisilicon.com  Tue Aug 25 02:58:54 2015
From: wangzhou1 at hisilicon.com (Zhou Wang)
Date: Tue, 25 Aug 2015 17:58:54 +0800
Subject: [PATCH v8 6/6] MAINTAINERS: Add pcie-hisi maintainer
In-Reply-To: <1440496734-18417-1-git-send-email-wangzhou1@hisilicon.com>
References: <1440496734-18417-1-git-send-email-wangzhou1@hisilicon.com>
Message-ID: <1440496734-18417-7-git-send-email-wangzhou1@hisilicon.com>

Signed-off-by: Zhou Wang <wangzhou1 at hisilicon.com>
---
 MAINTAINERS | 7 +++++++
 1 file changed, 7 insertions(+)

diff --git a/MAINTAINERS b/MAINTAINERS
index 8133cef..7cd8e47 100644
--- a/MAINTAINERS
+++ b/MAINTAINERS
@@ -7854,6 +7854,13 @@ S:	Maintained
 F:	Documentation/devicetree/bindings/pci/xgene-pci-msi.txt
 F:	drivers/pci/host/pci-xgene-msi.c
 
+PCIE DRIVER FOR HISILICON
+M:	Zhou Wang <wangzhou1 at hisilicon.com>
+L:	linux-pci at vger.kernel.org
+S:	Maintained
+F:	Documentation/devicetree/bindings/pci/hisilicon-pcie.txt
+F:	drivers/pci/host/pcie-hisi.c
+
 PCMCIA SUBSYSTEM
 P:	Linux PCMCIA Team
 L:	linux-pcmcia at lists.infradead.org
-- 
1.9.1



From wangzhou1 at hisilicon.com  Tue Aug 25 02:58:50 2015
From: wangzhou1 at hisilicon.com (Zhou Wang)
Date: Tue, 25 Aug 2015 17:58:50 +0800
Subject: [PATCH v8 2/6] ARM/PCI: remove align_resource in pci_sys_data
In-Reply-To: <1440496734-18417-1-git-send-email-wangzhou1@hisilicon.com>
References: <1440496734-18417-1-git-send-email-wangzhou1@hisilicon.com>
Message-ID: <1440496734-18417-3-git-send-email-wangzhou1@hisilicon.com>

From: gabriele paoloni <gabriele.paoloni at huawei.com>

This patch is needed in order to unify the PCIe designware framework for ARM and
ARM64 architectures. In the PCIe designware unification process we are calling
pci_create_root_bus() passing a "sysdata" parameter that is the same for both
ARM and ARM64 and is of type "struct pcie_port*". In the ARM case this will
cause a problem with the function pcibios_align_resource(); in fact this will
cast "dev->sysdata" to "struct pci_sys_data*", whereas designware had passed a
"struct pcie_port*" pointer.

This patch solves the issue by removing "align_resource" from "pci_sys_data"
struct and defining a static global function pointer in "bios32.c"

Signed-off-by: Gabriele Paoloni <gabriele.paoloni at huawei.com>
Acked-by: Pratyush Anand <pratyush.anand at gmail.com>
---
 arch/arm/include/asm/mach/pci.h |  5 -----
 arch/arm/kernel/bios32.c        | 12 ++++++++----
 2 files changed, 8 insertions(+), 9 deletions(-)

diff --git a/arch/arm/include/asm/mach/pci.h b/arch/arm/include/asm/mach/pci.h
index 28b9bb3..8a4e4de 100644
--- a/arch/arm/include/asm/mach/pci.h
+++ b/arch/arm/include/asm/mach/pci.h
@@ -58,11 +58,6 @@ struct pci_sys_data {
 					/* IRQ mapping				*/
 	int		(*map_irq)(const struct pci_dev *, u8, u8);
 					/* Resource alignement requirements	*/
-	resource_size_t (*align_resource)(struct pci_dev *dev,
-					  const struct resource *res,
-					  resource_size_t start,
-					  resource_size_t size,
-					  resource_size_t align);
 	void		*private_data;	/* platform controller private data	*/
 };
 
diff --git a/arch/arm/kernel/bios32.c b/arch/arm/kernel/bios32.c
index fcbbbb1..4cdc64d 100644
--- a/arch/arm/kernel/bios32.c
+++ b/arch/arm/kernel/bios32.c
@@ -17,6 +17,11 @@
 #include <asm/mach/pci.h>
 
 static int debug_pci;
+static resource_size_t (*align_resource)(struct pci_dev *dev,
+		  const struct resource *res,
+		  resource_size_t start,
+		  resource_size_t size,
+		  resource_size_t align) = NULL;
 
 #ifdef CONFIG_PCI_MSI
 struct msi_controller *pcibios_msi_controller(struct pci_dev *dev)
@@ -468,7 +473,7 @@ static void pcibios_init_hw(struct device *parent, struct hw_pci *hw,
 		sys->busnr   = busnr;
 		sys->swizzle = hw->swizzle;
 		sys->map_irq = hw->map_irq;
-		sys->align_resource = hw->align_resource;
+		align_resource = hw->align_resource;
 		INIT_LIST_HEAD(&sys->resources);
 
 		if (hw->private_data)
@@ -589,7 +594,6 @@ resource_size_t pcibios_align_resource(void *data, const struct resource *res,
 				resource_size_t size, resource_size_t align)
 {
 	struct pci_dev *dev = data;
-	struct pci_sys_data *sys = dev->sysdata;
 	resource_size_t start = res->start;
 
 	if (res->flags & IORESOURCE_IO && start & 0x300)
@@ -597,8 +601,8 @@ resource_size_t pcibios_align_resource(void *data, const struct resource *res,
 
 	start = (start + align - 1) & ~(align - 1);
 
-	if (sys->align_resource)
-		return sys->align_resource(dev, res, start, size, align);
+	if (align_resource)
+		return align_resource(dev, res, start, size, align);
 
 	return start;
 }
-- 
1.9.1



From wangzhou1 at hisilicon.com  Tue Aug 25 02:58:53 2015
From: wangzhou1 at hisilicon.com (Zhou Wang)
Date: Tue, 25 Aug 2015 17:58:53 +0800
Subject: [PATCH v8 5/6] Documentation: DT: Add HiSilicon PCIe host binding
In-Reply-To: <1440496734-18417-1-git-send-email-wangzhou1@hisilicon.com>
References: <1440496734-18417-1-git-send-email-wangzhou1@hisilicon.com>
Message-ID: <1440496734-18417-6-git-send-email-wangzhou1@hisilicon.com>

This patch adds related DTS binding document for HiSilicon PCIe host driver.

Signed-off-by: Zhou Wang <wangzhou1 at hisilicon.com>
---
 .../devicetree/bindings/pci/hisilicon-pcie.txt     | 46 ++++++++++++++++++++++
 1 file changed, 46 insertions(+)
 create mode 100644 Documentation/devicetree/bindings/pci/hisilicon-pcie.txt

diff --git a/Documentation/devicetree/bindings/pci/hisilicon-pcie.txt b/Documentation/devicetree/bindings/pci/hisilicon-pcie.txt
new file mode 100644
index 0000000..2afc9d1
--- /dev/null
+++ b/Documentation/devicetree/bindings/pci/hisilicon-pcie.txt
@@ -0,0 +1,46 @@
+HiSilicon PCIe host bridge DT description
+
+HiSilicon PCIe host controller is based on Designware PCI core.
+It shares common functions with PCIe Designware core driver and inherits
+common properties defined in
+Documentation/devicetree/bindings/pci/designware-pci.txt.
+
+Additional properties are described here:
+
+Required properties:
+- compatible: Should contain "hisilicon,hip05-pcie".
+- reg: Should contain rc_dbi, subctrl, config registers location and length.
+- reg-names: Must include the following entries:
+  "rc_dbi": controller configuration registers;
+  "subctrl": whole PCIe hosts configuration registers;
+  "config": PCIe configuration space registers.
+- msi-parent: Should be its_pcie which is an ITS receiving MSI interrupts.
+- port-id: Should be 0, 1, 2 or 3.
+
+Optional properties:
+- status: Either "ok" or "disabled".
+- dma-coherent: Present if DMA operations are coherent.
+
+Example:
+	pcie at 0xb0080000 {
+		compatible = "hisilicon,hip05-pcie", "snps,dw-pcie";
+		reg = <0 0xb0080000 0 0x10000>, <0 0xb0000000 0 0x10000>,
+		      <0x220 0x00000000 0 0x2000>;
+		reg-names = "rc_dbi", "subctrl", "config";
+		bus-range = <0  15>;
+		msi-parent = <&its_pcie>;
+		#address-cells = <3>;
+		#size-cells = <2>;
+		device_type = "pci";
+		dma-coherent;
+		ranges = <0x82000000 0 0x00000000 0x220 0x00000000 0 0x10000000>;
+		num-lanes = <8>;
+		port-id = <1>;
+		#interrupts-cells = <1>;
+		interrupts-map-mask = <0xf800 0 0 7>;
+		interrupts-map = <0x0 0 0 1 &mbigen_pcie 1 10
+				  0x0 0 0 2 &mbigen_pcie 2 11
+				  0x0 0 0 3 &mbigen_pcie 3 12
+				  0x0 0 0 4 &mbigen_pcie 4 13>;
+		status = "ok";
+	};
-- 
1.9.1



From wangzhou1 at hisilicon.com  Tue Aug 25 02:58:49 2015
From: wangzhou1 at hisilicon.com (Zhou Wang)
Date: Tue, 25 Aug 2015 17:58:49 +0800
Subject: [PATCH v8 1/6] PCI: designware: move calculation of bus addresses to
 DRA7xx
In-Reply-To: <1440496734-18417-1-git-send-email-wangzhou1@hisilicon.com>
References: <1440496734-18417-1-git-send-email-wangzhou1@hisilicon.com>
Message-ID: <1440496734-18417-2-git-send-email-wangzhou1@hisilicon.com>

From: gabriele paoloni <gabriele.paoloni at huawei.com>

Commit f4c55c5a3f7f "PCI: designware: Program ATU with untranslated
address" added the calculation of PCI BUS addresses in designware,
storing them in new fields added in "struct pcie_port". This
calculation is done for every designware user even if is only
applicable to DRA7xx.
This patch moves the calculation of the bus addresses to the DRA7xx
driver and is needed to allow the rework of designware to use
the new DT parsing API.

Signed-off-by: Gabriele Paoloni <gabriele.paoloni at huawei.com>
Signed-off-by: Zhou Wang <wangzhou1 at hisilicon.com>
Acked-by: Pratyush Anand <pratyush.anand at gmail.com>
---
 drivers/pci/host/pci-dra7xx.c      | 13 +++++++++++++
 drivers/pci/host/pcie-designware.c | 15 ++++-----------
 2 files changed, 17 insertions(+), 11 deletions(-)

diff --git a/drivers/pci/host/pci-dra7xx.c b/drivers/pci/host/pci-dra7xx.c
index 80db09e..18ae7ff 100644
--- a/drivers/pci/host/pci-dra7xx.c
+++ b/drivers/pci/host/pci-dra7xx.c
@@ -61,6 +61,7 @@
 
 #define	PCIECTRL_DRA7XX_CONF_PHY_CS			0x010C
 #define	LINK_UP						BIT(16)
+#define	CPU_TO_BUS_ADDR					0x0FFFFFFF
 
 struct dra7xx_pcie {
 	void __iomem		*base;
@@ -139,6 +140,18 @@ static void dra7xx_pcie_enable_interrupts(struct pcie_port *pp)
 static void dra7xx_pcie_host_init(struct pcie_port *pp)
 {
 	dw_pcie_setup_rc(pp);
+
+	if (pp->io_mod_base)
+		pp->io_mod_base &= CPU_TO_BUS_ADDR;
+
+	if (pp->mem_mod_base)
+		pp->mem_mod_base &= CPU_TO_BUS_ADDR;
+
+	if (pp->cfg0_mod_base) {
+		pp->cfg0_mod_base &= CPU_TO_BUS_ADDR;
+		pp->cfg1_mod_base &= CPU_TO_BUS_ADDR;
+	}
+
 	dra7xx_pcie_establish_link(pp);
 	if (IS_ENABLED(CONFIG_PCI_MSI))
 		dw_pcie_msi_init(pp);
diff --git a/drivers/pci/host/pcie-designware.c b/drivers/pci/host/pcie-designware.c
index 69486be..c5d407c 100644
--- a/drivers/pci/host/pcie-designware.c
+++ b/drivers/pci/host/pcie-designware.c
@@ -366,14 +366,10 @@ int dw_pcie_host_init(struct pcie_port *pp)
 	struct of_pci_range range;
 	struct of_pci_range_parser parser;
 	struct resource *cfg_res;
-	u32 val, na, ns;
+	u32 val, ns;
 	const __be32 *addrp;
 	int i, index, ret;
 
-	/* Find the address cell size and the number of cells in order to get
-	 * the untranslated address.
-	 */
-	of_property_read_u32(np, "#address-cells", &na);
 	ns = of_n_size_cells(np);
 
 	cfg_res = platform_get_resource_byname(pdev, IORESOURCE_MEM, "config");
@@ -416,8 +412,7 @@ int dw_pcie_host_init(struct pcie_port *pp)
 			pp->io_base = range.cpu_addr;
 
 			/* Find the untranslated IO space address */
-			pp->io_mod_base = of_read_number(parser.range -
-							 parser.np + na, ns);
+			pp->io_mod_base = range.cpu_addr;
 		}
 		if (restype == IORESOURCE_MEM) {
 			of_pci_range_to_resource(&range, np, &pp->mem);
@@ -426,8 +421,7 @@ int dw_pcie_host_init(struct pcie_port *pp)
 			pp->mem_bus_addr = range.pci_addr;
 
 			/* Find the untranslated MEM space address */
-			pp->mem_mod_base = of_read_number(parser.range -
-							  parser.np + na, ns);
+			pp->mem_mod_base = range.cpu_addr;
 		}
 		if (restype == 0) {
 			of_pci_range_to_resource(&range, np, &pp->cfg);
@@ -437,8 +431,7 @@ int dw_pcie_host_init(struct pcie_port *pp)
 			pp->cfg1_base = pp->cfg.start + pp->cfg0_size;
 
 			/* Find the untranslated configuration space address */
-			pp->cfg0_mod_base = of_read_number(parser.range -
-							   parser.np + na, ns);
+			pp->cfg0_mod_base = range.cpu_addr;
 			pp->cfg1_mod_base = pp->cfg0_mod_base +
 					    pp->cfg0_size;
 		}
-- 
1.9.1



From wangzhou1 at hisilicon.com  Tue Aug 25 02:58:48 2015
From: wangzhou1 at hisilicon.com (Zhou Wang)
Date: Tue, 25 Aug 2015 17:58:48 +0800
Subject: [PATCH v8 0/6] PCI: hisi: Add PCIe host support for HiSilicon SoC
 Hip05
Message-ID: <1440496734-18417-1-git-send-email-wangzhou1@hisilicon.com>

This patchset adds PCIe host support for HiSilicon SoC Hip05. The PCIe hosts
use PCIe IP core from Synopsys, So this driver is base on designware PCIe driver.

Hip05 is an ARMv8 architecture SoC. It should be able to use ARM64 PCIe API in
designeware PCIe driver. So this patch also adds ARM64 support for designware
pcie.

This patchset is based on v4.2-rc1.

Change from v7:
- Remove pp->root_bus_nr = 0 in dra7xx, exynos, imx6, keystone, layerscape,
  spear13xx. Pass pp->busn->start to pci_create_root_bus as root bus number.
- Remove bus-range parsing in pcie-hisi.c.

Change from v6:
- Add Pratyush's Acked-by for 1/6 and 2/6.
- Add James' Tested-by for 3/6.

Change from v5:
- Merge 1/6 in this series, discussion about this can be found in [1]

Change from v4:
- Change the author of 1/5 to Gabriele.
- Modify problems in 3/5 pointed by Bjorn.
- Modify spelling problems in 4/5.

Change from v3:
- Change 1/5 to what Gabriele suggested.
- Use win->__res.start to get *_mod_base in 2/5, this fix a bug in v3 series.

Change from v2:
- Move struct pci_dev *dev and struct pci_sys_data *sys in
  pcibios_align_resource in 1/5.
- Add Gabriele's codes in 2/5 which delete unnecessary information parse and
  use of_pci_get_host_bridge_resources for both ARM32 and ARM64.
- Add maintainer patch 5/5.

Change from RFC v1:
- Add 1/4 patch by Arnd which removes align_resource callback in ARM
  pcibios_align_resource.
- Change head file in pcie-designware from asm/hardirq.h to linux/hardirq.h.
- Set pp->root_bus_nr = 0 in dra7xx, exynos, imx6, keystone, layerscape,
  spear13xx.
- Remove unnecessary parentheses of some macros in pcie-hisi.
- Use macro to replace some magic values.
- Merge two loops together and add some comments about it in context_config
  function in pcie-hisi.
- Modify some value of items in pcie node example in binding document. 

Change from RFC:
- delete dw_pcie_setup, dw_pcie_scan_bus, dw_pcie_map_irq and struct hw_pci,
  merge related operations into dw_pcie_host_init.

Link of v7:
- http://www.spinics.net/lists/devicetree/msg90690.html
Link of v6:
- http://www.spinics.net/lists/linux-pci/msg43669.html
Link of v5:
- http://www.spinics.net/lists/devicetree/msg87959.html
Link of v4:
- http://www.spinics.net/lists/arm-kernel/msg433050.html
Link of v3:
- http://www.spinics.net/lists/linux-pci/msg42539.html
Link of v2:
- http://www.spinics.net/lists/linux-pci/msg41844.html
Link of RFC v1:
- http://www.spinics.net/lists/linux-pci/msg41305.html
Link of RFC:
- http://www.spinics.net/lists/linux-pci/msg40434.html

[1] http://lists.infradead.org/pipermail/linux-arm-kernel/2015-July/359741.html


Zhou Wang (4):
  PCI: designware: Add ARM64 support
  PCI: hisi: Add PCIe host support for HiSilicon SoC Hip05
  Documentation: DT: Add HiSilicon PCIe host binding
  MAINTAINERS: Add pcie-hisi maintainer

gabriele paoloni (2):
  PCI: designware: move calculation of bus addresses to DRA7xx
  ARM/PCI: remove align_resource in pci_sys_data

 .../devicetree/bindings/pci/hisilicon-pcie.txt     |  46 ++++
 MAINTAINERS                                        |   7 +
 arch/arm/include/asm/mach/pci.h                    |   5 -
 arch/arm/kernel/bios32.c                           |  12 +-
 drivers/pci/host/Kconfig                           |   8 +
 drivers/pci/host/Makefile                          |   1 +
 drivers/pci/host/pci-dra7xx.c                      |  13 ++
 drivers/pci/host/pci-keystone-dw.c                 |   2 +-
 drivers/pci/host/pcie-designware.c                 | 237 +++++++-------------
 drivers/pci/host/pcie-designware.h                 |  14 +-
 drivers/pci/host/pcie-hisi.c                       | 247 +++++++++++++++++++++
 11 files changed, 413 insertions(+), 179 deletions(-)
 create mode 100644 Documentation/devicetree/bindings/pci/hisilicon-pcie.txt
 create mode 100644 drivers/pci/host/pcie-hisi.c

-- 
1.9.1



From wangzhou1 at hisilicon.com  Tue Aug 25 02:58:52 2015
From: wangzhou1 at hisilicon.com (Zhou Wang)
Date: Tue, 25 Aug 2015 17:58:52 +0800
Subject: [PATCH v8 4/6] PCI: hisi: Add PCIe host support for HiSilicon SoC
 Hip05
In-Reply-To: <1440496734-18417-1-git-send-email-wangzhou1@hisilicon.com>
References: <1440496734-18417-1-git-send-email-wangzhou1@hisilicon.com>
Message-ID: <1440496734-18417-5-git-send-email-wangzhou1@hisilicon.com>

This patch adds PCIe host support for HiSilicon SoC Hip05.

Signed-off-by: Zhou Wang <wangzhou1 at hisilicon.com>
---
 drivers/pci/host/Kconfig     |   8 ++
 drivers/pci/host/Makefile    |   1 +
 drivers/pci/host/pcie-hisi.c | 247 +++++++++++++++++++++++++++++++++++++++++++
 3 files changed, 256 insertions(+)
 create mode 100644 drivers/pci/host/pcie-hisi.c

diff --git a/drivers/pci/host/Kconfig b/drivers/pci/host/Kconfig
index c132bdd..cd2b80b 100644
--- a/drivers/pci/host/Kconfig
+++ b/drivers/pci/host/Kconfig
@@ -145,4 +145,12 @@ config PCIE_IPROC_BCMA
 	  Say Y here if you want to use the Broadcom iProc PCIe controller
 	  through the BCMA bus interface
 
+config PCI_HISI
+	depends on OF && ARM64
+	bool "HiSilicon SoC HIP05 PCIe controller"
+	select PCIEPORTBUS
+	select PCIE_DW
+	help
+	  Say Y here if you want PCIe controller support on HiSilicon HIP05 SoC
+
 endmenu
diff --git a/drivers/pci/host/Makefile b/drivers/pci/host/Makefile
index 140d66f..ea1dbf2 100644
--- a/drivers/pci/host/Makefile
+++ b/drivers/pci/host/Makefile
@@ -17,3 +17,4 @@ obj-$(CONFIG_PCI_VERSATILE) += pci-versatile.o
 obj-$(CONFIG_PCIE_IPROC) += pcie-iproc.o
 obj-$(CONFIG_PCIE_IPROC_PLATFORM) += pcie-iproc-platform.o
 obj-$(CONFIG_PCIE_IPROC_BCMA) += pcie-iproc-bcma.o
+obj-$(CONFIG_PCI_HISI) += pcie-hisi.o
diff --git a/drivers/pci/host/pcie-hisi.c b/drivers/pci/host/pcie-hisi.c
new file mode 100644
index 0000000..10e8eaa
--- /dev/null
+++ b/drivers/pci/host/pcie-hisi.c
@@ -0,0 +1,247 @@
+/*
+ * PCIe host controller driver for HiSilicon Hip05 SoC
+ *
+ * Copyright (C) 2015 HiSilicon Co., Ltd. http://www.hisilicon.com
+ *
+ * Author: Zhou Wang <wangzhou1 at hisilicon.com>
+ *         Dacai Zhu <zhudacai at hisilicon.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.
+ */
+#include <linux/interrupt.h>
+#include <linux/irqdomain.h>
+#include <linux/module.h>
+#include <linux/of.h>
+#include <linux/of_pci.h>
+#include <linux/platform_device.h>
+
+#include "pcie-designware.h"
+
+#define PCIE_SUBCTRL_MODE_REG                           0x2800
+#define PCIE_SUBCTRL_SYS_STATE4_REG                     0x6818
+#define PCIE_SLV_DBI_MODE                               0x0
+#define PCIE_SLV_SYSCTRL_MODE                           0x1
+#define PCIE_SLV_CONTENT_MODE                           0x2
+#define PCIE_SLV_MSI_ASID                               0x10
+#define PCIE_LTSSM_LINKUP_STATE                         0x11
+#define PCIE_LTSSM_STATE_MASK                           0x3F
+#define PCIE_MSI_ASID_ENABLE                            (0x1 << 12)
+#define PCIE_MSI_ASID_VALUE                             (0x1 << 16)
+#define PCIE_MSI_TRANS_ENABLE                           (0x1 << 12)
+#define PCIE_MSI_TRANS_REG                              0x1c8
+#define PCIE_MSI_LOW_ADDRESS                            0x1b4
+#define PCIE_MSI_HIGH_ADDRESS                           0x1c4
+#define PCIE_MSI_ADDRESS_VAL                            0xb7010040
+
+#define to_hisi_pcie(x)	container_of(x, struct hisi_pcie, pp)
+
+struct hisi_pcie {
+	void __iomem *subctrl_base;
+	void __iomem *reg_base;
+	struct msi_controller *msi;
+	u32 port_id;
+	struct pcie_port pp;
+};
+
+static inline void hisi_pcie_subctrl_writel(struct hisi_pcie *pcie,
+					    u32 val, u32 reg)
+{
+	writel(val, pcie->subctrl_base + reg);
+}
+
+static inline u32 hisi_pcie_subctrl_readl(struct hisi_pcie *pcie, u32 reg)
+{
+	return readl(pcie->subctrl_base + reg);
+}
+
+static inline void hisi_pcie_apb_writel(struct hisi_pcie *pcie,
+					u32 val, u32 reg)
+{
+	writel(val, pcie->reg_base + reg);
+}
+
+static inline u32 hisi_pcie_apb_readl(struct hisi_pcie *pcie, u32 reg)
+{
+	return readl(pcie->reg_base + reg);
+}
+
+/*
+ * Change mode to indicate the same reg_base to base of PCIe host configure
+ * registers, base of RC configure space or base of vmid/asid context table
+ */
+static void hisi_pcie_change_apb_mode(struct hisi_pcie *pcie, u32 mode)
+{
+	u32 val;
+	u32 bit_mask;
+	u32 bit_shift;
+	u32 port_id = pcie->port_id;
+	u32 reg = PCIE_SUBCTRL_MODE_REG + 0x100 * port_id;
+
+	if ((port_id == 1) || (port_id == 2)) {
+		bit_mask = 0xc;
+		bit_shift = 0x2;
+	} else {
+		bit_mask = 0x6;
+		bit_shift = 0x1;
+	}
+
+	val = hisi_pcie_subctrl_readl(pcie, reg);
+	val = (val & (~bit_mask)) | (mode << bit_shift);
+	hisi_pcie_subctrl_writel(pcie, val, reg);
+}
+
+/* Configure vmid/asid table in PCIe host */
+static void hisi_pcie_config_context(struct hisi_pcie *pcie)
+{
+	int i;
+
+	hisi_pcie_change_apb_mode(pcie, PCIE_SLV_CONTENT_MODE);
+
+	/*
+	 * init vmid and asid tables for all PCIe devices as 0
+	 * vmid table: 0 ~ 0x3ff, asid table: 0x400 ~ 0x7ff
+	 */
+	for (i = 0; i < 0x800; i++)
+		hisi_pcie_apb_writel(pcie, 0x0, i * 4);
+
+	hisi_pcie_change_apb_mode(pcie, PCIE_SLV_SYSCTRL_MODE);
+
+	hisi_pcie_apb_writel(pcie, PCIE_MSI_ADDRESS_VAL, PCIE_MSI_LOW_ADDRESS);
+	hisi_pcie_apb_writel(pcie, 0x0, PCIE_MSI_HIGH_ADDRESS);
+	hisi_pcie_apb_writel(pcie, PCIE_MSI_ASID_ENABLE | PCIE_MSI_ASID_VALUE,
+			     PCIE_SLV_MSI_ASID);
+	hisi_pcie_apb_writel(pcie, PCIE_MSI_TRANS_ENABLE, PCIE_MSI_TRANS_REG);
+
+	hisi_pcie_change_apb_mode(pcie, PCIE_SLV_DBI_MODE);
+}
+
+static int hisi_pcie_link_up(struct pcie_port *pp)
+{
+	u32 val;
+	struct hisi_pcie *hisi_pcie = to_hisi_pcie(pp);
+
+	val = hisi_pcie_subctrl_readl(hisi_pcie, PCIE_SUBCTRL_SYS_STATE4_REG +
+				      0x100 * hisi_pcie->port_id);
+
+	return ((val & PCIE_LTSSM_STATE_MASK) == PCIE_LTSSM_LINKUP_STATE);
+}
+
+static
+int hisi_pcie_msi_host_init(struct pcie_port *pp, struct msi_controller *chip)
+{
+	struct device_node *msi_node;
+	struct irq_domain *irq_domain;
+	struct device_node *np = pp->dev->of_node;
+
+	msi_node = of_parse_phandle(np, "msi-parent", 0);
+	if (!msi_node) {
+		dev_err(pp->dev, "failed to find msi-parent\n");
+		return -ENODEV;
+	}
+
+	irq_domain = irq_find_host(msi_node);
+	if (!irq_domain) {
+		dev_err(pp->dev, "failed to find irq domain\n");
+		return -ENODEV;
+	}
+
+	pp->irq_domain = irq_domain;
+
+	return 0;
+}
+
+static struct pcie_host_ops hisi_pcie_host_ops = {
+	.link_up = hisi_pcie_link_up,
+	.msi_host_init = hisi_pcie_msi_host_init,
+};
+
+static int __init hisi_add_pcie_port(struct pcie_port *pp,
+				     struct platform_device *pdev)
+{
+	int ret;
+	u32 port_id;
+	struct resource busn;
+	struct hisi_pcie *hisi_pcie = to_hisi_pcie(pp);
+
+	if (of_property_read_u32(pdev->dev.of_node, "port-id", &port_id)) {
+		dev_err(&pdev->dev, "failed to read port-id\n");
+		return -EINVAL;
+	}
+	if (port_id > 3) {
+		dev_err(&pdev->dev, "Invalid port-id: %d\n", port_id);
+		return -EINVAL;
+	}
+	hisi_pcie->port_id = port_id;
+
+	pp->ops = &hisi_pcie_host_ops;
+
+	hisi_pcie_config_context(hisi_pcie);
+
+	ret = dw_pcie_host_init(pp);
+	if (ret) {
+		dev_err(&pdev->dev, "failed to initialize host\n");
+		return ret;
+	}
+
+	return 0;
+}
+
+static int __init hisi_pcie_probe(struct platform_device *pdev)
+{
+	struct hisi_pcie *hisi_pcie;
+	struct pcie_port *pp;
+	struct resource *reg;
+	struct resource *subctrl;
+	int ret;
+
+	hisi_pcie = devm_kzalloc(&pdev->dev, sizeof(*hisi_pcie), GFP_KERNEL);
+	if (!hisi_pcie)
+		return -ENOMEM;
+
+	pp = &hisi_pcie->pp;
+	pp->dev = &pdev->dev;
+
+	subctrl = platform_get_resource_byname(pdev, IORESOURCE_MEM, "subctrl");
+	hisi_pcie->subctrl_base = devm_ioremap_nocache(&pdev->dev,
+					subctrl->start, resource_size(subctrl));
+	if (IS_ERR(hisi_pcie->subctrl_base)) {
+		dev_err(pp->dev, "cannot get subctrl base\n");
+		return PTR_ERR(hisi_pcie->subctrl_base);
+	}
+
+	reg = platform_get_resource_byname(pdev, IORESOURCE_MEM, "rc_dbi");
+	hisi_pcie->reg_base = devm_ioremap_resource(&pdev->dev, reg);
+	if (IS_ERR(hisi_pcie->reg_base)) {
+		dev_err(pp->dev, "cannot get rc_dbi base\n");
+		return PTR_ERR(hisi_pcie->reg_base);
+	}
+
+	hisi_pcie->pp.dbi_base = hisi_pcie->reg_base;
+
+	ret = hisi_add_pcie_port(pp, pdev);
+	if (ret)
+		return ret;
+
+	platform_set_drvdata(pdev, hisi_pcie);
+
+	return 0;
+}
+
+static const struct of_device_id hisi_pcie_of_match[] = {
+	{.compatible = "hisilicon,hip05-pcie",},
+	{},
+};
+
+MODULE_DEVICE_TABLE(of, hisi_pcie_of_match);
+
+static struct platform_driver hisi_pcie_driver = {
+	.probe  = hisi_pcie_probe,
+	.driver = {
+		   .name = "hisi-pcie",
+		   .of_match_table = hisi_pcie_of_match,
+	},
+};
+
+module_platform_driver(hisi_pcie_driver);
-- 
1.9.1



From wangzhou1 at hisilicon.com  Tue Aug 25 02:58:51 2015
From: wangzhou1 at hisilicon.com (Zhou Wang)
Date: Tue, 25 Aug 2015 17:58:51 +0800
Subject: [PATCH v8 3/6] PCI: designware: Add ARM64 support
In-Reply-To: <1440496734-18417-1-git-send-email-wangzhou1@hisilicon.com>
References: <1440496734-18417-1-git-send-email-wangzhou1@hisilicon.com>
Message-ID: <1440496734-18417-4-git-send-email-wangzhou1@hisilicon.com>

This patch tries to unify ARM32 and ARM64 PCIe in designware driver. Delete
function dw_pcie_setup, dw_pcie_scan_bus, dw_pcie_map_irq and struct hw_pci,
move related operations to dw_pcie_host_init.

This patch also try to use of_pci_get_host_bridge_resources for ARM32 and ARM64
according to the suggestion for Gabriele[1]

Finally this patch reverts commit f4c55c5a3f7f "PCI: designware: Program ATU
with untranslated address" based on 1/6 in this series. we delete *_mod_base in
pcie-designware. This was discussed in [2]

I have compiled the driver with multi_v7_defconfig. However, I don't have
ARM32 PCIe related board to do test. It will be appreciated if someone could
help to test it.

Signed-off-by: Zhou Wang <wangzhou1 at hisilicon.com>
Signed-off-by: Gabriele Paoloni <gabriele.paoloni at huawei.com>
Signed-off-by: Arnd Bergmann <arnd at arndb.de>
Tested-By: James Morse <james.morse at arm.com>

[1] http://www.spinics.net/lists/linux-pci/msg42194.html
[2] http://www.spinics.net/lists/arm-kernel/msg436779.html
---
 drivers/pci/host/pci-dra7xx.c      |  14 +--
 drivers/pci/host/pci-keystone-dw.c |   2 +-
 drivers/pci/host/pcie-designware.c | 230 +++++++++++++------------------------
 drivers/pci/host/pcie-designware.h |  14 +--
 4 files changed, 90 insertions(+), 170 deletions(-)

diff --git a/drivers/pci/host/pci-dra7xx.c b/drivers/pci/host/pci-dra7xx.c
index 18ae7ff..ac401be 100644
--- a/drivers/pci/host/pci-dra7xx.c
+++ b/drivers/pci/host/pci-dra7xx.c
@@ -141,15 +141,15 @@ static void dra7xx_pcie_host_init(struct pcie_port *pp)
 {
 	dw_pcie_setup_rc(pp);
 
-	if (pp->io_mod_base)
-		pp->io_mod_base &= CPU_TO_BUS_ADDR;
+	if (pp->io_base)
+		pp->io_base &= CPU_TO_BUS_ADDR;
 
-	if (pp->mem_mod_base)
-		pp->mem_mod_base &= CPU_TO_BUS_ADDR;
+	if (pp->mem_base)
+		pp->mem_base &= CPU_TO_BUS_ADDR;
 
-	if (pp->cfg0_mod_base) {
-		pp->cfg0_mod_base &= CPU_TO_BUS_ADDR;
-		pp->cfg1_mod_base &= CPU_TO_BUS_ADDR;
+	if (pp->cfg0_base) {
+		pp->cfg0_base &= CPU_TO_BUS_ADDR;
+		pp->cfg1_base &= CPU_TO_BUS_ADDR;
 	}
 
 	dra7xx_pcie_establish_link(pp);
diff --git a/drivers/pci/host/pci-keystone-dw.c b/drivers/pci/host/pci-keystone-dw.c
index f34892e..b1e4135 100644
--- a/drivers/pci/host/pci-keystone-dw.c
+++ b/drivers/pci/host/pci-keystone-dw.c
@@ -327,7 +327,7 @@ static void ks_dw_pcie_clear_dbi_mode(void __iomem *reg_virt)
 void ks_dw_pcie_setup_rc_app_regs(struct keystone_pcie *ks_pcie)
 {
 	struct pcie_port *pp = &ks_pcie->pp;
-	u32 start = pp->mem.start, end = pp->mem.end;
+	u32 start = pp->mem->start, end = pp->mem->end;
 	int i, tr_size;
 
 	/* Disable BARs for inbound access */
diff --git a/drivers/pci/host/pcie-designware.c b/drivers/pci/host/pcie-designware.c
index c5d407c..e2d1898 100644
--- a/drivers/pci/host/pcie-designware.c
+++ b/drivers/pci/host/pcie-designware.c
@@ -11,6 +11,7 @@
  * published by the Free Software Foundation.
  */
 
+#include <linux/hardirq.h>
 #include <linux/irq.h>
 #include <linux/irqdomain.h>
 #include <linux/kernel.h>
@@ -69,16 +70,7 @@
 #define PCIE_ATU_FUNC(x)		(((x) & 0x7) << 16)
 #define PCIE_ATU_UPPER_TARGET		0x91C
 
-static struct hw_pci dw_pci;
-
-static unsigned long global_io_offset;
-
-static inline struct pcie_port *sys_to_pcie(struct pci_sys_data *sys)
-{
-	BUG_ON(!sys->private_data);
-
-	return sys->private_data;
-}
+static struct pci_ops dw_pcie_ops;
 
 int dw_pcie_cfg_read(void __iomem *addr, int where, int size, u32 *val)
 {
@@ -255,7 +247,7 @@ static void dw_pcie_msi_set_irq(struct pcie_port *pp, int irq)
 static int assign_irq(int no_irqs, struct msi_desc *desc, int *pos)
 {
 	int irq, pos0, i;
-	struct pcie_port *pp = sys_to_pcie(desc->dev->bus->sysdata);
+	struct pcie_port *pp = desc->dev->bus->sysdata;
 
 	pos0 = bitmap_find_free_region(pp->msi_irq_in_use, MAX_MSI_IRQS,
 				       order_base_2(no_irqs));
@@ -298,7 +290,7 @@ static int dw_msi_setup_irq(struct msi_controller *chip, struct pci_dev *pdev,
 {
 	int irq, pos;
 	struct msi_msg msg;
-	struct pcie_port *pp = sys_to_pcie(pdev->bus->sysdata);
+	struct pcie_port *pp = pdev->bus->sysdata;
 
 	if (desc->msi_attrib.is_msix)
 		return -EINVAL;
@@ -327,7 +319,7 @@ static void dw_msi_teardown_irq(struct msi_controller *chip, unsigned int irq)
 {
 	struct irq_data *data = irq_get_irq_data(irq);
 	struct msi_desc *msi = irq_data_get_msi(data);
-	struct pcie_port *pp = sys_to_pcie(msi->dev->bus->sysdata);
+	struct pcie_port *pp = msi->dev->bus->sysdata;
 
 	clear_irq_range(pp, irq, 1, data->hwirq);
 }
@@ -363,14 +355,12 @@ int dw_pcie_host_init(struct pcie_port *pp)
 {
 	struct device_node *np = pp->dev->of_node;
 	struct platform_device *pdev = to_platform_device(pp->dev);
-	struct of_pci_range range;
-	struct of_pci_range_parser parser;
+	struct pci_bus *bus;
 	struct resource *cfg_res;
-	u32 val, ns;
-	const __be32 *addrp;
-	int i, index, ret;
-
-	ns = of_n_size_cells(np);
+	LIST_HEAD(res);
+	u32 val;
+	int i, ret;
+	struct resource_entry *win;
 
 	cfg_res = platform_get_resource_byname(pdev, IORESOURCE_MEM, "config");
 	if (cfg_res) {
@@ -378,85 +368,60 @@ int dw_pcie_host_init(struct pcie_port *pp)
 		pp->cfg1_size = resource_size(cfg_res)/2;
 		pp->cfg0_base = cfg_res->start;
 		pp->cfg1_base = cfg_res->start + pp->cfg0_size;
-
-		/* Find the untranslated configuration space address */
-		index = of_property_match_string(np, "reg-names", "config");
-		addrp = of_get_address(np, index, NULL, NULL);
-		pp->cfg0_mod_base = of_read_number(addrp, ns);
-		pp->cfg1_mod_base = pp->cfg0_mod_base + pp->cfg0_size;
 	} else {
 		dev_err(pp->dev, "missing *config* reg space\n");
 	}
 
-	if (of_pci_range_parser_init(&parser, np)) {
-		dev_err(pp->dev, "missing ranges property\n");
-		return -EINVAL;
-	}
+	ret = of_pci_get_host_bridge_resources(np, 0, 0xff, &res, &pp->io_base);
+	if (ret)
+		return ret;
 
 	/* Get the I/O and memory ranges from DT */
-	for_each_of_pci_range(&parser, &range) {
-		unsigned long restype = range.flags & IORESOURCE_TYPE_BITS;
-
-		if (restype == IORESOURCE_IO) {
-			of_pci_range_to_resource(&range, np, &pp->io);
-			pp->io.name = "I/O";
-			pp->io.start = max_t(resource_size_t,
-					     PCIBIOS_MIN_IO,
-					     range.pci_addr + global_io_offset);
-			pp->io.end = min_t(resource_size_t,
-					   IO_SPACE_LIMIT,
-					   range.pci_addr + range.size
-					   + global_io_offset - 1);
-			pp->io_size = resource_size(&pp->io);
-			pp->io_bus_addr = range.pci_addr;
-			pp->io_base = range.cpu_addr;
-
-			/* Find the untranslated IO space address */
-			pp->io_mod_base = range.cpu_addr;
-		}
-		if (restype == IORESOURCE_MEM) {
-			of_pci_range_to_resource(&range, np, &pp->mem);
-			pp->mem.name = "MEM";
-			pp->mem_size = resource_size(&pp->mem);
-			pp->mem_bus_addr = range.pci_addr;
-
-			/* Find the untranslated MEM space address */
-			pp->mem_mod_base = range.cpu_addr;
-		}
-		if (restype == 0) {
-			of_pci_range_to_resource(&range, np, &pp->cfg);
-			pp->cfg0_size = resource_size(&pp->cfg)/2;
-			pp->cfg1_size = resource_size(&pp->cfg)/2;
-			pp->cfg0_base = pp->cfg.start;
-			pp->cfg1_base = pp->cfg.start + pp->cfg0_size;
-
-			/* Find the untranslated configuration space address */
-			pp->cfg0_mod_base = range.cpu_addr;
-			pp->cfg1_mod_base = pp->cfg0_mod_base +
-					    pp->cfg0_size;
+	resource_list_for_each_entry(win, &res) {
+		switch (resource_type(win->res)) {
+		case IORESOURCE_IO:
+			pp->io = win->res;
+			pp->io->name = "I/O";
+			pp->io_size = resource_size(pp->io);
+			pp->io_bus_addr = pp->io->start - win->offset;
+			ret = pci_remap_iospace(pp->io, pp->io_base);
+			if (ret) {
+				dev_warn(pp->dev, "error %d: failed to map resource %pR\n",
+					 ret, pp->io);
+				continue;
+			}
+			break;
+		case IORESOURCE_MEM:
+			pp->mem = win->res;
+			pp->mem->name = "MEM";
+			pp->mem_size = resource_size(pp->mem);
+			pp->mem_bus_addr = pp->mem->start - win->offset;
+			break;
+		case 0:
+			pp->cfg = win->res;
+			pp->cfg0_size = resource_size(pp->cfg)/2;
+			pp->cfg1_size = resource_size(pp->cfg)/2;
+			pp->cfg0_base = pp->cfg->start;
+			pp->cfg1_base = pp->cfg->start + pp->cfg0_size;
+			break;
+		case IORESOURCE_BUS:
+			pp->busn = win->res;
+			break;
+		default:
+			continue;
 		}
 	}
 
-	ret = of_pci_parse_bus_range(np, &pp->busn);
-	if (ret < 0) {
-		pp->busn.name = np->name;
-		pp->busn.start = 0;
-		pp->busn.end = 0xff;
-		pp->busn.flags = IORESOURCE_BUS;
-		dev_dbg(pp->dev, "failed to parse bus-range property: %d, using default %pR\n",
-			ret, &pp->busn);
-	}
-
 	if (!pp->dbi_base) {
-		pp->dbi_base = devm_ioremap(pp->dev, pp->cfg.start,
-					resource_size(&pp->cfg));
+		pp->dbi_base = devm_ioremap(pp->dev, pp->cfg->start,
+					resource_size(pp->cfg));
 		if (!pp->dbi_base) {
 			dev_err(pp->dev, "error with ioremap\n");
 			return -ENOMEM;
 		}
 	}
 
-	pp->mem_base = pp->mem.start;
+	pp->mem_base = pp->mem->start;
 
 	if (!pp->va_cfg0_base) {
 		pp->va_cfg0_base = devm_ioremap(pp->dev, pp->cfg0_base,
@@ -505,7 +470,7 @@ int dw_pcie_host_init(struct pcie_port *pp)
 
 	if (!pp->ops->rd_other_conf)
 		dw_pcie_prog_outbound_atu(pp, PCIE_ATU_REGION_INDEX1,
-					  PCIE_ATU_TYPE_MEM, pp->mem_mod_base,
+					  PCIE_ATU_TYPE_MEM, pp->mem_base,
 					  pp->mem_bus_addr, pp->mem_size);
 
 	dw_pcie_wr_own_conf(pp, PCI_BASE_ADDRESS_0, 4, 0);
@@ -517,15 +482,30 @@ int dw_pcie_host_init(struct pcie_port *pp)
 	val |= PORT_LOGIC_SPEED_CHANGE;
 	dw_pcie_wr_own_conf(pp, PCIE_LINK_WIDTH_SPEED_CONTROL, 4, val);
 
-#ifdef CONFIG_PCI_MSI
+	pp->root_bus_nr = pp->busn->start;
+	bus = pci_create_root_bus(pp->dev, pp->root_bus_nr, &dw_pcie_ops,
+				  pp, &res);
+	if (!bus)
+		return -ENOMEM;
+
+#ifdef CONFIG_GENERIC_MSI_IRQ_DOMAIN
+	bus->msi = container_of(&pp->irq_domain, struct msi_controller, domain);
+#else
 	dw_pcie_msi_chip.dev = pp->dev;
-	dw_pci.msi_ctrl = &dw_pcie_msi_chip;
+	bus->msi = &dw_pcie_msi_chip;
 #endif
 
-	dw_pci.nr_controllers = 1;
-	dw_pci.private_data = (void **)&pp;
+	pci_scan_child_bus(bus);
+	if (pp->ops->scan_bus)
+		pp->ops->scan_bus(pp);
+
+#ifdef CONFIG_ARM
+	/* support old dtbs that incorrectly describe IRQs */
+	pci_fixup_irqs(pci_common_swizzle, of_irq_parse_and_map_pci);
+#endif
 
-	pci_common_init_dev(pp->dev, &dw_pci);
+	pci_assign_unassigned_bus_resources(bus);
+	pci_bus_add_devices(bus);
 
 	return 0;
 }
@@ -544,12 +524,12 @@ static int dw_pcie_rd_other_conf(struct pcie_port *pp, struct pci_bus *bus,
 
 	if (bus->parent->number == pp->root_bus_nr) {
 		type = PCIE_ATU_TYPE_CFG0;
-		cpu_addr = pp->cfg0_mod_base;
+		cpu_addr = pp->cfg0_base;
 		cfg_size = pp->cfg0_size;
 		va_cfg_base = pp->va_cfg0_base;
 	} else {
 		type = PCIE_ATU_TYPE_CFG1;
-		cpu_addr = pp->cfg1_mod_base;
+		cpu_addr = pp->cfg1_base;
 		cfg_size = pp->cfg1_size;
 		va_cfg_base = pp->va_cfg1_base;
 	}
@@ -559,7 +539,7 @@ static int dw_pcie_rd_other_conf(struct pcie_port *pp, struct pci_bus *bus,
 				  busdev, cfg_size);
 	ret = dw_pcie_cfg_read(va_cfg_base + address, where, size, val);
 	dw_pcie_prog_outbound_atu(pp, PCIE_ATU_REGION_INDEX0,
-				  PCIE_ATU_TYPE_IO, pp->io_mod_base,
+				  PCIE_ATU_TYPE_IO, pp->io_base,
 				  pp->io_bus_addr, pp->io_size);
 
 	return ret;
@@ -579,12 +559,12 @@ static int dw_pcie_wr_other_conf(struct pcie_port *pp, struct pci_bus *bus,
 
 	if (bus->parent->number == pp->root_bus_nr) {
 		type = PCIE_ATU_TYPE_CFG0;
-		cpu_addr = pp->cfg0_mod_base;
+		cpu_addr = pp->cfg0_base;
 		cfg_size = pp->cfg0_size;
 		va_cfg_base = pp->va_cfg0_base;
 	} else {
 		type = PCIE_ATU_TYPE_CFG1;
-		cpu_addr = pp->cfg1_mod_base;
+		cpu_addr = pp->cfg1_base;
 		cfg_size = pp->cfg1_size;
 		va_cfg_base = pp->va_cfg1_base;
 	}
@@ -594,7 +574,7 @@ static int dw_pcie_wr_other_conf(struct pcie_port *pp, struct pci_bus *bus,
 				  busdev, cfg_size);
 	ret = dw_pcie_cfg_write(va_cfg_base + address, where, size, val);
 	dw_pcie_prog_outbound_atu(pp, PCIE_ATU_REGION_INDEX0,
-				  PCIE_ATU_TYPE_IO, pp->io_mod_base,
+				  PCIE_ATU_TYPE_IO, pp->io_base,
 				  pp->io_bus_addr, pp->io_size);
 
 	return ret;
@@ -626,7 +606,7 @@ static int dw_pcie_valid_config(struct pcie_port *pp,
 static int dw_pcie_rd_conf(struct pci_bus *bus, u32 devfn, int where,
 			int size, u32 *val)
 {
-	struct pcie_port *pp = sys_to_pcie(bus->sysdata);
+	struct pcie_port *pp = bus->sysdata;
 	int ret;
 
 	if (dw_pcie_valid_config(pp, bus, PCI_SLOT(devfn)) == 0) {
@@ -650,7 +630,7 @@ static int dw_pcie_rd_conf(struct pci_bus *bus, u32 devfn, int where,
 static int dw_pcie_wr_conf(struct pci_bus *bus, u32 devfn,
 			int where, int size, u32 val)
 {
-	struct pcie_port *pp = sys_to_pcie(bus->sysdata);
+	struct pcie_port *pp = bus->sysdata;
 	int ret;
 
 	if (dw_pcie_valid_config(pp, bus, PCI_SLOT(devfn)) == 0)
@@ -674,62 +654,6 @@ static struct pci_ops dw_pcie_ops = {
 	.write = dw_pcie_wr_conf,
 };
 
-static int dw_pcie_setup(int nr, struct pci_sys_data *sys)
-{
-	struct pcie_port *pp;
-
-	pp = sys_to_pcie(sys);
-
-	if (global_io_offset < SZ_1M && pp->io_size > 0) {
-		sys->io_offset = global_io_offset - pp->io_bus_addr;
-		pci_ioremap_io(global_io_offset, pp->io_base);
-		global_io_offset += SZ_64K;
-		pci_add_resource_offset(&sys->resources, &pp->io,
-					sys->io_offset);
-	}
-
-	sys->mem_offset = pp->mem.start - pp->mem_bus_addr;
-	pci_add_resource_offset(&sys->resources, &pp->mem, sys->mem_offset);
-	pci_add_resource(&sys->resources, &pp->busn);
-
-	return 1;
-}
-
-static struct pci_bus *dw_pcie_scan_bus(int nr, struct pci_sys_data *sys)
-{
-	struct pci_bus *bus;
-	struct pcie_port *pp = sys_to_pcie(sys);
-
-	pp->root_bus_nr = sys->busnr;
-	bus = pci_scan_root_bus(pp->dev, sys->busnr,
-				  &dw_pcie_ops, sys, &sys->resources);
-	if (!bus)
-		return NULL;
-
-	if (bus && pp->ops->scan_bus)
-		pp->ops->scan_bus(pp);
-
-	return bus;
-}
-
-static int dw_pcie_map_irq(const struct pci_dev *dev, u8 slot, u8 pin)
-{
-	struct pcie_port *pp = sys_to_pcie(dev->bus->sysdata);
-	int irq;
-
-	irq = of_irq_parse_and_map_pci(dev, slot, pin);
-	if (!irq)
-		irq = pp->irq;
-
-	return irq;
-}
-
-static struct hw_pci dw_pci = {
-	.setup		= dw_pcie_setup,
-	.scan		= dw_pcie_scan_bus,
-	.map_irq	= dw_pcie_map_irq,
-};
-
 void dw_pcie_setup_rc(struct pcie_port *pp)
 {
 	u32 val;
diff --git a/drivers/pci/host/pcie-designware.h b/drivers/pci/host/pcie-designware.h
index d0bbd27..264c969 100644
--- a/drivers/pci/host/pcie-designware.h
+++ b/drivers/pci/host/pcie-designware.h
@@ -27,25 +27,21 @@ struct pcie_port {
 	u8			root_bus_nr;
 	void __iomem		*dbi_base;
 	u64			cfg0_base;
-	u64			cfg0_mod_base;
 	void __iomem		*va_cfg0_base;
 	u32			cfg0_size;
 	u64			cfg1_base;
-	u64			cfg1_mod_base;
 	void __iomem		*va_cfg1_base;
 	u32			cfg1_size;
-	u64			io_base;
-	u64			io_mod_base;
+	resource_size_t		io_base;
 	phys_addr_t		io_bus_addr;
 	u32			io_size;
 	u64			mem_base;
-	u64			mem_mod_base;
 	phys_addr_t		mem_bus_addr;
 	u32			mem_size;
-	struct resource		cfg;
-	struct resource		io;
-	struct resource		mem;
-	struct resource		busn;
+	struct resource		*cfg;
+	struct resource		*io;
+	struct resource		*mem;
+	struct resource		*busn;
 	int			irq;
 	u32			lanes;
 	struct pcie_host_ops	*ops;
-- 
1.9.1



From treding at nvidia.com  Tue Aug 25 02:58:19 2015
From: treding at nvidia.com (Thierry Reding)
Date: Tue, 25 Aug 2015 11:58:19 +0200
Subject: [PATCH v3 06/14] Documentation: drm/bridge: add document for
 analogix_dp
In-Reply-To: <1439995834-18363-1-git-send-email-ykk@rock-chips.com>
References: <1439995728-18046-1-git-send-email-ykk@rock-chips.com>
 <1439995834-18363-1-git-send-email-ykk@rock-chips.com>
Message-ID: <20150825095817.GC14034@ulmo.nvidia.com>

On Wed, Aug 19, 2015 at 09:50:34AM -0500, Yakir Yang wrote:
[...]
> +	-analogix,color-space:
> +		input video data format.
> +			COLOR_RGB = 0, COLOR_YCBCR422 = 1, COLOR_YCBCR444 = 2

I don't think DT is an appropriate place to set this. To my knowledge
this depends on the display and/or mode, so I don't think hard-coding
it here is the right thing to do.

Thierry
-------------- next part --------------
A non-text attachment was scrubbed...
Name: signature.asc
Type: application/pgp-signature
Size: 819 bytes
Desc: not available
URL: <http://lists.infradead.org/pipermail/linux-arm-kernel/attachments/20150825/185a923a/attachment-0001.sig>

From will.deacon at arm.com  Tue Aug 25 03:02:54 2015
From: will.deacon at arm.com (Will Deacon)
Date: Tue, 25 Aug 2015 11:02:54 +0100
Subject: [PATCH 0/2] arm64: ignore memory outside of the linear range
In-Reply-To: <CAKv+Gu-d77ab78WfT8r9YovrNXwFtpq4K9uKmSq5E1jOmRitYw@mail.gmail.com>
References: <1439890482-20798-1-git-send-email-ard.biesheuvel@linaro.org>
 <CY1PR0301MB0748FC71E6866C8AFACAAFF687780@CY1PR0301MB0748.namprd03.prod.outlook.com>
 <CAKv+Gu-OQ4VyCqe=mEDOrrfAtAWTfRtAiqXMGSVjJxOH6xi4Ow@mail.gmail.com>
 <20150824092256.GA11262@arm.com>
 <CY1PR0301MB0748EAE8103DDF771A37785787620@CY1PR0301MB0748.namprd03.prod.outlook.com>
 <20150824140828.GB20147@arm.com>
 <CY1PR0301MB07481C5861695902A75CD23D87620@CY1PR0301MB0748.namprd03.prod.outlook.com>
 <CAKv+Gu-d77ab78WfT8r9YovrNXwFtpq4K9uKmSq5E1jOmRitYw@mail.gmail.com>
Message-ID: <20150825100254.GB21300@arm.com>

On Tue, Aug 25, 2015 at 10:45:01AM +0100, Ard Biesheuvel wrote:
> On 25 August 2015 at 00:34, Stuart Yoder <stuart.yoder at freescale.com> wrote:
> >> On Mon, Aug 24, 2015 at 02:58:26PM +0100, Stuart Yoder wrote:
> >> > Are we sending to stable as well?
> >>
> >> I've already pushed the patch out without a Cc stable (it's not a
> >> regression afaict), so if you want it backported then you'll need to send
> >> it to stable separately.
> >
> > Ok, was asking because of Catalin's previous comment:
> >
> >  > Even though it is not a regression, I think it is a bug fix and it's
> >  > worth cc'ing stable (though we could push it after 4.3-rc1).
> >
> 
> Indeed. Catalin also mentioned that you and he discussed a minimal fix
> with a cc to stable, only the fix itself was flawed. So let's not make
> this Stuart's problem, considering that this issue breaks all arm64
> systems with 32+ GB of RAM if they follow ARM's own recommendation
> regarding the physical layout of memory.
> 
> > Ard, are you going to send to stable?
> >
> 
> We'll have to wait until the merge window closes, of course, but yes,
> we should propose it.
> 
> @Will: what do you think? It would be nice to have you on record with
> an opinion rather than leaving it up to Stuart.

This isn't something that has *ever* worked with the arm64 kernel,
right? In which case, it's not a regression, it's more like adding
support for some systems that we've not supported before. Now, given the
nature of the patch, I'm not against stable, but by the time Stuart
pointed that out, I'd already pushed the patch and I don't want to
rebase our 4.3 queue at this stage.

The best bet is to send this to stable once it's in mainline (i.e. -rc1)
and I think it makes sense for Stuart to do that, since he is the one
most interested in having that happen.

Will


From treding at nvidia.com  Tue Aug 25 03:06:30 2015
From: treding at nvidia.com (Thierry Reding)
Date: Tue, 25 Aug 2015 12:06:30 +0200
Subject: [PATCH v3 06/14] Documentation: drm/bridge: add document for
 analogix_dp
In-Reply-To: <55DC383F.4000103@rock-chips.com>
References: <1439995728-18046-1-git-send-email-ykk@rock-chips.com>
 <1439995834-18363-1-git-send-email-ykk@rock-chips.com>
 <CAL_JsqLz+8RtBucctUj4euXZ3Ac0DvB52N9ONpAerh5T9BiTJg@mail.gmail.com>
 <20150824125758.GA7557@n2100.arm.linux.org.uk>
 <CAL_JsqKZYMMzV9Sc2r3K_rnM0FNuyb1TyJEhjGq1Hf7dTiWFKQ@mail.gmail.com>
 <20150825091246.GA14034@ulmo.nvidia.com>
 <55DC383F.4000103@rock-chips.com>
Message-ID: <20150825100628.GD14034@ulmo.nvidia.com>

On Tue, Aug 25, 2015 at 05:41:19PM +0800, Yakir Yang wrote:
> Hi Thierry,
> 
> ? 2015/8/25 17:12, Thierry Reding ??:
> >On Mon, Aug 24, 2015 at 09:48:27AM -0500, Rob Herring wrote:
> >>On Mon, Aug 24, 2015 at 7:57 AM, Russell King - ARM Linux
> >><linux at arm.linux.org.uk> wrote:
> >>>On Sun, Aug 23, 2015 at 06:23:14PM -0500, Rob Herring wrote:
> >>>>On Wed, Aug 19, 2015 at 9:50 AM, Yakir Yang <ykk at rock-chips.com> wrote:
> >>>>>+       -analogix,color-depth:
> >>>>>+               number of bits per colour component.
> >>>>>+                       COLOR_6 = 0, COLOR_8 = 1, COLOR_10 = 2, COLOR_12 = 3
> >>>>This seems pretty generic. Just use 6, 8, 10, or 12 for values. And
> >>>>drop the vendor prefix.
> >>>Please think about this some more.  What does "color-depth" mean?  Does it
> >>>mean the number of bits per colour _component_, or does it mean the total
> >>>number of bits to represent a particular colour.  It's confusing as it
> >>>stands.
> >>Then "component-color-bpp" perhaps?
> >There should be no need to have this in DT at all. The BPC is a property
> >of the attached panel and it should come from the panel (either the
> >panel driver or parsed from EDID if available).
> 
> Actually I have send an email about this one to you in version 2, just past
> from that email:
> 
> "samsung,color_space" and "samsung,color-depth"
> 
> The drm_display_info's color_formats and bpc indicate the monitor display
> ability, but
> the edp driver could not take it as input video format directly.
> 
> For example, with my DP TV I would found "RGB444 & YCRCB422 & & YCRCB444"
> support in drm_display_info.color_formats and 16bit bpc support, but RK3288
> crtc
> driver could only output RGB & ITU formats, so finally analogix_dp-rockchip
> driver
> config crtc to RGBaaa 10bpc mode.
> 
> In this sutiation, the analogix_dp core driver would pazzled by the
> drm_display_info,
> can't chose the right color_space and bpc.
> 
> And this is the place that confused me, wish you could give some ideas about
> this one :-)

Your display driver should choose whatever it is capable of outputting.
If the display reports that it can do 16 bits-per-color, but your
display driver can't do it, then it should choose a configuration that
it supports. Similarily for the color encodings. If you can't generate
YCrCb444 with your hardware, then it's the driver's job to know about
that and select the next appropriate configuration.

But hard-coding this is not the right solution because the value in DT
may end up conflicting with what the display reports.

Thierry
-------------- next part --------------
A non-text attachment was scrubbed...
Name: signature.asc
Type: application/pgp-signature
Size: 819 bytes
Desc: not available
URL: <http://lists.infradead.org/pipermail/linux-arm-kernel/attachments/20150825/6976039d/attachment.sig>

From ard.biesheuvel at linaro.org  Tue Aug 25 03:10:58 2015
From: ard.biesheuvel at linaro.org (Ard Biesheuvel)
Date: Tue, 25 Aug 2015 12:10:58 +0200
Subject: [PATCH 0/2] arm64: ignore memory outside of the linear range
In-Reply-To: <20150825100254.GB21300@arm.com>
References: <1439890482-20798-1-git-send-email-ard.biesheuvel@linaro.org>
 <CY1PR0301MB0748FC71E6866C8AFACAAFF687780@CY1PR0301MB0748.namprd03.prod.outlook.com>
 <CAKv+Gu-OQ4VyCqe=mEDOrrfAtAWTfRtAiqXMGSVjJxOH6xi4Ow@mail.gmail.com>
 <20150824092256.GA11262@arm.com>
 <CY1PR0301MB0748EAE8103DDF771A37785787620@CY1PR0301MB0748.namprd03.prod.outlook.com>
 <20150824140828.GB20147@arm.com>
 <CY1PR0301MB07481C5861695902A75CD23D87620@CY1PR0301MB0748.namprd03.prod.outlook.com>
 <CAKv+Gu-d77ab78WfT8r9YovrNXwFtpq4K9uKmSq5E1jOmRitYw@mail.gmail.com>
 <20150825100254.GB21300@arm.com>
Message-ID: <CAKv+Gu8pAm99fm8vE40+ugboCr93ioMP17RpfKf35W8+m7TrCA@mail.gmail.com>

On 25 August 2015 at 12:02, Will Deacon <will.deacon at arm.com> wrote:
> On Tue, Aug 25, 2015 at 10:45:01AM +0100, Ard Biesheuvel wrote:
>> On 25 August 2015 at 00:34, Stuart Yoder <stuart.yoder at freescale.com> wrote:
>> >> On Mon, Aug 24, 2015 at 02:58:26PM +0100, Stuart Yoder wrote:
>> >> > Are we sending to stable as well?
>> >>
>> >> I've already pushed the patch out without a Cc stable (it's not a
>> >> regression afaict), so if you want it backported then you'll need to send
>> >> it to stable separately.
>> >
>> > Ok, was asking because of Catalin's previous comment:
>> >
>> >  > Even though it is not a regression, I think it is a bug fix and it's
>> >  > worth cc'ing stable (though we could push it after 4.3-rc1).
>> >
>>
>> Indeed. Catalin also mentioned that you and he discussed a minimal fix
>> with a cc to stable, only the fix itself was flawed. So let's not make
>> this Stuart's problem, considering that this issue breaks all arm64
>> systems with 32+ GB of RAM if they follow ARM's own recommendation
>> regarding the physical layout of memory.
>>
>> > Ard, are you going to send to stable?
>> >
>>
>> We'll have to wait until the merge window closes, of course, but yes,
>> we should propose it.
>>
>> @Will: what do you think? It would be nice to have you on record with
>> an opinion rather than leaving it up to Stuart.
>
> This isn't something that has *ever* worked with the arm64 kernel,
> right? In which case, it's not a regression, it's more like adding
> support for some systems that we've not supported before.

I am somewhat on the fence on this one, to be honest. The bug has
always existed but since DRAM is upgradeable, it may affect systems
that we do support and are working fine currently.

> Now, given the
> nature of the patch, I'm not against stable, but by the time Stuart
> pointed that out, I'd already pushed the patch and I don't want to
> rebase our 4.3 queue at this stage.
>

Noted. I just wanted to understand whether you had left it out on purpose.

> The best bet is to send this to stable once it's in mainline (i.e. -rc1)
> and I think it makes sense for Stuart to do that, since he is the one
> most interested in having that happen.
>

Indeed. I take Russell's point about fixes being important, but in
this case, I think it can wait until after the merge window.

-- 
Ard.


From haojian.zhuang at linaro.org  Tue Aug 25 03:15:10 2015
From: haojian.zhuang at linaro.org (Haojian Zhuang)
Date: Tue, 25 Aug 2015 18:15:10 +0800
Subject: [PATCH v1 3/3] arm64: dts: add Hi6220 mailbox node
In-Reply-To: <20150825094630.GU10728@bivouac.eciton.net>
References: <1439977055-1747-1-git-send-email-leo.yan@linaro.org>
 <1439977055-1747-4-git-send-email-leo.yan@linaro.org>
 <20150821184059.GB2000@svinekod> <20150824091845.GA28290@leoy-linaro>
 <20150824095144.GA7139@leverpostej> <1440411596.3517.12.camel@linaro.org>
 <20150824114903.GT10728@bivouac.eciton.net>
 <1440490427.10987.29.camel@linaro.org>
 <20150825094630.GU10728@bivouac.eciton.net>
Message-ID: <1440497710.10987.42.camel@linaro.org>

On Tue, 2015-08-25 at 10:46 +0100, Leif Lindholm wrote:
> On Tue, Aug 25, 2015 at 04:13:47PM +0800, Haojian Zhuang wrote:
> > On Mon, 2015-08-24 at 12:49 +0100, Leif Lindholm wrote:
> > > On Mon, Aug 24, 2015 at 06:19:56PM +0800, Haojian Zhuang wrote:
> > > > > If your EFI memory map describes the memory as mappable, it is wrong.
> > > > 
> > > > When kernel is working, kernel will create its own page table based on
> > > > UEFI memory map. Since it's reserved in DTS file as Leo's patch, it'll
> > > > be moved to reserved memblock. Why is it wrong?
> > > > 
> > > > In the second, UEFI is firmware. When it's stable, nobody should change
> > > > it without any reason.
> > > 
> > > Much like the memory map.
> > > 
> > > > These reserved memory are used in mailbox driver.
> > > > Look. It's driver, so it could be changed at any time.
> > > 
> > > No, it is a set of regions of memory set aside for use by a different
> > > master in the system as well as communications with that master.
> > > 
> > > The fact that there is a driver somewhere that is aware of this is
> > > entirely beside the point. All agents in the system must adher to this
> > > protocol.
> > > 
> > > > Why do you want
> > > > to UEFI knowing this memory range? Do you hope UEFI to change when
> > > > mailbox driver is changed?
> > > 
> > > Yes.
> > > 
> > > UEFI is a runtime environment. Having random magic areas not to be
> > > touched will cause random pieces of software running under it to break
> > > horribly or break other things horribly.
> > > Unless you mark them as reserved in the UEFI memory map.
> > > At which point the Linux kernel will automatically ignore them, and
> > > the proposed patch is redundant.
> > > 
> > > So, yes, if you want a system that can boot reliably, run testsuites
> > > (like SCT or FWTS), run applications (like fastboot ... or the EFI
> > > stub kernel itself), then any memory regions that is reserved for
> > > mailbox communication (or other masters in the system) _must_ be
> > > marked in the EFI memory map.
> > 
> > 1. We need support both UEFI and uboot. So the reserved buffer have to
> > be declared in DTB since they are used by kernel driver, not UEFI.
> 
> The buffer may need to be declared in DTB also, but it most certanily
> needs to be declared in UEFI.
> 
> And for the U-Boot case, since it is not memory available to Linux, it
> should not be declared as "memory".

Something are messed at here. We have these buffer are used in mailbox.
They should be allocated as non-cacheable.

If these buffers are contained in memory memblock in kernel, it means
that they exist in kernel page table with cachable property. When it's
used in mailbox driver with non-cachable property, it'll only cause
cache maintenance issue. So Leo declared these buffers as reserved
in DT with "no-map" property. It's the key. It could avoid the cache
maintenance issue.

> 
> > 2. UEFI just loads grub. It's no time to run any other custom EFI
> > application.
> 
> Apart from being completely irrelevant, how are you intending to
> validate that GRUB never touches these memory regions?
> 

GRUB is just a part of bootloader. When linux kernel is running,
who cares GRUB? GRUB's lifetime is already finished.

By the way, UEFI code region is at [0x3Dxx_xxxx, 0x3DFF_FFFF]. Those
mailbox buffer is in [0x05e0_xxxx, 0x06f0_xxxx]. Then I can make sure
UEFI won't touch the reserved buffer. Even if UEFI touched the reserved
buffer, is it an issue? Definitely it's not. UEFI's lifetime is end
when linux kernel is running at hikey. Even if UEFI runtime service
is enabled, the runtime data area is at [0x38xx_xxxx, 0x38xx_xxxx].

> Build a version once, test it, and hope the results remain valid
> forever? And then when you move the regions and the previously working
> GRUB now tramples all over them? Or when something changes in upstream
> GRUB and its memory allocations drifts into the secretly untouchable
> regions?

As I said above, UEFI won't touch it. And even UEFI touch it, kernel
doesn't care since UEFI's lifetime is end.

> 
> Are you then going to hack GRUB, release a special HiKey version of
> GRUB, not support any other versions, and still can your firmware
> UEFI?

I don't need to hack GRUB at all.



From cyrille.pitchen at atmel.com  Tue Aug 25 03:17:37 2015
From: cyrille.pitchen at atmel.com (Cyrille Pitchen)
Date: Tue, 25 Aug 2015 12:17:37 +0200
Subject: [PATCH linux-next v4 5/5] mtd: atmel-quadspi: add driver for
 Atmel QSPI controller
In-Reply-To: <201508241303.52066.marex@denx.de>
References: <cover.1440410236.git.cyrille.pitchen@atmel.com>
 <bf368fc101f38db231131b69eff0863210f2b01c.1440410236.git.cyrille.pitchen@atmel.com>
 <201508241303.52066.marex@denx.de>
Message-ID: <55DC40C1.3050405@atmel.com>

Hi Marek,

Le 24/08/2015 13:03, Marek Vasut a ?crit :
> On Monday, August 24, 2015 at 12:14:00 PM, Cyrille Pitchen wrote:
>> This driver add support to the new Atmel QSPI controller embedded into
>> sama5d2x SoCs. It expects a NOR memory to be connected to the QSPI
>> controller.
>>
>> Signed-off-by: Cyrille Pitchen <cyrille.pitchen at atmel.com>
>> Acked-by: Nicolas Ferre <nicolas.ferre at atmel.com>
> 
> Hi,
> 
> [...]
> 
>> +/* Register access macros */
> 
> These are functions, not macros :)
> 
> btw is there any reason for these ? I'd say, just put the read*() and
> write*() functions directly into the code and be done with it, it is
> much less confusing.

If you don't mind, I'd rather keep some of these inline functions. I have
no strong justification, it's more a personal taste: it makes lines
shorter as it avoids the need to add "->regs + ".
Also it makes the code consistent with other Atmel drivers which already
use such wrappers.

However I'll fix the comment and remove the byte and word versions, which
are not used. So only qspi_readl() and qspi_writel() are left.

Does it sound good to you?

> 
> Also, why do you use the _relaxed() versions of the functions ?
> 
>> +static inline u32 qspi_readl(struct atmel_qspi *aq, u32 reg)
>> +{
>> +	return readl_relaxed(aq->regs + reg);
>> +}
>> +
>> +static inline void qspi_writel(struct atmel_qspi *aq, u32 reg, u32 value)
>> +{
>> +	writel_relaxed(value, aq->regs + reg);
>> +}
>> +
>> +static inline u16 qspi_readw(struct atmel_qspi *aq, u32 reg)
>> +{
>> +	return readw_relaxed(aq->regs + reg);
>> +}
>> +
>> +static inline void qspi_writew(struct atmel_qspi *aq, u32 reg, u16 value)
>> +{
>> +	writew_relaxed(value, aq->regs + reg);
>> +}
>> +
>> +static inline u8 qspi_readb(struct atmel_qspi *aq, u32 reg)
>> +{
>> +	return readb_relaxed(aq->regs + reg);
>> +}
>> +
>> +static inline void qspi_writeb(struct atmel_qspi *aq, u32 reg, u8 value)
>> +{
>> +	writeb_relaxed(value, aq->regs + reg);
>> +}
> 
> [...]
> 
> Hope this helps :)
> 

Best regards,

Cyrille


From gkulkarni at caviumnetworks.com  Tue Aug 25 03:18:05 2015
From: gkulkarni at caviumnetworks.com (Ganapatrao Kulkarni)
Date: Tue, 25 Aug 2015 15:48:05 +0530
Subject: [PATCH v2] irqchip, gicv3-its,
 numa: Workaround for Cavium ThunderX erratum 23144
Message-ID: <1440497885-24584-1-git-send-email-gkulkarni@caviumnetworks.com>

The patch below adds a workaround for gicv3 in a numa environment. It
is on top of Robert's recent gicv3 errata patch submission v4 and my
arm64 numa patches v5.

This implements a workaround for gicv3-its erratum 23144 on Cavium's
ThunderX dual-socket platforms, where LPI cannot be routed to a
redistributors present on a foreign node.

v2:
updatated as per Marc Zyngier's review comments.

Signed-off-by: Ganapatrao Kulkarni <gkulkarni at caviumnetworks.com>
Signed-off-by: Robert Richter <rrichter at cavium.com>
---
 drivers/irqchip/irq-gic-v3-its.c | 53 +++++++++++++++++++++++++++++++++-------
 1 file changed, 44 insertions(+), 9 deletions(-)

diff --git a/drivers/irqchip/irq-gic-v3-its.c b/drivers/irqchip/irq-gic-v3-its.c
index 614a367..d3fe0a4 100644
--- a/drivers/irqchip/irq-gic-v3-its.c
+++ b/drivers/irqchip/irq-gic-v3-its.c
@@ -40,7 +40,8 @@
 #include "irqchip.h"
 
 #define ITS_FLAGS_CMDQ_NEEDS_FLUSHING          (1ULL << 0)
-#define ITS_FLAGS_CAVIUM_THUNDERX              (1ULL << 1)
+#define ITS_WORKAROUND_CAVIUM_22375            (1ULL << 1)
+#define ITS_WORKAROUND_CAVIUM_23144            (1ULL << 2)
 
 #define RDIST_FLAGS_PROPBASE_NEEDS_FLUSHING	(1 << 0)
 
@@ -73,6 +74,7 @@ struct its_node {
 	struct list_head	its_device_list;
 	u64			flags;
 	u32			ite_size;
+	int			numa_node;
 };
 
 #define ITS_ITT_ALIGN		SZ_256
@@ -607,11 +609,20 @@ static void its_eoi_irq(struct irq_data *d)
 static int its_set_affinity(struct irq_data *d, const struct cpumask *mask_val,
 			    bool force)
 {
-	unsigned int cpu = cpumask_any_and(mask_val, cpu_online_mask);
+	unsigned int cpu;
+	const struct cpumask *cpu_mask = cpu_online_mask;
 	struct its_device *its_dev = irq_data_get_irq_chip_data(d);
 	struct its_collection *target_col;
 	u32 id = its_get_event_id(d);
 
+	/* lpi cannot be routed to a redistributor that is on a foreign node */
+	if (its_dev->its->flags & ITS_WORKAROUND_CAVIUM_23144) {
+		cpu_mask = cpumask_of_node(its_dev->its->numa_node);
+		if (!cpumask_intersects(mask_val, cpu_mask))
+			return -EINVAL;
+	}
+
+	cpu = cpumask_any_and(mask_val, cpu_mask);
 	if (cpu >= nr_cpu_ids)
 		return -EINVAL;
 
@@ -1338,9 +1349,14 @@ static void its_irq_domain_activate(struct irq_domain *domain,
 {
 	struct its_device *its_dev = irq_data_get_irq_chip_data(d);
 	u32 event = its_get_event_id(d);
+	const struct cpumask *cpu_mask = cpu_online_mask;
+
+	/* get the cpu_mask of local node */
+	if (IS_ENABLED(CONFIG_NUMA))
+		cpu_mask = cpumask_of_node(its_dev->its->numa_node);
 
 	/* Bind the LPI to the first possible CPU */
-	its_dev->event_map.col_map[event] = cpumask_first(cpu_online_mask);
+	its_dev->event_map.col_map[event] = cpumask_first(cpu_mask);
 
 	/* Map the GIC IRQ and event to the device */
 	its_send_mapvi(its_dev, d->hwirq, event);
@@ -1423,11 +1439,19 @@ static int its_force_quiescent(void __iomem *base)
 	}
 }
 
-static void its_enable_cavium_thunderx(void *data)
+static void its_enable_cavium_thunderx_22375(void *data)
 {
        struct its_node *its = data;
 
-       its->flags |= ITS_FLAGS_CAVIUM_THUNDERX;
+	its->flags |= ITS_WORKAROUND_CAVIUM_22375;
+}
+
+static void its_enable_cavium_thunderx_23144(void *data)
+{
+	struct its_node *its = data;
+
+	if (num_possible_nodes() > 1)
+		its->flags |= ITS_WORKAROUND_CAVIUM_23144;
 }
 
 static const struct gic_capabilities its_errata[] = {
@@ -1435,10 +1459,16 @@ static const struct gic_capabilities its_errata[] = {
                .desc   = "ITS: Cavium errata 22375, 24313",
                .iidr   = 0xa100034c,   /* ThunderX pass 1.x */
                .mask   = 0xffff0fff,
-               .init   = its_enable_cavium_thunderx,
-       },
-       {
-       }
+		.init	= its_enable_cavium_thunderx_22375,
+	},
+	{
+		.desc	= "ITS: Cavium errata 23144",
+		.iidr	= 0xa100034c,	/* ThunderX pass 1.x */
+		.mask	= 0xffff0fff,
+		.init	= its_enable_cavium_thunderx_23144,
+	},
+	{
+	}
 };
 
 static void its_enable_quirks(struct its_node *its)
@@ -1456,6 +1486,7 @@ static int its_probe(struct device_node *node, struct irq_domain *parent)
 	u32 val;
 	u64 baser, tmp;
 	int err;
+	int numa_node;
 
 	err = of_address_to_resource(node, 0, &res);
 	if (err) {
@@ -1463,6 +1494,9 @@ static int its_probe(struct device_node *node, struct irq_domain *parent)
 		return -ENXIO;
 	}
 
+	/* get numa affinity of its node*/
+	numa_node = of_node_to_nid(node);
+
 	its_base = ioremap(res.start, resource_size(&res));
 	if (!its_base) {
 		pr_warn("%s: unable to map registers\n", node->full_name);
@@ -1498,6 +1532,7 @@ static int its_probe(struct device_node *node, struct irq_domain *parent)
 	its->phys_base = res.start;
 	its->msi_chip.of_node = node;
 	its->ite_size = ((readl_relaxed(its_base + GITS_TYPER) >> 4) & 0xf) + 1;
+	its->numa_node = numa_node;
 
 	its->cmd_base = kzalloc(ITS_CMD_QUEUE_SZ, GFP_KERNEL);
 	if (!its->cmd_base) {
-- 
1.8.1.4



From cyrille.pitchen at atmel.com  Tue Aug 25 03:21:06 2015
From: cyrille.pitchen at atmel.com (Cyrille Pitchen)
Date: Tue, 25 Aug 2015 12:21:06 +0200
Subject: [PATCH linux-next v4 5/5] mtd: atmel-quadspi: add driver for
 Atmel QSPI controller
In-Reply-To: <CAOiHx=kExyKAoGW4ciWHHxGNosNR0VdvHHrSqeo7RH1rNOXgig@mail.gmail.com>
References: <cover.1440410236.git.cyrille.pitchen@atmel.com>
 <201508241303.52066.marex@denx.de> <55DB4EA6.9090807@atmel.com>
 <201508241945.33577.marex@denx.de>
 <CAOiHx=kExyKAoGW4ciWHHxGNosNR0VdvHHrSqeo7RH1rNOXgig@mail.gmail.com>
Message-ID: <55DC4192.6060906@atmel.com>

Le 25/08/2015 11:46, Jonas Gorski a ?crit :
> On Mon, Aug 24, 2015 at 7:45 PM, Marek Vasut <marex at denx.de> wrote:
>> On Monday, August 24, 2015 at 07:04:38 PM, Cyrille Pitchen wrote:
>>> Hi Marek,
>>
>> Hi!
>>
>>> Le 24/08/2015 13:03, Marek Vasut a ?crit :
>>>> On Monday, August 24, 2015 at 12:14:00 PM, Cyrille Pitchen wrote:
>>>>> This driver add support to the new Atmel QSPI controller embedded into
>>>>> sama5d2x SoCs. It expects a NOR memory to be connected to the QSPI
>>>>> controller.
>>
>> [...]
>>
>>>>> +  /* Compute address parameters */
>>>>> +  switch (cmd->enable.bits.address) {
>>>>> +  case 4:
>>>>> +          ifr |= QSPI_IFR_ADDRL;
>>>>> +          /*break;*/ /* fallback to the 24bit address case */
>>>>
>>>> What's this commented out bit of code for ? :-)
>>>
>>> I just wanted to stress out there was no missing "break;".
>>> I've reworded the comment to:
>>> /* No "break" on purpose: fallback to the 24bit address case. */
>>
>> Oh, the address is in bytes . I see, yes, it makes sense to be more
>> explicit here about the purpose of the fallback. I think this change
>> in the comment will make it easier for everyone who comes back in a
>> few years and reads this code.
> 
> I think you are looking for the term "(switch case) fallthrough", not
> "fallback". "Fallback" makes it sound like there is something missing,
> or an invalid state.
> 
> 
> Jonas
> 

will be modified in the next series, thanks for the review!


From andre.przywara at arm.com  Tue Aug 25 03:23:01 2015
From: andre.przywara at arm.com (Andre Przywara)
Date: Tue, 25 Aug 2015 11:23:01 +0100
Subject: [PATCH v2 09/15] KVM: arm64: implement basic ITS register handlers
In-Reply-To: <55CCB6EC.50609@linaro.org>
References: <1436538111-4294-1-git-send-email-andre.przywara@arm.com>
 <1436538111-4294-10-git-send-email-andre.przywara@arm.com>
 <55CCB6EC.50609@linaro.org>
Message-ID: <55DC4205.5030806@arm.com>

Hi Eric,

....

>> diff --git a/virt/kvm/arm/its-emul.c b/virt/kvm/arm/its-emul.c
>> index 659dd39..b498f06 100644
>> --- a/virt/kvm/arm/its-emul.c
>> +++ b/virt/kvm/arm/its-emul.c
>> @@ -32,10 +32,62 @@
>>  #include "vgic.h"
>>  #include "its-emul.h"
>>
>> +#define BASER_BASE_ADDRESS(x) ((x) & 0xfffffffff000ULL)
>> +
>> +/* The distributor lock is held by the VGIC MMIO handler. */
>>  static bool handle_mmio_misc_gits(struct kvm_vcpu *vcpu,
>>                                 struct kvm_exit_mmio *mmio,
>>                                 phys_addr_t offset)
>>  {
>> +     struct vgic_its *its = &vcpu->kvm->arch.vgic.its;
>> +     u32 reg;
>> +     bool was_enabled;
>> +
>> +     switch (offset & ~3) {
>> +     case 0x00:              /* GITS_CTLR */
>> +             /* We never defer any command execution. */
>> +             reg = GITS_CTLR_QUIESCENT;
>> +             if (its->enabled)
>> +                     reg |= GITS_CTLR_ENABLE;
>> +             was_enabled = its->enabled;
>> +             vgic_reg_access(mmio, &reg, offset & 3,
>> +                             ACCESS_READ_VALUE | ACCESS_WRITE_VALUE);
>> +             its->enabled = !!(reg & GITS_CTLR_ENABLE);
>> +             return !was_enabled && its->enabled;
>> +     case 0x04:              /* GITS_IIDR */
>> +             reg = (PRODUCT_ID_KVM << 24) | (IMPLEMENTER_ARM << 0);
>> +             vgic_reg_access(mmio, &reg, offset & 3,
>> +                             ACCESS_READ_VALUE | ACCESS_WRITE_IGNORED);
>> +             break;
>> +     case 0x08:              /* GITS_TYPER */
>> +             /*
>> +              * We use linear CPU numbers for redistributor addressing,
>> +              * so GITS_TYPER.PTA is 0.
>> +              * To avoid memory waste on the guest side, we keep the
>> +              * number of IDBits and DevBits low for the time being.
>> +              * This could later be made configurable by userland.
>> +              * Since we have all collections in linked list, we claim
>> +              * that we can hold all of the collection tables in our
>> +              * own memory and that the ITT entry size is 1 byte (the
>> +              * smallest possible one).
>> +              */
>> +             reg = GITS_TYPER_PLPIS;
>> +             reg |= 0xff << GITS_TYPER_HWCOLLCNT_SHIFT;
>> +             reg |= 0x0f << GITS_TYPER_DEVBITS_SHIFT;
>> +             reg |= 0x0f << GITS_TYPER_IDBITS_SHIFT;
>> +             vgic_reg_access(mmio, &reg, offset & 3,
>> +                             ACCESS_READ_VALUE | ACCESS_WRITE_IGNORED);
>> +             break;
>> +     case 0x0c:
>> +             /* The upper 32bits of TYPER are all 0 for the time being.
>> +              * Should we need more than 256 collections, we can enable
>> +              * some bits in here.
>> +              */
>> +             vgic_reg_access(mmio, NULL, offset & 3,
>> +                             ACCESS_READ_RAZ | ACCESS_WRITE_IGNORED);
>> +             break;
>> +     }
>> +
>>       return false;
>>  }
>>
>> @@ -43,20 +95,142 @@ static bool handle_mmio_gits_idregs(struct kvm_vcpu *vcpu,
>>                                   struct kvm_exit_mmio *mmio,
>>                                   phys_addr_t offset)
>>  {
>> +     u32 reg = 0;
>> +     int idreg = (offset & ~3) + GITS_IDREGS_BASE;
>> +
>> +     switch (idreg) {
>> +     case GITS_PIDR2:
>> +             reg = GIC_PIDR2_ARCH_GICv3;
>> +             break;
>> +     case GITS_PIDR4:
>> +             /* This is a 64K software visible page */
>> +             reg = 0x40;
>> +             break;
>> +     /* Those are the ID registers for (any) GIC. */
>> +     case GITS_CIDR0:
>> +             reg = 0x0d;
>> +             break;
>> +     case GITS_CIDR1:
>> +             reg = 0xf0;
>> +             break;
>> +     case GITS_CIDR2:
>> +             reg = 0x05;
>> +             break;
>> +     case GITS_CIDR3:
>> +             reg = 0xb1;
>> +             break;
>> +     }
>> +     vgic_reg_access(mmio, &reg, offset & 3,
>> +                     ACCESS_READ_VALUE | ACCESS_WRITE_IGNORED);
>>       return false;
>>  }
>>
>> +static int vits_handle_command(struct kvm_vcpu *vcpu, u64 *its_cmd)
>> +{
>> +     return -ENODEV;
>> +}
>> +
>>  static bool handle_mmio_gits_cbaser(struct kvm_vcpu *vcpu,
>>                                   struct kvm_exit_mmio *mmio,
>>                                   phys_addr_t offset)
>>  {
>> +     struct vgic_its *its = &vcpu->kvm->arch.vgic.its;
>> +     int mode = ACCESS_READ_VALUE;
>> +
>> +     mode |= its->enabled ? ACCESS_WRITE_IGNORED : ACCESS_WRITE_VALUE;
>> +
>> +     vgic_handle_base_register(vcpu, mmio, offset, &its->cbaser, mode);
>> +
>> +     /* Writing CBASER resets the read pointer. */
>> +     if (mmio->is_write)
>> +             its->creadr = 0;
>> +
>>       return false;
>>  }
>>
>> +static int its_cmd_buffer_size(struct kvm *kvm)
>> +{
>> +     struct vgic_its *its = &kvm->arch.vgic.its;
>> +
>> +     return ((its->cbaser & 0xff) + 1) << 12;
>> +}
>> +
>> +static gpa_t its_cmd_buffer_base(struct kvm *kvm)
>> +{
>> +     struct vgic_its *its = &kvm->arch.vgic.its;
>> +
>> +     return BASER_BASE_ADDRESS(its->cbaser);
>> +}
>> +
>> +/*
>> + * By writing to CWRITER the guest announces new commands to be processed.
>> + * Since we cannot read from guest memory inside the ITS spinlock, we
>> + * iterate over the command buffer (with the lock dropped) until the read
>> + * pointer matches the write pointer. Other VCPUs writing this register in the
>> + * meantime will just update the write pointer, leaving the command
>> + * processing to the first instance of the function.
>> + */
> I am lost, isn't the dist lock hold by vgic_handle_mmio_access before
> calling call_range_handler/range->handle_mmio ?

Indeed, I was so focussed on the ITS lock...

> if confirmed we need to move the command enumeration + execution
> somewhere else.

I think we get away with dropping the dist lock after doing the actual
register access. Just before returning we then take it again to make the
caller happy.
I will give this a try. Thanks for spotting this!

> Besides that piece of code may deserve to be
> encaspulated in a function. what do you think?

Makes some sense, yes.

Cheers,
Andr?


From marex at denx.de  Tue Aug 25 03:22:10 2015
From: marex at denx.de (Marek Vasut)
Date: Tue, 25 Aug 2015 12:22:10 +0200
Subject: [PATCH linux-next v4 5/5] mtd: atmel-quadspi: add driver for
 Atmel QSPI controller
In-Reply-To: <55DC40C1.3050405@atmel.com>
References: <cover.1440410236.git.cyrille.pitchen@atmel.com>
 <201508241303.52066.marex@denx.de> <55DC40C1.3050405@atmel.com>
Message-ID: <201508251222.10813.marex@denx.de>

On Tuesday, August 25, 2015 at 12:17:37 PM, Cyrille Pitchen wrote:
> Hi Marek,

Hi!

> Le 24/08/2015 13:03, Marek Vasut a ?crit :
> > On Monday, August 24, 2015 at 12:14:00 PM, Cyrille Pitchen wrote:
> >> This driver add support to the new Atmel QSPI controller embedded into
> >> sama5d2x SoCs. It expects a NOR memory to be connected to the QSPI
> >> controller.
> >> 
> >> Signed-off-by: Cyrille Pitchen <cyrille.pitchen at atmel.com>
> >> Acked-by: Nicolas Ferre <nicolas.ferre at atmel.com>
> > 
> > Hi,
> > 
> > [...]
> > 
> >> +/* Register access macros */
> > 
> > These are functions, not macros :)
> > 
> > btw is there any reason for these ? I'd say, just put the read*() and
> > write*() functions directly into the code and be done with it, it is
> > much less confusing.
> 
> If you don't mind, I'd rather keep some of these inline functions. I have
> no strong justification, it's more a personal taste: it makes lines
> shorter as it avoids the need to add "->regs + ".
> Also it makes the code consistent with other Atmel drivers which already
> use such wrappers.
> 
> However I'll fix the comment and remove the byte and word versions, which
> are not used. So only qspi_readl() and qspi_writel() are left.
> 
> Does it sound good to you?

In my mind, seeing explicit readl_relaxed() somewhere is much easier to
digest than seeing some wrapper, which I have to look up. But please do
wait for others to voice their concern too, I might not be the best person
to tell you what to do when it comes to wrapping IO accessors ;-)

Best regards,
Marek Vasut


From lee.jones at linaro.org  Tue Aug 25 03:30:19 2015
From: lee.jones at linaro.org (Lee Jones)
Date: Tue, 25 Aug 2015 11:30:19 +0100
Subject: [PATCH-v2 1/5] mfd: 88pm800: Fix tabbing issue
In-Reply-To: <55DC2A51.6090008@linaro.org>
References: <1440442594-3102-1-git-send-email-vaibhav.hiremath@linaro.org>
 <1440442594-3102-2-git-send-email-vaibhav.hiremath@linaro.org>
 <20150825075121.GE19409@x1> <55DC2A51.6090008@linaro.org>
Message-ID: <20150825103019.GP19409@x1>

On Tue, 25 Aug 2015, Vaibhav Hiremath wrote:
> On Tuesday 25 August 2015 01:21 PM, Lee Jones wrote:
> >On Tue, 25 Aug 2015, Vaibhav Hiremath wrote:
> >
> >>Driver had coding style issues where spaces were used instead
> >>of tabs. This patch fixes them all.
> >
> >That's not all it's doing though is it?
> >
> 
> Yes, its just tabbing related fixes.

No, it's really not.

> >Please describe all of your changes.

... we're also taking the opportunity to remove the unnecessary
protection surrounding some of the defined values.

> >>Signed-off-by: Vaibhav Hiremath <vaibhav.hiremath at linaro.org>
> >>---
> >>  drivers/mfd/88pm800.c | 125 ++++++++++++++++++++++++--------------------------
> >>  1 file changed, 61 insertions(+), 64 deletions(-)
> >>
> >>diff --git a/drivers/mfd/88pm800.c b/drivers/mfd/88pm800.c
> >>index f104a32..c4e097d 100644
> >>--- a/drivers/mfd/88pm800.c
> >>+++ b/drivers/mfd/88pm800.c
> >>@@ -30,55 +30,55 @@
> >>  #include <linux/of_device.h>
> >>
> >>  /* Interrupt Registers */
> >>-#define PM800_INT_STATUS1		(0x05)
> >>+#define PM800_INT_STATUS1		0x05
> >>  #define PM800_ONKEY_INT_STS1		(1 << 0)
> >>  #define PM800_EXTON_INT_STS1		(1 << 1)
> >>-#define PM800_CHG_INT_STS1			(1 << 2)
> >>-#define PM800_BAT_INT_STS1			(1 << 3)
> >>-#define PM800_RTC_INT_STS1			(1 << 4)
> >>+#define PM800_CHG_INT_STS1		(1 << 2)
> >>+#define PM800_BAT_INT_STS1		(1 << 3)
> >>+#define PM800_RTC_INT_STS1		(1 << 4)
> >>  #define PM800_CLASSD_OC_INT_STS1	(1 << 5)
> >
> >These should all be replaced by BIT().
> >
> >Please fix the whole file.
> 
> Will do.
> 
> Thanks,
> Vaibhav

-- 
Lee Jones
Linaro STMicroelectronics Landing Team Lead
Linaro.org ? Open source software for ARM SoCs
Follow Linaro: Facebook | Twitter | Blog


From geert at linux-m68k.org  Tue Aug 25 03:32:51 2015
From: geert at linux-m68k.org (Geert Uytterhoeven)
Date: Tue, 25 Aug 2015 12:32:51 +0200
Subject: [PATCH 9/9] ARM: software-based priviledged-no-access support
In-Reply-To: <E1ZSmQG-0002za-E3@rmk-PC.arm.linux.org.uk>
References: <20150821133043.GV7557@n2100.arm.linux.org.uk>
 <E1ZSmQG-0002za-E3@rmk-PC.arm.linux.org.uk>
Message-ID: <CAMuHMdVMka2mt5pFpnXfLRY2M3Sj_71MgEpthOia2C99RaP_DA@mail.gmail.com>

Hi Russell,

On Fri, Aug 21, 2015 at 3:31 PM, Russell King
<rmk+kernel at arm.linux.org.uk> wrote:
> Provide a software-based implementation of the priviledged no access
> support found in ARMv8.1.
>
> Userspace pages are mapped using a different domain number from the
> kernel and IO mappings.  If we switch the user domain to "no access"
> when we enter the kernel, we can prevent the kernel from touching
> userspace.
>
> However, the kernel needs to be able to access userspace via the
> various user accessor functions.  With the wrapping in the previous
> patch, we can temporarily enable access when the kernel needs user
> access, and re-disable it afterwards.
>
> This allows us to trap non-intended accesses to userspace, eg, caused
> by an inadvertent dereference of the LIST_POISON* values, which, with
> appropriate user mappings setup, can be made to succeed.  This in turn
> can allow use-after-free bugs to be further exploited than would
> otherwise be possible.
>
> Signed-off-by: Russell King <rmk+kernel at arm.linux.org.uk>

This patch, which is now in arm-soc/for-next, breaks shmobile_defconfig
on r8a7791/koelsch, which has a dual core CA15:

    [ ok ] Configuring network interfaces...done.
    Unhandled fault: page domain fault (0x01b) at 0xbe8e6120
    pgd = edbb0000
    [be8e6120] *pgd=6da77831, *pte=bf4d075f, *ppte=bf4d0c7f
    Internal error: : 1b [#1] SMP ARM
    CPU: 1 PID: 1629 Comm: ntpdate Not tainted
4.2.0-rc8-06444-g3c24fd89c9421db1 #31
    9
    Hardware name: Generic R8A7791 (Flattened Device Tree)
    task: ed883a80 ti: ed41c000 task.ti: ed41c000
    PC is at csum_partial_copy_from_user+0x28/0x3d8
    LR is at csum_and_copy_from_iter+0x334/0x4c0
    pc : [<c04ba510>]    lr : [<c01c82e8>]    psr: 000f0013
    sp : ed41db00  ip : 00000020  fp : ed41db6c
    r10: ed41ddc0  r9 : 00000027  r8 : ed41dc20
    r7 : 00000027  r6 : eda52653  r5 : ed41dec8  r4 : 00000000
    r3 : 00000000  r2 : 00000027  r1 : eda5262c  r0 : be8e6120
    Flags: nzcv  IRQs on  FIQs on  Mode SVC_32  ISA ARM  Segment none
    Control: 10c5307d  Table: 6dbb006a  DAC: 00000051
    Process ntpdate (pid: 1629, stack limit = 0xed41c210)
    Stack: (0xed41db00 to 0xed41e000)
    db00: eda5262c 00000027 00000000 ed41dec8 eda52653 00000027
ed41dc20 c01c82e8
    db20: ed41db3c c03d7d44 000000d0 c00a85a0 ed41db74 00000000
ed41dba4 00000000
    db40: 00000000 00000027 edb36940 ed9b9380 00000000 ed41dc20
0000002f ed41dc30
    db60: ed41db8c ed41db70 c040dd5c c01c7fc0 00000000 00000000
00000027 edb36940
    db80: ed41dc04 ed41db90 c040c454 c040dd04 00000000 edb36940
ed41dbc4 00000043
    dba0: 000005c8 000005c8 0000002f 00000000 00000000 00000010
000005dc ee3c7280
    dba0: 000005c8 000005c8 0000002f 00000000 00000000 00000010
000005dc ee3c7280
    dbc0: 00000000 000005dc 00000000 00000014 ed41dc04 ffffff97
c040bde4 00004040
    dbe0: ed41dc20 ed9b95a8 ed9b9380 ed41dec0 c040dcf8 00003500
ed41dc74 ed41dc08
    dc00: c040e7f4 c040be8c ed883e5c c040dcf8 ed41dec0 0000002f
00000008 00004040
    dc20: ed41dc20 ed41dc20 00000000 c067bc40 00000000 00000000
00000000 000005dc
    dc40: 0000002f ee3c7280 ffff0000 ed41dc00 ed9b9380 ed9b95a8
ed41dec0 fe61a8c0
    dc60: 00000000 fe61a8c0 ed41dd64 ed41dc78 c0432118 c040e758
0000002f 00000008
    dc80: ed41dcb4 ed41dcb0 00004040 ffffffff 00000000 00000000
ed9b95a8 00000000
    dca0: c040dcf8 1c61a8c0 00000000 00000027 00000000 fe61a8c0
00000000 00000000
    dcc0: ffff0000 00000000 01ffffff b6d21000 edbb2db0 edb81580
ed41dd74 ed41dce8
    dce0: c0098d60 c00985d0 c04c27f8 ed41ddc0 00000001 be8e6068
00000051 ed41ddc0
    dd00: 00000008 00000000 00000008 c00cc668 00000008 ed41dec8
ed41dd9c 00000001
    dd20: 00000001 00000001 ed41dd64 ed41dd38 c01c8c7c c01c62f0
00000027 ed9b9380
    dd40: ed41dec0 00000027 ed41dda0 edc78c80 ed41deec 00004040
ed41dd84 ed41dd68
    dd60: c043b224 c0431c30 c043b198 ed41dec0 be8e6078 00000000
ed41dd94 ed41dd88
    dd80: c03cbaf0 c043b1a4 ed41deac ed41dd98 c03cbd3c c03cbae0
6f7f979f 00000000
    dda0: eedaf25c b6d21000 edb12484 edbb2db0 ed41de24 ed41ddc0
c00b1898 c00b02d8
    ddc0: be8e6120 00000027 00000001 000000fe 00000001 ee36d740
ed41ddf4 ed9b95a8
    dde0: c06a5b80 00000000 00000000 ed9b95a8 ed9b95a8 ee25f580
ed41de64 ed41de08
    de00: c0407274 00000000 c06a5b80 00000000 ee3c7280 00000006
c06a5b80 ee3c7280
    de20: c06a5b80 c06a5b80 ed9b9380 ed8736f0 ed41de4c ed41de40
ed41de94 ed41de48
    de40: c042e1c8 c04049b8 c0432688 c04c5a44 ed9b9380 ed9b944c
ee3c7280 ed41df08
    de60: ed9b95a8 00000000 ed41de8c ed41de78 ed9b9380 00000000
ed41de94 ed41de88
    de80: c00e5c08 00000000 be8e6078 edc78c80 00000002 00004000
ed41c030 00000000
    dea0: ed41df94 ed41deb0 c03ccfe8 c03cbbc0 ed41deec ed41dec0
00000000 00000000
    dec0: 00000000 00000000 00000001 00000000 00000027 ed41ddc0
00000001 00000000
    dee0: 00000000 00004040 00000000 c037ff04 ed41df44 ed41df00
c007181c c03801b0
    df00: 08cc6da6 00000000 00000000 002aea54 ffffffff 00ffffff
ed41df44 ed41df80
    df20: be8e5f88 00000005 0000004e c000fea4 ed41c000 00000000
ed41df54 ed41df48
    df40: c0071918 c00717dc ed41df7c ed41df58 c0071f04 00000000
00000001 be8e6060
    df60: 00000000 c000fea4 ed41c000 ffffffff 00000000 00004000
00000002 00000176
    df80: c000fea4 ed41c000 ed41dfa4 ed41df98 c03cd080 c03ccf80
00000000 ed41dfa8
    dfa0: c000fce0 c03cd07c 00000000 00004000 00000003 be8e6078
00000002 00004000
    dfc0: 00000000 00004000 00000002 00000176 00000003 00000005
b6e4ec14 2af73cb0
    dfe0: 00000176 be8e5f70 b6df6191 b6d798e6 800f0030 00000003
00000000 00000000
    Backtrace:
    [<c01c7fb4>] (csum_and_copy_from_iter) from [<c040dd5c>]
(ip_generic_getfrag+0x64/0xb4)
     r10:ed41dc30 r9:0000002f r8:ed41dc20 r7:00000000 r6:ed9b9380 r5:edb36940
     r4:00000027
    [<c040dcf8>] (ip_generic_getfrag) from [<c040c454>]
(__ip_append_data.isra.37+0x5d4/0x9b0)
     r5:edb36940 r4:00000027
    [<c040be80>] (__ip_append_data.isra.37) from [<c040e7f4>]
(ip_make_skb+0xa8/0xe0)
     r10:00003500 r9:c040dcf8 r8:ed41dec0 r7:ed9b9380 r6:ed9b95a8 r5:ed41dc20
     r4:00004040
    [<c040e74c>] (ip_make_skb) from [<c0432118>] (udp_sendmsg+0x4f4/0x6d8)
     r9:fe61a8c0 r8:00000000 r7:fe61a8c0 r6:ed41dec0 r5:ed9b95a8 r4:ed9b9380
    [<c0431c24>] (udp_sendmsg) from [<c043b224>] (inet_sendmsg+0x8c/0xc0)
     r10:00004040 r9:ed41deec r8:edc78c80 r7:ed41dda0 r6:00000027 r5:ed41dec0
     r4:ed9b9380
    [<c043b198>] (inet_sendmsg) from [<c03cbaf0>] (sock_sendmsg+0x1c/0x2c)
     r6:00000000 r5:be8e6078 r4:ed41dec0 r3:c043b198
    [<c03cbad4>] (sock_sendmsg) from [<c03cbd3c>] (___sys_sendmsg+0x188/0x1f8)
    [<c03cbbb4>] (___sys_sendmsg) from [<c03ccfe8>] (__sys_sendmmsg+0x74/0xfc)
     r10:00000000 r9:ed41c030 r8:00004000 r7:00000002 r6:edc78c80 r5:be8e6078
     r4:00000000
    [<c03ccf74>] (__sys_sendmmsg) from [<c03cd080>] (SyS_sendmmsg+0x10/0x14)
     r9:ed41c000 r8:c000fea4 r7:00000176 r6:00000002 r5:00004000 r4:00000000
    [<c03cd070>] (SyS_sendmmsg) from [<c000fce0>] (ret_fast_syscall+0x0/0x3c)
    Code: e3100003 1a00002f e3d2c00f 0a00000b (e4904004)
    ---[ end trace 21df281cc5d080da ]---

There are a few more networking-related backtraces during further booting
of userspace.

After disabling CONFIG_CPU_SW_DOMAIN_PAN it  fails differently:

    VFS: Mounted root (nfs filesystem) readonly on device 0:13.
    devtmpfs: mounted
    Freeing unused kernel memory: 300K (c0629000 - c0674000)
    Unhandled fault: page domain fault (0x81b) at 0x000263e0
    pgd = ed908000
    [000263e0] *pgd=6e299831, *pte=bf81d75f, *ppte=bf81dc7f
    Internal error: : 81b [#1] SMP ARM
    CPU: 1 PID: 1 Comm: init Not tainted 4.2.0-rc8-06444-g3c24fd89c9421db1 #332
    Hardware name: Generic R8A7791 (Flattened Device Tree)
    task: ee0319c0 ti: ee04e000 task.ti: ee04e000
    PC is at __clear_user_std+0x34/0x68
    LR is at padzero+0x4c/0x60
    pc : [<c01b2bd8>]    lr : [<c010a470>]    psr: 20000113
    sp : ee04fe40  ip : 00000000  fp : ee04fe54
    r10: ee0f5300  r9 : ee316120  r8 : 00000000
    r7 : 000265fc  r6 : 000263e0  r5 : ee314400  r4 : ee290e00
    r3 : 00000000  r2 : 00000000  r1 : 00000c18  r0 : 000263e0
    Flags: nzCv  IRQs on  FIQs on  Mode SVC_32  ISA ARM  Segment none
    Control: 10c5307d  Table: 6d90806a  DAC: 00000051
    Process init (pid: 1, stack limit = 0xee04e210)
    Stack: (0xee04fe40 to 0xee050000)
    fe40: 00000c20 c010a470 ee04fed4 ee04fe58 c010ae78 c010a430
00001812 00000000
    fe60: ee04fe94 ee04fe58 ee04e018 00025ef4 00015ad8 00010000
00000009 00010000
    fe80: 00000001 ee316000 ee31b300 000263e0 ee3d3600 00000000
ef7e93c0 00000000
    fea0: ee04febc ee04feb0 c001dde4 fffffff8 ee0f5300 c06c3ccc
c06c3ccc c067ff0c
    fec0: c0680374 c06c3ccc ee04ff04 ee04fed8 c00cf0b8 c010a7cc
c067c8b8 ee0f5300
    fee0: 00000000 ee13a000 00000001 00000000 ed9d5040 c0679318
ee04ff4c ee04ff08
    ff00: c00cf5a4 c00cf038 c05d6ab9 ed9d5078 c0679290 00000000
00000000 ee031c18
    ff20: ee04ff44 c0679318 c0679290 00000000 00000000 00000000
00000000 00000000
    ff40: ee04ff64 ee04ff50 c00cf784 c00cf198 00000000 00000000
ee04ff7c ee04ff68
    ff60: c000a5c8 c00cf75c c06a6000 c05ca7cd ee04ff94 ee04ff80
c000a5e4 c000a5ac
    ff80: c06a6000 c04b54c4 ee04ffac ee04ff98 c04b5544 c000a5dc
ee04e000 00000000
    ffa0: 00000000 ee04ffb0 c000fc88 c04b54d0 00000000 00000000
00000000 00000000
    ffc0: 00000000 00000000 00000000 00000000 00000000 00000000
00000000 00000000
    ffe0: 00000000 00000000 00000000 00000000 00000013 00000000
00000000 00000000
    Backtrace:
    [<c010a424>] (padzero) from [<c010ae78>] (load_elf_binary+0x6b8/0xfbc)
    [<c010a7c0>] (load_elf_binary) from [<c00cf0b8>]
(search_binary_handler+0x8c/0x160)
     r10:c06c3ccc r9:c0680374 r8:c067ff0c r7:c06c3ccc r6:c06c3ccc r5:ee0f5300
     r4:fffffff8
    [<c00cf02c>] (search_binary_handler) from [<c00cf5a4>]
(do_execveat_common+0x418/0x5c4)
     r10:c0679318 r9:ed9d5040 r8:00000000 r7:00000001 r6:ee13a000 r5:00000000
     r4:ee0f5300 r3:c067c8b8
    [<c00cf18c>] (do_execveat_common) from [<c00cf784>] (do_execve+0x34/0x3c)
     r10:00000000 r9:00000000 r8:00000000 r7:00000000 r6:00000000 r5:c0679290
     r4:c0679318
    [<c00cf750>] (do_execve) from [<c000a5c8>] (run_init_process+0x28/0x30)
    [<c000a5a0>] (run_init_process) from [<c000a5e4>]
(try_to_run_init_process+0x14/0x40)
     r5:c05ca7cd r4:c06a6000
    [<c000a5d0>] (try_to_run_init_process) from [<c04b5544>]
(kernel_init+0x80/0xec)
     r5:c04b54c4 r4:c06a6000
    [<c04b54c4>] (kernel_init) from [<c000fc88>] (ret_from_fork+0x14/0x2c)
     r4:00000000 r3:ee04e000
    Code: b4c02001 e26cc004 e041100c e2511008 (54802004)
    ---[ end trace 807fed3702987ba4 ]---
    Kernel panic - not syncing: Attempted to kill init! exitcode=0x0000000b

Reverting commit 0db805aa8c96f0ea ("ARM: software-based priviledged-no-access
support") fixes it.

Another board-specific config that has CONFIG_ARM_LPAE=y runs fine on the
same hardware. Disabling CONFIG_ARM_LPAE breaks it.

Gr{oetje,eeting}s,

                        Geert

--
Geert Uytterhoeven -- There's lots of Linux beyond ia32 -- geert at linux-m68k.org

In personal conversations with technical people, I call myself a hacker. But
when I'm talking to journalists I just say "programmer" or something like that.
                                -- Linus Torvalds


From lee.jones at linaro.org  Tue Aug 25 03:35:46 2015
From: lee.jones at linaro.org (Lee Jones)
Date: Tue, 25 Aug 2015 11:35:46 +0100
Subject: [PATCH-v2 1/5] mfd: 88pm800: Fix tabbing issue
In-Reply-To: <55DC2C4D.1040304@linaro.org>
References: <1440442594-3102-1-git-send-email-vaibhav.hiremath@linaro.org>
 <1440442594-3102-3-git-send-email-vaibhav.hiremath@linaro.org>
 <20150825075246.GF19409@x1> <55DC2C4D.1040304@linaro.org>
Message-ID: <20150825103546.GQ19409@x1>

On Tue, 25 Aug 2015, Vaibhav Hiremath wrote:

> 
> 
> On Tuesday 25 August 2015 01:22 PM, Lee Jones wrote:
> >On Tue, 25 Aug 2015, Vaibhav Hiremath wrote:
> >
> >>Driver had coding style issues where spaces were used instead
> >>of tabs. This patch fixes them all.
> >>
> >>Signed-off-by: Vaibhav Hiremath <vaibhav.hiremath at linaro.org>
> >>---
> >>  drivers/mfd/88pm800.c | 125 ++++++++++++++++++++++++--------------------------
> >>  1 file changed, 61 insertions(+), 64 deletions(-)
> >
> >Same comment as before.
> >
> >How similar is this file to the other one?
> 
> I believe you are referring to include/linux/mfd/88pm80x.h
> 
> >
> >Can you reduce the size by having shared register defines?
> >
> 
> Not sure whether I understand your comment here,
> They are common defines.

I guess the question was a little convoluted.

How about; why are the extra defines in the driver?  Why aren't all of
them in the header file?  What is the difference between the defines
in the C file compared with the ones defined in the header?

-- 
Lee Jones
Linaro STMicroelectronics Landing Team Lead
Linaro.org ? Open source software for ARM SoCs
Follow Linaro: Facebook | Twitter | Blog


From leif.lindholm at linaro.org  Tue Aug 25 03:40:53 2015
From: leif.lindholm at linaro.org (Leif Lindholm)
Date: Tue, 25 Aug 2015 11:40:53 +0100
Subject: [PATCH v1 3/3] arm64: dts: add Hi6220 mailbox node
In-Reply-To: <1440497710.10987.42.camel@linaro.org>
References: <1439977055-1747-1-git-send-email-leo.yan@linaro.org>
 <1439977055-1747-4-git-send-email-leo.yan@linaro.org>
 <20150821184059.GB2000@svinekod>
 <20150824091845.GA28290@leoy-linaro>
 <20150824095144.GA7139@leverpostej>
 <1440411596.3517.12.camel@linaro.org>
 <20150824114903.GT10728@bivouac.eciton.net>
 <1440490427.10987.29.camel@linaro.org>
 <20150825094630.GU10728@bivouac.eciton.net>
 <1440497710.10987.42.camel@linaro.org>
Message-ID: <20150825104053.GV10728@bivouac.eciton.net>

On Tue, Aug 25, 2015 at 06:15:10PM +0800, Haojian Zhuang wrote:
> > > 1. We need support both UEFI and uboot. So the reserved buffer have to
> > > be declared in DTB since they are used by kernel driver, not UEFI.
> > 
> > The buffer may need to be declared in DTB also, but it most certanily
> > needs to be declared in UEFI.
> > 
> > And for the U-Boot case, since it is not memory available to Linux, it
> > should not be declared as "memory".
> 
> Something are messed at here. We have these buffer are used in mailbox.
> They should be allocated as non-cacheable.

That is a completely different issue, and if that is not currently
possible, then we need to fix that. But it needs to be fixed in the
right place.

> If these buffers are contained in memory memblock in kernel, it means
> that they exist in kernel page table with cachable property. When it's
> used in mailbox driver with non-cachable property, it'll only cause
> cache maintenance issue. So Leo declared these buffers as reserved
> in DT with "no-map" property. It's the key. It could avoid the cache
> maintenance issue.

Yes, when not booting with UEFI.

> > > 2. UEFI just loads grub. It's no time to run any other custom EFI
> > > application.
> > 
> > Apart from being completely irrelevant, how are you intending to
> > validate that GRUB never touches these memory regions?
> 
> GRUB is just a part of bootloader. When linux kernel is running,
> who cares GRUB? GRUB's lifetime is already finished.

We don't care once Linux is running - we care between UEFI boot
services starting and Linux memblock being initialised.

> By the way, UEFI code region is at [0x3Dxx_xxxx, 0x3DFF_FFFF]. Those
> mailbox buffer is in [0x05e0_xxxx, 0x06f0_xxxx]. Then I can make sure
> UEFI won't touch the reserved buffer.

And if a UEFI application explicitly requests to map an area
elsewhere, will your UEFI reject that request? How will it do that
without having information in its memory map about areas it must not
access?

> Even if UEFI touched the reserved
> buffer, is it an issue? Definitely it's not. UEFI's lifetime is end
> when linux kernel is running at hikey. Even if UEFI runtime service
> is enabled, the runtime data area is at [0x38xx_xxxx, 0x38xx_xxxx].

The runtime data area is currently, in your current image, at
[0x38xx_xxxx, 0x38xx_xxxx].

What happens if a UEFI application registers a configuration table?
Or registers a protocol for use at runtime?

Areas of memory that are not available for UEFI _must_ be marked as
such in the UEFI memory map. Once they are, we can deal with them in
the kernel. If this is not currently being done, that is a bug that
needs fixing.

> > Build a version once, test it, and hope the results remain valid
> > forever? And then when you move the regions and the previously working
> > GRUB now tramples all over them? Or when something changes in upstream
> > GRUB and its memory allocations drifts into the secretly untouchable
> > regions?
> 
> As I said above, UEFI won't touch it. And even UEFI touch it, kernel
> doesn't care since UEFI's lifetime is end.

UEFI's lifetime doesn't end until reset.

> > Are you then going to hack GRUB, release a special HiKey version of
> > GRUB, not support any other versions, and still can your firmware
> > UEFI?
> 
> I don't need to hack GRUB at all.

You will if you're running it under a "UEFI" which has areas you can't
touch and aren't telling it about that.

/
    Leif


From treding at nvidia.com  Tue Aug 25 03:40:01 2015
From: treding at nvidia.com (Thierry Reding)
Date: Tue, 25 Aug 2015 12:40:01 +0200
Subject: [PATCH v3 06/14] Documentation: drm/bridge: add document for
 analogix_dp
In-Reply-To: <20150825092939.GM7557@n2100.arm.linux.org.uk>
References: <1439995728-18046-1-git-send-email-ykk@rock-chips.com>
 <1439995834-18363-1-git-send-email-ykk@rock-chips.com>
 <CAL_JsqLz+8RtBucctUj4euXZ3Ac0DvB52N9ONpAerh5T9BiTJg@mail.gmail.com>
 <20150824125758.GA7557@n2100.arm.linux.org.uk>
 <CAL_JsqKZYMMzV9Sc2r3K_rnM0FNuyb1TyJEhjGq1Hf7dTiWFKQ@mail.gmail.com>
 <20150825091246.GA14034@ulmo.nvidia.com>
 <20150825092939.GM7557@n2100.arm.linux.org.uk>
Message-ID: <20150825104000.GE14034@ulmo.nvidia.com>

On Tue, Aug 25, 2015 at 10:29:39AM +0100, Russell King - ARM Linux wrote:
> On Tue, Aug 25, 2015 at 11:12:48AM +0200, Thierry Reding wrote:
> > On Mon, Aug 24, 2015 at 09:48:27AM -0500, Rob Herring wrote:
> > > It goes beyond bindings IMO. The use of the component framework or not
> > > has been at the whim of driver writers as well. It is either used or
> > > private APIs are created. I'm using components and my need for it
> > > boils down to passing the struct drm_device pointer to the encoder.
> > > Other components like panels and bridges have different ways to attach
> > > to the DRM driver.
> > 
> > I certainly support unification, but it needs to be reasonable. There
> > are cases where a different structure for the binding work better than
> > another and I think this always needs to be evaluated on a case by case
> > basis.
> 
> It can't be a case-by-case basis.
> 
> The TDA998x encoder/connector is going to be component only.  This is
> a generic chip, which can be attached to the output of any parallel
> RGB+sync+clock bus.  In other words, it could appear anywhere.
> 
> Are you really saying that we need to support multiple schemes of
> attaching the driver to DRM?  That's totally insane IMHO.

No, what I'm saying is that we should have a single scheme, but one
that doesn't put any restrictions on what kind of DT binding you use or
how your driver is architected.

> The problem with the drm_encoder_slave stuff is that you can't sanely
> attach of-nodes to the drm-created i2c device.  Yes, you can parse
> them from the DT file as a sub-node of the upper device, but that
> then goes against the principle of the I2C bindings, which is to
> list the I2C devices as a child below the I2C adapter node.  If you
> try and put the DT node there, then the OF code will create the I2C
> device for you, and the drm_encoder_slave stuff won't have the
> control it needs to communicate through the wrapped i2c_driver
> stuff.
> 
> So, tda998x is going component-only, as that's the _only_ sane solution
> for it.

Has anyone ever considered turning it into a DRM bridge driver? I had
always envisioned component/master to be primarily useful to glue
together various SoC components to form one componentized device. Now
if tda998x is an I2C slave it is external to the SoC (auxiliary), so
in my opinion much better off as a bridge driver.

Bridge drivers don't come with any of the disadvantages that the
drm_encoder_slave stuff has. They are regular drivers that are probed
via their parent busses (I2C, platform, SPI, ...) and hook into DRM via
an abstract interface. The DT aspect is taken care of automatically
because they get instantiated by their parent bus like any other device.

> Now, what happens when some other DRM driver wants to use the tda998x
> driver, and its bindings are not compatible with the component helpers?
> They're pretty much stuck up the creek without a paddle.

I'm sure that will be very helpful response for whoever's going to end
up having to deal with that situation.

> Case by case doesn't work unless you're talking about truely isolated
> hardware where no one shares anything.

There are two different things here. The inter-driver interface, which,
in my opinion, it makes a lot of sense to standardize. Like I mentioned
above I think it unwise to make this interface depend upon a framework
or the firmware description such as DT in order to avoid unnecessary
restrictions. The second, orthogonal, issue, is the DT bindings. Those
I think should absolutely be designed case by case and select whatever
most accurately describes the hardware.

Thierry
-------------- next part --------------
A non-text attachment was scrubbed...
Name: signature.asc
Type: application/pgp-signature
Size: 819 bytes
Desc: not available
URL: <http://lists.infradead.org/pipermail/linux-arm-kernel/attachments/20150825/de0cd192/attachment.sig>

From mark.rutland at arm.com  Tue Aug 25 03:42:56 2015
From: mark.rutland at arm.com (Mark Rutland)
Date: Tue, 25 Aug 2015 11:42:56 +0100
Subject: [PATCH v1 3/3] arm64: dts: add Hi6220 mailbox node
In-Reply-To: <1440497710.10987.42.camel@linaro.org>
References: <1439977055-1747-1-git-send-email-leo.yan@linaro.org>
 <1439977055-1747-4-git-send-email-leo.yan@linaro.org>
 <20150821184059.GB2000@svinekod>
 <20150824091845.GA28290@leoy-linaro>
 <20150824095144.GA7139@leverpostej>
 <1440411596.3517.12.camel@linaro.org>
 <20150824114903.GT10728@bivouac.eciton.net>
 <1440490427.10987.29.camel@linaro.org>
 <20150825094630.GU10728@bivouac.eciton.net>
 <1440497710.10987.42.camel@linaro.org>
Message-ID: <20150825104256.GB13471@leverpostej>

On Tue, Aug 25, 2015 at 11:15:10AM +0100, Haojian Zhuang wrote:
> On Tue, 2015-08-25 at 10:46 +0100, Leif Lindholm wrote:
> > On Tue, Aug 25, 2015 at 04:13:47PM +0800, Haojian Zhuang wrote:
> > > On Mon, 2015-08-24 at 12:49 +0100, Leif Lindholm wrote:
> > > > On Mon, Aug 24, 2015 at 06:19:56PM +0800, Haojian Zhuang wrote:
> > > > > > If your EFI memory map describes the memory as mappable, it is wrong.
> > > > > 
> > > > > When kernel is working, kernel will create its own page table based on
> > > > > UEFI memory map. Since it's reserved in DTS file as Leo's patch, it'll
> > > > > be moved to reserved memblock. Why is it wrong?
> > > > > 
> > > > > In the second, UEFI is firmware. When it's stable, nobody should change
> > > > > it without any reason.
> > > > 
> > > > Much like the memory map.
> > > > 
> > > > > These reserved memory are used in mailbox driver.
> > > > > Look. It's driver, so it could be changed at any time.
> > > > 
> > > > No, it is a set of regions of memory set aside for use by a different
> > > > master in the system as well as communications with that master.
> > > > 
> > > > The fact that there is a driver somewhere that is aware of this is
> > > > entirely beside the point. All agents in the system must adher to this
> > > > protocol.
> > > > 
> > > > > Why do you want
> > > > > to UEFI knowing this memory range? Do you hope UEFI to change when
> > > > > mailbox driver is changed?
> > > > 
> > > > Yes.
> > > > 
> > > > UEFI is a runtime environment. Having random magic areas not to be
> > > > touched will cause random pieces of software running under it to break
> > > > horribly or break other things horribly.
> > > > Unless you mark them as reserved in the UEFI memory map.
> > > > At which point the Linux kernel will automatically ignore them, and
> > > > the proposed patch is redundant.
> > > > 
> > > > So, yes, if you want a system that can boot reliably, run testsuites
> > > > (like SCT or FWTS), run applications (like fastboot ... or the EFI
> > > > stub kernel itself), then any memory regions that is reserved for
> > > > mailbox communication (or other masters in the system) _must_ be
> > > > marked in the EFI memory map.
> > > 
> > > 1. We need support both UEFI and uboot. So the reserved buffer have to
> > > be declared in DTB since they are used by kernel driver, not UEFI.
> > 
> > The buffer may need to be declared in DTB also, but it most certanily
> > needs to be declared in UEFI.
> > 
> > And for the U-Boot case, since it is not memory available to Linux, it
> > should not be declared as "memory".
> 
> Something are messed at here. We have these buffer are used in mailbox.
> They should be allocated as non-cacheable.
> 
> If these buffers are contained in memory memblock in kernel, it means
> that they exist in kernel page table with cachable property. When it's
> used in mailbox driver with non-cachable property, it'll only cause
> cache maintenance issue. So Leo declared these buffers as reserved
> in DT with "no-map" property. It's the key. It could avoid the cache
> maintenance issue.

The better solution is to never describe the memory to the kernel as
memory, by never placing it in a memory node, and ensuring that if it is
in the UEFI memory map, its attributes do not allow it to be mapped.

That way a driver can map it as non-cacheable if it wishes, but nothing
else can possibly touch that memory.

That is all you need to do.

> > > 2. UEFI just loads grub. It's no time to run any other custom EFI
> > > application.
> > 
> > Apart from being completely irrelevant, how are you intending to
> > validate that GRUB never touches these memory regions?
> > 
> 
> GRUB is just a part of bootloader. When linux kernel is running,
> who cares GRUB? GRUB's lifetime is already finished.

If GRUB temporarily maps memory as cacheable, or hands it to a device,
then your statements above about cache maintenance are broken.

An EFI application like GRUB might leave something resident in memory
after it's done (consider the UEFI shim), or it could even load the
kernel into the region that you care about having reserved, because as
far as it's concerned it's just memory. That could leave you with a
conflict for that region of memory.

You _must_ care about GRUB (and other EFI applications) doing the right
thing. To get them to avoid a region of memory, it must not be described
as being usable by them in the UEFI memory map.

> By the way, UEFI code region is at [0x3Dxx_xxxx, 0x3DFF_FFFF]. Those
> mailbox buffer is in [0x05e0_xxxx, 0x06f0_xxxx]. Then I can make sure
> UEFI won't touch the reserved buffer. Even if UEFI touched the reserved
> buffer, is it an issue? Definitely it's not.

It definitely is, due to the possibility of stale cache lines being left
in the region from when UEFI may have mapped it with cacheable
attributes.

> > Build a version once, test it, and hope the results remain valid
> > forever? And then when you move the regions and the previously working
> > GRUB now tramples all over them? Or when something changes in upstream
> > GRUB and its memory allocations drifts into the secretly untouchable
> > regions?
> 
> As I said above, UEFI won't touch it. And even UEFI touch it, kernel
> doesn't care since UEFI's lifetime is end.

If EFI touches it there may be stale cache lines left around, which you
don't seem to expect.

> > Are you then going to hack GRUB, release a special HiKey version of
> > GRUB, not support any other versions, and still can your firmware
> > UEFI?
> 
> I don't need to hack GRUB at all.

Then it is working for you by pure chance alone.

Please listen to the advice you are being given here; we're trying to
ensure that your platform functions (and continues to function) as best
it can.

Thanks,
Mark.


From linux at arm.linux.org.uk  Tue Aug 25 03:44:22 2015
From: linux at arm.linux.org.uk (Russell King - ARM Linux)
Date: Tue, 25 Aug 2015 11:44:22 +0100
Subject: [PATCH 9/9] ARM: software-based priviledged-no-access support
In-Reply-To: <CAMuHMdVMka2mt5pFpnXfLRY2M3Sj_71MgEpthOia2C99RaP_DA@mail.gmail.com>
References: <20150821133043.GV7557@n2100.arm.linux.org.uk>
 <E1ZSmQG-0002za-E3@rmk-PC.arm.linux.org.uk>
 <CAMuHMdVMka2mt5pFpnXfLRY2M3Sj_71MgEpthOia2C99RaP_DA@mail.gmail.com>
Message-ID: <20150825104422.GO7557@n2100.arm.linux.org.uk>

On Tue, Aug 25, 2015 at 12:32:51PM +0200, Geert Uytterhoeven wrote:
> This patch, which is now in arm-soc/for-next, breaks shmobile_defconfig
> on r8a7791/koelsch, which has a dual core CA15:
> 
>     [ ok ] Configuring network interfaces...done.
>     Unhandled fault: page domain fault (0x01b) at 0xbe8e6120
>     pgd = edbb0000
>     [be8e6120] *pgd=6da77831, *pte=bf4d075f, *ppte=bf4d0c7f
>     Internal error: : 1b [#1] SMP ARM
>     CPU: 1 PID: 1629 Comm: ntpdate Not tainted
> 4.2.0-rc8-06444-g3c24fd89c9421db1 #31
>     9
>     Hardware name: Generic R8A7791 (Flattened Device Tree)
>     task: ed883a80 ti: ed41c000 task.ti: ed41c000
>     PC is at csum_partial_copy_from_user+0x28/0x3d8
>     LR is at csum_and_copy_from_iter+0x334/0x4c0
>     pc : [<c04ba510>]    lr : [<c01c82e8>]    psr: 000f0013
>     sp : ed41db00  ip : 00000020  fp : ed41db6c
>     r10: ed41ddc0  r9 : 00000027  r8 : ed41dc20
>     r7 : 00000027  r6 : eda52653  r5 : ed41dec8  r4 : 00000000
>     r3 : 00000000  r2 : 00000027  r1 : eda5262c  r0 : be8e6120
>     Flags: nzcv  IRQs on  FIQs on  Mode SVC_32  ISA ARM  Segment none
>     Control: 10c5307d  Table: 6dbb006a  DAC: 00000051
>     Process ntpdate (pid: 1629, stack limit = 0xed41c210)

Thanks.  I wonder what's different about your ntpdate that triggers
this, and why all my iMX6 behave fine, which have desktop-like ubuntu
installs on (of two different versions.)

What it's basically showing is that (unsurprisingly)
csum_partial_copy_from_user is trying to access userspace.  I'll see
about fixing that today, or pulling the patch from -next if I can't.

I've also noticed that on rpc_defconfig, the 0-day builder shows that
this triggers an ICE as the compiler appears to think it's run out of
registers.

> After disabling CONFIG_CPU_SW_DOMAIN_PAN it  fails differently:
> 
>     VFS: Mounted root (nfs filesystem) readonly on device 0:13.
>     devtmpfs: mounted
>     Freeing unused kernel memory: 300K (c0629000 - c0674000)
>     Unhandled fault: page domain fault (0x81b) at 0x000263e0
>     pgd = ed908000
>     [000263e0] *pgd=6e299831, *pte=bf81d75f, *ppte=bf81dc7f

Yes, this one is because I forgot to provide the non-protected default
for bootup, which I've already merged a fix for.

-- 
FTTC broadband for 0.8mile line: currently at 10.5Mbps down 400kbps up
according to speedtest.net.


From vaibhav.hiremath at linaro.org  Tue Aug 25 03:49:18 2015
From: vaibhav.hiremath at linaro.org (Vaibhav Hiremath)
Date: Tue, 25 Aug 2015 16:19:18 +0530
Subject: [PATCH-v2 1/5] mfd: 88pm800: Fix tabbing issue
In-Reply-To: <20150825103019.GP19409@x1>
References: <1440442594-3102-1-git-send-email-vaibhav.hiremath@linaro.org>
 <1440442594-3102-2-git-send-email-vaibhav.hiremath@linaro.org>
 <20150825075121.GE19409@x1> <55DC2A51.6090008@linaro.org>
 <20150825103019.GP19409@x1>
Message-ID: <55DC482E.8030206@linaro.org>



On Tuesday 25 August 2015 04:00 PM, Lee Jones wrote:
> On Tue, 25 Aug 2015, Vaibhav Hiremath wrote:
>> On Tuesday 25 August 2015 01:21 PM, Lee Jones wrote:
>>> On Tue, 25 Aug 2015, Vaibhav Hiremath wrote:
>>>
>>>> Driver had coding style issues where spaces were used instead
>>>> of tabs. This patch fixes them all.
>>>
>>> That's not all it's doing though is it?
>>>
>>
>> Yes, its just tabbing related fixes.
>
> No, it's really not.
>
>>> Please describe all of your changes.
>
> ... we're also taking the opportunity to remove the unnecessary
> protection surrounding some of the defined values.
>

Ohhh ok. Forgot about brackets :)

Anyway,
Based on the comments you provided, I think both header file and
source file needs some more cleanup.
I will try to incorporate all changes in next version.

I may also submit separate series for cleanup version (depends on
patches I produce).

Thanks,
Vaibhav


From linux at arm.linux.org.uk  Tue Aug 25 03:52:46 2015
From: linux at arm.linux.org.uk (Russell King - ARM Linux)
Date: Tue, 25 Aug 2015 11:52:46 +0100
Subject: [PATCH v3 06/14] Documentation: drm/bridge: add document for
 analogix_dp
In-Reply-To: <20150825104000.GE14034@ulmo.nvidia.com>
References: <1439995728-18046-1-git-send-email-ykk@rock-chips.com>
 <1439995834-18363-1-git-send-email-ykk@rock-chips.com>
 <CAL_JsqLz+8RtBucctUj4euXZ3Ac0DvB52N9ONpAerh5T9BiTJg@mail.gmail.com>
 <20150824125758.GA7557@n2100.arm.linux.org.uk>
 <CAL_JsqKZYMMzV9Sc2r3K_rnM0FNuyb1TyJEhjGq1Hf7dTiWFKQ@mail.gmail.com>
 <20150825091246.GA14034@ulmo.nvidia.com>
 <20150825092939.GM7557@n2100.arm.linux.org.uk>
 <20150825104000.GE14034@ulmo.nvidia.com>
Message-ID: <20150825105246.GP7557@n2100.arm.linux.org.uk>

On Tue, Aug 25, 2015 at 12:40:01PM +0200, Thierry Reding wrote:
> On Tue, Aug 25, 2015 at 10:29:39AM +0100, Russell King - ARM Linux wrote:
> > Now, what happens when some other DRM driver wants to use the tda998x
> > driver, and its bindings are not compatible with the component helpers?
> > They're pretty much stuck up the creek without a paddle.
> 
> I'm sure that will be very helpful response for whoever's going to end
> up having to deal with that situation.

Thank you for that comment, it's very constructive and much appreciated.
I can see it's well worth me continuing to spend time on this thread.

-- 
FTTC broadband for 0.8mile line: currently at 10.5Mbps down 400kbps up
according to speedtest.net.


From vaibhav.hiremath at linaro.org  Tue Aug 25 03:56:16 2015
From: vaibhav.hiremath at linaro.org (Vaibhav Hiremath)
Date: Tue, 25 Aug 2015 16:26:16 +0530
Subject: [PATCH-v2 1/5] mfd: 88pm800: Fix tabbing issue
In-Reply-To: <20150825103546.GQ19409@x1>
References: <1440442594-3102-1-git-send-email-vaibhav.hiremath@linaro.org>
 <1440442594-3102-3-git-send-email-vaibhav.hiremath@linaro.org>
 <20150825075246.GF19409@x1> <55DC2C4D.1040304@linaro.org>
 <20150825103546.GQ19409@x1>
Message-ID: <55DC49D0.1030608@linaro.org>



On Tuesday 25 August 2015 04:05 PM, Lee Jones wrote:
> On Tue, 25 Aug 2015, Vaibhav Hiremath wrote:
>
>>
>>
>> On Tuesday 25 August 2015 01:22 PM, Lee Jones wrote:
>>> On Tue, 25 Aug 2015, Vaibhav Hiremath wrote:
>>>
>>>> Driver had coding style issues where spaces were used instead
>>>> of tabs. This patch fixes them all.
>>>>
>>>> Signed-off-by: Vaibhav Hiremath <vaibhav.hiremath at linaro.org>
>>>> ---
>>>>   drivers/mfd/88pm800.c | 125 ++++++++++++++++++++++++--------------------------
>>>>   1 file changed, 61 insertions(+), 64 deletions(-)
>>>
>>> Same comment as before.
>>>
>>> How similar is this file to the other one?
>>
>> I believe you are referring to include/linux/mfd/88pm80x.h
>>
>>>
>>> Can you reduce the size by having shared register defines?
>>>
>>
>> Not sure whether I understand your comment here,
>> They are common defines.
>
> I guess the question was a little convoluted.
>
> How about; why are the extra defines in the driver?  Why aren't all of
> them in the header file?  What is the difference between the defines
> in the C file compared with the ones defined in the header?
>


I do not see any difference and need of having defines separately in C
file.
That's the cleanup I was referring to in another email.

I will walk through the whole driver code and try to cleanup all such
coding related issues. Probably expect separate series here.

Thanks,
Vaibhav


From p.fedin at samsung.com  Tue Aug 25 04:01:22 2015
From: p.fedin at samsung.com (Pavel Fedin)
Date: Tue, 25 Aug 2015 14:01:22 +0300
Subject: [PATCH 2/5] gic-its: Allow pci_requester_id to be overridden.
In-Reply-To: <55D5F0E1.30702@caviumnetworks.com>
References: <1436979285-8177-1-git-send-email-ddaney.cavm@gmail.com>
 <1436979285-8177-3-git-send-email-ddaney.cavm@gmail.com>
 <01a101d0db52$2d23b360$876b1a20$@samsung.com>
 <55D5F0E1.30702@caviumnetworks.com>
Message-ID: <012a01d0df25$61515ad0$23f41070$@samsung.com>

 Hello!

> >   What if instead of this function we simply add a field to a struct pci_bus ? Then bus driver
would
> > fill in HW-specific ID bits for every bus.
> >   I can send a patch if interested.
> 
> There is a lot of work being done in the upstream to extract the proper
> information from the device tree.  We are going to piggyback on that for
> the next versions of the patch.

 Where can i take a look at the code?

Kind regards,
Pavel Fedin
Expert Engineer
Samsung Electronics Research center Russia



From mark.rutland at arm.com  Tue Aug 25 04:09:36 2015
From: mark.rutland at arm.com (Mark Rutland)
Date: Tue, 25 Aug 2015 12:09:36 +0100
Subject: [PATCH v1 3/3] arm64: dts: add Hi6220 mailbox node
In-Reply-To: <1440489885.10987.26.camel@linaro.org>
References: <1439977055-1747-1-git-send-email-leo.yan@linaro.org>
 <1439977055-1747-4-git-send-email-leo.yan@linaro.org>
 <20150821184059.GB2000@svinekod>
 <20150824091845.GA28290@leoy-linaro>
 <20150824095144.GA7139@leverpostej>
 <1440411596.3517.12.camel@linaro.org>
 <20150824124800.GD7139@leverpostej>
 <1440489885.10987.26.camel@linaro.org>
Message-ID: <20150825110936.GC13471@leverpostej>

Hi,

On Tue, Aug 25, 2015 at 09:04:45AM +0100, Haojian Zhuang wrote:
> On Mon, 2015-08-24 at 13:48 +0100, Mark Rutland wrote:
> > > > > > I don't see why you need reserved-memory here, given you're not referring to
> > > > > > these regions by phandle anyway.
> > > > > 
> > > > > - Now we have enabled EFI_STUB, so the memory node will be removed in
> > > > >   kernel:
> > > > >     efi_entry()
> > > > >       \-> allocate_new_fdt_and_exit_boot()
> > > > >             \-> update_fdt();
> > > > > 
> > > > >   Finally in kernel it cannot use memory node to carve out reseved
> > > > >   memory regions.
> > > > > 
> > > > > - On the other hand, DTS's the memory node is to "describes the
> > > > >   physical memory layout for the system"; so it's better to use it only
> > > > >   to describe the hardware info for memory. We can use reserved-memory
> > > > >   to help manage the memory regions which are reserved from software
> > > > >   perspective.
> > > > 
> > > > The fact that you have no-map means that the memory should not be
> > > > described to the kernel as mappable in the first place. It's wrong to
> > > > place such memory in the memory node, even if listed in reserved-memory.
> > > > 
> > > > If your EFI memory map describes the memory as mappable, it is wrong.
> > > 
> > > When kernel is working, kernel will create its own page table based on
> > > UEFI memory map. Since it's reserved in DTS file as Leo's patch, it'll
> > > be moved to reserved memblock. Why is it wrong?
> > 
> > That is a _Linux_ detail, not a _UEFI_ detail.
> > 
> > Anything which only handles UEFI and knows nothing of reserved-memory
> > (e.g. GRUB) will be broken and/or break the Linux use of the region, as
> > it will happily try to allocate memory in the region (and could even
> > decide to reserve it permanently for its own usage).
> > 
> > If the memory is truly specific to the mailbox, then UEFI needs to know
> > that it is reserved as such. If it is not, then it need not be described
> > in the DT and can be allocated dynamically by the kernel.
> 
> No. We support both UEFI and uboot on hikey. We must reserve these
> mailbox buffer in DT. Otherwise, it's a problem to support uboot.

The same solution applies to both: don't describe the memory in the
first place. Don't place it in a memory node, and don't give it
attributes allowing it to be mapped and used in the UEFI memory map.

> We should only deliver one kernel and one DTB to support both UEFI and
> uboot.

I do not disagree with this point generally, but it's irrelevant to the
point at hand.

> And mailbox driver is already upgraded from beginning. Nobody can say
> that it won't be upgraded again in the future.

This doesn't follow. If you want to pointlessly change things, you will
encounter pain. That's not an argument for hacking a partial solution
into the DT and ignoring the problems this causes.

As I tried to ask earlier, how is the mailbox memory used? Does the
kernel configure the address in the hardware, or is this pre-configured?
Could the kernel choose a region of memory to use dynamically?

> By the way, UEFI is loaded in the upper memory region of hikey. It won't
> break anything in linux kernel.

The code might be there, but UEFI can make use of any memory it knows
about for stacks, pool allocations and so on. It needs to be prevented
from using the mailbox memory.

> > > In the second, UEFI is firmware. When it's stable, nobody should change
> > > it without any reason. These reserved memory are used in mailbox driver.
> > > Look. It's driver, so it could be changed at any time. Why do you want
> > > to UEFI knowing this memory range? Do you hope UEFI to change when
> > > mailbox driver is changed?
> > 
> > It shouldn't need to change if that memory is truly reserved for the
> > sole use of the mailbox. If that's not the case then we have a different
> > issue.
> > 
> > If the memory range to use can be allocated by the driver, then I don't
> > see why it should be described in reserved-memory. It certainly should
> > not require a no-map attribute.
> > 
> > Additionally, the driver needs to ensure that the requisite cache
> > maintenance takes place prior to the use of the memory region given
> > prior agents may have ampped it as cacheable, leaving stale (perhaps
> > dirty) lines in the caches.
> > 
> 
> Since those mailbox buffer is declared as reserved with "no-map"
> property, it means that linux kernel won't create the page table of
> them.

I am well aware of how this works. Please re-read my replies, this is
not the issue I describe.

> The meaning of "no-map" is removing it from memory memblock.
> setup_arch()
>   |
>   ---> efi_init() -- Get memory map information from UEFI
>   |
>   ---> arm64_memblock_init()
>   |      |
>   |      ---> early_init_fdt_scan_reserved_mem()
>   |           Get reserved memory buffer from DT. Split memory
>   |           memblock according to reserved buffer.
>   ---> paging_init()
>          |--> map_mem()
>               _Only_ map the discrete memory memblock into kernel
>               page table.
> 
> From this working flow, we could know that those mailbox buffers
> won't be mapped into kernel page table. So there's no concern on
> cache maintenance.

This is simply not true. If UEFI (or any UEFI application) mapped the
memory as cacheable in the past, you need to perform cache maintenance
to get rid of any stale (dirty) cachelines.

This is one of the reasons that the UEFI memory map needs to not
describe the memory as being available to be mapped and used, and why
having a reserved-memory node is insufficient.

> > > > > According to upper info, we still need to use reserved-memory node to
> > > > > depict the reserved memory regions. i have no knowledge about EFI_STUB,
> > > > > so please confirm or correct as needed.
> > > > 
> > > > If the memory shouldn't be mapped, it should neither be in the memory
> > > > node nor EFI memory map (with attributes allowing it to be mapped) to
> > > > begin with.
> > > 
> > > As I said above, kernel will create its own page table. When kernel's
> > > page table is working, UEFI's page table is destroying. So the memory
> > > won't be mapped twice at the same time. What's wrong?
> > > > 
> > > > As far as I can see you do not need to use reserved-memory.
> > > 
> > > 1. Are we talking on the same thing? Leo already mentioned that all
> > > memory node in DTB will be destroyed by kernel when EFI_STUB is enabled
> > > on arm. Did you read the source code after his reply?
> > > And you suggested that Leo to use discrete memory region in DTB. It is
> > > really wrong. Kernel only gets memory map information from UEFI, not
> > > DTB.
> > 
> > I did _not_ suggest that Leo use discrete memory. I suggested that
> > reserved regions should not be described in the memory node (the same
> > premise applying to the UEFI memory map).
> 
> I agree that reserved region shouldn't be described in the memory node.
> And Leo didn't describe reserved region in memory node too.

The issue is that the region you describe in reserved-memory also falls
within an existing region in a memory node (or the UEFI memory map).

The no-map forces a memblock_remove after the memory was added to
memblock, but before it was mapped. This ensures Linux won't map the
memory. This does not ensure that UEFI or UEFI application will not map,
reserve, or use the memory for their own purposes.

> > w.r.t. UEFI, please see my comments above. If you're using the UEFI
> > memory map, you have to use the UEFI memory map, not the UEFI memory map
> > with additional (non-UEFI) caveats applied atop.
> 
> The main concern is that we're supporting both UEFI and uboot.
> Declaring these reserved buffer in DTB will be a better choice.

Unfortunately this is insufficient. This leaves a slew of problems when
using UEFI, and given that, it's not a common solution.

Using reserved-memory in this case only gives a semblance of
correctness, but doesn't mean you are doing the right thing.

> > > 4. Again and again. Memory node should be only used to describe the
> > > RAM information.
> > 
> > The memory node describes the memory available to the OS. There are some
> > caveats w.r.t. /memreserve/, regions which may be mapped but remain
> > unused and so on, but the memory node does generally encode a policy
> > that the memory may be used.
> > 
> > Describing unusable memory in a memory node is pointless, and has an
> > adverse effect on clients which don't support reserved-memory. It's
> > doubly harmful when that memory should never be mapped.
> > 
> 
> He didn't declare those buffer in memory node. He only declared it
> in reserved-memory node. And it's not never be mapped. He use ioremap()
> in the driver.

If the memory is not in the memory nodes nor the UEFI memory map, there
is no need for a reserved-memory entry. If it exists in the UEFI memory
map, the reserved-memory entry is insufficient for the reasons I have
stated previously.

Likewise for the MCU firmware memory.

Thanks,
Mark.


From suravee.suthikulpanit at amd.com  Tue Aug 25 04:11:41 2015
From: suravee.suthikulpanit at amd.com (Suthikulpanit, Suravee)
Date: Tue, 25 Aug 2015 18:11:41 +0700
Subject: [PATCH] pci: acpi: Generic function for setting up PCI device DMA
 coherency
In-Reply-To: <CAErSpo6TcwVH+TT5wZnLjOPMTa1NBoN=qJCev1rg1n_xFbggBQ@mail.gmail.com>
References: <1439459925-2361-1-git-send-email-Suravee.Suthikulpanit@amd.com>
 <20150814015004.GA26431@google.com>
 <CAErSpo7yN08tKyo-yyyVG58vUptbHGN=L+MEZ8TQy1gm5a1_0Q@mail.gmail.com>
 <55DB6BF6.1030206@amd.com>
 <CAErSpo6TcwVH+TT5wZnLjOPMTa1NBoN=qJCev1rg1n_xFbggBQ@mail.gmail.com>
Message-ID: <55DC4D6D.207@amd.com>

Hi Bjorn,

On 8/25/2015 3:14 AM, Bjorn Helgaas wrote:
> On Mon, Aug 24, 2015 at 12:09 PM, Suravee Suthikulpanit
> <Suravee.Suthikulpanit at amd.com> wrote:
>
>>>> commit 84cfb2213cd400fef227ec0d7829ec4e12895da9
>>>> Author: Bjorn Helgaas <bhelgaas at google.com>
>>>> Date:   Thu Aug 13 19:49:52 2015 -0500
>>>>
>>>>       ACPI / scan: Rename acpi_check_dma() to acpi_dma_is_coherent()
>>>>
>>>>       The name "acpi_check_dma()" doesn't give any much indication about
>>>> what
>>>>       exactly it checks.  The function also returns information both as a
>>>> normal
>>>>       return value and as the "bool *coherent" return parameter.  But
>>>> "*coherent"
>>>>       doesn't actually give any extra information: it is unchanged when
>>>> returning
>>>>       false and set to true when returning true.
>>>>
>>>>       Rename acpi_check_dma() to acpi_dma_is_coherent() so the callers
>>>> read more
>>>>       naturally.  Drop the return parameter and just use the function
>>>> return
>>>>       value.
>>>>
>>>>       Signed-off-by: Bjorn Helgaas <bhelgaas at google.com>
>>
>>
>> This was because, at one point, we wanted to be able to differentiate
>> between the case _CCA=0 and missing _CCA in ARM64, where we would support
>> DMA (using arch-specific cache maintenance) if _CCA=0, and disable DMA when
>> missing _CCA on ARM64.
>>
>> It seems like the logic is now required (please see
>> https://www.mail-archive.com/linux-usb at vger.kernel.org/msg62735.html). So,
>> we would need the true/false return, and the coherent variable to be able to
>> differentiate between the two cases.
>>
>> Please let me know what you think.
>
> It's hard for me to comment without seeing the actual patches.  I
> think returning two values (_CCA-seen and coherent) is a confusing
> interface.

Ok. Let me simplify this and send out V2.

Thanks,
Suravee

> --
> To unsubscribe from this list: send the line "unsubscribe linux-pci" in
> the body of a message to majordomo at vger.kernel.org
> More majordomo info at  http://vger.kernel.org/majordomo-info.html
>


From andre.przywara at arm.com  Tue Aug 25 04:15:11 2015
From: andre.przywara at arm.com (Andre Przywara)
Date: Tue, 25 Aug 2015 12:15:11 +0100
Subject: [PATCH v2 10/15] KVM: arm64: add data structures to model ITS
 interrupt translation
In-Reply-To: <55CCBBBF.1080407@linaro.org>
References: <1436538111-4294-1-git-send-email-andre.przywara@arm.com>
 <1436538111-4294-11-git-send-email-andre.przywara@arm.com>
 <55CCBBBF.1080407@linaro.org>
Message-ID: <55DC4E3F.506@arm.com>

Hi Eric,

On 13/08/15 16:46, Eric Auger wrote:
> 
> On 07/10/2015 04:21 PM, Andre Przywara wrote:
>> The GICv3 Interrupt Translation Service (ITS) uses tables in memory
>> to allow a sophisticated interrupt routing. It features device tables,
>> an interrupt table per device and a table connecting "collections" to
>> actual CPUs (aka. redistributors in the GICv3 lingo).
>> Since the interrupt numbers for the LPIs are allocated quite sparsely
>> and the range can be quite huge (8192 LPIs being the minimum), using
>> bitmaps or arrays for storing information is a waste of memory.
>> We use linked lists instead, which we iterate linearily. This works
>> very well with the actual number of LPIs/MSIs in the guest being
>> quite low. Should the number of LPIs exceed the number where iterating
>> through lists seems acceptable, we can later revisit this and use more
>> efficient data structures.
>>
>> Signed-off-by: Andre Przywara <andre.przywara at arm.com>
>> ---
>>  include/kvm/arm_vgic.h  |  3 +++
>>  virt/kvm/arm/its-emul.c | 48 ++++++++++++++++++++++++++++++++++++++++++++++++
>>  2 files changed, 51 insertions(+)
>>
>> diff --git a/include/kvm/arm_vgic.h b/include/kvm/arm_vgic.h
>> index b432055..1648668 100644
>> --- a/include/kvm/arm_vgic.h
>> +++ b/include/kvm/arm_vgic.h
>> @@ -25,6 +25,7 @@
>>  #include <linux/spinlock.h>
>>  #include <linux/types.h>
>>  #include <kvm/iodev.h>
>> +#include <linux/list.h>
>>  
>>  #define VGIC_NR_IRQS_LEGACY	256
>>  #define VGIC_NR_SGIS		16
>> @@ -162,6 +163,8 @@ struct vgic_its {
>>  	u64			cbaser;
>>  	int			creadr;
>>  	int			cwriter;
>> +	struct list_head	device_list;
>> +	struct list_head	collection_list;
>>  };
>>  
>>  struct vgic_dist {
>> diff --git a/virt/kvm/arm/its-emul.c b/virt/kvm/arm/its-emul.c
>> index b498f06..7f217fa 100644
>> --- a/virt/kvm/arm/its-emul.c
>> +++ b/virt/kvm/arm/its-emul.c
>> @@ -21,6 +21,7 @@
>>  #include <linux/kvm.h>
>>  #include <linux/kvm_host.h>
>>  #include <linux/interrupt.h>
>> +#include <linux/list.h>
>>  
>>  #include <linux/irqchip/arm-gic-v3.h>
>>  #include <kvm/arm_vgic.h>
>> @@ -32,6 +33,25 @@
>>  #include "vgic.h"
>>  #include "its-emul.h"
>>  
>> +struct its_device {
>> +	struct list_head dev_list;
>> +	struct list_head itt;
>> +	u32 device_id;
>> +};
>> +
>> +struct its_collection {
>> +	struct list_head coll_list;
>> +	u32 collection_id;
>> +	u32 target_addr;
>> +};
>> +
>> +struct its_itte {
>> +	struct list_head itte_list;
>> +	struct its_collection *collection;
>> +	u32 lpi;
>> +	u32 event_id;
>> +};
>> +
>>  #define BASER_BASE_ADDRESS(x) ((x) & 0xfffffffff000ULL)
>>  
>>  /* The distributor lock is held by the VGIC MMIO handler. */
>> @@ -311,6 +331,9 @@ int vits_init(struct kvm *kvm)
>>  
>>  	spin_lock_init(&its->lock);
>>  
>> +	INIT_LIST_HEAD(&its->device_list);
>> +	INIT_LIST_HEAD(&its->collection_list);
>> +
>>  	its->enabled = false;
>>  
>>  	return -ENXIO;
>> @@ -320,11 +343,36 @@ void vits_destroy(struct kvm *kvm)
>>  {
>>  	struct vgic_dist *dist = &kvm->arch.vgic;
>>  	struct vgic_its *its = &dist->its;
>> +	struct its_device *dev;
>> +	struct its_itte *itte;
>> +	struct list_head *dev_cur, *dev_temp;
>> +	struct list_head *cur, *temp;
>>  
>>  	if (!vgic_has_its(kvm))
>>  		return;
>>  
>> +	if (!its->device_list.next)
> Why not using list_empty? But I think I would simply remove this since
> the empty case if handle below...

list_empty() requires the list to be initialized before. This check here
is to detect that map_resources was never called (this is only done on
the first VCPU run) and thus device_list is basically still all zeroes.
If we abort the guest without ever running a VCPU (for instance because
some initialization failed), we call vits_destroy() anyway (because this
is called when tearing down the VGIC device).
So the check is here to detect early that vits_destroy() has been called
without the ITS ever been fully initialized. This fixed a real bug when
the guest start was aborted before the ITS was ever used.
I will add a comment to make this clear.

>> +		return;
>> +
>> +	spin_lock(&its->lock);
>> +	list_for_each_safe(dev_cur, dev_temp, &its->device_list) {
>> +		dev = container_of(dev_cur, struct its_device, dev_list);
> isn't the usage of list_for_each_entry_safe more synthetic here?

If I got this correctly, we need the _safe variant if we want to remove
the list item within the loop. Or am I missing something here?

Cheers,
Andre.


>> +		list_for_each_safe(cur, temp, &dev->itt) {
>> +			itte = (container_of(cur, struct its_itte, itte_list));
> same
> 
> Eric
>> +			list_del(cur);
>> +			kfree(itte);
>> +		}
>> +		list_del(dev_cur);
>> +		kfree(dev);
>> +	}
>> +
>> +	list_for_each_safe(cur, temp, &its->collection_list) {
>> +		list_del(cur);
>> +		kfree(container_of(cur, struct its_collection, coll_list));
>> +	}
>> +
>>  	kfree(dist->pendbaser);
>>  
>>  	its->enabled = false;
>> +	spin_unlock(&its->lock);
>>  }
>>
> 


From sudeep.holla at arm.com  Tue Aug 25 04:17:20 2015
From: sudeep.holla at arm.com (Sudeep Holla)
Date: Tue, 25 Aug 2015 12:17:20 +0100
Subject: [PATCH v1 1/3] dt-bindings: mailbox: Document Hi6220 mailbox
 driver
In-Reply-To: <1439977055-1747-2-git-send-email-leo.yan@linaro.org>
References: <1439977055-1747-1-git-send-email-leo.yan@linaro.org>
 <1439977055-1747-2-git-send-email-leo.yan@linaro.org>
Message-ID: <55DC4EC0.4060301@arm.com>



On 19/08/15 10:37, Leo Yan wrote:
> Document the new compatible for Hisilicon Hi6220 mailbox driver.
>
> Signed-off-by: Leo Yan <leo.yan at linaro.org>
> ---
>   .../bindings/mailbox/hisilicon,hi6220-mailbox.txt  | 57 ++++++++++++++++++++++
>   1 file changed, 57 insertions(+)
>   create mode 100644 Documentation/devicetree/bindings/mailbox/hisilicon,hi6220-mailbox.txt
>
> diff --git a/Documentation/devicetree/bindings/mailbox/hisilicon,hi6220-mailbox.txt b/Documentation/devicetree/bindings/mailbox/hisilicon,hi6220-mailbox.txt
> new file mode 100644
> index 0000000..3dfb0b0
> --- /dev/null
> +++ b/Documentation/devicetree/bindings/mailbox/hisilicon,hi6220-mailbox.txt
> @@ -0,0 +1,57 @@
> +Hisilicon Hi6220 Mailbox Driver
> +===============================
> +
> +Hisilicon Hi6220 mailbox supports up to 32 channels. Each channel
> +is unidirectional with a maximum message size of 8 words. I/O is
> +performed using register access (there is no DMA) and the cell
> +raises an interrupt when messages are received.
> +
> +Mailbox Device Node:
> +====================
> +
> +Required properties:
> +--------------------
> +- compatible:		Shall be "hisilicon,hi6220-mbox"
> +- reg:			Contains the mailbox register address range (base
> +			address and length); the first item is for IPC
> +			registers, the second item is shared buffer for
> +			slots.

Not sure if the shared buffer needs to be part of the controller binding
as it's not related to it. It's just agreement between the endpoints of
this mailbox on particular SoC and IMO has to part of the client binding.

Regards,
Sudeep


From geert at linux-m68k.org  Tue Aug 25 04:21:04 2015
From: geert at linux-m68k.org (Geert Uytterhoeven)
Date: Tue, 25 Aug 2015 13:21:04 +0200
Subject: [PATCH 9/9] ARM: software-based priviledged-no-access support
In-Reply-To: <20150825104422.GO7557@n2100.arm.linux.org.uk>
References: <20150821133043.GV7557@n2100.arm.linux.org.uk>
 <E1ZSmQG-0002za-E3@rmk-PC.arm.linux.org.uk>
 <CAMuHMdVMka2mt5pFpnXfLRY2M3Sj_71MgEpthOia2C99RaP_DA@mail.gmail.com>
 <20150825104422.GO7557@n2100.arm.linux.org.uk>
Message-ID: <CAMuHMdWCLcDS=64m0J09KJJ4bDtgZ1Yvq8rw7u9FE0vZkKT2cw@mail.gmail.com>

Hi Russell,

On Tue, Aug 25, 2015 at 12:44 PM, Russell King - ARM Linux
<linux at arm.linux.org.uk> wrote:
> On Tue, Aug 25, 2015 at 12:32:51PM +0200, Geert Uytterhoeven wrote:
>> This patch, which is now in arm-soc/for-next, breaks shmobile_defconfig
>> on r8a7791/koelsch, which has a dual core CA15:
>>
>>     [ ok ] Configuring network interfaces...done.
>>     Unhandled fault: page domain fault (0x01b) at 0xbe8e6120
>>     pgd = edbb0000
>>     [be8e6120] *pgd=6da77831, *pte=bf4d075f, *ppte=bf4d0c7f
>>     Internal error: : 1b [#1] SMP ARM
>>     CPU: 1 PID: 1629 Comm: ntpdate Not tainted
>> 4.2.0-rc8-06444-g3c24fd89c9421db1 #31
>>     9
>>     Hardware name: Generic R8A7791 (Flattened Device Tree)
>>     task: ed883a80 ti: ed41c000 task.ti: ed41c000
>>     PC is at csum_partial_copy_from_user+0x28/0x3d8
>>     LR is at csum_and_copy_from_iter+0x334/0x4c0
>>     pc : [<c04ba510>]    lr : [<c01c82e8>]    psr: 000f0013
>>     sp : ed41db00  ip : 00000020  fp : ed41db6c
>>     r10: ed41ddc0  r9 : 00000027  r8 : ed41dc20
>>     r7 : 00000027  r6 : eda52653  r5 : ed41dec8  r4 : 00000000
>>     r3 : 00000000  r2 : 00000027  r1 : eda5262c  r0 : be8e6120
>>     Flags: nzcv  IRQs on  FIQs on  Mode SVC_32  ISA ARM  Segment none
>>     Control: 10c5307d  Table: 6dbb006a  DAC: 00000051
>>     Process ntpdate (pid: 1629, stack limit = 0xed41c210)
>
> Thanks.  I wonder what's different about your ntpdate that triggers
> this, and why all my iMX6 behave fine, which have desktop-like ubuntu
> installs on (of two different versions.)

It's ntpdate 1:4.2.6.p5+dfsg-7 from desktop-like Debian jessie.

But I get similar dumps during boot up from rpc.idmapd (SyS_send),
rsyslogd (SyS_send), and from sshd (SyS_write) when trying to log in.

Gr{oetje,eeting}s,

                        Geert

--
Geert Uytterhoeven -- There's lots of Linux beyond ia32 -- geert at linux-m68k.org

In personal conversations with technical people, I call myself a hacker. But
when I'm talking to journalists I just say "programmer" or something like that.
                                -- Linus Torvalds


From l.stach at pengutronix.de  Tue Aug 25 04:24:05 2015
From: l.stach at pengutronix.de (Lucas Stach)
Date: Tue, 25 Aug 2015 13:24:05 +0200
Subject: [PATCH] ARM: enable imprecise aborts during early kernel startup
Message-ID: <1440501845-25723-1-git-send-email-l.stach@pengutronix.de>

From: Fabrice Gasnier <fabrice.gasnier at st.com>

This patch adds imprecise abort enable/disable macros and uses them to
enable imprecise aborts early when starting the kernel.

This helps in tracking down the real cause for such imprecise abort, as
they are handled as soon as they occur. Until now those aborts would
only be enabled when entering the userspace and as a consequence crash
the first userspace process if any abort had been raised during kernel
startup.

Signed-off-by: Fabrice Gasnier <fabrice.gasnier at st.com>
Signed-off-by: Lucas Stach <l.stach at pengutronix.de>
---
lst:
- rebased to current kernel
- reworked commit message
- moved abort enable to point where handlers could run
  (tested by hacking bootloader to leave a dangling abort behind)
---
 arch/arm/include/asm/irqflags.h | 10 ++++++++++
 arch/arm/kernel/smp.c           |  1 +
 arch/arm/mm/mmu.c               |  3 +++
 3 files changed, 14 insertions(+)

diff --git a/arch/arm/include/asm/irqflags.h b/arch/arm/include/asm/irqflags.h
index 43908146a5cf..e6b70d9d084e 100644
--- a/arch/arm/include/asm/irqflags.h
+++ b/arch/arm/include/asm/irqflags.h
@@ -54,6 +54,14 @@ static inline void arch_local_irq_disable(void)
 
 #define local_fiq_enable()  __asm__("cpsie f	@ __stf" : : : "memory", "cc")
 #define local_fiq_disable() __asm__("cpsid f	@ __clf" : : : "memory", "cc")
+
+#ifndef CONFIG_CPU_V7M
+#define local_abt_enable()  __asm__("cpsie a	@ __sta" : : : "memory", "cc")
+#define local_abt_disable() __asm__("cpsid a	@ __cla" : : : "memory", "cc")
+#else
+#define local_abt_enable()	do { } while (0)
+#define local_abt_disable()	do { } while (0)
+#endif
 #else
 
 /*
@@ -136,6 +144,8 @@ static inline void arch_local_irq_disable(void)
 	: "memory", "cc");					\
 	})
 
+#define local_abt_enable()	do { } while (0)
+#define local_abt_disable()	do { } while (0)
 #endif
 
 /*
diff --git a/arch/arm/kernel/smp.c b/arch/arm/kernel/smp.c
index 3d6b7821cff8..f6f0a76ee573 100644
--- a/arch/arm/kernel/smp.c
+++ b/arch/arm/kernel/smp.c
@@ -385,6 +385,7 @@ asmlinkage void secondary_start_kernel(void)
 
 	local_irq_enable();
 	local_fiq_enable();
+	local_abt_enable();
 
 	/*
 	 * OK, it's off to the idle thread for us
diff --git a/arch/arm/mm/mmu.c b/arch/arm/mm/mmu.c
index 870838a46d52..862caeadcaf0 100644
--- a/arch/arm/mm/mmu.c
+++ b/arch/arm/mm/mmu.c
@@ -1319,6 +1319,9 @@ static void __init devicemaps_init(const struct machine_desc *mdesc)
 	 */
 	local_flush_tlb_all();
 	flush_cache_all();
+
+	/* Enable asynchronous aborts */
+	local_abt_enable();
 }
 
 static void __init kmap_init(void)
-- 
2.4.6



From cyrille.pitchen at atmel.com  Tue Aug 25 04:24:20 2015
From: cyrille.pitchen at atmel.com (Cyrille Pitchen)
Date: Tue, 25 Aug 2015 13:24:20 +0200
Subject: [PATCH linux-next v4 5/5] mtd: atmel-quadspi: add driver for
 Atmel QSPI controller
In-Reply-To: <A765B125120D1346A63912DDE6D8B6310BF47A26@NTXXIAMBX02.xacn.micron.com>
References: <cover.1440410236.git.cyrille.pitchen@atmel.com>
 <bf368fc101f38db231131b69eff0863210f2b01c.1440410236.git.cyrille.pitchen@atmel.com>
 <A765B125120D1346A63912DDE6D8B6310BF47A26@NTXXIAMBX02.xacn.micron.com>
Message-ID: <55DC5064.6050500@atmel.com>

Hi!

Le 25/08/2015 03:44, Bean Huo ??? (beanhuo) a ?crit :
> 
>> +	nor->read_reg = atmel_qspi_read_reg;
>> +	nor->write_reg = atmel_qspi_write_reg;
>> +	nor->read = atmel_qspi_read;
>> +	nor->write = atmel_qspi_write;
>> +	nor->erase = atmel_qspi_erase;
>> +	nor->set_protocol = atmel_qspi_set_protocol;
> 
> This is very good, the structure of spi_nor should add a hook function to notify spi controller 
> That spi nor transfer protocol already changed.
> 
>> +
>> +	if (of_modalias_node(child, modalias, sizeof(modalias)) < 0) {
>> +		err = -ENODEV;
>> +		goto release_channel;
>> +	}
>> +
>> +	err = of_property_read_u32(child, "spi-max-frequency", &aq->clk_rate);
>> +	if (err < 0)
>> +		goto release_channel;
>> +
>> +	err = atmel_qspi_init(aq);
>> +	if (err)
>> +		goto release_channel;
>> +
>> +	nor->dev->of_node = child;
>> +	err = spi_nor_scan(nor, modalias, SPI_NOR_QUAD);
>> 		goto release_channel;
>> +
> 
> 
> .......
> 
>> static inline struct spi_nor *mtd_to_spi_nor(struct mtd_info *mtd)  {
>  	return mtd->priv;
>> @@ -944,6 +960,11 @@ static int micron_quad_enable(struct spi_nor *nor)
>> 		return ret;
>> 	}
>>
>> +	/* switch protocol to Quad CMD 4-4-4 */
>> +	ret = spi_nor_set_protocol(nor, SPI_PROTO_4_4_4);
>> +	if (ret)
>> +		return ret;
>> +
> 
> This make sense,from spi nor side,once its protocol being changed,
> Mtd layer must notify this status to spi nor controller immediately,
> And spi nor controller also should re-adjust its protocol.
> Otherwise, following reading SR operation will fail. 
> 
>>
>> 	ret = spi_nor_wait_till_ready(nor);
>> 	if (ret)
>> 		return ret;
> 
> If my ack has any value in here, feel free to add it.
> 
> Acked-by: Bean Huo <beanhuo at micron.com>
> 

Since your comments deal with the protocol change, I'll add your ack to the
first patch of the series:
"mtd: spi-nor: notify (Q)SPI controller about protocol change"

Thanks for your review!

Best regards,

Cyrille



From marc.zyngier at arm.com  Tue Aug 25 04:25:33 2015
From: marc.zyngier at arm.com (Marc Zyngier)
Date: Tue, 25 Aug 2015 12:25:33 +0100
Subject: [PATCH v5 3/5] pci: altera: Add Altera PCIe MSI driver
In-Reply-To: <1440495348-2666-4-git-send-email-lftan@altera.com>
References: <1440495348-2666-1-git-send-email-lftan@altera.com>
 <1440495348-2666-4-git-send-email-lftan@altera.com>
Message-ID: <55DC50AD.1050607@arm.com>

On 25/08/15 10:35, Ley Foon Tan wrote:
> This patch adds Altera PCIe MSI driver. This soft IP supports configurable
> number of vectors, which is a dts parameter.
> 
> Signed-off-by: Ley Foon Tan <lftan at altera.com>
> ---
>  drivers/pci/host/Kconfig           |   8 +
>  drivers/pci/host/Makefile          |   1 +
>  drivers/pci/host/pcie-altera-msi.c | 322 +++++++++++++++++++++++++++++++++++++
>  3 files changed, 331 insertions(+)
>  create mode 100644 drivers/pci/host/pcie-altera-msi.c
> 
> diff --git a/drivers/pci/host/Kconfig b/drivers/pci/host/Kconfig
> index 4b4754a..d28cc6d 100644
> --- a/drivers/pci/host/Kconfig
> +++ b/drivers/pci/host/Kconfig
> @@ -152,4 +152,12 @@ config PCIE_ALTERA
>  	  Say Y here if you want to enable PCIe controller support for Altera
>  	  SoCFPGA family of SoCs.
>  
> +config PCIE_ALTERA_MSI
> +	bool "Altera PCIe MSI feature"
> +	depends on PCI_MSI
> +	select PCI_MSI_IRQ_DOMAIN
> +	help
> +	  Say Y here if you want PCIe MSI support for the Altera SocFPGA SoC.
> +	  This MSI driver supports Altera MSI to GIC controller IP.
> +
>  endmenu
> diff --git a/drivers/pci/host/Makefile b/drivers/pci/host/Makefile
> index 6954f76..6c4913d 100644
> --- a/drivers/pci/host/Makefile
> +++ b/drivers/pci/host/Makefile
> @@ -18,3 +18,4 @@ obj-$(CONFIG_PCIE_IPROC) += pcie-iproc.o
>  obj-$(CONFIG_PCIE_IPROC_PLATFORM) += pcie-iproc-platform.o
>  obj-$(CONFIG_PCIE_IPROC_BCMA) += pcie-iproc-bcma.o
>  obj-$(CONFIG_PCIE_ALTERA) += pcie-altera.o
> +obj-$(CONFIG_PCIE_ALTERA_MSI) += pcie-altera-msi.o
> diff --git a/drivers/pci/host/pcie-altera-msi.c b/drivers/pci/host/pcie-altera-msi.c
> new file mode 100644
> index 0000000..d3ad96f
> --- /dev/null
> +++ b/drivers/pci/host/pcie-altera-msi.c
> @@ -0,0 +1,322 @@
> +/*
> + * Copyright Altera Corporation (C) 2013-2015. All rights reserved
> + *
> + * This program is free software; you can redistribute it and/or modify it
> + * under the terms and conditions of the GNU General Public License,
> + * version 2, as published by the Free Software Foundation.
> + *
> + * This program is distributed in the hope 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.
> + *
> + * You should have received a copy of the GNU General Public License along with
> + * this program.  If not, see <http://www.gnu.org/licenses/>.
> + */
> +#include <linux/interrupt.h>
> +#include <linux/irqchip/chained_irq.h>
> +#include <linux/module.h>
> +#include <linux/msi.h>
> +#include <linux/of_address.h>
> +#include <linux/of_irq.h>
> +#include <linux/of_pci.h>
> +#include <linux/pci.h>
> +#include <linux/platform_device.h>
> +#include <linux/slab.h>
> +
> +#define MSI_STATUS		0x0
> +#define MSI_ERROR		0x4
> +#define MSI_INTMASK		0x8
> +
> +#define MAX_MSI_VECTORS		32
> +struct altera_msi {
> +	DECLARE_BITMAP(used, MAX_MSI_VECTORS);
> +	struct mutex		lock;	/* proctect used variable */
> +	struct platform_device	*pdev;
> +	struct irq_domain		*msi_domain;
> +	struct irq_domain		*inner_domain;
> +	void __iomem		*csr_base;
> +	void __iomem		*vector_base;
> +	phys_addr_t		vector_phy;
> +	u32			num_of_vectors;
> +	int			irq;
> +};
> +
> +static inline void msi_writel(struct altera_msi *msi, u32 value, u32 reg)
> +{
> +	writel_relaxed(value, msi->csr_base + reg);
> +}
> +
> +static inline u32 msi_readl(struct altera_msi *msi, u32 reg)
> +{
> +	return readl_relaxed(msi->csr_base + reg);
> +}
> +
> +static void altera_msi_isr(unsigned int irq, struct irq_desc *desc)
> +{
> +	struct irq_chip *chip = irq_desc_get_chip(desc);
> +	struct altera_msi *msi;
> +	unsigned long status;
> +	u32 num_of_vectors;
> +	u32 bit;
> +	u32 virq;
> +
> +	chained_irq_enter(chip, desc);
> +	msi = irq_desc_get_handler_data(desc);
> +	num_of_vectors = msi->num_of_vectors;
> +
> +	do {
> +		status = msi_readl(msi, MSI_STATUS);
> +		if (!status)
> +			break;
> +
> +		do {
> +			bit = find_first_bit(&status, num_of_vectors);
> +			/* Dummy read from vector to clear the interrupt */
> +			readl_relaxed(msi->vector_base + (bit * sizeof(u32)));
> +
> +			virq = irq_find_mapping(msi->inner_domain, bit);
> +			if (virq && test_bit(bit, msi->used))

I still wonder under which circumstances you can obtain a valid virq and
yet not find the bit in the bitmap. Unless you have a scenario when that
can happen, I suggest you remove that test.

> +				generic_handle_irq(virq);
> +			else
> +				dev_err(&msi->pdev->dev, "unexpected MSI\n");
> +
> +			/* Clear the bit from status and repeat without reading
> +			 * again status register. */
> +			__clear_bit(bit, &status);
> +		} while (status);
> +	} while (1);

I think this could be rewritten as:

while ((status = msi_readl(msi, MSI_STATUS)) != 0) {
	for_each_set_bit(bit, &status, msi->num_of_vectors) {
		/* Dummy read from vector to clear the interrupt */
		readl_relaxed(msi->vector_base + (bit * sizeof(u32)));

		virq = irq_find_mapping(msi->inner_domain, bit);
		if (virq)
			generic_handle_irq(virq);
		else
			dev_err(&msi->pdev->dev, "unexpected MSI\n");
	}
}

which saves the __clear_bit call and the double test of status which I
find a bit awkward.

> +
> +	chained_irq_exit(chip, desc);
> +}
> +
> +static struct irq_chip altera_msi_irq_chip = {
> +	.name = "Altera PCIe MSI",
> +	.irq_enable = pci_msi_unmask_irq,
> +	.irq_disable = pci_msi_mask_irq,
> +	.irq_mask = pci_msi_mask_irq,
> +	.irq_unmask = pci_msi_unmask_irq,

Why do you have both enable/disable and unmask/mask? Specially pointing
to the same function? This is completely useless. Just stick with
unmask/mask and remove the enable/disable.

> +};
> +
> +static struct msi_domain_info altera_msi_domain_info = {
> +	.flags	= (MSI_FLAG_USE_DEF_DOM_OPS | MSI_FLAG_USE_DEF_CHIP_OPS |
> +		     MSI_FLAG_PCI_MSIX),
> +	.chip	= &altera_msi_irq_chip,
> +};
> +
> +static void altera_compose_msi_msg(struct irq_data *data, struct msi_msg *msg)
> +{
> +	struct altera_msi *msi = irq_data_get_irq_chip_data(data);
> +	phys_addr_t addr = msi->vector_phy + (data->hwirq * sizeof(u32));
> +
> +	msg->address_lo = lower_32_bits(addr);
> +	msg->address_hi = upper_32_bits(addr);
> +	msg->data = data->hwirq;
> +
> +	dev_dbg(&msi->pdev->dev, "msi#%d address_lo 0x%x address_hi 0x%x\n",
> +		(int)data->hwirq, msg->address_hi, msg->address_lo);
> +}
> +
> +static int altera_msi_set_affinity(struct irq_data *irq_data,
> +				   const struct cpumask *mask, bool force)
> +{
> +	 return -EINVAL;
> +}
> +
> +static struct irq_chip altera_msi_bottom_irq_chip = {
> +	.name			= "Altera MSI",
> +	.irq_compose_msi_msg	= altera_compose_msi_msg,
> +	.irq_set_affinity	= altera_msi_set_affinity,
> +};
> +
> +static int altera_irq_domain_alloc(struct irq_domain *domain, unsigned int virq,
> +				   unsigned int nr_irqs, void *args)
> +{
> +	struct altera_msi *msi = domain->host_data;
> +	unsigned long bit;
> +	u32 mask;
> +
> +	WARN_ON(nr_irqs != 1);
> +	mutex_lock(&msi->lock);
> +
> +	bit = find_first_zero_bit(msi->used, msi->num_of_vectors);
> +	if (bit >= msi->num_of_vectors)
> +		return -ENOSPC;
> +
> +	set_bit(bit, msi->used);
> +
> +	mutex_unlock(&msi->lock);
> +
> +	irq_domain_set_info(domain, virq, bit, &altera_msi_bottom_irq_chip,
> +			    domain->host_data, handle_simple_irq,
> +			    NULL, NULL);
> +	set_irq_flags(virq, IRQF_VALID);
> +
> +	mask = msi_readl(msi, MSI_INTMASK);
> +	mask |= 1 << bit;
> +	msi_writel(msi, mask, MSI_INTMASK);
> +
> +	return 0;
> +}
> +
> +static void altera_irq_domain_free(struct irq_domain *domain,
> +				   unsigned int virq, unsigned int nr_irqs)
> +{
> +	struct irq_data *d = irq_domain_get_irq_data(domain, virq);
> +	struct altera_msi *msi = irq_data_get_irq_chip_data(d);
> +	u32 mask;
> +
> +	mutex_lock(&msi->lock);
> +
> +	if (!test_bit(d->hwirq, msi->used)) {
> +		dev_err(&msi->pdev->dev, "trying to free unused MSI#%lu\n",
> +			d->hwirq);
> +	} else {
> +		__clear_bit(d->hwirq, msi->used);
> +		mask = msi_readl(msi, MSI_INTMASK);
> +		mask &= ~(1 << d->hwirq);
> +		msi_writel(msi, mask, MSI_INTMASK);
> +	}
> +
> +	mutex_unlock(&msi->lock);
> +}
> +
> +static const struct irq_domain_ops msi_domain_ops = {
> +	.alloc	= altera_irq_domain_alloc,
> +	.free	= altera_irq_domain_free,
> +};
> +
> +static int altera_allocate_domains(struct altera_msi *msi)
> +{
> +	msi->inner_domain = irq_domain_add_linear(NULL, msi->num_of_vectors,
> +					     &msi_domain_ops, msi);
> +	if (!msi->inner_domain) {
> +		dev_err(&msi->pdev->dev, "failed to create IRQ domain\n");
> +		return -ENOMEM;
> +	}
> +
> +	msi->msi_domain = pci_msi_create_irq_domain(msi->pdev->dev.of_node,
> +				&altera_msi_domain_info, msi->inner_domain);
> +	if (!msi->msi_domain) {
> +		dev_err(&msi->pdev->dev, "failed to create MSI domain\n");
> +		irq_domain_remove(msi->inner_domain);
> +		return -ENOMEM;
> +	}
> +
> +	return 0;
> +}
> +
> +static void altera_free_domains(struct altera_msi *msi)
> +{
> +	irq_domain_remove(msi->msi_domain);
> +	irq_domain_remove(msi->inner_domain);
> +}
> +
> +static int altera_msi_remove(struct platform_device *pdev)
> +{
> +	struct altera_msi *msi = platform_get_drvdata(pdev);
> +
> +	msi_writel(msi, 0, MSI_INTMASK);
> +	irq_set_chained_handler(msi->irq, NULL);
> +	irq_set_handler_data(msi->irq, NULL);
> +
> +	altera_free_domains(msi);
> +
> +	platform_set_drvdata(pdev, NULL);
> +	return 0;
> +}
> +
> +static int altera_msi_probe(struct platform_device *pdev)
> +{
> +	struct altera_msi *msi;
> +	struct device_node *np = pdev->dev.of_node;
> +	struct resource *res;
> +	int ret;
> +
> +	msi = devm_kzalloc(&pdev->dev, sizeof(struct altera_msi),
> +			   GFP_KERNEL);
> +	if (!msi)
> +		return -ENOMEM;
> +
> +	mutex_init(&msi->lock);
> +	msi->pdev = pdev;
> +
> +	res = platform_get_resource_byname(pdev, IORESOURCE_MEM, "csr");
> +	if (!res) {
> +		dev_err(&pdev->dev,
> +			"no csr memory resource defined\n");
> +		return -ENODEV;
> +	}
> +
> +	msi->csr_base = devm_ioremap_resource(&pdev->dev, res);
> +	if (IS_ERR(msi->csr_base)) {
> +		dev_err(&pdev->dev, "failed to map csr memory\n");
> +		return PTR_ERR(msi->csr_base);
> +	}
> +
> +	res = platform_get_resource_byname(pdev, IORESOURCE_MEM,
> +					   "vector_slave");
> +	if (!res) {
> +		dev_err(&pdev->dev,
> +			"no vector_slave memory resource defined\n");
> +		return -ENODEV;
> +	}
> +
> +	msi->vector_base = devm_ioremap_resource(&pdev->dev, res);
> +	if (IS_ERR(msi->vector_base)) {
> +		dev_err(&pdev->dev, "failed to map vector_slave memory\n");
> +		return PTR_ERR(msi->vector_base);
> +	}
> +
> +	msi->vector_phy = res->start;
> +
> +	if (of_property_read_u32(np, "num-vectors", &msi->num_of_vectors)) {
> +		dev_err(&pdev->dev, "failed to parse the number of vectors\n");
> +		return -EINVAL;
> +	}
> +
> +	ret = altera_allocate_domains(msi);
> +	if (ret)
> +		return ret;
> +
> +	msi->irq = platform_get_irq(pdev, 0);
> +	if (msi->irq <= 0) {
> +		dev_err(&pdev->dev, "failed to map IRQ: %d\n", msi->irq);
> +		ret = -ENODEV;
> +		goto err;
> +	}
> +
> +	irq_set_chained_handler_and_data(msi->irq, altera_msi_isr, msi);
> +	platform_set_drvdata(pdev, msi);
> +
> +	return 0;
> +
> +err:
> +	altera_msi_remove(pdev);
> +	return ret;
> +}
> +
> +static const struct of_device_id altera_msi_of_match[] = {
> +	{ .compatible = "altr,msi-1.0", NULL },
> +	{ },
> +};
> +
> +static struct platform_driver altera_msi_driver = {
> +	.driver = {
> +		.name = "altera-msi",
> +		.of_match_table = altera_msi_of_match,
> +	},
> +	.probe = altera_msi_probe,
> +	.remove = altera_msi_remove,
> +};
> +
> +static int __init altera_msi_init(void)
> +{
> +	return platform_driver_register(&altera_msi_driver);
> +}
> +
> +subsys_initcall(altera_msi_init);
> +
> +MODULE_AUTHOR("Ley Foon Tan <lftan at altera.com>");
> +MODULE_DESCRIPTION("Altera PCIe MSI support");
> +MODULE_LICENSE("GPL v2");
> 

Once you've fixed the above issues, you can add my:

Reviewed-by: Marc Zyngier <marc.zyngier at arm.com>

	M.
-- 
Jazz is not dead. It just smells funny...


From mchehab at osg.samsung.com  Tue Aug 25 04:32:36 2015
From: mchehab at osg.samsung.com (Mauro Carvalho Chehab)
Date: Tue, 25 Aug 2015 08:32:36 -0300
Subject: [PATCH v7 25/44] [media] replace all occurrences of
 MEDIA_ENT_T_DEVNODE_V4L
In-Reply-To: <55DC340C.8030503@xs4all.nl>
References: <cover.1440359643.git.mchehab@osg.samsung.com>
 <23e2f9440a259e1162e15dba7e6261dbc4c521c6.1440359643.git.mchehab@osg.samsung.com>
 <55DC340C.8030503@xs4all.nl>
Message-ID: <20150825083236.37659d22@recife.lan>

Em Tue, 25 Aug 2015 11:23:24 +0200
Hans Verkuil <hverkuil at xs4all.nl> escreveu:

> On 08/23/15 22:17, Mauro Carvalho Chehab wrote:
> > Now that interfaces and entities are distinct, it makes no sense
> > of keeping something named as MEDIA_ENT_T_DEVNODE.
> > 
> > This change was done with this script:
> > 
> > 	for i in $(git grep -l MEDIA_ENT_T|grep -v uapi/linux/media.h); do sed s,MEDIA_ENT_T_DEVNODE_V4L,MEDIA_ENT_T_V4L2_VIDEO, <$i >a && mv a $i; done
> > 
> > Signed-off-by: Mauro Carvalho Chehab <mchehab at osg.samsung.com>
> > 
> > diff --git a/Documentation/DocBook/media/v4l/media-ioc-enum-entities.xml b/Documentation/DocBook/media/v4l/media-ioc-enum-entities.xml
> > index 5872f8bbf774..910243d4edb8 100644
> > --- a/Documentation/DocBook/media/v4l/media-ioc-enum-entities.xml
> > +++ b/Documentation/DocBook/media/v4l/media-ioc-enum-entities.xml
> > @@ -183,7 +183,7 @@
> >  	    <entry>Unknown device node</entry>
> >  	  </row>
> >  	  <row>
> > -	    <entry><constant>MEDIA_ENT_T_DEVNODE_V4L</constant></entry>
> > +	    <entry><constant>MEDIA_ENT_T_V4L2_VIDEO</constant></entry>
> >  	    <entry>V4L video, radio or vbi device node</entry>
> >  	  </row>
> 
> OK, this makes no sense and that ties in with my confusion of the previous patch.
> 
> These are not device nodes, in the new scheme these are DMA entities (I know,
> naming TDB) that have an associated interface.

Yes. Well, DMA is a bad name. It won't cover USB devices, where the DMA
engine is outside the V4L2 drivers, nor it would work for RDS radio data,
with may not need any DMA at all on no-USB devices, as the data flows via
the I2C bus.

> I think a much better approach would be to add entity type(s) for such DMA
> engines in patch 24, then use that new name in existing drivers and split
> up the existing DEVNODE_V4L media_entity into a media_entity and a
> media_intf_devnode:

Sorry, but I didn't get. That's precisely what I did ;)

> The current media_entity defined in struct video_device has to be replaced
> by media_intf_devnode, and the DMA entity has to be added as a new entity
> to these drivers.

If I do this way, it would break bisectability. I need first to replace
the names, but keep them as entities, and then add the interfaces.

> 
> This reflects these two action items from our meeting:
> 
> Migration: add v4l-subdev media_interface: Laurent
> Migration: add explicit DMA Engine entity: Laurent
> 
> Unless Laurent says differently I think this is something you'll have to
> do given Laurent's workload.

Yes. The above action items are covered on this series.

What patch 24 does is to define the new namespace, moving the legacy
symbols kept due to backward compatibility on a separate part of the
header.

Then, patches 25-38 replace the occurrences of the deprecated names
by the new ones.

Nothing is touched at the interfaces yet, to avoid breaking bisectability.

Then, the next patches add interfaces support at the V4L side.

> I think doing this at this stage of the patch series is crucial, otherwise
> the remaining patches really make no sense.
> 
> I'll skip reviewing patches 26-38 for now.
> 
> Regards,
> 
> 	Hans
> 
> >  	  <row>
> > diff --git a/drivers/media/platform/xilinx/xilinx-dma.c b/drivers/media/platform/xilinx/xilinx-dma.c
> > index 92e8116dc28f..88cd789cdaf7 100644
> > --- a/drivers/media/platform/xilinx/xilinx-dma.c
> > +++ b/drivers/media/platform/xilinx/xilinx-dma.c
> > @@ -193,7 +193,7 @@ static int xvip_pipeline_validate(struct xvip_pipeline *pipe,
> >  	while ((entity = media_entity_graph_walk_next(&graph))) {
> >  		struct xvip_dma *dma;
> >  
> > -		if (entity->type != MEDIA_ENT_T_DEVNODE_V4L)
> > +		if (entity->type != MEDIA_ENT_T_V4L2_VIDEO)
> >  			continue;
> >  
> >  		dma = to_xvip_dma(media_entity_to_video_device(entity));
> > diff --git a/drivers/media/v4l2-core/v4l2-dev.c b/drivers/media/v4l2-core/v4l2-dev.c
> > index 71a1b93b0790..44b330589787 100644
> > --- a/drivers/media/v4l2-core/v4l2-dev.c
> > +++ b/drivers/media/v4l2-core/v4l2-dev.c
> > @@ -912,7 +912,7 @@ int __video_register_device(struct video_device *vdev, int type, int nr,
> >  	/* Part 5: Register the entity. */
> >  	if (vdev->v4l2_dev->mdev &&
> >  	    vdev->vfl_type != VFL_TYPE_SUBDEV) {
> > -		vdev->entity.type = MEDIA_ENT_T_DEVNODE_V4L;
> > +		vdev->entity.type = MEDIA_ENT_T_V4L2_VIDEO;
> >  		vdev->entity.name = vdev->name;
> >  		vdev->entity.info.dev.major = VIDEO_MAJOR;
> >  		vdev->entity.info.dev.minor = vdev->minor;
> > diff --git a/drivers/media/v4l2-core/v4l2-subdev.c b/drivers/media/v4l2-core/v4l2-subdev.c
> > index 83615b8fb46a..e6e1115d8215 100644
> > --- a/drivers/media/v4l2-core/v4l2-subdev.c
> > +++ b/drivers/media/v4l2-core/v4l2-subdev.c
> > @@ -535,7 +535,7 @@ v4l2_subdev_link_validate_get_format(struct media_pad *pad,
> >  		return v4l2_subdev_call(sd, pad, get_fmt, NULL, fmt);
> >  	}
> >  
> > -	WARN(pad->entity->type != MEDIA_ENT_T_DEVNODE_V4L,
> > +	WARN(pad->entity->type != MEDIA_ENT_T_V4L2_VIDEO,
> >  	     "Driver bug! Wrong media entity type 0x%08x, entity %s\n",
> >  	     pad->entity->type, pad->entity->name);
> >  
> > 


From sudeep.holla at arm.com  Tue Aug 25 04:36:12 2015
From: sudeep.holla at arm.com (Sudeep Holla)
Date: Tue, 25 Aug 2015 12:36:12 +0100
Subject: [PATCH v1 3/3] arm64: dts: add Hi6220 mailbox node
In-Reply-To: <1439977055-1747-4-git-send-email-leo.yan@linaro.org>
References: <1439977055-1747-1-git-send-email-leo.yan@linaro.org>
 <1439977055-1747-4-git-send-email-leo.yan@linaro.org>
Message-ID: <55DC532C.3020005@arm.com>



On 19/08/15 10:37, Leo Yan wrote:
> On Hi6220, below memory regions in DDR have specific purpose:
>
>    0x05e0,0000 - 0x05ef,ffff: For MCU firmware using at runtime;
>    0x0740,f000 - 0x0740,ffff: For MCU firmware's section;
>    0x06df,f000 - 0x06df,ffff: For mailbox message data.
>

Unless I am reading the DTS file completely wrong, I don't think the 
above memory regions are in DDR as per the memory node.

> This patch reserves these memory regions and add device node for
> mailbox in dts.
>
> Signed-off-by: Leo Yan <leo.yan at linaro.org>
> ---
>   arch/arm64/boot/dts/hisilicon/hi6220-hikey.dts | 20 +++++++++++++++++---
>   arch/arm64/boot/dts/hisilicon/hi6220.dtsi      |  8 ++++++++
>   2 files changed, 25 insertions(+), 3 deletions(-)
>
> diff --git a/arch/arm64/boot/dts/hisilicon/hi6220-hikey.dts b/arch/arm64/boot/dts/hisilicon/hi6220-hikey.dts
> index e36a539..d5470d3 100644
> --- a/arch/arm64/boot/dts/hisilicon/hi6220-hikey.dts
> +++ b/arch/arm64/boot/dts/hisilicon/hi6220-hikey.dts
> @@ -7,9 +7,6 @@
>
>   /dts-v1/;
>
> -/*Reserved 1MB memory for MCU*/
> -/memreserve/ 0x05e00000 0x00100000;
> -
>   #include "hi6220.dtsi"
>
>   / {
> @@ -28,4 +25,21 @@
>   		device_type = "memory";
>   		reg = <0x0 0x0 0x0 0x40000000>;
>   	};

I have no access to the spec, but I read this as 1GB RAM @0x0
Unless this entry is completely wrong, what your commit log claims is
incorrect. If this entry is wrong I wonder how is it booting with this
DT then.

> +
> +	reserved-memory {
> +		#address-cells = <2>;
> +		#size-cells = <2>;
> +		ranges;
> +
> +		mcu-buf at 05e00000 {
> +			no-map;
> +			reg = <0x0 0x05e00000 0x0 0x00100000>,	/* MCU firmware buffer */
> +			      <0x0 0x0740f000 0x0 0x00001000>;	/* MCU firmware section */

So I don't see how can this be part of DDR ? Or at-least part of DDR
that's mapped by kernel ?

Regards,
Sudeep


From marc.zyngier at arm.com  Tue Aug 25 04:39:50 2015
From: marc.zyngier at arm.com (Marc Zyngier)
Date: Tue, 25 Aug 2015 12:39:50 +0100
Subject: [PATCH v5 2/5] pci:host: Add Altera PCIe host controller driver
In-Reply-To: <1440495348-2666-3-git-send-email-lftan@altera.com>
References: <1440495348-2666-1-git-send-email-lftan@altera.com>
 <1440495348-2666-3-git-send-email-lftan@altera.com>
Message-ID: <55DC5406.3080703@arm.com>

On 25/08/15 10:35, Ley Foon Tan wrote:
> This patch adds the Altera PCIe host controller driver.
> 
> Signed-off-by: Ley Foon Tan <lftan at altera.com>
> ---
>  drivers/pci/host/Kconfig       |   7 +
>  drivers/pci/host/Makefile      |   1 +
>  drivers/pci/host/pcie-altera.c | 588 +++++++++++++++++++++++++++++++++++++++++
>  3 files changed, 596 insertions(+)
>  create mode 100644 drivers/pci/host/pcie-altera.c
> 
> diff --git a/drivers/pci/host/Kconfig b/drivers/pci/host/Kconfig
> index 675c2d1..4b4754a 100644
> --- a/drivers/pci/host/Kconfig
> +++ b/drivers/pci/host/Kconfig
> @@ -145,4 +145,11 @@ config PCIE_IPROC_BCMA
>  	  Say Y here if you want to use the Broadcom iProc PCIe controller
>  	  through the BCMA bus interface
>  
> +config PCIE_ALTERA
> +	tristate "Altera PCIe controller"
> +	depends on ARCH_SOCFPGA
> +	help
> +	  Say Y here if you want to enable PCIe controller support for Altera
> +	  SoCFPGA family of SoCs.
> +
>  endmenu
> diff --git a/drivers/pci/host/Makefile b/drivers/pci/host/Makefile
> index 140d66f..6954f76 100644
> --- a/drivers/pci/host/Makefile
> +++ b/drivers/pci/host/Makefile
> @@ -17,3 +17,4 @@ obj-$(CONFIG_PCI_VERSATILE) += pci-versatile.o
>  obj-$(CONFIG_PCIE_IPROC) += pcie-iproc.o
>  obj-$(CONFIG_PCIE_IPROC_PLATFORM) += pcie-iproc-platform.o
>  obj-$(CONFIG_PCIE_IPROC_BCMA) += pcie-iproc-bcma.o
> +obj-$(CONFIG_PCIE_ALTERA) += pcie-altera.o
> diff --git a/drivers/pci/host/pcie-altera.c b/drivers/pci/host/pcie-altera.c
> new file mode 100644
> index 0000000..c168ec7
> --- /dev/null
> +++ b/drivers/pci/host/pcie-altera.c
> @@ -0,0 +1,588 @@
> +/*
> + * Copyright Altera Corporation (C) 2013-2015. All rights reserved
> + *
> + * This program is free software; you can redistribute it and/or modify it
> + * under the terms and conditions of the GNU General Public License,
> + * version 2, as published by the Free Software Foundation.
> + *
> + * This program is distributed in the hope 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.
> + *
> + * You should have received a copy of the GNU General Public License along with
> + * this program.  If not, see <http://www.gnu.org/licenses/>.
> + */
> +#include <linux/delay.h>
> +#include <linux/interrupt.h>
> +#include <linux/irqchip/chained_irq.h>
> +#include <linux/module.h>
> +#include <linux/of_address.h>
> +#include <linux/of_irq.h>
> +#include <linux/of_pci.h>
> +#include <linux/pci.h>
> +#include <linux/platform_device.h>
> +#include <linux/slab.h>
> +
> +#define A2P_ADDR_MAP_LO0		0x1000
> +#define A2P_ADDR_MAP_HI0		0x1004
> +#define RP_TX_REG0			0x2000
> +#define RP_TX_REG1			0x2004
> +#define RP_TX_CNTRL			0x2008
> +#define RP_TX_EOP			0x2
> +#define RP_TX_SOP			0x1
> +#define RP_RXCPL_STATUS		0x2010
> +#define RP_RXCPL_EOP			0x2
> +#define RP_RXCPL_SOP			0x1
> +#define RP_RXCPL_REG0			0x2014
> +#define RP_RXCPL_REG1			0x2018
> +#define P2A_INT_STATUS			0x3060
> +#define P2A_INT_STS_ALL			0xF
> +#define P2A_INT_ENABLE			0x3070
> +#define P2A_INT_ENA_ALL			0xF
> +#define RP_LTSSM			0x3C64
> +#define LTSSM_L0			0xF
> +
> +/* TLP configuration type 0 and 1 */
> +#define TLP_FMTTYPE_CFGRD0		0x04	/* Configuration Read Type 0 */
> +#define TLP_FMTTYPE_CFGWR0		0x44	/* Configuration Write Type 0 */
> +#define TLP_FMTTYPE_CFGRD1		0x05	/* Configuration Read Type 1 */
> +#define TLP_FMTTYPE_CFGWR1		0x45	/* Configuration Write Type 1 */
> +#define TLP_PAYLOAD_SIZE		0x01
> +#define TLP_READ_TAG			0x1D
> +#define TLP_WRITE_TAG			0x10
> +#define TLP_CFG_DW0(fmttype)		(((fmttype) << 24) | TLP_PAYLOAD_SIZE)
> +#define TLP_CFG_DW1(reqid, tag)		(((reqid) << 16) | (tag << 8) | 0xF)
> +#define TLP_CFG_DW2(bus, devfn, offset)	\
> +				(((bus) << 24) | ((devfn) << 16) | (offset))
> +#define TLP_REQ_ID(bus, devfn)		(((bus) << 8) | (devfn))
> +#define TLP_COMPL_STATUS(hdr)		(((hdr) & 0xE0) >> 13)
> +#define TLP_HDR_SIZE			3
> +#define TLP_LOOP			10
> +
> +#define INTX_NUM		4
> +
> +/* Address translation table entry size */
> +#define ATT_ENTRY_SIZE		8
> +
> +#define DWORD_MASK		3
> +
> +struct altera_pcie {
> +	struct platform_device	*pdev;
> +	void __iomem		*cra_base;
> +	int			irq;
> +	u8			root_bus_nr;
> +	struct irq_domain		*irq_domain;
> +	struct resource		bus_range;
> +	struct list_head		resources;
> +};
> +
> +struct tlp_rp_regpair_t {
> +	u32 ctrl;
> +	u32 reg0;
> +	u32 reg1;
> +};
> +
> +static void altera_pcie_retrain(struct pci_dev *dev)
> +{
> +	u16 linkcap, linkstat;
> +
> +	/*
> +	 * Set the retrain bit if the PCIe rootport support > 2.5GB/s, but
> +	 * current speed is 2.5 GB/s.
> +	 */
> +	pcie_capability_read_word(dev, PCI_EXP_LNKCAP, &linkcap);
> +
> +	if ((linkcap & PCI_EXP_LNKCAP_SLS) <= PCI_EXP_LNKCAP_SLS_2_5GB)
> +		return;
> +
> +	pcie_capability_read_word(dev, PCI_EXP_LNKSTA, &linkstat);
> +	if ((linkstat & PCI_EXP_LNKSTA_CLS) == PCI_EXP_LNKSTA_CLS_2_5GB)
> +		pcie_capability_set_word(dev, PCI_EXP_LNKCTL,
> +					 PCI_EXP_LNKCTL_RL);
> +}
> +DECLARE_PCI_FIXUP_EARLY(PCI_ANY_ID, PCI_ANY_ID, altera_pcie_retrain);

Do I read this correctly? This function is being called on any PCI
device, without any filtering? What if the platform is not using this
driver despite the driver being compiled in?

> +
> +static void altera_pcie_fixup_res(struct pci_dev *dev)
> +{
> +	/*
> +	 * Prevent enumeration of root port.
> +	 */
> +	if (!dev->bus->parent && dev->devfn == 0) {
> +		int i;
> +
> +		for (i = 0; i < PCI_NUM_RESOURCES; i++) {
> +			dev->resource[i].start = 0;
> +			dev->resource[i].end   = 0;
> +			dev->resource[i].flags   = 0;
> +		}
> +	}
> +}
> +DECLARE_PCI_FIXUP_HEADER(PCI_ANY_ID, PCI_ANY_ID, altera_pcie_fixup_res);

Same here. I also question the validity of nuking the resources, but I'm
not a PCI expert.

> +
> +static inline void cra_writel(struct altera_pcie *pcie, u32 value, u32 reg)
> +{
> +	writel_relaxed(value, pcie->cra_base + reg);
> +}
> +
> +static inline u32 cra_readl(struct altera_pcie *pcie, u32 reg)
> +{
> +	return readl_relaxed(pcie->cra_base + reg);
> +}
> +
> +static void tlp_read_rx(struct altera_pcie *pcie,
> +			struct tlp_rp_regpair_t *tlp_rp_regdata)
> +{
> +	tlp_rp_regdata->ctrl = cra_readl(pcie, RP_RXCPL_STATUS);
> +	tlp_rp_regdata->reg0 = cra_readl(pcie, RP_RXCPL_REG0);
> +	tlp_rp_regdata->reg1 = cra_readl(pcie, RP_RXCPL_REG1);
> +}
> +
> +static void tlp_write_tx(struct altera_pcie *pcie,
> +			 struct tlp_rp_regpair_t *tlp_rp_regdata)
> +{
> +	cra_writel(pcie, tlp_rp_regdata->reg0, RP_TX_REG0);
> +	cra_writel(pcie, tlp_rp_regdata->reg1, RP_TX_REG1);
> +	cra_writel(pcie, tlp_rp_regdata->ctrl, RP_TX_CNTRL);
> +}
> +
> +static bool altera_pcie_link_is_up(struct altera_pcie *pcie)
> +{
> +	return !!(cra_readl(pcie, RP_LTSSM) & LTSSM_L0);
> +}
> +
> +static bool altera_pcie_valid_config(struct altera_pcie *pcie,
> +				     struct pci_bus *bus, int dev)
> +{
> +	/* If there is no link, then there is no device */
> +	if (bus->number != pcie->root_bus_nr) {
> +		if (!altera_pcie_link_is_up(pcie))
> +			return false;
> +	}
> +
> +	/* access only one slot on each root port */
> +	if (bus->number == pcie->root_bus_nr && dev > 0)
> +		return false;
> +
> +	/*
> +	 * Do not read more than one device on the bus directly attached
> +	 * to RC.
> +	 */
> +	if (bus->primary == pcie->root_bus_nr && dev > 0)
> +		return false;
> +
> +	 return true;
> +}
> +
> +static int tlp_read_packet(struct altera_pcie *pcie, u32 *value)
> +{
> +	u8 loop;
> +	struct tlp_rp_regpair_t tlp_rp_regdata;
> +
> +	for (loop = 0; loop < TLP_LOOP; loop++) {
> +		tlp_read_rx(pcie, &tlp_rp_regdata);
> +		if (tlp_rp_regdata.ctrl & RP_RXCPL_EOP) {
> +			if (value)
> +				*value = tlp_rp_regdata.reg0;
> +			return PCIBIOS_SUCCESSFUL;
> +		}
> +		udelay(5);
> +	}
> +
> +	return -ENOENT;
> +}
> +
> +static void tlp_write_packet_unaligned(struct altera_pcie *pcie, u32 *headers,
> +				       u32 data)
> +{
> +	struct tlp_rp_regpair_t tlp_rp_regdata;
> +
> +	tlp_rp_regdata.reg0 = headers[0];
> +	tlp_rp_regdata.reg1 = headers[1];
> +	tlp_rp_regdata.ctrl = RP_TX_SOP;
> +	tlp_write_tx(pcie, &tlp_rp_regdata);
> +
> +	tlp_rp_regdata.reg0 = headers[2];
> +	tlp_rp_regdata.reg1 = data;
> +	tlp_rp_regdata.ctrl = RP_TX_EOP;
> +	tlp_write_tx(pcie, &tlp_rp_regdata);
> +}
> +
> +static void tlp_write_packet_aligned(struct altera_pcie *pcie, u32 *headers,
> +				     u32 data)
> +{
> +	struct tlp_rp_regpair_t tlp_rp_regdata;
> +
> +	tlp_rp_regdata.reg0 = headers[0];
> +	tlp_rp_regdata.reg1 = headers[1];
> +	tlp_rp_regdata.ctrl = RP_TX_SOP;
> +	tlp_write_tx(pcie, &tlp_rp_regdata);
> +
> +	tlp_rp_regdata.reg0 = headers[2];
> +	tlp_rp_regdata.reg1 = 0;
> +	tlp_rp_regdata.ctrl = 0;
> +	tlp_write_tx(pcie, &tlp_rp_regdata);
> +
> +	tlp_rp_regdata.reg0 = data;
> +	tlp_rp_regdata.reg1 = 0;
> +	tlp_rp_regdata.ctrl = RP_TX_EOP;
> +	tlp_write_tx(pcie, &tlp_rp_regdata);
> +}
> +
> +static int tlp_cfg_dword_read(struct altera_pcie *pcie, u8 bus, u32 devfn,
> +			      int where, u32 *value)
> +{
> +	int ret;
> +	u32 headers[TLP_HDR_SIZE];
> +
> +	if (bus == pcie->root_bus_nr)
> +		headers[0] = TLP_CFG_DW0(TLP_FMTTYPE_CFGRD0);
> +	else
> +		headers[0] = TLP_CFG_DW0(TLP_FMTTYPE_CFGRD1);
> +
> +	headers[1] = TLP_CFG_DW1(TLP_REQ_ID(pcie->root_bus_nr, devfn),
> +					TLP_READ_TAG);
> +	headers[2] = TLP_CFG_DW2(bus, devfn, where);
> +
> +	tlp_write_packet_unaligned(pcie, headers, 0);
> +
> +	ret = tlp_read_packet(pcie, value);
> +	if (ret != PCIBIOS_SUCCESSFUL)
> +		*value = ~0UL;	/* return 0xFFFFFFFF if error */
> +
> +	return ret;
> +}
> +
> +static int tlp_cfg_dword_write(struct altera_pcie *pcie, u8 bus, u32 devfn,
> +			       int where, u32 value)
> +{
> +	u32 headers[TLP_HDR_SIZE];
> +	int ret;
> +
> +	if (bus == pcie->root_bus_nr)
> +		headers[0] = TLP_CFG_DW0(TLP_FMTTYPE_CFGWR0);
> +	else
> +		headers[0] = TLP_CFG_DW0(TLP_FMTTYPE_CFGWR1);
> +
> +	headers[1] = TLP_CFG_DW1(TLP_REQ_ID(pcie->root_bus_nr, devfn),
> +					TLP_WRITE_TAG);
> +	headers[2] = TLP_CFG_DW2(bus, devfn, where);
> +
> +	/* check alignment to Qword */
> +	if ((where & 0x7) == 0)
> +		tlp_write_packet_aligned(pcie, headers, value);
> +	else
> +		tlp_write_packet_unaligned(pcie, headers, value);
> +
> +	ret = tlp_read_packet(pcie, NULL);
> +	if (ret != PCIBIOS_SUCCESSFUL)
> +		return ret;
> +
> +	/* Keep an eye out for changes to the root bus number */
> +	if ((bus == pcie->root_bus_nr) && (where == PCI_PRIMARY_BUS))
> +		pcie->root_bus_nr = (u8)(value);
> +
> +	return PCIBIOS_SUCCESSFUL;
> +}
> +
> +static int altera_pcie_cfg_read(struct pci_bus *bus, unsigned int devfn,
> +				int where, int size, u32 *value)
> +{
> +	struct altera_pcie *pcie = bus->sysdata;
> +	int ret;
> +
> +	if (!altera_pcie_valid_config(pcie, bus, PCI_SLOT(devfn))) {
> +		*value = ~0UL;
> +		return PCIBIOS_DEVICE_NOT_FOUND;
> +	}
> +
> +	ret = tlp_cfg_dword_read(pcie, bus->number, devfn,
> +				 (where & ~DWORD_MASK), value);
> +	if (ret != PCIBIOS_SUCCESSFUL)
> +		return ret;
> +
> +	if (size == 1)
> +		*value = (*value >> (8 * (where & 0x3))) & 0xff;
> +	else if (size == 2)
> +		*value = (*value >> (8 * (where & 0x2))) & 0xffff;

Please write this as a switch/case statement, with a default handling case.

> +
> +	return PCIBIOS_SUCCESSFUL;
> +}
> +
> +static int altera_pcie_cfg_write(struct pci_bus *bus, unsigned int devfn,
> +				 int where, int size, u32 value)
> +{
> +	struct altera_pcie *pcie = bus->sysdata;
> +	u32 data32 = value;
> +	u32 shift = 8 * (where & 3);
> +	int ret;
> +
> +	if (!altera_pcie_valid_config(pcie, bus, PCI_SLOT(devfn)))
> +		return PCIBIOS_DEVICE_NOT_FOUND;
> +
> +	/* write partial */
> +	if (size != sizeof(u32)) {
> +		ret = tlp_cfg_dword_read(pcie, bus->number, devfn,
> +					 where & ~DWORD_MASK, &data32);
> +		if (ret)
> +			return ret;
> +
> +		if (size == 2)
> +			data32 = (data32 & ~(0xffff << shift)) |
> +					((value & 0xffff) << shift);
> +		 else if (size == 1)
> +			data32 = (data32 & ~(0xff << shift)) |
> +					((value & 0xff) << shift);

Same here.

> +	}
> +
> +	return tlp_cfg_dword_write(pcie, bus->number, devfn,
> +		(where & ~DWORD_MASK), data32);
> +}
> +
> +static struct pci_ops altera_pcie_ops = {
> +	.read = altera_pcie_cfg_read,
> +	.write = altera_pcie_cfg_write,
> +};
> +
> +static int altera_pcie_intx_map(struct irq_domain *domain, unsigned int irq,
> +				irq_hw_number_t hwirq)
> +{
> +	irq_set_chip_and_handler(irq, &dummy_irq_chip, handle_simple_irq);
> +	irq_set_chip_data(irq, domain->host_data);
> +	set_irq_flags(irq, IRQF_VALID);
> +
> +	return 0;
> +}
> +
> +static const struct irq_domain_ops intx_domain_ops = {
> +	.map = altera_pcie_intx_map,
> +};
> +
> +static void altera_pcie_isr(unsigned int irq, struct irq_desc *desc)
> +{
> +	struct irq_chip *chip = irq_desc_get_chip(desc);
> +	struct altera_pcie *pcie;
> +	unsigned long status;
> +	u32 bit;
> +	u32 virq;
> +
> +	chained_irq_enter(chip, desc);
> +	pcie = irq_desc_get_handler_data(desc);
> +
> +	do {
> +		status = cra_readl(pcie, P2A_INT_STATUS) & P2A_INT_STS_ALL;
> +		if (!status)
> +			break;
> +
> +		do {
> +			bit = find_first_bit(&status, INTX_NUM);
> +			/* clear interrupts */
> +			cra_writel(pcie, 1 << bit, P2A_INT_STATUS);
> +
> +			virq = irq_find_mapping(pcie->irq_domain, bit + 1);
> +			if (virq)
> +				generic_handle_irq(virq);
> +			else
> +				dev_info(&pcie->pdev->dev, "unexpected IRQ\n");
> +
> +			/* Clear the bit from status and repeat without reading
> +			 * again status register. */
> +			__clear_bit(bit, &status);
> +		} while (status);
> +	} while (1);

Please rewrite similarily to the way I proposed in your MSI driver.

> +
> +	chained_irq_exit(chip, desc);
> +}
> +
> +static void altera_pcie_release_of_pci_ranges(struct altera_pcie *pcie)
> +{
> +	pci_free_resource_list(&pcie->resources);
> +}
> +
> +static int altera_pcie_parse_request_of_pci_ranges(struct altera_pcie *pcie)
> +{
> +	int err, res_valid = 0;
> +	struct device *dev = &pcie->pdev->dev;
> +	struct device_node *np = dev->of_node;
> +	resource_size_t iobase;
> +	struct resource_entry *win;
> +
> +	err = of_pci_get_host_bridge_resources(np, 0, 0xff, &pcie->resources,
> +					       &iobase);
> +	if (err)
> +		return err;
> +
> +	resource_list_for_each_entry(win, &pcie->resources) {
> +		struct resource *parent, *res = win->res;
> +
> +		switch (resource_type(res)) {
> +		case IORESOURCE_MEM:
> +			parent = &iomem_resource;
> +			res_valid |= !(res->flags & IORESOURCE_PREFETCH);
> +			break;
> +		default:
> +			continue;
> +		}
> +
> +		err = devm_request_resource(dev, parent, res);
> +		if (err)
> +			goto out_release_res;
> +	}
> +
> +	if (!res_valid) {
> +		dev_err(dev, "non-prefetchable memory resource required\n");
> +		err = -EINVAL;
> +		goto out_release_res;
> +	}
> +
> +	return 0;
> +
> +out_release_res:
> +	altera_pcie_release_of_pci_ranges(pcie);
> +	return err;
> +}
> +
> +static void altera_pcie_free_irq_domain(struct altera_pcie *pcie)
> +{
> +	int i;
> +	u32 irq;
> +
> +	for (i = 0; i < INTX_NUM; i++) {
> +		irq = irq_find_mapping(pcie->irq_domain, i);
> +		if (irq > 0)
> +			irq_dispose_mapping(irq);
> +	}
> +
> +	irq_domain_remove(pcie->irq_domain);
> +}
> +
> +static int altera_pcie_init_irq_domain(struct altera_pcie *pcie)
> +{
> +	struct device *dev = &pcie->pdev->dev;
> +	struct device_node *node = dev->of_node;
> +
> +	/* Setup INTx */
> +	pcie->irq_domain = irq_domain_add_linear(node, INTX_NUM,
> +					&intx_domain_ops, pcie);
> +	if (!pcie->irq_domain) {
> +		dev_err(dev, "Failed to get a INTx IRQ domain\n");
> +		return -ENOMEM;
> +	}
> +
> +	return 0;
> +}
> +
> +static int altera_pcie_parse_dt(struct altera_pcie *pcie)
> +{
> +	struct resource *cra;
> +	struct platform_device *pdev = pcie->pdev;
> +
> +	cra = platform_get_resource_byname(pdev, IORESOURCE_MEM, "Cra");
> +	if (!cra) {
> +		cra = platform_get_resource_byname(pdev, IORESOURCE_MEM, "cra");
> +		if (!cra) {
> +			dev_err(&pdev->dev,
> +				"no cra memory resource defined\n");
> +			return -ENODEV;
> +		}
> +	}
> +
> +	pcie->cra_base = devm_ioremap_resource(&pdev->dev, cra);
> +	if (IS_ERR(pcie->cra_base)) {
> +		dev_err(&pdev->dev, "failed to map cra memory\n");
> +		return PTR_ERR(pcie->cra_base);
> +	}
> +
> +	/* setup IRQ */
> +	pcie->irq = platform_get_irq(pdev, 0);
> +	if (pcie->irq <= 0) {
> +		dev_err(&pdev->dev, "failed to get IRQ: %d\n", pcie->irq);
> +		return -EINVAL;
> +	}
> +
> +	irq_set_chained_handler_and_data(pcie->irq, altera_pcie_isr, pcie);
> +
> +	return 0;
> +}
> +
> +static int altera_pcie_probe(struct platform_device *pdev)
> +{
> +	struct altera_pcie *pcie;
> +	struct pci_bus *bus;
> +	int ret;
> +
> +	pcie = devm_kzalloc(&pdev->dev, sizeof(*pcie), GFP_KERNEL);
> +	if (!pcie)
> +		return -ENOMEM;
> +
> +	pcie->pdev = pdev;
> +
> +	ret = altera_pcie_parse_dt(pcie);
> +	if (ret) {
> +		dev_err(&pdev->dev, "Parsing DT failed\n");
> +		return ret;
> +	}
> +
> +	INIT_LIST_HEAD(&pcie->resources);
> +
> +	ret = altera_pcie_parse_request_of_pci_ranges(pcie);
> +	if (ret) {
> +		dev_err(&pdev->dev, "Failed add resources\n");
> +		return ret;
> +	}
> +
> +	ret = altera_pcie_init_irq_domain(pcie);
> +	if (ret) {
> +		dev_err(&pdev->dev, "Failed creating IRQ Domain\n");
> +		return ret;
> +	}
> +
> +	pcie->root_bus_nr = 0;
> +
> +	/* clear all interrupts */
> +	cra_writel(pcie, P2A_INT_STS_ALL, P2A_INT_STATUS);
> +	/* enable all interrupts */
> +	cra_writel(pcie, P2A_INT_ENA_ALL, P2A_INT_ENABLE);
> +
> +	bus = pci_scan_root_bus(&pdev->dev, pcie->root_bus_nr, &altera_pcie_ops,
> +				pcie, &pcie->resources);
> +	if (!bus)
> +		return -ENOMEM;
> +
> +	pci_fixup_irqs(pci_common_swizzle, of_irq_parse_and_map_pci);
> +	pci_assign_unassigned_bus_resources(bus);
> +	pci_bus_add_devices(bus);
> +
> +	platform_set_drvdata(pdev, pcie);
> +	return ret;
> +}
> +
> +static int __exit altera_pcie_remove(struct platform_device *pdev)
> +{
> +	struct altera_pcie *pcie = platform_get_drvdata(pdev);
> +
> +	altera_pcie_free_irq_domain(pcie);
> +	platform_set_drvdata(pdev, NULL);
> +	return 0;
> +}
> +
> +static const struct of_device_id altera_pcie_of_match[] = {
> +	{ .compatible = "altr,pcie-root-port-1.0", },
> +	{},
> +};
> +MODULE_DEVICE_TABLE(of, altera_pcie_of_match);
> +
> +static struct platform_driver altera_pcie_driver = {
> +	.probe		= altera_pcie_probe,
> +	.remove		= altera_pcie_remove,
> +	.driver = {
> +		.name	= "altera-pcie",
> +		.of_match_table = altera_pcie_of_match,
> +	},
> +};
> +
> +module_platform_driver(altera_pcie_driver);
> +
> +MODULE_AUTHOR("Ley Foon Tan <lftan at altera.com>");
> +MODULE_DESCRIPTION("Altera PCIe host controller driver");
> +MODULE_LICENSE("GPL v2");
> 

Thanks,

	M.
-- 
Jazz is not dead. It just smells funny...


From cyrille.pitchen at atmel.com  Tue Aug 25 04:42:21 2015
From: cyrille.pitchen at atmel.com (Cyrille Pitchen)
Date: Tue, 25 Aug 2015 13:42:21 +0200
Subject: [PATCH v8 1/2] mfd: devicetree: add bindings for Atmel Flexcom
In-Reply-To: <20150724150854.GI3436@x1>
References: <cover.1437731428.git.cyrille.pitchen@atmel.com>
 <738a001f14a5fa4fa8e5f90ad859a318cba0de42.1437731428.git.cyrille.pitchen@atmel.com>
 <20150724150854.GI3436@x1>
Message-ID: <55DC549D.7060307@atmel.com>

Hi all,

any feedback on this kind of DT bindings?
Is it a proper way of using the "ranges" property?

Best regards,

Cyrille

Le 24/07/2015 17:08, Lee Jones a ?crit :
> DT chaps,
> 
> Please can you take a look at this binding.
> 
> In particular the use of the 'ranges' property to store device 'mode'.
> 
>> This patch documents the DT bindings for the Atmel Flexcom which will be
>> introduced by sama5d2x SoCs. These bindings will be used by the actual
>> Flexcom driver to be sent in another patch.
>>
>> Signed-off-by: Cyrille Pitchen <cyrille.pitchen at atmel.com>
>> Acked-by: Nicolas Ferre <nicolas.ferre at atmel.com>
>> ---
>>  .../devicetree/bindings/mfd/atmel-flexcom.txt      | 68 ++++++++++++++++++++++
>>  1 file changed, 68 insertions(+)
>>  create mode 100644 Documentation/devicetree/bindings/mfd/atmel-flexcom.txt
>>
>> diff --git a/Documentation/devicetree/bindings/mfd/atmel-flexcom.txt b/Documentation/devicetree/bindings/mfd/atmel-flexcom.txt
>> new file mode 100644
>> index 000000000000..588d527dbfa7
>> --- /dev/null
>> +++ b/Documentation/devicetree/bindings/mfd/atmel-flexcom.txt
>> @@ -0,0 +1,68 @@
>> +* Device tree bindings for Atmel Flexcom (Flexible Serial Communication Unit)
>> +
>> +The Atmel Flexcom is just a wrapper which embeds a SPI controller, an I2C
>> +controller and an USART. Only one function can be used at a time and is chosen
>> +at boot time according to the device tree.
>> +
>> +Required properties:
>> +- compatible:		Should be "atmel,sama5d2-flexcom"
>> +- reg:			Should be the pair (offset, size) for the Flexcom
>> +			dedicated I/O registers (without USART, TWI or SPI
>> +			registers).
>> +- clocks:		Should be the Flexcom peripheral clock from PMC.
>> +- #address-cells:	Should be <2>
>> +- #size-cells:		Should be <1>
>> +- ranges:		Should be a list of ranges.
>> +			One range per peripheral wrapped by the Flexcom. So each
>> +			range is a triplet (child_addr, parent_addr, size). The
>> +			first u32 of "child_addr" is the value to be set in the
>> +			Operating Mode bitfield of the Flexcom Mode Register.
>> +			Then "parent_addr" stores the base address of the
>> +			corresponding peripheral in the system memory. Finally,
>> +			"size" if the size of the memory region of this
>> +			peripheral.
>> +
>> +Required child:
>> +A single available child for the serial controller to enable.
>> +
>> +Required properties of this child:
>> +- reg:			Should be a pair (child_addr, size) with child_addr
>> +			matching one of the parent ranges.
>> +- clocks:		Should be the very same phandle as for the parent's one.
>> +
>> +Other properties remain unchanged. See documentation of the respective device:
>> +- ../serial/atmel-usart.txt
>> +- ../spi/spi_atmel.txt
>> +- ../i2c/i2c-at91.txt
>> +
>> +Example:
>> +
>> +flexcom at f8034000 {
>> +	compatible = "atmel,sama5d2-flexcom";
>> +	reg = <0xf8034000 0x200>;
>> +	clocks = <&flx0_clk>;
>> +	#address-cells = <2>;
>> +	#size-cells = <1>;
>> +	ranges = <1 0 0xf8034200 0x200		/* opmode 1: USART */
>> +		  2 0 0xf8034400 0x200		/* opmode 2: SPI */
>> +		  3 0 0xf8034600 0x200>;	/* opmode 3: I2C */
>> +
>> +	spi at 2,0 {
>> +		compatible = "atmel,at91rm9200-spi";
>> +		reg = <2 0 0x200>;
>> +		interrupts = <19 IRQ_TYPE_LEVEL_HIGH 7>;
>> +		pinctrl-names = "default";
>> +		pinctrl-0 = <&pinctrl_flx0_default>;
>> +		#address-cells = <1>;
>> +		#size-cells = <0>;
>> +		clocks = <&flx0_clk>;
>> +		clock-names = "spi_clk";
>> +		atmel,fifo-size = <32>;
>> +
>> +		mtd_dataflash at 0 {
>> +			compatible = "atmel,at25f512b";
>> +			reg = <0>;
>> +			spi-max-frequency = <20000000>;
>> +		};
>> +	};
>> +};
> 



From marc.zyngier at arm.com  Tue Aug 25 04:53:21 2015
From: marc.zyngier at arm.com (Marc Zyngier)
Date: Tue, 25 Aug 2015 12:53:21 +0100
Subject: [PATCH v3 0/4] irqchip: GICv2/v3: Add support for irq_vcpu_affinity
Message-ID: <1440503605-10185-1-git-send-email-marc.zyngier@arm.com>

The GICv2 and GICv3 architectures allow an active physical interrupt
to be forwarded to a guest, and the guest to indirectly perform the
deactivation of the interrupt by performing an EOI on the virtual
interrupt (see for example the GICv2 spec, 3.2.1).

This allows some substantial performance improvement for level
triggered interrupts that otherwise have to be masked/unmasked in
VFIO, not to mention the required trap back to KVM when the guest
performs an EOI.

To enable this, the GICs need to be switched to a different EOImode,
where a taken interrupt can be left "active" (which prevents the same
interrupt from being taken again), while other interrupts are still
being processed normally.

We also use the new irq_set_vcpu_affinity hook that was introduced for
Intel's "Posted Interrupts" to determine whether or not to perform the
deactivation at EOI-time.

As all of this only makes sense when the kernel can behave as a
hypervisor, we only enable this mode on detecting that the kernel was
actually booted in HYP mode, and that the GIC supports this feature.

This series is a complete rework of a RFC I sent over a year ago:

http://lists.infradead.org/pipermail/linux-arm-kernel/2014-June/266328.html

Since then, a lot has been either merged (the irqchip_state) or reworked
(my active-timer series: http://www.spinics.net/lists/kvm/msg118768.html),
and this implements the last few bits for Eric Auger's series to
finally make it into the kernel:

https://lkml.org/lkml/2015/7/2/268
https://lkml.org/lkml/2015/7/6/291

With all these patches combined, physical interrupt routing from the
kernel into a VM becomes possible.

This has been tested on Juno (GICv2) and FastModel (GICv3), and Eric
tested it on a Calxeda Midway. A branch is available at:

git://git.kernel.org/pub/scm/linux/kernel/git/maz/arm-platforms.git irq/gic-irq-vcpu-affinity-v2

* From v2:
  - Another small fix from Eric
  - Some commit message cleanups

* From v1:
  - Fixes after review from Eric
  - Got rid of the cascaded GICv2 hack (it was broken anyway)
  - Folded the LPI deactivation patch (it makes more sense as part of
    the main one.
  - Some clarifying comments about the "deactivate on mask"
  - I haven't retained Eric's Reviewed/Tested-by, as the code as
    significantly changed on GICv2

Marc Zyngier (4):
  irqchip: GICv3: Convert to EOImode == 1
  irqchip: GICv3: Don't deactivate interrupts forwarded to a guest
  irqchip: GIC: Convert to EOImode == 1
  irqchip: GIC: Don't deactivate interrupts forwarded to a guest

 drivers/irqchip/irq-gic-v3.c       |  70 +++++++++++++++++++++--
 drivers/irqchip/irq-gic.c          | 111 ++++++++++++++++++++++++++++++++++++-
 include/linux/irqchip/arm-gic-v3.h |   9 +++
 include/linux/irqchip/arm-gic.h    |   4 ++
 4 files changed, 188 insertions(+), 6 deletions(-)

-- 
2.1.4



From marc.zyngier at arm.com  Tue Aug 25 04:53:23 2015
From: marc.zyngier at arm.com (Marc Zyngier)
Date: Tue, 25 Aug 2015 12:53:23 +0100
Subject: [PATCH v3 2/4] irqchip: GICv3: Don't deactivate interrupts forwarded
 to a guest
In-Reply-To: <1440503605-10185-1-git-send-email-marc.zyngier@arm.com>
References: <1440503605-10185-1-git-send-email-marc.zyngier@arm.com>
Message-ID: <1440503605-10185-3-git-send-email-marc.zyngier@arm.com>

Commit 0a4377de3056 ("genirq: Introduce irq_set_vcpu_affinity() to
target an interrupt to a VCPU") added just what we needed at the
lowest level to allow an interrupt to be deactivated by a guest.

When such a request reaches the GIC, it knows it doesn't need to
perform the deactivation anymore, and can safely leave the guest
do its magic. This of course requires additional support in both
VFIO and KVM.

Reviewed-by: Eric Auger <eric.auger at linaro.org>
Signed-off-by: Marc Zyngier <marc.zyngier at arm.com>
---
 drivers/irqchip/irq-gic-v3.c | 35 +++++++++++++++++++++++++++++++++--
 1 file changed, 33 insertions(+), 2 deletions(-)

diff --git a/drivers/irqchip/irq-gic-v3.c b/drivers/irqchip/irq-gic-v3.c
index addd2ee..5aa9bf6 100644
--- a/drivers/irqchip/irq-gic-v3.c
+++ b/drivers/irqchip/irq-gic-v3.c
@@ -70,6 +70,11 @@ static inline int gic_irq_in_rdist(struct irq_data *d)
 	return gic_irq(d) < 32;
 }
 
+static inline bool forwarded_irq(struct irq_data *d)
+{
+	return d->handler_data != NULL;
+}
+
 static inline void __iomem *gic_dist_base(struct irq_data *d)
 {
 	if (gic_irq_in_rdist(d))	/* SGI+PPI -> SGI_base for this CPU */
@@ -231,6 +236,18 @@ static void gic_poke_irq(struct irq_data *d, u32 offset)
 static void gic_mask_irq(struct irq_data *d)
 {
 	gic_poke_irq(d, GICD_ICENABLER);
+	/*
+	 * When masking a forwarded interrupt, make sure it is
+	 * deactivated as well.
+	 *
+	 * This ensures that an interrupt that is getting
+	 * disabled/masked will not get "stuck", because there is
+	 * noone to deactivate it (guest is being terminated).
+	 */
+	if (static_key_true(&supports_deactivate)) {
+		if (forwarded_irq(d))
+			gic_poke_irq(d, GICD_ICACTIVER);
+	}
 }
 
 static void gic_unmask_irq(struct irq_data *d)
@@ -296,8 +313,11 @@ static int gic_irq_get_irqchip_state(struct irq_data *d,
 static void gic_eoi_irq(struct irq_data *d)
 {
 	if (static_key_true(&supports_deactivate)) {
-		/* No need to deactivate an LPI */
-		if (gic_irq(d) >= 8192)
+		/*
+		 * No need to deactivate an LPI, or an interrupt that
+		 * is is getting forwarded to a vcpu.
+		 */
+		if (gic_irq(d) >= 8192 || forwarded_irq(d))
 			return;
 		gic_write_dir(gic_irq(d));
 	} else {
@@ -331,6 +351,16 @@ static int gic_set_type(struct irq_data *d, unsigned int type)
 	return gic_configure_irq(irq, type, base, rwp_wait);
 }
 
+static int gic_irq_set_vcpu_affinity(struct irq_data *d, void *vcpu)
+{
+	if (static_key_true(&supports_deactivate)) {
+		d->handler_data = vcpu;
+		return 0;
+	}
+
+	return -EINVAL;
+}
+
 static u64 gic_mpidr_to_affinity(u64 mpidr)
 {
 	u64 aff;
@@ -683,6 +713,7 @@ static struct irq_chip gic_chip = {
 	.irq_set_affinity	= gic_set_affinity,
 	.irq_get_irqchip_state	= gic_irq_get_irqchip_state,
 	.irq_set_irqchip_state	= gic_irq_set_irqchip_state,
+	.irq_set_vcpu_affinity	= gic_irq_set_vcpu_affinity,
 	.flags			= IRQCHIP_SET_TYPE_MASKED,
 };
 
-- 
2.1.4



From marc.zyngier at arm.com  Tue Aug 25 04:53:22 2015
From: marc.zyngier at arm.com (Marc Zyngier)
Date: Tue, 25 Aug 2015 12:53:22 +0100
Subject: [PATCH v3 1/4] irqchip: GICv3: Convert to EOImode == 1
In-Reply-To: <1440503605-10185-1-git-send-email-marc.zyngier@arm.com>
References: <1440503605-10185-1-git-send-email-marc.zyngier@arm.com>
Message-ID: <1440503605-10185-2-git-send-email-marc.zyngier@arm.com>

So far, GICv3 has been used in with EOImode == 0. The effect of this
mode is to perform the priority drop and the deactivation of the
interrupt at the same time.

While this works perfectly for Linux (we only have a single priority),
it causes issues when an interrupt is forwarded to a guest, and when
we want the guest to perform the EOI itself.

For this case, the GIC architecture provides EOImode == 1, where:
- A write to ICC_EOIR1_EL1 drops the priority of the interrupt and
  leaves it active. Other interrupts at the same priority level can
  now be taken, but the active interrupt cannot be taken again
- A write to ICC_DIR_EL1 marks the interrupt as inactive, meaning
  it can now be taken again.

This patch converts the driver to be able to use this new mode,
depending on whether or not the kernel can behave as a hypervisor.
No feature change.

Reviewed-by: Eric Auger <eric.auger at linaro.org>
Signed-off-by: Marc Zyngier <marc.zyngier at arm.com>
---
 drivers/irqchip/irq-gic-v3.c       | 39 ++++++++++++++++++++++++++++++++++----
 include/linux/irqchip/arm-gic-v3.h |  9 +++++++++
 2 files changed, 44 insertions(+), 4 deletions(-)

diff --git a/drivers/irqchip/irq-gic-v3.c b/drivers/irqchip/irq-gic-v3.c
index c52f7ba..addd2ee 100644
--- a/drivers/irqchip/irq-gic-v3.c
+++ b/drivers/irqchip/irq-gic-v3.c
@@ -30,6 +30,7 @@
 #include <asm/cputype.h>
 #include <asm/exception.h>
 #include <asm/smp_plat.h>
+#include <asm/virt.h>
 
 #include "irq-gic-common.h"
 #include "irqchip.h"
@@ -50,6 +51,7 @@ struct gic_chip_data {
 };
 
 static struct gic_chip_data gic_data __read_mostly;
+static struct static_key supports_deactivate = STATIC_KEY_INIT_TRUE;
 
 #define gic_data_rdist()		(this_cpu_ptr(gic_data.rdists.rdist))
 #define gic_data_rdist_rd_base()	(gic_data_rdist()->rd_base)
@@ -293,7 +295,14 @@ static int gic_irq_get_irqchip_state(struct irq_data *d,
 
 static void gic_eoi_irq(struct irq_data *d)
 {
-	gic_write_eoir(gic_irq(d));
+	if (static_key_true(&supports_deactivate)) {
+		/* No need to deactivate an LPI */
+		if (gic_irq(d) >= 8192)
+			return;
+		gic_write_dir(gic_irq(d));
+	} else {
+		gic_write_eoir(gic_irq(d));
+	}
 }
 
 static int gic_set_type(struct irq_data *d, unsigned int type)
@@ -343,15 +352,26 @@ static asmlinkage void __exception_irq_entry gic_handle_irq(struct pt_regs *regs
 
 		if (likely(irqnr > 15 && irqnr < 1020) || irqnr >= 8192) {
 			int err;
+
+			if (static_key_true(&supports_deactivate))
+				gic_write_eoir(irqnr);
+
 			err = handle_domain_irq(gic_data.domain, irqnr, regs);
 			if (err) {
 				WARN_ONCE(true, "Unexpected interrupt received!\n");
-				gic_write_eoir(irqnr);
+				if (static_key_true(&supports_deactivate)) {
+					if (irqnr < 8192)
+						gic_write_dir(irqnr);
+				} else {
+					gic_write_eoir(irqnr);
+				}
 			}
 			continue;
 		}
 		if (irqnr < 16) {
 			gic_write_eoir(irqnr);
+			if (static_key_true(&supports_deactivate))
+				gic_write_dir(irqnr);
 #ifdef CONFIG_SMP
 			handle_IPI(irqnr, regs);
 #else
@@ -451,8 +471,13 @@ static void gic_cpu_sys_reg_init(void)
 	/* Set priority mask register */
 	gic_write_pmr(DEFAULT_PMR_VALUE);
 
-	/* EOI deactivates interrupt too (mode 0) */
-	gic_write_ctlr(ICC_CTLR_EL1_EOImode_drop_dir);
+	if (static_key_true(&supports_deactivate)) {
+		/* EOI drops priority only (mode 1) */
+		gic_write_ctlr(ICC_CTLR_EL1_EOImode_drop);
+	} else {
+		/* EOI deactivates interrupt too (mode 0) */
+		gic_write_ctlr(ICC_CTLR_EL1_EOImode_drop_dir);
+	}
 
 	/* ... and let's hit the road... */
 	gic_write_grpen1(1);
@@ -820,6 +845,12 @@ static int __init gic_of_init(struct device_node *node, struct device_node *pare
 	if (of_property_read_u64(node, "redistributor-stride", &redist_stride))
 		redist_stride = 0;
 
+	if (!is_hyp_mode_available())
+		static_key_slow_dec(&supports_deactivate);
+
+	if (static_key_true(&supports_deactivate))
+		pr_info("GIC: Using split EOI/Deactivate mode\n");
+
 	gic_data.dist_base = dist_base;
 	gic_data.redist_regions = rdist_regs;
 	gic_data.nr_redist_regions = nr_redist_regions;
diff --git a/include/linux/irqchip/arm-gic-v3.h b/include/linux/irqchip/arm-gic-v3.h
index ffbc034..bc98832 100644
--- a/include/linux/irqchip/arm-gic-v3.h
+++ b/include/linux/irqchip/arm-gic-v3.h
@@ -104,6 +104,8 @@
 #define GICR_SYNCR			0x00C0
 #define GICR_MOVLPIR			0x0100
 #define GICR_MOVALLR			0x0110
+#define GICR_ISACTIVER			GICD_ISACTIVER
+#define GICR_ICACTIVER			GICD_ICACTIVER
 #define GICR_IDREGS			GICD_IDREGS
 #define GICR_PIDR2			GICD_PIDR2
 
@@ -288,6 +290,7 @@
 #define ICH_VMCR_PMR_MASK		(0xffUL << ICH_VMCR_PMR_SHIFT)
 
 #define ICC_EOIR1_EL1			sys_reg(3, 0, 12, 12, 1)
+#define ICC_DIR_EL1			sys_reg(3, 0, 12, 11, 1)
 #define ICC_IAR1_EL1			sys_reg(3, 0, 12, 12, 0)
 #define ICC_SGI1R_EL1			sys_reg(3, 0, 12, 11, 5)
 #define ICC_PMR_EL1			sys_reg(3, 0, 4, 6, 0)
@@ -384,6 +387,12 @@ static inline void gic_write_eoir(u64 irq)
 	isb();
 }
 
+static inline void gic_write_dir(u64 irq)
+{
+	asm volatile("msr_s " __stringify(ICC_DIR_EL1) ", %0" : : "r" (irq));
+	isb();
+}
+
 struct irq_domain;
 int its_cpu_init(void);
 int its_init(struct device_node *node, struct rdists *rdists,
-- 
2.1.4



From marc.zyngier at arm.com  Tue Aug 25 04:53:24 2015
From: marc.zyngier at arm.com (Marc Zyngier)
Date: Tue, 25 Aug 2015 12:53:24 +0100
Subject: [PATCH v3 3/4] irqchip: GIC: Convert to EOImode == 1
In-Reply-To: <1440503605-10185-1-git-send-email-marc.zyngier@arm.com>
References: <1440503605-10185-1-git-send-email-marc.zyngier@arm.com>
Message-ID: <1440503605-10185-4-git-send-email-marc.zyngier@arm.com>

So far, GICv2 has been used with EOImode == 0. The effect of this
mode is to perform the priority drop and the deactivation of the
interrupt at the same time.

While this works perfectly for Linux (we only have a single priority),
it causes issues when an interrupt is forwarded to a guest, and when
we want the guest to perform the EOI itself.

For this case, the GIC architecture provides EOImode == 1, where:
- A write to the EOI register drops the priority of the interrupt
  and leaves it active. Other interrupts at the same priority level
  can now be taken, but the active interrupt cannot be taken again
- A write to the DIR marks the interrupt as inactive, meaning it can
  now be taken again.

We only enable this feature when booted in HYP mode and that
the device-tree reported a suitable CPU interface. Observable behaviour
should remain unchanged.

Signed-off-by: Marc Zyngier <marc.zyngier at arm.com>
---
 drivers/irqchip/irq-gic.c       | 51 +++++++++++++++++++++++++++++++++++++++--
 include/linux/irqchip/arm-gic.h |  4 ++++
 2 files changed, 53 insertions(+), 2 deletions(-)

diff --git a/drivers/irqchip/irq-gic.c b/drivers/irqchip/irq-gic.c
index 4dd8826..505aaf3 100644
--- a/drivers/irqchip/irq-gic.c
+++ b/drivers/irqchip/irq-gic.c
@@ -46,6 +46,7 @@
 #include <asm/irq.h>
 #include <asm/exception.h>
 #include <asm/smp_plat.h>
+#include <asm/virt.h>
 
 #include "irq-gic-common.h"
 #include "irqchip.h"
@@ -82,6 +83,8 @@ static DEFINE_RAW_SPINLOCK(irq_controller_lock);
 #define NR_GIC_CPU_IF 8
 static u8 gic_cpu_map[NR_GIC_CPU_IF] __read_mostly;
 
+static struct static_key supports_deactivate = STATIC_KEY_INIT_TRUE;
+
 #ifndef MAX_GIC_NR
 #define MAX_GIC_NR	1
 #endif
@@ -137,6 +140,14 @@ static inline unsigned int gic_irq(struct irq_data *d)
 	return d->hwirq;
 }
 
+static inline bool primary_gic_irq(struct irq_data *d)
+{
+	if (MAX_GIC_NR > 1)
+		return irq_data_get_irq_chip_data(d) == &gic_data[0];
+
+	return true;
+}
+
 /*
  * Routines to acknowledge, disable and enable interrupts
  */
@@ -164,7 +175,14 @@ static void gic_unmask_irq(struct irq_data *d)
 
 static void gic_eoi_irq(struct irq_data *d)
 {
-	writel_relaxed(gic_irq(d), gic_cpu_base(d) + GIC_CPU_EOI);
+	u32 deact_offset = GIC_CPU_EOI;
+
+	if (static_key_true(&supports_deactivate)) {
+		if (primary_gic_irq(d))
+			deact_offset = GIC_CPU_DEACTIVATE;
+	}
+
+	writel_relaxed(gic_irq(d), gic_cpu_base(d) + deact_offset);
 }
 
 static int gic_irq_set_irqchip_state(struct irq_data *d,
@@ -272,11 +290,15 @@ static void __exception_irq_entry gic_handle_irq(struct pt_regs *regs)
 		irqnr = irqstat & GICC_IAR_INT_ID_MASK;
 
 		if (likely(irqnr > 15 && irqnr < 1021)) {
+			if (static_key_true(&supports_deactivate))
+				writel_relaxed(irqstat, cpu_base + GIC_CPU_EOI);
 			handle_domain_irq(gic->domain, irqnr, regs);
 			continue;
 		}
 		if (irqnr < 16) {
 			writel_relaxed(irqstat, cpu_base + GIC_CPU_EOI);
+			if (static_key_true(&supports_deactivate))
+				writel_relaxed(irqstat, cpu_base + GIC_CPU_DEACTIVATE);
 #ifdef CONFIG_SMP
 			handle_IPI(irqnr, regs);
 #endif
@@ -359,6 +381,10 @@ static void gic_cpu_if_up(void)
 {
 	void __iomem *cpu_base = gic_data_cpu_base(&gic_data[0]);
 	u32 bypass = 0;
+	u32 mode = 0;
+
+	if (static_key_true(&supports_deactivate))
+		mode = GIC_CPU_CTRL_EOImodeNS;
 
 	/*
 	* Preserve bypass disable bits to be written back later
@@ -366,7 +392,7 @@ static void gic_cpu_if_up(void)
 	bypass = readl(cpu_base + GIC_CPU_CTRL);
 	bypass &= GICC_DIS_BYPASS_MASK;
 
-	writel_relaxed(bypass | GICC_ENABLE, cpu_base + GIC_CPU_CTRL);
+	writel_relaxed(bypass | mode | GICC_ENABLE, cpu_base + GIC_CPU_CTRL);
 }
 
 
@@ -986,6 +1012,8 @@ void __init gic_init_bases(unsigned int gic_nr, int irq_start,
 		register_cpu_notifier(&gic_cpu_notifier);
 #endif
 		set_handle_irq(gic_handle_irq);
+		if (static_key_true(&supports_deactivate))
+			pr_info("GIC: Using split EOI/Deactivate mode\n");
 	}
 
 	gic_dist_init(gic);
@@ -1001,6 +1029,7 @@ gic_of_init(struct device_node *node, struct device_node *parent)
 {
 	void __iomem *cpu_base;
 	void __iomem *dist_base;
+	struct resource cpu_res;
 	u32 percpu_offset;
 	int irq;
 
@@ -1013,6 +1042,16 @@ gic_of_init(struct device_node *node, struct device_node *parent)
 	cpu_base = of_iomap(node, 1);
 	WARN(!cpu_base, "unable to map gic cpu registers\n");
 
+	of_address_to_resource(node, 1, &cpu_res);
+
+	/*
+	 * Disable split EOI/Deactivate if either HYP is not available
+	 * or the CPU interface is too small.
+	 */
+	if (gic_cnt == 0 && (!is_hyp_mode_available() ||
+			     resource_size(&cpu_res) < SZ_8K))
+		static_key_slow_dec(&supports_deactivate);
+
 	if (of_property_read_u32(node, "cpu-offset", &percpu_offset))
 		percpu_offset = 0;
 
@@ -1132,6 +1171,14 @@ gic_v2_acpi_init(struct acpi_table_header *table)
 	}
 
 	/*
+	 * Disable split EOI/Deactivate if HYP is not available. ACPI
+	 * guarantees that we'll always have a GICv2, so the CPU
+	 * interface will always be the right size.
+	 */
+	if (!is_hyp_mode_available())
+		static_key_slow_dec(&supports_deactivate);
+
+	/*
 	 * Initialize zero GIC instance (no multi-GIC support). Also, set GIC
 	 * as default IRQ domain to allow for GSI registration and GSI to IRQ
 	 * number translation (see acpi_register_gsi() and acpi_gsi_to_irq()).
diff --git a/include/linux/irqchip/arm-gic.h b/include/linux/irqchip/arm-gic.h
index 9de976b..b1533c0 100644
--- a/include/linux/irqchip/arm-gic.h
+++ b/include/linux/irqchip/arm-gic.h
@@ -20,9 +20,13 @@
 #define GIC_CPU_ALIAS_BINPOINT		0x1c
 #define GIC_CPU_ACTIVEPRIO		0xd0
 #define GIC_CPU_IDENT			0xfc
+#define GIC_CPU_DEACTIVATE		0x1000
 
 #define GICC_ENABLE			0x1
 #define GICC_INT_PRI_THRESHOLD		0xf0
+
+#define GIC_CPU_CTRL_EOImodeNS		(1 << 9)
+
 #define GICC_IAR_INT_ID_MASK		0x3ff
 #define GICC_INT_SPURIOUS		1023
 #define GICC_DIS_BYPASS_MASK		0x1e0
-- 
2.1.4



From marc.zyngier at arm.com  Tue Aug 25 04:53:25 2015
From: marc.zyngier at arm.com (Marc Zyngier)
Date: Tue, 25 Aug 2015 12:53:25 +0100
Subject: [PATCH v3 4/4] irqchip: GIC: Don't deactivate interrupts forwarded to
 a guest
In-Reply-To: <1440503605-10185-1-git-send-email-marc.zyngier@arm.com>
References: <1440503605-10185-1-git-send-email-marc.zyngier@arm.com>
Message-ID: <1440503605-10185-5-git-send-email-marc.zyngier@arm.com>

Commit 0a4377de3056 ("genirq: Introduce irq_set_vcpu_affinity() to
target an interrupt to a VCPU") added just what we needed at the
lowest level to allow an interrupt to be deactivated by a guest.

When such a request reaches the GIC, it knows it doesn't need to
perform the deactivation anymore, and can safely leave the guest
do its magic. This of course requires additional support in both
VFIO and KVM.

Reviewed-by: Eric Auger <eric.auger at linaro.org>
Tested-by: Eric Auger <eric.auger at linaro.org>
Signed-off-by: Marc Zyngier <marc.zyngier at arm.com>
---
 drivers/irqchip/irq-gic.c | 60 +++++++++++++++++++++++++++++++++++++++++++++++
 1 file changed, 60 insertions(+)

diff --git a/drivers/irqchip/irq-gic.c b/drivers/irqchip/irq-gic.c
index 505aaf3..5e48850 100644
--- a/drivers/irqchip/irq-gic.c
+++ b/drivers/irqchip/irq-gic.c
@@ -148,6 +148,36 @@ static inline bool primary_gic_irq(struct irq_data *d)
 	return true;
 }
 
+static inline bool cascading_gic_irq(struct irq_data *d)
+{
+	void *data = irq_data_get_irq_handler_data(d);
+
+	/*
+	 * If handler_data pointing to one of the secondary GICs, then
+	 * this is a cascading interrupt, and it cannot possibly be
+	 * forwarded.
+	 */
+	if (data >= (void *)(gic_data + 1) &&
+	    data <  (void *)(gic_data + MAX_GIC_NR))
+		return true;
+
+	return false;
+}
+
+static inline bool forwarded_irq(struct irq_data *d)
+{
+	/*
+	 * A forwarded interrupt:
+	 * - is on the primary GIC
+	 * - has its handler_data set to a value
+	 * - that isn't a secondary GIC
+	 */
+	if (primary_gic_irq(d) && d->handler_data && !cascading_gic_irq(d))
+		return true;
+
+	return false;
+}
+
 /*
  * Routines to acknowledge, disable and enable interrupts
  */
@@ -166,6 +196,18 @@ static int gic_peek_irq(struct irq_data *d, u32 offset)
 static void gic_mask_irq(struct irq_data *d)
 {
 	gic_poke_irq(d, GIC_DIST_ENABLE_CLEAR);
+	/*
+	 * When masking a forwarded interrupt, make sure it is
+	 * deactivated as well.
+	 *
+	 * This ensures that an interrupt that is getting
+	 * disabled/masked will not get "stuck", because there is
+	 * noone to deactivate it (guest is being terminated).
+	 */
+	if (static_key_true(&supports_deactivate)) {
+		if (forwarded_irq(d))
+			gic_poke_irq(d, GIC_DIST_ACTIVE_CLEAR);
+	}
 }
 
 static void gic_unmask_irq(struct irq_data *d)
@@ -178,6 +220,10 @@ static void gic_eoi_irq(struct irq_data *d)
 	u32 deact_offset = GIC_CPU_EOI;
 
 	if (static_key_true(&supports_deactivate)) {
+		/* Do not deactivate an IRQ forwarded to a vcpu. */
+		if (forwarded_irq(d))
+			return;
+
 		if (primary_gic_irq(d))
 			deact_offset = GIC_CPU_DEACTIVATE;
 	}
@@ -251,6 +297,19 @@ static int gic_set_type(struct irq_data *d, unsigned int type)
 	return gic_configure_irq(gicirq, type, base, NULL);
 }
 
+static int gic_irq_set_vcpu_affinity(struct irq_data *d, void *vcpu)
+{
+	/* Only interrupts on the primary GIC can be forwarded to a vcpu. */
+	if (static_key_true(&supports_deactivate)) {
+		if (primary_gic_irq(d) && !cascading_gic_irq(d)) {
+			d->handler_data = vcpu;
+			return 0;
+		}
+	}
+
+	return -EINVAL;
+}
+
 #ifdef CONFIG_SMP
 static int gic_set_affinity(struct irq_data *d, const struct cpumask *mask_val,
 			    bool force)
@@ -346,6 +405,7 @@ static struct irq_chip gic_chip = {
 #endif
 	.irq_get_irqchip_state	= gic_irq_get_irqchip_state,
 	.irq_set_irqchip_state	= gic_irq_set_irqchip_state,
+	.irq_set_vcpu_affinity	= gic_irq_set_vcpu_affinity,
 	.flags			= IRQCHIP_SET_TYPE_MASKED,
 };
 
-- 
2.1.4



From ulf.hansson at linaro.org  Tue Aug 25 05:04:49 2015
From: ulf.hansson at linaro.org (Ulf Hansson)
Date: Tue, 25 Aug 2015 14:04:49 +0200
Subject: [PATCH v3 1/2] mmc: sdhci: fix abort due to missing runtime PM
In-Reply-To: <f2ab27135652e987ba9bf3b152e9652d@agner.ch>
References: <1432192504-3601-1-git-send-email-stefan@agner.ch>
 <f2ab27135652e987ba9bf3b152e9652d@agner.ch>
Message-ID: <CAPDyKFosM5QHLL4bGXYtVRpEFisoOOUNJtSfcRLroiv1feAARA@mail.gmail.com>

On 30 July 2015 at 13:37, Stefan Agner <stefan at agner.ch> wrote:
> Hi Ulf,
>
> What is the status on that?
>
> --
> Stefan
>
> On 2015-05-21 09:15, Stefan Agner wrote:
>> When using i.MX ESDHC driver, while entering suspend while the device
>> is in runtime PM, the sdhci_(suspend|resume)_host function are called
>> with disabled clocks. Since this functions access the SDHC host
>> registers, this leads to an external abort on Vybrid SoC:
>>
>> [   37.772967] Unhandled fault: imprecise external abort (0x1c06) at 0x76f5f000
>> [   37.780304] Internal error: : 1c06 [#1] ARM
>> [   37.784670] Modules linked in:
>> [   37.787908] CPU: 0 PID: 428 Comm: sh Not tainted
>> 3.18.0-rc5-00119-geefd097-dirty #1540
>> [   37.796142] task: 8e246c00 ti: 8ca6c000 task.ti: 8ca6c000
>> [   37.801785] PC is at esdhc_writel_le+0x40/0xec
>> [   37.806431] LR is at sdhci_set_card_detection+0xe0/0xe4
>> [   37.811877] pc : [<803f0584>]    lr : [<803eaaa0>]    psr: 400f0013
>> [   37.811877] sp : 8ca6dd28  ip : 00000001  fp : 8ca6dd3c
>> [   37.823766] r10: 807a233c  r9 : 00000000  r8 : 8e8b7210
>> [   37.829194] r7 : 802d8a08  r6 : 8082e928  r5 : 00000000  r4 : 00000002
>> [   37.835974] r3 : 8ea34e90  r2 : 00000038  r1 : 00000000  r0 : 8ea32ac0
>> ...
>>
>> Clocks need to be enabled to access the registers. Fix the issue by
>> add runtime PM enabled pltfm implementation of suspend/resume which
>> take care of clocks by using the runtime PM API properly.
>>
>> Signed-off-by: Stefan Agner <stefan at agner.ch>
>> ---
>> Changes since v2:
>> - Implement a generic pltfm suspend/resume function instead of a local
>>   function in sdhci-esdhc-imx.c
>> - Convert sdhci-pxav3 to use the runtime PM enabled pltfm suspend/resume
>>   function too
>>
>>  drivers/mmc/host/sdhci-esdhc-imx.c |  2 +-
>>  drivers/mmc/host/sdhci-pltfm.c     | 36 ++++++++++++++++++++++++++++++++++++
>>  drivers/mmc/host/sdhci-pltfm.h     |  2 ++
>>  3 files changed, 39 insertions(+), 1 deletion(-)
>>
>> diff --git a/drivers/mmc/host/sdhci-esdhc-imx.c
>> b/drivers/mmc/host/sdhci-esdhc-imx.c
>> index 82f512d..7b7b3a3 100644
>> --- a/drivers/mmc/host/sdhci-esdhc-imx.c
>> +++ b/drivers/mmc/host/sdhci-esdhc-imx.c
>> @@ -1132,7 +1132,7 @@ static int sdhci_esdhc_runtime_resume(struct device *dev)
>>  #endif
>>
>>  static const struct dev_pm_ops sdhci_esdhc_pmops = {
>> -     SET_SYSTEM_SLEEP_PM_OPS(sdhci_pltfm_suspend, sdhci_pltfm_resume)
>> +     SET_SYSTEM_SLEEP_PM_OPS(sdhci_pltfm_rpm_suspend, sdhci_pltfm_rpm_resume)
>>       SET_RUNTIME_PM_OPS(sdhci_esdhc_runtime_suspend,
>>                               sdhci_esdhc_runtime_resume, NULL)
>>  };
>> diff --git a/drivers/mmc/host/sdhci-pltfm.c b/drivers/mmc/host/sdhci-pltfm.c
>> index a207f5a..38c03cd 100644
>> --- a/drivers/mmc/host/sdhci-pltfm.c
>> +++ b/drivers/mmc/host/sdhci-pltfm.c
>> @@ -31,6 +31,7 @@
>>  #include <linux/err.h>
>>  #include <linux/module.h>
>>  #include <linux/of.h>
>> +#include <linux/pm_runtime.h>
>>  #ifdef CONFIG_PPC
>>  #include <asm/machdep.h>
>>  #endif
>> @@ -256,6 +257,41 @@ const struct dev_pm_ops sdhci_pltfm_pmops = {
>>       .resume         = sdhci_pltfm_resume,
>>  };
>>  EXPORT_SYMBOL_GPL(sdhci_pltfm_pmops);
>> +
>> +int sdhci_pltfm_rpm_suspend(struct device *dev)
>> +{
>> +     int ret;
>> +     struct sdhci_host *host = dev_get_drvdata(dev);
>> +
>> +     pm_runtime_get_sync(dev);
>> +     ret = sdhci_suspend_host(host);
>> +     pm_runtime_mark_last_busy(dev);
>> +     pm_runtime_put_autosuspend(dev);
>> +     if (ret)
>> +             return ret;
>> +
>> +     return pm_runtime_force_suspend(dev);
>> +}
>> +EXPORT_SYMBOL_GPL(sdhci_pltfm_rpm_suspend);
>> +
>> +int sdhci_pltfm_rpm_resume(struct device *dev)
>> +{
>> +     int ret;
>> +     struct sdhci_host *host = dev_get_drvdata(dev);
>> +
>> +     ret = pm_runtime_force_resume(dev);
>> +
>> +     if (ret)
>> +             return ret;
>> +
>> +     pm_runtime_get_sync(dev);
>> +     ret = sdhci_resume_host(host);
>> +     pm_runtime_mark_last_busy(dev);
>> +     pm_runtime_put_autosuspend(dev);
>> +
>> +     return ret;
>> +}
>> +EXPORT_SYMBOL_GPL(sdhci_pltfm_rpm_resume);
>>  #endif       /* CONFIG_PM */
>>
>>  static int __init sdhci_pltfm_drv_init(void)
>> diff --git a/drivers/mmc/host/sdhci-pltfm.h b/drivers/mmc/host/sdhci-pltfm.h
>> index 04bc248..ac5f6ea 100644
>> --- a/drivers/mmc/host/sdhci-pltfm.h
>> +++ b/drivers/mmc/host/sdhci-pltfm.h
>> @@ -114,6 +114,8 @@ static inline void *sdhci_pltfm_priv(struct
>> sdhci_pltfm_host *host)
>>  extern int sdhci_pltfm_suspend(struct device *dev);
>>  extern int sdhci_pltfm_resume(struct device *dev);
>>  extern const struct dev_pm_ops sdhci_pltfm_pmops;
>> +extern int sdhci_pltfm_rpm_suspend(struct device *dev);
>> +extern int sdhci_pltfm_rpm_resume(struct device *dev);
>>  #define SDHCI_PLTFM_PMOPS (&sdhci_pltfm_pmops)
>>  #else
>>  #define SDHCI_PLTFM_PMOPS NULL
>

This is a bit complicated, mostly due to the code structure of sdhci
and around how it handles wakeup settings. I do understand that you
want to fix a real bug, but in this case I think we need to figure out
a long term solution, else we will be solving one problem but
inserting another.

Obviously the sdhci device needs to be runtime resumed while accessing
it. Now, I wonder *why* sdhci-pltfm drivers need to access their
devices during system suspend? Normally that's because you want to
apply a different wakeup configuration in system suspend than in
runtime suspend, but is that really the case? And if so, could we
teach sdhci_runtime_suspend_host() to deal with this?

So, I think we first need to understand how to let sdhci deal with
wakeups. By cleaning up that piece of code and possibly also
converting it to use the new wakeirq API
(drivers/base/power/wakeirq.c) we should be better prepared to apply a
proper fix for your issue.

Kind regards
Uffe


From ulf.hansson at linaro.org  Tue Aug 25 05:05:06 2015
From: ulf.hansson at linaro.org (Ulf Hansson)
Date: Tue, 25 Aug 2015 14:05:06 +0200
Subject: [PATCH v2] mmc: sunxi: Don't start commands while the card is busy
In-Reply-To: <55BC8ADE.3070802@redhat.com>
References: <1436541284-11800-1-git-send-email-hdegoede@redhat.com>
 <CAPDyKFoNe0bghfSXs48stHzZToTc7Hjd5gVPy-VbDF8bzdVVMQ@mail.gmail.com>
 <55BC8ADE.3070802@redhat.com>
Message-ID: <CAPDyKFrYvL33DsaATg4fyAJg=G3SEuOP+xU=o_UwasmNZ+a07Q@mail.gmail.com>

On 1 August 2015 at 11:01, Hans de Goede <hdegoede at redhat.com> wrote:
> Hi,
>
> On 21-07-15 14:15, Ulf Hansson wrote:
>>
>> On 10 July 2015 at 17:14, Hans de Goede <hdegoede at redhat.com> wrote:
>>>
>>> Some sdio wifi modules have not been working reliable with the sunxi-mmc
>>> host code. This turns out to be caused by it starting new commands while
>>> the card signals that it is still busy processing a previous command.
>>
>>
>> Which are those commands?
>
>
> The code were things get stuck when not waiting for the busy signal uses
> the following sdio helper functions:
>
> sdio_readb/sdio_writeb
> sdio_f0_readb/sdio_f0_writeb
> sdio_readw/sdio_writew
> sdio_readl/sdio_writel
> sdio_readsb
> sdio_memcpy_fromio/sdio_memcpy_toio
>
> And directly issues the following command:
>
>         mmc_dat.flags = write ? MMC_DATA_WRITE : MMC_DATA_READ;
>         mmc_cmd.opcode = SD_IO_RW_EXTENDED;
>         mmc_cmd.arg = write ? 1<<31 : 0;        /* write flag  */
>         mmc_cmd.arg |= (fn & 0x7) << 28;        /* SDIO func num */
>         mmc_cmd.arg |= 1<<27;                   /* block mode */
>         /* for function 1 the addr will be incremented */
>         mmc_cmd.arg |= (fn == 1) ? 1<<26 : 0;
>         mmc_cmd.flags = MMC_RSP_SPI_R5 | MMC_RSP_R5 | MMC_CMD_ADTC;
>
> I do not know if the busy wait is necessary for all
> of these, but the hack in the android kernel code,
> which inserts calls to a wait_card_busy function directly
> into: drivers/net/wireless/brcm80211/brcmfmac/bcmsdh.c
>
> Does so for all of these.
>
>> Or more interesting, which response types do
>>
>> these commands expect?
>> I don't think this is a sunxi specific issue, I have seen similar
>> issues for other host controllers.
>
>
> Agreed, recent dw-mmc patches address the same issue, also involving
> broadcom sdio wifi chips.
>
>> I am thinking that perhaps this should be managed by the mmc core
>> instead of local hacks to sunxi. Potentially we could make the core to
>> invoke the already existing host_ops->card_busy() callback when
>> needed...
>
>
> I'm fine with solving this either way, implementing host_ops->card_busy()
> for sunxi is easy, and if the core os modified to call that function
> before issue sdio io ops (which seems to be the common thing here),
> then that indeed is better then having the sunxi code always do
> the busy check.

Okay, so let's make the core to call the ->card_busy() callback and
then it's up to each host driver to implement that callback.

As an optimization, we might consider (in a separate step) to add
MMC_RSP_BUSY to the response type. I realize that would somewhat be a
violation of the spec, but apparently the SDIO spec isn't really clear
on this area.

>
>> Within this context, could I ask whether you controller supports IRQ
>> based HW-busy detection? Or you need polling of the status register?
>
>
> I'm afraid that we need to poll the status register. I've been unable
> to find an irq flag corresponding to this.

Okay, thanks for the info.

[...]

Kind regards
Uffe


From ulf.hansson at linaro.org  Tue Aug 25 05:05:56 2015
From: ulf.hansson at linaro.org (Ulf Hansson)
Date: Tue, 25 Aug 2015 14:05:56 +0200
Subject: [PATCH 1/2] mmc: core: enable CMD19 tuning for DDR50 mode
In-Reply-To: <CAGsJ_4wvvQdyjFi=JmWfASm-LbJMybrhC=Wxxn7jHZEP5dUfEw@mail.gmail.com>
References: <1439282492-6274-1-git-send-email-21cnbao@gmail.com>
 <CAPDyKFpXZD28NwNAhKQyxmWasVhk_7AeyOW6oXaBPHKuSTmGUA@mail.gmail.com>
 <CAGsJ_4wvvQdyjFi=JmWfASm-LbJMybrhC=Wxxn7jHZEP5dUfEw@mail.gmail.com>
Message-ID: <CAPDyKFpEwWvu3tnbMT9ZvM0TUvEHp0Qa8PADohyJoTaNZ9HS9g@mail.gmail.com>

On 20 August 2015 at 02:16, Barry Song <21cnbao at gmail.com> wrote:
> 2015-08-18 1:11 GMT+08:00 Ulf Hansson <ulf.hansson at linaro.org>:
>> On 11 August 2015 at 10:41, Barry Song <21cnbao at gmail.com> wrote:
>>> From: Weijun Yang <york.yang at csr.com>
>>>
>>> As SD Specifications Part1 Physical Layer Specification Version
>>> 3.01 says, CMD19 tuning is available for unlocked cards in transfer
>>> state of 1.8V signaling mode. The small difference between v3.00
>>> and 3.01 spec means that CMD19 tuning is also available for DDR50
>>> mode.
>>
>> So what happens with cards following the 3.0 spec version, those
>> doesn't need to support the tuning CMD right? Perhaps that needs to be
>> addressed in this patch well!?
>
> from HW registers of the card, we cann't know whether the HW needs
> tuning. it is said 3.0.x need tuning, but 3.0 doesn't need.  @weijun,
> pls fix me if i am wrong.
> if so, it seems we need a static flag somewhere to indicate whether
> the tuning is needed. we can't detect to find the tuning requirement.

Another way is to always try doing the tuning for DDR50, but in case
of errors just ignore them and print a debug/info message!?

Kind regards
Uffe


From ulf.hansson at linaro.org  Tue Aug 25 05:06:05 2015
From: ulf.hansson at linaro.org (Ulf Hansson)
Date: Tue, 25 Aug 2015 14:06:05 +0200
Subject: [PATCH v6 0/6] mmc: imx: a few fixes and new feature
In-Reply-To: <1439293111-21077-1-git-send-email-haibo.chen@freescale.com>
References: <1439293111-21077-1-git-send-email-haibo.chen@freescale.com>
Message-ID: <CAPDyKFriWeJTsymd+Ha0ZY+UWjpbEdKMwZgw1hA2zZhw5khPaw@mail.gmail.com>

On 11 August 2015 at 13:38, Haibo Chen <haibo.chen at freescale.com> wrote:
> Changes for v6:
> -remove duplicate code in esdhc_set_uhs_signaling().
> -fix a typo for patch-2.
> -make commit log of patch-3 more specific.
>
> Haibo Chen (6):
>   mmc: sdhci-esdhc-imx: add imx7d support and support HS400
>   mmc: sdhci-esdhc-imx: add tuning-step setting support
>   mmc: sdhci-esdhc-imx: add imx7d support in bingding doc
>   ARM: dts: imx7d-sdb: add eMMC5.0 support
>   mmc: sdhci-esdhc-imx: set back the burst_length_enable bit to 1
>   mmc: sdhci-esdhc-imx: change default watermark level and burst length
>
>  .../devicetree/bindings/mmc/fsl-imx-esdhc.txt      |   6 ++
>  arch/arm/boot/dts/imx7d-sdb.dts                    |  13 +++
>  drivers/mmc/host/sdhci-esdhc-imx.c                 | 114 ++++++++++++++++++++-
>  include/linux/platform_data/mmc-esdhc-imx.h        |   1 +
>  4 files changed, 130 insertions(+), 4 deletions(-)
>
> --
> 1.9.1
>

I have applied this for next - except patch4 as it needs and ack from
the IMX SOC maintainer, or it may be better to take that patch through
ARM soc...

Regarding patch3, which document the new bindings and the compatible
string, I moved this to be the first patch and fixed the spelling of
the commit message header.

Thanks!

Kind regards
Uffe


From ulf.hansson at linaro.org  Tue Aug 25 05:06:31 2015
From: ulf.hansson at linaro.org (Ulf Hansson)
Date: Tue, 25 Aug 2015 14:06:31 +0200
Subject: [linux-sunxi] [PATCH v3 1/3] mmc: sunxi: fix timeout in
 sunxi_mmc_oclk_onoff
In-Reply-To: <55CB5CE6.1000303@redhat.com>
References: <cover.1439381423.git.hramrach@gmail.com>
 <7f9c6f99b31702c02436ef3356b3ebffa4754260.1439381423.git.hramrach@gmail.com>
 <bdcb7ce26f359b7fedbd8559eb275c324bfb52bb.1439386047.git.hramrach@gmail.com>
 <55CB5CE6.1000303@redhat.com>
Message-ID: <CAPDyKFp67DTNXYiphqPKsKL9ZtGO28x_UZa-d-KifD-7EXGzhw@mail.gmail.com>

On 12 August 2015 at 16:49, Hans de Goede <hdegoede at redhat.com> wrote:
> Hi,
>
> On 08/12/2015 03:29 PM, Michal Suchanek wrote:
>>
>> The 250ms timeout is too short.
>>
>> On my system enabling the oclk takes under 50ms and disabling slightly
>> over 100ms when idle. Under load disabling the clock can take over
>> 350ms.
>>
>> This does not make mmc clock gating look like good option to have on
>> sunxi but the system should not crash with mmc clock gating enabled
>> nonetheless.
>>
>> This patch sets the timeout to 750ms.
>>
>> Signed-off-by: Michal Suchanek <hramrach at gmail.com>
>>
>> ---
>> v3
>>   - remove debug message
>
>
> Thanks, this one looks good to me:
>
> Acked-by: Hans de Goede <hdegoede at redhat.com>
>
> Ulf, can you apply this one please?
>
> Thanks & Regards,
>
> Hans
>

Thanks, applied for next!

Kind regards
Uffe

>
>
>> v2
>>   - fix formatting
>> ---
>>   drivers/mmc/host/sunxi-mmc.c | 2 +-
>>   1 file changed, 1 insertion(+), 1 deletion(-)
>>
>> diff --git a/drivers/mmc/host/sunxi-mmc.c b/drivers/mmc/host/sunxi-mmc.c
>> index 4d3e1ff..a7b7a67 100644
>> --- a/drivers/mmc/host/sunxi-mmc.c
>> +++ b/drivers/mmc/host/sunxi-mmc.c
>> @@ -595,7 +595,7 @@ static irqreturn_t sunxi_mmc_handle_manual_stop(int
>> irq, void *dev_id)
>>
>>   static int sunxi_mmc_oclk_onoff(struct sunxi_mmc_host *host, u32
>> oclk_en)
>>   {
>> -       unsigned long expire = jiffies + msecs_to_jiffies(250);
>> +       unsigned long expire = jiffies + msecs_to_jiffies(750);
>>         u32 rval;
>>
>>         rval = mmc_readl(host, REG_CLKCR);
>>
>


From geert at linux-m68k.org  Tue Aug 25 05:06:31 2015
From: geert at linux-m68k.org (Geert Uytterhoeven)
Date: Tue, 25 Aug 2015 14:06:31 +0200
Subject: [PATCH] ARM: shmobile: remove Makefile.boot
In-Reply-To: <1440113264-30359-1-git-send-email-horms+renesas@verge.net.au>
References: <1440113264-30359-1-git-send-email-horms+renesas@verge.net.au>
Message-ID: <CAMuHMdWYM6vVWzUQgR4u8cvoH6Jtq4XerYd2PbpvfUruDPi7-Q@mail.gmail.com>

On Fri, Aug 21, 2015 at 1:27 AM, Simon Horman
<horms+renesas at verge.net.au> wrote:
> Now that the only multiplatform boot is supported for all
> shmobile platforms Makefile.boot may be removed.
>
> This seems correct to me given:
> * Setting MACHINE to no value in arch/arm/Makefile
>   if CONFIG_ARCH_MULTIPLATFORM is set
> * Not including Makefile.boot in arch/arm/boot/Makefile
>   if MACHINE has no value
>
> Signed-off-by: Simon Horman <horms+renesas at verge.net.au>

Acked-by: Geert Uytterhoeven <geert+renesas at glider.be>

Gr{oetje,eeting}s,

                        Geert

--
Geert Uytterhoeven -- There's lots of Linux beyond ia32 -- geert at linux-m68k.org

In personal conversations with technical people, I call myself a hacker. But
when I'm talking to journalists I just say "programmer" or something like that.
                                -- Linus Torvalds


From ulf.hansson at linaro.org  Tue Aug 25 05:06:36 2015
From: ulf.hansson at linaro.org (Ulf Hansson)
Date: Tue, 25 Aug 2015 14:06:36 +0200
Subject: [PATCH] mmc: atmel-mci: remove useless include
In-Reply-To: <1439216808-11826-1-git-send-email-alexandre.belloni@free-electrons.com>
References: <1439216808-11826-1-git-send-email-alexandre.belloni@free-electrons.com>
Message-ID: <CAPDyKFrOnmd2prcsYsSpFD66V5vpcFWQvPyBQgyyiTde_ew7eg@mail.gmail.com>

On 10 August 2015 at 16:26, Alexandre Belloni
<alexandre.belloni at free-electrons.com> wrote:
> Definitions from linux/platform_data/atmel.h are not used, remove the
> include.
>
> Signed-off-by: Alexandre Belloni <alexandre.belloni at free-electrons.com>

Thanks, applied for next!

Kind regards
Uffe

> ---
>  drivers/mmc/host/atmel-mci.c | 1 -
>  1 file changed, 1 deletion(-)
>
> diff --git a/drivers/mmc/host/atmel-mci.c b/drivers/mmc/host/atmel-mci.c
> index 9a39e0b7e583..bf62e429f7fc 100644
> --- a/drivers/mmc/host/atmel-mci.c
> +++ b/drivers/mmc/host/atmel-mci.c
> @@ -29,7 +29,6 @@
>  #include <linux/slab.h>
>  #include <linux/stat.h>
>  #include <linux/types.h>
> -#include <linux/platform_data/atmel.h>
>  #include <linux/platform_data/mmc-atmel-mci.h>
>
>  #include <linux/mmc/host.h>
> --
> 2.1.4
>


From ulf.hansson at linaro.org  Tue Aug 25 05:06:48 2015
From: ulf.hansson at linaro.org (Ulf Hansson)
Date: Tue, 25 Aug 2015 14:06:48 +0200
Subject: [PATCH v3] mmc: sdhci: also get preset value and driver type for
 MMC_DDR52
In-Reply-To: <1439886099-5531-1-git-send-email-jszhang@marvell.com>
References: <1439886099-5531-1-git-send-email-jszhang@marvell.com>
Message-ID: <CAPDyKFpj+Mw5w43MD3wUssryn9y-Vyr6oNNQ+WVk2bLrbRUXjA@mail.gmail.com>

On 18 August 2015 at 10:21, Jisheng Zhang <jszhang at marvell.com> wrote:
> commit bb8175a8aa42 ("mmc: sdhci: clarify DDR timing mode between
> SD-UHS and eMMC") added MMC_DDR52 as eMMC's DDR mode to be
> distinguished from SD-UHS, but it missed setting driver type for
> MMC_DDR52 timing mode.
>
> So sometimes we get the following error on Marvell BG2Q DMP board:
>
> [    1.559598] mmcblk0: error -84 transferring data, sector 0, nr 8, cmd
> response 0x900, card status 0xb00
> [    1.569314] mmcblk0: retrying using single block read
> [    1.575676] mmcblk0: error -84 transferring data, sector 2, nr 6, cmd
> response 0x900, card status 0x0
> [    1.585202] blk_update_request: I/O error, dev mmcblk0, sector 2
> [    1.591818] mmcblk0: error -84 transferring data, sector 3, nr 5, cmd
> response 0x900, card status 0x0
> [    1.601341] blk_update_request: I/O error, dev mmcblk0, sector 3
>
> This patches fixes this by adding the missing driver type setting.
>
> Fixes: bb8175a8aa42 ("mmc: sdhci: clarify DDR timing mode ...")
> Signed-off-by: Jisheng Zhang <jszhang at marvell.com>

Thanks, applied for next!

Kind regards
Uffe

> ---
>  Since v2:
>   - fix sdhci_get_preset_value for MMC_DDR52
>   - add typical emmc error log which this patch intends to fix
>
>  Since v1:
>   - correct commit-msg
>
>  drivers/mmc/host/sdhci.c | 4 +++-
>  1 file changed, 3 insertions(+), 1 deletion(-)
>
> diff --git a/drivers/mmc/host/sdhci.c b/drivers/mmc/host/sdhci.c
> index 1dbe932..673d703 100644
> --- a/drivers/mmc/host/sdhci.c
> +++ b/drivers/mmc/host/sdhci.c
> @@ -1132,6 +1132,7 @@ static u16 sdhci_get_preset_value(struct sdhci_host *host)
>                 preset = sdhci_readw(host, SDHCI_PRESET_FOR_SDR104);
>                 break;
>         case MMC_TIMING_UHS_DDR50:
> +       case MMC_TIMING_MMC_DDR52:
>                 preset = sdhci_readw(host, SDHCI_PRESET_FOR_DDR50);
>                 break;
>         case MMC_TIMING_MMC_HS400:
> @@ -1559,7 +1560,8 @@ static void sdhci_do_set_ios(struct sdhci_host *host, struct mmc_ios *ios)
>                                  (ios->timing == MMC_TIMING_UHS_SDR25) ||
>                                  (ios->timing == MMC_TIMING_UHS_SDR50) ||
>                                  (ios->timing == MMC_TIMING_UHS_SDR104) ||
> -                                (ios->timing == MMC_TIMING_UHS_DDR50))) {
> +                                (ios->timing == MMC_TIMING_UHS_DDR50) ||
> +                                (ios->timing == MMC_TIMING_MMC_DDR52))) {
>                         u16 preset;
>
>                         sdhci_enable_preset_value(host, true);
> --
> 2.5.0
>


From ulf.hansson at linaro.org  Tue Aug 25 05:06:54 2015
From: ulf.hansson at linaro.org (Ulf Hansson)
Date: Tue, 25 Aug 2015 14:06:54 +0200
Subject: [PATCH] pwrseq: bind pinctrl pins before using the gpios
In-Reply-To: <1439812687-18259-1-git-send-email-srinivas.kandagatla@linaro.org>
References: <1439812687-18259-1-git-send-email-srinivas.kandagatla@linaro.org>
Message-ID: <CAPDyKFqMOr5DwDcOjDTUV4Eaqp4VK1Q-Dt2_KcG-GtsNOr8JkQ@mail.gmail.com>

On 17 August 2015 at 13:58, Srinivas Kandagatla
<srinivas.kandagatla at linaro.org> wrote:
> Some of the pin-controllers like the Qualcomms "qcom,pm8921", which
> require a pinconf to be setup to use pins as gpios. Using the pins
> directly without pinconf setup would result in incorrect output voltage
> or load settings. On the other hand pwrseq code does not configure the
> pinctrl by default as it does not go thru the driver core.
>
> This patch adds a call to pinctrl_bind_pins() to bind pins which
> are going to be used as gpios.
>
> Signed-off-by: Srinivas Kandagatla <srinivas.kandagatla at linaro.org>

Thanks, applied for next! I add the "mmc:" to the prefix of the commit
message header.

Kind regards
Uffe

> ---
>  drivers/mmc/core/pwrseq.c | 5 +++++
>  1 file changed, 5 insertions(+)
>
> diff --git a/drivers/mmc/core/pwrseq.c b/drivers/mmc/core/pwrseq.c
> index 4c1d175..6e5d8b3 100644
> --- a/drivers/mmc/core/pwrseq.c
> +++ b/drivers/mmc/core/pwrseq.c
> @@ -12,6 +12,7 @@
>  #include <linux/err.h>
>  #include <linux/of.h>
>  #include <linux/of_platform.h>
> +#include <linux/pinctrl/devinfo.h>
>
>  #include <linux/mmc/host.h>
>
> @@ -65,6 +66,10 @@ int mmc_pwrseq_alloc(struct mmc_host *host)
>                 goto err;
>         }
>
> +       ret = pinctrl_bind_pins(&pdev->dev);
> +       if (ret)
> +               goto err;
> +
>         match = mmc_pwrseq_find(np);
>         if (IS_ERR(match)) {
>                 ret = PTR_ERR(match);
> --
> 1.9.1
>


From ulf.hansson at linaro.org  Tue Aug 25 05:07:00 2015
From: ulf.hansson at linaro.org (Ulf Hansson)
Date: Tue, 25 Aug 2015 14:07:00 +0200
Subject: [PATCH 1/4] mmc: mediatek: Add online-tuning support of EMMC/SD
In-Reply-To: <1439812888.5627.9.camel@mhfsdcap03>
References: <1439367845-5891-1-git-send-email-chaotian.jing@mediatek.com>
 <1439367845-5891-2-git-send-email-chaotian.jing@mediatek.com>
 <CAPDyKFpX4Pp1+U9eNBuGd83sBeBgLU17qysAJ-2V-ABZZHYAGQ@mail.gmail.com>
 <1439812888.5627.9.camel@mhfsdcap03>
Message-ID: <CAPDyKFpGk9gcLLjBnN=+BD5WP-7dZ0+XHC1bcEEGGLvLbTyKHw@mail.gmail.com>

On 17 August 2015 at 14:01, Chaotian Jing <chaotian.jing at mediatek.com> wrote:
> Hi Ulf,
> Thanks, please see my comment:
> On Mon, 2015-08-17 at 13:31 +0200, Ulf Hansson wrote:
>> On 12 August 2015 at 10:24, Chaotian Jing <chaotian.jing at mediatek.com> wrote:
>> > Schedule a workqueue to do tuning when CRC error
>> > Call mmc_hw_reset to re-init card when data timeout
>>
>> Thanks to Adrian Hunter, the mmc core already supports re-tuning for
>> the above scenarios through the mmc_retune_*() APIs.
>>
>> SDHCI driver has already adopted to use that feature, you should do
>> that for the mtk-sd driver as well.
>>
>> Kind regards
>> Uffe
>>
> I also noticed that the mmc core already supports re-tuning, but it is
> not suitable for our host.
> For EMMC, the CMD21 only support HS200/HS400 mode, for SD card, CMD19
> only support SDR50/SDR104 mode, but in our host, even 50Mhz clock
> frequency may also occur CRC error, Cannot find a parameter that can
> cover all SD cards which running at 50Mhz, even 25Mhz, will occur CRC
> error for stress test, DDR50 mode is worse.

I don't follow. You may run for example HS200 in lower speed, nothing
will prevent tuning and re-tuning from happen for these scenarios.

Or you are talking about other speed modes than HS200/400 and
SDR50/104? If so, which speed modes are these?

BTW, there are currently a patch being discussed which is about adding
tuning for DDR mode. Please have look.
http://www.spinics.net/lists/arm-kernel/msg438434.html

Regarding re-tuning on CRC errors, that's already supported by the mmc
core. More precisely when a host driver returns -EILSEQ for a request.

> By the way,there are too many tune parameters need try for response,
> read data, write crc status CRC error, these parameters are
> multidimensional, it is hard to find a best parameter, and, try
> thousands of parameters will take long time.

As I see, it's your responsibility from the host driver to propagate
the proper error code towards the mmc core. If you encounter an error
that you want to trigger a retune, just return -EILSEQ.

Moreover, if you see a need to extend the tuning/re-tuning support in
the mmc core to suit your need - I am definitely open to look into
that. More importantly, I don't want to see host specific hacks trying
to deal with this.

Kind regards
Uffe


From varada at codeaurora.org  Tue Aug 25 05:08:04 2015
From: varada at codeaurora.org (Varadarajan Narayanan)
Date: Tue, 25 Aug 2015 17:38:04 +0530
Subject: [PATCH v4] qcom: ipq4019: Add basic board/dts support for IPQ4019 SoC
Message-ID: <20150825120804.GA30996@codeaurora.org>

Add initial dts files and SoC support for IPQ4019

Signed-off-by: Varadarajan Narayanan <varada at codeaurora.org>
---
Changes in v2:
  - Added devicetree bindings documentation

Changes in v3:
  - Split 'gcnt' into a separate patch
  - Added the new entries to Makefiles, Kconfig & board.c in sorted order
  - Used "qcom,ipq40xx" instead of "qcom,ipq40xx-r3pc" in board.c

Changes in v4:
  - Renamed IPQ40xx as IPQ4019
  - Moved kconfig and defconfig enablement to separate patch
  - Dropped Documentation/devicetree/bindings/qcom.txt

 arch/arm/boot/dts/Makefile              |  1 +
 arch/arm/boot/dts/qcom-ipq4019-r3pc.dts | 34 ++++++++++++++
 arch/arm/boot/dts/qcom-ipq4019.dtsi     | 81 +++++++++++++++++++++++++++++++++
 3 files changed, 116 insertions(+)
 create mode 100644 arch/arm/boot/dts/qcom-ipq4019-r3pc.dts
 create mode 100644 arch/arm/boot/dts/qcom-ipq4019.dtsi

diff --git a/arch/arm/boot/dts/Makefile b/arch/arm/boot/dts/Makefile
index 246473a..ca603f3 100644
--- a/arch/arm/boot/dts/Makefile
+++ b/arch/arm/boot/dts/Makefile
@@ -474,6 +474,7 @@ dtb-$(CONFIG_ARCH_QCOM) += \
 	qcom-apq8074-dragonboard.dtb \
 	qcom-apq8084-ifc6540.dtb \
 	qcom-apq8084-mtp.dtb \
+	qcom-ipq4019-r3pc.dtb \
 	qcom-ipq8064-ap148.dtb \
 	qcom-msm8660-surf.dtb \
 	qcom-msm8960-cdp.dtb \
diff --git a/arch/arm/boot/dts/qcom-ipq4019-r3pc.dts b/arch/arm/boot/dts/qcom-ipq4019-r3pc.dts
new file mode 100644
index 0000000..e3855d7
--- /dev/null
+++ b/arch/arm/boot/dts/qcom-ipq4019-r3pc.dts
@@ -0,0 +1,34 @@
+/* Copyright (c) 2014, The Linux Foundation. All rights reserved.
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License version 2 and
+ * only 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 "qcom-ipq4019.dtsi"
+
+/ {
+	model = "Qualcomm Technologies, Inc. IPQ4019 R3PC";
+	compatible = "qcom,ipq4019-r3pc", "qcom,ipq4019";
+
+	memory {
+		device_type = "memory";
+		reg = <0x80000000 0x20000000>; /* 512MB */
+	};
+
+	chosen {
+		bootargs = "root=/dev/ram rw init=/init initrd=0x82000000,0x000E2246";
+		stdout-path = "/serial at 78b0000:115200";
+	};
+
+	soc {
+		serial at 78b0000 {
+			status = "ok";
+		};
+	};
+};
diff --git a/arch/arm/boot/dts/qcom-ipq4019.dtsi b/arch/arm/boot/dts/qcom-ipq4019.dtsi
new file mode 100644
index 0000000..1be0322
--- /dev/null
+++ b/arch/arm/boot/dts/qcom-ipq4019.dtsi
@@ -0,0 +1,81 @@
+/*
+ * Copyright (c) 2014, The Linux Foundation. All rights reserved.
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License version 2 and
+ * only 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.
+ */
+
+/dts-v1/;
+
+#include "skeleton.dtsi"
+
+/ {
+	model = "Qualcomm Technologies, Inc. IPQ4019";
+	compatible = "qcom,ipq4019";
+	interrupt-parent = <&intc>;
+
+	cpus {
+		#address-cells = <1>;
+		#size-cells = <0>;
+		cpu at 0 {
+			device_type = "cpu";
+			compatible = "arm,cortex-a7";
+			reg = <0x0>;
+		};
+
+		cpu at 1 {
+			device_type = "cpu";
+			compatible = "arm,cortex-a7";
+			reg = <0x1>;
+		};
+
+		cpu at 2 {
+			device_type = "cpu";
+			compatible = "arm,cortex-a7";
+			reg = <0x2>;
+		};
+
+		cpu at 3 {
+			device_type = "cpu";
+			compatible = "arm,cortex-a7";
+			reg = <0x3>;
+		};
+	};
+
+	soc {
+		#address-cells = <1>;
+		#size-cells = <1>;
+		ranges;
+		compatible = "simple-bus";
+
+		intc: interrupt-controller at b000000 {
+			compatible = "qcom,msm-qgic2";
+			interrupt-controller;
+			#interrupt-cells = <3>;
+			reg = <0x0b000000 0x1000>,
+			<0x0b002000 0x1000>;
+		};
+
+		serial at 78b0000 {
+			compatible = "qcom,msm-uartdm-v1.4", "qcom,msm-uartdm";
+			reg = <0x78b0000 0x200>;
+			interrupts = <0 108 0>;
+			status = "disabled";
+		};
+	};
+
+	timer {
+		compatible = "arm,armv7-timer";
+		interrupts = <1 2 0xf08>,
+			     <1 3 0xf08>,
+			     <1 4 0xf08>,
+			     <1 1 0xf08>;
+		clock-frequency = <20833333>;
+	};
+};
-- 
1.8.2.1



From hdegoede at redhat.com  Tue Aug 25 05:09:45 2015
From: hdegoede at redhat.com (Hans de Goede)
Date: Tue, 25 Aug 2015 14:09:45 +0200
Subject: [PATCH v2] mmc: sunxi: Don't start commands while the card is busy
In-Reply-To: <CAPDyKFrYvL33DsaATg4fyAJg=G3SEuOP+xU=o_UwasmNZ+a07Q@mail.gmail.com>
References: <1436541284-11800-1-git-send-email-hdegoede@redhat.com>
 <CAPDyKFoNe0bghfSXs48stHzZToTc7Hjd5gVPy-VbDF8bzdVVMQ@mail.gmail.com>
 <55BC8ADE.3070802@redhat.com>
 <CAPDyKFrYvL33DsaATg4fyAJg=G3SEuOP+xU=o_UwasmNZ+a07Q@mail.gmail.com>
Message-ID: <55DC5B09.2020705@redhat.com>

Hi,

On 25-08-15 14:05, Ulf Hansson wrote:
> On 1 August 2015 at 11:01, Hans de Goede <hdegoede at redhat.com> wrote:
>> Hi,
>>
>> On 21-07-15 14:15, Ulf Hansson wrote:
>>>
>>> On 10 July 2015 at 17:14, Hans de Goede <hdegoede at redhat.com> wrote:
>>>>
>>>> Some sdio wifi modules have not been working reliable with the sunxi-mmc
>>>> host code. This turns out to be caused by it starting new commands while
>>>> the card signals that it is still busy processing a previous command.
>>>
>>>
>>> Which are those commands?
>>
>>
>> The code were things get stuck when not waiting for the busy signal uses
>> the following sdio helper functions:
>>
>> sdio_readb/sdio_writeb
>> sdio_f0_readb/sdio_f0_writeb
>> sdio_readw/sdio_writew
>> sdio_readl/sdio_writel
>> sdio_readsb
>> sdio_memcpy_fromio/sdio_memcpy_toio
>>
>> And directly issues the following command:
>>
>>          mmc_dat.flags = write ? MMC_DATA_WRITE : MMC_DATA_READ;
>>          mmc_cmd.opcode = SD_IO_RW_EXTENDED;
>>          mmc_cmd.arg = write ? 1<<31 : 0;        /* write flag  */
>>          mmc_cmd.arg |= (fn & 0x7) << 28;        /* SDIO func num */
>>          mmc_cmd.arg |= 1<<27;                   /* block mode */
>>          /* for function 1 the addr will be incremented */
>>          mmc_cmd.arg |= (fn == 1) ? 1<<26 : 0;
>>          mmc_cmd.flags = MMC_RSP_SPI_R5 | MMC_RSP_R5 | MMC_CMD_ADTC;
>>
>> I do not know if the busy wait is necessary for all
>> of these, but the hack in the android kernel code,
>> which inserts calls to a wait_card_busy function directly
>> into: drivers/net/wireless/brcm80211/brcmfmac/bcmsdh.c
>>
>> Does so for all of these.
>>
>>> Or more interesting, which response types do
>>>
>>> these commands expect?
>>> I don't think this is a sunxi specific issue, I have seen similar
>>> issues for other host controllers.
>>
>>
>> Agreed, recent dw-mmc patches address the same issue, also involving
>> broadcom sdio wifi chips.
>>
>>> I am thinking that perhaps this should be managed by the mmc core
>>> instead of local hacks to sunxi. Potentially we could make the core to
>>> invoke the already existing host_ops->card_busy() callback when
>>> needed...
>>
>>
>> I'm fine with solving this either way, implementing host_ops->card_busy()
>> for sunxi is easy, and if the core os modified to call that function
>> before issue sdio io ops (which seems to be the common thing here),
>> then that indeed is better then having the sunxi code always do
>> the busy check.
>
> Okay, so let's make the core to call the ->card_busy() callback and
> then it's up to each host driver to implement that callback.

Ok, do you plan to do a patch for this, or do you expect to get
one submitted to you ?

Regards,

Hans


> As an optimization, we might consider (in a separate step) to add
> MMC_RSP_BUSY to the response type. I realize that would somewhat be a
> violation of the spec, but apparently the SDIO spec isn't really clear
> on this area.
>
>>
>>> Within this context, could I ask whether you controller supports IRQ
>>> based HW-busy detection? Or you need polling of the status register?
>>
>>
>> I'm afraid that we need to poll the status register. I've been unable
>> to find an irq flag corresponding to this.
>
> Okay, thanks for the info.
>
> [...]
>
> Kind regards
> Uffe
>


From linux at arm.linux.org.uk  Tue Aug 25 05:38:00 2015
From: linux at arm.linux.org.uk (Russell King - ARM Linux)
Date: Tue, 25 Aug 2015 13:38:00 +0100
Subject: [PATCH 9/9] ARM: software-based priviledged-no-access support
In-Reply-To: <CAMuHMdWCLcDS=64m0J09KJJ4bDtgZ1Yvq8rw7u9FE0vZkKT2cw@mail.gmail.com>
References: <20150821133043.GV7557@n2100.arm.linux.org.uk>
 <E1ZSmQG-0002za-E3@rmk-PC.arm.linux.org.uk>
 <CAMuHMdVMka2mt5pFpnXfLRY2M3Sj_71MgEpthOia2C99RaP_DA@mail.gmail.com>
 <20150825104422.GO7557@n2100.arm.linux.org.uk>
 <CAMuHMdWCLcDS=64m0J09KJJ4bDtgZ1Yvq8rw7u9FE0vZkKT2cw@mail.gmail.com>
Message-ID: <20150825123800.GQ7557@n2100.arm.linux.org.uk>

On Tue, Aug 25, 2015 at 01:21:04PM +0200, Geert Uytterhoeven wrote:
> Hi Russell,
> 
> On Tue, Aug 25, 2015 at 12:44 PM, Russell King - ARM Linux
> <linux at arm.linux.org.uk> wrote:
> > On Tue, Aug 25, 2015 at 12:32:51PM +0200, Geert Uytterhoeven wrote:
> >> This patch, which is now in arm-soc/for-next, breaks shmobile_defconfig
> >> on r8a7791/koelsch, which has a dual core CA15:
> >>
> >>     [ ok ] Configuring network interfaces...done.
> >>     Unhandled fault: page domain fault (0x01b) at 0xbe8e6120
> >>     pgd = edbb0000
> >>     [be8e6120] *pgd=6da77831, *pte=bf4d075f, *ppte=bf4d0c7f
> >>     Internal error: : 1b [#1] SMP ARM
> >>     CPU: 1 PID: 1629 Comm: ntpdate Not tainted
> >> 4.2.0-rc8-06444-g3c24fd89c9421db1 #31
> >>     9
> >>     Hardware name: Generic R8A7791 (Flattened Device Tree)
> >>     task: ed883a80 ti: ed41c000 task.ti: ed41c000
> >>     PC is at csum_partial_copy_from_user+0x28/0x3d8
> >>     LR is at csum_and_copy_from_iter+0x334/0x4c0
> >>     pc : [<c04ba510>]    lr : [<c01c82e8>]    psr: 000f0013
> >>     sp : ed41db00  ip : 00000020  fp : ed41db6c
> >>     r10: ed41ddc0  r9 : 00000027  r8 : ed41dc20
> >>     r7 : 00000027  r6 : eda52653  r5 : ed41dec8  r4 : 00000000
> >>     r3 : 00000000  r2 : 00000027  r1 : eda5262c  r0 : be8e6120
> >>     Flags: nzcv  IRQs on  FIQs on  Mode SVC_32  ISA ARM  Segment none
> >>     Control: 10c5307d  Table: 6dbb006a  DAC: 00000051
> >>     Process ntpdate (pid: 1629, stack limit = 0xed41c210)
> >
> > Thanks.  I wonder what's different about your ntpdate that triggers
> > this, and why all my iMX6 behave fine, which have desktop-like ubuntu
> > installs on (of two different versions.)
> 
> It's ntpdate 1:4.2.6.p5+dfsg-7 from desktop-like Debian jessie.

Hmm, I think I tried at one time to install Debian on an iMX6 platform
and gave up with it after spending 50 minutes with the installer getting
so far, and then killing the network - it was very repeatable, and always
happened at the same point in the installation.  I gave up with Debian
at that point, as I didn't have lots of 50 minutes to babysit the silly
installer (which can't ask the questions up-front) nor did I want to
waste my monthly internet allowance on multiple failed install attempts.

The reports I was getting from other iMX6 users was that Debian Jessie
had lots of problems at that time.

> But I get similar dumps during boot up from rpc.idmapd (SyS_send),
> rsyslogd (SyS_send), and from sshd (SyS_write) when trying to log in.

Hmm.

root       693  0.0  0.1   4944  3196 ?        Ss   01:22   0:00 /usr/sbin/sshd -D
syslog     720  0.2  0.0  30404  2032 ?        Sl   01:23   1:19 rsyslogd -c5
root       722  0.0  0.0   2392  1340 ?        Ss   01:23   0:00 rpc.idmapd

So, the question I need to find an answer to is... why hasn't this path
been exercised on my platforms during my testing.  It's certainly
compiled into the kernel...

Anyway, I've now (hopefully) fixed the bug, but I've nobbled
csum_partial_copy_from_user to ensure that it will always oops the kernel
if called:

000000b4 <csum_partial_copy_from_user>:
  b4:   ee133f10        mrc     15, 0, r3, cr3, cr0, {0}
  b8:   e92d41fe        push    {r1, r2, r3, r4, r5, r6, r7, r8, lr}
  bc:   e3a03055        mov     r3, #85 ; 0x55
  c0:   ee033f10        mcr     15, 0, r3, cr3, cr0, {0}
  c4:   e7033003        str     r3, [r3, -r3]

and... it doesn't trigger.  I can only assume that this is because the
iMX6 ethernet interface uses TSO (which implies checksum offload), there's
no need to use these csum functions - and that would explain why it never
came up in my local testing.

-- 
FTTC broadband for 0.8mile line: currently at 10.5Mbps down 400kbps up
according to speedtest.net.


From linux at arm.linux.org.uk  Tue Aug 25 05:40:43 2015
From: linux at arm.linux.org.uk (Russell King - ARM Linux)
Date: Tue, 25 Aug 2015 13:40:43 +0100
Subject: [PATCH] ARM: enable imprecise aborts during early kernel startup
In-Reply-To: <1440501845-25723-1-git-send-email-l.stach@pengutronix.de>
References: <1440501845-25723-1-git-send-email-l.stach@pengutronix.de>
Message-ID: <20150825124042.GR7557@n2100.arm.linux.org.uk>

On Tue, Aug 25, 2015 at 01:24:05PM +0200, Lucas Stach wrote:
> From: Fabrice Gasnier <fabrice.gasnier at st.com>
> 
> This patch adds imprecise abort enable/disable macros and uses them to
> enable imprecise aborts early when starting the kernel.
> 
> This helps in tracking down the real cause for such imprecise abort, as
> they are handled as soon as they occur. Until now those aborts would
> only be enabled when entering the userspace and as a consequence crash
> the first userspace process if any abort had been raised during kernel
> startup.
> 
> Signed-off-by: Fabrice Gasnier <fabrice.gasnier at st.com>
> Signed-off-by: Lucas Stach <l.stach at pengutronix.de>

Looks fine to me.  I think as we know Keystone2 definitely has issues
with this, I'd like to delay it to the v4.4 merge window, but please
consider putting it in the patch system anyway so it doesn't get
forgotten about.  I'll queue it after 4.3-rc1 is out.

Thanks.

-- 
FTTC broadband for 0.8mile line: currently at 10.5Mbps down 400kbps up
according to speedtest.net.


From geert at linux-m68k.org  Tue Aug 25 05:47:23 2015
From: geert at linux-m68k.org (Geert Uytterhoeven)
Date: Tue, 25 Aug 2015 14:47:23 +0200
Subject: [PATCH 9/9] ARM: software-based priviledged-no-access support
In-Reply-To: <20150825123800.GQ7557@n2100.arm.linux.org.uk>
References: <20150821133043.GV7557@n2100.arm.linux.org.uk>
 <E1ZSmQG-0002za-E3@rmk-PC.arm.linux.org.uk>
 <CAMuHMdVMka2mt5pFpnXfLRY2M3Sj_71MgEpthOia2C99RaP_DA@mail.gmail.com>
 <20150825104422.GO7557@n2100.arm.linux.org.uk>
 <CAMuHMdWCLcDS=64m0J09KJJ4bDtgZ1Yvq8rw7u9FE0vZkKT2cw@mail.gmail.com>
 <20150825123800.GQ7557@n2100.arm.linux.org.uk>
Message-ID: <CAMuHMdUjojHFuARpeYi5mquCsNX1Lqy2Zw2YHmg9p0DLGS9WFw@mail.gmail.com>

On Tue, Aug 25, 2015 at 2:38 PM, Russell King - ARM Linux
<linux at arm.linux.org.uk> wrote:
>> It's ntpdate 1:4.2.6.p5+dfsg-7 from desktop-like Debian jessie.
>
> Hmm, I think I tried at one time to install Debian on an iMX6 platform
> and gave up with it after spending 50 minutes with the installer getting
> so far, and then killing the network - it was very repeatable, and always
> happened at the same point in the installation.  I gave up with Debian
> at that point, as I didn't have lots of 50 minutes to babysit the silly
> installer (which can't ask the questions up-front) nor did I want to
> waste my monthly internet allowance on multiple failed install attempts.

debootstrap is your friend.

Gr{oetje,eeting}s,

                        Geert

--
Geert Uytterhoeven -- There's lots of Linux beyond ia32 -- geert at linux-m68k.org

In personal conversations with technical people, I call myself a hacker. But
when I'm talking to journalists I just say "programmer" or something like that.
                                -- Linus Torvalds


From l.stach at pengutronix.de  Tue Aug 25 05:56:09 2015
From: l.stach at pengutronix.de (Lucas Stach)
Date: Tue, 25 Aug 2015 14:56:09 +0200
Subject: [PATCH] ARM: enable imprecise aborts during early kernel startup
In-Reply-To: <20150825124042.GR7557@n2100.arm.linux.org.uk>
References: <1440501845-25723-1-git-send-email-l.stach@pengutronix.de>
 <20150825124042.GR7557@n2100.arm.linux.org.uk>
Message-ID: <1440507369.3066.38.camel@pengutronix.de>

Am Dienstag, den 25.08.2015, 13:40 +0100 schrieb Russell King - ARM
Linux:
> On Tue, Aug 25, 2015 at 01:24:05PM +0200, Lucas Stach wrote:
> > From: Fabrice Gasnier <fabrice.gasnier at st.com>
> > 
> > This patch adds imprecise abort enable/disable macros and uses them to
> > enable imprecise aborts early when starting the kernel.
> > 
> > This helps in tracking down the real cause for such imprecise abort, as
> > they are handled as soon as they occur. Until now those aborts would
> > only be enabled when entering the userspace and as a consequence crash
> > the first userspace process if any abort had been raised during kernel
> > startup.
> > 
> > Signed-off-by: Fabrice Gasnier <fabrice.gasnier at st.com>
> > Signed-off-by: Lucas Stach <l.stach at pengutronix.de>
> 
> Looks fine to me.  I think as we know Keystone2 definitely has issues
> with this, I'd like to delay it to the v4.4 merge window, but please
> consider putting it in the patch system anyway so it doesn't get
> forgotten about.  I'll queue it after 4.3-rc1 is out.
> 
That sounds sensible.

Patch is in the system as 8422/1.

Regards,
Lucas

-- 
Pengutronix e.K.             | Lucas Stach                 |
Industrial Linux Solutions   | http://www.pengutronix.de/  |



From leo.yan at linaro.org  Tue Aug 25 06:01:49 2015
From: leo.yan at linaro.org (Leo Yan)
Date: Tue, 25 Aug 2015 21:01:49 +0800
Subject: [PATCH v1 1/3] dt-bindings: mailbox: Document Hi6220 mailbox
 driver
In-Reply-To: <55DC4EC0.4060301@arm.com>
References: <1439977055-1747-1-git-send-email-leo.yan@linaro.org>
 <1439977055-1747-2-git-send-email-leo.yan@linaro.org>
 <55DC4EC0.4060301@arm.com>
Message-ID: <20150825130149.GA28262@leoy-linaro>

Hi Sudeep,

Thanks for review, please see below comment.

On Tue, Aug 25, 2015 at 12:17:20PM +0100, Sudeep Holla wrote:
> On 19/08/15 10:37, Leo Yan wrote:
> >Document the new compatible for Hisilicon Hi6220 mailbox driver.
> >
> >Signed-off-by: Leo Yan <leo.yan at linaro.org>
> >---
> >  .../bindings/mailbox/hisilicon,hi6220-mailbox.txt  | 57 ++++++++++++++++++++++
> >  1 file changed, 57 insertions(+)
> >  create mode 100644 Documentation/devicetree/bindings/mailbox/hisilicon,hi6220-mailbox.txt
> >
> >diff --git a/Documentation/devicetree/bindings/mailbox/hisilicon,hi6220-mailbox.txt b/Documentation/devicetree/bindings/mailbox/hisilicon,hi6220-mailbox.txt
> >new file mode 100644
> >index 0000000..3dfb0b0
> >--- /dev/null
> >+++ b/Documentation/devicetree/bindings/mailbox/hisilicon,hi6220-mailbox.txt
> >@@ -0,0 +1,57 @@
> >+Hisilicon Hi6220 Mailbox Driver
> >+===============================
> >+
> >+Hisilicon Hi6220 mailbox supports up to 32 channels. Each channel
> >+is unidirectional with a maximum message size of 8 words. I/O is
> >+performed using register access (there is no DMA) and the cell
> >+raises an interrupt when messages are received.
> >+
> >+Mailbox Device Node:
> >+====================
> >+
> >+Required properties:
> >+--------------------
> >+- compatible:		Shall be "hisilicon,hi6220-mbox"
> >+- reg:			Contains the mailbox register address range (base
> >+			address and length); the first item is for IPC
> >+			registers, the second item is shared buffer for
> >+			slots.
> 
> Not sure if the shared buffer needs to be part of the controller binding
> as it's not related to it. It's just agreement between the endpoints of
> this mailbox on particular SoC and IMO has to part of the client binding.

Yes, we need distinguish the buffer is really used for channel's
management or just only used for client. Here "shared buffer" is
used for channels' state machine, mode and raw data with 8 words.

So mailbox driver just read/write raw data according to client's
requirement, client will define their specific format for data
transcation.

Thanks,
Leo Yan


From sudeep.holla at arm.com  Tue Aug 25 06:02:54 2015
From: sudeep.holla at arm.com (Sudeep Holla)
Date: Tue, 25 Aug 2015 14:02:54 +0100
Subject: [PATCH v3 1/1] misc: sram: add dev_pm_ops to support module power
 gate
In-Reply-To: <1438272681-29338-1-git-send-email-shenwei.wang@freescale.com>
References: <1438272681-29338-1-git-send-email-shenwei.wang@freescale.com>
Message-ID: <55DC677E.1030004@arm.com>



On 30/07/15 17:11, Shenwei Wang wrote:
> When system goes into low power states like SUSPEND_MEM and
> HIBERNATION, the hardware IP block may be powered off to reduce
> the power consumption. This power down will lost all the
> data inside the ram. This patch added the dev_pm_ops and
> implemented two callbacks: suspend_noirq and resume_noirq, which
> will save the data in the on-chip-ram right before power down
> and restore it after system resumes.
>

Who uses this SRAM ? Can't they be released before suspending ?
This might not be feasible and time consuming as the size of SRAM increases.

Also I just check the entire tree for the users of gen_pool, I found
it's used for video/audio and crypto which needs to on-demand basis.
Apart from that it's mainly used for low power modes in which case,
SRAM needs to be powered on. So can you provide more details on your
use-case.

> A new property string named "can-power-gate" is added to
> the devicetree bindings too.
>
> Signed-off-by: Shenwei Wang <shenwei.wang at freescale.com>
> Signed-off-by: Anson Huang <b20788 at freescale.com>
> ---
> Change log:
>
> PATCH v3
> 	Removed the unnecessary clk_enable/clk_disable.
>
> PATCH v2
> 	Use vmalloc to allocate the SRAM backup memory.
> 	Code clean up.
>
>   Documentation/devicetree/bindings/misc/sram.txt |  2 ++
>   drivers/misc/sram.c                             | 42 +++++++++++++++++++++++++
>   2 files changed, 44 insertions(+)
>
> diff --git a/Documentation/devicetree/bindings/misc/sram.txt b/Documentation/devicetree/bindings/misc/sram.txt
> index 36cbe5a..1170086 100644
> --- a/Documentation/devicetree/bindings/misc/sram.txt
> +++ b/Documentation/devicetree/bindings/misc/sram.txt
> @@ -33,6 +33,8 @@ Optional properties in the area nodes:
>
>   - compatible : standard definition, should contain a vendor specific string
>                  in the form <vendor>,[<device>-]<usage>
> +- can-power-gate: a property to tell the driver that the sram can support
> +		power gate
>

Please cc device-tree list for such generic bindings.

Regards,
Sudeep


From nschichan at freebox.fr  Tue Aug 25 06:17:41 2015
From: nschichan at freebox.fr (Nicolas Schichan)
Date: Tue, 25 Aug 2015 15:17:41 +0200
Subject: Prevent list poison values from being mapped by userspace
 processes
In-Reply-To: <20150825081556.GL7557@n2100.arm.linux.org.uk>
References: <CABXk95C=CpeL4mNmS6-jJ-0bMJf6fawwfs6DM1-p8FctTEFbpw@mail.gmail.com>
 <20150821133043.GV7557@n2100.arm.linux.org.uk> <55DB16AF.7090607@freebox.fr>
 <20150825081556.GL7557@n2100.arm.linux.org.uk>
Message-ID: <55DC6AF5.1090306@freebox.fr>

On 08/25/2015 10:15 AM, Russell King - ARM Linux wrote:
>> Also, when CONFIG_CPU_SW_DOMAIN_PAN is not set, the DACR_INIT constant is
>> setup with (domain_val(DOMAIN_USER, DOMAIN_NOACCESS) which will cause the
>> kernel to die with a "page domain fault" when running init.
> 
> If you don't mind, I'll merge that into the patch adding this so it
> doesn't introduce a regression there.
> 
> Once I've fixed the abort handler issue, would you mind re-testing
> and giving a tested-by attributation please?

Sure, I've got no problem with that and I'll be happy to re-test.

-- 
Nicolas Schichan



From yingjoe.chen at mediatek.com  Tue Aug 25 06:21:11 2015
From: yingjoe.chen at mediatek.com (Yingjoe Chen)
Date: Tue, 25 Aug 2015 21:21:11 +0800
Subject: [PATCH V2] clockevents/drivers/mtk: Fix spurious interrupt
 leading to crash
In-Reply-To: <1440453450-21203-1-git-send-email-daniel.lezcano@linaro.org>
References: <1440426924.17418.11.camel@mtksdaap41>
 <1440453450-21203-1-git-send-email-daniel.lezcano@linaro.org>
Message-ID: <1440508871.29634.1.camel@mtksdaap41>

On Mon, 2015-08-24 at 23:57 +0200, Daniel Lezcano wrote:
> After analysis done by Yingjoe Chen, the timer appears to have a pending
> interrupt when it is enabled.
> 
> Fix this by acknowledging the pending interrupt when enabling the timer
> interrupt.
> 
> Signed-off-by: Daniel Lezcano <daniel.lezcano at linaro.org>
> ---
>  drivers/clocksource/mtk_timer.c | 16 ++++++----------
>  1 file changed, 6 insertions(+), 10 deletions(-)
> 
> diff --git a/drivers/clocksource/mtk_timer.c b/drivers/clocksource/mtk_timer.c
> index 4cd16fb..505f53d 100644
> --- a/drivers/clocksource/mtk_timer.c
> +++ b/drivers/clocksource/mtk_timer.c
> @@ -156,14 +156,6 @@ static irqreturn_t mtk_timer_interrupt(int irq, void *dev_id)
>  	return IRQ_HANDLED;
>  }
>  
> -static void mtk_timer_global_reset(struct mtk_clock_event_device *evt)
> -{
> -	/* Disable all interrupts */
> -	writel(0x0, evt->gpt_base + GPT_IRQ_EN_REG);
> -	/* Acknowledge all interrupts */
> -	writel(0x3f, evt->gpt_base + GPT_IRQ_ACK_REG);
> -}
> -
>  static void
>  mtk_timer_setup(struct mtk_clock_event_device *evt, u8 timer, u8 option)
>  {
> @@ -183,6 +175,12 @@ static void mtk_timer_enable_irq(struct mtk_clock_event_device *evt, u8 timer)
>  {
>  	u32 val;
>  
> +	/* Disable all interrupts */
> +	writel(0x0, evt->gpt_base + GPT_IRQ_EN_REG);
> +
> +	/* Acknowledge all spurious pending interrupts */
> +	writel(0x3f, evt->gpt_base + GPT_IRQ_ACK_REG);
> +
>  	val = readl(evt->gpt_base + GPT_IRQ_EN_REG);
>  	writel(val | GPT_IRQ_ENABLE(timer),
>  			evt->gpt_base + GPT_IRQ_EN_REG);
> @@ -232,8 +230,6 @@ static void __init mtk_timer_init(struct device_node *node)
>  	}
>  	rate = clk_get_rate(clk);
>  
> -	mtk_timer_global_reset(evt);
> -
>  	if (request_irq(evt->dev.irq, mtk_timer_interrupt,
>  			IRQF_TIMER | IRQF_IRQPOLL, "mtk_timer", evt)) {
>  		pr_warn("failed to setup irq %d\n", evt->dev.irq);


Hi Daniel,


Thanks for your patch, tested on mt8173
Tested-by: Yingjoe Chen <yingjoe.chen at mediatek.com>

Joe.C




From robherring2 at gmail.com  Tue Aug 25 06:27:10 2015
From: robherring2 at gmail.com (Rob Herring)
Date: Tue, 25 Aug 2015 08:27:10 -0500
Subject: [PATCH v3 06/14] Documentation: drm/bridge: add document for
 analogix_dp
In-Reply-To: <20150825091534.GB14034@ulmo.nvidia.com>
References: <1439995728-18046-1-git-send-email-ykk@rock-chips.com>
 <1439995834-18363-1-git-send-email-ykk@rock-chips.com>
 <CAL_JsqLz+8RtBucctUj4euXZ3Ac0DvB52N9ONpAerh5T9BiTJg@mail.gmail.com>
 <20150825091534.GB14034@ulmo.nvidia.com>
Message-ID: <CAL_Jsq++RLZo4gvEUTKO8MfEPwSqT2R+bqG22Jsgb2qLgDQFpw@mail.gmail.com>

On Tue, Aug 25, 2015 at 4:15 AM, Thierry Reding <treding at nvidia.com> wrote:
> On Sun, Aug 23, 2015 at 06:23:14PM -0500, Rob Herring wrote:
>> On Wed, Aug 19, 2015 at 9:50 AM, Yakir Yang <ykk at rock-chips.com> wrote:
> [...]
>> > +       -analogix,link-rate:
>> > +               max link rate supported by the eDP controller.
>> > +                       LINK_RATE_1_62GBPS = 0x6, LINK_RATE_2_70GBPS = 0x0A,
>> > +                       LINK_RATE_5_40GBPS = 0x14
>>
>> Same here. I'd rather see something like "link-rate-mbps" and use the
>> actual rate.
>
> There is no need whatsoever to hard-code this in DT. (e)DP provides the
> means to detect what rate the link supports and the specification
> provides guidance on how to select an appropriate one.

Good, even better.

Rob


From Shenwei.Wang at freescale.com  Tue Aug 25 06:38:28 2015
From: Shenwei.Wang at freescale.com (Shenwei Wang)
Date: Tue, 25 Aug 2015 13:38:28 +0000
Subject: [PATCH v9 1/1] irqchip: imx-gpcv2: IMX GPCv2 driver for wakeup
 sources
In-Reply-To: <55DC3452.3070205@arm.com>
References: <1440443055-7291-1-git-send-email-shenwei.wang@freescale.com>
 <55DC3452.3070205@arm.com>
Message-ID: <CY1PR0301MB08439B6C5F841AFFD152DFD883610@CY1PR0301MB0843.namprd03.prod.outlook.com>



> -----Original Message-----
> From: Sudeep Holla [mailto:sudeep.holla at arm.com]
> Sent: 2015?8?25? 4:25
> To: Wang Shenwei-B38339
> Cc: shawn.guo at linaro.org; tglx at linutronix.de; jason at lakedaemon.net; Sudeep
> Holla; Huang Yongcai-B20788; linux-kernel at vger.kernel.org;
> linux-arm-kernel at lists.infradead.org
> Subject: Re: [PATCH v9 1/1] irqchip: imx-gpcv2: IMX GPCv2 driver for wakeup
> sources
> 
> 
> 
> On 24/08/15 20:04, Shenwei Wang wrote:
> > IMX7D contains a new version of GPC IP block (GPCv2). It has two major
> > functions: power management and wakeup source management.
> > This patch adds a new irqchip driver to manage the interrupt wakeup
> > sources on IMX7D.
> 
> Interesting, you mention that this IP block has mainly power management and it
> itself requires save/restore. Is it not in always on domain ?

Yes, it is in always on domain.

> > When the system is in WFI (wait for interrupt) mode, this GPC block
> > will be the first block on the platform to be activated and signaled.
> > Under normal wait mode during cpu idle, the system can be woke up by
> > +static void gpcv2_wakeup_source_restore(void) {
> > +	struct gpcv2_irqchip_data *cd;
> > +	void __iomem *reg;
> > +	int i;
> > +
> > +	cd = imx_gpcv2_instance;
> > +	if (!cd)
> > +		return;
> > +
> > +	for (i = 0; i < IMR_NUM; i++) {
> > +		reg = cd->gpc_base + cd->cpu2wakeup + i * 4;
> > +		writel_relaxed(cd->saved_irq_mask[i], reg);
> 
> Instead of saving all the non-wakeup sources, can't you use raw save/restore of
> these registers and mask all the non-wakeup sources by setting
> MASK_ON_SUSPEND ?

I can't catch what you mean. Can you show me an example?

> Also your interrupt controller seems like has no special way to configure wakeups,
> you are just leaving them enabled. i.e. I see cpu2wakeup used for both
> {un,}masking and wakeup enable. So you can just use IRQCHIP_SKIP_SET_WAKE.
> Correct me if my understanding is wrong.

In this driver, the Core0 is configured to be the default core to be woke up, not both. You can
configure it to Core1 by changing the cpu2wakeup value. I don't see any reason to
use IRQCHIP_SKIP_SET_WAKE flag.

Thanks,
Shenwei
 


> Regards,
> Sudeep

From haojian.zhuang at linaro.org  Tue Aug 25 06:43:14 2015
From: haojian.zhuang at linaro.org (Haojian Zhuang)
Date: Tue, 25 Aug 2015 21:43:14 +0800
Subject: [PATCH v1 3/3] arm64: dts: add Hi6220 mailbox node
In-Reply-To: <20150825104256.GB13471@leverpostej>
References: <1439977055-1747-1-git-send-email-leo.yan@linaro.org>
 <1439977055-1747-4-git-send-email-leo.yan@linaro.org>
 <20150821184059.GB2000@svinekod> <20150824091845.GA28290@leoy-linaro>
 <20150824095144.GA7139@leverpostej> <1440411596.3517.12.camel@linaro.org>
 <20150824114903.GT10728@bivouac.eciton.net>
 <1440490427.10987.29.camel@linaro.org>
 <20150825094630.GU10728@bivouac.eciton.net>
 <1440497710.10987.42.camel@linaro.org> <20150825104256.GB13471@leverpostej>
Message-ID: <1440510194.10987.52.camel@linaro.org>

On Tue, 2015-08-25 at 11:42 +0100, Mark Rutland wrote:
> > > Are you then going to hack GRUB, release a special HiKey version of
> > > GRUB, not support any other versions, and still can your firmware
> > > UEFI?
> > 
> > I don't need to hack GRUB at all.
> 
> Then it is working for you by pure chance alone.
> 
> Please listen to the advice you are being given here; we're trying to
> ensure that your platform functions (and continues to function) as best
> it can.

Since we discussed a lot on this, let's make a conclusion on it.

1. UEFI could append the reserved buffer in it's memory mapping.
2. These reserved buffer must be declared in DT, since we also need to
   support non-UEFI (uboot) at the same time.
3. Mailbox node should reference reserved buffer by phandle in DT. Then
   map the buffer as non-cacheable in driver.
4. These reserved buffer must use "no-map" property since it should be
   non-cacheable in driver.
5. A patch is necessary in kernel. If efi stub feature is enabled,
   arm kernel should not parse memory node or reserved memory buffer in
   DT any more. Arm kernel should either fetch memory information from 
   efi or DT. Currently arm kernel fetch both efi memory information and
   reserved buffer from DTB at the same time.

Do you agree on these points?

Regards
Haojian



From Shenwei.Wang at freescale.com  Tue Aug 25 06:47:00 2015
From: Shenwei.Wang at freescale.com (Shenwei Wang)
Date: Tue, 25 Aug 2015 13:47:00 +0000
Subject: [PATCH v3 1/1] misc: sram: add dev_pm_ops to support module power
 gate
In-Reply-To: <55DC677E.1030004@arm.com>
References: <1438272681-29338-1-git-send-email-shenwei.wang@freescale.com>
 <55DC677E.1030004@arm.com>
Message-ID: <CY1PR0301MB0843D5CB5FFC56991B90EB4283610@CY1PR0301MB0843.namprd03.prod.outlook.com>



> -----Original Message-----
> From: Sudeep Holla [mailto:sudeep.holla at arm.com]
> Sent: 2015?8?25? 8:03
> To: Wang Shenwei-B38339
> Cc: gregkh at linuxfoundation.org; arnd at arndb.de; Sudeep Holla; Huang
> Yongcai-B20788; linux-arm-kernel at lists.infradead.org
> Subject: Re: [PATCH v3 1/1] misc: sram: add dev_pm_ops to support module
> power gate
> 
> 
> 
> On 30/07/15 17:11, Shenwei Wang wrote:
> > When system goes into low power states like SUSPEND_MEM and
> > HIBERNATION, the hardware IP block may be powered off to reduce the
> > power consumption. This power down will lost all the data inside the
> > ram. This patch added the dev_pm_ops and implemented two callbacks:
> > suspend_noirq and resume_noirq, which will save the data in the
> > on-chip-ram right before power down and restore it after system
> > resumes.
> >
> 
> Who uses this SRAM ? Can't they be released before suspending ?
> This might not be feasible and time consuming as the size of SRAM increases.

On Freescale i.MX7D, we are using this kind of SRAM. As I implemented this as an 
optional feature, a user can balance between the suspend/resume time and the power
consumption.

> Also I just check the entire tree for the users of gen_pool, I found it's used for
> video/audio and crypto which needs to on-demand basis.
> Apart from that it's mainly used for low power modes in which case, SRAM needs
> to be powered on. So can you provide more details on your use-case.

On latest Freescale i.MX7D, it has two SRAMs in side. One is for low power mode which will be powered
on in suspend state. The other one is for other peripherals which can be powered off on demand.

Thanks,
Shenwei 

> > A new property string named "can-power-gate" is added to the
> > devicetree bindings too.
> >
> > Signed-off-by: Shenwei Wang <shenwei.wang at freescale.com>
> > Signed-off-by: Anson Huang <b20788 at freescale.com>
> > ---
> > Change log:
> >
> > PATCH v3
> > 	Removed the unnecessary clk_enable/clk_disable.
> >
> > PATCH v2
> > 	Use vmalloc to allocate the SRAM backup memory.
> > 	Code clean up.
> >
> >   Documentation/devicetree/bindings/misc/sram.txt |  2 ++
> >   drivers/misc/sram.c                             | 42
> +++++++++++++++++++++++++
> >   2 files changed, 44 insertions(+)
> >
> > diff --git a/Documentation/devicetree/bindings/misc/sram.txt
> > b/Documentation/devicetree/bindings/misc/sram.txt
> > index 36cbe5a..1170086 100644
> > --- a/Documentation/devicetree/bindings/misc/sram.txt
> > +++ b/Documentation/devicetree/bindings/misc/sram.txt
> > @@ -33,6 +33,8 @@ Optional properties in the area nodes:
> >
> >   - compatible : standard definition, should contain a vendor specific string
> >                  in the form <vendor>,[<device>-]<usage>
> > +- can-power-gate: a property to tell the driver that the sram can support
> > +		power gate
> >
> 
> Please cc device-tree list for such generic bindings.
> 
> Regards,
> Sudeep

From sudeep.holla at arm.com  Tue Aug 25 06:54:21 2015
From: sudeep.holla at arm.com (Sudeep Holla)
Date: Tue, 25 Aug 2015 14:54:21 +0100
Subject: [PATCH v9 1/1] irqchip: imx-gpcv2: IMX GPCv2 driver for wakeup
 sources
In-Reply-To: <CY1PR0301MB08439B6C5F841AFFD152DFD883610@CY1PR0301MB0843.namprd03.prod.outlook.com>
References: <1440443055-7291-1-git-send-email-shenwei.wang@freescale.com>
 <55DC3452.3070205@arm.com>
 <CY1PR0301MB08439B6C5F841AFFD152DFD883610@CY1PR0301MB0843.namprd03.prod.outlook.com>
Message-ID: <55DC738D.8000302@arm.com>



On 25/08/15 14:38, Shenwei Wang wrote:
>
>
>> -----Original Message-----
>> From: Sudeep Holla [mailto:sudeep.holla at arm.com]
>> Sent: 2015?8?25? 4:25
>> To: Wang Shenwei-B38339
>> Cc: shawn.guo at linaro.org; tglx at linutronix.de; jason at lakedaemon.net; Sudeep
>> Holla; Huang Yongcai-B20788; linux-kernel at vger.kernel.org;
>> linux-arm-kernel at lists.infradead.org
>> Subject: Re: [PATCH v9 1/1] irqchip: imx-gpcv2: IMX GPCv2 driver for wakeup
>> sources
>>
>>
>>
>> On 24/08/15 20:04, Shenwei Wang wrote:
>>> IMX7D contains a new version of GPC IP block (GPCv2). It has two major
>>> functions: power management and wakeup source management.
>>> This patch adds a new irqchip driver to manage the interrupt wakeup
>>> sources on IMX7D.
>>
>> Interesting, you mention that this IP block has mainly power management and it
>> itself requires save/restore. Is it not in always on domain ?
>
> Yes, it is in always on domain.
>

Hmm, then why do you need to save and restore the mask ?

>>> When the system is in WFI (wait for interrupt) mode, this GPC block
>>> will be the first block on the platform to be activated and signaled.
>>> Under normal wait mode during cpu idle, the system can be woke up by
>>> +static void gpcv2_wakeup_source_restore(void) {
>>> +	struct gpcv2_irqchip_data *cd;
>>> +	void __iomem *reg;
>>> +	int i;
>>> +
>>> +	cd = imx_gpcv2_instance;
>>> +	if (!cd)
>>> +		return;
>>> +
>>> +	for (i = 0; i < IMR_NUM; i++) {
>>> +		reg = cd->gpc_base + cd->cpu2wakeup + i * 4;
>>> +		writel_relaxed(cd->saved_irq_mask[i], reg);
>>
>> Instead of saving all the non-wakeup sources, can't you use raw save/restore of
>> these registers and mask all the non-wakeup sources by setting
>> MASK_ON_SUSPEND ?
>
> I can't catch what you mean. Can you show me an example?
>

What I meant is instead of you tracking all the enabled irqs(both wakeup
and non-wakeup) in saved_irq_mask, just set MASK_ON_SUSPEND flag
where all the non-wakeup interrupts are masked on suspend and unmasked
on resume by the irq core. You can then just save and restore the wakeup
irq mask, but as I asked above do you have to do that as you are saying
it's in always on domain ?

>> Also your interrupt controller seems like has no special way to configure wakeups,
>> you are just leaving them enabled. i.e. I see cpu2wakeup used for both
>> {un,}masking and wakeup enable. So you can just use IRQCHIP_SKIP_SET_WAKE.
>> Correct me if my understanding is wrong.
>
> In this driver, the Core0 is configured to be the default core to be woke up, not both. You can
> configure it to Core1 by changing the cpu2wakeup value. I don't see any reason to
> use IRQCHIP_SKIP_SET_WAKE flag.
>

I don't see this driver doing anything extra apart from keeping the
wakeup irqs enabled. i.e. You use the same cpu*wake register to
mask/unmask the interrupt as well as set the wakeup source. Since
the wakeup interrupt will be enabled by the driver, you just need to
mark it as wake-up source and nothing extra in the controller right ?
If so, you need to set IRQCHIP_SKIP_SET_WAKE as you are just leaving
that irq enabled and not doing any extra configuration to enable it as
wakeup source. Please correct if that wrong, but from the code that's
what I could infer.

Regards,
Sudeep


From nschichan at freebox.fr  Tue Aug 25 06:55:04 2015
From: nschichan at freebox.fr (Nicolas Schichan)
Date: Tue, 25 Aug 2015 15:55:04 +0200
Subject: [PATCH 9/9] ARM: software-based priviledged-no-access support
In-Reply-To: <20150825123800.GQ7557@n2100.arm.linux.org.uk>
References: <20150821133043.GV7557@n2100.arm.linux.org.uk>
 <E1ZSmQG-0002za-E3@rmk-PC.arm.linux.org.uk>
 <CAMuHMdVMka2mt5pFpnXfLRY2M3Sj_71MgEpthOia2C99RaP_DA@mail.gmail.com>
 <20150825104422.GO7557@n2100.arm.linux.org.uk>
 <CAMuHMdWCLcDS=64m0J09KJJ4bDtgZ1Yvq8rw7u9FE0vZkKT2cw@mail.gmail.com>
 <20150825123800.GQ7557@n2100.arm.linux.org.uk>
Message-ID: <55DC73B8.3010002@freebox.fr>

On 08/25/2015 02:38 PM, Russell King - ARM Linux wrote:
> On Tue, Aug 25, 2015 at 01:21:04PM +0200, Geert Uytterhoeven wrote:
>> Hi Russell,
>>
>> On Tue, Aug 25, 2015 at 12:44 PM, Russell King - ARM Linux
>> <linux at arm.linux.org.uk> wrote:
>>> On Tue, Aug 25, 2015 at 12:32:51PM +0200, Geert Uytterhoeven wrote:
>>>> This patch, which is now in arm-soc/for-next, breaks shmobile_defconfig
>>>> on r8a7791/koelsch, which has a dual core CA15:
>>>>
>>>>     [ ok ] Configuring network interfaces...done.
>>>>     Unhandled fault: page domain fault (0x01b) at 0xbe8e6120
>>>>     pgd = edbb0000
>>>>     [be8e6120] *pgd=6da77831, *pte=bf4d075f, *ppte=bf4d0c7f
>>>>     Internal error: : 1b [#1] SMP ARM
>>>>     CPU: 1 PID: 1629 Comm: ntpdate Not tainted
>>>> 4.2.0-rc8-06444-g3c24fd89c9421db1 #31
>>>>     9
>>>>     Hardware name: Generic R8A7791 (Flattened Device Tree)
>>>>     task: ed883a80 ti: ed41c000 task.ti: ed41c000
>>>>     PC is at csum_partial_copy_from_user+0x28/0x3d8
>>>>     LR is at csum_and_copy_from_iter+0x334/0x4c0
>>>>     pc : [<c04ba510>]    lr : [<c01c82e8>]    psr: 000f0013
>>>>     sp : ed41db00  ip : 00000020  fp : ed41db6c
>>>>     r10: ed41ddc0  r9 : 00000027  r8 : ed41dc20
>>>>     r7 : 00000027  r6 : eda52653  r5 : ed41dec8  r4 : 00000000
>>>>     r3 : 00000000  r2 : 00000027  r1 : eda5262c  r0 : be8e6120
>>>>     Flags: nzcv  IRQs on  FIQs on  Mode SVC_32  ISA ARM  Segment none
>>>>     Control: 10c5307d  Table: 6dbb006a  DAC: 00000051
>>>>     Process ntpdate (pid: 1629, stack limit = 0xed41c210)
>>>
>>> Thanks.  I wonder what's different about your ntpdate that triggers
>>> this, and why all my iMX6 behave fine, which have desktop-like ubuntu
>>> installs on (of two different versions.)
>>
>> It's ntpdate 1:4.2.6.p5+dfsg-7 from desktop-like Debian jessie.
> 
> Hmm, I think I tried at one time to install Debian on an iMX6 platform
> and gave up with it after spending 50 minutes with the installer getting
> so far, and then killing the network - it was very repeatable, and always
> happened at the same point in the installation.  I gave up with Debian
> at that point, as I didn't have lots of 50 minutes to babysit the silly
> installer (which can't ask the questions up-front) nor did I want to
> waste my monthly internet allowance on multiple failed install attempts.
> 
> The reports I was getting from other iMX6 users was that Debian Jessie
> had lots of problems at that time.
> 
>> But I get similar dumps during boot up from rpc.idmapd (SyS_send),
>> rsyslogd (SyS_send), and from sshd (SyS_write) when trying to log in.
> 
> Hmm.
> 
> root       693  0.0  0.1   4944  3196 ?        Ss   01:22   0:00 /usr/sbin/sshd -D
> syslog     720  0.2  0.0  30404  2032 ?        Sl   01:23   1:19 rsyslogd -c5
> root       722  0.0  0.0   2392  1340 ?        Ss   01:23   0:00 rpc.idmapd
> 
> So, the question I need to find an answer to is... why hasn't this path
> been exercised on my platforms during my testing.  It's certainly
> compiled into the kernel...
> 
> Anyway, I've now (hopefully) fixed the bug, but I've nobbled
> csum_partial_copy_from_user to ensure that it will always oops the kernel
> if called:
> 
> 000000b4 <csum_partial_copy_from_user>:
>   b4:   ee133f10        mrc     15, 0, r3, cr3, cr0, {0}
>   b8:   e92d41fe        push    {r1, r2, r3, r4, r5, r6, r7, r8, lr}
>   bc:   e3a03055        mov     r3, #85 ; 0x55
>   c0:   ee033f10        mcr     15, 0, r3, cr3, cr0, {0}
>   c4:   e7033003        str     r3, [r3, -r3]
> 
> and... it doesn't trigger.  I can only assume that this is because the
> iMX6 ethernet interface uses TSO (which implies checksum offload), there's
> no need to use these csum functions - and that would explain why it never
> came up in my local testing.

[resent with the list and other original recipients this time]

I have the csum_partial_copy_from_user issue too, but with radvd (which sends
ipv6 packets). ipv4 networking is fine on the other hand. The kirkwood
platform I use does have checksum offload for ipv4 only and not ipv6 so the
csum functions will get called in the ipv6 case.


-- 
Nicolas Schichan
Freebox SAS


From hverkuil at xs4all.nl  Tue Aug 25 06:54:09 2015
From: hverkuil at xs4all.nl (Hans Verkuil)
Date: Tue, 25 Aug 2015 15:54:09 +0200
Subject: [PATCH v7 25/44] [media] replace all occurrences of
 MEDIA_ENT_T_DEVNODE_V4L
In-Reply-To: <20150825083236.37659d22@recife.lan>
References: <cover.1440359643.git.mchehab@osg.samsung.com>	<23e2f9440a259e1162e15dba7e6261dbc4c521c6.1440359643.git.mchehab@osg.samsung.com>	<55DC340C.8030503@xs4all.nl>
 <20150825083236.37659d22@recife.lan>
Message-ID: <55DC7381.9090600@xs4all.nl>

On 08/25/15 13:32, Mauro Carvalho Chehab wrote:
> Em Tue, 25 Aug 2015 11:23:24 +0200
> Hans Verkuil <hverkuil at xs4all.nl> escreveu:
> 
>> On 08/23/15 22:17, Mauro Carvalho Chehab wrote:
>>> Now that interfaces and entities are distinct, it makes no sense
>>> of keeping something named as MEDIA_ENT_T_DEVNODE.
>>>
>>> This change was done with this script:
>>>
>>> 	for i in $(git grep -l MEDIA_ENT_T|grep -v uapi/linux/media.h); do sed s,MEDIA_ENT_T_DEVNODE_V4L,MEDIA_ENT_T_V4L2_VIDEO, <$i >a && mv a $i; done
>>>
>>> Signed-off-by: Mauro Carvalho Chehab <mchehab at osg.samsung.com>
>>>
>>> diff --git a/Documentation/DocBook/media/v4l/media-ioc-enum-entities.xml b/Documentation/DocBook/media/v4l/media-ioc-enum-entities.xml
>>> index 5872f8bbf774..910243d4edb8 100644
>>> --- a/Documentation/DocBook/media/v4l/media-ioc-enum-entities.xml
>>> +++ b/Documentation/DocBook/media/v4l/media-ioc-enum-entities.xml
>>> @@ -183,7 +183,7 @@
>>>  	    <entry>Unknown device node</entry>
>>>  	  </row>
>>>  	  <row>
>>> -	    <entry><constant>MEDIA_ENT_T_DEVNODE_V4L</constant></entry>
>>> +	    <entry><constant>MEDIA_ENT_T_V4L2_VIDEO</constant></entry>
>>>  	    <entry>V4L video, radio or vbi device node</entry>
>>>  	  </row>
>>
>> OK, this makes no sense and that ties in with my confusion of the previous patch.
>>
>> These are not device nodes, in the new scheme these are DMA entities (I know,
>> naming TDB) that have an associated interface.
> 
> Yes. Well, DMA is a bad name. It won't cover USB devices, where the DMA
> engine is outside the V4L2 drivers, nor it would work for RDS radio data,
> with may not need any DMA at all on no-USB devices, as the data flows via
> the I2C bus.
> 
>> I think a much better approach would be to add entity type(s) for such DMA
>> engines in patch 24, then use that new name in existing drivers and split
>> up the existing DEVNODE_V4L media_entity into a media_entity and a
>> media_intf_devnode:
> 
> Sorry, but I didn't get. That's precisely what I did ;)
> 
>> The current media_entity defined in struct video_device has to be replaced
>> by media_intf_devnode, and the DMA entity has to be added as a new entity
>> to these drivers.
> 
> If I do this way, it would break bisectability. I need first to replace
> the names, but keep them as entities, and then add the interfaces.
> 
>>
>> This reflects these two action items from our meeting:
>>
>> Migration: add v4l-subdev media_interface: Laurent
>> Migration: add explicit DMA Engine entity: Laurent
>>
>> Unless Laurent says differently I think this is something you'll have to
>> do given Laurent's workload.
> 
> Yes. The above action items are covered on this series.
> 
> What patch 24 does is to define the new namespace, moving the legacy
> symbols kept due to backward compatibility on a separate part of the
> header.
> 
> Then, patches 25-38 replace the occurrences of the deprecated names
> by the new ones.
> 
> Nothing is touched at the interfaces yet, to avoid breaking bisectability.

I don't follow why that would break bisect.

> Then, the next patches add interfaces support at the V4L side.

So this is not yet included in this patch series? That would explain
my confusion. If it is, then I need to take another look on Friday.

Regards,

	Hans


From ulf.hansson at linaro.org  Tue Aug 25 06:58:45 2015
From: ulf.hansson at linaro.org (Ulf Hansson)
Date: Tue, 25 Aug 2015 15:58:45 +0200
Subject: [PATCH v2] mmc: sunxi: Don't start commands while the card is busy
In-Reply-To: <55DC5B09.2020705@redhat.com>
References: <1436541284-11800-1-git-send-email-hdegoede@redhat.com>
 <CAPDyKFoNe0bghfSXs48stHzZToTc7Hjd5gVPy-VbDF8bzdVVMQ@mail.gmail.com>
 <55BC8ADE.3070802@redhat.com>
 <CAPDyKFrYvL33DsaATg4fyAJg=G3SEuOP+xU=o_UwasmNZ+a07Q@mail.gmail.com>
 <55DC5B09.2020705@redhat.com>
Message-ID: <CAPDyKFpJGBA7GN=PJmWdpT+_OiPF_ET0i9wC7XYBCJA9EwLrgw@mail.gmail.com>

On 25 August 2015 at 14:09, Hans de Goede <hdegoede at redhat.com> wrote:
> Hi,
>
>
> On 25-08-15 14:05, Ulf Hansson wrote:
>>
>> On 1 August 2015 at 11:01, Hans de Goede <hdegoede at redhat.com> wrote:
>>>
>>> Hi,
>>>
>>> On 21-07-15 14:15, Ulf Hansson wrote:
>>>>
>>>>
>>>> On 10 July 2015 at 17:14, Hans de Goede <hdegoede at redhat.com> wrote:
>>>>>
>>>>>
>>>>> Some sdio wifi modules have not been working reliable with the
>>>>> sunxi-mmc
>>>>> host code. This turns out to be caused by it starting new commands
>>>>> while
>>>>> the card signals that it is still busy processing a previous command.
>>>>
>>>>
>>>>
>>>> Which are those commands?
>>>
>>>
>>>
>>> The code were things get stuck when not waiting for the busy signal uses
>>> the following sdio helper functions:
>>>
>>> sdio_readb/sdio_writeb
>>> sdio_f0_readb/sdio_f0_writeb
>>> sdio_readw/sdio_writew
>>> sdio_readl/sdio_writel
>>> sdio_readsb
>>> sdio_memcpy_fromio/sdio_memcpy_toio
>>>
>>> And directly issues the following command:
>>>
>>>          mmc_dat.flags = write ? MMC_DATA_WRITE : MMC_DATA_READ;
>>>          mmc_cmd.opcode = SD_IO_RW_EXTENDED;
>>>          mmc_cmd.arg = write ? 1<<31 : 0;        /* write flag  */
>>>          mmc_cmd.arg |= (fn & 0x7) << 28;        /* SDIO func num */
>>>          mmc_cmd.arg |= 1<<27;                   /* block mode */
>>>          /* for function 1 the addr will be incremented */
>>>          mmc_cmd.arg |= (fn == 1) ? 1<<26 : 0;
>>>          mmc_cmd.flags = MMC_RSP_SPI_R5 | MMC_RSP_R5 | MMC_CMD_ADTC;
>>>
>>> I do not know if the busy wait is necessary for all
>>> of these, but the hack in the android kernel code,
>>> which inserts calls to a wait_card_busy function directly
>>> into: drivers/net/wireless/brcm80211/brcmfmac/bcmsdh.c
>>>
>>> Does so for all of these.
>>>
>>>> Or more interesting, which response types do
>>>>
>>>> these commands expect?
>>>> I don't think this is a sunxi specific issue, I have seen similar
>>>> issues for other host controllers.
>>>
>>>
>>>
>>> Agreed, recent dw-mmc patches address the same issue, also involving
>>> broadcom sdio wifi chips.
>>>
>>>> I am thinking that perhaps this should be managed by the mmc core
>>>> instead of local hacks to sunxi. Potentially we could make the core to
>>>> invoke the already existing host_ops->card_busy() callback when
>>>> needed...
>>>
>>>
>>>
>>> I'm fine with solving this either way, implementing host_ops->card_busy()
>>> for sunxi is easy, and if the core os modified to call that function
>>> before issue sdio io ops (which seems to be the common thing here),
>>> then that indeed is better then having the sunxi code always do
>>> the busy check.
>>
>>
>> Okay, so let's make the core to call the ->card_busy() callback and
>> then it's up to each host driver to implement that callback.
>
>
> Ok, do you plan to do a patch for this, or do you expect to get
> one submitted to you ?

I prefer to get a patch submitted to me. My bandwidth has been limited
and still have a lot to catch up with...

Kind regards
Uffe


From sudeep.holla at arm.com  Tue Aug 25 06:59:43 2015
From: sudeep.holla at arm.com (Sudeep Holla)
Date: Tue, 25 Aug 2015 14:59:43 +0100
Subject: [PATCH v3 1/1] misc: sram: add dev_pm_ops to support module power
 gate
In-Reply-To: <CY1PR0301MB0843D5CB5FFC56991B90EB4283610@CY1PR0301MB0843.namprd03.prod.outlook.com>
References: <1438272681-29338-1-git-send-email-shenwei.wang@freescale.com>
 <55DC677E.1030004@arm.com>
 <CY1PR0301MB0843D5CB5FFC56991B90EB4283610@CY1PR0301MB0843.namprd03.prod.outlook.com>
Message-ID: <55DC74CF.7070300@arm.com>



On 25/08/15 14:47, Shenwei Wang wrote:
>
>
>> -----Original Message-----
>> From: Sudeep Holla [mailto:sudeep.holla at arm.com]
>> Sent: 2015?8?25? 8:03
>> To: Wang Shenwei-B38339
>> Cc: gregkh at linuxfoundation.org; arnd at arndb.de; Sudeep Holla; Huang
>> Yongcai-B20788; linux-arm-kernel at lists.infradead.org
>> Subject: Re: [PATCH v3 1/1] misc: sram: add dev_pm_ops to support module
>> power gate
>>
>>
>>
>> On 30/07/15 17:11, Shenwei Wang wrote:
>>> When system goes into low power states like SUSPEND_MEM and
>>> HIBERNATION, the hardware IP block may be powered off to reduce the
>>> power consumption. This power down will lost all the data inside the
>>> ram. This patch added the dev_pm_ops and implemented two callbacks:
>>> suspend_noirq and resume_noirq, which will save the data in the
>>> on-chip-ram right before power down and restore it after system
>>> resumes.
>>>
>>
>> Who uses this SRAM ? Can't they be released before suspending ?
>> This might not be feasible and time consuming as the size of SRAM increases.
>
> On Freescale i.MX7D, we are using this kind of SRAM. As I implemented this as an
> optional feature, a user can balance between the suspend/resume time and the power
> consumption.
>
>> Also I just check the entire tree for the users of gen_pool, I found it's used for
>> video/audio and crypto which needs to on-demand basis.
>> Apart from that it's mainly used for low power modes in which case, SRAM needs
>> to be powered on. So can you provide more details on your use-case.
>
> On latest Freescale i.MX7D, it has two SRAMs in side. One is for low
> power mode which will be powered on in suspend state. The other one
> is for other peripherals which can be powered off on demand.
>

What I meant is who will be using the SRAM when entering S2R that you
need to save the content. Either the user needs to take care of the
content or just release the pool when not in use. When the sram pool has
no user, clock can be gated.

Again can you give details of this use-case.

Regards,
Sudeep


From msalter at redhat.com  Tue Aug 25 07:01:19 2015
From: msalter at redhat.com (Mark Salter)
Date: Tue, 25 Aug 2015 10:01:19 -0400
Subject: [PATCH] ARM64: kernel: implement ACPI parking protocol
In-Reply-To: <20150824171345.GA4981@red-moon>
References: <1436959990-32054-1-git-send-email-lorenzo.pieralisi@arm.com>
 <1437063431.3583.2.camel@redhat.com> <20150716171221.GB18582@red-moon>
 <55A7F24D.2000100@redhat.com> <1437071026.21160.1.camel@redhat.com>
 <20150824171345.GA4981@red-moon>
Message-ID: <1440511279.5882.14.camel@redhat.com>

On Mon, 2015-08-24 at 18:13 +0100, Lorenzo Pieralisi wrote:
> Hi Mark,
> 
> On Thu, Jul 16, 2015 at 07:23:46PM +0100, Mark Salter wrote:
> > On Thu, 2015-07-16 at 12:05 -0600, Al Stone wrote:
> > 
> > > On 07/16/2015 11:12 AM, Lorenzo Pieralisi wrote:
> > 
> > > > On Thu, Jul 16, 2015 at 05:17:11PM +0100, Mark Salter wrote:
> > 
> > > > > On Wed, 2015-07-15 at 12:33 +0100, Lorenzo Pieralisi wrote:
> > > > > 
> > 
> > > > > > The SBBR and ACPI specifications allow ACPI based systems that 
> > > > > > do not
> > > > > > implement PSCI (eg systems with no EL3) to boot through the 
> > > > > > ACPI parking
> > > > > > protocol specification[1].
> > > > > > 
> > > > > > This patch implements the ACPI parking protocol CPU operations, 
> > > > > > and adds
> > > > > > code that eases parsing the parking protocol data structures to 
> > > > > > the
> > > > > > ARM64 SMP initializion carried out at the same time as cpus 
> > > > > > enumeration.
> > > > > > 
> > > > > > To wake-up the CPUs from the parked state, this patch 
> > > > > > implements a
> > > > > > wakeup IPI for ARM64 (ie arch_send_wakeup_ipi_mask()) that 
> > > > > > mirrors the
> > > > > > ARM one, so that a specific IPI is sent for wake-up purpose in 
> > > > > > order
> > > > > > to distinguish it from other IPI sources.
> > > > > > 
> > > > > > Given the current ACPI MADT parsing API, the patch implements a 
> > > > > > glue
> > > > > > layer that helps passing MADT GICC data structure from SMP 
> > > > > > initialization
> > > > > 
> > > > > Somewhat off topic, but this reminds once again, that it might be
> > > > > better to generalize the ACPI_MADT_TYPE_GENERIC_INTERRUPT so that 
> > > > > it
> > > > > could be done in one pass. Currently, the SMP code and the GIC 
> > > > > code
> > > > > need boot-time info from ACPI_MADT_TYPE_GENERIC_INTERRUPT tables. 
> > > > > This
> > > > > patch adds parking protocol, and this patch:
> > > > > 
> > > > >  https://lkml.org/lkml/2015/5/1/203
> > > > > 
> > > > > need to get the PMU irq from the same table. I've been thinking 
> > > > > of
> > > > > something like a single loop through the table in setup.c with
> > > > > callouts to registered users of the various bits of data.
> > > > 
> > > > It is not off topic at all, it is bang on topic. I hate the code
> > > > as it stands forcing parsing the MADT in multiple places at 
> > > > different
> > > > times, that's why I added hooks to set the parking protocol entries
> > > > from smp.c and I know that's ugly, I posted it like this on purpose
> > > > to get feedback.
> > > > 
> > 
> > > > > Those users could register a handler function with something like 
> > > > > an
> > > > > ACPI_MADT_GIC_DECLARE() macro which would add a handler to a
> > > > > special linker section.
> > > > > 
> > > > > I could work up a separate patch if others think it a worthwhile
> > > > > thing to do.
> > > > 
> > > > Something simpler ? Like stashing the GICC entries (I know we need
> > > > permanent table mappings for that to work unless we create data
> > > > structures out of the MADT entries with the fields we are 
> > > > interested in)
> > > > for possible CPUS ?
> > > 
> > > Right -- it seems like it would be pretty straightforward to traverse
> > > the MADT once, and capture all the GICC subtables in a list of 
> > > pointers,
> > > or even make a copy of the contents of all of them.  Each user of the
> > > content would still have to traverse the list, though, unless data is
> > > reduced to only those things that are needed and the rest tossed. 
> > >  Even
> > > if only keep the info needed, I've still got a list of entries, one 
> > > for
> > > each CPU, I think, that I would still have to traverse.
> > > 
> > > If I have to register a handler to gather a specific bit of data 
> > > needed,
> > > I'm not understanding how that's any less complicated than what I 
> > > need
> > > to do today -- call acpi_parse_table_madt() with my GICC handler. 
> > >  Wouldn't
> > > both GICC subtable handlers be just about the same code?
> > > 
> > > I'm probably missing something obvious, but I'm not understanding 
> > > what problem
> > > is being solved....
> > > 
> > 
> > The difference is that GIC code and SMP code each loop
> > through the tables getting the info they need. If they
> > registered a handler, there is only one loop through
> > the tables regardless of how many handlers get registered.
> > Having each loop through as currently done isn't really
> > a performance issue (its boot-time only right now), but
> > there is duplicated code wrt validating the table entry
> > and calling the acpi API to do it. All of that could be
> > done in one place instead of duplicating it in different
> > places.
> 
> Did you have time to put the patch together ? I would like
> to post a v2 for this set soon.
> 
> Thank you !
> Lorenzo

No. The original idea I had wasn't going to work out because the
parsing had to happen at different times during the boot. I'm not
sure if there's a better way than what we're doing now.




From leo.yan at linaro.org  Tue Aug 25 07:04:50 2015
From: leo.yan at linaro.org (Leo Yan)
Date: Tue, 25 Aug 2015 22:04:50 +0800
Subject: [PATCH v1 3/3] arm64: dts: add Hi6220 mailbox node
In-Reply-To: <55DC532C.3020005@arm.com>
References: <1439977055-1747-1-git-send-email-leo.yan@linaro.org>
 <1439977055-1747-4-git-send-email-leo.yan@linaro.org>
 <55DC532C.3020005@arm.com>
Message-ID: <20150825140450.GB28262@leoy-linaro>

Hi Sudeep,

On Tue, Aug 25, 2015 at 12:36:12PM +0100, Sudeep Holla wrote:
> 
> 
> On 19/08/15 10:37, Leo Yan wrote:
> >On Hi6220, below memory regions in DDR have specific purpose:
> >
> >   0x05e0,0000 - 0x05ef,ffff: For MCU firmware using at runtime;
> >   0x0740,f000 - 0x0740,ffff: For MCU firmware's section;
> >   0x06df,f000 - 0x06df,ffff: For mailbox message data.
> >
> 
> Unless I am reading the DTS file completely wrong, I don't think the
> above memory regions are in DDR as per the memory node.

i'm not sure if understand correctly for your question; Hikey board
has DDR 1GB at 0x0, but there have some memory regions are used for MCU.

So this patch is to reserve these memory regions so that make sure
kernel will not map and allocate them.

Will remove these memory regions from memory node in next version.

> >This patch reserves these memory regions and add device node for
> >mailbox in dts.
> >
> >Signed-off-by: Leo Yan <leo.yan at linaro.org>
> >---
> >  arch/arm64/boot/dts/hisilicon/hi6220-hikey.dts | 20 +++++++++++++++++---
> >  arch/arm64/boot/dts/hisilicon/hi6220.dtsi      |  8 ++++++++
> >  2 files changed, 25 insertions(+), 3 deletions(-)
> >
> >diff --git a/arch/arm64/boot/dts/hisilicon/hi6220-hikey.dts b/arch/arm64/boot/dts/hisilicon/hi6220-hikey.dts
> >index e36a539..d5470d3 100644
> >--- a/arch/arm64/boot/dts/hisilicon/hi6220-hikey.dts
> >+++ b/arch/arm64/boot/dts/hisilicon/hi6220-hikey.dts
> >@@ -7,9 +7,6 @@
> >
> >  /dts-v1/;
> >
> >-/*Reserved 1MB memory for MCU*/
> >-/memreserve/ 0x05e00000 0x00100000;
> >-
> >  #include "hi6220.dtsi"
> >
> >  / {
> >@@ -28,4 +25,21 @@
> >  		device_type = "memory";
> >  		reg = <0x0 0x0 0x0 0x40000000>;
> >  	};
> 
> I have no access to the spec, but I read this as 1GB RAM @0x0
> Unless this entry is completely wrong, what your commit log claims is
> incorrect. If this entry is wrong I wonder how is it booting with this
> DT then.

Do you mean should remove all reserved memory regions from memory
node? Will submit next version's patch for this.

Kernel can boot successfully on Hikey with this patch [1].

[1] https://github.com/96boards/linux

> >+
> >+	reserved-memory {
> >+		#address-cells = <2>;
> >+		#size-cells = <2>;
> >+		ranges;
> >+
> >+		mcu-buf at 05e00000 {
> >+			no-map;
> >+			reg = <0x0 0x05e00000 0x0 0x00100000>,	/* MCU firmware buffer */
> >+			      <0x0 0x0740f000 0x0 0x00001000>;	/* MCU firmware section */
> 
> So I don't see how can this be part of DDR ? Or at-least part of DDR
> that's mapped by kernel ?

Here use reserved-memory node to remove these regions from memblock
during kernel's boot up; kernel also will not map for them with
property "no-map".

I think this is the same question which have been brought up by Mark
in his early mail and suggested to use UEFI to do this.

Thanks,
Leo Yan


From will.deacon at arm.com  Tue Aug 25 07:05:52 2015
From: will.deacon at arm.com (Will Deacon)
Date: Tue, 25 Aug 2015 15:05:52 +0100
Subject: [PATCH 9/9] ARM: software-based priviledged-no-access support
In-Reply-To: <E1ZSmQG-0002za-E3@rmk-PC.arm.linux.org.uk>
References: <20150821133043.GV7557@n2100.arm.linux.org.uk>
 <E1ZSmQG-0002za-E3@rmk-PC.arm.linux.org.uk>
Message-ID: <20150825140552.GH21300@arm.com>

On Fri, Aug 21, 2015 at 02:31:56PM +0100, Russell King wrote:
> Provide a software-based implementation of the priviledged no access
> support found in ARMv8.1.
> 
> Userspace pages are mapped using a different domain number from the
> kernel and IO mappings.  If we switch the user domain to "no access"
> when we enter the kernel, we can prevent the kernel from touching
> userspace.
> 
> However, the kernel needs to be able to access userspace via the
> various user accessor functions.  With the wrapping in the previous
> patch, we can temporarily enable access when the kernel needs user
> access, and re-disable it afterwards.
> 
> This allows us to trap non-intended accesses to userspace, eg, caused
> by an inadvertent dereference of the LIST_POISON* values, which, with
> appropriate user mappings setup, can be made to succeed.  This in turn
> can allow use-after-free bugs to be further exploited than would
> otherwise be possible.
> 
> Signed-off-by: Russell King <rmk+kernel at arm.linux.org.uk>
> ---
>  arch/arm/Kconfig               | 15 +++++++++++++++
>  arch/arm/include/asm/domain.h  | 15 ++++++++++++---
>  arch/arm/include/asm/uaccess.h | 14 ++++++++++++++
>  arch/arm/kernel/entry-header.S | 25 +++++++++++++++++++++++++
>  arch/arm/kernel/process.c      | 24 ++++++++++++++++++------
>  5 files changed, 84 insertions(+), 9 deletions(-)

[...]

> diff --git a/arch/arm/kernel/entry-header.S b/arch/arm/kernel/entry-header.S
> index 3aa6c3742182..bec7ee0764e1 100644
> --- a/arch/arm/kernel/entry-header.S
> +++ b/arch/arm/kernel/entry-header.S
> @@ -54,15 +54,40 @@
>  	.endm
>  
>  	.macro	uaccess_disable, tmp
> +#ifdef CONFIG_CPU_SW_DOMAIN_PAN
> +	/*
> +	 * Whenever we re-enter userspace, the domains should always be
> +	 * set appropriately.
> +	 */
> +	mov	\tmp, #DACR_UACCESS_DISABLE
> +	mcr	p15, 0, \tmp, c3, c0, 0		@ Set domain register
> +#endif

Missing ISB?

>  	.endm
>  
>  	.macro	uaccess_enable, tmp
> +#ifdef CONFIG_CPU_SW_DOMAIN_PAN
> +	/*
> +	 * Whenever we re-enter userspace, the domains should always be
> +	 * set appropriately.
> +	 */
> +	mov	\tmp, #DACR_UACCESS_ENABLE
> +	mcr	p15, 0, \tmp, c3, c0, 0
> +#endif
>  	.endm
>  
>  	.macro	uaccess_save_and_disable, tmp
> +#ifdef CONFIG_CPU_SW_DOMAIN_PAN
> +	mrc	p15, 0, \tmp, c3, c0, 0
> +	str	\tmp, [sp, #S_FRAME_SIZE]
> +#endif
> +	uaccess_disable \tmp
>  	.endm

Same here. For the enable/restore cases, the exception return will
synchronise the DACR for us, but I think we need the ISB to be sure that
the change has taken effect on the exception entry paths.

Will


From wangkefeng.wang at huawei.com  Tue Aug 25 07:06:49 2015
From: wangkefeng.wang at huawei.com (Kefeng Wang)
Date: Tue, 25 Aug 2015 22:06:49 +0800
Subject: ask for help about BUG: soft lockup - CPU#13 stuck for 22s!
 [trinity-c13:6691]
Message-ID: <55DC7679.5090707@huawei.com>

Hi all,

We got issues about rcu/ soft lockup in trinity test on our arm64 board,
and have no idea to fix this, any advice will be appreciated.

Our board test environment:
1) Kernel version: 3.19.0/3.19.8/4.1.0/4.1.6
2) Hardware: 32cpu, 128G memory
3) CONFIG: based on defconfig, use CONFIG_PREEMPT_NONE=y
4) TEST:  'trinity --dangerous' use root (trinity version 1.5)


And we met rcu/soft lockup once in qemu environment,
1) Qemu:  2.4.0   cpu 8, mem 30G
2) Kernel version: 4.1
3) CONFIG: same as board
3) TEST: same as board

log[1]: logging pieces in board
------------------------------------------------------------------

[ 3430.085690] INFO: rcu_sched self-detected stall on CPU { 13}  (t=21006 jiffies g=10664 c=10663 q=2837)
[ 3430.093697] INFO: rcu_sched detected stalls on CPUs/tasks: { 13} (detected by 16, t=21007 jiffies, g=10664, c=10663, q=2837)
[ 3430.093698] Task dump for CPU 13:
[ 3430.093701] trinity-c13     R  running task        0  6691   6001 0x00000003
[ 3430.093702] Call trace:
[ 3430.093709] [<ffffffc000087438>] __switch_to+0x74/0x8c
[ 3430.104867] Task dump for CPU 13:
[ 3430.104868] trinity-c13     R  running task        0  6691   6001 0x00000003
[ 3430.104872] Call trace:
[ 3430.106019] [<ffffffc00008a1d0>] dump_backtrace+0x0/0x124
[ 3430.106022] [<ffffffc00008a304>] show_stack+0x10/0x1c
[ 3430.106026] [<ffffffc0000d4c4c>] sched_show_task+0x98/0xf8
[ 3430.106030] [<ffffffc0000d7d74>] dump_cpu_task+0x3c/0x4c
[ 3430.106033] [<ffffffc0000f61ac>] rcu_dump_cpu_stacks+0xa4/0xf8
[ 3430.106035] [<ffffffc0000f91cc>] rcu_check_callbacks+0x3d4/0x6a4
[ 3430.106039] [<ffffffc0000fc788>] update_process_times+0x38/0x6c
[ 3430.106042] [<ffffffc00010af34>] tick_sched_handle.isra.16+0x1c/0x68
[ 3430.106044] [<ffffffc00010afc0>] tick_sched_timer+0x40/0x88
[ 3430.106047] [<ffffffc0000fce64>] __run_hrtimer.isra.34+0x4c/0x108
[ 3430.106050] [<ffffffc0000fd53c>] hrtimer_interrupt+0x100/0x2ac
[ 3430.106054] [<ffffffc000594074>] arch_timer_handler_phys+0x28/0x38
[ 3430.106058] [<ffffffc0000f0668>] handle_percpu_devid_irq+0x74/0x9c
[ 3430.106060] [<ffffffc0000ec638>] generic_handle_irq+0x30/0x4c
[ 3430.106062] [<ffffffc0000ec954>] __handle_domain_irq+0x5c/0xac
[ 3430.106065] [<ffffffc0000824f4>] gic_handle_irq+0x88/0xf8
[ 3430.106067] Exception stack(0xffffffdf84c97940 to 0xffffffdf84c97a60)
[ 3430.106070] 7940: 84c97cf0 ffffffdf b46e1d40 ffffffdf 84c97a90 ffffffdf 00162930 ffffffc0
[ 3430.106073] 7960: 80000145 00000000 96000047 00000000 b0aa0228 ffffffdf 7db41000 0000007f
[ 3430.106075] 7980: b0aa0228 ffffffdf 79e422d8 ffffffdf 79e422e8 ffffffdf 7dc0f000 0000007f
[ 3430.106077] 79a0: 00000000 00000000 00000000 00000000 00000000 00000000 00000000 00000000
[ 3430.106080] 79c0: 7f7f7f7f 7f7f7f7f 01010101 01010101 00000018 00000000 66666566 66666466
[ 3430.106083] 79e0: 66653766 74202c66 b7ef7529 00091372 000fedf0 ffffffc0 7e5a1ce0 0000007f
[ 3430.106085] 7a00: 00000000 00000000 84c97cf0 ffffffdf b46e1d40 ffffffdf 00000029 00000000
[ 3430.106087] 7a20: 79e42040 ffffffdf 7db41000 0000007f 96000047 00000000 dfff7eff ffffefff
[ 3430.106090] 7a40: 00000002 00000000 b78872c0 ffffffdf b46e1da0 ffffffdf 84c97a90 ffffffdf
[ 3430.106092] [<ffffffc000085da4>] el1_irq+0x64/0xc0
[ 3430.106095] [<ffffffc000096e50>] do_page_fault+0xa4/0x350
[ 3430.106097] [<ffffffc000082294>] do_mem_abort+0x38/0x9c
[ 3430.106098] Exception stack(0xffffffdf84c97c50 to 0xffffffdf84c97d70)
[ 3430.106101] 7c40:                                     48778d1f ffffffdf 00000009 00000000
[ 3430.106103] 7c60: 84c97e10 ffffffdf 0030a74c ffffffc0 00000009 00000000 84c97e10 ffffffdf
[ 3430.106106] 7c80: 0030a74c ffffffc0 60000145 00000000 00000025 00000000 dfff7eff ffffefff
[ 3430.106108] 7ca0: 78a260d8 ffffffdf b78872c0 ffffffdf 009ff100 ffffffc0 84c97e10 ffffffdf
[ 3430.106111] 7cc0: 000ff0dc ffffffc0 84c97cf0 ffffffdf 00085c20 ffffffc0 60000145 00000000
[ 3430.106113] 7ce0: 60000145 00000000 009ffd00 ffffffc0 7db41000 0000007f 84c97e90 ffffffdf
[ 3430.106116] 7d00: fffffffc ffffffff 00000009 00000000 7db41004 0000007f 00000009 00000000
[ 3430.106118] 7d20: 00000073 00000000 00000000 00000000 00000000 00000000 00000000 00000000
[ 3430.106121] 7d40: 7f7f7f7f 7f7f7f7f 01010101 01010101 00000018 00000000 66666566 66666466
[ 3430.106123] 7d60: 66653766 74202c66 b7ef7529 00091372
[ 3430.106125] [<ffffffc000085c24>] el1_da+0x14/0x70
[ 3456.373558] NMI watchdog: BUG: soft lockup - CPU#13 stuck for 22s! [trinity-c13:6691]
[ 3456.380109] Modules linked in: ipmi_si ipmi_devintf ipmi_msghandler

[ 3456.380116] CPU: 13 PID: 6691 Comm: trinity-c13 Tainted: G             L  3.19.8+ #48

[ 3456.380120] task: ffffffdf79e42040 ti: ffffffdf84c94000 task.ti: ffffffdf84c94000
[ 3456.380122] PC is at handle_mm_fault+0x35c/0xdb8
[ 3456.380124] LR is at handle_mm_fault+0x350/0xdb8
[ 3456.380126] pc : [<ffffffc00015f7b8>] lr : [<ffffffc00015f7ac>] pstate: 60000145
[ 3456.380127] sp : ffffffdf84c97a00
[ 3456.380129] x29: ffffffdf84c97a00 x28: ffffffc00098c000
[ 3456.380132] x27: ffffffdfb0aa0228 x26: 00000000000001ed
[ 3456.380134] x25: ffffffbe3ed19ab0 x24: 0000007f7db41000
[ 3456.380137] x23: 0d34000007f7db41 x22: ffffffdf85bd9f68
[ 3456.380140] x21: ffffffdfb46e1d40 x20: ffffffdfb446a000
[ 3456.380142] x19: ffffffbe3ed19a80 x18: 0000000000000000
[ 3456.380145] x17: 0000007f7e5a1ce0 x16: ffffffc0000fedf0
[ 3456.380147] x15: 00091372b7ef7529 x14: 74202c6666653766
[ 3456.380150] x13: 6666646666666566 x12: 0000000000000018
[ 3456.380152] x11: 0101010101010101 x10: 7f7f7f7f7f7f7f7f
[ 3456.380155] x9 : 0000000000000000 x8 : 0000000007f7db41
[ 3456.380157] x7 : 0000000000000141 x6 : 02e0002fa95c6751
[ 3456.380160] x5 : 0000000000000a08 x4 : 02e0002fa95c6751
[ 3456.380162] x3 : 02e0002fa95c6751 x2 : ffffffdfb446aa08
[ 3456.380165] x1 : 0000007f7db41000 x0 : 0000000000010d34

[ 3484.373416] NMI watchdog: BUG: soft lockup - CPU#13 stuck for 23s! [trinity-c13:6691]
[ 3484.379975] CPU: 13 PID: 6691 Comm: trinity-c13 Tainted: G             L  3.19.8+ #48
[ 3484.379979] task: ffffffdf79e42040 ti: ffffffdf84c94000 task.ti: ffffffdf84c94000
[ 3484.379981] PC is at handle_mm_fault+0x35c/0xdb8
[ 3484.379983] LR is at handle_mm_fault+0x350/0xdb8
[ 3484.379985] pc : [<ffffffc00015f7b8>] lr : [<ffffffc00015f7ac>] pstate: 60000145
[ 3484.379986] sp : ffffffdf84c97a00
[ 3484.379988] x29: ffffffdf84c97a00 x28: ffffffc00098c000
[ 3484.379990] x27: ffffffdfb0aa0228 x26: 00000000000001ed
[ 3484.379993] x25: ffffffbe3ed19ab0 x24: 0000007f7db41000
[ 3484.379996] x23: 0d34000007f7db41 x22: ffffffdf85bd9f68
[ 3484.379998] x21: ffffffdfb46e1d40 x20: ffffffdfb446a000
[ 3484.380001] x19: ffffffbe3ed19a80 x18: 0000000000000000
[ 3484.380003] x17: 0000007f7e5a1ce0 x16: ffffffc0000fedf0
[ 3484.380006] x15: 00091372b7ef7529 x14: 74202c6666653766
[ 3484.380008] x13: 6666646666666566 x12: 0000000000000018
[ 3484.380011] x11: 0101010101010101 x10: 7f7f7f7f7f7f7f7f
[ 3484.380013] x9 : 0000000000000000 x8 : 0000000007f7db41
[ 3484.380016] x7 : 0000000000000141 x6 : 02e0002fa95c6751
[ 3484.380018] x5 : 0000000000000a08 x4 : 02e0002fa95c6751
[ 3484.380021] x3 : 02e0002fa95c6751 x2 : ffffffdfb446aa08
[ 3484.380024] x1 : 0000007f7db41000 x0 : 0000000000010d34



log[2]: logging pieces in QEMU
------------------------------------------------------------------
[ 9720.804545] INFO: rcu_sched detected stalls on CPUs/tasks:
[ 9720.807407] 	0: (166 ticks this GP) idle=cab/140000000000000/0 softirq=114221/114221 fqs=38
[ 9720.808447] 	(detected by 3, t=2102 jiffies, g=84925, c=84924, q=114)
[ 9720.809416] Task dump for CPU 0:
[ 9720.809768] ksoftirqd/0     R  running task        0     3      2 0x00000002
[ 9720.812007] Call trace:
[ 9720.813325] [<ffffffc000086c5c>] __switch_to+0x74/0x8c
[ 9724.041575] NMI watchdog: BUG: soft lockup - CPU#0 stuck for 23s! [ksoftirqd/0:3]
[ 9724.044976] Modules linked in:

[ 9724.047586] CPU: 0 PID: 3 Comm: ksoftirqd/0 Not tainted 4.1.0 #3
[ 9724.050050] Hardware name: linux,dummy-virt (DT)
[ 9724.050886] NMI watchdog: BUG: soft lockup - CPU#1 stuck for 23s! [trinity-main:1331]
[ 9724.050991] Modules linked in:

[ 9724.051589] CPU: 1 PID: 1331 Comm: trinity-main Not tainted 4.1.0 #3
[ 9724.051610] Hardware name: linux,dummy-virt (DT)
[ 9724.051729] task: ffffffc75db44200 ti: ffffffc755a54000 task.ti: ffffffc755a54000
[ 9724.051888] PC is at run_hrtimer_softirq+0x1c/0x28
[ 9724.051951] LR is at run_hrtimer_softirq+0x18/0x28
[ 9724.052004] pc : [<ffffffc0000fec5c>] lr : [<ffffffc0000fec58>] pstate: 20000145
[ 9724.052033] sp : ffffffc755a57b80
[ 9724.052152] x29: ffffffc755a57b80 x28: 0000000000000000
[ 9724.052211] x27: ffffffc00084a140 x26: ffffffc00084a110
[ 9724.052258] x25: 0000000000000008 x24: 0000000000000100
[ 9724.052304] x23: 0000000000000030 x22: ffffffc755a57ba0
[ 9724.052352] x21: ffffffc000837ab8 x20: ffffffc00084a000
[ 9724.052407] x19: 0000000000000140 x18: 0000007fdf417090
[ 9724.052453] x17: 0000007f7e3ae2c0 x16: ffffffc0000b6104
[ 9724.052497] x15: 0000000000005d67 x14: 0000000000000000
[ 9724.052540] x13: 00000000696e695b x12: ffffffc0005bd43c
[ 9724.052583] x11: 0000000000000005 x10: 0000000000000533
[ 9724.052621] x9 : 0000000000000004 x8 : ffffffc0005bd460
[ 9724.052660] x7 : ffffffc755a54000 x6 : 00119557c0000000
[ 9724.052700] x5 : 0000000010000000 x4 : 0000000000000020
[ 9724.052739] x3 : ffffffc0004b2634 x2 : 00000000000003e8
[ 9724.052779] x1 : 0000000000000001 x0 : 0000000000000000

[ 9724.410042] task: ffffffc75e871600 ti: ffffffc75e994000 task.ti: ffffffc75e994000
[ 9724.483895] PC is at _raw_read_lock+0x8/0x20
[ 9724.485252] LR is at raw_local_deliver+0x48/0x1b0
[ 9724.485939] pc : [<ffffffc0005aa7f4>] lr : [<ffffffc0005437ec>] pstate: a0000145
[ 9724.486792] sp : ffffffc75e997a40
[ 9724.487214] x29: ffffffc75e997a40 x28: ffffffc74e174600
[ 9724.488052] x27: 0000000000000000 x26: 0000000000000000
[ 9724.488854] x25: 000000000000a888 x24: ffffffc7562d20a0
[ 9724.489679] x23: ffffffc0008db000 x22: ffffffc0008a1000
[ 9724.490462] x21: ffffffc0008db578 x20: ffffffc74e174600
[ 9724.491294] x19: ffffffc6af86f990 x18: 00000000000000b9
[ 9724.492142] x17: 0000007fb0630120 x16: ffffffc000196244
[ 9724.555949] x15: 001dcd6500000000 x14: 0000000000000000
[ 9724.556187] x13: 00000000a15d7a92 x12: 0000000000000020
[ 9724.556410] x11: 0101010101010101 x10: 7f7f7f7f7f7f7f7f
[ 9724.556629] x9 : fefefefefefefeff x8 : 0000000000000000
[ 9724.556816] x7 : 0000000000000004 x6 : 0000000000000000
[ 9724.557006] x5 : 0000000000000005 x4 : ffffffc756130000
[ 9724.557198] x3 : ffffffc0008db548 x2 : ffffffc0ba9bc7b8
[ 9724.557393] x1 : 0000000000000050 x0 : ffffffc0008db548

Thanks,
Kefeng



From sudeep.holla at arm.com  Tue Aug 25 07:13:26 2015
From: sudeep.holla at arm.com (Sudeep Holla)
Date: Tue, 25 Aug 2015 15:13:26 +0100
Subject: [PATCH v1 3/3] arm64: dts: add Hi6220 mailbox node
In-Reply-To: <20150825140450.GB28262@leoy-linaro>
References: <1439977055-1747-1-git-send-email-leo.yan@linaro.org>
 <1439977055-1747-4-git-send-email-leo.yan@linaro.org>
 <55DC532C.3020005@arm.com> <20150825140450.GB28262@leoy-linaro>
Message-ID: <55DC7806.2010003@arm.com>



On 25/08/15 15:04, Leo Yan wrote:
> Hi Sudeep,
>
> On Tue, Aug 25, 2015 at 12:36:12PM +0100, Sudeep Holla wrote:
>>
>>
>> On 19/08/15 10:37, Leo Yan wrote:
>>> On Hi6220, below memory regions in DDR have specific purpose:
>>>
>>>    0x05e0,0000 - 0x05ef,ffff: For MCU firmware using at runtime;
>>>    0x0740,f000 - 0x0740,ffff: For MCU firmware's section;
>>>    0x06df,f000 - 0x06df,ffff: For mailbox message data.
>>>
>>
>> Unless I am reading the DTS file completely wrong, I don't think the
>> above memory regions are in DDR as per the memory node.
>
> i'm not sure if understand correctly for your question; Hikey board
> has DDR 1GB at 0x0, but there have some memory regions are used for MCU.
>

Ah, I misread the address range, left the leading zero and assumed they
are not in DDR range. Sorry for the noise.

Regards,
Sudeep


From Shenwei.Wang at freescale.com  Tue Aug 25 07:14:58 2015
From: Shenwei.Wang at freescale.com (Shenwei Wang)
Date: Tue, 25 Aug 2015 14:14:58 +0000
Subject: [PATCH v9 1/1] irqchip: imx-gpcv2: IMX GPCv2 driver for wakeup
 sources
In-Reply-To: <55DC738D.8000302@arm.com>
References: <1440443055-7291-1-git-send-email-shenwei.wang@freescale.com>
 <55DC3452.3070205@arm.com>
 <CY1PR0301MB08439B6C5F841AFFD152DFD883610@CY1PR0301MB0843.namprd03.prod.outlook.com>
 <55DC738D.8000302@arm.com>
Message-ID: <CY1PR0301MB0843AE566996617D855CC00683610@CY1PR0301MB0843.namprd03.prod.outlook.com>



> -----Original Message-----
> From: Sudeep Holla [mailto:sudeep.holla at arm.com]
> >>> IMX7D contains a new version of GPC IP block (GPCv2). It has two
> >>> major
> >>> functions: power management and wakeup source management.
> >>> This patch adds a new irqchip driver to manage the interrupt wakeup
> >>> sources on IMX7D.
> >>
> >> Interesting, you mention that this IP block has mainly power
> >> management and it itself requires save/restore. Is it not in always on
> domain ?
> >
> > Yes, it is in always on domain.
> >
> 
> Hmm, then why do you need to save and restore the mask ?

The save/restore is used to handle the two different low power states: one is
WFI in cpu idle, and the other case is suspend. This has nothing to do with this
IP block itself.

> >>> When the system is in WFI (wait for interrupt) mode, this GPC block
> >>> will be the first block on the platform to be activated and signaled.
> >>> Under normal wait mode during cpu idle, the system can be woke up by
> >>> +static void gpcv2_wakeup_source_restore(void) {
> >>> +	struct gpcv2_irqchip_data *cd;
> >>> +	void __iomem *reg;
> >>> +	int i;
> >>> +
> >>> +	cd = imx_gpcv2_instance;
> >>> +	if (!cd)
> >>> +		return;
> >>> +
> >>> +	for (i = 0; i < IMR_NUM; i++) {
> >>> +		reg = cd->gpc_base + cd->cpu2wakeup + i * 4;
> >>> +		writel_relaxed(cd->saved_irq_mask[i], reg);
> >>
> >> Instead of saving all the non-wakeup sources, can't you use raw
> >> save/restore of these registers and mask all the non-wakeup sources
> >> by setting MASK_ON_SUSPEND ?
> >
> > I can't catch what you mean. Can you show me an example?
> >
> 
> What I meant is instead of you tracking all the enabled irqs(both wakeup and
> non-wakeup) in saved_irq_mask, just set MASK_ON_SUSPEND flag where all the
> non-wakeup interrupts are masked on suspend and unmasked on resume by the
> irq core. You can then just save and restore the wakeup irq mask, but as I asked
> above do you have to do that as you are saying it's in always on domain ?
> 
> >> Also your interrupt controller seems like has no special way to
> >> configure wakeups, you are just leaving them enabled. i.e. I see
> >> cpu2wakeup used for both {un,}masking and wakeup enable. So you can just
> use IRQCHIP_SKIP_SET_WAKE.
> >> Correct me if my understanding is wrong.
> >
> > In this driver, the Core0 is configured to be the default core to be
> > woke up, not both. You can configure it to Core1 by changing the
> > cpu2wakeup value. I don't see any reason to use IRQCHIP_SKIP_SET_WAKE flag.
> >
> 
> I don't see this driver doing anything extra apart from keeping the wakeup irqs
> enabled. i.e. You use the same cpu*wake register to mask/unmask the interrupt
> as well as set the wakeup source. Since the wakeup interrupt will be enabled by
> the driver, you just need to mark it as wake-up source and nothing extra in the
> controller right ?
> If so, you need to set IRQCHIP_SKIP_SET_WAKE as you are just leaving that irq
> enabled and not doing any extra configuration to enable it as wakeup source.
> Please correct if that wrong, but from the code that's what I could infer.

There is no special for this driver. We just use the IRQCHIP driver framework to
manage the wakeup sources. Why did you propose to set IRQCHIP_SKIP_SET_WAKE
flag here? If you don't need the wakeup feature, you should just not enable this
driver in the configuration.

Thanks,
Shenwei

> Regards,
> Sudeep

From treding at nvidia.com  Tue Aug 25 07:16:43 2015
From: treding at nvidia.com (Thierry Reding)
Date: Tue, 25 Aug 2015 16:16:43 +0200
Subject: [PATCH v3 06/14] Documentation: drm/bridge: add document for
 analogix_dp
In-Reply-To: <55DC7211.9080601@rock-chips.com>
References: <1439995728-18046-1-git-send-email-ykk@rock-chips.com>
 <1439995834-18363-1-git-send-email-ykk@rock-chips.com>
 <CAL_JsqLz+8RtBucctUj4euXZ3Ac0DvB52N9ONpAerh5T9BiTJg@mail.gmail.com>
 <20150825091534.GB14034@ulmo.nvidia.com>
 <CAL_Jsq++RLZo4gvEUTKO8MfEPwSqT2R+bqG22Jsgb2qLgDQFpw@mail.gmail.com>
 <55DC7211.9080601@rock-chips.com>
Message-ID: <20150825141642.GA3820@ulmo.nvidia.com>

On Tue, Aug 25, 2015 at 09:48:01PM +0800, Yakir Yang wrote:
> Hi Thierry & Rob,
> 
> ? 2015/8/25 21:27, Rob Herring ??:
> >On Tue, Aug 25, 2015 at 4:15 AM, Thierry Reding <treding at nvidia.com> wrote:
> >>On Sun, Aug 23, 2015 at 06:23:14PM -0500, Rob Herring wrote:
> >>>On Wed, Aug 19, 2015 at 9:50 AM, Yakir Yang <ykk at rock-chips.com> wrote:
> >>[...]
> >>>>+       -analogix,link-rate:
> >>>>+               max link rate supported by the eDP controller.
> >>>>+                       LINK_RATE_1_62GBPS = 0x6, LINK_RATE_2_70GBPS = 0x0A,
> >>>>+                       LINK_RATE_5_40GBPS = 0x14
> >>>Same here. I'd rather see something like "link-rate-mbps" and use the
> >>>actual rate.
> >>There is no need whatsoever to hard-code this in DT. (e)DP provides the
> >>means to detect what rate the link supports and the specification
> >>provides guidance on how to select an appropriate one.
> >Good, even better.
> 
> I do think we still need keep this DT prop yet.
> 
> I think drm_dp_help.c could get the "panel" max link-rate and lane-count,
> but it's not enough, we still need knew the "eDP controller" max link-rate
> and lane-count.
> 
> Let me show the exact example that happened in my side. When I connect
> my board to my 2K DP-1.2 TV. Analogix dp driver would get the max link-rate
> from dpcd, and the max link-rate is 5.4Gbps. So if I just set eDP controller
> link-rate
> to 5.4Gbps, the DP TV just broken, do not light up normally.
> 
> This reason why TV broken is the max link-rate which support by RK3288 eDP
> controller is 2.7Gbps. Here are the exact words that RK3288 eDP TRM said:
> 
> *??Compliant with DisplayPortTM Specification, Version 1.2.
> ??Compliant with eDPTM Specification, Version 1.3.
> ??HDCP v1.3 amendment for DisplayPortTM Revision 1.0.
> ??Main link containing 4 physical lanes of 2.7/1.62 Gbps/lane
> *
> **
> 
> 
> Beside I haven't found there are some registers would indicate the eDP
> controller
> max link-rate and lane-count, so this is why I still instance that we need
> this DT
> prop to indicata "Max rate controller support".
> 
> So, I wish you could agree with me on this point.

Your driver should know what link rates it supports and restrict itself
to use those. This is implied by the compatible string and doesn't need
to be duplicated into device tree.

Thierry
-------------- next part --------------
A non-text attachment was scrubbed...
Name: signature.asc
Type: application/pgp-signature
Size: 819 bytes
Desc: not available
URL: <http://lists.infradead.org/pipermail/linux-arm-kernel/attachments/20150825/5f331b4b/attachment-0001.sig>

From Shenwei.Wang at freescale.com  Tue Aug 25 07:20:20 2015
From: Shenwei.Wang at freescale.com (Shenwei Wang)
Date: Tue, 25 Aug 2015 14:20:20 +0000
Subject: [PATCH v3 1/1] misc: sram: add dev_pm_ops to support module power
 gate
In-Reply-To: <55DC74CF.7070300@arm.com>
References: <1438272681-29338-1-git-send-email-shenwei.wang@freescale.com>
 <55DC677E.1030004@arm.com>
 <CY1PR0301MB0843D5CB5FFC56991B90EB4283610@CY1PR0301MB0843.namprd03.prod.outlook.com>
 <55DC74CF.7070300@arm.com>
Message-ID: <CY1PR0301MB084302FA2AA9582A3BA9B50B83610@CY1PR0301MB0843.namprd03.prod.outlook.com>



> -----Original Message-----
> From: Sudeep Holla [mailto:sudeep.holla at arm.com]
> Sent: 2015?8?25? 9:00
> To: Wang Shenwei-B38339
> Cc: Sudeep Holla; gregkh at linuxfoundation.org; arnd at arndb.de; Huang
> Yongcai-B20788; linux-arm-kernel at lists.infradead.org
> Subject: Re: [PATCH v3 1/1] misc: sram: add dev_pm_ops to support module
> power gate
> > On latest Freescale i.MX7D, it has two SRAMs in side. One is for low
> > power mode which will be powered on in suspend state. The other one is
> > for other peripherals which can be powered off on demand.
> >
> 
> What I meant is who will be using the SRAM when entering S2R that you need to
> save the content. Either the user needs to take care of the content or just release
> the pool when not in use. When the sram pool has no user, clock can be gated.
> 
> Again can you give details of this use-case.

We are not talking about clock gate state. Here we are handling the power gate for 
this SRAM IP block. Of course, you can ask each driver to save its contents during 
low power state, but I think the easier way is to save the contents in this sram driver
and just leave the drivers who use this sram behave as is today.

Thanks,
Shenwei

> Regards,
> Sudeep

From linus.walleij at linaro.org  Tue Aug 25 07:22:50 2015
From: linus.walleij at linaro.org (Linus Walleij)
Date: Tue, 25 Aug 2015 16:22:50 +0200
Subject: [PATCH] pinctrl-zynq.c: Fix typos in smc0_nand_grp and
 smc0_nor_grp
In-Reply-To: <1439389332-9373-1-git-send-email-mike.looijmans@topic.nl>
References: <1439389332-9373-1-git-send-email-mike.looijmans@topic.nl>
Message-ID: <CACRpkdbv63vTZEDncPc4BPK09xNiWRd=+1xtvRVZr7kN4ncZ=w@mail.gmail.com>

On Wed, Aug 12, 2015 at 4:22 PM, Mike Looijmans <mike.looijmans at topic.nl> wrote:

> Group names should be smc0_nand_grp and smc0_nor_grp, otherwise you'll
> get errors like this if you try to pinmux them via the devicetree:
> zynq-pinctrl 700.pinctrl: invalid group "smc0_nand_grp" for function "smc0_nand"
>
> Probably a typo while creating these tables.
>
> Signed-off-by: Mike Looijmans <mike.looijmans at topic.nl>
> Acked-by: S?ren Brinkmann <soren.brinkmann at xilinx.com>

Patch applied with Moritz' ACK.

Yours,
Linus Walleij


From treding at nvidia.com  Tue Aug 25 07:21:51 2015
From: treding at nvidia.com (Thierry Reding)
Date: Tue, 25 Aug 2015 16:21:51 +0200
Subject: [PATCH v3 06/14] Documentation: drm/bridge: add document for
 analogix_dp
In-Reply-To: <55DC75C8.209@rock-chips.com>
References: <1439995728-18046-1-git-send-email-ykk@rock-chips.com>
 <1439995834-18363-1-git-send-email-ykk@rock-chips.com>
 <20150825095817.GC14034@ulmo.nvidia.com>
 <55DC75C8.209@rock-chips.com>
Message-ID: <20150825142150.GB3820@ulmo.nvidia.com>

On Tue, Aug 25, 2015 at 10:03:52PM +0800, Yakir Yang wrote:
> Hi Thierry,
> 
> ? 2015/8/25 17:58, Thierry Reding ??:
> >On Wed, Aug 19, 2015 at 09:50:34AM -0500, Yakir Yang wrote:
> >[...]
> >>+	-analogix,color-space:
> >>+		input video data format.
> >>+			COLOR_RGB = 0, COLOR_YCBCR422 = 1, COLOR_YCBCR444 = 2
> >I don't think DT is an appropriate place to set this. To my knowledge
> >this depends on the display and/or mode, so I don't think hard-coding
> >it here is the right thing to do.
> 
> Yeah, same question with my previous reply ;)

I don't have an answer for you, unfortunately. But like I said,
hard-coding isn't going to work. What if, for example, you set this to a
fixed value and then you connect a monitor that doesn't support the
specific one you set?

You cited code from dw_hdmi.c earlier, it looks like it might be correct
even though it doesn't cite a reference for why this was done. Perhaps
someone on this thread, or someone involved with dw_hdmi can answer
where that code came from.

Thierry
-------------- next part --------------
A non-text attachment was scrubbed...
Name: signature.asc
Type: application/pgp-signature
Size: 819 bytes
Desc: not available
URL: <http://lists.infradead.org/pipermail/linux-arm-kernel/attachments/20150825/79ae0ecb/attachment.sig>

From leif.lindholm at linaro.org  Tue Aug 25 07:24:16 2015
From: leif.lindholm at linaro.org (Leif Lindholm)
Date: Tue, 25 Aug 2015 15:24:16 +0100
Subject: [PATCH v1 3/3] arm64: dts: add Hi6220 mailbox node
In-Reply-To: <1440510194.10987.52.camel@linaro.org>
References: <20150821184059.GB2000@svinekod>
 <20150824091845.GA28290@leoy-linaro>
 <20150824095144.GA7139@leverpostej>
 <1440411596.3517.12.camel@linaro.org>
 <20150824114903.GT10728@bivouac.eciton.net>
 <1440490427.10987.29.camel@linaro.org>
 <20150825094630.GU10728@bivouac.eciton.net>
 <1440497710.10987.42.camel@linaro.org>
 <20150825104256.GB13471@leverpostej>
 <1440510194.10987.52.camel@linaro.org>
Message-ID: <20150825142416.GW10728@bivouac.eciton.net>

On Tue, Aug 25, 2015 at 09:43:14PM +0800, Haojian Zhuang wrote:
> Since we discussed a lot on this, let's make a conclusion on it.
> 
> 1. UEFI could append the reserved buffer in it's memory mapping.

Yes. It needs to.

(I will let Mark comment on points 2-4.)

> 5. A patch is necessary in kernel. If efi stub feature is enabled,
>    arm kernel should not parse memory node or reserved memory buffer in
>    DT any more.

This is already the case. The stub deletes any present memory nodes and
reserved entries in drivers/firmware/efi/libstub/fdt.c:update_fdt().

Then, during setup_arch(), arch/arm64/kernel/efi.c:efi_init() calls
reserve_regions(), which adds only those memory regions available for
use by Linux as RAM to memblock.

>    Arm kernel should either fetch memory information from 
>    efi or DT.

Absolutely.

>    Currently arm kernel fetch both efi memory information and
>    reserved buffer from DTB at the same time.

No, it does not.

Regards,

Leif


From linus.walleij at linaro.org  Tue Aug 25 07:25:09 2015
From: linus.walleij at linaro.org (Linus Walleij)
Date: Tue, 25 Aug 2015 16:25:09 +0200
Subject: [PATCH 2/6] gpio: Introduce gpio descriptor 'name'
In-Reply-To: <20150813132813.GX19600@pengutronix.de>
References: <1438680203-13432-1-git-send-email-mpa@pengutronix.de>
 <1438680203-13432-3-git-send-email-mpa@pengutronix.de>
 <CACRpkdYv=-fCj+ts9tTmFsovPN0RPYkOdYh9Dj6oFDJiRV=RUA@mail.gmail.com>
 <20150813132813.GX19600@pengutronix.de>
Message-ID: <CACRpkdYhAe7fpqvixLhZ2t=3hC1w=VHNtWNSJverVb7ng3Qe_Q@mail.gmail.com>

On Thu, Aug 13, 2015 at 3:28 PM, Markus Pargmann <mpa at pengutronix.de> wrote:
> On Mon, Aug 10, 2015 at 11:37:06AM +0200, Linus Walleij wrote:
>> On Tue, Aug 4, 2015 at 11:23 AM, Markus Pargmann <mpa at pengutronix.de> wrote:
>>
>> > The latest gpio hogging mechanism assigns each gpio a 'line-name' in the
>> > devicetree. The 'name' field is different from the 'label' field.
>> > 'label' is only used for requested GPIOs to describe its current use by
>> > driver or userspace.
>> >
>> > The 'name' field describes the GPIO itself, not the use. This is most
>> > likely identical to the label in the schematic on the GPIO line and
>> > should help to find this particular GPIO.
>> >
>> > This patch adds a helper function to find gpio descriptors by name
>> > instead of gpio number.
>> >
>> > Signed-off-by: Markus Pargmann <mpa at pengutronix.de>
>>
>> Oh I realized there is a big problem with this.
>>
>> struct gpio_chip already contains this:
>>
>>         const char              *const *names;
>>
>> Now it seems like names can be stored in two places:
>> in an array in the gpio_chip and in a name tag in struct
>> gpio_desc.
>>
>> So how do we handle this?
>>
>> I guess we need to keep just *one* of them, so maybe remove
>> the names array from the struct gpio_chip and add a helper function
>> that sets the names on the descs for the lines like:
>>
>> int gpiochip_set_names(struct gpio_chip *gc, const char * const names);
>>
>> And then refactor all code and chips that use the old names
>> array to use this instead. I don't think they are too many, really.
>
> That sounds good. There are just a few users of this names array, so it
> should all be fine.

OK thanks.

> Just to clarify: The line names will then be the same as this name
> array? So all GPIOs with name/line-names are then exported by their name
> and not the number?

Yeah I consider it a legacy mechanism to achieve the same thing.

The problem with it is that it has a flat namespace and we
need to conform to that.

Yours,
Linus Walleij


From andre.przywara at arm.com  Tue Aug 25 07:34:06 2015
From: andre.przywara at arm.com (Andre Przywara)
Date: Tue, 25 Aug 2015 15:34:06 +0100
Subject: [PATCH v2 11/15] KVM: arm64: handle pending bit for LPIs in ITS
 emulation
In-Reply-To: <55CDD7ED.90008@linaro.org>
References: <1436538111-4294-1-git-send-email-andre.przywara@arm.com>
 <1436538111-4294-12-git-send-email-andre.przywara@arm.com>
 <55CDD7ED.90008@linaro.org>
Message-ID: <55DC7CDE.3020409@arm.com>

Hi Eric,

On 14/08/15 12:58, Eric Auger wrote:
> On 07/10/2015 04:21 PM, Andre Przywara wrote:
>> As the actual LPI number in a guest can be quite high, but is mostly
>> assigned using a very sparse allocation scheme, bitmaps and arrays
>> for storing the virtual interrupt status are a waste of memory.
>> We use our equivalent of the "Interrupt Translation Table Entry"
>> (ITTE) to hold this extra status information for a virtual LPI.
>> As the normal VGIC code cannot use it's fancy bitmaps to manage
>> pending interrupts, we provide a hook in the VGIC code to let the
>> ITS emulation handle the list register queueing itself.
>> LPIs are located in a separate number range (>=8192), so
>> distinguishing them is easy. With LPIs being only edge-triggered, we
>> get away with a less complex IRQ handling.
>>
>> Signed-off-by: Andre Przywara <andre.przywara at arm.com>
>> ---
>>  include/kvm/arm_vgic.h      |  2 ++
>>  virt/kvm/arm/its-emul.c     | 71 ++++++++++++++++++++++++++++++++++++++++++++
>>  virt/kvm/arm/its-emul.h     |  3 ++
>>  virt/kvm/arm/vgic-v3-emul.c |  2 ++
>>  virt/kvm/arm/vgic.c         | 72 ++++++++++++++++++++++++++++++++++-----------
>>  5 files changed, 133 insertions(+), 17 deletions(-)
>>
>> diff --git a/include/kvm/arm_vgic.h b/include/kvm/arm_vgic.h
>> index 1648668..2a67a10 100644
>> --- a/include/kvm/arm_vgic.h
>> +++ b/include/kvm/arm_vgic.h
>> @@ -147,6 +147,8 @@ struct vgic_vm_ops {
>>       int     (*init_model)(struct kvm *);
>>       void    (*destroy_model)(struct kvm *);
>>       int     (*map_resources)(struct kvm *, const struct vgic_params *);
>> +     bool    (*queue_lpis)(struct kvm_vcpu *);
>> +     void    (*unqueue_lpi)(struct kvm_vcpu *, int irq);
>>  };
>>
>>  struct vgic_io_device {
>> diff --git a/virt/kvm/arm/its-emul.c b/virt/kvm/arm/its-emul.c
>> index 7f217fa..b9c40d7 100644
>> --- a/virt/kvm/arm/its-emul.c
>> +++ b/virt/kvm/arm/its-emul.c
>> @@ -50,8 +50,26 @@ struct its_itte {
>>       struct its_collection *collection;
>>       u32 lpi;
>>       u32 event_id;
>> +     bool enabled;
>> +     unsigned long *pending;
>>  };
>>
>> +#define for_each_lpi(dev, itte, kvm) \
>> +     list_for_each_entry(dev, &(kvm)->arch.vgic.its.device_list, dev_list) \
>> +             list_for_each_entry(itte, &(dev)->itt, itte_list)
>> +
> You have a checkpatch error here:
> 
> ERROR: Macros with complex values should be enclosed in parentheses
> #52: FILE: virt/kvm/arm/its-emul.c:57:
> +#define for_each_lpi(dev, itte, kvm) \
> +       list_for_each_entry(dev, &(kvm)->arch.vgic.its.device_list, dev_list) \
> +               list_for_each_entry(itte, &(dev)->itt, itte_list)

I know about that one. The problem is that if I add the parentheses it
breaks the usage below due to the curly brackets. But the definition
above is just so convenient and I couldn't find another neat solution so
far. If you are concerned about that I can give it another try,
otherwise I tend to just ignore checkpatch here.

>> +static struct its_itte *find_itte_by_lpi(struct kvm *kvm, int lpi)
>> +{
> can't we have the same LPI present in different interrupt translation
> tables? I don't know it is a sensible setting but I did not succeed in
> finding it was not possible.

Thanks to Marc I am happy (and relieved!) to point you to 6.1.1 LPI INTIDs:
"The behavior of the GIC is UNPREDICTABLE if software:
- Maps multiple EventID/DeviceID combinations to the same physical LPI
INTID."

So I exercise the freedom of UNPREDICTABLE here ;-)

>> +     struct its_device *device;
>> +     struct its_itte *itte;
>> +
>> +     for_each_lpi(device, itte, kvm) {
>> +             if (itte->lpi == lpi)
>> +                     return itte;
>> +     }
>> +     return NULL;
>> +}
>> +
>>  #define BASER_BASE_ADDRESS(x) ((x) & 0xfffffffff000ULL)
>>
>>  /* The distributor lock is held by the VGIC MMIO handler. */
>> @@ -145,6 +163,59 @@ static bool handle_mmio_gits_idregs(struct kvm_vcpu *vcpu,
>>       return false;
>>  }
>>
>> +/*
>> + * Find all enabled and pending LPIs and queue them into the list
>> + * registers.
>> + * The dist lock is held by the caller.
>> + */
>> +bool vits_queue_lpis(struct kvm_vcpu *vcpu)
>> +{
>> +     struct vgic_its *its = &vcpu->kvm->arch.vgic.its;
>> +     struct its_device *device;
>> +     struct its_itte *itte;
>> +     bool ret = true;
>> +
>> +     if (!vgic_has_its(vcpu->kvm))
>> +             return true;
>> +     if (!its->enabled || !vcpu->kvm->arch.vgic.lpis_enabled)
>> +             return true;
>> +
>> +     spin_lock(&its->lock);
>> +     for_each_lpi(device, itte, vcpu->kvm) {
>> +             if (!itte->enabled || !test_bit(vcpu->vcpu_id, itte->pending))
>> +                     continue;
>> +
>> +             if (!itte->collection)
>> +                     continue;
>> +
>> +             if (itte->collection->target_addr != vcpu->vcpu_id)
>> +                     continue;
>> +
>> +             __clear_bit(vcpu->vcpu_id, itte->pending);
>> +
>> +             ret &= vgic_queue_irq(vcpu, 0, itte->lpi);
> what if the vgic_queue_irq fails since no LR can be found, the
> itte->pending was cleared so we forget that LPI? shouldn't we restore
> the pending state in ITT? in vgic_queue_hwirq the state change only is
> performed if the vgic_queue_irq succeeds

Of course you are right. I will just only clear the bit if the call
succeeds.

>> +     }
>> +
>> +     spin_unlock(&its->lock);
>> +     return ret;
>> +}
>> +
>> +/* Called with the distributor lock held by the caller. */
>> +void vits_unqueue_lpi(struct kvm_vcpu *vcpu, int lpi)
> I was a bit confused by the name of the function, with regard to
> existing vgic_unqueue_irqs which restores the states in accordance to
> what we have in LR. Wouldn't it make sense to call it
> vits_lpi_set_pending(vcpu, lpi) or something that looks more similar to
> vgic_dist_irq_set_pending setter which I think it mirrors.

Well, vgic_unqueue_irqs() "move[s] pending/active IRQs from LRs to the
distributor", this is what vits_unqueue_lpi() also does, just for one
_single_ LPI instead of iterating over all LRs. Originally I planned to
call vgic_unqueue_irqs on every guest exit, so this would have a more
obvious match.
Admittedly the function does not do much "unqueueing", as this is done
in the caller, so I will think about the renaming part.

>> +{
>> +     struct vgic_its *its = &vcpu->kvm->arch.vgic.its;
>> +     struct its_itte *itte;
>> +
>> +     spin_lock(&its->lock);
>> +
>> +     /* Find the right ITTE and put the pending state back in there */
>> +     itte = find_itte_by_lpi(vcpu->kvm, lpi);
>> +     if (itte)
>> +             __set_bit(vcpu->vcpu_id, itte->pending);
>> +
>> +     spin_unlock(&its->lock);
>> +}
>> +
>>  static int vits_handle_command(struct kvm_vcpu *vcpu, u64 *its_cmd)
>>  {
>>       return -ENODEV;
>> diff --git a/virt/kvm/arm/its-emul.h b/virt/kvm/arm/its-emul.h
>> index 472a6d0..cc5d5ff 100644
>> --- a/virt/kvm/arm/its-emul.h
>> +++ b/virt/kvm/arm/its-emul.h
>> @@ -33,4 +33,7 @@ void vgic_enable_lpis(struct kvm_vcpu *vcpu);
>>  int vits_init(struct kvm *kvm);
>>  void vits_destroy(struct kvm *kvm);
>>
>> +bool vits_queue_lpis(struct kvm_vcpu *vcpu);
>> +void vits_unqueue_lpi(struct kvm_vcpu *vcpu, int irq);
>> +
>>  #endif
>> diff --git a/virt/kvm/arm/vgic-v3-emul.c b/virt/kvm/arm/vgic-v3-emul.c
>> index 49be3c3..4132c26 100644
>> --- a/virt/kvm/arm/vgic-v3-emul.c
>> +++ b/virt/kvm/arm/vgic-v3-emul.c
>> @@ -948,6 +948,8 @@ void vgic_v3_init_emulation(struct kvm *kvm)
>>       dist->vm_ops.init_model = vgic_v3_init_model;
>>       dist->vm_ops.destroy_model = vgic_v3_destroy_model;
>>       dist->vm_ops.map_resources = vgic_v3_map_resources;
>> +     dist->vm_ops.queue_lpis = vits_queue_lpis;
>> +     dist->vm_ops.unqueue_lpi = vits_unqueue_lpi;
>>
>>       dist->vgic_dist_base = VGIC_ADDR_UNDEF;
>>       dist->vgic_redist_base = VGIC_ADDR_UNDEF;
>> diff --git a/virt/kvm/arm/vgic.c b/virt/kvm/arm/vgic.c
>> index 49ee92b..9dfd094 100644
>> --- a/virt/kvm/arm/vgic.c
>> +++ b/virt/kvm/arm/vgic.c
>> @@ -95,6 +95,20 @@ static bool queue_sgi(struct kvm_vcpu *vcpu, int irq)
>>       return vcpu->kvm->arch.vgic.vm_ops.queue_sgi(vcpu, irq);
>>  }
>>
>> +static bool vgic_queue_lpis(struct kvm_vcpu *vcpu)
>> +{
>> +     if (vcpu->kvm->arch.vgic.vm_ops.queue_lpis)
>> +             return vcpu->kvm->arch.vgic.vm_ops.queue_lpis(vcpu);
>> +     else
>> +             return true;
>> +}
>> +
>> +static void vgic_unqueue_lpi(struct kvm_vcpu *vcpu, int irq)
>> +{
>> +     if (vcpu->kvm->arch.vgic.vm_ops.unqueue_lpi)
>> +             vcpu->kvm->arch.vgic.vm_ops.unqueue_lpi(vcpu, irq);
>> +}
>> +
>>  int kvm_vgic_map_resources(struct kvm *kvm)
>>  {
>>       return kvm->arch.vgic.vm_ops.map_resources(kvm, vgic);
>> @@ -1135,6 +1149,10 @@ static void vgic_retire_disabled_irqs(struct kvm_vcpu *vcpu)
>>       for_each_clear_bit(lr, elrsr_ptr, vgic->nr_lr) {
>>               vlr = vgic_get_lr(vcpu, lr);
>>
>> +             /* We don't care about LPIs here */
>> +             if (vlr.irq >= 8192)
>> +                     continue;
>> +
>>               if (!vgic_irq_is_enabled(vcpu, vlr.irq)) {
>>                       vlr.state = 0;
>>                       vgic_set_lr(vcpu, lr, vlr);
>> @@ -1147,25 +1165,33 @@ static void vgic_retire_disabled_irqs(struct kvm_vcpu *vcpu)
>>  static void vgic_queue_irq_to_lr(struct kvm_vcpu *vcpu, int irq,
>>                                int lr_nr, int sgi_source_id)
>>  {
>> +     struct vgic_dist *dist = &vcpu->kvm->arch.vgic;
>>       struct vgic_lr vlr;
>>
>>       vlr.state = 0;
>>       vlr.irq = irq;
>>       vlr.source = sgi_source_id;
>>
>> -     if (vgic_irq_is_active(vcpu, irq)) {
>> -             vlr.state |= LR_STATE_ACTIVE;
>> -             kvm_debug("Set active, clear distributor: 0x%x\n", vlr.state);
>> -             vgic_irq_clear_active(vcpu, irq);
>> -             vgic_update_state(vcpu->kvm);
>> -     } else if (vgic_dist_irq_is_pending(vcpu, irq)) {
>> -             vlr.state |= LR_STATE_PENDING;
>> -             kvm_debug("Set pending: 0x%x\n", vlr.state);
>> -     }
>> -
>> -     if (!vgic_irq_is_edge(vcpu, irq))
>> -             vlr.state |= LR_EOI_INT;
>> +     /* We care only about state for SGIs/PPIs/SPIs, not for LPIs */
>> +     if (irq < dist->nr_irqs) {
>> +             if (vgic_irq_is_active(vcpu, irq)) {
>> +                     vlr.state |= LR_STATE_ACTIVE;
>> +                     kvm_debug("Set active, clear distributor: 0x%x\n",
>> +                               vlr.state);
>> +                     vgic_irq_clear_active(vcpu, irq);
>> +                     vgic_update_state(vcpu->kvm);
>> +             } else if (vgic_dist_irq_is_pending(vcpu, irq)) {
>> +                     vlr.state |= LR_STATE_PENDING;
>> +                     kvm_debug("Set pending: 0x%x\n", vlr.state);
>> +             }
>>
>> +             if (!vgic_irq_is_edge(vcpu, irq))
>> +                     vlr.state |= LR_EOI_INT;
>> +     } else {
>> +             /* If this is an LPI, it can only be pending */
>> +             if (irq >= 8192)
>> +                     vlr.state |= LR_STATE_PENDING;
>> +     }
>>       vgic_set_lr(vcpu, lr_nr, vlr);
>>       vgic_sync_lr_elrsr(vcpu, lr_nr, vlr);
>>  }
>> @@ -1177,7 +1203,6 @@ static void vgic_queue_irq_to_lr(struct kvm_vcpu *vcpu, int irq,
>>   */
>>  bool vgic_queue_irq(struct kvm_vcpu *vcpu, u8 sgi_source_id, int irq)
>>  {
>> -     struct vgic_dist *dist = &vcpu->kvm->arch.vgic;
>>       u64 elrsr = vgic_get_elrsr(vcpu);
>>       unsigned long *elrsr_ptr = u64_to_bitmask(&elrsr);
>>       int lr;
>> @@ -1185,7 +1210,6 @@ bool vgic_queue_irq(struct kvm_vcpu *vcpu, u8 sgi_source_id, int irq)
>>       /* Sanitize the input... */
>>       BUG_ON(sgi_source_id & ~7);
>>       BUG_ON(sgi_source_id && irq >= VGIC_NR_SGIS);
>> -     BUG_ON(irq >= dist->nr_irqs);
> Is it safe to remove that check. What if it is attempted to inject an
> SPI larger than supported. I think you should refine the check but not
> remove it.

The check is now in vgic_queue_irq_to_lr (see above), where we
differentiate between LPIs (>=8192) and SPIs (<dist->nr_irqs). Please
correct me if I am wrong on this, but since we are not setting any state
bits the vgic_set_lr() and vgic_sync_lr_elrsr() calls should be NOPs in
this case, right?
I may re-add the explicit check here for the sake of clarity, though.

>>
>>       kvm_debug("Queue IRQ%d\n", irq);
>>
>> @@ -1265,8 +1289,12 @@ static void __kvm_vgic_flush_hwstate(struct kvm_vcpu *vcpu)
>>                       overflow = 1;
>>       }
>>
>> -
>> -
>> +     /*
>> +      * LPIs are not mapped in our bitmaps, so we leave the iteration
>> +      * to the ITS emulation code.
>> +      */
>> +     if (!vgic_queue_lpis(vcpu))
>> +             overflow = 1;
>>
>>  epilog:
>>       if (overflow) {
>> @@ -1387,6 +1415,16 @@ static void __kvm_vgic_sync_hwstate(struct kvm_vcpu *vcpu)
>>       for_each_clear_bit(lr_nr, elrsr_ptr, vgic_cpu->nr_lr) {
>>               vlr = vgic_get_lr(vcpu, lr_nr);
>>
>> +             /* LPIs are handled separately */
>> +             if (vlr.irq >= 8192) {
>> +                     /* We just need to take care about still pending LPIs */
>> +                     if (vlr.state & LR_STATE_PENDING) {
>> +                             vgic_unqueue_lpi(vcpu, vlr.irq);
>> +                             pending = true;
>> +                     }
>> +                     continue;
> don't we need to reset the LR & update elrsr?

Mmmh, interesting, I just wonder how it worked before. I will move most
of the lower part into an else clause and call the LR maintainance code
in both cases.

Cheers,
Andre.

>> +             }
>> +
>>               BUG_ON(!(vlr.state & LR_STATE_MASK));
>>               pending = true;
>>
>> @@ -1411,7 +1449,7 @@ static void __kvm_vgic_sync_hwstate(struct kvm_vcpu *vcpu)
>>       }
>>       vgic_update_state(vcpu->kvm);
>>
>> -     /* vgic_update_state would not cover only-active IRQs */
>> +     /* vgic_update_state would not cover only-active IRQs or LPIs */
>>       if (pending)
>>               set_bit(vcpu->vcpu_id, dist->irq_pending_on_cpu);
>>  }
>>
> 


From linus.walleij at linaro.org  Tue Aug 25 07:34:38 2015
From: linus.walleij at linaro.org (Linus Walleij)
Date: Tue, 25 Aug 2015 16:34:38 +0200
Subject: [PATCH 6/6] gpiolib: Add gpio name information to
 /sys/kernel/debug/gpio
In-Reply-To: <CAAVeFuKSQP2DYWdhYy-k+cr9F0jc46Q-xuoWXSTguQYaf3SY+w@mail.gmail.com>
References: <1438680203-13432-1-git-send-email-mpa@pengutronix.de>
 <1438680203-13432-7-git-send-email-mpa@pengutronix.de>
 <CACRpkdajd5B6qUa6mi_0m53eMtLenoAWUCnmq-mOC+EhXfzpTA@mail.gmail.com>
 <CAAVeFuKSQP2DYWdhYy-k+cr9F0jc46Q-xuoWXSTguQYaf3SY+w@mail.gmail.com>
Message-ID: <CACRpkdaMw=3JXF4n-u+=x7aSWKnn5rQQ4Xy4afkTL30Q6RHWTg@mail.gmail.com>

On Mon, Aug 17, 2015 at 9:29 AM, Alexandre Courbot <gnurou at gmail.com> wrote:
> On Mon, Aug 10, 2015 at 7:02 PM, Linus Walleij <linus.walleij at linaro.org> wrote:
>> On Tue, Aug 4, 2015 at 11:23 AM, Markus Pargmann <mpa at pengutronix.de> wrote:
>>
>>> Add some information about gpio names to the debugfs gpio file. name and
>>> label of a GPIO are then displayed next to each other. This way it is
>>> easy to see what the real name of GPIO is and what the driver requested
>>> it for.
>>>
>>> Signed-off-by: Markus Pargmann <mpa at pengutronix.de>
>>
>> This patch looks correct in the context.
>
> Looks correct indeed, but on a related note one might question the
> need to have both a "name" and a "label" for a GPIO?

The way I see it a certain GPIO controller has names for the
GPIO lines, like gpio0,1,2...n, while the label is for the actual
use of the GPIO line. It's a bit like the regulator name, rail name
and consumer endpoints guess. Just we only have two names,
not three :P

Yours,
Linus Walleij


From sudeep.holla at arm.com  Tue Aug 25 07:40:30 2015
From: sudeep.holla at arm.com (Sudeep Holla)
Date: Tue, 25 Aug 2015 15:40:30 +0100
Subject: [PATCH v3 1/1] misc: sram: add dev_pm_ops to support module power
 gate
In-Reply-To: <CY1PR0301MB084302FA2AA9582A3BA9B50B83610@CY1PR0301MB0843.namprd03.prod.outlook.com>
References: <1438272681-29338-1-git-send-email-shenwei.wang@freescale.com>
 <55DC677E.1030004@arm.com>
 <CY1PR0301MB0843D5CB5FFC56991B90EB4283610@CY1PR0301MB0843.namprd03.prod.outlook.com>
 <55DC74CF.7070300@arm.com>
 <CY1PR0301MB084302FA2AA9582A3BA9B50B83610@CY1PR0301MB0843.namprd03.prod.outlook.com>
Message-ID: <55DC7E5E.5020701@arm.com>



On 25/08/15 15:20, Shenwei Wang wrote:
>
>
>> -----Original Message-----
>> From: Sudeep Holla [mailto:sudeep.holla at arm.com]
>> Sent: 2015?8?25? 9:00
>> To: Wang Shenwei-B38339
>> Cc: Sudeep Holla; gregkh at linuxfoundation.org; arnd at arndb.de; Huang
>> Yongcai-B20788; linux-arm-kernel at lists.infradead.org
>> Subject: Re: [PATCH v3 1/1] misc: sram: add dev_pm_ops to support module
>> power gate
>>> On latest Freescale i.MX7D, it has two SRAMs in side. One is for low
>>> power mode which will be powered on in suspend state. The other one is
>>> for other peripherals which can be powered off on demand.
>>>
>>
>> What I meant is who will be using the SRAM when entering S2R that you need to
>> save the content. Either the user needs to take care of the content or just release
>> the pool when not in use. When the sram pool has no user, clock can be gated.
>>
>> Again can you give details of this use-case.
>
> We are not talking about clock gate state. Here we are handling the power gate for
> this SRAM IP block. Of course, you can ask each driver to save its contents during
> low power state, but I think the easier way is to save the contents in this sram driver
> and just leave the drivers who use this sram behave as is today.
>

I don't like that solution as it's not scalable with SRAM size and
saving all the content of SRAM just because of few active regions makes
no sense to me at-least. I prefer leaving it to the users to handle that
rather than SRAM driver.

Regards,
Sudeep


From sudeep.holla at arm.com  Tue Aug 25 07:45:56 2015
From: sudeep.holla at arm.com (Sudeep Holla)
Date: Tue, 25 Aug 2015 15:45:56 +0100
Subject: [PATCH v9 1/1] irqchip: imx-gpcv2: IMX GPCv2 driver for wakeup
 sources
In-Reply-To: <CY1PR0301MB0843AE566996617D855CC00683610@CY1PR0301MB0843.namprd03.prod.outlook.com>
References: <1440443055-7291-1-git-send-email-shenwei.wang@freescale.com>
 <55DC3452.3070205@arm.com>
 <CY1PR0301MB08439B6C5F841AFFD152DFD883610@CY1PR0301MB0843.namprd03.prod.outlook.com>
 <55DC738D.8000302@arm.com>
 <CY1PR0301MB0843AE566996617D855CC00683610@CY1PR0301MB0843.namprd03.prod.outlook.com>
Message-ID: <55DC7FA4.7040902@arm.com>



On 25/08/15 15:14, Shenwei Wang wrote:
>
>
>> -----Original Message-----
>> From: Sudeep Holla [mailto:sudeep.holla at arm.com]

[...]

>> I don't see this driver doing anything extra apart from keeping the wakeup irqs
>> enabled. i.e. You use the same cpu*wake register to mask/unmask the interrupt
>> as well as set the wakeup source. Since the wakeup interrupt will be enabled by
>> the driver, you just need to mark it as wake-up source and nothing extra in the
>> controller right ?
>> If so, you need to set IRQCHIP_SKIP_SET_WAKE as you are just leaving that irq
>> enabled and not doing any extra configuration to enable it as wakeup source.
>> Please correct if that wrong, but from the code that's what I could infer.
>
> There is no special for this driver. We just use the IRQCHIP driver framework to
> manage the wakeup sources. Why did you propose to set IRQCHIP_SKIP_SET_WAKE
> flag here? If you don't need the wakeup feature, you should just not enable this
> driver in the configuration.
>

No, if the driver doesn't nothing extra to configure the wake up source
other than keeping it enabled, then it fits the case of SKIP_SET_WAKE.
The driver using this wake would have requested and enabled the irq.
When it calls enable_irq_wake, you have nothing extra to set(atleast
from the looks of the driver), so setting SKIP_SET_WAKE will skip the
call and updated the wake flags in irq core.

I don't see the real need of 2 separate sets of irq mask being saved in
either case.

Regards,
Sudeep


From jogo at openwrt.org  Tue Aug 25 07:50:05 2015
From: jogo at openwrt.org (Jonas Gorski)
Date: Tue, 25 Aug 2015 16:50:05 +0200
Subject: [PATCH v4] qcom: ipq4019: Add basic board/dts support for IPQ4019
 SoC
In-Reply-To: <20150825120804.GA30996@codeaurora.org>
References: <20150825120804.GA30996@codeaurora.org>
Message-ID: <CAOiHx=kz1voQXre2tkNC2bZo6fqq0L81+V9VeZadKhjR0nDNww@mail.gmail.com>

Hi,

On Tue, Aug 25, 2015 at 2:08 PM, Varadarajan Narayanan
<varada at codeaurora.org> wrote:
> Add initial dts files and SoC support for IPQ4019
>
> Signed-off-by: Varadarajan Narayanan <varada at codeaurora.org>
> ---
> Changes in v2:
>   - Added devicetree bindings documentation
>
> Changes in v3:
>   - Split 'gcnt' into a separate patch
>   - Added the new entries to Makefiles, Kconfig & board.c in sorted order
>   - Used "qcom,ipq40xx" instead of "qcom,ipq40xx-r3pc" in board.c
>
> Changes in v4:
>   - Renamed IPQ40xx as IPQ4019
>   - Moved kconfig and defconfig enablement to separate patch
>   - Dropped Documentation/devicetree/bindings/qcom.txt
>
>  arch/arm/boot/dts/Makefile              |  1 +
>  arch/arm/boot/dts/qcom-ipq4019-r3pc.dts | 34 ++++++++++++++
>  arch/arm/boot/dts/qcom-ipq4019.dtsi     | 81 +++++++++++++++++++++++++++++++++
>  3 files changed, 116 insertions(+)
>  create mode 100644 arch/arm/boot/dts/qcom-ipq4019-r3pc.dts
>  create mode 100644 arch/arm/boot/dts/qcom-ipq4019.dtsi
>
> diff --git a/arch/arm/boot/dts/Makefile b/arch/arm/boot/dts/Makefile
> index 246473a..ca603f3 100644
> --- a/arch/arm/boot/dts/Makefile
> +++ b/arch/arm/boot/dts/Makefile
> @@ -474,6 +474,7 @@ dtb-$(CONFIG_ARCH_QCOM) += \
>         qcom-apq8074-dragonboard.dtb \
>         qcom-apq8084-ifc6540.dtb \
>         qcom-apq8084-mtp.dtb \
> +       qcom-ipq4019-r3pc.dtb \
>         qcom-ipq8064-ap148.dtb \
>         qcom-msm8660-surf.dtb \
>         qcom-msm8960-cdp.dtb \
> diff --git a/arch/arm/boot/dts/qcom-ipq4019-r3pc.dts b/arch/arm/boot/dts/qcom-ipq4019-r3pc.dts
> new file mode 100644
> index 0000000..e3855d7
> --- /dev/null
> +++ b/arch/arm/boot/dts/qcom-ipq4019-r3pc.dts
> @@ -0,0 +1,34 @@
> +/* Copyright (c) 2014, The Linux Foundation. All rights reserved.
> + *
> + * This program is free software; you can redistribute it and/or modify
> + * it under the terms of the GNU General Public License version 2 and
> + * only 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 "qcom-ipq4019.dtsi"
> +
> +/ {
> +       model = "Qualcomm Technologies, Inc. IPQ4019 R3PC";
> +       compatible = "qcom,ipq4019-r3pc", "qcom,ipq4019";
> +
> +       memory {
> +               device_type = "memory";
> +               reg = <0x80000000 0x20000000>; /* 512MB */
> +       };
> +
> +       chosen {
> +               bootargs = "root=/dev/ram rw init=/init initrd=0x82000000,0x000E2246";
> +               stdout-path = "/serial at 78b0000:115200";

I suggest adding an alias to the serial node, so you can just use the
alias name instead of the path (also I never tried using an actual
path, but wouldn't it be "/soc/serial at 78b0000"?).

> +       };
> +
> +       soc {
> +               serial at 78b0000 {
> +                       status = "ok";
> +               };
> +       };
> +};
> diff --git a/arch/arm/boot/dts/qcom-ipq4019.dtsi b/arch/arm/boot/dts/qcom-ipq4019.dtsi
> new file mode 100644
> index 0000000..1be0322
> --- /dev/null
> +++ b/arch/arm/boot/dts/qcom-ipq4019.dtsi
> @@ -0,0 +1,81 @@
> +/*
> + * Copyright (c) 2014, The Linux Foundation. All rights reserved.
> + *
> + * This program is free software; you can redistribute it and/or modify
> + * it under the terms of the GNU General Public License version 2 and
> + * only 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.
> + */
> +
> +/dts-v1/;
> +
> +#include "skeleton.dtsi"
> +
> +/ {
> +       model = "Qualcomm Technologies, Inc. IPQ4019";
> +       compatible = "qcom,ipq4019";
> +       interrupt-parent = <&intc>;
> +
> +       cpus {
> +               #address-cells = <1>;
> +               #size-cells = <0>;
> +               cpu at 0 {
> +                       device_type = "cpu";
> +                       compatible = "arm,cortex-a7";
> +                       reg = <0x0>;
> +               };
> +
> +               cpu at 1 {
> +                       device_type = "cpu";
> +                       compatible = "arm,cortex-a7";
> +                       reg = <0x1>;
> +               };
> +
> +               cpu at 2 {
> +                       device_type = "cpu";
> +                       compatible = "arm,cortex-a7";
> +                       reg = <0x2>;
> +               };
> +
> +               cpu at 3 {
> +                       device_type = "cpu";
> +                       compatible = "arm,cortex-a7";
> +                       reg = <0x3>;
> +               };
> +       };
> +
> +       soc {
> +               #address-cells = <1>;
> +               #size-cells = <1>;
> +               ranges;
> +               compatible = "simple-bus";
> +
> +               intc: interrupt-controller at b000000 {
> +                       compatible = "qcom,msm-qgic2";
> +                       interrupt-controller;
> +                       #interrupt-cells = <3>;
> +                       reg = <0x0b000000 0x1000>,
> +                       <0x0b002000 0x1000>;
> +               };
> +
> +               serial at 78b0000 {
> +                       compatible = "qcom,msm-uartdm-v1.4", "qcom,msm-uartdm";
> +                       reg = <0x78b0000 0x200>;
> +                       interrupts = <0 108 0>;
> +                       status = "disabled";
> +               };

I think it's nice to have the nodes ordered by their (first) registers
address, so maybe consider doing that. This makes it also clear where
new blocks should be added, and if several people try to add blocks
the chance of conflicts is reduced.

> +       };
> +
> +       timer {
> +               compatible = "arm,armv7-timer";
> +               interrupts = <1 2 0xf08>,
> +                            <1 3 0xf08>,
> +                            <1 4 0xf08>,
> +                            <1 1 0xf08>;
> +               clock-frequency = <20833333>;

Assuming ipq4019 is the name of the emulated chip and not a special id
for the emulator, and "IPQ4019 R3PC" is the dts file for the emulator,
you could set the clock-frequency in the board dts instead of forcing
every "real chip" board dts to overwrite/clear it.

> +       };
> +};
> --

regards
Jonas


From ard.biesheuvel at linaro.org  Tue Aug 25 07:51:22 2015
From: ard.biesheuvel at linaro.org (Ard Biesheuvel)
Date: Tue, 25 Aug 2015 16:51:22 +0200
Subject: [PATCH v1 3/3] arm64: dts: add Hi6220 mailbox node
In-Reply-To: <20150825142416.GW10728@bivouac.eciton.net>
References: <20150821184059.GB2000@svinekod>
 <20150824091845.GA28290@leoy-linaro>
 <20150824095144.GA7139@leverpostej>
 <1440411596.3517.12.camel@linaro.org>
 <20150824114903.GT10728@bivouac.eciton.net>
 <1440490427.10987.29.camel@linaro.org>
 <20150825094630.GU10728@bivouac.eciton.net>
 <1440497710.10987.42.camel@linaro.org>
 <20150825104256.GB13471@leverpostej>
 <1440510194.10987.52.camel@linaro.org>
 <20150825142416.GW10728@bivouac.eciton.net>
Message-ID: <CAKv+Gu-b=QvMF++V9UjULRxrGvoz-0ytFLeuLm8Y5sQH4p53Sw@mail.gmail.com>

On 25 August 2015 at 16:24, Leif Lindholm <leif.lindholm at linaro.org> wrote:
> On Tue, Aug 25, 2015 at 09:43:14PM +0800, Haojian Zhuang wrote:
>> Since we discussed a lot on this, let's make a conclusion on it.
>>
>> 1. UEFI could append the reserved buffer in it's memory mapping.
>
> Yes. It needs to.
>
> (I will let Mark comment on points 2-4.)
>
>> 5. A patch is necessary in kernel. If efi stub feature is enabled,
>>    arm kernel should not parse memory node or reserved memory buffer in
>>    DT any more.
>
> This is already the case. The stub deletes any present memory nodes and
> reserved entries in drivers/firmware/efi/libstub/fdt.c:update_fdt().
>
> Then, during setup_arch(), arch/arm64/kernel/efi.c:efi_init() calls
> reserve_regions(), which adds only those memory regions available for
> use by Linux as RAM to memblock.
>
>>    Arm kernel should either fetch memory information from
>>    efi or DT.
>
> Absolutely.
>
>>    Currently arm kernel fetch both efi memory information and
>>    reserved buffer from DTB at the same time.
>
> No, it does not.
>

It should not, but it does. Due to an oversight, the stub removes
/memreserve/ entries but ignores the reserved-memory node completely.

This was reported here in fact

http://thread.gmane.org/gmane.linux.kernel.efi/5736/focus=5742

but there has not been a followup to this series.

I think it is fine to keep those memory reservations in the DT, but
you should simply understand that UEFI does not parse the DT, so you
need to tell it which memory it cannot touch. Otherwise, the firmware
itself or anything that executes under it (UEFI drivers, the UEFI
Shell, GRUB, the UEFI stub in the kernel) will think it is available
and may allocate it for its own use. This may include runtime services
regions that will remain reserved even after exiting boot services.

-- 
Ard.


From Shenwei.Wang at freescale.com  Tue Aug 25 07:54:41 2015
From: Shenwei.Wang at freescale.com (Shenwei Wang)
Date: Tue, 25 Aug 2015 14:54:41 +0000
Subject: [PATCH v9 1/1] irqchip: imx-gpcv2: IMX GPCv2 driver for wakeup
 sources
In-Reply-To: <55DC7FA4.7040902@arm.com>
References: <1440443055-7291-1-git-send-email-shenwei.wang@freescale.com>
 <55DC3452.3070205@arm.com>
 <CY1PR0301MB08439B6C5F841AFFD152DFD883610@CY1PR0301MB0843.namprd03.prod.outlook.com>
 <55DC738D.8000302@arm.com>
 <CY1PR0301MB0843AE566996617D855CC00683610@CY1PR0301MB0843.namprd03.prod.outlook.com>
 <55DC7FA4.7040902@arm.com>
Message-ID: <CY1PR0301MB08433A2659C75028821F0AE783610@CY1PR0301MB0843.namprd03.prod.outlook.com>



> -----Original Message-----
> From: Sudeep Holla [mailto:sudeep.holla at arm.com]
> Sent: 2015?8?25? 9:46
> To: Wang Shenwei-B38339
> Cc: Sudeep Holla; shawn.guo at linaro.org; tglx at linutronix.de;
> jason at lakedaemon.net; Huang Yongcai-B20788; linux-kernel at vger.kernel.org;
> linux-arm-kernel at lists.infradead.org
> Subject: Re: [PATCH v9 1/1] irqchip: imx-gpcv2: IMX GPCv2 driver for wakeup
> sources
> 
> 
> 
> On 25/08/15 15:14, Shenwei Wang wrote:
> >
> >
> >> -----Original Message-----
> >> From: Sudeep Holla [mailto:sudeep.holla at arm.com]
> 
> [...]
> 
> >> I don't see this driver doing anything extra apart from keeping the
> >> wakeup irqs enabled. i.e. You use the same cpu*wake register to
> >> mask/unmask the interrupt as well as set the wakeup source. Since the
> >> wakeup interrupt will be enabled by the driver, you just need to mark
> >> it as wake-up source and nothing extra in the controller right ?
> >> If so, you need to set IRQCHIP_SKIP_SET_WAKE as you are just leaving
> >> that irq enabled and not doing any extra configuration to enable it as wakeup
> source.
> >> Please correct if that wrong, but from the code that's what I could infer.
> >
> > There is no special for this driver. We just use the IRQCHIP driver
> > framework to manage the wakeup sources. Why did you propose to set
> > IRQCHIP_SKIP_SET_WAKE flag here? If you don't need the wakeup feature,
> > you should just not enable this driver in the configuration.
> >
> 
> No, if the driver doesn't nothing extra to configure the wake up source other than
> keeping it enabled, then it fits the case of SKIP_SET_WAKE.
> The driver using this wake would have requested and enabled the irq.
> When it calls enable_irq_wake, you have nothing extra to set(atleast from the
> looks of the driver), so setting SKIP_SET_WAKE will skip the call and updated the
> wake flags in irq core.
> 
> I don't see the real need of 2 separate sets of irq mask being saved in either case.

You don't really understand what happens after a driver calls enable_irq_wake. In suspend state, even the interrupt
controller itself is powered off. How can you get the system up again by just using a SKIP_SET_WAKE.

Regards,
Shenwei

> Regards,
> Sudeep

From nicolas.pitre at linaro.org  Tue Aug 25 08:01:32 2015
From: nicolas.pitre at linaro.org (Nicolas Pitre)
Date: Tue, 25 Aug 2015 08:01:32 -0700 (PDT)
Subject: [RFC] arm: change some function and data to init section
In-Reply-To: <1440488173-28825-1-git-send-email-yalin.wang2010@gmail.com>
References: <1440488173-28825-1-git-send-email-yalin.wang2010@gmail.com>
Message-ID: <alpine.LFD.2.20.1508250800090.21591@knanqh.ubzr>

On Tue, 25 Aug 2015, yalin wang wrote:

> This patch change some function and the related data to init section,
> they are only called by free_initmem(), can be freed safely after
> boot up.

The magic keyword here is __init_refok.

> Signed-off-by: yalin wang <yalin.wang2010 at gmail.com>

Acked-by: Nicolas Pitre <nico at linaro.org>


> ---
>  arch/arm/mm/init.c | 12 ++++++------
>  1 file changed, 6 insertions(+), 6 deletions(-)
> 
> diff --git a/arch/arm/mm/init.c b/arch/arm/mm/init.c
> index 8a63b4c..7b505de 100644
> --- a/arch/arm/mm/init.c
> +++ b/arch/arm/mm/init.c
> @@ -577,7 +577,7 @@ struct section_perm {
>  	pmdval_t clear;
>  };
>  
> -static struct section_perm nx_perms[] = {
> +static struct section_perm nx_perms[] __initdata = {
>  	/* Make pages tables, etc before _stext RW (set NX). */
>  	{
>  		.start	= PAGE_OFFSET,
> @@ -680,7 +680,7 @@ static inline bool arch_has_strict_perms(void)
>  	}								\
>  }
>  
> -static inline void fix_kernmem_perms(void)
> +static void __init fix_kernmem_perms(void)
>  {
>  	set_section_perms(nx_perms, prot);
>  }
> @@ -706,7 +706,7 @@ void set_kernel_text_ro(void)
>  static inline void fix_kernmem_perms(void) { }
>  #endif /* CONFIG_ARM_KERNMEM_PERMS */
>  
> -void free_tcmmem(void)
> +static void __init free_tcmmem(void)
>  {
>  #ifdef CONFIG_HAVE_TCM
>  	extern char __tcm_start, __tcm_end;
> @@ -716,7 +716,7 @@ void free_tcmmem(void)
>  #endif
>  }
>  
> -void free_initmem(void)
> +void __init_refok free_initmem(void)
>  {
>  	fix_kernmem_perms();
>  	free_tcmmem();
> @@ -728,9 +728,9 @@ void free_initmem(void)
>  
>  #ifdef CONFIG_BLK_DEV_INITRD
>  
> -static int keep_initrd;
> +static int keep_initrd __initdata;
>  
> -void free_initrd_mem(unsigned long start, unsigned long end)
> +void __init free_initrd_mem(unsigned long start, unsigned long end)
>  {
>  	if (!keep_initrd) {
>  		if (start == initrd_start)
> -- 
> 1.9.1
> 
> --
> To unsubscribe from this list: send the line "unsubscribe linux-kernel" in
> the body of a message to majordomo at vger.kernel.org
> More majordomo info at  http://vger.kernel.org/majordomo-info.html
> Please read the FAQ at  http://www.tux.org/lkml/
> 
> 


From Shenwei.Wang at freescale.com  Tue Aug 25 08:05:36 2015
From: Shenwei.Wang at freescale.com (Shenwei Wang)
Date: Tue, 25 Aug 2015 15:05:36 +0000
Subject: [PATCH v3 1/1] misc: sram: add dev_pm_ops to support module power
 gate
In-Reply-To: <55DC7E5E.5020701@arm.com>
References: <1438272681-29338-1-git-send-email-shenwei.wang@freescale.com>
 <55DC677E.1030004@arm.com>
 <CY1PR0301MB0843D5CB5FFC56991B90EB4283610@CY1PR0301MB0843.namprd03.prod.outlook.com>
 <55DC74CF.7070300@arm.com>
 <CY1PR0301MB084302FA2AA9582A3BA9B50B83610@CY1PR0301MB0843.namprd03.prod.outlook.com>
 <55DC7E5E.5020701@arm.com>
Message-ID: <CY1PR0301MB0843A508122C7FCF3969AF3D83610@CY1PR0301MB0843.namprd03.prod.outlook.com>



> -----Original Message-----
> From: Sudeep Holla [mailto:sudeep.holla at arm.com]
> Sent: 2015?8?25? 9:41
> To: Wang Shenwei-B38339
> Cc: Sudeep Holla; gregkh at linuxfoundation.org; arnd at arndb.de; Huang
> Yongcai-B20788; linux-arm-kernel at lists.infradead.org
> Subject: Re: [PATCH v3 1/1] misc: sram: add dev_pm_ops to support module
> power gate
> >> What I meant is who will be using the SRAM when entering S2R that you
> >> need to save the content. Either the user needs to take care of the
> >> content or just release the pool when not in use. When the sram pool has no
> user, clock can be gated.
> >>
> >> Again can you give details of this use-case.
> >
> > We are not talking about clock gate state. Here we are handling the
> > power gate for this SRAM IP block. Of course, you can ask each driver
> > to save its contents during low power state, but I think the easier
> > way is to save the contents in this sram driver and just leave the drivers who
> use this sram behave as is today.
> >
> 
> I don't like that solution as it's not scalable with SRAM size and saving all the
> content of SRAM just because of few active regions makes no sense to me
> at-least. I prefer leaving it to the users to handle that rather than SRAM driver.

I don't think it is not scalable. The choice should be made by the application.
From the driver side, it should be able to provide the way to retain its contents
during power gate. 

Regards,
Shenwei

> Regards,
> Sudeep

From mchehab at osg.samsung.com  Tue Aug 25 08:12:29 2015
From: mchehab at osg.samsung.com (Mauro Carvalho Chehab)
Date: Tue, 25 Aug 2015 12:12:29 -0300
Subject: [PATCH v7 25/44] [media] replace all occurrences of
 MEDIA_ENT_T_DEVNODE_V4L
In-Reply-To: <55DC7381.9090600@xs4all.nl>
References: <cover.1440359643.git.mchehab@osg.samsung.com>
 <23e2f9440a259e1162e15dba7e6261dbc4c521c6.1440359643.git.mchehab@osg.samsung.com>
 <55DC340C.8030503@xs4all.nl> <20150825083236.37659d22@recife.lan>
 <55DC7381.9090600@xs4all.nl>
Message-ID: <20150825121229.77ddcb60@recife.lan>

Em Tue, 25 Aug 2015 15:54:09 +0200
Hans Verkuil <hverkuil at xs4all.nl> escreveu:

> On 08/25/15 13:32, Mauro Carvalho Chehab wrote:
> > Em Tue, 25 Aug 2015 11:23:24 +0200
> > Hans Verkuil <hverkuil at xs4all.nl> escreveu:
> > 
> >> On 08/23/15 22:17, Mauro Carvalho Chehab wrote:
> >>> Now that interfaces and entities are distinct, it makes no sense
> >>> of keeping something named as MEDIA_ENT_T_DEVNODE.
> >>>
> >>> This change was done with this script:
> >>>
> >>> 	for i in $(git grep -l MEDIA_ENT_T|grep -v uapi/linux/media.h); do sed s,MEDIA_ENT_T_DEVNODE_V4L,MEDIA_ENT_T_V4L2_VIDEO, <$i >a && mv a $i; done
> >>>
> >>> Signed-off-by: Mauro Carvalho Chehab <mchehab at osg.samsung.com>
> >>>
> >>> diff --git a/Documentation/DocBook/media/v4l/media-ioc-enum-entities.xml b/Documentation/DocBook/media/v4l/media-ioc-enum-entities.xml
> >>> index 5872f8bbf774..910243d4edb8 100644
> >>> --- a/Documentation/DocBook/media/v4l/media-ioc-enum-entities.xml
> >>> +++ b/Documentation/DocBook/media/v4l/media-ioc-enum-entities.xml
> >>> @@ -183,7 +183,7 @@
> >>>  	    <entry>Unknown device node</entry>
> >>>  	  </row>
> >>>  	  <row>
> >>> -	    <entry><constant>MEDIA_ENT_T_DEVNODE_V4L</constant></entry>
> >>> +	    <entry><constant>MEDIA_ENT_T_V4L2_VIDEO</constant></entry>
> >>>  	    <entry>V4L video, radio or vbi device node</entry>
> >>>  	  </row>
> >>
> >> OK, this makes no sense and that ties in with my confusion of the previous patch.
> >>
> >> These are not device nodes, in the new scheme these are DMA entities (I know,
> >> naming TDB) that have an associated interface.
> > 
> > Yes. Well, DMA is a bad name. It won't cover USB devices, where the DMA
> > engine is outside the V4L2 drivers, nor it would work for RDS radio data,
> > with may not need any DMA at all on no-USB devices, as the data flows via
> > the I2C bus.
> > 
> >> I think a much better approach would be to add entity type(s) for such DMA
> >> engines in patch 24, then use that new name in existing drivers and split
> >> up the existing DEVNODE_V4L media_entity into a media_entity and a
> >> media_intf_devnode:
> > 
> > Sorry, but I didn't get. That's precisely what I did ;)
> > 
> >> The current media_entity defined in struct video_device has to be replaced
> >> by media_intf_devnode, and the DMA entity has to be added as a new entity
> >> to these drivers.
> > 
> > If I do this way, it would break bisectability. I need first to replace
> > the names, but keep them as entities, and then add the interfaces.
> > 
> >>
> >> This reflects these two action items from our meeting:
> >>
> >> Migration: add v4l-subdev media_interface: Laurent
> >> Migration: add explicit DMA Engine entity: Laurent
> >>
> >> Unless Laurent says differently I think this is something you'll have to
> >> do given Laurent's workload.
> > 
> > Yes. The above action items are covered on this series.
> > 
> > What patch 24 does is to define the new namespace, moving the legacy
> > symbols kept due to backward compatibility on a separate part of the
> > header.
> > 
> > Then, patches 25-38 replace the occurrences of the deprecated names
> > by the new ones.
> > 
> > Nothing is touched at the interfaces yet, to avoid breaking bisectability.
> 
> I don't follow why that would break bisect.

It won't break compilation, but it will break runtime.

I mean: if we replace the current occurrences of the
"video output data entities" [1] any userspace app that would be used to test 
somethingwill stop working.

Ok, that means that it would break bisectability for us ;)
Still, better to avoid.

[1] I don't like the "DMA" entities term, as it is too broken.
I prefer to refer to them with some other name, like I/O entities. 
However, even this name is not perfect. Those are, in reality, a
"data interface", while what we call interface is actually a 
"control interface", but calling like that would be confusing, I think.
So, I'll simply call it as "video/vbi/... output data entities".

> 
> > Then, the next patches add interfaces support at the V4L side.
> 
> So this is not yet included in this patch series? That would explain
> my confusion. If it is, then I need to take another look on Friday.

It is on the 3 patches I sent yesterday, after this patch series:
	https://patchwork.linuxtv.org/patch/31081/
	https://patchwork.linuxtv.org/patch/31082/
	https://patchwork.linuxtv.org/patch/31083/

Please notice that the above patch series is not complete, as
there's something non-trivial to be addressed on non-subdev
V4L2 interfaces: how to create the indirect links.

By indirect links, I meant to refer to the interface links that
don't control an entity directly, but via the internal hardware
control/I2C bus(es).

So, a video interface, on a PC customer's hardware controls not only
the video output data entity, but it also indirectly controls the
tuner and the analog demod. Or, on a webcam hardware, it will also
controls the sensor.

However, on platform drivers, it controls just the
"video output data entity" that is directly associated with it via 
its device node.

We need to add some support to automatically create those links,
once available, but only if the device is a PC customer's hardware.

Btw, that's another reason to postpone it: creating the interfaces
offer this additional challenge, while creating the entities are
easy, as nothing changes there.

Regards,
Mauro


From hverkuil at xs4all.nl  Tue Aug 25 08:22:34 2015
From: hverkuil at xs4all.nl (Hans Verkuil)
Date: Tue, 25 Aug 2015 17:22:34 +0200
Subject: [PATCH v7 25/44] [media] replace all occurrences of
 MEDIA_ENT_T_DEVNODE_V4L
In-Reply-To: <20150825121229.77ddcb60@recife.lan>
References: <cover.1440359643.git.mchehab@osg.samsung.com>	<23e2f9440a259e1162e15dba7e6261dbc4c521c6.1440359643.git.mchehab@osg.samsung.com>	<55DC340C.8030503@xs4all.nl>	<20150825083236.37659d22@recife.lan>	<55DC7381.9090600@xs4all.nl>
 <20150825121229.77ddcb60@recife.lan>
Message-ID: <55DC883A.4010103@xs4all.nl>

On 08/25/2015 05:12 PM, Mauro Carvalho Chehab wrote:
> Em Tue, 25 Aug 2015 15:54:09 +0200
> Hans Verkuil <hverkuil at xs4all.nl> escreveu:
> 
>> On 08/25/15 13:32, Mauro Carvalho Chehab wrote:
>>> Em Tue, 25 Aug 2015 11:23:24 +0200
>>> Hans Verkuil <hverkuil at xs4all.nl> escreveu:
>>>
>>>> On 08/23/15 22:17, Mauro Carvalho Chehab wrote:
>>>>> Now that interfaces and entities are distinct, it makes no sense
>>>>> of keeping something named as MEDIA_ENT_T_DEVNODE.
>>>>>
>>>>> This change was done with this script:
>>>>>
>>>>> 	for i in $(git grep -l MEDIA_ENT_T|grep -v uapi/linux/media.h); do sed s,MEDIA_ENT_T_DEVNODE_V4L,MEDIA_ENT_T_V4L2_VIDEO, <$i >a && mv a $i; done
>>>>>
>>>>> Signed-off-by: Mauro Carvalho Chehab <mchehab at osg.samsung.com>
>>>>>
>>>>> diff --git a/Documentation/DocBook/media/v4l/media-ioc-enum-entities.xml b/Documentation/DocBook/media/v4l/media-ioc-enum-entities.xml
>>>>> index 5872f8bbf774..910243d4edb8 100644
>>>>> --- a/Documentation/DocBook/media/v4l/media-ioc-enum-entities.xml
>>>>> +++ b/Documentation/DocBook/media/v4l/media-ioc-enum-entities.xml
>>>>> @@ -183,7 +183,7 @@
>>>>>  	    <entry>Unknown device node</entry>
>>>>>  	  </row>
>>>>>  	  <row>
>>>>> -	    <entry><constant>MEDIA_ENT_T_DEVNODE_V4L</constant></entry>
>>>>> +	    <entry><constant>MEDIA_ENT_T_V4L2_VIDEO</constant></entry>
>>>>>  	    <entry>V4L video, radio or vbi device node</entry>
>>>>>  	  </row>
>>>>
>>>> OK, this makes no sense and that ties in with my confusion of the previous patch.
>>>>
>>>> These are not device nodes, in the new scheme these are DMA entities (I know,
>>>> naming TDB) that have an associated interface.
>>>
>>> Yes. Well, DMA is a bad name. It won't cover USB devices, where the DMA
>>> engine is outside the V4L2 drivers, nor it would work for RDS radio data,
>>> with may not need any DMA at all on no-USB devices, as the data flows via
>>> the I2C bus.
>>>
>>>> I think a much better approach would be to add entity type(s) for such DMA
>>>> engines in patch 24, then use that new name in existing drivers and split
>>>> up the existing DEVNODE_V4L media_entity into a media_entity and a
>>>> media_intf_devnode:
>>>
>>> Sorry, but I didn't get. That's precisely what I did ;)
>>>
>>>> The current media_entity defined in struct video_device has to be replaced
>>>> by media_intf_devnode, and the DMA entity has to be added as a new entity
>>>> to these drivers.
>>>
>>> If I do this way, it would break bisectability. I need first to replace
>>> the names, but keep them as entities, and then add the interfaces.
>>>
>>>>
>>>> This reflects these two action items from our meeting:
>>>>
>>>> Migration: add v4l-subdev media_interface: Laurent
>>>> Migration: add explicit DMA Engine entity: Laurent
>>>>
>>>> Unless Laurent says differently I think this is something you'll have to
>>>> do given Laurent's workload.
>>>
>>> Yes. The above action items are covered on this series.
>>>
>>> What patch 24 does is to define the new namespace, moving the legacy
>>> symbols kept due to backward compatibility on a separate part of the
>>> header.
>>>
>>> Then, patches 25-38 replace the occurrences of the deprecated names
>>> by the new ones.
>>>
>>> Nothing is touched at the interfaces yet, to avoid breaking bisectability.
>>
>> I don't follow why that would break bisect.
> 
> It won't break compilation, but it will break runtime.
> 
> I mean: if we replace the current occurrences of the
> "video output data entities" [1] any userspace app that would be used to test 
> somethingwill stop working.
> 
> Ok, that means that it would break bisectability for us ;)
> Still, better to avoid.
> 
> [1] I don't like the "DMA" entities term, as it is too broken.
> I prefer to refer to them with some other name, like I/O entities. 
> However, even this name is not perfect. Those are, in reality, a
> "data interface", while what we call interface is actually a 
> "control interface", but calling like that would be confusing, I think.
> So, I'll simply call it as "video/vbi/... output data entities".
> 
>>
>>> Then, the next patches add interfaces support at the V4L side.
>>
>> So this is not yet included in this patch series? That would explain
>> my confusion. If it is, then I need to take another look on Friday.
> 
> It is on the 3 patches I sent yesterday, after this patch series:
> 	https://patchwork.linuxtv.org/patch/31081/
> 	https://patchwork.linuxtv.org/patch/31082/
> 	https://patchwork.linuxtv.org/patch/31083/
> 

Ah, OK. These are not part of this patch series, so that explains
it. I hadn't gotten around to reviewing these 3.

I'll plan reviewing these on Friday and I'll revisit the patches
I skipped in the 44 part-series with this in mind.

Regards,

	Hans


> Please notice that the above patch series is not complete, as
> there's something non-trivial to be addressed on non-subdev
> V4L2 interfaces: how to create the indirect links.
> 
> By indirect links, I meant to refer to the interface links that
> don't control an entity directly, but via the internal hardware
> control/I2C bus(es).
> 
> So, a video interface, on a PC customer's hardware controls not only
> the video output data entity, but it also indirectly controls the
> tuner and the analog demod. Or, on a webcam hardware, it will also
> controls the sensor.
> 
> However, on platform drivers, it controls just the
> "video output data entity" that is directly associated with it via 
> its device node.
> 
> We need to add some support to automatically create those links,
> once available, but only if the device is a PC customer's hardware.
> 
> Btw, that's another reason to postpone it: creating the interfaces
> offer this additional challenge, while creating the entities are
> easy, as nothing changes there.
> 
> Regards,
> Mauro
> --
> To unsubscribe from this list: send the line "unsubscribe linux-media" in
> the body of a message to majordomo at vger.kernel.org
> More majordomo info at  http://vger.kernel.org/majordomo-info.html
> 



From andre.przywara at arm.com  Tue Aug 25 08:27:12 2015
From: andre.przywara at arm.com (Andre Przywara)
Date: Tue, 25 Aug 2015 16:27:12 +0100
Subject: [PATCH v2 12/15] KVM: arm64: sync LPI configuration and pending
 tables
In-Reply-To: <55CDD7CB.9020103@linaro.org>
References: <1436538111-4294-1-git-send-email-andre.przywara@arm.com>
 <1436538111-4294-13-git-send-email-andre.przywara@arm.com>
 <55CDD7CB.9020103@linaro.org>
Message-ID: <55DC8950.3050306@arm.com>

Hi Eric,

On 14/08/15 12:58, Eric Auger wrote:
> On 07/10/2015 04:21 PM, Andre Przywara wrote:
>> The LPI configuration and pending tables of the GICv3 LPIs are held
>> in tables in (guest) memory. To achieve reasonable performance, we
>> cache this data in our own data structures, so we need to sync those
>> two views from time to time. This behaviour is well described in the
>> GICv3 spec and is also exercised by hardware, so the sync points are
>> well known.
>>
>> Provide functions that read the guest memory and store the
>> information from the configuration and pending tables in the kernel.
>>
>> Signed-off-by: Andre Przywara <andre.przywara at arm.com>
>> ---
> would help to have change log between v1 -> v2 (valid for the whole series)
>>  include/kvm/arm_vgic.h  |   2 +
>>  virt/kvm/arm/its-emul.c | 124 ++++++++++++++++++++++++++++++++++++++++++++++++
>>  virt/kvm/arm/its-emul.h |   3 ++
>>  3 files changed, 129 insertions(+)
>>
>> diff --git a/include/kvm/arm_vgic.h b/include/kvm/arm_vgic.h
>> index 2a67a10..323c33a 100644
>> --- a/include/kvm/arm_vgic.h
>> +++ b/include/kvm/arm_vgic.h
>> @@ -167,6 +167,8 @@ struct vgic_its {
>>  	int			cwriter;
>>  	struct list_head	device_list;
>>  	struct list_head	collection_list;
>> +	/* memory used for buffering guest's memory */
>> +	void			*buffer_page;
>>  };
>>  
>>  struct vgic_dist {
>> diff --git a/virt/kvm/arm/its-emul.c b/virt/kvm/arm/its-emul.c
>> index b9c40d7..05245cb 100644
>> --- a/virt/kvm/arm/its-emul.c
>> +++ b/virt/kvm/arm/its-emul.c
>> @@ -50,6 +50,7 @@ struct its_itte {
>>  	struct its_collection *collection;
>>  	u32 lpi;
>>  	u32 event_id;
>> +	u8 priority;
>>  	bool enabled;
>>  	unsigned long *pending;
>>  };
>> @@ -70,8 +71,124 @@ static struct its_itte *find_itte_by_lpi(struct kvm *kvm, int lpi)
>>  	return NULL;
>>  }
>>  
>> +#define LPI_PROP_ENABLE_BIT(p)	((p) & LPI_PROP_ENABLED)
>> +#define LPI_PROP_PRIORITY(p)	((p) & 0xfc)
>> +
>> +/* stores the priority and enable bit for a given LPI */
>> +static void update_lpi_config(struct kvm *kvm, struct its_itte *itte, u8 prop)
>> +{
>> +	itte->priority = LPI_PROP_PRIORITY(prop);
>> +	itte->enabled  = LPI_PROP_ENABLE_BIT(prop);
>> +}
>> +
>> +#define GIC_LPI_OFFSET 8192
>> +
>> +/* We scan the table in chunks the size of the smallest page size */
> 4kB chunks?

Marc was complaining about this wording, I think. The rationale was that
"4K" is already in the code and thus does not need to be repeated in the
comment, whereas the comment should explain the meaning of the value.

>> +#define CHUNK_SIZE 4096U
>> +
>>  #define BASER_BASE_ADDRESS(x) ((x) & 0xfffffffff000ULL)
>>  
>> +static int nr_idbits_propbase(u64 propbaser)
>> +{
>> +	int nr_idbits = (1U << (propbaser & 0x1f)) + 1;
>> +
>> +	return max(nr_idbits, INTERRUPT_ID_BITS_ITS);
>> +}
>> +
>> +/*
>> + * Scan the whole LPI configuration table and put the LPI configuration
>> + * data in our own data structures. This relies on the LPI being
>> + * mapped before.
>> + */
>> +static bool its_update_lpis_configuration(struct kvm *kvm)
>> +{
>> +	struct vgic_dist *dist = &kvm->arch.vgic;
>> +	u8 *prop = dist->its.buffer_page;
>> +	u32 tsize;
>> +	gpa_t propbase;
>> +	int lpi = GIC_LPI_OFFSET;
>> +	struct its_itte *itte;
>> +	struct its_device *device;
>> +	int ret;
>> +
>> +	propbase = BASER_BASE_ADDRESS(dist->propbaser);
>> +	tsize = nr_idbits_propbase(dist->propbaser);
>> +
>> +	while (tsize > 0) {
>> +		int chunksize = min(tsize, CHUNK_SIZE);
>> +
>> +		ret = kvm_read_guest(kvm, propbase, prop, chunksize);
> I think you still have the spin_lock issue  since if my understanding is
> correct this is called from
> vgic_handle_mmio_access/vcall_range_handler/gic_enable_lpis
> where vgic_handle_mmio_access. Or does it take another path?

Well, it's (also) called on handling the INVALL command, but you are
right that on that enable path the dist lock is held. I reckon that this
init part isn't racy so that shouldn't be a problem (famous last words ;-).
Let me see whether I can find a way to just drop the lock around the
while loop.

Cheers,
Andre.

> 
> Shouldn't we create a new kvm_io_device to avoid holding the dist lock?
> 
> Eric


From stanimir.varbanov at linaro.org  Tue Aug 25 08:37:42 2015
From: stanimir.varbanov at linaro.org (Stanimir Varbanov)
Date: Tue, 25 Aug 2015 18:37:42 +0300
Subject: [PATCH] arm64: dts: qcom: Add RNG device tree node
Message-ID: <1440517062-30313-1-git-send-email-stanimir.varbanov@linaro.org>

Adds rng device tree node for msm8916 SoCs.

Signed-off-by: Stanimir Varbanov <stanimir.varbanov at linaro.org>
---
 arch/arm64/boot/dts/qcom/msm8916.dtsi |    7 +++++++
 1 file changed, 7 insertions(+)

diff --git a/arch/arm64/boot/dts/qcom/msm8916.dtsi b/arch/arm64/boot/dts/qcom/msm8916.dtsi
index 0f49ebd0aa8b..060c6c53ff33 100644
--- a/arch/arm64/boot/dts/qcom/msm8916.dtsi
+++ b/arch/arm64/boot/dts/qcom/msm8916.dtsi
@@ -215,5 +215,12 @@
 			interrupt-controller;
 			#interrupt-cells = <4>;
 		};
+
+		rng at 22000 {
+			compatible = "qcom,prng";
+			reg = <0x00022000 0x200>;
+			clocks = <&gcc GCC_PRNG_AHB_CLK>;
+			clock-names = "core";
+		};
 	};
 };
-- 
1.7.9.5



From leif.lindholm at linaro.org  Tue Aug 25 08:37:54 2015
From: leif.lindholm at linaro.org (Leif Lindholm)
Date: Tue, 25 Aug 2015 16:37:54 +0100
Subject: [PATCH v1 3/3] arm64: dts: add Hi6220 mailbox node
In-Reply-To: <CAKv+Gu-b=QvMF++V9UjULRxrGvoz-0ytFLeuLm8Y5sQH4p53Sw@mail.gmail.com>
References: <20150824095144.GA7139@leverpostej>
 <1440411596.3517.12.camel@linaro.org>
 <20150824114903.GT10728@bivouac.eciton.net>
 <1440490427.10987.29.camel@linaro.org>
 <20150825094630.GU10728@bivouac.eciton.net>
 <1440497710.10987.42.camel@linaro.org>
 <20150825104256.GB13471@leverpostej>
 <1440510194.10987.52.camel@linaro.org>
 <20150825142416.GW10728@bivouac.eciton.net>
 <CAKv+Gu-b=QvMF++V9UjULRxrGvoz-0ytFLeuLm8Y5sQH4p53Sw@mail.gmail.com>
Message-ID: <20150825153754.GY10728@bivouac.eciton.net>

On Tue, Aug 25, 2015 at 04:51:22PM +0200, Ard Biesheuvel wrote:
> >>    Arm kernel should either fetch memory information from
> >>    efi or DT.
> >
> > Absolutely.
> >
> >>    Currently arm kernel fetch both efi memory information and
> >>    reserved buffer from DTB at the same time.
> >
> > No, it does not.
> 
> It should not, but it does. Due to an oversight, the stub removes
> /memreserve/ entries but ignores the reserved-memory node completely.

Urgh.

> This was reported here in fact
> 
> http://thread.gmane.org/gmane.linux.kernel.efi/5736/focus=5742
> 
> but there has not been a followup to this series.

Are all of those patches still relevant, or did some of them go in
already?

Haojian: can you give that patch a spin and see if it does what you
need, combined with adding the reserved areas to the UEFI memory map?

/
    Leif


From linux at arm.linux.org.uk  Tue Aug 25 08:40:27 2015
From: linux at arm.linux.org.uk (Russell King - ARM Linux)
Date: Tue, 25 Aug 2015 16:40:27 +0100
Subject: [PATCH v2 00/10] Prevent list poison values from being mapped by
 userspace processes
Message-ID: <20150825154026.GT7557@n2100.arm.linux.org.uk>

Here's v2 of the uaccess patches, with the comments raised so far
addressed.  As such, it's grown a tad more than the previous set of
patches.

 arch/arm/Kconfig                            | 15 +++++
 arch/arm/include/asm/assembler.h            | 47 ++++++++++++++++
 arch/arm/include/asm/domain.h               | 53 ++++++++++++++----
 arch/arm/include/asm/futex.h                | 19 ++++++-
 arch/arm/include/asm/pgtable-2level-hwdef.h |  1 +
 arch/arm/include/asm/thread_info.h          |  3 -
 arch/arm/include/asm/uaccess.h              | 85 +++++++++++++++++++++++++++--
 arch/arm/kernel/armksyms.c                  |  6 +-
 arch/arm/kernel/entry-armv.S                | 32 ++++++++---
 arch/arm/kernel/entry-common.S              |  2 +
 arch/arm/kernel/entry-header.S              |  5 ++
 arch/arm/kernel/head.S                      |  5 +-
 arch/arm/kernel/process.c                   | 37 ++++++++++---
 arch/arm/kernel/traps.c                     |  1 -
 arch/arm/lib/clear_user.S                   |  6 +-
 arch/arm/lib/copy_from_user.S               |  6 +-
 arch/arm/lib/copy_to_user.S                 |  6 +-
 arch/arm/lib/csumpartialcopyuser.S          | 14 +++++
 arch/arm/lib/uaccess_with_memcpy.c          |  4 +-
 arch/arm/mm/abort-ev4.S                     |  1 +
 arch/arm/mm/abort-ev5t.S                    |  4 +-
 arch/arm/mm/abort-ev5tj.S                   |  4 +-
 arch/arm/mm/abort-ev6.S                     |  8 ++-
 arch/arm/mm/abort-ev7.S                     |  1 +
 arch/arm/mm/abort-lv4t.S                    |  2 +
 arch/arm/mm/abort-macro.S                   | 14 ++---
 arch/arm/mm/mmu.c                           |  4 +-
 arch/arm/mm/pgd.c                           | 10 ++++
 28 files changed, 324 insertions(+), 71 deletions(-)

-- 
FTTC broadband for 0.8mile line: currently at 10.5Mbps down 400kbps up
according to speedtest.net.


From rmk+kernel at arm.linux.org.uk  Tue Aug 25 08:41:37 2015
From: rmk+kernel at arm.linux.org.uk (Russell King)
Date: Tue, 25 Aug 2015 16:41:37 +0100
Subject: [PATCH v2 04/10] ARM: domains: get rid of manager mode for user domain
In-Reply-To: <20150825154026.GT7557@n2100.arm.linux.org.uk>
References: <20150825154026.GT7557@n2100.arm.linux.org.uk>
Message-ID: <E1ZUGLx-00080h-EP@rmk-PC.arm.linux.org.uk>

Since we switched to early trap initialisation in 94e5a85b3be0
("ARM: earlier initialization of vectors page") we haven't been writing
directly to the vectors page, and so there's no need for this domain
to be in manager mode.  Switch it to client mode.

Signed-off-by: Russell King <rmk+kernel at arm.linux.org.uk>
---
 arch/arm/include/asm/domain.h | 2 +-
 arch/arm/kernel/traps.c       | 1 -
 2 files changed, 1 insertion(+), 2 deletions(-)

diff --git a/arch/arm/include/asm/domain.h b/arch/arm/include/asm/domain.h
index 4218f88e8f7e..08b601e69ddc 100644
--- a/arch/arm/include/asm/domain.h
+++ b/arch/arm/include/asm/domain.h
@@ -59,7 +59,7 @@
 #define domain_val(dom,type)	((type) << (2 * (dom)))
 
 #define DACR_INIT \
-	(domain_val(DOMAIN_USER, DOMAIN_MANAGER) | \
+	(domain_val(DOMAIN_USER, DOMAIN_CLIENT) | \
 	 domain_val(DOMAIN_KERNEL, DOMAIN_MANAGER) | \
 	 domain_val(DOMAIN_TABLE, DOMAIN_MANAGER) | \
 	 domain_val(DOMAIN_IO, DOMAIN_CLIENT))
diff --git a/arch/arm/kernel/traps.c b/arch/arm/kernel/traps.c
index d358226236f2..969f9d9e665f 100644
--- a/arch/arm/kernel/traps.c
+++ b/arch/arm/kernel/traps.c
@@ -870,7 +870,6 @@ void __init early_trap_init(void *vectors_base)
 	kuser_init(vectors_base);
 
 	flush_icache_range(vectors, vectors + PAGE_SIZE * 2);
-	modify_domain(DOMAIN_USER, DOMAIN_CLIENT);
 #else /* ifndef CONFIG_CPU_V7M */
 	/*
 	 * on V7-M there is no need to copy the vector table to a dedicated
-- 
2.1.0



From rmk+kernel at arm.linux.org.uk  Tue Aug 25 08:41:42 2015
From: rmk+kernel at arm.linux.org.uk (Russell King)
Date: Tue, 25 Aug 2015 16:41:42 +0100
Subject: [PATCH v2 05/10] ARM: domains: keep vectors in separate domain
In-Reply-To: <20150825154026.GT7557@n2100.arm.linux.org.uk>
References: <20150825154026.GT7557@n2100.arm.linux.org.uk>
Message-ID: <E1ZUGM2-0008FF-Jm@rmk-PC.arm.linux.org.uk>

Keep the machine vectors in its own domain to avoid software based
user access control from making the vector code inaccessible, and
thereby deadlocking the machine.

Signed-off-by: Russell King <rmk+kernel at arm.linux.org.uk>
---
 arch/arm/include/asm/domain.h               |  4 +++-
 arch/arm/include/asm/pgtable-2level-hwdef.h |  1 +
 arch/arm/mm/mmu.c                           |  4 ++--
 arch/arm/mm/pgd.c                           | 10 ++++++++++
 4 files changed, 16 insertions(+), 3 deletions(-)

diff --git a/arch/arm/include/asm/domain.h b/arch/arm/include/asm/domain.h
index 08b601e69ddc..396a12e486fe 100644
--- a/arch/arm/include/asm/domain.h
+++ b/arch/arm/include/asm/domain.h
@@ -43,6 +43,7 @@
 #define DOMAIN_USER	1
 #define DOMAIN_IO	0
 #endif
+#define DOMAIN_VECTORS	3
 
 /*
  * Domain types
@@ -62,7 +63,8 @@
 	(domain_val(DOMAIN_USER, DOMAIN_CLIENT) | \
 	 domain_val(DOMAIN_KERNEL, DOMAIN_MANAGER) | \
 	 domain_val(DOMAIN_TABLE, DOMAIN_MANAGER) | \
-	 domain_val(DOMAIN_IO, DOMAIN_CLIENT))
+	 domain_val(DOMAIN_IO, DOMAIN_CLIENT) | \
+	 domain_val(DOMAIN_VECTORS, DOMAIN_CLIENT))
 
 #ifndef __ASSEMBLY__
 
diff --git a/arch/arm/include/asm/pgtable-2level-hwdef.h b/arch/arm/include/asm/pgtable-2level-hwdef.h
index 5e68278e953e..d0131ee6f6af 100644
--- a/arch/arm/include/asm/pgtable-2level-hwdef.h
+++ b/arch/arm/include/asm/pgtable-2level-hwdef.h
@@ -23,6 +23,7 @@
 #define PMD_PXNTABLE		(_AT(pmdval_t, 1) << 2)     /* v7 */
 #define PMD_BIT4		(_AT(pmdval_t, 1) << 4)
 #define PMD_DOMAIN(x)		(_AT(pmdval_t, (x)) << 5)
+#define PMD_DOMAIN_MASK		PMD_DOMAIN(0x0f)
 #define PMD_PROTECTION		(_AT(pmdval_t, 1) << 9)		/* v5 */
 /*
  *   - section
diff --git a/arch/arm/mm/mmu.c b/arch/arm/mm/mmu.c
index 6ca7d9aa896f..a016de248034 100644
--- a/arch/arm/mm/mmu.c
+++ b/arch/arm/mm/mmu.c
@@ -291,13 +291,13 @@ static struct mem_type mem_types[] = {
 		.prot_pte  = L_PTE_PRESENT | L_PTE_YOUNG | L_PTE_DIRTY |
 				L_PTE_RDONLY,
 		.prot_l1   = PMD_TYPE_TABLE,
-		.domain    = DOMAIN_USER,
+		.domain    = DOMAIN_VECTORS,
 	},
 	[MT_HIGH_VECTORS] = {
 		.prot_pte  = L_PTE_PRESENT | L_PTE_YOUNG | L_PTE_DIRTY |
 				L_PTE_USER | L_PTE_RDONLY,
 		.prot_l1   = PMD_TYPE_TABLE,
-		.domain    = DOMAIN_USER,
+		.domain    = DOMAIN_VECTORS,
 	},
 	[MT_MEMORY_RWX] = {
 		.prot_pte  = L_PTE_PRESENT | L_PTE_YOUNG | L_PTE_DIRTY,
diff --git a/arch/arm/mm/pgd.c b/arch/arm/mm/pgd.c
index a3681f11dd9f..e683db1b90a3 100644
--- a/arch/arm/mm/pgd.c
+++ b/arch/arm/mm/pgd.c
@@ -84,6 +84,16 @@ pgd_t *pgd_alloc(struct mm_struct *mm)
 		if (!new_pte)
 			goto no_pte;
 
+#ifndef CONFIG_ARM_LPAE
+		/*
+		 * Modify the PTE pointer to have the correct domain.  This
+		 * needs to be the vectors domain to avoid the low vectors
+		 * being unmapped.
+		 */
+		pmd_val(*new_pmd) &= ~PMD_DOMAIN_MASK;
+		pmd_val(*new_pmd) |= PMD_DOMAIN(DOMAIN_VECTORS);
+#endif
+
 		init_pud = pud_offset(init_pgd, 0);
 		init_pmd = pmd_offset(init_pud, 0);
 		init_pte = pte_offset_map(init_pmd, 0);
-- 
2.1.0



From rmk+kernel at arm.linux.org.uk  Tue Aug 25 08:41:47 2015
From: rmk+kernel at arm.linux.org.uk (Russell King)
Date: Tue, 25 Aug 2015 16:41:47 +0100
Subject: [PATCH v2 06/10] ARM: domains: remove DOMAIN_TABLE
In-Reply-To: <20150825154026.GT7557@n2100.arm.linux.org.uk>
References: <20150825154026.GT7557@n2100.arm.linux.org.uk>
Message-ID: <E1ZUGM7-0008Li-Nq@rmk-PC.arm.linux.org.uk>

DOMAIN_TABLE is not used; in any case, it aliases to the kernel domain.
Remove this definition.

Signed-off-by: Russell King <rmk+kernel at arm.linux.org.uk>
---
 arch/arm/include/asm/domain.h | 3 ---
 1 file changed, 3 deletions(-)

diff --git a/arch/arm/include/asm/domain.h b/arch/arm/include/asm/domain.h
index 396a12e486fe..2be929549938 100644
--- a/arch/arm/include/asm/domain.h
+++ b/arch/arm/include/asm/domain.h
@@ -34,12 +34,10 @@
  */
 #ifndef CONFIG_IO_36
 #define DOMAIN_KERNEL	0
-#define DOMAIN_TABLE	0
 #define DOMAIN_USER	1
 #define DOMAIN_IO	2
 #else
 #define DOMAIN_KERNEL	2
-#define DOMAIN_TABLE	2
 #define DOMAIN_USER	1
 #define DOMAIN_IO	0
 #endif
@@ -62,7 +60,6 @@
 #define DACR_INIT \
 	(domain_val(DOMAIN_USER, DOMAIN_CLIENT) | \
 	 domain_val(DOMAIN_KERNEL, DOMAIN_MANAGER) | \
-	 domain_val(DOMAIN_TABLE, DOMAIN_MANAGER) | \
 	 domain_val(DOMAIN_IO, DOMAIN_CLIENT) | \
 	 domain_val(DOMAIN_VECTORS, DOMAIN_CLIENT))
 
-- 
2.1.0



From rmk+kernel at arm.linux.org.uk  Tue Aug 25 08:41:52 2015
From: rmk+kernel at arm.linux.org.uk (Russell King)
Date: Tue, 25 Aug 2015 16:41:52 +0100
Subject: [PATCH v2 07/10] ARM: mm: improve do_ldrd_abort macro
In-Reply-To: <20150825154026.GT7557@n2100.arm.linux.org.uk>
References: <20150825154026.GT7557@n2100.arm.linux.org.uk>
Message-ID: <E1ZUGMC-0008Ty-Sg@rmk-PC.arm.linux.org.uk>

Improve the do_ldrd_abort macro code - firstly, it inefficiently checks
for the LDRD encoding by doing a multi-stage test of various bits.  This
can be simplified by generating a mask, bitmasking the instruction and
then comparing the result.

Secondly, we want to be able to test the result rather than branching
to do_DataAbort, so remove the branch at the end and rename the macro
to 'teq_ldrd' to reflect it's new usage.  teq_ldrd macro returns 'eq'
if the instruction was a LDRD.

Signed-off-by: Russell King <rmk+kernel at arm.linux.org.uk>
---
 arch/arm/mm/abort-ev5t.S  |  3 ++-
 arch/arm/mm/abort-ev5tj.S |  3 ++-
 arch/arm/mm/abort-ev6.S   |  3 ++-
 arch/arm/mm/abort-macro.S | 13 +++++--------
 4 files changed, 11 insertions(+), 11 deletions(-)

diff --git a/arch/arm/mm/abort-ev5t.S b/arch/arm/mm/abort-ev5t.S
index a0908d4653a3..c913031b79cc 100644
--- a/arch/arm/mm/abort-ev5t.S
+++ b/arch/arm/mm/abort-ev5t.S
@@ -22,7 +22,8 @@ ENTRY(v5t_early_abort)
 	do_thumb_abort fsr=r1, pc=r4, psr=r5, tmp=r3
 	ldreq	r3, [r4]			@ read aborted ARM instruction
 	bic	r1, r1, #1 << 11		@ clear bits 11 of FSR
-	do_ldrd_abort tmp=ip, insn=r3
+	teq_ldrd tmp=ip, insn=r3		@ insn was LDRD?
+	beq	do_DataAbort			@ yes
 	tst	r3, #1 << 20			@ check write
 	orreq	r1, r1, #1 << 11
 	b	do_DataAbort
diff --git a/arch/arm/mm/abort-ev5tj.S b/arch/arm/mm/abort-ev5tj.S
index 4006b7a61264..1b80d71adb0f 100644
--- a/arch/arm/mm/abort-ev5tj.S
+++ b/arch/arm/mm/abort-ev5tj.S
@@ -24,7 +24,8 @@ ENTRY(v5tj_early_abort)
 	bne	do_DataAbort
 	do_thumb_abort fsr=r1, pc=r4, psr=r5, tmp=r3
 	ldreq	r3, [r4]			@ read aborted ARM instruction
-	do_ldrd_abort tmp=ip, insn=r3
+	teq_ldrd tmp=ip, insn=r3		@ insn was LDRD?
+	beq	do_DataAbort			@ yes
 	tst	r3, #1 << 20			@ L = 0 -> write
 	orreq	r1, r1, #1 << 11		@ yes.
 	b	do_DataAbort
diff --git a/arch/arm/mm/abort-ev6.S b/arch/arm/mm/abort-ev6.S
index 8c48c5c22a33..113704f30e9f 100644
--- a/arch/arm/mm/abort-ev6.S
+++ b/arch/arm/mm/abort-ev6.S
@@ -34,7 +34,8 @@ ENTRY(v6_early_abort)
 	ldr	r3, [r4]			@ read aborted ARM instruction
  ARM_BE8(rev	r3, r3)
 
-	do_ldrd_abort tmp=ip, insn=r3
+	teq_ldrd tmp=ip, insn=r3		@ insn was LDRD?
+	beq	do_DataAbort			@ yes
 	tst	r3, #1 << 20			@ L = 0 -> write
 	orreq	r1, r1, #1 << 11		@ yes.
 #endif
diff --git a/arch/arm/mm/abort-macro.S b/arch/arm/mm/abort-macro.S
index 2cbf68ef0e83..50d6c0a900b1 100644
--- a/arch/arm/mm/abort-macro.S
+++ b/arch/arm/mm/abort-macro.S
@@ -29,12 +29,9 @@ not_thumb:
  *   [7:4] == 1101
  *    [20] == 0
  */
-	.macro	do_ldrd_abort, tmp, insn
-	tst	\insn, #0x0e100000		@ [27:25,20] == 0
-	bne	not_ldrd
-	and	\tmp, \insn, #0x000000f0	@ [7:4] == 1101
-	cmp	\tmp, #0x000000d0
-	beq	do_DataAbort
-not_ldrd:
+	.macro	teq_ldrd, tmp, insn
+	mov	\tmp, #0x0e100000
+	orr	\tmp, #0x000000f0
+	and	\tmp, \insn, \tmp
+	teq	\tmp, #0x000000d0
 	.endm
-
-- 
2.1.0



From rmk+kernel at arm.linux.org.uk  Tue Aug 25 08:41:58 2015
From: rmk+kernel at arm.linux.org.uk (Russell King)
Date: Tue, 25 Aug 2015 16:41:58 +0100
Subject: [PATCH v2 08/10] ARM: uaccess: provide uaccess_save_and_enable() and
 uaccess_restore()
In-Reply-To: <20150825154026.GT7557@n2100.arm.linux.org.uk>
References: <20150825154026.GT7557@n2100.arm.linux.org.uk>
Message-ID: <E1ZUGMI-00005g-0p@rmk-PC.arm.linux.org.uk>

Provide uaccess_save_and_enable() and uaccess_restore() to permit
control of userspace visibility to the kernel, and hook these into
the appropriate places in the kernel where we need to access
userspace.

Signed-off-by: Russell King <rmk+kernel at arm.linux.org.uk>
---
 arch/arm/include/asm/futex.h       | 19 ++++++++--
 arch/arm/include/asm/uaccess.h     | 71 +++++++++++++++++++++++++++++++++++---
 arch/arm/kernel/armksyms.c         |  6 ++--
 arch/arm/lib/clear_user.S          |  6 ++--
 arch/arm/lib/copy_from_user.S      |  6 ++--
 arch/arm/lib/copy_to_user.S        |  6 ++--
 arch/arm/lib/uaccess_with_memcpy.c |  4 +--
 7 files changed, 97 insertions(+), 21 deletions(-)

diff --git a/arch/arm/include/asm/futex.h b/arch/arm/include/asm/futex.h
index 5eed82809d82..6795368ad023 100644
--- a/arch/arm/include/asm/futex.h
+++ b/arch/arm/include/asm/futex.h
@@ -22,8 +22,11 @@
 #ifdef CONFIG_SMP
 
 #define __futex_atomic_op(insn, ret, oldval, tmp, uaddr, oparg)	\
+({								\
+	unsigned int __ua_flags;				\
 	smp_mb();						\
 	prefetchw(uaddr);					\
+	__ua_flags = uaccess_save_and_enable();			\
 	__asm__ __volatile__(					\
 	"1:	ldrex	%1, [%3]\n"				\
 	"	" insn "\n"					\
@@ -34,12 +37,15 @@
 	__futex_atomic_ex_table("%5")				\
 	: "=&r" (ret), "=&r" (oldval), "=&r" (tmp)		\
 	: "r" (uaddr), "r" (oparg), "Ir" (-EFAULT)		\
-	: "cc", "memory")
+	: "cc", "memory");					\
+	uaccess_restore(__ua_flags);				\
+})
 
 static inline int
 futex_atomic_cmpxchg_inatomic(u32 *uval, u32 __user *uaddr,
 			      u32 oldval, u32 newval)
 {
+	unsigned int __ua_flags;
 	int ret;
 	u32 val;
 
@@ -49,6 +55,7 @@ futex_atomic_cmpxchg_inatomic(u32 *uval, u32 __user *uaddr,
 	smp_mb();
 	/* Prefetching cannot fault */
 	prefetchw(uaddr);
+	__ua_flags = uaccess_save_and_enable();
 	__asm__ __volatile__("@futex_atomic_cmpxchg_inatomic\n"
 	"1:	ldrex	%1, [%4]\n"
 	"	teq	%1, %2\n"
@@ -61,6 +68,7 @@ futex_atomic_cmpxchg_inatomic(u32 *uval, u32 __user *uaddr,
 	: "=&r" (ret), "=&r" (val)
 	: "r" (oldval), "r" (newval), "r" (uaddr), "Ir" (-EFAULT)
 	: "cc", "memory");
+	uaccess_restore(__ua_flags);
 	smp_mb();
 
 	*uval = val;
@@ -73,6 +81,8 @@ futex_atomic_cmpxchg_inatomic(u32 *uval, u32 __user *uaddr,
 #include <asm/domain.h>
 
 #define __futex_atomic_op(insn, ret, oldval, tmp, uaddr, oparg)	\
+({								\
+	unsigned int __ua_flags = uaccess_save_and_enable();	\
 	__asm__ __volatile__(					\
 	"1:	" TUSER(ldr) "	%1, [%3]\n"			\
 	"	" insn "\n"					\
@@ -81,12 +91,15 @@ futex_atomic_cmpxchg_inatomic(u32 *uval, u32 __user *uaddr,
 	__futex_atomic_ex_table("%5")				\
 	: "=&r" (ret), "=&r" (oldval), "=&r" (tmp)		\
 	: "r" (uaddr), "r" (oparg), "Ir" (-EFAULT)		\
-	: "cc", "memory")
+	: "cc", "memory");					\
+	uaccess_restore(__ua_flags);				\
+})
 
 static inline int
 futex_atomic_cmpxchg_inatomic(u32 *uval, u32 __user *uaddr,
 			      u32 oldval, u32 newval)
 {
+	unsigned int __ua_flags;
 	int ret = 0;
 	u32 val;
 
@@ -94,6 +107,7 @@ futex_atomic_cmpxchg_inatomic(u32 *uval, u32 __user *uaddr,
 		return -EFAULT;
 
 	preempt_disable();
+	__ua_flags = uaccess_save_and_enable();
 	__asm__ __volatile__("@futex_atomic_cmpxchg_inatomic\n"
 	"1:	" TUSER(ldr) "	%1, [%4]\n"
 	"	teq	%1, %2\n"
@@ -103,6 +117,7 @@ futex_atomic_cmpxchg_inatomic(u32 *uval, u32 __user *uaddr,
 	: "+r" (ret), "=&r" (val)
 	: "r" (oldval), "r" (newval), "r" (uaddr), "Ir" (-EFAULT)
 	: "cc", "memory");
+	uaccess_restore(__ua_flags);
 
 	*uval = val;
 	preempt_enable();
diff --git a/arch/arm/include/asm/uaccess.h b/arch/arm/include/asm/uaccess.h
index 74b17d09ef7a..82880132f941 100644
--- a/arch/arm/include/asm/uaccess.h
+++ b/arch/arm/include/asm/uaccess.h
@@ -50,6 +50,21 @@ struct exception_table_entry
 extern int fixup_exception(struct pt_regs *regs);
 
 /*
+ * These two functions allow hooking accesses to userspace to increase
+ * system integrity by ensuring that the kernel can not inadvertantly
+ * perform such accesses (eg, via list poison values) which could then
+ * be exploited for priviledge escalation.
+ */
+static inline unsigned int uaccess_save_and_enable(void)
+{
+	return 0;
+}
+
+static inline void uaccess_restore(unsigned int flags)
+{
+}
+
+/*
  * These two are intentionally not defined anywhere - if the kernel
  * code generates any references to them, that's a bug.
  */
@@ -165,6 +180,7 @@ extern int __get_user_64t_4(void *);
 		register typeof(x) __r2 asm("r2");			\
 		register unsigned long __l asm("r1") = __limit;		\
 		register int __e asm("r0");				\
+		unsigned int __ua_flags = uaccess_save_and_enable();	\
 		switch (sizeof(*(__p))) {				\
 		case 1:							\
 			if (sizeof((x)) >= 8)				\
@@ -192,6 +208,7 @@ extern int __get_user_64t_4(void *);
 			break;						\
 		default: __e = __get_user_bad(); break;			\
 		}							\
+		uaccess_restore(__ua_flags);				\
 		x = (typeof(*(p))) __r2;				\
 		__e;							\
 	})
@@ -224,6 +241,7 @@ extern int __put_user_8(void *, unsigned long long);
 		register const typeof(*(p)) __user *__p asm("r0") = __tmp_p; \
 		register unsigned long __l asm("r1") = __limit;		\
 		register int __e asm("r0");				\
+		unsigned int __ua_flags = uaccess_save_and_enable();	\
 		switch (sizeof(*(__p))) {				\
 		case 1:							\
 			__put_user_x(__r2, __p, __e, __l, 1);		\
@@ -239,6 +257,7 @@ extern int __put_user_8(void *, unsigned long long);
 			break;						\
 		default: __e = __put_user_bad(); break;			\
 		}							\
+		uaccess_restore(__ua_flags);				\
 		__e;							\
 	})
 
@@ -300,14 +319,17 @@ static inline void set_fs(mm_segment_t fs)
 do {									\
 	unsigned long __gu_addr = (unsigned long)(ptr);			\
 	unsigned long __gu_val;						\
+	unsigned int __ua_flags;					\
 	__chk_user_ptr(ptr);						\
 	might_fault();							\
+	__ua_flags = uaccess_save_and_enable();				\
 	switch (sizeof(*(ptr))) {					\
 	case 1:	__get_user_asm_byte(__gu_val, __gu_addr, err);	break;	\
 	case 2:	__get_user_asm_half(__gu_val, __gu_addr, err);	break;	\
 	case 4:	__get_user_asm_word(__gu_val, __gu_addr, err);	break;	\
 	default: (__gu_val) = __get_user_bad();				\
 	}								\
+	uaccess_restore(__ua_flags);					\
 	(x) = (__typeof__(*(ptr)))__gu_val;				\
 } while (0)
 
@@ -381,9 +403,11 @@ do {									\
 #define __put_user_err(x, ptr, err)					\
 do {									\
 	unsigned long __pu_addr = (unsigned long)(ptr);			\
+	unsigned int __ua_flags;					\
 	__typeof__(*(ptr)) __pu_val = (x);				\
 	__chk_user_ptr(ptr);						\
 	might_fault();							\
+	__ua_flags = uaccess_save_and_enable();				\
 	switch (sizeof(*(ptr))) {					\
 	case 1: __put_user_asm_byte(__pu_val, __pu_addr, err);	break;	\
 	case 2: __put_user_asm_half(__pu_val, __pu_addr, err);	break;	\
@@ -391,6 +415,7 @@ do {									\
 	case 8:	__put_user_asm_dword(__pu_val, __pu_addr, err);	break;	\
 	default: __put_user_bad();					\
 	}								\
+	uaccess_restore(__ua_flags);					\
 } while (0)
 
 #define __put_user_asm_byte(x, __pu_addr, err)			\
@@ -474,11 +499,46 @@ do {									\
 
 
 #ifdef CONFIG_MMU
-extern unsigned long __must_check __copy_from_user(void *to, const void __user *from, unsigned long n);
-extern unsigned long __must_check __copy_to_user(void __user *to, const void *from, unsigned long n);
-extern unsigned long __must_check __copy_to_user_std(void __user *to, const void *from, unsigned long n);
-extern unsigned long __must_check __clear_user(void __user *addr, unsigned long n);
-extern unsigned long __must_check __clear_user_std(void __user *addr, unsigned long n);
+extern unsigned long __must_check
+arm_copy_from_user(void *to, const void __user *from, unsigned long n);
+
+static inline unsigned long __must_check
+__copy_from_user(void *to, const void __user *from, unsigned long n)
+{
+	unsigned int __ua_flags = uaccess_save_and_enable();
+	n = arm_copy_from_user(to, from, n);
+	uaccess_restore(__ua_flags);
+	return n;
+}
+
+extern unsigned long __must_check
+arm_copy_to_user(void __user *to, const void *from, unsigned long n);
+extern unsigned long __must_check
+__copy_to_user_std(void __user *to, const void *from, unsigned long n);
+
+static inline unsigned long __must_check
+__copy_to_user(void __user *to, const void *from, unsigned long n)
+{
+	unsigned int __ua_flags = uaccess_save_and_enable();
+	n = arm_copy_to_user(to, from, n);
+	uaccess_restore(__ua_flags);
+	return n;
+}
+
+extern unsigned long __must_check
+arm_clear_user(void __user *addr, unsigned long n);
+extern unsigned long __must_check
+__clear_user_std(void __user *addr, unsigned long n);
+
+static inline unsigned long __must_check
+__clear_user(void __user *addr, unsigned long n)
+{
+	unsigned int __ua_flags = uaccess_save_and_enable();
+	n = arm_clear_user(addr, n);
+	uaccess_restore(__ua_flags);
+	return n;
+}
+
 #else
 #define __copy_from_user(to, from, n)	(memcpy(to, (void __force *)from, n), 0)
 #define __copy_to_user(to, from, n)	(memcpy((void __force *)to, from, n), 0)
@@ -511,6 +571,7 @@ static inline unsigned long __must_check clear_user(void __user *to, unsigned lo
 	return n;
 }
 
+/* These are from lib/ code, and use __get_user() and friends */
 extern long strncpy_from_user(char *dest, const char __user *src, long count);
 
 extern __must_check long strlen_user(const char __user *str);
diff --git a/arch/arm/kernel/armksyms.c b/arch/arm/kernel/armksyms.c
index a88671cfe1ff..a35d72d30b56 100644
--- a/arch/arm/kernel/armksyms.c
+++ b/arch/arm/kernel/armksyms.c
@@ -91,9 +91,9 @@ EXPORT_SYMBOL(__memzero);
 #ifdef CONFIG_MMU
 EXPORT_SYMBOL(copy_page);
 
-EXPORT_SYMBOL(__copy_from_user);
-EXPORT_SYMBOL(__copy_to_user);
-EXPORT_SYMBOL(__clear_user);
+EXPORT_SYMBOL(arm_copy_from_user);
+EXPORT_SYMBOL(arm_copy_to_user);
+EXPORT_SYMBOL(arm_clear_user);
 
 EXPORT_SYMBOL(__get_user_1);
 EXPORT_SYMBOL(__get_user_2);
diff --git a/arch/arm/lib/clear_user.S b/arch/arm/lib/clear_user.S
index 1710fd7db2d5..970d6c043774 100644
--- a/arch/arm/lib/clear_user.S
+++ b/arch/arm/lib/clear_user.S
@@ -12,14 +12,14 @@
 
 		.text
 
-/* Prototype: int __clear_user(void *addr, size_t sz)
+/* Prototype: unsigned long arm_clear_user(void *addr, size_t sz)
  * Purpose  : clear some user memory
  * Params   : addr - user memory address to clear
  *          : sz   - number of bytes to clear
  * Returns  : number of bytes NOT cleared
  */
 ENTRY(__clear_user_std)
-WEAK(__clear_user)
+WEAK(arm_clear_user)
 		stmfd	sp!, {r1, lr}
 		mov	r2, #0
 		cmp	r1, #4
@@ -44,7 +44,7 @@ WEAK(__clear_user)
 USER(		strnebt	r2, [r0])
 		mov	r0, #0
 		ldmfd	sp!, {r1, pc}
-ENDPROC(__clear_user)
+ENDPROC(arm_clear_user)
 ENDPROC(__clear_user_std)
 
 		.pushsection .text.fixup,"ax"
diff --git a/arch/arm/lib/copy_from_user.S b/arch/arm/lib/copy_from_user.S
index 7a235b9952be..1512bebfbf1b 100644
--- a/arch/arm/lib/copy_from_user.S
+++ b/arch/arm/lib/copy_from_user.S
@@ -17,7 +17,7 @@
 /*
  * Prototype:
  *
- *	size_t __copy_from_user(void *to, const void *from, size_t n)
+ *	size_t arm_copy_from_user(void *to, const void *from, size_t n)
  *
  * Purpose:
  *
@@ -89,11 +89,11 @@
 
 	.text
 
-ENTRY(__copy_from_user)
+ENTRY(arm_copy_from_user)
 
 #include "copy_template.S"
 
-ENDPROC(__copy_from_user)
+ENDPROC(arm_copy_from_user)
 
 	.pushsection .fixup,"ax"
 	.align 0
diff --git a/arch/arm/lib/copy_to_user.S b/arch/arm/lib/copy_to_user.S
index 9648b0675a3e..caf5019d8161 100644
--- a/arch/arm/lib/copy_to_user.S
+++ b/arch/arm/lib/copy_to_user.S
@@ -17,7 +17,7 @@
 /*
  * Prototype:
  *
- *	size_t __copy_to_user(void *to, const void *from, size_t n)
+ *	size_t arm_copy_to_user(void *to, const void *from, size_t n)
  *
  * Purpose:
  *
@@ -93,11 +93,11 @@
 	.text
 
 ENTRY(__copy_to_user_std)
-WEAK(__copy_to_user)
+WEAK(arm_copy_to_user)
 
 #include "copy_template.S"
 
-ENDPROC(__copy_to_user)
+ENDPROC(arm_copy_to_user)
 ENDPROC(__copy_to_user_std)
 
 	.pushsection .text.fixup,"ax"
diff --git a/arch/arm/lib/uaccess_with_memcpy.c b/arch/arm/lib/uaccess_with_memcpy.c
index 3e58d710013c..77f020e75ccd 100644
--- a/arch/arm/lib/uaccess_with_memcpy.c
+++ b/arch/arm/lib/uaccess_with_memcpy.c
@@ -136,7 +136,7 @@ __copy_to_user_memcpy(void __user *to, const void *from, unsigned long n)
 }
 
 unsigned long
-__copy_to_user(void __user *to, const void *from, unsigned long n)
+arm_copy_to_user(void __user *to, const void *from, unsigned long n)
 {
 	/*
 	 * This test is stubbed out of the main function above to keep
@@ -190,7 +190,7 @@ __clear_user_memset(void __user *addr, unsigned long n)
 	return n;
 }
 
-unsigned long __clear_user(void __user *addr, unsigned long n)
+unsigned long arm_clear_user(void __user *addr, unsigned long n)
 {
 	/* See rational for this in __copy_to_user() above. */
 	if (n < 64)
-- 
2.1.0



From rmk+kernel at arm.linux.org.uk  Tue Aug 25 08:42:03 2015
From: rmk+kernel at arm.linux.org.uk (Russell King)
Date: Tue, 25 Aug 2015 16:42:03 +0100
Subject: [PATCH v2 09/10] ARM: entry: provide uaccess assembly macro hooks
In-Reply-To: <20150825154026.GT7557@n2100.arm.linux.org.uk>
References: <20150825154026.GT7557@n2100.arm.linux.org.uk>
Message-ID: <E1ZUGMN-00007p-4V@rmk-PC.arm.linux.org.uk>

Provide hooks into the kernel entry and exit paths to permit control
of userspace visibility to the kernel.  The intended use is:

- on entry to kernel from user, uaccess_disable will be called to
  disable userspace visibility
- on exit from kernel to user, uaccess_enable will be called to
  enable userspace visibility
- on entry from a kernel exception, uaccess_save_and_disable will be
  called to save the current userspace visibility setting, and disable
  access
- on exit from a kernel exception, uaccess_restore will be called to
  restore the userspace visibility as it was before the exception
  occurred.

These hooks allows us to keep userspace visibility disabled for the
vast majority of the kernel, except for localised regions where we
want to explicitly access userspace.

Signed-off-by: Russell King <rmk+kernel at arm.linux.org.uk>
---
 arch/arm/include/asm/assembler.h | 17 +++++++++++++++++
 arch/arm/kernel/entry-armv.S     | 30 ++++++++++++++++++++++--------
 arch/arm/kernel/entry-common.S   |  2 ++
 arch/arm/kernel/entry-header.S   |  5 +++++
 arch/arm/mm/abort-ev4.S          |  1 +
 arch/arm/mm/abort-ev5t.S         |  1 +
 arch/arm/mm/abort-ev5tj.S        |  1 +
 arch/arm/mm/abort-ev6.S          |  7 ++++---
 arch/arm/mm/abort-ev7.S          |  1 +
 arch/arm/mm/abort-lv4t.S         |  2 ++
 arch/arm/mm/abort-macro.S        |  1 +
 11 files changed, 57 insertions(+), 11 deletions(-)

diff --git a/arch/arm/include/asm/assembler.h b/arch/arm/include/asm/assembler.h
index 4abe57279c66..a91177043467 100644
--- a/arch/arm/include/asm/assembler.h
+++ b/arch/arm/include/asm/assembler.h
@@ -445,6 +445,23 @@ THUMB(	orr	\reg , \reg , #PSR_T_BIT	)
 #endif
 	.endm
 
+	.macro	uaccess_disable, tmp, isb=1
+	.endm
+
+	.macro	uaccess_enable, tmp, isb=1
+	.endm
+
+	.macro	uaccess_save, tmp
+	.endm
+
+	.macro	uaccess_restore
+	.endm
+
+	.macro	uaccess_save_and_disable, tmp
+	uaccess_save \tmp
+	uaccess_disable \tmp
+	.endm
+
 	.irp	c,,eq,ne,cs,cc,mi,pl,vs,vc,hi,ls,ge,lt,gt,le,hs,lo
 	.macro	ret\c, reg
 #if __LINUX_ARM_ARCH__ < 6
diff --git a/arch/arm/kernel/entry-armv.S b/arch/arm/kernel/entry-armv.S
index d19adcf6c580..61f00a3f3047 100644
--- a/arch/arm/kernel/entry-armv.S
+++ b/arch/arm/kernel/entry-armv.S
@@ -149,10 +149,10 @@ ENDPROC(__und_invalid)
 #define SPFIX(code...)
 #endif
 
-	.macro	svc_entry, stack_hole=0, trace=1
+	.macro	svc_entry, stack_hole=0, trace=1, uaccess=1
  UNWIND(.fnstart		)
  UNWIND(.save {r0 - pc}		)
-	sub	sp, sp, #(S_FRAME_SIZE + \stack_hole - 4)
+	sub	sp, sp, #(S_FRAME_SIZE + 8 + \stack_hole - 4)
 #ifdef CONFIG_THUMB2_KERNEL
  SPFIX(	str	r0, [sp]	)	@ temporarily saved
  SPFIX(	mov	r0, sp		)
@@ -167,7 +167,7 @@ ENDPROC(__und_invalid)
 	ldmia	r0, {r3 - r5}
 	add	r7, sp, #S_SP - 4	@ here for interlock avoidance
 	mov	r6, #-1			@  ""  ""      ""       ""
-	add	r2, sp, #(S_FRAME_SIZE + \stack_hole - 4)
+	add	r2, sp, #(S_FRAME_SIZE + 8 + \stack_hole - 4)
  SPFIX(	addeq	r2, r2, #4	)
 	str	r3, [sp, #-4]!		@ save the "real" r0 copied
 					@ from the exception stack
@@ -185,6 +185,11 @@ ENDPROC(__und_invalid)
 	@
 	stmia	r7, {r2 - r6}
 
+	uaccess_save r0
+	.if \uaccess
+	uaccess_disable r0
+	.endif
+
 	.if \trace
 #ifdef CONFIG_TRACE_IRQFLAGS
 	bl	trace_hardirqs_off
@@ -194,7 +199,7 @@ ENDPROC(__und_invalid)
 
 	.align	5
 __dabt_svc:
-	svc_entry
+	svc_entry uaccess=0
 	mov	r2, sp
 	dabt_helper
  THUMB(	ldr	r5, [sp, #S_PSR]	)	@ potentially updated CPSR
@@ -368,7 +373,7 @@ ENDPROC(__fiq_abt)
 #error "sizeof(struct pt_regs) must be a multiple of 8"
 #endif
 
-	.macro	usr_entry, trace=1
+	.macro	usr_entry, trace=1, uaccess=1
  UNWIND(.fnstart	)
  UNWIND(.cantunwind	)	@ don't unwind the user space
 	sub	sp, sp, #S_FRAME_SIZE
@@ -400,6 +405,10 @@ ENDPROC(__fiq_abt)
  ARM(	stmdb	r0, {sp, lr}^			)
  THUMB(	store_user_sp_lr r0, r1, S_SP - S_PC	)
 
+	.if \uaccess
+	uaccess_disable ip
+	.endif
+
 	@ Enable the alignment trap while in kernel mode
  ATRAP(	teq	r8, r7)
  ATRAP( mcrne	p15, 0, r8, c1, c0, 0)
@@ -435,7 +444,7 @@ ENDPROC(__fiq_abt)
 
 	.align	5
 __dabt_usr:
-	usr_entry
+	usr_entry uaccess=0
 	kuser_cmpxchg_check
 	mov	r2, sp
 	dabt_helper
@@ -458,7 +467,7 @@ ENDPROC(__irq_usr)
 
 	.align	5
 __und_usr:
-	usr_entry
+	usr_entry uaccess=0
 
 	mov	r2, r4
 	mov	r3, r5
@@ -484,6 +493,8 @@ __und_usr:
 1:	ldrt	r0, [r4]
  ARM_BE8(rev	r0, r0)				@ little endian instruction
 
+	uaccess_disable ip
+
 	@ r0 = 32-bit ARM instruction which caused the exception
 	@ r2 = PC value for the following instruction (:= regs->ARM_pc)
 	@ r4 = PC value for the faulting instruction
@@ -518,9 +529,10 @@ __und_usr_thumb:
 2:	ldrht	r5, [r4]
 ARM_BE8(rev16	r5, r5)				@ little endian instruction
 	cmp	r5, #0xe800			@ 32bit instruction if xx != 0
-	blo	__und_usr_fault_16		@ 16bit undefined instruction
+	blo	__und_usr_fault_16_pan		@ 16bit undefined instruction
 3:	ldrht	r0, [r2]
 ARM_BE8(rev16	r0, r0)				@ little endian instruction
+	uaccess_disable ip
 	add	r2, r2, #2			@ r2 is PC + 2, make it PC + 4
 	str	r2, [sp, #S_PC]			@ it's a 2x16bit instr, update
 	orr	r0, r0, r5, lsl #16
@@ -715,6 +727,8 @@ ENDPROC(no_fp)
 __und_usr_fault_32:
 	mov	r1, #4
 	b	1f
+__und_usr_fault_16_pan:
+	uaccess_disable ip
 __und_usr_fault_16:
 	mov	r1, #2
 1:	mov	r0, sp
diff --git a/arch/arm/kernel/entry-common.S b/arch/arm/kernel/entry-common.S
index 92828a1dec80..189154980703 100644
--- a/arch/arm/kernel/entry-common.S
+++ b/arch/arm/kernel/entry-common.S
@@ -173,6 +173,8 @@ ENTRY(vector_swi)
  USER(	ldr	scno, [lr, #-4]		)	@ get SWI instruction
 #endif
 
+	uaccess_disable tbl
+
 	adr	tbl, sys_call_table		@ load syscall table pointer
 
 #if defined(CONFIG_OABI_COMPAT)
diff --git a/arch/arm/kernel/entry-header.S b/arch/arm/kernel/entry-header.S
index 1a0045abead7..220ac24900cc 100644
--- a/arch/arm/kernel/entry-header.S
+++ b/arch/arm/kernel/entry-header.S
@@ -215,6 +215,7 @@
 	blne	trace_hardirqs_off
 #endif
 	.endif
+	uaccess_restore
 	msr	spsr_cxsf, \rpsr
 #if defined(CONFIG_CPU_V6) || defined(CONFIG_CPU_32v6K)
 	@ We must avoid clrex due to Cortex-A15 erratum #830321
@@ -241,6 +242,7 @@
 	@ on the stack remains correct).
 	@
 	.macro  svc_exit_via_fiq
+	uaccess_restore
 	mov	r0, sp
 	ldmib	r0, {r1 - r14}	@ abort is deadly from here onward (it will
 				@ clobber state restored below)
@@ -253,6 +255,7 @@
 	.endm
 
 	.macro	restore_user_regs, fast = 0, offset = 0
+	uaccess_enable r1, isb=0
 	mov	r2, sp
 	ldr	r1, [r2, #\offset + S_PSR]	@ get calling cpsr
 	ldr	lr, [r2, #\offset + S_PC]!	@ get pc
@@ -329,6 +332,7 @@
 	 * part of each exception entry and exit sequence.
 	 */
 	.macro	restore_user_regs, fast = 0, offset = 0
+	uaccess_enable r1, isb=0
 	.if	\offset
 	add	sp, #\offset
 	.endif
@@ -336,6 +340,7 @@
 	.endm
 #else	/* ifdef CONFIG_CPU_V7M */
 	.macro	restore_user_regs, fast = 0, offset = 0
+	uaccess_enable r1, isb=0
 	mov	r2, sp
 	load_user_sp_lr r2, r3, \offset + S_SP	@ calling sp, lr
 	ldr	r1, [sp, #\offset + S_PSR]	@ get calling cpsr
diff --git a/arch/arm/mm/abort-ev4.S b/arch/arm/mm/abort-ev4.S
index 54473cd4aba9..b3b31e30cadd 100644
--- a/arch/arm/mm/abort-ev4.S
+++ b/arch/arm/mm/abort-ev4.S
@@ -19,6 +19,7 @@ ENTRY(v4_early_abort)
 	mrc	p15, 0, r1, c5, c0, 0		@ get FSR
 	mrc	p15, 0, r0, c6, c0, 0		@ get FAR
 	ldr	r3, [r4]			@ read aborted ARM instruction
+	uaccess_disable ip			@ disable userspace access
 	bic	r1, r1, #1 << 11 | 1 << 10	@ clear bits 11 and 10 of FSR
 	tst	r3, #1 << 20			@ L = 1 -> write?
 	orreq	r1, r1, #1 << 11		@ yes.
diff --git a/arch/arm/mm/abort-ev5t.S b/arch/arm/mm/abort-ev5t.S
index c913031b79cc..a6a381a6caa5 100644
--- a/arch/arm/mm/abort-ev5t.S
+++ b/arch/arm/mm/abort-ev5t.S
@@ -21,6 +21,7 @@ ENTRY(v5t_early_abort)
 	mrc	p15, 0, r0, c6, c0, 0		@ get FAR
 	do_thumb_abort fsr=r1, pc=r4, psr=r5, tmp=r3
 	ldreq	r3, [r4]			@ read aborted ARM instruction
+	uaccess_disable ip			@ disable user access
 	bic	r1, r1, #1 << 11		@ clear bits 11 of FSR
 	teq_ldrd tmp=ip, insn=r3		@ insn was LDRD?
 	beq	do_DataAbort			@ yes
diff --git a/arch/arm/mm/abort-ev5tj.S b/arch/arm/mm/abort-ev5tj.S
index 1b80d71adb0f..00ab011bef58 100644
--- a/arch/arm/mm/abort-ev5tj.S
+++ b/arch/arm/mm/abort-ev5tj.S
@@ -24,6 +24,7 @@ ENTRY(v5tj_early_abort)
 	bne	do_DataAbort
 	do_thumb_abort fsr=r1, pc=r4, psr=r5, tmp=r3
 	ldreq	r3, [r4]			@ read aborted ARM instruction
+	uaccess_disable ip			@ disable userspace access
 	teq_ldrd tmp=ip, insn=r3		@ insn was LDRD?
 	beq	do_DataAbort			@ yes
 	tst	r3, #1 << 20			@ L = 0 -> write
diff --git a/arch/arm/mm/abort-ev6.S b/arch/arm/mm/abort-ev6.S
index 113704f30e9f..8801a15aa105 100644
--- a/arch/arm/mm/abort-ev6.S
+++ b/arch/arm/mm/abort-ev6.S
@@ -26,17 +26,18 @@ ENTRY(v6_early_abort)
 	ldr	ip, =0x4107b36
 	mrc	p15, 0, r3, c0, c0, 0		@ get processor id
 	teq	ip, r3, lsr #4			@ r0 ARM1136?
-	bne	do_DataAbort
+	bne	1f
 	tst	r5, #PSR_J_BIT			@ Java?
 	tsteq	r5, #PSR_T_BIT			@ Thumb?
-	bne	do_DataAbort
+	bne	1f
 	bic	r1, r1, #1 << 11		@ clear bit 11 of FSR
 	ldr	r3, [r4]			@ read aborted ARM instruction
  ARM_BE8(rev	r3, r3)
 
 	teq_ldrd tmp=ip, insn=r3		@ insn was LDRD?
-	beq	do_DataAbort			@ yes
+	beq	1f				@ yes
 	tst	r3, #1 << 20			@ L = 0 -> write
 	orreq	r1, r1, #1 << 11		@ yes.
 #endif
+1:	uaccess_disable ip			@ disable userspace access
 	b	do_DataAbort
diff --git a/arch/arm/mm/abort-ev7.S b/arch/arm/mm/abort-ev7.S
index 4812ad054214..e8d0e08c227f 100644
--- a/arch/arm/mm/abort-ev7.S
+++ b/arch/arm/mm/abort-ev7.S
@@ -15,6 +15,7 @@
 ENTRY(v7_early_abort)
 	mrc	p15, 0, r1, c5, c0, 0		@ get FSR
 	mrc	p15, 0, r0, c6, c0, 0		@ get FAR
+	uaccess_disable ip			@ disable userspace access
 
 	/*
 	 * V6 code adjusts the returned DFSR.
diff --git a/arch/arm/mm/abort-lv4t.S b/arch/arm/mm/abort-lv4t.S
index f3982580c273..6d8e8e3365d1 100644
--- a/arch/arm/mm/abort-lv4t.S
+++ b/arch/arm/mm/abort-lv4t.S
@@ -26,6 +26,7 @@ ENTRY(v4t_late_abort)
 #endif
 	bne	.data_thumb_abort
 	ldr	r8, [r4]			@ read arm instruction
+	uaccess_disable ip			@ disable userspace access
 	tst	r8, #1 << 20			@ L = 1 -> write?
 	orreq	r1, r1, #1 << 11		@ yes.
 	and	r7, r8, #15 << 24
@@ -155,6 +156,7 @@ ENTRY(v4t_late_abort)
 
 .data_thumb_abort:
 	ldrh	r8, [r4]			@ read instruction
+	uaccess_disable ip			@ disable userspace access
 	tst	r8, #1 << 11			@ L = 1 -> write?
 	orreq	r1, r1, #1 << 8			@ yes
 	and	r7, r8, #15 << 12
diff --git a/arch/arm/mm/abort-macro.S b/arch/arm/mm/abort-macro.S
index 50d6c0a900b1..4509bee4e081 100644
--- a/arch/arm/mm/abort-macro.S
+++ b/arch/arm/mm/abort-macro.S
@@ -13,6 +13,7 @@
 	tst	\psr, #PSR_T_BIT
 	beq	not_thumb
 	ldrh	\tmp, [\pc]			@ Read aborted Thumb instruction
+	uaccess_disable ip			@ disable userspace access
 	and	\tmp, \tmp, # 0xfe00		@ Mask opcode field
 	cmp	\tmp, # 0x5600			@ Is it ldrsb?
 	orreq	\tmp, \tmp, #1 << 11		@ Set L-bit if yes
-- 
2.1.0



From rmk+kernel at arm.linux.org.uk  Tue Aug 25 08:42:08 2015
From: rmk+kernel at arm.linux.org.uk (Russell King)
Date: Tue, 25 Aug 2015 16:42:08 +0100
Subject: [PATCH v2 10/10] ARM: software-based priviledged-no-access support
In-Reply-To: <20150825154026.GT7557@n2100.arm.linux.org.uk>
References: <20150825154026.GT7557@n2100.arm.linux.org.uk>
Message-ID: <E1ZUGMS-0000BG-8B@rmk-PC.arm.linux.org.uk>

Provide a software-based implementation of the priviledged no access
support found in ARMv8.1.

Userspace pages are mapped using a different domain number from the
kernel and IO mappings.  If we switch the user domain to "no access"
when we enter the kernel, we can prevent the kernel from touching
userspace.

However, the kernel needs to be able to access userspace via the
various user accessor functions.  With the wrapping in the previous
patch, we can temporarily enable access when the kernel needs user
access, and re-disable it afterwards.

This allows us to trap non-intended accesses to userspace, eg, caused
by an inadvertent dereference of the LIST_POISON* values, which, with
appropriate user mappings setup, can be made to succeed.  This in turn
can allow use-after-free bugs to be further exploited than would
otherwise be possible.

Signed-off-by: Russell King <rmk+kernel at arm.linux.org.uk>
---
 arch/arm/Kconfig                   | 15 +++++++++++++++
 arch/arm/include/asm/assembler.h   | 30 ++++++++++++++++++++++++++++++
 arch/arm/include/asm/domain.h      | 21 +++++++++++++++++++--
 arch/arm/include/asm/uaccess.h     | 14 ++++++++++++++
 arch/arm/kernel/process.c          | 24 ++++++++++++++++++------
 arch/arm/lib/csumpartialcopyuser.S | 14 ++++++++++++++
 6 files changed, 110 insertions(+), 8 deletions(-)

diff --git a/arch/arm/Kconfig b/arch/arm/Kconfig
index a750c1425c3a..a898eb72da51 100644
--- a/arch/arm/Kconfig
+++ b/arch/arm/Kconfig
@@ -1694,6 +1694,21 @@ config HIGHPTE
 	bool "Allocate 2nd-level pagetables from highmem"
 	depends on HIGHMEM
 
+config CPU_SW_DOMAIN_PAN
+	bool "Enable use of CPU domains to implement priviledged no-access"
+	depends on MMU && !ARM_LPAE
+	default y
+	help
+	  Increase kernel security by ensuring that normal kernel accesses
+	  are unable to access userspace addresses.  This can help prevent
+	  use-after-free bugs becoming an exploitable privilege escalation
+	  by ensuring that magic values (such as LIST_POISON) will always
+	  fault when dereferenced.
+
+	  CPUs with low-vector mappings use a best-efforts implementation.
+	  Their lower 1MB needs to remain accessible for the vectors, but
+	  the remainder of userspace will become appropriately inaccessible.
+
 config HW_PERF_EVENTS
 	bool "Enable hardware performance counter support for perf events"
 	depends on PERF_EVENTS
diff --git a/arch/arm/include/asm/assembler.h b/arch/arm/include/asm/assembler.h
index a91177043467..ff74f0b54b0e 100644
--- a/arch/arm/include/asm/assembler.h
+++ b/arch/arm/include/asm/assembler.h
@@ -446,15 +446,45 @@ THUMB(	orr	\reg , \reg , #PSR_T_BIT	)
 	.endm
 
 	.macro	uaccess_disable, tmp, isb=1
+#ifdef CONFIG_CPU_SW_DOMAIN_PAN
+	/*
+	 * Whenever we re-enter userspace, the domains should always be
+	 * set appropriately.
+	 */
+	mov	\tmp, #DACR_UACCESS_DISABLE
+	mcr	p15, 0, \tmp, c3, c0, 0		@ Set domain register
+	.if	\isb
+	isb
+	.endif
+#endif
 	.endm
 
 	.macro	uaccess_enable, tmp, isb=1
+#ifdef CONFIG_CPU_SW_DOMAIN_PAN
+	/*
+	 * Whenever we re-enter userspace, the domains should always be
+	 * set appropriately.
+	 */
+	mov	\tmp, #DACR_UACCESS_ENABLE
+	mcr	p15, 0, \tmp, c3, c0, 0
+	.if	\isb
+	isb
+	.endif
+#endif
 	.endm
 
 	.macro	uaccess_save, tmp
+#ifdef CONFIG_CPU_SW_DOMAIN_PAN
+	mrc	p15, 0, \tmp, c3, c0, 0
+	str	\tmp, [sp, #S_FRAME_SIZE]
+#endif
 	.endm
 
 	.macro	uaccess_restore
+#ifdef CONFIG_CPU_SW_DOMAIN_PAN
+	ldr	r0, [sp, #S_FRAME_SIZE]
+	mcr	p15, 0, r0, c3, c0, 0
+#endif
 	.endm
 
 	.macro	uaccess_save_and_disable, tmp
diff --git a/arch/arm/include/asm/domain.h b/arch/arm/include/asm/domain.h
index 2be929549938..e878129f2fee 100644
--- a/arch/arm/include/asm/domain.h
+++ b/arch/arm/include/asm/domain.h
@@ -57,11 +57,29 @@
 #define domain_mask(dom)	((3) << (2 * (dom)))
 #define domain_val(dom,type)	((type) << (2 * (dom)))
 
+#ifdef CONFIG_CPU_SW_DOMAIN_PAN
+#define DACR_INIT \
+	(domain_val(DOMAIN_USER, DOMAIN_NOACCESS) | \
+	 domain_val(DOMAIN_KERNEL, DOMAIN_MANAGER) | \
+	 domain_val(DOMAIN_IO, DOMAIN_CLIENT) | \
+	 domain_val(DOMAIN_VECTORS, DOMAIN_CLIENT))
+#else
 #define DACR_INIT \
 	(domain_val(DOMAIN_USER, DOMAIN_CLIENT) | \
 	 domain_val(DOMAIN_KERNEL, DOMAIN_MANAGER) | \
 	 domain_val(DOMAIN_IO, DOMAIN_CLIENT) | \
 	 domain_val(DOMAIN_VECTORS, DOMAIN_CLIENT))
+#endif
+
+#define __DACR_DEFAULT \
+	domain_val(DOMAIN_KERNEL, DOMAIN_CLIENT) | \
+	domain_val(DOMAIN_IO, DOMAIN_CLIENT) | \
+	domain_val(DOMAIN_VECTORS, DOMAIN_CLIENT)
+
+#define DACR_UACCESS_DISABLE	\
+	(__DACR_DEFAULT | domain_val(DOMAIN_USER, DOMAIN_NOACCESS))
+#define DACR_UACCESS_ENABLE	\
+	(__DACR_DEFAULT | domain_val(DOMAIN_USER, DOMAIN_CLIENT))
 
 #ifndef __ASSEMBLY__
 
@@ -76,7 +94,6 @@ static inline unsigned int get_domain(void)
 	return domain;
 }
 
-#ifdef CONFIG_CPU_USE_DOMAINS
 static inline void set_domain(unsigned val)
 {
 	asm volatile(
@@ -85,6 +102,7 @@ static inline void set_domain(unsigned val)
 	isb();
 }
 
+#ifdef CONFIG_CPU_USE_DOMAINS
 #define modify_domain(dom,type)					\
 	do {							\
 		unsigned int domain = get_domain();		\
@@ -94,7 +112,6 @@ static inline void set_domain(unsigned val)
 	} while (0)
 
 #else
-static inline void set_domain(unsigned val) { }
 static inline void modify_domain(unsigned dom, unsigned type)	{ }
 #endif
 
diff --git a/arch/arm/include/asm/uaccess.h b/arch/arm/include/asm/uaccess.h
index 82880132f941..01bae13b2cea 100644
--- a/arch/arm/include/asm/uaccess.h
+++ b/arch/arm/include/asm/uaccess.h
@@ -57,11 +57,25 @@ extern int fixup_exception(struct pt_regs *regs);
  */
 static inline unsigned int uaccess_save_and_enable(void)
 {
+#ifdef CONFIG_CPU_SW_DOMAIN_PAN
+	unsigned int old_domain = get_domain();
+
+	/* Set the current domain access to permit user accesses */
+	set_domain((old_domain & ~domain_mask(DOMAIN_USER)) |
+		   domain_val(DOMAIN_USER, DOMAIN_CLIENT));
+
+	return old_domain;
+#else
 	return 0;
+#endif
 }
 
 static inline void uaccess_restore(unsigned int flags)
 {
+#ifdef CONFIG_CPU_SW_DOMAIN_PAN
+	/* Restore the user access mask */
+	set_domain(flags);
+#endif
 }
 
 /*
diff --git a/arch/arm/kernel/process.c b/arch/arm/kernel/process.c
index e722f9b3c9b1..b407cc7a7b55 100644
--- a/arch/arm/kernel/process.c
+++ b/arch/arm/kernel/process.c
@@ -129,12 +129,24 @@ void __show_regs(struct pt_regs *regs)
 	buf[4] = '\0';
 
 #ifndef CONFIG_CPU_V7M
-	printk("Flags: %s  IRQs o%s  FIQs o%s  Mode %s  ISA %s  Segment %s\n",
-		buf, interrupts_enabled(regs) ? "n" : "ff",
-		fast_interrupts_enabled(regs) ? "n" : "ff",
-		processor_modes[processor_mode(regs)],
-		isa_modes[isa_mode(regs)],
-		get_fs() == get_ds() ? "kernel" : "user");
+	{
+		unsigned int domain = get_domain();
+		const char *segment;
+
+		if ((domain & domain_mask(DOMAIN_USER)) ==
+		    domain_val(DOMAIN_USER, DOMAIN_NOACCESS))
+			segment = "none";
+		else if (get_fs() == get_ds())
+			segment = "kernel";
+		else
+			segment = "user";
+
+		printk("Flags: %s  IRQs o%s  FIQs o%s  Mode %s  ISA %s  Segment %s\n",
+			buf, interrupts_enabled(regs) ? "n" : "ff",
+			fast_interrupts_enabled(regs) ? "n" : "ff",
+			processor_modes[processor_mode(regs)],
+			isa_modes[isa_mode(regs)], segment);
+	}
 #else
 	printk("xPSR: %08lx\n", regs->ARM_cpsr);
 #endif
diff --git a/arch/arm/lib/csumpartialcopyuser.S b/arch/arm/lib/csumpartialcopyuser.S
index 1d0957e61f89..52784f6f1086 100644
--- a/arch/arm/lib/csumpartialcopyuser.S
+++ b/arch/arm/lib/csumpartialcopyuser.S
@@ -17,6 +17,19 @@
 
 		.text
 
+#ifdef CONFIG_CPU_SW_DOMAIN_PAN
+		.macro	save_regs
+		mrc	p15, 0, r3, c3, c0, 0
+		stmfd	sp!, {r1 - r8, lr}
+		uaccess_enable r3
+		.endm
+
+		.macro	load_regs
+		ldmfd	sp!, {r1 - r8, lr}
+		mcr	p15, 0, r3, c3, c0, 0
+		ret	lr
+		.endm
+#else
 		.macro	save_regs
 		stmfd	sp!, {r1, r2, r4 - r8, lr}
 		.endm
@@ -24,6 +37,7 @@
 		.macro	load_regs
 		ldmfd	sp!, {r1, r2, r4 - r8, pc}
 		.endm
+#endif
 
 		.macro	load1b,	reg1
 		ldrusr	\reg1, r0, 1
-- 
2.1.0



From rmk+kernel at arm.linux.org.uk  Tue Aug 25 08:41:21 2015
From: rmk+kernel at arm.linux.org.uk (Russell King)
Date: Tue, 25 Aug 2015 16:41:21 +0100
Subject: [PATCH v2 01/10] ARM: domains: switch to keeping domain value in
 register
In-Reply-To: <20150825154026.GT7557@n2100.arm.linux.org.uk>
References: <20150825154026.GT7557@n2100.arm.linux.org.uk>
Message-ID: <E1ZUGLh-0007n3-Fu@rmk-PC.arm.linux.org.uk>

Rather than modifying both the domain access control register and our
per-thread copy, modify only the domain access control register, and
use the per-thread copy to save and restore the register over context
switches.  We can also avoid the explicit initialisation of the
init thread_info structure.

This allows us to avoid needing to gain access to the thread information
at the uaccess control sites.

Signed-off-by: Russell King <rmk+kernel at arm.linux.org.uk>
---
 arch/arm/include/asm/domain.h      | 20 +++++++++++++++-----
 arch/arm/include/asm/thread_info.h |  3 ---
 arch/arm/kernel/entry-armv.S       |  2 ++
 arch/arm/kernel/process.c          | 13 ++++++++++---
 4 files changed, 27 insertions(+), 11 deletions(-)

diff --git a/arch/arm/include/asm/domain.h b/arch/arm/include/asm/domain.h
index 6ddbe446425e..7f2941905714 100644
--- a/arch/arm/include/asm/domain.h
+++ b/arch/arm/include/asm/domain.h
@@ -59,6 +59,17 @@
 
 #ifndef __ASSEMBLY__
 
+static inline unsigned int get_domain(void)
+{
+	unsigned int domain;
+
+	asm(
+	"mrc	p15, 0, %0, c3, c0	@ get domain"
+	 : "=r" (domain));
+
+	return domain;
+}
+
 #ifdef CONFIG_CPU_USE_DOMAINS
 static inline void set_domain(unsigned val)
 {
@@ -70,11 +81,10 @@ static inline void set_domain(unsigned val)
 
 #define modify_domain(dom,type)					\
 	do {							\
-	struct thread_info *thread = current_thread_info();	\
-	unsigned int domain = thread->cpu_domain;		\
-	domain &= ~domain_val(dom, DOMAIN_MANAGER);		\
-	thread->cpu_domain = domain | domain_val(dom, type);	\
-	set_domain(thread->cpu_domain);				\
+		unsigned int domain = get_domain();		\
+		domain &= ~domain_val(dom, DOMAIN_MANAGER);	\
+		domain = domain | domain_val(dom, type);	\
+		set_domain(domain);				\
 	} while (0)
 
 #else
diff --git a/arch/arm/include/asm/thread_info.h b/arch/arm/include/asm/thread_info.h
index bd32eded3e50..0a0aec410d8c 100644
--- a/arch/arm/include/asm/thread_info.h
+++ b/arch/arm/include/asm/thread_info.h
@@ -74,9 +74,6 @@ struct thread_info {
 	.flags		= 0,						\
 	.preempt_count	= INIT_PREEMPT_COUNT,				\
 	.addr_limit	= KERNEL_DS,					\
-	.cpu_domain	= domain_val(DOMAIN_USER, DOMAIN_MANAGER) |	\
-			  domain_val(DOMAIN_KERNEL, DOMAIN_MANAGER) |	\
-			  domain_val(DOMAIN_IO, DOMAIN_CLIENT),		\
 }
 
 #define init_thread_info	(init_thread_union.thread_info)
diff --git a/arch/arm/kernel/entry-armv.S b/arch/arm/kernel/entry-armv.S
index 7dac3086e361..d19adcf6c580 100644
--- a/arch/arm/kernel/entry-armv.S
+++ b/arch/arm/kernel/entry-armv.S
@@ -770,6 +770,8 @@ ENTRY(__switch_to)
 	ldr	r4, [r2, #TI_TP_VALUE]
 	ldr	r5, [r2, #TI_TP_VALUE + 4]
 #ifdef CONFIG_CPU_USE_DOMAINS
+	mrc	p15, 0, r6, c3, c0, 0		@ Get domain register
+	str	r6, [r1, #TI_CPU_DOMAIN]	@ Save old domain register
 	ldr	r6, [r2, #TI_CPU_DOMAIN]
 #endif
 	switch_tls r1, r4, r5, r3, r7
diff --git a/arch/arm/kernel/process.c b/arch/arm/kernel/process.c
index f192a2a41719..e722f9b3c9b1 100644
--- a/arch/arm/kernel/process.c
+++ b/arch/arm/kernel/process.c
@@ -146,10 +146,9 @@ void __show_regs(struct pt_regs *regs)
 		buf[0] = '\0';
 #ifdef CONFIG_CPU_CP15_MMU
 		{
-			unsigned int transbase, dac;
+			unsigned int transbase, dac = get_domain();
 			asm("mrc p15, 0, %0, c2, c0\n\t"
-			    "mrc p15, 0, %1, c3, c0\n"
-			    : "=r" (transbase), "=r" (dac));
+			    : "=r" (transbase));
 			snprintf(buf, sizeof(buf), "  Table: %08x  DAC: %08x",
 			  	transbase, dac);
 		}
@@ -210,6 +209,14 @@ copy_thread(unsigned long clone_flags, unsigned long stack_start,
 
 	memset(&thread->cpu_context, 0, sizeof(struct cpu_context_save));
 
+	/*
+	 * Copy the initial value of the domain access control register
+	 * from the current thread: thread->addr_limit will have been
+	 * copied from the current thread via setup_thread_stack() in
+	 * kernel/fork.c
+	 */
+	thread->cpu_domain = get_domain();
+
 	if (likely(!(p->flags & PF_KTHREAD))) {
 		*childregs = *current_pt_regs();
 		childregs->ARM_r0 = 0;
-- 
2.1.0



From rmk+kernel at arm.linux.org.uk  Tue Aug 25 08:41:27 2015
From: rmk+kernel at arm.linux.org.uk (Russell King)
Date: Tue, 25 Aug 2015 16:41:27 +0100
Subject: [PATCH v2 02/10] ARM: domains: provide domain_mask()
In-Reply-To: <20150825154026.GT7557@n2100.arm.linux.org.uk>
References: <20150825154026.GT7557@n2100.arm.linux.org.uk>
Message-ID: <E1ZUGLn-0007sZ-1D@rmk-PC.arm.linux.org.uk>

Provide a macro to generate the mask for a domain, rather than using
domain_val(, DOMAIN_MANAGER) which won't work when CPU_USE_DOMAINS
is turned off.

Signed-off-by: Russell King <rmk+kernel at arm.linux.org.uk>
---
 arch/arm/include/asm/domain.h | 5 +++--
 1 file changed, 3 insertions(+), 2 deletions(-)

diff --git a/arch/arm/include/asm/domain.h b/arch/arm/include/asm/domain.h
index 7f2941905714..045b9b453bcd 100644
--- a/arch/arm/include/asm/domain.h
+++ b/arch/arm/include/asm/domain.h
@@ -55,7 +55,8 @@
 #define DOMAIN_MANAGER	1
 #endif
 
-#define domain_val(dom,type)	((type) << (2*(dom)))
+#define domain_mask(dom)	((3) << (2 * (dom)))
+#define domain_val(dom,type)	((type) << (2 * (dom)))
 
 #ifndef __ASSEMBLY__
 
@@ -82,7 +83,7 @@ static inline void set_domain(unsigned val)
 #define modify_domain(dom,type)					\
 	do {							\
 		unsigned int domain = get_domain();		\
-		domain &= ~domain_val(dom, DOMAIN_MANAGER);	\
+		domain &= ~domain_mask(dom);			\
 		domain = domain | domain_val(dom, type);	\
 		set_domain(domain);				\
 	} while (0)
-- 
2.1.0



From rmk+kernel at arm.linux.org.uk  Tue Aug 25 08:41:32 2015
From: rmk+kernel at arm.linux.org.uk (Russell King)
Date: Tue, 25 Aug 2015 16:41:32 +0100
Subject: [PATCH v2 03/10] ARM: domains: move initial domain setting value to
 asm/domains.h
In-Reply-To: <20150825154026.GT7557@n2100.arm.linux.org.uk>
References: <20150825154026.GT7557@n2100.arm.linux.org.uk>
Message-ID: <E1ZUGLs-0007xg-7o@rmk-PC.arm.linux.org.uk>

Signed-off-by: Russell King <rmk+kernel at arm.linux.org.uk>
---
 arch/arm/include/asm/domain.h | 6 ++++++
 arch/arm/kernel/head.S        | 5 +----
 2 files changed, 7 insertions(+), 4 deletions(-)

diff --git a/arch/arm/include/asm/domain.h b/arch/arm/include/asm/domain.h
index 045b9b453bcd..4218f88e8f7e 100644
--- a/arch/arm/include/asm/domain.h
+++ b/arch/arm/include/asm/domain.h
@@ -58,6 +58,12 @@
 #define domain_mask(dom)	((3) << (2 * (dom)))
 #define domain_val(dom,type)	((type) << (2 * (dom)))
 
+#define DACR_INIT \
+	(domain_val(DOMAIN_USER, DOMAIN_MANAGER) | \
+	 domain_val(DOMAIN_KERNEL, DOMAIN_MANAGER) | \
+	 domain_val(DOMAIN_TABLE, DOMAIN_MANAGER) | \
+	 domain_val(DOMAIN_IO, DOMAIN_CLIENT))
+
 #ifndef __ASSEMBLY__
 
 static inline unsigned int get_domain(void)
diff --git a/arch/arm/kernel/head.S b/arch/arm/kernel/head.S
index bd755d97e459..d56e5e9a9e1e 100644
--- a/arch/arm/kernel/head.S
+++ b/arch/arm/kernel/head.S
@@ -461,10 +461,7 @@ __enable_mmu:
 #ifdef CONFIG_ARM_LPAE
 	mcrr	p15, 0, r4, r5, c2		@ load TTBR0
 #else
-	mov	r5, #(domain_val(DOMAIN_USER, DOMAIN_MANAGER) | \
-		      domain_val(DOMAIN_KERNEL, DOMAIN_MANAGER) | \
-		      domain_val(DOMAIN_TABLE, DOMAIN_MANAGER) | \
-		      domain_val(DOMAIN_IO, DOMAIN_CLIENT))
+	mov	r5, #DACR_INIT
 	mcr	p15, 0, r5, c3, c0, 0		@ load domain access register
 	mcr	p15, 0, r4, c2, c0, 0		@ load page table pointer
 #endif
-- 
2.1.0



From ard.biesheuvel at linaro.org  Tue Aug 25 08:45:17 2015
From: ard.biesheuvel at linaro.org (Ard Biesheuvel)
Date: Tue, 25 Aug 2015 17:45:17 +0200
Subject: [PATCH v1 3/3] arm64: dts: add Hi6220 mailbox node
In-Reply-To: <20150825153754.GY10728@bivouac.eciton.net>
References: <20150824095144.GA7139@leverpostej>
 <1440411596.3517.12.camel@linaro.org>
 <20150824114903.GT10728@bivouac.eciton.net>
 <1440490427.10987.29.camel@linaro.org>
 <20150825094630.GU10728@bivouac.eciton.net>
 <1440497710.10987.42.camel@linaro.org>
 <20150825104256.GB13471@leverpostej>
 <1440510194.10987.52.camel@linaro.org>
 <20150825142416.GW10728@bivouac.eciton.net>
 <CAKv+Gu-b=QvMF++V9UjULRxrGvoz-0ytFLeuLm8Y5sQH4p53Sw@mail.gmail.com>
 <20150825153754.GY10728@bivouac.eciton.net>
Message-ID: <CAKv+Gu-JrEmf+wLOsDDjT0vPhGvQkrWqmOBx7KA_31DPmpP7UA@mail.gmail.com>

On 25 August 2015 at 17:37, Leif Lindholm <leif.lindholm at linaro.org> wrote:
> On Tue, Aug 25, 2015 at 04:51:22PM +0200, Ard Biesheuvel wrote:
>> >>    Arm kernel should either fetch memory information from
>> >>    efi or DT.
>> >
>> > Absolutely.
>> >
>> >>    Currently arm kernel fetch both efi memory information and
>> >>    reserved buffer from DTB at the same time.
>> >
>> > No, it does not.
>>
>> It should not, but it does. Due to an oversight, the stub removes
>> /memreserve/ entries but ignores the reserved-memory node completely.
>
> Urgh.
>
>> This was reported here in fact
>>
>> http://thread.gmane.org/gmane.linux.kernel.efi/5736/focus=5742
>>
>> but there has not been a followup to this series.
>
> Are all of those patches still relevant, or did some of them go in
> already?
>

The first two patches are in v4.2-rc1 and up, the others should still
apply on top of that.

-- 
Ard.


From andre.przywara at arm.com  Tue Aug 25 08:47:01 2015
From: andre.przywara at arm.com (Andre Przywara)
Date: Tue, 25 Aug 2015 16:47:01 +0100
Subject: [PATCH v2 12/15] KVM: arm64: sync LPI configuration and pending
 tables
In-Reply-To: <55CDE0A6.5010906@linaro.org>
References: <1436538111-4294-1-git-send-email-andre.przywara@arm.com>
 <1436538111-4294-13-git-send-email-andre.przywara@arm.com>
 <55CDD7CB.9020103@linaro.org> <55CDE0A6.5010906@linaro.org>
Message-ID: <55DC8DF5.3010303@arm.com>

Hi Eric,

On 14/08/15 13:35, Eric Auger wrote:
> On 08/14/2015 01:58 PM, Eric Auger wrote:
>> On 07/10/2015 04:21 PM, Andre Przywara wrote:
>>> The LPI configuration and pending tables of the GICv3 LPIs are held
>>> in tables in (guest) memory. To achieve reasonable performance, we
>>> cache this data in our own data structures, so we need to sync those
>>> two views from time to time. This behaviour is well described in the
>>> GICv3 spec and is also exercised by hardware, so the sync points are
>>> well known.
>>>
>>> Provide functions that read the guest memory and store the
>>> information from the configuration and pending tables in the kernel.
>>>
>>> Signed-off-by: Andre Przywara <andre.przywara at arm.com>
>>> ---
>> would help to have change log between v1 -> v2 (valid for the whole series)
>>>  include/kvm/arm_vgic.h  |   2 +
>>>  virt/kvm/arm/its-emul.c | 124 ++++++++++++++++++++++++++++++++++++++++++++++++
>>>  virt/kvm/arm/its-emul.h |   3 ++
>>>  3 files changed, 129 insertions(+)
>>>
>>> diff --git a/include/kvm/arm_vgic.h b/include/kvm/arm_vgic.h
>>> index 2a67a10..323c33a 100644
>>> --- a/include/kvm/arm_vgic.h
>>> +++ b/include/kvm/arm_vgic.h
>>> @@ -167,6 +167,8 @@ struct vgic_its {
>>>  	int			cwriter;
>>>  	struct list_head	device_list;
>>>  	struct list_head	collection_list;
>>> +	/* memory used for buffering guest's memory */
>>> +	void			*buffer_page;
>>>  };
>>>  
>>>  struct vgic_dist {
>>> diff --git a/virt/kvm/arm/its-emul.c b/virt/kvm/arm/its-emul.c
>>> index b9c40d7..05245cb 100644
>>> --- a/virt/kvm/arm/its-emul.c
>>> +++ b/virt/kvm/arm/its-emul.c
>>> @@ -50,6 +50,7 @@ struct its_itte {
>>>  	struct its_collection *collection;
>>>  	u32 lpi;
>>>  	u32 event_id;
>>> +	u8 priority;
>>>  	bool enabled;
>>>  	unsigned long *pending;
>>>  };
>>> @@ -70,8 +71,124 @@ static struct its_itte *find_itte_by_lpi(struct kvm *kvm, int lpi)
>>>  	return NULL;
>>>  }
>>>  
>>> +#define LPI_PROP_ENABLE_BIT(p)	((p) & LPI_PROP_ENABLED)
>>> +#define LPI_PROP_PRIORITY(p)	((p) & 0xfc)
>>> +
>>> +/* stores the priority and enable bit for a given LPI */
>>> +static void update_lpi_config(struct kvm *kvm, struct its_itte *itte, u8 prop)
>>> +{
>>> +	itte->priority = LPI_PROP_PRIORITY(prop);
>>> +	itte->enabled  = LPI_PROP_ENABLE_BIT(prop);
>>> +}
>>> +
>>> +#define GIC_LPI_OFFSET 8192
>>> +
>>> +/* We scan the table in chunks the size of the smallest page size */
>> 4kB chunks?
>>> +#define CHUNK_SIZE 4096U
>>> +
>>>  #define BASER_BASE_ADDRESS(x) ((x) & 0xfffffffff000ULL)
>>>  
>>> +static int nr_idbits_propbase(u64 propbaser)
>>> +{
>>> +	int nr_idbits = (1U << (propbaser & 0x1f)) + 1;
>>> +
>>> +	return max(nr_idbits, INTERRUPT_ID_BITS_ITS);
>>> +}
>>> +
>>> +/*
>>> + * Scan the whole LPI configuration table and put the LPI configuration
>>> + * data in our own data structures. This relies on the LPI being
>>> + * mapped before.
>>> + */
>>> +static bool its_update_lpis_configuration(struct kvm *kvm)
>>> +{
>>> +	struct vgic_dist *dist = &kvm->arch.vgic;
>>> +	u8 *prop = dist->its.buffer_page;
>>> +	u32 tsize;
>>> +	gpa_t propbase;
>>> +	int lpi = GIC_LPI_OFFSET;
>>> +	struct its_itte *itte;
>>> +	struct its_device *device;
>>> +	int ret;
>>> +
>>> +	propbase = BASER_BASE_ADDRESS(dist->propbaser);
>>> +	tsize = nr_idbits_propbase(dist->propbaser);
>>> +
>>> +	while (tsize > 0) {
>>> +		int chunksize = min(tsize, CHUNK_SIZE);
>>> +
>>> +		ret = kvm_read_guest(kvm, propbase, prop, chunksize);
>> I think you still have the spin_lock issue  since if my understanding is
>> correct this is called from
>> vgic_handle_mmio_access/vcall_range_handler/gic_enable_lpis
>> where vgic_handle_mmio_access. Or does it take another path?
>>
>> Shouldn't we create a new kvm_io_device to avoid holding the dist lock?
> 
> Sorry I forgot it was the case already. But currently we always register
> the same io ops (registration entry point being
> vgic_register_kvm_io_dev) and maybe we should have separate dispatcher
> function for dist, redit and its?

What would be the idea behind it? To have separate locks for each? I
don't think that will work, as some ITS functions are called from GICv3
register handler functions which manipulate members of the distributor
structure. So I am more in favour of dropping the dist lock in these
cases before handing off execution to ITS specific functions.

Cheers,
Andre.


From tglx at linutronix.de  Tue Aug 25 08:46:44 2015
From: tglx at linutronix.de (Thomas Gleixner)
Date: Tue, 25 Aug 2015 17:46:44 +0200 (CEST)
Subject: [PATCH v3 3/4] irqchip: GIC: Convert to EOImode == 1
In-Reply-To: <1440503605-10185-4-git-send-email-marc.zyngier@arm.com>
References: <1440503605-10185-1-git-send-email-marc.zyngier@arm.com>
 <1440503605-10185-4-git-send-email-marc.zyngier@arm.com>
Message-ID: <alpine.DEB.2.11.1508251745070.15006@nanos>

On Tue, 25 Aug 2015, Marc Zyngier wrote:
> +static struct static_key supports_deactivate = STATIC_KEY_INIT_TRUE;
> +
>  #ifndef MAX_GIC_NR
>  #define MAX_GIC_NR	1
>  #endif
> @@ -137,6 +140,14 @@ static inline unsigned int gic_irq(struct irq_data *d)
>  	return d->hwirq;
>  }
>  
> +static inline bool primary_gic_irq(struct irq_data *d)
> +{
> +	if (MAX_GIC_NR > 1)
> +		return irq_data_get_irq_chip_data(d) == &gic_data[0];
> +
> +	return true;
> +}
> +
>  /*
>   * Routines to acknowledge, disable and enable interrupts
>   */
> @@ -164,7 +175,14 @@ static void gic_unmask_irq(struct irq_data *d)
>  
>  static void gic_eoi_irq(struct irq_data *d)
>  {
> -	writel_relaxed(gic_irq(d), gic_cpu_base(d) + GIC_CPU_EOI);
> +	u32 deact_offset = GIC_CPU_EOI;
> +
> +	if (static_key_true(&supports_deactivate)) {
> +		if (primary_gic_irq(d))
> +			deact_offset = GIC_CPU_DEACTIVATE;

I really wonder for the whole series whether you really want all that
static key dance and extra conditionals in the callbacks instead of
just using seperate irq chips for the different interrupts.

Thanks,

	tglx


From computersforpeace at gmail.com  Tue Aug 25 08:57:49 2015
From: computersforpeace at gmail.com (Brian Norris)
Date: Tue, 25 Aug 2015 08:57:49 -0700
Subject: [PATCH linux-next v4 5/5] mtd: atmel-quadspi: add driver for
 Atmel QSPI controller
In-Reply-To: <201508251222.10813.marex@denx.de>
References: <cover.1440410236.git.cyrille.pitchen@atmel.com>
 <201508241303.52066.marex@denx.de> <55DC40C1.3050405@atmel.com>
 <201508251222.10813.marex@denx.de>
Message-ID: <20150825155749.GA7622@localhost>

On Tue, Aug 25, 2015 at 12:22:10PM +0200, Marek Vasut wrote:
> On Tuesday, August 25, 2015 at 12:17:37 PM, Cyrille Pitchen wrote:
> > If you don't mind, I'd rather keep some of these inline functions. I have
> > no strong justification, it's more a personal taste: it makes lines
> > shorter as it avoids the need to add "->regs + ".
> > Also it makes the code consistent with other Atmel drivers which already
> > use such wrappers.
> > 
> > However I'll fix the comment and remove the byte and word versions, which
> > are not used. So only qspi_readl() and qspi_writel() are left.
> > 
> > Does it sound good to you?
> 
> In my mind, seeing explicit readl_relaxed() somewhere is much easier to
> digest than seeing some wrapper, which I have to look up. But please do
> wait for others to voice their concern too, I might not be the best person
> to tell you what to do when it comes to wrapping IO accessors ;-)

I could go either way, but there are times where local wrapper I/O
accessors are useful. Case in point: it makes it really easy to make the
choice between readl() and readl_relaxed() in one place (i.e., the
discussion you had in another branch of this thread). That's been useful
for me on brcmnand, where certain platforms (big-endian MIPS) have
different assumptions about endianness than your average platform. Also,
it helps with things like what Robert Jarzmik is trying to do on
pxa3xx_nand -- add debug info to print every register read/write.

Also as Cyrille mentioned, personal taste is a factor.

Anyway, I'll go with whatever makes sense between y'all. I don't mind.

Brian


From linux at arm.linux.org.uk  Tue Aug 25 08:57:52 2015
From: linux at arm.linux.org.uk (Russell King - ARM Linux)
Date: Tue, 25 Aug 2015 16:57:52 +0100
Subject: [PATCH v3 06/14] Documentation: drm/bridge: add document for
 analogix_dp
In-Reply-To: <20150825142150.GB3820@ulmo.nvidia.com>
References: <1439995728-18046-1-git-send-email-ykk@rock-chips.com>
 <1439995834-18363-1-git-send-email-ykk@rock-chips.com>
 <20150825095817.GC14034@ulmo.nvidia.com>
 <55DC75C8.209@rock-chips.com>
 <20150825142150.GB3820@ulmo.nvidia.com>
Message-ID: <20150825155752.GU7557@n2100.arm.linux.org.uk>

On Tue, Aug 25, 2015 at 04:21:51PM +0200, Thierry Reding wrote:
> You cited code from dw_hdmi.c earlier, it looks like it might be correct
> even though it doesn't cite a reference for why this was done. Perhaps
> someone on this thread, or someone involved with dw_hdmi can answer
> where that code came from.

dw_hdmi doesn't do any format conversion - it's hard coded to RGB, 8
bits per colour component.  That's a requirement for all HDMI sinks.

The reason it's hard-coded in dw_hdmi is that (a) no one has yet decided
its worth the effort to get the dw_hdmi hardware to do the colourspace
conversion to the YUV spaces and verify that it works, and (b) I really
don't see the point when we're talking about computer like devices which
work primerily with RGB and RGB is always supported by the sink.

As far as greater colour depths go, the driver came from the Freescale
iMX6 code base, and the hardware which feeds dw_hdmi can't do more than
8 bits per component - so going to 10, 12 or 16 bits per component is
beyond what iMX6 can cope with.  Hence, no one on the iMX6 side has a
need for the deep colour stuff.

In any case, I view this as a very low priority issue - it would be nice
to have audio support on HDMI for iMX6 at some point in the next 20 years,
preferably before the hardware becomes obsolete.  I've been maintaining
patches for this for 1.5 years now... how much longer is it going to take?
My pull request to David from 15th July was ignored.  My re-send of that
after he returned was ignored.  My reminder of it has been ignored.  What's
going on in DRM land?  It would be nice to get _some_ kind of feedback so
I know why they're not being taken, so I can fix whatever the issue is.

-- 
FTTC broadband for 0.8mile line: currently at 10.5Mbps down 400kbps up
according to speedtest.net.


From leo.yan at linaro.org  Tue Aug 25 09:00:30 2015
From: leo.yan at linaro.org (Leo Yan)
Date: Wed, 26 Aug 2015 00:00:30 +0800
Subject: [PATCH v1 3/3] arm64: dts: add Hi6220 mailbox node
In-Reply-To: <1440510194.10987.52.camel@linaro.org>
References: <20150821184059.GB2000@svinekod>
 <20150824091845.GA28290@leoy-linaro>
 <20150824095144.GA7139@leverpostej>
 <1440411596.3517.12.camel@linaro.org>
 <20150824114903.GT10728@bivouac.eciton.net>
 <1440490427.10987.29.camel@linaro.org>
 <20150825094630.GU10728@bivouac.eciton.net>
 <1440497710.10987.42.camel@linaro.org>
 <20150825104256.GB13471@leverpostej>
 <1440510194.10987.52.camel@linaro.org>
Message-ID: <20150825160030.GA3774@leoy-linaro>

On Tue, Aug 25, 2015 at 09:43:14PM +0800, Haojian Zhuang wrote:
> On Tue, 2015-08-25 at 11:42 +0100, Mark Rutland wrote:
> > > > Are you then going to hack GRUB, release a special HiKey version of
> > > > GRUB, not support any other versions, and still can your firmware
> > > > UEFI?
> > > 
> > > I don't need to hack GRUB at all.
> > 
> > Then it is working for you by pure chance alone.
> > 
> > Please listen to the advice you are being given here; we're trying to
> > ensure that your platform functions (and continues to function) as best
> > it can.
> 
> Since we discussed a lot on this, let's make a conclusion on it.
> 
> 1. UEFI could append the reserved buffer in it's memory mapping.
> 2. These reserved buffer must be declared in DT, since we also need to
>    support non-UEFI (uboot) at the same time.
> 3. Mailbox node should reference reserved buffer by phandle in DT. Then
>    map the buffer as non-cacheable in driver.
> 4. These reserved buffer must use "no-map" property since it should be
>    non-cacheable in driver.

For more specific discussion for DTS, i list two options at here;

- Option 1: just simply reserve memory regions through memory node,
  and mailbox node will directly use the buffer through reg ranges;

- Option 2: use reserved-memory and mailbox node will refer phandle
  of reserved-memory;

These two options both can work well with UEFI and Uboot, but option 1
is more simple and straightforward; so i personally prefer it. But
look forwarding your guys' suggestion.

Option 1:

	memory at 0 {
		device_type = "memory";
		reg = <0x00000000 0x00000000 0x00000000 0x05e00000>,
		      <0x00000000 0x05f00000 0x00000000 0x00eff000>,
		      <0x00000000 0x06e00000 0x00000000 0x0060f000>,
		      <0x00000000 0x07410000 0x00000000 0x38bf0000>;
	};

        [...]

	mailbox: mailbox at f7510000 {
		#mbox-cells = <1>;
		compatible = "hisilicon,hi6220-mbox";
		reg = <0x0 0xf7510000 0x0 0x1000>, /* IPC_S */
		      <0x0 0x06dff800 0x0 0x0800>; /* Mailbox buffer */
		interrupts = <GIC_SPI 94 IRQ_TYPE_LEVEL_HIGH>;
	};

Option 2:

	memory at 0 {
		device_type = "memory";
		reg = <0x0 0x0 0x0 0x40000000>;
	};

	reserved-memory {
		#address-cells = <2>;
		#size-cells = <2>;
		ranges;

		mcu_reserved: mcu_reserved at 06dff000 {
			no-map;
			reg = <0x0 0x06dff000 0x0 0x00001000>,	/* MCU mailbox buffer */
			      <0x0 0x05e00000 0x0 0x00100000>,	/* MCU firmware buffer */
			      <0x0 0x0740f000 0x0 0x00001000>;	/* MCU firmware section */
		};
	};

        [...]

	mailbox: mailbox at f7510000 {
		#mbox-cells = <1>;
		compatible = "hisilicon,hi6220-mbox";
		reg = <0x0 0xf7510000 0x0 0x1000>; /* IPC_S */
		memory-region = <&mcu_reserved>;   /* Mailbox buffer */
		interrupts = <GIC_SPI 94 IRQ_TYPE_LEVEL_HIGH>;
	};


> 5. A patch is necessary in kernel. If efi stub feature is enabled,
>    arm kernel should not parse memory node or reserved memory buffer in
>    DT any more. Arm kernel should either fetch memory information from 
>    efi or DT. Currently arm kernel fetch both efi memory information and
>    reserved buffer from DTB at the same time.
> 
> Do you agree on these points?
> 
> Regards
> Haojian
> 


From sudeep.holla at arm.com  Tue Aug 25 09:03:10 2015
From: sudeep.holla at arm.com (Sudeep Holla)
Date: Tue, 25 Aug 2015 17:03:10 +0100
Subject: [PATCH v3 1/1] misc: sram: add dev_pm_ops to support module power
 gate
In-Reply-To: <CY1PR0301MB0843A508122C7FCF3969AF3D83610@CY1PR0301MB0843.namprd03.prod.outlook.com>
References: <1438272681-29338-1-git-send-email-shenwei.wang@freescale.com>
 <55DC677E.1030004@arm.com>
 <CY1PR0301MB0843D5CB5FFC56991B90EB4283610@CY1PR0301MB0843.namprd03.prod.outlook.com>
 <55DC74CF.7070300@arm.com>
 <CY1PR0301MB084302FA2AA9582A3BA9B50B83610@CY1PR0301MB0843.namprd03.prod.outlook.com>
 <55DC7E5E.5020701@arm.com>
 <CY1PR0301MB0843A508122C7FCF3969AF3D83610@CY1PR0301MB0843.namprd03.prod.outlook.com>
Message-ID: <55DC91BE.7090107@arm.com>



On 25/08/15 16:05, Shenwei Wang wrote:
>
>
>> -----Original Message-----
>> From: Sudeep Holla [mailto:sudeep.holla at arm.com]
>> Sent: 2015?8?25? 9:41
>> To: Wang Shenwei-B38339
>> Cc: Sudeep Holla; gregkh at linuxfoundation.org; arnd at arndb.de; Huang
>> Yongcai-B20788; linux-arm-kernel at lists.infradead.org
>> Subject: Re: [PATCH v3 1/1] misc: sram: add dev_pm_ops to support module
>> power gate
>>>> What I meant is who will be using the SRAM when entering S2R that you
>>>> need to save the content. Either the user needs to take care of the
>>>> content or just release the pool when not in use. When the sram pool has no
>> user, clock can be gated.
>>>>
>>>> Again can you give details of this use-case.
>>>
>>> We are not talking about clock gate state. Here we are handling
>>> the power gate for this SRAM IP block. Of course, you can ask
>>> each driver to save its contents during low power state, but I
>>> think the easier way is to save the contents in this sram driver
>>> and just leave the  drivers who use this sram behave as is today.
>>
>> I don't like that solution as it's not scalable with SRAM size and
>> saving all the content of SRAM just because of few active regions
>> makes no sense to me at-least. I prefer leaving it to the users to
>> handle that rather than SRAM driver.
>
> I don't think it is not scalable. The choice should be made by the
> application. From the driver side, it should be able to provide the
> way to retain its contents during power gate.
>

OK that was just my opinion. I just wanted to avoid unnecessary
save/restore, e.g. if say just few kilobytes are active in say 32MB
SRAM, you will save/restore entire SRAM ?

Anyways, the driver is saving/restoring the memory unconditionally
whenever DT sets that boolean right ? at-least as the patch stands.

Regards,
Sudeep


From peter.griffin at linaro.org  Tue Aug 25 09:22:07 2015
From: peter.griffin at linaro.org (Peter Griffin)
Date: Tue, 25 Aug 2015 17:22:07 +0100
Subject: [PATCH 0/3] c8sectpfe
Message-ID: <1440519730-486-1-git-send-email-peter.griffin@linaro.org>

Hi Mauro,

This series includes a couple of fixes for the c8sectpfe Linux dvb driver.

One was caused by omitting a patch from the original c8sectpfe series which
defined the ssc2 and ssc3 dt nodes, which was then used by the later DT patch.

This patch is included, along with the original patch which you reverted.

Also Valentin Rothberg spotted LIBELF32 Kconfig symbol I was selecting in the
Kconfig, this isn't required upstream and is left over legacy so I've removed
it.

Sorry for the delay in sending these fixes, I've been on holiday for the last
3 weeks.

kind regards,

Peter.

Peter Griffin (3):
  ARM: DT: STi: stihxxx-b2120: Add pulse-width properties to ssc2 & ssc3
  ARM: DT: STi: STiH407: Add c8sectpfe LinuxDVB DT node.
  [media] c8sectpfe: Remove select on undefined LIBELF_32

 arch/arm/boot/dts/stihxxx-b2120.dtsi         | 48 ++++++++++++++++++++++++++--
 drivers/media/platform/sti/c8sectpfe/Kconfig |  1 -
 2 files changed, 46 insertions(+), 3 deletions(-)

-- 
1.9.1



From peter.griffin at linaro.org  Tue Aug 25 09:22:09 2015
From: peter.griffin at linaro.org (Peter Griffin)
Date: Tue, 25 Aug 2015 17:22:09 +0100
Subject: [PATCH 2/3] ARM: DT: STi: STiH407: Add c8sectpfe LinuxDVB DT node.
In-Reply-To: <1440519730-486-1-git-send-email-peter.griffin@linaro.org>
References: <1440519730-486-1-git-send-email-peter.griffin@linaro.org>
Message-ID: <1440519730-486-3-git-send-email-peter.griffin@linaro.org>

This patch adds in the required DT node for the c8sectpfe
Linux DVB demux driver which allows the tsin channels
to be used on an upstream kernel.

Signed-off-by: Peter Griffin <peter.griffin at linaro.org>
---
 arch/arm/boot/dts/stihxxx-b2120.dtsi | 38 ++++++++++++++++++++++++++++++++++++
 1 file changed, 38 insertions(+)

diff --git a/arch/arm/boot/dts/stihxxx-b2120.dtsi b/arch/arm/boot/dts/stihxxx-b2120.dtsi
index 62994ae..1bc018e 100644
--- a/arch/arm/boot/dts/stihxxx-b2120.dtsi
+++ b/arch/arm/boot/dts/stihxxx-b2120.dtsi
@@ -6,6 +6,10 @@
  * it under the terms of the GNU General Public License version 2 as
  * published by the Free Software Foundation.
  */
+
+#include <dt-bindings/clock/stih407-clks.h>
+#include <dt-bindings/media/c8sectpfe.h>
+
 / {
 	soc {
 		sbc_serial0: serial at 9530000 {
@@ -85,5 +89,39 @@
 			status = "okay";
 		};
 
+		c8sectpfe at 08a20000 {
+			compatible = "st,stih407-c8sectpfe";
+			status = "okay";
+			reg = <0x08a20000 0x10000>, <0x08a00000 0x4000>;
+			reg-names = "c8sectpfe", "c8sectpfe-ram";
+
+			interrupts = <0 34 0>, <0 35 0>;
+			interrupt-names = "c8sectpfe-error-irq",
+					  "c8sectpfe-idle-irq";
+
+			pinctrl-names	= "tsin0-serial", "tsin0-parallel",
+					  "tsin3-serial", "tsin4-serial",
+					  "tsin5-serial";
+
+			pinctrl-0	= <&pinctrl_tsin0_serial>;
+			pinctrl-1	= <&pinctrl_tsin0_parallel>;
+			pinctrl-2	= <&pinctrl_tsin3_serial>;
+			pinctrl-3	= <&pinctrl_tsin4_serial_alt3>;
+			pinctrl-4	= <&pinctrl_tsin5_serial_alt1>;
+
+			clocks = <&clk_s_c0_flexgen CLK_PROC_STFE>;
+			clock-names = "c8sectpfe";
+
+			/* tsin0 is TSA on NIMA */
+			tsin0: port at 0 {
+
+				tsin-num = <0>;
+				serial-not-parallel;
+				i2c-bus = <&ssc2>;
+				rst-gpio = <&pio15 4 0>;
+
+				dvb-card = <STV0367_TDA18212_NIMA_1>;
+			};
+		};
 	};
 };
-- 
1.9.1



From peter.griffin at linaro.org  Tue Aug 25 09:22:08 2015
From: peter.griffin at linaro.org (Peter Griffin)
Date: Tue, 25 Aug 2015 17:22:08 +0100
Subject: [PATCH 1/3] ARM: DT: STi: stihxxx-b2120: Add pulse-width properties
 to ssc2 & ssc3
In-Reply-To: <1440519730-486-1-git-send-email-peter.griffin@linaro.org>
References: <1440519730-486-1-git-send-email-peter.griffin@linaro.org>
Message-ID: <1440519730-486-2-git-send-email-peter.griffin@linaro.org>

Adding these properties makes the I2C bus to the demodulators much
more reliable, and we no longer suffer from I2C errors when tuning.

Signed-off-by: Peter Griffin <peter.griffin at linaro.org>
---
 arch/arm/boot/dts/stihxxx-b2120.dtsi | 10 ++++++++--
 1 file changed, 8 insertions(+), 2 deletions(-)

diff --git a/arch/arm/boot/dts/stihxxx-b2120.dtsi b/arch/arm/boot/dts/stihxxx-b2120.dtsi
index f589fe4..62994ae 100644
--- a/arch/arm/boot/dts/stihxxx-b2120.dtsi
+++ b/arch/arm/boot/dts/stihxxx-b2120.dtsi
@@ -27,12 +27,18 @@
 			};
 		};
 
-		i2c at 9842000 {
+		ssc2: i2c at 9842000 {
 			status = "okay";
+			clock-frequency = <100000>;
+			st,i2c-min-scl-pulse-width-us = <0>;
+			st,i2c-min-sda-pulse-width-us = <5>;
 		};
 
-		i2c at 9843000 {
+		ssc3: i2c at 9843000 {
 			status = "okay";
+			clock-frequency = <100000>;
+			st,i2c-min-scl-pulse-width-us = <0>;
+			st,i2c-min-sda-pulse-width-us = <5>;
 		};
 
 		i2c at 9844000 {
-- 
1.9.1



From peter.griffin at linaro.org  Tue Aug 25 09:22:10 2015
From: peter.griffin at linaro.org (Peter Griffin)
Date: Tue, 25 Aug 2015 17:22:10 +0100
Subject: [PATCH 3/3] [media] c8sectpfe: Remove select on undefined LIBELF_32
In-Reply-To: <1440519730-486-1-git-send-email-peter.griffin@linaro.org>
References: <1440519730-486-1-git-send-email-peter.griffin@linaro.org>
Message-ID: <1440519730-486-4-git-send-email-peter.griffin@linaro.org>

LIBELF_32 is not defined in Kconfig, and is left over legacy
which is not required in the upstream driver, so remove it.

Signed-off-by: Peter Griffin <peter.griffin at linaro.org>
Suggested-by: Valentin Rothberg <valentinrothberg at gmail.com>
---
 drivers/media/platform/sti/c8sectpfe/Kconfig | 1 -
 1 file changed, 1 deletion(-)

diff --git a/drivers/media/platform/sti/c8sectpfe/Kconfig b/drivers/media/platform/sti/c8sectpfe/Kconfig
index d1bfd4c..b9ec667 100644
--- a/drivers/media/platform/sti/c8sectpfe/Kconfig
+++ b/drivers/media/platform/sti/c8sectpfe/Kconfig
@@ -1,7 +1,6 @@
 config DVB_C8SECTPFE
 	tristate "STMicroelectronics C8SECTPFE DVB support"
 	depends on DVB_CORE && I2C && (ARCH_STI || ARCH_MULTIPLATFORM)
-	select LIBELF_32
 	select FW_LOADER
 	select FW_LOADER_USER_HELPER_FALLBACK
 	select DEBUG_FS
-- 
1.9.1



From robherring2 at gmail.com  Tue Aug 25 09:22:36 2015
From: robherring2 at gmail.com (Rob Herring)
Date: Tue, 25 Aug 2015 11:22:36 -0500
Subject: [PATCH] arm: rpi: Device tree modifications for U-Boot
In-Reply-To: <CAPnjgZ3ubK_5j4AV4wO6xgoRf8iN+G8YSQm0pSW5fVzwpxYu5Q@mail.gmail.com>
References: <1439303153-12171-1-git-send-email-sjg@chromium.org>
 <1439312701.2451.3.camel@lynxeye.de>
 <CAPnjgZ3ztXnkxZJvitiXiKMzq5+x46hbv0PW4HcF7yGgsXUV+Q@mail.gmail.com>
 <CAPnjgZ0hzyjy=8o8ocaGCoOC7Js4CirhystidbvtabzbhRi4RQ@mail.gmail.com>
 <CAL_Jsq++ihz6svJAKWwT7-=KyJvyWXjdf=tZb4aDGgV_Dc=-Nw@mail.gmail.com>
 <CAPnjgZ3ubK_5j4AV4wO6xgoRf8iN+G8YSQm0pSW5fVzwpxYu5Q@mail.gmail.com>
Message-ID: <CAL_JsqJ-N+nFEMEEmg4O45DVF0g382fUvjGTH=fP_HbgK38aKw@mail.gmail.com>

On Sat, Aug 15, 2015 at 8:46 AM, Simon Glass <sjg at chromium.org> wrote:
> Hi Rob,
>
> On 14 August 2015 at 14:29, Rob Herring <robherring2 at gmail.com> wrote:
>> On Fri, Aug 14, 2015 at 1:34 PM, Simon Glass <sjg at chromium.org> wrote:
>>> -linux-tegra
>>>
>>> Hi,
>>>
>>> On 12 August 2015 at 07:21, Simon Glass <sjg at chromium.org> wrote:
>>>> Hi Lucas,
>>>>
>>>> On 11 August 2015 at 11:05, Lucas Stach <dev at lynxeye.de> wrote:
>>>>> Hi Simon,
>>>>>
>>>>> why did you send this to the Tegra ML?
>>>>>
>>>>> Am Dienstag, den 11.08.2015, 08:25 -0600 schrieb Simon Glass:
>>>>>> This updates the device tree from the kernel version to something suitable
>>>>>> for U-Boot:
>>>>>>
>>>>>> - Add stdout-path alias for console
>>>>>> - Mark the /soc node to be available pre-relocation so that the early
>>>>>> serial console works (we need the 'ranges' property to be available)
>>
>> I find it quite strange that you must explicitly enable the parent
>> node, but not the uart node.
>
> U-Boot tries hard to find and bind the UART using the stdout-path
> link. I would like to add it in the UART node also but we were able to
> work around it so far.
>
>>
>>>>>>
>>>>>> Signed-off-by: Simon Glass <sjg at chromium.org>
>>>>>> ---
>>>>>>
>>>>>>  arch/arm/boot/dts/bcm2835.dtsi | 4 +++-
>>>>>>  1 file changed, 3 insertions(+), 1 deletion(-)
>>>>>>
>>>>>> diff --git a/arch/arm/boot/dts/bcm2835.dtsi b/arch/arm/boot/dts/bcm2835.dtsi
>>>>>> index 301c73f..bd6bff6 100644
>>>>>> --- a/arch/arm/boot/dts/bcm2835.dtsi
>>>>>> +++ b/arch/arm/boot/dts/bcm2835.dtsi
>>>>>> @@ -8,6 +8,7 @@
>>>>>>
>>>>>>       chosen {
>>>>>>               bootargs = "earlyprintk console=ttyAMA0";
>>>>>> +             stdout-path = &uart;
>>>>>>       };
>>>>>>
>>>>>>       soc {
>>>>>> @@ -16,6 +17,7 @@
>>>>>>               #size-cells = <1>;
>>>>>>               ranges = <0x7e000000 0x20000000 0x02000000>;
>>>>>>               dma-ranges = <0x40000000 0x00000000 0x20000000>;
>>>>>> +             u-boot,dm-pre-reloc;
>>>>>
>>>>> Why do you need this and why should upstream carry your favourite
>>>>> bootloaders configuration? This is in no way hardware description.
>>>>
>>>> I'm not sure how much you know about U-Boot, so let me know if you
>>>> need more info.
>>>>
>>>> U-Boot normally starts up by setting up its serial UART and displaying
>>>> a banner message. At this stage typically only a few devices are
>>>> initialised (e.g. maybe just the UART). It then relocates itself to
>>>> the top of memory and starts up all the devices. It throws away any
>>>> previous devices that it set up before relocation and starts again.
>>>>
>>>> U-Boot uses a thing called driver model (dm) which handles driver
>>>> binding and probing. Driver model has the device tree and would
>>>> normally scan through it and create devices for everything it finds.
>>
>> How do you debug the DM itself? It seems like you still would need
>> something earlier for debug like earlycon in the kernel. u-boot DM is
>> probably simple enough you can get away with using it early, but you
>> often can't as the complexity increases. Ultimately you need something
>> simple that just hits all the registers needed to get characters out.
>> What happens when you add pinmux, clocks, PMIC, power domains, etc. to
>> the DM and they all become dependencies for the UART?
>
> This doesn't seem like a device tree binding question but let me try
> to answer it.
>
> This is a problem - one of the challenges of driver model is that the
> UART gets further away from the reset vector.

This is a common problem for any complex embedded system. Nothing
special about u-boot here. So either we don't need anything because
everyone else has dealt with the problem in some way or we need a
common solution because we all have this problem.

> In U-Boot there is a single debug UART which can be supported by the
> various serial drivers (only one can be selected on each platform).
> There is a special debug_uart_init() function which is supposed to set
> up the UART for that platform. After that, and until driver model UART
> is up, console output can go through the debug UART.

So you don't need this for the common case of an early console, but
only for platforms needing some other platform specific setup?

>>>> Before relocation we don't need every device. Also the CPU is often
>>>> running slowly, perhaps without the cache enabled. SDRAM may not be
>>>> available yet so space is short. We want to avoid starting up things
>>>> that will not be used.
>>>>
>>>> So this property indicates that the device is needed before relocation
>>>> and should be set up by driver model. We need it to avoid a very slow
>>>> and memory-hungry startup.
>>
>> Can't the need for that property change over time? Either as more
>> drivers are converted to DM you need to add this or you add some
>> feature that depends on a driver (e.g. get a board rev or boot mode
>> from GPIO). You would have backwards compatibility issues with this.
>> I'm somewhat less worried about that for u-boot as we should be
>> bundling the dtb and bootloader rather than kernel and dtb. For the
>> UART, you can just get which UART to initialize early from
>> stdout-path. But for other cases, couldn't you just have the platform
>> provide the list of needed drivers. Then when u-boot needs change, you
>> just change u-boot.
>
> Yes U-Boot and its device tree are normally built from the same tree
> at the same time. We don't expect to have to support an older or newer
> device tree with the same U-Boot binary. So I don't see a problem
> here.

My point is that if I had to pick how bootloader+dtb+kernel are
bundled or not, I would rather see the dtb in sync with the bootloader
rather than the kernel. But I can't decide that for everyone and
neither can you. You still have a compatibility problem and that has
to be addressed.

> The UART should have as few dependencies as possible. But if the
> particular platform needs to check a GPIO to find out the UART number
> (i.e. stdout-path cannot be used) then we would need to support that
> case. It hasn't come up yet but it might. I certainly see platforms
> where we need some other nodes before relocation and would like to
> mark them as such. But I hope that for UART we can generally use
> stdout-path.
>
> The list of drivers doesn't help that much. What would I do with such
> a list, and where would I keep such platform-specific information
> other than in the device tree? It seems much simpler to hold the
> information about what the platform needs to get through early boot in
> one place. Then we have just a few lines of generic code to deal with
> it.

If you need certain drivers such as gpio, then you obviously have some
board specific code using those drivers already. If you can tell the
DM which devices to enumerate via DT, you can also tell the DM with C
code.

While doing everything generically without board code is nice, we
should only do that for the common cases and handle the screwy cases
with board code.

Rob


From sudeep.holla at arm.com  Tue Aug 25 09:24:26 2015
From: sudeep.holla at arm.com (Sudeep Holla)
Date: Tue, 25 Aug 2015 17:24:26 +0100
Subject: [PATCH v9 1/1] irqchip: imx-gpcv2: IMX GPCv2 driver for wakeup
 sources
In-Reply-To: <CY1PR0301MB08433A2659C75028821F0AE783610@CY1PR0301MB0843.namprd03.prod.outlook.com>
References: <1440443055-7291-1-git-send-email-shenwei.wang@freescale.com>
 <55DC3452.3070205@arm.com>
 <CY1PR0301MB08439B6C5F841AFFD152DFD883610@CY1PR0301MB0843.namprd03.prod.outlook.com>
 <55DC738D.8000302@arm.com>
 <CY1PR0301MB0843AE566996617D855CC00683610@CY1PR0301MB0843.namprd03.prod.outlook.com>
 <55DC7FA4.7040902@arm.com>
 <CY1PR0301MB08433A2659C75028821F0AE783610@CY1PR0301MB0843.namprd03.prod.outlook.com>
Message-ID: <55DC96BA.2020905@arm.com>



On 25/08/15 15:54, Shenwei Wang wrote:
>
>
>> -----Original Message-----
>> From: Sudeep Holla [mailto:sudeep.holla at arm.com]
>> Sent: 2015?8?25? 9:46
>> To: Wang Shenwei-B38339
>> Cc: Sudeep Holla; shawn.guo at linaro.org; tglx at linutronix.de;
>> jason at lakedaemon.net; Huang Yongcai-B20788; linux-kernel at vger.kernel.org;
>> linux-arm-kernel at lists.infradead.org
>> Subject: Re: [PATCH v9 1/1] irqchip: imx-gpcv2: IMX GPCv2 driver for wakeup
>> sources
>>
>>
>>
>> On 25/08/15 15:14, Shenwei Wang wrote:
>>>
>>>
>>>> -----Original Message-----
>>>> From: Sudeep Holla [mailto:sudeep.holla at arm.com]
>>
>> [...]
>>
>>>> I don't see this driver doing anything extra apart from keeping
>>>> the wakeup irqs enabled. i.e. You use the same cpu*wake
>>>> register to mask/unmask the interrupt as well as set the wakeup
>>>> source. Since the wakeup interrupt will be enabled by the
>>>> driver, you just need to mark it as wake-up source and nothing
>>>> extra in the controller right ? If so, you need to set
>>>> IRQCHIP_SKIP_SET_WAKE as you are just leaving that irq enabled
>>>> and not doing any extra configuration to enable it  as wakeup source.
>>>> Please correct if that wrong, but from the code that's what I
>>>> couldinfer.
>>>
>>> There is no special for this driver. We just use the IRQCHIP
>>> driver framework to manage the wakeup sources. Why did you
>>> propose to set IRQCHIP_SKIP_SET_WAKE flag here? If you don't need
>>> the wakeup feature, you should just not enable this driver in the
>>> configuration.
>>>
>>
>> No, if the driver doesn't nothing extra to configure the wake up
>> source other than  keeping it enabled, then it fits the case of
>> SKIP_SET_WAKE. The driver using this wake would have requested
>> and enabled the irq. When it calls enable_irq_wake, you have
>> nothing extra to set(atleast  from the looks of the driver), so
>> setting SKIP_SET_WAKE will skip the call and  updated the wake
>> flags in irq core.
>>
>> I don't see the real need of 2 separate sets of irq mask being
>> saved  in either case.
>
> You don't really understand what happens after a driver calls
> enable_irq_wake. In suspend state, even the interrupt
> controller itself is powered off. How can you get the system up
> again  by just using a SKIP_SET_WAKE.
>

Sorry for that, let me try to understand aloud. So you have
irq_{un,}mask function that are called when interrupts are enabled and
disabled. So suppose you have 3 irqs that are enabled and only one of
then is set as wakeup source.

Now you call enable_irq_wake, you save that in wakeup_sources, fine.
Later when you enter suspend, you save all the 3 active irqs in
saved_irq_mask and over-write cpu2wakeup with wakeup_sources, right?

All fine, what I am saying is let irq-core know that you want to mask
the 2 non-wakeup irqs you have using MASK_ON_SUSPEND. So when
suspend_device_irqs is called in suspend path, that's done for you
automatically and the cpu2wakeup will have just 1 wakeup enabled which
is what you are doing in suspend callback, right ?

Now that it's already done for you, you need not do anything extra and
hence just set SKIP_SET_WAKE to do nothing.

Hope this clarifies, sorry if I am still missing to understand something
here, but I don't see anything. Let me know.

Regards,
Sudeep


From broonie at kernel.org  Tue Aug 25 09:33:04 2015
From: broonie at kernel.org (Mark Brown)
Date: Tue, 25 Aug 2015 17:33:04 +0100
Subject: [RESEND PATCH v1 0/1] A misjudgement should be fixed
In-Reply-To: <1440489162-28270-1-git-send-email-zhengxing@rock-chips.com>
References: <1440489162-28270-1-git-send-email-zhengxing@rock-chips.com>
Message-ID: <20150825163304.GC12878@sirena.org.uk>

On Tue, Aug 25, 2015 at 03:52:41PM +0800, Xing Zheng wrote:
> 
> Hi,
> Being careless, judge the return value of snd_soc_card_jack_new
> is opposite, so it should be fixed.

Please don't send cover letters for single patches, if there is anything
useful it should either be in the changelog or after the --- in the
patch.
-------------- next part --------------
A non-text attachment was scrubbed...
Name: signature.asc
Type: application/pgp-signature
Size: 473 bytes
Desc: Digital signature
URL: <http://lists.infradead.org/pipermail/linux-arm-kernel/attachments/20150825/08a5037f/attachment.sig>

From rmk+kernel at arm.linux.org.uk  Tue Aug 25 09:37:49 2015
From: rmk+kernel at arm.linux.org.uk (Russell King)
Date: Tue, 25 Aug 2015 17:37:49 +0100
Subject: [PATCH v2 11/10] ARM: fix swp-emulate
In-Reply-To: <20150825154026.GT7557@n2100.arm.linux.org.uk>
References: <20150825154026.GT7557@n2100.arm.linux.org.uk>
Message-ID: <E1ZUHEL-000337-7Q@rmk-PC.arm.linux.org.uk>

Signed-off-by: Russell King <rmk+kernel at arm.linux.org.uk>
---
Local testing found this direct userspace access from the kernel.  I'll
be rolling this into patch 10 tomorrow, but for the time being I'm adding
it on top of the set.

 arch/arm/kernel/swp_emulate.c | 3 +++
 1 file changed, 3 insertions(+)

diff --git a/arch/arm/kernel/swp_emulate.c b/arch/arm/kernel/swp_emulate.c
index 1361756782c7..5b26e7efa9ea 100644
--- a/arch/arm/kernel/swp_emulate.c
+++ b/arch/arm/kernel/swp_emulate.c
@@ -141,11 +141,14 @@ static int emulate_swpX(unsigned int address, unsigned int *data,
 
 	while (1) {
 		unsigned long temp;
+		unsigned int __ua_flags;
 
+		__ua_flags = uaccess_save_and_enable();
 		if (type == TYPE_SWPB)
 			__user_swpb_asm(*data, address, res, temp);
 		else
 			__user_swp_asm(*data, address, res, temp);
+		uaccess_restore(__ua_flags);
 
 		if (likely(res != -EAGAIN) || signal_pending(current))
 			break;
-- 
2.1.0



From peter.griffin at linaro.org  Tue Aug 25 09:49:04 2015
From: peter.griffin at linaro.org (Peter Griffin)
Date: Tue, 25 Aug 2015 17:49:04 +0100
Subject: [PATCH v2 05/11] ARM: DT: STi: STiH407: Add c8sectpfe LinuxDVB
 DT node.
In-Reply-To: <20150817115242.4ae9a51e@recife.lan>
References: <1438276141-16902-1-git-send-email-peter.griffin@linaro.org>
 <1438276141-16902-6-git-send-email-peter.griffin@linaro.org>
 <20150817115242.4ae9a51e@recife.lan>
Message-ID: <20150825164904.GB13253@griffinp-ThinkPad-X1-Carbon-2nd>

Hi Mauro,

On Mon, 17 Aug 2015, Mauro Carvalho Chehab wrote:

> Em Thu, 30 Jul 2015 18:08:55 +0100
> Peter Griffin <peter.griffin at linaro.org> escreveu:
> 
> > This patch adds in the required DT node for the c8sectpfe
> > Linux DVB demux driver which allows the tsin channels
> > to be used on an upstream kernel.
> > 
> > Signed-off-by: Peter Griffin <peter.griffin at linaro.org>
> > ---
> >  arch/arm/boot/dts/stihxxx-b2120.dtsi | 38 ++++++++++++++++++++++++++++++++++++
> >  1 file changed, 38 insertions(+)
> > 
> > diff --git a/arch/arm/boot/dts/stihxxx-b2120.dtsi b/arch/arm/boot/dts/stihxxx-b2120.dtsi
> > index 62994ae..1bc018e 100644
> > --- a/arch/arm/boot/dts/stihxxx-b2120.dtsi
> > +++ b/arch/arm/boot/dts/stihxxx-b2120.dtsi
> > @@ -6,6 +6,10 @@
> >   * it under the terms of the GNU General Public License version 2 as
> >   * published by the Free Software Foundation.
> >   */
> > +
> > +#include <dt-bindings/clock/stih407-clks.h>
> > +#include <dt-bindings/media/c8sectpfe.h>
> > +
> >  / {
> >  	soc {
> >  		sbc_serial0: serial at 9530000 {
> > @@ -85,5 +89,39 @@
> >  			status = "okay";
> >  		};
> >  
> > +		c8sectpfe at 08a20000 {
> > +			compatible = "st,stih407-c8sectpfe";
> > +			status = "okay";
> > +			reg = <0x08a20000 0x10000>, <0x08a00000 0x4000>;
> > +			reg-names = "c8sectpfe", "c8sectpfe-ram";
> > +
> > +			interrupts = <0 34 0>, <0 35 0>;
> > +			interrupt-names = "c8sectpfe-error-irq",
> > +					  "c8sectpfe-idle-irq";
> > +
> > +			pinctrl-names	= "tsin0-serial", "tsin0-parallel",
> > +					  "tsin3-serial", "tsin4-serial",
> > +					  "tsin5-serial";
> > +
> > +			pinctrl-0	= <&pinctrl_tsin0_serial>;
> > +			pinctrl-1	= <&pinctrl_tsin0_parallel>;
> > +			pinctrl-2	= <&pinctrl_tsin3_serial>;
> > +			pinctrl-3	= <&pinctrl_tsin4_serial_alt3>;
> > +			pinctrl-4	= <&pinctrl_tsin5_serial_alt1>;
> > +
> > +			clocks = <&clk_s_c0_flexgen CLK_PROC_STFE>;
> > +			clock-names = "c8sectpfe";
> > +
> > +			/* tsin0 is TSA on NIMA */
> > +			tsin0: port at 0 {
> > +
> > +				tsin-num = <0>;
> > +				serial-not-parallel;
> > +				i2c-bus = <&ssc2>;
> 
> There's no ssc2 defined at the device tree.

Whoops, I missed one patch off from the series in v2.
> 
> I'll revert this patch and mark the driver as broken until this gets
> fixed.

I just sent you another series here https://lkml.org/lkml/2015/8/25/499
which includes this patch, and also the patch which adds ssc2/3, along
with a fix to the Kconfig file spotted by Valentin Rothberg.

regards,

Peter.


From keescook at chromium.org  Tue Aug 25 09:50:11 2015
From: keescook at chromium.org (Kees Cook)
Date: Tue, 25 Aug 2015 09:50:11 -0700
Subject: [PATCH] ARM: probes: Don't stop the machine if we're in the
 debugger
In-Reply-To: <55DBB48E.7040508@codeaurora.org>
References: <1440460739-19522-1-git-send-email-dianders@chromium.org>
 <55DBB48E.7040508@codeaurora.org>
Message-ID: <CAGXu5j+oExmQPR9UuJy8oVaL_DzZ70kSP6ftS+ZhyFSs7hyxsA@mail.gmail.com>

On Mon, Aug 24, 2015 at 5:19 PM, Stephen Boyd <sboyd at codeaurora.org> wrote:
> On 08/24/2015 04:58 PM, Douglas Anderson wrote:
>>
>> If we're in kgdb then the machine is already stopped.  Trying to stop
>> it again will cause us to try to sleep, which is not allowed while in
>> kgdb.  To avoid this problem, only stop the machine when we're not in
>> kgdb.
>>
>> Reported-by: Aapo Vienamo <avienamo at nvidia.com>
>> Suggested-by: Kees Cook <keescook at chromium.org>

I actually suggested using in_atomic_preempt_off() which is I think a
better catch-all. Could you use that instead, please?

-Kees

>> Signed-off-by: Douglas Anderson <dianders at chromium.org>
>> ---
>
>
> Can you add the backtrace?
>
>>   arch/arm/kernel/patch.c | 7 ++++++-
>>   1 file changed, 6 insertions(+), 1 deletion(-)
>>
>> diff --git a/arch/arm/kernel/patch.c b/arch/arm/kernel/patch.c
>> index 69bda1a..abf30ec 100644
>> --- a/arch/arm/kernel/patch.c
>> +++ b/arch/arm/kernel/patch.c
>> @@ -1,5 +1,6 @@
>>   #include <linux/kernel.h>
>>   #include <linux/spinlock.h>
>> +#include <linux/kgdb.h>
>>   #include <linux/kprobes.h>
>>   #include <linux/mm.h>
>>   #include <linux/stop_machine.h>
>> @@ -124,6 +125,9 @@ void __kprobes patch_text(void *addr, unsigned int
>> insn)
>>                 .insn = insn,
>>         };
>>   -     stop_machine(patch_text_stop_machine, &patch, NULL);
>> +       /* Stop machine before patching; but not if in the debugger */
>> +       if (unlikely(in_dbg_master()))
>> +               patch_text_stop_machine(&patch);
>> +       else
>> +               stop_machine(patch_text_stop_machine, &patch, NULL);
>>   }
>
>
> Perhaps it would be better to add a different function for the kgdb call
> site? Then it's explicit what's going on without us having to figure out
> when in_dbg_master() is true.
>
> --
> Qualcomm Innovation Center, Inc. is a member of Code Aurora Forum,
> a Linux Foundation Collaborative Project
>



-- 
Kees Cook
Chrome OS Security


From will.deacon at arm.com  Tue Aug 25 09:53:26 2015
From: will.deacon at arm.com (Will Deacon)
Date: Tue, 25 Aug 2015 17:53:26 +0100
Subject: [PATCH v2 10/10] ARM: software-based priviledged-no-access support
In-Reply-To: <E1ZUGMS-0000BG-8B@rmk-PC.arm.linux.org.uk>
References: <20150825154026.GT7557@n2100.arm.linux.org.uk>
 <E1ZUGMS-0000BG-8B@rmk-PC.arm.linux.org.uk>
Message-ID: <20150825165326.GL21300@arm.com>

Hi Russell,

On Tue, Aug 25, 2015 at 04:42:08PM +0100, Russell King wrote:
> Provide a software-based implementation of the priviledged no access
> support found in ARMv8.1.
> 
> Userspace pages are mapped using a different domain number from the
> kernel and IO mappings.  If we switch the user domain to "no access"
> when we enter the kernel, we can prevent the kernel from touching
> userspace.
> 
> However, the kernel needs to be able to access userspace via the
> various user accessor functions.  With the wrapping in the previous
> patch, we can temporarily enable access when the kernel needs user
> access, and re-disable it afterwards.
> 
> This allows us to trap non-intended accesses to userspace, eg, caused
> by an inadvertent dereference of the LIST_POISON* values, which, with
> appropriate user mappings setup, can be made to succeed.  This in turn
> can allow use-after-free bugs to be further exploited than would
> otherwise be possible.
> 
> Signed-off-by: Russell King <rmk+kernel at arm.linux.org.uk>
> ---
>  arch/arm/Kconfig                   | 15 +++++++++++++++
>  arch/arm/include/asm/assembler.h   | 30 ++++++++++++++++++++++++++++++
>  arch/arm/include/asm/domain.h      | 21 +++++++++++++++++++--
>  arch/arm/include/asm/uaccess.h     | 14 ++++++++++++++
>  arch/arm/kernel/process.c          | 24 ++++++++++++++++++------
>  arch/arm/lib/csumpartialcopyuser.S | 14 ++++++++++++++
>  6 files changed, 110 insertions(+), 8 deletions(-)
> 
> diff --git a/arch/arm/Kconfig b/arch/arm/Kconfig
> index a750c1425c3a..a898eb72da51 100644
> --- a/arch/arm/Kconfig
> +++ b/arch/arm/Kconfig
> @@ -1694,6 +1694,21 @@ config HIGHPTE
>  	bool "Allocate 2nd-level pagetables from highmem"
>  	depends on HIGHMEM
>  
> +config CPU_SW_DOMAIN_PAN
> +	bool "Enable use of CPU domains to implement priviledged no-access"

Minor comment, but you've consistently misspelt "privileged".

Anyway, I tried this on my TC2 board running Debian Jessie armhf and,
whilst it boots to a shell on the console, ssh connections appear to
hang on the client before even trying to auth. I don't see anything
like a domain fault and the machine is still responsive on the console.
Disabling this option gets things working again for me.

Note that I *do* see undefined instruction exceptions from sshd
regardless of this patch, however I think they're triggered from
something like libcrypto which is prepared to handle the SIGILL.

FWIW, I'm using your ten patches from this series on top of 4.2-rc8 and
I've put the .config here:

  http://www.willdeacon.ukfsn.org/bitbucket/oopsen/pan/pan-tc2.config

Will


From nschichan at freebox.fr  Tue Aug 25 10:07:39 2015
From: nschichan at freebox.fr (Nicolas Schichan)
Date: Tue, 25 Aug 2015 19:07:39 +0200
Subject: [PATCH v2 10/10] ARM: software-based priviledged-no-access support
In-Reply-To: <E1ZUGMS-0000BG-8B@rmk-PC.arm.linux.org.uk>
References: <20150825154026.GT7557@n2100.arm.linux.org.uk>
 <E1ZUGMS-0000BG-8B@rmk-PC.arm.linux.org.uk>
Message-ID: <55DCA0DB.7000103@freebox.fr>

On 08/25/2015 05:42 PM, Russell King wrote:
> Provide a software-based implementation of the priviledged no access
> support found in ARMv8.1.
[...]
> diff --git a/arch/arm/include/asm/assembler.h b/arch/arm/include/asm/assembler.h
> index a91177043467..ff74f0b54b0e 100644
> --- a/arch/arm/include/asm/assembler.h
> +++ b/arch/arm/include/asm/assembler.h
> @@ -446,15 +446,45 @@ THUMB(	orr	\reg , \reg , #PSR_T_BIT	)
>  	.endm
>  
>  	.macro	uaccess_disable, tmp, isb=1
> +#ifdef CONFIG_CPU_SW_DOMAIN_PAN
> +	/*
> +	 * Whenever we re-enter userspace, the domains should always be
> +	 * set appropriately.
> +	 */
> +	mov	\tmp, #DACR_UACCESS_DISABLE
> +	mcr	p15, 0, \tmp, c3, c0, 0		@ Set domain register
> +	.if	\isb
> +	isb
> +	.endif
> +#endif
>  	.endm
>  
>  	.macro	uaccess_enable, tmp, isb=1
> +#ifdef CONFIG_CPU_SW_DOMAIN_PAN
> +	/*
> +	 * Whenever we re-enter userspace, the domains should always be
> +	 * set appropriately.
> +	 */
> +	mov	\tmp, #DACR_UACCESS_ENABLE
> +	mcr	p15, 0, \tmp, c3, c0, 0
> +	.if	\isb
> +	isb
> +	.endif
> +#endif
>  	.endm

Thanks for the updated serie,

on ARMv5, I get the following compile error:

arch/arm/kernel/entry-common.S: Assembler messages:
arch/arm/kernel/entry-common.S:200: Error: selected processor does not support
ARM mode `isb'

replacing those two "isb" occurences with "instr_sync" fixed it.

With that added access to LIST_POISON are still correctly catched, when
CONFIG_CPU_SW_DOMAIN_PAN is set. Also the transmit of an ipv6 packet does not
result in a fault anymore. Also with CONFIG_CPU_SW_DOMAIN_PAN disabled, the
system now boots fine.

This has been tested on Linux 4.1 / kirkwood and Linux 4.2-rc8 / qemu,armv5.

Thanks,

-- 
Nicolas Schichan
Freebox SAS


From peter.griffin at linaro.org  Tue Aug 25 10:08:40 2015
From: peter.griffin at linaro.org (Peter Griffin)
Date: Tue, 25 Aug 2015 18:08:40 +0100
Subject: [PATCH 1/7] dmaengine: st_fdma: Add STMicroelectronics FDMA DT
 binding documentation
In-Reply-To: <20150819150605.GA13546@localhost>
References: <1436371888-27863-1-git-send-email-peter.griffin@linaro.org>
 <1436371888-27863-2-git-send-email-peter.griffin@linaro.org>
 <20150819150605.GA13546@localhost>
Message-ID: <20150825170840.GA1498@griffinp-ThinkPad-X1-Carbon-2nd>

Hi Vinod,

Thanks for reviewing.

On Wed, 19 Aug 2015, Vinod Koul wrote:

> On Wed, Jul 08, 2015 at 05:11:22PM +0100, Peter Griffin wrote:
> > This patch adds the DT binding documentation for the FDMA constroller
> > found on STi based chipsets from STMicroelectronics.
> > 
> > Signed-off-by: Ludovic Barre <ludovic.barre at st.com>
> > Signed-off-by: Peter Griffin <peter.griffin at linaro.org>
> > ---
> >  Documentation/devicetree/bindings/dma/st_fdma.txt | 76 +++++++++++++++++++++++
> >  1 file changed, 76 insertions(+)
> >  create mode 100644 Documentation/devicetree/bindings/dma/st_fdma.txt
> > 
> > diff --git a/Documentation/devicetree/bindings/dma/st_fdma.txt b/Documentation/devicetree/bindings/dma/st_fdma.txt
> > new file mode 100644
> > index 0000000..1ec7470
> > --- /dev/null
> > +++ b/Documentation/devicetree/bindings/dma/st_fdma.txt
> > @@ -0,0 +1,76 @@
> > +* STMicroelectronics Flexible Direct Memory Access Device Tree bindings
> > +
> > +The FDMA is a general-purpose direct memory access controller capable of
> > +supporting 16 independent DMA channels. It accepts up to 32 DMA requests.
> > +The FDMA is based on a Slim processor which require a firmware.
> > +
> > +* FDMA Controller
> > +
> > +Required properties:
> > +- compatible	: Should be "st,fdma_mpe31"
> > +- reg		: Should contain DMA registers location and length
> > +- interrupts	: Should contain one interrupt shared by all channel
> 
> s/channel/channels

Will fix in v2.

> 
> > +- dma-channels	: Number of channels supported by the controller
> > +- #dma-cells	: Must be <3>.
> 
> any reason three?

Yes, it is documented further down in the file under DMA Client.

To make it clearer in V2 I could change to

"- #dma-cells	: Must be <3>. See DMA client section below"?

regards,

Peter.


From olof at lixom.net  Tue Aug 25 10:16:24 2015
From: olof at lixom.net (Olof Johansson)
Date: Tue, 25 Aug 2015 10:16:24 -0700
Subject: [GIT PULL 1/2] Rockchip dts fixes for 4.3
In-Reply-To: <1879932.6Bpqy7C2KO@phil>
References: <1879932.6Bpqy7C2KO@phil>
Message-ID: <CAOesGMgcDkj3EpT9owhtgMaG7TeFr8BhRCQ4dCTwHDG3_Uva6w@mail.gmail.com>

On Tue, Aug 25, 2015 at 2:25 AM, Heiko Stuebner <heiko at sntech.de> wrote:
> Hi Arnd, Kevin, Olof
>
> Brian found two issues with regulator suspend-properties of the newly
> added veyron boards, so please pull these fixes on top.
>
>
> Thanks
> Heiko
>
> The following changes since commit 378abcdf3297613f6712343ce3a79b7d6abdf955:
>
>   ARM: dts: rockchip: add veyron-minnie board (2015-08-08 12:31:27 +0200)
>
> are available in the git repository at:
>
>   git://git.kernel.org/pub/scm/linux/kernel/git/mmind/linux-rockchip.git tags/v4.3-rockchip32-dts3
>
> for you to fetch changes up to 467fb18a8d538be6548ef4093003b63aebbb07b9:
>
>   ARM: dts: rockchip: correct regulator power states for suspend (2015-08-21 01:40:35 +0200)

Merged, thanks!

-Olof


From olof at lixom.net  Tue Aug 25 10:17:38 2015
From: olof at lixom.net (Olof Johansson)
Date: Tue, 25 Aug 2015 10:17:38 -0700
Subject: [GIT PULL 2/2] Rockchip soc fix for 4.3
In-Reply-To: <9416843.VhjrryKIms@phil>
References: <1879932.6Bpqy7C2KO@phil>
	<9416843.VhjrryKIms@phil>
Message-ID: <CAOesGMiVy5F-EJFCyj5LLKCGUWNZGenrK6AhbjubfBADXMxE_A@mail.gmail.com>

On Tue, Aug 25, 2015 at 2:30 AM, Heiko Stuebner <heiko at sntech.de> wrote:
> Hi Arnd, Kevin, Olof,
>
> Fabio did find an error in what is returned as error codes in the init of
> the suspend code. Nobody complained about this actually breaking stuff
> but it would be nice to have this fixed nevertheless, so please pull.
>
>
> Thanks
> Heiko
>
>
> The following changes since commit 9bb91ae970dd004393a3d7d09bdcc30dfe2f8693:
>
>   ARM: rockchip: enable PMU_GPIOINT_WAKEUP_EN when entering shallow suspend (2015-08-06 13:05:14 +0200)
>
> are available in the git repository at:
>
>   git://git.kernel.org/pub/scm/linux/kernel/git/mmind/linux-rockchip.git tags/v4.3-rockchip32-soc3
>
> for you to fetch changes up to 2a03c025fdea25a491c359b31d8a8c8d452b06d0:
>
>   ARM: rockchip: pm: Fix PTR_ERR() argument (2015-08-24 12:39:14 +0200)

Merged, thanks.


-Olof


From marc.zyngier at arm.com  Tue Aug 25 10:18:51 2015
From: marc.zyngier at arm.com (Marc Zyngier)
Date: Tue, 25 Aug 2015 18:18:51 +0100
Subject: [PATCH v3 3/4] irqchip: GIC: Convert to EOImode == 1
In-Reply-To: <alpine.DEB.2.11.1508251745070.15006@nanos>
References: <1440503605-10185-1-git-send-email-marc.zyngier@arm.com>
 <1440503605-10185-4-git-send-email-marc.zyngier@arm.com>
 <alpine.DEB.2.11.1508251745070.15006@nanos>
Message-ID: <55DCA37B.8030208@arm.com>

Hi Thomas,

On 25/08/15 16:46, Thomas Gleixner wrote:
> On Tue, 25 Aug 2015, Marc Zyngier wrote:
>> +static struct static_key supports_deactivate = STATIC_KEY_INIT_TRUE;
>> +
>>  #ifndef MAX_GIC_NR
>>  #define MAX_GIC_NR	1
>>  #endif
>> @@ -137,6 +140,14 @@ static inline unsigned int gic_irq(struct irq_data *d)
>>  	return d->hwirq;
>>  }
>>  
>> +static inline bool primary_gic_irq(struct irq_data *d)
>> +{
>> +	if (MAX_GIC_NR > 1)
>> +		return irq_data_get_irq_chip_data(d) == &gic_data[0];
>> +
>> +	return true;
>> +}
>> +
>>  /*
>>   * Routines to acknowledge, disable and enable interrupts
>>   */
>> @@ -164,7 +175,14 @@ static void gic_unmask_irq(struct irq_data *d)
>>  
>>  static void gic_eoi_irq(struct irq_data *d)
>>  {
>> -	writel_relaxed(gic_irq(d), gic_cpu_base(d) + GIC_CPU_EOI);
>> +	u32 deact_offset = GIC_CPU_EOI;
>> +
>> +	if (static_key_true(&supports_deactivate)) {
>> +		if (primary_gic_irq(d))
>> +			deact_offset = GIC_CPU_DEACTIVATE;
> 
> I really wonder for the whole series whether you really want all that
> static key dance and extra conditionals in the callbacks instead of
> just using seperate irq chips for the different interrupts.

Hmmm. We definitely could have different irqchips between primary and
secondary controllers indeed. We'd still need a static key for the
gic_handle_irq path though, but that's not too bad.

Let me hack something, and I'll come back to you ;-).

	M.
-- 
Jazz is not dead. It just smells funny...


From olof at lixom.net  Fri Aug 21 10:16:40 2015
From: olof at lixom.net (Olof Johansson)
Date: Fri, 21 Aug 2015 10:16:40 -0700
Subject: [GIT PULL 8/9] ARM: tegra: Devicetree changes for v4.3-rc1
 (updated)
In-Reply-To: <1440175939-13663-1-git-send-email-thierry.reding@gmail.com>
References: <1439563720-13189-9-git-send-email-thierry.reding@gmail.com>
 <1440175939-13663-1-git-send-email-thierry.reding@gmail.com>
Message-ID: <20150821171640.GA31493@localhost>

On Fri, Aug 21, 2015 at 06:52:19PM +0200, Thierry Reding wrote:
> Hi ARM SoC maintainers,
> 
> The following changes since commit d770e558e21961ad6cfdf0ff7df0eb5d7d4f0754:
> 
>   Linux 4.2-rc1 (2015-07-05 11:01:52 -0700)
> 
> are available in the git repository at:
> 
>   git://git.kernel.org/pub/scm/linux/kernel/git/tegra/linux.git tags/tegra-for-4.3-dt
> 
> for you to fetch changes up to 17cdddf0fb684f5456c1af3aa2c10aca3b68b8de:
> 
>   ARM: tegra: Add gpio-ranges property (2015-08-21 18:44:28 +0200)
> 
> This updated version of the pull request includes the for-4.3/clk branch
> which is a build-time dependency for for-4.3/dt.

Merged, thanks.


-Olof



From Suravee.Suthikulpanit at amd.com  Tue Aug 25 10:33:25 2015
From: Suravee.Suthikulpanit at amd.com (Suravee Suthikulpanit)
Date: Wed, 26 Aug 2015 00:33:25 +0700
Subject: [PATCH V2 0/4] PCI: ACPI: Setting up DMA coherency for PCI device
 from _CCA attribute
Message-ID: <1440524009-5359-1-git-send-email-Suravee.Suthikulpanit@amd.com>

This patch adds support to setup DMA coherency for PCI device using
the ACPI _CCA attribute. According to the ACPI spec, the _CCA attribute
is required for ARM64. Therefore, this patch is a pre-req for ACPI PCI
support for ARM64 which is currently in development.

Also, this should not affect other architectures that does not define 
CONFIG_ACPI_CCA_REQUIRED, since the default value is coherent.

In the V2 of this patch series, I have pulled in the following patch from Jeremy
before cleaning up the acpi_check_dma() function (in patch 2).

    http://www.spinics.net/lists/linux-usb/msg128582.html)

Changes from V1: (https://lkml.org/lkml/2015/8/13/182)
    * Include patch 1 from Jeremy to enable support for _CCA=0
    * Clean up acpi_check_dma() per Bjorn suggestions
    * Split the original V1 patch into two patches (patch 3 and 4)

Jeremy Linton (1):
  Honor ACPI _CCA attribute setting

Suravee Suthikulpanit (3):
  ACPI/scan: Clean up acpi_check_dma
  PCI: OF: Move of_pci_dma_configure() to pci_dma_configure()
  PCI: ACPI: Add support for PCI device DMA coherency

 drivers/acpi/acpi_platform.c |  7 ++++++-
 drivers/acpi/glue.c          |  5 +++--
 drivers/acpi/scan.c          | 39 +++++++++++++++++++++++++++++++++++++++
 drivers/base/property.c      |  8 ++++++--
 drivers/of/of_pci.c          | 20 --------------------
 drivers/pci/probe.c          | 32 ++++++++++++++++++++++++++++++--
 include/acpi/acpi_bus.h      | 35 ++---------------------------------
 include/linux/acpi.h         |  4 ++--
 include/linux/of_pci.h       |  3 ---
 9 files changed, 88 insertions(+), 65 deletions(-)

-- 
2.1.0



From Suravee.Suthikulpanit at amd.com  Tue Aug 25 10:33:26 2015
From: Suravee.Suthikulpanit at amd.com (Suravee Suthikulpanit)
Date: Wed, 26 Aug 2015 00:33:26 +0700
Subject: [PATCH V2 1/4] Honor ACPI _CCA attribute setting
In-Reply-To: <1440524009-5359-1-git-send-email-Suravee.Suthikulpanit@amd.com>
References: <1440524009-5359-1-git-send-email-Suravee.Suthikulpanit@amd.com>
Message-ID: <1440524009-5359-2-git-send-email-Suravee.Suthikulpanit@amd.com>

From: Jeremy Linton <jeremy.linton at arm.com>

ACPI configurations can now mark devices as noncoherent,
support that choice.

NOTE: This is required to support USB on ARM Juno Development Board.

Signed-off-by: Jeremy Linton <jeremy.linton at arm.com>
Signed-off-by: Suravee Suthikulpanit <Suravee.Suthikulpanit at amd.com>
CC: Bjorn Helgaas <bhelgaas at google.com>
CC: Catalin Marinas <catalin.marinas at arm.com>
CC: Rob Herring <robh+dt at kernel.org>
CC: Will Deacon <will.deacon at arm.com>
CC: Rafael J. Wysocki <rjw at rjwysocki.net>
---
 include/acpi/acpi_bus.h | 5 +++--
 1 file changed, 3 insertions(+), 2 deletions(-)

diff --git a/include/acpi/acpi_bus.h b/include/acpi/acpi_bus.h
index 83061ca..7ecb8e4 100644
--- a/include/acpi/acpi_bus.h
+++ b/include/acpi/acpi_bus.h
@@ -399,7 +399,7 @@ static inline bool acpi_check_dma(struct acpi_device *adev, bool *coherent)
 	 * case 1. Do not support and disable DMA.
 	 * case 2. Support but rely on arch-specific cache maintenance for
 	 *         non-coherence DMA operations.
-	 * Currently, we implement case 1 above.
+	 * Currently, we implement case 2 above.
 	 *
 	 * For the case when _CCA is missing (i.e. cca_seen=0) and
 	 * platform specifies ACPI_CCA_REQUIRED, we do not support DMA,
@@ -407,7 +407,8 @@ static inline bool acpi_check_dma(struct acpi_device *adev, bool *coherent)
 	 *
 	 * See acpi_init_coherency() for more info.
 	 */
-	if (adev->flags.coherent_dma) {
+	if (adev->flags.coherent_dma ||
+	    (adev->flags.cca_seen && IS_ENABLED(CONFIG_ARM64))) {
 		ret = true;
 		if (coherent)
 			*coherent = adev->flags.coherent_dma;
-- 
2.1.0



From Suravee.Suthikulpanit at amd.com  Tue Aug 25 10:33:27 2015
From: Suravee.Suthikulpanit at amd.com (Suravee Suthikulpanit)
Date: Wed, 26 Aug 2015 00:33:27 +0700
Subject: [PATCH V2 2/4] ACPI/scan: Clean up acpi_check_dma
In-Reply-To: <1440524009-5359-1-git-send-email-Suravee.Suthikulpanit@amd.com>
References: <1440524009-5359-1-git-send-email-Suravee.Suthikulpanit@amd.com>
Message-ID: <1440524009-5359-3-git-send-email-Suravee.Suthikulpanit@amd.com>

The original name of acpi_check_dma() function does not clearly tell what
exactly it is checking. Also, returning two boolean values (one to indicate
device is DMA capability, and the other to inidicate device coherency
attribute) can be confusing.

So, in order to simplify the function, this patch renames acpi_check_dma()
to acpi_check_dma_coherency() to clearly indicate the purpose of this
function, and only returns an integer where -1 means DMA not supported,
1 means coherent DMA, and 0 means non-coherent DMA.

Also, this patch moves the function into drivers/acpi/scan.c since
it is easier to follow the logic in the acpi_init_coherency() in the
same file here.

Signed-off-by: Suravee Suthikulpanit <Suravee.Suthikulpanit at amd.com>
CC: Bjorn Helgaas <bhelgaas at google.com>
CC: Catalin Marinas <catalin.marinas at arm.com>
CC: Rob Herring <robh+dt at kernel.org>
CC: Will Deacon <will.deacon at arm.com>
CC: Rafael J. Wysocki <rjw at rjwysocki.net>
---
 drivers/acpi/acpi_platform.c |  7 ++++++-
 drivers/acpi/glue.c          |  5 +++--
 drivers/acpi/scan.c          | 39 +++++++++++++++++++++++++++++++++++++++
 drivers/base/property.c      |  8 ++++++--
 include/acpi/acpi_bus.h      | 36 ++----------------------------------
 include/linux/acpi.h         |  4 ++--
 6 files changed, 58 insertions(+), 41 deletions(-)

diff --git a/drivers/acpi/acpi_platform.c b/drivers/acpi/acpi_platform.c
index 06a67d5..2261e85 100644
--- a/drivers/acpi/acpi_platform.c
+++ b/drivers/acpi/acpi_platform.c
@@ -103,7 +103,12 @@ struct platform_device *acpi_create_platform_device(struct acpi_device *adev)
 	pdevinfo.res = resources;
 	pdevinfo.num_res = count;
 	pdevinfo.fwnode = acpi_fwnode_handle(adev);
-	pdevinfo.dma_mask = acpi_check_dma(adev, NULL) ? DMA_BIT_MASK(32) : 0;
+
+	if (-1 != acpi_check_dma_coherency(adev))
+		pdevinfo.dma_mask = DMA_BIT_MASK(32);
+	else
+		pdevinfo.dma_mask = 0;
+
 	pdev = platform_device_register_full(&pdevinfo);
 	if (IS_ERR(pdev))
 		dev_err(&adev->dev, "platform device creation failed: %ld\n",
diff --git a/drivers/acpi/glue.c b/drivers/acpi/glue.c
index b9657af..55cf916 100644
--- a/drivers/acpi/glue.c
+++ b/drivers/acpi/glue.c
@@ -168,7 +168,7 @@ int acpi_bind_one(struct device *dev, struct acpi_device *acpi_dev)
 	struct list_head *physnode_list;
 	unsigned int node_id;
 	int retval = -EINVAL;
-	bool coherent;
+	int coherent;
 
 	if (has_acpi_companion(dev)) {
 		if (acpi_dev) {
@@ -225,7 +225,8 @@ int acpi_bind_one(struct device *dev, struct acpi_device *acpi_dev)
 	if (!has_acpi_companion(dev))
 		ACPI_COMPANION_SET(dev, acpi_dev);
 
-	if (acpi_check_dma(acpi_dev, &coherent))
+	coherent = acpi_check_dma_coherency(acpi_dev);
+	if (coherent != -1)
 		arch_setup_dma_ops(dev, 0, 0, NULL, coherent);
 
 	acpi_physnode_link_name(physical_node_name, node_id);
diff --git a/drivers/acpi/scan.c b/drivers/acpi/scan.c
index ec25635..299a825 100644
--- a/drivers/acpi/scan.c
+++ b/drivers/acpi/scan.c
@@ -2182,6 +2182,45 @@ void acpi_free_pnp_ids(struct acpi_device_pnp *pnp)
 	kfree(pnp->unique_id);
 }
 
+/**
+ * acpi_check_dma_coherency - Check DMA coherency for the specified device.
+ * @adev: The pointer to acpi device to check coherency attribute
+ *
+ * Return -1 if DMA is not supported. Otherwise, return 1 if the
+ * device support coherent DMA, or 0 for non-coherent DMA.
+ */
+int acpi_check_dma_coherency(struct acpi_device *adev)
+{
+	int ret = -1;
+
+	if (!adev)
+		return ret;
+
+	/**
+	 * Currently, we only support _CCA=1 (i.e. coherent_dma=1)
+	 * This should be equivalent to specifying dma-coherent for
+	 * a device in OF.
+	 *
+	 * For the case when _CCA=0 (i.e. coherent_dma=0 && cca_seen=1),
+	 * we have two choices:
+	 *   1. Do not support and disable DMA.
+	 *   2. Support but rely on arch-specific cache maintenance for
+	 *      non-coherenje DMA operations.
+	 * Currently, we implement case 2 above.
+	 *
+	 * For the case when _CCA is missing (i.e. cca_seen=0) and
+	 * platform specifies ACPI_CCA_REQUIRED, we do not support DMA,
+	 * and fallback to arch-specific default handling.
+	 *
+	 * See acpi_init_coherency() for more info.
+	 */
+	if (!adev->flags.cca_seen && IS_ENABLED(CONFIG_ACPI_CCA_REQUIRED))
+		return ret;
+
+	return adev->flags.coherent_dma;
+}
+EXPORT_SYMBOL_GPL(acpi_check_dma_coherency);
+
 static void acpi_init_coherency(struct acpi_device *adev)
 {
 	unsigned long long cca = 0;
diff --git a/drivers/base/property.c b/drivers/base/property.c
index f3f6d16..643b0fb 100644
--- a/drivers/base/property.c
+++ b/drivers/base/property.c
@@ -527,8 +527,12 @@ bool device_dma_is_coherent(struct device *dev)
 
 	if (IS_ENABLED(CONFIG_OF) && dev->of_node)
 		coherent = of_dma_is_coherent(dev->of_node);
-	else
-		acpi_check_dma(ACPI_COMPANION(dev), &coherent);
+	else {
+		int ac = acpi_check_dma_coherency(ACPI_COMPANION(dev));
+
+		if (ac != -1)
+			coherent = ac;
+	}
 
 	return coherent;
 }
diff --git a/include/acpi/acpi_bus.h b/include/acpi/acpi_bus.h
index 7ecb8e4..baf43ea 100644
--- a/include/acpi/acpi_bus.h
+++ b/include/acpi/acpi_bus.h
@@ -382,40 +382,6 @@ struct acpi_device {
 	void (*remove)(struct acpi_device *);
 };
 
-static inline bool acpi_check_dma(struct acpi_device *adev, bool *coherent)
-{
-	bool ret = false;
-
-	if (!adev)
-		return ret;
-
-	/**
-	 * Currently, we only support _CCA=1 (i.e. coherent_dma=1)
-	 * This should be equivalent to specifyig dma-coherent for
-	 * a device in OF.
-	 *
-	 * For the case when _CCA=0 (i.e. coherent_dma=0 && cca_seen=1),
-	 * There are two cases:
-	 * case 1. Do not support and disable DMA.
-	 * case 2. Support but rely on arch-specific cache maintenance for
-	 *         non-coherence DMA operations.
-	 * Currently, we implement case 2 above.
-	 *
-	 * For the case when _CCA is missing (i.e. cca_seen=0) and
-	 * platform specifies ACPI_CCA_REQUIRED, we do not support DMA,
-	 * and fallback to arch-specific default handling.
-	 *
-	 * See acpi_init_coherency() for more info.
-	 */
-	if (adev->flags.coherent_dma ||
-	    (adev->flags.cca_seen && IS_ENABLED(CONFIG_ARM64))) {
-		ret = true;
-		if (coherent)
-			*coherent = adev->flags.coherent_dma;
-	}
-	return ret;
-}
-
 static inline bool is_acpi_node(struct fwnode_handle *fwnode)
 {
 	return fwnode && fwnode->type == FWNODE_ACPI;
@@ -640,6 +606,8 @@ static inline bool acpi_device_can_poweroff(struct acpi_device *adev)
 	return adev->power.states[ACPI_STATE_D3_COLD].flags.valid;
 }
 
+int acpi_check_dma_coherency(struct acpi_device *adev);
+
 #else	/* CONFIG_ACPI */
 
 static inline int register_acpi_bus_type(void *bus) { return 0; }
diff --git a/include/linux/acpi.h b/include/linux/acpi.h
index d2445fa..530d2fa 100644
--- a/include/linux/acpi.h
+++ b/include/linux/acpi.h
@@ -562,9 +562,9 @@ static inline int acpi_device_modalias(struct device *dev,
 	return -ENODEV;
 }
 
-static inline bool acpi_check_dma(struct acpi_device *adev, bool *coherent)
+static inline int acpi_check_dma_coherency(struct acpi_device *adev)
 {
-	return false;
+	return -1;
 }
 
 #define ACPI_PTR(_ptr)	(NULL)
-- 
2.1.0



From Suravee.Suthikulpanit at amd.com  Tue Aug 25 10:33:28 2015
From: Suravee.Suthikulpanit at amd.com (Suravee Suthikulpanit)
Date: Wed, 26 Aug 2015 00:33:28 +0700
Subject: [PATCH V2 3/4] PCI: OF: Move of_pci_dma_configure() to
 pci_dma_configure()
In-Reply-To: <1440524009-5359-1-git-send-email-Suravee.Suthikulpanit@amd.com>
References: <1440524009-5359-1-git-send-email-Suravee.Suthikulpanit@amd.com>
Message-ID: <1440524009-5359-4-git-send-email-Suravee.Suthikulpanit@amd.com>

This patch move of_pci_dma_configure() to a more generic
pci_dma_configure(), which can be extended by non-OF code (e.g. ACPI).

This has no functional change.

Signed-off-by: Suravee Suthikulpanit <Suravee.Suthikulpanit at amd.com>
CC: Bjorn Helgaas <bhelgaas at google.com>
CC: Catalin Marinas <catalin.marinas at arm.com>
CC: Rob Herring <robh+dt at kernel.org>
CC: Will Deacon <will.deacon at arm.com>
CC: Rafael J. Wysocki <rjw at rjwysocki.net>
CC: Murali Karicheri <m-karicheri2 at ti.com>
---
 drivers/of/of_pci.c    | 20 --------------------
 drivers/pci/probe.c    | 27 +++++++++++++++++++++++++--
 include/linux/of_pci.h |  3 ---
 3 files changed, 25 insertions(+), 25 deletions(-)

diff --git a/drivers/of/of_pci.c b/drivers/of/of_pci.c
index 5751dc5..b66ee4e 100644
--- a/drivers/of/of_pci.c
+++ b/drivers/of/of_pci.c
@@ -117,26 +117,6 @@ int of_get_pci_domain_nr(struct device_node *node)
 }
 EXPORT_SYMBOL_GPL(of_get_pci_domain_nr);
 
-/**
- * of_pci_dma_configure - Setup DMA configuration
- * @dev: ptr to pci_dev struct of the PCI device
- *
- * Function to update PCI devices's DMA configuration using the same
- * info from the OF node of host bridge's parent (if any).
- */
-void of_pci_dma_configure(struct pci_dev *pci_dev)
-{
-	struct device *dev = &pci_dev->dev;
-	struct device *bridge = pci_get_host_bridge_device(pci_dev);
-
-	if (!bridge->parent)
-		return;
-
-	of_dma_configure(dev, bridge->parent->of_node);
-	pci_put_host_bridge_device(bridge);
-}
-EXPORT_SYMBOL_GPL(of_pci_dma_configure);
-
 #if defined(CONFIG_OF_ADDRESS)
 /**
  * of_pci_get_host_bridge_resources - Parse PCI host bridge resources from DT
diff --git a/drivers/pci/probe.c b/drivers/pci/probe.c
index cefd636..4de6594 100644
--- a/drivers/pci/probe.c
+++ b/drivers/pci/probe.c
@@ -6,12 +6,14 @@
 #include <linux/delay.h>
 #include <linux/init.h>
 #include <linux/pci.h>
-#include <linux/of_pci.h>
+#include <linux/of_device.h>
 #include <linux/pci_hotplug.h>
 #include <linux/slab.h>
 #include <linux/module.h>
 #include <linux/cpumask.h>
 #include <linux/pci-aspm.h>
+#include <linux/acpi.h>
+#include <linux/property.h>
 #include <asm-generic/pci-bridge.h>
 #include "pci.h"
 
@@ -1544,6 +1546,27 @@ static void pci_init_capabilities(struct pci_dev *dev)
 	pci_enable_acs(dev);
 }
 
+/**
+ * pci_dma_configure - Setup DMA configuration
+ * @dev: ptr to pci_dev struct of the PCI device
+ *
+ * Function to update PCI devices's DMA configuration using the same
+ * info from the OF node of host bridge's parent (if any).
+ */
+static void pci_dma_configure(struct pci_dev *dev)
+{
+	struct device *bridge = pci_get_host_bridge_device(dev);
+
+	if (IS_ENABLED(CONFIG_OF) && dev->dev.of_node) {
+		if (!bridge->parent)
+			return;
+
+		of_dma_configure(&dev->dev, bridge->parent->of_node);
+	}
+
+	pci_put_host_bridge_device(bridge);
+}
+
 void pci_device_add(struct pci_dev *dev, struct pci_bus *bus)
 {
 	int ret;
@@ -1557,7 +1580,7 @@ void pci_device_add(struct pci_dev *dev, struct pci_bus *bus)
 	dev->dev.dma_mask = &dev->dma_mask;
 	dev->dev.dma_parms = &dev->dma_parms;
 	dev->dev.coherent_dma_mask = 0xffffffffull;
-	of_pci_dma_configure(dev);
+	pci_dma_configure(dev);
 
 	pci_set_dma_max_seg_size(dev, 65536);
 	pci_set_dma_seg_boundary(dev, 0xffffffff);
diff --git a/include/linux/of_pci.h b/include/linux/of_pci.h
index 29fd3fe..ce0e5ab 100644
--- a/include/linux/of_pci.h
+++ b/include/linux/of_pci.h
@@ -16,7 +16,6 @@ int of_pci_get_devfn(struct device_node *np);
 int of_irq_parse_and_map_pci(const struct pci_dev *dev, u8 slot, u8 pin);
 int of_pci_parse_bus_range(struct device_node *node, struct resource *res);
 int of_get_pci_domain_nr(struct device_node *node);
-void of_pci_dma_configure(struct pci_dev *pci_dev);
 #else
 static inline int of_irq_parse_pci(const struct pci_dev *pdev, struct of_phandle_args *out_irq)
 {
@@ -51,8 +50,6 @@ of_get_pci_domain_nr(struct device_node *node)
 {
 	return -1;
 }
-
-static inline void of_pci_dma_configure(struct pci_dev *pci_dev) { }
 #endif
 
 #if defined(CONFIG_OF_ADDRESS)
-- 
2.1.0



From Suravee.Suthikulpanit at amd.com  Tue Aug 25 10:33:29 2015
From: Suravee.Suthikulpanit at amd.com (Suravee Suthikulpanit)
Date: Wed, 26 Aug 2015 00:33:29 +0700
Subject: [PATCH V2 4/4] PCI: ACPI: Add support for PCI device DMA coherency
In-Reply-To: <1440524009-5359-1-git-send-email-Suravee.Suthikulpanit@amd.com>
References: <1440524009-5359-1-git-send-email-Suravee.Suthikulpanit@amd.com>
Message-ID: <1440524009-5359-5-git-send-email-Suravee.Suthikulpanit@amd.com>

This patch adds support for setting up PCI device DMA coherency from
ACPI _CCA object that should normally be specified in the DSDT node
of its PCI host bridge.

Signed-off-by: Suravee Suthikulpanit <Suravee.Suthikulpanit at amd.com>
CC: Bjorn Helgaas <bhelgaas at google.com>
CC: Catalin Marinas <catalin.marinas at arm.com>
CC: Rob Herring <robh+dt at kernel.org>
CC: Will Deacon <will.deacon at arm.com>
CC: Rafael J. Wysocki <rjw at rjwysocki.net>
CC: Murali Karicheri <m-karicheri2 at ti.com>
---
 drivers/pci/probe.c | 15 ++++++++++-----
 1 file changed, 10 insertions(+), 5 deletions(-)

diff --git a/drivers/pci/probe.c b/drivers/pci/probe.c
index 4de6594..2fd2a60 100644
--- a/drivers/pci/probe.c
+++ b/drivers/pci/probe.c
@@ -1551,17 +1551,22 @@ static void pci_init_capabilities(struct pci_dev *dev)
  * @dev: ptr to pci_dev struct of the PCI device
  *
  * Function to update PCI devices's DMA configuration using the same
- * info from the OF node of host bridge's parent (if any).
+ * info from the OF node or ACPI node of host bridge's parent (if any).
  */
 static void pci_dma_configure(struct pci_dev *dev)
 {
 	struct device *bridge = pci_get_host_bridge_device(dev);
 
 	if (IS_ENABLED(CONFIG_OF) && dev->dev.of_node) {
-		if (!bridge->parent)
-			return;
-
-		of_dma_configure(&dev->dev, bridge->parent->of_node);
+		if (bridge->parent)
+			of_dma_configure(&dev->dev,
+					 bridge->parent->of_node);
+	} else if (has_acpi_companion(bridge)) {
+		struct acpi_device *adev = to_acpi_node(bridge->fwnode);
+		int coherent = acpi_check_dma_coherency(adev);
+
+		if (-1 != coherent)
+			arch_setup_dma_ops(&dev->dev, 0, 0, NULL, coherent);
 	}
 
 	pci_put_host_bridge_device(bridge);
-- 
2.1.0



From broonie at kernel.org  Tue Aug 25 10:47:21 2015
From: broonie at kernel.org (Mark Brown)
Date: Tue, 25 Aug 2015 18:47:21 +0100
Subject: [PATCH v3 2/4] spi: mediatek: replace int with u32, delete TAB
 and define MTK_SPI_PAUSE_INT_STATUS marco
In-Reply-To: <1440387918-22191-3-git-send-email-leilk.liu@mediatek.com>
References: <1440387918-22191-1-git-send-email-leilk.liu@mediatek.com>
 <1440387918-22191-3-git-send-email-leilk.liu@mediatek.com>
Message-ID: <20150825174721.GH12878@sirena.org.uk>

On Mon, Aug 24, 2015 at 11:45:16AM +0800, Leilk Liu wrote:

> this patch replaces int with u32, deletes TAB, and defines
> MTK_SPI_PAUSE_INT_STATUS marco.

You've listed three changes in one patch and they're not obviously
interrelated.  As has been said before one change per patch please :(
-------------- next part --------------
A non-text attachment was scrubbed...
Name: signature.asc
Type: application/pgp-signature
Size: 473 bytes
Desc: Digital signature
URL: <http://lists.infradead.org/pipermail/linux-arm-kernel/attachments/20150825/7b786396/attachment.sig>

From linux at arm.linux.org.uk  Tue Aug 25 10:48:41 2015
From: linux at arm.linux.org.uk (Russell King - ARM Linux)
Date: Tue, 25 Aug 2015 18:48:41 +0100
Subject: [PATCH v2 10/10] ARM: software-based priviledged-no-access support
In-Reply-To: <55DCA0DB.7000103@freebox.fr>
References: <20150825154026.GT7557@n2100.arm.linux.org.uk>
 <E1ZUGMS-0000BG-8B@rmk-PC.arm.linux.org.uk>
 <55DCA0DB.7000103@freebox.fr>
Message-ID: <20150825174841.GV7557@n2100.arm.linux.org.uk>

On Tue, Aug 25, 2015 at 07:07:39PM +0200, Nicolas Schichan wrote:
> arch/arm/kernel/entry-common.S: Assembler messages:
> arch/arm/kernel/entry-common.S:200: Error: selected processor does not support
> ARM mode `isb'
> 
> replacing those two "isb" occurences with "instr_sync" fixed it.

Thanks, that's exactly what I've done.  I've pushed that and the other
fixes out for linux-next to pick up, hopefully with fewer failures.

This series passed my own build tests (which included building and
booting SDP4430, LDP4430, Versatile Express and iMX6 platforms.)
Unfortunately, they're all Cortex-A8 or A9 platforms.

Olof's builder is showing some build failures in the boot log, but I'll
assume that they're down to the above - I don't yet have the build log,
and that's going to arrive at some point after I've left for a committee
meeting which will extend for most of the evening.  So, I'm hoping that
tonight's linux-next will see improvement rather than deterioration -
that's all I can do at this point... hope.  I'm out of time to do any
more build checking prior to linux-next pulling my tree.

-- 
FTTC broadband for 0.8mile line: currently at 10.5Mbps down 400kbps up
according to speedtest.net.


From mturquette at baylibre.com  Tue Aug 25 11:40:13 2015
From: mturquette at baylibre.com (Michael Turquette)
Date: Tue, 25 Aug 2015 11:40:13 -0700
Subject: [PATCH v4 2/6] clk: samsung: exynos4x12: add cpu clock
 configuration data and instantiate cpu clock
In-Reply-To: <1438868514-8814-3-git-send-email-b.zolnierkie@samsung.com>
References: <1438868514-8814-1-git-send-email-b.zolnierkie@samsung.com>
 <1438868514-8814-3-git-send-email-b.zolnierkie@samsung.com>
Message-ID: <20150825184013.31346.67214@quantum>

Quoting Bartlomiej Zolnierkiewicz (2015-08-06 06:41:50)
> With the addition of the new Samsung specific cpu-clock type, the
> arm clock can be represented as a cpu-clock type. Add the CPU clock
> configuration data and instantiate the CPU clock type for Exynos4x12.
> 
> Based on the earlier work by Thomas Abraham.
> 
> Cc: Tomasz Figa <tomasz.figa at gmail.com>
> Cc: Michael Turquette <mturquette at baylibre.com>
> Cc: Thomas Abraham <thomas.ab at samsung.com>
> Reviewed-by: Javier Martinez Canillas <javier at osg.samsung.com>
> Reviewed-by: Krzysztof Kozlowski <k.kozlowski at samsung.com>
> Acked-by: Sylwester Nawrocki <s.nawrocki at samsung.com>
> Tested-by: Tobias Jakobi <tjakobi at math.uni-bielefeld.de>
> Signed-off-by: Bartlomiej Zolnierkiewicz <b.zolnierkie at samsung.com>

Acked-by: Michael Turquette <mturquette at baylibre.com>

> ---
>  drivers/clk/samsung/clk-exynos4.c | 50 +++++++++++++++++++++++++++++++++++++++
>  1 file changed, 50 insertions(+)
> 
> diff --git a/drivers/clk/samsung/clk-exynos4.c b/drivers/clk/samsung/clk-exynos4.c
> index 251f48d..7f370d3 100644
> --- a/drivers/clk/samsung/clk-exynos4.c
> +++ b/drivers/clk/samsung/clk-exynos4.c
> @@ -1398,6 +1398,45 @@ static const struct exynos_cpuclk_cfg_data e4210_armclk_d[] __initconst = {
>         {  0 },
>  };
>  
> +static const struct exynos_cpuclk_cfg_data e4212_armclk_d[] __initconst = {
> +       { 1500000, E4210_CPU_DIV0(2, 1, 6, 0, 7, 3), E4210_CPU_DIV1(2, 6), },
> +       { 1400000, E4210_CPU_DIV0(2, 1, 6, 0, 7, 3), E4210_CPU_DIV1(2, 6), },
> +       { 1300000, E4210_CPU_DIV0(2, 1, 5, 0, 7, 3), E4210_CPU_DIV1(2, 5), },
> +       { 1200000, E4210_CPU_DIV0(2, 1, 5, 0, 7, 3), E4210_CPU_DIV1(2, 5), },
> +       { 1100000, E4210_CPU_DIV0(2, 1, 4, 0, 6, 3), E4210_CPU_DIV1(2, 4), },
> +       { 1000000, E4210_CPU_DIV0(1, 1, 4, 0, 5, 2), E4210_CPU_DIV1(2, 4), },
> +       {  900000, E4210_CPU_DIV0(1, 1, 3, 0, 5, 2), E4210_CPU_DIV1(2, 3), },
> +       {  800000, E4210_CPU_DIV0(1, 1, 3, 0, 5, 2), E4210_CPU_DIV1(2, 3), },
> +       {  700000, E4210_CPU_DIV0(1, 1, 3, 0, 4, 2), E4210_CPU_DIV1(2, 3), },
> +       {  600000, E4210_CPU_DIV0(1, 1, 3, 0, 4, 2), E4210_CPU_DIV1(2, 3), },
> +       {  500000, E4210_CPU_DIV0(1, 1, 3, 0, 4, 2), E4210_CPU_DIV1(2, 3), },
> +       {  400000, E4210_CPU_DIV0(1, 1, 3, 0, 4, 2), E4210_CPU_DIV1(2, 3), },
> +       {  300000, E4210_CPU_DIV0(1, 1, 2, 0, 4, 2), E4210_CPU_DIV1(2, 3), },
> +       {  200000, E4210_CPU_DIV0(1, 1, 1, 0, 3, 1), E4210_CPU_DIV1(2, 3), },
> +       {  0 },
> +};
> +
> +#define E4412_CPU_DIV1(cores, hpm, copy)                               \
> +               (((cores) << 8) | ((hpm) << 4) | ((copy) << 0))
> +
> +static const struct exynos_cpuclk_cfg_data e4412_armclk_d[] __initconst = {
> +       { 1500000, E4210_CPU_DIV0(2, 1, 6, 0, 7, 3), E4412_CPU_DIV1(7, 0, 6), },
> +       { 1400000, E4210_CPU_DIV0(2, 1, 6, 0, 7, 3), E4412_CPU_DIV1(6, 0, 6), },
> +       { 1300000, E4210_CPU_DIV0(2, 1, 5, 0, 7, 3), E4412_CPU_DIV1(6, 0, 5), },
> +       { 1200000, E4210_CPU_DIV0(2, 1, 5, 0, 7, 3), E4412_CPU_DIV1(5, 0, 5), },
> +       { 1100000, E4210_CPU_DIV0(2, 1, 4, 0, 6, 3), E4412_CPU_DIV1(5, 0, 4), },
> +       { 1000000, E4210_CPU_DIV0(1, 1, 4, 0, 5, 2), E4412_CPU_DIV1(4, 0, 4), },
> +       {  900000, E4210_CPU_DIV0(1, 1, 3, 0, 5, 2), E4412_CPU_DIV1(4, 0, 3), },
> +       {  800000, E4210_CPU_DIV0(1, 1, 3, 0, 5, 2), E4412_CPU_DIV1(3, 0, 3), },
> +       {  700000, E4210_CPU_DIV0(1, 1, 3, 0, 4, 2), E4412_CPU_DIV1(3, 0, 3), },
> +       {  600000, E4210_CPU_DIV0(1, 1, 3, 0, 4, 2), E4412_CPU_DIV1(2, 0, 3), },
> +       {  500000, E4210_CPU_DIV0(1, 1, 3, 0, 4, 2), E4412_CPU_DIV1(2, 0, 3), },
> +       {  400000, E4210_CPU_DIV0(1, 1, 3, 0, 4, 2), E4412_CPU_DIV1(1, 0, 3), },
> +       {  300000, E4210_CPU_DIV0(1, 1, 2, 0, 4, 2), E4412_CPU_DIV1(1, 0, 3), },
> +       {  200000, E4210_CPU_DIV0(1, 1, 1, 0, 3, 1), E4412_CPU_DIV1(0, 0, 3), },
> +       {  0 },
> +};
> +
>  /* register exynos4 clocks */
>  static void __init exynos4_clk_init(struct device_node *np,
>                                     enum exynos4_soc soc)
> @@ -1491,6 +1530,17 @@ static void __init exynos4_clk_init(struct device_node *np,
>                 samsung_clk_register_fixed_factor(ctx,
>                         exynos4x12_fixed_factor_clks,
>                         ARRAY_SIZE(exynos4x12_fixed_factor_clks));
> +               if (of_machine_is_compatible("samsung,exynos4412")) {
> +                       exynos_register_cpu_clock(ctx, CLK_ARM_CLK, "armclk",
> +                               mout_core_p4x12[0], mout_core_p4x12[1], 0x14200,
> +                               e4412_armclk_d, ARRAY_SIZE(e4412_armclk_d),
> +                               CLK_CPU_NEEDS_DEBUG_ALT_DIV | CLK_CPU_HAS_DIV1);
> +               } else {
> +                       exynos_register_cpu_clock(ctx, CLK_ARM_CLK, "armclk",
> +                               mout_core_p4x12[0], mout_core_p4x12[1], 0x14200,
> +                               e4212_armclk_d, ARRAY_SIZE(e4212_armclk_d),
> +                               CLK_CPU_NEEDS_DEBUG_ALT_DIV | CLK_CPU_HAS_DIV1);
> +               }
>         }
>  
>         samsung_clk_register_alias(ctx, exynos4_aliases,
> -- 
> 1.9.1
> 
> --
> To unsubscribe from this list: send the line "unsubscribe linux-kernel" in
> the body of a message to majordomo at vger.kernel.org
> More majordomo info at  http://vger.kernel.org/majordomo-info.html
> Please read the FAQ at  http://www.tux.org/lkml/


From mturquette at baylibre.com  Tue Aug 25 11:45:27 2015
From: mturquette at baylibre.com (Michael Turquette)
Date: Tue, 25 Aug 2015 11:45:27 -0700
Subject: [PATCH V1 0/3] fix clock issue for fsl,spdif
In-Reply-To: <cover.1439284957.git.shengjiu.wang@freescale.com>
References: <cover.1439284957.git.shengjiu.wang@freescale.com>
Message-ID: <20150825184527.31346.52324@quantum>

Quoting Shengjiu Wang (2015-08-11 02:26:51)
> fix clock issue for fsl,spdif
> 
> Shengjiu Wang (3):
>   ARM: imx6q: Add SPDIF_GCLK clock in clock tree
>   ARM: imx6sl: Add SPDIF_GCLK clock in clock tree
>   ARM: imx6sx: Add SPDIF_GCLK clock in clock tree

Hello Shengjiu Wang,

Please move the dts changes into separate patches. I can take the
changes to the clock driver and the header through the clk tree, but the
dt patches need to go through arm-soc.

Regards,
Mike

> 
>  arch/arm/boot/dts/imx6qdl.dtsi            |  2 +-
>  arch/arm/boot/dts/imx6sl.dtsi             | 16 ++++++++++++++++
>  arch/arm/boot/dts/imx6sx.dtsi             |  2 +-
>  drivers/clk/imx/clk-imx6q.c               |  4 +++-
>  drivers/clk/imx/clk-imx6sl.c              |  4 +++-
>  drivers/clk/imx/clk-imx6sx.c              |  1 +
>  include/dt-bindings/clock/imx6qdl-clock.h |  3 ++-
>  include/dt-bindings/clock/imx6sl-clock.h  |  3 ++-
>  include/dt-bindings/clock/imx6sx-clock.h  |  3 ++-
>  9 files changed, 31 insertions(+), 7 deletions(-)
> 
> -- 
> 1.9.1
> 
> --
> To unsubscribe from this list: send the line "unsubscribe linux-kernel" in
> the body of a message to majordomo at vger.kernel.org
> More majordomo info at  http://vger.kernel.org/majordomo-info.html
> Please read the FAQ at  http://www.tux.org/lkml/


From arnd at arndb.de  Tue Aug 25 11:48:24 2015
From: arnd at arndb.de (Arnd Bergmann)
Date: Tue, 25 Aug 2015 20:48:24 +0200
Subject: [PATCH V2 0/4] PCI: ACPI: Setting up DMA coherency for PCI device
 from _CCA attribute
In-Reply-To: <1440524009-5359-1-git-send-email-Suravee.Suthikulpanit@amd.com>
References: <1440524009-5359-1-git-send-email-Suravee.Suthikulpanit@amd.com>
Message-ID: <240091906.Gl2z931jjW@wuerfel>

On Wednesday 26 August 2015 00:33:25 Suravee Suthikulpanit wrote:
> This patch adds support to setup DMA coherency for PCI device using
> the ACPI _CCA attribute. According to the ACPI spec, the _CCA attribute
> is required for ARM64. Therefore, this patch is a pre-req for ACPI PCI
> support for ARM64 which is currently in development.
> 
> Also, this should not affect other architectures that does not define 
> CONFIG_ACPI_CCA_REQUIRED, since the default value is coherent.
> 

We only support ACPI on SBSA compliant platforms, and SBSA mandates
cache-coherent PCI, so I don't think this is actually needed,
just use coherent all the time and do WARN_ON(!CCA) to catch people
that try to incorrectly use ACPI on a non-SBSA platform.

	Arnd


From shuahkh at osg.samsung.com  Tue Aug 25 11:55:41 2015
From: shuahkh at osg.samsung.com (Shuah Khan)
Date: Tue, 25 Aug 2015 12:55:41 -0600
Subject: [PATCH v7 10/44] [media] media: rename the function that create
 pad links
In-Reply-To: <f095b87884d435e296a455ab07a9951a74c0c3a6.1440359643.git.mchehab@osg.samsung.com>
References: <cover.1440359643.git.mchehab@osg.samsung.com>
 <f095b87884d435e296a455ab07a9951a74c0c3a6.1440359643.git.mchehab@osg.samsung.com>
Message-ID: <55DCBA2D.9090901@osg.samsung.com>

On 08/23/2015 02:17 PM, Mauro Carvalho Chehab wrote:
> Now that a link can be either between two different graph
> objects, we'll need to add more functions to create links.

Is this an incomplete sentence. Should it read: "either between
two different graph objects or two pads" ?

> So, rename the existing one that create links only between
> two pads as media_create_pad_link().

> 
> No functional changes.
> 
> This patch was created via this shell script:
> 	for i in $(find drivers/media -name '*.[ch]' -type f) $(find drivers/staging/media -name '*.[ch]' -type f) $(find include/ -name '*.h' -type f) ; do sed s,media_entity_create_link,media_create_pad_link,g <$i >a && mv a $i; done
> 

Didn't want to experiment with Coccinelle?? :)

> Signed-off-by: Mauro Carvalho Chehab <mchehab at osg.samsung.com>
> Acked-by: Hans Verkuil <hans.verkuil at cisco.com>
> Signed-off-by: Mauro Carvalho Chehab <mchehab at osg.samsung.com>
> 

Changes look good to me. After fixing the commit log:

Acked-by: Shuah Khan <shuahkh at osg.samsung.com>

thanks,
-- Shuah


-- 
Shuah Khan
Sr. Linux Kernel Developer
Open Source Innovation Group
Samsung Research America (Silicon Valley)
shuahkh at osg.samsung.com | (970) 217-8978


From mturquette at baylibre.com  Tue Aug 25 11:59:31 2015
From: mturquette at baylibre.com (Michael Turquette)
Date: Tue, 25 Aug 2015 11:59:31 -0700
Subject: [PATCH v2] clk: rockchip: add pclk_cpu to the list of rk3188
 critical clocks
In-Reply-To: <F5234F5E-2A91-4B63-B260-3F20A4D16A9D@mniewoehner.de>
References: <5400BEF8-5245-4F7B-845B-D326A7BC56B5@mniewoehner.de>
 <5275855.eah07vmf4I@phil>
 <9DBF9CCE-196E-43FB-BA76-BFB4B5F47A22@mniewoehner.de>
 <10213368.VjAQGt7Kjq@phil>
 <F5234F5E-2A91-4B63-B260-3F20A4D16A9D@mniewoehner.de>
Message-ID: <20150825185931.31346.26497@quantum>

Quoting Michael Niewoehner (2015-08-17 12:50:53)
> pclk_cpu needs to keep running because it is needed for devices like
> the act8865 regulator but with the recent gpio clock handling this is
> not always the case anymore. So add it to the list of critical clocks.
> 
> Signed-off-by: Michael Niewoehner <linux at mniewoehner.de>

Patch fails to apply due to a problem with line 15. git format-patch
problem?

Regards,
Mike

> ---
> Changes in v2:
> - adapt commit message
> - add Linus Walleij to recipients, as the patch is related to the gpio clock
>   change in the rockchip pinctrl driver it should go through his tree as well
> 
> drivers/clk/rockchip/clk-rk3188.c | 1 +
> 1 file changed, 1 insertion(+)
> 
> diff --git a/drivers/clk/rockchip/clk-rk3188.c b/drivers/clk/rockchip/clk-rk3188.c
> index e4f9d47..1c93229 100644
> --- a/drivers/clk/rockchip/clk-rk3188.c
> +++ b/drivers/clk/rockchip/clk-rk3188.c
> @@ -708,6 +708,7 @@ static const char *const rk3188_critical_clocks[] __initconst = {
>         "aclk_cpu",
>         "aclk_peri",
>         "hclk_peri",
> +       "pclk_cpu",
> };
> 
> static void __init rk3188_common_clk_init(struct device_node *np)
> -- 
> 2.5.0
> --
> To unsubscribe from this list: send the line "unsubscribe linux-kernel" in
> the body of a message to majordomo at vger.kernel.org
> More majordomo info at  http://vger.kernel.org/majordomo-info.html
> Please read the FAQ at  http://www.tux.org/lkml/


From mturquette at baylibre.com  Tue Aug 25 12:10:33 2015
From: mturquette at baylibre.com (Michael Turquette)
Date: Tue, 25 Aug 2015 12:10:33 -0700
Subject: [PULL] clk: at91: sama5d2 materials
In-Reply-To: <20150818102401.17de779b@bbrezillon>
References: <20150818102401.17de779b@bbrezillon>
Message-ID: <20150825191033.31346.67237@quantum>

Quoting Boris Brezillon (2015-08-18 01:24:01)
> Stephen, Mike,
> 
> Here is a PR for the sama5d2 materials.
> I know we're already late in the release cycle and I'm not sure you can
> take this PR into account for 4.3, so if you can't could you please
> queue it for 4.4?

Queued for 4.4.

Thanks,
Mike

> 
> Thanks,
> 
> Boris
> 
> The following changes since commit c42743f11f58646a50bc4b96da363429dca0c5e6:
> 
>   clk: add bindings for the Ux500 clocks (2015-08-13 11:29:45 -0700)
> 
> are available in the git repository at:
> 
>   https://github.com/bbrezillon/linux-at91.git clk/atmel-clk-next
> 
> for you to fetch changes up to 3be0527c0f8bbbb744a6a34603d6a83e511c6741:
> 
>   clk: at91: add generated clock driver (2015-08-18 10:11:57 +0200)
> 
> ----------------------------------------------------------------
> Nicolas Ferre (4):
>       clk: at91: cleanup PMC header file for PCR register fields
>       clk: at91: modify PMC peripheral clock to deal with newer register layout
>       clk: at91: add PMC sama5d2 support
>       clk: at91: add generated clock driver
> 
>  Documentation/devicetree/bindings/clock/at91-clock.txt |  35 +++++++++++++++++++++
>  arch/arm/mach-at91/Kconfig                             |   3 ++
>  drivers/clk/at91/Makefile                              |   1 +
>  drivers/clk/at91/clk-generated.c                       | 306 ++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
>  drivers/clk/at91/clk-peripheral.c                      |  24 +++++++++-----
>  drivers/clk/at91/pmc.c                                 |  21 +++++++++++++
>  drivers/clk/at91/pmc.h                                 |   3 ++
>  include/dt-bindings/clock/at91.h                       |   1 +
>  include/linux/clk/at91_pmc.h                           |  22 ++++++++-----
>  9 files changed, 400 insertions(+), 16 deletions(-)
>  create mode 100644 drivers/clk/at91/clk-generated.c
> 
> _______________________________________________
> linux-arm-kernel mailing list
> linux-arm-kernel at lists.infradead.org
> http://lists.infradead.org/mailman/listinfo/linux-arm-kernel


From Shenwei.Wang at freescale.com  Tue Aug 25 12:24:28 2015
From: Shenwei.Wang at freescale.com (Shenwei Wang)
Date: Tue, 25 Aug 2015 19:24:28 +0000
Subject: [PATCH v9 1/1] irqchip: imx-gpcv2: IMX GPCv2 driver for wakeup
 sources
In-Reply-To: <55DC96BA.2020905@arm.com>
References: <1440443055-7291-1-git-send-email-shenwei.wang@freescale.com>
 <55DC3452.3070205@arm.com>
 <CY1PR0301MB08439B6C5F841AFFD152DFD883610@CY1PR0301MB0843.namprd03.prod.outlook.com>
 <55DC738D.8000302@arm.com>
 <CY1PR0301MB0843AE566996617D855CC00683610@CY1PR0301MB0843.namprd03.prod.outlook.com>
 <55DC7FA4.7040902@arm.com>
 <CY1PR0301MB08433A2659C75028821F0AE783610@CY1PR0301MB0843.namprd03.prod.outlook.com>
 <55DC96BA.2020905@arm.com>
Message-ID: <CY1PR0301MB0843388CA3BB07493BC2907183610@CY1PR0301MB0843.namprd03.prod.outlook.com>



> -----Original Message-----
> From: Sudeep Holla [mailto:sudeep.holla at arm.com]
> Sent: 2015?8?25? 11:24
> To: Wang Shenwei-B38339
> Cc: Sudeep Holla; shawn.guo at linaro.org; tglx at linutronix.de;
> jason at lakedaemon.net; Huang Yongcai-B20788; linux-kernel at vger.kernel.org;
> linux-arm-kernel at lists.infradead.org
> Subject: Re: [PATCH v9 1/1] irqchip: imx-gpcv2: IMX GPCv2 driver for wakeup
> >
> > You don't really understand what happens after a driver calls
> > enable_irq_wake. In suspend state, even the interrupt controller
> > itself is powered off. How can you get the system up again  by just
> > using a SKIP_SET_WAKE.
> >
> 
> Sorry for that, let me try to understand aloud. So you have irq_{un,}mask function
> that are called when interrupts are enabled and disabled. So suppose you have 3
> irqs that are enabled and only one of then is set as wakeup source.
> 
> Now you call enable_irq_wake, you save that in wakeup_sources, fine.
> Later when you enter suspend, you save all the 3 active irqs in saved_irq_mask
> and over-write cpu2wakeup with wakeup_sources, right?
> 
> All fine, what I am saying is let irq-core know that you want to mask the 2
> non-wakeup irqs you have using MASK_ON_SUSPEND. So when
> suspend_device_irqs is called in suspend path, that's done for you automatically
> and the cpu2wakeup will have just 1 wakeup enabled which is what you are doing
> in suspend callback, right ?

	/*
	 * Hardware which has no wakeup source configuration facility
	 * requires that the non wakeup interrupts are masked at the
	 * chip level. The chip implementation indicates that with
	 * IRQCHIP_MASK_ON_SUSPEND.
	 */
	if (irq_desc_get_chip(desc)->flags & IRQCHIP_MASK_ON_SUSPEND)
		mask_irq(desc);

IRQCHIP_MASK_ON_SUSPEND flag is for the hardware that has no wakeup source capability.
This GPCv2 block is designed to manage the wakeup source, so the flag does not make any sense.

> Now that it's already done for you, you need not do anything extra and hence just
> set SKIP_SET_WAKE to do nothing.

static int set_irq_wake_real(unsigned int irq, unsigned int on)
{
	struct irq_desc *desc = irq_to_desc(irq);
	int ret = -ENXIO;

	if (irq_desc_get_chip(desc)->flags &  IRQCHIP_SKIP_SET_WAKE)
		return 0;

	if (desc->irq_data.chip->irq_set_wake)
		ret = desc->irq_data.chip->irq_set_wake(&desc->irq_data, on);

	return ret;
}
From the codes above, if a irqchip can not handle the wakeup sources, it can set SKIP flag.
This driver is intended to manage the wakeup sources, what's the reason to skip here?

Regards,
Shenwei


> Hope this clarifies, sorry if I am still missing to understand something here, but I
> don't see anything. Let me know.
> 
> Regards,
> Sudeep

From shuahkhan at gmail.com  Tue Aug 25 12:25:15 2015
From: shuahkhan at gmail.com (Shuah Khan)
Date: Tue, 25 Aug 2015 13:25:15 -0600
Subject: [PATCH v7 11/44] [media] media: use entity.graph_obj.mdev instead
 of .parent
In-Reply-To: <55DC0D08.10504@xs4all.nl>
References: <cover.1440359643.git.mchehab@osg.samsung.com>
 <dc1be98277c46ddd87e431148fc7e332176828ab.1440359643.git.mchehab@osg.samsung.com>
 <55DC0D08.10504@xs4all.nl>
Message-ID: <CAKocOOM7_mgp1ORz1mLzso9AZxSTuEcHAef64_LQ-NZVp5FASw@mail.gmail.com>

On Tue, Aug 25, 2015 at 12:36 AM, Hans Verkuil <hverkuil at xs4all.nl> wrote:
> On 08/23/2015 10:17 PM, Mauro Carvalho Chehab wrote:
>> From: Javier Martinez Canillas <javier at osg.samsung.com>
>>
>> The struct media_entity has a .parent field that stores a pointer
>> to the parent struct media_device. But recently a media_gobj was
>> embedded into the entities and since struct media_gojb already has
>> a pointer to a struct media_device in the .mdev field, the .parent
>> field becomes redundant and can be removed.
>>
>> This patch replaces all the usage of .parent by .graph_obj.mdev so
>> that field will become unused and can be removed on a later patch.
>>
>> No functional changes.
>>
>> The transformation was made using the following coccinelle spatch:
>>
>> @@
>> struct media_entity *me;
>> @@
>>
>> - me->parent
>> + me->graph_obj.mdev
>>
>> @@
>> struct media_entity *link;
>> @@
>>
>> - link->source->entity->parent
>> + link->source->entity->graph_obj.mdev
>>
>> @@
>> struct exynos_video_entity *ve;
>> @@
>>
>> - ve->vdev.entity.parent
>> + ve->vdev.entity.graph_obj.mdev
>>
>> Suggested-by: Mauro Carvalho Chehab <mchehab at osg.samsung.com>
>>
>> Signed-off-by: Javier Martinez Canillas <javier at osg.samsung.com>
>> Signed-off-by: Mauro Carvalho Chehab <mchehab at osg.samsung.com>
>
> Acked-by: Hans Verkuil <hans.verkuil at cisco.com>

The change looks good to me. I would really like to see a before and after
media graph with these changes, this patch and series in general.

thanks,
-- Shuah


From tglx at linutronix.de  Tue Aug 25 12:26:20 2015
From: tglx at linutronix.de (Thomas Gleixner)
Date: Tue, 25 Aug 2015 21:26:20 +0200 (CEST)
Subject: [PATCH v9 1/1] irqchip: imx-gpcv2: IMX GPCv2 driver for wakeup
 sources
In-Reply-To: <55DC96BA.2020905@arm.com>
References: <1440443055-7291-1-git-send-email-shenwei.wang@freescale.com>
 <55DC3452.3070205@arm.com>
 <CY1PR0301MB08439B6C5F841AFFD152DFD883610@CY1PR0301MB0843.namprd03.prod.outlook.com>
 <55DC738D.8000302@arm.com>
 <CY1PR0301MB0843AE566996617D855CC00683610@CY1PR0301MB0843.namprd03.prod.outlook.com>
 <55DC7FA4.7040902@arm.com>
 <CY1PR0301MB08433A2659C75028821F0AE783610@CY1PR0301MB0843.namprd03.prod.outlook.com>
 <55DC96BA.2020905@arm.com>
Message-ID: <alpine.DEB.2.11.1508252123310.15006@nanos>

On Tue, 25 Aug 2015, Sudeep Holla wrote:
> On 25/08/15 15:54, Shenwei Wang wrote:
> > You don't really understand what happens after a driver calls
> > enable_irq_wake. In suspend state, even the interrupt
> > controller itself is powered off. How can you get the system up
> > again  by just using a SKIP_SET_WAKE.
> 
> Sorry for that, let me try to understand aloud. So you have
> irq_{un,}mask function that are called when interrupts are enabled and
> disabled. So suppose you have 3 irqs that are enabled and only one of
> then is set as wakeup source.
> 
> Now you call enable_irq_wake, you save that in wakeup_sources, fine.
> Later when you enter suspend, you save all the 3 active irqs in
> saved_irq_mask and over-write cpu2wakeup with wakeup_sources, right?
> 
> All fine, what I am saying is let irq-core know that you want to mask
> the 2 non-wakeup irqs you have using MASK_ON_SUSPEND. So when
> suspend_device_irqs is called in suspend path, that's done for you
> automatically and the cpu2wakeup will have just 1 wakeup enabled which
> is what you are doing in suspend callback, right ?

I missed that when I reviewed the patch. You are right, it can be
simplified.
 
> Now that it's already done for you, you need not do anything extra and
> hence just set SKIP_SET_WAKE to do nothing.

He still needs the set_wake function to capture the wake enabled
interrupts as they are handed over to the low level asm code via
imx_gpcv2_get_wakeup_source(). Though they could be read back from the
hw registers as well.

Thanks,

	tglx


From robherring2 at gmail.com  Tue Aug 25 12:27:47 2015
From: robherring2 at gmail.com (Rob Herring)
Date: Tue, 25 Aug 2015 14:27:47 -0500
Subject: [PATCH V2 3/4] PCI: OF: Move of_pci_dma_configure() to
 pci_dma_configure()
In-Reply-To: <1440524009-5359-4-git-send-email-Suravee.Suthikulpanit@amd.com>
References: <1440524009-5359-1-git-send-email-Suravee.Suthikulpanit@amd.com>
 <1440524009-5359-4-git-send-email-Suravee.Suthikulpanit@amd.com>
Message-ID: <CAL_JsqLDkTKs4XVDCzY=CDubdQ+NuC3e+yFND9W2zmCgmLkTFQ@mail.gmail.com>

On Tue, Aug 25, 2015 at 12:33 PM, Suravee Suthikulpanit
<Suravee.Suthikulpanit at amd.com> wrote:
> This patch move of_pci_dma_configure() to a more generic
> pci_dma_configure(), which can be extended by non-OF code (e.g. ACPI).
>
> This has no functional change.
>
> Signed-off-by: Suravee Suthikulpanit <Suravee.Suthikulpanit at amd.com>
> CC: Bjorn Helgaas <bhelgaas at google.com>
> CC: Catalin Marinas <catalin.marinas at arm.com>
> CC: Rob Herring <robh+dt at kernel.org>

Acked-by: Rob Herring <robh at kernel.org>

> CC: Will Deacon <will.deacon at arm.com>
> CC: Rafael J. Wysocki <rjw at rjwysocki.net>
> CC: Murali Karicheri <m-karicheri2 at ti.com>
> ---
>  drivers/of/of_pci.c    | 20 --------------------
>  drivers/pci/probe.c    | 27 +++++++++++++++++++++++++--
>  include/linux/of_pci.h |  3 ---
>  3 files changed, 25 insertions(+), 25 deletions(-)
>
> diff --git a/drivers/of/of_pci.c b/drivers/of/of_pci.c
> index 5751dc5..b66ee4e 100644
> --- a/drivers/of/of_pci.c
> +++ b/drivers/of/of_pci.c
> @@ -117,26 +117,6 @@ int of_get_pci_domain_nr(struct device_node *node)
>  }
>  EXPORT_SYMBOL_GPL(of_get_pci_domain_nr);
>
> -/**
> - * of_pci_dma_configure - Setup DMA configuration
> - * @dev: ptr to pci_dev struct of the PCI device
> - *
> - * Function to update PCI devices's DMA configuration using the same
> - * info from the OF node of host bridge's parent (if any).
> - */
> -void of_pci_dma_configure(struct pci_dev *pci_dev)
> -{
> -       struct device *dev = &pci_dev->dev;
> -       struct device *bridge = pci_get_host_bridge_device(pci_dev);
> -
> -       if (!bridge->parent)
> -               return;
> -
> -       of_dma_configure(dev, bridge->parent->of_node);
> -       pci_put_host_bridge_device(bridge);
> -}
> -EXPORT_SYMBOL_GPL(of_pci_dma_configure);
> -
>  #if defined(CONFIG_OF_ADDRESS)
>  /**
>   * of_pci_get_host_bridge_resources - Parse PCI host bridge resources from DT
> diff --git a/drivers/pci/probe.c b/drivers/pci/probe.c
> index cefd636..4de6594 100644
> --- a/drivers/pci/probe.c
> +++ b/drivers/pci/probe.c
> @@ -6,12 +6,14 @@
>  #include <linux/delay.h>
>  #include <linux/init.h>
>  #include <linux/pci.h>
> -#include <linux/of_pci.h>
> +#include <linux/of_device.h>
>  #include <linux/pci_hotplug.h>
>  #include <linux/slab.h>
>  #include <linux/module.h>
>  #include <linux/cpumask.h>
>  #include <linux/pci-aspm.h>
> +#include <linux/acpi.h>
> +#include <linux/property.h>
>  #include <asm-generic/pci-bridge.h>
>  #include "pci.h"
>
> @@ -1544,6 +1546,27 @@ static void pci_init_capabilities(struct pci_dev *dev)
>         pci_enable_acs(dev);
>  }
>
> +/**
> + * pci_dma_configure - Setup DMA configuration
> + * @dev: ptr to pci_dev struct of the PCI device
> + *
> + * Function to update PCI devices's DMA configuration using the same
> + * info from the OF node of host bridge's parent (if any).
> + */
> +static void pci_dma_configure(struct pci_dev *dev)
> +{
> +       struct device *bridge = pci_get_host_bridge_device(dev);
> +
> +       if (IS_ENABLED(CONFIG_OF) && dev->dev.of_node) {
> +               if (!bridge->parent)
> +                       return;
> +
> +               of_dma_configure(&dev->dev, bridge->parent->of_node);
> +       }
> +
> +       pci_put_host_bridge_device(bridge);
> +}
> +
>  void pci_device_add(struct pci_dev *dev, struct pci_bus *bus)
>  {
>         int ret;
> @@ -1557,7 +1580,7 @@ void pci_device_add(struct pci_dev *dev, struct pci_bus *bus)
>         dev->dev.dma_mask = &dev->dma_mask;
>         dev->dev.dma_parms = &dev->dma_parms;
>         dev->dev.coherent_dma_mask = 0xffffffffull;
> -       of_pci_dma_configure(dev);
> +       pci_dma_configure(dev);
>
>         pci_set_dma_max_seg_size(dev, 65536);
>         pci_set_dma_seg_boundary(dev, 0xffffffff);
> diff --git a/include/linux/of_pci.h b/include/linux/of_pci.h
> index 29fd3fe..ce0e5ab 100644
> --- a/include/linux/of_pci.h
> +++ b/include/linux/of_pci.h
> @@ -16,7 +16,6 @@ int of_pci_get_devfn(struct device_node *np);
>  int of_irq_parse_and_map_pci(const struct pci_dev *dev, u8 slot, u8 pin);
>  int of_pci_parse_bus_range(struct device_node *node, struct resource *res);
>  int of_get_pci_domain_nr(struct device_node *node);
> -void of_pci_dma_configure(struct pci_dev *pci_dev);
>  #else
>  static inline int of_irq_parse_pci(const struct pci_dev *pdev, struct of_phandle_args *out_irq)
>  {
> @@ -51,8 +50,6 @@ of_get_pci_domain_nr(struct device_node *node)
>  {
>         return -1;
>  }
> -
> -static inline void of_pci_dma_configure(struct pci_dev *pci_dev) { }
>  #endif
>
>  #if defined(CONFIG_OF_ADDRESS)
> --
> 2.1.0
>


From tglx at linutronix.de  Tue Aug 25 12:29:49 2015
From: tglx at linutronix.de (Thomas Gleixner)
Date: Tue, 25 Aug 2015 21:29:49 +0200 (CEST)
Subject: [PATCH v9 1/1] irqchip: imx-gpcv2: IMX GPCv2 driver for wakeup
 sources
In-Reply-To: <CY1PR0301MB0843388CA3BB07493BC2907183610@CY1PR0301MB0843.namprd03.prod.outlook.com>
References: <1440443055-7291-1-git-send-email-shenwei.wang@freescale.com>
 <55DC3452.3070205@arm.com>
 <CY1PR0301MB08439B6C5F841AFFD152DFD883610@CY1PR0301MB0843.namprd03.prod.outlook.com>
 <55DC738D.8000302@arm.com>
 <CY1PR0301MB0843AE566996617D855CC00683610@CY1PR0301MB0843.namprd03.prod.outlook.com>
 <55DC7FA4.7040902@arm.com>
 <CY1PR0301MB08433A2659C75028821F0AE783610@CY1PR0301MB0843.namprd03.prod.outlook.com>
 <55DC96BA.2020905@arm.com>
 <CY1PR0301MB0843388CA3BB07493BC2907183610@CY1PR0301MB0843.namprd03.prod.outlook.com>
Message-ID: <alpine.DEB.2.11.1508252126360.15006@nanos>

On Tue, 25 Aug 2015, Shenwei Wang wrote:
> > From: Sudeep Holla [mailto:sudeep.holla at arm.com]
> > All fine, what I am saying is let irq-core know that you want to mask the 2
> > non-wakeup irqs you have using MASK_ON_SUSPEND. So when
> > suspend_device_irqs is called in suspend path, that's done for you automatically
> > and the cpu2wakeup will have just 1 wakeup enabled which is what you are doing
> > in suspend callback, right ?
> 
> 	/*
> 	 * Hardware which has no wakeup source configuration facility
> 	 * requires that the non wakeup interrupts are masked at the
> 	 * chip level. The chip implementation indicates that with
> 	 * IRQCHIP_MASK_ON_SUSPEND.
> 	 */
> 	if (irq_desc_get_chip(desc)->flags & IRQCHIP_MASK_ON_SUSPEND)
> 		mask_irq(desc);
> 
> IRQCHIP_MASK_ON_SUSPEND flag is for the hardware that has no wakeup
> source capability.  This GPCv2 block is designed to manage the
> wakeup source, so the flag does not make any sense.

You have no seperate wakeup source mechanism. All you do is to mask all
non wakeup sources and keep the wakeup sources unmask.

That's what happens in gpcv2_wakeup_source_save()

       writel_relaxed(cd->wakeup_sources[i], reg);

So it's the same as letting the core mask all non wakeup sources and
leave the wakeup sources unmask.

> > Now that it's already done for you, you need not do anything extra and hence just
> > set SKIP_SET_WAKE to do nothing.
> 
> static int set_irq_wake_real(unsigned int irq, unsigned int on)
> {
> 	struct irq_desc *desc = irq_to_desc(irq);
> 	int ret = -ENXIO;
> 
> 	if (irq_desc_get_chip(desc)->flags &  IRQCHIP_SKIP_SET_WAKE)
> 		return 0;
> 
> 	if (desc->irq_data.chip->irq_set_wake)
> 		ret = desc->irq_data.chip->irq_set_wake(&desc->irq_data, on);
> 
> 	return ret;
> }
> From the codes above, if a irqchip can not handle the wakeup
> sources, it can set SKIP flag.  This driver is intended to manage
> the wakeup sources, what's the reason to skip here?

To reduce code. Everything the core can do for you is something you
don't have to implement.

Thanks,

	tglx


From Shenwei.Wang at freescale.com  Tue Aug 25 12:35:04 2015
From: Shenwei.Wang at freescale.com (Shenwei Wang)
Date: Tue, 25 Aug 2015 19:35:04 +0000
Subject: [PATCH v3 1/1] misc: sram: add dev_pm_ops to support module power
 gate
In-Reply-To: <55DC91BE.7090107@arm.com>
References: <1438272681-29338-1-git-send-email-shenwei.wang@freescale.com>
 <55DC677E.1030004@arm.com>
 <CY1PR0301MB0843D5CB5FFC56991B90EB4283610@CY1PR0301MB0843.namprd03.prod.outlook.com>
 <55DC74CF.7070300@arm.com>
 <CY1PR0301MB084302FA2AA9582A3BA9B50B83610@CY1PR0301MB0843.namprd03.prod.outlook.com>
 <55DC7E5E.5020701@arm.com>
 <CY1PR0301MB0843A508122C7FCF3969AF3D83610@CY1PR0301MB0843.namprd03.prod.outlook.com>
 <55DC91BE.7090107@arm.com>
Message-ID: <CY1PR0301MB0843AB9C6330D29EBD5F47DA83610@CY1PR0301MB0843.namprd03.prod.outlook.com>



> -----Original Message-----
> From: Sudeep Holla [mailto:sudeep.holla at arm.com]
> Sent: 2015?8?25? 11:03
> To: Wang Shenwei-B38339
> Cc: Sudeep Holla; gregkh at linuxfoundation.org; arnd at arndb.de; Huang
> Yongcai-B20788; linux-arm-kernel at lists.infradead.org
> Subject: Re: [PATCH v3 1/1] misc: sram: add dev_pm_ops to support module
> power gate
> >> I don't like that solution as it's not scalable with SRAM size and
> >> saving all the content of SRAM just because of few active regions
> >> makes no sense to me at-least. I prefer leaving it to the users to
> >> handle that rather than SRAM driver.
> >
> > I don't think it is not scalable. The choice should be made by the
> > application. From the driver side, it should be able to provide the
> > way to retain its contents during power gate.
> >
> 
> OK that was just my opinion. I just wanted to avoid unnecessary save/restore, e.g.
> if say just few kilobytes are active in say 32MB SRAM, you will save/restore entire
> SRAM ?

Although in theory a SoC can integrate such a big SRAM like 32MB inside, but I don't
think anyone will practice it because the cost is too high. So far, the most popular size
of a SRAM in a SoC is hundreds of KB. 
 
> Anyways, the driver is saving/restoring the memory unconditionally whenever DT
> sets that boolean right ? at-least as the patch stands.

The saving/restoring feature is not enabled by default in this patch. To enable it you
need to add the can-power-gate string in the relating DT node.

Regards,
Shenwei

> Regards,
> Sudeep

From dianders at chromium.org  Tue Aug 25 12:40:00 2015
From: dianders at chromium.org (Doug Anderson)
Date: Tue, 25 Aug 2015 12:40:00 -0700
Subject: [PATCH] ARM: probes: Don't stop the machine if we're in the
 debugger
In-Reply-To: <CAGXu5j+oExmQPR9UuJy8oVaL_DzZ70kSP6ftS+ZhyFSs7hyxsA@mail.gmail.com>
References: <1440460739-19522-1-git-send-email-dianders@chromium.org>
 <55DBB48E.7040508@codeaurora.org>
 <CAGXu5j+oExmQPR9UuJy8oVaL_DzZ70kSP6ftS+ZhyFSs7hyxsA@mail.gmail.com>
Message-ID: <CAD=FV=Xe7hg7ifJ3JAO8StfugMYnojc3SNfsa=gLfWpm0n262A@mail.gmail.com>

Kees,

On Tue, Aug 25, 2015 at 9:50 AM, Kees Cook <keescook at chromium.org> wrote:
> On Mon, Aug 24, 2015 at 5:19 PM, Stephen Boyd <sboyd at codeaurora.org> wrote:
>> On 08/24/2015 04:58 PM, Douglas Anderson wrote:
>>>
>>> If we're in kgdb then the machine is already stopped.  Trying to stop
>>> it again will cause us to try to sleep, which is not allowed while in
>>> kgdb.  To avoid this problem, only stop the machine when we're not in
>>> kgdb.
>>>
>>> Reported-by: Aapo Vienamo <avienamo at nvidia.com>
>>> Suggested-by: Kees Cook <keescook at chromium.org>
>
> I actually suggested using in_atomic_preempt_off() which is I think a
> better catch-all. Could you use that instead, please?

I chose not to use that because (I think) in_atomic_preempt_off()
doesn't guarantee that stop_machine() is not needed.  Said another
way: if in_atomic_preempt_off() returns true then we can't sleep on
the current CPU.  ...but other CPUs may be running.  In this case
technically we need to call stop_machine(), but we'd need to do it in
a way that didn't require sleeping.

In the case of kgdb we know that the machine is stopped and we're
atomic too.  ...so we could certainly fix kgdb by checking for
"atomic", but that would mean there would be other places where we'd
get no warning and (I think) invalid behavior.

Stephen Boyd suggested that I just change this so that we expose a new
function and that makes everything a bit cleaner.  I'll try that.

-Doug


From computersforpeace at gmail.com  Tue Aug 25 12:54:11 2015
From: computersforpeace at gmail.com (Brian Norris)
Date: Tue, 25 Aug 2015 12:54:11 -0700
Subject: [PATCH v10 2/5] mtd: nand: vf610_nfc: add hardware BCH-ECC support
In-Reply-To: <ff2e2716578a1ae5f0c4b0e0ca8bbdc3@agner.ch>
References: <1438594050-4595-1-git-send-email-stefan@agner.ch>
 <1438594050-4595-3-git-send-email-stefan@agner.ch>
 <ff2e2716578a1ae5f0c4b0e0ca8bbdc3@agner.ch>
Message-ID: <20150825195411.GJ81844@google.com>

On Mon, Aug 03, 2015 at 11:28:43AM +0200, Stefan Agner wrote:
> On 2015-08-03 11:27, Stefan Agner wrote:
> <snip>
> > +static inline int vf610_nfc_correct_data(struct mtd_info *mtd, uint8_t *dat,
> > +					 uint8_t *oob, int oob_loaded)
> > +{
> > +	struct vf610_nfc *nfc = mtd_to_nfc(mtd);
> > +	u8 ecc_status;
> > +	u8 ecc_count;
> > +	int flip;
> > +
> > +	ecc_status = __raw_readb(nfc->regs + ECC_SRAM_ADDR * 8 + ECC_OFFSET);

Why __raw_readb()? That's not normally encourage, and it has issues with
endianness. It looks like maybe this is actulaly a 32-bit register, and
you're having trouble when trying to do bytewise access? I see this
earlier:

/*
 * ECC status is stored at NFC_CFG[ECCADD] +4 for little-endian
 * and +7 for big-endian SoCs.
 */
#ifdef __LITTLE_ENDIAN
#define ECC_OFFSET      4
#else
#define ECC_OFFSET      7
#endif

So maybe you really just want:

#define ECC_OFFSET	4
...
	ecc_status = vf610_nfc_read(ECC_SRAM_ADDR * 8 + ECC_OFFSET) & 0xff;

?

> > +	ecc_count = ecc_status & ECC_ERR_COUNT;
> > +
> > +	if (!(ecc_status & ECC_STATUS_MASK))
> > +		return ecc_count;
> > +
> > +	if (!oob_loaded)
> > +		vf610_nfc_read_buf(mtd, oob, mtd->oobsize);
> > +
> > +	/*
> > +	 * On an erased page, bit count (including OOB) should be zero or
> > +	 * at least less then half of the ECC strength.
> > +	 */
> > +	flip = count_written_bits(dat, nfc->chip.ecc.size, ecc_count);

Another side note: why are you using ecc_count as a max threshold? AIUI,
an ECC algorithm doesn't really report useful error count information if
it's above the correction limit. So wouldn't we be looking to count up
to our SW threshold? i.e., ecc.strength / 2, or similar? Similar
comments below.

> > +	flip += count_written_bits(oob, mtd->oobsize - nfc->chip.ecc.bytes,
> > +				   ecc_count);
> 
> With ECC the controller seems to clear the ECC bytes in SRAM buffer.
> This is a dump of 64 Bit OOB with the 32-error ECC mode which requires
> 60 bytes of OOB for ECC:
> 
> [   22.190273] ff ff ff ff 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
> 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
> 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00

Hmm, that's not really good. The point is that we need to make sure that
everything that could have been programmed (including the ECC area) was
not actually programmed. But your ECC controller is not, contrary to
MTD's expectations, dumping raw uncorrected data here.

> [   22.209698] vf610_nfc_correct_data, flips 1
> 
> Not sure if this is acceptable, but I now only count the bits in the
> non-ECC area of the OOB.

That's not the intention of my suggestion. You're still missing out on a
class of patterns that might look close to all 0xff but are not
actually.

If the HW ECC really doesn't give you valid data+OOB at this point, then
you might have to re-read with ECC disabled. Of course, that's got a
performance cost...

Or perhaps Boris has a better suggestion? He's been surveying other NAND
drivers that need to do similar things, and he's working on providing
some support code for common design patterns.

> Btw, if the ECC check fails, the controller seems kind of count the
> amount of bitflips. It works for most devices reliable, but we had
> devices for which that number was not accurate, see:
> http://thread.gmane.org/gmane.linux.ports.arm.kernel/357439

I'm a little confused there. Why would you be expecting to get a count
of bitflips, when the ECC engine can't correct all errors? How is it
supposed to know what the "right" data is if the bit errors are beyond
the correction strength?

Brian


From balbi at ti.com  Tue Aug 25 12:58:30 2015
From: balbi at ti.com (Felipe Balbi)
Date: Tue, 25 Aug 2015 14:58:30 -0500
Subject: CONFIG_DEBUG_SHIRQ and PM
Message-ID: <20150825195830.GH27534@saruman.tx.rr.com>

Hi Ingo,

I'm facing an issue with CONFIG_DEBUG_SHIRQ and pm_runtime when using
devm_request_*irq().

If we using devm_request_*irq(), that irq will be freed after device
drivers' ->remove() gets called. If on ->remove(), we're calling
pm_runtime_put_sync(); pm_runtime_disable(), device's clocks might get
gated and, because we do an extra call to the device's IRQ handler when
CONFIG_DEBUG_SHIRQ=y, we might trigger an abort exception if, inside the
IRQ handler, we try to read a register which is clocked by the device's
clock.

This is, of course, really old code which has been in tree for many,
many years. I guess nobody has been running their tests in the setup
mentioned above (CONFIG_DEBUG_SHIRQ=y, pm_runtime_put_sync() on
->remove(), a register read on IRQ handler, and a shared IRQ handler),
so that's why we never caught this before.

Disabling CONFIG_DEBUG_SHIRQ, of course, makes the problem go away, but
if driver *must* be ready to receive, and handle, an IRQ even during
module removal, I wonder what the IRQ handler should do. We can't, in
most cases, call pm_runtime_put_sync() from IRQ handler.

I'm guessing the only way would be to move pm_runtime calls into the bus
driver (in this case, the platform_bus) and make sure it only gets
called after device managed resources are freed ?

Any hints would be greatly appreciated.

cheers

-- 
balbi
-------------- next part --------------
A non-text attachment was scrubbed...
Name: signature.asc
Type: application/pgp-signature
Size: 819 bytes
Desc: Digital signature
URL: <http://lists.infradead.org/pipermail/linux-arm-kernel/attachments/20150825/091ce5a7/attachment.sig>

From Shenwei.Wang at freescale.com  Tue Aug 25 12:58:50 2015
From: Shenwei.Wang at freescale.com (Shenwei Wang)
Date: Tue, 25 Aug 2015 19:58:50 +0000
Subject: [PATCH v9 1/1] irqchip: imx-gpcv2: IMX GPCv2 driver for wakeup
 sources
In-Reply-To: <alpine.DEB.2.11.1508252126360.15006@nanos>
References: <1440443055-7291-1-git-send-email-shenwei.wang@freescale.com>
 <55DC3452.3070205@arm.com>
 <CY1PR0301MB08439B6C5F841AFFD152DFD883610@CY1PR0301MB0843.namprd03.prod.outlook.com>
 <55DC738D.8000302@arm.com>
 <CY1PR0301MB0843AE566996617D855CC00683610@CY1PR0301MB0843.namprd03.prod.outlook.com>
 <55DC7FA4.7040902@arm.com>
 <CY1PR0301MB08433A2659C75028821F0AE783610@CY1PR0301MB0843.namprd03.prod.outlook.com>
 <55DC96BA.2020905@arm.com>
 <CY1PR0301MB0843388CA3BB07493BC2907183610@CY1PR0301MB0843.namprd03.prod.outlook.com>
 <alpine.DEB.2.11.1508252126360.15006@nanos>
Message-ID: <CY1PR0301MB08430902E0E46A43D00317C283610@CY1PR0301MB0843.namprd03.prod.outlook.com>



> -----Original Message-----
> From: Thomas Gleixner [mailto:tglx at linutronix.de]
> Sent: 2015?8?25? 14:30
> To: Wang Shenwei-B38339
> Cc: Sudeep Holla; shawn.guo at linaro.org; jason at lakedaemon.net; Huang
> Yongcai-B20788; linux-kernel at vger.kernel.org;
> linux-arm-kernel at lists.infradead.org
> Subject: RE: [PATCH v9 1/1] irqchip: imx-gpcv2: IMX GPCv2 driver for wakeup
> sources
> 
> On Tue, 25 Aug 2015, Shenwei Wang wrote:
> > > From: Sudeep Holla [mailto:sudeep.holla at arm.com] All fine, what I am
> > > saying is let irq-core know that you want to mask the 2 non-wakeup
> > > irqs you have using MASK_ON_SUSPEND. So when suspend_device_irqs is
> > > called in suspend path, that's done for you automatically and the
> > > cpu2wakeup will have just 1 wakeup enabled which is what you are
> > > doing in suspend callback, right ?
> >
> > 	/*
> > 	 * Hardware which has no wakeup source configuration facility
> > 	 * requires that the non wakeup interrupts are masked at the
> > 	 * chip level. The chip implementation indicates that with
> > 	 * IRQCHIP_MASK_ON_SUSPEND.
> > 	 */
> > 	if (irq_desc_get_chip(desc)->flags & IRQCHIP_MASK_ON_SUSPEND)
> > 		mask_irq(desc);
> >
> > IRQCHIP_MASK_ON_SUSPEND flag is for the hardware that has no wakeup
> > source capability.  This GPCv2 block is designed to manage the wakeup
> > source, so the flag does not make any sense.
> 
> You have no seperate wakeup source mechanism. All you do is to mask all non
> wakeup sources and keep the wakeup sources unmask.
> 
> That's what happens in gpcv2_wakeup_source_save()
> 
>        writel_relaxed(cd->wakeup_sources[i], reg);
> 
> So it's the same as letting the core mask all non wakeup sources and leave the
> wakeup sources unmask.

Does it mean an unexpected interrupt may activate the system, and the core will let
the system go into suspend again if the core determines it not a wakeup source? The current design
is to ignore all the unexpected interrupts in the hardware level. Only the presetting 
wakeup sources can activate the platform. Here power consumption is more 
important.

> > > Now that it's already done for you, you need not do anything extra
> > > and hence just set SKIP_SET_WAKE to do nothing.
> >
> > static int set_irq_wake_real(unsigned int irq, unsigned int on) {
> > 	struct irq_desc *desc = irq_to_desc(irq);
> > 	int ret = -ENXIO;
> >
> > 	if (irq_desc_get_chip(desc)->flags &  IRQCHIP_SKIP_SET_WAKE)
> > 		return 0;
> >
> > 	if (desc->irq_data.chip->irq_set_wake)
> > 		ret = desc->irq_data.chip->irq_set_wake(&desc->irq_data, on);
> >
> > 	return ret;
> > }
> > From the codes above, if a irqchip can not handle the wakeup sources,
> > it can set SKIP flag.  This driver is intended to manage the wakeup
> > sources, what's the reason to skip here?
> 
> To reduce code. Everything the core can do for you is something you don't have to
> implement.

Same as above.

Thanks,
Shenwei

> Thanks,
> 
> 	tglx

From mcoquelin.stm32 at gmail.com  Tue Aug 25 13:07:17 2015
From: mcoquelin.stm32 at gmail.com (Maxime Coquelin)
Date: Tue, 25 Aug 2015 22:07:17 +0200
Subject: [PATCH] ARM: stm32: Reduce FORCE_MAX_ZONEORDER to 9
Message-ID: <1440533237-5831-1-git-send-email-mcoquelin.stm32@gmail.com>

STM32 boards having small amount of RAM, we can optimize by reducing max order
page blocks size.

Suggested-by: Andreas F?rber <afaerber at suse.de>
Signed-off-by: Maxime Coquelin <mcoquelin.stm32 at gmail.com>
---
 arch/arm/Kconfig | 2 +-
 1 file changed, 1 insertion(+), 1 deletion(-)

diff --git a/arch/arm/Kconfig b/arch/arm/Kconfig
index a750c14..57d53af 100644
--- a/arch/arm/Kconfig
+++ b/arch/arm/Kconfig
@@ -1734,7 +1734,7 @@ config FORCE_MAX_ZONEORDER
 	int "Maximum zone order" if ARCH_SHMOBILE_LEGACY
 	range 11 64 if ARCH_SHMOBILE_LEGACY
 	default "12" if SOC_AM33XX
-	default "9" if SA1111 || ARCH_EFM32
+	default "9" if SA1111 || ARCH_EFM32 || ARCH_STM32
 	default "11"
 	help
 	  The kernel memory allocator divides physically contiguous memory
-- 
1.9.1



From tglx at linutronix.de  Tue Aug 25 13:15:59 2015
From: tglx at linutronix.de (Thomas Gleixner)
Date: Tue, 25 Aug 2015 22:15:59 +0200 (CEST)
Subject: [PATCH v9 1/1] irqchip: imx-gpcv2: IMX GPCv2 driver for wakeup
 sources
In-Reply-To: <CY1PR0301MB08430902E0E46A43D00317C283610@CY1PR0301MB0843.namprd03.prod.outlook.com>
References: <1440443055-7291-1-git-send-email-shenwei.wang@freescale.com>
 <55DC3452.3070205@arm.com>
 <CY1PR0301MB08439B6C5F841AFFD152DFD883610@CY1PR0301MB0843.namprd03.prod.outlook.com>
 <55DC738D.8000302@arm.com>
 <CY1PR0301MB0843AE566996617D855CC00683610@CY1PR0301MB0843.namprd03.prod.outlook.com>
 <55DC7FA4.7040902@arm.com>
 <CY1PR0301MB08433A2659C75028821F0AE783610@CY1PR0301MB0843.namprd03.prod.outlook.com>
 <55DC96BA.2020905@arm.com>
 <CY1PR0301MB0843388CA3BB07493BC2907183610@CY1PR0301MB0843.namprd03.prod.outlook.com>
 <alpine.DEB.2.11.1508252126360.15006@nanos>
 <CY1PR0301MB08430902E0E46A43D00317C283610@CY1PR0301MB0843.namprd03.prod.outlook.com>
Message-ID: <alpine.DEB.2.11.1508252213220.15006@nanos>

On Tue, 25 Aug 2015, Shenwei Wang wrote:
> > From: Thomas Gleixner [mailto:tglx at linutronix.de]
> > > IRQCHIP_MASK_ON_SUSPEND flag is for the hardware that has no wakeup
> > > source capability.  This GPCv2 block is designed to manage the wakeup
> > > source, so the flag does not make any sense.
> > 
> > You have no seperate wakeup source mechanism. All you do is to mask all non
> > wakeup sources and keep the wakeup sources unmask.
> > 
> > That's what happens in gpcv2_wakeup_source_save()
> > 
> >        writel_relaxed(cd->wakeup_sources[i], reg);
> > 
> > So it's the same as letting the core mask all non wakeup sources and leave the
> > wakeup sources unmask.
> 
> Does it mean an unexpected interrupt may activate the system, and
> the core will let the system go into suspend again if the core
> determines it not a wakeup source? The current design is to ignore
> all the unexpected interrupts in the hardware level. Only the
> presetting wakeup sources can activate the platform. Here power
> consumption is more important.

Did you actually read, what I wrote?

The core does in case of MASK_ON_SUSPEND

    for_each_irq() {
	if (!irq->wakeupsource)
	   mask(irq)
    }

That's identical to what you are doing. You just do it differently by
saving the active wakeup sources in your own data structure and then
write that info to the mask register, which leaves only the wakeup
sources unmasked.

Thanks,

	tglx


From computersforpeace at gmail.com  Tue Aug 25 13:16:31 2015
From: computersforpeace at gmail.com (Brian Norris)
Date: Tue, 25 Aug 2015 13:16:31 -0700
Subject: [PATCH v10 1/5] mtd: nand: vf610_nfc: Freescale NFC for VF610,
 MPC5125 and others
In-Reply-To: <1438594050-4595-2-git-send-email-stefan@agner.ch>
References: <1438594050-4595-1-git-send-email-stefan@agner.ch>
 <1438594050-4595-2-git-send-email-stefan@agner.ch>
Message-ID: <20150825201631.GK81844@google.com>

A few more comments.

On Mon, Aug 03, 2015 at 11:27:26AM +0200, Stefan Agner wrote:
> diff --git a/drivers/mtd/nand/vf610_nfc.c b/drivers/mtd/nand/vf610_nfc.c
> new file mode 100644
> index 0000000..5c8dfe8
> --- /dev/null
> +++ b/drivers/mtd/nand/vf610_nfc.c
> @@ -0,0 +1,645 @@

...

> +/*
> + * This function supports Vybrid only (MPC5125 would have full RB and four CS)
> + */
> +static void vf610_nfc_select_chip(struct mtd_info *mtd, int chip)
> +{
> +#ifdef CONFIG_SOC_VF610

Why the #ifdef? I don't see anything compile-time specific to SOC_VF610.

If this is trying to handle the comment above ("This function supports
Vybrid only (MPC5125 would have full RB and four CS)") then that's the
wrong way of doing it, as you need to support multiplatform kernels.
You'll need to have a way to differentiate the different platform
support at runtime, not compile time.

> +	struct vf610_nfc *nfc = mtd_to_nfc(mtd);
> +	u32 tmp = vf610_nfc_read(nfc, NFC_ROW_ADDR);
> +
> +	tmp &= ~(ROW_ADDR_CHIP_SEL_RB_MASK | ROW_ADDR_CHIP_SEL_MASK);
> +	tmp |= 1 << ROW_ADDR_CHIP_SEL_RB_SHIFT;
> +
> +	if (chip == 0)
> +		tmp |= 1 << ROW_ADDR_CHIP_SEL_SHIFT;
> +	else if (chip == 1)
> +		tmp |= 2 << ROW_ADDR_CHIP_SEL_SHIFT;

	else ... ?

Maybe you can write this as a formulaic pattern (e.g.:

	tmp |= (chip + 1) << ROW_ADDR_CHIP_SEL_SHIFT;

) and just do the "max # of chips" checks on a per-platform basis in the
probe(). Then I'm guessing this same function can apply to both
platforms. (I'm not looking at HW datasheets for this, BTW, just
guessing based on the context here.)

But wait...I see that you call nand_scan_ident() with a max of 1 chip.
So you won't ever see the chip > 0 case, right?

So does this driver support multiple flash attached or not? Looks like
you're assuming you'll only be using chip-select 0. (This is fine for
now, but at least your code should acknowledge this. Perhaps a comment
at the top under "limitations.")

> +
> +	vf610_nfc_write(nfc, NFC_ROW_ADDR, tmp);
> +#endif
> +}

...

> +static int vf610_nfc_probe(struct platform_device *pdev)
> +{

...

> +	/* first scan to find the device and get the page size */
> +	if (nand_scan_ident(mtd, 1, NULL)) {
> +		err = -ENXIO;
> +		goto error;
> +	}

...

Brian


From heiko at sntech.de  Tue Aug 25 13:17:39 2015
From: heiko at sntech.de (Heiko Stuebner)
Date: Tue, 25 Aug 2015 22:17:39 +0200
Subject: [PATCH v2] clk: rockchip: add pclk_cpu to the list of rk3188
 critical clocks
In-Reply-To: <20150825185931.31346.26497@quantum>
References: <5400BEF8-5245-4F7B-845B-D326A7BC56B5@mniewoehner.de>
 <F5234F5E-2A91-4B63-B260-3F20A4D16A9D@mniewoehner.de>
 <20150825185931.31346.26497@quantum>
Message-ID: <1672317.UnLkKbcVf3@phil>

Am Dienstag, 25. August 2015, 11:59:31 schrieb Michael Turquette:
> Quoting Michael Niewoehner (2015-08-17 12:50:53)
> 
> > pclk_cpu needs to keep running because it is needed for devices like
> > the act8865 regulator but with the recent gpio clock handling this is
> > not always the case anymore. So add it to the list of critical clocks.
> > 
> > Signed-off-by: Michael Niewoehner <linux at mniewoehner.de>
> 
> Patch fails to apply due to a problem with line 15. git format-patch
> problem?

see comment below. We triggered this problem with a change to the pinctrl 
driver and another clock-entry to the critical clocks already went into Linus' 
pinctrl tree. So I guess this patch should probably also go through his tree - 
or just go in through any tree after 4.3-rc1.


> 
> Regards,
> Mike
> 
> > ---
> > Changes in v2:
> > - adapt commit message
> > - add Linus Walleij to recipients, as the patch is related to the gpio
> > clock> 
> >   change in the rockchip pinctrl driver it should go through his tree as
> >   well
> > 
> > drivers/clk/rockchip/clk-rk3188.c | 1 +
> > 1 file changed, 1 insertion(+)
> > 
> > diff --git a/drivers/clk/rockchip/clk-rk3188.c
> > b/drivers/clk/rockchip/clk-rk3188.c index e4f9d47..1c93229 100644
> > --- a/drivers/clk/rockchip/clk-rk3188.c
> > +++ b/drivers/clk/rockchip/clk-rk3188.c
> > @@ -708,6 +708,7 @@ static const char *const rk3188_critical_clocks[]
> > __initconst = {> 
> >         "aclk_cpu",
> >         "aclk_peri",
> >         "hclk_peri",
> > 
> > +       "pclk_cpu",
> > };
> > 
> > static void __init rk3188_common_clk_init(struct device_node *np)



From linux at mniewoehner.de  Tue Aug 25 13:22:07 2015
From: linux at mniewoehner.de (Michael Niewoehner)
Date: Tue, 25 Aug 2015 22:22:07 +0200
Subject: [PATCH v3] clk: rockchip: add pclk_cpu to the list of rk3188 critical
 clocks
In-Reply-To: <20150825185931.31346.26497@quantum>
References: <5400BEF8-5245-4F7B-845B-D326A7BC56B5@mniewoehner.de>
 <5275855.eah07vmf4I@phil>
 <9DBF9CCE-196E-43FB-BA76-BFB4B5F47A22@mniewoehner.de>
 <10213368.VjAQGt7Kjq@phil>
 <F5234F5E-2A91-4B63-B260-3F20A4D16A9D@mniewoehner.de>
 <20150825185931.31346.26497@quantum>
Message-ID: <8804658D-175F-4668-BC12-4AC439438B61@mniewoehner.de>

pclk_cpu needs to keep running because it is needed for devices like
the act8865 regulator but with the recent gpio clock handling this is
not always the case anymore. So add it to the list of critical clocks.

Signed-off-by: Michael Niewoehner <linux at mniewoehner.de>
Reviewed-by: Heiko Stuebner <heiko at sntech.de>
---
Changes in v3:
- fix git format-patch problem

Changes in v2:
- adapt commit message
- add Linus Walleij to recipients, as the patch is related to the gpio clock
 change in the rockchip pinctrl driver it should go through his tree as well

 drivers/clk/rockchip/clk-rk3188.c | 1 +
 1 file changed, 1 insertion(+)

diff --git a/drivers/clk/rockchip/clk-rk3188.c b/drivers/clk/rockchip/clk-rk3188.c
index ed02bbc..f63a642 100644
--- a/drivers/clk/rockchip/clk-rk3188.c
+++ b/drivers/clk/rockchip/clk-rk3188.c
@@ -716,6 +716,7 @@ static const char *const rk3188_critical_clocks[] __initconst = {
 	"aclk_cpu",
 	"aclk_peri",
 	"hclk_peri",
+	"pclk_cpu",
 };
 
 static void __init rk3188_common_clk_init(struct device_node *np)
-- 
2.5.0




From computersforpeace at gmail.com  Tue Aug 25 13:25:46 2015
From: computersforpeace at gmail.com (Brian Norris)
Date: Tue, 25 Aug 2015 13:25:46 -0700
Subject: [PATCH v10 3/5] mtd: nand: vf610_nfc: add device tree bindings
In-Reply-To: <1438594050-4595-4-git-send-email-stefan@agner.ch>
References: <1438594050-4595-1-git-send-email-stefan@agner.ch>
 <1438594050-4595-4-git-send-email-stefan@agner.ch>
Message-ID: <20150825202546.GL81844@google.com>

Sorry, I realized a potential issue here.

On Mon, Aug 03, 2015 at 11:27:28AM +0200, Stefan Agner wrote:
> Signed-off-by: Bill Pringlemeir <bpringlemeir at nbsps.com>
> Acked-by: Shawn Guo <shawnguo at kernel.org>
> Reviewed-by: Brian Norris <computersforpeace at gmail.com>
> Signed-off-by: Stefan Agner <stefan at agner.ch>
> ---
>  .../devicetree/bindings/mtd/vf610-nfc.txt          | 45 ++++++++++++++++++++++
>  1 file changed, 45 insertions(+)
>  create mode 100644 Documentation/devicetree/bindings/mtd/vf610-nfc.txt
> 
> diff --git a/Documentation/devicetree/bindings/mtd/vf610-nfc.txt b/Documentation/devicetree/bindings/mtd/vf610-nfc.txt
> new file mode 100644
> index 0000000..cae5f25
> --- /dev/null
> +++ b/Documentation/devicetree/bindings/mtd/vf610-nfc.txt
> @@ -0,0 +1,45 @@
> +Freescale's NAND flash controller (NFC)
> +
> +This variant of the Freescale NAND flash controller (NFC) can be found on
> +Vybrid (vf610), MPC5125, MCF54418 and Kinetis K70.
> +
> +Required properties:
> +- compatible: Should be set to "fsl,vf610-nfc"
> +- reg: address range of the NFC
> +- interrupts: interrupt of the NFC
> +- nand-bus-width: see nand.txt
> +- nand-ecc-mode: see nand.txt
> +- nand-on-flash-bbt: see nand.txt

Stumbling across the "multi-CS" questions on the driver reminds me: it
typically makes sense to define new NAND bindings using separate NAND
*controller* and *flash* device nodes. The above 3 properties, at least,
would apply on a per-flash basis, not per-controller typically. See
sunxi-nand, for instance:

http://lxr.free-electrons.com/source/Documentation/devicetree/bindings/mtd/sunxi-nand.txt

brcmnand had a similar pattern:

https://git.kernel.org/cgit/linux/kernel/git/torvalds/linux.git/tree/Documentation/devicetree/bindings/mtd/brcm,brcmnand.txt

(Perhaps it's time we standardized this a little more formally...)

> +- assigned-clocks: main clock from the SoC, for Vybrid <&clks VF610_CLK_NFC>;
> +- assigned-clock-rates: The NAND bus timing is derived from this clock
> +    rate and should not exceed maximum timing for any NAND memory chip
> +    in a board stuffing. Typical NAND memory timings derived from this
> +    clock are found in the SoC hardware reference manual. Furthermore,
> +    there might be restrictions on maximum rates when using hardware ECC.
> +
> +- #address-cells, #size-cells : Must be present if the device has sub-nodes
> +  representing partitions.
> +
> +Required properties for hardware ECC:
> +- nand-ecc-strength: supported strengths are 24 and 32 bit (see nand.txt)
> +- nand-ecc-step-size: step size equals page size, currently only 2k pages are
> +    supported
> +
> +Example:
> +
> +	nfc: nand at 400e0000 {
> +		compatible = "fsl,vf610-nfc";
> +		#address-cells = <1>;
> +		#size-cells = <1>;
> +		reg = <0x400e0000 0x4000>;
> +		interrupts = <GIC_SPI 83 IRQ_TYPE_LEVEL_HIGH>;
> +		clocks = <&clks VF610_CLK_NFC>;
> +		clock-names = "nfc";
> +		assigned-clocks = <&clks VF610_CLK_NFC>;
> +		assigned-clock-rates = <33000000>;
> +		nand-bus-width = <8>;
> +		nand-ecc-mode = "hw";
> +		nand-ecc-strength = <32>;
> +		nand-ecc-step-size = <2048>;
> +		nand-on-flash-bbt;
> +	};

Brian


From mturquette at baylibre.com  Tue Aug 25 13:25:51 2015
From: mturquette at baylibre.com (Michael Turquette)
Date: Tue, 25 Aug 2015 13:25:51 -0700
Subject: [PATCH v2 1/6] clk: berlin: move MAX_CLKS out of
 drivers/clk/berlin
In-Reply-To: <1439898368-11543-2-git-send-email-antoine.tenart@free-electrons.com>
References: <1439898368-11543-1-git-send-email-antoine.tenart@free-electrons.com>
 <1439898368-11543-2-git-send-email-antoine.tenart@free-electrons.com>
Message-ID: <20150825202551.31346.93685@quantum>

Quoting Antoine Tenart (2015-08-18 04:46:03)
> Move the MAX_CLKS definition used in the Berlin clock driver outside the
> driver.
> 
> Signed-off-by: Antoine Tenart <antoine.tenart at free-electrons.com>

Acked-by: Michael Turquette <mturquette at baylibre.com>

> ---
>  drivers/clk/berlin/bg2.c             | 1 -
>  drivers/clk/berlin/bg2q.c            | 1 -
>  include/dt-bindings/clock/berlin2.h  | 2 ++
>  include/dt-bindings/clock/berlin2q.h | 2 ++
>  4 files changed, 4 insertions(+), 2 deletions(-)
> 
> diff --git a/drivers/clk/berlin/bg2.c b/drivers/clk/berlin/bg2.c
> index 73153fc45ee9..469a2c57e1b4 100644
> --- a/drivers/clk/berlin/bg2.c
> +++ b/drivers/clk/berlin/bg2.c
> @@ -91,7 +91,6 @@
>   *
>   */
>  
> -#define        MAX_CLKS 41
>  static struct clk *clks[MAX_CLKS];
>  static struct clk_onecell_data clk_data;
>  static DEFINE_SPINLOCK(lock);
> diff --git a/drivers/clk/berlin/bg2q.c b/drivers/clk/berlin/bg2q.c
> index 221f40c2b850..a27958efab92 100644
> --- a/drivers/clk/berlin/bg2q.c
> +++ b/drivers/clk/berlin/bg2q.c
> @@ -45,7 +45,6 @@
>  #define REG_SDIO0XIN_CLKCTL    0x0158
>  #define REG_SDIO1XIN_CLKCTL    0x015c
>  
> -#define        MAX_CLKS 27
>  static struct clk *clks[MAX_CLKS];
>  static struct clk_onecell_data clk_data;
>  static DEFINE_SPINLOCK(lock);
> diff --git a/include/dt-bindings/clock/berlin2.h b/include/dt-bindings/clock/berlin2.h
> index 0c30800175df..97832b840beb 100644
> --- a/include/dt-bindings/clock/berlin2.h
> +++ b/include/dt-bindings/clock/berlin2.h
> @@ -43,3 +43,5 @@
>  #define CLKID_VIDEO1           38
>  #define CLKID_VIDEO2           39
>  #define CLKID_TWD              40
> +
> +#define MAX_CLKS               41
> diff --git a/include/dt-bindings/clock/berlin2q.h b/include/dt-bindings/clock/berlin2q.h
> index 287fc3b4afb2..c79af928ae92 100644
> --- a/include/dt-bindings/clock/berlin2q.h
> +++ b/include/dt-bindings/clock/berlin2q.h
> @@ -29,3 +29,5 @@
>  #define CLKID_SMEMC            24
>  #define CLKID_PCIE             25
>  #define CLKID_TWD              26
> +
> +#define MAX_CLKS               27
> -- 
> 2.5.0
> 
> --
> To unsubscribe from this list: send the line "unsubscribe linux-kernel" in
> the body of a message to majordomo at vger.kernel.org
> More majordomo info at  http://vger.kernel.org/majordomo-info.html
> Please read the FAQ at  http://www.tux.org/lkml/


From computersforpeace at gmail.com  Tue Aug 25 13:34:12 2015
From: computersforpeace at gmail.com (Brian Norris)
Date: Tue, 25 Aug 2015 13:34:12 -0700
Subject: [PATCH v10 1/5] mtd: nand: vf610_nfc: Freescale NFC for VF610,
 MPC5125 and others
In-Reply-To: <1438594050-4595-2-git-send-email-stefan@agner.ch>
References: <1438594050-4595-1-git-send-email-stefan@agner.ch>
 <1438594050-4595-2-git-send-email-stefan@agner.ch>
Message-ID: <20150825203412.GM81844@google.com>

One more thing...

On Mon, Aug 03, 2015 at 11:27:26AM +0200, Stefan Agner wrote:
> --- /dev/null
> +++ b/drivers/mtd/nand/vf610_nfc.c
> @@ -0,0 +1,645 @@
...
> +struct vf610_nfc {
> +	struct mtd_info mtd;
> +	struct nand_chip chip;
> +	struct device *dev;
> +	void __iomem *regs;
> +	struct completion cmd_done;
> +	uint buf_offset;
> +	int page_sz;

AFAICT (even with the 2nd patch), you never really use this field. You
just set it/increment it, but don't use it for anything. Kill it?

> +	/* Status and ID are in alternate locations. */
> +	int alt_buf;
> +#define ALT_BUF_ID   1
> +#define ALT_BUF_STAT 2
> +#define ALT_BUF_ONFI 3
> +	struct clk *clk;
> +};

Brian


From arnd at arndb.de  Tue Aug 25 13:36:22 2015
From: arnd at arndb.de (Arnd Bergmann)
Date: Tue, 25 Aug 2015 22:36:22 +0200
Subject: [PATCH] ARM: stm32: Reduce FORCE_MAX_ZONEORDER to 9
In-Reply-To: <1440533237-5831-1-git-send-email-mcoquelin.stm32@gmail.com>
References: <1440533237-5831-1-git-send-email-mcoquelin.stm32@gmail.com>
Message-ID: <3551937.qa4lRhD8e3@wuerfel>

On Tuesday 25 August 2015 22:07:17 Maxime Coquelin wrote:
> diff --git a/arch/arm/Kconfig b/arch/arm/Kconfig
> index a750c14..57d53af 100644
> --- a/arch/arm/Kconfig
> +++ b/arch/arm/Kconfig
> @@ -1734,7 +1734,7 @@ config FORCE_MAX_ZONEORDER
>         int "Maximum zone order" if ARCH_SHMOBILE_LEGACY
>         range 11 64 if ARCH_SHMOBILE_LEGACY
>         default "12" if SOC_AM33XX
> -       default "9" if SA1111 || ARCH_EFM32
> +       default "9" if SA1111 || ARCH_EFM32 || ARCH_STM32
>         default "11"
> 

This looks wrong now that we can enable multiple ARMV7M platforms
together. In practice it doesn't matter much, because you wouldn't
do that for a real-life system, but out of principle this seems
like something you'd better put into the defconfig file for
both ARCH_EFM32 and ARCH_STM32. We could also think about changing
the default to "9" for any ARM_SINGLE_ARMV7M config and increasing
it again in defconfig for any platform that actually has a lot of
RAM (if any).

The SOC_AM33XX is slightly different because it increases the default
rather than reducing it, presumably because the larger allocation is
actually required (for what?).

	Arnd


From agross at codeaurora.org  Tue Aug 25 13:36:35 2015
From: agross at codeaurora.org (Andy Gross)
Date: Tue, 25 Aug 2015 15:36:35 -0500
Subject: [PATCH] soc: qcom: smd: Use correct remote processor ID
Message-ID: <1440534995-12899-1-git-send-email-agross@codeaurora.org>

This patch fixes SMEM addressing issues when remote processors need to use
secure SMEM partitions.

Signed-off-by: Andy Gross <agross at codeaurora.org>
---
 .../devicetree/bindings/soc/qcom/qcom,smd.txt      |    7 +++++++
 drivers/soc/qcom/smd.c                             |   18 ++++++++++++++----
 2 files changed, 21 insertions(+), 4 deletions(-)

diff --git a/Documentation/devicetree/bindings/soc/qcom/qcom,smd.txt b/Documentation/devicetree/bindings/soc/qcom/qcom,smd.txt
index f65c76d..3b60702 100644
--- a/Documentation/devicetree/bindings/soc/qcom/qcom,smd.txt
+++ b/Documentation/devicetree/bindings/soc/qcom/qcom,smd.txt
@@ -37,6 +37,12 @@ The edge is described by the following properties:
 	Definition: the identifier of the remote processor in the smd channel
 		    allocation table
 
+- qcom,remote-pid:
+	Usage: required
+	Value type: <u32>
+	Definition: the identifier for the remote processor as known by the rest
+		    of the system.
+
 = SMD DEVICES
 
 In turn, subnodes of the "edges" represent devices tied to SMD channels on that
@@ -68,6 +74,7 @@ The following example represents a smd node, with one edge representing the
 			interrupts = <0 168 1>;
 			qcom,ipc = <&apcs 8 0>;
 			qcom,smd-edge = <15>;
+			qcom,remote-pid = <0xffffffff>;
 
 			rpm_requests {
 				compatible = "qcom,rpm-msm8974";
diff --git a/drivers/soc/qcom/smd.c b/drivers/soc/qcom/smd.c
index 327adcf..bca8aba 100644
--- a/drivers/soc/qcom/smd.c
+++ b/drivers/soc/qcom/smd.c
@@ -111,6 +111,7 @@ struct qcom_smd_edge {
 	struct qcom_smd *smd;
 	struct device_node *of_node;
 	unsigned edge_id;
+	unsigned remote_pid;
 
 	int irq;
 
@@ -572,7 +573,7 @@ static irqreturn_t qcom_smd_edge_intr(int irq, void *data)
 	 * have to scan if the amount of available space in smem have changed
 	 * since last scan.
 	 */
-	available = qcom_smem_get_free_space(edge->edge_id);
+	available = qcom_smem_get_free_space(edge->remote_pid);
 	if (available != edge->smem_available) {
 		edge->smem_available = available;
 		edge->need_rescan = true;
@@ -976,7 +977,8 @@ static struct qcom_smd_channel *qcom_smd_create_channel(struct qcom_smd_edge *ed
 	spin_lock_init(&channel->recv_lock);
 	init_waitqueue_head(&channel->fblockread_event);
 
-	ret = qcom_smem_get(edge->edge_id, smem_info_item, (void **)&info, &info_size);
+	ret = qcom_smem_get(edge->remote_pid, smem_info_item, (void **)&info,
+			    &info_size);
 	if (ret)
 		goto free_name_and_channel;
 
@@ -997,7 +999,8 @@ static struct qcom_smd_channel *qcom_smd_create_channel(struct qcom_smd_edge *ed
 		goto free_name_and_channel;
 	}
 
-	ret = qcom_smem_get(edge->edge_id, smem_fifo_item, &fifo_base, &fifo_size);
+	ret = qcom_smem_get(edge->remote_pid, smem_fifo_item, &fifo_base,
+			    &fifo_size);
 	if (ret)
 		goto free_name_and_channel;
 
@@ -1041,7 +1044,7 @@ static void qcom_discover_channels(struct qcom_smd_edge *edge)
 	int i;
 
 	for (tbl = 0; tbl < SMD_ALLOC_TBL_COUNT; tbl++) {
-		ret = qcom_smem_get(edge->edge_id,
+		ret = qcom_smem_get(edge->remote_pid,
 				    smem_items[tbl].alloc_tbl_id,
 				    (void **)&alloc_tbl,
 				    NULL);
@@ -1184,6 +1187,13 @@ static int qcom_smd_parse_edge(struct device *dev,
 		return -EINVAL;
 	}
 
+	key = "qcom,remote-pid";
+	ret = of_property_read_u32(node, key, &edge->remote_pid);
+	if (ret) {
+		dev_err(dev, "edge missing %s property\n", key);
+		return -EINVAL;
+	}
+
 	syscon_np = of_parse_phandle(node, "qcom,ipc", 0);
 	if (!syscon_np) {
 		dev_err(dev, "no qcom,ipc node\n");
-- 
The Qualcomm Innovation Center, Inc. is a member of the Code Aurora Forum,
hosted by The Linux Foundation



From robdclark at gmail.com  Tue Aug 25 13:42:18 2015
From: robdclark at gmail.com (Rob Clark)
Date: Tue, 25 Aug 2015 16:42:18 -0400
Subject: [PATCH 1/7] drm/vc4: Add devicetree bindings for VC4.
In-Reply-To: <CAL_JsqJxiGUR5BxBPyR3-0NxqWsOxMGrWQA6cMXe2pjTom__nw@mail.gmail.com>
References: <1439427380-2436-1-git-send-email-eric@anholt.net>
 <1439427380-2436-2-git-send-email-eric@anholt.net>
 <55CEC25E.7070303@wwwdotorg.org>
 <874mjxwyx5.fsf@eliezer.anholt.net>
 <CAL_JsqJxiGUR5BxBPyR3-0NxqWsOxMGrWQA6cMXe2pjTom__nw@mail.gmail.com>
Message-ID: <CAF6AEGu2fi0M7DsicHz+5SDHi1DyDRmvWjkmYPPgY6pZ423WcA@mail.gmail.com>

On Mon, Aug 24, 2015 at 9:47 AM, Rob Herring <robherring2 at gmail.com> wrote:
> On Mon, Aug 17, 2015 at 1:30 PM, Eric Anholt <eric at anholt.net> wrote:
>> Stephen Warren <swarren at wwwdotorg.org> writes:
>>
>>> On 08/12/2015 06:56 PM, Eric Anholt wrote:
>>>> Signed-off-by: Eric Anholt <eric at anholt.net>
>>>
>>> This one definitely needs a patch description, since someone might not
>>> know what a VC4 is, and "git log" won't show the text from the binding
>>> doc itself. I'd suggest adding the initial paragraph of the binding doc
>>> as the patch description, or more.
>>>
>>>> diff --git a/Documentation/devicetree/bindings/gpu/brcm,bcm-vc4.txt b/Documentation/devicetree/bindings/gpu/brcm,bcm-vc4.txt
>>
>>>> +- hvss:             List of references to HVS video scalers
>>>> +- encoders: List of references to output encoders (HDMI, SDTV)
>>>
>>> Would it make sense to make all those nodes child node of the vc4
>>> object. That way, there's no need to have these lists of objects; they
>>> can be automatically built up as the DT is enumerated. I know that e.g.
>>> the NVIDIA Tegra host1x binding works this way, and I think it may have
>>> been inspired by other similar cases.
>>
>> I've looked at tegra, and the component system used by msm appears to be
>> nicer than it.  To follow tegra's model, it looks like I need to build
>> this extra bus thing corresponding to host1x that is effectively the
>> drivers/base/component.c code, so that I can get at vc4's structure from
>> the component drivers.
>>
>>> Of course, this is only appropriate if the HW modules really are
>>> logically children of the VC4 HW module. Perhaps they aren't. If they
>>> aren't though, I wonder what this "vc4" module actually represents in HW?
>>
>> It's the subsystem, same as we use a subsystem node for msm, sti,
>> rockchip, imx, and exynos.  This appears to be the common model of how
>> the collection of graphics-related components is represented in the DT.
>
> I think most of these bindings are wrong. They are grouped together
> because that is what DRM wants not because that reflects the h/w. So
> convince me this is one block, not that it is what other people do.

I think, when it comes to more complex driver subsystems (like drm in
particular) we have a bit of mismatch between how things look from the
"pure hw ignoring sw" perspective, and the "how sw and in particular
userspace expects things" perspective.  Maybe it is less a problem in
other subsystems, where bindings map to things that are only visible
in the kernel, or well defined devices like uart or sata controller.
But when given the choice, I'm going to err on the side of not
confusing userspace and the large software stack that sits above
drm/kms, over dt purity.

Maybe it would be nice to have a sort of dt overlay that adds the bits
needed to tie together hw blocks that should be assembled into a
single logical device for linux and userspace (but maybe not some
other hypothetical operating system).  But so far that doesn't exist.
All we have is a hammer (devicetree), everything looks like a nail.
End result is we end up adding some things in the bindings which
aren't purely about the hw.  Until someone invents a screwdriver, I'm
not sure what else to do.  In the end, other hypothetical OS is free
to ignore those extra fields in the bindings if it doesn't need them.
So meh?

BR,
-R


> Rob
>
> _______________________________________________
> linux-arm-kernel mailing list
> linux-arm-kernel at lists.infradead.org
> http://lists.infradead.org/mailman/listinfo/linux-arm-kernel


From Shenwei.Wang at freescale.com  Tue Aug 25 13:43:36 2015
From: Shenwei.Wang at freescale.com (Shenwei Wang)
Date: Tue, 25 Aug 2015 20:43:36 +0000
Subject: [PATCH v9 1/1] irqchip: imx-gpcv2: IMX GPCv2 driver for wakeup
 sources
In-Reply-To: <alpine.DEB.2.11.1508252213220.15006@nanos>
References: <1440443055-7291-1-git-send-email-shenwei.wang@freescale.com>
 <55DC3452.3070205@arm.com>
 <CY1PR0301MB08439B6C5F841AFFD152DFD883610@CY1PR0301MB0843.namprd03.prod.outlook.com>
 <55DC738D.8000302@arm.com>
 <CY1PR0301MB0843AE566996617D855CC00683610@CY1PR0301MB0843.namprd03.prod.outlook.com>
 <55DC7FA4.7040902@arm.com>
 <CY1PR0301MB08433A2659C75028821F0AE783610@CY1PR0301MB0843.namprd03.prod.outlook.com>
 <55DC96BA.2020905@arm.com>
 <CY1PR0301MB0843388CA3BB07493BC2907183610@CY1PR0301MB0843.namprd03.prod.outlook.com>
 <alpine.DEB.2.11.1508252126360.15006@nanos>
 <CY1PR0301MB08430902E0E46A43D00317C283610@CY1PR0301MB0843.namprd03.prod.outlook.com>
 <alpine.DEB.2.11.1508252213220.15006@nanos>
Message-ID: <CY1PR0301MB08439BB31108FD3DDC234EDA83610@CY1PR0301MB0843.namprd03.prod.outlook.com>



> -----Original Message-----
> From: Thomas Gleixner [mailto:tglx at linutronix.de]
> Sent: 2015?8?25? 15:16
> To: Wang Shenwei-B38339
> Cc: Sudeep Holla; shawn.guo at linaro.org; jason at lakedaemon.net; Huang
> Yongcai-B20788; linux-kernel at vger.kernel.org;
> linux-arm-kernel at lists.infradead.org
> Subject: RE: [PATCH v9 1/1] irqchip: imx-gpcv2: IMX GPCv2 driver for wakeup
> sources
> 
> On Tue, 25 Aug 2015, Shenwei Wang wrote:
> > > From: Thomas Gleixner [mailto:tglx at linutronix.de]
> > > > IRQCHIP_MASK_ON_SUSPEND flag is for the hardware that has no
> > > > wakeup source capability.  This GPCv2 block is designed to manage
> > > > the wakeup source, so the flag does not make any sense.
> > >
> > > You have no seperate wakeup source mechanism. All you do is to mask
> > > all non wakeup sources and keep the wakeup sources unmask.
> > >
> > > That's what happens in gpcv2_wakeup_source_save()
> > >
> > >        writel_relaxed(cd->wakeup_sources[i], reg);
> > >
> > > So it's the same as letting the core mask all non wakeup sources and
> > > leave the wakeup sources unmask.
> >
> > Does it mean an unexpected interrupt may activate the system, and the
> > core will let the system go into suspend again if the core determines
> > it not a wakeup source? The current design is to ignore all the
> > unexpected interrupts in the hardware level. Only the presetting
> > wakeup sources can activate the platform. Here power consumption is
> > more important.
> 
> Did you actually read, what I wrote?
> 
> The core does in case of MASK_ON_SUSPEND
> 
>     for_each_irq() {
> 	if (!irq->wakeupsource)
> 	   mask(irq)
>     }
> 
> That's identical to what you are doing. You just do it differently by saving the
> active wakeup sources in your own data structure and then write that info to the
> mask register, which leaves only the wakeup sources unmasked.

Sorry. I just took a study on the two flags: MASK_ON_SUSPEND and IRQCHIP_SKIP_SET_WAKE.
MASK_ON_SUSPEND flag does simply the implementation. 
IRQCHIP_SKIP_SET_WAKE flag can't be used here because the wakeup sources are required for power management.
I will send out a subsequent patch to simply the implementation by using this idea.

Thank you Sudeep for the insightful review!

Thanks,
Shenwei



> Thanks,
> 
> 	tglx

From boris.brezillon at free-electrons.com  Tue Aug 25 13:43:35 2015
From: boris.brezillon at free-electrons.com (Boris Brezillon)
Date: Tue, 25 Aug 2015 22:43:35 +0200
Subject: [PATCH v10 2/5] mtd: nand: vf610_nfc: add hardware BCH-ECC support
In-Reply-To: <20150825195411.GJ81844@google.com>
References: <1438594050-4595-1-git-send-email-stefan@agner.ch>
 <1438594050-4595-3-git-send-email-stefan@agner.ch>
 <ff2e2716578a1ae5f0c4b0e0ca8bbdc3@agner.ch>
 <20150825195411.GJ81844@google.com>
Message-ID: <20150825224335.6f846a28@bbrezillon>

Brian, Stefan,

On Tue, 25 Aug 2015 12:54:11 -0700
Brian Norris <computersforpeace at gmail.com> wrote:

> On Mon, Aug 03, 2015 at 11:28:43AM +0200, Stefan Agner wrote:
> > On 2015-08-03 11:27, Stefan Agner wrote:
> > <snip>
> > > +static inline int vf610_nfc_correct_data(struct mtd_info *mtd, uint8_t *dat,
> > > +					 uint8_t *oob, int oob_loaded)
> > > +{
> > > +	struct vf610_nfc *nfc = mtd_to_nfc(mtd);
> > > +	u8 ecc_status;
> > > +	u8 ecc_count;
> > > +	int flip;
> > > +
> > > +	ecc_status = __raw_readb(nfc->regs + ECC_SRAM_ADDR * 8 + ECC_OFFSET);
> 
> Why __raw_readb()? That's not normally encourage, and it has issues with
> endianness. It looks like maybe this is actulaly a 32-bit register, and
> you're having trouble when trying to do bytewise access? I see this
> earlier:
> 
> /*
>  * ECC status is stored at NFC_CFG[ECCADD] +4 for little-endian
>  * and +7 for big-endian SoCs.
>  */
> #ifdef __LITTLE_ENDIAN
> #define ECC_OFFSET      4
> #else
> #define ECC_OFFSET      7
> #endif
> 
> So maybe you really just want:
> 
> #define ECC_OFFSET	4
> ...
> 	ecc_status = vf610_nfc_read(ECC_SRAM_ADDR * 8 + ECC_OFFSET) & 0xff;
> 
> ?
> 
> > > +	ecc_count = ecc_status & ECC_ERR_COUNT;
> > > +
> > > +	if (!(ecc_status & ECC_STATUS_MASK))
> > > +		return ecc_count;
> > > +
> > > +	if (!oob_loaded)
> > > +		vf610_nfc_read_buf(mtd, oob, mtd->oobsize);
> > > +
> > > +	/*
> > > +	 * On an erased page, bit count (including OOB) should be zero or
> > > +	 * at least less then half of the ECC strength.
> > > +	 */
> > > +	flip = count_written_bits(dat, nfc->chip.ecc.size, ecc_count);
> 
> Another side note: why are you using ecc_count as a max threshold? AIUI,
> an ECC algorithm doesn't really report useful error count information if
> it's above the correction limit. So wouldn't we be looking to count up
> to our SW threshold? i.e., ecc.strength / 2, or similar? Similar
> comments below.

The exact threshold value is still something I'm not sure about, though
I'm sure it should be correlated to ecc.strength value (whether it's
directly set to ecc.strength or less than ecc.strength is something
we'll have to figure out).

> 
> > > +	flip += count_written_bits(oob, mtd->oobsize - nfc->chip.ecc.bytes,
> > > +				   ecc_count);
> > 
> > With ECC the controller seems to clear the ECC bytes in SRAM buffer.
> > This is a dump of 64 Bit OOB with the 32-error ECC mode which requires
> > 60 bytes of OOB for ECC:
> > 
> > [   22.190273] ff ff ff ff 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
> > 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
> > 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
> 
> Hmm, that's not really good. The point is that we need to make sure that
> everything that could have been programmed (including the ECC area) was
> not actually programmed. But your ECC controller is not, contrary to
> MTD's expectations, dumping raw uncorrected data here.

Yep, for this test we really need the ECC bytes generated for the chunk
you're currently testing.
How to retrieve those bytes really depends on your NAND controller, but
such controllers usually provides a way to disable the ECC engine. The
only thing you'll have to do in this case is disable the ECC engine and
read the OOB data (using RNDOUT and read_buf for example).

> 
> > [   22.209698] vf610_nfc_correct_data, flips 1
> > 
> > Not sure if this is acceptable, but I now only count the bits in the
> > non-ECC area of the OOB.
> 
> That's not the intention of my suggestion. You're still missing out on a
> class of patterns that might look close to all 0xff but are not
> actually.

Exactly.

> 
> If the HW ECC really doesn't give you valid data+OOB at this point, then
> you might have to re-read with ECC disabled. Of course, that's got a
> performance cost...

As suggested above, if that's possible, reading the OOB area (or a
portion of the OOB area) with the ECC engine disabled should be enough.

> 
> Or perhaps Boris has a better suggestion? He's been surveying other NAND
> drivers that need to do similar things, and he's working on providing
> some support code for common design patterns.

Yep, the patch series is here in case you want to have a look [1].

Best Regards,

Boris

[1]https://patchwork.ozlabs.org/patch/509970/


-- 
Boris Brezillon, Free Electrons
Embedded Linux and Kernel engineering
http://free-electrons.com


From davem at davemloft.net  Tue Aug 25 13:49:12 2015
From: davem at davemloft.net (David Miller)
Date: Tue, 25 Aug 2015 13:49:12 -0700 (PDT)
Subject: [PATCH] net: sun4i-emac: Claim emac sram
In-Reply-To: <1440354698-11144-1-git-send-email-hdegoede@redhat.com>
References: <1440354698-11144-1-git-send-email-hdegoede@redhat.com>
Message-ID: <20150825.134912.1446921736351472961.davem@davemloft.net>

From: Hans de Goede <hdegoede at redhat.com>
Date: Sun, 23 Aug 2015 20:31:38 +0200

> Claim the emac sram ourselves, rather then relying on the bootloader
> having mapped the sram to the emac controller during boot.
> 
> Signed-off-by: Hans de Goede <hdegoede at redhat.com>

Applied to net-next, thanks.


From tglx at linutronix.de  Tue Aug 25 13:49:32 2015
From: tglx at linutronix.de (Thomas Gleixner)
Date: Tue, 25 Aug 2015 22:49:32 +0200 (CEST)
Subject: [PATCH v9 1/1] irqchip: imx-gpcv2: IMX GPCv2 driver for wakeup
 sources
In-Reply-To: <CY1PR0301MB08439BB31108FD3DDC234EDA83610@CY1PR0301MB0843.namprd03.prod.outlook.com>
References: <1440443055-7291-1-git-send-email-shenwei.wang@freescale.com>
 <55DC3452.3070205@arm.com>
 <CY1PR0301MB08439B6C5F841AFFD152DFD883610@CY1PR0301MB0843.namprd03.prod.outlook.com>
 <55DC738D.8000302@arm.com>
 <CY1PR0301MB0843AE566996617D855CC00683610@CY1PR0301MB0843.namprd03.prod.outlook.com>
 <55DC7FA4.7040902@arm.com>
 <CY1PR0301MB08433A2659C75028821F0AE783610@CY1PR0301MB0843.namprd03.prod.outlook.com>
 <55DC96BA.2020905@arm.com>
 <CY1PR0301MB0843388CA3BB07493BC2907183610@CY1PR0301MB0843.namprd03.prod.outlook.com>
 <alpine.DEB.2.11.1508252126360.15006@nanos>
 <CY1PR0301MB08430902E0E46A43D00317C283610@CY1PR0301MB0843.namprd03.prod.outlook.com>
 <alpine.DEB.2.11.1508252213220.15006@nanos>
 <CY1PR0301MB08439BB31108FD3DDC234EDA83610@CY1PR0301MB0843.namprd03.prod.outlook.com>
Message-ID: <alpine.DEB.2.11.1508252248040.15006@nanos>

On Tue, 25 Aug 2015, Shenwei Wang wrote:
> 
> IRQCHIP_SKIP_SET_WAKE flag can't be used here because the wakeup
> sources are required for power management.

You could use it. Instead of copying the saved values, you can read
the values back from the register.

Thanks,

	tglx


From Shenwei.Wang at freescale.com  Tue Aug 25 13:53:52 2015
From: Shenwei.Wang at freescale.com (Shenwei Wang)
Date: Tue, 25 Aug 2015 20:53:52 +0000
Subject: [PATCH v9 1/1] irqchip: imx-gpcv2: IMX GPCv2 driver for wakeup
 sources
In-Reply-To: <alpine.DEB.2.11.1508252248040.15006@nanos>
References: <1440443055-7291-1-git-send-email-shenwei.wang@freescale.com>
 <55DC3452.3070205@arm.com>
 <CY1PR0301MB08439B6C5F841AFFD152DFD883610@CY1PR0301MB0843.namprd03.prod.outlook.com>
 <55DC738D.8000302@arm.com>
 <CY1PR0301MB0843AE566996617D855CC00683610@CY1PR0301MB0843.namprd03.prod.outlook.com>
 <55DC7FA4.7040902@arm.com>
 <CY1PR0301MB08433A2659C75028821F0AE783610@CY1PR0301MB0843.namprd03.prod.outlook.com>
 <55DC96BA.2020905@arm.com>
 <CY1PR0301MB0843388CA3BB07493BC2907183610@CY1PR0301MB0843.namprd03.prod.outlook.com>
 <alpine.DEB.2.11.1508252126360.15006@nanos>
 <CY1PR0301MB08430902E0E46A43D00317C283610@CY1PR0301MB0843.namprd03.prod.outlook.com>
 <alpine.DEB.2.11.1508252213220.15006@nanos>
 <CY1PR0301MB08439BB31108FD3DDC234EDA83610@CY1PR0301MB0843.namprd03.prod.outlook.com>
 <alpine.DEB.2.11.1508252248040.15006@nanos>
Message-ID: <CY1PR0301MB08434BC3FDA533BF580598CC83610@CY1PR0301MB0843.namprd03.prod.outlook.com>



> -----Original Message-----
> From: Thomas Gleixner [mailto:tglx at linutronix.de]
> Sent: 2015?8?25? 15:50
> To: Wang Shenwei-B38339
> Cc: Sudeep Holla; shawn.guo at linaro.org; jason at lakedaemon.net; Huang
> Yongcai-B20788; linux-kernel at vger.kernel.org;
> linux-arm-kernel at lists.infradead.org
> Subject: RE: [PATCH v9 1/1] irqchip: imx-gpcv2: IMX GPCv2 driver for wakeup
> sources
> 
> On Tue, 25 Aug 2015, Shenwei Wang wrote:
> >
> > IRQCHIP_SKIP_SET_WAKE flag can't be used here because the wakeup
> > sources are required for power management.
> 
> You could use it. Instead of copying the saved values, you can read the values
> back from the register.

It is an option too. 

Thanks,
Shenwei

> Thanks,
> 
> 	tglx

From khilman at kernel.org  Tue Aug 25 13:57:16 2015
From: khilman at kernel.org (Kevin Hilman)
Date: Tue, 25 Aug 2015 13:57:16 -0700
Subject: [RESEND PATCH v16 3/4] soc: rockchip: power-domain: Add power
 domain driver
In-Reply-To: <1440487486-6154-4-git-send-email-wxt@rock-chips.com> (Caesar
 Wang's message of "Tue, 25 Aug 2015 15:24:45 +0800")
References: <1440487486-6154-1-git-send-email-wxt@rock-chips.com>
 <1440487486-6154-4-git-send-email-wxt@rock-chips.com>
Message-ID: <7hwpwjaxxv.fsf@deeprootsystems.com>

Caesar Wang <wxt at rock-chips.com> writes:

> This driver is found on RK3288 SoCs.
>
> In order to meet high performance and low power requirements, a power
> management unit is designed or saving power when RK3288 in low power
> mode.
> The RK3288 PMU is dedicated for managing the power of the whole chip.
>
> PMU can work in the Low Power Mode by setting bit[0] of PMU_PWRMODE_CON
> register. After setting the register, PMU would enter the Low Power mode.
> In the low power mode, pmu will auto power on/off the specified power
> domain, send idle req to specified power domain, shut down/up pll and
> so on. All of above are configurable by setting corresponding registers.
>
> Signed-off-by: jinkun.hong <jinkun.hong at rock-chips.com>
> Signed-off-by: Caesar Wang <wxt at rock-chips.com>

[...]

> diff --git a/drivers/soc/rockchip/Kconfig b/drivers/soc/rockchip/Kconfig
> new file mode 100644
> index 0000000..87a09c3
> --- /dev/null
> +++ b/drivers/soc/rockchip/Kconfig
> @@ -0,0 +1,13 @@
> +#
> +# Rockchip Soc drivers
> +#
> +config PM_GENERIC_DOMAINS

Why are you (re)defining this config option?  This name is already used in kernel/pm/Kconfig.

Kevin


From mcoquelin.stm32 at gmail.com  Tue Aug 25 14:03:29 2015
From: mcoquelin.stm32 at gmail.com (Maxime Coquelin)
Date: Tue, 25 Aug 2015 23:03:29 +0200
Subject: [PATCH] ARM: stm32: Reduce FORCE_MAX_ZONEORDER to 9
In-Reply-To: <3551937.qa4lRhD8e3@wuerfel>
References: <1440533237-5831-1-git-send-email-mcoquelin.stm32@gmail.com>
 <3551937.qa4lRhD8e3@wuerfel>
Message-ID: <55DCD821.5040600@gmail.com>



On 08/25/2015 10:36 PM, Arnd Bergmann wrote:
> On Tuesday 25 August 2015 22:07:17 Maxime Coquelin wrote:
>> diff --git a/arch/arm/Kconfig b/arch/arm/Kconfig
>> index a750c14..57d53af 100644
>> --- a/arch/arm/Kconfig
>> +++ b/arch/arm/Kconfig
>> @@ -1734,7 +1734,7 @@ config FORCE_MAX_ZONEORDER
>>          int "Maximum zone order" if ARCH_SHMOBILE_LEGACY
>>          range 11 64 if ARCH_SHMOBILE_LEGACY
>>          default "12" if SOC_AM33XX
>> -       default "9" if SA1111 || ARCH_EFM32
>> +       default "9" if SA1111 || ARCH_EFM32 || ARCH_STM32
>>          default "11"
>>
> This looks wrong now that we can enable multiple ARMV7M platforms
> together. In practice it doesn't matter much, because you wouldn't
> do that for a real-life system, but out of principle this seems
> like something you'd better put into the defconfig file for
> both ARCH_EFM32 and ARCH_STM32. We could also think about changing
> the default to "9" for any ARM_SINGLE_ARMV7M config and increasing
> it again in defconfig for any platform that actually has a lot of
> RAM (if any).
>

Both proposals seem reasonable.
I propose to make this entry configurable in defconfig if ARM_SINGLE_ARMV7M,
keeping the default to 11. Then, in efm32 and stm32 defconfig files, 
select value 9.

Uwe, is it ok for you?

Regards,
Maxime


From khilman at kernel.org  Tue Aug 25 14:07:04 2015
From: khilman at kernel.org (Kevin Hilman)
Date: Tue, 25 Aug 2015 14:07:04 -0700
Subject: [RESEND PATCH v16 4/4] ARM: dts: add the support power-domain
 node on RK3288 SoCs
In-Reply-To: <1440487486-6154-5-git-send-email-wxt@rock-chips.com> (Caesar
 Wang's message of "Tue, 25 Aug 2015 15:24:46 +0800")
References: <1440487486-6154-1-git-send-email-wxt@rock-chips.com>
 <1440487486-6154-5-git-send-email-wxt@rock-chips.com>
Message-ID: <7hfv37axhj.fsf@deeprootsystems.com>

Caesar Wang <wxt at rock-chips.com> writes:

> We can add more domains node in the future.
> This patch add the needed clocks into power-controller.
> As the discuess about all the device clocks being listed in
> the power-domains itself.
>
> There are several reasons as follows:
>
> Firstly, the clocks need be turned off to save power when
> the system enter the suspend state. So we need to enumerate
> the clocks in the dts. In order to power domain can turn on and off.

Yes, but this is the job of device drivers which are runtime PM adapted
to gate their own clocks.  I agree these clocks need to be enumerated in
the DTS, but they should be in the device nodes.

> Secondly, the reset-circuit should reset be synchronous on RK3288,
> then sync revoked. So we need to enable clocks of all devices.
> In other words, we have to enable the clocks before you operate them
> if all the device clocks are included in someone domians.

Yes, this is pretty common for reset.  

> Someone wish was to get the clocks by reading the clocks from the
> device nodes, We can do that but we can solve the above issues.

I don't follow this sentence.  Are you saying doing that will not solve
the above issues?  Why not?  Please explain.

If there are non-device clocks that also need to be enabled before
asserting reset, then those are candidates for the power-domain node,
but not device clocks.

> Anyway, the best ideas we can fix it in the future SoCs.

I don't think this is an SoC design issue as this is needed when you
have synchronous reset.  My concern is primarily around how to describe
this in the DT.

Kevin


From agross at codeaurora.org  Tue Aug 25 14:08:57 2015
From: agross at codeaurora.org (Andy Gross)
Date: Tue, 25 Aug 2015 16:08:57 -0500
Subject: [PATCH] arm64: dts: qcom: Add RNG device tree node
In-Reply-To: <1440517062-30313-1-git-send-email-stanimir.varbanov@linaro.org>
References: <1440517062-30313-1-git-send-email-stanimir.varbanov@linaro.org>
Message-ID: <20150825210857.GA12349@qualcomm.com>

On Tue, Aug 25, 2015 at 06:37:42PM +0300, Stanimir Varbanov wrote:
> Adds rng device tree node for msm8916 SoCs.
> 
> Signed-off-by: Stanimir Varbanov <stanimir.varbanov at linaro.org>
> ---
>  arch/arm64/boot/dts/qcom/msm8916.dtsi |    7 +++++++
>  1 file changed, 7 insertions(+)

Looks good to me.  Applied.

-- 
Qualcomm Innovation Center, Inc.
The Qualcomm Innovation Center, Inc. is a member of the Code Aurora Forum,
a Linux Foundation Collaborative Project



From djkurtz at chromium.org  Tue Aug 25 14:11:47 2015
From: djkurtz at chromium.org (Daniel Kurtz)
Date: Wed, 26 Aug 2015 05:11:47 +0800
Subject: [PATCH v2] soc: mediatek: add scpsys support active_wakeup
In-Reply-To: <1440482440-28700-1-git-send-email-eddie.huang@mediatek.com>
References: <1440482440-28700-1-git-send-email-eddie.huang@mediatek.com>
Message-ID: <CAGS+omBqTbcJk-6QvupV4tkB5WQm97zpb5NzZ-S2ivR-UEWF4g@mail.gmail.com>

Hi Eddie,

On Tue, Aug 25, 2015 at 2:00 PM, Eddie Huang <eddie.huang at mediatek.com> wrote:
> Register gpd_dev_ops.active_wakeup function to support keep power
> during suspend state. And add flag to each power domain to
> decide whether keep power during suspend or not.
>
> Signed-off-by: Chunfeng Yun <chunfeng.yun at mediatek.com>
> Signed-off-by: Eddie Huang <eddie.huang at mediatek.com>
> Acked-by: Sascha Hauer <s.hauer at pengutronix.de>
>
> ---
> Change in v2:
> Drop .active_wakeup = false lines in scp_domain_data[] array
>
> ---
>  drivers/soc/mediatek/mtk-scpsys.c | 19 +++++++++++++++++++
>  1 file changed, 19 insertions(+)
>
> diff --git a/drivers/soc/mediatek/mtk-scpsys.c b/drivers/soc/mediatek/mtk-scpsys.c
> index 43a79ed..df2f288 100644
> --- a/drivers/soc/mediatek/mtk-scpsys.c
> +++ b/drivers/soc/mediatek/mtk-scpsys.c
> @@ -67,6 +67,7 @@ struct scp_domain_data {
>         u32 sram_pdn_ack_bits;
>         u32 bus_prot_mask;
>         enum clk_id clk_id;
> +       bool active_wakeup;
>  };
>
>  static const struct scp_domain_data scp_domain_data[] __initconst = {
> @@ -127,6 +128,7 @@ static const struct scp_domain_data scp_domain_data[] __initconst = {
>                 .sram_pdn_bits = GENMASK(11, 8),
>                 .sram_pdn_ack_bits = GENMASK(15, 12),
>                 .clk_id = MT8173_CLK_NONE,
> +               .active_wakeup = true,
>         },
>         [MT8173_POWER_DOMAIN_MFG_ASYNC] = {
>                 .name = "mfg_async",
> @@ -171,6 +173,7 @@ struct scp_domain {
>         u32 sram_pdn_bits;
>         u32 sram_pdn_ack_bits;
>         u32 bus_prot_mask;
> +       bool active_wakeup;
>  };
>
>  struct scp {
> @@ -370,6 +373,20 @@ out:
>         return ret;
>  }
>
> +static bool scpsys_active_wakeup(struct device *dev)
> +{
> +       struct generic_pm_domain *genpd;
> +       struct scp_domain *scpd;
> +
> +       if (IS_ERR_OR_NULL(dev->pm_domain))
> +               return false;

Is it really possible to get here w/ pm_domain as an ERR or NULL?
If the power core can ensure this cannot happen, then this function
could be a bit simpler.

Other than that, this patch is:
Reviewed-by: Daniel Kurtz <djkurtz at chromium.org>

-Dan

> +
> +       genpd = pd_to_genpd(dev->pm_domain);
> +       scpd = container_of(genpd, struct scp_domain, genpd);
> +
> +       return scpd->active_wakeup;
> +}


From sboyd at codeaurora.org  Tue Aug 25 14:14:05 2015
From: sboyd at codeaurora.org (Stephen Boyd)
Date: Tue, 25 Aug 2015 14:14:05 -0700
Subject: [PATCH v3] qcom: ipq40xx: Add basic board/dts support for
 IPQ40XX SoC
In-Reply-To: <20150825081042.GA14028@codeaurora.org>
References: <20150824092813.GA15581@codeaurora.org>
 <20150824224928.GE14330@codeaurora.org>
 <20150825081042.GA14028@codeaurora.org>
Message-ID: <20150825211405.GJ19120@codeaurora.org>

On 08/25, Varadarajan Narayanan wrote:
> On Mon, Aug 24, 2015 at 03:49:28PM -0700, Stephen Boyd wrote:
> > On 08/24, Varadarajan Narayanan wrote:
> 
> > > +	compatible = "qcom,ipq40xx-r3pc", "qcom,ipq40xx";
> > > +
> > > +	memory {
> > > +		device_type = "memory";
> > > +		reg = <0x80000000 0x20000000>; /* 512MB */
> > > +	};
> >
> > Doesn't the bootloader fill the memory node for us? Why do we
> > need this?
> >
> > > +
> > > +	chosen {
> > > +		bootargs = "root=/dev/ram rw init=/init console=ttyMSM0,115200n8 initrd=0x82000000,0x000E2246";
> > > +	};
> >
> > Please don't add bootargs. Use stdout-path for the console part
> > and everything else should be done by the bootloader or is the
> > defaults.
> 
> Since this is for the emulation platform, we don't have the bootloader.

Why are we upstreaming an emulation platform?

I assume you have some sort of scripts or something to load the
kernel image into the emulator, so those scripts could go and
modify the dtb in place to populate the initrd and commandline.
If you need pointers on that feel free to contact me directly.

> 
> > > +			compatible = "arm,armv7-timer";
> > > +			interrupts = <1 2 0xf08>,
> > > +				     <1 3 0xf08>,
> > > +				     <1 4 0xf08>,
> > > +				     <1 1 0xf08>;
> > > +			clock-frequency = <20833333>;
> >
> > Drop this clock-frequency part if you can. The hardware should
> > properly report the frequency.
> 
> Cannot drop this. This is the ref-clock frequency. For the
> chip it is 48MHz, for emulation is ~20MHz. Similar to
> https://git.kernel.org/cgit/linux/kernel/git/torvalds/linux.git/tree/arch/arm/boot/dts/qcom-msm8974.dtsi#n89

And the hardware is not emulated properly to report the actual
frequency that the timer is running at? That's sad.

At the least, this should be in the board specific dtsi file
instead of the SoC specific file, because it's a board quirk.

-- 
Qualcomm Innovation Center, Inc. is a member of Code Aurora Forum,
a Linux Foundation Collaborative Project


From agross at codeaurora.org  Tue Aug 25 14:24:09 2015
From: agross at codeaurora.org (Andy Gross)
Date: Tue, 25 Aug 2015 16:24:09 -0500
Subject: [PATCH v2 4/6] ARM: dts: qs600: remove unnecessary i2c pinctrl
 nodes in board file.
In-Reply-To: <1439903419-20275-1-git-send-email-srinivas.kandagatla@linaro.org>
References: <1439903069-19752-1-git-send-email-srinivas.kandagatla@linaro.org>
 <1439903419-20275-1-git-send-email-srinivas.kandagatla@linaro.org>
Message-ID: <20150825212409.GB12349@qualcomm.com>

On Tue, Aug 18, 2015 at 02:10:19PM +0100, Srinivas Kandagatla wrote:
> This patch removes unnecessary i2c pinctrl nodes in board file, these
> are already defined in the soc specific file qcom-apq8064.dtsi.
> 
> Signed-off-by: Srinivas Kandagatla <srinivas.kandagatla at linaro.org>
> ---
>  arch/arm/boot/dts/qcom-apq8064-cm-qs600.dts | 9 ---------
>  1 file changed, 9 deletions(-)

Applied, thanks!

-- 
Qualcomm Innovation Center, Inc.
The Qualcomm Innovation Center, Inc. is a member of the Code Aurora Forum,
a Linux Foundation Collaborative Project



From sboyd at codeaurora.org  Tue Aug 25 14:33:13 2015
From: sboyd at codeaurora.org (Stephen Boyd)
Date: Tue, 25 Aug 2015 14:33:13 -0700
Subject: [PATCH v2 1/6] ARM: dts: ifc6410: Add pwrseq support for WLAN
In-Reply-To: <1439903212-19931-1-git-send-email-srinivas.kandagatla@linaro.org>
References: <1439903069-19752-1-git-send-email-srinivas.kandagatla@linaro.org>
 <1439903212-19931-1-git-send-email-srinivas.kandagatla@linaro.org>
Message-ID: <55DCDF19.4070901@codeaurora.org>

On 08/18/2015 06:06 AM, Srinivas Kandagatla wrote:
> @@ -10,6 +11,20 @@
>   		serial1 = &gsbi6_serial;
>   	};
>   
> +	pwrseq {
> +		#address-cells = <1>;
> +		#size-cells = <1>;
> +		ranges;

Why do we need any of these three properties?

> +		compatible = "simple-bus";
> +
> +		sdcc4_pwrseq: sdcc4_pwrseq {
> +			pinctrl-names = "default";
> +			pinctrl-0 = <&wlan_default_gpios>;
> +			compatible = "mmc-pwrseq-simple";
> +			reset-gpios = <&pm8921_gpio 43 GPIO_ACTIVE_LOW>;

Especially because this node doesn't have a reg property.

-- 
Qualcomm Innovation Center, Inc. is a member of Code Aurora Forum,
a Linux Foundation Collaborative Project



From sboyd at codeaurora.org  Tue Aug 25 14:36:01 2015
From: sboyd at codeaurora.org (Stephen Boyd)
Date: Tue, 25 Aug 2015 14:36:01 -0700
Subject: [PATCH v2 3/6] ARM: dts: apq8064-ifc6410: add notify led support.
In-Reply-To: <1439903409-20233-1-git-send-email-srinivas.kandagatla@linaro.org>
References: <1439903069-19752-1-git-send-email-srinivas.kandagatla@linaro.org>
 <1439903409-20233-1-git-send-email-srinivas.kandagatla@linaro.org>
Message-ID: <55DCDFC1.4010803@codeaurora.org>

On 08/18/2015 06:10 AM, Srinivas Kandagatla wrote:
> diff --git a/arch/arm/boot/dts/qcom-apq8064-ifc6410.dts b/arch/arm/boot/dts/qcom-apq8064-ifc6410.dts
> index b1f9ddb..08daafe 100644
> --- a/arch/arm/boot/dts/qcom-apq8064-ifc6410.dts
> +++ b/arch/arm/boot/dts/qcom-apq8064-ifc6410.dts
> @@ -221,6 +221,18 @@
>   			status = "okay";
>   		};
>   
> +		leds {
> +			compatible = "gpio-leds";
> +			pinctrl-names = "default";
> +			pinctrl-0 = <&notify_led>;
> +
> +			led at 1 {
> +				label = "apq8064:green:user1";
> +				gpios = <&pm8921_gpio 18 GPIO_ACTIVE_HIGH>;
> +				default-state = "on";
> +			};
> +		};

Wrong place. Should be in root, not soc node.

-- 
Qualcomm Innovation Center, Inc. is a member of Code Aurora Forum,
a Linux Foundation Collaborative Project



From sboyd at codeaurora.org  Tue Aug 25 14:39:06 2015
From: sboyd at codeaurora.org (Stephen Boyd)
Date: Tue, 25 Aug 2015 14:39:06 -0700
Subject: [PATCH v2 5/6] ARM: dts: qs600: add alias to serial0
In-Reply-To: <1439903427-20317-1-git-send-email-srinivas.kandagatla@linaro.org>
References: <1439903069-19752-1-git-send-email-srinivas.kandagatla@linaro.org>
 <1439903427-20317-1-git-send-email-srinivas.kandagatla@linaro.org>
Message-ID: <55DCE07A.8000105@codeaurora.org>

On 08/18/2015 06:10 AM, Srinivas Kandagatla wrote:
> This patch add alias node with serial0.
>
> Signed-off-by: Srinivas Kandagatla <srinivas.kandagatla at linaro.org>
> ---

I have a whole set of patches to add all the serial aliases and 
stdout-path properties [1]. Please drop this patch from your series.

[1] 
http://lkml.kernel.org/r/1434490313-13905-1-git-send-email-sboyd at codeaurora.org

-- 
Qualcomm Innovation Center, Inc. is a member of Code Aurora Forum,
a Linux Foundation Collaborative Project



From agross at codeaurora.org  Tue Aug 25 14:46:22 2015
From: agross at codeaurora.org (Andy Gross)
Date: Tue, 25 Aug 2015 16:46:22 -0500
Subject: [PATCH v2 5/6] ARM: dts: qs600: add alias to serial0
In-Reply-To: <1439903427-20317-1-git-send-email-srinivas.kandagatla@linaro.org>
References: <1439903069-19752-1-git-send-email-srinivas.kandagatla@linaro.org>
 <1439903427-20317-1-git-send-email-srinivas.kandagatla@linaro.org>
Message-ID: <20150825214622.GC12349@qualcomm.com>

On Tue, Aug 18, 2015 at 02:10:27PM +0100, Srinivas Kandagatla wrote:
> This patch add alias node with serial0.
> 
> Signed-off-by: Srinivas Kandagatla <srinivas.kandagatla at linaro.org>
> ---
>  arch/arm/boot/dts/qcom-apq8064-cm-qs600.dts | 4 ++++
>  1 file changed, 4 insertions(+)

Looks fine.  Applied.

-- 
Qualcomm Innovation Center, Inc.
The Qualcomm Innovation Center, Inc. is a member of the Code Aurora Forum,
a Linux Foundation Collaborative Project



From heiko at sntech.de  Tue Aug 25 14:47:24 2015
From: heiko at sntech.de (Heiko Stuebner)
Date: Tue, 25 Aug 2015 23:47:24 +0200
Subject: [GIT PULL] ARM64: juno: SCPI and dependent drivers for v4.3
In-Reply-To: <20150821161732.GC14452@localhost>
References: <55C1E3FB.5090309@arm.com> <55CCAF50.4040503@arm.com>
 <20150821161732.GC14452@localhost>
Message-ID: <10834223.pThsip28PI@phil>

Hi,

Am Freitag, 21. August 2015, 09:17:32 schrieb Olof Johansson:
> > >PSCI only covers CPU boot/cpuidle and platform suspend. It does not have
> > >any provisions for DVFS and I'm not sure this could be easily
> > >standardised (or whether we could find enough supporters to get it
> > >adopted).
> > 
> > Though we are not campaigning it as aggressively as PSCI.
> 
> Which, given the resistance to pick up PSCI, this is unlikely to be used by
> anyone...

Rockchip seems to use SCPI to offload ddr frequency to a mcu scaling on the 
rk3368 ;-)


Heiko


From dianders at chromium.org  Tue Aug 25 14:48:41 2015
From: dianders at chromium.org (Doug Anderson)
Date: Tue, 25 Aug 2015 14:48:41 -0700
Subject: [RESEND PATCH v16 4/4] ARM: dts: add the support power-domain
 node on RK3288 SoCs
In-Reply-To: <7hfv37axhj.fsf@deeprootsystems.com>
References: <1440487486-6154-1-git-send-email-wxt@rock-chips.com>
 <1440487486-6154-5-git-send-email-wxt@rock-chips.com>
 <7hfv37axhj.fsf@deeprootsystems.com>
Message-ID: <CAD=FV=V6oG+9U=W_JZmqCuNo-9-5wW8ffZzG7ZE_3cnSTNAjFQ@mail.gmail.com>

Kevin,

On Tue, Aug 25, 2015 at 2:07 PM, Kevin Hilman <khilman at kernel.org> wrote:
> Caesar Wang <wxt at rock-chips.com> writes:
>
>> We can add more domains node in the future.
>> This patch add the needed clocks into power-controller.
>> As the discuess about all the device clocks being listed in
>> the power-domains itself.
>>
>> There are several reasons as follows:
>>
>> Firstly, the clocks need be turned off to save power when
>> the system enter the suspend state. So we need to enumerate
>> the clocks in the dts. In order to power domain can turn on and off.
>
> Yes, but this is the job of device drivers which are runtime PM adapted
> to gate their own clocks.  I agree these clocks need to be enumerated in
> the DTS, but they should be in the device nodes.

I _think_ what Caesar means is that the alternative to this patch is
to leave the clocks on all the time as they were during the early days
of Rockchip (AKA last year).  If the clocks are on all the time then
the power domain patches can work fine.  However, once you start
letting clocks turn off then you need to make sure that the power
domain code turns the back on temporarily.


>> Secondly, the reset-circuit should reset be synchronous on RK3288,
>> then sync revoked. So we need to enable clocks of all devices.
>> In other words, we have to enable the clocks before you operate them
>> if all the device clocks are included in someone domians.
>
> Yes, this is pretty common for reset.
>
>> Someone wish was to get the clocks by reading the clocks from the
>> device nodes, We can do that but we can solve the above issues.
>
> I don't follow this sentence.  Are you saying doing that will not solve
> the above issues?  Why not?  Please explain.
>
> If there are non-device clocks that also need to be enabled before
> asserting reset, then those are candidates for the power-domain node,
> but not device clocks.

It's been a long time and I don't know that I've reviewed every
revision of this series, but I think there was a proposal that we
shouldn't list clocks here.  Instead we should search through and find
all devices that refer to this power domain, reach in and find their
clocks, and turn them on.  Did I get that right?  To put things in a
concrete way, for pd_vio we'd go through the entire device tree
ourselves and find all properties that look like "power-domains =
<&power RK3288_PD_VIO>;".  We'd then find the parent of those
properties and look for a property named "clocks".  We'd then iterate
over all those clocks and turn those on.  Did I get that right?

The above doesn't seem like a terribly great idea to me for a number
of reasons, including:

1. If I remember correctly, it's important to turn on clocks for
devices even if they're not something you're using / have a driver
for.  If you don't then the device won't get reset properly and this
can affect things like suspend/resume because the hardware in the SoC
will query all devices at suspend time to make sure they're ready.  If
a device is wedged because its clock wasn't on at the right them then
it will cause problems.

2. If we absolutely need to turn all clocks and we get clocks from
device tree nodes on then it means we need device tree nodes for every
device in the domain.  These would be needed even if there are no
accepted bindings for this device yet.  So we'd need to do one of: A)
Block power domain patches on feature complete bindings for all
drivers; B) Make up non-approved compatible strings for all devices
and throw them into the DTS; C) Add nodes in the DTS without a
compatible string just to satisfy the power domain requirements.  None
of these seem terribly appealing.

3. It is entirely possible that there are clocks that will be listed
in the individual devices that aren't needed for powering on the power
domain.  I'd tend to believe that PCLK_EDP_CTRL (the pixel clock)
doesn't really need to be turned on when adjusting the "VIO" power
domain.  Right now Caesar has it listed, but it probably isn't needed
(Caesar: can you confirm?).

4. It seems just slightly brittle to be reaching into other device
nodes and making assumptions about their properties.  Yeah, it's
probably safe to assume that "clocks" has a list of clocks and
"power-domains" will point to something whose first entry is a
phandle, but it still seems just a tad bit like violating an
abstraction barrier.


Anyway, perhaps I'm misunderstanding, or perhaps my concerns are
simply not for important things.  If so feel free to yell at me.  ;)


>> Anyway, the best ideas we can fix it in the future SoCs.
>
> I don't think this is an SoC design issue as this is needed when you
> have synchronous reset.  My concern is primarily around how to describe
> this in the DT.

I suppose the SoC could override things and make sure clocks are on in
this case?  ...or if a clock is off it could defer powering it up
somehow until the clock came on?  ...dunno how this actually looks in
hardware.  In any case letting devices get wedged doesn't seem
ideal...

-Doug


From vishalm at ti.com  Tue Aug 25 14:50:50 2015
From: vishalm at ti.com (Vishal Mahaveer)
Date: Tue, 25 Aug 2015 16:50:50 -0500
Subject: [PATCH] ARM: dts: DRA7: fix a typo in ethernet
Message-ID: <1440539450-8393-1-git-send-email-vishalm@ti.com>

Register address in name of the node is wrong

Signed-off-by: Vishal Mahaveer <vishalm at ti.com>
Acked-by: Mugunthan V N <mugunthanvnm at ti.com>
---
 arch/arm/boot/dts/dra7.dtsi |    2 +-
 1 files changed, 1 insertions(+), 1 deletions(-)

diff --git a/arch/arm/boot/dts/dra7.dtsi b/arch/arm/boot/dts/dra7.dtsi
index 1e29ccf..9a20d46 100644
--- a/arch/arm/boot/dts/dra7.dtsi
+++ b/arch/arm/boot/dts/dra7.dtsi
@@ -1398,7 +1398,7 @@
 			ti,irqs-safe-map = <0>;
 		};
 
-		mac: ethernet at 4a100000 {
+		mac: ethernet at 48484000 {
 			compatible = "ti,cpsw";
 			ti,hwmods = "gmac";
 			clocks = <&dpll_gmac_ck>, <&gmac_gmii_ref_clk_div>;
-- 
1.7.4.1



From tglx at linutronix.de  Tue Aug 25 14:51:50 2015
From: tglx at linutronix.de (Thomas Gleixner)
Date: Tue, 25 Aug 2015 23:51:50 +0200 (CEST)
Subject: [PATCH] drivers: i2c: exynos5: irq spinlock rt-safe
In-Reply-To: <1440489125-20082-1-git-send-email-anders.roxell@linaro.org>
References: <1440489125-20082-1-git-send-email-anders.roxell@linaro.org>
Message-ID: <alpine.DEB.2.11.1508252349070.15006@nanos>

On Tue, 25 Aug 2015, Anders Roxell wrote:

> The exynos5_i2c_message_start enables interrupts while holding the i2c
> lock which is sought by the irq handler. If an IRQ is received before
> this lock is released then a deadlock occurs.

That's crap. The interrupt handler runs in an irq thread as RT forces
all normal interrupts to that.

Thanks,

	tglx

 


From dianders at chromium.org  Tue Aug 25 15:02:45 2015
From: dianders at chromium.org (Douglas Anderson)
Date: Tue, 25 Aug 2015 15:02:45 -0700
Subject: [PATCH] arm: kgdb: Don't try to stop the machine when setting
 breakpoints
Message-ID: <1440540165-28875-1-git-send-email-dianders@chromium.org>

In (23a4e40 arm: kgdb: Handle read-only text / modules) we moved to
using patch_text() to set breakpoints so that we could handle the case
when we had CONFIG_DEBUG_RODATA.  That patch used patch_text().
Unfortunately, patch_text() assumes that we're not in atomic context
when it runs since it needs to grab a mutex and also wait for other
CPUs to stop (which it does with a completion).

This would result in a stack crawl if you had
CONFIG_DEBUG_ATOMIC_SLEEP and tried to set a breakpoint in kgdb.  The
crawl looked something like:

 BUG: scheduling while atomic: swapper/0/0/0x00010007
 CPU: 0 PID: 0 Comm: swapper/0 Not tainted 4.2.0-rc7-00133-geb63b34 #1073
 Hardware name: Rockchip (Device Tree)
  (unwind_backtrace) from [<c00133d4>] (show_stack+0x20/0x24)
  (show_stack) from [<c05400e8>] (dump_stack+0x84/0xb8)
  (dump_stack) from [<c004913c>] (__schedule_bug+0x54/0x6c)
  (__schedule_bug) from [<c054065c>] (__schedule+0x80/0x668)
  (__schedule) from [<c0540cfc>] (schedule+0xb8/0xd4)
  (schedule) from [<c0543a3c>] (schedule_timeout+0x2c/0x234)
  (schedule_timeout) from [<c05417c0>] (wait_for_common+0xf4/0x188)
  (wait_for_common) from [<c0541874>] (wait_for_completion+0x20/0x24)
  (wait_for_completion) from [<c00a0104>] (__stop_cpus+0x58/0x70)
  (__stop_cpus) from [<c00a0580>] (stop_cpus+0x3c/0x54)
  (stop_cpus) from [<c00a06c4>] (__stop_machine+0xcc/0xe8)
  (__stop_machine) from [<c00a0714>] (stop_machine+0x34/0x44)
  (stop_machine) from [<c00173e8>] (patch_text+0x28/0x34)
  (patch_text) from [<c001733c>] (kgdb_arch_set_breakpoint+0x40/0x4c)
  (kgdb_arch_set_breakpoint) from [<c00a0d68>] (kgdb_validate_break_address+0x2c/0x60)
  (kgdb_validate_break_address) from [<c00a0e90>] (dbg_set_sw_break+0x1c/0xdc)
  (dbg_set_sw_break) from [<c00a2e88>] (gdb_serial_stub+0x9c4/0xba4)
  (gdb_serial_stub) from [<c00a11cc>] (kgdb_cpu_enter+0x1f8/0x60c)
  (kgdb_cpu_enter) from [<c00a18cc>] (kgdb_handle_exception+0x19c/0x1d0)
  (kgdb_handle_exception) from [<c0016f7c>] (kgdb_compiled_brk_fn+0x30/0x3c)
  (kgdb_compiled_brk_fn) from [<c00091a4>] (do_undefinstr+0x1a4/0x20c)
  (do_undefinstr) from [<c001400c>] (__und_svc_finish+0x0/0x34)

It turns out that when we're in kgdb all the CPUs are stopped anyway
so there's no reason we should be calling patch_text().  We can
instead directly call __patch_text() which assumes that CPUs have
already been stopped.

Fixes: 23a4e4050ba9 ("arm: kgdb: Handle read-only text / modules")
Reported-by: Aapo Vienamo <avienamo at nvidia.com>
Signed-off-by: Douglas Anderson <dianders at chromium.org>
---
 arch/arm/kernel/kgdb.c | 8 +++++---
 1 file changed, 5 insertions(+), 3 deletions(-)

diff --git a/arch/arm/kernel/kgdb.c b/arch/arm/kernel/kgdb.c
index a6ad93c..fd9eefc 100644
--- a/arch/arm/kernel/kgdb.c
+++ b/arch/arm/kernel/kgdb.c
@@ -259,15 +259,17 @@ int kgdb_arch_set_breakpoint(struct kgdb_bkpt *bpt)
 	if (err)
 		return err;
 
-	patch_text((void *)bpt->bpt_addr,
-		   *(unsigned int *)arch_kgdb_ops.gdb_bpt_instr);
+	/* Machine is already stopped, so we can use __patch_text() directly */
+	__patch_text((void *)bpt->bpt_addr,
+		     *(unsigned int *)arch_kgdb_ops.gdb_bpt_instr);
 
 	return err;
 }
 
 int kgdb_arch_remove_breakpoint(struct kgdb_bkpt *bpt)
 {
-	patch_text((void *)bpt->bpt_addr, *(unsigned int *)bpt->saved_instr);
+	/* Machine is already stopped, so we can use __patch_text() directly */
+	__patch_text((void *)bpt->bpt_addr, *(unsigned int *)bpt->saved_instr);
 
 	return 0;
 }
-- 
2.5.0.457.gab17608



From shenwei.wang at freescale.com  Tue Aug 25 15:03:07 2015
From: shenwei.wang at freescale.com (Shenwei Wang)
Date: Tue, 25 Aug 2015 17:03:07 -0500
Subject: [PATCH v3 1/1][Resend] misc: sram: add dev_pm_ops to support module
 power gate
Message-ID: <1440540187-6208-1-git-send-email-shenwei.wang@freescale.com>

When system goes into low power states like SUSPEND_MEM and
HIBERNATION, the hardware IP block may be powered off to reduce
the power consumption. This power down will lost all the
data inside the ram. This patch added the dev_pm_ops and
implemented two callbacks: suspend_noirq and resume_noirq, which
will save the data in the on-chip-ram right before power down
and restore it after system resumes.

A new property string named "can-power-gate" is added to
the devicetree bindings too.

Based-on-a-patch-by: Anson Huang <b20788 at freescale.com>
Signed-off-by: Shenwei Wang <shenwei.wang at freescale.com>

---
Change log:

PATCH v3
	Removed the unnecessary clk_enable/clk_disable.

PATCH v2
	Use vmalloc to allocate the SRAM backup memory.
	Code clean up.

 Documentation/devicetree/bindings/misc/sram.txt |  2 ++
 drivers/misc/sram.c                             | 42 +++++++++++++++++++++++++
 2 files changed, 44 insertions(+)

diff --git a/Documentation/devicetree/bindings/misc/sram.txt b/Documentation/devicetree/bindings/misc/sram.txt
index 36cbe5a..1170086 100644
--- a/Documentation/devicetree/bindings/misc/sram.txt
+++ b/Documentation/devicetree/bindings/misc/sram.txt
@@ -33,6 +33,8 @@ Optional properties in the area nodes:

 - compatible : standard definition, should contain a vendor specific string
                in the form <vendor>,[<device>-]<usage>
+- can-power-gate: a property to tell the driver that the sram can support
+		power gate

 Example:

diff --git a/drivers/misc/sram.c b/drivers/misc/sram.c
index 15c33cc..db9f1fa 100644
--- a/drivers/misc/sram.c
+++ b/drivers/misc/sram.c
@@ -30,7 +30,9 @@

 struct sram_dev {
 	struct device *dev;
+	void *power_off_save;
 	void __iomem *virt_base;
+	u32 size;

 	struct gen_pool *pool;
 	struct clk *clk;
@@ -156,6 +158,33 @@ static int sram_reserve_regions(struct sram_dev *sram, struct resource *res)
 	return ret;
 }

+static int sram_suspend_noirq(struct device *dev)
+{
+	struct platform_device *pdev = to_platform_device(dev);
+	struct sram_dev *sram = platform_get_drvdata(pdev);
+
+	if (!sram->power_off_save)
+		return 0;
+
+	/* Save necessary regs */
+	memcpy(sram->power_off_save, sram->virt_base, sram->size);
+
+	return 0;
+}
+
+static int sram_resume_noirq(struct device *dev)
+{
+	struct platform_device *pdev = to_platform_device(dev);
+	struct sram_dev *sram = platform_get_drvdata(pdev);
+
+	if (!sram->power_off_save)
+		return 0;
+
+	memcpy(sram->virt_base, sram->power_off_save, sram->size);
+
+	return 0;
+}
+
 static int sram_probe(struct platform_device *pdev)
 {
 	struct sram_dev *sram;
@@ -176,6 +205,7 @@ static int sram_probe(struct platform_device *pdev)
 	}

 	size = resource_size(res);
+	sram->size = size;

 	if (!devm_request_mem_region(sram->dev, res->start, size, pdev->name)) {
 		dev_err(sram->dev, "could not request region for resource\n");
@@ -203,6 +233,9 @@ static int sram_probe(struct platform_device *pdev)

 	platform_set_drvdata(pdev, sram);

+	if (of_property_read_bool(pdev->dev.of_node, "can-power-gate"))
+		sram->power_off_save = vmalloc(size);
+
 	dev_dbg(sram->dev, "SRAM pool: %zu KiB @ 0x%p\n",
 		gen_pool_size(sram->pool) / 1024, sram->virt_base);

@@ -219,6 +252,9 @@ static int sram_remove(struct platform_device *pdev)
 	if (sram->clk)
 		clk_disable_unprepare(sram->clk);

+	if (sram->power_off_save)
+		vfree(sram->power_off_save);
+
 	return 0;
 }

@@ -229,10 +265,16 @@ static const struct of_device_id sram_dt_ids[] = {
 };
 #endif

+static const struct dev_pm_ops sram_pm_ops = {
+	.suspend_noirq = sram_suspend_noirq,
+	.resume_noirq = sram_resume_noirq,
+};
+
 static struct platform_driver sram_driver = {
 	.driver = {
 		.name = "sram",
 		.of_match_table = of_match_ptr(sram_dt_ids),
+		.pm	= &sram_pm_ops,
 	},
 	.probe = sram_probe,
 	.remove = sram_remove,
--
2.5.0.rc2




From isubramanian at apm.com  Tue Aug 25 15:03:03 2015
From: isubramanian at apm.com (Iyappan Subramanian)
Date: Tue, 25 Aug 2015 15:03:03 -0700
Subject: [PATCH] drivers: net: xgene: fix: Oops in linkwatch_fire_event
Message-ID: <1440540183-11006-1-git-send-email-isubramanian@apm.com>

[ 1065.801569] Internal error: Oops: 96000006 [#1] SMP
...
[ 1065.866655] Hardware name: AppliedMicro Mustang/Mustang, BIOS 1.1.0 Apr 22 2015
[ 1065.873937] Workqueue: events_power_efficient phy_state_machine
[ 1065.879837] task: fffffe01de105e80 ti: fffffe00bcf18000 task.ti: fffffe00bcf18000
[ 1065.887288] PC is at linkwatch_fire_event+0xac/0xc0
[ 1065.892141] LR is at linkwatch_fire_event+0xa0/0xc0
[ 1065.896995] pc : [<fffffe000060284c>] lr : [<fffffe0000602840>] pstate: 200001c5
[ 1065.904356] sp : fffffe00bcf1bd00
...
[ 1066.196813] Call Trace:
[ 1066.199248] [<fffffe000060284c>] linkwatch_fire_event+0xac/0xc0
[ 1066.205140] [<fffffe000061167c>] netif_carrier_off+0x54/0x64
[ 1066.210773] [<fffffe00004f1654>] phy_state_machine+0x120/0x3bc
[ 1066.216578] [<fffffe00000d8d10>] process_one_work+0x15c/0x3a8
[ 1066.222296] [<fffffe00000d9090>] worker_thread+0x134/0x470
[ 1066.227757] [<fffffe00000df014>] kthread+0xe0/0xf8
[ 1066.232525] Code: 97f65ee9 f9420660 d538d082 8b000042 (885f7c40)

The fix is to call phy_disconnect() from xgene_enet_mdio_remove,
which in turn call cancel_delayed_work_sync().

Signed-off-by: Iyappan Subramanian <isubramanian at apm.com>
---
 drivers/net/ethernet/apm/xgene/xgene_enet_hw.c   | 3 +++
 drivers/net/ethernet/apm/xgene/xgene_enet_main.c | 5 +++--
 2 files changed, 6 insertions(+), 2 deletions(-)

diff --git a/drivers/net/ethernet/apm/xgene/xgene_enet_hw.c b/drivers/net/ethernet/apm/xgene/xgene_enet_hw.c
index a626c43..cfa3704 100644
--- a/drivers/net/ethernet/apm/xgene/xgene_enet_hw.c
+++ b/drivers/net/ethernet/apm/xgene/xgene_enet_hw.c
@@ -801,6 +801,9 @@ int xgene_enet_mdio_config(struct xgene_enet_pdata *pdata)
 
 void xgene_enet_mdio_remove(struct xgene_enet_pdata *pdata)
 {
+	if (pdata->phy_dev)
+		phy_disconnect(pdata->phy_dev);
+
 	mdiobus_unregister(pdata->mdio_bus);
 	mdiobus_free(pdata->mdio_bus);
 	pdata->mdio_bus = NULL;
diff --git a/drivers/net/ethernet/apm/xgene/xgene_enet_main.c b/drivers/net/ethernet/apm/xgene/xgene_enet_main.c
index 299eb43..a02ea7f8 100644
--- a/drivers/net/ethernet/apm/xgene/xgene_enet_main.c
+++ b/drivers/net/ethernet/apm/xgene/xgene_enet_main.c
@@ -1277,9 +1277,10 @@ static int xgene_enet_remove(struct platform_device *pdev)
 	mac_ops->tx_disable(pdata);
 
 	xgene_enet_napi_del(pdata);
-	xgene_enet_mdio_remove(pdata);
-	xgene_enet_delete_desc_rings(pdata);
+	if (pdata->phy_mode == PHY_INTERFACE_MODE_RGMII)
+		xgene_enet_mdio_remove(pdata);
 	unregister_netdev(ndev);
+	xgene_enet_delete_desc_rings(pdata);
 	pdata->port_ops->shutdown(pdata);
 	free_netdev(ndev);
 
-- 
1.9.1



From dianders at chromium.org  Tue Aug 25 15:06:02 2015
From: dianders at chromium.org (Doug Anderson)
Date: Tue, 25 Aug 2015 15:06:02 -0700
Subject: [BUG] arm: kgdb: patch_text() in kgdb_arch_set_breakpoint() may
 sleep
In-Reply-To: <CAD=FV=Xkye3_e-ZvpUfXyQJ7VFz2s6bTPSuty4-x7Fpa72UW2g@mail.gmail.com>
References: <55C230C7.2000909@nvidia.com>
 <CAD=FV=V_E+YMQuW5kvn+52Ugc_5hZsyXKKQ9Ywo_emoqK-N+Qw@mail.gmail.com>
 <CAGXu5j+P=LtTAVQbkn4w6Y9pTVouvRgAhwfS+rAmKfqTXC8pyg@mail.gmail.com>
 <CAD=FV=Xkye3_e-ZvpUfXyQJ7VFz2s6bTPSuty4-x7Fpa72UW2g@mail.gmail.com>
Message-ID: <CAD=FV=Wbqx+m9GopFztvT+RE0P_NKDVLogqn8=JbhtoEt3apEg@mail.gmail.com>

Hi,

On Mon, Aug 24, 2015 at 4:56 PM, Doug Anderson <dianders at chromium.org> wrote:
>> Perhaps we need to test if we're already atomic in patch_text, and
>> only call stop_machine if we need to?
>>
>> Untested (and likely mangled by gmail):
>>
>> diff --git a/arch/arm/kernel/patch.c b/arch/arm/kernel/patch.c
>> index 69bda1a5707e..855696bfe072 100644
>> --- a/arch/arm/kernel/patch.c
>> +++ b/arch/arm/kernel/patch.c
>> @@ -124,5 +124,8 @@ void __kprobes patch_text(void *addr, unsigned int insn)
>>                 .insn = insn,
>>         };
>>
>> -       stop_machine(patch_text_stop_machine, &patch, NULL);
>> +       if (unlikely(in_atomic_preempt_off()))
>> +               patch_text_stop_machine(&patch);
>> +       else
>> +               stop_machine(patch_text_stop_machine, &patch, NULL);
>
> Ah, right.  We're already stopped, so just not stopping again seems
> reasonable.  I think I'd rather just use in_dbg_master() as the test
> since that's a case where I _know_ all the CPUs are stopped.  Doesn't
> in_atomic_preempt_off() just check if preemption is off for this
> single CPU?
>
> Anyway, I'll throw a patch up now.  It fixes it for me.  :)

In case anyone happens upon this thread, the patch I originally put up
is at <https://patchwork.kernel.org/patch/7067211/>.  ...I've since
spun it to <https://patchwork.kernel.org/patch/7073441/>

-Doug


From dianders at chromium.org  Tue Aug 25 15:08:07 2015
From: dianders at chromium.org (Doug Anderson)
Date: Tue, 25 Aug 2015 15:08:07 -0700
Subject: [PATCH] ARM: probes: Don't stop the machine if we're in the
 debugger
In-Reply-To: <55DBB48E.7040508@codeaurora.org>
References: <1440460739-19522-1-git-send-email-dianders@chromium.org>
 <55DBB48E.7040508@codeaurora.org>
Message-ID: <CAD=FV=WDJ3-QimHA56nc3rg7T_aGqW2kw+BBW7zMye_6VfqeVg@mail.gmail.com>

Hi,

On Mon, Aug 24, 2015 at 5:19 PM, Stephen Boyd <sboyd at codeaurora.org> wrote:
> Can you add the backtrace?

Good point.  Done.

> Perhaps it would be better to add a different function for the kgdb call
> site? Then it's explicit what's going on without us having to figure out
> when in_dbg_master() is true.

Actually, there was already a function to patch the text directly
without stopping the machine.  :)

Adding a bit of extra noise here to point to my new patch since it has
a very different title than this one (so might be hard to find).  See
<https://patchwork.kernel.org/patch/7073441/>.

-Doug


From sboyd at codeaurora.org  Tue Aug 25 15:26:26 2015
From: sboyd at codeaurora.org (Stephen Boyd)
Date: Tue, 25 Aug 2015 15:26:26 -0700
Subject: [PATCH] arm: kgdb: Don't try to stop the machine when setting
 breakpoints
In-Reply-To: <1440540165-28875-1-git-send-email-dianders@chromium.org>
References: <1440540165-28875-1-git-send-email-dianders@chromium.org>
Message-ID: <20150825222626.GK19120@codeaurora.org>

On 08/25, Douglas Anderson wrote:
> In (23a4e40 arm: kgdb: Handle read-only text / modules) we moved to
> using patch_text() to set breakpoints so that we could handle the case
> when we had CONFIG_DEBUG_RODATA.  That patch used patch_text().
> Unfortunately, patch_text() assumes that we're not in atomic context
> when it runs since it needs to grab a mutex and also wait for other
> CPUs to stop (which it does with a completion).
> 
> This would result in a stack crawl if you had
> CONFIG_DEBUG_ATOMIC_SLEEP and tried to set a breakpoint in kgdb.  The
> crawl looked something like:
> 
>  BUG: scheduling while atomic: swapper/0/0/0x00010007
>  CPU: 0 PID: 0 Comm: swapper/0 Not tainted 4.2.0-rc7-00133-geb63b34 #1073
>  Hardware name: Rockchip (Device Tree)
>   (unwind_backtrace) from [<c00133d4>] (show_stack+0x20/0x24)
>   (show_stack) from [<c05400e8>] (dump_stack+0x84/0xb8)
>   (dump_stack) from [<c004913c>] (__schedule_bug+0x54/0x6c)
>   (__schedule_bug) from [<c054065c>] (__schedule+0x80/0x668)
>   (__schedule) from [<c0540cfc>] (schedule+0xb8/0xd4)
>   (schedule) from [<c0543a3c>] (schedule_timeout+0x2c/0x234)
>   (schedule_timeout) from [<c05417c0>] (wait_for_common+0xf4/0x188)
>   (wait_for_common) from [<c0541874>] (wait_for_completion+0x20/0x24)
>   (wait_for_completion) from [<c00a0104>] (__stop_cpus+0x58/0x70)
>   (__stop_cpus) from [<c00a0580>] (stop_cpus+0x3c/0x54)
>   (stop_cpus) from [<c00a06c4>] (__stop_machine+0xcc/0xe8)
>   (__stop_machine) from [<c00a0714>] (stop_machine+0x34/0x44)
>   (stop_machine) from [<c00173e8>] (patch_text+0x28/0x34)
>   (patch_text) from [<c001733c>] (kgdb_arch_set_breakpoint+0x40/0x4c)
>   (kgdb_arch_set_breakpoint) from [<c00a0d68>] (kgdb_validate_break_address+0x2c/0x60)
>   (kgdb_validate_break_address) from [<c00a0e90>] (dbg_set_sw_break+0x1c/0xdc)
>   (dbg_set_sw_break) from [<c00a2e88>] (gdb_serial_stub+0x9c4/0xba4)
>   (gdb_serial_stub) from [<c00a11cc>] (kgdb_cpu_enter+0x1f8/0x60c)
>   (kgdb_cpu_enter) from [<c00a18cc>] (kgdb_handle_exception+0x19c/0x1d0)
>   (kgdb_handle_exception) from [<c0016f7c>] (kgdb_compiled_brk_fn+0x30/0x3c)
>   (kgdb_compiled_brk_fn) from [<c00091a4>] (do_undefinstr+0x1a4/0x20c)
>   (do_undefinstr) from [<c001400c>] (__und_svc_finish+0x0/0x34)
> 
> It turns out that when we're in kgdb all the CPUs are stopped anyway
> so there's no reason we should be calling patch_text().  We can
> instead directly call __patch_text() which assumes that CPUs have
> already been stopped.
> 
> Fixes: 23a4e4050ba9 ("arm: kgdb: Handle read-only text / modules")
> Reported-by: Aapo Vienamo <avienamo at nvidia.com>
> Signed-off-by: Douglas Anderson <dianders at chromium.org>
> ---

Reviewed-by: Stephen Boyd <sboyd at codeaurora.org>

-- 
Qualcomm Innovation Center, Inc. is a member of Code Aurora Forum,
a Linux Foundation Collaborative Project


From rjw at rjwysocki.net  Tue Aug 25 16:01:37 2015
From: rjw at rjwysocki.net (Rafael J. Wysocki)
Date: Wed, 26 Aug 2015 01:01:37 +0200
Subject: [RESEND PATCH 0/3 v6] Add Mediatek MT8173 cpufreq driver
In-Reply-To: <CALx668VWg2xVxzy8P7f5QFWRzm+TDJXUghL-_rbvRLsLYjtnng@mail.gmail.com>
References: <1439803465-19683-1-git-send-email-pi-cheng.chen@linaro.org>
 <CALx668VWg2xVxzy8P7f5QFWRzm+TDJXUghL-_rbvRLsLYjtnng@mail.gmail.com>
Message-ID: <1617873.VRHfat3V76@vostro.rjw.lan>

On Tuesday, August 25, 2015 10:10:44 AM Pi-Cheng Chen wrote:
> On Mon, Aug 17, 2015 at 5:24 PM, Pi-Cheng Chen <pi-cheng.chen at linaro.org> wrote:
> > MT8173 is a ARMv8 based SoC with 2 clusters. All CPUs in a single cluster
> > share the same power and clock domain. This series tries to add cpufreq support
> > for MT8173 SoC. The v6 of this series is resent with Acks added.
> 
> Hi Rafael,
> 
> Not sure if I has missed the merge window.
> Do I have chance to have this series merged for 4.3?

Yes, it should make it.

> Would you please take [1,2] of this series?

I'm not sure what you mean.  Are you withdrawing the [3/3]?

Thanks,
Rafael



From khilman at kernel.org  Tue Aug 25 15:45:55 2015
From: khilman at kernel.org (Kevin Hilman)
Date: Tue, 25 Aug 2015 15:45:55 -0700
Subject: [RESEND PATCH v16 4/4] ARM: dts: add the support power-domain
 node on RK3288 SoCs
In-Reply-To: <CAD=FV=V6oG+9U=W_JZmqCuNo-9-5wW8ffZzG7ZE_3cnSTNAjFQ@mail.gmail.com>
 (Doug Anderson's message of "Tue, 25 Aug 2015 14:48:41 -0700")
References: <1440487486-6154-1-git-send-email-wxt@rock-chips.com>
 <1440487486-6154-5-git-send-email-wxt@rock-chips.com>
 <7hfv37axhj.fsf@deeprootsystems.com>
 <CAD=FV=V6oG+9U=W_JZmqCuNo-9-5wW8ffZzG7ZE_3cnSTNAjFQ@mail.gmail.com>
Message-ID: <7htwrn6l7g.fsf@deeprootsystems.com>

Doug Anderson <dianders at chromium.org> writes:

> Kevin,
>
> On Tue, Aug 25, 2015 at 2:07 PM, Kevin Hilman <khilman at kernel.org> wrote:
>> Caesar Wang <wxt at rock-chips.com> writes:
>>
>>> We can add more domains node in the future.
>>> This patch add the needed clocks into power-controller.
>>> As the discuess about all the device clocks being listed in
>>> the power-domains itself.
>>>
>>> There are several reasons as follows:
>>>
>>> Firstly, the clocks need be turned off to save power when
>>> the system enter the suspend state. So we need to enumerate
>>> the clocks in the dts. In order to power domain can turn on and off.
>>
>> Yes, but this is the job of device drivers which are runtime PM adapted
>> to gate their own clocks.  I agree these clocks need to be enumerated in
>> the DTS, but they should be in the device nodes.
>
> I _think_ what Caesar means is that the alternative to this patch is
> to leave the clocks on all the time as they were during the early days
> of Rockchip (AKA last year).  If the clocks are on all the time then
> the power domain patches can work fine.  However, once you start
> letting clocks turn off then you need to make sure that the power
> domain code turns the back on temporarily.

Yup, I understand that part, and many SoCs have this same "feature".

>>> Secondly, the reset-circuit should reset be synchronous on RK3288,
>>> then sync revoked. So we need to enable clocks of all devices.
>>> In other words, we have to enable the clocks before you operate them
>>> if all the device clocks are included in someone domians.
>>
>> Yes, this is pretty common for reset.
>>
>>> Someone wish was to get the clocks by reading the clocks from the
>>> device nodes, We can do that but we can solve the above issues.
>>
>> I don't follow this sentence.  Are you saying doing that will not solve
>> the above issues?  Why not?  Please explain.
>>
>> If there are non-device clocks that also need to be enabled before
>> asserting reset, then those are candidates for the power-domain node,
>> but not device clocks.
>
> It's been a long time and I don't know that I've reviewed every
> revision of this series, but I think there was a proposal that we
> shouldn't list clocks here.  Instead we should search through and find
> all devices that refer to this power domain, reach in and find their
> clocks, and turn them on.  Did I get that right?  

Yes...

> To put things in a
> concrete way, for pd_vio we'd go through the entire device tree
> ourselves and find all properties that look like "power-domains =
> <&power RK3288_PD_VIO>;".  We'd then find the parent of those
> properties and look for a property named "clocks".  We'd then iterate
> over all those clocks and turn those on.  Did I get that right?

... but you make it sound like more work than it is.  The genpd already
keeps a list of devices that refer to the power domain.  In fact, the
genpd 'attach' method can be platform-specific, so could be used to keep
track of a list (or a subset) of clocks which are needed for reset.

> The above doesn't seem like a terribly great idea to me for a number
> of reasons, including:
>
> 1. If I remember correctly, it's important to turn on clocks for
> devices even if they're not something you're using / have a driver
> for.  If you don't then the device won't get reset properly and this
> can affect things like suspend/resume because the hardware in the SoC
> will query all devices at suspend time to make sure they're ready.  

Correct.  This condition also exists in the clock framework when unused
clocks are disabled, or if you have drivers but PM_RUNTIME is disabled
(which can happen from userspace on a per-device basis) so it needs to
be understood and managed already.

> If
> a device is wedged because its clock wasn't on at the right them then
> it will cause problems.

Right.  I'm not arguing that the power domain doesn't have to deal with
device clocks. It has to for sync reset.  The objection I have have is
where these clocks are described.

> 2. If we absolutely need to turn all clocks and we get clocks from
> device tree nodes on then it means we need device tree nodes for every
> device in the domain.  

Isn't that the end goal?

> These would be needed even if there are no
> accepted bindings for this device yet.  So we'd need to do one of: A)
> Block power domain patches on feature complete bindings for all
> drivers; B) Make up non-approved compatible strings for all devices
> and throw them into the DTS; C) Add nodes in the DTS without a
> compatible string just to satisfy the power domain requirements.  None
> of these seem terribly appealing.

well, I think we can be slightly more accomodating than that and go for
somewhere in between:

D) In the power-domain DTS, clearly describe why each clock is needed by
the power-domain.  In particular list out clocks that are not device
clocks (and why they need to be asserted for reset) and separate those
from device clocks which are only listed in the power-domain because
there is not *yet* a driver/binding for that device node.

Doing it that way also makes it clear that when a new driver/binding is
added, the clocks should be removed from the power-domain node and put
into the device node.

Also, this addresses my primary concern that the DTS acurately describes
the hardware.  IOW, in hardware, most of these clocks are are properties
of devices, not power-domains, and the DT should reflect that.

IMO, if it's not describing the hardware, and is a placeholder until a
driver/binding is in place, it should be properly documented.

> 3. It is entirely possible that there are clocks that will be listed
> in the individual devices that aren't needed for powering on the power
> domain.  I'd tend to believe that PCLK_EDP_CTRL (the pixel clock)
> doesn't really need to be turned on when adjusting the "VIO" power
> domain.  Right now Caesar has it listed, but it probably isn't needed
> (Caesar: can you confirm?).

Yes, I suspect there are several of those, which is also why I'd like to
see the clocks in the power-domain node described in detail, and exacly 
why they're needed to be enabled.

Also, in the current proposed DTS, clocks that are listed in both device
nodes and the power domain are also suspicous, especially when the
device node doesn't have a power-domain property.  (c.f. vop[bl] nodes
and ACLK_VOP[01] clocks.)  For that matter, this series doesn't add any
devices to the power domains, which makes it even more confusing about
how this is meant to work.  IOW, with no devices belonging to
power-domains, how are the power-domain power_on/power_off callbacks
being called?

> 4. It seems just slightly brittle to be reaching into other device
> nodes and making assumptions about their properties.  Yeah, it's
> probably safe to assume that "clocks" has a list of clocks and
> "power-domains" will point to something whose first entry is a
> phandle, but it still seems just a tad bit like violating an
> abstraction barrier.

shmobile is already doing this with platform-specific genpd attach
callbacks, and using the pm_clk API.  I don't see any issues with that.

> Anyway, perhaps I'm misunderstanding, or perhaps my concerns are
> simply not for important things.  If so feel free to yell at me.  ;)

No need for me to yell. Your concerns are perfectly valid, and it's not
my style anyways. ;)

Thanks for the feedback,

Kevin





From rjw at rjwysocki.net  Tue Aug 25 16:48:10 2015
From: rjw at rjwysocki.net (Rafael J. Wysocki)
Date: Wed, 26 Aug 2015 01:48:10 +0200
Subject: [PATCH V2 2/4] ACPI/scan: Clean up acpi_check_dma
In-Reply-To: <1440524009-5359-3-git-send-email-Suravee.Suthikulpanit@amd.com>
References: <1440524009-5359-1-git-send-email-Suravee.Suthikulpanit@amd.com>
 <1440524009-5359-3-git-send-email-Suravee.Suthikulpanit@amd.com>
Message-ID: <1659571.paO1iYcMuM@vostro.rjw.lan>

On Wednesday, August 26, 2015 12:33:27 AM Suravee Suthikulpanit wrote:
> The original name of acpi_check_dma() function does not clearly tell what
> exactly it is checking. Also, returning two boolean values (one to indicate
> device is DMA capability, and the other to inidicate device coherency
> attribute) can be confusing.
> 
> So, in order to simplify the function, this patch renames acpi_check_dma()
> to acpi_check_dma_coherency() to clearly indicate the purpose of this
> function, and only returns an integer where -1 means DMA not supported,
> 1 means coherent DMA, and 0 means non-coherent DMA.
> 
> Also, this patch moves the function into drivers/acpi/scan.c since
> it is easier to follow the logic in the acpi_init_coherency() in the
> same file here.
> 
> Signed-off-by: Suravee Suthikulpanit <Suravee.Suthikulpanit at amd.com>
> CC: Bjorn Helgaas <bhelgaas at google.com>
> CC: Catalin Marinas <catalin.marinas at arm.com>
> CC: Rob Herring <robh+dt at kernel.org>
> CC: Will Deacon <will.deacon at arm.com>
> CC: Rafael J. Wysocki <rjw at rjwysocki.net>
> ---
>  drivers/acpi/acpi_platform.c |  7 ++++++-
>  drivers/acpi/glue.c          |  5 +++--
>  drivers/acpi/scan.c          | 39 +++++++++++++++++++++++++++++++++++++++
>  drivers/base/property.c      |  8 ++++++--
>  include/acpi/acpi_bus.h      | 36 ++----------------------------------
>  include/linux/acpi.h         |  4 ++--
>  6 files changed, 58 insertions(+), 41 deletions(-)
> 
> diff --git a/drivers/acpi/acpi_platform.c b/drivers/acpi/acpi_platform.c
> index 06a67d5..2261e85 100644
> --- a/drivers/acpi/acpi_platform.c
> +++ b/drivers/acpi/acpi_platform.c
> @@ -103,7 +103,12 @@ struct platform_device *acpi_create_platform_device(struct acpi_device *adev)
>  	pdevinfo.res = resources;
>  	pdevinfo.num_res = count;
>  	pdevinfo.fwnode = acpi_fwnode_handle(adev);
> -	pdevinfo.dma_mask = acpi_check_dma(adev, NULL) ? DMA_BIT_MASK(32) : 0;
> +
> +	if (-1 != acpi_check_dma_coherency(adev))
> +		pdevinfo.dma_mask = DMA_BIT_MASK(32);
> +	else
> +		pdevinfo.dma_mask = 0;
> +
>  	pdev = platform_device_register_full(&pdevinfo);
>  	if (IS_ERR(pdev))
>  		dev_err(&adev->dev, "platform device creation failed: %ld\n",
> diff --git a/drivers/acpi/glue.c b/drivers/acpi/glue.c
> index b9657af..55cf916 100644
> --- a/drivers/acpi/glue.c
> +++ b/drivers/acpi/glue.c
> @@ -168,7 +168,7 @@ int acpi_bind_one(struct device *dev, struct acpi_device *acpi_dev)
>  	struct list_head *physnode_list;
>  	unsigned int node_id;
>  	int retval = -EINVAL;
> -	bool coherent;
> +	int coherent;

enum, anyone?  With clearly defined values?


>  
>  	if (has_acpi_companion(dev)) {
>  		if (acpi_dev) {
> @@ -225,7 +225,8 @@ int acpi_bind_one(struct device *dev, struct acpi_device *acpi_dev)
>  	if (!has_acpi_companion(dev))
>  		ACPI_COMPANION_SET(dev, acpi_dev);
>  
> -	if (acpi_check_dma(acpi_dev, &coherent))
> +	coherent = acpi_check_dma_coherency(acpi_dev);
> +	if (coherent != -1)

Like here I'm not sure why -1 is special?


>  		arch_setup_dma_ops(dev, 0, 0, NULL, coherent);
>  
>  	acpi_physnode_link_name(physical_node_name, node_id);

Thanks,
Rafael



From rjw at rjwysocki.net  Tue Aug 25 16:48:55 2015
From: rjw at rjwysocki.net (Rafael J. Wysocki)
Date: Wed, 26 Aug 2015 01:48:55 +0200
Subject: [PATCH V2 4/4] PCI: ACPI: Add support for PCI device DMA coherency
In-Reply-To: <1440524009-5359-5-git-send-email-Suravee.Suthikulpanit@amd.com>
References: <1440524009-5359-1-git-send-email-Suravee.Suthikulpanit@amd.com>
 <1440524009-5359-5-git-send-email-Suravee.Suthikulpanit@amd.com>
Message-ID: <5541922.5doADRYBJG@vostro.rjw.lan>

On Wednesday, August 26, 2015 12:33:29 AM Suravee Suthikulpanit wrote:
> This patch adds support for setting up PCI device DMA coherency from
> ACPI _CCA object that should normally be specified in the DSDT node
> of its PCI host bridge.
> 
> Signed-off-by: Suravee Suthikulpanit <Suravee.Suthikulpanit at amd.com>
> CC: Bjorn Helgaas <bhelgaas at google.com>
> CC: Catalin Marinas <catalin.marinas at arm.com>
> CC: Rob Herring <robh+dt at kernel.org>
> CC: Will Deacon <will.deacon at arm.com>
> CC: Rafael J. Wysocki <rjw at rjwysocki.net>
> CC: Murali Karicheri <m-karicheri2 at ti.com>
> ---
>  drivers/pci/probe.c | 15 ++++++++++-----
>  1 file changed, 10 insertions(+), 5 deletions(-)
> 
> diff --git a/drivers/pci/probe.c b/drivers/pci/probe.c
> index 4de6594..2fd2a60 100644
> --- a/drivers/pci/probe.c
> +++ b/drivers/pci/probe.c
> @@ -1551,17 +1551,22 @@ static void pci_init_capabilities(struct pci_dev *dev)
>   * @dev: ptr to pci_dev struct of the PCI device
>   *
>   * Function to update PCI devices's DMA configuration using the same
> - * info from the OF node of host bridge's parent (if any).
> + * info from the OF node or ACPI node of host bridge's parent (if any).
>   */
>  static void pci_dma_configure(struct pci_dev *dev)
>  {
>  	struct device *bridge = pci_get_host_bridge_device(dev);
>  
>  	if (IS_ENABLED(CONFIG_OF) && dev->dev.of_node) {
> -		if (!bridge->parent)
> -			return;
> -
> -		of_dma_configure(&dev->dev, bridge->parent->of_node);
> +		if (bridge->parent)
> +			of_dma_configure(&dev->dev,
> +					 bridge->parent->of_node);
> +	} else if (has_acpi_companion(bridge)) {
> +		struct acpi_device *adev = to_acpi_node(bridge->fwnode);
> +		int coherent = acpi_check_dma_coherency(adev);
> +
> +		if (-1 != coherent)

The ordering of this check is somewhat unusual.


> +			arch_setup_dma_ops(&dev->dev, 0, 0, NULL, coherent);
>  	}
>  
>  	pci_put_host_bridge_device(bridge);
> 

Thanks,
Rafael



From robherring2 at gmail.com  Tue Aug 25 16:22:29 2015
From: robherring2 at gmail.com (Rob Herring)
Date: Tue, 25 Aug 2015 18:22:29 -0500
Subject: [PATCH 1/7] drm/vc4: Add devicetree bindings for VC4.
In-Reply-To: <CAF6AEGu2fi0M7DsicHz+5SDHi1DyDRmvWjkmYPPgY6pZ423WcA@mail.gmail.com>
References: <1439427380-2436-1-git-send-email-eric@anholt.net>
 <1439427380-2436-2-git-send-email-eric@anholt.net>
 <55CEC25E.7070303@wwwdotorg.org>
 <874mjxwyx5.fsf@eliezer.anholt.net>
 <CAL_JsqJxiGUR5BxBPyR3-0NxqWsOxMGrWQA6cMXe2pjTom__nw@mail.gmail.com>
 <CAF6AEGu2fi0M7DsicHz+5SDHi1DyDRmvWjkmYPPgY6pZ423WcA@mail.gmail.com>
Message-ID: <CAL_JsqJpWmEpOZK5-HG5Xz8J-h7SX8ViytagjxGLdeMwXeONow@mail.gmail.com>

On Tue, Aug 25, 2015 at 3:42 PM, Rob Clark <robdclark at gmail.com> wrote:
> On Mon, Aug 24, 2015 at 9:47 AM, Rob Herring <robherring2 at gmail.com> wrote:
>> On Mon, Aug 17, 2015 at 1:30 PM, Eric Anholt <eric at anholt.net> wrote:
>>> Stephen Warren <swarren at wwwdotorg.org> writes:
>>>
>>>> On 08/12/2015 06:56 PM, Eric Anholt wrote:
>>>>> Signed-off-by: Eric Anholt <eric at anholt.net>
>>>>
>>>> This one definitely needs a patch description, since someone might not
>>>> know what a VC4 is, and "git log" won't show the text from the binding
>>>> doc itself. I'd suggest adding the initial paragraph of the binding doc
>>>> as the patch description, or more.
>>>>
>>>>> diff --git a/Documentation/devicetree/bindings/gpu/brcm,bcm-vc4.txt b/Documentation/devicetree/bindings/gpu/brcm,bcm-vc4.txt
>>>
>>>>> +- hvss:             List of references to HVS video scalers
>>>>> +- encoders: List of references to output encoders (HDMI, SDTV)
>>>>
>>>> Would it make sense to make all those nodes child node of the vc4
>>>> object. That way, there's no need to have these lists of objects; they
>>>> can be automatically built up as the DT is enumerated. I know that e.g.
>>>> the NVIDIA Tegra host1x binding works this way, and I think it may have
>>>> been inspired by other similar cases.
>>>
>>> I've looked at tegra, and the component system used by msm appears to be
>>> nicer than it.  To follow tegra's model, it looks like I need to build
>>> this extra bus thing corresponding to host1x that is effectively the
>>> drivers/base/component.c code, so that I can get at vc4's structure from
>>> the component drivers.
>>>
>>>> Of course, this is only appropriate if the HW modules really are
>>>> logically children of the VC4 HW module. Perhaps they aren't. If they
>>>> aren't though, I wonder what this "vc4" module actually represents in HW?
>>>
>>> It's the subsystem, same as we use a subsystem node for msm, sti,
>>> rockchip, imx, and exynos.  This appears to be the common model of how
>>> the collection of graphics-related components is represented in the DT.
>>
>> I think most of these bindings are wrong. They are grouped together
>> because that is what DRM wants not because that reflects the h/w. So
>> convince me this is one block, not that it is what other people do.
>
> I think, when it comes to more complex driver subsystems (like drm in
> particular) we have a bit of mismatch between how things look from the
> "pure hw ignoring sw" perspective, and the "how sw and in particular
> userspace expects things" perspective.  Maybe it is less a problem in
> other subsystems, where bindings map to things that are only visible
> in the kernel, or well defined devices like uart or sata controller.
> But when given the choice, I'm going to err on the side of not
> confusing userspace and the large software stack that sits above
> drm/kms, over dt purity.

I wasn't implying that this should get exposed to userspace as
components. V4L2 has gone that route with media controller and
sub-devs. Perhaps that is needed for DRM, perhaps not. For the moment,
I definitely agree the kernel should hide most/all of those details,
but I don't think that means DT has to hide the details or know what
components are handled by a single driver. My point was that on the DT
side we have a mixture of OF graph usage, parent-child nodes or custom
phandles (this case) to describe the relationships between h/w
components. That's not necessarily wrong, but we should have some
rules around how certain relationships are described. Then in the
drivers we have a mixture of deferred probe, component API, and custom
inter-module APIs to control init order. We then have a mixture of all
those which leads to very few if any drivers having the same overall
structure that could be shared. Should we mandate using the component
API for h/w that is discrete blocks? Should we throw out the component
API for something else? Can we tie the graph parsing and component API
together with common code?


> Maybe it would be nice to have a sort of dt overlay that adds the bits
> needed to tie together hw blocks that should be assembled into a
> single logical device for linux and userspace (but maybe not some
> other hypothetical operating system).  But so far that doesn't exist.

OF graph is supposed to do this. OF graph is a double edged sword. It
is very flexible, but then each platform can do something different.
We need to have some level of requirements around how the OF graph is
used. As an example, any system with an HDMI connector should have an
"hdmi-connector" compatible node or encoder/bridge chips/blocks must
have certain ports defined.


> All we have is a hammer (devicetree), everything looks like a nail.
> End result is we end up adding some things in the bindings which
> aren't purely about the hw.  Until someone invents a screwdriver, I'm
> not sure what else to do.  In the end, other hypothetical OS is free
> to ignore those extra fields in the bindings if it doesn't need them.
> So meh?

We really want to err on the side of fewer bindings, not more as once
used they are an ABI.

Rob


From olof at lixom.net  Tue Aug 25 16:36:45 2015
From: olof at lixom.net (Olof Johansson)
Date: Tue, 25 Aug 2015 16:36:45 -0700
Subject: [PATCH 2/5] ARM: NSP: add minimal Northstar Plus device tree
In-Reply-To: <1440092804-25726-1-git-send-email-jonmason@broadcom.com>
References: <1440092804-25726-1-git-send-email-jonmason@broadcom.com>
Message-ID: <CAOesGMhE40_mfZCD2PqcTObE_Gz_6rKFwhf3-6kZY4n9Yxn2rQ@mail.gmail.com>

Hi,

I'm not sure what the strategy behind your cc:ing on this patch set
is. I only got a couple of them in my inbox, and this one wasn't one
of them. :)

On Thu, Aug 20, 2015 at 10:46 AM, Jon Mason <jonmason at broadcom.com> wrote:
> Add a very minimalistic set of Northstar Plus Device Tree files which
> describes the SoC and the BCM958625 implementation.  The perpherials
> described are:
>
> ARM Cortex A9 CPU
> 2 8250 UARTs
> ARM GIC
> PL310 L2 Cache
> ARM A9 Global timer
>
> Signed-off-by: Jon Mason <jonmason at broadcom.com>
> Signed-off-by: Kapil Hali <kapilh at broadcom.com>
> Reviewed-by: Ray Jui <rjui at broadcom.com>
> Reviewed-by: Scott Branden <sbranden at broadcom.com>

Seeing reviewed-by already attached to a v1 of a patchset has limited
value for someone on the outside.

Reviewed-by is one of those tags that has a value that's mostly
dependent on who it comes from. By not actually seeing the review and
the feedback provided (and revisions made), less data is provided to
tell if it's a valuable review or not.

Also, if you're posting the code you should probably have your name
below Kapil's, since you're the one signing off the origin of the
code. See Documentation/SubmittingPatches.txt for details on what
S-o-b actually means.


> --- /dev/null
> +++ b/arch/arm/boot/dts/bcm-nsp.dtsi
> @@ -0,0 +1,105 @@
> +/*
> + *  BSD LICENSE
> + *
> + *  Copyright(c) 2015 Broadcom Corporation.  All rights reserved.
> + *
> + *  Redistribution and use in source and binary forms, with or without
> + *  modification, are permitted provided that the following conditions
> + *  are met:
> + *
> + *    * Redistributions of source code must retain the above copyright
> + *      notice, this list of conditions and the following disclaimer.
> + *    * Redistributions in binary form must reproduce the above copyright
> + *      notice, this list of conditions and the following disclaimer in
> + *      the documentation and/or other materials provided with the
> + *      distribution.
> + *    * Neither the name of Broadcom Corporation nor the names of its
> + *      contributors may be used to endorse or promote products derived
> + *      from this software without specific prior written permission.
> + *
> + *  THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
> + *  "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
> + *  LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
> + *  A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
> + *  OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
> + *  SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
> + *  LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
> + *  DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
> + *  THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
> + *  (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
> + *  OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
> + */

I'm not sure we've seen BSD-only submissions before. I'll let DT
maintainers (or Ian) speak up in case this would cause problems.


> +
> +#include <dt-bindings/interrupt-controller/arm-gic.h>
> +#include <dt-bindings/interrupt-controller/irq.h>
> +
> +#include "skeleton.dtsi"
> +
> +/ {
> +       compatible = "brcm,nsp";
> +       model = "Broadcom Northstar Plus SoC";
> +       interrupt-parent = <&gic>;
> +
> +       cpus {
> +               #address-cells = <1>;
> +               #size-cells = <0>;
> +
> +               cpu at 0 {
> +                       device_type = "cpu";
> +                       compatible = "arm,cortex-a9";
> +                       next-level-cache = <&L2>;
> +                       reg = <0x0>;
> +               };
> +       };
> +
> +       clocks {
> +               #address-cells = <1>;
> +               #size-cells = <1>;
> +               ranges;
> +
> +               periph_clk: periph_clk {
> +                       compatible = "fixed-clock";
> +                       #clock-cells = <0>;
> +                       clock-frequency = <500000000>;
> +               };
> +       };
> +
> +       uart0: serial at 18000300 {
> +               compatible = "ns16550a";
> +               reg = <0x18000300 0x100>;
> +               interrupts = <GIC_SPI 85 IRQ_TYPE_LEVEL_HIGH>;
> +               clock-frequency = <62499840>;
> +               status = "disabled";
> +       };
> +
> +       uart1: serial at 18000400 {
> +               compatible = "ns16550a";
> +               reg = <0x18000400 0x100>;
> +               interrupts = <GIC_SPI 85 IRQ_TYPE_LEVEL_HIGH>;
> +               clock-frequency = <62499840>;
> +               status = "disabled";
> +       };
> +
> +       gic: interrupt-controller at 19021000 {
> +               compatible = "arm,cortex-a9-gic";
> +               #interrupt-cells = <3>;
> +               #address-cells = <0>;
> +               interrupt-controller;
> +               reg = <0x19021000 0x1000>,
> +                     <0x19020100 0x100>;
> +       };
> +
> +       L2: l2-cache {
> +               compatible = "arm,pl310-cache";
> +               reg = <0x19022000 0x1000>;
> +               cache-unified;
> +               cache-level = <2>;
> +       };
> +
> +       timer at 19020200 {
> +               compatible = "arm,cortex-a9-global-timer";
> +               reg = <0x19020200 0x100>;
> +               interrupts = <GIC_PPI 11 IRQ_TYPE_LEVEL_HIGH>;
> +               clocks = <&periph_clk>;
> +       };
> +};
> diff --git a/arch/arm/boot/dts/bcm958625k.dts b/arch/arm/boot/dts/bcm958625k.dts
> new file mode 100644
> index 0000000..a1bc151
> --- /dev/null
> +++ b/arch/arm/boot/dts/bcm958625k.dts
> @@ -0,0 +1,57 @@
> +/*
> + *  BSD LICENSE
> + *
> + *  Copyright(c) 2015 Broadcom Corporation.  All rights reserved.
> + *
> + *  Redistribution and use in source and binary forms, with or without
> + *  modification, are permitted provided that the following conditions
> + *  are met:
> + *
> + *    * Redistributions of source code must retain the above copyright
> + *      notice, this list of conditions and the following disclaimer.
> + *    * Redistributions in binary form must reproduce the above copyright
> + *      notice, this list of conditions and the following disclaimer in
> + *      the documentation and/or other materials provided with the
> + *      distribution.
> + *    * Neither the name of Broadcom Corporation nor the names of its
> + *      contributors may be used to endorse or promote products derived
> + *      from this software without specific prior written permission.
> + *
> + *  THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
> + *  "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
> + *  LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
> + *  A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
> + *  OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
> + *  SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
> + *  LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
> + *  DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
> + *  THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
> + *  (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
> + *  OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
> + */
> +
> +/dts-v1/;
> +
> +#include "bcm-nsp.dtsi"
> +
> +/ {
> +       model = "NorthStar Plus SVK (BCM958625K)";
> +       compatible = "brcm,bcm58625", "brcm,nsp";
> +
> +       aliases {
> +               serial0 = &uart0;
> +               serial1 = &uart1;
> +       };
> +
> +       chosen {
> +               stdout-path = "serial0:115200n8";
> +       };

No way to mount a root filesystem yet? How much work remains for that
to be possible, and what's the plan for that?

> +
> +       uart0: serial at 18000300 {
> +               status = "okay";
> +       };
> +
> +       uart1: serial at 18000400 {
> +               status = "okay";
> +       };

I recommend using labels here instead so you don't have to mirror the
DT layout to get the updated property right.

I.e.

&uart1 {
        status = "okay";
};



-Olof


From olof at lixom.net  Tue Aug 25 16:42:42 2015
From: olof at lixom.net (Olof Johansson)
Date: Tue, 25 Aug 2015 16:42:42 -0700
Subject: [PATCH 5/5] MAINTAINERS: add entry for the Broadcom Northstar
 Plus SoCs
In-Reply-To: <1440092861-25825-1-git-send-email-jonmason@broadcom.com>
References: <1440092861-25825-1-git-send-email-jonmason@broadcom.com>
Message-ID: <CAOesGMioBQY9qy-S8kMJmo_=B6-KZiUkd=Ns1Uo2dGu0BiqppQ@mail.gmail.com>

On Thu, Aug 20, 2015 at 10:47 AM, Jon Mason <jonmason at broadcom.com> wrote:
> Modify the iProc MAINTAINER to cover the Nortstar Plus SoCs, and add me
> to the list of people responsible for it.

That's not what this patch does. It removes CYGNUS from the
description as well. Hmm?

I'm also not a fan of the complex patterns, but that's more of a
bikeshedding comment. Does Broadcom really not have a bit more
systematic naming than this? :)

> Signed-off-by: Jon Mason <jonmason at broadcom.com>
> Reviewed-by: Scott Branden <sbranden at broadcom.com>

For maintainer updates, we usuallu like to see a public ack of this
and not just a pre-acked patch. You _could_ have added it yourself
without Scott's actual approval, after all.


-Olof


From sboyd at codeaurora.org  Tue Aug 25 16:43:40 2015
From: sboyd at codeaurora.org (Stephen Boyd)
Date: Tue, 25 Aug 2015 16:43:40 -0700
Subject: [GIT PULL 1/9] clk: tegra: Changes for v4.3-rc1
In-Reply-To: <1439563720-13189-2-git-send-email-thierry.reding@gmail.com>
References: <1439563720-13189-1-git-send-email-thierry.reding@gmail.com>
 <1439563720-13189-2-git-send-email-thierry.reding@gmail.com>
Message-ID: <20150825234340.GN19120@codeaurora.org>

On 08/14, Thierry Reding wrote:
> Hi Mike, Stephen,
> 
> The following changes since commit d770e558e21961ad6cfdf0ff7df0eb5d7d4f0754:
> 
>   Linux 4.2-rc1 (2015-07-05 11:01:52 -0700)
> 
> are available in the git repository at:
> 
>   git://git.kernel.org/pub/scm/linux/kernel/git/tegra/linux.git tags/tegra-for-4.3-clk
> 
> for you to fetch changes up to 79cf95c763a11d4b365cd5a627fd1ab4dca67890:
> 
>   clk: tegra: Add the DFLL as a possible parent of the cclk_g clock (2015-07-16 10:40:20 +0200)
> 

Pulled into clk-next. I had to apply this patch on top though.
Please check and be more careful next time.

Also, I don't understand why __raw_{readl,writel} is used. You
probably wanted the relaxed versions of the accessors, and not
the ones that don't do any byte swapping.

Finally, please Cc linux-clk at vger.kernel.org next time.

Thanks!

----8<----
From: Stephen Boyd <sboyd at codeaurora.org>
Subject: [PATCH] clk: tegra: Fix some static checker problems

The latest Tegra clk pull had some problems. Fix them.

drivers/clk/tegra/clk-tegra124.c:1450:6: warning: symbol 'tegra124_clock_assert_dfll_dvco_reset' was not declared. Should it be static?
drivers/clk/tegra/clk-tegra124.c:1466:6: warning: symbol 'tegra124_clock_deassert_dfll_dvco_reset' was not declared. Should it be static?
drivers/clk/tegra/clk-tegra124.c:1476:5: warning: symbol 'tegra124_reset_assert' was not declared. Should it be static?
drivers/clk/tegra/clk-tegra124.c:1486:5: warning: symbol 'tegra124_reset_deassert' was not declared. Should it be static?
drivers/clk/tegra/clk-dfll.c:590 dfll_load_i2c_lut() warn: inconsistent indenting
drivers/clk/tegra/clk-dfll.c:1448 dfll_build_i2c_lut() warn: unsigned 'td->i2c_lut[0]' is never less than zero.

Signed-off-by: Stephen Boyd <sboyd at codeaurora.org>
---
 drivers/clk/tegra/clk-dfll.c     | 8 +++++---
 drivers/clk/tegra/clk-tegra124.c | 8 ++++----
 2 files changed, 9 insertions(+), 7 deletions(-)

diff --git a/drivers/clk/tegra/clk-dfll.c b/drivers/clk/tegra/clk-dfll.c
index 109a79b95238..c2ff859ee0e8 100644
--- a/drivers/clk/tegra/clk-dfll.c
+++ b/drivers/clk/tegra/clk-dfll.c
@@ -587,7 +587,7 @@ static void dfll_load_i2c_lut(struct tegra_dfll *td)
 		else
 			lut_index = i;
 
-		  val = regulator_list_hardware_vsel(td->vdd_reg,
+		val = regulator_list_hardware_vsel(td->vdd_reg,
 						     td->i2c_lut[lut_index]);
 		__raw_writel(val, td->lut_base + i * 4);
 	}
@@ -1432,6 +1432,7 @@ static int dfll_build_i2c_lut(struct tegra_dfll *td)
 	int selector;
 	unsigned long rate;
 	struct dev_pm_opp *opp;
+	int lut;
 
 	rcu_read_lock();
 
@@ -1444,9 +1445,10 @@ static int dfll_build_i2c_lut(struct tegra_dfll *td)
 	v_max = dev_pm_opp_get_voltage(opp);
 
 	v = td->soc->min_millivolts * 1000;
-	td->i2c_lut[0] = find_vdd_map_entry_exact(td, v);
-	if (td->i2c_lut[0] < 0)
+	lut = find_vdd_map_entry_exact(td, v);
+	if (lut < 0)
 		goto out;
+	td->i2c_lut[0] = lut;
 
 	for (j = 1, rate = 0; ; rate++) {
 		opp = dev_pm_opp_find_freq_ceil(td->soc->dev, &rate);
diff --git a/drivers/clk/tegra/clk-tegra124.c b/drivers/clk/tegra/clk-tegra124.c
index a9e2b30737ec..824d75883d2b 100644
--- a/drivers/clk/tegra/clk-tegra124.c
+++ b/drivers/clk/tegra/clk-tegra124.c
@@ -1447,7 +1447,7 @@ static void tegra124_car_barrier(void)
  *
  * Assert the reset line of the DFLL's DVCO.  No return value.
  */
-void tegra124_clock_assert_dfll_dvco_reset(void)
+static void tegra124_clock_assert_dfll_dvco_reset(void)
 {
 	u32 v;
 
@@ -1463,7 +1463,7 @@ void tegra124_clock_assert_dfll_dvco_reset(void)
  * Deassert the reset line of the DFLL's DVCO, allowing the DVCO to
  * operate.  No return value.
  */
-void tegra124_clock_deassert_dfll_dvco_reset(void)
+static void tegra124_clock_deassert_dfll_dvco_reset(void)
 {
 	u32 v;
 
@@ -1473,7 +1473,7 @@ void tegra124_clock_deassert_dfll_dvco_reset(void)
 	tegra124_car_barrier();
 }
 
-int tegra124_reset_assert(unsigned long id)
+static int tegra124_reset_assert(unsigned long id)
 {
 	if (id == TEGRA124_RST_DFLL_DVCO)
 		tegra124_clock_assert_dfll_dvco_reset();
@@ -1483,7 +1483,7 @@ int tegra124_reset_assert(unsigned long id)
 	return 0;
 }
 
-int tegra124_reset_deassert(unsigned long id)
+static int tegra124_reset_deassert(unsigned long id)
 {
 	if (id == TEGRA124_RST_DFLL_DVCO)
 		tegra124_clock_deassert_dfll_dvco_reset();
-- 
Qualcomm Innovation Center, Inc. is a member of Code Aurora Forum,
a Linux Foundation Collaborative Project


From dmitry.torokhov at gmail.com  Tue Aug 25 16:47:58 2015
From: dmitry.torokhov at gmail.com (Dmitry Torokhov)
Date: Tue, 25 Aug 2015 16:47:58 -0700
Subject: [RESEND PATCH v16 4/4] ARM: dts: add the support power-domain
 node on RK3288 SoCs
In-Reply-To: <7htwrn6l7g.fsf@deeprootsystems.com>
References: <1440487486-6154-1-git-send-email-wxt@rock-chips.com>
 <1440487486-6154-5-git-send-email-wxt@rock-chips.com>
 <7hfv37axhj.fsf@deeprootsystems.com>
 <CAD=FV=V6oG+9U=W_JZmqCuNo-9-5wW8ffZzG7ZE_3cnSTNAjFQ@mail.gmail.com>
 <7htwrn6l7g.fsf@deeprootsystems.com>
Message-ID: <CAKdAkRS=9Dq+YpMNSjpij0Am4ZD6uUURv74OLLYf+akD=W885A@mail.gmail.com>

On Tue, Aug 25, 2015 at 3:45 PM, Kevin Hilman <khilman at kernel.org> wrote:
> Doug Anderson <dianders at chromium.org> writes:
>
>> To put things in a
>> concrete way, for pd_vio we'd go through the entire device tree
>> ourselves and find all properties that look like "power-domains =
>> <&power RK3288_PD_VIO>;".  We'd then find the parent of those
>> properties and look for a property named "clocks".  We'd then iterate
>> over all those clocks and turn those on.  Did I get that right?
>
> ... but you make it sound like more work than it is.  The genpd already
> keeps a list of devices that refer to the power domain.  In fact, the
> genpd 'attach' method can be platform-specific, so could be used to keep
> track of a list (or a subset) of clocks which are needed for reset.

That is not really workable: the attach and detach happen in
probe/remove path; if you do not have driver for the device you will
miss the clocks for it. And the quirk of this SoC is that we need to
turn all clocks during domain transition, regardless of whether there
is a driver for all devices.

Thanks.

-- 
Dmitry


From dianders at chromium.org  Tue Aug 25 16:55:41 2015
From: dianders at chromium.org (Doug Anderson)
Date: Tue, 25 Aug 2015 16:55:41 -0700
Subject: [RESEND PATCH v16 4/4] ARM: dts: add the support power-domain
 node on RK3288 SoCs
In-Reply-To: <7htwrn6l7g.fsf@deeprootsystems.com>
References: <1440487486-6154-1-git-send-email-wxt@rock-chips.com>
 <1440487486-6154-5-git-send-email-wxt@rock-chips.com>
 <7hfv37axhj.fsf@deeprootsystems.com>
 <CAD=FV=V6oG+9U=W_JZmqCuNo-9-5wW8ffZzG7ZE_3cnSTNAjFQ@mail.gmail.com>
 <7htwrn6l7g.fsf@deeprootsystems.com>
Message-ID: <CAD=FV=WAjXcgft8H8orrDcJ9OXaUDoOKSFEmibFMm51a9kHkBQ@mail.gmail.com>

Kevin,

On Tue, Aug 25, 2015 at 3:45 PM, Kevin Hilman <khilman at kernel.org> wrote:
>> To put things in a
>> concrete way, for pd_vio we'd go through the entire device tree
>> ourselves and find all properties that look like "power-domains =
>> <&power RK3288_PD_VIO>;".  We'd then find the parent of those
>> properties and look for a property named "clocks".  We'd then iterate
>> over all those clocks and turn those on.  Did I get that right?
>
> ... but you make it sound like more work than it is.  The genpd already
> keeps a list of devices that refer to the power domain.  In fact, the
> genpd 'attach' method can be platform-specific, so could be used to keep
> track of a list (or a subset) of clocks which are needed for reset.

OK.  I'll need to dig through and figure out how this works.  So this
list will include devices whose drivers are compiled out and also
devices that are marked as 'status = "disabled";' in the device tree?
It would need to do this in case someone had a board that didn't use
one of these peripherals (since we still need to clock it as we make
the domain go up and down).

I took a quick gander and didn't see code that would do this.  Can you
give me a quick pointer?

We also need to really make sure that there are no probe order issues...


>> 2. If we absolutely need to turn all clocks and we get clocks from
>> device tree nodes on then it means we need device tree nodes for every
>> device in the domain.
>
> Isn't that the end goal?

In the ideal world, yes.  ...but it's possibly years before all
drivers are added, or possibly they never will be.  To name a concrete
example, unless I'm mistaken, the "hardware crypto" device present in
exynos5250 still isn't anywhere in upstream despite several years
having passed.  There are just so many devices in these SoCs that
aren't used.


>> These would be needed even if there are no
>> accepted bindings for this device yet.  So we'd need to do one of: A)
>> Block power domain patches on feature complete bindings for all
>> drivers; B) Make up non-approved compatible strings for all devices
>> and throw them into the DTS; C) Add nodes in the DTS without a
>> compatible string just to satisfy the power domain requirements.  None
>> of these seem terribly appealing.
>
> well, I think we can be slightly more accomodating than that and go for
> somewhere in between:
>
> D) In the power-domain DTS, clearly describe why each clock is needed by
> the power-domain.  In particular list out clocks that are not device
> clocks (and why they need to be asserted for reset) and separate those
> from device clocks which are only listed in the power-domain because
> there is not *yet* a driver/binding for that device node.
>
> Doing it that way also makes it clear that when a new driver/binding is
> added, the clocks should be removed from the power-domain node and put
> into the device node.
>
> Also, this addresses my primary concern that the DTS acurately describes
> the hardware.  IOW, in hardware, most of these clocks are are properties
> of devices, not power-domains, and the DT should reflect that.
>
> IMO, if it's not describing the hardware, and is a placeholder until a
> driver/binding is in place, it should be properly documented.

Agreed that more documentation about why each clock is needed would go
a long way to helping.

I'd say that the clocks are properties of the device, but I'd again
assert that not all clocks that are owned by the device are relevant
to turning power domains on and off.  If you really wanted to be
correct, you'd add a property like this to devices:

power-on-clocks = <..>;

...this would be a list of clocks needed to power on the device
properly.  If such a property was added that would erase my objection
to that.  Note that you could say that if "power-on-clocks" wasn't
present then you could fall back to "clocks".  I do worry a little bit
about over-engineering, so I guess this could just be a future
improvement...


>> 3. It is entirely possible that there are clocks that will be listed
>> in the individual devices that aren't needed for powering on the power
>> domain.  I'd tend to believe that PCLK_EDP_CTRL (the pixel clock)
>> doesn't really need to be turned on when adjusting the "VIO" power
>> domain.  Right now Caesar has it listed, but it probably isn't needed
>> (Caesar: can you confirm?).
>
> Yes, I suspect there are several of those, which is also why I'd like to
> see the clocks in the power-domain node described in detail, and exacly
> why they're needed to be enabled.

I guess my point was that this was a reason for doing something like
"power-on-clocks" because it would let you avoid turning on
PCLK_EDP_CTRL (which is listed in the "clocks" of the EDP device but
maybe not needed while powering on/off the domain).  ...or just have
the list as part of the power domain.  :-P


> Also, in the current proposed DTS, clocks that are listed in both device
> nodes and the power domain are also suspicous, especially when the
> device node doesn't have a power-domain property.  (c.f. vop[bl] nodes
> and ACLK_VOP[01] clocks.)  For that matter, this series doesn't add any
> devices to the power domains, which makes it even more confusing about
> how this is meant to work.  IOW, with no devices belonging to
> power-domains, how are the power-domain power_on/power_off callbacks
> being called?

I totally believe that our current hardware definition isn't so
correct (though it does seem to work).  I'd be that devices that never
turn off often don't have a power domain defined (though they
technically have one) because that power domain always happens to be
on and no amount of specifying will allow it to turn off.  An
advantage of what you're pushing for is that it really forces us to
think about exactly what clocks are needed and forces us to specify
power domains more correctly.


>> 4. It seems just slightly brittle to be reaching into other device
>> nodes and making assumptions about their properties.  Yeah, it's
>> probably safe to assume that "clocks" has a list of clocks and
>> "power-domains" will point to something whose first entry is a
>> phandle, but it still seems just a tad bit like violating an
>> abstraction barrier.
>
> shmobile is already doing this with platform-specific genpd attach
> callbacks, and using the pm_clk API.  I don't see any issues with that.

I can see it working.  It's more of a feeling of unease.  ...but
that's not a good enough reason to reject something...

-Doug


From davem at davemloft.net  Tue Aug 25 17:06:11 2015
From: davem at davemloft.net (David Miller)
Date: Tue, 25 Aug 2015 17:06:11 -0700 (PDT)
Subject: [PATCH] drivers: net: xgene: fix: Oops in linkwatch_fire_event
In-Reply-To: <1440540183-11006-1-git-send-email-isubramanian@apm.com>
References: <1440540183-11006-1-git-send-email-isubramanian@apm.com>
Message-ID: <20150825.170611.202935268032680894.davem@davemloft.net>

From: Iyappan Subramanian <isubramanian at apm.com>
Date: Tue, 25 Aug 2015 15:03:03 -0700

> [ 1065.801569] Internal error: Oops: 96000006 [#1] SMP
> ...
> [ 1065.866655] Hardware name: AppliedMicro Mustang/Mustang, BIOS 1.1.0 Apr 22 2015
> [ 1065.873937] Workqueue: events_power_efficient phy_state_machine
> [ 1065.879837] task: fffffe01de105e80 ti: fffffe00bcf18000 task.ti: fffffe00bcf18000
> [ 1065.887288] PC is at linkwatch_fire_event+0xac/0xc0
> [ 1065.892141] LR is at linkwatch_fire_event+0xa0/0xc0
> [ 1065.896995] pc : [<fffffe000060284c>] lr : [<fffffe0000602840>] pstate: 200001c5
> [ 1065.904356] sp : fffffe00bcf1bd00
> ...
> [ 1066.196813] Call Trace:
> [ 1066.199248] [<fffffe000060284c>] linkwatch_fire_event+0xac/0xc0
> [ 1066.205140] [<fffffe000061167c>] netif_carrier_off+0x54/0x64
> [ 1066.210773] [<fffffe00004f1654>] phy_state_machine+0x120/0x3bc
> [ 1066.216578] [<fffffe00000d8d10>] process_one_work+0x15c/0x3a8
> [ 1066.222296] [<fffffe00000d9090>] worker_thread+0x134/0x470
> [ 1066.227757] [<fffffe00000df014>] kthread+0xe0/0xf8
> [ 1066.232525] Code: 97f65ee9 f9420660 d538d082 8b000042 (885f7c40)
> 
> The fix is to call phy_disconnect() from xgene_enet_mdio_remove,
> which in turn call cancel_delayed_work_sync().
> 
> Signed-off-by: Iyappan Subramanian <isubramanian at apm.com>

Applied, thanks.


From hongzhou.yang at mediatek.com  Tue Aug 25 17:16:10 2015
From: hongzhou.yang at mediatek.com (Hongzhou Yang)
Date: Tue, 25 Aug 2015 17:16:10 -0700
Subject: [PATCH v4] pinctrl: mediatek: Fix multiple registration issue.
Message-ID: <1440548170-10174-1-git-send-email-hongzhou.yang@mediatek.com>

Since our common driver need support main chip and PMU
at the same time, that means it will register two
pinctrl device, and the pinctrl_desc structure should
be used two times.

But pinctrl_desc use global static definition, then
the latest registered pinctrl device will overwrite
the old one's, all members in pinctrl_desc will set to
the new one's, such as name, pins and pins numbers, etc.
This is a bug. Changing to use devm_kzalloc to fix it.

Cc: stable at vger.kernel.org # v4.1+
Signed-off-by: Hongzhou Yang <hongzhou.yang at mediatek.com>
Reviewed-by: Axel Lin <axel.lin at ingics.com>
---
 Adding pinctrl_desc into mtk_pinctrl, assign new value for each 
 pinctrl device.

 drivers/pinctrl/mediatek/pinctrl-mtk-common.c |   21 ++++++++++-----------
 drivers/pinctrl/mediatek/pinctrl-mtk-common.h |    1 +
 2 files changed, 11 insertions(+), 11 deletions(-)

diff --git a/drivers/pinctrl/mediatek/pinctrl-mtk-common.c b/drivers/pinctrl/mediatek/pinctrl-mtk-common.c
index ad1ea16..4a52072 100644
--- a/drivers/pinctrl/mediatek/pinctrl-mtk-common.c
+++ b/drivers/pinctrl/mediatek/pinctrl-mtk-common.c
@@ -1202,12 +1202,6 @@ static int mtk_pctrl_build_state(struct platform_device *pdev)
 	return 0;
 }
 
-static struct pinctrl_desc mtk_pctrl_desc = {
-	.confops	= &mtk_pconf_ops,
-	.pctlops	= &mtk_pctrl_ops,
-	.pmxops		= &mtk_pmx_ops,
-};
-
 int mtk_pctrl_init(struct platform_device *pdev,
 		const struct mtk_pinctrl_devdata *data,
 		struct regmap *regmap)
@@ -1265,12 +1259,17 @@ int mtk_pctrl_init(struct platform_device *pdev,
 
 	for (i = 0; i < pctl->devdata->npins; i++)
 		pins[i] = pctl->devdata->pins[i].pin;
-	mtk_pctrl_desc.name = dev_name(&pdev->dev);
-	mtk_pctrl_desc.owner = THIS_MODULE;
-	mtk_pctrl_desc.pins = pins;
-	mtk_pctrl_desc.npins = pctl->devdata->npins;
+
+	pctl->pctl_desc.name = dev_name(&pdev->dev);
+	pctl->pctl_desc.owner = THIS_MODULE;
+	pctl->pctl_desc.pins = pins;
+	pctl->pctl_desc.npins = pctl->devdata->npins;
+	pctl->pctl_desc.confops = &mtk_pconf_ops;
+	pctl->pctl_desc.pctlops = &mtk_pctrl_ops;
+	pctl->pctl_desc.pmxops = &mtk_pmx_ops;
 	pctl->dev = &pdev->dev;
-	pctl->pctl_dev = pinctrl_register(&mtk_pctrl_desc, &pdev->dev, pctl);
+
+	pctl->pctl_dev = pinctrl_register(&pctl->pctl_desc, &pdev->dev, pctl);
 	if (IS_ERR(pctl->pctl_dev)) {
 		dev_err(&pdev->dev, "couldn't register pinctrl driver\n");
 		return PTR_ERR(pctl->pctl_dev);
diff --git a/drivers/pinctrl/mediatek/pinctrl-mtk-common.h b/drivers/pinctrl/mediatek/pinctrl-mtk-common.h
index 30213e5..c532c23 100644
--- a/drivers/pinctrl/mediatek/pinctrl-mtk-common.h
+++ b/drivers/pinctrl/mediatek/pinctrl-mtk-common.h
@@ -256,6 +256,7 @@ struct mtk_pinctrl_devdata {
 struct mtk_pinctrl {
 	struct regmap	*regmap1;
 	struct regmap	*regmap2;
+	struct pinctrl_desc pctl_desc;
 	struct device           *dev;
 	struct gpio_chip	*chip;
 	struct mtk_pinctrl_group	*groups;
-- 
1.7.9.5



From horms at verge.net.au  Tue Aug 25 17:27:25 2015
From: horms at verge.net.au (Simon Horman)
Date: Wed, 26 Aug 2015 09:27:25 +0900
Subject: [PATCH] ARM: shmobile: remove Makefile.boot
In-Reply-To: <CAMuHMdWYM6vVWzUQgR4u8cvoH6Jtq4XerYd2PbpvfUruDPi7-Q@mail.gmail.com>
References: <1440113264-30359-1-git-send-email-horms+renesas@verge.net.au>
 <CAMuHMdWYM6vVWzUQgR4u8cvoH6Jtq4XerYd2PbpvfUruDPi7-Q@mail.gmail.com>
Message-ID: <20150826002724.GA11168@verge.net.au>

On Tue, Aug 25, 2015 at 02:06:31PM +0200, Geert Uytterhoeven wrote:
> On Fri, Aug 21, 2015 at 1:27 AM, Simon Horman
> <horms+renesas at verge.net.au> wrote:
> > Now that the only multiplatform boot is supported for all
> > shmobile platforms Makefile.boot may be removed.
> >
> > This seems correct to me given:
> > * Setting MACHINE to no value in arch/arm/Makefile
> >   if CONFIG_ARCH_MULTIPLATFORM is set
> > * Not including Makefile.boot in arch/arm/boot/Makefile
> >   if MACHINE has no value
> >
> > Signed-off-by: Simon Horman <horms+renesas at verge.net.au>
> 
> Acked-by: Geert Uytterhoeven <geert+renesas at glider.be>

Thanks, I have queued this up for v4.4.


From hongzhou.yang at mediatek.com  Tue Aug 25 17:28:14 2015
From: hongzhou.yang at mediatek.com (Hongzhou Yang)
Date: Tue, 25 Aug 2015 17:28:14 -0700
Subject: [PATCH v4] pinctrl: mediatek: Fix multiple registration issue.
In-Reply-To: <1440548170-10174-1-git-send-email-hongzhou.yang@mediatek.com>
References: <1440548170-10174-1-git-send-email-hongzhou.yang@mediatek.com>
Message-ID: <1440548894.14000.1.camel@mussux00.eus.mediatek.inc>

On Tue, 2015-08-25 at 17:16 -0700, Hongzhou Yang wrote:
> Since our common driver need support main chip and PMU
> at the same time, that means it will register two
> pinctrl device, and the pinctrl_desc structure should
> be used two times.
> 
> But pinctrl_desc use global static definition, then
> the latest registered pinctrl device will overwrite
> the old one's, all members in pinctrl_desc will set to
> the new one's, such as name, pins and pins numbers, etc.
> This is a bug. Changing to use devm_kzalloc to fix it.
> 
> Cc: stable at vger.kernel.org # v4.1+
> Signed-off-by: Hongzhou Yang <hongzhou.yang at mediatek.com>
> Reviewed-by: Axel Lin <axel.lin at ingics.com>
> ---
>  Adding pinctrl_desc into mtk_pinctrl, assign new value for each 
>  pinctrl device.
> 
>  drivers/pinctrl/mediatek/pinctrl-mtk-common.c |   21 ++++++++++-----------
>  drivers/pinctrl/mediatek/pinctrl-mtk-common.h |    1 +
>  2 files changed, 11 insertions(+), 11 deletions(-)
> 
> diff --git a/drivers/pinctrl/mediatek/pinctrl-mtk-common.c b/drivers/pinctrl/mediatek/pinctrl-mtk-common.c
> index ad1ea16..4a52072 100644
> --- a/drivers/pinctrl/mediatek/pinctrl-mtk-common.c
> +++ b/drivers/pinctrl/mediatek/pinctrl-mtk-common.c
> @@ -1202,12 +1202,6 @@ static int mtk_pctrl_build_state(struct platform_device *pdev)
>  	return 0;
>  }
>  
> -static struct pinctrl_desc mtk_pctrl_desc = {
> -	.confops	= &mtk_pconf_ops,
> -	.pctlops	= &mtk_pctrl_ops,
> -	.pmxops		= &mtk_pmx_ops,
> -};
> -
>  int mtk_pctrl_init(struct platform_device *pdev,
>  		const struct mtk_pinctrl_devdata *data,
>  		struct regmap *regmap)
> @@ -1265,12 +1259,17 @@ int mtk_pctrl_init(struct platform_device *pdev,
>  
>  	for (i = 0; i < pctl->devdata->npins; i++)
>  		pins[i] = pctl->devdata->pins[i].pin;
> -	mtk_pctrl_desc.name = dev_name(&pdev->dev);
> -	mtk_pctrl_desc.owner = THIS_MODULE;
> -	mtk_pctrl_desc.pins = pins;
> -	mtk_pctrl_desc.npins = pctl->devdata->npins;
> +
> +	pctl->pctl_desc.name = dev_name(&pdev->dev);
> +	pctl->pctl_desc.owner = THIS_MODULE;
> +	pctl->pctl_desc.pins = pins;
> +	pctl->pctl_desc.npins = pctl->devdata->npins;
> +	pctl->pctl_desc.confops = &mtk_pconf_ops;
> +	pctl->pctl_desc.pctlops = &mtk_pctrl_ops;
> +	pctl->pctl_desc.pmxops = &mtk_pmx_ops;
>  	pctl->dev = &pdev->dev;
> -	pctl->pctl_dev = pinctrl_register(&mtk_pctrl_desc, &pdev->dev, pctl);
> +
> +	pctl->pctl_dev = pinctrl_register(&pctl->pctl_desc, &pdev->dev, pctl);
>  	if (IS_ERR(pctl->pctl_dev)) {
>  		dev_err(&pdev->dev, "couldn't register pinctrl driver\n");
>  		return PTR_ERR(pctl->pctl_dev);
> diff --git a/drivers/pinctrl/mediatek/pinctrl-mtk-common.h b/drivers/pinctrl/mediatek/pinctrl-mtk-common.h
> index 30213e5..c532c23 100644
> --- a/drivers/pinctrl/mediatek/pinctrl-mtk-common.h
> +++ b/drivers/pinctrl/mediatek/pinctrl-mtk-common.h
> @@ -256,6 +256,7 @@ struct mtk_pinctrl_devdata {
>  struct mtk_pinctrl {
>  	struct regmap	*regmap1;
>  	struct regmap	*regmap2;
> +	struct pinctrl_desc pctl_desc;
>  	struct device           *dev;
>  	struct gpio_chip	*chip;
>  	struct mtk_pinctrl_group	*groups;

Please ignore this patch, I will send another one.
Sorry about this.

Yours,
Hongzhou



From keescook at chromium.org  Tue Aug 25 17:32:06 2015
From: keescook at chromium.org (Kees Cook)
Date: Tue, 25 Aug 2015 17:32:06 -0700
Subject: [PATCH] arm: kgdb: Don't try to stop the machine when setting
 breakpoints
In-Reply-To: <1440540165-28875-1-git-send-email-dianders@chromium.org>
References: <1440540165-28875-1-git-send-email-dianders@chromium.org>
Message-ID: <CAGXu5jL+JUysOA8-B30__6vf-u6jhqJMTB++zuqQBxY17A-TRw@mail.gmail.com>

On Tue, Aug 25, 2015 at 3:02 PM, Douglas Anderson <dianders at chromium.org> wrote:
> In (23a4e40 arm: kgdb: Handle read-only text / modules) we moved to
> using patch_text() to set breakpoints so that we could handle the case
> when we had CONFIG_DEBUG_RODATA.  That patch used patch_text().
> Unfortunately, patch_text() assumes that we're not in atomic context
> when it runs since it needs to grab a mutex and also wait for other
> CPUs to stop (which it does with a completion).
>
> This would result in a stack crawl if you had
> CONFIG_DEBUG_ATOMIC_SLEEP and tried to set a breakpoint in kgdb.  The
> crawl looked something like:
>
>  BUG: scheduling while atomic: swapper/0/0/0x00010007
>  CPU: 0 PID: 0 Comm: swapper/0 Not tainted 4.2.0-rc7-00133-geb63b34 #1073
>  Hardware name: Rockchip (Device Tree)
>   (unwind_backtrace) from [<c00133d4>] (show_stack+0x20/0x24)
>   (show_stack) from [<c05400e8>] (dump_stack+0x84/0xb8)
>   (dump_stack) from [<c004913c>] (__schedule_bug+0x54/0x6c)
>   (__schedule_bug) from [<c054065c>] (__schedule+0x80/0x668)
>   (__schedule) from [<c0540cfc>] (schedule+0xb8/0xd4)
>   (schedule) from [<c0543a3c>] (schedule_timeout+0x2c/0x234)
>   (schedule_timeout) from [<c05417c0>] (wait_for_common+0xf4/0x188)
>   (wait_for_common) from [<c0541874>] (wait_for_completion+0x20/0x24)
>   (wait_for_completion) from [<c00a0104>] (__stop_cpus+0x58/0x70)
>   (__stop_cpus) from [<c00a0580>] (stop_cpus+0x3c/0x54)
>   (stop_cpus) from [<c00a06c4>] (__stop_machine+0xcc/0xe8)
>   (__stop_machine) from [<c00a0714>] (stop_machine+0x34/0x44)
>   (stop_machine) from [<c00173e8>] (patch_text+0x28/0x34)
>   (patch_text) from [<c001733c>] (kgdb_arch_set_breakpoint+0x40/0x4c)
>   (kgdb_arch_set_breakpoint) from [<c00a0d68>] (kgdb_validate_break_address+0x2c/0x60)
>   (kgdb_validate_break_address) from [<c00a0e90>] (dbg_set_sw_break+0x1c/0xdc)
>   (dbg_set_sw_break) from [<c00a2e88>] (gdb_serial_stub+0x9c4/0xba4)
>   (gdb_serial_stub) from [<c00a11cc>] (kgdb_cpu_enter+0x1f8/0x60c)
>   (kgdb_cpu_enter) from [<c00a18cc>] (kgdb_handle_exception+0x19c/0x1d0)
>   (kgdb_handle_exception) from [<c0016f7c>] (kgdb_compiled_brk_fn+0x30/0x3c)
>   (kgdb_compiled_brk_fn) from [<c00091a4>] (do_undefinstr+0x1a4/0x20c)
>   (do_undefinstr) from [<c001400c>] (__und_svc_finish+0x0/0x34)
>
> It turns out that when we're in kgdb all the CPUs are stopped anyway
> so there's no reason we should be calling patch_text().  We can
> instead directly call __patch_text() which assumes that CPUs have
> already been stopped.
>
> Fixes: 23a4e4050ba9 ("arm: kgdb: Handle read-only text / modules")
> Reported-by: Aapo Vienamo <avienamo at nvidia.com>
> Signed-off-by: Douglas Anderson <dianders at chromium.org>
> ---
>  arch/arm/kernel/kgdb.c | 8 +++++---
>  1 file changed, 5 insertions(+), 3 deletions(-)
>
> diff --git a/arch/arm/kernel/kgdb.c b/arch/arm/kernel/kgdb.c
> index a6ad93c..fd9eefc 100644
> --- a/arch/arm/kernel/kgdb.c
> +++ b/arch/arm/kernel/kgdb.c
> @@ -259,15 +259,17 @@ int kgdb_arch_set_breakpoint(struct kgdb_bkpt *bpt)
>         if (err)
>                 return err;
>
> -       patch_text((void *)bpt->bpt_addr,
> -                  *(unsigned int *)arch_kgdb_ops.gdb_bpt_instr);
> +       /* Machine is already stopped, so we can use __patch_text() directly */
> +       __patch_text((void *)bpt->bpt_addr,
> +                    *(unsigned int *)arch_kgdb_ops.gdb_bpt_instr);
>
>         return err;
>  }
>
>  int kgdb_arch_remove_breakpoint(struct kgdb_bkpt *bpt)
>  {
> -       patch_text((void *)bpt->bpt_addr, *(unsigned int *)bpt->saved_instr);
> +       /* Machine is already stopped, so we can use __patch_text() directly */
> +       __patch_text((void *)bpt->bpt_addr, *(unsigned int *)bpt->saved_instr);
>
>         return 0;
>  }
> --
> 2.5.0.457.gab17608
>

Ah, yes, much nicer. :) Thanks for chasing this!

Acked-by: Kees Cook <keescook at chromium.org>

-Kees

-- 
Kees Cook
Chrome OS Security


From hongzhou.yang at mediatek.com  Tue Aug 25 17:32:45 2015
From: hongzhou.yang at mediatek.com (Hongzhou Yang)
Date: Tue, 25 Aug 2015 17:32:45 -0700
Subject: [PATCH v4] pinctrl: mediatek: Fix multiple registration issue.
Message-ID: <1440549165-35637-1-git-send-email-hongzhou.yang@mediatek.com>

Since our common driver need support main chip and PMU
at the same time, that means it will register two
pinctrl device, and the pinctrl_desc structure should
be used two times.

But pinctrl_desc use global static definition, then
the latest registered pinctrl device will overwrite
the old one's, all members in pinctrl_desc will set to
the new one's, such as name, pins and pins numbers, etc.
This is a bug.

Move pinctrl_desc into mtk_pinctrl, assign new value for
each pinctrl device to fix it.

Cc: stable at vger.kernel.org # v4.1+
Signed-off-by: Hongzhou Yang <hongzhou.yang at mediatek.com>
Reviewed-by: Axel Lin <axel.lin at ingics.com>
---
 In order to fix multiple registration issue, move 
 pinctrl_desc into mtk_pinctrl, assign new value for
 each pinctrl device.

 drivers/pinctrl/mediatek/pinctrl-mtk-common.c |   21 ++++++++++-----------
 drivers/pinctrl/mediatek/pinctrl-mtk-common.h |    1 +
 2 files changed, 11 insertions(+), 11 deletions(-)

diff --git a/drivers/pinctrl/mediatek/pinctrl-mtk-common.c b/drivers/pinctrl/mediatek/pinctrl-mtk-common.c
index ad1ea16..4a52072 100644
--- a/drivers/pinctrl/mediatek/pinctrl-mtk-common.c
+++ b/drivers/pinctrl/mediatek/pinctrl-mtk-common.c
@@ -1202,12 +1202,6 @@ static int mtk_pctrl_build_state(struct platform_device *pdev)
 	return 0;
 }
 
-static struct pinctrl_desc mtk_pctrl_desc = {
-	.confops	= &mtk_pconf_ops,
-	.pctlops	= &mtk_pctrl_ops,
-	.pmxops		= &mtk_pmx_ops,
-};
-
 int mtk_pctrl_init(struct platform_device *pdev,
 		const struct mtk_pinctrl_devdata *data,
 		struct regmap *regmap)
@@ -1265,12 +1259,17 @@ int mtk_pctrl_init(struct platform_device *pdev,
 
 	for (i = 0; i < pctl->devdata->npins; i++)
 		pins[i] = pctl->devdata->pins[i].pin;
-	mtk_pctrl_desc.name = dev_name(&pdev->dev);
-	mtk_pctrl_desc.owner = THIS_MODULE;
-	mtk_pctrl_desc.pins = pins;
-	mtk_pctrl_desc.npins = pctl->devdata->npins;
+
+	pctl->pctl_desc.name = dev_name(&pdev->dev);
+	pctl->pctl_desc.owner = THIS_MODULE;
+	pctl->pctl_desc.pins = pins;
+	pctl->pctl_desc.npins = pctl->devdata->npins;
+	pctl->pctl_desc.confops = &mtk_pconf_ops;
+	pctl->pctl_desc.pctlops = &mtk_pctrl_ops;
+	pctl->pctl_desc.pmxops = &mtk_pmx_ops;
 	pctl->dev = &pdev->dev;
-	pctl->pctl_dev = pinctrl_register(&mtk_pctrl_desc, &pdev->dev, pctl);
+
+	pctl->pctl_dev = pinctrl_register(&pctl->pctl_desc, &pdev->dev, pctl);
 	if (IS_ERR(pctl->pctl_dev)) {
 		dev_err(&pdev->dev, "couldn't register pinctrl driver\n");
 		return PTR_ERR(pctl->pctl_dev);
diff --git a/drivers/pinctrl/mediatek/pinctrl-mtk-common.h b/drivers/pinctrl/mediatek/pinctrl-mtk-common.h
index 30213e5..c532c23 100644
--- a/drivers/pinctrl/mediatek/pinctrl-mtk-common.h
+++ b/drivers/pinctrl/mediatek/pinctrl-mtk-common.h
@@ -256,6 +256,7 @@ struct mtk_pinctrl_devdata {
 struct mtk_pinctrl {
 	struct regmap	*regmap1;
 	struct regmap	*regmap2;
+	struct pinctrl_desc pctl_desc;
 	struct device           *dev;
 	struct gpio_chip	*chip;
 	struct mtk_pinctrl_group	*groups;
-- 
1.7.9.5



From dingtianhong at huawei.com  Tue Aug 25 18:13:03 2015
From: dingtianhong at huawei.com (Ding Tianhong)
Date: Wed, 26 Aug 2015 09:13:03 +0800
Subject: ask for help about BUG: soft lockup - CPU#13 stuck for 22s!
 [trinity-c13:6691]
In-Reply-To: <55DC7679.5090707@huawei.com>
References: <55DC7679.5090707@huawei.com>
Message-ID: <55DD129F.2050703@huawei.com>

Looks like the none-preempt kernel will not schedule from trinity and the program run into D states?

Ding

On 2015/8/25 22:06, Kefeng Wang wrote:
> Hi all,
> 
> We got issues about rcu/ soft lockup in trinity test on our arm64 board,
> and have no idea to fix this, any advice will be appreciated.
> 
> Our board test environment:
> 1) Kernel version: 3.19.0/3.19.8/4.1.0/4.1.6
> 2) Hardware: 32cpu, 128G memory
> 3) CONFIG: based on defconfig, use CONFIG_PREEMPT_NONE=y
> 4) TEST:  'trinity --dangerous' use root (trinity version 1.5)
> 
> 
> And we met rcu/soft lockup once in qemu environment,
> 1) Qemu:  2.4.0   cpu 8, mem 30G
> 2) Kernel version: 4.1
> 3) CONFIG: same as board
> 3) TEST: same as board
> 
> log[1]: logging pieces in board
> ------------------------------------------------------------------
> 
> [ 3430.085690] INFO: rcu_sched self-detected stall on CPU { 13}  (t=21006 jiffies g=10664 c=10663 q=2837)
> [ 3430.093697] INFO: rcu_sched detected stalls on CPUs/tasks: { 13} (detected by 16, t=21007 jiffies, g=10664, c=10663, q=2837)
> [ 3430.093698] Task dump for CPU 13:
> [ 3430.093701] trinity-c13     R  running task        0  6691   6001 0x00000003
> [ 3430.093702] Call trace:
> [ 3430.093709] [<ffffffc000087438>] __switch_to+0x74/0x8c
> [ 3430.104867] Task dump for CPU 13:
> [ 3430.104868] trinity-c13     R  running task        0  6691   6001 0x00000003
> [ 3430.104872] Call trace:
> [ 3430.106019] [<ffffffc00008a1d0>] dump_backtrace+0x0/0x124
> [ 3430.106022] [<ffffffc00008a304>] show_stack+0x10/0x1c
> [ 3430.106026] [<ffffffc0000d4c4c>] sched_show_task+0x98/0xf8
> [ 3430.106030] [<ffffffc0000d7d74>] dump_cpu_task+0x3c/0x4c
> [ 3430.106033] [<ffffffc0000f61ac>] rcu_dump_cpu_stacks+0xa4/0xf8
> [ 3430.106035] [<ffffffc0000f91cc>] rcu_check_callbacks+0x3d4/0x6a4
> [ 3430.106039] [<ffffffc0000fc788>] update_process_times+0x38/0x6c
> [ 3430.106042] [<ffffffc00010af34>] tick_sched_handle.isra.16+0x1c/0x68
> [ 3430.106044] [<ffffffc00010afc0>] tick_sched_timer+0x40/0x88
> [ 3430.106047] [<ffffffc0000fce64>] __run_hrtimer.isra.34+0x4c/0x108
> [ 3430.106050] [<ffffffc0000fd53c>] hrtimer_interrupt+0x100/0x2ac
> [ 3430.106054] [<ffffffc000594074>] arch_timer_handler_phys+0x28/0x38
> [ 3430.106058] [<ffffffc0000f0668>] handle_percpu_devid_irq+0x74/0x9c
> [ 3430.106060] [<ffffffc0000ec638>] generic_handle_irq+0x30/0x4c
> [ 3430.106062] [<ffffffc0000ec954>] __handle_domain_irq+0x5c/0xac
> [ 3430.106065] [<ffffffc0000824f4>] gic_handle_irq+0x88/0xf8
> [ 3430.106067] Exception stack(0xffffffdf84c97940 to 0xffffffdf84c97a60)
> [ 3430.106070] 7940: 84c97cf0 ffffffdf b46e1d40 ffffffdf 84c97a90 ffffffdf 00162930 ffffffc0
> [ 3430.106073] 7960: 80000145 00000000 96000047 00000000 b0aa0228 ffffffdf 7db41000 0000007f
> [ 3430.106075] 7980: b0aa0228 ffffffdf 79e422d8 ffffffdf 79e422e8 ffffffdf 7dc0f000 0000007f
> [ 3430.106077] 79a0: 00000000 00000000 00000000 00000000 00000000 00000000 00000000 00000000
> [ 3430.106080] 79c0: 7f7f7f7f 7f7f7f7f 01010101 01010101 00000018 00000000 66666566 66666466
> [ 3430.106083] 79e0: 66653766 74202c66 b7ef7529 00091372 000fedf0 ffffffc0 7e5a1ce0 0000007f
> [ 3430.106085] 7a00: 00000000 00000000 84c97cf0 ffffffdf b46e1d40 ffffffdf 00000029 00000000
> [ 3430.106087] 7a20: 79e42040 ffffffdf 7db41000 0000007f 96000047 00000000 dfff7eff ffffefff
> [ 3430.106090] 7a40: 00000002 00000000 b78872c0 ffffffdf b46e1da0 ffffffdf 84c97a90 ffffffdf
> [ 3430.106092] [<ffffffc000085da4>] el1_irq+0x64/0xc0
> [ 3430.106095] [<ffffffc000096e50>] do_page_fault+0xa4/0x350
> [ 3430.106097] [<ffffffc000082294>] do_mem_abort+0x38/0x9c
> [ 3430.106098] Exception stack(0xffffffdf84c97c50 to 0xffffffdf84c97d70)
> [ 3430.106101] 7c40:                                     48778d1f ffffffdf 00000009 00000000
> [ 3430.106103] 7c60: 84c97e10 ffffffdf 0030a74c ffffffc0 00000009 00000000 84c97e10 ffffffdf
> [ 3430.106106] 7c80: 0030a74c ffffffc0 60000145 00000000 00000025 00000000 dfff7eff ffffefff
> [ 3430.106108] 7ca0: 78a260d8 ffffffdf b78872c0 ffffffdf 009ff100 ffffffc0 84c97e10 ffffffdf
> [ 3430.106111] 7cc0: 000ff0dc ffffffc0 84c97cf0 ffffffdf 00085c20 ffffffc0 60000145 00000000
> [ 3430.106113] 7ce0: 60000145 00000000 009ffd00 ffffffc0 7db41000 0000007f 84c97e90 ffffffdf
> [ 3430.106116] 7d00: fffffffc ffffffff 00000009 00000000 7db41004 0000007f 00000009 00000000
> [ 3430.106118] 7d20: 00000073 00000000 00000000 00000000 00000000 00000000 00000000 00000000
> [ 3430.106121] 7d40: 7f7f7f7f 7f7f7f7f 01010101 01010101 00000018 00000000 66666566 66666466
> [ 3430.106123] 7d60: 66653766 74202c66 b7ef7529 00091372
> [ 3430.106125] [<ffffffc000085c24>] el1_da+0x14/0x70
> [ 3456.373558] NMI watchdog: BUG: soft lockup - CPU#13 stuck for 22s! [trinity-c13:6691]
> [ 3456.380109] Modules linked in: ipmi_si ipmi_devintf ipmi_msghandler
> 
> [ 3456.380116] CPU: 13 PID: 6691 Comm: trinity-c13 Tainted: G             L  3.19.8+ #48
> 
> [ 3456.380120] task: ffffffdf79e42040 ti: ffffffdf84c94000 task.ti: ffffffdf84c94000
> [ 3456.380122] PC is at handle_mm_fault+0x35c/0xdb8
> [ 3456.380124] LR is at handle_mm_fault+0x350/0xdb8
> [ 3456.380126] pc : [<ffffffc00015f7b8>] lr : [<ffffffc00015f7ac>] pstate: 60000145
> [ 3456.380127] sp : ffffffdf84c97a00
> [ 3456.380129] x29: ffffffdf84c97a00 x28: ffffffc00098c000
> [ 3456.380132] x27: ffffffdfb0aa0228 x26: 00000000000001ed
> [ 3456.380134] x25: ffffffbe3ed19ab0 x24: 0000007f7db41000
> [ 3456.380137] x23: 0d34000007f7db41 x22: ffffffdf85bd9f68
> [ 3456.380140] x21: ffffffdfb46e1d40 x20: ffffffdfb446a000
> [ 3456.380142] x19: ffffffbe3ed19a80 x18: 0000000000000000
> [ 3456.380145] x17: 0000007f7e5a1ce0 x16: ffffffc0000fedf0
> [ 3456.380147] x15: 00091372b7ef7529 x14: 74202c6666653766
> [ 3456.380150] x13: 6666646666666566 x12: 0000000000000018
> [ 3456.380152] x11: 0101010101010101 x10: 7f7f7f7f7f7f7f7f
> [ 3456.380155] x9 : 0000000000000000 x8 : 0000000007f7db41
> [ 3456.380157] x7 : 0000000000000141 x6 : 02e0002fa95c6751
> [ 3456.380160] x5 : 0000000000000a08 x4 : 02e0002fa95c6751
> [ 3456.380162] x3 : 02e0002fa95c6751 x2 : ffffffdfb446aa08
> [ 3456.380165] x1 : 0000007f7db41000 x0 : 0000000000010d34
> 
> [ 3484.373416] NMI watchdog: BUG: soft lockup - CPU#13 stuck for 23s! [trinity-c13:6691]
> [ 3484.379975] CPU: 13 PID: 6691 Comm: trinity-c13 Tainted: G             L  3.19.8+ #48
> [ 3484.379979] task: ffffffdf79e42040 ti: ffffffdf84c94000 task.ti: ffffffdf84c94000
> [ 3484.379981] PC is at handle_mm_fault+0x35c/0xdb8
> [ 3484.379983] LR is at handle_mm_fault+0x350/0xdb8
> [ 3484.379985] pc : [<ffffffc00015f7b8>] lr : [<ffffffc00015f7ac>] pstate: 60000145
> [ 3484.379986] sp : ffffffdf84c97a00
> [ 3484.379988] x29: ffffffdf84c97a00 x28: ffffffc00098c000
> [ 3484.379990] x27: ffffffdfb0aa0228 x26: 00000000000001ed
> [ 3484.379993] x25: ffffffbe3ed19ab0 x24: 0000007f7db41000
> [ 3484.379996] x23: 0d34000007f7db41 x22: ffffffdf85bd9f68
> [ 3484.379998] x21: ffffffdfb46e1d40 x20: ffffffdfb446a000
> [ 3484.380001] x19: ffffffbe3ed19a80 x18: 0000000000000000
> [ 3484.380003] x17: 0000007f7e5a1ce0 x16: ffffffc0000fedf0
> [ 3484.380006] x15: 00091372b7ef7529 x14: 74202c6666653766
> [ 3484.380008] x13: 6666646666666566 x12: 0000000000000018
> [ 3484.380011] x11: 0101010101010101 x10: 7f7f7f7f7f7f7f7f
> [ 3484.380013] x9 : 0000000000000000 x8 : 0000000007f7db41
> [ 3484.380016] x7 : 0000000000000141 x6 : 02e0002fa95c6751
> [ 3484.380018] x5 : 0000000000000a08 x4 : 02e0002fa95c6751
> [ 3484.380021] x3 : 02e0002fa95c6751 x2 : ffffffdfb446aa08
> [ 3484.380024] x1 : 0000007f7db41000 x0 : 0000000000010d34
> 
> 
> 
> log[2]: logging pieces in QEMU
> ------------------------------------------------------------------
> [ 9720.804545] INFO: rcu_sched detected stalls on CPUs/tasks:
> [ 9720.807407] 	0: (166 ticks this GP) idle=cab/140000000000000/0 softirq=114221/114221 fqs=38
> [ 9720.808447] 	(detected by 3, t=2102 jiffies, g=84925, c=84924, q=114)
> [ 9720.809416] Task dump for CPU 0:
> [ 9720.809768] ksoftirqd/0     R  running task        0     3      2 0x00000002
> [ 9720.812007] Call trace:
> [ 9720.813325] [<ffffffc000086c5c>] __switch_to+0x74/0x8c
> [ 9724.041575] NMI watchdog: BUG: soft lockup - CPU#0 stuck for 23s! [ksoftirqd/0:3]
> [ 9724.044976] Modules linked in:
> 
> [ 9724.047586] CPU: 0 PID: 3 Comm: ksoftirqd/0 Not tainted 4.1.0 #3
> [ 9724.050050] Hardware name: linux,dummy-virt (DT)
> [ 9724.050886] NMI watchdog: BUG: soft lockup - CPU#1 stuck for 23s! [trinity-main:1331]
> [ 9724.050991] Modules linked in:
> 
> [ 9724.051589] CPU: 1 PID: 1331 Comm: trinity-main Not tainted 4.1.0 #3
> [ 9724.051610] Hardware name: linux,dummy-virt (DT)
> [ 9724.051729] task: ffffffc75db44200 ti: ffffffc755a54000 task.ti: ffffffc755a54000
> [ 9724.051888] PC is at run_hrtimer_softirq+0x1c/0x28
> [ 9724.051951] LR is at run_hrtimer_softirq+0x18/0x28
> [ 9724.052004] pc : [<ffffffc0000fec5c>] lr : [<ffffffc0000fec58>] pstate: 20000145
> [ 9724.052033] sp : ffffffc755a57b80
> [ 9724.052152] x29: ffffffc755a57b80 x28: 0000000000000000
> [ 9724.052211] x27: ffffffc00084a140 x26: ffffffc00084a110
> [ 9724.052258] x25: 0000000000000008 x24: 0000000000000100
> [ 9724.052304] x23: 0000000000000030 x22: ffffffc755a57ba0
> [ 9724.052352] x21: ffffffc000837ab8 x20: ffffffc00084a000
> [ 9724.052407] x19: 0000000000000140 x18: 0000007fdf417090
> [ 9724.052453] x17: 0000007f7e3ae2c0 x16: ffffffc0000b6104
> [ 9724.052497] x15: 0000000000005d67 x14: 0000000000000000
> [ 9724.052540] x13: 00000000696e695b x12: ffffffc0005bd43c
> [ 9724.052583] x11: 0000000000000005 x10: 0000000000000533
> [ 9724.052621] x9 : 0000000000000004 x8 : ffffffc0005bd460
> [ 9724.052660] x7 : ffffffc755a54000 x6 : 00119557c0000000
> [ 9724.052700] x5 : 0000000010000000 x4 : 0000000000000020
> [ 9724.052739] x3 : ffffffc0004b2634 x2 : 00000000000003e8
> [ 9724.052779] x1 : 0000000000000001 x0 : 0000000000000000
> 
> [ 9724.410042] task: ffffffc75e871600 ti: ffffffc75e994000 task.ti: ffffffc75e994000
> [ 9724.483895] PC is at _raw_read_lock+0x8/0x20
> [ 9724.485252] LR is at raw_local_deliver+0x48/0x1b0
> [ 9724.485939] pc : [<ffffffc0005aa7f4>] lr : [<ffffffc0005437ec>] pstate: a0000145
> [ 9724.486792] sp : ffffffc75e997a40
> [ 9724.487214] x29: ffffffc75e997a40 x28: ffffffc74e174600
> [ 9724.488052] x27: 0000000000000000 x26: 0000000000000000
> [ 9724.488854] x25: 000000000000a888 x24: ffffffc7562d20a0
> [ 9724.489679] x23: ffffffc0008db000 x22: ffffffc0008a1000
> [ 9724.490462] x21: ffffffc0008db578 x20: ffffffc74e174600
> [ 9724.491294] x19: ffffffc6af86f990 x18: 00000000000000b9
> [ 9724.492142] x17: 0000007fb0630120 x16: ffffffc000196244
> [ 9724.555949] x15: 001dcd6500000000 x14: 0000000000000000
> [ 9724.556187] x13: 00000000a15d7a92 x12: 0000000000000020
> [ 9724.556410] x11: 0101010101010101 x10: 7f7f7f7f7f7f7f7f
> [ 9724.556629] x9 : fefefefefefefeff x8 : 0000000000000000
> [ 9724.556816] x7 : 0000000000000004 x6 : 0000000000000000
> [ 9724.557006] x5 : 0000000000000005 x4 : ffffffc756130000
> [ 9724.557198] x3 : ffffffc0008db548 x2 : ffffffc0ba9bc7b8
> [ 9724.557393] x1 : 0000000000000050 x0 : ffffffc0008db548
> 
> Thanks,
> Kefeng
> 
> 
> .
> 




From yalin.wang2010 at gmail.com  Tue Aug 25 18:24:26 2015
From: yalin.wang2010 at gmail.com (yalin wang)
Date: Wed, 26 Aug 2015 09:24:26 +0800
Subject: [PATCH] arm: insn: use set_fixmap_offset to make it more clear
Message-ID: <1440552266-19940-1-git-send-email-yalin.wang2010@gmail.com>

A little change to patch_map() function,
use set_fixmap_offset() to make code more clear.

Signed-off-by: yalin wang <yalin.wang2010 at gmail.com>
---
 arch/arm/kernel/patch.c | 5 ++---
 1 file changed, 2 insertions(+), 3 deletions(-)

diff --git a/arch/arm/kernel/patch.c b/arch/arm/kernel/patch.c
index 69bda1a..5779105 100644
--- a/arch/arm/kernel/patch.c
+++ b/arch/arm/kernel/patch.c
@@ -36,9 +36,8 @@ static void __kprobes *patch_map(void *addr, int fixmap, unsigned long *flags)
 	else
 		__acquire(&patch_lock);
 
-	set_fixmap(fixmap, page_to_phys(page));
-
-	return (void *) (__fix_to_virt(fixmap) + (uintaddr & ~PAGE_MASK));
+	return (void *)set_fixmap_offset(fixmap, page_to_phys(page) +
+			(uintaddr & ~PAGE_MASK));
 }
 
 static void __kprobes patch_unmap(int fixmap, unsigned long *flags)
-- 
1.9.1



From haojian.zhuang at linaro.org  Tue Aug 25 18:25:41 2015
From: haojian.zhuang at linaro.org (Haojian Zhuang)
Date: Wed, 26 Aug 2015 09:25:41 +0800
Subject: [PATCH v1 3/3] arm64: dts: add Hi6220 mailbox node
In-Reply-To: <20150825160030.GA3774@leoy-linaro>
References: <20150821184059.GB2000@svinekod>
 <20150824091845.GA28290@leoy-linaro> <20150824095144.GA7139@leverpostej>
 <1440411596.3517.12.camel@linaro.org>
 <20150824114903.GT10728@bivouac.eciton.net>
 <1440490427.10987.29.camel@linaro.org>
 <20150825094630.GU10728@bivouac.eciton.net>
 <1440497710.10987.42.camel@linaro.org> <20150825104256.GB13471@leverpostej>
 <1440510194.10987.52.camel@linaro.org> <20150825160030.GA3774@leoy-linaro>
Message-ID: <1440552341.10987.53.camel@linaro.org>

On Wed, 2015-08-26 at 00:00 +0800, Leo Yan wrote:
> On Tue, Aug 25, 2015 at 09:43:14PM +0800, Haojian Zhuang wrote:
> > On Tue, 2015-08-25 at 11:42 +0100, Mark Rutland wrote:
> > > > > Are you then going to hack GRUB, release a special HiKey version of
> > > > > GRUB, not support any other versions, and still can your firmware
> > > > > UEFI?
> > > > 
> > > > I don't need to hack GRUB at all.
> > > 
> > > Then it is working for you by pure chance alone.
> > > 
> > > Please listen to the advice you are being given here; we're trying to
> > > ensure that your platform functions (and continues to function) as best
> > > it can.
> > 
> > Since we discussed a lot on this, let's make a conclusion on it.
> > 
> > 1. UEFI could append the reserved buffer in it's memory mapping.
> > 2. These reserved buffer must be declared in DT, since we also need to
> >    support non-UEFI (uboot) at the same time.
> > 3. Mailbox node should reference reserved buffer by phandle in DT. Then
> >    map the buffer as non-cacheable in driver.
> > 4. These reserved buffer must use "no-map" property since it should be
> >    non-cacheable in driver.
> 
> For more specific discussion for DTS, i list two options at here;
> 
> - Option 1: just simply reserve memory regions through memory node,
>   and mailbox node will directly use the buffer through reg ranges;
> 
> - Option 2: use reserved-memory and mailbox node will refer phandle
>   of reserved-memory;
> 
> These two options both can work well with UEFI and Uboot, but option 1
> is more simple and straightforward; so i personally prefer it. But
> look forwarding your guys' suggestion.
> 
> Option 1:
> 
> 	memory at 0 {
> 		device_type = "memory";
> 		reg = <0x00000000 0x00000000 0x00000000 0x05e00000>,
> 		      <0x00000000 0x05f00000 0x00000000 0x00eff000>,
> 		      <0x00000000 0x06e00000 0x00000000 0x0060f000>,
> 		      <0x00000000 0x07410000 0x00000000 0x38bf0000>;
> 	};
> 
>         [...]
> 
> 	mailbox: mailbox at f7510000 {
> 		#mbox-cells = <1>;
> 		compatible = "hisilicon,hi6220-mbox";
> 		reg = <0x0 0xf7510000 0x0 0x1000>, /* IPC_S */
> 		      <0x0 0x06dff800 0x0 0x0800>; /* Mailbox buffer */
> 		interrupts = <GIC_SPI 94 IRQ_TYPE_LEVEL_HIGH>;
> 	};
> 
> Option 2:
> 
> 	memory at 0 {
> 		device_type = "memory";
> 		reg = <0x0 0x0 0x0 0x40000000>;
> 	};
> 
> 	reserved-memory {
> 		#address-cells = <2>;
> 		#size-cells = <2>;
> 		ranges;
> 
> 		mcu_reserved: mcu_reserved at 06dff000 {
> 			no-map;
> 			reg = <0x0 0x06dff000 0x0 0x00001000>,	/* MCU mailbox buffer */
> 			      <0x0 0x05e00000 0x0 0x00100000>,	/* MCU firmware buffer */
> 			      <0x0 0x0740f000 0x0 0x00001000>;	/* MCU firmware section */
> 		};
> 	};
> 
>         [...]
> 
> 	mailbox: mailbox at f7510000 {
> 		#mbox-cells = <1>;
> 		compatible = "hisilicon,hi6220-mbox";
> 		reg = <0x0 0xf7510000 0x0 0x1000>; /* IPC_S */
> 		memory-region = <&mcu_reserved>;   /* Mailbox buffer */
> 		interrupts = <GIC_SPI 94 IRQ_TYPE_LEVEL_HIGH>;
> 	};

I prefer the second one. From my view, memory node should only describe
the hardware information of memory.

Regards
Haojian



From pi-cheng.chen at linaro.org  Tue Aug 25 18:25:29 2015
From: pi-cheng.chen at linaro.org (Pi-Cheng Chen)
Date: Wed, 26 Aug 2015 09:25:29 +0800
Subject: [RESEND PATCH 0/3 v6] Add Mediatek MT8173 cpufreq driver
In-Reply-To: <1617873.VRHfat3V76@vostro.rjw.lan>
References: <1439803465-19683-1-git-send-email-pi-cheng.chen@linaro.org>
 <CALx668VWg2xVxzy8P7f5QFWRzm+TDJXUghL-_rbvRLsLYjtnng@mail.gmail.com>
 <1617873.VRHfat3V76@vostro.rjw.lan>
Message-ID: <CALx668UvkYhLoU8rxLG70RqTzsnaiV5-ybDYTKqb4MEJS8pmRw@mail.gmail.com>

Hi Rafael,

On Wed, Aug 26, 2015 at 7:01 AM, Rafael J. Wysocki <rjw at rjwysocki.net> wrote:
> On Tuesday, August 25, 2015 10:10:44 AM Pi-Cheng Chen wrote:
>> On Mon, Aug 17, 2015 at 5:24 PM, Pi-Cheng Chen <pi-cheng.chen at linaro.org> wrote:
>> > MT8173 is a ARMv8 based SoC with 2 clusters. All CPUs in a single cluster
>> > share the same power and clock domain. This series tries to add cpufreq support
>> > for MT8173 SoC. The v6 of this series is resent with Acks added.
>>
>> Hi Rafael,
>>
>> Not sure if I has missed the merge window.
>> Do I have chance to have this series merged for 4.3?
>
> Yes, it should make it.
>
>> Would you please take [1,2] of this series?

Thanks.

>
> I'm not sure what you mean.  Are you withdrawing the [3/3]?

The [3/3] is based on Mediatek SoC maintainer tree[1] and the patch which
introduce a new clock type[2] consumed by MT8173 cpufreq driver. So it will
cause some conflicts if it goes through your tree. I am not sure how this
should be handled, but should it be merged through Mediatek SoC maintainer
tree?

@Matthias?

Thanks

Best Regards,
Pi-Cheng

[1] https://github.com/mbgg/linux-mediatek.git v4.2-next/arm64
[2] http://article.gmane.org/gmane.linux.kernel/2021379

>
> Thanks,
> Rafael
>


From yamada.masahiro at socionext.com  Tue Aug 25 18:38:59 2015
From: yamada.masahiro at socionext.com (Masahiro Yamada)
Date: Wed, 26 Aug 2015 10:38:59 +0900
Subject: [PATCH 1/3] ARM: uniphier: add outer cache support
In-Reply-To: <2021253.vgeYqalDfp@wuerfel>
References: <1440382692-3855-1-git-send-email-yamada.masahiro@socionext.com>
 <1440382692-3855-2-git-send-email-yamada.masahiro@socionext.com>
 <2021253.vgeYqalDfp@wuerfel>
Message-ID: <CAK7LNAQ_oymnQNEcP+FDqyxNKtMyiCwgxSRMmg5HAKQW9C6eRg@mail.gmail.com>

Hi Arnd,


2015-08-25 4:59 GMT+09:00 Arnd Bergmann <arnd at arndb.de>:
> On Monday 24 August 2015 11:18:10 Masahiro Yamada wrote:
>> diff --git a/Documentation/devicetree/bindings/arm/uniphier/cache-uniphier.txt b/Documentation/devicetree/bindings/arm/uniphier/cache-uniphier.txt
>> new file mode 100644
>> index 0000000..6428289
>> --- /dev/null
>> +++ b/Documentation/devicetree/bindings/arm/uniphier/cache-uniphier.txt
>> @@ -0,0 +1,30 @@
>> +UniPhier outer cache controller
>> +
>> +UniPhier SoCs are integrated with a level 2 cache controller that resides
>> +outside of the ARM cores, some of them also have a level 3 cache controller.
>> +
>> +Required properties:
>> +- compatible: should be one of the followings:
>> +       "socionext,uniphier-l2-cache"   (L2 cache)
>> +       "socionext,uniphier-l3-cache"   (L3 cache)
>> +- reg: offsets and lengths of the register sets for the device.  It should
>> +  contain 3 regions: control registers, revision registers, operation
>> +  registers, in this order.
>> +
>> +The L2 cache must exist to use the L3 cache; adding only an L3 cache device
>> +node to the device tree causes the initialization failure of the whole outer
>> +cache system.
>>
>
> How much does this outer cache have in common with the l2x0/pl310 cache
> controller model?

Nothing.

This outer cache is not a variant of l2x0/pl310.
It was designed only for our SoCs from scratch.


> Would it make sense to at least share the
> common entry point at l2x0_of_init() so you don't need to call it from
> the platform file?

I do not think so.


l2x0_of_init() checks L2X0_AUX_CTRL register,
but the cache-uniphier does not have such register,
so the boot code crashes.



BTW, what makes l2x0_of_init() so special?

Only L2x0/L310 and variants can be initialized
directly from init_IRQ().

Moreover, outer-cache init seems to be unrelated to
IRQ init.


-- 
Best Regards
Masahiro Yamada


From swarren at wwwdotorg.org  Tue Aug 25 18:44:51 2015
From: swarren at wwwdotorg.org (Stephen Warren)
Date: Tue, 25 Aug 2015 19:44:51 -0600
Subject: [PATCH v4 3/5] dt/bindings: bcm2835: add binding documentation
 for bcm2835-aux
In-Reply-To: <1440405608-3995-4-git-send-email-kernel@martin.sperl.org>
References: <1440405608-3995-1-git-send-email-kernel@martin.sperl.org>
 <1440405608-3995-4-git-send-email-kernel@martin.sperl.org>
Message-ID: <55DD1A13.7010705@wwwdotorg.org>

On 08/24/2015 02:40 AM, kernel at martin.sperl.org wrote:
> From: Martin Sperl <kernel at martin.sperl.org>

Patch description?

> diff --git a/Documentation/devicetree/bindings/soc/bcm/brcm,bcm2835-aux.txt b/Documentation/devicetree/bindings/soc/bcm/brcm,bcm2835-aux.txt

> +Required properties:
> +- compatible: Should be "brcm,bcm2835-aux".
> +- reg: Should contain register location and length for the
> +       enable register

As I mentioned before, why not all the aux registers (that aren't part
of a sub-device like SPI).

> +Example:
> +
> +aux_enable: aux_enable at 0x7e215004 {
> +	compatible = "bcrm,bcm2835-aux";
> +	reg = <0x7e215004 0x04>;

I'd expect that to be <0x7e215000 0x8>;


From swarren at wwwdotorg.org  Tue Aug 25 18:49:05 2015
From: swarren at wwwdotorg.org (Stephen Warren)
Date: Tue, 25 Aug 2015 19:49:05 -0600
Subject: [PATCH v4 5/5] dt/bindings: bcm2835: Add binding documentation
 for auxiliar spi devices
In-Reply-To: <1440405608-3995-6-git-send-email-kernel@martin.sperl.org>
References: <1440405608-3995-1-git-send-email-kernel@martin.sperl.org>
 <1440405608-3995-6-git-send-email-kernel@martin.sperl.org>
Message-ID: <55DD1B11.30709@wwwdotorg.org>

On 08/24/2015 02:40 AM, kernel at martin.sperl.org wrote:
> From: Martin Sperl <kernel at martin.sperl.org>

Patch description?

> diff --git a/Documentation/devicetree/bindings/spi/brcm,bcm2835-aux-spi.txt b/Documentation/devicetree/bindings/spi/brcm,bcm2835-aux-spi.txt

> +Required properties:
> +- compatible: Should be "brcm,bcm2835-aux-spi".
> +- reg: Should contain register location and length for the spi block
> +       as well as for the common aux block control

Is that meant to imply that reg should contain a single value that
covers both the common aux registers and the SPI device, or two separate
values, one for the aux common registers and another for the SPI device?
Neither of those options sound correct. I would expect only a single
entry which covered solely the SPI registers. The common aux registers
are owned by the other brcm,bcm2835-aux binding.

> +Example:
> +
> +spi1 at 7e215080 {
> +	compatible = "brcm,bcm2835-aux-spi";
> +	reg = <0x7e215080 0x40>;

That seems to match what I'd expect, but doesn't correspond to the
description above.

> +/* the necessary syscon config referenced above*/
> +aux_enable: aux_enable at 0x7e215004 {

It's not a "syscon"...

> +Note that it also requires the GPIOs to be set up with the
> +correct ALT-functions.
> +
> +For spi1 the following pins need to be set as:
> +* ALT4: 19, 20, 21 (MISO, MOSI, SCK)
> +
> +For spi2 the following pins need to be set as:
> +* ALT4: 40, 41, 42 (MISO, MOSI, SCK)
> +
> +CS-GPIOS need to get set as output - typically:
> +* spi1: 18, 17, 16 (CS0, CS1, CS2)
> +* spi2: 43, 44, 45 (CS0, CS1, CS2)

That's generally true of any HW block, and has nothing to do with the
binding for the device. I would suggest removing that chunk of text.



From swarren at wwwdotorg.org  Tue Aug 25 18:52:15 2015
From: swarren at wwwdotorg.org (Stephen Warren)
Date: Tue, 25 Aug 2015 19:52:15 -0600
Subject: [PATCH v4 1/5] soc: bcm2835: auxiliar devices enable
 infrastructure
In-Reply-To: <1440405608-3995-2-git-send-email-kernel@martin.sperl.org>
References: <1440405608-3995-1-git-send-email-kernel@martin.sperl.org>
 <1440405608-3995-2-git-send-email-kernel@martin.sperl.org>
Message-ID: <55DD1BCF.7040200@wwwdotorg.org>

On 08/24/2015 02:40 AM, kernel at martin.sperl.org wrote:
> From: Martin Sperl <kernel at martin.sperl.org>
> 
> The bcm2835 SOC contains 3 auxiliar devices (spi1, spi2 and uart1)
> that all are enabled via a shared register.
> 
> To serialize access to this shared register this soc-driver
> is created that implements:
>   bcm2835aux_enable(struct device *dev, const char *property);
>   bcm2835aux_disable(struct device *dev, const char *property);
> 
> Which will read the property from the device tree of the device
> and enable/disable that specific device as per device tree.
> 
> First use of this api will be spi-bcm2835aux.

> diff --git a/drivers/soc/bcm/bcm2835-aux.c b/drivers/soc/bcm/bcm2835-aux.c

> +static void *bcm2835aux_find_base(struct device *dev, const char *property)
> +{
> +	struct device *found = NULL;
> +	struct device_node *np;
> +
> +	/* get the phandle of the device */
> +	np = of_parse_phandle(dev->of_node, property, 0);
> +	if (!np) {
> +		dev_err(dev, "missing property %s\n", property);
> +		return ERR_PTR(-ENODEV);
> +	}
> +
> +	/* now find the device it points to */
> +	found = driver_find_device(&bcm2835aux_driver.driver, NULL,
> +				   np, bcm2835aux_dev_match);
> +	if (!found) {
> +		dev_err(dev, "device for phandle of %s not found\n",
> +			property);
> +		return ERR_PTR(-ENODEV);

That should return ERR_PTR(-EPROBE_DEFER) so that client drivers know
when to defer their own probe, and not print an error. This is an
expected condition during probing. I could have sworn this was correct
in a previous patch revision.


From swarren at wwwdotorg.org  Tue Aug 25 18:56:31 2015
From: swarren at wwwdotorg.org (Stephen Warren)
Date: Tue, 25 Aug 2015 19:56:31 -0600
Subject: [PATCH v4 4/5] spi: bcm2835: new driver implementing auxiliar
 spi1/spi2 on the bcm2835 soc
In-Reply-To: <1440405608-3995-5-git-send-email-kernel@martin.sperl.org>
References: <1440405608-3995-1-git-send-email-kernel@martin.sperl.org>
 <1440405608-3995-5-git-send-email-kernel@martin.sperl.org>
Message-ID: <55DD1CCF.4080808@wwwdotorg.org>

On 08/24/2015 02:40 AM, kernel at martin.sperl.org wrote:
> From: Martin Sperl <kernel at martin.sperl.org>

Patch description?

>  arch/arm/configs/bcm2835_defconfig |    1 +
>  drivers/spi/Kconfig                |   12 +
>  drivers/spi/Makefile               |    1 +
>  drivers/spi/spi-bcm2835aux.c       |  506 ++++++++++++++++++++++++++++++++++++

A change to the defconfig would be applied by the RPi maintainers, and a
change to drivers/spi by the SPI maintainers. Those need to be in
different patches.

> diff --git a/drivers/spi/spi-bcm2835aux.c b/drivers/spi/spi-bcm2835aux.c

> +static int bcm2835aux_spi_probe(struct platform_device *pdev)

> +	clk_prepare_enable(bs->clk);

Error checking?

> +	/* enable HW block */
> +	bcm2835aux_enable(&pdev->dev, ENABLE_PROPERTY);

The return value needs to be error-checked, so that deferred probe can
work, and so other kinds of errors can be detected. Wasn't this correct
in a previous patch version?

Note that I didn't review any code besides probe(), remove() and the
driver boiler-plate that refers to those functions.



From Suravee.Suthikulpanit at amd.com  Tue Aug 25 19:00:23 2015
From: Suravee.Suthikulpanit at amd.com (Suravee Suthikulpanit)
Date: Wed, 26 Aug 2015 09:00:23 +0700
Subject: [PATCH V2 2/4] ACPI/scan: Clean up acpi_check_dma
In-Reply-To: <1659571.paO1iYcMuM@vostro.rjw.lan>
References: <1440524009-5359-1-git-send-email-Suravee.Suthikulpanit@amd.com>
 <1440524009-5359-3-git-send-email-Suravee.Suthikulpanit@amd.com>
 <1659571.paO1iYcMuM@vostro.rjw.lan>
Message-ID: <55DD1DB7.1020203@amd.com>

Hi Rafael,

On 8/26/15 06:48, Rafael J. Wysocki wrote:

>[...]
> On Wednesday, August 26, 2015 12:33:27 AM Suravee Suthikulpanit wrote:
>> diff --git a/drivers/acpi/glue.c b/drivers/acpi/glue.c
>> index b9657af..55cf916 100644
>> --- a/drivers/acpi/glue.c
>> +++ b/drivers/acpi/glue.c
>> @@ -168,7 +168,7 @@ int acpi_bind_one(struct device *dev, struct acpi_device *acpi_dev)
>>   	struct list_head *physnode_list;
>>   	unsigned int node_id;
>>   	int retval = -EINVAL;
>> -	bool coherent;
>> +	int coherent;
>
> enum, anyone?  With clearly defined values?

Originally I had defined

enum acpi_dma_coherency {
	ACPI_DMA_NON_COHERENT,
	ACPI_DMA_COHERENT,
	APCI_DMA_NOT_SUPPORTED = -1,
};

Although, this would need to be defined in the include/linux/acpi.h, and 
will be used also for #ifndef CONFIG_ACPI code to return errors. I was 
not sure if this would be too much. If this is preferred, I'll add this 
back in.

>>
>>   	if (has_acpi_companion(dev)) {
>>   		if (acpi_dev) {
>> @@ -225,7 +225,8 @@ int acpi_bind_one(struct device *dev, struct acpi_device *acpi_dev)
>>   	if (!has_acpi_companion(dev))
>>   		ACPI_COMPANION_SET(dev, acpi_dev);
>>
>> -	if (acpi_check_dma(acpi_dev, &coherent))
>> +	coherent = acpi_check_dma_coherency(acpi_dev);
>> +	if (coherent != -1)
>
> Like here I'm not sure why -1 is special?

It's just another value to communicate that DMA is not supported. :)

Thanks,
Suravee
>
>>   		arch_setup_dma_ops(dev, 0, 0, NULL, coherent);
>>
>>   	acpi_physnode_link_name(physical_node_name, node_id);
>
> Thanks,
> Rafael
>


From Suravee.Suthikulpanit at amd.com  Tue Aug 25 19:01:58 2015
From: Suravee.Suthikulpanit at amd.com (Suravee Suthikulpanit)
Date: Wed, 26 Aug 2015 09:01:58 +0700
Subject: [PATCH V2 4/4] PCI: ACPI: Add support for PCI device DMA coherency
In-Reply-To: <5541922.5doADRYBJG@vostro.rjw.lan>
References: <1440524009-5359-1-git-send-email-Suravee.Suthikulpanit@amd.com>
 <1440524009-5359-5-git-send-email-Suravee.Suthikulpanit@amd.com>
 <5541922.5doADRYBJG@vostro.rjw.lan>
Message-ID: <55DD1E16.40607@amd.com>

Hi Rafael,

On 8/26/15 06:48, Rafael J. Wysocki wrote:
> On Wednesday, August 26, 2015 12:33:29 AM Suravee Suthikulpanit wrote:
>> This patch adds support for setting up PCI device DMA coherency from
>> ACPI _CCA object that should normally be specified in the DSDT node
>> of its PCI host bridge.
>>
>> Signed-off-by: Suravee Suthikulpanit <Suravee.Suthikulpanit at amd.com>
>> CC: Bjorn Helgaas <bhelgaas at google.com>
>> CC: Catalin Marinas <catalin.marinas at arm.com>
>> CC: Rob Herring <robh+dt at kernel.org>
>> CC: Will Deacon <will.deacon at arm.com>
>> CC: Rafael J. Wysocki <rjw at rjwysocki.net>
>> CC: Murali Karicheri <m-karicheri2 at ti.com>
>> ---
>>   drivers/pci/probe.c | 15 ++++++++++-----
>>   1 file changed, 10 insertions(+), 5 deletions(-)
>>
>> diff --git a/drivers/pci/probe.c b/drivers/pci/probe.c
>> index 4de6594..2fd2a60 100644
>> --- a/drivers/pci/probe.c
>> +++ b/drivers/pci/probe.c
>> @@ -1551,17 +1551,22 @@ static void pci_init_capabilities(struct pci_dev *dev)
>>    * @dev: ptr to pci_dev struct of the PCI device
>>    *
>>    * Function to update PCI devices's DMA configuration using the same
>> - * info from the OF node of host bridge's parent (if any).
>> + * info from the OF node or ACPI node of host bridge's parent (if any).
>>    */
>>   static void pci_dma_configure(struct pci_dev *dev)
>>   {
>>   	struct device *bridge = pci_get_host_bridge_device(dev);
>>
>>   	if (IS_ENABLED(CONFIG_OF) && dev->dev.of_node) {
>> -		if (!bridge->parent)
>> -			return;
>> -
>> -		of_dma_configure(&dev->dev, bridge->parent->of_node);
>> +		if (bridge->parent)
>> +			of_dma_configure(&dev->dev,
>> +					 bridge->parent->of_node);
>> +	} else if (has_acpi_companion(bridge)) {
>> +		struct acpi_device *adev = to_acpi_node(bridge->fwnode);
>> +		int coherent = acpi_check_dma_coherency(adev);
>> +
>> +		if (-1 != coherent)
>
> The ordering of this check is somewhat unusual.

I'll fix this.

Thanks,
Suravee


From swarren at wwwdotorg.org  Tue Aug 25 19:02:59 2015
From: swarren at wwwdotorg.org (Stephen Warren)
Date: Tue, 25 Aug 2015 20:02:59 -0600
Subject: [PATCH v2 6/7] ARM: bcm2835: Add the DDC I2C controller to the
 device tree.
In-Reply-To: <1439934848-7196-7-git-send-email-eric@anholt.net>
References: <1439934848-7196-1-git-send-email-eric@anholt.net>
 <1439934848-7196-7-git-send-email-eric@anholt.net>
Message-ID: <55DD1E53.1050608@wwwdotorg.org>

On 08/18/2015 03:54 PM, Eric Anholt wrote:
> We need to use it for getting video modes over HDMI.

This patch,
Acked-by: Stephen Warren <swarren at wwwdotorg.org>


From swarren at wwwdotorg.org  Tue Aug 25 19:04:36 2015
From: swarren at wwwdotorg.org (Stephen Warren)
Date: Tue, 25 Aug 2015 20:04:36 -0600
Subject: [PATCH v2 7/7] ARM: bcm2835: Add VC4 to the device tree.
In-Reply-To: <1439934848-7196-8-git-send-email-eric@anholt.net>
References: <1439934848-7196-1-git-send-email-eric@anholt.net>
 <1439934848-7196-8-git-send-email-eric@anholt.net>
Message-ID: <55DD1EB4.9000401@wwwdotorg.org>

On 08/18/2015 03:54 PM, Eric Anholt wrote:
> VC4 is the GPU (display and 3D) present on the 2835.

This patch and patch 1 seem OK to me, although I'll withhold any ack
until the DT binding design discussion with Rob has been resolved. I
haven't looked at the OF graph bindings he mentioned so have no clue
about his suggestions.


From rjw at rjwysocki.net  Tue Aug 25 19:44:20 2015
From: rjw at rjwysocki.net (Rafael J. Wysocki)
Date: Wed, 26 Aug 2015 04:44:20 +0200
Subject: [PATCH V2 2/4] ACPI/scan: Clean up acpi_check_dma
In-Reply-To: <55DD1DB7.1020203@amd.com>
References: <1440524009-5359-1-git-send-email-Suravee.Suthikulpanit@amd.com>
 <1659571.paO1iYcMuM@vostro.rjw.lan> <55DD1DB7.1020203@amd.com>
Message-ID: <1937405.90E8lxrvy8@vostro.rjw.lan>

On Wednesday, August 26, 2015 09:00:23 AM Suravee Suthikulpanit wrote:
> Hi Rafael,
> 
> On 8/26/15 06:48, Rafael J. Wysocki wrote:
> 
> >[...]
> > On Wednesday, August 26, 2015 12:33:27 AM Suravee Suthikulpanit wrote:
> >> diff --git a/drivers/acpi/glue.c b/drivers/acpi/glue.c
> >> index b9657af..55cf916 100644
> >> --- a/drivers/acpi/glue.c
> >> +++ b/drivers/acpi/glue.c
> >> @@ -168,7 +168,7 @@ int acpi_bind_one(struct device *dev, struct acpi_device *acpi_dev)
> >>   	struct list_head *physnode_list;
> >>   	unsigned int node_id;
> >>   	int retval = -EINVAL;
> >> -	bool coherent;
> >> +	int coherent;
> >
> > enum, anyone?  With clearly defined values?
> 
> Originally I had defined
> 
> enum acpi_dma_coherency {
> 	ACPI_DMA_NON_COHERENT,
> 	ACPI_DMA_COHERENT,
> 	APCI_DMA_NOT_SUPPORTED = -1,
> };
> 
> Although, this would need to be defined in the include/linux/acpi.h, and 
> will be used also for #ifndef CONFIG_ACPI code to return errors. I was 
> not sure if this would be too much. If this is preferred, I'll add this 
> back in.
> 
> >>
> >>   	if (has_acpi_companion(dev)) {
> >>   		if (acpi_dev) {
> >> @@ -225,7 +225,8 @@ int acpi_bind_one(struct device *dev, struct acpi_device *acpi_dev)
> >>   	if (!has_acpi_companion(dev))
> >>   		ACPI_COMPANION_SET(dev, acpi_dev);
> >>
> >> -	if (acpi_check_dma(acpi_dev, &coherent))
> >> +	coherent = acpi_check_dma_coherency(acpi_dev);
> >> +	if (coherent != -1)
> >
> > Like here I'm not sure why -1 is special?
> 
> It's just another value to communicate that DMA is not supported. :)

OK

So maybe use 0/1 for the coherence thing and a proper error code
(-ENOTSUPP seems to be a good candidate) for the "no DMA" case?

Then, if you rename the local variable to something like "ret",
it will be slightly less confusing.

And instead of checking against a specific negative value, you can
simply use "if (stuff < 0)" or "if (stuff >= 0)" to check whether or
not it is supported at all.

Thanks,
Rafael



From viresh.kumar at linaro.org  Tue Aug 25 19:16:59 2015
From: viresh.kumar at linaro.org (Viresh Kumar)
Date: Wed, 26 Aug 2015 07:46:59 +0530
Subject: [RESEND PATCH 0/3 v6] Add Mediatek MT8173 cpufreq driver
In-Reply-To: <CALx668UvkYhLoU8rxLG70RqTzsnaiV5-ybDYTKqb4MEJS8pmRw@mail.gmail.com>
References: <1439803465-19683-1-git-send-email-pi-cheng.chen@linaro.org>
 <CALx668VWg2xVxzy8P7f5QFWRzm+TDJXUghL-_rbvRLsLYjtnng@mail.gmail.com>
 <1617873.VRHfat3V76@vostro.rjw.lan>
 <CALx668UvkYhLoU8rxLG70RqTzsnaiV5-ybDYTKqb4MEJS8pmRw@mail.gmail.com>
Message-ID: <20150826021659.GD8784@linux>

On 26-08-15, 09:25, Pi-Cheng Chen wrote:
> The [3/3] is based on Mediatek SoC maintainer tree[1] and the patch which
> introduce a new clock type[2] consumed by MT8173 cpufreq driver. So it will
> cause some conflicts if it goes through your tree. I am not sure how this
> should be handled, but should it be merged through Mediatek SoC maintainer
> tree?

Just get that applied to MTK tree, it doesn't have any dependency on
rest of the patches for build/boot. The only thing is that cpufreq
wouldn't work and it will work as soon as Rafael's and MTK's trees are
merged by Linus.

-- 
viresh


From shengjiu.wang at freescale.com  Tue Aug 25 18:19:24 2015
From: shengjiu.wang at freescale.com (Shengjiu Wang)
Date: Wed, 26 Aug 2015 09:19:24 +0800
Subject: [PATCH V1 0/3] fix clock issue for fsl,spdif
In-Reply-To: <20150825184527.31346.52324@quantum>
References: <cover.1439284957.git.shengjiu.wang@freescale.com>
 <20150825184527.31346.52324@quantum>
Message-ID: <20150826011922.GA9708@shlinux2>

On Tue, Aug 25, 2015 at 11:45:27AM -0700, Michael Turquette wrote:
> Quoting Shengjiu Wang (2015-08-11 02:26:51)
> > fix clock issue for fsl,spdif
> > 
> > Shengjiu Wang (3):
> >   ARM: imx6q: Add SPDIF_GCLK clock in clock tree
> >   ARM: imx6sl: Add SPDIF_GCLK clock in clock tree
> >   ARM: imx6sx: Add SPDIF_GCLK clock in clock tree
> 
> Hello Shengjiu Wang,
> 
> Please move the dts changes into separate patches. I can take the
> changes to the clock driver and the header through the clk tree, but the
> dt patches need to go through arm-soc.
> 
> Regards,
> Mike

Thanks Mike. I will send another patches for dts changes.

> 
> > 
> >  arch/arm/boot/dts/imx6qdl.dtsi            |  2 +-
> >  arch/arm/boot/dts/imx6sl.dtsi             | 16 ++++++++++++++++
> >  arch/arm/boot/dts/imx6sx.dtsi             |  2 +-
> >  drivers/clk/imx/clk-imx6q.c               |  4 +++-
> >  drivers/clk/imx/clk-imx6sl.c              |  4 +++-
> >  drivers/clk/imx/clk-imx6sx.c              |  1 +
> >  include/dt-bindings/clock/imx6qdl-clock.h |  3 ++-
> >  include/dt-bindings/clock/imx6sl-clock.h  |  3 ++-
> >  include/dt-bindings/clock/imx6sx-clock.h  |  3 ++-
> >  9 files changed, 31 insertions(+), 7 deletions(-)
> > 
> > -- 
> > 1.9.1
> > 
> > --
> > To unsubscribe from this list: send the line "unsubscribe linux-kernel" in
> > the body of a message to majordomo at vger.kernel.org
> > More majordomo info at  http://vger.kernel.org/majordomo-info.html
> > Please read the FAQ at  http://www.tux.org/lkml/


From Suravee.Suthikulpanit at amd.com  Tue Aug 25 19:36:28 2015
From: Suravee.Suthikulpanit at amd.com (Suravee Suthikulpanit)
Date: Wed, 26 Aug 2015 09:36:28 +0700
Subject: [PATCH V2 0/4] PCI: ACPI: Setting up DMA coherency for PCI device
 from _CCA attribute
In-Reply-To: <240091906.Gl2z931jjW@wuerfel>
References: <1440524009-5359-1-git-send-email-Suravee.Suthikulpanit@amd.com>
 <240091906.Gl2z931jjW@wuerfel>
Message-ID: <55DD262C.3010008@amd.com>

Hi Arnd,

On 8/26/15 01:48, Arnd Bergmann wrote:
> On Wednesday 26 August 2015 00:33:25 Suravee Suthikulpanit wrote:
>> This patch adds support to setup DMA coherency for PCI device using
>> the ACPI _CCA attribute. According to the ACPI spec, the _CCA attribute
>> is required for ARM64. Therefore, this patch is a pre-req for ACPI PCI
>> support for ARM64 which is currently in development.
>>
>> Also, this should not affect other architectures that does not define
>> CONFIG_ACPI_CCA_REQUIRED, since the default value is coherent.
>>
>
> We only support ACPI on SBSA compliant platforms, and SBSA mandates
> cache-coherent PCI, so I don't think this is actually needed,
> just use coherent all the time and do WARN_ON(!CCA) to catch people
> that try to incorrectly use ACPI on a non-SBSA platform.
>
> 	Arnd

Thanks for pointing out. The CONFIG_ACPI_CCA_REQUIRED is already existed 
and selected in arch/arm64/Kconfig, and used for both PCI and non-PCI 
devices. I am not adding anything specific for the PCI case.

Although, I think WARN_ON(!CCA) when it is required is a good idea. I'll 
find a proper place for it.

Thanks,
Suravee.

> --
> To unsubscribe from this list: send the line "unsubscribe linux-acpi" in
> the body of a message to majordomo at vger.kernel.org
> More majordomo info at  http://vger.kernel.org/majordomo-info.html
>


From haojian.zhuang at linaro.org  Tue Aug 25 19:41:52 2015
From: haojian.zhuang at linaro.org (Haojian Zhuang)
Date: Wed, 26 Aug 2015 10:41:52 +0800
Subject: [PATCH v1 3/3] arm64: dts: add Hi6220 mailbox node
In-Reply-To: <20150825153754.GY10728@bivouac.eciton.net>
References: <20150824095144.GA7139@leverpostej>
 <1440411596.3517.12.camel@linaro.org>
 <20150824114903.GT10728@bivouac.eciton.net>
 <1440490427.10987.29.camel@linaro.org>
 <20150825094630.GU10728@bivouac.eciton.net>
 <1440497710.10987.42.camel@linaro.org> <20150825104256.GB13471@leverpostej>
 <1440510194.10987.52.camel@linaro.org>
 <20150825142416.GW10728@bivouac.eciton.net>
 <CAKv+Gu-b=QvMF++V9UjULRxrGvoz-0ytFLeuLm8Y5sQH4p53Sw@mail.gmail.com>
 <20150825153754.GY10728@bivouac.eciton.net>
Message-ID: <1440556912.10987.54.camel@linaro.org>

On Tue, 2015-08-25 at 16:37 +0100, Leif Lindholm wrote:
> On Tue, Aug 25, 2015 at 04:51:22PM +0200, Ard Biesheuvel wrote:
> > >>    Arm kernel should either fetch memory information from
> > >>    efi or DT.
> > >
> > > Absolutely.
> > >
> > >>    Currently arm kernel fetch both efi memory information and
> > >>    reserved buffer from DTB at the same time.
> > >
> > > No, it does not.
> > 
> > It should not, but it does. Due to an oversight, the stub removes
> > /memreserve/ entries but ignores the reserved-memory node completely.
> 
> Urgh.
> 
> > This was reported here in fact
> > 
> > http://thread.gmane.org/gmane.linux.kernel.efi/5736/focus=5742
> > 
> > but there has not been a followup to this series.
> 
> Are all of those patches still relevant, or did some of them go in
> already?
> 
> Haojian: can you give that patch a spin and see if it does what you
> need, combined with adding the reserved areas to the UEFI memory map?
> 
> /
>     Leif

It's so nice. This patch is what I need.

Thanks
Haojian



From chunyan.zhang at spreadtrum.com  Tue Aug 25 19:40:41 2015
From: chunyan.zhang at spreadtrum.com (Chunyan Zhang)
Date: Wed, 26 Aug 2015 10:40:41 +0800
Subject: [PATCH] arm64: fix bug for reloading FPSIMD state after execve on cpu
 0.
Message-ID: <1440556841-17219-1-git-send-email-chunyan.zhang@spreadtrum.com>

From: Janet Liu <janet.liu at spreadtrum.com>

If process A is running on CPU 0 and do execve syscall and after sched_exec,
dest_cpu is 0, fpsimd_state.cpu is 0. If at the time Process A get scheduled
out and after some kernel threads running on CPU 0, process A is back in CPU 0,
A's fpsimd_state.cpu is current cpu id "0", and per_cpu(fpsimd_last_state)
points A's fpsimd_state, TIF_FOREIGN_FPSTATE will be clear, kernel will not
reload the context during it return to userspace. so set the cpu's
fpsimd_last_state to NULL to avoid this.

Signed-off-by: Janet Liu <janet.liu at spreadtrum.com>
Signed-off-by: Chunyan Zhang <chunyan.zhang at spreadtrum.com>
---
 arch/arm64/kernel/fpsimd.c |    1 +
 1 file changed, 1 insertion(+)

diff --git a/arch/arm64/kernel/fpsimd.c b/arch/arm64/kernel/fpsimd.c
index 44d6f75..ec58d94 100644
--- a/arch/arm64/kernel/fpsimd.c
+++ b/arch/arm64/kernel/fpsimd.c
@@ -159,6 +159,7 @@ void fpsimd_flush_thread(void)
 {
 	memset(&current->thread.fpsimd_state, 0, sizeof(struct fpsimd_state));
 	set_thread_flag(TIF_FOREIGN_FPSTATE);
+	this_cpu_write(fpsimd_last_state, NULL);
 }
 
 /*
-- 
1.7.9.5



From zhengxing at rock-chips.com  Tue Aug 25 20:20:44 2015
From: zhengxing at rock-chips.com (Xing Zheng)
Date: Wed, 26 Aug 2015 11:20:44 +0800
Subject: [PATCH v2] ASoC: rockchip: fix a misjudgement by return
Message-ID: <1440559244-17634-1-git-send-email-zhengxing@rock-chips.com>

Being careless, judge the return value of snd_soc_card_jack_new
is opposite, so it should be fixed.

---

Changes in v2:
Signed-off-by: Xing Zheng <zhengxing at rock-chips.com>
Reviewed-by: Dylan Reid <dgreid at chromium.org>

 sound/soc/rockchip/rockchip_rt5645.c |    2 +-
 1 file changed, 1 insertion(+), 1 deletion(-)

diff --git a/sound/soc/rockchip/rockchip_rt5645.c b/sound/soc/rockchip/rockchip_rt5645.c
index 3c6bb1e..adfe98c 100644
--- a/sound/soc/rockchip/rockchip_rt5645.c
+++ b/sound/soc/rockchip/rockchip_rt5645.c
@@ -118,7 +118,7 @@ static int rk_init(struct snd_soc_pcm_runtime *runtime)
 				    SND_JACK_BTN_0 | SND_JACK_BTN_1 |
 				    SND_JACK_BTN_2 | SND_JACK_BTN_3,
 				    &headset_jack, NULL, 0);
-	if (!ret) {
+	if (ret) {
 		dev_err(card->dev, "New Headset Jack failed! (%d)\n", ret);
 		return ret;
 	}
-- 
1.7.9.5




From bjorn.andersson at sonymobile.com  Tue Aug 25 20:46:22 2015
From: bjorn.andersson at sonymobile.com (Bjorn Andersson)
Date: Tue, 25 Aug 2015 20:46:22 -0700
Subject: [PATCH] soc: qcom: smd: Use correct remote processor ID
In-Reply-To: <1440534995-12899-1-git-send-email-agross@codeaurora.org>
References: <1440534995-12899-1-git-send-email-agross@codeaurora.org>
Message-ID: <20150826034622.GH13472@usrtlx11787.corpusers.net>

On Tue 25 Aug 13:36 PDT 2015, Andy Gross wrote:

> This patch fixes SMEM addressing issues when remote processors need to use
> secure SMEM partitions.
> 

Right, sorry for missing that remote_pid and edge_pid isn't in sync...

> Signed-off-by: Andy Gross <agross at codeaurora.org>
> ---
>  .../devicetree/bindings/soc/qcom/qcom,smd.txt      |    7 +++++++
>  drivers/soc/qcom/smd.c                             |   18 ++++++++++++++----
>  2 files changed, 21 insertions(+), 4 deletions(-)
> 
> diff --git a/Documentation/devicetree/bindings/soc/qcom/qcom,smd.txt b/Documentation/devicetree/bindings/soc/qcom/qcom,smd.txt
> index f65c76d..3b60702 100644
> --- a/Documentation/devicetree/bindings/soc/qcom/qcom,smd.txt
> +++ b/Documentation/devicetree/bindings/soc/qcom/qcom,smd.txt
> @@ -37,6 +37,12 @@ The edge is described by the following properties:
>  	Definition: the identifier of the remote processor in the smd channel
>  		    allocation table
>  
> +- qcom,remote-pid:
> +	Usage: required

I would like to see this being optional, as this is not a property that
matters on any of the 32-bit systems (perhaps 8084?).

> +	Value type: <u32>
> +	Definition: the identifier for the remote processor as known by the rest
> +		    of the system.
> +
>  = SMD DEVICES
>  
>  In turn, subnodes of the "edges" represent devices tied to SMD channels on that
> @@ -68,6 +74,7 @@ The following example represents a smd node, with one edge representing the
>  			interrupts = <0 168 1>;
>  			qcom,ipc = <&apcs 8 0>;
>  			qcom,smd-edge = <15>;
> +			qcom,remote-pid = <0xffffffff>;

This looks messy, so let's make the property optional and make its
absence indicate the "global partition".

>  
>  			rpm_requests {
>  				compatible = "qcom,rpm-msm8974";
> diff --git a/drivers/soc/qcom/smd.c b/drivers/soc/qcom/smd.c
[..]
> @@ -1184,6 +1187,13 @@ static int qcom_smd_parse_edge(struct device *dev,
>  		return -EINVAL;
>  	}
>  
> +	key = "qcom,remote-pid";
> +	ret = of_property_read_u32(node, key, &edge->remote_pid);
> +	if (ret) {
> +		dev_err(dev, "edge missing %s property\n", key);
> +		return -EINVAL;
> +	}
> +

So I suggest you changing this to:

edge->remote_pid = QCOM_SMEM_HOST_ANY;
of_property_read_u32(node, "qcom,remote-pid", &edge->remote_pid);

>  	syscon_np = of_parse_phandle(node, "qcom,ipc", 0);
>  	if (!syscon_np) {
>  		dev_err(dev, "no qcom,ipc node\n");

Regards,
Bjorn


From gkulkarni at caviumnetworks.com  Tue Aug 25 21:52:39 2015
From: gkulkarni at caviumnetworks.com (Ganapatrao Kulkarni)
Date: Wed, 26 Aug 2015 10:22:39 +0530
Subject: [PATCH v2 RESEND] irqchip, gicv3-its,
 numa: Workaround for Cavium ThunderX erratum 23144
Message-ID: <1440564759-3786-1-git-send-email-gkulkarni@caviumnetworks.com>

This implements a workaround for gicv3-its erratum 23144 on Cavium's
ThunderX dual-socket platforms, where LPI cannot be routed to a
redistributors present on a foreign node.

Signed-off-by: Ganapatrao Kulkarni <gkulkarni at caviumnetworks.com>
Signed-off-by: Robert Richter <rrichter at cavium.com>
---

The patch below is on top of Robert's recent gicv3 errata patch
submission v4 and my arm64 numa patches v5.

v2:
updatated as per Marc Zyngier's review comments.

 drivers/irqchip/irq-gic-v3-its.c | 49 ++++++++++++++++++++++++++++++++++------
 1 file changed, 42 insertions(+), 7 deletions(-)

diff --git a/drivers/irqchip/irq-gic-v3-its.c b/drivers/irqchip/irq-gic-v3-its.c
index b83b132..47fded0 100644
--- a/drivers/irqchip/irq-gic-v3-its.c
+++ b/drivers/irqchip/irq-gic-v3-its.c
@@ -39,7 +39,8 @@
 #include "irqchip.h"
 
 #define ITS_FLAGS_CMDQ_NEEDS_FLUSHING		(1ULL << 0)
-#define ITS_FLAGS_CAVIUM_THUNDERX		(1ULL << 1)
+#define ITS_WORKAROUND_CAVIUM_22375            (1ULL << 1)
+#define ITS_WORKAROUND_CAVIUM_23144            (1ULL << 2)
 
 #define RDIST_FLAGS_PROPBASE_NEEDS_FLUSHING	(1 << 0)
 
@@ -72,6 +73,7 @@ struct its_node {
 	struct list_head	its_device_list;
 	u64			flags;
 	u32			ite_size;
+	int			numa_node;
 };
 
 #define ITS_ITT_ALIGN		SZ_256
@@ -606,11 +608,20 @@ static void its_eoi_irq(struct irq_data *d)
 static int its_set_affinity(struct irq_data *d, const struct cpumask *mask_val,
 			    bool force)
 {
-	unsigned int cpu = cpumask_any_and(mask_val, cpu_online_mask);
+	unsigned int cpu;
+	const struct cpumask *cpu_mask = cpu_online_mask;
 	struct its_device *its_dev = irq_data_get_irq_chip_data(d);
 	struct its_collection *target_col;
 	u32 id = its_get_event_id(d);
 
+	/* lpi cannot be routed to a redistributor that is on a foreign node */
+	if (its_dev->its->flags & ITS_WORKAROUND_CAVIUM_23144) {
+		cpu_mask = cpumask_of_node(its_dev->its->numa_node);
+		if (!cpumask_intersects(mask_val, cpu_mask))
+			return -EINVAL;
+	}
+
+	cpu = cpumask_any_and(mask_val, cpu_mask);
 	if (cpu >= nr_cpu_ids)
 		return -EINVAL;
 
@@ -842,7 +853,7 @@ static int its_alloc_tables(struct its_node *its)
 	u64 typer;
 	u32 ids;
 
-	if (its->flags & ITS_FLAGS_CAVIUM_THUNDERX) {
+	if (its->flags & ITS_WORKAROUND_CAVIUM_22375) {
 		/*
 		 * erratum 22375: only alloc 8MB table size
 		 * erratum 24313: ignore memory access type
@@ -1349,9 +1360,14 @@ static void its_irq_domain_activate(struct irq_domain *domain,
 {
 	struct its_device *its_dev = irq_data_get_irq_chip_data(d);
 	u32 event = its_get_event_id(d);
+	const struct cpumask *cpu_mask = cpu_online_mask;
+
+	/* get the cpu_mask of local node */
+	if (IS_ENABLED(CONFIG_NUMA))
+		cpu_mask = cpumask_of_node(its_dev->its->numa_node);
 
 	/* Bind the LPI to the first possible CPU */
-	its_dev->event_map.col_map[event] = cpumask_first(cpu_online_mask);
+	its_dev->event_map.col_map[event] = cpumask_first(cpu_mask);
 
 	/* Map the GIC IRQ and event to the device */
 	its_send_mapvi(its_dev, d->hwirq, event);
@@ -1434,11 +1450,19 @@ static int its_force_quiescent(void __iomem *base)
 	}
 }
 
-static void its_enable_cavium_thunderx(void *data)
+static void its_enable_cavium_thunderx_22375(void *data)
 {
 	struct its_node *its = data;
 
-	its->flags |= ITS_FLAGS_CAVIUM_THUNDERX;
+	its->flags |= ITS_WORKAROUND_CAVIUM_22375;
+}
+
+static void its_enable_cavium_thunderx_23144(void *data)
+{
+	struct its_node *its = data;
+
+	if (num_possible_nodes() > 1)
+		its->flags |= ITS_WORKAROUND_CAVIUM_23144;
 }
 
 static const struct gic_capabilities its_errata[] = {
@@ -1446,7 +1470,13 @@ static const struct gic_capabilities its_errata[] = {
 		.desc	= "ITS: Cavium errata 22375, 24313",
 		.iidr	= 0xa100034c,	/* ThunderX pass 1.x */
 		.mask	= 0xffff0fff,
-		.init	= its_enable_cavium_thunderx,
+		.init	= its_enable_cavium_thunderx_22375,
+	},
+	{
+		.desc	= "ITS: Cavium errata 23144",
+		.iidr	= 0xa100034c,	/* ThunderX pass 1.x */
+		.mask	= 0xffff0fff,
+		.init	= its_enable_cavium_thunderx_23144,
 	},
 	{
 	}
@@ -1465,6 +1495,7 @@ static int its_probe(struct device_node *node, struct irq_domain *parent)
 	u32 val;
 	u64 baser, tmp;
 	int err;
+	int numa_node;
 
 	err = of_address_to_resource(node, 0, &res);
 	if (err) {
@@ -1472,6 +1503,9 @@ static int its_probe(struct device_node *node, struct irq_domain *parent)
 		return -ENXIO;
 	}
 
+	/* get numa affinity of its node*/
+	numa_node = of_node_to_nid(node);
+
 	its_base = ioremap(res.start, resource_size(&res));
 	if (!its_base) {
 		pr_warn("%s: unable to map registers\n", node->full_name);
@@ -1507,6 +1541,7 @@ static int its_probe(struct device_node *node, struct irq_domain *parent)
 	its->phys_base = res.start;
 	its->msi_chip.of_node = node;
 	its->ite_size = ((readl_relaxed(its_base + GITS_TYPER) >> 4) & 0xf) + 1;
+	its->numa_node = numa_node;
 
 	its->cmd_base = kzalloc(ITS_CMD_QUEUE_SZ, GFP_KERNEL);
 	if (!its->cmd_base) {
-- 
1.8.1.4



From varada at codeaurora.org  Tue Aug 25 22:39:50 2015
From: varada at codeaurora.org (Varadarajan Narayanan)
Date: Wed, 26 Aug 2015 11:09:50 +0530
Subject: [PATCH v3] qcom: ipq40xx: Add basic board/dts support for
 IPQ40XX SoC
In-Reply-To: <20150825211405.GJ19120@codeaurora.org>
References: <20150824092813.GA15581@codeaurora.org>
 <20150824224928.GE14330@codeaurora.org>
 <20150825081042.GA14028@codeaurora.org>
 <20150825211405.GJ19120@codeaurora.org>
Message-ID: <20150826053950.GB25312@codeaurora.org>

On Tue, Aug 25, 2015 at 02:14:05PM -0700, Stephen Boyd wrote:
> On 08/25, Varadarajan Narayanan wrote:
> > On Mon, Aug 24, 2015 at 03:49:28PM -0700, Stephen Boyd wrote:
> > > On 08/24, Varadarajan Narayanan wrote:
> >
> > > > +	compatible = "qcom,ipq40xx-r3pc", "qcom,ipq40xx";
> > > > +
> > > > +	memory {
> > > > +		device_type = "memory";
> > > > +		reg = <0x80000000 0x20000000>; /* 512MB */
> > > > +	};
> > >
> > > Doesn't the bootloader fill the memory node for us? Why do we
> > > need this?
> > >
> > > > +
> > > > +	chosen {
> > > > +		bootargs = "root=/dev/ram rw init=/init console=ttyMSM0,115200n8 initrd=0x82000000,0x000E2246";
> > > > +	};
> > >
> > > Please don't add bootargs. Use stdout-path for the console part
> > > and everything else should be done by the bootloader or is the
> > > defaults.
> >
> > Since this is for the emulation platform, we don't have the bootloader.
>
> Why are we upstreaming an emulation platform?

Ok, will skip this.

-Varada

> I assume you have some sort of scripts or something to load the
> kernel image into the emulator, so those scripts could go and
> modify the dtb in place to populate the initrd and commandline.
> If you need pointers on that feel free to contact me directly.
>
> >
> > > > +			compatible = "arm,armv7-timer";
> > > > +			interrupts = <1 2 0xf08>,
> > > > +				     <1 3 0xf08>,
> > > > +				     <1 4 0xf08>,
> > > > +				     <1 1 0xf08>;
> > > > +			clock-frequency = <20833333>;
> > >
> > > Drop this clock-frequency part if you can. The hardware should
> > > properly report the frequency.
> >
> > Cannot drop this. This is the ref-clock frequency. For the
> > chip it is 48MHz, for emulation is ~20MHz. Similar to
> > https://git.kernel.org/cgit/linux/kernel/git/torvalds/linux.git/tree/arch/arm/boot/dts/qcom-msm8974.dtsi#n89
>
> And the hardware is not emulated properly to report the actual
> frequency that the timer is running at? That's sad.
>
> At the least, this should be in the board specific dtsi file
> instead of the SoC specific file, because it's a board quirk.
>
> --
> Qualcomm Innovation Center, Inc. is a member of Code Aurora Forum,
> a Linux Foundation Collaborative Project


From yong.wu at mediatek.com  Tue Aug 25 23:19:26 2015
From: yong.wu at mediatek.com (Yong Wu)
Date: Wed, 26 Aug 2015 14:19:26 +0800
Subject: [PATCH v5 0/3] arm64: IOMMU-backed DMA mapping
In-Reply-To: <cover.1438362603.git.robin.murphy@arm.com>
References: <cover.1438362603.git.robin.murphy@arm.com>
Message-ID: <1440569966.25782.3.camel@mhfsdcap03>

On Fri, 2015-07-31 at 18:18 +0100, Robin Murphy wrote:
> Hi all,
> 
> Here's an update following Catalin's feedback on v4[1].
> 
> Changes this round:
> - Rebased onto linux-next
>   - IOVA alignment fix applied already
>   - iommu_iova_cache_init() is now iova_cache_get()
> - Tidied up iommu_dma_alloc()
>   - Simplified pgprot handling
>   - Removed redundant memset
>   - Skip coherent page-flushing in a simpler way
> - Spotted a bug in iommu_dma_init_domain() where the checks for
>   reinitialising an existing domain were backwards.
> 
> If it is going to be down to me to tackle all the driver fixes and
> conversion of arch/arm dma_ops, I'd still much rather have this
> code merged first as a stable base to work with (and un-block arm64
> in the meantime). Have we decided yet whether this should go via the
> IOMMU tree or the arm64 tree?

Hi Robin,
   Sorry to disturb you. Is there any plan for the next version of arm64
DMA. If it's yes, when could we get it?
   Thanks very much.

> 
> Thanks,
> Robin.
> 
> [1]:http://thread.gmane.org/gmane.linux.kernel.iommu/10181
> 
> Robin Murphy (3):
>   iommu: Implement common IOMMU ops for DMA mapping
>   arm64: Add IOMMU dma_ops
>   arm64: Hook up IOMMU dma_ops
> 
>  arch/arm64/Kconfig                   |   1 +
>  arch/arm64/include/asm/dma-mapping.h |  15 +-
>  arch/arm64/mm/dma-mapping.c          | 449 +++++++++++++++++++++++++++++
>  drivers/iommu/Kconfig                |   7 +
>  drivers/iommu/Makefile               |   1 +
>  drivers/iommu/dma-iommu.c            | 534 +++++++++++++++++++++++++++++++++++
>  include/linux/dma-iommu.h            |  84 ++++++
>  include/linux/iommu.h                |   1 +
>  8 files changed, 1084 insertions(+), 8 deletions(-)
>  create mode 100644 drivers/iommu/dma-iommu.c
>  create mode 100644 include/linux/dma-iommu.h
> 




From mark.yao at rock-chips.com  Tue Aug 25 23:34:21 2015
From: mark.yao at rock-chips.com (Mark yao)
Date: Wed, 26 Aug 2015 14:34:21 +0800
Subject: [GIT PULL] drm/rockchip: fixes and new features
In-Reply-To: <1437962762-19157-1-git-send-email-mark.yao@rock-chips.com>
References: <1437962762-19157-1-git-send-email-mark.yao@rock-chips.com>
Message-ID: <55DD5DED.7030109@rock-chips.com>

Hi Dave
     Here are some fixes and some new features for rockchip drm,
     tested on popmetal rk3288 board, can you land them?

The following changes since commit db56176025cee5e242dfeed5f4e304d095d29fa3:

   Revert "drm/atomic: Call ww_acquire_done after check phase is 
complete" (2015-08-25 17:23:36 +1000)

are available in the git repository at:

   https://github.com/markyzq/kernel-drm-rockchip.git 
drm-rockchip-2015-08-26

for you to fetch changes up to 4c156c21c7948a0be854cbe5914af3181303e529:

   drm/rockchip: vop: support plane scale (2015-08-26 14:16:26 +0800)

----------------------------------------------------------------
Mark Yao (6):
       drm/rockchip: vop: Fix virtual stride calculation
       drm/rockchip: vop: Fix window dest start point
       drm/rockchip: vop: Add yuv plane support
       drm/rockchip: vop: Default enable win2/3 area0 bit
       drm/rockchip: vop: restore vop registers when resume
       drm/rockchip: vop: support plane scale

  drivers/gpu/drm/rockchip/rockchip_drm_vop.c |  269 
++++++++++++++++++++++++++-
  drivers/gpu/drm/rockchip/rockchip_drm_vop.h |   88 +++++++++
  2 files changed, 348 insertions(+), 9 deletions(-)

-Mark



From ranjit.waghmode at xilinx.com  Tue Aug 25 23:26:07 2015
From: ranjit.waghmode at xilinx.com (Ranjit Waghmode)
Date: Wed, 26 Aug 2015 11:56:07 +0530
Subject: [LINUX RFC v2 4/4] spi: zynqmp: gqspi: add support for dual parallel
 mode configuration
In-Reply-To: <1440570367-22569-1-git-send-email-ranjit.waghmode@xilinx.com>
References: <1440570367-22569-1-git-send-email-ranjit.waghmode@xilinx.com>
Message-ID: <1440570367-22569-5-git-send-email-ranjit.waghmode@xilinx.com>

This patch adds support of dual parallel mode configuration
for Zynq Ultrascale+ MPSoC GQSPI controller driver.

Signed-off-by: Ranjit Waghmode <ranjit.waghmode at xilinx.com>
---
V2 Changes:
- No change in this patch
---
 drivers/spi/spi-zynqmp-gqspi.c | 24 +++++++++++++++++++++++-
 1 file changed, 23 insertions(+), 1 deletion(-)

diff --git a/drivers/spi/spi-zynqmp-gqspi.c b/drivers/spi/spi-zynqmp-gqspi.c
index f23f36e..7a72781 100644
--- a/drivers/spi/spi-zynqmp-gqspi.c
+++ b/drivers/spi/spi-zynqmp-gqspi.c
@@ -153,6 +153,7 @@ enum mode_type {GQSPI_MODE_IO, GQSPI_MODE_DMA};
  * @dma_rx_bytes:	Remaining bytes to receive by DMA mode
  * @dma_addr:		DMA address after mapping the kernel buffer
  * @genfifoentry:	Used for storing the genfifoentry instruction.
+ * @isinstr:		To determine whether the transfer is instruction
  * @mode:		Defines the mode in which QSPI is operating
  */
 struct zynqmp_qspi {
@@ -170,6 +171,7 @@ struct zynqmp_qspi {
 	u32 dma_rx_bytes;
 	dma_addr_t dma_addr;
 	u32 genfifoentry;
+	bool isinstr;
 	enum mode_type mode;
 };

@@ -405,9 +407,20 @@ static void zynqmp_qspi_chipselect(struct spi_device *qspi, bool is_high)
 	genfifoentry |= GQSPI_GENFIFO_MODE_SPI;
 	genfifoentry |= xqspi->genfifobus;

+	if (qspi->master->flags & SPI_MASTER_BOTH_CS) {
+		zynqmp_gqspi_selectslave(xqspi,
+				GQSPI_SELECT_FLASH_CS_BOTH,
+				GQSPI_SELECT_FLASH_BUS_BOTH);
+	} else {
+		zynqmp_gqspi_selectslave(xqspi,
+				GQSPI_SELECT_FLASH_CS_LOWER,
+				GQSPI_SELECT_FLASH_BUS_LOWER);
+	}
+
 	if (!is_high) {
 		genfifoentry |= xqspi->genfifocs;
 		genfifoentry |= GQSPI_GENFIFO_CS_SETUP;
+		xqspi->isinstr = true;
 	} else {
 		genfifoentry |= GQSPI_GENFIFO_CS_HOLD;
 	}
@@ -664,6 +677,7 @@ static irqreturn_t zynqmp_qspi_irq(int irq, void *dev_id)
 	if ((xqspi->bytes_to_receive == 0) && (xqspi->bytes_to_transfer == 0)
 			&& ((status & GQSPI_IRQ_MASK) == GQSPI_IRQ_MASK)) {
 		zynqmp_gqspi_write(xqspi, GQSPI_IDR_OFST, GQSPI_ISR_IDR_MASK);
+		xqspi->isinstr = false;
 		spi_finalize_current_transfer(master);
 		ret = IRQ_HANDLED;
 	}
@@ -827,6 +841,9 @@ static int zynqmp_qspi_start_transfer(struct spi_master *master,
 	genfifoentry |= xqspi->genfifocs;
 	genfifoentry |= xqspi->genfifobus;

+	if ((!xqspi->isinstr) && (master->flags & SPI_MASTER_DATA_STRIPE))
+		genfifoentry |= GQSPI_GENFIFO_STRIPE;
+
 	zynqmp_qspi_txrxsetup(xqspi, transfer, &genfifoentry);

 	if (xqspi->mode == GQSPI_MODE_DMA)
@@ -983,6 +1000,7 @@ static int zynqmp_qspi_probe(struct platform_device *pdev)
 	struct zynqmp_qspi *xqspi;
 	struct resource *res;
 	struct device *dev = &pdev->dev;
+	u32 num_cs;

 	master = spi_alloc_master(&pdev->dev, sizeof(*xqspi));
 	if (!master)
@@ -1043,7 +1061,11 @@ static int zynqmp_qspi_probe(struct platform_device *pdev)
 		goto clk_dis_all;
 	}

-	master->num_chipselect = GQSPI_DEFAULT_NUM_CS;
+	ret = of_property_read_u32(pdev->dev.of_node, "num-cs", &num_cs);
+	if (ret < 0)
+		master->num_chipselect = GQSPI_DEFAULT_NUM_CS;
+	else
+		master->num_chipselect = num_cs;

 	master->setup = zynqmp_qspi_setup;
 	master->set_cs = zynqmp_qspi_chipselect;
--
2.1.2



From ranjit.waghmode at xilinx.com  Tue Aug 25 23:26:05 2015
From: ranjit.waghmode at xilinx.com (Ranjit Waghmode)
Date: Wed, 26 Aug 2015 11:56:05 +0530
Subject: [LINUX RFC v2 2/4] mtd: add spi_device instance to spi_nor struct
In-Reply-To: <1440570367-22569-1-git-send-email-ranjit.waghmode@xilinx.com>
References: <1440570367-22569-1-git-send-email-ranjit.waghmode@xilinx.com>
Message-ID: <1440570367-22569-3-git-send-email-ranjit.waghmode@xilinx.com>

This patch adds struct spi_device instacne to the spi_nor structure

Signed-off-by: Ranjit Waghmode <ranjit.waghmode at xilinx.com>
---
V2 Changes:
This is new patch, basically splitted on request of Mark Brown
---
 drivers/mtd/devices/m25p80.c | 1 +
 include/linux/mtd/spi-nor.h  | 1 +
 2 files changed, 2 insertions(+)

diff --git a/drivers/mtd/devices/m25p80.c b/drivers/mtd/devices/m25p80.c
index d313f948b..174ed0f 100644
--- a/drivers/mtd/devices/m25p80.c
+++ b/drivers/mtd/devices/m25p80.c
@@ -207,6 +207,7 @@ static int m25p_probe(struct spi_device *spi)
 	spi_set_drvdata(spi, flash);
 	flash->mtd.priv = nor;
 	flash->spi = spi;
+	nor->spi = spi;

 	if (spi->mode & SPI_RX_QUAD)
 		mode = SPI_NOR_QUAD;
diff --git a/include/linux/mtd/spi-nor.h b/include/linux/mtd/spi-nor.h
index e540952..1705dc3 100644
--- a/include/linux/mtd/spi-nor.h
+++ b/include/linux/mtd/spi-nor.h
@@ -163,6 +163,7 @@ struct spi_nor {
 	struct mtd_info		*mtd;
 	struct mutex		lock;
 	struct device		*dev;
+	struct spi_device	*spi;
 	u32			page_size;
 	u8			addr_width;
 	u8			erase_opcode;
--
2.1.2



From ranjit.waghmode at xilinx.com  Tue Aug 25 23:26:04 2015
From: ranjit.waghmode at xilinx.com (Ranjit Waghmode)
Date: Wed, 26 Aug 2015 11:56:04 +0530
Subject: [LINUX RFC v2 1/4] spi: add support of two chip selects & data stripe
In-Reply-To: <1440570367-22569-1-git-send-email-ranjit.waghmode@xilinx.com>
References: <1440570367-22569-1-git-send-email-ranjit.waghmode@xilinx.com>
Message-ID: <1440570367-22569-2-git-send-email-ranjit.waghmode@xilinx.com>

To support dual parallel mode operation of ZynqMP GQSPI controller
following API's are added inside the core:

- Added API to support two chip selects:

  Dual parallel mode supports two SPI flash memories operating in
  parallel i.e 8 I/O lines.
  Chip selects and clock are shared to both the flash devices.
  So newly added API will help in enabling both the chips.

- Added API to support data stripe feature:

  with data stripe enabled,
  even bytes i.e. 0, 2, 4,... are transmitted on lower data bus
  odd bytes i.e. 1, 3, 5,.. are transmitted on upper data bus.

Signed-off-by: Ranjit Waghmode <ranjit.waghmode at xilinx.com>
---
V2 Changes:
- Added error handling condition for newly added features
---
 drivers/spi/spi.c       |  8 ++++++++
 include/linux/spi/spi.h | 11 +++++++++++
 2 files changed, 19 insertions(+)

diff --git a/drivers/spi/spi.c b/drivers/spi/spi.c
index cf8b91b..22e8e7f 100644
--- a/drivers/spi/spi.c
+++ b/drivers/spi/spi.c
@@ -1828,6 +1828,14 @@ static int __spi_validate(struct spi_device *spi, struct spi_message *message)
 	if (list_empty(&message->transfers))
 		return -EINVAL;

+	/*
+	 * Data stripe option is selected if and only if when
+	 * two chips are enabled
+	 */
+	if ((master->flags & SPI_MASTER_DATA_STRIPE)
+		&& !(master->flags & SPI_MASTER_BOTH_CS))
+			return -EINVAL;
+
 	/* Half-duplex links include original MicroWire, and ones with
 	 * only one data pin like SPI_3WIRE (switches direction) or where
 	 * either MOSI or MISO is missing.  They can also be caused by
diff --git a/include/linux/spi/spi.h b/include/linux/spi/spi.h
index d673072..53d3bc6 100644
--- a/include/linux/spi/spi.h
+++ b/include/linux/spi/spi.h
@@ -355,6 +355,17 @@ struct spi_master {
 #define SPI_MASTER_NO_TX	BIT(2)		/* can't do buffer write */
 #define SPI_MASTER_MUST_RX      BIT(3)		/* requires rx */
 #define SPI_MASTER_MUST_TX      BIT(4)		/* requires tx */
+	/* Controller may support data stripe feature when more than one
+	 * chips are present.
+	 * Setting data stripe will send data in following manner:
+	 * -> even bytes i.e. 0, 2, 4,... are transmitted on lower data bus
+	 * -> odd bytes i.e. 1, 3, 5,.. are transmitted on upper data bus
+	 */
+#define SPI_MASTER_DATA_STRIPE		BIT(7)		/* support data stripe */
+	/* Controller may support more than one chip.
+	 * This flag will enable that feature.
+	 */
+#define SPI_MASTER_BOTH_CS		BIT(8)		/* enable both chips */

 	/* lock and mutex for SPI bus locking */
 	spinlock_t		bus_lock_spinlock;
--
2.1.2



From ranjit.waghmode at xilinx.com  Tue Aug 25 23:26:06 2015
From: ranjit.waghmode at xilinx.com (Ranjit Waghmode)
Date: Wed, 26 Aug 2015 11:56:06 +0530
Subject: [LINUX RFC v2 3/4] spi-nor: add dual parallel mode support
In-Reply-To: <1440570367-22569-1-git-send-email-ranjit.waghmode@xilinx.com>
References: <1440570367-22569-1-git-send-email-ranjit.waghmode@xilinx.com>
Message-ID: <1440570367-22569-4-git-send-email-ranjit.waghmode@xilinx.com>

This patch adds support for dual parallel configuration by:

- Adding required parameters like isparallel and shift to spi_nor structure.
- Initializing all added parameters in spi_nor_scan()
- Updating read_sr() and read_fsr() for getting status of both flashes
- Increasing page_size, sector_size, erase_size and toatal flash size
  as and when required.
- Dividing address by 2
- Updating spi->master->flags for qspi driver to change CS

Signed-off-by: Ranjit Waghmode <ranjit.waghmode at xilinx.com>
---
V2 Changes:
Splitted to separate MTD layer changes from SPI core changes
---
 drivers/mtd/spi-nor/spi-nor.c | 91 ++++++++++++++++++++++++++++++++++---------
 include/linux/mtd/spi-nor.h   |  2 +
 2 files changed, 74 insertions(+), 19 deletions(-)

diff --git a/drivers/mtd/spi-nor/spi-nor.c b/drivers/mtd/spi-nor/spi-nor.c
index d78831b..6a2e80b 100644
--- a/drivers/mtd/spi-nor/spi-nor.c
+++ b/drivers/mtd/spi-nor/spi-nor.c
@@ -22,6 +22,7 @@
 #include <linux/of_platform.h>
 #include <linux/spi/flash.h>
 #include <linux/mtd/spi-nor.h>
+#include <linux/spi/spi.h>

 /* Define max times to check status register before we give up. */
 #define	MAX_READY_WAIT_JIFFIES	(40 * HZ) /* M25P16 specs 40s max chip erase */
@@ -69,15 +70,24 @@ static const struct spi_device_id *spi_nor_match_id(const char *name);
 static int read_sr(struct spi_nor *nor)
 {
 	int ret;
-	u8 val;
+	u8 val[2];

-	ret = nor->read_reg(nor, SPINOR_OP_RDSR, &val, 1);
-	if (ret < 0) {
-		pr_err("error %d reading SR\n", (int) ret);
-		return ret;
+	if (nor->isparallel) {
+		ret = nor->read_reg(nor, SPINOR_OP_RDSR, &val[0], 2);
+		if (ret < 0) {
+			pr_err("error %d reading SR\n", (int) ret);
+			return ret;
+		}
+		val[0] |= val[1];
+	} else {
+		ret = nor->read_reg(nor, SPINOR_OP_RDSR, &val[0], 1);
+		if (ret < 0) {
+			pr_err("error %d reading SR\n", (int) ret);
+			return ret;
+		}
 	}

-	return val;
+	return val[0];
 }

 /*
@@ -87,16 +97,24 @@ static int read_sr(struct spi_nor *nor)
  */
 static int read_fsr(struct spi_nor *nor)
 {
-	int ret;
-	u8 val;
+	int ret, size;
+	u8 val[2];
+
+	size = 1;
+	val[1] = 0xff;
+
+	if (nor->isparallel)
+		size = 2;

-	ret = nor->read_reg(nor, SPINOR_OP_RDFSR, &val, 1);
+	ret = nor->read_reg(nor, SPINOR_OP_RDFSR, &val[0], size);
 	if (ret < 0) {
 		pr_err("error %d reading FSR\n", ret);
 		return ret;
 	}

-	return val;
+	val[0] &= val[1];
+
+	return val[0];
 }

 /*
@@ -317,6 +335,9 @@ static int spi_nor_erase(struct mtd_info *mtd, struct erase_info *instr)
 	if (ret)
 		return ret;

+	if (nor->isparallel)
+		nor->spi->master->flags |= SPI_MASTER_DATA_STRIPE;
+
 	/* whole-chip erase? */
 	if (len == mtd->size) {
 		write_enable(nor);
@@ -340,6 +361,8 @@ static int spi_nor_erase(struct mtd_info *mtd, struct erase_info *instr)
 		while (len) {
 			write_enable(nor);

+			addr = addr >> nor->shift;
+
 			if (nor->erase(nor, addr)) {
 				ret = -EIO;
 				goto erase_err;
@@ -360,19 +383,22 @@ static int spi_nor_erase(struct mtd_info *mtd, struct erase_info *instr)

 	instr->state = MTD_ERASE_DONE;
 	mtd_erase_callback(instr);
-
+	if (nor->isparallel)
+		nor->spi->master->flags &= ~SPI_MASTER_DATA_STRIPE;
 	return ret;

 erase_err:
 	spi_nor_unlock_and_unprep(nor, SPI_NOR_OPS_ERASE);
 	instr->state = MTD_ERASE_FAILED;
+	if (nor->isparallel)
+		nor->spi->master->flags &= ~SPI_MASTER_DATA_STRIPE;
 	return ret;
 }

 static int stm_lock(struct spi_nor *nor, loff_t ofs, uint64_t len)
 {
 	struct mtd_info *mtd = nor->mtd;
-	uint32_t offset = ofs;
+	uint32_t offset = ofs >> nor->shift;
 	uint8_t status_old, status_new;
 	int ret = 0;

@@ -406,7 +432,7 @@ static int stm_lock(struct spi_nor *nor, loff_t ofs, uint64_t len)
 static int stm_unlock(struct spi_nor *nor, loff_t ofs, uint64_t len)
 {
 	struct mtd_info *mtd = nor->mtd;
-	uint32_t offset = ofs;
+	uint32_t offset = ofs >> nor->shift;
 	uint8_t status_old, status_new;
 	int ret = 0;

@@ -446,6 +472,8 @@ static int spi_nor_lock(struct mtd_info *mtd, loff_t ofs, uint64_t len)
 	if (ret)
 		return ret;

+	ofs = ofs >> nor->shift;
+
 	ret = nor->flash_lock(nor, ofs, len);

 	spi_nor_unlock_and_unprep(nor, SPI_NOR_OPS_UNLOCK);
@@ -461,6 +489,8 @@ static int spi_nor_unlock(struct mtd_info *mtd, loff_t ofs, uint64_t len)
 	if (ret)
 		return ret;

+	ofs = ofs >> nor->shift;
+
 	ret = nor->flash_unlock(nor, ofs, len);

 	spi_nor_unlock_and_unprep(nor, SPI_NOR_OPS_LOCK);
@@ -738,7 +768,13 @@ static int spi_nor_read(struct mtd_info *mtd, loff_t from, size_t len,
 	if (ret)
 		return ret;

-	ret = nor->read(nor, from, len, retlen, buf);
+	if (nor->isparallel)
+		nor->spi->master->flags |= SPI_MASTER_DATA_STRIPE;
+
+	ret = nor->read(nor, from >> nor->shift, len, retlen, buf);
+
+	if (nor->isparallel)
+		nor->spi->master->flags &= ~SPI_MASTER_DATA_STRIPE;

 	spi_nor_unlock_and_unprep(nor, SPI_NOR_OPS_READ);
 	return ret;
@@ -834,11 +870,11 @@ static int spi_nor_write(struct mtd_info *mtd, loff_t to, size_t len,

 	/* do all the bytes fit onto one page? */
 	if (page_offset + len <= nor->page_size) {
-		nor->write(nor, to, len, retlen, buf);
+		nor->write(nor, to >> nor->shift, len, retlen, buf);
 	} else {
 		/* the size of data remaining on the first page */
 		page_size = nor->page_size - page_offset;
-		nor->write(nor, to, page_size, retlen, buf);
+		nor->write(nor, to >> nor->shift, page_size, retlen, buf);

 		/* write everything in nor->page_size chunks */
 		for (i = page_size; i < len; i += page_size) {
@@ -852,12 +888,15 @@ static int spi_nor_write(struct mtd_info *mtd, loff_t to, size_t len,

 			write_enable(nor);

-			nor->write(nor, to + i, page_size, retlen, buf + i);
+			nor->write(nor, (to + i) >> nor->shift, page_size,
+					retlen, buf + i);
 		}
 	}

 	ret = spi_nor_wait_till_ready(nor);
 write_err:
+	if (nor->isparallel)
+		nor->spi->master->flags &= ~SPI_MASTER_DATA_STRIPE;
 	spi_nor_unlock_and_unprep(nor, SPI_NOR_OPS_WRITE);
 	return ret;
 }
@@ -1073,6 +1112,20 @@ int spi_nor_scan(struct spi_nor *nor, const char *name, enum read_mode mode)
 	mtd->_erase = spi_nor_erase;
 	mtd->_read = spi_nor_read;

+#ifdef CONFIG_OF
+	struct device_node *np_spi = of_get_next_parent(np);
+	u32 is_dual;
+
+	if (of_property_read_u32(np_spi, "is-dual", &is_dual) > 0) {
+		nor->shift = 1;
+		info->sector_size <<= nor->shift;
+		info->page_size <<= nor->shift;
+		mtd->size <<= nor->shift;
+		nor->isparallel = 1;
+		nor->spi->master->flags |= SPI_MASTER_BOTH_CS;
+	}
+#endif
+
 	/* nor protection support for STmicro chips */
 	if (JEDEC_MFR(info) == CFI_MFR_ST) {
 		nor->flash_lock = stm_lock;
@@ -1097,10 +1150,10 @@ int spi_nor_scan(struct spi_nor *nor, const char *name, enum read_mode mode)
 	/* prefer "small sector" erase if possible */
 	if (info->flags & SECT_4K) {
 		nor->erase_opcode = SPINOR_OP_BE_4K;
-		mtd->erasesize = 4096;
+		mtd->erasesize = 4096 << nor->shift;
 	} else if (info->flags & SECT_4K_PMC) {
 		nor->erase_opcode = SPINOR_OP_BE_4K_PMC;
-		mtd->erasesize = 4096;
+		mtd->erasesize = 4096 << nor->shift;
 	} else
 #endif
 	{
diff --git a/include/linux/mtd/spi-nor.h b/include/linux/mtd/spi-nor.h
index 1705dc3..6ef25a8 100644
--- a/include/linux/mtd/spi-nor.h
+++ b/include/linux/mtd/spi-nor.h
@@ -171,6 +171,8 @@ struct spi_nor {
 	u8			read_dummy;
 	u8			program_opcode;
 	enum read_mode		flash_read;
+	bool			shift;
+	bool			isparallel;
 	bool			sst_write_second;
 	u32			flags;
 	struct spi_nor_xfer_cfg	cfg;
--
2.1.2



From ranjit.waghmode at xilinx.com  Tue Aug 25 23:26:03 2015
From: ranjit.waghmode at xilinx.com (Ranjit Waghmode)
Date: Wed, 26 Aug 2015 11:56:03 +0530
Subject: [LINUX RFC v2 0/4] spi: add dual parallel mode support in Zynq MPSoC
 GQSPI controller
Message-ID: <1440570367-22569-1-git-send-email-ranjit.waghmode@xilinx.com>

This series adds dual parallel mode support for Zynq Ultrascale+
MPSoC GQSPI controller driver.

What is dual parallel mode?
---------------------------
ZynqMP GQSPI controller supports Dual Parallel mode with following functionalities:
1) Supporting two SPI flash memories operating in parallel. 8 I/O lines.
2) Chip selects and clock are shared to both the flash devices
3) This mode is targeted for faster read/write speed and also doubles the size
4) Commands/data can be transmitted/received from both the devices(mirror),
   or only upper or only lower flash memory devices.
5) Data arrangement:
   With stripe enabled,
   Even bytes i.e. 0, 2, 4,... are transmitted on Lower Data Bus
   Odd bytes i.e. 1, 3, 5,.. are transmitted on Upper Data Bus.

This series also updated MTD layer files for adding parallel mode support.

1) Added Support for two flashes
2) Support to enable/disable data stripe as and when required.
3) Added required parameters to spi_nor structure. Initialized all
   added parameters in spi_nor_scan()
4) Added support for dual parallel in spi_nor_read/write/erase functions by:
   a) Increasing page_size, sector_size, erase_size and toatal flash size
      as and when required.
   b) Dividing address by 2
   c) Updating spi->master->flags for qspi driver to change CS
5) Updated read_sr() to get status of both flashes
6) Also updated read_fsr() to get status of both flashes

These all are very high level changes and expected to make an idea clear.
Comments and suggestions are always welcomed

---
V2 Changes:
a) Splitted patches based on logical changes
b) Added error handling for newly added APIs in SPI core
---

Ranjit Waghmode (4):
  spi: add support of two chip selects & data stripe
  mtd: add spi_device instance to spi_nor struct
  spi-nor: add dual parallel mode support
  spi: zynqmp: gqspi: add support for dual parallel mode configuration

 drivers/mtd/devices/m25p80.c   |  1 +
 drivers/mtd/spi-nor/spi-nor.c  | 91 +++++++++++++++++++++++++++++++++---------
 drivers/spi/spi-zynqmp-gqspi.c | 24 ++++++++++-
 drivers/spi/spi.c              |  8 ++++
 include/linux/mtd/spi-nor.h    |  3 ++
 include/linux/spi/spi.h        | 11 +++++
 6 files changed, 118 insertions(+), 20 deletions(-)

--
2.1.2



From pi-cheng.chen at linaro.org  Tue Aug 25 23:53:39 2015
From: pi-cheng.chen at linaro.org (Pi-Cheng Chen)
Date: Wed, 26 Aug 2015 14:53:39 +0800
Subject: [RESEND PATCH 0/3 v6] Add Mediatek MT8173 cpufreq driver
In-Reply-To: <20150826021659.GD8784@linux>
References: <1439803465-19683-1-git-send-email-pi-cheng.chen@linaro.org>
 <CALx668VWg2xVxzy8P7f5QFWRzm+TDJXUghL-_rbvRLsLYjtnng@mail.gmail.com>
 <1617873.VRHfat3V76@vostro.rjw.lan>
 <CALx668UvkYhLoU8rxLG70RqTzsnaiV5-ybDYTKqb4MEJS8pmRw@mail.gmail.com>
 <20150826021659.GD8784@linux>
Message-ID: <CALx668V2herrp6XOtCDR7nNvFhd7DLLMjXmr86cjfCOQ_cgmrw@mail.gmail.com>

On Wed, Aug 26, 2015 at 10:16 AM, Viresh Kumar <viresh.kumar at linaro.org> wrote:
> On 26-08-15, 09:25, Pi-Cheng Chen wrote:
>> The [3/3] is based on Mediatek SoC maintainer tree[1] and the patch which
>> introduce a new clock type[2] consumed by MT8173 cpufreq driver. So it will
>> cause some conflicts if it goes through your tree. I am not sure how this
>> should be handled, but should it be merged through Mediatek SoC maintainer
>> tree?
>
> Just get that applied to MTK tree, it doesn't have any dependency on
> rest of the patches for build/boot. The only thing is that cpufreq
> wouldn't work and it will work as soon as Rafael's and MTK's trees are
> merged by Linus.

Thanks for your explanation.

@Rafael, Would you please apply [1,2] to your tree?

@Matthias, Would you please apply [3/3] of this series?

Thanks.

Best Regards,
Pi-Cheng

>
> --
> viresh


From eddie.huang at mediatek.com  Tue Aug 25 23:55:08 2015
From: eddie.huang at mediatek.com (Eddie Huang)
Date: Wed, 26 Aug 2015 14:55:08 +0800
Subject: [PATCH v2] soc: mediatek: add scpsys support active_wakeup
In-Reply-To: <CAGS+omBqTbcJk-6QvupV4tkB5WQm97zpb5NzZ-S2ivR-UEWF4g@mail.gmail.com>
References: <1440482440-28700-1-git-send-email-eddie.huang@mediatek.com>
 <CAGS+omBqTbcJk-6QvupV4tkB5WQm97zpb5NzZ-S2ivR-UEWF4g@mail.gmail.com>
Message-ID: <1440572108.28149.4.camel@mtksdaap41>

On Wed, 2015-08-26 at 05:11 +0800, Daniel Kurtz wrote:
> Hi Eddie,
> 
> On Tue, Aug 25, 2015 at 2:00 PM, Eddie Huang <eddie.huang at mediatek.com> wrote:
> > Register gpd_dev_ops.active_wakeup function to support keep power
> > during suspend state. And add flag to each power domain to
> > decide whether keep power during suspend or not.
> >
> > Signed-off-by: Chunfeng Yun <chunfeng.yun at mediatek.com>
> > Signed-off-by: Eddie Huang <eddie.huang at mediatek.com>
> > Acked-by: Sascha Hauer <s.hauer at pengutronix.de>
> >
> > ---
> > Change in v2:
> > Drop .active_wakeup = false lines in scp_domain_data[] array
> >
> > ---
> >  drivers/soc/mediatek/mtk-scpsys.c | 19 +++++++++++++++++++
> >  1 file changed, 19 insertions(+)
> >
> > diff --git a/drivers/soc/mediatek/mtk-scpsys.c b/drivers/soc/mediatek/mtk-scpsys.c
> > index 43a79ed..df2f288 100644
> > --- a/drivers/soc/mediatek/mtk-scpsys.c
> > +++ b/drivers/soc/mediatek/mtk-scpsys.c
> > @@ -67,6 +67,7 @@ struct scp_domain_data {
> >         u32 sram_pdn_ack_bits;
> >         u32 bus_prot_mask;
> >         enum clk_id clk_id;
> > +       bool active_wakeup;
> >  };
> >
> >  static const struct scp_domain_data scp_domain_data[] __initconst = {
> > @@ -127,6 +128,7 @@ static const struct scp_domain_data scp_domain_data[] __initconst = {
> >                 .sram_pdn_bits = GENMASK(11, 8),
> >                 .sram_pdn_ack_bits = GENMASK(15, 12),
> >                 .clk_id = MT8173_CLK_NONE,
> > +               .active_wakeup = true,
> >         },
> >         [MT8173_POWER_DOMAIN_MFG_ASYNC] = {
> >                 .name = "mfg_async",
> > @@ -171,6 +173,7 @@ struct scp_domain {
> >         u32 sram_pdn_bits;
> >         u32 sram_pdn_ack_bits;
> >         u32 bus_prot_mask;
> > +       bool active_wakeup;
> >  };
> >
> >  struct scp {
> > @@ -370,6 +373,20 @@ out:
> >         return ret;
> >  }
> >
> > +static bool scpsys_active_wakeup(struct device *dev)
> > +{
> > +       struct generic_pm_domain *genpd;
> > +       struct scp_domain *scpd;
> > +
> > +       if (IS_ERR_OR_NULL(dev->pm_domain))
> > +               return false;
> 
> Is it really possible to get here w/ pm_domain as an ERR or NULL?
> If the power core can ensure this cannot happen, then this function
> could be a bit simpler.
> 
> Other than that, this patch is:
> Reviewed-by: Daniel Kurtz <djkurtz at chromium.org>
> 
> -Dan
> 

After checking drivers/base/power/domain.c, I believe check
dev->pm_domain here is redundant, I will remove it.

Eddie
Thanks




From marex at denx.de  Tue Aug 25 23:56:22 2015
From: marex at denx.de (Marek Vasut)
Date: Wed, 26 Aug 2015 08:56:22 +0200
Subject: [LINUX RFC v2 0/4] spi: add dual parallel mode support in Zynq
 MPSoC GQSPI controller
In-Reply-To: <1440570367-22569-1-git-send-email-ranjit.waghmode@xilinx.com>
References: <1440570367-22569-1-git-send-email-ranjit.waghmode@xilinx.com>
Message-ID: <201508260856.22258.marex@denx.de>

On Wednesday, August 26, 2015 at 08:26:03 AM, Ranjit Waghmode wrote:
> This series adds dual parallel mode support for Zynq Ultrascale+
> MPSoC GQSPI controller driver.
> 
> What is dual parallel mode?
> ---------------------------
> ZynqMP GQSPI controller supports Dual Parallel mode with following
> functionalities: 1) Supporting two SPI flash memories operating in
> parallel. 8 I/O lines. 2) Chip selects and clock are shared to both the
> flash devices
> 3) This mode is targeted for faster read/write speed and also doubles the
> size 4) Commands/data can be transmitted/received from both the
> devices(mirror), or only upper or only lower flash memory devices.
> 5) Data arrangement:
>    With stripe enabled,
>    Even bytes i.e. 0, 2, 4,... are transmitted on Lower Data Bus
>    Odd bytes i.e. 1, 3, 5,.. are transmitted on Upper Data Bus.

This might be a dumb question, but why don't you just treat this as an
SPI NOR flash with 8-bit bus ?

Best regards,
Marek Vasut


From leo.yan at linaro.org  Tue Aug 25 23:59:50 2015
From: leo.yan at linaro.org (Leo Yan)
Date: Wed, 26 Aug 2015 14:59:50 +0800
Subject: [PATCH v1 3/3] arm64: dts: add Hi6220 mailbox node
In-Reply-To: <1440552341.10987.53.camel@linaro.org>
References: <20150824095144.GA7139@leverpostej>
 <1440411596.3517.12.camel@linaro.org>
 <20150824114903.GT10728@bivouac.eciton.net>
 <1440490427.10987.29.camel@linaro.org>
 <20150825094630.GU10728@bivouac.eciton.net>
 <1440497710.10987.42.camel@linaro.org>
 <20150825104256.GB13471@leverpostej>
 <1440510194.10987.52.camel@linaro.org>
 <20150825160030.GA3774@leoy-linaro>
 <1440552341.10987.53.camel@linaro.org>
Message-ID: <20150826065950.GB19594@leoy-linaro>

Hi Haojian,

On Wed, Aug 26, 2015 at 09:25:41AM +0800, Haojian Zhuang wrote:
> On Wed, 2015-08-26 at 00:00 +0800, Leo Yan wrote:
> > On Tue, Aug 25, 2015 at 09:43:14PM +0800, Haojian Zhuang wrote:
> > > On Tue, 2015-08-25 at 11:42 +0100, Mark Rutland wrote:
> > > > > > Are you then going to hack GRUB, release a special HiKey version of
> > > > > > GRUB, not support any other versions, and still can your firmware
> > > > > > UEFI?
> > > > > 
> > > > > I don't need to hack GRUB at all.
> > > > 
> > > > Then it is working for you by pure chance alone.
> > > > 
> > > > Please listen to the advice you are being given here; we're trying to
> > > > ensure that your platform functions (and continues to function) as best
> > > > it can.
> > > 
> > > Since we discussed a lot on this, let's make a conclusion on it.
> > > 
> > > 1. UEFI could append the reserved buffer in it's memory mapping.
> > > 2. These reserved buffer must be declared in DT, since we also need to
> > >    support non-UEFI (uboot) at the same time.
> > > 3. Mailbox node should reference reserved buffer by phandle in DT. Then
> > >    map the buffer as non-cacheable in driver.
> > > 4. These reserved buffer must use "no-map" property since it should be
> > >    non-cacheable in driver.
> > 
> > For more specific discussion for DTS, i list two options at here;
> > 
> > - Option 1: just simply reserve memory regions through memory node,
> >   and mailbox node will directly use the buffer through reg ranges;
> > 
> > - Option 2: use reserved-memory and mailbox node will refer phandle
> >   of reserved-memory;
> > 
> > These two options both can work well with UEFI and Uboot, but option 1
> > is more simple and straightforward; so i personally prefer it. But
> > look forwarding your guys' suggestion.
> > 
> > Option 1:
> > 
> > 	memory at 0 {
> > 		device_type = "memory";
> > 		reg = <0x00000000 0x00000000 0x00000000 0x05e00000>,
> > 		      <0x00000000 0x05f00000 0x00000000 0x00eff000>,
> > 		      <0x00000000 0x06e00000 0x00000000 0x0060f000>,
> > 		      <0x00000000 0x07410000 0x00000000 0x38bf0000>;
> > 	};
> > 
> >         [...]
> > 
> > 	mailbox: mailbox at f7510000 {
> > 		#mbox-cells = <1>;
> > 		compatible = "hisilicon,hi6220-mbox";
> > 		reg = <0x0 0xf7510000 0x0 0x1000>, /* IPC_S */
> > 		      <0x0 0x06dff800 0x0 0x0800>; /* Mailbox buffer */
> > 		interrupts = <GIC_SPI 94 IRQ_TYPE_LEVEL_HIGH>;
> > 	};
> > 
> > Option 2:
> > 
> > 	memory at 0 {
> > 		device_type = "memory";
> > 		reg = <0x0 0x0 0x0 0x40000000>;
> > 	};
> > 
> > 	reserved-memory {
> > 		#address-cells = <2>;
> > 		#size-cells = <2>;
> > 		ranges;
> > 
> > 		mcu_reserved: mcu_reserved at 06dff000 {
> > 			no-map;
> > 			reg = <0x0 0x06dff000 0x0 0x00001000>,	/* MCU mailbox buffer */
> > 			      <0x0 0x05e00000 0x0 0x00100000>,	/* MCU firmware buffer */
> > 			      <0x0 0x0740f000 0x0 0x00001000>;	/* MCU firmware section */
> > 		};
> > 	};
> > 
> >         [...]
> > 
> > 	mailbox: mailbox at f7510000 {
> > 		#mbox-cells = <1>;
> > 		compatible = "hisilicon,hi6220-mbox";
> > 		reg = <0x0 0xf7510000 0x0 0x1000>; /* IPC_S */
> > 		memory-region = <&mcu_reserved>;   /* Mailbox buffer */
> > 		interrupts = <GIC_SPI 94 IRQ_TYPE_LEVEL_HIGH>;
> > 	};
> 
> I prefer the second one. From my view, memory node should only describe
> the hardware information of memory.

Yes, option 2 will be more simple for memory node.

But option 2 also will introduce complexity for mailbox node, due mailbox
driver need use property "reg" and "memory-region" to sepeately depict
the regions for mailbox's ipc and slots. If later mailbox is designed to
use SRAM for both ipc and slots, then it will no matter with DDR anymore,
in this case option 1 will easily switch to support it.

Another question is a general question: for Linux kernel, which is the
best method to reserve memory regions? According to previous discussion,
we can use /memory/ node or /reseved-memory/ node to reserve memory
regions.

when review Juno's dts, i also see there have reserved 16MB DDR for secure
world. If so, looks like /reserved-memory/ node is unnecessary. if have some
specific scenarios will we use reserved-memory node to help reserve memory
regions?

Thanks,
Leo Yan


From peter.ujfalusi at ti.com  Wed Aug 26 00:09:21 2015
From: peter.ujfalusi at ti.com (Peter Ujfalusi)
Date: Wed, 26 Aug 2015 10:09:21 +0300
Subject: ARM: davinci: linux-next: Boot failure on OMAP-L138 with commit
 0db805aa8c96
Message-ID: <55DD6621.20907@ti.com>

Hi Russell,

with next-20150825 I have the following kernel panic:

RAMDISK: cramfs filesystem found at block 0
RAMDISK: Loading 7412KiB [1 disk] into ram disk... done.
VFS: Mounted root (cramfs filesystem) readonly on device 1:0.
devtmpfs: mounted
Freeing unused kernel memory: 200K (c04de000 - c0510000)
Unhandled fault: page domain fault (0x01b) at 0xb6f306a0
pgd = c64e0000
[b6f306a0] *pgd=c5a2e831, *pte=c76e718b, *ppte=c76e7aaa
Internal error: : 1b [#1] PREEMPT ARM
Modules linked in:
CPU: 0 PID: 1 Comm: init Not tainted 4.2.0-rc8-next-20150825 #19
Hardware name: DaVinci DA850/OMAP-L138/AM18x EVM
task: c7034000 ti: c7036000 task.ti: c7036000
PC is at not_thumb+0x0/0x18
LR is at __dabt_usr+0x50/0x60
pc : [<c00130b8>]    lr : [<c000e290>]    psr: 40000093
sp : c7037fb0  ip : 00000051  fp : 00000000
r10: 00000000  r9 : 00000000  r8 : 00053177
r7 : 0005317f  r6 : ffffffff  r5 : 60000010  r4 : b6f306a0
r3 : becacd60  r2 : c7037fb0  r1 : 00000017  r0 : b6f38f70
Flags: nZcv  IRQs off  FIQs on  Mode SVC_32  ISA ARM  Segment none
Control: 0005317f  Table: c64e0000  DAC: 00000051
Process init (pid: 1, stack limit = 0xc7036190)
Stack: (0xc7037fb0 to 0xc7038000)
7fa0:                                     ???????? ???????? ???????? ????????
7fc0: ???????? ???????? ???????? ???????? ???????? ???????? ???????? ????????
7fe0: ???????? ???????? ???????? ???????? ???????? ???????? ???????? ????????
Backtrace: no frame pointer
Code: bad PC value
---[ end trace 8cb5f050de571f06 ]---
Kernel panic - not syncing: Attempted to kill init! exitcode=0x0000000b

---[ end Kernel panic - not syncing: Attempted to kill init! exitcode=0x0000000b

bisect points me to the following commit:
0db805aa8c96 ARM: software-based priviledged-no-access support

If I disable the CONFIG_CPU_SW_DOMAIN_PAN, I will have:

RAMDISK: cramfs filesystem found at block 0
RAMDISK: Loading 7412KiB [1 disk] into ram disk... done.
VFS: Mounted root (cramfs filesystem) readonly on device 1:0.
devtmpfs: mounted
Freeing unused kernel memory: 204K (c04d9000 - c050c000)
Unhandled fault: page domain fault (0x81b) at 0x000b2b4a
pgd = c36d4000
[000b2b4a] *pgd=c36c5831, *pte=c050a14b, *ppte=c050affa
Internal error: : 81b [#1] PREEMPT ARM
Modules linked in:
CPU: 0 PID: 1 Comm: init Not tainted 4.2.0-rc8-next-20150825 #21
Hardware name: DaVinci DA850/OMAP-L138/AM18x EVM
task: c7034000 ti: c7036000 task.ti: c7036000
PC is at __clear_user_std+0x1c/0x68
LR is at padzero+0x54/0x60
pc : [<c01e607c>]    lr : [<c010dd28>]    psr: 60000013
sp : c7037e48  ip : 00000002  fp : c7037e5c
r10: c70800a0  r9 : c47816e0  r8 : c4786300
r7 : c7037e60  r6 : 00000000  r5 : c4786200  r4 : c46e6100
r3 : 00000000  r2 : 00000000  r1 : 000004b6  r0 : 000b2b4a
Flags: nZCv  IRQs on  FIQs on  Mode SVC_32  ISA ARM  Segment none
Control: 0005317f  Table: c36d4000  DAC: 00000051
Process init (pid: 1, stack limit = 0xc7036190)
Stack: (0xc7037e48 to 0xc7038000)
7e40:                   000004b6 c010dd28 c7037ee4 c7037e60 c010fbb0 c010dce4
7e60: 00001812 00000000 00000000 00000000 c7037e60 00000000 c7036000 c4786200
7e80: 00008000 000b2b4a 000b2500 000aa500 00008000 00000000 c47816e0 000b2b4a
7ea0: 000b3e2c c474de40 c7037f4c c7037f10 c003a8c0 c00c73bc c00c6108 c0539508
7ec0: c4786200 c05390b8 fffffff8 c7036000 00000001 c36d9000 c7037f0c c7037ee8
7ee0: c00c5b54 c010f434 c7034000 c701a000 00000001 c0510ff8 c4786200 00000000
7f00: c7037f4c c7037f10 c00c73bc c00c5ad0 c36d9034 c4772b40 00000000 c7034218
7f20: c0510ff8 c0510ff8 c0510f70 00000000 00000000 00000000 00000000 00000000
7f40: c7037f64 c7037f50 c00c7518 c00c6ef4 00000000 00000000 c7037f7c c7037f68
7f60: c0009558 c00c74f8 c054a640 c046dc24 c7037f94 c7037f80 c0009574 c0009540
7f80: c054a640 c03ac7bc c7037fac c7037f98 c03ac84c c0009570 c7036000 00000000
7fa0: 00000000 c7037fb0 c000a4a0 c03ac7cc 00000000 00000000 00000000 00000000
7fc0: 00000000 00000000 00000000 00000000 00000000 00000000 00000000 00000000
7fe0: 00000000 00000000 00000000 00000000 00000013 00000000 00000000 80000400
Backtrace:
[<c010dcd4>] (padzero) from [<c010fbb0>] (load_elf_binary+0x78c/0x1190)
[<c010f424>] (load_elf_binary) from [<c00c5b54>]
(search_binary_handler+0x94/0x24c)
 r10:c36d9000 r9:00000001 r8:c7036000 r7:fffffff8 r6:c05390b8 r5:c4786200
 r4:c0539508
[<c00c5ac0>] (search_binary_handler) from [<c00c73bc>]
(do_execveat_common+0x4d8/0x604)
 r9:00000000 r8:c4786200 r7:c0510ff8 r6:00000001 r5:c701a000 r4:c7034000
[<c00c6ee4>] (do_execveat_common) from [<c00c7518>] (do_execve+0x30/0x38)
 r10:00000000 r9:00000000 r8:00000000 r7:00000000 r6:00000000 r5:c0510f70
 r4:c0510ff8
[<c00c74e8>] (do_execve) from [<c0009558>] (run_init_process+0x28/0x30)
[<c0009530>] (run_init_process) from [<c0009574>]
(try_to_run_init_process+0x14/0x44)
 r5:c046dc24 r4:c054a640
[<c0009560>] (try_to_run_init_process) from [<c03ac84c>] (kernel_init+0x90/0xf4)
 r5:c03ac7bc r4:c054a640
[<c03ac7bc>] (kernel_init) from [<c000a4a0>] (ret_from_fork+0x14/0x34)
 r4:00000000 r3:c7036000
Code: ba00000d e210c003 0a000005 e35c0002 (e4e02001)
---[ end trace 613fb4181e192889 ]---
Kernel panic - not syncing: Attempted to kill init! exitcode=0x0000000b

---[ end Kernel panic - not syncing: Attempted to kill init! exitcode=0x0000000b

Reverting commit 0db805aa8c96 will allows me to boot up properly as it used to
work up to 4.2-rc8.

OMAP-L138 is ARM926EJ-S, the filesystem is built with buildroot
(arm926t/EABI/Soft float/ARM instruction set).

Using davinci_all_defconfig for the kernel.

Regards,
P?ter


From lee.jones at linaro.org  Wed Aug 26 00:12:36 2015
From: lee.jones at linaro.org (Lee Jones)
Date: Wed, 26 Aug 2015 08:12:36 +0100
Subject: [PATCH 1/7] dmaengine: st_fdma: Add STMicroelectronics FDMA DT
 binding documentation
In-Reply-To: <20150825170840.GA1498@griffinp-ThinkPad-X1-Carbon-2nd>
References: <1436371888-27863-1-git-send-email-peter.griffin@linaro.org>
 <1436371888-27863-2-git-send-email-peter.griffin@linaro.org>
 <20150819150605.GA13546@localhost>
 <20150825170840.GA1498@griffinp-ThinkPad-X1-Carbon-2nd>
Message-ID: <20150826071236.GS19409@x1>

On Tue, 25 Aug 2015, Peter Griffin wrote:

> Hi Vinod,
> 
> Thanks for reviewing.
> 
> On Wed, 19 Aug 2015, Vinod Koul wrote:
> 
> > On Wed, Jul 08, 2015 at 05:11:22PM +0100, Peter Griffin wrote:
> > > This patch adds the DT binding documentation for the FDMA constroller
> > > found on STi based chipsets from STMicroelectronics.
> > > 
> > > Signed-off-by: Ludovic Barre <ludovic.barre at st.com>
> > > Signed-off-by: Peter Griffin <peter.griffin at linaro.org>
> > > ---
> > >  Documentation/devicetree/bindings/dma/st_fdma.txt | 76 +++++++++++++++++++++++
> > >  1 file changed, 76 insertions(+)
> > >  create mode 100644 Documentation/devicetree/bindings/dma/st_fdma.txt
> > > 
> > > diff --git a/Documentation/devicetree/bindings/dma/st_fdma.txt b/Documentation/devicetree/bindings/dma/st_fdma.txt
> > > new file mode 100644
> > > index 0000000..1ec7470
> > > --- /dev/null
> > > +++ b/Documentation/devicetree/bindings/dma/st_fdma.txt
> > > @@ -0,0 +1,76 @@
> > > +* STMicroelectronics Flexible Direct Memory Access Device Tree bindings
> > > +
> > > +The FDMA is a general-purpose direct memory access controller capable of
> > > +supporting 16 independent DMA channels. It accepts up to 32 DMA requests.
> > > +The FDMA is based on a Slim processor which require a firmware.
> > > +
> > > +* FDMA Controller
> > > +
> > > +Required properties:
> > > +- compatible	: Should be "st,fdma_mpe31"
> > > +- reg		: Should contain DMA registers location and length
> > > +- interrupts	: Should contain one interrupt shared by all channel
> > 
> > s/channel/channels
> 
> Will fix in v2.
> 
> > 
> > > +- dma-channels	: Number of channels supported by the controller
> > > +- #dma-cells	: Must be <3>.
> > 
> > any reason three?
> 
> Yes, it is documented further down in the file under DMA Client.
> 
> To make it clearer in V2 I could change to
> 
> "- #dma-cells	: Must be <3>. See DMA client section below"?

- #dma-cells	: Must be <3>
			1st cell: Phandle to       ... <blah>
			2nd cell: DMA channel      ... <blah>
			3rd cell: Flags describing ... <blah>   

-- 
Lee Jones
Linaro STMicroelectronics Landing Team Lead
Linaro.org ? Open source software for ARM SoCs
Follow Linaro: Facebook | Twitter | Blog


From eddie.huang at mediatek.com  Wed Aug 26 00:14:41 2015
From: eddie.huang at mediatek.com (Eddie Huang)
Date: Wed, 26 Aug 2015 15:14:41 +0800
Subject: [PATCH v3] soc: mediatek: add scpsys support active_wakeup
Message-ID: <1440573281-28952-1-git-send-email-eddie.huang@mediatek.com>

Register gpd_dev_ops.active_wakeup function to support keep power
during suspend state. And add flag to each power domain to
decide whether keep power during suspend or not.

Signed-off-by: Chunfeng Yun <chunfeng.yun at mediatek.com>
Signed-off-by: Eddie Huang <eddie.huang at mediatek.com>
Acked-by: Sascha Hauer <s.hauer at pengutronix.de>
Reviewed-by: Daniel Kurtz <djkurtz at chromium.org>

---
Change in v3:
Remove check dev->power_domain NULL or ERR. This will not happen
when call scpsys_active_wakeup function

Change in v2:
Drop .active_wakeup = false lines in scp_domain_data[] array
---
 drivers/soc/mediatek/mtk-scpsys.c | 16 ++++++++++++++++
 1 file changed, 16 insertions(+)

diff --git a/drivers/soc/mediatek/mtk-scpsys.c b/drivers/soc/mediatek/mtk-scpsys.c
index 43a79ed..3a00975 100644
--- a/drivers/soc/mediatek/mtk-scpsys.c
+++ b/drivers/soc/mediatek/mtk-scpsys.c
@@ -67,6 +67,7 @@ struct scp_domain_data {
 	u32 sram_pdn_ack_bits;
 	u32 bus_prot_mask;
 	enum clk_id clk_id;
+	bool active_wakeup;
 };
 
 static const struct scp_domain_data scp_domain_data[] __initconst = {
@@ -127,6 +128,7 @@ static const struct scp_domain_data scp_domain_data[] __initconst = {
 		.sram_pdn_bits = GENMASK(11, 8),
 		.sram_pdn_ack_bits = GENMASK(15, 12),
 		.clk_id = MT8173_CLK_NONE,
+		.active_wakeup = true,
 	},
 	[MT8173_POWER_DOMAIN_MFG_ASYNC] = {
 		.name = "mfg_async",
@@ -171,6 +173,7 @@ struct scp_domain {
 	u32 sram_pdn_bits;
 	u32 sram_pdn_ack_bits;
 	u32 bus_prot_mask;
+	bool active_wakeup;
 };
 
 struct scp {
@@ -370,6 +373,17 @@ out:
 	return ret;
 }
 
+static bool scpsys_active_wakeup(struct device *dev)
+{
+	struct generic_pm_domain *genpd;
+	struct scp_domain *scpd;
+
+	genpd = pd_to_genpd(dev->pm_domain);
+	scpd = container_of(genpd, struct scp_domain, genpd);
+
+	return scpd->active_wakeup;
+}
+
 static int __init scpsys_probe(struct platform_device *pdev)
 {
 	struct genpd_onecell_data *pd_data;
@@ -427,12 +441,14 @@ static int __init scpsys_probe(struct platform_device *pdev)
 		scpd->sram_pdn_bits = data->sram_pdn_bits;
 		scpd->sram_pdn_ack_bits = data->sram_pdn_ack_bits;
 		scpd->bus_prot_mask = data->bus_prot_mask;
+		scpd->active_wakeup = data->active_wakeup;
 		if (data->clk_id != MT8173_CLK_NONE)
 			scpd->clk = clk[data->clk_id];
 
 		genpd->name = data->name;
 		genpd->power_off = scpsys_power_off;
 		genpd->power_on = scpsys_power_on;
+		genpd->dev_ops.active_wakeup = scpsys_active_wakeup;
 
 		/*
 		 * Initially turn on all domains to make the domains usable
-- 
1.9.1



From lee.jones at linaro.org  Wed Aug 26 00:30:41 2015
From: lee.jones at linaro.org (Lee Jones)
Date: Wed, 26 Aug 2015 08:30:41 +0100
Subject: [PATCH 2/3] ARM: DT: STi: STiH407: Add c8sectpfe LinuxDVB DT node.
In-Reply-To: <1440519730-486-3-git-send-email-peter.griffin@linaro.org>
References: <1440519730-486-1-git-send-email-peter.griffin@linaro.org>
 <1440519730-486-3-git-send-email-peter.griffin@linaro.org>
Message-ID: <20150826073041.GT19409@x1>

On Tue, 25 Aug 2015, Peter Griffin wrote:

> This patch adds in the required DT node for the c8sectpfe
> Linux DVB demux driver which allows the tsin channels
> to be used on an upstream kernel.
> 
> Signed-off-by: Peter Griffin <peter.griffin at linaro.org>
> ---
>  arch/arm/boot/dts/stihxxx-b2120.dtsi | 38 ++++++++++++++++++++++++++++++++++++
>  1 file changed, 38 insertions(+)
> 
> diff --git a/arch/arm/boot/dts/stihxxx-b2120.dtsi b/arch/arm/boot/dts/stihxxx-b2120.dtsi
> index 62994ae..1bc018e 100644
> --- a/arch/arm/boot/dts/stihxxx-b2120.dtsi
> +++ b/arch/arm/boot/dts/stihxxx-b2120.dtsi
> @@ -6,6 +6,10 @@
>   * it under the terms of the GNU General Public License version 2 as
>   * published by the Free Software Foundation.
>   */
> +
> +#include <dt-bindings/clock/stih407-clks.h>
> +#include <dt-bindings/media/c8sectpfe.h>
> +

Looks like some of the STi files are a little wavering on convention,
but I suggest the extra '\n's are superfluous.

>  / {
>  	soc {
>  		sbc_serial0: serial at 9530000 {
> @@ -85,5 +89,39 @@
>  			status = "okay";
>  		};
>  
> +		c8sectpfe at 08a20000 {

This should be a device type, not a model number.

demodulator at abcdabcd {

> +			compatible = "st,stih407-c8sectpfe";

To the uninitiated c8sectpfe is pretty indecipherable.

How about *-c8sectpfe-demod?

> +			status = "okay";
> +			reg = <0x08a20000 0x10000>, <0x08a00000 0x4000>;
> +			reg-names = "c8sectpfe", "c8sectpfe-ram";
> +
> +			interrupts = <0 34 0>, <0 35 0>;

Please use the predetermined DEFINES for the flags cell.

> +			interrupt-names = "c8sectpfe-error-irq",
> +					  "c8sectpfe-idle-irq";
> +
> +			pinctrl-names	= "tsin0-serial", "tsin0-parallel",
> +					  "tsin3-serial", "tsin4-serial",
> +					  "tsin5-serial";

I would put *-names *under* the properties they pertain to and in the
same format i.e. one per line in this case, for easy eye-match.

> +			pinctrl-0	= <&pinctrl_tsin0_serial>;
> +			pinctrl-1	= <&pinctrl_tsin0_parallel>;
> +			pinctrl-2	= <&pinctrl_tsin3_serial>;
> +			pinctrl-3	= <&pinctrl_tsin4_serial_alt3>;
> +			pinctrl-4	= <&pinctrl_tsin5_serial_alt1>;
> +
> +			clocks = <&clk_s_c0_flexgen CLK_PROC_STFE>;
> +			clock-names = "c8sectpfe";
> +
> +			/* tsin0 is TSA on NIMA */
> +			tsin0: port at 0 {
> +

Why the '\n'?

> +				tsin-num = <0>;
> +				serial-not-parallel;
> +				i2c-bus = <&ssc2>;

If you are adding this property, I would get Wolfram or one of the DT
guys to Ack it.

> +				rst-gpio = <&pio15 4 0>;

Why not use the whole name "reset"?

"-gpio" should be "-gpios".

So, in full: "reset-gpios"?

Flags: GPIO_ACTIVE_HIGH ?

> +				dvb-card = <STV0367_TDA18212_NIMA_1>;
> +			};
> +		};
>  	};
>  };

-- 
Lee Jones
Linaro STMicroelectronics Landing Team Lead
Linaro.org ? Open source software for ARM SoCs
Follow Linaro: Facebook | Twitter | Blog


From linus.walleij at linaro.org  Wed Aug 26 00:32:55 2015
From: linus.walleij at linaro.org (Linus Walleij)
Date: Wed, 26 Aug 2015 09:32:55 +0200
Subject: [PATCH] pinctrl: at91: Use generic irq_{request,
 release}_resources()
In-Reply-To: <1439818336-31230-1-git-send-email-geert+renesas@glider.be>
References: <1439818336-31230-1-git-send-email-geert+renesas@glider.be>
Message-ID: <CACRpkdbPt4rZF0gvsCkz20qftRCkMeiZ0vP-OOn2SEjFuEFcPg@mail.gmail.com>

On Mon, Aug 17, 2015 at 3:32 PM, Geert Uytterhoeven
<geert+renesas at glider.be> wrote:

> The at91-specific irq_{request,release}_resources() callbacks are
> identical to the generic ones, modulo the bug fix in 5b76e79c77264899
> ("gpiolib: irqchip: prevent driver unloading if gpio is used as irq
> only").
>
> Until commit 8b67a1f0ad1f260f ("gpio: don't override irq_*_resources()
> callbacks"), the buggy at91-specific callbacks were never used, though.
>
> Hence drop the at91-specific ones in favor of the generic ones.
>
> Signed-off-by: Geert Uytterhoeven <geert+renesas at glider.be>
> ---
> Compile-tested only.

Right thing to do so patch applied.

Yours,
Linus Walleij


From lee.jones at linaro.org  Wed Aug 26 00:33:51 2015
From: lee.jones at linaro.org (Lee Jones)
Date: Wed, 26 Aug 2015 08:33:51 +0100
Subject: [PATCH 6/7] MAINTAINERS: Add FDMA driver files to STi section.
In-Reply-To: <1436371888-27863-7-git-send-email-peter.griffin@linaro.org>
References: <1436371888-27863-1-git-send-email-peter.griffin@linaro.org>
 <1436371888-27863-7-git-send-email-peter.griffin@linaro.org>
Message-ID: <20150826073351.GU19409@x1>

On Wed, 08 Jul 2015, Peter Griffin wrote:

> This patch adds the FDMA driver files to the STi
> section of the maintainers file.
> 
> Signed-off-by: Peter Griffin <peter.griffin at linaro.org>
> ---
>  MAINTAINERS | 2 ++
>  1 file changed, 2 insertions(+)
> 
> diff --git a/MAINTAINERS b/MAINTAINERS
> index 8133cef..8cb1ad9 100644
> --- a/MAINTAINERS
> +++ b/MAINTAINERS
> @@ -1503,6 +1503,8 @@ S:	Maintained
>  F:	arch/arm/mach-sti/
>  F:	arch/arm/boot/dts/sti*
>  F:	drivers/clocksource/arm_global_timer.c
> +F:	drivers/dma/st_fdma.*
> +F:	drivers/dma/st_fdma_xbar.c

How about you replace both lines with:

F:	drivers/dma/st_fdma*

>  F:	drivers/i2c/busses/i2c-st.c
>  F:	drivers/media/rc/st_rc.c
>  F:	drivers/mmc/host/sdhci-st.c

-- 
Lee Jones
Linaro STMicroelectronics Landing Team Lead
Linaro.org ? Open source software for ARM SoCs
Follow Linaro: Facebook | Twitter | Blog


From daniel.lezcano at linaro.org  Wed Aug 26 00:37:40 2015
From: daniel.lezcano at linaro.org (Daniel Lezcano)
Date: Wed, 26 Aug 2015 09:37:40 +0200
Subject: [PATCH 0/5] add GPT timer support for mt8173
In-Reply-To: <1436779969-18610-1-git-send-email-yingjoe.chen@mediatek.com>
References: <1436779969-18610-1-git-send-email-yingjoe.chen@mediatek.com>
Message-ID: <55DD6CC4.6010708@linaro.org>

On 07/13/2015 11:32 AM, Yingjoe Chen wrote:
> This series add GPT timer support for mt8173. This is based on v4.2-rc1
> and Matthias' next branch (for dts parts).
>
> The first 2 patches comes from 'Add SMP bringup support for mt65xx socs'
> series [1]. I decide to move these 2 patches to this series, since it
> is more relevent here. They are changed based on Matthias' and Daniel's
> comments.
>
> [1] http://lists.infradead.org/pipermail/linux-mediatek/2015-May/000714.html
>
> Daniel Kurtz (1):
>    arm64: dts: mt8173: add timer node
>
> Yingjoe Chen (4):
>    clocksource: mediatek: do not enable GPT_CLK_EVT when setup
>    clocksource: mediatek: Use GPT as sched clock source
>    arm64: mediatek: enable MTK_TIMER
>    clk: mediatek: add 13mhz clock for MT8173
>
>   arch/arm64/Kconfig                       |  1 +
>   arch/arm64/boot/dts/mediatek/mt8173.dtsi |  9 +++++++++
>   drivers/clk/mediatek/clk-mt8173.c        |  5 +++++
>   drivers/clocksource/mtk_timer.c          | 26 ++++++++++++++++++++------
>   include/dt-bindings/clock/mt8173-clk.h   |  3 ++-
>   5 files changed, 37 insertions(+), 7 deletions(-)

Who will take this patchset ? I can take the patch 2 if needed.


-- 
  <http://www.linaro.org/> Linaro.org ? Open source software for ARM SoCs

Follow Linaro:  <http://www.facebook.com/pages/Linaro> Facebook |
<http://twitter.com/#!/linaroorg> Twitter |
<http://www.linaro.org/linaro-blog/> Blog



From lee.jones at linaro.org  Wed Aug 26 00:46:20 2015
From: lee.jones at linaro.org (Lee Jones)
Date: Wed, 26 Aug 2015 08:46:20 +0100
Subject: [PATCH 5/7] ARM: STi: DT: STiH407: Add FDMA driver and xbar
 driver dt nodes.
In-Reply-To: <1436371888-27863-6-git-send-email-peter.griffin@linaro.org>
References: <1436371888-27863-1-git-send-email-peter.griffin@linaro.org>
 <1436371888-27863-6-git-send-email-peter.griffin@linaro.org>
Message-ID: <20150826074620.GV19409@x1>

On Wed, 08 Jul 2015, Peter Griffin wrote:

> These nodes are required to get the fdma and xbar driver working
> on STiH407 based silicon.
> 
> Signed-off-by: Peter Griffin <peter.griffin at linaro.org>
> ---
>  arch/arm/boot/dts/stih407-family.dtsi | 59 +++++++++++++++++++++++++++++++++++
>  1 file changed, 59 insertions(+)
> 
> diff --git a/arch/arm/boot/dts/stih407-family.dtsi b/arch/arm/boot/dts/stih407-family.dtsi
> index 838b812..b6d9e20 100644
> --- a/arch/arm/boot/dts/stih407-family.dtsi
> +++ b/arch/arm/boot/dts/stih407-family.dtsi
> @@ -565,5 +565,64 @@
>  						  <&phy_port2 PHY_TYPE_USB3>;
>  			};
>  		};
> +
> +		xbar0: fdma-xbar-mpe at 0 {

The unit address should match the one in the reg property.

> +			compatible = "st,fdma-xbar-1.0";

Is that a version number in the compatible string?

> +			reg = <0x8e80000 0x1000>;
> +			dma-requests = <79>;
> +			#st,fdma-xbar-cells = <1>;

Why can't FDMA use the generic DMA properties?

> +		};
> +
> +		fdma0: fdma-audio at 0 {

Same comment as above.

> +			compatible = "st,fdma_mpe31";

DT doesn't usually like underscores.

> +			reg = <0x8e20000 0x20000>;
> +			interrupts = <GIC_SPI 5 IRQ_TYPE_NONE>;
> +			dma-channels = <16>;
> +			#dma-cells = <3>;
> +			st,fw-name = "fdma_STiH407_0.elf";

I've bought this up before somewhere (although there doesn't appear to
be a Firmware Maintainer), surely we should define a generic binding
for passing firmware names?  Many vendors are going to require it.

> +			clocks = <&clk_s_c0_flexgen CLK_FDMA>,
> +				 <&clk_s_c0_flexgen CLK_EXT2F_A9>,
> +				 <&clk_s_c0_flexgen CLK_EXT2F_A9>,
> +				 <&clk_s_c0_flexgen CLK_EXT2F_A9>;
> +			clock-names = "fdma_slim",
> +				      "fdma_hi",
> +				      "fdma_low",
> +				      "fdma_ic";
> +		};
> +
> +		fdma1: fdma-app at 1 {

As above.

> +			compatible = "st,fdma_mpe31";

As above.

> +			reg = <0x8e40000 0x20000>;
> +			interrupts = <GIC_SPI 7 IRQ_TYPE_NONE>;
> +			dma-channels = <16>;
> +			#dma-cells = <3>;
> +			st,fdma-xbar = <&xbar0 0>;
> +			st,fw-name = "fdma_STiH407_1.elf";
> +			clocks = <&clk_s_c0_flexgen CLK_FDMA>,
> +				 <&clk_s_c0_flexgen CLK_TX_ICN_DMU>,
> +				 <&clk_s_c0_flexgen CLK_TX_ICN_DMU>,
> +				 <&clk_s_c0_flexgen CLK_EXT2F_A9>;
> +			clock-names = "fdma_slim",
> +				      "fdma_hi",
> +				      "fdma_low",
> +				      "fdma_ic";
> +		};
> +
> +		fdma2: fdma-free_running at 2 {
> +			compatible = "st,fdma_mpe31";
> +			reg = <0x8e60000 0x20000>;
> +			interrupts = <GIC_SPI 9 IRQ_TYPE_NONE>;
> +			dma-channels = <16>;
> +			#dma-cells = <3>;
> +			st,fw-name = "fdma_STiH407_2.elf";
> +			clocks = <&clk_s_c0_flexgen CLK_FDMA>,
> +				 <&clk_s_c0_flexgen CLK_EXT2F_A9>,
> +				 <&clk_s_c0_flexgen CLK_TX_ICN_DISP_0>,
> +				 <&clk_s_c0_flexgen CLK_EXT2F_A9>;
> +			clock-names = "fdma_slim",
> +				      "fdma_hi",
> +				      "fdma_low",
> +				      "fdma_ic";
> +		};
>  	};
>  };

-- 
Lee Jones
Linaro STMicroelectronics Landing Team Lead
Linaro.org ? Open source software for ARM SoCs
Follow Linaro: Facebook | Twitter | Blog


From peter.ujfalusi at ti.com  Wed Aug 26 01:05:30 2015
From: peter.ujfalusi at ti.com (Peter Ujfalusi)
Date: Wed, 26 Aug 2015 11:05:30 +0300
Subject: ARM: davinci: linux-next: Boot failure on OMAP-L138 with commit
 0db805aa8c96
In-Reply-To: <55DD6621.20907@ti.com>
References: <55DD6621.20907@ti.com>
Message-ID: <55DD734A.1030008@ti.com>

On 08/26/2015 10:09 AM, Peter Ujfalusi wrote:
> Hi Russell,
> 
> with next-20150825 I have the following kernel panic:

next-20150826 is fine, please ignore this report.

--
P?ter

> RAMDISK: cramfs filesystem found at block 0
> RAMDISK: Loading 7412KiB [1 disk] into ram disk... done.
> VFS: Mounted root (cramfs filesystem) readonly on device 1:0.
> devtmpfs: mounted
> Freeing unused kernel memory: 200K (c04de000 - c0510000)
> Unhandled fault: page domain fault (0x01b) at 0xb6f306a0
> pgd = c64e0000
> [b6f306a0] *pgd=c5a2e831, *pte=c76e718b, *ppte=c76e7aaa
> Internal error: : 1b [#1] PREEMPT ARM
> Modules linked in:
> CPU: 0 PID: 1 Comm: init Not tainted 4.2.0-rc8-next-20150825 #19
> Hardware name: DaVinci DA850/OMAP-L138/AM18x EVM
> task: c7034000 ti: c7036000 task.ti: c7036000
> PC is at not_thumb+0x0/0x18
> LR is at __dabt_usr+0x50/0x60
> pc : [<c00130b8>]    lr : [<c000e290>]    psr: 40000093
> sp : c7037fb0  ip : 00000051  fp : 00000000
> r10: 00000000  r9 : 00000000  r8 : 00053177
> r7 : 0005317f  r6 : ffffffff  r5 : 60000010  r4 : b6f306a0
> r3 : becacd60  r2 : c7037fb0  r1 : 00000017  r0 : b6f38f70
> Flags: nZcv  IRQs off  FIQs on  Mode SVC_32  ISA ARM  Segment none
> Control: 0005317f  Table: c64e0000  DAC: 00000051
> Process init (pid: 1, stack limit = 0xc7036190)
> Stack: (0xc7037fb0 to 0xc7038000)
> 7fa0:                                     ???????? ???????? ???????? ????????
> 7fc0: ???????? ???????? ???????? ???????? ???????? ???????? ???????? ????????
> 7fe0: ???????? ???????? ???????? ???????? ???????? ???????? ???????? ????????
> Backtrace: no frame pointer
> Code: bad PC value
> ---[ end trace 8cb5f050de571f06 ]---
> Kernel panic - not syncing: Attempted to kill init! exitcode=0x0000000b
> 
> ---[ end Kernel panic - not syncing: Attempted to kill init! exitcode=0x0000000b
> 
> bisect points me to the following commit:
> 0db805aa8c96 ARM: software-based priviledged-no-access support
> 
> If I disable the CONFIG_CPU_SW_DOMAIN_PAN, I will have:
> 
> RAMDISK: cramfs filesystem found at block 0
> RAMDISK: Loading 7412KiB [1 disk] into ram disk... done.
> VFS: Mounted root (cramfs filesystem) readonly on device 1:0.
> devtmpfs: mounted
> Freeing unused kernel memory: 204K (c04d9000 - c050c000)
> Unhandled fault: page domain fault (0x81b) at 0x000b2b4a
> pgd = c36d4000
> [000b2b4a] *pgd=c36c5831, *pte=c050a14b, *ppte=c050affa
> Internal error: : 81b [#1] PREEMPT ARM
> Modules linked in:
> CPU: 0 PID: 1 Comm: init Not tainted 4.2.0-rc8-next-20150825 #21
> Hardware name: DaVinci DA850/OMAP-L138/AM18x EVM
> task: c7034000 ti: c7036000 task.ti: c7036000
> PC is at __clear_user_std+0x1c/0x68
> LR is at padzero+0x54/0x60
> pc : [<c01e607c>]    lr : [<c010dd28>]    psr: 60000013
> sp : c7037e48  ip : 00000002  fp : c7037e5c
> r10: c70800a0  r9 : c47816e0  r8 : c4786300
> r7 : c7037e60  r6 : 00000000  r5 : c4786200  r4 : c46e6100
> r3 : 00000000  r2 : 00000000  r1 : 000004b6  r0 : 000b2b4a
> Flags: nZCv  IRQs on  FIQs on  Mode SVC_32  ISA ARM  Segment none
> Control: 0005317f  Table: c36d4000  DAC: 00000051
> Process init (pid: 1, stack limit = 0xc7036190)
> Stack: (0xc7037e48 to 0xc7038000)
> 7e40:                   000004b6 c010dd28 c7037ee4 c7037e60 c010fbb0 c010dce4
> 7e60: 00001812 00000000 00000000 00000000 c7037e60 00000000 c7036000 c4786200
> 7e80: 00008000 000b2b4a 000b2500 000aa500 00008000 00000000 c47816e0 000b2b4a
> 7ea0: 000b3e2c c474de40 c7037f4c c7037f10 c003a8c0 c00c73bc c00c6108 c0539508
> 7ec0: c4786200 c05390b8 fffffff8 c7036000 00000001 c36d9000 c7037f0c c7037ee8
> 7ee0: c00c5b54 c010f434 c7034000 c701a000 00000001 c0510ff8 c4786200 00000000
> 7f00: c7037f4c c7037f10 c00c73bc c00c5ad0 c36d9034 c4772b40 00000000 c7034218
> 7f20: c0510ff8 c0510ff8 c0510f70 00000000 00000000 00000000 00000000 00000000
> 7f40: c7037f64 c7037f50 c00c7518 c00c6ef4 00000000 00000000 c7037f7c c7037f68
> 7f60: c0009558 c00c74f8 c054a640 c046dc24 c7037f94 c7037f80 c0009574 c0009540
> 7f80: c054a640 c03ac7bc c7037fac c7037f98 c03ac84c c0009570 c7036000 00000000
> 7fa0: 00000000 c7037fb0 c000a4a0 c03ac7cc 00000000 00000000 00000000 00000000
> 7fc0: 00000000 00000000 00000000 00000000 00000000 00000000 00000000 00000000
> 7fe0: 00000000 00000000 00000000 00000000 00000013 00000000 00000000 80000400
> Backtrace:
> [<c010dcd4>] (padzero) from [<c010fbb0>] (load_elf_binary+0x78c/0x1190)
> [<c010f424>] (load_elf_binary) from [<c00c5b54>]
> (search_binary_handler+0x94/0x24c)
>  r10:c36d9000 r9:00000001 r8:c7036000 r7:fffffff8 r6:c05390b8 r5:c4786200
>  r4:c0539508
> [<c00c5ac0>] (search_binary_handler) from [<c00c73bc>]
> (do_execveat_common+0x4d8/0x604)
>  r9:00000000 r8:c4786200 r7:c0510ff8 r6:00000001 r5:c701a000 r4:c7034000
> [<c00c6ee4>] (do_execveat_common) from [<c00c7518>] (do_execve+0x30/0x38)
>  r10:00000000 r9:00000000 r8:00000000 r7:00000000 r6:00000000 r5:c0510f70
>  r4:c0510ff8
> [<c00c74e8>] (do_execve) from [<c0009558>] (run_init_process+0x28/0x30)
> [<c0009530>] (run_init_process) from [<c0009574>]
> (try_to_run_init_process+0x14/0x44)
>  r5:c046dc24 r4:c054a640
> [<c0009560>] (try_to_run_init_process) from [<c03ac84c>] (kernel_init+0x90/0xf4)
>  r5:c03ac7bc r4:c054a640
> [<c03ac7bc>] (kernel_init) from [<c000a4a0>] (ret_from_fork+0x14/0x34)
>  r4:00000000 r3:c7036000
> Code: ba00000d e210c003 0a000005 e35c0002 (e4e02001)
> ---[ end trace 613fb4181e192889 ]---
> Kernel panic - not syncing: Attempted to kill init! exitcode=0x0000000b
> 
> ---[ end Kernel panic - not syncing: Attempted to kill init! exitcode=0x0000000b
> 
> Reverting commit 0db805aa8c96 will allows me to boot up properly as it used to
> work up to 4.2-rc8.
> 
> OMAP-L138 is ARM926EJ-S, the filesystem is built with buildroot
> (arm926t/EABI/Soft float/ARM instruction set).
> 
> Using davinci_all_defconfig for the kernel.
> 
> Regards,
> P?ter
> 
> _______________________________________________
> linux-arm-kernel mailing list
> linux-arm-kernel at lists.infradead.org
> http://lists.infradead.org/mailman/listinfo/linux-arm-kernel
> 




From ard.biesheuvel at linaro.org  Wed Aug 26 01:06:26 2015
From: ard.biesheuvel at linaro.org (Ard Biesheuvel)
Date: Wed, 26 Aug 2015 10:06:26 +0200
Subject: [PATCH v2 0/5] arm64 UEFI early FDT handling
Message-ID: <1440576391-25725-1-git-send-email-ard.biesheuvel@linaro.org>

This is a followup to the "arm64: update/clarify/relax Image and FDT placement
rules" series I sent a while ago:
(http://article.gmane.org/gmane.linux.ports.arm.kernel/407148)

This has now been split in two series: this first series deals with the
early FDT handling, primarily in the context of UEFI, but not exclusively.

A number of minor issues exist in the early UEFI/FDT handling path, such as:
- when booting via UEFI, memreserve entries are removed from the device tree but
  the /reserved-memory node is not
- memory nodes are removed from the device tree in a way that is not officially
  supported by the libfdt API (i.e., you cannot delete nodes while traversing
  the tree)
- removal of memory nodes may discard annotations (such as NUMA topology) that
  should ideally be retained, or may corrupt the tree by discarding nodes
  referenced by phandles.

Patch #1 introduces an arm64 specific version of early_init_dt_add_memory_arch()
so that we can modify it later to ignore DT memory nodes if booting via UEFI.

Patch #2 moves some UEFI+FDT init code around before making changes to it.

Patch #3 moves the UEFI initialization to before the early FDT scanning so we
know at that point whether we are booting via UEFI or not.

Patch #4 changes the UEFI init code so that memory nodes are simply ignored, so
that they don't have to be removed by the stub anymore.

Patch #5 does the same as #6, but for memreserves and the /reserved-memory
node.

Changes since v1:
- dropped first two patches, they have been merged into v4.2-rc1
- dropped last patch regarding FDT placement by the stub, this is not entirely
  relevant to the primary issue targeted by this series
- rebased onto for-next/core (arm64) as of today

Ard Biesheuvel (5):
  arm64: clone early_init_dt_add_memory_arch() to override default
  efi: move FDT handling to separate object file
  arm64/efi: move EFI init before early FDT processing
  arm64/efi: ignore DT memory nodes instead of removing them
  arm64/efi: ignore DT memreserve entries instead of removing them

 arch/arm64/include/asm/efi.h       |  4 +-
 arch/arm64/kernel/efi.c            | 14 +---
 arch/arm64/kernel/setup.c          |  4 +-
 arch/arm64/mm/init.c               | 54 +++++++++++-
 drivers/firmware/efi/Makefile      |  1 +
 drivers/firmware/efi/efi-fdt.c     | 77 ++++++++++++++++++
 drivers/firmware/efi/efi.c         | 86 --------------------
 drivers/firmware/efi/libstub/fdt.c | 33 +-------
 include/linux/efi.h                |  3 +-
 9 files changed, 143 insertions(+), 133 deletions(-)
 create mode 100644 drivers/firmware/efi/efi-fdt.c

-- 
1.9.1



From ard.biesheuvel at linaro.org  Wed Aug 26 01:06:27 2015
From: ard.biesheuvel at linaro.org (Ard Biesheuvel)
Date: Wed, 26 Aug 2015 10:06:27 +0200
Subject: [PATCH v2 1/5] arm64: clone early_init_dt_add_memory_arch() to
 override default
In-Reply-To: <1440576391-25725-1-git-send-email-ard.biesheuvel@linaro.org>
References: <1440576391-25725-1-git-send-email-ard.biesheuvel@linaro.org>
Message-ID: <1440576391-25725-2-git-send-email-ard.biesheuvel@linaro.org>

Override the __weak early_init_dt_add_memory_arch() with our own
version. We need this in a subsequent patch to make the handling of
the memory nodes conditional on whether we are booting via UEFI or
not.

Signed-off-by: Ard Biesheuvel <ard.biesheuvel at linaro.org>
---
 arch/arm64/mm/init.c | 41 ++++++++++++++++++++
 1 file changed, 41 insertions(+)

diff --git a/arch/arm64/mm/init.c b/arch/arm64/mm/init.c
index f5c0680d17d9..ab25fde7397c 100644
--- a/arch/arm64/mm/init.c
+++ b/arch/arm64/mm/init.c
@@ -374,3 +374,44 @@ static int __init keepinitrd_setup(char *__unused)
 
 __setup("keepinitrd", keepinitrd_setup);
 #endif
+
+void __init early_init_dt_add_memory_arch(u64 base, u64 size)
+{
+	const u64 phys_offset = __pa(PAGE_OFFSET);
+
+	if (!PAGE_ALIGNED(base)) {
+		if (size < PAGE_SIZE - (base & ~PAGE_MASK)) {
+			pr_warn("Ignoring memory block 0x%llx - 0x%llx\n",
+				base, base + size);
+			return;
+		}
+		size -= PAGE_SIZE - (base & ~PAGE_MASK);
+		base = PAGE_ALIGN(base);
+	}
+	size &= PAGE_MASK;
+
+	if (base > MAX_MEMBLOCK_ADDR) {
+		pr_warning("Ignoring memory block 0x%llx - 0x%llx\n",
+				base, base + size);
+		return;
+	}
+
+	if (base + size - 1 > MAX_MEMBLOCK_ADDR) {
+		pr_warning("Ignoring memory range 0x%llx - 0x%llx\n",
+				((u64)MAX_MEMBLOCK_ADDR) + 1, base + size);
+		size = MAX_MEMBLOCK_ADDR - base + 1;
+	}
+
+	if (base + size < phys_offset) {
+		pr_warning("Ignoring memory block 0x%llx - 0x%llx\n",
+			   base, base + size);
+		return;
+	}
+	if (base < phys_offset) {
+		pr_warning("Ignoring memory range 0x%llx - 0x%llx\n",
+			   base, phys_offset);
+		size -= phys_offset - base;
+		base = phys_offset;
+	}
+	memblock_add(base, size);
+}
-- 
1.9.1



From ard.biesheuvel at linaro.org  Wed Aug 26 01:06:28 2015
From: ard.biesheuvel at linaro.org (Ard Biesheuvel)
Date: Wed, 26 Aug 2015 10:06:28 +0200
Subject: [PATCH v2 2/5] efi: move FDT handling to separate object file
In-Reply-To: <1440576391-25725-1-git-send-email-ard.biesheuvel@linaro.org>
References: <1440576391-25725-1-git-send-email-ard.biesheuvel@linaro.org>
Message-ID: <1440576391-25725-3-git-send-email-ard.biesheuvel@linaro.org>

The EFI specific FDT handling is compiled conditionally, and is
logically independent of the rest of efi.o. So move it to a separate
file before making changes to it in subsequent patches.

Acked-by: Matt Fleming <matt.fleming at intel.com>
Signed-off-by: Ard Biesheuvel <ard.biesheuvel at linaro.org>
---
 drivers/firmware/efi/Makefile  |  1 +
 drivers/firmware/efi/efi-fdt.c | 93 ++++++++++++++++++++
 drivers/firmware/efi/efi.c     | 86 ------------------
 3 files changed, 94 insertions(+), 86 deletions(-)

diff --git a/drivers/firmware/efi/Makefile b/drivers/firmware/efi/Makefile
index 6fd3da938717..d9140208fc1c 100644
--- a/drivers/firmware/efi/Makefile
+++ b/drivers/firmware/efi/Makefile
@@ -9,3 +9,4 @@ obj-$(CONFIG_UEFI_CPER)			+= cper.o
 obj-$(CONFIG_EFI_RUNTIME_MAP)		+= runtime-map.o
 obj-$(CONFIG_EFI_RUNTIME_WRAPPERS)	+= runtime-wrappers.o
 obj-$(CONFIG_EFI_STUB)			+= libstub/
+obj-$(CONFIG_EFI_PARAMS_FROM_FDT)	+= efi-fdt.o
diff --git a/drivers/firmware/efi/efi-fdt.c b/drivers/firmware/efi/efi-fdt.c
new file mode 100644
index 000000000000..f0e7ef2ae0e9
--- /dev/null
+++ b/drivers/firmware/efi/efi-fdt.c
@@ -0,0 +1,93 @@
+/*
+ * Copyright (C) 2013 - 2015 Linaro Ltd.
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License version 2 as
+ * published by the Free Software Foundation.
+ */
+
+#include <linux/init.h>
+#include <linux/efi.h>
+#include <linux/of.h>
+#include <linux/of_fdt.h>
+
+#define UEFI_PARAM(name, prop, field)			   \
+	{						   \
+		{ name },				   \
+		{ prop },				   \
+		offsetof(struct efi_fdt_params, field),    \
+		FIELD_SIZEOF(struct efi_fdt_params, field) \
+	}
+
+static __initdata struct {
+	const char name[32];
+	const char propname[32];
+	int offset;
+	int size;
+} dt_params[] = {
+	UEFI_PARAM("System Table", "linux,uefi-system-table", system_table),
+	UEFI_PARAM("MemMap Address", "linux,uefi-mmap-start", mmap),
+	UEFI_PARAM("MemMap Size", "linux,uefi-mmap-size", mmap_size),
+	UEFI_PARAM("MemMap Desc. Size", "linux,uefi-mmap-desc-size", desc_size),
+	UEFI_PARAM("MemMap Desc. Version", "linux,uefi-mmap-desc-ver", desc_ver)
+};
+
+struct param_info {
+	int verbose;
+	int found;
+	void *params;
+};
+
+static int __init fdt_find_uefi_params(unsigned long node, const char *uname,
+				       int depth, void *data)
+{
+	struct param_info *info = data;
+	const void *prop;
+	void *dest;
+	u64 val;
+	int i, len;
+
+	if (depth != 1 || strcmp(uname, "chosen") != 0)
+		return 0;
+
+	for (i = 0; i < ARRAY_SIZE(dt_params); i++) {
+		prop = of_get_flat_dt_prop(node, dt_params[i].propname, &len);
+		if (!prop)
+			return 0;
+		dest = info->params + dt_params[i].offset;
+		info->found++;
+
+		val = of_read_number(prop, len / sizeof(u32));
+
+		if (dt_params[i].size == sizeof(u32))
+			*(u32 *)dest = val;
+		else
+			*(u64 *)dest = val;
+
+		if (info->verbose)
+			pr_info("  %s: 0x%0*llx\n", dt_params[i].name,
+				dt_params[i].size * 2, val);
+	}
+	return 1;
+}
+
+int __init efi_get_fdt_params(struct efi_fdt_params *params, int verbose)
+{
+	struct param_info info;
+	int ret;
+
+	pr_info("Getting EFI parameters from FDT:\n");
+
+	info.verbose = verbose;
+	info.found = 0;
+	info.params = params;
+
+	ret = of_scan_flat_dt(fdt_find_uefi_params, &info);
+	if (!info.found)
+		pr_info("UEFI not found.\n");
+	else if (!ret)
+		pr_err("Can't find '%s' in device tree!\n",
+		       dt_params[info.found].name);
+
+	return ret;
+}
diff --git a/drivers/firmware/efi/efi.c b/drivers/firmware/efi/efi.c
index 9fa8084a7c8d..f975a1a45b80 100644
--- a/drivers/firmware/efi/efi.c
+++ b/drivers/firmware/efi/efi.c
@@ -20,8 +20,6 @@
 #include <linux/init.h>
 #include <linux/device.h>
 #include <linux/efi.h>
-#include <linux/of.h>
-#include <linux/of_fdt.h>
 #include <linux/io.h>
 #include <linux/platform_device.h>
 
@@ -460,90 +458,6 @@ static int __init efi_load_efivars(void)
 device_initcall(efi_load_efivars);
 #endif
 
-#ifdef CONFIG_EFI_PARAMS_FROM_FDT
-
-#define UEFI_PARAM(name, prop, field)			   \
-	{						   \
-		{ name },				   \
-		{ prop },				   \
-		offsetof(struct efi_fdt_params, field),    \
-		FIELD_SIZEOF(struct efi_fdt_params, field) \
-	}
-
-static __initdata struct {
-	const char name[32];
-	const char propname[32];
-	int offset;
-	int size;
-} dt_params[] = {
-	UEFI_PARAM("System Table", "linux,uefi-system-table", system_table),
-	UEFI_PARAM("MemMap Address", "linux,uefi-mmap-start", mmap),
-	UEFI_PARAM("MemMap Size", "linux,uefi-mmap-size", mmap_size),
-	UEFI_PARAM("MemMap Desc. Size", "linux,uefi-mmap-desc-size", desc_size),
-	UEFI_PARAM("MemMap Desc. Version", "linux,uefi-mmap-desc-ver", desc_ver)
-};
-
-struct param_info {
-	int verbose;
-	int found;
-	void *params;
-};
-
-static int __init fdt_find_uefi_params(unsigned long node, const char *uname,
-				       int depth, void *data)
-{
-	struct param_info *info = data;
-	const void *prop;
-	void *dest;
-	u64 val;
-	int i, len;
-
-	if (depth != 1 || strcmp(uname, "chosen") != 0)
-		return 0;
-
-	for (i = 0; i < ARRAY_SIZE(dt_params); i++) {
-		prop = of_get_flat_dt_prop(node, dt_params[i].propname, &len);
-		if (!prop)
-			return 0;
-		dest = info->params + dt_params[i].offset;
-		info->found++;
-
-		val = of_read_number(prop, len / sizeof(u32));
-
-		if (dt_params[i].size == sizeof(u32))
-			*(u32 *)dest = val;
-		else
-			*(u64 *)dest = val;
-
-		if (info->verbose)
-			pr_info("  %s: 0x%0*llx\n", dt_params[i].name,
-				dt_params[i].size * 2, val);
-	}
-	return 1;
-}
-
-int __init efi_get_fdt_params(struct efi_fdt_params *params, int verbose)
-{
-	struct param_info info;
-	int ret;
-
-	pr_info("Getting EFI parameters from FDT:\n");
-
-	info.verbose = verbose;
-	info.found = 0;
-	info.params = params;
-
-	ret = of_scan_flat_dt(fdt_find_uefi_params, &info);
-	if (!info.found)
-		pr_info("UEFI not found.\n");
-	else if (!ret)
-		pr_err("Can't find '%s' in device tree!\n",
-		       dt_params[info.found].name);
-
-	return ret;
-}
-#endif /* CONFIG_EFI_PARAMS_FROM_FDT */
-
 static __initdata char memory_type_name[][20] = {
 	"Reserved",
 	"Loader Code",
-- 
1.9.1



From ard.biesheuvel at linaro.org  Wed Aug 26 01:06:30 2015
From: ard.biesheuvel at linaro.org (Ard Biesheuvel)
Date: Wed, 26 Aug 2015 10:06:30 +0200
Subject: [PATCH v2 4/5] arm64/efi: ignore DT memory nodes instead of removing
 them
In-Reply-To: <1440576391-25725-1-git-send-email-ard.biesheuvel@linaro.org>
References: <1440576391-25725-1-git-send-email-ard.biesheuvel@linaro.org>
Message-ID: <1440576391-25725-5-git-send-email-ard.biesheuvel@linaro.org>

There are two problems with the UEFI stub DT memory node removal
routine:
- it deletes nodes as it traverses the tree, which happens to work
  but is not supported, as deletion invalidates the node iterator;
- deleting memory nodes entirely may discard annotations in the form
  of additional properties on the nodes.

Now that the UEFI initialization has moved to an earlier stage, we can
actually just ignore any memblocks that are installed after we have
processed the UEFI memory map. This way, it is no longer necessary to
remove the nodes, so we can remove that logic from the stub as well.

Signed-off-by: Ard Biesheuvel <ard.biesheuvel at linaro.org>
---
 arch/arm64/mm/init.c               | 10 ++++++++
 drivers/firmware/efi/libstub/fdt.c | 24 +-------------------
 2 files changed, 11 insertions(+), 23 deletions(-)

diff --git a/arch/arm64/mm/init.c b/arch/arm64/mm/init.c
index ab25fde7397c..ecbc051bc66b 100644
--- a/arch/arm64/mm/init.c
+++ b/arch/arm64/mm/init.c
@@ -379,6 +379,16 @@ void __init early_init_dt_add_memory_arch(u64 base, u64 size)
 {
 	const u64 phys_offset = __pa(PAGE_OFFSET);
 
+	/*
+	 * This callback will be invoked both when booting via UEFI and when
+	 * booting via DT only. In the former case, we need to ignore memory
+	 * nodes in the DT since UEFI is authoritative when it comes to the
+	 * memory map. So ignore any invocations of this callback after
+	 * EFI_MEMMAP has been set.
+	 */
+	if (efi_enabled(EFI_MEMMAP))
+		return;
+
 	if (!PAGE_ALIGNED(base)) {
 		if (size < PAGE_SIZE - (base & ~PAGE_MASK)) {
 			pr_warn("Ignoring memory block 0x%llx - 0x%llx\n",
diff --git a/drivers/firmware/efi/libstub/fdt.c b/drivers/firmware/efi/libstub/fdt.c
index ef5d764e2a27..343e7992bd8f 100644
--- a/drivers/firmware/efi/libstub/fdt.c
+++ b/drivers/firmware/efi/libstub/fdt.c
@@ -24,7 +24,7 @@ efi_status_t update_fdt(efi_system_table_t *sys_table, void *orig_fdt,
 			unsigned long map_size, unsigned long desc_size,
 			u32 desc_ver)
 {
-	int node, prev, num_rsv;
+	int node, num_rsv;
 	int status;
 	u32 fdt_val32;
 	u64 fdt_val64;
@@ -54,28 +54,6 @@ efi_status_t update_fdt(efi_system_table_t *sys_table, void *orig_fdt,
 		goto fdt_set_fail;
 
 	/*
-	 * Delete any memory nodes present. We must delete nodes which
-	 * early_init_dt_scan_memory may try to use.
-	 */
-	prev = 0;
-	for (;;) {
-		const char *type;
-		int len;
-
-		node = fdt_next_node(fdt, prev, NULL);
-		if (node < 0)
-			break;
-
-		type = fdt_getprop(fdt, node, "device_type", &len);
-		if (type && strncmp(type, "memory", len) == 0) {
-			fdt_del_node(fdt, node);
-			continue;
-		}
-
-		prev = node;
-	}
-
-	/*
 	 * Delete all memory reserve map entries. When booting via UEFI,
 	 * kernel will use the UEFI memory map to find reserved regions.
 	 */
-- 
1.9.1



From ard.biesheuvel at linaro.org  Wed Aug 26 01:06:29 2015
From: ard.biesheuvel at linaro.org (Ard Biesheuvel)
Date: Wed, 26 Aug 2015 10:06:29 +0200
Subject: [PATCH v2 3/5] arm64/efi: move EFI init before early FDT processing
In-Reply-To: <1440576391-25725-1-git-send-email-ard.biesheuvel@linaro.org>
References: <1440576391-25725-1-git-send-email-ard.biesheuvel@linaro.org>
Message-ID: <1440576391-25725-4-git-send-email-ard.biesheuvel@linaro.org>

The early FDT processing is responsible for enumerating the
DT memory nodes and installing them as memblocks. This should
only be done if we are not booting via EFI, but at this point,
we don't know yet if that is the case or not.

So move the EFI init to before the early FDT processing. This involves
making some changes to the way EFI discovers the locations of the
EFI system table and the memory map, since those values are retrieved
from the FDT as well. Instead the of_scan infrastructure, it now uses
libfdt directly to access the /chosen node.

Signed-off-by: Ard Biesheuvel <ard.biesheuvel at linaro.org>
---
 arch/arm64/include/asm/efi.h   |  4 +-
 arch/arm64/kernel/efi.c        | 14 ++--
 arch/arm64/kernel/setup.c      |  4 +-
 drivers/firmware/efi/efi-fdt.c | 74 ++++++++------------
 include/linux/efi.h            |  3 +-
 5 files changed, 40 insertions(+), 59 deletions(-)

diff --git a/arch/arm64/include/asm/efi.h b/arch/arm64/include/asm/efi.h
index ef572206f1c3..635101f36720 100644
--- a/arch/arm64/include/asm/efi.h
+++ b/arch/arm64/include/asm/efi.h
@@ -5,9 +5,9 @@
 #include <asm/neon.h>
 
 #ifdef CONFIG_EFI
-extern void efi_init(void);
+extern void efi_init_fdt(void *fdt);
 #else
-#define efi_init()
+#define efi_init_fdt(x)
 #endif
 
 #define efi_call_virt(f, ...)						\
diff --git a/arch/arm64/kernel/efi.c b/arch/arm64/kernel/efi.c
index 9d4aa18f2a82..0e3dbe2cb752 100644
--- a/arch/arm64/kernel/efi.c
+++ b/arch/arm64/kernel/efi.c
@@ -51,14 +51,7 @@ static struct mm_struct efi_mm = {
 	INIT_MM_CONTEXT(efi_mm)
 };
 
-static int uefi_debug __initdata;
-static int __init uefi_debug_setup(char *str)
-{
-	uefi_debug = 1;
-
-	return 0;
-}
-early_param("uefi_debug", uefi_debug_setup);
+static bool uefi_debug __initdata;
 
 static int __init is_normal_ram(efi_memory_desc_t *md)
 {
@@ -205,14 +198,15 @@ static __init void reserve_regions(void)
 	set_bit(EFI_MEMMAP, &efi.flags);
 }
 
-void __init efi_init(void)
+void __init efi_init_fdt(void *fdt)
 {
 	struct efi_fdt_params params;
 
 	/* Grab UEFI information placed in FDT by stub */
-	if (!efi_get_fdt_params(&params, uefi_debug))
+	if (!efi_get_fdt_params(fdt, &params))
 		return;
 
+	uefi_debug = params.verbose;
 	efi_system_table = params.system_table;
 
 	memblock_reserve(params.mmap & PAGE_MASK,
diff --git a/arch/arm64/kernel/setup.c b/arch/arm64/kernel/setup.c
index fddae2c15ad2..8fdde97c975c 100644
--- a/arch/arm64/kernel/setup.c
+++ b/arch/arm64/kernel/setup.c
@@ -298,6 +298,9 @@ static void __init setup_machine_fdt(phys_addr_t dt_phys)
 {
 	void *dt_virt = fixmap_remap_fdt(dt_phys);
 
+	if (dt_virt)
+		efi_init_fdt(dt_virt);
+
 	if (!dt_virt || !early_init_dt_scan(dt_virt)) {
 		pr_crit("\n"
 			"Error: invalid device tree blob at physical address %pa (virtual address 0x%p)\n"
@@ -366,7 +369,6 @@ void __init setup_arch(char **cmdline_p)
 	 */
 	local_async_enable();
 
-	efi_init();
 	arm64_memblock_init();
 
 	/* Parse the ACPI tables for possible boot-time configuration */
diff --git a/drivers/firmware/efi/efi-fdt.c b/drivers/firmware/efi/efi-fdt.c
index f0e7ef2ae0e9..2e0e1a5a3fbb 100644
--- a/drivers/firmware/efi/efi-fdt.c
+++ b/drivers/firmware/efi/efi-fdt.c
@@ -8,8 +8,7 @@
 
 #include <linux/init.h>
 #include <linux/efi.h>
-#include <linux/of.h>
-#include <linux/of_fdt.h>
+#include <linux/libfdt.h>
 
 #define UEFI_PARAM(name, prop, field)			   \
 	{						   \
@@ -32,62 +31,47 @@ static __initdata struct {
 	UEFI_PARAM("MemMap Desc. Version", "linux,uefi-mmap-desc-ver", desc_ver)
 };
 
-struct param_info {
-	int verbose;
-	int found;
-	void *params;
-};
-
-static int __init fdt_find_uefi_params(unsigned long node, const char *uname,
-				       int depth, void *data)
+bool __init efi_get_fdt_params(void *fdt, struct efi_fdt_params *params)
 {
-	struct param_info *info = data;
 	const void *prop;
-	void *dest;
-	u64 val;
-	int i, len;
+	int node, i;
+
+	pr_info("Getting EFI parameters from FDT:\n");
 
-	if (depth != 1 || strcmp(uname, "chosen") != 0)
-		return 0;
+	node = fdt_path_offset(fdt, "/chosen");
+	if (node < 0) {
+		pr_err("/chosen node not found!\n");
+		return false;
+	}
+
+	prop = fdt_getprop(fdt, node, "bootargs", NULL);
+	params->verbose = prop && strstr(prop, "uefi_debug");
 
 	for (i = 0; i < ARRAY_SIZE(dt_params); i++) {
-		prop = of_get_flat_dt_prop(node, dt_params[i].propname, &len);
-		if (!prop)
-			return 0;
-		dest = info->params + dt_params[i].offset;
-		info->found++;
+		void *dest;
+		int len;
+		u64 val;
 
-		val = of_read_number(prop, len / sizeof(u32));
+		prop = fdt_getprop(fdt, node, dt_params[i].propname, &len);
+		if (!prop)
+			goto not_found;
+		dest = (void *)params + dt_params[i].offset;
 
 		if (dt_params[i].size == sizeof(u32))
-			*(u32 *)dest = val;
+			val = *(u32 *)dest = be32_to_cpup(prop);
 		else
-			*(u64 *)dest = val;
+			val = *(u64 *)dest = be64_to_cpup(prop);
 
-		if (info->verbose)
+		if (params->verbose)
 			pr_info("  %s: 0x%0*llx\n", dt_params[i].name,
 				dt_params[i].size * 2, val);
 	}
-	return 1;
-}
-
-int __init efi_get_fdt_params(struct efi_fdt_params *params, int verbose)
-{
-	struct param_info info;
-	int ret;
+	return true;
 
-	pr_info("Getting EFI parameters from FDT:\n");
-
-	info.verbose = verbose;
-	info.found = 0;
-	info.params = params;
-
-	ret = of_scan_flat_dt(fdt_find_uefi_params, &info);
-	if (!info.found)
+not_found:
+	if (i == 0)
 		pr_info("UEFI not found.\n");
-	else if (!ret)
-		pr_err("Can't find '%s' in device tree!\n",
-		       dt_params[info.found].name);
-
-	return ret;
+	else
+		pr_err("Can't find '%s' in device tree!\n", dt_params[i].name);
+	return false;
 }
diff --git a/include/linux/efi.h b/include/linux/efi.h
index 85ef051ac6fb..faafa1ad6ea7 100644
--- a/include/linux/efi.h
+++ b/include/linux/efi.h
@@ -690,6 +690,7 @@ struct efi_fdt_params {
 	u32 mmap_size;
 	u32 desc_size;
 	u32 desc_ver;
+	bool verbose;
 };
 
 typedef struct {
@@ -901,7 +902,7 @@ extern void efi_initialize_iomem_resources(struct resource *code_resource,
 		struct resource *data_resource, struct resource *bss_resource);
 extern void efi_get_time(struct timespec *now);
 extern void efi_reserve_boot_services(void);
-extern int efi_get_fdt_params(struct efi_fdt_params *params, int verbose);
+extern bool efi_get_fdt_params(void *fdt, struct efi_fdt_params *params);
 extern struct efi_memory_map memmap;
 extern struct kobject *efi_kobj;
 
-- 
1.9.1



From ard.biesheuvel at linaro.org  Wed Aug 26 01:06:31 2015
From: ard.biesheuvel at linaro.org (Ard Biesheuvel)
Date: Wed, 26 Aug 2015 10:06:31 +0200
Subject: [PATCH v2 5/5] arm64/efi: ignore DT memreserve entries instead of
 removing them
In-Reply-To: <1440576391-25725-1-git-send-email-ard.biesheuvel@linaro.org>
References: <1440576391-25725-1-git-send-email-ard.biesheuvel@linaro.org>
Message-ID: <1440576391-25725-6-git-send-email-ard.biesheuvel@linaro.org>

Now that the reservation of the FDT image itself is split off, we
can make the DT scanning of memreserves conditional on whether we
booted via UEFI and have its memory map available. This allows us
to drop deletion of these memreserves in the stub. It also fixes
the issue where the /reserved-memory/ node (which offers another
way of reserving memory ranges) was not being ignored under UEFI.

Signed-off-by: Ard Biesheuvel <ard.biesheuvel at linaro.org>
---
 arch/arm64/mm/init.c               |  3 ++-
 drivers/firmware/efi/libstub/fdt.c | 11 +----------
 2 files changed, 3 insertions(+), 11 deletions(-)

diff --git a/arch/arm64/mm/init.c b/arch/arm64/mm/init.c
index ecbc051bc66b..0c33670ed1b6 100644
--- a/arch/arm64/mm/init.c
+++ b/arch/arm64/mm/init.c
@@ -170,7 +170,8 @@ void __init arm64_memblock_init(void)
 		memblock_reserve(__virt_to_phys(initrd_start), initrd_end - initrd_start);
 #endif
 
-	early_init_fdt_scan_reserved_mem();
+	if (!efi_enabled(EFI_MEMMAP))
+		early_init_fdt_scan_reserved_mem();
 
 	/* 4GB maximum for 32-bit only capable devices */
 	if (IS_ENABLED(CONFIG_ZONE_DMA))
diff --git a/drivers/firmware/efi/libstub/fdt.c b/drivers/firmware/efi/libstub/fdt.c
index 343e7992bd8f..a7e87cd582f2 100644
--- a/drivers/firmware/efi/libstub/fdt.c
+++ b/drivers/firmware/efi/libstub/fdt.c
@@ -24,8 +24,7 @@ efi_status_t update_fdt(efi_system_table_t *sys_table, void *orig_fdt,
 			unsigned long map_size, unsigned long desc_size,
 			u32 desc_ver)
 {
-	int node, num_rsv;
-	int status;
+	int node, status;
 	u32 fdt_val32;
 	u64 fdt_val64;
 
@@ -53,14 +52,6 @@ efi_status_t update_fdt(efi_system_table_t *sys_table, void *orig_fdt,
 	if (status != 0)
 		goto fdt_set_fail;
 
-	/*
-	 * Delete all memory reserve map entries. When booting via UEFI,
-	 * kernel will use the UEFI memory map to find reserved regions.
-	 */
-	num_rsv = fdt_num_mem_rsv(fdt);
-	while (num_rsv-- > 0)
-		fdt_del_mem_rsv(fdt, num_rsv);
-
 	node = fdt_subnode_offset(fdt, 0, "chosen");
 	if (node < 0) {
 		node = fdt_add_subnode(fdt, 0, "chosen");
-- 
1.9.1



From antoine.tenart at free-electrons.com  Wed Aug 26 01:07:28 2015
From: antoine.tenart at free-electrons.com (Antoine Tenart)
Date: Wed, 26 Aug 2015 10:07:28 +0200
Subject: [PATCH v5 3/5] ARM: berlin: add a PWM node on the BG2Q
In-Reply-To: <1440576450-17420-1-git-send-email-antoine.tenart@free-electrons.com>
References: <1440576450-17420-1-git-send-email-antoine.tenart@free-electrons.com>
Message-ID: <1440576450-17420-4-git-send-email-antoine.tenart@free-electrons.com>

This patch adds a PWM node in the Berlin BG2Q device tree, using the
newly added Berlin PWM driver.

Signed-off-by: Antoine Tenart <antoine.tenart at free-electrons.com>
---
 arch/arm/boot/dts/berlin2q.dtsi | 7 +++++++
 1 file changed, 7 insertions(+)

diff --git a/arch/arm/boot/dts/berlin2q.dtsi b/arch/arm/boot/dts/berlin2q.dtsi
index 63a48490e2f9..5bfa71a87617 100644
--- a/arch/arm/boot/dts/berlin2q.dtsi
+++ b/arch/arm/boot/dts/berlin2q.dtsi
@@ -477,6 +477,13 @@
 			status = "disabled";
 		};
 
+		pwm: pwm at f20000 {
+			compatible = "marvell,berlin-pwm";
+			reg = <0xf20000 0x40>;
+			clocks = <&chip_clk CLKID_CFG>;
+			#pwm-cells = <3>;
+		};
+
 		apb at fc0000 {
 			compatible = "simple-bus";
 			#address-cells = <1>;
-- 
2.5.0



From antoine.tenart at free-electrons.com  Wed Aug 26 01:07:27 2015
From: antoine.tenart at free-electrons.com (Antoine Tenart)
Date: Wed, 26 Aug 2015 10:07:27 +0200
Subject: [PATCH v5 2/5] Documentation: bindings: document the Berlin PWM driver
In-Reply-To: <1440576450-17420-1-git-send-email-antoine.tenart@free-electrons.com>
References: <1440576450-17420-1-git-send-email-antoine.tenart@free-electrons.com>
Message-ID: <1440576450-17420-3-git-send-email-antoine.tenart@free-electrons.com>

Following the addition of a Berlin PWM driver, this patch adds the
corresponding documentation.

Signed-off-by: Antoine Tenart <antoine.tenart at free-electrons.com>
Acked-by: Sebastian Hesselbarth <sebastian.hesselbarth at gmail.com>
---
 Documentation/devicetree/bindings/pwm/pwm-berlin.txt | 19 +++++++++++++++++++
 1 file changed, 19 insertions(+)
 create mode 100644 Documentation/devicetree/bindings/pwm/pwm-berlin.txt

diff --git a/Documentation/devicetree/bindings/pwm/pwm-berlin.txt b/Documentation/devicetree/bindings/pwm/pwm-berlin.txt
new file mode 100644
index 000000000000..8f9bc11f8c4c
--- /dev/null
+++ b/Documentation/devicetree/bindings/pwm/pwm-berlin.txt
@@ -0,0 +1,19 @@
+Berlin PWM controller
+
+PWM IP found in Marvell Berlin SoCs.
+
+Required properties:
+- compatible: should be "marvell,berlin-pwm"
+- reg: physical base address and length of the controller's registers
+- clocks: phandle to the input clock
+- #pwm-cells: should be 3. See pwm.txt in this directory for a description of
+  the cells format.
+
+Example:
+
+pwm: pwm at f7f20000 {
+	compatible = "marvell,berlin-pwm";
+	reg = <0xf7f20000 0x40>;
+	clocks = <&chip_clk CLKID_CFG>;
+	#pwm-cells = <3>;
+}
-- 
2.5.0



From antoine.tenart at free-electrons.com  Wed Aug 26 01:07:25 2015
From: antoine.tenart at free-electrons.com (Antoine Tenart)
Date: Wed, 26 Aug 2015 10:07:25 +0200
Subject: [PATCH v5 0/5] ARM: berlin: PWM support
Message-ID: <1440576450-17420-1-git-send-email-antoine.tenart@free-electrons.com>

Hi all,

This series adds a driver for the Marvell Berlin PWM controller, which
has 4 channels.

This has been tested on a BG2Q DMP.

Thanks,

Antoine

Changes since v4:
	- Reworked _remove()
	- Reworked _enable()

Changes since v3:
        - Use readl_relaxed
        - Reworked the clk enable / clk disable calls
        - Removed BERLIN_PWM_DISABLE

Changes since v2:
        - Reworked the prescaler/tcnt calculation
        - Added an input clock
        - Updated the documentation
        - Reordered the pwm node
        - Added some definition for BIT()

Changes since v1:
        - Added a sentinel in berlin_pwm_match[]

Antoine Tenart (5):
  pwm: add the Berlin pwm controller driver
  Documentation: bindings: document the Berlin PWM driver
  ARM: berlin: add a PWM node on the BG2Q
  ARM: berlin: add a PWM node on the BG2
  ARM: berlin: add a PWM node on the BG2CD

 .../devicetree/bindings/pwm/pwm-berlin.txt         |  19 ++
 arch/arm/boot/dts/berlin2.dtsi                     |   7 +
 arch/arm/boot/dts/berlin2cd.dtsi                   |   7 +
 arch/arm/boot/dts/berlin2q.dtsi                    |   7 +
 drivers/pwm/Kconfig                                |   9 +
 drivers/pwm/Makefile                               |   1 +
 drivers/pwm/pwm-berlin.c                           | 227 +++++++++++++++++++++
 7 files changed, 277 insertions(+)
 create mode 100644 Documentation/devicetree/bindings/pwm/pwm-berlin.txt
 create mode 100644 drivers/pwm/pwm-berlin.c

-- 
2.5.0



From antoine.tenart at free-electrons.com  Wed Aug 26 01:07:29 2015
From: antoine.tenart at free-electrons.com (Antoine Tenart)
Date: Wed, 26 Aug 2015 10:07:29 +0200
Subject: [PATCH v5 4/5] ARM: berlin: add a PWM node on the BG2
In-Reply-To: <1440576450-17420-1-git-send-email-antoine.tenart@free-electrons.com>
References: <1440576450-17420-1-git-send-email-antoine.tenart@free-electrons.com>
Message-ID: <1440576450-17420-5-git-send-email-antoine.tenart@free-electrons.com>

This patch adds a PWM node in the Berlin BG2 device tree, using the
newly added Berlin PWM driver.

Signed-off-by: Antoine Tenart <antoine.tenart at free-electrons.com>
---
 arch/arm/boot/dts/berlin2.dtsi | 7 +++++++
 1 file changed, 7 insertions(+)

diff --git a/arch/arm/boot/dts/berlin2.dtsi b/arch/arm/boot/dts/berlin2.dtsi
index ef811de09908..f094b06d16aa 100644
--- a/arch/arm/boot/dts/berlin2.dtsi
+++ b/arch/arm/boot/dts/berlin2.dtsi
@@ -404,6 +404,13 @@
 			};
 		};
 
+		pwm: pwm at f20000 {
+			compatible = "marvell,berlin-pwm";
+			reg = <0xf20000 0x40>;
+			clocks = <&chip_clk CLKID_CFG>;
+			#pwm-cells = <3>;
+		};
+
 		apb at fc0000 {
 			compatible = "simple-bus";
 			#address-cells = <1>;
-- 
2.5.0



From antoine.tenart at free-electrons.com  Wed Aug 26 01:07:26 2015
From: antoine.tenart at free-electrons.com (Antoine Tenart)
Date: Wed, 26 Aug 2015 10:07:26 +0200
Subject: [PATCH v5 1/5] pwm: add the Berlin pwm controller driver
In-Reply-To: <1440576450-17420-1-git-send-email-antoine.tenart@free-electrons.com>
References: <1440576450-17420-1-git-send-email-antoine.tenart@free-electrons.com>
Message-ID: <1440576450-17420-2-git-send-email-antoine.tenart@free-electrons.com>

Add a PWM controller driver for the Marvell Berlin SoCs. This PWM
controller has 4 channels.

Signed-off-by: Antoine Tenart <antoine.tenart at free-electrons.com>
Acked-by: Sebastian Hesselbarth <sebastian.hesselbarth at gmail.com>
---
 drivers/pwm/Kconfig      |   9 ++
 drivers/pwm/Makefile     |   1 +
 drivers/pwm/pwm-berlin.c | 227 +++++++++++++++++++++++++++++++++++++++++++++++
 3 files changed, 237 insertions(+)
 create mode 100644 drivers/pwm/pwm-berlin.c

diff --git a/drivers/pwm/Kconfig b/drivers/pwm/Kconfig
index b1541f40fd8d..1773da8145b8 100644
--- a/drivers/pwm/Kconfig
+++ b/drivers/pwm/Kconfig
@@ -92,6 +92,15 @@ config PWM_BCM2835
 	  To compile this driver as a module, choose M here: the module
 	  will be called pwm-bcm2835.
 
+config PWM_BERLIN
+	tristate "Berlin PWM support"
+	depends on ARCH_BERLIN
+	help
+	  PWM framework driver for Berlin.
+
+	  To compile this driver as a module, choose M here: the module
+	  will be called pwm-berlin.
+
 config PWM_BFIN
 	tristate "Blackfin PWM support"
 	depends on BFIN_GPTIMERS
diff --git a/drivers/pwm/Makefile b/drivers/pwm/Makefile
index ec50eb5b5a8f..670c5fce8bbb 100644
--- a/drivers/pwm/Makefile
+++ b/drivers/pwm/Makefile
@@ -6,6 +6,7 @@ obj-$(CONFIG_PWM_ATMEL_HLCDC_PWM)	+= pwm-atmel-hlcdc.o
 obj-$(CONFIG_PWM_ATMEL_TCB)	+= pwm-atmel-tcb.o
 obj-$(CONFIG_PWM_BCM_KONA)	+= pwm-bcm-kona.o
 obj-$(CONFIG_PWM_BCM2835)	+= pwm-bcm2835.o
+obj-$(CONFIG_PWM_BERLIN)	+= pwm-berlin.o
 obj-$(CONFIG_PWM_BFIN)		+= pwm-bfin.o
 obj-$(CONFIG_PWM_CLPS711X)	+= pwm-clps711x.o
 obj-$(CONFIG_PWM_EP93XX)	+= pwm-ep93xx.o
diff --git a/drivers/pwm/pwm-berlin.c b/drivers/pwm/pwm-berlin.c
new file mode 100644
index 000000000000..3a373fd72892
--- /dev/null
+++ b/drivers/pwm/pwm-berlin.c
@@ -0,0 +1,227 @@
+/*
+ * Marvell Berlin PWM driver
+ *
+ * Copyright (C) 2015 Marvell Technology Group Ltd.
+ *
+ * Antoine Tenart <antoine.tenart at free-electrons.com>
+ *
+ * This file is licensed under the terms of the GNU General Public
+ * License version 2. This program is licensed "as is" without any
+ * warranty of any kind, whether express or implied.
+ */
+
+#include <linux/clk.h>
+#include <linux/io.h>
+#include <linux/kernel.h>
+#include <linux/module.h>
+#include <linux/platform_device.h>
+#include <linux/pwm.h>
+#include <linux/spinlock.h>
+
+#define BERLIN_PWM_EN			0x0
+#define BERLIN_PWM_CONTROL		0x4
+#define BERLIN_PWM_DUTY			0x8
+#define BERLIN_PWM_TCNT			0xc
+
+#define BERLIN_PWM_ENABLE		BIT(0)
+#define BERLIN_PWM_INVERT_POLARITY	BIT(3)
+#define BERLIN_PWM_PRESCALE_MASK	0x7
+#define BERLIN_PWM_PRESCALE_MAX		4096
+#define BERLIN_PWM_MAX_TCNT		65535
+
+struct berlin_pwm_chip {
+	struct pwm_chip chip;
+	struct clk *clk;
+	void __iomem *base;
+	spinlock_t lock;
+};
+
+#define to_berlin_pwm_chip(chip)	\
+	container_of((chip), struct berlin_pwm_chip, chip)
+
+#define berlin_pwm_readl(chip, channel, offset)		\
+	readl_relaxed((chip)->base + (channel) * 0x10 + offset)
+#define berlin_pwm_writel(val, chip, channel, offset)	\
+	writel_relaxed(val, (chip)->base + (channel) * 0x10 + offset)
+
+/* prescaler table: {1, 4, 8, 16, 64, 256, 1024, 4096} */
+static const u32 prescaler_diff_table[] = {
+	1, 4, 2, 2, 4, 4, 4, 4,
+};
+
+static int berlin_pwm_config(struct pwm_chip *chip, struct pwm_device *pwm_dev,
+			     int duty_ns, int period_ns)
+{
+	struct berlin_pwm_chip *pwm = to_berlin_pwm_chip(chip);
+	int prescale = 0;
+	u32 val, duty, period;
+	u64 cycles;
+
+	cycles = clk_get_rate(pwm->clk);
+	cycles *= period_ns;
+	do_div(cycles, NSEC_PER_SEC);
+
+	while (cycles > BERLIN_PWM_MAX_TCNT)
+		do_div(cycles, prescaler_diff_table[++prescale]);
+
+	if (cycles > BERLIN_PWM_MAX_TCNT)
+		return -EINVAL;
+
+	period = cycles;
+	cycles *= duty_ns;
+	do_div(cycles, period_ns);
+	duty = cycles;
+
+	spin_lock(&pwm->lock);
+
+	val = berlin_pwm_readl(pwm, pwm_dev->hwpwm, BERLIN_PWM_CONTROL);
+	val &= ~BERLIN_PWM_PRESCALE_MASK;
+	val |= prescale;
+	berlin_pwm_writel(val, pwm, pwm_dev->hwpwm, BERLIN_PWM_CONTROL);
+
+	berlin_pwm_writel(duty, pwm, pwm_dev->hwpwm, BERLIN_PWM_DUTY);
+	berlin_pwm_writel(period, pwm, pwm_dev->hwpwm, BERLIN_PWM_TCNT);
+
+	spin_unlock(&pwm->lock);
+
+	return 0;
+}
+
+static int berlin_pwm_set_polarity(struct pwm_chip *chip,
+				   struct pwm_device *pwm_dev,
+				   enum pwm_polarity polarity)
+{
+	struct berlin_pwm_chip *pwm = to_berlin_pwm_chip(chip);
+	u32 val;
+
+	spin_lock(&pwm->lock);
+
+	val = berlin_pwm_readl(pwm, pwm_dev->hwpwm, BERLIN_PWM_CONTROL);
+
+	if (polarity == PWM_POLARITY_NORMAL)
+		val &= ~BERLIN_PWM_INVERT_POLARITY;
+	else
+		val |= BERLIN_PWM_INVERT_POLARITY;
+
+	berlin_pwm_writel(val, pwm, pwm_dev->hwpwm, BERLIN_PWM_CONTROL);
+
+	spin_unlock(&pwm->lock);
+
+	return 0;
+}
+
+static int berlin_pwm_enable(struct pwm_chip *chip, struct pwm_device *pwm_dev)
+{
+	struct berlin_pwm_chip *pwm = to_berlin_pwm_chip(chip);
+	u32 val;
+
+	spin_lock(&pwm->lock);
+
+	val = berlin_pwm_readl(pwm, pwm_dev->hwpwm, BERLIN_PWM_EN);
+	val |= BERLIN_PWM_ENABLE;
+	berlin_pwm_writel(val, pwm, pwm_dev->hwpwm, BERLIN_PWM_EN);
+
+	spin_unlock(&pwm->lock);
+
+	return 0;
+}
+
+static void berlin_pwm_disable(struct pwm_chip *chip,
+			       struct pwm_device *pwm_dev)
+{
+	struct berlin_pwm_chip *pwm = to_berlin_pwm_chip(chip);
+	u32 val;
+
+	spin_lock(&pwm->lock);
+
+	val = berlin_pwm_readl(pwm, pwm_dev->hwpwm, BERLIN_PWM_EN);
+	val &= ~BERLIN_PWM_ENABLE;
+	berlin_pwm_writel(val, pwm, pwm_dev->hwpwm, BERLIN_PWM_EN);
+
+	spin_unlock(&pwm->lock);
+}
+
+static const struct pwm_ops berlin_pwm_ops = {
+	.config = berlin_pwm_config,
+	.set_polarity = berlin_pwm_set_polarity,
+	.enable = berlin_pwm_enable,
+	.disable = berlin_pwm_disable,
+	.owner = THIS_MODULE,
+};
+
+static const struct of_device_id berlin_pwm_match[] = {
+	{ .compatible = "marvell,berlin-pwm" },
+	{ },
+};
+MODULE_DEVICE_TABLE(of, berlin_pwm_match);
+
+static int berlin_pwm_probe(struct platform_device *pdev)
+{
+	struct berlin_pwm_chip *pwm;
+	struct resource *res;
+	int ret;
+
+	pwm = devm_kzalloc(&pdev->dev, sizeof(*pwm), GFP_KERNEL);
+	if (!pwm)
+		return -ENOMEM;
+
+	res = platform_get_resource(pdev, IORESOURCE_MEM, 0);
+	pwm->base = devm_ioremap_resource(&pdev->dev, res);
+	if (IS_ERR(pwm->base))
+		return PTR_ERR(pwm->base);
+
+	pwm->clk = devm_clk_get(&pdev->dev, NULL);
+	if (IS_ERR(pwm->clk))
+		return PTR_ERR(pwm->clk);
+
+	ret = clk_prepare_enable(pwm->clk);
+	if (ret)
+		return ret;
+
+	pwm->chip.dev = &pdev->dev;
+	pwm->chip.ops = &berlin_pwm_ops;
+	pwm->chip.base = -1;
+	pwm->chip.npwm = 4;
+	pwm->chip.can_sleep = true;
+	pwm->chip.of_xlate = of_pwm_xlate_with_flags;
+	pwm->chip.of_pwm_n_cells = 3;
+
+	spin_lock_init(&pwm->lock);
+
+	ret = pwmchip_add(&pwm->chip);
+	if (ret < 0) {
+		dev_err(&pdev->dev, "Failed to add PWM chip: %d\n", ret);
+		return ret;
+	}
+
+	platform_set_drvdata(pdev, pwm);
+
+	return 0;
+}
+
+static int berlin_pwm_remove(struct platform_device *pdev)
+{
+	struct berlin_pwm_chip *pwm = platform_get_drvdata(pdev);
+	int ret;
+
+	ret = pwmchip_remove(&pwm->chip);
+	if (ret)
+		return ret;
+
+	clk_disable_unprepare(pwm->clk);
+	return 0;
+}
+
+static struct platform_driver berlin_pwm_driver = {
+	.probe	= berlin_pwm_probe,
+	.remove	= berlin_pwm_remove,
+	.driver	= {
+		.name	= "berlin-pwm",
+		.of_match_table = berlin_pwm_match,
+	},
+};
+module_platform_driver(berlin_pwm_driver);
+
+MODULE_AUTHOR("Antoine Tenart <antoine.tenart at free-electrons.com>");
+MODULE_DESCRIPTION("Marvell Berlin PWM driver");
+MODULE_LICENSE("GPL v2");
-- 
2.5.0



From antoine.tenart at free-electrons.com  Wed Aug 26 01:07:30 2015
From: antoine.tenart at free-electrons.com (Antoine Tenart)
Date: Wed, 26 Aug 2015 10:07:30 +0200
Subject: [PATCH v5 5/5] ARM: berlin: add a PWM node on the BG2CD
In-Reply-To: <1440576450-17420-1-git-send-email-antoine.tenart@free-electrons.com>
References: <1440576450-17420-1-git-send-email-antoine.tenart@free-electrons.com>
Message-ID: <1440576450-17420-6-git-send-email-antoine.tenart@free-electrons.com>

This patch adds a PWM node in the Berlin BG2CD device tree, using the
newly added Berlin PWM driver.

Signed-off-by: Antoine Tenart <antoine.tenart at free-electrons.com>
---
 arch/arm/boot/dts/berlin2cd.dtsi | 7 +++++++
 1 file changed, 7 insertions(+)

diff --git a/arch/arm/boot/dts/berlin2cd.dtsi b/arch/arm/boot/dts/berlin2cd.dtsi
index 900213d78a32..5d984f58dde7 100644
--- a/arch/arm/boot/dts/berlin2cd.dtsi
+++ b/arch/arm/boot/dts/berlin2cd.dtsi
@@ -368,6 +368,13 @@
 			status = "disabled";
 		};
 
+		pwm: pwm at f20000 {
+			compatible = "marvell,berlin-pwm";
+			reg = <0xf20000 0x40>;
+			clocks = <&chip_clk CLKID_CFG>;
+			#pwm-cells = <3>;
+		};
+
 		apb at fc0000 {
 			compatible = "simple-bus";
 			#address-cells = <1>;
-- 
2.5.0



From chaotian.jing at mediatek.com  Wed Aug 26 01:40:16 2015
From: chaotian.jing at mediatek.com (Chaotian Jing)
Date: Wed, 26 Aug 2015 16:40:16 +0800
Subject: [PATCH 1/4] mmc: mediatek: Add online-tuning support of EMMC/SD
In-Reply-To: <CAPDyKFpGk9gcLLjBnN=+BD5WP-7dZ0+XHC1bcEEGGLvLbTyKHw@mail.gmail.com>
References: <1439367845-5891-1-git-send-email-chaotian.jing@mediatek.com>
 <1439367845-5891-2-git-send-email-chaotian.jing@mediatek.com>
 <CAPDyKFpX4Pp1+U9eNBuGd83sBeBgLU17qysAJ-2V-ABZZHYAGQ@mail.gmail.com>
 <1439812888.5627.9.camel@mhfsdcap03>
 <CAPDyKFpGk9gcLLjBnN=+BD5WP-7dZ0+XHC1bcEEGGLvLbTyKHw@mail.gmail.com>
Message-ID: <1440578416.26912.12.camel@mhfsdcap03>

On Tue, 2015-08-25 at 14:07 +0200, Ulf Hansson wrote:
> On 17 August 2015 at 14:01, Chaotian Jing <chaotian.jing at mediatek.com> wrote:
> > Hi Ulf,
> > Thanks, please see my comment:
> > On Mon, 2015-08-17 at 13:31 +0200, Ulf Hansson wrote:
> >> On 12 August 2015 at 10:24, Chaotian Jing <chaotian.jing at mediatek.com> wrote:
> >> > Schedule a workqueue to do tuning when CRC error
> >> > Call mmc_hw_reset to re-init card when data timeout
> >>
> >> Thanks to Adrian Hunter, the mmc core already supports re-tuning for
> >> the above scenarios through the mmc_retune_*() APIs.
> >>
> >> SDHCI driver has already adopted to use that feature, you should do
> >> that for the mtk-sd driver as well.
> >>
> >> Kind regards
> >> Uffe
> >>
> > I also noticed that the mmc core already supports re-tuning, but it is
> > not suitable for our host.
> > For EMMC, the CMD21 only support HS200/HS400 mode, for SD card, CMD19
> > only support SDR50/SDR104 mode, but in our host, even 50Mhz clock
> > frequency may also occur CRC error, Cannot find a parameter that can
> > cover all SD cards which running at 50Mhz, even 25Mhz, will occur CRC
> > error for stress test, DDR50 mode is worse.
> 
> I don't follow. You may run for example HS200 in lower speed, nothing
> will prevent tuning and re-tuning from happen for these scenarios.
> 
> Or you are talking about other speed modes than HS200/400 and
> SDR50/104? If so, which speed modes are these?
> 
Yes, I am talking about other speed modes.
For SD card, the speed mode is High Speed, for EMMC, the speed may be
High Speed or DDR mode.
If CRC error occurs at these speed modes, the MMC core layer will never
handler it. even propagate the -EILSEQ towards to the mmc core, it will
not start mmc_retune.
> BTW, there are currently a patch being discussed which is about adding
> tuning for DDR mode. Please have look.
> http://www.spinics.net/lists/arm-kernel/msg438434.html
> 
> Regarding re-tuning on CRC errors, that's already supported by the mmc
> core. More precisely when a host driver returns -EILSEQ for a request.
> 
> > By the way,there are too many tune parameters need try for response,
> > read data, write crc status CRC error, these parameters are
> > multidimensional, it is hard to find a best parameter, and, try
> > thousands of parameters will take long time.
> 
> As I see, it's your responsibility from the host driver to propagate
> the proper error code towards the mmc core. If you encounter an error
> that you want to trigger a retune, just return -EILSEQ.
> 
> Moreover, if you see a need to extend the tuning/re-tuning support in
> the mmc core to suit your need - I am definitely open to look into
> that. More importantly, I don't want to see host specific hacks trying
> to deal with this.
> 
In addition, the CMD21 is only valid for HS200 mode, do not support
HS400, So that there is no chance to tune the HS400 read/write data with
current mmc core layer codes.
As you see, in our platform, tune of HS200 and HS400 is different, but
if use the CMD21, it will never work at HS400 mode, even with
"prepare_hs400_tuning", but it prepare what ? what we need is that
running at HS400 mode and tune the read/write parameters, but not HS200,
because for data Rx path, the tune result of HS200 is meaningless for
HS400.
> Kind regards
> Uffe




From nicolas.ferre at atmel.com  Wed Aug 26 01:45:45 2015
From: nicolas.ferre at atmel.com (Nicolas Ferre)
Date: Wed, 26 Aug 2015 10:45:45 +0200
Subject: [PATCH] ARM: at91/dt: corrections to i2c1 declaration to sama5d4
Message-ID: <1440578745-9585-1-git-send-email-nicolas.ferre@atmel.com>

From: Holger Busse <h.busse at kathrein-sachsen.de>

Correcting the dma declaration for i2c1 dma.

Signed-off-by: Holger Busse <h.busse at kathrein-sachsen.de>
Signed-off-by: Nicolas Ferre <nicolas.ferre at atmel.com>
---
 arch/arm/boot/dts/sama5d4.dtsi | 8 ++++----
 1 file changed, 4 insertions(+), 4 deletions(-)

diff --git a/arch/arm/boot/dts/sama5d4.dtsi b/arch/arm/boot/dts/sama5d4.dtsi
index 3ee22ee13c5a..1ba10e495f21 100644
--- a/arch/arm/boot/dts/sama5d4.dtsi
+++ b/arch/arm/boot/dts/sama5d4.dtsi
@@ -939,11 +939,11 @@
 				reg = <0xf8018000 0x4000>;
 				interrupts = <33 IRQ_TYPE_LEVEL_HIGH 6>;
 				dmas = <&dma1
-					(AT91_XDMAC_DT_MEM_IF(0) | AT91_XDMAC_DT_PER_IF(1))
-					AT91_XDMAC_DT_PERID(4)>,
+					(AT91_XDMAC_DT_MEM_IF(0) | AT91_XDMAC_DT_PER_IF(1)
+					| AT91_XDMAC_DT_PERID(4))>,
 				       <&dma1
-					(AT91_XDMAC_DT_MEM_IF(0) | AT91_XDMAC_DT_PER_IF(1))
-					AT91_XDMAC_DT_PERID(5)>;
+					(AT91_XDMAC_DT_MEM_IF(0) | AT91_XDMAC_DT_PER_IF(1)
+					| AT91_XDMAC_DT_PERID(5))>;
 				dma-names = "tx", "rx";
 				pinctrl-names = "default";
 				pinctrl-0 = <&pinctrl_i2c1>;
-- 
2.1.3



From sudeep.holla at arm.com  Wed Aug 26 01:52:16 2015
From: sudeep.holla at arm.com (Sudeep Holla)
Date: Wed, 26 Aug 2015 09:52:16 +0100
Subject: [PATCH v9 1/1] irqchip: imx-gpcv2: IMX GPCv2 driver for wakeup
 sources
In-Reply-To: <alpine.DEB.2.11.1508252123310.15006@nanos>
References: <1440443055-7291-1-git-send-email-shenwei.wang@freescale.com>
 <55DC3452.3070205@arm.com>
 <CY1PR0301MB08439B6C5F841AFFD152DFD883610@CY1PR0301MB0843.namprd03.prod.outlook.com>
 <55DC738D.8000302@arm.com>
 <CY1PR0301MB0843AE566996617D855CC00683610@CY1PR0301MB0843.namprd03.prod.outlook.com>
 <55DC7FA4.7040902@arm.com>
 <CY1PR0301MB08433A2659C75028821F0AE783610@CY1PR0301MB0843.namprd03.prod.outlook.com>
 <55DC96BA.2020905@arm.com> <alpine.DEB.2.11.1508252123310.15006@nanos>
Message-ID: <55DD7E40.1040009@arm.com>

Hi Thomas,

On 25/08/15 20:26, Thomas Gleixner wrote:
> On Tue, 25 Aug 2015, Sudeep Holla wrote:
>> On 25/08/15 15:54, Shenwei Wang wrote:
>>> You don't really understand what happens after a driver calls
>>> enable_irq_wake. In suspend state, even the interrupt
>>> controller itself is powered off. How can you get the system up
>>> again  by just using a SKIP_SET_WAKE.
>>
>> Sorry for that, let me try to understand aloud. So you have
>> irq_{un,}mask function that are called when interrupts are enabled and
>> disabled. So suppose you have 3 irqs that are enabled and only one of
>> then is set as wakeup source.
>>
>> Now you call enable_irq_wake, you save that in wakeup_sources, fine.
>> Later when you enter suspend, you save all the 3 active irqs in
>> saved_irq_mask and over-write cpu2wakeup with wakeup_sources, right?
>>
>> All fine, what I am saying is let irq-core know that you want to mask
>> the 2 non-wakeup irqs you have using MASK_ON_SUSPEND. So when
>> suspend_device_irqs is called in suspend path, that's done for you
>> automatically and the cpu2wakeup will have just 1 wakeup enabled which
>> is what you are doing in suspend callback, right ?
>
> I missed that when I reviewed the patch. You are right, it can be
> simplified.
>
>> Now that it's already done for you, you need not do anything extra and
>> hence just set SKIP_SET_WAKE to do nothing.

Thanks for confirming this.

>
> He still needs the set_wake function to capture the wake enabled
> interrupts as they are handed over to the low level asm code via
> imx_gpcv2_get_wakeup_source(). Though they could be read back from the
> hw registers as well.
>

Correct, I have no objection on how it's saved/restored but was against
having 2 different masks and with the approach taken in this patch the
non-wakeup interrupts are enabled until syscore_suspend which is wrong.

There's whole lot of drivers blindly copy pasting this as theme which I
am going through and trying to clean up. I wanted to ensure no more such
additions happen meanwhile, so I am watching such patches closely.

Regards,
Sudeep


From eric.auger at linaro.org  Wed Aug 26 01:54:51 2015
From: eric.auger at linaro.org (Eric Auger)
Date: Wed, 26 Aug 2015 10:54:51 +0200
Subject: [PATCH v3 1/4] irqchip: GICv3: Convert to EOImode == 1
In-Reply-To: <1440503605-10185-2-git-send-email-marc.zyngier@arm.com>
References: <1440503605-10185-1-git-send-email-marc.zyngier@arm.com>
 <1440503605-10185-2-git-send-email-marc.zyngier@arm.com>
Message-ID: <55DD7EDB.7010208@linaro.org>

Hi Marc,
On 08/25/2015 01:53 PM, Marc Zyngier wrote:
> So far, GICv3 has been used in with EOImode == 0. The effect of this
> mode is to perform the priority drop and the deactivation of the
> interrupt at the same time.
> 
> While this works perfectly for Linux (we only have a single priority),
> it causes issues when an interrupt is forwarded to a guest, and when
> we want the guest to perform the EOI itself.
> 
> For this case, the GIC architecture provides EOImode == 1, where:
> - A write to ICC_EOIR1_EL1 drops the priority of the interrupt and
>   leaves it active. Other interrupts at the same priority level can
>   now be taken, but the active interrupt cannot be taken again
> - A write to ICC_DIR_EL1 marks the interrupt as inactive, meaning
>   it can now be taken again.
> 
> This patch converts the driver to be able to use this new mode,
> depending on whether or not the kernel can behave as a hypervisor.
> No feature change.
> 
> Reviewed-by: Eric Auger <eric.auger at linaro.org>
> Signed-off-by: Marc Zyngier <marc.zyngier at arm.com>
> ---
>  drivers/irqchip/irq-gic-v3.c       | 39 ++++++++++++++++++++++++++++++++++----
>  include/linux/irqchip/arm-gic-v3.h |  9 +++++++++
>  2 files changed, 44 insertions(+), 4 deletions(-)
> 
> diff --git a/drivers/irqchip/irq-gic-v3.c b/drivers/irqchip/irq-gic-v3.c
> index c52f7ba..addd2ee 100644
> --- a/drivers/irqchip/irq-gic-v3.c
> +++ b/drivers/irqchip/irq-gic-v3.c
> @@ -30,6 +30,7 @@
>  #include <asm/cputype.h>
>  #include <asm/exception.h>
>  #include <asm/smp_plat.h>
> +#include <asm/virt.h>
>  
>  #include "irq-gic-common.h"
>  #include "irqchip.h"
> @@ -50,6 +51,7 @@ struct gic_chip_data {
>  };
>  
>  static struct gic_chip_data gic_data __read_mostly;
> +static struct static_key supports_deactivate = STATIC_KEY_INIT_TRUE;

in http://www.spinics.net/lists/arm-kernel/msg439813.html, Catalin
reported the direct usage of static_key was deprecated. Sorry I learned
that after my last review.

see https://lkml.org/lkml/2015/8/3/539

Best Regards

Eric
>  
>  #define gic_data_rdist()		(this_cpu_ptr(gic_data.rdists.rdist))
>  #define gic_data_rdist_rd_base()	(gic_data_rdist()->rd_base)
> @@ -293,7 +295,14 @@ static int gic_irq_get_irqchip_state(struct irq_data *d,
>  
>  static void gic_eoi_irq(struct irq_data *d)
>  {
> -	gic_write_eoir(gic_irq(d));
> +	if (static_key_true(&supports_deactivate)) {
> +		/* No need to deactivate an LPI */
> +		if (gic_irq(d) >= 8192)
> +			return;
> +		gic_write_dir(gic_irq(d));
> +	} else {
> +		gic_write_eoir(gic_irq(d));
> +	}
>  }
>  
>  static int gic_set_type(struct irq_data *d, unsigned int type)
> @@ -343,15 +352,26 @@ static asmlinkage void __exception_irq_entry gic_handle_irq(struct pt_regs *regs
>  
>  		if (likely(irqnr > 15 && irqnr < 1020) || irqnr >= 8192) {
>  			int err;
> +
> +			if (static_key_true(&supports_deactivate))
> +				gic_write_eoir(irqnr);
> +
>  			err = handle_domain_irq(gic_data.domain, irqnr, regs);
>  			if (err) {
>  				WARN_ONCE(true, "Unexpected interrupt received!\n");
> -				gic_write_eoir(irqnr);
> +				if (static_key_true(&supports_deactivate)) {
> +					if (irqnr < 8192)
> +						gic_write_dir(irqnr);
> +				} else {
> +					gic_write_eoir(irqnr);
> +				}
>  			}
>  			continue;
>  		}
>  		if (irqnr < 16) {
>  			gic_write_eoir(irqnr);
> +			if (static_key_true(&supports_deactivate))
> +				gic_write_dir(irqnr);
>  #ifdef CONFIG_SMP
>  			handle_IPI(irqnr, regs);
>  #else
> @@ -451,8 +471,13 @@ static void gic_cpu_sys_reg_init(void)
>  	/* Set priority mask register */
>  	gic_write_pmr(DEFAULT_PMR_VALUE);
>  
> -	/* EOI deactivates interrupt too (mode 0) */
> -	gic_write_ctlr(ICC_CTLR_EL1_EOImode_drop_dir);
> +	if (static_key_true(&supports_deactivate)) {
> +		/* EOI drops priority only (mode 1) */
> +		gic_write_ctlr(ICC_CTLR_EL1_EOImode_drop);
> +	} else {
> +		/* EOI deactivates interrupt too (mode 0) */
> +		gic_write_ctlr(ICC_CTLR_EL1_EOImode_drop_dir);
> +	}
>  
>  	/* ... and let's hit the road... */
>  	gic_write_grpen1(1);
> @@ -820,6 +845,12 @@ static int __init gic_of_init(struct device_node *node, struct device_node *pare
>  	if (of_property_read_u64(node, "redistributor-stride", &redist_stride))
>  		redist_stride = 0;
>  
> +	if (!is_hyp_mode_available())
> +		static_key_slow_dec(&supports_deactivate);
> +
> +	if (static_key_true(&supports_deactivate))
> +		pr_info("GIC: Using split EOI/Deactivate mode\n");
> +
>  	gic_data.dist_base = dist_base;
>  	gic_data.redist_regions = rdist_regs;
>  	gic_data.nr_redist_regions = nr_redist_regions;
> diff --git a/include/linux/irqchip/arm-gic-v3.h b/include/linux/irqchip/arm-gic-v3.h
> index ffbc034..bc98832 100644
> --- a/include/linux/irqchip/arm-gic-v3.h
> +++ b/include/linux/irqchip/arm-gic-v3.h
> @@ -104,6 +104,8 @@
>  #define GICR_SYNCR			0x00C0
>  #define GICR_MOVLPIR			0x0100
>  #define GICR_MOVALLR			0x0110
> +#define GICR_ISACTIVER			GICD_ISACTIVER
> +#define GICR_ICACTIVER			GICD_ICACTIVER
>  #define GICR_IDREGS			GICD_IDREGS
>  #define GICR_PIDR2			GICD_PIDR2
>  
> @@ -288,6 +290,7 @@
>  #define ICH_VMCR_PMR_MASK		(0xffUL << ICH_VMCR_PMR_SHIFT)
>  
>  #define ICC_EOIR1_EL1			sys_reg(3, 0, 12, 12, 1)
> +#define ICC_DIR_EL1			sys_reg(3, 0, 12, 11, 1)
>  #define ICC_IAR1_EL1			sys_reg(3, 0, 12, 12, 0)
>  #define ICC_SGI1R_EL1			sys_reg(3, 0, 12, 11, 5)
>  #define ICC_PMR_EL1			sys_reg(3, 0, 4, 6, 0)
> @@ -384,6 +387,12 @@ static inline void gic_write_eoir(u64 irq)
>  	isb();
>  }
>  
> +static inline void gic_write_dir(u64 irq)
> +{
> +	asm volatile("msr_s " __stringify(ICC_DIR_EL1) ", %0" : : "r" (irq));
> +	isb();
> +}
> +
>  struct irq_domain;
>  int its_cpu_init(void);
>  int its_init(struct device_node *node, struct rdists *rdists,
> 



From sudeep.holla at arm.com  Wed Aug 26 02:01:23 2015
From: sudeep.holla at arm.com (Sudeep Holla)
Date: Wed, 26 Aug 2015 10:01:23 +0100
Subject: [GIT PULL] ARM64: juno: SCPI and dependent drivers for v4.3
In-Reply-To: <10834223.pThsip28PI@phil>
References: <55C1E3FB.5090309@arm.com> <55CCAF50.4040503@arm.com>
 <20150821161732.GC14452@localhost> <10834223.pThsip28PI@phil>
Message-ID: <55DD8063.3080804@arm.com>



On 25/08/15 22:47, Heiko Stuebner wrote:
> Hi,
>
> Am Freitag, 21. August 2015, 09:17:32 schrieb Olof Johansson:
>>>> PSCI only covers CPU boot/cpuidle and platform suspend. It does not have
>>>> any provisions for DVFS and I'm not sure this could be easily
>>>> standardised (or whether we could find enough supporters to get it
>>>> adopted).
>>>
>>> Though we are not campaigning it as aggressively as PSCI.
>>
>> Which, given the resistance to pick up PSCI, this is unlikely to be used by
>> anyone...
>
> Rockchip seems to use SCPI to offload ddr frequency to a mcu scaling on the
> rk3368 ;-)
>

Good to hear that, thanks Heiko for letting us know. IMHO I must admit I
am still sceptical about large SCPI adoption.

Regards,
Sudeep


From nicolas.ferre at atmel.com  Wed Aug 26 02:04:39 2015
From: nicolas.ferre at atmel.com (Nicolas Ferre)
Date: Wed, 26 Aug 2015 11:04:39 +0200
Subject: [PATCH] ARM: at91/dt: corrections to i2c1 declaration to sama5d4
In-Reply-To: <1440578745-9585-1-git-send-email-nicolas.ferre@atmel.com>
References: <1440578745-9585-1-git-send-email-nicolas.ferre@atmel.com>
Message-ID: <55DD8127.1000909@atmel.com>

Le 26/08/2015 10:45, Nicolas Ferre a ?crit :
> From: Holger Busse <h.busse at kathrein-sachsen.de>
> 
> Correcting the dma declaration for i2c1 dma.
> 
> Signed-off-by: Holger Busse <h.busse at kathrein-sachsen.de>
> Signed-off-by: Nicolas Ferre <nicolas.ferre at atmel.com>

Oh, and I forgot to add:

Fixes: 4cc7cdf35c5f ("ARM: at91/dt: add i2c1 declaration to sama5d4")
Cc: stable at vger.kernel.org  # v4.1+

I'll add that when I including it to the "dt" branch.

Bye,

> ---
>  arch/arm/boot/dts/sama5d4.dtsi | 8 ++++----
>  1 file changed, 4 insertions(+), 4 deletions(-)
> 
> diff --git a/arch/arm/boot/dts/sama5d4.dtsi b/arch/arm/boot/dts/sama5d4.dtsi
> index 3ee22ee13c5a..1ba10e495f21 100644
> --- a/arch/arm/boot/dts/sama5d4.dtsi
> +++ b/arch/arm/boot/dts/sama5d4.dtsi
> @@ -939,11 +939,11 @@
>  				reg = <0xf8018000 0x4000>;
>  				interrupts = <33 IRQ_TYPE_LEVEL_HIGH 6>;
>  				dmas = <&dma1
> -					(AT91_XDMAC_DT_MEM_IF(0) | AT91_XDMAC_DT_PER_IF(1))
> -					AT91_XDMAC_DT_PERID(4)>,
> +					(AT91_XDMAC_DT_MEM_IF(0) | AT91_XDMAC_DT_PER_IF(1)
> +					| AT91_XDMAC_DT_PERID(4))>,
>  				       <&dma1
> -					(AT91_XDMAC_DT_MEM_IF(0) | AT91_XDMAC_DT_PER_IF(1))
> -					AT91_XDMAC_DT_PERID(5)>;
> +					(AT91_XDMAC_DT_MEM_IF(0) | AT91_XDMAC_DT_PER_IF(1)
> +					| AT91_XDMAC_DT_PERID(5))>;
>  				dma-names = "tx", "rx";
>  				pinctrl-names = "default";
>  				pinctrl-0 = <&pinctrl_i2c1>;
> 


-- 
Nicolas Ferre


From antonios.motakis at huawei.com  Wed Aug 26 02:12:27 2015
From: antonios.motakis at huawei.com (Antonios Motakis)
Date: Wed, 26 Aug 2015 11:12:27 +0200
Subject: [PATCH 00/13] arm64: Virtualization Host Extension support
In-Reply-To: <1436372356-30410-1-git-send-email-marc.zyngier@arm.com>
References: <1436372356-30410-1-git-send-email-marc.zyngier@arm.com>
Message-ID: <55DD82FB.60903@huawei.com>

Hello Marc,

On 08-Jul-15 18:19, Marc Zyngier wrote:
> ARMv8.1 comes with the "Virtualization Host Extension" (VHE for
> short), which enables simpler support of Type-2 hypervisors.
> 
> This extension allows the kernel to directly run at EL2, and
> significantly reduces the number of system registers shared between
> host and guest, reducing the overhead of virtualization.
> 
> In order to have the same kernel binary running on all versions of the
> architecture, this series makes heavy use of runtime code patching.
> 
> The first ten patches massage the KVM code to deal with VHE and enable
> Linux to run at EL2.

I am currently working on getting the Jailhouse hypervisor to work on AArch64.

I've been looking at your patches, trying to figure out the implications for Jailhouse. It seems there are a few :)

Jailhouse likes to be loaded by Linux into memory, and then to inject itself at a higher level than Linux (demoting Linux into being the "root cell"). This works on x86 and ARM (AArch32 and eventually AArch64 without VHE). What this means in ARM, is that Jailhouse hooks into the HVC stub exposed by Linux, and happily installs itself in EL2.

With Linux running in EL2 though, that won't be as straightforward. It looks like we can't just demote Linux to EL1 without breaking something. Obviously it's OK for us that KVM won't work, but it looks like at least the timer code will break horribly if we try to do something like that.

Any comments on this? One work around would be to just remap the incoming interrupt from the timer, so Linux never really realizes it's not running in EL2 anymore. Then we would also have to deal with the intricacies of removing and re-adding vCPUs to the Linux root cell, so we would have to maintain the illusion of running in EL2 for each one of them.

Cheers,
Antonios

> 
> The next patch catches an ugly case when VHE capable CPUs are paired
> with some of their less capable siblings. This should never happen,
> but hey...
> 
> The last two patches add an optimisation allowing a physical interrupt
> to be serviced on the host without doing a full save/restore, leading
> to potential reduction in interrupt latency.
> 
> This has been tested on the FVP_Base_SLV-V8-A model, and based on
> v4.2-rc1. I've put a branch out on:
> 
> git://git.kernel.org/pub/scm/linux/kernel/git/maz/arm-platforms.git kvm-arm64/vhe
> 
> Marc Zyngier (13):
>   arm/arm64: Add new is_kernel_in_hyp_mode predicate
>   arm64: Allow the arch timer to use the HYP timer
>   arm64: Add ARM64_HAS_VIRT_HOST_EXTN feature
>   arm64: KVM: skip HYP setup when already running in HYP
>   arm64: KVM: VHE: macroize VTCR_EL2 setup
>   arm64: KVM: VHE: Patch out kern_hyp_va
>   arm64: KVM: VHE: Patch out use of HVC
>   arm64: KVM: VHE: Preserve VHE config in world switch
>   arm64: KVM: VHE: Add alternatives for VHE-enabled world-switch
>   arm64: Add support for running Linux in EL2 mode
>   arm64: Panic when VHE and non VHE CPUs coexist
>   arm64: KVM: Split sysreg save/restore
>   arm64: KVM: VHE: Early interrupt handling
> 
>  arch/arm/include/asm/virt.h          |   5 +
>  arch/arm/kvm/arm.c                   | 134 ++++++++-----
>  arch/arm/kvm/mmu.c                   |   6 +
>  arch/arm64/include/asm/cpufeature.h  |   3 +-
>  arch/arm64/include/asm/kvm_arm.h     |   1 +
>  arch/arm64/include/asm/kvm_asm.h     |  40 +++-
>  arch/arm64/include/asm/kvm_emulate.h |   2 +
>  arch/arm64/include/asm/kvm_mmu.h     |  24 ++-
>  arch/arm64/include/asm/virt.h        |  25 +++
>  arch/arm64/kernel/cpufeature.c       |  11 ++
>  arch/arm64/kernel/head.S             |  38 +++-
>  arch/arm64/kernel/smp.c              |   4 +
>  arch/arm64/kvm/hyp-init.S            |   9 +-
>  arch/arm64/kvm/hyp.S                 | 363 ++++++++++++++++++++++++-----------
>  arch/arm64/kvm/vgic-v2-switch.S      |  19 +-
>  arch/arm64/kvm/vgic-v3-switch.S      |  33 ++--
>  arch/arm64/kvm/vhe-macros.h          |  54 ++++++
>  drivers/clocksource/arm_arch_timer.c |  96 +++++----
>  18 files changed, 638 insertions(+), 229 deletions(-)
>  create mode 100644 arch/arm64/kvm/vhe-macros.h
> 

-- 
Antonios Motakis
Virtualization Engineer
Huawei Technologies Duesseldorf GmbH
European Research Center
Riesstrasse 25, 80992 M?nchen



From jan.kiszka at siemens.com  Wed Aug 26 02:21:31 2015
From: jan.kiszka at siemens.com (Jan Kiszka)
Date: Wed, 26 Aug 2015 11:21:31 +0200
Subject: [PATCH 00/13] arm64: Virtualization Host Extension support
In-Reply-To: <55DD82FB.60903@huawei.com>
References: <1436372356-30410-1-git-send-email-marc.zyngier@arm.com>
 <55DD82FB.60903@huawei.com>
Message-ID: <55DD851B.4040106@siemens.com>

On 2015-08-26 11:12, Antonios Motakis wrote:
> Hello Marc,
> 
> On 08-Jul-15 18:19, Marc Zyngier wrote:
>> ARMv8.1 comes with the "Virtualization Host Extension" (VHE for
>> short), which enables simpler support of Type-2 hypervisors.
>>
>> This extension allows the kernel to directly run at EL2, and
>> significantly reduces the number of system registers shared between
>> host and guest, reducing the overhead of virtualization.
>>
>> In order to have the same kernel binary running on all versions of the
>> architecture, this series makes heavy use of runtime code patching.
>>
>> The first ten patches massage the KVM code to deal with VHE and enable
>> Linux to run at EL2.
> 
> I am currently working on getting the Jailhouse hypervisor to work on AArch64.
> 
> I've been looking at your patches, trying to figure out the implications for Jailhouse. It seems there are a few :)
> 
> Jailhouse likes to be loaded by Linux into memory, and then to inject itself at a higher level than Linux (demoting Linux into being the "root cell"). This works on x86 and ARM (AArch32 and eventually AArch64 without VHE). What this means in ARM, is that Jailhouse hooks into the HVC stub exposed by Linux, and happily installs itself in EL2.
> 
> With Linux running in EL2 though, that won't be as straightforward. It looks like we can't just demote Linux to EL1 without breaking something. Obviously it's OK for us that KVM won't work, but it looks like at least the timer code will break horribly if we try to do something like that.
> 
> Any comments on this? One work around would be to just remap the incoming interrupt from the timer, so Linux never really realizes it's not running in EL2 anymore. Then we would also have to deal with the intricacies of removing and re-adding vCPUs to the Linux root cell, so we would have to maintain the illusion of running in EL2 for each one of them.

Without knowing any of the details, I would say there are two strategies
regarding this:

- Disable KVM support in the Linux kernel - then we shouldn't boot into
  EL2 in the first place, should we?

- Emulate what Linux is missing after take-over by Jailhouse (we do
  this on x86 with VT-d interrupt remapping which cannot be disabled
  anymore for Linux once it started with it, and we cannot boot without
  it when we want to use the x2APIC).

Jan

-- 
Siemens AG, Corporate Technology, CT RTC ITP SES-DE
Corporate Competence Center Embedded Linux


From wxt at rock-chips.com  Wed Aug 26 02:24:39 2015
From: wxt at rock-chips.com (Caesar Wang)
Date: Wed, 26 Aug 2015 17:24:39 +0800
Subject: [RESEND PATCH v16 4/4] ARM: dts: add the support power-domain
 node on RK3288 SoCs
In-Reply-To: <7htwrn6l7g.fsf@deeprootsystems.com>
References: <1440487486-6154-1-git-send-email-wxt@rock-chips.com>
 <1440487486-6154-5-git-send-email-wxt@rock-chips.com>
 <7hfv37axhj.fsf@deeprootsystems.com>
 <CAD=FV=V6oG+9U=W_JZmqCuNo-9-5wW8ffZzG7ZE_3cnSTNAjFQ@mail.gmail.com>
 <7htwrn6l7g.fsf@deeprootsystems.com>
Message-ID: <55DD85D7.5010208@rock-chips.com>



? 2015?08?26? 06:45, Kevin Hilman ??:
> Doug Anderson <dianders at chromium.org> writes:
>
>> Kevin,
>>
>> On Tue, Aug 25, 2015 at 2:07 PM, Kevin Hilman <khilman at kernel.org> wrote:
>>> Caesar Wang <wxt at rock-chips.com> writes:
>>>
>>>> We can add more domains node in the future.
>>>> This patch add the needed clocks into power-controller.
>>>> As the discuess about all the device clocks being listed in
>>>> the power-domains itself.
>>>>
>>>> There are several reasons as follows:
>>>>
>>>> Firstly, the clocks need be turned off to save power when
>>>> the system enter the suspend state. So we need to enumerate
>>>> the clocks in the dts. In order to power domain can turn on and off.
>>> Yes, but this is the job of device drivers which are runtime PM adapted
>>> to gate their own clocks.  I agree these clocks need to be enumerated in
>>> the DTS, but they should be in the device nodes.
>> I _think_ what Caesar means is that the alternative to this patch is
>> to leave the clocks on all the time as they were during the early days
>> of Rockchip (AKA last year).  If the clocks are on all the time then
>> the power domain patches can work fine.  However, once you start
>> letting clocks turn off then you need to make sure that the power
>> domain code turns the back on temporarily.
> Yup, I understand that part, and many SoCs have this same "feature".
>
>>>> Secondly, the reset-circuit should reset be synchronous on RK3288,
>>>> then sync revoked. So we need to enable clocks of all devices.
>>>> In other words, we have to enable the clocks before you operate them
>>>> if all the device clocks are included in someone domians.
>>> Yes, this is pretty common for reset.
>>>
>>>> Someone wish was to get the clocks by reading the clocks from the
>>>> device nodes, We can do that but we can solve the above issues.
>>> I don't follow this sentence.  Are you saying doing that will not solve
>>> the above issues?  Why not?  Please explain.
>>>
>>> If there are non-device clocks that also need to be enabled before
>>> asserting reset, then those are candidates for the power-domain node,
>>> but not device clocks.
>> It's been a long time and I don't know that I've reviewed every
>> revision of this series, but I think there was a proposal that we
>> shouldn't list clocks here.  Instead we should search through and find
>> all devices that refer to this power domain, reach in and find their
>> clocks, and turn them on.  Did I get that right?
> Yes...

Sounds resonable, the domain(e.g. "pd_vio"...) idle will be abnormal but 
you have registered all devices.
Why?
AFAIK, you need turn on the noc/ip clocks if we are operating the 
"pd_vio" domain to enter the idle status.
if the noc is same clock with ip side.  We need turn on the IP side 
clocks. Otherwise we need turn on the noc clocks.

>> To put things in a
>> concrete way, for pd_vio we'd go through the entire device tree
>> ourselves and find all properties that look like "power-domains =
>> <&power RK3288_PD_VIO>;".  We'd then find the parent of those
>> properties and look for a property named "clocks".  We'd then iterate
>> over all those clocks and turn those on.  Did I get that right?
> ... but you make it sound like more work than it is.  The genpd already
> keeps a list of devices that refer to the power domain.  In fact, the
> genpd 'attach' method can be platform-specific, so could be used to keep
> track of a list (or a subset) of clocks which are needed for reset.
>
>> The above doesn't seem like a terribly great idea to me for a number
>> of reasons, including:
>>
>> 1. If I remember correctly, it's important to turn on clocks for
>> devices even if they're not something you're using / have a driver
>> for.  If you don't then the device won't get reset properly and this
>> can affect things like suspend/resume because the hardware in the SoC
>> will query all devices at suspend time to make sure they're ready.
> Correct.  This condition also exists in the clock framework when unused
> clocks are disabled, or if you have drivers but PM_RUNTIME is disabled
> (which can happen from userspace on a per-device basis) so it needs to
> be understood and managed already.
>
>> If
>> a device is wedged because its clock wasn't on at the right them then
>> it will cause problems.
> Right.  I'm not arguing that the power domain doesn't have to deal with
> device clocks. It has to for sync reset.  The objection I have have is
> where these clocks are described.
>
>> 2. If we absolutely need to turn all clocks and we get clocks from
>> device tree nodes on then it means we need device tree nodes for every
>> device in the domain.
> Isn't that the end goal?
>
>> These would be needed even if there are no
>> accepted bindings for this device yet.  So we'd need to do one of: A)
>> Block power domain patches on feature complete bindings for all
>> drivers; B) Make up non-approved compatible strings for all devices
>> and throw them into the DTS; C) Add nodes in the DTS without a
>> compatible string just to satisfy the power domain requirements.  None
>> of these seem terribly appealing.
> well, I think we can be slightly more accomodating than that and go for
> somewhere in between:
>
> D) In the power-domain DTS, clearly describe why each clock is needed by
> the power-domain.  In particular list out clocks that are not device
> clocks (and why they need to be asserted for reset) and separate those
> from device clocks which are only listed in the power-domain because
> there is not *yet* a driver/binding for that device node.
>
> Doing it that way also makes it clear that when a new driver/binding is
> added, the clocks should be removed from the power-domain node and put
> into the device node.
>
> Also, this addresses my primary concern that the DTS acurately describes
> the hardware.  IOW, in hardware, most of these clocks are are properties
> of devices, not power-domains, and the DT should reflect that.
>
> IMO, if it's not describing the hardware, and is a placeholder until a
> driver/binding is in place, it should be properly documented.
>
>> 3. It is entirely possible that there are clocks that will be listed
>> in the individual devices that aren't needed for powering on the power
>> domain.  I'd tend to believe that PCLK_EDP_CTRL (the pixel clock)
>> doesn't really need to be turned on when adjusting the "VIO" power
>> domain.  Right now Caesar has it listed, but it probably isn't needed
>> (Caesar: can you confirm?).
> Yes, I suspect there are several of those, which is also why I'd like to
> see the clocks in the power-domain node described in detail, and exacly
> why they're needed to be enabled.
>
> Also, in the current proposed DTS, clocks that are listed in both device
> nodes and the power domain are also suspicous, especially when the
> device node doesn't have a power-domain property.  (c.f. vop[bl] nodes
> and ACLK_VOP[01] clocks.)  For that matter, this series doesn't add any
> devices to the power domains, which makes it even more confusing about
> how this is meant to work.  IOW, with no devices belonging to
> power-domains, how are the power-domain power_on/power_off callbacks
> being called?

Okay, As the cover-letter lists.
We can add the EDP/VOP domain node to test in next-kernel.

Also, the chromium-3.14 has some devices to complete it.

https://chromium.googlesource.com/chromiumos/third_party/kernel/+/v3.14

----
Thanks,
Caesar


>> 4. It seems just slightly brittle to be reaching into other device
>> nodes and making assumptions about their properties.  Yeah, it's
>> probably safe to assume that "clocks" has a list of clocks and
>> "power-domains" will point to something whose first entry is a
>> phandle, but it still seems just a tad bit like violating an
>> abstraction barrier.
> shmobile is already doing this with platform-specific genpd attach
> callbacks, and using the pm_clk API.  I don't see any issues with that.
>
>> Anyway, perhaps I'm misunderstanding, or perhaps my concerns are
>> simply not for important things.  If so feel free to yell at me.  ;)
> No need for me to yell. Your concerns are perfectly valid, and it's not
> my style anyways. ;)
>
> Thanks for the feedback,
>
> Kevin
>
>
>
>
> _______________________________________________
> Linux-rockchip mailing list
> Linux-rockchip at lists.infradead.org
> http://lists.infradead.org/mailman/listinfo/linux-rockchip



From sudeep.holla at arm.com  Wed Aug 26 02:26:54 2015
From: sudeep.holla at arm.com (Sudeep Holla)
Date: Wed, 26 Aug 2015 10:26:54 +0100
Subject: [PATCH v3 1/1] misc: sram: add dev_pm_ops to support module power
 gate
In-Reply-To: <CY1PR0301MB0843AB9C6330D29EBD5F47DA83610@CY1PR0301MB0843.namprd03.prod.outlook.com>
References: <1438272681-29338-1-git-send-email-shenwei.wang@freescale.com>
 <55DC677E.1030004@arm.com>
 <CY1PR0301MB0843D5CB5FFC56991B90EB4283610@CY1PR0301MB0843.namprd03.prod.outlook.com>
 <55DC74CF.7070300@arm.com>
 <CY1PR0301MB084302FA2AA9582A3BA9B50B83610@CY1PR0301MB0843.namprd03.prod.outlook.com>
 <55DC7E5E.5020701@arm.com>
 <CY1PR0301MB0843A508122C7FCF3969AF3D83610@CY1PR0301MB0843.namprd03.prod.outlook.com>
 <55DC91BE.7090107@arm.com>
 <CY1PR0301MB0843AB9C6330D29EBD5F47DA83610@CY1PR0301MB0843.namprd03.prod.outlook.com>
Message-ID: <55DD865E.4050603@arm.com>



On 25/08/15 20:35, Shenwei Wang wrote:
>
>
>> -----Original Message-----
>> From: Sudeep Holla [mailto:sudeep.holla at arm.com]
>> Sent: 2015?8?25? 11:03
>> To: Wang Shenwei-B38339
>> Cc: Sudeep Holla; gregkh at linuxfoundation.org; arnd at arndb.de; Huang
>> Yongcai-B20788; linux-arm-kernel at lists.infradead.org
>> Subject: Re: [PATCH v3 1/1] misc: sram: add dev_pm_ops to support module
>> power gate
>>>> I don't like that solution as it's not scalable with SRAM size and
>>>> saving all the content of SRAM just because of few active regions
>>>> makes no sense to me at-least. I prefer leaving it to the users to
>>>> handle that rather than SRAM driver.
>>>
>>> I don't think it is not scalable. The choice should be made by the
>>> application. From the driver side, it should be able to provide the
>>> way to retain its contents during power gate.
>>>
>>
>> OK that was just my opinion. I just wanted to avoid unnecessary save/restore, e.g.
>> if say just few kilobytes are active in say 32MB SRAM, you will save/restore entire
>> SRAM ?
>
> Although in theory a SoC can integrate such a big SRAM like 32MB inside, but I don't
> think anyone will practice it because the cost is too high. So far, the most popular size
> of a SRAM in a SoC is hundreds of KB.
>

I have seen 32MB SRAM and people are thinking of doubling it. So I
disagree, especially if that's your main argument.

On Android targets, I have seen suspend-to-ram used quite aggressively
and this save/restore might add significant delay and might be
unnecessary most of the time.

>> Anyways, the driver is saving/restoring the memory unconditionally whenever DT
>> sets that boolean right ? at-least as the patch stands.
>
> The saving/restoring feature is not enabled by default in this patch. To enable it you
> need to add the can-power-gate string in the relating DT node.

Yes I understood and that's what I mentioned above, but once it's
present in DT, it's unconditional for the entire SRAM which might not be
used actively. So I still don't like this approach.

Regards,
Sudeep


From wxt at rock-chips.com  Wed Aug 26 02:27:59 2015
From: wxt at rock-chips.com (Caesar Wang)
Date: Wed, 26 Aug 2015 17:27:59 +0800
Subject: [RESEND PATCH v16 3/4] soc: rockchip: power-domain: Add power
 domain driver
In-Reply-To: <7hwpwjaxxv.fsf@deeprootsystems.com>
References: <1440487486-6154-1-git-send-email-wxt@rock-chips.com>
 <1440487486-6154-4-git-send-email-wxt@rock-chips.com>
 <7hwpwjaxxv.fsf@deeprootsystems.com>
Message-ID: <55DD869F.9010309@rock-chips.com>



? 2015?08?26? 04:57, Kevin Hilman ??:
> Caesar Wang <wxt at rock-chips.com> writes:
>
>> This driver is found on RK3288 SoCs.
>>
>> In order to meet high performance and low power requirements, a power
>> management unit is designed or saving power when RK3288 in low power
>> mode.
>> The RK3288 PMU is dedicated for managing the power of the whole chip.
>>
>> PMU can work in the Low Power Mode by setting bit[0] of PMU_PWRMODE_CON
>> register. After setting the register, PMU would enter the Low Power mode.
>> In the low power mode, pmu will auto power on/off the specified power
>> domain, send idle req to specified power domain, shut down/up pll and
>> so on. All of above are configurable by setting corresponding registers.
>>
>> Signed-off-by: jinkun.hong <jinkun.hong at rock-chips.com>
>> Signed-off-by: Caesar Wang <wxt at rock-chips.com>
> [...]
>
>> diff --git a/drivers/soc/rockchip/Kconfig b/drivers/soc/rockchip/Kconfig
>> new file mode 100644
>> index 0000000..87a09c3
>> --- /dev/null
>> +++ b/drivers/soc/rockchip/Kconfig
>> @@ -0,0 +1,13 @@
>> +#
>> +# Rockchip Soc drivers
>> +#
>> +config PM_GENERIC_DOMAINS
> Why are you (re)defining this config option?  This name is already used in kernel/pm/Kconfig.

Fixed.

----
Thanks,
Caesar

> Kevin
>
> _______________________________________________
> Linux-rockchip mailing list
> Linux-rockchip at lists.infradead.org
> http://lists.infradead.org/mailman/listinfo/linux-rockchip



From antonios.motakis at huawei.com  Wed Aug 26 02:28:47 2015
From: antonios.motakis at huawei.com (Antonios Motakis)
Date: Wed, 26 Aug 2015 11:28:47 +0200
Subject: [PATCH 00/13] arm64: Virtualization Host Extension support
In-Reply-To: <55DD851B.4040106@siemens.com>
References: <1436372356-30410-1-git-send-email-marc.zyngier@arm.com>
 <55DD82FB.60903@huawei.com> <55DD851B.4040106@siemens.com>
Message-ID: <55DD86CF.70309@huawei.com>



On 26-Aug-15 11:21, Jan Kiszka wrote:
> On 2015-08-26 11:12, Antonios Motakis wrote:
>> Hello Marc,
>>
>> On 08-Jul-15 18:19, Marc Zyngier wrote:
>>> ARMv8.1 comes with the "Virtualization Host Extension" (VHE for
>>> short), which enables simpler support of Type-2 hypervisors.
>>>
>>> This extension allows the kernel to directly run at EL2, and
>>> significantly reduces the number of system registers shared between
>>> host and guest, reducing the overhead of virtualization.
>>>
>>> In order to have the same kernel binary running on all versions of the
>>> architecture, this series makes heavy use of runtime code patching.
>>>
>>> The first ten patches massage the KVM code to deal with VHE and enable
>>> Linux to run at EL2.
>>
>> I am currently working on getting the Jailhouse hypervisor to work on AArch64.
>>
>> I've been looking at your patches, trying to figure out the implications for Jailhouse. It seems there are a few :)
>>
>> Jailhouse likes to be loaded by Linux into memory, and then to inject itself at a higher level than Linux (demoting Linux into being the "root cell"). This works on x86 and ARM (AArch32 and eventually AArch64 without VHE). What this means in ARM, is that Jailhouse hooks into the HVC stub exposed by Linux, and happily installs itself in EL2.
>>
>> With Linux running in EL2 though, that won't be as straightforward. It looks like we can't just demote Linux to EL1 without breaking something. Obviously it's OK for us that KVM won't work, but it looks like at least the timer code will break horribly if we try to do something like that.
>>
>> Any comments on this? One work around would be to just remap the incoming interrupt from the timer, so Linux never really realizes it's not running in EL2 anymore. Then we would also have to deal with the intricacies of removing and re-adding vCPUs to the Linux root cell, so we would have to maintain the illusion of running in EL2 for each one of them.
> 
> Without knowing any of the details, I would say there are two strategies
> regarding this:
> 
> - Disable KVM support in the Linux kernel - then we shouldn't boot into
>   EL2 in the first place, should we?

We would have to ask the user to patch the kernel, to ignore VHE and keep all the hyp stub magic that we rely on currently. It is an option of course.

> 
> - Emulate what Linux is missing after take-over by Jailhouse (we do
>   this on x86 with VT-d interrupt remapping which cannot be disabled
>   anymore for Linux once it started with it, and we cannot boot without
>   it when we want to use the x2APIC).

Essentially what I described above; let's call it nested virtualization without the virtualization parts? :)

> 
> Jan
> 

-- 
Antonios Motakis
Virtualization Engineer
Huawei Technologies Duesseldorf GmbH
European Research Center
Riesstrasse 25, 80992 M?nchen



From libv at skynet.be  Wed Aug 26 02:44:39 2015
From: libv at skynet.be (Luc Verhaegen)
Date: Wed, 26 Aug 2015 11:44:39 +0200
Subject: [PATCH v2 1/7] drm/vc4: Add devicetree bindings for VC4.
In-Reply-To: <1439934848-7196-2-git-send-email-eric@anholt.net>
References: <1439934848-7196-1-git-send-email-eric@anholt.net>
 <1439934848-7196-2-git-send-email-eric@anholt.net>
Message-ID: <20150826094438.GB2032@skynet.be>

On Tue, Aug 18, 2015 at 02:54:02PM -0700, Eric Anholt wrote:
> VC4 is the GPU (display and 3D) subsystem present on the 2835 and some
> other Broadcom SoCs.
> ...
> +Broadcom VC4 GPU
> +
> +The VC4 device present on the Raspberry Pi includes a display system
> +with HDMI output and the HVS scaler for compositing display planes.

Is this a direct hw driver implementation, banging registers, or is this 
talking to the os/firmware/binary blob running on the videocore dsp?

Luc Verhaegen.


From jan.kiszka at siemens.com  Wed Aug 26 02:54:38 2015
From: jan.kiszka at siemens.com (Jan Kiszka)
Date: Wed, 26 Aug 2015 11:54:38 +0200
Subject: [PATCH 00/13] arm64: Virtualization Host Extension support
In-Reply-To: <55DD86CF.70309@huawei.com>
References: <1436372356-30410-1-git-send-email-marc.zyngier@arm.com>
 <55DD82FB.60903@huawei.com> <55DD851B.4040106@siemens.com>
 <55DD86CF.70309@huawei.com>
Message-ID: <55DD8CDE.8000407@siemens.com>

On 2015-08-26 11:28, Antonios Motakis wrote:
> 
> 
> On 26-Aug-15 11:21, Jan Kiszka wrote:
>> On 2015-08-26 11:12, Antonios Motakis wrote:
>>> Hello Marc,
>>>
>>> On 08-Jul-15 18:19, Marc Zyngier wrote:
>>>> ARMv8.1 comes with the "Virtualization Host Extension" (VHE for
>>>> short), which enables simpler support of Type-2 hypervisors.
>>>>
>>>> This extension allows the kernel to directly run at EL2, and
>>>> significantly reduces the number of system registers shared between
>>>> host and guest, reducing the overhead of virtualization.
>>>>
>>>> In order to have the same kernel binary running on all versions of the
>>>> architecture, this series makes heavy use of runtime code patching.
>>>>
>>>> The first ten patches massage the KVM code to deal with VHE and enable
>>>> Linux to run at EL2.
>>>
>>> I am currently working on getting the Jailhouse hypervisor to work on AArch64.
>>>
>>> I've been looking at your patches, trying to figure out the implications for Jailhouse. It seems there are a few :)
>>>
>>> Jailhouse likes to be loaded by Linux into memory, and then to inject itself at a higher level than Linux (demoting Linux into being the "root cell"). This works on x86 and ARM (AArch32 and eventually AArch64 without VHE). What this means in ARM, is that Jailhouse hooks into the HVC stub exposed by Linux, and happily installs itself in EL2.
>>>
>>> With Linux running in EL2 though, that won't be as straightforward. It looks like we can't just demote Linux to EL1 without breaking something. Obviously it's OK for us that KVM won't work, but it looks like at least the timer code will break horribly if we try to do something like that.
>>>
>>> Any comments on this? One work around would be to just remap the incoming interrupt from the timer, so Linux never really realizes it's not running in EL2 anymore. Then we would also have to deal with the intricacies of removing and re-adding vCPUs to the Linux root cell, so we would have to maintain the illusion of running in EL2 for each one of them.
>>
>> Without knowing any of the details, I would say there are two strategies
>> regarding this:
>>
>> - Disable KVM support in the Linux kernel - then we shouldn't boot into
>>   EL2 in the first place, should we?
> 
> We would have to ask the user to patch the kernel, to ignore VHE and keep all the hyp stub magic that we rely on currently. It is an option of course.

Patch or reconfigure? CONFIG_KVM isn't mandatory for arm64, is it?

Jan

> 
>>
>> - Emulate what Linux is missing after take-over by Jailhouse (we do
>>   this on x86 with VT-d interrupt remapping which cannot be disabled
>>   anymore for Linux once it started with it, and we cannot boot without
>>   it when we want to use the x2APIC).
> 
> Essentially what I described above; let's call it nested virtualization without the virtualization parts? :)
> 
>>
>> Jan
>>
> 

-- 
Siemens AG, Corporate Technology, CT RTC ITP SES-DE
Corporate Competence Center Embedded Linux


From marc.zyngier at arm.com  Wed Aug 26 02:59:11 2015
From: marc.zyngier at arm.com (Marc Zyngier)
Date: Wed, 26 Aug 2015 10:59:11 +0100
Subject: [PATCH 00/13] arm64: Virtualization Host Extension support
In-Reply-To: <55DD851B.4040106@siemens.com>
References: <1436372356-30410-1-git-send-email-marc.zyngier@arm.com>
 <55DD82FB.60903@huawei.com> <55DD851B.4040106@siemens.com>
Message-ID: <55DD8DEF.9080301@arm.com>

On 26/08/15 10:21, Jan Kiszka wrote:
> On 2015-08-26 11:12, Antonios Motakis wrote:
>> Hello Marc,
>> 
>> On 08-Jul-15 18:19, Marc Zyngier wrote:
>>> ARMv8.1 comes with the "Virtualization Host Extension" (VHE for 
>>> short), which enables simpler support of Type-2 hypervisors.
>>> 
>>> This extension allows the kernel to directly run at EL2, and 
>>> significantly reduces the number of system registers shared
>>> between host and guest, reducing the overhead of virtualization.
>>> 
>>> In order to have the same kernel binary running on all versions
>>> of the architecture, this series makes heavy use of runtime code
>>> patching.
>>> 
>>> The first ten patches massage the KVM code to deal with VHE and
>>> enable Linux to run at EL2.
>> 
>> I am currently working on getting the Jailhouse hypervisor to work
>> on AArch64.
>> 
>> I've been looking at your patches, trying to figure out the
>> implications for Jailhouse. It seems there are a few :)
>> 
>> Jailhouse likes to be loaded by Linux into memory, and then to
>> inject itself at a higher level than Linux (demoting Linux into
>> being the "root cell"). This works on x86 and ARM (AArch32 and
>> eventually AArch64 without VHE). What this means in ARM, is that
>> Jailhouse hooks into the HVC stub exposed by Linux, and happily
>> installs itself in EL2.
>> 
>> With Linux running in EL2 though, that won't be as straightforward.
>> It looks like we can't just demote Linux to EL1 without breaking
>> something. Obviously it's OK for us that KVM won't work, but it
>> looks like at least the timer code will break horribly if we try to
>> do something like that.
>> 
>> Any comments on this? One work around would be to just remap the
>> incoming interrupt from the timer, so Linux never really realizes
>> it's not running in EL2 anymore. Then we would also have to deal
>> with the intricacies of removing and re-adding vCPUs to the Linux
>> root cell, so we would have to maintain the illusion of running in
>> EL2 for each one of them.

Unfortunately, there is more to downgrading to EL1 than just interrupts.
You need to migrate the whole VM context from EL2 to EL1 in an atomic
fashion, clear the HCR_EL2.E2H and HCR_EL2.TGE bits while running at EL2
(which is a bit like pulling the rug from under your own feet so you
need to transition via a low mapping or an idmap), reinstall the EL2
stub and do an exception return into EL1.

And that's only for the CPU. Downgrading to EL1 has other fun
consequences at the system level (SMMUs listening to TLB traffic would
need to be reconfigured on the flight - it's a joke, don't even think of
it).

> 
> Without knowing any of the details, I would say there are two
> strategies regarding this:
> 
> - Disable KVM support in the Linux kernel - then we shouldn't boot
> into EL2 in the first place, should we?

Disabling KVM support won't drop the kernel to EL1. At least that's not
what the current code does (we stay at EL2 if we detect VHE), and that's
way too early to be able to parse a command line option.

> - Emulate what Linux is missing after take-over by Jailhouse (we do 
> this on x86 with VT-d interrupt remapping which cannot be disabled 
> anymore for Linux once it started with it, and we cannot boot
> without it when we want to use the x2APIC).

I can't really see what you want to emulate (I'm afraid I'm lacking the
x86-specific background).

As far as I can see, the only practical solution to this is to have a
VHE config option, and Jailhouse that can be set to conflict it (depends
on !VHE).

Thanks,

	M.
-- 
Jazz is not dead. It just smells funny...


From marc.zyngier at arm.com  Wed Aug 26 03:09:58 2015
From: marc.zyngier at arm.com (Marc Zyngier)
Date: Wed, 26 Aug 2015 11:09:58 +0100
Subject: [PATCH v3 1/4] irqchip: GICv3: Convert to EOImode == 1
In-Reply-To: <55DD7EDB.7010208@linaro.org>
References: <1440503605-10185-1-git-send-email-marc.zyngier@arm.com>
 <1440503605-10185-2-git-send-email-marc.zyngier@arm.com>
 <55DD7EDB.7010208@linaro.org>
Message-ID: <55DD9076.7080000@arm.com>

On 26/08/15 09:54, Eric Auger wrote:
> Hi Marc,
> On 08/25/2015 01:53 PM, Marc Zyngier wrote:
>> So far, GICv3 has been used in with EOImode == 0. The effect of this
>> mode is to perform the priority drop and the deactivation of the
>> interrupt at the same time.
>>
>> While this works perfectly for Linux (we only have a single priority),
>> it causes issues when an interrupt is forwarded to a guest, and when
>> we want the guest to perform the EOI itself.
>>
>> For this case, the GIC architecture provides EOImode == 1, where:
>> - A write to ICC_EOIR1_EL1 drops the priority of the interrupt and
>>   leaves it active. Other interrupts at the same priority level can
>>   now be taken, but the active interrupt cannot be taken again
>> - A write to ICC_DIR_EL1 marks the interrupt as inactive, meaning
>>   it can now be taken again.
>>
>> This patch converts the driver to be able to use this new mode,
>> depending on whether or not the kernel can behave as a hypervisor.
>> No feature change.
>>
>> Reviewed-by: Eric Auger <eric.auger at linaro.org>
>> Signed-off-by: Marc Zyngier <marc.zyngier at arm.com>
>> ---
>>  drivers/irqchip/irq-gic-v3.c       | 39 ++++++++++++++++++++++++++++++++++----
>>  include/linux/irqchip/arm-gic-v3.h |  9 +++++++++
>>  2 files changed, 44 insertions(+), 4 deletions(-)
>>
>> diff --git a/drivers/irqchip/irq-gic-v3.c b/drivers/irqchip/irq-gic-v3.c
>> index c52f7ba..addd2ee 100644
>> --- a/drivers/irqchip/irq-gic-v3.c
>> +++ b/drivers/irqchip/irq-gic-v3.c
>> @@ -30,6 +30,7 @@
>>  #include <asm/cputype.h>
>>  #include <asm/exception.h>
>>  #include <asm/smp_plat.h>
>> +#include <asm/virt.h>
>>  
>>  #include "irq-gic-common.h"
>>  #include "irqchip.h"
>> @@ -50,6 +51,7 @@ struct gic_chip_data {
>>  };
>>  
>>  static struct gic_chip_data gic_data __read_mostly;
>> +static struct static_key supports_deactivate = STATIC_KEY_INIT_TRUE;
> 
> in http://www.spinics.net/lists/arm-kernel/msg439813.html, Catalin
> reported the direct usage of static_key was deprecated. Sorry I learned
> that after my last review.
> 
> see https://lkml.org/lkml/2015/8/3/539

Hi Eric,

I'm aware of Peter's work to rework static keys, but that code is not
merged yet (though I believe it is on its way to 4.3). I have an
additional patch that repaints the code to use static_key_likely() all
over the place, but I keep it separate for the time being.

If this series makes it in for 4.3, I'll post the repainting patch after
-rc1. Otherwise, I'll just update it in my tree.

I'm about to post v4 anyway, and I'll mention this in the cover letter.

Thanks,

	M.
-- 
Jazz is not dead. It just smells funny...


From ard.biesheuvel at linaro.org  Wed Aug 26 03:37:17 2015
From: ard.biesheuvel at linaro.org (Ard Biesheuvel)
Date: Wed, 26 Aug 2015 12:37:17 +0200
Subject: [PATCH] arm: Handle starting up in secure mode
In-Reply-To: <1440424572-27116-1-git-send-email-cov@codeaurora.org>
References: <1440424572-27116-1-git-send-email-cov@codeaurora.org>
Message-ID: <CAKv+Gu90tTKEBpdrarvnVMFqH27WhxRwvbeXNuhR12FFBOtuYg@mail.gmail.com>

On 24 August 2015 at 15:55, Christopher Covington <cov at codeaurora.org> wrote:
> ARM Linux appears to have never been made aware of the ARMv7 security
> extensions. When CONFIG_ARM_SEC_EXT=y, have it probe for its security
> state by checking whether CNTFRQ is writeable and potentially make
> mode changes based on the information. The most features are available
> from hypervisor (HYP) mode, so switch to it possible. Failing that,
> prefer non-secure supervisor (SVC) mode to secure supervisor mode.
>
> Signed-off-by: Christopher Covington <cov at codeaurora.org>

Nice hack! One comment below ...

> ---
>  arch/arm/include/asm/sec.h         |  27 +++++++
>  arch/arm/include/uapi/asm/ptrace.h |   1 +
>  arch/arm/kernel/Makefile           |   1 +
>  arch/arm/kernel/head.S             |   3 +
>  arch/arm/kernel/mon-stub.S         | 158 +++++++++++++++++++++++++++++++++++++
>  arch/arm/mm/Kconfig                |  20 ++++-
>  6 files changed, 206 insertions(+), 4 deletions(-)
>  create mode 100644 arch/arm/include/asm/sec.h
>  create mode 100644 arch/arm/kernel/mon-stub.S
>
> diff --git a/arch/arm/include/asm/sec.h b/arch/arm/include/asm/sec.h
> new file mode 100644
> index 0000000..4a9a573
> --- /dev/null
> +++ b/arch/arm/include/asm/sec.h
> @@ -0,0 +1,27 @@
> +/*
> + * Copyright (c) 2014, The Linux Foundation. All rights reserved.
> + *
> + * This program is free software; you can redistribute it and/or modify
> + * it under the terms of the GNU General Public License version 2 and
> + * only 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.
> + */
> +
> +#ifndef SEC_H
> +#define SEC_H
> +
> +#ifndef __ASSEMBLY__
> +
> +#ifdef CONFIG_ARM_SEC_EXT
> +extern int __boot_cpu_secure;
> +#else
> +#define __boot_cpu_secure 0
> +#endif
> +
> +#endif /* ! __ASSEMBLY__ */
> +
> +#endif /* SEC_H */
> diff --git a/arch/arm/include/uapi/asm/ptrace.h b/arch/arm/include/uapi/asm/ptrace.h
> index 5af0ed1..70ff6bf 100644
> --- a/arch/arm/include/uapi/asm/ptrace.h
> +++ b/arch/arm/include/uapi/asm/ptrace.h
> @@ -53,6 +53,7 @@
>  #endif
>  #define FIQ_MODE       0x00000011
>  #define IRQ_MODE       0x00000012
> +#define MON_MODE       0x00000016
>  #define ABT_MODE       0x00000017
>  #define HYP_MODE       0x0000001a
>  #define UND_MODE       0x0000001b
> diff --git a/arch/arm/kernel/Makefile b/arch/arm/kernel/Makefile
> index e69f7a1..a60a0f7 100644
> --- a/arch/arm/kernel/Makefile
> +++ b/arch/arm/kernel/Makefile
> @@ -87,6 +87,7 @@ head-y                        := head$(MMUEXT).o
>  obj-$(CONFIG_DEBUG_LL) += debug.o
>  obj-$(CONFIG_EARLY_PRINTK)     += early_printk.o
>
> +obj-$(CONFIG_ARM_SEC_EXT)      += mon-stub.o
>  obj-$(CONFIG_ARM_VIRT_EXT)     += hyp-stub.o
>  ifeq ($(CONFIG_ARM_PSCI),y)
>  obj-y                          += psci.o psci-call.o
> diff --git a/arch/arm/kernel/head.S b/arch/arm/kernel/head.S
> index 29e2991..d137ba4 100644
> --- a/arch/arm/kernel/head.S
> +++ b/arch/arm/kernel/head.S
> @@ -85,6 +85,9 @@ ENTRY(stext)
>   THUMB(        .thumb                  )       @ switch to Thumb now.
>   THUMB(1:                      )
>
> +#ifdef CONFIG_ARM_SEC_EXT
> +       bl      __mon_stub_install
> +#endif
>  #ifdef CONFIG_ARM_VIRT_EXT
>         bl      __hyp_stub_install
>  #endif
> diff --git a/arch/arm/kernel/mon-stub.S b/arch/arm/kernel/mon-stub.S
> new file mode 100644
> index 0000000..ab1a361
> --- /dev/null
> +++ b/arch/arm/kernel/mon-stub.S
> @@ -0,0 +1,158 @@
> +/*
> + * Copyright (c) 2014, The Linux Foundation. All rights reserved.
> + *
> + * This program is free software; you can redistribute it and/or modify
> + * it under the terms of the GNU General Public License version 2 and
> + * only 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/linkage.h>
> +#include <asm/assembler.h>
> +#include <asm/sec.h>
> +
> +.data
> +ENTRY(__boot_cpu_secure)
> +       .long   0
> +.text
> +
> +/*
> + * ARM Linux has the most features available in hypervisor mode and
> + * running in non-secure mode is recommended. Thus, try to get into
> + * hypervisor mode if we're not already there, or failing that, try
> + * to get into non-secure supervisor mode.
> + */
> +ENTRY(__mon_stub_install)
> +       /*
> +        * Store the mode field of the CPSR in r4 and return early if we're
> +        * already in hypervisor mode.
> +        */
> +       mrs     r4, cpsr
> +       and     r4, r4, #MODE_MASK
> +       cmp     r4, #HYP_MODE
> +       reteq   lr
> +
> +       /*
> +        * Save the link register in a non-banked register, r5, so that we
> +        * still have access to it after mode switches.
> +        */
> +       mov     r5, lr
> +
> +       /*
> +        * Read ID_PFR1 and store the value in r6. This register indicates
> +        * the presence of the security and virtualization extensions. The
> +        * former is interesting because we must traverse secure monitor mode
> +        * to get to hypervisor mode and it allows easy manipulation of
> +        * exception vectors via the Vector Base Address Register (VBAR).
> +        *
> +        * ID_PFR1 also indicates whether the generic timer is present, which
> +        * has a handy register for our purposes, CNTFRQ. Accesses won't trap
> +        * even with higher exception levels in AArch64 and writes will only
> +        * succeed from the highest exception level on a system (the undefined
> +        * exception from a failed write is used as a branch).
> +        */
> +
> +       mrc   p15, 0, r6, c0, c1, 1     @ ID_PFR1
> +
> +       /*
> +        * If we're in monitor mode then we know the security setting and can
> +        * begin the transition to hypervisor or non-secure supervisor mode
> +        * immediately.
> +        */
> +
> +       cmp     r4, #MON_MODE
> +       beq     monitor
> +
> +       /*
> +        * Check that the security extensions and generic timer are present.
> +        */
> +       and     r7, r6, #0xf0
> +       cmp     r7, #0x10
> +       cmpne   r7, #0x20
> +       retne   lr
> +       and     r8, r6, #0xf0000
> +       cmp     r8, #0x10000
> +       retne   lr
> +
> +       /*
> +        * Set things up so that if a CNTFRQ access causes an undefined
> +        * instruction exception, we return to the address indicated in r5
> +        * in the mode indicated in r4.
> +        */
> +       adr     r7, __mon_stub_vectors
> +       mcr     p15, 0, r7, c12, c0, 0  @ set vector base address (VBAR)
> +
> +       mrc     p15, 0, r7, c14, c0, 0  @ CNTFRQ
> +       mcr     p15, 0, r7, c14, c0, 0  @ CNTFRQ
> +
> +       /*
> +        * If we got this far, switch to monitor mode and prepare for further
> +        * switching.
> +        */
> +       cps     #MON_MODE
> +
> +monitor:
> +       /*
> +        * TODO: Handle SIF and separate secure physical memory in general
> +        */
> +       mrc     p15, 0, r8, c1, c1, 0   @ get secure configuration (SCR)
> +       orr     r8, r8, #1              @ non-secure (NS)
> +
> +       mov     r8, #1
> +       ldr     r7, =__boot_cpu_secure
> +       str     r8, [r7]

'=__boot_cpu_secure' gives you a link time virtual address, which is
unusable at this point, since you are still running with the MMU off.

c022f99c:       e59f707c        ldr     r7, [pc, #124]  ; c022fa20
c022f9a0:       e5878000        str     r8, [r7]

and

c022fa20:       c0f31508        .word   0xc0f31508

You need to use a PC relative reference instead.

-- 
Ard.


> +
> +       /*
> +        * See whether the switch will be to hypervisor or supervisor.
> +        */
> +       and     r7, r6, #0xf000
> +       cmp     r7, #0x1000
> +       mcrne   p15, 0, r8, c1, c1, 0   @ set secure configuration (SCR)
> +       bne     supervise
> +
> +       orr     r8, r8, #0x100          @ hypercall enable (HCE)
> +       mcr     p15, 0, r8, c1, c1, 0   @ set secure configuration (SCR)
> +
> +       mov     lr, r5
> +       msr     spsr, #HYP_MODE
> +       __ERET
> +
> +supervise:
> +       /*
> +        * Switch to supervisor mode and return using a non-banked register,
> +        * in case we're not in the mode we started out in.
> +        */
> +       cps     #SVC_MODE
> +       ret     r5
> +ENDPROC(__mon_stub_install)
> +
> +ENTRY(__mon_stub_do_undef)
> +       /*
> +        * Return to the address at r5 with the mode in r4. If there is an
> +        * illegal or unimplemented mode in r4 the cpsr write will cause an
> +        * undefined exception, recursing. To avoid that, put the current
> +        * mode in r4 before performing the write.
> +        */
> +       mrs     r6, cpsr
> +       bic     r7, r6, #MODE_MASK
> +       orr     r7, r7, r4
> +       and     r4, r6, #MODE_MASK
> +       msr     cpsr, r7
> +       ret     r5
> +ENDPROC(__mon_stub_do_undef)
> +
> +.align 5
> +__mon_stub_vectors:
> +__mon_stub_reset:      W(b)    .
> +__mon_stub_und:                W(b)    __mon_stub_do_undef
> +__mon_stub_call:       W(b)    .
> +__mon_stub_pabort:     W(b)    .
> +__mon_stub_dabort:     W(b)    .
> +__mon_stub_trap:       W(b)    .
> +__mon_stub_irq:                W(b)    .
> +__mon_stub_fiq:                W(b)    .
> +ENDPROC(__mon_stub_vectors)
> diff --git a/arch/arm/mm/Kconfig b/arch/arm/mm/Kconfig
> index 7c6b976..32fa451 100644
> --- a/arch/arm/mm/Kconfig
> +++ b/arch/arm/mm/Kconfig
> @@ -676,7 +676,7 @@ config ARM_THUMBEE
>           make use of it. Say N for code that can run on CPUs without ThumbEE.
>
>  config ARM_VIRT_EXT
> -       bool
> +       bool "Support for Virtualization Extensions"
>         depends on MMU
>         default y if CPU_V7
>         help
> @@ -684,9 +684,21 @@ config ARM_VIRT_EXT
>           Extensions to install hypervisors without run-time firmware
>           assistance.
>
> -         A compliant bootloader is required in order to make maximum
> -         use of this feature.  Refer to Documentation/arm/Booting for
> -         details.
> +         A compliant bootloader or enabling ARM_SEC_EXT is required in
> +         order to make maximum use of this feature. Refer to
> +         Documentation/arm/Booting for details.
> +
> +config ARM_SEC_EXT
> +       bool "Support for Security Extensions"
> +       depends on MMU
> +       default n
> +       help
> +         Say Y to have the kernel check for the presence of the ARM Security
> +         Extensions and where possible, use them to switch to preferred
> +         security and mode settings. This decreases the kernel's dependency
> +         on bootloaders.
> +
> +         If unsure, say N.
>
>  config SWP_EMULATE
>         bool "Emulate SWP/SWPB instructions" if !SMP
> --
> Qualcomm Innovation Center, Inc.
> The Qualcomm Innovation Center, Inc. is a member of the Code Aurora Forum,
> a Linux Foundation Collaborative Project
>


From Dave.Martin at arm.com  Wed Aug 26 03:39:42 2015
From: Dave.Martin at arm.com (Dave Martin)
Date: Wed, 26 Aug 2015 11:39:42 +0100
Subject: [PATCH] arm: Handle starting up in secure mode
In-Reply-To: <1440424572-27116-1-git-send-email-cov@codeaurora.org>
References: <1440424572-27116-1-git-send-email-cov@codeaurora.org>
Message-ID: <20150826103940.GD6281@e103592.cambridge.arm.com>

On Mon, Aug 24, 2015 at 09:55:26AM -0400, Christopher Covington wrote:
> ARM Linux appears to have never been made aware of the ARMv7 security
> extensions. When CONFIG_ARM_SEC_EXT=y, have it probe for its security
> state by checking whether CNTFRQ is writeable and potentially make
> mode changes based on the information. The most features are available
> from hypervisor (HYP) mode, so switch to it possible. Failing that,
> prefer non-secure supervisor (SVC) mode to secure supervisor mode.

Up to now we've steered clear of this, since it's a bit of a fig leaf
for broken firmware unless Linux actually has some valid use for the
Security Extensions itself.

Shouldn't the bootloader or firmware be doing this stuff, and if not,
why not?


Some other things that would need to be considered in any case:

 * SoC-specific setup of the Non-secure view of the system:  This has
   to happen very early, so making it DT aware is going to be hard --
   failing that, we are effectively risking bringing back board files.
   The split in responsibility between firmware/bootloader and kernel
   needs to be clearly defined and (as far as possible) platform-
   independent, otherwise we'll have total chaos.

 * Out of reset, generally the CPU state is only fully defined for the
   highest exception level.  You probably need to be doing more setup
   than you're currently doing.

 * SMP, secondary boot and suspend/resume -- again involving board-
   specific code.

 * You need to safely "park" the Secure World before running anything
   in Non-Secure.  As a minimum, you would need to quiesce any
   Secure interrupt sources, disable all interrupt traps to Monitor
   mode, and make sure that the Monitor vectors point somewhere
   real, so that executing SMC doesn't send the CPU off into the
   long grass...

Cheers
---Dave

> 
> Signed-off-by: Christopher Covington <cov at codeaurora.org>
> ---
>  arch/arm/include/asm/sec.h         |  27 +++++++
>  arch/arm/include/uapi/asm/ptrace.h |   1 +
>  arch/arm/kernel/Makefile           |   1 +
>  arch/arm/kernel/head.S             |   3 +
>  arch/arm/kernel/mon-stub.S         | 158 +++++++++++++++++++++++++++++++++++++
>  arch/arm/mm/Kconfig                |  20 ++++-
>  6 files changed, 206 insertions(+), 4 deletions(-)
>  create mode 100644 arch/arm/include/asm/sec.h
>  create mode 100644 arch/arm/kernel/mon-stub.S
> 
> diff --git a/arch/arm/include/asm/sec.h b/arch/arm/include/asm/sec.h
> new file mode 100644
> index 0000000..4a9a573
> --- /dev/null
> +++ b/arch/arm/include/asm/sec.h
> @@ -0,0 +1,27 @@
> +/*
> + * Copyright (c) 2014, The Linux Foundation. All rights reserved.
> + *
> + * This program is free software; you can redistribute it and/or modify
> + * it under the terms of the GNU General Public License version 2 and
> + * only 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.
> + */
> +
> +#ifndef SEC_H
> +#define SEC_H
> +
> +#ifndef __ASSEMBLY__
> +
> +#ifdef CONFIG_ARM_SEC_EXT
> +extern int __boot_cpu_secure;
> +#else
> +#define __boot_cpu_secure 0
> +#endif
> +
> +#endif /* ! __ASSEMBLY__ */
> +
> +#endif /* SEC_H */
> diff --git a/arch/arm/include/uapi/asm/ptrace.h b/arch/arm/include/uapi/asm/ptrace.h
> index 5af0ed1..70ff6bf 100644
> --- a/arch/arm/include/uapi/asm/ptrace.h
> +++ b/arch/arm/include/uapi/asm/ptrace.h
> @@ -53,6 +53,7 @@
>  #endif
>  #define FIQ_MODE	0x00000011
>  #define IRQ_MODE	0x00000012
> +#define MON_MODE	0x00000016
>  #define ABT_MODE	0x00000017
>  #define HYP_MODE	0x0000001a
>  #define UND_MODE	0x0000001b
> diff --git a/arch/arm/kernel/Makefile b/arch/arm/kernel/Makefile
> index e69f7a1..a60a0f7 100644
> --- a/arch/arm/kernel/Makefile
> +++ b/arch/arm/kernel/Makefile
> @@ -87,6 +87,7 @@ head-y			:= head$(MMUEXT).o
>  obj-$(CONFIG_DEBUG_LL)	+= debug.o
>  obj-$(CONFIG_EARLY_PRINTK)	+= early_printk.o
>  
> +obj-$(CONFIG_ARM_SEC_EXT)	+= mon-stub.o
>  obj-$(CONFIG_ARM_VIRT_EXT)	+= hyp-stub.o
>  ifeq ($(CONFIG_ARM_PSCI),y)
>  obj-y				+= psci.o psci-call.o
> diff --git a/arch/arm/kernel/head.S b/arch/arm/kernel/head.S
> index 29e2991..d137ba4 100644
> --- a/arch/arm/kernel/head.S
> +++ b/arch/arm/kernel/head.S
> @@ -85,6 +85,9 @@ ENTRY(stext)
>   THUMB(	.thumb			)	@ switch to Thumb now.
>   THUMB(1:			)
>  
> +#ifdef CONFIG_ARM_SEC_EXT
> +	bl	__mon_stub_install
> +#endif
>  #ifdef CONFIG_ARM_VIRT_EXT
>  	bl	__hyp_stub_install
>  #endif
> diff --git a/arch/arm/kernel/mon-stub.S b/arch/arm/kernel/mon-stub.S
> new file mode 100644
> index 0000000..ab1a361
> --- /dev/null
> +++ b/arch/arm/kernel/mon-stub.S
> @@ -0,0 +1,158 @@
> +/*
> + * Copyright (c) 2014, The Linux Foundation. All rights reserved.
> + *
> + * This program is free software; you can redistribute it and/or modify
> + * it under the terms of the GNU General Public License version 2 and
> + * only 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/linkage.h>
> +#include <asm/assembler.h>
> +#include <asm/sec.h>
> +
> +.data
> +ENTRY(__boot_cpu_secure)
> +	.long	0
> +.text
> +
> +/*
> + * ARM Linux has the most features available in hypervisor mode and
> + * running in non-secure mode is recommended. Thus, try to get into
> + * hypervisor mode if we're not already there, or failing that, try
> + * to get into non-secure supervisor mode.
> + */
> +ENTRY(__mon_stub_install)
> +	/*
> +	 * Store the mode field of the CPSR in r4 and return early if we're
> +	 * already in hypervisor mode.
> +	 */
> +	mrs	r4, cpsr
> +	and	r4, r4, #MODE_MASK
> +	cmp	r4, #HYP_MODE
> +	reteq	lr
> +
> +	/*
> +	 * Save the link register in a non-banked register, r5, so that we
> +	 * still have access to it after mode switches.
> +	 */
> +	mov	r5, lr
> +
> +	/*
> +	 * Read ID_PFR1 and store the value in r6. This register indicates
> +	 * the presence of the security and virtualization extensions. The
> +	 * former is interesting because we must traverse secure monitor mode
> +	 * to get to hypervisor mode and it allows easy manipulation of
> +	 * exception vectors via the Vector Base Address Register (VBAR).
> +	 *
> +	 * ID_PFR1 also indicates whether the generic timer is present, which
> +	 * has a handy register for our purposes, CNTFRQ. Accesses won't trap
> +	 * even with higher exception levels in AArch64 and writes will only
> +	 * succeed from the highest exception level on a system (the undefined
> +	 * exception from a failed write is used as a branch).
> +	 */
> +
> +	mrc   p15, 0, r6, c0, c1, 1	@ ID_PFR1
> +
> +	/*
> +	 * If we're in monitor mode then we know the security setting and can
> +	 * begin the transition to hypervisor or non-secure supervisor mode
> +	 * immediately.
> +	 */
> +
> +	cmp	r4, #MON_MODE
> +	beq	monitor
> +
> +	/*
> +	 * Check that the security extensions and generic timer are present.
> +	 */
> +	and	r7, r6, #0xf0
> +	cmp	r7, #0x10
> +	cmpne	r7, #0x20
> +	retne	lr
> +	and	r8, r6, #0xf0000
> +	cmp	r8, #0x10000
> +	retne	lr
> +
> +	/*
> +	 * Set things up so that if a CNTFRQ access causes an undefined
> +	 * instruction exception, we return to the address indicated in r5
> +	 * in the mode indicated in r4.
> +	 */
> +	adr	r7, __mon_stub_vectors
> +	mcr	p15, 0, r7, c12, c0, 0	@ set vector base address (VBAR)
> +
> +	mrc	p15, 0, r7, c14, c0, 0	@ CNTFRQ
> +	mcr	p15, 0, r7, c14, c0, 0	@ CNTFRQ
> +
> +	/*
> +	 * If we got this far, switch to monitor mode and prepare for further
> +	 * switching.
> +	 */
> +	cps	#MON_MODE
> +
> +monitor:
> +	/*
> +	 * TODO: Handle SIF and separate secure physical memory in general
> +	 */
> +	mrc	p15, 0, r8, c1, c1, 0	@ get secure configuration (SCR)
> +	orr	r8, r8, #1		@ non-secure (NS)
> +
> +	mov	r8, #1
> +	ldr	r7, =__boot_cpu_secure
> +	str	r8, [r7]
> +
> +	/*
> +	 * See whether the switch will be to hypervisor or supervisor.
> +	 */
> +	and	r7, r6, #0xf000
> +	cmp	r7, #0x1000
> +	mcrne	p15, 0, r8, c1, c1, 0	@ set secure configuration (SCR)
> +	bne	supervise
> +
> +	orr	r8, r8, #0x100		@ hypercall enable (HCE)
> +	mcr	p15, 0, r8, c1, c1, 0	@ set secure configuration (SCR)
> +
> +	mov	lr, r5
> +	msr	spsr, #HYP_MODE
> +	__ERET
> +
> +supervise:
> +	/*
> +	 * Switch to supervisor mode and return using a non-banked register,
> +	 * in case we're not in the mode we started out in.
> +	 */
> +	cps	#SVC_MODE
> +	ret	r5
> +ENDPROC(__mon_stub_install)
> +
> +ENTRY(__mon_stub_do_undef)
> +	/*
> +	 * Return to the address at r5 with the mode in r4. If there is an
> +	 * illegal or unimplemented mode in r4 the cpsr write will cause an
> +	 * undefined exception, recursing. To avoid that, put the current
> +	 * mode in r4 before performing the write.
> +	 */
> +	mrs	r6, cpsr
> +	bic	r7, r6, #MODE_MASK
> +	orr	r7, r7, r4
> +	and	r4, r6, #MODE_MASK
> +	msr	cpsr, r7
> +	ret	r5
> +ENDPROC(__mon_stub_do_undef)
> +
> +.align 5
> +__mon_stub_vectors:
> +__mon_stub_reset:	W(b)	.
> +__mon_stub_und:		W(b)	__mon_stub_do_undef
> +__mon_stub_call:	W(b)	.
> +__mon_stub_pabort:	W(b)	.
> +__mon_stub_dabort:	W(b)	.
> +__mon_stub_trap:	W(b)	.
> +__mon_stub_irq:		W(b)	.
> +__mon_stub_fiq:		W(b)	.
> +ENDPROC(__mon_stub_vectors)
> diff --git a/arch/arm/mm/Kconfig b/arch/arm/mm/Kconfig
> index 7c6b976..32fa451 100644
> --- a/arch/arm/mm/Kconfig
> +++ b/arch/arm/mm/Kconfig
> @@ -676,7 +676,7 @@ config ARM_THUMBEE
>  	  make use of it. Say N for code that can run on CPUs without ThumbEE.
>  
>  config ARM_VIRT_EXT
> -	bool
> +	bool "Support for Virtualization Extensions"
>  	depends on MMU
>  	default y if CPU_V7
>  	help
> @@ -684,9 +684,21 @@ config ARM_VIRT_EXT
>  	  Extensions to install hypervisors without run-time firmware
>  	  assistance.
>  
> -	  A compliant bootloader is required in order to make maximum
> -	  use of this feature.  Refer to Documentation/arm/Booting for
> -	  details.
> +	  A compliant bootloader or enabling ARM_SEC_EXT is required in
> +	  order to make maximum use of this feature. Refer to
> +	  Documentation/arm/Booting for details.
> +
> +config ARM_SEC_EXT
> +	bool "Support for Security Extensions"
> +	depends on MMU
> +	default n
> +	help
> +	  Say Y to have the kernel check for the presence of the ARM Security
> +	  Extensions and where possible, use them to switch to preferred
> +	  security and mode settings. This decreases the kernel's dependency
> +	  on bootloaders.
> +
> +	  If unsure, say N.
>  
>  config SWP_EMULATE
>  	bool "Emulate SWP/SWPB instructions" if !SMP
> -- 
> Qualcomm Innovation Center, Inc.
> The Qualcomm Innovation Center, Inc. is a member of the Code Aurora Forum,
> a Linux Foundation Collaborative Project
> 
> 
> _______________________________________________
> linux-arm-kernel mailing list
> linux-arm-kernel at lists.infradead.org
> http://lists.infradead.org/mailman/listinfo/linux-arm-kernel



From linux at arm.linux.org.uk  Wed Aug 26 03:46:34 2015
From: linux at arm.linux.org.uk (Russell King - ARM Linux)
Date: Wed, 26 Aug 2015 11:46:34 +0100
Subject: [PATCH] arm: Handle starting up in secure mode
In-Reply-To: <1440424572-27116-1-git-send-email-cov@codeaurora.org>
References: <1440424572-27116-1-git-send-email-cov@codeaurora.org>
Message-ID: <20150826104634.GB21084@n2100.arm.linux.org.uk>

On Mon, Aug 24, 2015 at 09:55:26AM -0400, Christopher Covington wrote:
> +/*
> + * ARM Linux has the most features available in hypervisor mode and
> + * running in non-secure mode is recommended. Thus, try to get into
> + * hypervisor mode if we're not already there, or failing that, try
> + * to get into non-secure supervisor mode.
> + */
> +ENTRY(__mon_stub_install)
> +	/*
> +	 * Store the mode field of the CPSR in r4 and return early if we're
> +	 * already in hypervisor mode.
> +	 */
> +	mrs	r4, cpsr
> +	and	r4, r4, #MODE_MASK
> +	cmp	r4, #HYP_MODE
> +	reteq	lr
> +
> +	/*
> +	 * Save the link register in a non-banked register, r5, so that we
> +	 * still have access to it after mode switches.
> +	 */
> +	mov	r5, lr
> +
> +	/*
> +	 * Read ID_PFR1 and store the value in r6. This register indicates
> +	 * the presence of the security and virtualization extensions. The
> +	 * former is interesting because we must traverse secure monitor mode
> +	 * to get to hypervisor mode and it allows easy manipulation of
> +	 * exception vectors via the Vector Base Address Register (VBAR).
> +	 *
> +	 * ID_PFR1 also indicates whether the generic timer is present, which
> +	 * has a handy register for our purposes, CNTFRQ. Accesses won't trap
> +	 * even with higher exception levels in AArch64 and writes will only
> +	 * succeed from the highest exception level on a system (the undefined
> +	 * exception from a failed write is used as a branch).
> +	 */
> +
> +	mrc   p15, 0, r6, c0, c1, 1	@ ID_PFR1

As this code can be built into any kernel for a CPU containing a MMU,
including all the way back to ARMv4, you had better make sure that
this code will run there without causing faults.

You should probably be checking the main ID register and ensuring that
the CPU supports the new ID scheme before trying to read CP15 registers
that may not be present in older cores.

> diff --git a/arch/arm/mm/Kconfig b/arch/arm/mm/Kconfig
> index 7c6b976..32fa451 100644
> --- a/arch/arm/mm/Kconfig
> +++ b/arch/arm/mm/Kconfig
> @@ -676,7 +676,7 @@ config ARM_THUMBEE
>  	  make use of it. Say N for code that can run on CPUs without ThumbEE.
>  
>  config ARM_VIRT_EXT
> -	bool
> +	bool "Support for Virtualization Extensions"

This change is not explained in the commit message.

>  	depends on MMU
>  	default y if CPU_V7
>  	help
> @@ -684,9 +684,21 @@ config ARM_VIRT_EXT
>  	  Extensions to install hypervisors without run-time firmware
>  	  assistance.
>  
> -	  A compliant bootloader is required in order to make maximum
> -	  use of this feature.  Refer to Documentation/arm/Booting for
> -	  details.
> +	  A compliant bootloader or enabling ARM_SEC_EXT is required in
> +	  order to make maximum use of this feature. Refer to
> +	  Documentation/arm/Booting for details.
> +
> +config ARM_SEC_EXT
> +	bool "Support for Security Extensions"
> +	depends on MMU
> +	default n

Please get rid of this redundant "default n".

-- 
FTTC broadband for 0.8mile line: currently at 10.5Mbps down 400kbps up
according to speedtest.net.


From broonie at kernel.org  Wed Aug 26 03:48:19 2015
From: broonie at kernel.org (Mark Brown)
Date: Wed, 26 Aug 2015 11:48:19 +0100
Subject: [PATCH v2] ASoC: rockchip: fix a misjudgement by return
In-Reply-To: <1440559244-17634-1-git-send-email-zhengxing@rock-chips.com>
References: <1440559244-17634-1-git-send-email-zhengxing@rock-chips.com>
Message-ID: <20150826104819.GO12878@sirena.org.uk>

On Wed, Aug 26, 2015 at 11:20:44AM +0800, Xing Zheng wrote:
> Being careless, judge the return value of snd_soc_card_jack_new
> is opposite, so it should be fixed.

This patch has been applied already.  If any changes are required to
already applied patches please send incremental patches against current
code.
-------------- next part --------------
A non-text attachment was scrubbed...
Name: signature.asc
Type: application/pgp-signature
Size: 473 bytes
Desc: Digital signature
URL: <http://lists.infradead.org/pipermail/linux-arm-kernel/attachments/20150826/2f577cbf/attachment.sig>

From linux at arm.linux.org.uk  Wed Aug 26 03:48:39 2015
From: linux at arm.linux.org.uk (Russell King - ARM Linux)
Date: Wed, 26 Aug 2015 11:48:39 +0100
Subject: [PATCH] arm: Handle starting up in secure mode
In-Reply-To: <20150826103940.GD6281@e103592.cambridge.arm.com>
References: <1440424572-27116-1-git-send-email-cov@codeaurora.org>
 <20150826103940.GD6281@e103592.cambridge.arm.com>
Message-ID: <20150826104839.GC21084@n2100.arm.linux.org.uk>

On Wed, Aug 26, 2015 at 11:39:42AM +0100, Dave Martin wrote:
> On Mon, Aug 24, 2015 at 09:55:26AM -0400, Christopher Covington wrote:
> > ARM Linux appears to have never been made aware of the ARMv7 security
> > extensions. When CONFIG_ARM_SEC_EXT=y, have it probe for its security
> > state by checking whether CNTFRQ is writeable and potentially make
> > mode changes based on the information. The most features are available
> > from hypervisor (HYP) mode, so switch to it possible. Failing that,
> > prefer non-secure supervisor (SVC) mode to secure supervisor mode.
> 
> Up to now we've steered clear of this, since it's a bit of a fig leaf
> for broken firmware unless Linux actually has some valid use for the
> Security Extensions itself.
> 
> Shouldn't the bootloader or firmware be doing this stuff, and if not,
> why not?
> 
> 
> Some other things that would need to be considered in any case:
> 
>  * SoC-specific setup of the Non-secure view of the system:  This has
>    to happen very early, so making it DT aware is going to be hard --
>    failing that, we are effectively risking bringing back board files.
>    The split in responsibility between firmware/bootloader and kernel
>    needs to be clearly defined and (as far as possible) platform-
>    independent, otherwise we'll have total chaos.
> 
>  * Out of reset, generally the CPU state is only fully defined for the
>    highest exception level.  You probably need to be doing more setup
>    than you're currently doing.
> 
>  * SMP, secondary boot and suspend/resume -- again involving board-
>    specific code.
> 
>  * You need to safely "park" the Secure World before running anything
>    in Non-Secure.  As a minimum, you would need to quiesce any
>    Secure interrupt sources, disable all interrupt traps to Monitor
>    mode, and make sure that the Monitor vectors point somewhere
>    real, so that executing SMC doesn't send the CPU off into the
>    long grass...

Another question is: has this been tested with kexec?

-- 
FTTC broadband for 0.8mile line: currently at 10.5Mbps down 400kbps up
according to speedtest.net.


From alexander.stein at systec-electronic.com  Wed Aug 26 04:10:03 2015
From: alexander.stein at systec-electronic.com (Alexander Stein)
Date: Wed, 26 Aug 2015 13:10:03 +0200
Subject: [PATCH 1/1] ARM: imx35: Do not call mxc_timer_init twice when
 booting with DT
In-Reply-To: <1439277502-16917-1-git-send-email-alexander.stein@systec-electronic.com>
References: <1439277502-16917-1-git-send-email-alexander.stein@systec-electronic.com>
Message-ID: <4874555.Wi6XRVID6f@ws-stein>

On Tuesday 11 August 2015 09:18:22, Alexander Stein wrote:
> mxc_timer_init must not be called from within mx35_clocks_init_dt. It will
> eventually be called by imx31_timer_init_dt
> (drivers/clocksources/timer-imx-gpt.c).
> This arranges the initialization code similar to clk-imx27.c

Any feedback on this?

Alexander
-- 
Dipl.-Inf. Alexander Stein
SYS TEC electronic GmbH
alexander.stein at systec-electronic.com

Legal and Commercial Address:
Am Windrad 2
08468 Heinsdorfergrund
Germany

Office: +49 (0) 3765 38600-0
Fax:    +49 (0) 3765 38600-4100
 
Managing Directors:
	Director Technology/CEO: Dipl.-Phys. Siegmar Schmidt;
	Director Commercial Affairs/COO: Dipl. Ing. (FH) Armin von Collrepp
Commercial Registry:
	Amtsgericht Chemnitz, HRB 28082; USt.-Id Nr. DE150534010



From will.deacon at arm.com  Wed Aug 26 04:12:05 2015
From: will.deacon at arm.com (Will Deacon)
Date: Wed, 26 Aug 2015 12:12:05 +0100
Subject: [PATCH] arm64: fix bug for reloading FPSIMD state after execve
 on cpu 0.
In-Reply-To: <1440556841-17219-1-git-send-email-chunyan.zhang@spreadtrum.com>
References: <1440556841-17219-1-git-send-email-chunyan.zhang@spreadtrum.com>
Message-ID: <20150826111205.GD30466@arm.com>

Hello,

[adding Ard]

On Wed, Aug 26, 2015 at 03:40:41AM +0100, Chunyan Zhang wrote:
> From: Janet Liu <janet.liu at spreadtrum.com>
> 
> If process A is running on CPU 0 and do execve syscall and after sched_exec,
> dest_cpu is 0, fpsimd_state.cpu is 0. If at the time Process A get scheduled
> out and after some kernel threads running on CPU 0, process A is back in CPU 0,
> A's fpsimd_state.cpu is current cpu id "0", and per_cpu(fpsimd_last_state)
> points A's fpsimd_state, TIF_FOREIGN_FPSTATE will be clear, kernel will not
> reload the context during it return to userspace. so set the cpu's
> fpsimd_last_state to NULL to avoid this.

AFAICT, this is only a problem if one of the kernel threads uses the fpsimd
registers, right? However, kernel_neon_begin_partial clobbers
fpsimd_last_state, so I'm struggling to see the problem.

Are you seeing an issue in practice?

Will

> Signed-off-by: Janet Liu <janet.liu at spreadtrum.com>
> Signed-off-by: Chunyan Zhang <chunyan.zhang at spreadtrum.com>
> ---
>  arch/arm64/kernel/fpsimd.c |    1 +
>  1 file changed, 1 insertion(+)
> 
> diff --git a/arch/arm64/kernel/fpsimd.c b/arch/arm64/kernel/fpsimd.c
> index 44d6f75..ec58d94 100644
> --- a/arch/arm64/kernel/fpsimd.c
> +++ b/arch/arm64/kernel/fpsimd.c
> @@ -159,6 +159,7 @@ void fpsimd_flush_thread(void)
>  {
>  	memset(&current->thread.fpsimd_state, 0, sizeof(struct fpsimd_state));
>  	set_thread_flag(TIF_FOREIGN_FPSTATE);
> +	this_cpu_write(fpsimd_last_state, NULL);
>  }
>  
>  /*
> -- 
> 1.7.9.5
> 


From antonios.motakis at huawei.com  Wed Aug 26 04:16:52 2015
From: antonios.motakis at huawei.com (Antonios Motakis)
Date: Wed, 26 Aug 2015 13:16:52 +0200
Subject: [PATCH 00/13] arm64: Virtualization Host Extension support
In-Reply-To: <55DD8DEF.9080301@arm.com>
References: <1436372356-30410-1-git-send-email-marc.zyngier@arm.com>
 <55DD82FB.60903@huawei.com> <55DD851B.4040106@siemens.com>
 <55DD8DEF.9080301@arm.com>
Message-ID: <55DDA024.8040303@huawei.com>



On 26-Aug-15 11:59, Marc Zyngier wrote:
> On 26/08/15 10:21, Jan Kiszka wrote:
>> On 2015-08-26 11:12, Antonios Motakis wrote:
>>> Hello Marc,
>>>
>>> On 08-Jul-15 18:19, Marc Zyngier wrote:
>>>> ARMv8.1 comes with the "Virtualization Host Extension" (VHE for 
>>>> short), which enables simpler support of Type-2 hypervisors.
>>>>
>>>> This extension allows the kernel to directly run at EL2, and 
>>>> significantly reduces the number of system registers shared
>>>> between host and guest, reducing the overhead of virtualization.
>>>>
>>>> In order to have the same kernel binary running on all versions
>>>> of the architecture, this series makes heavy use of runtime code
>>>> patching.
>>>>
>>>> The first ten patches massage the KVM code to deal with VHE and
>>>> enable Linux to run at EL2.
>>>
>>> I am currently working on getting the Jailhouse hypervisor to work
>>> on AArch64.
>>>
>>> I've been looking at your patches, trying to figure out the
>>> implications for Jailhouse. It seems there are a few :)
>>>
>>> Jailhouse likes to be loaded by Linux into memory, and then to
>>> inject itself at a higher level than Linux (demoting Linux into
>>> being the "root cell"). This works on x86 and ARM (AArch32 and
>>> eventually AArch64 without VHE). What this means in ARM, is that
>>> Jailhouse hooks into the HVC stub exposed by Linux, and happily
>>> installs itself in EL2.
>>>
>>> With Linux running in EL2 though, that won't be as straightforward.
>>> It looks like we can't just demote Linux to EL1 without breaking
>>> something. Obviously it's OK for us that KVM won't work, but it
>>> looks like at least the timer code will break horribly if we try to
>>> do something like that.
>>>
>>> Any comments on this? One work around would be to just remap the
>>> incoming interrupt from the timer, so Linux never really realizes
>>> it's not running in EL2 anymore. Then we would also have to deal
>>> with the intricacies of removing and re-adding vCPUs to the Linux
>>> root cell, so we would have to maintain the illusion of running in
>>> EL2 for each one of them.
> 
> Unfortunately, there is more to downgrading to EL1 than just interrupts.
> You need to migrate the whole VM context from EL2 to EL1 in an atomic
> fashion, clear the HCR_EL2.E2H and HCR_EL2.TGE bits while running at EL2
> (which is a bit like pulling the rug from under your own feet so you
> need to transition via a low mapping or an idmap), reinstall the EL2
> stub and do an exception return into EL1.

When enabling Jailhouse, we already do most of that. We already use identity mapping, since we need to switch on the MMU for EL2, switch the exception level, etc. Jailhouse entry looks a lot like initializing a new kernel; we just save the state of what was running before it and restore it as the "root cell".

So I think we could handle the cpu context switch, with changes only in the Jailhouse entry code. But then of course, Linux would be expecting to be in EL2, while it is running in EL1, so we would have to emulate the differences in behavior. But...

> 
> And that's only for the CPU. Downgrading to EL1 has other fun
> consequences at the system level (SMMUs listening to TLB traffic would
> need to be reconfigured on the flight - it's a joke, don't even think of
> it).

...but then there's that.

Hm... even if the kernel is running in EL2, it will still be configuring stage 1 on the SMMU, no? I wonder if this could still be handled somehow... The root cell would be restored with identity mapping, too... Just thinking out loud :)

> 
>>
>> Without knowing any of the details, I would say there are two
>> strategies regarding this:
>>
>> - Disable KVM support in the Linux kernel - then we shouldn't boot
>> into EL2 in the first place, should we?
> 
> Disabling KVM support won't drop the kernel to EL1. At least that's not
> what the current code does (we stay at EL2 if we detect VHE), and that's
> way too early to be able to parse a command line option.
> 
>> - Emulate what Linux is missing after take-over by Jailhouse (we do 
>> this on x86 with VT-d interrupt remapping which cannot be disabled 
>> anymore for Linux once it started with it, and we cannot boot
>> without it when we want to use the x2APIC).
> 
> I can't really see what you want to emulate (I'm afraid I'm lacking the
> x86-specific background).
> 
> As far as I can see, the only practical solution to this is to have a
> VHE config option, and Jailhouse that can be set to conflict it (depends
> on !VHE).

Having a toggle to turn VHE off at build time would definitely be the easy way out. Then we can just tell the user that we only support kernels built without it (the Jailhouse driver is out of tree atm).

I don't have access to a VHE model though. Are you considering to add a config option for VHE in the next version of your patches?

In any case thanks for your thoughts,

-- 
Antonios Motakis
Virtualization Engineer
Huawei Technologies Duesseldorf GmbH
European Research Center
Riesstrasse 25, 80992 M?nchen



From sudeep.holla at arm.com  Wed Aug 26 04:25:32 2015
From: sudeep.holla at arm.com (Sudeep Holla)
Date: Wed, 26 Aug 2015 12:25:32 +0100
Subject: [PATCH v3 1/1][Resend] misc: sram: add dev_pm_ops to support
 module power gate
In-Reply-To: <1440540187-6208-1-git-send-email-shenwei.wang@freescale.com>
References: <1440540187-6208-1-git-send-email-shenwei.wang@freescale.com>
Message-ID: <55DDA22C.4090408@arm.com>



On 25/08/15 23:03, Shenwei Wang wrote:
> When system goes into low power states like SUSPEND_MEM and
> HIBERNATION, the hardware IP block may be powered off to reduce
> the power consumption. This power down will lost all the
> data inside the ram. This patch added the dev_pm_ops and
> implemented two callbacks: suspend_noirq and resume_noirq, which
> will save the data in the on-chip-ram right before power down
> and restore it after system resumes.
>
> A new property string named "can-power-gate" is added to
> the devicetree bindings too.
>
> Based-on-a-patch-by: Anson Huang <b20788 at freescale.com>
> Signed-off-by: Shenwei Wang <shenwei.wang at freescale.com>
>
> ---
> Change log:
>
> PATCH v3
> 	Removed the unnecessary clk_enable/clk_disable.
>
> PATCH v2
> 	Use vmalloc to allocate the SRAM backup memory.
> 	Code clean up.
>
>   Documentation/devicetree/bindings/misc/sram.txt |  2 ++
>   drivers/misc/sram.c                             | 42 +++++++++++++++++++++++++
>   2 files changed, 44 insertions(+)
>
> diff --git a/Documentation/devicetree/bindings/misc/sram.txt b/Documentation/devicetree/bindings/misc/sram.txt
> index 36cbe5a..1170086 100644
> --- a/Documentation/devicetree/bindings/misc/sram.txt
> +++ b/Documentation/devicetree/bindings/misc/sram.txt
> @@ -33,6 +33,8 @@ Optional properties in the area nodes:
>
>   - compatible : standard definition, should contain a vendor specific string
>                  in the form <vendor>,[<device>-]<usage>
> +- can-power-gate: a property to tell the driver that the sram can support
> +		power gate
>
>   Example:
>
> diff --git a/drivers/misc/sram.c b/drivers/misc/sram.c
> index 15c33cc..db9f1fa 100644
> --- a/drivers/misc/sram.c
> +++ b/drivers/misc/sram.c
> @@ -30,7 +30,9 @@
>
>   struct sram_dev {
>   	struct device *dev;
> +	void *power_off_save;
>   	void __iomem *virt_base;
> +	u32 size;
>
>   	struct gen_pool *pool;
>   	struct clk *clk;
> @@ -156,6 +158,33 @@ static int sram_reserve_regions(struct sram_dev *sram, struct resource *res)
>   	return ret;
>   }
>
> +static int sram_suspend_noirq(struct device *dev)
> +{
> +	struct platform_device *pdev = to_platform_device(dev);
> +	struct sram_dev *sram = platform_get_drvdata(pdev);
> +
> +	if (!sram->power_off_save)
> +		return 0;
> +
> +	/* Save necessary regs */
> +	memcpy(sram->power_off_save, sram->virt_base, sram->size);
> +
> +	return 0;
> +}
> +
> +static int sram_resume_noirq(struct device *dev)
> +{
> +	struct platform_device *pdev = to_platform_device(dev);
> +	struct sram_dev *sram = platform_get_drvdata(pdev);
> +
> +	if (!sram->power_off_save)
> +		return 0;
> +
> +	memcpy(sram->virt_base, sram->power_off_save, sram->size);

As I objected in the original thread[1], I am just iterating myself here
again. IMO this is unnecessary and can be avoided. It's also not
scalable for large SRAM. I *still can't understand* what's the use-case
where you need to save/restore the entire SRAM content.

I see it's mostly used for audio/video and some crypto use-case(in the
mainline). In most of those cases, when you enter S2R, all the devices
*needs to be in quiescent state* which implies they no longer use SRAM.
So can you please care to provide your reasons for this save/restore ?

On some platforms, it's used for PM in which case it needs to be always on.

Regards,
Sudeep

[1] http://www.spinics.net/lists/arm-kernel/msg441449.html


From ard.biesheuvel at linaro.org  Wed Aug 26 04:32:03 2015
From: ard.biesheuvel at linaro.org (Ard Biesheuvel)
Date: Wed, 26 Aug 2015 13:32:03 +0200
Subject: [PATCH] arm64: fix bug for reloading FPSIMD state after execve on
 cpu 0.
In-Reply-To: <20150826111205.GD30466@arm.com>
References: <1440556841-17219-1-git-send-email-chunyan.zhang@spreadtrum.com>
 <20150826111205.GD30466@arm.com>
Message-ID: <CAKv+Gu_VtFGsKPmFfLHm=kNM=vK=p1TR+fd52P68MiA6J0zUFQ@mail.gmail.com>

On 26 August 2015 at 13:12, Will Deacon <will.deacon at arm.com> wrote:
> Hello,
>
> [adding Ard]
>
> On Wed, Aug 26, 2015 at 03:40:41AM +0100, Chunyan Zhang wrote:
>> From: Janet Liu <janet.liu at spreadtrum.com>
>>
>> If process A is running on CPU 0 and do execve syscall and after sched_exec,
>> dest_cpu is 0, fpsimd_state.cpu is 0. If at the time Process A get scheduled
>> out and after some kernel threads running on CPU 0, process A is back in CPU 0,
>> A's fpsimd_state.cpu is current cpu id "0", and per_cpu(fpsimd_last_state)
>> points A's fpsimd_state, TIF_FOREIGN_FPSTATE will be clear, kernel will not
>> reload the context during it return to userspace. so set the cpu's
>> fpsimd_last_state to NULL to avoid this.
>
> AFAICT, this is only a problem if one of the kernel threads uses the fpsimd
> registers, right? However, kernel_neon_begin_partial clobbers
> fpsimd_last_state, so I'm struggling to see the problem.
>

I think the problem is real, but it would be better to set the
fpsimd_state::cpu field to an invalid value like we do in
fpsimd_flush_task_state()

diff --git a/arch/arm64/kernel/fpsimd.c b/arch/arm64/kernel/fpsimd.c
index 44d6f7545505..c56956a16d3f 100644
--- a/arch/arm64/kernel/fpsimd.c
+++ b/arch/arm64/kernel/fpsimd.c
@@ -158,6 +158,7 @@ void fpsimd_thread_switch(struct task_struct *next)
 void fpsimd_flush_thread(void)
 {
        memset(&current->thread.fpsimd_state, 0, sizeof(struct fpsimd_state));
+       fpsimd_flush_task_state(current);
        set_thread_flag(TIF_FOREIGN_FPSTATE);
 }

(note the memset erroneously initializes that field to CPU 0)

This more accurately reflects the state of the process after forking,
i.e., that its FPSIMD state has never been loaded into any CPU.

-- 
Ard.

> Are you seeing an issue in practice?
>
> Will
>
>> Signed-off-by: Janet Liu <janet.liu at spreadtrum.com>
>> Signed-off-by: Chunyan Zhang <chunyan.zhang at spreadtrum.com>
>> ---
>>  arch/arm64/kernel/fpsimd.c |    1 +
>>  1 file changed, 1 insertion(+)
>>
>> diff --git a/arch/arm64/kernel/fpsimd.c b/arch/arm64/kernel/fpsimd.c
>> index 44d6f75..ec58d94 100644
>> --- a/arch/arm64/kernel/fpsimd.c
>> +++ b/arch/arm64/kernel/fpsimd.c
>> @@ -159,6 +159,7 @@ void fpsimd_flush_thread(void)
>>  {
>>       memset(&current->thread.fpsimd_state, 0, sizeof(struct fpsimd_state));
>>       set_thread_flag(TIF_FOREIGN_FPSTATE);
>> +     this_cpu_write(fpsimd_last_state, NULL);
>>  }
>>
>>  /*
>> --
>> 1.7.9.5
>>


From linus.walleij at linaro.org  Wed Aug 26 04:38:19 2015
From: linus.walleij at linaro.org (Linus Walleij)
Date: Wed, 26 Aug 2015 13:38:19 +0200
Subject: [PATCH V2] Watchdog: Fix parent of watchdog_devices
In-Reply-To: <9fcc2a2cc8273f461baa13c6c9992f3ca56b508a.1439915117.git.panand@redhat.com>
References: <9fcc2a2cc8273f461baa13c6c9992f3ca56b508a.1439915117.git.panand@redhat.com>
Message-ID: <CACRpkdbT0Ew_LXys++EDykM-gp08dxKQ4HYp0CfAmk7EoCET9A@mail.gmail.com>

On Tue, Aug 18, 2015 at 6:34 PM, Pratyush Anand <panand at redhat.com> wrote:

> /sys/class/watchdog/watchdogn/device/modalias can help to identify the
> driver/module for a given watchdog node. However, many wdt devices does not set
> its parent and so, we do not see an entry for device in sysfs for such devices.
>
> This patch fixes parent of watchdog_device so that
> /sys/class/watchdog/watchdogn/device is populated.
>
> Exceptions: booke, diag288, mpc8xxx, octeon, softdog and w83627hf -- They do not
> have any parent. Not sure, how we can we identify driver for these devices.
>
> Signed-off-by: Pratyush Anand <panand at redhat.com>

Acked-by: Linus Walleij <linus.walleij at linaro.org>

Yours,
Linus Walleij


From will.deacon at arm.com  Wed Aug 26 04:39:22 2015
From: will.deacon at arm.com (Will Deacon)
Date: Wed, 26 Aug 2015 12:39:22 +0100
Subject: [PATCH] arm64: fix bug for reloading FPSIMD state after execve
 on cpu 0.
In-Reply-To: <CAKv+Gu_VtFGsKPmFfLHm=kNM=vK=p1TR+fd52P68MiA6J0zUFQ@mail.gmail.com>
References: <1440556841-17219-1-git-send-email-chunyan.zhang@spreadtrum.com>
 <20150826111205.GD30466@arm.com>
 <CAKv+Gu_VtFGsKPmFfLHm=kNM=vK=p1TR+fd52P68MiA6J0zUFQ@mail.gmail.com>
Message-ID: <20150826113922.GE30466@arm.com>

On Wed, Aug 26, 2015 at 12:32:03PM +0100, Ard Biesheuvel wrote:
> On 26 August 2015 at 13:12, Will Deacon <will.deacon at arm.com> wrote:
> > On Wed, Aug 26, 2015 at 03:40:41AM +0100, Chunyan Zhang wrote:
> >> From: Janet Liu <janet.liu at spreadtrum.com>
> >>
> >> If process A is running on CPU 0 and do execve syscall and after sched_exec,
> >> dest_cpu is 0, fpsimd_state.cpu is 0. If at the time Process A get scheduled
> >> out and after some kernel threads running on CPU 0, process A is back in CPU 0,
> >> A's fpsimd_state.cpu is current cpu id "0", and per_cpu(fpsimd_last_state)
> >> points A's fpsimd_state, TIF_FOREIGN_FPSTATE will be clear, kernel will not
> >> reload the context during it return to userspace. so set the cpu's
> >> fpsimd_last_state to NULL to avoid this.
> >
> > AFAICT, this is only a problem if one of the kernel threads uses the fpsimd
> > registers, right? However, kernel_neon_begin_partial clobbers
> > fpsimd_last_state, so I'm struggling to see the problem.
> >
> 
> I think the problem is real, but it would be better to set the
> fpsimd_state::cpu field to an invalid value like we do in
> fpsimd_flush_task_state()
> 
> diff --git a/arch/arm64/kernel/fpsimd.c b/arch/arm64/kernel/fpsimd.c
> index 44d6f7545505..c56956a16d3f 100644
> --- a/arch/arm64/kernel/fpsimd.c
> +++ b/arch/arm64/kernel/fpsimd.c
> @@ -158,6 +158,7 @@ void fpsimd_thread_switch(struct task_struct *next)
>  void fpsimd_flush_thread(void)
>  {
>         memset(&current->thread.fpsimd_state, 0, sizeof(struct fpsimd_state));
> +       fpsimd_flush_task_state(current);
>         set_thread_flag(TIF_FOREIGN_FPSTATE);
>  }
> 
> (note the memset erroneously initializes that field to CPU 0)

Aha, I see. So the problem is actually that we get a view on our fpsimd
state before the exec, rather than a view on some kernel state.

> This more accurately reflects the state of the process after forking,
> i.e., that its FPSIMD state has never been loaded into any CPU.

Yup, that's much clearer.

Will


From henryc.chen at mediatek.com  Wed Aug 26 04:43:16 2015
From: henryc.chen at mediatek.com (Henry Chen)
Date: Wed, 26 Aug 2015 19:43:16 +0800
Subject: [PATCH] regmap: Fix the null function of format_val on
 regmap_bulk_read.
Message-ID: <1440589396-696-1-git-send-email-henryc.chen@mediatek.com>

The regmap_format will not be initialize if device driver not declare the regmap_bus
when registering the regmap. To avoid the null function of format_val when
called regmap_bulk_read(). It need to give a format function when regmap init.

Signed-off-by: Henry Chen <henryc.chen at mediatek.com>
---
I ran into this bug when testing Matthias' v4.2-next/for-next branch on mt8173.
It now crashes on boot. The commit [0], which added the call to
map->format.format_val from regmap_bulk_read() when map->bus == NULL.

[0] commit 15b8d2c41fe5839582029f65c5f7004db451cc2b
  Author: Arun Chandran <achandran <at> mvista.com>
  regmap: Fix regmap_bulk_read in BE mode

Please see the error below, thanks.

Call trace:
[<          (null)>]           (null)
[<ffffffc0004cbdd0>] mtk_rtc_read_time+0x9c/0x134
[<ffffffc0004c9618>] __rtc_read_time.isra.3+0x40/0x7c
[<ffffffc0004c9688>] rtc_read_time+0x34/0x58
[<ffffffc0004c9e64>] __rtc_read_alarm+0x20/0x37c
[<ffffffc0004c8d2c>] rtc_device_register+0x194/0x2e0
[<ffffffc0004cbf60>] mtk_rtc_probe+0xf8/0x18c
[<ffffffc0003fb5e0>] platform_drv_probe+0x48/0xc4
[<ffffffc0003f99e0>] driver_probe_device+0x188/0x29c
[<ffffffc0003f9b8c>] __driver_attach+0x98/0xa0
[<ffffffc0003f7ce0>] bus_for_each_dev+0x54/0x98
[<ffffffc0003f94c8>] driver_attach+0x1c/0x28
[<ffffffc0003f9164>] bus_add_driver+0x1c0/0x228
[<ffffffc0003fa45c>] driver_register+0x64/0x130
[<ffffffc0003fb514>] __platform_driver_register+0x5c/0x68
[<ffffffc0008639a4>] mtk_rtc_driver_init+0x14/0x20
[<ffffffc000082864>] do_one_initcall+0x88/0x1ac
[<ffffffc000842b10>] kernel_init_freeable+0x158/0x1fc
[<ffffffc0005f45fc>] kernel_init+0xc/0xd8
---
 drivers/base/regmap/regmap.c | 20 +++++++++++++++++---
 1 file changed, 17 insertions(+), 3 deletions(-)

diff --git a/drivers/base/regmap/regmap.c b/drivers/base/regmap/regmap.c
index 7111d04..9357186 100644
--- a/drivers/base/regmap/regmap.c
+++ b/drivers/base/regmap/regmap.c
@@ -607,13 +607,13 @@ struct regmap *regmap_init(struct device *dev,
 		map->reg_write = config->reg_write;
 
 		map->defer_caching = false;
-		goto skip_format_initialization;
+		goto simple_format_initialization;
 	} else if (!bus->read || !bus->write) {
 		map->reg_read = _regmap_bus_reg_read;
 		map->reg_write = _regmap_bus_reg_write;
 
 		map->defer_caching = false;
-		goto skip_format_initialization;
+		goto simple_format_initialization;
 	} else {
 		map->reg_read  = _regmap_bus_read;
 	}
@@ -783,8 +783,22 @@ struct regmap *regmap_init(struct device *dev,
 		map->defer_caching = true;
 		map->reg_write = _regmap_bus_raw_write;
 	}
+/*
+ * For bulk read, need to hook the format function.
+ */
+simple_format_initialization:
 
-skip_format_initialization:
+	switch (config->val_bits) {
+		case 8:
+			map->format.format_val = regmap_format_8;
+			break;
+		case 16:
+			map->format.format_val = regmap_format_16_native;
+			break;
+		case 32:
+			map->format.format_val = regmap_format_32_native;
+			break;
+	}
 
 	map->range_tree = RB_ROOT;
 	for (i = 0; i < config->num_ranges; i++) {
-- 
1.8.1.1.dirty



From peter.griffin at linaro.org  Wed Aug 26 04:44:33 2015
From: peter.griffin at linaro.org (Peter Griffin)
Date: Wed, 26 Aug 2015 12:44:33 +0100
Subject: [PATCH 2/3] ARM: DT: STi: STiH407: Add c8sectpfe LinuxDVB DT node.
In-Reply-To: <20150826073041.GT19409@x1>
References: <1440519730-486-1-git-send-email-peter.griffin@linaro.org>
 <1440519730-486-3-git-send-email-peter.griffin@linaro.org>
 <20150826073041.GT19409@x1>
Message-ID: <20150826114433.GB1498@griffinp-ThinkPad-X1-Carbon-2nd>

Hi Lee,

On Wed, 26 Aug 2015, Lee Jones wrote:

> On Tue, 25 Aug 2015, Peter Griffin wrote:
> 
> > This patch adds in the required DT node for the c8sectpfe
> > Linux DVB demux driver which allows the tsin channels
> > to be used on an upstream kernel.
> > 
> > Signed-off-by: Peter Griffin <peter.griffin at linaro.org>
> > ---
> >  arch/arm/boot/dts/stihxxx-b2120.dtsi | 38 ++++++++++++++++++++++++++++++++++++
> >  1 file changed, 38 insertions(+)
> > 
> > diff --git a/arch/arm/boot/dts/stihxxx-b2120.dtsi b/arch/arm/boot/dts/stihxxx-b2120.dtsi
> > index 62994ae..1bc018e 100644
> > --- a/arch/arm/boot/dts/stihxxx-b2120.dtsi
> > +++ b/arch/arm/boot/dts/stihxxx-b2120.dtsi
> > @@ -6,6 +6,10 @@
> >   * it under the terms of the GNU General Public License version 2 as
> >   * published by the Free Software Foundation.
> >   */
> > +
> > +#include <dt-bindings/clock/stih407-clks.h>
> > +#include <dt-bindings/media/c8sectpfe.h>
> > +
> 
> Looks like some of the STi files are a little wavering on convention,
> but I suggest the extra '\n's are superfluous.

Ok I will remove them in v2.

> 
> >  / {
> >  	soc {
> >  		sbc_serial0: serial at 9530000 {
> > @@ -85,5 +89,39 @@
> >  			status = "okay";
> >  		};
> >  
> > +		c8sectpfe at 08a20000 {
> 
> This should be a device type, not a model number.
> 
> demodulator at abcdabcd {

Ok will change to demux at 08a20000 in v2

> 
> > +			compatible = "st,stih407-c8sectpfe";
> 
> To the uninitiated c8sectpfe is pretty indecipherable.

It is the name of the IP block in the datasheet. It stands
for SECurity TRansport Processor FrontEnd

> 
> How about *-c8sectpfe-demod?

That doesn't really make sense, the demod is a seperate device
typically controlled over I2C bus and connected to this IP block
via the TS pins. Also although a tsin channel is "normally" connected
to a demodulator device there is no reason it couldn't be connected
for example to another STi chipset which is doing tsout.

Also this IP block can do more than accept tsin, it can
also do tsout, and merge TS channels together (some coming from
DDR, external TS pins). Which are features we hope to add
to the driver in the future so the name needs to be very generic.

So with that in mind I would prefer to leave the compatible as
the name of the IP block from the SoC datasheet.

> 
> > +			status = "okay";
> > +			reg = <0x08a20000 0x10000>, <0x08a00000 0x4000>;
> > +			reg-names = "c8sectpfe", "c8sectpfe-ram";
> > +
> > +			interrupts = <0 34 0>, <0 35 0>;
> 
> Please use the predetermined DEFINES for the flags cell.

Will fix in V2

> 
> > +			interrupt-names = "c8sectpfe-error-irq",
> > +					  "c8sectpfe-idle-irq";
> > +
> > +			pinctrl-names	= "tsin0-serial", "tsin0-parallel",
> > +					  "tsin3-serial", "tsin4-serial",
> > +					  "tsin5-serial";
> 
> I would put *-names *under* the properties they pertain to and in the
> same format i.e. one per line in this case, for easy eye-match.

Ok will change in V2.
> 
> > +			pinctrl-0	= <&pinctrl_tsin0_serial>;
> > +			pinctrl-1	= <&pinctrl_tsin0_parallel>;
> > +			pinctrl-2	= <&pinctrl_tsin3_serial>;
> > +			pinctrl-3	= <&pinctrl_tsin4_serial_alt3>;
> > +			pinctrl-4	= <&pinctrl_tsin5_serial_alt1>;
> > +
> > +			clocks = <&clk_s_c0_flexgen CLK_PROC_STFE>;
> > +			clock-names = "c8sectpfe";
> > +
> > +			/* tsin0 is TSA on NIMA */
> > +			tsin0: port at 0 {
> > +
> 
> Why the '\n'?

Removed in v2
> 
> > +				tsin-num = <0>;
> > +				serial-not-parallel;
> > +				i2c-bus = <&ssc2>;
> 
> If you are adding this property, I would get Wolfram or one of the DT
> guys to Ack it.

This driver is actually already accepted, I just missed off one patch from
the v2 series which meant this patch broke the build when Mauro applied it,
which is the reason for re-sending it.

This binding is the same way the drm display drivers use DT via ddc-i2c-bus
property to get the i2c bus for EDID control, so I think uncontroversial.
> 
> > +				rst-gpio = <&pio15 4 0>;
> 
> Why not use the whole name "reset"?
> 
> "-gpio" should be "-gpios".
> 
> So, in full: "reset-gpios"?
> 
> Flags: GPIO_ACTIVE_HIGH ?

Doing a grep, that does seem to be "more standard". Will fix in V2 as a single
atomic commit.

regards,

Peter.


From fengguang.wu at intel.com  Wed Aug 26 04:44:10 2015
From: fengguang.wu at intel.com (kbuild test robot)
Date: Wed, 26 Aug 2015 19:44:10 +0800
Subject: [PATCH] ASoC: rockchip: fix platform_no_drv_owner.cocci warnings
In-Reply-To: <201508261907.XaXhY7JN%fengguang.wu@intel.com>
References: <201508261907.XaXhY7JN%fengguang.wu@intel.com>
Message-ID: <20150826114410.GA186569@ivytown2>

sound/soc/rockchip/rockchip_max98090.c:225:3-8: No need to set .owner here. The core will do it.

 Remove .owner field if calls are used which set it automatically

Generated by: scripts/coccinelle/api/platform_no_drv_owner.cocci

CC: zhengxing <zhengxing at rock-chips.com>
Signed-off-by: Fengguang Wu <fengguang.wu at intel.com>
---

 rockchip_max98090.c |    1 -
 1 file changed, 1 deletion(-)

--- a/sound/soc/rockchip/rockchip_max98090.c
+++ b/sound/soc/rockchip/rockchip_max98090.c
@@ -222,7 +222,6 @@ static struct platform_driver snd_rk_mc_
 	.probe = snd_rk_mc_probe,
 	.driver = {
 		.name = DRV_NAME,
-		.owner = THIS_MODULE,
 		.pm = &snd_soc_pm_ops,
 		.of_match_table = rockchip_max98090_of_match,
 	},


From fengguang.wu at intel.com  Wed Aug 26 04:48:13 2015
From: fengguang.wu at intel.com (kbuild test robot)
Date: Wed, 26 Aug 2015 19:48:13 +0800
Subject: [PATCH] ASoC: rockchip: fix platform_no_drv_owner.cocci warnings
In-Reply-To: <201508261911.CXlWEwle%fengguang.wu@intel.com>
References: <201508261911.CXlWEwle%fengguang.wu@intel.com>
Message-ID: <20150826114813.GA88839@ivytown2>

sound/soc/rockchip/rockchip_rt5645.c:214:3-8: No need to set .owner here. The core will do it.

 Remove .owner field if calls are used which set it automatically

Generated by: scripts/coccinelle/api/platform_no_drv_owner.cocci

CC: zhengxing <zhengxing at rock-chips.com>
Signed-off-by: Fengguang Wu <fengguang.wu at intel.com>
---

 rockchip_rt5645.c |    1 -
 1 file changed, 1 deletion(-)

--- a/sound/soc/rockchip/rockchip_rt5645.c
+++ b/sound/soc/rockchip/rockchip_rt5645.c
@@ -211,7 +211,6 @@ static struct platform_driver snd_rk_mc_
 	.probe = snd_rk_mc_probe,
 	.driver = {
 		.name = DRV_NAME,
-		.owner = THIS_MODULE,
 		.pm = &snd_soc_pm_ops,
 		.of_match_table = rockchip_rt5645_of_match,
 	},


From daniel at ffwll.ch  Wed Aug 26 04:52:29 2015
From: daniel at ffwll.ch (Daniel Vetter)
Date: Wed, 26 Aug 2015 13:52:29 +0200
Subject: [PATCH 1/7] drm/vc4: Add devicetree bindings for VC4.
In-Reply-To: <CAF6AEGu2fi0M7DsicHz+5SDHi1DyDRmvWjkmYPPgY6pZ423WcA@mail.gmail.com>
References: <1439427380-2436-1-git-send-email-eric@anholt.net>
 <1439427380-2436-2-git-send-email-eric@anholt.net>
 <55CEC25E.7070303@wwwdotorg.org>
 <874mjxwyx5.fsf@eliezer.anholt.net>
 <CAL_JsqJxiGUR5BxBPyR3-0NxqWsOxMGrWQA6cMXe2pjTom__nw@mail.gmail.com>
 <CAF6AEGu2fi0M7DsicHz+5SDHi1DyDRmvWjkmYPPgY6pZ423WcA@mail.gmail.com>
Message-ID: <20150826115229.GI1367@phenom.ffwll.local>

On Tue, Aug 25, 2015 at 04:42:18PM -0400, Rob Clark wrote:
> On Mon, Aug 24, 2015 at 9:47 AM, Rob Herring <robherring2 at gmail.com> wrote:
> > On Mon, Aug 17, 2015 at 1:30 PM, Eric Anholt <eric at anholt.net> wrote:
> >> Stephen Warren <swarren at wwwdotorg.org> writes:
> >>
> >>> On 08/12/2015 06:56 PM, Eric Anholt wrote:
> >>>> Signed-off-by: Eric Anholt <eric at anholt.net>
> >>>
> >>> This one definitely needs a patch description, since someone might not
> >>> know what a VC4 is, and "git log" won't show the text from the binding
> >>> doc itself. I'd suggest adding the initial paragraph of the binding doc
> >>> as the patch description, or more.
> >>>
> >>>> diff --git a/Documentation/devicetree/bindings/gpu/brcm,bcm-vc4.txt b/Documentation/devicetree/bindings/gpu/brcm,bcm-vc4.txt
> >>
> >>>> +- hvss:             List of references to HVS video scalers
> >>>> +- encoders: List of references to output encoders (HDMI, SDTV)
> >>>
> >>> Would it make sense to make all those nodes child node of the vc4
> >>> object. That way, there's no need to have these lists of objects; they
> >>> can be automatically built up as the DT is enumerated. I know that e.g.
> >>> the NVIDIA Tegra host1x binding works this way, and I think it may have
> >>> been inspired by other similar cases.
> >>
> >> I've looked at tegra, and the component system used by msm appears to be
> >> nicer than it.  To follow tegra's model, it looks like I need to build
> >> this extra bus thing corresponding to host1x that is effectively the
> >> drivers/base/component.c code, so that I can get at vc4's structure from
> >> the component drivers.
> >>
> >>> Of course, this is only appropriate if the HW modules really are
> >>> logically children of the VC4 HW module. Perhaps they aren't. If they
> >>> aren't though, I wonder what this "vc4" module actually represents in HW?
> >>
> >> It's the subsystem, same as we use a subsystem node for msm, sti,
> >> rockchip, imx, and exynos.  This appears to be the common model of how
> >> the collection of graphics-related components is represented in the DT.
> >
> > I think most of these bindings are wrong. They are grouped together
> > because that is what DRM wants not because that reflects the h/w. So
> > convince me this is one block, not that it is what other people do.
> 
> I think, when it comes to more complex driver subsystems (like drm in
> particular) we have a bit of mismatch between how things look from the
> "pure hw ignoring sw" perspective, and the "how sw and in particular
> userspace expects things" perspective.  Maybe it is less a problem in
> other subsystems, where bindings map to things that are only visible
> in the kernel, or well defined devices like uart or sata controller.
> But when given the choice, I'm going to err on the side of not
> confusing userspace and the large software stack that sits above
> drm/kms, over dt purity.
> 
> Maybe it would be nice to have a sort of dt overlay that adds the bits
> needed to tie together hw blocks that should be assembled into a
> single logical device for linux and userspace (but maybe not some
> other hypothetical operating system).  But so far that doesn't exist.
> All we have is a hammer (devicetree), everything looks like a nail.
> End result is we end up adding some things in the bindings which
> aren't purely about the hw.  Until someone invents a screwdriver, I'm
> not sure what else to do.  In the end, other hypothetical OS is free
> to ignore those extra fields in the bindings if it doesn't need them.
> So meh?

I thought we agreed a while back that these kind of "pull everything for
the logical device together" dt nodes which just have piles of phandles
are totally accepted? At least that's the point behind the component
helpers, and Eric even suggested to create dt-specific component helpers
to cut down a bit on the usual boilerplate. dt maintainers are also fine
with this approach afaik. From my understanding tegra with the host1x bus
really is the odd one out and not the norm.

Given that and with the hope that we'll eventually see a dt-enabled
component functions to standardize this even more the overall concept is

Acked-by: Daniel Vetter <daniel.vetter at ffwll.ch>

Cheers, Daniel
-- 
Daniel Vetter
Software Engineer, Intel Corporation
http://blog.ffwll.ch


From thierry.reding at gmail.com  Wed Aug 26 04:51:50 2015
From: thierry.reding at gmail.com (Thierry Reding)
Date: Wed, 26 Aug 2015 13:51:50 +0200
Subject: [PATCH 1/7] drm/vc4: Add devicetree bindings for VC4.
In-Reply-To: <55CEC25E.7070303@wwwdotorg.org>
References: <1439427380-2436-1-git-send-email-eric@anholt.net>
 <1439427380-2436-2-git-send-email-eric@anholt.net>
 <55CEC25E.7070303@wwwdotorg.org>
Message-ID: <20150826115148.GB320@ulmo.nvidia.com>

On Fri, Aug 14, 2015 at 10:38:54PM -0600, Stephen Warren wrote:
> On 08/12/2015 06:56 PM, Eric Anholt wrote:
> > Signed-off-by: Eric Anholt <eric at anholt.net>
> 
> This one definitely needs a patch description, since someone might not
> know what a VC4 is, and "git log" won't show the text from the binding
> doc itself. I'd suggest adding the initial paragraph of the binding doc
> as the patch description, or more.
> 
> > diff --git a/Documentation/devicetree/bindings/gpu/brcm,bcm-vc4.txt b/Documentation/devicetree/bindings/gpu/brcm,bcm-vc4.txt
> 
> > +Required properties for VC4:
> > +- compatible:	Should be "brcm,vc4"
> > +- crtcs:	List of references to pixelvalve scanout engines
> 
> s/references to/phandles of/ would be more typical DT language.
> 
> > +- hvss:		List of references to HVS video scalers
> > +- encoders:	List of references to output encoders (HDMI, SDTV)
> 
> Would it make sense to make all those nodes child node of the vc4
> object. That way, there's no need to have these lists of objects; they
> can be automatically built up as the DT is enumerated. I know that e.g.
> the NVIDIA Tegra host1x binding works this way, and I think it may have
> been inspired by other similar cases.

Actually the host1x binding was the first of its kind. Unfortunately for
the purposes of this discussion (but fortunately otherwise) Tegra is the
odd-ball it seems. host1x is indeed a physical parent of all the devices
pertaining to the DRM driver, so the DT description is accurate from a
hardware point of view while at the same time giving us a top-level
device that we can bind against.

Now for most other cases it seems like the central piece that they are
missing is this top-level device, hence why the "virtual DRM subsystem
device" is instantiated. I tried to argue in the past that it wasn't a
proper description and proposed alternatives, but I was always pretty
much the only one with this viewpoint, so my comments ended up being
ignored.

Technically there is nothing that would prevent other drivers from doing
without the lists of phandles. On Tegra, again this might be special for
this particular hardware, we've never had a need to describe these kinds
of relationships. Each display controller can essentially drive each of
the outputs, which we deal with elegantly by setting the .possible_crtcs
mask of the encoders.

Also, to pull together all devices that are needed to make up the DRM
device, we use a list of compatible strings in the driver to find these
devices. Then as each of them registers with the host1x bus we wait for
the subdevice list to become empty and ->probe() the component host1x
device.

Note that while this predates component/master, this is all very similar
in principle (Russell and I did have some discussions about this back at
the time, but I'm not sure how much, if anything, he took as inspiration
from the host1x infrastructure). After component/master was merged I did
try to convert Tegra DRM to use it. Things looked pretty good, but ended
up not working because each componentized device must have a unique
master device. This poses a problem because on Tegra we needed the top-
level (i.e. master) device to be shared among multiple drivers.

I posted patches at some point to try and fix remedy the situation but
wasn't able to elicit any reactions, and since I had something that was
working did not pursue this any further.

Thierry
-------------- next part --------------
A non-text attachment was scrubbed...
Name: signature.asc
Type: application/pgp-signature
Size: 819 bytes
Desc: not available
URL: <http://lists.infradead.org/pipermail/linux-arm-kernel/attachments/20150826/6ac61672/attachment.sig>

From lee.jones at linaro.org  Wed Aug 26 04:57:52 2015
From: lee.jones at linaro.org (Lee Jones)
Date: Wed, 26 Aug 2015 12:57:52 +0100
Subject: [PATCH 2/3] ARM: DT: STi: STiH407: Add c8sectpfe LinuxDVB DT node.
In-Reply-To: <20150826114433.GB1498@griffinp-ThinkPad-X1-Carbon-2nd>
References: <1440519730-486-1-git-send-email-peter.griffin@linaro.org>
 <1440519730-486-3-git-send-email-peter.griffin@linaro.org>
 <20150826073041.GT19409@x1>
 <20150826114433.GB1498@griffinp-ThinkPad-X1-Carbon-2nd>
Message-ID: <20150826115752.GX19409@x1>

On Wed, 26 Aug 2015, Peter Griffin wrote:
> On Wed, 26 Aug 2015, Lee Jones wrote:
> > On Tue, 25 Aug 2015, Peter Griffin wrote:
> > 
> > > This patch adds in the required DT node for the c8sectpfe
> > > Linux DVB demux driver which allows the tsin channels
> > > to be used on an upstream kernel.
> > > 
> > > Signed-off-by: Peter Griffin <peter.griffin at linaro.org>
> > > ---
> > >  arch/arm/boot/dts/stihxxx-b2120.dtsi | 38 ++++++++++++++++++++++++++++++++++++
> > >  1 file changed, 38 insertions(+)
> > > 
> > > diff --git a/arch/arm/boot/dts/stihxxx-b2120.dtsi b/arch/arm/boot/dts/stihxxx-b2120.dtsi
> > > index 62994ae..1bc018e 100644
> > > --- a/arch/arm/boot/dts/stihxxx-b2120.dtsi
> > > +++ b/arch/arm/boot/dts/stihxxx-b2120.dtsi

[...]

> > How about *-c8sectpfe-demod?
> 
> That doesn't really make sense, the demod is a seperate device
> typically controlled over I2C bus and connected to this IP block
> via the TS pins. Also although a tsin channel is "normally" connected
> to a demodulator device there is no reason it couldn't be connected
> for example to another STi chipset which is doing tsout.
> 
> Also this IP block can do more than accept tsin, it can
> also do tsout, and merge TS channels together (some coming from
> DDR, external TS pins). Which are features we hope to add
> to the driver in the future so the name needs to be very generic.
> 
> So with that in mind I would prefer to leave the compatible as
> the name of the IP block from the SoC datasheet.

Understood.  Thanks for the explanation.

[...]

> > > +				tsin-num = <0>;
> > > +				serial-not-parallel;
> > > +				i2c-bus = <&ssc2>;
> > 
> > If you are adding this property, I would get Wolfram or one of the DT
> > guys to Ack it.
> 
> This driver is actually already accepted, I just missed off one patch from
> the v2 series which meant this patch broke the build when Mauro applied it,
> which is the reason for re-sending it.
> 
> This binding is the same way the drm display drivers use DT via ddc-i2c-bus
> property to get the i2c bus for EDID control, so I think uncontroversial.

You're still adding a non-vendor property.  If you think it's generic
enough not to require a "<vendor>," prefix, please attempt to document
it in a generic binding document.

> > > +				rst-gpio = <&pio15 4 0>;
> > 
> > Why not use the whole name "reset"?
> > 
> > "-gpio" should be "-gpios".
> > 
> > So, in full: "reset-gpios"?
> > 
> > Flags: GPIO_ACTIVE_HIGH ?
> 
> Doing a grep, that does seem to be "more standard". Will fix in V2 as a single
> atomic commit.

It's not just 'more standard', it's documented in the GPIO binding.

-- 
Lee Jones
Linaro STMicroelectronics Landing Team Lead
Linaro.org ? Open source software for ARM SoCs
Follow Linaro: Facebook | Twitter | Blog


From jianhua.ljh at gmail.com  Wed Aug 26 05:02:32 2015
From: jianhua.ljh at gmail.com (Jianhua Liu)
Date: Wed, 26 Aug 2015 20:02:32 +0800
Subject: [PATCH] arm64: fix bug for reloading FPSIMD state after execve on
 cpu 0.
In-Reply-To: <20150826111205.GD30466@arm.com>
References: <1440556841-17219-1-git-send-email-chunyan.zhang@spreadtrum.com>
 <20150826111205.GD30466@arm.com>
Message-ID: <CAAgTQPXEMqdcVY0M+YX=HQobos47hEbTzH18ynioM1iwu39aXw@mail.gmail.com>

NO, kernel thread will not use fpsimd.
kernel threads get scheduled in, per_cpu(fpsimd_last_state) will not be updated.

The following is the condion that bug comes.
1. Process A runa on CPU 0, and does execve syscall.
2. Before execve syscall return to userspace, A gets scheduled out.
3. some kernel threads get scheduled in on CPU 0,
    per_cpu(fpsimd_last_state) will not be updated, still points to
A's fpsimd_state
4. Process A get scheduled in on CPU 0,
        1)process A's fpsimd_state.cpu contains 0,
        2)cpu 0's  fpsimd_last_state per-cpu variable points to
process A 's fpsimd_state,
        These two are the conditions that TIF_FOREIGN_FPSTATE get cleared?

The kernel will not reload the fpsimd context during A returns back to
user space.
But A's fpsimd context is cleared to zero after execve syscall and
must to be reload.


I am not seeing an exact issue in practice.

Janet


On Wed, Aug 26, 2015 at 7:12 PM, Will Deacon <will.deacon at arm.com> wrote:
> Hello,
>
> [adding Ard]
>
> On Wed, Aug 26, 2015 at 03:40:41AM +0100, Chunyan Zhang wrote:
>> From: Janet Liu <janet.liu at spreadtrum.com>
>>
>> If process A is running on CPU 0 and do execve syscall and after sched_exec,
>> dest_cpu is 0, fpsimd_state.cpu is 0. If at the time Process A get scheduled
>> out and after some kernel threads running on CPU 0, process A is back in CPU 0,
>> A's fpsimd_state.cpu is current cpu id "0", and per_cpu(fpsimd_last_state)
>> points A's fpsimd_state, TIF_FOREIGN_FPSTATE will be clear, kernel will not
>> reload the context during it return to userspace. so set the cpu's
>> fpsimd_last_state to NULL to avoid this.
>
> AFAICT, this is only a problem if one of the kernel threads uses the fpsimd
> registers, right? However, kernel_neon_begin_partial clobbers
> fpsimd_last_state, so I'm struggling to see the problem.
>
> Are you seeing an issue in practice?
>
> Will
>
>> Signed-off-by: Janet Liu <janet.liu at spreadtrum.com>
>> Signed-off-by: Chunyan Zhang <chunyan.zhang at spreadtrum.com>
>> ---
>>  arch/arm64/kernel/fpsimd.c |    1 +
>>  1 file changed, 1 insertion(+)
>>
>> diff --git a/arch/arm64/kernel/fpsimd.c b/arch/arm64/kernel/fpsimd.c
>> index 44d6f75..ec58d94 100644
>> --- a/arch/arm64/kernel/fpsimd.c
>> +++ b/arch/arm64/kernel/fpsimd.c
>> @@ -159,6 +159,7 @@ void fpsimd_flush_thread(void)
>>  {
>>       memset(&current->thread.fpsimd_state, 0, sizeof(struct fpsimd_state));
>>       set_thread_flag(TIF_FOREIGN_FPSTATE);
>> +     this_cpu_write(fpsimd_last_state, NULL);
>>  }
>>
>>  /*
>> --
>> 1.7.9.5
>>


From lee.jones at linaro.org  Wed Aug 26 05:06:28 2015
From: lee.jones at linaro.org (Lee Jones)
Date: Wed, 26 Aug 2015 13:06:28 +0100
Subject: [PATCH v4 2/2] dt: power: st: Provide bindings for ST's OPPs
In-Reply-To: <20150812110841.GC20238@linux>
References: <20150810132247.GH3249@x1> <20150811080023.GB5509@linux>
 <20150811093039.GA18282@x1> <20150811100941.GG5509@linux>
 <20150811115425.GE18282@x1> <20150811120124.GH5509@linux>
 <20150811132756.GG18282@x1> <20150811142812.GJ5509@linux>
 <20150811151736.GO18282@x1> <20150812110841.GC20238@linux>
Message-ID: <20150826120628.GZ19409@x1>

On Wed, 12 Aug 2015, Viresh Kumar wrote:

> On 11-08-15, 16:17, Lee Jones wrote:
> > This would work if we only had a single variable to contend with, but
> > what I showed you in my previous example is that we have 3 variables
> > to consider; cut (version), pcode and substrate.
> > 
> > Using the two (simple) examples I provided, how would your suggestion
> > look in our case?
> 
> So the solution I gave is for picking the microvolt based on pcode.
> The other two (cut, substrate) aren't about picking microvolt, but if
> the OPP is available or not. Right?

'pcode', 'cut' and 'substrate' all determine whether a given set of
OPPs an be used on the running platform.  I do not believe that you
can differentiate between them. 

> If these terms are generic enough, then we can add something similar
> to what you have added..

If it makes it easier, you can treat them as version numbers 2.2.1
<pcode.cut.substrate>, but I don't see how this can help.  Obviously
this becomes more difficult when you add wild cards to the OPPs, where
a particular OPP would be suitable for all cuts for example.

If you still think you can come up with a generic method to lay out
CPUFreq OPP nodes that will satisfy all vendors and not be a mass of
10's of separate nodes, then great.  Again, I'm struggling to see how
that might be possible.

What I believe we shouldn't do, is have this blocked forever for the
sake of adding a couple of vendor properties however.

-- 
Lee Jones
Linaro STMicroelectronics Landing Team Lead
Linaro.org ? Open source software for ARM SoCs
Follow Linaro: Facebook | Twitter | Blog


From linus.walleij at linaro.org  Wed Aug 26 05:08:31 2015
From: linus.walleij at linaro.org (Linus Walleij)
Date: Wed, 26 Aug 2015 14:08:31 +0200
Subject: [PATCH 3/3] gpiolib: Add GPIO initialization
In-Reply-To: <1439979512-3894-4-git-send-email-mpa@pengutronix.de>
References: <1439979512-3894-1-git-send-email-mpa@pengutronix.de>
 <1439979512-3894-4-git-send-email-mpa@pengutronix.de>
Message-ID: <CACRpkdZV0_QgT9eAPC7cQ4JFYb5npNobn40M13mhYruU0O0vdw@mail.gmail.com>

On Wed, Aug 19, 2015 at 12:18 PM, Markus Pargmann <mpa at pengutronix.de> wrote:

> From: Markus Pargmann <mpa at devmp.org>
>
> This functions adds a way to initialize a GPIO without hogging it.
>
> Signed-off-by: Markus Pargmann <mpa at devmp.org>
> ---
>  Documentation/devicetree/bindings/gpio/gpio.txt | 29 +++++++------

This needs to go to devicetree at vger.kernel.org for review.

Yours,
Linus Walleij


From thierry.reding at gmail.com  Wed Aug 26 05:09:36 2015
From: thierry.reding at gmail.com (Thierry Reding)
Date: Wed, 26 Aug 2015 14:09:36 +0200
Subject: [PATCH 1/7] drm/vc4: Add devicetree bindings for VC4.
In-Reply-To: <20150826115229.GI1367@phenom.ffwll.local>
References: <1439427380-2436-1-git-send-email-eric@anholt.net>
 <1439427380-2436-2-git-send-email-eric@anholt.net>
 <55CEC25E.7070303@wwwdotorg.org>
 <874mjxwyx5.fsf@eliezer.anholt.net>
 <CAL_JsqJxiGUR5BxBPyR3-0NxqWsOxMGrWQA6cMXe2pjTom__nw@mail.gmail.com>
 <CAF6AEGu2fi0M7DsicHz+5SDHi1DyDRmvWjkmYPPgY6pZ423WcA@mail.gmail.com>
 <20150826115229.GI1367@phenom.ffwll.local>
Message-ID: <20150826120934.GC320@ulmo.nvidia.com>

On Wed, Aug 26, 2015 at 01:52:29PM +0200, Daniel Vetter wrote:
> On Tue, Aug 25, 2015 at 04:42:18PM -0400, Rob Clark wrote:
> > On Mon, Aug 24, 2015 at 9:47 AM, Rob Herring <robherring2 at gmail.com> wrote:
> > > On Mon, Aug 17, 2015 at 1:30 PM, Eric Anholt <eric at anholt.net> wrote:
> > >> Stephen Warren <swarren at wwwdotorg.org> writes:
> > >>
> > >>> On 08/12/2015 06:56 PM, Eric Anholt wrote:
> > >>>> Signed-off-by: Eric Anholt <eric at anholt.net>
> > >>>
> > >>> This one definitely needs a patch description, since someone might not
> > >>> know what a VC4 is, and "git log" won't show the text from the binding
> > >>> doc itself. I'd suggest adding the initial paragraph of the binding doc
> > >>> as the patch description, or more.
> > >>>
> > >>>> diff --git a/Documentation/devicetree/bindings/gpu/brcm,bcm-vc4.txt b/Documentation/devicetree/bindings/gpu/brcm,bcm-vc4.txt
> > >>
> > >>>> +- hvss:             List of references to HVS video scalers
> > >>>> +- encoders: List of references to output encoders (HDMI, SDTV)
> > >>>
> > >>> Would it make sense to make all those nodes child node of the vc4
> > >>> object. That way, there's no need to have these lists of objects; they
> > >>> can be automatically built up as the DT is enumerated. I know that e.g.
> > >>> the NVIDIA Tegra host1x binding works this way, and I think it may have
> > >>> been inspired by other similar cases.
> > >>
> > >> I've looked at tegra, and the component system used by msm appears to be
> > >> nicer than it.  To follow tegra's model, it looks like I need to build
> > >> this extra bus thing corresponding to host1x that is effectively the
> > >> drivers/base/component.c code, so that I can get at vc4's structure from
> > >> the component drivers.
> > >>
> > >>> Of course, this is only appropriate if the HW modules really are
> > >>> logically children of the VC4 HW module. Perhaps they aren't. If they
> > >>> aren't though, I wonder what this "vc4" module actually represents in HW?
> > >>
> > >> It's the subsystem, same as we use a subsystem node for msm, sti,
> > >> rockchip, imx, and exynos.  This appears to be the common model of how
> > >> the collection of graphics-related components is represented in the DT.
> > >
> > > I think most of these bindings are wrong. They are grouped together
> > > because that is what DRM wants not because that reflects the h/w. So
> > > convince me this is one block, not that it is what other people do.
> > 
> > I think, when it comes to more complex driver subsystems (like drm in
> > particular) we have a bit of mismatch between how things look from the
> > "pure hw ignoring sw" perspective, and the "how sw and in particular
> > userspace expects things" perspective.  Maybe it is less a problem in
> > other subsystems, where bindings map to things that are only visible
> > in the kernel, or well defined devices like uart or sata controller.
> > But when given the choice, I'm going to err on the side of not
> > confusing userspace and the large software stack that sits above
> > drm/kms, over dt purity.
> > 
> > Maybe it would be nice to have a sort of dt overlay that adds the bits
> > needed to tie together hw blocks that should be assembled into a
> > single logical device for linux and userspace (but maybe not some
> > other hypothetical operating system).  But so far that doesn't exist.
> > All we have is a hammer (devicetree), everything looks like a nail.
> > End result is we end up adding some things in the bindings which
> > aren't purely about the hw.  Until someone invents a screwdriver, I'm
> > not sure what else to do.  In the end, other hypothetical OS is free
> > to ignore those extra fields in the bindings if it doesn't need them.
> > So meh?
> 
> I thought we agreed a while back that these kind of "pull everything for
> the logical device together" dt nodes which just have piles of phandles
> are totally accepted? At least that's the point behind the component
> helpers, and Eric even suggested to create dt-specific component helpers
> to cut down a bit on the usual boilerplate. dt maintainers are also fine
> with this approach afaik. From my understanding tegra with the host1x bus
> really is the odd one out and not the norm.

I agree that in many aspects Tegra is somewhat special. But the same
principles that the host1x infrastructure uses could be implemented in a
similar way for other DRM drivers. You can easily collect information
about subdevices by walking the device tree and matching on known
compatible strings. And you can also instantiate the top-level device
from driver code rather than have it in DT. It should still be possible
to make this work without an artificial device node in DT. The component
and master infrastructure is largely orthogonal to that, and as far as I
remember the only blocker is the need for a top-level device. I wonder
if perhaps this could be made to work by binding the master to the top-
level SoC device.

Obviously adding the node in DT is easier, but to my knowledge easy has
never been a good excuse for mangling DT. Perhaps that's different these
days...

Thierry
-------------- next part --------------
A non-text attachment was scrubbed...
Name: signature.asc
Type: application/pgp-signature
Size: 819 bytes
Desc: not available
URL: <http://lists.infradead.org/pipermail/linux-arm-kernel/attachments/20150826/23936e24/attachment.sig>

From linus.walleij at linaro.org  Wed Aug 26 05:11:28 2015
From: linus.walleij at linaro.org (Linus Walleij)
Date: Wed, 26 Aug 2015 14:11:28 +0200
Subject: [PATCH v2] pinctrl: mediatek: Fix multiple registration issue.
In-Reply-To: <CAFRkauDE4QRnZP4q61JyX+t8rn3zOtokiESJTV4uak71zM0kTg@mail.gmail.com>
References: <1440041931-38278-1-git-send-email-hongzhou.yang@mediatek.com>
 <CAFRkauDE4QRnZP4q61JyX+t8rn3zOtokiESJTV4uak71zM0kTg@mail.gmail.com>
Message-ID: <CACRpkdY-W+=Eq2nsabqULcFZCi1bLd3eyBDY8yQmyCLwEz1RSA@mail.gmail.com>

On Thu, Aug 20, 2015 at 5:49 AM, Axel Lin <axel.lin at ingics.com> wrote:
> 2015-08-20 11:38 GMT+08:00 Hongzhou Yang <hongzhou.yang at mediatek.com>:
>> Since our common driver need support main chip and PMU
>> at the same time, that means it will register two
>> pinctrl device, and the pinctrl_desc structure should
>> be used two times.
>>
>> But pinctrl_desc use global static definition, then
>> the latest registered pinctrl device will overwrite
>> the old one's, all members in pinctrl_desc will set to
>> the new one's, such as name, pins and pins numbers, etc.
>> This is a bug. Changing to use devm_kzalloc to fix it.
>>
>> Cc: stable at vger.kernel.org # v4.1+
>> Signed-off-by: Hongzhou Yang <hongzhou.yang at mediatek.com>
>> ---
>>  Use dynamic allocation to fix multiple registration issue.
>>
>>  drivers/pinctrl/mediatek/pinctrl-mtk-common.c |   26 ++++++++++++++-----------
>>  drivers/pinctrl/mediatek/pinctrl-mtk-common.h |    1 +
>>  2 files changed, 16 insertions(+), 11 deletions(-)
>>
>> diff --git a/drivers/pinctrl/mediatek/pinctrl-mtk-common.c b/drivers/pinctrl/mediatek/pinctrl-mtk-common.c
>> index ad1ea16..911c736 100644
>> --- a/drivers/pinctrl/mediatek/pinctrl-mtk-common.c
>> +++ b/drivers/pinctrl/mediatek/pinctrl-mtk-common.c
>> @@ -1202,12 +1202,6 @@ static int mtk_pctrl_build_state(struct platform_device *pdev)
>>         return 0;
>>  }
>>
>> -static struct pinctrl_desc mtk_pctrl_desc = {
>> -       .confops        = &mtk_pconf_ops,
>> -       .pctlops        = &mtk_pctrl_ops,
>> -       .pmxops         = &mtk_pmx_ops,
>> -};
>> -
>>  int mtk_pctrl_init(struct platform_device *pdev,
>>                 const struct mtk_pinctrl_devdata *data,
>>                 struct regmap *regmap)
>> @@ -1265,12 +1259,22 @@ int mtk_pctrl_init(struct platform_device *pdev,
>>
>>         for (i = 0; i < pctl->devdata->npins; i++)
>>                 pins[i] = pctl->devdata->pins[i].pin;
>> -       mtk_pctrl_desc.name = dev_name(&pdev->dev);
>> -       mtk_pctrl_desc.owner = THIS_MODULE;
>> -       mtk_pctrl_desc.pins = pins;
>> -       mtk_pctrl_desc.npins = pctl->devdata->npins;
>> +
>> +       pctl->pctl_desc = devm_kzalloc(&pdev->dev, sizeof(*pctl->pctl_desc),
>> +                               GFP_KERNEL);
>> +       if (!pctl->pctl_desc)
>> +               return -ENOMEM;
>> +
>> +       pctl->pctl_desc->name = dev_name(&pdev->dev);
>> +       pctl->pctl_desc->owner = THIS_MODULE;
>> +       pctl->pctl_desc->pins = pins;
>> +       pctl->pctl_desc->npins = pctl->devdata->npins;
>> +       pctl->pctl_desc->confops = &mtk_pconf_ops;
>> +       pctl->pctl_desc->pctlops = &mtk_pctrl_ops;
>> +       pctl->pctl_desc->pmxops = &mtk_pmx_ops;
>>         pctl->dev = &pdev->dev;
>> -       pctl->pctl_dev = pinctrl_register(&mtk_pctrl_desc, &pdev->dev, pctl);
>> +
>> +       pctl->pctl_dev = pinctrl_register(pctl->pctl_desc, &pdev->dev, pctl);
>>         if (IS_ERR(pctl->pctl_dev)) {
>>                 dev_err(&pdev->dev, "couldn't register pinctrl driver\n");
>>                 return PTR_ERR(pctl->pctl_dev);
>> diff --git a/drivers/pinctrl/mediatek/pinctrl-mtk-common.h b/drivers/pinctrl/mediatek/pinctrl-mtk-common.h
>> index 30213e5..93d6f5b 100644
>> --- a/drivers/pinctrl/mediatek/pinctrl-mtk-common.h
>> +++ b/drivers/pinctrl/mediatek/pinctrl-mtk-common.h
>> @@ -256,6 +256,7 @@ struct mtk_pinctrl_devdata {
>>  struct mtk_pinctrl {
>>         struct regmap   *regmap1;
>>         struct regmap   *regmap2;
>> +       struct pinctrl_desc *pctl_desc;
> Use
> struct pinctrl_desc pctl_desc;
>
> Then you can remove the devm_kzalloc.

I agree with Axel, use a true member instead of a pointer
and you get something simpler.

Yours,
Linus Walleij


From jteki at openedev.com  Wed Aug 26 05:19:59 2015
From: jteki at openedev.com (Jagan Teki)
Date: Wed, 26 Aug 2015 17:49:59 +0530
Subject: [LINUX RFC v2 0/4] spi: add dual parallel mode support in Zynq
 MPSoC GQSPI controller
In-Reply-To: <1440570367-22569-1-git-send-email-ranjit.waghmode@xilinx.com>
References: <1440570367-22569-1-git-send-email-ranjit.waghmode@xilinx.com>
Message-ID: <CAD6G_RQhWBsUTZNBB44W98Fjzw82H_D_E9nY0aDWezj729mkoA@mail.gmail.com>

On 26 August 2015 at 11:56, Ranjit Waghmode <ranjit.waghmode at xilinx.com> wrote:
> This series adds dual parallel mode support for Zynq Ultrascale+
> MPSoC GQSPI controller driver.
>
> What is dual parallel mode?
> ---------------------------
> ZynqMP GQSPI controller supports Dual Parallel mode with following functionalities:
> 1) Supporting two SPI flash memories operating in parallel. 8 I/O lines.
> 2) Chip selects and clock are shared to both the flash devices
> 3) This mode is targeted for faster read/write speed and also doubles the size
> 4) Commands/data can be transmitted/received from both the devices(mirror),
>    or only upper or only lower flash memory devices.
> 5) Data arrangement:
>    With stripe enabled,
>    Even bytes i.e. 0, 2, 4,... are transmitted on Lower Data Bus
>    Odd bytes i.e. 1, 3, 5,.. are transmitted on Upper Data Bus.
>
> This series also updated MTD layer files for adding parallel mode support.
>
> 1) Added Support for two flashes
> 2) Support to enable/disable data stripe as and when required.
> 3) Added required parameters to spi_nor structure. Initialized all
>    added parameters in spi_nor_scan()
> 4) Added support for dual parallel in spi_nor_read/write/erase functions by:
>    a) Increasing page_size, sector_size, erase_size and toatal flash size
>       as and when required.
>    b) Dividing address by 2
>    c) Updating spi->master->flags for qspi driver to change CS
> 5) Updated read_sr() to get status of both flashes
> 6) Also updated read_fsr() to get status of both flashes
>
> These all are very high level changes and expected to make an idea clear.
> Comments and suggestions are always welcomed
>
> ---
> V2 Changes:
> a) Splitted patches based on logical changes
> b) Added error handling for newly added APIs in SPI core
> ---
>
> Ranjit Waghmode (4):
>   spi: add support of two chip selects & data stripe
>   mtd: add spi_device instance to spi_nor struct
>   spi-nor: add dual parallel mode support
>   spi: zynqmp: gqspi: add support for dual parallel mode configuration

I don't find any previous discussion about way to inform flash
dual-ness into spi-nor
from spi drivers.

Here is my idea, probably others may think same.
Informing dual_flash from drivers/spi through flags or any other mode
bits is not a better approach as dual flash feature is specific to
spi-nor flash controller (controller specially designed for spi-nor
flash not the generic spi controller).  So if the driver sits on
drivers/mtd/spi-nor/ (ex: fsl-quadspi.c), may be we can inform flash
specific things to spi-nor as it's not touching generic spi stack in
Linux. But there is a defined-drawback if the driver is moved to
drivers/mtd/spi-nor ie it can't use spi core API's at-all.

thanks!
-- 
Jagan | openedev.


From varada at codeaurora.org  Wed Aug 26 05:27:47 2015
From: varada at codeaurora.org (Varadarajan Narayanan)
Date: Wed, 26 Aug 2015 17:57:47 +0530
Subject: [PATCH v5] qcom: ipq4019: Add basic board/dts support for IPQ4019 SoC
Message-ID: <20150826122747.GA4957@codeaurora.org>

Add initial dts files and SoC support for IPQ4019

Signed-off-by: Varadarajan Narayanan <varada at codeaurora.org>
---
Changes in v2:
  - Added devicetree bindings documentation

Changes in v3:
  - Split 'gcnt' into a separate patch
  - Added the new entries to Makefiles, Kconfig & board.c in sorted order
  - Used "qcom,ipq40xx" instead of "qcom,ipq40xx-r3pc" in board.c

Changes in v4:
  - Removed r3pc dts
  - Removed timer frequency

 arch/arm/boot/dts/qcom-ipq4019.dtsi | 72 +++++++++++++++++++++++++++++++++++++
 1 file changed, 72 insertions(+)
 create mode 100644 arch/arm/boot/dts/qcom-ipq4019.dtsi

diff --git a/arch/arm/boot/dts/qcom-ipq4019.dtsi b/arch/arm/boot/dts/qcom-ipq4019.dtsi
new file mode 100644
index 0000000..668cc84
--- /dev/null
+++ b/arch/arm/boot/dts/qcom-ipq4019.dtsi
@@ -0,0 +1,72 @@
+/*
+ * Copyright (c) 2014, The Linux Foundation. All rights reserved.
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License version 2 and
+ * only 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.
+ */
+
+/dts-v1/;
+
+#include "skeleton.dtsi"
+
+/ {
+	model = "Qualcomm Technologies, Inc. IPQ4019";
+	compatible = "qcom,ipq4019";
+	interrupt-parent = <&intc>;
+
+	cpus {
+		#address-cells = <1>;
+		#size-cells = <0>;
+		cpu at 0 {
+			device_type = "cpu";
+			compatible = "arm,cortex-a7";
+			reg = <0x0>;
+		};
+
+		cpu at 1 {
+			device_type = "cpu";
+			compatible = "arm,cortex-a7";
+			reg = <0x1>;
+		};
+
+		cpu at 2 {
+			device_type = "cpu";
+			compatible = "arm,cortex-a7";
+			reg = <0x2>;
+		};
+
+		cpu at 3 {
+			device_type = "cpu";
+			compatible = "arm,cortex-a7";
+			reg = <0x3>;
+		};
+	};
+
+	soc {
+		#address-cells = <1>;
+		#size-cells = <1>;
+		ranges;
+		compatible = "simple-bus";
+
+		intc: interrupt-controller at b000000 {
+			compatible = "qcom,msm-qgic2";
+			interrupt-controller;
+			#interrupt-cells = <3>;
+			reg = <0x0b000000 0x1000>,
+			<0x0b002000 0x1000>;
+		};
+
+		serial at 78b0000 {
+			compatible = "qcom,msm-uartdm-v1.4", "qcom,msm-uartdm";
+			reg = <0x78b0000 0x200>;
+			interrupts = <0 108 0>;
+			status = "disabled";
+		};
+	};
+};
-- 
1.8.2.1



From holler at ahsoftware.de  Wed Aug 26 05:28:12 2015
From: holler at ahsoftware.de (Alexander Holler)
Date: Wed, 26 Aug 2015 14:28:12 +0200
Subject: [PATCH 00/16] deps: deterministic driver initialization order
Message-ID: <1440592108-3740-1-git-send-email-holler@ahsoftware.de>

Hello,

I've already written a lot on that topic, therefor this introductory
mail doesn't explain everything.

Please have a look at the threads

"dt: dependencies (for deterministic driver initialization order based on
the DT)"

and

"On-demand device registration"

on LKML for previous discussions.

In short, the current init system is quiet old and doesn't really match
todays HW which needs much more drivers than 20 years ago.

As I've mentioned in those threads, initcalls should be identifiable
in order to sort them. My previous attempt intercepted the driver
registrations in order to do that, which unfortunately ended up with
having to deal how drivers are creating devices.

I've now spend some more time and this partly new approach now annotates
the initcalls directly, by storing a pointer to a struct device_driver in
addition to the pointer to the initcall.

This makes my previous patches smaller, cleaner and better to understand,
the result which you can see in this little patch series.

The whole patch series is made up of several parts.

The first 4 patches are modifying dtc to include dependencies (type
information for phandles).

The next 3 patches are the ones which are implementing those annotated
initcalls and the driver sort algorithm.

Then there are 3 patches with small changes on some dts.

The following 4 patches with the WIP (Work In Progress) are changing
some initcalls to annotated initcalls. I would split them up in
a bunch of patches (one for each driver), if I get the promise that
the other patches will be merged into mainline (but not without that
promise).

The final 2 patches are fixes which should end up in mainline, regardless
if this feature is merged or not.

Some numbers (5 boots on each board, without and with ordering drivers),
all times are seconds.

Kirkwood (dockstar, armv5):

Boot to "Freeing unused kernel memory" (includes mounting the rootfs),
unordered:
4.456016 3.937801 4.114788 4.114526 3.949480 (average 4.1145222)
ordered:
3.173054 3.164045 3.141418 3.480679 3.459298 (3.2836988)
Time needed to sort (of_init_build_order()):
0.003024
Time needed to match drivers to the order (without calling them):
0.002884

Beagleboard (rev C4, armv7):

unordered:
6.706024 6.821746 6.696014 6.673675 6.769866 (6.733465)
ordered:
5.544860 5.514160 5.505859 5.527374 5.496795 (5.5178096)
sorting: 0.021209
matching: 0.006165

Beaglebone Black (rev A5, armv7):

unordered:
3.826531 3.825662 3.826648 3.825434 3.825263 (3.8259076)
ordered:
2.838554 2.838322 2.839459 2.838467 2.838421 (2.8386446)
sorting: 0.004769
matching: 0.004860

imx6q (armv7):

unordered:
3.451998 3.418864 3.446952 3.429974 3.440996 (3.4377568)
ordered:
3.538312 3.549019 3.538105 3.515916 3.555715 (3.5394134)
sorting: 0.004622
matching: 0.003868


Because I'm using different configuration options on these boards,
the absolute times aren't comparable.

But in conclusion, most boards are booting faster when the initcalls
have been ordered.

In addition, ordering the initcalls makes the initialization sequence
more deterministic (it can even be seen without booting a machine).

But I still think the most benefit of these little series is by not having
to use in-driver hacks or that ugly brute force trial-and-error deferred
probing in order to fix a wrong default call order of initcalls.

Further improvements could be to initialize drivers in parallel (using
multiple cores) and/or to use this stuff on x86 (ACPI) too (e.g. by using a
minimal DT which just includes dependencies).


To test this series with any other DT enabled board, look at which
drivers are referenced in the DT (see patch 2 or 3), annotate these
drivers (trivial, see patch 5 or the examples with WIP in the subject),
turn on CONFIG_OF_DEPENDENCIES, compile and boot.


Just to mention it, unless CONFIG_OF_DEPENDENCIES is turned on (which is
marked as experimental), nothing will change, even if you've annotated
some drivers (the new macros will just map to the old ones).


Regards,

Alexander Holler

PS: Please keep in mind that these patches are an offer. I'm already
100+ patches above mainline and don't really care to maintain some more
for myself.


From holler at ahsoftware.de  Wed Aug 26 05:28:13 2015
From: holler at ahsoftware.de (Alexander Holler)
Date: Wed, 26 Aug 2015 14:28:13 +0200
Subject: [PATCH 01/16] deps: dtc: Automatically add new property
 'dependencies' which contains a list of referenced phandles
In-Reply-To: <1440592108-3740-1-git-send-email-holler@ahsoftware.de>
References: <1440592108-3740-1-git-send-email-holler@ahsoftware.de>
Message-ID: <1440592108-3740-2-git-send-email-holler@ahsoftware.de>

During the step from .dts to .dtb the information about dependcies
contained in the .dts through phandle references is lost. This makes it
impossible to use the binary blob to create a dependency graph without
knowing the semantic of all cell arrays.

Therefor automatically add a new property called 'dependencies' to all
nodes which have phandle references in one of their properties.

This new property will contain an array of phandles with one value for
every phandle referenced by other properties in the node.

If such a property already exists (e.g. to manually add dependencies
through the .dts), the existing list will be expanded.

Added phandles will be the phandle of either the referenced node itself
(if it has a property named 'compatible', or of the next parent of the
referenced node which as property named 'compatible'. This ensures only
dependencies to drivers will be added.

References to phandles of parent or child nodes will not be added to this
property, because this information is already contained in the blob (in
the form of the tree itself).

No dependencies to disabled nodes will be added.

Signed-off-by: Alexander Holler <holler at ahsoftware.de>
---
 scripts/dtc/Makefile       |   3 +-
 scripts/dtc/Makefile.dtc   |   1 +
 scripts/dtc/dependencies.c | 108 +++++++++++++++++++++++++++++++++++++++++++++
 scripts/dtc/dtc.c          |  12 ++++-
 scripts/dtc/dtc.h          |   3 ++
 5 files changed, 125 insertions(+), 2 deletions(-)
 create mode 100644 scripts/dtc/dependencies.c

diff --git a/scripts/dtc/Makefile b/scripts/dtc/Makefile
index 2a48022..1174cf9 100644
--- a/scripts/dtc/Makefile
+++ b/scripts/dtc/Makefile
@@ -4,7 +4,7 @@ hostprogs-y	:= dtc
 always		:= $(hostprogs-y)
 
 dtc-objs	:= dtc.o flattree.o fstree.o data.o livetree.o treesource.o \
-		   srcpos.o checks.o util.o
+		   srcpos.o checks.o util.o dependencies.o
 dtc-objs	+= dtc-lexer.lex.o dtc-parser.tab.o
 
 # Source files need to get at the userspace version of libfdt_env.h to compile
@@ -13,6 +13,7 @@ HOSTCFLAGS_DTC := -I$(src) -I$(src)/libfdt
 
 HOSTCFLAGS_checks.o := $(HOSTCFLAGS_DTC)
 HOSTCFLAGS_data.o := $(HOSTCFLAGS_DTC)
+HOSTCFLAGS_dependencies.o := $(HOSTCFLAGS_DTC)
 HOSTCFLAGS_dtc.o := $(HOSTCFLAGS_DTC)
 HOSTCFLAGS_flattree.o := $(HOSTCFLAGS_DTC)
 HOSTCFLAGS_fstree.o := $(HOSTCFLAGS_DTC)
diff --git a/scripts/dtc/Makefile.dtc b/scripts/dtc/Makefile.dtc
index bece49b..5fb5343 100644
--- a/scripts/dtc/Makefile.dtc
+++ b/scripts/dtc/Makefile.dtc
@@ -6,6 +6,7 @@
 DTC_SRCS = \
 	checks.c \
 	data.c \
+	dependencies.c \
 	dtc.c \
 	flattree.c \
 	fstree.c \
diff --git a/scripts/dtc/dependencies.c b/scripts/dtc/dependencies.c
new file mode 100644
index 0000000..dd4658c
--- /dev/null
+++ b/scripts/dtc/dependencies.c
@@ -0,0 +1,108 @@
+/*
+ * Code to add a property which contains dependencies (used phandle references)
+ * to all (driver) nodes which are having phandle references.
+ *
+ * Copyright (C) 2014 Alexander Holler <holler at ahsoftware.de>
+ *
+ * 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.
+ */
+
+#include <dtc.h>
+
+/* Searches upwards for a node with a property 'compatible' */
+static struct node *find_compatible_not_disabled(struct node *node)
+{
+	struct property *prop;
+
+	while (node) {
+		prop = get_property(node, "compatible");
+		if (prop) {
+			prop = get_property(node, "status");
+			if (prop)
+				if (!prop->val.len ||
+					(strcmp(prop->val.val, "okay") &&
+						strcmp(prop->val.val, "ok")))
+					return NULL; /* disabled */
+			return node;
+		}
+		node = node->parent;
+	}
+	return NULL;
+}
+
+static bool is_parent_of(struct node *node1, struct node *node2)
+{
+	while (node2) {
+		if (node2->parent == node1)
+			return true;
+		node2 = node2->parent;
+	}
+	return false;
+
+}
+
+static void add_deps(struct node *dt, struct node *node, struct property *prop)
+{
+	struct marker *m = prop->val.markers;
+	struct node *refnode;
+	cell_t phandle;
+	struct property *prop_deps;
+	unsigned i;
+	cell_t *cell;
+	struct node *source;
+	struct node *target;
+
+	for_each_marker_of_type(m, REF_PHANDLE) {
+		assert(m->offset + sizeof(cell_t) <= prop->val.len);
+
+		refnode = get_node_by_ref(dt, m->ref);
+		if (!refnode) {
+			fprintf(stderr,
+				"ERROR: Reference to non-existent node or label \"%s\"\n",
+				m->ref);
+			continue;
+		}
+
+		source = find_compatible_not_disabled(node);
+		target = find_compatible_not_disabled(refnode);
+		if (!source || !target || source == target ||
+				is_parent_of(source, target) ||
+				is_parent_of(target, source))
+			continue;
+		phandle = get_node_phandle(dt, target);
+		prop_deps = get_property(source, "dependencies");
+		if (!prop_deps) {
+			add_property(source,
+			     build_property("dependencies",
+				data_append_cell(empty_data, phandle)));
+			continue;
+		}
+		cell = (cell_t *)prop_deps->val.val;
+		for (i = 0; i < prop_deps->val.len/4; ++i)
+			if (*cell++ == cpu_to_fdt32(phandle))
+				break;
+		if (i < prop_deps->val.len/4)
+			continue; /* avoid duplicates */
+		prop_deps->val = data_append_cell(prop_deps->val, phandle);
+	}
+}
+
+static void process_nodes_props(struct node *dt, struct node *node)
+{
+	struct node *child;
+	struct property *prop;
+
+	for_each_property(node, prop)
+		add_deps(dt, node, prop);
+
+	for_each_child(node, child)
+		process_nodes_props(dt, child);
+}
+
+void add_dependencies(struct boot_info *bi)
+{
+	process_nodes_props(bi->dt, bi->dt);
+}
diff --git a/scripts/dtc/dtc.c b/scripts/dtc/dtc.c
index 8c4add6..28def27 100644
--- a/scripts/dtc/dtc.c
+++ b/scripts/dtc/dtc.c
@@ -51,7 +51,7 @@ static void fill_fullpaths(struct node *tree, const char *prefix)
 #define FDT_VERSION(version)	_FDT_VERSION(version)
 #define _FDT_VERSION(version)	#version
 static const char usage_synopsis[] = "dtc [options] <input file>";
-static const char usage_short_opts[] = "qI:O:o:V:d:R:S:p:fb:i:H:sW:E:hv";
+static const char usage_short_opts[] = "qI:O:o:V:d:R:S:p:fb:i:H:sDW:E:hv";
 static struct option const usage_long_opts[] = {
 	{"quiet",            no_argument, NULL, 'q'},
 	{"in-format",         a_argument, NULL, 'I'},
@@ -66,6 +66,7 @@ static struct option const usage_long_opts[] = {
 	{"force",            no_argument, NULL, 'f'},
 	{"include",           a_argument, NULL, 'i'},
 	{"sort",             no_argument, NULL, 's'},
+	{"no-deps",          no_argument, NULL, 'D'},
 	{"phandle",           a_argument, NULL, 'H'},
 	{"warning",           a_argument, NULL, 'W'},
 	{"error",             a_argument, NULL, 'E'},
@@ -93,6 +94,7 @@ static const char * const usage_opts_help[] = {
 	"\n\tTry to produce output even if the input tree has errors",
 	"\n\tAdd a path to search for include files",
 	"\n\tSort nodes and properties before outputting (useful for comparing trees)",
+	"\n\tDo not automatically add dependencies for phandle references",
 	"\n\tValid phandle formats are:\n"
 	 "\t\tlegacy - \"linux,phandle\" properties only\n"
 	 "\t\tepapr  - \"phandle\" properties only\n"
@@ -112,6 +114,7 @@ int main(int argc, char *argv[])
 	const char *outname = "-";
 	const char *depname = NULL;
 	bool force = false, sort = false;
+	bool dependencies = true;
 	const char *arg;
 	int opt;
 	FILE *outf = NULL;
@@ -179,6 +182,10 @@ int main(int argc, char *argv[])
 			sort = true;
 			break;
 
+		case 'D':
+			dependencies = false;
+			break;
+
 		case 'W':
 			parse_checks_option(true, false, optarg);
 			break;
@@ -236,6 +243,9 @@ int main(int argc, char *argv[])
 	if (sort)
 		sort_tree(bi);
 
+	if (dependencies)
+		add_dependencies(bi);
+
 	if (streq(outname, "-")) {
 		outf = stdout;
 	} else {
diff --git a/scripts/dtc/dtc.h b/scripts/dtc/dtc.h
index 56212c8..6facad1 100644
--- a/scripts/dtc/dtc.h
+++ b/scripts/dtc/dtc.h
@@ -266,4 +266,7 @@ struct boot_info *dt_from_source(const char *f);
 
 struct boot_info *dt_from_fs(const char *dirname);
 
+/* Dependencies */
+void add_dependencies(struct boot_info *bi);
+
 #endif /* _DTC_H */
-- 
2.1.0



From holler at ahsoftware.de  Wed Aug 26 05:28:14 2015
From: holler at ahsoftware.de (Alexander Holler)
Date: Wed, 26 Aug 2015 14:28:14 +0200
Subject: [PATCH 02/16] deps: dtc: Add option to print initialization order
In-Reply-To: <1440592108-3740-1-git-send-email-holler@ahsoftware.de>
References: <1440592108-3740-1-git-send-email-holler@ahsoftware.de>
Message-ID: <1440592108-3740-3-git-send-email-holler@ahsoftware.de>

Add option -t to print the default initialization order.
No other output will be generated.

To print the order, just use something like this:

	CROSS_COMPILE=gcc-foo ARCH=arm make foo.dtb
	scripts/dtc/dtc -I dtb -t arch/arm/boot/dts/foo.dtb

Since it's now possible to check to for cycles in the dependency graph,
this is now done too.

Signed-off-by: Alexander Holler <holler at ahsoftware.de>
---
 scripts/dtc/dependencies.c | 344 +++++++++++++++++++++++++++++++++++++++++++++
 scripts/dtc/dtc.c          |  24 +++-
 scripts/dtc/dtc.h          |   2 +
 3 files changed, 369 insertions(+), 1 deletion(-)

diff --git a/scripts/dtc/dependencies.c b/scripts/dtc/dependencies.c
index dd4658c..3fb5cef 100644
--- a/scripts/dtc/dependencies.c
+++ b/scripts/dtc/dependencies.c
@@ -106,3 +106,347 @@ void add_dependencies(struct boot_info *bi)
 {
 	process_nodes_props(bi->dt, bi->dt);
 }
+
+/*
+ * The code below is in large parts a copy of drivers/of/of_dependencies.c
+ * in the Linux kernel. So both files do share the same bugs.
+ * The next few ugly defines do exist to keep the differences at a minimum.
+ */
+static struct node *tree;
+#define pr_cont(format, ...) printf(format, ##__VA_ARGS__)
+#define pr_info(format, ...) printf(format, ##__VA_ARGS__)
+#define pr_warn(format, ...) printf(format, ##__VA_ARGS__)
+#define pr_err(format, ...) fprintf(stderr, format, ##__VA_ARGS__)
+typedef cell_t __be32;
+#define device_node node
+#define full_name fullpath
+#define __initdata
+#define __init
+#define unlikely(a) (a)
+#define of_node_put(a)
+#define of_find_node_by_phandle(v) get_node_by_phandle(tree, v)
+#define __of_get_property(a, b, c) get_property(a, b)
+#define for_each_child_of_node(a, b) for_each_child(a, b)
+
+
+#define MAX_DT_NODES 1000 /* maximum number of vertices */
+#define MAX_EDGES (MAX_DT_NODES*2) /* maximum number of edges (dependencies) */
+
+struct edgenode {
+	uint32_t y; /* phandle */
+	struct edgenode *next; /* next edge in list */
+};
+
+/*
+ * Vertex numbers do correspond to phandle numbers. That means the graph
+ * does contain as much vertices as the maximum of all phandles.
+ * Or in other words, we assume that for all phandles in the device tree
+ * 0 < phandle < MAX_DT_NODES+1 is true.
+ */
+struct dep_graph {
+	struct edgenode edge_slots[MAX_EDGES]; /* used to avoid kmalloc */
+	struct edgenode *edges[MAX_DT_NODES+1]; /* adjacency info */
+	unsigned nvertices; /* number of vertices in graph */
+	unsigned nedges; /* number of edges in graph */
+	bool processed[MAX_DT_NODES+1]; /* which vertices have been processed */
+	bool include_node[MAX_DT_NODES+1]; /* which nodes to consider */
+	bool discovered[MAX_DT_NODES+1]; /* which vertices have been found */
+	bool finished; /* if true, cut off search immediately */
+};
+static struct dep_graph graph __initdata;
+
+struct init_order {
+	uint32_t max_phandle; /* the max used phandle */
+	uint32_t old_max_phandle; /* used to keep track of added phandles */
+	struct device_node *order[MAX_DT_NODES+1];
+	unsigned count;
+	/* Used to keep track of parent devices in regard to the DT */
+	uint32_t parent_by_phandle[MAX_DT_NODES+1];
+	struct device *device_by_phandle[MAX_DT_NODES+1];
+};
+static struct init_order order __initdata;
+
+
+/* Copied from drivers/of/base.c (because it's lockless). */
+static int __init __of_device_is_available(struct device_node *device)
+{
+	struct property *status;
+
+	if (!device)
+		return 0;
+
+	status = get_property(device, "status");
+	if (status == NULL)
+		return 1;
+
+	if (status->val.len > 0) {
+		if (!strcmp(status->val.val, "okay") ||
+				!strcmp(status->val.val, "ok"))
+			return 1;
+	}
+
+	return 0;
+}
+
+/*
+ * x is a dependant of y or in other words
+ * y will be initialized before x.
+ */
+static int __init insert_edge(uint32_t x, uint32_t y)
+{
+	struct edgenode *p; /* temporary pointer */
+
+	if (unlikely(x > MAX_DT_NODES || y > MAX_DT_NODES)) {
+		pr_err("Node found with phandle 0x%x > MAX_DT_NODES (%d)!\n",
+			x > MAX_DT_NODES ? x : y, MAX_DT_NODES);
+		return -EINVAL;
+	}
+	if (unlikely(!x || !y))
+		return 0;
+	if (unlikely(graph.nedges >= MAX_EDGES)) {
+		pr_err("Maximum number of edges (%d) reached!\n", MAX_EDGES);
+		return -EINVAL;
+	}
+	p = &graph.edge_slots[graph.nedges++];
+	graph.include_node[x] = 1;
+	graph.include_node[y] = 1;
+	p->y = y;
+	p->next = graph.edges[x];
+	graph.edges[x] = p; /* insert at head of list */
+
+	graph.nvertices = (x > graph.nvertices) ? x : graph.nvertices;
+	graph.nvertices = (y > graph.nvertices) ? y : graph.nvertices;
+	return 0;
+}
+
+static void __init print_node_name(uint32_t v)
+{
+	struct device_node *node;
+
+	node = of_find_node_by_phandle(v);
+	if (!node) {
+		pr_err("Node for phandle 0x%x not found", v);
+		return;
+	}
+	if (node->name)
+		pr_err("%s", node->name);
+	if (node->full_name)
+		pr_err(" (%s)", node->full_name);
+	of_node_put(node);
+}
+
+/*
+ * I would prefer to use the BGL (Boost Graph Library), but as I can't use it
+ * here (for obvious reasons), the next four functions below are based on
+ * code of Steven Skiena's book 'The Algorithm Design Manual'.
+ */
+
+static void __init process_edge(uint32_t x, uint32_t y)
+{
+	if (unlikely(graph.discovered[y] && !graph.processed[y])) {
+		pr_err("Cycle found 0x%x ", x);
+		print_node_name(x);
+		pr_cont(" <-> 0x%x ", y);
+		print_node_name(y);
+		pr_cont("!\n");
+		graph.finished = 1;
+	}
+}
+
+static void __init process_vertex_late(uint32_t v)
+{
+	struct device_node *node;
+
+	node = of_find_node_by_phandle(v);
+	if (!node) {
+		pr_err("No node for phandle 0x%x not found", v);
+		return;
+	}
+	order.order[order.count++] = node;
+}
+
+static void __init depth_first_search(uint32_t v)
+{
+	struct edgenode *p;
+	uint32_t y; /* successor vertex */
+
+	if (graph.finished)
+		return;
+	graph.discovered[v] = 1;
+	p = graph.edges[v];
+	while (p) {
+		y = p->y;
+		if (!graph.discovered[y]) {
+			process_edge(v, y);
+			depth_first_search(y);
+		} else
+			process_edge(v, y);
+		if (graph.finished)
+			return;
+		p = p->next;
+	}
+	process_vertex_late(v);
+	graph.processed[v] = 1;
+}
+
+static void __init topological_sort(void)
+{
+	unsigned i;
+
+	for (i = 1; i <= graph.nvertices; ++i)
+		if (!graph.discovered[i] && graph.include_node[i])
+			depth_first_search(i);
+}
+
+static int __init add_dep_list(struct device_node *node)
+{
+	const __be32 *list, *list_end;
+	uint32_t ph;
+	struct property *prop;
+	int rc = 0;
+	struct device_node *dep;
+
+	prop = get_property(node, "dependencies");
+	if (!prop || !prop->val.len || prop->val.len%sizeof(*list))
+		return 0;
+	list = (const __be32 *)prop->val.val;
+	list_end = list + prop->val.len / sizeof(*list);
+	while (list < list_end) {
+		ph = fdt32_to_cpu(*list++);
+		if (unlikely(!ph)) {
+			/* Should never happen */
+			if (node->name)
+				pr_warn("phandle == 0 for %s\n", node->name);
+			continue;
+		}
+		dep = of_find_node_by_phandle(ph);
+		if (unlikely(!dep)) {
+			pr_err("No DT node for dependency with phandle 0x%x found\n",
+				ph);
+			continue;
+		}
+		rc = insert_edge(node->phandle, ph);
+		if (rc)
+			break;
+	}
+
+	return rc;
+}
+
+/* Copied from drivers/of/base.c */
+static const char *of_prop_next_string(struct property *prop, const char *cur)
+{
+	const char *curv = cur;
+
+	if (!prop)
+		return NULL;
+
+	if (!cur)
+		return prop->val.val;
+
+	curv += strlen(cur) + 1;
+	if (curv >= prop->val.val + prop->val.len)
+		return NULL;
+
+	return curv;
+}
+
+static int __init add_deps_lnx(struct device_node *parent,
+				struct device_node *node)
+{
+	struct device_node *child;
+	int rc = 0;
+
+	if (!__of_device_is_available(node))
+		return 0;
+	if (__of_get_property(node, "compatible", NULL)) {
+		if (!parent->phandle) {
+			if (__of_get_property(parent, "compatible", NULL))
+				parent->phandle = 1 + order.max_phandle++;
+		}
+		if (!node->phandle)
+			node->phandle = 1 + order.max_phandle++;
+		rc = insert_edge(node->phandle, parent->phandle);
+		if (rc)
+			return rc;
+		if (unlikely(order.parent_by_phandle[node->phandle])) {
+			/* sanity check */
+			pr_err("0x%x already has a parent!\n", node->phandle);
+			return -EINVAL;
+		}
+		order.parent_by_phandle[node->phandle] = parent->phandle;
+		rc = add_dep_list(node);
+		if (unlikely(rc))
+			return rc;
+		parent = node; /* change the parent only if node is a driver */
+	}
+	for_each_child_of_node(node, child) {
+		rc = add_deps_lnx(parent, child);
+		if (unlikely(rc))
+			break;
+	}
+
+	return rc;
+}
+
+static void calc_max_phandle(struct node *np)
+{
+	struct node *child;
+
+	if (!np || np->deleted)
+		return;
+	if (np->phandle > order.max_phandle)
+		order.max_phandle = np->phandle;
+
+	for_each_child(np, child)
+		calc_max_phandle(child);
+}
+
+void __init of_init_print_order(const char *name)
+{
+	unsigned i;
+	struct property *prop;
+	const char *cp;
+
+	pr_info("Default initialization order for %s:\n", name);
+	for (i = 0; i < order.count; ++i) {
+		pr_info("init %u 0x%x", i, order.order[i]->phandle);
+		if (order.order[i]->name)
+			pr_cont(" %s", order.order[i]->name);
+		if (order.order[i]->full_name)
+			pr_cont(" (%s)", order.order[i]->full_name);
+		prop = get_property(order.order[i], "compatible");
+		for (cp = of_prop_next_string(prop, NULL); cp;
+		     cp = of_prop_next_string(prop, cp))
+			pr_cont(" %s", cp);
+		pr_cont(" (parent 0x%x)\n",
+			order.parent_by_phandle[order.order[i]->phandle]);
+	}
+}
+
+int __init of_init_build_order(struct device_node *root)
+{
+	struct device_node *child;
+	int rc = 0;
+
+	tree = root;
+	if (unlikely(!root))
+		return -EINVAL;
+
+	calc_max_phandle(root);
+	order.old_max_phandle = order.max_phandle;
+
+	for_each_child_of_node(root, child) {
+		rc = add_deps_lnx(root, child);
+		if (unlikely(rc))
+			break;
+	}
+
+	of_node_put(root);
+	topological_sort();
+
+	if (graph.finished)
+		return -EINVAL; /* cycle found */
+
+	return rc;
+}
diff --git a/scripts/dtc/dtc.c b/scripts/dtc/dtc.c
index 28def27..494c531 100644
--- a/scripts/dtc/dtc.c
+++ b/scripts/dtc/dtc.c
@@ -51,7 +51,7 @@ static void fill_fullpaths(struct node *tree, const char *prefix)
 #define FDT_VERSION(version)	_FDT_VERSION(version)
 #define _FDT_VERSION(version)	#version
 static const char usage_synopsis[] = "dtc [options] <input file>";
-static const char usage_short_opts[] = "qI:O:o:V:d:R:S:p:fb:i:H:sDW:E:hv";
+static const char usage_short_opts[] = "qI:O:o:V:d:R:S:p:fb:i:H:sDtW:E:hv";
 static struct option const usage_long_opts[] = {
 	{"quiet",            no_argument, NULL, 'q'},
 	{"in-format",         a_argument, NULL, 'I'},
@@ -67,6 +67,7 @@ static struct option const usage_long_opts[] = {
 	{"include",           a_argument, NULL, 'i'},
 	{"sort",             no_argument, NULL, 's'},
 	{"no-deps",          no_argument, NULL, 'D'},
+	{"initialization-order", no_argument, NULL, 't'},
 	{"phandle",           a_argument, NULL, 'H'},
 	{"warning",           a_argument, NULL, 'W'},
 	{"error",             a_argument, NULL, 'E'},
@@ -95,6 +96,7 @@ static const char * const usage_opts_help[] = {
 	"\n\tAdd a path to search for include files",
 	"\n\tSort nodes and properties before outputting (useful for comparing trees)",
 	"\n\tDo not automatically add dependencies for phandle references",
+	"\n\tPrint (default) initialization order",
 	"\n\tValid phandle formats are:\n"
 	 "\t\tlegacy - \"linux,phandle\" properties only\n"
 	 "\t\tepapr  - \"phandle\" properties only\n"
@@ -115,6 +117,7 @@ int main(int argc, char *argv[])
 	const char *depname = NULL;
 	bool force = false, sort = false;
 	bool dependencies = true;
+	bool init_order = false;
 	const char *arg;
 	int opt;
 	FILE *outf = NULL;
@@ -186,6 +189,10 @@ int main(int argc, char *argv[])
 			dependencies = false;
 			break;
 
+		case 't':
+			init_order = true;
+			break;
+
 		case 'W':
 			parse_checks_option(true, false, optarg);
 			break;
@@ -246,6 +253,13 @@ int main(int argc, char *argv[])
 	if (dependencies)
 		add_dependencies(bi);
 
+	if (init_order) {
+		if (of_init_build_order(bi->dt))
+			exit(2);
+		of_init_print_order(arg);
+		exit(0);
+	}
+
 	if (streq(outname, "-")) {
 		outf = stdout;
 	} else {
@@ -267,5 +281,13 @@ int main(int argc, char *argv[])
 		die("Unknown output format \"%s\"\n", outform);
 	}
 
+	/*
+	 * Check for cycles by building the initialzation order.
+	 * This is done after the output was saved because it
+	 * changes the tree slightly.
+	 */
+	if (of_init_build_order(bi->dt))
+		exit(2);
+
 	exit(0);
 }
diff --git a/scripts/dtc/dtc.h b/scripts/dtc/dtc.h
index 6facad1..9ae4bfc 100644
--- a/scripts/dtc/dtc.h
+++ b/scripts/dtc/dtc.h
@@ -268,5 +268,7 @@ struct boot_info *dt_from_fs(const char *dirname);
 
 /* Dependencies */
 void add_dependencies(struct boot_info *bi);
+void of_init_print_order(const char *name);
+int of_init_build_order(struct node *root);
 
 #endif /* _DTC_H */
-- 
2.1.0



From holler at ahsoftware.de  Wed Aug 26 05:28:16 2015
From: holler at ahsoftware.de (Alexander Holler)
Date: Wed, 26 Aug 2015 14:28:16 +0200
Subject: [PATCH 04/16] deps: dtc: introduce new (virtual) property
 no-dependencies
In-Reply-To: <1440592108-3740-1-git-send-email-holler@ahsoftware.de>
References: <1440592108-3740-1-git-send-email-holler@ahsoftware.de>
Message-ID: <1440592108-3740-5-git-send-email-holler@ahsoftware.de>

In some cases it makes sense to handle some phandles not as dependencies.

This is escpecially true for 'remote-endpoint' properties, because these
otherwise introducing dependency cycles into the graph. To avoid these,
one end of each remote-endpoint pairs has not to be handled as a
dependency.

The syntax is like

	foo {
		remote-endpoint = <&bar>;
	};
	bar {
		remote-endpoint = <&foo>;
		no-dependencies = <&foo>;
	};

Without that 'no-dependencies' property dtc would automatically add a
dependency to foo to the property 'dependencies' of the node bar.
But with that 'no-dependencies' it will not automatically add the
listed dependencies.

The property 'no-dependencies' is virtual property and will not be added
to any output file.

Signed-off-by: Alexander Holler <holler at ahsoftware.de>
---
 scripts/dtc/dependencies.c | 33 +++++++++++++++++++++++++++++++++
 1 file changed, 33 insertions(+)

diff --git a/scripts/dtc/dependencies.c b/scripts/dtc/dependencies.c
index 2c1e0d4..76e4d91 100644
--- a/scripts/dtc/dependencies.c
+++ b/scripts/dtc/dependencies.c
@@ -44,6 +44,23 @@ static bool is_parent_of(struct node *node1, struct node *node2)
 
 }
 
+static bool is_no_dependency(struct node *dt, struct property *prop, cell_t ph)
+{
+	struct node *node;
+	unsigned i;
+	cell_t *cell = (cell_t *)(prop->val.val);
+
+	for (i = 0; i < prop->val.len/4; ++i) {
+		node = get_node_by_phandle(dt, cpu_to_fdt32(*cell++));
+		if (node) {
+			node = find_compatible_not_disabled(node);
+			if (node && get_node_phandle(dt, node) == ph)
+				return true;
+		}
+	}
+	return false;
+}
+
 static void add_deps(struct node *dt, struct node *node, struct property *prop)
 {
 	struct marker *m = prop->val.markers;
@@ -73,6 +90,10 @@ static void add_deps(struct node *dt, struct node *node, struct property *prop)
 				is_parent_of(target, source))
 			continue;
 		phandle = get_node_phandle(dt, target);
+		prop_deps = get_property(node, "no-dependencies");
+		if (prop_deps && is_no_dependency(dt, prop_deps, phandle))
+			/* avoid adding non-dependencies */
+			continue;
 		prop_deps = get_property(source, "dependencies");
 		if (!prop_deps) {
 			add_property(source,
@@ -102,9 +123,21 @@ static void process_nodes_props(struct node *dt, struct node *node)
 		process_nodes_props(dt, child);
 }
 
+static void del_prop_no_dependencies(struct node *node)
+{
+	struct node *child;
+
+	if (!node)
+		return;
+	delete_property_by_name(node, "no-dependencies");
+	for_each_child(node, child)
+		del_prop_no_dependencies(child);
+}
+
 void add_dependencies(struct boot_info *bi)
 {
 	process_nodes_props(bi->dt, bi->dt);
+	del_prop_no_dependencies(bi->dt);
 }
 
 /*
-- 
2.1.0



From cyrille.pitchen at atmel.com  Wed Aug 26 05:30:22 2015
From: cyrille.pitchen at atmel.com (Cyrille Pitchen)
Date: Wed, 26 Aug 2015 14:30:22 +0200
Subject: [PATCH linux-next v5 0/5] add driver for Atmel QSPI controller
Message-ID: <cover.1440580764.git.cyrille.pitchen@atmel.com>

ChangeLog

v5:
- remove unused inline functions qspi_read[bw]() and qspi_write[bw](),
  keep only qspi_readl() and qspi_writel().
- use reinit_completion() instead of init_completion() during run time,
  call init_completion() once for all in the probe().
- add a dev_warn() when trying to tune the number of dummy cycles for
  spi-nor of a not supported manufacturer then fall back to the default
  framework value.
- reword some comments.
- add "Acked-by: Marek Vasut <marex at denx.de>" for patches 1 and 4.
- add "Acked-by: Bean Huo <beanhuo at micron.com>" for patch 1.

v4:
- add "OF && HAS_DMA" dependency in Kconfig for Atmel Quad SPI driver.
- return -ENOMEM instead of the return code of dma_mapping_error() as this
  function returns a boolean on ARM achitecture.
- add "Acked-by: Nicolas Ferre <nicolas.ferre at atmel.com>" for Atmel Quad
  SPI driver and its DT binding documentation.

v3:
- reword the comment which explains that spi_nor_set_protocol() is used by
  the spi-nor framework to notify lower layers, especially the (Q)SPI
  controller about a protocol change.
- change the definitions of register/bitfield macros in the Atmel QSPI
  controller driver: get rid of concatenation operator and use BIT and
  GENMASK macros when possible.
- use #define[SPACE] instead of #define[TAB]

v2:
- remove the patches to set the "latency code" of Spansion QSPI memories
  (support of Spansion memories may be submitted in later series).
- rename "qspi" node into "spi" in the DT example to fit ePAPR standard.
- remove the useless "qspi0" label from the DT node example.
- remove the leading 0 from the size of the second memory region to make
  it consistent with the size of the first memory region.
- indent the DT bindings documentation to make it more readable.
- remove the useless ".bus	= &platform_bus_type," line from the
  platform driver definition.

v1:

This series of patches add support for the new Atmel QSPI controller
embedded inside sama5d2x SoCs.

These patches were first developped for linux-3.18-at91 and tested on a
sama5d27 Xplained ultra board, which embeds a Micron n25q128a13 QSPI NOR
flash memory. Then the series was adapted for mainline.

Cyrille Pitchen (5):
  mtd: spi-nor: notify (Q)SPI controller about protocol change
  Documentation: mtd: add a DT property to set the number of dummy
    cycles
  mtd: spi-nor: allow to tune the number of dummy cycles
  Documentation: atmel-quadspi: add binding file for Atmel QSPI driver
  mtd: atmel-quadspi: add driver for Atmel QSPI controller

 .../devicetree/bindings/mtd/atmel-quadspi.txt      |  29 +
 .../devicetree/bindings/mtd/jedec,spi-nor.txt      |   6 +
 drivers/mtd/spi-nor/Kconfig                        |   7 +
 drivers/mtd/spi-nor/Makefile                       |   1 +
 drivers/mtd/spi-nor/atmel-quadspi.c                | 859 +++++++++++++++++++++
 drivers/mtd/spi-nor/spi-nor.c                      | 123 ++-
 include/linux/mtd/spi-nor.h                        |  15 +
 7 files changed, 1021 insertions(+), 19 deletions(-)
 create mode 100644 Documentation/devicetree/bindings/mtd/atmel-quadspi.txt
 create mode 100644 drivers/mtd/spi-nor/atmel-quadspi.c

-- 
1.8.2.2



From holler at ahsoftware.de  Wed Aug 26 05:28:18 2015
From: holler at ahsoftware.de (Alexander Holler)
Date: Wed, 26 Aug 2015 14:28:18 +0200
Subject: [PATCH 06/16] deps: deterministic driver initialization sequence
 based on dependencies from the DT
In-Reply-To: <1440592108-3740-1-git-send-email-holler@ahsoftware.de>
References: <1440592108-3740-1-git-send-email-holler@ahsoftware.de>
Message-ID: <1440592108-3740-7-git-send-email-holler@ahsoftware.de>

Use annotated initcalls along with dependencies found in the DT to sort
the initialization of drivers.

This makes stuff like in-driver hacks (e.g. omap), bruteforce
trial-and-error (deferred probe calls which are killing error messages)
and similar workarounds to circumvent the limited level based
driver initialization sequence unnecessary.

If enabled, this changes the driver initialization sequence as
described in the following table.

old (level based)	new (ordered, in parts)
-------------------------------------------------------------
early			early
pure (0)		pure (0)
core (1, 1s)		core (1, 1s)
postcore (2, 2s)	postcore (2, 2s)
arch (3, 3s)		arch (3, 3s)
subsys (4. 4s)		subsys (4, 4s)
fs (5, 5s)		fs (5, 5s)
rootfs			rootfs
device (6. 6s)		annotated initcalls (ordered by DT)
			annotated initcalls (not found in DT)
			device (6. 6s)
late (7, 7s)		late (7, 7s)

To use this feature new binary DT blobs which are including dependencies
(type information for phandles) have to be used and most drivers found
in the DT should have been annotated.

Signed-off-by: Alexander Holler <holler at ahsoftware.de>
---
 drivers/of/Kconfig              |  12 ++
 drivers/of/Makefile             |   1 +
 drivers/of/of_dependencies.c    | 410 ++++++++++++++++++++++++++++++++++++++++
 include/linux/of_dependencies.h |  20 ++
 init/main.c                     |  11 +-
 5 files changed, 453 insertions(+), 1 deletion(-)
 create mode 100644 drivers/of/of_dependencies.c
 create mode 100644 include/linux/of_dependencies.h

diff --git a/drivers/of/Kconfig b/drivers/of/Kconfig
index 59bb855..9bf6c73 100644
--- a/drivers/of/Kconfig
+++ b/drivers/of/Kconfig
@@ -102,4 +102,16 @@ config OF_OVERLAY
 	  While this option is selected automatically when needed, you can
 	  enable it manually to improve device tree unit test coverage.
 
+config OF_DEPENDENCIES
+	bool "Device Tree dependency based initialization order (EXPERIMENTAL)"
+	select ANNOTATED_INITCALLS
+	help
+	  Enables dependency based initialization order of drivers.
+
+	  For correct operation the binary DT blob should have been
+	  populated with properties of type "dependencies" and the
+	  drivers referenced in the DT should have been annotated.
+
+	  If unsure, say N here.
+
 endif # OF
diff --git a/drivers/of/Makefile b/drivers/of/Makefile
index 156c072..05ced0d 100644
--- a/drivers/of/Makefile
+++ b/drivers/of/Makefile
@@ -14,5 +14,6 @@ obj-$(CONFIG_OF_MTD)	+= of_mtd.o
 obj-$(CONFIG_OF_RESERVED_MEM) += of_reserved_mem.o
 obj-$(CONFIG_OF_RESOLVE)  += resolver.o
 obj-$(CONFIG_OF_OVERLAY) += overlay.o
+obj-$(CONFIG_OF_DEPENDENCIES)	+= of_dependencies.o
 
 obj-$(CONFIG_OF_UNITTEST) += unittest-data/
diff --git a/drivers/of/of_dependencies.c b/drivers/of/of_dependencies.c
new file mode 100644
index 0000000..64ed049
--- /dev/null
+++ b/drivers/of/of_dependencies.c
@@ -0,0 +1,410 @@
+/*
+ * Code for building a deterministic initialization order based on dependencies
+ * defined in the device tree.
+ *
+ * Copyright (C) 2014 Alexander Holler <holler at ahsoftware.de>
+ *
+ * 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.
+ */
+
+#include <linux/of_dependencies.h>
+
+#define MAX_DT_NODES 1000 /* maximum number of vertices */
+#define MAX_EDGES (MAX_DT_NODES*2) /* maximum number of edges (dependencies) */
+
+struct edgenode {
+	uint32_t y; /* phandle */
+	struct edgenode *next; /* next edge in list */
+};
+
+/*
+ * Vertex numbers do correspond to phandle numbers. That means the graph
+ * does contain as much vertices as the maximum of all phandles.
+ * Or in other words, we assume that for all phandles in the device tree
+ * 0 < phandle < MAX_DT_NODES+1 is true.
+ */
+struct dep_graph {
+	struct edgenode edge_slots[MAX_EDGES]; /* used to avoid kmalloc */
+	struct edgenode *edges[MAX_DT_NODES+1]; /* adjacency info */
+	unsigned nvertices; /* number of vertices in graph */
+	unsigned nedges; /* number of edges in graph */
+	bool processed[MAX_DT_NODES+1]; /* which vertices have been processed */
+	bool include_node[MAX_DT_NODES+1]; /* which nodes to consider */
+	bool discovered[MAX_DT_NODES+1]; /* which vertices have been found */
+	bool finished; /* if true, cut off search immediately */
+};
+static struct dep_graph graph __initdata;
+
+struct init_order {
+	uint32_t max_phandle; /* the max used phandle */
+	uint32_t old_max_phandle; /* used to keep track of added phandles */
+	struct device_node *order[MAX_DT_NODES+1];
+	unsigned count;
+	uint32_t ph_root; /* the phandle of the root */
+};
+static struct init_order order __initdata;
+
+/* Copied from drivers/of/base.c (because it's lockless). */
+static struct property * __init __of_find_property(const struct device_node *np,
+					   const char *name, int *lenp)
+{
+	struct property *pp;
+
+	if (!np)
+		return NULL;
+
+	for (pp = np->properties; pp; pp = pp->next) {
+		if (of_prop_cmp(pp->name, name) == 0) {
+			if (lenp)
+				*lenp = pp->length;
+			break;
+		}
+	}
+
+	return pp;
+}
+
+/* Copied from drivers/of/base.c (because it's lockless). */
+static const void * __init __of_get_property(const struct device_node *np,
+				     const char *name, int *lenp)
+{
+	struct property *pp = __of_find_property(np, name, lenp);
+
+	return pp ? pp->value : NULL;
+}
+
+/* Copied from drivers/of/base.c (because it's lockless). */
+static int __init __of_device_is_available(const struct device_node *device)
+{
+	const char *status;
+	int statlen;
+
+	if (!device)
+		return 0;
+
+	status = __of_get_property(device, "status", &statlen);
+	if (status == NULL)
+		return 1;
+
+	if (statlen > 0) {
+		if (!strcmp(status, "okay") || !strcmp(status, "ok"))
+			return 1;
+	}
+
+	return 0;
+}
+
+/*
+ * x is a dependant of y or in other words
+ * y will be initialized before x.
+ */
+static int __init insert_edge(uint32_t x, uint32_t y)
+{
+	struct edgenode *p; /* temporary pointer */
+
+	if (unlikely(x > MAX_DT_NODES || y > MAX_DT_NODES)) {
+		pr_err("Node found with phandle 0x%x > MAX_DT_NODES (%d)!\n",
+			x > MAX_DT_NODES ? x : y, MAX_DT_NODES);
+		return -EINVAL;
+	}
+	if (unlikely(!x || !y))
+		return 0;
+	if (unlikely(graph.nedges >= MAX_EDGES)) {
+		pr_err("Maximum number of edges (%d) reached!\n", MAX_EDGES);
+		return -EINVAL;
+	}
+	p = &graph.edge_slots[graph.nedges++];
+	graph.include_node[x] = 1;
+	graph.include_node[y] = 1;
+	p->y = y;
+	p->next = graph.edges[x];
+	graph.edges[x] = p; /* insert at head of list */
+
+	graph.nvertices = (x > graph.nvertices) ? x : graph.nvertices;
+	graph.nvertices = (y > graph.nvertices) ? y : graph.nvertices;
+	return 0;
+}
+
+static void __init print_node_name(uint32_t v)
+{
+	struct device_node *node;
+
+	node = of_find_node_by_phandle(v);
+	if (!node) {
+		pr_cont("Node for phandle 0x%x not found", v);
+		return;
+	}
+	if (node->name)
+		pr_cont("%s", node->name);
+	if (node->full_name)
+		pr_cont(" (%s)", node->full_name);
+	of_node_put(node);
+}
+
+/*
+ * I would prefer to use the BGL (Boost Graph Library), but as I can't use it
+ * here (for obvious reasons), the next four functions below are based on
+ * code of Steven Skiena's book 'The Algorithm Design Manual'.
+ */
+
+static void __init process_edge(uint32_t x, uint32_t y)
+{
+	if (unlikely(graph.discovered[y] && !graph.processed[y])) {
+		pr_err("Cycle found 0x%x ", x);
+		print_node_name(x);
+		pr_cont(" <-> 0x%x ", y);
+		print_node_name(y);
+		pr_cont("!\n");
+		graph.finished = 1;
+	}
+}
+
+static void __init process_vertex_late(uint32_t v)
+{
+	struct device_node *node;
+
+	node = of_find_node_by_phandle(v);
+	if (!node) {
+		pr_err("No node for phandle 0x%x not found", v);
+		return;
+	}
+	order.order[order.count++] = node;
+}
+
+static void __init depth_first_search(uint32_t v)
+{
+	struct edgenode *p;
+	uint32_t y; /* successor vertex */
+
+	if (graph.finished)
+		return;
+	graph.discovered[v] = 1;
+	p = graph.edges[v];
+	while (p) {
+		y = p->y;
+		if (!graph.discovered[y]) {
+			process_edge(v, y);
+			depth_first_search(y);
+		} else
+			process_edge(v, y);
+		if (graph.finished)
+			return;
+		p = p->next;
+	}
+	process_vertex_late(v);
+	graph.processed[v] = 1;
+}
+
+static void __init topological_sort(void)
+{
+	unsigned i;
+
+	for (i = 1; i <= graph.nvertices; ++i)
+		if (!graph.discovered[i] && graph.include_node[i])
+			depth_first_search(i);
+}
+
+static int __init add_dep_list(struct device_node *node)
+{
+	const __be32 *list, *list_end;
+	uint32_t ph;
+	int size;
+	int rc = 0;
+	struct device_node *dep;
+
+	list = __of_get_property(node, "dependencies", &size);
+	if (!list || !size || size%sizeof(*list))
+		return 0;
+	list_end = list + size / sizeof(*list);
+	while (list < list_end) {
+		ph = be32_to_cpup(list++);
+		if (unlikely(!ph)) {
+			/* Should never happen */
+			if (node->name)
+				pr_warn("phandle == 0 for %s\n", node->name);
+			continue;
+		}
+		dep = of_find_node_by_phandle(ph);
+		if (unlikely(!dep)) {
+			pr_err("No DT node for dependency with phandle 0x%x found\n",
+				ph);
+			continue;
+		}
+		rc = insert_edge(node->phandle, ph);
+		if (rc)
+			break;
+	}
+
+	return rc;
+}
+
+static int __init add_deps(struct device_node *parent, struct device_node *node)
+{
+	struct device_node *child;
+	int rc = 0;
+
+	if (!__of_device_is_available(node))
+		return 0;
+	if (__of_get_property(node, "compatible", NULL)) {
+		if (!parent->phandle) {
+			if (__of_get_property(parent, "compatible", NULL))
+				parent->phandle = 1 + order.max_phandle++;
+		}
+		if (!node->phandle)
+			node->phandle = 1 + order.max_phandle++;
+		rc = insert_edge(node->phandle, parent->phandle);
+		if (rc)
+			return rc;
+		rc = add_dep_list(node);
+		if (unlikely(rc))
+			return rc;
+		parent = node; /* change the parent only if node is a driver */
+	}
+	for_each_child_of_node(node, child) {
+		rc = add_deps(parent, child);
+		if (unlikely(rc))
+			break;
+	}
+
+	return rc;
+}
+
+static void __init calc_max_phandle(void)
+{
+	struct device_node *np;
+	uint32_t t = 0;
+
+	for_each_of_allnodes(np)
+		if (np->phandle > t)
+			t = np->phandle;
+	order.max_phandle = t;
+}
+
+static bool __init all_compatibles_same(struct device_node *node1,
+					struct device_node *node2)
+{
+	const char *cp1;
+	const char *cp2;
+	unsigned count1 = 0;
+	unsigned count2 = 0;
+	struct property *prop1;
+	struct property *prop2;
+
+	prop1 = __of_find_property(node1, "compatible", NULL);
+	prop2 = __of_find_property(node2, "compatible", NULL);
+	for (cp1 = of_prop_next_string(prop1, NULL); cp1;
+					cp1 = of_prop_next_string(prop1, cp1)) {
+		++count1;
+		for (cp2 = of_prop_next_string(prop2, NULL); cp2;
+					cp2 = of_prop_next_string(prop2, cp2))
+			if (!strcmp(cp1, cp2))
+				break;
+		if (!cp2)
+			return 0;
+	}
+	for (cp2 = of_prop_next_string(prop2, NULL); cp2;
+					cp2 = of_prop_next_string(prop2, cp2))
+		++count2;
+	if (count1 == count2)
+		return 1;
+	return 0;
+}
+
+/*
+ * The order is based on devices but we are calling drivers.
+ * Therefor the order contains some drivers more than once.
+ * Remove the duplicates.
+ */
+static void __init of_init_remove_duplicates(void)
+{
+	unsigned i, j;
+
+	for (i = 1; i < order.count; ++i)
+		for (j = 0; j < i; ++j) {
+			if (all_compatibles_same(order.order[j],
+							order.order[i])) {
+				--order.count;
+				memmove(&order.order[i], &order.order[i+1],
+					(order.count - i) *
+						sizeof(order.order[0]));
+				--i;
+				break;
+			}
+		}
+}
+
+static int __init of_init_build_order(void)
+{
+	int rc = 0;
+	struct device_node *child;
+	struct device_node *root =  of_find_node_by_path("/");
+
+	if (unlikely(!root))
+		return -EINVAL;
+
+	calc_max_phandle();
+	order.old_max_phandle = order.max_phandle;
+
+	for_each_child_of_node(root, child) {
+		rc = add_deps(root, child);
+		if (unlikely(rc))
+			break;
+	}
+
+	order.ph_root = root->phandle;
+
+	of_node_put(root);
+	topological_sort();
+
+	if (graph.finished)
+		return -EINVAL; /* cycle found */
+
+	of_init_remove_duplicates();
+
+	return rc;
+}
+
+static void __init of_init_free_order(void)
+{
+	unsigned i;
+
+	for (i = 0; i < order.count; ++i)
+		of_node_put(order.order[i]);
+	order.count = 0;
+	/* remove_new_phandles(); */
+}
+
+static void __init init_if_matched(struct device_node *node)
+{
+	struct _annotated_initcall *ac;
+
+	ac = __annotated_initcall_start;
+	for (; ac < __annotated_initcall_end; ++ac) {
+		if (ac->initcall && ac->driver->of_match_table)
+			if (of_match_node(ac->driver->of_match_table,
+					 node)) {
+				do_one_initcall(*ac->initcall);
+				ac->initcall = 0;
+			}
+	}
+}
+
+void __init of_init_drivers(void)
+{
+	unsigned i;
+	struct _annotated_initcall *ac;
+
+	if (!of_init_build_order()) {
+		for (i = 0; i < order.count; ++i)
+			init_if_matched(order.order[i]);
+		of_init_free_order();
+	}
+	ac = __annotated_initcall_start;
+	for (; ac < __annotated_initcall_end; ++ac) {
+		if (ac->initcall)
+			do_one_initcall(*ac->initcall);
+	}
+}
diff --git a/include/linux/of_dependencies.h b/include/linux/of_dependencies.h
new file mode 100644
index 0000000..1c8c20a
--- /dev/null
+++ b/include/linux/of_dependencies.h
@@ -0,0 +1,20 @@
+#ifndef _LINUX_OF_DEPENDENCIES_H
+#define _LINUX_OF_DEPENDENCIES_H
+/*
+ * Definitions for building a deterministic initialization order based on
+ * dependencies defined in the device tree.
+ *
+ * Copyright (C) 2014 Alexander Holler <holler at ahsoftware.de>
+ *
+ * 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.
+ */
+
+#include <linux/of_platform.h>
+
+/* Calls annotated initcalls in an ordered way based on dependencies. */
+extern void of_init_drivers(void);
+
+#endif	/* _LINUX_OF_DEPENDENCIES_H */
diff --git a/init/main.c b/init/main.c
index 5650655..532b330 100644
--- a/init/main.c
+++ b/init/main.c
@@ -81,6 +81,7 @@
 #include <linux/integrity.h>
 #include <linux/proc_ns.h>
 #include <linux/io.h>
+#include <linux/of_dependencies.h>
 
 #include <asm/io.h>
 #include <asm/bugs.h>
@@ -863,8 +864,16 @@ static void __init do_initcalls(void)
 {
 	int level;
 
-	for (level = 0; level < ARRAY_SIZE(initcall_levels) - 1; level++)
+	for (level = 0; level < ARRAY_SIZE(initcall_levels) - 3; level++)
 		do_initcall_level(level);
+#ifdef CONFIG_OF_DEPENDENCIES
+	/* call annotated drivers (sorted) */
+	of_init_drivers();
+#endif
+	/* call normal and not annoted drivers (not sorted) */
+	do_initcall_level(level++);
+	/* call late drivers */
+	do_initcall_level(level);
 }
 
 /*
-- 
2.1.0



From cyrille.pitchen at atmel.com  Wed Aug 26 05:30:23 2015
From: cyrille.pitchen at atmel.com (Cyrille Pitchen)
Date: Wed, 26 Aug 2015 14:30:23 +0200
Subject: [PATCH linux-next v5 1/5] mtd: spi-nor: notify (Q)SPI controller
 about protocol change
In-Reply-To: <cover.1440580764.git.cyrille.pitchen@atmel.com>
References: <cover.1440580764.git.cyrille.pitchen@atmel.com>
Message-ID: <464fce12d75a5ba2105456cfd0a385b2d40305ba.1440580764.git.cyrille.pitchen@atmel.com>

Once the Quad SPI mode has been enabled on a Micron flash memory, this
device expects ALL the following commands to use the SPI 4-4-4 protocol.
The (Q)SPI controller needs to be notified about the protocol change so it
can adapt and keep on dialoging with the Micron memory.

Signed-off-by: Cyrille Pitchen <cyrille.pitchen at atmel.com>
Acked-by: Marek Vasut <marex at denx.de>
Acked-by: Bean Huo <beanhuo at micron.com>
---
 drivers/mtd/spi-nor/spi-nor.c | 21 +++++++++++++++++++++
 include/linux/mtd/spi-nor.h   | 13 +++++++++++++
 2 files changed, 34 insertions(+)

diff --git a/drivers/mtd/spi-nor/spi-nor.c b/drivers/mtd/spi-nor/spi-nor.c
index c27d427fead4..c8810313a752 100644
--- a/drivers/mtd/spi-nor/spi-nor.c
+++ b/drivers/mtd/spi-nor/spi-nor.c
@@ -165,6 +165,22 @@ static inline int write_disable(struct spi_nor *nor)
 	return nor->write_reg(nor, SPINOR_OP_WRDI, NULL, 0, 0);
 }
 
+/*
+ * Let the spi-nor framework notify lower layers, especially the driver of the
+ * (Q)SPI controller, about the new protocol to be used. Indeed, once the
+ * spi-nor framework has sent manufacturer specific commands to a memory to
+ * enable its Quad SPI mode, it should immediately after tell the QSPI
+ * controller to use the very same Quad SPI protocol as expected by the memory.
+ */
+static inline int spi_nor_set_protocol(struct spi_nor *nor,
+				       enum spi_protocol proto)
+{
+	if (nor->set_protocol)
+		return nor->set_protocol(nor, proto);
+
+	return 0;
+}
+
 static inline struct spi_nor *mtd_to_spi_nor(struct mtd_info *mtd)
 {
 	return mtd->priv;
@@ -940,6 +956,11 @@ static int micron_quad_enable(struct spi_nor *nor)
 		return ret;
 	}
 
+	/* switch protocol to Quad CMD 4-4-4 */
+	ret = spi_nor_set_protocol(nor, SPI_PROTO_4_4_4);
+	if (ret)
+		return ret;
+
 	ret = spi_nor_wait_till_ready(nor);
 	if (ret)
 		return ret;
diff --git a/include/linux/mtd/spi-nor.h b/include/linux/mtd/spi-nor.h
index e5409524bb0a..1bf6f11310ef 100644
--- a/include/linux/mtd/spi-nor.h
+++ b/include/linux/mtd/spi-nor.h
@@ -87,6 +87,16 @@ enum read_mode {
 	SPI_NOR_QUAD,
 };
 
+enum spi_protocol {
+	SPI_PROTO_1_1_1,	/* SPI */
+	SPI_PROTO_1_1_2,	/* Dual Output */
+	SPI_PROTO_1_1_4,	/* Quad Output */
+	SPI_PROTO_1_2_2,	/* Dual IO */
+	SPI_PROTO_1_4_4,	/* Quad IO */
+	SPI_PROTO_2_2_2,	/* Dual Command */
+	SPI_PROTO_4_4_4,	/* Quad Command */
+};
+
 /**
  * struct spi_nor_xfer_cfg - Structure for defining a Serial Flash transfer
  * @wren:		command for "Write Enable", or 0x00 for not required
@@ -149,6 +159,7 @@ enum spi_nor_option_flags {
  *			read/write/erase/lock/unlock operations
  * @read_xfer:		[OPTIONAL] the read fundamental primitive
  * @write_xfer:		[OPTIONAL] the writefundamental primitive
+ * @set_protocol:	[OPTIONAL] notify about protocol change
  * @read_reg:		[DRIVER-SPECIFIC] read out the register
  * @write_reg:		[DRIVER-SPECIFIC] write data to the register
  * @read:		[DRIVER-SPECIFIC] read data from the SPI NOR
@@ -185,6 +196,8 @@ struct spi_nor {
 	int (*write_reg)(struct spi_nor *nor, u8 opcode, u8 *buf, int len,
 			int write_enable);
 
+	int (*set_protocol)(struct spi_nor *nor, enum spi_protocol proto);
+
 	int (*read)(struct spi_nor *nor, loff_t from,
 			size_t len, size_t *retlen, u_char *read_buf);
 	void (*write)(struct spi_nor *nor, loff_t to,
-- 
1.8.2.2



From holler at ahsoftware.de  Wed Aug 26 05:28:20 2015
From: holler at ahsoftware.de (Alexander Holler)
Date: Wed, 26 Aug 2015 14:28:20 +0200
Subject: [PATCH 08/16] deps: dts: kirkwood: dockstar: add dependency ehci ->
 usb power regulator
In-Reply-To: <1440592108-3740-1-git-send-email-holler@ahsoftware.de>
References: <1440592108-3740-1-git-send-email-holler@ahsoftware.de>
Message-ID: <1440592108-3740-9-git-send-email-holler@ahsoftware.de>

This serves as an example how easy it is to fix an initialization order
if the order depends on the DT. No source code changes will be necessary.

If you look at the dependency graph for the dockstar, you will see that
there is no dependency between ehci and the usb power regulator. This
ends up with the fact that the regulator will be initialized after ehci.

Fix this by adding one dependency to the .dts.

Signed-off-by: Alexander Holler <holler at ahsoftware.de>
---
 arch/arm/boot/dts/kirkwood-dockstar.dts | 4 ++++
 1 file changed, 4 insertions(+)

diff --git a/arch/arm/boot/dts/kirkwood-dockstar.dts b/arch/arm/boot/dts/kirkwood-dockstar.dts
index 8497363..426d8840 100644
--- a/arch/arm/boot/dts/kirkwood-dockstar.dts
+++ b/arch/arm/boot/dts/kirkwood-dockstar.dts
@@ -107,3 +107,7 @@
 		phy-handle = <&ethphy0>;
 	};
 };
+
+&usb0 {
+	dependencies = <&usb_power>;
+};
-- 
2.1.0



From holler at ahsoftware.de  Wed Aug 26 05:28:21 2015
From: holler at ahsoftware.de (Alexander Holler)
Date: Wed, 26 Aug 2015 14:28:21 +0200
Subject: [PATCH 09/16] deps: dts: imx6q: make some remote-endpoints
 non-dependencies
In-Reply-To: <1440592108-3740-1-git-send-email-holler@ahsoftware.de>
References: <1440592108-3740-1-git-send-email-holler@ahsoftware.de>
Message-ID: <1440592108-3740-10-git-send-email-holler@ahsoftware.de>

This is necessary to remove dependency cycles introduced by
'remote-endpoints'.

Signed-off-by: Alexander Holler <holler at ahsoftware.de>
---
 arch/arm/boot/dts/imx6q.dtsi   | 2 ++
 arch/arm/boot/dts/imx6qdl.dtsi | 4 ++++
 2 files changed, 6 insertions(+)

diff --git a/arch/arm/boot/dts/imx6q.dtsi b/arch/arm/boot/dts/imx6q.dtsi
index 399103b..8db7f25 100644
--- a/arch/arm/boot/dts/imx6q.dtsi
+++ b/arch/arm/boot/dts/imx6q.dtsi
@@ -184,6 +184,7 @@
 
 				ipu2_di0_hdmi: endpoint at 1 {
 					remote-endpoint = <&hdmi_mux_2>;
+					no-dependencies = <&hdmi_mux_2>;
 				};
 
 				ipu2_di0_mipi: endpoint at 2 {
@@ -205,6 +206,7 @@
 
 				ipu2_di1_hdmi: endpoint at 1 {
 					remote-endpoint = <&hdmi_mux_3>;
+					no-dependencies = <&hdmi_mux_3>;
 				};
 
 				ipu2_di1_mipi: endpoint at 2 {
diff --git a/arch/arm/boot/dts/imx6qdl.dtsi b/arch/arm/boot/dts/imx6qdl.dtsi
index b57033e..db3d0d0 100644
--- a/arch/arm/boot/dts/imx6qdl.dtsi
+++ b/arch/arm/boot/dts/imx6qdl.dtsi
@@ -1150,10 +1150,12 @@
 
 				ipu1_di0_hdmi: endpoint at 1 {
 					remote-endpoint = <&hdmi_mux_0>;
+					no-dependencies = <&hdmi_mux_0>;
 				};
 
 				ipu1_di0_mipi: endpoint at 2 {
 					remote-endpoint = <&mipi_mux_0>;
+					no-dependencies = <&mipi_mux_0>;
 				};
 
 				ipu1_di0_lvds0: endpoint at 3 {
@@ -1175,10 +1177,12 @@
 
 				ipu1_di1_hdmi: endpoint at 1 {
 					remote-endpoint = <&hdmi_mux_1>;
+					no-dependencies = <&hdmi_mux_1>;
 				};
 
 				ipu1_di1_mipi: endpoint at 2 {
 					remote-endpoint = <&mipi_mux_1>;
+					no-dependencies = <&mipi_mux_1>;
 				};
 
 				ipu1_di1_lvds0: endpoint at 3 {
-- 
2.1.0



From holler at ahsoftware.de  Wed Aug 26 05:28:22 2015
From: holler at ahsoftware.de (Alexander Holler)
Date: Wed, 26 Aug 2015 14:28:22 +0200
Subject: [PATCH 10/16] deps: dts: omap: beagle: make some remote-endpoints
 non-dependencies
In-Reply-To: <1440592108-3740-1-git-send-email-holler@ahsoftware.de>
References: <1440592108-3740-1-git-send-email-holler@ahsoftware.de>
Message-ID: <1440592108-3740-11-git-send-email-holler@ahsoftware.de>

This is necessary to remove dependency cycles introduced by
'remote-endpoints'.

Signed-off-by: Alexander Holler <holler at ahsoftware.de>
---
 arch/arm/boot/dts/omap3-beagle.dts | 4 ++++
 1 file changed, 4 insertions(+)

diff --git a/arch/arm/boot/dts/omap3-beagle.dts b/arch/arm/boot/dts/omap3-beagle.dts
index a547411..78ba39e 100644
--- a/arch/arm/boot/dts/omap3-beagle.dts
+++ b/arch/arm/boot/dts/omap3-beagle.dts
@@ -101,6 +101,7 @@
 
 				tfp410_in: endpoint at 0 {
 					remote-endpoint = <&dpi_out>;
+					no-dependencies = <&dpi_out>;
 				};
 			};
 
@@ -109,6 +110,7 @@
 
 				tfp410_out: endpoint at 0 {
 					remote-endpoint = <&dvi_connector_in>;
+					no-dependencies = <&dvi_connector_in>;
 				};
 			};
 		};
@@ -150,6 +152,7 @@
 			etb_in: endpoint {
 				slave-mode;
 				remote-endpoint = <&etm_out>;
+				no-dependencies = <&etm_out>;
 			};
 		};
 	};
@@ -373,6 +376,7 @@
 	port {
 		venc_out: endpoint {
 			remote-endpoint = <&tv_connector_in>;
+			no-dependencies = <&tv_connector_in>;
 			ti,channels = <2>;
 		};
 	};
-- 
2.1.0



From holler at ahsoftware.de  Wed Aug 26 05:28:24 2015
From: holler at ahsoftware.de (Alexander Holler)
Date: Wed, 26 Aug 2015 14:28:24 +0200
Subject: [PATCH 12/16] deps: WIP: imx: annotate some initcalls
In-Reply-To: <1440592108-3740-1-git-send-email-holler@ahsoftware.de>
References: <1440592108-3740-1-git-send-email-holler@ahsoftware.de>
Message-ID: <1440592108-3740-13-git-send-email-holler@ahsoftware.de>

WIP means Work In Progress.

Change some imx drivers to offer annotated initcalls.

Signed-off-by: Alexander Holler <holler at ahsoftware.de>
---
 arch/arm/mach-imx/gpc.c                   | 2 +-
 arch/arm/mach-imx/mmdc.c                  | 2 +-
 drivers/dma/mxs-dma.c                     | 2 +-
 drivers/gpio/gpio-mxc.c                   | 2 +-
 drivers/i2c/busses/i2c-imx.c              | 2 +-
 drivers/pinctrl/freescale/pinctrl-imx6q.c | 2 +-
 drivers/power/reset/imx-snvs-poweroff.c   | 2 +-
 drivers/regulator/anatop-regulator.c      | 3 ++-
 drivers/tty/serial/imx.c                  | 2 +-
 drivers/usb/phy/phy-mxs-usb.c             | 2 +-
 sound/soc/fsl/imx-audmux.c                | 2 +-
 11 files changed, 12 insertions(+), 11 deletions(-)

diff --git a/arch/arm/mach-imx/gpc.c b/arch/arm/mach-imx/gpc.c
index 8c4467f..3802614 100644
--- a/arch/arm/mach-imx/gpc.c
+++ b/arch/arm/mach-imx/gpc.c
@@ -468,4 +468,4 @@ static int __init imx_pgc_init(void)
 {
 	return platform_driver_register(&imx_gpc_driver);
 }
-subsys_initcall(imx_pgc_init);
+annotated_initcall(subsys, imx_pgc_init, imx_gpc_driver.driver);
diff --git a/arch/arm/mach-imx/mmdc.c b/arch/arm/mach-imx/mmdc.c
index db9621c..cf84c03 100644
--- a/arch/arm/mach-imx/mmdc.c
+++ b/arch/arm/mach-imx/mmdc.c
@@ -87,4 +87,4 @@ static int __init imx_mmdc_init(void)
 {
 	return platform_driver_register(&imx_mmdc_driver);
 }
-postcore_initcall(imx_mmdc_init);
+annotated_initcall(postcore, imx_mmdc_init, imx_mmdc_driver.driver);
diff --git a/drivers/dma/mxs-dma.c b/drivers/dma/mxs-dma.c
index 60de352..5bfa232 100644
--- a/drivers/dma/mxs-dma.c
+++ b/drivers/dma/mxs-dma.c
@@ -884,4 +884,4 @@ static int __init mxs_dma_module_init(void)
 {
 	return platform_driver_probe(&mxs_dma_driver, mxs_dma_probe);
 }
-subsys_initcall(mxs_dma_module_init);
+annotated_initcall(subsys, mxs_dma_module_init, mxs_dma_driver.driver);
diff --git a/drivers/gpio/gpio-mxc.c b/drivers/gpio/gpio-mxc.c
index ec1eb1b..0a22a62 100644
--- a/drivers/gpio/gpio-mxc.c
+++ b/drivers/gpio/gpio-mxc.c
@@ -506,7 +506,7 @@ static int __init gpio_mxc_init(void)
 {
 	return platform_driver_register(&mxc_gpio_driver);
 }
-postcore_initcall(gpio_mxc_init);
+annotated_initcall(postcore, gpio_mxc_init, mxc_gpio_driver.driver);
 
 MODULE_AUTHOR("Freescale Semiconductor, "
 	      "Daniel Mack <danielncaiaq.de>, "
diff --git a/drivers/i2c/busses/i2c-imx.c b/drivers/i2c/busses/i2c-imx.c
index 785aa67..c20d03c 100644
--- a/drivers/i2c/busses/i2c-imx.c
+++ b/drivers/i2c/busses/i2c-imx.c
@@ -1110,7 +1110,7 @@ static int __init i2c_adap_imx_init(void)
 {
 	return platform_driver_register(&i2c_imx_driver);
 }
-subsys_initcall(i2c_adap_imx_init);
+annotated_initcall(subsys, i2c_adap_imx_init, i2c_imx_driver.driver);
 
 static void __exit i2c_adap_imx_exit(void)
 {
diff --git a/drivers/pinctrl/freescale/pinctrl-imx6q.c b/drivers/pinctrl/freescale/pinctrl-imx6q.c
index 4d1fcb8..77a1ffd 100644
--- a/drivers/pinctrl/freescale/pinctrl-imx6q.c
+++ b/drivers/pinctrl/freescale/pinctrl-imx6q.c
@@ -489,7 +489,7 @@ static int __init imx6q_pinctrl_init(void)
 {
 	return platform_driver_register(&imx6q_pinctrl_driver);
 }
-arch_initcall(imx6q_pinctrl_init);
+annotated_initcall(arch, imx6q_pinctrl_init, imx6q_pinctrl_driver.driver);
 
 static void __exit imx6q_pinctrl_exit(void)
 {
diff --git a/drivers/power/reset/imx-snvs-poweroff.c b/drivers/power/reset/imx-snvs-poweroff.c
index ad6ce50..57a06dc 100644
--- a/drivers/power/reset/imx-snvs-poweroff.c
+++ b/drivers/power/reset/imx-snvs-poweroff.c
@@ -63,4 +63,4 @@ static int __init imx_poweroff_init(void)
 {
 	return platform_driver_register(&imx_poweroff_driver);
 }
-device_initcall(imx_poweroff_init);
+annotated_initcall(device, imx_poweroff_init, imx_poweroff_driver.driver);
diff --git a/drivers/regulator/anatop-regulator.c b/drivers/regulator/anatop-regulator.c
index 738adfa..97808da 100644
--- a/drivers/regulator/anatop-regulator.c
+++ b/drivers/regulator/anatop-regulator.c
@@ -331,7 +331,8 @@ static int __init anatop_regulator_init(void)
 {
 	return platform_driver_register(&anatop_regulator_driver);
 }
-postcore_initcall(anatop_regulator_init);
+annotated_initcall(postcore, anatop_regulator_init,
+					anatop_regulator_driver.driver);
 
 static void __exit anatop_regulator_exit(void)
 {
diff --git a/drivers/tty/serial/imx.c b/drivers/tty/serial/imx.c
index 54fdc78..c79e19b 100644
--- a/drivers/tty/serial/imx.c
+++ b/drivers/tty/serial/imx.c
@@ -2024,7 +2024,7 @@ static void __exit imx_serial_exit(void)
 	uart_unregister_driver(&imx_reg);
 }
 
-module_init(imx_serial_init);
+annotated_module_init(imx_serial_init, serial_imx_driver.driver);
 module_exit(imx_serial_exit);
 
 MODULE_AUTHOR("Sascha Hauer");
diff --git a/drivers/usb/phy/phy-mxs-usb.c b/drivers/usb/phy/phy-mxs-usb.c
index 3fcc048..dd2768d 100644
--- a/drivers/usb/phy/phy-mxs-usb.c
+++ b/drivers/usb/phy/phy-mxs-usb.c
@@ -577,7 +577,7 @@ static int __init mxs_phy_module_init(void)
 {
 	return platform_driver_register(&mxs_phy_driver);
 }
-postcore_initcall(mxs_phy_module_init);
+annotated_initcall(postcore, mxs_phy_module_init, mxs_phy_driver.driver);
 
 static void __exit mxs_phy_module_exit(void)
 {
diff --git a/sound/soc/fsl/imx-audmux.c b/sound/soc/fsl/imx-audmux.c
index fc57da3..19fd729 100644
--- a/sound/soc/fsl/imx-audmux.c
+++ b/sound/soc/fsl/imx-audmux.c
@@ -364,7 +364,7 @@ static int __init imx_audmux_init(void)
 {
 	return platform_driver_register(&imx_audmux_driver);
 }
-subsys_initcall(imx_audmux_init);
+annotated_initcall(subsys, imx_audmux_init, imx_audmux_driver.driver);
 
 static void __exit imx_audmux_exit(void)
 {
-- 
2.1.0



From holler at ahsoftware.de  Wed Aug 26 05:28:26 2015
From: holler at ahsoftware.de (Alexander Holler)
Date: Wed, 26 Aug 2015 14:28:26 +0200
Subject: [PATCH 14/16] deps: WIP: kirkwood: annotate some initcalls
In-Reply-To: <1440592108-3740-1-git-send-email-holler@ahsoftware.de>
References: <1440592108-3740-1-git-send-email-holler@ahsoftware.de>
Message-ID: <1440592108-3740-15-git-send-email-holler@ahsoftware.de>

WIP means Work In Progress.

Change some kirkwood drivers to offer annotated initcalls.

Signed-off-by: Alexander Holler <holler at ahsoftware.de>
---
 drivers/dma/mv_xor.c                       | 2 +-
 drivers/net/ethernet/marvell/mv643xx_eth.c | 3 ++-
 drivers/usb/host/ehci-orion.c              | 2 +-
 3 files changed, 4 insertions(+), 3 deletions(-)

diff --git a/drivers/dma/mv_xor.c b/drivers/dma/mv_xor.c
index f1325f6..e766ab2 100644
--- a/drivers/dma/mv_xor.c
+++ b/drivers/dma/mv_xor.c
@@ -1295,7 +1295,7 @@ static int __init mv_xor_init(void)
 {
 	return platform_driver_register(&mv_xor_driver);
 }
-module_init(mv_xor_init);
+annotated_module_init(mv_xor_init, mv_xor_driver.driver);
 
 /* it's currently unsafe to unload this module */
 #if 0
diff --git a/drivers/net/ethernet/marvell/mv643xx_eth.c b/drivers/net/ethernet/marvell/mv643xx_eth.c
index d52639b..5eec4d8 100644
--- a/drivers/net/ethernet/marvell/mv643xx_eth.c
+++ b/drivers/net/ethernet/marvell/mv643xx_eth.c
@@ -3239,7 +3239,8 @@ static int __init mv643xx_eth_init_module(void)
 
 	return rc;
 }
-module_init(mv643xx_eth_init_module);
+annotated_module_init(mv643xx_eth_init_module,
+		      mv643xx_eth_shared_driver.driver);
 
 static void __exit mv643xx_eth_cleanup_module(void)
 {
diff --git a/drivers/usb/host/ehci-orion.c b/drivers/usb/host/ehci-orion.c
index bfcbb9a..28f8793 100644
--- a/drivers/usb/host/ehci-orion.c
+++ b/drivers/usb/host/ehci-orion.c
@@ -333,7 +333,7 @@ static int __init ehci_orion_init(void)
 	ehci_init_driver(&ehci_orion_hc_driver, &orion_overrides);
 	return platform_driver_register(&ehci_orion_driver);
 }
-module_init(ehci_orion_init);
+annotated_module_init(ehci_orion_init, ehci_orion_driver.driver);
 
 static void __exit ehci_orion_cleanup(void)
 {
-- 
2.1.0



From holler at ahsoftware.de  Wed Aug 26 05:28:28 2015
From: holler at ahsoftware.de (Alexander Holler)
Date: Wed, 26 Aug 2015 14:28:28 +0200
Subject: [PATCH 16/16] phy: phy-core: fix initcall level
In-Reply-To: <1440592108-3740-1-git-send-email-holler@ahsoftware.de>
References: <1440592108-3740-1-git-send-email-holler@ahsoftware.de>
Message-ID: <1440592108-3740-17-git-send-email-holler@ahsoftware.de>

The phy-core has to be initialized before other dependent usb-drivers,
otherwise a crash might occur.

Currently phy_core_init() is called in the initcall-level device, which is
the same level where most usb-drivers will end up. By luck this seemed to
have been called most of the time before other usb-drivers without having
been explicitly enforced. But if phy_core_init() is not called before a
dependent driver, a null-pointer exception might occur (e.g. because the
phy device class isn't registered).

To fix this, phy_core_init() is moved to the initcall-level fs (right
before the standard initcall level device).

Signed-off-by: Alexander Holler <holler at ahsoftware.de>
---
 drivers/phy/phy-core.c | 2 +-
 1 file changed, 1 insertion(+), 1 deletion(-)

diff --git a/drivers/phy/phy-core.c b/drivers/phy/phy-core.c
index fc48fac..4945029 100644
--- a/drivers/phy/phy-core.c
+++ b/drivers/phy/phy-core.c
@@ -930,7 +930,7 @@ static int __init phy_core_init(void)
 
 	return 0;
 }
-module_init(phy_core_init);
+fs_initcall_sync(phy_core_init);
 
 static void __exit phy_core_exit(void)
 {
-- 
2.1.0



From holler at ahsoftware.de  Wed Aug 26 05:28:27 2015
From: holler at ahsoftware.de (Alexander Holler)
Date: Wed, 26 Aug 2015 14:28:27 +0200
Subject: [PATCH 15/16] mtd: mtdcore: fix initcall level
In-Reply-To: <1440592108-3740-1-git-send-email-holler@ahsoftware.de>
References: <1440592108-3740-1-git-send-email-holler@ahsoftware.de>
Message-ID: <1440592108-3740-16-git-send-email-holler@ahsoftware.de>

The mtd-core has to be initialized before other dependent mtd-drivers,
otherwise a crash might occur.

Currently mtd_init() is called in the initcall-level device, which is the
same level where most mtd-drivers will end up. By luck this seemed to have
been called most of the time before other mtd-drivers without having been
explicitly enforced. But if mtd_init() is not called before a dependent
driver, a null-pointer exception might occur (e.g. because the mtd device
class isn't registered).

To fix this, mtd-init() is moved to the initcall-level fs (right before
the standard initcall level device).

Signed-off-by: Alexander Holler <holler at ahsoftware.de>
---
 drivers/mtd/mtdcore.c | 2 +-
 1 file changed, 1 insertion(+), 1 deletion(-)

diff --git a/drivers/mtd/mtdcore.c b/drivers/mtd/mtdcore.c
index 8bbbb75..fa8e6452 100644
--- a/drivers/mtd/mtdcore.c
+++ b/drivers/mtd/mtdcore.c
@@ -1303,7 +1303,7 @@ static void __exit cleanup_mtd(void)
 	bdi_destroy(&mtd_bdi);
 }
 
-module_init(init_mtd);
+fs_initcall_sync(init_mtd);
 module_exit(cleanup_mtd);
 
 MODULE_LICENSE("GPL");
-- 
2.1.0



From cyrille.pitchen at atmel.com  Wed Aug 26 05:30:27 2015
From: cyrille.pitchen at atmel.com (Cyrille Pitchen)
Date: Wed, 26 Aug 2015 14:30:27 +0200
Subject: [PATCH linux-next v5 5/5] mtd: atmel-quadspi: add driver for Atmel
 QSPI controller
In-Reply-To: <cover.1440580764.git.cyrille.pitchen@atmel.com>
References: <cover.1440580764.git.cyrille.pitchen@atmel.com>
Message-ID: <a4f28764a2561106a91d1896e3ec21d0a88f2037.1440580764.git.cyrille.pitchen@atmel.com>

This driver add support to the new Atmel QSPI controller embedded into
sama5d2x SoCs. It expects a NOR memory to be connected to the QSPI
controller.

Signed-off-by: Cyrille Pitchen <cyrille.pitchen at atmel.com>
Acked-by: Nicolas Ferre <nicolas.ferre at atmel.com>
---
 drivers/mtd/spi-nor/Kconfig         |   7 +
 drivers/mtd/spi-nor/Makefile        |   1 +
 drivers/mtd/spi-nor/atmel-quadspi.c | 859 ++++++++++++++++++++++++++++++++++++
 3 files changed, 867 insertions(+)
 create mode 100644 drivers/mtd/spi-nor/atmel-quadspi.c

diff --git a/drivers/mtd/spi-nor/Kconfig b/drivers/mtd/spi-nor/Kconfig
index 89bf4c1faa2b..7a3d55429550 100644
--- a/drivers/mtd/spi-nor/Kconfig
+++ b/drivers/mtd/spi-nor/Kconfig
@@ -29,6 +29,13 @@ config SPI_FSL_QUADSPI
 	  This controller does not support generic SPI. It only supports
 	  SPI NOR.
 
+config SPI_ATMEL_QUADSPI
+	tristate "Atmel Quad SPI Controller"
+	depends on OF && HAS_DMA && (ARCH_AT91 || COMPILE_TEST)
+	help
+	  This enables support for the Quad SPI controller in master mode.
+	  We only connect the NOR to this controller now.
+
 config SPI_NXP_SPIFI
 	tristate "NXP SPI Flash Interface (SPIFI)"
 	depends on OF && (ARCH_LPC18XX || COMPILE_TEST)
diff --git a/drivers/mtd/spi-nor/Makefile b/drivers/mtd/spi-nor/Makefile
index e53333ef8582..f5d23d7379bb 100644
--- a/drivers/mtd/spi-nor/Makefile
+++ b/drivers/mtd/spi-nor/Makefile
@@ -1,3 +1,4 @@
 obj-$(CONFIG_MTD_SPI_NOR)	+= spi-nor.o
 obj-$(CONFIG_SPI_FSL_QUADSPI)	+= fsl-quadspi.o
+obj-$(CONFIG_SPI_ATMEL_QUADSPI)	+= atmel-quadspi.o
 obj-$(CONFIG_SPI_NXP_SPIFI)	+= nxp-spifi.o
diff --git a/drivers/mtd/spi-nor/atmel-quadspi.c b/drivers/mtd/spi-nor/atmel-quadspi.c
new file mode 100644
index 000000000000..003cdf00e8b1
--- /dev/null
+++ b/drivers/mtd/spi-nor/atmel-quadspi.c
@@ -0,0 +1,859 @@
+/*
+ * Driver for Atmel QSPI Controller
+ *
+ * Copyright (C) 2015 Atmel Corporation
+ *
+ * Author: Cyrille Pitchen <cyrille.pitchen at atmel.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.
+ *
+ * You should have received a copy of the GNU General Public License along with
+ * this program.  If not, see <http://www.gnu.org/licenses/>.
+ *
+ * This driver is based on drivers/mtd/spi-nor/fsl-quadspi.c from Freescale.
+ */
+
+#include <linux/kernel.h>
+#include <linux/clk.h>
+#include <linux/module.h>
+#include <linux/platform_device.h>
+#include <linux/delay.h>
+#include <linux/dma-mapping.h>
+#include <linux/dmaengine.h>
+#include <linux/err.h>
+#include <linux/interrupt.h>
+#include <linux/mtd/mtd.h>
+#include <linux/mtd/partitions.h>
+#include <linux/mtd/spi-nor.h>
+#include <linux/platform_data/atmel.h>
+#include <linux/platform_data/dma-atmel.h>
+#include <linux/of.h>
+
+#include <linux/io.h>
+#include <linux/gpio.h>
+#include <linux/pinctrl/consumer.h>
+
+/* QSPI register offsets */
+#define QSPI_CR      0x0000  /* Control Register */
+#define QSPI_MR      0x0004  /* Mode Register */
+#define QSPI_RD      0x0008  /* Receive Data Register */
+#define QSPI_TD      0x000c  /* Transmit Data Register */
+#define QSPI_SR      0x0010  /* Status Register */
+#define QSPI_IER     0x0014  /* Interrupt Enable Register */
+#define QSPI_IDR     0x0018  /* Interrupt Disable Register */
+#define QSPI_IMR     0x001c  /* Interrupt Mask Register */
+#define QSPI_SCR     0x0020  /* Serial Clock Register */
+
+#define QSPI_IAR     0x0030  /* Instruction Address Register */
+#define QSPI_ICR     0x0034  /* Instruction Code Register */
+#define QSPI_IFR     0x0038  /* Instruction Frame Register */
+
+#define QSPI_SMR     0x0040  /* Scrambling Mode Register */
+#define QSPI_SKR     0x0044  /* Scrambling Key Register */
+
+#define QSPI_WPMR    0x00E4  /* Write Protection Mode Register */
+#define QSPI_WPSR    0x00E8  /* Write Protection Status Register */
+
+#define QSPI_VERSION 0x00FC  /* Version Register */
+
+
+/* Bitfields in QSPI_CR (Control Register) */
+#define QSPI_CR_QSPIEN                  BIT(0)
+#define QSPI_CR_QSPIDIS                 BIT(1)
+#define QSPI_CR_SWRST                   BIT(7)
+#define QSPI_CR_LASTXFER                BIT(24)
+
+/* Bitfields in QSPI_MR (Mode Register) */
+#define QSPI_MR_SSM                     BIT(0)
+#define QSPI_MR_LLB                     BIT(1)
+#define QSPI_MR_WDRBT                   BIT(2)
+#define QSPI_MR_SMRM                    BIT(3)
+#define QSPI_MR_CSMODE_MASK             GENMASK(5, 4)
+#define QSPI_MR_CSMODE_NOT_RELOADED     (0 << 4)
+#define QSPI_MR_CSMODE_LASTXFER         (1 << 4)
+#define QSPI_MR_CSMODE_SYSTEMATICALLY   (2 << 4)
+#define QSPI_MR_NBBITS_MASK             GENMASK(11, 8)
+#define QSPI_MR_NBBITS(n)               ((((n) - 8) << 8) & QSPI_MR_NBBITS_MASK)
+#define QSPI_MR_DLYBCT_MASK             GENMASK(23, 16)
+#define QSPI_MR_DLYBCT(n)               (((n) << 16) & QSPI_MR_DLYBCT_MASK)
+#define QSPI_MR_DLYCS_MASK              GENMASK(31, 24)
+#define QSPI_MR_DLYCS(n)                (((n) << 24) & QSPI_MR_DLYCS_MASK)
+
+/* Bitfields in QSPI_SR/QSPI_IER/QSPI_IDR/QSPI_IMR  */
+#define QSPI_SR_RDRF                    BIT(0)
+#define QSPI_SR_TDRE                    BIT(1)
+#define QSPI_SR_TXEMPTY                 BIT(2)
+#define QSPI_SR_OVRES                   BIT(3)
+#define QSPI_SR_CSR                     BIT(8)
+#define QSPI_SR_CSS                     BIT(9)
+#define QSPI_SR_INSTRE                  BIT(10)
+#define QSPI_SR_QSPIENS                 BIT(24)
+
+/* Bitfields in QSPI_SCR (Serial Clock Register) */
+#define QSPI_SCR_CPOL                   BIT(0)
+#define QSPI_SCR_CPHA                   BIT(1)
+#define QSPI_SCR_SCBR_MASK              GENMASK(15, 8)
+#define QSPI_SCR_SCBR(n)                (((n) << 8) & QSPI_SCR_SCBR_MASK)
+#define QSPI_SCR_DLYBS_MASK             GENMASK(23, 16)
+#define QSPI_SCR_DLYBS(n)               (((n) << 16) & QSPI_SCR_DLYBS_MASK)
+
+/* Bitfields in QSPI_ICR (Instruction Code Register) */
+#define QSPI_ICR_INST_MASK              GENMASK(7, 0)
+#define QSPI_ICR_INST(inst)             (((inst) << 0) & QSPI_ICR_INST_MASK)
+#define QSPI_ICR_OPT_MASK               GENMASK(23, 16)
+#define QSPI_ICR_OPT(opt)               (((opt) << 16) & QSPI_ICR_OPT_MASK)
+
+/* Bitfields in QSPI_IFR (Instruction Frame Register) */
+#define QSPI_IFR_WIDTH_MASK             GENMASK(2, 0)
+#define QSPI_IFR_WIDTH_SINGLE_BIT_SPI   (0 << 0)
+#define QSPI_IFR_WIDTH_DUAL_OUTPUT      (1 << 0)
+#define QSPI_IFR_WIDTH_QUAD_OUTPUT      (2 << 0)
+#define QSPI_IFR_WIDTH_DUAL_IO          (3 << 0)
+#define QSPI_IFR_WIDTH_QUAD_IO          (4 << 0)
+#define QSPI_IFR_WIDTH_DUAL_CMD         (5 << 0)
+#define QSPI_IFR_WIDTH_QUAD_CMD         (6 << 0)
+#define QSPI_IFR_INSTEN                 BIT(4)
+#define QSPI_IFR_ADDREN                 BIT(5)
+#define QSPI_IFR_OPTEN                  BIT(6)
+#define QSPI_IFR_DATAEN                 BIT(7)
+#define QSPI_IFR_OPTL_MASK              GENMASK(9, 8)
+#define QSPI_IFR_OPTL_1BIT              (0 << 8)
+#define QSPI_IFR_OPTL_2BIT              (1 << 8)
+#define QSPI_IFR_OPTL_4BIT              (2 << 8)
+#define QSPI_IFR_OPTL_8BIT              (3 << 8)
+#define QSPI_IFR_ADDRL                  BIT(10)
+#define QSPI_IFR_TFRTYP_MASK            GENMASK(13, 12)
+#define QSPI_IFR_TFRTYP_TRSFR_READ      (0 << 12)
+#define QSPI_IFR_TFRTYP_TRSFR_READ_MEM  (1 << 12)
+#define QSPI_IFR_TFRTYP_TRSFR_WRITE     (2 << 12)
+#define QSPI_IFR_TFRTYP_TRSFR_WRITE_MEM (3 << 13)
+#define QSPI_IFR_CRM                    BIT(14)
+#define QSPI_IFR_NBDUM_MASK             GENMASK(20, 16)
+#define QSPI_IFR_NBDUM(n)               (((n) << 16) & QSPI_IFR_NBDUM_MASK)
+
+/* Bitfields in QSPI_SMR (Scrambling Mode Register) */
+#define QSPI_SMR_SCREN                  BIT(0)
+#define QSPI_SMR_RVDIS                  BIT(1)
+
+/* Bitfields in QSPI_WPMR (Write Protection Mode Register) */
+#define QSPI_WPMR_WPEN                  BIT(0)
+#define QSPI_WPMR_WPKEY_MASK            GENMASK(31, 8)
+#define QSPI_WPMR_WPKEY(wpkey)          (((wpkey) << 8) & QSPI_WPMR_WPKEY_MASK)
+
+/* Bitfields in QSPI_WPSR (Write Protection Status Register) */
+#define QSPI_WPSR_WPVS                  BIT(0)
+#define QSPI_WPSR_WPVSRC_MASK           GENMASK(15, 8)
+#define QSPI_WPSR_WPVSRC(src)           (((src) << 8) & QSPI_WPSR_WPVSRC)
+
+
+struct atmel_qspi {
+	void __iomem		*regs;
+	void __iomem		*mem;
+	dma_addr_t		phys_addr;
+	struct dma_chan		*chan;
+	struct clk		*clk;
+	struct platform_device	*pdev;
+	u32			ifr_width;
+	u32			pending;
+
+	struct mtd_info		mtd;
+	struct spi_nor		nor;
+	u32			clk_rate;
+	struct completion	cmd_completion;
+	struct completion	dma_completion;
+
+#ifdef DEBUG
+	u8			last_instruction;
+#endif
+};
+
+struct atmel_qspi_command {
+	u32	ifr_tfrtyp;
+	union {
+		struct {
+			u32	instruction:1;
+			u32	address:3;
+			u32	mode:1;
+			u32	dummy:1;
+			u32	data:1;
+			u32	dma:1;
+			u32	reserved:24;
+		}		bits;
+		u32	word;
+	}	enable;
+	u8	instruction;
+	u8	mode;
+	u8	num_mode_cycles;
+	u8	num_dummy_cycles;
+	u32	address;
+
+	size_t		buf_len;
+	const void	*tx_buf;
+	void		*rx_buf;
+};
+
+/* Register access functions */
+static inline u32 qspi_readl(struct atmel_qspi *aq, u32 reg)
+{
+	return readl_relaxed(aq->regs + reg);
+}
+
+static inline void qspi_writel(struct atmel_qspi *aq, u32 reg, u32 value)
+{
+	writel_relaxed(value, aq->regs + reg);
+}
+
+
+#define QSPI_DMA_THRESHOLD	32
+
+static void atmel_qspi_dma_callback(void *arg)
+{
+	struct completion *dma_completion = arg;
+
+	complete(dma_completion);
+}
+
+static int atmel_qspi_run_dma_transfer(struct atmel_qspi *aq,
+				       const struct atmel_qspi_command *cmd)
+{
+	u32 offset = (cmd->enable.bits.address) ? cmd->address : 0;
+	struct dma_chan *chan = aq->chan;
+	struct device *dev = &aq->pdev->dev;
+	enum dma_data_direction direction;
+	dma_addr_t phys_addr, dst, src;
+	struct dma_async_tx_descriptor *desc;
+	dma_cookie_t cookie;
+	int err = 0;
+
+	if (cmd->tx_buf) {
+		direction = DMA_TO_DEVICE;
+		phys_addr = dma_map_single(dev, (void *)cmd->tx_buf,
+					   cmd->buf_len, direction);
+		src = phys_addr;
+		dst = aq->phys_addr + offset;
+	} else {
+		direction = DMA_FROM_DEVICE;
+		phys_addr = dma_map_single(dev, (void *)cmd->rx_buf,
+					   cmd->buf_len, direction);
+		src = aq->phys_addr + offset;
+		dst = phys_addr;
+	}
+	if (dma_mapping_error(dev, phys_addr))
+		return -ENOMEM;
+
+	desc = chan->device->device_prep_dma_memcpy(chan, dst, src,
+						    cmd->buf_len,
+						    DMA_PREP_INTERRUPT);
+	if (!desc) {
+		err = -ENOMEM;
+		goto unmap_single;
+	}
+
+	reinit_completion(&aq->dma_completion);
+	desc->callback = atmel_qspi_dma_callback;
+	desc->callback_param = &aq->dma_completion;
+	cookie = dmaengine_submit(desc);
+	err = dma_submit_error(cookie);
+	if (err)
+		goto unmap_single;
+	dma_async_issue_pending(chan);
+
+	if (!wait_for_completion_timeout(&aq->dma_completion,
+					 msecs_to_jiffies(1000)))
+		err = -ETIMEDOUT;
+
+	if (dma_async_is_tx_complete(chan, cookie, NULL, NULL) != DMA_COMPLETE)
+		err = -ETIMEDOUT;
+
+	if (err)
+		dmaengine_terminate_all(chan);
+unmap_single:
+	dma_unmap_single(dev, phys_addr, cmd->buf_len, direction);
+
+	return err;
+}
+
+static int atmel_qspi_run_transfer(struct atmel_qspi *aq,
+				   const struct atmel_qspi_command *cmd)
+{
+	void __iomem *ahb_mem;
+
+	/* First try a DMA transfer */
+	if (aq->chan && cmd->enable.bits.dma &&
+	    cmd->buf_len >= QSPI_DMA_THRESHOLD)
+		return atmel_qspi_run_dma_transfer(aq, cmd);
+
+	/* Then fallback to a PIO transfer */
+	ahb_mem = aq->mem;
+	if (cmd->enable.bits.address)
+		ahb_mem += cmd->address;
+	if (cmd->tx_buf)
+		memcpy_toio(ahb_mem, cmd->tx_buf, cmd->buf_len);
+	else
+		memcpy_fromio(cmd->rx_buf, ahb_mem, cmd->buf_len);
+
+	return 0;
+}
+
+#ifdef DEBUG
+static void atmel_qspi_debug_command(struct atmel_qspi *aq,
+				     const struct atmel_qspi_command *cmd)
+{
+	u8 cmd_buf[SPI_NOR_MAX_CMD_SIZE];
+	size_t len = 0;
+	int i;
+
+	if (cmd->enable.bits.instruction) {
+		if (aq->last_instruction == cmd->instruction)
+			return;
+		aq->last_instruction = cmd->instruction;
+	}
+
+	if (cmd->enable.bits.instruction)
+		cmd_buf[len++] = cmd->instruction;
+
+	for (i = cmd->enable.bits.address-1; i >= 0; --i)
+		cmd_buf[len++] = (cmd->address >> (i << 3)) & 0xff;
+
+	if (cmd->enable.bits.mode)
+		cmd_buf[len++] = cmd->mode;
+
+	if (cmd->enable.bits.dummy) {
+		int num = cmd->num_dummy_cycles;
+
+		switch (aq->ifr_width) {
+		case QSPI_IFR_WIDTH_SINGLE_BIT_SPI:
+		case QSPI_IFR_WIDTH_DUAL_OUTPUT:
+		case QSPI_IFR_WIDTH_QUAD_OUTPUT:
+			num >>= 3;
+			break;
+		case QSPI_IFR_WIDTH_DUAL_IO:
+		case QSPI_IFR_WIDTH_DUAL_CMD:
+			num >>= 2;
+			break;
+		case QSPI_IFR_WIDTH_QUAD_IO:
+		case QSPI_IFR_WIDTH_QUAD_CMD:
+			num >>= 1;
+			break;
+		default:
+			return;
+		}
+
+		for (i = 0; i < num; ++i)
+			cmd_buf[len++] = 0;
+	}
+
+	/* Dump the SPI command */
+	print_hex_dump(KERN_DEBUG, "qspi cmd: ", DUMP_PREFIX_NONE,
+		       32, 1, cmd_buf, len, false);
+
+#ifdef VERBOSE_DEBUG
+	/* If verbose debug is enabled, also dump the TX data */
+	if (cmd->enable.bits.data && cmd->tx_buf)
+		print_hex_dump(KERN_DEBUG, "qspi tx : ", DUMP_PREFIX_NONE,
+			       32, 1, cmd->tx_buf, cmd->buf_len, false);
+#endif
+}
+#else
+#define atmel_qspi_debug_command(aq, cmd)
+#endif
+
+static int atmel_qspi_run_command(struct atmel_qspi *aq,
+				  const struct atmel_qspi_command *cmd)
+{
+	u32 iar, icr, ifr, sr;
+	int err = 0;
+
+	iar = 0;
+	icr = 0;
+	ifr = aq->ifr_width | cmd->ifr_tfrtyp;
+
+	/* Compute instruction parameters */
+	if (cmd->enable.bits.instruction) {
+		icr |= QSPI_ICR_INST(cmd->instruction);
+		ifr |= QSPI_IFR_INSTEN;
+	}
+
+	/* Compute address parameters */
+	switch (cmd->enable.bits.address) {
+	case 4:
+		ifr |= QSPI_IFR_ADDRL;
+		/* fall through to the 24bit (3 byte) address case. */
+	case 3:
+		iar = (cmd->enable.bits.data) ? 0 : cmd->address;
+		ifr |= QSPI_IFR_ADDREN;
+		break;
+	case 0:
+		break;
+	default:
+		return -EINVAL;
+	}
+
+	/* Compute option parameters */
+	if (cmd->enable.bits.mode && cmd->num_mode_cycles) {
+		u32 mode_cycle_bits, mode_bits;
+
+		icr |= QSPI_ICR_OPT(cmd->mode);
+		ifr |= QSPI_IFR_OPTEN;
+
+		switch (ifr & QSPI_IFR_WIDTH_MASK) {
+		case QSPI_IFR_WIDTH_SINGLE_BIT_SPI:
+		case QSPI_IFR_WIDTH_DUAL_OUTPUT:
+		case QSPI_IFR_WIDTH_QUAD_OUTPUT:
+			mode_cycle_bits = 1;
+			break;
+		case QSPI_IFR_WIDTH_DUAL_IO:
+		case QSPI_IFR_WIDTH_DUAL_CMD:
+			mode_cycle_bits = 2;
+			break;
+		case QSPI_IFR_WIDTH_QUAD_IO:
+		case QSPI_IFR_WIDTH_QUAD_CMD:
+			mode_cycle_bits = 4;
+			break;
+		default:
+			return -EINVAL;
+		}
+
+		mode_bits = cmd->num_mode_cycles * mode_cycle_bits;
+		switch (mode_bits) {
+		case 1:
+			ifr |= QSPI_IFR_OPTL_1BIT;
+			break;
+
+		case 2:
+			ifr |= QSPI_IFR_OPTL_2BIT;
+			break;
+
+		case 4:
+			ifr |= QSPI_IFR_OPTL_4BIT;
+			break;
+
+		case 8:
+			ifr |= QSPI_IFR_OPTL_8BIT;
+			break;
+
+		default:
+			return -EINVAL;
+		}
+	}
+
+	/* Set number of dummy cycles */
+	if (cmd->enable.bits.dummy)
+		ifr |= QSPI_IFR_NBDUM(cmd->num_dummy_cycles);
+
+	/* Set data enable */
+	if (cmd->enable.bits.data) {
+		ifr |= QSPI_IFR_DATAEN;
+
+		/* Special case for Continuous Read Mode */
+		if (!cmd->tx_buf && !cmd->rx_buf)
+			ifr |= QSPI_IFR_CRM;
+	}
+
+	/* Set QSPI Instruction Frame registers */
+	atmel_qspi_debug_command(aq, cmd);
+	qspi_writel(aq, QSPI_IAR, iar);
+	qspi_writel(aq, QSPI_ICR, icr);
+	qspi_writel(aq, QSPI_IFR, ifr);
+
+	/* Skip to the final steps if there is no data */
+	if (!cmd->enable.bits.data)
+		goto no_data;
+
+	/* Dummy read of QSPI_IFR to synchronize APB and AHB accesses */
+	(void)qspi_readl(aq, QSPI_IFR);
+
+	/* Stop here for continuous read */
+	if (!cmd->tx_buf && !cmd->rx_buf)
+		return 0;
+	/* Send/Receive data */
+	err = atmel_qspi_run_transfer(aq, cmd);
+
+	/* Release the chip-select */
+	qspi_writel(aq, QSPI_CR, QSPI_CR_LASTXFER);
+
+	if (err)
+		return err;
+
+#if defined(DEBUG) && defined(VERBOSE_DEBUG)
+	/*
+	 * If verbose debug is enabled, also dump the RX data in addition to
+	 * the SPI command previously dumped by atmel_qspi_debug_command()
+	 */
+	if (cmd->rx_buf)
+		print_hex_dump(KERN_DEBUG, "qspi rx : ", DUMP_PREFIX_NONE,
+			       32, 1, cmd->rx_buf, cmd->buf_len, false);
+#endif
+no_data:
+	/* Poll INSTRuction End status */
+	sr = qspi_readl(aq, QSPI_SR);
+	if (sr & QSPI_SR_INSTRE)
+		return err;
+
+	/* Wait for INSTRuction End interrupt */
+	reinit_completion(&aq->cmd_completion);
+	aq->pending = 0;
+	qspi_writel(aq, QSPI_IER, QSPI_SR_INSTRE);
+	if (!wait_for_completion_timeout(&aq->cmd_completion,
+					 msecs_to_jiffies(1000)))
+		err = -ETIMEDOUT;
+	qspi_writel(aq, QSPI_IDR, QSPI_SR_INSTRE);
+
+	return err;
+}
+
+static int atmel_qspi_read_reg(struct spi_nor *nor, u8 opcode,
+			       u8 *buf, int len)
+{
+	struct atmel_qspi *aq = nor->priv;
+	struct atmel_qspi_command cmd;
+
+	memset(&cmd, 0, sizeof(cmd));
+	cmd.ifr_tfrtyp = QSPI_IFR_TFRTYP_TRSFR_READ;
+	cmd.enable.bits.instruction = 1;
+	cmd.enable.bits.data = 1;
+	cmd.instruction = opcode;
+	cmd.rx_buf = buf;
+	cmd.buf_len = len;
+	return atmel_qspi_run_command(aq, &cmd);
+}
+
+static int atmel_qspi_write_reg(struct spi_nor *nor, u8 opcode,
+				u8 *buf, int len,
+				int write_enable)
+{
+	struct atmel_qspi *aq = nor->priv;
+	struct atmel_qspi_command cmd;
+
+	memset(&cmd, 0, sizeof(cmd));
+	cmd.ifr_tfrtyp = QSPI_IFR_TFRTYP_TRSFR_WRITE;
+	cmd.enable.bits.instruction = 1;
+	cmd.enable.bits.data = (buf != NULL && len > 0);
+	cmd.instruction = opcode;
+	cmd.tx_buf = buf;
+	cmd.buf_len = len;
+	return atmel_qspi_run_command(aq, &cmd);
+}
+
+static void atmel_qspi_write(struct spi_nor *nor, loff_t to, size_t len,
+			     size_t *retlen, const u_char *write_buf)
+{
+	struct atmel_qspi *aq = nor->priv;
+	struct atmel_qspi_command cmd;
+
+	memset(&cmd, 0, sizeof(cmd));
+	cmd.ifr_tfrtyp = QSPI_IFR_TFRTYP_TRSFR_WRITE_MEM;
+	cmd.enable.bits.instruction = 1;
+	cmd.enable.bits.address = nor->addr_width;
+	cmd.enable.bits.data = 1;
+	cmd.enable.bits.dma = 1;
+	cmd.instruction = nor->program_opcode;
+	cmd.address = (u32)to;
+	cmd.tx_buf = write_buf;
+	cmd.buf_len = len;
+	if (!atmel_qspi_run_command(aq, &cmd))
+		*retlen += len;
+}
+
+static int atmel_qspi_erase(struct spi_nor *nor, loff_t offs)
+{
+	struct atmel_qspi *aq = nor->priv;
+	struct atmel_qspi_command cmd;
+
+	dev_dbg(nor->dev, "%dKiB at 0x%08x\n",
+		aq->mtd.erasesize / 1024, (u32)offs);
+
+	memset(&cmd, 0, sizeof(cmd));
+	cmd.ifr_tfrtyp = QSPI_IFR_TFRTYP_TRSFR_WRITE;
+	cmd.enable.bits.instruction = 1;
+	cmd.enable.bits.address = nor->addr_width;
+	cmd.instruction = nor->erase_opcode;
+	cmd.address = (u32)offs;
+	return atmel_qspi_run_command(aq, &cmd);
+}
+
+static int atmel_qspi_read(struct spi_nor *nor, loff_t from, size_t len,
+			   size_t *retlen, u_char *read_buf)
+{
+	struct atmel_qspi *aq = nor->priv;
+	struct atmel_qspi_command cmd;
+	int err;
+
+	memset(&cmd, 0, sizeof(cmd));
+	cmd.ifr_tfrtyp = QSPI_IFR_TFRTYP_TRSFR_READ_MEM;
+	cmd.enable.bits.instruction = 1;
+	cmd.enable.bits.address = nor->addr_width;
+	cmd.enable.bits.dummy = (nor->read_dummy > 0);
+	cmd.enable.bits.data = 1;
+	cmd.enable.bits.dma = 1;
+	cmd.instruction = nor->read_opcode;
+	cmd.address = (u32)from;
+	cmd.num_dummy_cycles = nor->read_dummy;
+	cmd.rx_buf = read_buf;
+	cmd.buf_len = len;
+	err = atmel_qspi_run_command(aq, &cmd);
+	if (err)
+		return err;
+
+	*retlen += len;
+	return 0;
+}
+
+static int atmel_qspi_set_protocol(struct spi_nor *nor, enum spi_protocol proto)
+{
+	struct atmel_qspi *aq = nor->priv;
+
+	switch (proto) {
+	case SPI_PROTO_1_1_1:
+		aq->ifr_width = QSPI_IFR_WIDTH_SINGLE_BIT_SPI;
+		break;
+	case SPI_PROTO_1_1_2:
+		aq->ifr_width = QSPI_IFR_WIDTH_DUAL_OUTPUT;
+		break;
+	case SPI_PROTO_1_1_4:
+		aq->ifr_width = QSPI_IFR_WIDTH_QUAD_OUTPUT;
+		break;
+	case SPI_PROTO_1_2_2:
+		aq->ifr_width = QSPI_IFR_WIDTH_DUAL_IO;
+		break;
+	case SPI_PROTO_1_4_4:
+		aq->ifr_width = QSPI_IFR_WIDTH_QUAD_IO;
+		break;
+	case SPI_PROTO_2_2_2:
+		aq->ifr_width = QSPI_IFR_WIDTH_DUAL_CMD;
+		break;
+	case SPI_PROTO_4_4_4:
+		aq->ifr_width = QSPI_IFR_WIDTH_QUAD_CMD;
+		break;
+	default:
+		return -EINVAL;
+	}
+
+	return 0;
+}
+
+static int atmel_qspi_init(struct atmel_qspi *aq)
+{
+	unsigned long src_rate;
+	u32 mr, scr, scbr;
+
+	/* Reset the QSPI controller */
+	qspi_writel(aq, QSPI_CR, QSPI_CR_SWRST);
+
+	/* Set the QSPI controller in Serial Memory Mode */
+	mr = QSPI_MR_SSM | QSPI_MR_NBBITS(8);
+	qspi_writel(aq, QSPI_MR, mr);
+
+	src_rate = clk_get_rate(aq->clk);
+	if (!src_rate)
+		return -EINVAL;
+
+	/* Compute the QSPI baudrate */
+	scbr = DIV_ROUND_UP(src_rate, aq->clk_rate);
+	if (scbr > 0)
+		scbr--;
+	scr = QSPI_SCR_SCBR(scbr);
+	qspi_writel(aq, QSPI_SCR, scr);
+
+	/* Enable the QSPI controller */
+	qspi_writel(aq, QSPI_CR, QSPI_CR_QSPIEN);
+
+	return 0;
+}
+
+static irqreturn_t atmel_qspi_interrupt(int irq, void *dev_id)
+{
+	struct atmel_qspi *aq = (struct atmel_qspi *)dev_id;
+	u32 status, mask, pending;
+
+	status = qspi_readl(aq, QSPI_SR);
+	mask = qspi_readl(aq, QSPI_IMR);
+	pending = status & mask;
+
+	if (!pending)
+		return IRQ_NONE;
+
+	aq->pending |= pending;
+	if (pending & QSPI_SR_INSTRE)
+		complete(&aq->cmd_completion);
+
+	return IRQ_HANDLED;
+}
+
+static int atmel_qspi_probe(struct platform_device *pdev)
+{
+	struct device_node *child, *np = pdev->dev.of_node;
+	struct mtd_part_parser_data ppdata;
+	struct atmel_qspi *aq;
+	struct resource *res;
+	dma_cap_mask_t mask;
+	struct spi_nor *nor;
+	struct mtd_info *mtd;
+	char modalias[40];
+	int irq, err = 0;
+
+	if (of_get_child_count(np) != 1)
+		return -ENODEV;
+	child = of_get_next_child(np, NULL);
+
+	aq = devm_kzalloc(&pdev->dev, sizeof(*aq), GFP_KERNEL);
+	if (!aq) {
+		err = -ENOMEM;
+		goto exit;
+	}
+
+	platform_set_drvdata(pdev, aq);
+	init_completion(&aq->cmd_completion);
+	init_completion(&aq->dma_completion);
+	aq->pdev = pdev;
+	/* Start in Extended SPI (1-1-1) */
+	aq->ifr_width = QSPI_IFR_WIDTH_SINGLE_BIT_SPI;
+
+	/* Map the registers */
+	res = platform_get_resource(pdev, IORESOURCE_MEM, 0);
+	aq->regs = devm_ioremap_resource(&pdev->dev, res);
+	if (IS_ERR(aq->regs)) {
+		dev_err(&pdev->dev, "missing registers\n");
+		err = PTR_ERR(aq->regs);
+		goto exit;
+	}
+
+	/* Map the AHB memory */
+	res = platform_get_resource(pdev, IORESOURCE_MEM, 1);
+	aq->mem = devm_ioremap_resource(&pdev->dev, res);
+	if (IS_ERR(aq->mem)) {
+		dev_err(&pdev->dev, "missing AHB memory\n");
+		err = PTR_ERR(aq->regs);
+		goto exit;
+	}
+	aq->phys_addr = (dma_addr_t)res->start;
+
+	/* Get the peripheral clock */
+	aq->clk = devm_clk_get(&pdev->dev, NULL);
+	if (IS_ERR(aq->clk)) {
+		dev_err(&pdev->dev, "missing peripheral clock\n");
+		err = PTR_ERR(aq->clk);
+		goto exit;
+	}
+
+	/* Enable the peripheral clock */
+	err = clk_prepare_enable(aq->clk);
+	if (err) {
+		dev_err(&pdev->dev, "failed to enable the peripheral clock\n");
+		goto exit;
+	}
+
+	/* Request the IRQ */
+	irq = platform_get_irq(pdev, 0);
+	if (irq < 0) {
+		dev_err(&pdev->dev, "missing IRQ\n");
+		err = irq;
+		goto disable_clk;
+	}
+	err = devm_request_irq(&pdev->dev, irq, atmel_qspi_interrupt,
+			       0, dev_name(&pdev->dev), aq);
+	if (err)
+		goto disable_clk;
+
+	/* Try to get a DMA channel for memcpy() operation */
+	dma_cap_zero(mask);
+	dma_cap_set(DMA_MEMCPY, mask);
+	aq->chan = dma_request_channel(mask, NULL, NULL);
+	if (!aq->chan)
+		dev_warn(&pdev->dev, "no available DMA channel\n");
+
+	/* Setup the spi-nor */
+	nor = &aq->nor;
+	mtd = &aq->mtd;
+
+	nor->mtd = mtd;
+	nor->dev = &pdev->dev;
+	nor->priv = aq;
+	mtd->priv = nor;
+
+	nor->read_reg = atmel_qspi_read_reg;
+	nor->write_reg = atmel_qspi_write_reg;
+	nor->read = atmel_qspi_read;
+	nor->write = atmel_qspi_write;
+	nor->erase = atmel_qspi_erase;
+	nor->set_protocol = atmel_qspi_set_protocol;
+
+	if (of_modalias_node(child, modalias, sizeof(modalias)) < 0) {
+		err = -ENODEV;
+		goto release_channel;
+	}
+
+	err = of_property_read_u32(child, "spi-max-frequency", &aq->clk_rate);
+	if (err < 0)
+		goto release_channel;
+
+	err = atmel_qspi_init(aq);
+	if (err)
+		goto release_channel;
+
+	nor->dev->of_node = child;
+	err = spi_nor_scan(nor, modalias, SPI_NOR_QUAD);
+	nor->dev->of_node = np;
+	if (err)
+		goto release_channel;
+
+	ppdata.of_node = child;
+	err = mtd_device_parse_register(mtd, NULL, &ppdata, NULL, 0);
+	if (err)
+		goto release_channel;
+
+	of_node_put(child);
+
+	return 0;
+
+release_channel:
+	if (aq->chan)
+		dma_release_channel(aq->chan);
+disable_clk:
+	clk_disable_unprepare(aq->clk);
+exit:
+	of_node_put(child);
+
+	return err;
+}
+
+static int atmel_qspi_remove(struct platform_device *pdev)
+{
+	struct atmel_qspi *aq = platform_get_drvdata(pdev);
+
+	mtd_device_unregister(&aq->mtd);
+	qspi_writel(aq, QSPI_CR, QSPI_CR_QSPIDIS);
+	if (aq->chan)
+		dma_release_channel(aq->chan);
+	clk_disable_unprepare(aq->clk);
+	return 0;
+}
+
+
+static const struct of_device_id atmel_qspi_dt_ids[] = {
+	{ .compatible = "atmel,sama5d2-qspi" },
+	{ /* sentinel */ }
+};
+
+MODULE_DEVICE_TABLE(of, atmel_qspi_dt_ids);
+
+static struct platform_driver atmel_qspi_driver = {
+	.driver = {
+		.name	= "atmel_qspi",
+		.of_match_table	= atmel_qspi_dt_ids,
+	},
+	.probe		= atmel_qspi_probe,
+	.remove		= atmel_qspi_remove,
+};
+module_platform_driver(atmel_qspi_driver);
+
+MODULE_AUTHOR("Cyrille Pitchen <cyrille.pitchen at atmel.com>");
+MODULE_DESCRIPTION("Atmel QSPI Controller driver");
+MODULE_LICENSE("GPL v2");
-- 
1.8.2.2



From holler at ahsoftware.de  Wed Aug 26 05:28:15 2015
From: holler at ahsoftware.de (Alexander Holler)
Date: Wed, 26 Aug 2015 14:28:15 +0200
Subject: [PATCH 03/16] deps: dtc: Add option to print dependency graph as dot
 (Graphviz)
In-Reply-To: <1440592108-3740-1-git-send-email-holler@ahsoftware.de>
References: <1440592108-3740-1-git-send-email-holler@ahsoftware.de>
Message-ID: <1440592108-3740-4-git-send-email-holler@ahsoftware.de>

Add option -T do print a dependency graph in dot format for
generating a picture with Graphviz.

E.g.

	dtc -T foo.dts | dot -T svg -o foo.svg

would generate the picture foo.png with the dependency graph.

Convential dependencies (those based on the tree structure) are having
black arrows, dependencies based on the property 'dependencies' are
having cyan arrows.

Option -D to not automatically add dependencies does still work, so
you could build a classic dependency graph with

	dtc -D -T foo.dts | dot -T png -o foo_no_auto_deps.png

This works with binary blobs as input too. E.g.

	CROSS_COMPILE=gcc-foo ARCH=arm make foo.dtb
	scripts/dtc/dtc -I dtb -T arch/arm/boot/dts/foo.dtb

would print the dot file.

Signed-off-by: Alexander Holler <holler at ahsoftware.de>
---
 scripts/dtc/dependencies.c | 49 ++++++++++++++++++++++++++++++++++++++++------
 scripts/dtc/dtc.c          | 19 +++++++++++++++---
 scripts/dtc/dtc.h          |  2 +-
 3 files changed, 60 insertions(+), 10 deletions(-)

diff --git a/scripts/dtc/dependencies.c b/scripts/dtc/dependencies.c
index 3fb5cef..2c1e0d4 100644
--- a/scripts/dtc/dependencies.c
+++ b/scripts/dtc/dependencies.c
@@ -298,7 +298,7 @@ static void __init topological_sort(void)
 			depth_first_search(i);
 }
 
-static int __init add_dep_list(struct device_node *node)
+static int __init add_dep_list(struct device_node *node, bool print_dot)
 {
 	const __be32 *list, *list_end;
 	uint32_t ph;
@@ -328,6 +328,9 @@ static int __init add_dep_list(struct device_node *node)
 		rc = insert_edge(node->phandle, ph);
 		if (rc)
 			break;
+		if (print_dot)
+			printf("      node0x%x -> node0x%x [color=cyan]\n",
+				node->phandle, ph);
 	}
 
 	return rc;
@@ -352,9 +355,10 @@ static const char *of_prop_next_string(struct property *prop, const char *cur)
 }
 
 static int __init add_deps_lnx(struct device_node *parent,
-				struct device_node *node)
+				struct device_node *node, bool print_dot)
 {
 	struct device_node *child;
+	const char *cp;
 	int rc = 0;
 
 	if (!__of_device_is_available(node))
@@ -375,13 +379,34 @@ static int __init add_deps_lnx(struct device_node *parent,
 			return -EINVAL;
 		}
 		order.parent_by_phandle[node->phandle] = parent->phandle;
-		rc = add_dep_list(node);
+		if (print_dot) {
+			struct property *prop;
+
+			printf("    node0x%x [label=\"0x%x %s", node->phandle,
+						node->phandle, node->name);
+			if (node->full_name)
+				printf(" (%s)", node->full_name);
+			prop = get_property(node, "compatible");
+			if (prop) {
+				printf("\\n");
+				for (cp = of_prop_next_string(prop, NULL); cp;
+				     cp = of_prop_next_string(prop, cp)) {
+					if (cp != prop->val.val)
+						putchar(' ');
+					printf("%s", cp);
+				}
+			}
+			printf("\"];\n");
+			printf("      node0x%x -> node0x%x\n", node->phandle,
+							parent->phandle);
+		}
+		rc = add_dep_list(node, print_dot);
 		if (unlikely(rc))
 			return rc;
 		parent = node; /* change the parent only if node is a driver */
 	}
 	for_each_child_of_node(node, child) {
-		rc = add_deps_lnx(parent, child);
+		rc = add_deps_lnx(parent, child, print_dot);
 		if (unlikely(rc))
 			break;
 	}
@@ -424,7 +449,7 @@ void __init of_init_print_order(const char *name)
 	}
 }
 
-int __init of_init_build_order(struct device_node *root)
+int __init of_init_build_order(struct device_node *root, const char *print_dot)
 {
 	struct device_node *child;
 	int rc = 0;
@@ -436,12 +461,24 @@ int __init of_init_build_order(struct device_node *root)
 	calc_max_phandle(root);
 	order.old_max_phandle = order.max_phandle;
 
+	if (print_dot) {
+		printf("digraph G {\n");
+		printf("    node0x%x [label=\"0x%x root (/)\"];\n",
+			order.max_phandle+1, order.max_phandle+1);
+	}
+
 	for_each_child_of_node(root, child) {
-		rc = add_deps_lnx(root, child);
+		rc = add_deps_lnx(root, child, print_dot);
 		if (unlikely(rc))
 			break;
 	}
 
+	if (print_dot) {
+		printf("  graph [label=\"Dependency Graph for %s (%u nodes, %u edges)\"];\n",
+			print_dot, graph.nvertices, graph.nedges);
+		printf("}\n");
+	}
+
 	of_node_put(root);
 	topological_sort();
 
diff --git a/scripts/dtc/dtc.c b/scripts/dtc/dtc.c
index 494c531..b1ca363 100644
--- a/scripts/dtc/dtc.c
+++ b/scripts/dtc/dtc.c
@@ -51,7 +51,7 @@ static void fill_fullpaths(struct node *tree, const char *prefix)
 #define FDT_VERSION(version)	_FDT_VERSION(version)
 #define _FDT_VERSION(version)	#version
 static const char usage_synopsis[] = "dtc [options] <input file>";
-static const char usage_short_opts[] = "qI:O:o:V:d:R:S:p:fb:i:H:sDtW:E:hv";
+static const char usage_short_opts[] = "qI:O:o:V:d:R:S:p:fb:i:H:sDtTW:E:hv";
 static struct option const usage_long_opts[] = {
 	{"quiet",            no_argument, NULL, 'q'},
 	{"in-format",         a_argument, NULL, 'I'},
@@ -68,6 +68,7 @@ static struct option const usage_long_opts[] = {
 	{"sort",             no_argument, NULL, 's'},
 	{"no-deps",          no_argument, NULL, 'D'},
 	{"initialization-order", no_argument, NULL, 't'},
+	{"dot",              no_argument, NULL, 'T'},
 	{"phandle",           a_argument, NULL, 'H'},
 	{"warning",           a_argument, NULL, 'W'},
 	{"error",             a_argument, NULL, 'E'},
@@ -97,6 +98,7 @@ static const char * const usage_opts_help[] = {
 	"\n\tSort nodes and properties before outputting (useful for comparing trees)",
 	"\n\tDo not automatically add dependencies for phandle references",
 	"\n\tPrint (default) initialization order",
+	"\n\tPrint dot with dependency graph (for use with Graphviz)",
 	"\n\tValid phandle formats are:\n"
 	 "\t\tlegacy - \"linux,phandle\" properties only\n"
 	 "\t\tepapr  - \"phandle\" properties only\n"
@@ -118,6 +120,7 @@ int main(int argc, char *argv[])
 	bool force = false, sort = false;
 	bool dependencies = true;
 	bool init_order = false;
+	bool print_dot = false;
 	const char *arg;
 	int opt;
 	FILE *outf = NULL;
@@ -193,6 +196,10 @@ int main(int argc, char *argv[])
 			init_order = true;
 			break;
 
+		case 'T':
+			print_dot = true;
+			break;
+
 		case 'W':
 			parse_checks_option(true, false, optarg);
 			break;
@@ -254,12 +261,18 @@ int main(int argc, char *argv[])
 		add_dependencies(bi);
 
 	if (init_order) {
-		if (of_init_build_order(bi->dt))
+		if (of_init_build_order(bi->dt, 0))
 			exit(2);
 		of_init_print_order(arg);
 		exit(0);
 	}
 
+	if (print_dot) {
+		if (of_init_build_order(bi->dt, arg))
+			exit(2);
+		exit(0);
+	}
+
 	if (streq(outname, "-")) {
 		outf = stdout;
 	} else {
@@ -286,7 +299,7 @@ int main(int argc, char *argv[])
 	 * This is done after the output was saved because it
 	 * changes the tree slightly.
 	 */
-	if (of_init_build_order(bi->dt))
+	if (of_init_build_order(bi->dt, 0))
 		exit(2);
 
 	exit(0);
diff --git a/scripts/dtc/dtc.h b/scripts/dtc/dtc.h
index 9ae4bfc..8ef8e6f 100644
--- a/scripts/dtc/dtc.h
+++ b/scripts/dtc/dtc.h
@@ -269,6 +269,6 @@ struct boot_info *dt_from_fs(const char *dirname);
 /* Dependencies */
 void add_dependencies(struct boot_info *bi);
 void of_init_print_order(const char *name);
-int of_init_build_order(struct node *root);
+int of_init_build_order(struct node *root, const char *print_dot);
 
 #endif /* _DTC_H */
-- 
2.1.0



From holler at ahsoftware.de  Wed Aug 26 05:28:17 2015
From: holler at ahsoftware.de (Alexander Holler)
Date: Wed, 26 Aug 2015 14:28:17 +0200
Subject: [PATCH 05/16] deps: introduce initcalls annotated with a struct
 device_driver
In-Reply-To: <1440592108-3740-1-git-send-email-holler@ahsoftware.de>
References: <1440592108-3740-1-git-send-email-holler@ahsoftware.de>
Message-ID: <1440592108-3740-6-git-send-email-holler@ahsoftware.de>

Make it possible to identify initcalls before calling them by adding
a pointer to a struct device_driver to the stored pointer to an initcall.

This is e.g. necessary in order to sort initcalls by whatever means
before calling them.

To annotate an initcall, the following changes are necessary on
drivers which want to offer that feature:

now				annotated
--------------------------------------------------------------------------
pure_initcall(fn)		annotated_initcall(pure, fn, dev_drv)
core_initcall(fn)		annotated_initcall(core, fn, dev_drv)
core_initcall_sync(fn)		annotated_initcall_sync(core, fn, dev_drv)
...
late_initcall(fn)		annotated_initcall(late, fn, dev_drv)
module_init(fn)			annotated_module_init(fn, dev_drv)

module_platform_driver(drv)	no changes necessary, done automatically
module_platform_driver_probe(drv, probe)	no changes necessary
module_i2c_driver(i2c_drv)	no changes necessary, done automatically

E.g. to make the driver sram offering an annotated initcall the
following patch is necessary:

----
-postcore_initcall(sram_init);
+annotated_initcall(postcore, sram_init, sram_driver.driver);
----

These changes can be done without any fear. If the feature is disabled,
which is the default, the new macros will just map to the old ones and
nothing is changed at all.

Signed-off-by: Alexander Holler <holler at ahsoftware.de>
---
 arch/arm/kernel/vmlinux.lds.S     |  1 +
 include/asm-generic/vmlinux.lds.h |  6 ++++++
 include/linux/device.h            | 12 ++++++++++++
 include/linux/i2c.h               |  2 +-
 include/linux/init.h              | 33 +++++++++++++++++++++++++++++++++
 include/linux/module.h            |  2 ++
 include/linux/platform_device.h   | 16 ++++++++++++----
 init/Kconfig                      |  3 +++
 8 files changed, 70 insertions(+), 5 deletions(-)

diff --git a/arch/arm/kernel/vmlinux.lds.S b/arch/arm/kernel/vmlinux.lds.S
index 8b60fde..10a328f 100644
--- a/arch/arm/kernel/vmlinux.lds.S
+++ b/arch/arm/kernel/vmlinux.lds.S
@@ -213,6 +213,7 @@ SECTIONS
 #endif
 		INIT_SETUP(16)
 		INIT_CALLS
+		ANNOTATED_INITCALL
 		CON_INITCALL
 		SECURITY_INITCALL
 		INIT_RAM_FS
diff --git a/include/asm-generic/vmlinux.lds.h b/include/asm-generic/vmlinux.lds.h
index 8bd374d..7318ba7 100644
--- a/include/asm-generic/vmlinux.lds.h
+++ b/include/asm-generic/vmlinux.lds.h
@@ -660,6 +660,11 @@
 		INIT_CALLS_LEVEL(7)					\
 		VMLINUX_SYMBOL(__initcall_end) = .;
 
+#define ANNOTATED_INITCALL						\
+		VMLINUX_SYMBOL(__annotated_initcall_start) = .;		\
+		*(.annotated_initcall.init)				\
+		VMLINUX_SYMBOL(__annotated_initcall_end) = .;
+
 #define CON_INITCALL							\
 		VMLINUX_SYMBOL(__con_initcall_start) = .;		\
 		*(.con_initcall.init)					\
@@ -816,6 +821,7 @@
 		INIT_DATA						\
 		INIT_SETUP(initsetup_align)				\
 		INIT_CALLS						\
+		ANNOTATED_INITCALL					\
 		CON_INITCALL						\
 		SECURITY_INITCALL					\
 		INIT_RAM_FS						\
diff --git a/include/linux/device.h b/include/linux/device.h
index a2b4ea7..128fddd 100644
--- a/include/linux/device.h
+++ b/include/linux/device.h
@@ -1321,4 +1321,16 @@ static int __init __driver##_init(void) \
 } \
 device_initcall(__driver##_init);
 
+#define annotated_module_driver(__driver, __register, __unregister, ...) \
+static int __init __driver##_init(void) \
+{ \
+	return __register(&(__driver), ##__VA_ARGS__); \
+} \
+annotated_module_init(__driver##_init, __driver.driver); \
+static void __exit __driver##_exit(void) \
+{ \
+	__unregister(&(__driver), ##__VA_ARGS__); \
+} \
+module_exit(__driver##_exit)
+
 #endif /* _DEVICE_H_ */
diff --git a/include/linux/i2c.h b/include/linux/i2c.h
index e83a738..fa63ec1 100644
--- a/include/linux/i2c.h
+++ b/include/linux/i2c.h
@@ -626,7 +626,7 @@ static inline int i2c_adapter_id(struct i2c_adapter *adap)
  * use this macro once, and calling it replaces module_init() and module_exit()
  */
 #define module_i2c_driver(__i2c_driver) \
-	module_driver(__i2c_driver, i2c_add_driver, \
+	annotated_module_driver(__i2c_driver, i2c_add_driver, \
 			i2c_del_driver)
 
 #endif /* I2C */
diff --git a/include/linux/init.h b/include/linux/init.h
index b449f37..52ea986 100644
--- a/include/linux/init.h
+++ b/include/linux/init.h
@@ -124,6 +124,15 @@
 typedef int (*initcall_t)(void);
 typedef void (*exitcall_t)(void);
 
+struct device_driver;
+
+struct _annotated_initcall {
+	initcall_t initcall;
+	struct device_driver *driver;
+};
+extern struct _annotated_initcall __annotated_initcall_start[],
+				  __annotated_initcall_end[];
+
 extern initcall_t __con_initcall_start[], __con_initcall_end[];
 extern initcall_t __security_initcall_start[], __security_initcall_end[];
 
@@ -184,6 +193,11 @@ extern bool initcall_debug;
 	__attribute__((__section__(".initcall" #id ".init"))) = fn; \
 	LTO_REFERENCE_INITCALL(__initcall_##fn##id)
 
+#define __define_annotated_initcall(fn, drv) \
+	static struct _annotated_initcall __annotated_initcall_##fn __used \
+	__attribute__((__section__(".annotated_initcall.init"))) = \
+							{ fn, &(drv) }
+
 /*
  * Early initcalls run before initializing SMP.
  *
@@ -216,6 +230,25 @@ extern bool initcall_debug;
 #define late_initcall(fn)		__define_initcall(fn, 7)
 #define late_initcall_sync(fn)		__define_initcall(fn, 7s)
 
+/*
+ * Annotated initcalls are accompanied by a struct device_driver.
+ * This makes initcalls identifiable and is used to order initcalls.
+ *
+ * If disabled, nothing is changed and the classic level based
+ * initialization sequence is in use.
+ */
+#ifdef CONFIG_ANNOTATED_INITCALLS
+#define annotated_module_init(fn, drv)	__define_annotated_initcall(fn, drv)
+#define annotated_initcall(level, fn, drv) \
+					__define_annotated_initcall(fn, drv)
+#define annotated_initcall_sync(level, fn, drv) \
+					__define_annotated_initcall(fn, drv)
+#else
+#define annotated_module_init(fn, drv)	module_init(fn)
+#define annotated_initcall(level, fn, drv)	level ## _initcall(fn)
+#define annotated_initcall_sync(level, fn, drv)	level ## _initcall_sync(fn)
+#endif
+
 #define __initcall(fn) device_initcall(fn)
 
 #define __exitcall(fn) \
diff --git a/include/linux/module.h b/include/linux/module.h
index 3a19c79..6079d28 100644
--- a/include/linux/module.h
+++ b/include/linux/module.h
@@ -119,6 +119,8 @@ extern void cleanup_module(void);
 #define device_initcall_sync(fn)	module_init(fn)
 #define late_initcall(fn)		module_init(fn)
 #define late_initcall_sync(fn)		module_init(fn)
+#define annotated_initcall(level, fn, drv)	module_init(fn)
+#define annotated_module_init(fn, drv)	module_init(fn)
 
 #define console_initcall(fn)		module_init(fn)
 #define security_initcall(fn)		module_init(fn)
diff --git a/include/linux/platform_device.h b/include/linux/platform_device.h
index bba08f4..baa5a66 100644
--- a/include/linux/platform_device.h
+++ b/include/linux/platform_device.h
@@ -218,9 +218,17 @@ static inline void platform_set_drvdata(struct platform_device *pdev,
  * boilerplate.  Each module may only use this macro once, and
  * calling it replaces module_init() and module_exit()
  */
-#define module_platform_driver(__platform_driver) \
-	module_driver(__platform_driver, platform_driver_register, \
-			platform_driver_unregister)
+#define module_platform_driver(__driver) \
+static int __init __driver##_init(void) \
+{ \
+	return platform_driver_register(&(__driver)); \
+} \
+annotated_module_init(__driver##_init, __driver.driver); \
+static void __exit __driver##_exit(void) \
+{ \
+	platform_driver_unregister(&(__driver)); \
+} \
+module_exit(__driver##_exit)
 
 /* builtin_platform_driver() - Helper macro for builtin drivers that
  * don't do anything special in driver init.  This eliminates some
@@ -242,7 +250,7 @@ static int __init __platform_driver##_init(void) \
 	return platform_driver_probe(&(__platform_driver), \
 				     __platform_probe);    \
 } \
-module_init(__platform_driver##_init); \
+annotated_module_init(__platform_driver##_init, __platform_driver.driver); \
 static void __exit __platform_driver##_exit(void) \
 { \
 	platform_driver_unregister(&(__platform_driver)); \
diff --git a/init/Kconfig b/init/Kconfig
index af09b4f..5cfd7c4 100644
--- a/init/Kconfig
+++ b/init/Kconfig
@@ -26,6 +26,9 @@ config IRQ_WORK
 config BUILDTIME_EXTABLE_SORT
 	bool
 
+config ANNOTATED_INITCALLS
+	bool
+
 menu "General setup"
 
 config BROKEN
-- 
2.1.0



From broonie at kernel.org  Wed Aug 26 05:35:56 2015
From: broonie at kernel.org (Mark Brown)
Date: Wed, 26 Aug 2015 13:35:56 +0100
Subject: [PATCH] regmap: Fix the null function of format_val on
 regmap_bulk_read.
In-Reply-To: <1440589396-696-1-git-send-email-henryc.chen@mediatek.com>
References: <1440589396-696-1-git-send-email-henryc.chen@mediatek.com>
Message-ID: <20150826123556.GB2977@sirena.org.uk>

On Wed, Aug 26, 2015 at 07:43:16PM +0800, Henry Chen wrote:
> The regmap_format will not be initialize if device driver not declare the regmap_bus
> when registering the regmap. To avoid the null function of format_val when
> called regmap_bulk_read(). It need to give a format function when regmap init.

> Call trace:
> [<          (null)>]           (null)
> [<ffffffc0004cbdd0>] mtk_rtc_read_time+0x9c/0x134
> [<ffffffc0004c9618>] __rtc_read_time.isra.3+0x40/0x7c
> [<ffffffc0004c9688>] rtc_read_time+0x34/0x58

Please don't paste entire backtraces in, they're enormous and tend to
obscure the actual content while adding little value.  If needed then
edited highlights work better.  I'm fairly sure I've mentioned this
before...

> @@ -783,8 +783,22 @@ struct regmap *regmap_init(struct device *dev,
>  		map->defer_caching = true;
>  		map->reg_write = _regmap_bus_raw_write;
>  	}
> +/*
> + * For bulk read, need to hook the format function.
> + */
> +simple_format_initialization:

The indentation is all messed up here, we're misssing a blank line and
the comment is not indented.

> -skip_format_initialization:
> +	switch (config->val_bits) {
> +		case 8:
> +			map->format.format_val = regmap_format_8;
> +			break;
> +		case 16:
> +			map->format.format_val = regmap_format_16_native;
> +			break;
> +		case 32:
> +			map->format.format_val = regmap_format_32_native;
> +			break;
> +	}

Why are these format functions sensible?  Converting a null pointer
dereference into data corruption wouldn't be ideal.  The commit message
should really cover this.
-------------- next part --------------
A non-text attachment was scrubbed...
Name: signature.asc
Type: application/pgp-signature
Size: 473 bytes
Desc: Digital signature
URL: <http://lists.infradead.org/pipermail/linux-arm-kernel/attachments/20150826/7785bcae/attachment.sig>

From linus.walleij at linaro.org  Wed Aug 26 05:38:20 2015
From: linus.walleij at linaro.org (Linus Walleij)
Date: Wed, 26 Aug 2015 14:38:20 +0200
Subject: [PATCH v4] pinctrl: mediatek: Fix multiple registration issue.
In-Reply-To: <1440549165-35637-1-git-send-email-hongzhou.yang@mediatek.com>
References: <1440549165-35637-1-git-send-email-hongzhou.yang@mediatek.com>
Message-ID: <CACRpkdZThvKa2sCC5HE_=nQXc0nTD7t-EkGwm6Lq8AUqUUjGFQ@mail.gmail.com>

On Wed, Aug 26, 2015 at 2:32 AM, Hongzhou Yang
<hongzhou.yang at mediatek.com> wrote:

> Since our common driver need support main chip and PMU
> at the same time, that means it will register two
> pinctrl device, and the pinctrl_desc structure should
> be used two times.
>
> But pinctrl_desc use global static definition, then
> the latest registered pinctrl device will overwrite
> the old one's, all members in pinctrl_desc will set to
> the new one's, such as name, pins and pins numbers, etc.
> This is a bug.
>
> Move pinctrl_desc into mtk_pinctrl, assign new value for
> each pinctrl device to fix it.
>
> Cc: stable at vger.kernel.org # v4.1+
> Signed-off-by: Hongzhou Yang <hongzhou.yang at mediatek.com>
> Reviewed-by: Axel Lin <axel.lin at ingics.com>
> ---
>  In order to fix multiple registration issue, move
>  pinctrl_desc into mtk_pinctrl, assign new value for
>  each pinctrl device.

This patch applied.

Yours,
Linus Walleij


From holler at ahsoftware.de  Wed Aug 26 05:28:23 2015
From: holler at ahsoftware.de (Alexander Holler)
Date: Wed, 26 Aug 2015 14:28:23 +0200
Subject: [PATCH 11/16] deps: WIP: generic: annotate some initcalls
In-Reply-To: <1440592108-3740-1-git-send-email-holler@ahsoftware.de>
References: <1440592108-3740-1-git-send-email-holler@ahsoftware.de>
Message-ID: <1440592108-3740-12-git-send-email-holler@ahsoftware.de>

WIP means Work In Progress.

Change some generic drivers to offer annotated initcalls.

Signed-off-by: Alexander Holler <holler at ahsoftware.de>
---
 drivers/input/keyboard/gpio_keys.c | 2 +-
 drivers/misc/sram.c                | 2 +-
 drivers/regulator/fixed.c          | 3 ++-
 drivers/usb/phy/phy-generic.c      | 2 +-
 4 files changed, 5 insertions(+), 4 deletions(-)

diff --git a/drivers/input/keyboard/gpio_keys.c b/drivers/input/keyboard/gpio_keys.c
index ddf4045..319bcf7 100644
--- a/drivers/input/keyboard/gpio_keys.c
+++ b/drivers/input/keyboard/gpio_keys.c
@@ -855,7 +855,7 @@ static void __exit gpio_keys_exit(void)
 	platform_driver_unregister(&gpio_keys_device_driver);
 }
 
-late_initcall(gpio_keys_init);
+annotated_initcall(late, gpio_keys_init, gpio_keys_device_driver.driver);
 module_exit(gpio_keys_exit);
 
 MODULE_LICENSE("GPL");
diff --git a/drivers/misc/sram.c b/drivers/misc/sram.c
index 15c33cc..eb662bd 100644
--- a/drivers/misc/sram.c
+++ b/drivers/misc/sram.c
@@ -243,4 +243,4 @@ static int __init sram_init(void)
 	return platform_driver_register(&sram_driver);
 }
 
-postcore_initcall(sram_init);
+annotated_initcall(postcore, sram_init, sram_driver.driver);
diff --git a/drivers/regulator/fixed.c b/drivers/regulator/fixed.c
index ff62d69..ec35d10 100644
--- a/drivers/regulator/fixed.c
+++ b/drivers/regulator/fixed.c
@@ -221,7 +221,8 @@ static int __init regulator_fixed_voltage_init(void)
 {
 	return platform_driver_register(&regulator_fixed_voltage_driver);
 }
-subsys_initcall(regulator_fixed_voltage_init);
+annotated_initcall(subsys, regulator_fixed_voltage_init,
+					regulator_fixed_voltage_driver.driver);
 
 static void __exit regulator_fixed_voltage_exit(void)
 {
diff --git a/drivers/usb/phy/phy-generic.c b/drivers/usb/phy/phy-generic.c
index deee68e..baf95d0 100644
--- a/drivers/usb/phy/phy-generic.c
+++ b/drivers/usb/phy/phy-generic.c
@@ -360,7 +360,7 @@ static int __init usb_phy_generic_init(void)
 {
 	return platform_driver_register(&usb_phy_generic_driver);
 }
-subsys_initcall(usb_phy_generic_init);
+annotated_initcall(subsys, usb_phy_generic_init, usb_phy_generic_driver.driver);
 
 static void __exit usb_phy_generic_exit(void)
 {
-- 
2.1.0



From holler at ahsoftware.de  Wed Aug 26 05:28:19 2015
From: holler at ahsoftware.de (Alexander Holler)
Date: Wed, 26 Aug 2015 14:28:19 +0200
Subject: [PATCH 07/16] deps: add debug configuration options
In-Reply-To: <1440592108-3740-1-git-send-email-holler@ahsoftware.de>
References: <1440592108-3740-1-git-send-email-holler@ahsoftware.de>
Message-ID: <1440592108-3740-8-git-send-email-holler@ahsoftware.de>

Add some debug options to print annotated initcalls, the ordered list of
annotated initcalls and to print a message right before an annotated
initcall is called.

Signed-off-by: Alexander Holler <holler at ahsoftware.de>
---
 drivers/of/Kconfig           | 18 ++++++++++++++
 drivers/of/of_dependencies.c | 57 ++++++++++++++++++++++++++++++++++++++++++--
 2 files changed, 73 insertions(+), 2 deletions(-)

diff --git a/drivers/of/Kconfig b/drivers/of/Kconfig
index 9bf6c73..26c4b1a 100644
--- a/drivers/of/Kconfig
+++ b/drivers/of/Kconfig
@@ -114,4 +114,22 @@ config OF_DEPENDENCIES
 
 	  If unsure, say N here.
 
+config OF_DEPENDENCIES_PRINT_INIT_ORDER
+	bool "Print dependency based initialization order"
+	depends on OF_DEPENDENCIES
+	help
+	  Used for debugging purposes.
+
+config OF_DEPENDENCIES_PRINT_ANNOTATED_INITCALLS
+	bool "Print names of annotated drivers"
+	depends on OF_DEPENDENCIES
+	help
+	  Used for debugging purposes.
+
+config OF_DEPENDENCIES_DEBUG_CALLS_OF_ANNOTATED_INITCALLS
+	bool "Show when annotated initcalls are actually called"
+	depends on OF_DEPENDENCIES
+	help
+	  Used for debugging purposes.
+
 endif # OF
diff --git a/drivers/of/of_dependencies.c b/drivers/of/of_dependencies.c
index 64ed049..06435d5 100644
--- a/drivers/of/of_dependencies.c
+++ b/drivers/of/of_dependencies.c
@@ -336,6 +336,41 @@ static void __init of_init_remove_duplicates(void)
 		}
 }
 
+#ifdef CONFIG_OF_DEPENDENCIES_PRINT_INIT_ORDER
+static void __init of_init_print_order(void)
+{
+	unsigned i;
+	struct property *prop;
+	const char *cp;
+
+	pr_info("Initialization order:\n");
+	for (i = 0; i < order.count; ++i) {
+		pr_info("init %u 0x%x", i, order.order[i]->phandle);
+		if (order.order[i]->name)
+			pr_cont(" %s", order.order[i]->name);
+		if (order.order[i]->full_name)
+			pr_cont(" (%s)", order.order[i]->full_name);
+		prop = __of_find_property(order.order[i], "compatible", NULL);
+		for (cp = of_prop_next_string(prop, NULL); cp;
+		     cp = of_prop_next_string(prop, cp))
+			pr_cont(" %s", cp);
+	}
+}
+#endif
+
+#ifdef CONFIG_OF_DEPENDENCIES_PRINT_ANNOTATED_INITCALLS
+static void __init of_init_print_annotated(void)
+{
+	struct _annotated_initcall *ac;
+
+	pr_info("Annotated drivers:\n");
+	ac = __annotated_initcall_start;
+	for (; ac < __annotated_initcall_end; ++ac)
+		pr_info("Driver '%s' (%s)\n", ac->driver->name,
+				ac->driver->of_match_table->compatible);
+}
+#endif
+
 static int __init of_init_build_order(void)
 {
 	int rc = 0;
@@ -363,7 +398,12 @@ static int __init of_init_build_order(void)
 		return -EINVAL; /* cycle found */
 
 	of_init_remove_duplicates();
-
+#ifdef CONFIG_OF_DEPENDENCIES_PRINT_INIT_ORDER
+	of_init_print_order();
+#endif
+#ifdef CONFIG_OF_DEPENDENCIES_PRINT_ANNOTATED_INITCALLS
+	of_init_print_annotated();
+#endif
 	return rc;
 }
 
@@ -386,6 +426,12 @@ static void __init init_if_matched(struct device_node *node)
 		if (ac->initcall && ac->driver->of_match_table)
 			if (of_match_node(ac->driver->of_match_table,
 					 node)) {
+#ifdef CONFIG_OF_DEPENDENCIES_DEBUG_CALLS_OF_ANNOTATED_INITCALLS
+				pr_info("Calling (ordered) initcall for driver %s (%s)\n",
+					ac->driver->name,
+					ac->driver->of_match_table ?
+						ac->driver->of_match_table->compatible : "");
+#endif
 				do_one_initcall(*ac->initcall);
 				ac->initcall = 0;
 			}
@@ -404,7 +450,14 @@ void __init of_init_drivers(void)
 	}
 	ac = __annotated_initcall_start;
 	for (; ac < __annotated_initcall_end; ++ac) {
-		if (ac->initcall)
+		if (ac->initcall) {
+#ifdef CONFIG_OF_DEPENDENCIES_DEBUG_CALLS_OF_ANNOTATED_INITCALLS
+			pr_info("Calling (unordered) initcall for driver %s (%s)\n",
+				ac->driver->name,
+				ac->driver->of_match_table ?
+					ac->driver->of_match_table->compatible : "");
+#endif
 			do_one_initcall(*ac->initcall);
+		}
 	}
 }
-- 
2.1.0



From holler at ahsoftware.de  Wed Aug 26 05:28:25 2015
From: holler at ahsoftware.de (Alexander Holler)
Date: Wed, 26 Aug 2015 14:28:25 +0200
Subject: [PATCH 13/16] deps: WIP: omap: annotate some initcalls
In-Reply-To: <1440592108-3740-1-git-send-email-holler@ahsoftware.de>
References: <1440592108-3740-1-git-send-email-holler@ahsoftware.de>
Message-ID: <1440592108-3740-14-git-send-email-holler@ahsoftware.de>

WIP means Work In Progress.

Change some omap drivers to offer annotated initcalls.

Signed-off-by: Alexander Holler <holler at ahsoftware.de>
---
 arch/arm/common/edma.c                 | 2 +-
 drivers/bus/omap_l3_smx.c              | 2 +-
 drivers/dma/omap-dma.c                 | 2 +-
 drivers/gpio/gpio-twl4030.c            | 2 +-
 drivers/gpu/drm/tilcdc/tilcdc_drv.c    | 2 +-
 drivers/i2c/busses/i2c-omap.c          | 2 +-
 drivers/iommu/omap-iommu.c             | 2 +-
 drivers/mailbox/omap-mailbox.c         | 2 +-
 drivers/memory/omap-gpmc.c             | 2 +-
 drivers/mfd/omap-usb-host.c            | 2 +-
 drivers/mfd/omap-usb-tll.c             | 2 +-
 drivers/mfd/tps65217.c                 | 2 +-
 drivers/net/ethernet/ti/cpsw.c         | 2 +-
 drivers/net/ethernet/ti/davinci_mdio.c | 2 +-
 drivers/phy/phy-twl4030-usb.c          | 2 +-
 drivers/regulator/twl-regulator.c      | 2 +-
 drivers/tty/serial/omap-serial.c       | 2 +-
 drivers/usb/host/ehci-omap.c           | 2 +-
 drivers/usb/host/ohci-omap3.c          | 2 +-
 drivers/usb/musb/omap2430.c            | 2 +-
 20 files changed, 20 insertions(+), 20 deletions(-)

diff --git a/arch/arm/common/edma.c b/arch/arm/common/edma.c
index 873dbfc..29f363c 100644
--- a/arch/arm/common/edma.c
+++ b/arch/arm/common/edma.c
@@ -1872,5 +1872,5 @@ static int __init edma_init(void)
 {
 	return platform_driver_probe(&edma_driver, edma_probe);
 }
-arch_initcall(edma_init);
+annotated_initcall(arch, edma_init, edma_driver.driver);
 
diff --git a/drivers/bus/omap_l3_smx.c b/drivers/bus/omap_l3_smx.c
index 360a5c0..e2172b8 100644
--- a/drivers/bus/omap_l3_smx.c
+++ b/drivers/bus/omap_l3_smx.c
@@ -302,7 +302,7 @@ static int __init omap3_l3_init(void)
 {
 	return platform_driver_register(&omap3_l3_driver);
 }
-postcore_initcall_sync(omap3_l3_init);
+annotated_initcall_sync(postcore, omap3_l3_init, omap3_l3_driver.driver);
 
 static void __exit omap3_l3_exit(void)
 {
diff --git a/drivers/dma/omap-dma.c b/drivers/dma/omap-dma.c
index 249445c..0866ae9 100644
--- a/drivers/dma/omap-dma.c
+++ b/drivers/dma/omap-dma.c
@@ -1285,7 +1285,7 @@ static int omap_dma_init(void)
 {
 	return platform_driver_register(&omap_dma_driver);
 }
-subsys_initcall(omap_dma_init);
+annotated_initcall(subsys, omap_dma_init, omap_dma_driver.driver);
 
 static void __exit omap_dma_exit(void)
 {
diff --git a/drivers/gpio/gpio-twl4030.c b/drivers/gpio/gpio-twl4030.c
index 9e1dbb9..60c0d1a 100644
--- a/drivers/gpio/gpio-twl4030.c
+++ b/drivers/gpio/gpio-twl4030.c
@@ -615,7 +615,7 @@ static int __init gpio_twl4030_init(void)
 {
 	return platform_driver_register(&gpio_twl4030_driver);
 }
-subsys_initcall(gpio_twl4030_init);
+annotated_initcall(subsys, gpio_twl4030_init, gpio_twl4030_driver.driver);
 
 static void __exit gpio_twl4030_exit(void)
 {
diff --git a/drivers/gpu/drm/tilcdc/tilcdc_drv.c b/drivers/gpu/drm/tilcdc/tilcdc_drv.c
index 0f283a3..8c50f23 100644
--- a/drivers/gpu/drm/tilcdc/tilcdc_drv.c
+++ b/drivers/gpu/drm/tilcdc/tilcdc_drv.c
@@ -715,7 +715,7 @@ static void __exit tilcdc_drm_fini(void)
 	tilcdc_tfp410_fini();
 }
 
-module_init(tilcdc_drm_init);
+annotated_module_init(tilcdc_drm_init, tilcdc_platform_driver.driver);
 module_exit(tilcdc_drm_fini);
 
 MODULE_AUTHOR("Rob Clark <robdclark at gmail.com");
diff --git a/drivers/i2c/busses/i2c-omap.c b/drivers/i2c/busses/i2c-omap.c
index fc9bf7f..0a5d63b 100644
--- a/drivers/i2c/busses/i2c-omap.c
+++ b/drivers/i2c/busses/i2c-omap.c
@@ -1541,7 +1541,7 @@ omap_i2c_init_driver(void)
 {
 	return platform_driver_register(&omap_i2c_driver);
 }
-subsys_initcall(omap_i2c_init_driver);
+annotated_initcall(subsys, omap_i2c_init_driver, omap_i2c_driver.driver);
 
 static void __exit omap_i2c_exit_driver(void)
 {
diff --git a/drivers/iommu/omap-iommu.c b/drivers/iommu/omap-iommu.c
index a22c33d..cf2ef44 100644
--- a/drivers/iommu/omap-iommu.c
+++ b/drivers/iommu/omap-iommu.c
@@ -1406,7 +1406,7 @@ static int __init omap_iommu_init(void)
 	return platform_driver_register(&omap_iommu_driver);
 }
 /* must be ready before omap3isp is probed */
-subsys_initcall(omap_iommu_init);
+annotated_initcall(subsys, omap_iommu_init, omap_iommu_driver.driver);
 
 static void __exit omap_iommu_exit(void)
 {
diff --git a/drivers/mailbox/omap-mailbox.c b/drivers/mailbox/omap-mailbox.c
index a3dbfd9..ac12306 100644
--- a/drivers/mailbox/omap-mailbox.c
+++ b/drivers/mailbox/omap-mailbox.c
@@ -883,7 +883,7 @@ static int __init omap_mbox_init(void)
 
 	return platform_driver_register(&omap_mbox_driver);
 }
-subsys_initcall(omap_mbox_init);
+annotated_initcall(subsys, omap_mbox_init, omap_mbox_driver.driver);
 
 static void __exit omap_mbox_exit(void)
 {
diff --git a/drivers/memory/omap-gpmc.c b/drivers/memory/omap-gpmc.c
index 9426276..65b0138 100644
--- a/drivers/memory/omap-gpmc.c
+++ b/drivers/memory/omap-gpmc.c
@@ -2217,7 +2217,7 @@ static __exit void gpmc_exit(void)
 
 }
 
-postcore_initcall(gpmc_init);
+annotated_initcall(postcore, gpmc_init, gpmc_driver.driver);
 module_exit(gpmc_exit);
 
 static irqreturn_t gpmc_handle_irq(int irq, void *dev)
diff --git a/drivers/mfd/omap-usb-host.c b/drivers/mfd/omap-usb-host.c
index 1d924d1..c996f45 100644
--- a/drivers/mfd/omap-usb-host.c
+++ b/drivers/mfd/omap-usb-host.c
@@ -896,7 +896,7 @@ static int __init omap_usbhs_drvinit(void)
  * This usbhs core driver should be initialized after
  * usb tll driver
  */
-fs_initcall_sync(omap_usbhs_drvinit);
+annotated_initcall_sync(fs, omap_usbhs_drvinit, usbhs_omap_driver.driver);
 
 static void __exit omap_usbhs_drvexit(void)
 {
diff --git a/drivers/mfd/omap-usb-tll.c b/drivers/mfd/omap-usb-tll.c
index b7b3e8e..ac5d393 100644
--- a/drivers/mfd/omap-usb-tll.c
+++ b/drivers/mfd/omap-usb-tll.c
@@ -475,7 +475,7 @@ static int __init omap_usbtll_drvinit(void)
  * The usbtll driver should be initialized before
  * the usbhs core driver probe function is called.
  */
-fs_initcall(omap_usbtll_drvinit);
+annotated_initcall(fs, omap_usbtll_drvinit, usbtll_omap_driver.driver);
 
 static void __exit omap_usbtll_drvexit(void)
 {
diff --git a/drivers/mfd/tps65217.c b/drivers/mfd/tps65217.c
index 7d1cfc1..386dd15 100644
--- a/drivers/mfd/tps65217.c
+++ b/drivers/mfd/tps65217.c
@@ -260,7 +260,7 @@ static int __init tps65217_init(void)
 {
 	return i2c_add_driver(&tps65217_driver);
 }
-subsys_initcall(tps65217_init);
+annotated_initcall(subsys, tps65217_init, tps65217_driver.driver);
 
 static void __exit tps65217_exit(void)
 {
diff --git a/drivers/net/ethernet/ti/cpsw.c b/drivers/net/ethernet/ti/cpsw.c
index d155bf2..6b772b5 100644
--- a/drivers/net/ethernet/ti/cpsw.c
+++ b/drivers/net/ethernet/ti/cpsw.c
@@ -2524,7 +2524,7 @@ static int __init cpsw_init(void)
 {
 	return platform_driver_register(&cpsw_driver);
 }
-late_initcall(cpsw_init);
+annotated_initcall(late, cpsw_init, cpsw_driver.driver);
 
 static void __exit cpsw_exit(void)
 {
diff --git a/drivers/net/ethernet/ti/davinci_mdio.c b/drivers/net/ethernet/ti/davinci_mdio.c
index c00084d..32e0269 100644
--- a/drivers/net/ethernet/ti/davinci_mdio.c
+++ b/drivers/net/ethernet/ti/davinci_mdio.c
@@ -493,7 +493,7 @@ static int __init davinci_mdio_init(void)
 {
 	return platform_driver_register(&davinci_mdio_driver);
 }
-device_initcall(davinci_mdio_init);
+annotated_initcall(device, davinci_mdio_init, davinci_mdio_driver.driver);
 
 static void __exit davinci_mdio_exit(void)
 {
diff --git a/drivers/phy/phy-twl4030-usb.c b/drivers/phy/phy-twl4030-usb.c
index 3a707dd..b3bba7a 100644
--- a/drivers/phy/phy-twl4030-usb.c
+++ b/drivers/phy/phy-twl4030-usb.c
@@ -801,7 +801,7 @@ static int __init twl4030_usb_init(void)
 {
 	return platform_driver_register(&twl4030_usb_driver);
 }
-subsys_initcall(twl4030_usb_init);
+annotated_initcall(subsys, twl4030_usb_init, twl4030_usb_driver.driver);
 
 static void __exit twl4030_usb_exit(void)
 {
diff --git a/drivers/regulator/twl-regulator.c b/drivers/regulator/twl-regulator.c
index 955a6fb..356066b 100644
--- a/drivers/regulator/twl-regulator.c
+++ b/drivers/regulator/twl-regulator.c
@@ -1229,7 +1229,7 @@ static int __init twlreg_init(void)
 {
 	return platform_driver_register(&twlreg_driver);
 }
-subsys_initcall(twlreg_init);
+annotated_initcall(subsys, twlreg_init, twlreg_driver.driver);
 
 static void __exit twlreg_exit(void)
 {
diff --git a/drivers/tty/serial/omap-serial.c b/drivers/tty/serial/omap-serial.c
index 7a2172b..b78b4d7 100644
--- a/drivers/tty/serial/omap-serial.c
+++ b/drivers/tty/serial/omap-serial.c
@@ -1889,7 +1889,7 @@ static void __exit serial_omap_exit(void)
 	uart_unregister_driver(&serial_omap_reg);
 }
 
-module_init(serial_omap_init);
+annotated_module_init(serial_omap_init, serial_omap_driver.driver);
 module_exit(serial_omap_exit);
 
 MODULE_DESCRIPTION("OMAP High Speed UART driver");
diff --git a/drivers/usb/host/ehci-omap.c b/drivers/usb/host/ehci-omap.c
index a24720b..1e4076d 100644
--- a/drivers/usb/host/ehci-omap.c
+++ b/drivers/usb/host/ehci-omap.c
@@ -310,7 +310,7 @@ static int __init ehci_omap_init(void)
 	ehci_init_driver(&ehci_omap_hc_driver, &ehci_omap_overrides);
 	return platform_driver_register(&ehci_hcd_omap_driver);
 }
-module_init(ehci_omap_init);
+annotated_module_init(ehci_omap_init, ehci_hcd_omap_driver.driver);
 
 static void __exit ehci_omap_cleanup(void)
 {
diff --git a/drivers/usb/host/ohci-omap3.c b/drivers/usb/host/ohci-omap3.c
index ec15aeb..bcb1a1b 100644
--- a/drivers/usb/host/ohci-omap3.c
+++ b/drivers/usb/host/ohci-omap3.c
@@ -197,7 +197,7 @@ static int __init ohci_omap3_init(void)
 	ohci_init_driver(&ohci_omap3_hc_driver, NULL);
 	return platform_driver_register(&ohci_hcd_omap3_driver);
 }
-module_init(ohci_omap3_init);
+annotated_module_init(ohci_omap3_init, ohci_hcd_omap3_driver.driver);
 
 static void __exit ohci_omap3_cleanup(void)
 {
diff --git a/drivers/usb/musb/omap2430.c b/drivers/usb/musb/omap2430.c
index 70f2b8a..6a13f0b 100644
--- a/drivers/usb/musb/omap2430.c
+++ b/drivers/usb/musb/omap2430.c
@@ -725,7 +725,7 @@ static int __init omap2430_init(void)
 {
 	return platform_driver_register(&omap2430_driver);
 }
-subsys_initcall(omap2430_init);
+annotated_initcall(subsys, omap2430_init, omap2430_driver.driver);
 
 static void __exit omap2430_exit(void)
 {
-- 
2.1.0



From linus.walleij at linaro.org  Wed Aug 26 05:41:37 2015
From: linus.walleij at linaro.org (Linus Walleij)
Date: Wed, 26 Aug 2015 14:41:37 +0200
Subject: [PATCH v4] pinctrl: mediatek: Implement wake handler and suspend
 resume
In-Reply-To: <1439541486-22203-1-git-send-email-maoguang.meng@mediatek.com>
References: <1439541486-22203-1-git-send-email-maoguang.meng@mediatek.com>
Message-ID: <CACRpkdad3iQ89CtUyybAiz7pgNV8cuFKm=z93UAAhJXJJBt15Q@mail.gmail.com>

On Fri, Aug 14, 2015 at 10:38 AM,  <maoguang.meng at mediatek.com> wrote:

> From: Maoguang Meng <maoguang.meng at mediatek.com>
>
> This patch implement irq_set_wake to get who is wakeup source and
> setup on suspend resume.
>
> Signed-off-by: Maoguang Meng <maoguang.meng at mediatek.com>
>
> ---
> changes since v3:
> -add a comment in mtk_eint_chip_read_mask.
> -delete ALIGN when allocate eint_offsets.ports.
> -fix unrelated change.

Patch applied with Daniel's, Yingjoe's and Hongzhu's tags.

Yours,
Linus Walleij


From linus.walleij at linaro.org  Wed Aug 26 05:47:37 2015
From: linus.walleij at linaro.org (Linus Walleij)
Date: Wed, 26 Aug 2015 14:47:37 +0200
Subject: [PATCH] gpio: vf610: handle level IRQ's properly
In-Reply-To: <1440197802-29720-1-git-send-email-stefan@agner.ch>
References: <1440197802-29720-1-git-send-email-stefan@agner.ch>
Message-ID: <CACRpkdYqU_yvZE4WS2jBDOhemPy7dcHeOoj_dG61hCL8ugTMYg@mail.gmail.com>

On Sat, Aug 22, 2015 at 12:56 AM, Stefan Agner <stefan at agner.ch> wrote:

> The GPIO IRQ controller is able to generate level triggered
> interrupts, however, these were handled by handle_simple_irq so far
> which did not take care of IRQ masking. This lead to "nobody cared
> (try booting with the "irqpoll" option)" stack traces.
>
> Use the generic interrupt handlers depending on the IRQ type.
>
> Signed-off-by: Stefan Agner <stefan at agner.ch>

Patch applied.

Hm, this looks like a problem that could exist in a few more
GPIO drivers. Can you look around and see if there is something
immediately suspicious in drivers/gpio?

Yours,
Linus Walleij


From cyrille.pitchen at atmel.com  Wed Aug 26 05:30:26 2015
From: cyrille.pitchen at atmel.com (Cyrille Pitchen)
Date: Wed, 26 Aug 2015 14:30:26 +0200
Subject: [PATCH linux-next v5 4/5] Documentation: atmel-quadspi: add binding
 file for Atmel QSPI driver
In-Reply-To: <cover.1440580764.git.cyrille.pitchen@atmel.com>
References: <cover.1440580764.git.cyrille.pitchen@atmel.com>
Message-ID: <793cb906c79eed821cf9b47e79dc1b54a7a5dbd0.1440580764.git.cyrille.pitchen@atmel.com>

This patch documents the DT bindings for the driver of the Atmel QSPI
controller embedded inside sama5d2x SoCs.

Signed-off-by: Cyrille Pitchen <cyrille.pitchen at atmel.com>
Acked-by: Nicolas Ferre <nicolas.ferre at atmel.com>
Acked-by: Marek Vasut <marex at denx.de>
---
 .../devicetree/bindings/mtd/atmel-quadspi.txt      | 29 ++++++++++++++++++++++
 1 file changed, 29 insertions(+)
 create mode 100644 Documentation/devicetree/bindings/mtd/atmel-quadspi.txt

diff --git a/Documentation/devicetree/bindings/mtd/atmel-quadspi.txt b/Documentation/devicetree/bindings/mtd/atmel-quadspi.txt
new file mode 100644
index 000000000000..0b8d545bb198
--- /dev/null
+++ b/Documentation/devicetree/bindings/mtd/atmel-quadspi.txt
@@ -0,0 +1,29 @@
+* Atmel Quad Serial Peripheral Interface (QSPI)
+
+Required properties:
+- compatible:     should be "atmel,sama5d2-qspi"
+- reg:            the first contains the register location and length,
+                  the second contains the memory mapping address and length
+- interrupts:     should contain the interrupt for the device
+- clocks:         the phandle of the clock needed by the QSPI controller
+- #address-cells: should be <1>
+- #size-cells:    should be <0>
+
+Example:
+
+spi at f0020000 {
+	compatible = "atmel,sama5d2-qspi";
+	reg = <0xf0020000 0x100>,
+	      <0xd0000000 0x8000000>;
+	interrupts = <52 IRQ_TYPE_LEVEL_HIGH 7>;
+	clocks = <&spi0_clk>;
+	#address-cells = <1>;
+	#size-cells = <0>;
+	pinctrl-names = "default";
+	pinctrl-0 = <&pinctrl_spi0_default>;
+	status = "okay";
+
+	m25p80 at 0 {
+		...
+	};
+};
-- 
1.8.2.2



From arnd at arndb.de  Wed Aug 26 05:52:45 2015
From: arnd at arndb.de (Arnd Bergmann)
Date: Wed, 26 Aug 2015 14:52:45 +0200
Subject: [PATCH 1/3] ARM: uniphier: add outer cache support
In-Reply-To: <CAK7LNAQ_oymnQNEcP+FDqyxNKtMyiCwgxSRMmg5HAKQW9C6eRg@mail.gmail.com>
References: <1440382692-3855-1-git-send-email-yamada.masahiro@socionext.com>
 <2021253.vgeYqalDfp@wuerfel>
 <CAK7LNAQ_oymnQNEcP+FDqyxNKtMyiCwgxSRMmg5HAKQW9C6eRg@mail.gmail.com>
Message-ID: <4027826.UsiXogeDbt@wuerfel>

On Wednesday 26 August 2015 10:38:59 Masahiro Yamada wrote:
> 
> 2015-08-25 4:59 GMT+09:00 Arnd Bergmann <arnd at arndb.de>:
> > On Monday 24 August 2015 11:18:10 Masahiro Yamada wrote:

> Nothing.
> 
> This outer cache is not a variant of l2x0/pl310.
> It was designed only for our SoCs from scratch.

Ok, I see.

> > Would it make sense to at least share the
> > common entry point at l2x0_of_init() so you don't need to call it from
> > the platform file?
> 
> I do not think so.
> 
> 
> l2x0_of_init() checks L2X0_AUX_CTRL register,
> but the cache-uniphier does not have such register,
> so the boot code crashes.
> 
> 
> 
> BTW, what makes l2x0_of_init() so special?
> 
> Only L2x0/L310 and variants can be initialized
> directly from init_IRQ().

The only thing that is special about it is that almost everyone
uses it because it is often licensed together with the Cortex-A
cores from ARM. There are a few variants that are closely related
(tauros3 and aurora, both from Marvell. All other outer_cache
implementations (feroceon, xscale, tauros2) are for older
Marvell (or Intel) cores that have since been replaced with
Cortex-A cores in newer products.

> Moreover, outer-cache init seems to be unrelated to
> IRQ init.

Agreed, this is also just a historic artifact, as we don't really
have a place to put cache controller initialization, and the
irq init callback was already there at the time when people
added code to init their outer caches. It often does not matter
much where you call it, but doing it early speeds up the boot
time.

It would be nice to unify the cache initialization a bit further,
apparently only a few older platforms still call the l2x0 init
manually and we can probably all convert them to the implicit
configuration in one way or another.

As we now have three kinds of cache controllers (l2x0, tauros2
and uniphier) that we need to support using DT, it would be nice
for generalize that init sequence a bit more.

A first step would be to add the tauros2 and uniphier outer cache
init to the init_IRQ() function, and then have another patch
that moves all the outercache initialization into a new place
like arch/arm/mm/outercache.c so we don't clutter up irq.c
with unrelated stuff.

Russell probably also has some ideas on this topic, in doubt
just do what he suggests.

	Arnd


From lee.jones at linaro.org  Wed Aug 26 06:08:02 2015
From: lee.jones at linaro.org (Lee Jones)
Date: Wed, 26 Aug 2015 14:08:02 +0100
Subject: [PATCH 3/4] ARM: STiH407: Add nodes for RemoteProc
In-Reply-To: <1440594483-29601-1-git-send-email-lee.jones@linaro.org>
References: <1440594483-29601-1-git-send-email-lee.jones@linaro.org>
Message-ID: <1440594483-29601-4-git-send-email-lee.jones@linaro.org>

Signed-off-by: Lee Jones <lee.jones at linaro.org>
---
 arch/arm/boot/dts/stih407-family.dtsi | 48 +++++++++++++++++++++++++++++++++++
 1 file changed, 48 insertions(+)

diff --git a/arch/arm/boot/dts/stih407-family.dtsi b/arch/arm/boot/dts/stih407-family.dtsi
index 33daa49..89a363c 100644
--- a/arch/arm/boot/dts/stih407-family.dtsi
+++ b/arch/arm/boot/dts/stih407-family.dtsi
@@ -608,5 +608,53 @@
 			status		= "okay";
 			tx-only;
 		};
+
+		st231_gp0: st231-gp0 at 0 {
+			compatible = "st,st231-rproc";
+			reg = <0x40000000 0x01000000>;
+			reg-names = "carveout";
+			resets = <&softreset STIH407_ST231_GP0_SOFTRESET>;
+			reset-names = "sw_reset";
+			clocks = <&clk_s_c0_flexgen CLK_ST231_GP_0>;
+			clock-names = "rproc_clk";
+			clock-frequency = <600000000>;
+			st,syscfg-boot = <&syscfg_core 0x22C>;
+		};
+
+		st231_gp1: st231-gp1 at 0 {
+			compatible = "st,st231-rproc";
+			reg = <0x41000000 0x01000000>;
+			reg-names = "carveout";
+			resets = <&softreset STIH407_ST231_GP1_SOFTRESET>;
+			reset-names = "sw_reset";
+			clocks = <&clk_s_c0_flexgen CLK_ST231_GP_1>;
+			clock-names = "rproc_clk";
+			clock-frequency = <600000000>;
+			st,syscfg-boot = <&syscfg_core 0x220>;
+		};
+
+		st231_audio: st231-audio at 0 {
+			compatible = "st,st231-rproc";
+			reg = <0x42000000 0x01000000>;
+			reg-names = "carveout";
+			resets = <&softreset STIH407_ST231_AUD_SOFTRESET>;
+			reset-names = "sw_reset";
+			clocks = <&clk_s_c0_flexgen CLK_ST231_AUD_0>;
+			clock-names = "rproc_clk";
+			clock-frequency = <600000000>;
+			st,syscfg-boot = <&syscfg_core 0x228>;
+		};
+
+		st231_dmu: st231-dmu at 0 {
+			compatible = "st,st231-rproc";
+			reg = <0x43000000 0x01000000>;
+			reg-names = "carveout";
+			resets = <&softreset STIH407_ST231_DMU_SOFTRESET>;
+			reset-names = "sw_reset";
+			clocks = <&clk_s_c0_flexgen CLK_ST231_DMU>;
+			clock-names = "rproc_clk";
+			clock-frequency = <600000000>;
+			st,syscfg-boot = <&syscfg_core 0x224>;
+		};
 	};
 };
-- 
1.9.1



From lee.jones at linaro.org  Wed Aug 26 06:07:59 2015
From: lee.jones at linaro.org (Lee Jones)
Date: Wed, 26 Aug 2015 14:07:59 +0100
Subject: [PATCH 0/4] remoteproc: Add driver for STMicroelectronics platforms
Message-ID: <1440594483-29601-1-git-send-email-lee.jones@linaro.org>

ST's platforms often have multiple co-processors (usually ST40s or ST231s)
on-board.  This provides the Linux-side infrastructure to flash and boot
them successfully.

This set has been tested on an STiH410-B2120.

Lee Jones (4):
  remoteproc: dt: Provide bindings for ST's Remote Processor Controller
    driver
  remoteproc: Supply controller driver for ST's Remote Processors
  ARM: STiH407: Add nodes for RemoteProc
  remoteproc: debugfs: Add ability to boot remote processor using
    debugfs

 .../devicetree/bindings/remoteproc/st-rproc.txt    |  38 +++
 arch/arm/boot/dts/stih407-family.dtsi              |  48 ++++
 drivers/remoteproc/Kconfig                         |   9 +
 drivers/remoteproc/Makefile                        |   1 +
 drivers/remoteproc/remoteproc_debugfs.c            |  25 ++
 drivers/remoteproc/st_remoteproc.c                 | 300 +++++++++++++++++++++
 6 files changed, 421 insertions(+)
 create mode 100644 Documentation/devicetree/bindings/remoteproc/st-rproc.txt
 create mode 100644 drivers/remoteproc/st_remoteproc.c

-- 
1.9.1



From lee.jones at linaro.org  Wed Aug 26 06:08:00 2015
From: lee.jones at linaro.org (Lee Jones)
Date: Wed, 26 Aug 2015 14:08:00 +0100
Subject: [PATCH 1/4] remoteproc: dt: Provide bindings for ST's Remote
 Processor Controller driver
In-Reply-To: <1440594483-29601-1-git-send-email-lee.jones@linaro.org>
References: <1440594483-29601-1-git-send-email-lee.jones@linaro.org>
Message-ID: <1440594483-29601-2-git-send-email-lee.jones@linaro.org>

Signed-off-by: Lee Jones <lee.jones at linaro.org>
---
 .../devicetree/bindings/remoteproc/st-rproc.txt    | 38 ++++++++++++++++++++++
 1 file changed, 38 insertions(+)
 create mode 100644 Documentation/devicetree/bindings/remoteproc/st-rproc.txt

diff --git a/Documentation/devicetree/bindings/remoteproc/st-rproc.txt b/Documentation/devicetree/bindings/remoteproc/st-rproc.txt
new file mode 100644
index 0000000..6a933c1
--- /dev/null
+++ b/Documentation/devicetree/bindings/remoteproc/st-rproc.txt
@@ -0,0 +1,38 @@
+STMicroelectronics Remote Processor
+-----------------------------------
+
+This binding provides support for adjunct processors found on ST SoCs.
+
+The remote processors can be controlled from the bootloader or the primary OS.
+If the bootloader starts a remote processor processor the primary OS must detect
+its state and act accordingly.
+
+The node name is significant, as it defines the name of the CPU and the name
+of the firmware to load: "rproc-<name>-fw".
+
+Required properties:
+- compatible		Should be one of:
+				"st,st231-rproc"
+				"st,st40-rproc"
+- reg			Size and length of reserved co-processor memory
+- resets		Reset lines (See: ../reset/reset.txt)
+- reset-names		Must be "sw_reset" and "pwr_reset"
+- clocks		Clock for co-processor (See: ../clock/clock-bindings.txt)
+- clock-names		Must be "rproc_clk"
+- clock-frequency	Clock frequency to set co-processor at if the bootloader
+			hasn't already done so
+- st,syscfg-boot	The register that holds the boot vector for the co-processor
+
+Example:
+
+	st231-audio at bae00000 {
+		compatible	= "st,st231-rproc";
+		reg		= <0xbae00000 0x01000000>;
+		reg-names	= "rproc_mem";
+		resets		= <&softreset STIH407_ST231_AUD_SOFTRESET>;
+		reset-names	= "sw_reset";
+		clocks		= <&clk_s_c0_flexgen CLK_ST231_AUD_0>;
+		clock-names	= "rproc_clk";
+		clock-frequency	= <600000000>;
+		st,syscfg-boot	= <&syscfg_core 0x228>;
+	};
-- 
1.9.1



From lee.jones at linaro.org  Wed Aug 26 06:08:01 2015
From: lee.jones at linaro.org (Lee Jones)
Date: Wed, 26 Aug 2015 14:08:01 +0100
Subject: [PATCH 2/4] remoteproc: Supply controller driver for ST's Remote
 Processors
In-Reply-To: <1440594483-29601-1-git-send-email-lee.jones@linaro.org>
References: <1440594483-29601-1-git-send-email-lee.jones@linaro.org>
Message-ID: <1440594483-29601-3-git-send-email-lee.jones@linaro.org>

Signed-off-by: Lee Jones <lee.jones at linaro.org>
---
 drivers/remoteproc/Kconfig         |   9 ++
 drivers/remoteproc/Makefile        |   1 +
 drivers/remoteproc/st_remoteproc.c | 300 +++++++++++++++++++++++++++++++++++++
 3 files changed, 310 insertions(+)
 create mode 100644 drivers/remoteproc/st_remoteproc.c

diff --git a/drivers/remoteproc/Kconfig b/drivers/remoteproc/Kconfig
index 28c711f..72e97d7 100644
--- a/drivers/remoteproc/Kconfig
+++ b/drivers/remoteproc/Kconfig
@@ -77,4 +77,13 @@ config DA8XX_REMOTEPROC
 	  It's safe to say n here if you're not interested in multimedia
 	  offloading.
 
+config ST_REMOTEPROC
+	tristate "ST remoteproc support"
+	depends on ARCH_STI
+	select REMOTEPROC
+	help
+	  Say y here to support ST's adjunct processors via the remote
+	  processor framework.
+	  This can be either built-in or a loadable module.
+
 endmenu
diff --git a/drivers/remoteproc/Makefile b/drivers/remoteproc/Makefile
index 81b04d1..279cb2e 100644
--- a/drivers/remoteproc/Makefile
+++ b/drivers/remoteproc/Makefile
@@ -11,3 +11,4 @@ obj-$(CONFIG_OMAP_REMOTEPROC)		+= omap_remoteproc.o
 obj-$(CONFIG_STE_MODEM_RPROC)	 	+= ste_modem_rproc.o
 obj-$(CONFIG_WKUP_M3_RPROC)		+= wkup_m3_rproc.o
 obj-$(CONFIG_DA8XX_REMOTEPROC)		+= da8xx_remoteproc.o
+obj-$(CONFIG_ST_REMOTEPROC)		+= st_remoteproc.o
diff --git a/drivers/remoteproc/st_remoteproc.c b/drivers/remoteproc/st_remoteproc.c
new file mode 100644
index 0000000..7afcfaf
--- /dev/null
+++ b/drivers/remoteproc/st_remoteproc.c
@@ -0,0 +1,300 @@
+/*
+ * ST's Remote Processor Control Driver
+ *
+ * Copyright (C) 2015 STMicroelectronics - All Rights Reserved
+ *
+ * Author: Ludovic Barre <ludovic.barre at st.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.
+ */
+
+#include <linux/clk.h>
+#include <linux/dma-mapping.h>
+#include <linux/err.h>
+#include <linux/interrupt.h>
+#include <linux/kernel.h>
+#include <linux/mfd/syscon.h>
+#include <linux/module.h>
+#include <linux/of.h>
+#include <linux/of_device.h>
+#include <linux/platform_device.h>
+#include <linux/regmap.h>
+#include <linux/remoteproc.h>
+#include <linux/reset.h>
+
+struct st_rproc_config {
+	bool			sw_reset;
+	bool			pwr_reset;
+	u32			bootaddr_mask;
+};
+
+struct st_rproc {
+	struct st_rproc_config	*config;
+	struct reset_control	*sw_reset;
+	struct reset_control	*pwr_reset;
+	struct clk		*clk;
+	u32			clk_rate;
+	struct	regmap		*boot_base;
+	u32			boot_offset;
+};
+
+static int st_rproc_stop(struct rproc *rproc)
+{
+	struct st_rproc *st_rproc = rproc->priv;
+	int err = 0;
+
+	if (st_rproc->config->sw_reset) {
+		err = reset_control_assert(st_rproc->sw_reset);
+		if (err)
+			dev_warn(&rproc->dev, "Failed to assert S/W Reset\n");
+	}
+
+	if (st_rproc->config->pwr_reset) {
+		err = reset_control_assert(st_rproc->pwr_reset);
+		if (err)
+			dev_warn(&rproc->dev, "Failed to assert Power Reset\n");
+	}
+
+	clk_disable(st_rproc->clk);
+
+	return 0;
+}
+
+static int st_rproc_start(struct rproc *rproc)
+{
+	struct st_rproc *st_rproc = rproc->priv;
+	int err;
+
+	regmap_update_bits(st_rproc->boot_base, st_rproc->boot_offset,
+			   st_rproc->config->bootaddr_mask, rproc->bootaddr);
+
+	err = clk_enable(st_rproc->clk);
+	if (err) {
+		dev_err(&rproc->dev, "Failed to enable clock\n");
+		return err;
+	}
+
+	if (st_rproc->config->sw_reset) {
+		err = reset_control_deassert(st_rproc->sw_reset);
+		if (err) {
+			dev_err(&rproc->dev, "Failed to deassert S/W Reset\n");
+			return err;
+		}
+	}
+
+	if (st_rproc->config->pwr_reset) {
+		err = reset_control_deassert(st_rproc->pwr_reset);
+		if (err) {
+			dev_err(&rproc->dev, "Failed to deassert Power Reset\n");
+			return err;
+		}
+	}
+
+	dev_info(&rproc->dev, "Started from 0x%x\n", rproc->bootaddr);
+
+	return 0;
+}
+
+static struct rproc_ops st_rproc_ops = {
+	.start		= st_rproc_start,
+	.stop		= st_rproc_stop,
+};
+
+/*
+ * Fetch state of the processor: 0 is off, 1 is on.
+ */
+static int st_rproc_state(struct st_rproc *st_rproc)
+{
+	int reset_sw, reset_pwr;
+
+	reset_sw = st_rproc->config->sw_reset ?
+		reset_control_status(st_rproc->sw_reset) : 0;
+
+	reset_pwr = st_rproc->config->pwr_reset ?
+		reset_control_status(st_rproc->pwr_reset) : 0;
+
+	if (reset_sw < 0 || reset_pwr < 0)
+		return -EINVAL;
+
+	return !reset_sw && !reset_pwr;
+}
+
+static const struct st_rproc_config st40_rproc_cfg = {
+	.sw_reset = true,
+	.pwr_reset = true,
+	.bootaddr_mask = GENMASK(28, 1),
+};
+
+static const struct st_rproc_config st231_rproc_cfg = {
+	.sw_reset = true,
+	.pwr_reset = false,
+	.bootaddr_mask = GENMASK(31, 6),
+};
+
+static struct of_device_id st_rproc_match[] = {
+	{ .compatible = "st,st40-rproc", .data = &st40_rproc_cfg },
+	{ .compatible = "st,st231-rproc", .data = &st231_rproc_cfg },
+	{},
+};
+MODULE_DEVICE_TABLE(of, st_rproc_match);
+
+static int st_rproc_parse_dt(struct platform_device *pdev)
+{
+	struct device *dev = &pdev->dev;
+	struct rproc *rproc = platform_get_drvdata(pdev);
+	struct st_rproc *st_rproc = rproc->priv;
+	struct device_node *np = dev->of_node;
+	struct resource	*mem;
+	int err;
+
+	if (st_rproc->config->sw_reset) {
+		st_rproc->sw_reset = devm_reset_control_get(dev, "sw_reset");
+		if (IS_ERR(st_rproc->sw_reset)) {
+			dev_err(dev, "Failed to get S/W Reset\n");
+			return PTR_ERR(st_rproc->sw_reset);
+		}
+	}
+
+	if (st_rproc->config->pwr_reset) {
+		st_rproc->pwr_reset = devm_reset_control_get(dev, "pwr_reset");
+		if (IS_ERR(st_rproc->pwr_reset)) {
+			dev_err(dev, "Failed to get Power Reset\n");
+			return PTR_ERR(st_rproc->pwr_reset);
+		}
+	}
+
+	st_rproc->clk = devm_clk_get(dev, "rproc_clk");
+	if (IS_ERR(st_rproc->clk)) {
+		dev_err(dev, "Failed to get clock\n");
+		return PTR_ERR(st_rproc->clk);
+	}
+
+	err = of_property_read_u32(np, "clock-frequency", &st_rproc->clk_rate);
+	if (err) {
+		dev_err(dev, "failed to get clock frequency\n");
+		return err;
+	}
+
+
+	st_rproc->boot_base =
+		syscon_regmap_lookup_by_phandle(np, "st,syscfg-boot");
+	if (!st_rproc->boot_base) {
+		dev_err(dev, "Boot base not found\n");
+		return -EINVAL;
+	}
+
+	err = of_property_read_u32_index(np, "st,syscfg-boot", 1,
+					 &st_rproc->boot_offset);
+	if (err) {
+		dev_err(dev, "Boot offset not found\n");
+		return -EINVAL;
+	}
+
+	mem = platform_get_resource_byname(pdev, IORESOURCE_MEM, "carveout");
+	if (!mem) {
+		dev_err(dev, "no rproc memory definition\n");
+		return -ENXIO;
+	}
+
+	if (!devm_request_mem_region(dev, mem->start,
+				     resource_size(mem), pdev->name)) {
+		dev_err(dev, "failed to get memory region resource\n");
+		return -EBUSY;
+	}
+	err = dmam_declare_coherent_memory(dev, mem->start, mem->start,
+					  resource_size(mem),
+					  DMA_MEMORY_MAP |
+					  DMA_MEMORY_EXCLUSIVE);
+	if (err < 0) {
+		dev_err(dev, "cannot declare coherent memory: %d\n", err);
+		return -ENXIO;
+	}
+
+	err = clk_prepare(st_rproc->clk);
+	if (err)
+		dev_err(dev, "failed to get clock\n");
+
+	return err;
+}
+
+static int st_rproc_probe(struct platform_device *pdev)
+{
+	struct device *dev = &pdev->dev;
+	const struct of_device_id *match;
+	struct st_rproc *st_rproc;
+	struct device_node *np = dev->of_node;
+	struct rproc *rproc;
+	int enabled;
+	int ret;
+
+	match = of_match_device((st_rproc_match), dev);
+	if (!match || !match->data) {
+		dev_err(dev, "No device match found\n");
+		return -ENODEV;
+	}
+
+	rproc = rproc_alloc(dev, np->name, &st_rproc_ops,
+			    NULL, sizeof(*st_rproc));
+	if (!rproc)
+		return -ENOMEM;
+
+	st_rproc = rproc->priv;
+	st_rproc->config = (struct st_rproc_config *)match->data;
+	platform_set_drvdata(pdev, rproc);
+
+	ret = st_rproc_parse_dt(pdev);
+	if (ret)
+		goto free_rproc;
+
+	ret = st_rproc_state(st_rproc);
+	if (ret < 0)
+		goto free_rproc;
+	enabled = ret;
+
+	if (enabled) {
+		atomic_inc(&rproc->power);
+		rproc->state = RPROC_RUNNING;
+	} else {
+		clk_set_rate(st_rproc->clk, st_rproc->clk_rate);
+	}
+
+	ret = rproc_add(rproc);
+	if (ret)
+		goto free_rproc;
+
+	return 0;
+
+free_rproc:
+	rproc_put(rproc);
+	return ret;
+}
+
+static int st_rproc_remove(struct platform_device *pdev)
+{
+	struct rproc *rproc = platform_get_drvdata(pdev);
+	struct st_rproc *st_rproc = rproc->priv;
+
+	rproc_del(rproc);
+
+	clk_disable_unprepare(st_rproc->clk);
+
+	rproc_put(rproc);
+
+	return 0;
+}
+
+static struct platform_driver st_rproc_driver = {
+	.probe = st_rproc_probe,
+	.remove = st_rproc_remove,
+	.driver = {
+		.name = "st-rproc",
+		.of_match_table = of_match_ptr(st_rproc_match),
+	},
+};
+module_platform_driver(st_rproc_driver);
+
+MODULE_DESCRIPTION("ST Remote Processor Control Driver");
+MODULE_AUTHOR("Ludovic.barre <Ludovic.barre at st.com>");
+MODULE_LICENSE("GPL v2");
-- 
1.9.1



From lee.jones at linaro.org  Wed Aug 26 06:08:03 2015
From: lee.jones at linaro.org (Lee Jones)
Date: Wed, 26 Aug 2015 14:08:03 +0100
Subject: [PATCH 4/4] remoteproc: debugfs: Add ability to boot remote processor
 using debugfs
In-Reply-To: <1440594483-29601-1-git-send-email-lee.jones@linaro.org>
References: <1440594483-29601-1-git-send-email-lee.jones@linaro.org>
Message-ID: <1440594483-29601-5-git-send-email-lee.jones@linaro.org>

Signed-off-by: Lee Jones <lee.jones at linaro.org>
---
 drivers/remoteproc/remoteproc_debugfs.c | 25 +++++++++++++++++++++++++
 1 file changed, 25 insertions(+)

diff --git a/drivers/remoteproc/remoteproc_debugfs.c b/drivers/remoteproc/remoteproc_debugfs.c
index 9d30809..9620962 100644
--- a/drivers/remoteproc/remoteproc_debugfs.c
+++ b/drivers/remoteproc/remoteproc_debugfs.c
@@ -88,8 +88,33 @@ static ssize_t rproc_state_read(struct file *filp, char __user *userbuf,
 	return simple_read_from_buffer(userbuf, count, ppos, buf, i);
 }
 
+static ssize_t rproc_state_write(struct file *filp, const char __user *userbuf,
+				 size_t count, loff_t *ppos)
+{
+	struct rproc *rproc = filp->private_data;
+	char buf[2];
+	int ret;
+
+	ret = copy_from_user(buf, userbuf, 1);
+	if (ret)
+		return -EFAULT;
+
+	switch (buf[0]) {
+	case '1':
+		ret = rproc_boot(rproc);
+		if (ret)
+			dev_warn(&rproc->dev, "Boot failed: %d\n", ret);
+		break;
+	default:
+		rproc_shutdown(rproc);
+	}
+
+	return count;
+}
+
 static const struct file_operations rproc_state_ops = {
 	.read = rproc_state_read,
+	.write = rproc_state_write,
 	.open = simple_open,
 	.llseek	= generic_file_llseek,
 };
-- 
1.9.1



From lftan at altera.com  Wed Aug 26 06:18:58 2015
From: lftan at altera.com (Ley Foon Tan)
Date: Wed, 26 Aug 2015 21:18:58 +0800
Subject: [PATCH v5 2/5] pci:host: Add Altera PCIe host controller driver
In-Reply-To: <55DC5406.3080703@arm.com>
References: <1440495348-2666-1-git-send-email-lftan@altera.com>
 <1440495348-2666-3-git-send-email-lftan@altera.com>
 <55DC5406.3080703@arm.com>
Message-ID: <CAFiDJ5_A0jO5aBXGDMpm8QCizNbWpvHp+v_v3f4p86wrrA96Vg@mail.gmail.com>

On Tue, Aug 25, 2015 at 7:39 PM, Marc Zyngier <marc.zyngier at arm.com> wrote:
>

> > +
> > +static void altera_pcie_retrain(struct pci_dev *dev)
> > +{
> > +     u16 linkcap, linkstat;
> > +
> > +     /*
> > +      * Set the retrain bit if the PCIe rootport support > 2.5GB/s, but
> > +      * current speed is 2.5 GB/s.
> > +      */
> > +     pcie_capability_read_word(dev, PCI_EXP_LNKCAP, &linkcap);
> > +
> > +     if ((linkcap & PCI_EXP_LNKCAP_SLS) <= PCI_EXP_LNKCAP_SLS_2_5GB)
> > +             return;
> > +
> > +     pcie_capability_read_word(dev, PCI_EXP_LNKSTA, &linkstat);
> > +     if ((linkstat & PCI_EXP_LNKSTA_CLS) == PCI_EXP_LNKSTA_CLS_2_5GB)
> > +             pcie_capability_set_word(dev, PCI_EXP_LNKCTL,
> > +                                      PCI_EXP_LNKCTL_RL);
> > +}
> > +DECLARE_PCI_FIXUP_EARLY(PCI_ANY_ID, PCI_ANY_ID, altera_pcie_retrain);
>
> Do I read this correctly? This function is being called on any PCI
> device, without any filtering? What if the platform is not using this
> driver despite the driver being compiled in?
Will change it to Altera vendor ID.

>
> > +
> > +static void altera_pcie_fixup_res(struct pci_dev *dev)
> > +{
> > +     /*
> > +      * Prevent enumeration of root port.
> > +      */
> > +     if (!dev->bus->parent && dev->devfn == 0) {
> > +             int i;
> > +
> > +             for (i = 0; i < PCI_NUM_RESOURCES; i++) {
> > +                     dev->resource[i].start = 0;
> > +                     dev->resource[i].end   = 0;
> > +                     dev->resource[i].flags   = 0;
> > +             }
> > +     }
> > +}
> > +DECLARE_PCI_FIXUP_HEADER(PCI_ANY_ID, PCI_ANY_ID, altera_pcie_fixup_res);
>
> Same here. I also question the validity of nuking the resources, but I'm
> not a PCI expert.
We want to hide the host BARs from kernel as their content doesn't fix
well in the resource management and cause the pci enumeration failed.
Some other controllers also using same way to hide the host BARs resources.
>
> > +
> > +static inline void cra_writel(struct altera_pcie *pcie, u32 value, u32 reg)
> > +{
> > +     writel_relaxed(value, pcie->cra_base + reg);
> > +}
> > +
> > +static inline u32 cra_readl(struct altera_pcie *pcie, u32 reg)
> > +{
> > +     return readl_relaxed(pcie->cra_base + reg);
> > +}
> > +
> > +static void tlp_read_rx(struct altera_pcie *pcie,
> > +                     struct tlp_rp_regpair_t *tlp_rp_regdata)
> > +{
> > +     tlp_rp_regdata->ctrl = cra_readl(pcie, RP_RXCPL_STATUS);
> > +     tlp_rp_regdata->reg0 = cra_readl(pcie, RP_RXCPL_REG0);
> > +     tlp_rp_regdata->reg1 = cra_readl(pcie, RP_RXCPL_REG1);
> > +}
> > +
> > +static void tlp_write_tx(struct altera_pcie *pcie,
> > +                      struct tlp_rp_regpair_t *tlp_rp_regdata)
> > +{
> > +     cra_writel(pcie, tlp_rp_regdata->reg0, RP_TX_REG0);
> > +     cra_writel(pcie, tlp_rp_regdata->reg1, RP_TX_REG1);
> > +     cra_writel(pcie, tlp_rp_regdata->ctrl, RP_TX_CNTRL);
> > +}
> > +
> > +static bool altera_pcie_link_is_up(struct altera_pcie *pcie)
> > +{
> > +     return !!(cra_readl(pcie, RP_LTSSM) & LTSSM_L0);
> > +}
> > +
> > +static bool altera_pcie_valid_config(struct altera_pcie *pcie,
> > +                                  struct pci_bus *bus, int dev)
> > +{
> > +     /* If there is no link, then there is no device */
> > +     if (bus->number != pcie->root_bus_nr) {
> > +             if (!altera_pcie_link_is_up(pcie))
> > +                     return false;
> > +     }
> > +
> > +     /* access only one slot on each root port */
> > +     if (bus->number == pcie->root_bus_nr && dev > 0)
> > +             return false;
> > +
> > +     /*
> > +      * Do not read more than one device on the bus directly attached
> > +      * to RC.
> > +      */
> > +     if (bus->primary == pcie->root_bus_nr && dev > 0)
> > +             return false;
> > +
> > +      return true;
> > +}
> > +
> > +static int tlp_read_packet(struct altera_pcie *pcie, u32 *value)
> > +{
> > +     u8 loop;
> > +     struct tlp_rp_regpair_t tlp_rp_regdata;
> > +
> > +     for (loop = 0; loop < TLP_LOOP; loop++) {
> > +             tlp_read_rx(pcie, &tlp_rp_regdata);
> > +             if (tlp_rp_regdata.ctrl & RP_RXCPL_EOP) {
> > +                     if (value)
> > +                             *value = tlp_rp_regdata.reg0;
> > +                     return PCIBIOS_SUCCESSFUL;
> > +             }
> > +             udelay(5);
> > +     }
> > +
> > +     return -ENOENT;
> > +}
> > +
> > +static void tlp_write_packet_unaligned(struct altera_pcie *pcie, u32 *headers,
> > +                                    u32 data)
> > +{
> > +     struct tlp_rp_regpair_t tlp_rp_regdata;
> > +
> > +     tlp_rp_regdata.reg0 = headers[0];
> > +     tlp_rp_regdata.reg1 = headers[1];
> > +     tlp_rp_regdata.ctrl = RP_TX_SOP;
> > +     tlp_write_tx(pcie, &tlp_rp_regdata);
> > +
> > +     tlp_rp_regdata.reg0 = headers[2];
> > +     tlp_rp_regdata.reg1 = data;
> > +     tlp_rp_regdata.ctrl = RP_TX_EOP;
> > +     tlp_write_tx(pcie, &tlp_rp_regdata);
> > +}
> > +
> > +static void tlp_write_packet_aligned(struct altera_pcie *pcie, u32 *headers,
> > +                                  u32 data)
> > +{
> > +     struct tlp_rp_regpair_t tlp_rp_regdata;
> > +
> > +     tlp_rp_regdata.reg0 = headers[0];
> > +     tlp_rp_regdata.reg1 = headers[1];
> > +     tlp_rp_regdata.ctrl = RP_TX_SOP;
> > +     tlp_write_tx(pcie, &tlp_rp_regdata);
> > +
> > +     tlp_rp_regdata.reg0 = headers[2];
> > +     tlp_rp_regdata.reg1 = 0;
> > +     tlp_rp_regdata.ctrl = 0;
> > +     tlp_write_tx(pcie, &tlp_rp_regdata);
> > +
> > +     tlp_rp_regdata.reg0 = data;
> > +     tlp_rp_regdata.reg1 = 0;
> > +     tlp_rp_regdata.ctrl = RP_TX_EOP;
> > +     tlp_write_tx(pcie, &tlp_rp_regdata);
> > +}
> > +
> > +static int tlp_cfg_dword_read(struct altera_pcie *pcie, u8 bus, u32 devfn,
> > +                           int where, u32 *value)
> > +{
> > +     int ret;
> > +     u32 headers[TLP_HDR_SIZE];
> > +
> > +     if (bus == pcie->root_bus_nr)
> > +             headers[0] = TLP_CFG_DW0(TLP_FMTTYPE_CFGRD0);
> > +     else
> > +             headers[0] = TLP_CFG_DW0(TLP_FMTTYPE_CFGRD1);
> > +
> > +     headers[1] = TLP_CFG_DW1(TLP_REQ_ID(pcie->root_bus_nr, devfn),
> > +                                     TLP_READ_TAG);
> > +     headers[2] = TLP_CFG_DW2(bus, devfn, where);
> > +
> > +     tlp_write_packet_unaligned(pcie, headers, 0);
> > +
> > +     ret = tlp_read_packet(pcie, value);
> > +     if (ret != PCIBIOS_SUCCESSFUL)
> > +             *value = ~0UL;  /* return 0xFFFFFFFF if error */
> > +
> > +     return ret;
> > +}
> > +
> > +static int tlp_cfg_dword_write(struct altera_pcie *pcie, u8 bus, u32 devfn,
> > +                            int where, u32 value)
> > +{
> > +     u32 headers[TLP_HDR_SIZE];
> > +     int ret;
> > +
> > +     if (bus == pcie->root_bus_nr)
> > +             headers[0] = TLP_CFG_DW0(TLP_FMTTYPE_CFGWR0);
> > +     else
> > +             headers[0] = TLP_CFG_DW0(TLP_FMTTYPE_CFGWR1);
> > +
> > +     headers[1] = TLP_CFG_DW1(TLP_REQ_ID(pcie->root_bus_nr, devfn),
> > +                                     TLP_WRITE_TAG);
> > +     headers[2] = TLP_CFG_DW2(bus, devfn, where);
> > +
> > +     /* check alignment to Qword */
> > +     if ((where & 0x7) == 0)
> > +             tlp_write_packet_aligned(pcie, headers, value);
> > +     else
> > +             tlp_write_packet_unaligned(pcie, headers, value);
> > +
> > +     ret = tlp_read_packet(pcie, NULL);
> > +     if (ret != PCIBIOS_SUCCESSFUL)
> > +             return ret;
> > +
> > +     /* Keep an eye out for changes to the root bus number */
> > +     if ((bus == pcie->root_bus_nr) && (where == PCI_PRIMARY_BUS))
> > +             pcie->root_bus_nr = (u8)(value);
> > +
> > +     return PCIBIOS_SUCCESSFUL;
> > +}
> > +
> > +static int altera_pcie_cfg_read(struct pci_bus *bus, unsigned int devfn,
> > +                             int where, int size, u32 *value)
> > +{
> > +     struct altera_pcie *pcie = bus->sysdata;
> > +     int ret;
> > +
> > +     if (!altera_pcie_valid_config(pcie, bus, PCI_SLOT(devfn))) {
> > +             *value = ~0UL;
> > +             return PCIBIOS_DEVICE_NOT_FOUND;
> > +     }
> > +
> > +     ret = tlp_cfg_dword_read(pcie, bus->number, devfn,
> > +                              (where & ~DWORD_MASK), value);
> > +     if (ret != PCIBIOS_SUCCESSFUL)
> > +             return ret;
> > +
> > +     if (size == 1)
> > +             *value = (*value >> (8 * (where & 0x3))) & 0xff;
> > +     else if (size == 2)
> > +             *value = (*value >> (8 * (where & 0x2))) & 0xffff;
>
> Please write this as a switch/case statement, with a default handling case.
Okay.

>
> > +
> > +     return PCIBIOS_SUCCESSFUL;
> > +}
> > +
> > +static int altera_pcie_cfg_write(struct pci_bus *bus, unsigned int devfn,
> > +                              int where, int size, u32 value)
> > +{
> > +     struct altera_pcie *pcie = bus->sysdata;
> > +     u32 data32 = value;
> > +     u32 shift = 8 * (where & 3);
> > +     int ret;
> > +
> > +     if (!altera_pcie_valid_config(pcie, bus, PCI_SLOT(devfn)))
> > +             return PCIBIOS_DEVICE_NOT_FOUND;
> > +
> > +     /* write partial */
> > +     if (size != sizeof(u32)) {
> > +             ret = tlp_cfg_dword_read(pcie, bus->number, devfn,
> > +                                      where & ~DWORD_MASK, &data32);
> > +             if (ret)
> > +                     return ret;
> > +
> > +             if (size == 2)
> > +                     data32 = (data32 & ~(0xffff << shift)) |
> > +                                     ((value & 0xffff) << shift);
> > +              else if (size == 1)
> > +                     data32 = (data32 & ~(0xff << shift)) |
> > +                                     ((value & 0xff) << shift);
>
> Same here.
Okay.

> > +     }
> > +
> > +     return tlp_cfg_dword_write(pcie, bus->number, devfn,
> > +             (where & ~DWORD_MASK), data32);
> > +}
> > +
> > +static struct pci_ops altera_pcie_ops = {
> > +     .read = altera_pcie_cfg_read,
> > +     .write = altera_pcie_cfg_write,
> > +};
> > +
> > +static int altera_pcie_intx_map(struct irq_domain *domain, unsigned int irq,
> > +                             irq_hw_number_t hwirq)
> > +{
> > +     irq_set_chip_and_handler(irq, &dummy_irq_chip, handle_simple_irq);
> > +     irq_set_chip_data(irq, domain->host_data);
> > +     set_irq_flags(irq, IRQF_VALID);
> > +
> > +     return 0;
> > +}
> > +
> > +static const struct irq_domain_ops intx_domain_ops = {
> > +     .map = altera_pcie_intx_map,
> > +};
> > +
> > +static void altera_pcie_isr(unsigned int irq, struct irq_desc *desc)
> > +{
> > +     struct irq_chip *chip = irq_desc_get_chip(desc);
> > +     struct altera_pcie *pcie;
> > +     unsigned long status;
> > +     u32 bit;
> > +     u32 virq;
> > +
> > +     chained_irq_enter(chip, desc);
> > +     pcie = irq_desc_get_handler_data(desc);
> > +
> > +     do {
> > +             status = cra_readl(pcie, P2A_INT_STATUS) & P2A_INT_STS_ALL;
> > +             if (!status)
> > +                     break;
> > +
> > +             do {
> > +                     bit = find_first_bit(&status, INTX_NUM);
> > +                     /* clear interrupts */
> > +                     cra_writel(pcie, 1 << bit, P2A_INT_STATUS);
> > +
> > +                     virq = irq_find_mapping(pcie->irq_domain, bit + 1);
> > +                     if (virq)
> > +                             generic_handle_irq(virq);
> > +                     else
> > +                             dev_info(&pcie->pdev->dev, "unexpected IRQ\n");
> > +
> > +                     /* Clear the bit from status and repeat without reading
> > +                      * again status register. */
> > +                     __clear_bit(bit, &status);
> > +             } while (status);
> > +     } while (1);
>
> Please rewrite similarily to the way I proposed in your MSI driver.
Okay.

Thanks.

Regards
Ley Foon


From lftan at altera.com  Wed Aug 26 06:19:32 2015
From: lftan at altera.com (Ley Foon Tan)
Date: Wed, 26 Aug 2015 21:19:32 +0800
Subject: [PATCH v5 3/5] pci: altera: Add Altera PCIe MSI driver
In-Reply-To: <55DC50AD.1050607@arm.com>
References: <1440495348-2666-1-git-send-email-lftan@altera.com>
 <1440495348-2666-4-git-send-email-lftan@altera.com>
 <55DC50AD.1050607@arm.com>
Message-ID: <CAFiDJ5-ZMqB85N5K4_cMqjNGUJFaB-QGdOGmPQj+VF13Gk1Twg@mail.gmail.com>

On Tue, Aug 25, 2015 at 7:25 PM, Marc Zyngier <marc.zyngier at arm.com> wrote:

> > +
> > +static void altera_msi_isr(unsigned int irq, struct irq_desc *desc)
> > +{
> > +     struct irq_chip *chip = irq_desc_get_chip(desc);
> > +     struct altera_msi *msi;
> > +     unsigned long status;
> > +     u32 num_of_vectors;
> > +     u32 bit;
> > +     u32 virq;
> > +
> > +     chained_irq_enter(chip, desc);
> > +     msi = irq_desc_get_handler_data(desc);
> > +     num_of_vectors = msi->num_of_vectors;
> > +
> > +     do {
> > +             status = msi_readl(msi, MSI_STATUS);
> > +             if (!status)
> > +                     break;
> > +
> > +             do {
> > +                     bit = find_first_bit(&status, num_of_vectors);
> > +                     /* Dummy read from vector to clear the interrupt */
> > +                     readl_relaxed(msi->vector_base + (bit * sizeof(u32)));
> > +
> > +                     virq = irq_find_mapping(msi->inner_domain, bit);
> > +                     if (virq && test_bit(bit, msi->used))
>
> I still wonder under which circumstances you can obtain a valid virq and
> yet not find the bit in the bitmap. Unless you have a scenario when that
> can happen, I suggest you remove that test.
>
> > +                             generic_handle_irq(virq);
> > +                     else
> > +                             dev_err(&msi->pdev->dev, "unexpected MSI\n");
> > +
> > +                     /* Clear the bit from status and repeat without reading
> > +                      * again status register. */
> > +                     __clear_bit(bit, &status);
> > +             } while (status);
> > +     } while (1);
>
> I think this could be rewritten as:
>
> while ((status = msi_readl(msi, MSI_STATUS)) != 0) {
>         for_each_set_bit(bit, &status, msi->num_of_vectors) {
>                 /* Dummy read from vector to clear the interrupt */
>                 readl_relaxed(msi->vector_base + (bit * sizeof(u32)));
>
>                 virq = irq_find_mapping(msi->inner_domain, bit);
>                 if (virq)
>                         generic_handle_irq(virq);
>                 else
>                         dev_err(&msi->pdev->dev, "unexpected MSI\n");
>         }
> }
>
> which saves the __clear_bit call and the double test of status which I
> find a bit awkward.
Okay.

>
> > +
> > +     chained_irq_exit(chip, desc);
> > +}
> > +
> > +static struct irq_chip altera_msi_irq_chip = {
> > +     .name = "Altera PCIe MSI",
> > +     .irq_enable = pci_msi_unmask_irq,
> > +     .irq_disable = pci_msi_mask_irq,
> > +     .irq_mask = pci_msi_mask_irq,
> > +     .irq_unmask = pci_msi_unmask_irq,
>
> Why do you have both enable/disable and unmask/mask? Specially pointing
> to the same function? This is completely useless. Just stick with
> unmask/mask and remove the enable/disable.
Okay.
>
> > +};
> > +
> > +static struct msi_domain_info altera_msi_domain_info = {
> > +     .flags  = (MSI_FLAG_USE_DEF_DOM_OPS | MSI_FLAG_USE_DEF_CHIP_OPS |
> > +                  MSI_FLAG_PCI_MSIX),
> > +     .chip   = &altera_msi_irq_chip,
> > +};
> > +
> > +static void altera_compose_msi_msg(struct irq_data *data, struct msi_msg *msg)
> > +{
> > +     struct altera_msi *msi = irq_data_get_irq_chip_data(data);
> > +     phys_addr_t addr = msi->vector_phy + (data->hwirq * sizeof(u32));
> > +
> > +     msg->address_lo = lower_32_bits(addr);
> > +     msg->address_hi = upper_32_bits(addr);
> > +     msg->data = data->hwirq;
> > +
> > +     dev_dbg(&msi->pdev->dev, "msi#%d address_lo 0x%x address_hi 0x%x\n",
> > +             (int)data->hwirq, msg->address_hi, msg->address_lo);
> > +}
> > +
> > +static int altera_msi_set_affinity(struct irq_data *irq_data,
> > +                                const struct cpumask *mask, bool force)
> > +{
> > +      return -EINVAL;
> > +}
> > +
> > +static struct irq_chip altera_msi_bottom_irq_chip = {
> > +     .name                   = "Altera MSI",
> > +     .irq_compose_msi_msg    = altera_compose_msi_msg,
> > +     .irq_set_affinity       = altera_msi_set_affinity,
> > +};
> > +
> > +static int altera_irq_domain_alloc(struct irq_domain *domain, unsigned int virq,
> > +                                unsigned int nr_irqs, void *args)
> > +{
> > +     struct altera_msi *msi = domain->host_data;
> > +     unsigned long bit;
> > +     u32 mask;
> > +
> > +     WARN_ON(nr_irqs != 1);
> > +     mutex_lock(&msi->lock);
> > +
> > +     bit = find_first_zero_bit(msi->used, msi->num_of_vectors);
> > +     if (bit >= msi->num_of_vectors)
> > +             return -ENOSPC;
> > +
> > +     set_bit(bit, msi->used);
> > +
> > +     mutex_unlock(&msi->lock);
> > +
> > +     irq_domain_set_info(domain, virq, bit, &altera_msi_bottom_irq_chip,
> > +                         domain->host_data, handle_simple_irq,
> > +                         NULL, NULL);
> > +     set_irq_flags(virq, IRQF_VALID);
> > +
> > +     mask = msi_readl(msi, MSI_INTMASK);
> > +     mask |= 1 << bit;
> > +     msi_writel(msi, mask, MSI_INTMASK);
> > +
> > +     return 0;
> > +}
> > +
> > +static void altera_irq_domain_free(struct irq_domain *domain,
> > +                                unsigned int virq, unsigned int nr_irqs)
> > +{
> > +     struct irq_data *d = irq_domain_get_irq_data(domain, virq);
> > +     struct altera_msi *msi = irq_data_get_irq_chip_data(d);
> > +     u32 mask;
> > +
> > +     mutex_lock(&msi->lock);
> > +
> > +     if (!test_bit(d->hwirq, msi->used)) {
> > +             dev_err(&msi->pdev->dev, "trying to free unused MSI#%lu\n",
> > +                     d->hwirq);
> > +     } else {
> > +             __clear_bit(d->hwirq, msi->used);
> > +             mask = msi_readl(msi, MSI_INTMASK);
> > +             mask &= ~(1 << d->hwirq);
> > +             msi_writel(msi, mask, MSI_INTMASK);
> > +     }
> > +
> > +     mutex_unlock(&msi->lock);
> > +}
> > +
> > +static const struct irq_domain_ops msi_domain_ops = {
> > +     .alloc  = altera_irq_domain_alloc,
> > +     .free   = altera_irq_domain_free,
> > +};
> > +
> > +static int altera_allocate_domains(struct altera_msi *msi)
> > +{
> > +     msi->inner_domain = irq_domain_add_linear(NULL, msi->num_of_vectors,
> > +                                          &msi_domain_ops, msi);
> > +     if (!msi->inner_domain) {
> > +             dev_err(&msi->pdev->dev, "failed to create IRQ domain\n");
> > +             return -ENOMEM;
> > +     }
> > +
> > +     msi->msi_domain = pci_msi_create_irq_domain(msi->pdev->dev.of_node,
> > +                             &altera_msi_domain_info, msi->inner_domain);
> > +     if (!msi->msi_domain) {
> > +             dev_err(&msi->pdev->dev, "failed to create MSI domain\n");
> > +             irq_domain_remove(msi->inner_domain);
> > +             return -ENOMEM;
> > +     }
> > +
> > +     return 0;
> > +}
> > +
> > +static void altera_free_domains(struct altera_msi *msi)
> > +{
> > +     irq_domain_remove(msi->msi_domain);
> > +     irq_domain_remove(msi->inner_domain);
> > +}
> > +
> > +static int altera_msi_remove(struct platform_device *pdev)
> > +{
> > +     struct altera_msi *msi = platform_get_drvdata(pdev);
> > +
> > +     msi_writel(msi, 0, MSI_INTMASK);
> > +     irq_set_chained_handler(msi->irq, NULL);
> > +     irq_set_handler_data(msi->irq, NULL);
> > +
> > +     altera_free_domains(msi);
> > +
> > +     platform_set_drvdata(pdev, NULL);
> > +     return 0;
> > +}
> > +
> > +static int altera_msi_probe(struct platform_device *pdev)
> > +{
> > +     struct altera_msi *msi;
> > +     struct device_node *np = pdev->dev.of_node;
> > +     struct resource *res;
> > +     int ret;
> > +
> > +     msi = devm_kzalloc(&pdev->dev, sizeof(struct altera_msi),
> > +                        GFP_KERNEL);
> > +     if (!msi)
> > +             return -ENOMEM;
> > +
> > +     mutex_init(&msi->lock);
> > +     msi->pdev = pdev;
> > +
> > +     res = platform_get_resource_byname(pdev, IORESOURCE_MEM, "csr");
> > +     if (!res) {
> > +             dev_err(&pdev->dev,
> > +                     "no csr memory resource defined\n");
> > +             return -ENODEV;
> > +     }
> > +
> > +     msi->csr_base = devm_ioremap_resource(&pdev->dev, res);
> > +     if (IS_ERR(msi->csr_base)) {
> > +             dev_err(&pdev->dev, "failed to map csr memory\n");
> > +             return PTR_ERR(msi->csr_base);
> > +     }
> > +
> > +     res = platform_get_resource_byname(pdev, IORESOURCE_MEM,
> > +                                        "vector_slave");
> > +     if (!res) {
> > +             dev_err(&pdev->dev,
> > +                     "no vector_slave memory resource defined\n");
> > +             return -ENODEV;
> > +     }
> > +
> > +     msi->vector_base = devm_ioremap_resource(&pdev->dev, res);
> > +     if (IS_ERR(msi->vector_base)) {
> > +             dev_err(&pdev->dev, "failed to map vector_slave memory\n");
> > +             return PTR_ERR(msi->vector_base);
> > +     }
> > +
> > +     msi->vector_phy = res->start;
> > +
> > +     if (of_property_read_u32(np, "num-vectors", &msi->num_of_vectors)) {
> > +             dev_err(&pdev->dev, "failed to parse the number of vectors\n");
> > +             return -EINVAL;
> > +     }
> > +
> > +     ret = altera_allocate_domains(msi);
> > +     if (ret)
> > +             return ret;
> > +
> > +     msi->irq = platform_get_irq(pdev, 0);
> > +     if (msi->irq <= 0) {
> > +             dev_err(&pdev->dev, "failed to map IRQ: %d\n", msi->irq);
> > +             ret = -ENODEV;
> > +             goto err;
> > +     }
> > +
> > +     irq_set_chained_handler_and_data(msi->irq, altera_msi_isr, msi);
> > +     platform_set_drvdata(pdev, msi);
> > +
> > +     return 0;
> > +
> > +err:
> > +     altera_msi_remove(pdev);
> > +     return ret;
> > +}
> > +
> > +static const struct of_device_id altera_msi_of_match[] = {
> > +     { .compatible = "altr,msi-1.0", NULL },
> > +     { },
> > +};
> > +
> > +static struct platform_driver altera_msi_driver = {
> > +     .driver = {
> > +             .name = "altera-msi",
> > +             .of_match_table = altera_msi_of_match,
> > +     },
> > +     .probe = altera_msi_probe,
> > +     .remove = altera_msi_remove,
> > +};
> > +
> > +static int __init altera_msi_init(void)
> > +{
> > +     return platform_driver_register(&altera_msi_driver);
> > +}
> > +
> > +subsys_initcall(altera_msi_init);
> > +
> > +MODULE_AUTHOR("Ley Foon Tan <lftan at altera.com>");
> > +MODULE_DESCRIPTION("Altera PCIe MSI support");
> > +MODULE_LICENSE("GPL v2");
> >
>
> Once you've fixed the above issues, you can add my:
>
> Reviewed-by: Marc Zyngier <marc.zyngier at arm.com>
Okay, thanks.

Thanks.

Regards
Ley Foon


From mpa at pengutronix.de  Wed Aug 26 06:22:46 2015
From: mpa at pengutronix.de (Markus Pargmann)
Date: Wed, 26 Aug 2015 15:22:46 +0200
Subject: [PATCH] regmap: Fix the null function of format_val on
 regmap_bulk_read.
In-Reply-To: <20150826123556.GB2977@sirena.org.uk>
References: <1440589396-696-1-git-send-email-henryc.chen@mediatek.com>
 <20150826123556.GB2977@sirena.org.uk>
Message-ID: <20150826132246.GR706@pengutronix.de>

On Wed, Aug 26, 2015 at 01:35:56PM +0100, Mark Brown wrote:
> On Wed, Aug 26, 2015 at 07:43:16PM +0800, Henry Chen wrote:
> > The regmap_format will not be initialize if device driver not declare the regmap_bus
> > when registering the regmap. To avoid the null function of format_val when
> > called regmap_bulk_read(). It need to give a format function when regmap init.
> 
> > Call trace:
> > [<          (null)>]           (null)
> > [<ffffffc0004cbdd0>] mtk_rtc_read_time+0x9c/0x134
> > [<ffffffc0004c9618>] __rtc_read_time.isra.3+0x40/0x7c
> > [<ffffffc0004c9688>] rtc_read_time+0x34/0x58
> 
> Please don't paste entire backtraces in, they're enormous and tend to
> obscure the actual content while adding little value.  If needed then
> edited highlights work better.  I'm fairly sure I've mentioned this
> before...
> 
> > @@ -783,8 +783,22 @@ struct regmap *regmap_init(struct device *dev,
> >  		map->defer_caching = true;
> >  		map->reg_write = _regmap_bus_raw_write;
> >  	}
> > +/*
> > + * For bulk read, need to hook the format function.
> > + */
> > +simple_format_initialization:
> 
> The indentation is all messed up here, we're misssing a blank line and
> the comment is not indented.
> 
> > -skip_format_initialization:
> > +	switch (config->val_bits) {
> > +		case 8:
> > +			map->format.format_val = regmap_format_8;
> > +			break;
> > +		case 16:
> > +			map->format.format_val = regmap_format_16_native;
> > +			break;
> > +		case 32:
> > +			map->format.format_val = regmap_format_32_native;
> > +			break;
> > +	}
> 
> Why are these format functions sensible?  Converting a null pointer
> dereference into data corruption wouldn't be ideal.  The commit message
> should really cover this.

The regmap_bulk_read() function worked before the following patch:
	15b8d2c41fe5 (regmap: Fix regmap_bulk_read in BE mode)

As far as I can see this patch fixes this issue by using simple format
functions. Before the above mentioned patch, the code used memcpy. Now
regmap_format_*_native is used which should result in the same behaviour
but fixes the null pointer.

I am not sure if there are other locations in the code where format_val
is used in this setup so I don't know if this would change behavior in a
different codepath.

Best regards,

Markus

-- 
Pengutronix e.K.                           |                             |
Industrial Linux Solutions                 | http://www.pengutronix.de/  |
Peiner Str. 6-8, 31137 Hildesheim, Germany | Phone: +49-5121-206917-0    |
Amtsgericht Hildesheim, HRA 2686           | Fax:   +49-5121-206917-5555 |
-------------- next part --------------
A non-text attachment was scrubbed...
Name: signature.asc
Type: application/pgp-signature
Size: 819 bytes
Desc: Digital signature
URL: <http://lists.infradead.org/pipermail/linux-arm-kernel/attachments/20150826/d7064fcd/attachment.sig>

From leif.lindholm at linaro.org  Wed Aug 26 06:24:55 2015
From: leif.lindholm at linaro.org (Leif Lindholm)
Date: Wed, 26 Aug 2015 14:24:55 +0100
Subject: [PATCH 0/3] unify efi debug output across architectures
Message-ID: <1440595498-30630-1-git-send-email-leif.lindholm@linaro.org>

efi didn't use to have much in the way of kernel command line options,
until some point last year. Then once the efi= option was added, it has
been expanded on.

x86 had an efi=debug option added, but that would be a useful thing
across all efi architectures.

arm64 efi support (predating efi=debug) came with its own 'uefi_debug'
option, and passed along a special verbosity flag when calling into
some not-strictly-arch-specific functions in core efi code.

So:
- Move efi=debug into core code, to be usable by all architectures
- Change arm64 efi code to use 'efi=debug' instead of 'uefi_debug'
- Rework arm64 interface to core code to drop special verbosity flag

Leif Lindholm (3):
  efi/x86: move efi=debug option parsing to core
  arm64: use core efi=debug instead of uefi_debug command line parameter
  efi/arm64: clean up efi_get_fdt_params() interface

 Documentation/arm/uefi.txt  |  2 --
 arch/arm64/kernel/efi.c     | 19 +++++--------------
 arch/x86/platform/efi/efi.c |  2 --
 drivers/firmware/efi/efi.c  |  9 +++++----
 include/linux/efi.h         |  2 +-
 5 files changed, 11 insertions(+), 23 deletions(-)

-- 
2.1.4



From leif.lindholm at linaro.org  Wed Aug 26 06:24:56 2015
From: leif.lindholm at linaro.org (Leif Lindholm)
Date: Wed, 26 Aug 2015 14:24:56 +0100
Subject: [PATCH 1/3] efi/x86: move efi=debug option parsing to core
In-Reply-To: <1440595498-30630-1-git-send-email-leif.lindholm@linaro.org>
References: <1440595498-30630-1-git-send-email-leif.lindholm@linaro.org>
Message-ID: <1440595498-30630-2-git-send-email-leif.lindholm@linaro.org>

fed6cefe3b6e ("x86/efi: Add a "debug" option to the efi= cmdline")
adds the DBG flag, but does so for x86 only. Move this early param
parsing to core code.

Signed-off-by: Leif Lindholm <leif.lindholm at linaro.org>
---
 arch/x86/platform/efi/efi.c | 2 --
 drivers/firmware/efi/efi.c  | 3 +++
 2 files changed, 3 insertions(+), 2 deletions(-)

diff --git a/arch/x86/platform/efi/efi.c b/arch/x86/platform/efi/efi.c
index e4308fe..9757b79 100644
--- a/arch/x86/platform/efi/efi.c
+++ b/arch/x86/platform/efi/efi.c
@@ -979,8 +979,6 @@ static int __init arch_parse_efi_cmdline(char *str)
 
 	if (parse_option_str(str, "old_map"))
 		set_bit(EFI_OLD_MEMMAP, &efi.flags);
-	if (parse_option_str(str, "debug"))
-		set_bit(EFI_DBG, &efi.flags);
 
 	return 0;
 }
diff --git a/drivers/firmware/efi/efi.c b/drivers/firmware/efi/efi.c
index d6144e3..78de0bd 100644
--- a/drivers/firmware/efi/efi.c
+++ b/drivers/firmware/efi/efi.c
@@ -63,6 +63,9 @@ static int __init parse_efi_cmdline(char *str)
 		return -EINVAL;
 	}
 
+	if (parse_option_str(str, "debug"))
+		set_bit(EFI_DBG, &efi.flags);
+
 	if (parse_option_str(str, "noruntime"))
 		disable_runtime = true;
 
-- 
2.1.4



From leif.lindholm at linaro.org  Wed Aug 26 06:24:57 2015
From: leif.lindholm at linaro.org (Leif Lindholm)
Date: Wed, 26 Aug 2015 14:24:57 +0100
Subject: [PATCH 2/3] arm64: use core efi=debug instead of uefi_debug command
 line parameter
In-Reply-To: <1440595498-30630-1-git-send-email-leif.lindholm@linaro.org>
References: <1440595498-30630-1-git-send-email-leif.lindholm@linaro.org>
Message-ID: <1440595498-30630-3-git-send-email-leif.lindholm@linaro.org>

Now that we have an efi=debug command line option in the core code, use
this instead of the arm64-specific uefi_debug option.

Signed-off-by: Leif Lindholm <leif.lindholm at linaro.org>
---
 Documentation/arm/uefi.txt |  2 --
 arch/arm64/kernel/efi.c    | 19 +++++--------------
 2 files changed, 5 insertions(+), 16 deletions(-)

diff --git a/Documentation/arm/uefi.txt b/Documentation/arm/uefi.txt
index d60030a..7b3fdfe 100644
--- a/Documentation/arm/uefi.txt
+++ b/Documentation/arm/uefi.txt
@@ -60,5 +60,3 @@ linux,uefi-mmap-desc-ver  | 32-bit | Version of the mmap descriptor format.
 --------------------------------------------------------------------------------
 linux,uefi-stub-kern-ver  | string | Copy of linux_banner from build.
 --------------------------------------------------------------------------------
-
-For verbose debug messages, specify 'uefi_debug' on the kernel command line.
diff --git a/arch/arm64/kernel/efi.c b/arch/arm64/kernel/efi.c
index e8ca6ea..612ad5e 100644
--- a/arch/arm64/kernel/efi.c
+++ b/arch/arm64/kernel/efi.c
@@ -51,15 +51,6 @@ static struct mm_struct efi_mm = {
 	INIT_MM_CONTEXT(efi_mm)
 };
 
-static int uefi_debug __initdata;
-static int __init uefi_debug_setup(char *str)
-{
-	uefi_debug = 1;
-
-	return 0;
-}
-early_param("uefi_debug", uefi_debug_setup);
-
 static int __init is_normal_ram(efi_memory_desc_t *md)
 {
 	if (md->attribute & EFI_MEMORY_WB)
@@ -171,14 +162,14 @@ static __init void reserve_regions(void)
 	efi_memory_desc_t *md;
 	u64 paddr, npages, size;
 
-	if (uefi_debug)
+	if (efi_enabled(EFI_DBG))
 		pr_info("Processing EFI memory map:\n");
 
 	for_each_efi_memory_desc(&memmap, md) {
 		paddr = md->phys_addr;
 		npages = md->num_pages;
 
-		if (uefi_debug) {
+		if (efi_enabled(EFI_DBG)) {
 			char buf[64];
 
 			pr_info("  0x%012llx-0x%012llx %s",
@@ -194,11 +185,11 @@ static __init void reserve_regions(void)
 
 		if (is_reserve_region(md)) {
 			memblock_reserve(paddr, size);
-			if (uefi_debug)
+			if (efi_enabled(EFI_DBG))
 				pr_cont("*");
 		}
 
-		if (uefi_debug)
+		if (efi_enabled(EFI_DBG))
 			pr_cont("\n");
 	}
 
@@ -210,7 +201,7 @@ void __init efi_init(void)
 	struct efi_fdt_params params;
 
 	/* Grab UEFI information placed in FDT by stub */
-	if (!efi_get_fdt_params(&params, uefi_debug))
+	if (!efi_get_fdt_params(&params, efi_enabled(EFI_DBG)))
 		return;
 
 	efi_system_table = params.system_table;
-- 
2.1.4



From leif.lindholm at linaro.org  Wed Aug 26 06:24:58 2015
From: leif.lindholm at linaro.org (Leif Lindholm)
Date: Wed, 26 Aug 2015 14:24:58 +0100
Subject: [PATCH 3/3] efi/arm64: clean up efi_get_fdt_params() interface
In-Reply-To: <1440595498-30630-1-git-send-email-leif.lindholm@linaro.org>
References: <1440595498-30630-1-git-send-email-leif.lindholm@linaro.org>
Message-ID: <1440595498-30630-4-git-send-email-leif.lindholm@linaro.org>

As we now have a common debug infrastructure between core and arm64 efi,
drop the bit of the interface passing verbose output flags around.

Signed-off-by: Leif Lindholm <leif.lindholm at linaro.org>
---
 arch/arm64/kernel/efi.c    | 2 +-
 drivers/firmware/efi/efi.c | 6 ++----
 include/linux/efi.h        | 2 +-
 3 files changed, 4 insertions(+), 6 deletions(-)

diff --git a/arch/arm64/kernel/efi.c b/arch/arm64/kernel/efi.c
index 612ad5e..ab5eeb6 100644
--- a/arch/arm64/kernel/efi.c
+++ b/arch/arm64/kernel/efi.c
@@ -201,7 +201,7 @@ void __init efi_init(void)
 	struct efi_fdt_params params;
 
 	/* Grab UEFI information placed in FDT by stub */
-	if (!efi_get_fdt_params(&params, efi_enabled(EFI_DBG)))
+	if (!efi_get_fdt_params(&params))
 		return;
 
 	efi_system_table = params.system_table;
diff --git a/drivers/firmware/efi/efi.c b/drivers/firmware/efi/efi.c
index 78de0bd..aca6aaf 100644
--- a/drivers/firmware/efi/efi.c
+++ b/drivers/firmware/efi/efi.c
@@ -492,7 +492,6 @@ static __initdata struct {
 };
 
 struct param_info {
-	int verbose;
 	int found;
 	void *params;
 };
@@ -523,21 +522,20 @@ static int __init fdt_find_uefi_params(unsigned long node, const char *uname,
 		else
 			*(u64 *)dest = val;
 
-		if (info->verbose)
+		if (efi_enabled(EFI_DBG))
 			pr_info("  %s: 0x%0*llx\n", dt_params[i].name,
 				dt_params[i].size * 2, val);
 	}
 	return 1;
 }
 
-int __init efi_get_fdt_params(struct efi_fdt_params *params, int verbose)
+int __init efi_get_fdt_params(struct efi_fdt_params *params)
 {
 	struct param_info info;
 	int ret;
 
 	pr_info("Getting EFI parameters from FDT:\n");
 
-	info.verbose = verbose;
 	info.found = 0;
 	info.params = params;
 
diff --git a/include/linux/efi.h b/include/linux/efi.h
index 85ef051..b1a5b74 100644
--- a/include/linux/efi.h
+++ b/include/linux/efi.h
@@ -901,7 +901,7 @@ extern void efi_initialize_iomem_resources(struct resource *code_resource,
 		struct resource *data_resource, struct resource *bss_resource);
 extern void efi_get_time(struct timespec *now);
 extern void efi_reserve_boot_services(void);
-extern int efi_get_fdt_params(struct efi_fdt_params *params, int verbose);
+extern int efi_get_fdt_params(struct efi_fdt_params *params);
 extern struct efi_memory_map memmap;
 extern struct kobject *efi_kobj;
 
-- 
2.1.4



From ard.biesheuvel at linaro.org  Wed Aug 26 06:30:02 2015
From: ard.biesheuvel at linaro.org (Ard Biesheuvel)
Date: Wed, 26 Aug 2015 15:30:02 +0200
Subject: [PATCH v2] arm64/efi: base UEFI mapping permissions on region
 attributes
Message-ID: <1440595802-20359-1-git-send-email-ard.biesheuvel@linaro.org>

Currently, we infer the UEFI memory region mapping permissions
from the memory region type (i.e., runtime services code are
mapped RWX and runtime services data mapped RW-). This appears to
work fine but is not entirely UEFI spec compliant. So instead, use
the designated permission attributes to decide how these regions
should be mapped.

Since UEFIv2.5 introduces a new EFI_MEMORY_RO permission attribute,
and redefines EFI_MEMORY_WP as a cacheability attribute, use only
the former as a read-only attribute. For setting the PXN bit, the
corresponding EFI_MEMORY_XP attribute is used.

Signed-off-by: Ard Biesheuvel <ard.biesheuvel at linaro.org>
---
Changes since v1:
- rewrote page size and alignment check to be more legible
- use code that is STRICT_MM_TYPECHECKS compliant

Example output of a recent Tianocore build on FVP Foundation model
is attached below.

 arch/arm64/kernel/efi.c | 37 +++++++++++++-------
 1 file changed, 24 insertions(+), 13 deletions(-)

diff --git a/arch/arm64/kernel/efi.c b/arch/arm64/kernel/efi.c
index ab21e0d58278..c8d587f46f3e 100644
--- a/arch/arm64/kernel/efi.c
+++ b/arch/arm64/kernel/efi.c
@@ -235,7 +235,7 @@ static bool __init efi_virtmap_init(void)
 
 	for_each_efi_memory_desc(&memmap, md) {
 		u64 paddr, npages, size;
-		pgprot_t prot;
+		pteval_t prot_val;
 
 		if (!(md->attribute & EFI_MEMORY_RUNTIME))
 			continue;
@@ -247,22 +247,33 @@ static bool __init efi_virtmap_init(void)
 		memrange_efi_to_native(&paddr, &npages);
 		size = npages << PAGE_SHIFT;
 
-		pr_info("  EFI remap 0x%016llx => %p\n",
-			md->phys_addr, (void *)md->virt_addr);
+		if (!is_normal_ram(md))
+			prot_val = PROT_DEVICE_nGnRE;
+		else
+			prot_val = pgprot_val(PAGE_KERNEL_EXEC);
 
 		/*
-		 * Only regions of type EFI_RUNTIME_SERVICES_CODE need to be
-		 * executable, everything else can be mapped with the XN bits
-		 * set.
+		 * On 64 KB granule kernels, only use strict permissions when
+		 * the region does not share a 64 KB page frame with another
+		 * region at either end.
 		 */
-		if (!is_normal_ram(md))
-			prot = __pgprot(PROT_DEVICE_nGnRE);
-		else if (md->type == EFI_RUNTIME_SERVICES_CODE)
-			prot = PAGE_KERNEL_EXEC;
-		else
-			prot = PAGE_KERNEL;
+		if (PAGE_SIZE == EFI_PAGE_SIZE ||
+		    (PAGE_ALIGNED(md->virt_addr) &&
+		     PAGE_ALIGNED(md->phys_addr + md->num_pages * EFI_PAGE_SIZE))) {
+
+			if (md->attribute & EFI_MEMORY_RO)
+				prot_val |= PTE_RDONLY;
+			if (md->attribute & EFI_MEMORY_XP)
+				prot_val |= PTE_PXN;
+		}
+
+		pr_info("  EFI remap 0x%016llx => %p (R%c%c)\n",
+			md->phys_addr, (void *)md->virt_addr,
+			prot_val & PTE_RDONLY ? '-' : 'W',
+			prot_val & PTE_PXN ? '-' : 'X');
 
-		create_pgd_mapping(&efi_mm, paddr, md->virt_addr, size, prot);
+		create_pgd_mapping(&efi_mm, paddr, md->virt_addr, size,
+				   __pgprot(prot_val));
 	}
 	return true;
 }
-- 
1.9.1

Processing EFI memory map:
  0x00000c000000-0x00000ffeffff [Memory Mapped I/O  |RUN|XP|  |  |  |   |  |  |  |UC]
  0x00001c170000-0x00001c170fff [Memory Mapped I/O  |RUN|XP|  |  |  |   |  |  |  |UC]
  ...
  0x0008fabf0000-0x0008fac0ffff [Runtime Data       |RUN|XP|  |  |  |   |WB|WT|WC|UC]*
  0x0008fac10000-0x0008fac1ffff [Runtime Code       |RUN|  |  |  |RO|   |WB|WT|WC|UC]*
  0x0008fac20000-0x0008fac4ffff [Runtime Data       |RUN|XP|  |  |  |   |WB|WT|WC|UC]*
  0x0008fac50000-0x0008fac5ffff [Runtime Code       |RUN|  |  |  |RO|   |WB|WT|WC|UC]*
  0x0008fac60000-0x0008fac8ffff [Runtime Data       |RUN|XP|  |  |  |   |WB|WT|WC|UC]*
  0x0008fac90000-0x0008fac9ffff [Runtime Code       |RUN|  |  |  |RO|   |WB|WT|WC|UC]*
  0x0008faca0000-0x0008fad4ffff [Runtime Data       |RUN|XP|  |  |  |   |WB|WT|WC|UC]*
  0x0008fad50000-0x0008fad5ffff [Runtime Data       |RUN|XP|  |  |  |   |WB|WT|WC|UC]*
  0x0008fad60000-0x0008fad6ffff [Runtime Code       |RUN|  |  |  |RO|   |WB|WT|WC|UC]*
  0x0008fad70000-0x0008fae8ffff [Runtime Data       |RUN|XP|  |  |  |   |WB|WT|WC|UC]*
  0x0008fae90000-0x0008fae9ffff [Runtime Data       |RUN|XP|  |  |  |   |WB|WT|WC|UC]*
  0x0008faea0000-0x0008faeaffff [Runtime Code       |RUN|  |  |  |RO|   |WB|WT|WC|UC]*
  0x0008faeb0000-0x0008faf2ffff [Runtime Data       |RUN|XP|  |  |  |   |WB|WT|WC|UC]*
  0x0008faf30000-0x0008faf3ffff [Runtime Data       |RUN|XP|  |  |  |   |WB|WT|WC|UC]*
  0x0008faf40000-0x0008faf4ffff [Runtime Code       |RUN|  |  |  |RO|   |WB|WT|WC|UC]*
  0x0008faf50000-0x0008faf7ffff [Runtime Data       |RUN|XP|  |  |  |   |WB|WT|WC|UC]*
  ...
  0x0008fff50000-0x0008fff5ffff [Runtime Data       |RUN|XP|  |  |  |   |WB|WT|WC|UC]*
  0x0008fff60000-0x0008fff6ffff [Runtime Code       |RUN|  |  |  |RO|   |WB|WT|WC|UC]*
  0x0008fff70000-0x0008fff8ffff [Runtime Data       |RUN|XP|  |  |  |   |WB|WT|WC|UC]*
  0x0008fff90000-0x0008fff9ffff [Conventional Memory|   |  |  |  |  |   |WB|WT|WC|UC]
  0x0008fffa0000-0x0008fffeffff [Runtime Data       |RUN|XP|  |  |  |   |WB|WT|WC|UC]*
...
Remapping and enabling EFI services.
  EFI remap 0x000000000c000000 => 0000000040000000 (RW-)
  EFI remap 0x000000001c170000 => 0000000043ff0000 (RW-)
  EFI remap 0x00000008fabf0000 => 0000000044000000 (RW-)
  EFI remap 0x00000008fac10000 => 0000000044020000 (R-X)
  EFI remap 0x00000008fac20000 => 0000000044030000 (RW-)
  EFI remap 0x00000008fac50000 => 0000000044060000 (R-X)
  EFI remap 0x00000008fac60000 => 0000000044070000 (RW-)
  EFI remap 0x00000008fac90000 => 00000000440a0000 (R-X)
  EFI remap 0x00000008faca0000 => 00000000440b0000 (RW-)
  EFI remap 0x00000008fad50000 => 0000000044160000 (RW-)
  EFI remap 0x00000008fad60000 => 0000000044170000 (R-X)
  EFI remap 0x00000008fad70000 => 0000000044180000 (RW-)
  EFI remap 0x00000008fae90000 => 00000000442a0000 (RW-)
  EFI remap 0x00000008faea0000 => 00000000442b0000 (R-X)
  EFI remap 0x00000008faeb0000 => 00000000442c0000 (RW-)
  EFI remap 0x00000008faf30000 => 0000000044340000 (RW-)
  EFI remap 0x00000008faf40000 => 0000000044350000 (R-X)
  EFI remap 0x00000008faf50000 => 0000000044360000 (RW-)
  EFI remap 0x00000008fff50000 => 0000000044390000 (RW-)
  EFI remap 0x00000008fff60000 => 00000000443a0000 (R-X)
  EFI remap 0x00000008fff70000 => 00000000443b0000 (RW-)
  EFI remap 0x00000008fffa0000 => 00000000443d0000 (RW-)



From nschichan at freebox.fr  Wed Aug 26 06:36:56 2015
From: nschichan at freebox.fr (Nicolas Schichan)
Date: Wed, 26 Aug 2015 15:36:56 +0200
Subject: [PATCH v2 10/10] ARM: software-based priviledged-no-access support
In-Reply-To: <20150825174841.GV7557@n2100.arm.linux.org.uk>
References: <20150825154026.GT7557@n2100.arm.linux.org.uk>
 <E1ZUGMS-0000BG-8B@rmk-PC.arm.linux.org.uk> <55DCA0DB.7000103@freebox.fr>
 <20150825174841.GV7557@n2100.arm.linux.org.uk>
Message-ID: <55DDC0F8.5080906@freebox.fr>

On 08/25/2015 07:48 PM, Russell King - ARM Linux wrote:
> On Tue, Aug 25, 2015 at 07:07:39PM +0200, Nicolas Schichan wrote:
>> arch/arm/kernel/entry-common.S: Assembler messages:
>> arch/arm/kernel/entry-common.S:200: Error: selected processor does not support
>> ARM mode `isb'
>>
>> replacing those two "isb" occurences with "instr_sync" fixed it.
> 
> Thanks, that's exactly what I've done.  I've pushed that and the other
> fixes out for linux-next to pick up, hopefully with fewer failures.

For the code in next-20150826:

Tested-by: Nicolas Schichan <nschichan at freebox.fr>

Thanks,

-- 
Nicolas Schichan
Freebox SAS


From linus.walleij at linaro.org  Wed Aug 26 06:39:28 2015
From: linus.walleij at linaro.org (Linus Walleij)
Date: Wed, 26 Aug 2015 15:39:28 +0200
Subject: [PATCH 1/3] ARM: uniphier: add outer cache support
In-Reply-To: <1440382692-3855-2-git-send-email-yamada.masahiro@socionext.com>
References: <1440382692-3855-1-git-send-email-yamada.masahiro@socionext.com>
 <1440382692-3855-2-git-send-email-yamada.masahiro@socionext.com>
Message-ID: <CACRpkdbJppuA6ZyciNAGfSgrf4M2THVHggzuZYSqORjy2JBp_A@mail.gmail.com>

On Mon, Aug 24, 2015 at 4:18 AM, Masahiro Yamada
<yamada.masahiro at socionext.com> wrote:
> This commit adds support for UniPhier outer cache controller.
> All the UniPhier SoCs are equipped with the L2 cache, while the L3
> cache is currently only integrated on PH1-Pro5 SoC.
>
> Signed-off-by: Masahiro Yamada <yamada.masahiro at socionext.com>

Wow it is really a custom L2$ controller. Wow. Just wow. That's
really brave, given all the problems we've seen in l2x0.

> +UniPhier SoCs are integrated with a level 2 cache controller that resides
> +outside of the ARM cores, some of them also have a level 3 cache controller.
> +
> +Required properties:
> +- compatible: should be one of the followings:
> +       "socionext,uniphier-l2-cache"   (L2 cache)
> +       "socionext,uniphier-l3-cache"   (L3 cache)

Refer to and use the 3.7.3 ePAPR v1.1 specification too:
https://www.power.org/wp-content/uploads/2012/06/Power_ePAPR_APPROVED_v1.1.pdf

cache-unified and cache-level are *not* optional and should be required.

So:

> +The L2 cache must exist to use the L3 cache; adding only an L3 cache device
> +node to the device tree causes the initialization failure of the whole outer
> +cache system.
> +
> +Example:
> +       l2-cache at 500c0000 {
> +               compatible = "socionext,uniphier-l2-cache";
> +               reg = <0x500c0000 0x2000>, <0x503c0100 0x8>,
> +                     <0x506c0000 0x400>;

cache-unified;
cache-level = <2>;

> +       /* Not all of UniPhier SoCs have L3 cache */
> +       l3-cache at 500c8000 {
> +               compatible = "socionext,uniphier-l3-cache";
> +               reg = <0x500c8000 0x2000>, <0x503c8100 0x8>,
> +                     <0x506c8000 0x400>;

cache-unified;
cache-level = <3>;

(I'm just assuming this cache is unified, anything else would be baffling.)

Further the ePAPR spec optionally supports specifying things like the
cache size, number of sets, block size and line size, unless this can
be hard coded.

Yours,
Linus Walleij


From cyrille.pitchen at atmel.com  Wed Aug 26 05:30:25 2015
From: cyrille.pitchen at atmel.com (Cyrille Pitchen)
Date: Wed, 26 Aug 2015 14:30:25 +0200
Subject: [PATCH linux-next v5 3/5] mtd: spi-nor: allow to tune the number of
 dummy cycles
In-Reply-To: <cover.1440580764.git.cyrille.pitchen@atmel.com>
References: <cover.1440580764.git.cyrille.pitchen@atmel.com>
Message-ID: <4324f398c0e69e3057e7da6a1a3e0328b44f224f.1440580764.git.cyrille.pitchen@atmel.com>

The number of dummy cycles used during Fast Read commands can be reduced
to improve transfer performances. Each manufacturer has a dedicated set of
registers to provide the memory with the exact number of dummy cycles it
should expect. Both the memory and the (Q)SPI controller must agree on
this number of dummy cycles.

The number of dummy cycles can be found into the memory datasheet and
mostly depends on the SPI clock frequency, the Fast Read op code and the
Single/Dual Data Rate mode.

Probing JEDEC Serial Flash Discoverable Parameters (SFDP) tables would
only provide the driver with a high enough number of dummy cycles for each
Fast Read command to be used for all clock frequencies: this solution
would not be optimized.

Signed-off-by: Cyrille Pitchen <cyrille.pitchen at atmel.com>
---
 drivers/mtd/spi-nor/spi-nor.c | 102 ++++++++++++++++++++++++++++++++++--------
 include/linux/mtd/spi-nor.h   |   2 +
 2 files changed, 85 insertions(+), 19 deletions(-)

diff --git a/drivers/mtd/spi-nor/spi-nor.c b/drivers/mtd/spi-nor/spi-nor.c
index c8810313a752..46d6e02f7560 100644
--- a/drivers/mtd/spi-nor/spi-nor.c
+++ b/drivers/mtd/spi-nor/spi-nor.c
@@ -121,24 +121,6 @@ static int read_cr(struct spi_nor *nor)
 }
 
 /*
- * Dummy Cycle calculation for different type of read.
- * It can be used to support more commands with
- * different dummy cycle requirements.
- */
-static inline int spi_nor_read_dummy_cycles(struct spi_nor *nor)
-{
-	switch (nor->flash_read) {
-	case SPI_NOR_FAST:
-	case SPI_NOR_DUAL:
-	case SPI_NOR_QUAD:
-		return 8;
-	case SPI_NOR_NORMAL:
-		return 0;
-	}
-	return 0;
-}
-
-/*
  * Write status register 1 byte
  * Returns negative if error occurred.
  */
@@ -1008,6 +990,86 @@ static int set_quad_mode(struct spi_nor *nor, const struct flash_info *info)
 	}
 }
 
+static int micron_set_dummy_cycles(struct spi_nor *nor)
+{
+	int ret;
+	u8 val, mask;
+
+	/* Read the Volatile Configuration Register (VCR). */
+	ret = nor->read_reg(nor, SPINOR_OP_RD_VCR, &val, 1);
+	if (ret < 0) {
+		dev_err(nor->dev, "error %d reading VCR\n", ret);
+		return ret;
+	}
+
+	write_enable(nor);
+
+	/* Update the number of dummy into the VCR. */
+	mask = GENMASK(7, 4);
+	val &= ~mask;
+	val |= (nor->read_dummy << 4) & mask;
+	ret = nor->write_reg(nor, SPINOR_OP_WR_VCR, &val, 1, 0);
+	if (ret < 0) {
+		dev_err(nor->dev, "error while writing VCR register\n");
+		return ret;
+	}
+
+	ret = spi_nor_wait_till_ready(nor);
+	if (ret)
+		return ret;
+
+	return 0;
+}
+
+/*
+ * Dummy Cycle calculation for different type of read.
+ * It can be used to support more commands with
+ * different dummy cycle requirements.
+ */
+static int spi_nor_read_dummy_cycles(struct spi_nor *nor,
+				     const struct flash_info *info)
+{
+	struct device_node *np = nor->dev->of_node;
+	struct device *dev = nor->dev;
+	u32 num_dummy_cycles;
+
+	if (np && !of_property_read_u32(np, "m25p,num-dummy-cycles",
+					&num_dummy_cycles)) {
+		nor->read_dummy = num_dummy_cycles;
+
+		/*
+		 * This switch block might be moved at the end of the function,
+		 * once nor->read_dummy has been set, but it was not tested with
+		 * all Micron memories.
+		 * Now the "m25p,num-dummy-cycles" property needs to be
+		 * explicitly set in the device tree so the switch statement is
+		 * executed. This should avoid unwanted side effects and keep
+		 * backward compatibility.
+		 */
+		switch (JEDEC_MFR(info)) {
+		case CFI_MFR_ST:
+			return micron_set_dummy_cycles(nor);
+		default:
+			dev_warn(dev,
+				 "Tuning of the number of dummy cycles is not implemented for spi-nor of this manufacturer,\n"
+				 "ignoring the DT property value and falling back to the framework default settings.\n");
+			break;
+		}
+	}
+
+	/* Fallback to legacy code. */
+	switch (nor->flash_read) {
+	case SPI_NOR_FAST:
+	case SPI_NOR_DUAL:
+	case SPI_NOR_QUAD:
+		nor->read_dummy = 8;
+	case SPI_NOR_NORMAL:
+		nor->read_dummy = 0;
+	}
+
+	return 0;
+}
+
 static int spi_nor_check(struct spi_nor *nor)
 {
 	if (!nor->dev || !nor->read || !nor->write ||
@@ -1208,7 +1270,9 @@ int spi_nor_scan(struct spi_nor *nor, const char *name, enum read_mode mode)
 		nor->addr_width = 3;
 	}
 
-	nor->read_dummy = spi_nor_read_dummy_cycles(nor);
+	ret = spi_nor_read_dummy_cycles(nor, info);
+	if (ret)
+		return ret;
 
 	dev_info(dev, "%s (%lld Kbytes)\n", info->name,
 			(long long)mtd->size >> 10);
diff --git a/include/linux/mtd/spi-nor.h b/include/linux/mtd/spi-nor.h
index 1bf6f11310ef..e03a4c4053d3 100644
--- a/include/linux/mtd/spi-nor.h
+++ b/include/linux/mtd/spi-nor.h
@@ -59,6 +59,8 @@
 /* Used for Micron flashes only. */
 #define SPINOR_OP_RD_EVCR      0x65    /* Read EVCR register */
 #define SPINOR_OP_WD_EVCR      0x61    /* Write EVCR register */
+#define SPINOR_OP_RD_VCR	0x85	/* Read VCR register */
+#define SPINOR_OP_WR_VCR	0x81	/* Write VCR register */
 
 /* Status Register bits. */
 #define SR_WIP			1	/* Write in progress */
-- 
1.8.2.2



From cyrille.pitchen at atmel.com  Wed Aug 26 05:30:24 2015
From: cyrille.pitchen at atmel.com (Cyrille Pitchen)
Date: Wed, 26 Aug 2015 14:30:24 +0200
Subject: [PATCH linux-next v5 2/5] Documentation: mtd: add a DT property to
 set the number of dummy cycles
In-Reply-To: <cover.1440580764.git.cyrille.pitchen@atmel.com>
References: <cover.1440580764.git.cyrille.pitchen@atmel.com>
Message-ID: <648dbf9f9d1d4cd414fe2df8d298880b2245c7b5.1440580764.git.cyrille.pitchen@atmel.com>

Depending on the SPI clock frequency, the Fast Read op code and the
Single/Dual Data Rate mode, the number of dummy cycles can be tuned to
improve transfer speed.
The actual number of dummy cycles is specific for each memory model and is
provided by the manufacturer thanks to the memory datasheet.

Signed-off-by: Cyrille Pitchen <cyrille.pitchen at atmel.com>
---
 Documentation/devicetree/bindings/mtd/jedec,spi-nor.txt | 6 ++++++
 1 file changed, 6 insertions(+)

diff --git a/Documentation/devicetree/bindings/mtd/jedec,spi-nor.txt b/Documentation/devicetree/bindings/mtd/jedec,spi-nor.txt
index 2bee68103b01..4387567d8024 100644
--- a/Documentation/devicetree/bindings/mtd/jedec,spi-nor.txt
+++ b/Documentation/devicetree/bindings/mtd/jedec,spi-nor.txt
@@ -19,6 +19,11 @@ Optional properties:
                    all chips and support for it can not be detected at runtime.
                    Refer to your chips' datasheet to check if this is supported
                    by your chip.
+- m25p,num-dummy-cycles : Set the number of dummy cycles for Fast Read commands.
+                          Depending on the manufacturer additional dedicated
+                          commands are sent to the flash memory so the
+                          controller and the memory can agree on the number of
+                          dummy cycles to use.
 
 Example:
 
@@ -29,4 +34,5 @@ Example:
 		reg = <0>;
 		spi-max-frequency = <40000000>;
 		m25p,fast-read;
+		m25p,num-dummy-cycles = <8>;
 	};
-- 
1.8.2.2



From ard.biesheuvel at linaro.org  Wed Aug 26 06:46:38 2015
From: ard.biesheuvel at linaro.org (Ard Biesheuvel)
Date: Wed, 26 Aug 2015 15:46:38 +0200
Subject: [PATCH 0/3] unify efi debug output across architectures
In-Reply-To: <1440595498-30630-1-git-send-email-leif.lindholm@linaro.org>
References: <1440595498-30630-1-git-send-email-leif.lindholm@linaro.org>
Message-ID: <CAKv+Gu9rePiKwk63+tppYWKW-3VV7OmKekteUra57zowejfQqw@mail.gmail.com>

On 26 August 2015 at 15:24, Leif Lindholm <leif.lindholm at linaro.org> wrote:
> efi didn't use to have much in the way of kernel command line options,
> until some point last year. Then once the efi= option was added, it has
> been expanded on.
>
> x86 had an efi=debug option added, but that would be a useful thing
> across all efi architectures.
>
> arm64 efi support (predating efi=debug) came with its own 'uefi_debug'
> option, and passed along a special verbosity flag when calling into
> some not-strictly-arch-specific functions in core efi code.
>
> So:
> - Move efi=debug into core code, to be usable by all architectures
> - Change arm64 efi code to use 'efi=debug' instead of 'uefi_debug'
> - Rework arm64 interface to core code to drop special verbosity flag
>

For the series:

Acked-by: Ard Biesheuvel <ard.biesheuvel at linaro.org>
Tested-by: Ard Biesheuvel <ard.biesheuvel at linaro.org>

> Leif Lindholm (3):
>   efi/x86: move efi=debug option parsing to core
>   arm64: use core efi=debug instead of uefi_debug command line parameter
>   efi/arm64: clean up efi_get_fdt_params() interface
>
>  Documentation/arm/uefi.txt  |  2 --
>  arch/arm64/kernel/efi.c     | 19 +++++--------------
>  arch/x86/platform/efi/efi.c |  2 --
>  drivers/firmware/efi/efi.c  |  9 +++++----
>  include/linux/efi.h         |  2 +-
>  5 files changed, 11 insertions(+), 23 deletions(-)
>
> --
> 2.1.4
>


From robh at kernel.org  Wed Aug 26 06:47:38 2015
From: robh at kernel.org (Rob Herring)
Date: Wed, 26 Aug 2015 08:47:38 -0500
Subject: [PATCH v3] irqchip: kill off set_irq_flags usage
In-Reply-To: <1438030523-15853-6-git-send-email-robh@kernel.org>
References: <1438030523-15853-1-git-send-email-robh@kernel.org>
 <1438030523-15853-6-git-send-email-robh@kernel.org>
Message-ID: <CAL_JsqL9EsFpE3j_ud6bvoJ38di+2428mBD2VgQPX8fba=BpdQ@mail.gmail.com>

On Mon, Jul 27, 2015 at 3:55 PM, Rob Herring <robh at kernel.org> wrote:
> set_irq_flags is ARM specific with custom flags which have genirq
> equivalents. Convert drivers to use the genirq interfaces directly, so we
> can kill off set_irq_flags. The translation of flags is as follows:
>
> IRQF_VALID -> !IRQ_NOREQUEST
> IRQF_PROBE -> !IRQ_NOPROBE
> IRQF_NOAUTOEN -> IRQ_NOAUTOEN
>
> For IRQs managed by an irqdomain, the irqdomain core code handles clearing
> and setting IRQ_NOREQUEST already, so there is no need to do this in
> .map() functions and we can simply remove the set_irq_flags calls. Some
> users also modify IRQ_NOPROBE and this has been maintained although it
> is not clear that is really needed. There appears to be a great deal of
> blind copy and paste of this code.
>
> Signed-off-by: Rob Herring <robh at kernel.org>
> Cc: Thomas Gleixner <tglx at linutronix.de>
> Cc: Jason Cooper <jason at lakedaemon.net>
> Cc: Kukjin Kim <kgene at kernel.org>
> Cc: Krzysztof Kozlowski <k.kozlowski at samsung.com>
> Cc: Stephen Warren <swarren at wwwdotorg.org>
> Cc: Lee Jones <lee at kernel.org>
> Cc: Alexander Shiyan <shc_work at mail.ru>
> Cc: Maxime Ripard <maxime.ripard at free-electrons.com>
> Cc: linux-arm-kernel at lists.infradead.org
> Cc: linux-samsung-soc at vger.kernel.org
> Cc: linux-rpi-kernel at lists.infradead.org
> ---
> Thomas asked that this be merged thru subsystem trees instead of arm-soc,
> so please apply this to your tree.

Thomas, Jason,

Everything except this patch, sh, gpu, and final removal of
set_irq_flags in arm/arm64 are in -next. There don't appear to be any
new users either.

Can you apply this patch and these 2 now so they have some time in -next:

http://lkml.kernel.org/r/1438030523-15853-11-git-send-email-robh at kernel.org
http://lkml.kernel.org/r/1438030523-15853-5-git-send-email-robh at kernel.org

And these 2 toward the end of the merge window once there is no more
set_irq_flags:

http://lkml.kernel.org/r/1436711211-18223-13-git-send-email-robh at kernel.org
http://lkml.kernel.org/r/1436711211-18223-14-git-send-email-robh at kernel.org

Rob

>  drivers/irqchip/exynos-combiner.c         |  2 +-
>  drivers/irqchip/irq-armada-370-xp.c       |  3 +--
>  drivers/irqchip/irq-bcm2835.c             |  2 +-
>  drivers/irqchip/irq-clps711x.c            |  6 +++---
>  drivers/irqchip/irq-gic-v3.c              |  5 ++---
>  drivers/irqchip/irq-gic.c                 |  4 ++--
>  drivers/irqchip/irq-hip04.c               |  4 ++--
>  drivers/irqchip/irq-keystone.c            |  2 +-
>  drivers/irqchip/irq-mmp.c                 |  3 ---
>  drivers/irqchip/irq-mxs.c                 |  1 -
>  drivers/irqchip/irq-renesas-intc-irqpin.c |  1 -
>  drivers/irqchip/irq-renesas-irqc.c        |  1 -
>  drivers/irqchip/irq-s3c24xx.c             | 14 ++------------
>  drivers/irqchip/irq-sun4i.c               |  2 +-
>  drivers/irqchip/irq-versatile-fpga.c      |  2 +-
>  drivers/irqchip/irq-vic.c                 |  2 +-
>  drivers/irqchip/irq-vt8500.c              |  1 -
>  drivers/irqchip/spear-shirq.c             |  1 -
>  18 files changed, 18 insertions(+), 38 deletions(-)
>
> diff --git a/drivers/irqchip/exynos-combiner.c b/drivers/irqchip/exynos-combiner.c
> index 5c82e3b..a62cfd3 100644
> --- a/drivers/irqchip/exynos-combiner.c
> +++ b/drivers/irqchip/exynos-combiner.c
> @@ -165,7 +165,7 @@ static int combiner_irq_domain_map(struct irq_domain *d, unsigned int irq,
>
>         irq_set_chip_and_handler(irq, &combiner_chip, handle_level_irq);
>         irq_set_chip_data(irq, &combiner_data[hw >> 3]);
> -       set_irq_flags(irq, IRQF_VALID | IRQF_PROBE);
> +       irq_set_probe(irq);
>
>         return 0;
>  }
> diff --git a/drivers/irqchip/irq-armada-370-xp.c b/drivers/irqchip/irq-armada-370-xp.c
> index 0d3b0fe..017f881 100644
> --- a/drivers/irqchip/irq-armada-370-xp.c
> +++ b/drivers/irqchip/irq-armada-370-xp.c
> @@ -201,7 +201,6 @@ static int armada_370_xp_msi_map(struct irq_domain *domain, unsigned int virq,
>  {
>         irq_set_chip_and_handler(virq, &armada_370_xp_msi_irq_chip,
>                                  handle_simple_irq);
> -       set_irq_flags(virq, IRQF_VALID);
>
>         return 0;
>  }
> @@ -318,7 +317,7 @@ static int armada_370_xp_mpic_irq_map(struct irq_domain *h,
>                 irq_set_chip_and_handler(virq, &armada_370_xp_irq_chip,
>                                         handle_level_irq);
>         }
> -       set_irq_flags(virq, IRQF_VALID | IRQF_PROBE);
> +       irq_set_probe(virq);
>
>         return 0;
>  }
> diff --git a/drivers/irqchip/irq-bcm2835.c b/drivers/irqchip/irq-bcm2835.c
> index e68c3b6..9c4ba16 100644
> --- a/drivers/irqchip/irq-bcm2835.c
> +++ b/drivers/irqchip/irq-bcm2835.c
> @@ -165,7 +165,7 @@ static int __init armctrl_of_init(struct device_node *node,
>                         BUG_ON(irq <= 0);
>                         irq_set_chip_and_handler(irq, &armctrl_chip,
>                                 handle_level_irq);
> -                       set_irq_flags(irq, IRQF_VALID | IRQF_PROBE);
> +                       irq_set_probe(irq);
>                 }
>         }
>
> diff --git a/drivers/irqchip/irq-clps711x.c b/drivers/irqchip/irq-clps711x.c
> index 33127f1..2e74e81 100644
> --- a/drivers/irqchip/irq-clps711x.c
> +++ b/drivers/irqchip/irq-clps711x.c
> @@ -133,14 +133,14 @@ static int __init clps711x_intc_irq_map(struct irq_domain *h, unsigned int virq,
>                                         irq_hw_number_t hw)
>  {
>         irq_flow_handler_t handler = handle_level_irq;
> -       unsigned int flags = IRQF_VALID | IRQF_PROBE;
> +       unsigned int flags = 0;
>
>         if (!clps711x_irqs[hw].flags)
>                 return 0;
>
>         if (clps711x_irqs[hw].flags & CLPS711X_FLAG_FIQ) {
>                 handler = handle_bad_irq;
> -               flags |= IRQF_NOAUTOEN;
> +               flags |= IRQ_NOAUTOEN;
>         } else if (clps711x_irqs[hw].eoi) {
>                 handler = handle_fasteoi_irq;
>         }
> @@ -150,7 +150,7 @@ static int __init clps711x_intc_irq_map(struct irq_domain *h, unsigned int virq,
>                 writel_relaxed(0, clps711x_intc->base + clps711x_irqs[hw].eoi);
>
>         irq_set_chip_and_handler(virq, &clps711x_intc_chip, handler);
> -       set_irq_flags(virq, flags);
> +       irq_modify_status(virq, IRQ_NOPROBE, flags);
>
>         return 0;
>  }
> diff --git a/drivers/irqchip/irq-gic-v3.c b/drivers/irqchip/irq-gic-v3.c
> index c52f7ba..16f9028 100644
> --- a/drivers/irqchip/irq-gic-v3.c
> +++ b/drivers/irqchip/irq-gic-v3.c
> @@ -681,13 +681,13 @@ static int gic_irq_domain_map(struct irq_domain *d, unsigned int irq,
>                 irq_set_percpu_devid(irq);
>                 irq_domain_set_info(d, irq, hw, &gic_chip, d->host_data,
>                                     handle_percpu_devid_irq, NULL, NULL);
> -               set_irq_flags(irq, IRQF_VALID | IRQF_NOAUTOEN);
> +               irq_set_status_flags(irq, IRQ_NOAUTOEN);
>         }
>         /* SPIs */
>         if (hw >= 32 && hw < gic_data.irq_nr) {
>                 irq_domain_set_info(d, irq, hw, &gic_chip, d->host_data,
>                                     handle_fasteoi_irq, NULL, NULL);
> -               set_irq_flags(irq, IRQF_VALID | IRQF_PROBE);
> +               irq_set_probe(irq);
>         }
>         /* LPIs */
>         if (hw >= 8192 && hw < GIC_ID_NR) {
> @@ -695,7 +695,6 @@ static int gic_irq_domain_map(struct irq_domain *d, unsigned int irq,
>                         return -EPERM;
>                 irq_domain_set_info(d, irq, hw, &gic_chip, d->host_data,
>                                     handle_fasteoi_irq, NULL, NULL);
> -               set_irq_flags(irq, IRQF_VALID);
>         }
>
>         return 0;
> diff --git a/drivers/irqchip/irq-gic.c b/drivers/irqchip/irq-gic.c
> index 4dd8826..d6a1ba1 100644
> --- a/drivers/irqchip/irq-gic.c
> +++ b/drivers/irqchip/irq-gic.c
> @@ -793,11 +793,11 @@ static int gic_irq_domain_map(struct irq_domain *d, unsigned int irq,
>                 irq_set_percpu_devid(irq);
>                 irq_domain_set_info(d, irq, hw, &gic_chip, d->host_data,
>                                     handle_percpu_devid_irq, NULL, NULL);
> -               set_irq_flags(irq, IRQF_VALID | IRQF_NOAUTOEN);
> +               irq_set_status_flags(irq, IRQ_NOAUTOEN);
>         } else {
>                 irq_domain_set_info(d, irq, hw, &gic_chip, d->host_data,
>                                     handle_fasteoi_irq, NULL, NULL);
> -               set_irq_flags(irq, IRQF_VALID | IRQF_PROBE);
> +               irq_set_probe(irq);
>         }
>         return 0;
>  }
> diff --git a/drivers/irqchip/irq-hip04.c b/drivers/irqchip/irq-hip04.c
> index 0cae45d..469fba6 100644
> --- a/drivers/irqchip/irq-hip04.c
> +++ b/drivers/irqchip/irq-hip04.c
> @@ -305,11 +305,11 @@ static int hip04_irq_domain_map(struct irq_domain *d, unsigned int irq,
>                 irq_set_percpu_devid(irq);
>                 irq_set_chip_and_handler(irq, &hip04_irq_chip,
>                                          handle_percpu_devid_irq);
> -               set_irq_flags(irq, IRQF_VALID | IRQF_NOAUTOEN);
> +               irq_set_status_flags(irq, IRQ_NOAUTOEN);
>         } else {
>                 irq_set_chip_and_handler(irq, &hip04_irq_chip,
>                                          handle_fasteoi_irq);
> -               set_irq_flags(irq, IRQF_VALID | IRQF_PROBE);
> +               irq_set_probe(irq);
>         }
>         irq_set_chip_data(irq, d->host_data);
>         return 0;
> diff --git a/drivers/irqchip/irq-keystone.c b/drivers/irqchip/irq-keystone.c
> index 81e3cf5..e7090ec 100644
> --- a/drivers/irqchip/irq-keystone.c
> +++ b/drivers/irqchip/irq-keystone.c
> @@ -127,7 +127,7 @@ static int keystone_irq_map(struct irq_domain *h, unsigned int virq,
>
>         irq_set_chip_data(virq, kirq);
>         irq_set_chip_and_handler(virq, &kirq->chip, handle_level_irq);
> -       set_irq_flags(virq, IRQF_VALID | IRQF_PROBE);
> +       irq_set_probe(virq);
>         return 0;
>  }
>
> diff --git a/drivers/irqchip/irq-mmp.c b/drivers/irqchip/irq-mmp.c
> index c0da57b..3dfef63 100644
> --- a/drivers/irqchip/irq-mmp.c
> +++ b/drivers/irqchip/irq-mmp.c
> @@ -164,7 +164,6 @@ static int mmp_irq_domain_map(struct irq_domain *d, unsigned int irq,
>                               irq_hw_number_t hw)
>  {
>         irq_set_chip_and_handler(irq, &icu_irq_chip, handle_level_irq);
> -       set_irq_flags(irq, IRQF_VALID);
>         return 0;
>  }
>
> @@ -234,7 +233,6 @@ void __init icu_init_irq(void)
>         for (irq = 0; irq < 64; irq++) {
>                 icu_mask_irq(irq_get_irq_data(irq));
>                 irq_set_chip_and_handler(irq, &icu_irq_chip, handle_level_irq);
> -               set_irq_flags(irq, IRQF_VALID);
>         }
>         irq_set_default_host(icu_data[0].domain);
>         set_handle_irq(mmp_handle_irq);
> @@ -337,7 +335,6 @@ void __init mmp2_init_icu(void)
>                         irq_set_chip_and_handler(irq, &icu_irq_chip,
>                                                  handle_level_irq);
>                 }
> -               set_irq_flags(irq, IRQF_VALID);
>         }
>         irq_set_default_host(icu_data[0].domain);
>         set_handle_irq(mmp2_handle_irq);
> diff --git a/drivers/irqchip/irq-mxs.c b/drivers/irqchip/irq-mxs.c
> index 04bf97b..ffe85d6 100644
> --- a/drivers/irqchip/irq-mxs.c
> +++ b/drivers/irqchip/irq-mxs.c
> @@ -85,7 +85,6 @@ static int icoll_irq_domain_map(struct irq_domain *d, unsigned int virq,
>                                 irq_hw_number_t hw)
>  {
>         irq_set_chip_and_handler(virq, &mxs_icoll_chip, handle_level_irq);
> -       set_irq_flags(virq, IRQF_VALID);
>
>         return 0;
>  }
> diff --git a/drivers/irqchip/irq-renesas-intc-irqpin.c b/drivers/irqchip/irq-renesas-intc-irqpin.c
> index 0670ab4..20a86de 100644
> --- a/drivers/irqchip/irq-renesas-intc-irqpin.c
> +++ b/drivers/irqchip/irq-renesas-intc-irqpin.c
> @@ -343,7 +343,6 @@ static int intc_irqpin_irq_domain_map(struct irq_domain *h, unsigned int virq,
>         intc_irqpin_dbg(&p->irq[hw], "map");
>         irq_set_chip_data(virq, h->host_data);
>         irq_set_chip_and_handler(virq, &p->irq_chip, handle_level_irq);
> -       set_irq_flags(virq, IRQF_VALID); /* kill me now */
>         return 0;
>  }
>
> diff --git a/drivers/irqchip/irq-renesas-irqc.c b/drivers/irqchip/irq-renesas-irqc.c
> index 778bd07..74e980f 100644
> --- a/drivers/irqchip/irq-renesas-irqc.c
> +++ b/drivers/irqchip/irq-renesas-irqc.c
> @@ -162,7 +162,6 @@ static int irqc_irq_domain_map(struct irq_domain *h, unsigned int virq,
>         irqc_dbg(&p->irq[hw], "map");
>         irq_set_chip_data(virq, h->host_data);
>         irq_set_chip_and_handler(virq, &p->irq_chip, handle_level_irq);
> -       set_irq_flags(virq, IRQF_VALID); /* kill me now */
>         return 0;
>  }
>
> diff --git a/drivers/irqchip/irq-s3c24xx.c b/drivers/irqchip/irq-s3c24xx.c
> index e96717f..19d1fc4 100644
> --- a/drivers/irqchip/irq-s3c24xx.c
> +++ b/drivers/irqchip/irq-s3c24xx.c
> @@ -469,13 +469,11 @@ static int s3c24xx_irq_map(struct irq_domain *h, unsigned int virq,
>
>         irq_set_chip_data(virq, irq_data);
>
> -       set_irq_flags(virq, IRQF_VALID);
> -
>         if (parent_intc && irq_data->type != S3C_IRQTYPE_NONE) {
>                 if (irq_data->parent_irq > 31) {
>                         pr_err("irq-s3c24xx: parent irq %lu is out of range\n",
>                                irq_data->parent_irq);
> -                       goto err;
> +                       return -EINVAL;
>                 }
>
>                 parent_irq_data = &parent_intc->irqs[irq_data->parent_irq];
> @@ -488,18 +486,12 @@ static int s3c24xx_irq_map(struct irq_domain *h, unsigned int virq,
>                 if (!irqno) {
>                         pr_err("irq-s3c24xx: could not find mapping for parent irq %lu\n",
>                                irq_data->parent_irq);
> -                       goto err;
> +                       return -EINVAL;
>                 }
>                 irq_set_chained_handler(irqno, s3c_irq_demux);
>         }
>
>         return 0;
> -
> -err:
> -       set_irq_flags(virq, 0);
> -
> -       /* the only error can result from bad mapping data*/
> -       return -EINVAL;
>  }
>
>  static const struct irq_domain_ops s3c24xx_irq_ops = {
> @@ -1177,8 +1169,6 @@ static int s3c24xx_irq_map_of(struct irq_domain *h, unsigned int virq,
>
>         irq_set_chip_data(virq, irq_data);
>
> -       set_irq_flags(virq, IRQF_VALID);
> -
>         return 0;
>  }
>
> diff --git a/drivers/irqchip/irq-sun4i.c b/drivers/irqchip/irq-sun4i.c
> index 83d6aa6..f1f401c 100644
> --- a/drivers/irqchip/irq-sun4i.c
> +++ b/drivers/irqchip/irq-sun4i.c
> @@ -84,7 +84,7 @@ static int sun4i_irq_map(struct irq_domain *d, unsigned int virq,
>                          irq_hw_number_t hw)
>  {
>         irq_set_chip_and_handler(virq, &sun4i_irq_chip, handle_fasteoi_irq);
> -       set_irq_flags(virq, IRQF_VALID | IRQF_PROBE);
> +       irq_set_probe(virq);
>
>         return 0;
>  }
> diff --git a/drivers/irqchip/irq-versatile-fpga.c b/drivers/irqchip/irq-versatile-fpga.c
> index 888111b..e96b4fe 100644
> --- a/drivers/irqchip/irq-versatile-fpga.c
> +++ b/drivers/irqchip/irq-versatile-fpga.c
> @@ -128,7 +128,7 @@ static int fpga_irqdomain_map(struct irq_domain *d, unsigned int irq,
>         irq_set_chip_data(irq, f);
>         irq_set_chip_and_handler(irq, &f->chip,
>                                 handle_level_irq);
> -       set_irq_flags(irq, IRQF_VALID | IRQF_PROBE);
> +       irq_set_probe(irq);
>         return 0;
>  }
>
> diff --git a/drivers/irqchip/irq-vic.c b/drivers/irqchip/irq-vic.c
> index d4ce331..401561c 100644
> --- a/drivers/irqchip/irq-vic.c
> +++ b/drivers/irqchip/irq-vic.c
> @@ -202,7 +202,7 @@ static int vic_irqdomain_map(struct irq_domain *d, unsigned int irq,
>                 return -EPERM;
>         irq_set_chip_and_handler(irq, &vic_chip, handle_level_irq);
>         irq_set_chip_data(irq, v->base);
> -       set_irq_flags(irq, IRQF_VALID | IRQF_PROBE);
> +       irq_set_probe(irq);
>         return 0;
>  }
>
> diff --git a/drivers/irqchip/irq-vt8500.c b/drivers/irqchip/irq-vt8500.c
> index 0b29700..8b235c9 100644
> --- a/drivers/irqchip/irq-vt8500.c
> +++ b/drivers/irqchip/irq-vt8500.c
> @@ -168,7 +168,6 @@ static int vt8500_irq_map(struct irq_domain *h, unsigned int virq,
>                                                         irq_hw_number_t hw)
>  {
>         irq_set_chip_and_handler(virq, &vt8500_irq_chip, handle_level_irq);
> -       set_irq_flags(virq, IRQF_VALID);
>
>         return 0;
>  }
> diff --git a/drivers/irqchip/spear-shirq.c b/drivers/irqchip/spear-shirq.c
> index acb721b..e2b4e99 100644
> --- a/drivers/irqchip/spear-shirq.c
> +++ b/drivers/irqchip/spear-shirq.c
> @@ -212,7 +212,6 @@ static void __init spear_shirq_register(struct spear_shirq *shirq,
>         for (i = 0; i < shirq->nr_irqs; i++) {
>                 irq_set_chip_and_handler(shirq->virq_base + i,
>                                          shirq->irq_chip, handle_simple_irq);
> -               set_irq_flags(shirq->virq_base + i, IRQF_VALID);
>                 irq_set_chip_data(shirq->virq_base + i, shirq);
>         }
>  }
> --
> 2.1.0
>


From Suravee.Suthikulpanit at amd.com  Wed Aug 26 06:54:35 2015
From: Suravee.Suthikulpanit at amd.com (Suravee Suthikulpanit)
Date: Wed, 26 Aug 2015 20:54:35 +0700
Subject: [PATCH V3 0/4] PCI: ACPI: Setting up DMA coherency for PCI device
 from _CCA attribute
Message-ID: <1440597279-11802-1-git-send-email-Suravee.Suthikulpanit@amd.com>

This patch adds support to setup DMA coherency for PCI device using
the ACPI _CCA attribute. According to the ACPI spec, the _CCA attribute
is required for ARM64. Therefore, this patch is a pre-req for ACPI PCI
support for ARM64 which is currently in development.

Also, this should not affect other architectures that does not define 
CONFIG_ACPI_CCA_REQUIRED, since the default value is coherent.

I have included the following patch from Jeremy before cleaning up
the acpi_check_dma() function (in patch 2).

    http://www.spinics.net/lists/linux-usb/msg128582.html)

Changes from V2: (https://lkml.org/lkml/2015/8/25/549)
    * Return -ENOSUPP instead of -1 (per Rafael's suggestion)
    * Add WARN() when fail to setup DMA for PCI device when booting
      ACPI (per Arnd's suggestion)
    * Added Acked-by from Rob.
    * Minor clean up

Changes from V1: (https://lkml.org/lkml/2015/8/13/182)
    * Include patch 1 from Jeremy to enable support for _CCA=0
    * Clean up acpi_check_dma() per Bjorn suggestions
    * Split the original V1 patch into two patches (patch 3 and 4)


Jeremy Linton (1):
  Honor ACPI _CCA attribute setting

Suravee Suthikulpanit (3):
  ACPI/scan: Clean up acpi_check_dma
  PCI: OF: Move of_pci_dma_configure() to pci_dma_configure()
  PCI: ACPI: Add support for PCI device DMA coherency

 drivers/acpi/acpi_platform.c |  7 ++++++-
 drivers/acpi/glue.c          |  6 +++---
 drivers/acpi/scan.c          | 39 +++++++++++++++++++++++++++++++++++++++
 drivers/base/property.c      | 10 +++++++---
 drivers/of/of_pci.c          | 20 --------------------
 drivers/pci/probe.c          | 35 +++++++++++++++++++++++++++++++++--
 include/acpi/acpi_bus.h      | 35 ++---------------------------------
 include/linux/acpi.h         |  4 ++--
 include/linux/of_pci.h       |  3 ---
 9 files changed, 92 insertions(+), 67 deletions(-)

-- 
2.1.0



From Suravee.Suthikulpanit at amd.com  Wed Aug 26 06:54:36 2015
From: Suravee.Suthikulpanit at amd.com (Suravee Suthikulpanit)
Date: Wed, 26 Aug 2015 20:54:36 +0700
Subject: [PATCH V3 1/4] Honor ACPI _CCA attribute setting
In-Reply-To: <1440597279-11802-1-git-send-email-Suravee.Suthikulpanit@amd.com>
References: <1440597279-11802-1-git-send-email-Suravee.Suthikulpanit@amd.com>
Message-ID: <1440597279-11802-2-git-send-email-Suravee.Suthikulpanit@amd.com>

From: Jeremy Linton <jeremy.linton at arm.com>

ACPI configurations can now mark devices as noncoherent,
support that choice.

NOTE: This is required to support USB on ARM Juno Development Board.

Signed-off-by: Jeremy Linton <jeremy.linton at arm.com>
Signed-off-by: Suravee Suthikulpanit <Suravee.Suthikulpanit at amd.com>
CC: Bjorn Helgaas <bhelgaas at google.com>
CC: Catalin Marinas <catalin.marinas at arm.com>
CC: Rob Herring <robh+dt at kernel.org>
CC: Will Deacon <will.deacon at arm.com>
CC: Rafael J. Wysocki <rjw at rjwysocki.net>
---
 include/acpi/acpi_bus.h | 5 +++--
 1 file changed, 3 insertions(+), 2 deletions(-)

diff --git a/include/acpi/acpi_bus.h b/include/acpi/acpi_bus.h
index 83061ca..7ecb8e4 100644
--- a/include/acpi/acpi_bus.h
+++ b/include/acpi/acpi_bus.h
@@ -399,7 +399,7 @@ static inline bool acpi_check_dma(struct acpi_device *adev, bool *coherent)
 	 * case 1. Do not support and disable DMA.
 	 * case 2. Support but rely on arch-specific cache maintenance for
 	 *         non-coherence DMA operations.
-	 * Currently, we implement case 1 above.
+	 * Currently, we implement case 2 above.
 	 *
 	 * For the case when _CCA is missing (i.e. cca_seen=0) and
 	 * platform specifies ACPI_CCA_REQUIRED, we do not support DMA,
@@ -407,7 +407,8 @@ static inline bool acpi_check_dma(struct acpi_device *adev, bool *coherent)
 	 *
 	 * See acpi_init_coherency() for more info.
 	 */
-	if (adev->flags.coherent_dma) {
+	if (adev->flags.coherent_dma ||
+	    (adev->flags.cca_seen && IS_ENABLED(CONFIG_ARM64))) {
 		ret = true;
 		if (coherent)
 			*coherent = adev->flags.coherent_dma;
-- 
2.1.0



From Suravee.Suthikulpanit at amd.com  Wed Aug 26 06:54:37 2015
From: Suravee.Suthikulpanit at amd.com (Suravee Suthikulpanit)
Date: Wed, 26 Aug 2015 20:54:37 +0700
Subject: [PATCH V3 2/4] ACPI/scan: Clean up acpi_check_dma
In-Reply-To: <1440597279-11802-1-git-send-email-Suravee.Suthikulpanit@amd.com>
References: <1440597279-11802-1-git-send-email-Suravee.Suthikulpanit@amd.com>
Message-ID: <1440597279-11802-3-git-send-email-Suravee.Suthikulpanit@amd.com>

The original name of acpi_check_dma() function does not clearly tell what
exactly it is checking. Also, returning two boolean values (one to indicate
device is DMA capability, and the other to inidicate device coherency
attribute) can be confusing.

So, in order to simplify the function, this patch renames acpi_check_dma()
to acpi_check_dma_coherency() to clearly indicate the purpose of this
function, and only returns an integer where -1 means DMA not supported,
1 means coherent DMA, and 0 means non-coherent DMA.

Also, this patch moves the function into drivers/acpi/scan.c since
it is easier to follow the logic in the acpi_init_coherency() in the
same file here.

Signed-off-by: Suravee Suthikulpanit <Suravee.Suthikulpanit at amd.com>
Suggested-by: Bjorn Helgaas <bhelgaas at google.com>
Suggested-by: Rafael J. Wysocki <rjw at rjwysocki.net>
CC: Catalin Marinas <catalin.marinas at arm.com>
CC: Rob Herring <robh+dt at kernel.org>
CC: Will Deacon <will.deacon at arm.com>
---
 drivers/acpi/acpi_platform.c |  7 ++++++-
 drivers/acpi/glue.c          |  6 +++---
 drivers/acpi/scan.c          | 39 +++++++++++++++++++++++++++++++++++++++
 drivers/base/property.c      | 10 +++++++---
 include/acpi/acpi_bus.h      | 36 ++----------------------------------
 include/linux/acpi.h         |  4 ++--
 6 files changed, 59 insertions(+), 43 deletions(-)

diff --git a/drivers/acpi/acpi_platform.c b/drivers/acpi/acpi_platform.c
index 06a67d5..0b17a78 100644
--- a/drivers/acpi/acpi_platform.c
+++ b/drivers/acpi/acpi_platform.c
@@ -103,7 +103,12 @@ struct platform_device *acpi_create_platform_device(struct acpi_device *adev)
 	pdevinfo.res = resources;
 	pdevinfo.num_res = count;
 	pdevinfo.fwnode = acpi_fwnode_handle(adev);
-	pdevinfo.dma_mask = acpi_check_dma(adev, NULL) ? DMA_BIT_MASK(32) : 0;
+
+	if (acpi_check_dma_coherency(adev) < 0)
+		pdevinfo.dma_mask = 0;
+	else
+		pdevinfo.dma_mask = DMA_BIT_MASK(32);
+
 	pdev = platform_device_register_full(&pdevinfo);
 	if (IS_ERR(pdev))
 		dev_err(&adev->dev, "platform device creation failed: %ld\n",
diff --git a/drivers/acpi/glue.c b/drivers/acpi/glue.c
index b9657af..9be7f0f 100644
--- a/drivers/acpi/glue.c
+++ b/drivers/acpi/glue.c
@@ -168,7 +168,6 @@ int acpi_bind_one(struct device *dev, struct acpi_device *acpi_dev)
 	struct list_head *physnode_list;
 	unsigned int node_id;
 	int retval = -EINVAL;
-	bool coherent;
 
 	if (has_acpi_companion(dev)) {
 		if (acpi_dev) {
@@ -225,8 +224,9 @@ int acpi_bind_one(struct device *dev, struct acpi_device *acpi_dev)
 	if (!has_acpi_companion(dev))
 		ACPI_COMPANION_SET(dev, acpi_dev);
 
-	if (acpi_check_dma(acpi_dev, &coherent))
-		arch_setup_dma_ops(dev, 0, 0, NULL, coherent);
+	retval = acpi_check_dma_coherency(acpi_dev);
+	if (retval >= 0)
+		arch_setup_dma_ops(dev, 0, 0, NULL, retval);
 
 	acpi_physnode_link_name(physical_node_name, node_id);
 	retval = sysfs_create_link(&acpi_dev->dev.kobj, &dev->kobj,
diff --git a/drivers/acpi/scan.c b/drivers/acpi/scan.c
index ec25635..1d68289 100644
--- a/drivers/acpi/scan.c
+++ b/drivers/acpi/scan.c
@@ -2182,6 +2182,45 @@ void acpi_free_pnp_ids(struct acpi_device_pnp *pnp)
 	kfree(pnp->unique_id);
 }
 
+/**
+ * acpi_check_dma_coherency - Check DMA coherency for the specified device.
+ * @adev: The pointer to acpi device to check coherency attribute
+ *
+ * Return -ENOTSUPP if DMA is not supported. Otherwise, return 1 if the
+ * device support coherent DMA, or 0 for non-coherent DMA.
+ */
+int acpi_check_dma_coherency(struct acpi_device *adev)
+{
+	int ret = -ENOTSUPP;
+
+	if (!adev)
+		return ret;
+
+	/**
+	 * Currently, we only support _CCA=1 (i.e. coherent_dma=1)
+	 * This should be equivalent to specifying dma-coherent for
+	 * a device in OF.
+	 *
+	 * For the case when _CCA=0 (i.e. coherent_dma=0 && cca_seen=1),
+	 * we have two choices:
+	 *   1. Do not support and disable DMA.
+	 *   2. Support but rely on arch-specific cache maintenance for
+	 *      non-coherenje DMA operations.
+	 * Currently, we implement case 2 above.
+	 *
+	 * For the case when _CCA is missing (i.e. cca_seen=0) and
+	 * platform specifies ACPI_CCA_REQUIRED, we do not support DMA,
+	 * and fallback to arch-specific default handling.
+	 *
+	 * See acpi_init_coherency() for more info.
+	 */
+	if (!adev->flags.cca_seen && IS_ENABLED(CONFIG_ACPI_CCA_REQUIRED))
+		return ret;
+
+	return adev->flags.coherent_dma;
+}
+EXPORT_SYMBOL_GPL(acpi_check_dma_coherency);
+
 static void acpi_init_coherency(struct acpi_device *adev)
 {
 	unsigned long long cca = 0;
diff --git a/drivers/base/property.c b/drivers/base/property.c
index f3f6d16..cd45dfc 100644
--- a/drivers/base/property.c
+++ b/drivers/base/property.c
@@ -525,10 +525,14 @@ bool device_dma_is_coherent(struct device *dev)
 {
 	bool coherent = false;
 
-	if (IS_ENABLED(CONFIG_OF) && dev->of_node)
+	if (IS_ENABLED(CONFIG_OF) && dev->of_node) {
 		coherent = of_dma_is_coherent(dev->of_node);
-	else
-		acpi_check_dma(ACPI_COMPANION(dev), &coherent);
+	} else {
+		int ret = acpi_check_dma_coherency(ACPI_COMPANION(dev));
+
+		if (ret >= 0)
+			coherent = ret;
+	}
 
 	return coherent;
 }
diff --git a/include/acpi/acpi_bus.h b/include/acpi/acpi_bus.h
index 7ecb8e4..baf43ea 100644
--- a/include/acpi/acpi_bus.h
+++ b/include/acpi/acpi_bus.h
@@ -382,40 +382,6 @@ struct acpi_device {
 	void (*remove)(struct acpi_device *);
 };
 
-static inline bool acpi_check_dma(struct acpi_device *adev, bool *coherent)
-{
-	bool ret = false;
-
-	if (!adev)
-		return ret;
-
-	/**
-	 * Currently, we only support _CCA=1 (i.e. coherent_dma=1)
-	 * This should be equivalent to specifyig dma-coherent for
-	 * a device in OF.
-	 *
-	 * For the case when _CCA=0 (i.e. coherent_dma=0 && cca_seen=1),
-	 * There are two cases:
-	 * case 1. Do not support and disable DMA.
-	 * case 2. Support but rely on arch-specific cache maintenance for
-	 *         non-coherence DMA operations.
-	 * Currently, we implement case 2 above.
-	 *
-	 * For the case when _CCA is missing (i.e. cca_seen=0) and
-	 * platform specifies ACPI_CCA_REQUIRED, we do not support DMA,
-	 * and fallback to arch-specific default handling.
-	 *
-	 * See acpi_init_coherency() for more info.
-	 */
-	if (adev->flags.coherent_dma ||
-	    (adev->flags.cca_seen && IS_ENABLED(CONFIG_ARM64))) {
-		ret = true;
-		if (coherent)
-			*coherent = adev->flags.coherent_dma;
-	}
-	return ret;
-}
-
 static inline bool is_acpi_node(struct fwnode_handle *fwnode)
 {
 	return fwnode && fwnode->type == FWNODE_ACPI;
@@ -640,6 +606,8 @@ static inline bool acpi_device_can_poweroff(struct acpi_device *adev)
 	return adev->power.states[ACPI_STATE_D3_COLD].flags.valid;
 }
 
+int acpi_check_dma_coherency(struct acpi_device *adev);
+
 #else	/* CONFIG_ACPI */
 
 static inline int register_acpi_bus_type(void *bus) { return 0; }
diff --git a/include/linux/acpi.h b/include/linux/acpi.h
index d2445fa..d350c9e 100644
--- a/include/linux/acpi.h
+++ b/include/linux/acpi.h
@@ -562,9 +562,9 @@ static inline int acpi_device_modalias(struct device *dev,
 	return -ENODEV;
 }
 
-static inline bool acpi_check_dma(struct acpi_device *adev, bool *coherent)
+static inline int acpi_check_dma_coherency(struct acpi_device *adev)
 {
-	return false;
+	return -ENOTSUPP;
 }
 
 #define ACPI_PTR(_ptr)	(NULL)
-- 
2.1.0



From Suravee.Suthikulpanit at amd.com  Wed Aug 26 06:54:39 2015
From: Suravee.Suthikulpanit at amd.com (Suravee Suthikulpanit)
Date: Wed, 26 Aug 2015 20:54:39 +0700
Subject: [PATCH V3 4/4] PCI: ACPI: Add support for PCI device DMA coherency
In-Reply-To: <1440597279-11802-1-git-send-email-Suravee.Suthikulpanit@amd.com>
References: <1440597279-11802-1-git-send-email-Suravee.Suthikulpanit@amd.com>
Message-ID: <1440597279-11802-5-git-send-email-Suravee.Suthikulpanit@amd.com>

This patch adds support for setting up PCI device DMA coherency from
ACPI _CCA object that should normally be specified in the DSDT node
of its PCI host bridge.

Signed-off-by: Suravee Suthikulpanit <Suravee.Suthikulpanit at amd.com>
CC: Bjorn Helgaas <bhelgaas at google.com>
CC: Catalin Marinas <catalin.marinas at arm.com>
CC: Rob Herring <robh+dt at kernel.org>
CC: Will Deacon <will.deacon at arm.com>
CC: Rafael J. Wysocki <rjw at rjwysocki.net>
CC: Murali Karicheri <m-karicheri2 at ti.com>
---
 drivers/pci/probe.c | 18 +++++++++++++-----
 1 file changed, 13 insertions(+), 5 deletions(-)

diff --git a/drivers/pci/probe.c b/drivers/pci/probe.c
index 4de6594..7cfd8e2 100644
--- a/drivers/pci/probe.c
+++ b/drivers/pci/probe.c
@@ -1551,17 +1551,25 @@ static void pci_init_capabilities(struct pci_dev *dev)
  * @dev: ptr to pci_dev struct of the PCI device
  *
  * Function to update PCI devices's DMA configuration using the same
- * info from the OF node of host bridge's parent (if any).
+ * info from the OF node or ACPI node of host bridge's parent (if any).
  */
 static void pci_dma_configure(struct pci_dev *dev)
 {
 	struct device *bridge = pci_get_host_bridge_device(dev);
 
 	if (IS_ENABLED(CONFIG_OF) && dev->dev.of_node) {
-		if (!bridge->parent)
-			return;
-
-		of_dma_configure(&dev->dev, bridge->parent->of_node);
+		if (bridge->parent)
+			of_dma_configure(&dev->dev,
+					 bridge->parent->of_node);
+	} else if (has_acpi_companion(bridge)) {
+		struct acpi_device *adev = to_acpi_node(bridge->fwnode);
+		int ret = acpi_check_dma_coherency(adev);
+
+		if (ret < 0)
+			WARN(1, FW_BUG "PCI device %s fail to setup DMA.\n",
+			     pci_name(dev));
+		else
+			arch_setup_dma_ops(&dev->dev, 0, 0, NULL, ret);
 	}
 
 	pci_put_host_bridge_device(bridge);
-- 
2.1.0



From Suravee.Suthikulpanit at amd.com  Wed Aug 26 06:54:38 2015
From: Suravee.Suthikulpanit at amd.com (Suravee Suthikulpanit)
Date: Wed, 26 Aug 2015 20:54:38 +0700
Subject: [PATCH V3 3/4] PCI: OF: Move of_pci_dma_configure() to
 pci_dma_configure()
In-Reply-To: <1440597279-11802-1-git-send-email-Suravee.Suthikulpanit@amd.com>
References: <1440597279-11802-1-git-send-email-Suravee.Suthikulpanit@amd.com>
Message-ID: <1440597279-11802-4-git-send-email-Suravee.Suthikulpanit@amd.com>

This patch move of_pci_dma_configure() to a more generic
pci_dma_configure(), which can be extended by non-OF code (e.g. ACPI).

This has no functional change.

Signed-off-by: Suravee Suthikulpanit <Suravee.Suthikulpanit at amd.com>
Acked-by: Rob Herring <robh+dt at kernel.org>
CC: Bjorn Helgaas <bhelgaas at google.com>
CC: Catalin Marinas <catalin.marinas at arm.com>
CC: Will Deacon <will.deacon at arm.com>
CC: Rafael J. Wysocki <rjw at rjwysocki.net>
CC: Murali Karicheri <m-karicheri2 at ti.com>
---
 drivers/of/of_pci.c    | 20 --------------------
 drivers/pci/probe.c    | 27 +++++++++++++++++++++++++--
 include/linux/of_pci.h |  3 ---
 3 files changed, 25 insertions(+), 25 deletions(-)

diff --git a/drivers/of/of_pci.c b/drivers/of/of_pci.c
index 5751dc5..b66ee4e 100644
--- a/drivers/of/of_pci.c
+++ b/drivers/of/of_pci.c
@@ -117,26 +117,6 @@ int of_get_pci_domain_nr(struct device_node *node)
 }
 EXPORT_SYMBOL_GPL(of_get_pci_domain_nr);
 
-/**
- * of_pci_dma_configure - Setup DMA configuration
- * @dev: ptr to pci_dev struct of the PCI device
- *
- * Function to update PCI devices's DMA configuration using the same
- * info from the OF node of host bridge's parent (if any).
- */
-void of_pci_dma_configure(struct pci_dev *pci_dev)
-{
-	struct device *dev = &pci_dev->dev;
-	struct device *bridge = pci_get_host_bridge_device(pci_dev);
-
-	if (!bridge->parent)
-		return;
-
-	of_dma_configure(dev, bridge->parent->of_node);
-	pci_put_host_bridge_device(bridge);
-}
-EXPORT_SYMBOL_GPL(of_pci_dma_configure);
-
 #if defined(CONFIG_OF_ADDRESS)
 /**
  * of_pci_get_host_bridge_resources - Parse PCI host bridge resources from DT
diff --git a/drivers/pci/probe.c b/drivers/pci/probe.c
index cefd636..4de6594 100644
--- a/drivers/pci/probe.c
+++ b/drivers/pci/probe.c
@@ -6,12 +6,14 @@
 #include <linux/delay.h>
 #include <linux/init.h>
 #include <linux/pci.h>
-#include <linux/of_pci.h>
+#include <linux/of_device.h>
 #include <linux/pci_hotplug.h>
 #include <linux/slab.h>
 #include <linux/module.h>
 #include <linux/cpumask.h>
 #include <linux/pci-aspm.h>
+#include <linux/acpi.h>
+#include <linux/property.h>
 #include <asm-generic/pci-bridge.h>
 #include "pci.h"
 
@@ -1544,6 +1546,27 @@ static void pci_init_capabilities(struct pci_dev *dev)
 	pci_enable_acs(dev);
 }
 
+/**
+ * pci_dma_configure - Setup DMA configuration
+ * @dev: ptr to pci_dev struct of the PCI device
+ *
+ * Function to update PCI devices's DMA configuration using the same
+ * info from the OF node of host bridge's parent (if any).
+ */
+static void pci_dma_configure(struct pci_dev *dev)
+{
+	struct device *bridge = pci_get_host_bridge_device(dev);
+
+	if (IS_ENABLED(CONFIG_OF) && dev->dev.of_node) {
+		if (!bridge->parent)
+			return;
+
+		of_dma_configure(&dev->dev, bridge->parent->of_node);
+	}
+
+	pci_put_host_bridge_device(bridge);
+}
+
 void pci_device_add(struct pci_dev *dev, struct pci_bus *bus)
 {
 	int ret;
@@ -1557,7 +1580,7 @@ void pci_device_add(struct pci_dev *dev, struct pci_bus *bus)
 	dev->dev.dma_mask = &dev->dma_mask;
 	dev->dev.dma_parms = &dev->dma_parms;
 	dev->dev.coherent_dma_mask = 0xffffffffull;
-	of_pci_dma_configure(dev);
+	pci_dma_configure(dev);
 
 	pci_set_dma_max_seg_size(dev, 65536);
 	pci_set_dma_seg_boundary(dev, 0xffffffff);
diff --git a/include/linux/of_pci.h b/include/linux/of_pci.h
index 29fd3fe..ce0e5ab 100644
--- a/include/linux/of_pci.h
+++ b/include/linux/of_pci.h
@@ -16,7 +16,6 @@ int of_pci_get_devfn(struct device_node *np);
 int of_irq_parse_and_map_pci(const struct pci_dev *dev, u8 slot, u8 pin);
 int of_pci_parse_bus_range(struct device_node *node, struct resource *res);
 int of_get_pci_domain_nr(struct device_node *node);
-void of_pci_dma_configure(struct pci_dev *pci_dev);
 #else
 static inline int of_irq_parse_pci(const struct pci_dev *pdev, struct of_phandle_args *out_irq)
 {
@@ -51,8 +50,6 @@ of_get_pci_domain_nr(struct device_node *node)
 {
 	return -1;
 }
-
-static inline void of_pci_dma_configure(struct pci_dev *pci_dev) { }
 #endif
 
 #if defined(CONFIG_OF_ADDRESS)
-- 
2.1.0



From jogo at openwrt.org  Wed Aug 26 07:02:49 2015
From: jogo at openwrt.org (Jonas Gorski)
Date: Wed, 26 Aug 2015 16:02:49 +0200
Subject: [PATCH linux-next v5 1/5] mtd: spi-nor: notify (Q)SPI controller
 about protocol change
In-Reply-To: <464fce12d75a5ba2105456cfd0a385b2d40305ba.1440580764.git.cyrille.pitchen@atmel.com>
References: <cover.1440580764.git.cyrille.pitchen@atmel.com>
 <464fce12d75a5ba2105456cfd0a385b2d40305ba.1440580764.git.cyrille.pitchen@atmel.com>
Message-ID: <CAOiHx=n+byfsbJNhnboqDEwhruOT8uKDJ+CcES7QBqPDLVAMsw@mail.gmail.com>

On Wed, Aug 26, 2015 at 2:30 PM, Cyrille Pitchen
<cyrille.pitchen at atmel.com> wrote:
> Once the Quad SPI mode has been enabled on a Micron flash memory, this
> device expects ALL the following commands to use the SPI 4-4-4 protocol.
> The (Q)SPI controller needs to be notified about the protocol change so it
> can adapt and keep on dialoging with the Micron memory.

Doesn't that mean you need to disable quad mode on removal? Else the
following will break/fail:

insmod atmel-quadspi.ko ~> spi-nor attaches -> sees micron -> enables quad mode
rmmod atmel-quadspi.ko ~> spi-nor detaches
insmod atmel-quadspi.ko ~> spi-nor attaches -> fails to read the id
because flash is still in quad mode.

> Signed-off-by: Cyrille Pitchen <cyrille.pitchen at atmel.com>
> Acked-by: Marek Vasut <marex at denx.de>
> Acked-by: Bean Huo <beanhuo at micron.com>
> ---
>  drivers/mtd/spi-nor/spi-nor.c | 21 +++++++++++++++++++++
>  include/linux/mtd/spi-nor.h   | 13 +++++++++++++
>  2 files changed, 34 insertions(+)
>
> diff --git a/drivers/mtd/spi-nor/spi-nor.c b/drivers/mtd/spi-nor/spi-nor.c
> index c27d427fead4..c8810313a752 100644
> --- a/drivers/mtd/spi-nor/spi-nor.c
> +++ b/drivers/mtd/spi-nor/spi-nor.c
> @@ -165,6 +165,22 @@ static inline int write_disable(struct spi_nor *nor)
>         return nor->write_reg(nor, SPINOR_OP_WRDI, NULL, 0, 0);
>  }
>
> +/*
> + * Let the spi-nor framework notify lower layers, especially the driver of the
> + * (Q)SPI controller, about the new protocol to be used. Indeed, once the
> + * spi-nor framework has sent manufacturer specific commands to a memory to
> + * enable its Quad SPI mode, it should immediately after tell the QSPI
> + * controller to use the very same Quad SPI protocol as expected by the memory.
> + */
> +static inline int spi_nor_set_protocol(struct spi_nor *nor,
> +                                      enum spi_protocol proto)
> +{
> +       if (nor->set_protocol)
> +               return nor->set_protocol(nor, proto);
> +
> +       return 0;

Shouldn't the default assumption be that it won't support it? Also it
might make sense to first check if it's supported before enabling it
in the chip, so that we don't enable something just to then find out
we can't back out of it.

I also wonder if we need an extra flag for that as at least SPI has
RX_{DUAL,QUAD} and TX_{DUAL,QUAD} separated, so in theory there could
be a controller that supports quad read, but not quad write, so we
shouldn't be using the quad mode in that case. m25p80 currently sets
SPI_NOR_{DUAL,QUAD} only based on SPI_RX_{DUAL,QUAD}, so that would
then fail.

At least the n25q32 seems to support the "boring" 1_1_2 and 1_1_4
commands, so these should work in case the spi controller does not
support quad tx, but quad rx.

So maybe an additional flag for the "full" dual/quad modes would be in order.

Last but not least, the protocol probably should be stored somewhere
in the nor struct, so that users don't have to store it themselves (I
assume they will need to check it for each command again to know if
the cmd/address should be send in serial or quad mode).


Jonas


From ard.biesheuvel at linaro.org  Wed Aug 26 07:04:57 2015
From: ard.biesheuvel at linaro.org (Ard Biesheuvel)
Date: Wed, 26 Aug 2015 16:04:57 +0200
Subject: [PATCH 3/3] efi/arm64: clean up efi_get_fdt_params() interface
In-Reply-To: <1440595498-30630-4-git-send-email-leif.lindholm@linaro.org>
References: <1440595498-30630-1-git-send-email-leif.lindholm@linaro.org>
 <1440595498-30630-4-git-send-email-leif.lindholm@linaro.org>
Message-ID: <CAKv+Gu9KwJfr6x8A607CsbAvpLUG2pqLPzcXsqhvmQnrcGy_ug@mail.gmail.com>

On 26 August 2015 at 15:24, Leif Lindholm <leif.lindholm at linaro.org> wrote:
> As we now have a common debug infrastructure between core and arm64 efi,
> drop the bit of the interface passing verbose output flags around.
>
> Signed-off-by: Leif Lindholm <leif.lindholm at linaro.org>
> ---
>  arch/arm64/kernel/efi.c    | 2 +-
>  drivers/firmware/efi/efi.c | 6 ++----
>  include/linux/efi.h        | 2 +-
>  3 files changed, 4 insertions(+), 6 deletions(-)
>
> diff --git a/arch/arm64/kernel/efi.c b/arch/arm64/kernel/efi.c
> index 612ad5e..ab5eeb6 100644
> --- a/arch/arm64/kernel/efi.c
> +++ b/arch/arm64/kernel/efi.c
> @@ -201,7 +201,7 @@ void __init efi_init(void)
>         struct efi_fdt_params params;
>

Actually, one nit: struct efi_fdt_params has a verbose field that was
never used in the first place, but was added [supposedly] to convey
the same as EFI_DBG that we have now. So I think you should remove
that as well.

-- 
Ard.


>         /* Grab UEFI information placed in FDT by stub */
> -       if (!efi_get_fdt_params(&params, efi_enabled(EFI_DBG)))
> +       if (!efi_get_fdt_params(&params))
>                 return;
>
>         efi_system_table = params.system_table;
> diff --git a/drivers/firmware/efi/efi.c b/drivers/firmware/efi/efi.c
> index 78de0bd..aca6aaf 100644
> --- a/drivers/firmware/efi/efi.c
> +++ b/drivers/firmware/efi/efi.c
> @@ -492,7 +492,6 @@ static __initdata struct {
>  };
>
>  struct param_info {
> -       int verbose;
>         int found;
>         void *params;
>  };
> @@ -523,21 +522,20 @@ static int __init fdt_find_uefi_params(unsigned long node, const char *uname,
>                 else
>                         *(u64 *)dest = val;
>
> -               if (info->verbose)
> +               if (efi_enabled(EFI_DBG))
>                         pr_info("  %s: 0x%0*llx\n", dt_params[i].name,
>                                 dt_params[i].size * 2, val);
>         }
>         return 1;
>  }
>
> -int __init efi_get_fdt_params(struct efi_fdt_params *params, int verbose)
> +int __init efi_get_fdt_params(struct efi_fdt_params *params)
>  {
>         struct param_info info;
>         int ret;
>
>         pr_info("Getting EFI parameters from FDT:\n");
>
> -       info.verbose = verbose;
>         info.found = 0;
>         info.params = params;
>
> diff --git a/include/linux/efi.h b/include/linux/efi.h
> index 85ef051..b1a5b74 100644
> --- a/include/linux/efi.h
> +++ b/include/linux/efi.h
> @@ -901,7 +901,7 @@ extern void efi_initialize_iomem_resources(struct resource *code_resource,
>                 struct resource *data_resource, struct resource *bss_resource);
>  extern void efi_get_time(struct timespec *now);
>  extern void efi_reserve_boot_services(void);
> -extern int efi_get_fdt_params(struct efi_fdt_params *params, int verbose);
> +extern int efi_get_fdt_params(struct efi_fdt_params *params);
>  extern struct efi_memory_map memmap;
>  extern struct kobject *efi_kobj;
>
> --
> 2.1.4
>


From yingjoe.chen at mediatek.com  Wed Aug 26 07:10:08 2015
From: yingjoe.chen at mediatek.com (Yingjoe Chen)
Date: Wed, 26 Aug 2015 22:10:08 +0800
Subject: [PATCH 0/5] add GPT timer support for mt8173
In-Reply-To: <55DD6CC4.6010708@linaro.org>
References: <1436779969-18610-1-git-send-email-yingjoe.chen@mediatek.com>
 <55DD6CC4.6010708@linaro.org>
Message-ID: <1440598208.30139.3.camel@mtksdaap41>

On Wed, 2015-08-26 at 09:37 +0200, Daniel Lezcano wrote:
> On 07/13/2015 11:32 AM, Yingjoe Chen wrote:
> > This series add GPT timer support for mt8173. This is based on v4.2-rc1
> > and Matthias' next branch (for dts parts).
> >
> > The first 2 patches comes from 'Add SMP bringup support for mt65xx socs'
> > series [1]. I decide to move these 2 patches to this series, since it
> > is more relevent here. They are changed based on Matthias' and Daniel's
> > comments.
> >
> > [1] http://lists.infradead.org/pipermail/linux-mediatek/2015-May/000714.html
> >
> > Daniel Kurtz (1):
> >    arm64: dts: mt8173: add timer node
> >
> > Yingjoe Chen (4):
> >    clocksource: mediatek: do not enable GPT_CLK_EVT when setup
> >    clocksource: mediatek: Use GPT as sched clock source
> >    arm64: mediatek: enable MTK_TIMER
> >    clk: mediatek: add 13mhz clock for MT8173
> >
> >   arch/arm64/Kconfig                       |  1 +
> >   arch/arm64/boot/dts/mediatek/mt8173.dtsi |  9 +++++++++
> >   drivers/clk/mediatek/clk-mt8173.c        |  5 +++++
> >   drivers/clocksource/mtk_timer.c          | 26 ++++++++++++++++++++------
> >   include/dt-bindings/clock/mt8173-clk.h   |  3 ++-
> >   5 files changed, 37 insertions(+), 7 deletions(-)
> 
> Who will take this patchset ? I can take the patch 2 if needed.
> 
> 

Hi Daniel,

Please take patch 2 with your fix. Thanks.

I think patch 3(enable MTK_TIMER in Kconfig) and 5 (add timer node)
should go through Matthias' tree to arm-soc and patch 4(add 13mhz clock)
should go through James' mtk-clk tree to clk maintainer.

Joe.C




From zajec5 at gmail.com  Wed Aug 26 07:13:22 2015
From: zajec5 at gmail.com (=?UTF-8?q?Rafa=C5=82=20Mi=C5=82ecki?=)
Date: Wed, 26 Aug 2015 16:13:22 +0200
Subject: [PATCH] ARM: BCM5301X: Add DT for Netgear R7000
Message-ID: <1440598402-19106-1-git-send-email-zajec5@gmail.com>

Signed-off-by: Rafa? Mi?ecki <zajec5 at gmail.com>
---
 arch/arm/boot/dts/Makefile                  |   1 +
 arch/arm/boot/dts/bcm4709-netgear-r7000.dts | 106 ++++++++++++++++++++++++++++
 2 files changed, 107 insertions(+)
 create mode 100644 arch/arm/boot/dts/bcm4709-netgear-r7000.dts

diff --git a/arch/arm/boot/dts/Makefile b/arch/arm/boot/dts/Makefile
index 685b488..dd551bf 100644
--- a/arch/arm/boot/dts/Makefile
+++ b/arch/arm/boot/dts/Makefile
@@ -72,6 +72,7 @@ dtb-$(CONFIG_ARCH_BCM_5301X) += \
 	bcm47081-buffalo-wzr-900dhp.dtb \
 	bcm4709-asus-rt-ac87u.dtb \
 	bcm4709-buffalo-wxr-1900dhp.dtb \
+	bcm4709-netgear-r7000.dtb \
 	bcm4709-netgear-r8000.dtb
 dtb-$(CONFIG_ARCH_BCM_63XX) += \
 	bcm963138dvt.dtb
diff --git a/arch/arm/boot/dts/bcm4709-netgear-r7000.dts b/arch/arm/boot/dts/bcm4709-netgear-r7000.dts
new file mode 100644
index 0000000..a22ed14
--- /dev/null
+++ b/arch/arm/boot/dts/bcm4709-netgear-r7000.dts
@@ -0,0 +1,106 @@
+/*
+ * Broadcom BCM470X / BCM5301X ARM platform code.
+ * DTS for Netgear R7000
+ *
+ * Copyright (C) 2015 Rafa? Mi?ecki <zajec5 at gmail.com>
+ *
+ * Licensed under the GNU/GPL. See COPYING for details.
+ */
+
+/dts-v1/;
+
+#include "bcm4708.dtsi"
+#include "bcm5301x-nand-cs0-bch8.dtsi"
+
+/ {
+	compatible = "netgear,r7000", "brcm,bcm4709", "brcm,bcm4708";
+	model = "Netgear R7000";
+
+	chosen {
+		bootargs = "console=ttyS0,115200";
+	};
+
+	memory {
+		reg = <0x00000000 0x08000000>;
+	};
+
+	leds {
+		compatible = "gpio-leds";
+
+		power-white {
+			label = "bcm53xx:white:power";
+			gpios = <&chipcommon 2 GPIO_ACTIVE_LOW>;
+			linux,default-trigger = "default-on";
+		};
+
+		power-amber {
+			label = "bcm53xx:amber:power";
+			gpios = <&chipcommon 3 GPIO_ACTIVE_LOW>;
+			linux,default-trigger = "default-off";
+		};
+
+		5ghz {
+			label = "bcm53xx:white:5ghz";
+			gpios = <&chipcommon 12 GPIO_ACTIVE_LOW>;
+			linux,default-trigger = "default-off";
+		};
+
+		2ghz {
+			label = "bcm53xx:white:2ghz";
+			gpios = <&chipcommon 13 GPIO_ACTIVE_LOW>;
+			linux,default-trigger = "default-off";
+		};
+
+		wps {
+			label = "bcm53xx:white:wps";
+			gpios = <&chipcommon 14 GPIO_ACTIVE_HIGH>;
+			linux,default-trigger = "default-off";
+		};
+
+		wireless {
+			label = "bcm53xx:white:wireless";
+			gpios = <&chipcommon 15 GPIO_ACTIVE_HIGH>;
+			linux,default-trigger = "default-off";
+		};
+
+		usb3 {
+			label = "bcm53xx:white:usb3";
+			gpios = <&chipcommon 17 GPIO_ACTIVE_LOW>;
+			linux,default-trigger = "default-off";
+		};
+
+		usb2 {
+			label = "bcm53xx:white:usb2";
+			gpios = <&chipcommon 18 GPIO_ACTIVE_LOW>;
+			linux,default-trigger = "default-off";
+		};
+	};
+
+	gpio-keys {
+		compatible = "gpio-keys";
+		#address-cells = <1>;
+		#size-cells = <0>;
+
+		wps {
+			label = "WPS";
+			linux,code = <KEY_WPS_BUTTON>;
+			gpios = <&chipcommon 4 GPIO_ACTIVE_LOW>;
+		};
+
+		rfkill {
+			label = "WiFi";
+			linux,code = <KEY_RFKILL>;
+			gpios = <&chipcommon 5 GPIO_ACTIVE_LOW>;
+		};
+
+		restart {
+			label = "Reset";
+			linux,code = <KEY_RESTART>;
+			gpios = <&chipcommon 6 GPIO_ACTIVE_LOW>;
+		};
+	};
+};
+
+&uart0 {
+	status = "okay";
+};
-- 
1.8.4.5



From msalter at redhat.com  Wed Aug 26 07:15:03 2015
From: msalter at redhat.com (Mark Salter)
Date: Wed, 26 Aug 2015 10:15:03 -0400
Subject: [PATCH 3/3] efi/arm64: clean up efi_get_fdt_params() interface
In-Reply-To: <CAKv+Gu9KwJfr6x8A607CsbAvpLUG2pqLPzcXsqhvmQnrcGy_ug@mail.gmail.com>
References: <1440595498-30630-1-git-send-email-leif.lindholm@linaro.org>
 <1440595498-30630-4-git-send-email-leif.lindholm@linaro.org>
 <CAKv+Gu9KwJfr6x8A607CsbAvpLUG2pqLPzcXsqhvmQnrcGy_ug@mail.gmail.com>
Message-ID: <1440598503.13044.1.camel@redhat.com>

On Wed, 2015-08-26 at 16:04 +0200, Ard Biesheuvel wrote:
> On 26 August 2015 at 15:24, Leif Lindholm <leif.lindholm at linaro.org> 
> wrote:
> > As we now have a common debug infrastructure between core and arm64 
> > efi,
> > drop the bit of the interface passing verbose output flags around.
> > 
> > Signed-off-by: Leif Lindholm <leif.lindholm at linaro.org>
> > ---
> >  arch/arm64/kernel/efi.c    | 2 +-
> >  drivers/firmware/efi/efi.c | 6 ++----
> >  include/linux/efi.h        | 2 +-
> >  3 files changed, 4 insertions(+), 6 deletions(-)
> > 
> > diff --git a/arch/arm64/kernel/efi.c b/arch/arm64/kernel/efi.c
> > index 612ad5e..ab5eeb6 100644
> > --- a/arch/arm64/kernel/efi.c
> > +++ b/arch/arm64/kernel/efi.c
> > @@ -201,7 +201,7 @@ void __init efi_init(void)
> >         struct efi_fdt_params params;
> > 
> 
> Actually, one nit: struct efi_fdt_params has a verbose field that was

No it doesn't. :)

> never used in the first place, but was added [supposedly] to convey
> the same as EFI_DBG that we have now. So I think you should remove
> that as well.
> 



From ard.biesheuvel at linaro.org  Wed Aug 26 07:16:24 2015
From: ard.biesheuvel at linaro.org (Ard Biesheuvel)
Date: Wed, 26 Aug 2015 16:16:24 +0200
Subject: [PATCH 3/3] efi/arm64: clean up efi_get_fdt_params() interface
In-Reply-To: <1440598503.13044.1.camel@redhat.com>
References: <1440595498-30630-1-git-send-email-leif.lindholm@linaro.org>
 <1440595498-30630-4-git-send-email-leif.lindholm@linaro.org>
 <CAKv+Gu9KwJfr6x8A607CsbAvpLUG2pqLPzcXsqhvmQnrcGy_ug@mail.gmail.com>
 <1440598503.13044.1.camel@redhat.com>
Message-ID: <CAKv+Gu_jVAq0CGh1J+H3Yufwd2Gx3kU=8ZsVfawoi2VKjYxE9A@mail.gmail.com>

On 26 August 2015 at 16:15, Mark Salter <msalter at redhat.com> wrote:
> On Wed, 2015-08-26 at 16:04 +0200, Ard Biesheuvel wrote:
>> On 26 August 2015 at 15:24, Leif Lindholm <leif.lindholm at linaro.org>
>> wrote:
>> > As we now have a common debug infrastructure between core and arm64
>> > efi,
>> > drop the bit of the interface passing verbose output flags around.
>> >
>> > Signed-off-by: Leif Lindholm <leif.lindholm at linaro.org>
>> > ---
>> >  arch/arm64/kernel/efi.c    | 2 +-
>> >  drivers/firmware/efi/efi.c | 6 ++----
>> >  include/linux/efi.h        | 2 +-
>> >  3 files changed, 4 insertions(+), 6 deletions(-)
>> >
>> > diff --git a/arch/arm64/kernel/efi.c b/arch/arm64/kernel/efi.c
>> > index 612ad5e..ab5eeb6 100644
>> > --- a/arch/arm64/kernel/efi.c
>> > +++ b/arch/arm64/kernel/efi.c
>> > @@ -201,7 +201,7 @@ void __init efi_init(void)
>> >         struct efi_fdt_params params;
>> >
>>
>> Actually, one nit: struct efi_fdt_params has a verbose field that was
>
> No it doesn't. :)
>

OK, must have been something I added myself locally then.
Never mind.


From cov at codeaurora.org  Wed Aug 26 07:19:39 2015
From: cov at codeaurora.org (Christopher Covington)
Date: Wed, 26 Aug 2015 10:19:39 -0400
Subject: [PATCH] arm: Handle starting up in secure mode
In-Reply-To: <20150826104839.GC21084@n2100.arm.linux.org.uk>
References: <1440424572-27116-1-git-send-email-cov@codeaurora.org>
 <20150826103940.GD6281@e103592.cambridge.arm.com>
 <20150826104839.GC21084@n2100.arm.linux.org.uk>
Message-ID: <55DDCAFB.60602@codeaurora.org>

Hi,

Thank you for the feedback.

On 08/26/2015 06:48 AM, Russell King - ARM Linux wrote:
> On Wed, Aug 26, 2015 at 11:39:42AM +0100, Dave Martin wrote:
>> On Mon, Aug 24, 2015 at 09:55:26AM -0400, Christopher Covington wrote:
>>> ARM Linux appears to have never been made aware of the ARMv7 security
>>> extensions. When CONFIG_ARM_SEC_EXT=y, have it probe for its security
>>> state by checking whether CNTFRQ is writeable and potentially make
>>> mode changes based on the information. The most features are available
>>> from hypervisor (HYP) mode, so switch to it possible. Failing that,
>>> prefer non-secure supervisor (SVC) mode to secure supervisor mode.
>>
>> Up to now we've steered clear of this, since it's a bit of a fig leaf
>> for broken firmware unless Linux actually has some valid use for the
>> Security Extensions itself.
>>
>> Shouldn't the bootloader or firmware be doing this stuff, and if not,
>> why not?

In my opinion, it is sometimes useful, particularly when running on simulators
or performing bring up, to have as little dependency on firmwares and
bootloaders as possible. I want to run Linux out of reset, or get as close to
that as possible. I want an ease of use comparable to QEMU's Linux loader on
other simulators, like ARM's RTSM/AEM/FVPs, without various different,
fragmented model plugins or the overhead and noise of the semihosting
bootwrapper. I have attempted to craft the patches in such a way that the
enjoyment of sophisticated firmwares and bootloaders remains unhindered.

>> Some other things that would need to be considered in any case:
>>
>>  * SoC-specific setup of the Non-secure view of the system:  This has
>>    to happen very early, so making it DT aware is going to be hard --
>>    failing that, we are effectively risking bringing back board files.
>>    The split in responsibility between firmware/bootloader and kernel
>>    needs to be clearly defined and (as far as possible) platform-
>>    independent, otherwise we'll have total chaos.

My intention was to only perform architecturally defined initialization. All
implementation defined specifics would remain delegated to firmware, simulator
reset state hacks, or external debuggers, as the case may be. Note that using
this code does not preclude running firmware, just that if you want Linux to
do the exception level/mode transitions, you can omit those instructions from
firmware. I'll have to refresh my memory--it's been a while since I worked on
this, I apologize--but I think I used a modified bootwrapper to still perform
its usual GIC initialization.

>>  * Out of reset, generally the CPU state is only fully defined for the
>>    highest exception level.  You probably need to be doing more setup
>>    than you're currently doing.

Agreed. This is just the first step.

>>  * SMP, secondary boot and suspend/resume -- again involving board-
>>    specific code.

I've only tested single core so far, but I was thinking external debuggers and
simulators may be able to emulate PSCI in a semihosting-like manner, if
merging holding pen code is as frowned upon as I think it is (that may be an
AArch64-specific statement, but it'd probably be nice if similar facilities
were available across A32 and A64).

>>  * You need to safely "park" the Secure World before running anything
>>    in Non-Secure.  As a minimum, you would need to quiesce any
>>    Secure interrupt sources, disable all interrupt traps to Monitor
>>    mode, and make sure that the Monitor vectors point somewhere
>>    real, so that executing SMC doesn't send the CPU off into the
>>    long grass...

Thanks. I'll work towards support for these aspects in the next version.

> Another question is: has this been tested with kexec?

I have not tested it with kexec. My testing was mostly of cold boots performed
some time back on ARM's AEM/RSTM/FVP using its configurable parameters and
some simple custom firmwares to simulate entry under all the circumstances I
could think of. I grepped instruction traces to make sure the initial mode
after firmware was as intended and then that AArch32 Linux switched into the
intended mode.

EL3: not present, AArch64, AArch32
EL2: not present, AArch64, AArch32
AArch32 Linux starts in: svc_s, svc_n, hyp_n, mon_s

By my calculations, there were 36 - 17 = 19 valid combinations.

Thanks,
Christopher Covington

-- 
Qualcomm Innovation Center, Inc.
The Qualcomm Innovation Center, Inc. is a member of the Code Aurora Forum,
a Linux Foundation Collaborative Project


From daniel.lezcano at linaro.org  Wed Aug 26 07:25:15 2015
From: daniel.lezcano at linaro.org (Daniel Lezcano)
Date: Wed, 26 Aug 2015 16:25:15 +0200
Subject: [PATCH V2] clockevents/drivers/mtk: Fix spurious interrupt leading
 to crash
In-Reply-To: <1440508871.29634.1.camel@mtksdaap41>
References: <1440426924.17418.11.camel@mtksdaap41>	
 <1440453450-21203-1-git-send-email-daniel.lezcano@linaro.org>
 <1440508871.29634.1.camel@mtksdaap41>
Message-ID: <55DDCC4B.7010203@linaro.org>

On 08/25/2015 03:21 PM, Yingjoe Chen wrote:
> Tested-by: Yingjoe Chen<yingjoe.chen at mediatek.com>

Applied to my tree for 4.4.

   -- Daniel

-- 
  <http://www.linaro.org/> Linaro.org ? Open source software for ARM SoCs

Follow Linaro:  <http://www.facebook.com/pages/Linaro> Facebook |
<http://twitter.com/#!/linaroorg> Twitter |
<http://www.linaro.org/linaro-blog/> Blog



From robherring2 at gmail.com  Wed Aug 26 07:30:17 2015
From: robherring2 at gmail.com (Rob Herring)
Date: Wed, 26 Aug 2015 09:30:17 -0500
Subject: [PATCH 1/7] drm/vc4: Add devicetree bindings for VC4.
In-Reply-To: <20150826120934.GC320@ulmo.nvidia.com>
References: <1439427380-2436-1-git-send-email-eric@anholt.net>
 <1439427380-2436-2-git-send-email-eric@anholt.net>
 <55CEC25E.7070303@wwwdotorg.org>
 <874mjxwyx5.fsf@eliezer.anholt.net>
 <CAL_JsqJxiGUR5BxBPyR3-0NxqWsOxMGrWQA6cMXe2pjTom__nw@mail.gmail.com>
 <CAF6AEGu2fi0M7DsicHz+5SDHi1DyDRmvWjkmYPPgY6pZ423WcA@mail.gmail.com>
 <20150826115229.GI1367@phenom.ffwll.local>
 <20150826120934.GC320@ulmo.nvidia.com>
Message-ID: <CAL_JsqJ2v=wBaUe_gN_UcpQKis+kRH6oa0NTN24Lp9w9LVWtbQ@mail.gmail.com>

On Wed, Aug 26, 2015 at 7:09 AM, Thierry Reding
<thierry.reding at gmail.com> wrote:
> On Wed, Aug 26, 2015 at 01:52:29PM +0200, Daniel Vetter wrote:
>> On Tue, Aug 25, 2015 at 04:42:18PM -0400, Rob Clark wrote:
>> > On Mon, Aug 24, 2015 at 9:47 AM, Rob Herring <robherring2 at gmail.com> wrote:
>> > > On Mon, Aug 17, 2015 at 1:30 PM, Eric Anholt <eric at anholt.net> wrote:
>> > >> Stephen Warren <swarren at wwwdotorg.org> writes:
>> > >>
>> > >>> On 08/12/2015 06:56 PM, Eric Anholt wrote:
>> > >>>> Signed-off-by: Eric Anholt <eric at anholt.net>
>> > >>>
>> > >>> This one definitely needs a patch description, since someone might not
>> > >>> know what a VC4 is, and "git log" won't show the text from the binding
>> > >>> doc itself. I'd suggest adding the initial paragraph of the binding doc
>> > >>> as the patch description, or more.
>> > >>>
>> > >>>> diff --git a/Documentation/devicetree/bindings/gpu/brcm,bcm-vc4.txt b/Documentation/devicetree/bindings/gpu/brcm,bcm-vc4.txt
>> > >>
>> > >>>> +- hvss:             List of references to HVS video scalers
>> > >>>> +- encoders: List of references to output encoders (HDMI, SDTV)
>> > >>>
>> > >>> Would it make sense to make all those nodes child node of the vc4
>> > >>> object. That way, there's no need to have these lists of objects; they
>> > >>> can be automatically built up as the DT is enumerated. I know that e.g.
>> > >>> the NVIDIA Tegra host1x binding works this way, and I think it may have
>> > >>> been inspired by other similar cases.
>> > >>
>> > >> I've looked at tegra, and the component system used by msm appears to be
>> > >> nicer than it.  To follow tegra's model, it looks like I need to build
>> > >> this extra bus thing corresponding to host1x that is effectively the
>> > >> drivers/base/component.c code, so that I can get at vc4's structure from
>> > >> the component drivers.
>> > >>
>> > >>> Of course, this is only appropriate if the HW modules really are
>> > >>> logically children of the VC4 HW module. Perhaps they aren't. If they
>> > >>> aren't though, I wonder what this "vc4" module actually represents in HW?
>> > >>
>> > >> It's the subsystem, same as we use a subsystem node for msm, sti,
>> > >> rockchip, imx, and exynos.  This appears to be the common model of how
>> > >> the collection of graphics-related components is represented in the DT.
>> > >
>> > > I think most of these bindings are wrong. They are grouped together
>> > > because that is what DRM wants not because that reflects the h/w. So
>> > > convince me this is one block, not that it is what other people do.
>> >
>> > I think, when it comes to more complex driver subsystems (like drm in
>> > particular) we have a bit of mismatch between how things look from the
>> > "pure hw ignoring sw" perspective, and the "how sw and in particular
>> > userspace expects things" perspective.  Maybe it is less a problem in
>> > other subsystems, where bindings map to things that are only visible
>> > in the kernel, or well defined devices like uart or sata controller.
>> > But when given the choice, I'm going to err on the side of not
>> > confusing userspace and the large software stack that sits above
>> > drm/kms, over dt purity.
>> >
>> > Maybe it would be nice to have a sort of dt overlay that adds the bits
>> > needed to tie together hw blocks that should be assembled into a
>> > single logical device for linux and userspace (but maybe not some
>> > other hypothetical operating system).  But so far that doesn't exist.
>> > All we have is a hammer (devicetree), everything looks like a nail.
>> > End result is we end up adding some things in the bindings which
>> > aren't purely about the hw.  Until someone invents a screwdriver, I'm
>> > not sure what else to do.  In the end, other hypothetical OS is free
>> > to ignore those extra fields in the bindings if it doesn't need them.
>> > So meh?
>>
>> I thought we agreed a while back that these kind of "pull everything for
>> the logical device together" dt nodes which just have piles of phandles
>> are totally accepted? At least that's the point behind the component
>> helpers, and Eric even suggested to create dt-specific component helpers
>> to cut down a bit on the usual boilerplate. dt maintainers are also fine
>> with this approach afaik. From my understanding tegra with the host1x bus
>> really is the odd one out and not the norm.
>
> I agree that in many aspects Tegra is somewhat special. But the same
> principles that the host1x infrastructure uses could be implemented in a
> similar way for other DRM drivers. You can easily collect information
> about subdevices by walking the device tree and matching on known
> compatible strings. And you can also instantiate the top-level device
> from driver code rather than have it in DT. It should still be possible
> to make this work without an artificial device node in DT. The component
> and master infrastructure is largely orthogonal to that, and as far as I
> remember the only blocker is the need for a top-level device. I wonder
> if perhaps this could be made to work by binding the master to the top-
> level SoC device.
>
> Obviously adding the node in DT is easier, but to my knowledge easy has
> never been a good excuse for mangling DT. Perhaps that's different these
> days...

I agree we should avoid the virtual node if possible. It is certainly
possible as I started out with one and removed it. At least in my
case, it essentially required the drm_device and crtc to be a single
driver rather than 2 components. However, I'm more concerned that we
are consistent from platform to platform where it makes sense than
whether we have a somewhat questionable node or not.

Rob


From marex at denx.de  Wed Aug 26 07:39:02 2015
From: marex at denx.de (Marek Vasut)
Date: Wed, 26 Aug 2015 16:39:02 +0200
Subject: [PATCH linux-next v5 3/5] mtd: spi-nor: allow to tune the number
 of dummy cycles
In-Reply-To: <4324f398c0e69e3057e7da6a1a3e0328b44f224f.1440580764.git.cyrille.pitchen@atmel.com>
References: <cover.1440580764.git.cyrille.pitchen@atmel.com>
 <4324f398c0e69e3057e7da6a1a3e0328b44f224f.1440580764.git.cyrille.pitchen@atmel.com>
Message-ID: <201508261639.02377.marex@denx.de>

On Wednesday, August 26, 2015 at 02:30:25 PM, Cyrille Pitchen wrote:
> The number of dummy cycles used during Fast Read commands can be reduced
> to improve transfer performances. Each manufacturer has a dedicated set of
> registers to provide the memory with the exact number of dummy cycles it
> should expect. Both the memory and the (Q)SPI controller must agree on
> this number of dummy cycles.
> 
> The number of dummy cycles can be found into the memory datasheet and
> mostly depends on the SPI clock frequency, the Fast Read op code and the
> Single/Dual Data Rate mode.
> 
> Probing JEDEC Serial Flash Discoverable Parameters (SFDP) tables would
> only provide the driver with a high enough number of dummy cycles for each
> Fast Read command to be used for all clock frequencies: this solution
> would not be optimized.
> 
> Signed-off-by: Cyrille Pitchen <cyrille.pitchen at atmel.com>

Acked-by: Marek Vasut <marex at denx.de>

Best regards,
Marek Vasut


From leif.lindholm at linaro.org  Wed Aug 26 07:43:25 2015
From: leif.lindholm at linaro.org (Leif Lindholm)
Date: Wed, 26 Aug 2015 15:43:25 +0100
Subject: [PATCH v2 1/5] arm64: clone early_init_dt_add_memory_arch() to
 override default
In-Reply-To: <1440576391-25725-2-git-send-email-ard.biesheuvel@linaro.org>
References: <1440576391-25725-1-git-send-email-ard.biesheuvel@linaro.org>
 <1440576391-25725-2-git-send-email-ard.biesheuvel@linaro.org>
Message-ID: <20150826144325.GA10728@bivouac.eciton.net>

On Wed, Aug 26, 2015 at 10:06:27AM +0200, Ard Biesheuvel wrote:
> Override the __weak early_init_dt_add_memory_arch() with our own
> version. We need this in a subsequent patch to make the handling of
> the memory nodes conditional on whether we are booting via UEFI or
> not.

Worth clarifying that this is a direct copy?
("Our own version" can be read as there being modifications here.)

> Signed-off-by: Ard Biesheuvel <ard.biesheuvel at linaro.org>
> ---
>  arch/arm64/mm/init.c | 41 ++++++++++++++++++++
>  1 file changed, 41 insertions(+)
> 
> diff --git a/arch/arm64/mm/init.c b/arch/arm64/mm/init.c
> index f5c0680d17d9..ab25fde7397c 100644
> --- a/arch/arm64/mm/init.c
> +++ b/arch/arm64/mm/init.c
> @@ -374,3 +374,44 @@ static int __init keepinitrd_setup(char *__unused)
>  
>  __setup("keepinitrd", keepinitrd_setup);
>  #endif
> +
> +void __init early_init_dt_add_memory_arch(u64 base, u64 size)
> +{
> +	const u64 phys_offset = __pa(PAGE_OFFSET);
> +
> +	if (!PAGE_ALIGNED(base)) {
> +		if (size < PAGE_SIZE - (base & ~PAGE_MASK)) {
> +			pr_warn("Ignoring memory block 0x%llx - 0x%llx\n",
> +				base, base + size);
> +			return;
> +		}
> +		size -= PAGE_SIZE - (base & ~PAGE_MASK);
> +		base = PAGE_ALIGN(base);
> +	}
> +	size &= PAGE_MASK;
> +
> +	if (base > MAX_MEMBLOCK_ADDR) {
> +		pr_warning("Ignoring memory block 0x%llx - 0x%llx\n",
> +				base, base + size);
> +		return;
> +	}
> +
> +	if (base + size - 1 > MAX_MEMBLOCK_ADDR) {
> +		pr_warning("Ignoring memory range 0x%llx - 0x%llx\n",
> +				((u64)MAX_MEMBLOCK_ADDR) + 1, base + size);
> +		size = MAX_MEMBLOCK_ADDR - base + 1;
> +	}
> +
> +	if (base + size < phys_offset) {
> +		pr_warning("Ignoring memory block 0x%llx - 0x%llx\n",
> +			   base, base + size);
> +		return;
> +	}
> +	if (base < phys_offset) {
> +		pr_warning("Ignoring memory range 0x%llx - 0x%llx\n",
> +			   base, phys_offset);
> +		size -= phys_offset - base;
> +		base = phys_offset;
> +	}
> +	memblock_add(base, size);
> +}
> -- 
> 1.9.1

Would it be too crazy to do this via an added call to a weak
memblock_use_dt() function in the original instead, to avoid
duplicating this entire function?

We need the functionality for 4/5 (nice cleanup) and 5/5 (bugfix), so
happy with whatever works.

/
    Leif


From leif.lindholm at linaro.org  Wed Aug 26 07:47:39 2015
From: leif.lindholm at linaro.org (Leif Lindholm)
Date: Wed, 26 Aug 2015 15:47:39 +0100
Subject: [PATCH v2 2/5] efi: move FDT handling to separate object file
In-Reply-To: <1440576391-25725-3-git-send-email-ard.biesheuvel@linaro.org>
References: <1440576391-25725-1-git-send-email-ard.biesheuvel@linaro.org>
 <1440576391-25725-3-git-send-email-ard.biesheuvel@linaro.org>
Message-ID: <20150826144739.GB10728@bivouac.eciton.net>

On Wed, Aug 26, 2015 at 10:06:28AM +0200, Ard Biesheuvel wrote:
> The EFI specific FDT handling is compiled conditionally, and is
> logically independent of the rest of efi.o. So move it to a separate
> file before making changes to it in subsequent patches.
> 
> Acked-by: Matt Fleming <matt.fleming at intel.com>
> Signed-off-by: Ard Biesheuvel <ard.biesheuvel at linaro.org>
> ---
>  drivers/firmware/efi/Makefile  |  1 +
>  drivers/firmware/efi/efi-fdt.c | 93 ++++++++++++++++++++
>  drivers/firmware/efi/efi.c     | 86 ------------------
>  3 files changed, 94 insertions(+), 86 deletions(-)

Acked-by: Leif Lindholm <leif.lindholm at linaro.org>

> diff --git a/drivers/firmware/efi/Makefile b/drivers/firmware/efi/Makefile
> index 6fd3da938717..d9140208fc1c 100644
> --- a/drivers/firmware/efi/Makefile
> +++ b/drivers/firmware/efi/Makefile
> @@ -9,3 +9,4 @@ obj-$(CONFIG_UEFI_CPER)			+= cper.o
>  obj-$(CONFIG_EFI_RUNTIME_MAP)		+= runtime-map.o
>  obj-$(CONFIG_EFI_RUNTIME_WRAPPERS)	+= runtime-wrappers.o
>  obj-$(CONFIG_EFI_STUB)			+= libstub/
> +obj-$(CONFIG_EFI_PARAMS_FROM_FDT)	+= efi-fdt.o
> diff --git a/drivers/firmware/efi/efi-fdt.c b/drivers/firmware/efi/efi-fdt.c
> new file mode 100644
> index 000000000000..f0e7ef2ae0e9
> --- /dev/null
> +++ b/drivers/firmware/efi/efi-fdt.c
> @@ -0,0 +1,93 @@
> +/*
> + * Copyright (C) 2013 - 2015 Linaro Ltd.
> + *
> + * This program is free software; you can redistribute it and/or modify
> + * it under the terms of the GNU General Public License version 2 as
> + * published by the Free Software Foundation.
> + */
> +
> +#include <linux/init.h>
> +#include <linux/efi.h>
> +#include <linux/of.h>
> +#include <linux/of_fdt.h>
> +
> +#define UEFI_PARAM(name, prop, field)			   \
> +	{						   \
> +		{ name },				   \
> +		{ prop },				   \
> +		offsetof(struct efi_fdt_params, field),    \
> +		FIELD_SIZEOF(struct efi_fdt_params, field) \
> +	}
> +
> +static __initdata struct {
> +	const char name[32];
> +	const char propname[32];
> +	int offset;
> +	int size;
> +} dt_params[] = {
> +	UEFI_PARAM("System Table", "linux,uefi-system-table", system_table),
> +	UEFI_PARAM("MemMap Address", "linux,uefi-mmap-start", mmap),
> +	UEFI_PARAM("MemMap Size", "linux,uefi-mmap-size", mmap_size),
> +	UEFI_PARAM("MemMap Desc. Size", "linux,uefi-mmap-desc-size", desc_size),
> +	UEFI_PARAM("MemMap Desc. Version", "linux,uefi-mmap-desc-ver", desc_ver)
> +};
> +
> +struct param_info {
> +	int verbose;
> +	int found;
> +	void *params;
> +};
> +
> +static int __init fdt_find_uefi_params(unsigned long node, const char *uname,
> +				       int depth, void *data)
> +{
> +	struct param_info *info = data;
> +	const void *prop;
> +	void *dest;
> +	u64 val;
> +	int i, len;
> +
> +	if (depth != 1 || strcmp(uname, "chosen") != 0)
> +		return 0;
> +
> +	for (i = 0; i < ARRAY_SIZE(dt_params); i++) {
> +		prop = of_get_flat_dt_prop(node, dt_params[i].propname, &len);
> +		if (!prop)
> +			return 0;
> +		dest = info->params + dt_params[i].offset;
> +		info->found++;
> +
> +		val = of_read_number(prop, len / sizeof(u32));
> +
> +		if (dt_params[i].size == sizeof(u32))
> +			*(u32 *)dest = val;
> +		else
> +			*(u64 *)dest = val;
> +
> +		if (info->verbose)
> +			pr_info("  %s: 0x%0*llx\n", dt_params[i].name,
> +				dt_params[i].size * 2, val);
> +	}
> +	return 1;
> +}
> +
> +int __init efi_get_fdt_params(struct efi_fdt_params *params, int verbose)
> +{
> +	struct param_info info;
> +	int ret;
> +
> +	pr_info("Getting EFI parameters from FDT:\n");
> +
> +	info.verbose = verbose;
> +	info.found = 0;
> +	info.params = params;
> +
> +	ret = of_scan_flat_dt(fdt_find_uefi_params, &info);
> +	if (!info.found)
> +		pr_info("UEFI not found.\n");
> +	else if (!ret)
> +		pr_err("Can't find '%s' in device tree!\n",
> +		       dt_params[info.found].name);
> +
> +	return ret;
> +}
> diff --git a/drivers/firmware/efi/efi.c b/drivers/firmware/efi/efi.c
> index 9fa8084a7c8d..f975a1a45b80 100644
> --- a/drivers/firmware/efi/efi.c
> +++ b/drivers/firmware/efi/efi.c
> @@ -20,8 +20,6 @@
>  #include <linux/init.h>
>  #include <linux/device.h>
>  #include <linux/efi.h>
> -#include <linux/of.h>
> -#include <linux/of_fdt.h>
>  #include <linux/io.h>
>  #include <linux/platform_device.h>
>  
> @@ -460,90 +458,6 @@ static int __init efi_load_efivars(void)
>  device_initcall(efi_load_efivars);
>  #endif
>  
> -#ifdef CONFIG_EFI_PARAMS_FROM_FDT
> -
> -#define UEFI_PARAM(name, prop, field)			   \
> -	{						   \
> -		{ name },				   \
> -		{ prop },				   \
> -		offsetof(struct efi_fdt_params, field),    \
> -		FIELD_SIZEOF(struct efi_fdt_params, field) \
> -	}
> -
> -static __initdata struct {
> -	const char name[32];
> -	const char propname[32];
> -	int offset;
> -	int size;
> -} dt_params[] = {
> -	UEFI_PARAM("System Table", "linux,uefi-system-table", system_table),
> -	UEFI_PARAM("MemMap Address", "linux,uefi-mmap-start", mmap),
> -	UEFI_PARAM("MemMap Size", "linux,uefi-mmap-size", mmap_size),
> -	UEFI_PARAM("MemMap Desc. Size", "linux,uefi-mmap-desc-size", desc_size),
> -	UEFI_PARAM("MemMap Desc. Version", "linux,uefi-mmap-desc-ver", desc_ver)
> -};
> -
> -struct param_info {
> -	int verbose;
> -	int found;
> -	void *params;
> -};
> -
> -static int __init fdt_find_uefi_params(unsigned long node, const char *uname,
> -				       int depth, void *data)
> -{
> -	struct param_info *info = data;
> -	const void *prop;
> -	void *dest;
> -	u64 val;
> -	int i, len;
> -
> -	if (depth != 1 || strcmp(uname, "chosen") != 0)
> -		return 0;
> -
> -	for (i = 0; i < ARRAY_SIZE(dt_params); i++) {
> -		prop = of_get_flat_dt_prop(node, dt_params[i].propname, &len);
> -		if (!prop)
> -			return 0;
> -		dest = info->params + dt_params[i].offset;
> -		info->found++;
> -
> -		val = of_read_number(prop, len / sizeof(u32));
> -
> -		if (dt_params[i].size == sizeof(u32))
> -			*(u32 *)dest = val;
> -		else
> -			*(u64 *)dest = val;
> -
> -		if (info->verbose)
> -			pr_info("  %s: 0x%0*llx\n", dt_params[i].name,
> -				dt_params[i].size * 2, val);
> -	}
> -	return 1;
> -}
> -
> -int __init efi_get_fdt_params(struct efi_fdt_params *params, int verbose)
> -{
> -	struct param_info info;
> -	int ret;
> -
> -	pr_info("Getting EFI parameters from FDT:\n");
> -
> -	info.verbose = verbose;
> -	info.found = 0;
> -	info.params = params;
> -
> -	ret = of_scan_flat_dt(fdt_find_uefi_params, &info);
> -	if (!info.found)
> -		pr_info("UEFI not found.\n");
> -	else if (!ret)
> -		pr_err("Can't find '%s' in device tree!\n",
> -		       dt_params[info.found].name);
> -
> -	return ret;
> -}
> -#endif /* CONFIG_EFI_PARAMS_FROM_FDT */
> -
>  static __initdata char memory_type_name[][20] = {
>  	"Reserved",
>  	"Loader Code",
> -- 
> 1.9.1



From mchehab at osg.samsung.com  Wed Aug 26 07:54:03 2015
From: mchehab at osg.samsung.com (Mauro Carvalho Chehab)
Date: Wed, 26 Aug 2015 11:54:03 -0300
Subject: [PATCH v7 10/44] [media] media: rename the function that create
 pad links
In-Reply-To: <55DCBA2D.9090901@osg.samsung.com>
References: <cover.1440359643.git.mchehab@osg.samsung.com>
 <f095b87884d435e296a455ab07a9951a74c0c3a6.1440359643.git.mchehab@osg.samsung.com>
 <55DCBA2D.9090901@osg.samsung.com>
Message-ID: <20150826115403.7a794597@recife.lan>

Em Tue, 25 Aug 2015 12:55:41 -0600
Shuah Khan <shuahkh at osg.samsung.com> escreveu:

> On 08/23/2015 02:17 PM, Mauro Carvalho Chehab wrote:
> > Now that a link can be either between two different graph
> > objects, we'll need to add more functions to create links.
> 
> Is this an incomplete sentence. Should it read: "either between
> two different graph objects or two pads" ?

That would be redundant, as pad is a graph object ;)

> 
> > So, rename the existing one that create links only between
> > two pads as media_create_pad_link().
> 
> > 
> > No functional changes.
> > 
> > This patch was created via this shell script:
> > 	for i in $(find drivers/media -name '*.[ch]' -type f) $(find drivers/staging/media -name '*.[ch]' -type f) $(find include/ -name '*.h' -type f) ; do sed s,media_entity_create_link,media_create_pad_link,g <$i >a && mv a $i; done
> > 
> 
> Didn't want to experiment with Coccinelle?? :)

I use Coccinelle, but only when I need more complex changes, as
Coccinelle may mangle with comments.

> 
> > Signed-off-by: Mauro Carvalho Chehab <mchehab at osg.samsung.com>
> > Acked-by: Hans Verkuil <hans.verkuil at cisco.com>
> > Signed-off-by: Mauro Carvalho Chehab <mchehab at osg.samsung.com>
> > 
> 
> Changes look good to me. After fixing the commit log:
> 
> Acked-by: Shuah Khan <shuahkh at osg.samsung.com>
> 
> thanks,
> -- Shuah
> 
> 


From mchehab at osg.samsung.com  Wed Aug 26 07:59:05 2015
From: mchehab at osg.samsung.com (Mauro Carvalho Chehab)
Date: Wed, 26 Aug 2015 11:59:05 -0300
Subject: [PATCH v7 11/44] [media] media: use entity.graph_obj.mdev
 instead of .parent
In-Reply-To: <CAKocOOM7_mgp1ORz1mLzso9AZxSTuEcHAef64_LQ-NZVp5FASw@mail.gmail.com>
References: <cover.1440359643.git.mchehab@osg.samsung.com>
 <dc1be98277c46ddd87e431148fc7e332176828ab.1440359643.git.mchehab@osg.samsung.com>
 <55DC0D08.10504@xs4all.nl>
 <CAKocOOM7_mgp1ORz1mLzso9AZxSTuEcHAef64_LQ-NZVp5FASw@mail.gmail.com>
Message-ID: <20150826115905.3a953918@recife.lan>

Em Tue, 25 Aug 2015 13:25:15 -0600
Shuah Khan <shuahkhan at gmail.com> escreveu:

> On Tue, Aug 25, 2015 at 12:36 AM, Hans Verkuil <hverkuil at xs4all.nl> wrote:
> > On 08/23/2015 10:17 PM, Mauro Carvalho Chehab wrote:
> >> From: Javier Martinez Canillas <javier at osg.samsung.com>
> >>
> >> The struct media_entity has a .parent field that stores a pointer
> >> to the parent struct media_device. But recently a media_gobj was
> >> embedded into the entities and since struct media_gojb already has
> >> a pointer to a struct media_device in the .mdev field, the .parent
> >> field becomes redundant and can be removed.
> >>
> >> This patch replaces all the usage of .parent by .graph_obj.mdev so
> >> that field will become unused and can be removed on a later patch.
> >>
> >> No functional changes.
> >>
> >> The transformation was made using the following coccinelle spatch:
> >>
> >> @@
> >> struct media_entity *me;
> >> @@
> >>
> >> - me->parent
> >> + me->graph_obj.mdev
> >>
> >> @@
> >> struct media_entity *link;
> >> @@
> >>
> >> - link->source->entity->parent
> >> + link->source->entity->graph_obj.mdev
> >>
> >> @@
> >> struct exynos_video_entity *ve;
> >> @@
> >>
> >> - ve->vdev.entity.parent
> >> + ve->vdev.entity.graph_obj.mdev
> >>
> >> Suggested-by: Mauro Carvalho Chehab <mchehab at osg.samsung.com>
> >>
> >> Signed-off-by: Javier Martinez Canillas <javier at osg.samsung.com>
> >> Signed-off-by: Mauro Carvalho Chehab <mchehab at osg.samsung.com>
> >
> > Acked-by: Hans Verkuil <hans.verkuil at cisco.com>
> 
> The change looks good to me. I would really like to see a before and after
> media graph with these changes, this patch and series in general.

Well, it shouldn't change. If something changes, things would be wrong
:)

Btw, Javier is doing a before/after tests on OMAP3. There are a few
fixup things to be added/adjusted (unfortunately, OMAP3 doesn't compile
on x86 COMPILE_TEST), but on his tests, the differences between before
and after, with media-ctl are zero.

As media-ctl is using the legacy API, it shouldn't have any changes
there, otherwise something is broken and should be fixed ;)

I'll spin this patch series with Javier fixes for OMAP at the next 
version of this patch series.

> 
> thanks,
> -- Shuah


From ard.biesheuvel at linaro.org  Wed Aug 26 08:00:28 2015
From: ard.biesheuvel at linaro.org (Ard Biesheuvel)
Date: Wed, 26 Aug 2015 17:00:28 +0200
Subject: [PATCH v2 1/5] arm64: clone early_init_dt_add_memory_arch() to
 override default
In-Reply-To: <20150826144325.GA10728@bivouac.eciton.net>
References: <1440576391-25725-1-git-send-email-ard.biesheuvel@linaro.org>
 <1440576391-25725-2-git-send-email-ard.biesheuvel@linaro.org>
 <20150826144325.GA10728@bivouac.eciton.net>
Message-ID: <CAKv+Gu9roNfr8KPUJj_hhP6jw-Rz_CdcoT08vyxYDgW2AXpt4A@mail.gmail.com>

On 26 August 2015 at 16:43, Leif Lindholm <leif.lindholm at linaro.org> wrote:
> On Wed, Aug 26, 2015 at 10:06:27AM +0200, Ard Biesheuvel wrote:
>> Override the __weak early_init_dt_add_memory_arch() with our own
>> version. We need this in a subsequent patch to make the handling of
>> the memory nodes conditional on whether we are booting via UEFI or
>> not.
>
> Worth clarifying that this is a direct copy?
> ("Our own version" can be read as there being modifications here.)
>

Yes. In fact, it wasn't before, so hence the choice of words here.

>> Signed-off-by: Ard Biesheuvel <ard.biesheuvel at linaro.org>
>> ---
>>  arch/arm64/mm/init.c | 41 ++++++++++++++++++++
>>  1 file changed, 41 insertions(+)
>>
>> diff --git a/arch/arm64/mm/init.c b/arch/arm64/mm/init.c
>> index f5c0680d17d9..ab25fde7397c 100644
>> --- a/arch/arm64/mm/init.c
>> +++ b/arch/arm64/mm/init.c
>> @@ -374,3 +374,44 @@ static int __init keepinitrd_setup(char *__unused)
>>
>>  __setup("keepinitrd", keepinitrd_setup);
>>  #endif
>> +
>> +void __init early_init_dt_add_memory_arch(u64 base, u64 size)
>> +{
>> +     const u64 phys_offset = __pa(PAGE_OFFSET);
>> +
>> +     if (!PAGE_ALIGNED(base)) {
>> +             if (size < PAGE_SIZE - (base & ~PAGE_MASK)) {
>> +                     pr_warn("Ignoring memory block 0x%llx - 0x%llx\n",
>> +                             base, base + size);
>> +                     return;
>> +             }
>> +             size -= PAGE_SIZE - (base & ~PAGE_MASK);
>> +             base = PAGE_ALIGN(base);
>> +     }
>> +     size &= PAGE_MASK;
>> +
>> +     if (base > MAX_MEMBLOCK_ADDR) {
>> +             pr_warning("Ignoring memory block 0x%llx - 0x%llx\n",
>> +                             base, base + size);
>> +             return;
>> +     }
>> +
>> +     if (base + size - 1 > MAX_MEMBLOCK_ADDR) {
>> +             pr_warning("Ignoring memory range 0x%llx - 0x%llx\n",
>> +                             ((u64)MAX_MEMBLOCK_ADDR) + 1, base + size);
>> +             size = MAX_MEMBLOCK_ADDR - base + 1;
>> +     }
>> +
>> +     if (base + size < phys_offset) {
>> +             pr_warning("Ignoring memory block 0x%llx - 0x%llx\n",
>> +                        base, base + size);
>> +             return;
>> +     }
>> +     if (base < phys_offset) {
>> +             pr_warning("Ignoring memory range 0x%llx - 0x%llx\n",
>> +                        base, phys_offset);
>> +             size -= phys_offset - base;
>> +             base = phys_offset;
>> +     }
>> +     memblock_add(base, size);
>> +}
>> --
>> 1.9.1
>
> Would it be too crazy to do this via an added call to a weak
> memblock_use_dt() function in the original instead, to avoid
> duplicating this entire function?
>

This keeps coming up: I have a series in the freezer that decouples
the kernel mapping from the linear mapping, which makes another round
of changes to this function. So that is why I cloned the function in
the first place, only to reuse this patch for this series as well.

The following does the trick as well, but I am not sure if the alias
attribute is allowed in the kernel

"""
diff --git a/arch/arm64/mm/init.c b/arch/arm64/mm/init.c
index ad87ce826cce..af2f30cbf357 100644
--- a/arch/arm64/mm/init.c
+++ b/arch/arm64/mm/init.c
@@ -374,3 +374,8

 __setup("keepinitrd", keepinitrd_setup);
 #endif
+
+void __init early_init_dt_add_memory_arch(u64 base, u64 size)
+{
+       __early_init_dt_add_memory_arch(base, size);
+}
diff --git a/drivers/of/fdt.c b/drivers/of/fdt.c
index 07496560e5b9..2da75619ed78 100644
--- a/drivers/of/fdt.c
+++ b/drivers/of/fdt.c
@@ -1047,6 +1047,9
 }
 #endif

+void __early_init_dt_add_memory_arch(u64 base, u64 size)
+                       __attribute__((alias("early_init_dt_add_memory_arch")));
+
 bool __init early_init_dt_verify(void *params)
 {
        if (!params)
diff --git a/include/linux/of_fdt.h b/include/linux/of_fdt.h
index df9ef3801812..64fcb143f5f4 100644
--- a/include/linux/of_fdt.h
+++ b/include/linux/of_fdt.h
@@ -66,6 +66,7
 extern void early_init_fdt_scan_reserved_mem(void);
 extern void early_init_fdt_reserve_self(void);
 extern void early_init_dt_add_memory_arch(u64 base, u64 size);
+extern void __early_init_dt_add_memory_arch(u64 base, u64 size);
 extern int early_init_dt_reserve_memory_arch(phys_addr_t base,
phys_addr_t size,
                                             bool no_map);
 extern void * early_init_dt_alloc_memory_arch(u64 size, u64 align);
"""

> We need the functionality for 4/5 (nice cleanup) and 5/5 (bugfix), so
> happy with whatever works.
>

Indeed.


From ulf.hansson at linaro.org  Wed Aug 26 08:06:45 2015
From: ulf.hansson at linaro.org (Ulf Hansson)
Date: Wed, 26 Aug 2015 17:06:45 +0200
Subject: [PATCH 1/4] mmc: mediatek: Add online-tuning support of EMMC/SD
In-Reply-To: <1440578416.26912.12.camel@mhfsdcap03>
References: <1439367845-5891-1-git-send-email-chaotian.jing@mediatek.com>
 <1439367845-5891-2-git-send-email-chaotian.jing@mediatek.com>
 <CAPDyKFpX4Pp1+U9eNBuGd83sBeBgLU17qysAJ-2V-ABZZHYAGQ@mail.gmail.com>
 <1439812888.5627.9.camel@mhfsdcap03>
 <CAPDyKFpGk9gcLLjBnN=+BD5WP-7dZ0+XHC1bcEEGGLvLbTyKHw@mail.gmail.com>
 <1440578416.26912.12.camel@mhfsdcap03>
Message-ID: <CAPDyKFp0Eypyr8Asx_-_+VOfnDVW19Lrc-MmG2XA8kW+WM6Cnw@mail.gmail.com>

On 26 August 2015 at 10:40, Chaotian Jing <chaotian.jing at mediatek.com> wrote:
> On Tue, 2015-08-25 at 14:07 +0200, Ulf Hansson wrote:
>> On 17 August 2015 at 14:01, Chaotian Jing <chaotian.jing at mediatek.com> wrote:
>> > Hi Ulf,
>> > Thanks, please see my comment:
>> > On Mon, 2015-08-17 at 13:31 +0200, Ulf Hansson wrote:
>> >> On 12 August 2015 at 10:24, Chaotian Jing <chaotian.jing at mediatek.com> wrote:
>> >> > Schedule a workqueue to do tuning when CRC error
>> >> > Call mmc_hw_reset to re-init card when data timeout
>> >>
>> >> Thanks to Adrian Hunter, the mmc core already supports re-tuning for
>> >> the above scenarios through the mmc_retune_*() APIs.
>> >>
>> >> SDHCI driver has already adopted to use that feature, you should do
>> >> that for the mtk-sd driver as well.
>> >>
>> >> Kind regards
>> >> Uffe
>> >>
>> > I also noticed that the mmc core already supports re-tuning, but it is
>> > not suitable for our host.
>> > For EMMC, the CMD21 only support HS200/HS400 mode, for SD card, CMD19
>> > only support SDR50/SDR104 mode, but in our host, even 50Mhz clock
>> > frequency may also occur CRC error, Cannot find a parameter that can
>> > cover all SD cards which running at 50Mhz, even 25Mhz, will occur CRC
>> > error for stress test, DDR50 mode is worse.
>>
>> I don't follow. You may run for example HS200 in lower speed, nothing
>> will prevent tuning and re-tuning from happen for these scenarios.
>>
>> Or you are talking about other speed modes than HS200/400 and
>> SDR50/104? If so, which speed modes are these?
>>
> Yes, I am talking about other speed modes.
> For SD card, the speed mode is High Speed, for EMMC, the speed may be
> High Speed or DDR mode.
> If CRC error occurs at these speed modes, the MMC core layer will never
> handler it. even propagate the -EILSEQ towards to the mmc core, it will
> not start mmc_retune.

That's true and that's because the MMC/SD/SDIO specs states it.
Moreover, there a no tuning ever executed even while initializing such
cards. I think you need to elaborate more on what kind of "tuning"
your controller needs for these legacy speed modes, can you please do
that?

Currently the mmc block layer has request retry mechanism when
encountering IO errors. That may even reset or power cycle the card,
via mmc_hw_reset(). Isn't that sufficient?

>> BTW, there are currently a patch being discussed which is about adding
>> tuning for DDR mode. Please have look.
>> http://www.spinics.net/lists/arm-kernel/msg438434.html
>>
>> Regarding re-tuning on CRC errors, that's already supported by the mmc
>> core. More precisely when a host driver returns -EILSEQ for a request.
>>
>> > By the way,there are too many tune parameters need try for response,
>> > read data, write crc status CRC error, these parameters are
>> > multidimensional, it is hard to find a best parameter, and, try
>> > thousands of parameters will take long time.
>>
>> As I see, it's your responsibility from the host driver to propagate
>> the proper error code towards the mmc core. If you encounter an error
>> that you want to trigger a retune, just return -EILSEQ.
>>
>> Moreover, if you see a need to extend the tuning/re-tuning support in
>> the mmc core to suit your need - I am definitely open to look into
>> that. More importantly, I don't want to see host specific hacks trying
>> to deal with this.
>>
> In addition, the CMD21 is only valid for HS200 mode, do not support
> HS400, So that there is no chance to tune the HS400 read/write data with
> current mmc core layer codes.
> As you see, in our platform, tune of HS200 and HS400 is different, but
> if use the CMD21, it will never work at HS400 mode, even with
> "prepare_hs400_tuning", but it prepare what ? what we need is that
> running at HS400 mode and tune the read/write parameters, but not HS200,
> because for data Rx path, the tune result of HS200 is meaningless for
> HS400.

So, should we perhaps add another host_ops callback to satisfy your
need for HS400?

Kind regards
Uffe


From leif.lindholm at linaro.org  Wed Aug 26 08:16:27 2015
From: leif.lindholm at linaro.org (Leif Lindholm)
Date: Wed, 26 Aug 2015 16:16:27 +0100
Subject: [PATCH v2 3/5] arm64/efi: move EFI init before early FDT
 processing
In-Reply-To: <1440576391-25725-4-git-send-email-ard.biesheuvel@linaro.org>
References: <1440576391-25725-1-git-send-email-ard.biesheuvel@linaro.org>
 <1440576391-25725-4-git-send-email-ard.biesheuvel@linaro.org>
Message-ID: <20150826151627.GC10728@bivouac.eciton.net>

On Wed, Aug 26, 2015 at 10:06:29AM +0200, Ard Biesheuvel wrote:
> The early FDT processing is responsible for enumerating the
> DT memory nodes and installing them as memblocks. This should
> only be done if we are not booting via EFI, but at this point,
> we don't know yet if that is the case or not.
> 
> So move the EFI init to before the early FDT processing. This involves
> making some changes to the way EFI discovers the locations of the
> EFI system table and the memory map, since those values are retrieved
> from the FDT as well. Instead the of_scan infrastructure, it now uses
> libfdt directly to access the /chosen node.
> 
> Signed-off-by: Ard Biesheuvel <ard.biesheuvel at linaro.org>
> ---
>  arch/arm64/include/asm/efi.h   |  4 +-
>  arch/arm64/kernel/efi.c        | 14 ++--
>  arch/arm64/kernel/setup.c      |  4 +-
>  drivers/firmware/efi/efi-fdt.c | 74 ++++++++------------
>  include/linux/efi.h            |  3 +-
>  5 files changed, 40 insertions(+), 59 deletions(-)
> 
> diff --git a/arch/arm64/include/asm/efi.h b/arch/arm64/include/asm/efi.h
> index ef572206f1c3..635101f36720 100644
> --- a/arch/arm64/include/asm/efi.h
> +++ b/arch/arm64/include/asm/efi.h
> @@ -5,9 +5,9 @@
>  #include <asm/neon.h>
>  
>  #ifdef CONFIG_EFI
> -extern void efi_init(void);
> +extern void efi_init_fdt(void *fdt);
>  #else
> -#define efi_init()
> +#define efi_init_fdt(x)
>  #endif
>  
>  #define efi_call_virt(f, ...)						\
> diff --git a/arch/arm64/kernel/efi.c b/arch/arm64/kernel/efi.c
> index 9d4aa18f2a82..0e3dbe2cb752 100644
> --- a/arch/arm64/kernel/efi.c
> +++ b/arch/arm64/kernel/efi.c
> @@ -51,14 +51,7 @@ static struct mm_struct efi_mm = {
>  	INIT_MM_CONTEXT(efi_mm)
>  };
>  
> -static int uefi_debug __initdata;
> -static int __init uefi_debug_setup(char *str)
> -{
> -	uefi_debug = 1;
> -
> -	return 0;
> -}
> -early_param("uefi_debug", uefi_debug_setup);
> +static bool uefi_debug __initdata;

So, this obviously clashes with the patches I sent out recently, but
then they were triggered by the awkwardness of the interface passing
the verbosity flag around...
  
>  static int __init is_normal_ram(efi_memory_desc_t *md)
>  {
> @@ -205,14 +198,15 @@ static __init void reserve_regions(void)
>  	set_bit(EFI_MEMMAP, &efi.flags);
>  }
>  
> -void __init efi_init(void)
> +void __init efi_init_fdt(void *fdt)

(Nitpick: efi_init_fdt here, efi_virtmap_init below - naming consistency)

>  {
>  	struct efi_fdt_params params;
>  
>  	/* Grab UEFI information placed in FDT by stub */
> -	if (!efi_get_fdt_params(&params, uefi_debug))
> +	if (!efi_get_fdt_params(fdt, &params))
>  		return;
>  
> +	uefi_debug = params.verbose;
>  	efi_system_table = params.system_table;

Here is where it gets problematic.
Because this is now called before parse_early_params(), we lose the
ability to do debug output. Now, the details in the DT parsing is
maybe not that critical, but what follow is:
  
>  	memblock_reserve(params.mmap & PAGE_MASK,

... and we _really_ need to be able to dump the memory regions, with
attributes, for debugging purposes.

> diff --git a/arch/arm64/kernel/setup.c b/arch/arm64/kernel/setup.c
> index fddae2c15ad2..8fdde97c975c 100644
> --- a/arch/arm64/kernel/setup.c
> +++ b/arch/arm64/kernel/setup.c
> @@ -298,6 +298,9 @@ static void __init setup_machine_fdt(phys_addr_t dt_phys)
>  {
>  	void *dt_virt = fixmap_remap_fdt(dt_phys);
>  
> +	if (dt_virt)
> +		efi_init_fdt(dt_virt);
> +
>  	if (!dt_virt || !early_init_dt_scan(dt_virt)) {
>  		pr_crit("\n"
>  			"Error: invalid device tree blob at physical address %pa (virtual address 0x%p)\n"
> @@ -366,7 +369,6 @@ void __init setup_arch(char **cmdline_p)
>  	 */
>  	local_async_enable();
>  
> -	efi_init();

So can we just keep this call and terminate efi_init_fdt before
memblock_reserve?

>  	arm64_memblock_init();
>  
>  	/* Parse the ACPI tables for possible boot-time configuration */
> diff --git a/drivers/firmware/efi/efi-fdt.c b/drivers/firmware/efi/efi-fdt.c
> index f0e7ef2ae0e9..2e0e1a5a3fbb 100644
> --- a/drivers/firmware/efi/efi-fdt.c
> +++ b/drivers/firmware/efi/efi-fdt.c
> @@ -8,8 +8,7 @@
>  
>  #include <linux/init.h>
>  #include <linux/efi.h>
> -#include <linux/of.h>
> -#include <linux/of_fdt.h>
> +#include <linux/libfdt.h>
>  
>  #define UEFI_PARAM(name, prop, field)			   \
>  	{						   \
> @@ -32,62 +31,47 @@ static __initdata struct {
>  	UEFI_PARAM("MemMap Desc. Version", "linux,uefi-mmap-desc-ver", desc_ver)
>  };
>  
> -struct param_info {
> -	int verbose;
> -	int found;
> -	void *params;
> -};
> -
> -static int __init fdt_find_uefi_params(unsigned long node, const char *uname,
> -				       int depth, void *data)
> +bool __init efi_get_fdt_params(void *fdt, struct efi_fdt_params *params)
>  {
> -	struct param_info *info = data;
>  	const void *prop;
> -	void *dest;
> -	u64 val;
> -	int i, len;
> +	int node, i;
> +
> +	pr_info("Getting EFI parameters from FDT:\n");
>  
> -	if (depth != 1 || strcmp(uname, "chosen") != 0)
> -		return 0;
> +	node = fdt_path_offset(fdt, "/chosen");
> +	if (node < 0) {
> +		pr_err("/chosen node not found!\n");
> +		return false;
> +	}
> +
> +	prop = fdt_getprop(fdt, node, "bootargs", NULL);
> +	params->verbose = prop && strstr(prop, "uefi_debug");
>  
>  	for (i = 0; i < ARRAY_SIZE(dt_params); i++) {
> -		prop = of_get_flat_dt_prop(node, dt_params[i].propname, &len);
> -		if (!prop)
> -			return 0;
> -		dest = info->params + dt_params[i].offset;
> -		info->found++;
> +		void *dest;
> +		int len;
> +		u64 val;
>  
> -		val = of_read_number(prop, len / sizeof(u32));
> +		prop = fdt_getprop(fdt, node, dt_params[i].propname, &len);
> +		if (!prop)
> +			goto not_found;
> +		dest = (void *)params + dt_params[i].offset;
>  
>  		if (dt_params[i].size == sizeof(u32))
> -			*(u32 *)dest = val;
> +			val = *(u32 *)dest = be32_to_cpup(prop);
>  		else
> -			*(u64 *)dest = val;
> +			val = *(u64 *)dest = be64_to_cpup(prop);
>  
> -		if (info->verbose)
> +		if (params->verbose)
>  			pr_info("  %s: 0x%0*llx\n", dt_params[i].name,
>  				dt_params[i].size * 2, val);
>  	}
> -	return 1;
> -}
> -
> -int __init efi_get_fdt_params(struct efi_fdt_params *params, int verbose)
> -{
> -	struct param_info info;
> -	int ret;
> +	return true;
>  
> -	pr_info("Getting EFI parameters from FDT:\n");
> -
> -	info.verbose = verbose;
> -	info.found = 0;
> -	info.params = params;
> -
> -	ret = of_scan_flat_dt(fdt_find_uefi_params, &info);
> -	if (!info.found)
> +not_found:
> +	if (i == 0)
>  		pr_info("UEFI not found.\n");
> -	else if (!ret)
> -		pr_err("Can't find '%s' in device tree!\n",
> -		       dt_params[info.found].name);
> -
> -	return ret;
> +	else
> +		pr_err("Can't find '%s' in device tree!\n", dt_params[i].name);
> +	return false;
>  }
> diff --git a/include/linux/efi.h b/include/linux/efi.h
> index 85ef051ac6fb..faafa1ad6ea7 100644
> --- a/include/linux/efi.h
> +++ b/include/linux/efi.h
> @@ -690,6 +690,7 @@ struct efi_fdt_params {
>  	u32 mmap_size;
>  	u32 desc_size;
>  	u32 desc_ver;
> +	bool verbose;
>  };
>  
>  typedef struct {
> @@ -901,7 +902,7 @@ extern void efi_initialize_iomem_resources(struct resource *code_resource,
>  		struct resource *data_resource, struct resource *bss_resource);
>  extern void efi_get_time(struct timespec *now);
>  extern void efi_reserve_boot_services(void);
> -extern int efi_get_fdt_params(struct efi_fdt_params *params, int verbose);
> +extern bool efi_get_fdt_params(void *fdt, struct efi_fdt_params *params);
>  extern struct efi_memory_map memmap;
>  extern struct kobject *efi_kobj;
>  
> -- 
> 1.9.1
> 


From leif.lindholm at linaro.org  Wed Aug 26 08:25:26 2015
From: leif.lindholm at linaro.org (Leif Lindholm)
Date: Wed, 26 Aug 2015 16:25:26 +0100
Subject: [PATCH v2 4/5] arm64/efi: ignore DT memory nodes instead of
 removing them
In-Reply-To: <1440576391-25725-5-git-send-email-ard.biesheuvel@linaro.org>
References: <1440576391-25725-1-git-send-email-ard.biesheuvel@linaro.org>
 <1440576391-25725-5-git-send-email-ard.biesheuvel@linaro.org>
Message-ID: <20150826152526.GD10728@bivouac.eciton.net>

On Wed, Aug 26, 2015 at 10:06:30AM +0200, Ard Biesheuvel wrote:
> There are two problems with the UEFI stub DT memory node removal
> routine:
> - it deletes nodes as it traverses the tree, which happens to work
>   but is not supported, as deletion invalidates the node iterator;
> - deleting memory nodes entirely may discard annotations in the form
>   of additional properties on the nodes.
> 
> Now that the UEFI initialization has moved to an earlier stage, we can
> actually just ignore any memblocks that are installed after we have
> processed the UEFI memory map. This way, it is no longer necessary to
> remove the nodes, so we can remove that logic from the stub as well.
> 
> Signed-off-by: Ard Biesheuvel <ard.biesheuvel at linaro.org>
> ---
>  arch/arm64/mm/init.c               | 10 ++++++++
>  drivers/firmware/efi/libstub/fdt.c | 24 +-------------------
>  2 files changed, 11 insertions(+), 23 deletions(-)

Nice cleanup.

Acked-by: Leif Lindholm <leif.lindholm at linaro.org>
 
> diff --git a/arch/arm64/mm/init.c b/arch/arm64/mm/init.c
> index ab25fde7397c..ecbc051bc66b 100644
> --- a/arch/arm64/mm/init.c
> +++ b/arch/arm64/mm/init.c
> @@ -379,6 +379,16 @@ void __init early_init_dt_add_memory_arch(u64 base, u64 size)
>  {
>  	const u64 phys_offset = __pa(PAGE_OFFSET);
>  
> +	/*
> +	 * This callback will be invoked both when booting via UEFI and when
> +	 * booting via DT only. In the former case, we need to ignore memory
> +	 * nodes in the DT since UEFI is authoritative when it comes to the
> +	 * memory map. So ignore any invocations of this callback after
> +	 * EFI_MEMMAP has been set.
> +	 */
> +	if (efi_enabled(EFI_MEMMAP))
> +		return;
> +
>  	if (!PAGE_ALIGNED(base)) {
>  		if (size < PAGE_SIZE - (base & ~PAGE_MASK)) {
>  			pr_warn("Ignoring memory block 0x%llx - 0x%llx\n",
> diff --git a/drivers/firmware/efi/libstub/fdt.c b/drivers/firmware/efi/libstub/fdt.c
> index ef5d764e2a27..343e7992bd8f 100644
> --- a/drivers/firmware/efi/libstub/fdt.c
> +++ b/drivers/firmware/efi/libstub/fdt.c
> @@ -24,7 +24,7 @@ efi_status_t update_fdt(efi_system_table_t *sys_table, void *orig_fdt,
>  			unsigned long map_size, unsigned long desc_size,
>  			u32 desc_ver)
>  {
> -	int node, prev, num_rsv;
> +	int node, num_rsv;
>  	int status;
>  	u32 fdt_val32;
>  	u64 fdt_val64;
> @@ -54,28 +54,6 @@ efi_status_t update_fdt(efi_system_table_t *sys_table, void *orig_fdt,
>  		goto fdt_set_fail;
>  
>  	/*
> -	 * Delete any memory nodes present. We must delete nodes which
> -	 * early_init_dt_scan_memory may try to use.
> -	 */
> -	prev = 0;
> -	for (;;) {
> -		const char *type;
> -		int len;
> -
> -		node = fdt_next_node(fdt, prev, NULL);
> -		if (node < 0)
> -			break;
> -
> -		type = fdt_getprop(fdt, node, "device_type", &len);
> -		if (type && strncmp(type, "memory", len) == 0) {
> -			fdt_del_node(fdt, node);
> -			continue;
> -		}
> -
> -		prev = node;
> -	}
> -
> -	/*
>  	 * Delete all memory reserve map entries. When booting via UEFI,
>  	 * kernel will use the UEFI memory map to find reserved regions.
>  	 */
> -- 
> 1.9.1
> 


From bpringle at sympatico.ca  Wed Aug 26 08:26:36 2015
From: bpringle at sympatico.ca (Bill Pringlemeir)
Date: Wed, 26 Aug 2015 11:26:36 -0400
Subject: [PATCH v10 3/5] mtd: nand: vf610_nfc: add device tree bindings
References: <1438594050-4595-1-git-send-email-stefan@agner.ch>
 <1438594050-4595-4-git-send-email-stefan@agner.ch>
 <20150825202546.GL81844@google.com>
Message-ID: <BLU436-SMTP1971442F63D96D55AC8E905B8600@phx.gbl>

On 25 Aug 2015, computersforpeace at gmail.com wrote:

> Sorry, I realized a potential issue here.

> On Mon, Aug 03, 2015 at 11:27:28AM +0200, Stefan Agner wrote:
>> Signed-off-by: Bill Pringlemeir <bpringlemeir at nbsps.com>
>> Acked-by: Shawn Guo <shawnguo at kernel.org>
>> Reviewed-by: Brian Norris <computersforpeace at gmail.com>
>> Signed-off-by: Stefan Agner <stefan at agner.ch>
>> ---
>> .../devicetree/bindings/mtd/vf610-nfc.txt | 45 ++++++++++++++++++++++
>> 1 file changed, 45 insertions(+) create mode 100644
>> Documentation/devicetree/bindings/mtd/vf610-nfc.txt

>> diff --git a/Documentation/devicetree/bindings/mtd/vf610-nfc.txt
>> b/Documentation/devicetree/bindings/mtd/vf610-nfc.txt
>> new file mode 100644
>> index 0000000..cae5f25
>> --- /dev/null
>> +++ b/Documentation/devicetree/bindings/mtd/vf610-nfc.txt
>>>> -0,0 +1,45 @@
>> +- nand-bus-width: see nand.txt
>> +- nand-ecc-mode: see nand.txt
>> +- nand-on-flash-bbt: see nand.txt

> Stumbling across the "multi-CS" questions on the driver reminds me: it
> typically makes sense to define new NAND bindings using separate NAND
> *controller* and *flash* device nodes. The above 3 properties, at
> least, would apply on a per-flash basis, not per-controller
> typically. See sunxi-nand, for instance:

> http://lxr.free-electrons.com/source/Documentation/devicetree/bindings/mtd/sunxi-nand.txt

> brcmnand had a similar pattern:

> https://git.kernel.org/cgit/linux/kernel/git/torvalds/linux.git/tree/Documentation/devicetree/bindings/mtd/brcm,brcmnand.txt

> (Perhaps it's time we standardized this a little more formally...)

These would apply per chip, but the controller has to be configured to
support each and every one.  Every time an operation was performed, we
would have to check the chip type and reconfigure the controller.
Currently, the driver does not support this and it would add a lot of
overhead in some cases unless a register cache was used.

Is the flexibility of using a system with combined 8/16bit devices
really worth all the overhead?  Isn't it sort of brain dead hardware not
to make all of the chips similar?  Why would everyone have to pay for
such a crazy setup?

To separate it would at least be a lie versus the code in the current
form.  As well, there are only a few SOC which support multiple chip
selects.  The 'multi-CS' register bits of this controller varies between
PowerPC, 68K/Coldfire and ARM platforms.

I looked briefly at the brcmnand.c  and it seems that it is not
supporting different ECC per chip even though the nodes are broken out
this way.  In fact, if some raw functions are called, I think it will
put it in ECC mode even if it wasn't before?  Well, I agree that this
would be good generically, I think it puts a lot of effort in the
drivers for not so much payoff?

Fwiw,
Bill Pringlemeir.


From punnaia at xilinx.com  Wed Aug 26 08:32:02 2015
From: punnaia at xilinx.com (punnaiah choudary kalluri)
Date: Wed, 26 Aug 2015 21:02:02 +0530
Subject: [LINUX RFC v2 0/4] spi: add dual parallel mode support in Zynq
 MPSoC GQSPI controller
In-Reply-To: <CAD6G_RQhWBsUTZNBB44W98Fjzw82H_D_E9nY0aDWezj729mkoA@mail.gmail.com>
References: <1440570367-22569-1-git-send-email-ranjit.waghmode@xilinx.com>
 <CAD6G_RQhWBsUTZNBB44W98Fjzw82H_D_E9nY0aDWezj729mkoA@mail.gmail.com>
Message-ID: <CAGnW=BZtsVtT+Z7gTq5jybXsHWp+RNpjc6ckk6-MXWxAS7u8Mw@mail.gmail.com>

On Wed, Aug 26, 2015 at 5:49 PM, Jagan Teki <jteki at openedev.com> wrote:
> On 26 August 2015 at 11:56, Ranjit Waghmode <ranjit.waghmode at xilinx.com> wrote:
>> This series adds dual parallel mode support for Zynq Ultrascale+
>> MPSoC GQSPI controller driver.
>>
>> What is dual parallel mode?
>> ---------------------------
>> ZynqMP GQSPI controller supports Dual Parallel mode with following functionalities:
>> 1) Supporting two SPI flash memories operating in parallel. 8 I/O lines.
>> 2) Chip selects and clock are shared to both the flash devices
>> 3) This mode is targeted for faster read/write speed and also doubles the size
>> 4) Commands/data can be transmitted/received from both the devices(mirror),
>>    or only upper or only lower flash memory devices.
>> 5) Data arrangement:
>>    With stripe enabled,
>>    Even bytes i.e. 0, 2, 4,... are transmitted on Lower Data Bus
>>    Odd bytes i.e. 1, 3, 5,.. are transmitted on Upper Data Bus.
>>
>> This series also updated MTD layer files for adding parallel mode support.
>>
>> 1) Added Support for two flashes
>> 2) Support to enable/disable data stripe as and when required.
>> 3) Added required parameters to spi_nor structure. Initialized all
>>    added parameters in spi_nor_scan()
>> 4) Added support for dual parallel in spi_nor_read/write/erase functions by:
>>    a) Increasing page_size, sector_size, erase_size and toatal flash size
>>       as and when required.
>>    b) Dividing address by 2
>>    c) Updating spi->master->flags for qspi driver to change CS
>> 5) Updated read_sr() to get status of both flashes
>> 6) Also updated read_fsr() to get status of both flashes
>>
>> These all are very high level changes and expected to make an idea clear.
>> Comments and suggestions are always welcomed
>>
>> ---
>> V2 Changes:
>> a) Splitted patches based on logical changes
>> b) Added error handling for newly added APIs in SPI core
>> ---
>>
>> Ranjit Waghmode (4):
>>   spi: add support of two chip selects & data stripe
>>   mtd: add spi_device instance to spi_nor struct
>>   spi-nor: add dual parallel mode support
>>   spi: zynqmp: gqspi: add support for dual parallel mode configuration
>
> I don't find any previous discussion about way to inform flash
> dual-ness into spi-nor
> from spi drivers.
>
> Here is my idea, probably others may think same.
> Informing dual_flash from drivers/spi through flags or any other mode
> bits is not a better approach as dual flash feature is specific to
> spi-nor flash controller (controller specially designed for spi-nor
> flash not the generic spi controller).  So if the driver sits on
> drivers/mtd/spi-nor/ (ex: fsl-quadspi.c), may be we can inform flash
> specific things to spi-nor as it's not touching generic spi stack in
> Linux. But there is a defined-drawback if the driver is moved to
> drivers/mtd/spi-nor ie it can't use spi core API's at-all.

Xilinx GQSPI is a generic quad spi controller. The primary goal is to support
Generic/Future command sequences and Future NOR/NAND flash devices.
This core can also be used for legacy SPI devices. Due to the generic nature
of the core, software can generate any command sequence. It also has additional
features like parallel and stacked configurations to double the data
rate and size.
Accessing spi-nor flash device is one particular use case and like
that there will be
many. So, we decided to keep this driver in generic spi framework and
that is the ideal
thing to do for the GQSPI controller.

Regards,
Punnaiah

>
> thanks!
> --
> Jagan | openedev.
> --
> To unsubscribe from this list: send the line "unsubscribe linux-kernel" in
> the body of a message to majordomo at vger.kernel.org
> More majordomo info at  http://vger.kernel.org/majordomo-info.html
> Please read the FAQ at  http://www.tux.org/lkml/


From leif.lindholm at linaro.org  Wed Aug 26 08:35:18 2015
From: leif.lindholm at linaro.org (Leif Lindholm)
Date: Wed, 26 Aug 2015 16:35:18 +0100
Subject: [PATCH v2 5/5] arm64/efi: ignore DT memreserve entries instead
 of removing them
In-Reply-To: <1440576391-25725-6-git-send-email-ard.biesheuvel@linaro.org>
References: <1440576391-25725-1-git-send-email-ard.biesheuvel@linaro.org>
 <1440576391-25725-6-git-send-email-ard.biesheuvel@linaro.org>
Message-ID: <20150826153518.GE10728@bivouac.eciton.net>

On Wed, Aug 26, 2015 at 10:06:31AM +0200, Ard Biesheuvel wrote:
> Now that the reservation of the FDT image itself is split off, we
> can make the DT scanning of memreserves conditional on whether we
> booted via UEFI and have its memory map available. This allows us
> to drop deletion of these memreserves in the stub. It also fixes
> the issue where the /reserved-memory/ node (which offers another
> way of reserving memory ranges) was not being ignored under UEFI.
> 
> Signed-off-by: Ard Biesheuvel <ard.biesheuvel at linaro.org>
> ---
>  arch/arm64/mm/init.c               |  3 ++-
>  drivers/firmware/efi/libstub/fdt.c | 11 +----------
>  2 files changed, 3 insertions(+), 11 deletions(-)

Acked-by: Leif Lindholm <leif.lindholm at linaro.org>

And possibly a reference to 0ceac9e094b0?

As it is a bugfix, it would be nice to see this one go into 4.3, but...

> diff --git a/arch/arm64/mm/init.c b/arch/arm64/mm/init.c
> index ecbc051bc66b..0c33670ed1b6 100644
> --- a/arch/arm64/mm/init.c
> +++ b/arch/arm64/mm/init.c
> @@ -170,7 +170,8 @@ void __init arm64_memblock_init(void)
>  		memblock_reserve(__virt_to_phys(initrd_start), initrd_end - initrd_start);
>  #endif
>  
> -	early_init_fdt_scan_reserved_mem();
> +	if (!efi_enabled(EFI_MEMMAP))
> +		early_init_fdt_scan_reserved_mem();
>  
>  	/* 4GB maximum for 32-bit only capable devices */
>  	if (IS_ENABLED(CONFIG_ZONE_DMA))
> diff --git a/drivers/firmware/efi/libstub/fdt.c b/drivers/firmware/efi/libstub/fdt.c
> index 343e7992bd8f..a7e87cd582f2 100644
> --- a/drivers/firmware/efi/libstub/fdt.c
> +++ b/drivers/firmware/efi/libstub/fdt.c
> @@ -24,8 +24,7 @@ efi_status_t update_fdt(efi_system_table_t *sys_table, void *orig_fdt,
>  			unsigned long map_size, unsigned long desc_size,
>  			u32 desc_ver)
>  {
> -	int node, num_rsv;
> -	int status;
> +	int node, status;
>  	u32 fdt_val32;
>  	u64 fdt_val64;
>  
> @@ -53,14 +52,6 @@ efi_status_t update_fdt(efi_system_table_t *sys_table, void *orig_fdt,
>  	if (status != 0)
>  		goto fdt_set_fail;
>  
> -	/*
> -	 * Delete all memory reserve map entries. When booting via UEFI,
> -	 * kernel will use the UEFI memory map to find reserved regions.
> -	 */
> -	num_rsv = fdt_num_mem_rsv(fdt);
> -	while (num_rsv-- > 0)
> -		fdt_del_mem_rsv(fdt, num_rsv);
> -
>  	node = fdt_subnode_offset(fdt, 0, "chosen");
>  	if (node < 0) {
>  		node = fdt_add_subnode(fdt, 0, "chosen");
> -- 
> 1.9.1
> 


From linux at roeck-us.net  Wed Aug 26 08:36:29 2015
From: linux at roeck-us.net (Guenter Roeck)
Date: Wed, 26 Aug 2015 08:36:29 -0700
Subject: Build error in -next with gcc 4.9.1+ due to 'ARM: software-based
 priviledged-no-access support'
Message-ID: <55DDDCFD.7040208@roeck-us.net>

Hi Russell,

your patch 'ARM: software-based priviledged-no-access support' results in an internal
gcc error when trying to build arm:rpc_defconfig with gcc version 4.9.1 and 4.9.2.

fs/fat/dir.c: In function 'fat_ioctl_filldir':
fs/fat/dir.c:752:43: internal compiler error: Max. number of generated reload insns per insn is achieved (90)

  FAT_IOCTL_FILLDIR_FUNC(fat_ioctl_filldir, __fat_dirent)
                                            ^
fs/fat/dir.c:707:9: note: in definition of macro 'FAT_IOCTL_FILLDIR_FUNC'
   struct dirent_type __user *d2 = d1 + 1;       \
          ^

This is with yocto/poky toolchains (version 1.7 for gcc 4.9.1 and 1.8 for gcc 4.9.2).
The error is not seen with gcc 4.7.2 (from yocto/poky 1.4.2).

Guenter

---
bisect log:

# bad: [4aae1afc9fcd8fce05c9c429bf46991166aa14b6] Add linux-next specific files for 20150826
# good: [c13dcf9f2d6f5f06ef1bf79ec456df614c5e058b] Linux 4.2-rc8
git bisect start 'HEAD' 'v4.2-rc8'
# bad: [72fc9ce3821064893ae82c94da877437f2ccf2ea] Merge remote-tracking branch 'crypto/master'
git bisect bad 72fc9ce3821064893ae82c94da877437f2ccf2ea
# bad: [364353176f56b287fe8a8a12cc33d6e6ae62cb84] Merge remote-tracking branch 'hid/for-next'
git bisect bad 364353176f56b287fe8a8a12cc33d6e6ae62cb84
# bad: [bf7be12bfc48f8429596f2c2df8e9ad1c88b0923] Merge remote-tracking branch 'tegra/for-next'
git bisect bad bf7be12bfc48f8429596f2c2df8e9ad1c88b0923
# good: [5908b2fba50b28d1435f15a2c5edb346677172ed] Merge branch 'next/dt' into for-next
git bisect good 5908b2fba50b28d1435f15a2c5edb346677172ed
# good: [9a1d1799d5acbc961fbabdeaaac1bee31a84484e] Merge branch 'next/soc' into for-next
git bisect good 9a1d1799d5acbc961fbabdeaaac1bee31a84484e
# bad: [803f911c33ce5ba474335757ac6ddac5fafc4118] Merge remote-tracking branch 'arm-soc/for-next'
git bisect bad 803f911c33ce5ba474335757ac6ddac5fafc4118
# bad: [2a3639fea519310619e803414e565a3d3c875258] Merge branch 'drm-dwhdmi-devel' into for-next
git bisect bad 2a3639fea519310619e803414e565a3d3c875258
# bad: [42050b2a875fbe66f2cbef9a0b8fdb24f70b6b9a] Merge branches 'cleanup', 'fixes', 'fiq' (early part), 'misc', 'omap-barrier', 'pcmcia' and 'uaccess' into for-next
git bisect bad 42050b2a875fbe66f2cbef9a0b8fdb24f70b6b9a
# good: [9205b797dbe519a629267ec8c5766cd973d35063] ARM: 8421/1: smp: Collapse arch_cpu_idle_dead() into cpu_die()
git bisect good 9205b797dbe519a629267ec8c5766cd973d35063
# bad: [a2421d7da31d098570059007f6f7e290420034ee] ARM: software-based priviledged-no-access support
git bisect bad a2421d7da31d098570059007f6f7e290420034ee
# good: [a02d8dfd54cdf3b1b0464ccc2c1c4afe2c003a35] ARM: domains: keep vectors in separate domain
git bisect good a02d8dfd54cdf3b1b0464ccc2c1c4afe2c003a35
# good: [08446b129bbde34665c423d882f857a45b8c3aed] ARM: mm: improve do_ldrd_abort macro
git bisect good 08446b129bbde34665c423d882f857a45b8c3aed
# good: [c043dd6568a98f105e62b03481dff047ebcb3585] ARM: entry: provide uaccess assembly macro hooks
git bisect good c043dd6568a98f105e62b03481dff047ebcb3585
# first bad commit: [a2421d7da31d098570059007f6f7e290420034ee] ARM: software-based priviledged-no-access support


From timur at codeaurora.org  Wed Aug 26 08:38:42 2015
From: timur at codeaurora.org (Timur Tabi)
Date: Wed, 26 Aug 2015 10:38:42 -0500
Subject: [PATCH v2 1/5] ACPI: add in a bad_madt_entry() function to
 eventually replace the macro
In-Reply-To: <1440022048-6285-2-git-send-email-al.stone@linaro.org>
References: <1440022048-6285-1-git-send-email-al.stone@linaro.org>
 <1440022048-6285-2-git-send-email-al.stone@linaro.org>
Message-ID: <CAOZdJXXCnb7ChYqh-QYptTQBmfESDPaauThHyu8Dav6Qs_+4Bw@mail.gmail.com>

On Wed, Aug 19, 2015 at 5:07 PM, Al Stone <al.stone at linaro.org> wrote:
> +                               pr_err("Variable length MADT subtable %d is wrong size: %d\n",
> +                                      entry->type, entry->length);
> +                               return 1;
> +                       }
> +               }
> +       } else {
> +               if (entry->length != len) {
> +                       pr_err("MADT subtable %d is wrong size: %d\n",
> +                              len, entry->type);

Can we make these a little more descriptive?

pr_err("Variable length MADT subtable type %d is wrong size: %d,
should be %d\n",
      entry->type, entry->length, len);

pr_err("MADT subtable type %d is wrong size: %d, should be %d\n",
      entry->type, entry->length, len);




-- 
Qualcomm Innovation Center, Inc.
The Qualcomm Innovation Center, Inc. is a member of the Code Aurora Forum,
a Linux Foundation Collaborative Project.


From boris.brezillon at free-electrons.com  Wed Aug 26 08:39:03 2015
From: boris.brezillon at free-electrons.com (Boris Brezillon)
Date: Wed, 26 Aug 2015 17:39:03 +0200
Subject: [PATCH v10 3/5] mtd: nand: vf610_nfc: add device tree bindings
In-Reply-To: <BLU436-SMTP1971442F63D96D55AC8E905B8600@phx.gbl>
References: <1438594050-4595-1-git-send-email-stefan@agner.ch>
 <1438594050-4595-4-git-send-email-stefan@agner.ch>
 <20150825202546.GL81844@google.com>
 <BLU436-SMTP1971442F63D96D55AC8E905B8600@phx.gbl>
Message-ID: <20150826173903.25479201@bbrezillon>

Hi Bill,

On Wed, 26 Aug 2015 11:26:36 -0400
Bill Pringlemeir <bpringle at sympatico.ca> wrote:

> On 25 Aug 2015, computersforpeace at gmail.com wrote:
> 
> > Sorry, I realized a potential issue here.
> 
> > On Mon, Aug 03, 2015 at 11:27:28AM +0200, Stefan Agner wrote:
> >> Signed-off-by: Bill Pringlemeir <bpringlemeir at nbsps.com>
> >> Acked-by: Shawn Guo <shawnguo at kernel.org>
> >> Reviewed-by: Brian Norris <computersforpeace at gmail.com>
> >> Signed-off-by: Stefan Agner <stefan at agner.ch>
> >> ---
> >> .../devicetree/bindings/mtd/vf610-nfc.txt | 45 ++++++++++++++++++++++
> >> 1 file changed, 45 insertions(+) create mode 100644
> >> Documentation/devicetree/bindings/mtd/vf610-nfc.txt
> 
> >> diff --git a/Documentation/devicetree/bindings/mtd/vf610-nfc.txt
> >> b/Documentation/devicetree/bindings/mtd/vf610-nfc.txt
> >> new file mode 100644
> >> index 0000000..cae5f25
> >> --- /dev/null
> >> +++ b/Documentation/devicetree/bindings/mtd/vf610-nfc.txt
> >>>> -0,0 +1,45 @@
> >> +- nand-bus-width: see nand.txt
> >> +- nand-ecc-mode: see nand.txt
> >> +- nand-on-flash-bbt: see nand.txt
> 
> > Stumbling across the "multi-CS" questions on the driver reminds me: it
> > typically makes sense to define new NAND bindings using separate NAND
> > *controller* and *flash* device nodes. The above 3 properties, at
> > least, would apply on a per-flash basis, not per-controller
> > typically. See sunxi-nand, for instance:
> 
> > http://lxr.free-electrons.com/source/Documentation/devicetree/bindings/mtd/sunxi-nand.txt
> 
> > brcmnand had a similar pattern:
> 
> > https://git.kernel.org/cgit/linux/kernel/git/torvalds/linux.git/tree/Documentation/devicetree/bindings/mtd/brcm,brcmnand.txt
> 
> > (Perhaps it's time we standardized this a little more formally...)
> 
> These would apply per chip, but the controller has to be configured to
> support each and every one.  Every time an operation was performed, we
> would have to check the chip type and reconfigure the controller.
> Currently, the driver does not support this and it would add a lot of
> overhead in some cases unless a register cache was used.
> 
> Is the flexibility of using a system with combined 8/16bit devices
> really worth all the overhead?  Isn't it sort of brain dead hardware not
> to make all of the chips similar?  Why would everyone have to pay for
> such a crazy setup?
> 
> To separate it would at least be a lie versus the code in the current
> form.  As well, there are only a few SOC which support multiple chip
> selects.  The 'multi-CS' register bits of this controller varies between
> PowerPC, 68K/Coldfire and ARM platforms.
> 
> I looked briefly at the brcmnand.c  and it seems that it is not
> supporting different ECC per chip even though the nodes are broken out
> this way.  In fact, if some raw functions are called, I think it will
> put it in ECC mode even if it wasn't before?  Well, I agree that this
> would be good generically, I think it puts a lot of effort in the
> drivers for not so much payoff?

Hm, the sunxi driver supports it, and it does not add such a big
overhead...
The only thing you have to do is cache a bunch of register values
per-chip and restore/apply them when the chip is selected
(in your ->select_chip() implementation).

Anyway, even if the suggested DT representation is a lie in regards to
your implementation, it's actually pretty accurate from an hardware
POV, and this is exactly what DT is supposed to represent.

Best Regards,

Boris

-- 
Boris Brezillon, Free Electrons
Embedded Linux and Kernel engineering
http://free-electrons.com


From shenwei.wang at freescale.com  Wed Aug 26 08:49:26 2015
From: shenwei.wang at freescale.com (Shenwei Wang)
Date: Wed, 26 Aug 2015 10:49:26 -0500
Subject: [PATCH 1/1] irqchip: imx-gpcv2:  Simplify the implemenation
Message-ID: <1440604166-2624-1-git-send-email-shenwei.wang@freescale.com>

Based on Sudeep Holla's review comments, the implementation can
be simplified by using the two flags: IRQCHIP_SKIP_SET_WAKE and
IRQCHIP_MASK_ON_SUSPEND. This patch enables the flags in the
struct irq_chip and removes the unnecessory syscore_ops callbacks.

Signed-off-by: Shenwei Wang <shenwei.wang at freescale.com>
---
 drivers/irqchip/irq-imx-gpcv2.c | 83 +++++++----------------------------------
 1 file changed, 13 insertions(+), 70 deletions(-)

diff --git a/drivers/irqchip/irq-imx-gpcv2.c b/drivers/irqchip/irq-imx-gpcv2.c
index 4a97afa..e25df78 100644
--- a/drivers/irqchip/irq-imx-gpcv2.c
+++ b/drivers/irqchip/irq-imx-gpcv2.c
@@ -22,7 +22,6 @@ struct gpcv2_irqchip_data {
 	struct raw_spinlock    rlock;
 	void __iomem       *gpc_base;
 	u32 wakeup_sources[IMR_NUM];
-	u32 saved_irq_mask[IMR_NUM];
 	u32 cpu2wakeup;
 };
 
@@ -30,79 +29,25 @@ static struct gpcv2_irqchip_data *imx_gpcv2_instance;
 
 u32 imx_gpcv2_get_wakeup_source(u32 **sources)
 {
-	if (!imx_gpcv2_instance)
+	struct gpcv2_irqchip_data *cd;
+	void __iomem *reg;
+	int i;
+
+	cd = imx_gpcv2_instance;
+	if (!cd)
 		return 0;
 
+	for (i = 0; i < IMR_NUM; i++) {
+		reg = cd->gpc_base + cd->cpu2wakeup + i * 4;
+		cd->wakeup_sources[i] = readl_relaxed(reg);
+	}
+
 	if (sources)
-		*sources = imx_gpcv2_instance->wakeup_sources;
+		*sources = cd->wakeup_sources;
 
 	return IMR_NUM;
 }
 
-static int gpcv2_wakeup_source_save(void)
-{
-	struct gpcv2_irqchip_data *cd;
-	void __iomem *reg;
-	int i;
-
-	cd = imx_gpcv2_instance;
-	if (!cd)
-		return 0;
-
-	for (i = 0; i < IMR_NUM; i++) {
-		reg = cd->gpc_base + cd->cpu2wakeup + i * 4;
-		cd->saved_irq_mask[i] = readl_relaxed(reg);
-		writel_relaxed(cd->wakeup_sources[i], reg);
-	}
-
-	return 0;
-}
-
-static void gpcv2_wakeup_source_restore(void)
-{
-	struct gpcv2_irqchip_data *cd;
-	void __iomem *reg;
-	int i;
-
-	cd = imx_gpcv2_instance;
-	if (!cd)
-		return;
-
-	for (i = 0; i < IMR_NUM; i++) {
-		reg = cd->gpc_base + cd->cpu2wakeup + i * 4;
-		writel_relaxed(cd->saved_irq_mask[i], reg);
-	}
-}
-
-static struct syscore_ops imx_gpcv2_syscore_ops = {
-	.suspend	= gpcv2_wakeup_source_save,
-	.resume		= gpcv2_wakeup_source_restore,
-};
-
-static int imx_gpcv2_irq_set_wake(struct irq_data *d, unsigned int on)
-{
-	struct gpcv2_irqchip_data *cd = d->chip_data;
-	unsigned int idx = d->hwirq / 32;
-	unsigned long flags;
-	void __iomem *reg;
-	u32 mask, val;
-
-	raw_spin_lock_irqsave(&cd->rlock, flags);
-	reg = cd->gpc_base + cd->cpu2wakeup + idx * 4;
-	mask = 1 << d->hwirq % 32;
-	val = cd->wakeup_sources[idx];
-
-	cd->wakeup_sources[idx] = on ? (val & ~mask) : (val | mask);
-	raw_spin_unlock_irqrestore(&cd->rlock, flags);
-
-	/*
-	 * Do *not* call into the parent, as the GIC doesn't have any
-	 * wake-up facility...
-	 */
-
-	return 0;
-}
-
 static void imx_gpcv2_irq_unmask(struct irq_data *d)
 {
 	struct gpcv2_irqchip_data *cd = d->chip_data;
@@ -140,11 +85,11 @@ static struct irq_chip gpcv2_irqchip_data_chip = {
 	.irq_eoi		= irq_chip_eoi_parent,
 	.irq_mask		= imx_gpcv2_irq_mask,
 	.irq_unmask		= imx_gpcv2_irq_unmask,
-	.irq_set_wake		= imx_gpcv2_irq_set_wake,
 	.irq_retrigger		= irq_chip_retrigger_hierarchy,
 #ifdef CONFIG_SMP
 	.irq_set_affinity	= irq_chip_set_affinity_parent,
 #endif
+	.flags			= IRQCHIP_SKIP_SET_WAKE | IRQCHIP_MASK_ON_SUSPEND,
 };
 
 static int imx_gpcv2_domain_xlate(struct irq_domain *domain,
@@ -253,7 +198,6 @@ static int __init imx_gpcv2_irqchip_init(struct device_node *node,
 	for (i = 0; i < IMR_NUM; i++) {
 		writel_relaxed(~0, cd->gpc_base + GPC_IMR1_CORE0 + i * 4);
 		writel_relaxed(~0, cd->gpc_base + GPC_IMR1_CORE1 + i * 4);
-		cd->wakeup_sources[i] = ~0;
 	}
 
 	/* Let CORE0 as the default CPU to wake up by GPC */
@@ -267,7 +211,6 @@ static int __init imx_gpcv2_irqchip_init(struct device_node *node,
 	writel_relaxed(~0x1, cd->gpc_base + cd->cpu2wakeup);
 
 	imx_gpcv2_instance = cd;
-	register_syscore_ops(&imx_gpcv2_syscore_ops);
 
 	return 0;
 }
-- 
2.5.0.rc2




From Nathan_Lynch at mentor.com  Wed Aug 26 08:59:22 2015
From: Nathan_Lynch at mentor.com (Nathan Lynch)
Date: Wed, 26 Aug 2015 10:59:22 -0500
Subject: [PATCH 1/4] remoteproc: dt: Provide bindings for ST's Remote
 Processor Controller driver
In-Reply-To: <1440594483-29601-2-git-send-email-lee.jones@linaro.org>
References: <1440594483-29601-1-git-send-email-lee.jones@linaro.org>
 <1440594483-29601-2-git-send-email-lee.jones@linaro.org>
Message-ID: <55DDE25A.2050000@mentor.com>

On 08/26/2015 08:08 AM, Lee Jones wrote:
> diff --git a/Documentation/devicetree/bindings/remoteproc/st-rproc.txt b/Documentation/devicetree/bindings/remoteproc/st-rproc.txt
> new file mode 100644
> index 0000000..6a933c1
> --- /dev/null
> +++ b/Documentation/devicetree/bindings/remoteproc/st-rproc.txt
> @@ -0,0 +1,38 @@
> +STMicroelectronics Remote Processor
> +-----------------------------------
> +
> +This binding provides support for adjunct processors found on ST SoCs.
> +
> +The remote processors can be controlled from the bootloader or the primary OS.
> +If the bootloader starts a remote processor processor the primary OS must detect
> +its state and act accordingly.
> +
> +The node name is significant, as it defines the name of the CPU and the name
> +of the firmware to load: "rproc-<name>-fw".

This business about the firmware name describes a behavior of Linux's
core remoteproc code and seems out of place in a binding document.



From tglx at linutronix.de  Wed Aug 26 09:00:24 2015
From: tglx at linutronix.de (Thomas Gleixner)
Date: Wed, 26 Aug 2015 18:00:24 +0200 (CEST)
Subject: [PATCH 1/1] irqchip: imx-gpcv2: Simplify the implemenation
In-Reply-To: <1440604166-2624-1-git-send-email-shenwei.wang@freescale.com>
References: <1440604166-2624-1-git-send-email-shenwei.wang@freescale.com>
Message-ID: <alpine.DEB.2.11.1508261756540.15006@nanos>

On Wed, 26 Aug 2015, Shenwei Wang wrote:
>  u32 imx_gpcv2_get_wakeup_source(u32 **sources)
>  {
> -	if (!imx_gpcv2_instance)
> +	struct gpcv2_irqchip_data *cd;
> +	void __iomem *reg;
> +	int i;
> +
> +	cd = imx_gpcv2_instance;
> +	if (!cd)
>  		return 0;
>  
> +	for (i = 0; i < IMR_NUM; i++) {
> +		reg = cd->gpc_base + cd->cpu2wakeup + i * 4;
> +		cd->wakeup_sources[i] = readl_relaxed(reg);
> +	}
> +
>  	if (sources)
> -		*sources = imx_gpcv2_instance->wakeup_sources;
> +		*sources = cd->wakeup_sources;
>  
>  	return IMR_NUM;

You do not need the intermediate storage at all.

u32 imx_gpcv2_get_wakeup_source(u32 *sources)
{
	if (sources) {
		for (i = 0; i < IMR_NUM; i++) {
			reg = cd->gpc_base + cd->cpu2wakeup + i * 4;
			sources[i] = readl_relaxed(reg);
		}
	}
	....

Hmm?


From marc.zyngier at arm.com  Wed Aug 26 09:00:45 2015
From: marc.zyngier at arm.com (Marc Zyngier)
Date: Wed, 26 Aug 2015 17:00:45 +0100
Subject: [PATCH v4 4/4] irqchip: GIC: Don't deactivate interrupts forwarded to
 a guest
In-Reply-To: <1440604845-28229-1-git-send-email-marc.zyngier@arm.com>
References: <1440604845-28229-1-git-send-email-marc.zyngier@arm.com>
Message-ID: <1440604845-28229-5-git-send-email-marc.zyngier@arm.com>

Commit 0a4377de3056 ("genirq: Introduce irq_set_vcpu_affinity() to
target an interrupt to a VCPU") added just what we needed at the
lowest level to allow an interrupt to be deactivated by a guest.

When such a request reaches the GIC, it knows it doesn't need to
perform the deactivation anymore, and can safely leave the guest
do its magic. This of course requires additional support in both
VFIO and KVM.

Signed-off-by: Marc Zyngier <marc.zyngier at arm.com>
---
 drivers/irqchip/irq-gic.c | 55 +++++++++++++++++++++++++++++++++++++++++++++++
 1 file changed, 55 insertions(+)

diff --git a/drivers/irqchip/irq-gic.c b/drivers/irqchip/irq-gic.c
index 9215897..0f1f00c 100644
--- a/drivers/irqchip/irq-gic.c
+++ b/drivers/irqchip/irq-gic.c
@@ -140,6 +140,36 @@ static inline unsigned int gic_irq(struct irq_data *d)
 	return d->hwirq;
 }
 
+static inline bool cascading_gic_irq(struct irq_data *d)
+{
+	void *data = irq_data_get_irq_handler_data(d);
+
+	/*
+	 * If handler_data pointing to one of the secondary GICs, then
+	 * this is a cascading interrupt, and it cannot possibly be
+	 * forwarded.
+	 */
+	if (data >= (void *)(gic_data + 1) &&
+	    data <  (void *)(gic_data + MAX_GIC_NR))
+		return true;
+
+	return false;
+}
+
+static inline bool forwarded_irq(struct irq_data *d)
+{
+	/*
+	 * A forwarded interrupt:
+	 * - is on the primary GIC
+	 * - has its handler_data set to a value
+	 * - that isn't a secondary GIC
+	 */
+	if (d->handler_data && !cascading_gic_irq(d))
+		return true;
+
+	return false;
+}
+
 /*
  * Routines to acknowledge, disable and enable interrupts
  */
@@ -163,6 +193,16 @@ static void gic_mask_irq(struct irq_data *d)
 static void gic_eoimode1_mask_irq(struct irq_data *d)
 {
 	gic_mask_irq(d);
+	/*
+	 * When masking a forwarded interrupt, make sure it is
+	 * deactivated as well.
+	 *
+	 * This ensures that an interrupt that is getting
+	 * disabled/masked will not get "stuck", because there is
+	 * noone to deactivate it (guest is being terminated).
+	 */
+	if (forwarded_irq(d))
+		gic_poke_irq(d, GIC_DIST_ACTIVE_CLEAR);
 }
 
 static void gic_unmask_irq(struct irq_data *d)
@@ -177,6 +217,10 @@ static void gic_eoi_irq(struct irq_data *d)
 
 static void gic_eoimode1_eoi_irq(struct irq_data *d)
 {
+	/* Do not deactivate an IRQ forwarded to a vcpu. */
+	if (forwarded_irq(d))
+		return;
+
 	writel_relaxed(gic_irq(d), gic_cpu_base(d) + GIC_CPU_DEACTIVATE);
 }
 
@@ -246,6 +290,16 @@ static int gic_set_type(struct irq_data *d, unsigned int type)
 	return gic_configure_irq(gicirq, type, base, NULL);
 }
 
+static int gic_irq_set_vcpu_affinity(struct irq_data *d, void *vcpu)
+{
+	/* Only interrupts on the primary GIC can be forwarded to a vcpu. */
+	if (cascading_gic_irq(d))
+		return -EINVAL;
+
+	d->handler_data = vcpu;
+	return 0;
+}
+
 #ifdef CONFIG_SMP
 static int gic_set_affinity(struct irq_data *d, const struct cpumask *mask_val,
 			    bool force)
@@ -355,6 +409,7 @@ static struct irq_chip gic_eoimode1_chip = {
 #endif
 	.irq_get_irqchip_state	= gic_irq_get_irqchip_state,
 	.irq_set_irqchip_state	= gic_irq_set_irqchip_state,
+	.irq_set_vcpu_affinity	= gic_irq_set_vcpu_affinity,
 	.flags			= IRQCHIP_SET_TYPE_MASKED,
 };
 
-- 
2.1.4



From marc.zyngier at arm.com  Wed Aug 26 09:00:41 2015
From: marc.zyngier at arm.com (Marc Zyngier)
Date: Wed, 26 Aug 2015 17:00:41 +0100
Subject: [PATCH v4 0/4] irqchip: GICv2/v3: Add support for irq_vcpu_affinity
Message-ID: <1440604845-28229-1-git-send-email-marc.zyngier@arm.com>

The GICv2 and GICv3 architectures allow an active physical interrupt
to be forwarded to a guest, and the guest to indirectly perform the
deactivation of the interrupt by performing an EOI on the virtual
interrupt (see for example the GICv2 spec, 3.2.1).

This allows some substantial performance improvement for level
triggered interrupts that otherwise have to be masked/unmasked in
VFIO, not to mention the required trap back to KVM when the guest
performs an EOI.

To enable this, the GICs need to be switched to a different EOImode,
where a taken interrupt can be left "active" (which prevents the same
interrupt from being taken again), while other interrupts are still
being processed normally.

We also use the new irq_set_vcpu_affinity hook that was introduced for
Intel's "Posted Interrupts" to determine whether or not to perform the
deactivation at EOI-time.

As all of this only makes sense when the kernel can behave as a
hypervisor, we only enable this mode on detecting that the kernel was
actually booted in HYP mode, and that the GIC supports this feature.

This series is a complete rework of a RFC I sent over a year ago:

http://lists.infradead.org/pipermail/linux-arm-kernel/2014-June/266328.html

Since then, a lot has been either merged (the irqchip_state) or reworked
(my active-timer series: http://www.spinics.net/lists/kvm/msg118768.html),
and this implements the last few bits for Eric Auger's series to
finally make it into the kernel:

https://lkml.org/lkml/2015/7/2/268
https://lkml.org/lkml/2015/7/6/291

With all these patches combined, physical interrupt routing from the
kernel into a VM becomes possible.

Note that the implementation makes use of the static_key mechanism,
which is undergoing an extensive rework in 4.3. I intend to convert
this code once both are in mainline.

This has been tested on Juno (GICv2) and FastModel (GICv3). A branch
is available at:

git://git.kernel.org/pub/scm/linux/kernel/git/maz/arm-platforms.git irq/gic-irq-vcpu-affinity-v4

* From v3:
  - Use separate irq_chip structures, leading to much nicer code (tglx)
  - Dropped Eric's Tested/Reviewed-by as there is significant changes

* From v2:
  - Another small fix from Eric
  - Some commit message cleanups

* From v1:
  - Fixes after review from Eric
  - Got rid of the cascaded GICv2 hack (it was broken anyway)
  - Folded the LPI deactivation patch (it makes more sense as part of
    the main one.
  - Some clarifying comments about the "deactivate on mask"
  - I haven't retained Eric's Reviewed/Tested-by, as the code as
    significantly changed on GICv2

Marc Zyngier (4):
  irqchip: GICv3: Convert to EOImode == 1
  irqchip: GICv3: Don't deactivate interrupts forwarded to a guest
  irqchip: GIC: Convert to EOImode == 1
  irqchip: GIC: Don't deactivate interrupts forwarded to a guest

 drivers/irqchip/irq-gic-v3.c       |  70 +++++++++++++++++++++--
 drivers/irqchip/irq-gic.c          | 111 ++++++++++++++++++++++++++++++++++++-
 include/linux/irqchip/arm-gic-v3.h |   9 +++
 include/linux/irqchip/arm-gic.h    |   4 ++
 4 files changed, 188 insertions(+), 6 deletions(-)

-- 
2.1.4

*** BLURB HERE ***

Marc Zyngier (4):
  irqchip: GICv3: Convert to EOImode == 1
  irqchip: GICv3: Don't deactivate interrupts forwarded to a guest
  irqchip: GIC: Convert to EOImode == 1
  irqchip: GIC: Don't deactivate interrupts forwarded to a guest

 drivers/irqchip/irq-gic-v3.c       |  91 +++++++++++++++++++++++++--
 drivers/irqchip/irq-gic.c          | 124 ++++++++++++++++++++++++++++++++++++-
 include/linux/irqchip/arm-gic-v3.h |   9 +++
 include/linux/irqchip/arm-gic.h    |   4 ++
 4 files changed, 219 insertions(+), 9 deletions(-)

-- 
2.1.4



From marc.zyngier at arm.com  Wed Aug 26 09:00:43 2015
From: marc.zyngier at arm.com (Marc Zyngier)
Date: Wed, 26 Aug 2015 17:00:43 +0100
Subject: [PATCH v4 2/4] irqchip: GICv3: Don't deactivate interrupts forwarded
 to a guest
In-Reply-To: <1440604845-28229-1-git-send-email-marc.zyngier@arm.com>
References: <1440604845-28229-1-git-send-email-marc.zyngier@arm.com>
Message-ID: <1440604845-28229-3-git-send-email-marc.zyngier@arm.com>

Commit 0a4377de3056 ("genirq: Introduce irq_set_vcpu_affinity() to
target an interrupt to a VCPU") added just what we needed at the
lowest level to allow an interrupt to be deactivated by a guest.

When such a request reaches the GIC, it knows it doesn't need to
perform the deactivation anymore, and can safely leave the guest
do its magic. This of course requires additional support in both
VFIO and KVM.

Signed-off-by: Marc Zyngier <marc.zyngier at arm.com>
---
 drivers/irqchip/irq-gic-v3.c | 27 +++++++++++++++++++++++++--
 1 file changed, 25 insertions(+), 2 deletions(-)

diff --git a/drivers/irqchip/irq-gic-v3.c b/drivers/irqchip/irq-gic-v3.c
index e4eba7e..51635af 100644
--- a/drivers/irqchip/irq-gic-v3.c
+++ b/drivers/irqchip/irq-gic-v3.c
@@ -70,6 +70,11 @@ static inline int gic_irq_in_rdist(struct irq_data *d)
 	return gic_irq(d) < 32;
 }
 
+static inline bool forwarded_irq(struct irq_data *d)
+{
+	return d->handler_data != NULL;
+}
+
 static inline void __iomem *gic_dist_base(struct irq_data *d)
 {
 	if (gic_irq_in_rdist(d))	/* SGI+PPI -> SGI_base for this CPU */
@@ -236,6 +241,16 @@ static void gic_mask_irq(struct irq_data *d)
 static void gic_eoimode1_mask_irq(struct irq_data *d)
 {
 	gic_mask_irq(d);
+	/*
+	 * When masking a forwarded interrupt, make sure it is
+	 * deactivated as well.
+	 *
+	 * This ensures that an interrupt that is getting
+	 * disabled/masked will not get "stuck", because there is
+	 * noone to deactivate it (guest is being terminated).
+	 */
+	if (forwarded_irq(d))
+		gic_poke_irq(d, GICD_ICACTIVER);
 }
 
 static void gic_unmask_irq(struct irq_data *d)
@@ -306,9 +321,10 @@ static void gic_eoi_irq(struct irq_data *d)
 static void gic_eoimode1_eoi_irq(struct irq_data *d)
 {
 	/*
-	 * No need to deactivate an LPI.
+	 * No need to deactivate an LPI, or an interrupt that
+	 * is is getting forwarded to a vcpu.
 	 */
-	if (gic_irq(d) >= 8192)
+	if (gic_irq(d) >= 8192 || forwarded_irq(d))
 		return;
 	gic_write_dir(gic_irq(d));
 }
@@ -339,6 +355,12 @@ static int gic_set_type(struct irq_data *d, unsigned int type)
 	return gic_configure_irq(irq, type, base, rwp_wait);
 }
 
+static int gic_irq_set_vcpu_affinity(struct irq_data *d, void *vcpu)
+{
+	d->handler_data = vcpu;
+	return 0;
+}
+
 static u64 gic_mpidr_to_affinity(u64 mpidr)
 {
 	u64 aff;
@@ -703,6 +725,7 @@ static struct irq_chip gic_eoimode1_chip = {
 	.irq_set_affinity	= gic_set_affinity,
 	.irq_get_irqchip_state	= gic_irq_get_irqchip_state,
 	.irq_set_irqchip_state	= gic_irq_set_irqchip_state,
+	.irq_set_vcpu_affinity	= gic_irq_set_vcpu_affinity,
 	.flags			= IRQCHIP_SET_TYPE_MASKED,
 };
 
-- 
2.1.4



From marc.zyngier at arm.com  Wed Aug 26 09:00:44 2015
From: marc.zyngier at arm.com (Marc Zyngier)
Date: Wed, 26 Aug 2015 17:00:44 +0100
Subject: [PATCH v4 3/4] irqchip: GIC: Convert to EOImode == 1
In-Reply-To: <1440604845-28229-1-git-send-email-marc.zyngier@arm.com>
References: <1440604845-28229-1-git-send-email-marc.zyngier@arm.com>
Message-ID: <1440604845-28229-4-git-send-email-marc.zyngier@arm.com>

So far, GICv2 has been used with EOImode == 0. The effect of this
mode is to perform the priority drop and the deactivation of the
interrupt at the same time.

While this works perfectly for Linux (we only have a single priority),
it causes issues when an interrupt is forwarded to a guest, and when
we want the guest to perform the EOI itself.

For this case, the GIC architecture provides EOImode == 1, where:
- A write to the EOI register drops the priority of the interrupt
  and leaves it active. Other interrupts at the same priority level
  can now be taken, but the active interrupt cannot be taken again
- A write to the DIR marks the interrupt as inactive, meaning it can
  now be taken again.

We only enable this feature when booted in HYP mode and that
the device-tree reported a suitable CPU interface. Observable behaviour
should remain unchanged.

Signed-off-by: Marc Zyngier <marc.zyngier at arm.com>
---
 drivers/irqchip/irq-gic.c       | 69 +++++++++++++++++++++++++++++++++++++++--
 include/linux/irqchip/arm-gic.h |  4 +++
 2 files changed, 70 insertions(+), 3 deletions(-)

diff --git a/drivers/irqchip/irq-gic.c b/drivers/irqchip/irq-gic.c
index 4dd8826..9215897 100644
--- a/drivers/irqchip/irq-gic.c
+++ b/drivers/irqchip/irq-gic.c
@@ -46,6 +46,7 @@
 #include <asm/irq.h>
 #include <asm/exception.h>
 #include <asm/smp_plat.h>
+#include <asm/virt.h>
 
 #include "irq-gic-common.h"
 #include "irqchip.h"
@@ -82,6 +83,8 @@ static DEFINE_RAW_SPINLOCK(irq_controller_lock);
 #define NR_GIC_CPU_IF 8
 static u8 gic_cpu_map[NR_GIC_CPU_IF] __read_mostly;
 
+static struct static_key supports_deactivate = STATIC_KEY_INIT_TRUE;
+
 #ifndef MAX_GIC_NR
 #define MAX_GIC_NR	1
 #endif
@@ -157,6 +160,11 @@ static void gic_mask_irq(struct irq_data *d)
 	gic_poke_irq(d, GIC_DIST_ENABLE_CLEAR);
 }
 
+static void gic_eoimode1_mask_irq(struct irq_data *d)
+{
+	gic_mask_irq(d);
+}
+
 static void gic_unmask_irq(struct irq_data *d)
 {
 	gic_poke_irq(d, GIC_DIST_ENABLE_SET);
@@ -167,6 +175,11 @@ static void gic_eoi_irq(struct irq_data *d)
 	writel_relaxed(gic_irq(d), gic_cpu_base(d) + GIC_CPU_EOI);
 }
 
+static void gic_eoimode1_eoi_irq(struct irq_data *d)
+{
+	writel_relaxed(gic_irq(d), gic_cpu_base(d) + GIC_CPU_DEACTIVATE);
+}
+
 static int gic_irq_set_irqchip_state(struct irq_data *d,
 				     enum irqchip_irq_state which, bool val)
 {
@@ -272,11 +285,15 @@ static void __exception_irq_entry gic_handle_irq(struct pt_regs *regs)
 		irqnr = irqstat & GICC_IAR_INT_ID_MASK;
 
 		if (likely(irqnr > 15 && irqnr < 1021)) {
+			if (static_key_true(&supports_deactivate))
+				writel_relaxed(irqstat, cpu_base + GIC_CPU_EOI);
 			handle_domain_irq(gic->domain, irqnr, regs);
 			continue;
 		}
 		if (irqnr < 16) {
 			writel_relaxed(irqstat, cpu_base + GIC_CPU_EOI);
+			if (static_key_true(&supports_deactivate))
+				writel_relaxed(irqstat, cpu_base + GIC_CPU_DEACTIVATE);
 #ifdef CONFIG_SMP
 			handle_IPI(irqnr, regs);
 #endif
@@ -327,6 +344,20 @@ static struct irq_chip gic_chip = {
 	.flags			= IRQCHIP_SET_TYPE_MASKED,
 };
 
+static struct irq_chip gic_eoimode1_chip = {
+	.name			= "GICv2",
+	.irq_mask		= gic_eoimode1_mask_irq,
+	.irq_unmask		= gic_unmask_irq,
+	.irq_eoi		= gic_eoimode1_eoi_irq,
+	.irq_set_type		= gic_set_type,
+#ifdef CONFIG_SMP
+	.irq_set_affinity	= gic_set_affinity,
+#endif
+	.irq_get_irqchip_state	= gic_irq_get_irqchip_state,
+	.irq_set_irqchip_state	= gic_irq_set_irqchip_state,
+	.flags			= IRQCHIP_SET_TYPE_MASKED,
+};
+
 void __init gic_cascade_irq(unsigned int gic_nr, unsigned int irq)
 {
 	if (gic_nr >= MAX_GIC_NR)
@@ -359,6 +390,10 @@ static void gic_cpu_if_up(void)
 {
 	void __iomem *cpu_base = gic_data_cpu_base(&gic_data[0]);
 	u32 bypass = 0;
+	u32 mode = 0;
+
+	if (static_key_true(&supports_deactivate))
+		mode = GIC_CPU_CTRL_EOImodeNS;
 
 	/*
 	* Preserve bypass disable bits to be written back later
@@ -366,7 +401,7 @@ static void gic_cpu_if_up(void)
 	bypass = readl(cpu_base + GIC_CPU_CTRL);
 	bypass &= GICC_DIS_BYPASS_MASK;
 
-	writel_relaxed(bypass | GICC_ENABLE, cpu_base + GIC_CPU_CTRL);
+	writel_relaxed(bypass | mode | GICC_ENABLE, cpu_base + GIC_CPU_CTRL);
 }
 
 
@@ -789,13 +824,20 @@ void __init gic_init_physaddr(struct device_node *node)
 static int gic_irq_domain_map(struct irq_domain *d, unsigned int irq,
 				irq_hw_number_t hw)
 {
+	struct irq_chip *chip = &gic_chip;
+
+	if (static_key_true(&supports_deactivate)) {
+		if (d->host_data == (void *)&gic_data[0])
+			chip = &gic_eoimode1_chip;
+	}
+
 	if (hw < 32) {
 		irq_set_percpu_devid(irq);
-		irq_domain_set_info(d, irq, hw, &gic_chip, d->host_data,
+		irq_domain_set_info(d, irq, hw, chip, d->host_data,
 				    handle_percpu_devid_irq, NULL, NULL);
 		set_irq_flags(irq, IRQF_VALID | IRQF_NOAUTOEN);
 	} else {
-		irq_domain_set_info(d, irq, hw, &gic_chip, d->host_data,
+		irq_domain_set_info(d, irq, hw, chip, d->host_data,
 				    handle_fasteoi_irq, NULL, NULL);
 		set_irq_flags(irq, IRQF_VALID | IRQF_PROBE);
 	}
@@ -986,6 +1028,8 @@ void __init gic_init_bases(unsigned int gic_nr, int irq_start,
 		register_cpu_notifier(&gic_cpu_notifier);
 #endif
 		set_handle_irq(gic_handle_irq);
+		if (static_key_true(&supports_deactivate))
+			pr_info("GIC: Using split EOI/Deactivate mode\n");
 	}
 
 	gic_dist_init(gic);
@@ -1001,6 +1045,7 @@ gic_of_init(struct device_node *node, struct device_node *parent)
 {
 	void __iomem *cpu_base;
 	void __iomem *dist_base;
+	struct resource cpu_res;
 	u32 percpu_offset;
 	int irq;
 
@@ -1013,6 +1058,16 @@ gic_of_init(struct device_node *node, struct device_node *parent)
 	cpu_base = of_iomap(node, 1);
 	WARN(!cpu_base, "unable to map gic cpu registers\n");
 
+	of_address_to_resource(node, 1, &cpu_res);
+
+	/*
+	 * Disable split EOI/Deactivate if either HYP is not available
+	 * or the CPU interface is too small.
+	 */
+	if (gic_cnt == 0 && (!is_hyp_mode_available() ||
+			     resource_size(&cpu_res) < SZ_8K))
+		static_key_slow_dec(&supports_deactivate);
+
 	if (of_property_read_u32(node, "cpu-offset", &percpu_offset))
 		percpu_offset = 0;
 
@@ -1132,6 +1187,14 @@ gic_v2_acpi_init(struct acpi_table_header *table)
 	}
 
 	/*
+	 * Disable split EOI/Deactivate if HYP is not available. ACPI
+	 * guarantees that we'll always have a GICv2, so the CPU
+	 * interface will always be the right size.
+	 */
+	if (!is_hyp_mode_available())
+		static_key_slow_dec(&supports_deactivate);
+
+	/*
 	 * Initialize zero GIC instance (no multi-GIC support). Also, set GIC
 	 * as default IRQ domain to allow for GSI registration and GSI to IRQ
 	 * number translation (see acpi_register_gsi() and acpi_gsi_to_irq()).
diff --git a/include/linux/irqchip/arm-gic.h b/include/linux/irqchip/arm-gic.h
index 9de976b..b1533c0 100644
--- a/include/linux/irqchip/arm-gic.h
+++ b/include/linux/irqchip/arm-gic.h
@@ -20,9 +20,13 @@
 #define GIC_CPU_ALIAS_BINPOINT		0x1c
 #define GIC_CPU_ACTIVEPRIO		0xd0
 #define GIC_CPU_IDENT			0xfc
+#define GIC_CPU_DEACTIVATE		0x1000
 
 #define GICC_ENABLE			0x1
 #define GICC_INT_PRI_THRESHOLD		0xf0
+
+#define GIC_CPU_CTRL_EOImodeNS		(1 << 9)
+
 #define GICC_IAR_INT_ID_MASK		0x3ff
 #define GICC_INT_SPURIOUS		1023
 #define GICC_DIS_BYPASS_MASK		0x1e0
-- 
2.1.4



From marc.zyngier at arm.com  Wed Aug 26 09:00:42 2015
From: marc.zyngier at arm.com (Marc Zyngier)
Date: Wed, 26 Aug 2015 17:00:42 +0100
Subject: [PATCH v4 1/4] irqchip: GICv3: Convert to EOImode == 1
In-Reply-To: <1440604845-28229-1-git-send-email-marc.zyngier@arm.com>
References: <1440604845-28229-1-git-send-email-marc.zyngier@arm.com>
Message-ID: <1440604845-28229-2-git-send-email-marc.zyngier@arm.com>

So far, GICv3 has been used in with EOImode == 0. The effect of this
mode is to perform the priority drop and the deactivation of the
interrupt at the same time.

While this works perfectly for Linux (we only have a single priority),
it causes issues when an interrupt is forwarded to a guest, and when
we want the guest to perform the EOI itself.

For this case, the GIC architecture provides EOImode == 1, where:
- A write to ICC_EOIR1_EL1 drops the priority of the interrupt and
  leaves it active. Other interrupts at the same priority level can
  now be taken, but the active interrupt cannot be taken again
- A write to ICC_DIR_EL1 marks the interrupt as inactive, meaning
  it can now be taken again.

This patch converts the driver to be able to use this new mode,
depending on whether or not the kernel can behave as a hypervisor.
No feature change.

Signed-off-by: Marc Zyngier <marc.zyngier at arm.com>
---
 drivers/irqchip/irq-gic-v3.c       | 68 ++++++++++++++++++++++++++++++++++----
 include/linux/irqchip/arm-gic-v3.h |  9 +++++
 2 files changed, 71 insertions(+), 6 deletions(-)

diff --git a/drivers/irqchip/irq-gic-v3.c b/drivers/irqchip/irq-gic-v3.c
index c52f7ba..e4eba7e 100644
--- a/drivers/irqchip/irq-gic-v3.c
+++ b/drivers/irqchip/irq-gic-v3.c
@@ -30,6 +30,7 @@
 #include <asm/cputype.h>
 #include <asm/exception.h>
 #include <asm/smp_plat.h>
+#include <asm/virt.h>
 
 #include "irq-gic-common.h"
 #include "irqchip.h"
@@ -50,6 +51,7 @@ struct gic_chip_data {
 };
 
 static struct gic_chip_data gic_data __read_mostly;
+static struct static_key supports_deactivate = STATIC_KEY_INIT_TRUE;
 
 #define gic_data_rdist()		(this_cpu_ptr(gic_data.rdists.rdist))
 #define gic_data_rdist_rd_base()	(gic_data_rdist()->rd_base)
@@ -231,6 +233,11 @@ static void gic_mask_irq(struct irq_data *d)
 	gic_poke_irq(d, GICD_ICENABLER);
 }
 
+static void gic_eoimode1_mask_irq(struct irq_data *d)
+{
+	gic_mask_irq(d);
+}
+
 static void gic_unmask_irq(struct irq_data *d)
 {
 	gic_poke_irq(d, GICD_ISENABLER);
@@ -296,6 +303,16 @@ static void gic_eoi_irq(struct irq_data *d)
 	gic_write_eoir(gic_irq(d));
 }
 
+static void gic_eoimode1_eoi_irq(struct irq_data *d)
+{
+	/*
+	 * No need to deactivate an LPI.
+	 */
+	if (gic_irq(d) >= 8192)
+		return;
+	gic_write_dir(gic_irq(d));
+}
+
 static int gic_set_type(struct irq_data *d, unsigned int type)
 {
 	unsigned int irq = gic_irq(d);
@@ -343,15 +360,26 @@ static asmlinkage void __exception_irq_entry gic_handle_irq(struct pt_regs *regs
 
 		if (likely(irqnr > 15 && irqnr < 1020) || irqnr >= 8192) {
 			int err;
+
+			if (static_key_true(&supports_deactivate))
+				gic_write_eoir(irqnr);
+
 			err = handle_domain_irq(gic_data.domain, irqnr, regs);
 			if (err) {
 				WARN_ONCE(true, "Unexpected interrupt received!\n");
-				gic_write_eoir(irqnr);
+				if (static_key_true(&supports_deactivate)) {
+					if (irqnr < 8192)
+						gic_write_dir(irqnr);
+				} else {
+					gic_write_eoir(irqnr);
+				}
 			}
 			continue;
 		}
 		if (irqnr < 16) {
 			gic_write_eoir(irqnr);
+			if (static_key_true(&supports_deactivate))
+				gic_write_dir(irqnr);
 #ifdef CONFIG_SMP
 			handle_IPI(irqnr, regs);
 #else
@@ -451,8 +479,13 @@ static void gic_cpu_sys_reg_init(void)
 	/* Set priority mask register */
 	gic_write_pmr(DEFAULT_PMR_VALUE);
 
-	/* EOI deactivates interrupt too (mode 0) */
-	gic_write_ctlr(ICC_CTLR_EL1_EOImode_drop_dir);
+	if (static_key_true(&supports_deactivate)) {
+		/* EOI drops priority only (mode 1) */
+		gic_write_ctlr(ICC_CTLR_EL1_EOImode_drop);
+	} else {
+		/* EOI deactivates interrupt too (mode 0) */
+		gic_write_ctlr(ICC_CTLR_EL1_EOImode_drop_dir);
+	}
 
 	/* ... and let's hit the road... */
 	gic_write_grpen1(1);
@@ -661,11 +694,28 @@ static struct irq_chip gic_chip = {
 	.flags			= IRQCHIP_SET_TYPE_MASKED,
 };
 
+static struct irq_chip gic_eoimode1_chip = {
+	.name			= "GICv3",
+	.irq_mask		= gic_eoimode1_mask_irq,
+	.irq_unmask		= gic_unmask_irq,
+	.irq_eoi		= gic_eoimode1_eoi_irq,
+	.irq_set_type		= gic_set_type,
+	.irq_set_affinity	= gic_set_affinity,
+	.irq_get_irqchip_state	= gic_irq_get_irqchip_state,
+	.irq_set_irqchip_state	= gic_irq_set_irqchip_state,
+	.flags			= IRQCHIP_SET_TYPE_MASKED,
+};
+
 #define GIC_ID_NR		(1U << gic_data.rdists.id_bits)
 
 static int gic_irq_domain_map(struct irq_domain *d, unsigned int irq,
 			      irq_hw_number_t hw)
 {
+	struct irq_chip *chip = &gic_chip;
+
+	if (static_key_true(&supports_deactivate))
+		chip = &gic_eoimode1_chip;
+
 	/* SGIs are private to the core kernel */
 	if (hw < 16)
 		return -EPERM;
@@ -679,13 +729,13 @@ static int gic_irq_domain_map(struct irq_domain *d, unsigned int irq,
 	/* PPIs */
 	if (hw < 32) {
 		irq_set_percpu_devid(irq);
-		irq_domain_set_info(d, irq, hw, &gic_chip, d->host_data,
+		irq_domain_set_info(d, irq, hw, chip, d->host_data,
 				    handle_percpu_devid_irq, NULL, NULL);
 		set_irq_flags(irq, IRQF_VALID | IRQF_NOAUTOEN);
 	}
 	/* SPIs */
 	if (hw >= 32 && hw < gic_data.irq_nr) {
-		irq_domain_set_info(d, irq, hw, &gic_chip, d->host_data,
+		irq_domain_set_info(d, irq, hw, chip, d->host_data,
 				    handle_fasteoi_irq, NULL, NULL);
 		set_irq_flags(irq, IRQF_VALID | IRQF_PROBE);
 	}
@@ -693,7 +743,7 @@ static int gic_irq_domain_map(struct irq_domain *d, unsigned int irq,
 	if (hw >= 8192 && hw < GIC_ID_NR) {
 		if (!gic_dist_supports_lpis())
 			return -EPERM;
-		irq_domain_set_info(d, irq, hw, &gic_chip, d->host_data,
+		irq_domain_set_info(d, irq, hw, chip, d->host_data,
 				    handle_fasteoi_irq, NULL, NULL);
 		set_irq_flags(irq, IRQF_VALID);
 	}
@@ -820,6 +870,12 @@ static int __init gic_of_init(struct device_node *node, struct device_node *pare
 	if (of_property_read_u64(node, "redistributor-stride", &redist_stride))
 		redist_stride = 0;
 
+	if (!is_hyp_mode_available())
+		static_key_slow_dec(&supports_deactivate);
+
+	if (static_key_true(&supports_deactivate))
+		pr_info("GIC: Using split EOI/Deactivate mode\n");
+
 	gic_data.dist_base = dist_base;
 	gic_data.redist_regions = rdist_regs;
 	gic_data.nr_redist_regions = nr_redist_regions;
diff --git a/include/linux/irqchip/arm-gic-v3.h b/include/linux/irqchip/arm-gic-v3.h
index ffbc034..bc98832 100644
--- a/include/linux/irqchip/arm-gic-v3.h
+++ b/include/linux/irqchip/arm-gic-v3.h
@@ -104,6 +104,8 @@
 #define GICR_SYNCR			0x00C0
 #define GICR_MOVLPIR			0x0100
 #define GICR_MOVALLR			0x0110
+#define GICR_ISACTIVER			GICD_ISACTIVER
+#define GICR_ICACTIVER			GICD_ICACTIVER
 #define GICR_IDREGS			GICD_IDREGS
 #define GICR_PIDR2			GICD_PIDR2
 
@@ -288,6 +290,7 @@
 #define ICH_VMCR_PMR_MASK		(0xffUL << ICH_VMCR_PMR_SHIFT)
 
 #define ICC_EOIR1_EL1			sys_reg(3, 0, 12, 12, 1)
+#define ICC_DIR_EL1			sys_reg(3, 0, 12, 11, 1)
 #define ICC_IAR1_EL1			sys_reg(3, 0, 12, 12, 0)
 #define ICC_SGI1R_EL1			sys_reg(3, 0, 12, 11, 5)
 #define ICC_PMR_EL1			sys_reg(3, 0, 4, 6, 0)
@@ -384,6 +387,12 @@ static inline void gic_write_eoir(u64 irq)
 	isb();
 }
 
+static inline void gic_write_dir(u64 irq)
+{
+	asm volatile("msr_s " __stringify(ICC_DIR_EL1) ", %0" : : "r" (irq));
+	isb();
+}
+
 struct irq_domain;
 int its_cpu_init(void);
 int its_init(struct device_node *node, struct rdists *rdists,
-- 
2.1.4



From lorenzo.pieralisi at arm.com  Wed Aug 26 09:07:16 2015
From: lorenzo.pieralisi at arm.com (Lorenzo Pieralisi)
Date: Wed, 26 Aug 2015 17:07:16 +0100
Subject: [PATCH] ARM64: kernel: implement ACPI parking protocol
In-Reply-To: <1437068449.3583.4.camel@redhat.com>
References: <1436959990-32054-1-git-send-email-lorenzo.pieralisi@arm.com>
 <1437063431.3583.2.camel@redhat.com>
 <20150716171221.GB18582@red-moon>
 <1437068449.3583.4.camel@redhat.com>
Message-ID: <20150826160716.GB11863@red-moon>

Mark,

On Thu, Jul 16, 2015 at 06:40:49PM +0100, Mark Salter wrote:

[...]

> > > The kernel will only add cached memory regions to linear mapping and
> > > presumably, the FW will mark the mailboxes as uncached. Otherwise, it
> > > is a FW bug. But I suppose we could run into problems with kernels
> > > using 64K pagesize since firmware assumes 4k.
> >
> > Nope, ioremap takes care of that, everything should be fine.
> 
> The mailbox is 4K. If it is next to a cached UEFI region, the kernel may
> have to overlap the mailbox with a cached 64K mapping in order to include
> the adjoining UEFI region in the linear map. Then the ioremap would fail
> because the mailbox is included in the linear mapping.

You have to acknowledge that what you describe is a bit of a corner
case (and a silly FW set-up), are you aware of any existing FW set-up
where we actually hit the corner case above ?

I think it is fine to leave code as-is, at least the mailbox
mappings, I will check to see I can improve the MADT parsing,
somehow.

Lorenzo


From sudeep.holla at arm.com  Wed Aug 26 09:12:30 2015
From: sudeep.holla at arm.com (Sudeep Holla)
Date: Wed, 26 Aug 2015 17:12:30 +0100
Subject: [PATCH 1/1] irqchip: imx-gpcv2:  Simplify the implemenation
In-Reply-To: <1440604166-2624-1-git-send-email-shenwei.wang@freescale.com>
References: <1440604166-2624-1-git-send-email-shenwei.wang@freescale.com>
Message-ID: <55DDE56E.2040206@arm.com>

typo in $subject

On 26/08/15 16:49, Shenwei Wang wrote:
> Based on Sudeep Holla's review comments, the implementation can
> be simplified by using the two flags: IRQCHIP_SKIP_SET_WAKE and
> IRQCHIP_MASK_ON_SUSPEND. This patch enables the flags in the
> struct irq_chip and removes the unnecessory syscore_ops callbacks.
>
> Signed-off-by: Shenwei Wang <shenwei.wang at freescale.com>
> ---
>   drivers/irqchip/irq-imx-gpcv2.c | 83 +++++++----------------------------------
>   1 file changed, 13 insertions(+), 70 deletions(-)
>
> diff --git a/drivers/irqchip/irq-imx-gpcv2.c b/drivers/irqchip/irq-imx-gpcv2.c
> index 4a97afa..e25df78 100644
> --- a/drivers/irqchip/irq-imx-gpcv2.c
> +++ b/drivers/irqchip/irq-imx-gpcv2.c
> @@ -22,7 +22,6 @@ struct gpcv2_irqchip_data {
>   	struct raw_spinlock    rlock;
>   	void __iomem       *gpc_base;
>   	u32 wakeup_sources[IMR_NUM];
> -	u32 saved_irq_mask[IMR_NUM];
>   	u32 cpu2wakeup;
>   };
>
> @@ -30,79 +29,25 @@ static struct gpcv2_irqchip_data *imx_gpcv2_instance;
>
>   u32 imx_gpcv2_get_wakeup_source(u32 **sources)

I assume this patch is against -next and I don't see any users of
imx_gpcv2_get_wakeup_source in -next.

If possible I would avoid exposing this function by implementing
suspend_ops just as before(just saving raw h/w reg values and restoring
then back on resume w/o tagging them as wakeup mask though they might be
indeed wakeup mask).

In that way, this driver is self-contained and whatever imx code calls
this function will not have dependency on this driver, no ? Do you need
access to imx_gpcv2_get_wakeup_source too early in resume much before
suspend_ops resume ? I would like to see the user of that function to
comment on that any further.

Regards,
Sudeep


From ryabinin.a.a at gmail.com  Wed Aug 26 09:15:04 2015
From: ryabinin.a.a at gmail.com (Andrey Ryabinin)
Date: Wed, 26 Aug 2015 19:15:04 +0300
Subject: [PATCH 1/4] x86, efi, kasan: #undef memset/memcpy/memmove per arch.
In-Reply-To: <1440605707-8325-1-git-send-email-ryabinin.a.a@gmail.com>
References: <1440605707-8325-1-git-send-email-ryabinin.a.a@gmail.com>
Message-ID: <1440605707-8325-2-git-send-email-ryabinin.a.a@gmail.com>

In not-instrumented code KASAN replaces instrumented
memset/memcpy/memmove with not-instrumented analogues
__memset/__memcpy/__memove.
However, on x86 EFI stub is not linked with kernel.
It uses not-instrumented mem*() functions from
arch/x86/boot/compressed/string.c
So we don't replace them with __mem*() variants in EFI stub.

In ARM64 EFI stub is linked with the kernel, so we should
replace mem*() functions with __mem*(), because EFI stub
runs before KASAN setup early shadow.

So let's move these #undef mem* into arch's asm/efi.h which is
also included by EFI stub.

Signed-off-by: Andrey Ryabinin <ryabinin.a.a at gmail.com>
---
 arch/x86/include/asm/efi.h             | 8 ++++++++
 drivers/firmware/efi/libstub/efistub.h | 4 ----
 2 files changed, 8 insertions(+), 4 deletions(-)

diff --git a/arch/x86/include/asm/efi.h b/arch/x86/include/asm/efi.h
index 155162e..d821ce2 100644
--- a/arch/x86/include/asm/efi.h
+++ b/arch/x86/include/asm/efi.h
@@ -25,6 +25,14 @@
 #define EFI32_LOADER_SIGNATURE	"EL32"
 #define EFI64_LOADER_SIGNATURE	"EL64"
 
+/*
+ * Use memcpy/memset from arch/x86/boot/compressed/string.c
+ * for EFI stub.
+ */
+#undef memcpy
+#undef memset
+#undef memmove
+
 #ifdef CONFIG_X86_32
 
 
diff --git a/drivers/firmware/efi/libstub/efistub.h b/drivers/firmware/efi/libstub/efistub.h
index e334a01..6b6548f 100644
--- a/drivers/firmware/efi/libstub/efistub.h
+++ b/drivers/firmware/efi/libstub/efistub.h
@@ -5,10 +5,6 @@
 /* error code which can't be mistaken for valid address */
 #define EFI_ERROR	(~0UL)
 
-#undef memcpy
-#undef memset
-#undef memmove
-
 void efi_char16_printk(efi_system_table_t *, efi_char16_t *);
 
 efi_status_t efi_open_volume(efi_system_table_t *sys_table_arg, void *__image,
-- 
2.4.6



From ryabinin.a.a at gmail.com  Wed Aug 26 09:15:03 2015
From: ryabinin.a.a at gmail.com (Andrey Ryabinin)
Date: Wed, 26 Aug 2015 19:15:03 +0300
Subject: [PATCH 0/4] KASAN/ARM64 EFI fixes
Message-ID: <1440605707-8325-1-git-send-email-ryabinin.a.a@gmail.com>

On 08/13/2015 08:23 PM, Will Deacon wrote:
> I tried this out under EFI and it dies horribly in the stub code because
> we're missing at least one KASAN_SANITIZE_ Makefile entry.
> 
> So I think this needs longer to stew before hitting mainline. By all means
> get the x86 dependencies in for 4.3, but the arm64 port can probably use
> another cycle to iron out the bugs.
> 
> Cheers,
> 
> Will
> 

These series fixes boot crash with KASAN under EFI.
I'm sending it separetly for easier review.
We have one more small x86 dependcy in the first patch.
Patches 2-4 I'm going to squash into v6 'arm64: add KASAN support' patch.


Andrey Ryabinin (4):
  x86, efi, kasan: #undef memset/memcpy/memmove per arch.
  efi/runtime-wrappers, kasan: don't sanitize runtime wrappers.
  arm64/efi-stub, kasan: don't instrument efi-stub.
  libfdt, kasan: don't instrument libfdt.

 arch/arm64/kernel/Makefile             | 2 ++
 arch/x86/include/asm/efi.h             | 8 ++++++++
 drivers/firmware/efi/Makefile          | 8 ++++++++
 drivers/firmware/efi/libstub/efistub.h | 4 ----
 lib/Makefile                           | 3 ++-
 5 files changed, 20 insertions(+), 5 deletions(-)

--
2.4.6



From ryabinin.a.a at gmail.com  Wed Aug 26 09:15:05 2015
From: ryabinin.a.a at gmail.com (Andrey Ryabinin)
Date: Wed, 26 Aug 2015 19:15:05 +0300
Subject: [PATCH 2/4] efi/runtime-wrappers,
 kasan: don't sanitize runtime wrappers.
In-Reply-To: <1440605707-8325-1-git-send-email-ryabinin.a.a@gmail.com>
References: <1440605707-8325-1-git-send-email-ryabinin.a.a@gmail.com>
Message-ID: <1440605707-8325-3-git-send-email-ryabinin.a.a@gmail.com>

ARM64 maps efi runtime services in userspace addresses
which don't have KASAN shadow. So dereferencing these addresses
in efi_call_virt() will cause crash if this code instrumented.

Signed-off-by: Andrey Ryabinin <ryabinin.a.a at gmail.com>
---
 drivers/firmware/efi/Makefile | 8 ++++++++
 1 file changed, 8 insertions(+)

diff --git a/drivers/firmware/efi/Makefile b/drivers/firmware/efi/Makefile
index 6fd3da9..413fcf2 100644
--- a/drivers/firmware/efi/Makefile
+++ b/drivers/firmware/efi/Makefile
@@ -1,6 +1,14 @@
 #
 # Makefile for linux kernel
 #
+
+#
+# ARM64 maps efi runtime services in userspace addresses
+# which don't have KASAN shadow. So dereference of these addresses
+# in efi_call_virt() will cause crash if this code instrumented.
+#
+KASAN_SANITIZE_runtime-wrappers.o	:= n
+
 obj-$(CONFIG_EFI)			+= efi.o vars.o reboot.o
 obj-$(CONFIG_EFI_VARS)			+= efivars.o
 obj-$(CONFIG_EFI_ESRT)			+= esrt.o
-- 
2.4.6



From ryabinin.a.a at gmail.com  Wed Aug 26 09:15:07 2015
From: ryabinin.a.a at gmail.com (Andrey Ryabinin)
Date: Wed, 26 Aug 2015 19:15:07 +0300
Subject: [PATCH 4/4] libfdt, kasan: don't instrument libfdt.
In-Reply-To: <1440605707-8325-1-git-send-email-ryabinin.a.a@gmail.com>
References: <1440605707-8325-1-git-send-email-ryabinin.a.a@gmail.com>
Message-ID: <1440605707-8325-5-git-send-email-ryabinin.a.a@gmail.com>

libfdt is used by EFI code and it runs before we setup early
shadow, so it has to be not instrumented to prevent boot crash.

Signed-off-by: Andrey Ryabinin <ryabinin.a.a at gmail.com>
---
 lib/Makefile | 3 ++-
 1 file changed, 2 insertions(+), 1 deletion(-)

diff --git a/lib/Makefile b/lib/Makefile
index 6897b52..44e1d81 100644
--- a/lib/Makefile
+++ b/lib/Makefile
@@ -165,7 +165,8 @@ obj-$(CONFIG_STMP_DEVICE) += stmp_device.o
 libfdt_files = fdt.o fdt_ro.o fdt_wip.o fdt_rw.o fdt_sw.o fdt_strerror.o \
 	       fdt_empty_tree.o
 $(foreach file, $(libfdt_files), \
-	$(eval CFLAGS_$(file) = -I$(src)/../scripts/dtc/libfdt))
+	$(eval CFLAGS_$(file) = -I$(src)/../scripts/dtc/libfdt) \
+	$(eval KASAN_SANITIZE_$(file) := n))
 lib-$(CONFIG_LIBFDT) += $(libfdt_files)
 
 obj-$(CONFIG_RBTREE_TEST) += rbtree_test.o
-- 
2.4.6



From ryabinin.a.a at gmail.com  Wed Aug 26 09:15:06 2015
From: ryabinin.a.a at gmail.com (Andrey Ryabinin)
Date: Wed, 26 Aug 2015 19:15:06 +0300
Subject: [PATCH 3/4] arm64/efi-stub, kasan: don't instrument efi-stub.
In-Reply-To: <1440605707-8325-1-git-send-email-ryabinin.a.a@gmail.com>
References: <1440605707-8325-1-git-send-email-ryabinin.a.a@gmail.com>
Message-ID: <1440605707-8325-4-git-send-email-ryabinin.a.a@gmail.com>

efi-stub.c code runs before we setup early shadow.
Intrumentation of it will cause boot crash.

Signed-off-by: Andrey Ryabinin <ryabinin.a.a at gmail.com>
---
 arch/arm64/kernel/Makefile | 2 ++
 1 file changed, 2 insertions(+)

diff --git a/arch/arm64/kernel/Makefile b/arch/arm64/kernel/Makefile
index 426d076..086b122 100644
--- a/arch/arm64/kernel/Makefile
+++ b/arch/arm64/kernel/Makefile
@@ -7,6 +7,8 @@ AFLAGS_head.o		:= -DTEXT_OFFSET=$(TEXT_OFFSET)
 CFLAGS_efi-stub.o 	:= -DTEXT_OFFSET=$(TEXT_OFFSET)
 CFLAGS_armv8_deprecated.o := -I$(src)
 
+KASAN_SANITIZE_efi-stub.o	:= n
+
 CFLAGS_REMOVE_ftrace.o = -pg
 CFLAGS_REMOVE_insn.o = -pg
 CFLAGS_REMOVE_return_address.o = -pg
-- 
2.4.6



From gregory.clement at free-electrons.com  Wed Aug 26 09:19:43 2015
From: gregory.clement at free-electrons.com (Gregory CLEMENT)
Date: Wed, 26 Aug 2015 18:19:43 +0200
Subject: [PATCH v3 0/2] Fix dma mapping when the cache is coherent
Message-ID: <1440605985-13446-1-git-send-email-gregory.clement@free-electrons.com>

Hi,

These two patches fixes the dma mapping functions when the system is
cache coherent. The first one allows to fix an issue we have on Armada
375/38x with the PL310 that's why it is tagged for stable too.

The second one was suggested by Catalin. I put it in form and (really)
checked that it can be built, but I don't have the platform to test
it. However it seems that currently nobody has a platform using it, at
least it would be good to test that it does not introduce a regression
for the platform using IOMMU.

Changelog

v2 -> v3:

 - Fix comments in patch 1 as suggested by Catalin.
 - Fix build issues in patch 2 (by using the multi_v7_defconfig +
   CONFIG_ROCKCHIP_IOMMU).
 - Add the arm_coherent_iommu_mmap_attrs function.

Gregory

Gregory CLEMENT (2):
  ARM: dma-mapping: Don't use outer_flush_range when the L2C is coherent
  ARM: dma-mapping: Fix the coherent case when iommu is used

 arch/arm/mm/dma-mapping.c | 141 +++++++++++++++++++++++++++++++++-------------
 1 file changed, 102 insertions(+), 39 deletions(-)

-- 
2.1.0



From gregory.clement at free-electrons.com  Wed Aug 26 09:19:44 2015
From: gregory.clement at free-electrons.com (Gregory CLEMENT)
Date: Wed, 26 Aug 2015 18:19:44 +0200
Subject: [PATCH v3 1/2] ARM: dma-mapping: Don't use outer_flush_range when the
 L2C is coherent
In-Reply-To: <1440605985-13446-1-git-send-email-gregory.clement@free-electrons.com>
References: <1440605985-13446-1-git-send-email-gregory.clement@free-electrons.com>
Message-ID: <1440605985-13446-2-git-send-email-gregory.clement@free-electrons.com>

When a L2 cache controller is used in a system that provides hardware
coherency, the entire outer cache operations are useless, and can be
skipped.  Moreover, on some systems, it is harmful as it causes
deadlocks between the Marvell coherency mechanism, the Marvell PCIe
controller and the Cortex-A9.

In the current kernel implementation, the outer cache flush range
operation is triggered by the dma_alloc function.
This operation can be take place during runtime and in some
circumstances may lead to the PCIe/PL310 deadlock on Armada 375/38x
SoCs.

This patch extends the __dma_clear_buffer() function to receive a
boolean argument related to the coherency of the system. The same
things is done for the calling functions.

Reported-by: Nadav Haklai <nadavh at marvell.com>
Signed-off-by: Gregory CLEMENT <gregory.clement at free-electrons.com>
Cc: <stable at vger.kernel.org> # v3.16+
Reviewed-by: Catalin Marinas <catalin.marinas at arm.com>
---
 arch/arm/mm/dma-mapping.c | 57 +++++++++++++++++++++++++++++++----------------
 1 file changed, 38 insertions(+), 19 deletions(-)

diff --git a/arch/arm/mm/dma-mapping.c b/arch/arm/mm/dma-mapping.c
index 1ced8a0f7a52..a2513c0031c2 100644
--- a/arch/arm/mm/dma-mapping.c
+++ b/arch/arm/mm/dma-mapping.c
@@ -224,7 +224,7 @@ static u64 get_coherent_dma_mask(struct device *dev)
 	return mask;
 }
 
-static void __dma_clear_buffer(struct page *page, size_t size)
+static void __dma_clear_buffer(struct page *page, size_t size, bool is_coherent)
 {
 	/*
 	 * Ensure that the allocated pages are zeroed, and that any data
@@ -236,17 +236,21 @@ static void __dma_clear_buffer(struct page *page, size_t size)
 		while (size > 0) {
 			void *ptr = kmap_atomic(page);
 			memset(ptr, 0, PAGE_SIZE);
-			dmac_flush_range(ptr, ptr + PAGE_SIZE);
+			if (!is_coherent)
+				dmac_flush_range(ptr, ptr + PAGE_SIZE);
 			kunmap_atomic(ptr);
 			page++;
 			size -= PAGE_SIZE;
 		}
-		outer_flush_range(base, end);
+		if (!is_coherent)
+			outer_flush_range(base, end);
 	} else {
 		void *ptr = page_address(page);
 		memset(ptr, 0, size);
-		dmac_flush_range(ptr, ptr + size);
-		outer_flush_range(__pa(ptr), __pa(ptr) + size);
+		if (!is_coherent) {
+			dmac_flush_range(ptr, ptr + size);
+			outer_flush_range(__pa(ptr), __pa(ptr) + size);
+		}
 	}
 }
 
@@ -254,7 +258,8 @@ static void __dma_clear_buffer(struct page *page, size_t size)
  * Allocate a DMA buffer for 'dev' of size 'size' using the
  * specified gfp mask.  Note that 'size' must be page aligned.
  */
-static struct page *__dma_alloc_buffer(struct device *dev, size_t size, gfp_t gfp)
+static struct page *__dma_alloc_buffer(struct device *dev, size_t size,
+				gfp_t gfp, bool is_coherent)
 {
 	unsigned long order = get_order(size);
 	struct page *page, *p, *e;
@@ -270,7 +275,7 @@ static struct page *__dma_alloc_buffer(struct device *dev, size_t size, gfp_t gf
 	for (p = page + (size >> PAGE_SHIFT), e = page + (1 << order); p < e; p++)
 		__free_page(p);
 
-	__dma_clear_buffer(page, size);
+	__dma_clear_buffer(page, size, is_coherent);
 
 	return page;
 }
@@ -292,7 +297,8 @@ static void __dma_free_buffer(struct page *page, size_t size)
 
 static void *__alloc_from_contiguous(struct device *dev, size_t size,
 				     pgprot_t prot, struct page **ret_page,
-				     const void *caller, bool want_vaddr);
+				     const void *caller, bool want_vaddr,
+				     bool is_coherent);
 
 static void *__alloc_remap_buffer(struct device *dev, size_t size, gfp_t gfp,
 				 pgprot_t prot, struct page **ret_page,
@@ -358,9 +364,13 @@ static int __init atomic_pool_init(void)
 	if (!atomic_pool)
 		goto out;
 
+	/*
+	 * The atomic pool is only used for non-coherent allocations
+	 * so we must pass false for is_coherent.
+	 */
 	if (dev_get_cma_area(NULL))
 		ptr = __alloc_from_contiguous(NULL, atomic_pool_size, prot,
-					      &page, atomic_pool_init, true);
+					&page, atomic_pool_init, true, false);
 	else
 		ptr = __alloc_remap_buffer(NULL, atomic_pool_size, gfp, prot,
 					   &page, atomic_pool_init, true);
@@ -474,7 +484,11 @@ static void *__alloc_remap_buffer(struct device *dev, size_t size, gfp_t gfp,
 {
 	struct page *page;
 	void *ptr = NULL;
-	page = __dma_alloc_buffer(dev, size, gfp);
+	/*
+	 * __alloc_remap_buffer is only called when the device is
+	 * non-coherent
+	 */
+	page = __dma_alloc_buffer(dev, size, gfp, false);
 	if (!page)
 		return NULL;
 	if (!want_vaddr)
@@ -529,7 +543,8 @@ static int __free_from_pool(void *start, size_t size)
 
 static void *__alloc_from_contiguous(struct device *dev, size_t size,
 				     pgprot_t prot, struct page **ret_page,
-				     const void *caller, bool want_vaddr)
+				     const void *caller, bool want_vaddr,
+				     bool is_coherent)
 {
 	unsigned long order = get_order(size);
 	size_t count = size >> PAGE_SHIFT;
@@ -540,7 +555,7 @@ static void *__alloc_from_contiguous(struct device *dev, size_t size,
 	if (!page)
 		return NULL;
 
-	__dma_clear_buffer(page, size);
+	__dma_clear_buffer(page, size, is_coherent);
 
 	if (!want_vaddr)
 		goto out;
@@ -590,7 +605,7 @@ static inline pgprot_t __get_dma_pgprot(struct dma_attrs *attrs, pgprot_t prot)
 #define __get_dma_pgprot(attrs, prot)				__pgprot(0)
 #define __alloc_remap_buffer(dev, size, gfp, prot, ret, c, wv)	NULL
 #define __alloc_from_pool(size, ret_page)			NULL
-#define __alloc_from_contiguous(dev, size, prot, ret, c, wv)	NULL
+#define __alloc_from_contiguous(dev, size, prot, ret, c, wv, is_coherent)   NULL
 #define __free_from_pool(cpu_addr, size)			0
 #define __free_from_contiguous(dev, page, cpu_addr, size, wv)	do { } while (0)
 #define __dma_free_remap(cpu_addr, size)			do { } while (0)
@@ -601,7 +616,8 @@ static void *__alloc_simple_buffer(struct device *dev, size_t size, gfp_t gfp,
 				   struct page **ret_page)
 {
 	struct page *page;
-	page = __dma_alloc_buffer(dev, size, gfp);
+	/* __alloc_simple_buffer is only called when the device is coherent */
+	page = __dma_alloc_buffer(dev, size, gfp, true);
 	if (!page)
 		return NULL;
 
@@ -655,7 +671,8 @@ static void *__dma_alloc(struct device *dev, size_t size, dma_addr_t *handle,
 	else if (!dev_get_cma_area(dev))
 		addr = __alloc_remap_buffer(dev, size, gfp, prot, &page, caller, want_vaddr);
 	else
-		addr = __alloc_from_contiguous(dev, size, prot, &page, caller, want_vaddr);
+		addr = __alloc_from_contiguous(dev, size, prot, &page, caller,
+					want_vaddr, is_coherent);
 
 	if (page)
 		*handle = pfn_to_dma(dev, page_to_pfn(page));
@@ -1131,7 +1148,8 @@ static inline void __free_iova(struct dma_iommu_mapping *mapping,
 }
 
 static struct page **__iommu_alloc_buffer(struct device *dev, size_t size,
-					  gfp_t gfp, struct dma_attrs *attrs)
+					gfp_t gfp, struct dma_attrs *attrs,
+					bool is_coherent)
 {
 	struct page **pages;
 	int count = size >> PAGE_SHIFT;
@@ -1154,7 +1172,7 @@ static struct page **__iommu_alloc_buffer(struct device *dev, size_t size,
 		if (!page)
 			goto error;
 
-		__dma_clear_buffer(page, size);
+		__dma_clear_buffer(page, size, is_coherent);
 
 		for (i = 0; i < count; i++)
 			pages[i] = page + i;
@@ -1198,7 +1216,7 @@ static struct page **__iommu_alloc_buffer(struct device *dev, size_t size,
 				pages[i + j] = pages[i] + j;
 		}
 
-		__dma_clear_buffer(pages[i], PAGE_SIZE << order);
+		__dma_clear_buffer(pages[i], PAGE_SIZE << order, is_coherent);
 		i += 1 << order;
 		count -= 1 << order;
 	}
@@ -1381,7 +1399,8 @@ static void *arm_iommu_alloc_attrs(struct device *dev, size_t size,
 	 */
 	gfp &= ~(__GFP_COMP);
 
-	pages = __iommu_alloc_buffer(dev, size, gfp, attrs);
+	/* For now always consider we are in a non-coherent case */
+	pages = __iommu_alloc_buffer(dev, size, gfp, attrs, false);
 	if (!pages)
 		return NULL;
 
-- 
2.1.0



From gregory.clement at free-electrons.com  Wed Aug 26 09:19:45 2015
From: gregory.clement at free-electrons.com (Gregory CLEMENT)
Date: Wed, 26 Aug 2015 18:19:45 +0200
Subject: [PATCH v3 2/2] ARM: dma-mapping: Fix the coherent case when iommu is
 used
In-Reply-To: <1440605985-13446-1-git-send-email-gregory.clement@free-electrons.com>
References: <1440605985-13446-1-git-send-email-gregory.clement@free-electrons.com>
Message-ID: <1440605985-13446-3-git-send-email-gregory.clement@free-electrons.com>

When doing dma allocation with IOMMU the __iommu_alloc_atomic() was
used even when the system was coherent. However, this function
allocates from a non-cacheable pool, which is fine when the device is
not cache coherent but won't work as expected in the device is cache
coherent. Indeed, the CPU and device must access the memory using the
same cacheability attributes.

Moreover when the devices are coherent, the mmap call must not change
the pg_prot flags in the vma struct. The arm_coherent_iommu_mmap_attrs
has been updated in the same way that it was done for the arm_dma_mmap
in commit 55af8a91640d ("ARM: 8387/1: arm/mm/dma-mapping.c: Add
arm_coherent_dma_mmap").

Suggested-by: Catalin Marinas <catalin.marinas at arm.com>
Signed-off-by: Gregory CLEMENT <gregory.clement at free-electrons.com>
---
 arch/arm/mm/dma-mapping.c | 88 +++++++++++++++++++++++++++++++++++------------
 1 file changed, 66 insertions(+), 22 deletions(-)

diff --git a/arch/arm/mm/dma-mapping.c b/arch/arm/mm/dma-mapping.c
index a2513c0031c2..d678286e8ff1 100644
--- a/arch/arm/mm/dma-mapping.c
+++ b/arch/arm/mm/dma-mapping.c
@@ -1349,13 +1349,16 @@ static struct page **__iommu_get_pages(void *cpu_addr, struct dma_attrs *attrs)
 	return NULL;
 }
 
-static void *__iommu_alloc_atomic(struct device *dev, size_t size,
-				  dma_addr_t *handle)
+static void *__iommu_alloc_simple(struct device *dev, size_t size, gfp_t gfp,
+				  dma_addr_t *handle, bool is_coherent)
 {
 	struct page *page;
 	void *addr;
 
-	addr = __alloc_from_pool(size, &page);
+	if (is_coherent)
+		addr = __alloc_simple_buffer(dev, size, gfp, &page);
+	else
+		addr = __alloc_from_pool(size, &page);
 	if (!addr)
 		return NULL;
 
@@ -1370,15 +1373,19 @@ err_mapping:
 	return NULL;
 }
 
-static void __iommu_free_atomic(struct device *dev, void *cpu_addr,
-				dma_addr_t handle, size_t size)
+static void __iommu_free_simple(struct device *dev, void *cpu_addr,
+	    dma_addr_t handle, size_t size, bool is_coherent)
 {
 	__iommu_remove_mapping(dev, handle, size);
-	__free_from_pool(cpu_addr, size);
+	if (is_coherent)
+		__dma_free_buffer(virt_to_page(cpu_addr), size);
+	else
+		__free_from_pool(cpu_addr, size);
 }
 
-static void *arm_iommu_alloc_attrs(struct device *dev, size_t size,
-	    dma_addr_t *handle, gfp_t gfp, struct dma_attrs *attrs)
+static void *__arm_iommu_alloc_attrs(struct device *dev, size_t size,
+	    dma_addr_t *handle, gfp_t gfp, struct dma_attrs *attrs,
+	    bool is_coherent)
 {
 	pgprot_t prot = __get_dma_pgprot(attrs, PAGE_KERNEL);
 	struct page **pages;
@@ -1387,8 +1394,8 @@ static void *arm_iommu_alloc_attrs(struct device *dev, size_t size,
 	*handle = DMA_ERROR_CODE;
 	size = PAGE_ALIGN(size);
 
-	if (!(gfp & __GFP_WAIT))
-		return __iommu_alloc_atomic(dev, size, handle);
+	if (is_coherent || !(gfp & __GFP_WAIT))
+		return __iommu_alloc_simple(dev, size, gfp, handle, is_coherent);
 
 	/*
 	 * Following is a work-around (a.k.a. hack) to prevent pages
@@ -1399,8 +1406,7 @@ static void *arm_iommu_alloc_attrs(struct device *dev, size_t size,
 	 */
 	gfp &= ~(__GFP_COMP);
 
-	/* For now always consider we are in a non-coherent case */
-	pages = __iommu_alloc_buffer(dev, size, gfp, attrs, false);
+	pages = __iommu_alloc_buffer(dev, size, gfp, attrs, is_coherent);
 	if (!pages)
 		return NULL;
 
@@ -1425,7 +1431,19 @@ err_buffer:
 	return NULL;
 }
 
-static int arm_iommu_mmap_attrs(struct device *dev, struct vm_area_struct *vma,
+static void *arm_iommu_alloc_attrs(struct device *dev, size_t size,
+	    dma_addr_t *handle, gfp_t gfp, struct dma_attrs *attrs)
+{
+	return __arm_iommu_alloc_attrs(dev, size, handle, gfp, attrs, false);
+}
+
+static void *arm_coherent_iommu_alloc_attrs(struct device *dev, size_t size,
+	    dma_addr_t *handle, gfp_t gfp, struct dma_attrs *attrs)
+{
+	return __arm_iommu_alloc_attrs(dev, size, handle, gfp, attrs, true);
+}
+
+static int __arm_iommu_mmap_attrs(struct device *dev, struct vm_area_struct *vma,
 		    void *cpu_addr, dma_addr_t dma_addr, size_t size,
 		    struct dma_attrs *attrs)
 {
@@ -1433,8 +1451,6 @@ static int arm_iommu_mmap_attrs(struct device *dev, struct vm_area_struct *vma,
 	unsigned long usize = vma->vm_end - vma->vm_start;
 	struct page **pages = __iommu_get_pages(cpu_addr, attrs);
 
-	vma->vm_page_prot = __get_dma_pgprot(attrs, vma->vm_page_prot);
-
 	if (!pages)
 		return -ENXIO;
 
@@ -1451,18 +1467,34 @@ static int arm_iommu_mmap_attrs(struct device *dev, struct vm_area_struct *vma,
 	return 0;
 }
 
+static int arm_iommu_mmap_attrs(struct device *dev,
+		    struct vm_area_struct *vma, void *cpu_addr,
+		    dma_addr_t dma_addr, size_t size, struct dma_attrs *attrs)
+{
+	vma->vm_page_prot = __get_dma_pgprot(attrs, vma->vm_page_prot);
+
+	return __arm_iommu_mmap_attrs(dev, vma, cpu_addr, dma_addr, size, attrs);
+}
+
+static int arm_coherent_iommu_mmap_attrs(struct device *dev,
+		    struct vm_area_struct *vma, void *cpu_addr,
+		    dma_addr_t dma_addr, size_t size, struct dma_attrs *attrs)
+{
+	return __arm_iommu_mmap_attrs(dev, vma, cpu_addr, dma_addr, size, attrs);
+}
+
 /*
  * free a page as defined by the above mapping.
  * Must not be called with IRQs disabled.
  */
-void arm_iommu_free_attrs(struct device *dev, size_t size, void *cpu_addr,
-			  dma_addr_t handle, struct dma_attrs *attrs)
+void __arm_iommu_free_attrs(struct device *dev, size_t size, void *cpu_addr,
+	dma_addr_t handle, struct dma_attrs *attrs, bool is_coherent)
 {
 	struct page **pages;
 	size = PAGE_ALIGN(size);
 
-	if (__in_atomic_pool(cpu_addr, size)) {
-		__iommu_free_atomic(dev, cpu_addr, handle, size);
+	if (is_coherent || __in_atomic_pool(cpu_addr, size)) {
+		__iommu_free_simple(dev, cpu_addr, handle, size, is_coherent);
 		return;
 	}
 
@@ -1481,6 +1513,18 @@ void arm_iommu_free_attrs(struct device *dev, size_t size, void *cpu_addr,
 	__iommu_free_buffer(dev, pages, size, attrs);
 }
 
+void arm_iommu_free_attrs(struct device *dev, size_t size,
+	    void *cpu_addr, dma_addr_t handle, struct dma_attrs *attrs)
+{
+	__arm_iommu_free_attrs(dev, size, cpu_addr, handle, attrs, false);
+}
+
+void arm_coherent_iommu_free_attrs(struct device *dev, size_t size,
+	    void *cpu_addr, dma_addr_t handle, struct dma_attrs *attrs)
+{
+	__arm_iommu_free_attrs(dev, size, cpu_addr, handle, attrs, true);
+}
+
 static int arm_iommu_get_sgtable(struct device *dev, struct sg_table *sgt,
 				 void *cpu_addr, dma_addr_t dma_addr,
 				 size_t size, struct dma_attrs *attrs)
@@ -1887,9 +1931,9 @@ struct dma_map_ops iommu_ops = {
 };
 
 struct dma_map_ops iommu_coherent_ops = {
-	.alloc		= arm_iommu_alloc_attrs,
-	.free		= arm_iommu_free_attrs,
-	.mmap		= arm_iommu_mmap_attrs,
+	.alloc		= arm_coherent_iommu_alloc_attrs,
+	.free		= arm_coherent_iommu_free_attrs,
+	.mmap		= arm_coherent_iommu_mmap_attrs,
 	.get_sgtable	= arm_iommu_get_sgtable,
 
 	.map_page	= arm_coherent_iommu_map_page,
-- 
2.1.0



From dianders at chromium.org  Wed Aug 26 09:20:38 2015
From: dianders at chromium.org (Douglas Anderson)
Date: Wed, 26 Aug 2015 09:20:38 -0700
Subject: [PATCH v2] arm: kgdb: Fix registers on sleeping tasks
Message-ID: <1440606038-14816-1-git-send-email-dianders@chromium.org>

From: Doug Anderson <dianders at chromium.org>

Dumping registers from other sleeping tasks in KGDB was totally
failing for me.  All registers were reported as 0 in many cases.

The code was using task_pt_regs(task) to try to get other thread
registers.  This doesn't appear to be the right place to look.  From
my tests, I saw non-zero values in this structure when we were looking
at a kernel thread that had a userspace task associated with it, but
it contained the register values from the userspace task.  So even in
the cases where registers weren't reported as 0 we were still not
showing the right thing.

Instead of using task_pt_regs(task) let's use task_thread_info(task).
This is the same place that is referred to when doing a dump of all
sleeping task stacks (kdb_show_stack() -> show_stack() ->
dump_backtrace() -> unwind_backtrace() -> thread_saved_sp()).

As further evidence that this is the right thing to do, you can find
the following comment in "gdbstub.c" right before it calls
sleeping_thread_to_gdb_regs():
  Pull stuff saved during switch_to; nothing else is accessible (or
  even particularly relevant).  This should be enough for a stack
  trace.
...and if you look at switch_to() it only saves r4-r11, sp and lr.
Those are the same registers that I'm getting out of the
task_thread_info().

With this change you can use "info thread" to see all tasks in the
kernel and you can switch to other tasks and examine them in gdb.

Signed-off-by: Doug Anderson <dianders at chromium.org>
Signed-off-by: Douglas Anderson <dianders at chromium.org>
---
Changes in v2:
- Don't use task_pt_regs(task) at all.

 arch/arm/kernel/kgdb.c | 31 ++++++++++++-------------------
 1 file changed, 12 insertions(+), 19 deletions(-)

diff --git a/arch/arm/kernel/kgdb.c b/arch/arm/kernel/kgdb.c
index a6ad93c..abb17b0 100644
--- a/arch/arm/kernel/kgdb.c
+++ b/arch/arm/kernel/kgdb.c
@@ -74,7 +74,7 @@ int dbg_set_reg(int regno, void *mem, struct pt_regs *regs)
 void
 sleeping_thread_to_gdb_regs(unsigned long *gdb_regs, struct task_struct *task)
 {
-	struct pt_regs *thread_regs;
+	struct thread_info *ti;
 	int regno;
 
 	/* Just making sure... */
@@ -86,24 +86,17 @@ sleeping_thread_to_gdb_regs(unsigned long *gdb_regs, struct task_struct *task)
 		gdb_regs[regno] = 0;
 
 	/* Otherwise, we have only some registers from switch_to() */
-	thread_regs		= task_pt_regs(task);
-	gdb_regs[_R0]		= thread_regs->ARM_r0;
-	gdb_regs[_R1]		= thread_regs->ARM_r1;
-	gdb_regs[_R2]		= thread_regs->ARM_r2;
-	gdb_regs[_R3]		= thread_regs->ARM_r3;
-	gdb_regs[_R4]		= thread_regs->ARM_r4;
-	gdb_regs[_R5]		= thread_regs->ARM_r5;
-	gdb_regs[_R6]		= thread_regs->ARM_r6;
-	gdb_regs[_R7]		= thread_regs->ARM_r7;
-	gdb_regs[_R8]		= thread_regs->ARM_r8;
-	gdb_regs[_R9]		= thread_regs->ARM_r9;
-	gdb_regs[_R10]		= thread_regs->ARM_r10;
-	gdb_regs[_FP]		= thread_regs->ARM_fp;
-	gdb_regs[_IP]		= thread_regs->ARM_ip;
-	gdb_regs[_SPT]		= thread_regs->ARM_sp;
-	gdb_regs[_LR]		= thread_regs->ARM_lr;
-	gdb_regs[_PC]		= thread_regs->ARM_pc;
-	gdb_regs[_CPSR]		= thread_regs->ARM_cpsr;
+	ti			= task_thread_info(task);
+	gdb_regs[_R4]		= ti->cpu_context.r4;
+	gdb_regs[_R5]		= ti->cpu_context.r5;
+	gdb_regs[_R6]		= ti->cpu_context.r6;
+	gdb_regs[_R7]		= ti->cpu_context.r7;
+	gdb_regs[_R8]		= ti->cpu_context.r8;
+	gdb_regs[_R9]		= ti->cpu_context.r9;
+	gdb_regs[_R10]		= ti->cpu_context.sl;
+	gdb_regs[_FP]		= ti->cpu_context.fp;
+	gdb_regs[_SPT]		= ti->cpu_context.sp;
+	gdb_regs[_PC]		= ti->cpu_context.pc;
 }
 
 void kgdb_arch_set_pc(struct pt_regs *regs, unsigned long pc)
-- 
2.5.0.457.gab17608



From marex at denx.de  Wed Aug 26 09:26:15 2015
From: marex at denx.de (Marek Vasut)
Date: Wed, 26 Aug 2015 18:26:15 +0200
Subject: [PATCH linux-next v5 5/5] mtd: atmel-quadspi: add driver for
 Atmel QSPI controller
In-Reply-To: <a4f28764a2561106a91d1896e3ec21d0a88f2037.1440580764.git.cyrille.pitchen@atmel.com>
References: <cover.1440580764.git.cyrille.pitchen@atmel.com>
 <a4f28764a2561106a91d1896e3ec21d0a88f2037.1440580764.git.cyrille.pitchen@atmel.com>
Message-ID: <201508261826.15668.marex@denx.de>

On Wednesday, August 26, 2015 at 02:30:27 PM, Cyrille Pitchen wrote:
> This driver add support to the new Atmel QSPI controller embedded into
> sama5d2x SoCs. It expects a NOR memory to be connected to the QSPI
> controller.
> 
> Signed-off-by: Cyrille Pitchen <cyrille.pitchen at atmel.com>
> Acked-by: Nicolas Ferre <nicolas.ferre at atmel.com>

Acked-by: Marek Vasut <marex at denx.de>

Best regards,
Marek Vasut


From Shenwei.Wang at freescale.com  Wed Aug 26 09:32:11 2015
From: Shenwei.Wang at freescale.com (Shenwei Wang)
Date: Wed, 26 Aug 2015 16:32:11 +0000
Subject: [PATCH 1/1] irqchip: imx-gpcv2: Simplify the implemenation
In-Reply-To: <alpine.DEB.2.11.1508261756540.15006@nanos>
References: <1440604166-2624-1-git-send-email-shenwei.wang@freescale.com>
 <alpine.DEB.2.11.1508261756540.15006@nanos>
Message-ID: <CY1PR0301MB084315B04E53CF64EF299D0B83600@CY1PR0301MB0843.namprd03.prod.outlook.com>



> -----Original Message-----
> From: Thomas Gleixner [mailto:tglx at linutronix.de]
> Sent: 2015?8?26? 11:00
> To: Wang Shenwei-B38339
> Cc: shawn.guo at linaro.org; jason at lakedaemon.net; sudeep.holla at arm.com;
> linux-arm-kernel at lists.infradead.org; linux-kernel at vger.kernel.org; Huang
> Yongcai-B20788
> Subject: Re: [PATCH 1/1] irqchip: imx-gpcv2: Simplify the implemenation
> 
> On Wed, 26 Aug 2015, Shenwei Wang wrote:
> >  u32 imx_gpcv2_get_wakeup_source(u32 **sources)  {
> > -	if (!imx_gpcv2_instance)
> > +	struct gpcv2_irqchip_data *cd;
> > +	void __iomem *reg;
> > +	int i;
> > +
> > +	cd = imx_gpcv2_instance;
> > +	if (!cd)
> >  		return 0;
> >
> > +	for (i = 0; i < IMR_NUM; i++) {
> > +		reg = cd->gpc_base + cd->cpu2wakeup + i * 4;
> > +		cd->wakeup_sources[i] = readl_relaxed(reg);
> > +	}
> > +
> >  	if (sources)
> > -		*sources = imx_gpcv2_instance->wakeup_sources;
> > +		*sources = cd->wakeup_sources;
> >
> >  	return IMR_NUM;
> 
> You do not need the intermediate storage at all.
> 
> u32 imx_gpcv2_get_wakeup_source(u32 *sources) {
> 	if (sources) {
> 		for (i = 0; i < IMR_NUM; i++) {
> 			reg = cd->gpc_base + cd->cpu2wakeup + i * 4;
> 			sources[i] = readl_relaxed(reg);
> 		}
> 	}
> 	....

Using the intermediate storage here can make the caller a little easier,
because the caller does not need to malloc the memory before the call.
Especially the caller does not even know how many memory to allocate
In the beginning.

Thanks,
Shenwei

> Hmm?

From p.zabel at pengutronix.de  Wed Aug 26 09:34:35 2015
From: p.zabel at pengutronix.de (Philipp Zabel)
Date: Wed, 26 Aug 2015 18:34:35 +0200
Subject: [RFC][PATCH 1/2] dt-bindings: drm/mediatek: Add Mediatek DRM
 dts binding
In-Reply-To: <1431530626-31493-2-git-send-email-ck.hu@mediatek.com>
References: <1431530626-31493-1-git-send-email-ck.hu@mediatek.com>
 <1431530626-31493-2-git-send-email-ck.hu@mediatek.com>
Message-ID: <1440606875.3190.103.camel@pengutronix.de>

Hi,

overall it looks to me like this binding is modeled after the Linux DRM
abstractions. Instead, the device nodes should be modeled after the
hardware.

Describing each function block as a separate device node is probably not
the best choice, as would be combining all devices in the mmsys range
into a single device node. So a somewhat arbitrary decision has to be
made what to group together. See my comments below:

Am Mittwoch, den 13.05.2015, 23:23 +0800 schrieb CK Hu:
> This patch includes
> 1. Mediatek DRM Device binding
> 2. Mediatek DSI Device binding
> 3. Mediatek CRTC Main Device binding
> 4. Mediatek DDP Device binding
> 
> Signed-off-by: CK Hu <ck.hu at mediatek.com>
> ---
>  .../bindings/drm/mediatek/mediatek,crtc-main.txt   | 38 ++++++++++++++++++++++
>  .../bindings/drm/mediatek/mediatek,ddp.txt         | 22 +++++++++++++
>  .../bindings/drm/mediatek/mediatek,drm.txt         | 27 +++++++++++++++
>  .../bindings/drm/mediatek/mediatek,dsi.txt         | 20 ++++++++++++
>  4 files changed, 107 insertions(+)
>  create mode 100644 Documentation/devicetree/bindings/drm/mediatek/mediatek,crtc-main.txt
>  create mode 100644 Documentation/devicetree/bindings/drm/mediatek/mediatek,ddp.txt
>  create mode 100644 Documentation/devicetree/bindings/drm/mediatek/mediatek,drm.txt
>  create mode 100644 Documentation/devicetree/bindings/drm/mediatek/mediatek,dsi.txt
> 
> diff --git a/Documentation/devicetree/bindings/drm/mediatek/mediatek,crtc-main.txt b/Documentation/devicetree/bindings/drm/mediatek/mediatek,crtc-main.txt
> new file mode 100644
> index 0000000..5c6c420
> --- /dev/null
> +++ b/Documentation/devicetree/bindings/drm/mediatek/mediatek,crtc-main.txt
> @@ -0,0 +1,38 @@
> +Mediatek CRTC Main Device
> +================================
> +
> +The Mediatek CRTC Main device is a crtc device of DRM system.

"crtc" does not belong in the device tree. There is no crtc hardware.
What this node describes is a useful, but fixed configuration of a part
of the DISP subsystem function blocks.

In my opinion, it would be better to not describe the separate display
pipes in the device tree at all if they are dynamically configurable.
What for example if you model two separate fixed pipelines in the device
tree and then in the future you want to support the MERGE or SPLIT
blocks (I'm not sure what MERGE does, SPLIT seems to be needed for
8-lane DSI)?

As far as I currently understand, there are five source function blocks
that can read from memory (OVL0, OVL1, RDMA0, RDMA1, RDMA2) and three
sink function blocks (DSI0, DSI1, DPI0) that can be connected to panels,
or encoder bridges. How these map to the crtcs doesn't necessarily have
to be described in the device tree.

How about a single node that contains all of the DISP functional blocks
that don't need their own node (like DSI, which has to be connectable to
bridges or panels):

disp: disp at 0x1400c000 {
        compatible = "mediatek,mt8173-disp";
        interrupts = <GIC_SPI 180 IRQ_TYPE_LEVEL_LOW>, /* OVL0 */
                     <GIC_SPI 181 IRQ_TYPE_LEVEL_LOW>; /* OVL1 */
	interrupt-names = "ovl0", "ovl1";
        reg = <0 0x1400c000 0 0x1000>,  /* OVL0 */
              <0 0x1400d000 0 0x1000>,  /* OVL1 */
              <0 0x1400e000 0 0x1000>,  /* RDMA0 */
              <0 0x1400f000 0 0x1000>,  /* RDMA1 */
              <0 0x14010000 0 0x1000>,  /* RDMA2 */
              <0 0x14013000 0 0x1000>,  /* COLOR0 */
              <0 0x14014000 0 0x1000>,  /* COLOR1 */
              <0 0x14015000 0 0x1000>,  /* AAL */
              <0 0x14016000 0 0x1000>,  /* GAMMA */
              <0 0x14017000 0 0x1000>,  /* MERGE */
              <0 0x14018000 0 0x1000>,  /* SPLIT0 */
              <0 0x14019000 0 0x1000>,  /* SPLIT1 */
              <0 0x1401a000 0 0x1000>,  /* UFOE */
              <0 0x14020000 0 0x1000>;  /* MUTEX */
              <0 0x14023000 0 0x1000>;  /* OD */
	reg-names = "ovl0", "ovl1", "rdma0", "rdma1", "rdma2",
		"color0", "color1", "aal", "gamma", "merge",
		"split0", "split1", "ufoe", "mutex", "od";
        clocks = <&mmsys CLK_MM_DISP_OVL0>,
		 <&mmsys CLK_MM_DISP_OVL1>,
                 <&mmsys CLK_MM_DISP_RDMA0>,
                 <&mmsys CLK_MM_DISP_RDMA1>,
                 <&mmsys CLK_MM_DISP_RDMA2>,
                 <&mmsys CLK_MM_DISP_COLOR0>,
                 <&mmsys CLK_MM_DISP_COLOR1>,
                 <&mmsys CLK_MM_DISP_AAL>,
                 <&mmsys CLK_MM_DISP_GAMMA>,
                 <&mmsys CLK_MM_DISP_MERGE>,
                 <&mmsys CLK_MM_DISP_SPLIT0>,
                 <&mmsys CLK_MM_DISP_SPLIT1>,
                 <&mmsys CLK_MM_DISP_UFOE>,
                 <&mmsys CLK_MM_MUTEX_32K>,
                 <&mmsys CLK_MM_DISP_OD>;
	clock-names = "ovl0", "ovl1", "rdma0", "rdma1", "rdma2",
		"color0", "color1", "aal", "gamma", "merge",
		"split0", "split1", "ufoe", "mutex", "od";
        power-domains = <&scpsys MT8173_POWER_DOMAIN_DIS>;
        config = <&mmsys>; /* syscon */
};

How the muxes in the config area are set up to connect those blocks
could be determined by the driver.

> +Required properties:
> +- compatible: "mediatek,<chip>-crtc-main"
> +- interrupts: The interrupt signal from the CRTC Main block.
> +- reg: Physical base address and length of the controller's registers
> +- clocks: device clocks
> +  See Documentation/devicetree/bindings/clock/clock-bindings.txt for details.
> +- ddp: phandle of ddp device which control display data path.
> +
> +Example:
> +
> +crtc_main: crtc at 1400c000 {
> +	compatible = "mediatek,mt8173-crtc-main";
> +	interrupts = <GIC_SPI 196 IRQ_TYPE_LEVEL_LOW>;

Should it be mentioned that this is the interrupt of the source of the
pipeline (OVL0/1)?

> +	reg = <0 0x1400c000 0 0x1000>,	/* OVL0 */
> +	      <0 0x1400e000 0 0x1000>,	/* RDMA0 */
> +	      <0 0x14013000 0 0x1000>,	/* COLOR0 */
> +	      <0 0x14015000 0 0x1000>,	/* AAL */
> +	      <0 0x1401a000 0 0x1000>,	/* UFOE */
> +	      <0 0x14023000 0 0x1000>;	/* OD */

With the amount of register ranges and given the symmetry with the
clocks, better use reg-names instead of position to determine the
register space for each function block.

	reg-names = "ovl0", "rdma0", "color0", "aal", "ufoe", "od";

> +	clocks = <&mmsys MM_DISP_OVL0>,
> +		 <&mmsys MM_DISP_RDMA0>,
> +		 <&mmsys MM_DISP_COLOR0>,
> +		 <&mmsys MM_DISP_AAL>,
> +		 <&mmsys MM_DISP_UFOE>,
> +		 <&mmsys MM_DISP_OD>;
> +	clock-names = "ovl0_disp",
> +		      "rdma0_disp",
> +		      "color0_disp",
> +		      "aal_disp",
> +		      "ufoe_disp",
> +		      "od_disp";

I'd drop the disp suffix from the clock input names.

	clock-names = "ovl0", "rdma0", "color0", "aal", "ufoe", "od";

> +	ddp = <&ddp>;
> +};
> \ No newline at end of file
> diff --git a/Documentation/devicetree/bindings/drm/mediatek/mediatek,ddp.txt b/Documentation/devicetree/bindings/drm/mediatek/mediatek,ddp.txt
> new file mode 100644
> index 0000000..77cf630
> --- /dev/null
> +++ b/Documentation/devicetree/bindings/drm/mediatek/mediatek,ddp.txt
> @@ -0,0 +1,22 @@
> +Mediatek DDP Device
> +================================
> +
> +The Mediatek DDP device control the display data path.

This is not a real device either. There is nothing wrong with having a
ddp driver, but I don't think it is right to describe this driver in the
device tree. What we really have here is the mutex function block and
some registers in the mmsys config region, which already can be accessed
via the mmsys syscon.
With a single disp device node including the mutex and power domain
phandle this node would not be necessary.

> +Required properties:
> +- compatible: "mediatek,<chip>-ddp"
> +- reg: Physical base address and length of the controller's registers
> +- power-domains: a phandle to DDP power domain node.
> +- clocks: device clocks
> +  See Documentation/devicetree/bindings/clock/clock-bindings.txt for details.
> +
> +Example:
> +
> +ddp: ddp at 14000000 {
> +	compatible = "mediatek,mt8173-ddp";
> +	reg = <0 0x14000000 0 0x100>,	/* CONFIG */

This remaps part of the mmsys register space, which is already a syscon.
Why not use syscon to access it?

> +	      <0 0x14020000 0 0x1000>;	/* MUTEX */
> +	power-domains = <&scpsys MT8173_POWER_DOMAIN_DIS>;
> +	clocks = <&mmsys MM_MUTEX_32K>;
> +	clock-names = "mutex_disp";
> +};
> \ No newline at end of file
> diff --git a/Documentation/devicetree/bindings/drm/mediatek/mediatek,drm.txt b/Documentation/devicetree/bindings/drm/mediatek/mediatek,drm.txt
> new file mode 100644
> index 0000000..c4a5702
> --- /dev/null
> +++ b/Documentation/devicetree/bindings/drm/mediatek/mediatek,drm.txt
> @@ -0,0 +1,27 @@
> +Mediatek DRM Device
> +================================
> +
> +The Mediatek DRM device is a device needed to list all
> +display component nodes that comprise the display subsystem.
> +And it list the memory-related interface.

"drm" does not belong in the device tree. There is no "drm" hardware.
Other SoCs use the "display-subsystem" name for this node, it would be
better to follow that.

> +Required properties:
> +- compatible: "mediatek,<chip>-drm"
> +- larb: Should contain a list of phandles pointing to larb device.
> +  larb definitions as defined in
> +  Documentation/devicetree/bindings/soc/mediatek/mediatek,smi-larb.txt
> +- iommus: required a iommu node
> +- connectors: Should contain a list of phandles pointing to connector device.
> +  connector device should be one component of this master.
> +- crtcs: Should contain a list of phandles pointing to crtc device.
> +  crtc device should be one component of this master.

"connectors" and "crtcs" as used here are DRM concepts, not hardware
devices that should exist in the device tree. Ideally you would use
something recognizable from the datasheet, like "sinks" or from the
device tree, like "ports" if of-graph bindings are used, or just
"components" if this also were to include things like the ddp.

Another possibility would be to even merge the 

> +
> +Example:
> +
> +drm0: drm {
> +	compatible = "mediatek,mt8173-drm";
> +	larb = <&larb0>;
> +	iommus = <&iommu M4U_PORT_DISP_OVL0>;
> +	connectors = <&dsi>;
> +	crtcs = <&crtc_main>;
> +};
> \ No newline at end of file
> diff --git a/Documentation/devicetree/bindings/drm/mediatek/mediatek,dsi.txt b/Documentation/devicetree/bindings/drm/mediatek/mediatek,dsi.txt
> new file mode 100644
> index 0000000..16e3eb3
> --- /dev/null
> +++ b/Documentation/devicetree/bindings/drm/mediatek/mediatek,dsi.txt
> @@ -0,0 +1,20 @@
> +Mediatek DSI Device
> +================================
> +
> +The Mediatek DSI device is a connector device of DRM system.
> +
> +Required properties:
> +- compatible: "mediatek,<chip>-dsi"
> +- reg: Physical base address and length of the controller's registers
> +- clocks: device clocks
> +  See Documentation/devicetree/bindings/clock/clock-bindings.txt for details.

Will this use the
Documentation/devicetree/bindings/mipi/dsi/mipi-dsi-bus.txt
bindings to connect panels controlled via the DSI command channel
or the
Documentation/devicetree/bindings/graph.txt
bindings to connect panels controlled via I2C or other control buses?
If so, this should be documented here.

> +Example:
> +
> +dsi: dsi at 10215000 {
> +	compatible = "mediatek,mt8173-dsi";
> +	reg = <0 0x1401B000 0 0x1000>,	/* DSI0 */
> +	      <0 0x10215000 0 0x1000>;  /* MIPITX */
> +	clocks = <&mmsys MM_DSI0_ENGINE>,	<&mmsys MM_DSI0_DIGITAL>;
> +	clock-names = "dsi0_engine_disp_ck", "dsi0_digital_disp_ck";

Maybe shorten the clock names to "engine" and "digital" ?
And add an example of panel or bridge connected to the DSI sink.

What about DSI1 and the DPI sink?

best regards
Philipp



From lee.jones at linaro.org  Wed Aug 26 09:40:12 2015
From: lee.jones at linaro.org (Lee Jones)
Date: Wed, 26 Aug 2015 17:40:12 +0100
Subject: [PATCH 1/4] remoteproc: dt: Provide bindings for ST's Remote
 Processor Controller driver
In-Reply-To: <55DDE25A.2050000@mentor.com>
References: <1440594483-29601-1-git-send-email-lee.jones@linaro.org>
 <1440594483-29601-2-git-send-email-lee.jones@linaro.org>
 <55DDE25A.2050000@mentor.com>
Message-ID: <20150826164012.GA19409@x1>

On Wed, 26 Aug 2015, Nathan Lynch wrote:

> On 08/26/2015 08:08 AM, Lee Jones wrote:
> > diff --git a/Documentation/devicetree/bindings/remoteproc/st-rproc.txt b/Documentation/devicetree/bindings/remoteproc/st-rproc.txt
> > new file mode 100644
> > index 0000000..6a933c1
> > --- /dev/null
> > +++ b/Documentation/devicetree/bindings/remoteproc/st-rproc.txt
> > @@ -0,0 +1,38 @@
> > +STMicroelectronics Remote Processor
> > +-----------------------------------
> > +
> > +This binding provides support for adjunct processors found on ST SoCs.
> > +
> > +The remote processors can be controlled from the bootloader or the primary OS.
> > +If the bootloader starts a remote processor processor the primary OS must detect
> > +its state and act accordingly.
> > +
> > +The node name is significant, as it defines the name of the CPU and the name
> > +of the firmware to load: "rproc-<name>-fw".
> 
> This business about the firmware name describes a behavior of Linux's
> core remoteproc code and seems out of place in a binding document.

Agreed, will remove.

-- 
Lee Jones
Linaro STMicroelectronics Landing Team Lead
Linaro.org ? Open source software for ARM SoCs
Follow Linaro: Facebook | Twitter | Blog


From drew.richardson at arm.com  Mon Aug 17 13:58:09 2015
From: drew.richardson at arm.com (Drew Richardson)
Date: Mon, 17 Aug 2015 13:58:09 -0700
Subject: [PATCH] arm: perf: Add event descriptions
In-Reply-To: <20150804001522.GA13214@dreric01-gentoo.localdomain>
References: <20150804001522.GA13214@dreric01-gentoo.localdomain>
Message-ID: <20150817205809.GA16506@dreric01-gentoo.localdomain>

On Tue, Aug 04, 2015 at 01:15:23AM +0100, Drew Richardson wrote:
> Add additional information about hardware events to make counters self
> describing. This makes the hardware PMUs easier to use as perf list
> contains the possible events instead of users having to refer to
> documentation like the ARM TRMs. This could also allow tools like
> oprofile to support PMUs without requiring an update.
> 
> Signed-off-by: Drew Richardson <drew.richardson at arm.com>
> ---
>  arch/arm/kernel/perf_event.c    |   1 +
>  arch/arm/kernel/perf_event_v7.c | 617 ++++++++++++++++++++++++++++++++++++++++
>  2 files changed, 618 insertions(+)

Any concerns with merging this?

Thanks,

Drew


From Shenwei.Wang at freescale.com  Wed Aug 26 09:44:02 2015
From: Shenwei.Wang at freescale.com (Shenwei Wang)
Date: Wed, 26 Aug 2015 16:44:02 +0000
Subject: [PATCH 1/1] irqchip: imx-gpcv2:  Simplify the implemenation
In-Reply-To: <55DDE56E.2040206@arm.com>
References: <1440604166-2624-1-git-send-email-shenwei.wang@freescale.com>
 <55DDE56E.2040206@arm.com>
Message-ID: <CY1PR0301MB0843D36145639EB35E956CA383600@CY1PR0301MB0843.namprd03.prod.outlook.com>



> -----Original Message-----
> From: Sudeep Holla [mailto:sudeep.holla at arm.com]
> Sent: 2015?8?26? 11:13
> To: Wang Shenwei-B38339; jason at lakedaemon.net
> Cc: shawn.guo at linaro.org; tglx at linutronix.de; Sudeep Holla;
> linux-arm-kernel at lists.infradead.org; linux-kernel at vger.kernel.org; Huang
> Yongcai-B20788
> Subject: Re: [PATCH 1/1] irqchip: imx-gpcv2: Simplify the implemenation
> 
> typo in $subject

Just noticed. Will change it.

> On 26/08/15 16:49, Shenwei Wang wrote:
> > Based on Sudeep Holla's review comments, the implementation can be
> > simplified by using the two flags: IRQCHIP_SKIP_SET_WAKE and
> > IRQCHIP_MASK_ON_SUSPEND. This patch enables the flags in the struct
> > irq_chip and removes the unnecessory syscore_ops callbacks.
> >
> > Signed-off-by: Shenwei Wang <shenwei.wang at freescale.com>
> > ---
> >   drivers/irqchip/irq-imx-gpcv2.c | 83 +++++++----------------------------------
> >   1 file changed, 13 insertions(+), 70 deletions(-)
> >
> > diff --git a/drivers/irqchip/irq-imx-gpcv2.c
> > b/drivers/irqchip/irq-imx-gpcv2.c index 4a97afa..e25df78 100644
> > --- a/drivers/irqchip/irq-imx-gpcv2.c
> > +++ b/drivers/irqchip/irq-imx-gpcv2.c
> > @@ -22,7 +22,6 @@ struct gpcv2_irqchip_data {
> >   	struct raw_spinlock    rlock;
> >   	void __iomem       *gpc_base;
> >   	u32 wakeup_sources[IMR_NUM];
> > -	u32 saved_irq_mask[IMR_NUM];
> >   	u32 cpu2wakeup;
> >   };
> >
> > @@ -30,79 +29,25 @@ static struct gpcv2_irqchip_data
> > *imx_gpcv2_instance;
> >
> >   u32 imx_gpcv2_get_wakeup_source(u32 **sources)
> 
> I assume this patch is against -next and I don't see any users of
> imx_gpcv2_get_wakeup_source in -next.
> 
> If possible I would avoid exposing this function by implementing suspend_ops just
> as before(just saving raw h/w reg values and restoring then back on resume w/o
> tagging them as wakeup mask though they might be indeed wakeup mask).
> 
> In that way, this driver is self-contained and whatever imx code calls this function
> will not have dependency on this driver, no ? Do you need access to
> imx_gpcv2_get_wakeup_source too early in resume much before suspend_ops
> resume ? I would like to see the user of that function to comment on that any
> further.

It is linux-next. The user is in the following patch which is under review.
http://lists.infradead.org/pipermail/linux-arm-kernel/2015-July/361388.html

The access to this function will only happen in suspend_ops so far.

Regards,
Shenwei


> Regards,
> Sudeep

From will.deacon at arm.com  Wed Aug 26 09:51:49 2015
From: will.deacon at arm.com (Will Deacon)
Date: Wed, 26 Aug 2015 17:51:49 +0100
Subject: [PATCH] arm: perf: Add event descriptions
In-Reply-To: <20150817205809.GA16506@dreric01-gentoo.localdomain>
References: <20150804001522.GA13214@dreric01-gentoo.localdomain>
 <20150817205809.GA16506@dreric01-gentoo.localdomain>
Message-ID: <20150826165148.GF30466@arm.com>

On Mon, Aug 17, 2015 at 09:58:09PM +0100, Drew Richardson wrote:
> On Tue, Aug 04, 2015 at 01:15:23AM +0100, Drew Richardson wrote:
> > Add additional information about hardware events to make counters self
> > describing. This makes the hardware PMUs easier to use as perf list
> > contains the possible events instead of users having to refer to
> > documentation like the ARM TRMs. This could also allow tools like
> > oprofile to support PMUs without requiring an update.
> > 
> > Signed-off-by: Drew Richardson <drew.richardson at arm.com>
> > ---
> >  arch/arm/kernel/perf_event.c    |   1 +
> >  arch/arm/kernel/perf_event_v7.c | 617 ++++++++++++++++++++++++++++++++++++++++
> >  2 files changed, 618 insertions(+)
> 
> Any concerns with merging this?

We should revisit this after the merge window (since the ARM perf code is
moving out to drivers/), but I do have reservations about putting all these
strings into the kernel. Why can't we put this into something like libpfm
instead?

Will


From Nathan_Lynch at mentor.com  Wed Aug 26 10:07:30 2015
From: Nathan_Lynch at mentor.com (Nathan Lynch)
Date: Wed, 26 Aug 2015 12:07:30 -0500
Subject: [PATCH 2/4] remoteproc: Supply controller driver for ST's Remote
 Processors
In-Reply-To: <1440594483-29601-3-git-send-email-lee.jones@linaro.org>
References: <1440594483-29601-1-git-send-email-lee.jones@linaro.org>
 <1440594483-29601-3-git-send-email-lee.jones@linaro.org>
Message-ID: <55DDF252.2010901@mentor.com>

On 08/26/2015 08:08 AM, Lee Jones wrote:
> --- /dev/null
> +++ b/drivers/remoteproc/st_remoteproc.c
> @@ -0,0 +1,300 @@
> +/*
> + * ST's Remote Processor Control Driver
> + *
> + * Copyright (C) 2015 STMicroelectronics - All Rights Reserved
> + *
> + * Author: Ludovic Barre <ludovic.barre at st.com>

When submitting code you didn't write, I'd say it's better practice to
clearly indicate its provenance in the commit message.  E.g. something
like "Driver based on code authored by Ludovic Barre for ST".  And
obtain signoffs etc if possible.


> + *
> + * 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.

Please review the wording here.  It's unclear whether this is intended
to be v2-only or v2 or later.


> +static int st_rproc_stop(struct rproc *rproc)
> +{
> +	struct st_rproc *st_rproc = rproc->priv;
> +	int err = 0;
> +
> +	if (st_rproc->config->sw_reset) {
> +		err = reset_control_assert(st_rproc->sw_reset);
> +		if (err)
> +			dev_warn(&rproc->dev, "Failed to assert S/W Reset\n");
> +	}
> +
> +	if (st_rproc->config->pwr_reset) {
> +		err = reset_control_assert(st_rproc->pwr_reset);
> +		if (err)
> +			dev_warn(&rproc->dev, "Failed to assert Power Reset\n");
> +	}
> +
> +	clk_disable(st_rproc->clk);
> +
> +	return 0;
> +}

Seems like st_rproc_stop should propagate errors back to its caller
instead of always returning 0.



From Nathan_Lynch at mentor.com  Wed Aug 26 10:08:48 2015
From: Nathan_Lynch at mentor.com (Nathan Lynch)
Date: Wed, 26 Aug 2015 12:08:48 -0500
Subject: [PATCH 4/4] remoteproc: debugfs: Add ability to boot remote
 processor using debugfs
In-Reply-To: <1440594483-29601-5-git-send-email-lee.jones@linaro.org>
References: <1440594483-29601-1-git-send-email-lee.jones@linaro.org>
 <1440594483-29601-5-git-send-email-lee.jones@linaro.org>
Message-ID: <55DDF2A0.5010404@mentor.com>

On 08/26/2015 08:08 AM, Lee Jones wrote:
> Signed-off-by: Lee Jones <lee.jones at linaro.org>
> ---
>  drivers/remoteproc/remoteproc_debugfs.c | 25 +++++++++++++++++++++++++
>  1 file changed, 25 insertions(+)

The commit message should describe why this is needed...


> diff --git a/drivers/remoteproc/remoteproc_debugfs.c b/drivers/remoteproc/remoteproc_debugfs.c
> index 9d30809..9620962 100644
> --- a/drivers/remoteproc/remoteproc_debugfs.c
> +++ b/drivers/remoteproc/remoteproc_debugfs.c
> @@ -88,8 +88,33 @@ static ssize_t rproc_state_read(struct file *filp, char __user *userbuf,
>  	return simple_read_from_buffer(userbuf, count, ppos, buf, i);
>  }
>  
> +static ssize_t rproc_state_write(struct file *filp, const char __user *userbuf,
> +				 size_t count, loff_t *ppos)
> +{
> +	struct rproc *rproc = filp->private_data;
> +	char buf[2];
> +	int ret;
> +
> +	ret = copy_from_user(buf, userbuf, 1);
> +	if (ret)
> +		return -EFAULT;
> +
> +	switch (buf[0]) {
> +	case '1':
> +		ret = rproc_boot(rproc);
> +		if (ret)
> +			dev_warn(&rproc->dev, "Boot failed: %d\n", ret);
> +		break;
> +	default:
> +		rproc_shutdown(rproc);
> +	}
> +
> +	return count;
> +}

... and I suggest that the user interface be reconsidered.  If '1' means
"boot" and literally anything else means "shut down" then you can't add
operations in the future without potentially breaking things.



From sudeep.holla at arm.com  Wed Aug 26 10:10:53 2015
From: sudeep.holla at arm.com (Sudeep Holla)
Date: Wed, 26 Aug 2015 18:10:53 +0100
Subject: [PATCH 1/1] irqchip: imx-gpcv2:  Simplify the implemenation
In-Reply-To: <CY1PR0301MB0843D36145639EB35E956CA383600@CY1PR0301MB0843.namprd03.prod.outlook.com>
References: <1440604166-2624-1-git-send-email-shenwei.wang@freescale.com>
 <55DDE56E.2040206@arm.com>
 <CY1PR0301MB0843D36145639EB35E956CA383600@CY1PR0301MB0843.namprd03.prod.outlook.com>
Message-ID: <55DDF31D.2030702@arm.com>



On 26/08/15 17:44, Shenwei Wang wrote:
>
>
>> -----Original Message-----
>> From: Sudeep Holla [mailto:sudeep.holla at arm.com]
>> Sent: 2015?8?26? 11:13
>> To: Wang Shenwei-B38339; jason at lakedaemon.net
>> Cc: shawn.guo at linaro.org; tglx at linutronix.de; Sudeep Holla;
>> linux-arm-kernel at lists.infradead.org; linux-kernel at vger.kernel.org; Huang
>> Yongcai-B20788
>> Subject: Re: [PATCH 1/1] irqchip: imx-gpcv2: Simplify the implemenation
>>
>> typo in $subject
>
> Just noticed. Will change it.
>
>> On 26/08/15 16:49, Shenwei Wang wrote:
>>> Based on Sudeep Holla's review comments, the implementation can be
>>> simplified by using the two flags: IRQCHIP_SKIP_SET_WAKE and
>>> IRQCHIP_MASK_ON_SUSPEND. This patch enables the flags in the struct
>>> irq_chip and removes the unnecessory syscore_ops callbacks.
>>>
>>> Signed-off-by: Shenwei Wang <shenwei.wang at freescale.com>
>>> ---
>>>    drivers/irqchip/irq-imx-gpcv2.c | 83 +++++++----------------------------------
>>>    1 file changed, 13 insertions(+), 70 deletions(-)
>>>
>>> diff --git a/drivers/irqchip/irq-imx-gpcv2.c
>>> b/drivers/irqchip/irq-imx-gpcv2.c index 4a97afa..e25df78 100644
>>> --- a/drivers/irqchip/irq-imx-gpcv2.c
>>> +++ b/drivers/irqchip/irq-imx-gpcv2.c
>>> @@ -22,7 +22,6 @@ struct gpcv2_irqchip_data {
>>>    	struct raw_spinlock    rlock;
>>>    	void __iomem       *gpc_base;
>>>    	u32 wakeup_sources[IMR_NUM];
>>> -	u32 saved_irq_mask[IMR_NUM];
>>>    	u32 cpu2wakeup;
>>>    };
>>>
>>> @@ -30,79 +29,25 @@ static struct gpcv2_irqchip_data
>>> *imx_gpcv2_instance;
>>>
>>>    u32 imx_gpcv2_get_wakeup_source(u32 **sources)
>>
>> I assume this patch is against -next and I don't see any users of
>> imx_gpcv2_get_wakeup_source in -next.
>>
>> If possible I would avoid exposing this function by implementing suspend_ops just
>> as before(just saving raw h/w reg values and restoring then back on resume w/o
>> tagging them as wakeup mask though they might be indeed wakeup mask).
>>
>> In that way, this driver is self-contained and whatever imx code calls this function
>> will not have dependency on this driver, no ? Do you need access to
>> imx_gpcv2_get_wakeup_source too early in resume much before suspend_ops
>> resume ? I would like to see the user of that function to comment on that any
>> further.
>
> It is linux-next. The user is in the following patch which is under review.
> http://lists.infradead.org/pipermail/linux-arm-kernel/2015-July/361388.html
>

I got lost trying to follow through that 1000 odd line of code with lots
of register accesses. I couldn't understand much, so I gave up.

Such details are abstracted well and hidden in firmware with PSCI(good
that it's enforced in ARM64, hopefully ARM32 also sees more adoption).

So, for the parts adding those 2 flags and removing the unnecessary
code, you can add:
Reviewed-by: Sudeep Holla <sudeep.holla at arm.com>

Regards,
Sudeep


From stefan at agner.ch  Wed Aug 26 10:11:25 2015
From: stefan at agner.ch (Stefan Agner)
Date: Wed, 26 Aug 2015 10:11:25 -0700
Subject: [PATCH] gpio: vf610: handle level IRQ's properly
In-Reply-To: <CACRpkdYqU_yvZE4WS2jBDOhemPy7dcHeOoj_dG61hCL8ugTMYg@mail.gmail.com>
References: <1440197802-29720-1-git-send-email-stefan@agner.ch>
 <CACRpkdYqU_yvZE4WS2jBDOhemPy7dcHeOoj_dG61hCL8ugTMYg@mail.gmail.com>
Message-ID: <99db8c092e8b54d485e88887630d51c0@agner.ch>

On 2015-08-26 05:47, Linus Walleij wrote:
> On Sat, Aug 22, 2015 at 12:56 AM, Stefan Agner <stefan at agner.ch> wrote:
> 
>> The GPIO IRQ controller is able to generate level triggered
>> interrupts, however, these were handled by handle_simple_irq so far
>> which did not take care of IRQ masking. This lead to "nobody cared
>> (try booting with the "irqpoll" option)" stack traces.
>>
>> Use the generic interrupt handlers depending on the IRQ type.
>>
>> Signed-off-by: Stefan Agner <stefan at agner.ch>
> 
> Patch applied.

Thx

 
> Hm, this looks like a problem that could exist in a few more
> GPIO drivers. Can you look around and see if there is something
> immediately suspicious in drivers/gpio?

Just looked a bit around. There are some which use handle_simple_irq but
also run their handler in threaded/one-shot handler. I guess in that
case it is fine to use the simple_irq handler.

However, those GPIO drivers look suspicious:

gpio-altera.c: Uses handle_simple_irq, supports edge and level
gpio-bcm-kona.c: Uses handle_simple_irq, supports only edge
gpio-grgpio.c: Uses handle_simple_irq, supports edge and level
gpio-intel-mid.c: Uses handle_simple_irq, supports only edge
gpio-lynxpoint.c: Uses handle_simple_irq, supports edge and level
gpio-ml-ioh.c: Uses handle_simple_irq, supports edge and level
gpio-pl061.c: Uses handle_simple_irq, supports edge and level
gpio-rcar.c: Uses handle_level_irq, supports edge and level
gpio-timberdale.c: Uses handle_simple_irq, supports edge and level

--
Stefan


From f.fainelli at gmail.com  Wed Aug 26 10:17:05 2015
From: f.fainelli at gmail.com (Florian Fainelli)
Date: Wed, 26 Aug 2015 10:17:05 -0700
Subject: [PATCH 5/5] MAINTAINERS: add entry for the Broadcom Northstar
 Plus SoCs
In-Reply-To: <CAOesGMioBQY9qy-S8kMJmo_=B6-KZiUkd=Ns1Uo2dGu0BiqppQ@mail.gmail.com>
References: <1440092861-25825-1-git-send-email-jonmason@broadcom.com>
 <CAOesGMioBQY9qy-S8kMJmo_=B6-KZiUkd=Ns1Uo2dGu0BiqppQ@mail.gmail.com>
Message-ID: <55DDF491.3090700@gmail.com>

On 25/08/15 16:42, Olof Johansson wrote:
> On Thu, Aug 20, 2015 at 10:47 AM, Jon Mason <jonmason at broadcom.com> wrote:
>> Modify the iProc MAINTAINER to cover the Nortstar Plus SoCs, and add me
>> to the list of people responsible for it.
> 
> That's not what this patch does. It removes CYGNUS from the
> description as well. Hmm?
> 
> I'm also not a fan of the complex patterns, but that's more of a
> bikeshedding comment. Does Broadcom really not have a bit more
> systematic naming than this? :)

The naming conventions are fairly simple actually:

* BCM is just a common prefix for internal names/projects/whatever
* 9 indicates that this is a development/reference board
* 4 to 5 digits designate the chip identifier

Now, if you are trying to get some sense about how the chip ids are
actually chosen, I am afraid none of us have that knowledge ;)

> 
>> Signed-off-by: Jon Mason <jonmason at broadcom.com>
>> Reviewed-by: Scott Branden <sbranden at broadcom.com>
> 
> For maintainer updates, we usuallu like to see a public ack of this
> and not just a pre-acked patch. You _could_ have added it yourself
> without Scott's actual approval, after all.
> 
> 
> -Olof
> 


-- 
Florian


From matt at codeblueprint.co.uk  Wed Aug 26 10:24:55 2015
From: matt at codeblueprint.co.uk (Matt Fleming)
Date: Wed, 26 Aug 2015 18:24:55 +0100
Subject: [PATCH 2/3] arm64: use core efi=debug instead of uefi_debug
 command line parameter
In-Reply-To: <1440595498-30630-3-git-send-email-leif.lindholm@linaro.org>
References: <1440595498-30630-1-git-send-email-leif.lindholm@linaro.org>
 <1440595498-30630-3-git-send-email-leif.lindholm@linaro.org>
Message-ID: <20150826172455.GB2837@codeblueprint.co.uk>

On Wed, 26 Aug, at 02:24:57PM, Leif Lindholm wrote:
> Now that we have an efi=debug command line option in the core code, use
> this instead of the arm64-specific uefi_debug option.
> 
> Signed-off-by: Leif Lindholm <leif.lindholm at linaro.org>
> ---
>  Documentation/arm/uefi.txt |  2 --
>  arch/arm64/kernel/efi.c    | 19 +++++--------------
>  2 files changed, 5 insertions(+), 16 deletions(-)

Are there no concerns with backwards-compatibility here? I expected
this patch to internally convert uefi_debug to efi=debug if old boot
loaders, kernel config, etc specify it.

Is that something that can be safely ignored?

-- 
Matt Fleming, Intel Open Source Technology Center


From drew.richardson at arm.com  Mon Aug 17 14:40:36 2015
From: drew.richardson at arm.com (Drew Richardson)
Date: Mon, 17 Aug 2015 14:40:36 -0700
Subject: [PATCH] arm: perf: Add event descriptions
In-Reply-To: <20150826165148.GF30466@arm.com>
References: <20150804001522.GA13214@dreric01-gentoo.localdomain>
 <20150817205809.GA16506@dreric01-gentoo.localdomain>
 <20150826165148.GF30466@arm.com>
Message-ID: <20150817214035.GA25775@dreric01-gentoo.localdomain>

On Wed, Aug 26, 2015 at 05:51:49PM +0100, Will Deacon wrote:
> On Mon, Aug 17, 2015 at 09:58:09PM +0100, Drew Richardson wrote:
> > On Tue, Aug 04, 2015 at 01:15:23AM +0100, Drew Richardson wrote:
> > > Add additional information about hardware events to make counters self
> > > describing. This makes the hardware PMUs easier to use as perf list
> > > contains the possible events instead of users having to refer to
> > > documentation like the ARM TRMs. This could also allow tools like
> > > oprofile to support PMUs without requiring an update.
> > > 
> > > Signed-off-by: Drew Richardson <drew.richardson at arm.com>
> > > ---
> > >  arch/arm/kernel/perf_event.c    |   1 +
> > >  arch/arm/kernel/perf_event_v7.c | 617 ++++++++++++++++++++++++++++++++++++++++
> > >  2 files changed, 618 insertions(+)
> > 
> > Any concerns with merging this?
> 
> We should revisit this after the merge window (since the ARM perf code is
> moving out to drivers/)

Not a problem

> but I do have reservations about putting all these
> strings into the kernel. Why can't we put this into something like libpfm
> instead?
> 
> Will
> 

My intent is to make it easier for people to use hardware counters on
ARM, particularly with new CPUs. Currently, the developer of the tool
needs to extract the event information from the ARM TRMs, add it to
their tool and make a new release. This work is done by multiple
tools, for example for the Cortex-A15:

http://sourceforge.net/p/perfmon2/libpfm4/ci/master/tree/lib/events/arm_cortex_a15_events.h
http://sourceforge.net/p/oprofile/oprofile/ci/master/tree/events/arm/armv7-ca15/events
https://github.com/ARM-software/gator/blob/master/daemon/events-Cortex-A15.xml

There are likely more tools, these are the ones I could easily
find. Note that the new ARM Cortex-A72 isn't supported by most of
them. And the perf command line tool doesn't have any of this.

Once the tool supports the new CPUs events the user needs to make sure
they're running a recent version of the tool that contains these
events for their new ARM CPU. Technically the user could add the event
information themselves and upstream the change, but not all users will
do this.

So my suggestion to solve the problem is that the kernel can have the
list of events as proposed in the patch. This is already done for some
PMUs like arm-ccn and arm-cci. If the tool doesn't support the
particular CPU, they can fall back to the event list provided by the
kernel. There will be some information missing like user-friendly
descriptions of the events, but it's hopefully enough that users can
do what they need to do and update their tool at a later time.

I'd be glad to wrap this all in a config option so users can disable
it to reduce bloat. Perhaps there is some other central location
outside the kernel that could store this information?

Thanks,

Drew


From matt at codeblueprint.co.uk  Wed Aug 26 10:25:41 2015
From: matt at codeblueprint.co.uk (Matt Fleming)
Date: Wed, 26 Aug 2015 18:25:41 +0100
Subject: [PATCH 1/3] efi/x86: move efi=debug option parsing to core
In-Reply-To: <1440595498-30630-2-git-send-email-leif.lindholm@linaro.org>
References: <1440595498-30630-1-git-send-email-leif.lindholm@linaro.org>
 <1440595498-30630-2-git-send-email-leif.lindholm@linaro.org>
Message-ID: <20150826172541.GC2837@codeblueprint.co.uk>

On Wed, 26 Aug, at 02:24:56PM, Leif Lindholm wrote:
> fed6cefe3b6e ("x86/efi: Add a "debug" option to the efi= cmdline")
> adds the DBG flag, but does so for x86 only. Move this early param
> parsing to core code.
> 
> Signed-off-by: Leif Lindholm <leif.lindholm at linaro.org>
> ---
>  arch/x86/platform/efi/efi.c | 2 --
>  drivers/firmware/efi/efi.c  | 3 +++
>  2 files changed, 3 insertions(+), 2 deletions(-)

Nice clean up. Thanks Leif, applied.

-- 
Matt Fleming, Intel Open Source Technology Center


From leif.lindholm at linaro.org  Wed Aug 26 10:30:00 2015
From: leif.lindholm at linaro.org (Leif Lindholm)
Date: Wed, 26 Aug 2015 18:30:00 +0100
Subject: [PATCH 2/3] arm64: use core efi=debug instead of uefi_debug
 command line parameter
In-Reply-To: <20150826172455.GB2837@codeblueprint.co.uk>
References: <1440595498-30630-1-git-send-email-leif.lindholm@linaro.org>
 <1440595498-30630-3-git-send-email-leif.lindholm@linaro.org>
 <20150826172455.GB2837@codeblueprint.co.uk>
Message-ID: <20150826173000.GG10728@bivouac.eciton.net>

On Wed, Aug 26, 2015 at 06:24:55PM +0100, Matt Fleming wrote:
> On Wed, 26 Aug, at 02:24:57PM, Leif Lindholm wrote:
> > Now that we have an efi=debug command line option in the core code, use
> > this instead of the arm64-specific uefi_debug option.
> > 
> > Signed-off-by: Leif Lindholm <leif.lindholm at linaro.org>
> > ---
> >  Documentation/arm/uefi.txt |  2 --
> >  arch/arm64/kernel/efi.c    | 19 +++++--------------
> >  2 files changed, 5 insertions(+), 16 deletions(-)
> 
> Are there no concerns with backwards-compatibility here? I expected
> this patch to internally convert uefi_debug to efi=debug if old boot
> loaders, kernel config, etc specify it.
> 
> Is that something that can be safely ignored?

Since it is purely a debug feature, I opted to just drop it.
I don't have strong feelings, and it could certainly be kept as an
arm64-only alias (but setting the EFI_DBG flag) if others disagree.

/
    Leif


From broonie at kernel.org  Wed Aug 26 10:38:12 2015
From: broonie at kernel.org (Mark Brown)
Date: Wed, 26 Aug 2015 18:38:12 +0100
Subject: [PATCH] regmap: Fix the null function of format_val on
 regmap_bulk_read.
In-Reply-To: <20150826132246.GR706@pengutronix.de>
References: <1440589396-696-1-git-send-email-henryc.chen@mediatek.com>
 <20150826123556.GB2977@sirena.org.uk>
 <20150826132246.GR706@pengutronix.de>
Message-ID: <20150826173812.GA28760@sirena.org.uk>

On Wed, Aug 26, 2015 at 03:22:46PM +0200, Markus Pargmann wrote:
> On Wed, Aug 26, 2015 at 01:35:56PM +0100, Mark Brown wrote:
> > On Wed, Aug 26, 2015 at 07:43:16PM +0800, Henry Chen wrote:

> > Why are these format functions sensible?  Converting a null pointer
> > dereference into data corruption wouldn't be ideal.  The commit message
> > should really cover this.

> The regmap_bulk_read() function worked before the following patch:
> 	15b8d2c41fe5 (regmap: Fix regmap_bulk_read in BE mode)

Define "worked" here.

> As far as I can see this patch fixes this issue by using simple format
> functions. Before the above mentioned patch, the code used memcpy. Now
> regmap_format_*_native is used which should result in the same behaviour
> but fixes the null pointer.

Again, this sort of analysis needs to be in the commit message (and
really ought to explain why the resulting API makes sense).

> I am not sure if there are other locations in the code where format_val
> is used in this setup so I don't know if this would change behavior in a
> different codepath.

Which is another part of the concern, being able to format values is a
more general concept.
-------------- next part --------------
A non-text attachment was scrubbed...
Name: signature.asc
Type: application/pgp-signature
Size: 473 bytes
Desc: Digital signature
URL: <http://lists.infradead.org/pipermail/linux-arm-kernel/attachments/20150826/8d198de1/attachment-0001.sig>

From cov at codeaurora.org  Wed Aug 26 10:57:21 2015
From: cov at codeaurora.org (Christopher Covington)
Date: Wed, 26 Aug 2015 13:57:21 -0400
Subject: [PATCH 2/5] coresight-etm4x: Change the name of the
 ctxid_val to ctxid_pid
In-Reply-To: <1436258518-9339-3-git-send-email-zhang.chunyan@linaro.org>
References: <1436258518-9339-1-git-send-email-zhang.chunyan@linaro.org>
 <1436258518-9339-3-git-send-email-zhang.chunyan@linaro.org>
Message-ID: <55DDFE01.50201@codeaurora.org>

On 07/07/2015 04:41 AM, Chunyan Zhang wrote:
> 'ctxid_val' array was used to store the value of ETM context ID comparator
> which actually stores the process ID to be traced, so using 'ctxid_pid' as
> its name instead make it easier to understand.

Previous discussion with some ARM folks has led me to believe there isn't a
guarantee that the Context ID Register will always have a PID. Why not allow
filtering on thread group ID, session ID, cgroup related identifiers, etc.?

> This patch also changes the ABI, it is normally not allowed, but
> fortunately it is a testing ABI and very new for now. Nevertheless,
> if you don't think it should be changed, we could always add an alias
> for userspace.
> 
> Signed-off-by: Chunyan Zhang <zhang.chunyan at linaro.org>
> Reviewed-by: Mark Brown <broonie at kernel.org>
> ---
>  .../ABI/testing/sysfs-bus-coresight-devices-etm4x    |  2 +-
>  drivers/hwtracing/coresight/coresight-etm4x.c        | 20 ++++++++++----------
>  drivers/hwtracing/coresight/coresight-etm4x.h        |  4 ++--
>  3 files changed, 13 insertions(+), 13 deletions(-)
> 
> diff --git a/Documentation/ABI/testing/sysfs-bus-coresight-devices-etm4x b/Documentation/ABI/testing/sysfs-bus-coresight-devices-etm4x
> index 2fe2e3d..2355ed8 100644
> --- a/Documentation/ABI/testing/sysfs-bus-coresight-devices-etm4x
> +++ b/Documentation/ABI/testing/sysfs-bus-coresight-devices-etm4x
> @@ -249,7 +249,7 @@ KernelVersion:	4.01
>  Contact:	Mathieu Poirier <mathieu.poirier at linaro.org>
>  Description:	(RW) Select which context ID comparator to work with.
>  
> -What:		/sys/bus/coresight/devices/<memory_map>.etm/ctxid_val
> +What:		/sys/bus/coresight/devices/<memory_map>.etm/ctxid_pid
>  Date:		April 2015
>  KernelVersion:	4.01
>  Contact:	Mathieu Poirier <mathieu.poirier at linaro.org>
> diff --git a/drivers/hwtracing/coresight/coresight-etm4x.c b/drivers/hwtracing/coresight/coresight-etm4x.c
> index 1312e99..9afbda5 100644
> --- a/drivers/hwtracing/coresight/coresight-etm4x.c
> +++ b/drivers/hwtracing/coresight/coresight-etm4x.c
> @@ -155,7 +155,7 @@ static void etm4_enable_hw(void *info)
>  			       drvdata->base + TRCACATRn(i));
>  	}
>  	for (i = 0; i < drvdata->numcidc; i++)
> -		writeq_relaxed(drvdata->ctxid_val[i],
> +		writeq_relaxed(drvdata->ctxid_pid[i],
>  			       drvdata->base + TRCCIDCVRn(i));
>  	writel_relaxed(drvdata->ctxid_mask0, drvdata->base + TRCCIDCCTLR0);
>  	writel_relaxed(drvdata->ctxid_mask1, drvdata->base + TRCCIDCCTLR1);
> @@ -507,7 +507,7 @@ static ssize_t reset_store(struct device *dev,
>  
>  	drvdata->ctxid_idx = 0x0;
>  	for (i = 0; i < drvdata->numcidc; i++)
> -		drvdata->ctxid_val[i] = 0x0;
> +		drvdata->ctxid_pid[i] = 0x0;
>  	drvdata->ctxid_mask0 = 0x0;
>  	drvdata->ctxid_mask1 = 0x0;
>  
> @@ -1815,7 +1815,7 @@ static ssize_t ctxid_idx_store(struct device *dev,
>  }
>  static DEVICE_ATTR_RW(ctxid_idx);
>  
> -static ssize_t ctxid_val_show(struct device *dev,
> +static ssize_t ctxid_pid_show(struct device *dev,
>  			      struct device_attribute *attr,
>  			      char *buf)
>  {
> @@ -1825,12 +1825,12 @@ static ssize_t ctxid_val_show(struct device *dev,
>  
>  	spin_lock(&drvdata->spinlock);
>  	idx = drvdata->ctxid_idx;
> -	val = (unsigned long)drvdata->ctxid_val[idx];
> +	val = (unsigned long)drvdata->ctxid_pid[idx];
>  	spin_unlock(&drvdata->spinlock);
>  	return scnprintf(buf, PAGE_SIZE, "%#lx\n", val);
>  }
>  
> -static ssize_t ctxid_val_store(struct device *dev,
> +static ssize_t ctxid_pid_store(struct device *dev,
>  			       struct device_attribute *attr,
>  			       const char *buf, size_t size)
>  {
> @@ -1850,11 +1850,11 @@ static ssize_t ctxid_val_store(struct device *dev,
>  
>  	spin_lock(&drvdata->spinlock);
>  	idx = drvdata->ctxid_idx;
> -	drvdata->ctxid_val[idx] = (u64)val;
> +	drvdata->ctxid_pid[idx] = (u64)val;
>  	spin_unlock(&drvdata->spinlock);
>  	return size;
>  }
> -static DEVICE_ATTR_RW(ctxid_val);
> +static DEVICE_ATTR_RW(ctxid_pid);
>  
>  static ssize_t ctxid_masks_show(struct device *dev,
>  				struct device_attribute *attr,
> @@ -1949,7 +1949,7 @@ static ssize_t ctxid_masks_store(struct device *dev,
>  		 */
>  		for (j = 0; j < 8; j++) {
>  			if (maskbyte & 1)
> -				drvdata->ctxid_val[i] &= ~(0xFF << (j * 8));
> +				drvdata->ctxid_pid[i] &= ~(0xFF << (j * 8));
>  			maskbyte >>= 1;
>  		}
>  		/* Select the next ctxid comparator mask value */
> @@ -2193,7 +2193,7 @@ static struct attribute *coresight_etmv4_attrs[] = {
>  	&dev_attr_res_idx.attr,
>  	&dev_attr_res_ctrl.attr,
>  	&dev_attr_ctxid_idx.attr,
> -	&dev_attr_ctxid_val.attr,
> +	&dev_attr_ctxid_pid.attr,
>  	&dev_attr_ctxid_masks.attr,
>  	&dev_attr_vmid_idx.attr,
>  	&dev_attr_vmid_val.attr,
> @@ -2514,7 +2514,7 @@ static void etm4_init_default_data(struct etmv4_drvdata *drvdata)
>  	}
>  
>  	for (i = 0; i < drvdata->numcidc; i++)
> -		drvdata->ctxid_val[i] = 0x0;
> +		drvdata->ctxid_pid[i] = 0x0;
>  	drvdata->ctxid_mask0 = 0x0;
>  	drvdata->ctxid_mask1 = 0x0;
>  
> diff --git a/drivers/hwtracing/coresight/coresight-etm4x.h b/drivers/hwtracing/coresight/coresight-etm4x.h
> index e08e983..1e8fb36 100644
> --- a/drivers/hwtracing/coresight/coresight-etm4x.h
> +++ b/drivers/hwtracing/coresight/coresight-etm4x.h
> @@ -265,7 +265,7 @@
>   * @addr_type:	Current status of the comparator register.
>   * @ctxid_idx:	Context ID index selector.
>   * @ctxid_size:	Size of the context ID field to consider.
> - * @ctxid_val:	Value of the context ID comparator.
> + * @ctxid_pid:	Value of the context ID comparator.
>   * @ctxid_mask0:Context ID comparator mask for comparator 0-3.
>   * @ctxid_mask1:Context ID comparator mask for comparator 4-7.
>   * @vmid_idx:	VM ID index selector.
> @@ -352,7 +352,7 @@ struct etmv4_drvdata {
>  	u8				addr_type[ETM_MAX_SINGLE_ADDR_CMP];
>  	u8				ctxid_idx;
>  	u8				ctxid_size;
> -	u64				ctxid_val[ETMv4_MAX_CTXID_CMP];
> +	u64				ctxid_pid[ETMv4_MAX_CTXID_CMP];
>  	u32				ctxid_mask0;
>  	u32				ctxid_mask1;
>  	u8				vmid_idx;
> 


-- 
Qualcomm Innovation Center, Inc.
The Qualcomm Innovation Center, Inc. is a member of the Code Aurora Forum,
a Linux Foundation Collaborative Project


From stefan at agner.ch  Wed Aug 26 10:57:38 2015
From: stefan at agner.ch (Stefan Agner)
Date: Wed, 26 Aug 2015 10:57:38 -0700
Subject: [PATCH v10 2/5] mtd: nand: vf610_nfc: add hardware BCH-ECC support
In-Reply-To: <20150825195411.GJ81844@google.com>
References: <1438594050-4595-1-git-send-email-stefan@agner.ch>
 <1438594050-4595-3-git-send-email-stefan@agner.ch>
 <ff2e2716578a1ae5f0c4b0e0ca8bbdc3@agner.ch>
 <20150825195411.GJ81844@google.com>
Message-ID: <07a479863eef4c53ab2ef6ef85321680@agner.ch>

On 2015-08-25 12:54, Brian Norris wrote:
> On Mon, Aug 03, 2015 at 11:28:43AM +0200, Stefan Agner wrote:
>> On 2015-08-03 11:27, Stefan Agner wrote:
>> <snip>
>> > +static inline int vf610_nfc_correct_data(struct mtd_info *mtd, uint8_t *dat,
>> > +					 uint8_t *oob, int oob_loaded)
>> > +{
>> > +	struct vf610_nfc *nfc = mtd_to_nfc(mtd);
>> > +	u8 ecc_status;
>> > +	u8 ecc_count;
>> > +	int flip;
>> > +
>> > +	ecc_status = __raw_readb(nfc->regs + ECC_SRAM_ADDR * 8 + ECC_OFFSET);
> 
> Why __raw_readb()? That's not normally encourage, and it has issues with
> endianness. It looks like maybe this is actulaly a 32-bit register, and
> you're having trouble when trying to do bytewise access? I see this
> earlier:
> 
> /*
>  * ECC status is stored at NFC_CFG[ECCADD] +4 for little-endian
>  * and +7 for big-endian SoCs.
>  */
> #ifdef __LITTLE_ENDIAN
> #define ECC_OFFSET      4
> #else
> #define ECC_OFFSET      7
> #endif
> 
> So maybe you really just want:
> 
> #define ECC_OFFSET	4
> ...
> 	ecc_status = vf610_nfc_read(ECC_SRAM_ADDR * 8 + ECC_OFFSET) & 0xff;
> 
> ?
> 

Agreed, much cleaner.

>> > +	ecc_count = ecc_status & ECC_ERR_COUNT;
>> > +
>> > +	if (!(ecc_status & ECC_STATUS_MASK))
>> > +		return ecc_count;
>> > +
>> > +	if (!oob_loaded)
>> > +		vf610_nfc_read_buf(mtd, oob, mtd->oobsize);
>> > +
>> > +	/*
>> > +	 * On an erased page, bit count (including OOB) should be zero or
>> > +	 * at least less then half of the ECC strength.
>> > +	 */
>> > +	flip = count_written_bits(dat, nfc->chip.ecc.size, ecc_count);
> 
> Another side note: why are you using ecc_count as a max threshold? AIUI,
> an ECC algorithm doesn't really report useful error count information if
> it's above the correction limit. So wouldn't we be looking to count up
> to our SW threshold? i.e., ecc.strength / 2, or similar? Similar
> comments below.
> 

Initially, that was the only threshold below, hence it made sense. But I
agree, we should count up to the threshold used below...

>> > +	flip += count_written_bits(oob, mtd->oobsize - nfc->chip.ecc.bytes,
>> > +				   ecc_count);
>>
>> With ECC the controller seems to clear the ECC bytes in SRAM buffer.
>> This is a dump of 64 Bit OOB with the 32-error ECC mode which requires
>> 60 bytes of OOB for ECC:
>>
>> [   22.190273] ff ff ff ff 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
>> 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
>> 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
> 
> Hmm, that's not really good. The point is that we need to make sure that
> everything that could have been programmed (including the ECC area) was
> not actually programmed. But your ECC controller is not, contrary to
> MTD's expectations, dumping raw uncorrected data here.
> 
>> [   22.209698] vf610_nfc_correct_data, flips 1
>>
>> Not sure if this is acceptable, but I now only count the bits in the
>> non-ECC area of the OOB.
> 
> That's not the intention of my suggestion. You're still missing out on a
> class of patterns that might look close to all 0xff but are not
> actually.
> 
> If the HW ECC really doesn't give you valid data+OOB at this point, then
> you might have to re-read with ECC disabled. Of course, that's got a
> performance cost...

Yes I can do that. Not sure yet how it will look like exactly, maybe I
only need to reread the OOB area and (re-)use the main data part since
those arrive uncorrected in the error case.

> 
> Or perhaps Boris has a better suggestion? He's been surveying other NAND
> drivers that need to do similar things, and he's working on providing
> some support code for common design patterns.
> 
>> Btw, if the ECC check fails, the controller seems kind of count the
>> amount of bitflips. It works for most devices reliable, but we had
>> devices for which that number was not accurate, see:
>> http://thread.gmane.org/gmane.linux.ports.arm.kernel/357439
> 
> I'm a little confused there. Why would you be expecting to get a count
> of bitflips, when the ECC engine can't correct all errors? How is it
> supposed to know what the "right" data is if the bit errors are beyond
> the correction strength?

When printing the ECC error count on ECC fail when reading an erased
NAND flash, the numbers of bit flips (stuck at zero) seem to widely
correlate with the number returned by the controller. While it seems to
correlate widely, there are exceptions, as discussed in the thread:
http://thread.gmane.org/gmane.linux.ports.arm.kernel/295424

Maybe this is an artifact of the ECC algorithm we just can't/shouldn't
rely on? I am not sure where this originated, I did not found any
indication in the reference manual about what that value contains in the
error case.

Bill, do you have an idea why we used that value as threshold in early
implementations?

Otherwise I also think we should just drop the use of this value.

--
Stefan


From grygorii.strashko at ti.com  Wed Aug 26 10:58:10 2015
From: grygorii.strashko at ti.com (Grygorii Strashko)
Date: Wed, 26 Aug 2015 20:58:10 +0300
Subject: [PATCH] ARM: OMAP2+: omap-device: remove omap_device_late_init call
 completely
Message-ID: <1440611890-4935-1-git-send-email-grygorii.strashko@ti.com>

Now Kernel fails to boot 50% of times (form build to build) with
RT-patchset applied due to the following race - on late boot
stages deferred_probe_work_func races with omap_device_late_ini

late_initcall
 - deferred_probe_initcal() tries to re-probe all pending driver's probe.
   [In general, It's NOT expected to probe any other built-in drivers after
   deferred_probe_initcal() is finished, because most of
   late_initcall_sync/late_initcall functions expected that all driver
   or probed or deferred already.]

- later on, some driver is probing in this case It's could cpsw.c
  (but could be any other drivers)
  cpsw_init
  - platform_driver_register
    - really_probe
       - driver_bound
         - driver_deferred_probe_trigger
  and boot proceed.
  So, at this moment we have  deferred_probe_work_func scheduled.

late_initcall_sync
  - omap_device_late_init
    - omap_device_idle

CPU1					CPU2
  - deferred_probe_work_func
    - really_probe
      - omap_hsmmc_probe
	- pm_runtime_get_sync
					late_initcall_sync
					- omap_device_late_init
						if (od->_driver_status != BUS_NOTIFY_BOUND_DRIVER) {
							if (od->_state == OMAP_DEVICE_STATE_ENABLED) {
								- omap_device_idle [ops - IP is disabled, ]
	- [fail]
	- pm_runtime_put_sync
          - omap_hsmmc_runtime_suspend [ooops!]

== log ==
 omap_hsmmc 480b4000.mmc: unable to get vmmc regulator -517
 davinci_mdio 48485000.mdio: davinci mdio revision 1.6
 davinci_mdio 48485000.mdio: detected phy mask fffffff3
 libphy: 48485000.mdio: probed
 davinci_mdio 48485000.mdio: phy[2]: device 48485000.mdio:02, driver unknown
 davinci_mdio 48485000.mdio: phy[3]: device 48485000.mdio:03, driver unknown
 omap_hsmmc 480b4000.mmc: unable to get vmmc regulator -517
 cpsw 48484000.ethernet: Detected MACID = b4:99:4c:c7:d2:48
 cpsw 48484000.ethernet: cpsw: Detected MACID = b4:99:4c:c7:d2:49
 hctosys: unable to open rtc device (rtc0)
 omap_hsmmc 480b4000.mmc: omap_device_late_idle: enabled but no driver.  Idling
 ldousb: disabling
 Unhandled fault: imprecise external abort (0x1406) at 0x00000000
 [00000000] *pgd=00000000
 Internal error: : 1406 [#1] PREEMPT SMP ARM
 Modules linked in:
 CPU: 1 PID: 58 Comm: kworker/u4:1 Not tainted 4.1.2-rt1-00467-g6da3c0a-dirty #5
 Hardware name: Generic DRA74X (Flattened Device Tree)
 Workqueue: deferwq deferred_probe_work_func
 task: ee6ddb00 ti: edd3c000 task.ti: edd3c000
 PC is at omap_hsmmc_runtime_suspend+0x1c/0x12c
 LR is at _od_runtime_suspend+0xc/0x24
 pc : [<c0471998>]    lr : [<c0029590>]    psr: a0000013
 sp : edd3dda0  ip : ee6ddb00  fp : c07be540
 r10: 00000000  r9 : c07be540  r8 : 00000008
 r7 : 00000000  r6 : ee646c10  r5 : ee646c10  r4 : edd79380
 r3 : fa0b4100  r2 : 00000000  r1 : 00000000  r0 : ee646c10
 Flags: NzCv  IRQs on  FIQs on  Mode SVC_32  ISA ARM  Segment kernel
 Control: 10c5387d  Table: 8000406a  DAC: 00000015
 Process kworker/u4:1 (pid: 58, stack limit = 0xedd3c218)
 Stack: (0xedd3dda0 to 0xedd3e000)
 dda0: ee646c70 ee646c10 c0029584 00000000 00000008 c0029590 ee646c70 ee646c10
 ddc0: c0029584 c03adfb8 ee646c10 00000004 0000000c c03adff0 ee646c10 00000004
 dde0: 0000000c c03ae4ec 00000000 edd3c000 ee646c10 00000004 ee646c70 00000004
 de00: fa0b4000 c03aec20 ee6ddb00 ee646c10 00000004 ee646c70 ee646c10 fffffdfb
 de20: edd79380 00000000 fa0b4000 c03aee90 fffffdfb edd79000 ee646c00 c0474290
 de40: 00000000 edda24c0 edd79380 edc81f00 00000000 00000200 00000001 c06dd488
 de60: edda3960 ee646c10 ee646c10 c0824cc4 fffffdfb c0880c94 00000002 edc92600
 de80: c0836378 c03a7f84 ee646c10 c0824cc4 00000000 c0880c80 c0880c94 c03a6568
 dea0: 00000000 ee646c10 c03a66ac ee4f8000 00000000 00000001 edc92600 c03a4b40
 dec0: ee404c94 edc83c4c ee646c10 ee646c10 ee646c44 c03a63c4 ee646c10 ee646c10
 dee0: c0814448 c03a5aa8 ee646c10 c0814220 edd3c000 c03a5ec0 c0814250 ee6be400
 df00: edd3c000 c004e5bc ee6ddb01 00000078 ee6ddb00 ee4f8000 ee6be418 edd3c000
 df20: ee4f8028 00000088 c0836045 ee4f8000 ee6be400 c004e928 ee4f8028 00000000
 df40: c004e8ec 00000000 ee6bf1c0 ee6be400 c004e8ec 00000000 00000000 00000000
 df60: 00000000 c0053450 2e56fa97 00000000 afdffbd7 ee6be400 00000000 00000000
 df80: edd3df80 edd3df80 00000000 00000000 edd3df90 edd3df90 edd3dfac ee6bf1c0
 dfa0: c0053384 00000000 00000000 c000f668 00000000 00000000 00000000 00000000
 dfc0: 00000000 00000000 00000000 00000000 00000000 00000000 00000000 00000000
 dfe0: 00000000 00000000 00000000 00000000 00000013 00000000 f1fc9d7e febfbdff
 [<c0471998>] (omap_hsmmc_runtime_suspend) from [<c0029590>] (_od_runtime_suspend+0xc/0x24)
 [<c0029590>] (_od_runtime_suspend) from [<c03adfb8>] (__rpm_callback+0x24/0x3c)
 [<c03adfb8>] (__rpm_callback) from [<c03adff0>] (rpm_callback+0x20/0x80)
 [<c03adff0>] (rpm_callback) from [<c03ae4ec>] (rpm_suspend+0xe4/0x618)
 [<c03ae4ec>] (rpm_suspend) from [<c03aee90>] (__pm_runtime_idle+0x60/0x80)
 [<c03aee90>] (__pm_runtime_idle) from [<c0474290>] (omap_hsmmc_probe+0x6bc/0xa7c)
 [<c0474290>] (omap_hsmmc_probe) from [<c03a7f84>] (platform_drv_probe+0x44/0xa4)
 [<c03a7f84>] (platform_drv_probe) from [<c03a6568>] (driver_probe_device+0x170/0x2b4)
 [<c03a6568>] (driver_probe_device) from [<c03a4b40>] (bus_for_each_drv+0x64/0x98)
 [<c03a4b40>] (bus_for_each_drv) from [<c03a63c4>] (device_attach+0x70/0x88)
 [<c03a63c4>] (device_attach) from [<c03a5aa8>] (bus_probe_device+0x84/0xac)
 [<c03a5aa8>] (bus_probe_device) from [<c03a5ec0>] (deferred_probe_work_func+0x58/0x88)
 [<c03a5ec0>] (deferred_probe_work_func) from [<c004e5bc>] (process_one_work+0x134/0x464)
 [<c004e5bc>] (process_one_work) from [<c004e928>] (worker_thread+0x3c/0x4fc)
 [<c004e928>] (worker_thread) from [<c0053450>] (kthread+0xcc/0xe4)
 [<c0053450>] (kthread) from [<c000f668>] (ret_from_fork+0x14/0x2c)
 Code: e594302c e593202c e584205c e594302c (e5932128)
 ---[ end trace 0000000000000002 ]---

Lets remove just remove omap_device_late_init completely as suggested
by Tero Kristo:

"How about remove omap_device_late_init call completely. I don't think
it does anything useful at the moment; none of the omap devices get
enabled outside runtime_pm, so there should be no need to explicitly
disable the devices."

Cc: Tero Kristo <t-kristo at ti.com>
Cc: Keerthy <j-keerthy at ti.com>
Signed-off-by: Grygorii Strashko <grygorii.strashko at ti.com>
---
Hi Tony,

Keerthy has reported that he can observe the same issue on -next.
Most probably it's related to new feature - "asynchronous probing support".

regards,
-grygorii 

 arch/arm/mach-omap2/omap_device.c | 52 ---------------------------------------
 1 file changed, 52 deletions(-)

diff --git a/arch/arm/mach-omap2/omap_device.c b/arch/arm/mach-omap2/omap_device.c
index 4cb8fd9..50c923e 100644
--- a/arch/arm/mach-omap2/omap_device.c
+++ b/arch/arm/mach-omap2/omap_device.c
@@ -870,55 +870,3 @@ static int __init omap_device_init(void)
 	return 0;
 }
 omap_core_initcall(omap_device_init);
-
-/**
- * omap_device_late_idle - idle devices without drivers
- * @dev: struct device * associated with omap_device
- * @data: unused
- *
- * Check the driver bound status of this device, and idle it
- * if there is no driver attached.
- */
-static int __init omap_device_late_idle(struct device *dev, void *data)
-{
-	struct platform_device *pdev = to_platform_device(dev);
-	struct omap_device *od = to_omap_device(pdev);
-	int i;
-
-	if (!od)
-		return 0;
-
-	/*
-	 * If omap_device state is enabled, but has no driver bound,
-	 * idle it.
-	 */
-
-	/*
-	 * Some devices (like memory controllers) are always kept
-	 * enabled, and should not be idled even with no drivers.
-	 */
-	for (i = 0; i < od->hwmods_cnt; i++)
-		if (od->hwmods[i]->flags & HWMOD_INIT_NO_IDLE)
-			return 0;
-
-	if (od->_driver_status != BUS_NOTIFY_BOUND_DRIVER) {
-		if (od->_state == OMAP_DEVICE_STATE_ENABLED) {
-			dev_warn(dev, "%s: enabled but no driver.  Idling\n",
-				 __func__);
-			omap_device_idle(pdev);
-		}
-	}
-
-	return 0;
-}
-
-static int __init omap_device_late_init(void)
-{
-	bus_for_each_dev(&platform_bus_type, NULL, NULL, omap_device_late_idle);
-
-	WARN(!of_have_populated_dt(),
-		"legacy booting deprecated, please update to boot with .dts\n");
-
-	return 0;
-}
-omap_late_initcall_sync(omap_device_late_init);
-- 
2.5.0



From tony at atomide.com  Wed Aug 26 11:10:06 2015
From: tony at atomide.com (Tony Lindgren)
Date: Wed, 26 Aug 2015 11:10:06 -0700
Subject: [PATCH] ARM: OMAP2+: omap-device: remove omap_device_late_init
 call completely
In-Reply-To: <1440611890-4935-1-git-send-email-grygorii.strashko@ti.com>
References: <1440611890-4935-1-git-send-email-grygorii.strashko@ti.com>
Message-ID: <20150826181006.GT4215@atomide.com>

* Grygorii Strashko <grygorii.strashko at ti.com> [150826 11:01]:
> Now Kernel fails to boot 50% of times (form build to build) with
> RT-patchset applied due to the following race - on late boot
> stages deferred_probe_work_func races with omap_device_late_ini
> 
> late_initcall
>  - deferred_probe_initcal() tries to re-probe all pending driver's probe.
>    [In general, It's NOT expected to probe any other built-in drivers after
>    deferred_probe_initcal() is finished, because most of
>    late_initcall_sync/late_initcall functions expected that all driver
>    or probed or deferred already.]
> 
> - later on, some driver is probing in this case It's could cpsw.c
>   (but could be any other drivers)
>   cpsw_init
>   - platform_driver_register
>     - really_probe
>        - driver_bound
>          - driver_deferred_probe_trigger
>   and boot proceed.
>   So, at this moment we have  deferred_probe_work_func scheduled.
> 
> late_initcall_sync
>   - omap_device_late_init
>     - omap_device_idle
> 
> CPU1					CPU2
>   - deferred_probe_work_func
>     - really_probe
>       - omap_hsmmc_probe
> 	- pm_runtime_get_sync
> 					late_initcall_sync
> 					- omap_device_late_init
> 						if (od->_driver_status != BUS_NOTIFY_BOUND_DRIVER) {
> 							if (od->_state == OMAP_DEVICE_STATE_ENABLED) {
> 								- omap_device_idle [ops - IP is disabled, ]
> 	- [fail]
> 	- pm_runtime_put_sync
>           - omap_hsmmc_runtime_suspend [ooops!]

OK idling of unclaimed devices should not happen for deferred probe,
it should only happen when there's no driver and no probing happening. 
 
> Lets remove just remove omap_device_late_init completely as suggested
> by Tero Kristo:
> 
> "How about remove omap_device_late_init call completely. I don't think
> it does anything useful at the moment; none of the omap devices get
> enabled outside runtime_pm, so there should be no need to explicitly
> disable the devices."

I think this is still needed from PM point of view as otherwise we
don't idle any devices that don't have a driver available. Or am I
missing something?

To me it seems the bug is relying on the BUS_NOTIFY_BOUND_DRIVER is
not set in the deferred probe case.

Regards,

Tony


From agross at codeaurora.org  Wed Aug 26 11:14:10 2015
From: agross at codeaurora.org (Andy Gross)
Date: Wed, 26 Aug 2015 13:14:10 -0500
Subject: [PATCH] soc: qcom: smd: Use correct remote processor ID
In-Reply-To: <20150826034622.GH13472@usrtlx11787.corpusers.net>
References: <1440534995-12899-1-git-send-email-agross@codeaurora.org>
 <20150826034622.GH13472@usrtlx11787.corpusers.net>
Message-ID: <20150826181410.GC13139@qualcomm.com>

On Tue, Aug 25, 2015 at 08:46:22PM -0700, Bjorn Andersson wrote:
> On Tue 25 Aug 13:36 PDT 2015, Andy Gross wrote:
> 
> > This patch fixes SMEM addressing issues when remote processors need to use
> > secure SMEM partitions.
> > 
> 
> Right, sorry for missing that remote_pid and edge_pid isn't in sync...
> 
> > Signed-off-by: Andy Gross <agross at codeaurora.org>
> > ---
> >  .../devicetree/bindings/soc/qcom/qcom,smd.txt      |    7 +++++++
> >  drivers/soc/qcom/smd.c                             |   18 ++++++++++++++----
> >  2 files changed, 21 insertions(+), 4 deletions(-)
> > 
> > diff --git a/Documentation/devicetree/bindings/soc/qcom/qcom,smd.txt b/Documentation/devicetree/bindings/soc/qcom/qcom,smd.txt
> > index f65c76d..3b60702 100644
> > --- a/Documentation/devicetree/bindings/soc/qcom/qcom,smd.txt
> > +++ b/Documentation/devicetree/bindings/soc/qcom/qcom,smd.txt
> > @@ -37,6 +37,12 @@ The edge is described by the following properties:
> >  	Definition: the identifier of the remote processor in the smd channel
> >  		    allocation table
> >  
> > +- qcom,remote-pid:
> > +	Usage: required
> 
> I would like to see this being optional, as this is not a property that
> matters on any of the 32-bit systems (perhaps 8084?).

I thought about that myself, and yeah I have to agree.

> 
> > +	Value type: <u32>
> > +	Definition: the identifier for the remote processor as known by the rest
> > +		    of the system.
> > +
> >  = SMD DEVICES
> >  
> >  In turn, subnodes of the "edges" represent devices tied to SMD channels on that
> > @@ -68,6 +74,7 @@ The following example represents a smd node, with one edge representing the
> >  			interrupts = <0 168 1>;
> >  			qcom,ipc = <&apcs 8 0>;
> >  			qcom,smd-edge = <15>;
> > +			qcom,remote-pid = <0xffffffff>;
> 
> This looks messy, so let's make the property optional and make its
> absence indicate the "global partition".
> 
> >  
> >  			rpm_requests {
> >  				compatible = "qcom,rpm-msm8974";
> > diff --git a/drivers/soc/qcom/smd.c b/drivers/soc/qcom/smd.c
> [..]
> > @@ -1184,6 +1187,13 @@ static int qcom_smd_parse_edge(struct device *dev,
> >  		return -EINVAL;
> >  	}
> >  
> > +	key = "qcom,remote-pid";
> > +	ret = of_property_read_u32(node, key, &edge->remote_pid);
> > +	if (ret) {
> > +		dev_err(dev, "edge missing %s property\n", key);
> > +		return -EINVAL;
> > +	}
> > +
> 
> So I suggest you changing this to:
> 
> edge->remote_pid = QCOM_SMEM_HOST_ANY;
> of_property_read_u32(node, "qcom,remote-pid", &edge->remote_pid);

Agreed.

> 
> >  	syscon_np = of_parse_phandle(node, "qcom,ipc", 0);
> >  	if (!syscon_np) {
> >  		dev_err(dev, "no qcom,ipc node\n");
> 
> Regards,
> Bjorn

-- 
Qualcomm Innovation Center, Inc.
The Qualcomm Innovation Center, Inc. is a member of the Code Aurora Forum,
a Linux Foundation Collaborative Project



From sbranden at broadcom.com  Wed Aug 26 11:20:59 2015
From: sbranden at broadcom.com (Scott Branden)
Date: Wed, 26 Aug 2015 11:20:59 -0700
Subject: [PATCH 5/5] MAINTAINERS: add entry for the Broadcom Northstar
 Plus SoCs
In-Reply-To: <CAOesGMioBQY9qy-S8kMJmo_=B6-KZiUkd=Ns1Uo2dGu0BiqppQ@mail.gmail.com>
References: <1440092861-25825-1-git-send-email-jonmason@broadcom.com>
 <CAOesGMioBQY9qy-S8kMJmo_=B6-KZiUkd=Ns1Uo2dGu0BiqppQ@mail.gmail.com>
Message-ID: <55DE038B.1060908@broadcom.com>

On 15-08-25 04:42 PM, Olof Johansson wrote:
> On Thu, Aug 20, 2015 at 10:47 AM, Jon Mason <jonmason at broadcom.com> wrote:
>> Modify the iProc MAINTAINER to cover the Nortstar Plus SoCs, and add me
>> to the list of people responsible for it.
>
> That's not what this patch does. It removes CYGNUS from the
> description as well. Hmm?
>
> I'm also not a fan of the complex patterns, but that's more of a
> bikeshedding comment. Does Broadcom really not have a bit more
> systematic naming than this? :)
>
>> Signed-off-by: Jon Mason <jonmason at broadcom.com>
>> Reviewed-by: Scott Branden <sbranden at broadcom.com>
Acked-by: Scott Branden <sbranden at broadcom.com>

>
> For maintainer updates, we usuallu like to see a public ack of this
> and not just a pre-acked patch. You _could_ have added it yourself
> without Scott's actual approval, after all.
>
>
> -Olof
>



From ard.biesheuvel at linaro.org  Wed Aug 26 11:29:27 2015
From: ard.biesheuvel at linaro.org (Ard Biesheuvel)
Date: Wed, 26 Aug 2015 20:29:27 +0200
Subject: [PATCH 2/3] arm64: use core efi=debug instead of uefi_debug
 command line parameter
In-Reply-To: <20150826173000.GG10728@bivouac.eciton.net>
References: <1440595498-30630-1-git-send-email-leif.lindholm@linaro.org>
 <1440595498-30630-3-git-send-email-leif.lindholm@linaro.org>
 <20150826172455.GB2837@codeblueprint.co.uk>
 <20150826173000.GG10728@bivouac.eciton.net>
Message-ID: <CAKv+Gu8vkHaqkOrJpiQweczj1zzNh4sGfM4ySFJ7qiwDM5u_4A@mail.gmail.com>

On 26 August 2015 at 19:30, Leif Lindholm <leif.lindholm at linaro.org> wrote:
> On Wed, Aug 26, 2015 at 06:24:55PM +0100, Matt Fleming wrote:
>> On Wed, 26 Aug, at 02:24:57PM, Leif Lindholm wrote:
>> > Now that we have an efi=debug command line option in the core code, use
>> > this instead of the arm64-specific uefi_debug option.
>> >
>> > Signed-off-by: Leif Lindholm <leif.lindholm at linaro.org>
>> > ---
>> >  Documentation/arm/uefi.txt |  2 --
>> >  arch/arm64/kernel/efi.c    | 19 +++++--------------
>> >  2 files changed, 5 insertions(+), 16 deletions(-)
>>
>> Are there no concerns with backwards-compatibility here? I expected
>> this patch to internally convert uefi_debug to efi=debug if old boot
>> loaders, kernel config, etc specify it.
>>
>> Is that something that can be safely ignored?
>
> Since it is purely a debug feature, I opted to just drop it.
> I don't have strong feelings, and it could certainly be kept as an
> arm64-only alias (but setting the EFI_DBG flag) if others disagree.
>

Let's not bother. This is strictly a debug option that only affects
what gets printed to the kernel log, which itself is not (or should
not be) an ABI. Also, if anyone cares deeply about always having the
feature enabled both on before and after kernels, they can always pass
both options.

-- 
Ard.


From jonmason at broadcom.com  Wed Aug 26 11:40:10 2015
From: jonmason at broadcom.com (Jon Mason)
Date: Wed, 26 Aug 2015 14:40:10 -0400
Subject: [PATCH 2/5] ARM: NSP: add minimal Northstar Plus device tree
In-Reply-To: <CAOesGMhE40_mfZCD2PqcTObE_Gz_6rKFwhf3-6kZY4n9Yxn2rQ@mail.gmail.com>
References: <1440092804-25726-1-git-send-email-jonmason@broadcom.com>
 <CAOesGMhE40_mfZCD2PqcTObE_Gz_6rKFwhf3-6kZY4n9Yxn2rQ@mail.gmail.com>
Message-ID: <20150826184009.GA4171@broadcom.com>

On Tue, Aug 25, 2015 at 04:36:45PM -0700, Olof Johansson wrote:
> Hi,
> 
> I'm not sure what the strategy behind your cc:ing on this patch set
> is. I only got a couple of them in my inbox, and this one wasn't one
> of them. :)

I sent them to the people listed as maintainers in get_maintainer.pl.
It didn't seem to include you in all of them, but I thought the
mailing list would be enough of a catch all.  My apologies.  I'll CC
everyone listed as a maintainer on all of the patches in the future.

> 
> On Thu, Aug 20, 2015 at 10:46 AM, Jon Mason <jonmason at broadcom.com> wrote:
> > Add a very minimalistic set of Northstar Plus Device Tree files which
> > describes the SoC and the BCM958625 implementation.  The perpherials
> > described are:
> >
> > ARM Cortex A9 CPU
> > 2 8250 UARTs
> > ARM GIC
> > PL310 L2 Cache
> > ARM A9 Global timer
> >
> > Signed-off-by: Jon Mason <jonmason at broadcom.com>
> > Signed-off-by: Kapil Hali <kapilh at broadcom.com>
> > Reviewed-by: Ray Jui <rjui at broadcom.com>
> > Reviewed-by: Scott Branden <sbranden at broadcom.com>
> 
> Seeing reviewed-by already attached to a v1 of a patchset has limited
> value for someone on the outside.
> 
> Reviewed-by is one of those tags that has a value that's mostly
> dependent on who it comes from. By not actually seeing the review and
> the feedback provided (and revisions made), less data is provided to
> tell if it's a valuable review or not.
> 
> Also, if you're posting the code you should probably have your name
> below Kapil's, since you're the one signing off the origin of the
> code. See Documentation/SubmittingPatches.txt for details on what
> S-o-b actually means.

We worked on it together, but I'll be happy to reorder as you suggest.

> 
> 
> > --- /dev/null
> > +++ b/arch/arm/boot/dts/bcm-nsp.dtsi
> > @@ -0,0 +1,105 @@
> > +/*
> > + *  BSD LICENSE
> > + *
> > + *  Copyright(c) 2015 Broadcom Corporation.  All rights reserved.
> > + *
> > + *  Redistribution and use in source and binary forms, with or without
> > + *  modification, are permitted provided that the following conditions
> > + *  are met:
> > + *
> > + *    * Redistributions of source code must retain the above copyright
> > + *      notice, this list of conditions and the following disclaimer.
> > + *    * Redistributions in binary form must reproduce the above copyright
> > + *      notice, this list of conditions and the following disclaimer in
> > + *      the documentation and/or other materials provided with the
> > + *      distribution.
> > + *    * Neither the name of Broadcom Corporation nor the names of its
> > + *      contributors may be used to endorse or promote products derived
> > + *      from this software without specific prior written permission.
> > + *
> > + *  THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
> > + *  "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
> > + *  LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
> > + *  A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
> > + *  OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
> > + *  SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
> > + *  LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
> > + *  DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
> > + *  THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
> > + *  (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
> > + *  OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
> > + */
> 
> I'm not sure we've seen BSD-only submissions before. I'll let DT
> maintainers (or Ian) speak up in case this would cause problems.

I was following the precedent in arch/arm/boot/dts/bcm-cygnus.dtsi.
If this is preferred to be GPL v2, then I will happily comply.

> 
> 
> > +
> > +#include <dt-bindings/interrupt-controller/arm-gic.h>
> > +#include <dt-bindings/interrupt-controller/irq.h>
> > +
> > +#include "skeleton.dtsi"
> > +
> > +/ {
> > +       compatible = "brcm,nsp";
> > +       model = "Broadcom Northstar Plus SoC";
> > +       interrupt-parent = <&gic>;
> > +
> > +       cpus {
> > +               #address-cells = <1>;
> > +               #size-cells = <0>;
> > +
> > +               cpu at 0 {
> > +                       device_type = "cpu";
> > +                       compatible = "arm,cortex-a9";
> > +                       next-level-cache = <&L2>;
> > +                       reg = <0x0>;
> > +               };
> > +       };
> > +
> > +       clocks {
> > +               #address-cells = <1>;
> > +               #size-cells = <1>;
> > +               ranges;
> > +
> > +               periph_clk: periph_clk {
> > +                       compatible = "fixed-clock";
> > +                       #clock-cells = <0>;
> > +                       clock-frequency = <500000000>;
> > +               };
> > +       };
> > +
> > +       uart0: serial at 18000300 {
> > +               compatible = "ns16550a";
> > +               reg = <0x18000300 0x100>;
> > +               interrupts = <GIC_SPI 85 IRQ_TYPE_LEVEL_HIGH>;
> > +               clock-frequency = <62499840>;
> > +               status = "disabled";
> > +       };
> > +
> > +       uart1: serial at 18000400 {
> > +               compatible = "ns16550a";
> > +               reg = <0x18000400 0x100>;
> > +               interrupts = <GIC_SPI 85 IRQ_TYPE_LEVEL_HIGH>;
> > +               clock-frequency = <62499840>;
> > +               status = "disabled";
> > +       };
> > +
> > +       gic: interrupt-controller at 19021000 {
> > +               compatible = "arm,cortex-a9-gic";
> > +               #interrupt-cells = <3>;
> > +               #address-cells = <0>;
> > +               interrupt-controller;
> > +               reg = <0x19021000 0x1000>,
> > +                     <0x19020100 0x100>;
> > +       };
> > +
> > +       L2: l2-cache {
> > +               compatible = "arm,pl310-cache";
> > +               reg = <0x19022000 0x1000>;
> > +               cache-unified;
> > +               cache-level = <2>;
> > +       };
> > +
> > +       timer at 19020200 {
> > +               compatible = "arm,cortex-a9-global-timer";
> > +               reg = <0x19020200 0x100>;
> > +               interrupts = <GIC_PPI 11 IRQ_TYPE_LEVEL_HIGH>;
> > +               clocks = <&periph_clk>;
> > +       };
> > +};
> > diff --git a/arch/arm/boot/dts/bcm958625k.dts b/arch/arm/boot/dts/bcm958625k.dts
> > new file mode 100644
> > index 0000000..a1bc151
> > --- /dev/null
> > +++ b/arch/arm/boot/dts/bcm958625k.dts
> > @@ -0,0 +1,57 @@
> > +/*
> > + *  BSD LICENSE
> > + *
> > + *  Copyright(c) 2015 Broadcom Corporation.  All rights reserved.
> > + *
> > + *  Redistribution and use in source and binary forms, with or without
> > + *  modification, are permitted provided that the following conditions
> > + *  are met:
> > + *
> > + *    * Redistributions of source code must retain the above copyright
> > + *      notice, this list of conditions and the following disclaimer.
> > + *    * Redistributions in binary form must reproduce the above copyright
> > + *      notice, this list of conditions and the following disclaimer in
> > + *      the documentation and/or other materials provided with the
> > + *      distribution.
> > + *    * Neither the name of Broadcom Corporation nor the names of its
> > + *      contributors may be used to endorse or promote products derived
> > + *      from this software without specific prior written permission.
> > + *
> > + *  THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
> > + *  "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
> > + *  LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
> > + *  A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
> > + *  OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
> > + *  SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
> > + *  LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
> > + *  DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
> > + *  THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
> > + *  (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
> > + *  OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
> > + */
> > +
> > +/dts-v1/;
> > +
> > +#include "bcm-nsp.dtsi"
> > +
> > +/ {
> > +       model = "NorthStar Plus SVK (BCM958625K)";
> > +       compatible = "brcm,bcm58625", "brcm,nsp";
> > +
> > +       aliases {
> > +               serial0 = &uart0;
> > +               serial1 = &uart1;
> > +       };
> > +
> > +       chosen {
> > +               stdout-path = "serial0:115200n8";
> > +       };
> 
> No way to mount a root filesystem yet? How much work remains for that
> to be possible, and what's the plan for that?

It mounts rootfs.  I am adding the rootfs to the kernel and device
tree blob via the u-boot mkimage command.  It boots all the way to
shell without issue.

> 
> > +
> > +       uart0: serial at 18000300 {
> > +               status = "okay";
> > +       };
> > +
> > +       uart1: serial at 18000400 {
> > +               status = "okay";
> > +       };
> 
> I recommend using labels here instead so you don't have to mirror the
> DT layout to get the updated property right.

Agreed.

Thanks,
Jon

> 
> I.e.
> 
> &uart1 {
>         status = "okay";
> };
> 
> 
> 
> -Olof


From codekipper at gmail.com  Wed Aug 26 11:46:58 2015
From: codekipper at gmail.com (codekipper at gmail.com)
Date: Wed, 26 Aug 2015 20:46:58 +0200
Subject: [linux-next][PATCH v2] ARM: sun7i: dt: Add new Olimex A20 EVB device
Message-ID: <1440614818-25765-1-git-send-email-codekipper@gmail.com>

From: Marcus Cooper <codekipper at gmail.com>

The A20-SOM-EVB is a reference design of a 2-layer board for the
A20-SOM.
It expands the features of A20-SOM by adding VGA connector, HDMI
connector, audio In/Out, LCD connector, 2 Mpix camera, gigabit
Ethernet, SATA, USB-OTG and 2 USB hosts.

This patch adds basic support for the device
https://www.olimex.com/Products/SOM/A20/A20-SOM-EVB/

More information on the SOM can be found here
http://linux-sunxi.org/Olimex_A20-SOM.

Signed-off-by: Marcus Cooper <codekipper at gmail.com>
---
Changes since v1:
- renamed dts from sun7i-a20-olinuxino-evb to sun7i-a20-olimex-som-evb
- added "axp209 dtsi"
- change regulator settings
---
 arch/arm/boot/dts/Makefile                     |   1 +
 arch/arm/boot/dts/sun7i-a20-olimex-som-evb.dts | 216 +++++++++++++++++++++++++
 2 files changed, 217 insertions(+)
 create mode 100644 arch/arm/boot/dts/sun7i-a20-olimex-som-evb.dts

diff --git a/arch/arm/boot/dts/Makefile b/arch/arm/boot/dts/Makefile
index f830e1f..e4e1d29 100644
--- a/arch/arm/boot/dts/Makefile
+++ b/arch/arm/boot/dts/Makefile
@@ -588,6 +588,7 @@ dtb-$(CONFIG_MACH_SUN7I) += \
 	sun7i-a20-i12-tvbox.dtb \
 	sun7i-a20-m3.dtb \
 	sun7i-a20-mk808c.dtb \
+	sun7i-a20-olimex-som-evb.dtb \
 	sun7i-a20-olinuxino-lime.dtb \
 	sun7i-a20-olinuxino-lime2.dtb \
 	sun7i-a20-olinuxino-micro.dtb \
diff --git a/arch/arm/boot/dts/sun7i-a20-olimex-som-evb.dts b/arch/arm/boot/dts/sun7i-a20-olimex-som-evb.dts
new file mode 100644
index 0000000..36d1e77
--- /dev/null
+++ b/arch/arm/boot/dts/sun7i-a20-olimex-som-evb.dts
@@ -0,0 +1,216 @@
+/*
+ * Copyright 2015 - Marcus Cooper <codekipper at gmail.com>
+ *
+ * This file is dual-licensed: you can use it either under the terms
+ * of the GPL or the X11 license, at your option. Note that this dual
+ * licensing only applies to this file, and not this project as a
+ * whole.
+ *
+ *  a) This file is free software; you can redistribute it and/or
+ *     modify it under the terms of the GNU General Public License as
+ *     published by the Free Software Foundation; either version 2 of the
+ *     License, or (at your option) any later version.
+ *
+ *     This file is distributed in the hope that it will be useful,
+ *     but WITHOUT ANY WARRANTY; without even the implied warranty of
+ *     MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ *     GNU General Public License for more details.
+ *
+ * Or, alternatively,
+ *
+ *  b) Permission is hereby granted, free of charge, to any person
+ *     obtaining a copy of this software and associated documentation
+ *     files (the "Software"), to deal in the Software without
+ *     restriction, including without limitation the rights to use,
+ *     copy, modify, merge, publish, distribute, sublicense, and/or
+ *     sell copies of the Software, and to permit persons to whom the
+ *     Software is furnished to do so, subject to the following
+ *     conditions:
+ *
+ *     The above copyright notice and this permission notice shall be
+ *     included in all copies or substantial portions of the Software.
+ *
+ *     THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
+ *     EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES
+ *     OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
+ *     NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT
+ *     HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY,
+ *     WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
+ *     FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR
+ *     OTHER DEALINGS IN THE SOFTWARE.
+ */
+
+/dts-v1/;
+#include "sun7i-a20.dtsi"
+#include "sunxi-common-regulators.dtsi"
+
+#include <dt-bindings/gpio/gpio.h>
+#include <dt-bindings/interrupt-controller/irq.h>
+#include <dt-bindings/pinctrl/sun4i-a10.h>
+
+/ {
+	model = "Olimex A20-Olimex-SOM-EVB";
+	compatible = "olimex,a20-olimex-som-evb", "allwinner,sun7i-a20";
+
+	aliases {
+		serial0 = &uart0;
+	};
+
+	chosen {
+		stdout-path = "serial0:115200n8";
+	};
+
+	leds {
+		compatible = "gpio-leds";
+		pinctrl-names = "default";
+		pinctrl-0 = <&led_pins_olimex_som_evb>;
+
+		green {
+			label = "a20-olimex-som-evb:green:usr";
+			gpios = <&pio 7 2 GPIO_ACTIVE_HIGH>;
+			default-state = "on";
+		};
+	};
+
+	reg_axp_ipsout: axp_ipsout {
+		compatible = "regulator-fixed";
+		regulator-name = "axp-ipsout";
+		regulator-min-microvolt = <5000000>;
+		regulator-max-microvolt = <5000000>;
+		regulator-always-on;
+	};
+};
+
+&ahci {
+	target-supply = <&reg_ahci_5v>;
+	status = "okay";
+};
+
+&ehci0 {
+	status = "okay";
+};
+
+&ehci1 {
+	status = "okay";
+};
+
+&gmac {
+	pinctrl-names = "default";
+	pinctrl-0 = <&gmac_pins_rgmii_a>;
+	phy = <&phy1>;
+	phy-mode = "rgmii";
+	status = "okay";
+
+	phy1: ethernet-phy at 1 {
+		reg = <1>;
+	};
+};
+
+&i2c0 {
+	pinctrl-names = "default";
+	pinctrl-0 = <&i2c0_pins_a>;
+	status = "okay";
+
+	axp209: pmic at 34 {
+		reg = <0x34>;
+		interrupt-parent = <&nmi_intc>;
+		interrupts = <0 IRQ_TYPE_LEVEL_LOW>;
+	};
+};
+
+&i2c1 {
+	pinctrl-names = "default";
+	pinctrl-0 = <&i2c1_pins_a>;
+	status = "okay";
+};
+
+&mmc0 {
+	pinctrl-names = "default";
+	pinctrl-0 = <&mmc0_pins_a>, <&mmc0_cd_pin_reference_design>;
+	vmmc-supply = <&reg_vcc3v3>;
+	bus-width = <4>;
+	cd-gpios = <&pio 7 1 GPIO_ACTIVE_HIGH>; /* PH1 */
+	cd-inverted;
+	status = "okay";
+};
+
+&ohci0 {
+	status = "okay";
+};
+
+&ohci1 {
+	status = "okay";
+};
+
+&pio {
+	ahci_pwr_pin_olimex_som_evb: ahci_pwr_pin at 1 {
+		allwinner,pins = "PC3";
+		allwinner,function = "gpio_out";
+		allwinner,drive = <SUN4I_PINCTRL_10_MA>;
+		allwinner,pull = <SUN4I_PINCTRL_NO_PULL>;
+	};
+
+	led_pins_olimex_som_evb: led_pins at 0 {
+		allwinner,pins = "PH2";
+		allwinner,function = "gpio_out";
+		allwinner,drive = <SUN4I_PINCTRL_20_MA>;
+		allwinner,pull = <SUN4I_PINCTRL_NO_PULL>;
+	};
+};
+
+&reg_ahci_5v {
+	pinctrl-0 = <&ahci_pwr_pin_olimex_som_evb>;
+	gpio = <&pio 2 3 GPIO_ACTIVE_HIGH>;
+	status = "okay";
+};
+
+#include "axp209.dtsi"
+
+&reg_dcdc2 {
+	regulator-always-on;
+	regulator-min-microvolt = <1000000>;
+	regulator-max-microvolt = <1425000>;
+	regulator-name = "vdd-cpu";
+};
+
+&reg_dcdc3 {
+	regulator-always-on;
+	regulator-min-microvolt = <1000000>;
+	regulator-max-microvolt = <1400000>;
+	regulator-name = "vdd-int-dll";
+};
+
+&reg_ldo1 {
+	regulator-name = "vdd-rtc";
+};
+
+&reg_ldo2 {
+	regulator-always-on;
+	regulator-min-microvolt = <3000000>;
+	regulator-max-microvolt = <3000000>;
+	regulator-name = "avcc";
+};
+
+&reg_usb0_vbus {
+	status = "okay";
+};
+
+&reg_usb1_vbus {
+	status = "okay";
+};
+
+&reg_usb2_vbus {
+	status = "okay";
+};
+
+&uart0 {
+	pinctrl-names = "default";
+	pinctrl-0 = <&uart0_pins_a>;
+	status = "okay";
+};
+
+&usbphy {
+	usb1_vbus-supply = <&reg_usb1_vbus>;
+	usb2_vbus-supply = <&reg_usb2_vbus>;
+	status = "okay";
+};
-- 
2.5.0



From isubramanian at apm.com  Wed Aug 26 11:48:04 2015
From: isubramanian at apm.com (Iyappan Subramanian)
Date: Wed, 26 Aug 2015 11:48:04 -0700
Subject: [PATCH v2 0/2] drivers: net: xgene: Add TSO support
Message-ID: <1440614886-23566-1-git-send-email-isubramanian@apm.com>

Adding TSO support for 10GbE

iperf Tx data rate without TSO: 3.42 Gbps
                      with TSO: 9.41 Gbps

v2: Address review comments from v1
    - skb_linearize() if headers doesn't fit in 3 hardware buffers

v1:
* Initial version

Signed-off-by: Iyappan Subramanian <isubramanian at apm.com>
---

Iyappan Subramanian (2):
  drivers: net: xgene: Preparatory patch for TSO support
  drivers: net: xgene: Adding support for TSO

 drivers/net/ethernet/apm/xgene/xgene_enet_hw.h    |  16 +-
 drivers/net/ethernet/apm/xgene/xgene_enet_main.c  | 274 +++++++++++++++++++---
 drivers/net/ethernet/apm/xgene/xgene_enet_main.h  |  12 +
 drivers/net/ethernet/apm/xgene/xgene_enet_xgmac.c |   8 +-
 drivers/net/ethernet/apm/xgene/xgene_enet_xgmac.h |   2 +
 5 files changed, 283 insertions(+), 29 deletions(-)

-- 
1.9.1



From isubramanian at apm.com  Wed Aug 26 11:48:05 2015
From: isubramanian at apm.com (Iyappan Subramanian)
Date: Wed, 26 Aug 2015 11:48:05 -0700
Subject: [PATCH v2 1/2] drivers: net: xgene: Preparatory patch for TSO support
In-Reply-To: <1440614886-23566-1-git-send-email-isubramanian@apm.com>
References: <1440614886-23566-1-git-send-email-isubramanian@apm.com>
Message-ID: <1440614886-23566-2-git-send-email-isubramanian@apm.com>

- Rearranged descriptor writes
- Moved increment command write to xgene_enet_setup_tx_desc

Signed-off-by: Iyappan Subramanian <isubramanian at apm.com>
---
 drivers/net/ethernet/apm/xgene/xgene_enet_main.c | 29 ++++++++++++++++++------
 drivers/net/ethernet/apm/xgene/xgene_enet_main.h |  1 +
 2 files changed, 23 insertions(+), 7 deletions(-)

diff --git a/drivers/net/ethernet/apm/xgene/xgene_enet_main.c b/drivers/net/ethernet/apm/xgene/xgene_enet_main.c
index 4f68d19..652b4c3 100644
--- a/drivers/net/ethernet/apm/xgene/xgene_enet_main.c
+++ b/drivers/net/ethernet/apm/xgene/xgene_enet_main.c
@@ -219,6 +219,11 @@ out:
 	return hopinfo;
 }
 
+static u16 xgene_enet_encode_len(u16 len)
+{
+	return (len == BUFLEN_16K) ? 0 : len;
+}
+
 static int xgene_enet_setup_tx_desc(struct xgene_enet_desc_ring *tx_ring,
 				    struct sk_buff *skb)
 {
@@ -227,27 +232,36 @@ static int xgene_enet_setup_tx_desc(struct xgene_enet_desc_ring *tx_ring,
 	dma_addr_t dma_addr;
 	u16 tail = tx_ring->tail;
 	u64 hopinfo;
+	u32 len, hw_len;
+	u8 count = 1;
 
 	raw_desc = &tx_ring->raw_desc[tail];
 	memset(raw_desc, 0, sizeof(struct xgene_enet_raw_desc));
 
-	dma_addr = dma_map_single(dev, skb->data, skb->len, DMA_TO_DEVICE);
+	len = skb_headlen(skb);
+	hw_len = xgene_enet_encode_len(len);
+
+	dma_addr = dma_map_single(dev, skb->data, len, DMA_TO_DEVICE);
 	if (dma_mapping_error(dev, dma_addr)) {
 		netdev_err(tx_ring->ndev, "DMA mapping error\n");
 		return -EINVAL;
 	}
 
 	/* Hardware expects descriptor in little endian format */
-	raw_desc->m0 = cpu_to_le64(tail);
 	raw_desc->m1 = cpu_to_le64(SET_VAL(DATAADDR, dma_addr) |
-				   SET_VAL(BUFDATALEN, skb->len) |
+				   SET_VAL(BUFDATALEN, hw_len) |
 				   SET_BIT(COHERENT));
+
+	raw_desc->m0 = cpu_to_le64(SET_VAL(USERINFO, tail));
 	hopinfo = xgene_enet_work_msg(skb);
 	raw_desc->m3 = cpu_to_le64(SET_VAL(HENQNUM, tx_ring->dst_ring_num) |
 				   hopinfo);
 	tx_ring->cp_ring->cp_skb[tail] = skb;
 
-	return 0;
+	tail = (tail + 1) & (tx_ring->slots - 1);
+	tx_ring->tail = tail;
+
+	return count;
 }
 
 static netdev_tx_t xgene_enet_start_xmit(struct sk_buff *skb,
@@ -257,6 +271,7 @@ static netdev_tx_t xgene_enet_start_xmit(struct sk_buff *skb,
 	struct xgene_enet_desc_ring *tx_ring = pdata->tx_ring;
 	struct xgene_enet_desc_ring *cp_ring = tx_ring->cp_ring;
 	u32 tx_level, cq_level;
+	int count;
 
 	tx_level = pdata->ring_ops->len(tx_ring);
 	cq_level = pdata->ring_ops->len(cp_ring);
@@ -266,14 +281,14 @@ static netdev_tx_t xgene_enet_start_xmit(struct sk_buff *skb,
 		return NETDEV_TX_BUSY;
 	}
 
-	if (xgene_enet_setup_tx_desc(tx_ring, skb)) {
+	count = xgene_enet_setup_tx_desc(tx_ring, skb);
+	if (count <= 0) {
 		dev_kfree_skb_any(skb);
 		return NETDEV_TX_OK;
 	}
 
-	pdata->ring_ops->wr_cmd(tx_ring, 1);
+	pdata->ring_ops->wr_cmd(tx_ring, count);
 	skb_tx_timestamp(skb);
-	tx_ring->tail = (tx_ring->tail + 1) & (tx_ring->slots - 1);
 
 	pdata->stats.tx_packets++;
 	pdata->stats.tx_bytes += skb->len;
diff --git a/drivers/net/ethernet/apm/xgene/xgene_enet_main.h b/drivers/net/ethernet/apm/xgene/xgene_enet_main.h
index 1c85fc8..2ac547e 100644
--- a/drivers/net/ethernet/apm/xgene/xgene_enet_main.h
+++ b/drivers/net/ethernet/apm/xgene/xgene_enet_main.h
@@ -40,6 +40,7 @@
 #define XGENE_DRV_VERSION	"v1.0"
 #define XGENE_ENET_MAX_MTU	1536
 #define SKB_BUFFER_SIZE		(XGENE_ENET_MAX_MTU - NET_IP_ALIGN)
+#define BUFLEN_16K	(16 * 1024)
 #define NUM_PKT_BUF	64
 #define NUM_BUFPOOL	32
 
-- 
1.9.1



From isubramanian at apm.com  Wed Aug 26 11:48:06 2015
From: isubramanian at apm.com (Iyappan Subramanian)
Date: Wed, 26 Aug 2015 11:48:06 -0700
Subject: [PATCH v2 2/2] drivers: net: xgene: Adding support for TSO
In-Reply-To: <1440614886-23566-1-git-send-email-isubramanian@apm.com>
References: <1440614886-23566-1-git-send-email-isubramanian@apm.com>
Message-ID: <1440614886-23566-3-git-send-email-isubramanian@apm.com>

Signed-off-by: Iyappan Subramanian <isubramanian at apm.com>
---
 drivers/net/ethernet/apm/xgene/xgene_enet_hw.h    |  16 +-
 drivers/net/ethernet/apm/xgene/xgene_enet_main.c  | 249 ++++++++++++++++++++--
 drivers/net/ethernet/apm/xgene/xgene_enet_main.h  |  11 +
 drivers/net/ethernet/apm/xgene/xgene_enet_xgmac.c |   8 +-
 drivers/net/ethernet/apm/xgene/xgene_enet_xgmac.h |   2 +
 5 files changed, 262 insertions(+), 24 deletions(-)

diff --git a/drivers/net/ethernet/apm/xgene/xgene_enet_hw.h b/drivers/net/ethernet/apm/xgene/xgene_enet_hw.h
index 541bed0..ff05bbc 100644
--- a/drivers/net/ethernet/apm/xgene/xgene_enet_hw.h
+++ b/drivers/net/ethernet/apm/xgene/xgene_enet_hw.h
@@ -193,12 +193,16 @@ enum xgene_enet_rm {
 #define USERINFO_LEN			32
 #define FPQNUM_POS			32
 #define FPQNUM_LEN			12
+#define NV_POS				50
+#define NV_LEN				1
+#define LL_POS				51
+#define LL_LEN				1
 #define LERR_POS			60
 #define LERR_LEN			3
 #define STASH_POS			52
 #define STASH_LEN			2
 #define BUFDATALEN_POS			48
-#define BUFDATALEN_LEN			12
+#define BUFDATALEN_LEN			15
 #define DATAADDR_POS			0
 #define DATAADDR_LEN			42
 #define COHERENT_POS			63
@@ -215,9 +219,19 @@ enum xgene_enet_rm {
 #define IPHDR_LEN			6
 #define EC_POS				22	/* Enable checksum */
 #define EC_LEN				1
+#define ET_POS				23	/* Enable TSO */
 #define IS_POS				24	/* IP protocol select */
 #define IS_LEN				1
 #define TYPE_ETH_WORK_MESSAGE_POS	44
+#define LL_BYTES_MSB_POS		56
+#define LL_BYTES_MSB_LEN		8
+#define LL_BYTES_LSB_POS		48
+#define LL_BYTES_LSB_LEN		12
+#define LL_LEN_POS			48
+#define LL_LEN_LEN			8
+#define DATALEN_MASK			GENMASK(11, 0)
+
+#define LAST_BUFFER			(0x7800ULL << BUFDATALEN_POS)
 
 struct xgene_enet_raw_desc {
 	__le64 m0;
diff --git a/drivers/net/ethernet/apm/xgene/xgene_enet_main.c b/drivers/net/ethernet/apm/xgene/xgene_enet_main.c
index 652b4c3..b330cb6 100644
--- a/drivers/net/ethernet/apm/xgene/xgene_enet_main.c
+++ b/drivers/net/ethernet/apm/xgene/xgene_enet_main.c
@@ -147,18 +147,27 @@ static int xgene_enet_tx_completion(struct xgene_enet_desc_ring *cp_ring,
 {
 	struct sk_buff *skb;
 	struct device *dev;
+	skb_frag_t *frag;
+	dma_addr_t *frag_dma_addr;
 	u16 skb_index;
 	u8 status;
-	int ret = 0;
+	int i, ret = 0;
 
 	skb_index = GET_VAL(USERINFO, le64_to_cpu(raw_desc->m0));
 	skb = cp_ring->cp_skb[skb_index];
+	frag_dma_addr = &cp_ring->frag_dma_addr[skb_index * MAX_SKB_FRAGS];
 
 	dev = ndev_to_dev(cp_ring->ndev);
 	dma_unmap_single(dev, GET_VAL(DATAADDR, le64_to_cpu(raw_desc->m1)),
-			 GET_VAL(BUFDATALEN, le64_to_cpu(raw_desc->m1)),
+			 skb_headlen(skb),
 			 DMA_TO_DEVICE);
 
+	for (i = 0; i < skb_shinfo(skb)->nr_frags; i++) {
+		frag = &skb_shinfo(skb)->frags[i];
+		dma_unmap_page(dev, frag_dma_addr[i], skb_frag_size(frag),
+			       DMA_TO_DEVICE);
+	}
+
 	/* Checking for error */
 	status = GET_VAL(LERR, le64_to_cpu(raw_desc->m0));
 	if (unlikely(status > 2)) {
@@ -179,12 +188,16 @@ static int xgene_enet_tx_completion(struct xgene_enet_desc_ring *cp_ring,
 
 static u64 xgene_enet_work_msg(struct sk_buff *skb)
 {
+	struct net_device *ndev = skb->dev;
+	struct xgene_enet_pdata *pdata = netdev_priv(ndev);
 	struct iphdr *iph;
-	u8 l3hlen, l4hlen = 0;
-	u8 csum_enable = 0;
-	u8 proto = 0;
-	u8 ethhdr;
-	u64 hopinfo;
+	u8 l3hlen = 0, l4hlen = 0;
+	u8 ethhdr, proto = 0, csum_enable = 0;
+	u64 hopinfo = 0;
+	u32 hdr_len, mss = 0;
+	u32 i, len, nr_frags;
+
+	ethhdr = xgene_enet_hdr_len(skb->data);
 
 	if (unlikely(skb->protocol != htons(ETH_P_IP)) &&
 	    unlikely(skb->protocol != htons(ETH_P_8021Q)))
@@ -201,14 +214,40 @@ static u64 xgene_enet_work_msg(struct sk_buff *skb)
 		l4hlen = tcp_hdrlen(skb) >> 2;
 		csum_enable = 1;
 		proto = TSO_IPPROTO_TCP;
+		if (ndev->features & NETIF_F_TSO) {
+			hdr_len = ethhdr + ip_hdrlen(skb) + tcp_hdrlen(skb);
+			mss = skb_shinfo(skb)->gso_size;
+
+			if (skb_is_nonlinear(skb)) {
+				len = skb_headlen(skb);
+				nr_frags = skb_shinfo(skb)->nr_frags;
+
+				for (i = 0; i < 2 && i < nr_frags; i++)
+					len += skb_shinfo(skb)->frags[i].size;
+
+				/* HW requires header must reside in 3 buffer */
+				if (unlikely(hdr_len > len)) {
+					if (skb_linearize(skb))
+						return 0;
+				}
+			}
+
+			if (!mss || ((skb->len - hdr_len) <= mss))
+				goto out;
+
+			if (mss != pdata->mss) {
+				pdata->mss = mss;
+				pdata->mac_ops->set_mss(pdata);
+			}
+			hopinfo |= SET_BIT(ET);
+		}
 	} else if (iph->protocol == IPPROTO_UDP) {
 		l4hlen = UDP_HDR_SIZE;
 		csum_enable = 1;
 	}
 out:
 	l3hlen = ip_hdrlen(skb) >> 2;
-	ethhdr = xgene_enet_hdr_len(skb->data);
-	hopinfo = SET_VAL(TCPHDR, l4hlen) |
+	hopinfo |= SET_VAL(TCPHDR, l4hlen) |
 		  SET_VAL(IPHDR, l3hlen) |
 		  SET_VAL(ETHHDR, ethhdr) |
 		  SET_VAL(EC, csum_enable) |
@@ -224,20 +263,54 @@ static u16 xgene_enet_encode_len(u16 len)
 	return (len == BUFLEN_16K) ? 0 : len;
 }
 
+static void xgene_set_addr_len(__le64 *desc, u32 idx, dma_addr_t addr, u32 len)
+{
+	desc[idx ^ 1] = cpu_to_le64(SET_VAL(DATAADDR, addr) |
+				    SET_VAL(BUFDATALEN, len));
+}
+
+static __le64 *xgene_enet_get_exp_bufs(struct xgene_enet_desc_ring *ring)
+{
+	__le64 *exp_bufs;
+
+	exp_bufs = &ring->exp_bufs[ring->exp_buf_tail * MAX_EXP_BUFFS];
+	memset(exp_bufs, 0, sizeof(__le64) * MAX_EXP_BUFFS);
+	ring->exp_buf_tail = (ring->exp_buf_tail + 1) & ((ring->slots / 2) - 1);
+
+	return exp_bufs;
+}
+
+static dma_addr_t *xgene_get_frag_dma_array(struct xgene_enet_desc_ring *ring)
+{
+	return &ring->cp_ring->frag_dma_addr[ring->tail * MAX_SKB_FRAGS];
+}
+
 static int xgene_enet_setup_tx_desc(struct xgene_enet_desc_ring *tx_ring,
 				    struct sk_buff *skb)
 {
 	struct device *dev = ndev_to_dev(tx_ring->ndev);
 	struct xgene_enet_raw_desc *raw_desc;
-	dma_addr_t dma_addr;
+	__le64 *exp_desc = NULL, *exp_bufs = NULL;
+	dma_addr_t dma_addr, pbuf_addr, *frag_dma_addr;
+	skb_frag_t *frag;
 	u16 tail = tx_ring->tail;
 	u64 hopinfo;
 	u32 len, hw_len;
-	u8 count = 1;
+	u8 ll = 0, nv = 0, idx = 0;
+	bool split = false;
+	u32 size, offset, ell_bytes = 0;
+	u32 i, fidx, nr_frags, count = 1;
 
 	raw_desc = &tx_ring->raw_desc[tail];
+	tail = (tail + 1) & (tx_ring->slots - 1);
 	memset(raw_desc, 0, sizeof(struct xgene_enet_raw_desc));
 
+	hopinfo = xgene_enet_work_msg(skb);
+	if (!hopinfo)
+		return -EINVAL;
+	raw_desc->m3 = cpu_to_le64(SET_VAL(HENQNUM, tx_ring->dst_ring_num) |
+				   hopinfo);
+
 	len = skb_headlen(skb);
 	hw_len = xgene_enet_encode_len(len);
 
@@ -252,13 +325,100 @@ static int xgene_enet_setup_tx_desc(struct xgene_enet_desc_ring *tx_ring,
 				   SET_VAL(BUFDATALEN, hw_len) |
 				   SET_BIT(COHERENT));
 
-	raw_desc->m0 = cpu_to_le64(SET_VAL(USERINFO, tail));
-	hopinfo = xgene_enet_work_msg(skb);
-	raw_desc->m3 = cpu_to_le64(SET_VAL(HENQNUM, tx_ring->dst_ring_num) |
-				   hopinfo);
-	tx_ring->cp_ring->cp_skb[tail] = skb;
+	if (!skb_is_nonlinear(skb))
+		goto out;
 
+	/* scatter gather */
+	nv = 1;
+	exp_desc = (void *)&tx_ring->raw_desc[tail];
 	tail = (tail + 1) & (tx_ring->slots - 1);
+	memset(exp_desc, 0, sizeof(struct xgene_enet_raw_desc));
+
+	nr_frags = skb_shinfo(skb)->nr_frags;
+	for (i = nr_frags; i < 4 ; i++)
+		exp_desc[i ^ 1] = cpu_to_le64(LAST_BUFFER);
+
+	frag_dma_addr = xgene_get_frag_dma_array(tx_ring);
+
+	for (i = 0, fidx = 0; split || (fidx < nr_frags); i++) {
+		if (!split) {
+			frag = &skb_shinfo(skb)->frags[fidx];
+			size = skb_frag_size(frag);
+			offset = 0;
+
+			pbuf_addr = skb_frag_dma_map(dev, frag, 0, size,
+						     DMA_TO_DEVICE);
+			if (dma_mapping_error(dev, pbuf_addr))
+				return -EINVAL;
+
+			frag_dma_addr[fidx] = pbuf_addr;
+			fidx++;
+
+			if (size > BUFLEN_16K)
+				split = true;
+		}
+
+		if (size > BUFLEN_16K) {
+			len = BUFLEN_16K;
+			size -= BUFLEN_16K;
+		} else {
+			len = size;
+			split = false;
+		}
+
+		dma_addr = pbuf_addr + offset;
+		hw_len = xgene_enet_encode_len(len);
+
+		switch (i) {
+		case 0:
+		case 1:
+		case 2:
+			xgene_set_addr_len(exp_desc, i, dma_addr, hw_len);
+			break;
+		case 3:
+			if (split || (fidx != nr_frags)) {
+				exp_bufs = xgene_enet_get_exp_bufs(tx_ring);
+				xgene_set_addr_len(exp_bufs, idx, dma_addr,
+						   hw_len);
+				idx++;
+				ell_bytes += len;
+			} else {
+				xgene_set_addr_len(exp_desc, i, dma_addr,
+						   hw_len);
+			}
+			break;
+		default:
+			xgene_set_addr_len(exp_bufs, idx, dma_addr, hw_len);
+			idx++;
+			ell_bytes += len;
+			break;
+		}
+
+		if (split)
+			offset += BUFLEN_16K;
+	}
+	count++;
+
+	if (idx) {
+		ll = 1;
+		dma_addr = dma_map_single(dev, exp_bufs,
+					  sizeof(u64) * MAX_EXP_BUFFS,
+					  DMA_TO_DEVICE);
+		if (dma_mapping_error(dev, dma_addr)) {
+			dev_kfree_skb_any(skb);
+			return -EINVAL;
+		}
+		i = ell_bytes >> LL_BYTES_LSB_LEN;
+		exp_desc[2] = cpu_to_le64(SET_VAL(DATAADDR, dma_addr) |
+					  SET_VAL(LL_BYTES_MSB, i) |
+					  SET_VAL(LL_LEN, idx));
+		raw_desc->m2 = cpu_to_le64(SET_VAL(LL_BYTES_LSB, ell_bytes));
+	}
+
+out:
+	raw_desc->m0 = cpu_to_le64(SET_VAL(LL, ll) | SET_VAL(NV, nv) |
+				   SET_VAL(USERINFO, tx_ring->tail));
+	tx_ring->cp_ring->cp_skb[tx_ring->tail] = skb;
 	tx_ring->tail = tail;
 
 	return count;
@@ -281,6 +441,9 @@ static netdev_tx_t xgene_enet_start_xmit(struct sk_buff *skb,
 		return NETDEV_TX_BUSY;
 	}
 
+	if (skb_padto(skb, XGENE_MIN_ENET_FRAME_SIZE))
+		return NETDEV_TX_OK;
+
 	count = xgene_enet_setup_tx_desc(tx_ring, skb);
 	if (count <= 0) {
 		dev_kfree_skb_any(skb);
@@ -341,7 +504,7 @@ static int xgene_enet_rx_frame(struct xgene_enet_desc_ring *rx_ring,
 
 	/* strip off CRC as HW isn't doing this */
 	datalen = GET_VAL(BUFDATALEN, le64_to_cpu(raw_desc->m1));
-	datalen -= 4;
+	datalen = (datalen & DATALEN_MASK) - 4;
 	prefetch(skb->data - NET_IP_ALIGN);
 	skb_put(skb, datalen);
 
@@ -373,26 +536,41 @@ static int xgene_enet_process_ring(struct xgene_enet_desc_ring *ring,
 				   int budget)
 {
 	struct xgene_enet_pdata *pdata = netdev_priv(ring->ndev);
-	struct xgene_enet_raw_desc *raw_desc;
+	struct xgene_enet_raw_desc *raw_desc, *exp_desc;
 	u16 head = ring->head;
 	u16 slots = ring->slots - 1;
-	int ret, count = 0;
+	int ret, count = 0, processed = 0;
 
 	do {
 		raw_desc = &ring->raw_desc[head];
+		exp_desc = NULL;
 		if (unlikely(xgene_enet_is_desc_slot_empty(raw_desc)))
 			break;
 
 		/* read fpqnum field after dataaddr field */
 		dma_rmb();
+		if (GET_BIT(NV, le64_to_cpu(raw_desc->m0))) {
+			head = (head + 1) & slots;
+			exp_desc = &ring->raw_desc[head];
+
+			if (unlikely(xgene_enet_is_desc_slot_empty(exp_desc))) {
+				head = (head - 1) & slots;
+				break;
+			}
+			dma_rmb();
+			count++;
+		}
 		if (is_rx_desc(raw_desc))
 			ret = xgene_enet_rx_frame(ring, raw_desc);
 		else
 			ret = xgene_enet_tx_completion(ring, raw_desc);
 		xgene_enet_mark_desc_slot_empty(raw_desc);
+		if (exp_desc)
+			xgene_enet_mark_desc_slot_empty(exp_desc);
 
 		head = (head + 1) & slots;
 		count++;
+		processed++;
 
 		if (ret)
 			break;
@@ -408,7 +586,7 @@ static int xgene_enet_process_ring(struct xgene_enet_desc_ring *ring,
 		}
 	}
 
-	return count;
+	return processed;
 }
 
 static int xgene_enet_napi(struct napi_struct *napi, const int budget)
@@ -753,12 +931,13 @@ static int xgene_enet_create_desc_rings(struct net_device *ndev)
 	struct xgene_enet_desc_ring *rx_ring, *tx_ring, *cp_ring;
 	struct xgene_enet_desc_ring *buf_pool = NULL;
 	enum xgene_ring_owner owner;
+	dma_addr_t dma_exp_bufs;
 	u8 cpu_bufnum = pdata->cpu_bufnum;
 	u8 eth_bufnum = pdata->eth_bufnum;
 	u8 bp_bufnum = pdata->bp_bufnum;
 	u16 ring_num = pdata->ring_num;
 	u16 ring_id;
-	int ret;
+	int ret, size;
 
 	/* allocate rx descriptor ring */
 	owner = xgene_derive_ring_owner(pdata);
@@ -809,6 +988,15 @@ static int xgene_enet_create_desc_rings(struct net_device *ndev)
 		ret = -ENOMEM;
 		goto err;
 	}
+
+	size = (tx_ring->slots / 2) * sizeof(__le64) * MAX_EXP_BUFFS;
+	tx_ring->exp_bufs = dma_zalloc_coherent(dev, size, &dma_exp_bufs,
+						GFP_KERNEL);
+	if (!tx_ring->exp_bufs) {
+		ret = -ENOMEM;
+		goto err;
+	}
+
 	pdata->tx_ring = tx_ring;
 
 	if (!pdata->cq_cnt) {
@@ -833,6 +1021,16 @@ static int xgene_enet_create_desc_rings(struct net_device *ndev)
 		ret = -ENOMEM;
 		goto err;
 	}
+
+	size = sizeof(dma_addr_t) * MAX_SKB_FRAGS;
+	cp_ring->frag_dma_addr = devm_kcalloc(dev, tx_ring->slots,
+					      size, GFP_KERNEL);
+	if (!cp_ring->frag_dma_addr) {
+		devm_kfree(dev, cp_ring->cp_skb);
+		ret = -ENOMEM;
+		goto err;
+	}
+
 	pdata->tx_ring->cp_ring = cp_ring;
 	pdata->tx_ring->dst_ring_num = xgene_enet_dst_ring_num(cp_ring);
 
@@ -1188,7 +1386,8 @@ static int xgene_enet_probe(struct platform_device *pdev)
 	xgene_enet_set_ethtool_ops(ndev);
 	ndev->features |= NETIF_F_IP_CSUM |
 			  NETIF_F_GSO |
-			  NETIF_F_GRO;
+			  NETIF_F_GRO |
+			  NETIF_F_SG;
 
 	of_id = of_match_device(xgene_enet_of_match, &pdev->dev);
 	if (of_id) {
@@ -1214,6 +1413,12 @@ static int xgene_enet_probe(struct platform_device *pdev)
 
 	xgene_enet_setup_ops(pdata);
 
+	if (pdata->phy_mode == PHY_INTERFACE_MODE_XGMII) {
+		ndev->features |= NETIF_F_TSO;
+		pdata->mss = XGENE_ENET_MSS;
+	}
+	ndev->hw_features = ndev->features;
+
 	ret = register_netdev(ndev);
 	if (ret) {
 		netdev_err(ndev, "Failed to register netdev\n");
diff --git a/drivers/net/ethernet/apm/xgene/xgene_enet_main.h b/drivers/net/ethernet/apm/xgene/xgene_enet_main.h
index 2ac547e..50f92c3 100644
--- a/drivers/net/ethernet/apm/xgene/xgene_enet_main.h
+++ b/drivers/net/ethernet/apm/xgene/xgene_enet_main.h
@@ -43,6 +43,9 @@
 #define BUFLEN_16K	(16 * 1024)
 #define NUM_PKT_BUF	64
 #define NUM_BUFPOOL	32
+#define MAX_EXP_BUFFS	256
+#define XGENE_ENET_MSS	1448
+#define XGENE_MIN_ENET_FRAME_SIZE	60
 
 #define START_CPU_BUFNUM_0	0
 #define START_ETH_BUFNUM_0	2
@@ -80,6 +83,7 @@ struct xgene_enet_desc_ring {
 	u16 num;
 	u16 head;
 	u16 tail;
+	u16 exp_buf_tail;
 	u16 slots;
 	u16 irq;
 	char irq_name[IRQ_ID_SIZE];
@@ -94,6 +98,7 @@ struct xgene_enet_desc_ring {
 	u8 nbufpool;
 	struct sk_buff *(*rx_skb);
 	struct sk_buff *(*cp_skb);
+	dma_addr_t *frag_dma_addr;
 	enum xgene_enet_ring_cfgsize cfgsize;
 	struct xgene_enet_desc_ring *cp_ring;
 	struct xgene_enet_desc_ring *buf_pool;
@@ -103,6 +108,7 @@ struct xgene_enet_desc_ring {
 		struct xgene_enet_raw_desc *raw_desc;
 		struct xgene_enet_raw_desc16 *raw_desc16;
 	};
+	__le64 *exp_bufs;
 };
 
 struct xgene_mac_ops {
@@ -113,6 +119,7 @@ struct xgene_mac_ops {
 	void (*tx_disable)(struct xgene_enet_pdata *pdata);
 	void (*rx_disable)(struct xgene_enet_pdata *pdata);
 	void (*set_mac_addr)(struct xgene_enet_pdata *pdata);
+	void (*set_mss)(struct xgene_enet_pdata *pdata);
 	void (*link_state)(struct work_struct *work);
 };
 
@@ -171,6 +178,7 @@ struct xgene_enet_pdata {
 	u8 eth_bufnum;
 	u8 bp_bufnum;
 	u16 ring_num;
+	u32 mss;
 };
 
 struct xgene_indirect_ctl {
@@ -205,6 +213,9 @@ static inline u64 xgene_enet_get_field_value(int pos, int len, u64 src)
 #define GET_VAL(field, src) \
 		xgene_enet_get_field_value(field ## _POS, field ## _LEN, src)
 
+#define GET_BIT(field, src) \
+		xgene_enet_get_field_value(field ## _POS, 1, src)
+
 static inline struct device *ndev_to_dev(struct net_device *ndev)
 {
 	return ndev->dev.parent;
diff --git a/drivers/net/ethernet/apm/xgene/xgene_enet_xgmac.c b/drivers/net/ethernet/apm/xgene/xgene_enet_xgmac.c
index 05edb84..7a28a48 100644
--- a/drivers/net/ethernet/apm/xgene/xgene_enet_xgmac.c
+++ b/drivers/net/ethernet/apm/xgene/xgene_enet_xgmac.c
@@ -184,6 +184,11 @@ static void xgene_xgmac_set_mac_addr(struct xgene_enet_pdata *pdata)
 	xgene_enet_wr_mac(pdata, HSTMACADR_MSW_ADDR, addr1);
 }
 
+static void xgene_xgmac_set_mss(struct xgene_enet_pdata *pdata)
+{
+	xgene_enet_wr_csr(pdata, XG_TSIF_MSS_REG0_ADDR, pdata->mss);
+}
+
 static u32 xgene_enet_link_status(struct xgene_enet_pdata *pdata)
 {
 	u32 data;
@@ -204,8 +209,8 @@ static void xgene_xgmac_init(struct xgene_enet_pdata *pdata)
 	data &= ~HSTLENCHK;
 	xgene_enet_wr_mac(pdata, AXGMAC_CONFIG_1, data);
 
-	xgene_enet_wr_mac(pdata, HSTMAXFRAME_LENGTH_ADDR, 0x06000600);
 	xgene_xgmac_set_mac_addr(pdata);
+	xgene_xgmac_set_mss(pdata);
 
 	xgene_enet_rd_csr(pdata, XG_RSIF_CONFIG_REG_ADDR, &data);
 	data |= CFG_RSIF_FPBUFF_TIMEOUT_EN;
@@ -329,6 +334,7 @@ struct xgene_mac_ops xgene_xgmac_ops = {
 	.rx_disable = xgene_xgmac_rx_disable,
 	.tx_disable = xgene_xgmac_tx_disable,
 	.set_mac_addr = xgene_xgmac_set_mac_addr,
+	.set_mss = xgene_xgmac_set_mss,
 	.link_state = xgene_enet_link_state
 };
 
diff --git a/drivers/net/ethernet/apm/xgene/xgene_enet_xgmac.h b/drivers/net/ethernet/apm/xgene/xgene_enet_xgmac.h
index bf0a994..f8f908d 100644
--- a/drivers/net/ethernet/apm/xgene/xgene_enet_xgmac.h
+++ b/drivers/net/ethernet/apm/xgene/xgene_enet_xgmac.h
@@ -62,7 +62,9 @@
 #define XCLE_BYPASS_REG0_ADDR           0x0160
 #define XCLE_BYPASS_REG1_ADDR           0x0164
 #define XG_CFG_BYPASS_ADDR		0x0204
+#define XG_CFG_LINK_AGGR_RESUME_0_ADDR	0x0214
 #define XG_LINK_STATUS_ADDR		0x0228
+#define XG_TSIF_MSS_REG0_ADDR		0x02a4
 #define XG_ENET_SPARE_CFG_REG_ADDR	0x040c
 #define XG_ENET_SPARE_CFG_REG_1_ADDR	0x0410
 #define XGENET_RX_DV_GATE_REG_0_ADDR	0x0804
-- 
1.9.1



From emunson at akamai.com  Wed Aug 26 11:24:21 2015
From: emunson at akamai.com (Eric B Munson)
Date: Wed, 26 Aug 2015 14:24:21 -0400
Subject: [PATCH v8 2/6] mm: mlock: Add new mlock system call
In-Reply-To: <1440613465-30393-1-git-send-email-emunson@akamai.com>
References: <1440613465-30393-1-git-send-email-emunson@akamai.com>
Message-ID: <1440613465-30393-3-git-send-email-emunson@akamai.com>

With the refactored mlock code, introduce a new system call for mlock.
The new call will allow the user to specify what lock states are being
added.  mlock2 is trivial at the moment, but a follow on patch will add
a new mlock state making it useful.

Signed-off-by: Eric B Munson <emunson at akamai.com>
Acked-by: Vlastimil Babka <vbabka at suse.cz>
Acked-by: Michal Hocko <mhocko at suse.com>
Cc: Michal Hocko <mhocko at suse.cz>
Cc: Vlastimil Babka <vbabka at suse.cz>
Cc: Heiko Carstens <heiko.carstens at de.ibm.com>
Cc: Geert Uytterhoeven <geert at linux-m68k.org>
Cc: Catalin Marinas <catalin.marinas at arm.com>
Cc: Stephen Rothwell <sfr at canb.auug.org.au>
Cc: Guenter Roeck <linux at roeck-us.net>
Cc: linux-alpha at vger.kernel.org
Cc: linux-kernel at vger.kernel.org
Cc: linux-arm-kernel at lists.infradead.org
Cc: adi-buildroot-devel at lists.sourceforge.net
Cc: linux-cris-kernel at axis.com
Cc: linux-ia64 at vger.kernel.org
Cc: linux-m68k at lists.linux-m68k.org
Cc: linux-am33-list at redhat.com
Cc: linux-parisc at vger.kernel.org
Cc: linuxppc-dev at lists.ozlabs.org
Cc: linux-s390 at vger.kernel.org
Cc: linux-sh at vger.kernel.org
Cc: sparclinux at vger.kernel.org
Cc: linux-xtensa at linux-xtensa.org
Cc: linux-api at vger.kernel.org
Cc: linux-arch at vger.kernel.org
Cc: linux-mm at kvack.org
---
 arch/x86/entry/syscalls/syscall_32.tbl | 1 +
 arch/x86/entry/syscalls/syscall_64.tbl | 1 +
 include/linux/syscalls.h               | 2 ++
 include/uapi/asm-generic/unistd.h      | 4 +++-
 kernel/sys_ni.c                        | 1 +
 mm/mlock.c                             | 8 ++++++++
 6 files changed, 16 insertions(+), 1 deletion(-)

diff --git a/arch/x86/entry/syscalls/syscall_32.tbl b/arch/x86/entry/syscalls/syscall_32.tbl
index ef8187f..8e06da6 100644
--- a/arch/x86/entry/syscalls/syscall_32.tbl
+++ b/arch/x86/entry/syscalls/syscall_32.tbl
@@ -365,3 +365,4 @@
 356	i386	memfd_create		sys_memfd_create
 357	i386	bpf			sys_bpf
 358	i386	execveat		sys_execveat			stub32_execveat
+360	i386	mlock2			sys_mlock2
diff --git a/arch/x86/entry/syscalls/syscall_64.tbl b/arch/x86/entry/syscalls/syscall_64.tbl
index 9ef32d5..67601e7 100644
--- a/arch/x86/entry/syscalls/syscall_64.tbl
+++ b/arch/x86/entry/syscalls/syscall_64.tbl
@@ -329,6 +329,7 @@
 320	common	kexec_file_load		sys_kexec_file_load
 321	common	bpf			sys_bpf
 322	64	execveat		stub_execveat
+324	common	mlock2			sys_mlock2
 
 #
 # x32-specific system call numbers start at 512 to avoid cache impact
diff --git a/include/linux/syscalls.h b/include/linux/syscalls.h
index b45c45b..56a3d59 100644
--- a/include/linux/syscalls.h
+++ b/include/linux/syscalls.h
@@ -884,4 +884,6 @@ asmlinkage long sys_execveat(int dfd, const char __user *filename,
 			const char __user *const __user *argv,
 			const char __user *const __user *envp, int flags);
 
+asmlinkage long sys_mlock2(unsigned long start, size_t len, int flags);
+
 #endif
diff --git a/include/uapi/asm-generic/unistd.h b/include/uapi/asm-generic/unistd.h
index e016bd9..14a6013 100644
--- a/include/uapi/asm-generic/unistd.h
+++ b/include/uapi/asm-generic/unistd.h
@@ -709,9 +709,11 @@ __SYSCALL(__NR_memfd_create, sys_memfd_create)
 __SYSCALL(__NR_bpf, sys_bpf)
 #define __NR_execveat 281
 __SC_COMP(__NR_execveat, sys_execveat, compat_sys_execveat)
+#define __NR_mlock2 282
+__SYSCALL(__NR_mlock2, sys_mlock2)
 
 #undef __NR_syscalls
-#define __NR_syscalls 282
+#define __NR_syscalls 283
 
 /*
  * All syscalls below here should go away really,
diff --git a/kernel/sys_ni.c b/kernel/sys_ni.c
index 7995ef5..4818b71 100644
--- a/kernel/sys_ni.c
+++ b/kernel/sys_ni.c
@@ -193,6 +193,7 @@ cond_syscall(sys_mlock);
 cond_syscall(sys_munlock);
 cond_syscall(sys_mlockall);
 cond_syscall(sys_munlockall);
+cond_syscall(sys_mlock2);
 cond_syscall(sys_mincore);
 cond_syscall(sys_madvise);
 cond_syscall(sys_mremap);
diff --git a/mm/mlock.c b/mm/mlock.c
index 5692ee5..3094f27 100644
--- a/mm/mlock.c
+++ b/mm/mlock.c
@@ -643,6 +643,14 @@ SYSCALL_DEFINE2(mlock, unsigned long, start, size_t, len)
 	return do_mlock(start, len, VM_LOCKED);
 }
 
+SYSCALL_DEFINE3(mlock2, unsigned long, start, size_t, len, int, flags)
+{
+	if (flags)
+		return -EINVAL;
+
+	return do_mlock(start, len, VM_LOCKED);
+}
+
 SYSCALL_DEFINE2(munlock, unsigned long, start, size_t, len)
 {
 	int ret;
-- 
1.9.1



From tglx at linutronix.de  Wed Aug 26 11:54:21 2015
From: tglx at linutronix.de (Thomas Gleixner)
Date: Wed, 26 Aug 2015 20:54:21 +0200 (CEST)
Subject: [PATCH 1/1] irqchip: imx-gpcv2: Simplify the implemenation
In-Reply-To: <CY1PR0301MB084315B04E53CF64EF299D0B83600@CY1PR0301MB0843.namprd03.prod.outlook.com>
References: <1440604166-2624-1-git-send-email-shenwei.wang@freescale.com>
 <alpine.DEB.2.11.1508261756540.15006@nanos>
 <CY1PR0301MB084315B04E53CF64EF299D0B83600@CY1PR0301MB0843.namprd03.prod.outlook.com>
Message-ID: <alpine.DEB.2.11.1508262052260.15006@nanos>

On Wed, 26 Aug 2015, Shenwei Wang wrote:
> > From: Thomas Gleixner [mailto:tglx at linutronix.de]
> > > +	cd = imx_gpcv2_instance;
> > > +	if (!cd)
> > >  		return 0;
> > >
> > > +	for (i = 0; i < IMR_NUM; i++) {
> > > +		reg = cd->gpc_base + cd->cpu2wakeup + i * 4;
> > > +		cd->wakeup_sources[i] = readl_relaxed(reg);
> > > +	}
> > > +
> > >  	if (sources)
> > > -		*sources = imx_gpcv2_instance->wakeup_sources;
> > > +		*sources = cd->wakeup_sources;
> > >
> > >  	return IMR_NUM;
> > 
> > You do not need the intermediate storage at all.
> > 
> > u32 imx_gpcv2_get_wakeup_source(u32 *sources) {
> > 	if (sources) {
> > 		for (i = 0; i < IMR_NUM; i++) {
> > 			reg = cd->gpc_base + cd->cpu2wakeup + i * 4;
> > 			sources[i] = readl_relaxed(reg);
> > 		}
> > 	}
> > 	....
> 
> Using the intermediate storage here can make the caller a little easier,
> because the caller does not need to malloc the memory before the call.
> Especially the caller does not even know how many memory to allocate
> In the beginning.

Fair enough, but why do you need that case where sources can be NULL
just to return IMR_NUM?

Thanks,

	tglx



From jonmason at broadcom.com  Wed Aug 26 12:00:46 2015
From: jonmason at broadcom.com (Jon Mason)
Date: Wed, 26 Aug 2015 15:00:46 -0400
Subject: [PATCH 5/5] MAINTAINERS: add entry for the Broadcom Northstar
 Plus SoCs
In-Reply-To: <CAOesGMioBQY9qy-S8kMJmo_=B6-KZiUkd=Ns1Uo2dGu0BiqppQ@mail.gmail.com>
References: <1440092861-25825-1-git-send-email-jonmason@broadcom.com>
 <CAOesGMioBQY9qy-S8kMJmo_=B6-KZiUkd=Ns1Uo2dGu0BiqppQ@mail.gmail.com>
Message-ID: <20150826190046.GB4171@broadcom.com>

On Tue, Aug 25, 2015 at 04:42:42PM -0700, Olof Johansson wrote:
> On Thu, Aug 20, 2015 at 10:47 AM, Jon Mason <jonmason at broadcom.com> wrote:
> > Modify the iProc MAINTAINER to cover the Nortstar Plus SoCs, and add me
> > to the list of people responsible for it.
> 
> That's not what this patch does. It removes CYGNUS from the
> description as well. Hmm?

iProc is a family of SoCs that includes Cygnus, Northstar (BCM5301X),
Northstar Plus, Northstar 2, and a number of other platforms.  I
removed the "Cygnus" for that reason.

> 
> I'm also not a fan of the complex patterns, but that's more of a
> bikeshedding comment. Does Broadcom really not have a bit more
> systematic naming than this? :)

Per Florian's comment, it's a bit of a mess internally.

> 
> > Signed-off-by: Jon Mason <jonmason at broadcom.com>
> > Reviewed-by: Scott Branden <sbranden at broadcom.com>
> 
> For maintainer updates, we usuallu like to see a public ack of this
> and not just a pre-acked patch. You _could_ have added it yourself
> without Scott's actual approval, after all.

Thanks,
Jon

> 
> 
> -Olof


From Shenwei.Wang at freescale.com  Wed Aug 26 12:05:18 2015
From: Shenwei.Wang at freescale.com (Shenwei Wang)
Date: Wed, 26 Aug 2015 19:05:18 +0000
Subject: [PATCH 1/1] irqchip: imx-gpcv2: Simplify the implemenation
In-Reply-To: <alpine.DEB.2.11.1508262052260.15006@nanos>
References: <1440604166-2624-1-git-send-email-shenwei.wang@freescale.com>
 <alpine.DEB.2.11.1508261756540.15006@nanos>
 <CY1PR0301MB084315B04E53CF64EF299D0B83600@CY1PR0301MB0843.namprd03.prod.outlook.com>
 <alpine.DEB.2.11.1508262052260.15006@nanos>
Message-ID: <CY1PR0301MB0843D0E99E78F30D0DEBC8B783600@CY1PR0301MB0843.namprd03.prod.outlook.com>



> -----Original Message-----
> From: Thomas Gleixner [mailto:tglx at linutronix.de]
> > > > +
> > > >  	if (sources)
> > > > -		*sources = imx_gpcv2_instance->wakeup_sources;
> > > > +		*sources = cd->wakeup_sources;
> > > >
> > > >  	return IMR_NUM;
> > >
> > > You do not need the intermediate storage at all.
> > >
> > > u32 imx_gpcv2_get_wakeup_source(u32 *sources) {
> > > 	if (sources) {
> > > 		for (i = 0; i < IMR_NUM; i++) {
> > > 			reg = cd->gpc_base + cd->cpu2wakeup + i * 4;
> > > 			sources[i] = readl_relaxed(reg);
> > > 		}
> > > 	}
> > > 	....
> >
> > Using the intermediate storage here can make the caller a little
> > easier, because the caller does not need to malloc the memory before the call.
> > Especially the caller does not even know how many memory to allocate
> > In the beginning.
> 
> Fair enough, but why do you need that case where sources can be NULL just to
> return IMR_NUM?

The intention is to get the IMR_NUM only. But so far no user uses this feature.

Thanks,
Shenwei

> Thanks,
> 
> 	tglx



From msalter at redhat.com  Wed Aug 26 12:13:22 2015
From: msalter at redhat.com (Mark Salter)
Date: Wed, 26 Aug 2015 15:13:22 -0400
Subject: [PATCH] ARM64: kernel: implement ACPI parking protocol
In-Reply-To: <20150826160716.GB11863@red-moon>
References: <1436959990-32054-1-git-send-email-lorenzo.pieralisi@arm.com>
 <1437063431.3583.2.camel@redhat.com> <20150716171221.GB18582@red-moon>
 <1437068449.3583.4.camel@redhat.com> <20150826160716.GB11863@red-moon>
Message-ID: <1440616402.13044.16.camel@redhat.com>

On Wed, 2015-08-26 at 17:07 +0100, Lorenzo Pieralisi wrote:
> Mark,
> 
> On Thu, Jul 16, 2015 at 06:40:49PM +0100, Mark Salter wrote:
> 
> [...]
> 
> > > > The kernel will only add cached memory regions to linear mapping 
> > > > and
> > > > presumably, the FW will mark the mailboxes as uncached. Otherwise, 
> > > > it
> > > > is a FW bug. But I suppose we could run into problems with kernels
> > > > using 64K pagesize since firmware assumes 4k.
> > > 
> > > Nope, ioremap takes care of that, everything should be fine.
> > 
> > The mailbox is 4K. If it is next to a cached UEFI region, the kernel 
> > may
> > have to overlap the mailbox with a cached 64K mapping in order to 
> > include
> > the adjoining UEFI region in the linear map. Then the ioremap would 
> > fail
> > because the mailbox is included in the linear mapping.
> 
> You have to acknowledge that what you describe is a bit of a corner
> case (and a silly FW set-up), are you aware of any existing FW set-up
> where we actually hit the corner case above ?

Oh sure. It could definitely be a corner case. I'm not aware of any
existing firmware supporting the protocol implemented by your patch.
So time will tell how well firmware vendors which do implement it
avoid the corner case problem. I am aware of some existing firmwares
which put the mailbox area in RAM which is also in the kernel linear
mapping as cached memory. But those wouldn't work with your patch for
more reasons than that.

> 
> I think it is fine to leave code as-is, at least the mailbox
> mappings, I will check to see I can improve the MADT parsing,
> somehow.

I'm not strenuously opposed to leaving it as-is. But we need to
acknowledge that if the 64K pagesize issue isn't covered by the
protocol spec, we're relying on firmware vendors to be diligent
not to break 64K pagesize kernels.



From ezequiel at vanguardiasur.com.ar  Wed Aug 26 12:29:52 2015
From: ezequiel at vanguardiasur.com.ar (Ezequiel Garcia)
Date: Wed, 26 Aug 2015 16:29:52 -0300
Subject: CONFIG_DEBUG_SHIRQ and PM
In-Reply-To: <20150825195830.GH27534@saruman.tx.rr.com>
References: <20150825195830.GH27534@saruman.tx.rr.com>
Message-ID: <CAAEAJfCY1BRuoQCWfD2pCq36E54vDB5Coy2S7rz3RfL2BVLGaw@mail.gmail.com>

Felipe,

On 25 August 2015 at 16:58, Felipe Balbi <balbi at ti.com> wrote:
> Hi Ingo,
>
> I'm facing an issue with CONFIG_DEBUG_SHIRQ and pm_runtime when using
> devm_request_*irq().
>

I may be jumping on the gun here, but I believe here's your problem.
Using devm_request_irq with shared IRQs is not a good idea.

Or at least, it forces you to handle interrupts after your device
is _completely_ removed (e.g. your IRQ cookie could be bogus).

AFAICS, the CONFIG_DEBUG_SHIRQ option is just triggering a couple
spurious interrupts, that are expected to happen anyway.

Your IRQ is shared, and so you may get any IRQ at any time,
coming from another device (not yours).

So, if I'm right, my suggestion is simple: use request_irq/free_irq
and free your IRQ before you disable your clocks, remove your device, etc.

> If we using devm_request_*irq(), that irq will be freed after device
> drivers' ->remove() gets called. If on ->remove(), we're calling
> pm_runtime_put_sync(); pm_runtime_disable(), device's clocks might get
> gated and, because we do an extra call to the device's IRQ handler when
> CONFIG_DEBUG_SHIRQ=y, we might trigger an abort exception if, inside the
> IRQ handler, we try to read a register which is clocked by the device's
> clock.
>
> This is, of course, really old code which has been in tree for many,
> many years. I guess nobody has been running their tests in the setup
> mentioned above (CONFIG_DEBUG_SHIRQ=y, pm_runtime_put_sync() on
> ->remove(), a register read on IRQ handler, and a shared IRQ handler),
> so that's why we never caught this before.
>
> Disabling CONFIG_DEBUG_SHIRQ, of course, makes the problem go away, but
> if driver *must* be ready to receive, and handle, an IRQ even during
> module removal, I wonder what the IRQ handler should do. We can't, in
> most cases, call pm_runtime_put_sync() from IRQ handler.
>
> I'm guessing the only way would be to move pm_runtime calls into the bus
> driver (in this case, the platform_bus) and make sure it only gets
> called after device managed resources are freed ?
>
> Any hints would be greatly appreciated.
>

Hope it helps!
-- 
Ezequiel Garc?a, VanguardiaSur
www.vanguardiasur.com.ar


From sbranden at broadcom.com  Wed Aug 26 12:32:26 2015
From: sbranden at broadcom.com (Scott Branden)
Date: Wed, 26 Aug 2015 12:32:26 -0700
Subject: [PATCH 2/5] ARM: NSP: add minimal Northstar Plus device tree
In-Reply-To: <CAOesGMhE40_mfZCD2PqcTObE_Gz_6rKFwhf3-6kZY4n9Yxn2rQ@mail.gmail.com>
References: <1440092804-25726-1-git-send-email-jonmason@broadcom.com>
 <CAOesGMhE40_mfZCD2PqcTObE_Gz_6rKFwhf3-6kZY4n9Yxn2rQ@mail.gmail.com>
Message-ID: <55DE144A.4090202@broadcom.com>

Hi Olof,

Comments inline.

On 15-08-25 04:36 PM, Olof Johansson wrote:
> Hi,
>
> I'm not sure what the strategy behind your cc:ing on this patch set
> is. I only got a couple of them in my inbox, and this one wasn't one
> of them. :)
>
> On Thu, Aug 20, 2015 at 10:46 AM, Jon Mason <jonmason at broadcom.com> wrote:
>> Add a very minimalistic set of Northstar Plus Device Tree files which
>> describes the SoC and the BCM958625 implementation.  The perpherials
>> described are:
>>
>> ARM Cortex A9 CPU
>> 2 8250 UARTs
>> ARM GIC
>> PL310 L2 Cache
>> ARM A9 Global timer
>>
>> Signed-off-by: Jon Mason <jonmason at broadcom.com>
>> Signed-off-by: Kapil Hali <kapilh at broadcom.com>
>> Reviewed-by: Ray Jui <rjui at broadcom.com>
>> Reviewed-by: Scott Branden <sbranden at broadcom.com>
>
> Seeing reviewed-by already attached to a v1 of a patchset has limited
> value for someone on the outside.

>
> Reviewed-by is one of those tags that has a value that's mostly
> dependent on who it comes from. By not actually seeing the review and
> the feedback provided (and revisions made), less data is provided to
> tell if it's a valuable review or not.
should we start using Ack'd instead then for things that were reviewed 
internally?
>
> Also, if you're posting the code you should probably have your name
> below Kapil's, since you're the one signing off the origin of the
> code. See Documentation/SubmittingPatches.txt for details on what
> S-o-b actually means.
>
>
>> --- /dev/null
>> +++ b/arch/arm/boot/dts/bcm-nsp.dtsi
>> @@ -0,0 +1,105 @@
>> +/*
>> + *  BSD LICENSE
>> + *
>> + *  Copyright(c) 2015 Broadcom Corporation.  All rights reserved.
>> + *
>> + *  Redistribution and use in source and binary forms, with or without
>> + *  modification, are permitted provided that the following conditions
>> + *  are met:
>> + *
>> + *    * Redistributions of source code must retain the above copyright
>> + *      notice, this list of conditions and the following disclaimer.
>> + *    * Redistributions in binary form must reproduce the above copyright
>> + *      notice, this list of conditions and the following disclaimer in
>> + *      the documentation and/or other materials provided with the
>> + *      distribution.
>> + *    * Neither the name of Broadcom Corporation nor the names of its
>> + *      contributors may be used to endorse or promote products derived
>> + *      from this software without specific prior written permission.
>> + *
>> + *  THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
>> + *  "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
>> + *  LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
>> + *  A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
>> + *  OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
>> + *  SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
>> + *  LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
>> + *  DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
>> + *  THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
>> + *  (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
>> + *  OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
>> + */
>
> I'm not sure we've seen BSD-only submissions before. I'll let DT
> maintainers (or Ian) speak up in case this would cause problems.
>

Arnd is the one who require new DT content to be BSD licensed.
We're just following his orders:

http://lkml.iu.edu/hypermail/linux/kernel/1411.1/01109.html

>
>> +
>> +#include <dt-bindings/interrupt-controller/arm-gic.h>
>> +#include <dt-bindings/interrupt-controller/irq.h>
>> +
>> +#include "skeleton.dtsi"
>> +
>> +/ {
>> +       compatible = "brcm,nsp";
>> +       model = "Broadcom Northstar Plus SoC";
>> +       interrupt-parent = <&gic>;
>> +
>> +       cpus {
>> +               #address-cells = <1>;
>> +               #size-cells = <0>;
>> +
>> +               cpu at 0 {
>> +                       device_type = "cpu";
>> +                       compatible = "arm,cortex-a9";
>> +                       next-level-cache = <&L2>;
>> +                       reg = <0x0>;
>> +               };
>> +       };
>> +
>> +       clocks {
>> +               #address-cells = <1>;
>> +               #size-cells = <1>;
>> +               ranges;
>> +
>> +               periph_clk: periph_clk {
>> +                       compatible = "fixed-clock";
>> +                       #clock-cells = <0>;
>> +                       clock-frequency = <500000000>;
>> +               };
>> +       };
>> +
>> +       uart0: serial at 18000300 {
>> +               compatible = "ns16550a";
>> +               reg = <0x18000300 0x100>;
>> +               interrupts = <GIC_SPI 85 IRQ_TYPE_LEVEL_HIGH>;
>> +               clock-frequency = <62499840>;
>> +               status = "disabled";
>> +       };
>> +
>> +       uart1: serial at 18000400 {
>> +               compatible = "ns16550a";
>> +               reg = <0x18000400 0x100>;
>> +               interrupts = <GIC_SPI 85 IRQ_TYPE_LEVEL_HIGH>;
>> +               clock-frequency = <62499840>;
>> +               status = "disabled";
>> +       };
>> +
>> +       gic: interrupt-controller at 19021000 {
>> +               compatible = "arm,cortex-a9-gic";
>> +               #interrupt-cells = <3>;
>> +               #address-cells = <0>;
>> +               interrupt-controller;
>> +               reg = <0x19021000 0x1000>,
>> +                     <0x19020100 0x100>;
>> +       };
>> +
>> +       L2: l2-cache {
>> +               compatible = "arm,pl310-cache";
>> +               reg = <0x19022000 0x1000>;
>> +               cache-unified;
>> +               cache-level = <2>;
>> +       };
>> +
>> +       timer at 19020200 {
>> +               compatible = "arm,cortex-a9-global-timer";
>> +               reg = <0x19020200 0x100>;
>> +               interrupts = <GIC_PPI 11 IRQ_TYPE_LEVEL_HIGH>;
>> +               clocks = <&periph_clk>;
>> +       };
>> +};
>> diff --git a/arch/arm/boot/dts/bcm958625k.dts b/arch/arm/boot/dts/bcm958625k.dts
>> new file mode 100644
>> index 0000000..a1bc151
>> --- /dev/null
>> +++ b/arch/arm/boot/dts/bcm958625k.dts
>> @@ -0,0 +1,57 @@
>> +/*
>> + *  BSD LICENSE
>> + *
>> + *  Copyright(c) 2015 Broadcom Corporation.  All rights reserved.
>> + *
>> + *  Redistribution and use in source and binary forms, with or without
>> + *  modification, are permitted provided that the following conditions
>> + *  are met:
>> + *
>> + *    * Redistributions of source code must retain the above copyright
>> + *      notice, this list of conditions and the following disclaimer.
>> + *    * Redistributions in binary form must reproduce the above copyright
>> + *      notice, this list of conditions and the following disclaimer in
>> + *      the documentation and/or other materials provided with the
>> + *      distribution.
>> + *    * Neither the name of Broadcom Corporation nor the names of its
>> + *      contributors may be used to endorse or promote products derived
>> + *      from this software without specific prior written permission.
>> + *
>> + *  THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
>> + *  "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
>> + *  LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
>> + *  A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
>> + *  OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
>> + *  SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
>> + *  LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
>> + *  DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
>> + *  THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
>> + *  (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
>> + *  OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
>> + */
>> +
>> +/dts-v1/;
>> +
>> +#include "bcm-nsp.dtsi"
>> +
>> +/ {
>> +       model = "NorthStar Plus SVK (BCM958625K)";
>> +       compatible = "brcm,bcm58625", "brcm,nsp";
>> +
>> +       aliases {
>> +               serial0 = &uart0;
>> +               serial1 = &uart1;
>> +       };
>> +
>> +       chosen {
>> +               stdout-path = "serial0:115200n8";
>> +       };
>
> No way to mount a root filesystem yet? How much work remains for that
> to be possible, and what's the plan for that?
>
This is the bare bones DTS.  I'm sure Jon will activate NAND once tested 
- it "should" work with the same driver that Cygnus and STB chips use.

>> +
>> +       uart0: serial at 18000300 {
>> +               status = "okay";
>> +       };
>> +
>> +       uart1: serial at 18000400 {
>> +               status = "okay";
>> +       };
>
> I recommend using labels here instead so you don't have to mirror the
> DT layout to get the updated property right.
>
> I.e.
>
> &uart1 {
>          status = "okay";
> };
>
>
>
> -Olof
>

Regards,
  Scott


From sboyd at codeaurora.org  Wed Aug 26 12:32:42 2015
From: sboyd at codeaurora.org (Stephen Boyd)
Date: Wed, 26 Aug 2015 12:32:42 -0700
Subject: [PATCH] ARM: Add unwinding to __clear_user_std() conflicts
 (next-20150825)
In-Reply-To: <20150825233051.GA21612@n2100.arm.linux.org.uk>
References: <55dc65d7.040bc20a.609e.6686@mx.google.com>
 <CANMBJr4aeNa3P9bydT1L5KjZ0uH9REd2GXxV1bWAx4gF2++qbQ@mail.gmail.com>
 <20150825233051.GA21612@n2100.arm.linux.org.uk>
Message-ID: <20150826193242.GA28744@codeaurora.org>

Add unwinding annotations so that unwinding from this function
works properly.

Signed-off-by: Stephen Boyd <sboyd at codeaurora.org>
---

On 08/26, Russell King - ARM Linux wrote:
> 
> Looking at the oops dumps you have, it's really quite annoying that they
> do not contain a proper backtrace.  I also have to ask why your logs
> seem to screw up on the PC/LR values in the oops dumps - they seem to
> be completely missing.
> 

This fixes the stacktrace for me so that it's actually readable.

 CPU: 1 PID: 1 Comm: init Not tainted 4.2.0-rc8-next-20150825-00012-g7b30062de23c-dirty #170
 Hardware name: Qualcomm (Flattened Device Tree)
 task: ee0a8000 ti: ee0b0000 task.ti: ee0b0000
 PC is at __clear_user_std+0x16/0x78
 LR is at padzero+0x47/0x54
 pc : [<c03df522>]    lr : [<c02f103b>]    psr: 60000033
 sp : ee0b1ea8  ip : 00000002  fp : 00000000
 r10: 001de22e  r9 : 00000000  r8 : ee122300
 r7 : ee0b1eb8  r6 : ed8d0300  r5 : 00000000  r4 : 00000051
 r3 : 00000055  r2 : 00000000  r1 : 00000dd2  r0 : 001de22e
 Flags: nZCv  IRQs on  FIQs on  Mode SVC_32  ISA Thumb  Segment none
 Control: 50c5787d  Table: 2d8d806a  DAC: 00000051
 Process init (pid: 1, stack limit = 0xee0b0210)
 Stack: (0xee0b1ea8 to 0xee0b2000)
 1ea0:                   00000dd2 c02f103b ee124200 c02f175b 00001812 000001cd
 1ec0: 001e2a20 00000000 ee122300 00000000 00000000 001e2a20 001de22e 00000001
 1ee0: 00000000 00008000 00008000 001dd870 001de22e 001d5870 00000051 00000055
 1f00: 00000000 ee0b1eb8 beffffde ed8d0300 ef7f7160 c02c1cfb 00000001 c0865324
 1f20: ed8d0300 c0862ca4 fffffff8 00000001 c0852fe0 ed8d0300 00000000 c02c1e7f
 1f40: ee0a8000 ee033000 ee126000 ee0b1f58 00000001 c02c2f1f 00000001 ed8d6038
 1f60: 00000000 ee0a8280 c0851118 00000000 c0852f50 00000000 00000000 00000000
 1f80: 00000000 00000000 00000000 c02c3039 00000000 c02094f5 00000000 c08da000
 1fa0: c059f2b5 c059f2d7 00000000 c020e4d5 00000000 00000000 00000000 00000000
 1fc0: 00000000 00000000 00000000 00000000 00000000 00000000 00000000 00000000
 1fe0: 00000000 00000000 00000000 00000000 00000013 00000000 00000000 00000000
 [<c03df522>] (__clear_user_std) from [<c02f103b>] (padzero+0x47/0x54)
 [<c02f103b>] (padzero) from [<c02f175b>] (load_elf_binary+0x573/0xe74)
 [<c02f175b>] (load_elf_binary) from [<c02c1e7f>] (search_binary_handler+0x4f/0x124)
 [<c02c1e7f>] (search_binary_handler) from [<c02c2f1f>] (do_execveat_common+0x3df/0x4e0)
 [<c02c2f1f>] (do_execveat_common) from [<c02c3039>] (do_execve+0x19/0x1c)
 [<c02c3039>] (do_execve) from [<c059f2d7>] (kernel_init+0x23/0x9c)
 [<c059f2d7>] (kernel_init) from [<c020e4d5>] (ret_from_fork+0x11/0x3c)
 Code: 0c03 d011 f1bc 0f02 (f880) 2000

diff --git a/arch/arm/lib/clear_user.S b/arch/arm/lib/clear_user.S
index 970d6c043774..e936352ccb00 100644
--- a/arch/arm/lib/clear_user.S
+++ b/arch/arm/lib/clear_user.S
@@ -9,6 +9,7 @@
  */
 #include <linux/linkage.h>
 #include <asm/assembler.h>
+#include <asm/unwind.h>
 
 		.text
 
@@ -20,6 +21,8 @@
  */
 ENTRY(__clear_user_std)
 WEAK(arm_clear_user)
+UNWIND(.fnstart)
+UNWIND(.save {r1, lr})
 		stmfd	sp!, {r1, lr}
 		mov	r2, #0
 		cmp	r1, #4
@@ -44,6 +47,7 @@ WEAK(arm_clear_user)
 USER(		strnebt	r2, [r0])
 		mov	r0, #0
 		ldmfd	sp!, {r1, pc}
+UNWIND(.fnend)
 ENDPROC(arm_clear_user)
 ENDPROC(__clear_user_std)
 
-- 
The Qualcomm Innovation Center, Inc. is a member of the Code Aurora Forum,
a Linux Foundation Collaborative Project


From sboyd at codeaurora.org  Wed Aug 26 12:35:04 2015
From: sboyd at codeaurora.org (Stephen Boyd)
Date: Wed, 26 Aug 2015 12:35:04 -0700
Subject: [PATCH] ARM: dts: qcom: Remove extra reg element from iadc device
Message-ID: <1440617704-30346-1-git-send-email-sboyd@codeaurora.org>

This doesn't match the binding, and the driver doesn't look to
be using it. Remove the extra element.

CC: Ivan T. Ivanov <ivan.ivanov at linaro.org>
Signed-off-by: Stephen Boyd <sboyd at codeaurora.org>
---
 arch/arm/boot/dts/qcom-pm8941.dtsi | 3 +--
 1 file changed, 1 insertion(+), 2 deletions(-)

diff --git a/arch/arm/boot/dts/qcom-pm8941.dtsi b/arch/arm/boot/dts/qcom-pm8941.dtsi
index 968f1043d4f5..0fe1080aeb20 100644
--- a/arch/arm/boot/dts/qcom-pm8941.dtsi
+++ b/arch/arm/boot/dts/qcom-pm8941.dtsi
@@ -120,8 +120,7 @@
 
 		pm8941_iadc: iadc at 3600 {
 			compatible = "qcom,pm8941-iadc", "qcom,spmi-iadc";
-			reg = <0x3600 0x100>,
-				  <0x12f1 0x1>;
+			reg = <0x3600 0x100>;
 			interrupts = <0x0 0x36 0x0 IRQ_TYPE_EDGE_RISING>;
 			qcom,external-resistor-micro-ohms = <10000>;
 		};
-- 
The Qualcomm Innovation Center, Inc. is a member of the Code Aurora Forum,
a Linux Foundation Collaborative Project



From shenwei.wang at freescale.com  Wed Aug 26 12:35:55 2015
From: shenwei.wang at freescale.com (Shenwei Wang)
Date: Wed, 26 Aug 2015 14:35:55 -0500
Subject: [PATCH v2 1/1] irqchip: imx-gpcv2:  Simplify the implementation
Message-ID: <1440617755-2942-1-git-send-email-shenwei.wang@freescale.com>

Based on Sudeep Holla's review comments, the implementation can
be simplified by using the two flags: IRQCHIP_SKIP_SET_WAKE and
IRQCHIP_MASK_ON_SUSPEND. This patch enables the flags in the
struct irq_chip and removes the unnecessory syscore_ops callbacks.

Signed-off-by: Shenwei Wang <shenwei.wang at freescale.com>
---
Change log:
	v2 - Fixed the typo in the subject.

 drivers/irqchip/irq-imx-gpcv2.c | 83 +++++++----------------------------------
 1 file changed, 13 insertions(+), 70 deletions(-)

diff --git a/drivers/irqchip/irq-imx-gpcv2.c b/drivers/irqchip/irq-imx-gpcv2.c
index 4a97afa..e25df78 100644
--- a/drivers/irqchip/irq-imx-gpcv2.c
+++ b/drivers/irqchip/irq-imx-gpcv2.c
@@ -22,7 +22,6 @@ struct gpcv2_irqchip_data {
 	struct raw_spinlock    rlock;
 	void __iomem       *gpc_base;
 	u32 wakeup_sources[IMR_NUM];
-	u32 saved_irq_mask[IMR_NUM];
 	u32 cpu2wakeup;
 };

@@ -30,79 +29,25 @@ static struct gpcv2_irqchip_data *imx_gpcv2_instance;

 u32 imx_gpcv2_get_wakeup_source(u32 **sources)
 {
-	if (!imx_gpcv2_instance)
+	struct gpcv2_irqchip_data *cd;
+	void __iomem *reg;
+	int i;
+
+	cd = imx_gpcv2_instance;
+	if (!cd)
 		return 0;

+	for (i = 0; i < IMR_NUM; i++) {
+		reg = cd->gpc_base + cd->cpu2wakeup + i * 4;
+		cd->wakeup_sources[i] = readl_relaxed(reg);
+	}
+
 	if (sources)
-		*sources = imx_gpcv2_instance->wakeup_sources;
+		*sources = cd->wakeup_sources;

 	return IMR_NUM;
 }

-static int gpcv2_wakeup_source_save(void)
-{
-	struct gpcv2_irqchip_data *cd;
-	void __iomem *reg;
-	int i;
-
-	cd = imx_gpcv2_instance;
-	if (!cd)
-		return 0;
-
-	for (i = 0; i < IMR_NUM; i++) {
-		reg = cd->gpc_base + cd->cpu2wakeup + i * 4;
-		cd->saved_irq_mask[i] = readl_relaxed(reg);
-		writel_relaxed(cd->wakeup_sources[i], reg);
-	}
-
-	return 0;
-}
-
-static void gpcv2_wakeup_source_restore(void)
-{
-	struct gpcv2_irqchip_data *cd;
-	void __iomem *reg;
-	int i;
-
-	cd = imx_gpcv2_instance;
-	if (!cd)
-		return;
-
-	for (i = 0; i < IMR_NUM; i++) {
-		reg = cd->gpc_base + cd->cpu2wakeup + i * 4;
-		writel_relaxed(cd->saved_irq_mask[i], reg);
-	}
-}
-
-static struct syscore_ops imx_gpcv2_syscore_ops = {
-	.suspend	= gpcv2_wakeup_source_save,
-	.resume		= gpcv2_wakeup_source_restore,
-};
-
-static int imx_gpcv2_irq_set_wake(struct irq_data *d, unsigned int on)
-{
-	struct gpcv2_irqchip_data *cd = d->chip_data;
-	unsigned int idx = d->hwirq / 32;
-	unsigned long flags;
-	void __iomem *reg;
-	u32 mask, val;
-
-	raw_spin_lock_irqsave(&cd->rlock, flags);
-	reg = cd->gpc_base + cd->cpu2wakeup + idx * 4;
-	mask = 1 << d->hwirq % 32;
-	val = cd->wakeup_sources[idx];
-
-	cd->wakeup_sources[idx] = on ? (val & ~mask) : (val | mask);
-	raw_spin_unlock_irqrestore(&cd->rlock, flags);
-
-	/*
-	 * Do *not* call into the parent, as the GIC doesn't have any
-	 * wake-up facility...
-	 */
-
-	return 0;
-}
-
 static void imx_gpcv2_irq_unmask(struct irq_data *d)
 {
 	struct gpcv2_irqchip_data *cd = d->chip_data;
@@ -140,11 +85,11 @@ static struct irq_chip gpcv2_irqchip_data_chip = {
 	.irq_eoi		= irq_chip_eoi_parent,
 	.irq_mask		= imx_gpcv2_irq_mask,
 	.irq_unmask		= imx_gpcv2_irq_unmask,
-	.irq_set_wake		= imx_gpcv2_irq_set_wake,
 	.irq_retrigger		= irq_chip_retrigger_hierarchy,
 #ifdef CONFIG_SMP
 	.irq_set_affinity	= irq_chip_set_affinity_parent,
 #endif
+	.flags			= IRQCHIP_SKIP_SET_WAKE | IRQCHIP_MASK_ON_SUSPEND,
 };

 static int imx_gpcv2_domain_xlate(struct irq_domain *domain,
@@ -253,7 +198,6 @@ static int __init imx_gpcv2_irqchip_init(struct device_node *node,
 	for (i = 0; i < IMR_NUM; i++) {
 		writel_relaxed(~0, cd->gpc_base + GPC_IMR1_CORE0 + i * 4);
 		writel_relaxed(~0, cd->gpc_base + GPC_IMR1_CORE1 + i * 4);
-		cd->wakeup_sources[i] = ~0;
 	}

 	/* Let CORE0 as the default CPU to wake up by GPC */
@@ -267,7 +211,6 @@ static int __init imx_gpcv2_irqchip_init(struct device_node *node,
 	writel_relaxed(~0x1, cd->gpc_base + cd->cpu2wakeup);

 	imx_gpcv2_instance = cd;
-	register_syscore_ops(&imx_gpcv2_syscore_ops);

 	return 0;
 }
--
2.5.0.rc2




From balbi at ti.com  Wed Aug 26 12:38:20 2015
From: balbi at ti.com (Felipe Balbi)
Date: Wed, 26 Aug 2015 14:38:20 -0500
Subject: CONFIG_DEBUG_SHIRQ and PM
In-Reply-To: <CAAEAJfCY1BRuoQCWfD2pCq36E54vDB5Coy2S7rz3RfL2BVLGaw@mail.gmail.com>
References: <20150825195830.GH27534@saruman.tx.rr.com>
 <CAAEAJfCY1BRuoQCWfD2pCq36E54vDB5Coy2S7rz3RfL2BVLGaw@mail.gmail.com>
Message-ID: <20150826193820.GT14625@saruman.tx.rr.com>

Hi,

On Wed, Aug 26, 2015 at 04:29:52PM -0300, Ezequiel Garcia wrote:
> Felipe,
> 
> On 25 August 2015 at 16:58, Felipe Balbi <balbi at ti.com> wrote:
> > Hi Ingo,
> >
> > I'm facing an issue with CONFIG_DEBUG_SHIRQ and pm_runtime when using
> > devm_request_*irq().
> >
> 
> I may be jumping on the gun here, but I believe here's your problem.
> Using devm_request_irq with shared IRQs is not a good idea.
> 
> Or at least, it forces you to handle interrupts after your device
> is _completely_ removed (e.g. your IRQ cookie could be bogus).
> 
> AFAICS, the CONFIG_DEBUG_SHIRQ option is just triggering a couple
> spurious interrupts, that are expected to happen anyway.
> 
> Your IRQ is shared, and so you may get any IRQ at any time,
> coming from another device (not yours).
> 
> So, if I'm right, my suggestion is simple: use request_irq/free_irq
> and free your IRQ before you disable your clocks, remove your device,
> etc.

yeah, that's just a workaround though. Specially with IRQ flags coming
from DT, driver might have no knowledge that its IRQ is shared to start
with.

Besides, removing devm_* is just a workaround to the real problem. It
seems, to me at least, that drivers shouldn't be calling
pm_runtime_put_sync(); pm_runtime_disable() from their ->remove(),
rather the bus driver should be responsible for doing so; much
usb_bus_type and pci_bus_type do. Of course, this has the side effect of
requiring buses to make sure that by the time ->probe() is called, that
device's clocks are stable and running and the device is active.

However, that's not done today for the platform_bus_type and, frankly,
that would be somewhat of a complex problem to solve, considering that
different SoCs integrate IPs the way they want.

Personally, I think removing devm_* is but a workaround to the real
thing we're dealing with.

-- 
balbi
-------------- next part --------------
A non-text attachment was scrubbed...
Name: signature.asc
Type: application/pgp-signature
Size: 819 bytes
Desc: Digital signature
URL: <http://lists.infradead.org/pipermail/linux-arm-kernel/attachments/20150826/b828fd38/attachment.sig>

From agross at codeaurora.org  Wed Aug 26 12:42:45 2015
From: agross at codeaurora.org (Andy Gross)
Date: Wed, 26 Aug 2015 14:42:45 -0500
Subject: [PATCH v2] soc: qcom: smd: Use correct remote processor ID
Message-ID: <1440618165-9410-1-git-send-email-agross@codeaurora.org>

This patch fixes SMEM addressing issues when remote processors need to use
secure SMEM partitions.

Signed-off-by: Andy Gross <agross at codeaurora.org>
---
 .../devicetree/bindings/soc/qcom/qcom,smd.txt      |    6 ++++++
 drivers/soc/qcom/smd.c                             |   15 +++++++++++----
 2 files changed, 17 insertions(+), 4 deletions(-)

diff --git a/Documentation/devicetree/bindings/soc/qcom/qcom,smd.txt b/Documentation/devicetree/bindings/soc/qcom/qcom,smd.txt
index f65c76d..97d9b3e 100644
--- a/Documentation/devicetree/bindings/soc/qcom/qcom,smd.txt
+++ b/Documentation/devicetree/bindings/soc/qcom/qcom,smd.txt
@@ -37,6 +37,12 @@ The edge is described by the following properties:
 	Definition: the identifier of the remote processor in the smd channel
 		    allocation table
 
+- qcom,remote-pid:
+	Usage: optional
+	Value type: <u32>
+	Definition: the identifier for the remote processor as known by the rest
+		    of the system.
+
 = SMD DEVICES
 
 In turn, subnodes of the "edges" represent devices tied to SMD channels on that
diff --git a/drivers/soc/qcom/smd.c b/drivers/soc/qcom/smd.c
index 327adcf..5706a81 100644
--- a/drivers/soc/qcom/smd.c
+++ b/drivers/soc/qcom/smd.c
@@ -111,6 +111,7 @@ struct qcom_smd_edge {
 	struct qcom_smd *smd;
 	struct device_node *of_node;
 	unsigned edge_id;
+	unsigned remote_pid;
 
 	int irq;
 
@@ -572,7 +573,7 @@ static irqreturn_t qcom_smd_edge_intr(int irq, void *data)
 	 * have to scan if the amount of available space in smem have changed
 	 * since last scan.
 	 */
-	available = qcom_smem_get_free_space(edge->edge_id);
+	available = qcom_smem_get_free_space(edge->remote_pid);
 	if (available != edge->smem_available) {
 		edge->smem_available = available;
 		edge->need_rescan = true;
@@ -976,7 +977,8 @@ static struct qcom_smd_channel *qcom_smd_create_channel(struct qcom_smd_edge *ed
 	spin_lock_init(&channel->recv_lock);
 	init_waitqueue_head(&channel->fblockread_event);
 
-	ret = qcom_smem_get(edge->edge_id, smem_info_item, (void **)&info, &info_size);
+	ret = qcom_smem_get(edge->remote_pid, smem_info_item, (void **)&info,
+			    &info_size);
 	if (ret)
 		goto free_name_and_channel;
 
@@ -997,7 +999,8 @@ static struct qcom_smd_channel *qcom_smd_create_channel(struct qcom_smd_edge *ed
 		goto free_name_and_channel;
 	}
 
-	ret = qcom_smem_get(edge->edge_id, smem_fifo_item, &fifo_base, &fifo_size);
+	ret = qcom_smem_get(edge->remote_pid, smem_fifo_item, &fifo_base,
+			    &fifo_size);
 	if (ret)
 		goto free_name_and_channel;
 
@@ -1041,7 +1044,7 @@ static void qcom_discover_channels(struct qcom_smd_edge *edge)
 	int i;
 
 	for (tbl = 0; tbl < SMD_ALLOC_TBL_COUNT; tbl++) {
-		ret = qcom_smem_get(edge->edge_id,
+		ret = qcom_smem_get(edge->remote_pid,
 				    smem_items[tbl].alloc_tbl_id,
 				    (void **)&alloc_tbl,
 				    NULL);
@@ -1184,6 +1187,10 @@ static int qcom_smd_parse_edge(struct device *dev,
 		return -EINVAL;
 	}
 
+	edge->remote_pid = QCOM_SMEM_HOST_ANY;
+	key = "qcom,remote-pid";
+	of_property_read_u32(node, key, &edge->remote_pid);
+
 	syscon_np = of_parse_phandle(node, "qcom,ipc", 0);
 	if (!syscon_np) {
 		dev_err(dev, "no qcom,ipc node\n");
-- 
The Qualcomm Innovation Center, Inc. is a member of the Code Aurora Forum,
hosted by The Linux Foundation



From ezequiel at vanguardiasur.com.ar  Wed Aug 26 12:53:27 2015
From: ezequiel at vanguardiasur.com.ar (Ezequiel Garcia)
Date: Wed, 26 Aug 2015 16:53:27 -0300
Subject: CONFIG_DEBUG_SHIRQ and PM
In-Reply-To: <20150826193820.GT14625@saruman.tx.rr.com>
References: <20150825195830.GH27534@saruman.tx.rr.com>
 <CAAEAJfCY1BRuoQCWfD2pCq36E54vDB5Coy2S7rz3RfL2BVLGaw@mail.gmail.com>
 <20150826193820.GT14625@saruman.tx.rr.com>
Message-ID: <CAAEAJfAPVgxhRnfYJYzebFJDRJ4Ooam6n+0B5HJ-+uLJ0exTLA@mail.gmail.com>

On 26 August 2015 at 16:38, Felipe Balbi <balbi at ti.com> wrote:
> Hi,
>
> On Wed, Aug 26, 2015 at 04:29:52PM -0300, Ezequiel Garcia wrote:
>> Felipe,
>>
>> On 25 August 2015 at 16:58, Felipe Balbi <balbi at ti.com> wrote:
>> > Hi Ingo,
>> >
>> > I'm facing an issue with CONFIG_DEBUG_SHIRQ and pm_runtime when using
>> > devm_request_*irq().
>> >
>>
>> I may be jumping on the gun here, but I believe here's your problem.
>> Using devm_request_irq with shared IRQs is not a good idea.
>>
>> Or at least, it forces you to handle interrupts after your device
>> is _completely_ removed (e.g. your IRQ cookie could be bogus).
>>
>> AFAICS, the CONFIG_DEBUG_SHIRQ option is just triggering a couple
>> spurious interrupts, that are expected to happen anyway.
>>
>> Your IRQ is shared, and so you may get any IRQ at any time,
>> coming from another device (not yours).
>>
>> So, if I'm right, my suggestion is simple: use request_irq/free_irq
>> and free your IRQ before you disable your clocks, remove your device,
>> etc.
>
> yeah, that's just a workaround though. Specially with IRQ flags coming
> from DT, driver might have no knowledge that its IRQ is shared to start
> with.
>

Really? Is there any way the DT can set the IRQF_SHARED flag?
The caller of devm_request_irq / request_irq needs to pass the irqflags,
so I'd say the driver is perfectly aware of the IRQ being shared or not.

Maybe you can clarify what I'm missing here.

> Besides, removing devm_* is just a workaround to the real problem. It
> seems, to me at least, that drivers shouldn't be calling
> pm_runtime_put_sync(); pm_runtime_disable() from their ->remove(),
> rather the bus driver should be responsible for doing so; much
> usb_bus_type and pci_bus_type do. Of course, this has the side effect of
> requiring buses to make sure that by the time ->probe() is called, that
> device's clocks are stable and running and the device is active.
>
> However, that's not done today for the platform_bus_type and, frankly,
> that would be somewhat of a complex problem to solve, considering that
> different SoCs integrate IPs the way they want.
>
> Personally, I think removing devm_* is but a workaround to the real
> thing we're dealing with.
>

I don't see any problems here: if your interrupt is shared, then you must
be prepared to handle it any time, coming from any sources (not only
your device). And CONFIG_DEBUG_SHIRQ does exactly that, in order to
make sure all the drivers passing IRQF_SHARED comply with that rule.

So you either avoid using devm_request_irq, or you prepare your handler
accordingly to be ready to handle an interrupt _any time_.

-- 
Ezequiel Garc?a, VanguardiaSur
www.vanguardiasur.com.ar


From olof at lixom.net  Wed Aug 26 13:00:16 2015
From: olof at lixom.net (Olof Johansson)
Date: Wed, 26 Aug 2015 13:00:16 -0700
Subject: [PATCH 2/5] ARM: NSP: add minimal Northstar Plus device tree
In-Reply-To: <55DE144A.4090202@broadcom.com>
References: <1440092804-25726-1-git-send-email-jonmason@broadcom.com>
 <CAOesGMhE40_mfZCD2PqcTObE_Gz_6rKFwhf3-6kZY4n9Yxn2rQ@mail.gmail.com>
 <55DE144A.4090202@broadcom.com>
Message-ID: <CAOesGMix12spKq+UN=zkZ7AZOJgD76Cqm4gvebaneBXVwNgZLw@mail.gmail.com>

Hi,



On Wed, Aug 26, 2015 at 12:32 PM, Scott Branden <sbranden at broadcom.com> wrote:
> Hi Olof,
>
> Comments inline.
>
> On 15-08-25 04:36 PM, Olof Johansson wrote:
>>
>> Hi,
>>
>> I'm not sure what the strategy behind your cc:ing on this patch set
>> is. I only got a couple of them in my inbox, and this one wasn't one
>> of them. :)
>>
>> On Thu, Aug 20, 2015 at 10:46 AM, Jon Mason <jonmason at broadcom.com> wrote:
>>>
>>> Add a very minimalistic set of Northstar Plus Device Tree files which
>>> describes the SoC and the BCM958625 implementation.  The perpherials
>>> described are:
>>>
>>> ARM Cortex A9 CPU
>>> 2 8250 UARTs
>>> ARM GIC
>>> PL310 L2 Cache
>>> ARM A9 Global timer
>>>
>>> Signed-off-by: Jon Mason <jonmason at broadcom.com>
>>> Signed-off-by: Kapil Hali <kapilh at broadcom.com>
>>> Reviewed-by: Ray Jui <rjui at broadcom.com>
>>> Reviewed-by: Scott Branden <sbranden at broadcom.com>
>>
>>
>> Seeing reviewed-by already attached to a v1 of a patchset has limited
>> value for someone on the outside.
>
>
>>
>> Reviewed-by is one of those tags that has a value that's mostly
>> dependent on who it comes from. By not actually seeing the review and
>> the feedback provided (and revisions made), less data is provided to
>> tell if it's a valuable review or not.
>
> should we start using Ack'd instead then for things that were reviewed
> internally?

Best of all is to do more work in public, including sending the acks
on the list.

If you look around, it's relatively unusual that people post pre-acked
or pre-reviewed patches, even corporate contributors.

>> Also, if you're posting the code you should probably have your name
>> below Kapil's, since you're the one signing off the origin of the
>> code. See Documentation/SubmittingPatches.txt for details on what
>> S-o-b actually means.
>>
>>
>>> --- /dev/null
>>> +++ b/arch/arm/boot/dts/bcm-nsp.dtsi
>>> @@ -0,0 +1,105 @@
>>> +/*
>>> + *  BSD LICENSE
>>> + *
>>> + *  Copyright(c) 2015 Broadcom Corporation.  All rights reserved.
>>> + *
>>> + *  Redistribution and use in source and binary forms, with or without
>>> + *  modification, are permitted provided that the following conditions
>>> + *  are met:
>>> + *
>>> + *    * Redistributions of source code must retain the above copyright
>>> + *      notice, this list of conditions and the following disclaimer.
>>> + *    * Redistributions in binary form must reproduce the above
>>> copyright
>>> + *      notice, this list of conditions and the following disclaimer in
>>> + *      the documentation and/or other materials provided with the
>>> + *      distribution.
>>> + *    * Neither the name of Broadcom Corporation nor the names of its
>>> + *      contributors may be used to endorse or promote products derived
>>> + *      from this software without specific prior written permission.
>>> + *
>>> + *  THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
>>> + *  "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
>>> + *  LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS
>>> FOR
>>> + *  A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
>>> + *  OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT,
>>> INCIDENTAL,
>>> + *  SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
>>> + *  LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF
>>> USE,
>>> + *  DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON
>>> ANY
>>> + *  THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
>>> + *  (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE
>>> USE
>>> + *  OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
>>> + */
>>
>>
>> I'm not sure we've seen BSD-only submissions before. I'll let DT
>> maintainers (or Ian) speak up in case this would cause problems.
>>
>
> Arnd is the one who require new DT content to be BSD licensed.
> We're just following his orders:
>
> http://lkml.iu.edu/hypermail/linux/kernel/1411.1/01109.html

Yeah, we've been asking for (at least) dual GPL/BSD. This was the
first time I noticed BSD-only which is why I brought it up.

I suspect it is not an issue in reality.

>>> +
>>> +#include <dt-bindings/interrupt-controller/arm-gic.h>
>>> +#include <dt-bindings/interrupt-controller/irq.h>
>>> +
>>> +#include "skeleton.dtsi"
>>> +
>>> +/ {
>>> +       compatible = "brcm,nsp";
>>> +       model = "Broadcom Northstar Plus SoC";
>>> +       interrupt-parent = <&gic>;
>>> +
>>> +       cpus {
>>> +               #address-cells = <1>;
>>> +               #size-cells = <0>;
>>> +
>>> +               cpu at 0 {
>>> +                       device_type = "cpu";
>>> +                       compatible = "arm,cortex-a9";
>>> +                       next-level-cache = <&L2>;
>>> +                       reg = <0x0>;
>>> +               };
>>> +       };
>>> +
>>> +       clocks {
>>> +               #address-cells = <1>;
>>> +               #size-cells = <1>;
>>> +               ranges;
>>> +
>>> +               periph_clk: periph_clk {
>>> +                       compatible = "fixed-clock";
>>> +                       #clock-cells = <0>;
>>> +                       clock-frequency = <500000000>;
>>> +               };
>>> +       };
>>> +
>>> +       uart0: serial at 18000300 {
>>> +               compatible = "ns16550a";
>>> +               reg = <0x18000300 0x100>;
>>> +               interrupts = <GIC_SPI 85 IRQ_TYPE_LEVEL_HIGH>;
>>> +               clock-frequency = <62499840>;
>>> +               status = "disabled";
>>> +       };
>>> +
>>> +       uart1: serial at 18000400 {
>>> +               compatible = "ns16550a";
>>> +               reg = <0x18000400 0x100>;
>>> +               interrupts = <GIC_SPI 85 IRQ_TYPE_LEVEL_HIGH>;
>>> +               clock-frequency = <62499840>;
>>> +               status = "disabled";
>>> +       };
>>> +
>>> +       gic: interrupt-controller at 19021000 {
>>> +               compatible = "arm,cortex-a9-gic";
>>> +               #interrupt-cells = <3>;
>>> +               #address-cells = <0>;
>>> +               interrupt-controller;
>>> +               reg = <0x19021000 0x1000>,
>>> +                     <0x19020100 0x100>;
>>> +       };
>>> +
>>> +       L2: l2-cache {
>>> +               compatible = "arm,pl310-cache";
>>> +               reg = <0x19022000 0x1000>;
>>> +               cache-unified;
>>> +               cache-level = <2>;
>>> +       };
>>> +
>>> +       timer at 19020200 {
>>> +               compatible = "arm,cortex-a9-global-timer";
>>> +               reg = <0x19020200 0x100>;
>>> +               interrupts = <GIC_PPI 11 IRQ_TYPE_LEVEL_HIGH>;
>>> +               clocks = <&periph_clk>;
>>> +       };
>>> +};
>>> diff --git a/arch/arm/boot/dts/bcm958625k.dts
>>> b/arch/arm/boot/dts/bcm958625k.dts
>>> new file mode 100644
>>> index 0000000..a1bc151
>>> --- /dev/null
>>> +++ b/arch/arm/boot/dts/bcm958625k.dts
>>> @@ -0,0 +1,57 @@
>>> +/*
>>> + *  BSD LICENSE
>>> + *
>>> + *  Copyright(c) 2015 Broadcom Corporation.  All rights reserved.
>>> + *
>>> + *  Redistribution and use in source and binary forms, with or without
>>> + *  modification, are permitted provided that the following conditions
>>> + *  are met:
>>> + *
>>> + *    * Redistributions of source code must retain the above copyright
>>> + *      notice, this list of conditions and the following disclaimer.
>>> + *    * Redistributions in binary form must reproduce the above
>>> copyright
>>> + *      notice, this list of conditions and the following disclaimer in
>>> + *      the documentation and/or other materials provided with the
>>> + *      distribution.
>>> + *    * Neither the name of Broadcom Corporation nor the names of its
>>> + *      contributors may be used to endorse or promote products derived
>>> + *      from this software without specific prior written permission.
>>> + *
>>> + *  THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
>>> + *  "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
>>> + *  LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS
>>> FOR
>>> + *  A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
>>> + *  OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT,
>>> INCIDENTAL,
>>> + *  SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
>>> + *  LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF
>>> USE,
>>> + *  DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON
>>> ANY
>>> + *  THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
>>> + *  (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE
>>> USE
>>> + *  OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
>>> + */
>>> +
>>> +/dts-v1/;
>>> +
>>> +#include "bcm-nsp.dtsi"
>>> +
>>> +/ {
>>> +       model = "NorthStar Plus SVK (BCM958625K)";
>>> +       compatible = "brcm,bcm58625", "brcm,nsp";
>>> +
>>> +       aliases {
>>> +               serial0 = &uart0;
>>> +               serial1 = &uart1;
>>> +       };
>>> +
>>> +       chosen {
>>> +               stdout-path = "serial0:115200n8";
>>> +       };
>>
>>
>> No way to mount a root filesystem yet? How much work remains for that
>> to be possible, and what's the plan for that?
>>
> This is the bare bones DTS.  I'm sure Jon will activate NAND once tested -
> it "should" work with the same driver that Cygnus and STB chips use.

Ok, good. I've found there to be a slight drawback in upstreaming a
system dtb before there's basic device support since it can't be used
to determine whether a board is expected to have basic functionality
or not.

As long as it's in progress there's no big reason to hold off though.


-Olof


From olof at lixom.net  Wed Aug 26 13:02:18 2015
From: olof at lixom.net (Olof Johansson)
Date: Wed, 26 Aug 2015 13:02:18 -0700
Subject: [PATCH 5/5] MAINTAINERS: add entry for the Broadcom Northstar
 Plus SoCs
In-Reply-To: <20150826190046.GB4171@broadcom.com>
References: <1440092861-25825-1-git-send-email-jonmason@broadcom.com>
 <CAOesGMioBQY9qy-S8kMJmo_=B6-KZiUkd=Ns1Uo2dGu0BiqppQ@mail.gmail.com>
 <20150826190046.GB4171@broadcom.com>
Message-ID: <CAOesGMhS6vA_MToAYhU18Dwj=QXdmf3MVSwo33qR2kYJ=qrh5g@mail.gmail.com>

On Wed, Aug 26, 2015 at 12:00 PM, Jon Mason <jonmason at broadcom.com> wrote:
> On Tue, Aug 25, 2015 at 04:42:42PM -0700, Olof Johansson wrote:
>> On Thu, Aug 20, 2015 at 10:47 AM, Jon Mason <jonmason at broadcom.com> wrote:
>> > Modify the iProc MAINTAINER to cover the Nortstar Plus SoCs, and add me
>> > to the list of people responsible for it.
>>
>> That's not what this patch does. It removes CYGNUS from the
>> description as well. Hmm?
>
> iProc is a family of SoCs that includes Cygnus, Northstar (BCM5301X),
> Northstar Plus, Northstar 2, and a number of other platforms.  I
> removed the "Cygnus" for that reason.

Ok, feel free to add that info to the commit message in case others
see the same and wonder what happened.

>> I'm also not a fan of the complex patterns, but that's more of a
>> bikeshedding comment. Does Broadcom really not have a bit more
>> systematic naming than this? :)
>
> Per Florian's comment, it's a bit of a mess internally.

Unfortunate. Hopefully the chaotic product naming doesn't have to leak
quite everywhere in the tree and things can be referred to by family,
etc. :)


-Olof


From balbi at ti.com  Wed Aug 26 13:03:00 2015
From: balbi at ti.com (Felipe Balbi)
Date: Wed, 26 Aug 2015 15:03:00 -0500
Subject: CONFIG_DEBUG_SHIRQ and PM
In-Reply-To: <CAAEAJfAPVgxhRnfYJYzebFJDRJ4Ooam6n+0B5HJ-+uLJ0exTLA@mail.gmail.com>
References: <20150825195830.GH27534@saruman.tx.rr.com>
 <CAAEAJfCY1BRuoQCWfD2pCq36E54vDB5Coy2S7rz3RfL2BVLGaw@mail.gmail.com>
 <20150826193820.GT14625@saruman.tx.rr.com>
 <CAAEAJfAPVgxhRnfYJYzebFJDRJ4Ooam6n+0B5HJ-+uLJ0exTLA@mail.gmail.com>
Message-ID: <20150826200300.GU14625@saruman.tx.rr.com>

On Wed, Aug 26, 2015 at 04:53:27PM -0300, Ezequiel Garcia wrote:
> On 26 August 2015 at 16:38, Felipe Balbi <balbi at ti.com> wrote:
> > Hi,
> >
> > On Wed, Aug 26, 2015 at 04:29:52PM -0300, Ezequiel Garcia wrote:
> >> Felipe,
> >>
> >> On 25 August 2015 at 16:58, Felipe Balbi <balbi at ti.com> wrote:
> >> > Hi Ingo,
> >> >
> >> > I'm facing an issue with CONFIG_DEBUG_SHIRQ and pm_runtime when using
> >> > devm_request_*irq().
> >> >
> >>
> >> I may be jumping on the gun here, but I believe here's your problem.
> >> Using devm_request_irq with shared IRQs is not a good idea.
> >>
> >> Or at least, it forces you to handle interrupts after your device
> >> is _completely_ removed (e.g. your IRQ cookie could be bogus).
> >>
> >> AFAICS, the CONFIG_DEBUG_SHIRQ option is just triggering a couple
> >> spurious interrupts, that are expected to happen anyway.
> >>
> >> Your IRQ is shared, and so you may get any IRQ at any time,
> >> coming from another device (not yours).
> >>
> >> So, if I'm right, my suggestion is simple: use request_irq/free_irq
> >> and free your IRQ before you disable your clocks, remove your device,
> >> etc.
> >
> > yeah, that's just a workaround though. Specially with IRQ flags coming
> > from DT, driver might have no knowledge that its IRQ is shared to start
> > with.
> >
> 
> Really? Is there any way the DT can set the IRQF_SHARED flag?
> The caller of devm_request_irq / request_irq needs to pass the irqflags,
> so I'd say the driver is perfectly aware of the IRQ being shared or not.
> 
> Maybe you can clarify what I'm missing here.

hmm, that's true. Now that I look at it, DT can pass triggering flags.

> > Besides, removing devm_* is just a workaround to the real problem. It
> > seems, to me at least, that drivers shouldn't be calling
> > pm_runtime_put_sync(); pm_runtime_disable() from their ->remove(),
> > rather the bus driver should be responsible for doing so; much
> > usb_bus_type and pci_bus_type do. Of course, this has the side effect of
> > requiring buses to make sure that by the time ->probe() is called, that
> > device's clocks are stable and running and the device is active.
> >
> > However, that's not done today for the platform_bus_type and, frankly,
> > that would be somewhat of a complex problem to solve, considering that
> > different SoCs integrate IPs the way they want.
> >
> > Personally, I think removing devm_* is but a workaround to the real
> > thing we're dealing with.
> >
> 
> I don't see any problems here: if your interrupt is shared, then you must
> be prepared to handle it any time, coming from any sources (not only
> your device). And CONFIG_DEBUG_SHIRQ does exactly that, in order to
> make sure all the drivers passing IRQF_SHARED comply with that rule.

you need to be sure of that with non-shared IRQs anyway. Also, an IRQ
which isn't shared in SoC A, might become shared in SoC B which uses the
same IP.

> So you either avoid using devm_request_irq, or you prepare your handler
> accordingly to be ready to handle an interrupt _any time_.

the handler is ready to handle at any time, what isn't correct is the
fact that clocks get gated before IRQ is freed.

There should be no such special case as "if your handler is shared,
don't use devm_request_*irq()" because if we just disable PM_RUNTIME, it
works as expected anyway.

-- 
balbi
-------------- next part --------------
A non-text attachment was scrubbed...
Name: signature.asc
Type: application/pgp-signature
Size: 819 bytes
Desc: Digital signature
URL: <http://lists.infradead.org/pipermail/linux-arm-kernel/attachments/20150826/e9f85e8f/attachment-0001.sig>

From olof at lixom.net  Wed Aug 26 13:04:35 2015
From: olof at lixom.net (Olof Johansson)
Date: Wed, 26 Aug 2015 13:04:35 -0700
Subject: [PATCH 2/5] ARM: NSP: add minimal Northstar Plus device tree
In-Reply-To: <20150826184009.GA4171@broadcom.com>
References: <1440092804-25726-1-git-send-email-jonmason@broadcom.com>
 <CAOesGMhE40_mfZCD2PqcTObE_Gz_6rKFwhf3-6kZY4n9Yxn2rQ@mail.gmail.com>
 <20150826184009.GA4171@broadcom.com>
Message-ID: <CAOesGMif9Bxx=K5GQqkiJKg2SD7QvgU8=2PQa65mEbJHnhNQ8Q@mail.gmail.com>

On Wed, Aug 26, 2015 at 11:40 AM, Jon Mason <jonmason at broadcom.com> wrote:
> On Tue, Aug 25, 2015 at 04:36:45PM -0700, Olof Johansson wrote:
>> Hi,
>>
>> I'm not sure what the strategy behind your cc:ing on this patch set
>> is. I only got a couple of them in my inbox, and this one wasn't one
>> of them. :)
>
> I sent them to the people listed as maintainers in get_maintainer.pl.
> It didn't seem to include you in all of them, but I thought the
> mailing list would be enough of a catch all.  My apologies.  I'll CC
> everyone listed as a maintainer on all of the patches in the future.

No worries. Just pointing it out since you asked me to look at the
patches and, well, I hadn't received them all. :)

>> On Thu, Aug 20, 2015 at 10:46 AM, Jon Mason <jonmason at broadcom.com> wrote:
>> > Add a very minimalistic set of Northstar Plus Device Tree files which
>> > describes the SoC and the BCM958625 implementation.  The perpherials
>> > described are:
>> >
>> > ARM Cortex A9 CPU
>> > 2 8250 UARTs
>> > ARM GIC
>> > PL310 L2 Cache
>> > ARM A9 Global timer
>> >
>> > Signed-off-by: Jon Mason <jonmason at broadcom.com>
>> > Signed-off-by: Kapil Hali <kapilh at broadcom.com>
>> > Reviewed-by: Ray Jui <rjui at broadcom.com>
>> > Reviewed-by: Scott Branden <sbranden at broadcom.com>
>>
>> Seeing reviewed-by already attached to a v1 of a patchset has limited
>> value for someone on the outside.
>>
>> Reviewed-by is one of those tags that has a value that's mostly
>> dependent on who it comes from. By not actually seeing the review and
>> the feedback provided (and revisions made), less data is provided to
>> tell if it's a valuable review or not.
>>
>> Also, if you're posting the code you should probably have your name
>> below Kapil's, since you're the one signing off the origin of the
>> code. See Documentation/SubmittingPatches.txt for details on what
>> S-o-b actually means.
>
> We worked on it together, but I'll be happy to reorder as you suggest.
>
>>
>>
>> > --- /dev/null
>> > +++ b/arch/arm/boot/dts/bcm-nsp.dtsi
>> > @@ -0,0 +1,105 @@
>> > +/*
>> > + *  BSD LICENSE
>> > + *
>> > + *  Copyright(c) 2015 Broadcom Corporation.  All rights reserved.
>> > + *
>> > + *  Redistribution and use in source and binary forms, with or without
>> > + *  modification, are permitted provided that the following conditions
>> > + *  are met:
>> > + *
>> > + *    * Redistributions of source code must retain the above copyright
>> > + *      notice, this list of conditions and the following disclaimer.
>> > + *    * Redistributions in binary form must reproduce the above copyright
>> > + *      notice, this list of conditions and the following disclaimer in
>> > + *      the documentation and/or other materials provided with the
>> > + *      distribution.
>> > + *    * Neither the name of Broadcom Corporation nor the names of its
>> > + *      contributors may be used to endorse or promote products derived
>> > + *      from this software without specific prior written permission.
>> > + *
>> > + *  THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
>> > + *  "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
>> > + *  LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
>> > + *  A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
>> > + *  OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
>> > + *  SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
>> > + *  LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
>> > + *  DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
>> > + *  THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
>> > + *  (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
>> > + *  OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
>> > + */
>>
>> I'm not sure we've seen BSD-only submissions before. I'll let DT
>> maintainers (or Ian) speak up in case this would cause problems.
>
> I was following the precedent in arch/arm/boot/dts/bcm-cygnus.dtsi.
> If this is preferred to be GPL v2, then I will happily comply.

No, we'd rather have BSD-only than GPL-only, so keeping it as it is
should be OK.

>> > +       chosen {
>> > +               stdout-path = "serial0:115200n8";
>> > +       };
>>
>> No way to mount a root filesystem yet? How much work remains for that
>> to be possible, and what's the plan for that?
>
> It mounts rootfs.  I am adding the rootfs to the kernel and device
> tree blob via the u-boot mkimage command.  It boots all the way to
> shell without issue.

Sure, any system with memory can use ramdisk for root, that's not what I meant.

Still, based on post from Scott it sounds like NAND support isn't far away.


-Olof


From ezequiel at vanguardiasur.com.ar  Wed Aug 26 13:15:51 2015
From: ezequiel at vanguardiasur.com.ar (Ezequiel Garcia)
Date: Wed, 26 Aug 2015 17:15:51 -0300
Subject: CONFIG_DEBUG_SHIRQ and PM
In-Reply-To: <20150826200300.GU14625@saruman.tx.rr.com>
References: <20150825195830.GH27534@saruman.tx.rr.com>
 <CAAEAJfCY1BRuoQCWfD2pCq36E54vDB5Coy2S7rz3RfL2BVLGaw@mail.gmail.com>
 <20150826193820.GT14625@saruman.tx.rr.com>
 <CAAEAJfAPVgxhRnfYJYzebFJDRJ4Ooam6n+0B5HJ-+uLJ0exTLA@mail.gmail.com>
 <20150826200300.GU14625@saruman.tx.rr.com>
Message-ID: <CAAEAJfB3iiRENEKm6xx-kLae5AR6BV0XVo0KNkb8-okvLjhFhg@mail.gmail.com>

On 26 August 2015 at 17:03, Felipe Balbi <balbi at ti.com> wrote:
> On Wed, Aug 26, 2015 at 04:53:27PM -0300, Ezequiel Garcia wrote:
>> On 26 August 2015 at 16:38, Felipe Balbi <balbi at ti.com> wrote:
>> > Hi,
>> >
>> > On Wed, Aug 26, 2015 at 04:29:52PM -0300, Ezequiel Garcia wrote:
>> >> Felipe,
>> >>
>> >> On 25 August 2015 at 16:58, Felipe Balbi <balbi at ti.com> wrote:
>> >> > Hi Ingo,
>> >> >
>> >> > I'm facing an issue with CONFIG_DEBUG_SHIRQ and pm_runtime when using
>> >> > devm_request_*irq().
>> >> >
>> >>
>> >> I may be jumping on the gun here, but I believe here's your problem.
>> >> Using devm_request_irq with shared IRQs is not a good idea.
>> >>
>> >> Or at least, it forces you to handle interrupts after your device
>> >> is _completely_ removed (e.g. your IRQ cookie could be bogus).
>> >>
>> >> AFAICS, the CONFIG_DEBUG_SHIRQ option is just triggering a couple
>> >> spurious interrupts, that are expected to happen anyway.
>> >>
>> >> Your IRQ is shared, and so you may get any IRQ at any time,
>> >> coming from another device (not yours).
>> >>
>> >> So, if I'm right, my suggestion is simple: use request_irq/free_irq
>> >> and free your IRQ before you disable your clocks, remove your device,
>> >> etc.
>> >
>> > yeah, that's just a workaround though. Specially with IRQ flags coming
>> > from DT, driver might have no knowledge that its IRQ is shared to start
>> > with.
>> >
>>
>> Really? Is there any way the DT can set the IRQF_SHARED flag?
>> The caller of devm_request_irq / request_irq needs to pass the irqflags,
>> so I'd say the driver is perfectly aware of the IRQ being shared or not.
>>
>> Maybe you can clarify what I'm missing here.
>
> hmm, that's true. Now that I look at it, DT can pass triggering flags.
>
>> > Besides, removing devm_* is just a workaround to the real problem. It
>> > seems, to me at least, that drivers shouldn't be calling
>> > pm_runtime_put_sync(); pm_runtime_disable() from their ->remove(),
>> > rather the bus driver should be responsible for doing so; much
>> > usb_bus_type and pci_bus_type do. Of course, this has the side effect of
>> > requiring buses to make sure that by the time ->probe() is called, that
>> > device's clocks are stable and running and the device is active.
>> >
>> > However, that's not done today for the platform_bus_type and, frankly,
>> > that would be somewhat of a complex problem to solve, considering that
>> > different SoCs integrate IPs the way they want.
>> >
>> > Personally, I think removing devm_* is but a workaround to the real
>> > thing we're dealing with.
>> >
>>
>> I don't see any problems here: if your interrupt is shared, then you must
>> be prepared to handle it any time, coming from any sources (not only
>> your device). And CONFIG_DEBUG_SHIRQ does exactly that, in order to
>> make sure all the drivers passing IRQF_SHARED comply with that rule.
>
> you need to be sure of that with non-shared IRQs anyway.

Not entirely. If your IRQ is not shared, then you usually have a register
to enable or unmask your peripheral interrupts. So the driver is in control
of when it will get interrupts.

If the IRQ is shared, this won't do. This is what I mean by "shared IRQs
must be prepared to receive an interrupt any time", in the sense that
the driver has no way of preventing IRQs (because they may be
coming from any source).

In the same sense, shared IRQs handlers need to double-check
the IRQ is coming to the current device by checking some IRQ
status register to see if there's pending work.

> Also, an IRQ
> which isn't shared in SoC A, might become shared in SoC B which uses the
> same IP.
>
>> So you either avoid using devm_request_irq, or you prepare your handler
>> accordingly to be ready to handle an interrupt _any time_.
>
> the handler is ready to handle at any time, what isn't correct is the
> fact that clocks get gated before IRQ is freed.
>
> There should be no such special case as "if your handler is shared,
> don't use devm_request_*irq()" because if we just disable PM_RUNTIME, it
> works as expected anyway.
>

Yeah, I meant to say: if you use devm_request_irq with IRQF_SHARED
then you _must_ be prepared to get an IRQ *after* your remove() has
been called.

Let's consider this snippet from tw68:

static irqreturn_t tw68_irq(int irq, void *dev_id)
{
        struct tw68_dev *dev = dev_id;
        u32 status, orig;
        int loop;

        status = orig = tw_readl(TW68_INTSTAT) & dev->pci_irqmask;
        [etc]
}

The IRQ handler accesses the device struct and then
reads through PCI. So if you use devm_request_irq
you need to make sure the device struct is still allocated
after remove(), and the PCI read won't stall or crash.

Interestingly, tw68 uses devm_request_irq with IRQF_SHARED :-)

Still, I don't think that's a good idea, since it relies on
the IRQ being freed *before* the device struct.
-- 
Ezequiel Garc?a, VanguardiaSur
www.vanguardiasur.com.ar


From balbi at ti.com  Wed Aug 26 13:24:29 2015
From: balbi at ti.com (Felipe Balbi)
Date: Wed, 26 Aug 2015 15:24:29 -0500
Subject: CONFIG_DEBUG_SHIRQ and PM
In-Reply-To: <CAAEAJfB3iiRENEKm6xx-kLae5AR6BV0XVo0KNkb8-okvLjhFhg@mail.gmail.com>
References: <20150825195830.GH27534@saruman.tx.rr.com>
 <CAAEAJfCY1BRuoQCWfD2pCq36E54vDB5Coy2S7rz3RfL2BVLGaw@mail.gmail.com>
 <20150826193820.GT14625@saruman.tx.rr.com>
 <CAAEAJfAPVgxhRnfYJYzebFJDRJ4Ooam6n+0B5HJ-+uLJ0exTLA@mail.gmail.com>
 <20150826200300.GU14625@saruman.tx.rr.com>
 <CAAEAJfB3iiRENEKm6xx-kLae5AR6BV0XVo0KNkb8-okvLjhFhg@mail.gmail.com>
Message-ID: <20150826202429.GV14625@saruman.tx.rr.com>

Hi,

On Wed, Aug 26, 2015 at 05:15:51PM -0300, Ezequiel Garcia wrote:

<snip>

> >> be prepared to handle it any time, coming from any sources (not only
> >> your device). And CONFIG_DEBUG_SHIRQ does exactly that, in order to
> >> make sure all the drivers passing IRQF_SHARED comply with that rule.
> >
> > you need to be sure of that with non-shared IRQs anyway.
> 
> Not entirely. If your IRQ is not shared, then you usually have a register
> to enable or unmask your peripheral interrupts. So the driver is in control
> of when it will get interrupts.
> 
> If the IRQ is shared, this won't do. This is what I mean by "shared IRQs
> must be prepared to receive an interrupt any time", in the sense that
> the driver has no way of preventing IRQs (because they may be
> coming from any source).

right, the problem is much less likely on non-shared lines but the fine
that a line is shared or not is a function of HW integration, not the
e.g. USB Controller, so that knowledge really doesn't fit the driver in
a sense.

We might as well get rid of IRQF_SHARED and assume all lines are
shareable.

> In the same sense, shared IRQs handlers need to double-check
> the IRQ is coming to the current device by checking some IRQ
> status register to see if there's pending work.

you should the status register even on non-shared IRQs to catch spurious
right ?

> > Also, an IRQ
> > which isn't shared in SoC A, might become shared in SoC B which uses the
> > same IP.
> >
> >> So you either avoid using devm_request_irq, or you prepare your handler
> >> accordingly to be ready to handle an interrupt _any time_.
> >
> > the handler is ready to handle at any time, what isn't correct is the
> > fact that clocks get gated before IRQ is freed.
> >
> > There should be no such special case as "if your handler is shared,
> > don't use devm_request_*irq()" because if we just disable PM_RUNTIME, it
> > works as expected anyway.
> >
> 
> Yeah, I meant to say: if you use devm_request_irq with IRQF_SHARED
> then you _must_ be prepared to get an IRQ *after* your remove() has
> been called.
> 
> Let's consider this snippet from tw68:
> 
> static irqreturn_t tw68_irq(int irq, void *dev_id)
> {
>         struct tw68_dev *dev = dev_id;
>         u32 status, orig;
>         int loop;
> 
>         status = orig = tw_readl(TW68_INTSTAT) & dev->pci_irqmask;

Now try to read that register when your clock is gated. That's the
problem I'm talking about. Everything about the handler is functioning
correctly; however clocks are gated in ->remove() and free_irq() is
only called *AFTER* ->remove() has returned.

>         [etc]
> }
> 
> The IRQ handler accesses the device struct and then
> reads through PCI. So if you use devm_request_irq
> you need to make sure the device struct is still allocated
> after remove(), and the PCI read won't stall or crash.

dude, that's not the problem I'm talking about. I still have my
private_data around, what I don't have is:

              _            _    
  __ _    ___| | ___   ___| | __
 / _` |  / __| |/ _ \ / __| |/ /
| (_| | | (__| | (_) | (__|   < 
 \__,_|  \___|_|\___/ \___|_|\_\
                                

> Interestingly, tw68 uses devm_request_irq with IRQF_SHARED :-)
> 
> Still, I don't think that's a good idea, since it relies on
> the IRQ being freed *before* the device struct.

that's not an issue at all. If you're using devm_request_irq() you're
likely using devm_kzalloc() for the device struct anyway. Also, you
called devm_kzalloc() before devm_request_irq() so IRQ *will* be freed
before your private data; there's nothing wrong there.

-- 
balbi
-------------- next part --------------
A non-text attachment was scrubbed...
Name: signature.asc
Type: application/pgp-signature
Size: 819 bytes
Desc: Digital signature
URL: <http://lists.infradead.org/pipermail/linux-arm-kernel/attachments/20150826/7edc4eeb/attachment.sig>

From ahs3 at redhat.com  Wed Aug 26 13:30:25 2015
From: ahs3 at redhat.com (Al Stone)
Date: Wed, 26 Aug 2015 14:30:25 -0600
Subject: [PATCH v2 1/5] ACPI: add in a bad_madt_entry() function to
 eventually replace the macro
In-Reply-To: <CAOZdJXXCnb7ChYqh-QYptTQBmfESDPaauThHyu8Dav6Qs_+4Bw@mail.gmail.com>
References: <1440022048-6285-1-git-send-email-al.stone@linaro.org>
 <1440022048-6285-2-git-send-email-al.stone@linaro.org>
 <CAOZdJXXCnb7ChYqh-QYptTQBmfESDPaauThHyu8Dav6Qs_+4Bw@mail.gmail.com>
Message-ID: <55DE21E1.6070700@redhat.com>

On 08/26/2015 09:38 AM, Timur Tabi wrote:
> On Wed, Aug 19, 2015 at 5:07 PM, Al Stone <al.stone at linaro.org> wrote:
>> +                               pr_err("Variable length MADT subtable %d is wrong size: %d\n",
>> +                                      entry->type, entry->length);
>> +                               return 1;
>> +                       }
>> +               }
>> +       } else {
>> +               if (entry->length != len) {
>> +                       pr_err("MADT subtable %d is wrong size: %d\n",
>> +                              len, entry->type);
> 
> Can we make these a little more descriptive?
> 
> pr_err("Variable length MADT subtable type %d is wrong size: %d,
> should be %d\n",
>       entry->type, entry->length, len);
> 
> pr_err("MADT subtable type %d is wrong size: %d, should be %d\n",
>       entry->type, entry->length, len);
> 

Sure.  It's always a fine line between verbose and not enough info.

-- 
ciao,
al
-----------------------------------
Al Stone
Software Engineer
Red Hat, Inc.
ahs3 at redhat.com
-----------------------------------


From linux at arm.linux.org.uk  Wed Aug 26 13:34:46 2015
From: linux at arm.linux.org.uk (Russell King - ARM Linux)
Date: Wed, 26 Aug 2015 21:34:46 +0100
Subject: Prevent list poison values from being mapped by userspace
 processes
In-Reply-To: <CAGXu5jK=xfSpJFk9owMoNg7dybdaap+DWzGy+TPTYDHNb+V1Mg@mail.gmail.com>
References: <CABXk95C=CpeL4mNmS6-jJ-0bMJf6fawwfs6DM1-p8FctTEFbpw@mail.gmail.com>
 <20150821133043.GV7557@n2100.arm.linux.org.uk>
 <CAGXu5jJ8KOoVkx99rrajEEx77Z6zO4TzCXaXkB74zv9QQFuJFw@mail.gmail.com>
 <20150824184709.GE7557@n2100.arm.linux.org.uk>
 <CAGXu5jJFf+9OgnGt_Cx5Q-Pht7LAT7M-sSXftTDORybrr+SECg@mail.gmail.com>
 <20150824191427.GF7557@n2100.arm.linux.org.uk>
 <CAGXu5jLW-nfUr40cit25_GsBrPJ6e0topdBQ1RY6vSm2dBFyDA@mail.gmail.com>
 <20150824193256.GG7557@n2100.arm.linux.org.uk>
 <CAGXu5jK=xfSpJFk9owMoNg7dybdaap+DWzGy+TPTYDHNb+V1Mg@mail.gmail.com>
Message-ID: <20150826203446.GD21084@n2100.arm.linux.org.uk>

On Mon, Aug 24, 2015 at 03:01:06PM -0700, Kees Cook wrote:
> On Mon, Aug 24, 2015 at 12:32 PM, Russell King - ARM Linux
> <linux at arm.linux.org.uk> wrote:
> > That's one way of looking at it.
> >
> > Another way of looking at it is that by looking at their work, and
> > merging their ideas into your own, it becomes an encouragement for
> > working outside of mainline - not only do they get the kernel itself
> > free, but they get their feature merged without themselves doing any
> > work - while some other bugger has to sort out making their code
> > mergable.
> >
> > Therefore, my standard point of view is that if people can't be
> > bothered to talk about their ARM specific kernel features here with
> > a view to having them merged, they are leeching off the efforts of
> > the upstream kernel community, and their code just isn't worth
> > looking at.
> >
> > I hold the same view on "community" kernel trees which don't bother
> > pushing their code upstream as well.
> >
> > Sorry, I'm *not* supporting leeches.
> >
> > I've already been accused this year by one very mistaken individual
> > for not pushing _my_ iMX6 work into community kernel trees - when
> > the work that I do is solely targetted at mainline kernels.  The
> > leeches are going mad, and I'm saying no more to this crap.  If it's
> > not talked about on a recognised mainline kernel mailing list, it
> > doesn't exist, and deserves to be rewritten.
> 
> I certainly see your point, but I'm not sure it serves end users best
> to ignore proven technologies. I am trying to bring up the discussion
> on a mainline list, and it seemed redundant to paste the entire grsec
> forum post here as a starting point. :)

As kernel developers feeding code into mainline, we can't go around
picking "proven technologies" from other people's trees.  Doing that
carries with it risk.

Consider the difference between:

1) Individual A sends their code onto mailing lists for review, asking
   it to be merged.  It gets reviewed by multiple people, gains acks
   and tested-bys, and the proper well established and proven kernel
   submission process is followed.  Individual B merges the code and
   sends it upstream.

2) Individual A merges code into their own tree and publishes it on
   the Internet.  Individual B searches the Internet, finds this code,
   downloads, modifies it a bit to get it to apply, and sends it out
   for review.  It gains acks and tested-bys and eventually B merges
   the code and sends it upstream.

Sometime later, patent and/or copyright lawyers start creating a ruckus
over the code which has been merged.  In each case, where does the bulk
of the blame lie - would it be with individual A or individual B?

My _personal_ view is that in (2), much more of the blame lies on
individual B who _took_ code from individual A, potentially without
their knowledge and merged it into another "project".  Individual A
may share some of the blame too, but they have the ability to say
"I never submitted it to that project."  If lawyers target a project,
then the way that would work is they'd target the project, and leave
the project to fight it out with the next stage along.  (You see this
happening between companies: Company A (re)publishes work which
Company B did.  Company A gets sued.  Company A then has to sue
company B to recover costs and damages.)

As part of the process in (1) above, we require that the _sender_ of
the code signs-off that _submission_, and by doing so, they're basically
asserting that the code conforms with the statements in the DCO and
therefore they are taking the bulk of the responsibility.

To re-iterate the point, if I were to take someone elses code, then
_I_ would have to assert DCO (b) - I'm making that assertion, therefore
I'm the one at the end of the submission path for the project.

So, my view is that DCO (b) carries with it more risk than the other
sub-clauses, irrespective of what the GPL says.


As for my comments about leeching, those are a view that I've held
for well over a decade.  Trees which take from mainline but never
contribute back are trees which leech off the efforts of the many
who do contribute to mainline.  Such trees benefit from mainline, but
do not supply any benefit back to mainline.  I find such trees totally
abhorrent and disgusting, but I _can_ understand that it's human
nature.  Sure, the GPL does not require that code gets contributed
back, but there is a clear moral, ethical and fairness issue here.

In this case, it's more than that though.  Kees, in your comment
above, you talk about "proven technologies" and serving the best
interests of our users.  I think you're totally missing the point
here.  Are users best interests served by having these trees keep
their "proven technologies" to themselves, or are they best served
by having these proven technologies submitted into mainline in a
timely manner?

Consider the recent networking use-after-free bug which is the
subject of these domain patches, and think about this.  If this
"proven technology" was already in mainline and enabled, then this
particular use-after-free would not be a privilege escalation because
with this additional protection against dereference of LIST_POISON*,
there is no way userspace could exploit it.  Sure, they can oops the
kernel, but that's _far_ better than a privilege escalation and
potential undetected information leak.

So, in my mind, it's the leeches which are doing a dis-service to
users, not those of us who spend their time trying to fix the
problems which the leeches have already fixed but failed contribute
back.

It intensely annoys me when I _do_ find out that some feature
(especially bug fixes) has already been created but not fed back,
and I've spent time re-creating it.  It's really a waste of my
time.  That's what leads me to decide that no, I'm not going to
waste even more of my time trying to rip a feature out of a
leeching tree and allow them to have some of the credit for it.

-- 
FTTC broadband for 0.8mile line: currently at 10.5Mbps down 400kbps up
according to speedtest.net.


From ezequiel at vanguardiasur.com.ar  Wed Aug 26 13:36:24 2015
From: ezequiel at vanguardiasur.com.ar (Ezequiel Garcia)
Date: Wed, 26 Aug 2015 17:36:24 -0300
Subject: CONFIG_DEBUG_SHIRQ and PM
In-Reply-To: <20150826202429.GV14625@saruman.tx.rr.com>
References: <20150825195830.GH27534@saruman.tx.rr.com>
 <CAAEAJfCY1BRuoQCWfD2pCq36E54vDB5Coy2S7rz3RfL2BVLGaw@mail.gmail.com>
 <20150826193820.GT14625@saruman.tx.rr.com>
 <CAAEAJfAPVgxhRnfYJYzebFJDRJ4Ooam6n+0B5HJ-+uLJ0exTLA@mail.gmail.com>
 <20150826200300.GU14625@saruman.tx.rr.com>
 <CAAEAJfB3iiRENEKm6xx-kLae5AR6BV0XVo0KNkb8-okvLjhFhg@mail.gmail.com>
 <20150826202429.GV14625@saruman.tx.rr.com>
Message-ID: <CAAEAJfAPB1N-xcz+HbHCcF8JaXAVL05CSwpQGi7ea+114mMpmw@mail.gmail.com>

On 26 August 2015 at 17:24, Felipe Balbi <balbi at ti.com> wrote:
[..]
>>
>> static irqreturn_t tw68_irq(int irq, void *dev_id)
>> {
>>         struct tw68_dev *dev = dev_id;
>>         u32 status, orig;
>>         int loop;
>>
>>         status = orig = tw_readl(TW68_INTSTAT) & dev->pci_irqmask;
>
> Now try to read that register when your clock is gated. That's the
> problem I'm talking about. Everything about the handler is functioning
> correctly; however clocks are gated in ->remove() and free_irq() is
> only called *AFTER* ->remove() has returned.
>

Yeah, it's pretty clear you are talking about clocks here. That's
why I said "read won't stall" in the next paragraph.

>>         [etc]
>> }
>>
>> The IRQ handler accesses the device struct and then
>> reads through PCI. So if you use devm_request_irq
>> you need to make sure the device struct is still allocated
>> after remove(), and the PCI read won't stall or crash.
>
> dude, that's not the problem I'm talking about. I still have my
> private_data around, what I don't have is:
>
>               _            _
>   __ _    ___| | ___   ___| | __
>  / _` |  / __| |/ _ \ / __| |/ /
> | (_| | | (__| | (_) | (__|   <
>  \__,_|  \___|_|\___/ \___|_|\_\
>
>

Yes, *you* may have your private data around and have a clock gated,
others (the tw68 for instance) may have its region released and unmapped.

And yet others may have $whatever resource released in the
remove() and assume it's available in the IRQ handler.

I honestly can't think why using request_irq / free_irq to solve this
is a workaround.

>> Interestingly, tw68 uses devm_request_irq with IRQF_SHARED :-)
>>
>> Still, I don't think that's a good idea, since it relies on
>> the IRQ being freed *before* the device struct.
>
> that's not an issue at all. If you're using devm_request_irq() you're
> likely using devm_kzalloc() for the device struct anyway. Also, you
> called devm_kzalloc() before devm_request_irq() so IRQ *will* be freed
> before your private data; there's nothing wrong there.
>

-- 
Ezequiel Garc?a, VanguardiaSur
www.vanguardiasur.com.ar


From bjorn.andersson at sonymobile.com  Wed Aug 26 13:39:52 2015
From: bjorn.andersson at sonymobile.com (Bjorn Andersson)
Date: Wed, 26 Aug 2015 13:39:52 -0700
Subject: [PATCH v2] soc: qcom: smd: Use correct remote processor ID
In-Reply-To: <1440618165-9410-1-git-send-email-agross@codeaurora.org>
References: <1440618165-9410-1-git-send-email-agross@codeaurora.org>
Message-ID: <20150826203952.GL13472@usrtlx11787.corpusers.net>

On Wed 26 Aug 12:42 PDT 2015, Andy Gross wrote:

> This patch fixes SMEM addressing issues when remote processors need to use
> secure SMEM partitions.
> 

Reviewed-by: Bjorn Andersson <bjorn.andersson at sonymobile.com>

Regards,
Bjorn


From airlied at gmail.com  Wed Aug 26 13:59:36 2015
From: airlied at gmail.com (Dave Airlie)
Date: Thu, 27 Aug 2015 06:59:36 +1000
Subject: [PATCH 1/7] drm/vc4: Add devicetree bindings for VC4.
In-Reply-To: <CAL_JsqJ2v=wBaUe_gN_UcpQKis+kRH6oa0NTN24Lp9w9LVWtbQ@mail.gmail.com>
References: <1439427380-2436-1-git-send-email-eric@anholt.net>
 <1439427380-2436-2-git-send-email-eric@anholt.net>
 <55CEC25E.7070303@wwwdotorg.org>
 <874mjxwyx5.fsf@eliezer.anholt.net>
 <CAL_JsqJxiGUR5BxBPyR3-0NxqWsOxMGrWQA6cMXe2pjTom__nw@mail.gmail.com>
 <CAF6AEGu2fi0M7DsicHz+5SDHi1DyDRmvWjkmYPPgY6pZ423WcA@mail.gmail.com>
 <20150826115229.GI1367@phenom.ffwll.local>
 <20150826120934.GC320@ulmo.nvidia.com>
 <CAL_JsqJ2v=wBaUe_gN_UcpQKis+kRH6oa0NTN24Lp9w9LVWtbQ@mail.gmail.com>
Message-ID: <CAPM=9tw=3yGQE3_G+=ian-+iV-OCRatbFc-stoMczmXeM2Ko+Q@mail.gmail.com>

On 27 August 2015 at 00:30, Rob Herring <robherring2 at gmail.com> wrote:
> On Wed, Aug 26, 2015 at 7:09 AM, Thierry Reding
> <thierry.reding at gmail.com> wrote:
>> On Wed, Aug 26, 2015 at 01:52:29PM +0200, Daniel Vetter wrote:
>>> On Tue, Aug 25, 2015 at 04:42:18PM -0400, Rob Clark wrote:
>>> > On Mon, Aug 24, 2015 at 9:47 AM, Rob Herring <robherring2 at gmail.com> wrote:
>>> > > On Mon, Aug 17, 2015 at 1:30 PM, Eric Anholt <eric at anholt.net> wrote:
>>> > >> Stephen Warren <swarren at wwwdotorg.org> writes:
>>> > >>
>>> > >>> On 08/12/2015 06:56 PM, Eric Anholt wrote:
>>> > >>>> Signed-off-by: Eric Anholt <eric at anholt.net>
>>> > >>>
>>> > >>> This one definitely needs a patch description, since someone might not
>>> > >>> know what a VC4 is, and "git log" won't show the text from the binding
>>> > >>> doc itself. I'd suggest adding the initial paragraph of the binding doc
>>> > >>> as the patch description, or more.
>>> > >>>
>>> > >>>> diff --git a/Documentation/devicetree/bindings/gpu/brcm,bcm-vc4.txt b/Documentation/devicetree/bindings/gpu/brcm,bcm-vc4.txt
>>> > >>
>>> > >>>> +- hvss:             List of references to HVS video scalers
>>> > >>>> +- encoders: List of references to output encoders (HDMI, SDTV)
>>> > >>>
>>> > >>> Would it make sense to make all those nodes child node of the vc4
>>> > >>> object. That way, there's no need to have these lists of objects; they
>>> > >>> can be automatically built up as the DT is enumerated. I know that e.g.
>>> > >>> the NVIDIA Tegra host1x binding works this way, and I think it may have
>>> > >>> been inspired by other similar cases.
>>> > >>
>>> > >> I've looked at tegra, and the component system used by msm appears to be
>>> > >> nicer than it.  To follow tegra's model, it looks like I need to build
>>> > >> this extra bus thing corresponding to host1x that is effectively the
>>> > >> drivers/base/component.c code, so that I can get at vc4's structure from
>>> > >> the component drivers.
>>> > >>
>>> > >>> Of course, this is only appropriate if the HW modules really are
>>> > >>> logically children of the VC4 HW module. Perhaps they aren't. If they
>>> > >>> aren't though, I wonder what this "vc4" module actually represents in HW?
>>> > >>
>>> > >> It's the subsystem, same as we use a subsystem node for msm, sti,
>>> > >> rockchip, imx, and exynos.  This appears to be the common model of how
>>> > >> the collection of graphics-related components is represented in the DT.
>>> > >
>>> > > I think most of these bindings are wrong. They are grouped together
>>> > > because that is what DRM wants not because that reflects the h/w. So
>>> > > convince me this is one block, not that it is what other people do.
>>> >
>>> > I think, when it comes to more complex driver subsystems (like drm in
>>> > particular) we have a bit of mismatch between how things look from the
>>> > "pure hw ignoring sw" perspective, and the "how sw and in particular
>>> > userspace expects things" perspective.  Maybe it is less a problem in
>>> > other subsystems, where bindings map to things that are only visible
>>> > in the kernel, or well defined devices like uart or sata controller.
>>> > But when given the choice, I'm going to err on the side of not
>>> > confusing userspace and the large software stack that sits above
>>> > drm/kms, over dt purity.
>>> >
>>> > Maybe it would be nice to have a sort of dt overlay that adds the bits
>>> > needed to tie together hw blocks that should be assembled into a
>>> > single logical device for linux and userspace (but maybe not some
>>> > other hypothetical operating system).  But so far that doesn't exist.
>>> > All we have is a hammer (devicetree), everything looks like a nail.
>>> > End result is we end up adding some things in the bindings which
>>> > aren't purely about the hw.  Until someone invents a screwdriver, I'm
>>> > not sure what else to do.  In the end, other hypothetical OS is free
>>> > to ignore those extra fields in the bindings if it doesn't need them.
>>> > So meh?
>>>
>>> I thought we agreed a while back that these kind of "pull everything for
>>> the logical device together" dt nodes which just have piles of phandles
>>> are totally accepted? At least that's the point behind the component
>>> helpers, and Eric even suggested to create dt-specific component helpers
>>> to cut down a bit on the usual boilerplate. dt maintainers are also fine
>>> with this approach afaik. From my understanding tegra with the host1x bus
>>> really is the odd one out and not the norm.
>>
>> I agree that in many aspects Tegra is somewhat special. But the same
>> principles that the host1x infrastructure uses could be implemented in a
>> similar way for other DRM drivers. You can easily collect information
>> about subdevices by walking the device tree and matching on known
>> compatible strings. And you can also instantiate the top-level device
>> from driver code rather than have it in DT. It should still be possible
>> to make this work without an artificial device node in DT. The component
>> and master infrastructure is largely orthogonal to that, and as far as I
>> remember the only blocker is the need for a top-level device. I wonder
>> if perhaps this could be made to work by binding the master to the top-
>> level SoC device.
>>
>> Obviously adding the node in DT is easier, but to my knowledge easy has
>> never been a good excuse for mangling DT. Perhaps that's different these
>> days...
>
> I agree we should avoid the virtual node if possible. It is certainly
> possible as I started out with one and removed it. At least in my
> case, it essentially required the drm_device and crtc to be a single
> driver rather than 2 components. However, I'm more concerned that we
> are consistent from platform to platform where it makes sense than
> whether we have a somewhat questionable node or not.
>
http://lists.freedesktop.org/archives/dri-devel/2013-July/041159.html

So can we at least have some continuity of decision making,
bikeshedding this every time we submit a driver isn't giving me any
hope going forward.

Dave.


From stefan at agner.ch  Wed Aug 26 14:15:45 2015
From: stefan at agner.ch (Stefan Agner)
Date: Wed, 26 Aug 2015 14:15:45 -0700
Subject: [PATCH v10 3/5] mtd: nand: vf610_nfc: add device tree bindings
In-Reply-To: <20150826173903.25479201@bbrezillon>
References: <1438594050-4595-1-git-send-email-stefan@agner.ch>
 <1438594050-4595-4-git-send-email-stefan@agner.ch>
 <20150825202546.GL81844@google.com>
 <BLU436-SMTP1971442F63D96D55AC8E905B8600@phx.gbl>
 <20150826173903.25479201@bbrezillon>
Message-ID: <56589547ed623481ca2b94ff364d6434@agner.ch>

On 2015-08-26 08:39, Boris Brezillon wrote:
> Hi Bill,
> 
> On Wed, 26 Aug 2015 11:26:36 -0400
> Bill Pringlemeir <bpringle at sympatico.ca> wrote:
> 
>> On 25 Aug 2015, computersforpeace at gmail.com wrote:
>>
>> > Sorry, I realized a potential issue here.
>>
>> > On Mon, Aug 03, 2015 at 11:27:28AM +0200, Stefan Agner wrote:
>> >> Signed-off-by: Bill Pringlemeir <bpringlemeir at nbsps.com>
>> >> Acked-by: Shawn Guo <shawnguo at kernel.org>
>> >> Reviewed-by: Brian Norris <computersforpeace at gmail.com>
>> >> Signed-off-by: Stefan Agner <stefan at agner.ch>
>> >> ---
>> >> .../devicetree/bindings/mtd/vf610-nfc.txt | 45 ++++++++++++++++++++++
>> >> 1 file changed, 45 insertions(+) create mode 100644
>> >> Documentation/devicetree/bindings/mtd/vf610-nfc.txt
>>
>> >> diff --git a/Documentation/devicetree/bindings/mtd/vf610-nfc.txt
>> >> b/Documentation/devicetree/bindings/mtd/vf610-nfc.txt
>> >> new file mode 100644
>> >> index 0000000..cae5f25
>> >> --- /dev/null
>> >> +++ b/Documentation/devicetree/bindings/mtd/vf610-nfc.txt
>> >>>> -0,0 +1,45 @@
>> >> +- nand-bus-width: see nand.txt
>> >> +- nand-ecc-mode: see nand.txt
>> >> +- nand-on-flash-bbt: see nand.txt
>>
>> > Stumbling across the "multi-CS" questions on the driver reminds me: it
>> > typically makes sense to define new NAND bindings using separate NAND
>> > *controller* and *flash* device nodes. The above 3 properties, at
>> > least, would apply on a per-flash basis, not per-controller
>> > typically. See sunxi-nand, for instance:
>>
>> > http://lxr.free-electrons.com/source/Documentation/devicetree/bindings/mtd/sunxi-nand.txt
>>
>> > brcmnand had a similar pattern:
>>
>> > https://git.kernel.org/cgit/linux/kernel/git/torvalds/linux.git/tree/Documentation/devicetree/bindings/mtd/brcm,brcmnand.txt
>>
>> > (Perhaps it's time we standardized this a little more formally...)
>>
>> These would apply per chip, but the controller has to be configured to
>> support each and every one.  Every time an operation was performed, we
>> would have to check the chip type and reconfigure the controller.
>> Currently, the driver does not support this and it would add a lot of
>> overhead in some cases unless a register cache was used.
>>
>> Is the flexibility of using a system with combined 8/16bit devices
>> really worth all the overhead?  Isn't it sort of brain dead hardware not
>> to make all of the chips similar?  Why would everyone have to pay for
>> such a crazy setup?
>>
>> To separate it would at least be a lie versus the code in the current
>> form.  As well, there are only a few SOC which support multiple chip
>> selects.  The 'multi-CS' register bits of this controller varies between
>> PowerPC, 68K/Coldfire and ARM platforms.

The DT can be a lie versus the code. The DT should reflect how the
hardware is wired, afaik, if we take shortcuts in the driver code, that
is fine. If we don't support a certain configuration right now (e.g.
second NAND chip), the driver can just return an appropriate error code.
>>
>> I looked briefly at the brcmnand.c  and it seems that it is not
>> supporting different ECC per chip even though the nodes are broken out
>> this way.  In fact, if some raw functions are called, I think it will
>> put it in ECC mode even if it wasn't before?  Well, I agree that this
>> would be good generically, I think it puts a lot of effort in the
>> drivers for not so much payoff?
> 
> Hm, the sunxi driver supports it, and it does not add such a big
> overhead...
> The only thing you have to do is cache a bunch of register values
> per-chip and restore/apply them when the chip is selected
> (in your ->select_chip() implementation).
> 
> Anyway, even if the suggested DT representation is a lie in regards to
> your implementation, it's actually pretty accurate from an hardware
> POV, and this is exactly what DT is supposed to represent.

I agree with both of you. I don't see much value implementing multi-NAND
chip support, especially with different configurations, at the moment. I
am not aware of any hardware making use of that now.

I will update the driver to parse a NAND sub node and get the ECC
properties from the per flash configuration. However, I won't add chip
select or multi-NAND support right now...

Any objection?

--
Stefan


From daniel.thompson at linaro.org  Wed Aug 26 14:18:22 2015
From: daniel.thompson at linaro.org (Daniel Thompson)
Date: Wed, 26 Aug 2015 22:18:22 +0100
Subject: [PATCH v6 4/5] xhci: mediatek: support MTK xHCI host controller
In-Reply-To: <1440207911-17666-5-git-send-email-chunfeng.yun@mediatek.com>
References: <1440207911-17666-1-git-send-email-chunfeng.yun@mediatek.com>
 <1440207911-17666-5-git-send-email-chunfeng.yun@mediatek.com>
Message-ID: <55DE2D1E.7020307@linaro.org>

On 22/08/15 02:45, Chunfeng Yun wrote:
> MTK xhci host controller defines some extra SW scheduling
> parameters for HW to minimize the scheduling effort for
> synchronous and interrupt endpoints. The parameters are
> put into reseved DWs of slot context and endpoint context

According to the covering e-mail there are additional quirks beyond the 
scheduling algorithm. These should probably be mentioned here also (so 
that they end up in the changelog).


>
> Signed-off-by: Chunfeng Yun <chunfeng.yun at mediatek.com>
> ---
>   drivers/usb/host/Kconfig        |   9 +
>   drivers/usb/host/Makefile       |   4 +
>   drivers/usb/host/xhci-mtk-sch.c | 436 +++++++++++++++++++++
>   drivers/usb/host/xhci-mtk.c     | 831 ++++++++++++++++++++++++++++++++++++++++
>   drivers/usb/host/xhci-mtk.h     | 133 +++++++
>   drivers/usb/host/xhci-ring.c    |  35 +-
>   drivers/usb/host/xhci.c         |  19 +-
>   drivers/usb/host/xhci.h         |   1 +
>   8 files changed, 1461 insertions(+), 7 deletions(-)
>   create mode 100644 drivers/usb/host/xhci-mtk-sch.c
>   create mode 100644 drivers/usb/host/xhci-mtk.c
>   create mode 100644 drivers/usb/host/xhci-mtk.h
>
> [snip]
>
> diff --git a/drivers/usb/host/xhci-mtk-sch.c b/drivers/usb/host/xhci-mtk-sch.c
> new file mode 100644
> index 0000000..d4b41a6
> --- /dev/null
> +++ b/drivers/usb/host/xhci-mtk-sch.c
> @@ -0,0 +1,436 @@
> +/*
> + * Copyright (c) 2015 MediaTek Inc.
> + * Author:
> + *  Zhigang.Wei <zhigang.wei at mediatek.com>
> + *  Chunfeng.Yun <chunfeng.yun at mediatek.com>
> + *
> + * This software is licensed under the terms of the GNU General Public
> + * License version 2, as published by the Free Software Foundation, and
> + * may be copied, distributed, and modified under those terms.
> + *
> + * This program is distributed in the hope that it will be useful,
> + * but WITHOUT ANY WARRANTY; without even the implied warranty of
> + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
> + * GNU General Public License for more details.
> + *
> + */
> +
> +#include <linux/kernel.h>
> +#include <linux/module.h>
> +#include <linux/slab.h>
> +
> +#include "xhci.h"
> +#include "xhci-mtk.h"
> +
> +#define SS_BW_BOUNDARY	51000
> +/* table 5-5. High-speed Isoc Transaction Limits in usb_20 spec */
> +#define HS_BW_BOUNDARY	6144
> +/* usb2 spec section11.18.1: at most 188 FS bytes per microframe */
> +#define FS_PAYLOAD_MAX 188
> +
> +/* mtk scheduler bitmasks */
> +#define EP_BPKTS(p)	((p) & 0x3f)
> +#define EP_BCSCOUNT(p)	(((p) & 0x7) << 8)
> +#define EP_BBM(p)	((p) << 11)
> +#define EP_BOFFSET(p)	((p) & 0x3fff)
> +#define EP_BREPEAT(p)	(((p) & 0x7fff) << 16)
> +
> +static int is_fs_or_ls(enum usb_device_speed speed)
> +{
> +	return speed == USB_SPEED_FULL || speed == USB_SPEED_LOW;
> +}

This function is only used three times (and one of the uses would have 
been a switch statement except for needing to make this function call). 
Does it really make code clearer?


> +
> +static int get_bw_index(struct xhci_hcd *xhci, struct usb_device *udev,
> +	struct usb_host_endpoint *ep)
> +{
> +	int bw_index;
> +	int port_id;
> +	struct xhci_virt_device *virt_dev;
> +
> +	virt_dev = xhci->devs[udev->slot_id];
> +	port_id = virt_dev->real_port;
> +
> +	if (udev->speed == USB_SPEED_SUPER) {
> +		if (usb_endpoint_dir_out(&ep->desc))
> +			bw_index = (port_id - 1) * 2;
> +		else
> +			bw_index = (port_id - 1) * 2 + 1;
> +	} else {
> +		bw_index = port_id + xhci->num_usb3_ports - 1;
> +	}
> +
> +	return bw_index;
> +}

This appears to be a function to help the scheduling code lookup 
per-port private data held as an array in the device private structure.

Is this really the best way to lookup this data? (and if it *is* we 
still need some comments explaining what this function does and how it 
relates to sch_array).


> +
> +static void setup_sch_info(struct usb_device *udev,
> +		struct xhci_ep_ctx *ep_ctx, struct mu3h_sch_ep_info *sch_ep)
> +{
> +	u32 ep_type;
> +	u32 ep_interval;
> +	u32 max_packet_size;
> +	u32 max_burst;
> +	u32 mult;
> +	u32 esit_pkts;
> +
> +	ep_type = CTX_TO_EP_TYPE(le32_to_cpu(ep_ctx->ep_info2));
> +	ep_interval = CTX_TO_EP_INTERVAL(le32_to_cpu(ep_ctx->ep_info));
> +	max_packet_size = MAX_PACKET_DECODED(le32_to_cpu(ep_ctx->ep_info2));
> +	max_burst = CTX_TO_MAX_BURST(le32_to_cpu(ep_ctx->ep_info2));
> +	mult = CTX_TO_EP_MULT(le32_to_cpu(ep_ctx->ep_info));
> +
> +	sch_ep->ep_type = ep_type;
> +	sch_ep->max_packet_size = max_packet_size;
> +	sch_ep->esit = 1 << ep_interval;
> +	sch_ep->offset = 0;
> +	sch_ep->burst_mode = 0;
> +
> +	if (udev->speed == USB_SPEED_HIGH) {
> +		sch_ep->cs_count = 0;
> +		/*
> +		 * usb_20 spec section5.9
> +		 * a single microframe is enough for HS synchromous endpoints
> +		 * in a interval
> +		 */
> +		sch_ep->num_budget_microframes = 1;
> +		sch_ep->repeat = 0;
> +		/*
> +		 * xHCI spec section6.2.3.4
> +		 * @max_busrt is the number of additional transactions
> +		 * opportunities per microframe

Some nitpicks: s/busrt/burst/ and add whitespace around the comments 
(there lots of "missing" vertical whitespace in this file).


> +		 */
> +		sch_ep->pkts = max_burst + 1;
> +		sch_ep->bw_cost_per_microframe = max_packet_size * sch_ep->pkts;
> +	} else if (udev->speed == USB_SPEED_SUPER) {
> +		/* usb3_r1 spec section4.4.7 & 4.4.8 */
> +		sch_ep->cs_count = 0;
> +		esit_pkts = (mult + 1) * (max_burst + 1);
> +		if (ep_type == INT_IN_EP || ep_type == INT_OUT_EP) {
> +			sch_ep->pkts = esit_pkts;
> +			sch_ep->num_budget_microframes = 1;
> +			sch_ep->repeat = 0;
> +		}
> +
> +		if (ep_type == ISOC_IN_EP || ep_type == ISOC_OUT_EP) {
> +			if (esit_pkts <= sch_ep->esit)
> +				sch_ep->pkts = 1;
> +			else
> +				sch_ep->pkts = roundup_pow_of_two(esit_pkts)
> +					/ sch_ep->esit;
> +
> +			sch_ep->num_budget_microframes =
> +				DIV_ROUND_UP(esit_pkts, sch_ep->pkts);
> +
> +			if (sch_ep->num_budget_microframes > 1)
> +				sch_ep->repeat = 1;
> +			else
> +				sch_ep->repeat = 0;
> +		}
> +		sch_ep->bw_cost_per_microframe = max_packet_size * sch_ep->pkts;
> +	} else if (is_fs_or_ls(udev->speed)) {
> +		/*
> +		 * usb_20 spec section11.18.4
> +		 * assume worst cases
> +		 */
> +		sch_ep->repeat = 0;
> +		sch_ep->pkts = 1; /* at most one packet for each microframe */
> +		if (ep_type == INT_IN_EP || ep_type == INT_OUT_EP) {
> +			sch_ep->cs_count = 3; /* at most need 3 CS*/
> +			/* one for SS and one for budgeted transaction */
> +			sch_ep->num_budget_microframes = sch_ep->cs_count + 2;
> +			sch_ep->bw_cost_per_microframe = max_packet_size;
> +		}
> +		if (ep_type == ISOC_OUT_EP) {
> +			/* must never schedule a cs ISOC OUT ep */
> +			sch_ep->cs_count = 0;
> +			/*
> +			 * the best case FS budget assumes that 188 FS bytes
> +			 * occur in each microframe
> +			 */
> +			sch_ep->num_budget_microframes = DIV_ROUND_UP(
> +				sch_ep->max_packet_size, FS_PAYLOAD_MAX);

This function appears to arbitrarily switch from reading from 
max_packet_size to reading from sch_ep->max_packet_size .


> +			sch_ep->bw_cost_per_microframe = FS_PAYLOAD_MAX;
> +		}
> +		if (ep_type == ISOC_IN_EP) {
> +			/* at most need additional two CS. */
> +			sch_ep->cs_count = DIV_ROUND_UP(
> +				sch_ep->max_packet_size, FS_PAYLOAD_MAX) + 2;
> +			sch_ep->num_budget_microframes = sch_ep->cs_count + 2;
> +			sch_ep->bw_cost_per_microframe = FS_PAYLOAD_MAX;
> +		}
> +	}
> +}
> +
> +/* Get maximum bandwidth when we schedule at offset slot. */
> +static u32 get_max_bw(struct mu3h_sch_bw_info *sch_bw,
> +	struct mu3h_sch_ep_info *sch_ep, u32 offset)
> +{
> +	u32 num_esit;
> +	u32 max_bw = 0;
> +	int i;
> +	int j;
> +
> +	num_esit = XHCI_MTK_MAX_ESIT / sch_ep->esit;
> +	for (i = 0; i < num_esit; i++) {
> +		u32 base = offset + i * sch_ep->esit;
> +
> +		for (j = 0; j < sch_ep->num_budget_microframes; j++) {
> +			if (sch_bw->bus_bw[base + j] > max_bw)
> +				max_bw = sch_bw->bus_bw[base + j];
> +		}
> +	}
> +	return max_bw;
> +}
> +
> +static void update_bus_bw(struct mu3h_sch_bw_info *sch_bw,
> +	struct mu3h_sch_ep_info *sch_ep, int bw_cost)
> +{
> +	u32 num_esit;
> +	u32 base;
> +	int i;
> +	int j;
> +
> +	num_esit = XHCI_MTK_MAX_ESIT / sch_ep->esit;
> +	for (i = 0; i < num_esit; i++) {
> +		base = sch_ep->offset + i * sch_ep->esit;
> +		for (j = 0; j < sch_ep->num_budget_microframes; j++)
> +			sch_bw->bus_bw[base + j] += bw_cost;
> +	}
> +}
> +
> +static int check_sch_bw(struct usb_device *udev,
> +	struct mu3h_sch_bw_info *sch_bw, struct mu3h_sch_ep_info *sch_ep)
> +{
> +	u32 offset;
> +	u32 esit;
> +	u32 num_budget_microframes;
> +	u32 min_bw;
> +	u32 min_index;
> +	u32 worst_bw;
> +	u32 bw_boundary;
> +
> +	if (sch_ep->esit > XHCI_MTK_MAX_ESIT)
> +		sch_ep->esit = XHCI_MTK_MAX_ESIT;
> +
> +	esit = sch_ep->esit;
> +	num_budget_microframes = sch_ep->num_budget_microframes;
> +
> +	/*
> +	 * Search through all possible schedule microframes.
> +	 * and find a microframe where its worst bandwidth is minimum.
> +	 */
> +	min_bw = ~0;
> +	min_index = 0;
> +	for (offset = 0; offset < esit; offset++) {
> +		if ((offset + num_budget_microframes) > sch_ep->esit)
> +			break;
> +		/*
> +		 * usb_20 spec section11.18:
> +		 * must never schedule Start-Split in Y6
> +		 */
> +		if (is_fs_or_ls(udev->speed) && (offset % 8 == 6))
> +			continue;
> +
> +		worst_bw = get_max_bw(sch_bw, sch_ep, offset);
> +		if (min_bw > worst_bw) {
> +			min_bw = worst_bw;
> +			min_index = offset;
> +		}
> +		if (min_bw == 0)
> +			break;
> +	}
> +	sch_ep->offset = min_index;
> +
> +	bw_boundary = (udev->speed == USB_SPEED_SUPER)
> +				? SS_BW_BOUNDARY : HS_BW_BOUNDARY;
> +
> +	/* check bandwidth */
> +	if (min_bw + sch_ep->bw_cost_per_microframe > bw_boundary)
> +		return -1;

Couldn't this be -errno?


> +
> +	/* update bus bandwidth info */
> +	update_bus_bw(sch_bw, sch_ep, sch_ep->bw_cost_per_microframe);
> +
> +	return 0;
> +}
> +
> +static bool need_bw_sch(struct usb_host_endpoint *ep,
> +	enum usb_device_speed speed, int has_tt)
> +{
> +	/* only for periodic endpoints */
> +	if (usb_endpoint_xfer_control(&ep->desc)
> +		|| usb_endpoint_xfer_bulk(&ep->desc))
> +		return false;
> +	/*
> +	 * for LS & FS periodic endpoints which its device don't attach
> +	 * to TT are also ignored, root-hub will schedule them directly
> +	 */
> +	if (is_fs_or_ls(speed) && !has_tt)
> +		return false;
> +
> +	return true;
> +}
> +
> +int xhci_mtk_sch_init(struct xhci_hcd *xhci)
> +{
> +	struct usb_hcd *hcd = xhci_to_hcd(xhci);
> +	struct device *dev = hcd->self.controller;
> +	struct xhci_hcd_mtk *mtk = dev_get_drvdata(dev);
> +	struct mu3h_sch_bw_info *sch_array;
> +	int num_usb_bus;
> +	int i;
> +
> +	/* ss IN and OUT are separated */
> +	num_usb_bus = xhci->num_usb3_ports * 2 + xhci->num_usb2_ports;
> +
> +	sch_array = kcalloc(num_usb_bus, sizeof(*sch_array), GFP_KERNEL);
> +	if (sch_array == NULL)
> +		return -ENOMEM;
> +
> +	for (i = 0; i < num_usb_bus; i++)
> +		INIT_LIST_HEAD(&sch_array[i].bw_ep_list);
> +
> +	mtk->sch_array = sch_array;
> +
> +	return 0;
> +}
> +EXPORT_SYMBOL_GPL(xhci_mtk_sch_init);
> +
> +void xhci_mtk_sch_exit(struct xhci_hcd *xhci)
> +{
> +	struct usb_hcd *hcd = xhci_to_hcd(xhci);
> +	struct device *dev = hcd->self.controller;
> +	struct xhci_hcd_mtk *mtk = dev_get_drvdata(dev);
> +
> +	kfree(mtk->sch_array);
> +}
> +EXPORT_SYMBOL_GPL(xhci_mtk_sch_exit);
> +
> +int xhci_mtk_add_ep_quirk(struct usb_hcd *hcd, struct usb_device *udev,
> +		struct usb_host_endpoint *ep)
> +{
> +	struct device *dev = hcd->self.controller;
> +	struct xhci_hcd_mtk *mtk = dev_get_drvdata(dev);
> +
> +	int ret = 0;
> +	int port_id;
> +	int bw_index;
> +	struct xhci_hcd *xhci;
> +	unsigned int ep_index;
> +	struct xhci_ep_ctx *ep_ctx;
> +	struct xhci_slot_ctx *slot_ctx;
> +	struct xhci_virt_device *virt_dev;
> +	struct mu3h_sch_bw_info *sch_bw;
> +	struct mu3h_sch_ep_info *sch_ep;
> +	struct mu3h_sch_bw_info *sch_array;
> +
> +	xhci = hcd_to_xhci(hcd);
> +	virt_dev = xhci->devs[udev->slot_id];
> +	ep_index = xhci_get_endpoint_index(&ep->desc);
> +	slot_ctx = xhci_get_slot_ctx(xhci, virt_dev->in_ctx);
> +	ep_ctx = xhci_get_ep_ctx(xhci, virt_dev->in_ctx, ep_index);
> +	sch_array = mtk->sch_array;
> +
> +	port_id = virt_dev->real_port;
> +	xhci_dbg(xhci, "%s() xfer_type: %d, speed:%d, ep:%p\n", __func__,
> +		usb_endpoint_type(&ep->desc), udev->speed, ep);
> +
> +	if (!need_bw_sch(ep, udev->speed, slot_ctx->tt_info & TT_SLOT))
> +		return 0;
> +
> +	bw_index = get_bw_index(xhci, udev, ep);
> +	sch_bw = &sch_array[bw_index];
> +
> +	sch_ep = kzalloc(sizeof(struct mu3h_sch_ep_info), GFP_NOIO);
> +	if (!sch_ep)
> +		return -ENOMEM;
> +
> +	setup_sch_info(udev, ep_ctx, sch_ep);
> +
> +	ret = check_sch_bw(udev, sch_bw, sch_ep);
> +	if (ret) {
> +		xhci_err(xhci, "Not enough bandwidth!\n");
> +		kfree(sch_ep);
> +		return -ENOSPC;
> +	}
> +
> +	list_add_tail(&sch_ep->endpoint, &sch_bw->bw_ep_list);
> +	sch_ep->ep = ep;
> +
> +	ep_ctx->reserved[0] |= cpu_to_le32(EP_BPKTS(sch_ep->pkts)
> +		| EP_BCSCOUNT(sch_ep->cs_count) | EP_BBM(sch_ep->burst_mode));
> +	ep_ctx->reserved[1] |= cpu_to_le32(EP_BOFFSET(sch_ep->offset)
> +		| EP_BREPEAT(sch_ep->repeat));
> +
> +	return 0;
> +}
> +EXPORT_SYMBOL_GPL(xhci_mtk_add_ep_quirk);
> +
> +void xhci_mtk_drop_ep_quirk(struct usb_hcd *hcd, struct usb_device *udev,
> +		struct usb_host_endpoint *ep)
> +{
> +	struct device *dev = hcd->self.controller;
> +	struct xhci_hcd_mtk *mtk = dev_get_drvdata(dev);
> +
> +	int bw_index;
> +	struct xhci_hcd *xhci;
> +	struct xhci_slot_ctx *slot_ctx;
> +	struct xhci_virt_device *virt_dev;
> +	struct mu3h_sch_bw_info *sch_array;
> +	struct mu3h_sch_bw_info *sch_bw;
> +	struct mu3h_sch_ep_info *sch_ep;
> +
> +	xhci = hcd_to_xhci(hcd);
> +	virt_dev = xhci->devs[udev->slot_id];
> +	slot_ctx = xhci_get_slot_ctx(xhci, virt_dev->in_ctx);
> +	sch_array = mtk->sch_array;
> +
> +	xhci_dbg(xhci, "%s() xfer_type: %d, speed:%d, ep:%p\n", __func__,
> +		sb_endpoint_type(&ep->desc), udev->speed, ep);
> +
> +	if (!need_bw_sch(ep, udev->speed, slot_ctx->tt_info & TT_SLOT))
> +		return;
> +
> +	bw_index = get_bw_index(xhci, udev, ep);
> +	sch_bw = &sch_array[bw_index];
> +
> +	list_for_each_entry(sch_ep, &sch_bw->bw_ep_list, endpoint) {
> +		if (sch_ep->ep == ep) {
> +			update_bus_bw(sch_bw, sch_ep,
> +				-sch_ep->bw_cost_per_microframe);
> +			list_del(&sch_ep->endpoint);
> +			kfree(sch_ep);
> +			break;
> +		}
> +	}
> +}
> +EXPORT_SYMBOL_GPL(xhci_mtk_drop_ep_quirk);
> +
> +/*
> + * The TD size is the number of max packet sized packets remaining in the TD
> + * (including this TRB), right shifted by 10.
> + * It must fit in bits 21:17, so it can't be bigger than 31.
> + */
> +u32 xhci_mtk_td_remainder_quirk(unsigned int td_running_total,
> +	unsigned trb_buffer_length, struct urb *urb)
> +{
> +	u32 max = 31;
> +	int remainder, td_packet_count, packet_transferred;
> +	unsigned int td_transfer_size = urb->transfer_buffer_length;
> +	unsigned int maxp;
> +
> +	maxp = GET_MAX_PACKET(usb_endpoint_maxp(&urb->ep->desc));
> +
> +	/* 0 for the last TRB */
> +	if (td_running_total + trb_buffer_length == td_transfer_size)
> +		return 0;
> +
> +	packet_transferred = td_running_total / maxp;
> +	td_packet_count = DIV_ROUND_UP(td_transfer_size, maxp);
> +	remainder = td_packet_count - packet_transferred;
> +
> +	if (remainder > max)
> +		return max << 17;
> +	else
> +		return remainder << 17;
> +}
> +EXPORT_SYMBOL_GPL(xhci_mtk_td_remainder_quirk);
> diff --git a/drivers/usb/host/xhci-mtk.c b/drivers/usb/host/xhci-mtk.c
> new file mode 100644
> index 0000000..89c1417
> --- /dev/null
> +++ b/drivers/usb/host/xhci-mtk.c
> @@ -0,0 +1,831 @@
> +/*
> + * Copyright (c) 2015 MediaTek Inc.
> + * Author:
> + *  Chunfeng Yun <chunfeng.yun at mediatek.com>
> + *
> + * This software is licensed under the terms of the GNU General Public
> + * License version 2, as published by the Free Software Foundation, and
> + * may be copied, distributed, and modified under those terms.
> + *
> + * This program is distributed in the hope that it will be useful,
> + * but WITHOUT ANY WARRANTY; without even the implied warranty of
> + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
> + * GNU General Public License for more details.
> + *
> + */
> +
> +#include <linux/clk.h>
> +#include <linux/dma-mapping.h>
> +#include <linux/iopoll.h>
> +#include <linux/kernel.h>
> +#include <linux/mfd/syscon.h>
> +#include <linux/module.h>
> +#include <linux/of.h>
> +#include <linux/phy/phy.h>
> +#include <linux/platform_device.h>
> +#include <linux/pm_runtime.h>
> +#include <linux/regmap.h>
> +#include <linux/regulator/consumer.h>
> +#include <linux/slab.h>
> +#include <linux/usb/phy.h>
> +#include <linux/usb/xhci_pdriver.h>
> +
> +#include "xhci.h"
> +#include "xhci-mtk.h"
> +
> +#define SSUSB_USB3_MAC_CSR_BASE	(0x2400)
> +#define SSUSB_USB3_SYS_CSR_BASE	(0x2400)
> +#define SSUSB_USB2_CSR_BASE	(0x3400)

Can we lose the braces?


> +
> +#define SSUSB_SIFSLV_IPPC_BASE	(0x700)
> +
> +#define U3P_UX_EXIT_LFPS_PARAM	(SSUSB_USB3_MAC_CSR_BASE + 0x00A0)
> +#define RX_UX_EXIT_REF		(0xff << 8)

There's a macro to generate bit masks: GENMASK(15, 8)

Please apply this comment further down the file too...


> +#define RX_UX_EXIT_REF_VAL	(0x3 << 8)
> +
> +#define U3P_REF_CLK_PARAM	(SSUSB_USB3_MAC_CSR_BASE + 0x00B0)
> +#define REF_CLK_1000NS		(0xff << 0)
> +#define REF_CLK_VAL_DEF		(0xa << 0)
> +
> +#define U3P_LINK_PM_TIMER	(SSUSB_USB3_SYS_CSR_BASE + 0x0208)
> +#define PM_LC_TIMEOUT		(0xf << 0)
> +#define PM_LC_TIMEOUT_VAL	(0x3 << 0)
> +
> +#define U3P_TIMING_PULSE_CTRL	(SSUSB_USB3_SYS_CSR_BASE + 0x02B4)
> +#define U3T_CNT_1US			(0xff << 0)
> +#define U3T_CNT_1US_VAL		(0x3f << 0)	/* 62.5MHz: 63 */
> +
> +#define U3P_U2_TIMING_PARAM	(SSUSB_USB2_CSR_BASE + 0x0040)
> +#define U2T_VAL_1US		(0xff << 0)
> +#define U2T_VAL_1US_VAL	(0x3f << 0)	/* 62.5MHz: 63 */
> +
> +#define U3P_IP_PW_CTRL0	(SSUSB_SIFSLV_IPPC_BASE + 0x0000)
> +#define CTRL0_IP_SW_RST	BIT(0)
> +
> +#define U3P_IP_PW_CTRL1	(SSUSB_SIFSLV_IPPC_BASE + 0x0004)
> +#define CTRL1_IP_HOST_PDN	BIT(0)
> +
> +#define U3P_IP_PW_CTRL2	(SSUSB_SIFSLV_IPPC_BASE + 0x0008)
> +#define CTRL2_IP_DEV_PDN	BIT(0)
> +
> +#define U3P_IP_PW_STS1	(SSUSB_SIFSLV_IPPC_BASE + 0x0010)
> +#define STS1_IP_SLEEP_STS	BIT(30)
> +#define STS1_U3_MAC_RST	BIT(16)
> +#define STS1_SYS125_RST	BIT(10)
> +#define STS1_REF_RST		BIT(8)
> +#define STS1_SYSPLL_STABLE	BIT(0)
> +
> +#define U3P_IP_PW_STS2	(SSUSB_SIFSLV_IPPC_BASE + 0x0014)
> +#define STS2_U2_MAC_RST	BIT(0)
> +
> +#define U3P_IP_XHCI_CAP	(SSUSB_SIFSLV_IPPC_BASE + 0x0024)
> +#define CAP_U3_PORT_NUM(p)	((p) & 0xff)
> +#define CAP_U2_PORT_NUM(p)	(((p) >> 8) & 0xff)
> +
> +#define U3P_U3_CTRL_0P	(SSUSB_SIFSLV_IPPC_BASE + 0x0030)
> +#define CTRL_U3_PORT_HOST_SEL	BIT(2)
> +#define CTRL_U3_PORT_PDN	BIT(1)
> +#define CTRL_U3_PORT_DIS	BIT(0)
> +
> +#define U3P_U2_CTRL_0P	(SSUSB_SIFSLV_IPPC_BASE + 0x0050)
> +#define CTRL_U2_PORT_HOST_SEL	BIT(2)
> +#define CTRL_U2_PORT_PDN	BIT(1)
> +#define CTRL_U2_PORT_DIS	BIT(0)
> +
> +#define U3P_U2_PHY_PLL	(SSUSB_SIFSLV_IPPC_BASE+0x007c)
> +#define CTRL_U2_FORCE_PLL_STB	(0x1<<28)
> +
> +#define U3P_U3_CTRL(p)	(U3P_U3_CTRL_0P + ((p) * 0x08))
> +#define U3P_U2_CTRL(p)	(U3P_U2_CTRL_0P + ((p) * 0x08))
> +
> +#define PERI_WK_CTRL0		0x400
> +#define UWK_CTR0_0P_LS_PE	BIT(8)  /* posedge */
> +#define UWK_CTR0_0P_LS_NE	BIT(7)  /* negedge for 0p linestate*/
> +#define UWK_CTL1_1P_LS_C(x)	(((x) & 0xf) << 1)
> +#define UWK_CTL1_1P_LS_E	BIT(0)
> +
> +#define PERI_WK_CTRL1		0x404
> +#define UWK_CTL1_IS_C(x)	(((x) & 0xf) << 26)
> +#define UWK_CTL1_IS_E		BIT(25)
> +#define UWK_CTL1_0P_LS_C(x)	(((x) & 0xf) << 21)
> +#define UWK_CTL1_0P_LS_E	BIT(20)
> +#define UWK_CTL1_IDDIG_C(x)	(((x) & 0xf) << 11)  /* cycle debounce */
> +#define UWK_CTL1_IDDIG_E	BIT(10) /* enable debounce */
> +#define UWK_CTL1_IDDIG_P	BIT(9)  /* polarity */
> +#define UWK_CTL1_0P_LS_P	BIT(7)
> +#define UWK_CTL1_IS_P		BIT(6)  /* polarity for ip sleep */
> +
> +enum ssusb_wakeup_src {
> +	SSUSB_WK_IP_SLEEP = 1,
> +	SSUSB_WK_LINE_STATE = 2,
> +};
> +
> +static int check_ip_clk_status(struct xhci_hcd_mtk *mtk)
> +{
> +	int ret;
> +	int u3_port_num;
> +	int u2_port_num;
> +	u32 xhci_cap;
> +	u32 val;
> +	void __iomem *ippc_base = mtk->ippc_base;
> +
> +	xhci_cap = readl(ippc_base + U3P_IP_XHCI_CAP);
> +	u3_port_num = CAP_U3_PORT_NUM(xhci_cap);
> +	u2_port_num = CAP_U2_PORT_NUM(xhci_cap);
> +
> +	ret = readl_poll_timeout(ippc_base + U3P_IP_PW_STS1, val,
> +			  (val & STS1_SYSPLL_STABLE), 100, 10000);
> +	if (ret) {
> +		dev_err(mtk->dev, "syspll is not stable!!!\n");
> +		return ret;
> +	}
> +
> +	ret = readl_poll_timeout(ippc_base + U3P_IP_PW_STS1, val,
> +			  (val & STS1_REF_RST), 100, 10000);
> +	if (ret) {
> +		dev_err(mtk->dev, "ref_clk is still active!!!\n");

Just curious...

Why do we need to check the clocks are inactive after enabling the ports?

[I guess this means I'd like a comment explaining why this function is 
needed].

> +		return ret;
> +	}
> +
> +	ret = readl_poll_timeout(ippc_base + U3P_IP_PW_STS1, val,
> +			   (val & STS1_SYS125_RST), 100, 10000);
> +	if (ret) {
> +		dev_err(mtk->dev, "sys125_ck is still active!!!\n");
> +		return ret;
> +	}
> +
> +	if (u3_port_num) {
> +		ret = readl_poll_timeout(ippc_base + U3P_IP_PW_STS1, val,
> +				   (val & STS1_U3_MAC_RST), 100, 10000);
> +		if (ret) {
> +			dev_err(mtk->dev, "mac3_mac_ck is still active!!!\n");
> +			return ret;
> +		}
> +	}
> +
> +	if (u2_port_num) {
> +		ret = readl_poll_timeout(ippc_base + U3P_IP_PW_STS2, val,
> +				   (val & STS2_U2_MAC_RST), 100, 10000);
> +		if (ret) {
> +			dev_err(mtk->dev, "mac2_sys_ck is still active!!!\n");
> +			return ret;
> +		}
> +	}
> +
> +	return 0;
> +}
> +
> +static int xhci_mtk_ports_enable(struct xhci_hcd_mtk *mtk)
> +{
> +	int i;
> +	u32 temp;
> +	int u3_port_num;
> +	int u2_port_num;
> +	void __iomem *ippc_base = mtk->ippc_base;
> +
> +	temp = readl(ippc_base + U3P_IP_XHCI_CAP);
> +	u3_port_num = CAP_U3_PORT_NUM(temp);
> +	u2_port_num = CAP_U2_PORT_NUM(temp);
> +	dev_dbg(mtk->dev, "%s u2p:%d, u3p:%d\n", __func__,
> +			u2_port_num, u3_port_num);
> +
> +	/* power on host ip */
> +	temp = readl(ippc_base + U3P_IP_PW_CTRL1);
> +	temp &= ~CTRL1_IP_HOST_PDN;
> +	writel(temp, ippc_base + U3P_IP_PW_CTRL1);
> +
> +	/* power on and enable all u3 ports */
> +	for (i = 0; i < u3_port_num; i++) {
> +		temp = readl(ippc_base + U3P_U3_CTRL(i));
> +		temp &= ~(CTRL_U3_PORT_PDN | CTRL_U3_PORT_DIS);
> +		temp |= CTRL_U3_PORT_HOST_SEL;
> +		writel(temp, ippc_base + U3P_U3_CTRL(i));
> +	}
> +
> +	/* power on and enable all u2 ports */
> +	for (i = 0; i < u2_port_num; i++) {
> +		temp = readl(ippc_base + U3P_U2_CTRL(i));
> +		temp &= ~(CTRL_U2_PORT_PDN | CTRL_U2_PORT_DIS);
> +		temp |= CTRL_U2_PORT_HOST_SEL;
> +		writel(temp, ippc_base + U3P_U2_CTRL(i));
> +	}
> +	return check_ip_clk_status(mtk);
> +}
> +
> +static int xhci_mtk_ports_disable(struct xhci_hcd_mtk *mtk)
> +{
> +	int i;
> +	u32 temp;
> +	int ret;
> +	int u3_port_num;
> +	int u2_port_num;
> +	void __iomem *ippc_base = mtk->ippc_base;
> +
> +	temp = readl(ippc_base + U3P_IP_XHCI_CAP);
> +	u3_port_num = CAP_U3_PORT_NUM(temp);
> +	u2_port_num = CAP_U2_PORT_NUM(temp);
> +	dev_dbg(mtk->dev, "%s u2p:%d, u3p:%d\n", __func__,
> +			u2_port_num, u3_port_num);
> +
> +	/* disable all u3 ports */
> +	for (i = 0; i < u3_port_num; i++) {
> +		temp = readl(ippc_base + U3P_U3_CTRL(i));
> +		temp |= CTRL_U3_PORT_PDN;
> +		writel(temp, ippc_base + U3P_U3_CTRL(i));
> +	}
> +
> +	/* disable all u2 ports */
> +	for (i = 0; i < u2_port_num; i++) {
> +		temp = readl(ippc_base + U3P_U2_CTRL(i));
> +		temp |= CTRL_U2_PORT_PDN;
> +		writel(temp, ippc_base + U3P_U2_CTRL(i));
> +	}
> +
> +	/* power off ip */
> +	temp = readl(ippc_base + U3P_IP_PW_CTRL1);
> +	temp |= CTRL1_IP_HOST_PDN;
> +	writel(temp, ippc_base + U3P_IP_PW_CTRL1);
> +
> +	temp = readl(ippc_base + U3P_IP_PW_CTRL2);
> +	temp |= CTRL2_IP_DEV_PDN;
> +	writel(temp, ippc_base + U3P_IP_PW_CTRL2);
> +
> +	ret = readl_poll_timeout(ippc_base + U3P_IP_PW_STS1, temp,
> +			  (temp & STS1_IP_SLEEP_STS), 100, 100000);
> +	if (ret) {
> +		dev_err(mtk->dev, "ip sleep failed!!!\n");
> +		return ret;
> +	}
> +	return 0;
> +}
> +
> +static void xhci_mtk_timing_init(struct xhci_hcd_mtk *mtk)
> +{
> +	void __iomem *mbase = mtk->mac_base;
> +	int u3_port_num;
> +	u32 temp;
> +
> +	temp = readl(mtk->ippc_base + U3P_IP_XHCI_CAP);
> +	u3_port_num = CAP_U3_PORT_NUM(temp);
> +
> +	if (u3_port_num) {
> +		/* set MAC reference clock speed */
> +		temp = readl(mbase + U3P_UX_EXIT_LFPS_PARAM);
> +		temp &= ~RX_UX_EXIT_REF;
> +		temp |= RX_UX_EXIT_REF_VAL;
> +		writel(temp, mbase + U3P_UX_EXIT_LFPS_PARAM);

Very nitpicky but... a bit of whitespace would be nice here.

> +		/* set REF_CLK */
> +		temp = readl(mbase + U3P_REF_CLK_PARAM);
> +		temp &= ~REF_CLK_1000NS;
> +		temp |= REF_CLK_VAL_DEF;
> +		writel(temp, mbase + U3P_REF_CLK_PARAM);
> +		/* set SYS_CLK */
> +		temp = readl(mbase + U3P_TIMING_PULSE_CTRL);
> +		temp &= ~U3T_CNT_1US;
> +		temp |= U3T_CNT_1US_VAL;
> +		writel(temp, mbase + U3P_TIMING_PULSE_CTRL);
> +		/* set LINK_PM_TIMER=3 */
> +		temp = readl(mbase + U3P_LINK_PM_TIMER);
> +		temp &= ~PM_LC_TIMEOUT;
> +		temp |= PM_LC_TIMEOUT_VAL;
> +		writel(temp, mbase + U3P_LINK_PM_TIMER);
> +	}
> +
> +	temp = readl(mbase + U3P_U2_TIMING_PARAM);
> +	temp &= ~U2T_VAL_1US;
> +	temp |= U2T_VAL_1US_VAL;
> +	writel(temp, mbase + U3P_U2_TIMING_PARAM);
> +}
> +
> +static void xhci_mtk_ports_config(struct xhci_hcd_mtk *mtk)
> +{
> +	u32 temp;
> +
> +	/* reset whole ip */
> +	temp = readl(mtk->ippc_base + U3P_IP_PW_CTRL0);
> +	temp |= CTRL0_IP_SW_RST;
> +	writel(temp, mtk->ippc_base + U3P_IP_PW_CTRL0);
> +	udelay(1);
> +	temp = readl(mtk->ippc_base + U3P_IP_PW_CTRL0);
> +	temp &= ~CTRL0_IP_SW_RST;
> +	writel(temp, mtk->ippc_base + U3P_IP_PW_CTRL0);
> +
> +	xhci_mtk_ports_enable(mtk);
> +	xhci_mtk_timing_init(mtk);
> +}
> +
> +static int xhci_mtk_clks_enable(struct xhci_hcd_mtk *mtk)
> +{
> +	int ret;
> +
> +	ret = clk_prepare_enable(mtk->sys_mac);
> +	if (ret) {
> +		dev_err(mtk->dev, "failed to enable u3phya_ref\n");
> +		goto u3phya_ref_err;
> +	}
> +	ret = clk_prepare_enable(mtk->wk_deb_p0);
> +	if (ret) {
> +		dev_err(mtk->dev, "failed to enable wk_deb_p0\n");
> +		goto usb_p0_err;
> +	}
> +	if (mtk->num_phys > 1) {
> +		ret = clk_prepare_enable(mtk->wk_deb_p1);
> +		if (ret) {
> +			dev_err(mtk->dev, "failed to enable wk_deb_p1\n");
> +			goto usb_p1_err;
> +		}
> +	}
> +
> +	return 0;
> +
> +usb_p1_err:
> +	clk_disable_unprepare(mtk->wk_deb_p0);
> +usb_p0_err:
> +	clk_disable_unprepare(mtk->sys_mac);
> +u3phya_ref_err:
> +	return -EINVAL;
> +}
> +
> +static void xhci_mtk_clks_disable(struct xhci_hcd_mtk *mtk)
> +{
> +	if (mtk->num_phys > 1)
> +		clk_disable_unprepare(mtk->wk_deb_p1);
> +	clk_disable_unprepare(mtk->wk_deb_p0);
> +	clk_disable_unprepare(mtk->sys_mac);
> +}
> +
> +/* only clocks can be turn off for ip-sleep wakeup mode */
> +static void usb_wakeup_ip_sleep_en(struct xhci_hcd_mtk *mtk)
> +{
> +	u32 tmp;
> +	struct regmap *pericfg = mtk->pericfg;
> +
> +	regmap_read(pericfg, PERI_WK_CTRL1, &tmp);
> +	tmp &= ~UWK_CTL1_IS_P;
> +	tmp &= ~(UWK_CTL1_IS_C(0xf));
> +	tmp |= UWK_CTL1_IS_C(0x8);
> +	regmap_write(pericfg, PERI_WK_CTRL1, tmp);
> +	regmap_write(pericfg, PERI_WK_CTRL1, tmp | UWK_CTL1_IS_E);
> +
> +	regmap_read(pericfg, PERI_WK_CTRL1, &tmp);
> +	dev_dbg(mtk->dev, "%s(): WK_CTRL1[P6,E25,C26:29]=%#x\n",
> +		__func__, tmp);
> +}
> +
> +static void usb_wakeup_ip_sleep_dis(struct xhci_hcd_mtk *mtk)
> +{
> +	u32 tmp;
> +
> +	regmap_read(mtk->pericfg, PERI_WK_CTRL1, &tmp);
> +	tmp &= ~UWK_CTL1_IS_E;
> +	regmap_write(mtk->pericfg, PERI_WK_CTRL1, tmp);
> +}
> +
> +/*
> +* for line-state wakeup mode, phy's power should not power-down
> +* and only support cable plug in/out
> +*/
> +static void usb_wakeup_line_state_en(struct xhci_hcd_mtk *mtk)
> +{
> +	u32 tmp;
> +	struct regmap *pericfg = mtk->pericfg;
> +
> +	/* line-state of u2-port0 */
> +	regmap_read(pericfg, PERI_WK_CTRL1, &tmp);
> +	tmp &= ~UWK_CTL1_0P_LS_P;
> +	tmp &= ~(UWK_CTL1_0P_LS_C(0xf));
> +	tmp |= UWK_CTL1_0P_LS_C(0x8);
> +	regmap_write(pericfg, PERI_WK_CTRL1, tmp);
> +	regmap_read(pericfg, PERI_WK_CTRL1, &tmp);
> +	regmap_write(pericfg, PERI_WK_CTRL1, tmp | UWK_CTL1_0P_LS_E);
> +
> +	/* line-state of u2-port1 if support */
> +	if (mtk->num_phys > 1) {
> +		regmap_read(pericfg, PERI_WK_CTRL0, &tmp);
> +		tmp &= ~(UWK_CTL1_1P_LS_C(0xf));
> +		tmp |= UWK_CTL1_1P_LS_C(0x8);
> +		regmap_write(pericfg, PERI_WK_CTRL0, tmp);
> +		regmap_write(pericfg, PERI_WK_CTRL0, tmp | UWK_CTL1_1P_LS_E);
> +	}
> +}
> +
> +static void usb_wakeup_line_state_dis(struct xhci_hcd_mtk *mtk)
> +{
> +	u32 tmp;
> +	struct regmap *pericfg = mtk->pericfg;
> +
> +	regmap_read(pericfg, PERI_WK_CTRL1, &tmp);
> +	tmp &= ~UWK_CTL1_0P_LS_E;
> +	regmap_write(pericfg, PERI_WK_CTRL1, tmp);
> +
> +	if (mtk->num_phys > 1) {
> +		regmap_read(pericfg, PERI_WK_CTRL0, &tmp);
> +		tmp &= ~UWK_CTL1_1P_LS_E;
> +		regmap_write(pericfg, PERI_WK_CTRL0, tmp);
> +	}
> +}
> +
> +static void usb_wakeup_enable(struct xhci_hcd_mtk *mtk)
> +{
> +	if (mtk->wakeup_src == SSUSB_WK_IP_SLEEP)
> +		usb_wakeup_ip_sleep_en(mtk);
> +	else if (mtk->wakeup_src == SSUSB_WK_LINE_STATE)
> +		usb_wakeup_line_state_en(mtk);
> +}
> +
> +static void usb_wakeup_disable(struct xhci_hcd_mtk *mtk)
> +{
> +	if (mtk->wakeup_src == SSUSB_WK_IP_SLEEP)
> +		usb_wakeup_ip_sleep_dis(mtk);
> +	else if (mtk->wakeup_src == SSUSB_WK_LINE_STATE)
> +		usb_wakeup_line_state_dis(mtk);
> +}
> +
> +
> +static int xhci_mtk_setup(struct usb_hcd *hcd);
> +static const struct xhci_driver_overrides xhci_mtk_overrides __initconst = {
> +	.extra_priv_size = sizeof(struct xhci_hcd),
> +	.reset = xhci_mtk_setup,
> +};
> +
> +static struct hc_driver __read_mostly xhci_mtk_hc_driver;
> +
> +static int xhci_mtk_phy_enable(struct xhci_hcd_mtk *mtk)
> +{
> +	unsigned int i;
> +	int ret;
> +
> +	for (i = 0; i < mtk->num_phys; i++) {
> +		ret = phy_init(mtk->phys[i]);
> +		if (ret)
> +			goto disable_phy;
> +		ret = phy_power_on(mtk->phys[i]);
> +		if (ret) {
> +			phy_exit(mtk->phys[i]);
> +			goto disable_phy;
> +		}
> +	}
> +
> +	return 0;
> +
> +disable_phy:
> +	for (; i > 0; i--) {
> +		phy_power_off(mtk->phys[i - 1]);
> +		phy_exit(mtk->phys[i - 1]);
> +	}
> +	return ret;
> +}
> +
> +static void xhci_mtk_phy_disable(struct xhci_hcd_mtk *mtk)
> +{
> +	unsigned int i;
> +
> +	for (i = 0; i < mtk->num_phys; i++) {
> +		phy_power_off(mtk->phys[i]);
> +		phy_exit(mtk->phys[i]);
> +	}
> +}
> +
> +static int xhci_mtk_ldos_enable(struct xhci_hcd_mtk *mtk)
> +{
> +	int ret;
> +
> +	ret = regulator_enable(mtk->vbus);
> +	if (ret) {
> +		dev_err(mtk->dev, "failed to enable vbus\n");
> +		return ret;
> +	}
> +
> +	ret = regulator_enable(mtk->vusb33);
> +	if (ret) {
> +		dev_err(mtk->dev, "failed to enable vusb33\n");
> +		regulator_disable(mtk->vbus);
> +		return ret;
> +	}
> +	return 0;
> +}
> +
> +static void xhci_mtk_ldos_disable(struct xhci_hcd_mtk *mtk)
> +{
> +	regulator_disable(mtk->vbus);
> +	regulator_disable(mtk->vusb33);
> +}
> +
> +static void xhci_mtk_quirks(struct device *dev, struct xhci_hcd *xhci)
> +{
> +	/*
> +	 * As of now platform drivers don't provide MSI support so we ensure
> +	 * here that the generic code does not try to make a pci_dev from our
> +	 * dev struct in order to setup MSI
> +	 */
> +	xhci->quirks |= XHCI_PLAT;
> +	xhci->quirks |= XHCI_MTK_HOST;
> +	/*
> +	 * MTK host controller gives a spurious successful event after a
> +	 * short transfer. Ignore it.
> +	 */
> +	xhci->quirks |= XHCI_SPURIOUS_SUCCESS;
> +}
> +
> +/* called during probe() after chip reset completes */
> +static int xhci_mtk_setup(struct usb_hcd *hcd)
> +{
> +	struct xhci_hcd *xhci;
> +	int ret;
> +
> +	ret = xhci_gen_setup(hcd, xhci_mtk_quirks);
> +	if (ret)
> +		return ret;
> +
> +	if (!usb_hcd_is_primary_hcd(hcd))
> +		return 0;
> +
> +	xhci = hcd_to_xhci(hcd);
> +	ret = xhci_mtk_sch_init(xhci);
> +	if (ret) {
> +		kfree(xhci);

Why are you freeing the xhci structure here?


> +		return ret;
> +	}
> +
> +	return ret;
> +}
> +
> +
> +static int xhci_mtk_probe(struct platform_device *pdev)
> +{
> +	struct device *dev = &pdev->dev;
> +	struct device_node *node = dev->of_node;
> +	struct usb_xhci_pdata *pdata = dev_get_platdata(dev);
> +	struct xhci_hcd_mtk *mtk;
> +	const struct hc_driver *driver;
> +	struct xhci_hcd *xhci;
> +	struct resource *res;
> +	struct usb_hcd *hcd;
> +	struct phy *phy;
> +	int phy_num;
> +	int ret = -ENODEV;
> +	int irq;
> +
> +	if (usb_disabled())
> +		return -ENODEV;
> +
> +	driver = &xhci_mtk_hc_driver;
> +	mtk = devm_kzalloc(dev, sizeof(*mtk), GFP_KERNEL);
> +	if (!mtk)
> +		return -ENOMEM;
> +
> +	mtk->dev = dev;
> +	mtk->vbus = devm_regulator_get(dev, "vbus");
> +	if (IS_ERR(mtk->vbus)) {
> +		dev_err(dev, "fail to get vbus\n");
> +		return PTR_ERR(mtk->vbus);
> +	}
> +
> +	mtk->vusb33 = devm_regulator_get(dev, "vusb33");
> +	if (IS_ERR(mtk->vusb33)) {
> +		dev_err(dev, "fail to get vusb33\n");
> +		return PTR_ERR(mtk->vusb33);
> +	}
> +
> +	mtk->sys_mac = devm_clk_get(dev, "sys_ck");
> +	if (IS_ERR(mtk->sys_mac)) {
> +		dev_err(dev, "fail to get sys_ck\n");
> +		return PTR_ERR(mtk->sys_mac);
> +	}
> +
> +	of_property_read_u32(node, "mediatek,wakeup-src", &mtk->wakeup_src);
> +
> +	mtk->wk_deb_p0 = devm_clk_get(dev, "wakeup_deb_p0");
> +	if (IS_ERR(mtk->wk_deb_p0)) {
> +		dev_err(dev, "fail to get wakeup_deb_p0\n");
> +		return PTR_ERR(mtk->wk_deb_p0);
> +	}
> +
> +	mtk->wk_deb_p1 = devm_clk_get(dev, "wakeup_deb_p1");
> +	if (IS_ERR(mtk->wk_deb_p1)) {
> +		dev_err(dev, "fail to get wakeup_deb_p1\n");
> +		return PTR_ERR(mtk->wk_deb_p1);
> +	}
> +
> +	mtk->pericfg = syscon_regmap_lookup_by_phandle(node,
> +						"mediatek,syscon-wakeup");
> +	if (IS_ERR(mtk->pericfg)) {
> +		dev_err(dev, "fail to get pericfg regs\n");
> +		return PTR_ERR(mtk->pericfg);
> +	}
> +
> +	mtk->num_phys = of_count_phandle_with_args(node,
> +			"phys", "#phy-cells");
> +	if (mtk->num_phys > 0) {
> +		mtk->phys = devm_kcalloc(dev, mtk->num_phys,
> +					sizeof(*mtk->phys), GFP_KERNEL);
> +		if (!mtk->phys)
> +			return -ENOMEM;
> +	} else {
> +		mtk->num_phys = 0;
> +	}
> +	pm_runtime_enable(dev);
> +	pm_runtime_get_sync(dev);
> +
> +	ret = xhci_mtk_ldos_enable(mtk);
> +	if (ret)
> +		goto disable_pm;
> +
> +	ret = xhci_mtk_clks_enable(mtk);
> +	if (ret)
> +		goto disable_ldos;
> +
> +	irq = platform_get_irq(pdev, 0);
> +	if (irq < 0)
> +		goto disable_clk;
> +
> +	/* Initialize dma_mask and coherent_dma_mask to 32-bits */
> +	ret = dma_set_coherent_mask(dev, DMA_BIT_MASK(32));
> +	if (ret)
> +		goto disable_clk;
> +
> +	if (!dev->dma_mask)
> +		dev->dma_mask = &dev->coherent_dma_mask;
> +	else
> +		dma_set_mask(dev, DMA_BIT_MASK(32));
> +
> +	hcd = usb_create_hcd(driver, dev, dev_name(dev));
> +	if (!hcd) {
> +		ret = -ENOMEM;
> +		goto disable_clk;
> +	}
> +
> +	/*
> +	 * USB 2.0 roothub is stored in the platform_device.
> +	 * Swap it with mtk HCD.
> +	 */
> +	mtk->hcd = platform_get_drvdata(pdev);
> +	platform_set_drvdata(pdev, mtk);
> +
> +	res = platform_get_resource(pdev, IORESOURCE_MEM, 0);
> +	hcd->regs = devm_ioremap_resource(dev, res);
> +	if (IS_ERR(hcd->regs)) {
> +		ret = PTR_ERR(hcd->regs);
> +		goto put_usb2_hcd;
> +	}
> +	hcd->rsrc_start = res->start;
> +	hcd->rsrc_len = resource_size(res);
> +	mtk->mac_base = hcd->regs;
> +
> +	res = platform_get_resource(pdev, IORESOURCE_MEM, 1);
> +	mtk->ippc_base = devm_ioremap_resource(dev, res);
> +	if (IS_ERR(mtk->ippc_base)) {
> +		ret = PTR_ERR(mtk->ippc_base);
> +		goto put_usb2_hcd;
> +	}
> +
> +	for (phy_num = 0; phy_num < mtk->num_phys; phy_num++) {
> +		phy = devm_of_phy_get_by_index(dev, node, phy_num);
> +		if (IS_ERR(phy)) {
> +			ret = PTR_ERR(phy);
> +			goto put_usb2_hcd;
> +		}
> +		mtk->phys[phy_num] = phy;
> +	}
> +
> +	xhci_mtk_ports_config(mtk);
> +	xhci_mtk_phy_enable(mtk);
> +	device_init_wakeup(dev, 1);
> +
> +	xhci = hcd_to_xhci(hcd);
> +	xhci->main_hcd = hcd;
> +	xhci->shared_hcd = usb_create_shared_hcd(driver, dev,
> +			dev_name(dev), hcd);
> +	if (!xhci->shared_hcd) {
> +		ret = -ENOMEM;
> +		goto disable_usb_phy;
> +	}
> +
> +	if ((node && of_property_read_bool(node, "usb3-lpm-capable")) ||
> +			(pdata && pdata->usb3_lpm_capable))
> +		xhci->quirks |= XHCI_LPM_SUPPORT;
> +
> +	if (HCC_MAX_PSA(xhci->hcc_params) >= 4)
> +		xhci->shared_hcd->can_do_streams = 1;
> +
> +	ret = usb_add_hcd(hcd, irq, IRQF_SHARED);
> +	if (ret)
> +		goto put_usb3_hcd;
> +
> +	ret = usb_add_hcd(xhci->shared_hcd, irq, IRQF_SHARED);
> +	if (ret)
> +		goto dealloc_usb2_hcd;
> +
> +	return 0;
> +
> +dealloc_usb2_hcd:
> +	usb_remove_hcd(hcd);
> +
> +put_usb3_hcd:
> +	usb_put_hcd(xhci->shared_hcd);
> +
> +disable_usb_phy:
> +	xhci_mtk_phy_disable(mtk);
> +	device_init_wakeup(dev, 0);
> +
> +put_usb2_hcd:
> +	usb_put_hcd(hcd);
> +
> +disable_clk:
> +	xhci_mtk_clks_disable(mtk);
> +
> +disable_ldos:
> +	xhci_mtk_ldos_disable(mtk);
> +
> +disable_pm:
> +	pm_runtime_put_sync(dev);
> +	pm_runtime_disable(dev);
> +	return ret;
> +}
> +
> +static int xhci_mtk_remove(struct platform_device *dev)
> +{
> +	struct xhci_hcd_mtk *mtk = platform_get_drvdata(dev);
> +	struct usb_hcd	*hcd = mtk->hcd;
> +	struct xhci_hcd	*xhci = hcd_to_xhci(hcd);
> +
> +	usb_remove_hcd(xhci->shared_hcd);
> +	xhci_mtk_phy_disable(mtk);
> +	device_init_wakeup(&dev->dev, 0);
> +
> +	usb_remove_hcd(hcd);
> +	usb_put_hcd(xhci->shared_hcd);
> +	usb_put_hcd(hcd);
> +	xhci_mtk_sch_exit(xhci);

Why isn't xhci_mtk_sch_exit() needed during the unwind of a failed probe?


> +	xhci_mtk_clks_disable(mtk);
> +	xhci_mtk_ldos_disable(mtk);
> +	pm_runtime_put_sync(&dev->dev);
> +	pm_runtime_disable(&dev->dev);
> +
> +	return 0;
> +}
> +
> +#ifdef CONFIG_PM_SLEEP
> +static int xhci_mtk_suspend(struct device *dev)
> +{
> +	struct xhci_hcd_mtk *mtk = dev_get_drvdata(dev);
> +
> +	xhci_mtk_ports_disable(mtk);
> +	xhci_mtk_phy_disable(mtk);
> +	xhci_mtk_clks_disable(mtk);
> +	usb_wakeup_enable(mtk);
> +	return 0;
> +}
> +
> +static int xhci_mtk_resume(struct device *dev)
> +{
> +	struct xhci_hcd_mtk *mtk = dev_get_drvdata(dev);
> +
> +	usb_wakeup_disable(mtk);
> +	xhci_mtk_clks_enable(mtk);
> +	xhci_mtk_phy_enable(mtk);
> +	xhci_mtk_ports_enable(mtk);
> +	return 0;
> +}
> +
> +static const struct dev_pm_ops xhci_mtk_pm_ops = {
> +	SET_SYSTEM_SLEEP_PM_OPS(xhci_mtk_suspend, xhci_mtk_resume)
> +};
> +#define DEV_PM_OPS	(&xhci_mtk_pm_ops)
> +#else
> +#define DEV_PM_OPS	NULL
> +#endif /* CONFIG_PM */
> +
> +#ifdef CONFIG_OF
> +static const struct of_device_id mtk_xhci_of_match[] = {
> +	{ .compatible = "mediatek,mt8173-xhci"},
> +	{ },
> +};
> +MODULE_DEVICE_TABLE(of, mtk_xhci_of_match);
> +#endif
> +
> +static struct platform_driver mtk_xhci_driver = {
> +	.probe	= xhci_mtk_probe,
> +	.remove	= xhci_mtk_remove,
> +	.driver	= {
> +		.name = "xhci-mtk",
> +		.pm = DEV_PM_OPS,
> +		.of_match_table = of_match_ptr(mtk_xhci_of_match),
> +	},
> +};
> +
> +static int __init xhci_mtk_init(void)
> +{
> +	xhci_init_driver(&xhci_mtk_hc_driver, &xhci_mtk_overrides);
> +	return platform_driver_register(&mtk_xhci_driver);
> +}
> +module_init(xhci_mtk_init);
> +
> +static void __exit xhci_mtk_exit(void)
> +{
> +	platform_driver_unregister(&mtk_xhci_driver);
> +}
> +module_exit(xhci_mtk_exit);
> +
> +MODULE_DESCRIPTION("MediaTek xHCI Host Controller Driver");
> +MODULE_LICENSE("GPL v2");
> diff --git a/drivers/usb/host/xhci-mtk.h b/drivers/usb/host/xhci-mtk.h
> new file mode 100644
> index 0000000..5adba62
> --- /dev/null
> +++ b/drivers/usb/host/xhci-mtk.h
> @@ -0,0 +1,133 @@
> +/*
> + * Copyright (c) 2015 MediaTek Inc.
> + * Author:
> + *  Zhigang.Wei <zhigang.wei at mediatek.com>
> + *  Chunfeng.Yun <chunfeng.yun at mediatek.com>
> + *
> + * This software is licensed under the terms of the GNU General Public
> + * License version 2, as published by the Free Software Foundation, and
> + * may be copied, distributed, and modified under those terms.
> + *
> + * This program is distributed in the hope that it will be useful,
> + * but WITHOUT ANY WARRANTY; without even the implied warranty of
> + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
> + * GNU General Public License for more details.
> + *
> + */
> +
> +#ifndef _XHCI_MTK_H_
> +#define _XHCI_MTK_H_
> +
> +#include "xhci.h"
> +
> +/**
> + * To simplify scheduler algorithm, set a upper limit for ESIT,
> + * if a synchromous ep's ESIT is larger than @XHCI_MTK_MAX_ESIT,
> + * round down to the limit value, that means allocating more
> + * bandwidth to it.
> + */
> +#define XHCI_MTK_MAX_ESIT	64
> +
> +/**
> + * struct mu3h_sch_bw_info
> + * @bus_bw: array to keep track of bandwidth already used at each uframes
> + * @bw_ep_list: eps in the bandwidth domain
> + *
> + * treat a HS root port as a bandwidth domain, but treat a SS root port as
> + * two bandwidth domains, one for IN eps and another for OUT eps.
> + */
> +struct mu3h_sch_bw_info {
> +	u32 bus_bw[XHCI_MTK_MAX_ESIT];
> +	struct list_head bw_ep_list;
> +};
> +
> +/**
> + * struct mu3h_sch_ep_info
> + * @esit: unit is 125us, equal to 2 << Interval field in ep-context
> + * @num_budget_microframes: number of continuous uframes
> + *		(@repeat==1) scheduled within the interval
> + * @ep: address of usb_host_endpoint
> + * @offset: which uframe of the interval that transfer should be
> + *		scheduled first time within the interval
> + * @repeat: the time gap between two uframes that transfers are
> + *		scheduled within a interval. in the simple algorithm, only
> + *		assign 0 or 1 to it; 0 means using only one uframe in a
> + *		interval, and1 means using @num_budget_microframes
> + *		continuous uframes
> + * @pkts: number of packets to be transferred in the scheduled uframes
> + * @cs_count: number of CS that host will trigger
> + */
> +struct mu3h_sch_ep_info {
> +	u32 ep_type;

This appears to be a write-only variable. I don't think anything reads 
from this field. Its also not documented.


> +	u32 max_packet_size;

Also write only and undocumented. It is read from but only in code where 
the max_packet_size is already held in a local variable.


> +	u32 esit;
> +	u32 num_budget_microframes;
> +	u32 bw_cost_per_microframe;
> +	void *ep;
> +	struct list_head endpoint;
> +
> +	/* mtk xhci scheduling info */
> +	u32 offset;
> +	u32 repeat;
> +	u32 pkts;
> +	u32 cs_count;
> +	u32 burst_mode;
> +};
> +
> +struct xhci_hcd_mtk {
> +	struct device *dev;
> +	struct usb_hcd *hcd;
> +	struct mu3h_sch_bw_info *sch_array;
> +	void __iomem *mac_base;
> +	void __iomem *ippc_base;
> +	struct regulator *vusb33;
> +	struct regulator *vbus;
> +	struct clk *sys_mac;	/* sys and mac clock */
> +	struct clk *wk_deb_p0;	/* port0's wakeup debounce clock */
> +	struct clk *wk_deb_p1;
> +	struct regmap *pericfg;
> +	int wakeup_src;
> +	struct phy **phys;
> +	int num_phys;
> +};
> +
> +#if IS_ENABLED(CONFIG_USB_XHCI_MTK)
> +int xhci_mtk_sch_init(struct xhci_hcd *xhci);
> +void xhci_mtk_sch_exit(struct xhci_hcd *xhci);
> +int xhci_mtk_add_ep_quirk(struct usb_hcd *hcd, struct usb_device *udev,
> +		struct usb_host_endpoint *ep);
> +void xhci_mtk_drop_ep_quirk(struct usb_hcd *hcd, struct usb_device *udev,
> +		struct usb_host_endpoint *ep);
> +u32 xhci_mtk_td_remainder_quirk(unsigned int td_running_total,
> +	unsigned trb_buffer_length, struct urb *urb);
> +
> +#else
> +static inline int xhci_mtk_sch_init(struct xhci_hcd *xhci)
> +{
> +	return 0;
> +}
> +
> +static inline void xhci_mtk_sch_exit(struct xhci_hcd *xhci)
> +{
> +}

Why do we need dummy inlines for xhci_mtk_sch_init/_exit(). They are 
only ever called from xhci-mtk.c .


> +
> +static inline int xhci_mtk_add_ep_quirk(struct usb_hcd *hcd,
> +	struct usb_device *udev, struct usb_host_endpoint *ep)
> +{
> +	return 0;
> +}
> +
> +static inline void xhci_mtk_drop_ep_quirk(struct usb_hcd *hcd,
> +	struct usb_device *udev, struct usb_host_endpoint *ep)
> +{
> +}
> +
> +static inline u32 xhci_mtk_td_remainder_quirk(unsigned int td_running_total,
> +	unsigned trb_buffer_length, struct urb *urb)
> +{
> +	return 0;
> +}
> +
> +#endif
> +
> +#endif		/* _XHCI_MTK_H_ */
> diff --git a/drivers/usb/host/xhci-ring.c b/drivers/usb/host/xhci-ring.c
> index 94416ff..73997a0 100644
> --- a/drivers/usb/host/xhci-ring.c
> +++ b/drivers/usb/host/xhci-ring.c
> @@ -68,6 +68,7 @@
>   #include <linux/slab.h>
>   #include "xhci.h"
>   #include "xhci-trace.h"
> +#include "xhci-mtk.h"
>
>   /*
>    * Returns zero if the TRB isn't in this segment, otherwise it returns the DMA
> @@ -3131,9 +3132,14 @@ static int queue_bulk_sg_tx(struct xhci_hcd *xhci, gfp_t mem_flags,
>
>   		/* Set the TRB length, TD size, and interrupter fields. */
>   		if (xhci->hci_version < 0x100) {
> -			remainder = xhci_td_remainder(
> +			if (xhci->quirks & XHCI_MTK_HOST) {
> +				remainder = xhci_mtk_td_remainder_quirk(
> +					running_total, trb_buff_len, urb);
> +			} else {
> +				remainder = xhci_td_remainder(
>   					urb->transfer_buffer_length -
>   					running_total);
> +			}
>   		} else {
>   			remainder = xhci_v1_0_td_remainder(running_total,
>   					trb_buff_len, total_packet_count, urb,
> @@ -3286,9 +3292,14 @@ int xhci_queue_bulk_tx(struct xhci_hcd *xhci, gfp_t mem_flags,
>
>   		/* Set the TRB length, TD size, and interrupter fields. */
>   		if (xhci->hci_version < 0x100) {
> -			remainder = xhci_td_remainder(
> +			if (xhci->quirks & XHCI_MTK_HOST) {
> +				remainder = xhci_mtk_td_remainder_quirk(
> +					running_total, trb_buff_len, urb);
> +			} else {
> +				remainder = xhci_td_remainder(
>   					urb->transfer_buffer_length -
>   					running_total);
> +			}
>   		} else {
>   			remainder = xhci_v1_0_td_remainder(running_total,
>   					trb_buff_len, total_packet_count, urb,
> @@ -3383,7 +3394,7 @@ int xhci_queue_ctrl_tx(struct xhci_hcd *xhci, gfp_t mem_flags,
>   		field |= 0x1;
>
>   	/* xHCI 1.0 6.4.1.2.1: Transfer Type field */
> -	if (xhci->hci_version == 0x100) {
> +	if ((xhci->hci_version == 0x100) || (xhci->quirks & XHCI_MTK_HOST)) {
>   		if (urb->transfer_buffer_length > 0) {
>   			if (setup->bRequestType & USB_DIR_IN)
>   				field |= TRB_TX_TYPE(TRB_DATA_IN);
> @@ -3407,8 +3418,14 @@ int xhci_queue_ctrl_tx(struct xhci_hcd *xhci, gfp_t mem_flags,
>   		field = TRB_TYPE(TRB_DATA);
>
>   	length_field = TRB_LEN(urb->transfer_buffer_length) |
> -		xhci_td_remainder(urb->transfer_buffer_length) |
>   		TRB_INTR_TARGET(0);
> +
> +	if (xhci->quirks & XHCI_MTK_HOST)
> +		length_field |= xhci_mtk_td_remainder_quirk(0,
> +				urb->transfer_buffer_length, urb);
> +	else
> +		length_field |= xhci_td_remainder(urb->transfer_buffer_length);
> +
>   	if (urb->transfer_buffer_length > 0) {
>   		if (setup->bRequestType & USB_DIR_IN)
>   			field |= TRB_DIR_IN;
> @@ -3632,8 +3649,14 @@ static int xhci_queue_isoc_tx(struct xhci_hcd *xhci, gfp_t mem_flags,
>
>   			/* Set the TRB length, TD size, & interrupter fields. */
>   			if (xhci->hci_version < 0x100) {
> -				remainder = xhci_td_remainder(
> -						td_len - running_total);
> +				if (xhci->quirks & XHCI_MTK_HOST) {
> +					remainder = xhci_mtk_td_remainder_quirk(
> +						running_total, trb_buff_len,
> +						urb);
> +				} else {
> +					remainder = xhci_td_remainder(
> +							td_len - running_total);
> +				}
>   			} else {
>   				remainder = xhci_v1_0_td_remainder(
>   						running_total, trb_buff_len,
> diff --git a/drivers/usb/host/xhci.c b/drivers/usb/host/xhci.c
> index 7da0d60..209fc8a 100644
> --- a/drivers/usb/host/xhci.c
> +++ b/drivers/usb/host/xhci.c
> @@ -31,6 +31,7 @@
>
>   #include "xhci.h"
>   #include "xhci-trace.h"
> +#include "xhci-mtk.h"
>
>   #define DRIVER_AUTHOR "Sarah Sharp"
>   #define DRIVER_DESC "'eXtensible' Host Controller (xHC) Driver"
> @@ -623,7 +624,11 @@ int xhci_run(struct usb_hcd *hcd)
>   			"// Set the interrupt modulation register");
>   	temp = readl(&xhci->ir_set->irq_control);
>   	temp &= ~ER_IRQ_INTERVAL_MASK;
> -	temp |= (u32) 160;
> +	/*
> +	 * the increment interval is 8 times as much as that defined
> +	 * in xHCI spec on MTK's controller
> +	 */
> +	temp |= (u32) ((xhci->quirks & XHCI_MTK_HOST) ? 20 : 160);
>   	writel(temp, &xhci->ir_set->irq_control);
>
>   	/* Set the HCD state before we enable the irqs */
> @@ -1688,6 +1693,9 @@ int xhci_drop_endpoint(struct usb_hcd *hcd, struct usb_device *udev,
>
>   	xhci_endpoint_zero(xhci, xhci->devs[udev->slot_id], ep);
>
> +	if (xhci->quirks & XHCI_MTK_HOST)
> +		xhci_mtk_drop_ep_quirk(hcd, udev, ep);
> +
>   	xhci_dbg(xhci, "drop ep 0x%x, slot id %d, new drop flags = %#x, new add flags = %#x\n",
>   			(unsigned int) ep->desc.bEndpointAddress,
>   			udev->slot_id,
> @@ -1783,6 +1791,15 @@ int xhci_add_endpoint(struct usb_hcd *hcd, struct usb_device *udev,
>   		return -ENOMEM;
>   	}
>
> +	if (xhci->quirks & XHCI_MTK_HOST) {
> +		ret = xhci_mtk_add_ep_quirk(hcd, udev, ep);
> +		if (ret < 0) {
> +			xhci_free_or_cache_endpoint_ring(xhci,
> +				virt_dev, ep_index);
> +			return ret;
> +		}
> +	}
> +
>   	ctrl_ctx->add_flags |= cpu_to_le32(added_ctxs);
>   	new_add_flags = le32_to_cpu(ctrl_ctx->add_flags);
>
> diff --git a/drivers/usb/host/xhci.h b/drivers/usb/host/xhci.h
> index 31e46cc..d257ce3 100644
> --- a/drivers/usb/host/xhci.h
> +++ b/drivers/usb/host/xhci.h
> @@ -1567,6 +1567,7 @@ struct xhci_hcd {
>   /* For controllers with a broken beyond repair streams implementation */
>   #define XHCI_BROKEN_STREAMS	(1 << 19)
>   #define XHCI_PME_STUCK_QUIRK	(1 << 20)
> +#define XHCI_MTK_HOST		(1 << 21)
>   	unsigned int		num_active_eps;
>   	unsigned int		limit_active_eps;
>   	/* There are two roothubs to keep track of bus suspend info for */
>



From computersforpeace at gmail.com  Wed Aug 26 14:28:42 2015
From: computersforpeace at gmail.com (Brian Norris)
Date: Wed, 26 Aug 2015 14:28:42 -0700
Subject: [PATCH v10 3/5] mtd: nand: vf610_nfc: add device tree bindings
In-Reply-To: <56589547ed623481ca2b94ff364d6434@agner.ch>
References: <1438594050-4595-1-git-send-email-stefan@agner.ch>
 <1438594050-4595-4-git-send-email-stefan@agner.ch>
 <20150825202546.GL81844@google.com>
 <BLU436-SMTP1971442F63D96D55AC8E905B8600@phx.gbl>
 <20150826173903.25479201@bbrezillon>
 <56589547ed623481ca2b94ff364d6434@agner.ch>
Message-ID: <20150826212842.GT81844@google.com>

On Wed, Aug 26, 2015 at 02:15:45PM -0700, Stefan Agner wrote:
> On 2015-08-26 08:39, Boris Brezillon wrote:
> > On Wed, 26 Aug 2015 11:26:36 -0400
> > Bill Pringlemeir <bpringle at sympatico.ca> wrote:
> >> These would apply per chip, but the controller has to be configured to
> >> support each and every one.  Every time an operation was performed, we
> >> would have to check the chip type and reconfigure the controller.
> >> Currently, the driver does not support this and it would add a lot of
> >> overhead in some cases unless a register cache was used.
> >>
> >> Is the flexibility of using a system with combined 8/16bit devices
> >> really worth all the overhead?  Isn't it sort of brain dead hardware not
> >> to make all of the chips similar?  Why would everyone have to pay for
> >> such a crazy setup?
> >>
> >> To separate it would at least be a lie versus the code in the current
> >> form.  As well, there are only a few SOC which support multiple chip
> >> selects.  The 'multi-CS' register bits of this controller varies between
> >> PowerPC, 68K/Coldfire and ARM platforms.
> 
> The DT can be a lie versus the code. The DT should reflect how the
> hardware is wired, afaik, if we take shortcuts in the driver code, that
> is fine. If we don't support a certain configuration right now (e.g.
> second NAND chip), the driver can just return an appropriate error code.

Right, I was only asking for:
(1) a more accurate DT and
(2) clarity in the driver; the clarity might just be "we don't support
    multi-CS"

> >> I looked briefly at the brcmnand.c  and it seems that it is not
> >> supporting different ECC per chip even though the nodes are broken out
> >> this way.  In fact, if some raw functions are called, I think it will
> >> put it in ECC mode even if it wasn't before?  Well, I agree that this
> >> would be good generically, I think it puts a lot of effort in the
> >> drivers for not so much payoff?
> > 
> > Hm, the sunxi driver supports it, and it does not add such a big
> > overhead...
> > The only thing you have to do is cache a bunch of register values
> > per-chip and restore/apply them when the chip is selected
> > (in your ->select_chip() implementation).
> > 
> > Anyway, even if the suggested DT representation is a lie in regards to
> > your implementation, it's actually pretty accurate from an hardware
> > POV, and this is exactly what DT is supposed to represent.
> 
> I agree with both of you. I don't see much value implementing multi-NAND
> chip support, especially with different configurations, at the moment. I
> am not aware of any hardware making use of that now.
> 
> I will update the driver to parse a NAND sub node and get the ECC
> properties from the per flash configuration. However, I won't add chip
> select or multi-NAND support right now...
> 
> Any objection?

Nope, sounds good to me.

A few tips:
 * be defensive; i.e., error out if someone specifies 2 flash in the DT
 * use the 'reg' property to be the addressing index in the flash
   sub-node; i.e., the chip-select. This fits the practice done by most
   others, I think.

Regards,
Brian


From computersforpeace at gmail.com  Wed Aug 26 14:34:48 2015
From: computersforpeace at gmail.com (Brian Norris)
Date: Wed, 26 Aug 2015 14:34:48 -0700
Subject: [PATCH v10 2/5] mtd: nand: vf610_nfc: add hardware BCH-ECC support
In-Reply-To: <07a479863eef4c53ab2ef6ef85321680@agner.ch>
References: <1438594050-4595-1-git-send-email-stefan@agner.ch>
 <1438594050-4595-3-git-send-email-stefan@agner.ch>
 <ff2e2716578a1ae5f0c4b0e0ca8bbdc3@agner.ch>
 <20150825195411.GJ81844@google.com>
 <07a479863eef4c53ab2ef6ef85321680@agner.ch>
Message-ID: <20150826213448.GU81844@google.com>

On Wed, Aug 26, 2015 at 10:57:38AM -0700, Stefan Agner wrote:
> On 2015-08-25 12:54, Brian Norris wrote:
> > On Mon, Aug 03, 2015 at 11:28:43AM +0200, Stefan Agner wrote:
> >> Btw, if the ECC check fails, the controller seems kind of count the
> >> amount of bitflips. It works for most devices reliable, but we had
> >> devices for which that number was not accurate, see:
> >> http://thread.gmane.org/gmane.linux.ports.arm.kernel/357439
> > 
> > I'm a little confused there. Why would you be expecting to get a count
> > of bitflips, when the ECC engine can't correct all errors? How is it
> > supposed to know what the "right" data is if the bit errors are beyond
> > the correction strength?
> 
> When printing the ECC error count on ECC fail when reading an erased
> NAND flash, the numbers of bit flips (stuck at zero) seem to widely
> correlate with the number returned by the controller. While it seems to
> correlate widely, there are exceptions, as discussed in the thread:
> http://thread.gmane.org/gmane.linux.ports.arm.kernel/295424
> 
> Maybe this is an artifact of the ECC algorithm we just can't/shouldn't
> rely on? I am not sure where this originated, I did not found any
> indication in the reference manual about what that value contains in the
> error case.

Doesn't sound too reliable to me. And I'm not sure even if it was
reliable, that it would provide much value. We have to a lot of
re-counting anyway, so we might as well just be using our own threshold.
Or maybe I'm missing the point.

> Bill, do you have an idea why we used that value as threshold in early
> implementations?
> 
> Otherwise I also think we should just drop the use of this value.

Brian


From khilman at kernel.org  Wed Aug 26 14:47:30 2015
From: khilman at kernel.org (Kevin Hilman)
Date: Wed, 26 Aug 2015 14:47:30 -0700
Subject: [PATCH] clk: rockchip: register pll mux before pll itself
In-Reply-To: <2414716.nTJ39zAhgn@phil>
References: <7060610.CC2Q1RMG2L@phil>
 <CAD=FV=UG_QkU0W5tpb3Y7zxuq6X7dtQmC4m5_j9vMtJgjdiquQ@mail.gmail.com>
 <20150824234319.GG14330@codeaurora.org> <2414716.nTJ39zAhgn@phil>
Message-ID: <CAMAWPa_6pY3cGBpSWH1soKfEThgd_X3-iq9tO6O25-edzFVuyg@mail.gmail.com>

On Mon, Aug 24, 2015 at 11:53 PM, Heiko Stuebner <heiko at sntech.de> wrote:
> Am Montag, 24. August 2015, 16:43:19 schrieb Stephen Boyd:
>> On 08/24, Doug Anderson wrote:
>> > Heiko
>> >
>> > On Wed, Aug 19, 2015 at 6:06 AM, Heiko Stuebner <heiko at sntech.de> wrote:
>> > > The structure is xin24m -> pll -> pll-mux (xin24m,pll,xin32k). The pll
>> > > does have an init callback to make sure the boot-selected frequency is
>> > > using the expected pll settings and resets the same frequency using
>> > > the values provided in the driver if necessary.
>> > >
>> > > The setting itself also involves remuxing the pll-mux temporarily to
>> > > the xin24m source to let the new pll rate settle. Until now this worked
>> > > flawlessly, even when it had the flaw of accessing the mux settings
>> > > before the mux actually got registered.
>> > >
>> > > With the recent clock-core conversions this flaw became apparent in
>> > > null pointer dereference in
>> > > [<c03fc400>] (clk_hw_get_num_parents) from [<c0400df0>]
>> > > (clk_mux_get_parent+0x14/0xc8) [<c0400ddc>] (clk_mux_get_parent) from
>> > > [<c040246c>] (rockchip_rk3066_pll_set_rate+0xd8/0x320)
>> > >
>> > > So to fix that, simply register the pll-mux before the pll, so that
>> > > it will be fully initialized when the pll clock executes its init-
>> > > callback and possibly touches the pll-mux clock.
>> > >
>> > > Signed-off-by: Heiko Stuebner <heiko at sntech.de>
>> > > ---
>> > > This only surfaced with the clk_core changes for 4.3, so should
>> > > probably just go on top.
>> > >
>> > >  drivers/clk/rockchip/clk-pll.c | 63
>> > >  +++++++++++++++++++++--------------------- 1 file changed, 32
>> > >  insertions(+), 31 deletions(-)
>> >
>> > Fixes boot crash on rk3288-veyron-jerry on next-20150824.  It'd be
>> > super great to get this landed somewhere so that we can boot linuxnext
>> > again.  :)
>> >
>> > Tested-by: Douglas Anderson <dianders at chromium.org>
>>
>> So I understand the fix, but how could it have ever possibly
>> worked flawlessly? clk_mux_get_parent() should have returned
>> -EINVAL through that u8 which would have meant that the check in
>> rockchip_rk3066_pll_set_rate() for cur_parent == PLL_MODE_NORM
>> would never have been true, and we would never have switched the
>> PLL mux over. I guess we've been getting away with this because
>> we don't need to actually switch the mux at this time?
>
> The manual mandates the switch away from the pll source before touching the
> pll settings, aka to the slow mode from the 24MHz source. I guess we were
> lucky it simply still worked nevertheless.
>
> In normal rate changes both clocks will have been registered already, so only
> the init callback is affected and also only runs on plls that generate the rate
> from a different settings-touple that what we have in the rate-table, so not
> even all plls normally.

FYI... I also confirm this patch is needed to boot linux-next on the
rk3288-veyron-jerry.

Tested-by: Kevin Hilman <khilman at linaro.org>

Kevin


From sboyd at codeaurora.org  Wed Aug 26 15:12:24 2015
From: sboyd at codeaurora.org (Stephen Boyd)
Date: Wed, 26 Aug 2015 15:12:24 -0700
Subject: [PATCH v2] arm: kgdb: Fix registers on sleeping tasks
In-Reply-To: <1440606038-14816-1-git-send-email-dianders@chromium.org>
References: <1440606038-14816-1-git-send-email-dianders@chromium.org>
Message-ID: <20150826221224.GT19120@codeaurora.org>

On 08/26, Douglas Anderson wrote:
> From: Doug Anderson <dianders at chromium.org>
> 
> Dumping registers from other sleeping tasks in KGDB was totally
> failing for me.  All registers were reported as 0 in many cases.
> 
> The code was using task_pt_regs(task) to try to get other thread
> registers.  This doesn't appear to be the right place to look.  From
> my tests, I saw non-zero values in this structure when we were looking
> at a kernel thread that had a userspace task associated with it, but
> it contained the register values from the userspace task.  So even in
> the cases where registers weren't reported as 0 we were still not
> showing the right thing.
> 
> Instead of using task_pt_regs(task) let's use task_thread_info(task).
> This is the same place that is referred to when doing a dump of all
> sleeping task stacks (kdb_show_stack() -> show_stack() ->
> dump_backtrace() -> unwind_backtrace() -> thread_saved_sp()).
> 
> As further evidence that this is the right thing to do, you can find
> the following comment in "gdbstub.c" right before it calls
> sleeping_thread_to_gdb_regs():
>   Pull stuff saved during switch_to; nothing else is accessible (or
>   even particularly relevant).  This should be enough for a stack
>   trace.
> ...and if you look at switch_to() it only saves r4-r11, sp and lr.
> Those are the same registers that I'm getting out of the
> task_thread_info().
> 
> With this change you can use "info thread" to see all tasks in the
> kernel and you can switch to other tasks and examine them in gdb.
> 
> Signed-off-by: Doug Anderson <dianders at chromium.org>
> Signed-off-by: Douglas Anderson <dianders at chromium.org>
> ---

Works for me.

Tested-by: Stephen Boyd <sboyd at codeurora.org>

-- 
Qualcomm Innovation Center, Inc. is a member of Code Aurora Forum,
a Linux Foundation Collaborative Project


From jonmason at broadcom.com  Wed Aug 26 15:35:25 2015
From: jonmason at broadcom.com (Jon Mason)
Date: Wed, 26 Aug 2015 18:35:25 -0400
Subject: [PATCH v2 0/5] Add Broadcom Northstar Plus Support
Message-ID: <1440628530-6137-1-git-send-email-jonmason@broadcom.com>


Changes in version 2 incorporate Olof's comments regarding:
* the removal of all "Reviewed-by" lines not occurring on external
  mailing lists
* reordering of s-o-b lines
* modification of the device tree file to use labels when enabling
* increated description of the modification to the MAINTAINERS entry

Also, modifying the "to" and "cc" recepients so that everyone is
receving all of the patches. 

--

This patch series adds support for the Broadcom Northstar Plus family of
SoCs.  NSP is a Cortex A9 based SoC under the Broadcom iProc family.

Jon Mason (5):
  dt-bindings: Create Documentation for NSP DT bindings
  ARM: NSP: add minimal Northstar Plus device tree
  ARM: NSP: Add basic support for Broadcom Northstar Plus SoC
  ARM: multi_v7_defconfig: Add NSP to defconfig
  MAINTAINERS: add entry for the Broadcom Northstar Plus SoCs

 .../devicetree/bindings/arm/bcm/brcm,nsp.txt       |  34 +++++++
 MAINTAINERS                                        |  12 ++-
 arch/arm/boot/dts/Makefile                         |   2 +
 arch/arm/boot/dts/bcm-nsp.dtsi                     | 105 +++++++++++++++++++++
 arch/arm/boot/dts/bcm958625k.dts                   |  57 +++++++++++
 arch/arm/configs/multi_v7_defconfig                |   1 +
 arch/arm/mach-bcm/Kconfig                          |  14 +++
 arch/arm/mach-bcm/Makefile                         |   5 +-
 arch/arm/mach-bcm/bcm_nsp.c                        |  25 +++++
 9 files changed, 252 insertions(+), 3 deletions(-)
 create mode 100644 Documentation/devicetree/bindings/arm/bcm/brcm,nsp.txt
 create mode 100644 arch/arm/boot/dts/bcm-nsp.dtsi
 create mode 100644 arch/arm/boot/dts/bcm958625k.dts
 create mode 100644 arch/arm/mach-bcm/bcm_nsp.c

-- 
1.9.1



From jonmason at broadcom.com  Wed Aug 26 15:35:26 2015
From: jonmason at broadcom.com (Jon Mason)
Date: Wed, 26 Aug 2015 18:35:26 -0400
Subject: [PATCH v2 1/5] dt-bindings: Create Documentation for NSP DT bindings
In-Reply-To: <1440628530-6137-1-git-send-email-jonmason@broadcom.com>
References: <1440628530-6137-1-git-send-email-jonmason@broadcom.com>
Message-ID: <1440628530-6137-2-git-send-email-jonmason@broadcom.com>

Add the documentation for the Broadcom Northstar Plus device tree
bindings.

Signed-off-by: Jon Mason <jonmason at broadcom.com>
---
 .../devicetree/bindings/arm/bcm/brcm,nsp.txt       | 34 ++++++++++++++++++++++
 1 file changed, 34 insertions(+)
 create mode 100644 Documentation/devicetree/bindings/arm/bcm/brcm,nsp.txt

diff --git a/Documentation/devicetree/bindings/arm/bcm/brcm,nsp.txt b/Documentation/devicetree/bindings/arm/bcm/brcm,nsp.txt
new file mode 100644
index 0000000..eae53e4
--- /dev/null
+++ b/Documentation/devicetree/bindings/arm/bcm/brcm,nsp.txt
@@ -0,0 +1,34 @@
+Broadcom Northstar Plus device tree bindings
+--------------------------------------------
+
+Broadcom Northstar Plus family of SoCs are used for switching control
+and management applications as well as residential router/gateway
+applications. The SoC features dual core Cortex A9 ARM CPUs, integrating
+several peripheral interfaces including multiple Gigabit Ethernet PHYs,
+DDR3 memory, PCIE Gen-2, USB 2.0 and USB 3.0, serial and NAND flash,
+SATA and several other IO controllers.
+
+Boards with Northstar Plus SoCs shall have the following properties:
+
+Required root node property:
+
+BCM58522
+compatible = "brcm,bcm58522", "brcm,nsp";
+
+BCM58525
+compatible = "brcm,bcm58525", "brcm,nsp";
+
+BCM58535
+compatible = "brcm,bcm58535", "brcm,nsp";
+
+BCM58622
+compatible = "brcm,bcm58622", "brcm,nsp";
+
+BCM58623
+compatible = "brcm,bcm58623", "brcm,nsp";
+
+BCM58625
+compatible = "brcm,bcm58625", "brcm,nsp";
+
+BCM88312
+compatible = "brcm,bcm88312", "brcm,nsp";
-- 
1.9.1



From jonmason at broadcom.com  Wed Aug 26 15:35:28 2015
From: jonmason at broadcom.com (Jon Mason)
Date: Wed, 26 Aug 2015 18:35:28 -0400
Subject: [PATCH v2 3/5] ARM: NSP: Add basic support for Broadcom Northstar
 Plus SoC
In-Reply-To: <1440628530-6137-1-git-send-email-jonmason@broadcom.com>
References: <1440628530-6137-1-git-send-email-jonmason@broadcom.com>
Message-ID: <1440628530-6137-4-git-send-email-jonmason@broadcom.com>

Broadcom Northstar Plus family of SoCs are used for switching
control and management applications as well as residential
router/gateway applications. The SoC features dual core Cortex
A9 ARM CPUs, integrating several peripheral interfaces including
multiple Gigabit Ethernet PHYs, DDR3 memory, PCIE Gen-2, USB 2.0
and USB 3.0, serial and NAND flash, SATA and several other IO
controllers.

Signed-off-by: Kapil Hali <kapilh at broadcom.com>
Signed-off-by: Jon Mason <jonmason at broadcom.com>
---
 arch/arm/mach-bcm/Kconfig   | 14 ++++++++++++++
 arch/arm/mach-bcm/Makefile  |  5 ++++-
 arch/arm/mach-bcm/bcm_nsp.c | 25 +++++++++++++++++++++++++
 3 files changed, 43 insertions(+), 1 deletion(-)
 create mode 100644 arch/arm/mach-bcm/bcm_nsp.c

diff --git a/arch/arm/mach-bcm/Kconfig b/arch/arm/mach-bcm/Kconfig
index 0ac9e4b3..22c85b1 100644
--- a/arch/arm/mach-bcm/Kconfig
+++ b/arch/arm/mach-bcm/Kconfig
@@ -35,6 +35,20 @@ config ARCH_BCM_CYGNUS
 	  BCM11300, BCM11320, BCM11350, BCM11360,
 	  BCM58300, BCM58302, BCM58303, BCM58305.
 
+config ARCH_BCM_NSP
+	bool "Broadcom Northstar Plus SoC Support" if ARCH_MULTI_V7
+	select ARCH_BCM_IPROC
+	select ARM_ERRATA_754322
+	select ARM_ERRATA_775420
+	help
+	  Support for Broadcom Northstar Plus SoC.
+	  Broadcom Northstar Plus family of SoCs are used for switching control
+	  and management applications as well as residential router/gateway
+	  applications. The SoC features dual core Cortex A9 ARM CPUs,
+	  integrating several peripheral interfaces including multiple Gigabit
+	  Ethernet PHYs, DDR3 memory, PCIE Gen-2, USB 2.0 and USB 3.0, serial and
+	  NAND flash, SATA and several other IO controllers.
+
 config ARCH_BCM_5301X
 	bool "Broadcom BCM470X / BCM5301X ARM SoC" if ARCH_MULTI_V7
 	select ARCH_BCM_IPROC
diff --git a/arch/arm/mach-bcm/Makefile b/arch/arm/mach-bcm/Makefile
index 4fb0da4..786d720 100644
--- a/arch/arm/mach-bcm/Makefile
+++ b/arch/arm/mach-bcm/Makefile
@@ -1,5 +1,5 @@
 #
-# Copyright (C) 2012-2014 Broadcom Corporation
+# Copyright (C) 2012-2015 Broadcom Corporation
 #
 # This program is free software; you can redistribute it and/or
 # modify it under the terms of the GNU General Public License as
@@ -13,6 +13,9 @@
 # Cygnus
 obj-$(CONFIG_ARCH_BCM_CYGNUS) +=  bcm_cygnus.o
 
+# Northstar Plus
+obj-$(CONFIG_ARCH_BCM_NSP) += bcm_nsp.o
+
 # BCM281XX
 obj-$(CONFIG_ARCH_BCM_281XX)	+= board_bcm281xx.o
 
diff --git a/arch/arm/mach-bcm/bcm_nsp.c b/arch/arm/mach-bcm/bcm_nsp.c
new file mode 100644
index 0000000..a1101a3
--- /dev/null
+++ b/arch/arm/mach-bcm/bcm_nsp.c
@@ -0,0 +1,25 @@
+/*
+ * Copyright (C) 2015 Broadcom Corporation
+ *
+ * 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 version 2.
+ *
+ * This program is distributed "as is" WITHOUT ANY WARRANTY of any
+ * kind, whether express or implied; without even the implied warranty
+ * of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ * GNU General Public License for more details.
+ */
+
+#include <asm/mach/arch.h>
+
+static const char *const bcm_nsp_dt_compat[] __initconst = {
+	"brcm,nsp",
+	NULL,
+};
+
+DT_MACHINE_START(NSP_DT, "Broadcom Northstar Plus SoC")
+	.l2c_aux_val	= 0,
+	.l2c_aux_mask	= ~0,
+	.dt_compat = bcm_nsp_dt_compat,
+MACHINE_END
-- 
1.9.1



From jonmason at broadcom.com  Wed Aug 26 15:35:27 2015
From: jonmason at broadcom.com (Jon Mason)
Date: Wed, 26 Aug 2015 18:35:27 -0400
Subject: [PATCH v2 2/5] ARM: NSP: add minimal Northstar Plus device tree
In-Reply-To: <1440628530-6137-1-git-send-email-jonmason@broadcom.com>
References: <1440628530-6137-1-git-send-email-jonmason@broadcom.com>
Message-ID: <1440628530-6137-3-git-send-email-jonmason@broadcom.com>

Add a very minimalistic set of Northstar Plus Device Tree files which
describes the SoC and the BCM958625 implementation.  The perpherials
described are:

ARM Cortex A9 CPU
2 8250 UARTs
ARM GIC
PL310 L2 Cache
ARM A9 Global timer

Signed-off-by: Kapil Hali <kapilh at broadcom.com>
Signed-off-by: Jon Mason <jonmason at broadcom.com>
---
 arch/arm/boot/dts/Makefile       |   2 +
 arch/arm/boot/dts/bcm-nsp.dtsi   | 105 +++++++++++++++++++++++++++++++++++++++
 arch/arm/boot/dts/bcm958625k.dts |  57 +++++++++++++++++++++
 3 files changed, 164 insertions(+)
 create mode 100644 arch/arm/boot/dts/bcm-nsp.dtsi
 create mode 100644 arch/arm/boot/dts/bcm958625k.dts

diff --git a/arch/arm/boot/dts/Makefile b/arch/arm/boot/dts/Makefile
index 246473a..adb5732 100644
--- a/arch/arm/boot/dts/Makefile
+++ b/arch/arm/boot/dts/Makefile
@@ -82,6 +82,8 @@ dtb-$(CONFIG_ARCH_BCM_CYGNUS) += \
 dtb-$(CONFIG_ARCH_BCM_MOBILE) += \
 	bcm28155-ap.dtb \
 	bcm21664-garnet.dtb
+dtb-$(CONFIG_ARCH_BCM_NSP) += \
+	bcm958625k.dtb
 dtb-$(CONFIG_ARCH_BERLIN) += \
 	berlin2-sony-nsz-gs7.dtb \
 	berlin2cd-google-chromecast.dtb \
diff --git a/arch/arm/boot/dts/bcm-nsp.dtsi b/arch/arm/boot/dts/bcm-nsp.dtsi
new file mode 100644
index 0000000..77f9bfc
--- /dev/null
+++ b/arch/arm/boot/dts/bcm-nsp.dtsi
@@ -0,0 +1,105 @@
+/*
+ *  BSD LICENSE
+ *
+ *  Copyright(c) 2015 Broadcom Corporation.  All rights reserved.
+ *
+ *  Redistribution and use in source and binary forms, with or without
+ *  modification, are permitted provided that the following conditions
+ *  are met:
+ *
+ *    * Redistributions of source code must retain the above copyright
+ *      notice, this list of conditions and the following disclaimer.
+ *    * Redistributions in binary form must reproduce the above copyright
+ *      notice, this list of conditions and the following disclaimer in
+ *      the documentation and/or other materials provided with the
+ *      distribution.
+ *    * Neither the name of Broadcom Corporation nor the names of its
+ *      contributors may be used to endorse or promote products derived
+ *      from this software without specific prior written permission.
+ *
+ *  THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+ *  "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+ *  LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
+ *  A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
+ *  OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
+ *  SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
+ *  LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
+ *  DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
+ *  THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+ *  (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
+ *  OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ */
+
+#include <dt-bindings/interrupt-controller/arm-gic.h>
+#include <dt-bindings/interrupt-controller/irq.h>
+
+#include "skeleton.dtsi"
+
+/ {
+	compatible = "brcm,nsp";
+	model = "Broadcom Northstar Plus SoC";
+	interrupt-parent = <&gic>;
+
+	cpus {
+		#address-cells = <1>;
+		#size-cells = <0>;
+
+		cpu at 0 {
+			device_type = "cpu";
+			compatible = "arm,cortex-a9";
+			next-level-cache = <&L2>;
+			reg = <0x0>;
+		};
+	};
+
+	clocks {
+		#address-cells = <1>;
+		#size-cells = <1>;
+		ranges;
+
+		periph_clk: periph_clk {
+			compatible = "fixed-clock";
+			#clock-cells = <0>;
+			clock-frequency = <500000000>;
+		};
+	};
+
+	uart0: serial at 18000300 {
+		compatible = "ns16550a";
+		reg = <0x18000300 0x100>;
+		interrupts = <GIC_SPI 85 IRQ_TYPE_LEVEL_HIGH>;
+		clock-frequency = <62499840>;
+		status = "disabled";
+	};
+
+	uart1: serial at 18000400 {
+		compatible = "ns16550a";
+		reg = <0x18000400 0x100>;
+		interrupts = <GIC_SPI 85 IRQ_TYPE_LEVEL_HIGH>;
+		clock-frequency = <62499840>;
+		status = "disabled";
+	};
+
+	gic: interrupt-controller at 19021000 {
+		compatible = "arm,cortex-a9-gic";
+		#interrupt-cells = <3>;
+		#address-cells = <0>;
+		interrupt-controller;
+		reg = <0x19021000 0x1000>,
+		      <0x19020100 0x100>;
+	};
+
+	L2: l2-cache {
+		compatible = "arm,pl310-cache";
+		reg = <0x19022000 0x1000>;
+		cache-unified;
+		cache-level = <2>;
+	};
+
+	timer at 19020200 {
+		compatible = "arm,cortex-a9-global-timer";
+		reg = <0x19020200 0x100>;
+		interrupts = <GIC_PPI 11 IRQ_TYPE_LEVEL_HIGH>;
+		clocks = <&periph_clk>;
+	};
+};
diff --git a/arch/arm/boot/dts/bcm958625k.dts b/arch/arm/boot/dts/bcm958625k.dts
new file mode 100644
index 0000000..16303db
--- /dev/null
+++ b/arch/arm/boot/dts/bcm958625k.dts
@@ -0,0 +1,57 @@
+/*
+ *  BSD LICENSE
+ *
+ *  Copyright(c) 2015 Broadcom Corporation.  All rights reserved.
+ *
+ *  Redistribution and use in source and binary forms, with or without
+ *  modification, are permitted provided that the following conditions
+ *  are met:
+ *
+ *    * Redistributions of source code must retain the above copyright
+ *      notice, this list of conditions and the following disclaimer.
+ *    * Redistributions in binary form must reproduce the above copyright
+ *      notice, this list of conditions and the following disclaimer in
+ *      the documentation and/or other materials provided with the
+ *      distribution.
+ *    * Neither the name of Broadcom Corporation nor the names of its
+ *      contributors may be used to endorse or promote products derived
+ *      from this software without specific prior written permission.
+ *
+ *  THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+ *  "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+ *  LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
+ *  A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
+ *  OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
+ *  SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
+ *  LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
+ *  DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
+ *  THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+ *  (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
+ *  OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ */
+
+/dts-v1/;
+
+#include "bcm-nsp.dtsi"
+
+/ {
+	model = "NorthStar Plus SVK (BCM958625K)";
+	compatible = "brcm,bcm58625", "brcm,nsp";
+
+	aliases {
+		serial0 = &uart0;
+		serial1 = &uart1;
+	};
+
+	chosen {
+		stdout-path = "serial0:115200n8";
+	};
+};
+
+&uart0 {
+	status = "okay";
+};
+
+&uart1 {
+	status = "okay";
+};
-- 
1.9.1



From jonmason at broadcom.com  Wed Aug 26 15:35:30 2015
From: jonmason at broadcom.com (Jon Mason)
Date: Wed, 26 Aug 2015 18:35:30 -0400
Subject: [PATCH v2 5/5] MAINTAINERS: add entry for the Broadcom Northstar Plus
 SoCs
In-Reply-To: <1440628530-6137-1-git-send-email-jonmason@broadcom.com>
References: <1440628530-6137-1-git-send-email-jonmason@broadcom.com>
Message-ID: <1440628530-6137-6-git-send-email-jonmason@broadcom.com>

Modify the iProc MAINTAINER to cover the Nortstar Plus SoCs, and add me
to the list of people responsible for it.  Since iProc is a family of
SoCs that includes more than just Cygnus (i.e., Northstar (BCM5301X),
Northstar Plus, Northstar 2, and a number of other platforms), remove it
from the title to avoid any future confusion.

Signed-off-by: Jon Mason <jonmason at broadcom.com>
Acked-by: Scott Branden <sbranden at broadcom.com>
---
 MAINTAINERS | 12 ++++++++++--
 1 file changed, 10 insertions(+), 2 deletions(-)

diff --git a/MAINTAINERS b/MAINTAINERS
index a9ae6c1..4b851f5 100644
--- a/MAINTAINERS
+++ b/MAINTAINERS
@@ -2315,19 +2315,27 @@ L:	linux-scsi at vger.kernel.org
 S:	Supported
 F:	drivers/scsi/bnx2i/
 
-BROADCOM CYGNUS/IPROC ARM ARCHITECTURE
+BROADCOM IPROC ARM ARCHITECTURE
 M:	Ray Jui <rjui at broadcom.com>
 M:	Scott Branden <sbranden at broadcom.com>
+M:	Jon Mason <jonmason at broadcom.com>
 L:	linux-arm-kernel at lists.infradead.org (moderated for non-subscribers)
 L:	bcm-kernel-feedback-list at broadcom.com
 T:	git git://github.com/broadcom/cygnus-linux.git
 S:	Maintained
 N:	iproc
 N:	cygnus
+N:	nsp
 N:	bcm9113*
 N:	bcm9583*
-N:	bcm583*
+N:	bcm9585*
+N:	bcm9586*
+N:	bcm988312
 N:	bcm113*
+N:	bcm583*
+N:	bcm585*
+N:	bcm586*
+N:	bcm88312
 
 BROADCOM BRCMSTB GPIO DRIVER
 M:	Gregory Fong <gregory.0xf0 at gmail.com>
-- 
1.9.1



From jonmason at broadcom.com  Wed Aug 26 15:35:29 2015
From: jonmason at broadcom.com (Jon Mason)
Date: Wed, 26 Aug 2015 18:35:29 -0400
Subject: [PATCH v2 4/5] ARM: multi_v7_defconfig: Add NSP to defconfig
In-Reply-To: <1440628530-6137-1-git-send-email-jonmason@broadcom.com>
References: <1440628530-6137-1-git-send-email-jonmason@broadcom.com>
Message-ID: <1440628530-6137-5-git-send-email-jonmason@broadcom.com>

Add the Broadcom Northstar Plus SoC to the multi_v7_defconfig

Signed-off-by: Jon Mason <jonmason at broadcom.com>
---
 arch/arm/configs/multi_v7_defconfig | 1 +
 1 file changed, 1 insertion(+)

diff --git a/arch/arm/configs/multi_v7_defconfig b/arch/arm/configs/multi_v7_defconfig
index 5fd8df6..3fd46f7 100644
--- a/arch/arm/configs/multi_v7_defconfig
+++ b/arch/arm/configs/multi_v7_defconfig
@@ -25,6 +25,7 @@ CONFIG_SOC_SAMA5D3=y
 CONFIG_SOC_SAMA5D4=y
 CONFIG_ARCH_BCM=y
 CONFIG_ARCH_BCM_CYGNUS=y
+CONFIG_ARCH_BCM_NSP=y
 CONFIG_ARCH_BCM_21664=y
 CONFIG_ARCH_BCM_281XX=y
 CONFIG_ARCH_BCM_5301X=y
-- 
1.9.1



From robherring2 at gmail.com  Wed Aug 26 17:35:50 2015
From: robherring2 at gmail.com (Rob Herring)
Date: Wed, 26 Aug 2015 19:35:50 -0500
Subject: [PATCH 1/7] drm/vc4: Add devicetree bindings for VC4.
In-Reply-To: <CAPM=9tw=3yGQE3_G+=ian-+iV-OCRatbFc-stoMczmXeM2Ko+Q@mail.gmail.com>
References: <1439427380-2436-1-git-send-email-eric@anholt.net>
 <1439427380-2436-2-git-send-email-eric@anholt.net>
 <55CEC25E.7070303@wwwdotorg.org>
 <874mjxwyx5.fsf@eliezer.anholt.net>
 <CAL_JsqJxiGUR5BxBPyR3-0NxqWsOxMGrWQA6cMXe2pjTom__nw@mail.gmail.com>
 <CAF6AEGu2fi0M7DsicHz+5SDHi1DyDRmvWjkmYPPgY6pZ423WcA@mail.gmail.com>
 <20150826115229.GI1367@phenom.ffwll.local>
 <20150826120934.GC320@ulmo.nvidia.com>
 <CAL_JsqJ2v=wBaUe_gN_UcpQKis+kRH6oa0NTN24Lp9w9LVWtbQ@mail.gmail.com>
 <CAPM=9tw=3yGQE3_G+=ian-+iV-OCRatbFc-stoMczmXeM2Ko+Q@mail.gmail.com>
Message-ID: <CAL_JsqLPHuzvt-AsSVKLFGbxMQJ6JM4gz1M8UOamSBagHi=vXA@mail.gmail.com>

On Wed, Aug 26, 2015 at 3:59 PM, Dave Airlie <airlied at gmail.com> wrote:
> On 27 August 2015 at 00:30, Rob Herring <robherring2 at gmail.com> wrote:
>> On Wed, Aug 26, 2015 at 7:09 AM, Thierry Reding
>> <thierry.reding at gmail.com> wrote:
>>> On Wed, Aug 26, 2015 at 01:52:29PM +0200, Daniel Vetter wrote:
>>>> On Tue, Aug 25, 2015 at 04:42:18PM -0400, Rob Clark wrote:
>>>> > On Mon, Aug 24, 2015 at 9:47 AM, Rob Herring <robherring2 at gmail.com> wrote:
>>>> > > On Mon, Aug 17, 2015 at 1:30 PM, Eric Anholt <eric at anholt.net> wrote:
>>>> > >> Stephen Warren <swarren at wwwdotorg.org> writes:
>>>> > >>
>>>> > >>> On 08/12/2015 06:56 PM, Eric Anholt wrote:
>>>> > >>>> Signed-off-by: Eric Anholt <eric at anholt.net>
[...]
>>>> > >>>> +- hvss:             List of references to HVS video scalers
>>>> > >>>> +- encoders: List of references to output encoders (HDMI, SDTV)
[...]
>>>> > >>> Of course, this is only appropriate if the HW modules really are
>>>> > >>> logically children of the VC4 HW module. Perhaps they aren't. If they
>>>> > >>> aren't though, I wonder what this "vc4" module actually represents in HW?
>>>> > >>
>>>> > >> It's the subsystem, same as we use a subsystem node for msm, sti,
>>>> > >> rockchip, imx, and exynos.  This appears to be the common model of how
>>>> > >> the collection of graphics-related components is represented in the DT.
>>>> > >
>>>> > > I think most of these bindings are wrong. They are grouped together
>>>> > > because that is what DRM wants not because that reflects the h/w. So
>>>> > > convince me this is one block, not that it is what other people do.
>>>> >
>>>> > I think, when it comes to more complex driver subsystems (like drm in
>>>> > particular) we have a bit of mismatch between how things look from the
>>>> > "pure hw ignoring sw" perspective, and the "how sw and in particular
>>>> > userspace expects things" perspective.  Maybe it is less a problem in
>>>> > other subsystems, where bindings map to things that are only visible
>>>> > in the kernel, or well defined devices like uart or sata controller.
>>>> > But when given the choice, I'm going to err on the side of not
>>>> > confusing userspace and the large software stack that sits above
>>>> > drm/kms, over dt purity.
>>>> >
>>>> > Maybe it would be nice to have a sort of dt overlay that adds the bits
>>>> > needed to tie together hw blocks that should be assembled into a
>>>> > single logical device for linux and userspace (but maybe not some
>>>> > other hypothetical operating system).  But so far that doesn't exist.
>>>> > All we have is a hammer (devicetree), everything looks like a nail.
>>>> > End result is we end up adding some things in the bindings which
>>>> > aren't purely about the hw.  Until someone invents a screwdriver, I'm
>>>> > not sure what else to do.  In the end, other hypothetical OS is free
>>>> > to ignore those extra fields in the bindings if it doesn't need them.
>>>> > So meh?
>>>>
>>>> I thought we agreed a while back that these kind of "pull everything for
>>>> the logical device together" dt nodes which just have piles of phandles
>>>> are totally accepted? At least that's the point behind the component
>>>> helpers, and Eric even suggested to create dt-specific component helpers
>>>> to cut down a bit on the usual boilerplate. dt maintainers are also fine
>>>> with this approach afaik. From my understanding tegra with the host1x bus
>>>> really is the odd one out and not the norm.
>>>
>>> I agree that in many aspects Tegra is somewhat special. But the same
>>> principles that the host1x infrastructure uses could be implemented in a
>>> similar way for other DRM drivers. You can easily collect information
>>> about subdevices by walking the device tree and matching on known
>>> compatible strings. And you can also instantiate the top-level device
>>> from driver code rather than have it in DT. It should still be possible
>>> to make this work without an artificial device node in DT. The component
>>> and master infrastructure is largely orthogonal to that, and as far as I
>>> remember the only blocker is the need for a top-level device. I wonder
>>> if perhaps this could be made to work by binding the master to the top-
>>> level SoC device.
>>>
>>> Obviously adding the node in DT is easier, but to my knowledge easy has
>>> never been a good excuse for mangling DT. Perhaps that's different these
>>> days...
>>
>> I agree we should avoid the virtual node if possible. It is certainly
>> possible as I started out with one and removed it. At least in my
>> case, it essentially required the drm_device and crtc to be a single
>> driver rather than 2 components. However, I'm more concerned that we
>> are consistent from platform to platform where it makes sense than
>> whether we have a somewhat questionable node or not.
>>
> http://lists.freedesktop.org/archives/dri-devel/2013-July/041159.html
>
> So can we at least have some continuity of decision making,
> bikeshedding this every time we submit a driver isn't giving me any
> hope going forward.

As I said, whether we have a virtual node or not is a minor part of
having some consistency in bindings and was the only part Grant
discussed. We have though diverged from the specific problems with
this binding which is that it invents yet another way to describe the
relationship between components. The use of DRM component names in the
binding properties is the first clue. As to what is the "right" way,
well if that is known or documented I've seen no evidence. Defining
what that is and having the infrastructure in place to support it is
what I'm interested in.

Rob


From stefan at agner.ch  Wed Aug 26 18:02:31 2015
From: stefan at agner.ch (Stefan Agner)
Date: Wed, 26 Aug 2015 18:02:31 -0700
Subject: [PATCH v10 1/5] mtd: nand: vf610_nfc: Freescale NFC for VF610,
 MPC5125 and others
In-Reply-To: <20150825201631.GK81844@google.com>
References: <1438594050-4595-1-git-send-email-stefan@agner.ch>
 <1438594050-4595-2-git-send-email-stefan@agner.ch>
 <20150825201631.GK81844@google.com>
Message-ID: <bf1ed158fe08b51c4668faffde44083f@agner.ch>

On 2015-08-25 13:16, Brian Norris wrote:
> A few more comments.
> 
> On Mon, Aug 03, 2015 at 11:27:26AM +0200, Stefan Agner wrote:
>> diff --git a/drivers/mtd/nand/vf610_nfc.c b/drivers/mtd/nand/vf610_nfc.c
>> new file mode 100644
>> index 0000000..5c8dfe8
>> --- /dev/null
>> +++ b/drivers/mtd/nand/vf610_nfc.c
>> @@ -0,0 +1,645 @@
> 
> ...
> 
>> +/*
>> + * This function supports Vybrid only (MPC5125 would have full RB and four CS)
>> + */
>> +static void vf610_nfc_select_chip(struct mtd_info *mtd, int chip)
>> +{
>> +#ifdef CONFIG_SOC_VF610
> 
> Why the #ifdef? I don't see anything compile-time specific to SOC_VF610.
> 
> If this is trying to handle the comment above ("This function supports
> Vybrid only (MPC5125 would have full RB and four CS)") then that's the
> wrong way of doing it, as you need to support multiplatform kernels.
> You'll need to have a way to differentiate the different platform
> support at runtime, not compile time.

Yes it is trying to handle the comment above. Well, the other two
platforms I am aware of are also different architectures... (PowerPC and
ColdFire). I think we won't have a multi-architecture kernel anytime
soon, hence I think removing the code at compile time is the right thing
todo.

However, probably CONFIG_SOC_VF610 is the wrong symbol then, I could
just use CONFIG_ARM and add a comment that this might be different on
another other ARM SoC than VF610.

Just checked CodingStyle, and I see that IS_ENABLED is the preferred way
for conditional compiling.

So my suggestion:

static void vf610_nfc_select_chip(struct mtd_info *mtd, int chip)
{
	struct vf610_nfc *nfc = mtd_to_nfc(mtd);
	u32 tmp = vf610_nfc_read(nfc, NFC_ROW_ADDR);

	if (!IS_ENABLED(CONFIG_ARM))
		return;

	/*
	 * This code is only tested on the ARM platform VF610
	 * PowerPC based MPC5125 would have full RB and four CS
	 */
....

With that the compiler should be able to remove this (currently) ARM
VF610 specific code on the other supported architectures...

What do you think?


> 
>> +	struct vf610_nfc *nfc = mtd_to_nfc(mtd);
>> +	u32 tmp = vf610_nfc_read(nfc, NFC_ROW_ADDR);
>> +
>> +	tmp &= ~(ROW_ADDR_CHIP_SEL_RB_MASK | ROW_ADDR_CHIP_SEL_MASK);
>> +	tmp |= 1 << ROW_ADDR_CHIP_SEL_RB_SHIFT;
>> +
>> +	if (chip == 0)
>> +		tmp |= 1 << ROW_ADDR_CHIP_SEL_SHIFT;
>> +	else if (chip == 1)
>> +		tmp |= 2 << ROW_ADDR_CHIP_SEL_SHIFT;
> 
> 	else ... ?
> 
> Maybe you can write this as a formulaic pattern (e.g.:
> 
> 	tmp |= (chip + 1) << ROW_ADDR_CHIP_SEL_SHIFT;
> 
> ) and just do the "max # of chips" checks on a per-platform basis in the
> probe(). Then I'm guessing this same function can apply to both
> platforms. (I'm not looking at HW datasheets for this, BTW, just
> guessing based on the context here.)

It seems that MCP5125 is different than VF610. MCP5125 has 4 chip
selects and 4 R/B signals, whereas VF610 has only 2 chip selects and
just 1 R/B signals...

> But wait...I see that you call nand_scan_ident() with a max of 1 chip.
> So you won't ever see the chip > 0 case, right?
> 
> So does this driver support multiple flash attached or not? Looks like
> you're assuming you'll only be using chip-select 0. (This is fine for
> now, but at least your code should acknowledge this. Perhaps a comment
> at the top under "limitations.")
> 

Ok, will add that information under limitations.


>> +
>> +	vf610_nfc_write(nfc, NFC_ROW_ADDR, tmp);
>> +#endif
>> +}
> 
> ...
> 
>> +static int vf610_nfc_probe(struct platform_device *pdev)
>> +{
> 
> ...
> 
>> +	/* first scan to find the device and get the page size */
>> +	if (nand_scan_ident(mtd, 1, NULL)) {
>> +		err = -ENXIO;
>> +		goto error;
>> +	}

--
Stefan


From stefan at agner.ch  Wed Aug 26 18:10:05 2015
From: stefan at agner.ch (Stefan Agner)
Date: Wed, 26 Aug 2015 18:10:05 -0700
Subject: [PATCH v10 1/5] mtd: nand: vf610_nfc: Freescale NFC for VF610,
 MPC5125 and others
In-Reply-To: <20150825203412.GM81844@google.com>
References: <1438594050-4595-1-git-send-email-stefan@agner.ch>
 <1438594050-4595-2-git-send-email-stefan@agner.ch>
 <20150825203412.GM81844@google.com>
Message-ID: <a2060e9f1ad9f26e508af64549da52e7@agner.ch>

On 2015-08-25 13:34, Brian Norris wrote:
> One more thing...
> 
> On Mon, Aug 03, 2015 at 11:27:26AM +0200, Stefan Agner wrote:
>> --- /dev/null
>> +++ b/drivers/mtd/nand/vf610_nfc.c
>> @@ -0,0 +1,645 @@
> ...
>> +struct vf610_nfc {
>> +	struct mtd_info mtd;
>> +	struct nand_chip chip;
>> +	struct device *dev;
>> +	void __iomem *regs;
>> +	struct completion cmd_done;
>> +	uint buf_offset;
>> +	int page_sz;
> 
> AFAICT (even with the 2nd patch), you never really use this field. You
> just set it/increment it, but don't use it for anything. Kill it?

It is used in the write path, I think I meant to use it for subpage
writes, when I thought it would just mean to transfer only parts of the
page to the controller.

However, as the subpage discussion basically concluded in not using it
for now on this controller, we can as well transfer the complete page
(page_sz). Or is there another case in which vf610_nfc_write_buf could
be called with less than page_sz?

--
Stefan


From jianhua.ljh at gmail.com  Wed Aug 26 19:43:47 2015
From: jianhua.ljh at gmail.com (Jianhua Liu)
Date: Thu, 27 Aug 2015 10:43:47 +0800
Subject: [PATCH] arm64: fix bug for reloading FPSIMD state after execve on
 cpu 0.
In-Reply-To: <CAKv+Gu_VtFGsKPmFfLHm=kNM=vK=p1TR+fd52P68MiA6J0zUFQ@mail.gmail.com>
References: <1440556841-17219-1-git-send-email-chunyan.zhang@spreadtrum.com>
 <20150826111205.GD30466@arm.com>
 <CAKv+Gu_VtFGsKPmFfLHm=kNM=vK=p1TR+fd52P68MiA6J0zUFQ@mail.gmail.com>
Message-ID: <CAAgTQPUxuDZtuhAHswfW=mt+6qTNfrwY6qonWttyj+PNsp8_FA@mail.gmail.com>

On Wed, Aug 26, 2015 at 7:32 PM, Ard Biesheuvel
<ard.biesheuvel at linaro.org> wrote:
> On 26 August 2015 at 13:12, Will Deacon <will.deacon at arm.com> wrote:
>> Hello,
>>
>> [adding Ard]
>>
>> On Wed, Aug 26, 2015 at 03:40:41AM +0100, Chunyan Zhang wrote:
>>> From: Janet Liu <janet.liu at spreadtrum.com>
>>>
>>> If process A is running on CPU 0 and do execve syscall and after sched_exec,
>>> dest_cpu is 0, fpsimd_state.cpu is 0. If at the time Process A get scheduled
>>> out and after some kernel threads running on CPU 0, process A is back in CPU 0,
>>> A's fpsimd_state.cpu is current cpu id "0", and per_cpu(fpsimd_last_state)
>>> points A's fpsimd_state, TIF_FOREIGN_FPSTATE will be clear, kernel will not
>>> reload the context during it return to userspace. so set the cpu's
>>> fpsimd_last_state to NULL to avoid this.
>>
>> AFAICT, this is only a problem if one of the kernel threads uses the fpsimd
>> registers, right? However, kernel_neon_begin_partial clobbers
>> fpsimd_last_state, so I'm struggling to see the problem.
>>
>
> I think the problem is real, but it would be better to set the
> fpsimd_state::cpu field to an invalid value like we do in
> fpsimd_flush_task_state()
>
> diff --git a/arch/arm64/kernel/fpsimd.c b/arch/arm64/kernel/fpsimd.c
> index 44d6f7545505..c56956a16d3f 100644
> --- a/arch/arm64/kernel/fpsimd.c
> +++ b/arch/arm64/kernel/fpsimd.c
> @@ -158,6 +158,7 @@ void fpsimd_thread_switch(struct task_struct *next)
>  void fpsimd_flush_thread(void)
>  {
>         memset(&current->thread.fpsimd_state, 0, sizeof(struct fpsimd_state));
> +       fpsimd_flush_task_state(current);
>         set_thread_flag(TIF_FOREIGN_FPSTATE);
>  }
>
> (note the memset erroneously initializes that field to CPU 0)
>
> This more accurately reflects the state of the process after forking,
> i.e., that its FPSIMD state has never been loaded into any CPU.

I agree with you.
Can you send a patch to maintainer as soon as possible to solve this issue?


Janet
>
> --
> Ard.
>
>> Are you seeing an issue in practice?
>>
>> Will
>>
>>> Signed-off-by: Janet Liu <janet.liu at spreadtrum.com>
>>> Signed-off-by: Chunyan Zhang <chunyan.zhang at spreadtrum.com>
>>> ---
>>>  arch/arm64/kernel/fpsimd.c |    1 +
>>>  1 file changed, 1 insertion(+)
>>>
>>> diff --git a/arch/arm64/kernel/fpsimd.c b/arch/arm64/kernel/fpsimd.c
>>> index 44d6f75..ec58d94 100644
>>> --- a/arch/arm64/kernel/fpsimd.c
>>> +++ b/arch/arm64/kernel/fpsimd.c
>>> @@ -159,6 +159,7 @@ void fpsimd_flush_thread(void)
>>>  {
>>>       memset(&current->thread.fpsimd_state, 0, sizeof(struct fpsimd_state));
>>>       set_thread_flag(TIF_FOREIGN_FPSTATE);
>>> +     this_cpu_write(fpsimd_last_state, NULL);
>>>  }
>>>
>>>  /*
>>> --
>>> 1.7.9.5
>>>


From agross at codeaurora.org  Wed Aug 26 20:36:20 2015
From: agross at codeaurora.org (Andy Gross)
Date: Wed, 26 Aug 2015 22:36:20 -0500
Subject: [PATCH] arm64: dts: qcom: Add 8x16 Serial UART1 node
Message-ID: <1440646580-28241-1-git-send-email-agross@codeaurora.org>

This patch adds the nodes required to support the UART1 node on the
MSM8916.

Signed-off-by: Andy Gross <agross at codeaurora.org>
---
 arch/arm64/boot/dts/qcom/apq8016-sbc.dtsi |    8 +++++++
 arch/arm64/boot/dts/qcom/msm8916.dtsi     |   35 ++++++++++++++++++++++++++++-
 2 files changed, 42 insertions(+), 1 deletion(-)

diff --git a/arch/arm64/boot/dts/qcom/apq8016-sbc.dtsi b/arch/arm64/boot/dts/qcom/apq8016-sbc.dtsi
index 98abece..3cc53a7 100644
--- a/arch/arm64/boot/dts/qcom/apq8016-sbc.dtsi
+++ b/arch/arm64/boot/dts/qcom/apq8016-sbc.dtsi
@@ -19,6 +19,7 @@
 / {
 	aliases {
 		serial0 = &blsp1_uart2;
+		serial1 = &blsp1_uart1;
 	};
 
 	chosen {
@@ -26,6 +27,13 @@
 	};
 
 	soc {
+		serial at 78af000 {
+			status = "okay";
+			pinctrl-names = "default", "sleep";
+			pinctrl-0 = <&blsp1_uart1_default>;
+			pinctrl-1 = <&blsp1_uart1_sleep>;
+		};
+
 		serial at 78b0000 {
 			status = "okay";
 			pinctrl-names = "default", "sleep";
diff --git a/arch/arm64/boot/dts/qcom/msm8916.dtsi b/arch/arm64/boot/dts/qcom/msm8916.dtsi
index 0f49ebd..ba64447 100644
--- a/arch/arm64/boot/dts/qcom/msm8916.dtsi
+++ b/arch/arm64/boot/dts/qcom/msm8916.dtsi
@@ -91,6 +91,30 @@
 			interrupt-controller;
 			#interrupt-cells = <2>;
 
+			blsp1_uart1_default: blsp1_uart1_default {
+				pinmux {
+					function = "blsp_uart1";
+					pins = "gpio0", "gpio1";
+				};
+				pinconf {
+					pins = "gpio0", "gpio1";
+					drive-strength = <16>;
+					bias-disable;
+				};
+			};
+
+			blsp1_uart1_sleep: blsp1_uart1_sleep {
+				pinmux {
+					function = "gpio";
+					pins = "gpio0", "gpio1";
+				};
+				pinconf {
+					pins = "gpio0", "gpio1";
+					drive-strength = <2>;
+					bias-pull-down;
+				};
+			};
+
 			blsp1_uart2_default: blsp1_uart2_default {
 				pinmux {
 					function = "blsp_uart2";
@@ -105,7 +129,7 @@
 
 			blsp1_uart2_sleep: blsp1_uart2_sleep {
 				pinmux {
-					function = "blsp_uart2";
+					function = "gpio";
 					pins = "gpio4", "gpio5";
 				};
 				pinconf {
@@ -123,6 +147,15 @@
 			reg = <0x1800000 0x80000>;
 		};
 
+		blsp1_uart1: serial at 78af000 {
+			compatible = "qcom,msm-uartdm-v1.4", "qcom,msm-uartdm";
+			reg = <0x78af000 0x200>;
+			interrupts = <GIC_SPI 107 IRQ_TYPE_LEVEL_HIGH>;
+			clocks = <&gcc GCC_BLSP1_UART1_APPS_CLK>, <&gcc GCC_BLSP1_AHB_CLK>;
+			clock-names = "core", "iface";
+			status = "disabled";
+		};
+
 		blsp1_uart2: serial at 78b0000 {
 			compatible = "qcom,msm-uartdm-v1.4", "qcom,msm-uartdm";
 			reg = <0x78b0000 0x200>;
-- 
The Qualcomm Innovation Center, Inc. is a member of the Code Aurora Forum,
hosted by The Linux Foundation



From zhang.chunyan at linaro.org  Wed Aug 26 21:06:09 2015
From: zhang.chunyan at linaro.org (Chunyan Zhang)
Date: Thu, 27 Aug 2015 12:06:09 +0800
Subject: [PATCH] Coresight: ETMv4: Prevent TRCRSCTLR0&1 from being accessed
Message-ID: <1440648369-4614-1-git-send-email-zhang.chunyan@linaro.org>

1. TRCRSCTLRn - Resource Selection Control Registers n=0~1 are reserved,
   we shouldn't access them.
2. The max number of 'n' here is defined in TRCIDR4.NUMRSPAIR whoes value
   indicates the number of resource selection *pairs*, and 0 indicates
   one resource selection pair, 1 indicates two pairs, and so on ...

So, the total number of resource selection control registers which we can
access is (TRCIDR4.NUMRSPAIR * 2)

Signed-off-by: Chunyan Zhang <zhang.chunyan at linaro.org>
---
 drivers/hwtracing/coresight/coresight-etm4x.c | 15 ++++++++++-----
 1 file changed, 10 insertions(+), 5 deletions(-)

diff --git a/drivers/hwtracing/coresight/coresight-etm4x.c b/drivers/hwtracing/coresight/coresight-etm4x.c
index 1312e99..9425249 100644
--- a/drivers/hwtracing/coresight/coresight-etm4x.c
+++ b/drivers/hwtracing/coresight/coresight-etm4x.c
@@ -136,7 +136,9 @@ static void etm4_enable_hw(void *info)
 		writel_relaxed(drvdata->cntr_val[i],
 			       drvdata->base + TRCCNTVRn(i));
 	}
-	for (i = 0; i < drvdata->nr_resource; i++)
+
+	/* Resource selector pair 0 is always implemented and reserved */
+	for (i = 2; i < (drvdata->nr_resource + 1) * 2; i++)
 		writel_relaxed(drvdata->res_ctrl[i],
 			       drvdata->base + TRCRSCTLRn(i));
 
@@ -489,8 +491,9 @@ static ssize_t reset_store(struct device *dev,
 		drvdata->cntr_val[i] = 0x0;
 	}
 
-	drvdata->res_idx = 0x0;
-	for (i = 0; i < drvdata->nr_resource; i++)
+	/* Resource selector pair 0 is always implemented and reserved */
+	drvdata->res_idx = 0x2;
+	for (i = 2; i < (drvdata->nr_resource + 1) * 2; i++)
 		drvdata->res_ctrl[i] = 0x0;
 
 	for (i = 0; i < drvdata->nr_ss_cmp; i++) {
@@ -1729,7 +1732,7 @@ static ssize_t res_idx_store(struct device *dev,
 	if (kstrtoul(buf, 16, &val))
 		return -EINVAL;
 	/* Resource selector pair 0 is always implemented and reserved */
-	if ((val == 0) || (val >= drvdata->nr_resource))
+	if (val < 2 || val > (drvdata->nr_resource + 1) * 2)
 		return -EINVAL;
 
 	/*
@@ -2498,7 +2501,9 @@ static void etm4_init_default_data(struct etmv4_drvdata *drvdata)
 		drvdata->cntr_val[i] = 0x0;
 	}
 
-	for (i = 2; i < drvdata->nr_resource * 2; i++)
+	/* Resource selector pair 0 is always implemented and reserved */
+	drvdata->res_idx = 0x2;
+	for (i = 2; i < (drvdata->nr_resource + 1) * 2; i++)
 		drvdata->res_ctrl[i] = 0x0;
 
 	for (i = 0; i < drvdata->nr_ss_cmp; i++) {
-- 
1.9.1



From agross at codeaurora.org  Wed Aug 26 21:16:51 2015
From: agross at codeaurora.org (Andy Gross)
Date: Wed, 26 Aug 2015 23:16:51 -0500
Subject: [PATCH 03/10] ARM: dts: qcom: apq8064-ifc6410: Use stdout-path
In-Reply-To: <1434490313-13905-4-git-send-email-sboyd@codeaurora.org>
References: <1434490313-13905-1-git-send-email-sboyd@codeaurora.org>
 <1434490313-13905-4-git-send-email-sboyd@codeaurora.org>
Message-ID: <20150827041651.GA28274@qualcomm.com>

On Tue, Jun 16, 2015 at 02:31:46PM -0700, Stephen Boyd wrote:
> Use stdout-path so that we don't have to put the console on the
> kernel command line.
> 
> Signed-off-by: Stephen Boyd <sboyd at codeaurora.org>
> ---
>  arch/arm/boot/dts/qcom-apq8064-ifc6410.dts | 4 ++++
>  1 file changed, 4 insertions(+)
> 
> diff --git a/arch/arm/boot/dts/qcom-apq8064-ifc6410.dts b/arch/arm/boot/dts/qcom-apq8064-ifc6410.dts

Thanks.  Applied.

-- 
Qualcomm Innovation Center, Inc.
The Qualcomm Innovation Center, Inc. is a member of the Code Aurora Forum,
a Linux Foundation Collaborative Project



From agross at codeaurora.org  Wed Aug 26 21:17:28 2015
From: agross at codeaurora.org (Andy Gross)
Date: Wed, 26 Aug 2015 23:17:28 -0500
Subject: [PATCH 04/10] ARM: dts: qcom: apq8074-dragonboard: Use stdout-path
In-Reply-To: <1434490313-13905-5-git-send-email-sboyd@codeaurora.org>
References: <1434490313-13905-1-git-send-email-sboyd@codeaurora.org>
 <1434490313-13905-5-git-send-email-sboyd@codeaurora.org>
Message-ID: <20150827041728.GB28274@qualcomm.com>

On Tue, Jun 16, 2015 at 02:31:47PM -0700, Stephen Boyd wrote:
> Use stdout-path so that we don't have to put the console on the
> kernel command line.
> 
> Signed-off-by: Stephen Boyd <sboyd at codeaurora.org>
> ---
>  arch/arm/boot/dts/qcom-apq8074-dragonboard.dts | 8 ++++++++
>  1 file changed, 8 insertions(+)

Thanks.  Applied.

-- 
Qualcomm Innovation Center, Inc.
The Qualcomm Innovation Center, Inc. is a member of the Code Aurora Forum,
a Linux Foundation Collaborative Project



From a0131933 at ti.com  Wed Aug 26 21:21:41 2015
From: a0131933 at ti.com (Lokesh Vutla)
Date: Thu, 27 Aug 2015 09:51:41 +0530
Subject: [PATCH v3 0/3] ARM: OMAP2+: hwmod: RTC: Add lock and unlock hooks
In-Reply-To: <1437657946-10733-1-git-send-email-lokeshvutla@ti.com>
References: <1437657946-10733-1-git-send-email-lokeshvutla@ti.com>
Message-ID: <55DE9055.4090701@ti.com>

Hi Paul,

On Thursday 23 July 2015 06:55 PM, Lokesh Vutla wrote:
> This series implements lock and unlock functions for RTC and hooks
> the same to DRA7 and AMx3xx hwmod.
> This is dependent on the patch https://patchwork.kernel.org/patch/6578281/,
> which is queued recently by Paul.
Gentle ping on this series.

Thanks and regards,
Lokesh
> 
> Changes since v2:
> - Add kerneldoc for omap_hwmod_rtc_lock() function.
> 
> Lokesh Vutla (3):
>   ARM: hwmod: RTC: Add lock and unlock functions
>   ARM: DRA7: RTC: Add lock and unlock functions
>   ARM: AMx3xx: RTC: Add lock and unlock functions
> 
>  arch/arm/mach-omap2/omap_hwmod.h                   |  2 +
>  .../mach-omap2/omap_hwmod_33xx_43xx_ipblock_data.c |  2 +
>  arch/arm/mach-omap2/omap_hwmod_7xx_data.c          |  2 +
>  arch/arm/mach-omap2/omap_hwmod_reset.c             | 65 ++++++++++++++++++++++
>  4 files changed, 71 insertions(+)
> 


From jianwei.wang.chn at gmail.com  Wed Aug 26 21:19:57 2015
From: jianwei.wang.chn at gmail.com (Jianwei Wang)
Date: Thu, 27 Aug 2015 12:19:57 +0800
Subject: [PATCH 1/2] drm/layerscape: Add HDMI support for DCU DRM driver
Message-ID: <1440649198-27244-1-git-send-email-jianwei.wang.chn@gmail.com>

Some Freescale SoCs, there has an DVI/HDMI controller and a PHY,
attached to one of their display controller unit's LCDC interfaces.
This patch adds a driver for SiI902x. The SiI902x is a HDMI
transmitter It supports resolutions from standard definition
480i/p and 576i/p all the way to high-definition 720p, 1080i,
and 1080p, the highest resolution supported by HDTVs today.

Signed-off-by: Alison Wang <b18965 at freescale.com>
Signed-off-by: Xiubo Li <lixiubo at cmss.chinamobile.com>
Signed-off-by: Jianwei Wang <jianwei.wang.chn at gmail.com>
---
 .../devicetree/bindings/video/SiI902x.txt          |  17 +
 drivers/gpu/drm/fsl-dcu/Makefile                   |   1 +
 drivers/gpu/drm/fsl-dcu/fsl_dcu_drm_hdmi.c         | 639 +++++++++++++++++++++
 drivers/gpu/drm/fsl-dcu/fsl_dcu_drm_kms.c          |  10 +
 drivers/gpu/drm/fsl-dcu/fsl_dcu_drm_output.h       |  10 +
 5 files changed, 677 insertions(+)
 create mode 100644 Documentation/devicetree/bindings/video/SiI902x.txt
 create mode 100644 drivers/gpu/drm/fsl-dcu/fsl_dcu_drm_hdmi.c

diff --git a/Documentation/devicetree/bindings/video/SiI902x.txt b/Documentation/devicetree/bindings/video/SiI902x.txt
new file mode 100644
index 0000000..d304499
--- /dev/null
+++ b/Documentation/devicetree/bindings/video/SiI902x.txt
@@ -0,0 +1,17 @@
+Device-Tree bindings for the SiI902x hdmi transmitter.
+
+Required properties:
+- compatible: 	Should be "sii902x".
+- reg: 		The I2C address of the device.
+- interrupts:	Interrupt number to the cpu.
+
+Example:
+
+&i2c1 {
+       status = "okay";
+       hdmi: sii9022a at 39 {
+             compatible = "sii902x";
+             reg = <0x39>;
+             interrupts = <GIC_SPI 167 IRQ_TYPE_EDGE_RISING>;
+       };
+};
diff --git a/drivers/gpu/drm/fsl-dcu/Makefile b/drivers/gpu/drm/fsl-dcu/Makefile
index 6ea1523..98cacc2 100644
--- a/drivers/gpu/drm/fsl-dcu/Makefile
+++ b/drivers/gpu/drm/fsl-dcu/Makefile
@@ -1,6 +1,7 @@
 fsl-dcu-drm-y := fsl_dcu_drm_drv.o \
 		 fsl_dcu_drm_kms.o \
 		 fsl_dcu_drm_rgb.o \
+		 fsl_dcu_drm_hdmi.o \
 		 fsl_dcu_drm_plane.o \
 		 fsl_dcu_drm_crtc.o \
 		 fsl_dcu_drm_fbdev.o
diff --git a/drivers/gpu/drm/fsl-dcu/fsl_dcu_drm_hdmi.c b/drivers/gpu/drm/fsl-dcu/fsl_dcu_drm_hdmi.c
new file mode 100644
index 0000000..b91c8ca
--- /dev/null
+++ b/drivers/gpu/drm/fsl-dcu/fsl_dcu_drm_hdmi.c
@@ -0,0 +1,639 @@
+/*
+ * Copyright 2015 Freescale Semiconductor, Inc.
+ *
+ * Freescale DCU drm device driver
+ *
+ * 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.
+ */
+
+#include <linux/console.h>
+#include <linux/delay.h>
+#include <linux/errno.h>
+#include <linux/fb.h>
+#include <linux/fsl_devices.h>
+#include <linux/i2c.h>
+#include <linux/init.h>
+#include <linux/interrupt.h>
+#include <linux/kernel.h>
+#include <linux/module.h>
+#include <linux/of_device.h>
+#include <linux/backlight.h>
+#include <video/videomode.h>
+#include <video/of_display_timing.h>
+
+#include <drm/drmP.h>
+#include <drm/drm_atomic_helper.h>
+#include <drm/drm_crtc_helper.h>
+#include <drm/drm_edid.h>
+
+#include "fsl_dcu_drm_drv.h"
+#include "fsl_dcu_drm_output.h"
+
+#define SII902X_INPUT_BUS_FMT	0x08
+#define SII902X_TPI_AVI_INPUT_FMT	0x09
+#define SII902X_TPI_AVI_OUTPUT_FMT	0x0A
+#define SII902X_SYS_CONTROL	0x1A
+#define SII902X_SYS_CTR_DDC_REQ	BIT(2)
+#define SII902X_SYS_CTR_DDC_BUS_AVAI	(BIT(2) | BIT(1))
+#define SII902X_TPI_FAMILY_DEV_ID	0x1B
+#define SII902X_TPI_DEV_REV_ID	0x1C
+#define SII902X_TPI_REV_LEVEL_ID	0x1D
+#define SII902X_POWER_STATE	0x1E
+#define SII902X_TPI_AUDIO_CFG0	0x24
+#define SII902X_TPI_AUDIO_CFG1	0x25
+#define SII902X_TPI_AUDIO_CFG2	0x26
+#define SII902X_TPI_AUDIO_CFG3	0x27
+#define SII902X_TPI_HDCP_REV	0x30
+#define SII902X_TPI_INT_ENABLE	0x3C
+#define SII902X_TPI_INT_STATUS	0x3D
+#define SII902X_TPI_INT_PLUG_IN	BIT(2)
+#define SII902X_GENERAL_PURPOSE_IO0	0xBC
+#define SII902X_GENERAL_PURPOSE_IO1	0xBD
+#define SII902X_GENERAL_PURPOSE_IO2	0xBE
+#define SII902X_TRANS_MODE_DIFF	0xC7
+
+bool g_enable_hdmi;
+
+struct sii902x_data {
+	struct i2c_client *client;
+	struct delayed_work det_work;
+	struct fb_info *fbi;
+	struct fsl_dcu_drm_hdmicon *hdmicon;
+} *sii902x;
+
+static struct i2c_client *sii902x_to_i2c(struct sii902x_data *sii902x)
+{
+	return sii902x->client;
+}
+
+static s32 sii902x_write(const struct i2c_client *client,
+			 u8 command, u8 value)
+{
+	return i2c_smbus_write_byte_data(client, command, value);
+}
+
+static s32 sii902x_read(const struct i2c_client *client, u8 command)
+{
+	int val;
+
+	val = i2c_smbus_read_word_data(client, command);
+
+	return val & 0xff;
+}
+
+static void sii902x_power_up_tx(struct sii902x_data *sii902x)
+{
+	struct i2c_client *client = sii902x_to_i2c(sii902x);
+	int val;
+
+	val = sii902x_read(client, SII902X_POWER_STATE);
+	val &= ~0x3;
+	sii902x_write(client, SII902X_POWER_STATE, val);
+}
+
+static int sii902x_get_edid_preconfig(void)
+{
+	int old, dat, ret = 0, cnt = 100;
+
+	old = sii902x_read(sii902x->client, SII902X_SYS_CONTROL);
+
+	sii902x_write(sii902x->client, SII902X_SYS_CONTROL,
+		      old | SII902X_SYS_CTR_DDC_REQ);
+	do {
+		cnt--;
+		msleep(20);
+		dat = sii902x_read(sii902x->client, SII902X_SYS_CONTROL);
+	} while ((!(dat & 0x2)) && cnt);
+
+	if (!cnt) {
+		ret = -1;
+		goto done;
+	}
+
+	sii902x_write(sii902x->client, SII902X_SYS_CONTROL,
+		      old | SII902X_SYS_CTR_DDC_BUS_AVAI);
+
+done:
+	sii902x_write(sii902x->client, SII902X_SYS_CONTROL, old);
+	return ret;
+}
+
+struct edid *sii902x_drm_get_edid(struct drm_connector *connector,
+				  struct i2c_adapter *adapter)
+{
+	int old, dat, cnt = 100;
+	struct edid *edid;
+
+	old = sii902x_read(sii902x->client, SII902X_SYS_CONTROL);
+
+	sii902x_write(sii902x->client, SII902X_SYS_CONTROL,
+		      old | SII902X_SYS_CTR_DDC_REQ);
+	do {
+		cnt--;
+		msleep(20);
+		dat = sii902x_read(sii902x->client, SII902X_SYS_CONTROL);
+	} while ((!(dat & 0x2)) && cnt);
+
+	if (!cnt) {
+		edid = NULL;
+		goto done;
+	}
+
+	sii902x_write(sii902x->client, SII902X_SYS_CONTROL,
+		      old | SII902X_SYS_CTR_DDC_BUS_AVAI);
+
+	/* edid reading */
+	edid = drm_get_edid(connector, adapter);
+
+	cnt = 100;
+	do {
+		cnt--;
+		sii902x_write(sii902x->client, SII902X_SYS_CONTROL,
+			      old & ~SII902X_SYS_CTR_DDC_BUS_AVAI);
+		msleep(20);
+		dat = sii902x_read(sii902x->client, SII902X_SYS_CONTROL);
+	} while ((dat & 0x6) && cnt);
+
+	if (!cnt)
+		edid = NULL;
+
+done:
+	sii902x_write(sii902x->client, SII902X_SYS_CONTROL, old);
+	return edid;
+}
+
+static void det_worker(struct work_struct *work)
+{
+	struct fb_info *fbi = sii902x->fbi;
+	struct fsl_dcu_drm_hdmicon *hdmicon = sii902x->hdmicon;
+	struct drm_device *dev = hdmicon->connector.dev;
+	int val;
+
+	val = sii902x_read(sii902x->client, SII902X_TPI_INT_STATUS);
+	if (!(val & 0x1) && !g_enable_hdmi)
+		goto err;
+
+	/* cable connection changes */
+	if (val & SII902X_TPI_INT_PLUG_IN || g_enable_hdmi) {
+		hdmicon->status = connector_status_connected;
+
+		/* make sure fb is powerdown */
+		console_lock();
+		fb_blank(fbi, FB_BLANK_POWERDOWN);
+		console_unlock();
+
+		console_lock();
+		fb_blank(fbi, FB_BLANK_UNBLANK);
+		console_unlock();
+	} else {
+		console_lock();
+		fb_blank(fbi, FB_BLANK_POWERDOWN);
+		console_unlock();
+	}
+	drm_helper_hpd_irq_event(dev);
+
+err:
+	sii902x_write(sii902x->client, SII902X_TPI_INT_STATUS, val);
+}
+
+static irqreturn_t sii902x_detect_handler(int irq, void *data)
+{
+	if (g_enable_hdmi)
+		g_enable_hdmi = false;
+
+	if (sii902x->fbi)
+		schedule_delayed_work(&sii902x->det_work,
+				      msecs_to_jiffies(20));
+	return IRQ_HANDLED;
+}
+
+static void sii902x_poweron(void)
+{
+	/* Turn on DVI or HDMI */
+	sii902x_write(sii902x->client, SII902X_SYS_CONTROL, 0x00);
+}
+
+static void sii902x_poweroff(void)
+{
+	/* disable tmds before changing resolution */
+	sii902x_write(sii902x->client, SII902X_SYS_CONTROL, 0x10);
+}
+
+static int sii902x_fb_event(struct notifier_block *nb,
+			    unsigned long val, void *v)
+{
+	struct fb_event *event = v;
+	struct fb_info *fbi = event->info;
+
+	switch (val) {
+	case FB_EVENT_FB_REGISTERED:
+		if (sii902x->fbi)
+			break;
+		sii902x->fbi = fbi;
+		if (g_enable_hdmi && sii902x->fbi) {
+			schedule_delayed_work(&sii902x->det_work,
+					      msecs_to_jiffies(20));
+		}
+		break;
+	case FB_EVENT_MODE_CHANGE:
+		break;
+	case FB_EVENT_BLANK:
+		if (*((int *)event->data) == FB_BLANK_UNBLANK)
+			sii902x_poweron();
+		else
+			sii902x_poweroff();
+		break;
+	}
+
+	return 0;
+}
+
+static void sii902x_chip_id(struct sii902x_data *sii902x)
+{
+	struct i2c_client *client = sii902x_to_i2c(sii902x);
+	int val;
+
+	/* read device ID */
+	val = sii902x_read(client, SII902X_TPI_FAMILY_DEV_ID);
+	pr_info("Sii902x: read id = 0x%02X", val);
+	val = sii902x_read(client, SII902X_TPI_DEV_REV_ID);
+	pr_info("-0x%02X", val);
+	val = sii902x_read(client, SII902X_TPI_REV_LEVEL_ID);
+	pr_info("-0x%02X", val);
+	val = sii902x_read(client, SII902X_TPI_HDCP_REV);
+	pr_info("-0x%02X\n", val);
+}
+
+static int sii902x_initialize(struct sii902x_data *sii902x)
+{
+	struct i2c_client *client = sii902x_to_i2c(sii902x);
+	int ret, cnt;
+
+	for (cnt = 0; cnt < 5; cnt++) {
+		/* Set 902x in hardware TPI mode on and jump out of D3 state */
+		ret = sii902x_write(client, SII902X_TRANS_MODE_DIFF, 0x00);
+		if (ret < 0)
+			break;
+	}
+	if (0 != ret)
+		dev_err(&client->dev, "cound not find device\n");
+
+	return ret;
+}
+
+static void sii902x_enable_source(struct sii902x_data *sii902x)
+{
+	struct i2c_client *client = sii902x_to_i2c(sii902x);
+	int val;
+
+	sii902x_write(client, SII902X_GENERAL_PURPOSE_IO0, 0x01);
+	sii902x_write(client, SII902X_GENERAL_PURPOSE_IO1, 0x82);
+	val = sii902x_read(client, SII902X_GENERAL_PURPOSE_IO2);
+	val |= 0x1;
+	sii902x_write(client, SII902X_GENERAL_PURPOSE_IO2, val);
+}
+
+static struct notifier_block nb = {
+	.notifier_call = sii902x_fb_event,
+};
+
+static int sii902x_probe(struct i2c_client *client,
+			 const struct i2c_device_id *id)
+{
+	struct i2c_adapter *adap = to_i2c_adapter(client->dev.parent);
+	int ret, err;
+
+	if (!g_enable_hdmi)
+		return -EPERM;
+
+	if (!i2c_check_functionality(adap, I2C_FUNC_SMBUS_BYTE)) {
+		dev_err(&client->dev, "i2c_check_functionality error\n");
+		return -ENODEV;
+	}
+
+	sii902x = devm_kzalloc(&client->dev, sizeof(*sii902x), GFP_KERNEL);
+	if (!sii902x)
+		return -ENOMEM;
+
+	sii902x->client = client;
+	i2c_set_clientdata(client, sii902x);
+
+	err = sii902x_initialize(sii902x);
+	if (err)
+		return err;
+
+	sii902x_chip_id(sii902x);
+	sii902x_power_up_tx(sii902x);
+	sii902x_enable_source(sii902x);
+
+	if (sii902x_get_edid_preconfig() < 0)
+		dev_warn(&client->dev, "Read edid preconfig failed\n");
+
+	if (client->irq) {
+		ret = devm_request_irq(&client->dev, client->irq,
+				       sii902x_detect_handler, 0,
+				       "SII902x_det", sii902x);
+		if (ret < 0)
+			dev_warn(&client->dev,
+				 "cound not request det irq %d\n",
+				 client->irq);
+		else {
+			INIT_DELAYED_WORK(&sii902x->det_work, det_worker);
+			/*enable cable hot plug irq*/
+			sii902x_write(client, SII902X_TPI_INT_ENABLE, 0x01);
+		}
+	}
+
+	fb_register_client(&nb);
+
+	return 0;
+}
+
+static int sii902x_remove(struct i2c_client *client)
+{
+	fb_unregister_client(&nb);
+	sii902x_poweroff();
+	return 0;
+}
+
+static const struct i2c_device_id sii902x_id[] = {
+	{ "sii902x", 0 },
+	{},
+};
+MODULE_DEVICE_TABLE(i2c, sii902x_id);
+
+static const struct of_device_id sii902x_dt_ids[] = {
+	{ .compatible = "sii902x", },
+	{ /* sentinel */ }
+};
+MODULE_DEVICE_TABLE(of, sii902x_dt_ids);
+
+static struct i2c_driver sii902x_i2c_driver = {
+	.driver = {
+		.name = "sii902x",
+		.owner = THIS_MODULE,
+		.of_match_table = sii902x_dt_ids,
+	},
+	.probe = sii902x_probe,
+	.remove = sii902x_remove,
+	.id_table = sii902x_id,
+};
+
+static int __init enable_hdmi_setup(char *str)
+{
+	g_enable_hdmi = true;
+
+	return 1;
+}
+__setup("hdmi", enable_hdmi_setup);
+
+static int
+fsl_dcu_drm_hdmienc_atomic_check(struct drm_encoder *encoder,
+				 struct drm_crtc_state *crtc_state,
+				 struct drm_connector_state *conn_state)
+{
+	return 0;
+}
+
+static void fsl_dcu_drm_hdmienc_disable(struct drm_encoder *encoder)
+{
+}
+
+static void fsl_dcu_drm_hdmienc_enable(struct drm_encoder *encoder)
+{
+}
+
+static void fsl_dcu_drm_hdmienc_mode_set(struct drm_encoder *encoder,
+					 struct drm_display_mode *mode,
+					 struct drm_display_mode *adjusted_mode)
+{
+	struct videomode vm;
+	u16 data[4];
+	u32 refresh;
+	u8 *tmp;
+	int i;
+
+	/* Power up */
+	sii902x_power_up_tx(sii902x);
+
+	drm_display_mode_to_videomode(mode, &vm);
+	data[0] = PICOS2KHZ(vm.pixelclock) / 10;
+	data[2] = vm.hsync_len + vm.hback_porch +
+		  vm.hactive + vm.hfront_porch;
+	data[3] = vm.vsync_len + vm.vfront_porch +
+		  vm.vactive + vm.vback_porch;
+	refresh = data[2] * data[3];
+	refresh = (PICOS2KHZ(vm.pixelclock) * 1000) / refresh;
+	data[1] = refresh * 100;
+
+	tmp = (u8 *)data;
+	for (i = 0; i < 8; i++)
+		sii902x_write(sii902x->client, i, tmp[i]);
+
+	/* input bus/pixel: full pixel wide (24bit), rising edge */
+	sii902x_write(sii902x->client, SII902X_INPUT_BUS_FMT, 0x70);
+	/* Set input format to RGB */
+	sii902x_write(sii902x->client, SII902X_TPI_AVI_INPUT_FMT, 0x00);
+	/* set output format to RGB */
+	sii902x_write(sii902x->client, SII902X_TPI_AVI_OUTPUT_FMT, 0x00);
+	/* audio setup */
+	sii902x_write(sii902x->client, SII902X_TPI_AUDIO_CFG1, 0x00);
+	sii902x_write(sii902x->client, SII902X_TPI_AUDIO_CFG2, 0x40);
+	sii902x_write(sii902x->client, SII902X_TPI_AUDIO_CFG3, 0x00);
+}
+
+static const struct drm_encoder_helper_funcs encoder_helper_funcs = {
+	.atomic_check = fsl_dcu_drm_hdmienc_atomic_check,
+	.disable = fsl_dcu_drm_hdmienc_disable,
+	.enable = fsl_dcu_drm_hdmienc_enable,
+	.mode_set = fsl_dcu_drm_hdmienc_mode_set,
+};
+
+static void fsl_dcu_drm_hdmienc_destroy(struct drm_encoder *encoder)
+{
+	drm_encoder_cleanup(encoder);
+}
+
+static const struct drm_encoder_funcs encoder_funcs = {
+	.destroy = fsl_dcu_drm_hdmienc_destroy,
+};
+
+int fsl_dcu_drm_hdmienc_create(struct fsl_dcu_drm_device *fsl_dev,
+			       struct drm_crtc *crtc)
+{
+	struct drm_encoder *encoder;
+	int ret;
+
+	encoder = devm_kzalloc(fsl_dev->dev, sizeof(*encoder), GFP_KERNEL);
+	if (!encoder)
+		return -1;
+
+	encoder->possible_crtcs = 1;
+	ret = drm_encoder_init(fsl_dev->drm, encoder, &encoder_funcs,
+			       DRM_MODE_ENCODER_TMDS);
+	if (ret < 0)
+		return ret;
+
+	drm_encoder_helper_add(encoder, &encoder_helper_funcs);
+	encoder->crtc = crtc;
+
+	return 0;
+}
+
+	struct fsl_dcu_drm_hdmicon *hdmicon;
+#define to_fsl_dcu_drm_hdmicon(connector) \
+	container_of(connector, struct fsl_dcu_drm_hdmicon, connector)
+
+static struct drm_encoder *fsl_dcu_drm_hdmi_find_encoder(struct drm_device *dev)
+{
+	struct drm_encoder *encoder;
+
+	list_for_each_entry(encoder, &dev->mode_config.encoder_list, head) {
+		if (encoder->encoder_type == DRM_MODE_ENCODER_TMDS)
+			return encoder;
+	}
+
+	return NULL;
+}
+
+static void fsl_dcu_drm_hdmicon_destroy(struct drm_connector *connector)
+{
+	drm_connector_unregister(connector);
+	drm_connector_cleanup(connector);
+}
+
+static enum drm_connector_status
+fsl_dcu_drm_hdmicon_detect(struct drm_connector *connector, bool force)
+{
+	struct fsl_dcu_drm_hdmicon *hdmicon = to_fsl_dcu_drm_hdmicon(connector);
+
+	if (hdmicon->status == connector_status_disconnected)
+		return connector_status_disconnected;
+	else
+		return connector_status_connected;
+}
+
+static const struct drm_connector_funcs fsl_dcu_drm_connector_funcs = {
+	.atomic_duplicate_state = drm_atomic_helper_connector_duplicate_state,
+	.atomic_destroy_state = drm_atomic_helper_connector_destroy_state,
+	.destroy = fsl_dcu_drm_hdmicon_destroy,
+	.detect = fsl_dcu_drm_hdmicon_detect,
+	.dpms = drm_atomic_helper_connector_dpms,
+	.fill_modes = drm_helper_probe_single_connector_modes,
+	.reset = drm_atomic_helper_connector_reset,
+};
+
+static struct drm_encoder *
+fsl_dcu_drm_hdmicon_best_encoder(struct drm_connector *connector)
+{
+	struct drm_device *dev = connector->dev;
+
+	return fsl_dcu_drm_hdmi_find_encoder(dev);
+}
+
+static int fsl_dcu_drm_hdmicon_get_modes(struct drm_connector *connector)
+{
+	struct drm_device *dev = connector->dev;
+	struct i2c_adapter *adap = to_i2c_adapter(sii902x->client->dev.parent);
+	struct edid *edid;
+	struct drm_display_mode *mode;
+	int ret;
+
+	edid = sii902x_drm_get_edid(connector, adap);
+	if (edid) {
+		drm_mode_connector_update_edid_property(connector, edid);
+		ret = drm_add_edid_modes(connector, edid);
+		kfree(edid);
+	} else {
+		dev_dbg(dev->dev, "failed to get edid\n");
+	}
+
+	list_for_each_entry(mode, &connector->probed_modes, head) {
+		if (mode->hdisplay == 1024 || mode->vdisplay == 768)
+			mode->type |= DRM_MODE_TYPE_PREFERRED;
+		else
+			mode->type &= ~DRM_MODE_TYPE_PREFERRED;
+	}
+
+	return ret;
+}
+
+static int fsl_dcu_drm_hdmicon_mode_valid(struct drm_connector *connector,
+					  struct drm_display_mode *mode)
+{
+	if (mode->hdisplay > 1024)
+		return MODE_VIRTUAL_X;
+	else if	(mode->vdisplay > 768)
+		return MODE_VIRTUAL_Y;
+
+	return MODE_OK;
+}
+
+static const struct drm_connector_helper_funcs connector_helper_funcs = {
+	.best_encoder = fsl_dcu_drm_hdmicon_best_encoder,
+	.get_modes = fsl_dcu_drm_hdmicon_get_modes,
+	.mode_valid = fsl_dcu_drm_hdmicon_mode_valid,
+};
+
+int fsl_dcu_drm_hdmicon_create(struct fsl_dcu_drm_device *fsl_dev)
+{
+	struct drm_device *dev = fsl_dev->drm;
+	struct fsl_dcu_drm_hdmicon *hdmicon;
+	struct drm_connector *connector;
+	struct drm_encoder *encoder;
+	int ret;
+
+	i2c_add_driver(&sii902x_i2c_driver);
+
+	hdmicon = devm_kzalloc(fsl_dev->dev,
+			       sizeof(struct fsl_dcu_drm_hdmicon), GFP_KERNEL);
+	if (!hdmicon)
+		return -ENOMEM;
+
+	connector = &hdmicon->connector;
+	sii902x->hdmicon = hdmicon;
+
+	connector->display_info.width_mm = 0;
+	connector->display_info.height_mm = 0;
+	connector->polled = DRM_CONNECTOR_POLL_HPD;
+
+	ret = drm_connector_init(fsl_dev->drm, connector,
+				 &fsl_dcu_drm_connector_funcs,
+				 DRM_MODE_CONNECTOR_HDMIA);
+	if (ret < 0)
+		return ret;
+
+	connector->dpms = DRM_MODE_DPMS_OFF;
+	drm_connector_helper_add(connector, &connector_helper_funcs);
+	ret = drm_connector_register(connector);
+	if (ret < 0)
+		goto err_cleanup;
+
+	encoder = fsl_dcu_drm_hdmi_find_encoder(dev);
+	if (!encoder)
+		goto err_cleanup;
+	ret = drm_mode_connector_attach_encoder(connector, encoder);
+	if (ret < 0)
+		goto err_sysfs;
+
+	connector->encoder = encoder;
+
+	drm_object_property_set_value
+		(&connector->base, fsl_dev->drm->mode_config.dpms_property,
+		DRM_MODE_DPMS_OFF);
+
+	return 0;
+
+err_sysfs:
+	drm_connector_unregister(connector);
+err_cleanup:
+	drm_connector_cleanup(connector);
+	return ret;
+}
+
+MODULE_AUTHOR("Freescale Semiconductor, Inc.");
+MODULE_DESCRIPTION("SII902x DVI/HDMI driver");
+MODULE_LICENSE("GPL");
diff --git a/drivers/gpu/drm/fsl-dcu/fsl_dcu_drm_kms.c b/drivers/gpu/drm/fsl-dcu/fsl_dcu_drm_kms.c
index 0ef5959..f42ef5f 100644
--- a/drivers/gpu/drm/fsl-dcu/fsl_dcu_drm_kms.c
+++ b/drivers/gpu/drm/fsl-dcu/fsl_dcu_drm_kms.c
@@ -17,10 +17,18 @@
 #include "fsl_dcu_drm_crtc.h"
 #include "fsl_dcu_drm_drv.h"
 
+static void fsl_dcu_drm_output_poll_changed(struct drm_device *dev)
+{
+	struct fsl_dcu_drm_device *fsl_dev = dev->dev_private;
+
+	drm_fbdev_cma_hotplug_event(fsl_dev->fbdev);
+}
+
 static const struct drm_mode_config_funcs fsl_dcu_drm_mode_config_funcs = {
 	.atomic_check = drm_atomic_helper_check,
 	.atomic_commit = drm_atomic_helper_commit,
 	.fb_create = drm_fb_cma_create,
+	.output_poll_changed = fsl_dcu_drm_output_poll_changed,
 };
 
 int fsl_dcu_drm_modeset_init(struct fsl_dcu_drm_device *fsl_dev)
@@ -36,7 +44,9 @@ int fsl_dcu_drm_modeset_init(struct fsl_dcu_drm_device *fsl_dev)
 	drm_kms_helper_poll_init(fsl_dev->drm);
 	fsl_dcu_drm_crtc_create(fsl_dev);
 	fsl_dcu_drm_encoder_create(fsl_dev, &fsl_dev->crtc);
+	fsl_dcu_drm_hdmienc_create(fsl_dev, &fsl_dev->crtc);
 	fsl_dcu_drm_connector_create(fsl_dev, &fsl_dev->encoder);
+	fsl_dcu_drm_hdmicon_create(fsl_dev);
 	drm_mode_config_reset(fsl_dev->drm);
 
 	return 0;
diff --git a/drivers/gpu/drm/fsl-dcu/fsl_dcu_drm_output.h b/drivers/gpu/drm/fsl-dcu/fsl_dcu_drm_output.h
index 7093109..feab158 100644
--- a/drivers/gpu/drm/fsl-dcu/fsl_dcu_drm_output.h
+++ b/drivers/gpu/drm/fsl-dcu/fsl_dcu_drm_output.h
@@ -18,6 +18,12 @@ struct fsl_dcu_drm_connector {
 	struct drm_panel *panel;
 };
 
+struct fsl_dcu_drm_hdmicon {
+	struct drm_connector connector;
+	struct i2c_client *client;
+	enum drm_connector_status status;
+};
+
 static inline struct fsl_dcu_drm_connector *
 to_fsl_dcu_connector(struct drm_connector *con)
 {
@@ -29,5 +35,9 @@ int fsl_dcu_drm_connector_create(struct fsl_dcu_drm_device *fsl_dev,
 				 struct drm_encoder *encoder);
 int fsl_dcu_drm_encoder_create(struct fsl_dcu_drm_device *fsl_dev,
 			       struct drm_crtc *crtc);
+int fsl_dcu_drm_hdmicon_create(struct fsl_dcu_drm_device *fsl_dev);
+int fsl_dcu_drm_hdmienc_create(struct fsl_dcu_drm_device *fsl_dev,
+			       struct drm_crtc *crtc);
+
 
 #endif /* __FSL_DCU_DRM_CONNECTOR_H__ */
-- 
2.1.0.27.g96db324



From jianwei.wang.chn at gmail.com  Wed Aug 26 21:19:58 2015
From: jianwei.wang.chn at gmail.com (Jianwei Wang)
Date: Thu, 27 Aug 2015 12:19:58 +0800
Subject: [PATCH 2/2] arm:dts:ls1021a: Add SiI902x dts node
In-Reply-To: <1440649198-27244-1-git-send-email-jianwei.wang.chn@gmail.com>
References: <1440649198-27244-1-git-send-email-jianwei.wang.chn@gmail.com>
Message-ID: <1440649198-27244-2-git-send-email-jianwei.wang.chn@gmail.com>

The SiI902x is a HDMI transmitter.

Signed-off-by: Alison Wang <b18965 at freescale.com>
Signed-off-by: Xiubo Li <lixiubo at cmss.chinamobile.com>
Signed-off-by: Jianwei Wang <jianwei.wang.chn at gmail.com>
---
 arch/arm/boot/dts/ls1021a-twr.dts | 6 ++++++
 1 file changed, 6 insertions(+)

diff --git a/arch/arm/boot/dts/ls1021a-twr.dts b/arch/arm/boot/dts/ls1021a-twr.dts
index a2c591e..c3140f0 100644
--- a/arch/arm/boot/dts/ls1021a-twr.dts
+++ b/arch/arm/boot/dts/ls1021a-twr.dts
@@ -79,6 +79,12 @@
 
 &i2c1 {
 	status = "okay";
+
+	hdmi: sii9022a at 39 {
+		compatible = "sii902x";
+		reg = <0x39>;
+		interrupts = <GIC_SPI 167 IRQ_TYPE_EDGE_RISING>;
+		};
 };
 
 &ifc {
-- 
2.1.0.27.g96db324



From agross at codeaurora.org  Wed Aug 26 21:27:47 2015
From: agross at codeaurora.org (Andy Gross)
Date: Wed, 26 Aug 2015 23:27:47 -0500
Subject: [PATCH 05/10] ARM: dts: qcom: apq8084-ifc6540: Use stdout-path
In-Reply-To: <1434490313-13905-6-git-send-email-sboyd@codeaurora.org>
References: <1434490313-13905-1-git-send-email-sboyd@codeaurora.org>
 <1434490313-13905-6-git-send-email-sboyd@codeaurora.org>
Message-ID: <20150827042747.GC28274@qualcomm.com>

On Tue, Jun 16, 2015 at 02:31:48PM -0700, Stephen Boyd wrote:
> Use stdout-path so that we don't have to put the console on the
> kernel command line.
> 
> Signed-off-by: Stephen Boyd <sboyd at codeaurora.org>
> ---
>  arch/arm/boot/dts/qcom-apq8084-ifc6540.dts | 8 ++++++++
>  1 file changed, 8 insertions(+)

Applied.  Thanks

-- 
Qualcomm Innovation Center, Inc.
The Qualcomm Innovation Center, Inc. is a member of the Code Aurora Forum,
a Linux Foundation Collaborative Project



From agross at codeaurora.org  Wed Aug 26 21:28:13 2015
From: agross at codeaurora.org (Andy Gross)
Date: Wed, 26 Aug 2015 23:28:13 -0500
Subject: [PATCH 09/10] ARM: dts: qcom: msm8960-cdp: Use stdout-path
In-Reply-To: <1434490313-13905-10-git-send-email-sboyd@codeaurora.org>
References: <1434490313-13905-1-git-send-email-sboyd@codeaurora.org>
 <1434490313-13905-10-git-send-email-sboyd@codeaurora.org>
Message-ID: <20150827042813.GD28274@qualcomm.com>

On Tue, Jun 16, 2015 at 02:31:52PM -0700, Stephen Boyd wrote:
> Use stdout-path so that we don't have to put the console on the
> kernel command line.
> 
> Signed-off-by: Stephen Boyd <sboyd at codeaurora.org>
> ---
>  arch/arm/boot/dts/qcom-msm8960-cdp.dts | 8 ++++++++
>  1 file changed, 8 insertions(+)

Applied.  Thanks

-- 
Qualcomm Innovation Center, Inc.
The Qualcomm Innovation Center, Inc. is a member of the Code Aurora Forum,
a Linux Foundation Collaborative Project



From agross at codeaurora.org  Wed Aug 26 21:33:49 2015
From: agross at codeaurora.org (Andy Gross)
Date: Wed, 26 Aug 2015 23:33:49 -0500
Subject: [PATCH 02/10] ARM: dts: qcom: apq8064-cm-qs600: Use stdout-path
In-Reply-To: <1434490313-13905-3-git-send-email-sboyd@codeaurora.org>
References: <1434490313-13905-1-git-send-email-sboyd@codeaurora.org>
 <1434490313-13905-3-git-send-email-sboyd@codeaurora.org>
Message-ID: <20150827043349.GE28274@qualcomm.com>

On Tue, Jun 16, 2015 at 02:31:45PM -0700, Stephen Boyd wrote:
> Use stdout-path so that we don't have to put the console on the
> kernel command line.
> 
> Cc: Mike Rapoport <mike.rapoport at gmail.com>
> Cc: Igor Grinberg <grinberg at compulab.co.il>
> Signed-off-by: Stephen Boyd <sboyd at codeaurora.org>
> ---
>  arch/arm/boot/dts/qcom-apq8064-cm-qs600.dts | 8 ++++++++
>  1 file changed, 8 insertions(+)


Applied.  Thanks

-- 
Qualcomm Innovation Center, Inc.
The Qualcomm Innovation Center, Inc. is a member of the Code Aurora Forum,
a Linux Foundation Collaborative Project



From agross at codeaurora.org  Wed Aug 26 21:34:11 2015
From: agross at codeaurora.org (Andy Gross)
Date: Wed, 26 Aug 2015 23:34:11 -0500
Subject: [PATCH 07/10] ARM: dts: qcom: ipq8064-ap148: Use stdout-path
In-Reply-To: <1434490313-13905-8-git-send-email-sboyd@codeaurora.org>
References: <1434490313-13905-1-git-send-email-sboyd@codeaurora.org>
 <1434490313-13905-8-git-send-email-sboyd@codeaurora.org>
Message-ID: <20150827043411.GF28274@qualcomm.com>

On Tue, Jun 16, 2015 at 02:31:50PM -0700, Stephen Boyd wrote:
> Use stdout-path so that we don't have to put the console on the
> kernel command line.
> 
> Cc: Mathieu Olivari <mathieu at codeaurora.org>
> Signed-off-by: Stephen Boyd <sboyd at codeaurora.org>
> ---
>  arch/arm/boot/dts/qcom-ipq8064-ap148.dts | 8 ++++++++
>  1 file changed, 8 insertions(+)

Applied thanks

-- 
Qualcomm Innovation Center, Inc.
The Qualcomm Innovation Center, Inc. is a member of the Code Aurora Forum,
a Linux Foundation Collaborative Project



From agross at codeaurora.org  Wed Aug 26 21:35:29 2015
From: agross at codeaurora.org (Andy Gross)
Date: Wed, 26 Aug 2015 23:35:29 -0500
Subject: [PATCH 01/10] ARM: dts: qcom: Label serial nodes for aliasing
 and stdout-path
In-Reply-To: <1434490313-13905-2-git-send-email-sboyd@codeaurora.org>
References: <1434490313-13905-1-git-send-email-sboyd@codeaurora.org>
 <1434490313-13905-2-git-send-email-sboyd@codeaurora.org>
Message-ID: <20150827043529.GG28274@qualcomm.com>

On Tue, Jun 16, 2015 at 02:31:44PM -0700, Stephen Boyd wrote:
> Add a label to the serial nodes that are being used for the
> console.
> 
> Signed-off-by: Stephen Boyd <sboyd at codeaurora.org>
> ---

Applied.  Thanks

-- 
Qualcomm Innovation Center, Inc.
The Qualcomm Innovation Center, Inc. is a member of the Code Aurora Forum,
a Linux Foundation Collaborative Project



From agross at codeaurora.org  Wed Aug 26 21:36:05 2015
From: agross at codeaurora.org (Andy Gross)
Date: Wed, 26 Aug 2015 23:36:05 -0500
Subject: [PATCH 08/10] ARM: dts: qcom: msm8660-surf: Use stdout-path
In-Reply-To: <1434490313-13905-9-git-send-email-sboyd@codeaurora.org>
References: <1434490313-13905-1-git-send-email-sboyd@codeaurora.org>
 <1434490313-13905-9-git-send-email-sboyd@codeaurora.org>
Message-ID: <20150827043605.GH28274@qualcomm.com>

On Tue, Jun 16, 2015 at 02:31:51PM -0700, Stephen Boyd wrote:
> Use stdout-path so that we don't have to put the console on the
> kernel command line.
> 
> Signed-off-by: Stephen Boyd <sboyd at codeaurora.org>
> ---
>  arch/arm/boot/dts/qcom-msm8660-surf.dts | 8 ++++++++
>  1 file changed, 8 insertions(+)

Applied.  thanks

-- 
Qualcomm Innovation Center, Inc.
The Qualcomm Innovation Center, Inc. is a member of the Code Aurora Forum,
a Linux Foundation Collaborative Project



From agross at codeaurora.org  Wed Aug 26 21:36:30 2015
From: agross at codeaurora.org (Andy Gross)
Date: Wed, 26 Aug 2015 23:36:30 -0500
Subject: [PATCH 10/10] ARM: dts: qcom: msm8974-sony-xperia-honami: Use
 stdout-path
In-Reply-To: <1434490313-13905-11-git-send-email-sboyd@codeaurora.org>
References: <1434490313-13905-1-git-send-email-sboyd@codeaurora.org>
 <1434490313-13905-11-git-send-email-sboyd@codeaurora.org>
Message-ID: <20150827043630.GI28274@qualcomm.com>

On Tue, Jun 16, 2015 at 02:31:53PM -0700, Stephen Boyd wrote:
> Use stdout-path so that we don't have to put the console on the
> kernel command line.
> 
> Cc: Tim Bird <tim.bird at sonymobile.com>
> Cc: Bjorn Andersson <bjorn.andersson at sonymobile.com>
> Signed-off-by: Stephen Boyd <sboyd at codeaurora.org>
> ---
>  arch/arm/boot/dts/qcom-msm8974-sony-xperia-honami.dts | 8 ++++++++
>  1 file changed, 8 insertions(+)
> 

Applied.  Thanks

-- 
Qualcomm Innovation Center, Inc.
The Qualcomm Innovation Center, Inc. is a member of the Code Aurora Forum,
a Linux Foundation Collaborative Project



From agross at codeaurora.org  Wed Aug 26 21:36:54 2015
From: agross at codeaurora.org (Andy Gross)
Date: Wed, 26 Aug 2015 23:36:54 -0500
Subject: [PATCH 06/10] ARM: dts: qcom: apq8084-mtp: Use stdout-path
In-Reply-To: <1434490313-13905-7-git-send-email-sboyd@codeaurora.org>
References: <1434490313-13905-1-git-send-email-sboyd@codeaurora.org>
 <1434490313-13905-7-git-send-email-sboyd@codeaurora.org>
Message-ID: <20150827043654.GJ28274@qualcomm.com>

On Tue, Jun 16, 2015 at 02:31:49PM -0700, Stephen Boyd wrote:
> Use stdout-path so that we don't have to put the console on the
> kernel command line.
> 
> Signed-off-by: Stephen Boyd <sboyd at codeaurora.org>
> ---
>  arch/arm/boot/dts/qcom-apq8084-mtp.dts | 8 ++++++++
>  1 file changed, 8 insertions(+)


Applied.  Thanks

-- 
Qualcomm Innovation Center, Inc.
The Qualcomm Innovation Center, Inc. is a member of the Code Aurora Forum,
a Linux Foundation Collaborative Project



From agross at codeaurora.org  Wed Aug 26 21:53:48 2015
From: agross at codeaurora.org (Andy Gross)
Date: Wed, 26 Aug 2015 23:53:48 -0500
Subject: [PATCH v2 5/6] ARM: dts: qs600: add alias to serial0
In-Reply-To: <20150825214622.GC12349@qualcomm.com>
References: <1439903069-19752-1-git-send-email-srinivas.kandagatla@linaro.org>
 <1439903427-20317-1-git-send-email-srinivas.kandagatla@linaro.org>
 <20150825214622.GC12349@qualcomm.com>
Message-ID: <20150827045348.GK28274@qualcomm.com>

On Tue, Aug 25, 2015 at 04:46:22PM -0500, Andy Gross wrote:
> On Tue, Aug 18, 2015 at 02:10:27PM +0100, Srinivas Kandagatla wrote:
> > This patch add alias node with serial0.
> > 
> > Signed-off-by: Srinivas Kandagatla <srinivas.kandagatla at linaro.org>
> > ---
> >  arch/arm/boot/dts/qcom-apq8064-cm-qs600.dts | 4 ++++
> >  1 file changed, 4 insertions(+)
> 
> Looks fine.  Applied.

Scratch that.  I dropped it from the patch list due to stephen's set.

-- 
Qualcomm Innovation Center, Inc.
The Qualcomm Innovation Center, Inc. is a member of the Code Aurora Forum,
a Linux Foundation Collaborative Project



From varada at codeaurora.org  Wed Aug 26 22:31:38 2015
From: varada at codeaurora.org (Varadarajan Narayanan)
Date: Thu, 27 Aug 2015 11:01:38 +0530
Subject: [PATCH v4] qcom: ipq4019: Add basic board/dts support for IPQ4019 SoC
Message-ID: <20150827053138.GA24234@codeaurora.org>

Add initial dts files and SoC support for IPQ4019

Signed-off-by: Varadarajan Narayanan <varada at codeaurora.org>
---
All,
	Missed linux-arm-msm mailing list last time and
	incorrectly versioned the patch as v5.
	Kindly excuse.

Changes in v2:
  - Added devicetree bindings documentation

Changes in v3:
  - Split 'gcnt' into a separate patch
  - Added the new entries to Makefiles, Kconfig & board.c in sorted order
  - Used "qcom,ipq40xx" instead of "qcom,ipq40xx-r3pc" in board.c

Changes in v4:
  - Removed r3pc dts
  - Removed timer frequency

 arch/arm/boot/dts/qcom-ipq4019.dtsi | 72 +++++++++++++++++++++++++++++++++++++
 1 file changed, 72 insertions(+)
 create mode 100644 arch/arm/boot/dts/qcom-ipq4019.dtsi

diff --git a/arch/arm/boot/dts/qcom-ipq4019.dtsi b/arch/arm/boot/dts/qcom-ipq4019.dtsi
new file mode 100644
index 0000000..668cc84
--- /dev/null
+++ b/arch/arm/boot/dts/qcom-ipq4019.dtsi
@@ -0,0 +1,72 @@
+/*
+ * Copyright (c) 2014, The Linux Foundation. All rights reserved.
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License version 2 and
+ * only 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.
+ */
+
+/dts-v1/;
+
+#include "skeleton.dtsi"
+
+/ {
+	model = "Qualcomm Technologies, Inc. IPQ4019";
+	compatible = "qcom,ipq4019";
+	interrupt-parent = <&intc>;
+
+	cpus {
+		#address-cells = <1>;
+		#size-cells = <0>;
+		cpu at 0 {
+			device_type = "cpu";
+			compatible = "arm,cortex-a7";
+			reg = <0x0>;
+		};
+
+		cpu at 1 {
+			device_type = "cpu";
+			compatible = "arm,cortex-a7";
+			reg = <0x1>;
+		};
+
+		cpu at 2 {
+			device_type = "cpu";
+			compatible = "arm,cortex-a7";
+			reg = <0x2>;
+		};
+
+		cpu at 3 {
+			device_type = "cpu";
+			compatible = "arm,cortex-a7";
+			reg = <0x3>;
+		};
+	};
+
+	soc {
+		#address-cells = <1>;
+		#size-cells = <1>;
+		ranges;
+		compatible = "simple-bus";
+
+		intc: interrupt-controller at b000000 {
+			compatible = "qcom,msm-qgic2";
+			interrupt-controller;
+			#interrupt-cells = <3>;
+			reg = <0x0b000000 0x1000>,
+			<0x0b002000 0x1000>;
+		};
+
+		serial at 78b0000 {
+			compatible = "qcom,msm-uartdm-v1.4", "qcom,msm-uartdm";
+			reg = <0x78b0000 0x200>;
+			interrupts = <0 108 0>;
+			status = "disabled";
+		};
+	};
+};
-- 
1.8.2.1



From mpa at pengutronix.de  Wed Aug 26 22:49:25 2015
From: mpa at pengutronix.de (Markus Pargmann)
Date: Thu, 27 Aug 2015 07:49:25 +0200
Subject: [PATCH] regmap: Fix the null function of format_val on
 regmap_bulk_read.
In-Reply-To: <20150826173812.GA28760@sirena.org.uk>
References: <1440589396-696-1-git-send-email-henryc.chen@mediatek.com>
 <20150826123556.GB2977@sirena.org.uk>
 <20150826132246.GR706@pengutronix.de>
 <20150826173812.GA28760@sirena.org.uk>
Message-ID: <20150827054925.GK706@pengutronix.de>

On Wed, Aug 26, 2015 at 06:38:12PM +0100, Mark Brown wrote:
> On Wed, Aug 26, 2015 at 03:22:46PM +0200, Markus Pargmann wrote:
> > On Wed, Aug 26, 2015 at 01:35:56PM +0100, Mark Brown wrote:
> > > On Wed, Aug 26, 2015 at 07:43:16PM +0800, Henry Chen wrote:
> 
> > > Why are these format functions sensible?  Converting a null pointer
> > > dereference into data corruption wouldn't be ideal.  The commit message
> > > should really cover this.
> 
> > The regmap_bulk_read() function worked before the following patch:
> > 	15b8d2c41fe5 (regmap: Fix regmap_bulk_read in BE mode)
> 
> Define "worked" here.

"worked" means here that it did not run into a null pointer and returned
something that the user expected. I am not sure if someone actually
complained about the previous use of memcpy? I also don't know how the
behavior of regmap_bulk_read with reg_read() is defined.

Best Regards,

Markus

> 
> > As far as I can see this patch fixes this issue by using simple format
> > functions. Before the above mentioned patch, the code used memcpy. Now
> > regmap_format_*_native is used which should result in the same behaviour
> > but fixes the null pointer.
> 
> Again, this sort of analysis needs to be in the commit message (and
> really ought to explain why the resulting API makes sense).
> 
> > I am not sure if there are other locations in the code where format_val
> > is used in this setup so I don't know if this would change behavior in a
> > different codepath.
> 
> Which is another part of the concern, being able to format values is a
> more general concept.



-- 
Pengutronix e.K.                           |                             |
Industrial Linux Solutions                 | http://www.pengutronix.de/  |
Peiner Str. 6-8, 31137 Hildesheim, Germany | Phone: +49-5121-206917-0    |
Amtsgericht Hildesheim, HRA 2686           | Fax:   +49-5121-206917-5555 |
-------------- next part --------------
A non-text attachment was scrubbed...
Name: signature.asc
Type: application/pgp-signature
Size: 819 bytes
Desc: Digital signature
URL: <http://lists.infradead.org/pipermail/linux-arm-kernel/attachments/20150827/7e3ac6bd/attachment.sig>

From ard.biesheuvel at linaro.org  Wed Aug 26 23:12:33 2015
From: ard.biesheuvel at linaro.org (Ard Biesheuvel)
Date: Thu, 27 Aug 2015 08:12:33 +0200
Subject: [PATCH] arm64: flush FP/SIMD state correctly after execve()
Message-ID: <1440655953-31431-1-git-send-email-ard.biesheuvel@linaro.org>

When a task calls execve(), its FP/SIMD state is flushed so that
none of the original program state is observeable by the incoming
program.

However, since this flushing consists of setting the in-memory copy
of the FP/SIMD state to all zeroes, the CPU field is set to CPU 0 as
well, which indicates to the lazy FP/SIMD preserve/restore code that
the FP/SIMD state does not need to be reread from memory if the task
is scheduled again on CPU 0 without any other tasks having entered
userland (or used the FP/SIMD in kernel mode) on the same CPU in the
mean time. If this happens, the FP/SIMD state of the old program will
still be present in the registers when the new program starts.

So set the CPU field to the invalid value of NR_CPUS when performing
the flush, by calling fpsimd_flush_task_state().

Signed-off-by: Ard Biesheuvel <ard.biesheuvel at linaro.org>
---
 arch/arm64/kernel/fpsimd.c | 1 +
 1 file changed, 1 insertion(+)

diff --git a/arch/arm64/kernel/fpsimd.c b/arch/arm64/kernel/fpsimd.c
index 44d6f7545505..c56956a16d3f 100644
--- a/arch/arm64/kernel/fpsimd.c
+++ b/arch/arm64/kernel/fpsimd.c
@@ -158,6 +158,7 @@ void fpsimd_thread_switch(struct task_struct *next)
 void fpsimd_flush_thread(void)
 {
 	memset(&current->thread.fpsimd_state, 0, sizeof(struct fpsimd_state));
+	fpsimd_flush_task_state(current);
 	set_thread_flag(TIF_FOREIGN_FPSTATE);
 }
 
-- 
1.9.1



From jianwei.wang.chn at gmail.com  Wed Aug 26 23:13:46 2015
From: jianwei.wang.chn at gmail.com (Jianwei Wang)
Date: Thu, 27 Aug 2015 14:13:46 +0800
Subject: [PATCH v15 1/2] arm:dts:ls1021a: Add DCU dts node
Message-ID: <1440656027-8542-1-git-send-email-jianwei.wang.chn@gmail.com>

Add DCU node, DCU is a display controller of Freescale
named 2D-ACE.

Signed-off-by: Alison Wang <b18965 at freescale.com>
Signed-off-by: Xiubo Li <lixiubo at cmss.chinamobile.com>
Signed-off-by: Jianwei Wang <jianwei.wang.chn at gmail.com>
---
 arch/arm/boot/dts/ls1021a.dtsi | 10 ++++++++++
 1 file changed, 10 insertions(+)

diff --git a/arch/arm/boot/dts/ls1021a.dtsi b/arch/arm/boot/dts/ls1021a.dtsi
index c70bb27..6d6e3e2 100644
--- a/arch/arm/boot/dts/ls1021a.dtsi
+++ b/arch/arm/boot/dts/ls1021a.dtsi
@@ -383,6 +383,16 @@
 				 <&platform_clk 1>;
 		};
 
+		dcu: dcu at 2ce0000 {
+			compatible = "fsl,ls1021a-dcu";
+			reg = <0x0 0x2ce0000 0x0 0x10000>;
+			interrupts = <GIC_SPI 172 IRQ_TYPE_LEVEL_HIGH>;
+			clocks = <&platform_clk 0>;
+			clock-names = "dcu";
+			big-endian;
+			status = "disabled";
+		};
+
 		mdio0: mdio at 2d24000 {
 			compatible = "gianfar";
 			device_type = "mdio";
-- 
2.1.0.27.g96db324



From jianwei.wang.chn at gmail.com  Wed Aug 26 23:13:47 2015
From: jianwei.wang.chn at gmail.com (Jianwei Wang)
Date: Thu, 27 Aug 2015 14:13:47 +0800
Subject: [PATCH v15 2/2] arm:dts:ls1021a: Add a TFT LCD panel dts node
In-Reply-To: <1440656027-8542-1-git-send-email-jianwei.wang.chn@gmail.com>
References: <1440656027-8542-1-git-send-email-jianwei.wang.chn@gmail.com>
Message-ID: <1440656027-8542-2-git-send-email-jianwei.wang.chn@gmail.com>

Add a TFT LCD panel. the TFT LCD panel is WQVGA "480x272",
and the bpp is 24.

Signed-off-by: Alison Wang <b18965 at freescale.com>
Signed-off-by: Xiubo Li <lixiubo at cmss.chinamobile.com>
Signed-off-by: Jianwei Wang <jianwei.wang.chn at gmail.com>
---

Changed in V15:
Rename compatible string.

 arch/arm/boot/dts/ls1021a-twr.dts | 11 +++++++++++
 1 file changed, 11 insertions(+)

diff --git a/arch/arm/boot/dts/ls1021a-twr.dts b/arch/arm/boot/dts/ls1021a-twr.dts
index a2c591e..99c6aad 100644
--- a/arch/arm/boot/dts/ls1021a-twr.dts
+++ b/arch/arm/boot/dts/ls1021a-twr.dts
@@ -56,6 +56,17 @@
 		enet0_sgmii_phy = &sgmii_phy2;
 		enet1_sgmii_phy = &sgmii_phy0;
 	};
+
+	panel: panel {
+		compatible = "nec,nl4827hc19-05b";
+	};
+
+};
+
+&dcu {
+	fsl,panel = <&panel>;
+	status = "okay";
+
 };
 
 &dspi1 {
-- 
2.1.0.27.g96db324



From sfr at canb.auug.org.au  Wed Aug 26 23:22:29 2015
From: sfr at canb.auug.org.au (Stephen Rothwell)
Date: Thu, 27 Aug 2015 16:22:29 +1000
Subject: linux-next: manual merge of the rtc tree with the arm-soc tree
Message-ID: <20150827162229.10fe7255@canb.auug.org.au>

Hi Alexandre,

Today's linux-next merge of the rtc tree got a conflict in:

  arch/arm/boot/dts/am437x-gp-evm.dts

between commits:

  d3d92af19e99 ("ARM: dts: am437x-gp-evm: McASP1 node for audio support")
  cf9a4850e995 ("ARM: dts: am437x-gp-evm: Enable analog audio via simple-card")

from the arm-soc tree and commit:

  f7331bad0fa4 ("ARM: dts: AM437x: Add the internal and external clock nodes for rtc")

from the rtc tree.

I fixed it up (see below) and can carry the fix as necessary (no action
is required).

-- 
Cheers,
Stephen Rothwell                    sfr at canb.auug.org.au

diff --cc arch/arm/boot/dts/am437x-gp-evm.dts
index 215775dc6948,1d5733751fd4..000000000000
--- a/arch/arm/boot/dts/am437x-gp-evm.dts
+++ b/arch/arm/boot/dts/am437x-gp-evm.dts
@@@ -112,32 -124,12 +112,39 @@@
  		clock-frequency = <12000000>;
  	};
  
 +	sound0: sound at 0 {
 +		compatible = "simple-audio-card";
 +		simple-audio-card,name = "AM437x-GP-EVM";
 +		simple-audio-card,widgets =
 +			"Headphone", "Headphone Jack",
 +			"Line", "Line In";
 +		simple-audio-card,routing =
 +			"Headphone Jack",	"HPLOUT",
 +			"Headphone Jack",	"HPROUT",
 +			"LINE1L",		"Line In",
 +			"LINE1R",		"Line In";
 +		simple-audio-card,format = "dsp_b";
 +		simple-audio-card,bitclock-master = <&sound0_master>;
 +		simple-audio-card,frame-master = <&sound0_master>;
 +		simple-audio-card,bitclock-inversion;
 +
 +		simple-audio-card,cpu {
 +			sound-dai = <&mcasp1>;
 +			system-clock-frequency = <12000000>;
 +		};
 +
 +		sound0_master: simple-audio-card,codec {
 +			sound-dai = <&tlv320aic3106>;
 +			system-clock-frequency = <12000000>;
 +		};
 +	};
++
+ 	/* fixed 32k external oscillator clock */
+ 	clk_32k_rtc: clk_32k_rtc {
+ 		#clock-cells = <0>;
+ 		compatible = "fixed-clock";
+ 		clock-frequency = <32768>;
+ 	};
  };
  
  &am43xx_pinmux {
@@@ -924,20 -797,8 +931,26 @@@
  	};
  };
  
 +&mcasp1 {
 +	#sound-dai-cells = <0>;
 +	pinctrl-names = "default", "sleep";
 +	pinctrl-0 = <&mcasp1_pins>;
 +	pinctrl-1 = <&mcasp1_sleep_pins>;
 +
 +	status = "okay";
 +
 +	op-mode = <0>; /* MCASP_IIS_MODE */
 +	tdm-slots = <2>;
 +	/* 4 serializers */
 +	serial-dir = <  /* 0: INACTIVE, 1: TX, 2: RX */
 +		0 0 1 2
 +	>;
 +	tx-num-evt = <32>;
 +	rx-num-evt = <32>;
 +};
++
+ &rtc {
+ 	clocks = <&clk_32k_rtc>, <&clk_32768_ck>;
+ 	clock-names = "ext-clk", "int-clk";
+ 	status = "okay";
+ };


From jteki at openedev.com  Wed Aug 26 23:23:16 2015
From: jteki at openedev.com (Jagan Teki)
Date: Thu, 27 Aug 2015 11:53:16 +0530
Subject: [LINUX RFC v2 0/4] spi: add dual parallel mode support in Zynq
 MPSoC GQSPI controller
In-Reply-To: <CAGnW=BZtsVtT+Z7gTq5jybXsHWp+RNpjc6ckk6-MXWxAS7u8Mw@mail.gmail.com>
References: <1440570367-22569-1-git-send-email-ranjit.waghmode@xilinx.com>
 <CAD6G_RQhWBsUTZNBB44W98Fjzw82H_D_E9nY0aDWezj729mkoA@mail.gmail.com>
 <CAGnW=BZtsVtT+Z7gTq5jybXsHWp+RNpjc6ckk6-MXWxAS7u8Mw@mail.gmail.com>
Message-ID: <CAD6G_RTCQ5Fzjgxz+-3oMDAyUTg6UFAqvpEPQzJ9maSTZ3Nc_g@mail.gmail.com>

On 26 August 2015 at 21:02, punnaiah choudary kalluri
<punnaia at xilinx.com> wrote:
> On Wed, Aug 26, 2015 at 5:49 PM, Jagan Teki <jteki at openedev.com> wrote:
>> On 26 August 2015 at 11:56, Ranjit Waghmode <ranjit.waghmode at xilinx.com> wrote:
>>> This series adds dual parallel mode support for Zynq Ultrascale+
>>> MPSoC GQSPI controller driver.
>>>
>>> What is dual parallel mode?
>>> ---------------------------
>>> ZynqMP GQSPI controller supports Dual Parallel mode with following functionalities:
>>> 1) Supporting two SPI flash memories operating in parallel. 8 I/O lines.
>>> 2) Chip selects and clock are shared to both the flash devices
>>> 3) This mode is targeted for faster read/write speed and also doubles the size
>>> 4) Commands/data can be transmitted/received from both the devices(mirror),
>>>    or only upper or only lower flash memory devices.
>>> 5) Data arrangement:
>>>    With stripe enabled,
>>>    Even bytes i.e. 0, 2, 4,... are transmitted on Lower Data Bus
>>>    Odd bytes i.e. 1, 3, 5,.. are transmitted on Upper Data Bus.
>>>
>>> This series also updated MTD layer files for adding parallel mode support.
>>>
>>> 1) Added Support for two flashes
>>> 2) Support to enable/disable data stripe as and when required.
>>> 3) Added required parameters to spi_nor structure. Initialized all
>>>    added parameters in spi_nor_scan()
>>> 4) Added support for dual parallel in spi_nor_read/write/erase functions by:
>>>    a) Increasing page_size, sector_size, erase_size and toatal flash size
>>>       as and when required.
>>>    b) Dividing address by 2
>>>    c) Updating spi->master->flags for qspi driver to change CS
>>> 5) Updated read_sr() to get status of both flashes
>>> 6) Also updated read_fsr() to get status of both flashes
>>>
>>> These all are very high level changes and expected to make an idea clear.
>>> Comments and suggestions are always welcomed
>>>
>>> ---
>>> V2 Changes:
>>> a) Splitted patches based on logical changes
>>> b) Added error handling for newly added APIs in SPI core
>>> ---
>>>
>>> Ranjit Waghmode (4):
>>>   spi: add support of two chip selects & data stripe
>>>   mtd: add spi_device instance to spi_nor struct
>>>   spi-nor: add dual parallel mode support
>>>   spi: zynqmp: gqspi: add support for dual parallel mode configuration
>>
>> I don't find any previous discussion about way to inform flash
>> dual-ness into spi-nor
>> from spi drivers.
>>
>> Here is my idea, probably others may think same.
>> Informing dual_flash from drivers/spi through flags or any other mode
>> bits is not a better approach as dual flash feature is specific to
>> spi-nor flash controller (controller specially designed for spi-nor
>> flash not the generic spi controller).  So if the driver sits on
>> drivers/mtd/spi-nor/ (ex: fsl-quadspi.c), may be we can inform flash
>> specific things to spi-nor as it's not touching generic spi stack in
>> Linux. But there is a defined-drawback if the driver is moved to
>> drivers/mtd/spi-nor ie it can't use spi core API's at-all.
>
> Xilinx GQSPI is a generic quad spi controller. The primary goal is to support
> Generic/Future command sequences and Future NOR/NAND flash devices.
> This core can also be used for legacy SPI devices. Due to the generic nature
> of the core, software can generate any command sequence. It also has additional
> features like parallel and stacked configurations to double the data
> rate and size.
> Accessing spi-nor flash device is one particular use case and like
> that there will be
> many. So, we decided to keep this driver in generic spi framework and
> that is the ideal
> thing to do for the GQSPI controller.

Yes, I understand the generic nature of the GQSPI and it's good to
have all-in-one like generic spi, spi-nor and spi-nand and more
together, but Linux stacks were implemented in such a way to support
the each type of controller with connected slaves separably for better
handling.

Currently GQSPI driver is added in drivers/spi as it supports generic
spi nature and now it enhanced more through flags for supporting
spi-nor, what if we add spi-nand support for the same controller? do
we add one more driver in spi-nand framework (drivers/mtd/spi-nand -
an on going implementation)? My only observation here is even if the
controller is more generic to support more number of device classes,
and adding same driver and populate the slave stuff through flags or
different kind of mechanism to different driver stack, this is not a
better approach I thought.

Based on the above comments, there is an approach to handle this
support and I'm not 100% sure whether this fits or not but we
implemented the same -  this is "probing child devices from parent"
(there was a discussion with Arnd earlier wrt this, but I'm unable to
get the mailing thread)

Added Arnd (probably will give more inputs or corrections)

Let me explain how we implemented on our design.
We have PCIe controller that support basic root complex handling, dma
and controller hotplug (not in-build pcie hp) and ideally we need to
write driver for handling root complex on drivers/pci/host and one
hotplug driver in drivers/pci and one more driver in drivers/dma for
handling pcie dma stuff. And some pcie calls need to navigate from
root complex driver to dma and hotplug driver that means there is call
transition from driver/pci to driver/dma which is absolutely not a
good approach (spi to spi-nor and spi-nand transition - in GQSPI case)

So the implementation we follow is like there is a pcie root complex
driver(probably generic spi driver in drivers/spi/*) and inside probe
we have register platform_device for hotplug (spi-nor) and dma
(spi-nand) and the dma driver in drivers/dma and hotplug driver in
driver/pci/ are platform drivers which is of legacy binding (not with
dts) so there should be a common dts for root complex driver
(drivers/spi/*) and individual child driver need to take those while
registering platform_device.

example pseudo:

drivers/dma/dma-child2.c

Legacy platform_driver binding and handling dma future as normal dma
driver, spi-nand in your case

drivers/pci/hotplug/hp-child1.c

Legacy platform_driver binding and handling hotplug future as normal
hotplug driver, spi-nor in your case.

drivers/pci/host/rc-parent-pci.c

static int rc_parent_pcie_probe_bridge(struct platform_device *pdev)
{
   // Generic rc handling (genric spi stuff)

   // Hotplug handling (spi-nor)
   - platform_device_alloc
   - assign need resources
   - register pdev using platform_device_add

    // DMA handling (spi-nand)
   - same as above
}

static const struct of_device_id rc_parent_pcie_match_table[] = {
        {.compatible = "abc,rc-parent",},
        {},
};

static struct platform_driver rc_parent_pcie_driver = {
        .driver = {
                   .name = "rc-parent",
                   .of_match_table = of_match_ptr(rc_parent_pcie_match_table),
        },
        .probe = rc_parent_pcie_probe_bridge,
};
module_platform_driver(rc_parent_pcie_driver);

I couldn't find any driver mainlined wrt this design, think more on
GQSPI front, whether this design fits well or not.

thanks!
-- 
Jagan | openedev.


From Hannes.Schmelzer at br-automation.com  Wed Aug 26 23:25:57 2015
From: Hannes.Schmelzer at br-automation.com (Hannes Schmelzer)
Date: Thu, 27 Aug 2015 08:25:57 +0200
Subject: [PATCH 2/2] memory: omap-gpmc: Add Kconfig option for debug
In-Reply-To: <1432156863-19695-3-git-send-email-tony@atomide.com>
References: <1432156863-19695-1-git-send-email-tony@atomide.com>
 <1432156863-19695-3-git-send-email-tony@atomide.com>
Message-ID: <OFD8721230.94222018-ONC1257EAE.00234FC6-C1257EAE.0023561C@br-automation.com>

Hi Tony,

Did anyone test this changeset on some AM335x board?

Today I ran into trouble with that because:

The GPMC controller gets reseted on kernel boot due to the missing/removed 
HWMOD_INIT_NO_RESET flag.

Primary this should not be a big problem, but on my board (maybe on all 
AM335x) the GPMC doesn't behave as described in TRM.
Especially the GPMC_CONFIG register is not reset to 0h after reset, 
instead it holds the value 0xa00 which is very strange because bit 10-31 
are reserved.

Further this 0xa00 means that Bit9 (WAIT1PINPOLARITY) is set, exactly this 
causes my system to stall on first access the connected NAND flash because 
it never becomes ready due to the wrong wait pin polarity. Maybe others 
dont't run into trouble because they may use WAIT0PIN, which one has it's 
old polarity.

First approach was simply to write 0x0 to the GPMC_CONFIG register during 
gpmc_probe function.
It solves the problem.

I also tried to issue some SYSRESET through GPMC registers without 
success, same strange behavior.

What?s your thinking around that?

Best regards,
Hannes

linux-omap-owner at vger.kernel.org schrieb am 20.05.2015 23:21:03:

> Von: Tony Lindgren <tony at atomide.com>
> An: linux-omap at vger.kernel.org
> Kopie: linux-arm-kernel at lists.infradead.org, Brian Hutchinson 
> <b.hutchman at gmail.com>, Paul Walmsley <paul at pwsan.com>, Roger Quadros 
<rogerq at ti.com>
> Datum: 20.05.2015 23:37
> Betreff: [PATCH 2/2] memory: omap-gpmc: Add Kconfig option for debug
> Gesendet von: linux-omap-owner at vger.kernel.org
> 
> We support decoding the bootloader values if DEBUG is defined.
> But we also need to change the struct omap_hwmod flags to have
> HWMOD_INIT_NO_RESET to avoid the GPMC being reset during the
> boot. Otherwise just the default timings will be displayed
> instead of the bootloader configured timings.
> 
> This also allows us to clean up the various GPMC related
> hwmod flags. For debugging, we only need HWMOD_INIT_NO_RESET,
> and HWMOD_INIT_NO_IDLE is not needed.
> 
> Cc: Brian Hutchinson <b.hutchman at gmail.com>
> Cc: Paul Walmsley <paul at pwsan.com>
> Cc: Roger Quadros <rogerq at ti.com>
> Signed-off-by: Tony Lindgren <tony at atomide.com>
> ---
>  arch/arm/mach-omap2/omap_hwmod.h                        |  6 ++++++
>  arch/arm/mach-omap2/omap_hwmod_2xxx_ipblock_data.c      | 12 
++----------
>  arch/arm/mach-omap2/omap_hwmod_33xx_43xx_ipblock_data.c |  3 ++-
>  arch/arm/mach-omap2/omap_hwmod_3xxx_data.c              | 12 
++----------
>  arch/arm/mach-omap2/omap_hwmod_44xx_data.c              | 11 
++---------
>  arch/arm/mach-omap2/omap_hwmod_7xx_data.c               |  4 ++--
>  arch/arm/mach-omap2/omap_hwmod_81xx_data.c              |  2 ++
>  drivers/memory/Kconfig                                  |  8 ++++++++
>  drivers/memory/omap-gpmc.c                              |  6 +++---
>  9 files changed, 29 insertions(+), 35 deletions(-)
> 
> diff --git a/arch/arm/mach-omap2/omap_hwmod.h 
b/arch/arm/mach-omap2/omap_hwmod.h
> index 9611c91..b5d27ec 100644
> --- a/arch/arm/mach-omap2/omap_hwmod.h
> +++ b/arch/arm/mach-omap2/omap_hwmod.h
> @@ -109,6 +109,12 @@ extern struct omap_hwmod_sysc_fields 
omap_hwmod_sysc_type3;
> 
>  #define DEBUG_OMAPUART_FLAGS   (HWMOD_INIT_NO_IDLE | 
HWMOD_INIT_NO_RESET)
> 
> +#ifdef CONFIG_OMAP_GPMC_DEBUG
> +#define DEBUG_OMAP_GPMC_HWMOD_FLAGS   HWMOD_INIT_NO_RESET
> +#else
> +#define DEBUG_OMAP_GPMC_HWMOD_FLAGS   0
> +#endif
> +
>  #if defined(CONFIG_DEBUG_OMAP2UART1)
>  #undef DEBUG_OMAP2UART1_FLAGS
>  #define DEBUG_OMAP2UART1_FLAGS DEBUG_OMAPUART_FLAGS
> diff --git a/arch/arm/mach-omap2/omap_hwmod_2xxx_ipblock_data.c 
b/arch/arm/
> mach-omap2/omap_hwmod_2xxx_ipblock_data.c
> index 8821b9d..6dcfd03 100644
> --- a/arch/arm/mach-omap2/omap_hwmod_2xxx_ipblock_data.c
> +++ b/arch/arm/mach-omap2/omap_hwmod_2xxx_ipblock_data.c
> @@ -762,16 +762,8 @@ struct omap_hwmod omap2xxx_gpmc_hwmod = {
>     .name      = "gpmc",
>     .class      = &omap2xxx_gpmc_hwmod_class,
>     .main_clk   = "gpmc_fck",
> -   /*
> -    * XXX HWMOD_INIT_NO_RESET should not be needed for this IP
> -    * block.  It is not being added due to any known bugs with
> -    * resetting the GPMC IP block, but rather because any timings
> -    * set by the bootloader are not being correctly programmed by
> -    * the kernel from the board file or DT data.
> -    * HWMOD_INIT_NO_RESET should be removed ASAP.
> -    */
> -   .flags      = (HWMOD_INIT_NO_IDLE | HWMOD_INIT_NO_RESET |
> -            HWMOD_NO_IDLEST),
> +   /* Skip reset for CONFIG_OMAP_GPMC_DEBUG for bootloader timings */
> +   .flags      = HWMOD_NO_IDLEST | DEBUG_OMAP_GPMC_HWMOD_FLAGS,
>     .prcm      = {
>        .omap2   = {
>           .prcm_reg_id = 3,
> diff --git a/arch/arm/mach-omap2/omap_hwmod_33xx_43xx_ipblock_data.c 
b/arch/
> arm/mach-omap2/omap_hwmod_33xx_43xx_ipblock_data.c
> index cabc569..ae0cb67 100644
> --- a/arch/arm/mach-omap2/omap_hwmod_33xx_43xx_ipblock_data.c
> +++ b/arch/arm/mach-omap2/omap_hwmod_33xx_43xx_ipblock_data.c
> @@ -668,7 +668,8 @@ struct omap_hwmod am33xx_gpmc_hwmod = {
>     .name      = "gpmc",
>     .class      = &am33xx_gpmc_hwmod_class,
>     .clkdm_name   = "l3s_clkdm",
> -   .flags      = (HWMOD_INIT_NO_IDLE | HWMOD_INIT_NO_RESET),
> +   /* Skip reset for CONFIG_OMAP_GPMC_DEBUG for bootloader timings */
> +   .flags      = DEBUG_OMAP_GPMC_HWMOD_FLAGS,
>     .main_clk   = "l3s_gclk",
>     .prcm      = {
>        .omap4   = {
> diff --git a/arch/arm/mach-omap2/omap_hwmod_3xxx_data.c 
b/arch/arm/mach-omap2/
> omap_hwmod_3xxx_data.c
> index 4e8e93c..0ca4d3f 100644
> --- a/arch/arm/mach-omap2/omap_hwmod_3xxx_data.c
> +++ b/arch/arm/mach-omap2/omap_hwmod_3xxx_data.c
> @@ -2169,16 +2169,8 @@ static struct omap_hwmod omap3xxx_gpmc_hwmod = {
>     .clkdm_name   = "core_l3_clkdm",
>     .mpu_irqs   = omap3xxx_gpmc_irqs,
>     .main_clk   = "gpmc_fck",
> -   /*
> -    * XXX HWMOD_INIT_NO_RESET should not be needed for this IP
> -    * block.  It is not being added due to any known bugs with
> -    * resetting the GPMC IP block, but rather because any timings
> -    * set by the bootloader are not being correctly programmed by
> -    * the kernel from the board file or DT data.
> -    * HWMOD_INIT_NO_RESET should be removed ASAP.
> -    */
> -   .flags      = (HWMOD_INIT_NO_IDLE | HWMOD_INIT_NO_RESET |
> -            HWMOD_NO_IDLEST),
> +   /* Skip reset for CONFIG_OMAP_GPMC_DEBUG for bootloader timings */
> +   .flags      = HWMOD_NO_IDLEST | DEBUG_OMAP_GPMC_HWMOD_FLAGS,
>  };
> 
>  /*
> diff --git a/arch/arm/mach-omap2/omap_hwmod_44xx_data.c 
b/arch/arm/mach-omap2/
> omap_hwmod_44xx_data.c
> index f5e68a7..43eebf2 100644
> --- a/arch/arm/mach-omap2/omap_hwmod_44xx_data.c
> +++ b/arch/arm/mach-omap2/omap_hwmod_44xx_data.c
> @@ -1188,15 +1188,8 @@ static struct omap_hwmod omap44xx_gpmc_hwmod = {
>     .name      = "gpmc",
>     .class      = &omap44xx_gpmc_hwmod_class,
>     .clkdm_name   = "l3_2_clkdm",
> -   /*
> -    * XXX HWMOD_INIT_NO_RESET should not be needed for this IP
> -    * block.  It is not being added due to any known bugs with
> -    * resetting the GPMC IP block, but rather because any timings
> -    * set by the bootloader are not being correctly programmed by
> -    * the kernel from the board file or DT data.
> -    * HWMOD_INIT_NO_RESET should be removed ASAP.
> -    */
> -   .flags      = HWMOD_INIT_NO_IDLE | HWMOD_INIT_NO_RESET,
> +   /* Skip reset for CONFIG_OMAP_GPMC_DEBUG for bootloader timings */
> +   .flags      = DEBUG_OMAP_GPMC_HWMOD_FLAGS,
>     .prcm = {
>        .omap4 = {
>           .clkctrl_offs = OMAP4_CM_L3_2_GPMC_CLKCTRL_OFFSET,
> diff --git a/arch/arm/mach-omap2/omap_hwmod_7xx_data.c 
b/arch/arm/mach-omap2/
> omap_hwmod_7xx_data.c
> index 0e64c2f..a0411f3 100644
> --- a/arch/arm/mach-omap2/omap_hwmod_7xx_data.c
> +++ b/arch/arm/mach-omap2/omap_hwmod_7xx_data.c
> @@ -819,8 +819,8 @@ static struct omap_hwmod dra7xx_gpmc_hwmod = {
>     .name      = "gpmc",
>     .class      = &dra7xx_gpmc_hwmod_class,
>     .clkdm_name   = "l3main1_clkdm",
> -   .flags      = (HWMOD_INIT_NO_IDLE | HWMOD_INIT_NO_RESET |
> -            HWMOD_SWSUP_SIDLE),
> +   /* Skip reset for CONFIG_OMAP_GPMC_DEBUG for bootloader timings */
> +   .flags      = HWMOD_SWSUP_SIDLE | DEBUG_OMAP_GPMC_HWMOD_FLAGS,
>     .main_clk   = "l3_iclk_div",
>     .prcm = {
>        .omap4 = {
> diff --git a/arch/arm/mach-omap2/omap_hwmod_81xx_data.c 
b/arch/arm/mach-omap2/
> omap_hwmod_81xx_data.c
> index cab1eb6..c924137 100644
> --- a/arch/arm/mach-omap2/omap_hwmod_81xx_data.c
> +++ b/arch/arm/mach-omap2/omap_hwmod_81xx_data.c
> @@ -478,6 +478,8 @@ static struct omap_hwmod dm81xx_gpmc_hwmod = {
>     .clkdm_name   = "alwon_l3s_clkdm",
>     .class      = &dm81xx_gpmc_hwmod_class,
>     .main_clk   = "sysclk6_ck",
> +   /* Skip reset for CONFIG_OMAP_GPMC_DEBUG for bootloader timings */
> +   .flags      = DEBUG_OMAP_GPMC_HWMOD_FLAGS,
>     .prcm = {
>        .omap4 = {
>           .clkctrl_offs = DM816X_CM_ALWON_GPMC_CLKCTRL,
> diff --git a/drivers/memory/Kconfig b/drivers/memory/Kconfig
> index 868036f..8406c668 100644
> --- a/drivers/memory/Kconfig
> +++ b/drivers/memory/Kconfig
> @@ -49,6 +49,14 @@ config OMAP_GPMC
>       interfacing to a variety of asynchronous as well as synchronous
>       memory drives like NOR, NAND, OneNAND, SRAM.
> 
> +config OMAP_GPMC_DEBUG
> +   bool
> +   depends on OMAP_GPMC
> +   help
> +     Enables verbose debugging mostly to decode the bootloader provided
> +     timings. Enable this during development to configure devices
> +     connected to the GPMC bus.
> +
>  config MVEBU_DEVBUS
>     bool "Marvell EBU Device Bus Controller"
>     default y
> diff --git a/drivers/memory/omap-gpmc.c b/drivers/memory/omap-gpmc.c
> index 0e524a1..3a27a84 100644
> --- a/drivers/memory/omap-gpmc.c
> +++ b/drivers/memory/omap-gpmc.c
> @@ -403,7 +403,7 @@ static void gpmc_cs_bool_timings(int cs, const 
struct 
> gpmc_bool_timings *p)
>              p->cycle2cyclediffcsen);
>  }
> 
> -#ifdef DEBUG
> +#ifdef CONFIG_OMAP_GPMC_DEBUG
>  /**
>   * get_gpmc_timing_reg - read a timing parameter and print DTS settings 
for it.
>   * @cs:      Chip Select Region
> @@ -612,7 +612,7 @@ static int set_gpmc_timing_reg(int cs, int reg, int 
> st_bit, int end_bit, int max
>     }
> 
>     l = gpmc_cs_read_reg(cs, reg);
> -#ifdef DEBUG
> +#ifdef CONFIG_OMAP_GPMC_DEBUG
>     pr_info(
>        "GPMC CS%d: %-17s: %3d ticks, %3lu ns (was %3i ticks) %3d ns\n",
>            cs, name, ticks, gpmc_get_clk_period(cs, cd) * ticks / 1000,
> @@ -767,7 +767,7 @@ int gpmc_cs_set_timings(int cs, const struct 
gpmc_timings *t,
>               GPMC_CONFIG1_CLKACTIVATIONTIME_MAX,
>               clk_activation, GPMC_CD_FCLK);
> 
> -#ifdef DEBUG
> +#ifdef CONFIG_OMAP_GPMC_DEBUG
>     pr_info("GPMC CS%d CLK period is %lu ns (div %d)\n",
>           cs, (div * gpmc_get_fclk_period()) / 1000, div);
>  #endif
> -- 
> 2.1.4
> 
> --
> To unsubscribe from this list: send the line "unsubscribe linux-omap" in
> the body of a message to majordomo at vger.kernel.org
> More majordomo info at  http://vger.kernel.org/majordomo-info.html




From mpa at pengutronix.de  Wed Aug 26 23:44:31 2015
From: mpa at pengutronix.de (Markus Pargmann)
Date: Thu, 27 Aug 2015 08:44:31 +0200
Subject: [PATCH v3 3/4] regmap: Add raw_write/read checks for
 max_raw_write/read sizes
In-Reply-To: <1440657872-24554-1-git-send-email-mpa@pengutronix.de>
References: <1440657872-24554-1-git-send-email-mpa@pengutronix.de>
Message-ID: <1440657872-24554-4-git-send-email-mpa@pengutronix.de>

Check in regmap_raw_read() and regmap_raw_write() for correct maximum
sizes of the operations. Return -E2BIG if this size is not supported
because it is too big.

Also this patch causes an uninitialized variable warning so it
initializes ret (although not necessary).

Signed-off-by: Markus Pargmann <mpa at pengutronix.de>
---
 drivers/base/regmap/regmap.c | 6 ++++++
 1 file changed, 6 insertions(+)

diff --git a/drivers/base/regmap/regmap.c b/drivers/base/regmap/regmap.c
index b4d12fe15f21..157fe79a7d06 100644
--- a/drivers/base/regmap/regmap.c
+++ b/drivers/base/regmap/regmap.c
@@ -1581,6 +1581,8 @@ int regmap_raw_write(struct regmap *map, unsigned int reg,
 		return -EINVAL;
 	if (val_len % map->format.val_bytes)
 		return -EINVAL;
+	if (map->max_raw_write && map->max_raw_write > val_len)
+		return -E2BIG;
 
 	map->lock(map->lock_arg);
 
@@ -2253,6 +2255,10 @@ int regmap_raw_read(struct regmap *map, unsigned int reg, void *val,
 			ret = -ENOTSUPP;
 			goto out;
 		}
+		if (map->max_raw_read && map->max_raw_read < val_len) {
+			ret = -E2BIG;
+			goto out;
+		}
 
 		/* Physical block read if there's no cache involved */
 		ret = _regmap_raw_read(map, reg, val, val_len);
-- 
2.5.0



From mpa at pengutronix.de  Wed Aug 26 23:44:28 2015
From: mpa at pengutronix.de (Markus Pargmann)
Date: Thu, 27 Aug 2015 08:44:28 +0200
Subject: [PATCH v3 0/4] regmap: i2c block support
Message-ID: <1440657872-24554-1-git-send-email-mpa@pengutronix.de>

Hi,

This series adds support for i2c block read/writes. To support the maximum 32
byte read/write operations, the regmap core is extended by max_raw_read and
max_raw_write. bulk operations are splitted depending of the size of
max_raw_read/write.

The last patch needs testing before it can be applied.

Best Regards,

Markus


Changes in v3:
- Rebased onto latest version of "regmap: fixes" series

Changes in v2:
- max_raw_io splitted into max_raw_read/write
- Use E2BIG as error value in the block read/write functions

Markus Pargmann (4):
  regmap: Introduce max_raw_read/write for regmap_bulk_read/write
  regmap: regmap max_raw_read/write getter functions
  regmap: Add raw_write/read checks for max_raw_write/read sizes
  regmap-i2c: Add smbus i2c block support

 drivers/base/regmap/internal.h   |   4 ++
 drivers/base/regmap/regmap-i2c.c |  49 +++++++++++++++++
 drivers/base/regmap/regmap.c     | 113 +++++++++++++++++++++++++++++++++------
 include/linux/regmap.h           |   6 +++
 4 files changed, 157 insertions(+), 15 deletions(-)

-- 
2.5.0



From lee.jones at linaro.org  Wed Aug 26 23:44:52 2015
From: lee.jones at linaro.org (Lee Jones)
Date: Thu, 27 Aug 2015 07:44:52 +0100
Subject: [PATCH 4/4] remoteproc: debugfs: Add ability to boot remote
 processor using debugfs
In-Reply-To: <55DDF2A0.5010404@mentor.com>
References: <1440594483-29601-1-git-send-email-lee.jones@linaro.org>
 <1440594483-29601-5-git-send-email-lee.jones@linaro.org>
 <55DDF2A0.5010404@mentor.com>
Message-ID: <20150827064452.GC19409@x1>

On Wed, 26 Aug 2015, Nathan Lynch wrote:

> On 08/26/2015 08:08 AM, Lee Jones wrote:
> > Signed-off-by: Lee Jones <lee.jones at linaro.org>
> > ---
> >  drivers/remoteproc/remoteproc_debugfs.c | 25 +++++++++++++++++++++++++
> >  1 file changed, 25 insertions(+)
> 
> The commit message should describe why this is needed...
> 
> > diff --git a/drivers/remoteproc/remoteproc_debugfs.c b/drivers/remoteproc/remoteproc_debugfs.c
> > index 9d30809..9620962 100644
> > --- a/drivers/remoteproc/remoteproc_debugfs.c
> > +++ b/drivers/remoteproc/remoteproc_debugfs.c
> > @@ -88,8 +88,33 @@ static ssize_t rproc_state_read(struct file *filp, char __user *userbuf,
> >  	return simple_read_from_buffer(userbuf, count, ppos, buf, i);
> >  }
> >  
> > +static ssize_t rproc_state_write(struct file *filp, const char __user *userbuf,
> > +				 size_t count, loff_t *ppos)
> > +{
> > +	struct rproc *rproc = filp->private_data;
> > +	char buf[2];
> > +	int ret;
> > +
> > +	ret = copy_from_user(buf, userbuf, 1);
> > +	if (ret)
> > +		return -EFAULT;
> > +
> > +	switch (buf[0]) {
> > +	case '1':
> > +		ret = rproc_boot(rproc);
> > +		if (ret)
> > +			dev_warn(&rproc->dev, "Boot failed: %d\n", ret);
> > +		break;
> > +	default:
> > +		rproc_shutdown(rproc);
> > +	}
> > +
> > +	return count;
> > +}
> 
> ... and I suggest that the user interface be reconsidered.  If '1' means
> "boot" and literally anything else means "shut down" then you can't add
> operations in the future without potentially breaking things.

Good points, will fix.

-- 
Lee Jones
Linaro STMicroelectronics Landing Team Lead
Linaro.org ? Open source software for ARM SoCs
Follow Linaro: Facebook | Twitter | Blog


From mpa at pengutronix.de  Wed Aug 26 23:44:32 2015
From: mpa at pengutronix.de (Markus Pargmann)
Date: Thu, 27 Aug 2015 08:44:32 +0200
Subject: [PATCH v3 4/4] regmap-i2c: Add smbus i2c block support
In-Reply-To: <1440657872-24554-1-git-send-email-mpa@pengutronix.de>
References: <1440657872-24554-1-git-send-email-mpa@pengutronix.de>
Message-ID: <1440657872-24554-5-git-send-email-mpa@pengutronix.de>

This allows to read/write up to 32 bytes of data and is to be prefered
if supported before the register read/write smbus support.

Signed-off-by: Markus Pargmann <mpa at pengutronix.de>
---
 drivers/base/regmap/regmap-i2c.c | 49 ++++++++++++++++++++++++++++++++++++++++
 1 file changed, 49 insertions(+)

diff --git a/drivers/base/regmap/regmap-i2c.c b/drivers/base/regmap/regmap-i2c.c
index 4b76e33110a2..ddb9b0efb724 100644
--- a/drivers/base/regmap/regmap-i2c.c
+++ b/drivers/base/regmap/regmap-i2c.c
@@ -209,11 +209,60 @@ static struct regmap_bus regmap_i2c = {
 	.val_format_endian_default = REGMAP_ENDIAN_BIG,
 };
 
+static int regmap_i2c_smbus_i2c_write(void *context, const void *data,
+				      size_t count)
+{
+	struct device *dev = context;
+	struct i2c_client *i2c = to_i2c_client(dev);
+
+	if (count < 1)
+		return -EINVAL;
+	if (count >= I2C_SMBUS_BLOCK_MAX)
+		return -E2BIG;
+
+	--count;
+	return i2c_smbus_write_i2c_block_data(i2c, ((u8 *)data)[0], count,
+					      ((u8 *)data + 1));
+}
+
+static int regmap_i2c_smbus_i2c_read(void *context, const void *reg,
+				     size_t reg_size, void *val,
+				     size_t val_size)
+{
+	struct device *dev = context;
+	struct i2c_client *i2c = to_i2c_client(dev);
+	int ret;
+
+	if (reg_size != 1 || val_size < 1)
+		return -EINVAL;
+	if (val_size >= I2C_SMBUS_BLOCK_MAX)
+		return -E2BIG;
+
+	ret = i2c_smbus_read_i2c_block_data(i2c, ((u8 *)reg)[0], val_size, val);
+	if (ret == val_size)
+		return 0;
+	else if (ret < 0)
+		return ret;
+	else
+		return -EIO;
+}
+
+static struct regmap_bus regmap_i2c_smbus_i2c_block = {
+	.write = regmap_i2c_smbus_i2c_write,
+	.read = regmap_i2c_smbus_i2c_read,
+	.max_raw_read = I2C_SMBUS_BLOCK_MAX,
+	.max_raw_write = I2C_SMBUS_BLOCK_MAX,
+};
+
 static const struct regmap_bus *regmap_get_i2c_bus(struct i2c_client *i2c,
 					const struct regmap_config *config)
 {
 	if (i2c_check_functionality(i2c->adapter, I2C_FUNC_I2C))
 		return &regmap_i2c;
+	else if (config->reg_bits == 8 &&
+		 i2c_check_functionality(i2c->adapter,
+					 I2C_FUNC_SMBUS_I2C_BLOCK))
+		return &regmap_i2c_smbus_i2c_block;
 	else if (config->val_bits == 16 && config->reg_bits == 8 &&
 		 i2c_check_functionality(i2c->adapter,
 					 I2C_FUNC_SMBUS_WORD_DATA))
-- 
2.5.0



From mpa at pengutronix.de  Wed Aug 26 23:44:29 2015
From: mpa at pengutronix.de (Markus Pargmann)
Date: Thu, 27 Aug 2015 08:44:29 +0200
Subject: [PATCH v3 1/4] regmap: Introduce max_raw_read/write for
 regmap_bulk_read/write
In-Reply-To: <1440657872-24554-1-git-send-email-mpa@pengutronix.de>
References: <1440657872-24554-1-git-send-email-mpa@pengutronix.de>
Message-ID: <1440657872-24554-2-git-send-email-mpa@pengutronix.de>

There are some buses which have a limit on the maximum number of bytes
that can be send/received. An example for this is
I2C_FUNC_SMBUS_I2C_BLOCK which does not support any reads/writes of more
than 32 bytes. The regmap_bulk operations should still be able to
utilize the full 32 bytes in this case.

Signed-off-by: Markus Pargmann <mpa at pengutronix.de>
---
 drivers/base/regmap/internal.h |  4 ++
 drivers/base/regmap/regmap.c   | 85 ++++++++++++++++++++++++++++++++++--------
 include/linux/regmap.h         |  4 ++
 3 files changed, 78 insertions(+), 15 deletions(-)

diff --git a/drivers/base/regmap/internal.h b/drivers/base/regmap/internal.h
index d744ae3926dd..fc554e357c5d 100644
--- a/drivers/base/regmap/internal.h
+++ b/drivers/base/regmap/internal.h
@@ -146,6 +146,10 @@ struct regmap {
 	/* if set, the device supports multi write mode */
 	bool can_multi_write;
 
+	/* if set, raw reads/writes are limited to this size */
+	size_t max_raw_read;
+	size_t max_raw_write;
+
 	struct rb_root range_tree;
 	void *selector_work_buf;	/* Scratch buffer used for selector */
 };
diff --git a/drivers/base/regmap/regmap.c b/drivers/base/regmap/regmap.c
index 47fe0dfbbc46..c4ebc6bce46c 100644
--- a/drivers/base/regmap/regmap.c
+++ b/drivers/base/regmap/regmap.c
@@ -576,6 +576,8 @@ struct regmap *regmap_init(struct device *dev,
 	map->use_single_read = config->use_single_rw || !bus || !bus->read;
 	map->use_single_write = config->use_single_rw || !bus || !bus->write;
 	map->can_multi_write = config->can_multi_write && bus && bus->write;
+	map->max_raw_read = bus->max_raw_read;
+	map->max_raw_write = bus->max_raw_write;
 	map->dev = dev;
 	map->bus = bus;
 	map->bus_context = bus_context;
@@ -1671,6 +1673,7 @@ int regmap_bulk_write(struct regmap *map, unsigned int reg, const void *val,
 {
 	int ret = 0, i;
 	size_t val_bytes = map->format.val_bytes;
+	size_t total_size = val_bytes * val_count;
 
 	if (map->bus && !map->format.parse_inplace)
 		return -EINVAL;
@@ -1719,16 +1722,37 @@ int regmap_bulk_write(struct regmap *map, unsigned int reg, const void *val,
 		}
 out:
 		map->unlock(map->lock_arg);
-	} else if (map->use_single_write) {
+	} else if (map->use_single_write ||
+		   (map->max_raw_write && map->max_raw_write < total_size)) {
+		int chunk_stride = map->reg_stride;
+		size_t chunk_size = val_bytes;
+		size_t chunk_count = val_count;
+
+		if (!map->use_single_write) {
+			chunk_size = map->max_raw_write;
+			if (chunk_size % val_bytes)
+				chunk_size -= chunk_size % val_bytes;
+			chunk_count = total_size / chunk_size;
+			chunk_stride *= chunk_size / val_bytes;
+		}
+
 		map->lock(map->lock_arg);
-		for (i = 0; i < val_count; i++) {
+		/* Write as many bytes as possible with chunk_size */
+		for (i = 0; i < chunk_count; i++) {
 			ret = _regmap_raw_write(map,
-						reg + (i * map->reg_stride),
-						val + (i * val_bytes),
-						val_bytes);
+						reg + (i * chunk_stride),
+						val + (i * chunk_size),
+						chunk_size);
 			if (ret)
 				break;
 		}
+
+		/* Write remaining bytes */
+		if (!ret && chunk_size * i < total_size) {
+			ret = _regmap_raw_write(map, reg + (i * chunk_stride),
+						val + (i * chunk_size),
+						total_size - i * chunk_size);
+		}
 		map->unlock(map->lock_arg);
 	} else {
 		void *wval;
@@ -2316,20 +2340,51 @@ int regmap_bulk_read(struct regmap *map, unsigned int reg, void *val,
 		 * Some devices does not support bulk read, for
 		 * them we have a series of single read operations.
 		 */
-		if (map->use_single_read) {
-			for (i = 0; i < val_count; i++) {
-				ret = regmap_raw_read(map,
-						reg + (i * map->reg_stride),
-						val + (i * val_bytes),
-						val_bytes);
-				if (ret != 0)
-					return ret;
-			}
-		} else {
+		size_t total_size = val_bytes * val_count;
+
+		if (!map->use_single_read &&
+		    (!map->max_raw_read || map->max_raw_read > total_size)) {
 			ret = regmap_raw_read(map, reg, val,
 					      val_bytes * val_count);
 			if (ret != 0)
 				return ret;
+		} else {
+			/*
+			 * Some devices do not support bulk read or do not
+			 * support large bulk reads, for them we have a series
+			 * of read operations.
+			 */
+			int chunk_stride = map->reg_stride;
+			size_t chunk_size = val_bytes;
+			size_t chunk_count = val_count;
+
+			if (!map->use_single_read) {
+				chunk_size = map->max_raw_read;
+				if (chunk_size % val_bytes)
+					chunk_size -= chunk_size % val_bytes;
+				chunk_count = total_size / chunk_size;
+				chunk_stride *= chunk_size / val_bytes;
+			}
+
+			/* Read bytes that fit into a multiple of chunk_size */
+			for (i = 0; i < chunk_count; i++) {
+				ret = regmap_raw_read(map,
+						      reg + (i * chunk_stride),
+						      val + (i * chunk_size),
+						      chunk_size);
+				if (ret != 0)
+					return ret;
+			}
+
+			/* Read remaining bytes */
+			if (chunk_size * i < total_size) {
+				ret = regmap_raw_read(map,
+						      reg + (i * chunk_stride),
+						      val + (i * chunk_size),
+						      total_size - i * chunk_size);
+				if (ret != 0)
+					return ret;
+			}
 		}
 
 		for (i = 0; i < val_count * val_bytes; i += val_bytes)
diff --git a/include/linux/regmap.h b/include/linux/regmap.h
index 73fc34d0c4c2..327b8f291d3f 100644
--- a/include/linux/regmap.h
+++ b/include/linux/regmap.h
@@ -311,6 +311,8 @@ typedef void (*regmap_hw_free_context)(void *context);
  * @val_format_endian_default: Default endianness for formatted register
  *     values. Used when the regmap_config specifies DEFAULT. If this is
  *     DEFAULT, BIG is assumed.
+ * @max_raw_read: Max raw read size that can be used on the bus.
+ * @max_raw_write: Max raw write size that can be used on the bus.
  */
 struct regmap_bus {
 	bool fast_io;
@@ -325,6 +327,8 @@ struct regmap_bus {
 	u8 read_flag_mask;
 	enum regmap_endian reg_format_endian_default;
 	enum regmap_endian val_format_endian_default;
+	size_t max_raw_read;
+	size_t max_raw_write;
 };
 
 struct regmap *regmap_init(struct device *dev,
-- 
2.5.0



From mpa at pengutronix.de  Wed Aug 26 23:44:30 2015
From: mpa at pengutronix.de (Markus Pargmann)
Date: Thu, 27 Aug 2015 08:44:30 +0200
Subject: [PATCH v3 2/4] regmap: regmap max_raw_read/write getter functions
In-Reply-To: <1440657872-24554-1-git-send-email-mpa@pengutronix.de>
References: <1440657872-24554-1-git-send-email-mpa@pengutronix.de>
Message-ID: <1440657872-24554-3-git-send-email-mpa@pengutronix.de>

Add functions to access the maximum size we can read/write using
regmap_raw_read/write().

This helps drivers that need to know how much they can write with the
raw functions without problems. There are some devices (e.g. bmc150)
that have fifos as registers which need to be read in specific chunks
otherwise samples are dropped.

Signed-off-by: Markus Pargmann <mpa at pengutronix.de>
---
 drivers/base/regmap/regmap.c | 22 ++++++++++++++++++++++
 include/linux/regmap.h       |  2 ++
 2 files changed, 24 insertions(+)

diff --git a/drivers/base/regmap/regmap.c b/drivers/base/regmap/regmap.c
index c4ebc6bce46c..b4d12fe15f21 100644
--- a/drivers/base/regmap/regmap.c
+++ b/drivers/base/regmap/regmap.c
@@ -1390,6 +1390,28 @@ bool regmap_can_raw_write(struct regmap *map)
 }
 EXPORT_SYMBOL_GPL(regmap_can_raw_write);
 
+/**
+ * regmap_get_raw_read_max - Get the maximum size we can read
+ *
+ * @map: Map to check.
+ */
+size_t regmap_get_raw_read_max(struct regmap *map)
+{
+	return map->max_raw_read;
+}
+EXPORT_SYMBOL_GPL(regmap_get_raw_read_max);
+
+/**
+ * regmap_get_raw_write_max - Get the maximum size we can read
+ *
+ * @map: Map to check.
+ */
+size_t regmap_get_raw_write_max(struct regmap *map)
+{
+	return map->max_raw_write;
+}
+EXPORT_SYMBOL_GPL(regmap_get_raw_write_max);
+
 static int _regmap_bus_formatted_write(void *context, unsigned int reg,
 				       unsigned int val)
 {
diff --git a/include/linux/regmap.h b/include/linux/regmap.h
index 327b8f291d3f..6724d0e3819e 100644
--- a/include/linux/regmap.h
+++ b/include/linux/regmap.h
@@ -444,6 +444,8 @@ int regmap_get_max_register(struct regmap *map);
 int regmap_get_reg_stride(struct regmap *map);
 int regmap_async_complete(struct regmap *map);
 bool regmap_can_raw_write(struct regmap *map);
+size_t regmap_get_raw_read_max(struct regmap *map);
+size_t regmap_get_raw_write_max(struct regmap *map);
 
 int regcache_sync(struct regmap *map);
 int regcache_sync_region(struct regmap *map, unsigned int min,
-- 
2.5.0



From lee.jones at linaro.org  Wed Aug 26 23:45:39 2015
From: lee.jones at linaro.org (Lee Jones)
Date: Thu, 27 Aug 2015 07:45:39 +0100
Subject: [PATCH 2/4] remoteproc: Supply controller driver for ST's Remote
 Processors
In-Reply-To: <55DDF252.2010901@mentor.com>
References: <1440594483-29601-1-git-send-email-lee.jones@linaro.org>
 <1440594483-29601-3-git-send-email-lee.jones@linaro.org>
 <55DDF252.2010901@mentor.com>
Message-ID: <20150827064539.GD19409@x1>

On Wed, 26 Aug 2015, Nathan Lynch wrote:

> On 08/26/2015 08:08 AM, Lee Jones wrote:
> > --- /dev/null
> > +++ b/drivers/remoteproc/st_remoteproc.c
> > @@ -0,0 +1,300 @@
> > +/*
> > + * ST's Remote Processor Control Driver
> > + *
> > + * Copyright (C) 2015 STMicroelectronics - All Rights Reserved
> > + *
> > + * Author: Ludovic Barre <ludovic.barre at st.com>
> 
> When submitting code you didn't write, I'd say it's better practice to
> clearly indicate its provenance in the commit message.  E.g. something
> like "Driver based on code authored by Ludovic Barre for ST".  And
> obtain signoffs etc if possible.
> 
> 
> > + *
> > + * 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.
> 
> Please review the wording here.  It's unclear whether this is intended
> to be v2-only or v2 or later.
> 
> 
> > +static int st_rproc_stop(struct rproc *rproc)
> > +{
> > +	struct st_rproc *st_rproc = rproc->priv;
> > +	int err = 0;
> > +
> > +	if (st_rproc->config->sw_reset) {
> > +		err = reset_control_assert(st_rproc->sw_reset);
> > +		if (err)
> > +			dev_warn(&rproc->dev, "Failed to assert S/W Reset\n");
> > +	}
> > +
> > +	if (st_rproc->config->pwr_reset) {
> > +		err = reset_control_assert(st_rproc->pwr_reset);
> > +		if (err)
> > +			dev_warn(&rproc->dev, "Failed to assert Power Reset\n");
> > +	}
> > +
> > +	clk_disable(st_rproc->clk);
> > +
> > +	return 0;
> > +}
> 
> Seems like st_rproc_stop should propagate errors back to its caller
> instead of always returning 0.

Good points, will fix.

-- 
Lee Jones
Linaro STMicroelectronics Landing Team Lead
Linaro.org ? Open source software for ARM SoCs
Follow Linaro: Facebook | Twitter | Blog


From yalin.wang2010 at gmail.com  Thu Aug 27 01:21:00 2015
From: yalin.wang2010 at gmail.com (yalin wang)
Date: Thu, 27 Aug 2015 16:21:00 +0800
Subject: [PATCH] arm64: ioremap: change ioremap prototype and add
 ioremap_cache macro
Message-ID: <1440663660-24244-1-git-send-email-yalin.wang2010@gmail.com>

This patch change ioremap_*() first parameter type to resource_size_t to
be the same as other platforms, and add ioremap_cache macro,
because some code will test if this macro is defined or not, and
will generate a generric version if not defined, for example,
memremap.c do like this.

Signed-off-by: yalin wang <yalin.wang2010 at gmail.com>
---
 arch/arm64/include/asm/io.h | 5 +++--
 arch/arm64/mm/ioremap.c     | 6 +++---
 2 files changed, 6 insertions(+), 5 deletions(-)

diff --git a/arch/arm64/include/asm/io.h b/arch/arm64/include/asm/io.h
index 44be1e0..500e09f 100644
--- a/arch/arm64/include/asm/io.h
+++ b/arch/arm64/include/asm/io.h
@@ -163,15 +163,16 @@ extern void __memset_io(volatile void __iomem *, int, size_t);
 /*
  * I/O memory mapping functions.
  */
-extern void __iomem *__ioremap(phys_addr_t phys_addr, size_t size, pgprot_t prot);
+extern void __iomem *__ioremap(resource_size_t phys_addr, size_t size, pgprot_t prot);
 extern void __iounmap(volatile void __iomem *addr);
-extern void __iomem *ioremap_cache(phys_addr_t phys_addr, size_t size);
+extern void __iomem *ioremap_cache(resource_size_t phys_addr, size_t size);
 
 #define ioremap(addr, size)		__ioremap((addr), (size), __pgprot(PROT_DEVICE_nGnRE))
 #define ioremap_nocache(addr, size)	__ioremap((addr), (size), __pgprot(PROT_DEVICE_nGnRE))
 #define ioremap_wc(addr, size)		__ioremap((addr), (size), __pgprot(PROT_NORMAL_NC))
 #define ioremap_wt(addr, size)		__ioremap((addr), (size), __pgprot(PROT_DEVICE_nGnRE))
 #define iounmap				__iounmap
+#define ioremap_cache			ioremap_cache
 
 /*
  * io{read,write}{16,32}be() macros
diff --git a/arch/arm64/mm/ioremap.c b/arch/arm64/mm/ioremap.c
index 01e88c8..082e963 100644
--- a/arch/arm64/mm/ioremap.c
+++ b/arch/arm64/mm/ioremap.c
@@ -29,7 +29,7 @@
 #include <asm/tlbflush.h>
 #include <asm/pgalloc.h>
 
-static void __iomem *__ioremap_caller(phys_addr_t phys_addr, size_t size,
+static void __iomem *__ioremap_caller(resource_size_t phys_addr, size_t size,
 				      pgprot_t prot, void *caller)
 {
 	unsigned long last_addr;
@@ -73,7 +73,7 @@ static void __iomem *__ioremap_caller(phys_addr_t phys_addr, size_t size,
 	return (void __iomem *)(offset + addr);
 }
 
-void __iomem *__ioremap(phys_addr_t phys_addr, size_t size, pgprot_t prot)
+void __iomem *__ioremap(resource_size_t phys_addr, size_t size, pgprot_t prot)
 {
 	return __ioremap_caller(phys_addr, size, prot,
 				__builtin_return_address(0));
@@ -93,7 +93,7 @@ void __iounmap(volatile void __iomem *io_addr)
 }
 EXPORT_SYMBOL(__iounmap);
 
-void __iomem *ioremap_cache(phys_addr_t phys_addr, size_t size)
+void __iomem *ioremap_cache(resource_size_t phys_addr, size_t size)
 {
 	/* For normal memory we already have a cacheable mapping. */
 	if (pfn_valid(__phys_to_pfn(phys_addr)))
-- 
1.9.1



From p.zabel at pengutronix.de  Thu Aug 27 01:39:12 2015
From: p.zabel at pengutronix.de (Philipp Zabel)
Date: Thu, 27 Aug 2015 10:39:12 +0200
Subject: [PATCH 04/12] gpu: imx: fix support for interlaced modes
In-Reply-To: <E1ZO6ay-0002qh-6E@rmk-PC.arm.linux.org.uk>
References: <20150808160251.GM7557@n2100.arm.linux.org.uk>
 <E1ZO6ay-0002qh-6E@rmk-PC.arm.linux.org.uk>
Message-ID: <1440664752.3233.36.camel@pengutronix.de>

Hi Russell,

Am Samstag, den 08.08.2015, 17:03 +0100 schrieb Russell King:
> The support for interlaced video modes seems to be broken; we don't use
> anything other than the vtotal/htotal from the timing information to
> define the various sync counters.

I finally made time to test this series:

Tested-by: Philipp Zabel <p.zabel at pengutronix.de>
on i.MX6 GK802 via HDMI connected to a TV (1080p60, 1080i60).

Unfortunately these timings are completely different from what Freescale
came up with for the TV Encoder on i.MX5, but the code we have currently
in mainline doesn't work for that either. I suppose I'll follow up with
a patch that adds yet another sync counter setup for the i.MX5/TVE case.

I'd like to take the two ipu-v3 patches, making a few small changes on
this one:

> Freescale patches for interlaced video support contain an alternative
> sync counter setup, which we include here.  This setup produces the
> hsync and vsync via the normal counter 2 and 3, but moves the display
> enable signal from counter 5 to counter 6.  Therefore, we need to
> change the display controller setup as well.
> 
> The corresponding Freescale patches for this change are:
>   iMX6-HDMI-support-interlaced-display-mode.patch
>   IPU-fine-tuning-the-interlace-display-timing-for-CEA.patch
> 
> This produces a working interlace format output from the IPU.

... on i.MX6 via HDMI.

> Signed-off-by: Russell King <rmk+kernel at arm.linux.org.uk>
> ---
>  drivers/gpu/ipu-v3/ipu-dc.c | 18 ++++++++---
>  drivers/gpu/ipu-v3/ipu-di.c | 79 +++++++++++++++++++++------------------------
>  2 files changed, 51 insertions(+), 46 deletions(-)
> 
> diff --git a/drivers/gpu/ipu-v3/ipu-dc.c b/drivers/gpu/ipu-v3/ipu-dc.c
> index 9ef2e1f54ca4..aa560855c1dc 100644
> --- a/drivers/gpu/ipu-v3/ipu-dc.c
> +++ b/drivers/gpu/ipu-v3/ipu-dc.c
> @@ -183,12 +183,22 @@ int ipu_dc_init_sync(struct ipu_dc *dc, struct ipu_di *di, bool interlaced,
>  	}
>  
>  	if (interlaced) {
> -		dc_link_event(dc, DC_EVT_NL, 0, 3);
> -		dc_link_event(dc, DC_EVT_EOL, 0, 2);
> -		dc_link_event(dc, DC_EVT_NEW_DATA, 0, 1);
> +		int word, addr;
> +
> +		if (dc->di) {
> +			addr = 1;
> +			word = 1;

These two are really one and the same. The address written to the link
register for the given event has to point to the address of the
microcode instruction written to the template memory that should be
executed on this event.

I'd like to drop the word variable and use addr for both.

> +		} else {
> +			addr = 0;
> +			word = 0;
> +		}
> +
> +		dc_link_event(dc, DC_EVT_NL, addr, 3);
> +		dc_link_event(dc, DC_EVT_EOL, addr, 2);
> +		dc_link_event(dc, DC_EVT_NEW_DATA, addr, 1);
>  
>  		/* Init template microcode */
> -		dc_write_tmpl(dc, 0, WROD(0), 0, map, SYNC_WAVE, 0, 8, 1);
> +		dc_write_tmpl(dc, word, WROD(0), 0, map, SYNC_WAVE, 0, 6, 1);
>  	} else {
>  		if (dc->di) {
>  			dc_link_event(dc, DC_EVT_NL, 2, 3);
> diff --git a/drivers/gpu/ipu-v3/ipu-di.c b/drivers/gpu/ipu-v3/ipu-di.c
> index a96991c5c15f..359268e3a166 100644
> --- a/drivers/gpu/ipu-v3/ipu-di.c
> +++ b/drivers/gpu/ipu-v3/ipu-di.c
> @@ -71,6 +71,10 @@ enum di_sync_wave {
>  	DI_SYNC_HSYNC = 3,
>  	DI_SYNC_VSYNC = 4,
>  	DI_SYNC_DE = 6,
> +
> +	DI_SYNC_CNT1 = 2,	/* counter >= 2 only */
> +	DI_SYNC_CNT4 = 5,	/* counter >= 5 only */
> +	DI_SYNC_CNT5 = 6,	/* counter >= 6 only */
>  };
>  
>  #define SYNC_WAVE 0
> @@ -211,66 +215,59 @@ static void ipu_di_sync_config_interlaced(struct ipu_di *di,
>  		sig->mode.hback_porch + sig->mode.hfront_porch;
>  	u32 v_total = sig->mode.vactive + sig->mode.vsync_len +
>  		sig->mode.vback_porch + sig->mode.vfront_porch;
> -	u32 reg;
>  	struct di_sync_config cfg[] = {
>  		{
> -			.run_count = h_total / 2 - 1,
> -			.run_src = DI_SYNC_CLK,
> +			/* 1: internal VSYNC for each frame */
> +			.run_count = v_total * 2 - 1,
> +			.run_src = 3,			/* == counter 7 */

Do you know why this works? The Reference Manual v2 lists that value as
"NA" in the DI counter #1 Run Resolution field.

>  		}, {
> -			.run_count = h_total - 11,
> +			/* PIN2: HSYNC waveform */
> +			.run_count = h_total - 1,
>  			.run_src = DI_SYNC_CLK,
> -			.cnt_down = 4,
> +			.cnt_polarity_gen_en = 1,
> +			.cnt_polarity_trigger_src = DI_SYNC_CLK,
> +			.cnt_down = sig->mode.hsync_len * 2,
>  		}, {
> -			.run_count = v_total * 2 - 1,
> -			.run_src = DI_SYNC_INT_HSYNC,
> -			.offset_count = 1,
> -			.offset_src = DI_SYNC_INT_HSYNC,
> -			.cnt_down = 4,
> +			/* PIN3: VSYNC waveform */
> +			.run_count = v_total - 1,
> +			.run_src = 4,			/* == counter 7 */

Same here, ...

> +			.cnt_polarity_gen_en = 1,
> +			.cnt_polarity_trigger_src = 4,	/* == counter 7 */

... and same here, the DI counter #3 polarity Clear select field lists
the value 4 as "Reserved".

> +			.cnt_down = sig->mode.vsync_len * 2,
> +			.cnt_clr_src = DI_SYNC_CNT1,
>  		}, {
[...]
>  		}
>  	};
>  
>  	ipu_di_sync_config(di, cfg, 0, ARRAY_SIZE(cfg));
>  
> -	/* set gentime select and tag sel */
> -	reg = ipu_di_read(di, DI_SW_GEN1(9));
> -	reg &= 0x1FFFFFFF;
> -	reg |= (3 - 1) << 29 | 0x00008000;
> -	ipu_di_write(di, reg, DI_SW_GEN1(9));

As far as I understood, attaching counter #9 to counter #3 is needed to
generate the second vsync on i.MX5. Since this doesn't currently work,
I'm fine with removing it for now.

>  	ipu_di_write(di, v_total / 2 - 1, DI_SCR_CONF);
>  }
>  
> @@ -605,10 +602,8 @@ int ipu_di_init_sync_panel(struct ipu_di *di, struct ipu_di_signal_cfg *sig)
>  
>  		/* set y_sel = 1 */
>  		di_gen |= 0x10000000;
> -		di_gen |= DI_GEN_POLARITY_5;
> -		di_gen |= DI_GEN_POLARITY_8;
>  
> -		vsync_cnt = 7;
> +		vsync_cnt = 3;
>  	} else {
>  		ipu_di_sync_config_noninterlaced(di, sig, div);

regards
Philipp




From p.zabel at pengutronix.de  Thu Aug 27 01:42:21 2015
From: p.zabel at pengutronix.de (Philipp Zabel)
Date: Thu, 27 Aug 2015 10:42:21 +0200
Subject: [PATCH 0/9] dw-hdmi audio support
In-Reply-To: <20150808160936.GN7557@n2100.arm.linux.org.uk>
References: <20150808160251.GM7557@n2100.arm.linux.org.uk>
 <20150808160936.GN7557@n2100.arm.linux.org.uk>
Message-ID: <1440664941.3233.38.camel@pengutronix.de>

Am Samstag, den 08.08.2015, 17:09 +0100 schrieb Russell King - ARM
Linux:
> Following on from the previous sub-series, this sub-series adds audio
> support to dw-hdmi.
> 
> The two different variants are now in this patch: AHB audio support
> found on iMX6 platforms, and I2S support found on Rockchip patches.
> Thanks to Yakir Yang for contributing the I2S support.
> 
> I suspect that there is still some discussion to be had on this
> series, though I would like to see it moving forward so that we can
> get something merged.

Tested-by: Philipp Zabel <p.zabel at pengutronix.de>
on i.MX6 GK802 via HDMI connected to a TV (stereo only).

except for the i2s patch, which is broken in this series.

regards
Philipp



From punnaia at xilinx.com  Thu Aug 27 01:48:43 2015
From: punnaia at xilinx.com (punnaiah choudary kalluri)
Date: Thu, 27 Aug 2015 14:18:43 +0530
Subject: [LINUX RFC v2 0/4] spi: add dual parallel mode support in Zynq
 MPSoC GQSPI controller
In-Reply-To: <CAD6G_RTCQ5Fzjgxz+-3oMDAyUTg6UFAqvpEPQzJ9maSTZ3Nc_g@mail.gmail.com>
References: <1440570367-22569-1-git-send-email-ranjit.waghmode@xilinx.com>
 <CAD6G_RQhWBsUTZNBB44W98Fjzw82H_D_E9nY0aDWezj729mkoA@mail.gmail.com>
 <CAGnW=BZtsVtT+Z7gTq5jybXsHWp+RNpjc6ckk6-MXWxAS7u8Mw@mail.gmail.com>
 <CAD6G_RTCQ5Fzjgxz+-3oMDAyUTg6UFAqvpEPQzJ9maSTZ3Nc_g@mail.gmail.com>
Message-ID: <CAGnW=BZ80B_2kzZVULhZvEXFs+_GXkGbu8mii1eFp3MySvA8aA@mail.gmail.com>

On Thu, Aug 27, 2015 at 11:53 AM, Jagan Teki <jteki at openedev.com> wrote:
> On 26 August 2015 at 21:02, punnaiah choudary kalluri
> <punnaia at xilinx.com> wrote:
>> On Wed, Aug 26, 2015 at 5:49 PM, Jagan Teki <jteki at openedev.com> wrote:
>>> On 26 August 2015 at 11:56, Ranjit Waghmode <ranjit.waghmode at xilinx.com> wrote:
>>>> This series adds dual parallel mode support for Zynq Ultrascale+
>>>> MPSoC GQSPI controller driver.
>>>>
>>>> What is dual parallel mode?
>>>> ---------------------------
>>>> ZynqMP GQSPI controller supports Dual Parallel mode with following functionalities:
>>>> 1) Supporting two SPI flash memories operating in parallel. 8 I/O lines.
>>>> 2) Chip selects and clock are shared to both the flash devices
>>>> 3) This mode is targeted for faster read/write speed and also doubles the size
>>>> 4) Commands/data can be transmitted/received from both the devices(mirror),
>>>>    or only upper or only lower flash memory devices.
>>>> 5) Data arrangement:
>>>>    With stripe enabled,
>>>>    Even bytes i.e. 0, 2, 4,... are transmitted on Lower Data Bus
>>>>    Odd bytes i.e. 1, 3, 5,.. are transmitted on Upper Data Bus.
<snip>
>>> I don't find any previous discussion about way to inform flash
>>> dual-ness into spi-nor
>>> from spi drivers.
>>>
>>> Here is my idea, probably others may think same.
>>> Informing dual_flash from drivers/spi through flags or any other mode
>>> bits is not a better approach as dual flash feature is specific to
>>> spi-nor flash controller (controller specially designed for spi-nor
>>> flash not the generic spi controller).  So if the driver sits on
>>> drivers/mtd/spi-nor/ (ex: fsl-quadspi.c), may be we can inform flash
>>> specific things to spi-nor as it's not touching generic spi stack in
>>> Linux. But there is a defined-drawback if the driver is moved to
>>> drivers/mtd/spi-nor ie it can't use spi core API's at-all.
>>
>> Xilinx GQSPI is a generic quad spi controller. The primary goal is to support
>> Generic/Future command sequences and Future NOR/NAND flash devices.
>> This core can also be used for legacy SPI devices. Due to the generic nature
>> of the core, software can generate any command sequence. It also has additional
>> features like parallel and stacked configurations to double the data
>> rate and size.
>> Accessing spi-nor flash device is one particular use case and like
>> that there will be
>> many. So, we decided to keep this driver in generic spi framework and
>> that is the ideal
>> thing to do for the GQSPI controller.
>
> Yes, I understand the generic nature of the GQSPI and it's good to
> have all-in-one like generic spi, spi-nor and spi-nand and more
> together, but Linux stacks were implemented in such a way to support
> the each type of controller with connected slaves separably for better
> handling.

True and this is the reason we have controller drivers and protocol drivers.
GQSPI is the controller driver and spi-nor and spi-nand are the
protocol drivers.

>
> Currently GQSPI driver is added in drivers/spi as it supports generic
> spi nature and now it enhanced more through flags for supporting
> spi-nor, what if we add spi-nand support for the same controller? do
> we add one more driver in spi-nand framework (drivers/mtd/spi-nand -
> an on going implementation)? My only observation here is even if the
> controller is more generic to support more number of device classes,
> and adding same driver and populate the slave stuff through flags or
> different kind of mechanism to different driver stack, this is not a
> better approach I thought.

Just to clear, dual parallel( 2 CS and 8 IO lines) is not only specific
to flash parts, one can use for any other custom streaming protocols
I would say exporting dual parallel connection to protocol drivers is
something like depicting the spi bus topology to the protocol layer.

AFAIK, spi-nor and spi-nand are protocol drivers for accessing the
nor and nand flash devices sitting on the spi bus using the spi
controller driver.

Regards,
Punnaiah

>
> Based on the above comments, there is an approach to handle this
> support and I'm not 100% sure whether this fits or not but we
> implemented the same -  this is "probing child devices from parent"
> (there was a discussion with Arnd earlier wrt this, but I'm unable to
> get the mailing thread)
>
> Added Arnd (probably will give more inputs or corrections)
>
> Let me explain how we implemented on our design.
> We have PCIe controller that support basic root complex handling, dma
> and controller hotplug (not in-build pcie hp) and ideally we need to
> write driver for handling root complex on drivers/pci/host and one
> hotplug driver in drivers/pci and one more driver in drivers/dma for
> handling pcie dma stuff. And some pcie calls need to navigate from
> root complex driver to dma and hotplug driver that means there is call
> transition from driver/pci to driver/dma which is absolutely not a
> good approach (spi to spi-nor and spi-nand transition - in GQSPI case)
>
> So the implementation we follow is like there is a pcie root complex
> driver(probably generic spi driver in drivers/spi/*) and inside probe
> we have register platform_device for hotplug (spi-nor) and dma
> (spi-nand) and the dma driver in drivers/dma and hotplug driver in
> driver/pci/ are platform drivers which is of legacy binding (not with
> dts) so there should be a common dts for root complex driver
> (drivers/spi/*) and individual child driver need to take those while
> registering platform_device.
>
> example pseudo:
>
> drivers/dma/dma-child2.c
>
> Legacy platform_driver binding and handling dma future as normal dma
> driver, spi-nand in your case
>
> drivers/pci/hotplug/hp-child1.c
>
> Legacy platform_driver binding and handling hotplug future as normal
> hotplug driver, spi-nor in your case.
>
> drivers/pci/host/rc-parent-pci.c
>
> static int rc_parent_pcie_probe_bridge(struct platform_device *pdev)
> {
>    // Generic rc handling (genric spi stuff)
>
>    // Hotplug handling (spi-nor)
>    - platform_device_alloc
>    - assign need resources
>    - register pdev using platform_device_add
>
>     // DMA handling (spi-nand)
>    - same as above
> }
>
> static const struct of_device_id rc_parent_pcie_match_table[] = {
>         {.compatible = "abc,rc-parent",},
>         {},
> };
>
> static struct platform_driver rc_parent_pcie_driver = {
>         .driver = {
>                    .name = "rc-parent",
>                    .of_match_table = of_match_ptr(rc_parent_pcie_match_table),
>         },
>         .probe = rc_parent_pcie_probe_bridge,
> };
> module_platform_driver(rc_parent_pcie_driver);
>
> I couldn't find any driver mainlined wrt this design, think more on
> GQSPI front, whether this design fits well or not.
>
> thanks!
> --
> Jagan | openedev.
> --
> To unsubscribe from this list: send the line "unsubscribe linux-spi" in
> the body of a message to majordomo at vger.kernel.org
> More majordomo info at  http://vger.kernel.org/majordomo-info.html


From ulf.hansson at linaro.org  Thu Aug 27 01:48:58 2015
From: ulf.hansson at linaro.org (Ulf Hansson)
Date: Thu, 27 Aug 2015 10:48:58 +0200
Subject: [PATCH] pwrseq: bind pinctrl pins before using the gpios
In-Reply-To: <CAPDyKFqMOr5DwDcOjDTUV4Eaqp4VK1Q-Dt2_KcG-GtsNOr8JkQ@mail.gmail.com>
References: <1439812687-18259-1-git-send-email-srinivas.kandagatla@linaro.org>
 <CAPDyKFqMOr5DwDcOjDTUV4Eaqp4VK1Q-Dt2_KcG-GtsNOr8JkQ@mail.gmail.com>
Message-ID: <CAPDyKFpZaeBbfN05HoHGafbkEJ1k6ZCNn+o5w6HKUzJ7Q0irPg@mail.gmail.com>

+ Stephen Rothwell

On 25 August 2015 at 14:06, Ulf Hansson <ulf.hansson at linaro.org> wrote:
> On 17 August 2015 at 13:58, Srinivas Kandagatla
> <srinivas.kandagatla at linaro.org> wrote:
>> Some of the pin-controllers like the Qualcomms "qcom,pm8921", which
>> require a pinconf to be setup to use pins as gpios. Using the pins
>> directly without pinconf setup would result in incorrect output voltage
>> or load settings. On the other hand pwrseq code does not configure the
>> pinctrl by default as it does not go thru the driver core.
>>
>> This patch adds a call to pinctrl_bind_pins() to bind pins which
>> are going to be used as gpios.
>>
>> Signed-off-by: Srinivas Kandagatla <srinivas.kandagatla at linaro.org>
>
> Thanks, applied for next! I add the "mmc:" to the prefix of the commit
> message header.

This went in too quickly, my bad!

The kbuild test robot reports an error when building i386 with
allmodconfig, so I will drop this patch from my next branch.
https://lists.01.org/pipermail/kbuild-all/2015-August/011806.html

Moreover I have some more comment around the patch, see below.

>
> Kind regards
> Uffe
>
>> ---
>>  drivers/mmc/core/pwrseq.c | 5 +++++
>>  1 file changed, 5 insertions(+)
>>
>> diff --git a/drivers/mmc/core/pwrseq.c b/drivers/mmc/core/pwrseq.c
>> index 4c1d175..6e5d8b3 100644
>> --- a/drivers/mmc/core/pwrseq.c
>> +++ b/drivers/mmc/core/pwrseq.c
>> @@ -12,6 +12,7 @@
>>  #include <linux/err.h>
>>  #include <linux/of.h>
>>  #include <linux/of_platform.h>
>> +#include <linux/pinctrl/devinfo.h>
>>
>>  #include <linux/mmc/host.h>
>>
>> @@ -65,6 +66,10 @@ int mmc_pwrseq_alloc(struct mmc_host *host)
>>                 goto err;
>>         }
>>
>> +       ret = pinctrl_bind_pins(&pdev->dev);

pinctrl_bind_bins() uses devm_* functions and that's not going to work
as the used device here isn't being probed/released.

Instead you need to use the *non* devm_pinctrl_*() APIs, such as
pinctrl_get|put() etc.

>> +       if (ret)
>> +               goto err;
>> +
>>         match = mmc_pwrseq_find(np);
>>         if (IS_ERR(match)) {
>>                 ret = PTR_ERR(match);
>> --
>> 1.9.1
>>

Kind regards
Uffe


From shawn.lin at rock-chips.com  Thu Aug 27 01:48:00 2015
From: shawn.lin at rock-chips.com (Shawn Lin)
Date: Thu, 27 Aug 2015 16:48:00 +0800
Subject: [PATCH 0/5] Fix broken DMAFLUSHP on Rockchips platform
Message-ID: <1440665280-31557-1-git-send-email-shawn.lin@rock-chips.com>


The purpose of the DMAFLUSHP instruction:
- Tell the peripheral to clear its status and control registers.
- Send a message to the peripheral to resend its level status.

There are 3 timings described in PL330 Technical Reference Manual:
- Timing 1: Burst request, can work well without DMAFLUSHP.
- Timing 2: Single and burst request, DMAC will ignore the single
	    transfer request. This timing happens if there are single
	    and burst request.
- Timing 3: Single transfers for a burst request, DMAC should signals
	    datype to request the peripheral to flush the contents of
	    any control registers. This timing happens if there is
	    not enough MFIFO to places the burst data.

A peripheral may signal a DMA request during the execution of
DMAFLUSHP instruction, that cause DMA request being ignored by DMAC.

But DMAC and all peripherals on RK3X SoCs DO NOT support DMAFLUSHP.
It can't send a message to the peripheral to resend DMA request,
and the peripheral can't acknowledge a flush request from DMAC.
So all DMA requests should NOT be ignored by DMAC, and DMAC will not
notify the peripheral to flush.

To fix this problem, we need:
- Do NOT execute DMAFLUSHP instruction.
- Timing 2 and timing 3 should not happen.

Because on RK3X SoCs, there are 6 or below  channels and 32 MFIFO depth
for DMAC_BUS, and 8 channels and 64 MFIFO depth for DMAC_PERI, it is
impossible to hit the timing 3 if burst length is equal or less than 4.

Since the request type signal by the peripheral can only be set by
software. We can set Rockchip Soc's GRF_PERIDMAC_CON0[2:1] to select single
or burst request, if it is set b01,  all of the peripharals will signal a brust
request. So the timing 2 will not happen, too.

So DMAC on RK3X can support single or burst transfer, but can't support
mixed transfer.

Because burst transfer is more efficient than single transfer, this is
confirmed by our ASIC team, who strongly suggest to use burst transfer.
And this is confirmed by Addy's test on RK3288-Pink2 board, the speed of
spi flash burst transfer will increase about two times than single transfer.
Also, I have tested dw_mmc with pl330 on RK3188 platform to double confirm
the result. That means burst transfer is reansonable.

So we need a quirk not to execute DMAFLUSHP instruction and to use burst
transfer.

Note:
- The Rockchip Soc default value of GRF_PERIDMAC_CON0[2:1] is b01. To
  support brust transfer, these bits should not be changed in bootloader.



Shawn Lin (5):
  DMA: pl330: support burst mode for dev-to-mem and mem-to-dev transmit
  DMA: pl330: add quirk for broken no flushp
  ARM: dts: Add broken-no-flushp quirk for rk3288 platform
  ARM: dts: Add broken-no-flushp quirk for rk3xxx platform
  Documentation: arm-pl330: add description of broken-no-flushp

 .../devicetree/bindings/dma/arm-pl330.txt          |   1 +
 arch/arm/boot/dts/rk3288.dtsi                      |   3 +
 arch/arm/boot/dts/rk3xxx.dtsi                      |   3 +
 drivers/dma/pl330.c                                | 101 +++++++++++++++------
 4 files changed, 79 insertions(+), 29 deletions(-)

-- 
2.3.7




From shawn.lin at rock-chips.com  Thu Aug 27 01:48:33 2015
From: shawn.lin at rock-chips.com (Shawn Lin)
Date: Thu, 27 Aug 2015 16:48:33 +0800
Subject: [PATCH 1/5] DMA: pl330: support burst mode for dev-to-mem and
 mem-to-dev transmit
In-Reply-To: <1440665280-31557-1-git-send-email-shawn.lin@rock-chips.com>
References: <1440665280-31557-1-git-send-email-shawn.lin@rock-chips.com>
Message-ID: <1440665313-31603-1-git-send-email-shawn.lin@rock-chips.com>

This patch adds to support burst mode for dev-to-mem and
mem-to-dev transmit.

Signed-off-by: Boojin Kim <boojin.kim at samsung.com>
Signed-off-by: Addy Ke <addy.ke at rock-chips.com>
Signed-off-by: Shawn Lin <shawn.lin at rock-chips.com>
cc: Heiko Stuebner <heiko at sntech.de>
cc: Doug Anderson <dianders at chromium.org>
cc: Olof Johansson <olofj at google.com>
Reviewed-and-tested-by: Sonny Rao <sonnyrao at chromium.org>

---

 drivers/dma/pl330.c | 18 ++++++++++++------
 1 file changed, 12 insertions(+), 6 deletions(-)

diff --git a/drivers/dma/pl330.c b/drivers/dma/pl330.c
index ecab4ea0..0d544d2 100644
--- a/drivers/dma/pl330.c
+++ b/drivers/dma/pl330.c
@@ -1141,10 +1141,13 @@ static inline int _ldst_devtomem(unsigned dry_run, u8 buf[],
 		const struct _xfer_spec *pxs, int cyc)
 {
 	int off = 0;
+	enum pl330_cond cond;
+
+	cond = (pxs->desc->rqcfg.brst_len == 1) ? SINGLE : BURST;
 
 	while (cyc--) {
-		off += _emit_WFP(dry_run, &buf[off], SINGLE, pxs->desc->peri);
-		off += _emit_LDP(dry_run, &buf[off], SINGLE, pxs->desc->peri);
+		off += _emit_WFP(dry_run, &buf[off], cond, pxs->desc->peri);
+		off += _emit_LDP(dry_run, &buf[off], cond, pxs->desc->peri);
 		off += _emit_ST(dry_run, &buf[off], ALWAYS);
 		off += _emit_FLUSHP(dry_run, &buf[off], pxs->desc->peri);
 	}
@@ -1156,11 +1159,14 @@ static inline int _ldst_memtodev(unsigned dry_run, u8 buf[],
 		const struct _xfer_spec *pxs, int cyc)
 {
 	int off = 0;
+	enum pl330_cond cond;
+
+	cond = (pxs->desc->rqcfg.brst_len == 1) ? SINGLE : BURST;
 
 	while (cyc--) {
-		off += _emit_WFP(dry_run, &buf[off], SINGLE, pxs->desc->peri);
+		off += _emit_WFP(dry_run, &buf[off], cond, pxs->desc->peri);
 		off += _emit_LD(dry_run, &buf[off], ALWAYS);
-		off += _emit_STP(dry_run, &buf[off], SINGLE, pxs->desc->peri);
+		off += _emit_STP(dry_run, &buf[off], cond, pxs->desc->peri);
 		off += _emit_FLUSHP(dry_run, &buf[off], pxs->desc->peri);
 	}
 
@@ -2557,7 +2563,7 @@ static struct dma_async_tx_descriptor *pl330_prep_dma_cyclic(
 
 		desc->rqtype = direction;
 		desc->rqcfg.brst_size = pch->burst_sz;
-		desc->rqcfg.brst_len = 1;
+		desc->rqcfg.brst_len = pch->burst_len;
 		desc->bytes_requested = period_len;
 		fill_px(&desc->px, dst, src, period_len);
 
@@ -2702,7 +2708,7 @@ pl330_prep_slave_sg(struct dma_chan *chan, struct scatterlist *sgl,
 		}
 
 		desc->rqcfg.brst_size = pch->burst_sz;
-		desc->rqcfg.brst_len = 1;
+		desc->rqcfg.brst_len = pch->burst_len;
 		desc->rqtype = direction;
 		desc->bytes_requested = sg_dma_len(sg);
 	}
-- 
2.3.7




From shawn.lin at rock-chips.com  Thu Aug 27 01:48:46 2015
From: shawn.lin at rock-chips.com (Shawn Lin)
Date: Thu, 27 Aug 2015 16:48:46 +0800
Subject: [PATCH 2/5] DMA: pl330: add quirk for broken no flushp
In-Reply-To: <1440665280-31557-1-git-send-email-shawn.lin@rock-chips.com>
References: <1440665280-31557-1-git-send-email-shawn.lin@rock-chips.com>
Message-ID: <1440665326-31645-1-git-send-email-shawn.lin@rock-chips.com>

This patch add "broken-no-flushp" quirk to avoid execute
DMAFLUSHP if Soc doesn't support it.

Signed-off-by: Addy Ke <addy.ke at rock-chips.com>
Signed-off-by: Shawn Lin <shawn.lin at rock-chips.com>
cc: Heiko Stuebner <heiko at sntech.de>
cc: Doug Anderson <dianders at chromium.org>
cc: Olof Johansson <olofj at google.com>
Reviewed-and-tested-by: Sonny Rao <sonnyrao at chromium.org>
---

 drivers/dma/pl330.c | 87 ++++++++++++++++++++++++++++++++++++++---------------
 1 file changed, 62 insertions(+), 25 deletions(-)

diff --git a/drivers/dma/pl330.c b/drivers/dma/pl330.c
index 0d544d2..c300dc2 100644
--- a/drivers/dma/pl330.c
+++ b/drivers/dma/pl330.c
@@ -34,6 +34,8 @@
 #define PL330_MAX_IRQS		32
 #define PL330_MAX_PERI		32
 
+#define PL330_QUIRK_BROKEN_NO_FLUSHP BIT(0)
+
 enum pl330_cachectrl {
 	CCTRL0,		/* Noncacheable and nonbufferable */
 	CCTRL1,		/* Bufferable only */
@@ -488,6 +490,17 @@ struct pl330_dmac {
 	/* Peripheral channels connected to this DMAC */
 	unsigned int num_peripherals;
 	struct dma_pl330_chan *peripherals; /* keep at end */
+	int quirks;
+};
+
+static struct pl330_of_quirks {
+	char *quirk;
+	int id;
+} of_quirks[] = {
+	{
+		.quirk = "broken-no-flushp",
+		.id = PL330_QUIRK_BROKEN_NO_FLUSHP,
+	}
 };
 
 struct dma_pl330_desc {
@@ -1137,53 +1150,68 @@ static inline int _ldst_memtomem(unsigned dry_run, u8 buf[],
 	return off;
 }
 
-static inline int _ldst_devtomem(unsigned dry_run, u8 buf[],
-		const struct _xfer_spec *pxs, int cyc)
+static inline int _ldst_devtomem(struct pl330_dmac *pl330, unsigned dry_run,
+				 u8 buf[], const struct _xfer_spec *pxs,
+				 int cyc)
 {
 	int off = 0;
 	enum pl330_cond cond;
 
-	cond = (pxs->desc->rqcfg.brst_len == 1) ? SINGLE : BURST;
+	if (pl330->quirks & PL330_QUIRK_BROKEN_NO_FLUSHP)
+		cond = BURST;
+	else
+		cond = (pxs->desc->rqcfg.brst_len == 1) ? SINGLE : BURST;
 
 	while (cyc--) {
 		off += _emit_WFP(dry_run, &buf[off], cond, pxs->desc->peri);
 		off += _emit_LDP(dry_run, &buf[off], cond, pxs->desc->peri);
 		off += _emit_ST(dry_run, &buf[off], ALWAYS);
-		off += _emit_FLUSHP(dry_run, &buf[off], pxs->desc->peri);
+
+		if (!(pl330->quirks & PL330_QUIRK_BROKEN_NO_FLUSHP))
+			off += _emit_FLUSHP(dry_run, &buf[off],
+					    pxs->desc->peri);
 	}
 
 	return off;
 }
 
-static inline int _ldst_memtodev(unsigned dry_run, u8 buf[],
-		const struct _xfer_spec *pxs, int cyc)
+static inline int _ldst_memtodev(struct pl330_dmac *pl330,
+				 unsigned dry_run, u8 buf[],
+				 const struct _xfer_spec *pxs, int cyc)
 {
 	int off = 0;
 	enum pl330_cond cond;
 
-	cond = (pxs->desc->rqcfg.brst_len == 1) ? SINGLE : BURST;
+	if (pl330->quirks & PL330_QUIRK_BROKEN_NO_FLUSHP)
+		cond = BURST;
+	else
+		cond = (pxs->desc->rqcfg.brst_len == 1) ? SINGLE : BURST;
+
 
 	while (cyc--) {
 		off += _emit_WFP(dry_run, &buf[off], cond, pxs->desc->peri);
 		off += _emit_LD(dry_run, &buf[off], ALWAYS);
 		off += _emit_STP(dry_run, &buf[off], cond, pxs->desc->peri);
-		off += _emit_FLUSHP(dry_run, &buf[off], pxs->desc->peri);
+
+		if (!(pl330->quirks & PL330_QUIRK_BROKEN_NO_FLUSHP))
+			off += _emit_FLUSHP(dry_run, &buf[off],
+					    pxs->desc->peri);
 	}
 
 	return off;
 }
 
-static int _bursts(unsigned dry_run, u8 buf[],
+static int _bursts(struct pl330_dmac *pl330, unsigned dry_run, u8 buf[],
 		const struct _xfer_spec *pxs, int cyc)
 {
 	int off = 0;
 
 	switch (pxs->desc->rqtype) {
 	case DMA_MEM_TO_DEV:
-		off += _ldst_memtodev(dry_run, &buf[off], pxs, cyc);
+		off += _ldst_memtodev(pl330, dry_run, &buf[off], pxs, cyc);
 		break;
 	case DMA_DEV_TO_MEM:
-		off += _ldst_devtomem(dry_run, &buf[off], pxs, cyc);
+		off += _ldst_devtomem(pl330, dry_run, &buf[off], pxs, cyc);
 		break;
 	case DMA_MEM_TO_MEM:
 		off += _ldst_memtomem(dry_run, &buf[off], pxs, cyc);
@@ -1197,7 +1225,7 @@ static int _bursts(unsigned dry_run, u8 buf[],
 }
 
 /* Returns bytes consumed and updates bursts */
-static inline int _loop(unsigned dry_run, u8 buf[],
+static inline int _loop(struct pl330_dmac *pl330, unsigned dry_run, u8 buf[],
 		unsigned long *bursts, const struct _xfer_spec *pxs)
 {
 	int cyc, cycmax, szlp, szlpend, szbrst, off;
@@ -1220,7 +1248,7 @@ static inline int _loop(unsigned dry_run, u8 buf[],
 	}
 
 	szlp = _emit_LP(1, buf, 0, 0);
-	szbrst = _bursts(1, buf, pxs, 1);
+	szbrst = _bursts(pl330, 1, buf, pxs, 1);
 
 	lpend.cond = ALWAYS;
 	lpend.forever = false;
@@ -1252,7 +1280,7 @@ static inline int _loop(unsigned dry_run, u8 buf[],
 	off += _emit_LP(dry_run, &buf[off], 1, lcnt1);
 	ljmp1 = off;
 
-	off += _bursts(dry_run, &buf[off], pxs, cyc);
+	off += _bursts(pl330, dry_run, &buf[off], pxs, cyc);
 
 	lpend.cond = ALWAYS;
 	lpend.forever = false;
@@ -1275,8 +1303,9 @@ static inline int _loop(unsigned dry_run, u8 buf[],
 	return off;
 }
 
-static inline int _setup_loops(unsigned dry_run, u8 buf[],
-		const struct _xfer_spec *pxs)
+static inline int _setup_loops(struct pl330_dmac *pl330,
+			       unsigned dry_run, u8 buf[],
+			       const struct _xfer_spec *pxs)
 {
 	struct pl330_xfer *x = &pxs->desc->px;
 	u32 ccr = pxs->ccr;
@@ -1285,15 +1314,16 @@ static inline int _setup_loops(unsigned dry_run, u8 buf[],
 
 	while (bursts) {
 		c = bursts;
-		off += _loop(dry_run, &buf[off], &c, pxs);
+		off += _loop(pl330, dry_run, &buf[off], &c, pxs);
 		bursts -= c;
 	}
 
 	return off;
 }
 
-static inline int _setup_xfer(unsigned dry_run, u8 buf[],
-		const struct _xfer_spec *pxs)
+static inline int _setup_xfer(struct pl330_dmac *pl330,
+			      unsigned dry_run, u8 buf[],
+			      const struct _xfer_spec *pxs)
 {
 	struct pl330_xfer *x = &pxs->desc->px;
 	int off = 0;
@@ -1304,7 +1334,7 @@ static inline int _setup_xfer(unsigned dry_run, u8 buf[],
 	off += _emit_MOV(dry_run, &buf[off], DAR, x->dst_addr);
 
 	/* Setup Loop(s) */
-	off += _setup_loops(dry_run, &buf[off], pxs);
+	off += _setup_loops(pl330, dry_run, &buf[off], pxs);
 
 	return off;
 }
@@ -1313,8 +1343,9 @@ static inline int _setup_xfer(unsigned dry_run, u8 buf[],
  * A req is a sequence of one or more xfer units.
  * Returns the number of bytes taken to setup the MC for the req.
  */
-static int _setup_req(unsigned dry_run, struct pl330_thread *thrd,
-		unsigned index, struct _xfer_spec *pxs)
+static int _setup_req(struct pl330_dmac *pl330, unsigned dry_run,
+		      struct pl330_thread *thrd, unsigned index,
+		      struct _xfer_spec *pxs)
 {
 	struct _pl330_req *req = &thrd->req[index];
 	struct pl330_xfer *x;
@@ -1331,7 +1362,7 @@ static int _setup_req(unsigned dry_run, struct pl330_thread *thrd,
 	if (x->bytes % (BRST_SIZE(pxs->ccr) * BRST_LEN(pxs->ccr)))
 		return -EINVAL;
 
-	off += _setup_xfer(dry_run, &buf[off], pxs);
+	off += _setup_xfer(pl330, dry_run, &buf[off], pxs);
 
 	/* DMASEV peripheral/event */
 	off += _emit_SEV(dry_run, &buf[off], thrd->ev);
@@ -1425,7 +1456,7 @@ static int pl330_submit_req(struct pl330_thread *thrd,
 	xs.desc = desc;
 
 	/* First dry run to check if req is acceptable */
-	ret = _setup_req(1, thrd, idx, &xs);
+	ret = _setup_req(pl330, 1, thrd, idx, &xs);
 	if (ret < 0)
 		goto xfer_exit;
 
@@ -1439,7 +1470,7 @@ static int pl330_submit_req(struct pl330_thread *thrd,
 	/* Hook the request */
 	thrd->lstenq = idx;
 	thrd->req[idx].desc = desc;
-	_setup_req(0, thrd, idx, &xs);
+	_setup_req(pl330, 0, thrd, idx, &xs);
 
 	ret = 0;
 
@@ -2784,6 +2815,7 @@ pl330_probe(struct amba_device *adev, const struct amba_id *id)
 	struct resource *res;
 	int i, ret, irq;
 	int num_chan;
+	struct device_node *np = adev->dev.of_node;
 
 	pdat = dev_get_platdata(&adev->dev);
 
@@ -2803,6 +2835,11 @@ pl330_probe(struct amba_device *adev, const struct amba_id *id)
 
 	pl330->mcbufsz = pdat ? pdat->mcbuf_sz : 0;
 
+	/* get quirk */
+	for (i = 0; i < ARRAY_SIZE(of_quirks); i++)
+		if (of_property_read_bool(np, of_quirks[i].quirk))
+			pl330->quirks |= of_quirks[i].id;
+
 	res = &adev->res;
 	pl330->base = devm_ioremap_resource(&adev->dev, res);
 	if (IS_ERR(pl330->base))
-- 
2.3.7




From shawn.lin at rock-chips.com  Thu Aug 27 01:49:09 2015
From: shawn.lin at rock-chips.com (Shawn Lin)
Date: Thu, 27 Aug 2015 16:49:09 +0800
Subject: [PATCH 4/5] ARM: dts: Add broken-no-flushp quirk for rk3xxx platform
In-Reply-To: <1440665280-31557-1-git-send-email-shawn.lin@rock-chips.com>
References: <1440665280-31557-1-git-send-email-shawn.lin@rock-chips.com>
Message-ID: <1440665349-31729-1-git-send-email-shawn.lin@rock-chips.com>

Pl330 integrated in rk3xxx platform doesn't support
DMAFLUSHP function. So we add broken-no-flushp quirk
for it.

Signed-off-by: Shawn Lin <shawn.lin at rock-chips.com>
cc: Heiko Stuebner <heiko at sntech.de>
cc: Doug Anderson <dianders at chromium.org>
cc: Olof Johansson <olofj at google.com>
---

 arch/arm/boot/dts/rk3xxx.dtsi | 3 +++
 1 file changed, 3 insertions(+)

diff --git a/arch/arm/boot/dts/rk3xxx.dtsi b/arch/arm/boot/dts/rk3xxx.dtsi
index a2ae9f3..8bf9c71 100644
--- a/arch/arm/boot/dts/rk3xxx.dtsi
+++ b/arch/arm/boot/dts/rk3xxx.dtsi
@@ -79,6 +79,7 @@
 			#dma-cells = <1>;
 			clocks = <&cru ACLK_DMA1>;
 			clock-names = "apb_pclk";
+			broken-no-flushp;
 		};
 
 		dmac1_ns: dma-controller at 2001c000 {
@@ -89,6 +90,7 @@
 			#dma-cells = <1>;
 			clocks = <&cru ACLK_DMA1>;
 			clock-names = "apb_pclk";
+			broken-no-flushp;
 			status = "disabled";
 		};
 
@@ -100,6 +102,7 @@
 			#dma-cells = <1>;
 			clocks = <&cru ACLK_DMA2>;
 			clock-names = "apb_pclk";
+			broken-no-flushp;
 		};
 	};
 
-- 
2.3.7




From shawn.lin at rock-chips.com  Thu Aug 27 01:48:58 2015
From: shawn.lin at rock-chips.com (Shawn Lin)
Date: Thu, 27 Aug 2015 16:48:58 +0800
Subject: [PATCH 3/5] ARM: dts: Add broken-no-flushp quirk for rk3288 platform
In-Reply-To: <1440665280-31557-1-git-send-email-shawn.lin@rock-chips.com>
References: <1440665280-31557-1-git-send-email-shawn.lin@rock-chips.com>
Message-ID: <1440665338-31687-1-git-send-email-shawn.lin@rock-chips.com>

Pl330 integrated in rk3288 platform doesn't support
DMAFLUSHP function. So we add broken-no-flushp quirk
for it.

Signed-off-by: Addy Ke <addy.ke at rock-chips.com>
Signed-off-by: Shawn Lin <shawn.lin at rock-chips.com>
cc: Heiko Stuebner <heiko at sntech.de>
cc: Doug Anderson <dianders at chromium.org>
cc: Olof Johansson <olofj at google.com>
Reviewed-and-tested-by: Sonny Rao <sonnyrao at chromium.org>
---

 arch/arm/boot/dts/rk3288.dtsi | 3 +++
 1 file changed, 3 insertions(+)

diff --git a/arch/arm/boot/dts/rk3288.dtsi b/arch/arm/boot/dts/rk3288.dtsi
index 22316d0..c7ec98a 100644
--- a/arch/arm/boot/dts/rk3288.dtsi
+++ b/arch/arm/boot/dts/rk3288.dtsi
@@ -144,6 +144,7 @@
 			#dma-cells = <1>;
 			clocks = <&cru ACLK_DMAC2>;
 			clock-names = "apb_pclk";
+			broken-no-flushp;
 		};
 
 		dmac_bus_ns: dma-controller at ff600000 {
@@ -155,6 +156,7 @@
 			clocks = <&cru ACLK_DMAC1>;
 			clock-names = "apb_pclk";
 			status = "disabled";
+			broken-no-flushp;
 		};
 
 		dmac_bus_s: dma-controller at ffb20000 {
@@ -165,6 +167,7 @@
 			#dma-cells = <1>;
 			clocks = <&cru ACLK_DMAC1>;
 			clock-names = "apb_pclk";
+			broken-no-flushp;
 		};
 	};
 
-- 
2.3.7




From shawn.lin at rock-chips.com  Thu Aug 27 01:49:22 2015
From: shawn.lin at rock-chips.com (Shawn Lin)
Date: Thu, 27 Aug 2015 16:49:22 +0800
Subject: [PATCH 5/5] Documentation: arm-pl330: add description of
 broken-no-flushp
In-Reply-To: <1440665280-31557-1-git-send-email-shawn.lin@rock-chips.com>
References: <1440665280-31557-1-git-send-email-shawn.lin@rock-chips.com>
Message-ID: <1440665362-31771-1-git-send-email-shawn.lin@rock-chips.com>

Signed-off-by: Shawn Lin <shawn.lin at rock-chips.com>
---

 Documentation/devicetree/bindings/dma/arm-pl330.txt | 1 +
 1 file changed, 1 insertion(+)

diff --git a/Documentation/devicetree/bindings/dma/arm-pl330.txt b/Documentation/devicetree/bindings/dma/arm-pl330.txt
index 2675658..0f19268 100644
--- a/Documentation/devicetree/bindings/dma/arm-pl330.txt
+++ b/Documentation/devicetree/bindings/dma/arm-pl330.txt
@@ -15,6 +15,7 @@ Optional properties:
     cells in the dmas property of client device.
   - dma-channels: contains the total number of DMA channels supported by the DMAC
   - dma-requests: contains the total number of DMA requests supported by the DMAC
+  - broken-no-flushp: quirk for avoiding to execute DMAFLUSHP
 
 Example:
 
-- 
2.3.7




From linux at arm.linux.org.uk  Thu Aug 27 01:54:13 2015
From: linux at arm.linux.org.uk (Russell King - ARM Linux)
Date: Thu, 27 Aug 2015 09:54:13 +0100
Subject: [PATCH 04/12] gpu: imx: fix support for interlaced modes
In-Reply-To: <1440664752.3233.36.camel@pengutronix.de>
References: <20150808160251.GM7557@n2100.arm.linux.org.uk>
 <E1ZO6ay-0002qh-6E@rmk-PC.arm.linux.org.uk>
 <1440664752.3233.36.camel@pengutronix.de>
Message-ID: <20150827085411.GE21084@n2100.arm.linux.org.uk>

On Thu, Aug 27, 2015 at 10:39:12AM +0200, Philipp Zabel wrote:
> Hi Russell,
> 
> Am Samstag, den 08.08.2015, 17:03 +0100 schrieb Russell King:
> > The support for interlaced video modes seems to be broken; we don't use
> > anything other than the vtotal/htotal from the timing information to
> > define the various sync counters.
> 
> I finally made time to test this series:
> 
> Tested-by: Philipp Zabel <p.zabel at pengutronix.de>
> on i.MX6 GK802 via HDMI connected to a TV (1080p60, 1080i60).
> 
> Unfortunately these timings are completely different from what Freescale
> came up with for the TV Encoder on i.MX5, but the code we have currently
> in mainline doesn't work for that either. I suppose I'll follow up with
> a patch that adds yet another sync counter setup for the i.MX5/TVE case.
> 
> I'd like to take the two ipu-v3 patches, making a few small changes on
> this one:

Please don't split the series up.  The reason it's a series is because
there's interdependencies between the patches.

> > Freescale patches for interlaced video support contain an alternative
> > sync counter setup, which we include here.  This setup produces the
> > hsync and vsync via the normal counter 2 and 3, but moves the display
> > enable signal from counter 5 to counter 6.  Therefore, we need to
> > change the display controller setup as well.
> > 
> > The corresponding Freescale patches for this change are:
> >   iMX6-HDMI-support-interlaced-display-mode.patch
> >   IPU-fine-tuning-the-interlace-display-timing-for-CEA.patch
> > 
> > This produces a working interlace format output from the IPU.
> 
> ... on i.MX6 via HDMI.

It should also be correct for any other source which wants interlaced
output.

> > Signed-off-by: Russell King <rmk+kernel at arm.linux.org.uk>
> > ---
> >  drivers/gpu/ipu-v3/ipu-dc.c | 18 ++++++++---
> >  drivers/gpu/ipu-v3/ipu-di.c | 79 +++++++++++++++++++++------------------------
> >  2 files changed, 51 insertions(+), 46 deletions(-)
> > 
> > diff --git a/drivers/gpu/ipu-v3/ipu-dc.c b/drivers/gpu/ipu-v3/ipu-dc.c
> > index 9ef2e1f54ca4..aa560855c1dc 100644
> > --- a/drivers/gpu/ipu-v3/ipu-dc.c
> > +++ b/drivers/gpu/ipu-v3/ipu-dc.c
> > @@ -183,12 +183,22 @@ int ipu_dc_init_sync(struct ipu_dc *dc, struct ipu_di *di, bool interlaced,
> >  	}
> >  
> >  	if (interlaced) {
> > -		dc_link_event(dc, DC_EVT_NL, 0, 3);
> > -		dc_link_event(dc, DC_EVT_EOL, 0, 2);
> > -		dc_link_event(dc, DC_EVT_NEW_DATA, 0, 1);
> > +		int word, addr;
> > +
> > +		if (dc->di) {
> > +			addr = 1;
> > +			word = 1;
> 
> These two are really one and the same. The address written to the link
> register for the given event has to point to the address of the
> microcode instruction written to the template memory that should be
> executed on this event.
> 
> I'd like to drop the word variable and use addr for both.

Ok.  As I said in the commit message, this code comes from Freescale's
patches which I pointed to above.

> > +		} else {
> > +			addr = 0;
> > +			word = 0;
> > +		}
> > +
> > +		dc_link_event(dc, DC_EVT_NL, addr, 3);
> > +		dc_link_event(dc, DC_EVT_EOL, addr, 2);
> > +		dc_link_event(dc, DC_EVT_NEW_DATA, addr, 1);
> >  
> >  		/* Init template microcode */
> > -		dc_write_tmpl(dc, 0, WROD(0), 0, map, SYNC_WAVE, 0, 8, 1);
> > +		dc_write_tmpl(dc, word, WROD(0), 0, map, SYNC_WAVE, 0, 6, 1);
> >  	} else {
> >  		if (dc->di) {
> >  			dc_link_event(dc, DC_EVT_NL, 2, 3);
> > diff --git a/drivers/gpu/ipu-v3/ipu-di.c b/drivers/gpu/ipu-v3/ipu-di.c
> > index a96991c5c15f..359268e3a166 100644
> > --- a/drivers/gpu/ipu-v3/ipu-di.c
> > +++ b/drivers/gpu/ipu-v3/ipu-di.c
> > @@ -71,6 +71,10 @@ enum di_sync_wave {
> >  	DI_SYNC_HSYNC = 3,
> >  	DI_SYNC_VSYNC = 4,
> >  	DI_SYNC_DE = 6,
> > +
> > +	DI_SYNC_CNT1 = 2,	/* counter >= 2 only */
> > +	DI_SYNC_CNT4 = 5,	/* counter >= 5 only */
> > +	DI_SYNC_CNT5 = 6,	/* counter >= 6 only */
> >  };
> >  
> >  #define SYNC_WAVE 0
> > @@ -211,66 +215,59 @@ static void ipu_di_sync_config_interlaced(struct ipu_di *di,
> >  		sig->mode.hback_porch + sig->mode.hfront_porch;
> >  	u32 v_total = sig->mode.vactive + sig->mode.vsync_len +
> >  		sig->mode.vback_porch + sig->mode.vfront_porch;
> > -	u32 reg;
> >  	struct di_sync_config cfg[] = {
> >  		{
> > -			.run_count = h_total / 2 - 1,
> > -			.run_src = DI_SYNC_CLK,
> > +			/* 1: internal VSYNC for each frame */
> > +			.run_count = v_total * 2 - 1,
> > +			.run_src = 3,			/* == counter 7 */
> 
> Do you know why this works? The Reference Manual v2 lists that value as
> "NA" in the DI counter #1 Run Resolution field.

Yes, I noticed that Freescale were using values for the source fields
which were marked as NA in the manual.  As it works, I can only assume
that the engineer who came up with this setup has more knowledge than
is public.

> >  		}, {
> > -			.run_count = h_total - 11,
> > +			/* PIN2: HSYNC waveform */
> > +			.run_count = h_total - 1,
> >  			.run_src = DI_SYNC_CLK,
> > -			.cnt_down = 4,
> > +			.cnt_polarity_gen_en = 1,
> > +			.cnt_polarity_trigger_src = DI_SYNC_CLK,
> > +			.cnt_down = sig->mode.hsync_len * 2,
> >  		}, {
> > -			.run_count = v_total * 2 - 1,
> > -			.run_src = DI_SYNC_INT_HSYNC,
> > -			.offset_count = 1,
> > -			.offset_src = DI_SYNC_INT_HSYNC,
> > -			.cnt_down = 4,
> > +			/* PIN3: VSYNC waveform */
> > +			.run_count = v_total - 1,
> > +			.run_src = 4,			/* == counter 7 */
> 
> Same here, ...
> 
> > +			.cnt_polarity_gen_en = 1,
> > +			.cnt_polarity_trigger_src = 4,	/* == counter 7 */
> 
> ... and same here, the DI counter #3 polarity Clear select field lists
> the value 4 as "Reserved".
> 
> > +			.cnt_down = sig->mode.vsync_len * 2,
> > +			.cnt_clr_src = DI_SYNC_CNT1,
> >  		}, {
> [...]
> >  		}
> >  	};
> >  
> >  	ipu_di_sync_config(di, cfg, 0, ARRAY_SIZE(cfg));
> >  
> > -	/* set gentime select and tag sel */
> > -	reg = ipu_di_read(di, DI_SW_GEN1(9));
> > -	reg &= 0x1FFFFFFF;
> > -	reg |= (3 - 1) << 29 | 0x00008000;
> > -	ipu_di_write(di, reg, DI_SW_GEN1(9));
> 
> As far as I understood, attaching counter #9 to counter #3 is needed to
> generate the second vsync on i.MX5. Since this doesn't currently work,
> I'm fine with removing it for now.

I went through the counter setup to understand how it works, and it
seems correct provided you accept that the various source values do
work as the code claims, which includes creating the vsync at the
appropriate half-scanline position without needing this hack.

It's not easy to work back from the counter setup to get a mental
picture of what's going on, but it is possible to do so.

-- 
FTTC broadband for 0.8mile line: currently at 10.5Mbps down 400kbps up
according to speedtest.net.


From heiko at sntech.de  Thu Aug 27 01:57:12 2015
From: heiko at sntech.de (Heiko Stuebner)
Date: Thu, 27 Aug 2015 10:57:12 +0200
Subject: [PATCH 1/5] DMA: pl330: support burst mode for dev-to-mem and
 mem-to-dev transmit
In-Reply-To: <1440665313-31603-1-git-send-email-shawn.lin@rock-chips.com>
References: <1440665280-31557-1-git-send-email-shawn.lin@rock-chips.com>
 <1440665313-31603-1-git-send-email-shawn.lin@rock-chips.com>
Message-ID: <7170592.bdD8VT9GQ2@phil>

Hi Shawn,


you're loosing the original author. Your can override the patch-author (away 
from the mail sender) via a "From:" line at the top of the commit message, 
like:

------
From: Boojin Kim <boojin.kim at samsung.com>

This patch adds to support burst mode for dev-to-mem and
mem-to-dev transmit.
...
------


> This patch adds to support burst mode for dev-to-mem and
> mem-to-dev transmit.
> 
> Signed-off-by: Boojin Kim <boojin.kim at samsung.com>
> Signed-off-by: Addy Ke <addy.ke at rock-chips.com>
> Signed-off-by: Shawn Lin <shawn.lin at rock-chips.com>
> cc: Heiko Stuebner <heiko at sntech.de>
> cc: Doug Anderson <dianders at chromium.org>
> cc: Olof Johansson <olofj at google.com>
> Reviewed-and-tested-by: Sonny Rao <sonnyrao at chromium.org>
> 
> ---
> 
>  drivers/dma/pl330.c | 18 ++++++++++++------
>  1 file changed, 12 insertions(+), 6 deletions(-)
> 
> diff --git a/drivers/dma/pl330.c b/drivers/dma/pl330.c
> index ecab4ea0..0d544d2 100644
> --- a/drivers/dma/pl330.c
> +++ b/drivers/dma/pl330.c
> @@ -1141,10 +1141,13 @@ static inline int _ldst_devtomem(unsigned dry_run,
> u8 buf[], const struct _xfer_spec *pxs, int cyc)
>  {
>  	int off = 0;
> +	enum pl330_cond cond;
> +
> +	cond = (pxs->desc->rqcfg.brst_len == 1) ? SINGLE : BURST;
> 
>  	while (cyc--) {
> -		off += _emit_WFP(dry_run, &buf[off], SINGLE, pxs->desc->peri);
> -		off += _emit_LDP(dry_run, &buf[off], SINGLE, pxs->desc->peri);
> +		off += _emit_WFP(dry_run, &buf[off], cond, pxs->desc->peri);
> +		off += _emit_LDP(dry_run, &buf[off], cond, pxs->desc->peri);
>  		off += _emit_ST(dry_run, &buf[off], ALWAYS);
>  		off += _emit_FLUSHP(dry_run, &buf[off], pxs->desc->peri);
>  	}
> @@ -1156,11 +1159,14 @@ static inline int _ldst_memtodev(unsigned dry_run,
> u8 buf[], const struct _xfer_spec *pxs, int cyc)
>  {
>  	int off = 0;
> +	enum pl330_cond cond;
> +
> +	cond = (pxs->desc->rqcfg.brst_len == 1) ? SINGLE : BURST;
> 
>  	while (cyc--) {
> -		off += _emit_WFP(dry_run, &buf[off], SINGLE, pxs->desc->peri);
> +		off += _emit_WFP(dry_run, &buf[off], cond, pxs->desc->peri);
>  		off += _emit_LD(dry_run, &buf[off], ALWAYS);
> -		off += _emit_STP(dry_run, &buf[off], SINGLE, pxs->desc->peri);
> +		off += _emit_STP(dry_run, &buf[off], cond, pxs->desc->peri);
>  		off += _emit_FLUSHP(dry_run, &buf[off], pxs->desc->peri);
>  	}
> 
> @@ -2557,7 +2563,7 @@ static struct dma_async_tx_descriptor
> *pl330_prep_dma_cyclic(
> 
>  		desc->rqtype = direction;
>  		desc->rqcfg.brst_size = pch->burst_sz;
> -		desc->rqcfg.brst_len = 1;
> +		desc->rqcfg.brst_len = pch->burst_len;
>  		desc->bytes_requested = period_len;
>  		fill_px(&desc->px, dst, src, period_len);
> 
> @@ -2702,7 +2708,7 @@ pl330_prep_slave_sg(struct dma_chan *chan, struct
> scatterlist *sgl, }
> 
>  		desc->rqcfg.brst_size = pch->burst_sz;
> -		desc->rqcfg.brst_len = 1;
> +		desc->rqcfg.brst_len = pch->burst_len;
>  		desc->rqtype = direction;
>  		desc->bytes_requested = sg_dma_len(sg);
>  	}



From boris.brezillon at free-electrons.com  Thu Aug 27 02:30:35 2015
From: boris.brezillon at free-electrons.com (Boris Brezillon)
Date: Thu, 27 Aug 2015 11:30:35 +0200
Subject: [PATCH] clk: at91: add audio pll clock driver
In-Reply-To: <1438337864-27949-1-git-send-email-nicolas.ferre@atmel.com>
References: <1438337864-27949-1-git-send-email-nicolas.ferre@atmel.com>
Message-ID: <20150827113035.072cccb5@bbrezillon>

Hi Nicolas,

On Fri, 31 Jul 2015 12:17:44 +0200
Nicolas Ferre <nicolas.ferre at atmel.com> wrote:

> This new clock driver set allows to have a fractional divided clock
> that would generate a precise clock particularly suitable for
> audio applications.
> 
> The main audio pll clock has two children clocks: one that is connected
> to the PMC, the other that can directly drive a pad. As these two routes
> have different enable bits and different dividers and divider formula,
> they are handled by two different drivers.
> Each of them would modify the rate of the main audio pll parent.

Hm, not sure allowing both children to modify the parent clk rate is
a good idea, but let's see how it works.

> 
> Signed-off-by: Nicolas Ferre <nicolas.ferre at atmel.com>
> ---
>  .../devicetree/bindings/clock/at91-clock.txt       |  38 +++
>  drivers/clk/at91/Makefile                          |   2 +
>  drivers/clk/at91/clk-audio-pll-pad.c               | 220 +++++++++++++++++
>  drivers/clk/at91/clk-audio-pll-pmc.c               | 171 ++++++++++++++
>  drivers/clk/at91/clk-audio-pll.c                   | 261 +++++++++++++++++++++
>  drivers/clk/at91/pmc.c                             |  14 ++
>  drivers/clk/at91/pmc.h                             |   7 +
>  include/linux/clk/at91_pmc.h                       |  25 ++
>  8 files changed, 738 insertions(+)
>  create mode 100644 drivers/clk/at91/clk-audio-pll-pad.c
>  create mode 100644 drivers/clk/at91/clk-audio-pll-pmc.c
>  create mode 100644 drivers/clk/at91/clk-audio-pll.c
> 

[...]

> +
> +static int clk_audio_pll_compute_qdpad(unsigned long q_rate, unsigned long rate,
> +				       unsigned long *qd, u8 *div, u8 *ext_div)
> +{
> +	unsigned long tmp_qd;
> +	unsigned long rem2, rem3;
> +	unsigned long ldiv, lext_div;
> +
> +	if (!rate)
> +		return -EINVAL;
> +
> +	tmp_qd = q_rate / rate;
> +	if (!tmp_qd || tmp_qd > AUDIO_PLL_QDPAD_MAX)
> +		return -EINVAL;

Do you really want to return an error in this case?
I mean, you're calling this function from ->round_rate(), and
->round_rate() is supposed to find the closest rate, not to return an
error if the rate is too low or to high.
ITOH, you're calling the same function from ->set_rate(), which is
supposed to complain if the requested rate is not exactly met.

Maybe you can deal with that by passing an additional argument to this
function. Something like:

	tmp_qd = q_rate / rate;

	if (!strict) {
		if (!tmp_qd)
			tmp_qd = 1;
		else if (tmp_qd > AUDIO_PLL_QDPAD_MAX)
			tmp_qd = AUDIO_PLL_QDPAD_MAX;
	}

	if (!tmp_qd || tmp_qd > AUDIO_PLL_QDPAD_MAX)
		return -EINVAL;

> +
> +	if (tmp_qd <= AT91_PMC_AUDIO_PLL_QDPAD_EXTDIV_MAX) {
> +		ldiv = 1;
> +		lext_div = tmp_qd;
> +	} else {
> +		rem2 = tmp_qd % 2;
> +		rem3 = tmp_qd % 3;
> +
> +		if (rem3 == 0 ||
> +		    tmp_qd > AT91_PMC_AUDIO_PLL_QDPAD_EXTDIV_MAX * 2 ||
> +		    rem3 < rem2) {
> +			ldiv = 3;
> +			lext_div = tmp_qd / 3;
> +		} else {
> +			ldiv = 2;
> +			lext_div = tmp_qd >> 1;
> +		}
> +	}
> +
> +	pr_debug("A PLL/PAD: %s, qd = %lu (div = %lu, ext_div = %lu)\n",
> +		 __func__, ldiv * lext_div, ldiv, lext_div);
> +
> +	/* if we were given variable to store, we can provide them */
> +	if (qd)
> +		*qd = ldiv * lext_div;
> +	if (div && ext_div) {
> +		/* we can cast here as we verified the bounds just above */
> +		*div = (u8)ldiv;
> +		*ext_div = (u8)lext_div;
> +	}
> +
> +	return 0;
> +}
> +
> +static long clk_audio_pll_pad_round_rate(struct clk_hw *hw, unsigned long rate,
> +					 unsigned long *parent_rate)

I thought we were trying to get rid of the ->round_rate() function in
favor of the ->determine_rate() one (which is more flexible), but maybe
I'm wrong. Stephen, Mike, what's your opinion?

> +{
> +	struct clk *pclk = __clk_get_parent(hw->clk);
> +	long best_rate = -EINVAL;
> +	unsigned long best_parent_rate = 0;
> +	unsigned long tmp_qd;
> +
> +	pr_debug("A PLL/PAD: %s, rate = %lu (parent_rate = %lu)\n",
> +		 __func__, rate, *parent_rate);
> +
> +	if (clk_audio_pll_compute_qdpad(AUDIO_PLL_REFERENCE_FOUT, rate,
> +					&tmp_qd, NULL, NULL))
> +		return -EINVAL;

You're calculating your divisor based on the AUDIO_PLL_REFERENCE_FOUT
value...

> +
> +	best_parent_rate = __clk_round_rate(pclk, rate * tmp_qd);

... and then asking your parent to adapt its rate based on the returned
divisor. Wouldn't it be preferable to search for the best parent rate
when choosing the divisor?

> +	best_rate = best_parent_rate / tmp_qd;
> +
> +	pr_debug("A PLL/PAD: %s, best_rate = %ld, best_parent_rate = %lu\n",
> +		 __func__, best_rate, best_parent_rate);
> +
> +	*parent_rate = best_parent_rate;
> +	return best_rate;
> +}

[...]

> +
> +static long clk_audio_pll_pmc_round_rate(struct clk_hw *hw, unsigned long rate,
> +					 unsigned long *parent_rate)
> +{
> +	struct clk *pclk = __clk_get_parent(hw->clk);
> +	long best_rate = -EINVAL;
> +	unsigned long best_parent_rate = 0;
> +	unsigned long tmp_qd;
> +
> +	pr_debug("A PLL/PMC: %s, rate = %lu (parent_rate = %lu)\n",
> +		 __func__, rate, *parent_rate);
> +
> +	if (clk_audio_pll_compute_qdpmc(AUDIO_PLL_REFERENCE_FOUT, rate, &tmp_qd))
> +		return -EINVAL;
> +
> +	best_parent_rate = __clk_round_rate(pclk, rate * tmp_qd);

Ditto.

BTW, I'm not sure this is safe to allow both pll-audio children to
change their parent rate. What will happen if one of them change the
pll-audio rate while the other is still using it?

> +	best_rate = best_parent_rate / tmp_qd;
> +
> +	pr_debug("A PLL/PMC: %s, best_rate = %ld, best_parent_rate = %lu (qd = %lu)\n",
> +		 __func__, best_rate, best_parent_rate, tmp_qd - 1);
> +
> +	*parent_rate = best_parent_rate;
> +	return best_rate;
> +}

[...]

> +
> +#define to_clk_audio_frac(hw) container_of(hw, struct clk_audio_frac, hw)
> +
> +/* make sure that pll is in reset state beforehand */
> +static int clk_audio_pll_prepare(struct clk_hw *hw)
> +{
> +	struct clk_audio_frac *fck = to_clk_audio_frac(hw);
> +	struct at91_pmc *pmc = fck->pmc;
> +	u32 tmp;
> +
> +	pmc_lock(pmc);
> +	tmp = pmc_read(pmc, AT91_PMC_AUDIO_PLL0) & ~AT91_PMC_AUDIO_PLL_RESETN;
> +	pmc_write(pmc, AT91_PMC_AUDIO_PLL0, tmp);
> +	pmc_unlock(pmc);

Nothing sleeps in this code, so you could move everything in your
->enable() function.

> +	return 0;
> +}
> +
> +static void clk_audio_pll_unprepare(struct clk_hw *hw)
> +{
> +	clk_audio_pll_prepare(hw);

Ditto.

Best Regards,

Boris

-- 
Boris Brezillon, Free Electrons
Embedded Linux and Kernel engineering
http://free-electrons.com


From will.deacon at arm.com  Thu Aug 27 02:32:28 2015
From: will.deacon at arm.com (Will Deacon)
Date: Thu, 27 Aug 2015 10:32:28 +0100
Subject: [PATCH v2] arm64/efi: base UEFI mapping permissions on region
 attributes
In-Reply-To: <1440595802-20359-1-git-send-email-ard.biesheuvel@linaro.org>
References: <1440595802-20359-1-git-send-email-ard.biesheuvel@linaro.org>
Message-ID: <20150827093228.GA23520@arm.com>

Hi Ard,

On Wed, Aug 26, 2015 at 02:30:02PM +0100, Ard Biesheuvel wrote:
> Currently, we infer the UEFI memory region mapping permissions
> from the memory region type (i.e., runtime services code are
> mapped RWX and runtime services data mapped RW-). This appears to
> work fine but is not entirely UEFI spec compliant. So instead, use
> the designated permission attributes to decide how these regions
> should be mapped.
> 
> Since UEFIv2.5 introduces a new EFI_MEMORY_RO permission attribute,
> and redefines EFI_MEMORY_WP as a cacheability attribute, use only
> the former as a read-only attribute. For setting the PXN bit, the
> corresponding EFI_MEMORY_XP attribute is used.
> 
> Signed-off-by: Ard Biesheuvel <ard.biesheuvel at linaro.org>
> ---
> Changes since v1:
> - rewrote page size and alignment check to be more legible
> - use code that is STRICT_MM_TYPECHECKS compliant
> 
> Example output of a recent Tianocore build on FVP Foundation model
> is attached below.
> 
>  arch/arm64/kernel/efi.c | 37 +++++++++++++-------
>  1 file changed, 24 insertions(+), 13 deletions(-)
> 
> diff --git a/arch/arm64/kernel/efi.c b/arch/arm64/kernel/efi.c
> index ab21e0d58278..c8d587f46f3e 100644
> --- a/arch/arm64/kernel/efi.c
> +++ b/arch/arm64/kernel/efi.c
> @@ -235,7 +235,7 @@ static bool __init efi_virtmap_init(void)
>  
>  	for_each_efi_memory_desc(&memmap, md) {
>  		u64 paddr, npages, size;
> -		pgprot_t prot;
> +		pteval_t prot_val;
>  
>  		if (!(md->attribute & EFI_MEMORY_RUNTIME))
>  			continue;
> @@ -247,22 +247,33 @@ static bool __init efi_virtmap_init(void)
>  		memrange_efi_to_native(&paddr, &npages);
>  		size = npages << PAGE_SHIFT;
>  
> -		pr_info("  EFI remap 0x%016llx => %p\n",
> -			md->phys_addr, (void *)md->virt_addr);
> +		if (!is_normal_ram(md))
> +			prot_val = PROT_DEVICE_nGnRE;
> +		else
> +			prot_val = pgprot_val(PAGE_KERNEL_EXEC);
>  
>  		/*
> -		 * Only regions of type EFI_RUNTIME_SERVICES_CODE need to be
> -		 * executable, everything else can be mapped with the XN bits
> -		 * set.
> +		 * On 64 KB granule kernels, only use strict permissions when
> +		 * the region does not share a 64 KB page frame with another
> +		 * region at either end.
>  		 */
> -		if (!is_normal_ram(md))
> -			prot = __pgprot(PROT_DEVICE_nGnRE);
> -		else if (md->type == EFI_RUNTIME_SERVICES_CODE)
> -			prot = PAGE_KERNEL_EXEC;
> -		else
> -			prot = PAGE_KERNEL;
> +		if (PAGE_SIZE == EFI_PAGE_SIZE ||
> +		    (PAGE_ALIGNED(md->virt_addr) &&
> +		     PAGE_ALIGNED(md->phys_addr + md->num_pages * EFI_PAGE_SIZE))) {

Why do you use virt_addr instead of phys_addr for the base check?

Will


From p.zabel at pengutronix.de  Thu Aug 27 02:40:30 2015
From: p.zabel at pengutronix.de (Philipp Zabel)
Date: Thu, 27 Aug 2015 11:40:30 +0200
Subject: [PATCH 04/12] gpu: imx: fix support for interlaced modes
In-Reply-To: <20150827085411.GE21084@n2100.arm.linux.org.uk>
References: <20150808160251.GM7557@n2100.arm.linux.org.uk>
 <E1ZO6ay-0002qh-6E@rmk-PC.arm.linux.org.uk>
 <1440664752.3233.36.camel@pengutronix.de>
 <20150827085411.GE21084@n2100.arm.linux.org.uk>
Message-ID: <1440668430.3233.68.camel@pengutronix.de>

Am Donnerstag, den 27.08.2015, 09:54 +0100 schrieb Russell King - ARM
Linux:
> On Thu, Aug 27, 2015 at 10:39:12AM +0200, Philipp Zabel wrote:
> > Hi Russell,
> > 
> > Am Samstag, den 08.08.2015, 17:03 +0100 schrieb Russell King:
> > > The support for interlaced video modes seems to be broken; we don't use
> > > anything other than the vtotal/htotal from the timing information to
> > > define the various sync counters.
> > 
> > I finally made time to test this series:
> > 
> > Tested-by: Philipp Zabel <p.zabel at pengutronix.de>
> > on i.MX6 GK802 via HDMI connected to a TV (1080p60, 1080i60).
> > 
> > Unfortunately these timings are completely different from what Freescale
> > came up with for the TV Encoder on i.MX5, but the code we have currently
> > in mainline doesn't work for that either. I suppose I'll follow up with
> > a patch that adds yet another sync counter setup for the i.MX5/TVE case.
> > 
> > I'd like to take the two ipu-v3 patches, making a few small changes on
> > this one:
> 
> Please don't split the series up.  The reason it's a series is because
> there's interdependencies between the patches.

In that case, can I take the whole series? Or would you like to respin
and have my Acked-by: Philipp Zabel <p.zabel at pengutronix.de> with the
changes below:

> > > Freescale patches for interlaced video support contain an alternative
> > > sync counter setup, which we include here.  This setup produces the
> > > hsync and vsync via the normal counter 2 and 3, but moves the display
> > > enable signal from counter 5 to counter 6.  Therefore, we need to
> > > change the display controller setup as well.
> > > 
> > > The corresponding Freescale patches for this change are:
> > >   iMX6-HDMI-support-interlaced-display-mode.patch
> > >   IPU-fine-tuning-the-interlace-display-timing-for-CEA.patch
> > > 
> > > This produces a working interlace format output from the IPU.
> > 
> > ... on i.MX6 via HDMI.
> 
> It should also be correct for any other source which wants interlaced
> output.

... on i.MX6, then. Right now I don't know what is the effect of the
undocumented settings on the i.MX5's IPUv3M.

> > > Signed-off-by: Russell King <rmk+kernel at arm.linux.org.uk>
> > > ---
> > >  drivers/gpu/ipu-v3/ipu-dc.c | 18 ++++++++---
> > >  drivers/gpu/ipu-v3/ipu-di.c | 79 +++++++++++++++++++++------------------------
> > >  2 files changed, 51 insertions(+), 46 deletions(-)
> > > 
> > > diff --git a/drivers/gpu/ipu-v3/ipu-dc.c b/drivers/gpu/ipu-v3/ipu-dc.c
> > > index 9ef2e1f54ca4..aa560855c1dc 100644
> > > --- a/drivers/gpu/ipu-v3/ipu-dc.c
> > > +++ b/drivers/gpu/ipu-v3/ipu-dc.c
> > > @@ -183,12 +183,22 @@ int ipu_dc_init_sync(struct ipu_dc *dc, struct ipu_di *di, bool interlaced,
> > >  	}
> > >  
> > >  	if (interlaced) {
> > > -		dc_link_event(dc, DC_EVT_NL, 0, 3);
> > > -		dc_link_event(dc, DC_EVT_EOL, 0, 2);
> > > -		dc_link_event(dc, DC_EVT_NEW_DATA, 0, 1);
> > > +		int word, addr;
> > > +
> > > +		if (dc->di) {
> > > +			addr = 1;
> > > +			word = 1;
> > 
> > These two are really one and the same. The address written to the link
> > register for the given event has to point to the address of the
> > microcode instruction written to the template memory that should be
> > executed on this event.
> > 
> > I'd like to drop the word variable and use addr for both.
> 
> Ok.  As I said in the commit message, this code comes from Freescale's
> patches which I pointed to above.
[...]
> > > @@ -211,66 +215,59 @@ static void ipu_di_sync_config_interlaced(struct ipu_di *di,
> > >  		sig->mode.hback_porch + sig->mode.hfront_porch;
> > >  	u32 v_total = sig->mode.vactive + sig->mode.vsync_len +
> > >  		sig->mode.vback_porch + sig->mode.vfront_porch;
> > > -	u32 reg;
> > >  	struct di_sync_config cfg[] = {
> > >  		{
> > > -			.run_count = h_total / 2 - 1,
> > > -			.run_src = DI_SYNC_CLK,
> > > +			/* 1: internal VSYNC for each frame */
> > > +			.run_count = v_total * 2 - 1,
> > > +			.run_src = 3,			/* == counter 7 */
> > 
> > Do you know why this works? The Reference Manual v2 lists that value as
> > "NA" in the DI counter #1 Run Resolution field.
> 
> Yes, I noticed that Freescale were using values for the source fields
> which were marked as NA in the manual.  As it works, I can only assume
> that the engineer who came up with this setup has more knowledge than
> is public.

I'd like small a comment here that yes, we know this is marked as
NA/Reserved in the manuals.

[...]
> I went through the counter setup to understand how it works, and it
> seems correct provided you accept that the various source values do
> work as the code claims, which includes creating the vsync at the
> appropriate half-scanline position without needing this hack.
> 
> It's not easy to work back from the counter setup to get a mental
> picture of what's going on, but it is possible to do so.

Yes, being able to actually reference counters with higher numbers makes
things a lot easier to follow.

regards
Philipp



From liguozhu at hisilicon.com  Thu Aug 27 02:50:35 2015
From: liguozhu at hisilicon.com (Kenneth Lee)
Date: Thu, 27 Aug 2015 17:50:35 +0800
Subject: =?utf-8?B?562U5aSNOiBbUEFUQ0ggMS81XSBu?= =?utf-8?Q?et=3A_ad?=
 =?utf-8?Q?d?= Hisilicon Network Subsystem support (config and documents)
In-Reply-To: <2543796.7JthO5WCfI@wuerfel>
References: <1439548222-231611-1-git-send-email-liguozhu@hisilicon.com>
 <1536926.jEJjsM70Lj@wuerfel>
 <161EFA05D917D0419F95C4CAEEF86C1094E95FAA@SZXEMA504-MBS.china.huawei.com>
 <2543796.7JthO5WCfI@wuerfel>
Message-ID: <20150827095035.GB26498@Turing-Arch-b>

On Fri, Aug 21, 2015 at 04:00:35PM +0200, Arnd Bergmann wrote:
> Date: Fri, 21 Aug 2015 16:00:35 +0200
> From: Arnd Bergmann <arnd at arndb.de>
> To: "Liguozhu (Kenneth)" <liguozhu at hisilicon.com>
> CC: "mark.rutland at arm.com" <mark.rutland at arm.com>,
>  "devicetree at vger.kernel.org" <devicetree at vger.kernel.org>,
>  "pawel.moll at arm.com" <pawel.moll at arm.com>, "ijc+devicetree at hellion.org.uk"
>  <ijc+devicetree at hellion.org.uk>, "catalin.marinas at arm.com"
>  <catalin.marinas at arm.com>, "will.deacon at arm.com" <will.deacon at arm.com>,
>  "linux-kernel at vger.kernel.org" <linux-kernel at vger.kernel.org>, Linuxarm
>  <linuxarm at huawei.com>, "paul.gortmaker at windriver.com"
>  <paul.gortmaker at windriver.com>, "robh+dt at kernel.org" <robh+dt at kernel.org>,
>  "galak at codeaurora.org" <galak at codeaurora.org>, "zhangfei.gao at linaro.org"
>  <zhangfei.gao at linaro.org>, "netdev at vger.kernel.org"
>  <netdev at vger.kernel.org>, "davem at davemloft.net" <davem at davemloft.net>,
>  "linux-arm-kernel at lists.infradead.org"
>  <linux-arm-kernel at lists.infradead.org>
> Subject: Re: ??: [PATCH 1/5] net: add Hisilicon Network Subsystem
>  support (config and documents)
> User-Agent: KMail/4.11.5 (Linux/3.16.0-10-generic; KDE/4.11.5; x86_64; ; )
> Message-ID: <2543796.7JthO5WCfI at wuerfel>
> 
> On Monday 17 August 2015 01:28:07 Liguozhu wrote:
> > Thanks, Arnd. 
> > 
> > Regarding the ae-name: it is the name of the Acceleration Engine. It is provided
> > by the BIOS according to the position and the feature enabled of the IP.
> > So "soc0" means it is on SoC No. 0, while "n4" means it is running on 
> >"Non-dsaf mode 4". Ideally, we should setup the rule to name it. But as I
> > said in the patchset, the IP is original designed for a bare metal solution,
> > it is worthless to export all modes and we are planning to add more mode
> > for Linux itself in the IP in future version. So I think the better way is
> > to leave it as a "name" but add more meaning in the future.
> 
> The name property is a bit awkward. The position is normally implied by
> the location of the parent device in the DT, so you should not need that
> at all and instead derive it elsewhere. You can also add strings to the
> compatible property instead of this, to signify differences in the programming
> that are based on how the IP block is used.
>  
> > Regarding the ae-opts: it is the initial value for the AE's runtime options,
> > Currently, we have only "port number" (there are 6XGE+2GE port for a DSAF AE)
> > as option. But for future version, we will add other options such as "enable
> > Spanning Tree Protocol algorithm)" and so on. 
> 
> I think these can easily be converted into an index property and boolean
> flags (present if true, absent otherwise) for additional features.
>  
> > Should I add these background to somewhere?
> 
> The binding document needs to list all supported configurations, if you
> have a string property, describe specifically what strings are allowed
> and what they mean, but better try to avoid strings altogether.
> 
> 	Arnd
> _______________________________________________
> linuxarm mailing list
> linuxarm at huawei.com
> http://rnd-openeuler.huawei.com/mailman/listinfo/linuxarm

Dear Arnd,

We are working on the new PatchSet. I describe the new design here so in case
you can tell us if we make something wrong.

So now we will keep some attributes in enthernet node like this:

	ethernet at 0{
		compatible = "hisilicon,hns-nic";
		ae-name = "dsaf1";
		port-id = <0>;
	};

ae-name is simply a name referring to the name of dsa_name in SAF node.

port-id is the index of port provided by DSAF (the accelerator). DSAF can
connect to 8 PHYs. Port 0 to 1 are both used for adminstration purpose. They
are called debug ports. 

The remaining 6 PHYs are taken according to the mode of DSAF.

In NIC mode of DSAF, all 6 PHYs are taken as ethernet ports to the CPU. The
port-id can be 2 to 7. Here is the diagram:

            +-----+---------------+
            |            CPU      |
            +-+-+-+---+-+-+-+-+-+-+
              | |     | | | | | |
	     debug       service 
             port         port
	     (0,1)       (2-7)

In Switch mode of DSAF, all 6 PHYs are taken as physical ports connect to a
LAN Switch while the CPU side assume itself have one single NIC connect to
this switch. In this case, the port-id will be 2 only.

            +-----+---------------+
            |            CPU      |
            +-+-+-+---+-+-+-+-+-+-+
              | |         | service port(2)
	     debug   +------------+
             port    |   switch   |
             (0,1)   +-+-+-+-+-+-++
                       | | | | | |
                        external
			 port


-- 
			-Kenneth(Hisilicon)


From marcel.ziswiler at toradex.com  Thu Aug 27 02:44:48 2015
From: marcel.ziswiler at toradex.com (Marcel Ziswiler)
Date: Thu, 27 Aug 2015 11:44:48 +0200
Subject: [PATCH] arm: tegra: dtsi whitespace clean-up for tegra20,
 tegra30 and tegra124
Message-ID: <1440668688-17288-1-git-send-email-marcel.ziswiler@toradex.com>

There were a few cases of eight spaces being used instead of a tab
character plus one case of using two spaces after an equal sign instead
of just one which this patch fixes.

Signed-off-by: Marcel Ziswiler <marcel.ziswiler at toradex.com>
---

 arch/arm/boot/dts/tegra124.dtsi |  2 +-
 arch/arm/boot/dts/tegra20.dtsi  |  4 ++--
 arch/arm/boot/dts/tegra30.dtsi  | 10 +++++-----
 3 files changed, 8 insertions(+), 8 deletions(-)

diff --git a/arch/arm/boot/dts/tegra124.dtsi b/arch/arm/boot/dts/tegra124.dtsi
index 1e204a6..a5c878e 100644
--- a/arch/arm/boot/dts/tegra124.dtsi
+++ b/arch/arm/boot/dts/tegra124.dtsi
@@ -636,7 +636,7 @@
 		reg = <0x0 0x70030000 0x0 0x10000>;
 		interrupts = <GIC_SPI 81 IRQ_TYPE_LEVEL_HIGH>;
 		clocks = <&tegra_car TEGRA124_CLK_HDA>,
-		         <&tegra_car TEGRA124_CLK_HDA2HDMI>,
+			 <&tegra_car TEGRA124_CLK_HDA2HDMI>,
 			 <&tegra_car TEGRA124_CLK_HDA2CODEC_2X>;
 		clock-names = "hda", "hda2hdmi", "hda2codec_2x";
 		resets = <&tegra_car 125>, /* hda */
diff --git a/arch/arm/boot/dts/tegra20.dtsi b/arch/arm/boot/dts/tegra20.dtsi
index e058709..0a8d1a6 100644
--- a/arch/arm/boot/dts/tegra20.dtsi
+++ b/arch/arm/boot/dts/tegra20.dtsi
@@ -601,8 +601,8 @@
 			 <&tegra_car TEGRA20_CLK_PLL_E>;
 		clock-names = "pex", "afi", "pll_e";
 		resets = <&tegra_car 70>,
-		         <&tegra_car 72>,
-		         <&tegra_car 74>;
+			 <&tegra_car 72>,
+			 <&tegra_car 74>;
 		reset-names = "pex", "afi", "pcie_x";
 		status = "disabled";
 
diff --git a/arch/arm/boot/dts/tegra30.dtsi b/arch/arm/boot/dts/tegra30.dtsi
index fe04fb5..38e1e27 100644
--- a/arch/arm/boot/dts/tegra30.dtsi
+++ b/arch/arm/boot/dts/tegra30.dtsi
@@ -42,8 +42,8 @@
 			 <&tegra_car TEGRA30_CLK_CML0>;
 		clock-names = "pex", "afi", "pll_e", "cml";
 		resets = <&tegra_car 70>,
-		         <&tegra_car 72>,
-		         <&tegra_car 74>;
+			 <&tegra_car 72>,
+			 <&tegra_car 74>;
 		reset-names = "pex", "afi", "pcie_x";
 		status = "disabled";
 
@@ -153,7 +153,7 @@
 				  &tegra_car TEGRA30_CLK_GR3D2>;
 			clock-names = "3d", "3d2";
 			resets = <&tegra_car 24>,
-			         <&tegra_car 98>;
+				 <&tegra_car 98>;
 			reset-names = "3d", "3d2";
 		};
 
@@ -455,7 +455,7 @@
 	};
 
 	i2c at 7000c000 {
-		compatible =  "nvidia,tegra30-i2c", "nvidia,tegra20-i2c";
+		compatible = "nvidia,tegra30-i2c", "nvidia,tegra20-i2c";
 		reg = <0x7000c000 0x100>;
 		interrupts = <GIC_SPI 38 IRQ_TYPE_LEVEL_HIGH>;
 		#address-cells = <1>;
@@ -660,7 +660,7 @@
 		reg = <0x70030000 0x10000>;
 		interrupts = <GIC_SPI 81 IRQ_TYPE_LEVEL_HIGH>;
 		clocks = <&tegra_car TEGRA30_CLK_HDA>,
-		         <&tegra_car TEGRA30_CLK_HDA2HDMI>,
+			 <&tegra_car TEGRA30_CLK_HDA2HDMI>,
 			 <&tegra_car TEGRA30_CLK_HDA2CODEC_2X>;
 		clock-names = "hda", "hda2hdmi", "hda2codec_2x";
 		resets = <&tegra_car 125>, /* hda */
-- 
2.4.3



From lorenzo.pieralisi at arm.com  Thu Aug 27 02:50:26 2015
From: lorenzo.pieralisi at arm.com (Lorenzo Pieralisi)
Date: Thu, 27 Aug 2015 10:50:26 +0100
Subject: [PATCH] ARM64: kernel: implement ACPI parking protocol
In-Reply-To: <1440616402.13044.16.camel@redhat.com>
References: <1436959990-32054-1-git-send-email-lorenzo.pieralisi@arm.com>
 <1437063431.3583.2.camel@redhat.com>
 <20150716171221.GB18582@red-moon>
 <1437068449.3583.4.camel@redhat.com>
 <20150826160716.GB11863@red-moon>
 <1440616402.13044.16.camel@redhat.com>
Message-ID: <20150827095026.GB21134@red-moon>

On Wed, Aug 26, 2015 at 08:13:22PM +0100, Mark Salter wrote:
> On Wed, 2015-08-26 at 17:07 +0100, Lorenzo Pieralisi wrote:
> > Mark,
> > 
> > On Thu, Jul 16, 2015 at 06:40:49PM +0100, Mark Salter wrote:
> > 
> > [...]
> > 
> > > > > The kernel will only add cached memory regions to linear mapping 
> > > > > and
> > > > > presumably, the FW will mark the mailboxes as uncached. Otherwise, 
> > > > > it
> > > > > is a FW bug. But I suppose we could run into problems with kernels
> > > > > using 64K pagesize since firmware assumes 4k.
> > > > 
> > > > Nope, ioremap takes care of that, everything should be fine.
> > > 
> > > The mailbox is 4K. If it is next to a cached UEFI region, the kernel 
> > > may
> > > have to overlap the mailbox with a cached 64K mapping in order to 
> > > include
> > > the adjoining UEFI region in the linear map. Then the ioremap would 
> > > fail
> > > because the mailbox is included in the linear mapping.
> > 
> > You have to acknowledge that what you describe is a bit of a corner
> > case (and a silly FW set-up), are you aware of any existing FW set-up
> > where we actually hit the corner case above ?
> 
> Oh sure. It could definitely be a corner case. I'm not aware of any
> existing firmware supporting the protocol implemented by your patch.

So basically there is no existing firmware implementing the ARM64 ACPI
parking protocol.

> So time will tell how well firmware vendors which do implement it
> avoid the corner case problem. I am aware of some existing firmwares
> which put the mailbox area in RAM which is also in the kernel linear
> mapping as cached memory. But those wouldn't work with your patch for
> more reasons than that.

They will have to fix them, that's the reason why I am pushing this
patch upstream, and not a version that is massaged to make their
non-compliant firmware compliant.

> > I think it is fine to leave code as-is, at least the mailbox
> > mappings, I will check to see I can improve the MADT parsing,
> > somehow.
> 
> I'm not strenuously opposed to leaving it as-is. But we need to
> acknowledge that if the 64K pagesize issue isn't covered by the
> protocol spec, we're relying on firmware vendors to be diligent
> not to break 64K pagesize kernels.

Should we try to amend the protocol spec ? I will raise the point,
I do not see how we can prevent this issue otherwise, other than
relying on vendors to be aware of the issue and prevent it.

Thanks,
Lorenzo


From cyrille.pitchen at atmel.com  Thu Aug 27 02:51:57 2015
From: cyrille.pitchen at atmel.com (Cyrille Pitchen)
Date: Thu, 27 Aug 2015 11:51:57 +0200
Subject: [PATCH linux-next v5 1/5] mtd: spi-nor: notify (Q)SPI controller
 about protocol change
In-Reply-To: <CAOiHx=n+byfsbJNhnboqDEwhruOT8uKDJ+CcES7QBqPDLVAMsw@mail.gmail.com>
References: <cover.1440580764.git.cyrille.pitchen@atmel.com>
 <464fce12d75a5ba2105456cfd0a385b2d40305ba.1440580764.git.cyrille.pitchen@atmel.com>
 <CAOiHx=n+byfsbJNhnboqDEwhruOT8uKDJ+CcES7QBqPDLVAMsw@mail.gmail.com>
Message-ID: <55DEDDBD.8060408@atmel.com>

Hi Jonas,

Le 26/08/2015 16:02, Jonas Gorski a ?crit :
> On Wed, Aug 26, 2015 at 2:30 PM, Cyrille Pitchen
> <cyrille.pitchen at atmel.com> wrote:
>> Once the Quad SPI mode has been enabled on a Micron flash memory, this
>> device expects ALL the following commands to use the SPI 4-4-4 protocol.
>> The (Q)SPI controller needs to be notified about the protocol change so it
>> can adapt and keep on dialoging with the Micron memory.
> 
> Doesn't that mean you need to disable quad mode on removal? Else the
> following will break/fail:
> 
> insmod atmel-quadspi.ko ~> spi-nor attaches -> sees micron -> enables quad mode
> rmmod atmel-quadspi.ko ~> spi-nor detaches
> insmod atmel-quadspi.ko ~> spi-nor attaches -> fails to read the id
> because flash is still in quad mode.
>

Indeed you're right such an issue does exist. So as you said one solution
could be create a new function to "clean" what have been done by spi_nor_scan()
then call it from remove() function of each driver calling spi_nor_scan() from
its probe().
However we could also enhance the probing of the memory. It is true that Micron
spi nor memories only accept SPI 4-4-4 commands once switched in quad mode but
actually they also provide a new command for this purpose:
"Multiple I/O Read ID" (0xAF).
Hence we could first try to probe using the regular Read ID (0x9F) command then
change the protocol, for instance to SPI 4-4-4, and try the 0xAF command.
I don't think all combinations for command/protocol need to be tested: for
Micron memories, their datasheets claim the 0x9F command is only supported in
"extended spi mode" so for the SPI 1-1-1 protocol whereas the 0xAF command
only works in dual or quad modes.
On the other hand Spansion memories still reply to the regular 0x9F command in
SPI 1-1-1 protocol even after their quad mode had been enabled.
For other manufacturers, well... I don't know!

Some of the advantages of the probe solution as compared to the remove one are:
- we don't need to patch all drivers using spi_nor_scan() to call a new
  function from their remove().
- it doesn't rely on the assumption that the spi-nor memory starts in
  SPI 1-1-1 protocol. As a matter of fact the remove() won't be called for
  built-in modules or in many (all ?) cases of reset. Moreover some bootloaders
  may have already enabled the quad mode before starting the Linux kernel. This
  is what the sama5d2 romcode does when it is configured to boot from a QSPI
  memory.

Anyway you're right and the issue need to be addressed but maybe in another
dedicated patch ?
 
>> Signed-off-by: Cyrille Pitchen <cyrille.pitchen at atmel.com>
>> Acked-by: Marek Vasut <marex at denx.de>
>> Acked-by: Bean Huo <beanhuo at micron.com>
>> ---
>>  drivers/mtd/spi-nor/spi-nor.c | 21 +++++++++++++++++++++
>>  include/linux/mtd/spi-nor.h   | 13 +++++++++++++
>>  2 files changed, 34 insertions(+)
>>
>> diff --git a/drivers/mtd/spi-nor/spi-nor.c b/drivers/mtd/spi-nor/spi-nor.c
>> index c27d427fead4..c8810313a752 100644
>> --- a/drivers/mtd/spi-nor/spi-nor.c
>> +++ b/drivers/mtd/spi-nor/spi-nor.c
>> @@ -165,6 +165,22 @@ static inline int write_disable(struct spi_nor *nor)
>>         return nor->write_reg(nor, SPINOR_OP_WRDI, NULL, 0, 0);
>>  }
>>
>> +/*
>> + * Let the spi-nor framework notify lower layers, especially the driver of the
>> + * (Q)SPI controller, about the new protocol to be used. Indeed, once the
>> + * spi-nor framework has sent manufacturer specific commands to a memory to
>> + * enable its Quad SPI mode, it should immediately after tell the QSPI
>> + * controller to use the very same Quad SPI protocol as expected by the memory.
>> + */
>> +static inline int spi_nor_set_protocol(struct spi_nor *nor,
>> +                                      enum spi_protocol proto)
>> +{
>> +       if (nor->set_protocol)
>> +               return nor->set_protocol(nor, proto);
>> +
>> +       return 0;
> 
> Shouldn't the default assumption be that it won't support it? Also it
> might make sense to first check if it's supported before enabling it
> in the chip, so that we don't enable something just to then find out
> we can't back out of it.
> 
> I also wonder if we need an extra flag for that as at least SPI has
> RX_{DUAL,QUAD} and TX_{DUAL,QUAD} separated, so in theory there could
> be a controller that supports quad read, but not quad write, so we
> shouldn't be using the quad mode in that case. m25p80 currently sets
> SPI_NOR_{DUAL,QUAD} only based on SPI_RX_{DUAL,QUAD}, so that would
> then fail.
> 
> At least the n25q32 seems to support the "boring" 1_1_2 and 1_1_4
> commands, so these should work in case the spi controller does not
> support quad tx, but quad rx.
> 
> So maybe an additional flag for the "full" dual/quad modes would be in order.
> 

My first thought was to return -ENOSYS when the set_protocol() callback is not
implemented but logically none of the already existing drivers implements it.
So I made this new callback optional. This way, micron_quad_enable() works the
exact same way as before for all the existing drivers so no regression or side-
effect should be introduced by this patch.

Besides, the purpose of this callback is to notify the SPI controller that the
protocol change has been done at the memory side but not to decide whether such
a change is possible. Indeed, the capabilities of both the controller and the
memory are checked before calling set_quad_mode() so the decision has already
been taken when micron_quad_enable() is eventually called. Once the Quad Mode
bit set in the Enhanced Volatile Configuration Register of Micron memory, it's
too late: the memory now expects commands in SPI 4-4-4 protocol whether or not
the controller supports this protocol.

So more accurate checks should be done before calling set_quad_mode(). Maybe
the range of values for the mode parameter of spi_nor_scan() is too small.
SPI_NOR_QUAD doesn't allow to make the difference between SPI protocols 1-1-4,
1-4-4 or 4-4-4. Knowing the exact set of protocols supported by both the
controller and the memory could help making the right decision and choosing the
best suited Fast Read command.
The RX_{DUAL_QUAD} and TX_{DUAL,QUAD} flags from the spi->mode in the m25p80
driver provide more information than the limited "mode" argument of
spi_nor_scan().

> Last but not least, the protocol probably should be stored somewhere
> in the nor struct, so that users don't have to store it themselves (I
> assume they will need to check it for each command again to know if
> the cmd/address should be send in serial or quad mode).
> 
> 
I agree with you, this could be an improvement for some spi controller drivers :)

> Jonas
> 

thanks for your review!

Best regards,

Cyrille


From broonie at kernel.org  Thu Aug 27 03:06:41 2015
From: broonie at kernel.org (Mark Brown)
Date: Thu, 27 Aug 2015 11:06:41 +0100
Subject: [PATCH] regmap: Fix the null function of format_val on
 regmap_bulk_read.
In-Reply-To: <20150827054925.GK706@pengutronix.de>
References: <1440589396-696-1-git-send-email-henryc.chen@mediatek.com>
 <20150826123556.GB2977@sirena.org.uk>
 <20150826132246.GR706@pengutronix.de>
 <20150826173812.GA28760@sirena.org.uk>
 <20150827054925.GK706@pengutronix.de>
Message-ID: <20150827100641.GA5313@sirena.org.uk>

On Thu, Aug 27, 2015 at 07:49:25AM +0200, Markus Pargmann wrote:
> On Wed, Aug 26, 2015 at 06:38:12PM +0100, Mark Brown wrote:
> > On Wed, Aug 26, 2015 at 03:22:46PM +0200, Markus Pargmann wrote:

> > > The regmap_bulk_read() function worked before the following patch:
> > > 	15b8d2c41fe5 (regmap: Fix regmap_bulk_read in BE mode)

> > Define "worked" here.

> "worked" means here that it did not run into a null pointer and returned
> something that the user expected. I am not sure if someone actually
> complained about the previous use of memcpy? I also don't know how the
> behavior of regmap_bulk_read with reg_read() is defined.

Which basically boils down to hacked something that happened to work
with the current implementation but wasn't obviously coherent - this is 
part of the problem, the interface just happened so hasn't been thought
through.  It's not clear that defining the bit sizes at all without any
formatting makes sense, if anything I would have been expecting arrays
of unsigned integers to be being passed around since that's how we store
unformatted values in regmap.

Using memcpy() worries me because we are using memcpy() to move a value
that isn't an unsigned long out of an unsigned long and I can't convince
myself that this will be safe on big endian systems.  If we are going to
keep using the val_bits word size then we're going to need to rewrite
the values.
-------------- next part --------------
A non-text attachment was scrubbed...
Name: signature.asc
Type: application/pgp-signature
Size: 473 bytes
Desc: Digital signature
URL: <http://lists.infradead.org/pipermail/linux-arm-kernel/attachments/20150827/b16c5f24/attachment.sig>

From marcel.ziswiler at toradex.com  Thu Aug 27 03:10:55 2015
From: marcel.ziswiler at toradex.com (Marcel Ziswiler)
Date: Thu, 27 Aug 2015 12:10:55 +0200
Subject: [PATCH] arm: tegra: update default configuration
Message-ID: <1440670255-19437-1-git-send-email-marcel.ziswiler@toradex.com>

  * Expose hardware/virtual IRQ mapping via debugfs
  * WM9712 audio/touch controller as found on Colibri T20
  * sysfs interface for GPIOs
  * NFS client support for NFS version 4

Signed-off-by: Marcel Ziswiler <marcel.ziswiler at toradex.com>
---

 arch/arm/configs/tegra_defconfig | 8 ++++++++
 1 file changed, 8 insertions(+)

diff --git a/arch/arm/configs/tegra_defconfig b/arch/arm/configs/tegra_defconfig
index 9808581..6645460 100644
--- a/arch/arm/configs/tegra_defconfig
+++ b/arch/arm/configs/tegra_defconfig
@@ -1,5 +1,6 @@
 CONFIG_SYSVIPC=y
 CONFIG_FHANDLE=y
+CONFIG_IRQ_DOMAIN_DEBUG=y
 CONFIG_NO_HZ=y
 CONFIG_HIGH_RES_TIMERS=y
 CONFIG_IKCONFIG=y
@@ -121,6 +122,9 @@ CONFIG_KEYBOARD_CROS_EC=y
 CONFIG_MOUSE_PS2_ELANTECH=y
 CONFIG_INPUT_TOUCHSCREEN=y
 CONFIG_TOUCHSCREEN_ATMEL_MXT=y
+CONFIG_TOUCHSCREEN_WM97XX=y
+# CONFIG_TOUCHSCREEN_WM9705 is not set
+# CONFIG_TOUCHSCREEN_WM9713 is not set
 CONFIG_TOUCHSCREEN_STMPE=y
 CONFIG_INPUT_MISC=y
 CONFIG_INPUT_MPU3050=y
@@ -142,11 +146,13 @@ CONFIG_SPI_TEGRA20_SFLASH=y
 CONFIG_SPI_TEGRA20_SLINK=y
 CONFIG_PINCTRL_AS3722=y
 CONFIG_PINCTRL_PALMAS=y
+CONFIG_GPIO_SYSFS=y
 CONFIG_GPIO_PCA953X=y
 CONFIG_GPIO_PCA953X_IRQ=y
 CONFIG_GPIO_PALMAS=y
 CONFIG_GPIO_TPS6586X=y
 CONFIG_GPIO_TPS65910=y
+CONFIG_BATTERY_WM97XX=y
 CONFIG_BATTERY_SBS=y
 CONFIG_CHARGER_TPS65090=y
 CONFIG_POWER_RESET=y
@@ -208,6 +214,7 @@ CONFIG_SND_SOC_TEGRA=y
 CONFIG_SND_SOC_TEGRA_RT5640=y
 CONFIG_SND_SOC_TEGRA_WM8753=y
 CONFIG_SND_SOC_TEGRA_WM8903=y
+CONFIG_SND_SOC_TEGRA_WM9712=y
 CONFIG_SND_SOC_TEGRA_TRIMSLICE=y
 CONFIG_SND_SOC_TEGRA_ALC5632=y
 CONFIG_SND_SOC_TEGRA_MAX98090=y
@@ -278,6 +285,7 @@ CONFIG_SQUASHFS=y
 CONFIG_SQUASHFS_LZO=y
 CONFIG_SQUASHFS_XZ=y
 CONFIG_NFS_FS=y
+CONFIG_NFS_V4=y
 CONFIG_ROOT_NFS=y
 CONFIG_NLS_CODEPAGE_437=y
 CONFIG_NLS_ISO8859_1=y
-- 
2.4.3



From jteki at openedev.com  Thu Aug 27 03:15:43 2015
From: jteki at openedev.com (Jagan Teki)
Date: Thu, 27 Aug 2015 15:45:43 +0530
Subject: [LINUX RFC v2 0/4] spi: add dual parallel mode support in Zynq
 MPSoC GQSPI controller
In-Reply-To: <CAGnW=BZ80B_2kzZVULhZvEXFs+_GXkGbu8mii1eFp3MySvA8aA@mail.gmail.com>
References: <1440570367-22569-1-git-send-email-ranjit.waghmode@xilinx.com>
 <CAD6G_RQhWBsUTZNBB44W98Fjzw82H_D_E9nY0aDWezj729mkoA@mail.gmail.com>
 <CAGnW=BZtsVtT+Z7gTq5jybXsHWp+RNpjc6ckk6-MXWxAS7u8Mw@mail.gmail.com>
 <CAD6G_RTCQ5Fzjgxz+-3oMDAyUTg6UFAqvpEPQzJ9maSTZ3Nc_g@mail.gmail.com>
 <CAGnW=BZ80B_2kzZVULhZvEXFs+_GXkGbu8mii1eFp3MySvA8aA@mail.gmail.com>
Message-ID: <CAD6G_RR+QnuK++KvztYo+68sb7yQqwM7qg-X7bybCYaBN+nAGQ@mail.gmail.com>

On 27 August 2015 at 14:18, punnaiah choudary kalluri
<punnaia at xilinx.com> wrote:
> On Thu, Aug 27, 2015 at 11:53 AM, Jagan Teki <jteki at openedev.com> wrote:
>> On 26 August 2015 at 21:02, punnaiah choudary kalluri
>> <punnaia at xilinx.com> wrote:
>>> On Wed, Aug 26, 2015 at 5:49 PM, Jagan Teki <jteki at openedev.com> wrote:
>>>> On 26 August 2015 at 11:56, Ranjit Waghmode <ranjit.waghmode at xilinx.com> wrote:
>>>>> This series adds dual parallel mode support for Zynq Ultrascale+
>>>>> MPSoC GQSPI controller driver.
>>>>>
>>>>> What is dual parallel mode?
>>>>> ---------------------------
>>>>> ZynqMP GQSPI controller supports Dual Parallel mode with following functionalities:
>>>>> 1) Supporting two SPI flash memories operating in parallel. 8 I/O lines.
>>>>> 2) Chip selects and clock are shared to both the flash devices
>>>>> 3) This mode is targeted for faster read/write speed and also doubles the size
>>>>> 4) Commands/data can be transmitted/received from both the devices(mirror),
>>>>>    or only upper or only lower flash memory devices.
>>>>> 5) Data arrangement:
>>>>>    With stripe enabled,
>>>>>    Even bytes i.e. 0, 2, 4,... are transmitted on Lower Data Bus
>>>>>    Odd bytes i.e. 1, 3, 5,.. are transmitted on Upper Data Bus.
> <snip>
>>>> I don't find any previous discussion about way to inform flash
>>>> dual-ness into spi-nor
>>>> from spi drivers.
>>>>
>>>> Here is my idea, probably others may think same.
>>>> Informing dual_flash from drivers/spi through flags or any other mode
>>>> bits is not a better approach as dual flash feature is specific to
>>>> spi-nor flash controller (controller specially designed for spi-nor
>>>> flash not the generic spi controller).  So if the driver sits on
>>>> drivers/mtd/spi-nor/ (ex: fsl-quadspi.c), may be we can inform flash
>>>> specific things to spi-nor as it's not touching generic spi stack in
>>>> Linux. But there is a defined-drawback if the driver is moved to
>>>> drivers/mtd/spi-nor ie it can't use spi core API's at-all.
>>>
>>> Xilinx GQSPI is a generic quad spi controller. The primary goal is to support
>>> Generic/Future command sequences and Future NOR/NAND flash devices.
>>> This core can also be used for legacy SPI devices. Due to the generic nature
>>> of the core, software can generate any command sequence. It also has additional
>>> features like parallel and stacked configurations to double the data
>>> rate and size.
>>> Accessing spi-nor flash device is one particular use case and like
>>> that there will be
>>> many. So, we decided to keep this driver in generic spi framework and
>>> that is the ideal
>>> thing to do for the GQSPI controller.
>>
>> Yes, I understand the generic nature of the GQSPI and it's good to
>> have all-in-one like generic spi, spi-nor and spi-nand and more
>> together, but Linux stacks were implemented in such a way to support
>> the each type of controller with connected slaves separably for better
>> handling.
>
> True and this is the reason we have controller drivers and protocol drivers.
> GQSPI is the controller driver and spi-nor and spi-nand are the
> protocol drivers.
>
>>
>> Currently GQSPI driver is added in drivers/spi as it supports generic
>> spi nature and now it enhanced more through flags for supporting
>> spi-nor, what if we add spi-nand support for the same controller? do
>> we add one more driver in spi-nand framework (drivers/mtd/spi-nand -
>> an on going implementation)? My only observation here is even if the
>> controller is more generic to support more number of device classes,
>> and adding same driver and populate the slave stuff through flags or
>> different kind of mechanism to different driver stack, this is not a
>> better approach I thought.
>
> Just to clear, dual parallel( 2 CS and 8 IO lines) is not only specific
> to flash parts, one can use for any other custom streaming protocols
> I would say exporting dual parallel connection to protocol drivers is
> something like depicting the spi bus topology to the protocol layer.

So dual parallel may not used for spi-nor flash it can also used other
spi slaves that's what your saying is it?

>
> AFAIK, spi-nor and spi-nand are protocol drivers for accessing the
> nor and nand flash devices sitting on the spi bus using the spi
> controller driver.

Yes, I do agree with your point, but though driver stacks are
different with same kind of bus here, I'm trying to spit the GQSPI
into 3 different controller drivers as Linux understand it and fit on
to Linux stack with out disturbing the generic-ness.

Assumption is GQSPI shall split to various platform_drivers (if each
platform driver treated as a controller) thought it made up of  spi
bus.

>>
>> Based on the above comments, there is an approach to handle this
>> support and I'm not 100% sure whether this fits or not but we
>> implemented the same -  this is "probing child devices from parent"
>> (there was a discussion with Arnd earlier wrt this, but I'm unable to
>> get the mailing thread)
>>
>> Added Arnd (probably will give more inputs or corrections)
>>
>> Let me explain how we implemented on our design.
>> We have PCIe controller that support basic root complex handling, dma
>> and controller hotplug (not in-build pcie hp) and ideally we need to
>> write driver for handling root complex on drivers/pci/host and one
>> hotplug driver in drivers/pci and one more driver in drivers/dma for
>> handling pcie dma stuff. And some pcie calls need to navigate from
>> root complex driver to dma and hotplug driver that means there is call
>> transition from driver/pci to driver/dma which is absolutely not a
>> good approach (spi to spi-nor and spi-nand transition - in GQSPI case)
>>
>> So the implementation we follow is like there is a pcie root complex
>> driver(probably generic spi driver in drivers/spi/*) and inside probe
>> we have register platform_device for hotplug (spi-nor) and dma
>> (spi-nand) and the dma driver in drivers/dma and hotplug driver in
>> driver/pci/ are platform drivers which is of legacy binding (not with
>> dts) so there should be a common dts for root complex driver
>> (drivers/spi/*) and individual child driver need to take those while
>> registering platform_device.
>>
>> example pseudo:
>>
>> drivers/dma/dma-child2.c
>>
>> Legacy platform_driver binding and handling dma future as normal dma
>> driver, spi-nand in your case
>>
>> drivers/pci/hotplug/hp-child1.c
>>
>> Legacy platform_driver binding and handling hotplug future as normal
>> hotplug driver, spi-nor in your case.
>>
>> drivers/pci/host/rc-parent-pci.c
>>
>> static int rc_parent_pcie_probe_bridge(struct platform_device *pdev)
>> {
>>    // Generic rc handling (genric spi stuff)
>>
>>    // Hotplug handling (spi-nor)
>>    - platform_device_alloc
>>    - assign need resources
>>    - register pdev using platform_device_add
>>
>>     // DMA handling (spi-nand)
>>    - same as above
>> }
>>
>> static const struct of_device_id rc_parent_pcie_match_table[] = {
>>         {.compatible = "abc,rc-parent",},
>>         {},
>> };
>>
>> static struct platform_driver rc_parent_pcie_driver = {
>>         .driver = {
>>                    .name = "rc-parent",
>>                    .of_match_table = of_match_ptr(rc_parent_pcie_match_table),
>>         },
>>         .probe = rc_parent_pcie_probe_bridge,
>> };
>> module_platform_driver(rc_parent_pcie_driver);
>>
>> I couldn't find any driver mainlined wrt this design, think more on
>> GQSPI front, whether this design fits well or not.

thanks!
-- 
Jagan | openedev.


From javier at osg.samsung.com  Thu Aug 27 03:34:32 2015
From: javier at osg.samsung.com (Javier Martinez Canillas)
Date: Thu, 27 Aug 2015 12:34:32 +0200
Subject: [PATCH] rtc: Fix module autoload for rtc-{ab8500, max8997,
 s5m} drivers
Message-ID: <1440671672-26590-1-git-send-email-javier@osg.samsung.com>

These platform drivers have a platform device ID table but the module
alias information is not created so module autoloading will not work.

Signed-off-by: Javier Martinez Canillas <javier at osg.samsung.com>

---

 drivers/rtc/rtc-ab8500.c  | 1 +
 drivers/rtc/rtc-max8997.c | 1 +
 drivers/rtc/rtc-s5m.c     | 1 +
 3 files changed, 3 insertions(+)

diff --git a/drivers/rtc/rtc-ab8500.c b/drivers/rtc/rtc-ab8500.c
index 133d2e2e1a25..8537d1e3a995 100644
--- a/drivers/rtc/rtc-ab8500.c
+++ b/drivers/rtc/rtc-ab8500.c
@@ -446,6 +446,7 @@ static const struct platform_device_id ab85xx_rtc_ids[] = {
 	{ "ab8500-rtc", (kernel_ulong_t)&ab8500_rtc_ops, },
 	{ "ab8540-rtc", (kernel_ulong_t)&ab8540_rtc_ops, },
 };
+MODULE_DEVICE_TABLE(platform, ab85xx_rtc_ids);
 
 static int ab8500_rtc_probe(struct platform_device *pdev)
 {
diff --git a/drivers/rtc/rtc-max8997.c b/drivers/rtc/rtc-max8997.c
index 9e02bcda0c09..db984d4bf952 100644
--- a/drivers/rtc/rtc-max8997.c
+++ b/drivers/rtc/rtc-max8997.c
@@ -521,6 +521,7 @@ static const struct platform_device_id rtc_id[] = {
 	{ "max8997-rtc", 0 },
 	{},
 };
+MODULE_DEVICE_TABLE(platform, rtc_id);
 
 static struct platform_driver max8997_rtc_driver = {
 	.driver		= {
diff --git a/drivers/rtc/rtc-s5m.c b/drivers/rtc/rtc-s5m.c
index ab60287ee72d..f2504b4eef34 100644
--- a/drivers/rtc/rtc-s5m.c
+++ b/drivers/rtc/rtc-s5m.c
@@ -807,6 +807,7 @@ static const struct platform_device_id s5m_rtc_id[] = {
 	{ "s2mps14-rtc",	S2MPS14X },
 	{ },
 };
+MODULE_DEVICE_TABLE(platform, s5m_rtc_id);
 
 static struct platform_driver s5m_rtc_driver = {
 	.driver		= {
-- 
2.4.3



From lee at kernel.org  Thu Aug 27 03:48:54 2015
From: lee at kernel.org (Lee Jones)
Date: Thu, 27 Aug 2015 11:48:54 +0100
Subject: [PATCH v5 3/3] ARM: bcm2835: Add DT for the firmware clocks
 driver.
In-Reply-To: <55CEBC6B.9070001@wwwdotorg.org>
References: <1439507142-2965-1-git-send-email-eric@anholt.net>
 <1439507142-2965-4-git-send-email-eric@anholt.net>
 <55CEBC6B.9070001@wwwdotorg.org>
Message-ID: <20150827104854.GA4796@x1>

On Fri, 14 Aug 2015, Stephen Warren wrote:

> On 08/13/2015 05:05 PM, Eric Anholt wrote:
> > Signed-off-by: Eric Anholt <eric at anholt.net>
> > Acked-by: Lee Jones <lee at kernel.org>
> 
> A patch description might be nice, although admittedly the subject seems
> clear enough.

Agreed that the subject is clear enough on this occasion.

> > diff --git a/arch/arm/boot/dts/bcm2835-rpi.dtsi b/arch/arm/boot/dts/bcm2835-rpi.dtsi
> 
> > +		firmware_clocks: firmware-clocks {
> > +			compatible = "raspberrypi,bcm2835-firmware-clocks";
> > +			#clock-cells = <1>;
> > +			raspberrypi,firmware = <&firmware>;
> > +		};
> 
> No need to resend for this, but just a background note: DT node names
> usually contain a device type not a device identity, so "clocks" not
> "firmware-clocks" would be typical.

Please fix this up when you re-send the set.

> This patch,
> Acked-by: Stephen Warren <swarren at wwwdotorg.org>


From shawn.lin at rock-chips.com  Thu Aug 27 04:05:04 2015
From: shawn.lin at rock-chips.com (Shawn Lin)
Date: Thu, 27 Aug 2015 19:05:04 +0800
Subject: [PATCH 1/5] DMA: pl330: support burst mode for dev-to-mem and
 mem-to-dev transmit
In-Reply-To: <7170592.bdD8VT9GQ2@phil>
References: <1440665280-31557-1-git-send-email-shawn.lin@rock-chips.com>
 <1440665313-31603-1-git-send-email-shawn.lin@rock-chips.com>
 <7170592.bdD8VT9GQ2@phil>
Message-ID: <55DEEEE0.4060208@rock-chips.com>

On 2015/8/27 16:57, Heiko Stuebner wrote:
> Hi Shawn,
>
>
> you're loosing the original author. Your can override the patch-author (away
> from the mail sender) via a "From:" line at the top of the commit message,
> like:
>

Woops.... sorry for missing this bit. Thanks for pointing out that. :)

Patch 1 is from Boojin, and patch 2,3 attribute to Addy(Actually I 
rebase it for linux-next from v3.14). patch 4 and 5 comes from myself.

It will be fixed from the next ones if any.

> ------
> From: Boojin Kim <boojin.kim at samsung.com>
>
> This patch adds to support burst mode for dev-to-mem and
> mem-to-dev transmit.
> ...
> ------
>
>
>> This patch adds to support burst mode for dev-to-mem and
>> mem-to-dev transmit.
>>
>> Signed-off-by: Boojin Kim <boojin.kim at samsung.com>
>> Signed-off-by: Addy Ke <addy.ke at rock-chips.com>
>> Signed-off-by: Shawn Lin <shawn.lin at rock-chips.com>
>> cc: Heiko Stuebner <heiko at sntech.de>
>> cc: Doug Anderson <dianders at chromium.org>
>> cc: Olof Johansson <olofj at google.com>
>> Reviewed-and-tested-by: Sonny Rao <sonnyrao at chromium.org>
>>
>> ---
>>
>>   drivers/dma/pl330.c | 18 ++++++++++++------
>>   1 file changed, 12 insertions(+), 6 deletions(-)
>>
>> diff --git a/drivers/dma/pl330.c b/drivers/dma/pl330.c
>> index ecab4ea0..0d544d2 100644
>> --- a/drivers/dma/pl330.c
>> +++ b/drivers/dma/pl330.c
>> @@ -1141,10 +1141,13 @@ static inline int _ldst_devtomem(unsigned dry_run,
>> u8 buf[], const struct _xfer_spec *pxs, int cyc)
>>   {
>>   	int off = 0;
>> +	enum pl330_cond cond;
>> +
>> +	cond = (pxs->desc->rqcfg.brst_len == 1) ? SINGLE : BURST;
>>
>>   	while (cyc--) {
>> -		off += _emit_WFP(dry_run, &buf[off], SINGLE, pxs->desc->peri);
>> -		off += _emit_LDP(dry_run, &buf[off], SINGLE, pxs->desc->peri);
>> +		off += _emit_WFP(dry_run, &buf[off], cond, pxs->desc->peri);
>> +		off += _emit_LDP(dry_run, &buf[off], cond, pxs->desc->peri);
>>   		off += _emit_ST(dry_run, &buf[off], ALWAYS);
>>   		off += _emit_FLUSHP(dry_run, &buf[off], pxs->desc->peri);
>>   	}
>> @@ -1156,11 +1159,14 @@ static inline int _ldst_memtodev(unsigned dry_run,
>> u8 buf[], const struct _xfer_spec *pxs, int cyc)
>>   {
>>   	int off = 0;
>> +	enum pl330_cond cond;
>> +
>> +	cond = (pxs->desc->rqcfg.brst_len == 1) ? SINGLE : BURST;
>>
>>   	while (cyc--) {
>> -		off += _emit_WFP(dry_run, &buf[off], SINGLE, pxs->desc->peri);
>> +		off += _emit_WFP(dry_run, &buf[off], cond, pxs->desc->peri);
>>   		off += _emit_LD(dry_run, &buf[off], ALWAYS);
>> -		off += _emit_STP(dry_run, &buf[off], SINGLE, pxs->desc->peri);
>> +		off += _emit_STP(dry_run, &buf[off], cond, pxs->desc->peri);
>>   		off += _emit_FLUSHP(dry_run, &buf[off], pxs->desc->peri);
>>   	}
>>
>> @@ -2557,7 +2563,7 @@ static struct dma_async_tx_descriptor
>> *pl330_prep_dma_cyclic(
>>
>>   		desc->rqtype = direction;
>>   		desc->rqcfg.brst_size = pch->burst_sz;
>> -		desc->rqcfg.brst_len = 1;
>> +		desc->rqcfg.brst_len = pch->burst_len;
>>   		desc->bytes_requested = period_len;
>>   		fill_px(&desc->px, dst, src, period_len);
>>
>> @@ -2702,7 +2708,7 @@ pl330_prep_slave_sg(struct dma_chan *chan, struct
>> scatterlist *sgl, }
>>
>>   		desc->rqcfg.brst_size = pch->burst_sz;
>> -		desc->rqcfg.brst_len = 1;
>> +		desc->rqcfg.brst_len = pch->burst_len;
>>   		desc->rqtype = direction;
>>   		desc->bytes_requested = sg_dma_len(sg);
>>   	}
>
>
>
>


-- 
Best Regards
Shawn Lin



From lee at kernel.org  Thu Aug 27 04:10:46 2015
From: lee at kernel.org (Lee Jones)
Date: Thu, 27 Aug 2015 12:10:46 +0100
Subject: [GIT PULL] RPi DT changes due for v4.3
In-Reply-To: <878u9dhggh.fsf@eliezer.anholt.net>
References: <20150811160642.GQ18282@x1> <20150813103056.GY30160@localhost>
 <878u9dhggh.fsf@eliezer.anholt.net>
Message-ID: <20150827111046.GB4796@x1>

On Fri, 14 Aug 2015, Eric Anholt wrote:
> Olof Johansson <olof at lixom.net> writes:
> > On Tue, Aug 11, 2015 at 05:06:42PM +0100, Lee Jones wrote:
> >> ARM SoC Chaps,
> >> 
> >> Please find a couple of simple RPi changes pertaining to Firmware.
> >> 
> >> The following changes since commit bc0195aad0daa2ad5b0d76cce22b167bc3435590:
> >> 
> >>   Linux 4.2-rc2 (2015-07-12 15:10:30 -0700)
> >> 
> >> are available in the git repository at:
> >> 
> >>   git://git.kernel.org/pub/scm/linux/kernel/git/rpi/linux-rpi.git tags/rpi-dt-for-armsoc-4.3
> >> 
> >> for you to fetch changes up to fd26f8830979de48eb3f1c253eb9d2ee2e468eb6:
> >> 
> >>   dt/bindings: Add binding for the Raspberry Pi firmware driver (2015-08-11 16:56:41 +0100)
> >
> > I've merged this but I'm a little confused about bcm2835 maintainership:
> > I got a MAINTAINERS update from Florian earlier grouped in a set of
> > other bcm changes (adding Eric), and now this directly from you.
> >
> > In general the bcm platforms are quite diverse and we've asked Florian
> > to be the funnel for all of the new ones, but I don't think we talked
> > much about 2835 at that time. Should we expect to see merges directly
> > from you and the other maintainers there or will it go through Florian?
> 
> I'd been talking with Arnd and Florian about the delays in RPi patch
> acceptance (Stephen and Lee have limited time to dedicate to 2835), and
> Florian suggested me becoming a maintainer and routing patches through
> him.  He's been great to work with and has had useful feedback on my
> patches.
> 
> I was kind of surprised to see Lee send this pull request -- these
> patches had been sitting un-merged for 2 months and pings on irc didn't
> get replies, so I thought I was stepping in where the others definitely
> didn't have time.  It was also odd to see just these two patches, but
> not the actual driver.
> 
> I'm willing to do the merging process for 2835, and if I'm doing so, I
> like the idea of feeding it through a more experienced maintainer who's
> ready to look at my pull requests whenever, without bothering the main
> arm-soc folks.  My goal here, besides my actual job of getting open
> source graphics working for Broadcom, is to hopefully push the rpi
> foundation toward getting their code merged, so that this hardware fully
> works on stock upstream.

Apologies for the confusion caused by this pull-request.  After
speaking with Florian last cycle the plan was to send the request to
him prior to him sending to ARM-SoC; however, I didn't realise how
early in the cycle he was going to send that request and I missed the
boat.  So rather than miss the cycle, I decided just to send directly
to ARM-SoC instead.

I do resent the IRQ comment though, as I'm always on IRC during
working hours and (unless something has gone wrong) I have a proxy
which collects missed messages and replays them back to me, so in
theory I shouldn't miss a message.  All messages you've sent to me
I've replied to.

The Firmware patches wouldn't have ever been part of this set without
explicit request/permission from the Maintainer.  So that's why the
driver patches weren't part of this set.

How would you like to move forward?  Do you still want me to apply
patches to the RPi repo and send Florian a pull-request early in the
cycle (say -rc4 for example), or would you rather Florian picked the
patches form the list directly?


From bharat.kumar.gogada at xilinx.com  Thu Aug 27 04:44:20 2015
From: bharat.kumar.gogada at xilinx.com (Bharat Kumar Gogada)
Date: Thu, 27 Aug 2015 17:14:20 +0530
Subject: [PATCH] PCI: Xilinx-NWL-PCIe: Added support for Xilinx NWL PCIe Host
 Controller
Message-ID: <1440675860-21491-1-git-send-email-bharatku@xilinx.com>

Adding PCIe Root Port driver for Xilinx PCIe NWL bridge IP.

Signed-off-by: Bharat Kumar Gogada <bharatku at xilinx.com>
Signed-off-by: Ravi Kiran Gummaluri <rgummal at xilinx.com>
---
 .../devicetree/bindings/pci/xilinx-nwl-pcie.txt    |   39 +
 drivers/pci/host/Kconfig                           |    9 +
 drivers/pci/host/Makefile                          |    1 +
 drivers/pci/host/pci-xilinx-nwl.c                  | 1038 ++++++++++++++++++++
 4 files changed, 1087 insertions(+), 0 deletions(-)
 create mode 100644 Documentation/devicetree/bindings/pci/xilinx-nwl-pcie.txt
 create mode 100644 drivers/pci/host/pci-xilinx-nwl.c

diff --git a/Documentation/devicetree/bindings/pci/xilinx-nwl-pcie.txt b/Documentation/devicetree/bindings/pci/xilinx-nwl-pcie.txt
new file mode 100644
index 0000000..c554d6b
--- /dev/null
+++ b/Documentation/devicetree/bindings/pci/xilinx-nwl-pcie.txt
@@ -0,0 +1,39 @@
+* Xilinx NWL PCIe Root Port Bridge DT description
+
+Required properties:
+- compatible: Should contain "xlnx,nwl-pcie-2.11"
+- #address-cells: Address representation for root ports, set to <3>
+- #size-cells: Size representation for root ports, set to <2>
+- #interrupt-cells: specifies the number of cells needed to encode an
+	interrupt source. The value must be 1.
+- reg: Should contain Bridge, PCIe Controller registers location and length
+- device_type: must be "pci"
+- interrupts: Should contain NWL PCIe interrupt
+- ranges: ranges for the PCI memory regions (I/O space region is not
+	supported by hardware)
+	Please refer to the standard PCI bus binding document for a more
+	detailed explanation
+
+Optional properties:
+- xlnx,msi-fifo: To enable MSI FIFO mode
+
+Example:
+++++++++
+nwl_pcie: pcie at fd0e0000 {
+	compatible = "xlnx,nwl-pcie-2.11";
+	#address-cells = <3>;
+	#size-cells = <2>;
+	#interrupt-cells = <1>;
+	device_type = "pci";
+	interrupt-parent = <&gic>;
+	interrupts = < 0 118 4
+		       0 116 4
+		       0 115 4		// MSI_1 [63...32]
+		       0 114 4 >;	// MSI_0 [31...0]
+	interrupt-names = "misc", "intx", "msi_1", "msi_0";
+	reg = <0x0 0xfd0e0000 0x1000
+	       0x0 0xfd480000 0x1000
+	       0x0 0xE0000000 0x1000000>;
+	reg-names = "breg", "pcireg", "cfg";
+	ranges = <0x02000000 0x00000000 0xE1000000 0x00000000 0xE1000000 0 0x0F000000>;
+};
diff --git a/drivers/pci/host/Kconfig b/drivers/pci/host/Kconfig
index c132bdd..5ff4e7e 100644
--- a/drivers/pci/host/Kconfig
+++ b/drivers/pci/host/Kconfig
@@ -15,6 +15,15 @@ config PCI_MVEBU
	depends on ARCH_MVEBU || ARCH_DOVE
	depends on OF

+config PCI_XILINX_NWL
+	bool "NWL PCIe Core"
+	depends on ARCH_ZYNQMP && PCI_MSI
+	help
+	 Say 'Y' here if you want kernel to support for Xilinx
+	 NWL PCIe controller.The controller can act as Root Port
+	 or End Point.The current option selection will only
+	 support root port enabling.
+
 config PCIE_DW
	bool

diff --git a/drivers/pci/host/Makefile b/drivers/pci/host/Makefile
index 140d66f..0f3a789 100644
--- a/drivers/pci/host/Makefile
+++ b/drivers/pci/host/Makefile
@@ -10,6 +10,7 @@ obj-$(CONFIG_PCI_HOST_GENERIC) += pci-host-generic.o
 obj-$(CONFIG_PCIE_SPEAR13XX) += pcie-spear13xx.o
 obj-$(CONFIG_PCI_KEYSTONE) += pci-keystone-dw.o pci-keystone.o
 obj-$(CONFIG_PCIE_XILINX) += pcie-xilinx.o
+obj-$(CONFIG_PCI_XILINX_NWL) += pci-xilinx-nwl.o
 obj-$(CONFIG_PCI_XGENE) += pci-xgene.o
 obj-$(CONFIG_PCI_XGENE_MSI) += pci-xgene-msi.o
 obj-$(CONFIG_PCI_LAYERSCAPE) += pci-layerscape.o
diff --git a/drivers/pci/host/pci-xilinx-nwl.c b/drivers/pci/host/pci-xilinx-nwl.c
new file mode 100644
index 0000000..6c2fa80
--- /dev/null
+++ b/drivers/pci/host/pci-xilinx-nwl.c
@@ -0,0 +1,1038 @@
+/*
+ * PCIe host controller driver for NWL PCIe Bridge
+ * Based on pci-xilinx.c, pci-tegra.c
+ *
+ * (C) Copyright 2014 - 2015, Xilinx, Inc.
+ *
+ * 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.
+ */
+
+#include <linux/delay.h>
+#include <linux/interrupt.h>
+#include <linux/irq.h>
+#include <linux/irqdomain.h>
+#include <linux/kernel.h>
+#include <linux/module.h>
+#include <linux/msi.h>
+#include <linux/of_address.h>
+#include <linux/of_pci.h>
+#include <linux/of_platform.h>
+#include <linux/of_irq.h>
+#include <linux/pci.h>
+#include <linux/platform_device.h>
+
+/* Bridge core config registers */
+#define BRCFG_PCIE_RX0			0x00000000
+#define BRCFG_PCIE_RX1			0x00000004
+#define BRCFG_AXI_MASTER		0x00000008
+#define BRCFG_PCIE_TX			0x0000000C
+#define BRCFG_INTERRUPT			0x00000010
+#define BRCFG_RAM_DISABLE0		0x00000014
+#define BRCFG_RAM_DISABLE1		0x00000018
+#define BRCFG_PCIE_RELAXED_ORDER	0x0000001C
+#define BRCFG_PCIE_RX_MSG_FILTER	0x00000020
+
+/* Attribute registers */
+#define NWL_ATTRIB_100			0x00000190
+
+/* Egress - Bridge translation registers */
+#define E_BREG_CAPABILITIES		0x00000200
+#define E_BREG_STATUS			0x00000204
+#define E_BREG_CONTROL			0x00000208
+#define E_BREG_BASE_LO			0x00000210
+#define E_BREG_BASE_HI			0x00000214
+#define E_ECAM_CAPABILITIES		0x00000220
+#define E_ECAM_STATUS			0x00000224
+#define E_ECAM_CONTROL			0x00000228
+#define E_ECAM_BASE_LO			0x00000230
+#define E_ECAM_BASE_HI			0x00000234
+
+/* Ingress - address translations */
+#define I_MSII_CAPABILITIES		0x00000300
+#define I_MSII_CONTROL			0x00000308
+#define I_MSII_BASE_LO			0x00000310
+#define I_MSII_BASE_HI			0x00000314
+
+#define I_ISUB_CONTROL			0x000003E8
+#define SET_ISUB_CONTROL		BIT(0)
+/* Rxed msg fifo  - Interrupt status registers */
+#define MSGF_MISC_STATUS		0x00000400
+#define MSGF_MISC_MASK			0x00000404
+#define MSGF_LEG_STATUS			0x00000420
+#define MSGF_LEG_MASK			0x00000424
+#define MSGF_MSI_STATUS_LO		0x00000440
+#define MSGF_MSI_STATUS_HI		0x00000444
+#define MSGF_MSI_MASK_LO		0x00000448
+#define MSGF_MSI_MASK_HI		0x0000044C
+#define MSGF_RX_FIFO_POP		0x00000484
+#define MSGF_RX_FIFO_TYPE		0x00000488
+#define MSGF_RX_FIFO_ADDRLO		0x00000490
+#define MSGF_RX_FIFO_ADDRHI		0x00000494
+#define MSGF_RX_FIFO_DATA		0x00000498
+
+/* Msg filter mask bits */
+#define CFG_ENABLE_PM_MSG_FWD		BIT(1)
+#define CFG_ENABLE_INT_MSG_FWD		BIT(2)
+#define CFG_ENABLE_ERR_MSG_FWD		BIT(3)
+#define CFG_ENABLE_SLT_MSG_FWD		BIT(5)
+#define CFG_ENABLE_VEN_MSG_FWD		BIT(7)
+#define CFG_ENABLE_OTH_MSG_FWD		BIT(13)
+#define CFG_ENABLE_VEN_MSG_EN		BIT(14)
+#define CFG_ENABLE_VEN_MSG_VEN_INV	BIT(15)
+#define CFG_ENABLE_VEN_MSG_VEN_ID	GENMASK(31, 16)
+#define CFG_ENABLE_MSG_FILTER_MASK	(CFG_ENABLE_PM_MSG_FWD | \
+					CFG_ENABLE_INT_MSG_FWD | \
+					CFG_ENABLE_ERR_MSG_FWD | \
+					CFG_ENABLE_SLT_MSG_FWD | \
+					CFG_ENABLE_VEN_MSG_FWD | \
+					CFG_ENABLE_OTH_MSG_FWD | \
+					CFG_ENABLE_VEN_MSG_EN | \
+					CFG_ENABLE_VEN_MSG_VEN_INV | \
+					CFG_ENABLE_VEN_MSG_VEN_ID)
+
+/* Misc interrupt status mask bits */
+#define MSGF_MISC_SR_RXMSG_AVAIL	BIT(0)
+#define MSGF_MISC_SR_RXMSG_OVER		BIT(1)
+#define MSGF_MISC_SR_SLAVE_ERR		BIT(4)
+#define MSGF_MISC_SR_MASTER_ERR		BIT(5)
+#define MSGF_MISC_SR_I_ADDR_ERR		BIT(6)
+#define MSGF_MISC_SR_E_ADDR_ERR		BIT(7)
+
+#define MSGF_MISC_SR_PCIE_CORE		GENMASK(18, 16)
+#define MSGF_MISC_SR_PCIE_CORE_ERR	GENMASK(31, 20)
+
+#define MSGF_MISC_SR_MASKALL		(MSGF_MISC_SR_RXMSG_AVAIL | \
+					MSGF_MISC_SR_RXMSG_OVER | \
+					MSGF_MISC_SR_SLAVE_ERR | \
+					MSGF_MISC_SR_MASTER_ERR | \
+					MSGF_MISC_SR_I_ADDR_ERR | \
+					MSGF_MISC_SR_E_ADDR_ERR | \
+					MSGF_MISC_SR_PCIE_CORE | \
+					MSGF_MISC_SR_PCIE_CORE_ERR)
+
+/* Message rx fifo type mask bits */
+#define MSGF_RX_FIFO_TYPE_MSI	(1)
+#define MSGF_RX_FIFO_TYPE_TYPE	GENMASK(1, 0)
+
+/* Legacy interrupt status mask bits */
+#define MSGF_LEG_SR_INTA		BIT(0)
+#define MSGF_LEG_SR_INTB		BIT(1)
+#define MSGF_LEG_SR_INTC		BIT(2)
+#define MSGF_LEG_SR_INTD		BIT(3)
+#define MSGF_LEG_SR_MASKALL		(MSGF_LEG_SR_INTA | MSGF_LEG_SR_INTB | \
+					MSGF_LEG_SR_INTC | MSGF_LEG_SR_INTD)
+
+/* MSI interrupt status mask bits */
+#define MSGF_MSI_SR_LO_MASK		BIT(0)
+#define MSGF_MSI_SR_HI_MASK		BIT(0)
+
+#define MSII_PRESENT			BIT(0)
+#define MSII_ENABLE			BIT(0)
+#define MSII_STATUS_ENABLE		BIT(15)
+
+/* Bridge config interrupt mask */
+#define BRCFG_INTERRUPT_MASK		BIT(0)
+#define BREG_PRESENT			BIT(0)
+#define BREG_ENABLE			BIT(0)
+#define BREG_ENABLE_FORCE		BIT(1)
+
+/* E_ECAM status mask bits */
+#define E_ECAM_PRESENT			BIT(0)
+#define E_ECAM_SR_WR_PEND		BIT(16)
+#define E_ECAM_SR_RD_PEND		BIT(0)
+#define E_ECAM_SR_MASKALL		(E_ECAM_SR_WR_PEND | E_ECAM_SR_RD_PEND)
+#define E_ECAM_CR_ENABLE		BIT(0)
+#define E_ECAM_SIZE_LOC			GENMASK(20, 16)
+#define E_ECAM_SIZE_SHIFT		16
+#define ECAM_BUS_LOC_SHIFT		20
+#define ECAM_DEV_LOC_SHIFT		12
+#define NWL_ECAM_VALUE_DEFAULT		12
+#define NWL_ECAM_SIZE_MIN		4096
+
+#define ATTR_UPSTREAM_FACING		BIT(6)
+#define CFG_DMA_REG_BAR			GENMASK(2, 0)
+
+/* msgf_rx_fifo_pop bits */
+#define MSGF_RX_FIFO_POP_POP	BIT(0)
+
+#define INT_PCI_MSI_NR			(2 * 32)
+
+/* Readin the PS_LINKUP */
+#define PS_LINKUP_OFFSET			0x00000238
+#define PCIE_PHY_LINKUP_BIT			BIT(0)
+#define PHY_RDY_LINKUP_BIT			BIT(1)
+#define PCIE_USER_LINKUP			0
+#define PHY_RDY_LINKUP				1
+#define LINKUP_ITER_CHECK			5
+
+/* PCIE Message Request */
+#define TX_PCIE_MSG				0x00000620
+#define TX_PCIE_MSG_CNTL			0x00000004
+#define TX_PCIE_MSG_SPEC_LO			0x00000008
+#define TX_PCIE_MSG_SPEC_HI			0x0000000C
+#define TX_PCIE_MSG_DATA			0x00000010
+
+#define MSG_BUSY_BIT				BIT(8)
+#define MSG_EXECUTE_BIT				BIT(0)
+#define MSG_DONE_BIT				BIT(16)
+#define MSG_DONE_STATUS_BIT			(BIT(25) | BIT(24))
+#define RANDOM_DIGIT				0x11223344
+#define PATTRN_SSLP_TLP				0x01005074
+
+/**
+ * struct nwl_msi - MSI information
+ *
+ * @chip: MSI controller
+ * @used: Declare Bitmap for MSI
+ * @domain: IRQ domain pointer
+ * @pages: MSI pages
+ * @lock: mutex lock
+ * @irq_msi0: msi0 interrupt number
+ * @irq_msi1: msi1 interrupt number
+ */
+struct nwl_msi {
+	struct msi_controller chip;
+	DECLARE_BITMAP(used, INT_PCI_MSI_NR);
+	struct irq_domain *domain;
+	unsigned long pages;
+	struct mutex lock;
+	int irq_msi0;
+	int irq_msi1;
+};
+
+/**
+ * struct nwl_pcie - PCIe port information
+ *
+ * @dev: Device pointer
+ * @breg_base: IO Mapped Bridge Register Base
+ * @pcireg_base: IO Mapped PCIe controller attributes
+ * @ecam_base: IO Mapped configuration space
+ * @phys_breg_base: Physical Bridge Register Base
+ * @phys_pcie_reg_base: Physical PCIe Controller Attributes
+ * @phys_ecam_base: Physical Configuration Base
+ * @breg_size: Bridge Register space
+ * @pcie_reg_size: PCIe controller attributes space
+ * @ecam_size: PCIe Configuration space
+ * @irq_intx: Legacy interrupt number
+ * @irq_misc: Misc interrupt number
+ * @ecam_value: ECAM value
+ * @last_busno: Last Bus number configured
+ * @link_up: Link status flag
+ * @enable_msi_fifo: Enable MSI FIFO mode
+ * @bus: PCI bus
+ * @msi: MSI interrupt info
+ */
+struct nwl_pcie {
+	struct device *dev;
+	void __iomem *breg_base;
+	void __iomem *pcireg_base;
+	void __iomem *ecam_base;
+	u32 phys_breg_base;
+	u32 phys_pcie_reg_base;
+	u32 phys_ecam_base;
+	u32 breg_size;
+	u32 pcie_reg_size;
+	u32 ecam_size;
+	int irq_intx;
+	int irq_misc;
+	u32 ecam_value;
+	u8 last_busno;
+	u8 link_up;
+	bool enable_msi_fifo;
+	struct pci_bus *bus;
+	struct nwl_msi msi;
+};
+
+static inline struct nwl_msi *to_nwl_msi(struct msi_controller *chip)
+{
+	return container_of(chip, struct nwl_msi, chip);
+}
+
+static inline u32 nwl_bridge_readl(struct nwl_pcie *pcie, u32 off)
+{
+	return readl(pcie->breg_base + off);
+}
+
+static inline void nwl_bridge_writel(struct nwl_pcie *pcie, u32 val, u32 off)
+{
+	writel(val, pcie->breg_base + off);
+}
+
+static inline bool nwl_pcie_is_link_up(struct nwl_pcie *pcie, u32 check_bit)
+{
+	unsigned int status = -EINVAL;
+
+	if (check_bit == PCIE_USER_LINKUP)
+		status = (readl(pcie->pcireg_base + PS_LINKUP_OFFSET) &
+			  PCIE_PHY_LINKUP_BIT) ? 1 : 0;
+	else if (check_bit == PHY_RDY_LINKUP)
+		status = (readl(pcie->pcireg_base + PS_LINKUP_OFFSET) &
+			  PHY_RDY_LINKUP_BIT) ? 1 : 0;
+	return status;
+}
+
+/**
+ * nwl_pcie_get_config_base - Get configuration base
+ *
+ * @bus: Bus structure of current bus
+ * @devfn: Device/function
+ * @where: Offset from base
+ *
+ * Return: Base address of the configuration space needed to be
+ *	   accessed.
+ */
+static void __iomem *nwl_pcie_get_config_base(struct pci_bus *bus,
+						 unsigned int devfn,
+						 int where)
+{
+	struct nwl_pcie *pcie = bus->sysdata;
+	int relbus;
+
+	relbus = (bus->number << ECAM_BUS_LOC_SHIFT) |
+			(devfn << ECAM_DEV_LOC_SHIFT);
+
+	return pcie->ecam_base + relbus + where;
+}
+
+/**
+ * nwl_setup_sspl - Set Slot Power limit
+ *
+ * @pcie: PCIe port information
+ */
+static int nwl_setup_sspl(struct nwl_pcie *pcie)
+{
+	unsigned int status;
+	int check = 0;
+
+	do {
+		status = nwl_bridge_readl(pcie, TX_PCIE_MSG) & MSG_BUSY_BIT;
+		if (!status) {
+			/*
+			 * Generate the TLP message for a single EP
+			 * [TODO] Add a multi-endpoint code
+			 */
+			nwl_bridge_writel(pcie, 0x0,
+					  TX_PCIE_MSG + TX_PCIE_MSG_CNTL);
+			nwl_bridge_writel(pcie, 0x0,
+					  TX_PCIE_MSG + TX_PCIE_MSG_SPEC_LO);
+			nwl_bridge_writel(pcie, 0x0,
+					  TX_PCIE_MSG + TX_PCIE_MSG_SPEC_HI);
+			nwl_bridge_writel(pcie, 0x0,
+					  TX_PCIE_MSG + TX_PCIE_MSG_DATA);
+			/* Pattern to generate SSLP TLP */
+			nwl_bridge_writel(pcie, PATTRN_SSLP_TLP,
+					  TX_PCIE_MSG + TX_PCIE_MSG_CNTL);
+			nwl_bridge_writel(pcie, RANDOM_DIGIT,
+					  TX_PCIE_MSG + TX_PCIE_MSG_DATA);
+			nwl_bridge_writel(pcie, nwl_bridge_readl(pcie,
+					  TX_PCIE_MSG) | 0x1, TX_PCIE_MSG);
+			status = 0;
+			do {
+				status = nwl_bridge_readl(pcie, TX_PCIE_MSG) &
+							  MSG_DONE_BIT;
+				if (!status && (check < 1)) {
+					mdelay(1);
+					check++;
+				} else {
+					return false;
+				}
+
+			} while (!status);
+			status = nwl_bridge_readl(pcie, TX_PCIE_MSG)
+						  & MSG_DONE_STATUS_BIT;
+		}
+	} while (status);
+
+	return true;
+}
+
+/**
+ * nwl_nwl_readl_config - Read configuration space
+ *
+ * @bus: Bus structure of current bus
+ * @devfn: Device/function
+ * @where: Offset from base
+ * @size: Byte/word/dword
+ * @val: Value to be read
+ *
+ * Return: PCIBIOS_SUCCESSFUL on success
+ *	   PCIBIOS_DEVICE_NOT_FOUND on failure.
+ */
+static int nwl_nwl_readl_config(struct pci_bus *bus,
+				unsigned int devfn,
+				int where,
+				int size,
+				u32 *val)
+{
+	void __iomem *addr;
+
+	if (!bus->number && devfn > 0) {
+		*val = 0xFFFFFFFF;
+		return PCIBIOS_DEVICE_NOT_FOUND;
+	}
+
+	addr = nwl_pcie_get_config_base(bus, devfn, where);
+
+	switch (size) {
+	case 1:
+		*val = readb(addr);
+		break;
+	case 2:
+		*val = readw(addr);
+		break;
+	default:
+		*val = readl(addr);
+		break;
+	}
+	return PCIBIOS_SUCCESSFUL;
+}
+
+/**
+ * nwl_nwl_writel_config - Write configuration space
+ *
+ * @bus: Bus structure of current bus
+ * @devfn: Device/function
+ * @where: Offset from base
+ * @size: Byte/word/dword
+ * @val: Value to be written to device
+ *
+ * Return: PCIBIOS_SUCCESSFUL on success,
+ *	   PCIBIOS_DEVICE_NOT_FOUND on failure.
+ */
+static int nwl_nwl_writel_config(struct pci_bus *bus,
+				unsigned int devfn,
+				int where,
+				int size,
+				u32 val)
+{
+	void __iomem *addr;
+	int err = 0;
+	struct nwl_pcie *pcie = bus->sysdata;
+
+	if (!bus->number && devfn > 0)
+		return PCIBIOS_DEVICE_NOT_FOUND;
+
+	addr = nwl_pcie_get_config_base(bus, devfn, where);
+
+	switch (size) {
+	case 1:
+		writeb(val, addr);
+		break;
+	case 2:
+		writew(val, addr);
+		break;
+	default:
+		writel(val, addr);
+		break;
+	}
+	if (addr == (pcie->ecam_base + PCI_EXP_SLTCAP)) {
+		err = nwl_setup_sspl(pcie);
+		if (!err)
+			return PCIBIOS_SET_FAILED;
+	}
+
+	return PCIBIOS_SUCCESSFUL;
+}
+
+/* PCIe operations */
+static struct pci_ops nwl_pcie_ops = {
+	.read  = nwl_nwl_readl_config,
+	.write = nwl_nwl_writel_config,
+};
+
+static irqreturn_t nwl_pcie_misc_handler(int irq, void *data)
+{
+	struct nwl_pcie *pcie = (struct nwl_pcie *)data;
+	u32 misc_stat;
+
+	/* Checking for misc interrupts */
+	misc_stat = nwl_bridge_readl(pcie, MSGF_MISC_STATUS) &
+				     MSGF_MISC_SR_MASKALL;
+	if (!misc_stat)
+		return IRQ_NONE;
+
+	if (misc_stat & MSGF_MISC_SR_RXMSG_OVER)
+		dev_err(pcie->dev, "Received Message FIFO Overflow\n");
+
+	if (misc_stat & MSGF_MISC_SR_SLAVE_ERR)
+		dev_err(pcie->dev, "Slave error\n");
+
+	if (misc_stat & MSGF_MISC_SR_MASTER_ERR)
+		dev_err(pcie->dev, "Master error\n");
+
+	if (misc_stat & MSGF_MISC_SR_I_ADDR_ERR)
+		dev_err(pcie->dev,
+			"In Misc Ingress address translation error\n");
+
+	if (misc_stat & MSGF_MISC_SR_E_ADDR_ERR)
+		dev_err(pcie->dev,
+			"In Misc Egress address translation error\n");
+
+	if (misc_stat & MSGF_MISC_SR_PCIE_CORE_ERR)
+		dev_err(pcie->dev, "PCIe Core error\n");
+
+	if (pcie->enable_msi_fifo) {
+		if (misc_stat & MSGF_MISC_SR_RXMSG_AVAIL) {
+			u32 msg_type = nwl_bridge_readl(pcie,
+							MSGF_RX_FIFO_TYPE) &
+							MSGF_RX_FIFO_TYPE_TYPE;
+
+			if (msg_type == MSGF_RX_FIFO_TYPE_MSI) {
+				u32 irq_msi;
+				struct nwl_msi *msi = &pcie->msi;
+				u32 msi_data = nwl_bridge_readl(pcie,
+							MSGF_RX_FIFO_DATA);
+				/* Let all ready be completed before write */
+				rmb();
+				/* POP the FIFO */
+				nwl_bridge_writel(pcie, MSGF_RX_FIFO_POP_POP,
+						  MSGF_RX_FIFO_POP);
+
+				/* Handle the msi virtual interrupt */
+				irq_msi = irq_find_mapping(msi->domain,
+							   msi_data);
+
+				if (irq_msi) {
+					if (test_bit(msi_data, msi->used))
+						generic_handle_irq(irq_msi);
+					else
+						dev_info(pcie->dev,
+							 "unhandled MSI %d\n",
+							 irq_msi);
+				} else {
+					dev_info(pcie->dev, "unexpected MSI\n");
+				}
+			}
+		}
+	}
+	/* Clear misc interrupt status */
+	nwl_bridge_writel(pcie, misc_stat, MSGF_MISC_STATUS);
+
+	return IRQ_HANDLED;
+}
+
+static irqreturn_t nwl_pcie_leg_handler(int irq, void *data)
+{
+	struct nwl_pcie *pcie = (struct nwl_pcie *)data;
+	u32 leg_stat;
+
+	/* Checking for legacy interrupts */
+	leg_stat = nwl_bridge_readl(pcie, MSGF_LEG_STATUS) &
+				MSGF_LEG_SR_MASKALL;
+	if (!leg_stat)
+		return IRQ_NONE;
+
+	if (leg_stat & MSGF_LEG_SR_INTA)
+		dev_dbg(pcie->dev, "legacy interruptA\n");
+
+	if (leg_stat & MSGF_LEG_SR_INTB)
+		dev_dbg(pcie->dev, "legacy interruptB\n");
+
+	if (leg_stat & MSGF_LEG_SR_INTC)
+		dev_dbg(pcie->dev, "legacy interruptC\n");
+
+	if (leg_stat & MSGF_LEG_SR_INTD)
+		dev_dbg(pcie->dev, "legacy interruptD\n");
+
+	return IRQ_HANDLED;
+}
+
+static void __nwl_pcie_msi_handler(struct nwl_pcie *pcie,
+					unsigned long reg, u32 val)
+{
+	struct nwl_msi *msi = &pcie->msi;
+	unsigned int offset, index;
+	int irq_msi;
+
+	offset = find_first_bit(&reg, 32);
+	index = offset;
+
+	/* Clear the interrupt */
+	nwl_bridge_writel(pcie, 1 << offset, val);
+
+	/* Handle the msi virtual interrupt */
+	irq_msi = irq_find_mapping(msi->domain, index);
+	if (irq_msi) {
+		if (test_bit(index, msi->used))
+			generic_handle_irq(irq_msi);
+		else
+			dev_info(pcie->dev, "unhandled MSI\n");
+	} else {
+		/* that's weird who triggered this? just clear it */
+		dev_info(pcie->dev, "unexpected MSI\n");
+	}
+}
+
+static irqreturn_t nwl_pcie_msi_handler(int irq, void *data)
+{
+	struct nwl_pcie *pcie = data;
+	unsigned long reg;
+	int processed = 0;
+
+	reg = nwl_bridge_readl(pcie, MSGF_MSI_STATUS_LO);
+	if (reg) {
+		__nwl_pcie_msi_handler(pcie, reg, MSGF_MSI_STATUS_LO);
+		processed++;
+	}
+
+	reg = nwl_bridge_readl(pcie, MSGF_MSI_STATUS_HI);
+	if (reg) {
+		__nwl_pcie_msi_handler(pcie, reg, MSGF_MSI_STATUS_HI);
+		processed++;
+	}
+
+	return processed > 0 ? IRQ_HANDLED : IRQ_NONE;
+}
+
+static int nwl_msi_alloc(struct nwl_msi *chip)
+{
+	int msi;
+
+	mutex_lock(&chip->lock);
+
+	msi = find_first_zero_bit(chip->used, INT_PCI_MSI_NR);
+	if (msi < INT_PCI_MSI_NR)
+		set_bit(msi, chip->used);
+	else
+		msi = -ENOSPC;
+
+	mutex_unlock(&chip->lock);
+
+	return msi;
+}
+
+static void nwl_msi_free(struct nwl_msi *chip, unsigned long irq)
+{
+	struct device *dev = chip->chip.dev;
+
+	mutex_lock(&chip->lock);
+
+	if (!test_bit(irq, chip->used))
+		dev_err(dev, "trying to free unused MSI#%lu\n", irq);
+	else
+		clear_bit(irq, chip->used);
+
+	mutex_unlock(&chip->lock);
+}
+
+static int nwl_msi_setup_irq(struct msi_controller *chip, struct pci_dev *pdev,
+			       struct msi_desc *desc)
+{
+	struct nwl_msi *msi = to_nwl_msi(chip);
+	struct msi_msg msg;
+	unsigned int irq;
+	int hwirq;
+
+	if (desc->msi_attrib.is_msix) {
+		/* currently we are not supporting MSIx */
+		return -ENOSPC;
+	}
+
+	hwirq = nwl_msi_alloc(msi);
+	if (hwirq < 0)
+		return hwirq;
+
+	irq = irq_create_mapping(msi->domain, hwirq);
+	if (!irq)
+		return -EINVAL;
+
+	irq_set_msi_desc(irq, desc);
+
+	msg.address_lo = virt_to_phys((void *)msi->pages);
+	/* 32 bit address only */
+	msg.address_hi = 0;
+	msg.data = hwirq;
+
+	write_msi_msg(irq, &msg);
+
+	return 0;
+}
+
+static void nwl_msi_teardown_irq(struct msi_controller *chip, unsigned int irq)
+{
+	struct nwl_msi *msi = to_nwl_msi(chip);
+	struct irq_data *d = irq_get_irq_data(irq);
+
+	nwl_msi_free(msi, d->hwirq);
+}
+
+static struct irq_chip nwl_msi_irq_chip = {
+	.name = "nwl_pcie:msi",
+	.irq_enable = unmask_msi_irq,
+	.irq_disable = mask_msi_irq,
+	.irq_mask = mask_msi_irq,
+	.irq_unmask = unmask_msi_irq,
+};
+
+static int nwl_msi_map(struct irq_domain *domain, unsigned int irq,
+			 irq_hw_number_t hwirq)
+{
+	irq_set_chip_and_handler(irq, &nwl_msi_irq_chip, handle_simple_irq);
+	irq_set_chip_data(irq, domain->host_data);
+	set_irq_flags(irq, IRQF_VALID);
+
+	return 0;
+}
+
+static const struct irq_domain_ops msi_domain_ops = {
+	.map = nwl_msi_map,
+};
+
+static int nwl_pcie_enable_msi(struct nwl_pcie *pcie, struct pci_bus *bus)
+{
+	struct platform_device *pdev = to_platform_device(pcie->dev);
+	struct nwl_msi *msi = &pcie->msi;
+	unsigned long base;
+	int ret;
+
+	mutex_init(&msi->lock);
+
+	/* Assign msi chip hooks */
+	msi->chip.dev = pcie->dev;
+	msi->chip.setup_irq = nwl_msi_setup_irq;
+	msi->chip.teardown_irq = nwl_msi_teardown_irq;
+
+	bus->msi = &msi->chip;
+	/* Allocate linear irq domain */
+	msi->domain = irq_domain_add_linear(pcie->dev->of_node, INT_PCI_MSI_NR,
+					    &msi_domain_ops, &msi->chip);
+	if (!msi->domain) {
+		dev_err(&pdev->dev, "failed to create IRQ domain\n");
+		return -ENOMEM;
+	}
+
+	/* Check for msii_present bit */
+	ret = nwl_bridge_readl(pcie, I_MSII_CAPABILITIES) & MSII_PRESENT;
+	if (!ret) {
+		dev_err(pcie->dev, "MSI not present\n");
+		ret = -EIO;
+		goto err;
+	}
+
+	/* Enable MSII */
+	nwl_bridge_writel(pcie, nwl_bridge_readl(pcie, I_MSII_CONTROL) |
+			  MSII_ENABLE, I_MSII_CONTROL);
+	if (!pcie->enable_msi_fifo)
+		/* Enable MSII status */
+		nwl_bridge_writel(pcie, nwl_bridge_readl(pcie, I_MSII_CONTROL) |
+				  MSII_STATUS_ENABLE, I_MSII_CONTROL);
+
+	/* setup AFI/FPCI range */
+	msi->pages = __get_free_pages(GFP_KERNEL, 0);
+	base = virt_to_phys((void *)msi->pages);
+	/* Write base to MSII_BASE_LO */
+	nwl_bridge_writel(pcie, base, I_MSII_BASE_LO);
+
+	/* Write 0x0 to MSII_BASE_HI */
+	nwl_bridge_writel(pcie, 0x0, I_MSII_BASE_HI);
+
+	/* Disable high range msi interrupts */
+	nwl_bridge_writel(pcie, (u32)~MSGF_MSI_SR_HI_MASK, MSGF_MSI_MASK_HI);
+
+	/* Clear pending high range msi interrupts */
+	nwl_bridge_writel(pcie, nwl_bridge_readl(pcie,  MSGF_MSI_STATUS_HI) &
+			  MSGF_MSI_SR_HI_MASK, MSGF_MSI_STATUS_HI);
+	/* Get msi_1 IRQ number */
+	msi->irq_msi1 = platform_get_irq_byname(pdev, "msi_1");
+	if (msi->irq_msi1 < 0) {
+		dev_err(&pdev->dev, "failed to get IRQ#%d\n", msi->irq_msi1);
+		goto err;
+	}
+	/* Register msi handler */
+	ret = devm_request_irq(pcie->dev, msi->irq_msi1, nwl_pcie_msi_handler,
+			       0, nwl_msi_irq_chip.name, pcie);
+	if (ret < 0) {
+		dev_err(&pdev->dev, "failed to request IRQ#%d\n",
+					msi->irq_msi1);
+		goto err;
+	}
+
+	/* Enable all high range msi interrupts */
+	nwl_bridge_writel(pcie, MSGF_MSI_SR_HI_MASK, MSGF_MSI_MASK_HI);
+
+	/* Disable low range msi interrupts */
+	nwl_bridge_writel(pcie, (u32)~MSGF_MSI_SR_LO_MASK, MSGF_MSI_MASK_LO);
+
+	/* Clear pending low range msi interrupts */
+	nwl_bridge_writel(pcie, nwl_bridge_readl(pcie, MSGF_MSI_STATUS_LO) &
+			  MSGF_MSI_SR_LO_MASK, MSGF_MSI_STATUS_LO);
+	/* Get msi_0 IRQ number */
+	msi->irq_msi0 = platform_get_irq_byname(pdev, "msi_0");
+	if (msi->irq_msi0 < 0) {
+		dev_err(&pdev->dev, "failed to get IRQ#%d\n", msi->irq_msi0);
+		goto err;
+	}
+	/* Register msi handler */
+	ret = devm_request_irq(pcie->dev, msi->irq_msi0, nwl_pcie_msi_handler,
+			       0, nwl_msi_irq_chip.name, pcie);
+	if (ret < 0) {
+		dev_err(&pdev->dev, "failed to request IRQ#%d\n",
+					msi->irq_msi0);
+		goto err;
+	}
+	/* Enable all low range msi interrupts */
+	nwl_bridge_writel(pcie, MSGF_MSI_SR_LO_MASK, MSGF_MSI_MASK_LO);
+
+	return 0;
+err:
+	irq_domain_remove(msi->domain);
+	return ret;
+}
+
+static int nwl_pcie_bridge_init(struct nwl_pcie *pcie)
+{
+	struct platform_device *pdev = to_platform_device(pcie->dev);
+	u32 breg_val, ecam_val, first_busno = 0;
+	int err;
+	int check_link_up = 0;
+
+	/* Check for BREG present bit */
+	breg_val = nwl_bridge_readl(pcie, E_BREG_CAPABILITIES) & BREG_PRESENT;
+	if (!breg_val) {
+		dev_err(pcie->dev, "BREG is not present\n");
+		return breg_val;
+	}
+	/* Write bridge_off to breg base */
+	nwl_bridge_writel(pcie, (u32)(pcie->phys_breg_base),
+			  E_BREG_BASE_LO);
+
+	/* Enable BREG */
+	nwl_bridge_writel(pcie, ~BREG_ENABLE_FORCE & BREG_ENABLE,
+			  E_BREG_CONTROL);
+
+	/* Disable DMA channel registers */
+	nwl_bridge_writel(pcie, nwl_bridge_readl(pcie, BRCFG_PCIE_RX0) |
+			  CFG_DMA_REG_BAR, BRCFG_PCIE_RX0);
+
+	/* Enable the bridge config interrupt */
+	nwl_bridge_writel(pcie, nwl_bridge_readl(pcie, BRCFG_INTERRUPT) |
+			  BRCFG_INTERRUPT_MASK, BRCFG_INTERRUPT);
+	/* Enable Ingress subtractive decode translation */
+	nwl_bridge_writel(pcie, SET_ISUB_CONTROL, I_ISUB_CONTROL);
+
+	/* Enable msg filtering details */
+	nwl_bridge_writel(pcie, CFG_ENABLE_MSG_FILTER_MASK,
+			  BRCFG_PCIE_RX_MSG_FILTER);
+	do {
+		err = nwl_pcie_is_link_up(pcie, PHY_RDY_LINKUP);
+		if (err != 1) {
+			check_link_up++;
+			if (check_link_up > LINKUP_ITER_CHECK)
+				return -ENODEV;
+		}
+	} while (!err);
+
+	/* Check for ECAM present bit */
+	ecam_val = nwl_bridge_readl(pcie, E_ECAM_CAPABILITIES) & E_ECAM_PRESENT;
+	if (!ecam_val) {
+		dev_err(pcie->dev, "ECAM is not present\n");
+		return ecam_val;
+	}
+
+	/* Enable ECAM */
+	nwl_bridge_writel(pcie, nwl_bridge_readl(pcie, E_ECAM_CONTROL) |
+			  E_ECAM_CR_ENABLE, E_ECAM_CONTROL);
+	/* Write ecam_value on ecam_control */
+	nwl_bridge_writel(pcie, nwl_bridge_readl(pcie, E_ECAM_CONTROL) |
+			  (pcie->ecam_value << E_ECAM_SIZE_SHIFT),
+			  E_ECAM_CONTROL);
+	/* Write phy_reg_base to ecam base */
+	nwl_bridge_writel(pcie, (u32)pcie->phys_ecam_base, E_ECAM_BASE_LO);
+
+	/* Get bus range */
+	ecam_val = nwl_bridge_readl(pcie, E_ECAM_CONTROL);
+	pcie->last_busno = (ecam_val & E_ECAM_SIZE_LOC) >> E_ECAM_SIZE_SHIFT;
+	/* Write primary, secondary and subordinate bus numbers */
+	ecam_val = first_busno;
+	ecam_val |= (first_busno + 1) << 8;
+	ecam_val |= (pcie->last_busno << E_ECAM_SIZE_SHIFT);
+	writel(ecam_val, (pcie->ecam_base + PCI_PRIMARY_BUS));
+
+	/* Check if PCIe link is up? */
+	pcie->link_up = nwl_pcie_is_link_up(pcie, PCIE_USER_LINKUP);
+	if (!pcie->link_up)
+		dev_info(pcie->dev, "Link is DOWN\n");
+	else
+		dev_info(pcie->dev, "Link is UP\n");
+
+	/* Disable all misc interrupts */
+	nwl_bridge_writel(pcie, (u32)~MSGF_MISC_SR_MASKALL, MSGF_MISC_MASK);
+
+	/* Clear pending misc interrupts */
+	nwl_bridge_writel(pcie, nwl_bridge_readl(pcie, MSGF_MISC_STATUS) &
+			  MSGF_MISC_SR_MASKALL, MSGF_MISC_STATUS);
+
+	/* Get misc IRQ number */
+	pcie->irq_misc = platform_get_irq_byname(pdev, "misc");
+	if (pcie->irq_misc < 0) {
+		dev_err(&pdev->dev, "failed to get misc IRQ#%d\n",
+			pcie->irq_misc);
+		return pcie->irq_misc;
+	}
+	/* Register misc handler */
+	err = devm_request_irq(pcie->dev, pcie->irq_misc,
+			       nwl_pcie_misc_handler, IRQF_SHARED,
+			       "nwl_pcie:misc", pcie);
+	if (err) {
+		dev_err(pcie->dev, "fail to register misc IRQ#%d\n",
+			pcie->irq_misc);
+		return err;
+	}
+	/* Enable all misc interrupts */
+	nwl_bridge_writel(pcie, MSGF_MISC_SR_MASKALL, MSGF_MISC_MASK);
+
+	/* Disable all legacy interrupts */
+	nwl_bridge_writel(pcie, (u32)~MSGF_LEG_SR_MASKALL, MSGF_LEG_MASK);
+
+	/* Clear pending legacy interrupts */
+	nwl_bridge_writel(pcie, nwl_bridge_readl(pcie, MSGF_LEG_STATUS) &
+			  MSGF_LEG_SR_MASKALL, MSGF_LEG_STATUS);
+	/* Get intx IRQ number */
+	pcie->irq_intx = platform_get_irq_byname(pdev, "intx");
+	if (pcie->irq_intx < 0) {
+		dev_err(&pdev->dev, "failed to get intx IRQ#%d\n",
+			pcie->irq_intx);
+		return pcie->irq_intx;
+	}
+
+	/* Register intx handler */
+	err = devm_request_irq(pcie->dev, pcie->irq_intx,
+			       nwl_pcie_leg_handler, IRQF_SHARED,
+			       "nwl_pcie:intx", pcie);
+	if (err) {
+		dev_err(pcie->dev, "fail to register intx IRQ#%d\n",
+			pcie->irq_intx);
+		return err;
+	}
+	/* Enable all legacy interrupts */
+	nwl_bridge_writel(pcie, MSGF_LEG_SR_MASKALL, MSGF_LEG_MASK);
+
+	return 0;
+}
+
+static int nwl_pcie_parse_dt(struct nwl_pcie *pcie,
+					struct platform_device *pdev)
+{
+	struct device_node *node = pcie->dev->of_node;
+	struct resource *res;
+	const char *type;
+
+	/* Check for device type */
+	type = of_get_property(node, "device_type", NULL);
+	if (!type || strcmp(type, "pci")) {
+		dev_err(pcie->dev, "invalid \"device_type\" %s\n", type);
+		return -EINVAL;
+	}
+
+	res = platform_get_resource_byname(pdev, IORESOURCE_MEM, "breg");
+	pcie->breg_base = devm_ioremap_resource(pcie->dev, res);
+	if (IS_ERR(pcie->breg_base))
+		return PTR_ERR(pcie->breg_base);
+	pcie->phys_breg_base = res->start;
+
+	res = platform_get_resource_byname(pdev, IORESOURCE_MEM, "pcireg");
+	pcie->pcireg_base = devm_ioremap_resource(pcie->dev, res);
+	if (IS_ERR(pcie->pcireg_base))
+		return PTR_ERR(pcie->pcireg_base);
+	pcie->phys_pcie_reg_base = res->start;
+
+	res = platform_get_resource_byname(pdev, IORESOURCE_MEM, "cfg");
+	pcie->ecam_base = devm_ioremap_resource(pcie->dev, res);
+	if (IS_ERR(pcie->ecam_base))
+		return PTR_ERR(pcie->ecam_base);
+	pcie->phys_ecam_base = res->start;
+
+	pcie->enable_msi_fifo = of_property_read_bool(node, "xlnx,msi-fifo");
+
+	return 0;
+}
+
+static const struct of_device_id nwl_pcie_of_match[] = {
+	{ .compatible = "xlnx,nwl-pcie-2.11", },
+	{}
+};
+
+static int nwl_pcie_probe(struct platform_device *pdev)
+{
+	struct device_node *node = pdev->dev.of_node;
+	struct nwl_pcie *pcie;
+	struct pci_bus *bus;
+	int err;
+
+	resource_size_t iobase = 0;
+	LIST_HEAD(res);
+
+	/* Allocate private nwl_pcie struct */
+	pcie = devm_kzalloc(&pdev->dev, sizeof(*pcie), GFP_KERNEL);
+	if (!pcie)
+		return -ENOMEM;
+
+	/* Set ecam value */
+	pcie->ecam_value = NWL_ECAM_VALUE_DEFAULT;
+
+	pcie->dev = &pdev->dev;
+
+	/* Parse the device tree */
+	err = nwl_pcie_parse_dt(pcie, pdev);
+	if (err) {
+		dev_err(pcie->dev, "Parsing DT failed\n");
+		return err;
+	}
+	/* Bridge initialization */
+	err = nwl_pcie_bridge_init(pcie);
+	if (err) {
+		dev_err(pcie->dev, "HW Initalization failed\n");
+		return err;
+	}
+
+	err = of_pci_get_host_bridge_resources(node, 0, 0xff, &res, &iobase);
+	if (err) {
+		pr_err("Getting bridge resources failed\n");
+		return err;
+	}
+	bus = pci_create_root_bus(&pdev->dev, 0,
+				  &nwl_pcie_ops, pcie, &res);
+	if (!bus)
+		return -ENOMEM;
+
+	/* Enable MSI */
+	if (IS_ENABLED(CONFIG_PCI_MSI)) {
+		err = nwl_pcie_enable_msi(pcie, bus);
+		if (err < 0) {
+			dev_err(&pdev->dev,
+				"failed to enable MSI support: %d\n",
+				err);
+			return err;
+		}
+	}
+	pci_scan_child_bus(bus);
+	pci_assign_unassigned_bus_resources(bus);
+	pci_bus_add_devices(bus);
+	platform_set_drvdata(pdev, pcie);
+
+	return 0;
+}
+
+static int nwl_pcie_remove(struct platform_device *pdev)
+{
+	platform_set_drvdata(pdev, NULL);
+
+	return 0;
+}
+
+static struct platform_driver nwl_pcie_driver = {
+	.driver = {
+		.name = "nwl-pcie",
+		.of_match_table = nwl_pcie_of_match,
+	},
+	.probe = nwl_pcie_probe,
+	.remove = nwl_pcie_remove,
+};
+module_platform_driver(nwl_pcie_driver);
+
+MODULE_AUTHOR("Xilinx, Inc");
+MODULE_DESCRIPTION("NWL PCIe driver");
+MODULE_LICENSE("GPL");
--
1.7.4


From punnaia at xilinx.com  Thu Aug 27 04:49:15 2015
From: punnaia at xilinx.com (punnaiah choudary kalluri)
Date: Thu, 27 Aug 2015 17:19:15 +0530
Subject: [LINUX RFC v2 0/4] spi: add dual parallel mode support in Zynq
 MPSoC GQSPI controller
In-Reply-To: <CAD6G_RR+QnuK++KvztYo+68sb7yQqwM7qg-X7bybCYaBN+nAGQ@mail.gmail.com>
References: <1440570367-22569-1-git-send-email-ranjit.waghmode@xilinx.com>
 <CAD6G_RQhWBsUTZNBB44W98Fjzw82H_D_E9nY0aDWezj729mkoA@mail.gmail.com>
 <CAGnW=BZtsVtT+Z7gTq5jybXsHWp+RNpjc6ckk6-MXWxAS7u8Mw@mail.gmail.com>
 <CAD6G_RTCQ5Fzjgxz+-3oMDAyUTg6UFAqvpEPQzJ9maSTZ3Nc_g@mail.gmail.com>
 <CAGnW=BZ80B_2kzZVULhZvEXFs+_GXkGbu8mii1eFp3MySvA8aA@mail.gmail.com>
 <CAD6G_RR+QnuK++KvztYo+68sb7yQqwM7qg-X7bybCYaBN+nAGQ@mail.gmail.com>
Message-ID: <CAGnW=Bar5_t9Pzfz4v6x7HL6ZN=Tm8TPW8HpY42JaksT1NLnQw@mail.gmail.com>

On Thu, Aug 27, 2015 at 3:45 PM, Jagan Teki <jteki at openedev.com> wrote:
> On 27 August 2015 at 14:18, punnaiah choudary kalluri
> <punnaia at xilinx.com> wrote:
>> On Thu, Aug 27, 2015 at 11:53 AM, Jagan Teki <jteki at openedev.com> wrote:
>>> On 26 August 2015 at 21:02, punnaiah choudary kalluri
>>> <punnaia at xilinx.com> wrote:
>>>> On Wed, Aug 26, 2015 at 5:49 PM, Jagan Teki <jteki at openedev.com> wrote:
>>>>> On 26 August 2015 at 11:56, Ranjit Waghmode <ranjit.waghmode at xilinx.com> wrote:
>>>>>> This series adds dual parallel mode support for Zynq Ultrascale+
>>>>>> MPSoC GQSPI controller driver.
>>>>>>
>>>>>> What is dual parallel mode?
>>>>>> ---------------------------
>>>>>> ZynqMP GQSPI controller supports Dual Parallel mode with following functionalities:
>>>>>> 1) Supporting two SPI flash memories operating in parallel. 8 I/O lines.
>>>>>> 2) Chip selects and clock are shared to both the flash devices
>>>>>> 3) This mode is targeted for faster read/write speed and also doubles the size
>>>>>> 4) Commands/data can be transmitted/received from both the devices(mirror),
>>>>>>    or only upper or only lower flash memory devices.
>>>>>> 5) Data arrangement:
>>>>>>    With stripe enabled,
>>>>>>    Even bytes i.e. 0, 2, 4,... are transmitted on Lower Data Bus
>>>>>>    Odd bytes i.e. 1, 3, 5,.. are transmitted on Upper Data Bus.
>> <snip>
>>>>> I don't find any previous discussion about way to inform flash
>>>>> dual-ness into spi-nor
>>>>> from spi drivers.
>>>>>
>>>>> Here is my idea, probably others may think same.
>>>>> Informing dual_flash from drivers/spi through flags or any other mode
>>>>> bits is not a better approach as dual flash feature is specific to
>>>>> spi-nor flash controller (controller specially designed for spi-nor
>>>>> flash not the generic spi controller).  So if the driver sits on
>>>>> drivers/mtd/spi-nor/ (ex: fsl-quadspi.c), may be we can inform flash
>>>>> specific things to spi-nor as it's not touching generic spi stack in
>>>>> Linux. But there is a defined-drawback if the driver is moved to
>>>>> drivers/mtd/spi-nor ie it can't use spi core API's at-all.
>>>>
>>>> Xilinx GQSPI is a generic quad spi controller. The primary goal is to support
>>>> Generic/Future command sequences and Future NOR/NAND flash devices.
>>>> This core can also be used for legacy SPI devices. Due to the generic nature
>>>> of the core, software can generate any command sequence. It also has additional
>>>> features like parallel and stacked configurations to double the data
>>>> rate and size.
>>>> Accessing spi-nor flash device is one particular use case and like
>>>> that there will be
>>>> many. So, we decided to keep this driver in generic spi framework and
>>>> that is the ideal
>>>> thing to do for the GQSPI controller.
>>>
>>> Yes, I understand the generic nature of the GQSPI and it's good to
>>> have all-in-one like generic spi, spi-nor and spi-nand and more
>>> together, but Linux stacks were implemented in such a way to support
>>> the each type of controller with connected slaves separably for better
>>> handling.
>>
>> True and this is the reason we have controller drivers and protocol drivers.
>> GQSPI is the controller driver and spi-nor and spi-nand are the
>> protocol drivers.
>>
>>>
>>> Currently GQSPI driver is added in drivers/spi as it supports generic
>>> spi nature and now it enhanced more through flags for supporting
>>> spi-nor, what if we add spi-nand support for the same controller? do
>>> we add one more driver in spi-nand framework (drivers/mtd/spi-nand -
>>> an on going implementation)? My only observation here is even if the
>>> controller is more generic to support more number of device classes,
>>> and adding same driver and populate the slave stuff through flags or
>>> different kind of mechanism to different driver stack, this is not a
>>> better approach I thought.
>>
>> Just to clear, dual parallel( 2 CS and 8 IO lines) is not only specific
>> to flash parts, one can use for any other custom streaming protocols
>> I would say exporting dual parallel connection to protocol drivers is
>> something like depicting the spi bus topology to the protocol layer.
>
> So dual parallel may not used for spi-nor flash it can also used other
> spi slaves that's what your saying is it?

Yes. As i said above, the main intention of this feature is to improve
the data rate with an overhead of few IO lines.

>
>>
>> AFAIK, spi-nor and spi-nand are protocol drivers for accessing the
>> nor and nand flash devices sitting on the spi bus using the spi
>> controller driver.
>
> Yes, I do agree with your point, but though driver stacks are
> different with same kind of bus here, I'm trying to spit the GQSPI
> into 3 different controller drivers as Linux understand it and fit on
> to Linux stack with out disturbing the generic-ness.

 I feel this is not a nice idea. if there are 'n' functionalities and having
'n' controller drivers doesn't seem good in any direction.

Protocol driver can query the spi core about the bus topology and it is the
responsibility of the spi core and controller driver providing this information
to the upper layers.


Regards,
Punnaiah


>
> Assumption is GQSPI shall split to various platform_drivers (if each
> platform driver treated as a controller) thought it made up of  spi
> bus.
>
>>>
>>> Based on the above comments, there is an approach to handle this
>>> support and I'm not 100% sure whether this fits or not but we
>>> implemented the same -  this is "probing child devices from parent"
>>> (there was a discussion with Arnd earlier wrt this, but I'm unable to
>>> get the mailing thread)
>>>
>>> Added Arnd (probably will give more inputs or corrections)
>>>
>>> Let me explain how we implemented on our design.
>>> We have PCIe controller that support basic root complex handling, dma
>>> and controller hotplug (not in-build pcie hp) and ideally we need to
>>> write driver for handling root complex on drivers/pci/host and one
>>> hotplug driver in drivers/pci and one more driver in drivers/dma for
>>> handling pcie dma stuff. And some pcie calls need to navigate from
>>> root complex driver to dma and hotplug driver that means there is call
>>> transition from driver/pci to driver/dma which is absolutely not a
>>> good approach (spi to spi-nor and spi-nand transition - in GQSPI case)
>>>
>>> So the implementation we follow is like there is a pcie root complex
>>> driver(probably generic spi driver in drivers/spi/*) and inside probe
>>> we have register platform_device for hotplug (spi-nor) and dma
>>> (spi-nand) and the dma driver in drivers/dma and hotplug driver in
>>> driver/pci/ are platform drivers which is of legacy binding (not with
>>> dts) so there should be a common dts for root complex driver
>>> (drivers/spi/*) and individual child driver need to take those while
>>> registering platform_device.
>>>
>>> example pseudo:
>>>
>>> drivers/dma/dma-child2.c
>>>
>>> Legacy platform_driver binding and handling dma future as normal dma
>>> driver, spi-nand in your case
>>>
>>> drivers/pci/hotplug/hp-child1.c
>>>
>>> Legacy platform_driver binding and handling hotplug future as normal
>>> hotplug driver, spi-nor in your case.
>>>
>>> drivers/pci/host/rc-parent-pci.c
>>>
>>> static int rc_parent_pcie_probe_bridge(struct platform_device *pdev)
>>> {
>>>    // Generic rc handling (genric spi stuff)
>>>
>>>    // Hotplug handling (spi-nor)
>>>    - platform_device_alloc
>>>    - assign need resources
>>>    - register pdev using platform_device_add
>>>
>>>     // DMA handling (spi-nand)
>>>    - same as above
>>> }
>>>
>>> static const struct of_device_id rc_parent_pcie_match_table[] = {
>>>         {.compatible = "abc,rc-parent",},
>>>         {},
>>> };
>>>
>>> static struct platform_driver rc_parent_pcie_driver = {
>>>         .driver = {
>>>                    .name = "rc-parent",
>>>                    .of_match_table = of_match_ptr(rc_parent_pcie_match_table),
>>>         },
>>>         .probe = rc_parent_pcie_probe_bridge,
>>> };
>>> module_platform_driver(rc_parent_pcie_driver);
>>>
>>> I couldn't find any driver mainlined wrt this design, think more on
>>> GQSPI front, whether this design fits well or not.
>
> thanks!
> --
> Jagan | openedev.
> --
> To unsubscribe from this list: send the line "unsubscribe linux-kernel" in
> the body of a message to majordomo at vger.kernel.org
> More majordomo info at  http://vger.kernel.org/majordomo-info.html
> Please read the FAQ at  http://www.tux.org/lkml/


From javier at osg.samsung.com  Thu Aug 27 04:52:02 2015
From: javier at osg.samsung.com (Javier Martinez Canillas)
Date: Thu, 27 Aug 2015 13:52:02 +0200
Subject: [PATCH] rtc: Fix module autoload for OF platform drivers
Message-ID: <1440676322-19870-1-git-send-email-javier@osg.samsung.com>

These platform drivers have a OF device ID table but the OF module
alias information is not created so module autoloading won't work.

Signed-off-by: Javier Martinez Canillas <javier at osg.samsung.com>

---

 drivers/rtc/rtc-armada38x.c | 1 +
 drivers/rtc/rtc-coh901331.c | 1 +
 drivers/rtc/rtc-da9063.c    | 1 +
 drivers/rtc/rtc-moxart.c    | 1 +
 drivers/rtc/rtc-mpc5121.c   | 1 +
 drivers/rtc/rtc-mt6397.c    | 1 +
 drivers/rtc/rtc-mv.c        | 1 +
 drivers/rtc/rtc-vt8500.c    | 1 +
 8 files changed, 8 insertions(+)

diff --git a/drivers/rtc/rtc-armada38x.c b/drivers/rtc/rtc-armada38x.c
index 06c6bd5eab41..9a3f2a6f512e 100644
--- a/drivers/rtc/rtc-armada38x.c
+++ b/drivers/rtc/rtc-armada38x.c
@@ -295,6 +295,7 @@ static const struct of_device_id armada38x_rtc_of_match_table[] = {
 	{ .compatible = "marvell,armada-380-rtc", },
 	{}
 };
+MODULE_DEVICE_TABLE(of, armada38x_rtc_of_match_table);
 #endif
 
 static struct platform_driver armada38x_rtc_driver = {
diff --git a/drivers/rtc/rtc-coh901331.c b/drivers/rtc/rtc-coh901331.c
index 56343b2fbc68..101b7a240e0f 100644
--- a/drivers/rtc/rtc-coh901331.c
+++ b/drivers/rtc/rtc-coh901331.c
@@ -263,6 +263,7 @@ static const struct of_device_id coh901331_dt_match[] = {
 	{ .compatible = "stericsson,coh901331" },
 	{},
 };
+MODULE_DEVICE_TABLE(of, coh901331_dt_match);
 
 static struct platform_driver coh901331_driver = {
 	.driver = {
diff --git a/drivers/rtc/rtc-da9063.c b/drivers/rtc/rtc-da9063.c
index 5f38a5c84b56..00a8f7f4f87c 100644
--- a/drivers/rtc/rtc-da9063.c
+++ b/drivers/rtc/rtc-da9063.c
@@ -169,6 +169,7 @@ static const struct of_device_id da9063_compatible_reg_id_table[] = {
 	{ .compatible = "dlg,da9062-rtc", .data = &da9062_aa_regs },
 	{ },
 };
+MODULE_DEVICE_TABLE(of, da9063_compatible_reg_id_table);
 
 static void da9063_data_to_tm(u8 *data, struct rtc_time *tm,
 			      struct da9063_compatible_rtc *rtc)
diff --git a/drivers/rtc/rtc-moxart.c b/drivers/rtc/rtc-moxart.c
index 73759c9a4527..07b30a373a92 100644
--- a/drivers/rtc/rtc-moxart.c
+++ b/drivers/rtc/rtc-moxart.c
@@ -312,6 +312,7 @@ static const struct of_device_id moxart_rtc_match[] = {
 	{ .compatible = "moxa,moxart-rtc" },
 	{ },
 };
+MODULE_DEVICE_TABLE(of, moxart_rtc_match);
 
 static struct platform_driver moxart_rtc_driver = {
 	.probe	= moxart_rtc_probe,
diff --git a/drivers/rtc/rtc-mpc5121.c b/drivers/rtc/rtc-mpc5121.c
index 1767e18d5bd4..4ca4daa0b8f3 100644
--- a/drivers/rtc/rtc-mpc5121.c
+++ b/drivers/rtc/rtc-mpc5121.c
@@ -406,6 +406,7 @@ static const struct of_device_id mpc5121_rtc_match[] = {
 	{ .compatible = "fsl,mpc5200-rtc", },
 	{},
 };
+MODULE_DEVICE_TABLE(of, mpc5121_rtc_match);
 #endif
 
 static struct platform_driver mpc5121_rtc_driver = {
diff --git a/drivers/rtc/rtc-mt6397.c b/drivers/rtc/rtc-mt6397.c
index 30c926b36361..06a5c52b292f 100644
--- a/drivers/rtc/rtc-mt6397.c
+++ b/drivers/rtc/rtc-mt6397.c
@@ -402,6 +402,7 @@ static const struct of_device_id mt6397_rtc_of_match[] = {
 	{ .compatible = "mediatek,mt6397-rtc", },
 	{ }
 };
+MODULE_DEVICE_TABLE(of, mt6397_rtc_of_match);
 
 static struct platform_driver mtk_rtc_driver = {
 	.driver = {
diff --git a/drivers/rtc/rtc-mv.c b/drivers/rtc/rtc-mv.c
index 7f50d2ef7f6e..79bb28617d45 100644
--- a/drivers/rtc/rtc-mv.c
+++ b/drivers/rtc/rtc-mv.c
@@ -324,6 +324,7 @@ static const struct of_device_id rtc_mv_of_match_table[] = {
 	{ .compatible = "marvell,orion-rtc", },
 	{}
 };
+MODULE_DEVICE_TABLE(of, rtc_mv_of_match_table);
 #endif
 
 static struct platform_driver mv_rtc_driver = {
diff --git a/drivers/rtc/rtc-vt8500.c b/drivers/rtc/rtc-vt8500.c
index a58b6d17e6f0..27e896995e9b 100644
--- a/drivers/rtc/rtc-vt8500.c
+++ b/drivers/rtc/rtc-vt8500.c
@@ -271,6 +271,7 @@ static const struct of_device_id wmt_dt_ids[] = {
 	{ .compatible = "via,vt8500-rtc", },
 	{}
 };
+MODULE_DEVICE_TABLE(of, wmt_dt_ids);
 
 static struct platform_driver vt8500_rtc_driver = {
 	.probe		= vt8500_rtc_probe,
-- 
2.4.3



From eric.auger at linaro.org  Thu Aug 27 04:56:46 2015
From: eric.auger at linaro.org (Eric Auger)
Date: Thu, 27 Aug 2015 13:56:46 +0200
Subject: [PATCH v4 0/4] VFIO platform reset
In-Reply-To: <1434359385-19916-1-git-send-email-eric.auger@linaro.org>
References: <1434359385-19916-1-git-send-email-eric.auger@linaro.org>
Message-ID: <55DEFAFE.3000909@linaro.org>

Hi Marc,

I tested the series on Calxeda Midway with VFIO use case. Also reviewed
it again without finding anything new.

Tested-by: Eric Auger <eric.auger at linaro.org>
Reviewed-by: Eric Auger <eric.auger at linaro.org>

Best Regards

Eric

On 06/15/2015 11:09 AM, Eric Auger wrote:
> In situations where the userspace driver is stopped abnormally and the
> VFIO platform device is released, the assigned HW device currently is
> left running. As a consequence the HW device might continue issuing IRQs
> and performing DMA accesses.
> 
> On release, no physical IRQ handler is setup anymore. Also the DMA buffers
> are unmapped leading to IOMMU aborts. So there is no serious consequence.
> 
> However when assigning that HW device again to another userspace driver,
> this latter might face some unexpected IRQs and DMA accesses, which are
> the result of the previous assignment.
> 
> In virtualization use-case, a VM newly granted with that HW device may be
> impacted by the assignment of that device to a previous VM:
> - IRQs may be injected very early when booting the new guest, even before
>   the guest driver has initialized leading to possible driver state
>   inconsistency.
> - DMA accesses may hit the newly mapped VM address space at addresses that
>   may jeopardize the integrity of the newly installed VM.
> 
> Obviously the criticity depends on the assigned HW device.
> 
> As opposed to PCI, there is no standard mechanism to reset the platform
> device.
> 
> This series proposes to implement device specific reset functions in
> separate in-kernel vfio reset modules. The vfio-platform driver holds
> a whitelist of implemented triplets (compat string, module name,
> reset function name). When the vfio-platform driver is probed it identifies
> the fellow reset module/function matching the compat string of the
> device, if any, and forces the load of this reset module.
> 
> A first reset module is provided: the vfio-platform-calxedaxgmac
> module which implements a basic reset for the Calxeda xgmac.
> 
> The series can be found at
> https://git.linaro.org/people/eric.auger/linux.git/shortlog/refs/heads/v4.1-rc8-reset-v4
> 
> History:
> v3 -> v4:
> - fix the commit message of "VFIO: platform: add reset struct and lookup table"
> 
> v2 -> v3:
> - remove void module_init/exit functions in calxeda reset module
> - remove enum vfio_platform_reset_type
> - for reset lookup, use ARRAY_SIZE
> - in reset put use symbol_put_addr
> 
> v1 -> v2:
> - much simplified compared to v1 although principle of external modules is
>   kept: removed mechanism of dynamic registration of reset functions
> - list is replaced by whitelist lookup table
> - name of the reset function also stored in the lookup table
> - autoload of reset modules
> 
> RFC -> PATCH v1:
> - solution now based on a lookup list instead of specialized driver
> 
> 
> Eric Auger (4):
>   VFIO: platform: add reset struct and lookup table
>   VFIO: platform: add reset callback
>   VFIO: platform: populate the reset function on probe
>   VFIO: platform: Calxeda xgmac reset module
> 
>  drivers/vfio/platform/Kconfig                      |  2 +
>  drivers/vfio/platform/Makefile                     |  2 +
>  drivers/vfio/platform/reset/Kconfig                |  7 ++
>  drivers/vfio/platform/reset/Makefile               |  5 ++
>  .../platform/reset/vfio_platform_calxedaxgmac.c    | 86 ++++++++++++++++++++++
>  drivers/vfio/platform/vfio_platform_common.c       | 60 ++++++++++++++-
>  drivers/vfio/platform/vfio_platform_private.h      |  7 ++
>  7 files changed, 166 insertions(+), 3 deletions(-)
>  create mode 100644 drivers/vfio/platform/reset/Kconfig
>  create mode 100644 drivers/vfio/platform/reset/Makefile
>  create mode 100644 drivers/vfio/platform/reset/vfio_platform_calxedaxgmac.c
> 



From andrew at lunn.ch  Thu Aug 27 05:09:58 2015
From: andrew at lunn.ch (Andrew Lunn)
Date: Thu, 27 Aug 2015 14:09:58 +0200
Subject: [PATCH] rtc: Fix module autoload for OF platform drivers
In-Reply-To: <1440676322-19870-1-git-send-email-javier@osg.samsung.com>
References: <1440676322-19870-1-git-send-email-javier@osg.samsung.com>
Message-ID: <20150827120958.GD8094@lunn.ch>

On Thu, Aug 27, 2015 at 01:52:02PM +0200, Javier Martinez Canillas wrote:
> These platform drivers have a OF device ID table but the OF module
> alias information is not created so module autoloading won't work.
> 
> Signed-off-by: Javier Martinez Canillas <javier at osg.samsung.com>

Hi Javier

Acked-by: Andrew Lunn <andrew at lunn.ch>

for mv and armada38x.

Thanks
	Andrew
> 
> ---
> 
>  drivers/rtc/rtc-armada38x.c | 1 +
>  drivers/rtc/rtc-coh901331.c | 1 +
>  drivers/rtc/rtc-da9063.c    | 1 +
>  drivers/rtc/rtc-moxart.c    | 1 +
>  drivers/rtc/rtc-mpc5121.c   | 1 +
>  drivers/rtc/rtc-mt6397.c    | 1 +
>  drivers/rtc/rtc-mv.c        | 1 +
>  drivers/rtc/rtc-vt8500.c    | 1 +
>  8 files changed, 8 insertions(+)
> 
> diff --git a/drivers/rtc/rtc-armada38x.c b/drivers/rtc/rtc-armada38x.c
> index 06c6bd5eab41..9a3f2a6f512e 100644
> --- a/drivers/rtc/rtc-armada38x.c
> +++ b/drivers/rtc/rtc-armada38x.c
> @@ -295,6 +295,7 @@ static const struct of_device_id armada38x_rtc_of_match_table[] = {
>  	{ .compatible = "marvell,armada-380-rtc", },
>  	{}
>  };
> +MODULE_DEVICE_TABLE(of, armada38x_rtc_of_match_table);
>  #endif
>  
>  static struct platform_driver armada38x_rtc_driver = {
> diff --git a/drivers/rtc/rtc-coh901331.c b/drivers/rtc/rtc-coh901331.c
> index 56343b2fbc68..101b7a240e0f 100644
> --- a/drivers/rtc/rtc-coh901331.c
> +++ b/drivers/rtc/rtc-coh901331.c
> @@ -263,6 +263,7 @@ static const struct of_device_id coh901331_dt_match[] = {
>  	{ .compatible = "stericsson,coh901331" },
>  	{},
>  };
> +MODULE_DEVICE_TABLE(of, coh901331_dt_match);
>  
>  static struct platform_driver coh901331_driver = {
>  	.driver = {
> diff --git a/drivers/rtc/rtc-da9063.c b/drivers/rtc/rtc-da9063.c
> index 5f38a5c84b56..00a8f7f4f87c 100644
> --- a/drivers/rtc/rtc-da9063.c
> +++ b/drivers/rtc/rtc-da9063.c
> @@ -169,6 +169,7 @@ static const struct of_device_id da9063_compatible_reg_id_table[] = {
>  	{ .compatible = "dlg,da9062-rtc", .data = &da9062_aa_regs },
>  	{ },
>  };
> +MODULE_DEVICE_TABLE(of, da9063_compatible_reg_id_table);
>  
>  static void da9063_data_to_tm(u8 *data, struct rtc_time *tm,
>  			      struct da9063_compatible_rtc *rtc)
> diff --git a/drivers/rtc/rtc-moxart.c b/drivers/rtc/rtc-moxart.c
> index 73759c9a4527..07b30a373a92 100644
> --- a/drivers/rtc/rtc-moxart.c
> +++ b/drivers/rtc/rtc-moxart.c
> @@ -312,6 +312,7 @@ static const struct of_device_id moxart_rtc_match[] = {
>  	{ .compatible = "moxa,moxart-rtc" },
>  	{ },
>  };
> +MODULE_DEVICE_TABLE(of, moxart_rtc_match);
>  
>  static struct platform_driver moxart_rtc_driver = {
>  	.probe	= moxart_rtc_probe,
> diff --git a/drivers/rtc/rtc-mpc5121.c b/drivers/rtc/rtc-mpc5121.c
> index 1767e18d5bd4..4ca4daa0b8f3 100644
> --- a/drivers/rtc/rtc-mpc5121.c
> +++ b/drivers/rtc/rtc-mpc5121.c
> @@ -406,6 +406,7 @@ static const struct of_device_id mpc5121_rtc_match[] = {
>  	{ .compatible = "fsl,mpc5200-rtc", },
>  	{},
>  };
> +MODULE_DEVICE_TABLE(of, mpc5121_rtc_match);
>  #endif
>  
>  static struct platform_driver mpc5121_rtc_driver = {
> diff --git a/drivers/rtc/rtc-mt6397.c b/drivers/rtc/rtc-mt6397.c
> index 30c926b36361..06a5c52b292f 100644
> --- a/drivers/rtc/rtc-mt6397.c
> +++ b/drivers/rtc/rtc-mt6397.c
> @@ -402,6 +402,7 @@ static const struct of_device_id mt6397_rtc_of_match[] = {
>  	{ .compatible = "mediatek,mt6397-rtc", },
>  	{ }
>  };
> +MODULE_DEVICE_TABLE(of, mt6397_rtc_of_match);
>  
>  static struct platform_driver mtk_rtc_driver = {
>  	.driver = {
> diff --git a/drivers/rtc/rtc-mv.c b/drivers/rtc/rtc-mv.c
> index 7f50d2ef7f6e..79bb28617d45 100644
> --- a/drivers/rtc/rtc-mv.c
> +++ b/drivers/rtc/rtc-mv.c
> @@ -324,6 +324,7 @@ static const struct of_device_id rtc_mv_of_match_table[] = {
>  	{ .compatible = "marvell,orion-rtc", },
>  	{}
>  };
> +MODULE_DEVICE_TABLE(of, rtc_mv_of_match_table);
>  #endif
>  
>  static struct platform_driver mv_rtc_driver = {
> diff --git a/drivers/rtc/rtc-vt8500.c b/drivers/rtc/rtc-vt8500.c
> index a58b6d17e6f0..27e896995e9b 100644
> --- a/drivers/rtc/rtc-vt8500.c
> +++ b/drivers/rtc/rtc-vt8500.c
> @@ -271,6 +271,7 @@ static const struct of_device_id wmt_dt_ids[] = {
>  	{ .compatible = "via,vt8500-rtc", },
>  	{}
>  };
> +MODULE_DEVICE_TABLE(of, wmt_dt_ids);
>  
>  static struct platform_driver vt8500_rtc_driver = {
>  	.probe		= vt8500_rtc_probe,
> -- 
> 2.4.3
> 


From ryabinin.a.a at gmail.com  Thu Aug 27 05:20:34 2015
From: ryabinin.a.a at gmail.com (Andrey Ryabinin)
Date: Thu, 27 Aug 2015 15:20:34 +0300
Subject: [PATCH] rtc: Fix module autoload for rtc-{ab8500, max8997,
 s5m} drivers
In-Reply-To: <1440671672-26590-1-git-send-email-javier@osg.samsung.com>
References: <1440671672-26590-1-git-send-email-javier@osg.samsung.com>
Message-ID: <CAPAsAGyrEm--=WfGB4wSFSXE8HZpp+HDuV=p4JmFbV-X2keQCg@mail.gmail.com>

2015-08-27 13:34 GMT+03:00 Javier Martinez Canillas <javier at osg.samsung.com>:
> These platform drivers have a platform device ID table but the module
> alias information is not created so module autoloading will not work.
>
> Signed-off-by: Javier Martinez Canillas <javier at osg.samsung.com>
>
> ---
>
>  drivers/rtc/rtc-ab8500.c  | 1 +
>  drivers/rtc/rtc-max8997.c | 1 +
>  drivers/rtc/rtc-s5m.c     | 1 +
>  3 files changed, 3 insertions(+)
>
> diff --git a/drivers/rtc/rtc-ab8500.c b/drivers/rtc/rtc-ab8500.c
> index 133d2e2e1a25..8537d1e3a995 100644
> --- a/drivers/rtc/rtc-ab8500.c
> +++ b/drivers/rtc/rtc-ab8500.c
> @@ -446,6 +446,7 @@ static const struct platform_device_id ab85xx_rtc_ids[] = {
>         { "ab8500-rtc", (kernel_ulong_t)&ab8500_rtc_ops, },
>         { "ab8540-rtc", (kernel_ulong_t)&ab8540_rtc_ops, },

Completely irrelevant, but this array should have an empty terminating element.

>  };
> +MODULE_DEVICE_TABLE(platform, ab85xx_rtc_ids);
>


From javier at osg.samsung.com  Thu Aug 27 05:23:15 2015
From: javier at osg.samsung.com (Javier Martinez Canillas)
Date: Thu, 27 Aug 2015 14:23:15 +0200
Subject: [PATCH] rtc: Fix module autoload for rtc-{ab8500,max8997,s5m}
 drivers
In-Reply-To: <CAPAsAGyrEm--=WfGB4wSFSXE8HZpp+HDuV=p4JmFbV-X2keQCg@mail.gmail.com>
References: <1440671672-26590-1-git-send-email-javier@osg.samsung.com>
 <CAPAsAGyrEm--=WfGB4wSFSXE8HZpp+HDuV=p4JmFbV-X2keQCg@mail.gmail.com>
Message-ID: <55DF0133.2070009@osg.samsung.com>

Hello Andrey,

On 08/27/2015 02:20 PM, Andrey Ryabinin wrote:
> 2015-08-27 13:34 GMT+03:00 Javier Martinez Canillas <javier at osg.samsung.com>:
>> These platform drivers have a platform device ID table but the module
>> alias information is not created so module autoloading will not work.
>>
>> Signed-off-by: Javier Martinez Canillas <javier at osg.samsung.com>
>>
>> ---
>>
>>  drivers/rtc/rtc-ab8500.c  | 1 +
>>  drivers/rtc/rtc-max8997.c | 1 +
>>  drivers/rtc/rtc-s5m.c     | 1 +
>>  3 files changed, 3 insertions(+)
>>
>> diff --git a/drivers/rtc/rtc-ab8500.c b/drivers/rtc/rtc-ab8500.c
>> index 133d2e2e1a25..8537d1e3a995 100644
>> --- a/drivers/rtc/rtc-ab8500.c
>> +++ b/drivers/rtc/rtc-ab8500.c
>> @@ -446,6 +446,7 @@ static const struct platform_device_id ab85xx_rtc_ids[] = {
>>         { "ab8500-rtc", (kernel_ulong_t)&ab8500_rtc_ops, },
>>         { "ab8540-rtc", (kernel_ulong_t)&ab8540_rtc_ops, },
> 
> Completely irrelevant, but this array should have an empty terminating element.
>

You are right, it's missing a sentinel indeed. But
that change should be done in a separate patch.
 
>>  };
>> +MODULE_DEVICE_TABLE(platform, ab85xx_rtc_ids);
>>

Best regards,
-- 
Javier Martinez Canillas
Open Source Group
Samsung Research America


From peter.griffin at linaro.org  Thu Aug 27 05:29:30 2015
From: peter.griffin at linaro.org (Peter Griffin)
Date: Thu, 27 Aug 2015 13:29:30 +0100
Subject: [PATCH v2 0/5] [media] c8sectpfe: Various fixups
Message-ID: <1440678575-21646-1-git-send-email-peter.griffin@linaro.org>

Hi Mauro,

This series includes a couple of fixes for the c8sectpfe Linux dvb driver.

One was caused by omitting a patch from the original c8sectpfe series which
defined the ssc2 and ssc3 dt nodes, which was then used by the later DT patch.

This patch is included, along with the original patch which you reverted.

Also Valentin Rothberg spotted LIBELF32 Kconfig symbol I was selecting in the
Kconfig, this isn't required upstream and is left over legacy so I've removed
it.

Sorry for the delay in sending these fixes, I've been on holiday for the last
3 weeks.

Changes since v1:
 - Various formating patches to DT node
 - Update to reset-gpios
 - Use GPIO_ACTIVE_HIGH, GIC_SPI and IRQ_TYPE_NONE defines

kind regards,

Peter.

Peter Griffin (5):
  ARM: DT: STi: stihxxx-b2120: Add pulse-width properties to ssc2 & ssc3
  ARM: DT: STi: STiH407: Add c8sectpfe LinuxDVB DT node.
  [media] c8sectpfe: Remove select on undefined LIBELF_32
  [media] c8sectpfe: Update binding to reset-gpios
  [media] c8sectpfe: Update DT binding doc with some minor fixes

 .../bindings/media/stih407-c8sectpfe.txt           | 22 +++++------
 arch/arm/boot/dts/stihxxx-b2120.dtsi               | 44 +++++++++++++++++++++-
 drivers/media/platform/sti/c8sectpfe/Kconfig       |  1 -
 .../media/platform/sti/c8sectpfe/c8sectpfe-core.c  |  2 +-
 4 files changed, 53 insertions(+), 16 deletions(-)

-- 
1.9.1



From peter.griffin at linaro.org  Thu Aug 27 05:29:31 2015
From: peter.griffin at linaro.org (Peter Griffin)
Date: Thu, 27 Aug 2015 13:29:31 +0100
Subject: [PATCH v2 1/5] ARM: DT: STi: stihxxx-b2120: Add pulse-width
 properties to ssc2 & ssc3
In-Reply-To: <1440678575-21646-1-git-send-email-peter.griffin@linaro.org>
References: <1440678575-21646-1-git-send-email-peter.griffin@linaro.org>
Message-ID: <1440678575-21646-2-git-send-email-peter.griffin@linaro.org>

Adding these properties makes the I2C bus to the demodulators much
more reliable, and we no longer suffer from I2C errors when tuning.

Signed-off-by: Peter Griffin <peter.griffin at linaro.org>
---
 arch/arm/boot/dts/stihxxx-b2120.dtsi | 10 ++++++++--
 1 file changed, 8 insertions(+), 2 deletions(-)

diff --git a/arch/arm/boot/dts/stihxxx-b2120.dtsi b/arch/arm/boot/dts/stihxxx-b2120.dtsi
index f589fe4..62994ae 100644
--- a/arch/arm/boot/dts/stihxxx-b2120.dtsi
+++ b/arch/arm/boot/dts/stihxxx-b2120.dtsi
@@ -27,12 +27,18 @@
 			};
 		};
 
-		i2c at 9842000 {
+		ssc2: i2c at 9842000 {
 			status = "okay";
+			clock-frequency = <100000>;
+			st,i2c-min-scl-pulse-width-us = <0>;
+			st,i2c-min-sda-pulse-width-us = <5>;
 		};
 
-		i2c at 9843000 {
+		ssc3: i2c at 9843000 {
 			status = "okay";
+			clock-frequency = <100000>;
+			st,i2c-min-scl-pulse-width-us = <0>;
+			st,i2c-min-sda-pulse-width-us = <5>;
 		};
 
 		i2c at 9844000 {
-- 
1.9.1



From peter.griffin at linaro.org  Thu Aug 27 05:29:32 2015
From: peter.griffin at linaro.org (Peter Griffin)
Date: Thu, 27 Aug 2015 13:29:32 +0100
Subject: [PATCH v2 2/5] ARM: DT: STi: STiH407: Add c8sectpfe LinuxDVB DT node.
In-Reply-To: <1440678575-21646-1-git-send-email-peter.griffin@linaro.org>
References: <1440678575-21646-1-git-send-email-peter.griffin@linaro.org>
Message-ID: <1440678575-21646-3-git-send-email-peter.griffin@linaro.org>

This patch adds in the required DT node for the c8sectpfe
Linux DVB demux driver which allows the tsin channels
to be used on an upstream kernel.

Signed-off-by: Peter Griffin <peter.griffin at linaro.org>
---
 arch/arm/boot/dts/stihxxx-b2120.dtsi | 34 ++++++++++++++++++++++++++++++++++
 1 file changed, 34 insertions(+)

diff --git a/arch/arm/boot/dts/stihxxx-b2120.dtsi b/arch/arm/boot/dts/stihxxx-b2120.dtsi
index 62994ae..c014173 100644
--- a/arch/arm/boot/dts/stihxxx-b2120.dtsi
+++ b/arch/arm/boot/dts/stihxxx-b2120.dtsi
@@ -6,6 +6,9 @@
  * it under the terms of the GNU General Public License version 2 as
  * published by the Free Software Foundation.
  */
+
+#include <dt-bindings/clock/stih407-clks.h>
+#include <dt-bindings/media/c8sectpfe.h>
 / {
 	soc {
 		sbc_serial0: serial at 9530000 {
@@ -85,5 +88,36 @@
 			status = "okay";
 		};
 
+		demux at 08a20000 {
+			compatible	= "st,stih407-c8sectpfe";
+			status		= "okay";
+			reg		= <0x08a20000 0x10000>,
+					  <0x08a00000 0x4000>;
+			reg-names	= "c8sectpfe", "c8sectpfe-ram";
+			interrupts	= <GIC_SPI 34 IRQ_TYPE_NONE>,
+					  <GIC_SPI 35 IRQ_TYPE_NONE>;
+			interrupt-names	= "c8sectpfe-error-irq",
+					  "c8sectpfe-idle-irq";
+			pinctrl-names	= "tsin0-serial",
+					  "tsin0-parallel",
+					  "tsin3-serial",
+					  "tsin4-serial",
+					  "tsin5-serial";
+			pinctrl-0	= <&pinctrl_tsin0_serial>;
+			pinctrl-1	= <&pinctrl_tsin0_parallel>;
+			pinctrl-2	= <&pinctrl_tsin3_serial>;
+			pinctrl-3	= <&pinctrl_tsin4_serial_alt3>;
+			pinctrl-4	= <&pinctrl_tsin5_serial_alt1>;
+			clock-names	= "c8sectpfe";
+			clocks		= <&clk_s_c0_flexgen CLK_PROC_STFE>;
+			/* tsin0 is TSA on NIMA */
+			tsin0: port at 0 {
+				tsin-num	= <0>;
+				serial-not-parallel;
+				i2c-bus		= <&ssc2>;
+				rst-gpio	= <&pio15 4 0>;
+				dvb-card	= <STV0367_TDA18212_NIMA_1>;
+			};
+		};
 	};
 };
-- 
1.9.1



From peter.griffin at linaro.org  Thu Aug 27 05:29:33 2015
From: peter.griffin at linaro.org (Peter Griffin)
Date: Thu, 27 Aug 2015 13:29:33 +0100
Subject: [PATCH v2 3/5] [media] c8sectpfe: Remove select on undefined LIBELF_32
In-Reply-To: <1440678575-21646-1-git-send-email-peter.griffin@linaro.org>
References: <1440678575-21646-1-git-send-email-peter.griffin@linaro.org>
Message-ID: <1440678575-21646-4-git-send-email-peter.griffin@linaro.org>

LIBELF_32 is not defined in Kconfig, and is left over legacy
which is not required in the upstream driver, so remove it.

Signed-off-by: Peter Griffin <peter.griffin at linaro.org>
Suggested-by: Valentin Rothberg <valentinrothberg at gmail.com>
---
 drivers/media/platform/sti/c8sectpfe/Kconfig | 1 -
 1 file changed, 1 deletion(-)

diff --git a/drivers/media/platform/sti/c8sectpfe/Kconfig b/drivers/media/platform/sti/c8sectpfe/Kconfig
index d1bfd4c..b9ec667 100644
--- a/drivers/media/platform/sti/c8sectpfe/Kconfig
+++ b/drivers/media/platform/sti/c8sectpfe/Kconfig
@@ -1,7 +1,6 @@
 config DVB_C8SECTPFE
 	tristate "STMicroelectronics C8SECTPFE DVB support"
 	depends on DVB_CORE && I2C && (ARCH_STI || ARCH_MULTIPLATFORM)
-	select LIBELF_32
 	select FW_LOADER
 	select FW_LOADER_USER_HELPER_FALLBACK
 	select DEBUG_FS
-- 
1.9.1



From peter.griffin at linaro.org  Thu Aug 27 05:29:34 2015
From: peter.griffin at linaro.org (Peter Griffin)
Date: Thu, 27 Aug 2015 13:29:34 +0100
Subject: [PATCH v2 4/5] [media] c8sectpfe: Update binding to reset-gpios
In-Reply-To: <1440678575-21646-1-git-send-email-peter.griffin@linaro.org>
References: <1440678575-21646-1-git-send-email-peter.griffin@linaro.org>
Message-ID: <1440678575-21646-5-git-send-email-peter.griffin@linaro.org>

gpio.txt documents that GPIO properties should be named
"[<name>-]gpios", with <name> being the purpose of this
GPIO for the device.

This change has been done as one atomic commit.

Signed-off-by: Peter Griffin <peter.griffin at linaro.org>
---
 Documentation/devicetree/bindings/media/stih407-c8sectpfe.txt | 6 +++---
 arch/arm/boot/dts/stihxxx-b2120.dtsi                          | 4 ++--
 drivers/media/platform/sti/c8sectpfe/c8sectpfe-core.c         | 2 +-
 3 files changed, 6 insertions(+), 6 deletions(-)

diff --git a/Documentation/devicetree/bindings/media/stih407-c8sectpfe.txt b/Documentation/devicetree/bindings/media/stih407-c8sectpfe.txt
index d4def76..e70d840 100644
--- a/Documentation/devicetree/bindings/media/stih407-c8sectpfe.txt
+++ b/Documentation/devicetree/bindings/media/stih407-c8sectpfe.txt
@@ -35,7 +35,7 @@ Required properties (tsin (child) node):
 
 - tsin-num	: tsin id of the InputBlock (must be between 0 to 6)
 - i2c-bus	: phandle to the I2C bus DT node which the demodulators & tuners on this tsin channel are connected.
-- rst-gpio	: reset gpio for this tsin channel.
+- reset-gpios	: reset gpio for this tsin channel.
 
 Optional properties (tsin (child) node):
 
@@ -75,7 +75,7 @@ Example:
 			tsin-num		= <0>;
 			serial-not-parallel;
 			i2c-bus			= <&ssc2>;
-			rst-gpio		= <&pio15 4 0>;
+			reset-gpios		= <&pio15 4 GPIO_ACTIVE_HIGH>;
 			dvb-card		= <STV0367_TDA18212_NIMA_1>;
 		};
 
@@ -83,7 +83,7 @@ Example:
 			tsin-num		= <3>;
 			serial-not-parallel;
 			i2c-bus			= <&ssc3>;
-			rst-gpio		= <&pio15 7 0>;
+			reset-gpios		= <&pio15 7 GPIO_ACTIVE_HIGH>;
 			dvb-card		= <STV0367_TDA18212_NIMB_1>;
 		};
 	};
diff --git a/arch/arm/boot/dts/stihxxx-b2120.dtsi b/arch/arm/boot/dts/stihxxx-b2120.dtsi
index c014173..f932bfd 100644
--- a/arch/arm/boot/dts/stihxxx-b2120.dtsi
+++ b/arch/arm/boot/dts/stihxxx-b2120.dtsi
@@ -6,8 +6,8 @@
  * it under the terms of the GNU General Public License version 2 as
  * published by the Free Software Foundation.
  */
-
 #include <dt-bindings/clock/stih407-clks.h>
+#include <dt-bindings/gpio/gpio.h>
 #include <dt-bindings/media/c8sectpfe.h>
 / {
 	soc {
@@ -115,7 +115,7 @@
 				tsin-num	= <0>;
 				serial-not-parallel;
 				i2c-bus		= <&ssc2>;
-				rst-gpio	= <&pio15 4 0>;
+				reset-gpios	= <&pio15 4 GPIO_ACTIVE_HIGH>;
 				dvb-card	= <STV0367_TDA18212_NIMA_1>;
 			};
 		};
diff --git a/drivers/media/platform/sti/c8sectpfe/c8sectpfe-core.c b/drivers/media/platform/sti/c8sectpfe/c8sectpfe-core.c
index 3a91093..c691e13 100644
--- a/drivers/media/platform/sti/c8sectpfe/c8sectpfe-core.c
+++ b/drivers/media/platform/sti/c8sectpfe/c8sectpfe-core.c
@@ -822,7 +822,7 @@ static int c8sectpfe_probe(struct platform_device *pdev)
 		}
 		of_node_put(i2c_bus);
 
-		tsin->rst_gpio = of_get_named_gpio(child, "rst-gpio", 0);
+		tsin->rst_gpio = of_get_named_gpio(child, "reset-gpios", 0);
 
 		ret = gpio_is_valid(tsin->rst_gpio);
 		if (!ret) {
-- 
1.9.1



From peter.griffin at linaro.org  Thu Aug 27 05:29:35 2015
From: peter.griffin at linaro.org (Peter Griffin)
Date: Thu, 27 Aug 2015 13:29:35 +0100
Subject: [PATCH v2 5/5] [media] c8sectpfe: Update DT binding doc with some
 minor fixes
In-Reply-To: <1440678575-21646-1-git-send-email-peter.griffin@linaro.org>
References: <1440678575-21646-1-git-send-email-peter.griffin@linaro.org>
Message-ID: <1440678575-21646-6-git-send-email-peter.griffin@linaro.org>

Signed-off-by: Peter Griffin <peter.griffin at linaro.org>
---
 .../devicetree/bindings/media/stih407-c8sectpfe.txt      | 16 +++++++---------
 1 file changed, 7 insertions(+), 9 deletions(-)

diff --git a/Documentation/devicetree/bindings/media/stih407-c8sectpfe.txt b/Documentation/devicetree/bindings/media/stih407-c8sectpfe.txt
index e70d840..5d6438c 100644
--- a/Documentation/devicetree/bindings/media/stih407-c8sectpfe.txt
+++ b/Documentation/devicetree/bindings/media/stih407-c8sectpfe.txt
@@ -55,21 +55,20 @@ Example:
 		status = "okay";
 		reg = <0x08a20000 0x10000>, <0x08a00000 0x4000>;
 		reg-names = "stfe", "stfe-ram";
-		interrupts = <0 34 0>, <0 35 0>;
+		interrupts = <GIC_SPI 34 IRQ_TYPE_NONE>, <GIC_SPI 35 IRQ_TYPE_NONE>;
 		interrupt-names = "stfe-error-irq", "stfe-idle-irq";
-
-		pinctrl-names	= "tsin0-serial", "tsin0-parallel", "tsin3-serial",
-				"tsin4-serial", "tsin5-serial";
-
+		pinctrl-names	= "tsin0-serial",
+				  "tsin0-parallel",
+				  "tsin3-serial",
+				  "tsin4-serial",
+				  "tsin5-serial";
 		pinctrl-0	= <&pinctrl_tsin0_serial>;
 		pinctrl-1	= <&pinctrl_tsin0_parallel>;
 		pinctrl-2	= <&pinctrl_tsin3_serial>;
 		pinctrl-3	= <&pinctrl_tsin4_serial_alt3>;
 		pinctrl-4	= <&pinctrl_tsin5_serial_alt1>;
-
 		clocks = <&clk_s_c0_flexgen CLK_PROC_STFE>;
-		clock-names = "stfe";
-
+		clock-names = "c8sectpfe";
 		/* tsin0 is TSA on NIMA */
 		tsin0: port at 0 {
 			tsin-num		= <0>;
@@ -78,7 +77,6 @@ Example:
 			reset-gpios		= <&pio15 4 GPIO_ACTIVE_HIGH>;
 			dvb-card		= <STV0367_TDA18212_NIMA_1>;
 		};
-
 		tsin3: port at 3 {
 			tsin-num		= <3>;
 			serial-not-parallel;
-- 
1.9.1



From gabriel.fernandez at linaro.org  Thu Aug 27 05:34:14 2015
From: gabriel.fernandez at linaro.org (Gabriel Fernandez)
Date: Thu, 27 Aug 2015 14:34:14 +0200
Subject: [PATCH v4 1/4] ARM: STi: Kconfig update for PCIe support
In-Reply-To: <1440678857-27118-1-git-send-email-gabriel.fernandez@linaro.org>
References: <1440678857-27118-1-git-send-email-gabriel.fernandez@linaro.org>
Message-ID: <1440678857-27118-2-git-send-email-gabriel.fernandez@linaro.org>

Update Kconfig:
- MIGHT_HAVE_PCI
- PCI_DOMAINS

Signed-off-by: Fabrice Gasnier <fabrice.gasnier at st.com>
---
 arch/arm/mach-sti/Kconfig | 2 ++
 1 file changed, 2 insertions(+)

diff --git a/arch/arm/mach-sti/Kconfig b/arch/arm/mach-sti/Kconfig
index 125865d..5f99e93 100644
--- a/arch/arm/mach-sti/Kconfig
+++ b/arch/arm/mach-sti/Kconfig
@@ -9,6 +9,8 @@ menuconfig ARCH_STI
 	select ARCH_HAS_RESET_CONTROLLER
 	select HAVE_ARM_SCU if SMP
 	select ARCH_REQUIRE_GPIOLIB
+	select PCI_DOMAINS if PCI
+	select MIGHT_HAVE_PCI
 	select ARM_ERRATA_754322
 	select ARM_ERRATA_764369 if SMP
 	select ARM_ERRATA_775420
-- 
1.9.1



From gabriel.fernandez at linaro.org  Thu Aug 27 05:34:16 2015
From: gabriel.fernandez at linaro.org (Gabriel Fernandez)
Date: Thu, 27 Aug 2015 14:34:16 +0200
Subject: [PATCH v4 3/4] PCI: st: Provide support for the sti PCIe controller
In-Reply-To: <1440678857-27118-1-git-send-email-gabriel.fernandez@linaro.org>
References: <1440678857-27118-1-git-send-email-gabriel.fernandez@linaro.org>
Message-ID: <1440678857-27118-4-git-send-email-gabriel.fernandez@linaro.org>

sti pcie is built around a Synopsis Designware PCIe IP.

Signed-off-by: Fabrice Gasnier <fabrice.gasnier at st.com>
Signed-off-by: Gabriel Fernandez <gabriel.fernandez at linaro.org>
---
 drivers/pci/host/Kconfig  |   9 +
 drivers/pci/host/Makefile |   1 +
 drivers/pci/host/pci-st.c | 583 ++++++++++++++++++++++++++++++++++++++++++++++
 3 files changed, 593 insertions(+)
 create mode 100644 drivers/pci/host/pci-st.c

diff --git a/drivers/pci/host/Kconfig b/drivers/pci/host/Kconfig
index c132bdd..db56b8f 100644
--- a/drivers/pci/host/Kconfig
+++ b/drivers/pci/host/Kconfig
@@ -145,4 +145,13 @@ config PCIE_IPROC_BCMA
 	  Say Y here if you want to use the Broadcom iProc PCIe controller
 	  through the BCMA bus interface
 
+config PCI_ST
+	bool "ST PCIe controller"
+	depends on ARCH_STI || (ARM && COMPILE_TEST)
+	select PCIE_DW
+	help
+	  Enable PCIe controller support on ST Socs. This controller is based
+	  on Designware hardware and therefore the driver re-uses the
+	  Designware core functions to implement the driver.
+
 endmenu
diff --git a/drivers/pci/host/Makefile b/drivers/pci/host/Makefile
index 140d66f..c4024fa 100644
--- a/drivers/pci/host/Makefile
+++ b/drivers/pci/host/Makefile
@@ -17,3 +17,4 @@ obj-$(CONFIG_PCI_VERSATILE) += pci-versatile.o
 obj-$(CONFIG_PCIE_IPROC) += pcie-iproc.o
 obj-$(CONFIG_PCIE_IPROC_PLATFORM) += pcie-iproc-platform.o
 obj-$(CONFIG_PCIE_IPROC_BCMA) += pcie-iproc-bcma.o
+obj-$(CONFIG_PCI_ST) += pci-st.o
diff --git a/drivers/pci/host/pci-st.c b/drivers/pci/host/pci-st.c
new file mode 100644
index 0000000..0e7aaa2
--- /dev/null
+++ b/drivers/pci/host/pci-st.c
@@ -0,0 +1,583 @@
+/*
+ * Copyright (C) 2014 STMicroelectronics
+ *
+ * STMicroelectronics PCI express Driver for sti SoCs.
+ * ST PCIe IPs are built around a Synopsys IP Core.
+ *
+ * Author: Fabrice Gasnier <fabrice.gasnier at st.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.
+ *
+ */
+
+#include <linux/delay.h>
+#include <linux/interrupt.h>
+#include <linux/mfd/syscon.h>
+#include <linux/module.h>
+#include <linux/of_address.h>
+#include <linux/of_gpio.h>
+#include <linux/of_pci.h>
+#include <linux/of_platform.h>
+#include <linux/phy/phy.h>
+#include <linux/regmap.h>
+#include <linux/reset.h>
+
+#include "pcie-designware.h"
+
+#define TRANSLATION_CONTROL		0x900
+/* Controls if area is inclusive or exclusive */
+#define RC_PASS_ADDR_RANGE		BIT(1)
+
+/* Base of area reserved for config accesses. Fixed size of 64K. */
+#define CFG_BASE_ADDRESS		0x92c
+#define CFG_REGION_SIZE			65536
+#define CFG_SPACE1_OFFSET		0x1000
+
+/* First 4K of config space has this BDF (bus,device,function) */
+#define FUNC0_BDF_NUM			0x930
+
+/* Mem regions */
+#define IN0_MEM_ADDR_START		0x964
+#define IN0_MEM_ADDR_LIMIT		0x968
+#define IN1_MEM_ADDR_START		0x974
+#define IN1_MEM_ADDR_LIMIT		0x978
+
+/* This actually contains the LTSSM state machine state */
+#define PORT_LOGIC_DEBUG_REG_0		0x728
+
+/* LTSSM state machine values	*/
+#define DEBUG_REG_0_LTSSM_MASK		0x1f
+#define S_DETECT_QUIET			0x00
+#define S_DETECT_ACT			0x01
+#define S_POLL_ACTIVE			0x02
+#define S_POLL_COMPLIANCE		0x03
+#define S_POLL_CONFIG			0x04
+#define S_PRE_DETECT_QUIET		0x05
+#define S_DETECT_WAIT			0x06
+#define S_CFG_LINKWD_START		0x07
+#define S_CFG_LINKWD_ACEPT		0x08
+#define S_CFG_LANENUM_WAIT		0x09
+#define S_CFG_LANENUM_ACEPT		0x0A
+#define S_CFG_COMPLETE			0x0B
+#define S_CFG_IDLE			0x0C
+#define S_RCVRY_LOCK			0x0D
+#define S_RCVRY_SPEED			0x0E
+#define S_RCVRY_RCVRCFG			0x0F
+#define S_RCVRY_IDLE			0x10
+#define S_L0				0x11
+#define S_L0S				0x12
+#define S_L123_SEND_EIDLE		0x13
+#define S_L1_IDLE			0x14
+#define S_L2_IDLE			0x15
+#define S_L2_WAKE			0x16
+#define S_DISABLED_ENTRY		0x17
+#define S_DISABLED_IDLE			0x18
+#define S_DISABLED			0x19
+#define S_LPBK_ENTRY			0x1A
+#define S_LPBK_ACTIVE			0x1B
+#define S_LPBK_EXIT			0x1C
+#define S_LPBK_EXIT_TIMEOUT		0x1D
+#define S_HOT_RESET_ENTRY		0x1E
+#define S_HOT_RESET			0x1F
+
+/* syscfg bits */
+#define PCIE_SYS_INT			BIT(5)
+#define PCIE_APP_REQ_RETRY_EN		BIT(3)
+#define PCIE_APP_LTSSM_ENABLE		BIT(2)
+#define PCIE_APP_INIT_RST		BIT(1)
+#define PCIE_DEVICE_TYPE		BIT(0)
+#define PCIE_DEFAULT_VAL		PCIE_DEVICE_TYPE
+
+/* Time to wait between testing the link in msecs (hardware poll interval) */
+#define LINK_LOOP_DELAY_MS 1
+/* Total amount of time to wait for the link to come up in msecs */
+#define LINK_WAIT_MS 120
+#define LINK_LOOP_COUNT (LINK_WAIT_MS / LINK_LOOP_DELAY_MS)
+
+/* st,syscfg offsets */
+#define SYSCFG0_REG	1
+#define SYSCFG1_REG	2
+
+#define to_st_pcie(x)	container_of(x, struct st_pcie, pp)
+
+/**
+ * struct st_pcie - private data of the controller
+ * @pp: designware pcie port
+ * @syscfg0: PCIe configuration 0 register, regmap offset
+ * @syscfg1: PCIe configuration 1 register, regmap offset
+ * @phy: associated pcie phy
+ * @lmi: memory made available to the controller
+ * @regmap: Syscfg registers bank in which PCIe port is configured
+ * @pwr: power control
+ * @rst: reset control
+ * @reset_gpio: optional reset gpio
+ * @config_window_start: start address of 64K config space area
+ */
+struct st_pcie {
+	struct pcie_port pp;
+	int syscfg0;
+	int syscfg1;
+	struct phy *phy;
+	struct resource	*lmi;
+	struct regmap *regmap;
+	struct reset_control *pwr;
+	struct reset_control *rst;
+	int reset_gpio;
+	phys_addr_t config_window_start;
+};
+
+/*
+ * Function to test if the link is in an operational state or not. We must
+ * ensure the link is operational before we try to do a configuration access.
+ */
+static int st_pcie_link_up(struct pcie_port *pp)
+{
+	u32 status;
+	int link_up;
+	int count = 0;
+
+	/*
+	 * We have to be careful here. This is used in config read/write,
+	 * The higher levels switch off interrupts, so you cannot use
+	 * jiffies to do a timeout, or reschedule
+	 */
+	do {
+		/*
+		 * What about L2? I think software intervention is
+		 * required to get it out of L2, so in effect the link
+		 * is down. Requires more work when/if we implement power
+		 * management
+		 */
+		status = readl_relaxed(pp->dbi_base + PORT_LOGIC_DEBUG_REG_0);
+		status &= DEBUG_REG_0_LTSSM_MASK;
+
+		link_up = (status == S_L0) || (status == S_L0S) ||
+			  (status == S_L1_IDLE);
+
+		/*
+		 * It can take some considerable time for the link to actually
+		 * come up, caused by the PLLs. Experiments indicate it takes
+		 * about 8ms to actually bring the link up, but this can vary
+		 * considerably according to the specification. This code should
+		 * allow sufficient time
+		 */
+		if (!link_up)
+			mdelay(LINK_LOOP_DELAY_MS);
+
+	} while (!link_up && ++count < LINK_LOOP_COUNT);
+
+	return link_up;
+}
+
+/*
+ * On ARM platforms, we actually get a bus error returned when the PCIe IP
+ * returns a UR or CRS instead of an OK.
+ */
+static int st_pcie_abort_handler(unsigned long addr, unsigned int fsr,
+				 struct pt_regs *regs)
+{
+	return 0;
+}
+
+/*
+ * The PCI express core IP expects the following arrangement on it's address
+ * bus (slv_haddr) when driving config cycles.
+ * bus_number		[31:24]
+ * dev_number		[23:19]
+ * func_number		[18:16]
+ * unused		[15:12]
+ * ext_reg_number	[11:8]
+ * reg_number		[7:2]
+ *
+ * Bits [15:12] are unused.
+ *
+ * In the glue logic there is a 64K region of address space that can be
+ * written/read to generate config cycles. The base address of this is
+ * controlled by CFG_BASE_ADDRESS. There are 8 16 bit registers called
+ * FUNC0_BDF_NUM to FUNC8_BDF_NUM. These split the bottom half of the 64K
+ * window into 8 regions at 4K boundaries. These control the bus,device and
+ * function number you are trying to talk to.
+ *
+ * The decision on whether to generate a type 0 or type 1 access is controlled
+ * by bits 15:12 of the address you write to.  If they are zero, then a type 0
+ * is generated, if anything else it will be a type 1. Thus the bottom 4K
+ * region controlled by FUNC0_BDF_NUM can only generate type 0, all the others
+ * can only generate type 1.
+ *
+ * We only use FUNC0_BDF_NUM and FUNC1_BDF_NUM. Which one you use is selected
+ * by bit 12 of the address you write to. The selected register is then used
+ * for the top 16 bits of the slv_haddr to form the bus/dev/func, bit 15:12 are
+ * wired to zero, and bits 11:2 form the address of the register you want to
+ * read in config space.
+ *
+ * We always write FUNC0_BDF_NUM as a 32 bit write. So if we want type 1
+ * accesses we have to shift by 16 so in effect we are writing to FUNC1_BDF_NUM
+ */
+static inline u32 bdf_num(int bus, int devfn, int is_root_bus)
+{
+	return ((bus << 8) | devfn) << (is_root_bus ? 0 : 16);
+}
+
+static int st_pcie_rd_other_conf(struct pcie_port *pp, struct pci_bus *bus,
+				 unsigned int devfn, int where, int size,
+				 u32 *val)
+{
+	int ret;
+	u32 bdf, addr;
+
+	addr = where & ~0x3;
+	bdf = bdf_num(bus->number, devfn, pci_is_root_bus(bus));
+
+	/* Set the config packet devfn */
+	writel_relaxed(bdf, pp->dbi_base + FUNC0_BDF_NUM);
+	readl_relaxed(pp->dbi_base + FUNC0_BDF_NUM);
+
+	if (bus->parent->number == pp->root_bus_nr)
+		ret = dw_pcie_cfg_read(pp->va_cfg0_base + addr, where, size,
+				       val);
+	else
+		ret = dw_pcie_cfg_read(pp->va_cfg1_base + addr, where, size,
+				       val);
+	return ret;
+}
+
+static int st_pcie_wr_other_conf(struct pcie_port *pp, struct pci_bus *bus,
+				 unsigned int devfn, int where, int size,
+				 u32 val)
+{
+	int ret;
+	u32 bdf, addr;
+
+	addr = where & ~0x3;
+	bdf = bdf_num(bus->number, devfn, pci_is_root_bus(bus));
+
+	/* Set the config packet devfn */
+	writel_relaxed(bdf, pp->dbi_base + FUNC0_BDF_NUM);
+	readl_relaxed(pp->dbi_base + FUNC0_BDF_NUM);
+
+	if (bus->parent->number == pp->root_bus_nr)
+		ret = dw_pcie_cfg_write(pp->va_cfg0_base + addr, where, size,
+					val);
+	else
+		ret = dw_pcie_cfg_write(pp->va_cfg1_base + addr, where, size,
+					val);
+	return ret;
+}
+
+static void st_pcie_board_reset(struct pcie_port *pp)
+{
+	struct st_pcie *pcie = to_st_pcie(pp);
+
+	if (!gpio_is_valid(pcie->reset_gpio))
+		return;
+
+	if (gpio_direction_output(pcie->reset_gpio, 0)) {
+		dev_err(pp->dev, "Cannot set PERST# (gpio %u) to output\n",
+			pcie->reset_gpio);
+		return;
+	}
+
+	/* From PCIe spec */
+	msleep(2);
+	gpio_direction_output(pcie->reset_gpio, 1);
+
+	/*
+	 * PCIe specification states that you should not issue any config
+	 * requests until 100ms after asserting reset, so we enforce that here
+	 */
+	msleep(100);
+}
+
+static void st_pcie_hw_setup(struct pcie_port *pp)
+{
+	struct st_pcie *pcie = to_st_pcie(pp);
+
+	dw_pcie_setup_rc(pp);
+
+	/* Set up the config window to the top of the PCI address space */
+	writel_relaxed(pcie->config_window_start,
+		       pp->dbi_base + CFG_BASE_ADDRESS);
+
+	/*
+	 * Open up memory to the PCI controller. We could do slightly
+	 * better than this and exclude the kernel text segment and bss etc.
+	 * They are base/limit registers so can be of arbitrary alignment
+	 * presumably
+	 */
+	writel_relaxed(pcie->lmi->start, pp->dbi_base + IN0_MEM_ADDR_START);
+	writel_relaxed(pcie->lmi->end, pp->dbi_base + IN0_MEM_ADDR_LIMIT);
+
+	/* Disable the 2nd region */
+	writel_relaxed(~0, pp->dbi_base + IN1_MEM_ADDR_START);
+	writel_relaxed(0, pp->dbi_base + IN1_MEM_ADDR_LIMIT);
+
+	writel_relaxed(RC_PASS_ADDR_RANGE, pp->dbi_base + TRANSLATION_CONTROL);
+
+	/* Now assert the board level reset to the other PCIe device */
+	st_pcie_board_reset(pp);
+}
+
+static irqreturn_t st_pcie_msi_irq_handler(int irq, void *arg)
+{
+	struct pcie_port *pp = arg;
+
+	return dw_handle_msi_irq(pp);
+}
+
+static int st_pcie_init(struct pcie_port *pp)
+{
+	struct st_pcie *pcie = to_st_pcie(pp);
+	int ret;
+
+	ret = reset_control_deassert(pcie->pwr);
+	if (ret) {
+		dev_err(pp->dev, "unable to bring out of powerdown\n");
+		return ret;
+	}
+
+	ret = reset_control_deassert(pcie->rst);
+	if (ret) {
+		dev_err(pp->dev, "unable to bring out of softreset\n");
+		return ret;
+	}
+
+	/* Set device type : Root Complex */
+	ret = regmap_write(pcie->regmap, pcie->syscfg0, PCIE_DEVICE_TYPE);
+	if (ret < 0) {
+		dev_err(pp->dev, "unable to set device type\n");
+		return ret;
+	}
+
+	usleep_range(1000, 2000);
+	return ret;
+}
+
+static int st_pcie_enable_ltssm(struct pcie_port *pp)
+{
+	struct st_pcie *pcie = to_st_pcie(pp);
+
+	return regmap_update_bits(pcie->regmap, pcie->syscfg1,
+				  PCIE_APP_LTSSM_ENABLE, PCIE_APP_LTSSM_ENABLE);
+}
+
+static int st_pcie_disable_ltssm(struct pcie_port *pp)
+{
+	struct st_pcie *pcie = to_st_pcie(pp);
+
+	return regmap_update_bits(pcie->regmap, pcie->syscfg1,
+				  PCIE_APP_LTSSM_ENABLE, 0);
+}
+
+static void st_pcie_host_init(struct pcie_port *pp)
+{
+	struct st_pcie *pcie = to_st_pcie(pp);
+	int err;
+
+	/*
+	 * We have to initialise the PCIe cell on some hardware before we can
+	 * talk to the phy
+	 */
+	err = st_pcie_init(pp);
+	if (err)
+		return;
+
+	err = st_pcie_disable_ltssm(pp);
+	if (err) {
+		dev_err(pp->dev, "disable ltssm failed, %d\n", err);
+		return;
+	}
+
+	/* Now init the associated miphy */
+	err = phy_init(pcie->phy);
+	if (err < 0) {
+		dev_err(pp->dev, "Cannot init PHY: %d\n", err);
+		return;
+	}
+
+	/* Now do all the register poking */
+	st_pcie_hw_setup(pp);
+
+	/* Re-enable the link */
+	err = st_pcie_enable_ltssm(pp);
+	if (err)
+		dev_err(pp->dev, "enable ltssm failed, %d\n", err);
+
+	if (IS_ENABLED(CONFIG_PCI_MSI))
+		dw_pcie_msi_init(pp);
+}
+
+static struct pcie_host_ops st_pcie_host_ops = {
+	.rd_other_conf = st_pcie_rd_other_conf,
+	.wr_other_conf = st_pcie_wr_other_conf,
+	.link_up = st_pcie_link_up,
+	.host_init = st_pcie_host_init,
+};
+
+static const struct of_device_id st_pcie_of_match[] = {
+	{ .compatible = "st,pcie", },
+	{ },
+};
+
+static int __init st_pcie_probe(struct platform_device *pdev)
+{
+	struct resource *res;
+	struct st_pcie *pcie;
+	struct device_node *np = pdev->dev.of_node;
+	struct pcie_port *pp;
+	int ret;
+
+	pcie = devm_kzalloc(&pdev->dev, sizeof(*pcie), GFP_KERNEL);
+	if (!pcie)
+		return -ENOMEM;
+
+	memset(pcie, 0, sizeof(*pcie));
+
+	pp = &pcie->pp;
+	pp->dev = &pdev->dev;
+
+	/* mem regions */
+	res = platform_get_resource_byname(pdev, IORESOURCE_MEM, "dbi");
+	pp->dbi_base = devm_ioremap_resource(&pdev->dev, res);
+	if (IS_ERR(pp->dbi_base))
+		return PTR_ERR(pp->dbi_base);
+
+	res = platform_get_resource_byname(pdev, IORESOURCE_MEM, "config");
+	if (!res)
+		return -ENXIO;
+
+	/* Check that this has sensible values */
+	if ((resource_size(res) != CFG_REGION_SIZE) ||
+	    (res->start & (CFG_REGION_SIZE - 1))) {
+		dev_err(&pdev->dev, "Invalid config space properties\n");
+		return -EINVAL;
+	}
+	pcie->config_window_start = res->start;
+
+	pp->va_cfg0_base = devm_ioremap_resource(&pdev->dev, res);
+	if (IS_ERR(pp->va_cfg0_base))
+		return PTR_ERR(pp->va_cfg0_base);
+	pp->va_cfg1_base = pp->va_cfg0_base + CFG_SPACE1_OFFSET;
+
+	pcie->lmi = platform_get_resource_byname(pdev, IORESOURCE_MEM,
+						 "mem-window");
+	if (!pcie->lmi)
+		return -ENXIO;
+
+	/* regmap registers for PCIe IP configuration */
+	pcie->regmap = syscon_regmap_lookup_by_phandle(np, "st,syscfg");
+	if (IS_ERR(pcie->regmap)) {
+		dev_err(&pdev->dev, "No syscfg phandle specified\n");
+		return PTR_ERR(pcie->regmap);
+	}
+
+	ret = of_property_read_u32_index(np, "st,syscfg", SYSCFG0_REG,
+					 &pcie->syscfg0);
+	if (ret) {
+		dev_err(&pdev->dev, "can't get syscfg0 offset (%d)\n", ret);
+		return ret;
+	}
+
+	ret = of_property_read_u32_index(np, "st,syscfg", SYSCFG1_REG,
+					 &pcie->syscfg1);
+	if (ret) {
+		dev_err(&pdev->dev, "can't get syscfg1 offset (%d)\n", ret);
+		return ret;
+	}
+
+	/* powerdown / resets */
+	pcie->pwr = devm_reset_control_get(&pdev->dev, "powerdown");
+	if (IS_ERR(pcie->pwr)) {
+		dev_err(&pdev->dev, "powerdown reset control not defined\n");
+		return PTR_ERR(pcie->pwr);
+	}
+
+	pcie->rst = devm_reset_control_get(&pdev->dev, "softreset");
+	if (IS_ERR(pcie->rst)) {
+		dev_err(&pdev->dev, "Soft reset control not defined\n");
+		return PTR_ERR(pcie->pwr);
+	}
+
+	/* phy */
+	pcie->phy = devm_phy_get(&pdev->dev, "pcie");
+	if (IS_ERR(pcie->phy)) {
+		dev_err(&pdev->dev, "no PHY configured\n");
+		return PTR_ERR(pcie->phy);
+	}
+
+	/* Claim the GPIO for PRST# if available */
+	pcie->reset_gpio = of_get_named_gpio(np, "reset-gpio", 0);
+	if (!gpio_is_valid(pcie->reset_gpio))
+		dev_dbg(&pdev->dev, "No reset-gpio configured\n");
+	else {
+		ret = devm_gpio_request(&pdev->dev,
+					pcie->reset_gpio,
+					"PCIe reset");
+		if (ret) {
+			dev_err(&pdev->dev, "Cannot request reset-gpio %d\n",
+				pcie->reset_gpio);
+			return ret;
+		}
+	}
+
+	if (IS_ENABLED(CONFIG_PCI_MSI)) {
+		pp->msi_irq = platform_get_irq_byname(pdev, "msi");
+		if (pp->msi_irq <= 0) {
+			dev_err(&pdev->dev, "failed to get MSI irq\n");
+			return -ENODEV;
+		}
+
+		ret = devm_request_irq(&pdev->dev, pp->msi_irq,
+				       st_pcie_msi_irq_handler,
+				       IRQF_SHARED, "st-pcie-msi", pp);
+		if (ret) {
+			dev_err(&pdev->dev, "failed to request MSI irq\n");
+			return -ENODEV;
+		}
+	}
+
+	if (IS_ENABLED(CONFIG_ARM)) {
+		/*
+		 * We have to hook the abort handler so that we can intercept
+		 * bus errors when doing config read/write that return UR,
+		 * which is flagged up as a bus error
+		 */
+		hook_fault_code(16+6, st_pcie_abort_handler, SIGBUS, 0,
+				"imprecise external abort");
+	}
+
+	pp->root_bus_nr = -1;
+	pp->ops = &st_pcie_host_ops;
+
+	ret = dw_pcie_host_init(pp);
+	if (ret) {
+		dev_err(&pdev->dev, "failed to initialize host\n");
+		return ret;
+	}
+
+	platform_set_drvdata(pdev, pcie);
+
+	dev_info(&pdev->dev, "Initialized\n");
+	return 0;
+}
+
+MODULE_DEVICE_TABLE(of, st_pcie_of_match);
+
+static struct platform_driver st_pcie_driver = {
+	.driver = {
+		.name = "st-pcie",
+		.of_match_table = st_pcie_of_match,
+	},
+};
+
+/* ST PCIe driver does not allow module unload */
+static int __init pcie_init(void)
+{
+	return platform_driver_probe(&st_pcie_driver, st_pcie_probe);
+}
+module_init(pcie_init);
+
+MODULE_AUTHOR("Fabrice Gasnier <fabrice.gasnier at st.com>");
+MODULE_DESCRIPTION("PCI express Driver for ST SoCs");
+MODULE_LICENSE("GPL v2");
-- 
1.9.1



From gabriel.fernandez at linaro.org  Thu Aug 27 05:34:17 2015
From: gabriel.fernandez at linaro.org (Gabriel Fernandez)
Date: Thu, 27 Aug 2015 14:34:17 +0200
Subject: [PATCH v4 4/4] MAINTAINERS: Add pci-st.c to ARCH/STI architecture
In-Reply-To: <1440678857-27118-1-git-send-email-gabriel.fernandez@linaro.org>
References: <1440678857-27118-1-git-send-email-gabriel.fernandez@linaro.org>
Message-ID: <1440678857-27118-5-git-send-email-gabriel.fernandez@linaro.org>

This patch adds the pci-st.c pci driver found on STMicroelectronics
SoC's into the STI arch section of the maintainers file.

Signed-off-by: Gabriel Fernandez <gabriel.fernandez at linaro.org>
---
 MAINTAINERS | 1 +
 1 file changed, 1 insertion(+)

diff --git a/MAINTAINERS b/MAINTAINERS
index 8133cef..af5034f 100644
--- a/MAINTAINERS
+++ b/MAINTAINERS
@@ -1506,6 +1506,7 @@ F:	drivers/clocksource/arm_global_timer.c
 F:	drivers/i2c/busses/i2c-st.c
 F:	drivers/media/rc/st_rc.c
 F:	drivers/mmc/host/sdhci-st.c
+F:	drivers/pci/host/pci-st.c
 F:	drivers/phy/phy-miphy28lp.c
 F:	drivers/phy/phy-miphy365x.c
 F:	drivers/phy/phy-stih407-usb.c
-- 
1.9.1



From gabriel.fernandez at linaro.org  Thu Aug 27 05:34:15 2015
From: gabriel.fernandez at linaro.org (Gabriel Fernandez)
Date: Thu, 27 Aug 2015 14:34:15 +0200
Subject: [PATCH v4 2/4] PCI: st: Add Device Tree bindings for sti pcie
In-Reply-To: <1440678857-27118-1-git-send-email-gabriel.fernandez@linaro.org>
References: <1440678857-27118-1-git-send-email-gabriel.fernandez@linaro.org>
Message-ID: <1440678857-27118-3-git-send-email-gabriel.fernandez@linaro.org>

sti pcie is built around a Synopsis Designware PCIe IP.

Signed-off-by: Fabrice Gasnier <fabrice.gasnier at st.com>
Signed-off-by: Gabriel Fernandez <gabriel.fernandez at linaro.org>
---
 Documentation/devicetree/bindings/pci/st-pcie.txt | 53 +++++++++++++++++++++++
 1 file changed, 53 insertions(+)
 create mode 100644 Documentation/devicetree/bindings/pci/st-pcie.txt

diff --git a/Documentation/devicetree/bindings/pci/st-pcie.txt b/Documentation/devicetree/bindings/pci/st-pcie.txt
new file mode 100644
index 0000000..25fcab3
--- /dev/null
+++ b/Documentation/devicetree/bindings/pci/st-pcie.txt
@@ -0,0 +1,53 @@
+STMicroelectronics STi PCIe controller
+
+This PCIe host controller is based on the Synopsis Designware PCIe IP
+and thus inherits all the common properties defined in designware-pcie.txt.
+
+Required properties:
+ - compatible: "st,stih407-pcie"
+ - reg: base address and length of the pcie controller, mem-window address
+   and length available to the controller.
+ - interrupts: A list of interrupt outputs of the controller. Must contain an
+   entry for each entry in the interrupt-names property.
+ - interrupt-names: Should be "msi". STi interrupt that is asserted when an
+   MSI is received.
+ - st,syscfg : should be a phandle of the syscfg node. Also contains syscfg
+   offset for IP configuration.
+ - resets, reset-names: the power-down and soft-reset lines of PCIe IP.
+   Associated names must be "powerdown" and "softreset".
+ - phys, phy-names: the phandle for the PHY device.
+   Associated name must be "pcie"
+
+Optional properties:
+ - reset-gpio: a GPIO spec to define which pin is connected to the bus reset.
+
+Example:
+
+pcie0: pcie at 9b00000 {
+	compatible = "st,pcie", "snps,dw-pcie";
+	device_type = "pci";
+	reg = <0x09b00000 0x4000>,	/* dbi cntrl registers */
+	      <0x2fff0000 0x00010000>,	/* configuration space */
+	      <0x40000000 0x80000000>;	/* lmi mem window */
+	reg-names = "dbi", "config", "mem-window";
+	st,syscfg = <&syscfg_core 0xd8 0xe0>;
+	#address-cells = <3>;
+	#size-cells = <2>;
+	ranges = <0x82000000 0 0x20000000 0x20000000 0 0x0FFF0000>; /* non-prefetchable memory */
+	num-lanes = <1>;
+	interrupts = <GIC_SPI 164 IRQ_TYPE_LEVEL_HIGH>;
+	interrupt-names = "msi";
+	#interrupt-cells = <1>;
+	interrupt-map-mask = <0 0 0 7>;
+	interrupt-map = <0 0 0 1 &intc GIC_SPI 160 IRQ_TYPE_LEVEL_HIGH>, /* INT A */
+			<0 0 0 2 &intc GIC_SPI 161 IRQ_TYPE_LEVEL_HIGH>, /* INT B */
+			<0 0 0 3 &intc GIC_SPI 162 IRQ_TYPE_LEVEL_HIGH>, /* INT C */
+			<0 0 0 4 &intc GIC_SPI 163 IRQ_TYPE_LEVEL_HIGH>; /* INT D */
+
+	resets = <&powerdown STIH407_PCIE0_POWERDOWN>,
+		 <&softreset STIH407_PCIE0_SOFTRESET>;
+	reset-names = "powerdown",
+		      "softreset";
+	phys = <&phy_port0 PHY_TYPE_PCIE>;
+	phy-names = "pcie";
+};
-- 
1.9.1



From gabriel.fernandez at linaro.org  Thu Aug 27 05:34:13 2015
From: gabriel.fernandez at linaro.org (Gabriel Fernandez)
Date: Thu, 27 Aug 2015 14:34:13 +0200
Subject: [PATCH v4 0/4] PCI: st: provide support for dw pcie
Message-ID: <1440678857-27118-1-git-send-email-gabriel.fernandez@linaro.org>


This patchset is based on v4.2-rc1 and is based on 
[PATCH v8 0/6] PCI: hisi: Add PCIe host support for HiSilicon SoC Hip05
patchset from Zhou Wang.

Changes in v4:
 - Remove pci: designware: remove my pci_common_init_dev() patch and
	use [PATCH v8 3/6] PCI: designware: Add ARM64 support instead.
	This patch is a good solution for me to disable IO support.
 - add __init to st_pcie_probe() and use module_init() instead
	device_initcall() to prevent the probe function from being
	deferred and to prevent module unloading.

Changes in v3:
 - Remove power management functions (was not fully tested)
 - Remove configuration space range from dt binding
 - Remove pci_common_init_dev() call in pcie-designware.c to avoid 
   default IO space declaration. 

Changes in v2:
 - comestic corrections in device tree binding
 - add pci-st.c into MAINTAINERS
 - remove st_pcie_ops structure to avoid another level of indirection
 - remove nasty busy-loop
 - remove useless test using virt_to_phys()
 - move disable io support into dw-pcie driver

I don't change the st_pcie_abort_handler() function because abort handling
is masked during boot.


This patch-set introduces a STMicroelectronics PCIe controller.
It's based on designware PCIe driver.

Gabriel Fernandez (4):
  ARM: STi: Kconfig update for PCIe support
  PCI: st: Add Device Tree bindings for sti pcie
  PCI: st: Provide support for the sti PCIe controller
  MAINTAINERS: Add pci-st.c to ARCH/STI architecture

 Documentation/devicetree/bindings/pci/st-pcie.txt |  53 ++
 MAINTAINERS                                       |   1 +
 arch/arm/mach-sti/Kconfig                         |   2 +
 drivers/pci/host/Kconfig                          |   9 +
 drivers/pci/host/Makefile                         |   1 +
 drivers/pci/host/pci-st.c                         | 583 ++++++++++++++++++++++
 6 files changed, 649 insertions(+)
 create mode 100644 Documentation/devicetree/bindings/pci/st-pcie.txt
 create mode 100644 drivers/pci/host/pci-st.c

-- 
1.9.1



From gabriel.fernandez at linaro.org  Thu Aug 27 05:56:48 2015
From: gabriel.fernandez at linaro.org (Gabriel Fernandez)
Date: Thu, 27 Aug 2015 14:56:48 +0200
Subject: [PATCH v8 3/6] PCI: designware: Add ARM64 support
In-Reply-To: <1440496734-18417-4-git-send-email-wangzhou1@hisilicon.com>
References: <1440496734-18417-1-git-send-email-wangzhou1@hisilicon.com>
 <1440496734-18417-4-git-send-email-wangzhou1@hisilicon.com>
Message-ID: <CAG374jDDY4COvM_UTfGmJfbXQrMywYB511-fZiWen3GU9VhQvw@mail.gmail.com>

Hi Zhou,

You can add my Tested-by: Gabriel Fernandez <gabriel.fernandez at st.com>

I tested your patchset with a STMicroelectronics PCIe controller.
This controller is based on designware PCIe driver and works on ARM32.

Please find my patchset here:
http://www.spinics.net/lists/kernel/msg2064266.html

Best Regards.

Gabriel.

On 25 August 2015 at 11:58, Zhou Wang <wangzhou1 at hisilicon.com> wrote:
> This patch tries to unify ARM32 and ARM64 PCIe in designware driver. Delete
> function dw_pcie_setup, dw_pcie_scan_bus, dw_pcie_map_irq and struct hw_pci,
> move related operations to dw_pcie_host_init.
>
> This patch also try to use of_pci_get_host_bridge_resources for ARM32 and ARM64
> according to the suggestion for Gabriele[1]
>
> Finally this patch reverts commit f4c55c5a3f7f "PCI: designware: Program ATU
> with untranslated address" based on 1/6 in this series. we delete *_mod_base in
> pcie-designware. This was discussed in [2]
>
> I have compiled the driver with multi_v7_defconfig. However, I don't have
> ARM32 PCIe related board to do test. It will be appreciated if someone could
> help to test it.
>
> Signed-off-by: Zhou Wang <wangzhou1 at hisilicon.com>
> Signed-off-by: Gabriele Paoloni <gabriele.paoloni at huawei.com>
> Signed-off-by: Arnd Bergmann <arnd at arndb.de>
> Tested-By: James Morse <james.morse at arm.com>
>
> [1] http://www.spinics.net/lists/linux-pci/msg42194.html
> [2] http://www.spinics.net/lists/arm-kernel/msg436779.html
> ---
>  drivers/pci/host/pci-dra7xx.c      |  14 +--
>  drivers/pci/host/pci-keystone-dw.c |   2 +-
>  drivers/pci/host/pcie-designware.c | 230 +++++++++++++------------------------
>  drivers/pci/host/pcie-designware.h |  14 +--
>  4 files changed, 90 insertions(+), 170 deletions(-)
>
> diff --git a/drivers/pci/host/pci-dra7xx.c b/drivers/pci/host/pci-dra7xx.c
> index 18ae7ff..ac401be 100644
> --- a/drivers/pci/host/pci-dra7xx.c
> +++ b/drivers/pci/host/pci-dra7xx.c
> @@ -141,15 +141,15 @@ static void dra7xx_pcie_host_init(struct pcie_port *pp)
>  {
>         dw_pcie_setup_rc(pp);
>
> -       if (pp->io_mod_base)
> -               pp->io_mod_base &= CPU_TO_BUS_ADDR;
> +       if (pp->io_base)
> +               pp->io_base &= CPU_TO_BUS_ADDR;
>
> -       if (pp->mem_mod_base)
> -               pp->mem_mod_base &= CPU_TO_BUS_ADDR;
> +       if (pp->mem_base)
> +               pp->mem_base &= CPU_TO_BUS_ADDR;
>
> -       if (pp->cfg0_mod_base) {
> -               pp->cfg0_mod_base &= CPU_TO_BUS_ADDR;
> -               pp->cfg1_mod_base &= CPU_TO_BUS_ADDR;
> +       if (pp->cfg0_base) {
> +               pp->cfg0_base &= CPU_TO_BUS_ADDR;
> +               pp->cfg1_base &= CPU_TO_BUS_ADDR;
>         }
>
>         dra7xx_pcie_establish_link(pp);
> diff --git a/drivers/pci/host/pci-keystone-dw.c b/drivers/pci/host/pci-keystone-dw.c
> index f34892e..b1e4135 100644
> --- a/drivers/pci/host/pci-keystone-dw.c
> +++ b/drivers/pci/host/pci-keystone-dw.c
> @@ -327,7 +327,7 @@ static void ks_dw_pcie_clear_dbi_mode(void __iomem *reg_virt)
>  void ks_dw_pcie_setup_rc_app_regs(struct keystone_pcie *ks_pcie)
>  {
>         struct pcie_port *pp = &ks_pcie->pp;
> -       u32 start = pp->mem.start, end = pp->mem.end;
> +       u32 start = pp->mem->start, end = pp->mem->end;
>         int i, tr_size;
>
>         /* Disable BARs for inbound access */
> diff --git a/drivers/pci/host/pcie-designware.c b/drivers/pci/host/pcie-designware.c
> index c5d407c..e2d1898 100644
> --- a/drivers/pci/host/pcie-designware.c
> +++ b/drivers/pci/host/pcie-designware.c
> @@ -11,6 +11,7 @@
>   * published by the Free Software Foundation.
>   */
>
> +#include <linux/hardirq.h>
>  #include <linux/irq.h>
>  #include <linux/irqdomain.h>
>  #include <linux/kernel.h>
> @@ -69,16 +70,7 @@
>  #define PCIE_ATU_FUNC(x)               (((x) & 0x7) << 16)
>  #define PCIE_ATU_UPPER_TARGET          0x91C
>
> -static struct hw_pci dw_pci;
> -
> -static unsigned long global_io_offset;
> -
> -static inline struct pcie_port *sys_to_pcie(struct pci_sys_data *sys)
> -{
> -       BUG_ON(!sys->private_data);
> -
> -       return sys->private_data;
> -}
> +static struct pci_ops dw_pcie_ops;
>
>  int dw_pcie_cfg_read(void __iomem *addr, int where, int size, u32 *val)
>  {
> @@ -255,7 +247,7 @@ static void dw_pcie_msi_set_irq(struct pcie_port *pp, int irq)
>  static int assign_irq(int no_irqs, struct msi_desc *desc, int *pos)
>  {
>         int irq, pos0, i;
> -       struct pcie_port *pp = sys_to_pcie(desc->dev->bus->sysdata);
> +       struct pcie_port *pp = desc->dev->bus->sysdata;
>
>         pos0 = bitmap_find_free_region(pp->msi_irq_in_use, MAX_MSI_IRQS,
>                                        order_base_2(no_irqs));
> @@ -298,7 +290,7 @@ static int dw_msi_setup_irq(struct msi_controller *chip, struct pci_dev *pdev,
>  {
>         int irq, pos;
>         struct msi_msg msg;
> -       struct pcie_port *pp = sys_to_pcie(pdev->bus->sysdata);
> +       struct pcie_port *pp = pdev->bus->sysdata;
>
>         if (desc->msi_attrib.is_msix)
>                 return -EINVAL;
> @@ -327,7 +319,7 @@ static void dw_msi_teardown_irq(struct msi_controller *chip, unsigned int irq)
>  {
>         struct irq_data *data = irq_get_irq_data(irq);
>         struct msi_desc *msi = irq_data_get_msi(data);
> -       struct pcie_port *pp = sys_to_pcie(msi->dev->bus->sysdata);
> +       struct pcie_port *pp = msi->dev->bus->sysdata;
>
>         clear_irq_range(pp, irq, 1, data->hwirq);
>  }
> @@ -363,14 +355,12 @@ int dw_pcie_host_init(struct pcie_port *pp)
>  {
>         struct device_node *np = pp->dev->of_node;
>         struct platform_device *pdev = to_platform_device(pp->dev);
> -       struct of_pci_range range;
> -       struct of_pci_range_parser parser;
> +       struct pci_bus *bus;
>         struct resource *cfg_res;
> -       u32 val, ns;
> -       const __be32 *addrp;
> -       int i, index, ret;
> -
> -       ns = of_n_size_cells(np);
> +       LIST_HEAD(res);
> +       u32 val;
> +       int i, ret;
> +       struct resource_entry *win;
>
>         cfg_res = platform_get_resource_byname(pdev, IORESOURCE_MEM, "config");
>         if (cfg_res) {
> @@ -378,85 +368,60 @@ int dw_pcie_host_init(struct pcie_port *pp)
>                 pp->cfg1_size = resource_size(cfg_res)/2;
>                 pp->cfg0_base = cfg_res->start;
>                 pp->cfg1_base = cfg_res->start + pp->cfg0_size;
> -
> -               /* Find the untranslated configuration space address */
> -               index = of_property_match_string(np, "reg-names", "config");
> -               addrp = of_get_address(np, index, NULL, NULL);
> -               pp->cfg0_mod_base = of_read_number(addrp, ns);
> -               pp->cfg1_mod_base = pp->cfg0_mod_base + pp->cfg0_size;
>         } else {
>                 dev_err(pp->dev, "missing *config* reg space\n");
>         }
>
> -       if (of_pci_range_parser_init(&parser, np)) {
> -               dev_err(pp->dev, "missing ranges property\n");
> -               return -EINVAL;
> -       }
> +       ret = of_pci_get_host_bridge_resources(np, 0, 0xff, &res, &pp->io_base);
> +       if (ret)
> +               return ret;
>
>         /* Get the I/O and memory ranges from DT */
> -       for_each_of_pci_range(&parser, &range) {
> -               unsigned long restype = range.flags & IORESOURCE_TYPE_BITS;
> -
> -               if (restype == IORESOURCE_IO) {
> -                       of_pci_range_to_resource(&range, np, &pp->io);
> -                       pp->io.name = "I/O";
> -                       pp->io.start = max_t(resource_size_t,
> -                                            PCIBIOS_MIN_IO,
> -                                            range.pci_addr + global_io_offset);
> -                       pp->io.end = min_t(resource_size_t,
> -                                          IO_SPACE_LIMIT,
> -                                          range.pci_addr + range.size
> -                                          + global_io_offset - 1);
> -                       pp->io_size = resource_size(&pp->io);
> -                       pp->io_bus_addr = range.pci_addr;
> -                       pp->io_base = range.cpu_addr;
> -
> -                       /* Find the untranslated IO space address */
> -                       pp->io_mod_base = range.cpu_addr;
> -               }
> -               if (restype == IORESOURCE_MEM) {
> -                       of_pci_range_to_resource(&range, np, &pp->mem);
> -                       pp->mem.name = "MEM";
> -                       pp->mem_size = resource_size(&pp->mem);
> -                       pp->mem_bus_addr = range.pci_addr;
> -
> -                       /* Find the untranslated MEM space address */
> -                       pp->mem_mod_base = range.cpu_addr;
> -               }
> -               if (restype == 0) {
> -                       of_pci_range_to_resource(&range, np, &pp->cfg);
> -                       pp->cfg0_size = resource_size(&pp->cfg)/2;
> -                       pp->cfg1_size = resource_size(&pp->cfg)/2;
> -                       pp->cfg0_base = pp->cfg.start;
> -                       pp->cfg1_base = pp->cfg.start + pp->cfg0_size;
> -
> -                       /* Find the untranslated configuration space address */
> -                       pp->cfg0_mod_base = range.cpu_addr;
> -                       pp->cfg1_mod_base = pp->cfg0_mod_base +
> -                                           pp->cfg0_size;
> +       resource_list_for_each_entry(win, &res) {
> +               switch (resource_type(win->res)) {
> +               case IORESOURCE_IO:
> +                       pp->io = win->res;
> +                       pp->io->name = "I/O";
> +                       pp->io_size = resource_size(pp->io);
> +                       pp->io_bus_addr = pp->io->start - win->offset;
> +                       ret = pci_remap_iospace(pp->io, pp->io_base);
> +                       if (ret) {
> +                               dev_warn(pp->dev, "error %d: failed to map resource %pR\n",
> +                                        ret, pp->io);
> +                               continue;
> +                       }
> +                       break;
> +               case IORESOURCE_MEM:
> +                       pp->mem = win->res;
> +                       pp->mem->name = "MEM";
> +                       pp->mem_size = resource_size(pp->mem);
> +                       pp->mem_bus_addr = pp->mem->start - win->offset;
> +                       break;
> +               case 0:
> +                       pp->cfg = win->res;
> +                       pp->cfg0_size = resource_size(pp->cfg)/2;
> +                       pp->cfg1_size = resource_size(pp->cfg)/2;
> +                       pp->cfg0_base = pp->cfg->start;
> +                       pp->cfg1_base = pp->cfg->start + pp->cfg0_size;
> +                       break;
> +               case IORESOURCE_BUS:
> +                       pp->busn = win->res;
> +                       break;
> +               default:
> +                       continue;
>                 }
>         }
>
> -       ret = of_pci_parse_bus_range(np, &pp->busn);
> -       if (ret < 0) {
> -               pp->busn.name = np->name;
> -               pp->busn.start = 0;
> -               pp->busn.end = 0xff;
> -               pp->busn.flags = IORESOURCE_BUS;
> -               dev_dbg(pp->dev, "failed to parse bus-range property: %d, using default %pR\n",
> -                       ret, &pp->busn);
> -       }
> -
>         if (!pp->dbi_base) {
> -               pp->dbi_base = devm_ioremap(pp->dev, pp->cfg.start,
> -                                       resource_size(&pp->cfg));
> +               pp->dbi_base = devm_ioremap(pp->dev, pp->cfg->start,
> +                                       resource_size(pp->cfg));
>                 if (!pp->dbi_base) {
>                         dev_err(pp->dev, "error with ioremap\n");
>                         return -ENOMEM;
>                 }
>         }
>
> -       pp->mem_base = pp->mem.start;
> +       pp->mem_base = pp->mem->start;
>
>         if (!pp->va_cfg0_base) {
>                 pp->va_cfg0_base = devm_ioremap(pp->dev, pp->cfg0_base,
> @@ -505,7 +470,7 @@ int dw_pcie_host_init(struct pcie_port *pp)
>
>         if (!pp->ops->rd_other_conf)
>                 dw_pcie_prog_outbound_atu(pp, PCIE_ATU_REGION_INDEX1,
> -                                         PCIE_ATU_TYPE_MEM, pp->mem_mod_base,
> +                                         PCIE_ATU_TYPE_MEM, pp->mem_base,
>                                           pp->mem_bus_addr, pp->mem_size);
>
>         dw_pcie_wr_own_conf(pp, PCI_BASE_ADDRESS_0, 4, 0);
> @@ -517,15 +482,30 @@ int dw_pcie_host_init(struct pcie_port *pp)
>         val |= PORT_LOGIC_SPEED_CHANGE;
>         dw_pcie_wr_own_conf(pp, PCIE_LINK_WIDTH_SPEED_CONTROL, 4, val);
>
> -#ifdef CONFIG_PCI_MSI
> +       pp->root_bus_nr = pp->busn->start;
> +       bus = pci_create_root_bus(pp->dev, pp->root_bus_nr, &dw_pcie_ops,
> +                                 pp, &res);
> +       if (!bus)
> +               return -ENOMEM;
> +
> +#ifdef CONFIG_GENERIC_MSI_IRQ_DOMAIN
> +       bus->msi = container_of(&pp->irq_domain, struct msi_controller, domain);
> +#else
>         dw_pcie_msi_chip.dev = pp->dev;
> -       dw_pci.msi_ctrl = &dw_pcie_msi_chip;
> +       bus->msi = &dw_pcie_msi_chip;
>  #endif
>
> -       dw_pci.nr_controllers = 1;
> -       dw_pci.private_data = (void **)&pp;
> +       pci_scan_child_bus(bus);
> +       if (pp->ops->scan_bus)
> +               pp->ops->scan_bus(pp);
> +
> +#ifdef CONFIG_ARM
> +       /* support old dtbs that incorrectly describe IRQs */
> +       pci_fixup_irqs(pci_common_swizzle, of_irq_parse_and_map_pci);
> +#endif
>
> -       pci_common_init_dev(pp->dev, &dw_pci);
> +       pci_assign_unassigned_bus_resources(bus);
> +       pci_bus_add_devices(bus);
>
>         return 0;
>  }
> @@ -544,12 +524,12 @@ static int dw_pcie_rd_other_conf(struct pcie_port *pp, struct pci_bus *bus,
>
>         if (bus->parent->number == pp->root_bus_nr) {
>                 type = PCIE_ATU_TYPE_CFG0;
> -               cpu_addr = pp->cfg0_mod_base;
> +               cpu_addr = pp->cfg0_base;
>                 cfg_size = pp->cfg0_size;
>                 va_cfg_base = pp->va_cfg0_base;
>         } else {
>                 type = PCIE_ATU_TYPE_CFG1;
> -               cpu_addr = pp->cfg1_mod_base;
> +               cpu_addr = pp->cfg1_base;
>                 cfg_size = pp->cfg1_size;
>                 va_cfg_base = pp->va_cfg1_base;
>         }
> @@ -559,7 +539,7 @@ static int dw_pcie_rd_other_conf(struct pcie_port *pp, struct pci_bus *bus,
>                                   busdev, cfg_size);
>         ret = dw_pcie_cfg_read(va_cfg_base + address, where, size, val);
>         dw_pcie_prog_outbound_atu(pp, PCIE_ATU_REGION_INDEX0,
> -                                 PCIE_ATU_TYPE_IO, pp->io_mod_base,
> +                                 PCIE_ATU_TYPE_IO, pp->io_base,
>                                   pp->io_bus_addr, pp->io_size);
>
>         return ret;
> @@ -579,12 +559,12 @@ static int dw_pcie_wr_other_conf(struct pcie_port *pp, struct pci_bus *bus,
>
>         if (bus->parent->number == pp->root_bus_nr) {
>                 type = PCIE_ATU_TYPE_CFG0;
> -               cpu_addr = pp->cfg0_mod_base;
> +               cpu_addr = pp->cfg0_base;
>                 cfg_size = pp->cfg0_size;
>                 va_cfg_base = pp->va_cfg0_base;
>         } else {
>                 type = PCIE_ATU_TYPE_CFG1;
> -               cpu_addr = pp->cfg1_mod_base;
> +               cpu_addr = pp->cfg1_base;
>                 cfg_size = pp->cfg1_size;
>                 va_cfg_base = pp->va_cfg1_base;
>         }
> @@ -594,7 +574,7 @@ static int dw_pcie_wr_other_conf(struct pcie_port *pp, struct pci_bus *bus,
>                                   busdev, cfg_size);
>         ret = dw_pcie_cfg_write(va_cfg_base + address, where, size, val);
>         dw_pcie_prog_outbound_atu(pp, PCIE_ATU_REGION_INDEX0,
> -                                 PCIE_ATU_TYPE_IO, pp->io_mod_base,
> +                                 PCIE_ATU_TYPE_IO, pp->io_base,
>                                   pp->io_bus_addr, pp->io_size);
>
>         return ret;
> @@ -626,7 +606,7 @@ static int dw_pcie_valid_config(struct pcie_port *pp,
>  static int dw_pcie_rd_conf(struct pci_bus *bus, u32 devfn, int where,
>                         int size, u32 *val)
>  {
> -       struct pcie_port *pp = sys_to_pcie(bus->sysdata);
> +       struct pcie_port *pp = bus->sysdata;
>         int ret;
>
>         if (dw_pcie_valid_config(pp, bus, PCI_SLOT(devfn)) == 0) {
> @@ -650,7 +630,7 @@ static int dw_pcie_rd_conf(struct pci_bus *bus, u32 devfn, int where,
>  static int dw_pcie_wr_conf(struct pci_bus *bus, u32 devfn,
>                         int where, int size, u32 val)
>  {
> -       struct pcie_port *pp = sys_to_pcie(bus->sysdata);
> +       struct pcie_port *pp = bus->sysdata;
>         int ret;
>
>         if (dw_pcie_valid_config(pp, bus, PCI_SLOT(devfn)) == 0)
> @@ -674,62 +654,6 @@ static struct pci_ops dw_pcie_ops = {
>         .write = dw_pcie_wr_conf,
>  };
>
> -static int dw_pcie_setup(int nr, struct pci_sys_data *sys)
> -{
> -       struct pcie_port *pp;
> -
> -       pp = sys_to_pcie(sys);
> -
> -       if (global_io_offset < SZ_1M && pp->io_size > 0) {
> -               sys->io_offset = global_io_offset - pp->io_bus_addr;
> -               pci_ioremap_io(global_io_offset, pp->io_base);
> -               global_io_offset += SZ_64K;
> -               pci_add_resource_offset(&sys->resources, &pp->io,
> -                                       sys->io_offset);
> -       }
> -
> -       sys->mem_offset = pp->mem.start - pp->mem_bus_addr;
> -       pci_add_resource_offset(&sys->resources, &pp->mem, sys->mem_offset);
> -       pci_add_resource(&sys->resources, &pp->busn);
> -
> -       return 1;
> -}
> -
> -static struct pci_bus *dw_pcie_scan_bus(int nr, struct pci_sys_data *sys)
> -{
> -       struct pci_bus *bus;
> -       struct pcie_port *pp = sys_to_pcie(sys);
> -
> -       pp->root_bus_nr = sys->busnr;
> -       bus = pci_scan_root_bus(pp->dev, sys->busnr,
> -                                 &dw_pcie_ops, sys, &sys->resources);
> -       if (!bus)
> -               return NULL;
> -
> -       if (bus && pp->ops->scan_bus)
> -               pp->ops->scan_bus(pp);
> -
> -       return bus;
> -}
> -
> -static int dw_pcie_map_irq(const struct pci_dev *dev, u8 slot, u8 pin)
> -{
> -       struct pcie_port *pp = sys_to_pcie(dev->bus->sysdata);
> -       int irq;
> -
> -       irq = of_irq_parse_and_map_pci(dev, slot, pin);
> -       if (!irq)
> -               irq = pp->irq;
> -
> -       return irq;
> -}
> -
> -static struct hw_pci dw_pci = {
> -       .setup          = dw_pcie_setup,
> -       .scan           = dw_pcie_scan_bus,
> -       .map_irq        = dw_pcie_map_irq,
> -};
> -
>  void dw_pcie_setup_rc(struct pcie_port *pp)
>  {
>         u32 val;
> diff --git a/drivers/pci/host/pcie-designware.h b/drivers/pci/host/pcie-designware.h
> index d0bbd27..264c969 100644
> --- a/drivers/pci/host/pcie-designware.h
> +++ b/drivers/pci/host/pcie-designware.h
> @@ -27,25 +27,21 @@ struct pcie_port {
>         u8                      root_bus_nr;
>         void __iomem            *dbi_base;
>         u64                     cfg0_base;
> -       u64                     cfg0_mod_base;
>         void __iomem            *va_cfg0_base;
>         u32                     cfg0_size;
>         u64                     cfg1_base;
> -       u64                     cfg1_mod_base;
>         void __iomem            *va_cfg1_base;
>         u32                     cfg1_size;
> -       u64                     io_base;
> -       u64                     io_mod_base;
> +       resource_size_t         io_base;
>         phys_addr_t             io_bus_addr;
>         u32                     io_size;
>         u64                     mem_base;
> -       u64                     mem_mod_base;
>         phys_addr_t             mem_bus_addr;
>         u32                     mem_size;
> -       struct resource         cfg;
> -       struct resource         io;
> -       struct resource         mem;
> -       struct resource         busn;
> +       struct resource         *cfg;
> +       struct resource         *io;
> +       struct resource         *mem;
> +       struct resource         *busn;
>         int                     irq;
>         u32                     lanes;
>         struct pcie_host_ops    *ops;
> --
> 1.9.1
>
>
> _______________________________________________
> linux-arm-kernel mailing list
> linux-arm-kernel at lists.infradead.org
> http://lists.infradead.org/mailman/listinfo/linux-arm-kernel


From k.kozlowski at samsung.com  Thu Aug 27 05:57:52 2015
From: k.kozlowski at samsung.com (Krzysztof Kozlowski)
Date: Thu, 27 Aug 2015 21:57:52 +0900
Subject: [PATCH 1/5] DMA: pl330: support burst mode for dev-to-mem and
 mem-to-dev transmit
In-Reply-To: <1440665313-31603-1-git-send-email-shawn.lin@rock-chips.com>
References: <1440665280-31557-1-git-send-email-shawn.lin@rock-chips.com>
 <1440665313-31603-1-git-send-email-shawn.lin@rock-chips.com>
Message-ID: <CAJKOXPdw+ZZURRPUNvKHdx7wRG7M-Frqmvq46KFM_ckGq8h0Yg@mail.gmail.com>

2015-08-27 17:48 GMT+09:00 Shawn Lin <shawn.lin at rock-chips.com>:
>
> This patch adds to support burst mode for dev-to-mem and
> mem-to-dev transmit.
>
> Signed-off-by: Boojin Kim <boojin.kim at samsung.com>
> Signed-off-by: Addy Ke <addy.ke at rock-chips.com>
> Signed-off-by: Shawn Lin <shawn.lin at rock-chips.com>
> cc: Heiko Stuebner <heiko at sntech.de>
> cc: Doug Anderson <dianders at chromium.org>
> cc: Olof Johansson <olofj at google.com>
> Reviewed-and-tested-by: Sonny Rao <sonnyrao at chromium.org>

For the entire patchset: I would prefer to see someone's
reviewed/tested tag in his response. Sending a version 1 of patchset
(regardless of Boojin Kim's work two years ago) with such tag could
mean anything. I cannot verify it easily (unless digging somewhere...
or asking people). You could add for example: Reviewed-by Santa Claus.
Should I sent a letter to him asking for confirmation? :)

More seriously - reviewed-by is a statement (please look at
Documentation/SubmittingPatches) and you cannot force someone to make
that statement. He must make such statement on his own.

That's all from my side since I don't feel skilled enough to review the code.

Best regards,
Krzysztof

>
> ---
>
>  drivers/dma/pl330.c | 18 ++++++++++++------
>  1 file changed, 12 insertions(+), 6 deletions(-)
>
> diff --git a/drivers/dma/pl330.c b/drivers/dma/pl330.c
> index ecab4ea0..0d544d2 100644
> --- a/drivers/dma/pl330.c
> +++ b/drivers/dma/pl330.c
> @@ -1141,10 +1141,13 @@ static inline int _ldst_devtomem(unsigned dry_run, u8 buf[],
>                 const struct _xfer_spec *pxs, int cyc)
>  {
>         int off = 0;
> +       enum pl330_cond cond;
> +
> +       cond = (pxs->desc->rqcfg.brst_len == 1) ? SINGLE : BURST;
>
>         while (cyc--) {
> -               off += _emit_WFP(dry_run, &buf[off], SINGLE, pxs->desc->peri);
> -               off += _emit_LDP(dry_run, &buf[off], SINGLE, pxs->desc->peri);
> +               off += _emit_WFP(dry_run, &buf[off], cond, pxs->desc->peri);
> +               off += _emit_LDP(dry_run, &buf[off], cond, pxs->desc->peri);
>                 off += _emit_ST(dry_run, &buf[off], ALWAYS);
>                 off += _emit_FLUSHP(dry_run, &buf[off], pxs->desc->peri);
>         }
> @@ -1156,11 +1159,14 @@ static inline int _ldst_memtodev(unsigned dry_run, u8 buf[],
>                 const struct _xfer_spec *pxs, int cyc)
>  {
>         int off = 0;
> +       enum pl330_cond cond;
> +
> +       cond = (pxs->desc->rqcfg.brst_len == 1) ? SINGLE : BURST;
>
>         while (cyc--) {
> -               off += _emit_WFP(dry_run, &buf[off], SINGLE, pxs->desc->peri);
> +               off += _emit_WFP(dry_run, &buf[off], cond, pxs->desc->peri);
>                 off += _emit_LD(dry_run, &buf[off], ALWAYS);
> -               off += _emit_STP(dry_run, &buf[off], SINGLE, pxs->desc->peri);
> +               off += _emit_STP(dry_run, &buf[off], cond, pxs->desc->peri);
>                 off += _emit_FLUSHP(dry_run, &buf[off], pxs->desc->peri);
>         }
>
> @@ -2557,7 +2563,7 @@ static struct dma_async_tx_descriptor *pl330_prep_dma_cyclic(
>
>                 desc->rqtype = direction;
>                 desc->rqcfg.brst_size = pch->burst_sz;
> -               desc->rqcfg.brst_len = 1;
> +               desc->rqcfg.brst_len = pch->burst_len;
>                 desc->bytes_requested = period_len;
>                 fill_px(&desc->px, dst, src, period_len);
>
> @@ -2702,7 +2708,7 @@ pl330_prep_slave_sg(struct dma_chan *chan, struct scatterlist *sgl,
>                 }
>
>                 desc->rqcfg.brst_size = pch->burst_sz;
> -               desc->rqcfg.brst_len = 1;
> +               desc->rqcfg.brst_len = pch->burst_len;
>                 desc->rqtype = direction;
>                 desc->bytes_requested = sg_dma_len(sg);
>         }
> --
> 2.3.7
>
>
> --
> To unsubscribe from this list: send the line "unsubscribe dmaengine" in
> the body of a message to majordomo at vger.kernel.org
> More majordomo info at  http://vger.kernel.org/majordomo-info.html


From balbi at ti.com  Thu Aug 27 06:02:18 2015
From: balbi at ti.com (Felipe Balbi)
Date: Thu, 27 Aug 2015 08:02:18 -0500
Subject: CONFIG_DEBUG_SHIRQ and PM
In-Reply-To: <CAAEAJfAPB1N-xcz+HbHCcF8JaXAVL05CSwpQGi7ea+114mMpmw@mail.gmail.com>
References: <20150825195830.GH27534@saruman.tx.rr.com>
 <CAAEAJfCY1BRuoQCWfD2pCq36E54vDB5Coy2S7rz3RfL2BVLGaw@mail.gmail.com>
 <20150826193820.GT14625@saruman.tx.rr.com>
 <CAAEAJfAPVgxhRnfYJYzebFJDRJ4Ooam6n+0B5HJ-+uLJ0exTLA@mail.gmail.com>
 <20150826200300.GU14625@saruman.tx.rr.com>
 <CAAEAJfB3iiRENEKm6xx-kLae5AR6BV0XVo0KNkb8-okvLjhFhg@mail.gmail.com>
 <20150826202429.GV14625@saruman.tx.rr.com>
 <CAAEAJfAPB1N-xcz+HbHCcF8JaXAVL05CSwpQGi7ea+114mMpmw@mail.gmail.com>
Message-ID: <20150827130218.GA4701@saruman.tx.rr.com>

On Wed, Aug 26, 2015 at 05:36:24PM -0300, Ezequiel Garcia wrote:
> On 26 August 2015 at 17:24, Felipe Balbi <balbi at ti.com> wrote:
> [..]
> >>
> >> static irqreturn_t tw68_irq(int irq, void *dev_id)
> >> {
> >>         struct tw68_dev *dev = dev_id;
> >>         u32 status, orig;
> >>         int loop;
> >>
> >>         status = orig = tw_readl(TW68_INTSTAT) & dev->pci_irqmask;
> >
> > Now try to read that register when your clock is gated. That's the
> > problem I'm talking about. Everything about the handler is functioning
> > correctly; however clocks are gated in ->remove() and free_irq() is
> > only called *AFTER* ->remove() has returned.
> >
> 
> Yeah, it's pretty clear you are talking about clocks here. That's
> why I said "read won't stall" in the next paragraph.
> 
> >>         [etc]
> >> }
> >>
> >> The IRQ handler accesses the device struct and then
> >> reads through PCI. So if you use devm_request_irq
> >> you need to make sure the device struct is still allocated
> >> after remove(), and the PCI read won't stall or crash.
> >
> > dude, that's not the problem I'm talking about. I still have my
> > private_data around, what I don't have is:
> >
> >               _            _
> >   __ _    ___| | ___   ___| | __
> >  / _` |  / __| |/ _ \ / __| |/ /
> > | (_| | | (__| | (_) | (__|   <
> >  \__,_|  \___|_|\___/ \___|_|\_\
> >
> >
> 
> Yes, *you* may have your private data around and have a clock gated,
> others (the tw68 for instance) may have its region released and unmapped.
> 
> And yet others may have $whatever resource released in the
> remove() and assume it's available in the IRQ handler.
> 
> I honestly can't think why using request_irq / free_irq to solve this
> is a workaround.

because it'll, eventually, boil down to not using devm_* at all and
that's pretty stupid.

-- 
balbi
-------------- next part --------------
A non-text attachment was scrubbed...
Name: signature.asc
Type: application/pgp-signature
Size: 819 bytes
Desc: Digital signature
URL: <http://lists.infradead.org/pipermail/linux-arm-kernel/attachments/20150827/d7668b03/attachment.sig>

From eric.auger at linaro.org  Thu Aug 27 06:03:12 2015
From: eric.auger at linaro.org (Eric Auger)
Date: Thu, 27 Aug 2015 15:03:12 +0200
Subject: [PATCH v4 0/4] irqchip: GICv2/v3: Add support for
 irq_vcpu_affinity
In-Reply-To: <1440604845-28229-1-git-send-email-marc.zyngier@arm.com>
References: <1440604845-28229-1-git-send-email-marc.zyngier@arm.com>
Message-ID: <55DF0A90.9010407@linaro.org>

Hi Marc,

I tested the series on Calxeda Midway with VFIO use case. Also reviewed
it again without finding anything new.

Tested-by: Eric Auger <eric.auger at linaro.org>
Reviewed-by: Eric Auger <eric.auger at linaro.org>

Best Regards

Eric


On 08/26/2015 06:00 PM, Marc Zyngier wrote:
> The GICv2 and GICv3 architectures allow an active physical interrupt
> to be forwarded to a guest, and the guest to indirectly perform the
> deactivation of the interrupt by performing an EOI on the virtual
> interrupt (see for example the GICv2 spec, 3.2.1).
> 
> This allows some substantial performance improvement for level
> triggered interrupts that otherwise have to be masked/unmasked in
> VFIO, not to mention the required trap back to KVM when the guest
> performs an EOI.
> 
> To enable this, the GICs need to be switched to a different EOImode,
> where a taken interrupt can be left "active" (which prevents the same
> interrupt from being taken again), while other interrupts are still
> being processed normally.
> 
> We also use the new irq_set_vcpu_affinity hook that was introduced for
> Intel's "Posted Interrupts" to determine whether or not to perform the
> deactivation at EOI-time.
> 
> As all of this only makes sense when the kernel can behave as a
> hypervisor, we only enable this mode on detecting that the kernel was
> actually booted in HYP mode, and that the GIC supports this feature.
> 
> This series is a complete rework of a RFC I sent over a year ago:
> 
> http://lists.infradead.org/pipermail/linux-arm-kernel/2014-June/266328.html
> 
> Since then, a lot has been either merged (the irqchip_state) or reworked
> (my active-timer series: http://www.spinics.net/lists/kvm/msg118768.html),
> and this implements the last few bits for Eric Auger's series to
> finally make it into the kernel:
> 
> https://lkml.org/lkml/2015/7/2/268
> https://lkml.org/lkml/2015/7/6/291
> 
> With all these patches combined, physical interrupt routing from the
> kernel into a VM becomes possible.
> 
> Note that the implementation makes use of the static_key mechanism,
> which is undergoing an extensive rework in 4.3. I intend to convert
> this code once both are in mainline.
> 
> This has been tested on Juno (GICv2) and FastModel (GICv3). A branch
> is available at:
> 
> git://git.kernel.org/pub/scm/linux/kernel/git/maz/arm-platforms.git irq/gic-irq-vcpu-affinity-v4
> 
> * From v3:
>   - Use separate irq_chip structures, leading to much nicer code (tglx)
>   - Dropped Eric's Tested/Reviewed-by as there is significant changes
> 
> * From v2:
>   - Another small fix from Eric
>   - Some commit message cleanups
> 
> * From v1:
>   - Fixes after review from Eric
>   - Got rid of the cascaded GICv2 hack (it was broken anyway)
>   - Folded the LPI deactivation patch (it makes more sense as part of
>     the main one.
>   - Some clarifying comments about the "deactivate on mask"
>   - I haven't retained Eric's Reviewed/Tested-by, as the code as
>     significantly changed on GICv2
> 
> Marc Zyngier (4):
>   irqchip: GICv3: Convert to EOImode == 1
>   irqchip: GICv3: Don't deactivate interrupts forwarded to a guest
>   irqchip: GIC: Convert to EOImode == 1
>   irqchip: GIC: Don't deactivate interrupts forwarded to a guest
> 
>  drivers/irqchip/irq-gic-v3.c       |  70 +++++++++++++++++++++--
>  drivers/irqchip/irq-gic.c          | 111 ++++++++++++++++++++++++++++++++++++-
>  include/linux/irqchip/arm-gic-v3.h |   9 +++
>  include/linux/irqchip/arm-gic.h    |   4 ++
>  4 files changed, 188 insertions(+), 6 deletions(-)
> 



From eric.auger at linaro.org  Thu Aug 27 06:05:01 2015
From: eric.auger at linaro.org (Eric Auger)
Date: Thu, 27 Aug 2015 15:05:01 +0200
Subject: [PATCH v4 0/4] VFIO platform reset
In-Reply-To: <55DEFAFE.3000909@linaro.org>
References: <1434359385-19916-1-git-send-email-eric.auger@linaro.org>
 <55DEFAFE.3000909@linaro.org>
Message-ID: <55DF0AFD.7020806@linaro.org>

Dear all,

Please ignore this email. It is a reply to a wrong thread (was targeting
[PATCH v4 0/4] irqchip: GICv2/v3: Add support for irq_vcpu_affinity).

My apologies

Best Regards

Eric

On 08/27/2015 01:56 PM, Eric Auger wrote:
> Hi Marc,
> 
> I tested the series on Calxeda Midway with VFIO use case. Also reviewed
> it again without finding anything new.
> 
> Tested-by: Eric Auger <eric.auger at linaro.org>
> Reviewed-by: Eric Auger <eric.auger at linaro.org>
> 
> Best Regards
> 
> Eric
> 
> On 06/15/2015 11:09 AM, Eric Auger wrote:
>> In situations where the userspace driver is stopped abnormally and the
>> VFIO platform device is released, the assigned HW device currently is
>> left running. As a consequence the HW device might continue issuing IRQs
>> and performing DMA accesses.
>>
>> On release, no physical IRQ handler is setup anymore. Also the DMA buffers
>> are unmapped leading to IOMMU aborts. So there is no serious consequence.
>>
>> However when assigning that HW device again to another userspace driver,
>> this latter might face some unexpected IRQs and DMA accesses, which are
>> the result of the previous assignment.
>>
>> In virtualization use-case, a VM newly granted with that HW device may be
>> impacted by the assignment of that device to a previous VM:
>> - IRQs may be injected very early when booting the new guest, even before
>>   the guest driver has initialized leading to possible driver state
>>   inconsistency.
>> - DMA accesses may hit the newly mapped VM address space at addresses that
>>   may jeopardize the integrity of the newly installed VM.
>>
>> Obviously the criticity depends on the assigned HW device.
>>
>> As opposed to PCI, there is no standard mechanism to reset the platform
>> device.
>>
>> This series proposes to implement device specific reset functions in
>> separate in-kernel vfio reset modules. The vfio-platform driver holds
>> a whitelist of implemented triplets (compat string, module name,
>> reset function name). When the vfio-platform driver is probed it identifies
>> the fellow reset module/function matching the compat string of the
>> device, if any, and forces the load of this reset module.
>>
>> A first reset module is provided: the vfio-platform-calxedaxgmac
>> module which implements a basic reset for the Calxeda xgmac.
>>
>> The series can be found at
>> https://git.linaro.org/people/eric.auger/linux.git/shortlog/refs/heads/v4.1-rc8-reset-v4
>>
>> History:
>> v3 -> v4:
>> - fix the commit message of "VFIO: platform: add reset struct and lookup table"
>>
>> v2 -> v3:
>> - remove void module_init/exit functions in calxeda reset module
>> - remove enum vfio_platform_reset_type
>> - for reset lookup, use ARRAY_SIZE
>> - in reset put use symbol_put_addr
>>
>> v1 -> v2:
>> - much simplified compared to v1 although principle of external modules is
>>   kept: removed mechanism of dynamic registration of reset functions
>> - list is replaced by whitelist lookup table
>> - name of the reset function also stored in the lookup table
>> - autoload of reset modules
>>
>> RFC -> PATCH v1:
>> - solution now based on a lookup list instead of specialized driver
>>
>>
>> Eric Auger (4):
>>   VFIO: platform: add reset struct and lookup table
>>   VFIO: platform: add reset callback
>>   VFIO: platform: populate the reset function on probe
>>   VFIO: platform: Calxeda xgmac reset module
>>
>>  drivers/vfio/platform/Kconfig                      |  2 +
>>  drivers/vfio/platform/Makefile                     |  2 +
>>  drivers/vfio/platform/reset/Kconfig                |  7 ++
>>  drivers/vfio/platform/reset/Makefile               |  5 ++
>>  .../platform/reset/vfio_platform_calxedaxgmac.c    | 86 ++++++++++++++++++++++
>>  drivers/vfio/platform/vfio_platform_common.c       | 60 ++++++++++++++-
>>  drivers/vfio/platform/vfio_platform_private.h      |  7 ++
>>  7 files changed, 166 insertions(+), 3 deletions(-)
>>  create mode 100644 drivers/vfio/platform/reset/Kconfig
>>  create mode 100644 drivers/vfio/platform/reset/Makefile
>>  create mode 100644 drivers/vfio/platform/reset/vfio_platform_calxedaxgmac.c
>>
> 



From leilk.liu at mediatek.com  Thu Aug 27 06:09:04 2015
From: leilk.liu at mediatek.com (Leilk Liu)
Date: Thu, 27 Aug 2015 21:09:04 +0800
Subject: [PATCH] spi: mediatek: fix SPI_CMD_PAUSE_IE macro error
Message-ID: <1440680944-32537-1-git-send-email-leilk.liu@mediatek.com>

enable pause interrupt should use SPI_CMD_PAUSE_IE MACRO,
so fix it.

Signed-off-by: Leilk Liu <leilk.liu at mediatek.com>
---
 drivers/spi/spi-mt65xx.c | 2 +-
 1 file changed, 1 insertion(+), 1 deletion(-)

diff --git a/drivers/spi/spi-mt65xx.c b/drivers/spi/spi-mt65xx.c
index eaadc7e..d882261 100644
--- a/drivers/spi/spi-mt65xx.c
+++ b/drivers/spi/spi-mt65xx.c
@@ -158,7 +158,7 @@ static void mtk_spi_config(struct mtk_spi *mdata,
 #endif
 
 	/* set finish and pause interrupt always enable */
-	reg_val |= SPI_CMD_FINISH_IE | SPI_CMD_PAUSE_EN;
+	reg_val |= SPI_CMD_FINISH_IE | SPI_CMD_PAUSE_IE;
 
 	/* disable dma mode */
 	reg_val &= ~(SPI_CMD_TX_DMA | SPI_CMD_RX_DMA);
-- 
1.8.1.1.dirty



From shawn.lin at rock-chips.com  Thu Aug 27 06:17:33 2015
From: shawn.lin at rock-chips.com (Shawn Lin)
Date: Thu, 27 Aug 2015 21:17:33 +0800
Subject: [PATCH 5/5] Documentation: arm-pl330: add description of
 broken-no-flushp
In-Reply-To: <CAJKOXPfPLu09ZGChTRr+9-m_HLruYN6KvT=bvMrYrndCBtN2Rg@mail.gmail.com>
References: <1440665280-31557-1-git-send-email-shawn.lin@rock-chips.com>
 <1440665362-31771-1-git-send-email-shawn.lin@rock-chips.com>
 <CAJKOXPfPLu09ZGChTRr+9-m_HLruYN6KvT=bvMrYrndCBtN2Rg@mail.gmail.com>
Message-ID: <55DF0DED.3060702@rock-chips.com>

On 2015/8/27 20:59, Krzysztof Kozlowski write:
> 2015-08-27 17:49 GMT+09:00 Shawn Lin <shawn.lin at rock-chips.com>:
>> Signed-off-by: Shawn Lin <shawn.lin at rock-chips.com>
>> ---
>>
>>   Documentation/devicetree/bindings/dma/arm-pl330.txt | 1 +
>>   1 file changed, 1 insertion(+)
>>
>> diff --git a/Documentation/devicetree/bindings/dma/arm-pl330.txt b/Documentation/devicetree/bindings/dma/arm-pl330.txt
>> index 2675658..0f19268 100644
>> --- a/Documentation/devicetree/bindings/dma/arm-pl330.txt
>> +++ b/Documentation/devicetree/bindings/dma/arm-pl330.txt
>> @@ -15,6 +15,7 @@ Optional properties:
>>       cells in the dmas property of client device.
>>     - dma-channels: contains the total number of DMA channels supported by the DMAC
>>     - dma-requests: contains the total number of DMA requests supported by the DMAC
>> +  - broken-no-flushp: quirk for avoiding to execute DMAFLUSHP
>
> It looks like a device or vendor specific quirk so the property should
> have a prefix. For example:
> arm,pl330-broken-no-flushp
>

Got it.
Thanks, Krzysztof.

> Best regards,
> Krzysztof
>
>
>


-- 
Best Regards
Shawn Lin



From k.kozlowski at samsung.com  Thu Aug 27 05:59:57 2015
From: k.kozlowski at samsung.com (Krzysztof Kozlowski)
Date: Thu, 27 Aug 2015 21:59:57 +0900
Subject: [PATCH 5/5] Documentation: arm-pl330: add description of
 broken-no-flushp
In-Reply-To: <1440665362-31771-1-git-send-email-shawn.lin@rock-chips.com>
References: <1440665280-31557-1-git-send-email-shawn.lin@rock-chips.com>
 <1440665362-31771-1-git-send-email-shawn.lin@rock-chips.com>
Message-ID: <CAJKOXPfPLu09ZGChTRr+9-m_HLruYN6KvT=bvMrYrndCBtN2Rg@mail.gmail.com>

2015-08-27 17:49 GMT+09:00 Shawn Lin <shawn.lin at rock-chips.com>:
> Signed-off-by: Shawn Lin <shawn.lin at rock-chips.com>
> ---
>
>  Documentation/devicetree/bindings/dma/arm-pl330.txt | 1 +
>  1 file changed, 1 insertion(+)
>
> diff --git a/Documentation/devicetree/bindings/dma/arm-pl330.txt b/Documentation/devicetree/bindings/dma/arm-pl330.txt
> index 2675658..0f19268 100644
> --- a/Documentation/devicetree/bindings/dma/arm-pl330.txt
> +++ b/Documentation/devicetree/bindings/dma/arm-pl330.txt
> @@ -15,6 +15,7 @@ Optional properties:
>      cells in the dmas property of client device.
>    - dma-channels: contains the total number of DMA channels supported by the DMAC
>    - dma-requests: contains the total number of DMA requests supported by the DMAC
> +  - broken-no-flushp: quirk for avoiding to execute DMAFLUSHP

It looks like a device or vendor specific quirk so the property should
have a prefix. For example:
arm,pl330-broken-no-flushp

Best regards,
Krzysztof


From msalter at redhat.com  Thu Aug 27 06:27:37 2015
From: msalter at redhat.com (Mark Salter)
Date: Thu, 27 Aug 2015 09:27:37 -0400
Subject: [PATCH] ARM64: kernel: implement ACPI parking protocol
In-Reply-To: <20150827095026.GB21134@red-moon>
References: <1436959990-32054-1-git-send-email-lorenzo.pieralisi@arm.com>
 <1437063431.3583.2.camel@redhat.com> <20150716171221.GB18582@red-moon>
 <1437068449.3583.4.camel@redhat.com> <20150826160716.GB11863@red-moon>
 <1440616402.13044.16.camel@redhat.com> <20150827095026.GB21134@red-moon>
Message-ID: <1440682057.13044.24.camel@redhat.com>

On Thu, 2015-08-27 at 10:50 +0100, Lorenzo Pieralisi wrote:
> On Wed, Aug 26, 2015 at 08:13:22PM +0100, Mark Salter wrote:
> > On Wed, 2015-08-26 at 17:07 +0100, Lorenzo Pieralisi wrote:
> > > Mark,
> > > 
> > > On Thu, Jul 16, 2015 at 06:40:49PM +0100, Mark Salter wrote:
> > > 
> > > [...]
> > > 
> > > > > > The kernel will only add cached memory regions to linear 
> > > > > > mapping 
> > > > > > and
> > > > > > presumably, the FW will mark the mailboxes as uncached. 
> > > > > > Otherwise, 
> > > > > > it
> > > > > > is a FW bug. But I suppose we could run into problems with 
> > > > > > kernels
> > > > > > using 64K pagesize since firmware assumes 4k.
> > > > > 
> > > > > Nope, ioremap takes care of that, everything should be fine.
> > > > 
> > > > The mailbox is 4K. If it is next to a cached UEFI region, the 
> > > > kernel 
> > > > may
> > > > have to overlap the mailbox with a cached 64K mapping in order to 
> > > > include
> > > > the adjoining UEFI region in the linear map. Then the ioremap would 
> > > > fail
> > > > because the mailbox is included in the linear mapping.
> > > 
> > > You have to acknowledge that what you describe is a bit of a corner
> > > case (and a silly FW set-up), are you aware of any existing FW set-up
> > > where we actually hit the corner case above ?
> > 
> > Oh sure. It could definitely be a corner case. I'm not aware of any
> > existing firmware supporting the protocol implemented by your patch.
> 
> So basically there is no existing firmware implementing the ARM64 ACPI
> parking protocol.

None that I am aware of.

> 
> > So time will tell how well firmware vendors which do implement it
> > avoid the corner case problem. I am aware of some existing firmwares
> > which put the mailbox area in RAM which is also in the kernel linear
> > mapping as cached memory. But those wouldn't work with your patch for
> > more reasons than that.
> 
> They will have to fix them, that's the reason why I am pushing this
> patch upstream, and not a version that is massaged to make their
> non-compliant firmware compliant.

Absolutely agree.

> 
> > > I think it is fine to leave code as-is, at least the mailbox
> > > mappings, I will check to see I can improve the MADT parsing,
> > > somehow.
> > 
> > I'm not strenuously opposed to leaving it as-is. But we need to
> > acknowledge that if the 64K pagesize issue isn't covered by the
> > protocol spec, we're relying on firmware vendors to be diligent
> > not to break 64K pagesize kernels.
> 
> Should we try to amend the protocol spec ? I will raise the point,
> I do not see how we can prevent this issue otherwise, other than
> relying on vendors to be aware of the issue and prevent it.

Yes, please do.

> 
> Thanks,
> Lorenzo



From shawn.lin at rock-chips.com  Thu Aug 27 06:28:18 2015
From: shawn.lin at rock-chips.com (Shawn Lin)
Date: Thu, 27 Aug 2015 21:28:18 +0800
Subject: [PATCH 1/5] DMA: pl330: support burst mode for dev-to-mem and
 mem-to-dev transmit
In-Reply-To: <CAJKOXPdw+ZZURRPUNvKHdx7wRG7M-Frqmvq46KFM_ckGq8h0Yg@mail.gmail.com>
References: <1440665280-31557-1-git-send-email-shawn.lin@rock-chips.com>
 <1440665313-31603-1-git-send-email-shawn.lin@rock-chips.com>
 <CAJKOXPdw+ZZURRPUNvKHdx7wRG7M-Frqmvq46KFM_ckGq8h0Yg@mail.gmail.com>
Message-ID: <55DF1072.1070905@rock-chips.com>

? 2015/8/27 20:57, Krzysztof Kozlowski ??:
> 2015-08-27 17:48 GMT+09:00 Shawn Lin <shawn.lin at rock-chips.com>:
>>
>> This patch adds to support burst mode for dev-to-mem and
>> mem-to-dev transmit.
>>
>> Signed-off-by: Boojin Kim <boojin.kim at samsung.com>
>> Signed-off-by: Addy Ke <addy.ke at rock-chips.com>
>> Signed-off-by: Shawn Lin <shawn.lin at rock-chips.com>
>> cc: Heiko Stuebner <heiko at sntech.de>
>> cc: Doug Anderson <dianders at chromium.org>
>> cc: Olof Johansson <olofj at google.com>
>> Reviewed-and-tested-by: Sonny Rao <sonnyrao at chromium.org>
>
> For the entire patchset: I would prefer to see someone's
> reviewed/tested tag in his response. Sending a version 1 of patchset
> (regardless of Boojin Kim's work two years ago) with such tag could
> mean anything. I cannot verify it easily (unless digging somewhere...
> or asking people). You could add for example: Reviewed-by Santa Claus.
> Should I sent a letter to him asking for confirmation? :)
>

:) yes, you are right. I should comply with the rule, even if the 
patchest had been reviewed or tested by someone on another tree.

> More seriously - reviewed-by is a statement (please look at
> Documentation/SubmittingPatches) and you cannot force someone to make
> that statement. He must make such statement on his own.
>
> That's all from my side since I don't feel skilled enough to review the code.
>
> Best regards,
> Krzysztof
>
>>
>> ---
>>
>>   drivers/dma/pl330.c | 18 ++++++++++++------
>>   1 file changed, 12 insertions(+), 6 deletions(-)
>>
>> diff --git a/drivers/dma/pl330.c b/drivers/dma/pl330.c
>> index ecab4ea0..0d544d2 100644
>> --- a/drivers/dma/pl330.c
>> +++ b/drivers/dma/pl330.c
>> @@ -1141,10 +1141,13 @@ static inline int _ldst_devtomem(unsigned dry_run, u8 buf[],
>>                  const struct _xfer_spec *pxs, int cyc)
>>   {
>>          int off = 0;
>> +       enum pl330_cond cond;
>> +
>> +       cond = (pxs->desc->rqcfg.brst_len == 1) ? SINGLE : BURST;
>>
>>          while (cyc--) {
>> -               off += _emit_WFP(dry_run, &buf[off], SINGLE, pxs->desc->peri);
>> -               off += _emit_LDP(dry_run, &buf[off], SINGLE, pxs->desc->peri);
>> +               off += _emit_WFP(dry_run, &buf[off], cond, pxs->desc->peri);
>> +               off += _emit_LDP(dry_run, &buf[off], cond, pxs->desc->peri);
>>                  off += _emit_ST(dry_run, &buf[off], ALWAYS);
>>                  off += _emit_FLUSHP(dry_run, &buf[off], pxs->desc->peri);
>>          }
>> @@ -1156,11 +1159,14 @@ static inline int _ldst_memtodev(unsigned dry_run, u8 buf[],
>>                  const struct _xfer_spec *pxs, int cyc)
>>   {
>>          int off = 0;
>> +       enum pl330_cond cond;
>> +
>> +       cond = (pxs->desc->rqcfg.brst_len == 1) ? SINGLE : BURST;
>>
>>          while (cyc--) {
>> -               off += _emit_WFP(dry_run, &buf[off], SINGLE, pxs->desc->peri);
>> +               off += _emit_WFP(dry_run, &buf[off], cond, pxs->desc->peri);
>>                  off += _emit_LD(dry_run, &buf[off], ALWAYS);
>> -               off += _emit_STP(dry_run, &buf[off], SINGLE, pxs->desc->peri);
>> +               off += _emit_STP(dry_run, &buf[off], cond, pxs->desc->peri);
>>                  off += _emit_FLUSHP(dry_run, &buf[off], pxs->desc->peri);
>>          }
>>
>> @@ -2557,7 +2563,7 @@ static struct dma_async_tx_descriptor *pl330_prep_dma_cyclic(
>>
>>                  desc->rqtype = direction;
>>                  desc->rqcfg.brst_size = pch->burst_sz;
>> -               desc->rqcfg.brst_len = 1;
>> +               desc->rqcfg.brst_len = pch->burst_len;
>>                  desc->bytes_requested = period_len;
>>                  fill_px(&desc->px, dst, src, period_len);
>>
>> @@ -2702,7 +2708,7 @@ pl330_prep_slave_sg(struct dma_chan *chan, struct scatterlist *sgl,
>>                  }
>>
>>                  desc->rqcfg.brst_size = pch->burst_sz;
>> -               desc->rqcfg.brst_len = 1;
>> +               desc->rqcfg.brst_len = pch->burst_len;
>>                  desc->rqtype = direction;
>>                  desc->bytes_requested = sg_dma_len(sg);
>>          }
>> --
>> 2.3.7
>>
>>
>> --
>> To unsubscribe from this list: send the line "unsubscribe dmaengine" in
>> the body of a message to majordomo at vger.kernel.org
>> More majordomo info at  http://vger.kernel.org/majordomo-info.html
>
>
>


-- 
Best Regards
Shawn Lin



From grygorii.strashko at ti.com  Thu Aug 27 06:38:47 2015
From: grygorii.strashko at ti.com (Grygorii Strashko)
Date: Thu, 27 Aug 2015 16:38:47 +0300
Subject: [PATCH] ARM: OMAP2+: omap-device: remove omap_device_late_init
 call completely
In-Reply-To: <20150826181006.GT4215@atomide.com>
References: <1440611890-4935-1-git-send-email-grygorii.strashko@ti.com>
 <20150826181006.GT4215@atomide.com>
Message-ID: <55DF12E7.10802@ti.com>

Hi Tony,

On 08/26/2015 09:10 PM, Tony Lindgren wrote:
> * Grygorii Strashko <grygorii.strashko at ti.com> [150826 11:01]:
>> Now Kernel fails to boot 50% of times (form build to build) with
>> RT-patchset applied due to the following race - on late boot
>> stages deferred_probe_work_func races with omap_device_late_ini
>>
>> late_initcall
>>   - deferred_probe_initcal() tries to re-probe all pending driver's probe.
>>     [In general, It's NOT expected to probe any other built-in drivers after
>>     deferred_probe_initcal() is finished, because most of
>>     late_initcall_sync/late_initcall functions expected that all driver
>>     or probed or deferred already.]
>>
>> - later on, some driver is probing in this case It's could cpsw.c
>>    (but could be any other drivers)
>>    cpsw_init
>>    - platform_driver_register
>>      - really_probe
>>         - driver_bound
>>           - driver_deferred_probe_trigger
>>    and boot proceed.
>>    So, at this moment we have  deferred_probe_work_func scheduled.
>>
>> late_initcall_sync
>>    - omap_device_late_init
>>      - omap_device_idle
>>
>> CPU1					CPU2
>>    - deferred_probe_work_func
>>      - really_probe
>>        - omap_hsmmc_probe
>> 	- pm_runtime_get_sync
>> 					late_initcall_sync
>> 					- omap_device_late_init
>> 						if (od->_driver_status != BUS_NOTIFY_BOUND_DRIVER) {
>> 							if (od->_state == OMAP_DEVICE_STATE_ENABLED) {
>> 								- omap_device_idle [ops - IP is disabled, ]
>> 	- [fail]
>> 	- pm_runtime_put_sync
>>            - omap_hsmmc_runtime_suspend [ooops!]
> 
> OK idling of unclaimed devices should not happen for deferred probe,
> it should only happen when there's no driver and no probing happening.
>   
>> Lets remove just remove omap_device_late_init completely as suggested
>> by Tero Kristo:
>>
>> "How about remove omap_device_late_init call completely. I don't think
>> it does anything useful at the moment; none of the omap devices get
>> enabled outside runtime_pm, so there should be no need to explicitly
>> disable the devices."
> 
> I think this is still needed from PM point of view as otherwise we
> don't idle any devices that don't have a driver available. Or am I
> missing something?
> 
> To me it seems the bug is relying on the BUS_NOTIFY_BOUND_DRIVER is
> not set in the deferred probe case.
> 


What do you think about below alternative?

diff --git a/arch/arm/mach-omap2/omap_device.c b/arch/arm/mach-omap2/omap_device.c
index 4cb8fd9..72ebc4c 100644
--- a/arch/arm/mach-omap2/omap_device.c
+++ b/arch/arm/mach-omap2/omap_device.c
@@ -901,7 +901,8 @@ static int __init omap_device_late_idle(struct device *dev, void *data)
                if (od->hwmods[i]->flags & HWMOD_INIT_NO_IDLE)
                        return 0;
 
-       if (od->_driver_status != BUS_NOTIFY_BOUND_DRIVER) {
+       if (od->_driver_status != BUS_NOTIFY_BOUND_DRIVER &&
+           od->_driver_status != BUS_NOTIFY_BIND_DRIVER) {
                if (od->_state == OMAP_DEVICE_STATE_ENABLED) {
                        dev_warn(dev, "%s: enabled but no driver.  Idling\n",
                                 __func__);



-- 
regards,
-grygorii


From marc.zyngier at arm.com  Thu Aug 27 07:05:47 2015
From: marc.zyngier at arm.com (Marc Zyngier)
Date: Thu, 27 Aug 2015 15:05:47 +0100
Subject: [PATCH] arm64: KVM: Do not inject a 64bit fault for a 32bit guest
Message-ID: <1440684348-5292-1-git-send-email-marc.zyngier@arm.com>

When injecting a fault into a 32bit guest, it seems rather idiotic
to also inject a 64bit fault that is only going to corrupt the
guest state, and lead to a situation where we restore an illegal
context.

Just fix the stupid bug that has been there from day 1.

Cc: stable at vger.kernel.org
Reported-by: Russell King <linux at arm.linux.org.uk>
Signed-off-by: Marc Zyngier <marc.zyngier at arm.com>
---
Will: Paolo being on holiday, do you mind merging this one
via your tree?

Thanks,

	M.

 arch/arm64/kvm/inject_fault.c | 12 ++++++------
 1 file changed, 6 insertions(+), 6 deletions(-)

diff --git a/arch/arm64/kvm/inject_fault.c b/arch/arm64/kvm/inject_fault.c
index f02530e..85c5715 100644
--- a/arch/arm64/kvm/inject_fault.c
+++ b/arch/arm64/kvm/inject_fault.c
@@ -168,8 +168,8 @@ void kvm_inject_dabt(struct kvm_vcpu *vcpu, unsigned long addr)
 {
 	if (!(vcpu->arch.hcr_el2 & HCR_RW))
 		inject_abt32(vcpu, false, addr);
-
-	inject_abt64(vcpu, false, addr);
+	else
+		inject_abt64(vcpu, false, addr);
 }
 
 /**
@@ -184,8 +184,8 @@ void kvm_inject_pabt(struct kvm_vcpu *vcpu, unsigned long addr)
 {
 	if (!(vcpu->arch.hcr_el2 & HCR_RW))
 		inject_abt32(vcpu, true, addr);
-
-	inject_abt64(vcpu, true, addr);
+	else
+		inject_abt64(vcpu, true, addr);
 }
 
 /**
@@ -198,6 +198,6 @@ void kvm_inject_undefined(struct kvm_vcpu *vcpu)
 {
 	if (!(vcpu->arch.hcr_el2 & HCR_RW))
 		inject_undef32(vcpu);
-
-	inject_undef64(vcpu);
+	else
+		inject_undef64(vcpu);
 }
-- 
2.1.4



From eric.auger at linaro.org  Thu Aug 27 07:16:37 2015
From: eric.auger at linaro.org (Eric Auger)
Date: Thu, 27 Aug 2015 16:16:37 +0200
Subject: [PATCH v2 10/15] KVM: arm64: add data structures to model ITS
 interrupt translation
In-Reply-To: <55DC4E3F.506@arm.com>
References: <1436538111-4294-1-git-send-email-andre.przywara@arm.com>
 <1436538111-4294-11-git-send-email-andre.przywara@arm.com>
 <55CCBBBF.1080407@linaro.org> <55DC4E3F.506@arm.com>
Message-ID: <55DF1BC5.3020100@linaro.org>

Hi Andre,
On 08/25/2015 01:15 PM, Andre Przywara wrote:
> Hi Eric,
> 
> On 13/08/15 16:46, Eric Auger wrote:
>>
>> On 07/10/2015 04:21 PM, Andre Przywara wrote:
>>> The GICv3 Interrupt Translation Service (ITS) uses tables in memory
>>> to allow a sophisticated interrupt routing. It features device tables,
>>> an interrupt table per device and a table connecting "collections" to
>>> actual CPUs (aka. redistributors in the GICv3 lingo).
>>> Since the interrupt numbers for the LPIs are allocated quite sparsely
>>> and the range can be quite huge (8192 LPIs being the minimum), using
>>> bitmaps or arrays for storing information is a waste of memory.
>>> We use linked lists instead, which we iterate linearily. This works
>>> very well with the actual number of LPIs/MSIs in the guest being
>>> quite low. Should the number of LPIs exceed the number where iterating
>>> through lists seems acceptable, we can later revisit this and use more
>>> efficient data structures.
>>>
>>> Signed-off-by: Andre Przywara <andre.przywara at arm.com>
>>> ---
>>>  include/kvm/arm_vgic.h  |  3 +++
>>>  virt/kvm/arm/its-emul.c | 48 ++++++++++++++++++++++++++++++++++++++++++++++++
>>>  2 files changed, 51 insertions(+)
>>>
>>> diff --git a/include/kvm/arm_vgic.h b/include/kvm/arm_vgic.h
>>> index b432055..1648668 100644
>>> --- a/include/kvm/arm_vgic.h
>>> +++ b/include/kvm/arm_vgic.h
>>> @@ -25,6 +25,7 @@
>>>  #include <linux/spinlock.h>
>>>  #include <linux/types.h>
>>>  #include <kvm/iodev.h>
>>> +#include <linux/list.h>
>>>  
>>>  #define VGIC_NR_IRQS_LEGACY	256
>>>  #define VGIC_NR_SGIS		16
>>> @@ -162,6 +163,8 @@ struct vgic_its {
>>>  	u64			cbaser;
>>>  	int			creadr;
>>>  	int			cwriter;
>>> +	struct list_head	device_list;
>>> +	struct list_head	collection_list;
>>>  };
>>>  
>>>  struct vgic_dist {
>>> diff --git a/virt/kvm/arm/its-emul.c b/virt/kvm/arm/its-emul.c
>>> index b498f06..7f217fa 100644
>>> --- a/virt/kvm/arm/its-emul.c
>>> +++ b/virt/kvm/arm/its-emul.c
>>> @@ -21,6 +21,7 @@
>>>  #include <linux/kvm.h>
>>>  #include <linux/kvm_host.h>
>>>  #include <linux/interrupt.h>
>>> +#include <linux/list.h>
>>>  
>>>  #include <linux/irqchip/arm-gic-v3.h>
>>>  #include <kvm/arm_vgic.h>
>>> @@ -32,6 +33,25 @@
>>>  #include "vgic.h"
>>>  #include "its-emul.h"
>>>  
>>> +struct its_device {
>>> +	struct list_head dev_list;
>>> +	struct list_head itt;
>>> +	u32 device_id;
>>> +};
>>> +
>>> +struct its_collection {
>>> +	struct list_head coll_list;
>>> +	u32 collection_id;
>>> +	u32 target_addr;
>>> +};
>>> +
>>> +struct its_itte {
>>> +	struct list_head itte_list;
>>> +	struct its_collection *collection;
>>> +	u32 lpi;
>>> +	u32 event_id;
>>> +};
>>> +
>>>  #define BASER_BASE_ADDRESS(x) ((x) & 0xfffffffff000ULL)
>>>  
>>>  /* The distributor lock is held by the VGIC MMIO handler. */
>>> @@ -311,6 +331,9 @@ int vits_init(struct kvm *kvm)
>>>  
>>>  	spin_lock_init(&its->lock);
>>>  
>>> +	INIT_LIST_HEAD(&its->device_list);
>>> +	INIT_LIST_HEAD(&its->collection_list);
>>> +
>>>  	its->enabled = false;
>>>  
>>>  	return -ENXIO;
>>> @@ -320,11 +343,36 @@ void vits_destroy(struct kvm *kvm)
>>>  {
>>>  	struct vgic_dist *dist = &kvm->arch.vgic;
>>>  	struct vgic_its *its = &dist->its;
>>> +	struct its_device *dev;
>>> +	struct its_itte *itte;
>>> +	struct list_head *dev_cur, *dev_temp;
>>> +	struct list_head *cur, *temp;
>>>  
>>>  	if (!vgic_has_its(kvm))
>>>  		return;
>>>  
>>> +	if (!its->device_list.next)
>> Why not using list_empty? But I think I would simply remove this since
>> the empty case if handle below...
> 
> list_empty() requires the list to be initialized before. This check here
> is to detect that map_resources was never called (this is only done on
> the first VCPU run) and thus device_list is basically still all zeroes.
> If we abort the guest without ever running a VCPU (for instance because
> some initialization failed), we call vits_destroy() anyway (because this
> is called when tearing down the VGIC device).
> So the check is here to detect early that vits_destroy() has been called
> without the ITS ever been fully initialized. This fixed a real bug when
> the guest start was aborted before the ITS was ever used.
> I will add a comment to make this clear.

OK. My next question is why don't we call vits_init in vgic_init after
dist->nr_cpus? I had in mind map_resources was linked to the setting of
vgic_dist_base & vgic_cpu_base. Here you do not depend on those
addresses? Do I miss smthg?
> 
>>> +		return;
>>> +
>>> +	spin_lock(&its->lock);
>>> +	list_for_each_safe(dev_cur, dev_temp, &its->device_list) {
>>> +		dev = container_of(dev_cur, struct its_device, dev_list);
>> isn't the usage of list_for_each_entry_safe more synthetic here?
Sorry my point was about the _ENTRY_ variant that should avoid to use
container_of, isn't it?

Eric
> 
> If I got this correctly, we need the _safe variant if we want to remove
> the list item within the loop. Or am I missing something here?
> 
> Cheers,
> Andre.
> 
> 
>>> +		list_for_each_safe(cur, temp, &dev->itt) {
>>> +			itte = (container_of(cur, struct its_itte, itte_list));
>> same
>>
>> Eric
>>> +			list_del(cur);
>>> +			kfree(itte);
>>> +		}
>>> +		list_del(dev_cur);
>>> +		kfree(dev);
>>> +	}
>>> +
>>> +	list_for_each_safe(cur, temp, &its->collection_list) {
>>> +		list_del(cur);
>>> +		kfree(container_of(cur, struct its_collection, coll_list));
>>> +	}
>>> +
>>>  	kfree(dist->pendbaser);
>>>  
>>>  	its->enabled = false;
>>> +	spin_unlock(&its->lock);
>>>  }
>>>
>>



From marc.zyngier at arm.com  Thu Aug 27 07:18:12 2015
From: marc.zyngier at arm.com (Marc Zyngier)
Date: Thu, 27 Aug 2015 15:18:12 +0100
Subject: [PATCH v4 0/4] irqchip: GICv2/v3: Add support for
 irq_vcpu_affinity
In-Reply-To: <55DF0A90.9010407@linaro.org>
References: <1440604845-28229-1-git-send-email-marc.zyngier@arm.com>
 <55DF0A90.9010407@linaro.org>
Message-ID: <55DF1C24.2030002@arm.com>

Hi Eric,

On 27/08/15 14:03, Eric Auger wrote:
> Hi Marc,
> 
> I tested the series on Calxeda Midway with VFIO use case. Also reviewed
> it again without finding anything new.
> 
> Tested-by: Eric Auger <eric.auger at linaro.org>
> Reviewed-by: Eric Auger <eric.auger at linaro.org>

Thanks a lot Eric, much appreciated!

	M.
-- 
Jazz is not dead. It just smells funny...


From shawn.lin at rock-chips.com  Thu Aug 27 07:23:39 2015
From: shawn.lin at rock-chips.com (Shawn Lin)
Date: Thu, 27 Aug 2015 22:23:39 +0800
Subject: [PATCH v1 0/5] Fix broken DMAFLUSHP on Rockchips platform
Message-ID: <1440685419-22037-1-git-send-email-shawn.lin@rock-chips.com>


The purpose of the DMAFLUSHP instruction:
- Tell the peripheral to clear its status and control registers.
- Send a message to the peripheral to resend its level status.

There are 3 timings described in PL330 Technical Reference Manual:
- Timing 1: Burst request, can work well without DMAFLUSHP.
- Timing 2: Single and burst request, DMAC will ignore the single
	    transfer request. This timing happens if there are single
	    and burst request.
- Timing 3: Single transfers for a burst request, DMAC should signals
	    datype to request the peripheral to flush the contents of
	    any control registers. This timing happens if there is
	    not enough MFIFO to places the burst data.

A peripheral may signal a DMA request during the execution of
DMAFLUSHP instruction, that cause DMA request being ignored by DMAC.

But DMAC and all peripherals on RK3X SoCs DO NOT support DMAFLUSHP.
It can't send a message to the peripheral to resend DMA request,
and the peripheral can't acknowledge a flush request from DMAC.
So all DMA requests should NOT be ignored by DMAC, and DMAC will not
notify the peripheral to flush.

To fix this problem, we need:
- Do NOT execute DMAFLUSHP instruction.
- Timing 2 and timing 3 should not happen.

Because on RK3X SoCs, there are 6 or below  channels and 32 MFIFO depth
for DMAC_BUS, and 8 channels and 64 MFIFO depth for DMAC_PERI, it is
impossible to hit the timing 3 if burst length is equal or less than 4.

Since the request type signal by the peripheral can only be set by
software. We can set Rockchip Soc's GRF_PERIDMAC_CON0[2:1] to select single
or burst request, if it is set b01,  all of the peripharals will signal a brust
request. So the timing 2 will not happen, too.

So DMAC on RK3X can support single or burst transfer, but can't support
mixed transfer.

Because burst transfer is more efficient than single transfer, this is
confirmed by our ASIC team, who strongly suggest to use burst transfer.
And this is confirmed by Addy's test on RK3288-Pink2 board, the speed of
spi flash burst transfer will increase about two times than single transfer.
Also, I have tested dw_mmc with pl330 on RK3188 platform to double confirm
the result. That means burst transfer is reansonable.

So we need a quirk not to execute DMAFLUSHP instruction and to use burst
transfer.

Note:
- The Rockchip Soc default value of GRF_PERIDMAC_CON0[2:1] is b01. To
  support brust transfer, these bits should not be changed in bootloader.


Changes in v1:
- rename broken-no-flushp to "arm,pl330-broken-no-flushp" suggested
  by Krzysztof.
- add From original author.
- remove Sunny's tag

Shawn Lin (5):
  DMA: pl330: support burst mode for dev-to-mem and mem-to-dev transmit
  DMA: pl330: add quirk for broken no flushp
  ARM: dts: Add arm,pl330-broken-no-flushp quirk for rk3288 platform
  ARM: dts: Add arm,pl330-broken-no-flushp quirk for rk3xxx platform
  Documentation: arm-pl330: add description of
    arm,pl330-broken-no-flushp

 .../devicetree/bindings/dma/arm-pl330.txt          |   1 +
 arch/arm/boot/dts/rk3288.dtsi                      |   3 +
 arch/arm/boot/dts/rk3xxx.dtsi                      |   3 +
 drivers/dma/pl330.c                                | 101 +++++++++++++++------
 4 files changed, 79 insertions(+), 29 deletions(-)

-- 
2.3.7




From shawn.lin at rock-chips.com  Thu Aug 27 07:24:16 2015
From: shawn.lin at rock-chips.com (Shawn Lin)
Date: Thu, 27 Aug 2015 22:24:16 +0800
Subject: [PATCH v1 1/5] DMA: pl330: support burst mode for dev-to-mem and
 mem-to-dev transmit
In-Reply-To: <1440685419-22037-1-git-send-email-shawn.lin@rock-chips.com>
References: <1440685419-22037-1-git-send-email-shawn.lin@rock-chips.com>
Message-ID: <1440685456-22081-1-git-send-email-shawn.lin@rock-chips.com>

From: Boojin Kim <boojin.kim at samsung.com>

This patch adds to support burst mode for dev-to-mem and
mem-to-dev transmit.

Signed-off-by: Boojin Kim <boojin.kim at samsung.com>
Signed-off-by: Addy Ke <addy.ke at rock-chips.com>
Signed-off-by: Shawn Lin <shawn.lin at rock-chips.com>
cc: Heiko Stuebner <heiko at sntech.de>
cc: Doug Anderson <dianders at chromium.org>
cc: Olof Johansson <olofj at google.com>

---

Changes in v1:
- rename broken-no-flushp to "arm,pl330-broken-no-flushp" suggested
  by Krzysztof.
- add From original author.
- remove Sunny's tag

 drivers/dma/pl330.c | 18 ++++++++++++------
 1 file changed, 12 insertions(+), 6 deletions(-)

diff --git a/drivers/dma/pl330.c b/drivers/dma/pl330.c
index ecab4ea0..0d544d2 100644
--- a/drivers/dma/pl330.c
+++ b/drivers/dma/pl330.c
@@ -1141,10 +1141,13 @@ static inline int _ldst_devtomem(unsigned dry_run, u8 buf[],
 		const struct _xfer_spec *pxs, int cyc)
 {
 	int off = 0;
+	enum pl330_cond cond;
+
+	cond = (pxs->desc->rqcfg.brst_len == 1) ? SINGLE : BURST;
 
 	while (cyc--) {
-		off += _emit_WFP(dry_run, &buf[off], SINGLE, pxs->desc->peri);
-		off += _emit_LDP(dry_run, &buf[off], SINGLE, pxs->desc->peri);
+		off += _emit_WFP(dry_run, &buf[off], cond, pxs->desc->peri);
+		off += _emit_LDP(dry_run, &buf[off], cond, pxs->desc->peri);
 		off += _emit_ST(dry_run, &buf[off], ALWAYS);
 		off += _emit_FLUSHP(dry_run, &buf[off], pxs->desc->peri);
 	}
@@ -1156,11 +1159,14 @@ static inline int _ldst_memtodev(unsigned dry_run, u8 buf[],
 		const struct _xfer_spec *pxs, int cyc)
 {
 	int off = 0;
+	enum pl330_cond cond;
+
+	cond = (pxs->desc->rqcfg.brst_len == 1) ? SINGLE : BURST;
 
 	while (cyc--) {
-		off += _emit_WFP(dry_run, &buf[off], SINGLE, pxs->desc->peri);
+		off += _emit_WFP(dry_run, &buf[off], cond, pxs->desc->peri);
 		off += _emit_LD(dry_run, &buf[off], ALWAYS);
-		off += _emit_STP(dry_run, &buf[off], SINGLE, pxs->desc->peri);
+		off += _emit_STP(dry_run, &buf[off], cond, pxs->desc->peri);
 		off += _emit_FLUSHP(dry_run, &buf[off], pxs->desc->peri);
 	}
 
@@ -2557,7 +2563,7 @@ static struct dma_async_tx_descriptor *pl330_prep_dma_cyclic(
 
 		desc->rqtype = direction;
 		desc->rqcfg.brst_size = pch->burst_sz;
-		desc->rqcfg.brst_len = 1;
+		desc->rqcfg.brst_len = pch->burst_len;
 		desc->bytes_requested = period_len;
 		fill_px(&desc->px, dst, src, period_len);
 
@@ -2702,7 +2708,7 @@ pl330_prep_slave_sg(struct dma_chan *chan, struct scatterlist *sgl,
 		}
 
 		desc->rqcfg.brst_size = pch->burst_sz;
-		desc->rqcfg.brst_len = 1;
+		desc->rqcfg.brst_len = pch->burst_len;
 		desc->rqtype = direction;
 		desc->bytes_requested = sg_dma_len(sg);
 	}
-- 
2.3.7




From shawn.lin at rock-chips.com  Thu Aug 27 07:24:31 2015
From: shawn.lin at rock-chips.com (Shawn Lin)
Date: Thu, 27 Aug 2015 22:24:31 +0800
Subject: [PATCH v1 2/5] DMA: pl330: add quirk for broken no flushp
In-Reply-To: <1440685419-22037-1-git-send-email-shawn.lin@rock-chips.com>
References: <1440685419-22037-1-git-send-email-shawn.lin@rock-chips.com>
Message-ID: <1440685471-22122-1-git-send-email-shawn.lin@rock-chips.com>

From: Addy Ke <addy.ke at rock-chips.com>

This patch add "arm,pl330-broken-no-flushp" quirk to avoid execute
DMAFLUSHP if Soc doesn't support it.

Signed-off-by: Addy Ke <addy.ke at rock-chips.com>
Signed-off-by: Shawn Lin <shawn.lin at rock-chips.com>
cc: Heiko Stuebner <heiko at sntech.de>
cc: Doug Anderson <dianders at chromium.org>
cc: Olof Johansson <olofj at google.com>

---

Changes in v1:
- rename broken-no-flushp to "arm,pl330-broken-no-flushp" suggested
  by Krzysztof.
- remove Sunny's tag

 drivers/dma/pl330.c | 87 ++++++++++++++++++++++++++++++++++++++---------------
 1 file changed, 62 insertions(+), 25 deletions(-)

diff --git a/drivers/dma/pl330.c b/drivers/dma/pl330.c
index 0d544d2..3b9b426 100644
--- a/drivers/dma/pl330.c
+++ b/drivers/dma/pl330.c
@@ -34,6 +34,8 @@
 #define PL330_MAX_IRQS		32
 #define PL330_MAX_PERI		32
 
+#define PL330_QUIRK_BROKEN_NO_FLUSHP BIT(0)
+
 enum pl330_cachectrl {
 	CCTRL0,		/* Noncacheable and nonbufferable */
 	CCTRL1,		/* Bufferable only */
@@ -488,6 +490,17 @@ struct pl330_dmac {
 	/* Peripheral channels connected to this DMAC */
 	unsigned int num_peripherals;
 	struct dma_pl330_chan *peripherals; /* keep at end */
+	int quirks;
+};
+
+static struct pl330_of_quirks {
+	char *quirk;
+	int id;
+} of_quirks[] = {
+	{
+		.quirk = "arm,pl330-broken-no-flushp",
+		.id = PL330_QUIRK_BROKEN_NO_FLUSHP,
+	}
 };
 
 struct dma_pl330_desc {
@@ -1137,53 +1150,68 @@ static inline int _ldst_memtomem(unsigned dry_run, u8 buf[],
 	return off;
 }
 
-static inline int _ldst_devtomem(unsigned dry_run, u8 buf[],
-		const struct _xfer_spec *pxs, int cyc)
+static inline int _ldst_devtomem(struct pl330_dmac *pl330, unsigned dry_run,
+				 u8 buf[], const struct _xfer_spec *pxs,
+				 int cyc)
 {
 	int off = 0;
 	enum pl330_cond cond;
 
-	cond = (pxs->desc->rqcfg.brst_len == 1) ? SINGLE : BURST;
+	if (pl330->quirks & PL330_QUIRK_BROKEN_NO_FLUSHP)
+		cond = BURST;
+	else
+		cond = (pxs->desc->rqcfg.brst_len == 1) ? SINGLE : BURST;
 
 	while (cyc--) {
 		off += _emit_WFP(dry_run, &buf[off], cond, pxs->desc->peri);
 		off += _emit_LDP(dry_run, &buf[off], cond, pxs->desc->peri);
 		off += _emit_ST(dry_run, &buf[off], ALWAYS);
-		off += _emit_FLUSHP(dry_run, &buf[off], pxs->desc->peri);
+
+		if (!(pl330->quirks & PL330_QUIRK_BROKEN_NO_FLUSHP))
+			off += _emit_FLUSHP(dry_run, &buf[off],
+					    pxs->desc->peri);
 	}
 
 	return off;
 }
 
-static inline int _ldst_memtodev(unsigned dry_run, u8 buf[],
-		const struct _xfer_spec *pxs, int cyc)
+static inline int _ldst_memtodev(struct pl330_dmac *pl330,
+				 unsigned dry_run, u8 buf[],
+				 const struct _xfer_spec *pxs, int cyc)
 {
 	int off = 0;
 	enum pl330_cond cond;
 
-	cond = (pxs->desc->rqcfg.brst_len == 1) ? SINGLE : BURST;
+	if (pl330->quirks & PL330_QUIRK_BROKEN_NO_FLUSHP)
+		cond = BURST;
+	else
+		cond = (pxs->desc->rqcfg.brst_len == 1) ? SINGLE : BURST;
+
 
 	while (cyc--) {
 		off += _emit_WFP(dry_run, &buf[off], cond, pxs->desc->peri);
 		off += _emit_LD(dry_run, &buf[off], ALWAYS);
 		off += _emit_STP(dry_run, &buf[off], cond, pxs->desc->peri);
-		off += _emit_FLUSHP(dry_run, &buf[off], pxs->desc->peri);
+
+		if (!(pl330->quirks & PL330_QUIRK_BROKEN_NO_FLUSHP))
+			off += _emit_FLUSHP(dry_run, &buf[off],
+					    pxs->desc->peri);
 	}
 
 	return off;
 }
 
-static int _bursts(unsigned dry_run, u8 buf[],
+static int _bursts(struct pl330_dmac *pl330, unsigned dry_run, u8 buf[],
 		const struct _xfer_spec *pxs, int cyc)
 {
 	int off = 0;
 
 	switch (pxs->desc->rqtype) {
 	case DMA_MEM_TO_DEV:
-		off += _ldst_memtodev(dry_run, &buf[off], pxs, cyc);
+		off += _ldst_memtodev(pl330, dry_run, &buf[off], pxs, cyc);
 		break;
 	case DMA_DEV_TO_MEM:
-		off += _ldst_devtomem(dry_run, &buf[off], pxs, cyc);
+		off += _ldst_devtomem(pl330, dry_run, &buf[off], pxs, cyc);
 		break;
 	case DMA_MEM_TO_MEM:
 		off += _ldst_memtomem(dry_run, &buf[off], pxs, cyc);
@@ -1197,7 +1225,7 @@ static int _bursts(unsigned dry_run, u8 buf[],
 }
 
 /* Returns bytes consumed and updates bursts */
-static inline int _loop(unsigned dry_run, u8 buf[],
+static inline int _loop(struct pl330_dmac *pl330, unsigned dry_run, u8 buf[],
 		unsigned long *bursts, const struct _xfer_spec *pxs)
 {
 	int cyc, cycmax, szlp, szlpend, szbrst, off;
@@ -1220,7 +1248,7 @@ static inline int _loop(unsigned dry_run, u8 buf[],
 	}
 
 	szlp = _emit_LP(1, buf, 0, 0);
-	szbrst = _bursts(1, buf, pxs, 1);
+	szbrst = _bursts(pl330, 1, buf, pxs, 1);
 
 	lpend.cond = ALWAYS;
 	lpend.forever = false;
@@ -1252,7 +1280,7 @@ static inline int _loop(unsigned dry_run, u8 buf[],
 	off += _emit_LP(dry_run, &buf[off], 1, lcnt1);
 	ljmp1 = off;
 
-	off += _bursts(dry_run, &buf[off], pxs, cyc);
+	off += _bursts(pl330, dry_run, &buf[off], pxs, cyc);
 
 	lpend.cond = ALWAYS;
 	lpend.forever = false;
@@ -1275,8 +1303,9 @@ static inline int _loop(unsigned dry_run, u8 buf[],
 	return off;
 }
 
-static inline int _setup_loops(unsigned dry_run, u8 buf[],
-		const struct _xfer_spec *pxs)
+static inline int _setup_loops(struct pl330_dmac *pl330,
+			       unsigned dry_run, u8 buf[],
+			       const struct _xfer_spec *pxs)
 {
 	struct pl330_xfer *x = &pxs->desc->px;
 	u32 ccr = pxs->ccr;
@@ -1285,15 +1314,16 @@ static inline int _setup_loops(unsigned dry_run, u8 buf[],
 
 	while (bursts) {
 		c = bursts;
-		off += _loop(dry_run, &buf[off], &c, pxs);
+		off += _loop(pl330, dry_run, &buf[off], &c, pxs);
 		bursts -= c;
 	}
 
 	return off;
 }
 
-static inline int _setup_xfer(unsigned dry_run, u8 buf[],
-		const struct _xfer_spec *pxs)
+static inline int _setup_xfer(struct pl330_dmac *pl330,
+			      unsigned dry_run, u8 buf[],
+			      const struct _xfer_spec *pxs)
 {
 	struct pl330_xfer *x = &pxs->desc->px;
 	int off = 0;
@@ -1304,7 +1334,7 @@ static inline int _setup_xfer(unsigned dry_run, u8 buf[],
 	off += _emit_MOV(dry_run, &buf[off], DAR, x->dst_addr);
 
 	/* Setup Loop(s) */
-	off += _setup_loops(dry_run, &buf[off], pxs);
+	off += _setup_loops(pl330, dry_run, &buf[off], pxs);
 
 	return off;
 }
@@ -1313,8 +1343,9 @@ static inline int _setup_xfer(unsigned dry_run, u8 buf[],
  * A req is a sequence of one or more xfer units.
  * Returns the number of bytes taken to setup the MC for the req.
  */
-static int _setup_req(unsigned dry_run, struct pl330_thread *thrd,
-		unsigned index, struct _xfer_spec *pxs)
+static int _setup_req(struct pl330_dmac *pl330, unsigned dry_run,
+		      struct pl330_thread *thrd, unsigned index,
+		      struct _xfer_spec *pxs)
 {
 	struct _pl330_req *req = &thrd->req[index];
 	struct pl330_xfer *x;
@@ -1331,7 +1362,7 @@ static int _setup_req(unsigned dry_run, struct pl330_thread *thrd,
 	if (x->bytes % (BRST_SIZE(pxs->ccr) * BRST_LEN(pxs->ccr)))
 		return -EINVAL;
 
-	off += _setup_xfer(dry_run, &buf[off], pxs);
+	off += _setup_xfer(pl330, dry_run, &buf[off], pxs);
 
 	/* DMASEV peripheral/event */
 	off += _emit_SEV(dry_run, &buf[off], thrd->ev);
@@ -1425,7 +1456,7 @@ static int pl330_submit_req(struct pl330_thread *thrd,
 	xs.desc = desc;
 
 	/* First dry run to check if req is acceptable */
-	ret = _setup_req(1, thrd, idx, &xs);
+	ret = _setup_req(pl330, 1, thrd, idx, &xs);
 	if (ret < 0)
 		goto xfer_exit;
 
@@ -1439,7 +1470,7 @@ static int pl330_submit_req(struct pl330_thread *thrd,
 	/* Hook the request */
 	thrd->lstenq = idx;
 	thrd->req[idx].desc = desc;
-	_setup_req(0, thrd, idx, &xs);
+	_setup_req(pl330, 0, thrd, idx, &xs);
 
 	ret = 0;
 
@@ -2784,6 +2815,7 @@ pl330_probe(struct amba_device *adev, const struct amba_id *id)
 	struct resource *res;
 	int i, ret, irq;
 	int num_chan;
+	struct device_node *np = adev->dev.of_node;
 
 	pdat = dev_get_platdata(&adev->dev);
 
@@ -2803,6 +2835,11 @@ pl330_probe(struct amba_device *adev, const struct amba_id *id)
 
 	pl330->mcbufsz = pdat ? pdat->mcbuf_sz : 0;
 
+	/* get quirk */
+	for (i = 0; i < ARRAY_SIZE(of_quirks); i++)
+		if (of_property_read_bool(np, of_quirks[i].quirk))
+			pl330->quirks |= of_quirks[i].id;
+
 	res = &adev->res;
 	pl330->base = devm_ioremap_resource(&adev->dev, res);
 	if (IS_ERR(pl330->base))
-- 
2.3.7




From shawn.lin at rock-chips.com  Thu Aug 27 07:24:41 2015
From: shawn.lin at rock-chips.com (Shawn Lin)
Date: Thu, 27 Aug 2015 22:24:41 +0800
Subject: [PATCH v1 3/5] ARM: dts: Add arm,
 pl330-broken-no-flushp quirk for rk3288 platform
In-Reply-To: <1440685419-22037-1-git-send-email-shawn.lin@rock-chips.com>
References: <1440685419-22037-1-git-send-email-shawn.lin@rock-chips.com>
Message-ID: <1440685481-22163-1-git-send-email-shawn.lin@rock-chips.com>

From: Addy Ke <addy.ke at rock-chips.com>

Pl330 integrated in rk3288 platform doesn't support
DMAFLUSHP function. So we add broken-no-flushp quirk
for it.

Signed-off-by: Addy Ke <addy.ke at rock-chips.com>
Signed-off-by: Shawn Lin <shawn.lin at rock-chips.com>
cc: Heiko Stuebner <heiko at sntech.de>
cc: Doug Anderson <dianders at chromium.org>
cc: Olof Johansson <olofj at google.com>

---

Changes in v1:
- rename broken-no-flushp to "arm,pl330-broken-no-flushp" suggested
  by Krzysztof.
- remove Sunny's tag

 arch/arm/boot/dts/rk3288.dtsi | 3 +++
 1 file changed, 3 insertions(+)

diff --git a/arch/arm/boot/dts/rk3288.dtsi b/arch/arm/boot/dts/rk3288.dtsi
index 22316d0..106adf7 100644
--- a/arch/arm/boot/dts/rk3288.dtsi
+++ b/arch/arm/boot/dts/rk3288.dtsi
@@ -144,6 +144,7 @@
 			#dma-cells = <1>;
 			clocks = <&cru ACLK_DMAC2>;
 			clock-names = "apb_pclk";
+			arm,pl330-broken-no-flushp;
 		};
 
 		dmac_bus_ns: dma-controller at ff600000 {
@@ -155,6 +156,7 @@
 			clocks = <&cru ACLK_DMAC1>;
 			clock-names = "apb_pclk";
 			status = "disabled";
+			arm,pl330-broken-no-flushp;
 		};
 
 		dmac_bus_s: dma-controller at ffb20000 {
@@ -165,6 +167,7 @@
 			#dma-cells = <1>;
 			clocks = <&cru ACLK_DMAC1>;
 			clock-names = "apb_pclk";
+			arm,pl330-broken-no-flushp;
 		};
 	};
 
-- 
2.3.7




From shawn.lin at rock-chips.com  Thu Aug 27 07:24:51 2015
From: shawn.lin at rock-chips.com (Shawn Lin)
Date: Thu, 27 Aug 2015 22:24:51 +0800
Subject: [PATCH v1 4/5] ARM: dts: Add arm,
 pl330-broken-no-flushp quirk for rk3xxx platform
In-Reply-To: <1440685419-22037-1-git-send-email-shawn.lin@rock-chips.com>
References: <1440685419-22037-1-git-send-email-shawn.lin@rock-chips.com>
Message-ID: <1440685491-22206-1-git-send-email-shawn.lin@rock-chips.com>

Pl330 integrated in rk3xxx platform doesn't support
DMAFLUSHP function. So we add broken-no-flushp quirk
for it.

Signed-off-by: Shawn Lin <shawn.lin at rock-chips.com>
cc: Heiko Stuebner <heiko at sntech.de>
cc: Doug Anderson <dianders at chromium.org>
cc: Olof Johansson <olofj at google.com>

---

Changes in v1:
- rename broken-no-flushp to "arm,pl330-broken-no-flushp" suggested
  by Krzysztof.

 arch/arm/boot/dts/rk3xxx.dtsi | 3 +++
 1 file changed, 3 insertions(+)

diff --git a/arch/arm/boot/dts/rk3xxx.dtsi b/arch/arm/boot/dts/rk3xxx.dtsi
index a2ae9f3..a8ca4b3 100644
--- a/arch/arm/boot/dts/rk3xxx.dtsi
+++ b/arch/arm/boot/dts/rk3xxx.dtsi
@@ -79,6 +79,7 @@
 			#dma-cells = <1>;
 			clocks = <&cru ACLK_DMA1>;
 			clock-names = "apb_pclk";
+			arm,pl330-broken-no-flushp;
 		};
 
 		dmac1_ns: dma-controller at 2001c000 {
@@ -89,6 +90,7 @@
 			#dma-cells = <1>;
 			clocks = <&cru ACLK_DMA1>;
 			clock-names = "apb_pclk";
+			arm,pl330-broken-no-flushp;
 			status = "disabled";
 		};
 
@@ -100,6 +102,7 @@
 			#dma-cells = <1>;
 			clocks = <&cru ACLK_DMA2>;
 			clock-names = "apb_pclk";
+			arm,pl330-broken-no-flushp;
 		};
 	};
 
-- 
2.3.7




From shawn.lin at rock-chips.com  Thu Aug 27 07:25:05 2015
From: shawn.lin at rock-chips.com (Shawn Lin)
Date: Thu, 27 Aug 2015 22:25:05 +0800
Subject: [PATCH v1 5/5] Documentation: arm-pl330: add description of arm,
 pl330-broken-no-flushp
In-Reply-To: <1440685419-22037-1-git-send-email-shawn.lin@rock-chips.com>
References: <1440685419-22037-1-git-send-email-shawn.lin@rock-chips.com>
Message-ID: <1440685505-22247-1-git-send-email-shawn.lin@rock-chips.com>

Signed-off-by: Shawn Lin <shawn.lin at rock-chips.com>

---

Changes in v1:
- rename broken-no-flushp to "arm,pl330-broken-no-flushp" suggested
  by Krzysztof.

 Documentation/devicetree/bindings/dma/arm-pl330.txt | 1 +
 1 file changed, 1 insertion(+)

diff --git a/Documentation/devicetree/bindings/dma/arm-pl330.txt b/Documentation/devicetree/bindings/dma/arm-pl330.txt
index 2675658..db7e226 100644
--- a/Documentation/devicetree/bindings/dma/arm-pl330.txt
+++ b/Documentation/devicetree/bindings/dma/arm-pl330.txt
@@ -15,6 +15,7 @@ Optional properties:
     cells in the dmas property of client device.
   - dma-channels: contains the total number of DMA channels supported by the DMAC
   - dma-requests: contains the total number of DMA requests supported by the DMAC
+  - arm,pl330-broken-no-flushp: quirk for avoiding to execute DMAFLUSHP
 
 Example:
 
-- 
2.3.7




From moritz.fischer at ettus.com  Thu Aug 27 07:30:40 2015
From: moritz.fischer at ettus.com (Moritz Fischer)
Date: Thu, 27 Aug 2015 10:30:40 -0400
Subject: [PATCH v9] dmaengine: Add Xilinx AXI Direct Memory Access Engine
 driver support
In-Reply-To: <1440432666-10310-1-git-send-email-appanad@xilinx.com>
References: <1440432666-10310-1-git-send-email-appanad@xilinx.com>
Message-ID: <CAAtXAHccn5UjCg9Qr1Li1c9LfsBXrgF=gpMqJ6stGOaWL0u_-g@mail.gmail.com>

Hi Kedar,

one thing that I realized is that you're not grabbing any clocks, does
this assume that you boot your system with fclk_enable to make this
work on Zynq e.g?
I realize the Xilinx VDMA driver in mainline doesn't have clock
handling built in neither, but wouldn't having that in new drivers at
least be desirable?

On Mon, Aug 24, 2015 at 12:11 PM, Kedareswara rao Appana
<appana.durga.rao at xilinx.com> wrote:
> This is the driver for the AXI Direct Memory Access (AXI DMA)
> core, which is a soft Xilinx IP core that provides high-
> bandwidth direct memory access between memory and AXI4-Stream
> type target peripherals.
>
> Signed-off-by: Kedareswara rao Appana <appanad at xilinx.com>
> ---
> The deivce tree doc got applied in the slave-dmaengine.git.
>
> Changes in v9:
> - Used the readl_poll_timeout instead of do while loops
>   in the driver as suggested by Moritz Fischer.
> - Intialize the residue variable to get rid of compilation warining.
> Changes in v8:
> - Updated the SG handling as suggested by Nicolae Rosia.
> - Removed the unnecessary xilinx_dma_channel_set_config API the properties
>   in this API is not being used by the driver.
> Changes in v7:
> - Updated license in the driver as suggested by Paul.
> - Corrected return value in is_idle funtion.
> Changes in v6:
> - Fixed Odd indention in the Kconfig.
> - used GFP_NOWAIT instead of GFP_KERNEL during the desc allocation
> - Calculated residue in the tx_status instead of complete_descriptor.
> - Update copy right to 2015.
> - Modified spin_lock handling moved the spin_lock to the appropriate functions
> (instead of xilinx_dma_start_transfer doing it xilinx_dma_issue_pending api).
> - device_control and declare slave caps updated as per newer APi's.
> Changes in v5:
> - Modified the xilinx_dma.h header file location to the
>   include/linux/dma/xilinx_dma.h
> Changes in v4:
> - Add direction field to DMA descriptor structure and removed from
>   channel structure to avoid duplication.
> - Check for DMA idle condition before changing the configuration.
> - Residue is being calculated in complete_descriptor() and is reported
>   to slave driver.
> Changes in v3:
> - Rebased on 3.16-rc7
> Changes in v2:
> - Simplified the logic to set SOP and APP words in prep_slave_sg().
> - Corrected function description comments to match the return type.
> - Fixed some minor comments as suggested by Andy.
> ---
>  drivers/dma/Kconfig             |   13 +
>  drivers/dma/xilinx/Makefile     |    1 +
>  drivers/dma/xilinx/xilinx_dma.c | 1178 +++++++++++++++++++++++++++++++++++++++
>  3 files changed, 1192 insertions(+)
>  create mode 100644 drivers/dma/xilinx/xilinx_dma.c
>
> diff --git a/drivers/dma/Kconfig b/drivers/dma/Kconfig
> index 88d474b..5e95f07 100644
> --- a/drivers/dma/Kconfig
> +++ b/drivers/dma/Kconfig
> @@ -507,4 +507,17 @@ config QCOM_BAM_DMA
>           Enable support for the QCOM BAM DMA controller.  This controller
>           provides DMA capabilities for a variety of on-chip devices.
>
> +config XILINX_DMA
> +        tristate "Xilinx AXI DMA Engine"
> +        depends on (ARCH_ZYNQ || MICROBLAZE)
> +        select DMA_ENGINE
> +        help
> +          Enable support for Xilinx AXI DMA Soft IP.
> +
> +          This engine provides high-bandwidth direct memory access
> +          between memory and AXI4-Stream type target peripherals.
> +          It has two stream interfaces/channels, Memory Mapped to
> +          Stream (MM2S) and Stream to Memory Mapped (S2MM) for the
> +          data transfers.
> +
>  endif
> diff --git a/drivers/dma/xilinx/Makefile b/drivers/dma/xilinx/Makefile
> index 3c4e9f2..6224a49 100644
> --- a/drivers/dma/xilinx/Makefile
> +++ b/drivers/dma/xilinx/Makefile
> @@ -1 +1,2 @@
>  obj-$(CONFIG_XILINX_VDMA) += xilinx_vdma.o
> +obj-$(CONFIG_XILINX_DMA) += xilinx_dma.o
> diff --git a/drivers/dma/xilinx/xilinx_dma.c b/drivers/dma/xilinx/xilinx_dma.c
> new file mode 100644
> index 0000000..d19009e
> --- /dev/null
> +++ b/drivers/dma/xilinx/xilinx_dma.c
> @@ -0,0 +1,1178 @@
> +/*
> + * DMA driver for Xilinx DMA Engine
> + *
> + * Copyright (C) 2010 - 2015 Xilinx, Inc. All rights reserved.
> + *
> + * Based on the Freescale DMA driver.
> + *
> + * Description:
> + *  The AXI DMA, is a soft IP, which provides high-bandwidth Direct Memory
> + *  Access between memory and AXI4-Stream-type target peripherals. It can be
> + *  configured to have one channel or two channels and if configured as two
> + *  channels, one is to transmit data from memory to a device and another is
> + *  to receive from a device.
> + *
> + * This 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.
> + */
> +
> +#include <linux/bitops.h>
> +#include <linux/dma/xilinx_dma.h>
> +#include <linux/init.h>
> +#include <linux/interrupt.h>
> +#include <linux/io.h>
> +#include <linux/iopoll.h>
> +#include <linux/module.h>
> +#include <linux/of_address.h>
> +#include <linux/of_dma.h>
> +#include <linux/of_irq.h>
> +#include <linux/of_platform.h>
> +#include <linux/slab.h>
> +
> +#include "../dmaengine.h"
> +
> +/* Register Offsets */
> +#define XILINX_DMA_REG_CONTROL         0x00
> +#define XILINX_DMA_REG_STATUS          0x04
> +#define XILINX_DMA_REG_CURDESC         0x08
> +#define XILINX_DMA_REG_TAILDESC                0x10
> +#define XILINX_DMA_REG_SRCADDR         0x18
> +#define XILINX_DMA_REG_DSTADDR         0x20
> +#define XILINX_DMA_REG_BTT             0x28
> +
> +/* Channel/Descriptor Offsets */
> +#define XILINX_DMA_MM2S_CTRL_OFFSET    0x00
> +#define XILINX_DMA_S2MM_CTRL_OFFSET    0x30
> +
> +/* General register bits definitions */
> +#define XILINX_DMA_CR_RUNSTOP_MASK     BIT(0)
> +#define XILINX_DMA_CR_RESET_MASK       BIT(2)
> +
> +#define XILINX_DMA_CR_DELAY_SHIFT      24
> +#define XILINX_DMA_CR_COALESCE_SHIFT   16
> +
> +#define XILINX_DMA_CR_DELAY_MAX                GENMASK(7, 0)
> +#define XILINX_DMA_CR_COALESCE_MAX     GENMASK(7, 0)
> +
> +#define XILINX_DMA_SR_HALTED_MASK      BIT(0)
> +#define XILINX_DMA_SR_IDLE_MASK                BIT(1)
> +
> +#define XILINX_DMA_XR_IRQ_IOC_MASK     BIT(12)
> +#define XILINX_DMA_XR_IRQ_DELAY_MASK   BIT(13)
> +#define XILINX_DMA_XR_IRQ_ERROR_MASK   BIT(14)
> +#define XILINX_DMA_XR_IRQ_ALL_MASK     GENMASK(14, 12)
> +
> +/* BD definitions */
> +#define XILINX_DMA_BD_STS_ALL_MASK     GENMASK(31, 28)
> +#define XILINX_DMA_BD_SOP              BIT(27)
> +#define XILINX_DMA_BD_EOP              BIT(26)
> +
> +/* Hw specific definitions */
> +#define XILINX_DMA_MAX_CHANS_PER_DEVICE        0x2
> +#define XILINX_DMA_MAX_TRANS_LEN       GENMASK(22, 0)
> +
> +/* Delay loop counter to prevent hardware failure */
> +#define XILINX_DMA_LOOP_COUNT          1000000
> +
> +/* Maximum number of Descriptors */
> +#define XILINX_DMA_NUM_DESCS           255
> +#define XILINX_DMA_COALESCE_MAX                255
> +#define XILINX_DMA_NUM_APP_WORDS       5
> +
> +#define xilinx_dma_poll_timeout(chan, reg, val, cond, delay_us, timeout_us) \
> +       readl_poll_timeout(chan->xdev->regs + chan->ctrl_offset + reg, val, \
> +                          cond, delay_us, timeout_us)
> +
> +/**
> + * struct xilinx_dma_desc_hw - Hardware Descriptor
> + * @next_desc: Next Descriptor Pointer @0x00
> + * @pad1: Reserved @0x04
> + * @buf_addr: Buffer address @0x08
> + * @pad2: Reserved @0x0C
> + * @pad3: Reserved @0x10
> + * @pad4: Reserved @0x14
> + * @control: Control field @0x18
> + * @status: Status field @0x1C
> + * @app: APP Fields @0x20 - 0x30
> + */
> +struct xilinx_dma_desc_hw {
> +       u32 next_desc;
> +       u32 pad1;
> +       u32 buf_addr;
> +       u32 pad2;
> +       u32 pad3;
> +       u32 pad4;
> +       u32 control;
> +       u32 status;
> +       u32 app[XILINX_DMA_NUM_APP_WORDS];
> +} __aligned(64);
> +
> +/**
> + * struct xilinx_dma_tx_segment - Descriptor segment
> + * @hw: Hardware descriptor
> + * @node: Node in the descriptor segments list
> + * @phys: Physical address of segment
> + */
> +struct xilinx_dma_tx_segment {
> +       struct xilinx_dma_desc_hw hw;
> +       struct list_head node;
> +       dma_addr_t phys;
> +} __aligned(64);
> +
> +/**
> + * struct xilinx_dma_tx_descriptor - Per Transaction structure
> + * @async_tx: Async transaction descriptor
> + * @segments: TX segments list
> + * @node: Node in the channel descriptors list
> + * @direction: Transfer direction
> + */
> +struct xilinx_dma_tx_descriptor {
> +       struct dma_async_tx_descriptor async_tx;
> +       struct list_head segments;
> +       struct list_head node;
> +       enum dma_transfer_direction direction;
> +};
> +
> +/**
> + * struct xilinx_dma_chan - Driver specific DMA channel structure
> + * @xdev: Driver specific device structure
> + * @ctrl_offset: Control registers offset
> + * @ctrl_reg: Control register value
> + * @lock: Descriptor operation lock
> + * @pending_list: Descriptors waiting
> + * @active_list: Descriptors ready to submit
> + * @done_list: Complete descriptors
> + * @free_seg_list: Free descriptors
> + * @common: DMA common channel
> + * @seg_v: Statically allocated segments base
> + * @seg_p: Physical allocated segments base
> + * @dev: The dma device
> + * @irq: Channel IRQ
> + * @id: Channel ID
> + * @has_sg: Support scatter transfers
> + * @idle: Check for channel idle
> + * @err: Channel has errors
> + * @tasklet: Cleanup work after irq
> + * @residue: Residue
> + * @desc_pendingcount: Descriptor pending count
> + */
> +struct xilinx_dma_chan {
> +       struct xilinx_dma_device *xdev;
> +       u32 ctrl_offset;
> +       u32 ctrl_reg;
> +       spinlock_t lock;
> +       struct list_head pending_list;
> +       struct list_head done_list;
> +       struct list_head active_list;
> +       struct list_head free_seg_list;
> +       struct dma_chan common;
> +       struct xilinx_dma_tx_segment *seg_v;
> +       dma_addr_t seg_p;
> +       struct device *dev;
> +       int irq;
> +       int id;
> +       bool has_sg;
> +       bool idle;
> +       int err;
> +       struct tasklet_struct tasklet;
> +       u32 residue;
> +       u32 desc_pendingcount;
> +};
> +
> +/**
> + * struct xilinx_dma_device - DMA device structure
> + * @regs: I/O mapped base address
> + * @dev: Device Structure
> + * @common: DMA device structure
> + * @chan: Driver specific DMA channel
> + * @has_sg: Specifies whether Scatter-Gather is present or not
> + */
> +struct xilinx_dma_device {
> +       void __iomem *regs;
> +       struct device *dev;
> +       struct dma_device common;
> +       struct xilinx_dma_chan *chan[XILINX_DMA_MAX_CHANS_PER_DEVICE];
> +       bool has_sg;
> +};
> +
> +/* Macros */
> +#define to_xilinx_chan(chan) \
> +       container_of(chan, struct xilinx_dma_chan, common)
> +#define to_dma_tx_descriptor(tx) \
> +       container_of(tx, struct xilinx_dma_tx_descriptor, async_tx)
> +
> +/* IO accessors */
> +static inline void dma_write(struct xilinx_dma_chan *chan, u32 reg, u32 value)
> +{
> +       iowrite32(value, chan->xdev->regs + reg);
> +}
> +
> +static inline u32 dma_read(struct xilinx_dma_chan *chan, u32 reg)
> +{
> +       return ioread32(chan->xdev->regs + reg);
> +}
> +
> +static inline u32 dma_ctrl_read(struct xilinx_dma_chan *chan, u32 reg)
> +{
> +       return dma_read(chan, chan->ctrl_offset + reg);
> +}
> +
> +static inline void dma_ctrl_write(struct xilinx_dma_chan *chan, u32 reg,
> +                                 u32 value)
> +{
> +       dma_write(chan, chan->ctrl_offset + reg, value);
> +}
> +
> +/* -----------------------------------------------------------------------------
> + * Descriptors and segments alloc and free
> + */
> +
> +/**
> + * xilinx_dma_alloc_tx_segment - Allocate transaction segment
> + * @chan: Driver specific dma channel
> + *
> + * Return: The allocated segment on success and NULL on failure.
> + */
> +static struct xilinx_dma_tx_segment *
> +xilinx_dma_alloc_tx_segment(struct xilinx_dma_chan *chan)
> +{
> +       struct xilinx_dma_tx_segment *segment = NULL;
> +       unsigned long flags;
> +
> +       spin_lock_irqsave(&chan->lock, flags);
> +       if (!list_empty(&chan->free_seg_list)) {
> +               segment = list_first_entry(&chan->free_seg_list,
> +                                          struct xilinx_dma_tx_segment,
> +                                          node);
> +               list_del(&segment->node);
> +       }
> +       spin_unlock_irqrestore(&chan->lock, flags);
> +
> +       return segment;
> +}
> +
> +/**
> + * xilinx_dma_clean_hw_desc - Clean hardware descriptor
> + * @hw: HW descriptor to clean
> + */
> +static void xilinx_dma_clean_hw_desc(struct xilinx_dma_desc_hw *hw)
> +{
> +       u32 next_desc = hw->next_desc;
> +
> +       memset(hw, 0, sizeof(struct xilinx_dma_desc_hw));
> +
> +       hw->next_desc = next_desc;
> +}
> +
> +/**
> + * xilinx_dma_free_tx_segment - Free transaction segment
> + * @chan: Driver specific dma channel
> + * @segment: dma transaction segment
> + */
> +static void xilinx_dma_free_tx_segment(struct xilinx_dma_chan *chan,
> +                                      struct xilinx_dma_tx_segment *segment)
> +{
> +       xilinx_dma_clean_hw_desc(&segment->hw);
> +
> +       list_add_tail(&segment->node, &chan->free_seg_list);
> +}
> +
> +/**
> + * xilinx_dma_tx_descriptor - Allocate transaction descriptor
> + * @chan: Driver specific dma channel
> + *
> + * Return: The allocated descriptor on success and NULL on failure.
> + */
> +static struct xilinx_dma_tx_descriptor *
> +xilinx_dma_alloc_tx_descriptor(struct xilinx_dma_chan *chan)
> +{
> +       struct xilinx_dma_tx_descriptor *desc;
> +
> +       desc = kzalloc(sizeof(*desc), GFP_NOWAIT);
> +       if (!desc)
> +               return NULL;
> +
> +       INIT_LIST_HEAD(&desc->segments);
> +
> +       return desc;
> +}
> +
> +/**
> + * xilinx_dma_free_tx_descriptor - Free transaction descriptor
> + * @chan: Driver specific dma channel
> + * @desc: dma transaction descriptor
> + */
> +static void
> +xilinx_dma_free_tx_descriptor(struct xilinx_dma_chan *chan,
> +                             struct xilinx_dma_tx_descriptor *desc)
> +{
> +       struct xilinx_dma_tx_segment *segment, *next;
> +
> +       if (!desc)
> +               return;
> +
> +       list_for_each_entry_safe(segment, next, &desc->segments, node) {
> +               list_del(&segment->node);
> +               xilinx_dma_free_tx_segment(chan, segment);
> +       }
> +
> +       kfree(desc);
> +}
> +
> +/**
> + * xilinx_dma_alloc_chan_resources - Allocate channel resources
> + * @dchan: DMA channel
> + *
> + * Return: '0' on success and failure value on error
> + */
> +static int xilinx_dma_alloc_chan_resources(struct dma_chan *dchan)
> +{
> +       struct xilinx_dma_chan *chan = to_xilinx_chan(dchan);
> +       int i;
> +
> +       /* Allocate the buffer descriptors. */
> +       chan->seg_v = dma_zalloc_coherent(chan->dev,
> +                                         sizeof(*chan->seg_v) *
> +                                         XILINX_DMA_NUM_DESCS,
> +                                         &chan->seg_p, GFP_KERNEL);
> +       if (!chan->seg_v) {
> +               dev_err(chan->dev,
> +                       "unable to allocate channel %d descriptors\n",
> +                       chan->id);
> +               return -ENOMEM;
> +       }
> +
> +       for (i = 0; i < XILINX_DMA_NUM_DESCS; i++) {
> +               chan->seg_v[i].hw.next_desc =
> +                               chan->seg_p + sizeof(*chan->seg_v) *
> +                               ((i + 1) % XILINX_DMA_NUM_DESCS);
> +               chan->seg_v[i].phys =
> +                               chan->seg_p + sizeof(*chan->seg_v) * i;
> +               list_add_tail(&chan->seg_v[i].node, &chan->free_seg_list);
> +       }
> +
> +       dma_cookie_init(dchan);
> +
> +       /* Enable interrupts */
> +       chan->ctrl_reg |= XILINX_DMA_XR_IRQ_ALL_MASK;
> +       dma_ctrl_write(chan, XILINX_DMA_REG_CONTROL, chan->ctrl_reg);
> +
> +       return 0;
> +}
> +
> +/**
> + * xilinx_dma_free_desc_list - Free descriptors list
> + * @chan: Driver specific dma channel
> + * @list: List to parse and delete the descriptor
> + */
> +static void xilinx_dma_free_desc_list(struct xilinx_dma_chan *chan,
> +                                     struct list_head *list)
> +{
> +       struct xilinx_dma_tx_descriptor *desc, *next;
> +
> +       list_for_each_entry_safe(desc, next, list, node) {
> +               list_del(&desc->node);
> +               xilinx_dma_free_tx_descriptor(chan, desc);
> +       }
> +}
> +
> +/**
> + * xilinx_dma_free_descriptors - Free channel descriptors
> + * @chan: Driver specific dma channel
> + */
> +static void xilinx_dma_free_descriptors(struct xilinx_dma_chan *chan)
> +{
> +       unsigned long flags;
> +
> +       spin_lock_irqsave(&chan->lock, flags);
> +
> +       xilinx_dma_free_desc_list(chan, &chan->pending_list);
> +       xilinx_dma_free_desc_list(chan, &chan->done_list);
> +       xilinx_dma_free_desc_list(chan, &chan->active_list);
> +
> +       spin_unlock_irqrestore(&chan->lock, flags);
> +}
> +
> +/**
> + * xilinx_dma_free_chan_resources - Free channel resources
> + * @dchan: DMA channel
> + */
> +static void xilinx_dma_free_chan_resources(struct dma_chan *dchan)
> +{
> +       struct xilinx_dma_chan *chan = to_xilinx_chan(dchan);
> +
> +       xilinx_dma_free_descriptors(chan);
> +
> +       dma_free_coherent(chan->dev,
> +                         sizeof(*chan->seg_v) * XILINX_DMA_NUM_DESCS,
> +                         chan->seg_v, chan->seg_p);
> +}
> +
> +/**
> + * xilinx_dma_chan_desc_cleanup - Clean channel descriptors
> + * @chan: Driver specific dma channel
> + */
> +static void xilinx_dma_chan_desc_cleanup(struct xilinx_dma_chan *chan)
> +{
> +       struct xilinx_dma_tx_descriptor *desc;
> +       unsigned long flags;
> +
> +       spin_lock_irqsave(&chan->lock, flags);
> +
> +       while (!list_empty(&chan->done_list)) {
> +               dma_async_tx_callback callback;
> +               void *callback_param;
> +
> +               desc = list_first_entry(&chan->done_list,
> +                       struct xilinx_dma_tx_descriptor, node);
> +
> +               /* Remove from the list of running transactions */
> +               list_del(&desc->node);
> +
> +               /* Run the link descriptor callback function */
> +               callback = desc->async_tx.callback;
> +               callback_param = desc->async_tx.callback_param;
> +               if (callback) {
> +                       spin_unlock_irqrestore(&chan->lock, flags);
> +                       callback(callback_param);
> +                       spin_lock_irqsave(&chan->lock, flags);
> +               }
> +
> +               /* Run any dependencies, then free the descriptor */
> +               dma_run_dependencies(&desc->async_tx);
> +               xilinx_dma_free_tx_descriptor(chan, desc);
> +       }
> +
> +       spin_unlock_irqrestore(&chan->lock, flags);
> +}
> +
> +/**
> + * xilinx_dma_tx_status - Get dma transaction status
> + * @dchan: DMA channel
> + * @cookie: Transaction identifier
> + * @txstate: Transaction state
> + *
> + * Return: DMA transaction status
> + */
> +static enum dma_status xilinx_dma_tx_status(struct dma_chan *dchan,
> +                                           dma_cookie_t cookie,
> +                                           struct dma_tx_state *txstate)
> +{
> +       struct xilinx_dma_chan *chan = to_xilinx_chan(dchan);
> +       struct xilinx_dma_tx_descriptor *desc;
> +       struct xilinx_dma_tx_segment *segment;
> +       struct xilinx_dma_desc_hw *hw;
> +       enum dma_status ret;
> +       unsigned long flags;
> +       u32 residue = 0;
> +
> +       ret = dma_cookie_status(dchan, cookie, txstate);
> +       if (ret == DMA_COMPLETE || !txstate)
> +               return ret;
> +
> +       desc = list_last_entry(&chan->active_list,
> +                              struct xilinx_dma_tx_descriptor, node);
> +
> +       spin_lock_irqsave(&chan->lock, flags);
> +       if (chan->has_sg) {
> +               while (!list_empty(&desc->segments)) {
> +                       segment = list_first_entry(&desc->segments,
> +                                       struct xilinx_dma_tx_segment, node);
> +                       hw = &segment->hw;
> +                       residue += (hw->control - hw->status) &
> +                                  XILINX_DMA_MAX_TRANS_LEN;
> +               }
> +       }
> +
> +       chan->residue = residue;
> +       dma_set_residue(txstate, chan->residue);
> +       spin_unlock_irqrestore(&chan->lock, flags);
> +
> +       return ret;
> +}
> +
> +/**
> + * xilinx_dma_halt - Halt DMA channel
> + * @chan: Driver specific DMA channel
> + */
> +static void xilinx_dma_halt(struct xilinx_dma_chan *chan)
> +{
> +       int err = 0;
> +       u32 val;
> +
> +       chan->ctrl_reg &= ~XILINX_DMA_CR_RUNSTOP_MASK;
> +       dma_ctrl_write(chan, XILINX_DMA_REG_CONTROL, chan->ctrl_reg);
> +
> +       /* Wait for the hardware to halt */
> +       err = xilinx_dma_poll_timeout(chan, XILINX_DMA_REG_STATUS, val,
> +                                     (val & XILINX_DMA_SR_HALTED_MASK), 10,
> +                                     XILINX_DMA_LOOP_COUNT);
> +
> +       if (err) {
> +               dev_err(chan->dev, "Cannot stop channel %p: %x\n",
> +                       chan, dma_ctrl_read(chan, XILINX_DMA_REG_STATUS));
> +               chan->err = true;
> +       }
> +}
> +
> +/**
> + * xilinx_dma_start - Start DMA channel
> + * @chan: Driver specific DMA channel
> + */
> +static void xilinx_dma_start(struct xilinx_dma_chan *chan)
> +{
> +       int err = 0;
> +       u32 val;
> +
> +       chan->ctrl_reg |= XILINX_DMA_CR_RUNSTOP_MASK;
> +       dma_ctrl_write(chan, XILINX_DMA_REG_CONTROL, chan->ctrl_reg);
> +
> +       /* Wait for the hardware to start */
> +       err = xilinx_dma_poll_timeout(chan, XILINX_DMA_REG_STATUS, val,
> +                                     !(val & XILINX_DMA_SR_HALTED_MASK), 10,
> +                                     XILINX_DMA_LOOP_COUNT);
> +
> +       if (err) {
> +               dev_err(chan->dev, "Cannot start channel %p: %x\n",
> +                        chan, dma_ctrl_read(chan, XILINX_DMA_REG_STATUS));
> +               chan->err = true;
> +       }
> +}
> +
> +/**
> + * xilinx_dma_start_transfer - Starts DMA transfer
> + * @chan: Driver specific channel struct pointer
> + */
> +static void xilinx_dma_start_transfer(struct xilinx_dma_chan *chan)
> +{
> +       struct xilinx_dma_tx_descriptor *head_desc, *tail_desc;
> +       struct xilinx_dma_tx_segment *tail_segment;
> +
> +       if (chan->err)
> +               return;
> +
> +       if (list_empty(&chan->pending_list))
> +               return;
> +
> +       if (!chan->idle)
> +               return;
> +
> +       head_desc = list_first_entry(&chan->pending_list,
> +                                    struct xilinx_dma_tx_descriptor, node);
> +       tail_desc = list_last_entry(&chan->pending_list,
> +                                   struct xilinx_dma_tx_descriptor, node);
> +       tail_segment = list_last_entry(&tail_desc->segments,
> +                                      struct xilinx_dma_tx_segment, node);
> +
> +       if (chan->desc_pendingcount <= XILINX_DMA_COALESCE_MAX) {
> +               chan->ctrl_reg &= ~XILINX_DMA_CR_COALESCE_MAX;
> +               chan->ctrl_reg |= chan->desc_pendingcount <<
> +                                 XILINX_DMA_CR_COALESCE_SHIFT;
> +               dma_ctrl_write(chan, XILINX_DMA_REG_CONTROL, chan->ctrl_reg);
> +       }
> +
> +       if (chan->has_sg)
> +               dma_ctrl_write(chan, XILINX_DMA_REG_CURDESC,
> +                              head_desc->async_tx.phys);
> +
> +       xilinx_dma_start(chan);
> +
> +       if (chan->err)
> +               return;
> +
> +       /* Start the transfer */
> +       if (chan->has_sg) {
> +               dma_ctrl_write(chan, XILINX_DMA_REG_TAILDESC,
> +                              tail_segment->phys);
> +       } else {
> +               struct xilinx_dma_tx_segment *segment;
> +               struct xilinx_dma_desc_hw *hw;
> +
> +               segment = list_first_entry(&head_desc->segments,
> +                                          struct xilinx_dma_tx_segment, node);
> +               hw = &segment->hw;
> +
> +               if (head_desc->direction == DMA_MEM_TO_DEV)
> +                       dma_ctrl_write(chan, XILINX_DMA_REG_SRCADDR,
> +                                      hw->buf_addr);
> +               else
> +                       dma_ctrl_write(chan, XILINX_DMA_REG_DSTADDR,
> +                                      hw->buf_addr);
> +
> +               /* Start the transfer */
> +               dma_ctrl_write(chan, XILINX_DMA_REG_BTT,
> +                              hw->control & XILINX_DMA_MAX_TRANS_LEN);
> +       }
> +
> +       list_splice_tail_init(&chan->pending_list, &chan->active_list);
> +       chan->desc_pendingcount = 0;
> +       chan->idle = false;
> +}
> +
> +/**
> + * xilinx_dma_issue_pending - Issue pending transactions
> + * @dchan: DMA channel
> + */
> +static void xilinx_dma_issue_pending(struct dma_chan *dchan)
> +{
> +       struct xilinx_dma_chan *chan = to_xilinx_chan(dchan);
> +       unsigned long flags;
> +
> +       spin_lock_irqsave(&chan->lock, flags);
> +       xilinx_dma_start_transfer(chan);
> +       spin_unlock_irqrestore(&chan->lock, flags);
> +}
> +
> +/**
> + * xilinx_dma_complete_descriptor - Mark the active descriptor as complete
> + * @chan : xilinx DMA channel
> + */
> +static void xilinx_dma_complete_descriptor(struct xilinx_dma_chan *chan)
> +{
> +       struct xilinx_dma_tx_descriptor *desc, *next;
> +
> +       if (list_empty(&chan->active_list))
> +               return;
> +
> +       list_for_each_entry_safe(desc, next, &chan->active_list, node) {
> +               list_del(&desc->node);
> +               dma_cookie_complete(&desc->async_tx);
> +               list_add_tail(&desc->node, &chan->done_list);
> +       }
> +}
> +
> +/**
> + * xilinx_dma_chan_reset - Reset DMA channel
> + * @chan: Driver specific DMA channel
> + *
> + * Return: '0' on success and failure value on error
> + */
> +static int xilinx_dma_chan_reset(struct xilinx_dma_chan *chan)
> +{
> +       int err = 0;
> +       u32 val;
> +
> +       chan->ctrl_reg = dma_ctrl_read(chan, XILINX_DMA_REG_CONTROL);
> +       dma_ctrl_write(chan, XILINX_DMA_REG_CONTROL, chan->ctrl_reg |
> +                      XILINX_DMA_CR_RESET_MASK);
> +
> +       /* Wait for the hardware to finish reset */
> +       err = xilinx_dma_poll_timeout(chan, XILINX_DMA_REG_CONTROL, val,
> +                                     !(val & XILINX_DMA_CR_RESET_MASK), 10,
> +                                     XILINX_DMA_LOOP_COUNT);
> +
> +       if (err) {
> +               dev_err(chan->dev, "reset timeout, cr %x, sr %x\n",
> +                       dma_ctrl_read(chan, XILINX_DMA_REG_CONTROL),
> +                       dma_ctrl_read(chan, XILINX_DMA_REG_STATUS));
> +               return -EBUSY;
> +       }
> +
> +       chan->err = false;
> +
> +       return err;
> +}
> +
> +/**
> + * xilinx_dma_irq_handler - DMA Interrupt handler
> + * @irq: IRQ number
> + * @data: Pointer to the Xilinx DMA channel structure
> + *
> + * Return: IRQ_HANDLED/IRQ_NONE
> + */
> +static irqreturn_t xilinx_dma_irq_handler(int irq, void *data)
> +{
> +       struct xilinx_dma_chan *chan = data;
> +       u32 status;
> +
> +       /* Read the status and ack the interrupts. */
> +       status = dma_ctrl_read(chan, XILINX_DMA_REG_STATUS);
> +       if (!(status & XILINX_DMA_XR_IRQ_ALL_MASK))
> +               return IRQ_NONE;
> +
> +       dma_ctrl_write(chan, XILINX_DMA_REG_STATUS,
> +                      status & XILINX_DMA_XR_IRQ_ALL_MASK);
> +
> +       if (status & XILINX_DMA_XR_IRQ_ERROR_MASK) {
> +               dev_err(chan->dev,
> +                       "Channel %p has errors %x, cdr %x tdr %x\n",
> +                       chan, dma_ctrl_read(chan, XILINX_DMA_REG_STATUS),
> +                       dma_ctrl_read(chan, XILINX_DMA_REG_CURDESC),
> +                       dma_ctrl_read(chan, XILINX_DMA_REG_TAILDESC));
> +               chan->err = true;
> +       }
> +
> +       /*
> +        * Device takes too long to do the transfer when user requires
> +        * responsiveness
> +        */
> +       if (status & XILINX_DMA_XR_IRQ_DELAY_MASK)
> +               dev_dbg(chan->dev, "Inter-packet latency too long\n");
> +
> +       if (status & XILINX_DMA_XR_IRQ_IOC_MASK) {
> +               spin_lock(&chan->lock);
> +               xilinx_dma_complete_descriptor(chan);
> +               chan->idle = true;
> +               xilinx_dma_start_transfer(chan);
> +               spin_unlock(&chan->lock);
> +       }
> +
> +       tasklet_schedule(&chan->tasklet);
> +       return IRQ_HANDLED;
> +}
> +
> +/**
> + * xilinx_dma_do_tasklet - Schedule completion tasklet
> + * @data: Pointer to the Xilinx dma channel structure
> + */
> +static void xilinx_dma_do_tasklet(unsigned long data)
> +{
> +       struct xilinx_dma_chan *chan = (struct xilinx_dma_chan *)data;
> +
> +       xilinx_dma_chan_desc_cleanup(chan);
> +}
> +
> +/**
> + * append_desc_queue - Queuing descriptor
> + * @chan: Driver specific dma channel
> + * @desc: dma transaction descriptor
> + */
> +static void append_desc_queue(struct xilinx_dma_chan *chan,
> +                             struct xilinx_dma_tx_descriptor *desc)
> +{
> +       struct xilinx_dma_tx_segment *tail_segment;
> +       struct xilinx_dma_tx_descriptor *tail_desc;
> +
> +       if (list_empty(&chan->pending_list))
> +               goto append;
> +
> +       /*
> +        * Add the hardware descriptor to the chain of hardware descriptors
> +        * that already exists in memory.
> +        */
> +       tail_desc = list_last_entry(&chan->pending_list,
> +                                   struct xilinx_dma_tx_descriptor, node);
> +       tail_segment = list_last_entry(&tail_desc->segments,
> +                                      struct xilinx_dma_tx_segment, node);
> +       tail_segment->hw.next_desc = (u32)desc->async_tx.phys;
> +
> +       /*
> +        * Add the software descriptor and all children to the list
> +        * of pending transactions
> +        */
> +append:
> +       list_add_tail(&desc->node, &chan->pending_list);
> +       chan->desc_pendingcount++;
> +
> +       if (unlikely(chan->desc_pendingcount > XILINX_DMA_COALESCE_MAX)) {
> +               dev_dbg(chan->dev, "desc pendingcount is too high\n");
> +               chan->desc_pendingcount = XILINX_DMA_COALESCE_MAX;
> +               BUG();
> +       }
> +}
> +
> +/**
> + * xilinx_dma_tx_submit - Submit DMA transaction
> + * @tx: Async transaction descriptor
> + *
> + * Return: cookie value on success and failure value on error
> + */
> +static dma_cookie_t xilinx_dma_tx_submit(struct dma_async_tx_descriptor *tx)
> +{
> +       struct xilinx_dma_tx_descriptor *desc = to_dma_tx_descriptor(tx);
> +       struct xilinx_dma_chan *chan = to_xilinx_chan(tx->chan);
> +       dma_cookie_t cookie;
> +       unsigned long flags;
> +       int err;
> +
> +       if (chan->err) {
> +               /*
> +                * If reset fails, need to hard reset the system.
> +                * Channel is no longer functional
> +                */
> +               err = xilinx_dma_chan_reset(chan);
> +               if (err < 0)
> +                       return err;
> +       }
> +
> +       spin_lock_irqsave(&chan->lock, flags);
> +
> +       cookie = dma_cookie_assign(tx);
> +
> +       /* Put this transaction onto the tail of the pending queue */
> +       append_desc_queue(chan, desc);
> +
> +       spin_unlock_irqrestore(&chan->lock, flags);
> +
> +       return cookie;
> +}
> +
> +/**
> + * xilinx_dma_prep_slave_sg - prepare descriptors for a DMA_SLAVE transaction
> + * @dchan: DMA channel
> + * @sgl: scatterlist to transfer to/from
> + * @sg_len: number of entries in @scatterlist
> + * @direction: DMA direction
> + * @flags: transfer ack flags
> + * @context: APP words of the descriptor
> + *
> + * Return: Async transaction descriptor on success and NULL on failure
> + */
> +static struct dma_async_tx_descriptor *xilinx_dma_prep_slave_sg(
> +       struct dma_chan *dchan, struct scatterlist *sgl, unsigned int sg_len,
> +       enum dma_transfer_direction direction, unsigned long flags,
> +       void *context)
> +{
> +       struct xilinx_dma_chan *chan = to_xilinx_chan(dchan);
> +       struct xilinx_dma_tx_descriptor *desc;
> +       struct xilinx_dma_tx_segment *segment;
> +       u32 *app_w = (u32 *)context;
> +       struct scatterlist *sg;
> +       size_t copy, sg_used;
> +       int i;
> +
> +       if (!is_slave_direction(direction))
> +               return NULL;
> +
> +       /* Allocate a transaction descriptor. */
> +       desc = xilinx_dma_alloc_tx_descriptor(chan);
> +       if (!desc)
> +               return NULL;
> +
> +       desc->direction = direction;
> +       dma_async_tx_descriptor_init(&desc->async_tx, &chan->common);
> +       desc->async_tx.tx_submit = xilinx_dma_tx_submit;
> +
> +       /* Build transactions using information in the scatter gather list */
> +       for_each_sg(sgl, sg, sg_len, i) {
> +               sg_used = 0;
> +
> +               /* Loop until the entire scatterlist entry is used */
> +               while (sg_used < sg_dma_len(sg)) {
> +                       struct xilinx_dma_desc_hw *hw;
> +
> +                       /* Get a free segment */
> +                       segment = xilinx_dma_alloc_tx_segment(chan);
> +                       if (!segment)
> +                               goto error;
> +
> +                       /*
> +                        * Calculate the maximum number of bytes to transfer,
> +                        * making sure it is less than the hw limit
> +                        */
> +                       copy = min_t(size_t, sg_dma_len(sg) - sg_used,
> +                                    XILINX_DMA_MAX_TRANS_LEN);
> +                       hw = &segment->hw;
> +
> +                       /* Fill in the descriptor */
> +                       hw->buf_addr = sg_dma_address(sg) + sg_used;
> +
> +                       hw->control = copy;
> +
> +                       if (direction == DMA_MEM_TO_DEV) {
> +                               if (app_w)
> +                                       memcpy(hw->app, app_w, sizeof(u32) *
> +                                              XILINX_DMA_NUM_APP_WORDS);
> +                       }
> +
> +                       sg_used += copy;
> +
> +                       /*
> +                        * Insert the segment into the descriptor segments
> +                        * list.
> +                        */
> +                       list_add_tail(&segment->node, &desc->segments);
> +               }
> +       }
> +
> +       segment = list_first_entry(&desc->segments,
> +                                  struct xilinx_dma_tx_segment, node);
> +       desc->async_tx.phys = segment->phys;
> +
> +       /* For the last DMA_MEM_TO_DEV transfer, set EOP */
> +       if (direction == DMA_MEM_TO_DEV) {
> +               segment->hw.control |= XILINX_DMA_BD_SOP;
> +               segment = list_last_entry(&desc->segments,
> +                                         struct xilinx_dma_tx_segment,
> +                                         node);
> +               segment->hw.control |= XILINX_DMA_BD_EOP;
> +       }
> +
> +       return &desc->async_tx;
> +
> +error:
> +       xilinx_dma_free_tx_descriptor(chan, desc);
> +       return NULL;
> +}
> +
> +/**
> + * xilinx_dma_terminate_all - Halt the channel and free descriptors
> + * @dchan: DMA Channel pointer
> + *
> + * Return: '0' always
> + */
> +static int xilinx_dma_terminate_all(struct dma_chan *dchan)
> +{
> +       struct xilinx_dma_chan *chan = to_xilinx_chan(dchan);
> +
> +       /* Halt the DMA engine */
> +       xilinx_dma_halt(chan);
> +
> +       /* Remove and free all of the descriptors in the lists */
> +       xilinx_dma_free_descriptors(chan);
> +
> +       return 0;
> +}
> +
> +/**
> + * xilinx_dma_chan_remove - Per Channel remove function
> + * @chan: Driver specific DMA channel
> + */
> +static void xilinx_dma_chan_remove(struct xilinx_dma_chan *chan)
> +{
> +       /* Disable interrupts */
> +       chan->ctrl_reg &= ~XILINX_DMA_XR_IRQ_ALL_MASK;
> +       dma_ctrl_write(chan, XILINX_DMA_REG_CONTROL, chan->ctrl_reg);
> +
> +       if (chan->irq > 0)
> +               free_irq(chan->irq, chan);
> +
> +       tasklet_kill(&chan->tasklet);
> +
> +       list_del(&chan->common.device_node);
> +}
> +
> +/**
> + * xilinx_dma_chan_probe - Per Channel Probing
> + * It get channel features from the device tree entry and
> + * initialize special channel handling routines
> + *
> + * @xdev: Driver specific device structure
> + * @node: Device node
> + *
> + * Return: '0' on success and failure value on error
> + */
> +static int xilinx_dma_chan_probe(struct xilinx_dma_device *xdev,
> +                                struct device_node *node)
> +{
> +       struct xilinx_dma_chan *chan;
> +       int err;
> +       bool has_dre;
> +       u32 value, width = 0;
> +
> +       /* alloc channel */
> +       chan = devm_kzalloc(xdev->dev, sizeof(*chan), GFP_KERNEL);
> +       if (!chan)
> +               return -ENOMEM;
> +
> +       chan->dev = xdev->dev;
> +       chan->xdev = xdev;
> +       chan->has_sg = xdev->has_sg;
> +       chan->desc_pendingcount = 0x0;
> +
> +       has_dre = of_property_read_bool(node, "xlnx,include-dre");
> +
> +       err = of_property_read_u32(node, "xlnx,datawidth", &value);
> +       if (err) {
> +               dev_err(xdev->dev, "unable to read datawidth property");
> +               return err;
> +       }
> +
> +       width = value >> 3; /* Convert bits to bytes */
> +
> +       /* If data width is greater than 8 bytes, DRE is not in hw */
> +       if (width > 8)
> +               has_dre = false;
> +
> +       if (!has_dre)
> +               xdev->common.copy_align = fls(width - 1);
> +
> +       if (of_device_is_compatible(node, "xlnx,axi-dma-mm2s-channel")) {
> +               chan->id = 0;
> +               chan->ctrl_offset = XILINX_DMA_MM2S_CTRL_OFFSET;
> +       } else if (of_device_is_compatible(node, "xlnx,axi-dma-s2mm-channel")) {
> +               chan->id = 1;
> +               chan->ctrl_offset = XILINX_DMA_S2MM_CTRL_OFFSET;
> +       } else {
> +               dev_err(xdev->dev, "Invalid channel compatible node\n");
> +               return -EINVAL;
> +       }
> +
> +       xdev->chan[chan->id] = chan;
> +
> +       /* Initialize the channel */
> +       err = xilinx_dma_chan_reset(chan);
> +       if (err) {
> +               dev_err(xdev->dev, "Reset channel failed\n");
> +               return err;
> +       }
> +
> +       spin_lock_init(&chan->lock);
> +       INIT_LIST_HEAD(&chan->pending_list);
> +       INIT_LIST_HEAD(&chan->done_list);
> +       INIT_LIST_HEAD(&chan->active_list);
> +       INIT_LIST_HEAD(&chan->free_seg_list);
> +
> +       chan->common.device = &xdev->common;
> +
> +       /* find the IRQ line, if it exists in the device tree */
> +       chan->irq = irq_of_parse_and_map(node, 0);
> +       err = request_irq(chan->irq, xilinx_dma_irq_handler,
> +                         IRQF_SHARED,
> +                         "xilinx-dma-controller", chan);
> +       if (err) {
> +               dev_err(xdev->dev, "unable to request IRQ %d\n", chan->irq);
> +               return err;
> +       }
> +
> +       /* Initialize the tasklet */
> +       tasklet_init(&chan->tasklet, xilinx_dma_do_tasklet,
> +                    (unsigned long)chan);
> +
> +       /* Add the channel to DMA device channel list */
> +       list_add_tail(&chan->common.device_node, &xdev->common.channels);
> +
> +       chan->idle = true;
> +
> +       return 0;
> +}
> +
> +/**
> + * of_dma_xilinx_xlate - Translation function
> + * @dma_spec: Pointer to DMA specifier as found in the device tree
> + * @ofdma: Pointer to DMA controller data
> + *
> + * Return: DMA channel pointer on success and NULL on error
> + */
> +static struct dma_chan *of_dma_xilinx_xlate(struct of_phandle_args *dma_spec,
> +                                           struct of_dma *ofdma)
> +{
> +       struct xilinx_dma_device *xdev = ofdma->of_dma_data;
> +       int chan_id = dma_spec->args[0];
> +
> +       if (chan_id >= XILINX_DMA_MAX_CHANS_PER_DEVICE)
> +               return NULL;
> +
> +       return dma_get_slave_channel(&xdev->chan[chan_id]->common);
> +}
> +
> +/**
> + * xilinx_dma_probe - Driver probe function
> + * @pdev: Pointer to the platform_device structure
> + *
> + * Return: '0' on success and failure value on error
> + */
> +static int xilinx_dma_probe(struct platform_device *pdev)
> +{
> +       struct xilinx_dma_device *xdev;
> +       struct device_node *child, *node;
> +       struct resource *res;
> +       int i, ret;
> +
> +       xdev = devm_kzalloc(&pdev->dev, sizeof(*xdev), GFP_KERNEL);
> +       if (!xdev)
> +               return -ENOMEM;
> +
> +       xdev->dev = &(pdev->dev);
> +       INIT_LIST_HEAD(&xdev->common.channels);
> +
> +       node = pdev->dev.of_node;
> +
> +       /* Map the registers */
> +       res = platform_get_resource(pdev, IORESOURCE_MEM, 0);
> +       xdev->regs = devm_ioremap_resource(&pdev->dev, res);
> +       if (IS_ERR(xdev->regs))
> +               return PTR_ERR(xdev->regs);
> +
> +       /* Check if SG is enabled */
> +       xdev->has_sg = of_property_read_bool(node, "xlnx,include-sg");
> +
> +       /* Axi DMA only do slave transfers */
> +       dma_cap_set(DMA_SLAVE, xdev->common.cap_mask);
> +       dma_cap_set(DMA_PRIVATE, xdev->common.cap_mask);
> +       xdev->common.device_prep_slave_sg = xilinx_dma_prep_slave_sg;
> +       xdev->common.device_terminate_all = xilinx_dma_terminate_all;
> +       xdev->common.device_issue_pending = xilinx_dma_issue_pending;
> +       xdev->common.device_alloc_chan_resources =
> +               xilinx_dma_alloc_chan_resources;
> +       xdev->common.device_free_chan_resources =
> +               xilinx_dma_free_chan_resources;
> +       xdev->common.device_tx_status = xilinx_dma_tx_status;
> +       xdev->common.directions = BIT(DMA_DEV_TO_MEM) | BIT(DMA_MEM_TO_DEV);
> +       xdev->common.residue_granularity = DMA_RESIDUE_GRANULARITY_SEGMENT;
> +       xdev->common.dev = &pdev->dev;
> +
> +       platform_set_drvdata(pdev, xdev);
> +
> +       for_each_child_of_node(node, child) {
> +               ret = xilinx_dma_chan_probe(xdev, child);
> +               if (ret) {
> +                       dev_err(&pdev->dev, "Probing channels failed\n");
> +                       goto free_chan_resources;
> +               }
> +       }
> +
> +       dma_async_device_register(&xdev->common);
> +
> +       ret = of_dma_controller_register(node, of_dma_xilinx_xlate, xdev);
> +       if (ret) {
> +               dev_err(&pdev->dev, "Unable to register DMA to DT\n");
> +               dma_async_device_unregister(&xdev->common);
> +               goto free_chan_resources;
> +       }
> +
> +       dev_info(&pdev->dev, "Xilinx AXI DMA Engine driver Probed!!\n");
> +
> +       return 0;
> +
> +free_chan_resources:
> +       for (i = 0; i < XILINX_DMA_MAX_CHANS_PER_DEVICE; i++)
> +               if (xdev->chan[i])
> +                       xilinx_dma_chan_remove(xdev->chan[i]);
> +
> +       return ret;
> +}
> +
> +/**
> + * xilinx_dma_remove - Driver remove function
> + * @pdev: Pointer to the platform_device structure
> + *
> + * Return: Always '0'
> + */
> +static int xilinx_dma_remove(struct platform_device *pdev)
> +{
> +       struct xilinx_dma_device *xdev = platform_get_drvdata(pdev);
> +       int i;
> +
> +       of_dma_controller_free(pdev->dev.of_node);
> +       dma_async_device_unregister(&xdev->common);
> +
> +       for (i = 0; i < XILINX_DMA_MAX_CHANS_PER_DEVICE; i++)
> +               if (xdev->chan[i])
> +                       xilinx_dma_chan_remove(xdev->chan[i]);
> +
> +       return 0;
> +}
> +
> +static const struct of_device_id xilinx_dma_of_match[] = {
> +       { .compatible = "xlnx,axi-dma-1.00.a",},
> +       {}
> +};
> +MODULE_DEVICE_TABLE(of, xilinx_dma_of_match);
> +
> +static struct platform_driver xilinx_dma_driver = {
> +       .driver = {
> +               .name = "xilinx-dma",
> +               .of_match_table = xilinx_dma_of_match,
> +       },
> +       .probe = xilinx_dma_probe,
> +       .remove = xilinx_dma_remove,
> +};
> +
> +module_platform_driver(xilinx_dma_driver);
> +
> +MODULE_AUTHOR("Xilinx, Inc.");
> +MODULE_DESCRIPTION("Xilinx DMA driver");
> +MODULE_LICENSE("GPL");
> --
> 2.1.2
>
I'm currently traveling so it might be a while till I get around to
test stuff on hardware,

Cheers,
Moritz


From linux at arm.linux.org.uk  Thu Aug 27 07:45:49 2015
From: linux at arm.linux.org.uk (Russell King - ARM Linux)
Date: Thu, 27 Aug 2015 15:45:49 +0100
Subject: [PATCH] arm64: KVM: Do not inject a 64bit fault for a 32bit guest
In-Reply-To: <1440684348-5292-1-git-send-email-marc.zyngier@arm.com>
References: <1440684348-5292-1-git-send-email-marc.zyngier@arm.com>
Message-ID: <20150827144549.GF21084@n2100.arm.linux.org.uk>

On Thu, Aug 27, 2015 at 03:05:47PM +0100, Marc Zyngier wrote:
> When injecting a fault into a 32bit guest, it seems rather idiotic
> to also inject a 64bit fault that is only going to corrupt the
> guest state, and lead to a situation where we restore an illegal
> context.
> 
> Just fix the stupid bug that has been there from day 1.
> 
> Cc: stable at vger.kernel.org
> Reported-by: Russell King <linux at arm.linux.org.uk>

s/linux/rmk+kernel/ please

Tested-by: Russell King <rmk+kernel at arm.linux.org.uk>

> Signed-off-by: Marc Zyngier <marc.zyngier at arm.com>
> ---
> Will: Paolo being on holiday, do you mind merging this one
> via your tree?

I don't think the commit message does this bug justice.  The implication
is it's just a guest issue.  It isn't, the bug appears to take out the
host kernel in a truely spectacular way.

http://www.arm.linux.org.uk/developer/build/result.php?type=boot&idx=4871

Tested here, the fix stops the host kernel exploding.  The crashed kvm
instance can be stopped and a proper kernel can then be booted in a new
guest instance.

-- 
FTTC broadband for 0.8mile line: currently at 10.5Mbps down 400kbps up
according to speedtest.net.


From broonie at kernel.org  Thu Aug 27 07:54:51 2015
From: broonie at kernel.org (Mark Brown)
Date: Thu, 27 Aug 2015 15:54:51 +0100
Subject: [PATCH] arm: tegra: update default configuration
In-Reply-To: <1440670255-19437-1-git-send-email-marcel.ziswiler@toradex.com>
References: <1440670255-19437-1-git-send-email-marcel.ziswiler@toradex.com>
Message-ID: <20150827145451.GB5313@sirena.org.uk>

On Thu, Aug 27, 2015 at 12:10:55PM +0200, Marcel Ziswiler wrote:

>   * WM9712 audio/touch controller as found on Colibri T20

> +CONFIG_BATTERY_WM97XX=y

Does the system really have the wm9712 wired up as a battery monitor?
-------------- next part --------------
A non-text attachment was scrubbed...
Name: signature.asc
Type: application/pgp-signature
Size: 473 bytes
Desc: Digital signature
URL: <http://lists.infradead.org/pipermail/linux-arm-kernel/attachments/20150827/8445fd4d/attachment.sig>

From tglx at linutronix.de  Thu Aug 27 07:56:18 2015
From: tglx at linutronix.de (Thomas Gleixner)
Date: Thu, 27 Aug 2015 16:56:18 +0200 (CEST)
Subject: [PATCH v3] irqchip: kill off set_irq_flags usage
In-Reply-To: <CAL_JsqL9EsFpE3j_ud6bvoJ38di+2428mBD2VgQPX8fba=BpdQ@mail.gmail.com>
References: <1438030523-15853-1-git-send-email-robh@kernel.org>
 <1438030523-15853-6-git-send-email-robh@kernel.org>
 <CAL_JsqL9EsFpE3j_ud6bvoJ38di+2428mBD2VgQPX8fba=BpdQ@mail.gmail.com>
Message-ID: <alpine.DEB.2.11.1508271655220.15006@nanos>

On Wed, 26 Aug 2015, Rob Herring wrote:
> Everything except this patch, sh, gpu, and final removal of
> set_irq_flags in arm/arm64 are in -next. There don't appear to be any
> new users either.
> 
> Can you apply this patch and these 2 now so they have some time in -next:
> 
> http://lkml.kernel.org/r/1438030523-15853-11-git-send-email-robh at kernel.org
> http://lkml.kernel.org/r/1438030523-15853-5-git-send-email-robh at kernel.org
> 
> And these 2 toward the end of the merge window once there is no more
> set_irq_flags:
> 
> http://lkml.kernel.org/r/1436711211-18223-13-git-send-email-robh at kernel.org
> http://lkml.kernel.org/r/1436711211-18223-14-git-send-email-robh at kernel.org

Could you please resend these 5 patches to me. Seems I lost some of them.

Thanks,

	tglx


From mathieu.poirier at linaro.org  Thu Aug 27 08:05:33 2015
From: mathieu.poirier at linaro.org (Mathieu Poirier)
Date: Thu, 27 Aug 2015 09:05:33 -0600
Subject: [PATCH] Coresight: ETMv4: Prevent TRCRSCTLR0&1 from being accessed
In-Reply-To: <1440648369-4614-1-git-send-email-zhang.chunyan@linaro.org>
References: <1440648369-4614-1-git-send-email-zhang.chunyan@linaro.org>
Message-ID: <CANLsYkz8JwxoaCUg2EYrfcgFoL05OfhTmM5wT5CaHZFUHN87Lw@mail.gmail.com>

On 26 August 2015 at 22:06, Chunyan Zhang <zhang.chunyan at linaro.org> wrote:
> 1. TRCRSCTLRn - Resource Selection Control Registers n=0~1 are reserved,
>    we shouldn't access them.
> 2. The max number of 'n' here is defined in TRCIDR4.NUMRSPAIR whoes value
>    indicates the number of resource selection *pairs*, and 0 indicates
>    one resource selection pair, 1 indicates two pairs, and so on ...
>
> So, the total number of resource selection control registers which we can
> access is (TRCIDR4.NUMRSPAIR * 2)
>
> Signed-off-by: Chunyan Zhang <zhang.chunyan at linaro.org>
> ---
>  drivers/hwtracing/coresight/coresight-etm4x.c | 15 ++++++++++-----
>  1 file changed, 10 insertions(+), 5 deletions(-)
>
> diff --git a/drivers/hwtracing/coresight/coresight-etm4x.c b/drivers/hwtracing/coresight/coresight-etm4x.c
> index 1312e99..9425249 100644
> --- a/drivers/hwtracing/coresight/coresight-etm4x.c
> +++ b/drivers/hwtracing/coresight/coresight-etm4x.c
> @@ -136,7 +136,9 @@ static void etm4_enable_hw(void *info)
>                 writel_relaxed(drvdata->cntr_val[i],
>                                drvdata->base + TRCCNTVRn(i));
>         }
> -       for (i = 0; i < drvdata->nr_resource; i++)
> +
> +       /* Resource selector pair 0 is always implemented and reserved */
> +       for (i = 2; i < (drvdata->nr_resource + 1) * 2; i++)

Instead of repeating "->nr_resource + 1) * 2" every time, please add
"->nr_resource += 1" in etm4_init_arch_data() along with a comment
that explains why.

>                 writel_relaxed(drvdata->res_ctrl[i],
>                                drvdata->base + TRCRSCTLRn(i));
>
> @@ -489,8 +491,9 @@ static ssize_t reset_store(struct device *dev,
>                 drvdata->cntr_val[i] = 0x0;
>         }
>
> -       drvdata->res_idx = 0x0;
> -       for (i = 0; i < drvdata->nr_resource; i++)
> +       /* Resource selector pair 0 is always implemented and reserved */
> +       drvdata->res_idx = 0x2;
> +       for (i = 2; i < (drvdata->nr_resource + 1) * 2; i++)
>                 drvdata->res_ctrl[i] = 0x0;
>
>         for (i = 0; i < drvdata->nr_ss_cmp; i++) {
> @@ -1729,7 +1732,7 @@ static ssize_t res_idx_store(struct device *dev,
>         if (kstrtoul(buf, 16, &val))
>                 return -EINVAL;
>         /* Resource selector pair 0 is always implemented and reserved */
> -       if ((val == 0) || (val >= drvdata->nr_resource))
> +       if (val < 2 || val > (drvdata->nr_resource + 1) * 2)
>                 return -EINVAL;
>
>         /*
> @@ -2498,7 +2501,9 @@ static void etm4_init_default_data(struct etmv4_drvdata *drvdata)
>                 drvdata->cntr_val[i] = 0x0;
>         }
>
> -       for (i = 2; i < drvdata->nr_resource * 2; i++)
> +       /* Resource selector pair 0 is always implemented and reserved */
> +       drvdata->res_idx = 0x2;
> +       for (i = 2; i < (drvdata->nr_resource + 1) * 2; i++)
>                 drvdata->res_ctrl[i] = 0x0;
>
>         for (i = 0; i < drvdata->nr_ss_cmp; i++) {
> --
> 1.9.1
>


From marc.zyngier at arm.com  Thu Aug 27 08:10:01 2015
From: marc.zyngier at arm.com (Marc Zyngier)
Date: Thu, 27 Aug 2015 16:10:01 +0100
Subject: [PATCH v2] arm64: KVM: Do not inject a 64bit fault for a 32bit guest
Message-ID: <1440688201-6324-1-git-send-email-marc.zyngier@arm.com>

When injecting a fault into a misbehaving 32bit guest, it seems
rather idiotic to also inject a 64bit fault that is only going
to corrupt the guest state. This leads to a situation where we
perform an illegal exception return at EL2 causing the host
to crash instead of killing the guest.

Just fix the stupid bug that has been there from day 1.

Cc: stable at vger.kernel.org
Reported-by: Russell King <rmk+kernel at arm.linux.org.uk>
Tested-by: Russell King <rmk+kernel at arm.linux.org.uk>
Signed-off-by: Marc Zyngier <marc.zyngier at arm.com>
---
 arch/arm64/kvm/inject_fault.c | 12 ++++++------
 1 file changed, 6 insertions(+), 6 deletions(-)

diff --git a/arch/arm64/kvm/inject_fault.c b/arch/arm64/kvm/inject_fault.c
index f02530e..85c5715 100644
--- a/arch/arm64/kvm/inject_fault.c
+++ b/arch/arm64/kvm/inject_fault.c
@@ -168,8 +168,8 @@ void kvm_inject_dabt(struct kvm_vcpu *vcpu, unsigned long addr)
 {
 	if (!(vcpu->arch.hcr_el2 & HCR_RW))
 		inject_abt32(vcpu, false, addr);
-
-	inject_abt64(vcpu, false, addr);
+	else
+		inject_abt64(vcpu, false, addr);
 }
 
 /**
@@ -184,8 +184,8 @@ void kvm_inject_pabt(struct kvm_vcpu *vcpu, unsigned long addr)
 {
 	if (!(vcpu->arch.hcr_el2 & HCR_RW))
 		inject_abt32(vcpu, true, addr);
-
-	inject_abt64(vcpu, true, addr);
+	else
+		inject_abt64(vcpu, true, addr);
 }
 
 /**
@@ -198,6 +198,6 @@ void kvm_inject_undefined(struct kvm_vcpu *vcpu)
 {
 	if (!(vcpu->arch.hcr_el2 & HCR_RW))
 		inject_undef32(vcpu);
-
-	inject_undef64(vcpu);
+	else
+		inject_undef64(vcpu);
 }
-- 
2.1.4



From mathieu.poirier at linaro.org  Thu Aug 27 08:12:17 2015
From: mathieu.poirier at linaro.org (Mathieu Poirier)
Date: Thu, 27 Aug 2015 09:12:17 -0600
Subject: [PATCH 2/5] coresight-etm4x: Change the name of the ctxid_val to
 ctxid_pid
In-Reply-To: <55DDFE01.50201@codeaurora.org>
References: <1436258518-9339-1-git-send-email-zhang.chunyan@linaro.org>
 <1436258518-9339-3-git-send-email-zhang.chunyan@linaro.org>
 <55DDFE01.50201@codeaurora.org>
Message-ID: <CANLsYkyA_C=PUDEUSbcA_Sa6Abqnxk1TP9ye6F9i0bWW_OxqiA@mail.gmail.com>

On 26 August 2015 at 11:57, Christopher Covington <cov at codeaurora.org> wrote:
> On 07/07/2015 04:41 AM, Chunyan Zhang wrote:
>> 'ctxid_val' array was used to store the value of ETM context ID comparator
>> which actually stores the process ID to be traced, so using 'ctxid_pid' as
>> its name instead make it easier to understand.
>
> Previous discussion with some ARM folks has led me to believe there isn't a
> guarantee that the Context ID Register will always have a PID. Why not allow
> filtering on thread group ID, session ID, cgroup related identifiers, etc.?

Coresight tracers only support contextID tracing.  The HW
automatically does the match between the contextID comparator register
in the tracer with the contextID register of the core.  Tracing is
enabled if both values match (and the tracer is configured to do so).

>
>> This patch also changes the ABI, it is normally not allowed, but
>> fortunately it is a testing ABI and very new for now. Nevertheless,
>> if you don't think it should be changed, we could always add an alias
>> for userspace.
>>
>> Signed-off-by: Chunyan Zhang <zhang.chunyan at linaro.org>
>> Reviewed-by: Mark Brown <broonie at kernel.org>
>> ---
>>  .../ABI/testing/sysfs-bus-coresight-devices-etm4x    |  2 +-
>>  drivers/hwtracing/coresight/coresight-etm4x.c        | 20 ++++++++++----------
>>  drivers/hwtracing/coresight/coresight-etm4x.h        |  4 ++--
>>  3 files changed, 13 insertions(+), 13 deletions(-)
>>
>> diff --git a/Documentation/ABI/testing/sysfs-bus-coresight-devices-etm4x b/Documentation/ABI/testing/sysfs-bus-coresight-devices-etm4x
>> index 2fe2e3d..2355ed8 100644
>> --- a/Documentation/ABI/testing/sysfs-bus-coresight-devices-etm4x
>> +++ b/Documentation/ABI/testing/sysfs-bus-coresight-devices-etm4x
>> @@ -249,7 +249,7 @@ KernelVersion:    4.01
>>  Contact:     Mathieu Poirier <mathieu.poirier at linaro.org>
>>  Description: (RW) Select which context ID comparator to work with.
>>
>> -What:                /sys/bus/coresight/devices/<memory_map>.etm/ctxid_val
>> +What:                /sys/bus/coresight/devices/<memory_map>.etm/ctxid_pid
>>  Date:                April 2015
>>  KernelVersion:       4.01
>>  Contact:     Mathieu Poirier <mathieu.poirier at linaro.org>
>> diff --git a/drivers/hwtracing/coresight/coresight-etm4x.c b/drivers/hwtracing/coresight/coresight-etm4x.c
>> index 1312e99..9afbda5 100644
>> --- a/drivers/hwtracing/coresight/coresight-etm4x.c
>> +++ b/drivers/hwtracing/coresight/coresight-etm4x.c
>> @@ -155,7 +155,7 @@ static void etm4_enable_hw(void *info)
>>                              drvdata->base + TRCACATRn(i));
>>       }
>>       for (i = 0; i < drvdata->numcidc; i++)
>> -             writeq_relaxed(drvdata->ctxid_val[i],
>> +             writeq_relaxed(drvdata->ctxid_pid[i],
>>                              drvdata->base + TRCCIDCVRn(i));
>>       writel_relaxed(drvdata->ctxid_mask0, drvdata->base + TRCCIDCCTLR0);
>>       writel_relaxed(drvdata->ctxid_mask1, drvdata->base + TRCCIDCCTLR1);
>> @@ -507,7 +507,7 @@ static ssize_t reset_store(struct device *dev,
>>
>>       drvdata->ctxid_idx = 0x0;
>>       for (i = 0; i < drvdata->numcidc; i++)
>> -             drvdata->ctxid_val[i] = 0x0;
>> +             drvdata->ctxid_pid[i] = 0x0;
>>       drvdata->ctxid_mask0 = 0x0;
>>       drvdata->ctxid_mask1 = 0x0;
>>
>> @@ -1815,7 +1815,7 @@ static ssize_t ctxid_idx_store(struct device *dev,
>>  }
>>  static DEVICE_ATTR_RW(ctxid_idx);
>>
>> -static ssize_t ctxid_val_show(struct device *dev,
>> +static ssize_t ctxid_pid_show(struct device *dev,
>>                             struct device_attribute *attr,
>>                             char *buf)
>>  {
>> @@ -1825,12 +1825,12 @@ static ssize_t ctxid_val_show(struct device *dev,
>>
>>       spin_lock(&drvdata->spinlock);
>>       idx = drvdata->ctxid_idx;
>> -     val = (unsigned long)drvdata->ctxid_val[idx];
>> +     val = (unsigned long)drvdata->ctxid_pid[idx];
>>       spin_unlock(&drvdata->spinlock);
>>       return scnprintf(buf, PAGE_SIZE, "%#lx\n", val);
>>  }
>>
>> -static ssize_t ctxid_val_store(struct device *dev,
>> +static ssize_t ctxid_pid_store(struct device *dev,
>>                              struct device_attribute *attr,
>>                              const char *buf, size_t size)
>>  {
>> @@ -1850,11 +1850,11 @@ static ssize_t ctxid_val_store(struct device *dev,
>>
>>       spin_lock(&drvdata->spinlock);
>>       idx = drvdata->ctxid_idx;
>> -     drvdata->ctxid_val[idx] = (u64)val;
>> +     drvdata->ctxid_pid[idx] = (u64)val;
>>       spin_unlock(&drvdata->spinlock);
>>       return size;
>>  }
>> -static DEVICE_ATTR_RW(ctxid_val);
>> +static DEVICE_ATTR_RW(ctxid_pid);
>>
>>  static ssize_t ctxid_masks_show(struct device *dev,
>>                               struct device_attribute *attr,
>> @@ -1949,7 +1949,7 @@ static ssize_t ctxid_masks_store(struct device *dev,
>>                */
>>               for (j = 0; j < 8; j++) {
>>                       if (maskbyte & 1)
>> -                             drvdata->ctxid_val[i] &= ~(0xFF << (j * 8));
>> +                             drvdata->ctxid_pid[i] &= ~(0xFF << (j * 8));
>>                       maskbyte >>= 1;
>>               }
>>               /* Select the next ctxid comparator mask value */
>> @@ -2193,7 +2193,7 @@ static struct attribute *coresight_etmv4_attrs[] = {
>>       &dev_attr_res_idx.attr,
>>       &dev_attr_res_ctrl.attr,
>>       &dev_attr_ctxid_idx.attr,
>> -     &dev_attr_ctxid_val.attr,
>> +     &dev_attr_ctxid_pid.attr,
>>       &dev_attr_ctxid_masks.attr,
>>       &dev_attr_vmid_idx.attr,
>>       &dev_attr_vmid_val.attr,
>> @@ -2514,7 +2514,7 @@ static void etm4_init_default_data(struct etmv4_drvdata *drvdata)
>>       }
>>
>>       for (i = 0; i < drvdata->numcidc; i++)
>> -             drvdata->ctxid_val[i] = 0x0;
>> +             drvdata->ctxid_pid[i] = 0x0;
>>       drvdata->ctxid_mask0 = 0x0;
>>       drvdata->ctxid_mask1 = 0x0;
>>
>> diff --git a/drivers/hwtracing/coresight/coresight-etm4x.h b/drivers/hwtracing/coresight/coresight-etm4x.h
>> index e08e983..1e8fb36 100644
>> --- a/drivers/hwtracing/coresight/coresight-etm4x.h
>> +++ b/drivers/hwtracing/coresight/coresight-etm4x.h
>> @@ -265,7 +265,7 @@
>>   * @addr_type:       Current status of the comparator register.
>>   * @ctxid_idx:       Context ID index selector.
>>   * @ctxid_size:      Size of the context ID field to consider.
>> - * @ctxid_val:       Value of the context ID comparator.
>> + * @ctxid_pid:       Value of the context ID comparator.
>>   * @ctxid_mask0:Context ID comparator mask for comparator 0-3.
>>   * @ctxid_mask1:Context ID comparator mask for comparator 4-7.
>>   * @vmid_idx:        VM ID index selector.
>> @@ -352,7 +352,7 @@ struct etmv4_drvdata {
>>       u8                              addr_type[ETM_MAX_SINGLE_ADDR_CMP];
>>       u8                              ctxid_idx;
>>       u8                              ctxid_size;
>> -     u64                             ctxid_val[ETMv4_MAX_CTXID_CMP];
>> +     u64                             ctxid_pid[ETMv4_MAX_CTXID_CMP];
>>       u32                             ctxid_mask0;
>>       u32                             ctxid_mask1;
>>       u8                              vmid_idx;
>>
>
>
> --
> Qualcomm Innovation Center, Inc.
> The Qualcomm Innovation Center, Inc. is a member of the Code Aurora Forum,
> a Linux Foundation Collaborative Project


From dianders at chromium.org  Thu Aug 27 08:16:19 2015
From: dianders at chromium.org (Doug Anderson)
Date: Thu, 27 Aug 2015 08:16:19 -0700
Subject: [PATCH v1 0/5] Fix broken DMAFLUSHP on Rockchips platform
In-Reply-To: <1440685419-22037-1-git-send-email-shawn.lin@rock-chips.com>
References: <1440685419-22037-1-git-send-email-shawn.lin@rock-chips.com>
Message-ID: <CAD=FV=XTG8RukPwDvVuEifNz9WGUUs3w1B26cpm8obSdV5bFTQ@mail.gmail.com>

Shawn,

On Thu, Aug 27, 2015 at 7:23 AM, Shawn Lin <shawn.lin at rock-chips.com> wrote:
> Changes in v1:
> - rename broken-no-flushp to "arm,pl330-broken-no-flushp" suggested
>   by Krzysztof.
> - add From original author.
> - remove Sunny's tag
>
> Shawn Lin (5):
>   DMA: pl330: support burst mode for dev-to-mem and mem-to-dev transmit
>   DMA: pl330: add quirk for broken no flushp
>   ARM: dts: Add arm,pl330-broken-no-flushp quirk for rk3288 platform
>   ARM: dts: Add arm,pl330-broken-no-flushp quirk for rk3xxx platform
>   Documentation: arm-pl330: add description of
>     arm,pl330-broken-no-flushp

Something still seems strange here.  All patches are listed in the
cover letter as "From" you.  You should make sure you change the
author in your git tree using "git commit --amend --author=<author>"
so that patman can generate the proper cover letter.

-Doug


From gabriele.paoloni at huawei.com  Thu Aug 27 08:21:31 2015
From: gabriele.paoloni at huawei.com (Gabriele Paoloni)
Date: Thu, 27 Aug 2015 15:21:31 +0000
Subject: [PATCH v8 3/6] PCI: designware: Add ARM64 support
In-Reply-To: <CAG374jDDY4COvM_UTfGmJfbXQrMywYB511-fZiWen3GU9VhQvw@mail.gmail.com>
References: <1440496734-18417-1-git-send-email-wangzhou1@hisilicon.com>
 <1440496734-18417-4-git-send-email-wangzhou1@hisilicon.com>
 <CAG374jDDY4COvM_UTfGmJfbXQrMywYB511-fZiWen3GU9VhQvw@mail.gmail.com>
Message-ID: <EE11001F9E5DDD47B7634E2F8A612F2E162054A6@lhreml503-mbs>

> -----Original Message-----
> From: linux-pci-owner at vger.kernel.org [mailto:linux-pci-owner at vger.kernel.org]
> On Behalf Of Gabriel Fernandez
> Sent: 27 August 2015 13:57
> To: Wangzhou (B)
> Cc: Bjorn Helgaas; jingoohan1 at gmail.com; pratyush.anand at gmail.com; Arnd
> Bergmann; Russell King; thomas.petazzoni at free-electrons.com; Gabriele Paoloni;
> lorenzo.pieralisi at arm.com; james.morse at arm.com; Liviu Dudau;
> jason at lakedaemon.net; robh at kernel.org; devicetree at vger.kernel.org; linux-
> pci at vger.kernel.org; xuwei (O); qiuzhenfa; liudongdong (C); zhangjukuo;
> Liguozhu (Kenneth); qiujiang; linux-arm-kernel at lists.infradead.org
> Subject: Re: [PATCH v8 3/6] PCI: designware: Add ARM64 support
> 
> Hi Zhou,
> 
> You can add my Tested-by: Gabriel Fernandez <gabriel.fernandez at st.com>
> 
> I tested your patchset with a STMicroelectronics PCIe controller.
> This controller is based on designware PCIe driver and works on ARM32.
> 
> Please find my patchset here:
> http://www.spinics.net/lists/kernel/msg2064266.html
> 
> Best Regards.
> 
> Gabriel.

Many Thanks for this Gabriel

Cheers
Gab

> 
> On 25 August 2015 at 11:58, Zhou Wang <wangzhou1 at hisilicon.com> wrote:
> > This patch tries to unify ARM32 and ARM64 PCIe in designware driver. Delete
> > function dw_pcie_setup, dw_pcie_scan_bus, dw_pcie_map_irq and struct hw_pci,
> > move related operations to dw_pcie_host_init.
> >
> > This patch also try to use of_pci_get_host_bridge_resources for ARM32 and
> ARM64
> > according to the suggestion for Gabriele[1]
> >
> > Finally this patch reverts commit f4c55c5a3f7f "PCI: designware: Program ATU
> > with untranslated address" based on 1/6 in this series. we delete *_mod_base
> in
> > pcie-designware. This was discussed in [2]
> >
> > I have compiled the driver with multi_v7_defconfig. However, I don't have
> > ARM32 PCIe related board to do test. It will be appreciated if someone could
> > help to test it.
> >
> > Signed-off-by: Zhou Wang <wangzhou1 at hisilicon.com>
> > Signed-off-by: Gabriele Paoloni <gabriele.paoloni at huawei.com>
> > Signed-off-by: Arnd Bergmann <arnd at arndb.de>
> > Tested-By: James Morse <james.morse at arm.com>
> >
> > [1] http://www.spinics.net/lists/linux-pci/msg42194.html
> > [2] http://www.spinics.net/lists/arm-kernel/msg436779.html
> > ---
> >  drivers/pci/host/pci-dra7xx.c      |  14 +--
> >  drivers/pci/host/pci-keystone-dw.c |   2 +-
> >  drivers/pci/host/pcie-designware.c | 230 +++++++++++++---------------------
> ---
> >  drivers/pci/host/pcie-designware.h |  14 +--
> >  4 files changed, 90 insertions(+), 170 deletions(-)
> >
> > diff --git a/drivers/pci/host/pci-dra7xx.c b/drivers/pci/host/pci-dra7xx.c
> > index 18ae7ff..ac401be 100644
> > --- a/drivers/pci/host/pci-dra7xx.c
> > +++ b/drivers/pci/host/pci-dra7xx.c
> > @@ -141,15 +141,15 @@ static void dra7xx_pcie_host_init(struct pcie_port *pp)
> >  {
> >         dw_pcie_setup_rc(pp);
> >
> > -       if (pp->io_mod_base)
> > -               pp->io_mod_base &= CPU_TO_BUS_ADDR;
> > +       if (pp->io_base)
> > +               pp->io_base &= CPU_TO_BUS_ADDR;
> >
> > -       if (pp->mem_mod_base)
> > -               pp->mem_mod_base &= CPU_TO_BUS_ADDR;
> > +       if (pp->mem_base)
> > +               pp->mem_base &= CPU_TO_BUS_ADDR;
> >
> > -       if (pp->cfg0_mod_base) {
> > -               pp->cfg0_mod_base &= CPU_TO_BUS_ADDR;
> > -               pp->cfg1_mod_base &= CPU_TO_BUS_ADDR;
> > +       if (pp->cfg0_base) {
> > +               pp->cfg0_base &= CPU_TO_BUS_ADDR;
> > +               pp->cfg1_base &= CPU_TO_BUS_ADDR;
> >         }
> >
> >         dra7xx_pcie_establish_link(pp);
> > diff --git a/drivers/pci/host/pci-keystone-dw.c b/drivers/pci/host/pci-
> keystone-dw.c
> > index f34892e..b1e4135 100644
> > --- a/drivers/pci/host/pci-keystone-dw.c
> > +++ b/drivers/pci/host/pci-keystone-dw.c
> > @@ -327,7 +327,7 @@ static void ks_dw_pcie_clear_dbi_mode(void __iomem
> *reg_virt)
> >  void ks_dw_pcie_setup_rc_app_regs(struct keystone_pcie *ks_pcie)
> >  {
> >         struct pcie_port *pp = &ks_pcie->pp;
> > -       u32 start = pp->mem.start, end = pp->mem.end;
> > +       u32 start = pp->mem->start, end = pp->mem->end;
> >         int i, tr_size;
> >
> >         /* Disable BARs for inbound access */
> > diff --git a/drivers/pci/host/pcie-designware.c b/drivers/pci/host/pcie-
> designware.c
> > index c5d407c..e2d1898 100644
> > --- a/drivers/pci/host/pcie-designware.c
> > +++ b/drivers/pci/host/pcie-designware.c
> > @@ -11,6 +11,7 @@
> >   * published by the Free Software Foundation.
> >   */
> >
> > +#include <linux/hardirq.h>
> >  #include <linux/irq.h>
> >  #include <linux/irqdomain.h>
> >  #include <linux/kernel.h>
> > @@ -69,16 +70,7 @@
> >  #define PCIE_ATU_FUNC(x)               (((x) & 0x7) << 16)
> >  #define PCIE_ATU_UPPER_TARGET          0x91C
> >
> > -static struct hw_pci dw_pci;
> > -
> > -static unsigned long global_io_offset;
> > -
> > -static inline struct pcie_port *sys_to_pcie(struct pci_sys_data *sys)
> > -{
> > -       BUG_ON(!sys->private_data);
> > -
> > -       return sys->private_data;
> > -}
> > +static struct pci_ops dw_pcie_ops;
> >
> >  int dw_pcie_cfg_read(void __iomem *addr, int where, int size, u32 *val)
> >  {
> > @@ -255,7 +247,7 @@ static void dw_pcie_msi_set_irq(struct pcie_port *pp,
> int irq)
> >  static int assign_irq(int no_irqs, struct msi_desc *desc, int *pos)
> >  {
> >         int irq, pos0, i;
> > -       struct pcie_port *pp = sys_to_pcie(desc->dev->bus->sysdata);
> > +       struct pcie_port *pp = desc->dev->bus->sysdata;
> >
> >         pos0 = bitmap_find_free_region(pp->msi_irq_in_use, MAX_MSI_IRQS,
> >                                        order_base_2(no_irqs));
> > @@ -298,7 +290,7 @@ static int dw_msi_setup_irq(struct msi_controller *chip,
> struct pci_dev *pdev,
> >  {
> >         int irq, pos;
> >         struct msi_msg msg;
> > -       struct pcie_port *pp = sys_to_pcie(pdev->bus->sysdata);
> > +       struct pcie_port *pp = pdev->bus->sysdata;
> >
> >         if (desc->msi_attrib.is_msix)
> >                 return -EINVAL;
> > @@ -327,7 +319,7 @@ static void dw_msi_teardown_irq(struct msi_controller
> *chip, unsigned int irq)
> >  {
> >         struct irq_data *data = irq_get_irq_data(irq);
> >         struct msi_desc *msi = irq_data_get_msi(data);
> > -       struct pcie_port *pp = sys_to_pcie(msi->dev->bus->sysdata);
> > +       struct pcie_port *pp = msi->dev->bus->sysdata;
> >
> >         clear_irq_range(pp, irq, 1, data->hwirq);
> >  }
> > @@ -363,14 +355,12 @@ int dw_pcie_host_init(struct pcie_port *pp)
> >  {
> >         struct device_node *np = pp->dev->of_node;
> >         struct platform_device *pdev = to_platform_device(pp->dev);
> > -       struct of_pci_range range;
> > -       struct of_pci_range_parser parser;
> > +       struct pci_bus *bus;
> >         struct resource *cfg_res;
> > -       u32 val, ns;
> > -       const __be32 *addrp;
> > -       int i, index, ret;
> > -
> > -       ns = of_n_size_cells(np);
> > +       LIST_HEAD(res);
> > +       u32 val;
> > +       int i, ret;
> > +       struct resource_entry *win;
> >
> >         cfg_res = platform_get_resource_byname(pdev, IORESOURCE_MEM,
> "config");
> >         if (cfg_res) {
> > @@ -378,85 +368,60 @@ int dw_pcie_host_init(struct pcie_port *pp)
> >                 pp->cfg1_size = resource_size(cfg_res)/2;
> >                 pp->cfg0_base = cfg_res->start;
> >                 pp->cfg1_base = cfg_res->start + pp->cfg0_size;
> > -
> > -               /* Find the untranslated configuration space address */
> > -               index = of_property_match_string(np, "reg-names", "config");
> > -               addrp = of_get_address(np, index, NULL, NULL);
> > -               pp->cfg0_mod_base = of_read_number(addrp, ns);
> > -               pp->cfg1_mod_base = pp->cfg0_mod_base + pp->cfg0_size;
> >         } else {
> >                 dev_err(pp->dev, "missing *config* reg space\n");
> >         }
> >
> > -       if (of_pci_range_parser_init(&parser, np)) {
> > -               dev_err(pp->dev, "missing ranges property\n");
> > -               return -EINVAL;
> > -       }
> > +       ret = of_pci_get_host_bridge_resources(np, 0, 0xff, &res, &pp-
> >io_base);
> > +       if (ret)
> > +               return ret;
> >
> >         /* Get the I/O and memory ranges from DT */
> > -       for_each_of_pci_range(&parser, &range) {
> > -               unsigned long restype = range.flags & IORESOURCE_TYPE_BITS;
> > -
> > -               if (restype == IORESOURCE_IO) {
> > -                       of_pci_range_to_resource(&range, np, &pp->io);
> > -                       pp->io.name = "I/O";
> > -                       pp->io.start = max_t(resource_size_t,
> > -                                            PCIBIOS_MIN_IO,
> > -                                            range.pci_addr +
> global_io_offset);
> > -                       pp->io.end = min_t(resource_size_t,
> > -                                          IO_SPACE_LIMIT,
> > -                                          range.pci_addr + range.size
> > -                                          + global_io_offset - 1);
> > -                       pp->io_size = resource_size(&pp->io);
> > -                       pp->io_bus_addr = range.pci_addr;
> > -                       pp->io_base = range.cpu_addr;
> > -
> > -                       /* Find the untranslated IO space address */
> > -                       pp->io_mod_base = range.cpu_addr;
> > -               }
> > -               if (restype == IORESOURCE_MEM) {
> > -                       of_pci_range_to_resource(&range, np, &pp->mem);
> > -                       pp->mem.name = "MEM";
> > -                       pp->mem_size = resource_size(&pp->mem);
> > -                       pp->mem_bus_addr = range.pci_addr;
> > -
> > -                       /* Find the untranslated MEM space address */
> > -                       pp->mem_mod_base = range.cpu_addr;
> > -               }
> > -               if (restype == 0) {
> > -                       of_pci_range_to_resource(&range, np, &pp->cfg);
> > -                       pp->cfg0_size = resource_size(&pp->cfg)/2;
> > -                       pp->cfg1_size = resource_size(&pp->cfg)/2;
> > -                       pp->cfg0_base = pp->cfg.start;
> > -                       pp->cfg1_base = pp->cfg.start + pp->cfg0_size;
> > -
> > -                       /* Find the untranslated configuration space address
> */
> > -                       pp->cfg0_mod_base = range.cpu_addr;
> > -                       pp->cfg1_mod_base = pp->cfg0_mod_base +
> > -                                           pp->cfg0_size;
> > +       resource_list_for_each_entry(win, &res) {
> > +               switch (resource_type(win->res)) {
> > +               case IORESOURCE_IO:
> > +                       pp->io = win->res;
> > +                       pp->io->name = "I/O";
> > +                       pp->io_size = resource_size(pp->io);
> > +                       pp->io_bus_addr = pp->io->start - win->offset;
> > +                       ret = pci_remap_iospace(pp->io, pp->io_base);
> > +                       if (ret) {
> > +                               dev_warn(pp->dev, "error %d: failed to map
> resource %pR\n",
> > +                                        ret, pp->io);
> > +                               continue;
> > +                       }
> > +                       break;
> > +               case IORESOURCE_MEM:
> > +                       pp->mem = win->res;
> > +                       pp->mem->name = "MEM";
> > +                       pp->mem_size = resource_size(pp->mem);
> > +                       pp->mem_bus_addr = pp->mem->start - win->offset;
> > +                       break;
> > +               case 0:
> > +                       pp->cfg = win->res;
> > +                       pp->cfg0_size = resource_size(pp->cfg)/2;
> > +                       pp->cfg1_size = resource_size(pp->cfg)/2;
> > +                       pp->cfg0_base = pp->cfg->start;
> > +                       pp->cfg1_base = pp->cfg->start + pp->cfg0_size;
> > +                       break;
> > +               case IORESOURCE_BUS:
> > +                       pp->busn = win->res;
> > +                       break;
> > +               default:
> > +                       continue;
> >                 }
> >         }
> >
> > -       ret = of_pci_parse_bus_range(np, &pp->busn);
> > -       if (ret < 0) {
> > -               pp->busn.name = np->name;
> > -               pp->busn.start = 0;
> > -               pp->busn.end = 0xff;
> > -               pp->busn.flags = IORESOURCE_BUS;
> > -               dev_dbg(pp->dev, "failed to parse bus-range property: %d,
> using default %pR\n",
> > -                       ret, &pp->busn);
> > -       }
> > -
> >         if (!pp->dbi_base) {
> > -               pp->dbi_base = devm_ioremap(pp->dev, pp->cfg.start,
> > -                                       resource_size(&pp->cfg));
> > +               pp->dbi_base = devm_ioremap(pp->dev, pp->cfg->start,
> > +                                       resource_size(pp->cfg));
> >                 if (!pp->dbi_base) {
> >                         dev_err(pp->dev, "error with ioremap\n");
> >                         return -ENOMEM;
> >                 }
> >         }
> >
> > -       pp->mem_base = pp->mem.start;
> > +       pp->mem_base = pp->mem->start;
> >
> >         if (!pp->va_cfg0_base) {
> >                 pp->va_cfg0_base = devm_ioremap(pp->dev, pp->cfg0_base,
> > @@ -505,7 +470,7 @@ int dw_pcie_host_init(struct pcie_port *pp)
> >
> >         if (!pp->ops->rd_other_conf)
> >                 dw_pcie_prog_outbound_atu(pp, PCIE_ATU_REGION_INDEX1,
> > -                                         PCIE_ATU_TYPE_MEM, pp-
> >mem_mod_base,
> > +                                         PCIE_ATU_TYPE_MEM, pp->mem_base,
> >                                           pp->mem_bus_addr, pp->mem_size);
> >
> >         dw_pcie_wr_own_conf(pp, PCI_BASE_ADDRESS_0, 4, 0);
> > @@ -517,15 +482,30 @@ int dw_pcie_host_init(struct pcie_port *pp)
> >         val |= PORT_LOGIC_SPEED_CHANGE;
> >         dw_pcie_wr_own_conf(pp, PCIE_LINK_WIDTH_SPEED_CONTROL, 4, val);
> >
> > -#ifdef CONFIG_PCI_MSI
> > +       pp->root_bus_nr = pp->busn->start;
> > +       bus = pci_create_root_bus(pp->dev, pp->root_bus_nr, &dw_pcie_ops,
> > +                                 pp, &res);
> > +       if (!bus)
> > +               return -ENOMEM;
> > +
> > +#ifdef CONFIG_GENERIC_MSI_IRQ_DOMAIN
> > +       bus->msi = container_of(&pp->irq_domain, struct msi_controller,
> domain);
> > +#else
> >         dw_pcie_msi_chip.dev = pp->dev;
> > -       dw_pci.msi_ctrl = &dw_pcie_msi_chip;
> > +       bus->msi = &dw_pcie_msi_chip;
> >  #endif
> >
> > -       dw_pci.nr_controllers = 1;
> > -       dw_pci.private_data = (void **)&pp;
> > +       pci_scan_child_bus(bus);
> > +       if (pp->ops->scan_bus)
> > +               pp->ops->scan_bus(pp);
> > +
> > +#ifdef CONFIG_ARM
> > +       /* support old dtbs that incorrectly describe IRQs */
> > +       pci_fixup_irqs(pci_common_swizzle, of_irq_parse_and_map_pci);
> > +#endif
> >
> > -       pci_common_init_dev(pp->dev, &dw_pci);
> > +       pci_assign_unassigned_bus_resources(bus);
> > +       pci_bus_add_devices(bus);
> >
> >         return 0;
> >  }
> > @@ -544,12 +524,12 @@ static int dw_pcie_rd_other_conf(struct pcie_port *pp,
> struct pci_bus *bus,
> >
> >         if (bus->parent->number == pp->root_bus_nr) {
> >                 type = PCIE_ATU_TYPE_CFG0;
> > -               cpu_addr = pp->cfg0_mod_base;
> > +               cpu_addr = pp->cfg0_base;
> >                 cfg_size = pp->cfg0_size;
> >                 va_cfg_base = pp->va_cfg0_base;
> >         } else {
> >                 type = PCIE_ATU_TYPE_CFG1;
> > -               cpu_addr = pp->cfg1_mod_base;
> > +               cpu_addr = pp->cfg1_base;
> >                 cfg_size = pp->cfg1_size;
> >                 va_cfg_base = pp->va_cfg1_base;
> >         }
> > @@ -559,7 +539,7 @@ static int dw_pcie_rd_other_conf(struct pcie_port *pp,
> struct pci_bus *bus,
> >                                   busdev, cfg_size);
> >         ret = dw_pcie_cfg_read(va_cfg_base + address, where, size, val);
> >         dw_pcie_prog_outbound_atu(pp, PCIE_ATU_REGION_INDEX0,
> > -                                 PCIE_ATU_TYPE_IO, pp->io_mod_base,
> > +                                 PCIE_ATU_TYPE_IO, pp->io_base,
> >                                   pp->io_bus_addr, pp->io_size);
> >
> >         return ret;
> > @@ -579,12 +559,12 @@ static int dw_pcie_wr_other_conf(struct pcie_port *pp,
> struct pci_bus *bus,
> >
> >         if (bus->parent->number == pp->root_bus_nr) {
> >                 type = PCIE_ATU_TYPE_CFG0;
> > -               cpu_addr = pp->cfg0_mod_base;
> > +               cpu_addr = pp->cfg0_base;
> >                 cfg_size = pp->cfg0_size;
> >                 va_cfg_base = pp->va_cfg0_base;
> >         } else {
> >                 type = PCIE_ATU_TYPE_CFG1;
> > -               cpu_addr = pp->cfg1_mod_base;
> > +               cpu_addr = pp->cfg1_base;
> >                 cfg_size = pp->cfg1_size;
> >                 va_cfg_base = pp->va_cfg1_base;
> >         }
> > @@ -594,7 +574,7 @@ static int dw_pcie_wr_other_conf(struct pcie_port *pp,
> struct pci_bus *bus,
> >                                   busdev, cfg_size);
> >         ret = dw_pcie_cfg_write(va_cfg_base + address, where, size, val);
> >         dw_pcie_prog_outbound_atu(pp, PCIE_ATU_REGION_INDEX0,
> > -                                 PCIE_ATU_TYPE_IO, pp->io_mod_base,
> > +                                 PCIE_ATU_TYPE_IO, pp->io_base,
> >                                   pp->io_bus_addr, pp->io_size);
> >
> >         return ret;
> > @@ -626,7 +606,7 @@ static int dw_pcie_valid_config(struct pcie_port *pp,
> >  static int dw_pcie_rd_conf(struct pci_bus *bus, u32 devfn, int where,
> >                         int size, u32 *val)
> >  {
> > -       struct pcie_port *pp = sys_to_pcie(bus->sysdata);
> > +       struct pcie_port *pp = bus->sysdata;
> >         int ret;
> >
> >         if (dw_pcie_valid_config(pp, bus, PCI_SLOT(devfn)) == 0) {
> > @@ -650,7 +630,7 @@ static int dw_pcie_rd_conf(struct pci_bus *bus, u32
> devfn, int where,
> >  static int dw_pcie_wr_conf(struct pci_bus *bus, u32 devfn,
> >                         int where, int size, u32 val)
> >  {
> > -       struct pcie_port *pp = sys_to_pcie(bus->sysdata);
> > +       struct pcie_port *pp = bus->sysdata;
> >         int ret;
> >
> >         if (dw_pcie_valid_config(pp, bus, PCI_SLOT(devfn)) == 0)
> > @@ -674,62 +654,6 @@ static struct pci_ops dw_pcie_ops = {
> >         .write = dw_pcie_wr_conf,
> >  };
> >
> > -static int dw_pcie_setup(int nr, struct pci_sys_data *sys)
> > -{
> > -       struct pcie_port *pp;
> > -
> > -       pp = sys_to_pcie(sys);
> > -
> > -       if (global_io_offset < SZ_1M && pp->io_size > 0) {
> > -               sys->io_offset = global_io_offset - pp->io_bus_addr;
> > -               pci_ioremap_io(global_io_offset, pp->io_base);
> > -               global_io_offset += SZ_64K;
> > -               pci_add_resource_offset(&sys->resources, &pp->io,
> > -                                       sys->io_offset);
> > -       }
> > -
> > -       sys->mem_offset = pp->mem.start - pp->mem_bus_addr;
> > -       pci_add_resource_offset(&sys->resources, &pp->mem, sys->mem_offset);
> > -       pci_add_resource(&sys->resources, &pp->busn);
> > -
> > -       return 1;
> > -}
> > -
> > -static struct pci_bus *dw_pcie_scan_bus(int nr, struct pci_sys_data *sys)
> > -{
> > -       struct pci_bus *bus;
> > -       struct pcie_port *pp = sys_to_pcie(sys);
> > -
> > -       pp->root_bus_nr = sys->busnr;
> > -       bus = pci_scan_root_bus(pp->dev, sys->busnr,
> > -                                 &dw_pcie_ops, sys, &sys->resources);
> > -       if (!bus)
> > -               return NULL;
> > -
> > -       if (bus && pp->ops->scan_bus)
> > -               pp->ops->scan_bus(pp);
> > -
> > -       return bus;
> > -}
> > -
> > -static int dw_pcie_map_irq(const struct pci_dev *dev, u8 slot, u8 pin)
> > -{
> > -       struct pcie_port *pp = sys_to_pcie(dev->bus->sysdata);
> > -       int irq;
> > -
> > -       irq = of_irq_parse_and_map_pci(dev, slot, pin);
> > -       if (!irq)
> > -               irq = pp->irq;
> > -
> > -       return irq;
> > -}
> > -
> > -static struct hw_pci dw_pci = {
> > -       .setup          = dw_pcie_setup,
> > -       .scan           = dw_pcie_scan_bus,
> > -       .map_irq        = dw_pcie_map_irq,
> > -};
> > -
> >  void dw_pcie_setup_rc(struct pcie_port *pp)
> >  {
> >         u32 val;
> > diff --git a/drivers/pci/host/pcie-designware.h b/drivers/pci/host/pcie-
> designware.h
> > index d0bbd27..264c969 100644
> > --- a/drivers/pci/host/pcie-designware.h
> > +++ b/drivers/pci/host/pcie-designware.h
> > @@ -27,25 +27,21 @@ struct pcie_port {
> >         u8                      root_bus_nr;
> >         void __iomem            *dbi_base;
> >         u64                     cfg0_base;
> > -       u64                     cfg0_mod_base;
> >         void __iomem            *va_cfg0_base;
> >         u32                     cfg0_size;
> >         u64                     cfg1_base;
> > -       u64                     cfg1_mod_base;
> >         void __iomem            *va_cfg1_base;
> >         u32                     cfg1_size;
> > -       u64                     io_base;
> > -       u64                     io_mod_base;
> > +       resource_size_t         io_base;
> >         phys_addr_t             io_bus_addr;
> >         u32                     io_size;
> >         u64                     mem_base;
> > -       u64                     mem_mod_base;
> >         phys_addr_t             mem_bus_addr;
> >         u32                     mem_size;
> > -       struct resource         cfg;
> > -       struct resource         io;
> > -       struct resource         mem;
> > -       struct resource         busn;
> > +       struct resource         *cfg;
> > +       struct resource         *io;
> > +       struct resource         *mem;
> > +       struct resource         *busn;
> >         int                     irq;
> >         u32                     lanes;
> >         struct pcie_host_ops    *ops;
> > --
> > 1.9.1
> >
> >
> > _______________________________________________
> > linux-arm-kernel mailing list
> > linux-arm-kernel at lists.infradead.org
> > http://lists.infradead.org/mailman/listinfo/linux-arm-kernel
> --
> To unsubscribe from this list: send the line "unsubscribe linux-pci" in
> the body of a message to majordomo at vger.kernel.org
> More majordomo info at  http://vger.kernel.org/majordomo-info.html

From svarbanov at mm-sol.com  Thu Aug 27 08:26:45 2015
From: svarbanov at mm-sol.com (Stanimir Varbanov)
Date: Thu, 27 Aug 2015 18:26:45 +0300
Subject: [PATCH v2] soc: qcom: smd: Use correct remote processor ID
In-Reply-To: <1440618165-9410-1-git-send-email-agross@codeaurora.org>
References: <1440618165-9410-1-git-send-email-agross@codeaurora.org>
Message-ID: <55DF2C35.4030207@mm-sol.com>

On 08/26/2015 10:42 PM, Andy Gross wrote:
> This patch fixes SMEM addressing issues when remote processors need to use
> secure SMEM partitions.
> 
> Signed-off-by: Andy Gross <agross at codeaurora.org>
> ---
>  .../devicetree/bindings/soc/qcom/qcom,smd.txt      |    6 ++++++
>  drivers/soc/qcom/smd.c                             |   15 +++++++++++----
>  2 files changed, 17 insertions(+), 4 deletions(-)
> 
> diff --git a/Documentation/devicetree/bindings/soc/qcom/qcom,smd.txt b/Documentation/devicetree/bindings/soc/qcom/qcom,smd.txt
> index f65c76d..97d9b3e 100644
> --- a/Documentation/devicetree/bindings/soc/qcom/qcom,smd.txt
> +++ b/Documentation/devicetree/bindings/soc/qcom/qcom,smd.txt
> @@ -37,6 +37,12 @@ The edge is described by the following properties:
>  	Definition: the identifier of the remote processor in the smd channel
>  		    allocation table
>  
> +- qcom,remote-pid:
> +	Usage: optional
> +	Value type: <u32>
> +	Definition: the identifier for the remote processor as known by the rest
> +		    of the system.
> +
>  = SMD DEVICES
>  
>  In turn, subnodes of the "edges" represent devices tied to SMD channels on that
> diff --git a/drivers/soc/qcom/smd.c b/drivers/soc/qcom/smd.c
> index 327adcf..5706a81 100644
> --- a/drivers/soc/qcom/smd.c
> +++ b/drivers/soc/qcom/smd.c
> @@ -111,6 +111,7 @@ struct qcom_smd_edge {
>  	struct qcom_smd *smd;
>  	struct device_node *of_node;
>  	unsigned edge_id;
> +	unsigned remote_pid;

Andy, you forgot to add this new field in structure description header.

<snip>

-- 
regards,
Stan


From gregory.clement at free-electrons.com  Thu Aug 27 08:28:00 2015
From: gregory.clement at free-electrons.com (Gregory CLEMENT)
Date: Thu, 27 Aug 2015 17:28:00 +0200
Subject: [PATCH 03/10] ARM: marvell/dt: add crypto related nodes to armada
 370 dtsi
In-Reply-To: <1439885341-14644-4-git-send-email-boris.brezillon@free-electrons.com>
 (Boris Brezillon's message of "Tue, 18 Aug 2015 10:08:54 +0200")
References: <1439885341-14644-1-git-send-email-boris.brezillon@free-electrons.com>
 <1439885341-14644-4-git-send-email-boris.brezillon@free-electrons.com>
Message-ID: <877fog69a7.fsf@free-electrons.com>

Hi Boris and Arnaud,

Boris Brezillon <boris.brezillon at free-electrons.com> writes:

> From: Arnaud Ebalard <arno at natisbad.org>
>
> Add crypto related nodes in armada-370.dtsi.
[...]
> +
> +			crypto at 90000 {
> +				compatible = "marvell,armada-370-crypto";
> +				reg = <0x90000 0x10000>;
> +				reg-names = "regs";
> +				interrupts = <48>;
> +				clocks = <&gateclk 23>;
> +				clock-names = "cesa0";
> +				marvell,crypto-srams = <&crypto_sram>;
> +				marvell,crypto-sram-size = <0x7e0>;
> +			};
> +		};
> +
> +		crypto_sram: sa-sram {
> +			compatible = "mmio-sram";
> +			reg = <MBUS_ID(0x09, 0x01) 0 0x800>;
> +			reg-names = "sram";
> +			clocks = <&gateclk 23>;
> +			#address-cells = <1>;
> +			#size-cells = <1>;
> +			ranges = <0 MBUS_ID(0x09, 0x01) 0 0x800>;
> +
> +			idle-sram at 0 {
> +				reg = <0x0 0x20>;
> +			};

So you think at the cpuilde hack using the sram. And you reserved 32
bytes for it. So indeed it is enough to store the code we need. Could
you add a little comment about it ?

In mvebu_setup_boot_addr_wa we use mvebu_mbus_add_window_by_id but this
windows was also added by the code you add. I wonder if it could be a
problem.

Maybe we should look for if the idle-sram is present and in this case
not calling mvebu_mbus_add_window_by_id, but it is not necessary for
this series.

Once you have added the comment you can add my
Acked-by: Gregory CLEMENT <gregory.clement at free-electrons.com>

Thanks,

Gregory
-- 
Gregory Clement, Free Electrons
Kernel, drivers, real-time and embedded Linux
development, consulting, training and support.
http://free-electrons.com


From Dave.Martin at arm.com  Thu Aug 27 08:28:12 2015
From: Dave.Martin at arm.com (Dave Martin)
Date: Thu, 27 Aug 2015 16:28:12 +0100
Subject: [PATCH] arm: Handle starting up in secure mode
In-Reply-To: <55DDCAFB.60602@codeaurora.org>
References: <1440424572-27116-1-git-send-email-cov@codeaurora.org>
 <20150826103940.GD6281@e103592.cambridge.arm.com>
 <20150826104839.GC21084@n2100.arm.linux.org.uk>
 <55DDCAFB.60602@codeaurora.org>
Message-ID: <20150827152812.GE6281@e103592.cambridge.arm.com>

On Wed, Aug 26, 2015 at 10:19:39AM -0400, Christopher Covington wrote:
> Hi,
> 
> Thank you for the feedback.
> 
> On 08/26/2015 06:48 AM, Russell King - ARM Linux wrote:
> > On Wed, Aug 26, 2015 at 11:39:42AM +0100, Dave Martin wrote:
> >> On Mon, Aug 24, 2015 at 09:55:26AM -0400, Christopher Covington wrote:
> >>> ARM Linux appears to have never been made aware of the ARMv7 security
> >>> extensions. When CONFIG_ARM_SEC_EXT=y, have it probe for its security
> >>> state by checking whether CNTFRQ is writeable and potentially make
> >>> mode changes based on the information. The most features are available
> >>> from hypervisor (HYP) mode, so switch to it possible. Failing that,
> >>> prefer non-secure supervisor (SVC) mode to secure supervisor mode.
> >>
> >> Up to now we've steered clear of this, since it's a bit of a fig leaf
> >> for broken firmware unless Linux actually has some valid use for the
> >> Security Extensions itself.
> >>
> >> Shouldn't the bootloader or firmware be doing this stuff, and if not,
> >> why not?
> 
> In my opinion, it is sometimes useful, particularly when running on simulators
> or performing bring up, to have as little dependency on firmwares and
> bootloaders as possible. I want to run Linux out of reset, or get as close to

Definitely :)  That's exactly why the bootwrapper exists.

> that as possible. I want an ease of use comparable to QEMU's Linux loader on
> other simulators, like ARM's RTSM/AEM/FVPs, without various different,
> fragmented model plugins or the overhead and noise of the semihosting
> bootwrapper. I have attempted to craft the patches in such a way that the
> enjoyment of sophisticated firmwares and bootloaders remains unhindered.
> 
> >> Some other things that would need to be considered in any case:
> >>
> >>  * SoC-specific setup of the Non-secure view of the system:  This has
> >>    to happen very early, so making it DT aware is going to be hard --
> >>    failing that, we are effectively risking bringing back board files.
> >>    The split in responsibility between firmware/bootloader and kernel
> >>    needs to be clearly defined and (as far as possible) platform-
> >>    independent, otherwise we'll have total chaos.
> 
> My intention was to only perform architecturally defined initialization. All
> implementation defined specifics would remain delegated to firmware, simulator
> reset state hacks, or external debuggers, as the case may be. Note that using
> this code does not preclude running firmware, just that if you want Linux to
> do the exception level/mode transitions, you can omit those instructions from
> firmware. I'll have to refresh my memory--it's been a while since I worked on
> this, I apologize--but I think I used a modified bootwrapper to still perform
> its usual GIC initialization.

This is really just moving what is probably the smallest and simplest
piece of the initialisation problem into the kernel.  Only in trivial
cases that don't involve real hardware is this going to remove the need
for firmware.

In the general case, the S->NS switch cannot be done without platform-
specific knowledge of both the S and NS physical views of the system.
But except for switching to NS, the kernel isn't going to use the knowledge
about the S view.


It would be interesting to see what the amended Documentation/arm/Booting
would look like...

My worry is that this even if this is handy for development, it will
introduce a new kernel boot protocol that is impossible to standardise.
Nonethess, vendors in a hurry will be tempted to use it if it's there.

[...]

Cheers
---Dave

> 
> >>  * Out of reset, generally the CPU state is only fully defined for the
> >>    highest exception level.  You probably need to be doing more setup
> >>    than you're currently doing.
> 
> Agreed. This is just the first step.
> 
> >>  * SMP, secondary boot and suspend/resume -- again involving board-
> >>    specific code.
> 
> I've only tested single core so far, but I was thinking external debuggers and
> simulators may be able to emulate PSCI in a semihosting-like manner, if
> merging holding pen code is as frowned upon as I think it is (that may be an
> AArch64-specific statement, but it'd probably be nice if similar facilities
> were available across A32 and A64).
> 
> >>  * You need to safely "park" the Secure World before running anything
> >>    in Non-Secure.  As a minimum, you would need to quiesce any
> >>    Secure interrupt sources, disable all interrupt traps to Monitor
> >>    mode, and make sure that the Monitor vectors point somewhere
> >>    real, so that executing SMC doesn't send the CPU off into the
> >>    long grass...
> 
> Thanks. I'll work towards support for these aspects in the next version.
> 
> > Another question is: has this been tested with kexec?
> 
> I have not tested it with kexec. My testing was mostly of cold boots performed
> some time back on ARM's AEM/RSTM/FVP using its configurable parameters and
> some simple custom firmwares to simulate entry under all the circumstances I
> could think of. I grepped instruction traces to make sure the initial mode
> after firmware was as intended and then that AArch32 Linux switched into the
> intended mode.
> 
> EL3: not present, AArch64, AArch32
> EL2: not present, AArch64, AArch32
> AArch32 Linux starts in: svc_s, svc_n, hyp_n, mon_s
> 
> By my calculations, there were 36 - 17 = 19 valid combinations.
> 
> Thanks,
> Christopher Covington
> 
> -- 
> Qualcomm Innovation Center, Inc.
> The Qualcomm Innovation Center, Inc. is a member of the Code Aurora Forum,
> a Linux Foundation Collaborative Project
> 
> _______________________________________________
> linux-arm-kernel mailing list
> linux-arm-kernel at lists.infradead.org
> http://lists.infradead.org/mailman/listinfo/linux-arm-kernel



From cov at codeaurora.org  Thu Aug 27 08:33:09 2015
From: cov at codeaurora.org (Christopher Covington)
Date: Thu, 27 Aug 2015 11:33:09 -0400
Subject: [PATCH 2/5] coresight-etm4x: Change the name of the
 ctxid_val to ctxid_pid
In-Reply-To: <CANLsYkyA_C=PUDEUSbcA_Sa6Abqnxk1TP9ye6F9i0bWW_OxqiA@mail.gmail.com>
References: <1436258518-9339-1-git-send-email-zhang.chunyan@linaro.org>	<1436258518-9339-3-git-send-email-zhang.chunyan@linaro.org>	<55DDFE01.50201@codeaurora.org>
 <CANLsYkyA_C=PUDEUSbcA_Sa6Abqnxk1TP9ye6F9i0bWW_OxqiA@mail.gmail.com>
Message-ID: <55DF2DB5.7000909@codeaurora.org>

On 08/27/2015 11:12 AM, Mathieu Poirier wrote:
> On 26 August 2015 at 11:57, Christopher Covington <cov at codeaurora.org> wrote:
>> On 07/07/2015 04:41 AM, Chunyan Zhang wrote:
>>> 'ctxid_val' array was used to store the value of ETM context ID comparator
>>> which actually stores the process ID to be traced, so using 'ctxid_pid' as
>>> its name instead make it easier to understand.
>>
>> Previous discussion with some ARM folks has led me to believe there isn't a
>> guarantee that the Context ID Register will always have a PID. Why not allow
>> filtering on thread group ID, session ID, cgroup related identifiers, etc.?
> 
> Coresight tracers only support contextID tracing.  The HW
> automatically does the match between the contextID comparator register
> in the tracer with the contextID register of the core.  Tracing is
> enabled if both values match (and the tracer is configured to do so).

Is there a reason to only ever allow Process IDs to be written into the
Coresight and CPU Context ID registers? Is there anything in the hardware that
would prevent writing, for example, Thread Group IDs into the Coresight and
CPU Context ID registers? If there's no hardware limitation, why should there
be kernel or device tree architecture that states or implies that patches to
support such a use case are unacceptable?

Thanks,
Christopher Covington

-- 
Qualcomm Innovation Center, Inc.
The Qualcomm Innovation Center, Inc. is a member of the Code Aurora Forum,
a Linux Foundation Collaborative Project


From anurag.kumar.vulisha at xilinx.com  Thu Aug 27 08:49:18 2015
From: anurag.kumar.vulisha at xilinx.com (Anurag Kumar Vulisha)
Date: Thu, 27 Aug 2015 21:19:18 +0530
Subject: [PATCH v2] dmaengine: vdma: Add 64 bit addressing support to the
 driver
Message-ID: <1440690558-39822-1-git-send-email-anuragku@xilinx.com>

This VDMA  is a soft ip, which can be programmed to support
32 bit addressing or greater than 32 bit addressing.

When the VDMA ip is configured for 32 bit address space the
transfer start address is specified by a single register.

When the  VDMA core is configured for an address space greater
than 32 then each start address is specified by a combination
of two registers. The first register specifies the LSB 32 bits
of address, while the next register specifies the MSB 32 bits
of address.For example,5Ch will specify the LSB 32 bits while
60h will specify the MSB 32 bits of the first start address.So
we need to program two registers at a time.

This patch adds the 64 bit addressing support to the vdma driver.

Signed-off-by: Anurag Kumar Vulisha <anuragku at xilinx.com>
---
  Changes in v2:
  1. Added dma-ranges property in device tree as suggested by Arnd Bergmann.
  2. Added device tree property(xlnx,addrwidth) for an identification of whether
     the IP block itself is configured in 64-bit or 32-bit mode as suggested by
     Laurent Pinchart.
  3. Modified the driver code based on the xlnx,addrwidth.
---
 .../devicetree/bindings/dma/xilinx/xilinx_vdma.txt |    4 +
 drivers/dma/Kconfig                                |    2 +-
 drivers/dma/xilinx/xilinx_vdma.c                   |   81 +++++++++++++++++---
 3 files changed, 76 insertions(+), 11 deletions(-)

diff --git a/Documentation/devicetree/bindings/dma/xilinx/xilinx_vdma.txt b/Documentation/devicetree/bindings/dma/xilinx/xilinx_vdma.txt
index e4c4d47..434d380 100644
--- a/Documentation/devicetree/bindings/dma/xilinx/xilinx_vdma.txt
+++ b/Documentation/devicetree/bindings/dma/xilinx/xilinx_vdma.txt
@@ -8,6 +8,8 @@ Required properties:
 - #dma-cells: Should be <1>, see "dmas" property below
 - reg: Should contain VDMA registers location and length.
 - xlnx,num-fstores: Should be the number of framebuffers as configured in h/w.
+- xlnx,addrwidth: Should be the vdma addressing size in bits(ex: 32 bits).
+- dma-ranges: Should be as the following <dma_addr cpu_addr max_len>
 - dma-channel child node: Should have at least one channel and can have up to
 	two channels per device. This node specifies the properties of each
 	DMA channel (see child node properties below).
@@ -41,8 +43,10 @@ axi_vdma_0: axivdma at 40030000 {
 	compatible = "xlnx,axi-vdma-1.00.a";
 	#dma_cells = <1>;
 	reg = < 0x40030000 0x10000 >;
+	dma-ranges = <0x00000000 0x00000000 0x40000000>;
 	xlnx,num-fstores = <0x8>;
 	xlnx,flush-fsync = <0x1>;
+	xlnx,addrwidth = <0x20>;
 	dma-channel at 40030000 {
 		compatible = "xlnx,axi-vdma-mm2s-channel";
 		interrupts = < 0 54 4 >;
diff --git a/drivers/dma/Kconfig b/drivers/dma/Kconfig
index bda2cb0..a7cd0a8 100644
--- a/drivers/dma/Kconfig
+++ b/drivers/dma/Kconfig
@@ -398,7 +398,7 @@ config FSL_EDMA
 
 config XILINX_VDMA
 	tristate "Xilinx AXI VDMA Engine"
-	depends on (ARCH_ZYNQ || MICROBLAZE)
+	depends on (ARCH_ZYNQ || MICROBLAZE || ARM64)
 	select DMA_ENGINE
 	help
 	  Enable support for Xilinx AXI VDMA Soft IP.
diff --git a/drivers/dma/xilinx/xilinx_vdma.c b/drivers/dma/xilinx/xilinx_vdma.c
index d8434d4..d4eebc9 100644
--- a/drivers/dma/xilinx/xilinx_vdma.c
+++ b/drivers/dma/xilinx/xilinx_vdma.c
@@ -98,6 +98,8 @@
 #define XILINX_VDMA_FRMDLY_STRIDE_FRMDLY_SHIFT	24
 #define XILINX_VDMA_FRMDLY_STRIDE_STRIDE_SHIFT	0
 
+#define XILINX_VDMA_REG_START_ADDRESS_64(n)	(0x000c + 8 * (n))
+
 #define XILINX_VDMA_REG_START_ADDRESS(n)	(0x000c + 4 * (n))
 
 /* HW specific definitions */
@@ -143,16 +145,18 @@
  * @next_desc: Next Descriptor Pointer @0x00
  * @pad1: Reserved @0x04
  * @buf_addr: Buffer address @0x08
- * @pad2: Reserved @0x0C
- * @vsize: Vertical Size @0x10
- * @hsize: Horizontal Size @0x14
+ * @buf_addr_msb: Buffer msb address @0x0c
+ * @pad2: Reserved @0x10
+ * @vsize: Vertical Size @0x14
+ * @hsize: Horizontal Size @0x18
  * @stride: Number of bytes between the first
- *	    pixels of each horizontal line @0x18
+ *	    pixels of each horizontal line @0x1C
  */
 struct xilinx_vdma_desc_hw {
 	u32 next_desc;
 	u32 pad1;
 	u32 buf_addr;
+	u32 buf_addr_msb;
 	u32 pad2;
 	u32 vsize;
 	u32 hsize;
@@ -206,6 +210,7 @@ struct xilinx_vdma_tx_descriptor {
  * @tasklet: Cleanup work after irq
  * @config: Device configuration info
  * @flush_on_fsync: Flush on Frame sync
+ * @ext_addr: Indicates 64 bit addressing is supported by dma channel
  */
 struct xilinx_vdma_chan {
 	struct xilinx_vdma_device *xdev;
@@ -229,6 +234,7 @@ struct xilinx_vdma_chan {
 	struct tasklet_struct tasklet;
 	struct xilinx_vdma_config config;
 	bool flush_on_fsync;
+	bool ext_addr;
 };
 
 /**
@@ -239,6 +245,7 @@ struct xilinx_vdma_chan {
  * @chan: Driver specific VDMA channel
  * @has_sg: Specifies whether Scatter-Gather is present or not
  * @flush_on_fsync: Flush on frame sync
+ * @ext_addr: Indicates 64 bit addressing is supported by dma device
  */
 struct xilinx_vdma_device {
 	void __iomem *regs;
@@ -247,6 +254,7 @@ struct xilinx_vdma_device {
 	struct xilinx_vdma_chan *chan[XILINX_VDMA_MAX_CHANS_PER_DEVICE];
 	bool has_sg;
 	u32 flush_on_fsync;
+	bool ext_addr;
 };
 
 /* Macros */
@@ -272,6 +280,22 @@ static inline void vdma_desc_write(struct xilinx_vdma_chan *chan, u32 reg,
 	vdma_write(chan, chan->desc_offset + reg, value);
 }
 
+
+/* Since vdma driver is trying to write to a register offset which is not a
+ * multiple of 64 bits(ex : 0x5c), we are writing as two separate 32 bits
+ * instead of a single 64 bit register write.
+ */
+
+static inline void vdma_desc_write_64(struct xilinx_vdma_chan *chan, u32 reg,
+				 u32 value_lsb, u32 value_msb)
+{
+	/* Write the lsb 32 bits*/
+	writel(value_lsb, chan->xdev->regs + chan->desc_offset + reg);
+
+	/* Write the msb 32 bits */
+	writel(value_msb, chan->xdev->regs + chan->desc_offset + reg + 4);
+}
+
 static inline u32 vdma_ctrl_read(struct xilinx_vdma_chan *chan, u32 reg)
 {
 	return vdma_read(chan, chan->ctrl_offset + reg);
@@ -700,9 +724,17 @@ static void xilinx_vdma_start_transfer(struct xilinx_vdma_chan *chan)
 		int i = 0;
 
 		list_for_each_entry(segment, &desc->segments, node) {
-			vdma_desc_write(chan,
+			if (chan->ext_addr == true) {
+				/* vdma supports 64 bit addressing */
+				vdma_desc_write_64(chan,
+					XILINX_VDMA_REG_START_ADDRESS_64(i++),
+					segment->hw.buf_addr,
+					segment->hw.buf_addr_msb);
+			} else {
+				vdma_desc_write(chan,
 					XILINX_VDMA_REG_START_ADDRESS(i++),
 					segment->hw.buf_addr);
+			}
 			last = segment;
 		}
 
@@ -968,10 +1000,21 @@ xilinx_vdma_dma_prep_interleaved(struct dma_chan *dchan,
 	hw->stride |= chan->config.frm_dly <<
 			XILINX_VDMA_FRMDLY_STRIDE_FRMDLY_SHIFT;
 
-	if (xt->dir != DMA_MEM_TO_DEV)
-		hw->buf_addr = xt->dst_start;
-	else
-		hw->buf_addr = xt->src_start;
+	if (xt->dir != DMA_MEM_TO_DEV) {
+		if (chan->ext_addr == true) {
+			hw->buf_addr = lower_32_bits(xt->dst_start);
+			hw->buf_addr_msb = upper_32_bits(xt->dst_start);
+		} else {
+			hw->buf_addr = xt->dst_start;
+		}
+	} else {
+		if (chan->ext_addr == true) {
+			hw->buf_addr = lower_32_bits(xt->src_start);
+			hw->buf_addr_msb = upper_32_bits(xt->src_start);
+		} else {
+			hw->buf_addr = xt->src_start;
+		}
+	}
 
 	/* Link the previous next descriptor to current */
 	if (!list_empty(&desc->segments)) {
@@ -1124,6 +1167,7 @@ static int xilinx_vdma_chan_probe(struct xilinx_vdma_device *xdev,
 	if (!chan)
 		return -ENOMEM;
 
+	chan->ext_addr = xdev->ext_addr;
 	chan->dev = xdev->dev;
 	chan->xdev = xdev;
 	chan->has_sg = xdev->has_sg;
@@ -1240,7 +1284,7 @@ static int xilinx_vdma_probe(struct platform_device *pdev)
 	struct xilinx_vdma_device *xdev;
 	struct device_node *child;
 	struct resource *io;
-	u32 num_frames;
+	u32 num_frames, addr_width;
 	int i, err;
 
 	/* Allocate and initialize the DMA engine structure */
@@ -1270,6 +1314,23 @@ static int xilinx_vdma_probe(struct platform_device *pdev)
 	if (err < 0)
 		dev_warn(xdev->dev, "missing xlnx,flush-fsync property\n");
 
+	err = of_property_read_u32(node, "xlnx,addrwidth", &addr_width);
+
+	if (err < 0) {
+		/* Setting addr_width property to default 32 bits */
+		addr_width = 32;
+	}
+
+	if (addr_width > 32) {
+		/* VDMA device supports greater than 32 bit addressing*/
+		xdev->ext_addr = true;
+	} else {
+		xdev->ext_addr = false;
+	}
+
+	/* Set the dma mask bits */
+	dma_set_mask(xdev->dev, DMA_BIT_MASK(addr_width));
+
 	/* Initialize the DMA engine */
 	xdev->common.dev = &pdev->dev;
 
-- 
1.7.4



From m-karicheri2 at ti.com  Thu Aug 27 08:51:11 2015
From: m-karicheri2 at ti.com (Murali Karicheri)
Date: Thu, 27 Aug 2015 11:51:11 -0400
Subject: [PATCH] soc: ti: reset irq affinity before freeing irq
Message-ID: <1440690671-1029-1-git-send-email-m-karicheri2@ti.com>

When using accumulator queue for rx side for network driver, following
warning is seen when doing a reboot command from Linux console. This
is because, affinity value is not reset before calling free_irq(). This
patch fixes this.

Deconfiguring network interfaces...
[   55.176589] ------------[ cut here ]-----------
[   55.181232] WARNING: CPU: 0 PID: 2081 at kernel/irq/manage.c:1370
__free_irq+0x208/0x214

Signed-off-by: Murali Karicheri <m-karicheri2 at ti.com>
---
 - Applies to v4.2.0-rc8

 drivers/soc/ti/knav_qmss_acc.c | 4 ++++
 1 file changed, 4 insertions(+)

diff --git a/drivers/soc/ti/knav_qmss_acc.c b/drivers/soc/ti/knav_qmss_acc.c
index ef6f69d..b98fe56 100644
--- a/drivers/soc/ti/knav_qmss_acc.c
+++ b/drivers/soc/ti/knav_qmss_acc.c
@@ -261,6 +261,10 @@ static int knav_range_setup_acc_irq(struct knav_range_info *range,
 	if (old && !new) {
 		dev_dbg(kdev->dev, "setup-acc-irq: freeing %s for channel %s\n",
 			acc->name, acc->name);
+		ret = irq_set_affinity_hint(irq, NULL);
+		if (ret)
+			dev_warn(range->kdev->dev,
+				 "Failed to set IRQ affinity\n");
 		free_irq(irq, range);
 	}
 
-- 
1.9.1



From boris.brezillon at free-electrons.com  Thu Aug 27 08:51:51 2015
From: boris.brezillon at free-electrons.com (Boris Brezillon)
Date: Thu, 27 Aug 2015 17:51:51 +0200
Subject: [PATCH 03/10] ARM: marvell/dt: add crypto related nodes to
 armada 370 dtsi
In-Reply-To: <877fog69a7.fsf@free-electrons.com>
References: <1439885341-14644-1-git-send-email-boris.brezillon@free-electrons.com>
 <1439885341-14644-4-git-send-email-boris.brezillon@free-electrons.com>
 <877fog69a7.fsf@free-electrons.com>
Message-ID: <20150827175151.23994256@bbrezillon>

Hi Gregory,

On Thu, 27 Aug 2015 17:28:00 +0200
Gregory CLEMENT <gregory.clement at free-electrons.com> wrote:

> Hi Boris and Arnaud,
> 
> Boris Brezillon <boris.brezillon at free-electrons.com> writes:
> 
> > From: Arnaud Ebalard <arno at natisbad.org>
> >
> > Add crypto related nodes in armada-370.dtsi.
> [...]
> > +
> > +			crypto at 90000 {
> > +				compatible = "marvell,armada-370-crypto";
> > +				reg = <0x90000 0x10000>;
> > +				reg-names = "regs";
> > +				interrupts = <48>;
> > +				clocks = <&gateclk 23>;
> > +				clock-names = "cesa0";
> > +				marvell,crypto-srams = <&crypto_sram>;
> > +				marvell,crypto-sram-size = <0x7e0>;
> > +			};
> > +		};
> > +
> > +		crypto_sram: sa-sram {
> > +			compatible = "mmio-sram";
> > +			reg = <MBUS_ID(0x09, 0x01) 0 0x800>;
> > +			reg-names = "sram";
> > +			clocks = <&gateclk 23>;
> > +			#address-cells = <1>;
> > +			#size-cells = <1>;
> > +			ranges = <0 MBUS_ID(0x09, 0x01) 0 0x800>;
> > +
> > +			idle-sram at 0 {
> > +				reg = <0x0 0x20>;
> > +			};
> 
> So you think at the cpuilde hack using the sram. And you reserved 32
> bytes for it. So indeed it is enough to store the code we need. Could
> you add a little comment about it ?

Sure, I'll add a comment explaining why we reserve a memory region for
idle support.

> 
> In mvebu_setup_boot_addr_wa we use mvebu_mbus_add_window_by_id but this
> windows was also added by the code you add. I wonder if it could be a
> problem.

I tested it and it works: apparently you can create different MBUS
windows pointing to the same peripheral (in our case the SRAM).

> 
> Maybe we should look for if the idle-sram is present and in this case
> not calling mvebu_mbus_add_window_by_id, but it is not necessary for
> this series.

Hm, I considered reworking the code dealing with this erratum, but
since everything works as is I don't think this is necessary.

Best Regards,

Boris

-- 
Boris Brezillon, Free Electrons
Embedded Linux and Kernel engineering
http://free-electrons.com


From mathieu.poirier at linaro.org  Thu Aug 27 08:54:07 2015
From: mathieu.poirier at linaro.org (Mathieu Poirier)
Date: Thu, 27 Aug 2015 09:54:07 -0600
Subject: [PATCH 2/5] coresight-etm4x: Change the name of the ctxid_val to
 ctxid_pid
In-Reply-To: <55DF2DB5.7000909@codeaurora.org>
References: <1436258518-9339-1-git-send-email-zhang.chunyan@linaro.org>
 <1436258518-9339-3-git-send-email-zhang.chunyan@linaro.org>
 <55DDFE01.50201@codeaurora.org>
 <CANLsYkyA_C=PUDEUSbcA_Sa6Abqnxk1TP9ye6F9i0bWW_OxqiA@mail.gmail.com>
 <55DF2DB5.7000909@codeaurora.org>
Message-ID: <CANLsYkyfJX1CywxZ-e8TgK45XXs9jxkBDrp41OWAzTjC63Ggww@mail.gmail.com>

On 27 August 2015 at 09:33, Christopher Covington <cov at codeaurora.org> wrote:
> On 08/27/2015 11:12 AM, Mathieu Poirier wrote:
>> On 26 August 2015 at 11:57, Christopher Covington <cov at codeaurora.org> wrote:
>>> On 07/07/2015 04:41 AM, Chunyan Zhang wrote:
>>>> 'ctxid_val' array was used to store the value of ETM context ID comparator
>>>> which actually stores the process ID to be traced, so using 'ctxid_pid' as
>>>> its name instead make it easier to understand.
>>>
>>> Previous discussion with some ARM folks has led me to believe there isn't a
>>> guarantee that the Context ID Register will always have a PID. Why not allow
>>> filtering on thread group ID, session ID, cgroup related identifiers, etc.?
>>
>> Coresight tracers only support contextID tracing.  The HW
>> automatically does the match between the contextID comparator register
>> in the tracer with the contextID register of the core.  Tracing is
>> enabled if both values match (and the tracer is configured to do so).
>
> Is there a reason to only ever allow Process IDs to be written into the
> Coresight and CPU Context ID registers? Is there anything in the hardware that
> would prevent writing, for example, Thread Group IDs into the Coresight and
> CPU Context ID registers? If there's no hardware limitation, why should there
> be kernel or device tree architecture that states or implies that patches to
> support such a use case are unacceptable?

I'm not saying your idea is unacceptable - I actually think there is
value in it.  At this time the scheduler will automatically write the
PID to the contextID register when a task is running, a reality this
feature is exploiting.

There is no limitation as to what can be written to the coresight
contextID register - tracing will start for as long as the values and
mask are configured properly.  I do not know the limitation imposed on
the core's contextID register (if any). We'd also have to make sure
that all the code, everywhere, relying on that information has been
modified to take into account the new semantic.

>
> Thanks,
> Christopher Covington
>
> --
> Qualcomm Innovation Center, Inc.
> The Qualcomm Innovation Center, Inc. is a member of the Code Aurora Forum,
> a Linux Foundation Collaborative Project


From daniel.thompson at linaro.org  Thu Aug 27 08:54:49 2015
From: daniel.thompson at linaro.org (Daniel Thompson)
Date: Thu, 27 Aug 2015 16:54:49 +0100
Subject: [PATCH v1 3/3] arm64: dts: add Hi6220 mailbox node
In-Reply-To: <1440552341.10987.53.camel@linaro.org>
References: <20150821184059.GB2000@svinekod>
 <20150824091845.GA28290@leoy-linaro> <20150824095144.GA7139@leverpostej>
 <1440411596.3517.12.camel@linaro.org>
 <20150824114903.GT10728@bivouac.eciton.net>
 <1440490427.10987.29.camel@linaro.org>
 <20150825094630.GU10728@bivouac.eciton.net>
 <1440497710.10987.42.camel@linaro.org> <20150825104256.GB13471@leverpostej>
 <1440510194.10987.52.camel@linaro.org> <20150825160030.GA3774@leoy-linaro>
 <1440552341.10987.53.camel@linaro.org>
Message-ID: <55DF32C9.8040302@linaro.org>

On 26/08/15 02:25, Haojian Zhuang wrote:
>> Option 1:
>>
>> 	memory at 0 {
>> 		device_type = "memory";
>> 		reg = <0x00000000 0x00000000 0x00000000 0x05e00000>,
>> 		      <0x00000000 0x05f00000 0x00000000 0x00eff000>,
>> 		      <0x00000000 0x06e00000 0x00000000 0x0060f000>,
>> 		      <0x00000000 0x07410000 0x00000000 0x38bf0000>;
>> 	};
>>
>> [snip]
 >>
>> Option 2:
>>
>> 	memory at 0 {
>> 		device_type = "memory";
>> 		reg = <0x0 0x0 0x0 0x40000000>;
>> 	};
>>
 >> [snip]
 >>
>
> I prefer the second one. From my view, memory node should only describe
> the hardware information of memory.

Haven't we already established that, to avoid the risk of UEFI 
applications accessing inappropriate memory locations, a (correct) UEFI 
implementation must use, and pass to the kernel, a memory map that looks 
like option 1?

That being the case why would we want u-boot (or any other similar 
bootloader) to pass a memory map that is gratuitously different to the 
one supplied by UEFI?


Daniel.


From robh at kernel.org  Thu Aug 27 08:56:34 2015
From: robh at kernel.org (Rob Herring)
Date: Thu, 27 Aug 2015 10:56:34 -0500
Subject: [RFC PATCH] arm/arm64: build all dtbs for CONPILE_TEST
Message-ID: <1440690994-5978-1-git-send-email-robh@kernel.org>

Enable building all dtb files when COMPILE_TEST is enabled. The dtbs are
not really dependent on a platform being enabled or any other kernel
config, so for testing coverage it is convenient to build all of the
dtbs.

This builds all dts files in the tree, not just targets listed. This
is simpler for arm64 which has a bunch of sub-dirs.

Signed-off-by: Rob Herring <robh at kernel.org>
Cc: Russell King <linux at arm.linux.org.uk>
Cc: Catalin Marinas <catalin.marinas at arm.com>
Cc: Will Deacon <will.deacon at arm.com>
---
I've had this on my todo list for a while. RFC for now as I want to do 
the rest of the arches as well. I was originally thinking a new target 
for this, but thanks to Olof for the COMPILE_TEST suggestion. 

Rob

 arch/arm/boot/dts/Makefile   | 4 ++++
 arch/arm64/boot/dts/Makefile | 6 ++++++
 2 files changed, 10 insertions(+)

diff --git a/arch/arm/boot/dts/Makefile b/arch/arm/boot/dts/Makefile
index 246473a..4968442a 100644
--- a/arch/arm/boot/dts/Makefile
+++ b/arch/arm/boot/dts/Makefile
@@ -712,5 +712,9 @@ dtb-$(CONFIG_ARCH_MEDIATEK) += \
 dtb-$(CONFIG_ARCH_ZX) += zx296702-ad1.dtb
 endif
 
+dtstree		:= $(srctree)/$(src)
+
+dtb-$(CONFIG_COMPILE_TEST) := $(patsubst $(dtstree)/%.dts,%.dtb, $(wildcard $(dtstree)/*.dts))
+
 always		:= $(dtb-y)
 clean-files	:= *.dtb
diff --git a/arch/arm64/boot/dts/Makefile b/arch/arm64/boot/dts/Makefile
index 38913be..9f19390 100644
--- a/arch/arm64/boot/dts/Makefile
+++ b/arch/arm64/boot/dts/Makefile
@@ -11,3 +11,9 @@ dts-dirs += sprd
 dts-dirs += xilinx
 
 subdir-y	:= $(dts-dirs)
+
+dtstree		:= $(srctree)/$(src)
+
+dtb-$(CONFIG_COMPILE_TEST) := $(patsubst $(dtstree)/%.dts,%.dtb, $(foreach d,$(dts-dirs), $(wildcard $(dtstree)/$(d)/*.dts)))
+
+always		:= $(dtb-y)
-- 
2.1.4



From olof at lixom.net  Thu Aug 27 09:08:08 2015
From: olof at lixom.net (Olof Johansson)
Date: Thu, 27 Aug 2015 09:08:08 -0700
Subject: [RFC PATCH] arm/arm64: build all dtbs for CONPILE_TEST
In-Reply-To: <1440690994-5978-1-git-send-email-robh@kernel.org>
References: <1440690994-5978-1-git-send-email-robh@kernel.org>
Message-ID: <CAOesGMjzBaobpLsS77UziWeYO9wo21SkdpWT=Pib6AM7DDKTnA@mail.gmail.com>

On Thu, Aug 27, 2015 at 8:56 AM, Rob Herring <robh at kernel.org> wrote:
> Enable building all dtb files when COMPILE_TEST is enabled. The dtbs are
> not really dependent on a platform being enabled or any other kernel
> config, so for testing coverage it is convenient to build all of the
> dtbs.
>
> This builds all dts files in the tree, not just targets listed. This
> is simpler for arm64 which has a bunch of sub-dirs.
>
> Signed-off-by: Rob Herring <robh at kernel.org>
> Cc: Russell King <linux at arm.linux.org.uk>
> Cc: Catalin Marinas <catalin.marinas at arm.com>
> Cc: Will Deacon <will.deacon at arm.com>
> ---
> I've had this on my todo list for a while. RFC for now as I want to do
> the rest of the arches as well. I was originally thinking a new target
> for this, but thanks to Olof for the COMPILE_TEST suggestion.
>
> Rob
>
>  arch/arm/boot/dts/Makefile   | 4 ++++
>  arch/arm64/boot/dts/Makefile | 6 ++++++
>  2 files changed, 10 insertions(+)
>
> diff --git a/arch/arm/boot/dts/Makefile b/arch/arm/boot/dts/Makefile
> index 246473a..4968442a 100644
> --- a/arch/arm/boot/dts/Makefile
> +++ b/arch/arm/boot/dts/Makefile
> @@ -712,5 +712,9 @@ dtb-$(CONFIG_ARCH_MEDIATEK) += \
>  dtb-$(CONFIG_ARCH_ZX) += zx296702-ad1.dtb
>  endif
>
> +dtstree                := $(srctree)/$(src)
> +
> +dtb-$(CONFIG_COMPILE_TEST) := $(patsubst $(dtstree)/%.dts,%.dtb, $(wildcard $(dtstree)/*.dts))
> +
>  always         := $(dtb-y)
>  clean-files    := *.dtb
> diff --git a/arch/arm64/boot/dts/Makefile b/arch/arm64/boot/dts/Makefile
> index 38913be..9f19390 100644
> --- a/arch/arm64/boot/dts/Makefile
> +++ b/arch/arm64/boot/dts/Makefile
> @@ -11,3 +11,9 @@ dts-dirs += sprd
>  dts-dirs += xilinx
>
>  subdir-y       := $(dts-dirs)
> +
> +dtstree                := $(srctree)/$(src)
> +
> +dtb-$(CONFIG_COMPILE_TEST) := $(patsubst $(dtstree)/%.dts,%.dtb, $(foreach d,$(dts-dirs), $(wildcard $(dtstree)/$(d)/*.dts)))

I think it would be more appropriate to build dtb-n  here instead of
_any_ file ending in dts.

It would be useful to build all files, but it's not the behavior that
COMPILE_TEST usually has.


-Olof


From daniel.thompson at linaro.org  Thu Aug 27 09:17:11 2015
From: daniel.thompson at linaro.org (Daniel Thompson)
Date: Thu, 27 Aug 2015 17:17:11 +0100
Subject: [PATCH] arm: Handle starting up in secure mode
In-Reply-To: <1440424572-27116-1-git-send-email-cov@codeaurora.org>
References: <1440424572-27116-1-git-send-email-cov@codeaurora.org>
Message-ID: <55DF3807.40506@linaro.org>

On 24/08/15 14:55, Christopher Covington wrote:
> ARM Linux appears to have never been made aware of the ARMv7 security
> extensions. When CONFIG_ARM_SEC_EXT=y, have it probe for its security
> state by checking whether CNTFRQ is writeable and potentially make
> mode changes based on the information. The most features are available
> from hypervisor (HYP) mode, so switch to it possible. Failing that,
> prefer non-secure supervisor (SVC) mode to secure supervisor mode.

If there is no hypervisor mode available what benefit do we get from 
transitioning to non-secure mode?

When running in secure mode we retain access to some potentially useful 
features such as having access to FIQ.


Daniel.



From mark.rutland at arm.com  Thu Aug 27 09:31:09 2015
From: mark.rutland at arm.com (Mark Rutland)
Date: Thu, 27 Aug 2015 17:31:09 +0100
Subject: [PATCH v1 3/3] arm64: dts: add Hi6220 mailbox node
In-Reply-To: <20150826065950.GB19594@leoy-linaro>
References: <1440411596.3517.12.camel@linaro.org>
 <20150824114903.GT10728@bivouac.eciton.net>
 <1440490427.10987.29.camel@linaro.org>
 <20150825094630.GU10728@bivouac.eciton.net>
 <1440497710.10987.42.camel@linaro.org>
 <20150825104256.GB13471@leverpostej>
 <1440510194.10987.52.camel@linaro.org>
 <20150825160030.GA3774@leoy-linaro>
 <1440552341.10987.53.camel@linaro.org>
 <20150826065950.GB19594@leoy-linaro>
Message-ID: <20150827163108.GA31748@leverpostej>

On Wed, Aug 26, 2015 at 07:59:50AM +0100, Leo Yan wrote:
> Hi Haojian,
> 
> On Wed, Aug 26, 2015 at 09:25:41AM +0800, Haojian Zhuang wrote:
> > On Wed, 2015-08-26 at 00:00 +0800, Leo Yan wrote:
> > > On Tue, Aug 25, 2015 at 09:43:14PM +0800, Haojian Zhuang wrote:
> > > > On Tue, 2015-08-25 at 11:42 +0100, Mark Rutland wrote:
> > > > > > > Are you then going to hack GRUB, release a special HiKey version of
> > > > > > > GRUB, not support any other versions, and still can your firmware
> > > > > > > UEFI?
> > > > > > 
> > > > > > I don't need to hack GRUB at all.
> > > > > 
> > > > > Then it is working for you by pure chance alone.
> > > > > 
> > > > > Please listen to the advice you are being given here; we're trying to
> > > > > ensure that your platform functions (and continues to function) as best
> > > > > it can.
> > > > 
> > > > Since we discussed a lot on this, let's make a conclusion on it.
> > > > 
> > > > 1. UEFI could append the reserved buffer in it's memory mapping.
> > > > 2. These reserved buffer must be declared in DT, since we also need to
> > > >    support non-UEFI (uboot) at the same time.
> > > > 3. Mailbox node should reference reserved buffer by phandle in DT. Then
> > > >    map the buffer as non-cacheable in driver.
> > > > 4. These reserved buffer must use "no-map" property since it should be
> > > >    non-cacheable in driver.
> > > 
> > > For more specific discussion for DTS, i list two options at here;
> > > 
> > > - Option 1: just simply reserve memory regions through memory node,
> > >   and mailbox node will directly use the buffer through reg ranges;
> > > 
> > > - Option 2: use reserved-memory and mailbox node will refer phandle
> > >   of reserved-memory;
> > > 
> > > These two options both can work well with UEFI and Uboot, but option 1
> > > is more simple and straightforward; so i personally prefer it. But
> > > look forwarding your guys' suggestion.
> > > 
> > > Option 1:
> > > 
> > > 	memory at 0 {
> > > 		device_type = "memory";
> > > 		reg = <0x00000000 0x00000000 0x00000000 0x05e00000>,
> > > 		      <0x00000000 0x05f00000 0x00000000 0x00eff000>,
> > > 		      <0x00000000 0x06e00000 0x00000000 0x0060f000>,
> > > 		      <0x00000000 0x07410000 0x00000000 0x38bf0000>;
> > > 	};
> > > 
> > >         [...]
> > > 
> > > 	mailbox: mailbox at f7510000 {
> > > 		#mbox-cells = <1>;
> > > 		compatible = "hisilicon,hi6220-mbox";
> > > 		reg = <0x0 0xf7510000 0x0 0x1000>, /* IPC_S */
> > > 		      <0x0 0x06dff800 0x0 0x0800>; /* Mailbox buffer */
> > > 		interrupts = <GIC_SPI 94 IRQ_TYPE_LEVEL_HIGH>;
> > > 	};
> > > 
> > > Option 2:
> > > 
> > > 	memory at 0 {
> > > 		device_type = "memory";
> > > 		reg = <0x0 0x0 0x0 0x40000000>;
> > > 	};
> > > 
> > > 	reserved-memory {
> > > 		#address-cells = <2>;
> > > 		#size-cells = <2>;
> > > 		ranges;
> > > 
> > > 		mcu_reserved: mcu_reserved at 06dff000 {
> > > 			no-map;
> > > 			reg = <0x0 0x06dff000 0x0 0x00001000>,	/* MCU mailbox buffer */
> > > 			      <0x0 0x05e00000 0x0 0x00100000>,	/* MCU firmware buffer */
> > > 			      <0x0 0x0740f000 0x0 0x00001000>;	/* MCU firmware section */
> > > 		};
> > > 	};
> > > 
> > >         [...]
> > > 
> > > 	mailbox: mailbox at f7510000 {
> > > 		#mbox-cells = <1>;
> > > 		compatible = "hisilicon,hi6220-mbox";
> > > 		reg = <0x0 0xf7510000 0x0 0x1000>; /* IPC_S */
> > > 		memory-region = <&mcu_reserved>;   /* Mailbox buffer */
> > > 		interrupts = <GIC_SPI 94 IRQ_TYPE_LEVEL_HIGH>;
> > > 	};
> > 
> > I prefer the second one. From my view, memory node should only describe
> > the hardware information of memory.
> 
> Yes, option 2 will be more simple for memory node.
> 
> But option 2 also will introduce complexity for mailbox node, due mailbox
> driver need use property "reg" and "memory-region" to sepeately depict
> the regions for mailbox's ipc and slots. If later mailbox is designed to
> use SRAM for both ipc and slots, then it will no matter with DDR anymore,
> in this case option 1 will easily switch to support it.
> 
> Another question is a general question: for Linux kernel, which is the
> best method to reserve memory regions? According to previous discussion,
> we can use /memory/ node or /reseved-memory/ node to reserve memory
> regions.

If the memory is truly reserved for a purpose and cannot be used for
anything else, I don't think it should be in the memory node at all, and
should be carved out. That aligns with what you'd do in UEFI (either not
listing the region in the memory map, or listing it with attributes such
that it may not be mapped and/or used).

I don't see much of a reason for /memreserve/, as it can cause issues
(by allowing the OS to map the region with cacheable attributes), and is
not as rigorously specified for ARM as it is for Power in ePAPR.

I understand that reserved-memory is for carving out (potentially
reusable) memory pools for devices or other special uses (perhaps a
panic log). Usually such memory may also be used by the kernel for its
own purposes if not presently required by the device.

Having an entry in reserved-memory does not necessitate the region also
appears in memory nodes, and if a region cannot be used by an OS (or
other software) for other purposes, I would not expect it to be describe
in any memory node. That will prevent other software (e.g. bootloaders)
from erroneously using the memory.

If you have a region described with no-map, I would expect that this
doesn't exist in any memory node or the UEFI memory map, and is only
under reserved-memory so it may be referred to by phandle in a
consistent manner.

> when review Juno's dts, i also see there have reserved 16MB DDR for secure
> world. If so, looks like /reserved-memory/ node is unnecessary. if have some
> specific scenarios will we use reserved-memory node to help reserve memory
> regions?

I'd expect shared DMA pools to appear in reserved-memory. The OS can
choose to use these or ignore them if it chooses (or is otherwise forced
to, e.g. were it loaded over one).

Thanks,
Mark.


From agross at codeaurora.org  Thu Aug 27 09:32:00 2015
From: agross at codeaurora.org (Andy Gross)
Date: Thu, 27 Aug 2015 11:32:00 -0500
Subject: [PATCH v2] soc: qcom: smd: Use correct remote processor ID
In-Reply-To: <55DF2C35.4030207@mm-sol.com>
References: <1440618165-9410-1-git-send-email-agross@codeaurora.org>
 <55DF2C35.4030207@mm-sol.com>
Message-ID: <20150827163200.GB13642@qualcomm.com>

On Thu, Aug 27, 2015 at 06:26:45PM +0300, Stanimir Varbanov wrote:
> On 08/26/2015 10:42 PM, Andy Gross wrote:
> > This patch fixes SMEM addressing issues when remote processors need to use
> > secure SMEM partitions.
> > 
> > Signed-off-by: Andy Gross <agross at codeaurora.org>
> > ---
> >  .../devicetree/bindings/soc/qcom/qcom,smd.txt      |    6 ++++++
> >  drivers/soc/qcom/smd.c                             |   15 +++++++++++----
> >  2 files changed, 17 insertions(+), 4 deletions(-)
> > 
> > diff --git a/Documentation/devicetree/bindings/soc/qcom/qcom,smd.txt b/Documentation/devicetree/bindings/soc/qcom/qcom,smd.txt
> > index f65c76d..97d9b3e 100644
> > --- a/Documentation/devicetree/bindings/soc/qcom/qcom,smd.txt
> > +++ b/Documentation/devicetree/bindings/soc/qcom/qcom,smd.txt
> > @@ -37,6 +37,12 @@ The edge is described by the following properties:
> >  	Definition: the identifier of the remote processor in the smd channel
> >  		    allocation table
> >  
> > +- qcom,remote-pid:
> > +	Usage: optional
> > +	Value type: <u32>
> > +	Definition: the identifier for the remote processor as known by the rest
> > +		    of the system.
> > +
> >  = SMD DEVICES
> >  
> >  In turn, subnodes of the "edges" represent devices tied to SMD channels on that
> > diff --git a/drivers/soc/qcom/smd.c b/drivers/soc/qcom/smd.c
> > index 327adcf..5706a81 100644
> > --- a/drivers/soc/qcom/smd.c
> > +++ b/drivers/soc/qcom/smd.c
> > @@ -111,6 +111,7 @@ struct qcom_smd_edge {
> >  	struct qcom_smd *smd;
> >  	struct device_node *of_node;
> >  	unsigned edge_id;
> > +	unsigned remote_pid;
> 
> Andy, you forgot to add this new field in structure description header.

Good catch.  Thanks!

-- 
Qualcomm Innovation Center, Inc.
The Qualcomm Innovation Center, Inc. is a member of the Code Aurora Forum,
a Linux Foundation Collaborative Project



From computersforpeace at gmail.com  Thu Aug 27 09:34:21 2015
From: computersforpeace at gmail.com (Brian Norris)
Date: Thu, 27 Aug 2015 09:34:21 -0700
Subject: [PATCH v10 1/5] mtd: nand: vf610_nfc: Freescale NFC for VF610,
 MPC5125 and others
In-Reply-To: <bf1ed158fe08b51c4668faffde44083f@agner.ch>
References: <1438594050-4595-1-git-send-email-stefan@agner.ch>
 <1438594050-4595-2-git-send-email-stefan@agner.ch>
 <20150825201631.GK81844@google.com>
 <bf1ed158fe08b51c4668faffde44083f@agner.ch>
Message-ID: <20150827163421.GX81844@google.com>

On Wed, Aug 26, 2015 at 06:02:31PM -0700, Stefan Agner wrote:
> On 2015-08-25 13:16, Brian Norris wrote:
> > On Mon, Aug 03, 2015 at 11:27:26AM +0200, Stefan Agner wrote:
> >> diff --git a/drivers/mtd/nand/vf610_nfc.c b/drivers/mtd/nand/vf610_nfc.c
> >> new file mode 100644
> >> index 0000000..5c8dfe8
> >> --- /dev/null
> >> +++ b/drivers/mtd/nand/vf610_nfc.c
> >> @@ -0,0 +1,645 @@
> > 
> > ...
> > 
> >> +/*
> >> + * This function supports Vybrid only (MPC5125 would have full RB and four CS)
> >> + */
> >> +static void vf610_nfc_select_chip(struct mtd_info *mtd, int chip)
> >> +{
> >> +#ifdef CONFIG_SOC_VF610
> > 
> > Why the #ifdef? I don't see anything compile-time specific to SOC_VF610.
> > 
> > If this is trying to handle the comment above ("This function supports
> > Vybrid only (MPC5125 would have full RB and four CS)") then that's the
> > wrong way of doing it, as you need to support multiplatform kernels.
> > You'll need to have a way to differentiate the different platform
> > support at runtime, not compile time.
> 
> Yes it is trying to handle the comment above. Well, the other two
> platforms I am aware of are also different architectures... (PowerPC and
> ColdFire). I think we won't have a multi-architecture kernel anytime
> soon,

Ha, right. Sorry, I don't really know this particular IP.

> hence I think removing the code at compile time is the right thing
> todo.

I don't believe that conclusion follows though.

> However, probably CONFIG_SOC_VF610 is the wrong symbol then, I could
> just use CONFIG_ARM and add a comment that this might be different on
> another other ARM SoC than VF610.
> 
> Just checked CodingStyle, and I see that IS_ENABLED is the preferred way
> for conditional compiling.
> 
> So my suggestion:
> 
> static void vf610_nfc_select_chip(struct mtd_info *mtd, int chip)
> {
> 	struct vf610_nfc *nfc = mtd_to_nfc(mtd);
> 	u32 tmp = vf610_nfc_read(nfc, NFC_ROW_ADDR);
> 
> 	if (!IS_ENABLED(CONFIG_ARM))
> 		return;
> 
> 	/*
> 	 * This code is only tested on the ARM platform VF610
> 	 * PowerPC based MPC5125 would have full RB and four CS
> 	 */
> ....
> 
> With that the compiler should be able to remove this (currently) ARM
> VF610 specific code on the other supported architectures...
> 
> What do you think?

The code structure isn't bad, and yes, IS_ENABLED() would be preferable,
as it removes some of the problems with #ifdef, but I still don't think
the processor architecture has much to do with the version of the IP.
The canonical way of distiguishing per-IP revisions is to key on the
compatible property. So you'd have some kind of enum, which would
currently only have an entry for VF610. i.e.:

	/* MPC5125 not yet supported */
	if (nfc->revision != NAND_VFC610)
		return;

> >> +	struct vf610_nfc *nfc = mtd_to_nfc(mtd);
> >> +	u32 tmp = vf610_nfc_read(nfc, NFC_ROW_ADDR);
> >> +
> >> +	tmp &= ~(ROW_ADDR_CHIP_SEL_RB_MASK | ROW_ADDR_CHIP_SEL_MASK);
> >> +	tmp |= 1 << ROW_ADDR_CHIP_SEL_RB_SHIFT;
> >> +
> >> +	if (chip == 0)
> >> +		tmp |= 1 << ROW_ADDR_CHIP_SEL_SHIFT;
> >> +	else if (chip == 1)
> >> +		tmp |= 2 << ROW_ADDR_CHIP_SEL_SHIFT;
> > 
> > 	else ... ?
> > 
> > Maybe you can write this as a formulaic pattern (e.g.:
> > 
> > 	tmp |= (chip + 1) << ROW_ADDR_CHIP_SEL_SHIFT;
> > 
> > ) and just do the "max # of chips" checks on a per-platform basis in the
> > probe(). Then I'm guessing this same function can apply to both
> > platforms. (I'm not looking at HW datasheets for this, BTW, just
> > guessing based on the context here.)
> 
> It seems that MCP5125 is different than VF610. MCP5125 has 4 chip
> selects and 4 R/B signals, whereas VF610 has only 2 chip selects and
> just 1 R/B signals...

OK I don't presume to know what the different IP versions look like. And
if you just note they are unsupported/untested, you're fine.

Brian


From tony at atomide.com  Thu Aug 27 09:38:56 2015
From: tony at atomide.com (Tony Lindgren)
Date: Thu, 27 Aug 2015 09:38:56 -0700
Subject: [PATCH] ARM: OMAP2+: omap-device: remove omap_device_late_init
 call completely
In-Reply-To: <55DF12E7.10802@ti.com>
References: <1440611890-4935-1-git-send-email-grygorii.strashko@ti.com>
 <20150826181006.GT4215@atomide.com> <55DF12E7.10802@ti.com>
Message-ID: <20150827163856.GX4215@atomide.com>

* Grygorii Strashko <grygorii.strashko at ti.com> [150827 06:42]:
> Hi Tony,
> 
> On 08/26/2015 09:10 PM, Tony Lindgren wrote:
> > * Grygorii Strashko <grygorii.strashko at ti.com> [150826 11:01]:
> >> Now Kernel fails to boot 50% of times (form build to build) with
> >> RT-patchset applied due to the following race - on late boot
> >> stages deferred_probe_work_func races with omap_device_late_ini
> >>
> >> late_initcall
> >>   - deferred_probe_initcal() tries to re-probe all pending driver's probe.
> >>     [In general, It's NOT expected to probe any other built-in drivers after
> >>     deferred_probe_initcal() is finished, because most of
> >>     late_initcall_sync/late_initcall functions expected that all driver
> >>     or probed or deferred already.]
> >>
> >> - later on, some driver is probing in this case It's could cpsw.c
> >>    (but could be any other drivers)
> >>    cpsw_init
> >>    - platform_driver_register
> >>      - really_probe
> >>         - driver_bound
> >>           - driver_deferred_probe_trigger
> >>    and boot proceed.
> >>    So, at this moment we have  deferred_probe_work_func scheduled.
> >>
> >> late_initcall_sync
> >>    - omap_device_late_init
> >>      - omap_device_idle
> >>
> >> CPU1					CPU2
> >>    - deferred_probe_work_func
> >>      - really_probe
> >>        - omap_hsmmc_probe
> >> 	- pm_runtime_get_sync
> >> 					late_initcall_sync
> >> 					- omap_device_late_init
> >> 						if (od->_driver_status != BUS_NOTIFY_BOUND_DRIVER) {
> >> 							if (od->_state == OMAP_DEVICE_STATE_ENABLED) {
> >> 								- omap_device_idle [ops - IP is disabled, ]
> >> 	- [fail]
> >> 	- pm_runtime_put_sync
> >>            - omap_hsmmc_runtime_suspend [ooops!]
> > 
> > OK idling of unclaimed devices should not happen for deferred probe,
> > it should only happen when there's no driver and no probing happening.
> >   
> >> Lets remove just remove omap_device_late_init completely as suggested
> >> by Tero Kristo:
> >>
> >> "How about remove omap_device_late_init call completely. I don't think
> >> it does anything useful at the moment; none of the omap devices get
> >> enabled outside runtime_pm, so there should be no need to explicitly
> >> disable the devices."
> > 
> > I think this is still needed from PM point of view as otherwise we
> > don't idle any devices that don't have a driver available. Or am I
> > missing something?
> > 
> > To me it seems the bug is relying on the BUS_NOTIFY_BOUND_DRIVER is
> > not set in the deferred probe case.
> > 
> 
> 
> What do you think about below alternative?
> 
> diff --git a/arch/arm/mach-omap2/omap_device.c b/arch/arm/mach-omap2/omap_device.c
> index 4cb8fd9..72ebc4c 100644
> --- a/arch/arm/mach-omap2/omap_device.c
> +++ b/arch/arm/mach-omap2/omap_device.c
> @@ -901,7 +901,8 @@ static int __init omap_device_late_idle(struct device *dev, void *data)
>                 if (od->hwmods[i]->flags & HWMOD_INIT_NO_IDLE)
>                         return 0;
>  
> -       if (od->_driver_status != BUS_NOTIFY_BOUND_DRIVER) {
> +       if (od->_driver_status != BUS_NOTIFY_BOUND_DRIVER &&
> +           od->_driver_status != BUS_NOTIFY_BIND_DRIVER) {
>                 if (od->_state == OMAP_DEVICE_STATE_ENABLED) {
>                         dev_warn(dev, "%s: enabled but no driver.  Idling\n",
>                                  __func__);

Seems better to me if it really fixes the issue.

Regards,

Tony


From l.stach at pengutronix.de  Thu Aug 27 09:39:13 2015
From: l.stach at pengutronix.de (Lucas Stach)
Date: Thu, 27 Aug 2015 18:39:13 +0200
Subject: [PATCH 0/8] i.MX early debug UART clock fixes
Message-ID: <1440693561-28095-1-git-send-email-l.stach@pengutronix.de>

This series fixes a long standing interaction issue between the
kernels early debug facilities and the i.MX clock drivers.

Both earlyprintk and earlycon rely on the bootloader setup clocks
for the UARTs to be retained during kernel init. As those clocks are
only enabled in hardware, but not referenced in software they (or even
their parent clocks) may get disabled as a result of other clocks being
en-/disabled during boot.

This results in missing messages from the early debug console until the
regular system console takes over, or even worse system hangs in response
to unclocked register accesses. This renders those debugging facilities a
lot less useful.

The fix implemented here is to check if any of this early debugging is
enabled and keep the UART clocks referenced and enabled in that case.
The clocks will then only be disabled at the end of kernel init, at which
point the real console should have taken over and the early outputs being
disabled.

I've runtime tested this on i.MX6Q and i.MX53, other platforms are only
compile tested. This is mostly a mechanical change, but still I would
appreciate some testing.

Regards,
Lucas

Lucas Stach (8):
  clk: imx: add common logic to detect early UART usage
  clk: imx25: retain early UART clocks during kernel init
  clk: imx27: retain early UART clocks during kernel init
  clk: imx31: retain early UART clocks during kernel init
  clk: imx35: retain early UART clocks during kernel init
  clk: imx5: retain early UART clocks during kernel init
  clk: imx6: retain early UART clocks during kernel init
  clk: imx7d: retain early UART clocks during kernel init

 drivers/clk/imx/clk-imx25.c       | 20 ++++++++++++++++++++
 drivers/clk/imx/clk-imx27.c       | 22 ++++++++++++++++++++++
 drivers/clk/imx/clk-imx31.c       | 20 ++++++++++++++++++++
 drivers/clk/imx/clk-imx35.c       | 16 ++++++++++++++++
 drivers/clk/imx/clk-imx51-imx53.c | 28 ++++++++++++++++++++++++++++
 drivers/clk/imx/clk-imx6q.c       | 12 ++++++++++++
 drivers/clk/imx/clk-imx6sl.c      | 12 ++++++++++++
 drivers/clk/imx/clk-imx6sx.c      | 12 ++++++++++++
 drivers/clk/imx/clk-imx7d.c       | 22 ++++++++++++++++++++++
 drivers/clk/imx/clk.c             | 33 +++++++++++++++++++++++++++++++++
 drivers/clk/imx/clk.h             |  2 ++
 11 files changed, 199 insertions(+)

-- 
2.5.0



From l.stach at pengutronix.de  Thu Aug 27 09:39:19 2015
From: l.stach at pengutronix.de (Lucas Stach)
Date: Thu, 27 Aug 2015 18:39:19 +0200
Subject: [PATCH 6/8] clk: imx5: retain early UART clocks during kernel init
In-Reply-To: <1440693561-28095-1-git-send-email-l.stach@pengutronix.de>
References: <1440693561-28095-1-git-send-email-l.stach@pengutronix.de>
Message-ID: <1440693561-28095-7-git-send-email-l.stach@pengutronix.de>

Make sure to keep UART clocks enabled during kernel init if
earlyprintk or earlycon are active.

Signed-off-by: Lucas Stach <l.stach at pengutronix.de>
---
 drivers/clk/imx/clk-imx51-imx53.c | 28 ++++++++++++++++++++++++++++
 1 file changed, 28 insertions(+)

diff --git a/drivers/clk/imx/clk-imx51-imx53.c b/drivers/clk/imx/clk-imx51-imx53.c
index a7e4f394be0d..701d1d912a4b 100644
--- a/drivers/clk/imx/clk-imx51-imx53.c
+++ b/drivers/clk/imx/clk-imx51-imx53.c
@@ -130,6 +130,20 @@ static const char *cpu_podf_sels[] = { "pll1_sw", "step_sel" };
 static struct clk *clk[IMX5_CLK_END];
 static struct clk_onecell_data clk_data;
 
+static void __init imx5_uart_disable_cb(void)
+{
+	clk_disable_unprepare(clk[IMX5_CLK_UART1_IPG_GATE]);
+	clk_disable_unprepare(clk[IMX5_CLK_UART1_PER_GATE]);
+	clk_disable_unprepare(clk[IMX5_CLK_UART2_IPG_GATE]);
+	clk_disable_unprepare(clk[IMX5_CLK_UART2_PER_GATE]);
+	clk_disable_unprepare(clk[IMX5_CLK_UART3_IPG_GATE]);
+	clk_disable_unprepare(clk[IMX5_CLK_UART3_PER_GATE]);
+	clk_disable_unprepare(clk[IMX5_CLK_UART4_IPG_GATE]);
+	clk_disable_unprepare(clk[IMX5_CLK_UART4_PER_GATE]);
+	clk_disable_unprepare(clk[IMX5_CLK_UART5_IPG_GATE]);
+	clk_disable_unprepare(clk[IMX5_CLK_UART5_PER_GATE]);
+}
+
 static void __init mx5_clocks_common_init(void __iomem *ccm_base)
 {
 	clk[IMX5_CLK_DUMMY]		= imx_clk_fixed("dummy", 0);
@@ -310,6 +324,20 @@ static void __init mx5_clocks_common_init(void __iomem *ccm_base)
 	clk_prepare_enable(clk[IMX5_CLK_TMAX1]);
 	clk_prepare_enable(clk[IMX5_CLK_TMAX2]); /* esdhc2, fec */
 	clk_prepare_enable(clk[IMX5_CLK_TMAX3]); /* esdhc1, esdhc4 */
+
+	if (imx_clk_keep_uart()) {
+		clk_prepare_enable(clk[IMX5_CLK_UART1_IPG_GATE]);
+		clk_prepare_enable(clk[IMX5_CLK_UART1_PER_GATE]);
+		clk_prepare_enable(clk[IMX5_CLK_UART2_IPG_GATE]);
+		clk_prepare_enable(clk[IMX5_CLK_UART2_PER_GATE]);
+		clk_prepare_enable(clk[IMX5_CLK_UART3_IPG_GATE]);
+		clk_prepare_enable(clk[IMX5_CLK_UART3_PER_GATE]);
+		clk_prepare_enable(clk[IMX5_CLK_UART4_IPG_GATE]);
+		clk_prepare_enable(clk[IMX5_CLK_UART4_PER_GATE]);
+		clk_prepare_enable(clk[IMX5_CLK_UART5_IPG_GATE]);
+		clk_prepare_enable(clk[IMX5_CLK_UART5_PER_GATE]);
+		imx_clk_set_uart_disable_callback(imx5_uart_disable_cb);
+	}
 }
 
 static void __init mx50_clocks_init(struct device_node *np)
-- 
2.5.0



From l.stach at pengutronix.de  Thu Aug 27 09:39:16 2015
From: l.stach at pengutronix.de (Lucas Stach)
Date: Thu, 27 Aug 2015 18:39:16 +0200
Subject: [PATCH 3/8] clk: imx27: retain early UART clocks during kernel init
In-Reply-To: <1440693561-28095-1-git-send-email-l.stach@pengutronix.de>
References: <1440693561-28095-1-git-send-email-l.stach@pengutronix.de>
Message-ID: <1440693561-28095-4-git-send-email-l.stach@pengutronix.de>

Make sure to keep UART clocks enabled during kernel init if
earlyprintk or earlycon are active.

Signed-off-by: Lucas Stach <l.stach at pengutronix.de>
---
 drivers/clk/imx/clk-imx27.c | 22 ++++++++++++++++++++++
 1 file changed, 22 insertions(+)

diff --git a/drivers/clk/imx/clk-imx27.c b/drivers/clk/imx/clk-imx27.c
index d9d50d54ef2a..54fb783123a9 100644
--- a/drivers/clk/imx/clk-imx27.c
+++ b/drivers/clk/imx/clk-imx27.c
@@ -47,6 +47,17 @@ static const char *ssi_sel_clks[] = { "spll_gate", "mpll", };
 static struct clk *clk[IMX27_CLK_MAX];
 static struct clk_onecell_data clk_data;
 
+static void __init imx27_uart_disable_cb(void)
+{
+	clk_disable_unprepare(clk[IMX27_CLK_PER1_GATE]);
+	clk_disable_unprepare(clk[IMX27_CLK_UART1_IPG_GATE]);
+	clk_disable_unprepare(clk[IMX27_CLK_UART2_IPG_GATE]);
+	clk_disable_unprepare(clk[IMX27_CLK_UART3_IPG_GATE]);
+	clk_disable_unprepare(clk[IMX27_CLK_UART4_IPG_GATE]);
+	clk_disable_unprepare(clk[IMX27_CLK_UART5_IPG_GATE]);
+	clk_disable_unprepare(clk[IMX27_CLK_UART6_IPG_GATE]);
+}
+
 static void __init _mx27_clocks_init(unsigned long fref)
 {
 	BUG_ON(!ccm);
@@ -163,6 +174,17 @@ static void __init _mx27_clocks_init(unsigned long fref)
 
 	clk_prepare_enable(clk[IMX27_CLK_EMI_AHB_GATE]);
 
+	if (imx_clk_keep_uart()) {
+		clk_prepare_enable(clk[IMX27_CLK_PER1_GATE]);
+		clk_prepare_enable(clk[IMX27_CLK_UART1_IPG_GATE]);
+		clk_prepare_enable(clk[IMX27_CLK_UART2_IPG_GATE]);
+		clk_prepare_enable(clk[IMX27_CLK_UART3_IPG_GATE]);
+		clk_prepare_enable(clk[IMX27_CLK_UART4_IPG_GATE]);
+		clk_prepare_enable(clk[IMX27_CLK_UART5_IPG_GATE]);
+		clk_prepare_enable(clk[IMX27_CLK_UART6_IPG_GATE]);
+		imx_clk_set_uart_disable_callback(imx27_uart_disable_cb);
+	}
+
 	imx_print_silicon_rev("i.MX27", mx27_revision());
 }
 
-- 
2.5.0



From l.stach at pengutronix.de  Thu Aug 27 09:39:18 2015
From: l.stach at pengutronix.de (Lucas Stach)
Date: Thu, 27 Aug 2015 18:39:18 +0200
Subject: [PATCH 5/8] clk: imx35: retain early UART clocks during kernel init
In-Reply-To: <1440693561-28095-1-git-send-email-l.stach@pengutronix.de>
References: <1440693561-28095-1-git-send-email-l.stach@pengutronix.de>
Message-ID: <1440693561-28095-6-git-send-email-l.stach@pengutronix.de>

Make sure to keep UART clocks enabled during kernel init if
earlyprintk or earlycon are active.

Signed-off-by: Lucas Stach <l.stach at pengutronix.de>
---
 drivers/clk/imx/clk-imx35.c | 16 ++++++++++++++++
 1 file changed, 16 insertions(+)

diff --git a/drivers/clk/imx/clk-imx35.c b/drivers/clk/imx/clk-imx35.c
index 69138ba3dec7..7b2aaf123d3b 100644
--- a/drivers/clk/imx/clk-imx35.c
+++ b/drivers/clk/imx/clk-imx35.c
@@ -84,6 +84,14 @@ enum mx35_clks {
 
 static struct clk *clk[clk_max];
 
+static void __init imx35_uart_disable_cb(void)
+{
+	clk_disable_unprepare(clk[ipg]);
+	clk_disable_unprepare(clk[uart1_gate]);
+	clk_disable_unprepare(clk[uart2_gate]);
+	clk_disable_unprepare(clk[uart3_gate]);
+}
+
 int __init mx35_clocks_init(void)
 {
 	void __iomem *base;
@@ -292,6 +300,14 @@ int __init mx35_clocks_init(void)
 	 */
 	clk_prepare_enable(clk[scc_gate]);
 
+	if (imx_clk_keep_uart()) {
+		clk_prepare_enable(clk[ipg]);
+		clk_prepare_enable(clk[uart1_gate]);
+		clk_prepare_enable(clk[uart2_gate]);
+		clk_prepare_enable(clk[uart3_gate]);
+		imx_clk_set_uart_disable_callback(imx35_uart_disable_cb);
+	}
+
 	imx_print_silicon_rev("i.MX35", mx35_revision());
 
 	mxc_timer_init(MX35_GPT1_BASE_ADDR, MX35_INT_GPT, GPT_TYPE_IMX31);
-- 
2.5.0



From l.stach at pengutronix.de  Thu Aug 27 09:39:21 2015
From: l.stach at pengutronix.de (Lucas Stach)
Date: Thu, 27 Aug 2015 18:39:21 +0200
Subject: [PATCH 8/8] clk: imx7d: retain early UART clocks during kernel init
In-Reply-To: <1440693561-28095-1-git-send-email-l.stach@pengutronix.de>
References: <1440693561-28095-1-git-send-email-l.stach@pengutronix.de>
Message-ID: <1440693561-28095-9-git-send-email-l.stach@pengutronix.de>

Make sure to keep UART clocks enabled during kernel init if
earlyprintk or earlycon are active.

Signed-off-by: Lucas Stach <l.stach at pengutronix.de>
---
 drivers/clk/imx/clk-imx7d.c | 22 ++++++++++++++++++++++
 1 file changed, 22 insertions(+)

diff --git a/drivers/clk/imx/clk-imx7d.c b/drivers/clk/imx/clk-imx7d.c
index 71f3a94b472c..8daef5202841 100644
--- a/drivers/clk/imx/clk-imx7d.c
+++ b/drivers/clk/imx/clk-imx7d.c
@@ -363,6 +363,17 @@ static const char *pll_video_bypass_sel[] = { "pll_video_main", "pll_video_main_
 
 static struct clk_onecell_data clk_data;
 
+static void __init imx7d_uart_disable_cb(void)
+{
+	clk_disable_unprepare(clks[IMX7D_UART1_ROOT_CLK]);
+	clk_disable_unprepare(clks[IMX7D_UART2_ROOT_CLK]);
+	clk_disable_unprepare(clks[IMX7D_UART3_ROOT_CLK]);
+	clk_disable_unprepare(clks[IMX7D_UART4_ROOT_CLK]);
+	clk_disable_unprepare(clks[IMX7D_UART5_ROOT_CLK]);
+	clk_disable_unprepare(clks[IMX7D_UART6_ROOT_CLK]);
+	clk_disable_unprepare(clks[IMX7D_UART7_ROOT_CLK]);
+}
+
 static void __init imx7d_clocks_init(struct device_node *ccm_node)
 {
 	struct device_node *np;
@@ -856,5 +867,16 @@ static void __init imx7d_clocks_init(struct device_node *ccm_node)
 	/* set uart module clock's parent clock source that must be great then 80MHz */
 	clk_set_parent(clks[IMX7D_UART1_ROOT_SRC], clks[IMX7D_OSC_24M_CLK]);
 
+	if (imx_clk_keep_uart()) {
+		clk_prepare_enable(clks[IMX7D_UART1_ROOT_CLK]);
+		clk_prepare_enable(clks[IMX7D_UART2_ROOT_CLK]);
+		clk_prepare_enable(clks[IMX7D_UART3_ROOT_CLK]);
+		clk_prepare_enable(clks[IMX7D_UART4_ROOT_CLK]);
+		clk_prepare_enable(clks[IMX7D_UART5_ROOT_CLK]);
+		clk_prepare_enable(clks[IMX7D_UART6_ROOT_CLK]);
+		clk_prepare_enable(clks[IMX7D_UART7_ROOT_CLK]);
+		imx_clk_set_uart_disable_callback(imx7d_uart_disable_cb);
+	}
+
 }
 CLK_OF_DECLARE(imx7d, "fsl,imx7d-ccm", imx7d_clocks_init);
-- 
2.5.0



From l.stach at pengutronix.de  Thu Aug 27 09:39:20 2015
From: l.stach at pengutronix.de (Lucas Stach)
Date: Thu, 27 Aug 2015 18:39:20 +0200
Subject: [PATCH 7/8] clk: imx6: retain early UART clocks during kernel init
In-Reply-To: <1440693561-28095-1-git-send-email-l.stach@pengutronix.de>
References: <1440693561-28095-1-git-send-email-l.stach@pengutronix.de>
Message-ID: <1440693561-28095-8-git-send-email-l.stach@pengutronix.de>

Make sure to keep UART clocks enabled during kernel init if
earlyprintk or earlycon are active.

Signed-off-by: Lucas Stach <l.stach at pengutronix.de>
---
 drivers/clk/imx/clk-imx6q.c  | 12 ++++++++++++
 drivers/clk/imx/clk-imx6sl.c | 12 ++++++++++++
 drivers/clk/imx/clk-imx6sx.c | 12 ++++++++++++
 3 files changed, 36 insertions(+)

diff --git a/drivers/clk/imx/clk-imx6q.c b/drivers/clk/imx/clk-imx6q.c
index d046f8e43de8..af6a6517b26c 100644
--- a/drivers/clk/imx/clk-imx6q.c
+++ b/drivers/clk/imx/clk-imx6q.c
@@ -130,6 +130,12 @@ static inline int clk_on_imx6dl(void)
 	return of_machine_is_compatible("fsl,imx6dl");
 }
 
+static void __init imx6q_uart_disable_cb(void)
+{
+	clk_disable_unprepare(clk[IMX6QDL_CLK_UART_IPG]);
+	clk_disable_unprepare(clk[IMX6QDL_CLK_UART_SERIAL]);
+}
+
 static void __init imx6q_clocks_init(struct device_node *ccm_node)
 {
 	struct device_node *np;
@@ -534,5 +540,11 @@ static void __init imx6q_clocks_init(struct device_node *ccm_node)
 	/* All existing boards with PCIe use LVDS1 */
 	if (IS_ENABLED(CONFIG_PCI_IMX6))
 		clk_set_parent(clk[IMX6QDL_CLK_LVDS1_SEL], clk[IMX6QDL_CLK_SATA_REF_100M]);
+
+	if (imx_clk_keep_uart()) {
+		clk_prepare_enable(clk[IMX6QDL_CLK_UART_IPG]);
+		clk_prepare_enable(clk[IMX6QDL_CLK_UART_SERIAL]);
+		imx_clk_set_uart_disable_callback(imx6q_uart_disable_cb);
+	}
 }
 CLK_OF_DECLARE(imx6q, "fsl,imx6q-ccm", imx6q_clocks_init);
diff --git a/drivers/clk/imx/clk-imx6sl.c b/drivers/clk/imx/clk-imx6sl.c
index a0d4cf26cfa9..737a9a84f201 100644
--- a/drivers/clk/imx/clk-imx6sl.c
+++ b/drivers/clk/imx/clk-imx6sl.c
@@ -184,6 +184,12 @@ void imx6sl_set_wait_clk(bool enter)
 		imx6sl_enable_pll_arm(false);
 }
 
+static void __init imx6sl_uart_disable_cb(void)
+{
+	clk_disable_unprepare(clks[IMX6SL_CLK_UART]);
+	clk_disable_unprepare(clks[IMX6SL_CLK_UART_SERIAL]);
+}
+
 static void __init imx6sl_clocks_init(struct device_node *ccm_node)
 {
 	struct device_node *np;
@@ -439,5 +445,11 @@ static void __init imx6sl_clocks_init(struct device_node *ccm_node)
 
 	clk_set_parent(clks[IMX6SL_CLK_LCDIF_AXI_SEL],
 		       clks[IMX6SL_CLK_PLL2_PFD2]);
+
+	if (imx_clk_keep_uart()) {
+		clk_prepare_enable(clks[IMX6SL_CLK_UART]);
+		clk_prepare_enable(clks[IMX6SL_CLK_UART_SERIAL]);
+		imx_clk_set_uart_disable_callback(imx6sl_uart_disable_cb);
+	}
 }
 CLK_OF_DECLARE(imx6sl, "fsl,imx6sl-ccm", imx6sl_clocks_init);
diff --git a/drivers/clk/imx/clk-imx6sx.c b/drivers/clk/imx/clk-imx6sx.c
index 5b95c2c2bf52..ec14235659cc 100644
--- a/drivers/clk/imx/clk-imx6sx.c
+++ b/drivers/clk/imx/clk-imx6sx.c
@@ -135,6 +135,12 @@ static u32 share_count_ssi1;
 static u32 share_count_ssi2;
 static u32 share_count_ssi3;
 
+static void __init imx6sx_uart_disable_cb(void)
+{
+	clk_disable_unprepare(clks[IMX6SX_CLK_UART_IPG]);
+	clk_disable_unprepare(clks[IMX6SX_CLK_UART_SERIAL]);
+}
+
 static void __init imx6sx_clocks_init(struct device_node *ccm_node)
 {
 	struct device_node *np;
@@ -557,5 +563,11 @@ static void __init imx6sx_clocks_init(struct device_node *ccm_node)
 
 	clk_set_parent(clks[IMX6SX_CLK_QSPI1_SEL], clks[IMX6SX_CLK_PLL2_BUS]);
 	clk_set_parent(clks[IMX6SX_CLK_QSPI2_SEL], clks[IMX6SX_CLK_PLL2_BUS]);
+
+	if (imx_clk_keep_uart()) {
+		clk_prepare_enable(clks[IMX6SX_CLK_UART_IPG]);
+		clk_prepare_enable(clks[IMX6SX_CLK_UART_SERIAL]);
+		imx_clk_set_uart_disable_callback(imx6sx_uart_disable_cb);
+	}
 }
 CLK_OF_DECLARE(imx6sx, "fsl,imx6sx-ccm", imx6sx_clocks_init);
-- 
2.5.0



From l.stach at pengutronix.de  Thu Aug 27 09:39:17 2015
From: l.stach at pengutronix.de (Lucas Stach)
Date: Thu, 27 Aug 2015 18:39:17 +0200
Subject: [PATCH 4/8] clk: imx31: retain early UART clocks during kernel init
In-Reply-To: <1440693561-28095-1-git-send-email-l.stach@pengutronix.de>
References: <1440693561-28095-1-git-send-email-l.stach@pengutronix.de>
Message-ID: <1440693561-28095-5-git-send-email-l.stach@pengutronix.de>

Make sure to keep UART clocks enabled during kernel init if
earlyprintk or earlycon are active.

Signed-off-by: Lucas Stach <l.stach at pengutronix.de>
---
 drivers/clk/imx/clk-imx31.c | 20 ++++++++++++++++++++
 1 file changed, 20 insertions(+)

diff --git a/drivers/clk/imx/clk-imx31.c b/drivers/clk/imx/clk-imx31.c
index fe66c40b7be2..c8da3b31f24d 100644
--- a/drivers/clk/imx/clk-imx31.c
+++ b/drivers/clk/imx/clk-imx31.c
@@ -62,6 +62,16 @@ enum mx31_clks {
 static struct clk *clk[clk_max];
 static struct clk_onecell_data clk_data;
 
+static void __init imx31_uart_disable_cb(void)
+{
+	clk_disable_unprepare(clk[ipg]);
+	clk_disable_unprepare(clk[uart1_gate]);
+	clk_disable_unprepare(clk[uart2_gate]);
+	clk_disable_unprepare(clk[uart3_gate]);
+	clk_disable_unprepare(clk[uart4_gate]);
+	clk_disable_unprepare(clk[uart5_gate]);
+}
+
 int __init mx31_clocks_init(unsigned long fref)
 {
 	void __iomem *base;
@@ -199,6 +209,16 @@ int __init mx31_clocks_init(unsigned long fref)
 	mx31_revision();
 	clk_disable_unprepare(clk[iim_gate]);
 
+	if (imx_clk_keep_uart()) {
+		clk_prepare_enable(clk[ipg]);
+		clk_prepare_enable(clk[uart1_gate]);
+		clk_prepare_enable(clk[uart2_gate]);
+		clk_prepare_enable(clk[uart3_gate]);
+		clk_prepare_enable(clk[uart4_gate]);
+		clk_prepare_enable(clk[uart5_gate]);
+		imx_clk_set_uart_disable_callback(imx31_uart_disable_cb);
+	}
+
 	mxc_timer_init(MX31_GPT1_BASE_ADDR, MX31_INT_GPT, GPT_TYPE_IMX31);
 
 	return 0;
-- 
2.5.0



From l.stach at pengutronix.de  Thu Aug 27 09:39:14 2015
From: l.stach at pengutronix.de (Lucas Stach)
Date: Thu, 27 Aug 2015 18:39:14 +0200
Subject: [PATCH 1/8] clk: imx: add common logic to detect early UART usage
In-Reply-To: <1440693561-28095-1-git-send-email-l.stach@pengutronix.de>
References: <1440693561-28095-1-git-send-email-l.stach@pengutronix.de>
Message-ID: <1440693561-28095-2-git-send-email-l.stach@pengutronix.de>

Both earlycon and eralyprintk depend on the bootloader setup UART
clocks being retained. This patch adds the common logic to detect such
situations and make the information available to the clock drivers, as
well as adding the facilities to disable those clocks at the end of
the kernel init.

Signed-off-by: Lucas Stach <l.stach at pengutronix.de>
---
 drivers/clk/imx/clk.c | 33 +++++++++++++++++++++++++++++++++
 drivers/clk/imx/clk.h |  2 ++
 2 files changed, 35 insertions(+)

diff --git a/drivers/clk/imx/clk.c b/drivers/clk/imx/clk.c
index df12b5307175..70580c8d1a3c 100644
--- a/drivers/clk/imx/clk.c
+++ b/drivers/clk/imx/clk.c
@@ -73,3 +73,36 @@ void imx_cscmr1_fixup(u32 *val)
 	*val ^= CSCMR1_FIXUP;
 	return;
 }
+
+static int __initdata imx_keep_uart_clocks;
+static void __initdata (*imx_uart_disable_fn)(void);
+
+static int __init imx_keep_uart_clocks_param(char *str)
+{
+	imx_keep_uart_clocks = 1;
+
+	return 0;
+}
+__setup_param("earlycon", imx_keep_uart_earlycon,
+	      imx_keep_uart_clocks_param, 0);
+__setup_param("earlyprintk", imx_keep_uart_earlyprintk,
+	      imx_keep_uart_clocks_param, 0);
+
+int __init imx_clk_keep_uart(void)
+{
+	return imx_keep_uart_clocks;
+}
+
+void __init imx_clk_set_uart_disable_callback(void (*disable_cb)(void))
+{
+	imx_uart_disable_fn = disable_cb;
+}
+
+static int __init imx_clk_disable_uart(void)
+{
+	if (imx_uart_disable_fn)
+		imx_uart_disable_fn();
+
+	return 0;
+}
+late_initcall_sync(imx_clk_disable_uart);
diff --git a/drivers/clk/imx/clk.h b/drivers/clk/imx/clk.h
index 1049b0c7d818..41725a92c63c 100644
--- a/drivers/clk/imx/clk.h
+++ b/drivers/clk/imx/clk.h
@@ -7,6 +7,8 @@
 extern spinlock_t imx_ccm_lock;
 
 void imx_check_clocks(struct clk *clks[], unsigned int count);
+int imx_clk_keep_uart(void);
+void imx_clk_set_uart_disable_callback(void (*disable_cb)(void));
 
 extern void imx_cscmr1_fixup(u32 *val);
 
-- 
2.5.0



From l.stach at pengutronix.de  Thu Aug 27 09:39:15 2015
From: l.stach at pengutronix.de (Lucas Stach)
Date: Thu, 27 Aug 2015 18:39:15 +0200
Subject: [PATCH 2/8] clk: imx25: retain early UART clocks during kernel init
In-Reply-To: <1440693561-28095-1-git-send-email-l.stach@pengutronix.de>
References: <1440693561-28095-1-git-send-email-l.stach@pengutronix.de>
Message-ID: <1440693561-28095-3-git-send-email-l.stach@pengutronix.de>

Make sure to keep UART clocks enabled during kernel init if
earlyprintk or earlycon are active.

Signed-off-by: Lucas Stach <l.stach at pengutronix.de>
---
 drivers/clk/imx/clk-imx25.c | 20 ++++++++++++++++++++
 1 file changed, 20 insertions(+)

diff --git a/drivers/clk/imx/clk-imx25.c b/drivers/clk/imx/clk-imx25.c
index ec1a4c1dacf1..4322ef409cc6 100644
--- a/drivers/clk/imx/clk-imx25.c
+++ b/drivers/clk/imx/clk-imx25.c
@@ -86,6 +86,16 @@ enum mx25_clks {
 
 static struct clk *clk[clk_max];
 
+static void __init imx25_uart_disable_cb(void)
+{
+	clk_disable_unprepare(clk[uart_ipg_per]);
+	clk_disable_unprepare(clk[uart1_ipg]);
+	clk_disable_unprepare(clk[uart2_ipg]);
+	clk_disable_unprepare(clk[uart3_ipg]);
+	clk_disable_unprepare(clk[uart4_ipg]);
+	clk_disable_unprepare(clk[uart5_ipg]);
+}
+
 static int __init __mx25_clocks_init(unsigned long osc_rate,
 				     void __iomem *ccm_base)
 {
@@ -233,6 +243,16 @@ static int __init __mx25_clocks_init(unsigned long osc_rate,
 	 */
 	clk_set_parent(clk[cko_sel], clk[ipg]);
 
+	if (imx_clk_keep_uart()) {
+		clk_prepare_enable(clk[uart_ipg_per]);
+		clk_prepare_enable(clk[uart1_ipg]);
+		clk_prepare_enable(clk[uart2_ipg]);
+		clk_prepare_enable(clk[uart3_ipg]);
+		clk_prepare_enable(clk[uart4_ipg]);
+		clk_prepare_enable(clk[uart5_ipg]);
+		imx_clk_set_uart_disable_callback(imx25_uart_disable_cb);
+	}
+
 	return 0;
 }
 
-- 
2.5.0



From santosh.shilimkar at oracle.com  Thu Aug 27 09:39:49 2015
From: santosh.shilimkar at oracle.com (santosh.shilimkar at oracle.com)
Date: Thu, 27 Aug 2015 09:39:49 -0700
Subject: [PATCH] soc: ti: reset irq affinity before freeing irq
In-Reply-To: <1440690671-1029-1-git-send-email-m-karicheri2@ti.com>
References: <1440690671-1029-1-git-send-email-m-karicheri2@ti.com>
Message-ID: <55DF3D55.8020705@oracle.com>

On 8/27/15 8:51 AM, Murali Karicheri wrote:
> When using accumulator queue for rx side for network driver, following
> warning is seen when doing a reboot command from Linux console. This
> is because, affinity value is not reset before calling free_irq(). This
> patch fixes this.
>
> Deconfiguring network interfaces...
> [   55.176589] ------------[ cut here ]-----------
> [   55.181232] WARNING: CPU: 0 PID: 2081 at kernel/irq/manage.c:1370
> __free_irq+0x208/0x214
>
> Signed-off-by: Murali Karicheri <m-karicheri2 at ti.com>
> ---

Looks good. I will add it my queue. Thanks !!

Regards,
Santosh


From Nathan_Lynch at mentor.com  Thu Aug 27 09:43:43 2015
From: Nathan_Lynch at mentor.com (Nathan Lynch)
Date: Thu, 27 Aug 2015 11:43:43 -0500
Subject: [PATCH] soc: ti: reset irq affinity before freeing irq
In-Reply-To: <1440690671-1029-1-git-send-email-m-karicheri2@ti.com>
References: <1440690671-1029-1-git-send-email-m-karicheri2@ti.com>
Message-ID: <55DF3E3F.6030506@mentor.com>

On 08/27/2015 10:51 AM, Murali Karicheri wrote:
> When using accumulator queue for rx side for network driver, following
> warning is seen when doing a reboot command from Linux console. This
> is because, affinity value is not reset before calling free_irq(). This
> patch fixes this.
> 
> Deconfiguring network interfaces...
> [   55.176589] ------------[ cut here ]-----------
> [   55.181232] WARNING: CPU: 0 PID: 2081 at kernel/irq/manage.c:1370
> __free_irq+0x208/0x214

The full content of the warning should be included in the commit
message; __free_irq has several potential sources of warning messages,
and line 1370 doesn't correspond to any of them in 4.2-rc8.


> Signed-off-by: Murali Karicheri <m-karicheri2 at ti.com>
> ---
>  - Applies to v4.2.0-rc8
> 
>  drivers/soc/ti/knav_qmss_acc.c | 4 ++++
>  1 file changed, 4 insertions(+)
> 
> diff --git a/drivers/soc/ti/knav_qmss_acc.c b/drivers/soc/ti/knav_qmss_acc.c
> index ef6f69d..b98fe56 100644
> --- a/drivers/soc/ti/knav_qmss_acc.c
> +++ b/drivers/soc/ti/knav_qmss_acc.c
> @@ -261,6 +261,10 @@ static int knav_range_setup_acc_irq(struct knav_range_info *range,
>  	if (old && !new) {
>  		dev_dbg(kdev->dev, "setup-acc-irq: freeing %s for channel %s\n",
>  			acc->name, acc->name);
> +		ret = irq_set_affinity_hint(irq, NULL);
> +		if (ret)
> +			dev_warn(range->kdev->dev,
> +				 "Failed to set IRQ affinity\n");

Seems unnecessary to add a warning here.



From mark.rutland at arm.com  Thu Aug 27 09:46:17 2015
From: mark.rutland at arm.com (Mark Rutland)
Date: Thu, 27 Aug 2015 17:46:17 +0100
Subject: [PATCH v1 3/3] arm64: dts: add Hi6220 mailbox node
In-Reply-To: <1440552341.10987.53.camel@linaro.org>
References: <20150824095144.GA7139@leverpostej>
 <1440411596.3517.12.camel@linaro.org>
 <20150824114903.GT10728@bivouac.eciton.net>
 <1440490427.10987.29.camel@linaro.org>
 <20150825094630.GU10728@bivouac.eciton.net>
 <1440497710.10987.42.camel@linaro.org>
 <20150825104256.GB13471@leverpostej>
 <1440510194.10987.52.camel@linaro.org>
 <20150825160030.GA3774@leoy-linaro>
 <1440552341.10987.53.camel@linaro.org>
Message-ID: <20150827164617.GB31748@leverpostej>

> > Option 2:
> > 
> > 	memory at 0 {
> > 		device_type = "memory";
> > 		reg = <0x0 0x0 0x0 0x40000000>;
> > 	};
> > 
> > 	reserved-memory {
> > 		#address-cells = <2>;
> > 		#size-cells = <2>;
> > 		ranges;
> > 
> > 		mcu_reserved: mcu_reserved at 06dff000 {
> > 			no-map;
> > 			reg = <0x0 0x06dff000 0x0 0x00001000>,	/* MCU mailbox buffer */
> > 			      <0x0 0x05e00000 0x0 0x00100000>,	/* MCU firmware buffer */
> > 			      <0x0 0x0740f000 0x0 0x00001000>;	/* MCU firmware section */
> > 		};
> > 	};
> > 
> >         [...]
> > 
> > 	mailbox: mailbox at f7510000 {
> > 		#mbox-cells = <1>;
> > 		compatible = "hisilicon,hi6220-mbox";
> > 		reg = <0x0 0xf7510000 0x0 0x1000>; /* IPC_S */
> > 		memory-region = <&mcu_reserved>;   /* Mailbox buffer */
> > 		interrupts = <GIC_SPI 94 IRQ_TYPE_LEVEL_HIGH>;
> > 	};
> 
> I prefer the second one. From my view, memory node should only describe
> the hardware information of memory.

That doesn't align with the spec. Per ePAPR, in the description of a
memory node:

	The client program may access memory not covered by any memory
	reservations (see section 8.3) using any storage attributes it
	chooses. However, before changing the storage attributes used to
	access a real page, the client program is responsible for
	performing actions required by the architecture and
	implementation, possibly including flushing the real page from
	the caches.

Note that in this context, memory reservation applies to /memreserve/.
We can only expect other software to handle /memreserve/, and not
reserved-memory, as the latter was introduced by Linux and has not
existed for anywhere near as long.

Additionally, the OS is permitted to map reserved memory with cacheable
attributes.

So the memory nodes have never been about the raw hardware layout, but
rather the regions that the OS may map. If (outside of the driver
responsible for the region) the OS should not map a region of memory,
that region should not appear in any memory node.

As mentioned in my other reply, for a region that the OS could map but
cannot use, I don't see much point in listing that memory in any memory
node.

Thanks,
Mark


From computersforpeace at gmail.com  Thu Aug 27 09:47:36 2015
From: computersforpeace at gmail.com (Brian Norris)
Date: Thu, 27 Aug 2015 09:47:36 -0700
Subject: [PATCH v10 1/5] mtd: nand: vf610_nfc: Freescale NFC for VF610,
 MPC5125 and others
In-Reply-To: <a2060e9f1ad9f26e508af64549da52e7@agner.ch>
References: <1438594050-4595-1-git-send-email-stefan@agner.ch>
 <1438594050-4595-2-git-send-email-stefan@agner.ch>
 <20150825203412.GM81844@google.com>
 <a2060e9f1ad9f26e508af64549da52e7@agner.ch>
Message-ID: <20150827164736.GY81844@google.com>

On Wed, Aug 26, 2015 at 06:10:05PM -0700, Stefan Agner wrote:
> On 2015-08-25 13:34, Brian Norris wrote:
> > One more thing...
> > 
> > On Mon, Aug 03, 2015 at 11:27:26AM +0200, Stefan Agner wrote:
> >> --- /dev/null
> >> +++ b/drivers/mtd/nand/vf610_nfc.c
> >> @@ -0,0 +1,645 @@
> > ...
> >> +struct vf610_nfc {
> >> +	struct mtd_info mtd;
> >> +	struct nand_chip chip;
> >> +	struct device *dev;
> >> +	void __iomem *regs;
> >> +	struct completion cmd_done;
> >> +	uint buf_offset;
> >> +	int page_sz;
> > 
> > AFAICT (even with the 2nd patch), you never really use this field. You
> > just set it/increment it, but don't use it for anything. Kill it?
> 
> It is used in the write path, I think I meant to use it for subpage
> writes, when I thought it would just mean to transfer only parts of the
> page to the controller.

Ah, you're right. Sorry, I missed that. I got mixed up seeing most of
your uses of 'page_sz' were for a local variable of the same name, not
this field.

> However, as the subpage discussion basically concluded in not using it
> for now on this controller, we can as well transfer the complete page
> (page_sz). Or is there another case in which vf610_nfc_write_buf could
> be called with less than page_sz?

I'll leave that up to you. I'm perfectly fine leaving it in, now that I
see its proper use. Just in case things change in the future, I think it
does help to clarify the flow of information a little. Although, I might
recommend a change in naming, since it could get confused with the
actual page size -- which is normally constant -- whereas this field
changes dynamically depending on the command-in-flight.

Perhaps the struct could have 'write_len' (to help represent an action)
and the local variable in vf610_nfc_command() could be 'tfr_len' (to
distinguish how it isn't necessarily identical to 'write_len')? Just
throwing (likely bad) ideas out there.

Regards,
Brian


From robherring2 at gmail.com  Thu Aug 27 09:49:06 2015
From: robherring2 at gmail.com (Rob Herring)
Date: Thu, 27 Aug 2015 11:49:06 -0500
Subject: [PATCH 1/2] drm/layerscape: Add HDMI support for DCU DRM driver
In-Reply-To: <1440649198-27244-1-git-send-email-jianwei.wang.chn@gmail.com>
References: <1440649198-27244-1-git-send-email-jianwei.wang.chn@gmail.com>
Message-ID: <CAL_JsqJGPuZOya+UARaKkhWus2cHjr=8ByhL7WnQhMrCj7-beQ@mail.gmail.com>

On Wed, Aug 26, 2015 at 11:19 PM, Jianwei Wang
<jianwei.wang.chn at gmail.com> wrote:
> Some Freescale SoCs, there has an DVI/HDMI controller and a PHY,
> attached to one of their display controller unit's LCDC interfaces.
> This patch adds a driver for SiI902x. The SiI902x is a HDMI
> transmitter It supports resolutions from standard definition
> 480i/p and 576i/p all the way to high-definition 720p, 1080i,
> and 1080p, the highest resolution supported by HDTVs today.
>
> Signed-off-by: Alison Wang <b18965 at freescale.com>
> Signed-off-by: Xiubo Li <lixiubo at cmss.chinamobile.com>
> Signed-off-by: Jianwei Wang <jianwei.wang.chn at gmail.com>
> ---
>  .../devicetree/bindings/video/SiI902x.txt          |  17 +
>  drivers/gpu/drm/fsl-dcu/Makefile                   |   1 +
>  drivers/gpu/drm/fsl-dcu/fsl_dcu_drm_hdmi.c         | 639 +++++++++++++++++++++

This is a separate chip. It should not be part of the FSL DCU driver.

>  drivers/gpu/drm/fsl-dcu/fsl_dcu_drm_kms.c          |  10 +
>  drivers/gpu/drm/fsl-dcu/fsl_dcu_drm_output.h       |  10 +
>  5 files changed, 677 insertions(+)
>  create mode 100644 Documentation/devicetree/bindings/video/SiI902x.txt
>  create mode 100644 drivers/gpu/drm/fsl-dcu/fsl_dcu_drm_hdmi.c
>
> diff --git a/Documentation/devicetree/bindings/video/SiI902x.txt b/Documentation/devicetree/bindings/video/SiI902x.txt
> new file mode 100644
> index 0000000..d304499
> --- /dev/null
> +++ b/Documentation/devicetree/bindings/video/SiI902x.txt
> @@ -0,0 +1,17 @@
> +Device-Tree bindings for the SiI902x hdmi transmitter.
> +
> +Required properties:
> +- compatible:  Should be "sii902x".

This should have the vendor prefix sil. It should also be specific to
which chip number. There is already a binding for the 9022 in
vexpress-v2m.dtsi, so we should use the same binding although it is
not documented. I'm not too sure about the -tpi and -cpi parts of the
binding though. It appears the device has multiple i2c addresses which
is fairly common. I would not do multiple nodes like was done. If the
secondary addresses are known or programmable thru the primary
address, we can just hardcode them in the driver (ADV7511 is an
example). If we don't know the addresses, then we can just put
multiple addresses in the reg property.

Rob

> +- reg:                 The I2C address of the device.
> +- interrupts:  Interrupt number to the cpu.
> +
> +Example:
> +
> +&i2c1 {
> +       status = "okay";
> +       hdmi: sii9022a at 39 {
> +             compatible = "sii902x";
> +             reg = <0x39>;
> +             interrupts = <GIC_SPI 167 IRQ_TYPE_EDGE_RISING>;
> +       };

You should be using the OF graph to describe the connection to the DCU output.

Rob


From dianders at chromium.org  Thu Aug 27 09:52:08 2015
From: dianders at chromium.org (Doug Anderson)
Date: Thu, 27 Aug 2015 09:52:08 -0700
Subject: [PATCH v1 3/5] ARM: dts: Add arm, pl330-broken-no-flushp quirk
 for rk3288 platform
In-Reply-To: <1440685481-22163-1-git-send-email-shawn.lin@rock-chips.com>
References: <1440685419-22037-1-git-send-email-shawn.lin@rock-chips.com>
 <1440685481-22163-1-git-send-email-shawn.lin@rock-chips.com>
Message-ID: <CAD=FV=Uy8zhPnCQGcks9T-wezcRAohO8Ec3KSLn=Ftr7J1TeSA@mail.gmail.com>

Hi,

On Thu, Aug 27, 2015 at 7:24 AM, Shawn Lin <shawn.lin at rock-chips.com> wrote:
> From: Addy Ke <addy.ke at rock-chips.com>

Looks like you just added the "From" here.  I think that's fine, but
better to set the author so you get the right cover letter...


> Pl330 integrated in rk3288 platform doesn't support
> DMAFLUSHP function. So we add broken-no-flushp quirk
> for it.
>
> Signed-off-by: Addy Ke <addy.ke at rock-chips.com>
> Signed-off-by: Shawn Lin <shawn.lin at rock-chips.com>
> cc: Heiko Stuebner <heiko at sntech.de>
> cc: Doug Anderson <dianders at chromium.org>
> cc: Olof Johansson <olofj at google.com>
>
> ---
>
> Changes in v1:
> - rename broken-no-flushp to "arm,pl330-broken-no-flushp" suggested
>   by Krzysztof.
> - remove Sunny's tag

Note that typically for patches I see people go from "no v" to "v2".  AKA:
* PATCH
* PATCH v2
* PATCH v3


>  arch/arm/boot/dts/rk3288.dtsi | 3 +++
>  1 file changed, 3 insertions(+)
>
> diff --git a/arch/arm/boot/dts/rk3288.dtsi b/arch/arm/boot/dts/rk3288.dtsi
> index 22316d0..106adf7 100644
> --- a/arch/arm/boot/dts/rk3288.dtsi
> +++ b/arch/arm/boot/dts/rk3288.dtsi
> @@ -144,6 +144,7 @@
>                         #dma-cells = <1>;
>                         clocks = <&cru ACLK_DMAC2>;
>                         clock-names = "apb_pclk";
> +                       arm,pl330-broken-no-flushp;

Note that you should add bindings _before_ the usage of them.  So
patch #5 (Documentation) needs to come before this one.

>                 };
>
>                 dmac_bus_ns: dma-controller at ff600000 {
> @@ -155,6 +156,7 @@
>                         clocks = <&cru ACLK_DMAC1>;
>                         clock-names = "apb_pclk";
>                         status = "disabled";
> +                       arm,pl330-broken-no-flushp;
>                 };
>
>                 dmac_bus_s: dma-controller at ffb20000 {
> @@ -165,6 +167,7 @@
>                         #dma-cells = <1>;
>                         clocks = <&cru ACLK_DMAC1>;
>                         clock-names = "apb_pclk";
> +                       arm,pl330-broken-no-flushp;
>                 };
>         };

Other than the small nits above, this looks fine to me.

Reviewed-by: Douglas Anderson <dianders at chromium.org>


From mturquette at baylibre.com  Thu Aug 27 09:52:44 2015
From: mturquette at baylibre.com (Michael Turquette)
Date: Thu, 27 Aug 2015 09:52:44 -0700
Subject: [PATCH v3] clk: rockchip: add pclk_cpu to the list of rk3188
 critical clocks
In-Reply-To: <8804658D-175F-4668-BC12-4AC439438B61@mniewoehner.de>
References: <5400BEF8-5245-4F7B-845B-D326A7BC56B5@mniewoehner.de>
 <5275855.eah07vmf4I@phil>
 <9DBF9CCE-196E-43FB-BA76-BFB4B5F47A22@mniewoehner.de>
 <10213368.VjAQGt7Kjq@phil>
 <F5234F5E-2A91-4B63-B260-3F20A4D16A9D@mniewoehner.de>
 <20150825185931.31346.26497@quantum>
 <8804658D-175F-4668-BC12-4AC439438B61@mniewoehner.de>
Message-ID: <20150827165244.30921.8929@quantum>

Quoting Michael Niewoehner (2015-08-25 13:22:07)
> pclk_cpu needs to keep running because it is needed for devices like
> the act8865 regulator but with the recent gpio clock handling this is
> not always the case anymore. So add it to the list of critical clocks.
> 
> Signed-off-by: Michael Niewoehner <linux at mniewoehner.de>
> Reviewed-by: Heiko Stuebner <heiko at sntech.de>

Acked-by: Michael Turquette <mturquette at baylibre.com>

This patch applies cleanly to clk-next, so I guess the patch formatting
issues have been resolved ;-)

Note that I did NOT apply this to the clk tree, just locally for
testing.

Regards,
Mike

> ---
> Changes in v3:
> - fix git format-patch problem
> 
> Changes in v2:
> - adapt commit message
> - add Linus Walleij to recipients, as the patch is related to the gpio clock
>  change in the rockchip pinctrl driver it should go through his tree as well
> 
>  drivers/clk/rockchip/clk-rk3188.c | 1 +
>  1 file changed, 1 insertion(+)
> 
> diff --git a/drivers/clk/rockchip/clk-rk3188.c b/drivers/clk/rockchip/clk-rk3188.c
> index ed02bbc..f63a642 100644
> --- a/drivers/clk/rockchip/clk-rk3188.c
> +++ b/drivers/clk/rockchip/clk-rk3188.c
> @@ -716,6 +716,7 @@ static const char *const rk3188_critical_clocks[] __initconst = {
>         "aclk_cpu",
>         "aclk_peri",
>         "hclk_peri",
> +       "pclk_cpu",
>  };
>  
>  static void __init rk3188_common_clk_init(struct device_node *np)
> -- 
> 2.5.0
> 
> 
> --
> To unsubscribe from this list: send the line "unsubscribe linux-kernel" in
> the body of a message to majordomo at vger.kernel.org
> More majordomo info at  http://vger.kernel.org/majordomo-info.html
> Please read the FAQ at  http://www.tux.org/lkml/


From dianders at chromium.org  Thu Aug 27 09:53:28 2015
From: dianders at chromium.org (Doug Anderson)
Date: Thu, 27 Aug 2015 09:53:28 -0700
Subject: [PATCH v1 5/5] Documentation: arm-pl330: add description of arm,
 pl330-broken-no-flushp
In-Reply-To: <1440685505-22247-1-git-send-email-shawn.lin@rock-chips.com>
References: <1440685419-22037-1-git-send-email-shawn.lin@rock-chips.com>
 <1440685505-22247-1-git-send-email-shawn.lin@rock-chips.com>
Message-ID: <CAD=FV=W8nYeTuTZ7AB2o1sV=M-SjdwHuj1RoZ15wnKKS3NEpeQ@mail.gmail.com>

Hi,

On Thu, Aug 27, 2015 at 7:25 AM, Shawn Lin <shawn.lin at rock-chips.com> wrote:
> Signed-off-by: Shawn Lin <shawn.lin at rock-chips.com>
>
> ---
>
> Changes in v1:
> - rename broken-no-flushp to "arm,pl330-broken-no-flushp" suggested
>   by Krzysztof.
>
>  Documentation/devicetree/bindings/dma/arm-pl330.txt | 1 +
>  1 file changed, 1 insertion(+)
>
> diff --git a/Documentation/devicetree/bindings/dma/arm-pl330.txt b/Documentation/devicetree/bindings/dma/arm-pl330.txt
> index 2675658..db7e226 100644
> --- a/Documentation/devicetree/bindings/dma/arm-pl330.txt
> +++ b/Documentation/devicetree/bindings/dma/arm-pl330.txt
> @@ -15,6 +15,7 @@ Optional properties:
>      cells in the dmas property of client device.
>    - dma-channels: contains the total number of DMA channels supported by the DMAC
>    - dma-requests: contains the total number of DMA requests supported by the DMAC
> +  - arm,pl330-broken-no-flushp: quirk for avoiding to execute DMAFLUSHP

Seems fine except that it should be higher up in the list of patches...

Reviewed-by: Douglas Anderson <dianders at chromium.org>


From tony at atomide.com  Thu Aug 27 09:59:41 2015
From: tony at atomide.com (Tony Lindgren)
Date: Thu, 27 Aug 2015 09:59:41 -0700
Subject: [PATCH 2/2] memory: omap-gpmc: Add Kconfig option for debug
In-Reply-To: <OFCA2F1DCE.C787A961-ONC1257EAE.001D79BC-C1257EAE.00203AFF@br-automation.com>
References: <1432156863-19695-1-git-send-email-tony@atomide.com>
 <1432156863-19695-3-git-send-email-tony@atomide.com>
 <OFCA2F1DCE.C787A961-ONC1257EAE.001D79BC-C1257EAE.00203AFF@br-automation.com>
Message-ID: <20150827165940.GY4215@atomide.com>

Hi,

* Hannes Schmelzer <Hannes.Schmelzer at br-automation.com> [150826 22:55]:
> Hi Tony,
> 
> Did anyone test this changeset on some AM335x board?

Apparently not if it does not work or else you somehow have a different
configuration for GPMC.
 
> Today I ran into trouble with that because:
> 
> The GPMC controller gets reseted on kernel boot due to the missing/removed 
> HWMOD_INIT_NO_RESET flag.

Oh so you mean it only works on am335x if CONFIG_OMAP_GPMC_DEBUG is set?
 
> Primary this should not be a big problem, but on my board (maybe on all 
> AM335x) the GPMC doesn't behave as described in TRM.
> Especially the GPMC_CONFIG register is not reset to 0h after reset, 
> instead it holds the value 0xa00 which is very strange because bit 10-31 
> are reserved.
> 
> Further this 0xa00 means that Bit9 (WAIT1PINPOLARITY) is set, exactly this 
> causes my system to stall on first access the connected NAND flash because 
> it never becomes ready due to the wrong wait pin polarity. Maybe others 
> dont't run into trouble because they may use WAIT0PIN, which one has it's 
> old polarity.
> 
> First approach was simply to write 0x0 to the GPMC_CONFIG register during 
> gpmc_probe function.
> It solves the problem.

OK
 
> I also tried to issue some SYSRESET through GPMC registers without 
> success, same strange behavior.

Interesting, never heard of that one before.
 
> What?s your thinking around that?

We could add a custom hwmod reset function that sets GPMC_CONFIG to 0.
Similar to omap_i2c_reset() is set up. Or we could set up a property for
the wait pin polarity. Roger, got any better ideas?

Regards,

Tony


From agross at codeaurora.org  Thu Aug 27 10:01:23 2015
From: agross at codeaurora.org (Andy Gross)
Date: Thu, 27 Aug 2015 12:01:23 -0500
Subject: [PATCH v3] soc: qcom: smd: Use correct remote processor ID
Message-ID: <1440694883-22685-1-git-send-email-agross@codeaurora.org>

This patch fixes SMEM addressing issues when remote processors need to use
secure SMEM partitions.

Signed-off-by: Andy Gross <agross at codeaurora.org>
Reviewed-by: Bjorn Andersson <bjorn.andersson at sonymobile.com>
---
 .../devicetree/bindings/soc/qcom/qcom,smd.txt      |    6 ++++++
 drivers/soc/qcom/smd.c                             |   16 ++++++++++++----
 2 files changed, 18 insertions(+), 4 deletions(-)

diff --git a/Documentation/devicetree/bindings/soc/qcom/qcom,smd.txt b/Documentation/devicetree/bindings/soc/qcom/qcom,smd.txt
index f65c76d..97d9b3e 100644
--- a/Documentation/devicetree/bindings/soc/qcom/qcom,smd.txt
+++ b/Documentation/devicetree/bindings/soc/qcom/qcom,smd.txt
@@ -37,6 +37,12 @@ The edge is described by the following properties:
 	Definition: the identifier of the remote processor in the smd channel
 		    allocation table
 
+- qcom,remote-pid:
+	Usage: optional
+	Value type: <u32>
+	Definition: the identifier for the remote processor as known by the rest
+		    of the system.
+
 = SMD DEVICES
 
 In turn, subnodes of the "edges" represent devices tied to SMD channels on that
diff --git a/drivers/soc/qcom/smd.c b/drivers/soc/qcom/smd.c
index 327adcf..edd9d9a 100644
--- a/drivers/soc/qcom/smd.c
+++ b/drivers/soc/qcom/smd.c
@@ -96,6 +96,7 @@ static const struct {
  * @smd:		handle to qcom_smd
  * @of_node:		of_node handle for information related to this edge
  * @edge_id:		identifier of this edge
+ * @remote_pid:		identifier of remote processor
  * @irq:		interrupt for signals on this edge
  * @ipc_regmap:		regmap handle holding the outgoing ipc register
  * @ipc_offset:		offset within @ipc_regmap of the register for ipc
@@ -111,6 +112,7 @@ struct qcom_smd_edge {
 	struct qcom_smd *smd;
 	struct device_node *of_node;
 	unsigned edge_id;
+	unsigned remote_pid;
 
 	int irq;
 
@@ -572,7 +574,7 @@ static irqreturn_t qcom_smd_edge_intr(int irq, void *data)
 	 * have to scan if the amount of available space in smem have changed
 	 * since last scan.
 	 */
-	available = qcom_smem_get_free_space(edge->edge_id);
+	available = qcom_smem_get_free_space(edge->remote_pid);
 	if (available != edge->smem_available) {
 		edge->smem_available = available;
 		edge->need_rescan = true;
@@ -976,7 +978,8 @@ static struct qcom_smd_channel *qcom_smd_create_channel(struct qcom_smd_edge *ed
 	spin_lock_init(&channel->recv_lock);
 	init_waitqueue_head(&channel->fblockread_event);
 
-	ret = qcom_smem_get(edge->edge_id, smem_info_item, (void **)&info, &info_size);
+	ret = qcom_smem_get(edge->remote_pid, smem_info_item, (void **)&info,
+			    &info_size);
 	if (ret)
 		goto free_name_and_channel;
 
@@ -997,7 +1000,8 @@ static struct qcom_smd_channel *qcom_smd_create_channel(struct qcom_smd_edge *ed
 		goto free_name_and_channel;
 	}
 
-	ret = qcom_smem_get(edge->edge_id, smem_fifo_item, &fifo_base, &fifo_size);
+	ret = qcom_smem_get(edge->remote_pid, smem_fifo_item, &fifo_base,
+			    &fifo_size);
 	if (ret)
 		goto free_name_and_channel;
 
@@ -1041,7 +1045,7 @@ static void qcom_discover_channels(struct qcom_smd_edge *edge)
 	int i;
 
 	for (tbl = 0; tbl < SMD_ALLOC_TBL_COUNT; tbl++) {
-		ret = qcom_smem_get(edge->edge_id,
+		ret = qcom_smem_get(edge->remote_pid,
 				    smem_items[tbl].alloc_tbl_id,
 				    (void **)&alloc_tbl,
 				    NULL);
@@ -1184,6 +1188,10 @@ static int qcom_smd_parse_edge(struct device *dev,
 		return -EINVAL;
 	}
 
+	edge->remote_pid = QCOM_SMEM_HOST_ANY;
+	key = "qcom,remote-pid";
+	of_property_read_u32(node, key, &edge->remote_pid);
+
 	syscon_np = of_parse_phandle(node, "qcom,ipc", 0);
 	if (!syscon_np) {
 		dev_err(dev, "no qcom,ipc node\n");
-- 
The Qualcomm Innovation Center, Inc. is a member of the Code Aurora Forum,
hosted by The Linux Foundation



From grygorii.strashko at ti.com  Thu Aug 27 10:06:32 2015
From: grygorii.strashko at ti.com (Grygorii Strashko)
Date: Thu, 27 Aug 2015 20:06:32 +0300
Subject: [PATCH] ARM: OMAP2+: omap-device: remove omap_device_late_init
 call completely
In-Reply-To: <20150827163856.GX4215@atomide.com>
References: <1440611890-4935-1-git-send-email-grygorii.strashko@ti.com>
 <20150826181006.GT4215@atomide.com> <55DF12E7.10802@ti.com>
 <20150827163856.GX4215@atomide.com>
Message-ID: <55DF4398.7020201@ti.com>

On 08/27/2015 07:38 PM, Tony Lindgren wrote:
> * Grygorii Strashko <grygorii.strashko at ti.com> [150827 06:42]:
>> Hi Tony,
>>
>> On 08/26/2015 09:10 PM, Tony Lindgren wrote:
>>> * Grygorii Strashko <grygorii.strashko at ti.com> [150826 11:01]:
>>>> Now Kernel fails to boot 50% of times (form build to build) with
>>>> RT-patchset applied due to the following race - on late boot
>>>> stages deferred_probe_work_func races with omap_device_late_ini
>>>>
>>>> late_initcall
>>>>    - deferred_probe_initcal() tries to re-probe all pending driver's probe.
>>>>      [In general, It's NOT expected to probe any other built-in drivers after
>>>>      deferred_probe_initcal() is finished, because most of
>>>>      late_initcall_sync/late_initcall functions expected that all driver
>>>>      or probed or deferred already.]
>>>>
>>>> - later on, some driver is probing in this case It's could cpsw.c
>>>>     (but could be any other drivers)
>>>>     cpsw_init
>>>>     - platform_driver_register
>>>>       - really_probe
>>>>          - driver_bound
>>>>            - driver_deferred_probe_trigger
>>>>     and boot proceed.
>>>>     So, at this moment we have  deferred_probe_work_func scheduled.
>>>>
>>>> late_initcall_sync
>>>>     - omap_device_late_init
>>>>       - omap_device_idle
>>>>
>>>> CPU1					CPU2
>>>>     - deferred_probe_work_func
>>>>       - really_probe
>>>>         - omap_hsmmc_probe
>>>> 	- pm_runtime_get_sync
>>>> 					late_initcall_sync
>>>> 					- omap_device_late_init
>>>> 						if (od->_driver_status != BUS_NOTIFY_BOUND_DRIVER) {
>>>> 							if (od->_state == OMAP_DEVICE_STATE_ENABLED) {
>>>> 								- omap_device_idle [ops - IP is disabled, ]
>>>> 	- [fail]
>>>> 	- pm_runtime_put_sync
>>>>             - omap_hsmmc_runtime_suspend [ooops!]
>>>
>>> OK idling of unclaimed devices should not happen for deferred probe,
>>> it should only happen when there's no driver and no probing happening.
>>>    
>>>> Lets remove just remove omap_device_late_init completely as suggested
>>>> by Tero Kristo:
>>>>
>>>> "How about remove omap_device_late_init call completely. I don't think
>>>> it does anything useful at the moment; none of the omap devices get
>>>> enabled outside runtime_pm, so there should be no need to explicitly
>>>> disable the devices."
>>>
>>> I think this is still needed from PM point of view as otherwise we
>>> don't idle any devices that don't have a driver available. Or am I
>>> missing something?
>>>
>>> To me it seems the bug is relying on the BUS_NOTIFY_BOUND_DRIVER is
>>> not set in the deferred probe case.
>>>
>>
>>
>> What do you think about below alternative?
>>
>> diff --git a/arch/arm/mach-omap2/omap_device.c b/arch/arm/mach-omap2/omap_device.c
>> index 4cb8fd9..72ebc4c 100644
>> --- a/arch/arm/mach-omap2/omap_device.c
>> +++ b/arch/arm/mach-omap2/omap_device.c
>> @@ -901,7 +901,8 @@ static int __init omap_device_late_idle(struct device *dev, void *data)
>>                  if (od->hwmods[i]->flags & HWMOD_INIT_NO_IDLE)
>>                          return 0;
>>   
>> -       if (od->_driver_status != BUS_NOTIFY_BOUND_DRIVER) {
>> +       if (od->_driver_status != BUS_NOTIFY_BOUND_DRIVER &&
>> +           od->_driver_status != BUS_NOTIFY_BIND_DRIVER) {
>>                  if (od->_state == OMAP_DEVICE_STATE_ENABLED) {
>>                          dev_warn(dev, "%s: enabled but no driver.  Idling\n",
>>                                   __func__);
> 
> Seems better to me if it really fixes the issue.
> 

My dra7-evm failed to boot on "2b186e5 Add linux-next specific files for 20150827"
and this change restores boot.

Will wait for confirmation from Keerthy.


-- 
regards,
-grygorii


From stefan at agner.ch  Thu Aug 27 10:25:15 2015
From: stefan at agner.ch (Stefan Agner)
Date: Thu, 27 Aug 2015 10:25:15 -0700
Subject: [PATCH v10 1/5] mtd: nand: vf610_nfc: Freescale NFC for VF610,
 MPC5125 and others
In-Reply-To: <20150827163421.GX81844@google.com>
References: <1438594050-4595-1-git-send-email-stefan@agner.ch>
 <1438594050-4595-2-git-send-email-stefan@agner.ch>
 <20150825201631.GK81844@google.com>
 <bf1ed158fe08b51c4668faffde44083f@agner.ch>
 <20150827163421.GX81844@google.com>
Message-ID: <9ccab0ac37e59f58b16718708653d7ea@agner.ch>

On 2015-08-27 09:34, Brian Norris wrote:
> On Wed, Aug 26, 2015 at 06:02:31PM -0700, Stefan Agner wrote:
>> On 2015-08-25 13:16, Brian Norris wrote:
>> > On Mon, Aug 03, 2015 at 11:27:26AM +0200, Stefan Agner wrote:
>> >> diff --git a/drivers/mtd/nand/vf610_nfc.c b/drivers/mtd/nand/vf610_nfc.c
>> >> new file mode 100644
>> >> index 0000000..5c8dfe8
>> >> --- /dev/null
>> >> +++ b/drivers/mtd/nand/vf610_nfc.c
>> >> @@ -0,0 +1,645 @@
>> >
>> > ...
>> >
>> >> +/*
>> >> + * This function supports Vybrid only (MPC5125 would have full RB and four CS)
>> >> + */
>> >> +static void vf610_nfc_select_chip(struct mtd_info *mtd, int chip)
>> >> +{
>> >> +#ifdef CONFIG_SOC_VF610
>> >
>> > Why the #ifdef? I don't see anything compile-time specific to SOC_VF610.
>> >
>> > If this is trying to handle the comment above ("This function supports
>> > Vybrid only (MPC5125 would have full RB and four CS)") then that's the
>> > wrong way of doing it, as you need to support multiplatform kernels.
>> > You'll need to have a way to differentiate the different platform
>> > support at runtime, not compile time.
>>
>> Yes it is trying to handle the comment above. Well, the other two
>> platforms I am aware of are also different architectures... (PowerPC and
>> ColdFire). I think we won't have a multi-architecture kernel anytime
>> soon,
> 
> Ha, right. Sorry, I don't really know this particular IP.
> 
>> hence I think removing the code at compile time is the right thing
>> todo.
> 
> I don't believe that conclusion follows though.
> 
>> However, probably CONFIG_SOC_VF610 is the wrong symbol then, I could
>> just use CONFIG_ARM and add a comment that this might be different on
>> another other ARM SoC than VF610.
>>
>> Just checked CodingStyle, and I see that IS_ENABLED is the preferred way
>> for conditional compiling.
>>
>> So my suggestion:
>>
>> static void vf610_nfc_select_chip(struct mtd_info *mtd, int chip)
>> {
>> 	struct vf610_nfc *nfc = mtd_to_nfc(mtd);
>> 	u32 tmp = vf610_nfc_read(nfc, NFC_ROW_ADDR);
>>
>> 	if (!IS_ENABLED(CONFIG_ARM))
>> 		return;
>>
>> 	/*
>> 	 * This code is only tested on the ARM platform VF610
>> 	 * PowerPC based MPC5125 would have full RB and four CS
>> 	 */
>> ....
>>
>> With that the compiler should be able to remove this (currently) ARM
>> VF610 specific code on the other supported architectures...
>>
>> What do you think?
> 
> The code structure isn't bad, and yes, IS_ENABLED() would be preferable,
> as it removes some of the problems with #ifdef, but I still don't think
> the processor architecture has much to do with the version of the IP.

Well yes, the processor architecture has probably not much to do with
the IP version.

However, that particular problem, the wiring up of the CS/RB signals, is
probably more SoC (as a whole) specific, and how that is done might have
some relation which architecture is in use...

I do not have a strong opinion on this, so we might as well go with the
run-time distinction using compatible. If there are different IP
variants within one architecture, we anyway would need to do that.

> The canonical way of distiguishing per-IP revisions is to key on the
> compatible property. So you'd have some kind of enum, which would
> currently only have an entry for VF610. i.e.:
> 
> 	/* MPC5125 not yet supported */
> 	if (nfc->revision != NAND_VFC610)
> 		return;
> 

Ok, just checked, I can use the data field of the of table to assign
specific data to a compatible string, similar to how pxa3xx_nand.c does
it.

--
Stefan


From rabin at rab.in  Thu Aug 27 10:26:48 2015
From: rabin at rab.in (Rabin Vincent)
Date: Thu, 27 Aug 2015 19:26:48 +0200
Subject: [PATCH] arm: insn: use set_fixmap_offset to make it more clear
In-Reply-To: <1440552266-19940-1-git-send-email-yalin.wang2010@gmail.com>
References: <1440552266-19940-1-git-send-email-yalin.wang2010@gmail.com>
Message-ID: <20150827172605.GA5251@debian>

On Wed, Aug 26, 2015 at 09:24:26AM +0800, yalin wang wrote:
> A little change to patch_map() function,
> use set_fixmap_offset() to make code more clear.
> 
> Signed-off-by: yalin wang <yalin.wang2010 at gmail.com>
> ---
>  arch/arm/kernel/patch.c | 5 ++---
>  1 file changed, 2 insertions(+), 3 deletions(-)
> 
> diff --git a/arch/arm/kernel/patch.c b/arch/arm/kernel/patch.c
> index 69bda1a..5779105 100644
> --- a/arch/arm/kernel/patch.c
> +++ b/arch/arm/kernel/patch.c
> @@ -36,9 +36,8 @@ static void __kprobes *patch_map(void *addr, int fixmap, unsigned long *flags)
>  	else
>  		__acquire(&patch_lock);
>  
> -	set_fixmap(fixmap, page_to_phys(page));
> -
> -	return (void *) (__fix_to_virt(fixmap) + (uintaddr & ~PAGE_MASK));
> +	return (void *)set_fixmap_offset(fixmap, page_to_phys(page) +
> +			(uintaddr & ~PAGE_MASK));
>  }

Perhaps a temporary variable to make it clearerer?  Something like this:

diff --git a/arch/arm/kernel/patch.c b/arch/arm/kernel/patch.c
index 69bda1a..0b8e594 100644
--- a/arch/arm/kernel/patch.c
+++ b/arch/arm/kernel/patch.c
@@ -23,6 +23,7 @@ static void __kprobes *patch_map(void *addr, int fixmap, unsigned long *flags)
 	unsigned int uintaddr = (uintptr_t) addr;
 	bool module = !core_kernel_text(uintaddr);
 	struct page *page;
+	phys_addr_t phys;
 
 	if (module && IS_ENABLED(CONFIG_DEBUG_SET_MODULE_RONX))
 		page = vmalloc_to_page(addr);
@@ -36,9 +37,8 @@ static void __kprobes *patch_map(void *addr, int fixmap, unsigned long *flags)
 	else
 		__acquire(&patch_lock);
 
-	set_fixmap(fixmap, page_to_phys(page));
-
-	return (void *) (__fix_to_virt(fixmap) + (uintaddr & ~PAGE_MASK));
+	phys = page_to_phys(page) + (uintaddr & ~PAGE_MASK);
+	return (void *) set_fixmap_offset(fixmap, phys);
 }
 
 static void __kprobes patch_unmap(int fixmap, unsigned long *flags)


From pratyush.anand at gmail.com  Thu Aug 27 10:31:16 2015
From: pratyush.anand at gmail.com (Pratyush Anand)
Date: Thu, 27 Aug 2015 23:01:16 +0530
Subject: [PATCH v4 3/4] PCI: st: Provide support for the sti PCIe
 controller
In-Reply-To: <1440678857-27118-4-git-send-email-gabriel.fernandez@linaro.org>
References: <1440678857-27118-1-git-send-email-gabriel.fernandez@linaro.org>
 <1440678857-27118-4-git-send-email-gabriel.fernandez@linaro.org>
Message-ID: <CAHM4w1=g=UFoz=R-6hxJC0=fSieN1WDvZT97ykL1b3_YPhBjZg@mail.gmail.com>

Hi Gabriel,

Looks good to me.

On Thu, Aug 27, 2015 at 6:04 PM, Gabriel Fernandez
<gabriel.fernandez at linaro.org> wrote:
> sti pcie is built around a Synopsis Designware PCIe IP.
>
> Signed-off-by: Fabrice Gasnier <fabrice.gasnier at st.com>
> Signed-off-by: Gabriel Fernandez <gabriel.fernandez at linaro.org>


> +static int st_pcie_link_up(struct pcie_port *pp)
> +{
> +       u32 status;
> +       int link_up;

nit: why not bool

> +       int count = 0;

[...]

> +static void st_pcie_board_reset(struct pcie_port *pp)
> +{
> +       struct st_pcie *pcie = to_st_pcie(pp);
> +
> +       if (!gpio_is_valid(pcie->reset_gpio))
> +               return;
> +
> +       if (gpio_direction_output(pcie->reset_gpio, 0)) {
> +               dev_err(pp->dev, "Cannot set PERST# (gpio %u) to output\n",
> +                       pcie->reset_gpio);
> +               return;
> +       }
> +
> +       /* From PCIe spec */
> +       msleep(2);
> +       gpio_direction_output(pcie->reset_gpio, 1);
> +
> +       /*
> +        * PCIe specification states that you should not issue any config
> +        * requests until 100ms after asserting reset, so we enforce that here
> +        */
> +       msleep(100);

IIRC, specification says to wait after link training completes. So
shouldn't it be after st_pcie_enable_ltssm. Moreover, I wonder why
others do not need it.

Reviewed-by: Pratyush Anand <pratyush.anand at gmail.com>


From heiko at sntech.de  Thu Aug 27 10:59:08 2015
From: heiko at sntech.de (Heiko Stuebner)
Date: Thu, 27 Aug 2015 19:59:08 +0200
Subject: [PATCH] ARM: dts: rockchip: Add support for SD/MMC on
 MarsBoard-RK3066
In-Reply-To: <110804682.VHnft3L4vc@phil>
References: <1440432281-491-1-git-send-email-romain.perier@gmail.com>
 <110804682.VHnft3L4vc@phil>
Message-ID: <1510107.CgsiuXuzAt@phil>

Am Montag, 24. August 2015, 19:21:53 schrieb Heiko Stuebner:
> Am Montag, 24. August 2015, 18:04:41 schrieb Romain Perier:
> > This enables SDMMC0 on the board and gives a basic support for SD cards.
> > 
> > Signed-off-by: Romain Perier <romain.perier at gmail.com>
> 
> applied to my dts branch, after moving it above the "&pinctrl" node

just as notice, this moved down to linux-4.4 material


From will.deacon at arm.com  Thu Aug 27 11:02:44 2015
From: will.deacon at arm.com (Will Deacon)
Date: Thu, 27 Aug 2015 19:02:44 +0100
Subject: [GIT PULL] Late arm64 KVM fix for 4.2
Message-ID: <20150827180244.GE23520@arm.com>

Hi Linus,

I appreciate that it's extremely late in the cycle, but we've uncovered
a nasty bug in the arm64 KVM code which allows a badly behaved 32-bit
guest to bring down the host. The fix is simple (it's what I believe we
call a "brown paper bag" bug) and I don't think it makes sense to sit on
this, particularly as Russell ended up triggering this rather than just
somebody noticing a potential problem by inspection.

Usually arm64 KVM changes would go via Paolo's tree, but he's on holiday
at the moment and the deal is that anything urgent gets shuffled via
the arch trees, so here it is. Please pull.

Cheers,

Will

--->8

The following changes since commit c13dcf9f2d6f5f06ef1bf79ec456df614c5e058b:

  Linux 4.2-rc8 (2015-08-23 20:52:59 -0700)

are available in the git repository at:

  git://git.kernel.org/pub/scm/linux/kernel/git/arm64/linux.git tags/arm64-fixes

for you to fetch changes up to 126c69a0bd0e441bf6766a5d9bf20de011be9f68:

  arm64: KVM: Fix host crash when injecting a fault into a 32bit guest (2015-08-27 16:16:55 +0100)

----------------------------------------------------------------
Urgent arm64 KVM fix for 4.2:

Fix arm64 KVM issue when injecting an abort into a 32-bit guest, which
would lead to an illegal exception return at EL2 and a subsequent host
crash.

----------------------------------------------------------------
Marc Zyngier (1):
      arm64: KVM: Fix host crash when injecting a fault into a 32bit guest

 arch/arm64/kvm/inject_fault.c | 12 ++++++------
 1 file changed, 6 insertions(+), 6 deletions(-)


From m-karicheri2 at ti.com  Thu Aug 27 11:23:05 2015
From: m-karicheri2 at ti.com (Murali Karicheri)
Date: Thu, 27 Aug 2015 14:23:05 -0400
Subject: [PATCH] soc: ti: reset irq affinity before freeing irq
In-Reply-To: <55DF3E3F.6030506@mentor.com>
References: <1440690671-1029-1-git-send-email-m-karicheri2@ti.com>
 <55DF3E3F.6030506@mentor.com>
Message-ID: <55DF5589.6050802@ti.com>

On 08/27/2015 12:43 PM, Nathan Lynch wrote:
> On 08/27/2015 10:51 AM, Murali Karicheri wrote:
>> When using accumulator queue for rx side for network driver, following
>> warning is seen when doing a reboot command from Linux console. This
>> is because, affinity value is not reset before calling free_irq(). This
>> patch fixes this.
>>
>> Deconfiguring network interfaces...
>> [   55.176589] ------------[ cut here ]-----------
>> [   55.181232] WARNING: CPU: 0 PID: 2081 at kernel/irq/manage.c:1370
>> __free_irq+0x208/0x214
>
> The full content of the warning should be included in the commit
> message; __free_irq has several potential sources of warning messages,
> and line 1370 doesn't correspond to any of them in 4.2-rc8.

The log corresponds to 4.1.x kernel. Corresponding WARN_ONCE is

#ifdef CONFIG_SMP
         /* make sure affinity_hint is cleaned up */
         if (WARN_ON_ONCE(desc->affinity_hint))
                 desc->affinity_hint = NULL;
#endif

Which is line 1922. I can edit to make it 1922. Does that work?

Murali
>
>
>> Signed-off-by: Murali Karicheri <m-karicheri2 at ti.com>
>> ---
>>   - Applies to v4.2.0-rc8
>>
>>   drivers/soc/ti/knav_qmss_acc.c | 4 ++++
>>   1 file changed, 4 insertions(+)
>>
>> diff --git a/drivers/soc/ti/knav_qmss_acc.c b/drivers/soc/ti/knav_qmss_acc.c
>> index ef6f69d..b98fe56 100644
>> --- a/drivers/soc/ti/knav_qmss_acc.c
>> +++ b/drivers/soc/ti/knav_qmss_acc.c
>> @@ -261,6 +261,10 @@ static int knav_range_setup_acc_irq(struct knav_range_info *range,
>>   	if (old && !new) {
>>   		dev_dbg(kdev->dev, "setup-acc-irq: freeing %s for channel %s\n",
>>   			acc->name, acc->name);
>> +		ret = irq_set_affinity_hint(irq, NULL);
>> +		if (ret)
>> +			dev_warn(range->kdev->dev,
>> +				 "Failed to set IRQ affinity\n");
>
> Seems unnecessary to add a warning here.
>
>


-- 
Murali Karicheri
Linux Kernel, Keystone


From Nathan_Lynch at mentor.com  Thu Aug 27 11:34:02 2015
From: Nathan_Lynch at mentor.com (Nathan Lynch)
Date: Thu, 27 Aug 2015 13:34:02 -0500
Subject: [PATCH] soc: ti: reset irq affinity before freeing irq
In-Reply-To: <55DF5589.6050802@ti.com>
References: <1440690671-1029-1-git-send-email-m-karicheri2@ti.com>
 <55DF3E3F.6030506@mentor.com> <55DF5589.6050802@ti.com>
Message-ID: <55DF581A.2090300@mentor.com>

On 08/27/2015 01:23 PM, Murali Karicheri wrote:
> On 08/27/2015 12:43 PM, Nathan Lynch wrote:
>> On 08/27/2015 10:51 AM, Murali Karicheri wrote:
>>> When using accumulator queue for rx side for network driver, following
>>> warning is seen when doing a reboot command from Linux console. This
>>> is because, affinity value is not reset before calling free_irq(). This
>>> patch fixes this.
>>>
>>> Deconfiguring network interfaces...
>>> [   55.176589] ------------[ cut here ]-----------
>>> [   55.181232] WARNING: CPU: 0 PID: 2081 at kernel/irq/manage.c:1370
>>> __free_irq+0x208/0x214
>>
>> The full content of the warning should be included in the commit
>> message; __free_irq has several potential sources of warning messages,
>> and line 1370 doesn't correspond to any of them in 4.2-rc8.
> 
> The log corresponds to 4.1.x kernel. Corresponding WARN_ONCE is
> 
> #ifdef CONFIG_SMP
>         /* make sure affinity_hint is cleaned up */
>         if (WARN_ON_ONCE(desc->affinity_hint))
>                 desc->affinity_hint = NULL;
> #endif
> 
> Which is line 1922. I can edit to make it 1922. Does that work?

Eh, I guess I wasn't thinking clearly about this clearly when I wrote
that.  (I somehow had the notion that WARN_ON... maybe printed more than
just the file and line number, but that is clearly mistaken.)  I think
your message is fine as is, sorry for the noise.

I don't think changing the line number will make it any easier on future
readers.



From santosh.shilimkar at oracle.com  Thu Aug 27 11:36:16 2015
From: santosh.shilimkar at oracle.com (santosh.shilimkar at oracle.com)
Date: Thu, 27 Aug 2015 11:36:16 -0700
Subject: [PATCH] soc: ti: reset irq affinity before freeing irq
In-Reply-To: <55DF581A.2090300@mentor.com>
References: <1440690671-1029-1-git-send-email-m-karicheri2@ti.com>
 <55DF3E3F.6030506@mentor.com> <55DF5589.6050802@ti.com>
 <55DF581A.2090300@mentor.com>
Message-ID: <55DF58A0.8090105@oracle.com>

On 8/27/15 11:34 AM, Nathan Lynch wrote:
> On 08/27/2015 01:23 PM, Murali Karicheri wrote:
>> On 08/27/2015 12:43 PM, Nathan Lynch wrote:
>>> On 08/27/2015 10:51 AM, Murali Karicheri wrote:
>>>> When using accumulator queue for rx side for network driver, following
>>>> warning is seen when doing a reboot command from Linux console. This
>>>> is because, affinity value is not reset before calling free_irq(). This
>>>> patch fixes this.
>>>>
>>>> Deconfiguring network interfaces...
>>>> [   55.176589] ------------[ cut here ]-----------
>>>> [   55.181232] WARNING: CPU: 0 PID: 2081 at kernel/irq/manage.c:1370
>>>> __free_irq+0x208/0x214
>>>
>>> The full content of the warning should be included in the commit
>>> message; __free_irq has several potential sources of warning messages,
>>> and line 1370 doesn't correspond to any of them in 4.2-rc8.
>>
>> The log corresponds to 4.1.x kernel. Corresponding WARN_ONCE is
>>
>> #ifdef CONFIG_SMP
>>          /* make sure affinity_hint is cleaned up */
>>          if (WARN_ON_ONCE(desc->affinity_hint))
>>                  desc->affinity_hint = NULL;
>> #endif
>>
>> Which is line 1922. I can edit to make it 1922. Does that work?
>
> Eh, I guess I wasn't thinking clearly about this clearly when I wrote
> that.  (I somehow had the notion that WARN_ON... maybe printed more than
> just the file and line number, but that is clearly mistaken.)  I think
> your message is fine as is, sorry for the noise.
>
> I don't think changing the line number will make it any easier on future
> readers.
>
Right. Just leave the full call in the commit so that the context
is captured.


From hdegoede at redhat.com  Thu Aug 27 11:37:31 2015
From: hdegoede at redhat.com (Hans de Goede)
Date: Thu, 27 Aug 2015 20:37:31 +0200
Subject: [PATCH] ARM: dts: sun5i: inet98v_rev2 fix regulator for the usb wifi
 module
In-Reply-To: <1440700651-30575-1-git-send-email-hdegoede@redhat.com>
References: <1440700651-30575-1-git-send-email-hdegoede@redhat.com>
Message-ID: <1440700651-30575-2-git-send-email-hdegoede@redhat.com>

The usb-wifi module is not connected to a gpio controller regulator
(as is typical on sunxi boards), instead is it connected to ldo3.

This commit fixes the us_phy usb1_vbus-supply setting thereby making
sure that we power the usb-wifi and that it can be used.

This commit also removes the wrong and now unused bits which refer to
the gpio controlled reg_usb1_vbus.

Signed-off-by: Hans de Goede <hdegoede at redhat.com>
---
 arch/arm/boot/dts/sun5i-a13-inet-98v-rev2.dts | 11 +----------
 1 file changed, 1 insertion(+), 10 deletions(-)

diff --git a/arch/arm/boot/dts/sun5i-a13-inet-98v-rev2.dts b/arch/arm/boot/dts/sun5i-a13-inet-98v-rev2.dts
index 6d466a2..6fa54b6 100644
--- a/arch/arm/boot/dts/sun5i-a13-inet-98v-rev2.dts
+++ b/arch/arm/boot/dts/sun5i-a13-inet-98v-rev2.dts
@@ -201,11 +201,6 @@
 	status = "okay";
 };
 
-&reg_usb1_vbus {
-	gpio = <&pio 6 11 GPIO_ACTIVE_HIGH>; /* PG11 */
-	status = "okay";
-};
-
 &uart1 {
 	pinctrl-names = "default";
 	pinctrl-0 = <&uart1_pins_b>;
@@ -221,16 +216,12 @@
 	allwinner,pins = "PG12";
 };
 
-&usb1_vbus_pin_a {
-	allwinner,pins = "PG11";
-};
-
 &usbphy {
 	pinctrl-names = "default";
 	pinctrl-0 = <&usb0_id_detect_pin>, <&usb0_vbus_detect_pin>;
 	usb0_id_det-gpio = <&pio 6 2 GPIO_ACTIVE_HIGH>; /* PG2 */
 	usb0_vbus_det-gpio = <&pio 6 1 GPIO_ACTIVE_HIGH>; /* PG1 */
 	usb0_vbus-supply = <&reg_usb0_vbus>;
-	usb1_vbus-supply = <&reg_usb1_vbus>;
+	usb1_vbus-supply = <&reg_ldo3>;
 	status = "okay";
 };
-- 
2.4.3



From hdegoede at redhat.com  Thu Aug 27 11:37:30 2015
From: hdegoede at redhat.com (Hans de Goede)
Date: Thu, 27 Aug 2015 20:37:30 +0200
Subject: [PATCH 0/1] ARM: dts: sun5i: inet98v_rev2 fix regulator for the usb
 wifi
Message-ID: <1440700651-30575-1-git-send-email-hdegoede@redhat.com>

Hi Maxime,

Here is a fixup patch for the patch adding a dts for the inet98v_rev2.

I'm not sure if you've merged the original patch yet, hence I'm sending
this as a follow-up patch. If you've not yet merged the original patch
feel free to squash this fix in.

Regards,

Hans


From broonie at kernel.org  Thu Aug 27 11:45:26 2015
From: broonie at kernel.org (Mark Brown)
Date: Thu, 27 Aug 2015 19:45:26 +0100
Subject: [PATCH-v3 1/2] mfd: devicetree: bindings: 88pm800: Add DT
 property for dual phase enable
In-Reply-To: <55DB3012.6010904@linaro.org>
References: <1440420006-31556-1-git-send-email-vaibhav.hiremath@linaro.org>
 <1440420006-31556-2-git-send-email-vaibhav.hiremath@linaro.org>
 <20150824130205.GE3237@x1> <55DB3012.6010904@linaro.org>
Message-ID: <20150827184526.GJ5313@sirena.org.uk>

On Mon, Aug 24, 2015 at 08:24:10PM +0530, Vaibhav Hiremath wrote:

> Mark,

> Any comments here before I spin V4.

Please just resubmit things, seeing that a change was requested is
usually a good indication that a new version is incoming.
-------------- next part --------------
A non-text attachment was scrubbed...
Name: signature.asc
Type: application/pgp-signature
Size: 473 bytes
Desc: Digital signature
URL: <http://lists.infradead.org/pipermail/linux-arm-kernel/attachments/20150827/5eb1b350/attachment.sig>

From sboyd at codeaurora.org  Thu Aug 27 11:53:10 2015
From: sboyd at codeaurora.org (Stephen Boyd)
Date: Thu, 27 Aug 2015 11:53:10 -0700
Subject: [PATCH] clk: at91: add audio pll clock driver
In-Reply-To: <20150827113035.072cccb5@bbrezillon>
References: <1438337864-27949-1-git-send-email-nicolas.ferre@atmel.com>
 <20150827113035.072cccb5@bbrezillon>
Message-ID: <20150827185310.GV19120@codeaurora.org>

On 08/27, Boris Brezillon wrote:
> Nicolas Ferre <nicolas.ferre at atmel.com> wrote:
> > +
> > +static long clk_audio_pll_pad_round_rate(struct clk_hw *hw, unsigned long rate,
> > +					 unsigned long *parent_rate)
> 
> I thought we were trying to get rid of the ->round_rate() function in
> favor of the ->determine_rate() one (which is more flexible), but maybe
> I'm wrong. Stephen, Mike, what's your opinion?

I'm not opposed to people using ->round_rate() if they want to
use it and it serves their purpose. Moving everyone to
->determine_rate() will be a long journey that has little to no
benefit for most drivers, so it's not like we need to force
everyone to use the determine rate op for new submissions so that
we can delete the round rate op one day.

-- 
Qualcomm Innovation Center, Inc. is a member of Code Aurora Forum,
a Linux Foundation Collaborative Project


From holler at ahsoftware.de  Thu Aug 27 12:01:16 2015
From: holler at ahsoftware.de (Alexander Holler)
Date: Thu, 27 Aug 2015 21:01:16 +0200
Subject: [PATCH 00/16] deps: deterministic driver initialization order
In-Reply-To: <1440592108-3740-1-git-send-email-holler@ahsoftware.de>
References: <1440592108-3740-1-git-send-email-holler@ahsoftware.de>
Message-ID: <55DF5E7C.8030806@ahsoftware.de>

Am 26.08.2015 um 14:28 schrieb Alexander Holler:

> The final 2 patches are fixes which should end up in mainline, regardless
> if this feature is merged or not.

Just in case your serial or MTD-NAND partitions don't work, the drivers
drivers/tty/serial/8250/8250_core.c and drivers/mtd/ofpart.c need the 
same trivial fix for their initcall level as found in the last two 
patches of my series. I'm not going to post these patches now until I've 
got some feedback for the other stuff.

Regards,

Alexander Holler


From robh at kernel.org  Thu Aug 27 12:07:03 2015
From: robh at kernel.org (Rob Herring)
Date: Thu, 27 Aug 2015 14:07:03 -0500
Subject: [RFC PATCH] arm/arm64: build all dtbs for CONPILE_TEST
In-Reply-To: <CAOesGMjzBaobpLsS77UziWeYO9wo21SkdpWT=Pib6AM7DDKTnA@mail.gmail.com>
References: <1440690994-5978-1-git-send-email-robh@kernel.org>
 <CAOesGMjzBaobpLsS77UziWeYO9wo21SkdpWT=Pib6AM7DDKTnA@mail.gmail.com>
Message-ID: <CAL_JsqK+QHgCu4x-X+ShyWhj6g=+X-AC5AeCLm1DNYfFdCpH5A@mail.gmail.com>

On Thu, Aug 27, 2015 at 11:08 AM, Olof Johansson <olof at lixom.net> wrote:
> On Thu, Aug 27, 2015 at 8:56 AM, Rob Herring <robh at kernel.org> wrote:
>> Enable building all dtb files when COMPILE_TEST is enabled. The dtbs are
>> not really dependent on a platform being enabled or any other kernel
>> config, so for testing coverage it is convenient to build all of the
>> dtbs.
>>
>> This builds all dts files in the tree, not just targets listed. This
>> is simpler for arm64 which has a bunch of sub-dirs.
>>
>> Signed-off-by: Rob Herring <robh at kernel.org>
>> Cc: Russell King <linux at arm.linux.org.uk>
>> Cc: Catalin Marinas <catalin.marinas at arm.com>
>> Cc: Will Deacon <will.deacon at arm.com>
>> ---
>> I've had this on my todo list for a while. RFC for now as I want to do
>> the rest of the arches as well. I was originally thinking a new target
>> for this, but thanks to Olof for the COMPILE_TEST suggestion.
>>
>> Rob
>>
>>  arch/arm/boot/dts/Makefile   | 4 ++++
>>  arch/arm64/boot/dts/Makefile | 6 ++++++
>>  2 files changed, 10 insertions(+)
>>
>> diff --git a/arch/arm/boot/dts/Makefile b/arch/arm/boot/dts/Makefile
>> index 246473a..4968442a 100644
>> --- a/arch/arm/boot/dts/Makefile
>> +++ b/arch/arm/boot/dts/Makefile
>> @@ -712,5 +712,9 @@ dtb-$(CONFIG_ARCH_MEDIATEK) += \
>>  dtb-$(CONFIG_ARCH_ZX) += zx296702-ad1.dtb
>>  endif
>>
>> +dtstree                := $(srctree)/$(src)
>> +
>> +dtb-$(CONFIG_COMPILE_TEST) := $(patsubst $(dtstree)/%.dts,%.dtb, $(wildcard $(dtstree)/*.dts))
>> +
>>  always         := $(dtb-y)
>>  clean-files    := *.dtb
>> diff --git a/arch/arm64/boot/dts/Makefile b/arch/arm64/boot/dts/Makefile
>> index 38913be..9f19390 100644
>> --- a/arch/arm64/boot/dts/Makefile
>> +++ b/arch/arm64/boot/dts/Makefile
>> @@ -11,3 +11,9 @@ dts-dirs += sprd
>>  dts-dirs += xilinx
>>
>>  subdir-y       := $(dts-dirs)
>> +
>> +dtstree                := $(srctree)/$(src)
>> +
>> +dtb-$(CONFIG_COMPILE_TEST) := $(patsubst $(dtstree)/%.dts,%.dtb, $(foreach d,$(dts-dirs), $(wildcard $(dtstree)/$(d)/*.dts)))
>
> I think it would be more appropriate to build dtb-n  here instead of
> _any_ file ending in dts.

The problem is here dtb-n is NULL. We have to add this into every
sub-dir. Not a big deal to do, but my concern was remembering to it
for new ones. Then again, most people are good at mindlessly
copy-pasting so maybe that won't be a problem. :)

> It would be useful to build all files, but it's not the behavior that
> COMPILE_TEST usually has.

Just changing to dtb-n would be equivalent because there is no other
dependency to enable building. Code has other dependencies typically.
What dtb do we not want to built in an allyesconfig build? If dtb's
have any dependencies, that would be a bug. To really make this
equivalent to a driver using COMPILE_TEST, we would need kconfig
symbols specifically for each platform's dtbs. Then we would have the
2 stage unhide (setting COMPILE_TEST) then enable the option.

I was also thinking that perhaps we don't want to require a kconfig
symbol for every platform family. Adding a kconfig entry is the only
way to enable building a dtb ATM. I know there are 2 camps to this
policy though.

Rob


From holler at ahsoftware.de  Thu Aug 27 12:15:26 2015
From: holler at ahsoftware.de (Alexander Holler)
Date: Thu, 27 Aug 2015 21:15:26 +0200
Subject: [PATCH 00/16] deps: deterministic driver initialization order
In-Reply-To: <55DF5E7C.8030806@ahsoftware.de>
References: <1440592108-3740-1-git-send-email-holler@ahsoftware.de>
 <55DF5E7C.8030806@ahsoftware.de>
Message-ID: <55DF61CE.9030303@ahsoftware.de>

Am 27.08.2015 um 21:01 schrieb Alexander Holler:
> Am 26.08.2015 um 14:28 schrieb Alexander Holler:
>
>> The final 2 patches are fixes which should end up in mainline, regardless
>> if this feature is merged or not.
>
> Just in case your serial or MTD-NAND partitions don't work, the drivers
> drivers/tty/serial/8250/8250_core.c and drivers/mtd/ofpart.c need the
> same trivial fix for their initcall level as found in the last two
> patches of my series. I'm not going to post these patches now until I've
> got some feedback for the other stuff.

And just in case, I also have an idea how to fix such dependencies for 
drivers without DT (by adding hard-wired dependencies directly to 
drivers). That would also be usable for ACPI and x86.

But one step after another. Based on my past experiences, I don't even 
think the stuff I've just posted will ever end up in the kernel.

> Regards,
>
> Alexander Holler



From dianders at chromium.org  Thu Aug 27 12:30:51 2015
From: dianders at chromium.org (Doug Anderson)
Date: Thu, 27 Aug 2015 12:30:51 -0700
Subject: [PATCH 2/2] ARM: dts: rockchip: correct regulator PM properties
In-Reply-To: <10828643.SSUS2EOuvv@phil>
References: <1439923455-109818-1-git-send-email-briannorris@chromium.org>
 <20150818224831.GA140911@google.com>
 <20150818232806.GC140911@google.com> <10828643.SSUS2EOuvv@phil>
Message-ID: <CAD=FV=UiCcqCm+W4=ExOps8Npi=mkdVgJ2zgdomOw3YqPhCqug@mail.gmail.com>

Hi,

On Tue, Aug 18, 2015 at 11:19 PM, Heiko Stuebner <heiko at sntech.de> wrote:
> great, just take into account the deep vs. shallow suspend modes :-)

One note: do you think it would make sense to re-implement shallow
suspend as "standby"?  I had a proof of concept doing that in
<https://chromium-review.googlesource.com/#/c/275123/>.  One nice
advantage is that you "magically" get a second set of regulator states
for standby vs "mem".

If I understand correctly, the distinction between "standby" and "mem"
is not too clearly defined, so if we wanted to use it for this it
wouldn't be terrible?

-Doug


From ard.biesheuvel at linaro.org  Thu Aug 27 13:33:37 2015
From: ard.biesheuvel at linaro.org (Ard Biesheuvel)
Date: Thu, 27 Aug 2015 22:33:37 +0200
Subject: [PATCH v2] arm64/efi: base UEFI mapping permissions on region
 attributes
In-Reply-To: <20150827093228.GA23520@arm.com>
References: <1440595802-20359-1-git-send-email-ard.biesheuvel@linaro.org>
 <20150827093228.GA23520@arm.com>
Message-ID: <A4801D35-3216-43D2-AEAE-C01ED59A0F24@linaro.org>


> On 27 aug. 2015, at 11:32, Will Deacon <will.deacon at arm.com> wrote:
> 
> Hi Ard,
> 
>> On Wed, Aug 26, 2015 at 02:30:02PM +0100, Ard Biesheuvel wrote:
>> Currently, we infer the UEFI memory region mapping permissions
>> from the memory region type (i.e., runtime services code are
>> mapped RWX and runtime services data mapped RW-). This appears to
>> work fine but is not entirely UEFI spec compliant. So instead, use
>> the designated permission attributes to decide how these regions
>> should be mapped.
>> 
>> Since UEFIv2.5 introduces a new EFI_MEMORY_RO permission attribute,
>> and redefines EFI_MEMORY_WP as a cacheability attribute, use only
>> the former as a read-only attribute. For setting the PXN bit, the
>> corresponding EFI_MEMORY_XP attribute is used.
>> 
>> Signed-off-by: Ard Biesheuvel <ard.biesheuvel at linaro.org>
>> ---
>> Changes since v1:
>> - rewrote page size and alignment check to be more legible
>> - use code that is STRICT_MM_TYPECHECKS compliant
>> 
>> Example output of a recent Tianocore build on FVP Foundation model
>> is attached below.
>> 
>> arch/arm64/kernel/efi.c | 37 +++++++++++++-------
>> 1 file changed, 24 insertions(+), 13 deletions(-)
>> 
>> diff --git a/arch/arm64/kernel/efi.c b/arch/arm64/kernel/efi.c
>> index ab21e0d58278..c8d587f46f3e 100644
>> --- a/arch/arm64/kernel/efi.c
>> +++ b/arch/arm64/kernel/efi.c
>> @@ -235,7 +235,7 @@ static bool __init efi_virtmap_init(void)
>> 
>>    for_each_efi_memory_desc(&memmap, md) {
>>        u64 paddr, npages, size;
>> -        pgprot_t prot;
>> +        pteval_t prot_val;
>> 
>>        if (!(md->attribute & EFI_MEMORY_RUNTIME))
>>            continue;
>> @@ -247,22 +247,33 @@ static bool __init efi_virtmap_init(void)
>>        memrange_efi_to_native(&paddr, &npages);
>>        size = npages << PAGE_SHIFT;
>> 
>> -        pr_info("  EFI remap 0x%016llx => %p\n",
>> -            md->phys_addr, (void *)md->virt_addr);
>> +        if (!is_normal_ram(md))
>> +            prot_val = PROT_DEVICE_nGnRE;
>> +        else
>> +            prot_val = pgprot_val(PAGE_KERNEL_EXEC);
>> 
>>        /*
>> -         * Only regions of type EFI_RUNTIME_SERVICES_CODE need to be
>> -         * executable, everything else can be mapped with the XN bits
>> -         * set.
>> +         * On 64 KB granule kernels, only use strict permissions when
>> +         * the region does not share a 64 KB page frame with another
>> +         * region at either end.
>>         */
>> -        if (!is_normal_ram(md))
>> -            prot = __pgprot(PROT_DEVICE_nGnRE);
>> -        else if (md->type == EFI_RUNTIME_SERVICES_CODE)
>> -            prot = PAGE_KERNEL_EXEC;
>> -        else
>> -            prot = PAGE_KERNEL;
>> +        if (PAGE_SIZE == EFI_PAGE_SIZE ||
>> +            (PAGE_ALIGNED(md->virt_addr) &&
>> +             PAGE_ALIGNED(md->phys_addr + md->num_pages * EFI_PAGE_SIZE))) {
> 
> Why do you use virt_addr instead of phys_addr for the base check?

No reason in particular, as far as I remember, so i should probably change that




From agross at codeaurora.org  Thu Aug 27 13:39:14 2015
From: agross at codeaurora.org (Andy Gross)
Date: Thu, 27 Aug 2015 15:39:14 -0500
Subject: [PATCH v2] arm64: dts: qcom: Add 8x16 Serial UART1 node
Message-ID: <1440707954-18490-1-git-send-email-agross@codeaurora.org>

This patch adds the nodes required to support the UART1 node on the
MSM8916 and also fixes the sleep pins function for UART2.

Signed-off-by: Andy Gross <agross at codeaurora.org>
---
 arch/arm64/boot/dts/qcom/apq8016-sbc.dtsi  |    1 +
 arch/arm64/boot/dts/qcom/msm8916-pins.dtsi |   26 +++++++++++++++++++++++++-
 arch/arm64/boot/dts/qcom/msm8916.dtsi      |    9 +++++++++
 3 files changed, 35 insertions(+), 1 deletion(-)

diff --git a/arch/arm64/boot/dts/qcom/apq8016-sbc.dtsi b/arch/arm64/boot/dts/qcom/apq8016-sbc.dtsi
index 66804ff..3fc3be4 100644
--- a/arch/arm64/boot/dts/qcom/apq8016-sbc.dtsi
+++ b/arch/arm64/boot/dts/qcom/apq8016-sbc.dtsi
@@ -19,6 +19,7 @@
 / {
 	aliases {
 		serial0 = &blsp1_uart2;
+		serial1 = &blsp1_uart1;
 	};
 
 	chosen {
diff --git a/arch/arm64/boot/dts/qcom/msm8916-pins.dtsi b/arch/arm64/boot/dts/qcom/msm8916-pins.dtsi
index 5689568..42941b9 100644
--- a/arch/arm64/boot/dts/qcom/msm8916-pins.dtsi
+++ b/arch/arm64/boot/dts/qcom/msm8916-pins.dtsi
@@ -13,6 +13,30 @@
 
 &msmgpio {
 
+	blsp1_uart1_default: blsp1_uart1_default {
+		pinmux {
+			function = "blsp_uart1";
+			pins = "gpio0", "gpio1";
+		};
+		pinconf {
+			pins = "gpio0", "gpio1";
+			drive-strength = <16>;
+			bias-disable;
+		};
+	};
+
+	blsp1_uart1_sleep: blsp1_uart1_sleep {
+		pinmux {
+			function = "gpio";
+			pins = "gpio0", "gpio1";
+		};
+		pinconf {
+			pins = "gpio0", "gpio1";
+			drive-strength = <2>;
+			bias-pull-down;
+		};
+	};
+
 	blsp1_uart2_default: blsp1_uart2_default {
 		pinmux {
 			function = "blsp_uart2";
@@ -27,7 +51,7 @@
 
 	blsp1_uart2_sleep: blsp1_uart2_sleep {
 		pinmux {
-			function = "blsp_uart2";
+			function = "gpio";
 			pins = "gpio4", "gpio5";
 		};
 		pinconf {
diff --git a/arch/arm64/boot/dts/qcom/msm8916.dtsi b/arch/arm64/boot/dts/qcom/msm8916.dtsi
index 5911de0..9a49dff 100644
--- a/arch/arm64/boot/dts/qcom/msm8916.dtsi
+++ b/arch/arm64/boot/dts/qcom/msm8916.dtsi
@@ -102,6 +102,15 @@
 			reg = <0x1800000 0x80000>;
 		};
 
+		blsp1_uart1: serial at 78af000 {
+			compatible = "qcom,msm-uartdm-v1.4", "qcom,msm-uartdm";
+			reg = <0x78af000 0x200>;
+			interrupts = <GIC_SPI 107 IRQ_TYPE_LEVEL_HIGH>;
+			clocks = <&gcc GCC_BLSP1_UART1_APPS_CLK>, <&gcc GCC_BLSP1_AHB_CLK>;
+			clock-names = "core", "iface";
+			status = "disabled";
+		};
+
 		blsp1_uart2: serial at 78b0000 {
 			compatible = "qcom,msm-uartdm-v1.4", "qcom,msm-uartdm";
 			reg = <0x78b0000 0x200>;
-- 
The Qualcomm Innovation Center, Inc. is a member of the Code Aurora Forum,
hosted by The Linux Foundation



From geert at linux-m68k.org  Thu Aug 27 13:46:38 2015
From: geert at linux-m68k.org (Geert Uytterhoeven)
Date: Thu, 27 Aug 2015 22:46:38 +0200
Subject: [RFC PATCH] arm/arm64: build all dtbs for CONPILE_TEST
In-Reply-To: <CAL_JsqK+QHgCu4x-X+ShyWhj6g=+X-AC5AeCLm1DNYfFdCpH5A@mail.gmail.com>
References: <1440690994-5978-1-git-send-email-robh@kernel.org>
 <CAOesGMjzBaobpLsS77UziWeYO9wo21SkdpWT=Pib6AM7DDKTnA@mail.gmail.com>
 <CAL_JsqK+QHgCu4x-X+ShyWhj6g=+X-AC5AeCLm1DNYfFdCpH5A@mail.gmail.com>
Message-ID: <CAMuHMdXYBBxi6Y+ZW6nLP7+NEBcjvOtNWQGCgwArqUV95JyZTw@mail.gmail.com>

Hi Rob,

On Thu, Aug 27, 2015 at 9:07 PM, Rob Herring <robh at kernel.org> wrote:
>> It would be useful to build all files, but it's not the behavior that
>> COMPILE_TEST usually has.
>
> Just changing to dtb-n would be equivalent because there is no other
> dependency to enable building. Code has other dependencies typically.
> What dtb do we not want to built in an allyesconfig build? If dtb's
> have any dependencies, that would be a bug. To really make this
> equivalent to a driver using COMPILE_TEST, we would need kconfig
> symbols specifically for each platform's dtbs. Then we would have the
> 2 stage unhide (setting COMPILE_TEST) then enable the option.
>
> I was also thinking that perhaps we don't want to require a kconfig
> symbol for every platform family. Adding a kconfig entry is the only
> way to enable building a dtb ATM. I know there are 2 camps to this
> policy though.

I think it would be good to have a single Kconfig option (depending on
COMPILE_TEST) to build all dtbs.

For drivers, COMPILE_TEST doesn't enable anything by itself, it just
relaxes dependencies. Hence if any driver is broken, I can still
disable that driver in the .config.

If any dtb is broken, I cannot disable it, except by disabling COMPILE_TEST,
which I may not want to do for other reasons (e.g. I'm compile testing my
driver). If there would be an extra Kconfig symbol for building all dtbs,
I can still disable it.

Gr{oetje,eeting}s,

                        Geert

--
Geert Uytterhoeven -- There's lots of Linux beyond ia32 -- geert at linux-m68k.org

In personal conversations with technical people, I call myself a hacker. But
when I'm talking to journalists I just say "programmer" or something like that.
                                -- Linus Torvalds


From heiko at sntech.de  Thu Aug 27 13:51:22 2015
From: heiko at sntech.de (Heiko Stuebner)
Date: Thu, 27 Aug 2015 22:51:22 +0200
Subject: [PATCH 2/2] ARM: dts: rockchip: correct regulator PM properties
In-Reply-To: <CAD=FV=UiCcqCm+W4=ExOps8Npi=mkdVgJ2zgdomOw3YqPhCqug@mail.gmail.com>
References: <1439923455-109818-1-git-send-email-briannorris@chromium.org>
 <10828643.SSUS2EOuvv@phil>
 <CAD=FV=UiCcqCm+W4=ExOps8Npi=mkdVgJ2zgdomOw3YqPhCqug@mail.gmail.com>
Message-ID: <2079050.z559I6SEaj@phil>

Am Donnerstag, 27. August 2015, 12:30:51 schrieb Doug Anderson:
> Hi,
> 
> On Tue, Aug 18, 2015 at 11:19 PM, Heiko Stuebner <heiko at sntech.de> wrote:
> > great, just take into account the deep vs. shallow suspend modes :-)
> 
> One note: do you think it would make sense to re-implement shallow
> suspend as "standby"?  I had a proof of concept doing that in
> <https://chromium-review.googlesource.com/#/c/275123/>.  One nice
> advantage is that you "magically" get a second set of regulator states
> for standby vs "mem".

Somewhere I've read something about keeping wifi associated to an ap during 
suspend which might be a candidate for such a distinction?


> If I understand correctly, the distinction between "standby" and "mem"
> is not too clearly defined, so if we wanted to use it for this it
> wouldn't be terrible?

>From reading Documentation/power/states.txt it looks like the boot-cpu is 
supposed to retain power in the suspend state. Although we also do not lose 
"operating state" in our suspend I guess?

So using the shallow suspend as standby sounds interesting, for the time when 
the deep suspend works too. If there is only one suspend state it 
automatically becomes the "mem"-state it seems.


Heiko


From davem at davemloft.net  Thu Aug 27 13:51:56 2015
From: davem at davemloft.net (David Miller)
Date: Thu, 27 Aug 2015 13:51:56 -0700 (PDT)
Subject: [PATCH v2 0/2] drivers: net: xgene: Add TSO support
In-Reply-To: <1440614886-23566-1-git-send-email-isubramanian@apm.com>
References: <1440614886-23566-1-git-send-email-isubramanian@apm.com>
Message-ID: <20150827.135156.661392666355549469.davem@davemloft.net>

From: Iyappan Subramanian <isubramanian at apm.com>
Date: Wed, 26 Aug 2015 11:48:04 -0700

> Adding TSO support for 10GbE
> 
> iperf Tx data rate without TSO: 3.42 Gbps
>                       with TSO: 9.41 Gbps
> 
> v2: Address review comments from v1
>     - skb_linearize() if headers doesn't fit in 3 hardware buffers
> 
> v1:
> * Initial version
> 
> Signed-off-by: Iyappan Subramanian <isubramanian at apm.com>

Series applied, thanks.


From briannorris at chromium.org  Thu Aug 27 13:56:05 2015
From: briannorris at chromium.org (Brian Norris)
Date: Thu, 27 Aug 2015 13:56:05 -0700
Subject: [PATCH 2/2] ARM: dts: rockchip: correct regulator PM properties
In-Reply-To: <2079050.z559I6SEaj@phil>
References: <1439923455-109818-1-git-send-email-briannorris@chromium.org>
 <10828643.SSUS2EOuvv@phil>
 <CAD=FV=UiCcqCm+W4=ExOps8Npi=mkdVgJ2zgdomOw3YqPhCqug@mail.gmail.com>
 <2079050.z559I6SEaj@phil>
Message-ID: <20150827205605.GA42154@google.com>

On Thu, Aug 27, 2015 at 10:51:22PM +0200, Heiko Stuebner wrote:
> Am Donnerstag, 27. August 2015, 12:30:51 schrieb Doug Anderson:
> > If I understand correctly, the distinction between "standby" and "mem"
> > is not too clearly defined, so if we wanted to use it for this it
> > wouldn't be terrible?

I never understood many clear definitions here either, personally.

> From reading Documentation/power/states.txt it looks like the boot-cpu is 
> supposed to retain power in the suspend state. Although we also do not lose 
> "operating state" in our suspend I guess?
> 
> So using the shallow suspend as standby sounds interesting, for the time when 
> the deep suspend works too. If there is only one suspend state it 
> automatically becomes the "mem"-state it seems.

It's not really "automatic", it's a product of this line:

static const struct platform_suspend_ops rk3288_suspend_ops = {
        .enter   = rk3288_suspend_enter,
        .valid   = suspend_valid_only_mem,  <--- here
        .prepare = rk3288_suspend_prepare,
        .finish  = rk3288_suspend_finish,
};

and the fact that we don't check the 'state' argument in
.enter/.prepare/.finish.

But still, I'm not sure it's productive to rename shallow until we support
deep.

Regards,
Brian


From agross at codeaurora.org  Thu Aug 27 14:28:19 2015
From: agross at codeaurora.org (Andy Gross)
Date: Thu, 27 Aug 2015 16:28:19 -0500
Subject: [GIT PULL] qcom SoC changes for 4.3-rc2
Message-ID: <1440710899-29214-1-git-send-email-agross@codeaurora.org>

The following changes since commit 72af1ff60d08a57e223b9753f9c52396fb4c3897:

  Merge tag 'qcom-soc-for-4.3' into for-soc-new (2015-08-27 12:14:29 -0500)

are available in the git repository at:


  git://codeaurora.org/quic/kernel/agross-msm.git tags/qcom-soc-for-4.3-rc2

for you to fetch changes up to 3427446d72e21f6992534a3b68055f1b4c722546:

  soc: qcom: smd: Use correct remote processor ID (2015-08-27 12:15:58 -0500)

----------------------------------------------------------------
Qualcomm ARM Based SoC Updates for 4.3-rc2

* Fix errant private access in SMEM
* Fix use of correct remote processor ID in SMD transactions

----------------------------------------------------------------
Andy Gross (2):
      soc: qcom: smem: Fix errant private access
      soc: qcom: smd: Use correct remote processor ID

 .../devicetree/bindings/soc/qcom/qcom,smd.txt      |    6 ++++++
 drivers/soc/qcom/smd.c                             |   16 ++++++++++++----
 drivers/soc/qcom/smem.c                            |   18 ++++++------------
 3 files changed, 24 insertions(+), 16 deletions(-)


From agross at codeaurora.org  Thu Aug 27 14:29:01 2015
From: agross at codeaurora.org (Andy Gross)
Date: Thu, 27 Aug 2015 16:29:01 -0500
Subject: [GIT PULL] qcom dt changes for 4.3-rc2
Message-ID: <1440710941-29302-1-git-send-email-agross@codeaurora.org>

The following changes since commit 4040f37692ffbc602117d316c574a68a0fbfed93:

  Merge tag 'qcom-dt-for-4.3' into for-dt (2015-08-27 12:07:21 -0500)

are available in the git repository at:


  git://codeaurora.org/quic/kernel/agross-msm.git tags/qcom-dt-for-4.3-rc2

for you to fetch changes up to cecd36b9c847b451e8ae297b53b094445b5352e4:

  ARM: dts: qcom: msm8974-sony-xperia-honami: Use stdout-path (2015-08-27 12:11:22 -0500)

----------------------------------------------------------------
Qualcomm ARM Based Device Tree Updates for v4.3-rc2

* Add labels for serial nodes to be used for aliasing and stdout-path
* Add stdout-path for APQ8064 Compulab QS600
* Add stdout-path for APQ8064 Inforce 6410
* Add stdout-path for APQ8074 Dragonboard
* Add stdout-path for APQ8084 Inforce 6540
* Add stdout-path for APQ8084 MTP
* Add stdout-path for IPQ8064 AP148
* Add stdout-path for MSM8660 Surf
* Add stdout-path for MSM8960 CDP
* Add stdout-path for MSM8974 Xperia Honami

----------------------------------------------------------------
Stephen Boyd (10):
      ARM: dts: qcom: Label serial nodes for aliasing and stdout-path
      ARM: dts: qcom: apq8064-cm-qs600: Use stdout-path
      ARM: dts: qcom: apq8064-ifc6410: Use stdout-path
      ARM: dts: qcom: apq8074-dragonboard: Use stdout-path
      ARM: dts: qcom: apq8084-ifc6540: Use stdout-path
      ARM: dts: qcom: apq8084-mtp: Use stdout-path
      ARM: dts: qcom: ipq8064-ap148: Use stdout-path
      ARM: dts: qcom: msm8660-surf: Use stdout-path
      ARM: dts: qcom: msm8960-cdp: Use stdout-path
      ARM: dts: qcom: msm8974-sony-xperia-honami: Use stdout-path

 arch/arm/boot/dts/qcom-apq8064-cm-qs600.dts        |    8 ++++++++
 arch/arm/boot/dts/qcom-apq8064-ifc6410.dts         |    4 ++++
 arch/arm/boot/dts/qcom-apq8074-dragonboard.dts     |    8 ++++++++
 arch/arm/boot/dts/qcom-apq8084-ifc6540.dts         |    8 ++++++++
 arch/arm/boot/dts/qcom-apq8084-mtp.dts             |    8 ++++++++
 arch/arm/boot/dts/qcom-apq8084.dtsi                |    2 +-
 arch/arm/boot/dts/qcom-ipq8064-ap148.dts           |    8 ++++++++
 arch/arm/boot/dts/qcom-ipq8064.dtsi                |    2 +-
 arch/arm/boot/dts/qcom-msm8660-surf.dts            |    8 ++++++++
 arch/arm/boot/dts/qcom-msm8660.dtsi                |    2 +-
 arch/arm/boot/dts/qcom-msm8960-cdp.dts             |    8 ++++++++
 arch/arm/boot/dts/qcom-msm8960.dtsi                |    2 +-
 .../boot/dts/qcom-msm8974-sony-xperia-honami.dts   |    8 ++++++++
 arch/arm/boot/dts/qcom-msm8974.dtsi                |    2 +-
 14 files changed, 73 insertions(+), 5 deletions(-)


From sboyd at codeaurora.org  Thu Aug 27 14:40:05 2015
From: sboyd at codeaurora.org (Stephen Boyd)
Date: Thu, 27 Aug 2015 14:40:05 -0700
Subject: [PATCH 8/9] ARM: entry: provide uaccess assembly macro hooks
In-Reply-To: <E1ZSmQB-0002zT-A6@rmk-PC.arm.linux.org.uk>
References: <20150821133043.GV7557@n2100.arm.linux.org.uk>
 <E1ZSmQB-0002zT-A6@rmk-PC.arm.linux.org.uk>
Message-ID: <20150827214005.GX19120@codeaurora.org>

On 08/21, Russell King wrote:
> @@ -400,6 +402,10 @@ ENDPROC(__fiq_abt)
>   ARM(	stmdb	r0, {sp, lr}^			)
>   THUMB(	store_user_sp_lr r0, r1, S_SP - S_PC	)
>  
> +	.if \uaccess

This \u seems to trip up my clang build. It seems that the
assembler thinks \u is escaping for unicode or something?

 arch/arm/kernel/entry-armv.S:202:
 Error: non-constant expression in ".if" statement

Looking at the intermediate assembly file I see:

 .if ??ss
 uaccess_disable ip
 .endif

Changing 'uaccess' to 'access' seems to make the problem go away.

-- 
Qualcomm Innovation Center, Inc. is a member of Code Aurora Forum,
a Linux Foundation Collaborative Project


From m-karicheri2 at ti.com  Thu Aug 27 14:43:47 2015
From: m-karicheri2 at ti.com (Murali Karicheri)
Date: Thu, 27 Aug 2015 17:43:47 -0400
Subject: [PATCH] soc: ti: reset irq affinity before freeing irq
In-Reply-To: <55DF58A0.8090105@oracle.com>
References: <1440690671-1029-1-git-send-email-m-karicheri2@ti.com>
 <55DF3E3F.6030506@mentor.com> <55DF5589.6050802@ti.com>
 <55DF581A.2090300@mentor.com> <55DF58A0.8090105@oracle.com>
Message-ID: <55DF8493.7090307@ti.com>

On 08/27/2015 02:36 PM, santosh.shilimkar at oracle.com wrote:
> On 8/27/15 11:34 AM, Nathan Lynch wrote:
>> On 08/27/2015 01:23 PM, Murali Karicheri wrote:
>>> On 08/27/2015 12:43 PM, Nathan Lynch wrote:
>>>> On 08/27/2015 10:51 AM, Murali Karicheri wrote:
>>>>> When using accumulator queue for rx side for network driver, following
>>>>> warning is seen when doing a reboot command from Linux console. This
>>>>> is because, affinity value is not reset before calling free_irq().
>>>>> This
>>>>> patch fixes this.
>>>>>
>>>>> Deconfiguring network interfaces...
>>>>> [   55.176589] ------------[ cut here ]-----------
>>>>> [   55.181232] WARNING: CPU: 0 PID: 2081 at kernel/irq/manage.c:1370
>>>>> __free_irq+0x208/0x214
>>>>
>>>> The full content of the warning should be included in the commit
>>>> message; __free_irq has several potential sources of warning messages,
>>>> and line 1370 doesn't correspond to any of them in 4.2-rc8.
>>>
>>> The log corresponds to 4.1.x kernel. Corresponding WARN_ONCE is
>>>
>>> #ifdef CONFIG_SMP
>>>          /* make sure affinity_hint is cleaned up */
>>>          if (WARN_ON_ONCE(desc->affinity_hint))
>>>                  desc->affinity_hint = NULL;
>>> #endif
>>>
>>> Which is line 1922. I can edit to make it 1922. Does that work?
>>
>> Eh, I guess I wasn't thinking clearly about this clearly when I wrote
>> that.  (I somehow had the notion that WARN_ON... maybe printed more than
>> just the file and line number, but that is clearly mistaken.)  I think
>> your message is fine as is, sorry for the noise.
>>
>> I don't think changing the line number will make it any easier on future
>> readers.
>>
> Right. Just leave the full call in the commit so that the context
> is captured.
>
>
Will do that and resend it

-- 
Murali Karicheri
Linux Kernel, Keystone


From m-karicheri2 at ti.com  Thu Aug 27 14:44:07 2015
From: m-karicheri2 at ti.com (Murali Karicheri)
Date: Thu, 27 Aug 2015 17:44:07 -0400
Subject: [PATCH v1] soc: ti: reset irq affinity before freeing irq
Message-ID: <1440711847-24747-1-git-send-email-m-karicheri2@ti.com>

When using accumulator queue for rx side for network driver, following
warning is seen when doing a reboot command from Linux console. This
is because, affinity value is not reset before calling free_irq(). This
patch fixes this.

Deconfiguring network interfaces...
[   55.176589] ------------[ cut here ]-----------
[   55.181232] WARNING: CPU: 0 PID: 2081 at kernel/irq/manage.c:1370
__free_irq+0x208/0x214
[   55.181232] WARNING: CPU: 0 PID: 2081 at kernel/irq/manage.c:1370
__free_irq+0x208/0x214
()
[   55.189527] Modules linked in:
[   55.192598] CPU: 0 PID: 2081 Comm: ifconfig Not tainted
4.1.5-00908-g1049e206-dirty #1
[   55.200543] Hardware name: Keystone
[   55.204040] Backtrace: 
[   55.206507] [<c0012b98>] (dump_backtrace) from [<c0012dbc>]
(show_stack+0x18/0x1c)
[   55.214102]  r7:c005d0a8 r6:c06e2184 r5:c06e2184 r4:00000000
[   55.219811] [<c0012da4>] (show_stack) from [<c04e7168>]
(dump_stack+0x8c/0xcc)
[   55.227065] [<c04e70dc>] (dump_stack) from [<c0025944>]
(warn_slowpath_common+0x88/0xb8)
[   55.235183]  r7:c005d0a8 r6:0000055a r5:00000009 r4:00000000
[   55.240889] [<c00258bc>] (warn_slowpath_common) from [<c0025a18>]
(warn_slowpath_null+0x
24/0x2c)
[   55.249704]  r8:0000006c r7:ee513f60 r6:ee513f00 r5:ee611010 r4:cc873a00
[   55.256458] [<c00259f4>] (warn_slowpath_null) from [<c005d0a8>]
(__free_irq+0x208/0x214)
[   55.264580] [<c005cea0>] (__free_irq) from [<c005d158>]
 (free_irq+0x54/0xac)
[   55.271652]  r10:00000002 r9:00000000 r8:00000000 r7:ee611010
r6:0000006c r5:00000000
[   55.279538]  r4:ee513f00 r3:00000000
[   55.283140] [<c005d104>] (free_irq) from [<c02a81b0>]
(knav_range_setup_acc_irq+0xb0/0x1
28)
[   55.291519]  r7:00000001 r6:0000006c r5:ee611010 r4:00000001
[   55.297223] [<c02a8100>] (knav_range_setup_acc_irq) from [<c02a8248>]
(knav_acc_close_qu
eue+0x20/0x24)
[   55.306563]  r8:edd1a4c8 r7:00001000 r6:eed89980 r5:ee616650 r4:edf9d990
[   55.313320] [<c02a8228>] (knav_acc_close_queue) from [<c02a6160>]
(knav_queue_close+0xb4
/0xb8)
[   55.321969] [<c02a60ac>] (knav_queue_close) from [<c0336270>]
(netcp_free_navigator_reso
urces+0x1d4/0x2c0)
[   55.331656]  r5:edd1a480 r4:00000400
[   55.335255] [<c033609c>] (netcp_free_navigator_resources) from
[<c033657c>] (netcp_ndo_stop+0x220/0x230)
[   55.344768]  r10:00008914 r9:edf34400 r8:00000000 r7:edd1a5d8
r6:edd1a480 r5:00000400
[   55.352653]  r4:edd1a000
[   55.355202] [<c033635c>] (netcp_ndo_stop) from [<c03d9c80>]
(__dev_close_many+0x90/0xd8)
[   55.363320]  r7:00001003 r6:00001042 r5:edb0de20 r4:edd1a000
[   55.369023] [<c03d9bf0>] (__dev_close_many) from [<c03d9df4>]
(__dev_close+0x30/0x48)
[   55.376880]  r5:00000001 r4:edd1a000
[   55.380480] [<c03d9dc4>] (__dev_close) from [<c03e175c>]
(__dev_change_flags+0x9c/0x14c)
[   55.388602] [<c03e16c0>] (__dev_change_flags) from [<c03e182c>]
(dev_change_flags+0x20/0
x50)
[   55.397069]  r9:edf34400 r8:00000000 r7:00000000 r6:00001003 r5:edd1a138
r4:edd1a000
[   55.404875] [<c03e180c>] (dev_change_flags) from [<c0446f94>]
(devinet_ioctl+0x680/0x754
)
[   55.413080]  r9:edf34400 r8:bef6af3c r7:00000000 r6:bef6ac64 r5:edf3440c
r4:00000000
[   55.420882] [<c0446914>] (devinet_ioctl) from [<c0448760>]
(inet_ioctl+0x1a8/0x1d0)
[   55.428564]  r10:00000000 r9:edb0c000 r8:bef6ac64 r7:00000003
r6:bef6ac64 r5:bef6ac64
[   55.436449]  r4:00008914
[   55.438996] [<c04485b8>] (inet_ioctl) from [<c03c72fc>]
(sock_ioctl+0x1d0/0x2a8)
[   55.446423] [<c03c712c>] (sock_ioctl) from [<c00eb608>]
(do_vfs_ioctl+0x414/0x604)
[   55.454018]  r7:00000003 r6:ed8b60c0 r5:bef6ac64 r4:ccc88f20
[   55.459721] [<c00eb1f4>] (do_vfs_ioctl) from [<c00eb834>]
(SyS_ioctl+0x3c/0x64)
[   55.467055]  r9:edb0c000 r8:bef6ac64 r7:00008914 r6:ed8b60c0 r5:00000003
r4:ed8b60c0
[   55.474858] [<c00eb7f8>] (SyS_ioctl) from [<c000f780>]
(ret_fast_syscall+0x0/0x3c)
[   55.482452]  r9:edb0c000 r8:c000f924 r7:00000036 r6:0007e77c r5:bef6ac64
r4:0007e7d0
[   55.490252] ---[ end trace f565594c905af0b4 ]---

Signed-off-by: Murali Karicheri <m-karicheri2 at ti.com>
---
 - v1 - added all of the call trace per comment
 - Applies to v4.2.0-rc8

 drivers/soc/ti/knav_qmss_acc.c | 4 ++++
 1 file changed, 4 insertions(+)

diff --git a/drivers/soc/ti/knav_qmss_acc.c b/drivers/soc/ti/knav_qmss_acc.c
index ef6f69d..b98fe56 100644
--- a/drivers/soc/ti/knav_qmss_acc.c
+++ b/drivers/soc/ti/knav_qmss_acc.c
@@ -261,6 +261,10 @@ static int knav_range_setup_acc_irq(struct knav_range_info *range,
 	if (old && !new) {
 		dev_dbg(kdev->dev, "setup-acc-irq: freeing %s for channel %s\n",
 			acc->name, acc->name);
+		ret = irq_set_affinity_hint(irq, NULL);
+		if (ret)
+			dev_warn(range->kdev->dev,
+				 "Failed to set IRQ affinity\n");
 		free_irq(irq, range);
 	}
 
-- 
1.9.1



From dianders at chromium.org  Thu Aug 27 15:07:30 2015
From: dianders at chromium.org (Doug Anderson)
Date: Thu, 27 Aug 2015 15:07:30 -0700
Subject: [PATCH v3] ARM: dts: rockchip: add veyron-jaq board
In-Reply-To: <1440457083-77519-1-git-send-email-briannorris@chromium.org>
References: <1440457083-77519-1-git-send-email-briannorris@chromium.org>
Message-ID: <CAD=FV=W34EXSvfJCRjaTy7jE-EnjMyechY2EcXn13G6HOfsh1w@mail.gmail.com>

Brian,

On Mon, Aug 24, 2015 at 3:58 PM, Brian Norris <briannorris at chromium.org> wrote:
> a.k.a. Haier Chromebook 11, and others
>
> Signed-off-by: Brian Norris <briannorris at chromium.org>
> Cc: Alexandru M Stan <amstan at chromium.org>
> Cc: Douglas Anderson <dianders at chromium.org>
> Reviewed-by: Javier Martinez Canillas <javier at osg.samsung.com>
> ---
> v2 -> v3:
>  - add "and others" language
>  - drop other patches from series (picked up already by Heiko)
>
> v1 -> v2:
>  - add overlooked DT binding doc
>  - fixup regulator suspend state for LDO_REG2
>
>
>  Documentation/devicetree/bindings/arm/rockchip.txt |   7 +
>  arch/arm/boot/dts/Makefile                         |   1 +
>  arch/arm/boot/dts/rk3288-veyron-jaq.dts            | 176 +++++++++++++++++++++
>  3 files changed, 184 insertions(+)

Reviewed-by: Douglas Anderson <dianders at chromium.org>


From timur at codeaurora.org  Thu Aug 27 15:15:03 2015
From: timur at codeaurora.org (Timur Tabi)
Date: Thu, 27 Aug 2015 17:15:03 -0500
Subject: [PATCH v3 15/31] arm64: SMP support
In-Reply-To: <55DB0A8B.3090700@linaro.org>
References: <1347035226-18649-1-git-send-email-catalin.marinas@arm.com>
 <1347035226-18649-16-git-send-email-catalin.marinas@arm.com>
 <CAOZdJXVoDJM3y2mnKO+91yf2EHogKfMjumjhhi85REAfhcJM=Q@mail.gmail.com>
 <20150806095621.GB17691@e104818-lin.cambridge.arm.com>
 <55C8843D.8050600@linaro.org> <55C8D9DB.5080207@codeaurora.org>
 <55D7559E.8080609@codeaurora.org> <55DB0A8B.3090700@linaro.org>
Message-ID: <55DF8BE7.2090102@codeaurora.org>

On 08/24/2015 07:14 AM, Hanjun Guo wrote:

>> Actually, I think we need to keep it.  I just heard from another
>> developer who does actually use it for debugging.
>
> Hmm, could you please give a example for how it used?

For KVM guests, it's handy to know what the guests were doing when the 
guest crashes.  However, I still think we should quiesce the stack dumps 
by default.

>> I think the real problem is that emergency_restart() should not be
>> causing these outputs.  Shouldn't machine_restart() change the
>> system_state to SYSTEM_RESTART before it calls smp_send_stop()?
>
> The system_state is set to SYSTEM_RESTART in kernel_restart_prepare(),
> and kernel_restart() will call kernel_restart_prepare() and
> machine_restart(), so if we change the system_state to SYSTEM_RESTART
> in machine_restart(), it seems duplicate.

I don't see where emergency_restart() ever calls 
kernel_restart_prepare().  Here's the call chain:

emergency_restart
machine_emergency_restart
machine_restart
efi_reboot

I don't see where kernel_restart_prepare() is actually called in this chain.

kernel_restart() calls kernel_restart_prepare() and then calls 
machine_restart().  Perhaps machine_emergency_restart() also needs to 
call. kernel_restart_prepare() before calling machine_restart()?  Either 
that, or machine_emergency_restart() needs to manually set system_state 
is set to SYSTEM_RESTART.

  static inline void machine_emergency_restart(void)
  {
+	system_state = SYSTEM_RESTART;
  	machine_restart(NULL);
  }

> Could we just wait longer than one second in the following function?
>
> void smp_send_stop(void)
> {
>          unsigned long timeout;
>
>          if (num_online_cpus() > 1) {
>                  cpumask_t mask;
>
>                  cpumask_copy(&mask, cpu_online_mask);
>                  cpumask_clear_cpu(smp_processor_id(), &mask);
>
>                  smp_cross_call(&mask, IPI_CPU_STOP);
>          }
>
>          /* Wait up to one second for other CPUs to stop */
>          timeout = USEC_PER_SEC;
>          while (num_online_cpus() > 1 && timeout--)
>                  udelay(1);
>
> If we have lots of CPUs, one second seems not enough as it
> print lots dump message.

Yes, that's what we do internally.  However, as the number of cores is 
increased, the problem gets worse.  The default maximum cores is 64, so 
it just seems like this problem is going to get worse and worse as the 
core count grows.  I believe a large core count is going to be standard 
modus operandi for ARM64 servers.

-- 
Qualcomm Innovation Center, Inc.
The Qualcomm Innovation Center, Inc. is a member of the
Code Aurora Forum, a Linux Foundation Collaborative Project.


From santosh.shilimkar at oracle.com  Thu Aug 27 15:58:25 2015
From: santosh.shilimkar at oracle.com (santosh shilimkar)
Date: Thu, 27 Aug 2015 15:58:25 -0700
Subject: [PATCH v1] soc: ti: reset irq affinity before freeing irq
In-Reply-To: <1440711847-24747-1-git-send-email-m-karicheri2@ti.com>
References: <1440711847-24747-1-git-send-email-m-karicheri2@ti.com>
Message-ID: <55DF9611.4060801@oracle.com>



On 8/27/2015 2:44 PM, Murali Karicheri wrote:
> When using accumulator queue for rx side for network driver, following
> warning is seen when doing a reboot command from Linux console. This
> is because, affinity value is not reset before calling free_irq(). This
> patch fixes this.
>
> Deconfiguring network interfaces...
> [   55.176589] ------------[ cut here ]-----------
> [   55.181232] WARNING: CPU: 0 PID: 2081 at kernel/irq/manage.c:1370
> __free_irq+0x208/0x214
> [   55.181232] WARNING: CPU: 0 PID: 2081 at kernel/irq/manage.c:1370
> __free_irq+0x208/0x214
> ()
> [   55.189527] Modules linked in:
> [   55.192598] CPU: 0 PID: 2081 Comm: ifconfig Not tainted
> 4.1.5-00908-g1049e206-dirty #1
> [   55.200543] Hardware name: Keystone
> [   55.204040] Backtrace:
> [   55.206507] [<c0012b98>] (dump_backtrace) from [<c0012dbc>]
> (show_stack+0x18/0x1c)
> [   55.214102]  r7:c005d0a8 r6:c06e2184 r5:c06e2184 r4:00000000
> [   55.219811] [<c0012da4>] (show_stack) from [<c04e7168>]
> (dump_stack+0x8c/0xcc)
> [   55.227065] [<c04e70dc>] (dump_stack) from [<c0025944>]
> (warn_slowpath_common+0x88/0xb8)
> [   55.235183]  r7:c005d0a8 r6:0000055a r5:00000009 r4:00000000
> [   55.240889] [<c00258bc>] (warn_slowpath_common) from [<c0025a18>]
> (warn_slowpath_null+0x
> 24/0x2c)
> [   55.249704]  r8:0000006c r7:ee513f60 r6:ee513f00 r5:ee611010 r4:cc873a00
> [   55.256458] [<c00259f4>] (warn_slowpath_null) from [<c005d0a8>]
> (__free_irq+0x208/0x214)
> [   55.264580] [<c005cea0>] (__free_irq) from [<c005d158>]
>   (free_irq+0x54/0xac)
> [   55.271652]  r10:00000002 r9:00000000 r8:00000000 r7:ee611010
> r6:0000006c r5:00000000
> [   55.279538]  r4:ee513f00 r3:00000000
> [   55.283140] [<c005d104>] (free_irq) from [<c02a81b0>]
> (knav_range_setup_acc_irq+0xb0/0x1
> 28)
> [   55.291519]  r7:00000001 r6:0000006c r5:ee611010 r4:00000001
> [   55.297223] [<c02a8100>] (knav_range_setup_acc_irq) from [<c02a8248>]
> (knav_acc_close_qu
> eue+0x20/0x24)
> [   55.306563]  r8:edd1a4c8 r7:00001000 r6:eed89980 r5:ee616650 r4:edf9d990
> [   55.313320] [<c02a8228>] (knav_acc_close_queue) from [<c02a6160>]
> (knav_queue_close+0xb4
> /0xb8)
> [   55.321969] [<c02a60ac>] (knav_queue_close) from [<c0336270>]
> (netcp_free_navigator_reso
> urces+0x1d4/0x2c0)
> [   55.331656]  r5:edd1a480 r4:00000400
> [   55.335255] [<c033609c>] (netcp_free_navigator_resources) from
> [<c033657c>] (netcp_ndo_stop+0x220/0x230)
> [   55.344768]  r10:00008914 r9:edf34400 r8:00000000 r7:edd1a5d8
> r6:edd1a480 r5:00000400
> [   55.352653]  r4:edd1a000
> [   55.355202] [<c033635c>] (netcp_ndo_stop) from [<c03d9c80>]
> (__dev_close_many+0x90/0xd8)
> [   55.363320]  r7:00001003 r6:00001042 r5:edb0de20 r4:edd1a000
> [   55.369023] [<c03d9bf0>] (__dev_close_many) from [<c03d9df4>]
> (__dev_close+0x30/0x48)
> [   55.376880]  r5:00000001 r4:edd1a000
> [   55.380480] [<c03d9dc4>] (__dev_close) from [<c03e175c>]
> (__dev_change_flags+0x9c/0x14c)
> [   55.388602] [<c03e16c0>] (__dev_change_flags) from [<c03e182c>]
> (dev_change_flags+0x20/0
> x50)
> [   55.397069]  r9:edf34400 r8:00000000 r7:00000000 r6:00001003 r5:edd1a138
> r4:edd1a000
> [   55.404875] [<c03e180c>] (dev_change_flags) from [<c0446f94>]
> (devinet_ioctl+0x680/0x754
> )
> [   55.413080]  r9:edf34400 r8:bef6af3c r7:00000000 r6:bef6ac64 r5:edf3440c
> r4:00000000
> [   55.420882] [<c0446914>] (devinet_ioctl) from [<c0448760>]
> (inet_ioctl+0x1a8/0x1d0)
> [   55.428564]  r10:00000000 r9:edb0c000 r8:bef6ac64 r7:00000003
> r6:bef6ac64 r5:bef6ac64
> [   55.436449]  r4:00008914
> [   55.438996] [<c04485b8>] (inet_ioctl) from [<c03c72fc>]
> (sock_ioctl+0x1d0/0x2a8)
> [   55.446423] [<c03c712c>] (sock_ioctl) from [<c00eb608>]
> (do_vfs_ioctl+0x414/0x604)
> [   55.454018]  r7:00000003 r6:ed8b60c0 r5:bef6ac64 r4:ccc88f20
> [   55.459721] [<c00eb1f4>] (do_vfs_ioctl) from [<c00eb834>]
> (SyS_ioctl+0x3c/0x64)
> [   55.467055]  r9:edb0c000 r8:bef6ac64 r7:00008914 r6:ed8b60c0 r5:00000003
> r4:ed8b60c0
> [   55.474858] [<c00eb7f8>] (SyS_ioctl) from [<c000f780>]
> (ret_fast_syscall+0x0/0x3c)
> [   55.482452]  r9:edb0c000 r8:c000f924 r7:00000036 r6:0007e77c r5:bef6ac64
> r4:0007e7d0
> [   55.490252] ---[ end trace f565594c905af0b4 ]---
>
> Signed-off-by: Murali Karicheri <m-karicheri2 at ti.com>
> ---
>   - v1 - added all of the call trace per comment
>   - Applies to v4.2.0-rc8
>
Thanks Murali. I will drop time stamp while applying it.

Regards,
Santosh


From mturquette at baylibre.com  Thu Aug 27 16:02:31 2015
From: mturquette at baylibre.com (Michael Turquette)
Date: Thu, 27 Aug 2015 16:02:31 -0700
Subject: [PATCH 1/2] clk: atlas7: move variable-definition together
In-Reply-To: <1439514663-23979-1-git-send-email-21cnbao@gmail.com>
References: <1439514663-23979-1-git-send-email-21cnbao@gmail.com>
Message-ID: <20150827230231.30921.20071@quantum>

Quoting Barry Song (2015-08-13 18:11:02)
> From: Guo Zeng <Guo.Zeng at csr.com>
> 
> re-order the codes more reasonable by moving variable-definition
> together.
> 
> Signed-off-by: Guo Zeng <Guo.Zeng at csr.com>
> Signed-off-by: Barry Song <Baohua.Song at csr.com>

Hi Barry,

I'll apply these after -rc1 drops, towards 4.4. Please be sure to Cc
linux-clk at vger.kernel.org for future clk patches.

Thanks!
Mike

> ---
>  drivers/clk/sirf/clk-atlas7.c | 24 ++++++++++++------------
>  1 file changed, 12 insertions(+), 12 deletions(-)
> 
> diff --git a/drivers/clk/sirf/clk-atlas7.c b/drivers/clk/sirf/clk-atlas7.c
> index a98e21f..d34d1b3 100644
> --- a/drivers/clk/sirf/clk-atlas7.c
> +++ b/drivers/clk/sirf/clk-atlas7.c
> @@ -206,18 +206,6 @@
>  #define SIRFSOC_CLKC_LEAF_CLK_EN8_SET        0x0548
>  
>  
> -static void __iomem *sirfsoc_clk_vbase;
> -static struct clk_onecell_data clk_data;
> -
> -static const struct clk_div_table pll_div_table[] = {
> -       { .val = 0, .div = 1 },
> -       { .val = 1, .div = 2 },
> -       { .val = 2, .div = 4 },
> -       { .val = 3, .div = 8 },
> -       { .val = 4, .div = 16 },
> -       { .val = 5, .div = 32 },
> -};
> -
>  struct clk_pll {
>         struct clk_hw hw;
>         u16 regofs;  /* register offset */
> @@ -284,6 +272,18 @@ struct atlas7_reset_desc {
>         spinlock_t *lock;
>  };
>  
> +static void __iomem *sirfsoc_clk_vbase;
> +static struct clk_onecell_data clk_data;
> +
> +static const struct clk_div_table pll_div_table[] = {
> +       { .val = 0, .div = 1 },
> +       { .val = 1, .div = 2 },
> +       { .val = 2, .div = 4 },
> +       { .val = 3, .div = 8 },
> +       { .val = 4, .div = 16 },
> +       { .val = 5, .div = 32 },
> +};
> +
>  static DEFINE_SPINLOCK(cpupll_ctrl1_lock);
>  static DEFINE_SPINLOCK(mempll_ctrl1_lock);
>  static DEFINE_SPINLOCK(sys0pll_ctrl1_lock);
> -- 
> 1.9.1
> 
> 
> _______________________________________________
> linux-arm-kernel mailing list
> linux-arm-kernel at lists.infradead.org
> http://lists.infradead.org/mailman/listinfo/linux-arm-kernel


From sbranden at broadcom.com  Thu Aug 27 16:35:30 2015
From: sbranden at broadcom.com (Scott Branden)
Date: Thu, 27 Aug 2015 16:35:30 -0700
Subject: [PATCH v2 0/5] Add Broadcom Northstar Plus Support
In-Reply-To: <1440628530-6137-1-git-send-email-jonmason@broadcom.com>
References: <1440628530-6137-1-git-send-email-jonmason@broadcom.com>
Message-ID: <55DF9EC2.4060902@broadcom.com>

Patchset all look good.
Acked-by: Scott Branden <sbranden at broadcom.com>

On 15-08-26 03:35 PM, Jon Mason wrote:
>
> Changes in version 2 incorporate Olof's comments regarding:
> * the removal of all "Reviewed-by" lines not occurring on external
>    mailing lists
> * reordering of s-o-b lines
> * modification of the device tree file to use labels when enabling
> * increated description of the modification to the MAINTAINERS entry
>
> Also, modifying the "to" and "cc" recepients so that everyone is
> receving all of the patches.
>
> --
>
> This patch series adds support for the Broadcom Northstar Plus family of
> SoCs.  NSP is a Cortex A9 based SoC under the Broadcom iProc family.
>
> Jon Mason (5):
>    dt-bindings: Create Documentation for NSP DT bindings
>    ARM: NSP: add minimal Northstar Plus device tree
>    ARM: NSP: Add basic support for Broadcom Northstar Plus SoC
>    ARM: multi_v7_defconfig: Add NSP to defconfig
>    MAINTAINERS: add entry for the Broadcom Northstar Plus SoCs
>
>   .../devicetree/bindings/arm/bcm/brcm,nsp.txt       |  34 +++++++
>   MAINTAINERS                                        |  12 ++-
>   arch/arm/boot/dts/Makefile                         |   2 +
>   arch/arm/boot/dts/bcm-nsp.dtsi                     | 105 +++++++++++++++++++++
>   arch/arm/boot/dts/bcm958625k.dts                   |  57 +++++++++++
>   arch/arm/configs/multi_v7_defconfig                |   1 +
>   arch/arm/mach-bcm/Kconfig                          |  14 +++
>   arch/arm/mach-bcm/Makefile                         |   5 +-
>   arch/arm/mach-bcm/bcm_nsp.c                        |  25 +++++
>   9 files changed, 252 insertions(+), 3 deletions(-)
>   create mode 100644 Documentation/devicetree/bindings/arm/bcm/brcm,nsp.txt
>   create mode 100644 arch/arm/boot/dts/bcm-nsp.dtsi
>   create mode 100644 arch/arm/boot/dts/bcm958625k.dts
>   create mode 100644 arch/arm/mach-bcm/bcm_nsp.c
>



From shawn.lin at rock-chips.com  Thu Aug 27 16:52:19 2015
From: shawn.lin at rock-chips.com (Shawn Lin)
Date: Fri, 28 Aug 2015 07:52:19 +0800
Subject: [PATCH v1 3/5] ARM: dts: Add arm, pl330-broken-no-flushp quirk
 for rk3288 platform
In-Reply-To: <CAD=FV=Uy8zhPnCQGcks9T-wezcRAohO8Ec3KSLn=Ftr7J1TeSA@mail.gmail.com>
References: <1440685419-22037-1-git-send-email-shawn.lin@rock-chips.com>
 <1440685481-22163-1-git-send-email-shawn.lin@rock-chips.com>
 <CAD=FV=Uy8zhPnCQGcks9T-wezcRAohO8Ec3KSLn=Ftr7J1TeSA@mail.gmail.com>
Message-ID: <55DFA2B3.1010401@rock-chips.com>

On 2015/8/28 0:52, Doug Anderson wrote:
> Hi,
>
> On Thu, Aug 27, 2015 at 7:24 AM, Shawn Lin <shawn.lin at rock-chips.com> wrote:
>> From: Addy Ke <addy.ke at rock-chips.com>
>
> Looks like you just added the "From" here.  I think that's fine, but
> better to set the author so you get the right cover letter...
>
>
>> Pl330 integrated in rk3288 platform doesn't support
>> DMAFLUSHP function. So we add broken-no-flushp quirk
>> for it.
>>
>> Signed-off-by: Addy Ke <addy.ke at rock-chips.com>
>> Signed-off-by: Shawn Lin <shawn.lin at rock-chips.com>
>> cc: Heiko Stuebner <heiko at sntech.de>
>> cc: Doug Anderson <dianders at chromium.org>
>> cc: Olof Johansson <olofj at google.com>
>>
>> ---
>>
>> Changes in v1:
>> - rename broken-no-flushp to "arm,pl330-broken-no-flushp" suggested
>>    by Krzysztof.
>> - remove Sunny's tag
>
> Note that typically for patches I see people go from "no v" to "v2".  AKA:
> * PATCH
> * PATCH v2
> * PATCH v3
>
>
>>   arch/arm/boot/dts/rk3288.dtsi | 3 +++
>>   1 file changed, 3 insertions(+)
>>
>> diff --git a/arch/arm/boot/dts/rk3288.dtsi b/arch/arm/boot/dts/rk3288.dtsi
>> index 22316d0..106adf7 100644
>> --- a/arch/arm/boot/dts/rk3288.dtsi
>> +++ b/arch/arm/boot/dts/rk3288.dtsi
>> @@ -144,6 +144,7 @@
>>                          #dma-cells = <1>;
>>                          clocks = <&cru ACLK_DMAC2>;
>>                          clock-names = "apb_pclk";
>> +                       arm,pl330-broken-no-flushp;
>
> Note that you should add bindings _before_ the usage of them.  So
> patch #5 (Documentation) needs to come before this one.
>

Cool! That makes sense.
Thanks, Doug.

>>                  };
>>
>>                  dmac_bus_ns: dma-controller at ff600000 {
>> @@ -155,6 +156,7 @@
>>                          clocks = <&cru ACLK_DMAC1>;
>>                          clock-names = "apb_pclk";
>>                          status = "disabled";
>> +                       arm,pl330-broken-no-flushp;
>>                  };
>>
>>                  dmac_bus_s: dma-controller at ffb20000 {
>> @@ -165,6 +167,7 @@
>>                          #dma-cells = <1>;
>>                          clocks = <&cru ACLK_DMAC1>;
>>                          clock-names = "apb_pclk";
>> +                       arm,pl330-broken-no-flushp;
>>                  };
>>          };
>
> Other than the small nits above, this looks fine to me.
>
> Reviewed-by: Douglas Anderson <dianders at chromium.org>
>
>
>


-- 
Best Regards
Shawn Lin



From mturquette at baylibre.com  Thu Aug 27 16:58:49 2015
From: mturquette at baylibre.com (Michael Turquette)
Date: Thu, 27 Aug 2015 16:58:49 -0700
Subject: [PATCH] clk: at91: add audio pll clock driver
In-Reply-To: <20150827113035.072cccb5@bbrezillon>
References: <1438337864-27949-1-git-send-email-nicolas.ferre@atmel.com>
 <20150827113035.072cccb5@bbrezillon>
Message-ID: <20150827235849.30921.22045@quantum>

Quoting Boris Brezillon (2015-08-27 02:30:35)
> Hi Nicolas,
> 
> On Fri, 31 Jul 2015 12:17:44 +0200
> Nicolas Ferre <nicolas.ferre at atmel.com> wrote:
> 
> > This new clock driver set allows to have a fractional divided clock
> > that would generate a precise clock particularly suitable for
> > audio applications.
> > 
> > The main audio pll clock has two children clocks: one that is connected
> > to the PMC, the other that can directly drive a pad. As these two routes
> > have different enable bits and different dividers and divider formula,
> > they are handled by two different drivers.
> > Each of them would modify the rate of the main audio pll parent.
> 
> Hm, not sure allowing both children to modify the parent clk rate is
> a good idea, but let's see how it works.

Might be a good idea to use clk_set_rate_range? Of course most audio use
cases need exact rates...

Regards,
Mike

> 
> > 
> > Signed-off-by: Nicolas Ferre <nicolas.ferre at atmel.com>
> > ---
> >  .../devicetree/bindings/clock/at91-clock.txt       |  38 +++
> >  drivers/clk/at91/Makefile                          |   2 +
> >  drivers/clk/at91/clk-audio-pll-pad.c               | 220 +++++++++++++++++
> >  drivers/clk/at91/clk-audio-pll-pmc.c               | 171 ++++++++++++++
> >  drivers/clk/at91/clk-audio-pll.c                   | 261 +++++++++++++++++++++
> >  drivers/clk/at91/pmc.c                             |  14 ++
> >  drivers/clk/at91/pmc.h                             |   7 +
> >  include/linux/clk/at91_pmc.h                       |  25 ++
> >  8 files changed, 738 insertions(+)
> >  create mode 100644 drivers/clk/at91/clk-audio-pll-pad.c
> >  create mode 100644 drivers/clk/at91/clk-audio-pll-pmc.c
> >  create mode 100644 drivers/clk/at91/clk-audio-pll.c
> > 
> 
> [...]
> 
> > +
> > +static int clk_audio_pll_compute_qdpad(unsigned long q_rate, unsigned long rate,
> > +                                    unsigned long *qd, u8 *div, u8 *ext_div)
> > +{
> > +     unsigned long tmp_qd;
> > +     unsigned long rem2, rem3;
> > +     unsigned long ldiv, lext_div;
> > +
> > +     if (!rate)
> > +             return -EINVAL;
> > +
> > +     tmp_qd = q_rate / rate;
> > +     if (!tmp_qd || tmp_qd > AUDIO_PLL_QDPAD_MAX)
> > +             return -EINVAL;
> 
> Do you really want to return an error in this case?
> I mean, you're calling this function from ->round_rate(), and
> ->round_rate() is supposed to find the closest rate, not to return an
> error if the rate is too low or to high.
> ITOH, you're calling the same function from ->set_rate(), which is
> supposed to complain if the requested rate is not exactly met.
> 
> Maybe you can deal with that by passing an additional argument to this
> function. Something like:
> 
>         tmp_qd = q_rate / rate;
> 
>         if (!strict) {
>                 if (!tmp_qd)
>                         tmp_qd = 1;
>                 else if (tmp_qd > AUDIO_PLL_QDPAD_MAX)
>                         tmp_qd = AUDIO_PLL_QDPAD_MAX;
>         }
> 
>         if (!tmp_qd || tmp_qd > AUDIO_PLL_QDPAD_MAX)
>                 return -EINVAL;
> 
> > +
> > +     if (tmp_qd <= AT91_PMC_AUDIO_PLL_QDPAD_EXTDIV_MAX) {
> > +             ldiv = 1;
> > +             lext_div = tmp_qd;
> > +     } else {
> > +             rem2 = tmp_qd % 2;
> > +             rem3 = tmp_qd % 3;
> > +
> > +             if (rem3 == 0 ||
> > +                 tmp_qd > AT91_PMC_AUDIO_PLL_QDPAD_EXTDIV_MAX * 2 ||
> > +                 rem3 < rem2) {
> > +                     ldiv = 3;
> > +                     lext_div = tmp_qd / 3;
> > +             } else {
> > +                     ldiv = 2;
> > +                     lext_div = tmp_qd >> 1;
> > +             }
> > +     }
> > +
> > +     pr_debug("A PLL/PAD: %s, qd = %lu (div = %lu, ext_div = %lu)\n",
> > +              __func__, ldiv * lext_div, ldiv, lext_div);
> > +
> > +     /* if we were given variable to store, we can provide them */
> > +     if (qd)
> > +             *qd = ldiv * lext_div;
> > +     if (div && ext_div) {
> > +             /* we can cast here as we verified the bounds just above */
> > +             *div = (u8)ldiv;
> > +             *ext_div = (u8)lext_div;
> > +     }
> > +
> > +     return 0;
> > +}
> > +
> > +static long clk_audio_pll_pad_round_rate(struct clk_hw *hw, unsigned long rate,
> > +                                      unsigned long *parent_rate)
> 
> I thought we were trying to get rid of the ->round_rate() function in
> favor of the ->determine_rate() one (which is more flexible), but maybe
> I'm wrong. Stephen, Mike, what's your opinion?
> 
> > +{
> > +     struct clk *pclk = __clk_get_parent(hw->clk);
> > +     long best_rate = -EINVAL;
> > +     unsigned long best_parent_rate = 0;
> > +     unsigned long tmp_qd;
> > +
> > +     pr_debug("A PLL/PAD: %s, rate = %lu (parent_rate = %lu)\n",
> > +              __func__, rate, *parent_rate);
> > +
> > +     if (clk_audio_pll_compute_qdpad(AUDIO_PLL_REFERENCE_FOUT, rate,
> > +                                     &tmp_qd, NULL, NULL))
> > +             return -EINVAL;
> 
> You're calculating your divisor based on the AUDIO_PLL_REFERENCE_FOUT
> value...
> 
> > +
> > +     best_parent_rate = __clk_round_rate(pclk, rate * tmp_qd);
> 
> ... and then asking your parent to adapt its rate based on the returned
> divisor. Wouldn't it be preferable to search for the best parent rate
> when choosing the divisor?
> 
> > +     best_rate = best_parent_rate / tmp_qd;
> > +
> > +     pr_debug("A PLL/PAD: %s, best_rate = %ld, best_parent_rate = %lu\n",
> > +              __func__, best_rate, best_parent_rate);
> > +
> > +     *parent_rate = best_parent_rate;
> > +     return best_rate;
> > +}
> 
> [...]
> 
> > +
> > +static long clk_audio_pll_pmc_round_rate(struct clk_hw *hw, unsigned long rate,
> > +                                      unsigned long *parent_rate)
> > +{
> > +     struct clk *pclk = __clk_get_parent(hw->clk);
> > +     long best_rate = -EINVAL;
> > +     unsigned long best_parent_rate = 0;
> > +     unsigned long tmp_qd;
> > +
> > +     pr_debug("A PLL/PMC: %s, rate = %lu (parent_rate = %lu)\n",
> > +              __func__, rate, *parent_rate);
> > +
> > +     if (clk_audio_pll_compute_qdpmc(AUDIO_PLL_REFERENCE_FOUT, rate, &tmp_qd))
> > +             return -EINVAL;
> > +
> > +     best_parent_rate = __clk_round_rate(pclk, rate * tmp_qd);
> 
> Ditto.
> 
> BTW, I'm not sure this is safe to allow both pll-audio children to
> change their parent rate. What will happen if one of them change the
> pll-audio rate while the other is still using it?
> 
> > +     best_rate = best_parent_rate / tmp_qd;
> > +
> > +     pr_debug("A PLL/PMC: %s, best_rate = %ld, best_parent_rate = %lu (qd = %lu)\n",
> > +              __func__, best_rate, best_parent_rate, tmp_qd - 1);
> > +
> > +     *parent_rate = best_parent_rate;
> > +     return best_rate;
> > +}
> 
> [...]
> 
> > +
> > +#define to_clk_audio_frac(hw) container_of(hw, struct clk_audio_frac, hw)
> > +
> > +/* make sure that pll is in reset state beforehand */
> > +static int clk_audio_pll_prepare(struct clk_hw *hw)
> > +{
> > +     struct clk_audio_frac *fck = to_clk_audio_frac(hw);
> > +     struct at91_pmc *pmc = fck->pmc;
> > +     u32 tmp;
> > +
> > +     pmc_lock(pmc);
> > +     tmp = pmc_read(pmc, AT91_PMC_AUDIO_PLL0) & ~AT91_PMC_AUDIO_PLL_RESETN;
> > +     pmc_write(pmc, AT91_PMC_AUDIO_PLL0, tmp);
> > +     pmc_unlock(pmc);
> 
> Nothing sleeps in this code, so you could move everything in your
> ->enable() function.
> 
> > +     return 0;
> > +}
> > +
> > +static void clk_audio_pll_unprepare(struct clk_hw *hw)
> > +{
> > +     clk_audio_pll_prepare(hw);
> 
> Ditto.
> 
> Best Regards,
> 
> Boris
> 
> -- 
> Boris Brezillon, Free Electrons
> Embedded Linux and Kernel engineering
> http://free-electrons.com
> --
> To unsubscribe from this list: send the line "unsubscribe linux-kernel" in
> the body of a message to majordomo at vger.kernel.org
> More majordomo info at  http://vger.kernel.org/majordomo-info.html
> Please read the FAQ at  http://www.tux.org/lkml/


From robherring2 at gmail.com  Thu Aug 27 17:06:29 2015
From: robherring2 at gmail.com (Rob Herring)
Date: Thu, 27 Aug 2015 19:06:29 -0500
Subject: [PATCH v4 2/4] PCI: st: Add Device Tree bindings for sti pcie
In-Reply-To: <1440678857-27118-3-git-send-email-gabriel.fernandez@linaro.org>
References: <1440678857-27118-1-git-send-email-gabriel.fernandez@linaro.org>
 <1440678857-27118-3-git-send-email-gabriel.fernandez@linaro.org>
Message-ID: <CAL_Jsq+A-3bF2vdqQnD4HJXLoxDEnm1w=yBynbKYahgLe8CVPQ@mail.gmail.com>

On Thu, Aug 27, 2015 at 7:34 AM, Gabriel Fernandez
<gabriel.fernandez at linaro.org> wrote:
> sti pcie is built around a Synopsis Designware PCIe IP.
>
> Signed-off-by: Fabrice Gasnier <fabrice.gasnier at st.com>
> Signed-off-by: Gabriel Fernandez <gabriel.fernandez at linaro.org>
> ---
>  Documentation/devicetree/bindings/pci/st-pcie.txt | 53 +++++++++++++++++++++++
>  1 file changed, 53 insertions(+)
>  create mode 100644 Documentation/devicetree/bindings/pci/st-pcie.txt
>
> diff --git a/Documentation/devicetree/bindings/pci/st-pcie.txt b/Documentation/devicetree/bindings/pci/st-pcie.txt
> new file mode 100644
> index 0000000..25fcab3
> --- /dev/null
> +++ b/Documentation/devicetree/bindings/pci/st-pcie.txt
> @@ -0,0 +1,53 @@
> +STMicroelectronics STi PCIe controller
> +
> +This PCIe host controller is based on the Synopsis Designware PCIe IP
> +and thus inherits all the common properties defined in designware-pcie.txt.
> +
> +Required properties:
> + - compatible: "st,stih407-pcie"

What about "snps,dw-pcie" as well?

> + - reg: base address and length of the pcie controller, mem-window address
> +   and length available to the controller.

What is mem-window? Seems rather large and perhaps should be under ranges.

> + - interrupts: A list of interrupt outputs of the controller. Must contain an
> +   entry for each entry in the interrupt-names property.

Define how many interrupts.

> + - interrupt-names: Should be "msi". STi interrupt that is asserted when an
> +   MSI is received.

Kind of pointless with a single interrupt.

> + - st,syscfg : should be a phandle of the syscfg node. Also contains syscfg
> +   offset for IP configuration.
> + - resets, reset-names: the power-down and soft-reset lines of PCIe IP.
> +   Associated names must be "powerdown" and "softreset".
> + - phys, phy-names: the phandle for the PHY device.
> +   Associated name must be "pcie"

What does this mean?

> +
> +Optional properties:
> + - reset-gpio: a GPIO spec to define which pin is connected to the bus reset.
> +
> +Example:
> +
> +pcie0: pcie at 9b00000 {
> +       compatible = "st,pcie", "snps,dw-pcie";
> +       device_type = "pci";
> +       reg = <0x09b00000 0x4000>,      /* dbi cntrl registers */
> +             <0x2fff0000 0x00010000>,  /* configuration space */
> +             <0x40000000 0x80000000>;  /* lmi mem window */
> +       reg-names = "dbi", "config", "mem-window";
> +       st,syscfg = <&syscfg_core 0xd8 0xe0>;
> +       #address-cells = <3>;
> +       #size-cells = <2>;
> +       ranges = <0x82000000 0 0x20000000 0x20000000 0 0x0FFF0000>; /* non-prefetchable memory */

No i/o support?

> +       num-lanes = <1>;
> +       interrupts = <GIC_SPI 164 IRQ_TYPE_LEVEL_HIGH>;
> +       interrupt-names = "msi";
> +       #interrupt-cells = <1>;
> +       interrupt-map-mask = <0 0 0 7>;
> +       interrupt-map = <0 0 0 1 &intc GIC_SPI 160 IRQ_TYPE_LEVEL_HIGH>, /* INT A */
> +                       <0 0 0 2 &intc GIC_SPI 161 IRQ_TYPE_LEVEL_HIGH>, /* INT B */
> +                       <0 0 0 3 &intc GIC_SPI 162 IRQ_TYPE_LEVEL_HIGH>, /* INT C */
> +                       <0 0 0 4 &intc GIC_SPI 163 IRQ_TYPE_LEVEL_HIGH>; /* INT D */
> +
> +       resets = <&powerdown STIH407_PCIE0_POWERDOWN>,
> +                <&softreset STIH407_PCIE0_SOFTRESET>;
> +       reset-names = "powerdown",
> +                     "softreset";
> +       phys = <&phy_port0 PHY_TYPE_PCIE>;
> +       phy-names = "pcie";
> +};
> --
> 1.9.1
>


From bjorn.andersson at sonymobile.com  Thu Aug 27 17:16:03 2015
From: bjorn.andersson at sonymobile.com (Bjorn Andersson)
Date: Thu, 27 Aug 2015 17:16:03 -0700
Subject: [GIT PULL] qcom SoC changes for 4.3-rc2
In-Reply-To: <1440710899-29214-1-git-send-email-agross@codeaurora.org>
References: <1440710899-29214-1-git-send-email-agross@codeaurora.org>
Message-ID: <20150828001603.GO13472@usrtlx11787.corpusers.net>

On Thu 27 Aug 14:28 PDT 2015, Andy Gross wrote:

> The following changes since commit 72af1ff60d08a57e223b9753f9c52396fb4c3897:
> 
>   Merge tag 'qcom-soc-for-4.3' into for-soc-new (2015-08-27 12:14:29 -0500)
> 
> are available in the git repository at:
> 
> 
>   git://codeaurora.org/quic/kernel/agross-msm.git tags/qcom-soc-for-4.3-rc2
> 
> for you to fetch changes up to 3427446d72e21f6992534a3b68055f1b4c722546:
> 
>   soc: qcom: smd: Use correct remote processor ID (2015-08-27 12:15:58 -0500)
> 
> ----------------------------------------------------------------
> Qualcomm ARM Based SoC Updates for 4.3-rc2
> 
> * Fix errant private access in SMEM
> * Fix use of correct remote processor ID in SMD transactions
> 

I was hoping to see my fBLOCKREADINTR fix [1] here as well, as the issue
it's fixing it a never ending stall if we're trying to send data with a
full tx fifo - i.e. a rather bad result...

But I'm fine with you queuing it for -rc3 too...

[1] https://lkml.org/lkml/2015/8/24/756

Regards,
Bjorn



From khilman at kernel.org  Thu Aug 27 17:24:13 2015
From: khilman at kernel.org (Kevin Hilman)
Date: Thu, 27 Aug 2015 17:24:13 -0700
Subject: [RESEND PATCH v16 4/4] ARM: dts: add the support power-domain
 node on RK3288 SoCs
In-Reply-To: <CAKdAkRS=9Dq+YpMNSjpij0Am4ZD6uUURv74OLLYf+akD=W885A@mail.gmail.com>
 (Dmitry Torokhov's message of "Tue, 25 Aug 2015 16:47:58 -0700")
References: <1440487486-6154-1-git-send-email-wxt@rock-chips.com>
 <1440487486-6154-5-git-send-email-wxt@rock-chips.com>
 <7hfv37axhj.fsf@deeprootsystems.com>
 <CAD=FV=V6oG+9U=W_JZmqCuNo-9-5wW8ffZzG7ZE_3cnSTNAjFQ@mail.gmail.com>
 <7htwrn6l7g.fsf@deeprootsystems.com>
 <CAKdAkRS=9Dq+YpMNSjpij0Am4ZD6uUURv74OLLYf+akD=W885A@mail.gmail.com>
Message-ID: <7hmvxc45w2.fsf@deeprootsystems.com>

Dmitry Torokhov <dmitry.torokhov at gmail.com> writes:

> On Tue, Aug 25, 2015 at 3:45 PM, Kevin Hilman <khilman at kernel.org> wrote:
>> Doug Anderson <dianders at chromium.org> writes:
>>
>>> To put things in a
>>> concrete way, for pd_vio we'd go through the entire device tree
>>> ourselves and find all properties that look like "power-domains =
>>> <&power RK3288_PD_VIO>;".  We'd then find the parent of those
>>> properties and look for a property named "clocks".  We'd then iterate
>>> over all those clocks and turn those on.  Did I get that right?
>>
>> ... but you make it sound like more work than it is.  The genpd already
>> keeps a list of devices that refer to the power domain.  In fact, the
>> genpd 'attach' method can be platform-specific, so could be used to keep
>> track of a list (or a subset) of clocks which are needed for reset.
>
> That is not really workable: the attach and detach happen in
> probe/remove path; if you do not have driver for the device you will
> miss the clocks for it. 

And in my proposal, I suggested that clocks without drivers are
good candidates to list in the domain, with the caveat that the be
called out (documented) as being device clocks that are missing a
driver, so when a driver shows up they can be moved accordingly, and in
a way that actually describes the hardware.

> And the quirk of this SoC is that we need to
> turn all clocks during domain transition, regardless of whether there
> is a driver for all devices.

I understand.  And that "quirk" is not unique to rockchip socs.

Kevin






From k.kozlowski at samsung.com  Thu Aug 27 17:27:37 2015
From: k.kozlowski at samsung.com (Krzysztof Kozlowski)
Date: Fri, 28 Aug 2015 09:27:37 +0900
Subject: [PATCH] rtc: Fix module autoload for rtc-{ab8500,max8997,s5m}
 drivers
In-Reply-To: <1440671672-26590-1-git-send-email-javier@osg.samsung.com>
References: <1440671672-26590-1-git-send-email-javier@osg.samsung.com>
Message-ID: <55DFAAF9.3020202@samsung.com>

On 27.08.2015 19:34, Javier Martinez Canillas wrote:
> These platform drivers have a platform device ID table but the module
> alias information is not created so module autoloading will not work.
> 
> Signed-off-by: Javier Martinez Canillas <javier at osg.samsung.com>
> 
> ---
> 
>  drivers/rtc/rtc-ab8500.c  | 1 +
>  drivers/rtc/rtc-max8997.c | 1 +
>  drivers/rtc/rtc-s5m.c     | 1 +
>  3 files changed, 3 insertions(+)

Makes sense:
Reviewed-by: Krzysztof Kozlowski <k.kozlowski at samsung.com>

Best regards,
Krzysztof



From stefan at agner.ch  Thu Aug 27 17:34:55 2015
From: stefan at agner.ch (Stefan Agner)
Date: Thu, 27 Aug 2015 17:34:55 -0700
Subject: [PATCH v11 0/5] mtd: nand: vf610_nfc: Freescale NFC for VF610
Message-ID: <1440722100-25388-1-git-send-email-stefan@agner.ch>

In this 11th revision the driver now rereads the OOB area in case
hardware ECC fails. This allows to count the flipped bits accross
the whole page reliably. Also the device tree bindings have been
updated: NAND chips can be specified using sub-nodes, the ECC
properties are part of those chip nodes. Note however that the
driver currently only supports one NAND chip. The driver has been
verified again using the MTD tests.

More information and the full test log of earlier patchset version
can be found in the cover letter of the last revision v6:
http://thread.gmane.org/gmane.linux.kernel/1979868

Changes since v10:
- Rebased onto l2-mtd/master
- Use children nodes for NAND chips in device tree bindings
- Support exactly one NAND chip using the new device tree bindings
- Reread page OOB on ECC error in order to reliable determine the amount
  of bit flips on a erased page
- Use ECC strength/2 as the only bit flip threshold
- Rely on endianness aware word read to read the ECC status
- Introduce vf610_nfc_variant which reflects the variant according to
  the device tree compatible string
- Use variant to determine chip select implementation
- Use enum for alternate buffer indication
- Renamed page_sz variable in struct vf610_nfc as well as in the function
  vf610_nfc_command to more specific names
- Some smaller code cleanup (altered ECC_SRAM_ADDR, introduce OOB_MAX)

Changes since v9:
- Remove inline of vf610_nfc_done
- Add __iomem to src argument of vf610_nfc_memcpy
- Handle return value of mtd_device_parse_register correctly
- Count bits in OOB too (only non-ECC bits)
- Return bitflips in ecc.read_page callback vf610_nfc_read_page
- Fall-through ALT_BUF_ONFI
- Use BIT macros

Changes since v8:
- Fix 16-Bit NAND flash support by splitting up initialization
  (introduce vf610_nfc_preinit_controller)
- Updated comments in initialziation functions

Changes since v7:
- vf610-twr.dts: Moved NFC pinmux into the existing iomuxc node
  and sort new nfc node behind the existing iomuxc node as well.
- vf610-twr.dts/vf-colibri.dtsi: Dropped _1 suffixes

Changes since v6:
- Rebased ontop of l2-mtd/master (v4.2-rc1 based)
- Removed HAVE_NAND_VF610_NFC and use depends on. This made
  "[PATCH v6 4/6] ARM: vf610: enable NAND Flash Controller" unnecessary

Changes since v5:
- Removed fsl,mpc5125-nfc compatible string
- Removed readl/writel_relaxed
- Change interface of vf610_nfc_transfer_size to match other accessors

Changes since v4:
- Rebased ontop of l2-mtd/master (v4.1-rc4 based)
- Eliminate unnecessary page read (NAND_CMD_SEQIN) since the driver does
  not support sub-page writes anyway (improves write performance)
- Support ONFI by enabling READID command with offset and parameter page
  reads (CMD_PARAM)
- Change to dedicated read_page/write_page function, enables raw writes
- Use __LITTLE_ENDIAN to distingush between LE/BE relevant statements
- Eliminated vf610_nfc_probe_dt in favor of common DT init code
- Use wait_for_completion_timeout
- Some style fixes (spaces, etc.)

Changes since v3:
- Make the driver selectable when COMPILE_TEST is set
- Fix compile error due to superfluous ECC_STATUS configuration in initial
  patch (without ECC correction ECC_STATUS does not need to be configured)
- Remove custom BBT pattern and switch to in-band BBT in the initial patch
- Include two bug fixes, for details see the corresponding U-Boot patches:
  http://thread.gmane.org/gmane.comp.boot-loaders.u-boot/215802

Changes since v2:
- Updated binding documentation

Changes since v1:
- Nest nfc_config struct within the main nfc struct
- Use assigned clock binding to specify NFC clock
- Rebased ontop of MSCM IR patchset (driver parts have been merged)
- Split out arch Kconfig in a separate config
- Fix module license
- Updated MAINTAINERS

Changes since RFC (Bill Pringlemeir):
- Renamed driver from fsl_nfc to vf610_nfc
- Use readl/writel for all register in accessor functions
- Optimized field accessor functions
- Implemented PM (suspend/resume) functions
- Implemented basic support for ECC strength/ECC step size from dt
- Improved performance of count_written_bits by using hweight32
- Support ECC with 60-bytes to correct up to 32 bit errors
- Changed to in-band BBT (NAND_BBT_NO_OOB) which also allows ECC modes
  which uses up to 60 bytes on 64 byte OOB
- Removed custom (downstream) BBT pattern since BBT table won't be
  compatible anyway (due to the change above)

mtd_speedtest of this 11th revision on a Colibri VF61:

[ 2321.921612] =================================================
[ 2321.927459] mtd_speedtest: MTD device: 3
[ 2321.936619] mtd_speedtest: MTD device size 104857600, eraseblock size 131072, page size 2048, count of eraseblocks 800, pages per eraseblock 64, OOB size 64
[ 2321.954428] mtd_test: scanning for bad eraseblocks
[ 2321.959626] mtd_test: block 142 is bad
[ 2321.966038] mtd_test: scanned 800 eraseblocks, 1 are bad
[ 2322.370120] mtd_speedtest: testing eraseblock write speed
[ 2344.047677] mtd_speedtest: eraseblock write speed is 4718 KiB/s
[ 2344.053687] mtd_speedtest: testing eraseblock read speed
[ 2351.890573] mtd_speedtest: eraseblock read speed is 13059 KiB/s
[ 2352.315120] mtd_speedtest: testing page write speed
[ 2374.882015] mtd_speedtest: page write speed is 4533 KiB/s
[ 2374.887526] mtd_speedtest: testing page read speed
[ 2382.886572] mtd_speedtest: page read speed is 12791 KiB/s
[ 2383.290314] mtd_speedtest: testing 2 page write speed
[ 2405.362236] mtd_speedtest: 2 page write speed is 4634 KiB/s
[ 2405.367925] mtd_speedtest: testing 2 page read speed
[ 2413.299551] mtd_speedtest: 2 page read speed is 12901 KiB/s
[ 2413.305228] mtd_speedtest: Testing erase speed
[ 2413.707595] mtd_speedtest: erase speed is 257612 KiB/s
[ 2413.712796] mtd_speedtest: Testing 2x multi-block erase speed
[ 2414.110127] mtd_speedtest: 2x multi-block erase speed is 260897 KiB/s
[ 2414.116656] mtd_speedtest: Testing 4x multi-block erase speed
[ 2414.510316] mtd_speedtest: 4x multi-block erase speed is 264268 KiB/s
[ 2414.516838] mtd_speedtest: Testing 8x multi-block erase speed
[ 2414.908075] mtd_speedtest: 8x multi-block erase speed is 265641 KiB/s
[ 2414.914607] mtd_speedtest: Testing 16x multi-block erase speed
[ 2415.306958] mtd_speedtest: 16x multi-block erase speed is 264268 KiB/s
[ 2415.313586] mtd_speedtest: Testing 32x multi-block erase speed
[ 2415.702660] mtd_speedtest: 32x multi-block erase speed is 267028 KiB/s
[ 2415.709270] mtd_speedtest: Testing 64x multi-block erase speed
[ 2416.098225] mtd_speedtest: 64x multi-block erase speed is 266333 KiB/s
[ 2416.104833] mtd_speedtest: finished
[ 2416.108379] =================================================

Stefan Agner (5):
  mtd: nand: vf610_nfc: Freescale NFC for VF610, MPC5125 and others
  mtd: nand: vf610_nfc: add hardware BCH-ECC support
  mtd: nand: vf610_nfc: add device tree bindings
  ARM: dts: vf610twr: add NAND flash controller peripherial
  ARM: dts: vf-colibri: enable NAND flash controller

 .../devicetree/bindings/mtd/vf610-nfc.txt          |  59 ++
 MAINTAINERS                                        |   6 +
 arch/arm/boot/dts/vf-colibri.dtsi                  |  39 +
 arch/arm/boot/dts/vf610-twr.dts                    |  47 ++
 arch/arm/boot/dts/vfxxx.dtsi                       |  10 +
 drivers/mtd/nand/Kconfig                           |  11 +
 drivers/mtd/nand/Makefile                          |   1 +
 drivers/mtd/nand/vf610_nfc.c                       | 890 +++++++++++++++++++++
 8 files changed, 1063 insertions(+)
 create mode 100644 Documentation/devicetree/bindings/mtd/vf610-nfc.txt
 create mode 100644 drivers/mtd/nand/vf610_nfc.c

-- 
2.5.0



From stefan at agner.ch  Thu Aug 27 17:34:57 2015
From: stefan at agner.ch (Stefan Agner)
Date: Thu, 27 Aug 2015 17:34:57 -0700
Subject: [PATCH v11 2/5] mtd: nand: vf610_nfc: add hardware BCH-ECC support
In-Reply-To: <1440722100-25388-1-git-send-email-stefan@agner.ch>
References: <1440722100-25388-1-git-send-email-stefan@agner.ch>
Message-ID: <1440722100-25388-3-git-send-email-stefan@agner.ch>

This adds hardware ECC support using the BCH encoder in the NFC IP.
The ECC encoder supports up to 32-bit correction by using 60 error
correction bytes. There is no sub-page ECC step, ECC is calculated
always accross the whole page (up to 2k pages).

Limitations:
- HW ECC: Only 2K page with 64+ OOB.
- HW ECC: Only 24 and 32-bit error correction implemented.

Raw writes have been tested using the generic nand_write_page_raw
implementation. However, raw reads are currently not possible
because the controller need to know whether we are going to use
the ECC mode already at NAND_CMD_READ0 command time. At this point
we do not have the information whether it is a raw read or a
regular read at driver level...

Signed-off-by: Bill Pringlemeir <bpringlemeir at nbsps.com>
Signed-off-by: Stefan Agner <stefan at agner.ch>
---
 drivers/mtd/nand/Kconfig     |   6 +-
 drivers/mtd/nand/vf610_nfc.c | 204 ++++++++++++++++++++++++++++++++++++++++++-
 2 files changed, 206 insertions(+), 4 deletions(-)

diff --git a/drivers/mtd/nand/Kconfig b/drivers/mtd/nand/Kconfig
index 9f9736c..ccd1158 100644
--- a/drivers/mtd/nand/Kconfig
+++ b/drivers/mtd/nand/Kconfig
@@ -466,8 +466,10 @@ config MTD_NAND_VF610_NFC
 	help
 	  Enables support for NAND Flash Controller on some Freescale
 	  processors like the VF610, MPC5125, MCF54418 or Kinetis K70.
-	  The driver supports a maximum 2k page size. The driver
-	  currently does not support hardware ECC.
+	  The driver supports a maximum 2k page size. With 2k pages and
+	  64 bytes or more of OOB, hardware ECC with up to 32-bit error
+	  correction is supported. Hardware ECC is only enabled through
+	  device tree.
 
 config MTD_NAND_MXC
 	tristate "MXC NAND support"
diff --git a/drivers/mtd/nand/vf610_nfc.c b/drivers/mtd/nand/vf610_nfc.c
index eba67dc..14f51c8 100644
--- a/drivers/mtd/nand/vf610_nfc.c
+++ b/drivers/mtd/nand/vf610_nfc.c
@@ -19,8 +19,8 @@
  * - Untested on MPC5125 and M54418.
  * - DMA and pipelining not used.
  * - 2K pages or less.
- * - No chip select, one NAND chip per controller.
- * - No hardware ECC.
+ * - HW ECC: Only 2K page with 64+ OOB.
+ * - HW ECC: Only 24 and 32-bit error correction implemented.
  */
 
 #include <linux/module.h>
@@ -77,6 +77,8 @@
 
 /* NFC ECC mode define */
 #define ECC_BYPASS			0
+#define ECC_45_BYTE			6
+#define ECC_60_BYTE			7
 
 /*** Register Mask and bit definitions */
 
@@ -129,6 +131,18 @@
 #define CMD_DONE_CLEAR_BIT			BIT(18)
 #define IDLE_CLEAR_BIT				BIT(17)
 
+/*
+ * ECC status - seems to consume 8 bytes (double word). The documented
+ * status byte is located in the lowest byte of the second word (which is
+ * the 4th or 7th byte depending on endianness).
+ * Calculate an offset to store the ECC status at the end of the buffer.
+ */
+#define ECC_SRAM_ADDR		(PAGE_2K + OOB_MAX - 8)
+
+#define ECC_STATUS		0x4
+#define ECC_STATUS_MASK		0x80
+#define ECC_STATUS_ERR_COUNT	0x3F
+
 enum vf610_nfc_alt_buf {
 	ALT_BUF_DATA = 0,
 	ALT_BUF_ID = 1,
@@ -152,10 +166,40 @@ struct vf610_nfc {
 	enum vf610_nfc_alt_buf alt_buf;
 	enum vf610_nfc_variant variant;
 	struct clk *clk;
+	bool use_hw_ecc;
+	u32 ecc_mode;
 };
 
 #define mtd_to_nfc(_mtd) container_of(_mtd, struct vf610_nfc, mtd)
 
+static struct nand_ecclayout vf610_nfc_ecc45 = {
+	.eccbytes = 45,
+	.eccpos = {19, 20, 21, 22, 23,
+		   24, 25, 26, 27, 28, 29, 30, 31,
+		   32, 33, 34, 35, 36, 37, 38, 39,
+		   40, 41, 42, 43, 44, 45, 46, 47,
+		   48, 49, 50, 51, 52, 53, 54, 55,
+		   56, 57, 58, 59, 60, 61, 62, 63},
+	.oobfree = {
+		{.offset = 2,
+		 .length = 17} }
+};
+
+static struct nand_ecclayout vf610_nfc_ecc60 = {
+	.eccbytes = 60,
+	.eccpos = { 4,  5,  6,  7,  8,  9, 10, 11,
+		   12, 13, 14, 15, 16, 17, 18, 19,
+		   20, 21, 22, 23, 24, 25, 26, 27,
+		   28, 29, 30, 31, 32, 33, 34, 35,
+		   36, 37, 38, 39, 40, 41, 42, 43,
+		   44, 45, 46, 47, 48, 49, 50, 51,
+		   52, 53, 54, 55, 56, 57, 58, 59,
+		   60, 61, 62, 63 },
+	.oobfree = {
+		{.offset = 2,
+		 .length = 2} }
+};
+
 static inline u32 vf610_nfc_read(struct vf610_nfc *nfc, uint reg)
 {
 	return readl(nfc->regs + reg);
@@ -298,6 +342,13 @@ static void vf610_nfc_addr_cycle(struct vf610_nfc *nfc, int column, int page)
 				    ROW_ADDR_SHIFT, page);
 }
 
+static inline void vf610_nfc_ecc_mode(struct vf610_nfc *nfc, int ecc_mode)
+{
+	vf610_nfc_set_field(nfc, NFC_FLASH_CONFIG,
+			    CONFIG_ECC_MODE_MASK,
+			    CONFIG_ECC_MODE_SHIFT, ecc_mode);
+}
+
 static inline void vf610_nfc_transfer_size(struct vf610_nfc *nfc, int size)
 {
 	vf610_nfc_write(nfc, NFC_SECTOR_SIZE, size);
@@ -316,6 +367,8 @@ static void vf610_nfc_command(struct mtd_info *mtd, unsigned command,
 	case NAND_CMD_SEQIN:
 		/* Use valid column/page from preread... */
 		vf610_nfc_addr_cycle(nfc, column, page);
+		nfc->buf_offset = 0;
+
 		/*
 		 * SEQIN => data => PAGEPROG sequence is done by the controller
 		 * hence we do not need to issue the command here...
@@ -324,6 +377,11 @@ static void vf610_nfc_command(struct mtd_info *mtd, unsigned command,
 	case NAND_CMD_PAGEPROG:
 		trfr_sz += nfc->write_sz;
 
+		if (nfc->use_hw_ecc)
+			vf610_nfc_ecc_mode(nfc, nfc->ecc_mode);
+		else
+			vf610_nfc_ecc_mode(nfc, ECC_BYPASS);
+
 		vf610_nfc_transfer_size(nfc, trfr_sz);
 		vf610_nfc_send_commands(nfc, NAND_CMD_SEQIN,
 					command, PROGRAM_PAGE_CMD_CODE);
@@ -341,11 +399,13 @@ static void vf610_nfc_command(struct mtd_info *mtd, unsigned command,
 		vf610_nfc_send_commands(nfc, NAND_CMD_READ0,
 					NAND_CMD_READSTART, READ_PAGE_CMD_CODE);
 		vf610_nfc_addr_cycle(nfc, column, page);
+		vf610_nfc_ecc_mode(nfc, ECC_BYPASS);
 		break;
 
 	case NAND_CMD_READ0:
 		trfr_sz += mtd->writesize + mtd->oobsize;
 		vf610_nfc_transfer_size(nfc, trfr_sz);
+		vf610_nfc_ecc_mode(nfc, nfc->ecc_mode);
 		vf610_nfc_send_commands(nfc, NAND_CMD_READ0,
 					NAND_CMD_READSTART, READ_PAGE_CMD_CODE);
 		vf610_nfc_addr_cycle(nfc, column, page);
@@ -358,6 +418,7 @@ static void vf610_nfc_command(struct mtd_info *mtd, unsigned command,
 		vf610_nfc_send_command(nfc, command, READ_ONFI_PARAM_CMD_CODE);
 		vf610_nfc_set_field(nfc, NFC_ROW_ADDR, ROW_ADDR_MASK,
 				    ROW_ADDR_SHIFT, column);
+		vf610_nfc_ecc_mode(nfc, ECC_BYPASS);
 		break;
 
 	case NAND_CMD_ERASE1:
@@ -387,6 +448,7 @@ static void vf610_nfc_command(struct mtd_info *mtd, unsigned command,
 
 	vf610_nfc_done(nfc);
 
+	nfc->use_hw_ecc = false;
 	nfc->write_sz = 0;
 }
 
@@ -481,6 +543,94 @@ static void vf610_nfc_select_chip(struct mtd_info *mtd, int chip)
 	vf610_nfc_write(nfc, NFC_ROW_ADDR, tmp);
 }
 
+/* Count the number of 0's in buff up to max_bits */
+static inline int count_written_bits(uint8_t *buff, int size, int max_bits)
+{
+	uint32_t *buff32 = (uint32_t *)buff;
+	int k, written_bits = 0;
+
+	for (k = 0; k < (size / 4); k++) {
+		written_bits += hweight32(~buff32[k]);
+		if (unlikely(written_bits > max_bits))
+			break;
+	}
+
+	return written_bits;
+}
+
+static inline int vf610_nfc_correct_data(struct mtd_info *mtd, uint8_t *dat,
+					 uint8_t *oob, int page)
+{
+	struct vf610_nfc *nfc = mtd_to_nfc(mtd);
+	u32 ecc_status_off = NFC_MAIN_AREA(0) + ECC_SRAM_ADDR + ECC_STATUS;
+	u8 ecc_status;
+	u8 ecc_count;
+	int flips;
+	int flips_threshold = nfc->chip.ecc.strength / 2;
+
+	ecc_status = vf610_nfc_read(nfc, ecc_status_off) & 0xff;
+	ecc_count = ecc_status & ECC_STATUS_ERR_COUNT;
+
+	if (!(ecc_status & ECC_STATUS_MASK))
+		return ecc_count;
+
+	/* Read OOB without ECC unit enabled */
+	vf610_nfc_command(mtd, NAND_CMD_READOOB, 0, page);
+	vf610_nfc_read_buf(mtd, oob, mtd->oobsize);
+
+	/*
+	 * On an erased page, bit count (including OOB) should be zero or
+	 * at least less then half of the ECC strength.
+	 */
+	flips = count_written_bits(dat, nfc->chip.ecc.size, flips_threshold);
+	flips += count_written_bits(oob, mtd->oobsize, flips_threshold);
+
+	if (unlikely(flips > flips_threshold))
+		return -EINVAL;
+
+	/* Erased page. */
+	memset(dat, 0xff, nfc->chip.ecc.size);
+	memset(oob, 0xff, mtd->oobsize);
+	return 0;
+}
+
+static int vf610_nfc_read_page(struct mtd_info *mtd, struct nand_chip *chip,
+				uint8_t *buf, int oob_required, int page)
+{
+	int eccsize = chip->ecc.size;
+	int stat;
+
+	vf610_nfc_read_buf(mtd, buf, eccsize);
+	if (oob_required)
+		vf610_nfc_read_buf(mtd, chip->oob_poi, mtd->oobsize);
+
+	stat = vf610_nfc_correct_data(mtd, buf, chip->oob_poi, page);
+
+	if (stat < 0) {
+		mtd->ecc_stats.failed++;
+		return 0;
+	} else {
+		mtd->ecc_stats.corrected += stat;
+		return stat;
+	}
+}
+
+static int vf610_nfc_write_page(struct mtd_info *mtd, struct nand_chip *chip,
+			       const uint8_t *buf, int oob_required)
+{
+	struct vf610_nfc *nfc = mtd_to_nfc(mtd);
+
+	vf610_nfc_write_buf(mtd, buf, mtd->writesize);
+	if (oob_required)
+		vf610_nfc_write_buf(mtd, chip->oob_poi, mtd->oobsize);
+
+	/* Always write whole page including OOB due to HW ECC */
+	nfc->use_hw_ecc = true;
+	nfc->write_sz = mtd->writesize + mtd->oobsize;
+
+	return 0;
+}
+
 static const struct of_device_id vf610_nfc_dt_ids[] = {
 	{ .compatible = "fsl,vf610-nfc", .data = (void *)NFC_VFC610 },
 	{ /* sentinel */ }
@@ -507,6 +657,17 @@ static void vf610_nfc_init_controller(struct vf610_nfc *nfc)
 		vf610_nfc_set(nfc, NFC_FLASH_CONFIG, CONFIG_16BIT);
 	else
 		vf610_nfc_clear(nfc, NFC_FLASH_CONFIG, CONFIG_16BIT);
+
+	if (nfc->chip.ecc.mode == NAND_ECC_HW) {
+		/* Set ECC status offset in SRAM */
+		vf610_nfc_set_field(nfc, NFC_FLASH_CONFIG,
+				    CONFIG_ECC_SRAM_ADDR_MASK,
+				    CONFIG_ECC_SRAM_ADDR_SHIFT,
+				    ECC_SRAM_ADDR >> 3);
+
+		/* Enable ECC status in SRAM */
+		vf610_nfc_set(nfc, NFC_FLASH_CONFIG, CONFIG_ECC_SRAM_REQ_BIT);
+	}
 }
 
 static int vf610_nfc_probe(struct platform_device *pdev)
@@ -614,6 +775,45 @@ static int vf610_nfc_probe(struct platform_device *pdev)
 		goto error;
 	}
 
+	if (chip->ecc.mode == NAND_ECC_HW) {
+		if (mtd->writesize != PAGE_2K && mtd->oobsize < 64) {
+			dev_err(nfc->dev, "Unsupported flash with hwecc\n");
+			err = -ENXIO;
+			goto error;
+		}
+
+		if (chip->ecc.size != mtd->writesize) {
+			dev_err(nfc->dev, "Step size needs to be page size\n");
+			err = -ENXIO;
+			goto error;
+		}
+
+		/* Only 64 byte ECC layouts known */
+		if (mtd->oobsize > 64)
+			mtd->oobsize = 64;
+
+		if (chip->ecc.strength == 32) {
+			nfc->ecc_mode = ECC_60_BYTE;
+			chip->ecc.bytes = 60;
+			chip->ecc.layout = &vf610_nfc_ecc60;
+		} else if (chip->ecc.strength == 24) {
+			nfc->ecc_mode = ECC_45_BYTE;
+			chip->ecc.bytes = 45;
+			chip->ecc.layout = &vf610_nfc_ecc45;
+		} else {
+			dev_err(nfc->dev, "Unsupported ECC strength\n");
+			err = -ENXIO;
+			goto error;
+		}
+
+		/* propagate ecc.layout to mtd_info */
+		mtd->ecclayout = chip->ecc.layout;
+		chip->ecc.read_page = vf610_nfc_read_page;
+		chip->ecc.write_page = vf610_nfc_write_page;
+
+		chip->ecc.size = PAGE_2K;
+	}
+
 	/* second phase scan */
 	if (nand_scan_tail(mtd)) {
 		err = -ENXIO;
-- 
2.5.0



From stefan at agner.ch  Thu Aug 27 17:34:56 2015
From: stefan at agner.ch (Stefan Agner)
Date: Thu, 27 Aug 2015 17:34:56 -0700
Subject: [PATCH v11 1/5] mtd: nand: vf610_nfc: Freescale NFC for VF610,
 MPC5125 and others
In-Reply-To: <1440722100-25388-1-git-send-email-stefan@agner.ch>
References: <1440722100-25388-1-git-send-email-stefan@agner.ch>
Message-ID: <1440722100-25388-2-git-send-email-stefan@agner.ch>

This driver supports Freescale NFC (NAND flash controller) found on
Vybrid (VF610), MPC5125, MCF54418 and Kinetis K70. The driver has
been tested using 8-bit and 16-bit NAND interface on the ARM based
Vybrid SoC VF500 and VF610 platform.
parameter page reading.

Limitations:
- Untested on MPC5125 and M54418.
- DMA and pipelining not used.
- 2K pages or less.
- No chip select, one NAND chip per controller.
- No hardware ECC.

Some paths have been hand-optimized and evaluated by measurements
made using mtd_speedtest.ko on a 100MB MTD partition.

Colibri VF50
        eb write     %   eb read     %   page write      %   page read     %
rel/opt     5175           11537                4560             11039
opt         5164 -0.21     11420 -1.01          4737 +3.88       10918 -1.10
none        5113 -1.20     11352 -1.60          4490 -1.54       10865 -1.58

Colibri VF61
        eb write     %   eb read     %   page write      %   page read     %
rel/opt     5766           13096                5459             12846
opt         5883 +2.03     13064 -0.24          5561 +1.87       12802 -0.34
none        5701 -1.13     12980 -0.89          5488 +0.53       12735 -0.86

rel = using readl_relaxed/writel_relaxed in optimized paths
opt = hand-optimized by combining multiple accesses into one read/write

The measurements have not been statistically verfied, hence use them
with care. The author came to the conclusion that using the relaxed
variants of readl/writel are not worth the additional code.

Signed-off-by: Bill Pringlemeir <bpringlemeir at nbsps.com>
Tested-by: Albert ARIBAUD <albert.aribaud at 3adev.fr>
Signed-off-by: Stefan Agner <stefan at agner.ch>
---
 MAINTAINERS                  |   6 +
 drivers/mtd/nand/Kconfig     |   9 +
 drivers/mtd/nand/Makefile    |   1 +
 drivers/mtd/nand/vf610_nfc.c | 690 +++++++++++++++++++++++++++++++++++++++++++
 4 files changed, 706 insertions(+)
 create mode 100644 drivers/mtd/nand/vf610_nfc.c

diff --git a/MAINTAINERS b/MAINTAINERS
index 9567329..59975c7 100644
--- a/MAINTAINERS
+++ b/MAINTAINERS
@@ -10835,6 +10835,12 @@ S:	Maintained
 F:	Documentation/fb/uvesafb.txt
 F:	drivers/video/fbdev/uvesafb.*
 
+VF610 NAND DRIVER
+M:	Stefan Agner <stefan at agner.ch>
+L:	linux-mtd at lists.infradead.org
+S:	Supported
+F:	drivers/mtd/nand/vf610_nfc.c
+
 VFAT/FAT/MSDOS FILESYSTEM
 M:	OGAWA Hirofumi <hirofumi at mail.parknet.co.jp>
 S:	Maintained
diff --git a/drivers/mtd/nand/Kconfig b/drivers/mtd/nand/Kconfig
index 3324281..9f9736c 100644
--- a/drivers/mtd/nand/Kconfig
+++ b/drivers/mtd/nand/Kconfig
@@ -460,6 +460,15 @@ config MTD_NAND_MPC5121_NFC
 	  This enables the driver for the NAND flash controller on the
 	  MPC5121 SoC.
 
+config MTD_NAND_VF610_NFC
+	tristate "Support for Freescale NFC for VF610/MPC5125"
+	depends on (SOC_VF610 || COMPILE_TEST)
+	help
+	  Enables support for NAND Flash Controller on some Freescale
+	  processors like the VF610, MPC5125, MCF54418 or Kinetis K70.
+	  The driver supports a maximum 2k page size. The driver
+	  currently does not support hardware ECC.
+
 config MTD_NAND_MXC
 	tristate "MXC NAND support"
 	depends on ARCH_MXC
diff --git a/drivers/mtd/nand/Makefile b/drivers/mtd/nand/Makefile
index 1f897ec..a490af8 100644
--- a/drivers/mtd/nand/Makefile
+++ b/drivers/mtd/nand/Makefile
@@ -45,6 +45,7 @@ obj-$(CONFIG_MTD_NAND_SOCRATES)		+= socrates_nand.o
 obj-$(CONFIG_MTD_NAND_TXX9NDFMC)	+= txx9ndfmc.o
 obj-$(CONFIG_MTD_NAND_NUC900)		+= nuc900_nand.o
 obj-$(CONFIG_MTD_NAND_MPC5121_NFC)	+= mpc5121_nfc.o
+obj-$(CONFIG_MTD_NAND_VF610_NFC)	+= vf610_nfc.o
 obj-$(CONFIG_MTD_NAND_RICOH)		+= r852.o
 obj-$(CONFIG_MTD_NAND_JZ4740)		+= jz4740_nand.o
 obj-$(CONFIG_MTD_NAND_GPMI_NAND)	+= gpmi-nand/
diff --git a/drivers/mtd/nand/vf610_nfc.c b/drivers/mtd/nand/vf610_nfc.c
new file mode 100644
index 0000000..eba67dc
--- /dev/null
+++ b/drivers/mtd/nand/vf610_nfc.c
@@ -0,0 +1,690 @@
+/*
+ * Copyright 2009-2015 Freescale Semiconductor, Inc. and others
+ *
+ * Description: MPC5125, VF610, MCF54418 and Kinetis K70 Nand driver.
+ * Jason ported to M54418TWR and MVFA5 (VF610).
+ * Authors: Stefan Agner <stefan.agner at toradex.com>
+ *          Bill Pringlemeir <bpringlemeir at nbsps.com>
+ *          Shaohui Xie <b21989 at freescale.com>
+ *          Jason Jin <Jason.jin at freescale.com>
+ *
+ * Based on original driver mpc5121_nfc.c.
+ *
+ * This 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.
+ *
+ * Limitations:
+ * - Untested on MPC5125 and M54418.
+ * - DMA and pipelining not used.
+ * - 2K pages or less.
+ * - No chip select, one NAND chip per controller.
+ * - No hardware ECC.
+ */
+
+#include <linux/module.h>
+#include <linux/bitops.h>
+#include <linux/clk.h>
+#include <linux/delay.h>
+#include <linux/init.h>
+#include <linux/interrupt.h>
+#include <linux/io.h>
+#include <linux/mtd/mtd.h>
+#include <linux/mtd/nand.h>
+#include <linux/mtd/partitions.h>
+#include <linux/of_mtd.h>
+#include <linux/of_device.h>
+#include <linux/platform_device.h>
+#include <linux/slab.h>
+
+#define	DRV_NAME		"vf610_nfc"
+
+/* Register Offsets */
+#define NFC_FLASH_CMD1			0x3F00
+#define NFC_FLASH_CMD2			0x3F04
+#define NFC_COL_ADDR			0x3F08
+#define NFC_ROW_ADDR			0x3F0c
+#define NFC_ROW_ADDR_INC		0x3F14
+#define NFC_FLASH_STATUS1		0x3F18
+#define NFC_FLASH_STATUS2		0x3F1c
+#define NFC_CACHE_SWAP			0x3F28
+#define NFC_SECTOR_SIZE			0x3F2c
+#define NFC_FLASH_CONFIG		0x3F30
+#define NFC_IRQ_STATUS			0x3F38
+
+/* Addresses for NFC MAIN RAM BUFFER areas */
+#define NFC_MAIN_AREA(n)		((n) *  0x1000)
+
+#define PAGE_2K				0x0800
+#define OOB_64				0x0040
+#define OOB_MAX				0x0100
+
+/*
+ * NFC_CMD2[CODE] values. See section:
+ *  - 31.4.7 Flash Command Code Description, Vybrid manual
+ *  - 23.8.6 Flash Command Sequencer, MPC5125 manual
+ *
+ * Briefly these are bitmasks of controller cycles.
+ */
+#define READ_PAGE_CMD_CODE		0x7EE0
+#define READ_ONFI_PARAM_CMD_CODE	0x4860
+#define PROGRAM_PAGE_CMD_CODE		0x7FC0
+#define ERASE_CMD_CODE			0x4EC0
+#define READ_ID_CMD_CODE		0x4804
+#define RESET_CMD_CODE			0x4040
+#define STATUS_READ_CMD_CODE		0x4068
+
+/* NFC ECC mode define */
+#define ECC_BYPASS			0
+
+/*** Register Mask and bit definitions */
+
+/* NFC_FLASH_CMD1 Field */
+#define CMD_BYTE2_MASK				0xFF000000
+#define CMD_BYTE2_SHIFT				24
+
+/* NFC_FLASH_CM2 Field */
+#define CMD_BYTE1_MASK				0xFF000000
+#define CMD_BYTE1_SHIFT				24
+#define CMD_CODE_MASK				0x00FFFF00
+#define CMD_CODE_SHIFT				8
+#define BUFNO_MASK				0x00000006
+#define BUFNO_SHIFT				1
+#define START_BIT				BIT(0)
+
+/* NFC_COL_ADDR Field */
+#define COL_ADDR_MASK				0x0000FFFF
+#define COL_ADDR_SHIFT				0
+
+/* NFC_ROW_ADDR Field */
+#define ROW_ADDR_MASK				0x00FFFFFF
+#define ROW_ADDR_SHIFT				0
+#define ROW_ADDR_CHIP_SEL_RB_MASK		0xF0000000
+#define ROW_ADDR_CHIP_SEL_RB_SHIFT		28
+#define ROW_ADDR_CHIP_SEL_MASK			0x0F000000
+#define ROW_ADDR_CHIP_SEL_SHIFT			24
+
+/* NFC_FLASH_STATUS2 Field */
+#define STATUS_BYTE1_MASK			0x000000FF
+
+/* NFC_FLASH_CONFIG Field */
+#define CONFIG_ECC_SRAM_ADDR_MASK		0x7FC00000
+#define CONFIG_ECC_SRAM_ADDR_SHIFT		22
+#define CONFIG_ECC_SRAM_REQ_BIT			BIT(21)
+#define CONFIG_DMA_REQ_BIT			BIT(20)
+#define CONFIG_ECC_MODE_MASK			0x000E0000
+#define CONFIG_ECC_MODE_SHIFT			17
+#define CONFIG_FAST_FLASH_BIT			BIT(16)
+#define CONFIG_16BIT				BIT(7)
+#define CONFIG_BOOT_MODE_BIT			BIT(6)
+#define CONFIG_ADDR_AUTO_INCR_BIT		BIT(5)
+#define CONFIG_BUFNO_AUTO_INCR_BIT		BIT(4)
+#define CONFIG_PAGE_CNT_MASK			0xF
+#define CONFIG_PAGE_CNT_SHIFT			0
+
+/* NFC_IRQ_STATUS Field */
+#define IDLE_IRQ_BIT				BIT(29)
+#define IDLE_EN_BIT				BIT(20)
+#define CMD_DONE_CLEAR_BIT			BIT(18)
+#define IDLE_CLEAR_BIT				BIT(17)
+
+enum vf610_nfc_alt_buf {
+	ALT_BUF_DATA = 0,
+	ALT_BUF_ID = 1,
+	ALT_BUF_STAT = 2,
+	ALT_BUF_ONFI = 3,
+};
+
+enum vf610_nfc_variant {
+	NFC_VFC610 = 1,
+};
+
+struct vf610_nfc {
+	struct mtd_info mtd;
+	struct nand_chip chip;
+	struct device *dev;
+	void __iomem *regs;
+	struct completion cmd_done;
+	uint buf_offset;
+	int write_sz;
+	/* Status and ID are in alternate locations. */
+	enum vf610_nfc_alt_buf alt_buf;
+	enum vf610_nfc_variant variant;
+	struct clk *clk;
+};
+
+#define mtd_to_nfc(_mtd) container_of(_mtd, struct vf610_nfc, mtd)
+
+static inline u32 vf610_nfc_read(struct vf610_nfc *nfc, uint reg)
+{
+	return readl(nfc->regs + reg);
+}
+
+static inline void vf610_nfc_write(struct vf610_nfc *nfc, uint reg, u32 val)
+{
+	writel(val, nfc->regs + reg);
+}
+
+static inline void vf610_nfc_set(struct vf610_nfc *nfc, uint reg, u32 bits)
+{
+	vf610_nfc_write(nfc, reg, vf610_nfc_read(nfc, reg) | bits);
+}
+
+static inline void vf610_nfc_clear(struct vf610_nfc *nfc, uint reg, u32 bits)
+{
+	vf610_nfc_write(nfc, reg, vf610_nfc_read(nfc, reg) & ~bits);
+}
+
+static inline void vf610_nfc_set_field(struct vf610_nfc *nfc, u32 reg,
+				       u32 mask, u32 shift, u32 val)
+{
+	vf610_nfc_write(nfc, reg,
+			(vf610_nfc_read(nfc, reg) & (~mask)) | val << shift);
+}
+
+static inline void vf610_nfc_memcpy(void *dst, const void __iomem *src,
+				    size_t n)
+{
+	/*
+	 * Use this accessor for the internal SRAM buffers. On the ARM
+	 * Freescale Vybrid SoC it's known that the driver can treat
+	 * the SRAM buffer as if it's memory. Other platform might need
+	 * to treat the buffers differently.
+	 *
+	 * For the time being, use memcpy
+	 */
+	memcpy(dst, src, n);
+}
+
+/* Clear flags for upcoming command */
+static inline void vf610_nfc_clear_status(struct vf610_nfc *nfc)
+{
+	u32 tmp = vf610_nfc_read(nfc, NFC_IRQ_STATUS);
+
+	tmp |= CMD_DONE_CLEAR_BIT | IDLE_CLEAR_BIT;
+	vf610_nfc_write(nfc, NFC_IRQ_STATUS, tmp);
+}
+
+static void vf610_nfc_done(struct vf610_nfc *nfc)
+{
+	unsigned long timeout = msecs_to_jiffies(100);
+
+	/*
+	 * Barrier is needed after this write. This write need
+	 * to be done before reading the next register the first
+	 * time.
+	 * vf610_nfc_set implicates such a barrier by using writel
+	 * to write to the register.
+	 */
+	vf610_nfc_set(nfc, NFC_IRQ_STATUS, IDLE_EN_BIT);
+	vf610_nfc_set(nfc, NFC_FLASH_CMD2, START_BIT);
+
+	if (!(vf610_nfc_read(nfc, NFC_IRQ_STATUS) & IDLE_IRQ_BIT)) {
+		if (!wait_for_completion_timeout(&nfc->cmd_done, timeout))
+			dev_warn(nfc->dev, "Timeout while waiting for BUSY.\n");
+	}
+	vf610_nfc_clear_status(nfc);
+}
+
+static u8 vf610_nfc_get_id(struct vf610_nfc *nfc, int col)
+{
+	u32 flash_id;
+
+	if (col < 4) {
+		flash_id = vf610_nfc_read(nfc, NFC_FLASH_STATUS1);
+		flash_id >>= (3 - col) * 8;
+	} else {
+		flash_id = vf610_nfc_read(nfc, NFC_FLASH_STATUS2);
+		flash_id >>= 24;
+	}
+
+	return flash_id & 0xff;
+}
+
+static u8 vf610_nfc_get_status(struct vf610_nfc *nfc)
+{
+	return vf610_nfc_read(nfc, NFC_FLASH_STATUS2) & STATUS_BYTE1_MASK;
+}
+
+static void vf610_nfc_send_command(struct vf610_nfc *nfc, u32 cmd_byte1,
+				   u32 cmd_code)
+{
+	u32 tmp;
+
+	vf610_nfc_clear_status(nfc);
+
+	tmp = vf610_nfc_read(nfc, NFC_FLASH_CMD2);
+	tmp &= ~(CMD_BYTE1_MASK | CMD_CODE_MASK | BUFNO_MASK);
+	tmp |= cmd_byte1 << CMD_BYTE1_SHIFT;
+	tmp |= cmd_code << CMD_CODE_SHIFT;
+	vf610_nfc_write(nfc, NFC_FLASH_CMD2, tmp);
+}
+
+static void vf610_nfc_send_commands(struct vf610_nfc *nfc, u32 cmd_byte1,
+				    u32 cmd_byte2, u32 cmd_code)
+{
+	u32 tmp;
+
+	vf610_nfc_send_command(nfc, cmd_byte1, cmd_code);
+
+	tmp = vf610_nfc_read(nfc, NFC_FLASH_CMD1);
+	tmp &= ~CMD_BYTE2_MASK;
+	tmp |= cmd_byte2 << CMD_BYTE2_SHIFT;
+	vf610_nfc_write(nfc, NFC_FLASH_CMD1, tmp);
+}
+
+static irqreturn_t vf610_nfc_irq(int irq, void *data)
+{
+	struct mtd_info *mtd = data;
+	struct vf610_nfc *nfc = mtd_to_nfc(mtd);
+
+	vf610_nfc_clear(nfc, NFC_IRQ_STATUS, IDLE_EN_BIT);
+	complete(&nfc->cmd_done);
+
+	return IRQ_HANDLED;
+}
+
+static void vf610_nfc_addr_cycle(struct vf610_nfc *nfc, int column, int page)
+{
+	if (column != -1) {
+		if (nfc->chip.options & NAND_BUSWIDTH_16)
+			column = column / 2;
+		vf610_nfc_set_field(nfc, NFC_COL_ADDR, COL_ADDR_MASK,
+				    COL_ADDR_SHIFT, column);
+	}
+	if (page != -1)
+		vf610_nfc_set_field(nfc, NFC_ROW_ADDR, ROW_ADDR_MASK,
+				    ROW_ADDR_SHIFT, page);
+}
+
+static inline void vf610_nfc_transfer_size(struct vf610_nfc *nfc, int size)
+{
+	vf610_nfc_write(nfc, NFC_SECTOR_SIZE, size);
+}
+
+static void vf610_nfc_command(struct mtd_info *mtd, unsigned command,
+			      int column, int page)
+{
+	struct vf610_nfc *nfc = mtd_to_nfc(mtd);
+	int trfr_sz = nfc->chip.options & NAND_BUSWIDTH_16 ? 1 : 0;
+
+	nfc->buf_offset = max(column, 0);
+	nfc->alt_buf = ALT_BUF_DATA;
+
+	switch (command) {
+	case NAND_CMD_SEQIN:
+		/* Use valid column/page from preread... */
+		vf610_nfc_addr_cycle(nfc, column, page);
+		/*
+		 * SEQIN => data => PAGEPROG sequence is done by the controller
+		 * hence we do not need to issue the command here...
+		 */
+		return;
+	case NAND_CMD_PAGEPROG:
+		trfr_sz += nfc->write_sz;
+
+		vf610_nfc_transfer_size(nfc, trfr_sz);
+		vf610_nfc_send_commands(nfc, NAND_CMD_SEQIN,
+					command, PROGRAM_PAGE_CMD_CODE);
+		break;
+
+	case NAND_CMD_RESET:
+		vf610_nfc_transfer_size(nfc, 0);
+		vf610_nfc_send_command(nfc, command, RESET_CMD_CODE);
+		break;
+
+	case NAND_CMD_READOOB:
+		trfr_sz += mtd->oobsize;
+		column = mtd->writesize;
+		vf610_nfc_transfer_size(nfc, trfr_sz);
+		vf610_nfc_send_commands(nfc, NAND_CMD_READ0,
+					NAND_CMD_READSTART, READ_PAGE_CMD_CODE);
+		vf610_nfc_addr_cycle(nfc, column, page);
+		break;
+
+	case NAND_CMD_READ0:
+		trfr_sz += mtd->writesize + mtd->oobsize;
+		vf610_nfc_transfer_size(nfc, trfr_sz);
+		vf610_nfc_send_commands(nfc, NAND_CMD_READ0,
+					NAND_CMD_READSTART, READ_PAGE_CMD_CODE);
+		vf610_nfc_addr_cycle(nfc, column, page);
+		break;
+
+	case NAND_CMD_PARAM:
+		nfc->alt_buf = ALT_BUF_ONFI;
+		trfr_sz = 3 * sizeof(struct nand_onfi_params);
+		vf610_nfc_transfer_size(nfc, trfr_sz);
+		vf610_nfc_send_command(nfc, command, READ_ONFI_PARAM_CMD_CODE);
+		vf610_nfc_set_field(nfc, NFC_ROW_ADDR, ROW_ADDR_MASK,
+				    ROW_ADDR_SHIFT, column);
+		break;
+
+	case NAND_CMD_ERASE1:
+		vf610_nfc_transfer_size(nfc, 0);
+		vf610_nfc_send_commands(nfc, command,
+					NAND_CMD_ERASE2, ERASE_CMD_CODE);
+		vf610_nfc_addr_cycle(nfc, column, page);
+		break;
+
+	case NAND_CMD_READID:
+		nfc->alt_buf = ALT_BUF_ID;
+		nfc->buf_offset = 0;
+		vf610_nfc_transfer_size(nfc, 0);
+		vf610_nfc_send_command(nfc, command, READ_ID_CMD_CODE);
+		vf610_nfc_set_field(nfc, NFC_ROW_ADDR, ROW_ADDR_MASK,
+				    ROW_ADDR_SHIFT, column);
+		break;
+
+	case NAND_CMD_STATUS:
+		nfc->alt_buf = ALT_BUF_STAT;
+		vf610_nfc_transfer_size(nfc, 0);
+		vf610_nfc_send_command(nfc, command, STATUS_READ_CMD_CODE);
+		break;
+	default:
+		return;
+	}
+
+	vf610_nfc_done(nfc);
+
+	nfc->write_sz = 0;
+}
+
+static void vf610_nfc_read_buf(struct mtd_info *mtd, u_char *buf, int len)
+{
+	struct vf610_nfc *nfc = mtd_to_nfc(mtd);
+	uint c = nfc->buf_offset;
+
+	/* Alternate buffers are only supported through read_byte */
+	WARN_ON(nfc->alt_buf);
+
+	vf610_nfc_memcpy(buf, nfc->regs + NFC_MAIN_AREA(0) + c, len);
+
+	nfc->buf_offset += len;
+}
+
+static void vf610_nfc_write_buf(struct mtd_info *mtd, const uint8_t *buf,
+				int len)
+{
+	struct vf610_nfc *nfc = mtd_to_nfc(mtd);
+	uint c = nfc->buf_offset;
+	uint l;
+
+	l = min_t(uint, len, mtd->writesize + mtd->oobsize - c);
+	vf610_nfc_memcpy(nfc->regs + NFC_MAIN_AREA(0) + c, buf, l);
+
+	nfc->write_sz += l;
+	nfc->buf_offset += l;
+}
+
+static uint8_t vf610_nfc_read_byte(struct mtd_info *mtd)
+{
+	struct vf610_nfc *nfc = mtd_to_nfc(mtd);
+	u8 tmp;
+	uint c = nfc->buf_offset;
+
+	switch (nfc->alt_buf) {
+	case ALT_BUF_ID:
+		tmp = vf610_nfc_get_id(nfc, c);
+		break;
+	case ALT_BUF_STAT:
+		tmp = vf610_nfc_get_status(nfc);
+		break;
+#ifdef __LITTLE_ENDIAN
+	case ALT_BUF_ONFI:
+		/* Reverse byte since the controller uses big endianness */
+		c = nfc->buf_offset ^ 0x3;
+		/* fall-through */
+#endif
+	default:
+		tmp = *((u8 *)(nfc->regs + NFC_MAIN_AREA(0) + c));
+		break;
+	}
+	nfc->buf_offset++;
+	return tmp;
+}
+
+static u16 vf610_nfc_read_word(struct mtd_info *mtd)
+{
+	u16 tmp;
+
+	vf610_nfc_read_buf(mtd, (u_char *)&tmp, sizeof(tmp));
+	return tmp;
+}
+
+/* If not provided, upper layers apply a fixed delay. */
+static int vf610_nfc_dev_ready(struct mtd_info *mtd)
+{
+	/* NFC handles R/B internally; always ready.  */
+	return 1;
+}
+
+/*
+ * This function supports Vybrid only (MPC5125 would have full RB and four CS)
+ */
+static void vf610_nfc_select_chip(struct mtd_info *mtd, int chip)
+{
+	struct vf610_nfc *nfc = mtd_to_nfc(mtd);
+	u32 tmp = vf610_nfc_read(nfc, NFC_ROW_ADDR);
+
+	/* Vybrid only (MPC5125 would have full RB and four CS) */
+	if (nfc->variant != NFC_VFC610)
+		return;
+
+	tmp &= ~(ROW_ADDR_CHIP_SEL_RB_MASK | ROW_ADDR_CHIP_SEL_MASK);
+
+	if (chip >= 0) {
+		tmp |= 1 << ROW_ADDR_CHIP_SEL_RB_SHIFT;
+		tmp |= BIT(chip) << ROW_ADDR_CHIP_SEL_SHIFT;
+	}
+
+	vf610_nfc_write(nfc, NFC_ROW_ADDR, tmp);
+}
+
+static const struct of_device_id vf610_nfc_dt_ids[] = {
+	{ .compatible = "fsl,vf610-nfc", .data = (void *)NFC_VFC610 },
+	{ /* sentinel */ }
+};
+MODULE_DEVICE_TABLE(of, vf610_nfc_dt_ids);
+
+static void vf610_nfc_preinit_controller(struct vf610_nfc *nfc)
+{
+	vf610_nfc_clear(nfc, NFC_FLASH_CONFIG, CONFIG_16BIT);
+	vf610_nfc_clear(nfc, NFC_FLASH_CONFIG, CONFIG_ADDR_AUTO_INCR_BIT);
+	vf610_nfc_clear(nfc, NFC_FLASH_CONFIG, CONFIG_BUFNO_AUTO_INCR_BIT);
+	vf610_nfc_clear(nfc, NFC_FLASH_CONFIG, CONFIG_BOOT_MODE_BIT);
+	vf610_nfc_clear(nfc, NFC_FLASH_CONFIG, CONFIG_DMA_REQ_BIT);
+	vf610_nfc_set(nfc, NFC_FLASH_CONFIG, CONFIG_FAST_FLASH_BIT);
+
+	/* Disable virtual pages, only one elementary transfer unit */
+	vf610_nfc_set_field(nfc, NFC_FLASH_CONFIG, CONFIG_PAGE_CNT_MASK,
+			    CONFIG_PAGE_CNT_SHIFT, 1);
+}
+
+static void vf610_nfc_init_controller(struct vf610_nfc *nfc)
+{
+	if (nfc->chip.options & NAND_BUSWIDTH_16)
+		vf610_nfc_set(nfc, NFC_FLASH_CONFIG, CONFIG_16BIT);
+	else
+		vf610_nfc_clear(nfc, NFC_FLASH_CONFIG, CONFIG_16BIT);
+}
+
+static int vf610_nfc_probe(struct platform_device *pdev)
+{
+	struct vf610_nfc *nfc;
+	struct resource *res;
+	struct mtd_info *mtd;
+	struct nand_chip *chip;
+	struct device_node *child;
+	const struct of_device_id *of_id;
+	int err = 0;
+	int irq;
+
+	nfc = devm_kzalloc(&pdev->dev, sizeof(*nfc), GFP_KERNEL);
+	if (!nfc)
+		return -ENOMEM;
+
+	nfc->dev = &pdev->dev;
+	mtd = &nfc->mtd;
+	chip = &nfc->chip;
+
+	mtd->priv = chip;
+	mtd->owner = THIS_MODULE;
+	mtd->dev.parent = nfc->dev;
+	mtd->name = DRV_NAME;
+
+	irq = platform_get_irq(pdev, 0);
+	if (irq <= 0)
+		return -EINVAL;
+
+	res = platform_get_resource(pdev, IORESOURCE_MEM, 0);
+	nfc->regs = devm_ioremap_resource(nfc->dev, res);
+	if (IS_ERR(nfc->regs))
+		return PTR_ERR(nfc->regs);
+
+	nfc->clk = devm_clk_get(&pdev->dev, NULL);
+	if (IS_ERR(nfc->clk))
+		return PTR_ERR(nfc->clk);
+
+	err = clk_prepare_enable(nfc->clk);
+	if (err) {
+		dev_err(nfc->dev, "Unable to enable clock!\n");
+		return err;
+	}
+
+	of_id = of_match_device(vf610_nfc_dt_ids, &pdev->dev);
+	nfc->variant = (enum vf610_nfc_variant)of_id->data;
+
+	for_each_available_child_of_node(nfc->dev->of_node, child) {
+		if (of_device_is_compatible(child, "fsl,vf610-nfc-nandcs")) {
+
+			if (chip->dn) {
+				dev_err(nfc->dev,
+					"Only one NAND chip supported!\n");
+				err = -EINVAL;
+				goto error;
+			}
+
+			chip->dn = child;
+		}
+	}
+
+	if (!chip->dn) {
+		dev_err(nfc->dev, "NAND chip sub-node missing!\n");
+		err = -ENODEV;
+		goto err_clk;
+	}
+
+	chip->dev_ready = vf610_nfc_dev_ready;
+	chip->cmdfunc = vf610_nfc_command;
+	chip->read_byte = vf610_nfc_read_byte;
+	chip->read_word = vf610_nfc_read_word;
+	chip->read_buf = vf610_nfc_read_buf;
+	chip->write_buf = vf610_nfc_write_buf;
+	chip->select_chip = vf610_nfc_select_chip;
+
+	chip->options |= NAND_NO_SUBPAGE_WRITE;
+
+	init_completion(&nfc->cmd_done);
+
+	err = devm_request_irq(nfc->dev, irq, vf610_nfc_irq, 0, DRV_NAME, mtd);
+	if (err) {
+		dev_err(nfc->dev, "Error requesting IRQ!\n");
+		goto error;
+	}
+
+	vf610_nfc_preinit_controller(nfc);
+
+	/* first scan to find the device and get the page size */
+	if (nand_scan_ident(mtd, 1, NULL)) {
+		err = -ENXIO;
+		goto error;
+	}
+
+	vf610_nfc_init_controller(nfc);
+
+	/* Bad block options. */
+	if (chip->bbt_options & NAND_BBT_USE_FLASH)
+		chip->bbt_options |= NAND_BBT_NO_OOB;
+
+	/* Single buffer only, max 256 OOB minus ECC status */
+	if (mtd->writesize + mtd->oobsize > PAGE_2K + OOB_MAX - 8) {
+		dev_err(nfc->dev, "Unsupported flash page size\n");
+		err = -ENXIO;
+		goto error;
+	}
+
+	/* second phase scan */
+	if (nand_scan_tail(mtd)) {
+		err = -ENXIO;
+		goto error;
+	}
+
+	platform_set_drvdata(pdev, mtd);
+
+	/* Register device in MTD */
+	return mtd_device_parse_register(mtd, NULL,
+		&(struct mtd_part_parser_data){
+			.of_node = chip->dn,
+		},
+		NULL, 0);
+
+error:
+	of_node_put(chip->dn);
+err_clk:
+	clk_disable_unprepare(nfc->clk);
+	return err;
+}
+
+static int vf610_nfc_remove(struct platform_device *pdev)
+{
+	struct mtd_info *mtd = platform_get_drvdata(pdev);
+	struct vf610_nfc *nfc = mtd_to_nfc(mtd);
+
+	nand_release(mtd);
+	clk_disable_unprepare(nfc->clk);
+	return 0;
+}
+
+#ifdef CONFIG_PM_SLEEP
+static int vf610_nfc_suspend(struct device *dev)
+{
+	struct mtd_info *mtd = dev_get_drvdata(dev);
+	struct vf610_nfc *nfc = mtd_to_nfc(mtd);
+
+	clk_disable_unprepare(nfc->clk);
+	return 0;
+}
+
+static int vf610_nfc_resume(struct device *dev)
+{
+	struct mtd_info *mtd = dev_get_drvdata(dev);
+	struct vf610_nfc *nfc = mtd_to_nfc(mtd);
+
+	pinctrl_pm_select_default_state(dev);
+
+	clk_prepare_enable(nfc->clk);
+
+	vf610_nfc_preinit_controller(nfc);
+	vf610_nfc_init_controller(nfc);
+	return 0;
+}
+#endif
+
+static SIMPLE_DEV_PM_OPS(vf610_nfc_pm_ops, vf610_nfc_suspend, vf610_nfc_resume);
+
+static struct platform_driver vf610_nfc_driver = {
+	.driver		= {
+		.name	= DRV_NAME,
+		.of_match_table = vf610_nfc_dt_ids,
+		.pm	= &vf610_nfc_pm_ops,
+	},
+	.probe		= vf610_nfc_probe,
+	.remove		= vf610_nfc_remove,
+};
+
+module_platform_driver(vf610_nfc_driver);
+
+MODULE_AUTHOR("Stefan Agner <stefan.agner at toradex.com>");
+MODULE_DESCRIPTION("Freescale VF610/MPC5125 NFC MTD NAND driver");
+MODULE_LICENSE("GPL");
-- 
2.5.0



From stefan at agner.ch  Thu Aug 27 17:34:58 2015
From: stefan at agner.ch (Stefan Agner)
Date: Thu, 27 Aug 2015 17:34:58 -0700
Subject: [PATCH v11 3/5] mtd: nand: vf610_nfc: add device tree bindings
In-Reply-To: <1440722100-25388-1-git-send-email-stefan@agner.ch>
References: <1440722100-25388-1-git-send-email-stefan@agner.ch>
Message-ID: <1440722100-25388-4-git-send-email-stefan@agner.ch>

Signed-off-by: Bill Pringlemeir <bpringlemeir at nbsps.com>
Acked-by: Shawn Guo <shawnguo at kernel.org>
Signed-off-by: Stefan Agner <stefan at agner.ch>
---
 .../devicetree/bindings/mtd/vf610-nfc.txt          | 59 ++++++++++++++++++++++
 1 file changed, 59 insertions(+)
 create mode 100644 Documentation/devicetree/bindings/mtd/vf610-nfc.txt

diff --git a/Documentation/devicetree/bindings/mtd/vf610-nfc.txt b/Documentation/devicetree/bindings/mtd/vf610-nfc.txt
new file mode 100644
index 0000000..6be4871
--- /dev/null
+++ b/Documentation/devicetree/bindings/mtd/vf610-nfc.txt
@@ -0,0 +1,59 @@
+Freescale's NAND flash controller (NFC)
+
+This variant of the Freescale NAND flash controller (NFC) can be found on
+Vybrid (vf610), MPC5125, MCF54418 and Kinetis K70.
+
+Required properties:
+- compatible: Should be set to "fsl,vf610-nfc".
+- reg: address range of the NFC.
+- interrupts: interrupt of the NFC.
+- #address-cells: shall be set to 1. Encode the nand CS.
+- #size-cells : shall be set to 0.
+- assigned-clocks: main clock from the SoC, for Vybrid <&clks VF610_CLK_NFC>;
+- assigned-clock-rates: The NAND bus timing is derived from this clock
+    rate and should not exceed maximum timing for any NAND memory chip
+    in a board stuffing. Typical NAND memory timings derived from this
+    clock are found in the SoC hardware reference manual. Furthermore,
+    there might be restrictions on maximum rates when using hardware ECC.
+
+- #address-cells, #size-cells : Must be present if the device has sub-nodes
+  representing partitions.
+
+Required children nodes:
+Children nodes represent the available nand chips. Currently the driver can
+only handle one NAND chip.
+
+Required properties:
+- compatible: Should be set to "fsl,vf610-nfc-cs".
+- nand-bus-width: see nand.txt
+- nand-ecc-mode: see nand.txt
+
+Required properties for hardware ECC:
+- nand-ecc-strength: supported strengths are 24 and 32 bit (see nand.txt)
+- nand-ecc-step-size: step size equals page size, currently only 2k pages are
+    supported
+- nand-on-flash-bbt: see nand.txt
+
+Example:
+
+	nfc: nand at 400e0000 {
+		compatible = "fsl,vf610-nfc";
+		#address-cells = <1>;
+		#size-cells = <1>;
+		reg = <0x400e0000 0x4000>;
+		interrupts = <GIC_SPI 83 IRQ_TYPE_LEVEL_HIGH>;
+		clocks = <&clks VF610_CLK_NFC>;
+		clock-names = "nfc";
+		assigned-clocks = <&clks VF610_CLK_NFC>;
+		assigned-clock-rates = <33000000>;
+
+		nand at 0 {
+			compatible = "fsl,vf610-nfc-nandcs";
+			reg = <0>;
+			nand-bus-width = <8>;
+			nand-ecc-mode = "hw";
+			nand-ecc-strength = <32>;
+			nand-ecc-step-size = <2048>;
+			nand-on-flash-bbt;
+		};
+	};
-- 
2.5.0



From stefan at agner.ch  Thu Aug 27 17:35:00 2015
From: stefan at agner.ch (Stefan Agner)
Date: Thu, 27 Aug 2015 17:35:00 -0700
Subject: [PATCH v11 5/5] ARM: dts: vf-colibri: enable NAND flash controller
In-Reply-To: <1440722100-25388-1-git-send-email-stefan@agner.ch>
References: <1440722100-25388-1-git-send-email-stefan@agner.ch>
Message-ID: <1440722100-25388-6-git-send-email-stefan@agner.ch>

Enable NAND access by adding pinmux and NAND flash controller node
to device tree. The NAND chips currently used on the Colibri VF61
requires 8-bit ECC per 512 byte page, hence specify 32-bit ECC
strength per 2k page size.

Reviewed-by: Brian Norris <computersforpeace at gmail.com>
Signed-off-by: Stefan Agner <stefan at agner.ch>
---
 arch/arm/boot/dts/vf-colibri.dtsi | 39 +++++++++++++++++++++++++++++++++++++++
 1 file changed, 39 insertions(+)

diff --git a/arch/arm/boot/dts/vf-colibri.dtsi b/arch/arm/boot/dts/vf-colibri.dtsi
index 68ca125..e5949b9 100644
--- a/arch/arm/boot/dts/vf-colibri.dtsi
+++ b/arch/arm/boot/dts/vf-colibri.dtsi
@@ -52,6 +52,26 @@
 	pinctrl-0 = <&pinctrl_i2c0>;
 };
 
+&nfc {
+	assigned-clocks = <&clks VF610_CLK_NFC>;
+	assigned-clock-rates = <33000000>;
+	pinctrl-names = "default";
+	pinctrl-0 = <&pinctrl_nfc>;
+	status = "okay";
+
+	nand at 0 {
+		compatible = "fsl,vf610-nfc-nandcs";
+		reg = <0>;
+		#address-cells = <1>;
+		#size-cells = <1>;
+		nand-bus-width = <8>;
+		nand-ecc-mode = "hw";
+		nand-ecc-strength = <32>;
+		nand-ecc-step-size = <2048>;
+		nand-on-flash-bbt;
+	};
+};
+
 &pwm0 {
 	pinctrl-names = "default";
 	pinctrl-0 = <&pinctrl_pwm0>;
@@ -156,6 +176,25 @@
 			>;
 		};
 
+		pinctrl_nfc: nfcgrp {
+			fsl,pins = <
+				VF610_PAD_PTD23__NF_IO7		0x28df
+				VF610_PAD_PTD22__NF_IO6		0x28df
+				VF610_PAD_PTD21__NF_IO5		0x28df
+				VF610_PAD_PTD20__NF_IO4		0x28df
+				VF610_PAD_PTD19__NF_IO3		0x28df
+				VF610_PAD_PTD18__NF_IO2		0x28df
+				VF610_PAD_PTD17__NF_IO1		0x28df
+				VF610_PAD_PTD16__NF_IO0		0x28df
+				VF610_PAD_PTB24__NF_WE_B	0x28c2
+				VF610_PAD_PTB25__NF_CE0_B	0x28c2
+				VF610_PAD_PTB27__NF_RE_B	0x28c2
+				VF610_PAD_PTC26__NF_RB_B	0x283d
+				VF610_PAD_PTC27__NF_ALE		0x28c2
+				VF610_PAD_PTC28__NF_CLE		0x28c2
+			>;
+		};
+
 		pinctrl_pwm0: pwm0grp {
 			fsl,pins = <
 				VF610_PAD_PTB0__FTM0_CH0		0x1182
-- 
2.5.0



From stefan at agner.ch  Thu Aug 27 17:34:59 2015
From: stefan at agner.ch (Stefan Agner)
Date: Thu, 27 Aug 2015 17:34:59 -0700
Subject: [PATCH v11 4/5] ARM: dts: vf610twr: add NAND flash controller
 peripherial
In-Reply-To: <1440722100-25388-1-git-send-email-stefan@agner.ch>
References: <1440722100-25388-1-git-send-email-stefan@agner.ch>
Message-ID: <1440722100-25388-5-git-send-email-stefan@agner.ch>

This adds the NAND flash controller (NFC) peripherial. The driver
supports the SLC NAND chips found on Freescale's Vybrid Tower System
Module. The Micron NAND chip on the module needs 4-bit ECC per 512
byte page. Use 24-bit ECC per 2k page, which is supported by the
driver.

Signed-off-by: Bill Pringlemeir <bpringlemeir at nbsps.com>
Reviewed-by: Brian Norris <computersforpeace at gmail.com>
Signed-off-by: Stefan Agner <stefan at agner.ch>
---
 arch/arm/boot/dts/vf610-twr.dts | 47 +++++++++++++++++++++++++++++++++++++++++
 arch/arm/boot/dts/vfxxx.dtsi    | 10 +++++++++
 2 files changed, 57 insertions(+)

diff --git a/arch/arm/boot/dts/vf610-twr.dts b/arch/arm/boot/dts/vf610-twr.dts
index 375ab23..64d1696 100644
--- a/arch/arm/boot/dts/vf610-twr.dts
+++ b/arch/arm/boot/dts/vf610-twr.dts
@@ -237,6 +237,33 @@
 			>;
 		};
 
+		pinctrl_nfc: nfcgrp {
+			fsl,pins = <
+			VF610_PAD_PTD31__NF_IO15	0x28df
+			VF610_PAD_PTD30__NF_IO14	0x28df
+			VF610_PAD_PTD29__NF_IO13	0x28df
+			VF610_PAD_PTD28__NF_IO12	0x28df
+			VF610_PAD_PTD27__NF_IO11	0x28df
+			VF610_PAD_PTD26__NF_IO10	0x28df
+			VF610_PAD_PTD25__NF_IO9		0x28df
+			VF610_PAD_PTD24__NF_IO8		0x28df
+			VF610_PAD_PTD23__NF_IO7		0x28df
+			VF610_PAD_PTD22__NF_IO6		0x28df
+			VF610_PAD_PTD21__NF_IO5		0x28df
+			VF610_PAD_PTD20__NF_IO4		0x28df
+			VF610_PAD_PTD19__NF_IO3		0x28df
+			VF610_PAD_PTD18__NF_IO2		0x28df
+			VF610_PAD_PTD17__NF_IO1		0x28df
+			VF610_PAD_PTD16__NF_IO0		0x28df
+			VF610_PAD_PTB24__NF_WE_B	0x28c2
+			VF610_PAD_PTB25__NF_CE0_B	0x28c2
+			VF610_PAD_PTB27__NF_RE_B	0x28c2
+			VF610_PAD_PTC26__NF_RB_B	0x283d
+			VF610_PAD_PTC27__NF_ALE		0x28c2
+			VF610_PAD_PTC28__NF_CLE		0x28c2
+			>;
+		};
+
 		pinctrl_pwm0: pwm0grp {
 			fsl,pins = <
 				VF610_PAD_PTB0__FTM0_CH0		0x1582
@@ -274,6 +301,26 @@
 	};
 };
 
+&nfc {
+	assigned-clocks = <&clks VF610_CLK_NFC>;
+	assigned-clock-rates = <33000000>;
+	pinctrl-names = "default";
+	pinctrl-0 = <&pinctrl_nfc>;
+	status = "okay";
+
+	nand at 0 {
+		compatible = "fsl,vf610-nfc-nandcs";
+		reg = <0>;
+		#address-cells = <1>;
+		#size-cells = <1>;
+		nand-bus-width = <16>;
+		nand-ecc-mode = "hw";
+		nand-ecc-strength = <24>;
+		nand-ecc-step-size = <2048>;
+		nand-on-flash-bbt;
+	};
+};
+
 &pwm0 {
 	pinctrl-names = "default";
 	pinctrl-0 = <&pinctrl_pwm0>;
diff --git a/arch/arm/boot/dts/vfxxx.dtsi b/arch/arm/boot/dts/vfxxx.dtsi
index 4aa3351..17066a2 100644
--- a/arch/arm/boot/dts/vfxxx.dtsi
+++ b/arch/arm/boot/dts/vfxxx.dtsi
@@ -520,6 +520,16 @@
 				status = "disabled";
 			};
 
+			nfc: nand at 400e0000 {
+				#address-cells = <1>;
+				#size-cells = <0>;
+				compatible = "fsl,vf610-nfc";
+				reg = <0x400e0000 0x4000>;
+				interrupts = <83 IRQ_TYPE_LEVEL_HIGH>;
+				clocks = <&clks VF610_CLK_NFC>;
+				clock-names = "nfc";
+				status = "disabled";
+			};
 		};
 	};
 };
-- 
2.5.0



From shawn.lin at rock-chips.com  Thu Aug 27 17:36:16 2015
From: shawn.lin at rock-chips.com (Shawn Lin)
Date: Fri, 28 Aug 2015 08:36:16 +0800
Subject: [PATCH v2 0/5] Fix broken DMAFLUSHP on Rockchips platform
Message-ID: <1440722176-31588-1-git-send-email-shawn.lin@rock-chips.com>


The purpose of the DMAFLUSHP instruction:
- Tell the peripheral to clear its status and control registers.
- Send a message to the peripheral to resend its level status.

There are 3 timings described in PL330 Technical Reference Manual:
- Timing 1: Burst request, can work well without DMAFLUSHP.
- Timing 2: Single and burst request, DMAC will ignore the single
	    transfer request. This timing happens if there are single
	    and burst request.
- Timing 3: Single transfers for a burst request, DMAC should signals
	    datype to request the peripheral to flush the contents of
	    any control registers. This timing happens if there is
	    not enough MFIFO to places the burst data.

A peripheral may signal a DMA request during the execution of
DMAFLUSHP instruction, that cause DMA request being ignored by DMAC.

But DMAC and all peripherals on RK3X SoCs DO NOT support DMAFLUSHP.
It can't send a message to the peripheral to resend DMA request,
and the peripheral can't acknowledge a flush request from DMAC.
So all DMA requests should NOT be ignored by DMAC, and DMAC will not
notify the peripheral to flush.

To fix this problem, we need:
- Do NOT execute DMAFLUSHP instruction.
- Timing 2 and timing 3 should not happen.

Because on RK3X SoCs, there are 6 or below  channels and 32 MFIFO depth
for DMAC_BUS, and 8 channels and 64 MFIFO depth for DMAC_PERI, it is
impossible to hit the timing 3 if burst length is equal or less than 4.

Since the request type signal by the peripheral can only be set by
software. We can set Rockchip Soc's GRF_PERIDMAC_CON0[2:1] to select single
or burst request, if it is set b01,  all of the peripharals will signal a brust
request. So the timing 2 will not happen, too.

So DMAC on RK3X can support single or burst transfer, but can't support
mixed transfer.

Because burst transfer is more efficient than single transfer, this is
confirmed by our ASIC team, who strongly suggest to use burst transfer.
And this is confirmed by Addy's test on RK3288-Pink2 board, the speed of
spi flash burst transfer will increase about two times than single transfer.
Also, I have tested dw_mmc with pl330 on RK3188 platform to double confirm
the result. That means burst transfer is reansonable.

So we need a quirk not to execute DMAFLUSHP instruction and to use burst
transfer.

Note:
- The Rockchip Soc default value of GRF_PERIDMAC_CON0[2:1] is b01. To
  support brust transfer, these bits should not be changed in bootloader.


Changes in v2:
- amend the author
- reorder the patches suggested by Doug
- add Reviewed-by: Doug Anderson <dianders at chromium.org> for
  rk3288.dtsi patch and arm-pl330.txt patch
- amend Olof's mail address

Changes in v1:
- rename broken-no-flushp to "arm,pl330-broken-no-flushp" suggested
  by Krzysztof.
- add From original author.
- remove Sunny's tag

Addy Ke (2):
  DMA: pl330: add quirk for broken no flushp
  ARM: dts: Add arm,pl330-broken-no-flushp quirk for rk3288 platform

Boojin Kim (1):
  DMA: pl330: support burst mode for dev-to-mem and mem-to-dev transmit

Shawn Lin (2):
  Documentation: arm-pl330: add description of
    arm,pl330-broken-no-flushp
  ARM: dts: Add arm,pl330-broken-no-flushp quirk for rk3xxx platform

 .../devicetree/bindings/dma/arm-pl330.txt          |   1 +
 arch/arm/boot/dts/rk3288.dtsi                      |   3 +
 arch/arm/boot/dts/rk3xxx.dtsi                      |   3 +
 drivers/dma/pl330.c                                | 101 +++++++++++++++------
 4 files changed, 79 insertions(+), 29 deletions(-)

-- 
2.3.7




From shawn.lin at rock-chips.com  Thu Aug 27 17:37:48 2015
From: shawn.lin at rock-chips.com (Shawn Lin)
Date: Fri, 28 Aug 2015 08:37:48 +0800
Subject: [PATCH v2 1/5] DMA: pl330: support burst mode for dev-to-mem and
 mem-to-dev transmit
In-Reply-To: <1440722176-31588-1-git-send-email-shawn.lin@rock-chips.com>
References: <1440722176-31588-1-git-send-email-shawn.lin@rock-chips.com>
Message-ID: <1440722268-31637-1-git-send-email-shawn.lin@rock-chips.com>

From: Boojin Kim <boojin.kim at samsung.com>

This patch adds to support burst mode for dev-to-mem and
mem-to-dev transmit.

Signed-off-by: Boojin Kim <boojin.kim at samsung.com>
Signed-off-by: Addy Ke <addy.ke at rock-chips.com>
Signed-off-by: Shawn Lin <shawn.lin at rock-chips.com>
cc: Heiko Stuebner <heiko at sntech.de>
cc: Doug Anderson <dianders at chromium.org>
cc: Olof Johansson <olof at lixom.net>

---

Changes in v2:
- amend the author
- amend Olof's mail address

Changes in v1:
- rename broken-no-flushp to "arm,pl330-broken-no-flushp" suggested
  by Krzysztof.
- add From original author.
- remove Sunny's tag

 drivers/dma/pl330.c | 18 ++++++++++++------
 1 file changed, 12 insertions(+), 6 deletions(-)

diff --git a/drivers/dma/pl330.c b/drivers/dma/pl330.c
index ecab4ea0..0d544d2 100644
--- a/drivers/dma/pl330.c
+++ b/drivers/dma/pl330.c
@@ -1141,10 +1141,13 @@ static inline int _ldst_devtomem(unsigned dry_run, u8 buf[],
 		const struct _xfer_spec *pxs, int cyc)
 {
 	int off = 0;
+	enum pl330_cond cond;
+
+	cond = (pxs->desc->rqcfg.brst_len == 1) ? SINGLE : BURST;
 
 	while (cyc--) {
-		off += _emit_WFP(dry_run, &buf[off], SINGLE, pxs->desc->peri);
-		off += _emit_LDP(dry_run, &buf[off], SINGLE, pxs->desc->peri);
+		off += _emit_WFP(dry_run, &buf[off], cond, pxs->desc->peri);
+		off += _emit_LDP(dry_run, &buf[off], cond, pxs->desc->peri);
 		off += _emit_ST(dry_run, &buf[off], ALWAYS);
 		off += _emit_FLUSHP(dry_run, &buf[off], pxs->desc->peri);
 	}
@@ -1156,11 +1159,14 @@ static inline int _ldst_memtodev(unsigned dry_run, u8 buf[],
 		const struct _xfer_spec *pxs, int cyc)
 {
 	int off = 0;
+	enum pl330_cond cond;
+
+	cond = (pxs->desc->rqcfg.brst_len == 1) ? SINGLE : BURST;
 
 	while (cyc--) {
-		off += _emit_WFP(dry_run, &buf[off], SINGLE, pxs->desc->peri);
+		off += _emit_WFP(dry_run, &buf[off], cond, pxs->desc->peri);
 		off += _emit_LD(dry_run, &buf[off], ALWAYS);
-		off += _emit_STP(dry_run, &buf[off], SINGLE, pxs->desc->peri);
+		off += _emit_STP(dry_run, &buf[off], cond, pxs->desc->peri);
 		off += _emit_FLUSHP(dry_run, &buf[off], pxs->desc->peri);
 	}
 
@@ -2557,7 +2563,7 @@ static struct dma_async_tx_descriptor *pl330_prep_dma_cyclic(
 
 		desc->rqtype = direction;
 		desc->rqcfg.brst_size = pch->burst_sz;
-		desc->rqcfg.brst_len = 1;
+		desc->rqcfg.brst_len = pch->burst_len;
 		desc->bytes_requested = period_len;
 		fill_px(&desc->px, dst, src, period_len);
 
@@ -2702,7 +2708,7 @@ pl330_prep_slave_sg(struct dma_chan *chan, struct scatterlist *sgl,
 		}
 
 		desc->rqcfg.brst_size = pch->burst_sz;
-		desc->rqcfg.brst_len = 1;
+		desc->rqcfg.brst_len = pch->burst_len;
 		desc->rqtype = direction;
 		desc->bytes_requested = sg_dma_len(sg);
 	}
-- 
2.3.7




From shawn.lin at rock-chips.com  Thu Aug 27 17:38:00 2015
From: shawn.lin at rock-chips.com (Shawn Lin)
Date: Fri, 28 Aug 2015 08:38:00 +0800
Subject: [PATCH v2 2/5] DMA: pl330: add quirk for broken no flushp
In-Reply-To: <1440722176-31588-1-git-send-email-shawn.lin@rock-chips.com>
References: <1440722176-31588-1-git-send-email-shawn.lin@rock-chips.com>
Message-ID: <1440722280-31678-1-git-send-email-shawn.lin@rock-chips.com>

From: Addy Ke <addy.ke at rock-chips.com>

This patch add "arm,pl330-broken-no-flushp" quirk to avoid execute
DMAFLUSHP if Soc doesn't support it.

Signed-off-by: Addy Ke <addy.ke at rock-chips.com>
Signed-off-by: Shawn Lin <shawn.lin at rock-chips.com>
cc: Doug Anderson <dianders at chromium.org>
cc: Heiko Stuebner <heiko at sntech.de>
cc: Olof Johansson <olof at lixom.net>

---

Changes in v2:
- amend the author
- amend Olof's mail address

Changes in v1:
- rename broken-no-flushp to "arm,pl330-broken-no-flushp" suggested
  by Krzysztof.
- remove Sunny's tag

 drivers/dma/pl330.c | 87 ++++++++++++++++++++++++++++++++++++++---------------
 1 file changed, 62 insertions(+), 25 deletions(-)

diff --git a/drivers/dma/pl330.c b/drivers/dma/pl330.c
index 0d544d2..3b9b426 100644
--- a/drivers/dma/pl330.c
+++ b/drivers/dma/pl330.c
@@ -34,6 +34,8 @@
 #define PL330_MAX_IRQS		32
 #define PL330_MAX_PERI		32
 
+#define PL330_QUIRK_BROKEN_NO_FLUSHP BIT(0)
+
 enum pl330_cachectrl {
 	CCTRL0,		/* Noncacheable and nonbufferable */
 	CCTRL1,		/* Bufferable only */
@@ -488,6 +490,17 @@ struct pl330_dmac {
 	/* Peripheral channels connected to this DMAC */
 	unsigned int num_peripherals;
 	struct dma_pl330_chan *peripherals; /* keep at end */
+	int quirks;
+};
+
+static struct pl330_of_quirks {
+	char *quirk;
+	int id;
+} of_quirks[] = {
+	{
+		.quirk = "arm,pl330-broken-no-flushp",
+		.id = PL330_QUIRK_BROKEN_NO_FLUSHP,
+	}
 };
 
 struct dma_pl330_desc {
@@ -1137,53 +1150,68 @@ static inline int _ldst_memtomem(unsigned dry_run, u8 buf[],
 	return off;
 }
 
-static inline int _ldst_devtomem(unsigned dry_run, u8 buf[],
-		const struct _xfer_spec *pxs, int cyc)
+static inline int _ldst_devtomem(struct pl330_dmac *pl330, unsigned dry_run,
+				 u8 buf[], const struct _xfer_spec *pxs,
+				 int cyc)
 {
 	int off = 0;
 	enum pl330_cond cond;
 
-	cond = (pxs->desc->rqcfg.brst_len == 1) ? SINGLE : BURST;
+	if (pl330->quirks & PL330_QUIRK_BROKEN_NO_FLUSHP)
+		cond = BURST;
+	else
+		cond = (pxs->desc->rqcfg.brst_len == 1) ? SINGLE : BURST;
 
 	while (cyc--) {
 		off += _emit_WFP(dry_run, &buf[off], cond, pxs->desc->peri);
 		off += _emit_LDP(dry_run, &buf[off], cond, pxs->desc->peri);
 		off += _emit_ST(dry_run, &buf[off], ALWAYS);
-		off += _emit_FLUSHP(dry_run, &buf[off], pxs->desc->peri);
+
+		if (!(pl330->quirks & PL330_QUIRK_BROKEN_NO_FLUSHP))
+			off += _emit_FLUSHP(dry_run, &buf[off],
+					    pxs->desc->peri);
 	}
 
 	return off;
 }
 
-static inline int _ldst_memtodev(unsigned dry_run, u8 buf[],
-		const struct _xfer_spec *pxs, int cyc)
+static inline int _ldst_memtodev(struct pl330_dmac *pl330,
+				 unsigned dry_run, u8 buf[],
+				 const struct _xfer_spec *pxs, int cyc)
 {
 	int off = 0;
 	enum pl330_cond cond;
 
-	cond = (pxs->desc->rqcfg.brst_len == 1) ? SINGLE : BURST;
+	if (pl330->quirks & PL330_QUIRK_BROKEN_NO_FLUSHP)
+		cond = BURST;
+	else
+		cond = (pxs->desc->rqcfg.brst_len == 1) ? SINGLE : BURST;
+
 
 	while (cyc--) {
 		off += _emit_WFP(dry_run, &buf[off], cond, pxs->desc->peri);
 		off += _emit_LD(dry_run, &buf[off], ALWAYS);
 		off += _emit_STP(dry_run, &buf[off], cond, pxs->desc->peri);
-		off += _emit_FLUSHP(dry_run, &buf[off], pxs->desc->peri);
+
+		if (!(pl330->quirks & PL330_QUIRK_BROKEN_NO_FLUSHP))
+			off += _emit_FLUSHP(dry_run, &buf[off],
+					    pxs->desc->peri);
 	}
 
 	return off;
 }
 
-static int _bursts(unsigned dry_run, u8 buf[],
+static int _bursts(struct pl330_dmac *pl330, unsigned dry_run, u8 buf[],
 		const struct _xfer_spec *pxs, int cyc)
 {
 	int off = 0;
 
 	switch (pxs->desc->rqtype) {
 	case DMA_MEM_TO_DEV:
-		off += _ldst_memtodev(dry_run, &buf[off], pxs, cyc);
+		off += _ldst_memtodev(pl330, dry_run, &buf[off], pxs, cyc);
 		break;
 	case DMA_DEV_TO_MEM:
-		off += _ldst_devtomem(dry_run, &buf[off], pxs, cyc);
+		off += _ldst_devtomem(pl330, dry_run, &buf[off], pxs, cyc);
 		break;
 	case DMA_MEM_TO_MEM:
 		off += _ldst_memtomem(dry_run, &buf[off], pxs, cyc);
@@ -1197,7 +1225,7 @@ static int _bursts(unsigned dry_run, u8 buf[],
 }
 
 /* Returns bytes consumed and updates bursts */
-static inline int _loop(unsigned dry_run, u8 buf[],
+static inline int _loop(struct pl330_dmac *pl330, unsigned dry_run, u8 buf[],
 		unsigned long *bursts, const struct _xfer_spec *pxs)
 {
 	int cyc, cycmax, szlp, szlpend, szbrst, off;
@@ -1220,7 +1248,7 @@ static inline int _loop(unsigned dry_run, u8 buf[],
 	}
 
 	szlp = _emit_LP(1, buf, 0, 0);
-	szbrst = _bursts(1, buf, pxs, 1);
+	szbrst = _bursts(pl330, 1, buf, pxs, 1);
 
 	lpend.cond = ALWAYS;
 	lpend.forever = false;
@@ -1252,7 +1280,7 @@ static inline int _loop(unsigned dry_run, u8 buf[],
 	off += _emit_LP(dry_run, &buf[off], 1, lcnt1);
 	ljmp1 = off;
 
-	off += _bursts(dry_run, &buf[off], pxs, cyc);
+	off += _bursts(pl330, dry_run, &buf[off], pxs, cyc);
 
 	lpend.cond = ALWAYS;
 	lpend.forever = false;
@@ -1275,8 +1303,9 @@ static inline int _loop(unsigned dry_run, u8 buf[],
 	return off;
 }
 
-static inline int _setup_loops(unsigned dry_run, u8 buf[],
-		const struct _xfer_spec *pxs)
+static inline int _setup_loops(struct pl330_dmac *pl330,
+			       unsigned dry_run, u8 buf[],
+			       const struct _xfer_spec *pxs)
 {
 	struct pl330_xfer *x = &pxs->desc->px;
 	u32 ccr = pxs->ccr;
@@ -1285,15 +1314,16 @@ static inline int _setup_loops(unsigned dry_run, u8 buf[],
 
 	while (bursts) {
 		c = bursts;
-		off += _loop(dry_run, &buf[off], &c, pxs);
+		off += _loop(pl330, dry_run, &buf[off], &c, pxs);
 		bursts -= c;
 	}
 
 	return off;
 }
 
-static inline int _setup_xfer(unsigned dry_run, u8 buf[],
-		const struct _xfer_spec *pxs)
+static inline int _setup_xfer(struct pl330_dmac *pl330,
+			      unsigned dry_run, u8 buf[],
+			      const struct _xfer_spec *pxs)
 {
 	struct pl330_xfer *x = &pxs->desc->px;
 	int off = 0;
@@ -1304,7 +1334,7 @@ static inline int _setup_xfer(unsigned dry_run, u8 buf[],
 	off += _emit_MOV(dry_run, &buf[off], DAR, x->dst_addr);
 
 	/* Setup Loop(s) */
-	off += _setup_loops(dry_run, &buf[off], pxs);
+	off += _setup_loops(pl330, dry_run, &buf[off], pxs);
 
 	return off;
 }
@@ -1313,8 +1343,9 @@ static inline int _setup_xfer(unsigned dry_run, u8 buf[],
  * A req is a sequence of one or more xfer units.
  * Returns the number of bytes taken to setup the MC for the req.
  */
-static int _setup_req(unsigned dry_run, struct pl330_thread *thrd,
-		unsigned index, struct _xfer_spec *pxs)
+static int _setup_req(struct pl330_dmac *pl330, unsigned dry_run,
+		      struct pl330_thread *thrd, unsigned index,
+		      struct _xfer_spec *pxs)
 {
 	struct _pl330_req *req = &thrd->req[index];
 	struct pl330_xfer *x;
@@ -1331,7 +1362,7 @@ static int _setup_req(unsigned dry_run, struct pl330_thread *thrd,
 	if (x->bytes % (BRST_SIZE(pxs->ccr) * BRST_LEN(pxs->ccr)))
 		return -EINVAL;
 
-	off += _setup_xfer(dry_run, &buf[off], pxs);
+	off += _setup_xfer(pl330, dry_run, &buf[off], pxs);
 
 	/* DMASEV peripheral/event */
 	off += _emit_SEV(dry_run, &buf[off], thrd->ev);
@@ -1425,7 +1456,7 @@ static int pl330_submit_req(struct pl330_thread *thrd,
 	xs.desc = desc;
 
 	/* First dry run to check if req is acceptable */
-	ret = _setup_req(1, thrd, idx, &xs);
+	ret = _setup_req(pl330, 1, thrd, idx, &xs);
 	if (ret < 0)
 		goto xfer_exit;
 
@@ -1439,7 +1470,7 @@ static int pl330_submit_req(struct pl330_thread *thrd,
 	/* Hook the request */
 	thrd->lstenq = idx;
 	thrd->req[idx].desc = desc;
-	_setup_req(0, thrd, idx, &xs);
+	_setup_req(pl330, 0, thrd, idx, &xs);
 
 	ret = 0;
 
@@ -2784,6 +2815,7 @@ pl330_probe(struct amba_device *adev, const struct amba_id *id)
 	struct resource *res;
 	int i, ret, irq;
 	int num_chan;
+	struct device_node *np = adev->dev.of_node;
 
 	pdat = dev_get_platdata(&adev->dev);
 
@@ -2803,6 +2835,11 @@ pl330_probe(struct amba_device *adev, const struct amba_id *id)
 
 	pl330->mcbufsz = pdat ? pdat->mcbuf_sz : 0;
 
+	/* get quirk */
+	for (i = 0; i < ARRAY_SIZE(of_quirks); i++)
+		if (of_property_read_bool(np, of_quirks[i].quirk))
+			pl330->quirks |= of_quirks[i].id;
+
 	res = &adev->res;
 	pl330->base = devm_ioremap_resource(&adev->dev, res);
 	if (IS_ERR(pl330->base))
-- 
2.3.7




From shawn.lin at rock-chips.com  Thu Aug 27 17:38:12 2015
From: shawn.lin at rock-chips.com (Shawn Lin)
Date: Fri, 28 Aug 2015 08:38:12 +0800
Subject: [PATCH v2 3/5] Documentation: arm-pl330: add description of arm,
 pl330-broken-no-flushp
In-Reply-To: <1440722176-31588-1-git-send-email-shawn.lin@rock-chips.com>
References: <1440722176-31588-1-git-send-email-shawn.lin@rock-chips.com>
Message-ID: <1440722292-31721-1-git-send-email-shawn.lin@rock-chips.com>

Signed-off-by: Shawn Lin <shawn.lin at rock-chips.com>
Reviewed-by: Doug Anderson <dianders at chromium.org>
---

Changes in v2:
- add Reviewed-by: Doug Anderson <dianders at chromium.org>
- reorder this patch before the usage of the quirk

Changes in v1:
- rename broken-no-flushp to "arm,pl330-broken-no-flushp" suggested
  by Krzysztof.

 Documentation/devicetree/bindings/dma/arm-pl330.txt | 1 +
 1 file changed, 1 insertion(+)

diff --git a/Documentation/devicetree/bindings/dma/arm-pl330.txt b/Documentation/devicetree/bindings/dma/arm-pl330.txt
index 2675658..db7e226 100644
--- a/Documentation/devicetree/bindings/dma/arm-pl330.txt
+++ b/Documentation/devicetree/bindings/dma/arm-pl330.txt
@@ -15,6 +15,7 @@ Optional properties:
     cells in the dmas property of client device.
   - dma-channels: contains the total number of DMA channels supported by the DMAC
   - dma-requests: contains the total number of DMA requests supported by the DMAC
+  - arm,pl330-broken-no-flushp: quirk for avoiding to execute DMAFLUSHP
 
 Example:
 
-- 
2.3.7




From shawn.lin at rock-chips.com  Thu Aug 27 17:38:33 2015
From: shawn.lin at rock-chips.com (Shawn Lin)
Date: Fri, 28 Aug 2015 08:38:33 +0800
Subject: [PATCH v2 5/5] ARM: dts: Add arm,
 pl330-broken-no-flushp quirk for rk3xxx platform
In-Reply-To: <1440722176-31588-1-git-send-email-shawn.lin@rock-chips.com>
References: <1440722176-31588-1-git-send-email-shawn.lin@rock-chips.com>
Message-ID: <1440722313-31803-1-git-send-email-shawn.lin@rock-chips.com>

Pl330 integrated in rk3xxx platform doesn't support
DMAFLUSHP function. So we add arm,pl330-broken-no-flushp quirk
for it.

Signed-off-by: Shawn Lin <shawn.lin at rock-chips.com>
cc: Heiko Stuebner <heiko at sntech.de>
cc: Doug Anderson <dianders at chromium.org>
cc: Olof Johansson <olof at lixom.net>

---

Changes in v2: None
Changes in v1:
- rename broken-no-flushp to "arm,pl330-broken-no-flushp" suggested
  by Krzysztof.

 arch/arm/boot/dts/rk3xxx.dtsi | 3 +++
 1 file changed, 3 insertions(+)

diff --git a/arch/arm/boot/dts/rk3xxx.dtsi b/arch/arm/boot/dts/rk3xxx.dtsi
index a2ae9f3..a8ca4b3 100644
--- a/arch/arm/boot/dts/rk3xxx.dtsi
+++ b/arch/arm/boot/dts/rk3xxx.dtsi
@@ -79,6 +79,7 @@
 			#dma-cells = <1>;
 			clocks = <&cru ACLK_DMA1>;
 			clock-names = "apb_pclk";
+			arm,pl330-broken-no-flushp;
 		};
 
 		dmac1_ns: dma-controller at 2001c000 {
@@ -89,6 +90,7 @@
 			#dma-cells = <1>;
 			clocks = <&cru ACLK_DMA1>;
 			clock-names = "apb_pclk";
+			arm,pl330-broken-no-flushp;
 			status = "disabled";
 		};
 
@@ -100,6 +102,7 @@
 			#dma-cells = <1>;
 			clocks = <&cru ACLK_DMA2>;
 			clock-names = "apb_pclk";
+			arm,pl330-broken-no-flushp;
 		};
 	};
 
-- 
2.3.7




From f.fainelli at gmail.com  Thu Aug 27 17:43:03 2015
From: f.fainelli at gmail.com (Florian Fainelli)
Date: Thu, 27 Aug 2015 17:43:03 -0700
Subject: [PATCH v2 3/5] ARM: NSP: Add basic support for Broadcom Northstar
 Plus SoC
In-Reply-To: <1440628530-6137-4-git-send-email-jonmason@broadcom.com>
References: <1440628530-6137-1-git-send-email-jonmason@broadcom.com>
 <1440628530-6137-4-git-send-email-jonmason@broadcom.com>
Message-ID: <55DFAE97.3030003@gmail.com>

On 26/08/15 15:35, Jon Mason wrote:
> Broadcom Northstar Plus family of SoCs are used for switching
> control and management applications as well as residential
> router/gateway applications. The SoC features dual core Cortex
> A9 ARM CPUs, integrating several peripheral interfaces including
> multiple Gigabit Ethernet PHYs, DDR3 memory, PCIE Gen-2, USB 2.0
> and USB 3.0, serial and NAND flash, SATA and several other IO
> controllers.
> 
> Signed-off-by: Kapil Hali <kapilh at broadcom.com>
> Signed-off-by: Jon Mason <jonmason at broadcom.com>

Applied to soc/next at github.com/stblinux, thanks!

This is a little late for 4.3, so this will be queued for 4.4, thanks!
-- 
Florian


From fainelli at broadcom.com  Thu Aug 27 17:44:30 2015
From: fainelli at broadcom.com (Florian Fainelli)
Date: Thu, 27 Aug 2015 17:44:30 -0700
Subject: [PATCH v2 1/5] dt-bindings: Create Documentation for NSP DT
 bindings
In-Reply-To: <1440628530-6137-2-git-send-email-jonmason@broadcom.com>
References: <1440628530-6137-1-git-send-email-jonmason@broadcom.com>
 <1440628530-6137-2-git-send-email-jonmason@broadcom.com>
Message-ID: <55DFAEEE.60902@broadcom.com>

On 26/08/15 15:35, Jon Mason wrote:
> Add the documentation for the Broadcom Northstar Plus device tree
> bindings.
> 
> Signed-off-by: Jon Mason <jonmason at broadcom.com>

Applied to devicetree/next, thanks!
-- 
Florian


From fainelli at broadcom.com  Thu Aug 27 17:44:47 2015
From: fainelli at broadcom.com (Florian Fainelli)
Date: Thu, 27 Aug 2015 17:44:47 -0700
Subject: [PATCH v2 2/5] ARM: NSP: add minimal Northstar Plus device tree
In-Reply-To: <1440628530-6137-3-git-send-email-jonmason@broadcom.com>
References: <1440628530-6137-1-git-send-email-jonmason@broadcom.com>
 <1440628530-6137-3-git-send-email-jonmason@broadcom.com>
Message-ID: <55DFAEFF.9030305@broadcom.com>

On 26/08/15 15:35, Jon Mason wrote:
> Add a very minimalistic set of Northstar Plus Device Tree files which
> describes the SoC and the BCM958625 implementation.  The perpherials
> described are:
> 
> ARM Cortex A9 CPU
> 2 8250 UARTs
> ARM GIC
> PL310 L2 Cache
> ARM A9 Global timer
> 
> Signed-off-by: Kapil Hali <kapilh at broadcom.com>
> Signed-off-by: Jon Mason <jonmason at broadcom.com>

Applied to devicetree/next, thanks!
-- 
Florian


From fainelli at broadcom.com  Thu Aug 27 17:45:40 2015
From: fainelli at broadcom.com (Florian Fainelli)
Date: Thu, 27 Aug 2015 17:45:40 -0700
Subject: [PATCH v2 5/5] MAINTAINERS: add entry for the Broadcom Northstar
 Plus SoCs
In-Reply-To: <1440628530-6137-6-git-send-email-jonmason@broadcom.com>
References: <1440628530-6137-1-git-send-email-jonmason@broadcom.com>
 <1440628530-6137-6-git-send-email-jonmason@broadcom.com>
Message-ID: <55DFAF34.5050803@broadcom.com>

On 26/08/15 15:35, Jon Mason wrote:
> Modify the iProc MAINTAINER to cover the Nortstar Plus SoCs, and add me
> to the list of people responsible for it.  Since iProc is a family of
> SoCs that includes more than just Cygnus (i.e., Northstar (BCM5301X),
> Northstar Plus, Northstar 2, and a number of other platforms), remove it
> from the title to avoid any future confusion.
> 
> Signed-off-by: Jon Mason <jonmason at broadcom.com>
> Acked-by: Scott Branden <sbranden at broadcom.com>

Applied to maintainers/next, thanks!
-- 
Florian


From fainelli at broadcom.com  Thu Aug 27 17:46:47 2015
From: fainelli at broadcom.com (Florian Fainelli)
Date: Thu, 27 Aug 2015 17:46:47 -0700
Subject: [PATCH v2 4/5] ARM: multi_v7_defconfig: Add NSP to defconfig
In-Reply-To: <1440628530-6137-5-git-send-email-jonmason@broadcom.com>
References: <1440628530-6137-1-git-send-email-jonmason@broadcom.com>
 <1440628530-6137-5-git-send-email-jonmason@broadcom.com>
Message-ID: <55DFAF77.1090003@broadcom.com>

On 26/08/15 15:35, Jon Mason wrote:
> Add the Broadcom Northstar Plus SoC to the multi_v7_defconfig
> 
> Signed-off-by: Jon Mason <jonmason at broadcom.com>

Applied to defconfig/next, thanks!
-- 
Florian


From dianders at chromium.org  Thu Aug 27 19:03:20 2015
From: dianders at chromium.org (Doug Anderson)
Date: Thu, 27 Aug 2015 19:03:20 -0700
Subject: [RESEND PATCH v16 4/4] ARM: dts: add the support power-domain
 node on RK3288 SoCs
In-Reply-To: <7hmvxc45w2.fsf@deeprootsystems.com>
References: <1440487486-6154-1-git-send-email-wxt@rock-chips.com>
 <1440487486-6154-5-git-send-email-wxt@rock-chips.com>
 <7hfv37axhj.fsf@deeprootsystems.com>
 <CAD=FV=V6oG+9U=W_JZmqCuNo-9-5wW8ffZzG7ZE_3cnSTNAjFQ@mail.gmail.com>
 <7htwrn6l7g.fsf@deeprootsystems.com>
 <CAKdAkRS=9Dq+YpMNSjpij0Am4ZD6uUURv74OLLYf+akD=W885A@mail.gmail.com>
 <7hmvxc45w2.fsf@deeprootsystems.com>
Message-ID: <CAD=FV=VTR-PBcXXX1jHNw65x_cMP9CKwVWBs+XCcFqFPp7msjA@mail.gmail.com>

Kevin,

On Thu, Aug 27, 2015 at 5:24 PM, Kevin Hilman <khilman at kernel.org> wrote:
>> That is not really workable: the attach and detach happen in
>> probe/remove path; if you do not have driver for the device you will
>> miss the clocks for it.
>
> And in my proposal, I suggested that clocks without drivers are
> good candidates to list in the domain, with the caveat that the be
> called out (documented) as being device clocks that are missing a
> driver, so when a driver shows up they can be moved accordingly, and in
> a way that actually describes the hardware.

What happens if someone disables the driver using the CONFIG subsystem?

What happens if this is a device that someone has set to 'status =
"disabled";' in the device tree?

Even if the device is disabled in one of those two ways, we still need
the clocks to be turned on.  ...so if we turn on/off the VIO domain we
need to turn on the EDP clock even if there's no EDP in the current
board / config.  We might turn on/off VIO for one of the other devices
in the VIO domain for one of the other devices in VIO that we are
using.

-Doug


From fan.chen at mediatek.com  Thu Aug 27 19:11:59 2015
From: fan.chen at mediatek.com (fan.chen at mediatek.com)
Date: Fri, 28 Aug 2015 10:11:59 +0800
Subject: [PATCH] arm64: dts: mediatek: mt8173 PSCI-1.0 support
Message-ID: <1440727919-34719-1-git-send-email-fan.chen@mediatek.com>

From: Fan Chen <fan.chen at mediatek.com>

This patch adds psci comatible properties to support all mandatory
functions of PSCI-1.0, PSCI-0.2 and PSCI-0.1, and system suspend
can be supported in PSCI-1.0.

Signed-off-by: Fan Chen <fan.chen at mediatek.com>
---
Because PSCI-1.0 patches hadn't landed on mainline, this patch is
based on three patch sets below:
[0] http://www.spinics.net/lists/arm-kernel/msg425793.html
    PSCI: system suspend support
[1] git://git.kernel.org/pub/scm/linux/kernel/git/mark/linux.git
    psci/unification
[2] http://www.spinics.net/lists/devicetree/msg82017.html
    [PATCH 0/6] drivers: firmware: psci: add basic v1.0 support

Before they are merged in, this patch still works fine with psci-0.2
support in current mainline.
---
 arch/arm64/boot/dts/mediatek/mt8173.dtsi |    2 +-
 1 file changed, 1 insertion(+), 1 deletion(-)

diff --git a/arch/arm64/boot/dts/mediatek/mt8173.dtsi b/arch/arm64/boot/dts/mediatek/mt8173.dtsi
index d18ee42..b9b4205 100644
--- a/arch/arm64/boot/dts/mediatek/mt8173.dtsi
+++ b/arch/arm64/boot/dts/mediatek/mt8173.dtsi
@@ -95,7 +95,7 @@
 	};
 
 	psci {
-		compatible = "arm,psci";
+		compatible = "arm,psci-1.0", "arm,psci-0.2", "arm,psci";
 		method = "smc";
 		cpu_suspend   = <0x84000001>;
 		cpu_off	      = <0x84000002>;
-- 
1.7.9.5



From djkurtz at chromium.org  Thu Aug 27 20:02:29 2015
From: djkurtz at chromium.org (Daniel Kurtz)
Date: Fri, 28 Aug 2015 11:02:29 +0800
Subject: [PATCH v6] arm64: dts: Add spi bus dts
In-Reply-To: <CAGS+omCFQRoH3ft2O5qPLBgngCuLPaminTys5OU6QcKmRXTyNw@mail.gmail.com>
References: <1439782198-32396-1-git-send-email-leilk.liu@mediatek.com>
 <CAGS+omCFQRoH3ft2O5qPLBgngCuLPaminTys5OU6QcKmRXTyNw@mail.gmail.com>
Message-ID: <CAGS+omBBGmMzo6WeOdasMT9c-4BhKGJz1iPJjxF5vzJJ0J=Pug@mail.gmail.com>

Matthias,

On Mon, Aug 17, 2015 at 12:32 PM, Daniel Kurtz <djkurtz at chromium.org> wrote:
> On Mon, Aug 17, 2015 at 11:29 AM, Leilk Liu <leilk.liu at mediatek.com> wrote:
>>
>> This patch adds MT8173 spi bus controllers into device tree.
>>
>> Signed-off-by: Leilk Liu <leilk.liu at mediatek.com>
>
> Reviewed-by: Daniel Kurtz <djkurtz at chromium.org>

The other SPI patches have already been picked up in broonie's spi tree.
Can you pick this one into your mediatek tree?

Thanks.
-Dan

>
>> ---
>> Change in this patch:
>> pinctl and pad-select fields are board specific, so move to
>> mt8173-evb.dtsi, and status = "okay".
>> ---
>>  arch/arm64/boot/dts/mediatek/mt8173-evb.dts | 18 ++++++++++++++++++
>>  arch/arm64/boot/dts/mediatek/mt8173.dtsi    | 12 ++++++++++++
>>  2 files changed, 30 insertions(+)
>>
>> diff --git a/arch/arm64/boot/dts/mediatek/mt8173-evb.dts b/arch/arm64/boot/dts/mediatek/mt8173-evb.dts
>> index 4be66ca..811cb76 100644
>> --- a/arch/arm64/boot/dts/mediatek/mt8173-evb.dts
>> +++ b/arch/arm64/boot/dts/mediatek/mt8173-evb.dts
>> @@ -387,6 +387,24 @@
>>         };
>>  };
>>
>> +&pio {
>> +       spi_pins_a: spi0 {
>> +               pins_spi {
>> +                       pinmux = <MT8173_PIN_69_SPI_CK__FUNC_SPI_CK_0_>,
>> +                               <MT8173_PIN_70_SPI_MI__FUNC_SPI_MI_0_>,
>> +                               <MT8173_PIN_71_SPI_MO__FUNC_SPI_MO_0_>,
>> +                               <MT8173_PIN_72_SPI_CS__FUNC_SPI_CS_0_>;
>> +               };
>> +       };
>> +};
>> +
>> +&spi {
>> +       pinctrl-names = "default";
>> +       pinctrl-0 = <&spi_pins_a>;
>> +       mediatek,pad-select = <0>;
>> +       status = "okay";
>> +};
>> +
>>  &uart0 {
>>         status = "okay";
>>  };
>> diff --git a/arch/arm64/boot/dts/mediatek/mt8173.dtsi b/arch/arm64/boot/dts/mediatek/mt8173.dtsi
>> index d18ee42..3dfb6ed 100644
>> --- a/arch/arm64/boot/dts/mediatek/mt8173.dtsi
>> +++ b/arch/arm64/boot/dts/mediatek/mt8173.dtsi
>> @@ -365,6 +365,18 @@
>>                         status = "disabled";
>>                 };
>>
>> +               spi: spi at 1100a000 {
>> +                       compatible = "mediatek,mt8173-spi";
>> +                       #address-cells = <1>;
>> +                       #size-cells = <0>;
>> +                       reg = <0 0x1100a000 0 0x1000>;
>> +                       interrupts = <GIC_SPI 110 IRQ_TYPE_LEVEL_LOW>;
>> +                       clocks = <&topckgen CLK_TOP_SPI_SEL>,
>> +                                <&topckgen CLK_TOP_SYSPLL3_D2>;
>> +                       clock-names = "spi-clk", "parent-clk";
>> +                       status = "disabled";
>> +               };
>> +
>>                 i2c3: i2c3 at 11010000 {
>>                         compatible = "mediatek,mt8173-i2c";
>>                         reg = <0 0x11010000 0 0x70>,
>> --
>> 1.8.1.1.dirty
>>
>> --
>> To unsubscribe from this list: send the line "unsubscribe linux-kernel" in
>> the body of a message to majordomo at vger.kernel.org
>> More majordomo info at  http://vger.kernel.org/majordomo-info.html
>> Please read the FAQ at  http://www.tux.org/lkml/


From zhang.chunyan at linaro.org  Thu Aug 27 21:10:01 2015
From: zhang.chunyan at linaro.org (Chunyan Zhang)
Date: Fri, 28 Aug 2015 12:10:01 +0800
Subject: [PATCH v2] Coresight: ETMv4: Prevent TRCRSCTLR0&1 from being accessed
Message-ID: <1440735001-29760-1-git-send-email-zhang.chunyan@linaro.org>

1. TRCRSCTLRn - Resource Selection Control Registers n=0~1 are reserved,
   we shouldn't access them.
2. The max number of 'n' here is defined in TRCIDR4.NUMRSPAIR whoes value
   indicates the number of resource selection *pairs*, and 0 indicates
   one resource selection pair, 1 indicates two pairs, and so on ...

So, the total number of resource selection control registers which we can
access is (TRCIDR4.NUMRSPAIR * 2)

Signed-off-by: Chunyan Zhang <zhang.chunyan at linaro.org>
---
 drivers/hwtracing/coresight/coresight-etm4x.c | 17 +++++++++++------
 1 file changed, 11 insertions(+), 6 deletions(-)

diff --git a/drivers/hwtracing/coresight/coresight-etm4x.c b/drivers/hwtracing/coresight/coresight-etm4x.c
index 1312e99..fe93b47 100644
--- a/drivers/hwtracing/coresight/coresight-etm4x.c
+++ b/drivers/hwtracing/coresight/coresight-etm4x.c
@@ -136,7 +136,9 @@ static void etm4_enable_hw(void *info)
 		writel_relaxed(drvdata->cntr_val[i],
 			       drvdata->base + TRCCNTVRn(i));
 	}
-	for (i = 0; i < drvdata->nr_resource; i++)
+
+	/* Resource selector pair 0 is always implemented and reserved */
+	for (i = 2; i < drvdata->nr_resource * 2; i++)
 		writel_relaxed(drvdata->res_ctrl[i],
 			       drvdata->base + TRCRSCTLRn(i));
 
@@ -489,8 +491,9 @@ static ssize_t reset_store(struct device *dev,
 		drvdata->cntr_val[i] = 0x0;
 	}
 
-	drvdata->res_idx = 0x0;
-	for (i = 0; i < drvdata->nr_resource; i++)
+	/* Resource selector pair 0 is always implemented and reserved */
+	drvdata->res_idx = 0x2;
+	for (i = 2; i < drvdata->nr_resource * 2; i++)
 		drvdata->res_ctrl[i] = 0x0;
 
 	for (i = 0; i < drvdata->nr_ss_cmp; i++) {
@@ -1729,7 +1732,7 @@ static ssize_t res_idx_store(struct device *dev,
 	if (kstrtoul(buf, 16, &val))
 		return -EINVAL;
 	/* Resource selector pair 0 is always implemented and reserved */
-	if ((val == 0) || (val >= drvdata->nr_resource))
+	if (val < 2 || val >= drvdata->nr_resource * 2)
 		return -EINVAL;
 
 	/*
@@ -2410,8 +2413,8 @@ static void etm4_init_arch_data(void *info)
 	drvdata->nr_addr_cmp = BMVAL(etmidr4, 0, 3);
 	/* NUMPC, bits[15:12] number of PE comparator inputs for tracing */
 	drvdata->nr_pe_cmp = BMVAL(etmidr4, 12, 15);
-	/* NUMRSPAIR, bits[19:16] the number of resource pairs for tracing */
-	drvdata->nr_resource = BMVAL(etmidr4, 16, 19);
+	/* NUMRSPAIR, bits[19:16] the number of resource pairs minus one */
+	drvdata->nr_resource = BMVAL(etmidr4, 16, 19) + 1;
 	/*
 	 * NUMSSCC, bits[23:20] the number of single-shot
 	 * comparator control for tracing
@@ -2498,6 +2501,8 @@ static void etm4_init_default_data(struct etmv4_drvdata *drvdata)
 		drvdata->cntr_val[i] = 0x0;
 	}
 
+	/* Resource selector pair 0 is always implemented and reserved */
+	drvdata->res_idx = 0x2;
 	for (i = 2; i < drvdata->nr_resource * 2; i++)
 		drvdata->res_ctrl[i] = 0x0;
 
-- 
1.9.1



From jteki at openedev.com  Thu Aug 27 21:13:03 2015
From: jteki at openedev.com (Jagan Teki)
Date: Fri, 28 Aug 2015 09:43:03 +0530
Subject: [LINUX RFC v2 0/4] spi: add dual parallel mode support in Zynq
 MPSoC GQSPI controller
In-Reply-To: <CAGnW=Bar5_t9Pzfz4v6x7HL6ZN=Tm8TPW8HpY42JaksT1NLnQw@mail.gmail.com>
References: <1440570367-22569-1-git-send-email-ranjit.waghmode@xilinx.com>
 <CAD6G_RQhWBsUTZNBB44W98Fjzw82H_D_E9nY0aDWezj729mkoA@mail.gmail.com>
 <CAGnW=BZtsVtT+Z7gTq5jybXsHWp+RNpjc6ckk6-MXWxAS7u8Mw@mail.gmail.com>
 <CAD6G_RTCQ5Fzjgxz+-3oMDAyUTg6UFAqvpEPQzJ9maSTZ3Nc_g@mail.gmail.com>
 <CAGnW=BZ80B_2kzZVULhZvEXFs+_GXkGbu8mii1eFp3MySvA8aA@mail.gmail.com>
 <CAD6G_RR+QnuK++KvztYo+68sb7yQqwM7qg-X7bybCYaBN+nAGQ@mail.gmail.com>
 <CAGnW=Bar5_t9Pzfz4v6x7HL6ZN=Tm8TPW8HpY42JaksT1NLnQw@mail.gmail.com>
Message-ID: <CAD6G_RS6J3t7YPwBz+c9VduVRmRRN_DL0RUEMx713M4Km2oDHA@mail.gmail.com>

On 27 August 2015 at 17:19, punnaiah choudary kalluri
<punnaia at xilinx.com> wrote:
> On Thu, Aug 27, 2015 at 3:45 PM, Jagan Teki <jteki at openedev.com> wrote:
>> On 27 August 2015 at 14:18, punnaiah choudary kalluri
>> <punnaia at xilinx.com> wrote:
>>> On Thu, Aug 27, 2015 at 11:53 AM, Jagan Teki <jteki at openedev.com> wrote:
>>>> On 26 August 2015 at 21:02, punnaiah choudary kalluri
>>>> <punnaia at xilinx.com> wrote:
>>>>> On Wed, Aug 26, 2015 at 5:49 PM, Jagan Teki <jteki at openedev.com> wrote:
>>>>>> On 26 August 2015 at 11:56, Ranjit Waghmode <ranjit.waghmode at xilinx.com> wrote:
>>>>>>> This series adds dual parallel mode support for Zynq Ultrascale+
>>>>>>> MPSoC GQSPI controller driver.
>>>>>>>
>>>>>>> What is dual parallel mode?
>>>>>>> ---------------------------
>>>>>>> ZynqMP GQSPI controller supports Dual Parallel mode with following functionalities:
>>>>>>> 1) Supporting two SPI flash memories operating in parallel. 8 I/O lines.
>>>>>>> 2) Chip selects and clock are shared to both the flash devices
>>>>>>> 3) This mode is targeted for faster read/write speed and also doubles the size
>>>>>>> 4) Commands/data can be transmitted/received from both the devices(mirror),
>>>>>>>    or only upper or only lower flash memory devices.
>>>>>>> 5) Data arrangement:
>>>>>>>    With stripe enabled,
>>>>>>>    Even bytes i.e. 0, 2, 4,... are transmitted on Lower Data Bus
>>>>>>>    Odd bytes i.e. 1, 3, 5,.. are transmitted on Upper Data Bus.
>>> <snip>
>>>>>> I don't find any previous discussion about way to inform flash
>>>>>> dual-ness into spi-nor
>>>>>> from spi drivers.
>>>>>>
>>>>>> Here is my idea, probably others may think same.
>>>>>> Informing dual_flash from drivers/spi through flags or any other mode
>>>>>> bits is not a better approach as dual flash feature is specific to
>>>>>> spi-nor flash controller (controller specially designed for spi-nor
>>>>>> flash not the generic spi controller).  So if the driver sits on
>>>>>> drivers/mtd/spi-nor/ (ex: fsl-quadspi.c), may be we can inform flash
>>>>>> specific things to spi-nor as it's not touching generic spi stack in
>>>>>> Linux. But there is a defined-drawback if the driver is moved to
>>>>>> drivers/mtd/spi-nor ie it can't use spi core API's at-all.
>>>>>
>>>>> Xilinx GQSPI is a generic quad spi controller. The primary goal is to support
>>>>> Generic/Future command sequences and Future NOR/NAND flash devices.
>>>>> This core can also be used for legacy SPI devices. Due to the generic nature
>>>>> of the core, software can generate any command sequence. It also has additional
>>>>> features like parallel and stacked configurations to double the data
>>>>> rate and size.
>>>>> Accessing spi-nor flash device is one particular use case and like
>>>>> that there will be
>>>>> many. So, we decided to keep this driver in generic spi framework and
>>>>> that is the ideal
>>>>> thing to do for the GQSPI controller.
>>>>
>>>> Yes, I understand the generic nature of the GQSPI and it's good to
>>>> have all-in-one like generic spi, spi-nor and spi-nand and more
>>>> together, but Linux stacks were implemented in such a way to support
>>>> the each type of controller with connected slaves separably for better
>>>> handling.
>>>
>>> True and this is the reason we have controller drivers and protocol drivers.
>>> GQSPI is the controller driver and spi-nor and spi-nand are the
>>> protocol drivers.
>>>
>>>>
>>>> Currently GQSPI driver is added in drivers/spi as it supports generic
>>>> spi nature and now it enhanced more through flags for supporting
>>>> spi-nor, what if we add spi-nand support for the same controller? do
>>>> we add one more driver in spi-nand framework (drivers/mtd/spi-nand -
>>>> an on going implementation)? My only observation here is even if the
>>>> controller is more generic to support more number of device classes,
>>>> and adding same driver and populate the slave stuff through flags or
>>>> different kind of mechanism to different driver stack, this is not a
>>>> better approach I thought.
>>>
>>> Just to clear, dual parallel( 2 CS and 8 IO lines) is not only specific
>>> to flash parts, one can use for any other custom streaming protocols
>>> I would say exporting dual parallel connection to protocol drivers is
>>> something like depicting the spi bus topology to the protocol layer.
>>
>> So dual parallel may not used for spi-nor flash it can also used other
>> spi slaves that's what your saying is it?
>
> Yes. As i said above, the main intention of this feature is to improve
> the data rate with an overhead of few IO lines.
>
>>
>>>
>>> AFAIK, spi-nor and spi-nand are protocol drivers for accessing the
>>> nor and nand flash devices sitting on the spi bus using the spi
>>> controller driver.
>>
>> Yes, I do agree with your point, but though driver stacks are
>> different with same kind of bus here, I'm trying to spit the GQSPI
>> into 3 different controller drivers as Linux understand it and fit on
>> to Linux stack with out disturbing the generic-ness.
>
>  I feel this is not a nice idea. if there are 'n' functionalities and having
> 'n' controller drivers doesn't seem good in any direction.

Sorry, to be clear It doesn't depend on n-theory instead it divergent
based on the how many Linux stacks that the GQSPI handle. And also I
commented earlier on thread that it may not be a better solutions but
it could be one of the good approach to fit into Linux-where-it's-not
touching core stacks.

Yes, we can do by adding spi bus driver and adding the
generic-ness,but I'm feel it ended up talking to many stacks which is
advisably not a good idea.

>
> Protocol driver can query the spi core about the bus topology and it is the
> responsibility of the spi core and controller driver providing this information
> to the upper layers.

I agreed the protocol driver definition here,as per the spi-nor
framework the drivers/mtd/spi-nor driver not only a protocol or slave
or flash drivers but there are some controller driver as well ex:
fsl-qspi-spi-nor.c

OK, we both are in different directions - lets wait for any more
comments from others.

>> Assumption is GQSPI shall split to various platform_drivers (if each
>> platform driver treated as a controller) thought it made up of  spi
>> bus.
>>
>>>>
>>>> Based on the above comments, there is an approach to handle this
>>>> support and I'm not 100% sure whether this fits or not but we
>>>> implemented the same -  this is "probing child devices from parent"
>>>> (there was a discussion with Arnd earlier wrt this, but I'm unable to
>>>> get the mailing thread)
>>>>
>>>> Added Arnd (probably will give more inputs or corrections)
>>>>
>>>> Let me explain how we implemented on our design.
>>>> We have PCIe controller that support basic root complex handling, dma
>>>> and controller hotplug (not in-build pcie hp) and ideally we need to
>>>> write driver for handling root complex on drivers/pci/host and one
>>>> hotplug driver in drivers/pci and one more driver in drivers/dma for
>>>> handling pcie dma stuff. And some pcie calls need to navigate from
>>>> root complex driver to dma and hotplug driver that means there is call
>>>> transition from driver/pci to driver/dma which is absolutely not a
>>>> good approach (spi to spi-nor and spi-nand transition - in GQSPI case)
>>>>
>>>> So the implementation we follow is like there is a pcie root complex
>>>> driver(probably generic spi driver in drivers/spi/*) and inside probe
>>>> we have register platform_device for hotplug (spi-nor) and dma
>>>> (spi-nand) and the dma driver in drivers/dma and hotplug driver in
>>>> driver/pci/ are platform drivers which is of legacy binding (not with
>>>> dts) so there should be a common dts for root complex driver
>>>> (drivers/spi/*) and individual child driver need to take those while
>>>> registering platform_device.
>>>>
>>>> example pseudo:
>>>>
>>>> drivers/dma/dma-child2.c
>>>>
>>>> Legacy platform_driver binding and handling dma future as normal dma
>>>> driver, spi-nand in your case
>>>>
>>>> drivers/pci/hotplug/hp-child1.c
>>>>
>>>> Legacy platform_driver binding and handling hotplug future as normal
>>>> hotplug driver, spi-nor in your case.
>>>>
>>>> drivers/pci/host/rc-parent-pci.c
>>>>
>>>> static int rc_parent_pcie_probe_bridge(struct platform_device *pdev)
>>>> {
>>>>    // Generic rc handling (genric spi stuff)
>>>>
>>>>    // Hotplug handling (spi-nor)
>>>>    - platform_device_alloc
>>>>    - assign need resources
>>>>    - register pdev using platform_device_add
>>>>
>>>>     // DMA handling (spi-nand)
>>>>    - same as above
>>>> }
>>>>
>>>> static const struct of_device_id rc_parent_pcie_match_table[] = {
>>>>         {.compatible = "abc,rc-parent",},
>>>>         {},
>>>> };
>>>>
>>>> static struct platform_driver rc_parent_pcie_driver = {
>>>>         .driver = {
>>>>                    .name = "rc-parent",
>>>>                    .of_match_table = of_match_ptr(rc_parent_pcie_match_table),
>>>>         },
>>>>         .probe = rc_parent_pcie_probe_bridge,
>>>> };
>>>> module_platform_driver(rc_parent_pcie_driver);
>>>>
>>>> I couldn't find any driver mainlined wrt this design, think more on
>>>> GQSPI front, whether this design fits well or not.

thanks!
-- 
Jagan | openedev.


From Hannes.Schmelzer at br-automation.com  Thu Aug 27 21:44:02 2015
From: Hannes.Schmelzer at br-automation.com (Hannes Schmelzer)
Date: Fri, 28 Aug 2015 06:44:02 +0200
Subject: [PATCH 2/2] memory: omap-gpmc: Add Kconfig option for debug
In-Reply-To: <20150827165940.GY4215@atomide.com>
References: <1432156863-19695-1-git-send-email-tony@atomide.com>
 <1432156863-19695-3-git-send-email-tony@atomide.com>
 <OFCA2F1DCE.C787A961-ONC1257EAE.001D79BC-C1257EAE.00203AFF@br-automation.com>
 <20150827165940.GY4215@atomide.com>
Message-ID: <OF3C55E837.F60C3642-ONC1257EAF.0019FAE8-C1257EAF.001A0165@br-automation.com>

> 
> Hi,
Hi,

> 
> * Hannes Schmelzer <Hannes.Schmelzer at br-automation.com> [150826 22:55]:
> > Hi Tony,
> > 
> > Did anyone test this changeset on some AM335x board?
> 
> Apparently not if it does not work or else you somehow have a different
> configuration for GPMC.
> 
> > Today I ran into trouble with that because:
> > 
> > The GPMC controller gets reseted on kernel boot due to the 
missing/removed 
> > HWMOD_INIT_NO_RESET flag.
> 
> Oh so you mean it only works on am335x if CONFIG_OMAP_GPMC_DEBUG is set?
Exactly.

> 
> > I also tried to issue some SYSRESET through GPMC registers without 
> > success, same strange behavior.
> 
> Interesting, never heard of that one before.

Unfortunately i only have my B&R hardware to test,
maybe somebody else has an am335x board with NAND flash on it and can 
test.


> > What?s your thinking around that?
> 
> We could add a custom hwmod reset function that sets GPMC_CONFIG to 0.
> Similar to omap_i2c_reset() is set up. 
This would be possible, but we've to take care that such functions isn't 
called during the new introduced debug-case.


> Or we could set up a property for
> the wait pin polarity. Roger, got any better ideas?

In general, it would be a good idea to introduce a dt-property to control 
the polarity of the wait pins, since there is allready a property to 
select the wait pin - this would make the thing complete.

> 
> Regards,
> Tony

best regards,
Hannes





From zhengxing at rock-chips.com  Thu Aug 27 22:46:47 2015
From: zhengxing at rock-chips.com (Xing Zheng)
Date: Fri, 28 Aug 2015 13:46:47 +0800
Subject: [PATCH v1 2/3] pinctrl: rockchip: add support for the rk3036
In-Reply-To: <1440740808-15004-1-git-send-email-zhengxing@rock-chips.com>
References: <1440740808-15004-1-git-send-email-zhengxing@rock-chips.com>
Message-ID: <1440740808-15004-3-git-send-email-zhengxing@rock-chips.com>

Many parts of pinctrl rk3036 are similar to rk2928's.

Signed-off-by: Xing Zheng <zhengxing at rock-chips.com>
---

Changes in v1: None

 drivers/pinctrl/pinctrl-rockchip.c |   17 +++++++++++++++++
 1 file changed, 17 insertions(+)

diff --git a/drivers/pinctrl/pinctrl-rockchip.c b/drivers/pinctrl/pinctrl-rockchip.c
index cc2843a..d06631d 100644
--- a/drivers/pinctrl/pinctrl-rockchip.c
+++ b/drivers/pinctrl/pinctrl-rockchip.c
@@ -2042,6 +2042,21 @@ static struct rockchip_pin_ctrl rk2928_pin_ctrl = {
 		.pull_calc_reg		= rk2928_calc_pull_reg_and_bit,
 };
 
+static struct rockchip_pin_bank rk3036_pin_banks[] = {
+	PIN_BANK(0, 32, "gpio0"),
+	PIN_BANK(1, 32, "gpio1"),
+	PIN_BANK(2, 32, "gpio2"),
+};
+
+static struct rockchip_pin_ctrl rk3036_pin_ctrl = {
+		.pin_banks		= rk3036_pin_banks,
+		.nr_banks		= ARRAY_SIZE(rk3036_pin_banks),
+		.label			= "RK3036-GPIO",
+		.type			= RK2928,
+		.grf_mux_offset		= 0xa8,
+		.pull_calc_reg		= rk2928_calc_pull_reg_and_bit,
+};
+
 static struct rockchip_pin_bank rk3066a_pin_banks[] = {
 	PIN_BANK(0, 32, "gpio0"),
 	PIN_BANK(1, 32, "gpio1"),
@@ -2160,6 +2175,8 @@ static struct rockchip_pin_ctrl rk3368_pin_ctrl = {
 static const struct of_device_id rockchip_pinctrl_dt_match[] = {
 	{ .compatible = "rockchip,rk2928-pinctrl",
 		.data = (void *)&rk2928_pin_ctrl },
+	{ .compatible = "rockchip,rk3036-pinctrl",
+		.data = (void *)&rk3036_pin_ctrl },
 	{ .compatible = "rockchip,rk3066a-pinctrl",
 		.data = (void *)&rk3066a_pin_ctrl },
 	{ .compatible = "rockchip,rk3066b-pinctrl",
-- 
1.7.9.5




From zhengxing at rock-chips.com  Thu Aug 27 22:46:45 2015
From: zhengxing at rock-chips.com (Xing Zheng)
Date: Fri, 28 Aug 2015 13:46:45 +0800
Subject: [PATCH v1 0/3] Port and support rk3036 SoC platform
Message-ID: <1440740808-15004-1-git-send-email-zhengxing@rock-chips.com>


Hi,
We need to support rk3036 soc platform via upstream, there are
3 parts for the initial release of minimum system: dts, pinctrl,
and clock tree for rk3036, startup and run to init processs.

Thanks.


Changes in v1:
Signed-off-by: Xing Zheng <zhengxing at rock-chips.com>

Xing Zheng (3):
  ARM: dts: rockchip: add core rk3036 dts
  pinctrl: rockchip: add support for the rk3036
  clk: rockchip: add clock controller for rk3036

 arch/arm/boot/dts/Makefile             |    1 +
 arch/arm/boot/dts/rk3036-sdk.dts       |  362 +++++++++++++++++++++
 drivers/clk/rockchip/Makefile          |    1 +
 drivers/clk/rockchip/clk-pll.c         |  247 ++++++++++++++-
 drivers/clk/rockchip/clk-rk3036.c      |  539 ++++++++++++++++++++++++++++++++
 drivers/clk/rockchip/clk.h             |   30 ++
 drivers/pinctrl/pinctrl-rockchip.c     |   17 +
 include/dt-bindings/clock/rk3036-cru.h |  247 +++++++++++++++
 8 files changed, 1443 insertions(+), 1 deletion(-)
 create mode 100644 arch/arm/boot/dts/rk3036-sdk.dts
 create mode 100644 drivers/clk/rockchip/clk-rk3036.c
 create mode 100644 include/dt-bindings/clock/rk3036-cru.h

-- 
1.7.9.5




From zhengxing at rock-chips.com  Thu Aug 27 22:46:46 2015
From: zhengxing at rock-chips.com (Xing Zheng)
Date: Fri, 28 Aug 2015 13:46:46 +0800
Subject: [PATCH v1 1/3] ARM: dts: rockchip: add core rk3036 dts
In-Reply-To: <1440740808-15004-1-git-send-email-zhengxing@rock-chips.com>
References: <1440740808-15004-1-git-send-email-zhengxing@rock-chips.com>
Message-ID: <1440740808-15004-2-git-send-email-zhengxing@rock-chips.com>

Initial release for rk3036, node definitions rk3036 sdk board.

Signed-off-by: Xing Zheng <zhengxing at rock-chips.com>
---

Changes in v1: None

 arch/arm/boot/dts/Makefile       |    1 +
 arch/arm/boot/dts/rk3036-sdk.dts |  362 ++++++++++++++++++++++++++++++++++++++
 2 files changed, 363 insertions(+)
 create mode 100644 arch/arm/boot/dts/rk3036-sdk.dts

diff --git a/arch/arm/boot/dts/Makefile b/arch/arm/boot/dts/Makefile
index 6d7cec1..7014a3b 100644
--- a/arch/arm/boot/dts/Makefile
+++ b/arch/arm/boot/dts/Makefile
@@ -501,6 +501,7 @@ dtb-$(CONFIG_ARCH_ROCKCHIP) += \
 	rk3066a-bqcurie2.dtb \
 	rk3066a-marsboard.dtb \
 	rk3066a-rayeager.dtb \
+	rk3036-sdk.dtb \
 	rk3188-radxarock.dtb \
 	rk3288-evb-act8846.dtb \
 	rk3288-evb-rk808.dtb \
diff --git a/arch/arm/boot/dts/rk3036-sdk.dts b/arch/arm/boot/dts/rk3036-sdk.dts
new file mode 100644
index 0000000..0149c9a
--- /dev/null
+++ b/arch/arm/boot/dts/rk3036-sdk.dts
@@ -0,0 +1,362 @@
+/*
+ * This file is dual-licensed: you can use it either under the terms
+ * of the GPL or the X11 license, at your option. Note that this dual
+ * licensing only applies to this file, and not this project as a
+ * whole.
+ *
+ *  a) This file is free software; you can redistribute it and/or
+ *     modify it under the terms of the GNU General Public License as
+ *     published by the Free Software Foundation; either version 2 of the
+ *     License, or (at your option) any later version.
+ *
+ *     This file is distributed in the hope that it will be useful,
+ *     but WITHOUT ANY WARRANTY; without even the implied warranty of
+ *     MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ *     GNU General Public License for more details.
+ *
+ * Or, alternatively,
+ *
+ *  b) Permission is hereby granted, free of charge, to any person
+ *     obtaining a copy of this software and associated documentation
+ *     files (the "Software"), to deal in the Software without
+ *     restriction, including without limitation the rights to use,
+ *     copy, modify, merge, publish, distribute, sublicense, and/or
+ *     sell copies of the Software, and to permit persons to whom the
+ *     Software is furnished to do so, subject to the following
+ *     conditions:
+ *
+ *     The above copyright notice and this permission notice shall be
+ *     included in all copies or substantial portions of the Software.
+ *
+ *     THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
+ *     EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES
+ *     OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
+ *     NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT
+ *     HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY,
+ *     WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
+ *     FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR
+ *     OTHER DEALINGS IN THE SOFTWARE.
+ */
+
+/dts-v1/;
+
+#include <dt-bindings/gpio/gpio.h>
+#include <dt-bindings/interrupt-controller/irq.h>
+#include <dt-bindings/interrupt-controller/arm-gic.h>
+#include <dt-bindings/pinctrl/rockchip.h>
+#include <dt-bindings/clock/rk3036-cru.h>
+#include "skeleton.dtsi"
+
+/ {
+	compatible = "rockchip,rk3036";
+
+	interrupt-parent = <&gic>;
+
+	aliases {
+		serial0 = &uart0;
+		serial1 = &uart1;
+		serial2 = &uart2;
+	};
+
+	memory {
+		reg = <0x60000000 0x40000000>;
+	};
+
+        arm-pmu {
+                compatible = "arm,cortex-a7-pmu";
+                interrupts = <GIC_SPI 76 IRQ_TYPE_LEVEL_HIGH>,
+                             <GIC_SPI 77 IRQ_TYPE_LEVEL_HIGH>;
+        };
+
+	cpus {
+		#address-cells = <1>;
+		#size-cells = <0>;
+		//enable-method = "rockchip,rk3066-smp";
+
+		cpu at f00 {
+			device_type = "cpu";
+			compatible = "arm,cortex-a7";
+			reg = <0xf00>;
+			operating-points = <
+				/* KHz    uV */
+				 816000 1000000
+			>;
+			#cooling-cells = <2>; /* min followed by max */
+			clock-latency = <40000>;
+			clocks = <&cru ARMCLK>;
+			resets = <&cru SRST_CORE0>;
+		};
+		cpu at f01 {
+			device_type = "cpu";
+			compatible = "arm,cortex-a7";
+			reg = <0xf01>;
+			resets = <&cru SRST_CORE1>;
+		};
+	};
+
+	amba {
+		compatible = "arm,amba-bus";
+		#address-cells = <1>;
+		#size-cells = <1>;
+		ranges;
+
+                pdma: pdma at 20078000 {
+                        compatible = "arm,pl330", "arm,primecell";
+                        reg = <0x20078000 0x4000>;
+                        interrupts = <GIC_SPI 0 IRQ_TYPE_LEVEL_HIGH>,
+                                     <GIC_SPI 1 IRQ_TYPE_LEVEL_HIGH>;
+                        #dma-cells = <1>;
+                        clocks = <&cru ACLK_DMAC2>;
+                        clock-names = "apb_pclk";
+                };
+	};
+
+	xin24m: oscillator {
+		compatible = "fixed-clock";
+		clock-frequency = <24000000>;
+		clock-output-names = "xin24m";
+		#clock-cells = <0>;
+	};
+
+	timer {
+		compatible = "arm,armv7-timer";
+		arm,cpu-registers-not-fw-configured;
+		interrupts = <GIC_PPI 13 (GIC_CPU_MASK_SIMPLE(4) | IRQ_TYPE_LEVEL_HIGH)>,
+			     <GIC_PPI 14 (GIC_CPU_MASK_SIMPLE(4) | IRQ_TYPE_LEVEL_HIGH)>;
+		clock-frequency = <24000000>;
+		always-on;
+	};
+
+	cru: clock-controller at 20000000 {
+		compatible = "rockchip,rk3036-cru";
+		reg = <0x20000000 0x1000>;
+		rockchip,grf = <&grf>;
+		#clock-cells = <1>;
+		#reset-cells = <1>;
+		assigned-clocks = <&cru PLL_GPLL>;
+		assigned-clock-rates = <594000000>;
+	};
+
+	uart0: serial at 20060000 {
+		compatible = "rockchip,rk3036-uart", "snps,dw-apb-uart";
+		reg = <0x20060000 0x100>;
+		interrupts = <GIC_SPI 20 IRQ_TYPE_LEVEL_HIGH>;
+		reg-shift = <2>;
+		reg-io-width = <4>;
+		clock-frequency = <24000000>;
+		clocks = <&cru SCLK_UART0>, <&cru PCLK_UART0>;
+		clock-names = "baudclk", "apb_pclk";
+		pinctrl-names = "default";
+		pinctrl-0 = <&uart0_xfer &uart0_cts &uart0_rts>;
+	};
+
+	uart1: serial at 20064000 {
+		compatible = "rockchip,rk3036-uart", "snps,dw-apb-uart";
+		reg = <0x20064000 0x100>;
+		interrupts = <GIC_SPI 21 IRQ_TYPE_LEVEL_HIGH>;
+		reg-shift = <2>;
+		reg-io-width = <4>;
+		clock-frequency = <24000000>;
+		clocks = <&cru SCLK_UART1>, <&cru PCLK_UART1>;
+		clock-names = "baudclk", "apb_pclk";
+		pinctrl-names = "default";
+		pinctrl-0 = <&uart1_xfer>;
+	};
+
+	uart2: serial at 20068000 {
+		compatible = "rockchip,rk3036-uart", "snps,dw-apb-uart";
+		reg = <0x20068000 0x100>;
+		interrupts = <GIC_SPI 22 IRQ_TYPE_LEVEL_HIGH>;
+		reg-shift = <2>;
+		reg-io-width = <4>;
+		clock-frequency = <24000000>;
+		clocks = <&cru SCLK_UART2>, <&cru PCLK_UART2>;
+		clock-names = "baudclk", "apb_pclk";
+		pinctrl-names = "default";
+		pinctrl-0 = <&uart2_xfer>;
+	};
+
+	pwm0: pwm at 20050000 {
+		compatible = "rockchip,rk2928-pwm";
+		reg = <0x20050000 0x10>;
+		#pwm-cells = <3>;
+		pinctrl-names = "default";
+		pinctrl-0 = <&pwm0_pin>;
+		clocks = <&cru PCLK_PWM>;
+		clock-names = "pwm";
+		status = "disabled";
+	};
+
+	pwm1: pwm at 20050010 {
+		compatible = "rockchip,rk2928-pwm";
+		reg = <0x20050010 0x10>;
+		#pwm-cells = <3>;
+		pinctrl-names = "default";
+		pinctrl-0 = <&pwm1_pin>;
+		clocks = <&cru PCLK_PWM>;
+		clock-names = "pwm";
+		status = "disabled";
+	};
+
+	pwm2: pwm at 20050020 {
+		compatible = "rockchip,rk2928-pwm";
+		reg = <0x20050020 0x10>;
+		#pwm-cells = <3>;
+		pinctrl-names = "default";
+		pinctrl-0 = <&pwm2_pin>;
+		clocks = <&cru PCLK_PWM>;
+		clock-names = "pwm";
+		status = "disabled";
+	};
+
+	pwm3: pwm at 20050030 {
+		compatible = "rockchip,rk2928-pwm";
+		reg = <0x20050030 0x10>;
+		#pwm-cells = <2>;
+		pinctrl-names = "default";
+		pinctrl-0 = <&pwm3_pin>;
+		clocks = <&cru PCLK_PWM>;
+		clock-names = "pwm";
+		status = "disabled";
+	};
+
+	sram at 10080000 {
+		compatible = "mmio-sram";
+		reg = <0x10080000 0x2000>;
+		map-exec;
+	};
+
+	gic: interrupt-controller at 10139000 {
+		compatible = "arm,gic-400";
+		interrupt-controller;
+		#interrupt-cells = <3>;
+		#address-cells = <0>;
+
+		reg = <0x10139000 0x1000>,
+		      <0x1013a000 0x1000>;
+	};
+
+	grf: syscon at 20008000 {
+		compatible = "rockchip,rk3036-grf", "syscon";
+		reg = <0x20008000 0x1000>;
+	};
+
+	pinctrl: pinctrl {
+		compatible = "rockchip,rk3036-pinctrl";
+		rockchip,grf = <&grf>;
+		#address-cells = <1>;
+		#size-cells = <1>;
+		ranges;
+
+		gpio0: gpio0 at 2007c000 {
+			compatible = "rockchip,gpio-bank";
+			reg =	<0x2007c000 0x100>;
+			interrupts = <GIC_SPI 36 IRQ_TYPE_LEVEL_HIGH>;
+			clocks = <&cru PCLK_GPIO0>;
+
+			gpio-controller;
+			#gpio-cells = <2>;
+
+			interrupt-controller;
+			#interrupt-cells = <2>;
+		};
+
+		gpio1: gpio1 at 20080000 {
+			compatible = "rockchip,gpio-bank";
+			reg = <0x20080000 0x100>;
+			interrupts = <GIC_SPI 37 IRQ_TYPE_LEVEL_HIGH>;
+			clocks = <&cru PCLK_GPIO1>;
+
+			gpio-controller;
+			#gpio-cells = <2>;
+
+			interrupt-controller;
+			#interrupt-cells = <2>;
+		};
+
+		gpio2: gpio2 at 20084000 {
+			compatible = "rockchip,gpio-bank";
+			reg = <0x20084000 0x100>;
+			interrupts = <GIC_SPI 38 IRQ_TYPE_LEVEL_HIGH>;
+			clocks = <&cru PCLK_GPIO2>;
+
+			gpio-controller;
+			#gpio-cells = <2>;
+
+			interrupt-controller;
+			#interrupt-cells = <2>;
+		};
+
+		pcfg_pull_up: pcfg-pull-up {
+			bias-pull-up;
+		};
+
+		pcfg_pull_down: pcfg-pull-down {
+			bias-pull-down;
+		};
+
+		pcfg_pull_none: pcfg-pull-none {
+			bias-disable;
+		};
+
+		pcfg_pull_none_12ma: pcfg-pull-none-12ma {
+			bias-disable;
+			drive-strength = <12>;
+		};
+
+		uart0 {
+			uart0_xfer: uart0-xfer {
+				rockchip,pins = <0 16 RK_FUNC_1 &pcfg_pull_none>,
+						<0 17 RK_FUNC_1 &pcfg_pull_none>;
+			};
+
+			uart0_cts: uart0-cts {
+				rockchip,pins = <0 18 RK_FUNC_1 &pcfg_pull_none>;
+			};
+
+			uart0_rts: uart0-rts {
+				rockchip,pins = <0 19 RK_FUNC_1 &pcfg_pull_none>;
+			};
+		};
+
+		uart1 {
+			uart1_xfer: uart1-xfer {
+				rockchip,pins = <2 22 RK_FUNC_1 &pcfg_pull_none>,
+						<2 23 RK_FUNC_1 &pcfg_pull_none>;
+			};
+			/* no rts / cts for uart1 */
+		};
+
+                uart2 {
+                        uart2_xfer: uart2-xfer {
+                                rockchip,pins = <1 18 RK_FUNC_2 &pcfg_pull_none>,
+                                                <1 19 RK_FUNC_2 &pcfg_pull_none>;
+                        };
+                        /* no rts / cts for uart2 */
+                };
+
+		pwm0 {
+			pwm0_pin: pwm0-pin {
+				rockchip,pins = <0 0 RK_FUNC_2 &pcfg_pull_none>;
+			};
+		};
+
+		pwm1 {
+			pwm1_pin: pwm1-pin {
+				rockchip,pins = <0 1 RK_FUNC_2 &pcfg_pull_none>;
+			};
+		};
+
+		pwm2 {
+			pwm2_pin: pwm2-pin {
+				rockchip,pins = <0 1 2 &pcfg_pull_none>;
+			};
+		};
+
+		pwm3 {
+			pwm3_pin: pwm3-pin {
+				rockchip,pins = <0 27 1 &pcfg_pull_none>;
+			};
+		};
+	};
+};
-- 
1.7.9.5




From zhengxing at rock-chips.com  Thu Aug 27 22:46:48 2015
From: zhengxing at rock-chips.com (Xing Zheng)
Date: Fri, 28 Aug 2015 13:46:48 +0800
Subject: [PATCH v1 3/3] clk: rockchip: add clock controller for rk3036
In-Reply-To: <1440740808-15004-1-git-send-email-zhengxing@rock-chips.com>
References: <1440740808-15004-1-git-send-email-zhengxing@rock-chips.com>
Message-ID: <1440740808-15004-4-git-send-email-zhengxing@rock-chips.com>

Add the clock tree definition for the new rk3036 SoC,
but there are some issues to be fixed:
1. soc will crash if gpll run rate_change_remuxed
2. rk3036_clk_suspend and rk3036_clk_resume should be done
   in clk-rk3036.c

---

Changes in v1:
Signed-off-by: Xing Zheng <zhengxing at rock-chips.com>

 drivers/clk/rockchip/Makefile          |    1 +
 drivers/clk/rockchip/clk-pll.c         |  247 ++++++++++++++-
 drivers/clk/rockchip/clk-rk3036.c      |  539 ++++++++++++++++++++++++++++++++
 drivers/clk/rockchip/clk.h             |   30 ++
 include/dt-bindings/clock/rk3036-cru.h |  247 +++++++++++++++
 5 files changed, 1063 insertions(+), 1 deletion(-)
 create mode 100644 drivers/clk/rockchip/clk-rk3036.c
 create mode 100644 include/dt-bindings/clock/rk3036-cru.h

diff --git a/drivers/clk/rockchip/Makefile b/drivers/clk/rockchip/Makefile
index b27edd6..d599829 100644
--- a/drivers/clk/rockchip/Makefile
+++ b/drivers/clk/rockchip/Makefile
@@ -10,6 +10,7 @@ obj-y	+= clk-inverter.o
 obj-y	+= clk-mmc-phase.o
 obj-$(CONFIG_RESET_CONTROLLER)	+= softrst.o
 
+obj-y	+= clk-rk3036.o
 obj-y	+= clk-rk3188.o
 obj-y	+= clk-rk3288.o
 obj-y	+= clk-rk3368.o
diff --git a/drivers/clk/rockchip/clk-pll.c b/drivers/clk/rockchip/clk-pll.c
index 96903ae..cf56826 100644
--- a/drivers/clk/rockchip/clk-pll.c
+++ b/drivers/clk/rockchip/clk-pll.c
@@ -2,6 +2,9 @@
  * Copyright (c) 2014 MundoReader S.L.
  * Author: Heiko Stuebner <heiko at sntech.de>
  *
+ * Copyright (c) 2015 Rockchip Electronics Co. Ltd.
+ * Author: Xing Zheng <zhengxing at 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
@@ -48,6 +51,8 @@ struct rockchip_clk_pll {
 #define to_rockchip_clk_pll_nb(nb) \
 			container_of(nb, struct rockchip_clk_pll, clk_nb)
 
+static int rockchip_rk3036_pll_wait_lock(struct rockchip_clk_pll *pll);
+
 static const struct rockchip_pll_rate_table *rockchip_get_pll_settings(
 			    struct rockchip_clk_pll *pll, unsigned long rate)
 {
@@ -90,6 +95,11 @@ static int rockchip_pll_wait_lock(struct rockchip_clk_pll *pll)
 	unsigned int val;
 	int delay = 24000000, ret;
 
+	/* the plls of rk3036 wait lock */
+	if (pll->type == pll_rk3036 || pll->lock_offset == -1) {
+		return rockchip_rk3036_pll_wait_lock(pll);
+	}
+
 	while (delay > 0) {
 		ret = regmap_read(grf, pll->lock_offset, &val);
 		if (ret) {
@@ -305,6 +315,235 @@ static void rockchip_rk3066_pll_init(struct clk_hw *hw)
 		rockchip_rk3066_pll_set_rate(hw, drate, prate);
 	}
 }
+/**
+ * PLL used in RK3036
+ */
+
+#define RK3036_PLL_RESET_DELAY(nr)	((nr * 500) / 24 + 1)
+
+#define RK3036_PLLCON(i)			(i * 0x4)
+#define RK3036_PLLCON0_FBDIV_MASK		0xfff
+#define RK3036_PLLCON0_FBDIV_SHIFT		0
+#define RK3036_PLLCON0_POSTDIV1_MASK		0x7
+#define RK3036_PLLCON0_POSTDIV1_SHIFT		12
+#define RK3036_PLLCON1_REFDIV_MASK		0x3f
+#define RK3036_PLLCON1_REFDIV_SHIFT		0
+#define RK3036_PLLCON1_POSTDIV2_MASK		0x7
+#define RK3036_PLLCON1_POSTDIV2_SHIFT		6
+#define RK3036_PLLCON1_DSMPD_MASK		0x1
+#define RK3036_PLLCON1_DSMPD_SHIFT		12
+#define RK3036_PLLCON2_FRAC_MASK		0xffffff
+#define RK3036_PLLCON2_FRAC_SHIFT		0
+
+#define RK3036_MODECON				0x40
+#define RK3036_MODECON_AWM			(1 << 0)  /* apll work mode */
+
+#define RK3036_PLLCON0_BYPASS			(1 << 15)
+#define RK3036_PLLCON1_LOCK_STATUS		(1 << 10)
+#define RK3036_PLLCON1_RESET			(1 << 14)
+
+static int rockchip_rk3036_pll_wait_lock(struct rockchip_clk_pll *pll)
+{
+	u32 pllcon;
+	int delay = 24000000;
+
+	/* poll check the lock status in rk3036 xPLLCON1 */
+	while (delay > 0) {
+		pllcon = readl_relaxed(pll->reg_base + RK3036_PLLCON(1));
+		if (pllcon & RK3036_PLLCON1_LOCK_STATUS)
+			return 0;
+
+		delay--;
+	}
+
+	pr_err("%s: timeout waiting for pll to lock\n", __func__);
+	return -ETIMEDOUT;
+}
+
+static unsigned long rockchip_rk3036_pll_recalc_rate(struct clk_hw *hw,
+						     unsigned long prate)
+{
+	struct rockchip_clk_pll *pll = to_rockchip_clk_pll(hw);
+	unsigned int fbdiv, postdiv1, refdiv, postdiv2, dsmpd, frac;
+	u64 rate64 = prate;
+	u32 pllcon;
+
+	pllcon = readl_relaxed(pll->reg_base + RK3036_PLLCON(0));
+	fbdiv = ((pllcon >> RK3036_PLLCON0_FBDIV_SHIFT) & RK3036_PLLCON0_FBDIV_MASK);
+	postdiv1 = ((pllcon >> RK3036_PLLCON0_POSTDIV1_SHIFT) & RK3036_PLLCON0_POSTDIV1_MASK);
+
+	pllcon = readl_relaxed(pll->reg_base + RK3036_PLLCON(1));
+	refdiv = ((pllcon >> RK3036_PLLCON1_REFDIV_SHIFT) & RK3036_PLLCON1_REFDIV_MASK);
+	postdiv2 = ((pllcon >> RK3036_PLLCON1_POSTDIV2_SHIFT) & RK3036_PLLCON1_POSTDIV2_MASK);
+	dsmpd = ((pllcon >> RK3036_PLLCON1_DSMPD_SHIFT) & RK3036_PLLCON1_DSMPD_MASK);
+
+	pllcon = readl_relaxed(pll->reg_base + RK3036_PLLCON(2));
+	frac = ((pllcon >> RK3036_PLLCON2_FRAC_SHIFT) & RK3036_PLLCON2_FRAC_MASK);
+
+	rate64 *= fbdiv;
+	do_div(rate64, refdiv);
+
+	if (dsmpd == 0) {
+		/* fractional mode */
+		u64 frac_rate64 = prate * frac;
+
+		do_div(frac_rate64, refdiv);
+		rate64 += frac_rate64 >> 24;
+	}
+
+	do_div(rate64, postdiv1);
+	do_div(rate64, postdiv2);
+
+	return (unsigned long)rate64;
+}
+
+static int rockchip_rk3036_pll_set_rate(struct clk_hw *hw, unsigned long drate,
+					unsigned long prate)
+{
+	struct rockchip_clk_pll *pll = to_rockchip_clk_pll(hw);
+	const struct rockchip_pll_rate_table *rate;
+	unsigned long old_rate = rockchip_rk3036_pll_recalc_rate(hw, prate);
+	struct regmap *grf = rockchip_clk_get_grf();
+	struct clk_mux *pll_mux = &pll->pll_mux;
+	const struct clk_ops *pll_mux_ops = pll->pll_mux_ops;
+	int rate_change_remuxed = 0;
+	int cur_parent;
+	int ret;
+
+	if (IS_ERR(grf)) {
+		pr_debug("%s: grf regmap not available, aborting rate change\n",
+			 __func__);
+		return PTR_ERR(grf);
+	}
+
+	pr_debug("%s: changing %s from %lu to %lu with a parent rate of %lu\n",
+		 __func__, __clk_get_name(hw->clk), old_rate, drate, prate);
+
+	/* Get required rate settings from table */
+	rate = rockchip_get_pll_settings(pll, drate);
+	if (!rate) {
+		pr_err("%s: Invalid rate : %lu for pll clk %s\n", __func__,
+			drate, __clk_get_name(hw->clk));
+		return -EINVAL;
+	}
+
+	pr_debug("%s: rate settings for %lu fbdiv: %d, postdiv1: %d, refdiv: %d, postdiv2: %d, dsmpd: %d, frac: %d\n",
+		__func__, rate->rate,
+		rate->fbdiv, rate->postdiv1, rate->refdiv, rate->postdiv2, rate->dsmpd, rate->frac);
+
+	cur_parent = pll_mux_ops->get_parent(&pll_mux->hw);
+	if (cur_parent == PLL_MODE_NORM) {
+		pll_mux_ops->set_parent(&pll_mux->hw, PLL_MODE_SLOW);
+		rate_change_remuxed = 1;
+	}
+
+	/* enter reset mode */
+	writel(HIWORD_UPDATE(1, RK3036_PLLCON1_RESET, 0), pll->reg_base + RK3036_PLLCON(1));
+
+	/* update pll values */
+	writel_relaxed(HIWORD_UPDATE(rate->fbdiv, RK3036_PLLCON0_FBDIV_MASK,
+					  RK3036_PLLCON0_FBDIV_SHIFT) |
+		       HIWORD_UPDATE(rate->postdiv1, RK3036_PLLCON0_POSTDIV1_MASK,
+					     RK3036_PLLCON0_POSTDIV1_SHIFT),
+		       pll->reg_base + RK3036_PLLCON(0));
+
+	writel_relaxed(HIWORD_UPDATE(rate->refdiv, RK3036_PLLCON1_REFDIV_MASK,
+						   RK3036_PLLCON1_REFDIV_SHIFT) |
+		       HIWORD_UPDATE(rate->postdiv2, RK3036_PLLCON1_POSTDIV2_MASK,
+						     RK3036_PLLCON1_POSTDIV2_SHIFT) |
+		       HIWORD_UPDATE(rate->dsmpd, RK3036_PLLCON1_DSMPD_MASK,
+						  RK3036_PLLCON1_DSMPD_SHIFT),
+		       pll->reg_base + RK3036_PLLCON(1));
+
+	writel_relaxed(HIWORD_UPDATE(rate->frac, RK3036_PLLCON2_FRAC_MASK,
+						 RK3036_PLLCON2_FRAC_SHIFT),
+		       pll->reg_base + RK3036_PLLCON(2));
+
+	/* recover normal mode and wait the reset_delay */
+	writel(HIWORD_UPDATE(0, RK3036_PLLCON1_RESET, 0), pll->reg_base + RK3036_PLLCON(1));
+	udelay(RK3036_PLL_RESET_DELAY(rate->refdiv));
+
+	/* wait for the pll to lock */
+	ret = rockchip_pll_wait_lock(pll);
+	if (ret) {
+		pr_warn("%s: pll did not lock, trying to restore old rate %lu\n",
+			__func__, old_rate);
+		rockchip_rk3036_pll_set_rate(hw, old_rate, prate);
+	}
+
+#if 0 /* FIXME: soc will crash if gpll run here */
+	if (rate_change_remuxed)
+		pll_mux_ops->set_parent(&pll_mux->hw, PLL_MODE_NORM);
+#endif
+
+	return ret;
+}
+static void rockchip_rk3036_pll_init(struct clk_hw *hw)
+{
+	struct rockchip_clk_pll *pll = to_rockchip_clk_pll(hw);
+	const struct rockchip_pll_rate_table *rate;
+	unsigned int fbdiv, postdiv1, refdiv, postdiv2, dsmpd, frac;
+	unsigned long drate;
+	u32 pllcon;
+
+	if (!(pll->flags & ROCKCHIP_PLL_SYNC_RATE))
+		return;
+
+	drate = __clk_get_rate(hw->clk);
+	rate = rockchip_get_pll_settings(pll, drate);
+
+	/* when no rate setting for the current rate, rely on clk_set_rate */
+	if (!rate)
+		return;
+
+	pllcon = readl_relaxed(pll->reg_base + RK3036_PLLCON(0));
+	fbdiv = ((pllcon >> RK3036_PLLCON0_FBDIV_SHIFT) & RK3036_PLLCON0_FBDIV_MASK);
+	postdiv1 = ((pllcon >> RK3036_PLLCON0_POSTDIV1_SHIFT) & RK3036_PLLCON0_POSTDIV1_MASK);
+
+	pllcon = readl_relaxed(pll->reg_base + RK3036_PLLCON(1));
+	refdiv = ((pllcon >> RK3036_PLLCON1_REFDIV_SHIFT) & RK3036_PLLCON1_REFDIV_MASK);
+	postdiv2 = ((pllcon >> RK3036_PLLCON1_POSTDIV2_SHIFT) & RK3036_PLLCON1_POSTDIV2_MASK);
+	dsmpd = ((pllcon >> RK3036_PLLCON1_DSMPD_SHIFT) & RK3036_PLLCON1_DSMPD_MASK);
+
+	pllcon = readl_relaxed(pll->reg_base + RK3036_PLLCON(2));
+	frac = ((pllcon >> RK3036_PLLCON2_FRAC_SHIFT) & RK3036_PLLCON2_FRAC_MASK);
+
+	pr_info("%s: pll %s@%lu: Hz\n", __func__, __clk_get_name(hw->clk), drate);
+	pr_info("old - fbdiv: %d, postdiv1: %d, refdiv: %d, postdiv2: %d, dsmpd: %d, frac: %d\n",
+		fbdiv, postdiv1, refdiv, postdiv2, dsmpd, frac);
+	pr_info("new - fbdiv: %d, postdiv1: %d, refdiv: %d, postdiv2: %d, dsmpd: %d, frac: %d\n",
+		rate->fbdiv, rate->postdiv1, rate->refdiv, rate->postdiv2, rate->dsmpd, rate->frac);
+
+	if (rate->fbdiv != fbdiv || rate->postdiv1 != postdiv1 || rate->refdiv != refdiv ||
+		rate->postdiv2 != postdiv2 || rate->dsmpd != dsmpd || rate->frac != frac) {
+		struct clk *parent = __clk_get_parent(hw->clk);
+		unsigned long prate;
+
+		if (!parent) {
+			pr_warn("%s: parent of %s not available\n",
+				__func__, __clk_get_name(hw->clk));
+			return;
+		}
+
+		pr_info("%s: pll %s: rate params do not match rate table, adjusting\n",
+			 __func__, __clk_get_name(hw->clk));
+		prate = __clk_get_rate(parent);
+		rockchip_rk3036_pll_set_rate(hw, drate, prate);
+	}
+}
+static const struct clk_ops rockchip_rk3036_pll_clk_norate_ops = {
+	.recalc_rate = rockchip_rk3036_pll_recalc_rate,
+	.round_rate = rockchip_pll_round_rate,
+	.set_rate = rockchip_rk3036_pll_set_rate,
+	.init = rockchip_rk3036_pll_init,
+};
+
+static const struct clk_ops rockchip_rk3036_pll_clk_ops = {
+	.recalc_rate = rockchip_rk3036_pll_recalc_rate,
+	.round_rate = rockchip_pll_round_rate,
+	.set_rate = rockchip_rk3036_pll_set_rate,
+	.init = rockchip_rk3036_pll_init,
+};
 
 static const struct clk_ops rockchip_rk3066_pll_clk_norate_ops = {
 	.recalc_rate = rockchip_rk3066_pll_recalc_rate,
@@ -385,6 +624,12 @@ struct clk *rockchip_clk_register_pll(enum rockchip_pll_type pll_type,
 		else
 			init.ops = &rockchip_rk3066_pll_clk_ops;
 		break;
+	case pll_rk3036:
+		if (!pll->rate_table)
+			init.ops = &rockchip_rk3036_pll_clk_norate_ops;
+		else
+			init.ops = &rockchip_rk3036_pll_clk_ops;
+		break;
 	default:
 		pr_warn("%s: Unknown pll type for pll clk %s\n",
 			__func__, name);
@@ -408,7 +653,7 @@ struct clk *rockchip_clk_register_pll(enum rockchip_pll_type pll_type,
 	pll_mux->lock = lock;
 	pll_mux->hw.init = &init;
 
-	if (pll_type == pll_rk3066)
+	if (pll_type == pll_rk3066 || pll_type == pll_rk3036)
 		pll_mux->flags |= CLK_MUX_HIWORD_MASK;
 
 	pll_clk = clk_register(NULL, &pll->hw);
diff --git a/drivers/clk/rockchip/clk-rk3036.c b/drivers/clk/rockchip/clk-rk3036.c
new file mode 100644
index 0000000..19cdf0e
--- /dev/null
+++ b/drivers/clk/rockchip/clk-rk3036.c
@@ -0,0 +1,539 @@
+/*
+ * Copyright (c) 2014 MundoReader S.L.
+ * Author: Heiko Stuebner <heiko at sntech.de>
+ *
+ * Copyright (c) 2015 Rockchip Electronics Co. Ltd.
+ * Author: Xing Zheng <zhengxing at 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/rk3036-cru.h>
+#include "clk.h"
+
+enum rk3036_plls {
+	apll, dpll, gpll,
+};
+
+static struct rockchip_pll_rate_table rk3036_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),
+	RK3036_PLL_RATE(0, 1, 0, 1, 1, 1, 0),
+	{ /* sentinel */ },
+};
+
+#define RK3036_DIV_CPU_MASK		0x1f
+#define RK3036_DIV_CPU_SHIFT		8
+
+#define RK3036_DIV_PERI_MASK		0xf
+#define RK3036_DIV_PERI_SHIFT		0
+#define RK3036_DIV_ACLK_MASK		0x7
+#define RK3036_DIV_ACLK_SHIFT		4
+#define RK3036_DIV_HCLK_MASK		0x3
+#define RK3036_DIV_HCLK_SHIFT		8
+#define RK3036_DIV_PCLK_MASK		0x7
+#define RK3036_DIV_PCLK_SHIFT		12
+
+#define RK3036_CLKSEL1(_core_periph_div)					\
+	{									\
+		.reg = RK2928_CLKSEL_CON(1),					\
+		.val = HIWORD_UPDATE(_core_periph_div, RK3036_DIV_PERI_MASK,	\
+				RK3036_DIV_PERI_SHIFT)				\
+	}
+
+#define RK3036_CPUCLK_RATE(_prate, _core_periph_div)			\
+	{								\
+		.prate = _prate,					\
+		.divs = {						\
+			RK3036_CLKSEL1(_core_periph_div),		\
+		},							\
+	}
+
+static struct rockchip_cpuclk_rate_table rk3036_cpuclk_rates[] __initdata = {
+	RK3036_CPUCLK_RATE(816000000, 4),
+	RK3036_CPUCLK_RATE(600000000, 4),
+	RK3036_CPUCLK_RATE(312000000, 4),
+};
+
+static const struct rockchip_cpuclk_reg_data rk3036_cpuclk_data = {
+	.core_reg = RK2928_CLKSEL_CON(0),
+	.div_core_shift = 0,
+	.div_core_mask = 0x1f,
+	.mux_core_shift = 7,
+};
+
+PNAME(mux_pll_p)		= { "xin24m", "xin24m" };
+
+PNAME(mux_armclk_p)		= { "apll", "gpll_armclk" };
+PNAME(mux_busclk_p)		= { "apll", "dpll_cpu", "gpll_cpu" };
+PNAME(mux_ddrphy_p)		= { "dpll_ddr", "gpll_ddr" };
+PNAME(mux_pll_src_3plls_p)	= { "apll", "dpll", "gpll" };
+PNAME(mux_timer_p)		= { "xin24m", "pclk_peri_src" };
+
+PNAME(mux_pll_src_apll_gpll_dpll_usb480m_p)	= { "apll", "gpll", "dpll" "usb480m" };
+
+PNAME(mux_mmc_src_p)	= { "apll", "gpll", "dpll", "xin24m" };
+PNAME(mux_i2s_pre_p)	= { "i2s_src", "i2s_frac", "ext_i2s", "xin12m" };
+PNAME(mux_i2s_clkout_p)	= { "i2s_pre", "xin12m" };
+PNAME(mux_spdif_p)	= { "spdif_src", "spdif_frac", "xin12m" };
+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" };
+PNAME(mux_mac_p)	= { "mac_pll_src", "ext_gmac" };
+PNAME(mux_dclk_p)	= { "dclk_lcdc", "dclk_hdmi_src" };
+
+static struct rockchip_pll_clock rk3036_pll_clks[] __initdata = {
+	[apll] = PLL(pll_rk3036, PLL_APLL, "apll", mux_pll_p, 0, RK2928_PLL_CON(0),
+		     RK2928_MODE_CON, 0, 10, 0, rk3036_pll_rates),
+	[dpll] = PLL(pll_rk3036, PLL_DPLL, "dpll", mux_pll_p, 0, RK2928_PLL_CON(4),
+		     RK2928_MODE_CON, 4, 10, 0, NULL),
+	[gpll] = PLL(pll_rk3036, PLL_GPLL, "gpll", mux_pll_p, 0, RK2928_PLL_CON(12),
+		     RK2928_MODE_CON, 12, 10, ROCKCHIP_PLL_SYNC_RATE, rk3036_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 rk3036_clk_branches[] __initdata = {
+	/*
+	 * Clock-Architecture Diagram 1
+	 */
+
+	/* PD_CORE */
+	GATE(0, "gpll_armclk", "gpll", CLK_IGNORE_UNUSED,
+			RK2928_CLKGATE_CON(0), 6, GFLAGS),
+
+	/* PD_DDR */
+	GATE(0, "dpll_ddr", "dpll", CLK_IGNORE_UNUSED,
+			RK2928_CLKGATE_CON(0), 2, GFLAGS),
+	GATE(0, "gpll_ddr", "gpll", 0,
+			RK2928_CLKGATE_CON(0), 8, GFLAGS),
+	COMPOSITE_NOGATE(0, "ddrphy2x", mux_ddrphy_p, CLK_IGNORE_UNUSED,
+			RK2928_CLKSEL_CON(26), 8, 1, MFLAGS, 0, 2,
+					DFLAGS | CLK_DIVIDER_POWER_OF_TWO),
+
+	/* PD_CORE */
+	COMPOSITE_NOMUX(0, "pclk_dbg", "armclk", CLK_IGNORE_UNUSED,
+			RK2928_CLKSEL_CON(1), 0, 4, DFLAGS | CLK_DIVIDER_READ_ONLY,
+			RK2928_CLKGATE_CON(0), 7, GFLAGS),
+	COMPOSITE_NOMUX(0, "aclk_core_pre", "armclk", 0,
+			RK2928_CLKSEL_CON(1), 4, 3, DFLAGS | CLK_DIVIDER_READ_ONLY,
+			RK2928_CLKGATE_CON(0), 7, GFLAGS),
+
+	/* PD_CPU (BUS) */
+	GATE(0, "dpll_cpu", "dpll", 0, RK2928_CLKGATE_CON(10), 8, GFLAGS),
+	GATE(0, "gpll_cpu", "gpll", 0, RK2928_CLKGATE_CON(0), 1, GFLAGS),
+	COMPOSITE_NOGATE(0, "aclk_cpu_src", mux_busclk_p, 0,
+			RK2928_CLKSEL_CON(0), 14, 2, MFLAGS, 8, 5, DFLAGS),
+	GATE(ACLK_CPU, "aclk_cpu", "aclk_cpu_src", 0, RK2928_CLKGATE_CON(0), 3, GFLAGS),
+	COMPOSITE_NOMUX(PCLK_CPU, "pclk_cpu", "aclk_cpu_src", 0,
+			RK2928_CLKSEL_CON(1), 12, 3, DFLAGS | CLK_DIVIDER_READ_ONLY,
+			RK2928_CLKGATE_CON(0), 5, GFLAGS),
+	COMPOSITE_NOMUX(HCLK_CPU, "hclk_cpu", "aclk_cpu_src", 0,
+			RK2928_CLKSEL_CON(1), 8, 2, DFLAGS | CLK_DIVIDER_READ_ONLY,
+			RK2928_CLKGATE_CON(0), 4, GFLAGS),
+
+	/* PD_PERI */
+	COMPOSITE(0, "aclk_peri_src", mux_pll_src_3plls_p, 0,
+			RK2928_CLKSEL_CON(10), 14, 2, MFLAGS, 0, 5, DFLAGS,
+			RK2928_CLKGATE_CON(2), 0, GFLAGS),
+
+	GATE(ACLK_PERI, "aclk_peri", "aclk_peri_src", 0,
+			RK2928_CLKGATE_CON(2), 1, GFLAGS),
+	/* pclk_peri_src is soure for timers */
+	DIV(0, "pclk_peri_src", "aclk_peri_src", CLK_IGNORE_UNUSED,
+			RK2928_CLKSEL_CON(10), 12, 2, DFLAGS | CLK_DIVIDER_POWER_OF_TWO),
+	GATE(PCLK_PERI, "pclk_peri", "pclk_peri_src", 0,
+			RK2928_CLKGATE_CON(2), 3, GFLAGS),
+	/* hclk_peri_src is soure for sclk_macref_out */
+	DIV(0, "hclk_peri_src", "aclk_peri_src", CLK_IGNORE_UNUSED,
+			RK2928_CLKSEL_CON(10), 8, 2, DFLAGS | CLK_DIVIDER_POWER_OF_TWO),
+	GATE(HCLK_PERI, "hclk_peri", "hclk_peri_src", 0,
+			RK2928_CLKGATE_CON(2), 2, GFLAGS),
+
+	/* PD_TIMER */
+	COMPOSITE_NODIV(SCLK_TIMER0, "sclk_timer0", mux_timer_p, 0,
+			RK2928_CLKSEL_CON(2), 4, 1, DFLAGS,
+			RK2928_CLKGATE_CON(1), 0, GFLAGS),
+	COMPOSITE_NODIV(SCLK_TIMER1, "sclk_timer1", mux_timer_p, 0,
+			RK2928_CLKSEL_CON(2), 5, 1, DFLAGS,
+			RK2928_CLKGATE_CON(1), 1, GFLAGS),
+	COMPOSITE_NODIV(SCLK_TIMER2, "sclk_timer2", mux_timer_p, 0,
+			RK2928_CLKSEL_CON(2), 6, 1, DFLAGS,
+			RK2928_CLKGATE_CON(2), 4, GFLAGS),
+	COMPOSITE_NODIV(SCLK_TIMER3, "sclk_timer3", mux_timer_p, 0,
+			RK2928_CLKSEL_CON(2), 7, 1, DFLAGS,
+			RK2928_CLKGATE_CON(2), 5, GFLAGS),
+
+	/* PD_UART */
+	MUX(0, "uart_pll_clk", mux_pll_src_apll_gpll_dpll_usb480m_p, 0,
+			RK2928_CLKSEL_CON(13), 10, 2, MFLAGS),
+	COMPOSITE_NOMUX(0, "uart0_src", "uart_pll_clk", 0,
+			RK2928_CLKSEL_CON(13), 0, 7, DFLAGS,
+			RK2928_CLKGATE_CON(1), 8, GFLAGS),
+	COMPOSITE_NOMUX(0, "uart1_src", "uart_pll_clk", 0,
+			RK2928_CLKSEL_CON(13), 0, 7, DFLAGS,
+			RK2928_CLKGATE_CON(1), 8, GFLAGS),
+	COMPOSITE_NOMUX(0, "uart2_src", "uart_pll_clk", 0,
+			RK2928_CLKSEL_CON(13), 0, 7, DFLAGS,
+			RK2928_CLKGATE_CON(1), 8, GFLAGS),
+	COMPOSITE_FRAC(0, "uart0_frac", "uart0_src", CLK_SET_RATE_PARENT,
+			RK2928_CLKSEL_CON(17), 0,
+			RK2928_CLKGATE_CON(1), 9, GFLAGS),
+	COMPOSITE_FRAC(0, "uart1_frac", "uart1_src", CLK_SET_RATE_PARENT,
+			RK2928_CLKSEL_CON(18), 0,
+			RK2928_CLKGATE_CON(1), 11, GFLAGS),
+	COMPOSITE_FRAC(0, "uart2_frac", "uart2_src", CLK_SET_RATE_PARENT,
+			RK2928_CLKSEL_CON(19), 0,
+			RK2928_CLKGATE_CON(1), 13, GFLAGS),
+	MUX(SCLK_UART0, "sclk_uart0", mux_uart0_p, CLK_SET_RATE_PARENT,
+			RK2928_CLKSEL_CON(13), 8, 2, MFLAGS),
+	MUX(SCLK_UART1, "sclk_uart1", mux_uart1_p, CLK_SET_RATE_PARENT,
+			RK2928_CLKSEL_CON(14), 8, 2, MFLAGS),
+	MUX(SCLK_UART2, "sclk_uart2", mux_uart2_p, CLK_SET_RATE_PARENT,
+			RK2928_CLKSEL_CON(15), 8, 2, MFLAGS),
+
+	/* PD_VIDEO */
+	COMPOSITE(0, "aclk_vcodec", mux_pll_src_3plls_p, 0,
+			RK2928_CLKSEL_CON(32), 14, 2, MFLAGS, 8, 5, DFLAGS,
+			RK2928_CLKGATE_CON(3), 11, GFLAGS),
+
+	COMPOSITE(0, "aclk_hvec", mux_pll_src_3plls_p, 0,
+			RK2928_CLKSEL_CON(20), 0, 2, MFLAGS, 2, 5, DFLAGS,
+			RK2928_CLKGATE_CON(10), 6, GFLAGS),
+
+	/* PD_VIO */
+	COMPOSITE(0, "aclk_disp1_pre", mux_pll_src_3plls_p, 0,
+			RK2928_CLKSEL_CON(31), 14, 2, MFLAGS, 8, 5, DFLAGS,
+			RK2928_CLKGATE_CON(1), 4, GFLAGS),
+	COMPOSITE(0, "hclk_disp_pre", mux_pll_src_3plls_p, 0,
+			RK2928_CLKSEL_CON(30), 14, 2, MFLAGS, 8, 5, DFLAGS,
+			RK2928_CLKGATE_CON(0), 11, GFLAGS),
+	COMPOSITE(DCLK_LCDC, "dclk_lcdc", mux_pll_src_3plls_p, 0,
+			RK2928_CLKSEL_CON(28), 0, 2, MFLAGS, 8, 8, DFLAGS,
+			RK2928_CLKGATE_CON(3), 2, GFLAGS),
+
+	/* MMC */
+	COMPOSITE_NODIV(0, "sclk_sdmmc_src", mux_mmc_src_p, 0,
+			RK2928_CLKSEL_CON(12), 8, 2, DFLAGS,
+			RK2928_CLKGATE_CON(2), 11, GFLAGS),
+	DIV(SCLK_SDMMC, "sclk_sdmmc", "sclk_sdmmc_src", 0,
+			RK2928_CLKSEL_CON(11), 0, 7, DFLAGS),
+
+	COMPOSITE_NODIV(0, "sclk_sdio_src", mux_mmc_src_p, 0,
+			RK2928_CLKSEL_CON(12), 10, 2, DFLAGS,
+			RK2928_CLKGATE_CON(2), 13, GFLAGS),
+	DIV(SCLK_SDIO, "sclk_sdio", "sclk_sdio_src", 0,
+			RK2928_CLKSEL_CON(11), 8, 7, DFLAGS),
+
+	COMPOSITE(SCLK_EMMC, "sclk_emmc", mux_mmc_src_p, 0,
+			RK2928_CLKSEL_CON(12), 12, 2, MFLAGS, 0, 7, DFLAGS,
+			RK2928_CLKGATE_CON(2), 14, GFLAGS),
+
+	MMC(SCLK_SDMMC_DRV,    "sdmmc_drv",    "sclk_sdmmc", RK3036_SDMMC_CON0, 1),
+	MMC(SCLK_SDMMC_SAMPLE, "sdmmc_sample", "sclk_sdmmc", RK3036_SDMMC_CON1, 0),
+
+	MMC(SCLK_SDIO_DRV,    "sdio_drv",    "sclk_sdio", RK3036_SDIO_CON0, 1),
+	MMC(SCLK_SDIO_SAMPLE, "sdio_sample", "sclk_sdio", RK3036_SDIO_CON1, 0),
+
+	MMC(SCLK_EMMC_DRV,     "emmc_drv",     "sclk_emmc",  RK3036_EMMC_CON0,  1),
+	MMC(SCLK_EMMC_SAMPLE,  "emmc_sample",  "sclk_emmc",  RK3036_EMMC_CON1,  0),
+
+	/* I2S */
+	COMPOSITE(0, "i2s_src", mux_pll_src_3plls_p, 0,
+			RK2928_CLKSEL_CON(3), 14, 1, MFLAGS, 0, 7, DFLAGS,
+			RK2928_CLKGATE_CON(0), 9, GFLAGS),
+	COMPOSITE_FRAC(0, "i2s_frac", "i2s_src", CLK_SET_RATE_PARENT,
+			RK2928_CLKSEL_CON(7), 0,
+			RK2928_CLKGATE_CON(0), 10, GFLAGS),
+	MUX(0, "i2s_pre", mux_i2s_pre_p, CLK_SET_RATE_PARENT,
+			RK2928_CLKSEL_CON(3), 8, 2, MFLAGS),
+	COMPOSITE_NODIV(SCLK_I2S_OUT, "i2s_clkout", mux_i2s_clkout_p, 0,
+			RK2928_CLKSEL_CON(4), 12, 1, MFLAGS,
+			RK2928_CLKGATE_CON(0), 13, GFLAGS),
+	GATE(SCLK_I2S, "sclk_i2s", "i2s_pre", CLK_SET_RATE_PARENT,
+			RK2928_CLKGATE_CON(0), 14, GFLAGS),
+
+	COMPOSITE(0, "spdif_src", mux_pll_src_3plls_p, 0,
+			RK2928_CLKSEL_CON(5), 10, 2, MFLAGS, 0, 7, DFLAGS,
+			RK2928_CLKGATE_CON(2), 10, GFLAGS),
+	COMPOSITE_FRAC(0, "spdif_frac", "spdif_src", 0,
+			RK2928_CLKSEL_CON(9), 0,
+			RK2928_CLKGATE_CON(2), 12, GFLAGS),
+	MUX(SCLK_SPDIF, "sclk_spdif", mux_spdif_p, 0,
+			RK2928_CLKSEL_CON(5), 8, 2, MFLAGS),
+	/* USB */
+	GATE(0, "hsicphy12m_xin12m", "xin12m", 0,
+			RK2928_CLKGATE_CON(1), 5, GFLAGS),
+
+	/* GPU */
+	COMPOSITE(SCLK_GPU, "sclk_gpu", mux_pll_src_3plls_p, 0,
+			RK2928_CLKSEL_CON(34), 8, 2, MFLAGS, 0, 5, DFLAGS,
+			RK2928_CLKGATE_CON(3), 13, GFLAGS),
+
+	/* SPI */
+	COMPOSITE(SCLK_SPI, "sclk_spi", mux_pll_src_3plls_p, 0,
+			RK2928_CLKSEL_CON(25), 8, 2, MFLAGS, 0, 7, DFLAGS,
+			RK2928_CLKGATE_CON(2), 9, GFLAGS),
+
+	/* NANDC */
+	COMPOSITE(SCLK_NANDC, "sclk_nandc", mux_pll_src_3plls_p, 0,
+			RK2928_CLKSEL_CON(16), 8, 2, MFLAGS, 10, 5, DFLAGS,
+			RK2928_CLKGATE_CON(10), 4, GFLAGS),
+
+	/* SFC */
+	COMPOSITE(SCLK_SFC, "sclk_sfc", mux_pll_src_apll_gpll_dpll_usb480m_p, 0,
+			RK2928_CLKSEL_CON(16), 0, 2, MFLAGS, 2, 5, DFLAGS,
+			RK2928_CLKGATE_CON(10), 5, GFLAGS),
+
+	/* MAC */
+	COMPOSITE_NOGATE(0, "mac_pll_src", mux_pll_src_3plls_p, 0,
+			RK2928_CLKSEL_CON(21), 0, 2, MFLAGS, 4, 5, DFLAGS),
+	/* for clk_mac_ref & clk_mac_refout */
+	MUX(SCLK_MACREF, "mac_clk_ref", mux_mac_p, CLK_SET_RATE_PARENT,
+			RK2928_CLKSEL_CON(21), 3, 1, MFLAGS),
+
+	COMPOSITE_NOMUX(SCLK_MAC, "mac_clk", "mac_clk_ref", 0,
+			RK2928_CLKSEL_CON(21), 9, 5, DFLAGS,
+			RK2928_CLKGATE_CON(2), 6, GFLAGS),
+
+	/* HDMI */
+	/* total clks: pin_sys_clk / pin_sck / pin_mclk / pin_vclk / pin_vclk_pllref */
+	/* the same with dclk_lcdc */
+	COMPOSITE(0, "dclk_hdmi_src", mux_pll_src_3plls_p, 0,
+			RK2928_CLKSEL_CON(28), 0, 2, MFLAGS, 8, 8, DFLAGS,
+			RK2928_CLKGATE_CON(3), 2, GFLAGS),
+	/* hdmi dclk from dclk_lcdc directly */
+	MUX(SCLK_HDMI, "dclk_hdmi", mux_dclk_p, 0,
+			RK2928_CLKSEL_CON(31), 0, 1, MFLAGS),
+
+	/*
+	 * Clock-Architecture Diagram 2
+	 */
+
+	/* aclk_cpu gates */
+	GATE(0, "sclk_intmem", "aclk_cpu", CLK_IGNORE_UNUSED, RK2928_CLKGATE_CON(4), 12, GFLAGS),
+	GATE(0, "aclk_strc_sys", "aclk_cpu", CLK_IGNORE_UNUSED, RK2928_CLKGATE_CON(4), 10, GFLAGS),
+
+	/* hclk_cpu gates */
+	GATE(HCLK_ROM, "hclk_rom", "hclk_cpu", CLK_IGNORE_UNUSED, RK2928_CLKGATE_CON(5), 6, GFLAGS),
+
+	/* pclk_cpu gates */
+	GATE(PCLK_GRF, "pclk_grf", "pclk_cpu", 0, RK2928_CLKGATE_CON(5), 4, GFLAGS),
+	GATE(PCLK_DDRUPCTL, "pclk_ddrupctl", "pclk_cpu", 0, RK2928_CLKGATE_CON(5), 7, GFLAGS),
+	GATE(ACLK_VCODEC, "pclk_acodec", "pclk_cpu", 0, RK2928_CLKGATE_CON(5), 14, GFLAGS),
+	GATE(PCLK_HDMI, "pclk_hdmi", "pclk_cpu", 0, RK2928_CLKGATE_CON(3), 8, GFLAGS),
+
+	/* aclk_vio gates */
+	GATE(ACLK_VIO, "aclk_vio", "aclk_disp1_pre", 0,
+			RK2928_CLKGATE_CON(6), 13, GFLAGS),
+	GATE(ACLK_LCDC, "aclk_lcdc", "aclk_disp1_pre", 0,
+			RK2928_CLKGATE_CON(9), 6, GFLAGS),
+
+	GATE(HCLK_VIO_BUS, "hclk_vio_bus", "hclk_disp_pre", 0,
+			RK2928_CLKGATE_CON(6), 12, GFLAGS),
+	GATE(HCLK_LCDC, "hclk_lcdc", "hclk_disp_pre", 0,
+			RK2928_CLKGATE_CON(9), 5, GFLAGS),
+
+	/* aclk_video gates */
+	GATE(HCLK_LCDC, "hclk_vcodec", "hclk_disp_pre", 0,
+			RK2928_CLKGATE_CON(3), 12, GFLAGS),
+
+	/* xin24m gates */
+	GATE(SCLK_PVTM_CORE, "sclk_pvtm_core", "xin24m", 0, RK2928_CLKGATE_CON(10), 0, GFLAGS),
+	GATE(SCLK_PVTM_GPU, "sclk_pvtm_gpu", "xin24m", 0, RK2928_CLKGATE_CON(10), 1, GFLAGS),
+
+	/* aclk_peri gates */
+	GATE(0, "aclk_peri_axi_matrix", "aclk_peri", CLK_IGNORE_UNUSED, RK2928_CLKGATE_CON(4), 3, GFLAGS),
+	GATE(0, "aclk_cpu_peri", "aclk_peri", CLK_IGNORE_UNUSED, RK2928_CLKGATE_CON(4), 2, GFLAGS),
+	GATE(ACLK_DMAC2, "aclk_dmac2", "aclk_peri", 0, RK2928_CLKGATE_CON(5), 1, GFLAGS),
+	GATE(0, "aclk_peri_niu", "aclk_peri", CLK_IGNORE_UNUSED, RK2928_CLKGATE_CON(9), 15, GFLAGS),
+
+	/* hclk_peri gates */
+	GATE(0, "hclk_peri_matrix", "hclk_peri", CLK_IGNORE_UNUSED, RK2928_CLKGATE_CON(4), 0, GFLAGS),
+	GATE(0, "hclk_usb_peri", "hclk_peri", CLK_IGNORE_UNUSED, RK2928_CLKGATE_CON(9), 13, GFLAGS),
+	GATE(0, "hclk_peri_arbi", "hclk_peri", CLK_IGNORE_UNUSED, RK2928_CLKGATE_CON(9), 14, GFLAGS),
+	GATE(HCLK_NANDC, "hclk_nandc", "hclk_peri", 0, RK2928_CLKGATE_CON(5), 9, GFLAGS),
+	GATE(HCLK_SDMMC, "hclk_sdmmc", "hclk_peri", 0, RK2928_CLKGATE_CON(5), 10, GFLAGS),
+	GATE(HCLK_SDIO, "hclk_sdio", "hclk_peri", 0, RK2928_CLKGATE_CON(5), 11, GFLAGS),
+	GATE(HCLK_EMMC, "hclk_emmc", "hclk_peri", 0, RK2928_CLKGATE_CON(7), 0, GFLAGS),
+	GATE(HCLK_OTG0, "hclk_otg0", "hclk_peri", CLK_IGNORE_UNUSED, RK2928_CLKGATE_CON(5), 13, GFLAGS),
+	GATE(HCLK_OTG1, "hclk_otg1", "hclk_peri", CLK_IGNORE_UNUSED, RK2928_CLKGATE_CON(7), 13, GFLAGS),
+	GATE(HCLK_I2S, "hclk_i2s", "hclk_peri", CLK_IGNORE_UNUSED, RK2928_CLKGATE_CON(7), 2, GFLAGS),
+	GATE(0, "hclk_sfc", "hclk_peri", CLK_IGNORE_UNUSED, RK2928_CLKGATE_CON(3), 14, GFLAGS),
+	GATE(0, "hclk_mac", "hclk_peri", CLK_IGNORE_UNUSED, RK2928_CLKGATE_CON(3), 15, GFLAGS),
+
+	/* pclk_peri gates */
+	GATE(0, "pclk_peri_matrix", "pclk_peri", CLK_IGNORE_UNUSED, RK2928_CLKGATE_CON(4), 1, GFLAGS),
+	GATE(0, "pclk_efuse", "pclk_peri", CLK_IGNORE_UNUSED, RK2928_CLKGATE_CON(5), 2, GFLAGS),
+	GATE(PCLK_TIMER, "pclk_timer0", "pclk_peri", 0, RK2928_CLKGATE_CON(7), 7, GFLAGS),
+	GATE(PCLK_PWM, "pclk_pwm", "pclk_peri", 0, RK2928_CLKGATE_CON(7), 10, GFLAGS),
+	GATE(PCLK_SPI, "pclk_spi", "pclk_peri", 0, RK2928_CLKGATE_CON(7), 12, GFLAGS),
+	GATE(PCLK_WDT, "pclk_wdt", "pclk_peri", 0, RK2928_CLKGATE_CON(7), 15, GFLAGS),
+	GATE(PCLK_UART0, "pclk_uart0", "pclk_peri", 0, RK2928_CLKGATE_CON(8), 0, GFLAGS),
+	GATE(PCLK_UART1, "pclk_uart1", "pclk_peri", 0, RK2928_CLKGATE_CON(8), 1, GFLAGS),
+	GATE(PCLK_UART2, "pclk_uart2", "pclk_peri", 0, RK2928_CLKGATE_CON(8), 2, GFLAGS),
+	GATE(PCLK_I2C0, "pclk_i2c0", "pclk_peri", 0, RK2928_CLKGATE_CON(8), 4, GFLAGS),
+	GATE(PCLK_I2C1, "pclk_i2c1", "pclk_peri", 0, RK2928_CLKGATE_CON(8), 5, GFLAGS),
+	GATE(PCLK_I2C2, "pclk_i2c2", "pclk_peri", 0, RK2928_CLKGATE_CON(8), 6, GFLAGS),
+	GATE(PCLK_GPIO0, "pclk_gpio0", "pclk_peri", 0, RK2928_CLKGATE_CON(8), 9, GFLAGS),
+	GATE(PCLK_GPIO1, "pclk_gpio1", "pclk_peri", 0, RK2928_CLKGATE_CON(8), 10, GFLAGS),
+	GATE(PCLK_GPIO2, "pclk_gpio2", "pclk_peri", 0, RK2928_CLKGATE_CON(8), 11, GFLAGS),
+};
+
+static const char *const rk3036_critical_clocks[] __initconst = {
+	"aclk_cpu",
+	"aclk_peri",
+	"hclk_peri",
+};
+
+#ifdef CONFIG_PM_SLEEP
+static void __iomem *rk3036_cru_base;
+
+/* Some CRU registers will be reset in maskrom when the system
+ * wakes up from fastboot.
+ * So save them before suspend, restore them after resume.
+ */
+
+static int rk3036_clk_suspend(void)
+{
+	/* TODO */
+
+	return 0;
+}
+
+static void rk3036_clk_resume(void)
+{
+	/* TODO */
+}
+
+static struct syscore_ops rk3036_clk_syscore_ops = {
+	.suspend = rk3036_clk_suspend,
+	.resume = rk3036_clk_resume,
+};
+
+static void rk3036_clk_sleep_init(void __iomem *reg_base)
+{
+	rk3036_cru_base = reg_base;
+	register_syscore_ops(&rk3036_clk_syscore_ops);
+}
+
+#else /* CONFIG_PM_SLEEP */
+static void rk3036_clk_sleep_init(void __iomem *reg_base) {}
+#endif
+
+static void __init rk3036_clk_init(struct device_node *np)
+{
+	void __iomem *reg_base;
+	struct clk *clk;
+
+	reg_base = of_iomap(np, 0);
+	if (!reg_base) {
+		pr_err("%s: could not map cru region\n", __func__);
+		return;
+	}
+
+	rockchip_clk_init(np, reg_base, CLK_NR_CLKS);
+
+	/* xin12m is created by an cru-internal divider */
+	clk = clk_register_fixed_factor(NULL, "xin12m", "xin24m", 0, 1, 2);
+	if (IS_ERR(clk))
+		pr_warn("%s: could not register clock xin12m: %ld\n",
+			__func__, PTR_ERR(clk));
+
+	clk = clk_register_fixed_factor(NULL, "usb480m", "xin24m", 0, 20, 1);
+	if (IS_ERR(clk))
+		pr_warn("%s: could not register clock usb480m: %ld\n",
+			__func__, PTR_ERR(clk));
+
+	clk = clk_register_fixed_factor(NULL, "ddrphy", "ddrphy2x", 0, 1, 2);
+	if (IS_ERR(clk))
+		pr_warn("%s: could not register clock ddrphy: %ld\n",
+			__func__, PTR_ERR(clk));
+
+	clk = clk_register_fixed_factor(NULL, "hclk_vcodec_pre",
+					"aclk_vcodec", 0, 1, 4);
+	if (IS_ERR(clk))
+		pr_warn("%s: could not register clock hclk_vcodec_pre: %ld\n",
+			__func__, PTR_ERR(clk));
+
+	clk = clk_register_fixed_factor(NULL, "sclk_macref_out",
+					"hclk_peri_src", 0, 1, 2);
+	if (IS_ERR(clk))
+		pr_warn("%s: could not register clock sclk_macref_out: %ld\n",
+			__func__, PTR_ERR(clk));
+
+	rockchip_clk_register_plls(rk3036_pll_clks,
+				   ARRAY_SIZE(rk3036_pll_clks),
+				   -1);
+	rockchip_clk_register_branches(rk3036_clk_branches,
+				  ARRAY_SIZE(rk3036_clk_branches));
+	rockchip_clk_protect_critical(rk3036_critical_clocks,
+				      ARRAY_SIZE(rk3036_critical_clocks));
+
+	rockchip_clk_register_armclk(ARMCLK, "armclk",
+			mux_armclk_p, ARRAY_SIZE(mux_armclk_p),
+			&rk3036_cpuclk_data, rk3036_cpuclk_rates,
+			ARRAY_SIZE(rk3036_cpuclk_rates));
+
+	rockchip_register_softrst(np, 9, reg_base + RK2928_SOFTRST_CON(0),
+				  ROCKCHIP_SOFTRST_HIWORD_MASK);
+
+	rockchip_register_restart_notifier(RK2928_GLB_SRST_FST);
+	rk3036_clk_sleep_init(reg_base);
+}
+CLK_OF_DECLARE(rk3036_cru, "rockchip,rk3036-cru", rk3036_clk_init);
diff --git a/drivers/clk/rockchip/clk.h b/drivers/clk/rockchip/clk.h
index dc8ecb2..6603c07 100644
--- a/drivers/clk/rockchip/clk.h
+++ b/drivers/clk/rockchip/clk.h
@@ -2,6 +2,9 @@
  * Copyright (c) 2014 MundoReader S.L.
  * Author: Heiko Stuebner <heiko at sntech.de>
  *
+ * Copyright (c) 2015 Rockchip Electronics Co. Ltd.
+ * Author: Xing Zheng <zhengxing at rock-chips.com>
+ *
  * based on
  *
  * samsung/clk.h
@@ -40,6 +43,13 @@ struct clk;
 #define RK2928_SOFTRST_CON(x)	((x) * 0x4 + 0x110)
 #define RK2928_MISC_CON		0x134
 
+#define RK3036_SDMMC_CON0		0x144
+#define RK3036_SDMMC_CON1		0x148
+#define RK3036_SDIO_CON0		0x14c
+#define RK3036_SDIO_CON1		0x150
+#define RK3036_EMMC_CON0		0x154
+#define RK3036_EMMC_CON1		0x158
+
 #define RK3288_PLL_CON(x)		RK2928_PLL_CON(x)
 #define RK3288_MODE_CON			0x50
 #define RK3288_CLKSEL_CON(x)		((x) * 0x4 + 0x60)
@@ -75,6 +85,7 @@ struct clk;
 
 enum rockchip_pll_type {
 	pll_rk3066,
+	pll_rk3036,
 };
 
 #define RK3066_PLL_RATE(_rate, _nr, _nf, _no)	\
@@ -95,12 +106,31 @@ enum rockchip_pll_type {
 	.nb = _nb,						\
 }
 
+#define RK3036_PLL_RATE(_rate, _refdiv, _fbdiv, _postdiv1,	\
+			_postdiv2, _dsmpd, _frac)		\
+{								\
+	.rate	= _rate##U,					\
+	.fbdiv = _fbdiv,					\
+	.postdiv1 = _postdiv1,					\
+	.refdiv = _refdiv,					\
+	.postdiv2 = _postdiv2,					\
+	.dsmpd = _dsmpd,					\
+	.frac = _frac,						\
+}
+
 struct rockchip_pll_rate_table {
 	unsigned long rate;
 	unsigned int nr;
 	unsigned int nf;
 	unsigned int no;
 	unsigned int nb;
+	/* for RK3036 */
+	unsigned int fbdiv;
+	unsigned int postdiv1;
+	unsigned int refdiv;
+	unsigned int postdiv2;
+	unsigned int dsmpd;
+	unsigned int frac;
 };
 
 /**
diff --git a/include/dt-bindings/clock/rk3036-cru.h b/include/dt-bindings/clock/rk3036-cru.h
new file mode 100644
index 0000000..085e4c3
--- /dev/null
+++ b/include/dt-bindings/clock/rk3036-cru.h
@@ -0,0 +1,247 @@
+/*
+ * Copyright (c) 2014 MundoReader S.L.
+ * Author: Heiko Stuebner <heiko at sntech.de>
+ *
+ * Copyright (c) 2015 Rockchip Electronics Co. Ltd.
+ * Author: Xing Zheng <zhengxing at 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.
+ */
+
+/* core clocks */
+#define PLL_APLL		1
+#define PLL_DPLL		2
+#define PLL_GPLL		3
+#define ARMCLK			4
+
+/* sclk gates (special clocks) */
+#define SCLK_GPU		64
+#define SCLK_SPI		65
+#define SCLK_SDMMC		68
+#define SCLK_SDIO		69
+#define SCLK_EMMC		71
+#define SCLK_NANDC		76
+#define SCLK_UART0		77
+#define SCLK_UART1		78
+#define SCLK_UART2		79
+#define SCLK_I2S		82
+#define SCLK_SPDIF		83
+#define SCLK_TIMER0		85
+#define SCLK_TIMER1		86
+#define SCLK_TIMER2		87
+#define SCLK_TIMER3		88
+#define SCLK_OTGPHY0		93
+#define SCLK_OTGPHY1		94
+#define SCLK_LCDC		100
+#define SCLK_HDMI		109
+#define SCLK_HEVC		111
+#define SCLK_I2S_OUT		113
+#define SCLK_SDMMC_DRV		114
+#define SCLK_SDIO_DRV		115
+#define SCLK_EMMC_DRV		117
+#define SCLK_SDMMC_SAMPLE	118
+#define SCLK_SDIO_SAMPLE	119
+#define SCLK_EMMC_SAMPLE	121
+#define SCLK_PVTM_CORE          123
+#define SCLK_PVTM_GPU           124
+#define SCLK_PVTM_VIDEO         125
+#define SCLK_MAC		151
+#define SCLK_MACREF		152
+#define SCLK_SFC		160
+
+#define DCLK_LCDC		190
+
+/* aclk gates */
+#define ACLK_DMAC2		194
+#define ACLK_LCDC		197
+#define ACLK_VIO		203
+#define ACLK_VCODEC		208
+#define ACLK_CPU		209
+#define ACLK_PERI		210
+
+/* pclk gates */
+#define PCLK_GPIO0		320
+#define PCLK_GPIO1		321
+#define PCLK_GPIO2		322
+#define PCLK_GRF		329
+#define PCLK_I2C0		332
+#define PCLK_I2C1		333
+#define PCLK_I2C2		334
+#define PCLK_SPI		338
+#define PCLK_UART0		341
+#define PCLK_UART1		342
+#define PCLK_UART2		343
+#define PCLK_PWM		350
+#define PCLK_TIMER		353
+#define PCLK_HDMI		360
+#define PCLK_CPU		362
+#define PCLK_PERI		363
+#define PCLK_DDRUPCTL		364
+#define PCLK_WDT		368
+
+/* hclk gates */
+#define HCLK_OTG0		449
+#define HCLK_OTG1		450
+#define HCLK_NANDC		453
+#define HCLK_SDMMC		456
+#define HCLK_SDIO		457
+#define HCLK_EMMC		459
+#define HCLK_I2S		462
+#define HCLK_LCDC		465
+#define HCLK_ROM		467
+#define HCLK_VIO_BUS		472
+#define HCLK_VCODEC		476
+#define HCLK_CPU		477
+#define HCLK_PERI		478
+
+#define CLK_NR_CLKS		(HCLK_PERI + 1)
+
+/* soft-reset indices */
+#define SRST_CORE0		0
+#define SRST_CORE1		1
+#define SRST_0RES2		2
+#define SRST_0RES3		3
+#define SRST_CORE0_DBG		4
+#define SRST_CORE1_DBG		5
+#define SRST_0RES6		6
+#define SRST_0RES7		7
+#define SRST_CORE0_POR		8
+#define SRST_CORE1_POR		9
+#define SRST_0RES10		10
+#define SRST_0RES11		11
+#define SRST_L2C		12
+#define SRST_TOPDBG		13
+#define SRST_STRC_SYS_A		14
+#define SRST_PD_CORE_NIU	15
+
+#define SRST_TIMER2		16
+#define SRST_CPUSYS_H		17
+#define SRST_1RES2		18
+#define SRST_AHB2APB_H		19
+#define SRST_TIMER3		20
+#define SRST_INTMEM		21
+#define SRST_ROM		22
+#define SRST_PERI_NIU		23
+#define SRST_I2S		24
+#define SRST_DDR_PLL		25
+#define SRST_GPU_DLL		26
+#define SRST_TIMER0		27
+#define SRST_TIMER1		28
+#define SRST_CORE_DLL		29
+#define SRST_EFUSE_P		30
+#define SRST_ACODEC_P		31
+
+#define SRST_GPIO0		32
+#define SRST_GPIO1		33
+#define SRST_GPIO2		34
+#define SRST_2RES3		35
+#define SRST_2RES4		36
+#define SRST_2RES5		37
+#define SRST_2RES6		38
+#define SRST_UART0		39
+#define SRST_UART1		40
+#define SRST_UART2		41
+#define SRST_2RES10		42
+#define SRST_I2C0		43
+#define SRST_I2C1		44
+#define SRST_I2C2		45
+#define SRST_2RES14		46
+#define SRST_SFC		47
+
+#define SRST_PWM0		48
+#define SRST_3RES1		49
+#define SRST_3RES2		50
+#define SRST_DAP		51
+#define SRST_DAP_SYS		52
+#define SRST_3RES5		53
+#define SRST_3RES6		54
+#define SRST_GRF		55
+#define SRST_3RES8		56
+#define SRST_PERIPHSYS_A	57
+#define SRST_PERIPHSYS_H	58
+#define SRST_PERIPHSYS_P	59
+#define SRST_3RES12		60
+#define SRST_CPU_PERI		61
+#define SRST_EMEM_PERI		62
+#define SRST_USB_PERI		63
+
+#define SRST_DMA2		64
+#define SRST_4RES1		65
+#define SRST_MAC		66
+#define SRST_4RES3		67
+#define SRST_NANDC		68
+#define SRST_USBOTG0		69
+#define SRST_4RES6		70
+#define SRST_OTGC0		71
+#define SRST_USBOTG1		72
+#define SRST_4RES9		73
+#define SRST_OTGC1		74
+#define SRST_4RES11		75
+#define SRST_4RES12		76
+#define SRST_4RES13		77
+#define SRST_4RES14		78
+#define SRST_DDRMSCH		79
+
+#define SRST_5RES0		80
+#define SRST_MMC0		81
+#define SRST_SDIO		82
+#define SRST_EMMC		83
+#define SRST_SPI0		84
+#define SRST_5RES5		85
+#define SRST_WDT		86
+#define SRST_5RES7		87
+#define SRST_DDRPHY		88
+#define SRST_DDRPHY_P		89
+#define SRST_DDRCTRL		90
+#define SRST_DDRCTRL_P		91
+#define SRST_5RES12		92
+#define SRST_5RES13		93
+#define SRST_5RES14		94
+#define SRST_5RES15		95
+
+#define SRST_HDMI_P		96
+#define SRST_6RES1		97
+#define SRST_6RES2		98
+#define SRST_VIO_BUS_H		99
+#define SRST_6RES4		100
+#define SRST_6RES5		101
+#define SRST_6RES6		102
+#define SRST_UTMI0		103
+#define SRST_UTMI1		104
+#define SRST_USBPOR		105
+#define SRST_6RES10		106
+#define SRST_6RES11		107
+#define SRST_6RES12		108
+#define SRST_6RES13		109
+#define SRST_6RES14		110
+#define SRST_6RES15		111
+
+#define SRST_VCODEC_A		112
+#define SRST_VCODEC_H		113
+#define SRST_VIO1_A		114
+#define SRST_HEVC		115
+#define SRST_VCODEC_NIU_A	116
+#define SRST_LCDC1_A		117
+#define SRST_LCDC1_H		118
+#define SRST_LCDC1_D		119
+#define SRST_GPU		120
+#define SRST_7RES9		121
+#define SRST_GPU_NIU_A		122
+#define SRST_7RES11		123
+#define SRST_7RES12		124
+#define SRST_7RES13		125
+#define SRST_7RES14		126
+#define SRST_7RES15		127
+
+#define SRST_8RES0		128
+#define SRST_8RES1		129
+#define SRST_8RES2		130
+#define SRST_DBG_P		131
-- 
1.7.9.5




From mingo at kernel.org  Thu Aug 27 23:27:45 2015
From: mingo at kernel.org (Ingo Molnar)
Date: Fri, 28 Aug 2015 08:27:45 +0200
Subject: [PATCH 1/4] x86, efi, kasan: #undef memset/memcpy/memmove per
 arch.
In-Reply-To: <1440605707-8325-2-git-send-email-ryabinin.a.a@gmail.com>
References: <1440605707-8325-1-git-send-email-ryabinin.a.a@gmail.com>
 <1440605707-8325-2-git-send-email-ryabinin.a.a@gmail.com>
Message-ID: <20150828062745.GB1928@gmail.com>


* Andrey Ryabinin <ryabinin.a.a at gmail.com> wrote:

> In not-instrumented code KASAN replaces instrumented
> memset/memcpy/memmove with not-instrumented analogues
> __memset/__memcpy/__memove.
> However, on x86 EFI stub is not linked with kernel.

s/with the kernel

> It uses not-instrumented mem*() functions from
> arch/x86/boot/compressed/string.c
> So we don't replace them with __mem*() variants in EFI stub.
> 
> In ARM64 EFI stub is linked with the kernel, so we should

s/In ARM64 EFI stub/On ARM64 the EFI stub/.

> replace mem*() functions with __mem*(), because EFI stub

s/the EFI stub

> runs before KASAN setup early shadow.

s/before KASAN sets up the early shadow

?

> So let's move these #undef mem* into arch's asm/efi.h which is

s/lets

> also included by EFI stub.

s/by the EFI stub

> 
> Signed-off-by: Andrey Ryabinin <ryabinin.a.a at gmail.com>
> ---
>  arch/x86/include/asm/efi.h             | 8 ++++++++
>  drivers/firmware/efi/libstub/efistub.h | 4 ----
>  2 files changed, 8 insertions(+), 4 deletions(-)
> 
> diff --git a/arch/x86/include/asm/efi.h b/arch/x86/include/asm/efi.h
> index 155162e..d821ce2 100644
> --- a/arch/x86/include/asm/efi.h
> +++ b/arch/x86/include/asm/efi.h
> @@ -25,6 +25,14 @@
>  #define EFI32_LOADER_SIGNATURE	"EL32"
>  #define EFI64_LOADER_SIGNATURE	"EL64"
>  
> +/*
> + * Use memcpy/memset from arch/x86/boot/compressed/string.c
> + * for EFI stub.
> + */
> +#undef memcpy
> +#undef memset
> +#undef memmove

This comment should also mention why it's done, not what is done.

Also:

    s/for EFI stub/for the EFI stub

Thanks,

	Ingo


From michal.simek at xilinx.com  Thu Aug 27 23:31:44 2015
From: michal.simek at xilinx.com (Michal Simek)
Date: Fri, 28 Aug 2015 08:31:44 +0200
Subject: [PATCH v9] dmaengine: Add Xilinx AXI Direct Memory Access Engine
 driver support
In-Reply-To: <CAAtXAHccn5UjCg9Qr1Li1c9LfsBXrgF=gpMqJ6stGOaWL0u_-g@mail.gmail.com>
References: <1440432666-10310-1-git-send-email-appanad@xilinx.com>
 <CAAtXAHccn5UjCg9Qr1Li1c9LfsBXrgF=gpMqJ6stGOaWL0u_-g@mail.gmail.com>
Message-ID: <55E00050.2020709@xilinx.com>

Hi Moritz,

On 08/27/2015 04:30 PM, Moritz Fischer wrote:
> Hi Kedar,
> 
> one thing that I realized is that you're not grabbing any clocks, does
> this assume that you boot your system with fclk_enable to make this
> work on Zynq e.g?
> I realize the Xilinx VDMA driver in mainline doesn't have clock
> handling built in neither, but wouldn't having that in new drivers at
> least be desirable?

Handling clock for soft IPs is not trivial problem from generation point
of view. Adding clock handling to driver is simple and if you look all
our soft IP drivers are lacking it.
Users can change clocks freq in IP which needs to be covered too.
And yes currently fclks are enabled by default that's why adding clock
handling to the driver is not needed.

Definitely PL clk handling is a topic which we are aware of but we don't
have any 100% workable solution now. Current expectation is that clock
is just working.

Thanks,
Michal



From leo.yan at linaro.org  Thu Aug 27 23:37:19 2015
From: leo.yan at linaro.org (Leo Yan)
Date: Fri, 28 Aug 2015 14:37:19 +0800
Subject: [PATCH v1 3/3] arm64: dts: add Hi6220 mailbox node
In-Reply-To: <20150827163108.GA31748@leverpostej>
References: <20150824114903.GT10728@bivouac.eciton.net>
 <1440490427.10987.29.camel@linaro.org>
 <20150825094630.GU10728@bivouac.eciton.net>
 <1440497710.10987.42.camel@linaro.org>
 <20150825104256.GB13471@leverpostej>
 <1440510194.10987.52.camel@linaro.org>
 <20150825160030.GA3774@leoy-linaro>
 <1440552341.10987.53.camel@linaro.org>
 <20150826065950.GB19594@leoy-linaro>
 <20150827163108.GA31748@leverpostej>
Message-ID: <20150828063719.GA22886@leoy-linaro>

Hi Mark,

On Thu, Aug 27, 2015 at 05:31:09PM +0100, Mark Rutland wrote:
> On Wed, Aug 26, 2015 at 07:59:50AM +0100, Leo Yan wrote:
> > Hi Haojian,
> > 
> > On Wed, Aug 26, 2015 at 09:25:41AM +0800, Haojian Zhuang wrote:
> > > On Wed, 2015-08-26 at 00:00 +0800, Leo Yan wrote:
> > > > On Tue, Aug 25, 2015 at 09:43:14PM +0800, Haojian Zhuang wrote:
> > > > > On Tue, 2015-08-25 at 11:42 +0100, Mark Rutland wrote:
> > > > > > > > Are you then going to hack GRUB, release a special HiKey version of
> > > > > > > > GRUB, not support any other versions, and still can your firmware
> > > > > > > > UEFI?
> > > > > > > 
> > > > > > > I don't need to hack GRUB at all.
> > > > > > 
> > > > > > Then it is working for you by pure chance alone.
> > > > > > 
> > > > > > Please listen to the advice you are being given here; we're trying to
> > > > > > ensure that your platform functions (and continues to function) as best
> > > > > > it can.
> > > > > 
> > > > > Since we discussed a lot on this, let's make a conclusion on it.
> > > > > 
> > > > > 1. UEFI could append the reserved buffer in it's memory mapping.
> > > > > 2. These reserved buffer must be declared in DT, since we also need to
> > > > >    support non-UEFI (uboot) at the same time.
> > > > > 3. Mailbox node should reference reserved buffer by phandle in DT. Then
> > > > >    map the buffer as non-cacheable in driver.
> > > > > 4. These reserved buffer must use "no-map" property since it should be
> > > > >    non-cacheable in driver.
> > > > 
> > > > For more specific discussion for DTS, i list two options at here;
> > > > 
> > > > - Option 1: just simply reserve memory regions through memory node,
> > > >   and mailbox node will directly use the buffer through reg ranges;
> > > > 
> > > > - Option 2: use reserved-memory and mailbox node will refer phandle
> > > >   of reserved-memory;
> > > > 
> > > > These two options both can work well with UEFI and Uboot, but option 1
> > > > is more simple and straightforward; so i personally prefer it. But
> > > > look forwarding your guys' suggestion.
> > > > 
> > > > Option 1:
> > > > 
> > > > 	memory at 0 {
> > > > 		device_type = "memory";
> > > > 		reg = <0x00000000 0x00000000 0x00000000 0x05e00000>,
> > > > 		      <0x00000000 0x05f00000 0x00000000 0x00eff000>,
> > > > 		      <0x00000000 0x06e00000 0x00000000 0x0060f000>,
> > > > 		      <0x00000000 0x07410000 0x00000000 0x38bf0000>;
> > > > 	};
> > > > 
> > > >         [...]
> > > > 
> > > > 	mailbox: mailbox at f7510000 {
> > > > 		#mbox-cells = <1>;
> > > > 		compatible = "hisilicon,hi6220-mbox";
> > > > 		reg = <0x0 0xf7510000 0x0 0x1000>, /* IPC_S */
> > > > 		      <0x0 0x06dff800 0x0 0x0800>; /* Mailbox buffer */
> > > > 		interrupts = <GIC_SPI 94 IRQ_TYPE_LEVEL_HIGH>;
> > > > 	};
> > > > 
> > > > Option 2:
> > > > 
> > > > 	memory at 0 {
> > > > 		device_type = "memory";
> > > > 		reg = <0x0 0x0 0x0 0x40000000>;
> > > > 	};
> > > > 
> > > > 	reserved-memory {
> > > > 		#address-cells = <2>;
> > > > 		#size-cells = <2>;
> > > > 		ranges;
> > > > 
> > > > 		mcu_reserved: mcu_reserved at 06dff000 {
> > > > 			no-map;
> > > > 			reg = <0x0 0x06dff000 0x0 0x00001000>,	/* MCU mailbox buffer */
> > > > 			      <0x0 0x05e00000 0x0 0x00100000>,	/* MCU firmware buffer */
> > > > 			      <0x0 0x0740f000 0x0 0x00001000>;	/* MCU firmware section */
> > > > 		};
> > > > 	};
> > > > 
> > > >         [...]
> > > > 
> > > > 	mailbox: mailbox at f7510000 {
> > > > 		#mbox-cells = <1>;
> > > > 		compatible = "hisilicon,hi6220-mbox";
> > > > 		reg = <0x0 0xf7510000 0x0 0x1000>; /* IPC_S */
> > > > 		memory-region = <&mcu_reserved>;   /* Mailbox buffer */
> > > > 		interrupts = <GIC_SPI 94 IRQ_TYPE_LEVEL_HIGH>;
> > > > 	};
> > > 
> > > I prefer the second one. From my view, memory node should only describe
> > > the hardware information of memory.
> > 
> > Yes, option 2 will be more simple for memory node.
> > 
> > But option 2 also will introduce complexity for mailbox node, due mailbox
> > driver need use property "reg" and "memory-region" to sepeately depict
> > the regions for mailbox's ipc and slots. If later mailbox is designed to
> > use SRAM for both ipc and slots, then it will no matter with DDR anymore,
> > in this case option 1 will easily switch to support it.
> > 
> > Another question is a general question: for Linux kernel, which is the
> > best method to reserve memory regions? According to previous discussion,
> > we can use /memory/ node or /reseved-memory/ node to reserve memory
> > regions.
> 
> If the memory is truly reserved for a purpose and cannot be used for
> anything else, I don't think it should be in the memory node at all, and
> should be carved out. That aligns with what you'd do in UEFI (either not
> listing the region in the memory map, or listing it with attributes such
> that it may not be mapped and/or used).
> 
> I don't see much of a reason for /memreserve/, as it can cause issues
> (by allowing the OS to map the region with cacheable attributes), and is
> not as rigorously specified for ARM as it is for Power in ePAPR.
> 
> I understand that reserved-memory is for carving out (potentially
> reusable) memory pools for devices or other special uses (perhaps a
> panic log). Usually such memory may also be used by the kernel for its
> own purposes if not presently required by the device.
> 
> Having an entry in reserved-memory does not necessitate the region also
> appears in memory nodes, and if a region cannot be used by an OS (or
> other software) for other purposes, I would not expect it to be describe
> in any memory node. That will prevent other software (e.g. bootloaders)
> from erroneously using the memory.
> 
> If you have a region described with no-map, I would expect that this
> doesn't exist in any memory node or the UEFI memory map, and is only
> under reserved-memory so it may be referred to by phandle in a
> consistent manner.
> 
> > when review Juno's dts, i also see there have reserved 16MB DDR for secure
> > world. If so, looks like /reserved-memory/ node is unnecessary. if have some
> > specific scenarios will we use reserved-memory node to help reserve memory
> > regions?
> 
> I'd expect shared DMA pools to appear in reserved-memory. The OS can
> choose to use these or ignore them if it chooses (or is otherwise forced
> to, e.g. were it loaded over one).

Thanks a lot for detailed explain; it's quite clear now.

Thanks,
Leo Yan


From Haibo.Chen at freescale.com  Thu Aug 27 23:53:36 2015
From: Haibo.Chen at freescale.com (Chen Bough)
Date: Fri, 28 Aug 2015 06:53:36 +0000
Subject: [PATCH v6 0/6] mmc: imx: a few fixes and new feature
In-Reply-To: <CAPDyKFriWeJTsymd+Ha0ZY+UWjpbEdKMwZgw1hA2zZhw5khPaw@mail.gmail.com>
References: <1439293111-21077-1-git-send-email-haibo.chen@freescale.com>
 <CAPDyKFriWeJTsymd+Ha0ZY+UWjpbEdKMwZgw1hA2zZhw5khPaw@mail.gmail.com>
Message-ID: <BY1PR03MB1388F0A45EF1A6CC38D2A4489A6E0@BY1PR03MB1388.namprd03.prod.outlook.com>

Thanks? Uffe.


Hi Shawn and Sascha,

Can you help pull the patch4 in your branch? 


Best Regards
Haibo Chen


> -----Original Message-----
> From: Ulf Hansson [mailto:ulf.hansson at linaro.org]
> Sent: Tuesday, August 25, 2015 8:06 PM
> To: Chen Haibo-B51421
> Cc: Rob Herring; Pawe? Moll; Mark Rutland; Ian Campbell; Kumar Gala;
> Shawn Guo; Sascha Hauer; Russell King - ARM Linux; Dong Aisheng-B29396;
> Johan Derycke; Marc Kleine-Budde; Estevam Fabio-R49496;
> devicetree at vger.kernel.org; linux-kernel at vger.kernel.org; linux-arm-
> kernel at lists.infradead.org; linux-mmc
> Subject: Re: [PATCH v6 0/6] mmc: imx: a few fixes and new feature
> 
> On 11 August 2015 at 13:38, Haibo Chen <haibo.chen at freescale.com> wrote:
> > Changes for v6:
> > -remove duplicate code in esdhc_set_uhs_signaling().
> > -fix a typo for patch-2.
> > -make commit log of patch-3 more specific.
> >
> > Haibo Chen (6):
> >   mmc: sdhci-esdhc-imx: add imx7d support and support HS400
> >   mmc: sdhci-esdhc-imx: add tuning-step setting support
> >   mmc: sdhci-esdhc-imx: add imx7d support in bingding doc
> >   ARM: dts: imx7d-sdb: add eMMC5.0 support
> >   mmc: sdhci-esdhc-imx: set back the burst_length_enable bit to 1
> >   mmc: sdhci-esdhc-imx: change default watermark level and burst
> > length
> >
> >  .../devicetree/bindings/mmc/fsl-imx-esdhc.txt      |   6 ++
> >  arch/arm/boot/dts/imx7d-sdb.dts                    |  13 +++
> >  drivers/mmc/host/sdhci-esdhc-imx.c                 | 114
> ++++++++++++++++++++-
> >  include/linux/platform_data/mmc-esdhc-imx.h        |   1 +
> >  4 files changed, 130 insertions(+), 4 deletions(-)
> >
> > --
> > 1.9.1
> >
> 
> I have applied this for next - except patch4 as it needs and ack from the
> IMX SOC maintainer, or it may be better to take that patch through ARM
> soc...
> 
> Regarding patch3, which document the new bindings and the compatible
> string, I moved this to be the first patch and fixed the spelling of the
> commit message header.
> 
> Thanks!
> 
> Kind regards
> Uffe

From lee.jones at linaro.org  Thu Aug 27 23:57:02 2015
From: lee.jones at linaro.org (Lee Jones)
Date: Fri, 28 Aug 2015 07:57:02 +0100
Subject: [PATCH v2 5/5] [media] c8sectpfe: Update DT binding doc with
 some minor fixes
In-Reply-To: <1440678575-21646-6-git-send-email-peter.griffin@linaro.org>
References: <1440678575-21646-1-git-send-email-peter.griffin@linaro.org>
 <1440678575-21646-6-git-send-email-peter.griffin@linaro.org>
Message-ID: <20150828065702.GC4796@x1>

On Thu, 27 Aug 2015, Peter Griffin wrote:

> Signed-off-by: Peter Griffin <peter.griffin at linaro.org>
> ---
>  .../devicetree/bindings/media/stih407-c8sectpfe.txt      | 16 +++++++---------
>  1 file changed, 7 insertions(+), 9 deletions(-)
> 
> diff --git a/Documentation/devicetree/bindings/media/stih407-c8sectpfe.txt b/Documentation/devicetree/bindings/media/stih407-c8sectpfe.txt
> index e70d840..5d6438c 100644
> --- a/Documentation/devicetree/bindings/media/stih407-c8sectpfe.txt
> +++ b/Documentation/devicetree/bindings/media/stih407-c8sectpfe.txt
> @@ -55,21 +55,20 @@ Example:
>  		status = "okay";
>  		reg = <0x08a20000 0x10000>, <0x08a00000 0x4000>;
>  		reg-names = "stfe", "stfe-ram";
> -		interrupts = <0 34 0>, <0 35 0>;
> +		interrupts = <GIC_SPI 34 IRQ_TYPE_NONE>, <GIC_SPI 35 IRQ_TYPE_NONE>;
>  		interrupt-names = "stfe-error-irq", "stfe-idle-irq";
> -
> -		pinctrl-names	= "tsin0-serial", "tsin0-parallel", "tsin3-serial",
> -				"tsin4-serial", "tsin5-serial";
> -
> +		pinctrl-names	= "tsin0-serial",
> +				  "tsin0-parallel",
> +				  "tsin3-serial",
> +				  "tsin4-serial",
> +				  "tsin5-serial";
>  		pinctrl-0	= <&pinctrl_tsin0_serial>;
>  		pinctrl-1	= <&pinctrl_tsin0_parallel>;
>  		pinctrl-2	= <&pinctrl_tsin3_serial>;
>  		pinctrl-3	= <&pinctrl_tsin4_serial_alt3>;
>  		pinctrl-4	= <&pinctrl_tsin5_serial_alt1>;
> -
>  		clocks = <&clk_s_c0_flexgen CLK_PROC_STFE>;
> -		clock-names = "stfe";
> -
> +		clock-names = "c8sectpfe";

Are you sure you even need this property?  I'm thinking that *-names
properties are *usually* only required if there are more than one in a
single property.

>  		/* tsin0 is TSA on NIMA */
>  		tsin0: port at 0 {
>  			tsin-num		= <0>;
> @@ -78,7 +77,6 @@ Example:
>  			reset-gpios		= <&pio15 4 GPIO_ACTIVE_HIGH>;
>  			dvb-card		= <STV0367_TDA18212_NIMA_1>;
>  		};
> -

My personal preference is to have a '\n' between nodes.

>  		tsin3: port at 3 {
>  			tsin-num		= <3>;
>  			serial-not-parallel;

But these comments are pretty trivial, so agree or not, or fix-up or
not, it's that big of a deal.

Either way,
  Acked-by: Lee Jones <lee.jones at linaro.org>

-- 
Lee Jones
Linaro STMicroelectronics Landing Team Lead
Linaro.org ? Open source software for ARM SoCs
Follow Linaro: Facebook | Twitter | Blog


From lee.jones at linaro.org  Thu Aug 27 23:57:40 2015
From: lee.jones at linaro.org (Lee Jones)
Date: Fri, 28 Aug 2015 07:57:40 +0100
Subject: [PATCH v2 4/5] [media] c8sectpfe: Update binding to reset-gpios
In-Reply-To: <1440678575-21646-5-git-send-email-peter.griffin@linaro.org>
References: <1440678575-21646-1-git-send-email-peter.griffin@linaro.org>
 <1440678575-21646-5-git-send-email-peter.griffin@linaro.org>
Message-ID: <20150828065740.GD4796@x1>

On Thu, 27 Aug 2015, Peter Griffin wrote:

> gpio.txt documents that GPIO properties should be named
> "[<name>-]gpios", with <name> being the purpose of this
> GPIO for the device.
> 
> This change has been done as one atomic commit.
> 
> Signed-off-by: Peter Griffin <peter.griffin at linaro.org>
> ---
>  Documentation/devicetree/bindings/media/stih407-c8sectpfe.txt | 6 +++---
>  arch/arm/boot/dts/stihxxx-b2120.dtsi                          | 4 ++--
>  drivers/media/platform/sti/c8sectpfe/c8sectpfe-core.c         | 2 +-
>  3 files changed, 6 insertions(+), 6 deletions(-)

Acked-by: Lee Jones <lee.jones at linaro.org>

> diff --git a/Documentation/devicetree/bindings/media/stih407-c8sectpfe.txt b/Documentation/devicetree/bindings/media/stih407-c8sectpfe.txt
> index d4def76..e70d840 100644
> --- a/Documentation/devicetree/bindings/media/stih407-c8sectpfe.txt
> +++ b/Documentation/devicetree/bindings/media/stih407-c8sectpfe.txt
> @@ -35,7 +35,7 @@ Required properties (tsin (child) node):
>  
>  - tsin-num	: tsin id of the InputBlock (must be between 0 to 6)
>  - i2c-bus	: phandle to the I2C bus DT node which the demodulators & tuners on this tsin channel are connected.
> -- rst-gpio	: reset gpio for this tsin channel.
> +- reset-gpios	: reset gpio for this tsin channel.
>  
>  Optional properties (tsin (child) node):
>  
> @@ -75,7 +75,7 @@ Example:
>  			tsin-num		= <0>;
>  			serial-not-parallel;
>  			i2c-bus			= <&ssc2>;
> -			rst-gpio		= <&pio15 4 0>;
> +			reset-gpios		= <&pio15 4 GPIO_ACTIVE_HIGH>;
>  			dvb-card		= <STV0367_TDA18212_NIMA_1>;
>  		};
>  
> @@ -83,7 +83,7 @@ Example:
>  			tsin-num		= <3>;
>  			serial-not-parallel;
>  			i2c-bus			= <&ssc3>;
> -			rst-gpio		= <&pio15 7 0>;
> +			reset-gpios		= <&pio15 7 GPIO_ACTIVE_HIGH>;
>  			dvb-card		= <STV0367_TDA18212_NIMB_1>;
>  		};
>  	};
> diff --git a/arch/arm/boot/dts/stihxxx-b2120.dtsi b/arch/arm/boot/dts/stihxxx-b2120.dtsi
> index c014173..f932bfd 100644
> --- a/arch/arm/boot/dts/stihxxx-b2120.dtsi
> +++ b/arch/arm/boot/dts/stihxxx-b2120.dtsi
> @@ -6,8 +6,8 @@
>   * it under the terms of the GNU General Public License version 2 as
>   * published by the Free Software Foundation.
>   */
> -
>  #include <dt-bindings/clock/stih407-clks.h>
> +#include <dt-bindings/gpio/gpio.h>
>  #include <dt-bindings/media/c8sectpfe.h>
>  / {
>  	soc {
> @@ -115,7 +115,7 @@
>  				tsin-num	= <0>;
>  				serial-not-parallel;
>  				i2c-bus		= <&ssc2>;
> -				rst-gpio	= <&pio15 4 0>;
> +				reset-gpios	= <&pio15 4 GPIO_ACTIVE_HIGH>;
>  				dvb-card	= <STV0367_TDA18212_NIMA_1>;
>  			};
>  		};
> diff --git a/drivers/media/platform/sti/c8sectpfe/c8sectpfe-core.c b/drivers/media/platform/sti/c8sectpfe/c8sectpfe-core.c
> index 3a91093..c691e13 100644
> --- a/drivers/media/platform/sti/c8sectpfe/c8sectpfe-core.c
> +++ b/drivers/media/platform/sti/c8sectpfe/c8sectpfe-core.c
> @@ -822,7 +822,7 @@ static int c8sectpfe_probe(struct platform_device *pdev)
>  		}
>  		of_node_put(i2c_bus);
>  
> -		tsin->rst_gpio = of_get_named_gpio(child, "rst-gpio", 0);
> +		tsin->rst_gpio = of_get_named_gpio(child, "reset-gpios", 0);
>  
>  		ret = gpio_is_valid(tsin->rst_gpio);
>  		if (!ret) {

-- 
Lee Jones
Linaro STMicroelectronics Landing Team Lead
Linaro.org ? Open source software for ARM SoCs
Follow Linaro: Facebook | Twitter | Blog


From lee.jones at linaro.org  Thu Aug 27 23:58:30 2015
From: lee.jones at linaro.org (Lee Jones)
Date: Fri, 28 Aug 2015 07:58:30 +0100
Subject: [PATCH v2 3/5] [media] c8sectpfe: Remove select on undefined
 LIBELF_32
In-Reply-To: <1440678575-21646-4-git-send-email-peter.griffin@linaro.org>
References: <1440678575-21646-1-git-send-email-peter.griffin@linaro.org>
 <1440678575-21646-4-git-send-email-peter.griffin@linaro.org>
Message-ID: <20150828065830.GE4796@x1>

On Thu, 27 Aug 2015, Peter Griffin wrote:

> LIBELF_32 is not defined in Kconfig, and is left over legacy
> which is not required in the upstream driver, so remove it.
> 
> Signed-off-by: Peter Griffin <peter.griffin at linaro.org>
> Suggested-by: Valentin Rothberg <valentinrothberg at gmail.com>

These are the wrong way round, they should be in chronological order.

> ---
>  drivers/media/platform/sti/c8sectpfe/Kconfig | 1 -
>  1 file changed, 1 deletion(-)

Acked-by: Lee Jones <lee.jones at linaro.org>

> diff --git a/drivers/media/platform/sti/c8sectpfe/Kconfig b/drivers/media/platform/sti/c8sectpfe/Kconfig
> index d1bfd4c..b9ec667 100644
> --- a/drivers/media/platform/sti/c8sectpfe/Kconfig
> +++ b/drivers/media/platform/sti/c8sectpfe/Kconfig
> @@ -1,7 +1,6 @@
>  config DVB_C8SECTPFE
>  	tristate "STMicroelectronics C8SECTPFE DVB support"
>  	depends on DVB_CORE && I2C && (ARCH_STI || ARCH_MULTIPLATFORM)
> -	select LIBELF_32
>  	select FW_LOADER
>  	select FW_LOADER_USER_HELPER_FALLBACK
>  	select DEBUG_FS

-- 
Lee Jones
Linaro STMicroelectronics Landing Team Lead
Linaro.org ? Open source software for ARM SoCs
Follow Linaro: Facebook | Twitter | Blog


From lee.jones at linaro.org  Fri Aug 28 00:01:00 2015
From: lee.jones at linaro.org (Lee Jones)
Date: Fri, 28 Aug 2015 08:01:00 +0100
Subject: [PATCH v2 2/5] ARM: DT: STi: STiH407: Add c8sectpfe LinuxDVB DT
 node.
In-Reply-To: <1440678575-21646-3-git-send-email-peter.griffin@linaro.org>
References: <1440678575-21646-1-git-send-email-peter.griffin@linaro.org>
 <1440678575-21646-3-git-send-email-peter.griffin@linaro.org>
Message-ID: <20150828070100.GF4796@x1>

On Thu, 27 Aug 2015, Peter Griffin wrote:

> This patch adds in the required DT node for the c8sectpfe
> Linux DVB demux driver which allows the tsin channels
> to be used on an upstream kernel.
> 
> Signed-off-by: Peter Griffin <peter.griffin at linaro.org>
> ---
>  arch/arm/boot/dts/stihxxx-b2120.dtsi | 34 ++++++++++++++++++++++++++++++++++
>  1 file changed, 34 insertions(+)
> 
> diff --git a/arch/arm/boot/dts/stihxxx-b2120.dtsi b/arch/arm/boot/dts/stihxxx-b2120.dtsi
> index 62994ae..c014173 100644
> --- a/arch/arm/boot/dts/stihxxx-b2120.dtsi
> +++ b/arch/arm/boot/dts/stihxxx-b2120.dtsi
> @@ -6,6 +6,9 @@
>   * it under the terms of the GNU General Public License version 2 as
>   * published by the Free Software Foundation.
>   */
> +
> +#include <dt-bindings/clock/stih407-clks.h>
> +#include <dt-bindings/media/c8sectpfe.h>
>  / {
>  	soc {
>  		sbc_serial0: serial at 9530000 {
> @@ -85,5 +88,36 @@
>  			status = "okay";
>  		};
>  
> +		demux at 08a20000 {
> +			compatible	= "st,stih407-c8sectpfe";
> +			status		= "okay";
> +			reg		= <0x08a20000 0x10000>,
> +					  <0x08a00000 0x4000>;

These look like they're the wrong way round.

> +			reg-names	= "c8sectpfe", "c8sectpfe-ram";
> +			interrupts	= <GIC_SPI 34 IRQ_TYPE_NONE>,
> +					  <GIC_SPI 35 IRQ_TYPE_NONE>;
> +			interrupt-names	= "c8sectpfe-error-irq",
> +					  "c8sectpfe-idle-irq";
> +			pinctrl-names	= "tsin0-serial",
> +					  "tsin0-parallel",
> +					  "tsin3-serial",
> +					  "tsin4-serial",
> +					  "tsin5-serial";
> +			pinctrl-0	= <&pinctrl_tsin0_serial>;
> +			pinctrl-1	= <&pinctrl_tsin0_parallel>;
> +			pinctrl-2	= <&pinctrl_tsin3_serial>;
> +			pinctrl-3	= <&pinctrl_tsin4_serial_alt3>;
> +			pinctrl-4	= <&pinctrl_tsin5_serial_alt1>;
> +			clock-names	= "c8sectpfe";
> +			clocks		= <&clk_s_c0_flexgen CLK_PROC_STFE>;

Personal preferenc is that the *-names properties should come *after*
the ones they reference.

> +			/* tsin0 is TSA on NIMA */
> +			tsin0: port at 0 {
> +				tsin-num	= <0>;
> +				serial-not-parallel;
> +				i2c-bus		= <&ssc2>;
> +				rst-gpio	= <&pio15 4 0>;

"reset-gpios"?

Use the GPIO DEFINES.

> +				dvb-card	= <STV0367_TDA18212_NIMA_1>;
> +			};
> +		};
>  	};
>  };

-- 
Lee Jones
Linaro STMicroelectronics Landing Team Lead
Linaro.org ? Open source software for ARM SoCs
Follow Linaro: Facebook | Twitter | Blog


From lee.jones at linaro.org  Fri Aug 28 00:01:24 2015
From: lee.jones at linaro.org (Lee Jones)
Date: Fri, 28 Aug 2015 08:01:24 +0100
Subject: [PATCH v2 1/5] ARM: DT: STi: stihxxx-b2120: Add pulse-width
 properties to ssc2 & ssc3
In-Reply-To: <1440678575-21646-2-git-send-email-peter.griffin@linaro.org>
References: <1440678575-21646-1-git-send-email-peter.griffin@linaro.org>
 <1440678575-21646-2-git-send-email-peter.griffin@linaro.org>
Message-ID: <20150828070124.GG4796@x1>

On Thu, 27 Aug 2015, Peter Griffin wrote:

> Adding these properties makes the I2C bus to the demodulators much
> more reliable, and we no longer suffer from I2C errors when tuning.
> 
> Signed-off-by: Peter Griffin <peter.griffin at linaro.org>
> ---
>  arch/arm/boot/dts/stihxxx-b2120.dtsi | 10 ++++++++--
>  1 file changed, 8 insertions(+), 2 deletions(-)

Acked-by: Lee Jones <lee.jones at linaro.org>

> diff --git a/arch/arm/boot/dts/stihxxx-b2120.dtsi b/arch/arm/boot/dts/stihxxx-b2120.dtsi
> index f589fe4..62994ae 100644
> --- a/arch/arm/boot/dts/stihxxx-b2120.dtsi
> +++ b/arch/arm/boot/dts/stihxxx-b2120.dtsi
> @@ -27,12 +27,18 @@
>  			};
>  		};
>  
> -		i2c at 9842000 {
> +		ssc2: i2c at 9842000 {
>  			status = "okay";
> +			clock-frequency = <100000>;
> +			st,i2c-min-scl-pulse-width-us = <0>;
> +			st,i2c-min-sda-pulse-width-us = <5>;
>  		};
>  
> -		i2c at 9843000 {
> +		ssc3: i2c at 9843000 {
>  			status = "okay";
> +			clock-frequency = <100000>;
> +			st,i2c-min-scl-pulse-width-us = <0>;
> +			st,i2c-min-sda-pulse-width-us = <5>;
>  		};
>  
>  		i2c at 9844000 {

-- 
Lee Jones
Linaro STMicroelectronics Landing Team Lead
Linaro.org ? Open source software for ARM SoCs
Follow Linaro: Facebook | Twitter | Blog


From marc.zyngier at arm.com  Fri Aug 28 00:04:25 2015
From: marc.zyngier at arm.com (Marc Zyngier)
Date: Fri, 28 Aug 2015 08:04:25 +0100
Subject: [PATCH 00/13] arm64: Virtualization Host Extension support
In-Reply-To: <55DDA024.8040303@huawei.com>
References: <1436372356-30410-1-git-send-email-marc.zyngier@arm.com>
 <55DD82FB.60903@huawei.com> <55DD851B.4040106@siemens.com>
 <55DD8DEF.9080301@arm.com> <55DDA024.8040303@huawei.com>
Message-ID: <20150828080425.4fb41861@arm.com>

On Wed, 26 Aug 2015 13:16:52 +0200
Antonios Motakis <antonios.motakis at huawei.com> wrote:
> On 26-Aug-15 11:59, Marc Zyngier wrote:

[...]

> > Unfortunately, there is more to downgrading to EL1 than just interrupts.
> > You need to migrate the whole VM context from EL2 to EL1 in an atomic
> > fashion, clear the HCR_EL2.E2H and HCR_EL2.TGE bits while running at EL2
> > (which is a bit like pulling the rug from under your own feet so you
> > need to transition via a low mapping or an idmap), reinstall the EL2
> > stub and do an exception return into EL1.
> 
> When enabling Jailhouse, we already do most of that. We already use
> identity mapping, since we need to switch on the MMU for EL2, switch
> the exception level, etc. Jailhouse entry looks a lot like
> initializing a new kernel; we just save the state of what was running
> before it and restore it as the "root cell".
> 
> So I think we could handle the cpu context switch, with changes only
> in the Jailhouse entry code. But then of course, Linux would be
> expecting to be in EL2, while it is running in EL1, so we would have
> to emulate the differences in behavior. But...

There would be (almost) no difference in behaviour - VHE is designed
for the kernel to be unchanged, and the only difference is the timer
interrupt as you noticed.

What is really tricky is to perform the downgrade, because you're
completely changing the way the code is executed *while running it*.
This is not just about changing the memory map, but also changing the
effect of most system registers.

> 
> > 
> > And that's only for the CPU. Downgrading to EL1 has other fun
> > consequences at the system level (SMMUs listening to TLB traffic
> > would need to be reconfigured on the flight - it's a joke, don't
> > even think of it).
> 
> ...but then there's that.
> 
> Hm... even if the kernel is running in EL2, it will still be
> configuring stage 1 on the SMMU, no? I wonder if this could still be
> handled somehow... The root cell would be restored with identity
> mapping, too... Just thinking out loud :)

Stage-1 and EL2 are two vastly unrelated concept. The main issue is
that it is likely that your SMMU knows about VHE as well (it listens to
EL2-VHE DVM messages), and need to be reconfigured as well. Good luck
with that.

[...]

> > As far as I can see, the only practical solution to this is to have
> > a VHE config option, and Jailhouse that can be set to conflict it
> > (depends on !VHE).
> 
> Having a toggle to turn VHE off at build time would definitely be the
> easy way out. Then we can just tell the user that we only support
> kernels built without it (the Jailhouse driver is out of tree atm).
> 
> I don't have access to a VHE model though. Are you considering to add
> a config option for VHE in the next version of your patches?

Yes, that's the plan.

Thanks,

	M.
-- 
Jazz is not dead. It just smells funny.


From wangzhou1 at hisilicon.com  Fri Aug 28 00:14:37 2015
From: wangzhou1 at hisilicon.com (Zhou Wang)
Date: Fri, 28 Aug 2015 15:14:37 +0800
Subject: [PATCH v8 3/6] PCI: designware: Add ARM64 support
In-Reply-To: <CAG374jDDY4COvM_UTfGmJfbXQrMywYB511-fZiWen3GU9VhQvw@mail.gmail.com>
References: <1440496734-18417-1-git-send-email-wangzhou1@hisilicon.com>
 <1440496734-18417-4-git-send-email-wangzhou1@hisilicon.com>
 <CAG374jDDY4COvM_UTfGmJfbXQrMywYB511-fZiWen3GU9VhQvw@mail.gmail.com>
Message-ID: <55E00A5D.5070200@hisilicon.com>

On 2015/8/27 20:56, Gabriel Fernandez wrote:
> Hi Zhou,
> 
> You can add my Tested-by: Gabriel Fernandez <gabriel.fernandez at st.com>
> 
> I tested your patchset with a STMicroelectronics PCIe controller.
> This controller is based on designware PCIe driver and works on ARM32.
> 
> Please find my patchset here:
> http://www.spinics.net/lists/kernel/msg2064266.html
> 
> Best Regards.
> 
> Gabriel.
>

Hi Gabriel,

It is very helpful to test this patch. Many thanks!

Best Regards,
Zhou

> On 25 August 2015 at 11:58, Zhou Wang <wangzhou1 at hisilicon.com> wrote:
>> This patch tries to unify ARM32 and ARM64 PCIe in designware driver. Delete
>> function dw_pcie_setup, dw_pcie_scan_bus, dw_pcie_map_irq and struct hw_pci,
>> move related operations to dw_pcie_host_init.
>>
>> This patch also try to use of_pci_get_host_bridge_resources for ARM32 and ARM64
>> according to the suggestion for Gabriele[1]
>>
>> Finally this patch reverts commit f4c55c5a3f7f "PCI: designware: Program ATU
>> with untranslated address" based on 1/6 in this series. we delete *_mod_base in
>> pcie-designware. This was discussed in [2]
>>
>> I have compiled the driver with multi_v7_defconfig. However, I don't have
>> ARM32 PCIe related board to do test. It will be appreciated if someone could
>> help to test it.
>>
>> Signed-off-by: Zhou Wang <wangzhou1 at hisilicon.com>
>> Signed-off-by: Gabriele Paoloni <gabriele.paoloni at huawei.com>
>> Signed-off-by: Arnd Bergmann <arnd at arndb.de>
>> Tested-By: James Morse <james.morse at arm.com>
>>
>> [1] http://www.spinics.net/lists/linux-pci/msg42194.html
>> [2] http://www.spinics.net/lists/arm-kernel/msg436779.html
>> ---
>>  drivers/pci/host/pci-dra7xx.c      |  14 +--
>>  drivers/pci/host/pci-keystone-dw.c |   2 +-
>>  drivers/pci/host/pcie-designware.c | 230 +++++++++++++------------------------
>>  drivers/pci/host/pcie-designware.h |  14 +--
>>  4 files changed, 90 insertions(+), 170 deletions(-)
>>
>> diff --git a/drivers/pci/host/pci-dra7xx.c b/drivers/pci/host/pci-dra7xx.c
>> index 18ae7ff..ac401be 100644
>> --- a/drivers/pci/host/pci-dra7xx.c
>> +++ b/drivers/pci/host/pci-dra7xx.c
>> @@ -141,15 +141,15 @@ static void dra7xx_pcie_host_init(struct pcie_port *pp)
>>  {
>>         dw_pcie_setup_rc(pp);
>>
>> -       if (pp->io_mod_base)
>> -               pp->io_mod_base &= CPU_TO_BUS_ADDR;
>> +       if (pp->io_base)
>> +               pp->io_base &= CPU_TO_BUS_ADDR;
>>
>> -       if (pp->mem_mod_base)
>> -               pp->mem_mod_base &= CPU_TO_BUS_ADDR;
>> +       if (pp->mem_base)
>> +               pp->mem_base &= CPU_TO_BUS_ADDR;
>>
>> -       if (pp->cfg0_mod_base) {
>> -               pp->cfg0_mod_base &= CPU_TO_BUS_ADDR;
>> -               pp->cfg1_mod_base &= CPU_TO_BUS_ADDR;
>> +       if (pp->cfg0_base) {
>> +               pp->cfg0_base &= CPU_TO_BUS_ADDR;
>> +               pp->cfg1_base &= CPU_TO_BUS_ADDR;
>>         }
>>
>>         dra7xx_pcie_establish_link(pp);
>> diff --git a/drivers/pci/host/pci-keystone-dw.c b/drivers/pci/host/pci-keystone-dw.c
>> index f34892e..b1e4135 100644
>> --- a/drivers/pci/host/pci-keystone-dw.c
>> +++ b/drivers/pci/host/pci-keystone-dw.c
>> @@ -327,7 +327,7 @@ static void ks_dw_pcie_clear_dbi_mode(void __iomem *reg_virt)
>>  void ks_dw_pcie_setup_rc_app_regs(struct keystone_pcie *ks_pcie)
>>  {
>>         struct pcie_port *pp = &ks_pcie->pp;
>> -       u32 start = pp->mem.start, end = pp->mem.end;
>> +       u32 start = pp->mem->start, end = pp->mem->end;
>>         int i, tr_size;
>>
>>         /* Disable BARs for inbound access */
>> diff --git a/drivers/pci/host/pcie-designware.c b/drivers/pci/host/pcie-designware.c
>> index c5d407c..e2d1898 100644
>> --- a/drivers/pci/host/pcie-designware.c
>> +++ b/drivers/pci/host/pcie-designware.c
>> @@ -11,6 +11,7 @@
>>   * published by the Free Software Foundation.
>>   */
>>
>> +#include <linux/hardirq.h>
>>  #include <linux/irq.h>
>>  #include <linux/irqdomain.h>
>>  #include <linux/kernel.h>
>> @@ -69,16 +70,7 @@
>>  #define PCIE_ATU_FUNC(x)               (((x) & 0x7) << 16)
>>  #define PCIE_ATU_UPPER_TARGET          0x91C
>>
>> -static struct hw_pci dw_pci;
>> -
>> -static unsigned long global_io_offset;
>> -
>> -static inline struct pcie_port *sys_to_pcie(struct pci_sys_data *sys)
>> -{
>> -       BUG_ON(!sys->private_data);
>> -
>> -       return sys->private_data;
>> -}
>> +static struct pci_ops dw_pcie_ops;
>>
>>  int dw_pcie_cfg_read(void __iomem *addr, int where, int size, u32 *val)
>>  {
>> @@ -255,7 +247,7 @@ static void dw_pcie_msi_set_irq(struct pcie_port *pp, int irq)
>>  static int assign_irq(int no_irqs, struct msi_desc *desc, int *pos)
>>  {
>>         int irq, pos0, i;
>> -       struct pcie_port *pp = sys_to_pcie(desc->dev->bus->sysdata);
>> +       struct pcie_port *pp = desc->dev->bus->sysdata;
>>
>>         pos0 = bitmap_find_free_region(pp->msi_irq_in_use, MAX_MSI_IRQS,
>>                                        order_base_2(no_irqs));
>> @@ -298,7 +290,7 @@ static int dw_msi_setup_irq(struct msi_controller *chip, struct pci_dev *pdev,
>>  {
>>         int irq, pos;
>>         struct msi_msg msg;
>> -       struct pcie_port *pp = sys_to_pcie(pdev->bus->sysdata);
>> +       struct pcie_port *pp = pdev->bus->sysdata;
>>
>>         if (desc->msi_attrib.is_msix)
>>                 return -EINVAL;
>> @@ -327,7 +319,7 @@ static void dw_msi_teardown_irq(struct msi_controller *chip, unsigned int irq)
>>  {
>>         struct irq_data *data = irq_get_irq_data(irq);
>>         struct msi_desc *msi = irq_data_get_msi(data);
>> -       struct pcie_port *pp = sys_to_pcie(msi->dev->bus->sysdata);
>> +       struct pcie_port *pp = msi->dev->bus->sysdata;
>>
>>         clear_irq_range(pp, irq, 1, data->hwirq);
>>  }
>> @@ -363,14 +355,12 @@ int dw_pcie_host_init(struct pcie_port *pp)
>>  {
>>         struct device_node *np = pp->dev->of_node;
>>         struct platform_device *pdev = to_platform_device(pp->dev);
>> -       struct of_pci_range range;
>> -       struct of_pci_range_parser parser;
>> +       struct pci_bus *bus;
>>         struct resource *cfg_res;
>> -       u32 val, ns;
>> -       const __be32 *addrp;
>> -       int i, index, ret;
>> -
>> -       ns = of_n_size_cells(np);
>> +       LIST_HEAD(res);
>> +       u32 val;
>> +       int i, ret;
>> +       struct resource_entry *win;
>>
>>         cfg_res = platform_get_resource_byname(pdev, IORESOURCE_MEM, "config");
>>         if (cfg_res) {
>> @@ -378,85 +368,60 @@ int dw_pcie_host_init(struct pcie_port *pp)
>>                 pp->cfg1_size = resource_size(cfg_res)/2;
>>                 pp->cfg0_base = cfg_res->start;
>>                 pp->cfg1_base = cfg_res->start + pp->cfg0_size;
>> -
>> -               /* Find the untranslated configuration space address */
>> -               index = of_property_match_string(np, "reg-names", "config");
>> -               addrp = of_get_address(np, index, NULL, NULL);
>> -               pp->cfg0_mod_base = of_read_number(addrp, ns);
>> -               pp->cfg1_mod_base = pp->cfg0_mod_base + pp->cfg0_size;
>>         } else {
>>                 dev_err(pp->dev, "missing *config* reg space\n");
>>         }
>>
>> -       if (of_pci_range_parser_init(&parser, np)) {
>> -               dev_err(pp->dev, "missing ranges property\n");
>> -               return -EINVAL;
>> -       }
>> +       ret = of_pci_get_host_bridge_resources(np, 0, 0xff, &res, &pp->io_base);
>> +       if (ret)
>> +               return ret;
>>
>>         /* Get the I/O and memory ranges from DT */
>> -       for_each_of_pci_range(&parser, &range) {
>> -               unsigned long restype = range.flags & IORESOURCE_TYPE_BITS;
>> -
>> -               if (restype == IORESOURCE_IO) {
>> -                       of_pci_range_to_resource(&range, np, &pp->io);
>> -                       pp->io.name = "I/O";
>> -                       pp->io.start = max_t(resource_size_t,
>> -                                            PCIBIOS_MIN_IO,
>> -                                            range.pci_addr + global_io_offset);
>> -                       pp->io.end = min_t(resource_size_t,
>> -                                          IO_SPACE_LIMIT,
>> -                                          range.pci_addr + range.size
>> -                                          + global_io_offset - 1);
>> -                       pp->io_size = resource_size(&pp->io);
>> -                       pp->io_bus_addr = range.pci_addr;
>> -                       pp->io_base = range.cpu_addr;
>> -
>> -                       /* Find the untranslated IO space address */
>> -                       pp->io_mod_base = range.cpu_addr;
>> -               }
>> -               if (restype == IORESOURCE_MEM) {
>> -                       of_pci_range_to_resource(&range, np, &pp->mem);
>> -                       pp->mem.name = "MEM";
>> -                       pp->mem_size = resource_size(&pp->mem);
>> -                       pp->mem_bus_addr = range.pci_addr;
>> -
>> -                       /* Find the untranslated MEM space address */
>> -                       pp->mem_mod_base = range.cpu_addr;
>> -               }
>> -               if (restype == 0) {
>> -                       of_pci_range_to_resource(&range, np, &pp->cfg);
>> -                       pp->cfg0_size = resource_size(&pp->cfg)/2;
>> -                       pp->cfg1_size = resource_size(&pp->cfg)/2;
>> -                       pp->cfg0_base = pp->cfg.start;
>> -                       pp->cfg1_base = pp->cfg.start + pp->cfg0_size;
>> -
>> -                       /* Find the untranslated configuration space address */
>> -                       pp->cfg0_mod_base = range.cpu_addr;
>> -                       pp->cfg1_mod_base = pp->cfg0_mod_base +
>> -                                           pp->cfg0_size;
>> +       resource_list_for_each_entry(win, &res) {
>> +               switch (resource_type(win->res)) {
>> +               case IORESOURCE_IO:
>> +                       pp->io = win->res;
>> +                       pp->io->name = "I/O";
>> +                       pp->io_size = resource_size(pp->io);
>> +                       pp->io_bus_addr = pp->io->start - win->offset;
>> +                       ret = pci_remap_iospace(pp->io, pp->io_base);
>> +                       if (ret) {
>> +                               dev_warn(pp->dev, "error %d: failed to map resource %pR\n",
>> +                                        ret, pp->io);
>> +                               continue;
>> +                       }
>> +                       break;
>> +               case IORESOURCE_MEM:
>> +                       pp->mem = win->res;
>> +                       pp->mem->name = "MEM";
>> +                       pp->mem_size = resource_size(pp->mem);
>> +                       pp->mem_bus_addr = pp->mem->start - win->offset;
>> +                       break;
>> +               case 0:
>> +                       pp->cfg = win->res;
>> +                       pp->cfg0_size = resource_size(pp->cfg)/2;
>> +                       pp->cfg1_size = resource_size(pp->cfg)/2;
>> +                       pp->cfg0_base = pp->cfg->start;
>> +                       pp->cfg1_base = pp->cfg->start + pp->cfg0_size;
>> +                       break;
>> +               case IORESOURCE_BUS:
>> +                       pp->busn = win->res;
>> +                       break;
>> +               default:
>> +                       continue;
>>                 }
>>         }
>>
>> -       ret = of_pci_parse_bus_range(np, &pp->busn);
>> -       if (ret < 0) {
>> -               pp->busn.name = np->name;
>> -               pp->busn.start = 0;
>> -               pp->busn.end = 0xff;
>> -               pp->busn.flags = IORESOURCE_BUS;
>> -               dev_dbg(pp->dev, "failed to parse bus-range property: %d, using default %pR\n",
>> -                       ret, &pp->busn);
>> -       }
>> -
>>         if (!pp->dbi_base) {
>> -               pp->dbi_base = devm_ioremap(pp->dev, pp->cfg.start,
>> -                                       resource_size(&pp->cfg));
>> +               pp->dbi_base = devm_ioremap(pp->dev, pp->cfg->start,
>> +                                       resource_size(pp->cfg));
>>                 if (!pp->dbi_base) {
>>                         dev_err(pp->dev, "error with ioremap\n");
>>                         return -ENOMEM;
>>                 }
>>         }
>>
>> -       pp->mem_base = pp->mem.start;
>> +       pp->mem_base = pp->mem->start;
>>
>>         if (!pp->va_cfg0_base) {
>>                 pp->va_cfg0_base = devm_ioremap(pp->dev, pp->cfg0_base,
>> @@ -505,7 +470,7 @@ int dw_pcie_host_init(struct pcie_port *pp)
>>
>>         if (!pp->ops->rd_other_conf)
>>                 dw_pcie_prog_outbound_atu(pp, PCIE_ATU_REGION_INDEX1,
>> -                                         PCIE_ATU_TYPE_MEM, pp->mem_mod_base,
>> +                                         PCIE_ATU_TYPE_MEM, pp->mem_base,
>>                                           pp->mem_bus_addr, pp->mem_size);
>>
>>         dw_pcie_wr_own_conf(pp, PCI_BASE_ADDRESS_0, 4, 0);
>> @@ -517,15 +482,30 @@ int dw_pcie_host_init(struct pcie_port *pp)
>>         val |= PORT_LOGIC_SPEED_CHANGE;
>>         dw_pcie_wr_own_conf(pp, PCIE_LINK_WIDTH_SPEED_CONTROL, 4, val);
>>
>> -#ifdef CONFIG_PCI_MSI
>> +       pp->root_bus_nr = pp->busn->start;
>> +       bus = pci_create_root_bus(pp->dev, pp->root_bus_nr, &dw_pcie_ops,
>> +                                 pp, &res);
>> +       if (!bus)
>> +               return -ENOMEM;
>> +
>> +#ifdef CONFIG_GENERIC_MSI_IRQ_DOMAIN
>> +       bus->msi = container_of(&pp->irq_domain, struct msi_controller, domain);
>> +#else
>>         dw_pcie_msi_chip.dev = pp->dev;
>> -       dw_pci.msi_ctrl = &dw_pcie_msi_chip;
>> +       bus->msi = &dw_pcie_msi_chip;
>>  #endif
>>
>> -       dw_pci.nr_controllers = 1;
>> -       dw_pci.private_data = (void **)&pp;
>> +       pci_scan_child_bus(bus);
>> +       if (pp->ops->scan_bus)
>> +               pp->ops->scan_bus(pp);
>> +
>> +#ifdef CONFIG_ARM
>> +       /* support old dtbs that incorrectly describe IRQs */
>> +       pci_fixup_irqs(pci_common_swizzle, of_irq_parse_and_map_pci);
>> +#endif
>>
>> -       pci_common_init_dev(pp->dev, &dw_pci);
>> +       pci_assign_unassigned_bus_resources(bus);
>> +       pci_bus_add_devices(bus);
>>
>>         return 0;
>>  }
>> @@ -544,12 +524,12 @@ static int dw_pcie_rd_other_conf(struct pcie_port *pp, struct pci_bus *bus,
>>
>>         if (bus->parent->number == pp->root_bus_nr) {
>>                 type = PCIE_ATU_TYPE_CFG0;
>> -               cpu_addr = pp->cfg0_mod_base;
>> +               cpu_addr = pp->cfg0_base;
>>                 cfg_size = pp->cfg0_size;
>>                 va_cfg_base = pp->va_cfg0_base;
>>         } else {
>>                 type = PCIE_ATU_TYPE_CFG1;
>> -               cpu_addr = pp->cfg1_mod_base;
>> +               cpu_addr = pp->cfg1_base;
>>                 cfg_size = pp->cfg1_size;
>>                 va_cfg_base = pp->va_cfg1_base;
>>         }
>> @@ -559,7 +539,7 @@ static int dw_pcie_rd_other_conf(struct pcie_port *pp, struct pci_bus *bus,
>>                                   busdev, cfg_size);
>>         ret = dw_pcie_cfg_read(va_cfg_base + address, where, size, val);
>>         dw_pcie_prog_outbound_atu(pp, PCIE_ATU_REGION_INDEX0,
>> -                                 PCIE_ATU_TYPE_IO, pp->io_mod_base,
>> +                                 PCIE_ATU_TYPE_IO, pp->io_base,
>>                                   pp->io_bus_addr, pp->io_size);
>>
>>         return ret;
>> @@ -579,12 +559,12 @@ static int dw_pcie_wr_other_conf(struct pcie_port *pp, struct pci_bus *bus,
>>
>>         if (bus->parent->number == pp->root_bus_nr) {
>>                 type = PCIE_ATU_TYPE_CFG0;
>> -               cpu_addr = pp->cfg0_mod_base;
>> +               cpu_addr = pp->cfg0_base;
>>                 cfg_size = pp->cfg0_size;
>>                 va_cfg_base = pp->va_cfg0_base;
>>         } else {
>>                 type = PCIE_ATU_TYPE_CFG1;
>> -               cpu_addr = pp->cfg1_mod_base;
>> +               cpu_addr = pp->cfg1_base;
>>                 cfg_size = pp->cfg1_size;
>>                 va_cfg_base = pp->va_cfg1_base;
>>         }
>> @@ -594,7 +574,7 @@ static int dw_pcie_wr_other_conf(struct pcie_port *pp, struct pci_bus *bus,
>>                                   busdev, cfg_size);
>>         ret = dw_pcie_cfg_write(va_cfg_base + address, where, size, val);
>>         dw_pcie_prog_outbound_atu(pp, PCIE_ATU_REGION_INDEX0,
>> -                                 PCIE_ATU_TYPE_IO, pp->io_mod_base,
>> +                                 PCIE_ATU_TYPE_IO, pp->io_base,
>>                                   pp->io_bus_addr, pp->io_size);
>>
>>         return ret;
>> @@ -626,7 +606,7 @@ static int dw_pcie_valid_config(struct pcie_port *pp,
>>  static int dw_pcie_rd_conf(struct pci_bus *bus, u32 devfn, int where,
>>                         int size, u32 *val)
>>  {
>> -       struct pcie_port *pp = sys_to_pcie(bus->sysdata);
>> +       struct pcie_port *pp = bus->sysdata;
>>         int ret;
>>
>>         if (dw_pcie_valid_config(pp, bus, PCI_SLOT(devfn)) == 0) {
>> @@ -650,7 +630,7 @@ static int dw_pcie_rd_conf(struct pci_bus *bus, u32 devfn, int where,
>>  static int dw_pcie_wr_conf(struct pci_bus *bus, u32 devfn,
>>                         int where, int size, u32 val)
>>  {
>> -       struct pcie_port *pp = sys_to_pcie(bus->sysdata);
>> +       struct pcie_port *pp = bus->sysdata;
>>         int ret;
>>
>>         if (dw_pcie_valid_config(pp, bus, PCI_SLOT(devfn)) == 0)
>> @@ -674,62 +654,6 @@ static struct pci_ops dw_pcie_ops = {
>>         .write = dw_pcie_wr_conf,
>>  };
>>
>> -static int dw_pcie_setup(int nr, struct pci_sys_data *sys)
>> -{
>> -       struct pcie_port *pp;
>> -
>> -       pp = sys_to_pcie(sys);
>> -
>> -       if (global_io_offset < SZ_1M && pp->io_size > 0) {
>> -               sys->io_offset = global_io_offset - pp->io_bus_addr;
>> -               pci_ioremap_io(global_io_offset, pp->io_base);
>> -               global_io_offset += SZ_64K;
>> -               pci_add_resource_offset(&sys->resources, &pp->io,
>> -                                       sys->io_offset);
>> -       }
>> -
>> -       sys->mem_offset = pp->mem.start - pp->mem_bus_addr;
>> -       pci_add_resource_offset(&sys->resources, &pp->mem, sys->mem_offset);
>> -       pci_add_resource(&sys->resources, &pp->busn);
>> -
>> -       return 1;
>> -}
>> -
>> -static struct pci_bus *dw_pcie_scan_bus(int nr, struct pci_sys_data *sys)
>> -{
>> -       struct pci_bus *bus;
>> -       struct pcie_port *pp = sys_to_pcie(sys);
>> -
>> -       pp->root_bus_nr = sys->busnr;
>> -       bus = pci_scan_root_bus(pp->dev, sys->busnr,
>> -                                 &dw_pcie_ops, sys, &sys->resources);
>> -       if (!bus)
>> -               return NULL;
>> -
>> -       if (bus && pp->ops->scan_bus)
>> -               pp->ops->scan_bus(pp);
>> -
>> -       return bus;
>> -}
>> -
>> -static int dw_pcie_map_irq(const struct pci_dev *dev, u8 slot, u8 pin)
>> -{
>> -       struct pcie_port *pp = sys_to_pcie(dev->bus->sysdata);
>> -       int irq;
>> -
>> -       irq = of_irq_parse_and_map_pci(dev, slot, pin);
>> -       if (!irq)
>> -               irq = pp->irq;
>> -
>> -       return irq;
>> -}
>> -
>> -static struct hw_pci dw_pci = {
>> -       .setup          = dw_pcie_setup,
>> -       .scan           = dw_pcie_scan_bus,
>> -       .map_irq        = dw_pcie_map_irq,
>> -};
>> -
>>  void dw_pcie_setup_rc(struct pcie_port *pp)
>>  {
>>         u32 val;
>> diff --git a/drivers/pci/host/pcie-designware.h b/drivers/pci/host/pcie-designware.h
>> index d0bbd27..264c969 100644
>> --- a/drivers/pci/host/pcie-designware.h
>> +++ b/drivers/pci/host/pcie-designware.h
>> @@ -27,25 +27,21 @@ struct pcie_port {
>>         u8                      root_bus_nr;
>>         void __iomem            *dbi_base;
>>         u64                     cfg0_base;
>> -       u64                     cfg0_mod_base;
>>         void __iomem            *va_cfg0_base;
>>         u32                     cfg0_size;
>>         u64                     cfg1_base;
>> -       u64                     cfg1_mod_base;
>>         void __iomem            *va_cfg1_base;
>>         u32                     cfg1_size;
>> -       u64                     io_base;
>> -       u64                     io_mod_base;
>> +       resource_size_t         io_base;
>>         phys_addr_t             io_bus_addr;
>>         u32                     io_size;
>>         u64                     mem_base;
>> -       u64                     mem_mod_base;
>>         phys_addr_t             mem_bus_addr;
>>         u32                     mem_size;
>> -       struct resource         cfg;
>> -       struct resource         io;
>> -       struct resource         mem;
>> -       struct resource         busn;
>> +       struct resource         *cfg;
>> +       struct resource         *io;
>> +       struct resource         *mem;
>> +       struct resource         *busn;
>>         int                     irq;
>>         u32                     lanes;
>>         struct pcie_host_ops    *ops;
>> --
>> 1.9.1
>>
>>
>> _______________________________________________
>> linux-arm-kernel mailing list
>> linux-arm-kernel at lists.infradead.org
>> http://lists.infradead.org/mailman/listinfo/linux-arm-kernel
> 
> .
> 




From heiko at sntech.de  Fri Aug 28 00:53:20 2015
From: heiko at sntech.de (Heiko Stuebner)
Date: Fri, 28 Aug 2015 09:53:20 +0200
Subject: [PATCH v1 2/3] pinctrl: rockchip: add support for the rk3036
In-Reply-To: <1440740808-15004-3-git-send-email-zhengxing@rock-chips.com>
References: <1440740808-15004-1-git-send-email-zhengxing@rock-chips.com>
 <1440740808-15004-3-git-send-email-zhengxing@rock-chips.com>
Message-ID: <2085107.a4DMzAYYyZ@phil>

Hi,

Am Freitag, 28. August 2015, 13:46:47 schrieb Xing Zheng:
> Many parts of pinctrl rk3036 are similar to rk2928's.
> 
> Signed-off-by: Xing Zheng <zhengxing at rock-chips.com>
> ---
> 
> Changes in v1: None
> 
>  drivers/pinctrl/pinctrl-rockchip.c |   17 +++++++++++++++++
>  1 file changed, 17 insertions(+)

please also add the new "rockchip,rk3036-pinctrl" compatible to 
Documentation/devicetree/pinctrl/rockchip,pinctrl.txt


I've checked the values against the rk3036 TRM and everything seems to fit, so 
with the missing compatible added to the binding you can add my

Reviewed-by: Heiko Stuebner <heiko at sntech.de>


Heiko


From alison.wang at freescale.com  Fri Aug 28 01:04:03 2015
From: alison.wang at freescale.com (Huan Wang)
Date: Fri, 28 Aug 2015 08:04:03 +0000
Subject: [PATCH v3] ARM: configs: Add Freescale LS1021A defconfig
In-Reply-To: <55D6073C.1020000@freescale.com>
References: <1438941784-38403-1-git-send-email-b18965@freescale.com>
 <55CB4829.40204@freescale.com> <55CE1FFE.2080200@freescale.com>
 <CAOMZO5By_15OCsb7z2pbywPi3n9vKGj=393hWYHVEQ32=jDNaA@mail.gmail.com>
 <BN3PR0301MB08672520CA978383BBF2CF6CFE790@BN3PR0301MB0867.namprd03.prod.outlook.com>
 <55D6073C.1020000@freescale.com>
Message-ID: <BN3PR0301MB0867591B07957C47F30C9711FE6E0@BN3PR0301MB0867.namprd03.prod.outlook.com>

Hi, Horia,

> On 8/17/2015 6:42 AM, Wang Huan-B18965 wrote:
> > Hi, Fabio,
> 
> Please don't top post.
> 
> >
> > 	Based on the analysis and discussion, we prefer to use
> ls1021a_defconfig and remove LS1021A from imx_v6_v7_defconfig.
> 
> Alison, when you submit v4 for this patch (adding
> CONFIG_ARCH_DMA_ADDR_T_64BIT=y as suggested), could you also send a
> patch removing CONFIG_SOC_LS1021A from imx_v6_v7_config?
[Alison Wang] I don?t know CONFIG_ARCH_DMA_ADDR_T_64BIT=y is suggested.
Could you help to explain the suggestion?

I need Fabio's confirmation about removing CONFIG_SOC_LS1021A from imx_v6_v7_config.

Fabio, Do you agree it?
> 
> >
> > 	Thanks.
> >
> > Best Regards,
> > Alison Wang
> >
> >> On Fri, Aug 14, 2015 at 2:06 PM, Horia Geant?
> >> <horia.geanta at freescale.com> wrote:
> >>
> >>> Another thing:
> >>> Commit 385c0fb0e2c4 ("ARM: imx_v6_v7_defconfig: Select LS1021A")
> >> added
> >>> CONFIG_SOC_LS1021A in imx_v6_v7_defconfig.
> >>>
> >>> Besides this, booting a LS1021 AQDS board (Rev2) using
> >>> imx_v6_v7_defconfig did not work (stuck at "Starting kernel").
> >>
> >> What would be the recommended approach?
> >>
> >> - Fix imx_v6_v7_defconfig so that it can make LS1021A to boot
> >>
> >> or
> >>
> >> - Use this proposed ls1021a_defconfig and remove LS1021A from
> >> imx_v6_v7_defconfig?
> >>
> >> Regards,
> >>
> >> Fabio Estevam
> 


From alexandre.belloni at free-electrons.com  Fri Aug 28 01:08:09 2015
From: alexandre.belloni at free-electrons.com (Alexandre Belloni)
Date: Fri, 28 Aug 2015 10:08:09 +0200
Subject: linux-next: manual merge of the rtc tree with the arm-soc tree
In-Reply-To: <20150827162229.10fe7255@canb.auug.org.au>
References: <20150827162229.10fe7255@canb.auug.org.au>
Message-ID: <20150828080809.GU13155@piout.net>

Hi Stephen,

On 27/08/2015 at 16:22:29 +1000, Stephen Rothwell wrote :
>   		clock-frequency = <12000000>;
>   	};
>   
>  +	sound0: sound at 0 {
>  +		compatible = "simple-audio-card";
>  +		simple-audio-card,name = "AM437x-GP-EVM";
>  +		simple-audio-card,widgets =
>  +			"Headphone", "Headphone Jack",
>  +			"Line", "Line In";
>  +		simple-audio-card,routing =
>  +			"Headphone Jack",	"HPLOUT",
>  +			"Headphone Jack",	"HPROUT",
>  +			"LINE1L",		"Line In",
>  +			"LINE1R",		"Line In";
>  +		simple-audio-card,format = "dsp_b";
>  +		simple-audio-card,bitclock-master = <&sound0_master>;
>  +		simple-audio-card,frame-master = <&sound0_master>;
>  +		simple-audio-card,bitclock-inversion;
>  +
>  +		simple-audio-card,cpu {
>  +			sound-dai = <&mcasp1>;
>  +			system-clock-frequency = <12000000>;
>  +		};
>  +
>  +		sound0_master: simple-audio-card,codec {
>  +			sound-dai = <&tlv320aic3106>;
>  +			system-clock-frequency = <12000000>;
>  +		};
>  +	};
> ++
> + 	/* fixed 32k external oscillator clock */
> + 	clk_32k_rtc: clk_32k_rtc {
> + 		#clock-cells = <0>;
> + 		compatible = "fixed-clock";
> + 		clock-frequency = <32768>;
> + 	};

It is just a matter of taste but maybe both oscillators/clocks can be
grouped.

-- 
Alexandre Belloni, Free Electrons
Embedded Linux, Kernel and Android engineering
http://free-electrons.com


From javier at osg.samsung.com  Fri Aug 28 01:16:09 2015
From: javier at osg.samsung.com (Javier Martinez Canillas)
Date: Fri, 28 Aug 2015 10:16:09 +0200
Subject: [PATCH] ARM: exynos_defconfig: Enable big.LITTLE CPUidle support
Message-ID: <1440749769-10135-1-git-send-email-javier@osg.samsung.com>

Some Exynos big.LITTLE boards (i.e: Exynos5420 and Exynos5800 based
Chromebooks) have proper firmware that allow the big.LITTLE CPUidle
driver to work correctly, so enable support for this.

Signed-off-by: Javier Martinez Canillas <javier at osg.samsung.com>

---
Kukjin and Krzysztof,

As you know there are other boards like the Exynos5422 based Odroid XU{3,4}
whose firmware is broken due leaving CCI in secure mode which means that the
kernel MCPM support can't properly manage CCI.

So if you pick this patch, it should be tested in kernelci before appearing
in linux-next to prevent any boot issues.

But if that happens, I believe that is better to do a fix / workaround in
those broken platforms since nothing prevents users to enable this option
anyways. For example the CCI device node could be disabled in the DTS.

 arch/arm/configs/exynos_defconfig | 1 +
 1 file changed, 1 insertion(+)

diff --git a/arch/arm/configs/exynos_defconfig b/arch/arm/configs/exynos_defconfig
index 729e2fae3e58..228ee945b8ed 100644
--- a/arch/arm/configs/exynos_defconfig
+++ b/arch/arm/configs/exynos_defconfig
@@ -30,6 +30,7 @@ CONFIG_CPU_FREQ=y
 CONFIG_CPU_FREQ_DEFAULT_GOV_ONDEMAND=y
 CONFIG_CPUFREQ_DT=y
 CONFIG_CPU_IDLE=y
+CONFIG_ARM_BIG_LITTLE_CPUIDLE=y
 CONFIG_ARM_EXYNOS_CPUIDLE=y
 CONFIG_VFP=y
 CONFIG_NEON=y
-- 
2.4.3



From eddie.cai.kernel at gmail.com  Fri Aug 28 01:36:33 2015
From: eddie.cai.kernel at gmail.com (Eddie Cai)
Date: Fri, 28 Aug 2015 16:36:33 +0800
Subject: [PATCH v1 1/3] ARM: dts: rockchip: add core rk3036 dts
In-Reply-To: <1440740808-15004-2-git-send-email-zhengxing@rock-chips.com>
References: <1440740808-15004-1-git-send-email-zhengxing@rock-chips.com>
 <1440740808-15004-2-git-send-email-zhengxing@rock-chips.com>
Message-ID: <CANCyOWa9dy-gg27j8v7QGTvkrVzvMVhP3z_d2vdwXAkgP_3EjA@mail.gmail.com>

Hi ZhengXing

You should have two file for dts part. One is rk3036.dtsi for soc. The
other one is rk3036-sdk.dts for board.

2015-08-28 13:46 GMT+08:00 Xing Zheng <zhengxing at rock-chips.com>:
> Initial release for rk3036, node definitions rk3036 sdk board.
>
> Signed-off-by: Xing Zheng <zhengxing at rock-chips.com>
> ---
>
> Changes in v1: None
>
>  arch/arm/boot/dts/Makefile       |    1 +
>  arch/arm/boot/dts/rk3036-sdk.dts |  362 ++++++++++++++++++++++++++++++++++++++
>  2 files changed, 363 insertions(+)
>  create mode 100644 arch/arm/boot/dts/rk3036-sdk.dts
>
> diff --git a/arch/arm/boot/dts/Makefile b/arch/arm/boot/dts/Makefile
> index 6d7cec1..7014a3b 100644
> --- a/arch/arm/boot/dts/Makefile
> +++ b/arch/arm/boot/dts/Makefile
> @@ -501,6 +501,7 @@ dtb-$(CONFIG_ARCH_ROCKCHIP) += \
>         rk3066a-bqcurie2.dtb \
>         rk3066a-marsboard.dtb \
>         rk3066a-rayeager.dtb \
> +       rk3036-sdk.dtb \
>         rk3188-radxarock.dtb \
>         rk3288-evb-act8846.dtb \
>         rk3288-evb-rk808.dtb \
> diff --git a/arch/arm/boot/dts/rk3036-sdk.dts b/arch/arm/boot/dts/rk3036-sdk.dts
> new file mode 100644
> index 0000000..0149c9a
> --- /dev/null
> +++ b/arch/arm/boot/dts/rk3036-sdk.dts
> @@ -0,0 +1,362 @@
> +/*
> + * This file is dual-licensed: you can use it either under the terms
> + * of the GPL or the X11 license, at your option. Note that this dual
> + * licensing only applies to this file, and not this project as a
> + * whole.
> + *
> + *  a) This file is free software; you can redistribute it and/or
> + *     modify it under the terms of the GNU General Public License as
> + *     published by the Free Software Foundation; either version 2 of the
> + *     License, or (at your option) any later version.
> + *
> + *     This file is distributed in the hope that it will be useful,
> + *     but WITHOUT ANY WARRANTY; without even the implied warranty of
> + *     MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
> + *     GNU General Public License for more details.
> + *
> + * Or, alternatively,
> + *
> + *  b) Permission is hereby granted, free of charge, to any person
> + *     obtaining a copy of this software and associated documentation
> + *     files (the "Software"), to deal in the Software without
> + *     restriction, including without limitation the rights to use,
> + *     copy, modify, merge, publish, distribute, sublicense, and/or
> + *     sell copies of the Software, and to permit persons to whom the
> + *     Software is furnished to do so, subject to the following
> + *     conditions:
> + *
> + *     The above copyright notice and this permission notice shall be
> + *     included in all copies or substantial portions of the Software.
> + *
> + *     THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
> + *     EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES
> + *     OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
> + *     NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT
> + *     HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY,
> + *     WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
> + *     FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR
> + *     OTHER DEALINGS IN THE SOFTWARE.
> + */
> +
> +/dts-v1/;
> +
> +#include <dt-bindings/gpio/gpio.h>
> +#include <dt-bindings/interrupt-controller/irq.h>
> +#include <dt-bindings/interrupt-controller/arm-gic.h>
> +#include <dt-bindings/pinctrl/rockchip.h>
> +#include <dt-bindings/clock/rk3036-cru.h>
> +#include "skeleton.dtsi"
> +
> +/ {
> +       compatible = "rockchip,rk3036";
> +
> +       interrupt-parent = <&gic>;
> +
> +       aliases {
> +               serial0 = &uart0;
> +               serial1 = &uart1;
> +               serial2 = &uart2;
> +       };
> +
> +       memory {
> +               reg = <0x60000000 0x40000000>;
> +       };
> +
> +        arm-pmu {
> +                compatible = "arm,cortex-a7-pmu";
> +                interrupts = <GIC_SPI 76 IRQ_TYPE_LEVEL_HIGH>,
> +                             <GIC_SPI 77 IRQ_TYPE_LEVEL_HIGH>;
> +        };
> +
> +       cpus {
> +               #address-cells = <1>;
> +               #size-cells = <0>;
> +               //enable-method = "rockchip,rk3066-smp";
> +
> +               cpu at f00 {
> +                       device_type = "cpu";
> +                       compatible = "arm,cortex-a7";
> +                       reg = <0xf00>;
> +                       operating-points = <
> +                               /* KHz    uV */
> +                                816000 1000000
> +                       >;
> +                       #cooling-cells = <2>; /* min followed by max */
> +                       clock-latency = <40000>;
> +                       clocks = <&cru ARMCLK>;
> +                       resets = <&cru SRST_CORE0>;
> +               };
> +               cpu at f01 {
> +                       device_type = "cpu";
> +                       compatible = "arm,cortex-a7";
> +                       reg = <0xf01>;
> +                       resets = <&cru SRST_CORE1>;
> +               };
> +       };
> +
> +       amba {
> +               compatible = "arm,amba-bus";
> +               #address-cells = <1>;
> +               #size-cells = <1>;
> +               ranges;
> +
> +                pdma: pdma at 20078000 {
> +                        compatible = "arm,pl330", "arm,primecell";
> +                        reg = <0x20078000 0x4000>;
> +                        interrupts = <GIC_SPI 0 IRQ_TYPE_LEVEL_HIGH>,
> +                                     <GIC_SPI 1 IRQ_TYPE_LEVEL_HIGH>;
> +                        #dma-cells = <1>;
> +                        clocks = <&cru ACLK_DMAC2>;
> +                        clock-names = "apb_pclk";
> +                };
> +       };
> +
> +       xin24m: oscillator {
> +               compatible = "fixed-clock";
> +               clock-frequency = <24000000>;
> +               clock-output-names = "xin24m";
> +               #clock-cells = <0>;
> +       };
> +
> +       timer {
> +               compatible = "arm,armv7-timer";
> +               arm,cpu-registers-not-fw-configured;
> +               interrupts = <GIC_PPI 13 (GIC_CPU_MASK_SIMPLE(4) | IRQ_TYPE_LEVEL_HIGH)>,
> +                            <GIC_PPI 14 (GIC_CPU_MASK_SIMPLE(4) | IRQ_TYPE_LEVEL_HIGH)>;
> +               clock-frequency = <24000000>;
> +               always-on;
> +       };
> +
> +       cru: clock-controller at 20000000 {
> +               compatible = "rockchip,rk3036-cru";
> +               reg = <0x20000000 0x1000>;
> +               rockchip,grf = <&grf>;
> +               #clock-cells = <1>;
> +               #reset-cells = <1>;
> +               assigned-clocks = <&cru PLL_GPLL>;
> +               assigned-clock-rates = <594000000>;
> +       };
> +
> +       uart0: serial at 20060000 {
> +               compatible = "rockchip,rk3036-uart", "snps,dw-apb-uart";
> +               reg = <0x20060000 0x100>;
> +               interrupts = <GIC_SPI 20 IRQ_TYPE_LEVEL_HIGH>;
> +               reg-shift = <2>;
> +               reg-io-width = <4>;
> +               clock-frequency = <24000000>;
> +               clocks = <&cru SCLK_UART0>, <&cru PCLK_UART0>;
> +               clock-names = "baudclk", "apb_pclk";
> +               pinctrl-names = "default";
> +               pinctrl-0 = <&uart0_xfer &uart0_cts &uart0_rts>;
> +       };
> +
> +       uart1: serial at 20064000 {
> +               compatible = "rockchip,rk3036-uart", "snps,dw-apb-uart";
> +               reg = <0x20064000 0x100>;
> +               interrupts = <GIC_SPI 21 IRQ_TYPE_LEVEL_HIGH>;
> +               reg-shift = <2>;
> +               reg-io-width = <4>;
> +               clock-frequency = <24000000>;
> +               clocks = <&cru SCLK_UART1>, <&cru PCLK_UART1>;
> +               clock-names = "baudclk", "apb_pclk";
> +               pinctrl-names = "default";
> +               pinctrl-0 = <&uart1_xfer>;
> +       };
> +
> +       uart2: serial at 20068000 {
> +               compatible = "rockchip,rk3036-uart", "snps,dw-apb-uart";
> +               reg = <0x20068000 0x100>;
> +               interrupts = <GIC_SPI 22 IRQ_TYPE_LEVEL_HIGH>;
> +               reg-shift = <2>;
> +               reg-io-width = <4>;
> +               clock-frequency = <24000000>;
> +               clocks = <&cru SCLK_UART2>, <&cru PCLK_UART2>;
> +               clock-names = "baudclk", "apb_pclk";
> +               pinctrl-names = "default";
> +               pinctrl-0 = <&uart2_xfer>;
> +       };
> +
> +       pwm0: pwm at 20050000 {
> +               compatible = "rockchip,rk2928-pwm";
> +               reg = <0x20050000 0x10>;
> +               #pwm-cells = <3>;
> +               pinctrl-names = "default";
> +               pinctrl-0 = <&pwm0_pin>;
> +               clocks = <&cru PCLK_PWM>;
> +               clock-names = "pwm";
> +               status = "disabled";
> +       };
> +
> +       pwm1: pwm at 20050010 {
> +               compatible = "rockchip,rk2928-pwm";
> +               reg = <0x20050010 0x10>;
> +               #pwm-cells = <3>;
> +               pinctrl-names = "default";
> +               pinctrl-0 = <&pwm1_pin>;
> +               clocks = <&cru PCLK_PWM>;
> +               clock-names = "pwm";
> +               status = "disabled";
> +       };
> +
> +       pwm2: pwm at 20050020 {
> +               compatible = "rockchip,rk2928-pwm";
> +               reg = <0x20050020 0x10>;
> +               #pwm-cells = <3>;
> +               pinctrl-names = "default";
> +               pinctrl-0 = <&pwm2_pin>;
> +               clocks = <&cru PCLK_PWM>;
> +               clock-names = "pwm";
> +               status = "disabled";
> +       };
> +
> +       pwm3: pwm at 20050030 {
> +               compatible = "rockchip,rk2928-pwm";
> +               reg = <0x20050030 0x10>;
> +               #pwm-cells = <2>;
> +               pinctrl-names = "default";
> +               pinctrl-0 = <&pwm3_pin>;
> +               clocks = <&cru PCLK_PWM>;
> +               clock-names = "pwm";
> +               status = "disabled";
> +       };
> +
> +       sram at 10080000 {
> +               compatible = "mmio-sram";
> +               reg = <0x10080000 0x2000>;
> +               map-exec;
> +       };
> +
> +       gic: interrupt-controller at 10139000 {
> +               compatible = "arm,gic-400";
> +               interrupt-controller;
> +               #interrupt-cells = <3>;
> +               #address-cells = <0>;
> +
> +               reg = <0x10139000 0x1000>,
> +                     <0x1013a000 0x1000>;
> +       };
> +
> +       grf: syscon at 20008000 {
> +               compatible = "rockchip,rk3036-grf", "syscon";
> +               reg = <0x20008000 0x1000>;
> +       };
> +
> +       pinctrl: pinctrl {
> +               compatible = "rockchip,rk3036-pinctrl";
> +               rockchip,grf = <&grf>;
> +               #address-cells = <1>;
> +               #size-cells = <1>;
> +               ranges;
> +
> +               gpio0: gpio0 at 2007c000 {
> +                       compatible = "rockchip,gpio-bank";
> +                       reg =   <0x2007c000 0x100>;
> +                       interrupts = <GIC_SPI 36 IRQ_TYPE_LEVEL_HIGH>;
> +                       clocks = <&cru PCLK_GPIO0>;
> +
> +                       gpio-controller;
> +                       #gpio-cells = <2>;
> +
> +                       interrupt-controller;
> +                       #interrupt-cells = <2>;
> +               };
> +
> +               gpio1: gpio1 at 20080000 {
> +                       compatible = "rockchip,gpio-bank";
> +                       reg = <0x20080000 0x100>;
> +                       interrupts = <GIC_SPI 37 IRQ_TYPE_LEVEL_HIGH>;
> +                       clocks = <&cru PCLK_GPIO1>;
> +
> +                       gpio-controller;
> +                       #gpio-cells = <2>;
> +
> +                       interrupt-controller;
> +                       #interrupt-cells = <2>;
> +               };
> +
> +               gpio2: gpio2 at 20084000 {
> +                       compatible = "rockchip,gpio-bank";
> +                       reg = <0x20084000 0x100>;
> +                       interrupts = <GIC_SPI 38 IRQ_TYPE_LEVEL_HIGH>;
> +                       clocks = <&cru PCLK_GPIO2>;
> +
> +                       gpio-controller;
> +                       #gpio-cells = <2>;
> +
> +                       interrupt-controller;
> +                       #interrupt-cells = <2>;
> +               };
> +
> +               pcfg_pull_up: pcfg-pull-up {
> +                       bias-pull-up;
> +               };
> +
> +               pcfg_pull_down: pcfg-pull-down {
> +                       bias-pull-down;
> +               };
> +
> +               pcfg_pull_none: pcfg-pull-none {
> +                       bias-disable;
> +               };
> +
> +               pcfg_pull_none_12ma: pcfg-pull-none-12ma {
> +                       bias-disable;
> +                       drive-strength = <12>;
> +               };
> +
> +               uart0 {
> +                       uart0_xfer: uart0-xfer {
> +                               rockchip,pins = <0 16 RK_FUNC_1 &pcfg_pull_none>,
> +                                               <0 17 RK_FUNC_1 &pcfg_pull_none>;
> +                       };
> +
> +                       uart0_cts: uart0-cts {
> +                               rockchip,pins = <0 18 RK_FUNC_1 &pcfg_pull_none>;
> +                       };
> +
> +                       uart0_rts: uart0-rts {
> +                               rockchip,pins = <0 19 RK_FUNC_1 &pcfg_pull_none>;
> +                       };
> +               };
> +
> +               uart1 {
> +                       uart1_xfer: uart1-xfer {
> +                               rockchip,pins = <2 22 RK_FUNC_1 &pcfg_pull_none>,
> +                                               <2 23 RK_FUNC_1 &pcfg_pull_none>;
> +                       };
> +                       /* no rts / cts for uart1 */
> +               };
> +
> +                uart2 {
> +                        uart2_xfer: uart2-xfer {
> +                                rockchip,pins = <1 18 RK_FUNC_2 &pcfg_pull_none>,
> +                                                <1 19 RK_FUNC_2 &pcfg_pull_none>;
> +                        };
> +                        /* no rts / cts for uart2 */
> +                };
> +
> +               pwm0 {
> +                       pwm0_pin: pwm0-pin {
> +                               rockchip,pins = <0 0 RK_FUNC_2 &pcfg_pull_none>;
> +                       };
> +               };
> +
> +               pwm1 {
> +                       pwm1_pin: pwm1-pin {
> +                               rockchip,pins = <0 1 RK_FUNC_2 &pcfg_pull_none>;
> +                       };
> +               };
> +
> +               pwm2 {
> +                       pwm2_pin: pwm2-pin {
> +                               rockchip,pins = <0 1 2 &pcfg_pull_none>;
> +                       };
> +               };
> +
> +               pwm3 {
> +                       pwm3_pin: pwm3-pin {
> +                               rockchip,pins = <0 27 1 &pcfg_pull_none>;
> +                       };
> +               };
> +       };
> +};
> --
> 1.7.9.5
>
>
>
> _______________________________________________
> Linux-rockchip mailing list
> Linux-rockchip at lists.infradead.org
> http://lists.infradead.org/mailman/listinfo/linux-rockchip


From m.szyprowski at samsung.com  Fri Aug 28 01:36:58 2015
From: m.szyprowski at samsung.com (Marek Szyprowski)
Date: Fri, 28 Aug 2015 10:36:58 +0200
Subject: [PATCH 1/2] ARM: dma-mapping: add missing range check in dma_mmap()
Message-ID: <1440751036-6585-1-git-send-email-m.szyprowski@samsung.com>

dma_mmap() function in IOMMU-based dma-mapping implementation lacked
a check for valid range of mmap parameters (offset and buffer size), what
might have caused access beyond the allocated buffer. This patch fixes
this issue.

Signed-off-by: Marek Szyprowski <m.szyprowski at samsung.com>
CC: stable at vger.kernel.org  # v3.6+
---
 arch/arm/mm/dma-mapping.c | 5 +++++
 1 file changed, 5 insertions(+)

diff --git a/arch/arm/mm/dma-mapping.c b/arch/arm/mm/dma-mapping.c
index cba12f34ff77..67ae0f2ed983 100644
--- a/arch/arm/mm/dma-mapping.c
+++ b/arch/arm/mm/dma-mapping.c
@@ -1413,12 +1413,17 @@ static int arm_iommu_mmap_attrs(struct device *dev, struct vm_area_struct *vma,
 	unsigned long uaddr = vma->vm_start;
 	unsigned long usize = vma->vm_end - vma->vm_start;
 	struct page **pages = __iommu_get_pages(cpu_addr, attrs);
+	unsigned long nr_pages = PAGE_ALIGN(size) >> PAGE_SHIFT;
+	unsigned long off = vma->vm_pgoff;
 
 	vma->vm_page_prot = __get_dma_pgprot(attrs, vma->vm_page_prot);
 
 	if (!pages)
 		return -ENXIO;
 
+	if (off >= nr_pages || (usize >> PAGE_SHIFT) > nr_pages - off)
+		return -ENXIO;
+
 	do {
 		int ret = vm_insert_page(vma, uaddr, *pages++);
 		if (ret) {
-- 
1.9.2



From m.szyprowski at samsung.com  Fri Aug 28 01:36:59 2015
From: m.szyprowski at samsung.com (Marek Szyprowski)
Date: Fri, 28 Aug 2015 10:36:59 +0200
Subject: [PATCH 2/2] ARM: dma-mapping: add support for offset parameter in
 dma_mmap()
In-Reply-To: <1440751036-6585-1-git-send-email-m.szyprowski@samsung.com>
References: <1440751036-6585-1-git-send-email-m.szyprowski@samsung.com>
Message-ID: <1440751036-6585-2-git-send-email-m.szyprowski@samsung.com>

IOMMU-based dma_mmap() implementation lacked proper support for offset
parameter used in mmap call (it always assumed that mapping starts from
offset zero). This patch adds support for offset parameter to IOMMU-based
implementation.

Signed-off-by: Marek Szyprowski <m.szyprowski at samsung.com>
CC: stable at vger.kernel.org  # v3.6+
---
 arch/arm/mm/dma-mapping.c | 2 ++
 1 file changed, 2 insertions(+)

diff --git a/arch/arm/mm/dma-mapping.c b/arch/arm/mm/dma-mapping.c
index 67ae0f2ed983..25ecc6afec4c 100644
--- a/arch/arm/mm/dma-mapping.c
+++ b/arch/arm/mm/dma-mapping.c
@@ -1424,6 +1424,8 @@ static int arm_iommu_mmap_attrs(struct device *dev, struct vm_area_struct *vma,
 	if (off >= nr_pages || (usize >> PAGE_SHIFT) > nr_pages - off)
 		return -ENXIO;
 
+	pages += off;
+
 	do {
 		int ret = vm_insert_page(vma, uaddr, *pages++);
 		if (ret) {
-- 
1.9.2



From leif.lindholm at linaro.org  Fri Aug 28 01:39:41 2015
From: leif.lindholm at linaro.org (Leif Lindholm)
Date: Fri, 28 Aug 2015 09:39:41 +0100
Subject: [PATCH 1/4] x86, efi, kasan: #undef memset/memcpy/memmove per
 arch.
In-Reply-To: <20150828062745.GB1928@gmail.com>
References: <1440605707-8325-1-git-send-email-ryabinin.a.a@gmail.com>
 <1440605707-8325-2-git-send-email-ryabinin.a.a@gmail.com>
 <20150828062745.GB1928@gmail.com>
Message-ID: <20150828083941.GN10728@bivouac.eciton.net>

On Fri, Aug 28, 2015 at 08:27:45AM +0200, Ingo Molnar wrote:
> 
> * Andrey Ryabinin <ryabinin.a.a at gmail.com> wrote:
> 
> > In not-instrumented code KASAN replaces instrumented
> > memset/memcpy/memmove with not-instrumented analogues
> > __memset/__memcpy/__memove.
> > However, on x86 EFI stub is not linked with kernel.
> 
> s/with the kernel
> 
> > It uses not-instrumented mem*() functions from
> > arch/x86/boot/compressed/string.c
> > So we don't replace them with __mem*() variants in EFI stub.
> > 
> > In ARM64 EFI stub is linked with the kernel, so we should
> 
> s/In ARM64 EFI stub/On ARM64 the EFI stub/.
> 
> > replace mem*() functions with __mem*(), because EFI stub
> 
> s/the EFI stub
> 
> > runs before KASAN setup early shadow.
> 
> s/before KASAN sets up the early shadow
> 
> ?
> 
> > So let's move these #undef mem* into arch's asm/efi.h which is
> 
> s/lets

No, that one is actually correct. Abbreviation of let us.
 
> > also included by EFI stub.
> 
> s/by the EFI stub
> 
> > 
> > Signed-off-by: Andrey Ryabinin <ryabinin.a.a at gmail.com>
> > ---
> >  arch/x86/include/asm/efi.h             | 8 ++++++++
> >  drivers/firmware/efi/libstub/efistub.h | 4 ----
> >  2 files changed, 8 insertions(+), 4 deletions(-)
> > 
> > diff --git a/arch/x86/include/asm/efi.h b/arch/x86/include/asm/efi.h
> > index 155162e..d821ce2 100644
> > --- a/arch/x86/include/asm/efi.h
> > +++ b/arch/x86/include/asm/efi.h
> > @@ -25,6 +25,14 @@
> >  #define EFI32_LOADER_SIGNATURE	"EL32"
> >  #define EFI64_LOADER_SIGNATURE	"EL64"
> >  
> > +/*
> > + * Use memcpy/memset from arch/x86/boot/compressed/string.c
> > + * for EFI stub.
> > + */
> > +#undef memcpy
> > +#undef memset
> > +#undef memmove
> 
> This comment should also mention why it's done, not what is done.
> 
> Also:
> 
>     s/for EFI stub/for the EFI stub
> 
> Thanks,
> 
> 	Ingo
> --
> To unsubscribe from this list: send the line "unsubscribe linux-efi" in
> the body of a message to majordomo at vger.kernel.org
> More majordomo info at  http://vger.kernel.org/majordomo-info.html


From horia.geanta at freescale.com  Fri Aug 28 01:50:29 2015
From: horia.geanta at freescale.com (=?UTF-8?Q?Horia_Geant=c4=83?=)
Date: Fri, 28 Aug 2015 11:50:29 +0300
Subject: [PATCH v3] ARM: configs: Add Freescale LS1021A defconfig
In-Reply-To: <BN3PR0301MB0867591B07957C47F30C9711FE6E0@BN3PR0301MB0867.namprd03.prod.outlook.com>
References: <1438941784-38403-1-git-send-email-b18965@freescale.com>
 <55CB4829.40204@freescale.com> <55CE1FFE.2080200@freescale.com>
 <CAOMZO5By_15OCsb7z2pbywPi3n9vKGj=393hWYHVEQ32=jDNaA@mail.gmail.com>
 <BN3PR0301MB08672520CA978383BBF2CF6CFE790@BN3PR0301MB0867.namprd03.prod.outlook.com>
 <55D6073C.1020000@freescale.com>
 <BN3PR0301MB0867591B07957C47F30C9711FE6E0@BN3PR0301MB0867.namprd03.prod.outlook.com>
Message-ID: <55E020D5.4090201@freescale.com>

On 8/28/2015 11:04 AM, Wang Huan-B18965 wrote:
> Hi, Horia,
> 
>> On 8/17/2015 6:42 AM, Wang Huan-B18965 wrote:
>>> Hi, Fabio,
>>
>> Please don't top post.
>>
>>>
>>> 	Based on the analysis and discussion, we prefer to use
>> ls1021a_defconfig and remove LS1021A from imx_v6_v7_defconfig.
>>
>> Alison, when you submit v4 for this patch (adding
>> CONFIG_ARCH_DMA_ADDR_T_64BIT=y as suggested), could you also send a
>> patch removing CONFIG_SOC_LS1021A from imx_v6_v7_config?
> [Alison Wang] I don?t know CONFIG_ARCH_DMA_ADDR_T_64BIT=y is suggested.
> Could you help to explain the suggestion?

Please see
http://lists.infradead.org/pipermail/linux-arm-kernel/2011-November/072446.html

Instead of having CONFIG_ARCH_DMA_ADDR_T_64BIT=y in the defconfig, I
guess selecting it from Kconfig makes more sense:

diff --git a/arch/arm/mach-imx/Kconfig b/arch/arm/mach-imx/Kconfig
index 573536f1bb73..bb417e73af0f 100644
--- a/arch/arm/mach-imx/Kconfig
+++ b/arch/arm/mach-imx/Kconfig
@@ -563,6 +563,7 @@ config SOC_LS1021A
        select HAVE_ARM_ARCH_TIMER
        select PCI_DOMAINS if PCI
        select ZONE_DMA if ARM_LPAE
+       select ARCH_DMA_ADDR_T_64BIT
        help
          This enables support for Freescale LS1021A processor.

Horia



From sjoerd.simons at collabora.co.uk  Fri Aug 28 01:51:42 2015
From: sjoerd.simons at collabora.co.uk (Sjoerd Simons)
Date: Fri, 28 Aug 2015 10:51:42 +0200
Subject: [PATCH] ARM: exynos_defconfig: Enable big.LITTLE CPUidle support
In-Reply-To: <1440749769-10135-1-git-send-email-javier@osg.samsung.com>
References: <1440749769-10135-1-git-send-email-javier@osg.samsung.com>
Message-ID: <1440751902.13118.6.camel@collabora.co.uk>

On Fri, 2015-08-28 at 10:16 +0200, Javier Martinez Canillas wrote:
> Some Exynos big.LITTLE boards (i.e: Exynos5420 and Exynos5800 based
> Chromebooks) have proper firmware that allow the big.LITTLE CPUidle
> driver to work correctly, so enable support for this.
> 
> Signed-off-by: Javier Martinez Canillas <javier at osg.samsung.com>
> 
> ---
> Kukjin and Krzysztof,
> 
> As you know there are other boards like the Exynos5422 based Odroid 
> XU{3,4}
> whose firmware is broken due leaving CCI in secure mode which means 
> that the
> kernel MCPM support can't properly manage CCI.
> 
> So if you pick this patch, it should be tested in kernelci before 
> appearing
> in linux-next to prevent any boot issues.

I've pushed this patch into Collabora's for-next branch, which should
get picked up by kernelci soonish.

-- 
Sjoerd Simons
Collabora Ltd.


From robert.jarzmik at free.fr  Fri Aug 28 01:48:48 2015
From: robert.jarzmik at free.fr (Robert Jarzmik)
Date: Fri, 28 Aug 2015 10:48:48 +0200
Subject: [PATCH v2 10/21] ARM: pxa: magician: Add UDA1380 sound support
In-Reply-To: <55D65C32.6080503@tul.cz> (Petr Cvek's message of "Fri, 21 Aug
 2015 01:01:06 +0200")
References: <cover.1439843482.git.petr.cvek@tul.cz> <55D259B7.90703@tul.cz>
 <87h9nt68mm.fsf@belgarion.home> <55D65C32.6080503@tul.cz>
Message-ID: <87a8tb3ij3.fsf@belgarion.home>

Petr Cvek <petr.cvek at tul.cz> writes:

> Dne 20.8.2015 v 21:51 Robert Jarzmik napsal(a):
>> Petr Cvek <petr.cvek at tul.cz> writes:
>> 
>>> +/*
>>> + * Magician Audio controller
>>> + */
>>> +
>>> +static struct platform_device magician_audio_device = {
>>> +	.name = "magician-audio",
>> Is this already upstream or is it a submission in progress ? Other than that
>> detail, I'll queue it in a week probably.
>
> This one is problematic. Vanilla version did not work from at least 3.4 (where I
> started, but probably even more in past). Somewhere between 3.13 and ~4.1 there
> is a change which causes it to fail after driver reload (bad pointers I
> think). UDA codec routes are not constructed completely and in ~4.1 they are
> refused, there are some swapped control registers and bad DMA definitions. Oh
> and recording stopped to work too (maybe it is caused by that routes).
>
> I tried to send initial separate patches (for DMA and registers), but it got
> stuck somewhere (at least it is not in 4.2rcX and I sent them around start of
> this year).
>
> I can add some of these patches to this patchset (but I didn't started yet on
> failing reload, record and fixing the routes).

Ok, but not for this patchset. This would be an apart submission to sound/soc
and Mark Brown more likely.
So I presume my answer is "no, it is not upstream yet, it is a submission under
review". In that case, I'll take it in my "held" tree until you tell me your
patches have been queued up by Mark, and then I'll move them to the for-next
tree.

Cheers.

-- 
Robert

PS: For DMA registers, there will also be an impact by the dmaengine
conversion. I'd like to be joined to the sound/soc submission, to foresee the
conflicts.


From robert.jarzmik at free.fr  Fri Aug 28 01:49:36 2015
From: robert.jarzmik at free.fr (Robert Jarzmik)
Date: Fri, 28 Aug 2015 10:49:36 +0200
Subject: [PATCH v2 11/21] ARM: pxa: magician: Add MAX1586 Vcore regulator
 support
In-Reply-To: <55D655C5.40506@tul.cz> (Petr Cvek's message of "Fri, 21 Aug 2015
 00:33:41 +0200")
References: <cover.1439843482.git.petr.cvek@tul.cz> <55D259CC.6040307@tul.cz>
 <87pp2h69iy.fsf@belgarion.home> <55D655C5.40506@tul.cz>
Message-ID: <87613z3ihr.fsf@belgarion.home>

Petr Cvek <petr.cvek at tul.cz> writes:

> Dne 20.8.2015 v 21:32 Robert Jarzmik napsal(a):
>> Petr Cvek <petr.cvek at tul.cz> writes:
>> 
>>> Add support for MAX1586 Vcore regulator.
>>>
>>> Signed-off-by: Petr Cvek <petr.cvek at tul.cz>
>> I'll leave that for a week and if no objections queue it.
>> 
>> I would have expected a better commit message : for example, from your patch I
>> deduce magician has a 1587 regulator, not a 1586 one : that deserves a small
>> mention in the commit message. Moreover, the Maxim has 2 outputs : one is
>> connected to VCC_Core of the SoC, what about the other output ?  Is it unknown,
>> or do you know but don't use it ?
>> 
> You mean V6 - Usim? MAX1587 does not have this pin implemented. I will note it
> in commit message.
Excellent, thanks.

Cheers.

-- 
Robert


From heiko at sntech.de  Fri Aug 28 01:59:32 2015
From: heiko at sntech.de (Heiko Stuebner)
Date: Fri, 28 Aug 2015 10:59:32 +0200
Subject: [PATCH v1 1/3] ARM: dts: rockchip: add core rk3036 dts
In-Reply-To: <1440740808-15004-2-git-send-email-zhengxing@rock-chips.com>
References: <1440740808-15004-1-git-send-email-zhengxing@rock-chips.com>
 <1440740808-15004-2-git-send-email-zhengxing@rock-chips.com>
Message-ID: <1871781.cSEoq02CXi@phil>

Hi,

Am Freitag, 28. August 2015, 13:46:46 schrieb Xing Zheng:
> Initial release for rk3036, node definitions rk3036 sdk board.
> 
> Signed-off-by: Xing Zheng <zhengxing at rock-chips.com>
> ---
> 
> Changes in v1: None
> 
>  arch/arm/boot/dts/Makefile       |    1 +
>  arch/arm/boot/dts/rk3036-sdk.dts |  362
> ++++++++++++++++++++++++++++++++++++++ 2 files changed, 363 insertions(+)

as Eddie already said, please split into two files ... just look at the other 
Rockchip socs for inspiration :-)


>  create mode 100644 arch/arm/boot/dts/rk3036-sdk.dts
> 
> diff --git a/arch/arm/boot/dts/Makefile b/arch/arm/boot/dts/Makefile
> index 6d7cec1..7014a3b 100644
> --- a/arch/arm/boot/dts/Makefile
> +++ b/arch/arm/boot/dts/Makefile
> @@ -501,6 +501,7 @@ dtb-$(CONFIG_ARCH_ROCKCHIP) += \
>  	rk3066a-bqcurie2.dtb \
>  	rk3066a-marsboard.dtb \
>  	rk3066a-rayeager.dtb \
> +	rk3036-sdk.dtb \
>  	rk3188-radxarock.dtb \
>  	rk3288-evb-act8846.dtb \
>  	rk3288-evb-rk808.dtb \
> diff --git a/arch/arm/boot/dts/rk3036-sdk.dts
> b/arch/arm/boot/dts/rk3036-sdk.dts new file mode 100644
> index 0000000..0149c9a
> --- /dev/null
> +++ b/arch/arm/boot/dts/rk3036-sdk.dts
> @@ -0,0 +1,362 @@
> +/*
> + * This file is dual-licensed: you can use it either under the terms
> + * of the GPL or the X11 license, at your option. Note that this dual
> + * licensing only applies to this file, and not this project as a
> + * whole.
> + *
> + *  a) This file is free software; you can redistribute it and/or
> + *     modify it under the terms of the GNU General Public License as
> + *     published by the Free Software Foundation; either version 2 of the
> + *     License, or (at your option) any later version.
> + *
> + *     This file is distributed in the hope that it will be useful,
> + *     but WITHOUT ANY WARRANTY; without even the implied warranty of
> + *     MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
> + *     GNU General Public License for more details.
> + *
> + * Or, alternatively,
> + *
> + *  b) Permission is hereby granted, free of charge, to any person
> + *     obtaining a copy of this software and associated documentation
> + *     files (the "Software"), to deal in the Software without
> + *     restriction, including without limitation the rights to use,
> + *     copy, modify, merge, publish, distribute, sublicense, and/or
> + *     sell copies of the Software, and to permit persons to whom the
> + *     Software is furnished to do so, subject to the following
> + *     conditions:
> + *
> + *     The above copyright notice and this permission notice shall be
> + *     included in all copies or substantial portions of the Software.
> + *
> + *     THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
> + *     EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES
> + *     OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
> + *     NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT
> + *     HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY,
> + *     WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
> + *     FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR
> + *     OTHER DEALINGS IN THE SOFTWARE.
> + */
> +
> +/dts-v1/;
> +
> +#include <dt-bindings/gpio/gpio.h>
> +#include <dt-bindings/interrupt-controller/irq.h>
> +#include <dt-bindings/interrupt-controller/arm-gic.h>
> +#include <dt-bindings/pinctrl/rockchip.h>
> +#include <dt-bindings/clock/rk3036-cru.h>
> +#include "skeleton.dtsi"
> +
> +/ {
> +	compatible = "rockchip,rk3036";
> +
> +	interrupt-parent = <&gic>;
> +
> +	aliases {
> +		serial0 = &uart0;
> +		serial1 = &uart1;
> +		serial2 = &uart2;
> +	};
> +
> +	memory {
> +		reg = <0x60000000 0x40000000>;

missing
	device_type = "memory";


> +	};
> +
> +        arm-pmu {
> +                compatible = "arm,cortex-a7-pmu";
> +                interrupts = <GIC_SPI 76 IRQ_TYPE_LEVEL_HIGH>,
> +                             <GIC_SPI 77 IRQ_TYPE_LEVEL_HIGH>;

missing interrupt-affinity to map irq->cpu_core ?


> +        };
> +
> +	cpus {
> +		#address-cells = <1>;
> +		#size-cells = <0>;
> +		//enable-method = "rockchip,rk3066-smp";

please don't leave commented code around


> +
> +		cpu at f00 {
> +			device_type = "cpu";
> +			compatible = "arm,cortex-a7";
> +			reg = <0xf00>;
> +			operating-points = <
> +				/* KHz    uV */
> +				 816000 1000000
> +			>;
> +			#cooling-cells = <2>; /* min followed by max */
> +			clock-latency = <40000>;
> +			clocks = <&cru ARMCLK>;
> +			resets = <&cru SRST_CORE0>;
> +		};
> +		cpu at f01 {
> +			device_type = "cpu";
> +			compatible = "arm,cortex-a7";
> +			reg = <0xf01>;
> +			resets = <&cru SRST_CORE1>;
> +		};
> +	};
> +
> +	amba {
> +		compatible = "arm,amba-bus";
> +		#address-cells = <1>;
> +		#size-cells = <1>;
> +		ranges;
> +
> +                pdma: pdma at 20078000 {
> +                        compatible = "arm,pl330", "arm,primecell";
> +                        reg = <0x20078000 0x4000>;
> +                        interrupts = <GIC_SPI 0 IRQ_TYPE_LEVEL_HIGH>,
> +                                     <GIC_SPI 1 IRQ_TYPE_LEVEL_HIGH>;
> +                        #dma-cells = <1>;
> +                        clocks = <&cru ACLK_DMAC2>;
> +                        clock-names = "apb_pclk";
> +                };

indentation of the dma controller looks wrong


> +	};
> +
> +	xin24m: oscillator {
> +		compatible = "fixed-clock";
> +		clock-frequency = <24000000>;
> +		clock-output-names = "xin24m";
> +		#clock-cells = <0>;
> +	};
> +
> +	timer {
> +		compatible = "arm,armv7-timer";
> +		arm,cpu-registers-not-fw-configured;
> +		interrupts = <GIC_PPI 13 (GIC_CPU_MASK_SIMPLE(4) | 
IRQ_TYPE_LEVEL_HIGH)>,
> +			     <GIC_PPI 14 (GIC_CPU_MASK_SIMPLE(4) | 
IRQ_TYPE_LEVEL_HIGH)>;

please provide all 4 irqs (secure, non-secure, virtual and hypervisor)


> +		clock-frequency = <24000000>;
> +		always-on;
> +	};
> +
> +	cru: clock-controller at 20000000 {
> +		compatible = "rockchip,rk3036-cru";
> +		reg = <0x20000000 0x1000>;
> +		rockchip,grf = <&grf>;
> +		#clock-cells = <1>;
> +		#reset-cells = <1>;
> +		assigned-clocks = <&cru PLL_GPLL>;
> +		assigned-clock-rates = <594000000>;
> +	};
> +
> +	uart0: serial at 20060000 {
> +		compatible = "rockchip,rk3036-uart", "snps,dw-apb-uart";
> +		reg = <0x20060000 0x100>;
> +		interrupts = <GIC_SPI 20 IRQ_TYPE_LEVEL_HIGH>;
> +		reg-shift = <2>;
> +		reg-io-width = <4>;
> +		clock-frequency = <24000000>;
> +		clocks = <&cru SCLK_UART0>, <&cru PCLK_UART0>;
> +		clock-names = "baudclk", "apb_pclk";
> +		pinctrl-names = "default";
> +		pinctrl-0 = <&uart0_xfer &uart0_cts &uart0_rts>;
> +	};
> +
> +	uart1: serial at 20064000 {
> +		compatible = "rockchip,rk3036-uart", "snps,dw-apb-uart";
> +		reg = <0x20064000 0x100>;
> +		interrupts = <GIC_SPI 21 IRQ_TYPE_LEVEL_HIGH>;
> +		reg-shift = <2>;
> +		reg-io-width = <4>;
> +		clock-frequency = <24000000>;
> +		clocks = <&cru SCLK_UART1>, <&cru PCLK_UART1>;
> +		clock-names = "baudclk", "apb_pclk";
> +		pinctrl-names = "default";
> +		pinctrl-0 = <&uart1_xfer>;
> +	};
> +
> +	uart2: serial at 20068000 {
> +		compatible = "rockchip,rk3036-uart", "snps,dw-apb-uart";
> +		reg = <0x20068000 0x100>;
> +		interrupts = <GIC_SPI 22 IRQ_TYPE_LEVEL_HIGH>;
> +		reg-shift = <2>;
> +		reg-io-width = <4>;
> +		clock-frequency = <24000000>;
> +		clocks = <&cru SCLK_UART2>, <&cru PCLK_UART2>;
> +		clock-names = "baudclk", "apb_pclk";
> +		pinctrl-names = "default";
> +		pinctrl-0 = <&uart2_xfer>;
> +	};
> +
> +	pwm0: pwm at 20050000 {
> +		compatible = "rockchip,rk2928-pwm";
> +		reg = <0x20050000 0x10>;
> +		#pwm-cells = <3>;
> +		pinctrl-names = "default";
> +		pinctrl-0 = <&pwm0_pin>;
> +		clocks = <&cru PCLK_PWM>;
> +		clock-names = "pwm";
> +		status = "disabled";
> +	};
> +
> +	pwm1: pwm at 20050010 {
> +		compatible = "rockchip,rk2928-pwm";
> +		reg = <0x20050010 0x10>;
> +		#pwm-cells = <3>;
> +		pinctrl-names = "default";
> +		pinctrl-0 = <&pwm1_pin>;
> +		clocks = <&cru PCLK_PWM>;
> +		clock-names = "pwm";
> +		status = "disabled";
> +	};
> +
> +	pwm2: pwm at 20050020 {
> +		compatible = "rockchip,rk2928-pwm";
> +		reg = <0x20050020 0x10>;
> +		#pwm-cells = <3>;
> +		pinctrl-names = "default";
> +		pinctrl-0 = <&pwm2_pin>;
> +		clocks = <&cru PCLK_PWM>;
> +		clock-names = "pwm";
> +		status = "disabled";
> +	};
> +
> +	pwm3: pwm at 20050030 {
> +		compatible = "rockchip,rk2928-pwm";
> +		reg = <0x20050030 0x10>;
> +		#pwm-cells = <2>;
> +		pinctrl-names = "default";
> +		pinctrl-0 = <&pwm3_pin>;
> +		clocks = <&cru PCLK_PWM>;
> +		clock-names = "pwm";
> +		status = "disabled";
> +	};
> +
> +	sram at 10080000 {
> +		compatible = "mmio-sram";
> +		reg = <0x10080000 0x2000>;
> +		map-exec;
> +	};
> +
> +	gic: interrupt-controller at 10139000 {
> +		compatible = "arm,gic-400";
> +		interrupt-controller;
> +		#interrupt-cells = <3>;
> +		#address-cells = <0>;
> +
> +		reg = <0x10139000 0x1000>,
> +		      <0x1013a000 0x1000>;

please also provide the vgic registers and interrupt


> +	};
> +
> +	grf: syscon at 20008000 {
> +		compatible = "rockchip,rk3036-grf", "syscon";
> +		reg = <0x20008000 0x1000>;
> +	};
> +
> +	pinctrl: pinctrl {
> +		compatible = "rockchip,rk3036-pinctrl";
> +		rockchip,grf = <&grf>;
> +		#address-cells = <1>;
> +		#size-cells = <1>;
> +		ranges;
> +
> +		gpio0: gpio0 at 2007c000 {
> +			compatible = "rockchip,gpio-bank";
> +			reg =	<0x2007c000 0x100>;

please use a space after the "=" in "reg = <..."


> +			interrupts = <GIC_SPI 36 IRQ_TYPE_LEVEL_HIGH>;
> +			clocks = <&cru PCLK_GPIO0>;
> +
> +			gpio-controller;
> +			#gpio-cells = <2>;
> +
> +			interrupt-controller;
> +			#interrupt-cells = <2>;
> +		};
> +
> +		gpio1: gpio1 at 20080000 {
> +			compatible = "rockchip,gpio-bank";
> +			reg = <0x20080000 0x100>;
> +			interrupts = <GIC_SPI 37 IRQ_TYPE_LEVEL_HIGH>;
> +			clocks = <&cru PCLK_GPIO1>;
> +
> +			gpio-controller;
> +			#gpio-cells = <2>;
> +
> +			interrupt-controller;
> +			#interrupt-cells = <2>;
> +		};
> +
> +		gpio2: gpio2 at 20084000 {
> +			compatible = "rockchip,gpio-bank";
> +			reg = <0x20084000 0x100>;
> +			interrupts = <GIC_SPI 38 IRQ_TYPE_LEVEL_HIGH>;
> +			clocks = <&cru PCLK_GPIO2>;
> +
> +			gpio-controller;
> +			#gpio-cells = <2>;
> +
> +			interrupt-controller;
> +			#interrupt-cells = <2>;
> +		};
> +
> +		pcfg_pull_up: pcfg-pull-up {
> +			bias-pull-up;
> +		};
> +
> +		pcfg_pull_down: pcfg-pull-down {
> +			bias-pull-down;
> +		};
> +
> +		pcfg_pull_none: pcfg-pull-none {
> +			bias-disable;
> +		};
> +
> +		pcfg_pull_none_12ma: pcfg-pull-none-12ma {
> +			bias-disable;
> +			drive-strength = <12>;
> +		};

The rk3036 iomux does not have a per-pin drive-strength setting it seems, so 
at the moment the pinctrl driver does not support changing the drive-strength, 
so this node should probably be dropped. It seems unused anyway.


> +
> +		uart0 {
> +			uart0_xfer: uart0-xfer {
> +				rockchip,pins = <0 16 RK_FUNC_1 &pcfg_pull_none>,
> +						<0 17 RK_FUNC_1 &pcfg_pull_none>;
> +			};
> +
> +			uart0_cts: uart0-cts {
> +				rockchip,pins = <0 18 RK_FUNC_1 &pcfg_pull_none>;
> +			};
> +
> +			uart0_rts: uart0-rts {
> +				rockchip,pins = <0 19 RK_FUNC_1 &pcfg_pull_none>;
> +			};
> +		};
> +
> +		uart1 {
> +			uart1_xfer: uart1-xfer {
> +				rockchip,pins = <2 22 RK_FUNC_1 &pcfg_pull_none>,
> +						<2 23 RK_FUNC_1 &pcfg_pull_none>;
> +			};
> +			/* no rts / cts for uart1 */
> +		};
> +
> +                uart2 {
> +                        uart2_xfer: uart2-xfer {
> +                                rockchip,pins = <1 18 RK_FUNC_2
> &pcfg_pull_none>, +                                                <1 19
> RK_FUNC_2 &pcfg_pull_none>; +                        };
> +                        /* no rts / cts for uart2 */
> +                };
> +
> +		pwm0 {
> +			pwm0_pin: pwm0-pin {
> +				rockchip,pins = <0 0 RK_FUNC_2 &pcfg_pull_none>;
> +			};
> +		};
> +
> +		pwm1 {
> +			pwm1_pin: pwm1-pin {
> +				rockchip,pins = <0 1 RK_FUNC_2 &pcfg_pull_none>;
> +			};
> +		};
> +
> +		pwm2 {
> +			pwm2_pin: pwm2-pin {
> +				rockchip,pins = <0 1 2 &pcfg_pull_none>;
> +			};
> +		};
> +
> +		pwm3 {
> +			pwm3_pin: pwm3-pin {
> +				rockchip,pins = <0 27 1 &pcfg_pull_none>;
> +			};
> +		};
> +	};
> +};



From yamada.masahiro at socionext.com  Fri Aug 28 01:59:54 2015
From: yamada.masahiro at socionext.com (Masahiro Yamada)
Date: Fri, 28 Aug 2015 17:59:54 +0900
Subject: [PATCH 1/3] ARM: uniphier: add outer cache support
In-Reply-To: <4027826.UsiXogeDbt@wuerfel>
References: <1440382692-3855-1-git-send-email-yamada.masahiro@socionext.com>
 <2021253.vgeYqalDfp@wuerfel>
 <CAK7LNAQ_oymnQNEcP+FDqyxNKtMyiCwgxSRMmg5HAKQW9C6eRg@mail.gmail.com>
 <4027826.UsiXogeDbt@wuerfel>
Message-ID: <CAK7LNATq3XQc=frE09g_DC_cq4fr79FcmrwFd9CXPeCds4GtcA@mail.gmail.com>

Hi Arnd, Russell,


2015-08-26 21:52 GMT+09:00 Arnd Bergmann <arnd at arndb.de>:
> On Wednesday 26 August 2015 10:38:59 Masahiro Yamada wrote:
>>
>> 2015-08-25 4:59 GMT+09:00 Arnd Bergmann <arnd at arndb.de>:
>> > On Monday 24 August 2015 11:18:10 Masahiro Yamada wrote:
>
>> Nothing.
>>
>> This outer cache is not a variant of l2x0/pl310.
>> It was designed only for our SoCs from scratch.
>
> Ok, I see.
>
>> > Would it make sense to at least share the
>> > common entry point at l2x0_of_init() so you don't need to call it from
>> > the platform file?
>>
>> I do not think so.
>>
>>
>> l2x0_of_init() checks L2X0_AUX_CTRL register,
>> but the cache-uniphier does not have such register,
>> so the boot code crashes.
>>
>>
>>
>> BTW, what makes l2x0_of_init() so special?
>>
>> Only L2x0/L310 and variants can be initialized
>> directly from init_IRQ().
>
> The only thing that is special about it is that almost everyone
> uses it because it is often licensed together with the Cortex-A
> cores from ARM. There are a few variants that are closely related
> (tauros3 and aurora, both from Marvell. All other outer_cache
> implementations (feroceon, xscale, tauros2) are for older
> Marvell (or Intel) cores that have since been replaced with
> Cortex-A cores in newer products.
>
>> Moreover, outer-cache init seems to be unrelated to
>> IRQ init.
>
> Agreed, this is also just a historic artifact, as we don't really
> have a place to put cache controller initialization, and the
> irq init callback was already there at the time when people
> added code to init their outer caches. It often does not matter
> much where you call it, but doing it early speeds up the boot
> time.
>
> It would be nice to unify the cache initialization a bit further,
> apparently only a few older platforms still call the l2x0 init
> manually and we can probably all convert them to the implicit
> configuration in one way or another.
>
> As we now have three kinds of cache controllers (l2x0, tauros2
> and uniphier) that we need to support using DT, it would be nice
> for generalize that init sequence a bit more.
>
> A first step would be to add the tauros2 and uniphier outer cache
> init to the init_IRQ() function, and then have another patch
> that moves all the outercache initialization into a new place
> like arch/arm/mm/outercache.c so we don't clutter up irq.c
> with unrelated stuff.
>
> Russell probably also has some ideas on this topic, in doubt
> just do what he suggests.

In my v1 patch, the outer cache init is called from .init_machine
as some other SoCs do, but if moving my cache_init to init_IRQ() is acceptable,
that would be better for faster boot.

I will follow Arnd's suggestion in v2 unless Russell is opposed to it.

Thanks!



-- 
Best Regards
Masahiro Yamada


From haibo.chen at freescale.com  Fri Aug 28 02:09:31 2015
From: haibo.chen at freescale.com (Haibo Chen)
Date: Fri, 28 Aug 2015 17:09:31 +0800
Subject: [PATCH v3 0/5] Add imx6ul touch screen controller support
Message-ID: <1440752976-9094-1-git-send-email-haibo.chen@freescale.com>

i.MX6UL contains a touch screen controller. This patch set add imx6ul
touch screen controller driver support.

Changes for v3:
-change GPIO xnur to active low.
-Add open and close API, and delete remove API.
-Use devm functions to allocate resource.
-Use gpiod method to request GPIO.

Changes for v2:
-Add property in devicetree documentation.
-Add tsc disable code in tsc_remove function.
-Remove some redundant code.

Haibo Chen (5):
  input: touchscreen: add imx6ul_tsc driver support
  Documentation: Detail permitted DT properties for the imx6ul_tsc
  ARM: imx_v6_v7_defconfig: enable imx6ul_tsc
  ARM: dts: imx6ul.dtsi: add TSC support
  ARM: dts: imx6ul-14x14-evk.dts: add tsc support

 .../bindings/input/touchscreen/imx6ul_tsc.txt      |  36 ++
 arch/arm/boot/dts/imx6ul-14x14-evk.dts             |  18 +
 arch/arm/boot/dts/imx6ul.dtsi                      |  11 +
 arch/arm/configs/imx_v6_v7_defconfig               |   1 +
 drivers/input/touchscreen/Kconfig                  |  12 +
 drivers/input/touchscreen/Makefile                 |   1 +
 drivers/input/touchscreen/imx6ul_tsc.c             | 524 +++++++++++++++++++++
 7 files changed, 603 insertions(+)
 create mode 100644 Documentation/devicetree/bindings/input/touchscreen/imx6ul_tsc.txt
 create mode 100644 drivers/input/touchscreen/imx6ul_tsc.c

-- 
1.9.1



From haibo.chen at freescale.com  Fri Aug 28 02:09:32 2015
From: haibo.chen at freescale.com (Haibo Chen)
Date: Fri, 28 Aug 2015 17:09:32 +0800
Subject: [PATCH v3 1/5] input: touchscreen: add imx6ul_tsc driver support
In-Reply-To: <1440752976-9094-1-git-send-email-haibo.chen@freescale.com>
References: <1440752976-9094-1-git-send-email-haibo.chen@freescale.com>
Message-ID: <1440752976-9094-2-git-send-email-haibo.chen@freescale.com>

Freescale i.MX6UL contains a internal touchscreen controller,
this patch add a driver to support this controller.

Signed-off-by: Haibo Chen <haibo.chen at freescale.com>
---
 drivers/input/touchscreen/Kconfig      |  12 +
 drivers/input/touchscreen/Makefile     |   1 +
 drivers/input/touchscreen/imx6ul_tsc.c | 524 +++++++++++++++++++++++++++++++++
 3 files changed, 537 insertions(+)
 create mode 100644 drivers/input/touchscreen/imx6ul_tsc.c

diff --git a/drivers/input/touchscreen/Kconfig b/drivers/input/touchscreen/Kconfig
index 059edeb..50a42b8 100644
--- a/drivers/input/touchscreen/Kconfig
+++ b/drivers/input/touchscreen/Kconfig
@@ -479,6 +479,18 @@ config TOUCHSCREEN_MTOUCH
 	  To compile this driver as a module, choose M here: the
 	  module will be called mtouch.
 
+config TOUCHSCREEN_IMX6UL_TSC
+	tristate "Freescale i.MX6UL touchscreen controller"
+	depends on (OF && GPIOLIB) || COMPILE_TEST
+	help
+	  Say Y here if you have a Freescale i.MX6UL, and want to
+	  use the internal touchscreen controller.
+
+	  If unsure, say N.
+
+	  To compile this driver as a module, choose M here: the
+	  moduel will be called imx6ul_tsc.
+
 config TOUCHSCREEN_INEXIO
 	tristate "iNexio serial touchscreens"
 	select SERIO
diff --git a/drivers/input/touchscreen/Makefile b/drivers/input/touchscreen/Makefile
index c85aae2..9379b32 100644
--- a/drivers/input/touchscreen/Makefile
+++ b/drivers/input/touchscreen/Makefile
@@ -38,6 +38,7 @@ obj-$(CONFIG_TOUCHSCREEN_EGALAX)	+= egalax_ts.o
 obj-$(CONFIG_TOUCHSCREEN_FUJITSU)	+= fujitsu_ts.o
 obj-$(CONFIG_TOUCHSCREEN_GOODIX)	+= goodix.o
 obj-$(CONFIG_TOUCHSCREEN_ILI210X)	+= ili210x.o
+obj-$(CONFIG_TOUCHSCREEN_IMX6UL_TSC)	+= imx6ul_tsc.o
 obj-$(CONFIG_TOUCHSCREEN_INEXIO)	+= inexio.o
 obj-$(CONFIG_TOUCHSCREEN_INTEL_MID)	+= intel-mid-touch.o
 obj-$(CONFIG_TOUCHSCREEN_IPROC)		+= bcm_iproc_tsc.o
diff --git a/drivers/input/touchscreen/imx6ul_tsc.c b/drivers/input/touchscreen/imx6ul_tsc.c
new file mode 100644
index 0000000..fe1d3d9
--- /dev/null
+++ b/drivers/input/touchscreen/imx6ul_tsc.c
@@ -0,0 +1,524 @@
+/*
+ * Freescale i.MX6UL touchscreen controller driver
+ *
+ * Copyright (C) 2015 Freescale Semiconductor, Inc.
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License version 2 as
+ * published by the Free Software Foundation.
+ */
+
+#include <linux/errno.h>
+#include <linux/kernel.h>
+#include <linux/module.h>
+#include <linux/gpio/consumer.h>
+#include <linux/input.h>
+#include <linux/slab.h>
+#include <linux/completion.h>
+#include <linux/delay.h>
+#include <linux/of.h>
+#include <linux/interrupt.h>
+#include <linux/platform_device.h>
+#include <linux/clk.h>
+#include <linux/io.h>
+
+/* ADC configuration registers field define */
+#define ADC_AIEN		(0x1 << 7)
+#define ADC_CONV_DISABLE	0x1F
+#define ADC_CAL			(0x1 << 7)
+#define ADC_CALF		0x2
+#define ADC_12BIT_MODE		(0x2 << 2)
+#define ADC_IPG_CLK		0x00
+#define ADC_CLK_DIV_8		(0x03 << 5)
+#define ADC_SHORT_SAMPLE_MODE	(0x0 << 4)
+#define ADC_HARDWARE_TRIGGER	(0x1 << 13)
+#define SELECT_CHANNEL_4	0x04
+#define SELECT_CHANNEL_1	0x01
+#define DISABLE_CONVERSION_INT	(0x0 << 7)
+
+/* ADC registers */
+#define REG_ADC_HC0		0x00
+#define REG_ADC_HC1		0x04
+#define REG_ADC_HC2		0x08
+#define REG_ADC_HC3		0x0C
+#define REG_ADC_HC4		0x10
+#define REG_ADC_HS		0x14
+#define REG_ADC_R0		0x18
+#define REG_ADC_CFG		0x2C
+#define REG_ADC_GC		0x30
+#define REG_ADC_GS		0x34
+
+#define ADC_TIMEOUT		msecs_to_jiffies(100)
+
+/* TSC registers */
+#define REG_TSC_BASIC_SETING	0x00
+#define REG_TSC_PRE_CHARGE_TIME	0x10
+#define REG_TSC_FLOW_CONTROL	0x20
+#define REG_TSC_MEASURE_VALUE	0x30
+#define REG_TSC_INT_EN		0x40
+#define REG_TSC_INT_SIG_EN	0x50
+#define REG_TSC_INT_STATUS	0x60
+#define REG_TSC_DEBUG_MODE	0x70
+#define REG_TSC_DEBUG_MODE2	0x80
+
+/* TSC configuration registers field define */
+#define DETECT_4_WIRE_MODE	(0x0 << 4)
+#define AUTO_MEASURE		0x1
+#define MEASURE_SIGNAL		0x1
+#define DETECT_SIGNAL		(0x1 << 4)
+#define VALID_SIGNAL		(0x1 << 8)
+#define MEASURE_INT_EN		0x1
+#define MEASURE_SIG_EN		0x1
+#define VALID_SIG_EN		(0x1 << 8)
+#define DE_GLITCH_2		(0x2 << 29)
+#define START_SENSE		(0x1 << 12)
+#define TSC_DISABLE		(0x1 << 16)
+#define DETECT_MODE		0x2
+
+struct imx6ul_tsc {
+	struct device *dev;
+	struct input_dev *input;
+	void __iomem *tsc_regs;
+	void __iomem *adc_regs;
+	struct clk *tsc_clk;
+	struct clk *adc_clk;
+	struct gpio_desc *xnur_gpio;
+
+	int measure_delay_time;
+	int pre_charge_time;
+
+	struct completion completion;
+};
+
+/*
+ * TSC module need ADC to get the measure value. So
+ * before config TSC, we should initialize ADC module.
+ */
+static void imx6ul_adc_init(struct imx6ul_tsc *tsc)
+{
+	int adc_hc = 0;
+	int adc_gc;
+	int adc_gs;
+	int adc_cfg;
+	int timeout;
+
+	reinit_completion(&tsc->completion);
+
+	adc_cfg = readl(tsc->adc_regs + REG_ADC_CFG);
+	adc_cfg |= ADC_12BIT_MODE | ADC_IPG_CLK;
+	adc_cfg |= ADC_CLK_DIV_8 | ADC_SHORT_SAMPLE_MODE;
+	adc_cfg &= ~ADC_HARDWARE_TRIGGER;
+	writel(adc_cfg, tsc->adc_regs + REG_ADC_CFG);
+
+	/* enable calibration interrupt */
+	adc_hc |= ADC_AIEN;
+	adc_hc |= ADC_CONV_DISABLE;
+	writel(adc_hc, tsc->adc_regs + REG_ADC_HC0);
+
+	/* start ADC calibration */
+	adc_gc = readl(tsc->adc_regs + REG_ADC_GC);
+	adc_gc |= ADC_CAL;
+	writel(adc_gc, tsc->adc_regs + REG_ADC_GC);
+
+	timeout = wait_for_completion_timeout
+			(&tsc->completion, ADC_TIMEOUT);
+	if (timeout == 0)
+		dev_err(tsc->dev, "Timeout for adc calibration\n");
+
+	adc_gs = readl(tsc->adc_regs + REG_ADC_GS);
+	if (adc_gs & ADC_CALF)
+		dev_err(tsc->dev, "ADC calibration failed\n");
+
+	/* TSC need the ADC work in hardware trigger */
+	adc_cfg = readl(tsc->adc_regs + REG_ADC_CFG);
+	adc_cfg |= ADC_HARDWARE_TRIGGER;
+	writel(adc_cfg, tsc->adc_regs + REG_ADC_CFG);
+}
+
+/*
+ * This is a TSC workaround. Currently TSC misconnect two
+ * ADC channels, this function remap channel configure for
+ * hardware trigger.
+ */
+static void imx6ul_tsc_channel_config(struct imx6ul_tsc *tsc)
+{
+	int adc_hc0, adc_hc1, adc_hc2, adc_hc3, adc_hc4;
+
+	adc_hc0 = DISABLE_CONVERSION_INT;
+	writel(adc_hc0, tsc->adc_regs + REG_ADC_HC0);
+
+	adc_hc1 = DISABLE_CONVERSION_INT | SELECT_CHANNEL_4;
+	writel(adc_hc1, tsc->adc_regs + REG_ADC_HC1);
+
+	adc_hc2 = DISABLE_CONVERSION_INT;
+	writel(adc_hc2, tsc->adc_regs + REG_ADC_HC2);
+
+	adc_hc3 = DISABLE_CONVERSION_INT | SELECT_CHANNEL_1;
+	writel(adc_hc3, tsc->adc_regs + REG_ADC_HC3);
+
+	adc_hc4 = DISABLE_CONVERSION_INT;
+	writel(adc_hc4, tsc->adc_regs + REG_ADC_HC4);
+}
+
+/*
+ * TSC setting, confige the pre-charge time and measure delay time.
+ * different touch screen may need different pre-charge time and
+ * measure delay time.
+ */
+static void imx6ul_tsc_set(struct imx6ul_tsc *tsc)
+{
+	int basic_setting = 0;
+	int start;
+
+	basic_setting |= tsc->measure_delay_time << 8;
+	basic_setting |= DETECT_4_WIRE_MODE | AUTO_MEASURE;
+	writel(basic_setting, tsc->tsc_regs + REG_TSC_BASIC_SETING);
+
+	writel(DE_GLITCH_2, tsc->tsc_regs + REG_TSC_DEBUG_MODE2);
+
+	writel(tsc->pre_charge_time, tsc->tsc_regs + REG_TSC_PRE_CHARGE_TIME);
+	writel(MEASURE_INT_EN, tsc->tsc_regs + REG_TSC_INT_EN);
+	writel(MEASURE_SIG_EN | VALID_SIG_EN,
+		tsc->tsc_regs + REG_TSC_INT_SIG_EN);
+
+	/* start sense detection */
+	start = readl(tsc->tsc_regs + REG_TSC_FLOW_CONTROL);
+	start |= START_SENSE;
+	start &= ~TSC_DISABLE;
+	writel(start, tsc->tsc_regs + REG_TSC_FLOW_CONTROL);
+}
+
+static void imx6ul_tsc_init(struct imx6ul_tsc *tsc)
+{
+	imx6ul_adc_init(tsc);
+	imx6ul_tsc_channel_config(tsc);
+	imx6ul_tsc_set(tsc);
+}
+
+static void imx6ul_tsc_disable(struct imx6ul_tsc *tsc)
+{
+	int tsc_flow;
+	int adc_cfg;
+
+	/* TSC controller enters to idle status */
+	tsc_flow = readl(tsc->tsc_regs + REG_TSC_FLOW_CONTROL);
+	tsc_flow |= TSC_DISABLE;
+	writel(tsc_flow, tsc->tsc_regs + REG_TSC_FLOW_CONTROL);
+
+	/* ADC controller enters to stop mode */
+	adc_cfg = readl(tsc->adc_regs + REG_ADC_HC0);
+	adc_cfg |= ADC_CONV_DISABLE;
+	writel(adc_cfg, tsc->adc_regs + REG_ADC_HC0);
+}
+
+static irqreturn_t tsc_irq_fn(int irq, void *dev_id)
+{
+	struct imx6ul_tsc *tsc = (struct imx6ul_tsc *)dev_id;
+	int status;
+	int value;
+	int x, y;
+	int debug_mode2;
+	int state_machine;
+	int start;
+	unsigned long timeout;
+	bool touch;
+
+	status = readl(tsc->tsc_regs + REG_TSC_INT_STATUS);
+
+	/* write 1 to clear the bit measure-signal */
+	writel(MEASURE_SIGNAL | DETECT_SIGNAL,
+		tsc->tsc_regs + REG_TSC_INT_STATUS);
+
+	/* It's a HW self-clean bit. Set this bit and start sense detection */
+	start = readl(tsc->tsc_regs + REG_TSC_FLOW_CONTROL);
+	start |= START_SENSE;
+	writel(start, tsc->tsc_regs + REG_TSC_FLOW_CONTROL);
+
+	if (status & MEASURE_SIGNAL) {
+		value = readl(tsc->tsc_regs + REG_TSC_MEASURE_VALUE);
+		x = (value >> 16) & 0x0fff;
+		y = value & 0x0fff;
+
+		/*
+		 * Delay some time(max 2ms), wait the pre-charge done.
+		 * After the pre-change mode, TSC go into detect mode.
+		 * And in detect mode, we can get the xnur gpio value.
+		 * If xnur is high, this means the touch screen still
+		 * be touched. If xnur is low, this means finger leave
+		 * the touch screen.
+		 */
+		timeout = jiffies + HZ/500;
+		do {
+			if (time_after(jiffies, timeout)) {
+				touch = true;
+				goto report_touch;
+			}
+			usleep_range(200, 400);
+			debug_mode2 = readl(tsc->tsc_regs + REG_TSC_DEBUG_MODE2);
+			state_machine = (debug_mode2 >> 20) & 0x7;
+		} while (state_machine != DETECT_MODE);
+		usleep_range(200, 400);
+
+		touch = gpiod_get_value_cansleep(tsc->xnur_gpio);
+report_touch:
+		if (touch) {
+			input_report_key(tsc->input, BTN_TOUCH, 1);
+			input_report_abs(tsc->input, ABS_X, x);
+			input_report_abs(tsc->input, ABS_Y, y);
+		} else {
+			input_report_key(tsc->input, BTN_TOUCH, 0);
+		}
+
+		input_sync(tsc->input);
+	}
+
+	return IRQ_HANDLED;
+}
+
+static irqreturn_t adc_irq_fn(int irq, void *dev_id)
+{
+	struct imx6ul_tsc *tsc = dev_id;
+	int coco;
+	int value;
+
+	coco = readl(tsc->adc_regs + REG_ADC_HS);
+	if (coco & 0x01) {
+		value = readl(tsc->adc_regs + REG_ADC_R0);
+		complete(&tsc->completion);
+	}
+
+	return IRQ_HANDLED;
+}
+
+static int imx6ul_tsc_open(struct input_dev *input_dev)
+{
+	struct imx6ul_tsc *tsc = input_get_drvdata(input_dev);
+	int err;
+
+	err = clk_prepare_enable(tsc->adc_clk);
+	if (err) {
+		dev_err(tsc->dev,
+			"Could not prepare or enable the adc clock: %d\n",
+			err);
+		return err;
+	}
+
+	err = clk_prepare_enable(tsc->tsc_clk);
+	if (err) {
+		dev_err(tsc->dev,
+			"Could not prepare or enable the tsc clock: %d\n",
+			err);
+		clk_disable_unprepare(tsc->adc_clk);
+		return err;
+	}
+
+	imx6ul_tsc_init(tsc);
+
+	return 0;
+}
+
+static void imx6ul_tsc_close(struct input_dev *input_dev)
+{
+	struct imx6ul_tsc *tsc = input_get_drvdata(input_dev);
+
+	imx6ul_tsc_disable(tsc);
+
+	clk_disable_unprepare(tsc->tsc_clk);
+	clk_disable_unprepare(tsc->adc_clk);
+}
+
+static int imx6ul_tsc_probe(struct platform_device *pdev)
+{
+	struct device_node *np = pdev->dev.of_node;
+	struct imx6ul_tsc *tsc;
+	struct input_dev *input_dev;
+	struct resource *tsc_mem;
+	struct resource *adc_mem;
+	int err;
+	int tsc_irq;
+	int adc_irq;
+
+	tsc = devm_kzalloc(&pdev->dev, sizeof(struct imx6ul_tsc), GFP_KERNEL);
+	if (!tsc)
+		return -ENOMEM;
+
+	input_dev = devm_input_allocate_device(&pdev->dev);
+	if (!input_dev)
+		return -ENOMEM;
+
+	input_dev->name = "iMX6UL TouchScreen Controller";
+	input_dev->id.bustype = BUS_HOST;
+
+	input_dev->open = imx6ul_tsc_open;
+	input_dev->close = imx6ul_tsc_close;
+
+	input_set_capability(input_dev, EV_KEY, BTN_TOUCH);
+	input_set_abs_params(input_dev, ABS_X, 0, 0xFFF, 0, 0);
+	input_set_abs_params(input_dev, ABS_Y, 0, 0xFFF, 0, 0);
+
+	input_set_drvdata(input_dev, tsc);
+
+	tsc->dev = &pdev->dev;
+	tsc->input = input_dev;
+	init_completion(&tsc->completion);
+
+	tsc->xnur_gpio = devm_gpiod_get(&pdev->dev, "xnur", GPIOD_IN);
+	if (IS_ERR(tsc->xnur_gpio)) {
+		err = PTR_ERR(tsc->xnur_gpio);
+		dev_err(&pdev->dev,
+			"failed to request GPIO tsc_X- (xnur): %d\n", err);
+		return err;
+	}
+
+	tsc_mem = platform_get_resource(pdev, IORESOURCE_MEM, 0);
+	tsc->tsc_regs = devm_ioremap_resource(&pdev->dev, tsc_mem);
+	if (IS_ERR(tsc->tsc_regs)) {
+		err = PTR_ERR(tsc->tsc_regs);
+		dev_err(&pdev->dev, "failed to remap tsc memory: %d\n", err);
+		return err;
+	}
+
+	adc_mem = platform_get_resource(pdev, IORESOURCE_MEM, 1);
+	tsc->adc_regs = devm_ioremap_resource(&pdev->dev, adc_mem);
+	if (IS_ERR(tsc->adc_regs)) {
+		err = PTR_ERR(tsc->adc_regs);
+		dev_err(&pdev->dev, "failed to remap adc memory: %d\n", err);
+		return err;
+	}
+
+	tsc->tsc_clk = devm_clk_get(&pdev->dev, "tsc");
+	if (IS_ERR(tsc->tsc_clk)) {
+		err = PTR_ERR(tsc->tsc_clk);
+		dev_err(&pdev->dev, "failed getting tsc clock: %d\n", err);
+		return err;
+	}
+
+	tsc->adc_clk = devm_clk_get(&pdev->dev, "adc");
+	if (IS_ERR(tsc->adc_clk)) {
+		err = PTR_ERR(tsc->adc_clk);
+		dev_err(&pdev->dev, "failed getting adc clock: %d\n", err);
+		return err;
+	}
+
+	tsc_irq = platform_get_irq(pdev, 0);
+	if (tsc_irq < 0) {
+		dev_err(&pdev->dev, "no tsc irq resource?\n");
+		return tsc_irq;
+	}
+
+	adc_irq = platform_get_irq(pdev, 1);
+	if (adc_irq <= 0) {
+		dev_err(&pdev->dev, "no adc irq resource?\n");
+		return adc_irq;
+	}
+
+	err = devm_request_threaded_irq(tsc->dev, tsc_irq,
+					NULL, tsc_irq_fn, IRQF_ONESHOT,
+					dev_name(&pdev->dev), tsc);
+	if (err) {
+		dev_err(&pdev->dev,
+			"failed requesting tsc irq %d: %d\n",
+			tsc_irq, err);
+		return err;
+	}
+
+	err = devm_request_irq(tsc->dev, adc_irq, adc_irq_fn, 0,
+				dev_name(&pdev->dev), tsc);
+	if (err) {
+		dev_err(&pdev->dev,
+			"failed requesting adc irq %d: %d\n",
+			adc_irq, err);
+		return err;
+	}
+
+	err = of_property_read_u32(np, "measure-delay-time",
+				   &tsc->measure_delay_time);
+	if (err)
+		tsc->measure_delay_time = 0xffff;
+
+	err = of_property_read_u32(np, "pre-charge-time",
+				   &tsc->pre_charge_time);
+	if (err)
+		tsc->pre_charge_time = 0xfff;
+
+	err = input_register_device(tsc->input);
+	if (err) {
+		dev_err(&pdev->dev,
+			"failed to register input device: %d\n", err);
+		return err;
+	}
+
+	platform_set_drvdata(pdev, tsc);
+	return 0;
+}
+
+static int __maybe_unused imx6ul_tsc_suspend(struct device *dev)
+{
+	struct platform_device *pdev = to_platform_device(dev);
+	struct imx6ul_tsc *tsc = platform_get_drvdata(pdev);
+	struct input_dev *input_dev = tsc->input;
+
+	mutex_lock(&input_dev->mutex);
+
+	if (input_dev->users) {
+		imx6ul_tsc_disable(tsc);
+
+		clk_disable_unprepare(tsc->tsc_clk);
+		clk_disable_unprepare(tsc->adc_clk);
+	}
+
+	mutex_unlock(&input_dev->mutex);
+
+	return 0;
+}
+
+static int __maybe_unused imx6ul_tsc_resume(struct device *dev)
+{
+	struct platform_device *pdev = to_platform_device(dev);
+	struct imx6ul_tsc *tsc = platform_get_drvdata(pdev);
+	struct input_dev *input_dev = tsc->input;
+	int retval = 0;
+
+	mutex_lock(&input_dev->mutex);
+
+	if (input_dev->users) {
+		retval = clk_prepare_enable(tsc->adc_clk);
+		if (retval)
+			goto out;
+
+		retval = clk_prepare_enable(tsc->tsc_clk);
+		if (retval) {
+			clk_disable_unprepare(tsc->adc_clk);
+			goto out;
+		}
+
+		imx6ul_tsc_init(tsc);
+	}
+
+out:
+	mutex_unlock(&input_dev->mutex);
+	return retval;
+}
+
+static SIMPLE_DEV_PM_OPS(imx6ul_tsc_pm_ops,
+			 imx6ul_tsc_suspend, imx6ul_tsc_resume);
+
+static const struct of_device_id imx6ul_tsc_match[] = {
+	{ .compatible = "fsl,imx6ul-tsc", },
+	{ /* sentinel */ }
+};
+MODULE_DEVICE_TABLE(of, imx6ul_tsc_match);
+
+static struct platform_driver imx6ul_tsc_driver = {
+	.driver		= {
+		.name	= "imx6ul-tsc",
+		.of_match_table	= imx6ul_tsc_match,
+		.pm	= &imx6ul_tsc_pm_ops,
+	},
+	.probe		= imx6ul_tsc_probe,
+};
+module_platform_driver(imx6ul_tsc_driver);
+
+MODULE_AUTHOR("Haibo Chen <haibo.chen at freescale.com>");
+MODULE_DESCRIPTION("Freescale i.MX6UL Touchscreen controller driver");
+MODULE_LICENSE("GPL v2");
-- 
1.9.1



From haibo.chen at freescale.com  Fri Aug 28 02:09:33 2015
From: haibo.chen at freescale.com (Haibo Chen)
Date: Fri, 28 Aug 2015 17:09:33 +0800
Subject: [PATCH v3 2/5] Documentation: Detail permitted DT properties for the
 imx6ul_tsc
In-Reply-To: <1440752976-9094-1-git-send-email-haibo.chen@freescale.com>
References: <1440752976-9094-1-git-send-email-haibo.chen@freescale.com>
Message-ID: <1440752976-9094-3-git-send-email-haibo.chen@freescale.com>

Here we apply required documentation for the imx6ul touch screen
controller driver which describe available properties and how to
use them.

Signed-off-by: Haibo Chen <haibo.chen at freescale.com>
---
 .../bindings/input/touchscreen/imx6ul_tsc.txt      | 36 ++++++++++++++++++++++
 1 file changed, 36 insertions(+)
 create mode 100644 Documentation/devicetree/bindings/input/touchscreen/imx6ul_tsc.txt

diff --git a/Documentation/devicetree/bindings/input/touchscreen/imx6ul_tsc.txt b/Documentation/devicetree/bindings/input/touchscreen/imx6ul_tsc.txt
new file mode 100644
index 0000000..853dff9
--- /dev/null
+++ b/Documentation/devicetree/bindings/input/touchscreen/imx6ul_tsc.txt
@@ -0,0 +1,36 @@
+* Freescale i.MX6UL Touch Controller
+
+Required properties:
+- compatible: must be "fsl,imx6ul-tsc".
+- reg: this touch controller address and the ADC2 address.
+- interrupts: the interrupt of this touch controller and ADC2.
+- clocks: the root clock of touch controller and ADC2.
+- clock-names; must be "tsc" and "adc".
+- xnur-gpio: the X- gpio this controller connect to.
+  This xnur-gpio returns to low once the finger leave the touch screen (The
+  last touch event the touch controller capture).
+
+Optional properties:
+- measure-delay-time: the value of measure delay time.
+  Before X-axis or Y-axis measurement, the screen need some time before
+  even potential distribution ready.
+  This value depends on the touch screen.
+- pre-charge-time: the touch screen need some time to precharge.
+  This value depends on the touch screen.
+
+Example:
+	tsc: tsc at 02040000 {
+		compatible = "fsl,imx6ul-tsc";
+		reg = <0x02040000 0x4000>, <0x0219c000 0x4000>;
+		interrupts = <GIC_SPI 3 IRQ_TYPE_LEVEL_HIGH>,
+			     <GIC_SPI 101 IRQ_TYPE_LEVEL_HIGH>;
+		clocks = <&clks IMX6UL_CLK_IPG>,
+			 <&clks IMX6UL_CLK_ADC2>;
+		clock-names = "tsc", "adc";
+		pinctrl-names = "default";
+		pinctrl-0 = <&pinctrl_tsc>;
+		xnur-gpio = <&gpio1 3 GPIO_ACTIVE_LOW>;
+		measure-delay-time = <0xfff>;
+		pre-charge-time = <0xffff>;
+		status = "okay";
+	};
-- 
1.9.1



From haibo.chen at freescale.com  Fri Aug 28 02:09:34 2015
From: haibo.chen at freescale.com (Haibo Chen)
Date: Fri, 28 Aug 2015 17:09:34 +0800
Subject: [PATCH v3 3/5] ARM: imx_v6_v7_defconfig: enable imx6ul_tsc
In-Reply-To: <1440752976-9094-1-git-send-email-haibo.chen@freescale.com>
References: <1440752976-9094-1-git-send-email-haibo.chen@freescale.com>
Message-ID: <1440752976-9094-4-git-send-email-haibo.chen@freescale.com>

Enable imx6ul touchscreen controller

Signed-off-by: Haibo Chen <haibo.chen at freescale.com>
---
 arch/arm/configs/imx_v6_v7_defconfig | 1 +
 1 file changed, 1 insertion(+)

diff --git a/arch/arm/configs/imx_v6_v7_defconfig b/arch/arm/configs/imx_v6_v7_defconfig
index 79194c6..61d4e02 100644
--- a/arch/arm/configs/imx_v6_v7_defconfig
+++ b/arch/arm/configs/imx_v6_v7_defconfig
@@ -159,6 +159,7 @@ CONFIG_MOUSE_PS2=m
 CONFIG_MOUSE_PS2_ELANTECH=y
 CONFIG_INPUT_TOUCHSCREEN=y
 CONFIG_TOUCHSCREEN_EGALAX=y
+CONFIG_TOUCHSCREEN_IMX6UL_TSC=y
 CONFIG_TOUCHSCREEN_MC13783=y
 CONFIG_TOUCHSCREEN_TSC2007=y
 CONFIG_TOUCHSCREEN_STMPE=y
-- 
1.9.1



From haibo.chen at freescale.com  Fri Aug 28 02:09:35 2015
From: haibo.chen at freescale.com (Haibo Chen)
Date: Fri, 28 Aug 2015 17:09:35 +0800
Subject: [PATCH v3 4/5] ARM: dts: imx6ul.dtsi: add TSC support
In-Reply-To: <1440752976-9094-1-git-send-email-haibo.chen@freescale.com>
References: <1440752976-9094-1-git-send-email-haibo.chen@freescale.com>
Message-ID: <1440752976-9094-5-git-send-email-haibo.chen@freescale.com>

Add imx6ul touchscreen controller support.

TSC module need ADC2 module to measure the touchscreen
coordinate value. This patch put TSC and ADC2 together,
make ADC2 module only be used for TSC, can't be used as
a normal ADC.

Signed-off-by: Haibo Chen <haibo.chen at freescale.com>
---
 arch/arm/boot/dts/imx6ul.dtsi | 11 +++++++++++
 1 file changed, 11 insertions(+)

diff --git a/arch/arm/boot/dts/imx6ul.dtsi b/arch/arm/boot/dts/imx6ul.dtsi
index 09edbed..ed86052 100644
--- a/arch/arm/boot/dts/imx6ul.dtsi
+++ b/arch/arm/boot/dts/imx6ul.dtsi
@@ -571,6 +571,17 @@
 				status = "disabled";
 			};
 
+			tsc: tsc at 02040000 {
+				compatible = "fsl,imx6ul-tsc";
+				reg = <0x02040000 0x4000>, <0x0219c000 0x4000>;
+				interrupts = <GIC_SPI 3 IRQ_TYPE_LEVEL_HIGH>,
+					     <GIC_SPI 101 IRQ_TYPE_LEVEL_HIGH>;
+				clocks = <&clks IMX6UL_CLK_IPG>,
+					 <&clks IMX6UL_CLK_ADC2>;
+				clock-names = "tsc", "adc";
+				status = "disabled";
+			};
+
 			usdhc1: usdhc at 02190000 {
 				compatible = "fsl,imx6ul-usdhc", "fsl,imx6sx-usdhc";
 				reg = <0x02190000 0x4000>;
-- 
1.9.1



From haibo.chen at freescale.com  Fri Aug 28 02:09:36 2015
From: haibo.chen at freescale.com (Haibo Chen)
Date: Fri, 28 Aug 2015 17:09:36 +0800
Subject: [PATCH v3 5/5] ARM: dts: imx6ul-14x14-evk.dts: add tsc support
In-Reply-To: <1440752976-9094-1-git-send-email-haibo.chen@freescale.com>
References: <1440752976-9094-1-git-send-email-haibo.chen@freescale.com>
Message-ID: <1440752976-9094-6-git-send-email-haibo.chen@freescale.com>

Add touch screen surpport for i.MX6UL-EVK board.

Signed-off-by: Haibo Chen <haibo.chen at freescale.com>
---
 arch/arm/boot/dts/imx6ul-14x14-evk.dts | 18 ++++++++++++++++++
 1 file changed, 18 insertions(+)

diff --git a/arch/arm/boot/dts/imx6ul-14x14-evk.dts b/arch/arm/boot/dts/imx6ul-14x14-evk.dts
index 25746b1..f7ad467 100644
--- a/arch/arm/boot/dts/imx6ul-14x14-evk.dts
+++ b/arch/arm/boot/dts/imx6ul-14x14-evk.dts
@@ -87,6 +87,15 @@
 	};
 };
 
+&tsc {
+	pinctrl-names = "default";
+	pinctrl-0 = <&pinctrl_tsc>;
+	xnur-gpio = <&gpio1 3 GPIO_ACTIVE_LOW>;
+	measure-delay-time = <0xffff>;
+	pre-charge-time = <0xfff>;
+	status = "okay";
+};
+
 &uart1 {
 	pinctrl-names = "default";
 	pinctrl-0 = <&pinctrl_uart1>;
@@ -277,6 +286,15 @@
 		>;
 	};
 
+	pinctrl_tsc: tscgrp {
+		fsl,pins = <
+			MX6UL_PAD_GPIO1_IO01__GPIO1_IO01		0xb0
+			MX6UL_PAD_GPIO1_IO02__GPIO1_IO02		0xb0
+			MX6UL_PAD_GPIO1_IO03__GPIO1_IO03		0xb0
+			MX6UL_PAD_GPIO1_IO04__GPIO1_IO04		0xb0
+		>;
+	};
+
 	pinctrl_uart1: uart1grp {
 		fsl,pins = <
 			MX6UL_PAD_UART1_TX_DATA__UART1_DCE_TX 0x1b0b1
-- 
1.9.1



From a0393675 at ti.com  Fri Aug 28 02:24:23 2015
From: a0393675 at ti.com (Keerthy)
Date: Fri, 28 Aug 2015 14:54:23 +0530
Subject: [PATCH] ARM: OMAP2+: omap-device: remove omap_device_late_init
 call completely
In-Reply-To: <55DF4398.7020201@ti.com>
References: <1440611890-4935-1-git-send-email-grygorii.strashko@ti.com>
 <20150826181006.GT4215@atomide.com> <55DF12E7.10802@ti.com>
 <20150827163856.GX4215@atomide.com> <55DF4398.7020201@ti.com>
Message-ID: <55E028C7.3060509@ti.com>



On Thursday 27 August 2015 10:36 PM, Grygorii Strashko wrote:
> On 08/27/2015 07:38 PM, Tony Lindgren wrote:
>> * Grygorii Strashko <grygorii.strashko at ti.com> [150827 06:42]:
>>> Hi Tony,
>>>
>>> On 08/26/2015 09:10 PM, Tony Lindgren wrote:
>>>> * Grygorii Strashko <grygorii.strashko at ti.com> [150826 11:01]:
>>>>> Now Kernel fails to boot 50% of times (form build to build) with
>>>>> RT-patchset applied due to the following race - on late boot
>>>>> stages deferred_probe_work_func races with omap_device_late_ini
>>>>>
>>>>> late_initcall
>>>>>     - deferred_probe_initcal() tries to re-probe all pending driver's probe.
>>>>>       [In general, It's NOT expected to probe any other built-in drivers after
>>>>>       deferred_probe_initcal() is finished, because most of
>>>>>       late_initcall_sync/late_initcall functions expected that all driver
>>>>>       or probed or deferred already.]
>>>>>
>>>>> - later on, some driver is probing in this case It's could cpsw.c
>>>>>      (but could be any other drivers)
>>>>>      cpsw_init
>>>>>      - platform_driver_register
>>>>>        - really_probe
>>>>>           - driver_bound
>>>>>             - driver_deferred_probe_trigger
>>>>>      and boot proceed.
>>>>>      So, at this moment we have  deferred_probe_work_func scheduled.
>>>>>
>>>>> late_initcall_sync
>>>>>      - omap_device_late_init
>>>>>        - omap_device_idle
>>>>>
>>>>> CPU1					CPU2
>>>>>      - deferred_probe_work_func
>>>>>        - really_probe
>>>>>          - omap_hsmmc_probe
>>>>> 	- pm_runtime_get_sync
>>>>> 					late_initcall_sync
>>>>> 					- omap_device_late_init
>>>>> 						if (od->_driver_status != BUS_NOTIFY_BOUND_DRIVER) {
>>>>> 							if (od->_state == OMAP_DEVICE_STATE_ENABLED) {
>>>>> 								- omap_device_idle [ops - IP is disabled, ]
>>>>> 	- [fail]
>>>>> 	- pm_runtime_put_sync
>>>>>              - omap_hsmmc_runtime_suspend [ooops!]
>>>>
>>>> OK idling of unclaimed devices should not happen for deferred probe,
>>>> it should only happen when there's no driver and no probing happening.
>>>>
>>>>> Lets remove just remove omap_device_late_init completely as suggested
>>>>> by Tero Kristo:
>>>>>
>>>>> "How about remove omap_device_late_init call completely. I don't think
>>>>> it does anything useful at the moment; none of the omap devices get
>>>>> enabled outside runtime_pm, so there should be no need to explicitly
>>>>> disable the devices."
>>>>
>>>> I think this is still needed from PM point of view as otherwise we
>>>> don't idle any devices that don't have a driver available. Or am I
>>>> missing something?
>>>>
>>>> To me it seems the bug is relying on the BUS_NOTIFY_BOUND_DRIVER is
>>>> not set in the deferred probe case.
>>>>
>>>
>>>
>>> What do you think about below alternative?
>>>
>>> diff --git a/arch/arm/mach-omap2/omap_device.c b/arch/arm/mach-omap2/omap_device.c
>>> index 4cb8fd9..72ebc4c 100644
>>> --- a/arch/arm/mach-omap2/omap_device.c
>>> +++ b/arch/arm/mach-omap2/omap_device.c
>>> @@ -901,7 +901,8 @@ static int __init omap_device_late_idle(struct device *dev, void *data)
>>>                   if (od->hwmods[i]->flags & HWMOD_INIT_NO_IDLE)
>>>                           return 0;
>>>
>>> -       if (od->_driver_status != BUS_NOTIFY_BOUND_DRIVER) {
>>> +       if (od->_driver_status != BUS_NOTIFY_BOUND_DRIVER &&
>>> +           od->_driver_status != BUS_NOTIFY_BIND_DRIVER) {
>>>                   if (od->_state == OMAP_DEVICE_STATE_ENABLED) {
>>>                           dev_warn(dev, "%s: enabled but no driver.  Idling\n",
>>>                                    __func__);
>>
>> Seems better to me if it really fixes the issue.
>>
>
> My dra7-evm failed to boot on "2b186e5 Add linux-next specific files for 20150827"
> and this change restores boot.
>
> Will wait for confirmation from Keerthy.

I confirm that with this patch the boot crash is fixed.

Tested-by: Keerthy <j-keerthy at ti.com>


Without this patch i see this crash during boot:

[    2.423724] omap_hsmmc 4809c000.mmc: omap_device_late_idle: enabled 
but no driver.  Idling
[    2.432959] ldousb: disabling
[    2.461630] Unhandled fault: imprecise external abort (0x1406) at 
0x00000000
[    2.461638] ------------[ cut here ]------------
[    2.461654] WARNING: CPU: 0 PID: 0 at drivers/bus/omap_l3_noc.c:147 
l3_interrupt_handler+0x220/0x348()
[    2.461660] 44000000.ocp:L3 Custom Error: MASTER MPU TARGET 
L4_PER1_P3 (Read): Data Access in User mode during Functional access
[    2.461665] Modules linked in:
[    2.461672] CPU: 0 PID: 0 Comm: swapper/0 Not tainted 
4.2.0-rc8-00084-gf1f35f0 #85
[    2.461675] Hardware name: Generic DRA74X (Flattened Device Tree)
[    2.461690] [<c0016614>] (unwind_backtrace) from [<c0012b10>] 
(show_stack+0x10/0x14)
[    2.461699] [<c0012b10>] (show_stack) from [<c05e9568>] 
(dump_stack+0x80/0x9c)
[    2.461709] [<c05e9568>] (dump_stack) from [<c003fb98>] 
(warn_slowpath_common+0x7c/0xb8)
[    2.461717] [<c003fb98>] (warn_slowpath_common) from [<c003fc68>] 
(warn_slowpath_fmt+0x30/0x40)
[    2.461726] [<c003fc68>] (warn_slowpath_fmt) from [<c037b0c0>] 
(l3_interrupt_handler+0x220/0x348)
[    2.461739] [<c037b0c0>] (l3_interrupt_handler) from [<c0099238>] 
(handle_irq_event_percpu+0x64/0x204)
[    2.461748] [<c0099238>] (handle_irq_event_percpu) from [<c0099418>] 
(handle_irq_event+0x40/0x64)
[    2.461758] [<c0099418>] (handle_irq_event) from [<c009c324>] 
(handle_fasteoi_irq+0xcc/0x1a8)
[    2.461768] [<c009c324>] (handle_fasteoi_irq) from [<c0098ae8>] 
(generic_handle_irq+0x20/0x30)
[    2.461776] [<c0098ae8>] (generic_handle_irq) from [<c0098bfc>] 
(__handle_domain_irq+0x64/0xdc)
[    2.461784] [<c0098bfc>] (__handle_domain_irq) from [<c00094c4>] 
(gic_handle_irq+0x20/0x60)
[    2.461795] [<c00094c4>] (gic_handle_irq) from [<c05f03e4>] 
(__irq_svc+0x44/0x5c)
[    2.461799] Exception stack(0xc08b7f58 to 0xc08b7fa0)
[    2.461803] 7f40: 
    00000001 00000001
[    2.461809] 7f60: 00000000 c08bc0b8 00000000 c096c8c8 c08b89c8 
00000000 00000000 c08b8a28
[    2.461815] 7f80: c08b3ab8 c08b8a30 00000000 c08b7fa0 c008e9fc 
c0010140 20000013 ffffffff
[    2.461828] [<c05f03e4>] (__irq_svc) from [<c0010140>] 
(arch_cpu_idle+0x20/0x3c)
[    2.461838] [<c0010140>] (arch_cpu_idle) from [<c0082080>] 
(cpu_startup_entry+0x240/0x374)
[    2.461850] [<c0082080>] (cpu_startup_entry) from [<c084ac48>] 
(start_kernel+0x38c/0x404)
[    2.461859] [<c084ac48>] (start_kernel) from [<8000807c>] (0x8000807c)
[    2.461862] ---[ end trace 14dd5a34ef3f5143 ]---
[    2.685888] pgd = c0004000
[    2.688718] [00000000] *pgd=00000000
[    2.692465] Internal error: : 1406 [#1] SMP ARM
[    2.697213] Modules linked in:
[    2.700413] CPU: 1 PID: 40 Comm: kworker/u4:2 Tainted: G        W 
    4.2.0-rc8-00084-gf1f35f0 #85
[    2.709990] Hardware name: Generic DRA74X (Flattened Device Tree)
[    2.716374] Workqueue: deferwq deferred_probe_work_func
[    2.721851] task: c2032400 ti: c2158000 task.ti: c2158000
[    2.727505] PC is at omap_hsmmc_runtime_suspend+0x18/0xc4
[    2.733167] LR is at pm_generic_runtime_suspend+0x2c/0x38
[    2.738822] pc : [<c04bfc24>]    lr : [<c03e8444>]    psr: a0000013
[    2.738822] sp : c2159d40  ip : c0ac5658  fp : de224410
[    2.750853] r10: 0000000c  r9 : 00000000  r8 : c08b8100
[    2.756321] r7 : 00000008  r6 : de224410  r5 : de2244a0  r4 : c21c5cc0
[    2.763163] r3 : fa09c100  r2 : 00000000  r1 : c2032968  r0 : de224410
[    2.770001] Flags: NzCv  IRQs on  FIQs on  Mode SVC_32  ISA ARM 
Segment kernel
[    2.777652] Control: 10c5387d  Table: 8000406a  DAC: 00000015
[    2.783666] Process kworker/u4:2 (pid: 40, stack limit = 0xc2158218)
[    2.790316] Stack: (0xc2159d40 to 0xc215a000)
[    2.794880] 9d40: c04bfc0c de224410 de2244a0 c0029ee8 00000008 
c03e8444 c2032400 c0029ef4
[    2.803444] 9d60: de224410 c03e9b48 de224410 00000000 00000000 
c03e9b9c 00000000 c0029ee8
[    2.812009] 9d80: 00000000 c03e9fcc 00000004 c08b8100 0000013a 
c21c5cc0 60000093 c05eff54
[    2.820568] 9da0: 00000000 de224410 00000000 de224410 00000004 
de2244a0 60000013 fffffdfb
[    2.829135] 9dc0: 0000013a c21c5cc0 fa09c100 c03ea74c 00000081 
c21c5800 fffffdfb de224400
[    2.837702] 9de0: de224410 c04c1a6c 00000000 c21c1a80 c21c5cc0 
c20ea810 c07b7d90 00000400
[    2.846271] 9e00: 00000000 c21c3d50 c096c378 ffffffed de224410 
fffffdfb c094cdb8 0000000d
[    2.854843] 9e20: c096c378 de0a6800 00000000 c03e3650 c03e3608 
c1167258 de224410 00000000
[    2.863407] 9e40: c094cdb8 c03e1fe0 00000000 c2159e78 c03e2280 
00000001 c096c378 c03e069c
[    2.871974] 9e60: de100cd4 c20ebc94 de224410 de224444 c0939290 
c03e1da4 de224410 00000001
[    2.880531] 9e80: c0939ee8 de224410 de224410 c0939290 c2159ed0 
c03e1540 de224410 c09391d4
[    2.889094] 9ea0: c0939190 c03e1928 c093920c c20491c0 de0a4c00 
c0057b70 00000001 00000000
[    2.897658] 9ec0: c0057adc de0a4c00 00000001 00000001 c093920c 
c0ac5658 00000000 c07b0110
[    2.906220] 9ee0: 00000003 c20491c0 de0a4c30 c096bbb3 c20491d8 
00000088 de0a4c00 de0a4c00
[    2.914792] 9f00: 00000003 c0057ff4 c2032400 00000000 de2b63c0 
c20491c0 c0057ea0 00000000
[    2.923363] 9f20: 00000000 00000000 00000000 c005dcf8 00000000 
00000000 00000001 c20491c0
[    2.931927] 9f40: 00000000 00000000 dead4ead ffffffff ffffffff 
c0972e38 00000000 00000000
[    2.940499] 9f60: c076df74 c2159f64 c2159f64 00000000 00000000 
dead4ead ffffffff ffffffff
[    2.949060] 9f80: c0972e38 00000000 00000000 c076df74 c2159f90 
c2159f90 c2159fac de2b63c0
[    2.957623] 9fa0: c005dc24 00000000 00000000 c000f6b8 00000000 
00000000 00000000 00000000
[    2.966186] 9fc0: 00000000 00000000 00000000 00000000 00000000 
00000000 00000000 00000000
[    2.974749] 9fe0: 00000000 00000000 00000000 00000000 00000013 
00000000 e7fddef0 e7fddef0
[    2.983325] [<c04bfc24>] (omap_hsmmc_runtime_suspend) from 
[<c03e8444>] (pm_generic_runtime_suspend+0x2c/0x38)
[    2.993809] [<c03e8444>] (pm_generic_runtime_suspend) from 
[<c0029ef4>] (_od_runtime_suspend+0xc/0x20)
[    3.003566] [<c0029ef4>] (_od_runtime_suspend) from [<c03e9b48>] 
(__rpm_callback+0x2c/0x60)
[    3.012322] [<c03e9b48>] (__rpm_callback) from [<c03e9b9c>] 
(rpm_callback+0x20/0x80)
[    3.020435] [<c03e9b9c>] (rpm_callback) from [<c03e9fcc>] 
(rpm_suspend+0xf4/0x510)
[    3.028365] [<c03e9fcc>] (rpm_suspend) from [<c03ea74c>] 
(__pm_runtime_idle+0x60/0x84)
[    3.036662] [<c03ea74c>] (__pm_runtime_idle) from [<c04c1a6c>] 
(omap_hsmmc_probe+0x61c/0xa24)
[    3.045585] [<c04c1a6c>] (omap_hsmmc_probe) from [<c03e3650>] 
(platform_drv_probe+0x48/0xa4)
[    3.054427] [<c03e3650>] (platform_drv_probe) from [<c03e1fe0>] 
(driver_probe_device+0x1c4/0x26c)
[    3.063724] [<c03e1fe0>] (driver_probe_device) from [<c03e069c>] 
(bus_for_each_drv+0x44/0x8c)
[    3.072653] [<c03e069c>] (bus_for_each_drv) from [<c03e1da4>] 
(__device_attach+0x8c/0xdc)
[    3.081219] [<c03e1da4>] (__device_attach) from [<c03e1540>] 
(bus_probe_device+0x88/0x90)
[    3.089787] [<c03e1540>] (bus_probe_device) from [<c03e1928>] 
(deferred_probe_work_func+0x60/0x90)
[    3.099182] [<c03e1928>] (deferred_probe_work_func) from [<c0057b70>] 
(process_one_work+0x1b4/0x4b0)
[    3.108756] [<c0057b70>] (process_one_work) from [<c0057ff4>] 
(worker_thread+0x154/0x474)
[    3.117326] [<c0057ff4>] (worker_thread) from [<c005dcf8>] 
(kthread+0xd4/0xf0)
[    3.124889] [<c005dcf8>] (kthread) from [<c000f6b8>] 
(ret_from_fork+0x14/0x3c)
[    3.132448] Code: e5904084 e594302c e593202c e5842064 (e5932128)
[    3.138838] ---[ end trace 14dd5a34ef3f5144 ]---
[    3.143776] Unable to handle kernel paging request at virtual address 
ffffffd0
[    3.151344] pgd = c0004000
[    3.154175] [ffffffd0] *pgd=9fef6821, *pte=00000000, *ppte=00000000
[    3.160760] Internal error: Oops: 17 [#2] SMP ARM
[    3.165684] Modules linked in:
[    3.168887] CPU: 1 PID: 40 Comm: kworker/u4:2 Tainted: G      D W 
    4.2.0-rc8-00084-gf1f35f0 #85
[    3.178453] Hardware name: Generic DRA74X (Flattened Device Tree)
[    3.184841] task: c2032400 ti: c2158000 task.ti: c2158000
[    3.190499] PC is at kthread_data+0x4/0xc
[    3.194699] LR is at wq_worker_sleeping+0xc/0xd4
[    3.199527] pc : [<c005e3e4>]    lr : [<c0058f9c>]    psr: 00000193
[    3.199527] sp : c2159b40  ip : 00000000  fp : c2159b94
[    3.211557] r10: 00000001  r9 : df9f0580  r8 : c08b4580
[    3.217028] r7 : c08b95c4  r6 : c20327bc  r5 : df9f0590  r4 : 00000001
[    3.223861] r3 : 00000000  r2 : 00000000  r1 : 00000001  r0 : c2032400
[    3.230701] Flags: nzcv  IRQs off  FIQs on  Mode SVC_32  ISA ARM 
Segment user
[    3.238258] Control: 10c5387d  Table: 8000406a  DAC: 00000015
[    3.244278] Process kworker/u4:2 (pid: 40, stack limit = 0xc2158218)
[    3.250928] Stack: (0xc2159b40 to 0xc215a000)
[    3.255493] 9b40: c2032400 c05eaa74 c00428f8 c01039fc c08fa360 
00000001 dcfd31c4 c05eaf28
[    3.264059] 9b60: de2bc488 c00428f8 df9f0cc0 c2032fdc 60000113 
c215985c c2032400 c08f4658
[    3.272622] 9b80: c2032738 c2159bb0 00000001 c04bfc26 c2159b9c 
c05eaf28 00000001 c00429b0
[    3.281194] 9ba0: 00000000 00000001 c00984b8 c2159bcc c2159bb0 
c2159bb0 c2159cf8 c0971244
[    3.289767] 9bc0: c2159cf8 c08bdc28 60000193 0000000b c04bfc28 
c04bfc26 00000001 c0012efc
[    3.298326] 9be0: c2158218 0000000b 00000001 00000000 00000000 
00000008 65000000 34303935
[    3.306895] 9c00: 20343830 34393565 63323033 39356520 32303233 
35652063 30323438 28203436
[    3.315464] 9c20: 33393565 38323132 c0002029 c2159c4c c1132f9c 
00001406 00000007 00000000
[    3.324033] 9c40: c08be50c c2159cf8 00000000 0000000c de224410 
c0009344 00000000 000005a8
[    3.332601] 9c60: 00000007 00000000 00030003 00000000 c2032988 
00000588 c1132f9c c2032400
[    3.341172] 9c80: c20329a8 00000000 c1132f9c c2032400 c092ec54 
00000134 c0aa0688 c008c370
[    3.349741] 9ca0: c092ec54 0000013b 00000004 c008c370 3c220134 
22c11684 00000004 c0ab4dc8
[    3.358305] 9cc0: c20329a8 00000000 c1132f9c 000005a8 c092ec54 
00000110 c0fab7f4 c008c370
[    3.366877] 9ce0: c04bfc24 a0000013 ffffffff c2159d2c c08b8100 
c05f0364 de224410 c2032968
[    3.375448] 9d00: 00000000 fa09c100 c21c5cc0 de2244a0 de224410 
00000008 c08b8100 00000000
[    3.384011] 9d20: 0000000c de224410 c0ac5658 c2159d40 c03e8444 
c04bfc24 a0000013 ffffffff
[    3.392579] 9d40: c04bfc0c de224410 de2244a0 c0029ee8 00000008 
c03e8444 c2032400 c0029ef4
[    3.401144] 9d60: de224410 c03e9b48 de224410 00000000 00000000 
c03e9b9c 00000000 c0029ee8
[    3.409712] 9d80: 00000000 c03e9fcc 00000004 c08b8100 0000013a 
c21c5cc0 60000093 c05eff54
[    3.418280] 9da0: 00000000 de224410 00000000 de224410 00000004 
de2244a0 60000013 fffffdfb
[    3.426850] 9dc0: 0000013a c21c5cc0 fa09c100 c03ea74c 00000081 
c21c5800 fffffdfb de224400
[    3.435422] 9de0: de224410 c04c1a6c 00000000 c21c1a80 c21c5cc0 
c20ea810 c07b7d90 00000400
[    3.443983] 9e00: 00000000 c21c3d50 c096c378 ffffffed de224410 
fffffdfb c094cdb8 0000000d
[    3.452546] 9e20: c096c378 de0a6800 00000000 c03e3650 c03e3608 
c1167258 de224410 00000000
[    3.461114] 9e40: c094cdb8 c03e1fe0 00000000 c2159e78 c03e2280 
00000001 c096c378 c03e069c
[    3.469686] 9e60: de100cd4 c20ebc94 de224410 de224444 c0939290 
c03e1da4 de224410 00000001
[    3.478248] 9e80: c0939ee8 de224410 de224410 c0939290 c2159ed0 
c03e1540 de224410 c09391d4
[    3.486812] 9ea0: c0939190 c03e1928 c093920c c20491c0 de0a4c00 
c0057b70 00000001 00000000
[    3.495379] 9ec0: c0057adc de0a4c00 00000001 00000001 c093920c 
c0ac5658 00000000 c07b0110
[    3.503945] 9ee0: 00000003 c20491c0 de0a4c30 c096bbb3 c20491d8 
00000088 de0a4c00 de0a4c00
[    3.512515] 9f00: 00000003 c0057ff4 c2032400 00000000 de2b63c0 
c20491c0 c0057ea0 00000000
[    3.521079] 9f20: 00000000 00000000 00000000 c005dcf8 00000000 
00000000 00000001 c20491c0
[    3.529647] 9f40: 00000000 00000000 dead4ead ffffffff ffffffff 
c0972e38 00000000 00000000
[    3.538202] 9f60: c076df74 c2159f64 c2159f64 00000001 00010001 
dead4ead ffffffff ffffffff
[    3.546773] 9f80: c0972e38 00000000 00000000 c076df74 c2159f90 
c2159f90 c2159fac de2b63c0
[    3.555340] 9fa0: c005dc24 00000000 00000000 c000f6b8 00000000 
00000000 00000000 00000000
[    3.563906] 9fc0: 00000000 00000000 00000000 00000000 00000000 
00000000 00000000 00000000
[    3.572473] 9fe0: 00000000 00000000 00000000 00000000 00000013 
00000000 e7fddef0 e7fddef0
[    3.581043] [<c005e3e4>] (kthread_data) from [<c0058f9c>] 
(wq_worker_sleeping+0xc/0xd4)
[    3.589429] [<c0058f9c>] (wq_worker_sleeping) from [<c05eaa74>] 
(__schedule+0x5b4/0x970)
[    3.597911] [<c05eaa74>] (__schedule) from [<c05eaf28>] 
(schedule+0x34/0x98)
[    3.605294] [<c05eaf28>] (schedule) from [<c00429b0>] 
(do_exit+0x60c/0x994)
[    3.612594] [<c00429b0>] (do_exit) from [<c0012efc>] (die+0x3e8/0x438)
[    3.619427] [<c0012efc>] (die) from [<c0009344>] (do_DataAbort+0xa4/0xb4)
[    3.626540] [<c0009344>] (do_DataAbort) from [<c05f0364>] 
(__dabt_svc+0x44/0x80)
[    3.634280] Exception stack(0xc2159cf8 to 0xc2159d40)

>
>


From dcb314 at hotmail.com  Fri Aug 28 02:25:53 2015
From: dcb314 at hotmail.com (David Binderman)
Date: Fri, 28 Aug 2015 09:25:53 +0000
Subject: arch/arm/mach-omap2/vc.c:302: bad if test ?
Message-ID: <DUB128-W519E183FDD98EF80BD4CB79C6E0@phx.gbl>

Hello there,

arch/arm/mach-omap2/vc.c:302:47: warning: logical ?or? of collectively exhaustive tests is always true [-Wlogical-op]

Source code is

??????? if (!(val & OMAP3430_PRM_POLCTRL_CLKREQ_POL) ||
??????????? (val & OMAP3430_PRM_POLCTRL_CLKREQ_POL)) {

Suggest code rework.

Regards

David Binderman

 		 	   		  

From javier at osg.samsung.com  Fri Aug 28 02:30:26 2015
From: javier at osg.samsung.com (Javier Martinez Canillas)
Date: Fri, 28 Aug 2015 11:30:26 +0200
Subject: [PATCH] ARM: exynos_defconfig: Enable big.LITTLE CPUidle support
In-Reply-To: <1440751902.13118.6.camel@collabora.co.uk>
References: <1440749769-10135-1-git-send-email-javier@osg.samsung.com>
 <1440751902.13118.6.camel@collabora.co.uk>
Message-ID: <55E02A32.2070902@osg.samsung.com>

Hello Sjoerd,

On 08/28/2015 10:51 AM, Sjoerd Simons wrote:
> On Fri, 2015-08-28 at 10:16 +0200, Javier Martinez Canillas wrote:
>> Some Exynos big.LITTLE boards (i.e: Exynos5420 and Exynos5800 based
>> Chromebooks) have proper firmware that allow the big.LITTLE CPUidle
>> driver to work correctly, so enable support for this.
>>
>> Signed-off-by: Javier Martinez Canillas <javier at osg.samsung.com>
>>
>> ---
>> Kukjin and Krzysztof,
>>
>> As you know there are other boards like the Exynos5422 based Odroid 
>> XU{3,4}
>> whose firmware is broken due leaving CCI in secure mode which means 
>> that the
>> kernel MCPM support can't properly manage CCI.
>>
>> So if you pick this patch, it should be tested in kernelci before 
>> appearing
>> in linux-next to prevent any boot issues.
> 
> I've pushed this patch into Collabora's for-next branch, which should
> get picked up by kernelci soonish.
>

Awesome, thanks a lot for your help!
 
Best regards,
-- 
Javier Martinez Canillas
Open Source Group
Samsung Research America


From linux at arm.linux.org.uk  Fri Aug 28 02:44:13 2015
From: linux at arm.linux.org.uk (Russell King - ARM Linux)
Date: Fri, 28 Aug 2015 10:44:13 +0100
Subject: [PATCH 1/3] ARM: uniphier: add outer cache support
In-Reply-To: <4027826.UsiXogeDbt@wuerfel>
References: <1440382692-3855-1-git-send-email-yamada.masahiro@socionext.com>
 <2021253.vgeYqalDfp@wuerfel>
 <CAK7LNAQ_oymnQNEcP+FDqyxNKtMyiCwgxSRMmg5HAKQW9C6eRg@mail.gmail.com>
 <4027826.UsiXogeDbt@wuerfel>
Message-ID: <20150828094412.GH21084@n2100.arm.linux.org.uk>

On Wed, Aug 26, 2015 at 02:52:45PM +0200, Arnd Bergmann wrote:
> On Wednesday 26 August 2015 10:38:59 Masahiro Yamada wrote:
> > Moreover, outer-cache init seems to be unrelated to
> > IRQ init.
> 
> Agreed, this is also just a historic artifact, as we don't really
> have a place to put cache controller initialization, and the

Arnd, I'm afraid you're completely wrong there.  It's not a historic
artifact by any of the kind.

I explicitly placed the L2 cache initialisation there based upon
which callbacks into architecture code were available from init/main.c
and where in the initialisation sequence I wanted the L2 cache to be
initialised _for_ _everyone_.

That being, before SMP is brought up, preferably before the delay
loop calibration (so we don't calibrate the loop without the L2 cache,
and then invalidate that calibration when we enable the cache), but
sufficiently late that various services that the L2 cache code wants
(like kmalloc) have been initialised.

That rules out setup_arch(), leaving trap_init(), init_IRQ(), time_init()
and late_time_init().  I chose init_IRQ() out of that lot because it
seemed to be a sensible point to initialise it, though trap_init()
looks like it could have been another good site.

All L2 caches should be initialised at a similar point IMHO - not only
does this give us a more consistent initialisation sequence, but it
avoids issues such as the one I mention above with delay loop calibration
being wrong.

> A first step would be to add the tauros2 and uniphier outer cache
> init to the init_IRQ() function, and then have another patch
> that moves all the outercache initialization into a new place
> like arch/arm/mm/outercache.c so we don't clutter up irq.c

arch/arm/mm/l2c-common.c

> with unrelated stuff.

-- 
FTTC broadband for 0.8mile line: currently at 9.6Mbps down 400kbps up
according to speedtest.net.


From mingo at kernel.org  Fri Aug 28 02:53:49 2015
From: mingo at kernel.org (Ingo Molnar)
Date: Fri, 28 Aug 2015 11:53:49 +0200
Subject: [PATCH 1/4] x86, efi, kasan: #undef memset/memcpy/memmove per
 arch.
In-Reply-To: <20150828083941.GN10728@bivouac.eciton.net>
References: <1440605707-8325-1-git-send-email-ryabinin.a.a@gmail.com>
 <1440605707-8325-2-git-send-email-ryabinin.a.a@gmail.com>
 <20150828062745.GB1928@gmail.com>
 <20150828083941.GN10728@bivouac.eciton.net>
Message-ID: <20150828095349.GA23114@gmail.com>


* Leif Lindholm <leif.lindholm at linaro.org> wrote:

> > > So let's move these #undef mem* into arch's asm/efi.h which is
> > 
> > s/lets
> 
> No, that one is actually correct. Abbreviation of let us.

Indeed.

Thanks,

	Ingo


From wens at csie.org  Fri Aug 28 02:54:37 2015
From: wens at csie.org (Chen-Yu Tsai)
Date: Fri, 28 Aug 2015 17:54:37 +0800
Subject: [PATCH 4/6] ARM: dts: sun6i: Add mmc2 pins for 8 bit emmc
In-Reply-To: <1440755679-8266-1-git-send-email-wens@csie.org>
References: <1440755679-8266-1-git-send-email-wens@csie.org>
Message-ID: <1440755679-8266-5-git-send-email-wens@csie.org>

This also includes the reset pin for emmc.

Signed-off-by: Chen-Yu Tsai <wens at csie.org>
---
 arch/arm/boot/dts/sun6i-a31.dtsi | 10 ++++++++++
 1 file changed, 10 insertions(+)

diff --git a/arch/arm/boot/dts/sun6i-a31.dtsi b/arch/arm/boot/dts/sun6i-a31.dtsi
index 431c7c884e1c..98359f37bf11 100644
--- a/arch/arm/boot/dts/sun6i-a31.dtsi
+++ b/arch/arm/boot/dts/sun6i-a31.dtsi
@@ -691,6 +691,16 @@
 				allwinner,pull = <SUN4I_PINCTRL_NO_PULL>;
 			};
 
+			mmc2_8bit_emmc_pins: mmc2 at 0 {
+				allwinner,pins = "PC6", "PC7", "PC8", "PC9",
+						 "PC10", "PC11", "PC12",
+						 "PC13", "PC14", "PC15",
+						 "PC24";
+				allwinner,function = "mmc2";
+				allwinner,drive = <SUN4I_PINCTRL_30_MA>;
+				allwinner,pull = <SUN4I_PINCTRL_NO_PULL>;
+			};
+
 			gmac_pins_mii_a: gmac_mii at 0 {
 				allwinner,pins = "PA0", "PA1", "PA2", "PA3",
 						"PA8", "PA9", "PA11",
-- 
2.5.0



From wens at csie.org  Fri Aug 28 02:54:33 2015
From: wens at csie.org (Chen-Yu Tsai)
Date: Fri, 28 Aug 2015 17:54:33 +0800
Subject: [PATCH 0/6] ARM: sunxi: Support MSI Primo81 tablet and Sinlinx SinA31s
Message-ID: <1440755679-8266-1-git-send-email-wens@csie.org>

Hi Maxime,

This series adds support for MSI's Primo81 tablet, and Sinlinx's SinA31s
development kit. This also adds a common axp221.dtsi, like we have for
axp209 and axp152. The Hummingbird A31 dts is also migrated to this.

The Primo81 patch is actually a v5. Changes since the last version can
be found in that patch.

Patch 1 adds an lradc node to sun6i-a31.dtsi. This is the same lradc
for tablet buttons found on the other sunxi SoCs.

Patch 2 adds a common dtsi for the AXP221 PMIC. This includes listing
all the regulators, and the basic common properties, like
"interrupt-controller".

Patch 3 migrates the Hummingbird A31 dts to use the new axp221.dtsi

Patch 4 adds the pinmux settings for A31/A31s mmc2 with 8-bit bus for
emmc.

Patch 5 adds dtsi/dts files for the Sinlinx SinA31s development kit.

Patch 6 adds a dts file for the A31s based MSI Primo81 tablet.


Regards
ChenYu

Chen-Yu Tsai (5):
  ARM: dts: sun6i: Add lradc node
  ARM: dts: sunxi: Add dtsi for AXP221 PMIC
  ARM: dts: sun6i: hummingbird: Use axp221.dtsi for axp221 regulators
  ARM: dts: sun6i: Add mmc2 pins for 8 bit emmc
  ARM: dts: sun6i: Add support for Sinlinx A31s SDK board

Karsten Merker (1):
  ARM: dts: sun6i: Add dts file for MSI Primo81 tablet

 arch/arm/boot/dts/Makefile                     |   4 +-
 arch/arm/boot/dts/axp221.dtsi                  | 148 ++++++++++++++
 arch/arm/boot/dts/sun6i-a31-hummingbird.dts    | 114 ++++++-----
 arch/arm/boot/dts/sun6i-a31.dtsi               |  17 ++
 arch/arm/boot/dts/sun6i-a31s-primo81.dts       | 255 +++++++++++++++++++++++++
 arch/arm/boot/dts/sun6i-a31s-sina31s-core.dtsi | 131 +++++++++++++
 arch/arm/boot/dts/sun6i-a31s-sina31s.dts       | 149 +++++++++++++++
 7 files changed, 759 insertions(+), 59 deletions(-)
 create mode 100644 arch/arm/boot/dts/axp221.dtsi
 create mode 100644 arch/arm/boot/dts/sun6i-a31s-primo81.dts
 create mode 100644 arch/arm/boot/dts/sun6i-a31s-sina31s-core.dtsi
 create mode 100644 arch/arm/boot/dts/sun6i-a31s-sina31s.dts

-- 
2.5.0



From wens at csie.org  Fri Aug 28 02:54:34 2015
From: wens at csie.org (Chen-Yu Tsai)
Date: Fri, 28 Aug 2015 17:54:34 +0800
Subject: [PATCH 1/6] ARM: dts: sun6i: Add lradc node
In-Reply-To: <1440755679-8266-1-git-send-email-wens@csie.org>
References: <1440755679-8266-1-git-send-email-wens@csie.org>
Message-ID: <1440755679-8266-2-git-send-email-wens@csie.org>

sun6i also has the LRADC for tablet buttons.

Signed-off-by: Chen-Yu Tsai <wens at csie.org>
---
 arch/arm/boot/dts/sun6i-a31.dtsi | 7 +++++++
 1 file changed, 7 insertions(+)

diff --git a/arch/arm/boot/dts/sun6i-a31.dtsi b/arch/arm/boot/dts/sun6i-a31.dtsi
index 54bb83b58f42..431c7c884e1c 100644
--- a/arch/arm/boot/dts/sun6i-a31.dtsi
+++ b/arch/arm/boot/dts/sun6i-a31.dtsi
@@ -768,6 +768,13 @@
 			reg = <0x01c20ca0 0x20>;
 		};
 
+		lradc: lradc at 01c22800 {
+			compatible = "allwinner,sun4i-a10-lradc-keys";
+			reg = <0x01c22800 0x100>;
+			interrupts = <GIC_SPI 30 IRQ_TYPE_LEVEL_HIGH>;
+			status = "disabled";
+		};
+
 		rtp: rtp at 01c25000 {
 			compatible = "allwinner,sun6i-a31-ts";
 			reg = <0x01c25000 0x100>;
-- 
2.5.0



From wens at csie.org  Fri Aug 28 02:54:36 2015
From: wens at csie.org (Chen-Yu Tsai)
Date: Fri, 28 Aug 2015 17:54:36 +0800
Subject: [PATCH 3/6] ARM: dts: sun6i: hummingbird: Use axp221.dtsi for axp221
 regulators
In-Reply-To: <1440755679-8266-1-git-send-email-wens@csie.org>
References: <1440755679-8266-1-git-send-email-wens@csie.org>
Message-ID: <1440755679-8266-4-git-send-email-wens@csie.org>

Now that we have axp221.dtsi describing common axp22x hardware, use
it and reference the nodes instead of declaring the whole tree.

Also add regulator reference for cpu0 supply.

Signed-off-by: Chen-Yu Tsai <wens at csie.org>
---
 arch/arm/boot/dts/sun6i-a31-hummingbird.dts | 114 ++++++++++++++--------------
 1 file changed, 56 insertions(+), 58 deletions(-)

diff --git a/arch/arm/boot/dts/sun6i-a31-hummingbird.dts b/arch/arm/boot/dts/sun6i-a31-hummingbird.dts
index d0cfadac0691..d019cb70acec 100644
--- a/arch/arm/boot/dts/sun6i-a31-hummingbird.dts
+++ b/arch/arm/boot/dts/sun6i-a31-hummingbird.dts
@@ -67,6 +67,10 @@
 	};
 };
 
+&cpu0 {
+	cpu-supply = <&reg_dcdc2>;
+};
+
 &ehci0 {
 	status = "okay";
 };
@@ -119,7 +123,7 @@
 &mmc0 {
 	pinctrl-names = "default";
 	pinctrl-0 = <&mmc0_pins_a>, <&mmc0_cd_pin_hummingbird>;
-	vmmc-supply = <&vcc_3v0>;
+	vmmc-supply = <&reg_dcdc1>;
 	bus-width = <4>;
 	cd-gpios = <&pio 0 8 GPIO_ACTIVE_HIGH>; /* PA8 */
 	cd-inverted;
@@ -134,7 +138,7 @@
 &mmc1 {
 	pinctrl-names = "default";
 	pinctrl-0 = <&mmc1_pins_a>, <&wifi_reset_pin_hummingbird>;
-	vmmc-supply = <&vcc_wifi>;
+	vmmc-supply = <&reg_aldo1>;
 	mmc-pwrseq = <&wifi_pwrseq>;
 	bus-width = <4>;
 	non-removable;
@@ -169,65 +173,59 @@
 		reg = <0x68>;
 		interrupt-parent = <&nmi_intc>;
 		interrupts = <0 IRQ_TYPE_LEVEL_LOW>;
-		interrupt-controller;
-		#interrupt-cells = <1>;
-		dcdc1-supply = <&vcc_3v0>;
-		dcdc5-supply = <&vcc_dram>;
-
-		regulators {
-			x-powers,dcdc-freq = <3000>;
-
-			vcc_3v0: dcdc1 {
-				regulator-always-on;
-				regulator-min-microvolt = <3000000>;
-				regulator-max-microvolt = <3000000>;
-				regulator-name = "vcc-3v0";
-			};
-
-			vdd_cpu: dcdc2 {
-				regulator-always-on;
-				regulator-min-microvolt = <700000>;
-				regulator-max-microvolt = <1320000>;
-				regulator-name = "vdd-cpu";
-			};
-
-			vdd_gpu: dcdc3 {
-				regulator-always-on;
-				regulator-min-microvolt = <700000>;
-				regulator-max-microvolt = <1320000>;
-				regulator-name = "vdd-gpu";
-			};
-
-			vdd_sys_dll: dcdc4 {
-				regulator-always-on;
-				regulator-min-microvolt = <1100000>;
-				regulator-max-microvolt = <1100000>;
-				regulator-name = "vdd-sys-dll";
-			};
-
-			vcc_dram: dcdc5 {
-				regulator-always-on;
-				regulator-min-microvolt = <1500000>;
-				regulator-max-microvolt = <1500000>;
-				regulator-name = "vcc-dram";
-			};
-
-			vcc_wifi: aldo1 {
-				regulator-min-microvolt = <3300000>;
-				regulator-max-microvolt = <3300000>;
-				regulator-name = "vcc_wifi";
-			};
-
-			avcc: aldo3 {
-				regulator-always-on;
-				regulator-min-microvolt = <3000000>;
-				regulator-max-microvolt = <3000000>;
-				regulator-name = "avcc";
-			};
-		};
 	};
 };
 
+#include "axp221.dtsi"
+
+&reg_aldo1 {
+	regulator-min-microvolt = <3300000>;
+	regulator-max-microvolt = <3300000>;
+	regulator-name = "vcc-wifi";
+};
+
+&reg_aldo3 {
+	regulator-always-on;
+	regulator-min-microvolt = <3000000>;
+	regulator-max-microvolt = <3000000>;
+	regulator-name = "avcc";
+};
+
+&reg_dcdc1 {
+	regulator-always-on;
+	regulator-min-microvolt = <3000000>;
+	regulator-max-microvolt = <3000000>;
+	regulator-name = "vcc-3v0";
+};
+
+&reg_dcdc2 {
+	regulator-always-on;
+	regulator-min-microvolt = <700000>;
+	regulator-max-microvolt = <1320000>;
+	regulator-name = "vdd-cpu";
+};
+
+&reg_dcdc3 {
+	regulator-always-on;
+	regulator-min-microvolt = <700000>;
+	regulator-max-microvolt = <1320000>;
+	regulator-name = "vdd-gpu";
+};
+
+&reg_dcdc4 {
+	regulator-always-on;
+	regulator-min-microvolt = <1100000>;
+	regulator-max-microvolt = <1100000>;
+	regulator-name = "vdd-sys-dll";
+};
+
+&reg_dcdc5 {
+	regulator-always-on;
+	regulator-min-microvolt = <1500000>;
+	regulator-max-microvolt = <1500000>;
+	regulator-name = "vcc-dram";
+};
+
 &reg_usb1_vbus {
 	gpio = <&pio 7 24 GPIO_ACTIVE_HIGH>; /* PH24 */
 	status = "okay";
-- 
2.5.0



From wens at csie.org  Fri Aug 28 02:54:35 2015
From: wens at csie.org (Chen-Yu Tsai)
Date: Fri, 28 Aug 2015 17:54:35 +0800
Subject: [PATCH 2/6] ARM: dts: sunxi: Add dtsi for AXP221 PMIC
In-Reply-To: <1440755679-8266-1-git-send-email-wens@csie.org>
References: <1440755679-8266-1-git-send-email-wens@csie.org>
Message-ID: <1440755679-8266-3-git-send-email-wens@csie.org>

The AXP221 PMIC is used with some Allwinner SoCs. This patch adds
a dtsi file listing all the regulator nodes. The regulators are
initialized based on their device node names.

This can later be used with the AXP223 PMIC as well, which has
the same functionality as AXP221, except for its host interface.

Signed-off-by: Chen-Yu Tsai <wens at csie.org>
---
 arch/arm/boot/dts/axp221.dtsi | 148 ++++++++++++++++++++++++++++++++++++++++++
 1 file changed, 148 insertions(+)
 create mode 100644 arch/arm/boot/dts/axp221.dtsi

diff --git a/arch/arm/boot/dts/axp221.dtsi b/arch/arm/boot/dts/axp221.dtsi
new file mode 100644
index 000000000000..74836f329863
--- /dev/null
+++ b/arch/arm/boot/dts/axp221.dtsi
@@ -0,0 +1,148 @@
+/*
+ * Copyright 2015 Chen-Yu Tsai
+ *
+ * Chen-Yu Tsai <wens at csie.org>
+ *
+ * This file is dual-licensed: you can use it either under the terms
+ * of the GPL or the X11 license, at your option. Note that this dual
+ * licensing only applies to this file, and not this project as a
+ * whole.
+ *
+ *  a) This file is free software; you can redistribute it and/or
+ *     modify it under the terms of the GNU General Public License as
+ *     published by the Free Software Foundation; either version 2 of the
+ *     License, or (at your option) any later version.
+ *
+ *     This file is distributed in the hope that it will be useful,
+ *     but WITHOUT ANY WARRANTY; without even the implied warranty of
+ *     MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ *     GNU General Public License for more details.
+ *
+ * Or, alternatively,
+ *
+ *  b) Permission is hereby granted, free of charge, to any person
+ *     obtaining a copy of this software and associated documentation
+ *     files (the "Software"), to deal in the Software without
+ *     restriction, including without limitation the rights to use,
+ *     copy, modify, merge, publish, distribute, sublicense, and/or
+ *     sell copies of the Software, and to permit persons to whom the
+ *     Software is furnished to do so, subject to the following
+ *     conditions:
+ *
+ *     The above copyright notice and this permission notice shall be
+ *     included in all copies or substantial portions of the Software.
+ *
+ *     THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
+ *     EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES
+ *     OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
+ *     NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT
+ *     HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY,
+ *     WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
+ *     FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR
+ *     OTHER DEALINGS IN THE SOFTWARE.
+ */
+
+/*
+ * AXP221/221s/223 Integrated Power Management Chip
+ * http://www.x-powers.com/product/AXP22X.php
+ * http://dl.linux-sunxi.org/AXP/AXP221%20Datasheet%20V1.2%2020130326%20.pdf
+ */
+
+&axp221 {
+	compatible = "x-powers,axp221";
+	interrupt-controller;
+	#interrupt-cells = <1>;
+
+	regulators {
+		/* Default work frequency for buck regulators */
+		x-powers,dcdc-freq = <3000>;
+
+		/* supplies for dc1sw & dc5ldo are connected internally */
+		dcdc1-supply = <&reg_dcdc1>;
+		dcdc5-supply = <&reg_dcdc5>;
+
+		reg_dcdc1: dcdc1 {
+			regulator-name = "dcdc1";
+		};
+
+		reg_dcdc2: dcdc2 {
+			regulator-name = "dcdc2";
+		};
+
+		reg_dcdc3: dcdc3 {
+			regulator-name = "dcdc3";
+		};
+
+		reg_dcdc4: dcdc4 {
+			regulator-name = "dcdc4";
+		};
+
+		reg_dcdc5: dcdc5 {
+			regulator-name = "dcdc5";
+		};
+
+		reg_dc1sw: dc1sw {
+			regulator-name = "dc1sw";
+		};
+
+		reg_dc5ldo: dc5ldo {
+			regulator-name = "dc5ldo";
+		};
+
+		reg_aldo1: aldo1 {
+			regulator-name = "aldo1";
+		};
+
+		reg_aldo2: aldo2 {
+			regulator-name = "aldo2";
+		};
+
+		reg_aldo3: aldo3 {
+			regulator-name = "aldo3";
+		};
+
+		reg_dldo1: dldo1 {
+			regulator-name = "dldo1";
+		};
+
+		reg_dldo2: dldo2 {
+			regulator-name = "dldo2";
+		};
+
+		reg_dldo3: dldo3 {
+			regulator-name = "dldo3";
+		};
+
+		reg_dldo4: dldo4 {
+			regulator-name = "dldo4";
+		};
+
+		reg_eldo1: eldo1 {
+			regulator-name = "eldo1";
+		};
+
+		reg_eldo2: eldo2 {
+			regulator-name = "eldo2";
+		};
+
+		reg_eldo3: eldo3 {
+			regulator-name = "eldo3";
+		};
+
+		reg_ldo_io0: ldo_io0 {
+			regulator-name = "ldo_io0";
+		};
+
+		reg_ldo_io1: ldo_io1 {
+			regulator-name = "ldo_io1";
+		};
+
+		reg_rtc_ldo: rtc_ldo {
+			/* RTC_LDO is a fixed, always-on regulator */
+			regulator-always-on;
+			regulator-min-microvolt = <3000000>;
+			regulator-max-microvolt = <3000000>;
+			regulator-name = "rtc_ldo";
+		};
+	};
+};
-- 
2.5.0



From heiko at sntech.de  Fri Aug 28 02:54:50 2015
From: heiko at sntech.de (Heiko Stuebner)
Date: Fri, 28 Aug 2015 11:54:50 +0200
Subject: [PATCH v1 3/3] clk: rockchip: add clock controller for rk3036
In-Reply-To: <1440740808-15004-4-git-send-email-zhengxing@rock-chips.com>
References: <1440740808-15004-1-git-send-email-zhengxing@rock-chips.com>
 <1440740808-15004-4-git-send-email-zhengxing@rock-chips.com>
Message-ID: <4606154.zK3r9vHTef@phil>

Hi,

Am Freitag, 28. August 2015, 13:46:48 schrieb Xing Zheng:
> Add the clock tree definition for the new rk3036 SoC,
> but there are some issues to be fixed:
> 1. soc will crash if gpll run rate_change_remuxed
> 2. rk3036_clk_suspend and rk3036_clk_resume should be done
>    in clk-rk3036.c
> 
> ---
> 
> Changes in v1:
> Signed-off-by: Xing Zheng <zhengxing at rock-chips.com>
> 
>  drivers/clk/rockchip/Makefile          |    1 +
>  drivers/clk/rockchip/clk-pll.c         |  247 ++++++++++++++-

please split this into separate patches.
- addition of the new pll type
- three patches for binding-document, dt-binding header and clock controller
  like in "clk: rockchip: add support for the clock-tree of the rk3368"
  patches 4, 5 and 7:
  "dt-bindings: add documentation of rk3036 clock controller"
  "clk: rockchip: add dt-binding header for rk3036"
  "clk: rockchip: add rk3036 clock controller"

  so you should get in sum 4 clock patches.

[0] http://lists.infradead.org/pipermail/linux-rockchip/2015-July/003394.html


>  drivers/clk/rockchip/clk-rk3036.c      |  539
> ++++++++++++++++++++++++++++++++ drivers/clk/rockchip/clk.h             |  
> 30 ++
>  include/dt-bindings/clock/rk3036-cru.h |  247 +++++++++++++++
>  5 files changed, 1063 insertions(+), 1 deletion(-)
>  create mode 100644 drivers/clk/rockchip/clk-rk3036.c
>  create mode 100644 include/dt-bindings/clock/rk3036-cru.h
> 
> diff --git a/drivers/clk/rockchip/Makefile b/drivers/clk/rockchip/Makefile
> index b27edd6..d599829 100644
> --- a/drivers/clk/rockchip/Makefile
> +++ b/drivers/clk/rockchip/Makefile
> @@ -10,6 +10,7 @@ obj-y	+= clk-inverter.o
>  obj-y	+= clk-mmc-phase.o
>  obj-$(CONFIG_RESET_CONTROLLER)	+= softrst.o
> 
> +obj-y	+= clk-rk3036.o
>  obj-y	+= clk-rk3188.o
>  obj-y	+= clk-rk3288.o
>  obj-y	+= clk-rk3368.o
> diff --git a/drivers/clk/rockchip/clk-pll.c b/drivers/clk/rockchip/clk-pll.c
> index 96903ae..cf56826 100644
> --- a/drivers/clk/rockchip/clk-pll.c
> +++ b/drivers/clk/rockchip/clk-pll.c
> @@ -2,6 +2,9 @@
>   * Copyright (c) 2014 MundoReader S.L.
>   * Author: Heiko Stuebner <heiko at sntech.de>
>   *
> + * Copyright (c) 2015 Rockchip Electronics Co. Ltd.
> + * Author: Xing Zheng <zhengxing at 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
> @@ -48,6 +51,8 @@ struct rockchip_clk_pll {
>  #define to_rockchip_clk_pll_nb(nb) \
>  			container_of(nb, struct rockchip_clk_pll, clk_nb)
> 
> +static int rockchip_rk3036_pll_wait_lock(struct rockchip_clk_pll *pll);
> +
>  static const struct rockchip_pll_rate_table *rockchip_get_pll_settings(
>  			    struct rockchip_clk_pll *pll, unsigned long rate)
>  {
> @@ -90,6 +95,11 @@ static int rockchip_pll_wait_lock(struct rockchip_clk_pll
> *pll) unsigned int val;
>  	int delay = 24000000, ret;
> 
> +	/* the plls of rk3036 wait lock */
> +	if (pll->type == pll_rk3036 || pll->lock_offset == -1) {
> +		return rockchip_rk3036_pll_wait_lock(pll);
> +	}
> +

according to the rk3036 trm I have the GRF_SOC_STATUS0 [6:4] also contains the 
pll lock status like on the other socs. So you could just use the default 
mechanism of asking the GRF lock status like the other socs do, without 
needing to override the wait_lock .


>  	while (delay > 0) {
>  		ret = regmap_read(grf, pll->lock_offset, &val);
>  		if (ret) {
> @@ -305,6 +315,235 @@ static void rockchip_rk3066_pll_init(struct clk_hw
> *hw) rockchip_rk3066_pll_set_rate(hw, drate, prate);
>  	}
>  }
> +/**
> + * PLL used in RK3036
> + */
> +
> +#define RK3036_PLL_RESET_DELAY(nr)	((nr * 500) / 24 + 1)
> +
> +#define RK3036_PLLCON(i)			(i * 0x4)
> +#define RK3036_PLLCON0_FBDIV_MASK		0xfff
> +#define RK3036_PLLCON0_FBDIV_SHIFT		0
> +#define RK3036_PLLCON0_POSTDIV1_MASK		0x7
> +#define RK3036_PLLCON0_POSTDIV1_SHIFT		12
> +#define RK3036_PLLCON1_REFDIV_MASK		0x3f
> +#define RK3036_PLLCON1_REFDIV_SHIFT		0
> +#define RK3036_PLLCON1_POSTDIV2_MASK		0x7
> +#define RK3036_PLLCON1_POSTDIV2_SHIFT		6
> +#define RK3036_PLLCON1_DSMPD_MASK		0x1
> +#define RK3036_PLLCON1_DSMPD_SHIFT		12
> +#define RK3036_PLLCON2_FRAC_MASK		0xffffff
> +#define RK3036_PLLCON2_FRAC_SHIFT		0
> +
> +#define RK3036_MODECON				0x40
> +#define RK3036_MODECON_AWM			(1 << 0)  /* apll work mode */
> +
> +#define RK3036_PLLCON0_BYPASS			(1 << 15)
> +#define RK3036_PLLCON1_LOCK_STATUS		(1 << 10)
> +#define RK3036_PLLCON1_RESET			(1 << 14)
> +
> +static int rockchip_rk3036_pll_wait_lock(struct rockchip_clk_pll *pll)
> +{
> +	u32 pllcon;
> +	int delay = 24000000;
> +
> +	/* poll check the lock status in rk3036 xPLLCON1 */
> +	while (delay > 0) {
> +		pllcon = readl_relaxed(pll->reg_base + RK3036_PLLCON(1));
> +		if (pllcon & RK3036_PLLCON1_LOCK_STATUS)
> +			return 0;
> +
> +		delay--;
> +	}
> +
> +	pr_err("%s: timeout waiting for pll to lock\n", __func__);
> +	return -ETIMEDOUT;
> +}
> +
> +static unsigned long rockchip_rk3036_pll_recalc_rate(struct clk_hw *hw,
> +						     unsigned long prate)
> +{
> +	struct rockchip_clk_pll *pll = to_rockchip_clk_pll(hw);
> +	unsigned int fbdiv, postdiv1, refdiv, postdiv2, dsmpd, frac;
> +	u64 rate64 = prate;
> +	u32 pllcon;
> +
> +	pllcon = readl_relaxed(pll->reg_base + RK3036_PLLCON(0));
> +	fbdiv = ((pllcon >> RK3036_PLLCON0_FBDIV_SHIFT) &
> RK3036_PLLCON0_FBDIV_MASK); +	postdiv1 = ((pllcon >>
> RK3036_PLLCON0_POSTDIV1_SHIFT) & RK3036_PLLCON0_POSTDIV1_MASK); +
> +	pllcon = readl_relaxed(pll->reg_base + RK3036_PLLCON(1));
> +	refdiv = ((pllcon >> RK3036_PLLCON1_REFDIV_SHIFT) &
> RK3036_PLLCON1_REFDIV_MASK); +	postdiv2 = ((pllcon >>
> RK3036_PLLCON1_POSTDIV2_SHIFT) & RK3036_PLLCON1_POSTDIV2_MASK); +	dsmpd =
> ((pllcon >> RK3036_PLLCON1_DSMPD_SHIFT) & RK3036_PLLCON1_DSMPD_MASK); +
> +	pllcon = readl_relaxed(pll->reg_base + RK3036_PLLCON(2));
> +	frac = ((pllcon >> RK3036_PLLCON2_FRAC_SHIFT) & RK3036_PLLCON2_FRAC_MASK);
> +
> +	rate64 *= fbdiv;
> +	do_div(rate64, refdiv);
> +
> +	if (dsmpd == 0) {
> +		/* fractional mode */
> +		u64 frac_rate64 = prate * frac;
> +
> +		do_div(frac_rate64, refdiv);
> +		rate64 += frac_rate64 >> 24;
> +	}
> +
> +	do_div(rate64, postdiv1);
> +	do_div(rate64, postdiv2);
> +
> +	return (unsigned long)rate64;
> +}
> +
> +static int rockchip_rk3036_pll_set_rate(struct clk_hw *hw, unsigned long
> drate, +					unsigned long prate)
> +{
> +	struct rockchip_clk_pll *pll = to_rockchip_clk_pll(hw);
> +	const struct rockchip_pll_rate_table *rate;
> +	unsigned long old_rate = rockchip_rk3036_pll_recalc_rate(hw, prate);
> +	struct regmap *grf = rockchip_clk_get_grf();
> +	struct clk_mux *pll_mux = &pll->pll_mux;
> +	const struct clk_ops *pll_mux_ops = pll->pll_mux_ops;
> +	int rate_change_remuxed = 0;
> +	int cur_parent;
> +	int ret;
> +
> +	if (IS_ERR(grf)) {
> +		pr_debug("%s: grf regmap not available, aborting rate change\n",
> +			 __func__);
> +		return PTR_ERR(grf);
> +	}
> +
> +	pr_debug("%s: changing %s from %lu to %lu with a parent rate of %lu\n",
> +		 __func__, __clk_get_name(hw->clk), old_rate, drate, prate);
> +
> +	/* Get required rate settings from table */
> +	rate = rockchip_get_pll_settings(pll, drate);
> +	if (!rate) {
> +		pr_err("%s: Invalid rate : %lu for pll clk %s\n", __func__,
> +			drate, __clk_get_name(hw->clk));
> +		return -EINVAL;
> +	}
> +
> +	pr_debug("%s: rate settings for %lu fbdiv: %d, postdiv1: %d, refdiv: %d,
> postdiv2: %d, dsmpd: %d, frac: %d\n", +		__func__, rate->rate,
> +		rate->fbdiv, rate->postdiv1, rate->refdiv, rate->postdiv2, rate-
>dsmpd,
> rate->frac); +
> +	cur_parent = pll_mux_ops->get_parent(&pll_mux->hw);
> +	if (cur_parent == PLL_MODE_NORM) {
> +		pll_mux_ops->set_parent(&pll_mux->hw, PLL_MODE_SLOW);
> +		rate_change_remuxed = 1;
> +	}
> +
> +	/* enter reset mode */
> +	writel(HIWORD_UPDATE(1, RK3036_PLLCON1_RESET, 0), pll->reg_base +
> RK3036_PLLCON(1)); +
> +	/* update pll values */
> +	writel_relaxed(HIWORD_UPDATE(rate->fbdiv, RK3036_PLLCON0_FBDIV_MASK,
> +					  RK3036_PLLCON0_FBDIV_SHIFT) |
> +		       HIWORD_UPDATE(rate->postdiv1, RK3036_PLLCON0_POSTDIV1_MASK,
> +					     RK3036_PLLCON0_POSTDIV1_SHIFT),
> +		       pll->reg_base + RK3036_PLLCON(0));
> +
> +	writel_relaxed(HIWORD_UPDATE(rate->refdiv, RK3036_PLLCON1_REFDIV_MASK,
> +						   RK3036_PLLCON1_REFDIV_SHIFT) |
> +		       HIWORD_UPDATE(rate->postdiv2, RK3036_PLLCON1_POSTDIV2_MASK,
> +						     RK3036_PLLCON1_POSTDIV2_SHIFT) |
> +		       HIWORD_UPDATE(rate->dsmpd, RK3036_PLLCON1_DSMPD_MASK,
> +						  RK3036_PLLCON1_DSMPD_SHIFT),
> +		       pll->reg_base + RK3036_PLLCON(1));
> +
> +	writel_relaxed(HIWORD_UPDATE(rate->frac, RK3036_PLLCON2_FRAC_MASK,
> +						 RK3036_PLLCON2_FRAC_SHIFT),
> +		       pll->reg_base + RK3036_PLLCON(2));
> +
> +	/* recover normal mode and wait the reset_delay */
> +	writel(HIWORD_UPDATE(0, RK3036_PLLCON1_RESET, 0), pll->reg_base +
> RK3036_PLLCON(1)); +	udelay(RK3036_PLL_RESET_DELAY(rate->refdiv));
> +
> +	/* wait for the pll to lock */
> +	ret = rockchip_pll_wait_lock(pll);
> +	if (ret) {
> +		pr_warn("%s: pll did not lock, trying to restore old rate %lu\n",
> +			__func__, old_rate);
> +		rockchip_rk3036_pll_set_rate(hw, old_rate, prate);
> +	}
> +
> +#if 0 /* FIXME: soc will crash if gpll run here */
> +	if (rate_change_remuxed)
> +		pll_mux_ops->set_parent(&pll_mux->hw, PLL_MODE_NORM);
> +#endif

please don't leave commented code ("if 0") around and we should of course find 
out what is failing beforehand, so this can be enabled again.

Because as the code stands now, you're running on the gpll all the time.


> +
> +	return ret;
> +}
> +static void rockchip_rk3036_pll_init(struct clk_hw *hw)
> +{
> +	struct rockchip_clk_pll *pll = to_rockchip_clk_pll(hw);
> +	const struct rockchip_pll_rate_table *rate;
> +	unsigned int fbdiv, postdiv1, refdiv, postdiv2, dsmpd, frac;
> +	unsigned long drate;
> +	u32 pllcon;
> +
> +	if (!(pll->flags & ROCKCHIP_PLL_SYNC_RATE))
> +		return;
> +
> +	drate = __clk_get_rate(hw->clk);
> +	rate = rockchip_get_pll_settings(pll, drate);
> +
> +	/* when no rate setting for the current rate, rely on clk_set_rate */
> +	if (!rate)
> +		return;
> +
> +	pllcon = readl_relaxed(pll->reg_base + RK3036_PLLCON(0));
> +	fbdiv = ((pllcon >> RK3036_PLLCON0_FBDIV_SHIFT) &
> RK3036_PLLCON0_FBDIV_MASK); +	postdiv1 = ((pllcon >>
> RK3036_PLLCON0_POSTDIV1_SHIFT) & RK3036_PLLCON0_POSTDIV1_MASK); +
> +	pllcon = readl_relaxed(pll->reg_base + RK3036_PLLCON(1));
> +	refdiv = ((pllcon >> RK3036_PLLCON1_REFDIV_SHIFT) &
> RK3036_PLLCON1_REFDIV_MASK); +	postdiv2 = ((pllcon >>
> RK3036_PLLCON1_POSTDIV2_SHIFT) & RK3036_PLLCON1_POSTDIV2_MASK); +	dsmpd =
> ((pllcon >> RK3036_PLLCON1_DSMPD_SHIFT) & RK3036_PLLCON1_DSMPD_MASK); +
> +	pllcon = readl_relaxed(pll->reg_base + RK3036_PLLCON(2));
> +	frac = ((pllcon >> RK3036_PLLCON2_FRAC_SHIFT) & RK3036_PLLCON2_FRAC_MASK);
> +
> +	pr_info("%s: pll %s@%lu: Hz\n", __func__, __clk_get_name(hw->clk), drate);
> +	pr_info("old - fbdiv: %d, postdiv1: %d, refdiv: %d, postdiv2: %d, dsmpd:
> %d, frac: %d\n", +		fbdiv, postdiv1, refdiv, postdiv2, dsmpd, frac);
> +	pr_info("new - fbdiv: %d, postdiv1: %d, refdiv: %d, postdiv2: %d, dsmpd:
> %d, frac: %d\n", +		rate->fbdiv, rate->postdiv1, rate->refdiv,
> rate->postdiv2, rate->dsmpd, rate->frac);

please don't leave pr_info calls for debug messages in the code, like in the 
rk3066 pll-type these should be pr_debug.


> +
> +	if (rate->fbdiv != fbdiv || rate->postdiv1 != postdiv1 || rate->refdiv !=
> refdiv || +		rate->postdiv2 != postdiv2 || rate->dsmpd != dsmpd ||
> rate->frac != frac) { +		struct clk *parent = __clk_get_parent(hw->clk);
> +		unsigned long prate;
> +
> +		if (!parent) {
> +			pr_warn("%s: parent of %s not available\n",
> +				__func__, __clk_get_name(hw->clk));
> +			return;
> +		}
> +
> +		pr_info("%s: pll %s: rate params do not match rate table, 
adjusting\n",
> +			 __func__, __clk_get_name(hw->clk));
> +		prate = __clk_get_rate(parent);
> +		rockchip_rk3036_pll_set_rate(hw, drate, prate);
> +	}
> +}
> +static const struct clk_ops rockchip_rk3036_pll_clk_norate_ops = {
> +	.recalc_rate = rockchip_rk3036_pll_recalc_rate,
> +	.round_rate = rockchip_pll_round_rate,
> +	.set_rate = rockchip_rk3036_pll_set_rate,
> +	.init = rockchip_rk3036_pll_init,
> +};

the ops for plls without rate table should not contain round_rate and set_rate 
callbacks, as without rate-table you of course cannot set any rate


> +
> +static const struct clk_ops rockchip_rk3036_pll_clk_ops = {
> +	.recalc_rate = rockchip_rk3036_pll_recalc_rate,
> +	.round_rate = rockchip_pll_round_rate,
> +	.set_rate = rockchip_rk3036_pll_set_rate,
> +	.init = rockchip_rk3036_pll_init,
> +};

The rk3036 pll-type also has a powerdown function it seems (xPLL_CON1[13]), so 
you can also add appropriate enable, disable and is_enabled callbacks for both 
ops structs.


>  static const struct clk_ops rockchip_rk3066_pll_clk_norate_ops = {
>  	.recalc_rate = rockchip_rk3066_pll_recalc_rate,
> @@ -385,6 +624,12 @@ struct clk *rockchip_clk_register_pll(enum
> rockchip_pll_type pll_type, else
>  			init.ops = &rockchip_rk3066_pll_clk_ops;
>  		break;
> +	case pll_rk3036:
> +		if (!pll->rate_table)
> +			init.ops = &rockchip_rk3036_pll_clk_norate_ops;
> +		else
> +			init.ops = &rockchip_rk3036_pll_clk_ops;
> +		break;
>  	default:
>  		pr_warn("%s: Unknown pll type for pll clk %s\n",
>  			__func__, name);
> @@ -408,7 +653,7 @@ struct clk *rockchip_clk_register_pll(enum
> rockchip_pll_type pll_type, pll_mux->lock = lock;
>  	pll_mux->hw.init = &init;
> 
> -	if (pll_type == pll_rk3066)
> +	if (pll_type == pll_rk3066 || pll_type == pll_rk3036)
>  		pll_mux->flags |= CLK_MUX_HIWORD_MASK;
> 
>  	pll_clk = clk_register(NULL, &pll->hw);
> diff --git a/drivers/clk/rockchip/clk-rk3036.c
> b/drivers/clk/rockchip/clk-rk3036.c new file mode 100644
> index 0000000..19cdf0e
> --- /dev/null
> +++ b/drivers/clk/rockchip/clk-rk3036.c
> @@ -0,0 +1,539 @@
> +/*
> + * Copyright (c) 2014 MundoReader S.L.
> + * Author: Heiko Stuebner <heiko at sntech.de>
> + *
> + * Copyright (c) 2015 Rockchip Electronics Co. Ltd.
> + * Author: Xing Zheng <zhengxing at 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/rk3036-cru.h>
> +#include "clk.h"
> +
> +enum rk3036_plls {
> +	apll, dpll, gpll,
> +};
> +
> +static struct rockchip_pll_rate_table rk3036_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),
> +	RK3036_PLL_RATE(0, 1, 0, 1, 1, 1, 0),
> +	{ /* sentinel */ },
> +};
> +
> +#define RK3036_DIV_CPU_MASK		0x1f
> +#define RK3036_DIV_CPU_SHIFT		8
> +
> +#define RK3036_DIV_PERI_MASK		0xf
> +#define RK3036_DIV_PERI_SHIFT		0

> +#define RK3036_DIV_ACLK_MASK		0x7
> +#define RK3036_DIV_ACLK_SHIFT		4
> +#define RK3036_DIV_HCLK_MASK		0x3
> +#define RK3036_DIV_HCLK_SHIFT		8
> +#define RK3036_DIV_PCLK_MASK		0x7
> +#define RK3036_DIV_PCLK_SHIFT		12
> +
> +#define RK3036_CLKSEL1(_core_periph_div)					\
> +	{									\
> +		.reg = RK2928_CLKSEL_CON(1),					\
> +		.val = HIWORD_UPDATE(_core_periph_div, RK3036_DIV_PERI_MASK,	\
> +				RK3036_DIV_PERI_SHIFT)				\
> +	}
> +
> +#define RK3036_CPUCLK_RATE(_prate, _core_periph_div)			\
> +	{								\
> +		.prate = _prate,					\
> +		.divs = {						\
> +			RK3036_CLKSEL1(_core_periph_div),		\
> +		},							\
> +	}
> +
> +static struct rockchip_cpuclk_rate_table rk3036_cpuclk_rates[] __initdata =
> { +	RK3036_CPUCLK_RATE(816000000, 4),
> +	RK3036_CPUCLK_RATE(600000000, 4),
> +	RK3036_CPUCLK_RATE(312000000, 4),
> +};

this seems to be missing divider settings for aclk_core? I only see the core-
periph ones (for pclk_dbg) but not for aclk_core that is also sourced from the 
cpuclk?


> +
> +static const struct rockchip_cpuclk_reg_data rk3036_cpuclk_data = {
> +	.core_reg = RK2928_CLKSEL_CON(0),
> +	.div_core_shift = 0,
> +	.div_core_mask = 0x1f,
> +	.mux_core_shift = 7,
> +};
> +
> +PNAME(mux_pll_p)		= { "xin24m", "xin24m" };
> +
> +PNAME(mux_armclk_p)		= { "apll", "gpll_armclk" };
> +PNAME(mux_busclk_p)		= { "apll", "dpll_cpu", "gpll_cpu" };
> +PNAME(mux_ddrphy_p)		= { "dpll_ddr", "gpll_ddr" };
> +PNAME(mux_pll_src_3plls_p)	= { "apll", "dpll", "gpll" };
> +PNAME(mux_timer_p)		= { "xin24m", "pclk_peri_src" };
> +
> +PNAME(mux_pll_src_apll_gpll_dpll_usb480m_p)	= { "apll", "gpll", "dpll"
> "usb480m" }; +
> +PNAME(mux_mmc_src_p)	= { "apll", "gpll", "dpll", "xin24m" };
> +PNAME(mux_i2s_pre_p)	= { "i2s_src", "i2s_frac", "ext_i2s", "xin12m" };
> +PNAME(mux_i2s_clkout_p)	= { "i2s_pre", "xin12m" };
> +PNAME(mux_spdif_p)	= { "spdif_src", "spdif_frac", "xin12m" };
> +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" };
> +PNAME(mux_mac_p)	= { "mac_pll_src", "ext_gmac" };
> +PNAME(mux_dclk_p)	= { "dclk_lcdc", "dclk_hdmi_src" };
> +
> +static struct rockchip_pll_clock rk3036_pll_clks[] __initdata = {
> +	[apll] = PLL(pll_rk3036, PLL_APLL, "apll", mux_pll_p, 0,
> RK2928_PLL_CON(0), +		     RK2928_MODE_CON, 0, 10, 0, rk3036_pll_rates),
> +	[dpll] = PLL(pll_rk3036, PLL_DPLL, "dpll", mux_pll_p, 0,
> RK2928_PLL_CON(4), +		     RK2928_MODE_CON, 4, 10, 0, NULL),
> +	[gpll] = PLL(pll_rk3036, PLL_GPLL, "gpll", mux_pll_p, 0,
> RK2928_PLL_CON(12), +		     RK2928_MODE_CON, 12, 10,
> ROCKCHIP_PLL_SYNC_RATE, rk3036_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 rk3036_clk_branches[] __initdata = {
> +	/*
> +	 * Clock-Architecture Diagram 1
> +	 */
> +
> +	/* PD_CORE */
> +	GATE(0, "gpll_armclk", "gpll", CLK_IGNORE_UNUSED,
> +			RK2928_CLKGATE_CON(0), 6, GFLAGS),
> +
> +	/* PD_DDR */
> +	GATE(0, "dpll_ddr", "dpll", CLK_IGNORE_UNUSED,
> +			RK2928_CLKGATE_CON(0), 2, GFLAGS),
> +	GATE(0, "gpll_ddr", "gpll", 0,
> +			RK2928_CLKGATE_CON(0), 8, GFLAGS),
> +	COMPOSITE_NOGATE(0, "ddrphy2x", mux_ddrphy_p, CLK_IGNORE_UNUSED,
> +			RK2928_CLKSEL_CON(26), 8, 1, MFLAGS, 0, 2,
> +					DFLAGS | CLK_DIVIDER_POWER_OF_TWO),

please keep the formatting. With the big number of clock definitions, reading 
is easier if everything stays in one place without additional line-breaks.
So please move the "DFLAGS | ..." part up into the previous line. (same if 
this occures somewhere lese)


> +
> +	/* PD_CORE */
> +	COMPOSITE_NOMUX(0, "pclk_dbg", "armclk", CLK_IGNORE_UNUSED,
> +			RK2928_CLKSEL_CON(1), 0, 4, DFLAGS | CLK_DIVIDER_READ_ONLY,
> +			RK2928_CLKGATE_CON(0), 7, GFLAGS),
> +	COMPOSITE_NOMUX(0, "aclk_core_pre", "armclk", 0,
> +			RK2928_CLKSEL_CON(1), 4, 3, DFLAGS | CLK_DIVIDER_READ_ONLY,
> +			RK2928_CLKGATE_CON(0), 7, GFLAGS),
> +
> +	/* PD_CPU (BUS) */
> +	GATE(0, "dpll_cpu", "dpll", 0, RK2928_CLKGATE_CON(10), 8, GFLAGS),
> +	GATE(0, "gpll_cpu", "gpll", 0, RK2928_CLKGATE_CON(0), 1, GFLAGS),
> +	COMPOSITE_NOGATE(0, "aclk_cpu_src", mux_busclk_p, 0,
> +			RK2928_CLKSEL_CON(0), 14, 2, MFLAGS, 8, 5, DFLAGS),
> +	GATE(ACLK_CPU, "aclk_cpu", "aclk_cpu_src", 0, RK2928_CLKGATE_CON(0), 3,
> GFLAGS), +	COMPOSITE_NOMUX(PCLK_CPU, "pclk_cpu", "aclk_cpu_src", 0,
> +			RK2928_CLKSEL_CON(1), 12, 3, DFLAGS | CLK_DIVIDER_READ_ONLY,
> +			RK2928_CLKGATE_CON(0), 5, GFLAGS),
> +	COMPOSITE_NOMUX(HCLK_CPU, "hclk_cpu", "aclk_cpu_src", 0,
> +			RK2928_CLKSEL_CON(1), 8, 2, DFLAGS | CLK_DIVIDER_READ_ONLY,
> +			RK2928_CLKGATE_CON(0), 4, GFLAGS),
> +
> +	/* PD_PERI */
> +	COMPOSITE(0, "aclk_peri_src", mux_pll_src_3plls_p, 0,
> +			RK2928_CLKSEL_CON(10), 14, 2, MFLAGS, 0, 5, DFLAGS,
> +			RK2928_CLKGATE_CON(2), 0, GFLAGS),
> +
> +	GATE(ACLK_PERI, "aclk_peri", "aclk_peri_src", 0,
> +			RK2928_CLKGATE_CON(2), 1, GFLAGS),
> +	/* pclk_peri_src is soure for timers */
> +	DIV(0, "pclk_peri_src", "aclk_peri_src", CLK_IGNORE_UNUSED,
> +			RK2928_CLKSEL_CON(10), 12, 2, DFLAGS | 
CLK_DIVIDER_POWER_OF_TWO),
> +	GATE(PCLK_PERI, "pclk_peri", "pclk_peri_src", 0,
> +			RK2928_CLKGATE_CON(2), 3, GFLAGS),
> +	/* hclk_peri_src is soure for sclk_macref_out */
> +	DIV(0, "hclk_peri_src", "aclk_peri_src", CLK_IGNORE_UNUSED,
> +			RK2928_CLKSEL_CON(10), 8, 2, DFLAGS | CLK_DIVIDER_POWER_OF_TWO),
> +	GATE(HCLK_PERI, "hclk_peri", "hclk_peri_src", 0,
> +			RK2928_CLKGATE_CON(2), 2, GFLAGS),
> +
> +	/* PD_TIMER */
> +	COMPOSITE_NODIV(SCLK_TIMER0, "sclk_timer0", mux_timer_p, 0,
> +			RK2928_CLKSEL_CON(2), 4, 1, DFLAGS,
> +			RK2928_CLKGATE_CON(1), 0, GFLAGS),
> +	COMPOSITE_NODIV(SCLK_TIMER1, "sclk_timer1", mux_timer_p, 0,
> +			RK2928_CLKSEL_CON(2), 5, 1, DFLAGS,
> +			RK2928_CLKGATE_CON(1), 1, GFLAGS),
> +	COMPOSITE_NODIV(SCLK_TIMER2, "sclk_timer2", mux_timer_p, 0,
> +			RK2928_CLKSEL_CON(2), 6, 1, DFLAGS,
> +			RK2928_CLKGATE_CON(2), 4, GFLAGS),
> +	COMPOSITE_NODIV(SCLK_TIMER3, "sclk_timer3", mux_timer_p, 0,
> +			RK2928_CLKSEL_CON(2), 7, 1, DFLAGS,
> +			RK2928_CLKGATE_CON(2), 5, GFLAGS),
> +
> +	/* PD_UART */
> +	MUX(0, "uart_pll_clk", mux_pll_src_apll_gpll_dpll_usb480m_p, 0,
> +			RK2928_CLKSEL_CON(13), 10, 2, MFLAGS),
> +	COMPOSITE_NOMUX(0, "uart0_src", "uart_pll_clk", 0,
> +			RK2928_CLKSEL_CON(13), 0, 7, DFLAGS,
> +			RK2928_CLKGATE_CON(1), 8, GFLAGS),
> +	COMPOSITE_NOMUX(0, "uart1_src", "uart_pll_clk", 0,
> +			RK2928_CLKSEL_CON(13), 0, 7, DFLAGS,
> +			RK2928_CLKGATE_CON(1), 8, GFLAGS),
> +	COMPOSITE_NOMUX(0, "uart2_src", "uart_pll_clk", 0,
> +			RK2928_CLKSEL_CON(13), 0, 7, DFLAGS,
> +			RK2928_CLKGATE_CON(1), 8, GFLAGS),
> +	COMPOSITE_FRAC(0, "uart0_frac", "uart0_src", CLK_SET_RATE_PARENT,
> +			RK2928_CLKSEL_CON(17), 0,
> +			RK2928_CLKGATE_CON(1), 9, GFLAGS),
> +	COMPOSITE_FRAC(0, "uart1_frac", "uart1_src", CLK_SET_RATE_PARENT,
> +			RK2928_CLKSEL_CON(18), 0,
> +			RK2928_CLKGATE_CON(1), 11, GFLAGS),
> +	COMPOSITE_FRAC(0, "uart2_frac", "uart2_src", CLK_SET_RATE_PARENT,
> +			RK2928_CLKSEL_CON(19), 0,
> +			RK2928_CLKGATE_CON(1), 13, GFLAGS),
> +	MUX(SCLK_UART0, "sclk_uart0", mux_uart0_p, CLK_SET_RATE_PARENT,
> +			RK2928_CLKSEL_CON(13), 8, 2, MFLAGS),
> +	MUX(SCLK_UART1, "sclk_uart1", mux_uart1_p, CLK_SET_RATE_PARENT,
> +			RK2928_CLKSEL_CON(14), 8, 2, MFLAGS),
> +	MUX(SCLK_UART2, "sclk_uart2", mux_uart2_p, CLK_SET_RATE_PARENT,
> +			RK2928_CLKSEL_CON(15), 8, 2, MFLAGS),
> +
> +	/* PD_VIDEO */
> +	COMPOSITE(0, "aclk_vcodec", mux_pll_src_3plls_p, 0,
> +			RK2928_CLKSEL_CON(32), 14, 2, MFLAGS, 8, 5, DFLAGS,
> +			RK2928_CLKGATE_CON(3), 11, GFLAGS),
> +
> +	COMPOSITE(0, "aclk_hvec", mux_pll_src_3plls_p, 0,
> +			RK2928_CLKSEL_CON(20), 0, 2, MFLAGS, 2, 5, DFLAGS,
> +			RK2928_CLKGATE_CON(10), 6, GFLAGS),
> +
> +	/* PD_VIO */
> +	COMPOSITE(0, "aclk_disp1_pre", mux_pll_src_3plls_p, 0,
> +			RK2928_CLKSEL_CON(31), 14, 2, MFLAGS, 8, 5, DFLAGS,
> +			RK2928_CLKGATE_CON(1), 4, GFLAGS),
> +	COMPOSITE(0, "hclk_disp_pre", mux_pll_src_3plls_p, 0,
> +			RK2928_CLKSEL_CON(30), 14, 2, MFLAGS, 8, 5, DFLAGS,
> +			RK2928_CLKGATE_CON(0), 11, GFLAGS),
> +	COMPOSITE(DCLK_LCDC, "dclk_lcdc", mux_pll_src_3plls_p, 0,
> +			RK2928_CLKSEL_CON(28), 0, 2, MFLAGS, 8, 8, DFLAGS,
> +			RK2928_CLKGATE_CON(3), 2, GFLAGS),
> +
> +	/* MMC */
> +	COMPOSITE_NODIV(0, "sclk_sdmmc_src", mux_mmc_src_p, 0,
> +			RK2928_CLKSEL_CON(12), 8, 2, DFLAGS,
> +			RK2928_CLKGATE_CON(2), 11, GFLAGS),
> +	DIV(SCLK_SDMMC, "sclk_sdmmc", "sclk_sdmmc_src", 0,
> +			RK2928_CLKSEL_CON(11), 0, 7, DFLAGS),
> +
> +	COMPOSITE_NODIV(0, "sclk_sdio_src", mux_mmc_src_p, 0,
> +			RK2928_CLKSEL_CON(12), 10, 2, DFLAGS,
> +			RK2928_CLKGATE_CON(2), 13, GFLAGS),
> +	DIV(SCLK_SDIO, "sclk_sdio", "sclk_sdio_src", 0,
> +			RK2928_CLKSEL_CON(11), 8, 7, DFLAGS),
> +
> +	COMPOSITE(SCLK_EMMC, "sclk_emmc", mux_mmc_src_p, 0,
> +			RK2928_CLKSEL_CON(12), 12, 2, MFLAGS, 0, 7, DFLAGS,
> +			RK2928_CLKGATE_CON(2), 14, GFLAGS),
> +
> +	MMC(SCLK_SDMMC_DRV,    "sdmmc_drv",    "sclk_sdmmc", RK3036_SDMMC_CON0,
> 1), +	MMC(SCLK_SDMMC_SAMPLE, "sdmmc_sample", "sclk_sdmmc",
> RK3036_SDMMC_CON1, 0), +
> +	MMC(SCLK_SDIO_DRV,    "sdio_drv",    "sclk_sdio", RK3036_SDIO_CON0, 1),
> +	MMC(SCLK_SDIO_SAMPLE, "sdio_sample", "sclk_sdio", RK3036_SDIO_CON1, 0),
> +
> +	MMC(SCLK_EMMC_DRV,     "emmc_drv",     "sclk_emmc",  RK3036_EMMC_CON0, 
> 1), +	MMC(SCLK_EMMC_SAMPLE,  "emmc_sample",  "sclk_emmc", 
> RK3036_EMMC_CON1,  0), +
> +	/* I2S */
> +	COMPOSITE(0, "i2s_src", mux_pll_src_3plls_p, 0,
> +			RK2928_CLKSEL_CON(3), 14, 1, MFLAGS, 0, 7, DFLAGS,
> +			RK2928_CLKGATE_CON(0), 9, GFLAGS),
> +	COMPOSITE_FRAC(0, "i2s_frac", "i2s_src", CLK_SET_RATE_PARENT,
> +			RK2928_CLKSEL_CON(7), 0,
> +			RK2928_CLKGATE_CON(0), 10, GFLAGS),
> +	MUX(0, "i2s_pre", mux_i2s_pre_p, CLK_SET_RATE_PARENT,
> +			RK2928_CLKSEL_CON(3), 8, 2, MFLAGS),
> +	COMPOSITE_NODIV(SCLK_I2S_OUT, "i2s_clkout", mux_i2s_clkout_p, 0,
> +			RK2928_CLKSEL_CON(4), 12, 1, MFLAGS,
> +			RK2928_CLKGATE_CON(0), 13, GFLAGS),
> +	GATE(SCLK_I2S, "sclk_i2s", "i2s_pre", CLK_SET_RATE_PARENT,
> +			RK2928_CLKGATE_CON(0), 14, GFLAGS),
> +
> +	COMPOSITE(0, "spdif_src", mux_pll_src_3plls_p, 0,
> +			RK2928_CLKSEL_CON(5), 10, 2, MFLAGS, 0, 7, DFLAGS,
> +			RK2928_CLKGATE_CON(2), 10, GFLAGS),
> +	COMPOSITE_FRAC(0, "spdif_frac", "spdif_src", 0,
> +			RK2928_CLKSEL_CON(9), 0,
> +			RK2928_CLKGATE_CON(2), 12, GFLAGS),
> +	MUX(SCLK_SPDIF, "sclk_spdif", mux_spdif_p, 0,
> +			RK2928_CLKSEL_CON(5), 8, 2, MFLAGS),
> +	/* USB */
> +	GATE(0, "hsicphy12m_xin12m", "xin12m", 0,
> +			RK2928_CLKGATE_CON(1), 5, GFLAGS),
> +
> +	/* GPU */

some of these comments are redundant ... if the clock is already named 
sclk_gpu a comment GPU above does not help any :-)

Same for SPI, NANDC and everything else you might find.


> +	COMPOSITE(SCLK_GPU, "sclk_gpu", mux_pll_src_3plls_p, 0,
> +			RK2928_CLKSEL_CON(34), 8, 2, MFLAGS, 0, 5, DFLAGS,
> +			RK2928_CLKGATE_CON(3), 13, GFLAGS),
> +
> +	/* SPI */
> +	COMPOSITE(SCLK_SPI, "sclk_spi", mux_pll_src_3plls_p, 0,
> +			RK2928_CLKSEL_CON(25), 8, 2, MFLAGS, 0, 7, DFLAGS,
> +			RK2928_CLKGATE_CON(2), 9, GFLAGS),
> +
> +	/* NANDC */
> +	COMPOSITE(SCLK_NANDC, "sclk_nandc", mux_pll_src_3plls_p, 0,
> +			RK2928_CLKSEL_CON(16), 8, 2, MFLAGS, 10, 5, DFLAGS,
> +			RK2928_CLKGATE_CON(10), 4, GFLAGS),
> +
> +	/* SFC */
> +	COMPOSITE(SCLK_SFC, "sclk_sfc", mux_pll_src_apll_gpll_dpll_usb480m_p, 0,
> +			RK2928_CLKSEL_CON(16), 0, 2, MFLAGS, 2, 5, DFLAGS,
> +			RK2928_CLKGATE_CON(10), 5, GFLAGS),
> +
> +	/* MAC */
> +	COMPOSITE_NOGATE(0, "mac_pll_src", mux_pll_src_3plls_p, 0,
> +			RK2928_CLKSEL_CON(21), 0, 2, MFLAGS, 4, 5, DFLAGS),
> +	/* for clk_mac_ref & clk_mac_refout */
> +	MUX(SCLK_MACREF, "mac_clk_ref", mux_mac_p, CLK_SET_RATE_PARENT,
> +			RK2928_CLKSEL_CON(21), 3, 1, MFLAGS),
> +
> +	COMPOSITE_NOMUX(SCLK_MAC, "mac_clk", "mac_clk_ref", 0,
> +			RK2928_CLKSEL_CON(21), 9, 5, DFLAGS,
> +			RK2928_CLKGATE_CON(2), 6, GFLAGS),
> +

The hdmi diagram is actually labeled "Clock Architecture Diagram 2"

> +	/* HDMI */
> +	/* total clks: pin_sys_clk / pin_sck / pin_mclk / pin_vclk /
> pin_vclk_pllref */ +	/* the same with dclk_lcdc */
> +	COMPOSITE(0, "dclk_hdmi_src", mux_pll_src_3plls_p, 0,
> +			RK2928_CLKSEL_CON(28), 0, 2, MFLAGS, 8, 8, DFLAGS,
> +			RK2928_CLKGATE_CON(3), 2, GFLAGS),
> +	/* hdmi dclk from dclk_lcdc directly */
> +	MUX(SCLK_HDMI, "dclk_hdmi", mux_dclk_p, 0,
> +			RK2928_CLKSEL_CON(31), 0, 1, MFLAGS),
> +
> +	/*
> +	 * Clock-Architecture Diagram 2

The gates are in Diagram 3 in the RK3036 TRM I have


> +	 */
> +
> +	/* aclk_cpu gates */
> +	GATE(0, "sclk_intmem", "aclk_cpu", CLK_IGNORE_UNUSED,
> RK2928_CLKGATE_CON(4), 12, GFLAGS), +	GATE(0, "aclk_strc_sys", "aclk_cpu",
> CLK_IGNORE_UNUSED, RK2928_CLKGATE_CON(4), 10, GFLAGS), +
> +	/* hclk_cpu gates */
> +	GATE(HCLK_ROM, "hclk_rom", "hclk_cpu", CLK_IGNORE_UNUSED,
> RK2928_CLKGATE_CON(5), 6, GFLAGS), +
> +	/* pclk_cpu gates */
> +	GATE(PCLK_GRF, "pclk_grf", "pclk_cpu", 0, RK2928_CLKGATE_CON(5), 4,
> GFLAGS), +	GATE(PCLK_DDRUPCTL, "pclk_ddrupctl", "pclk_cpu", 0,
> RK2928_CLKGATE_CON(5), 7, GFLAGS), +	GATE(ACLK_VCODEC, "pclk_acodec",
> "pclk_cpu", 0, RK2928_CLKGATE_CON(5), 14, GFLAGS), +	GATE(PCLK_HDMI,
> "pclk_hdmi", "pclk_cpu", 0, RK2928_CLKGATE_CON(3), 8, GFLAGS), +
> +	/* aclk_vio gates */
> +	GATE(ACLK_VIO, "aclk_vio", "aclk_disp1_pre", 0,
> +			RK2928_CLKGATE_CON(6), 13, GFLAGS),
> +	GATE(ACLK_LCDC, "aclk_lcdc", "aclk_disp1_pre", 0,
> +			RK2928_CLKGATE_CON(9), 6, GFLAGS),
> +
> +	GATE(HCLK_VIO_BUS, "hclk_vio_bus", "hclk_disp_pre", 0,
> +			RK2928_CLKGATE_CON(6), 12, GFLAGS),
> +	GATE(HCLK_LCDC, "hclk_lcdc", "hclk_disp_pre", 0,
> +			RK2928_CLKGATE_CON(9), 5, GFLAGS),
> +
> +	/* aclk_video gates */
> +	GATE(HCLK_LCDC, "hclk_vcodec", "hclk_disp_pre", 0,
> +			RK2928_CLKGATE_CON(3), 12, GFLAGS),
> +
> +	/* xin24m gates */
> +	GATE(SCLK_PVTM_CORE, "sclk_pvtm_core", "xin24m", 0,
> RK2928_CLKGATE_CON(10), 0, GFLAGS), +	GATE(SCLK_PVTM_GPU, "sclk_pvtm_gpu",
> "xin24m", 0, RK2928_CLKGATE_CON(10), 1, GFLAGS), +
> +	/* aclk_peri gates */
> +	GATE(0, "aclk_peri_axi_matrix", "aclk_peri", CLK_IGNORE_UNUSED,
> RK2928_CLKGATE_CON(4), 3, GFLAGS), +	GATE(0, "aclk_cpu_peri", "aclk_peri",
> CLK_IGNORE_UNUSED, RK2928_CLKGATE_CON(4), 2, GFLAGS), +	GATE(ACLK_DMAC2,
> "aclk_dmac2", "aclk_peri", 0, RK2928_CLKGATE_CON(5), 1, GFLAGS), +	GATE(0,
> "aclk_peri_niu", "aclk_peri", CLK_IGNORE_UNUSED, RK2928_CLKGATE_CON(9), 15,
> GFLAGS), +
> +	/* hclk_peri gates */
> +	GATE(0, "hclk_peri_matrix", "hclk_peri", CLK_IGNORE_UNUSED,
> RK2928_CLKGATE_CON(4), 0, GFLAGS), +	GATE(0, "hclk_usb_peri", "hclk_peri",
> CLK_IGNORE_UNUSED, RK2928_CLKGATE_CON(9), 13, GFLAGS), +	GATE(0,
> "hclk_peri_arbi", "hclk_peri", CLK_IGNORE_UNUSED, RK2928_CLKGATE_CON(9),
> 14, GFLAGS), +	GATE(HCLK_NANDC, "hclk_nandc", "hclk_peri", 0,
> RK2928_CLKGATE_CON(5), 9, GFLAGS), +	GATE(HCLK_SDMMC, "hclk_sdmmc",
> "hclk_peri", 0, RK2928_CLKGATE_CON(5), 10, GFLAGS), +	GATE(HCLK_SDIO,
> "hclk_sdio", "hclk_peri", 0, RK2928_CLKGATE_CON(5), 11, GFLAGS),
> +	GATE(HCLK_EMMC, "hclk_emmc", "hclk_peri", 0, RK2928_CLKGATE_CON(7), 0,
> GFLAGS), +	GATE(HCLK_OTG0, "hclk_otg0", "hclk_peri", CLK_IGNORE_UNUSED,
> RK2928_CLKGATE_CON(5), 13, GFLAGS), +	GATE(HCLK_OTG1, "hclk_otg1",
> "hclk_peri", CLK_IGNORE_UNUSED, RK2928_CLKGATE_CON(7), 13, GFLAGS),
> +	GATE(HCLK_I2S, "hclk_i2s", "hclk_peri", CLK_IGNORE_UNUSED,
> RK2928_CLKGATE_CON(7), 2, GFLAGS), +	GATE(0, "hclk_sfc", "hclk_peri",
> CLK_IGNORE_UNUSED, RK2928_CLKGATE_CON(3), 14, GFLAGS), +	GATE(0,
> "hclk_mac", "hclk_peri", CLK_IGNORE_UNUSED, RK2928_CLKGATE_CON(3), 15,
> GFLAGS), +
> +	/* pclk_peri gates */
> +	GATE(0, "pclk_peri_matrix", "pclk_peri", CLK_IGNORE_UNUSED,
> RK2928_CLKGATE_CON(4), 1, GFLAGS), +	GATE(0, "pclk_efuse", "pclk_peri",
> CLK_IGNORE_UNUSED, RK2928_CLKGATE_CON(5), 2, GFLAGS), +	GATE(PCLK_TIMER,
> "pclk_timer0", "pclk_peri", 0, RK2928_CLKGATE_CON(7), 7, GFLAGS),
> +	GATE(PCLK_PWM, "pclk_pwm", "pclk_peri", 0, RK2928_CLKGATE_CON(7), 10,
> GFLAGS), +	GATE(PCLK_SPI, "pclk_spi", "pclk_peri", 0,
> RK2928_CLKGATE_CON(7), 12, GFLAGS), +	GATE(PCLK_WDT, "pclk_wdt",
> "pclk_peri", 0, RK2928_CLKGATE_CON(7), 15, GFLAGS), +	GATE(PCLK_UART0,
> "pclk_uart0", "pclk_peri", 0, RK2928_CLKGATE_CON(8), 0, GFLAGS),
> +	GATE(PCLK_UART1, "pclk_uart1", "pclk_peri", 0, RK2928_CLKGATE_CON(8), 1,
> GFLAGS), +	GATE(PCLK_UART2, "pclk_uart2", "pclk_peri", 0,
> RK2928_CLKGATE_CON(8), 2, GFLAGS), +	GATE(PCLK_I2C0, "pclk_i2c0",
> "pclk_peri", 0, RK2928_CLKGATE_CON(8), 4, GFLAGS), +	GATE(PCLK_I2C1,
> "pclk_i2c1", "pclk_peri", 0, RK2928_CLKGATE_CON(8), 5, GFLAGS),
> +	GATE(PCLK_I2C2, "pclk_i2c2", "pclk_peri", 0, RK2928_CLKGATE_CON(8), 6,
> GFLAGS), +	GATE(PCLK_GPIO0, "pclk_gpio0", "pclk_peri", 0,
> RK2928_CLKGATE_CON(8), 9, GFLAGS), +	GATE(PCLK_GPIO1, "pclk_gpio1",
> "pclk_peri", 0, RK2928_CLKGATE_CON(8), 10, GFLAGS), +	GATE(PCLK_GPIO2,
> "pclk_gpio2", "pclk_peri", 0, RK2928_CLKGATE_CON(8), 11, GFLAGS), +};
> +
> +static const char *const rk3036_critical_clocks[] __initconst = {
> +	"aclk_cpu",
> +	"aclk_peri",
> +	"hclk_peri",
> +};
> +
> +#ifdef CONFIG_PM_SLEEP
> +static void __iomem *rk3036_cru_base;
> +
> +/* Some CRU registers will be reset in maskrom when the system
> + * wakes up from fastboot.
> + * So save them before suspend, restore them after resume.
> + */
> +
> +static int rk3036_clk_suspend(void)
> +{
> +	/* TODO */
> +
> +	return 0;
> +}
> +
> +static void rk3036_clk_resume(void)
> +{
> +	/* TODO */
> +}
> +
> +static struct syscore_ops rk3036_clk_syscore_ops = {
> +	.suspend = rk3036_clk_suspend,
> +	.resume = rk3036_clk_resume,
> +};
> +
> +static void rk3036_clk_sleep_init(void __iomem *reg_base)
> +{
> +	rk3036_cru_base = reg_base;
> +	register_syscore_ops(&rk3036_clk_syscore_ops);
> +}
> +
> +#else /* CONFIG_PM_SLEEP */
> +static void rk3036_clk_sleep_init(void __iomem *reg_base) {}
> +#endif

please don't add empty "TODO" functions. If you want to work on suspend later, 
just leave this stuff out completely and add it when time comes.


> +
> +static void __init rk3036_clk_init(struct device_node *np)
> +{
> +	void __iomem *reg_base;
> +	struct clk *clk;
> +
> +	reg_base = of_iomap(np, 0);
> +	if (!reg_base) {
> +		pr_err("%s: could not map cru region\n", __func__);
> +		return;
> +	}
> +
> +	rockchip_clk_init(np, reg_base, CLK_NR_CLKS);
> +
> +	/* xin12m is created by an cru-internal divider */
> +	clk = clk_register_fixed_factor(NULL, "xin12m", "xin24m", 0, 1, 2);
> +	if (IS_ERR(clk))
> +		pr_warn("%s: could not register clock xin12m: %ld\n",
> +			__func__, PTR_ERR(clk));
> +
> +	clk = clk_register_fixed_factor(NULL, "usb480m", "xin24m", 0, 20, 1);
> +	if (IS_ERR(clk))
> +		pr_warn("%s: could not register clock usb480m: %ld\n",
> +			__func__, PTR_ERR(clk));
> +
> +	clk = clk_register_fixed_factor(NULL, "ddrphy", "ddrphy2x", 0, 1, 2);
> +	if (IS_ERR(clk))
> +		pr_warn("%s: could not register clock ddrphy: %ld\n",
> +			__func__, PTR_ERR(clk));
> +
> +	clk = clk_register_fixed_factor(NULL, "hclk_vcodec_pre",
> +					"aclk_vcodec", 0, 1, 4);
> +	if (IS_ERR(clk))
> +		pr_warn("%s: could not register clock hclk_vcodec_pre: %ld\n",
> +			__func__, PTR_ERR(clk));
> +
> +	clk = clk_register_fixed_factor(NULL, "sclk_macref_out",
> +					"hclk_peri_src", 0, 1, 2);
> +	if (IS_ERR(clk))
> +		pr_warn("%s: could not register clock sclk_macref_out: %ld\n",
> +			__func__, PTR_ERR(clk));
> +
> +	rockchip_clk_register_plls(rk3036_pll_clks,
> +				   ARRAY_SIZE(rk3036_pll_clks),
> +				   -1);
> +	rockchip_clk_register_branches(rk3036_clk_branches,
> +				  ARRAY_SIZE(rk3036_clk_branches));
> +	rockchip_clk_protect_critical(rk3036_critical_clocks,
> +				      ARRAY_SIZE(rk3036_critical_clocks));
> +
> +	rockchip_clk_register_armclk(ARMCLK, "armclk",
> +			mux_armclk_p, ARRAY_SIZE(mux_armclk_p),
> +			&rk3036_cpuclk_data, rk3036_cpuclk_rates,
> +			ARRAY_SIZE(rk3036_cpuclk_rates));
> +
> +	rockchip_register_softrst(np, 9, reg_base + RK2928_SOFTRST_CON(0),
> +				  ROCKCHIP_SOFTRST_HIWORD_MASK);
> +
> +	rockchip_register_restart_notifier(RK2928_GLB_SRST_FST);
> +	rk3036_clk_sleep_init(reg_base);
> +}
> +CLK_OF_DECLARE(rk3036_cru, "rockchip,rk3036-cru", rk3036_clk_init);
> diff --git a/drivers/clk/rockchip/clk.h b/drivers/clk/rockchip/clk.h
> index dc8ecb2..6603c07 100644
> --- a/drivers/clk/rockchip/clk.h
> +++ b/drivers/clk/rockchip/clk.h
> @@ -2,6 +2,9 @@
>   * Copyright (c) 2014 MundoReader S.L.
>   * Author: Heiko Stuebner <heiko at sntech.de>
>   *
> + * Copyright (c) 2015 Rockchip Electronics Co. Ltd.
> + * Author: Xing Zheng <zhengxing at rock-chips.com>
> + *
>   * based on
>   *
>   * samsung/clk.h
> @@ -40,6 +43,13 @@ struct clk;
>  #define RK2928_SOFTRST_CON(x)	((x) * 0x4 + 0x110)
>  #define RK2928_MISC_CON		0x134
> 
> +#define RK3036_SDMMC_CON0		0x144
> +#define RK3036_SDMMC_CON1		0x148
> +#define RK3036_SDIO_CON0		0x14c
> +#define RK3036_SDIO_CON1		0x150
> +#define RK3036_EMMC_CON0		0x154
> +#define RK3036_EMMC_CON1		0x158
> +
>  #define RK3288_PLL_CON(x)		RK2928_PLL_CON(x)
>  #define RK3288_MODE_CON			0x50
>  #define RK3288_CLKSEL_CON(x)		((x) * 0x4 + 0x60)
> @@ -75,6 +85,7 @@ struct clk;
> 
>  enum rockchip_pll_type {
>  	pll_rk3066,
> +	pll_rk3036,
>  };
> 
>  #define RK3066_PLL_RATE(_rate, _nr, _nf, _no)	\
> @@ -95,12 +106,31 @@ enum rockchip_pll_type {
>  	.nb = _nb,						\
>  }
> 
> +#define RK3036_PLL_RATE(_rate, _refdiv, _fbdiv, _postdiv1,	\
> +			_postdiv2, _dsmpd, _frac)		\
> +{								\
> +	.rate	= _rate##U,					\
> +	.fbdiv = _fbdiv,					\
> +	.postdiv1 = _postdiv1,					\
> +	.refdiv = _refdiv,					\
> +	.postdiv2 = _postdiv2,					\
> +	.dsmpd = _dsmpd,					\
> +	.frac = _frac,						\
> +}
> +
>  struct rockchip_pll_rate_table {
>  	unsigned long rate;
>  	unsigned int nr;
>  	unsigned int nf;
>  	unsigned int no;
>  	unsigned int nb;
> +	/* for RK3036 */
> +	unsigned int fbdiv;
> +	unsigned int postdiv1;
> +	unsigned int refdiv;
> +	unsigned int postdiv2;
> +	unsigned int dsmpd;
> +	unsigned int frac;
>  };
> 
>  /**
> diff --git a/include/dt-bindings/clock/rk3036-cru.h
> b/include/dt-bindings/clock/rk3036-cru.h new file mode 100644
> index 0000000..085e4c3
> --- /dev/null
> +++ b/include/dt-bindings/clock/rk3036-cru.h
> @@ -0,0 +1,247 @@
> +/*
> + * Copyright (c) 2014 MundoReader S.L.
> + * Author: Heiko Stuebner <heiko at sntech.de>
> + *
> + * Copyright (c) 2015 Rockchip Electronics Co. Ltd.
> + * Author: Xing Zheng <zhengxing at 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.
> + */
> +
> +/* core clocks */
> +#define PLL_APLL		1
> +#define PLL_DPLL		2
> +#define PLL_GPLL		3
> +#define ARMCLK			4
> +
> +/* sclk gates (special clocks) */
> +#define SCLK_GPU		64
> +#define SCLK_SPI		65
> +#define SCLK_SDMMC		68
> +#define SCLK_SDIO		69
> +#define SCLK_EMMC		71
> +#define SCLK_NANDC		76
> +#define SCLK_UART0		77
> +#define SCLK_UART1		78
> +#define SCLK_UART2		79
> +#define SCLK_I2S		82
> +#define SCLK_SPDIF		83
> +#define SCLK_TIMER0		85
> +#define SCLK_TIMER1		86
> +#define SCLK_TIMER2		87
> +#define SCLK_TIMER3		88
> +#define SCLK_OTGPHY0		93
> +#define SCLK_OTGPHY1		94
> +#define SCLK_LCDC		100
> +#define SCLK_HDMI		109
> +#define SCLK_HEVC		111
> +#define SCLK_I2S_OUT		113
> +#define SCLK_SDMMC_DRV		114
> +#define SCLK_SDIO_DRV		115
> +#define SCLK_EMMC_DRV		117
> +#define SCLK_SDMMC_SAMPLE	118
> +#define SCLK_SDIO_SAMPLE	119
> +#define SCLK_EMMC_SAMPLE	121
> +#define SCLK_PVTM_CORE          123
> +#define SCLK_PVTM_GPU           124
> +#define SCLK_PVTM_VIDEO         125
> +#define SCLK_MAC		151
> +#define SCLK_MACREF		152
> +#define SCLK_SFC		160
> +
> +#define DCLK_LCDC		190
> +
> +/* aclk gates */
> +#define ACLK_DMAC2		194
> +#define ACLK_LCDC		197
> +#define ACLK_VIO		203
> +#define ACLK_VCODEC		208
> +#define ACLK_CPU		209
> +#define ACLK_PERI		210
> +
> +/* pclk gates */
> +#define PCLK_GPIO0		320
> +#define PCLK_GPIO1		321
> +#define PCLK_GPIO2		322
> +#define PCLK_GRF		329
> +#define PCLK_I2C0		332
> +#define PCLK_I2C1		333
> +#define PCLK_I2C2		334
> +#define PCLK_SPI		338
> +#define PCLK_UART0		341
> +#define PCLK_UART1		342
> +#define PCLK_UART2		343
> +#define PCLK_PWM		350
> +#define PCLK_TIMER		353
> +#define PCLK_HDMI		360
> +#define PCLK_CPU		362
> +#define PCLK_PERI		363
> +#define PCLK_DDRUPCTL		364
> +#define PCLK_WDT		368
> +
> +/* hclk gates */
> +#define HCLK_OTG0		449
> +#define HCLK_OTG1		450
> +#define HCLK_NANDC		453
> +#define HCLK_SDMMC		456
> +#define HCLK_SDIO		457
> +#define HCLK_EMMC		459
> +#define HCLK_I2S		462
> +#define HCLK_LCDC		465
> +#define HCLK_ROM		467
> +#define HCLK_VIO_BUS		472
> +#define HCLK_VCODEC		476
> +#define HCLK_CPU		477
> +#define HCLK_PERI		478
> +
> +#define CLK_NR_CLKS		(HCLK_PERI + 1)
> +
> +/* soft-reset indices */
> +#define SRST_CORE0		0
> +#define SRST_CORE1		1
> +#define SRST_0RES2		2
> +#define SRST_0RES3		3
> +#define SRST_CORE0_DBG		4
> +#define SRST_CORE1_DBG		5
> +#define SRST_0RES6		6
> +#define SRST_0RES7		7
> +#define SRST_CORE0_POR		8
> +#define SRST_CORE1_POR		9
> +#define SRST_0RES10		10
> +#define SRST_0RES11		11
> +#define SRST_L2C		12
> +#define SRST_TOPDBG		13
> +#define SRST_STRC_SYS_A		14
> +#define SRST_PD_CORE_NIU	15
> +
> +#define SRST_TIMER2		16
> +#define SRST_CPUSYS_H		17
> +#define SRST_1RES2		18
> +#define SRST_AHB2APB_H		19
> +#define SRST_TIMER3		20
> +#define SRST_INTMEM		21
> +#define SRST_ROM		22
> +#define SRST_PERI_NIU		23
> +#define SRST_I2S		24
> +#define SRST_DDR_PLL		25
> +#define SRST_GPU_DLL		26
> +#define SRST_TIMER0		27
> +#define SRST_TIMER1		28
> +#define SRST_CORE_DLL		29
> +#define SRST_EFUSE_P		30
> +#define SRST_ACODEC_P		31
> +
> +#define SRST_GPIO0		32
> +#define SRST_GPIO1		33
> +#define SRST_GPIO2		34
> +#define SRST_2RES3		35
> +#define SRST_2RES4		36
> +#define SRST_2RES5		37
> +#define SRST_2RES6		38
> +#define SRST_UART0		39
> +#define SRST_UART1		40
> +#define SRST_UART2		41
> +#define SRST_2RES10		42
> +#define SRST_I2C0		43
> +#define SRST_I2C1		44
> +#define SRST_I2C2		45
> +#define SRST_2RES14		46
> +#define SRST_SFC		47
> +
> +#define SRST_PWM0		48
> +#define SRST_3RES1		49
> +#define SRST_3RES2		50
> +#define SRST_DAP		51
> +#define SRST_DAP_SYS		52
> +#define SRST_3RES5		53
> +#define SRST_3RES6		54
> +#define SRST_GRF		55
> +#define SRST_3RES8		56
> +#define SRST_PERIPHSYS_A	57
> +#define SRST_PERIPHSYS_H	58
> +#define SRST_PERIPHSYS_P	59
> +#define SRST_3RES12		60
> +#define SRST_CPU_PERI		61
> +#define SRST_EMEM_PERI		62
> +#define SRST_USB_PERI		63
> +
> +#define SRST_DMA2		64
> +#define SRST_4RES1		65
> +#define SRST_MAC		66
> +#define SRST_4RES3		67
> +#define SRST_NANDC		68
> +#define SRST_USBOTG0		69
> +#define SRST_4RES6		70
> +#define SRST_OTGC0		71
> +#define SRST_USBOTG1		72
> +#define SRST_4RES9		73
> +#define SRST_OTGC1		74
> +#define SRST_4RES11		75
> +#define SRST_4RES12		76
> +#define SRST_4RES13		77
> +#define SRST_4RES14		78
> +#define SRST_DDRMSCH		79
> +
> +#define SRST_5RES0		80
> +#define SRST_MMC0		81
> +#define SRST_SDIO		82
> +#define SRST_EMMC		83
> +#define SRST_SPI0		84
> +#define SRST_5RES5		85
> +#define SRST_WDT		86
> +#define SRST_5RES7		87
> +#define SRST_DDRPHY		88
> +#define SRST_DDRPHY_P		89
> +#define SRST_DDRCTRL		90
> +#define SRST_DDRCTRL_P		91
> +#define SRST_5RES12		92
> +#define SRST_5RES13		93
> +#define SRST_5RES14		94
> +#define SRST_5RES15		95
> +
> +#define SRST_HDMI_P		96
> +#define SRST_6RES1		97
> +#define SRST_6RES2		98
> +#define SRST_VIO_BUS_H		99
> +#define SRST_6RES4		100
> +#define SRST_6RES5		101
> +#define SRST_6RES6		102
> +#define SRST_UTMI0		103
> +#define SRST_UTMI1		104
> +#define SRST_USBPOR		105
> +#define SRST_6RES10		106
> +#define SRST_6RES11		107
> +#define SRST_6RES12		108
> +#define SRST_6RES13		109
> +#define SRST_6RES14		110
> +#define SRST_6RES15		111
> +
> +#define SRST_VCODEC_A		112
> +#define SRST_VCODEC_H		113
> +#define SRST_VIO1_A		114
> +#define SRST_HEVC		115
> +#define SRST_VCODEC_NIU_A	116
> +#define SRST_LCDC1_A		117
> +#define SRST_LCDC1_H		118
> +#define SRST_LCDC1_D		119
> +#define SRST_GPU		120
> +#define SRST_7RES9		121
> +#define SRST_GPU_NIU_A		122
> +#define SRST_7RES11		123
> +#define SRST_7RES12		124
> +#define SRST_7RES13		125
> +#define SRST_7RES14		126
> +#define SRST_7RES15		127

please don't add reserved (aka unused) reset slots. Of course the numbering 
stays the same, so just drop the xRESy lines from the definition.
Same for all xRESy entries in this file.


> +
> +#define SRST_8RES0		128
> +#define SRST_8RES1		129
> +#define SRST_8RES2		130
> +#define SRST_DBG_P		131



From wens at csie.org  Fri Aug 28 02:54:38 2015
From: wens at csie.org (Chen-Yu Tsai)
Date: Fri, 28 Aug 2015 17:54:38 +0800
Subject: [PATCH 5/6] ARM: dts: sun6i: Add support for Sinlinx A31s SDK board
In-Reply-To: <1440755679-8266-1-git-send-email-wens@csie.org>
References: <1440755679-8266-1-git-send-email-wens@csie.org>
Message-ID: <1440755679-8266-6-git-send-email-wens@csie.org>

The Sinlinx A31s SDK is a A31s based module/baseboard development kit.

The core module has the SoC, PMIC, DRAM, eMMC and supporting components.
There are also pads for UART0, JTAG and I2S.

The baseboard has 100 Mbps Ethernet, 5x USB 2.0 host ports via a USB 2.0
hub chip, MMC, HDMI, SPDIF, CIR, audio jacks, 2 tablet-like volume
buttons, RS232 style UART and USB OTG (though VBUS is not connected).
Various headers are available for other addon modules, such as SDIO
WiFi, LCD display, camera sensor, UARTs, I2C, SPI and GPIOs.

Signed-off-by: Chen-Yu Tsai <wens at csie.org>
---
 arch/arm/boot/dts/Makefile                     |   3 +-
 arch/arm/boot/dts/sun6i-a31s-sina31s-core.dtsi | 131 ++++++++++++++++++++++
 arch/arm/boot/dts/sun6i-a31s-sina31s.dts       | 149 +++++++++++++++++++++++++
 3 files changed, 282 insertions(+), 1 deletion(-)
 create mode 100644 arch/arm/boot/dts/sun6i-a31s-sina31s-core.dtsi
 create mode 100644 arch/arm/boot/dts/sun6i-a31s-sina31s.dts

diff --git a/arch/arm/boot/dts/Makefile b/arch/arm/boot/dts/Makefile
index f830e1f12716..ada5156fdd49 100644
--- a/arch/arm/boot/dts/Makefile
+++ b/arch/arm/boot/dts/Makefile
@@ -578,7 +578,8 @@ dtb-$(CONFIG_MACH_SUN6I) += \
 	sun6i-a31-i7.dtb \
 	sun6i-a31-m9.dtb \
 	sun6i-a31-mele-a1000g-quad.dtb \
-	sun6i-a31s-cs908.dtb
+	sun6i-a31s-cs908.dtb \
+	sun6i-a31s-sina31s.dtb
 dtb-$(CONFIG_MACH_SUN7I) += \
 	sun7i-a20-bananapi.dtb \
 	sun7i-a20-bananapro.dtb \
diff --git a/arch/arm/boot/dts/sun6i-a31s-sina31s-core.dtsi b/arch/arm/boot/dts/sun6i-a31s-sina31s-core.dtsi
new file mode 100644
index 000000000000..409b31ec647c
--- /dev/null
+++ b/arch/arm/boot/dts/sun6i-a31s-sina31s-core.dtsi
@@ -0,0 +1,131 @@
+/*
+ * Copyright 2015 Chen-Yu Tsai <wens at csie.org>
+ *
+ * This file is dual-licensed: you can use it either under the terms
+ * of the GPL or the X11 license, at your option. Note that this dual
+ * licensing only applies to this file, and not this project as a
+ * whole.
+ *
+ *  a) This file is free software; you can redistribute it and/or
+ *     modify it under the terms of the GNU General Public License as
+ *     published by the Free Software Foundation; either version 2 of the
+ *     License, or (at your option) any later version.
+ *
+ *     This file is distributed in the hope that it will be useful,
+ *     but WITHOUT ANY WARRANTY; without even the implied warranty of
+ *     MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ *     GNU General Public License for more details.
+ *
+ * Or, alternatively,
+ *
+ *  b) Permission is hereby granted, free of charge, to any person
+ *     obtaining a copy of this software and associated documentation
+ *     files (the "Software"), to deal in the Software without
+ *     restriction, including without limitation the rights to use,
+ *     copy, modify, merge, publish, distribute, sublicense, and/or
+ *     sell copies of the Software, and to permit persons to whom the
+ *     Software is furnished to do so, subject to the following
+ *     conditions:
+ *
+ *     The above copyright notice and this permission notice shall be
+ *     included in all copies or substantial portions of the Software.
+ *
+ *     THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
+ *     EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES
+ *     OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
+ *     NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT
+ *     HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY,
+ *     WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
+ *     FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR
+ *     OTHER DEALINGS IN THE SOFTWARE.
+ */
+
+/dts-v1/;
+#include "sun6i-a31s.dtsi"
+#include "sunxi-common-regulators.dtsi"
+
+#include <dt-bindings/gpio/gpio.h>
+#include <dt-bindings/pinctrl/sun4i-a10.h>
+
+/ {
+	model = "Sinlinx SinA31s Core Board";
+	compatible = "sinlinx,sina31s", "allwinner,sun6i-a31s";
+
+	aliases {
+		serial0 = &uart0;
+	};
+};
+
+/* eMMC on core board */
+&mmc2 {
+	pinctrl-names = "default";
+	pinctrl-0 = <&mmc2_8bit_emmc_pins>;
+	vmmc-supply = <&reg_vcc3v0>;
+	bus-width = <8>;
+	non-removable;
+	status = "okay";
+};
+
+/* AXP221s PMIC on core board */
+&p2wi {
+	status = "okay";
+
+	axp221: pmic at 68 {
+		reg = <0x68>;
+		interrupt-parent = <&nmi_intc>;
+		interrupts = <0 IRQ_TYPE_LEVEL_LOW>;
+	};
+};
+
+#include "axp221.dtsi"
+
+&reg_dcdc1 {
+	regulator-always-on;
+	regulator-min-microvolt = <3000000>;
+	regulator-max-microvolt = <3000000>;
+	regulator-name = "vcc-3v0";
+};
+
+&reg_dcdc2 {
+	regulator-always-on;
+	regulator-min-microvolt = <700000>;
+	regulator-max-microvolt = <1320000>;
+	regulator-name = "vdd-cpu";
+};
+
+&reg_dcdc3 {
+	regulator-always-on;
+	regulator-min-microvolt = <700000>;
+	regulator-max-microvolt = <1320000>;
+	regulator-name = "vdd-gpu";
+};
+
+&reg_dcdc4 {
+	regulator-always-on;
+	/* This board is not stable at recommended 1.1 V */
+	regulator-min-microvolt = <1200000>;
+	regulator-max-microvolt = <1200000>;
+	regulator-name = "vdd-sys";
+};
+
+&reg_dcdc5 {
+	regulator-always-on;
+	regulator-min-microvolt = <1500000>;
+	regulator-max-microvolt = <1500000>;
+	regulator-name = "vcc-dram";
+};
+
+&reg_aldo3 {
+	regulator-always-on;
+	regulator-min-microvolt = <3000000>;
+	regulator-max-microvolt = <3000000>;
+	regulator-name = "avcc";
+};
+
+/* UART0 pads available on core board */
+&uart0 {
+	pinctrl-names = "default";
+	pinctrl-0 = <&uart0_pins_a>;
+	status = "okay";
+};
+
diff --git a/arch/arm/boot/dts/sun6i-a31s-sina31s.dts b/arch/arm/boot/dts/sun6i-a31s-sina31s.dts
new file mode 100644
index 000000000000..47b517d7b8a1
--- /dev/null
+++ b/arch/arm/boot/dts/sun6i-a31s-sina31s.dts
@@ -0,0 +1,149 @@
+/*
+ * Copyright 2015 Chen-Yu Tsai <wens at csie.org>
+ *
+ * This file is dual-licensed: you can use it either under the terms
+ * of the GPL or the X11 license, at your option. Note that this dual
+ * licensing only applies to this file, and not this project as a
+ * whole.
+ *
+ *  a) This file is free software; you can redistribute it and/or
+ *     modify it under the terms of the GNU General Public License as
+ *     published by the Free Software Foundation; either version 2 of the
+ *     License, or (at your option) any later version.
+ *
+ *     This file is distributed in the hope that it will be useful,
+ *     but WITHOUT ANY WARRANTY; without even the implied warranty of
+ *     MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ *     GNU General Public License for more details.
+ *
+ * Or, alternatively,
+ *
+ *  b) Permission is hereby granted, free of charge, to any person
+ *     obtaining a copy of this software and associated documentation
+ *     files (the "Software"), to deal in the Software without
+ *     restriction, including without limitation the rights to use,
+ *     copy, modify, merge, publish, distribute, sublicense, and/or
+ *     sell copies of the Software, and to permit persons to whom the
+ *     Software is furnished to do so, subject to the following
+ *     conditions:
+ *
+ *     The above copyright notice and this permission notice shall be
+ *     included in all copies or substantial portions of the Software.
+ *
+ *     THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
+ *     EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES
+ *     OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
+ *     NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT
+ *     HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY,
+ *     WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
+ *     FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR
+ *     OTHER DEALINGS IN THE SOFTWARE.
+ */
+
+/* The SinA31s development board has the SinA31s core board soldered on */
+#include "sun6i-a31s-sina31s-core.dtsi"
+
+#include <dt-bindings/input/input.h>
+
+/ {
+	model = "Sinlinx SinA31s Development Board";
+	compatible = "sinlinx,sina31s-sdk", "allwinner,sun6i-a31s";
+
+	chosen {
+		stdout-path = "serial0:115200n8";
+	};
+};
+
+&ehci0 {
+	/* USB 2.0 4 port hub IC */
+	status = "okay";
+};
+
+&ehci1 {
+	status = "okay";
+};
+
+&gmac {
+	pinctrl-names = "default";
+	pinctrl-0 = <&gmac_pins_mii_a>;
+	phy = <&phy1>;
+	phy-mode = "mii";
+	phy-supply = <&reg_dldo1>;
+	status = "okay";
+
+	phy1: ethernet-phy at 1 {
+		reg = <1>;
+	};
+};
+
+&i2c0 {
+	/* Available on camera header */
+	pinctrl-names = "default";
+	pinctrl-0 = <&i2c0_pins_a>;
+	status = "okay";
+};
+
+&i2c1 {
+	/* Available on LCD header */
+	pinctrl-names = "default";
+	pinctrl-0 = <&i2c1_pins_a>;
+	status = "okay";
+};
+
+&ir {
+	pinctrl-names = "default";
+	pinctrl-0 = <&ir_pins_a>;
+	status = "okay";
+};
+
+&lradc {
+	vref-supply = <&reg_vcc3v0>;
+	status = "okay";
+
+	button at 158 {
+		label = "Volume Up";
+		linux,code = <KEY_VOLUMEUP>;
+		channel = <0>;
+		voltage = <158730>;
+	};
+
+	button at 349 {
+		label = "Volume Down";
+		linux,code = <KEY_VOLUMEDOWN>;
+		channel = <0>;
+		voltage = <349206>;
+	};
+};
+
+&mmc0 {
+	pinctrl-names = "default";
+	pinctrl-0 = <&mmc0_pins_a>, <&mmc0_cd_pin_sina31s>;
+	vmmc-supply = <&reg_vcc3v0>;
+	bus-width = <4>;
+	cd-gpios = <&pio 0 4 GPIO_ACTIVE_HIGH>; /* PA4 */
+	cd-inverted;
+	status = "okay";
+};
+
+&ohci1 {
+	status = "okay";
+};
+
+&pio {
+	mmc0_cd_pin_sina31s: mmc0_cd_pin at 0 {
+		allwinner,pins = "PA4";
+		allwinner,function = "gpio_in";
+		allwinner,drive = <SUN4I_PINCTRL_10_MA>;
+		allwinner,pull = <SUN4I_PINCTRL_PULL_UP>;
+	};
+};
+
+&reg_dldo1 {
+	regulator-min-microvolt = <3300000>;
+	regulator-max-microvolt = <3300000>;
+	regulator-name = "vcc_gmac_phy";
+};
+
+&usbphy {
+	status = "okay";
+};
-- 
2.5.0



From wens at csie.org  Fri Aug 28 02:54:39 2015
From: wens at csie.org (Chen-Yu Tsai)
Date: Fri, 28 Aug 2015 17:54:39 +0800
Subject: [PATCH 6/6] ARM: dts: sun6i: Add dts file for MSI Primo81 tablet
In-Reply-To: <1440755679-8266-1-git-send-email-wens@csie.org>
References: <1440755679-8266-1-git-send-email-wens@csie.org>
Message-ID: <1440755679-8266-7-git-send-email-wens@csie.org>

From: Karsten Merker <merker at debian.org>

The MSI Primo81 is an A31s based tablet, with 1G RAM, 16G NAND,
768x1024 IPS LCD display, mono speaker, 0.3 MP front camera, 2.0 MP
rear camera, 3500 mAh battery, gt911 touchscreen, mma8452 accelerometer
and rtl8188etv usb wifi. Has "power", "volume+" and "volume-" buttons
(both volume buttons are also connected to the UBOOT_SEL pin). The
external connectors are represented by MicroSD slot, MiniHDMI, MicroUSB
OTG and 3.5mm headphone jack. More details are available at

    http://linux-sunxi.org/MSI_Primo81

USB OTG is enabled in host only mode. AXP221 USB power supply and
GPIO support are required for full USB OTG support.

Signed-off-by: Siarhei Siamashka <siarhei.siamashka at gmail.com>
Signed-off-by: Karsten Merker <merker at debian.org>
Signed-off-by: Chen-Yu Tsai <wens at csie.org>
---

Changes since v4:

  - Use axp221.dtsi and add all active regulators.
  - Enable i2c controllers for capacitive touch panel and accelerometer.
  - Mark i2c controller for camera sensors as failed for now.
  - Enable USB OTG in host only mode.
  - Drop uart0 as this is not tested.
  - s/library/file/ in GPL header.

---
 arch/arm/boot/dts/Makefile               |   1 +
 arch/arm/boot/dts/sun6i-a31s-primo81.dts | 255 +++++++++++++++++++++++++++++++
 2 files changed, 256 insertions(+)
 create mode 100644 arch/arm/boot/dts/sun6i-a31s-primo81.dts

diff --git a/arch/arm/boot/dts/Makefile b/arch/arm/boot/dts/Makefile
index ada5156fdd49..c87513ed4eb4 100644
--- a/arch/arm/boot/dts/Makefile
+++ b/arch/arm/boot/dts/Makefile
@@ -579,6 +579,7 @@ dtb-$(CONFIG_MACH_SUN6I) += \
 	sun6i-a31-m9.dtb \
 	sun6i-a31-mele-a1000g-quad.dtb \
 	sun6i-a31s-cs908.dtb \
+	sun6i-a31s-primo81.dtb \
 	sun6i-a31s-sina31s.dtb
 dtb-$(CONFIG_MACH_SUN7I) += \
 	sun7i-a20-bananapi.dtb \
diff --git a/arch/arm/boot/dts/sun6i-a31s-primo81.dts b/arch/arm/boot/dts/sun6i-a31s-primo81.dts
new file mode 100644
index 000000000000..d22befaf363b
--- /dev/null
+++ b/arch/arm/boot/dts/sun6i-a31s-primo81.dts
@@ -0,0 +1,255 @@
+/*
+ * Copyright 2014 Siarhei Siamashka <siarhei.siamashka at gmail.com>
+ * Copyright 2015 Karsten Merker <merker at debian.org>
+ * Copyright 2015 Chen-Yu Tsai <wens at csie.org>
+ *
+ * This file is dual-licensed: you can use it either under the terms
+ * of the GPL or the X11 license, at your option. Note that this dual
+ * licensing only applies to this file, and not this project as a
+ * whole.
+ *
+ *  a) This file is free software; you can redistribute it and/or
+ *     modify it under the terms of the GNU General Public License as
+ *     published by the Free Software Foundation; either version 2 of the
+ *     License, or (at your option) any later version.
+ *
+ *     This file is distributed in the hope that it will be useful,
+ *     but WITHOUT ANY WARRANTY; without even the implied warranty of
+ *     MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ *     GNU General Public License for more details.
+ *
+ * Or, alternatively,
+ *
+ *  b) Permission is hereby granted, free of charge, to any person
+ *     obtaining a copy of this software and associated documentation
+ *     files (the "Software"), to deal in the Software without
+ *     restriction, including without limitation the rights to use,
+ *     copy, modify, merge, publish, distribute, sublicense, and/or
+ *     sell copies of the Software, and to permit persons to whom the
+ *     Software is furnished to do so, subject to the following
+ *     conditions:
+ *
+ *     The above copyright notice and this permission notice shall be
+ *     included in all copies or substantial portions of the Software.
+ *
+ *     THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
+ *     EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES
+ *     OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
+ *     NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT
+ *     HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY,
+ *     WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
+ *     FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR
+ *     OTHER DEALINGS IN THE SOFTWARE.
+ */
+
+/dts-v1/;
+#include "sun6i-a31s.dtsi"
+#include "sunxi-common-regulators.dtsi"
+
+#include <dt-bindings/gpio/gpio.h>
+#include <dt-bindings/input/input.h>
+#include <dt-bindings/pinctrl/sun4i-a10.h>
+
+/ {
+	model = "MSI Primo81 tablet";
+	compatible = "msi,primo81", "allwinner,sun6i-a31s";
+};
+
+&cpu0 {
+	cpu-supply = <&reg_dcdc2>;
+};
+
+&ehci0 {
+	/* rtl8188etv wifi is connected here */
+	status = "okay";
+};
+
+&i2c0 {
+	pinctrl-names = "default";
+	pinctrl-0 = <&i2c0_pins_a>;
+	/* pull-ups and device VDDIO require AXP221 DLDO3 */
+	status = "failed";
+};
+
+&i2c1 {
+	pinctrl-names = "default";
+	pinctrl-0 = <&i2c1_pins_a>;
+	status = "okay";
+
+	ctp at 5d {
+		pinctrl-names = "default";
+		pinctrl-0 = <&gt911_int_primo81>;
+		compatible = "goodix,gt911";
+		reg = <0x5d>;
+		interrupt-parent = <&pio>;
+		interrupts = <0 3 IRQ_TYPE_LEVEL_HIGH>; /* PA3 */
+		/*
+		 * The default 0,0 coordinate is at the corner closest to
+		 * the headphone jack. X goes along the long side, while
+		 * Y goes along the short side.
+		 */
+	};
+};
+
+&i2c2 {
+	pinctrl-names = "default";
+	pinctrl-0 = <&i2c2_pins_a>;
+	status = "okay";
+
+	accelerometer at 1c {
+		pinctrl-names = "default";
+		pinctrl-0 = <&mma8452_int_primo81>;
+		compatible = "fsl,mma8452";
+		reg = <0x1c>;
+		interrupt-parent = <&pio>;
+		interrupts = <0 9 IRQ_TYPE_LEVEL_HIGH>; /* PA9 */
+		#io-channel-cells = <1>;
+	};
+};
+
+&lradc {
+	vref-supply = <&reg_aldo3>;
+	status = "okay";
+
+	button at 158 {
+		label = "Volume Up";
+		linux,code = <KEY_VOLUMEUP>;
+		channel = <0>;
+		voltage = <158730>;
+	};
+
+	button at 349 {
+		label = "Volume Down";
+		linux,code = <KEY_VOLUMEDOWN>;
+		channel = <0>;
+		voltage = <349206>;
+	};
+};
+
+&mmc0 {
+	pinctrl-names = "default";
+	pinctrl-0 = <&mmc0_pins_a>, <&mmc0_cd_pin_primo81>;
+	vmmc-supply = <&reg_dcdc1>;
+	bus-width = <4>;
+	cd-gpios = <&pio 0 8 GPIO_ACTIVE_HIGH>; /* PA8 */
+	cd-inverted;
+	status = "okay";
+};
+
+&pio {
+	gt911_int_primo81: gt911_int_pin at 0 {
+		allwinner,pins = "PA3";
+		allwinner,function = "gpio_in";
+		allwinner,drive = <SUN4I_PINCTRL_10_MA>;
+		allwinner,pull = <SUN4I_PINCTRL_NO_PULL>;
+	};
+
+	mma8452_int_primo81: mma8452_int_pin at 0 {
+		allwinner,pins = "PA9";
+		allwinner,function = "gpio_in";
+		allwinner,drive = <SUN4I_PINCTRL_10_MA>;
+		allwinner,pull = <SUN4I_PINCTRL_PULL_UP>;
+	};
+
+	mmc0_cd_pin_primo81: mmc0_cd_pin at 0 {
+		allwinner,pins = "PA8";
+		allwinner,function = "gpio_in";
+		allwinner,drive = <SUN4I_PINCTRL_10_MA>;
+		allwinner,pull = <SUN4I_PINCTRL_PULL_UP>;
+	};
+};
+
+&p2wi {
+	status = "okay";
+
+	axp221: pmic at 68 {
+		compatible = "x-powers,axp221";
+		reg = <0x68>;
+		interrupt-parent = <&nmi_intc>;
+		interrupts = <0 IRQ_TYPE_LEVEL_LOW>;
+	};
+};
+
+#include "axp221.dtsi"
+
+&reg_dcdc1 {
+	regulator-always-on;
+	regulator-min-microvolt = <3000000>;
+	regulator-max-microvolt = <3000000>;
+	regulator-name = "vcc-3v0";
+};
+
+&reg_dcdc2 {
+	regulator-always-on;
+	regulator-min-microvolt = <700000>;
+	regulator-max-microvolt = <1320000>;
+	regulator-name = "vdd-cpu";
+};
+
+&reg_dcdc3 {
+	regulator-always-on;
+	regulator-min-microvolt = <700000>;
+	regulator-max-microvolt = <1320000>;
+	regulator-name = "vdd-gpu";
+};
+
+&reg_dcdc4 {
+	regulator-always-on;
+	regulator-min-microvolt = <1240000>;
+	regulator-max-microvolt = <1240000>;
+	regulator-name = "vdd-sys-dll";
+};
+
+&reg_dcdc5 {
+	regulator-always-on;
+	regulator-min-microvolt = <1500000>;
+	regulator-max-microvolt = <1500000>;
+	regulator-name = "vcc-dram";
+};
+
+&reg_aldo3 {
+	regulator-always-on;
+	regulator-min-microvolt = <3000000>;
+	regulator-max-microvolt = <3000000>;
+	regulator-name = "avcc";
+};
+
+&reg_dldo1 {
+	regulator-min-microvolt = <3300000>;
+	regulator-max-microvolt = <3300000>;
+	regulator-name = "vcc-wifi";
+};
+
+&reg_eldo3 {
+	regulator-always-on;
+	regulator-min-microvolt = <1200000>;
+	regulator-max-microvolt = <1200000>;
+	regulator-name = "vcc-mipi-bridge";
+	/* This is used by simplefb LCD display. Add regulator support? */
+};
+
+&reg_dc1sw {
+	regulator-always-on;
+	regulator-min-microvolt = <3000000>;
+	regulator-max-microvolt = <3000000>;
+	regulator-name = "vcc-lcd";
+	/* This is used by simplefb LCD display. Add regulator support? */
+};
+
+&reg_dc5ldo {
+	regulator-always-on;
+	regulator-min-microvolt = <1100000>;
+	regulator-max-microvolt = <1100000>;
+	regulator-name = "vcc-cpus"; /* This is an educated guess */
+};
+
+&usb_otg {
+	/* otg support requires support for AXP221 usb-power-supply and GPIO */
+	dr_mode = "host";
+	status = "okay";
+};
+
+&usbphy {
+	status = "okay";
+	usb1_vbus-supply = <&reg_dldo1>;
+};
-- 
2.5.0



From heiko at sntech.de  Fri Aug 28 02:59:59 2015
From: heiko at sntech.de (Heiko Stuebner)
Date: Fri, 28 Aug 2015 11:59:59 +0200
Subject: [PATCH v1 0/3] Port and support rk3036 SoC platform
In-Reply-To: <1440740808-15004-1-git-send-email-zhengxing@rock-chips.com>
References: <1440740808-15004-1-git-send-email-zhengxing@rock-chips.com>
Message-ID: <6551991.RUDkGfdSCp@phil>

Hi,

Am Freitag, 28. August 2015, 13:46:45 schrieb Xing Zheng:
> We need to support rk3036 soc platform via upstream, there are
> 3 parts for the initial release of minimum system: dts, pinctrl,
> and clock tree for rk3036, startup and run to init processs.

this is really cool that you're working on supporting the rk3036.
I had some comments to the individual patches, but overall it looks quite nice 
already.


So, thanks for working on this
Heiko



From robert.jarzmik at free.fr  Fri Aug 28 02:58:30 2015
From: robert.jarzmik at free.fr (Robert Jarzmik)
Date: Fri, 28 Aug 2015 11:58:30 +0200
Subject: [PATCH v2 12/21] ARM: pxa: magician: Add PXA27x UDC support
In-Reply-To: <55D652D0.90903@tul.cz> (Petr Cvek's message of "Fri, 21 Aug 2015
 00:21:04 +0200")
References: <cover.1439843482.git.petr.cvek@tul.cz> <55D25A06.9030507@tul.cz>
 <87twrt6fh5.fsf@belgarion.home> <55D652D0.90903@tul.cz>
Message-ID: <871ten3fax.fsf@belgarion.home>

Petr Cvek <petr.cvek at tul.cz> writes:

> Dne 20.8.2015 v 19:23 Robert Jarzmik napsal(a):
>> Petr Cvek <petr.cvek at tul.cz> writes:
>>> +static void magician_udc_command(int cmd)
>>> +{
>>> +	if (cmd == PXA2XX_UDC_CMD_CONNECT)
>>> +		UP2OCR |= UP2OCR_DPPUE | UP2OCR_DPPUBE;
>>> +	else if (cmd == PXA2XX_UDC_CMD_DISCONNECT)
>>> +		UP2OCR &= ~(UP2OCR_DPPUE | UP2OCR_DPPUBE);
>>> +}
>>> +
>>> +/* HACK, shared USB connected state with pda-power */
>>> +int my_usb_online = 1;
>> Definitely not, a global (ie. non static variable) is not something I'll let
>> in. Besides, can't a "gpio_get_value()" give the same level of information ?
>
> I will gladly remove it, but I want my phone to be able to charge and work as
> USB device (and maybe as USB host).
Okay, I understand that, but see below.

>> 
>>> +static int magician_udc_is_connected(void)
>>> +{
>>> +	/* Shared with pda_power or gpio-vbus */
>>> +	return my_usb_online;
>> gpio_get_value() something ?
>> 
>
> I need to use EGPIO_MAGICIAN_CABLE_INSERT1 GPIO in pda_power to be able to detect source for charging.
>
>>> +}
>>> +
>>> +static struct pxa2xx_udc_mach_info magician_udc_info __initdata = {
>>> +	.udc_command		= magician_udc_command,
>>> +	.udc_is_connected	= magician_udc_is_connected,
>> I don't think udc_is_connected is a field used by pxa27x_udc.c, it it ? The VBus
>> connection information comes from a transciever, usually from gpio_vbus driver
>> nowadays.
>
> Really? Well I guess I took a bad route :-D (when I tried to learn how to add an
> udc support). As there are two ways to define udc_is_connected, would it be
> possible to remove this field altogether (only mioa701 and lubbock have relevant
> use, but if this function is never called, then it is dead code)?
>
> Do you know which code / source is responsible for gpio_vbus -> pxa27x_udc
> communication about inserted cable? I will need to put some assert for
> testing.
Yes.
 - hooking: udc->transceiver = usb_get_phy(USB_PHY_TYPE_USB2);
 - detection: gpio_vbus_work()
   -> usb_gadget_vbus_connect()
     -> pxa_udc_vbus_session()

>>> @@ -1175,6 +1207,11 @@ static struct platform_device *devices[] __initdata = {
>>>  
>>>  	/* NOTICE mutually exclusive with PXA I2C */
>>>  	&i2c_gpio_bus_alt,
>>> +
>>> +	/* NOTICE mutually exclusive with UDC*/
>> Euh why so ?
>> In arch/arm/mach-pxa/mioa701.c they cooperate, why can't they for magician ?
>
> In mioa701 the GPIO13_nUSB_DETECT GPIO is requested by gpio_vbus driver, used in
> pda_power (without request) and "used" in PXA UDC driver without request. It is
> basically similar solution as my (ugly) global variable.
>
> Solution: I will try to use that second new GPIO (EGPIO_MAGICIAN_CABLE_INSERT2)
> for that, so there is no GPIO request dependency. I may create new names for
> them (magician.h).
Cool.
And if by chance you find an even cleaner solution, don't hesitate to modify
mioa701, hein ? ;)

Cheers.

-- 
Robert


From zhengxing at rock-chips.com  Fri Aug 28 03:07:24 2015
From: zhengxing at rock-chips.com (Xing Zheng)
Date: Fri, 28 Aug 2015 18:07:24 +0800
Subject: [PATCH v1 0/3] Port and support rk3036 SoC platform
In-Reply-To: <6551991.RUDkGfdSCp@phil>
References: <1440740808-15004-1-git-send-email-zhengxing@rock-chips.com>
 <6551991.RUDkGfdSCp@phil>
Message-ID: <55E032DC.1090703@rock-chips.com>

HI Heiko,
Thank you for your reply. I will improve them as quickly as possible.

Thanks. :)

On 2015?08?28? 17:59, Heiko Stuebner wrote:
> Hi,
>
> Am Freitag, 28. August 2015, 13:46:45 schrieb Xing Zheng:
>> We need to support rk3036 soc platform via upstream, there are
>> 3 parts for the initial release of minimum system: dts, pinctrl,
>> and clock tree for rk3036, startup and run to init processs.
> this is really cool that you're working on supporting the rk3036.
> I had some comments to the individual patches, but overall it looks quite nice
> already.
>
>
> So, thanks for working on this
> Heiko
>
>
>
>




From frans.klaver at xsens.com  Fri Aug 28 03:10:32 2015
From: frans.klaver at xsens.com (Frans Klaver)
Date: Fri, 28 Aug 2015 12:10:32 +0200
Subject: [PATCH] arm: omap2: vc: fix 'or' always true warning
In-Reply-To: <DUB128-W519E183FDD98EF80BD4CB79C6E0@phx.gbl>
References: <DUB128-W519E183FDD98EF80BD4CB79C6E0@phx.gbl>
Message-ID: <1440756632-14043-1-git-send-email-frans.klaver@xsens.com>

From: Frans Klaver <fransklaver at gmail.com>

Fix the warning:
arch/arm/mach-omap2/vc.c:302:47: warning: logical ?or? of collectively exhaustive tests is always true [-Wlogical-op]

As we're toggling both CLKREQ and OFFMODE, we should also be checking
OFFMODE.

Signed-off-by: Frans Klaver <fransklaver at gmail.com>
---
 arch/arm/mach-omap2/vc.c | 2 +-
 1 file changed, 1 insertion(+), 1 deletion(-)

diff --git a/arch/arm/mach-omap2/vc.c b/arch/arm/mach-omap2/vc.c
index 076fd20d7e5a..807bc79e3e3d 100644
--- a/arch/arm/mach-omap2/vc.c
+++ b/arch/arm/mach-omap2/vc.c
@@ -300,7 +300,7 @@ static void __init omap3_vc_init_pmic_signaling(struct voltagedomain *voltdm)
 
 	val = voltdm->read(OMAP3_PRM_POLCTRL_OFFSET);
 	if (!(val & OMAP3430_PRM_POLCTRL_CLKREQ_POL) ||
-	    (val & OMAP3430_PRM_POLCTRL_CLKREQ_POL)) {
+	    (val & OMAP3430_PRM_POLCTRL_OFFMODE_POL)) {
 		val |= OMAP3430_PRM_POLCTRL_CLKREQ_POL;
 		val &= ~OMAP3430_PRM_POLCTRL_OFFMODE_POL;
 		pr_debug("PM: fixing sys_clkreq and sys_off_mode polarity to 0x%x\n",
-- 
2.3.4



From lorenzo.pieralisi at arm.com  Fri Aug 28 03:23:14 2015
From: lorenzo.pieralisi at arm.com (Lorenzo Pieralisi)
Date: Fri, 28 Aug 2015 11:23:14 +0100
Subject: [PATCH] ARM64: kernel: implement ACPI parking protocol
In-Reply-To: <1437068449.3583.4.camel@redhat.com>
References: <1436959990-32054-1-git-send-email-lorenzo.pieralisi@arm.com>
 <1437063431.3583.2.camel@redhat.com>
 <20150716171221.GB18582@red-moon>
 <1437068449.3583.4.camel@redhat.com>
Message-ID: <20150828102314.GC15924@red-moon>

Mark,

On Thu, Jul 16, 2015 at 06:40:49PM +0100, Mark Salter wrote:

[...]

> On Thu, 2015-07-16 at 18:12 +0100, Lorenzo Pieralisi wrote:
> > > The kernel will only add cached memory regions to linear mapping and
> > > presumably, the FW will mark the mailboxes as uncached. Otherwise, it
> > > is a FW bug. But I suppose we could run into problems with kernels
> > > using 64K pagesize since firmware assumes 4k.
> >
> > Nope, ioremap takes care of that, everything should be fine.
> 
> The mailbox is 4K. If it is next to a cached UEFI region, the kernel may
> have to overlap the mailbox with a cached 64K mapping in order to include
> the adjoining UEFI region in the linear map. Then the ioremap would fail
> because the mailbox is included in the linear mapping.

So that I understand: are you referring to memrange_efi_to_native()
in arch/arm64/kernel/efi.c ? Is it safe to round up (and add it to
the memblock layer) the memory region size to PAGE_SIZE without checking
attributes of overlapping (within PAGE_SIZE) UEFI regions ?

Thanks,
Lorenzo


From yamada.masahiro at socionext.com  Fri Aug 28 03:24:47 2015
From: yamada.masahiro at socionext.com (Masahiro Yamada)
Date: Fri, 28 Aug 2015 19:24:47 +0900
Subject: [PATCH 1/3] ARM: uniphier: add outer cache support
In-Reply-To: <CACRpkdbJppuA6ZyciNAGfSgrf4M2THVHggzuZYSqORjy2JBp_A@mail.gmail.com>
References: <1440382692-3855-1-git-send-email-yamada.masahiro@socionext.com>
 <1440382692-3855-2-git-send-email-yamada.masahiro@socionext.com>
 <CACRpkdbJppuA6ZyciNAGfSgrf4M2THVHggzuZYSqORjy2JBp_A@mail.gmail.com>
Message-ID: <CAK7LNATWsa8AhyFGzsR0HAODmQD8yBPidTE0Lx2ACh4_PeQW9w@mail.gmail.com>

Hi Linus,


2015-08-26 22:39 GMT+09:00 Linus Walleij <linus.walleij at linaro.org>:
> On Mon, Aug 24, 2015 at 4:18 AM, Masahiro Yamada
> <yamada.masahiro at socionext.com> wrote:
>> This commit adds support for UniPhier outer cache controller.
>> All the UniPhier SoCs are equipped with the L2 cache, while the L3
>> cache is currently only integrated on PH1-Pro5 SoC.
>>
>> Signed-off-by: Masahiro Yamada <yamada.masahiro at socionext.com>
>
> Wow it is really a custom L2$ controller. Wow. Just wow. That's
> really brave, given all the problems we've seen in l2x0.

Looks like my company is crazy...
ARM Ltd. people said we are the only vendor that still uses
a custom outer cache.



>> +UniPhier SoCs are integrated with a level 2 cache controller that resides
>> +outside of the ARM cores, some of them also have a level 3 cache controller.
>> +
>> +Required properties:
>> +- compatible: should be one of the followings:
>> +       "socionext,uniphier-l2-cache"   (L2 cache)
>> +       "socionext,uniphier-l3-cache"   (L3 cache)
>
> Refer to and use the 3.7.3 ePAPR v1.1 specification too:
> https://www.power.org/wp-content/uploads/2012/06/Power_ePAPR_APPROVED_v1.1.pdf


I've checked it out.
Thanks, but I had some doubts.



> cache-unified and cache-level are *not* optional and should be required.


"cache-unified" is mentioned in "3.7.3 Internal (L1) Cache Properties"
(Table 3-8),
but it is not in "3.8 Multi-level and Shared Caches" (Table 3-9)

Are the rules in Table 3-8 also applied for L2?


> So:
>
>> +The L2 cache must exist to use the L3 cache; adding only an L3 cache device
>> +node to the device tree causes the initialization failure of the whole outer
>> +cache system.
>> +
>> +Example:
>> +       l2-cache at 500c0000 {
>> +               compatible = "socionext,uniphier-l2-cache";
>> +               reg = <0x500c0000 0x2000>, <0x503c0100 0x8>,
>> +                     <0x506c0000 0x400>;
>
> cache-unified;
> cache-level = <2>;
>
>> +       /* Not all of UniPhier SoCs have L3 cache */
>> +       l3-cache at 500c8000 {
>> +               compatible = "socionext,uniphier-l3-cache";
>> +               reg = <0x500c8000 0x2000>, <0x503c8100 0x8>,
>> +                     <0x506c8000 0x400>;
>
> cache-unified;
> cache-level = <3>;
>
> (I'm just assuming this cache is unified, anything else would be baffling.)

In fact, unified/harvard is configurable thru a register of this cache
controller.
It is usually used as a unified cached, though.



> Further the ePAPR spec optionally supports specifying things like the
> cache size, number of sets, block size and line size, unless this can
> be hard coded.
>
> Yours,
> Linus Walleij
>


Given that cache-level specifies the level and next-level-cache
specifies the topology,
I think "socionext,uniphier-l*-cache" gives redundant information.

The L2 and L3 cache controller look the same; they have the same register maps.

The differences between them are register-base, cache-size,
cache-sets, line-size,
which are specified by properties.

So,I am planning to use the same compatible for L2 and L3, like this:


       l2-cache at 500c0000 {
               compatible = "socionext,uniphier-cache";
               reg = <0x500c0000 0x2000>, <0x503c0100 0x8>,
                     <0x506c0000 0x400>;
               cache-unified;
               cache-level = <2>;
               next-level-cache = <&L2>;
               cache-size = <0x200000>;
               cache-sets = <256>;
               cache-line-size = <128>;
            };

       /* Not all of UniPhier SoCs have L3 cache */
       l3-cache at 500c8000 {
               compatible = "socionext,uniphier-cache";
               reg = <0x500c8000 0x2000>, <0x503c8100 0x8>,
                     <0x506c8000 0x400>;
               cache-unified;
               cache-level = <3>;
               cache-size = <0x400000>;
               cache-sets = <256>;
               cache-line-size = <256>;
       };



The Table 3-9 in ePAPR v1.1 says
the compatible should be "cache", but I do not think it makes sense here.




-- 
Best Regards
Masahiro Yamada


From lee.jones at linaro.org  Fri Aug 28 03:31:51 2015
From: lee.jones at linaro.org (Lee Jones)
Date: Fri, 28 Aug 2015 11:31:51 +0100
Subject: [PATCH v2 4/4] remoteproc: debugfs: Add ability to boot remote
 processor using debugfs
In-Reply-To: <1440757911-9120-1-git-send-email-lee.jones@linaro.org>
References: <1440757911-9120-1-git-send-email-lee.jones@linaro.org>
Message-ID: <1440757911-9120-5-git-send-email-lee.jones@linaro.org>

This functionality is especially useful during the testing phase.  When
used in conjunction with Mailbox's Test Framework we can trivially conduct
end-to-end testing i.e. boot co-processor, send and receive messages to
the co-processor, then shut it down again (repeat as required).

Signed-off-by: Ludovic Barre <ludovic.barre at st.com>
Signed-off-by: Lee Jones <lee.jones at linaro.org>
---
 drivers/remoteproc/remoteproc_debugfs.c | 29 +++++++++++++++++++++++++++++
 1 file changed, 29 insertions(+)

diff --git a/drivers/remoteproc/remoteproc_debugfs.c b/drivers/remoteproc/remoteproc_debugfs.c
index 9d30809..464470d 100644
--- a/drivers/remoteproc/remoteproc_debugfs.c
+++ b/drivers/remoteproc/remoteproc_debugfs.c
@@ -88,8 +88,37 @@ static ssize_t rproc_state_read(struct file *filp, char __user *userbuf,
 	return simple_read_from_buffer(userbuf, count, ppos, buf, i);
 }
 
+static ssize_t rproc_state_write(struct file *filp, const char __user *userbuf,
+				 size_t count, loff_t *ppos)
+{
+	struct rproc *rproc = filp->private_data;
+	char buf[2];
+	int ret;
+
+	ret = copy_from_user(buf, userbuf, 1);
+	if (ret)
+		return -EFAULT;
+
+	switch (buf[0]) {
+	case '0':
+		rproc_shutdown(rproc);
+		break;
+	case '1':
+		ret = rproc_boot(rproc);
+		if (ret)
+			dev_warn(&rproc->dev, "Boot failed: %d\n", ret);
+		break;
+	default:
+		dev_err(&rproc->dev, "Unrecognised option: %x\n", buf[1]);
+		return -EINVAL;
+	}
+
+	return count;
+}
+
 static const struct file_operations rproc_state_ops = {
 	.read = rproc_state_read,
+	.write = rproc_state_write,
 	.open = simple_open,
 	.llseek	= generic_file_llseek,
 };
-- 
1.9.1



From lee.jones at linaro.org  Fri Aug 28 03:31:48 2015
From: lee.jones at linaro.org (Lee Jones)
Date: Fri, 28 Aug 2015 11:31:48 +0100
Subject: [PATCH v2 1/4] ARM: STiH407: Add nodes for RemoteProc
In-Reply-To: <1440757911-9120-1-git-send-email-lee.jones@linaro.org>
References: <1440757911-9120-1-git-send-email-lee.jones@linaro.org>
Message-ID: <1440757911-9120-2-git-send-email-lee.jones@linaro.org>

Signed-off-by: Ludovic Barre <ludovic.barre at st.com>
Signed-off-by: Lee Jones <lee.jones at linaro.org>
---
 arch/arm/boot/dts/stih407-family.dtsi | 48 +++++++++++++++++++++++++++++++++++
 1 file changed, 48 insertions(+)

diff --git a/arch/arm/boot/dts/stih407-family.dtsi b/arch/arm/boot/dts/stih407-family.dtsi
index 33daa49..89a363c 100644
--- a/arch/arm/boot/dts/stih407-family.dtsi
+++ b/arch/arm/boot/dts/stih407-family.dtsi
@@ -608,5 +608,53 @@
 			status		= "okay";
 			tx-only;
 		};
+
+		st231_gp0: st231-gp0 at 0 {
+			compatible = "st,st231-rproc";
+			reg = <0x40000000 0x01000000>;
+			reg-names = "carveout";
+			resets = <&softreset STIH407_ST231_GP0_SOFTRESET>;
+			reset-names = "sw_reset";
+			clocks = <&clk_s_c0_flexgen CLK_ST231_GP_0>;
+			clock-names = "rproc_clk";
+			clock-frequency = <600000000>;
+			st,syscfg-boot = <&syscfg_core 0x22C>;
+		};
+
+		st231_gp1: st231-gp1 at 0 {
+			compatible = "st,st231-rproc";
+			reg = <0x41000000 0x01000000>;
+			reg-names = "carveout";
+			resets = <&softreset STIH407_ST231_GP1_SOFTRESET>;
+			reset-names = "sw_reset";
+			clocks = <&clk_s_c0_flexgen CLK_ST231_GP_1>;
+			clock-names = "rproc_clk";
+			clock-frequency = <600000000>;
+			st,syscfg-boot = <&syscfg_core 0x220>;
+		};
+
+		st231_audio: st231-audio at 0 {
+			compatible = "st,st231-rproc";
+			reg = <0x42000000 0x01000000>;
+			reg-names = "carveout";
+			resets = <&softreset STIH407_ST231_AUD_SOFTRESET>;
+			reset-names = "sw_reset";
+			clocks = <&clk_s_c0_flexgen CLK_ST231_AUD_0>;
+			clock-names = "rproc_clk";
+			clock-frequency = <600000000>;
+			st,syscfg-boot = <&syscfg_core 0x228>;
+		};
+
+		st231_dmu: st231-dmu at 0 {
+			compatible = "st,st231-rproc";
+			reg = <0x43000000 0x01000000>;
+			reg-names = "carveout";
+			resets = <&softreset STIH407_ST231_DMU_SOFTRESET>;
+			reset-names = "sw_reset";
+			clocks = <&clk_s_c0_flexgen CLK_ST231_DMU>;
+			clock-names = "rproc_clk";
+			clock-frequency = <600000000>;
+			st,syscfg-boot = <&syscfg_core 0x224>;
+		};
 	};
 };
-- 
1.9.1



From lee.jones at linaro.org  Fri Aug 28 03:31:47 2015
From: lee.jones at linaro.org (Lee Jones)
Date: Fri, 28 Aug 2015 11:31:47 +0100
Subject: [PATCH v2 0/4] remoteproc: Add driver for STMicroelectronics platforms
Message-ID: <1440757911-9120-1-git-send-email-lee.jones@linaro.org>

ST's platforms often have multiple co-processors (usually ST40s or ST231s)
on-board.  This provides the Linux-side infrastructure to flash and boot
them successfully.
 
This set has been tested on an STiH410-B2120.

v1 = v2:
 - Remove Linux implementation specific comment from binding document
 - Force debugfs '0' to shutdown co-processor - rather than !1
 - Supply more detailed commit message
 - Propagate errors back from .stop()
 - Review GPL wording
 - Supply original author's SoBs

Lee Jones (4):
  ARM: STiH407: Add nodes for RemoteProc
  remoteproc: dt: Provide bindings for ST's Remote Processor Controller
    driver
  remoteproc: Supply controller driver for ST's Remote Processors
  remoteproc: debugfs: Add ability to boot remote processor using
    debugfs

 .../devicetree/bindings/remoteproc/st-rproc.txt    |  35 +++
 arch/arm/boot/dts/stih407-family.dtsi              |  48 ++++
 drivers/remoteproc/Kconfig                         |   9 +
 drivers/remoteproc/Makefile                        |   1 +
 drivers/remoteproc/remoteproc_debugfs.c            |  29 ++
 drivers/remoteproc/st_remoteproc.c                 | 301 +++++++++++++++++++++
 6 files changed, 423 insertions(+)
 create mode 100644 Documentation/devicetree/bindings/remoteproc/st-rproc.txt
 create mode 100644 drivers/remoteproc/st_remoteproc.c

-- 
1.9.1



From lee.jones at linaro.org  Fri Aug 28 03:31:49 2015
From: lee.jones at linaro.org (Lee Jones)
Date: Fri, 28 Aug 2015 11:31:49 +0100
Subject: [PATCH v2 2/4] remoteproc: dt: Provide bindings for ST's Remote
 Processor Controller driver
In-Reply-To: <1440757911-9120-1-git-send-email-lee.jones@linaro.org>
References: <1440757911-9120-1-git-send-email-lee.jones@linaro.org>
Message-ID: <1440757911-9120-3-git-send-email-lee.jones@linaro.org>

Signed-off-by: Ludovic Barre <ludovic.barre at st.com>
Signed-off-by: Lee Jones <lee.jones at linaro.org>
---
 .../devicetree/bindings/remoteproc/st-rproc.txt    | 35 ++++++++++++++++++++++
 1 file changed, 35 insertions(+)
 create mode 100644 Documentation/devicetree/bindings/remoteproc/st-rproc.txt

diff --git a/Documentation/devicetree/bindings/remoteproc/st-rproc.txt b/Documentation/devicetree/bindings/remoteproc/st-rproc.txt
new file mode 100644
index 0000000..fbd7d78
--- /dev/null
+++ b/Documentation/devicetree/bindings/remoteproc/st-rproc.txt
@@ -0,0 +1,35 @@
+STMicroelectronics Remote Processor
+-----------------------------------
+
+This binding provides support for adjunct processors found on ST SoCs.
+
+The remote processors can be controlled from the bootloader or the primary OS.
+If the bootloader starts a remote processor processor the primary OS must detect
+its state and act accordingly.
+
+Required properties:
+- compatible		Should be one of:
+				"st,st231-rproc"
+				"st,st40-rproc"
+- reg			Size and length of reserved co-processor memory
+- resets		Reset lines (See: ../reset/reset.txt)
+- reset-names		Must be "sw_reset" and "pwr_reset"
+- clocks		Clock for co-processor (See: ../clock/clock-bindings.txt)
+- clock-names		Must be "rproc_clk"
+- clock-frequency	Clock frequency to set co-processor at if the bootloader
+			hasn't already done so
+- st,syscfg-boot	The register that holds the boot vector for the co-processor
+
+Example:
+
+	st231-audio at bae00000 {
+		compatible	= "st,st231-rproc";
+		reg		= <0xbae00000 0x01000000>;
+		reg-names	= "rproc_mem";
+		resets		= <&softreset STIH407_ST231_AUD_SOFTRESET>;
+		reset-names	= "sw_reset";
+		clocks		= <&clk_s_c0_flexgen CLK_ST231_AUD_0>;
+		clock-names	= "rproc_clk";
+		clock-frequency	= <600000000>;
+		st,syscfg-boot	= <&syscfg_core 0x228>;
+	};
-- 
1.9.1



From lee.jones at linaro.org  Fri Aug 28 03:31:50 2015
From: lee.jones at linaro.org (Lee Jones)
Date: Fri, 28 Aug 2015 11:31:50 +0100
Subject: [PATCH v2 3/4] remoteproc: Supply controller driver for ST's Remote
 Processors
In-Reply-To: <1440757911-9120-1-git-send-email-lee.jones@linaro.org>
References: <1440757911-9120-1-git-send-email-lee.jones@linaro.org>
Message-ID: <1440757911-9120-4-git-send-email-lee.jones@linaro.org>

Signed-off-by: Ludovic Barre <ludovic.barre at st.com>
Signed-off-by: Lee Jones <lee.jones at linaro.org>
---
 drivers/remoteproc/Kconfig         |   9 ++
 drivers/remoteproc/Makefile        |   1 +
 drivers/remoteproc/st_remoteproc.c | 301 +++++++++++++++++++++++++++++++++++++
 3 files changed, 311 insertions(+)
 create mode 100644 drivers/remoteproc/st_remoteproc.c

diff --git a/drivers/remoteproc/Kconfig b/drivers/remoteproc/Kconfig
index 28c711f..72e97d7 100644
--- a/drivers/remoteproc/Kconfig
+++ b/drivers/remoteproc/Kconfig
@@ -77,4 +77,13 @@ config DA8XX_REMOTEPROC
 	  It's safe to say n here if you're not interested in multimedia
 	  offloading.
 
+config ST_REMOTEPROC
+	tristate "ST remoteproc support"
+	depends on ARCH_STI
+	select REMOTEPROC
+	help
+	  Say y here to support ST's adjunct processors via the remote
+	  processor framework.
+	  This can be either built-in or a loadable module.
+
 endmenu
diff --git a/drivers/remoteproc/Makefile b/drivers/remoteproc/Makefile
index 81b04d1..279cb2e 100644
--- a/drivers/remoteproc/Makefile
+++ b/drivers/remoteproc/Makefile
@@ -11,3 +11,4 @@ obj-$(CONFIG_OMAP_REMOTEPROC)		+= omap_remoteproc.o
 obj-$(CONFIG_STE_MODEM_RPROC)	 	+= ste_modem_rproc.o
 obj-$(CONFIG_WKUP_M3_RPROC)		+= wkup_m3_rproc.o
 obj-$(CONFIG_DA8XX_REMOTEPROC)		+= da8xx_remoteproc.o
+obj-$(CONFIG_ST_REMOTEPROC)		+= st_remoteproc.o
diff --git a/drivers/remoteproc/st_remoteproc.c b/drivers/remoteproc/st_remoteproc.c
new file mode 100644
index 0000000..96b784d
--- /dev/null
+++ b/drivers/remoteproc/st_remoteproc.c
@@ -0,0 +1,301 @@
+/*
+ * ST's Remote Processor Control Driver
+ *
+ * Copyright (C) 2015 STMicroelectronics - All Rights Reserved
+ *
+ * Author: Ludovic Barre <ludovic.barre at st.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, or (at your option)
+ * any later version.
+ */
+
+#include <linux/clk.h>
+#include <linux/dma-mapping.h>
+#include <linux/err.h>
+#include <linux/interrupt.h>
+#include <linux/kernel.h>
+#include <linux/mfd/syscon.h>
+#include <linux/module.h>
+#include <linux/of.h>
+#include <linux/of_device.h>
+#include <linux/platform_device.h>
+#include <linux/regmap.h>
+#include <linux/remoteproc.h>
+#include <linux/reset.h>
+
+struct st_rproc_config {
+	bool			sw_reset;
+	bool			pwr_reset;
+	u32			bootaddr_mask;
+};
+
+struct st_rproc {
+	struct st_rproc_config	*config;
+	struct reset_control	*sw_reset;
+	struct reset_control	*pwr_reset;
+	struct clk		*clk;
+	u32			clk_rate;
+	struct	regmap		*boot_base;
+	u32			boot_offset;
+};
+
+static int st_rproc_stop(struct rproc *rproc)
+{
+	struct st_rproc *st_rproc = rproc->priv;
+	int ret, err = 0;
+
+	if (st_rproc->config->sw_reset) {
+		ret = reset_control_assert(st_rproc->sw_reset);
+		if (ret)
+			dev_err(&rproc->dev, "Failed to assert S/W Reset\n");
+	}
+
+	if (st_rproc->config->pwr_reset) {
+		err = reset_control_assert(st_rproc->pwr_reset);
+		if (err)
+			dev_err(&rproc->dev, "Failed to assert Power Reset\n");
+	}
+
+	clk_disable(st_rproc->clk);
+
+	return ret ?: err;
+}
+
+static int st_rproc_start(struct rproc *rproc)
+{
+	struct st_rproc *st_rproc = rproc->priv;
+	int err;
+
+	regmap_update_bits(st_rproc->boot_base, st_rproc->boot_offset,
+			   st_rproc->config->bootaddr_mask, rproc->bootaddr);
+
+	err = clk_enable(st_rproc->clk);
+	if (err) {
+		dev_err(&rproc->dev, "Failed to enable clock\n");
+		return err;
+	}
+
+	if (st_rproc->config->sw_reset) {
+		err = reset_control_deassert(st_rproc->sw_reset);
+		if (err) {
+			dev_err(&rproc->dev, "Failed to deassert S/W Reset\n");
+			return err;
+		}
+	}
+
+	if (st_rproc->config->pwr_reset) {
+		err = reset_control_deassert(st_rproc->pwr_reset);
+		if (err) {
+			dev_err(&rproc->dev, "Failed to deassert Power Reset\n");
+			return err;
+		}
+	}
+
+	dev_info(&rproc->dev, "Started from 0x%x\n", rproc->bootaddr);
+
+	return 0;
+}
+
+static struct rproc_ops st_rproc_ops = {
+	.start		= st_rproc_start,
+	.stop		= st_rproc_stop,
+};
+
+/*
+ * Fetch state of the processor: 0 is off, 1 is on.
+ */
+static int st_rproc_state(struct st_rproc *st_rproc)
+{
+	int reset_sw, reset_pwr;
+
+	reset_sw = st_rproc->config->sw_reset ?
+		reset_control_status(st_rproc->sw_reset) : 0;
+
+	reset_pwr = st_rproc->config->pwr_reset ?
+		reset_control_status(st_rproc->pwr_reset) : 0;
+
+	if (reset_sw < 0 || reset_pwr < 0)
+		return -EINVAL;
+
+	return !reset_sw && !reset_pwr;
+}
+
+static const struct st_rproc_config st40_rproc_cfg = {
+	.sw_reset = true,
+	.pwr_reset = true,
+	.bootaddr_mask = GENMASK(28, 1),
+};
+
+static const struct st_rproc_config st231_rproc_cfg = {
+	.sw_reset = true,
+	.pwr_reset = false,
+	.bootaddr_mask = GENMASK(31, 6),
+};
+
+static struct of_device_id st_rproc_match[] = {
+	{ .compatible = "st,st40-rproc", .data = &st40_rproc_cfg },
+	{ .compatible = "st,st231-rproc", .data = &st231_rproc_cfg },
+	{},
+};
+MODULE_DEVICE_TABLE(of, st_rproc_match);
+
+static int st_rproc_parse_dt(struct platform_device *pdev)
+{
+	struct device *dev = &pdev->dev;
+	struct rproc *rproc = platform_get_drvdata(pdev);
+	struct st_rproc *st_rproc = rproc->priv;
+	struct device_node *np = dev->of_node;
+	struct resource	*mem;
+	int err;
+
+	if (st_rproc->config->sw_reset) {
+		st_rproc->sw_reset = devm_reset_control_get(dev, "sw_reset");
+		if (IS_ERR(st_rproc->sw_reset)) {
+			dev_err(dev, "Failed to get S/W Reset\n");
+			return PTR_ERR(st_rproc->sw_reset);
+		}
+	}
+
+	if (st_rproc->config->pwr_reset) {
+		st_rproc->pwr_reset = devm_reset_control_get(dev, "pwr_reset");
+		if (IS_ERR(st_rproc->pwr_reset)) {
+			dev_err(dev, "Failed to get Power Reset\n");
+			return PTR_ERR(st_rproc->pwr_reset);
+		}
+	}
+
+	st_rproc->clk = devm_clk_get(dev, "rproc_clk");
+	if (IS_ERR(st_rproc->clk)) {
+		dev_err(dev, "Failed to get clock\n");
+		return PTR_ERR(st_rproc->clk);
+	}
+
+	err = of_property_read_u32(np, "clock-frequency", &st_rproc->clk_rate);
+	if (err) {
+		dev_err(dev, "failed to get clock frequency\n");
+		return err;
+	}
+
+
+	st_rproc->boot_base =
+		syscon_regmap_lookup_by_phandle(np, "st,syscfg-boot");
+	if (!st_rproc->boot_base) {
+		dev_err(dev, "Boot base not found\n");
+		return -EINVAL;
+	}
+
+	err = of_property_read_u32_index(np, "st,syscfg-boot", 1,
+					 &st_rproc->boot_offset);
+	if (err) {
+		dev_err(dev, "Boot offset not found\n");
+		return -EINVAL;
+	}
+
+	mem = platform_get_resource_byname(pdev, IORESOURCE_MEM, "carveout");
+	if (!mem) {
+		dev_err(dev, "no rproc memory definition\n");
+		return -ENXIO;
+	}
+
+	if (!devm_request_mem_region(dev, mem->start,
+				     resource_size(mem), pdev->name)) {
+		dev_err(dev, "failed to get memory region resource\n");
+		return -EBUSY;
+	}
+	err = dmam_declare_coherent_memory(dev, mem->start, mem->start,
+					  resource_size(mem),
+					  DMA_MEMORY_MAP |
+					  DMA_MEMORY_EXCLUSIVE);
+	if (err < 0) {
+		dev_err(dev, "cannot declare coherent memory: %d\n", err);
+		return -ENXIO;
+	}
+
+	err = clk_prepare(st_rproc->clk);
+	if (err)
+		dev_err(dev, "failed to get clock\n");
+
+	return err;
+}
+
+static int st_rproc_probe(struct platform_device *pdev)
+{
+	struct device *dev = &pdev->dev;
+	const struct of_device_id *match;
+	struct st_rproc *st_rproc;
+	struct device_node *np = dev->of_node;
+	struct rproc *rproc;
+	int enabled;
+	int ret;
+
+	match = of_match_device((st_rproc_match), dev);
+	if (!match || !match->data) {
+		dev_err(dev, "No device match found\n");
+		return -ENODEV;
+	}
+
+	rproc = rproc_alloc(dev, np->name, &st_rproc_ops,
+			    NULL, sizeof(*st_rproc));
+	if (!rproc)
+		return -ENOMEM;
+
+	st_rproc = rproc->priv;
+	st_rproc->config = (struct st_rproc_config *)match->data;
+	platform_set_drvdata(pdev, rproc);
+
+	ret = st_rproc_parse_dt(pdev);
+	if (ret)
+		goto free_rproc;
+
+	ret = st_rproc_state(st_rproc);
+	if (ret < 0)
+		goto free_rproc;
+	enabled = ret;
+
+	if (enabled) {
+		atomic_inc(&rproc->power);
+		rproc->state = RPROC_RUNNING;
+	} else {
+		clk_set_rate(st_rproc->clk, st_rproc->clk_rate);
+	}
+
+	ret = rproc_add(rproc);
+	if (ret)
+		goto free_rproc;
+
+	return 0;
+
+free_rproc:
+	rproc_put(rproc);
+	return ret;
+}
+
+static int st_rproc_remove(struct platform_device *pdev)
+{
+	struct rproc *rproc = platform_get_drvdata(pdev);
+	struct st_rproc *st_rproc = rproc->priv;
+
+	rproc_del(rproc);
+
+	clk_disable_unprepare(st_rproc->clk);
+
+	rproc_put(rproc);
+
+	return 0;
+}
+
+static struct platform_driver st_rproc_driver = {
+	.probe = st_rproc_probe,
+	.remove = st_rproc_remove,
+	.driver = {
+		.name = "st-rproc",
+		.of_match_table = of_match_ptr(st_rproc_match),
+	},
+};
+module_platform_driver(st_rproc_driver);
+
+MODULE_DESCRIPTION("ST Remote Processor Control Driver");
+MODULE_AUTHOR("Ludovic.barre <Ludovic.barre at st.com>");
+MODULE_LICENSE("GPL v2");
-- 
1.9.1



From b.zolnierkie at samsung.com  Fri Aug 28 03:46:05 2015
From: b.zolnierkie at samsung.com (Bartlomiej Zolnierkiewicz)
Date: Fri, 28 Aug 2015 12:46:05 +0200
Subject: [PATCH] clk: samsung: fix cpu clock's flags checking
In-Reply-To: <CABxcv=kVL94rdFgNKcxx2JOi9WRFnvhMWrpjEDcEmx7q7cEsgQ@mail.gmail.com>
References: <1435598978-21800-1-git-send-email-b.zolnierkie@samsung.com>
 <5591DD9B.4030507@samsung.com>
 <CABxcv=kVL94rdFgNKcxx2JOi9WRFnvhMWrpjEDcEmx7q7cEsgQ@mail.gmail.com>
Message-ID: <7248406.UkvN4Bv1cx@amdc1976>


Michael/Sylwester, could you please merge this patch?

It is a bugfix for ddeac8d968d41d13a52582d6e80395a329e9b1ff ("clk:
samsung: add infrastructure to register cpu clocks") which got
merged in v4.2-rc1.

Best regards,
--
Bartlomiej Zolnierkiewicz
Samsung R&D Institute Poland
Samsung Electronics

On Tuesday, June 30, 2015 08:27:36 AM Javier Martinez Canillas wrote:
> On Tue, Jun 30, 2015 at 2:06 AM, Krzysztof Kozlowski
> <k.kozlowski at samsung.com> wrote:
> > On 30.06.2015 02:29, Bartlomiej Zolnierkiewicz wrote:
> >> CLK_CPU_HAS_DIV1 and CLK_CPU_NEEDS_DEBUG_ALT_DIV masks were
> >> incorrectly used as a bit numbers.  Fix it.
> >>
> >> Tested on Exynos4210 based Origen board and on Exynos5250 based
> >> Arndale board.
> >>
> >> Cc: Tomasz Figa <tomasz.figa at gmail.com>
> >> Cc: Michael Turquette <mturquette at baylibre.com>
> >> Cc: Javier Martinez Canillas <javier.martinez at collabora.co.uk>
> >> Cc: Thomas Abraham <thomas.ab at samsung.com>
> >> Reported-by: Dan Carpenter <dan.carpenter at oracle.com>
> >> Signed-off-by: Bartlomiej Zolnierkiewicz <b.zolnierkie at samsung.com>
> >> ---
> >>  drivers/clk/samsung/clk-cpu.c | 10 +++++-----
> >>  1 file changed, 5 insertions(+), 5 deletions(-)
> >
> > Reviewed-by: Krzysztof Kozlowski <k.kozlowski at samsung.com>
> >
> 
> Looks good to me as well.
> 
> Reviewed-by: Javier Martinez Canillas <javier.martinez at collabora.co.uk>
> 
> > Best regards,
> > Krzysztof
> >
> 
> Best regards,
> Javier



From s.nawrocki at samsung.com  Fri Aug 28 03:50:19 2015
From: s.nawrocki at samsung.com (Sylwester Nawrocki)
Date: Fri, 28 Aug 2015 12:50:19 +0200
Subject: [PATCH] clk: samsung: fix cpu clock's flags checking
In-Reply-To: <1435598978-21800-1-git-send-email-b.zolnierkie@samsung.com>
References: <1435598978-21800-1-git-send-email-b.zolnierkie@samsung.com>
Message-ID: <55E03CEB.4070102@samsung.com>

On 29/06/15 19:29, Bartlomiej Zolnierkiewicz wrote:
> CLK_CPU_HAS_DIV1 and CLK_CPU_NEEDS_DEBUG_ALT_DIV masks were
> incorrectly used as a bit numbers.  Fix it.
> 
> Tested on Exynos4210 based Origen board and on Exynos5250 based
> Arndale board.
> 
> Cc: Tomasz Figa <tomasz.figa at gmail.com>
> Cc: Michael Turquette <mturquette at baylibre.com>
> Cc: Javier Martinez Canillas <javier.martinez at collabora.co.uk>
> Cc: Thomas Abraham <thomas.ab at samsung.com>
> Reported-by: Dan Carpenter <dan.carpenter at oracle.com>
> Signed-off-by: Bartlomiej Zolnierkiewicz <b.zolnierkie at samsung.com>

Acked-by: Sylwester Nawrocki <s.nawrocki at samsung.com>



From ryabinin.a.a at gmail.com  Fri Aug 28 04:09:59 2015
From: ryabinin.a.a at gmail.com (Andrey Ryabinin)
Date: Fri, 28 Aug 2015 14:09:59 +0300
Subject: [PATCH v2] x86, efi, kasan: #undef memset/memcpy/memmove per arch.
In-Reply-To: <20150828062745.GB1928@gmail.com>
References: <20150828062745.GB1928@gmail.com>
Message-ID: <1440760199-18111-1-git-send-email-ryabinin.a.a@gmail.com>

In not-instrumented code KASAN replaces instrumented
memset/memcpy/memmove with not-instrumented analogues
__memset/__memcpy/__memove.
However, on x86 the EFI stub is not linked with the kernel.
It uses not-instrumented mem*() functions from
arch/x86/boot/compressed/string.c
So we don't replace them with __mem*() variants in EFI stub.

On ARM64 the EFI stub is linked with the kernel, so we should
replace mem*() functions with __mem*(), because the EFI stub
runs before KASAN sets up early shadow.

So let's move these #undef mem* into arch's asm/efi.h which is
also included by the EFI stub.

Signed-off-by: Andrey Ryabinin <ryabinin.a.a at gmail.com>
---
 arch/x86/include/asm/efi.h             | 11 +++++++++++
 drivers/firmware/efi/libstub/efistub.h |  4 ----
 2 files changed, 11 insertions(+), 4 deletions(-)

diff --git a/arch/x86/include/asm/efi.h b/arch/x86/include/asm/efi.h
index 155162e..6862f11 100644
--- a/arch/x86/include/asm/efi.h
+++ b/arch/x86/include/asm/efi.h
@@ -25,6 +25,17 @@
 #define EFI32_LOADER_SIGNATURE	"EL32"
 #define EFI64_LOADER_SIGNATURE	"EL64"
 
+/*
+ * Sometimes we may redefine memset to __memset.
+ * The EFI stub doesn't have __memset() because it's not
+ * linked with the kernel. So we should use standard
+ * memset from arch/x86/boot/compressed/string.c
+ * The same applies to memcpy and memmove.
+ */
+#undef memcpy
+#undef memset
+#undef memmove
+
 #ifdef CONFIG_X86_32
 
 
diff --git a/drivers/firmware/efi/libstub/efistub.h b/drivers/firmware/efi/libstub/efistub.h
index e334a01..6b6548f 100644
--- a/drivers/firmware/efi/libstub/efistub.h
+++ b/drivers/firmware/efi/libstub/efistub.h
@@ -5,10 +5,6 @@
 /* error code which can't be mistaken for valid address */
 #define EFI_ERROR	(~0UL)
 
-#undef memcpy
-#undef memset
-#undef memmove
-
 void efi_char16_printk(efi_system_table_t *, efi_char16_t *);
 
 efi_status_t efi_open_volume(efi_system_table_t *sys_table_arg, void *__image,
-- 
2.4.6



From LW at KARO-electronics.de  Fri Aug 28 04:19:22 2015
From: LW at KARO-electronics.de (Lothar =?UTF-8?B?V2HDn21hbm4=?=)
Date: Fri, 28 Aug 2015 13:19:22 +0200
Subject: [PATCH v3 1/5] input: touchscreen: add imx6ul_tsc driver support
In-Reply-To: <1440752976-9094-2-git-send-email-haibo.chen@freescale.com>
References: <1440752976-9094-1-git-send-email-haibo.chen@freescale.com>
 <1440752976-9094-2-git-send-email-haibo.chen@freescale.com>
Message-ID: <20150828131922.79693714@ipc1.ka-ro>

Hi,

> Freescale i.MX6UL contains a internal touchscreen controller,
> this patch add a driver to support this controller.
> 
> Signed-off-by: Haibo Chen <haibo.chen at freescale.com>
> ---
>  drivers/input/touchscreen/Kconfig      |  12 +
>  drivers/input/touchscreen/Makefile     |   1 +
>  drivers/input/touchscreen/imx6ul_tsc.c | 524 +++++++++++++++++++++++++++++++++
>  3 files changed, 537 insertions(+)
>  create mode 100644 drivers/input/touchscreen/imx6ul_tsc.c
> 
> diff --git a/drivers/input/touchscreen/Kconfig b/drivers/input/touchscreen/Kconfig
> index 059edeb..50a42b8 100644
> --- a/drivers/input/touchscreen/Kconfig
> +++ b/drivers/input/touchscreen/Kconfig
> @@ -479,6 +479,18 @@ config TOUCHSCREEN_MTOUCH
>  	  To compile this driver as a module, choose M here: the
>  	  module will be called mtouch.
>  
> +config TOUCHSCREEN_IMX6UL_TSC
> +	tristate "Freescale i.MX6UL touchscreen controller"
> +	depends on (OF && GPIOLIB) || COMPILE_TEST
> +	help
> +	  Say Y here if you have a Freescale i.MX6UL, and want to
> +	  use the internal touchscreen controller.
> +
> +	  If unsure, say N.
> +
> +	  To compile this driver as a module, choose M here: the
> +	  moduel will be called imx6ul_tsc.
>
s/moduel/module/


Lothar Wa?mann



From matthias.bgg at gmail.com  Fri Aug 28 04:32:33 2015
From: matthias.bgg at gmail.com (Matthias Brugger)
Date: Fri, 28 Aug 2015 13:32:33 +0200
Subject: [PATCH v5 2/4] Documentation: arm64/arm: dt bindings for numa.
In-Reply-To: <1439570374-4079-3-git-send-email-gkulkarni@caviumnetworks.com>
References: <1439570374-4079-1-git-send-email-gkulkarni@caviumnetworks.com>
 <1439570374-4079-3-git-send-email-gkulkarni@caviumnetworks.com>
Message-ID: <55E046D1.10001@gmail.com>

On 14/08/15 18:39, Ganapatrao Kulkarni wrote:
> DT bindings for numa map for memory, cores and IOs using
> arm,associativity device node property.
>
> Signed-off-by: Ganapatrao Kulkarni <gkulkarni at caviumnetworks.com>
> ---
>   Documentation/devicetree/bindings/arm/numa.txt | 212 +++++++++++++++++++++++++
>   1 file changed, 212 insertions(+)
>   create mode 100644 Documentation/devicetree/bindings/arm/numa.txt
>
> diff --git a/Documentation/devicetree/bindings/arm/numa.txt b/Documentation/devicetree/bindings/arm/numa.txt
> new file mode 100644
> index 0000000..dc3ef86
> --- /dev/null
> +++ b/Documentation/devicetree/bindings/arm/numa.txt
> @@ -0,0 +1,212 @@
> +==============================================================================
> +NUMA binding description.
> +==============================================================================
> +
> +==============================================================================
> +1 - Introduction
> +==============================================================================
> +
> +Systems employing a Non Uniform Memory Access (NUMA) architecture contain
> +collections of hardware resources including processors, memory, and I/O buses,
> +that comprise what is commonly known as a NUMA node.
> +Processor accesses to memory within the local NUMA node is generally faster
> +than processor accesses to memory outside of the local NUMA node.
> +DT defines interfaces that allow the platform to convey NUMA node
> +topology information to OS.
> +
> +==============================================================================
> +2 - arm,associativity
> +==============================================================================
> +The mapping is done using arm,associativity device property.
> +this property needs to be present in every device node which needs to to be
> +mapped to numa nodes.
> +
> +arm,associativity property is set of 32-bit integers which defines level of
> +topology and boundary in the system at which a significant difference in
> +performance can be measured between cross-device accesses within
> +a single location and those spanning multiple locations.
> +The first cell always contains the broadest subdivision within the system,
> +while the last cell enumerates the individual devices, such as an SMT thread
> +of a CPU, or a bus bridge within an SoC".
> +
> +ex:
> +	/* board 0, socket 0, cluster 0, core 0  thread 0 */
> +	arm,associativity = <0 0 0 0 0>;
> +
> +==============================================================================
> +3 - arm,associativity-reference-points
> +==============================================================================
> +This property is a set of 32-bit integers, each representing an index into
> +the arm,associativity nodes. The first integer is the most significant
> +NUMA boundary and the following are progressively less significant boundaries.
> +There can be more than one level of NUMA.
> +
> +Ex:
> +	arm,associativity-reference-points = <0 1>;
> +	The board Id(index 0) used first to calculate the associativity (node
> +	distance), then follows the  socket id(index 1).
> +
> +	arm,associativity-reference-points = <1 0>;
> +	The socket Id(index 1) used first to calculate the associativity,
> +	then follows the board id(index 0).
> +
> +	arm,associativity-reference-points = <0>;
> +	Only the board Id(index 0) used to calculate the associativity.
> +
> +	arm,associativity-reference-points = <1>;
> +	Only socket Id(index 1) used to calculate the associativity.
> +
> +==============================================================================
> +4 - Example dts
> +==============================================================================
> +
> +Example: 2 Node system consists of 2 boards and each board having one socket
> +and 8 core in each socket.
> +
> +	arm,associativity-reference-points = <0>;
> +
> +	memory at 00c00000 {
> +		device_type = "memory";
> +		reg = <0x0 0x00c00000 0x0 0x80000000>;
> +		/* board 0, socket 0, no specific core */
> +		arm,associativity = <0 0 0xffff>;
> +	};
> +
> +	memory at 10000000000 {
> +		device_type = "memory";
> +		reg = <0x100 0x00000000 0x0 0x80000000>;
> +		/* board 1, socket 0, no specific core */
> +		arm,associativity = <1 0 0xffff>;
> +	};
> +
> +	cpus {
> +		#address-cells = <2>;
> +		#size-cells = <0>;
> +
> +		cpu at 000 {
> +			device_type = "cpu";
> +			compatible =  "arm,armv8";
> +			reg = <0x0 0x000>;
> +			enable-method = "psci";
> +			/* board 0, socket 0, core 0*/
> +			arm,associativity = <0 0 0>;
> +		};
> +		cpu at 001 {
> +			device_type = "cpu";
> +			compatible =  "arm,armv8";
> +			reg = <0x0 0x001>;
> +			enable-method = "psci";
> +			arm,associativity = <0 0 1>;
> +		};
> +		cpu at 002 {
> +			device_type = "cpu";
> +			compatible =  "arm,armv8";
> +			reg = <0x0 0x002>;
> +			enable-method = "psci";
> +			arm,associativity = <0 0 2>;
> +		};
> +		cpu at 003 {
> +			device_type = "cpu";
> +			compatible =  "arm,armv8";
> +			reg = <0x0 0x003>;
> +			enable-method = "psci";
> +			arm,associativity = <0 0 3>;
> +		};
> +		cpu at 004 {
> +			device_type = "cpu";
> +			compatible =  "arm,armv8";
> +			reg = <0x0 0x004>;
> +			enable-method = "psci";
> +			arm,associativity = <0 0 4>;
> +		};
> +		cpu at 005 {
> +			device_type = "cpu";
> +			compatible =  "arm,armv8";
> +			reg = <0x0 0x005>;
> +			enable-method = "psci";
> +			arm,associativity = <0 0 5>;
> +		};
> +		cpu at 006 {
> +			device_type = "cpu";
> +			compatible =  "arm,armv8";
> +			reg = <0x0 0x006>;
> +			enable-method = "psci";
> +			arm,associativity = <0 0 6>;
> +		};
> +		cpu at 007 {
> +			device_type = "cpu";
> +			compatible =  "arm,armv8";
> +			reg = <0x0 0x007>;
> +			enable-method = "psci";
> +			arm,associativity = <0 0 7>;
> +		};
> +		cpu at 008 {
> +			device_type = "cpu";
> +			compatible =  "arm,armv8";
> +			reg = <0x0 0x008>;
> +			enable-method = "psci";
> +			/* board 1, socket 0, core 0*/
> +			arm,associativity = <1 0 0>;
> +		};
> +		cpu at 009 {
> +			device_type = "cpu";
> +			compatible =  "arm,armv8";
> +			reg = <0x0 0x009>;
> +			enable-method = "psci";
> +			arm,associativity = <1 0 1>;
> +		};
> +		cpu at 00a {
> +			device_type = "cpu";
> +			compatible =  "arm,armv8";
> +			reg = <0x0 0x00a>;
> +			enable-method = "psci";
> +			arm,associativity = <0 0 2>;

Nit: this should be
arm,associativity = <1 0 2>;

> +		};
> +		cpu at 00b {
> +			device_type = "cpu";
> +			compatible =  "arm,armv8";
> +			reg = <0x0 0x00b>;
> +			enable-method = "psci";
> +			arm,associativity = <1 0 3>;
> +		};
> +		cpu at 00c {
> +			device_type = "cpu";
> +			compatible =  "arm,armv8";
> +			reg = <0x0 0x00c>;
> +			enable-method = "psci";
> +			arm,associativity = <1 0 4>;
> +		};
> +		cpu at 00d {
> +			device_type = "cpu";
> +			compatible =  "arm,armv8";
> +			reg = <0x0 0x00d>;
> +			enable-method = "psci";
> +			arm,associativity = <1 0 5>;
> +		};
> +		cpu at 00e {
> +			device_type = "cpu";
> +			compatible =  "arm,armv8";
> +			reg = <0x0 0x00e>;
> +			enable-method = "psci";
> +			arm,associativity = <1 0 6>;
> +		};
> +		cpu at 00f {
> +			device_type = "cpu";
> +			compatible =  "arm,armv8";
> +			reg = <0x0 0x00f>;
> +			enable-method = "psci";
> +			arm,associativity = <1 0 7>;
> +		};
> +	};
> +
> +	pcie0: pcie0 at 0x8480,00000000 {
> +		compatible = "arm,armv8";
> +		device_type = "pci";
> +		bus-range = <0 255>;
> +		#size-cells = <2>;
> +		#address-cells = <3>;
> +		reg = <0x8480 0x00000000 0 0x10000000>;  /* Configuration space */
> +		ranges = <0x03000000 0x8010 0x00000000 0x8010 0x00000000 0x70 0x00000000>; /* mem ranges */
> +		/* board 0, socket 0, pci bus 0*/
> +		arm,associativity = <0 0 0>;
> +        };
>



From alim.akhtar at samsung.com  Fri Aug 28 04:25:34 2015
From: alim.akhtar at samsung.com (Alim Akhtar)
Date: Fri, 28 Aug 2015 16:55:34 +0530
Subject: [PATCH] arm64: dts: Add BUS1 instance pinctrl support
Message-ID: <1440761134-27639-1-git-send-email-alim.akhtar@samsung.com>

This adds BUS1 instance pinctrl for exynos7 soc.

Signed-off-by: Alim Akhtar <alim.akhtar at samsung.com>
---
 arch/arm64/boot/dts/exynos/exynos7-pinctrl.dtsi |  111 +++++++++++++++++++++++
 arch/arm64/boot/dts/exynos/exynos7.dtsi         |    7 ++
 2 files changed, 118 insertions(+)

diff --git a/arch/arm64/boot/dts/exynos/exynos7-pinctrl.dtsi b/arch/arm64/boot/dts/exynos/exynos7-pinctrl.dtsi
index 2eef4a2..96be6e3 100644
--- a/arch/arm64/boot/dts/exynos/exynos7-pinctrl.dtsi
+++ b/arch/arm64/boot/dts/exynos/exynos7-pinctrl.dtsi
@@ -586,3 +586,114 @@
 		samsung,pin-drv = <2>;
 	};
 };
+
+&pinctrl_bus1 {
+	etc1: etc1 {
+		gpio-controller;
+		#gpio-cells = <2>;
+
+		interrupt-controller;
+		#interrupt-cells = <2>;
+	};
+
+	gpf0: gpf0 {
+		gpio-controller;
+		#gpio-cells = <2>;
+
+		interrupt-controller;
+		#interrupt-cells = <2>;
+	};
+
+	gpf1: gpf1 {
+		gpio-controller;
+		#gpio-cells = <2>;
+
+		interrupt-controller;
+		#interrupt-cells = <2>;
+	};
+
+	gpf2: gpf2 {
+		gpio-controller;
+		#gpio-cells = <2>;
+
+		interrupt-controller;
+		#interrupt-cells = <2>;
+	};
+
+	gpf3: gpf3 {
+		gpio-controller;
+		#gpio-cells = <2>;
+
+		interrupt-controller;
+		#interrupt-cells = <2>;
+	};
+
+	gpf4: gpf4 {
+		gpio-controller;
+		#gpio-cells = <2>;
+
+		interrupt-controller;
+		#interrupt-cells = <2>;
+	};
+
+	gpf5: gpf5 {
+		gpio-controller;
+		#gpio-cells = <2>;
+
+		interrupt-controller;
+		#interrupt-cells = <2>;
+	};
+
+	gpg1: gpg1 {
+		gpio-controller;
+		#gpio-cells = <2>;
+
+		interrupt-controller;
+		#interrupt-cells = <2>;
+	};
+
+	gpg2: gpg2 {
+		gpio-controller;
+		#gpio-cells = <2>;
+
+		interrupt-controller;
+		#interrupt-cells = <2>;
+	};
+
+	gph1: gph1 {
+		gpio-controller;
+		#gpio-cells = <2>;
+
+		interrupt-controller;
+		#interrupt-cells = <2>;
+	};
+
+	gpv6: gpv6 {
+		gpio-controller;
+		#gpio-cells = <2>;
+
+		interrupt-controller;
+		#interrupt-cells = <2>;
+	};
+
+	spi5_bus: spi5-bus {
+		samsung,pins = "gpf2-0", "gpf2-1", "gpf2-2", "gpf2-3";
+		samsung,pin-function = <2>;
+		samsung,pin-pud = <3>;
+		samsung,pin-drv = <0>;
+	};
+
+	ufs_refclk_out: ufs-refclk-out {
+		samsung,pins = "gpg2-4";
+		samsung,pin-function = <2>;
+		samsung,pin-pud = <0>;
+		samsung,pin-drv = <2>;
+	};
+
+	ufs_rst_n: ufs-rst-n {
+		samsung,pins = "gph1-5";
+		samsung,pin-function = <2>;
+		samsung,pin-pud = <3>;
+		samsung,pin-drv = <0>;
+	};
+};
diff --git a/arch/arm64/boot/dts/exynos/exynos7.dtsi b/arch/arm64/boot/dts/exynos/exynos7.dtsi
index d7a37c3..f9c5a54 100644
--- a/arch/arm64/boot/dts/exynos/exynos7.dtsi
+++ b/arch/arm64/boot/dts/exynos/exynos7.dtsi
@@ -26,6 +26,7 @@
 		pinctrl5 = &pinctrl_ese;
 		pinctrl6 = &pinctrl_fsys0;
 		pinctrl7 = &pinctrl_fsys1;
+		pinctrl8 = &pinctrl_bus1;
 	};
 
 	cpus {
@@ -278,6 +279,12 @@
 			interrupts = <0 203 0>;
 		};
 
+		pinctrl_bus1: pinctrl at 14870000 {
+			compatible = "samsung,exynos7-pinctrl";
+			reg = <0x14870000 0x1000>;
+			interrupts = <0 384 0>;
+		};
+
 		hsi2c_0: hsi2c at 13640000 {
 			compatible = "samsung,exynos7-hsi2c";
 			reg = <0x13640000 0x1000>;
-- 
1.7.10.4



From horia.geanta at freescale.com  Fri Aug 28 04:45:06 2015
From: horia.geanta at freescale.com (=?UTF-8?q?Horia=20Geant=C4=83?=)
Date: Fri, 28 Aug 2015 14:45:06 +0300
Subject: [RFC][PATCH 0/2] crypto: caam - Revamp I/O accessors
Message-ID: <1440762306-7764-1-git-send-email-horia.geanta@freescale.com>

(Part of the) I/O accessors in caam driver are PPC-specific.
Use io{read,write}XX[be] instead.

While here, prepare for "mixed" endianness platforms (like ARMv8-based
LS1043A), where caam endianness (big) does not match the endianness
of the core (little).

1st patch adds 64-bit accessors for arm64.

2nd patch updates the I/O accessors in the caam driver.

Horia Geant? (2):
  arm64: add ioread64be and iowrite64be macros
  crypto: caam - handle core endianness != caam endianness

 arch/arm64/include/asm/io.h       |  4 ++-
 drivers/crypto/caam/caamhash.c    |  5 +--
 drivers/crypto/caam/ctrl.c        |  2 +-
 drivers/crypto/caam/desc.h        |  9 ++++-
 drivers/crypto/caam/desc_constr.h | 42 +++++++++++++++--------
 drivers/crypto/caam/jr.c          |  8 ++---
 drivers/crypto/caam/regs.h        | 72 ++++++++++++++++++++++++++++-----------
 drivers/crypto/caam/sg_sw_sec4.h  | 10 +++---
 8 files changed, 105 insertions(+), 47 deletions(-)

-- 
2.4.4



From horia.geanta at freescale.com  Fri Aug 28 04:49:47 2015
From: horia.geanta at freescale.com (=?UTF-8?q?Horia=20Geant=C4=83?=)
Date: Fri, 28 Aug 2015 14:49:47 +0300
Subject: [RFC][PATCH 1/2] arm64: add ioread64be and iowrite64be macros
In-Reply-To: <1440762306-7764-1-git-send-email-horia.geanta@freescale.com>
References: <1440762306-7764-1-git-send-email-horia.geanta@freescale.com>
Message-ID: <1440762587-7815-1-git-send-email-horia.geanta@freescale.com>

This will allow device drivers to consistently use io{read,write}XXbe
macros also for 64-bit accesses.

Signed-off-by: Alex Porosanu <alexandru.porosanu at freescale.com>
Signed-off-by: Horia Geant? <horia.geanta at freescale.com>
---
 arch/arm64/include/asm/io.h | 4 +++-
 1 file changed, 3 insertions(+), 1 deletion(-)

diff --git a/arch/arm64/include/asm/io.h b/arch/arm64/include/asm/io.h
index 44be1e03ed65..9b6e408cfa51 100644
--- a/arch/arm64/include/asm/io.h
+++ b/arch/arm64/include/asm/io.h
@@ -174,13 +174,15 @@ extern void __iomem *ioremap_cache(phys_addr_t phys_addr, size_t size);
 #define iounmap				__iounmap
 
 /*
- * io{read,write}{16,32}be() macros
+ * io{read,write}{16,32,64}be() macros
  */
 #define ioread16be(p)		({ __u16 __v = be16_to_cpu((__force __be16)__raw_readw(p)); __iormb(); __v; })
 #define ioread32be(p)		({ __u32 __v = be32_to_cpu((__force __be32)__raw_readl(p)); __iormb(); __v; })
+#define ioread64be(p)		({ __u64 __v = be64_to_cpu((__force __be64)__raw_readq(p)); __iormb(); __v; })
 
 #define iowrite16be(v,p)	({ __iowmb(); __raw_writew((__force __u16)cpu_to_be16(v), p); })
 #define iowrite32be(v,p)	({ __iowmb(); __raw_writel((__force __u32)cpu_to_be32(v), p); })
+#define iowrite64be(v,p)	({ __iowmb(); __raw_writeq((__force __u64)cpu_to_be64(v), p); })
 
 /*
  * Convert a physical pointer to a virtual kernel pointer for /dev/mem
-- 
2.4.4



From b.zolnierkie at samsung.com  Fri Aug 28 04:49:35 2015
From: b.zolnierkie at samsung.com (Bartlomiej Zolnierkiewicz)
Date: Fri, 28 Aug 2015 13:49:35 +0200
Subject: [PATCH v2] clk: samsung: fix cpu clock's flags checking
Message-ID: <1440762575-21520-1-git-send-email-b.zolnierkie@samsung.com>

CLK_CPU_HAS_DIV1 and CLK_CPU_NEEDS_DEBUG_ALT_DIV masks were
incorrectly used as a bit numbers.  Fix it.

Tested on Exynos4210 based Origen board and on Exynos5250 based
Arndale board.

Cc: Tomasz Figa <tomasz.figa at gmail.com>
Cc: Michael Turquette <mturquette at baylibre.com>
Cc: Thomas Abraham <thomas.ab at samsung.com>
Fixes: ddeac8d96 ("clk: samsung: add infrastructure to register cpu clocks")
Reported-by: Dan Carpenter <dan.carpenter at oracle.com>
Reviewed-by: Krzysztof Kozlowski <k.kozlowski at samsung.com>
Reviewed-by: Javier Martinez Canillas <javier at dowhile0.org>
Acked-by: Sylwester Nawrocki <s.nawrocki at samsung.com>
Signed-off-by: Bartlomiej Zolnierkiewicz <b.zolnierkie at samsung.com>
---
v2:
- added Reviewed-by, Acked-by and Fixes tags (no code changes)

Michael, please apply.  Thank you.

 drivers/clk/samsung/clk-cpu.c | 10 +++++-----
 1 file changed, 5 insertions(+), 5 deletions(-)

diff --git a/drivers/clk/samsung/clk-cpu.c b/drivers/clk/samsung/clk-cpu.c
index 7c1e1f5..2fe37f7 100644
--- a/drivers/clk/samsung/clk-cpu.c
+++ b/drivers/clk/samsung/clk-cpu.c
@@ -164,7 +164,7 @@ static int exynos_cpuclk_pre_rate_change(struct clk_notifier_data *ndata,
 	 * the values for DIV_COPY and DIV_HPM dividers need not be set.
 	 */
 	div0 = cfg_data->div0;
-	if (test_bit(CLK_CPU_HAS_DIV1, &cpuclk->flags)) {
+	if (cpuclk->flags & CLK_CPU_HAS_DIV1) {
 		div1 = cfg_data->div1;
 		if (readl(base + E4210_SRC_CPU) & E4210_MUX_HPM_MASK)
 			div1 = readl(base + E4210_DIV_CPU1) &
@@ -185,7 +185,7 @@ static int exynos_cpuclk_pre_rate_change(struct clk_notifier_data *ndata,
 		alt_div = DIV_ROUND_UP(alt_prate, tmp_rate) - 1;
 		WARN_ON(alt_div >= MAX_DIV);
 
-		if (test_bit(CLK_CPU_NEEDS_DEBUG_ALT_DIV, &cpuclk->flags)) {
+		if (cpuclk->flags & CLK_CPU_NEEDS_DEBUG_ALT_DIV) {
 			/*
 			 * In Exynos4210, ATB clock parent is also mout_core. So
 			 * ATB clock also needs to be mantained at safe speed.
@@ -206,7 +206,7 @@ static int exynos_cpuclk_pre_rate_change(struct clk_notifier_data *ndata,
 	writel(div0, base + E4210_DIV_CPU0);
 	wait_until_divider_stable(base + E4210_DIV_STAT_CPU0, DIV_MASK_ALL);
 
-	if (test_bit(CLK_CPU_HAS_DIV1, &cpuclk->flags)) {
+	if (cpuclk->flags & CLK_CPU_HAS_DIV1) {
 		writel(div1, base + E4210_DIV_CPU1);
 		wait_until_divider_stable(base + E4210_DIV_STAT_CPU1,
 				DIV_MASK_ALL);
@@ -225,7 +225,7 @@ static int exynos_cpuclk_post_rate_change(struct clk_notifier_data *ndata,
 	unsigned long mux_reg;
 
 	/* find out the divider values to use for clock data */
-	if (test_bit(CLK_CPU_NEEDS_DEBUG_ALT_DIV, &cpuclk->flags)) {
+	if (cpuclk->flags & CLK_CPU_NEEDS_DEBUG_ALT_DIV) {
 		while ((cfg_data->prate * 1000) != ndata->new_rate) {
 			if (cfg_data->prate == 0)
 				return -EINVAL;
@@ -240,7 +240,7 @@ static int exynos_cpuclk_post_rate_change(struct clk_notifier_data *ndata,
 	writel(mux_reg & ~(1 << 16), base + E4210_SRC_CPU);
 	wait_until_mux_stable(base + E4210_STAT_CPU, 16, 1);
 
-	if (test_bit(CLK_CPU_NEEDS_DEBUG_ALT_DIV, &cpuclk->flags)) {
+	if (cpuclk->flags & CLK_CPU_NEEDS_DEBUG_ALT_DIV) {
 		div |= (cfg_data->div0 & E4210_DIV0_ATB_MASK);
 		div_mask |= E4210_DIV0_ATB_MASK;
 	}
-- 
1.9.1



From horia.geanta at freescale.com  Fri Aug 28 04:50:08 2015
From: horia.geanta at freescale.com (=?UTF-8?q?Horia=20Geant=C4=83?=)
Date: Fri, 28 Aug 2015 14:50:08 +0300
Subject: [RFC][PATCH 2/2] crypto: caam - handle core endianness != caam
 endianness
In-Reply-To: <1440762306-7764-1-git-send-email-horia.geanta@freescale.com>
References: <1440762306-7764-1-git-send-email-horia.geanta@freescale.com>
Message-ID: <1440762608-7866-1-git-send-email-horia.geanta@freescale.com>

There are SoCs like LS1043A where CAAM endianness (BE) does not match
the endianness of the core (LE).
Moreover, there are requirements for the driver to handle cases like
CPU_BIG_ENDIAN=y on ARM-based SoCs.
This requires for a complete rewrite of the I/O accessors.

PPC-specific accessors - {in,out}_{le,be}XX - are replaced with
generic io{read,write}[be]XX where possible (no 64-bit generic I/O).

Signed-off-by: Horia Geant? <horia.geanta at freescale.com>
Signed-off-by: Alex Porosanu <alexandru.porosanu at freescale.com>
---

While patch takes into consideration the S/G format (struct sec4_sg_entry)
for i.MX7, I don't have a board so I haven't tested this platform.

 drivers/crypto/caam/caamhash.c    |  5 +--
 drivers/crypto/caam/ctrl.c        |  2 +-
 drivers/crypto/caam/desc.h        |  9 ++++-
 drivers/crypto/caam/desc_constr.h | 42 +++++++++++++++--------
 drivers/crypto/caam/jr.c          |  8 ++---
 drivers/crypto/caam/regs.h        | 72 ++++++++++++++++++++++++++++-----------
 drivers/crypto/caam/sg_sw_sec4.h  | 10 +++---
 7 files changed, 102 insertions(+), 46 deletions(-)

diff --git a/drivers/crypto/caam/caamhash.c b/drivers/crypto/caam/caamhash.c
index 72acf8e5ac2f..c39332171fa3 100644
--- a/drivers/crypto/caam/caamhash.c
+++ b/drivers/crypto/caam/caamhash.c
@@ -841,7 +841,7 @@ static int ahash_update_ctx(struct ahash_request *req)
 							 *next_buflen, 0);
 		} else {
 			(edesc->sec4_sg + sec4_sg_src_index - 1)->len |=
-							SEC4_SG_LEN_FIN;
+				cpu_to_caam32(SEC4_SG_LEN_FIN);
 		}
 
 		state->current_buf = !state->current_buf;
@@ -942,7 +942,8 @@ static int ahash_final_ctx(struct ahash_request *req)
 	state->buf_dma = try_buf_map_to_sec4_sg(jrdev, edesc->sec4_sg + 1,
 						buf, state->buf_dma, buflen,
 						last_buflen);
-	(edesc->sec4_sg + sec4_sg_bytes - 1)->len |= SEC4_SG_LEN_FIN;
+	(edesc->sec4_sg + sec4_sg_bytes - 1)->len |=
+		cpu_to_caam32(SEC4_SG_LEN_FIN);
 
 	edesc->sec4_sg_dma = dma_map_single(jrdev, edesc->sec4_sg,
 					    sec4_sg_bytes, DMA_TO_DEVICE);
diff --git a/drivers/crypto/caam/ctrl.c b/drivers/crypto/caam/ctrl.c
index 8abb4bc548cc..e527d1e0b9ab 100644
--- a/drivers/crypto/caam/ctrl.c
+++ b/drivers/crypto/caam/ctrl.c
@@ -128,7 +128,7 @@ static inline int run_descriptor_deco0(struct device *ctrldev, u32 *desc,
 	}
 
 	for (i = 0; i < desc_len(desc); i++)
-		wr_reg32(&deco->descbuf[i], *(desc + i));
+		wr_reg32(&deco->descbuf[i], caam32_to_cpu(*(desc + i)));
 
 	flags = DECO_JQCR_WHL;
 	/*
diff --git a/drivers/crypto/caam/desc.h b/drivers/crypto/caam/desc.h
index 983d663ef671..fc257b343d3b 100644
--- a/drivers/crypto/caam/desc.h
+++ b/drivers/crypto/caam/desc.h
@@ -23,16 +23,23 @@
 #define SEC4_SG_OFFS_MASK	0x00001fff
 
 struct sec4_sg_entry {
-#ifdef CONFIG_CRYPTO_DEV_FSL_CAAM_IMX
+#if !defined(CONFIG_ARCH_DMA_ADDR_T_64BIT) && \
+	defined(CONFIG_CRYPTO_DEV_FSL_CAAM_IMX)
 	u32 rsvd1;
 	dma_addr_t ptr;
 #else
 	u64 ptr;
 #endif /* CONFIG_CRYPTO_DEV_FSL_CAAM_IMX */
 	u32 len;
+#ifndef CONFIG_CRYPTO_DEV_FSL_CAAM_LE
 	u8 rsvd2;
 	u8 buf_pool_id;
 	u16 offset;
+#else
+	u16 offset;
+	u8 buf_pool_id;
+	u8 rsvd2;
+#endif /* CONFIG_CRYPTO_DEV_FSL_CAAM_LE */
 };
 
 /* Max size of any CAAM descriptor in 32-bit words, inclusive of header */
diff --git a/drivers/crypto/caam/desc_constr.h b/drivers/crypto/caam/desc_constr.h
index 98d07de24fc4..40baf4752fbc 100644
--- a/drivers/crypto/caam/desc_constr.h
+++ b/drivers/crypto/caam/desc_constr.h
@@ -5,6 +5,7 @@
  */
 
 #include "desc.h"
+#include "regs.h"
 
 #define IMMEDIATE (1 << 23)
 #define CAAM_CMD_SZ sizeof(u32)
@@ -32,7 +33,7 @@
 
 static inline int desc_len(u32 *desc)
 {
-	return *desc & HDR_DESCLEN_MASK;
+	return caam32_to_cpu(*desc) & HDR_DESCLEN_MASK;
 }
 
 static inline int desc_bytes(void *desc)
@@ -52,7 +53,7 @@ static inline void *sh_desc_pdb(u32 *desc)
 
 static inline void init_desc(u32 *desc, u32 options)
 {
-	*desc = (options | HDR_ONE) + 1;
+	*desc = cpu_to_caam32((options | HDR_ONE) + 1);
 }
 
 static inline void init_sh_desc(u32 *desc, u32 options)
@@ -78,9 +79,10 @@ static inline void append_ptr(u32 *desc, dma_addr_t ptr)
 {
 	dma_addr_t *offset = (dma_addr_t *)desc_end(desc);
 
-	*offset = ptr;
+	*offset = wr_dma(ptr);
 
-	(*desc) += CAAM_PTR_SZ / CAAM_CMD_SZ;
+	(*desc) = cpu_to_caam32(caam32_to_cpu(*desc) +
+				CAAM_PTR_SZ / CAAM_CMD_SZ);
 }
 
 static inline void init_job_desc_shared(u32 *desc, dma_addr_t ptr, int len,
@@ -99,16 +101,17 @@ static inline void append_data(u32 *desc, void *data, int len)
 	if (len) /* avoid sparse warning: memcpy with byte count of 0 */
 		memcpy(offset, data, len);
 
-	(*desc) += (len + CAAM_CMD_SZ - 1) / CAAM_CMD_SZ;
+	(*desc) = cpu_to_caam32(caam32_to_cpu(*desc) +
+				(len + CAAM_CMD_SZ - 1) / CAAM_CMD_SZ);
 }
 
 static inline void append_cmd(u32 *desc, u32 command)
 {
 	u32 *cmd = desc_end(desc);
 
-	*cmd = command;
+	*cmd = cpu_to_caam32(command);
 
-	(*desc)++;
+	(*desc) = cpu_to_caam32(caam32_to_cpu(*desc) + 1);
 }
 
 #define append_u32 append_cmd
@@ -117,16 +120,22 @@ static inline void append_u64(u32 *desc, u64 data)
 {
 	u32 *offset = desc_end(desc);
 
-	*offset = upper_32_bits(data);
-	*(++offset) = lower_32_bits(data);
+	/* Only 32-bit alignment is guaranteed in descriptor buffer */
+	if (IS_ENABLED(CONFIG_CRYPTO_DEV_FSL_CAAM_LE)) {
+		*offset = cpu_to_caam32(lower_32_bits(data));
+		*(++offset) = cpu_to_caam32(upper_32_bits(data));
+	} else {
+		*offset = cpu_to_caam32(upper_32_bits(data));
+		*(++offset) = cpu_to_caam32(lower_32_bits(data));
+	}
 
-	(*desc) += 2;
+	(*desc) = cpu_to_caam32(caam32_to_cpu(*desc) + 2);
 }
 
 /* Write command without affecting header, and return pointer to next word */
 static inline u32 *write_cmd(u32 *desc, u32 command)
 {
-	*desc = command;
+	*desc = cpu_to_caam32(command);
 
 	return desc + 1;
 }
@@ -168,14 +177,17 @@ APPEND_CMD_RET(move, MOVE)
 
 static inline void set_jump_tgt_here(u32 *desc, u32 *jump_cmd)
 {
-	*jump_cmd = *jump_cmd | (desc_len(desc) - (jump_cmd - desc));
+	*jump_cmd = cpu_to_caam32(caam32_to_cpu(*jump_cmd) |
+				  (desc_len(desc) - (jump_cmd - desc)));
 }
 
 static inline void set_move_tgt_here(u32 *desc, u32 *move_cmd)
 {
-	*move_cmd &= ~MOVE_OFFSET_MASK;
-	*move_cmd = *move_cmd | ((desc_len(desc) << (MOVE_OFFSET_SHIFT + 2)) &
-				 MOVE_OFFSET_MASK);
+	u32 val = caam32_to_cpu(*move_cmd);
+
+	val &= ~MOVE_OFFSET_MASK;
+	val |= (desc_len(desc) << (MOVE_OFFSET_SHIFT + 2)) & MOVE_OFFSET_MASK;
+	*move_cmd = cpu_to_caam32(val);
 }
 
 #define APPEND_CMD(cmd, op) \
diff --git a/drivers/crypto/caam/jr.c b/drivers/crypto/caam/jr.c
index f7e0d8d4c3da..5add26b2a2ff 100644
--- a/drivers/crypto/caam/jr.c
+++ b/drivers/crypto/caam/jr.c
@@ -182,7 +182,7 @@ static void caam_jr_dequeue(unsigned long devarg)
 			sw_idx = (tail + i) & (JOBR_DEPTH - 1);
 
 			if (jrp->outring[hw_idx].desc ==
-			    jrp->entinfo[sw_idx].desc_addr_dma)
+			    rd_dma(jrp->entinfo[sw_idx].desc_addr_dma))
 				break; /* found */
 		}
 		/* we should never fail to find a matching descriptor */
@@ -200,7 +200,7 @@ static void caam_jr_dequeue(unsigned long devarg)
 		usercall = jrp->entinfo[sw_idx].callbk;
 		userarg = jrp->entinfo[sw_idx].cbkarg;
 		userdesc = jrp->entinfo[sw_idx].desc_addr_virt;
-		userstatus = jrp->outring[hw_idx].jrstatus;
+		userstatus = caam32_to_cpu(jrp->outring[hw_idx].jrstatus);
 
 		/*
 		 * Make sure all information from the job has been obtained
@@ -330,7 +330,7 @@ int caam_jr_enqueue(struct device *dev, u32 *desc,
 	int head, tail, desc_size;
 	dma_addr_t desc_dma;
 
-	desc_size = (*desc & HDR_JD_LENGTH_MASK) * sizeof(u32);
+	desc_size = (caam32_to_cpu(*desc) & HDR_JD_LENGTH_MASK) * sizeof(u32);
 	desc_dma = dma_map_single(dev, desc, desc_size, DMA_TO_DEVICE);
 	if (dma_mapping_error(dev, desc_dma)) {
 		dev_err(dev, "caam_jr_enqueue(): can't map jobdesc\n");
@@ -356,7 +356,7 @@ int caam_jr_enqueue(struct device *dev, u32 *desc,
 	head_entry->cbkarg = areq;
 	head_entry->desc_addr_dma = desc_dma;
 
-	jrp->inpring[jrp->inp_ring_write_index] = desc_dma;
+	jrp->inpring[jrp->inp_ring_write_index] = wr_dma(desc_dma);
 
 	/*
 	 * Guarantee that the descriptor's DMA address has been written to
diff --git a/drivers/crypto/caam/regs.h b/drivers/crypto/caam/regs.h
index a8a79975682f..d3e93e066cd8 100644
--- a/drivers/crypto/caam/regs.h
+++ b/drivers/crypto/caam/regs.h
@@ -65,7 +65,7 @@
  *
  */
 
-#ifdef CONFIG_ARM
+#if defined(CONFIG_ARM) || defined(CONFIG_ARM64)
 /* These are common macros for Power, put here for ARM */
 #define setbits32(_addr, _v) writel((readl(_addr) | (_v)), (_addr))
 #define clrbits32(_addr, _v) writel((readl(_addr) & ~(_v)), (_addr))
@@ -86,26 +86,62 @@
 #define clrsetbits_le32(addr, clear, set) clrsetbits(le32, addr, clear, set)
 #endif
 
-#ifdef __BIG_ENDIAN
-#define wr_reg32(reg, data) out_be32(reg, data)
-#define rd_reg32(reg) in_be32(reg)
+#ifdef CONFIG_CRYPTO_DEV_FSL_CAAM_LE
+#define caam16_to_cpu(value) le16_to_cpu(value)
+#define cpu_to_caam16(value) cpu_to_le16(value)
+#define caam32_to_cpu(value) le32_to_cpu(value)
+#define cpu_to_caam32(value) cpu_to_le32(value)
+#define caam64_to_cpu(value) le64_to_cpu(value)
+#define cpu_to_caam64(value) cpu_to_le64(value)
+#define wr_reg32(reg, data) iowrite32(data, reg)
+#define rd_reg32(reg) ioread32(reg)
+#define clrsetbits_32(addr, clear, set) clrsetbits_le32(addr, clear, set)
+#else
+#define caam16_to_cpu(value) be16_to_cpu(value)
+#define cpu_to_caam16(value) cpu_to_be16(value)
+#define caam32_to_cpu(value) be32_to_cpu(value)
+#define cpu_to_caam32(value) cpu_to_be32(value)
+#define caam64_to_cpu(value) be64_to_cpu(value)
+#define cpu_to_caam64(value) cpu_to_be64(value)
+#define wr_reg32(reg, data) iowrite32be(data, reg)
+#define rd_reg32(reg) ioread32be(reg)
 #define clrsetbits_32(addr, clear, set) clrsetbits_be32(addr, clear, set)
-#ifdef CONFIG_64BIT
-#define wr_reg64(reg, data) out_be64(reg, data)
-#define rd_reg64(reg) in_be64(reg)
 #endif
+
+#ifdef CONFIG_ARCH_DMA_ADDR_T_64BIT
+#ifdef CONFIG_SOC_IMX7D
+#define wr_dma(value) (((u64)cpu_to_caam32(lower_32_bits(value)) << 32) | \
+			(u64)cpu_to_caam32(higher_32_bits(value)))
+#define rd_dma(value) (((u64)caam32_to_cpu(lower_32_bits(value)) << 32) | \
+			(u64)caam32_to_cpu(higher_32_bits(value)))
 #else
-#ifdef __LITTLE_ENDIAN
-#define wr_reg32(reg, data) __raw_writel(data, reg)
-#define rd_reg32(reg) __raw_readl(reg)
-#define clrsetbits_32(addr, clear, set) clrsetbits_le32(addr, clear, set)
-#ifdef CONFIG_64BIT
-#define wr_reg64(reg, data) __raw_writeq(data, reg)
-#define rd_reg64(reg) __raw_readq(reg)
-#endif
-#endif
+#define wr_dma(value) cpu_to_caam64(value)
+#define rd_dma(value) caam64_to_cpu(value)
+#endif /* CONFIG_SOC_IMX7D */
+#else
+#define wr_dma(value) cpu_to_caam32(value)
+#define rd_dma(value) caam32_to_cpu(value)
 #endif
 
+#ifdef CONFIG_64BIT
+#ifdef CONFIG_PPC
+#ifdef CONFIG_CRYPTO_DEV_FSL_CAAM_LE
+#define wr_reg64(reg, data) out_le64(reg, data)
+#define rd_reg64(reg) in_le64(reg)
+#else
+#define wr_reg64(reg, data) out_be64(reg, data)
+#define rd_reg64(reg) in_be64(reg)
+#endif /* CONFIG_CRYPTO_DEV_FSL_CAAM_LE */
+#else /* CONFIG_PPC */
+#ifdef CONFIG_CRYPTO_DEV_FSL_CAAM_LE
+#define wr_reg64(reg, data) writeq(data, reg)
+#define rd_reg64(reg) readq(reg)
+#else
+#define wr_reg64(reg, data) iowrite64be(data, reg)
+#define rd_reg64(reg) ioread64be(reg)
+#endif /* CONFIG_CRYPTO_DEV_FSL_CAAM_LE */
+#endif /* CONFIG_PPC */
+#else /* CONFIG_64BIT */
 /*
  * The only users of these wr/rd_reg64 functions is the Job Ring (JR).
  * The DMA address registers in the JR are handled differently depending on
@@ -123,8 +159,6 @@
  *    base + 0x0000 : least-significant 32 bits
  *    base + 0x0004 : most-significant 32 bits
  */
-
-#ifndef CONFIG_64BIT
 #if !defined(CONFIG_CRYPTO_DEV_FSL_CAAM_LE) || \
 	defined(CONFIG_CRYPTO_DEV_FSL_CAAM_IMX)
 #define REG64_MS32(reg) ((u32 __iomem *)(reg))
@@ -145,7 +179,7 @@ static inline u64 rd_reg64(u64 __iomem *reg)
 	return ((u64)rd_reg32(REG64_MS32(reg)) << 32 |
 		(u64)rd_reg32(REG64_LS32(reg)));
 }
-#endif
+#endif /* CONFIG_64BIT */
 
 /*
  * jr_outentry
diff --git a/drivers/crypto/caam/sg_sw_sec4.h b/drivers/crypto/caam/sg_sw_sec4.h
index 18cd6d1f5870..fb8e0084e3e5 100644
--- a/drivers/crypto/caam/sg_sw_sec4.h
+++ b/drivers/crypto/caam/sg_sw_sec4.h
@@ -5,6 +5,8 @@
  *
  */
 
+#include "regs.h"
+
 struct sec4_sg_entry;
 
 /*
@@ -13,10 +15,10 @@ struct sec4_sg_entry;
 static inline void dma_to_sec4_sg_one(struct sec4_sg_entry *sec4_sg_ptr,
 				      dma_addr_t dma, u32 len, u32 offset)
 {
-	sec4_sg_ptr->ptr = dma;
-	sec4_sg_ptr->len = len;
+	sec4_sg_ptr->ptr = wr_dma(dma);
+	sec4_sg_ptr->len = cpu_to_caam32(len);
 	sec4_sg_ptr->buf_pool_id = 0;
-	sec4_sg_ptr->offset = offset;
+	sec4_sg_ptr->offset = cpu_to_caam16(offset & SEC4_SG_OFFS_MASK);
 #ifdef DEBUG
 	print_hex_dump(KERN_ERR, "sec4_sg_ptr@: ",
 		       DUMP_PREFIX_ADDRESS, 16, 4, sec4_sg_ptr,
@@ -51,7 +53,7 @@ static inline void sg_to_sec4_sg_last(struct scatterlist *sg, int sg_count,
 				      u32 offset)
 {
 	sec4_sg_ptr = sg_to_sec4_sg(sg, sg_count, sec4_sg_ptr, offset);
-	sec4_sg_ptr->len |= SEC4_SG_LEN_FIN;
+	sec4_sg_ptr->len |= cpu_to_caam32(SEC4_SG_LEN_FIN);
 }
 
 static inline struct sec4_sg_entry *sg_to_sec4_sg_len(
-- 
2.4.4



From grygorii.strashko at ti.com  Fri Aug 28 05:04:52 2015
From: grygorii.strashko at ti.com (Grygorii Strashko)
Date: Fri, 28 Aug 2015 15:04:52 +0300
Subject: [PATCH] ARM: OMAP2+: omap-device: remove omap_device_late_init
 call completely
In-Reply-To: <55E028C7.3060509@ti.com>
References: <1440611890-4935-1-git-send-email-grygorii.strashko@ti.com>
 <20150826181006.GT4215@atomide.com> <55DF12E7.10802@ti.com>
 <20150827163856.GX4215@atomide.com> <55DF4398.7020201@ti.com>
 <55E028C7.3060509@ti.com>
Message-ID: <55E04E64.2070204@ti.com>

On 08/28/2015 12:24 PM, Keerthy wrote:
>
>
> On Thursday 27 August 2015 10:36 PM, Grygorii Strashko wrote:
>> On 08/27/2015 07:38 PM, Tony Lindgren wrote:
>>> * Grygorii Strashko <grygorii.strashko at ti.com> [150827 06:42]:
>>>> Hi Tony,
>>>>
>>>> On 08/26/2015 09:10 PM, Tony Lindgren wrote:
>>>>> * Grygorii Strashko <grygorii.strashko at ti.com> [150826 11:01]:
>>>>>> Now Kernel fails to boot 50% of times (form build to build) with
>>>>>> RT-patchset applied due to the following race - on late boot
>>>>>> stages deferred_probe_work_func races with omap_device_late_ini
>>>>>>
>>>>>> late_initcall
>>>>>>     - deferred_probe_initcal() tries to re-probe all pending
>>>>>> driver's probe.
>>>>>>       [In general, It's NOT expected to probe any other built-in
>>>>>> drivers after
>>>>>>       deferred_probe_initcal() is finished, because most of
>>>>>>       late_initcall_sync/late_initcall functions expected that all
>>>>>> driver
>>>>>>       or probed or deferred already.]
>>>>>>
>>>>>> - later on, some driver is probing in this case It's could cpsw.c
>>>>>>      (but could be any other drivers)
>>>>>>      cpsw_init
>>>>>>      - platform_driver_register
>>>>>>        - really_probe
>>>>>>           - driver_bound
>>>>>>             - driver_deferred_probe_trigger
>>>>>>      and boot proceed.
>>>>>>      So, at this moment we have  deferred_probe_work_func scheduled.
>>>>>>
>>>>>> late_initcall_sync
>>>>>>      - omap_device_late_init
>>>>>>        - omap_device_idle
>>>>>>
>>>>>> CPU1                    CPU2
>>>>>>      - deferred_probe_work_func
>>>>>>        - really_probe
>>>>>>          - omap_hsmmc_probe
>>>>>>     - pm_runtime_get_sync
>>>>>>                     late_initcall_sync
>>>>>>                     - omap_device_late_init
>>>>>>                         if (od->_driver_status !=
>>>>>> BUS_NOTIFY_BOUND_DRIVER) {
>>>>>>                             if (od->_state ==
>>>>>> OMAP_DEVICE_STATE_ENABLED) {
>>>>>>                                 - omap_device_idle [ops - IP is
>>>>>> disabled, ]
>>>>>>     - [fail]
>>>>>>     - pm_runtime_put_sync
>>>>>>              - omap_hsmmc_runtime_suspend [ooops!]
>>>>>
>>>>> OK idling of unclaimed devices should not happen for deferred probe,
>>>>> it should only happen when there's no driver and no probing happening.
>>>>>
>>>>>> Lets remove just remove omap_device_late_init completely as suggested
>>>>>> by Tero Kristo:
>>>>>>
>>>>>> "How about remove omap_device_late_init call completely. I don't
>>>>>> think
>>>>>> it does anything useful at the moment; none of the omap devices get
>>>>>> enabled outside runtime_pm, so there should be no need to explicitly
>>>>>> disable the devices."
>>>>>
>>>>> I think this is still needed from PM point of view as otherwise we
>>>>> don't idle any devices that don't have a driver available. Or am I
>>>>> missing something?
>>>>>
>>>>> To me it seems the bug is relying on the BUS_NOTIFY_BOUND_DRIVER is
>>>>> not set in the deferred probe case.
>>>>>
>>>>
>>>>
>>>> What do you think about below alternative?
>>>>
>>>> diff --git a/arch/arm/mach-omap2/omap_device.c
>>>> b/arch/arm/mach-omap2/omap_device.c
>>>> index 4cb8fd9..72ebc4c 100644
>>>> --- a/arch/arm/mach-omap2/omap_device.c
>>>> +++ b/arch/arm/mach-omap2/omap_device.c
>>>> @@ -901,7 +901,8 @@ static int __init omap_device_late_idle(struct
>>>> device *dev, void *data)
>>>>                   if (od->hwmods[i]->flags & HWMOD_INIT_NO_IDLE)
>>>>                           return 0;
>>>>
>>>> -       if (od->_driver_status != BUS_NOTIFY_BOUND_DRIVER) {
>>>> +       if (od->_driver_status != BUS_NOTIFY_BOUND_DRIVER &&
>>>> +           od->_driver_status != BUS_NOTIFY_BIND_DRIVER) {
>>>>                   if (od->_state == OMAP_DEVICE_STATE_ENABLED) {
>>>>                           dev_warn(dev, "%s: enabled but no driver.
>>>> Idling\n",
>>>>                                    __func__);
>>>
>>> Seems better to me if it really fixes the issue.
>>>
>>
>> My dra7-evm failed to boot on "2b186e5 Add linux-next specific files
>> for 20150827"
>> and this change restores boot.
>>
>> Will wait for confirmation from Keerthy.
>
> I confirm that with this patch the boot crash is fixed.
>
> Tested-by: Keerthy <j-keerthy at ti.com>
>
>
> Without this patch i see this crash during boot:
>

Thanks, Keerthy.

I'll update and resend this new patch version.

-- 
regards,
-grygorii


From matthias.bgg at gmail.com  Fri Aug 28 04:32:33 2015
From: matthias.bgg at gmail.com (Matthias Brugger)
Date: Fri, 28 Aug 2015 13:32:33 +0200
Subject: [PATCH v5 2/4] Documentation: arm64/arm: dt bindings for numa.
In-Reply-To: <1439570374-4079-3-git-send-email-gkulkarni@caviumnetworks.com>
References: <1439570374-4079-1-git-send-email-gkulkarni@caviumnetworks.com>
 <1439570374-4079-3-git-send-email-gkulkarni@caviumnetworks.com>
Message-ID: <55E046D1.10001@gmail.com>

On 14/08/15 18:39, Ganapatrao Kulkarni wrote:
> DT bindings for numa map for memory, cores and IOs using
> arm,associativity device node property.
>
> Signed-off-by: Ganapatrao Kulkarni <gkulkarni at caviumnetworks.com>
> ---
>   Documentation/devicetree/bindings/arm/numa.txt | 212 +++++++++++++++++++++++++
>   1 file changed, 212 insertions(+)
>   create mode 100644 Documentation/devicetree/bindings/arm/numa.txt
>
> diff --git a/Documentation/devicetree/bindings/arm/numa.txt b/Documentation/devicetree/bindings/arm/numa.txt
> new file mode 100644
> index 0000000..dc3ef86
> --- /dev/null
> +++ b/Documentation/devicetree/bindings/arm/numa.txt
> @@ -0,0 +1,212 @@
> +==============================================================================
> +NUMA binding description.
> +==============================================================================
> +
> +==============================================================================
> +1 - Introduction
> +==============================================================================
> +
> +Systems employing a Non Uniform Memory Access (NUMA) architecture contain
> +collections of hardware resources including processors, memory, and I/O buses,
> +that comprise what is commonly known as a NUMA node.
> +Processor accesses to memory within the local NUMA node is generally faster
> +than processor accesses to memory outside of the local NUMA node.
> +DT defines interfaces that allow the platform to convey NUMA node
> +topology information to OS.
> +
> +==============================================================================
> +2 - arm,associativity
> +==============================================================================
> +The mapping is done using arm,associativity device property.
> +this property needs to be present in every device node which needs to to be
> +mapped to numa nodes.
> +
> +arm,associativity property is set of 32-bit integers which defines level of
> +topology and boundary in the system at which a significant difference in
> +performance can be measured between cross-device accesses within
> +a single location and those spanning multiple locations.
> +The first cell always contains the broadest subdivision within the system,
> +while the last cell enumerates the individual devices, such as an SMT thread
> +of a CPU, or a bus bridge within an SoC".
> +
> +ex:
> +	/* board 0, socket 0, cluster 0, core 0  thread 0 */
> +	arm,associativity = <0 0 0 0 0>;
> +
> +==============================================================================
> +3 - arm,associativity-reference-points
> +==============================================================================
> +This property is a set of 32-bit integers, each representing an index into
> +the arm,associativity nodes. The first integer is the most significant
> +NUMA boundary and the following are progressively less significant boundaries.
> +There can be more than one level of NUMA.
> +
> +Ex:
> +	arm,associativity-reference-points = <0 1>;
> +	The board Id(index 0) used first to calculate the associativity (node
> +	distance), then follows the  socket id(index 1).
> +
> +	arm,associativity-reference-points = <1 0>;
> +	The socket Id(index 1) used first to calculate the associativity,
> +	then follows the board id(index 0).
> +
> +	arm,associativity-reference-points = <0>;
> +	Only the board Id(index 0) used to calculate the associativity.
> +
> +	arm,associativity-reference-points = <1>;
> +	Only socket Id(index 1) used to calculate the associativity.
> +
> +==============================================================================
> +4 - Example dts
> +==============================================================================
> +
> +Example: 2 Node system consists of 2 boards and each board having one socket
> +and 8 core in each socket.
> +
> +	arm,associativity-reference-points = <0>;
> +
> +	memory at 00c00000 {
> +		device_type = "memory";
> +		reg = <0x0 0x00c00000 0x0 0x80000000>;
> +		/* board 0, socket 0, no specific core */
> +		arm,associativity = <0 0 0xffff>;
> +	};
> +
> +	memory at 10000000000 {
> +		device_type = "memory";
> +		reg = <0x100 0x00000000 0x0 0x80000000>;
> +		/* board 1, socket 0, no specific core */
> +		arm,associativity = <1 0 0xffff>;
> +	};
> +
> +	cpus {
> +		#address-cells = <2>;
> +		#size-cells = <0>;
> +
> +		cpu at 000 {
> +			device_type = "cpu";
> +			compatible =  "arm,armv8";
> +			reg = <0x0 0x000>;
> +			enable-method = "psci";
> +			/* board 0, socket 0, core 0*/
> +			arm,associativity = <0 0 0>;
> +		};
> +		cpu at 001 {
> +			device_type = "cpu";
> +			compatible =  "arm,armv8";
> +			reg = <0x0 0x001>;
> +			enable-method = "psci";
> +			arm,associativity = <0 0 1>;
> +		};
> +		cpu at 002 {
> +			device_type = "cpu";
> +			compatible =  "arm,armv8";
> +			reg = <0x0 0x002>;
> +			enable-method = "psci";
> +			arm,associativity = <0 0 2>;
> +		};
> +		cpu at 003 {
> +			device_type = "cpu";
> +			compatible =  "arm,armv8";
> +			reg = <0x0 0x003>;
> +			enable-method = "psci";
> +			arm,associativity = <0 0 3>;
> +		};
> +		cpu at 004 {
> +			device_type = "cpu";
> +			compatible =  "arm,armv8";
> +			reg = <0x0 0x004>;
> +			enable-method = "psci";
> +			arm,associativity = <0 0 4>;
> +		};
> +		cpu at 005 {
> +			device_type = "cpu";
> +			compatible =  "arm,armv8";
> +			reg = <0x0 0x005>;
> +			enable-method = "psci";
> +			arm,associativity = <0 0 5>;
> +		};
> +		cpu at 006 {
> +			device_type = "cpu";
> +			compatible =  "arm,armv8";
> +			reg = <0x0 0x006>;
> +			enable-method = "psci";
> +			arm,associativity = <0 0 6>;
> +		};
> +		cpu at 007 {
> +			device_type = "cpu";
> +			compatible =  "arm,armv8";
> +			reg = <0x0 0x007>;
> +			enable-method = "psci";
> +			arm,associativity = <0 0 7>;
> +		};
> +		cpu at 008 {
> +			device_type = "cpu";
> +			compatible =  "arm,armv8";
> +			reg = <0x0 0x008>;
> +			enable-method = "psci";
> +			/* board 1, socket 0, core 0*/
> +			arm,associativity = <1 0 0>;
> +		};
> +		cpu at 009 {
> +			device_type = "cpu";
> +			compatible =  "arm,armv8";
> +			reg = <0x0 0x009>;
> +			enable-method = "psci";
> +			arm,associativity = <1 0 1>;
> +		};
> +		cpu at 00a {
> +			device_type = "cpu";
> +			compatible =  "arm,armv8";
> +			reg = <0x0 0x00a>;
> +			enable-method = "psci";
> +			arm,associativity = <0 0 2>;

Nit: this should be
arm,associativity = <1 0 2>;

> +		};
> +		cpu at 00b {
> +			device_type = "cpu";
> +			compatible =  "arm,armv8";
> +			reg = <0x0 0x00b>;
> +			enable-method = "psci";
> +			arm,associativity = <1 0 3>;
> +		};
> +		cpu at 00c {
> +			device_type = "cpu";
> +			compatible =  "arm,armv8";
> +			reg = <0x0 0x00c>;
> +			enable-method = "psci";
> +			arm,associativity = <1 0 4>;
> +		};
> +		cpu at 00d {
> +			device_type = "cpu";
> +			compatible =  "arm,armv8";
> +			reg = <0x0 0x00d>;
> +			enable-method = "psci";
> +			arm,associativity = <1 0 5>;
> +		};
> +		cpu at 00e {
> +			device_type = "cpu";
> +			compatible =  "arm,armv8";
> +			reg = <0x0 0x00e>;
> +			enable-method = "psci";
> +			arm,associativity = <1 0 6>;
> +		};
> +		cpu at 00f {
> +			device_type = "cpu";
> +			compatible =  "arm,armv8";
> +			reg = <0x0 0x00f>;
> +			enable-method = "psci";
> +			arm,associativity = <1 0 7>;
> +		};
> +	};
> +
> +	pcie0: pcie0 at 0x8480,00000000 {
> +		compatible = "arm,armv8";
> +		device_type = "pci";
> +		bus-range = <0 255>;
> +		#size-cells = <2>;
> +		#address-cells = <3>;
> +		reg = <0x8480 0x00000000 0 0x10000000>;  /* Configuration space */
> +		ranges = <0x03000000 0x8010 0x00000000 0x8010 0x00000000 0x70 0x00000000>; /* mem ranges */
> +		/* board 0, socket 0, pci bus 0*/
> +		arm,associativity = <0 0 0>;
> +        };
>




From maxime.ripard at free-electrons.com  Fri Aug 28 05:28:47 2015
From: maxime.ripard at free-electrons.com (Maxime Ripard)
Date: Fri, 28 Aug 2015 14:28:47 +0200
Subject: [PATCH 0/1] ARM: dts: sun5i: inet98v_rev2 fix regulator for the
 usb wifi
In-Reply-To: <1440700651-30575-1-git-send-email-hdegoede@redhat.com>
References: <1440700651-30575-1-git-send-email-hdegoede@redhat.com>
Message-ID: <20150828122847.GH29389@lukather>

Hi Hans,

On Thu, Aug 27, 2015 at 08:37:30PM +0200, Hans de Goede wrote:
> Hi Maxime,
> 
> Here is a fixup patch for the patch adding a dts for the inet98v_rev2.
> 
> I'm not sure if you've merged the original patch yet, hence I'm sending
> this as a follow-up patch. If you've not yet merged the original patch
> feel free to squash this fix in.

Have you ever submitted that first patch in the first place?

I'm don't have the DTS file you're patching in my tree, and I don't
see any email and/or patch relating to that board.

Maxime

-- 
Maxime Ripard, Free Electrons
Embedded Linux, Kernel and Android engineering
http://free-electrons.com
-------------- next part --------------
A non-text attachment was scrubbed...
Name: signature.asc
Type: application/pgp-signature
Size: 819 bytes
Desc: Digital signature
URL: <http://lists.infradead.org/pipermail/linux-arm-kernel/attachments/20150828/5f0413b6/attachment.sig>

From maxime.ripard at free-electrons.com  Fri Aug 28 05:30:27 2015
From: maxime.ripard at free-electrons.com (Maxime Ripard)
Date: Fri, 28 Aug 2015 14:30:27 +0200
Subject: [PATCH 1/6] ARM: dts: sun6i: Add lradc node
In-Reply-To: <1440755679-8266-2-git-send-email-wens@csie.org>
References: <1440755679-8266-1-git-send-email-wens@csie.org>
 <1440755679-8266-2-git-send-email-wens@csie.org>
Message-ID: <20150828123027.GI29389@lukather>

On Fri, Aug 28, 2015 at 05:54:34PM +0800, Chen-Yu Tsai wrote:
> sun6i also has the LRADC for tablet buttons.
> 
> Signed-off-by: Chen-Yu Tsai <wens at csie.org>

Queued, thanks!

Maxime

-- 
Maxime Ripard, Free Electrons
Embedded Linux, Kernel and Android engineering
http://free-electrons.com
-------------- next part --------------
A non-text attachment was scrubbed...
Name: signature.asc
Type: application/pgp-signature
Size: 819 bytes
Desc: Digital signature
URL: <http://lists.infradead.org/pipermail/linux-arm-kernel/attachments/20150828/f253f113/attachment.sig>

From maxime.ripard at free-electrons.com  Fri Aug 28 05:31:59 2015
From: maxime.ripard at free-electrons.com (Maxime Ripard)
Date: Fri, 28 Aug 2015 14:31:59 +0200
Subject: [PATCH 2/6] ARM: dts: sunxi: Add dtsi for AXP221 PMIC
In-Reply-To: <1440755679-8266-3-git-send-email-wens@csie.org>
References: <1440755679-8266-1-git-send-email-wens@csie.org>
 <1440755679-8266-3-git-send-email-wens@csie.org>
Message-ID: <20150828123159.GJ29389@lukather>

On Fri, Aug 28, 2015 at 05:54:35PM +0800, Chen-Yu Tsai wrote:
> The AXP221 PMIC is used with some Allwinner SoCs. This patch adds
> a dtsi file listing all the regulator nodes. The regulators are
> initialized based on their device node names.
> 
> This can later be used with the AXP223 PMIC as well, which has
> the same functionality as AXP221, except for its host interface.
> 
> Signed-off-by: Chen-Yu Tsai <wens at csie.org>
> ---
>  arch/arm/boot/dts/axp221.dtsi | 148 ++++++++++++++++++++++++++++++++++++++++++
>  1 file changed, 148 insertions(+)
>  create mode 100644 arch/arm/boot/dts/axp221.dtsi
> 
> diff --git a/arch/arm/boot/dts/axp221.dtsi b/arch/arm/boot/dts/axp221.dtsi
> new file mode 100644
> index 000000000000..74836f329863
> --- /dev/null
> +++ b/arch/arm/boot/dts/axp221.dtsi
> @@ -0,0 +1,148 @@
> +/*
> + * Copyright 2015 Chen-Yu Tsai
> + *
> + * Chen-Yu Tsai <wens at csie.org>
> + *
> + * This file is dual-licensed: you can use it either under the terms
> + * of the GPL or the X11 license, at your option. Note that this dual
> + * licensing only applies to this file, and not this project as a
> + * whole.
> + *
> + *  a) This file is free software; you can redistribute it and/or
> + *     modify it under the terms of the GNU General Public License as
> + *     published by the Free Software Foundation; either version 2 of the
> + *     License, or (at your option) any later version.
> + *
> + *     This file is distributed in the hope that it will be useful,
> + *     but WITHOUT ANY WARRANTY; without even the implied warranty of
> + *     MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
> + *     GNU General Public License for more details.
> + *
> + * Or, alternatively,
> + *
> + *  b) Permission is hereby granted, free of charge, to any person
> + *     obtaining a copy of this software and associated documentation
> + *     files (the "Software"), to deal in the Software without
> + *     restriction, including without limitation the rights to use,
> + *     copy, modify, merge, publish, distribute, sublicense, and/or
> + *     sell copies of the Software, and to permit persons to whom the
> + *     Software is furnished to do so, subject to the following
> + *     conditions:
> + *
> + *     The above copyright notice and this permission notice shall be
> + *     included in all copies or substantial portions of the Software.
> + *
> + *     THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
> + *     EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES
> + *     OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
> + *     NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT
> + *     HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY,
> + *     WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
> + *     FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR
> + *     OTHER DEALINGS IN THE SOFTWARE.
> + */
> +
> +/*
> + * AXP221/221s/223 Integrated Power Management Chip
> + * http://www.x-powers.com/product/AXP22X.php
> + * http://dl.linux-sunxi.org/AXP/AXP221%20Datasheet%20V1.2%2020130326%20.pdf
> + */

I'm usually not really fond of URLs in the source code and/or the
commit logs. They tend to be broken very easily.

> +
> +&axp221 {
> +	compatible = "x-powers,axp221";
> +	interrupt-controller;
> +	#interrupt-cells = <1>;
> +
> +	regulators {
> +		/* Default work frequency for buck regulators */
> +		x-powers,dcdc-freq = <3000>;
> +
> +		/* supplies for dc1sw & dc5ldo are connected internally */
> +		dcdc1-supply = <&reg_dcdc1>;
> +		dcdc5-supply = <&reg_dcdc5>;

so the parent regulator of DCDC1 is DCDC1 ?

Maxime

-- 
Maxime Ripard, Free Electrons
Embedded Linux, Kernel and Android engineering
http://free-electrons.com
-------------- next part --------------
A non-text attachment was scrubbed...
Name: signature.asc
Type: application/pgp-signature
Size: 819 bytes
Desc: Digital signature
URL: <http://lists.infradead.org/pipermail/linux-arm-kernel/attachments/20150828/7cfabc51/attachment-0001.sig>

From mark.rutland at arm.com  Fri Aug 28 05:32:29 2015
From: mark.rutland at arm.com (Mark Rutland)
Date: Fri, 28 Aug 2015 13:32:29 +0100
Subject: [PATCH v5 2/4] Documentation: arm64/arm: dt bindings for numa.
In-Reply-To: <1439570374-4079-3-git-send-email-gkulkarni@caviumnetworks.com>
References: <1439570374-4079-1-git-send-email-gkulkarni@caviumnetworks.com>
 <1439570374-4079-3-git-send-email-gkulkarni@caviumnetworks.com>
Message-ID: <20150828123228.GE31748@leverpostej>

Hi,

On Fri, Aug 14, 2015 at 05:39:32PM +0100, Ganapatrao Kulkarni wrote:
> DT bindings for numa map for memory, cores and IOs using
> arm,associativity device node property.

Given this is just a copy of ibm,associativity, I'm not sure I see much
point in renaming the properties.

However, (somewhat counter to that) I'm also concerned that this isn't
sufficient for systems we're beginning to see today (more on that
below), so I don't think a simple copy of ibm,associativity is good
enough.

> 
> Signed-off-by: Ganapatrao Kulkarni <gkulkarni at caviumnetworks.com>
> ---
>  Documentation/devicetree/bindings/arm/numa.txt | 212 +++++++++++++++++++++++++
>  1 file changed, 212 insertions(+)
>  create mode 100644 Documentation/devicetree/bindings/arm/numa.txt
> 
> diff --git a/Documentation/devicetree/bindings/arm/numa.txt b/Documentation/devicetree/bindings/arm/numa.txt
> new file mode 100644
> index 0000000..dc3ef86
> --- /dev/null
> +++ b/Documentation/devicetree/bindings/arm/numa.txt
> @@ -0,0 +1,212 @@
> +==============================================================================
> +NUMA binding description.
> +==============================================================================
> +
> +==============================================================================
> +1 - Introduction
> +==============================================================================
> +
> +Systems employing a Non Uniform Memory Access (NUMA) architecture contain
> +collections of hardware resources including processors, memory, and I/O buses,
> +that comprise what is commonly known as a NUMA node.
> +Processor accesses to memory within the local NUMA node is generally faster
> +than processor accesses to memory outside of the local NUMA node.
> +DT defines interfaces that allow the platform to convey NUMA node
> +topology information to OS.
> +
> +==============================================================================
> +2 - arm,associativity
> +==============================================================================
> +The mapping is done using arm,associativity device property.
> +this property needs to be present in every device node which needs to to be
> +mapped to numa nodes.

Can't there be some inheritance? e.g. all devices on a bus with an
arm,associativity property being assumed to share that value?

> +
> +arm,associativity property is set of 32-bit integers which defines level of

s/set/list/ -- the order is important.

> +topology and boundary in the system at which a significant difference in
> +performance can be measured between cross-device accesses within
> +a single location and those spanning multiple locations.
> +The first cell always contains the broadest subdivision within the system,
> +while the last cell enumerates the individual devices, such as an SMT thread
> +of a CPU, or a bus bridge within an SoC".

While this gives us some hierarchy, this doesn't seem to encode relative
distances at all. That seems like an oversight.

Additionally, I'm somewhat unclear on how what you'd be expected to
provide for this property in cases like ring or mesh interconnects,
where there isn't a strict hierarchy (see systems with ARM's own CCN, or
Tilera's TILE-Mx), but there is some measure of closeness.

Must all of these have the same length? If so, why not have a
#(whatever)-cells property in the root to describe the expected length?
If not, how are they to be interpreted relative to each other?

> +
> +ex:

s/ex/Example:/, please. There's no need to contract that.

> +       /* board 0, socket 0, cluster 0, core 0  thread 0 */
> +       arm,associativity = <0 0 0 0 0>;
> +
> +==============================================================================
> +3 - arm,associativity-reference-points
> +==============================================================================
> +This property is a set of 32-bit integers, each representing an index into

Likeise, s/set/list/

> +the arm,associativity nodes. The first integer is the most significant
> +NUMA boundary and the following are progressively less significant boundaries.
> +There can be more than one level of NUMA.

I'm not clear on why this is necessary; the arm,associativity property
is already ordered from most significant to least significant per its
description.

What does this property achieve?

The description also doesn't describe where this property is expected to
live. The example isn't sufficient to disambiguate that, especially as
it seems like a trivial case.

Is this only expected at the root of the tree? Can it be re-defined in
sub-nodes?

> +
> +Ex:

s/Ex/Example:/, please

> +       arm,associativity-reference-points = <0 1>;
> +       The board Id(index 0) used first to calculate the associativity (node
> +       distance), then follows the  socket id(index 1).
> +
> +       arm,associativity-reference-points = <1 0>;
> +       The socket Id(index 1) used first to calculate the associativity,
> +       then follows the board id(index 0).
> +
> +       arm,associativity-reference-points = <0>;
> +       Only the board Id(index 0) used to calculate the associativity.
> +
> +       arm,associativity-reference-points = <1>;
> +       Only socket Id(index 1) used to calculate the associativity.
> +
> +==============================================================================
> +4 - Example dts
> +==============================================================================
> +
> +Example: 2 Node system consists of 2 boards and each board having one socket
> +and 8 core in each socket.
> +
> +       arm,associativity-reference-points = <0>;
> +
> +       memory at 00c00000 {
> +               device_type = "memory";
> +               reg = <0x0 0x00c00000 0x0 0x80000000>;
> +               /* board 0, socket 0, no specific core */
> +               arm,associativity = <0 0 0xffff>;
> +       };
> +
> +       memory at 10000000000 {
> +               device_type = "memory";
> +               reg = <0x100 0x00000000 0x0 0x80000000>;
> +               /* board 1, socket 0, no specific core */
> +               arm,associativity = <1 0 0xffff>;
> +       };
> +
> +       cpus {
> +               #address-cells = <2>;
> +               #size-cells = <0>;
> +
> +               cpu at 000 {
> +                       device_type = "cpu";
> +                       compatible =  "arm,armv8";
> +                       reg = <0x0 0x000>;
> +                       enable-method = "psci";
> +                       /* board 0, socket 0, core 0*/
> +                       arm,associativity = <0 0 0>;

We should specify w.r.t. memory and CPUs how the property is expected to
be used (e.g. in the CPU nodes rather than the cpu-map, with separate
memory nodes, etc). The generic description of arm,associativity isn't
sufficient to limit confusion there.

Thanks,
Mark.


From maxime.ripard at free-electrons.com  Fri Aug 28 05:32:45 2015
From: maxime.ripard at free-electrons.com (Maxime Ripard)
Date: Fri, 28 Aug 2015 14:32:45 +0200
Subject: [PATCH 3/6] ARM: dts: sun6i: hummingbird: Use axp221.dtsi for
 axp221 regulators
In-Reply-To: <1440755679-8266-4-git-send-email-wens@csie.org>
References: <1440755679-8266-1-git-send-email-wens@csie.org>
 <1440755679-8266-4-git-send-email-wens@csie.org>
Message-ID: <20150828123244.GK29389@lukather>

On Fri, Aug 28, 2015 at 05:54:36PM +0800, Chen-Yu Tsai wrote:
> Now that we have axp221.dtsi describing common axp22x hardware, use
> it and reference the nodes instead of declaring the whole tree.
> 
> Also add regulator reference for cpu0 supply.
> 
> Signed-off-by: Chen-Yu Tsai <wens at csie.org>
> ---
>  arch/arm/boot/dts/sun6i-a31-hummingbird.dts | 114 ++++++++++++++--------------
>  1 file changed, 56 insertions(+), 58 deletions(-)
> 
> diff --git a/arch/arm/boot/dts/sun6i-a31-hummingbird.dts b/arch/arm/boot/dts/sun6i-a31-hummingbird.dts
> index d0cfadac0691..d019cb70acec 100644
> --- a/arch/arm/boot/dts/sun6i-a31-hummingbird.dts
> +++ b/arch/arm/boot/dts/sun6i-a31-hummingbird.dts
> @@ -67,6 +67,10 @@
>  	};
>  };
>  
> +&cpu0 {
> +	cpu-supply = <&reg_dcdc2>;
> +};
> +
>  &ehci0 {
>  	status = "okay";
>  };
> @@ -119,7 +123,7 @@
>  &mmc0 {
>  	pinctrl-names = "default";
>  	pinctrl-0 = <&mmc0_pins_a>, <&mmc0_cd_pin_hummingbird>;
> -	vmmc-supply = <&vcc_3v0>;
> +	vmmc-supply = <&reg_dcdc1>;
>  	bus-width = <4>;
>  	cd-gpios = <&pio 0 8 GPIO_ACTIVE_HIGH>; /* PA8 */
>  	cd-inverted;
> @@ -134,7 +138,7 @@
>  &mmc1 {
>  	pinctrl-names = "default";
>  	pinctrl-0 = <&mmc1_pins_a>, <&wifi_reset_pin_hummingbird>;
> -	vmmc-supply = <&vcc_wifi>;
> +	vmmc-supply = <&reg_aldo1>;
>  	mmc-pwrseq = <&wifi_pwrseq>;
>  	bus-width = <4>;
>  	non-removable;
> @@ -169,65 +173,59 @@
>  		reg = <0x68>;
>  		interrupt-parent = <&nmi_intc>;
>  		interrupts = <0 IRQ_TYPE_LEVEL_LOW>;
> -		interrupt-controller;
> -		#interrupt-cells = <1>;
> -		dcdc1-supply = <&vcc_3v0>;
> -		dcdc5-supply = <&vcc_dram>;
> -
> -		regulators {
> -			x-powers,dcdc-freq = <3000>;
> -
> -			vcc_3v0: dcdc1 {
> -				regulator-always-on;
> -				regulator-min-microvolt = <3000000>;
> -				regulator-max-microvolt = <3000000>;
> -				regulator-name = "vcc-3v0";
> -			};
> -
> -			vdd_cpu: dcdc2 {
> -				regulator-always-on;
> -				regulator-min-microvolt = <700000>;
> -				regulator-max-microvolt = <1320000>;
> -				regulator-name = "vdd-cpu";
> -			};
> -
> -			vdd_gpu: dcdc3 {
> -				regulator-always-on;
> -				regulator-min-microvolt = <700000>;
> -				regulator-max-microvolt = <1320000>;
> -				regulator-name = "vdd-gpu";
> -			};
> -
> -			vdd_sys_dll: dcdc4 {
> -				regulator-always-on;
> -				regulator-min-microvolt = <1100000>;
> -				regulator-max-microvolt = <1100000>;
> -				regulator-name = "vdd-sys-dll";
> -			};
> -
> -			vcc_dram: dcdc5 {
> -				regulator-always-on;
> -				regulator-min-microvolt = <1500000>;
> -				regulator-max-microvolt = <1500000>;
> -				regulator-name = "vcc-dram";
> -			};
> -
> -			vcc_wifi: aldo1 {
> -				regulator-min-microvolt = <3300000>;
> -				regulator-max-microvolt = <3300000>;
> -				regulator-name = "vcc_wifi";
> -			};
> -
> -			avcc: aldo3 {
> -				regulator-always-on;
> -				regulator-min-microvolt = <3000000>;
> -				regulator-max-microvolt = <3000000>;
> -				regulator-name = "avcc";
> -			};
> -		};
>  	};
>  };
>  
> +#include "axp221.dtsi"
> +
> +&reg_aldo1 {
> +	regulator-min-microvolt = <3300000>;
> +	regulator-max-microvolt = <3300000>;
> +	regulator-name = "vcc-wifi";
> +};
> +
> +&reg_aldo3 {
> +	regulator-always-on;
> +	regulator-min-microvolt = <3000000>;
> +	regulator-max-microvolt = <3000000>;
> +	regulator-name = "avcc";
> +};
> +
> +&reg_dcdc1 {
> +	regulator-always-on;
> +	regulator-min-microvolt = <3000000>;
> +	regulator-max-microvolt = <3000000>;
> +	regulator-name = "vcc-3v0";
> +};
> +
> +&reg_dcdc2 {
> +	regulator-always-on;
> +	regulator-min-microvolt = <700000>;
> +	regulator-max-microvolt = <1320000>;
> +	regulator-name = "vdd-cpu";
> +};
> +
> +&reg_dcdc3 {
> +	regulator-always-on;
> +	regulator-min-microvolt = <700000>;
> +	regulator-max-microvolt = <1320000>;
> +	regulator-name = "vdd-gpu";
> +};

I'm know it's just a mechanical change from your part, but is the GPU
regulator really need to be always on?

Maxime

-- 
Maxime Ripard, Free Electrons
Embedded Linux, Kernel and Android engineering
http://free-electrons.com
-------------- next part --------------
A non-text attachment was scrubbed...
Name: signature.asc
Type: application/pgp-signature
Size: 819 bytes
Desc: Digital signature
URL: <http://lists.infradead.org/pipermail/linux-arm-kernel/attachments/20150828/bda2fc3c/attachment.sig>

From maxime.ripard at free-electrons.com  Fri Aug 28 05:33:04 2015
From: maxime.ripard at free-electrons.com (Maxime Ripard)
Date: Fri, 28 Aug 2015 14:33:04 +0200
Subject: [PATCH 4/6] ARM: dts: sun6i: Add mmc2 pins for 8 bit emmc
In-Reply-To: <1440755679-8266-5-git-send-email-wens@csie.org>
References: <1440755679-8266-1-git-send-email-wens@csie.org>
 <1440755679-8266-5-git-send-email-wens@csie.org>
Message-ID: <20150828123304.GL29389@lukather>

On Fri, Aug 28, 2015 at 05:54:37PM +0800, Chen-Yu Tsai wrote:
> This also includes the reset pin for emmc.
> 
> Signed-off-by: Chen-Yu Tsai <wens at csie.org>

Queued, thanks!

Maxime

-- 
Maxime Ripard, Free Electrons
Embedded Linux, Kernel and Android engineering
http://free-electrons.com
-------------- next part --------------
A non-text attachment was scrubbed...
Name: signature.asc
Type: application/pgp-signature
Size: 819 bytes
Desc: Digital signature
URL: <http://lists.infradead.org/pipermail/linux-arm-kernel/attachments/20150828/9f216db1/attachment.sig>

From maxime.ripard at free-electrons.com  Fri Aug 28 05:34:43 2015
From: maxime.ripard at free-electrons.com (Maxime Ripard)
Date: Fri, 28 Aug 2015 14:34:43 +0200
Subject: [PATCH 5/6] ARM: dts: sun6i: Add support for Sinlinx A31s SDK
 board
In-Reply-To: <1440755679-8266-6-git-send-email-wens@csie.org>
References: <1440755679-8266-1-git-send-email-wens@csie.org>
 <1440755679-8266-6-git-send-email-wens@csie.org>
Message-ID: <20150828123443.GM29389@lukather>

On Fri, Aug 28, 2015 at 05:54:38PM +0800, Chen-Yu Tsai wrote:
> The Sinlinx A31s SDK is a A31s based module/baseboard development kit.
> 
> The core module has the SoC, PMIC, DRAM, eMMC and supporting components.
> There are also pads for UART0, JTAG and I2S.

Can you use that core module without that baseboard?

> The baseboard has 100 Mbps Ethernet, 5x USB 2.0 host ports via a USB 2.0
> hub chip, MMC, HDMI, SPDIF, CIR, audio jacks, 2 tablet-like volume
> buttons, RS232 style UART and USB OTG (though VBUS is not connected).
> Various headers are available for other addon modules, such as SDIO
> WiFi, LCD display, camera sensor, UARTs, I2C, SPI and GPIOs.

Can the baseboard be used with our core modules?

Thanks,
Maxime

-- 
Maxime Ripard, Free Electrons
Embedded Linux, Kernel and Android engineering
http://free-electrons.com
-------------- next part --------------
A non-text attachment was scrubbed...
Name: signature.asc
Type: application/pgp-signature
Size: 819 bytes
Desc: Digital signature
URL: <http://lists.infradead.org/pipermail/linux-arm-kernel/attachments/20150828/d55d427f/attachment.sig>

From maxime.ripard at free-electrons.com  Fri Aug 28 05:38:05 2015
From: maxime.ripard at free-electrons.com (Maxime Ripard)
Date: Fri, 28 Aug 2015 14:38:05 +0200
Subject: [PATCH 6/6] ARM: dts: sun6i: Add dts file for MSI Primo81 tablet
In-Reply-To: <1440755679-8266-7-git-send-email-wens@csie.org>
References: <1440755679-8266-1-git-send-email-wens@csie.org>
 <1440755679-8266-7-git-send-email-wens@csie.org>
Message-ID: <20150828123805.GN29389@lukather>

On Fri, Aug 28, 2015 at 05:54:39PM +0800, Chen-Yu Tsai wrote:
> From: Karsten Merker <merker at debian.org>
> 
> The MSI Primo81 is an A31s based tablet, with 1G RAM, 16G NAND,
> 768x1024 IPS LCD display, mono speaker, 0.3 MP front camera, 2.0 MP
> rear camera, 3500 mAh battery, gt911 touchscreen, mma8452 accelerometer
> and rtl8188etv usb wifi. Has "power", "volume+" and "volume-" buttons
> (both volume buttons are also connected to the UBOOT_SEL pin). The
> external connectors are represented by MicroSD slot, MiniHDMI, MicroUSB
> OTG and 3.5mm headphone jack. More details are available at
> 
>     http://linux-sunxi.org/MSI_Primo81

Again, not a huge fan of the commit logs URL... This commit log is
already fine without it.

> 
> USB OTG is enabled in host only mode. AXP221 USB power supply and
> GPIO support are required for full USB OTG support.
> 
> Signed-off-by: Siarhei Siamashka <siarhei.siamashka at gmail.com>
> Signed-off-by: Karsten Merker <merker at debian.org>
> Signed-off-by: Chen-Yu Tsai <wens at csie.org>
> ---
> 
> Changes since v4:
> 
>   - Use axp221.dtsi and add all active regulators.
>   - Enable i2c controllers for capacitive touch panel and accelerometer.
>   - Mark i2c controller for camera sensors as failed for now.
>   - Enable USB OTG in host only mode.
>   - Drop uart0 as this is not tested.
>   - s/library/file/ in GPL header.
> 
> ---
>  arch/arm/boot/dts/Makefile               |   1 +
>  arch/arm/boot/dts/sun6i-a31s-primo81.dts | 255 +++++++++++++++++++++++++++++++
>  2 files changed, 256 insertions(+)
>  create mode 100644 arch/arm/boot/dts/sun6i-a31s-primo81.dts
> 
> diff --git a/arch/arm/boot/dts/Makefile b/arch/arm/boot/dts/Makefile
> index ada5156fdd49..c87513ed4eb4 100644
> --- a/arch/arm/boot/dts/Makefile
> +++ b/arch/arm/boot/dts/Makefile
> @@ -579,6 +579,7 @@ dtb-$(CONFIG_MACH_SUN6I) += \
>  	sun6i-a31-m9.dtb \
>  	sun6i-a31-mele-a1000g-quad.dtb \
>  	sun6i-a31s-cs908.dtb \
> +	sun6i-a31s-primo81.dtb \
>  	sun6i-a31s-sina31s.dtb
>  dtb-$(CONFIG_MACH_SUN7I) += \
>  	sun7i-a20-bananapi.dtb \
> diff --git a/arch/arm/boot/dts/sun6i-a31s-primo81.dts b/arch/arm/boot/dts/sun6i-a31s-primo81.dts
> new file mode 100644
> index 000000000000..d22befaf363b
> --- /dev/null
> +++ b/arch/arm/boot/dts/sun6i-a31s-primo81.dts
> @@ -0,0 +1,255 @@
> +/*
> + * Copyright 2014 Siarhei Siamashka <siarhei.siamashka at gmail.com>
> + * Copyright 2015 Karsten Merker <merker at debian.org>
> + * Copyright 2015 Chen-Yu Tsai <wens at csie.org>
> + *
> + * This file is dual-licensed: you can use it either under the terms
> + * of the GPL or the X11 license, at your option. Note that this dual
> + * licensing only applies to this file, and not this project as a
> + * whole.
> + *
> + *  a) This file is free software; you can redistribute it and/or
> + *     modify it under the terms of the GNU General Public License as
> + *     published by the Free Software Foundation; either version 2 of the
> + *     License, or (at your option) any later version.
> + *
> + *     This file is distributed in the hope that it will be useful,
> + *     but WITHOUT ANY WARRANTY; without even the implied warranty of
> + *     MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
> + *     GNU General Public License for more details.
> + *
> + * Or, alternatively,
> + *
> + *  b) Permission is hereby granted, free of charge, to any person
> + *     obtaining a copy of this software and associated documentation
> + *     files (the "Software"), to deal in the Software without
> + *     restriction, including without limitation the rights to use,
> + *     copy, modify, merge, publish, distribute, sublicense, and/or
> + *     sell copies of the Software, and to permit persons to whom the
> + *     Software is furnished to do so, subject to the following
> + *     conditions:
> + *
> + *     The above copyright notice and this permission notice shall be
> + *     included in all copies or substantial portions of the Software.
> + *
> + *     THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
> + *     EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES
> + *     OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
> + *     NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT
> + *     HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY,
> + *     WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
> + *     FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR
> + *     OTHER DEALINGS IN THE SOFTWARE.
> + */
> +
> +/dts-v1/;
> +#include "sun6i-a31s.dtsi"
> +#include "sunxi-common-regulators.dtsi"
> +
> +#include <dt-bindings/gpio/gpio.h>
> +#include <dt-bindings/input/input.h>
> +#include <dt-bindings/pinctrl/sun4i-a10.h>
> +
> +/ {
> +	model = "MSI Primo81 tablet";
> +	compatible = "msi,primo81", "allwinner,sun6i-a31s";
> +};
> +
> +&cpu0 {
> +	cpu-supply = <&reg_dcdc2>;
> +};
> +
> +&ehci0 {
> +	/* rtl8188etv wifi is connected here */
> +	status = "okay";
> +};
> +
> +&i2c0 {
> +	pinctrl-names = "default";
> +	pinctrl-0 = <&i2c0_pins_a>;
> +	/* pull-ups and device VDDIO require AXP221 DLDO3 */

Now that we have AXP221, that can probably be solved, right?

> +	status = "failed";
> +};
> +
> +&i2c1 {
> +	pinctrl-names = "default";
> +	pinctrl-0 = <&i2c1_pins_a>;
> +	status = "okay";
> +
> +	ctp at 5d {
> +		pinctrl-names = "default";
> +		pinctrl-0 = <&gt911_int_primo81>;
> +		compatible = "goodix,gt911";
> +		reg = <0x5d>;
> +		interrupt-parent = <&pio>;
> +		interrupts = <0 3 IRQ_TYPE_LEVEL_HIGH>; /* PA3 */
> +		/*
> +		 * The default 0,0 coordinate is at the corner closest to
> +		 * the headphone jack. X goes along the long side, while
> +		 * Y goes along the short side.
> +		 */

I'm not exactly sure what that comment is supposed to be for...

> +	};
> +};
> +
> +&i2c2 {
> +	pinctrl-names = "default";
> +	pinctrl-0 = <&i2c2_pins_a>;
> +	status = "okay";
> +
> +	accelerometer at 1c {
> +		pinctrl-names = "default";
> +		pinctrl-0 = <&mma8452_int_primo81>;
> +		compatible = "fsl,mma8452";
> +		reg = <0x1c>;
> +		interrupt-parent = <&pio>;
> +		interrupts = <0 9 IRQ_TYPE_LEVEL_HIGH>; /* PA9 */
> +		#io-channel-cells = <1>;
> +	};
> +};
> +
> +&lradc {
> +	vref-supply = <&reg_aldo3>;
> +	status = "okay";
> +
> +	button at 158 {
> +		label = "Volume Up";
> +		linux,code = <KEY_VOLUMEUP>;
> +		channel = <0>;
> +		voltage = <158730>;
> +	};
> +
> +	button at 349 {
> +		label = "Volume Down";
> +		linux,code = <KEY_VOLUMEDOWN>;
> +		channel = <0>;
> +		voltage = <349206>;
> +	};
> +};
> +
> +&mmc0 {
> +	pinctrl-names = "default";
> +	pinctrl-0 = <&mmc0_pins_a>, <&mmc0_cd_pin_primo81>;
> +	vmmc-supply = <&reg_dcdc1>;
> +	bus-width = <4>;
> +	cd-gpios = <&pio 0 8 GPIO_ACTIVE_HIGH>; /* PA8 */
> +	cd-inverted;
> +	status = "okay";
> +};
> +
> +&pio {
> +	gt911_int_primo81: gt911_int_pin at 0 {
> +		allwinner,pins = "PA3";
> +		allwinner,function = "gpio_in";
> +		allwinner,drive = <SUN4I_PINCTRL_10_MA>;
> +		allwinner,pull = <SUN4I_PINCTRL_NO_PULL>;
> +	};
> +
> +	mma8452_int_primo81: mma8452_int_pin at 0 {
> +		allwinner,pins = "PA9";
> +		allwinner,function = "gpio_in";
> +		allwinner,drive = <SUN4I_PINCTRL_10_MA>;
> +		allwinner,pull = <SUN4I_PINCTRL_PULL_UP>;
> +	};
> +
> +	mmc0_cd_pin_primo81: mmc0_cd_pin at 0 {
> +		allwinner,pins = "PA8";
> +		allwinner,function = "gpio_in";
> +		allwinner,drive = <SUN4I_PINCTRL_10_MA>;
> +		allwinner,pull = <SUN4I_PINCTRL_PULL_UP>;
> +	};
> +};
> +
> +&p2wi {
> +	status = "okay";
> +
> +	axp221: pmic at 68 {
> +		compatible = "x-powers,axp221";
> +		reg = <0x68>;
> +		interrupt-parent = <&nmi_intc>;
> +		interrupts = <0 IRQ_TYPE_LEVEL_LOW>;
> +	};
> +};
> +
> +#include "axp221.dtsi"
> +
> +&reg_dcdc1 {
> +	regulator-always-on;
> +	regulator-min-microvolt = <3000000>;
> +	regulator-max-microvolt = <3000000>;
> +	regulator-name = "vcc-3v0";
> +};
> +
> +&reg_dcdc2 {
> +	regulator-always-on;
> +	regulator-min-microvolt = <700000>;
> +	regulator-max-microvolt = <1320000>;
> +	regulator-name = "vdd-cpu";
> +};
> +
> +&reg_dcdc3 {
> +	regulator-always-on;
> +	regulator-min-microvolt = <700000>;
> +	regulator-max-microvolt = <1320000>;
> +	regulator-name = "vdd-gpu";
> +};

The GPU regulator can probably be disabled...

> +&reg_dcdc4 {
> +	regulator-always-on;
> +	regulator-min-microvolt = <1240000>;
> +	regulator-max-microvolt = <1240000>;
> +	regulator-name = "vdd-sys-dll";
> +};
> +
> +&reg_dcdc5 {
> +	regulator-always-on;
> +	regulator-min-microvolt = <1500000>;
> +	regulator-max-microvolt = <1500000>;
> +	regulator-name = "vcc-dram";
> +};
> +
> +&reg_aldo3 {
> +	regulator-always-on;
> +	regulator-min-microvolt = <3000000>;
> +	regulator-max-microvolt = <3000000>;
> +	regulator-name = "avcc";
> +};
> +
> +&reg_dldo1 {
> +	regulator-min-microvolt = <3300000>;
> +	regulator-max-microvolt = <3300000>;
> +	regulator-name = "vcc-wifi";
> +};
> +
> +&reg_eldo3 {
> +	regulator-always-on;
> +	regulator-min-microvolt = <1200000>;
> +	regulator-max-microvolt = <1200000>;
> +	regulator-name = "vcc-mipi-bridge";
> +	/* This is used by simplefb LCD display. Add regulator support? */
> +};
> +
> +&reg_dc1sw {
> +	regulator-always-on;
> +	regulator-min-microvolt = <3000000>;
> +	regulator-max-microvolt = <3000000>;
> +	regulator-name = "vcc-lcd";
> +	/* This is used by simplefb LCD display. Add regulator support? */

Yes.

Thanks,
Maxime

-- 
Maxime Ripard, Free Electrons
Embedded Linux, Kernel and Android engineering
http://free-electrons.com
-------------- next part --------------
A non-text attachment was scrubbed...
Name: signature.asc
Type: application/pgp-signature
Size: 819 bytes
Desc: Digital signature
URL: <http://lists.infradead.org/pipermail/linux-arm-kernel/attachments/20150828/40b50101/attachment-0001.sig>

From luis at debethencourt.com  Fri Aug 28 05:42:22 2015
From: luis at debethencourt.com (Luis de Bethencourt)
Date: Fri, 28 Aug 2015 14:42:22 +0200
Subject: [PATCH 0/5] clk: sunxi: Fix module autoload for OF platform driver
Message-ID: <20150828124222.GA24923@goodgumbo.baconseed.org>

Hello,

This series add the missing MODULE_DEVICE_TABLE() for OF to eport
that information so modules have the correct aliases built-in
and autoloading works correctly.

A longer explanation by Javier Canillas can be found here:
https://lkml.org/lkml/2015/7/30/519

Thanks,
Luis

Luis de Bethencourt (5)
  clk: sunxi: sun9i-mmc: Fix module autoload for OF platform driver
  clk: sunxi: sun8i-apb0: Fix module autoload for OF platform driver
  clk: sunxi: sun6i-ar100: Fix module autoload for OF platform driver
  clk: sunxi: sun6i-apb0-gates: Fix module autoload for OF platform driver
  clk: sunxi: sun6i-apb0: Fix module autoload for OF platform driver
 drivers/clk/sunxi/clk-sun6i-apb0-gates.c | 1 +
 drivers/clk/sunxi/clk-sun6i-apb0.c       | 1 +
 drivers/clk/sunxi/clk-sun6i-ar100.c      | 1 +
 drivers/clk/sunxi/clk-sun8i-apb0.c       | 1 +
 drivers/clk/sunxi/clk-sun9i-mmc.c        | 1 +
 5 files changed, 5 insertions(+)

--
2.4.6


From marcel.ziswiler at toradex.com  Fri Aug 28 05:42:31 2015
From: marcel.ziswiler at toradex.com (Marcel Ziswiler)
Date: Fri, 28 Aug 2015 14:42:31 +0200
Subject: [PATCH 4/9] arm: tegra: apalis_t30: add comment concerning emmc
In-Reply-To: <1440765756-1382-1-git-send-email-marcel.ziswiler@toradex.com>
References: <1440765756-1382-1-git-send-email-marcel.ziswiler@toradex.com>
Message-ID: <1440765756-1382-5-git-send-email-marcel.ziswiler@toradex.com>

Instead of adding an otherwise unused emmc label just add a comment.

Signed-off-by: Marcel Ziswiler <marcel.ziswiler at toradex.com>
---

 arch/arm/boot/dts/tegra30-apalis.dtsi | 1 +
 1 file changed, 1 insertion(+)

diff --git a/arch/arm/boot/dts/tegra30-apalis.dtsi b/arch/arm/boot/dts/tegra30-apalis.dtsi
index 84744dc..d1b24b1 100644
--- a/arch/arm/boot/dts/tegra30-apalis.dtsi
+++ b/arch/arm/boot/dts/tegra30-apalis.dtsi
@@ -636,6 +636,7 @@
 		nvidia,sys-clock-req-active-high;
 	};
 
+	/* eMMC */
 	sdhci at 78000600 {
 		status = "okay";
 		bus-width = <8>;
-- 
2.4.3



From marcel.ziswiler at toradex.com  Fri Aug 28 05:42:28 2015
From: marcel.ziswiler at toradex.com (Marcel Ziswiler)
Date: Fri, 28 Aug 2015 14:42:28 +0200
Subject: [PATCH 1/9] arm: tegra: apalis_t30: update hardware revisions
 compatibility comment
In-Reply-To: <1440765756-1382-1-git-send-email-marcel.ziswiler@toradex.com>
References: <1440765756-1382-1-git-send-email-marcel.ziswiler@toradex.com>
Message-ID: <1440765756-1382-2-git-send-email-marcel.ziswiler@toradex.com>

Update introductory comment about what exact hardware revisions this
device tree is compatible with as a hint for our customers.

Signed-off-by: Marcel Ziswiler <marcel.ziswiler at toradex.com>
---

 arch/arm/boot/dts/tegra30-apalis.dtsi | 5 +++--
 1 file changed, 3 insertions(+), 2 deletions(-)

diff --git a/arch/arm/boot/dts/tegra30-apalis.dtsi b/arch/arm/boot/dts/tegra30-apalis.dtsi
index a5446cb..3bff4d7 100644
--- a/arch/arm/boot/dts/tegra30-apalis.dtsi
+++ b/arch/arm/boot/dts/tegra30-apalis.dtsi
@@ -1,8 +1,9 @@
 #include "tegra30.dtsi"
 
 /*
- * Toradex Apalis T30 Device Tree
- * Compatible for Revisions 1GB: V1.0A; 2GB: V1.0B, V1.0C
+ * Toradex Apalis T30 Module Device Tree
+ * Compatible for Revisions 1GB: V1.0A, V1.1A; 1GB IT: V1.1A;
+ * 2GB: V1.0B, V1.0C, V1.0E, V1.1A
  */
 / {
 	model = "Toradex Apalis T30";
-- 
2.4.3



From luis at debethencourt.com  Fri Aug 28 05:43:14 2015
From: luis at debethencourt.com (Luis de Bethencourt)
Date: Fri, 28 Aug 2015 14:43:14 +0200
Subject: [PATCH 1/5] clk: sunxi: sun6i-apb0: Fix module autoload for OF
 platform driver
Message-ID: <20150828124314.GA26550@goodgumbo.baconseed.org>

This platform driver has a OF device ID table but the OF module
alias information is not created so module autoloading won't work.

Signed-off-by: Luis de Bethencourt <luis at debethencourt.com>
---
 drivers/clk/sunxi/clk-sun6i-apb0.c | 1 +
 1 file changed, 1 insertion(+)

diff --git a/drivers/clk/sunxi/clk-sun6i-apb0.c b/drivers/clk/sunxi/clk-sun6i-apb0.c
index 7076360..e703e18 100644
--- a/drivers/clk/sunxi/clk-sun6i-apb0.c
+++ b/drivers/clk/sunxi/clk-sun6i-apb0.c
@@ -61,6 +61,7 @@ static const struct of_device_id sun6i_a31_apb0_clk_dt_ids[] = {
 	{ .compatible = "allwinner,sun6i-a31-apb0-clk" },
 	{ /* sentinel */ }
 };
+MODULE_DEVICE_TABLE(of, sun6i_a31_apb0_clk_dt_ids);
 
 static struct platform_driver sun6i_a31_apb0_clk_driver = {
 	.driver = {
-- 
2.4.6



From marcel.ziswiler at toradex.com  Fri Aug 28 05:42:32 2015
From: marcel.ziswiler at toradex.com (Marcel Ziswiler)
Date: Fri, 28 Aug 2015 14:42:32 +0200
Subject: [PATCH 5/9] arm: tegra: apalis_t30: add digital audio pin muxing
In-Reply-To: <1440765756-1382-1-git-send-email-marcel.ziswiler@toradex.com>
References: <1440765756-1382-1-git-send-email-marcel.ziswiler@toradex.com>
Message-ID: <1440765756-1382-6-git-send-email-marcel.ziswiler@toradex.com>

Add Apalis digital audio pin muxing which is e.g. used for HDA
operation together with the Realtek HDA codec as found on the Apalis
Evaluation board.

Signed-off-by: Marcel Ziswiler <marcel.ziswiler at toradex.com>
---

 arch/arm/boot/dts/tegra30-apalis.dtsi | 24 ++++++++++++++++++++++++
 1 file changed, 24 insertions(+)

diff --git a/arch/arm/boot/dts/tegra30-apalis.dtsi b/arch/arm/boot/dts/tegra30-apalis.dtsi
index d1b24b1..4a6ca38 100644
--- a/arch/arm/boot/dts/tegra30-apalis.dtsi
+++ b/arch/arm/boot/dts/tegra30-apalis.dtsi
@@ -109,6 +109,30 @@
 				nvidia,enable-input = <TEGRA_PIN_ENABLE>;
 			};
 
+			/* Apalis Digital Audio */
+			clk1_req_pee2 {
+				nvidia,pins =	"clk1_req_pee2";
+				nvidia,function = "hda";
+				nvidia,pull = <TEGRA_PIN_PULL_NONE>;
+				nvidia,tristate = <TEGRA_PIN_DISABLE>;
+			};
+			clk2_out_pw5 {
+				nvidia,pins = "clk2_out_pw5";
+				nvidia,function = "extperiph2";
+				nvidia,pull = <TEGRA_PIN_PULL_NONE>;
+				nvidia,tristate = <TEGRA_PIN_DISABLE>;
+				nvidia,enable-input = <TEGRA_PIN_DISABLE>;
+			};
+			dap1_fs_pn0 {
+				nvidia,pins =	"dap1_fs_pn0",
+						"dap1_din_pn1",
+						"dap1_dout_pn2",
+						"dap1_sclk_pn3";
+				nvidia,function = "hda";
+				nvidia,pull = <TEGRA_PIN_PULL_NONE>;
+				nvidia,tristate = <TEGRA_PIN_DISABLE>;
+			};
+
 			/* Apalis I2C3 */
 			cam_i2c_scl_pbb1 {
 				nvidia,pins = "cam_i2c_scl_pbb1",
-- 
2.4.3



From marcel.ziswiler at toradex.com  Fri Aug 28 05:42:35 2015
From: marcel.ziswiler at toradex.com (Marcel Ziswiler)
Date: Fri, 28 Aug 2015 14:42:35 +0200
Subject: [PATCH 8/9] arm: tegra: apalis_t30: fix backlight pwm comment for
 eval board
In-Reply-To: <1440765756-1382-1-git-send-email-marcel.ziswiler@toradex.com>
References: <1440765756-1382-1-git-send-email-marcel.ziswiler@toradex.com>
Message-ID: <1440765756-1382-9-git-send-email-marcel.ziswiler@toradex.com>

Fix the backlight PWM comment as it is actually called PWM_BKL1 rather
than just PWM0.

Signed-off-by: Marcel Ziswiler <marcel.ziswiler at toradex.com>
---

 arch/arm/boot/dts/tegra30-apalis-eval.dts | 2 +-
 1 file changed, 1 insertion(+), 1 deletion(-)

diff --git a/arch/arm/boot/dts/tegra30-apalis-eval.dts b/arch/arm/boot/dts/tegra30-apalis-eval.dts
index 37437c6..c832c15 100644
--- a/arch/arm/boot/dts/tegra30-apalis-eval.dts
+++ b/arch/arm/boot/dts/tegra30-apalis-eval.dts
@@ -180,7 +180,7 @@
 	backlight: backlight {
 		compatible = "pwm-backlight";
 
-		/* PWM0 */
+		/* PWM_BKL1 */
 		pwms = <&pwm 0 5000000>;
 		brightness-levels = <255 231 223 207 191 159 127 0>;
 		default-brightness-level = <6>;
-- 
2.4.3



From marcel.ziswiler at toradex.com  Fri Aug 28 05:42:29 2015
From: marcel.ziswiler at toradex.com (Marcel Ziswiler)
Date: Fri, 28 Aug 2015 14:42:29 +0200
Subject: [PATCH 2/9] arm: tegra: apalis_t30: fix hdmi supply
In-Reply-To: <1440765756-1382-1-git-send-email-marcel.ziswiler@toradex.com>
References: <1440765756-1382-1-git-send-email-marcel.ziswiler@toradex.com>
Message-ID: <1440765756-1382-3-git-send-email-marcel.ziswiler@toradex.com>

Fix HDMI supplies (both regular VDD as well as PLL ones) being switched
by the TPS65911 PMIC's GPIO6 aka EN_VDD_HDMI by introducing two new
GPIO switched fixed regulators avdd_hdmi_pll_1v8_reg and
avdd_hdmi_3v3_reg.

Signed-off-by: Marcel Ziswiler <marcel.ziswiler at toradex.com>
---

 arch/arm/boot/dts/tegra30-apalis.dtsi | 32 +++++++++++++++++++++++++++-----
 1 file changed, 27 insertions(+), 5 deletions(-)

diff --git a/arch/arm/boot/dts/tegra30-apalis.dtsi b/arch/arm/boot/dts/tegra30-apalis.dtsi
index 3bff4d7..fd6c94e 100644
--- a/arch/arm/boot/dts/tegra30-apalis.dtsi
+++ b/arch/arm/boot/dts/tegra30-apalis.dtsi
@@ -34,8 +34,8 @@
 
 	host1x at 50000000 {
 		hdmi at 54280000 {
-			vdd-supply = <&sys_3v3_reg>;
-			pll-supply = <&vio_reg>;
+			vdd-supply = <&avdd_hdmi_3v3_reg>;
+			pll-supply = <&avdd_hdmi_pll_1v8_reg>;
 
 			nvidia,hpd-gpio =
 				<&gpio TEGRA_GPIO(N, 7) GPIO_ACTIVE_HIGH>;
@@ -667,18 +667,40 @@
 		#address-cells = <1>;
 		#size-cells = <0>;
 
-		sys_3v3_reg: regulator at 100 {
+		avdd_hdmi_pll_1v8_reg: regulator at 100 {
 			compatible = "regulator-fixed";
 			reg = <100>;
+			regulator-name = "+V1.8_AVDD_HDMI_PLL";
+			regulator-min-microvolt = <1800000>;
+			regulator-max-microvolt = <1800000>;
+			enable-active-high;
+			gpio = <&pmic 6 GPIO_ACTIVE_HIGH>;
+			vin-supply = <&vio_reg>;
+		};
+
+		sys_3v3_reg: regulator at 101 {
+			compatible = "regulator-fixed";
+			reg = <101>;
 			regulator-name = "3v3";
 			regulator-min-microvolt = <3300000>;
 			regulator-max-microvolt = <3300000>;
 			regulator-always-on;
 		};
 
-		charge_pump_5v0_reg: regulator at 101 {
+		avdd_hdmi_3v3_reg: regulator at 102 {
 			compatible = "regulator-fixed";
-			reg = <101>;
+			reg = <102>;
+			regulator-name = "+V3.3_AVDD_HDMI";
+			regulator-min-microvolt = <3300000>;
+			regulator-max-microvolt = <3300000>;
+			enable-active-high;
+			gpio = <&pmic 6 GPIO_ACTIVE_HIGH>;
+			vin-supply = <&sys_3v3_reg>;
+		};
+
+		charge_pump_5v0_reg: regulator at 103 {
+			compatible = "regulator-fixed";
+			reg = <103>;
 			regulator-name = "5v0";
 			regulator-min-microvolt = <5000000>;
 			regulator-max-microvolt = <5000000>;
-- 
2.4.3



From luis at debethencourt.com  Fri Aug 28 05:43:33 2015
From: luis at debethencourt.com (Luis de Bethencourt)
Date: Fri, 28 Aug 2015 14:43:33 +0200
Subject: [PATCH 2/5] clk: sunxi: sun6i-apb0-gates: Fix module autoload for OF
 platform driver
Message-ID: <20150828124333.GA26601@goodgumbo.baconseed.org>

This platform driver has a OF device ID table but the OF module
alias information is not created so module autoloading won't work.

Signed-off-by: Luis de Bethencourt <luis at debethencourt.com>
---
 drivers/clk/sunxi/clk-sun6i-apb0-gates.c | 1 +
 1 file changed, 1 insertion(+)

diff --git a/drivers/clk/sunxi/clk-sun6i-apb0-gates.c b/drivers/clk/sunxi/clk-sun6i-apb0-gates.c
index 64f3e46..23d042a 100644
--- a/drivers/clk/sunxi/clk-sun6i-apb0-gates.c
+++ b/drivers/clk/sunxi/clk-sun6i-apb0-gates.c
@@ -34,6 +34,7 @@ static const struct of_device_id sun6i_a31_apb0_gates_clk_dt_ids[] = {
 	{ .compatible = "allwinner,sun8i-a23-apb0-gates-clk", .data = &sun8i_a23_apb0_gates },
 	{ /* sentinel */ }
 };
+MODULE_DEVICE_TABLE(of, sun6i_a31_apb0_gates_clk_dt_ids);
 
 static int sun6i_a31_apb0_gates_clk_probe(struct platform_device *pdev)
 {
-- 
2.4.6



From marcel.ziswiler at toradex.com  Fri Aug 28 05:42:36 2015
From: marcel.ziswiler at toradex.com (Marcel Ziswiler)
Date: Fri, 28 Aug 2015 14:42:36 +0200
Subject: [PATCH 9/9] arm: tegra: apalis_t30: fix power/wakeup key for eval
 board
In-Reply-To: <1440765756-1382-1-git-send-email-marcel.ziswiler@toradex.com>
References: <1440765756-1382-1-git-send-email-marcel.ziswiler@toradex.com>
Message-ID: <1440765756-1382-10-git-send-email-marcel.ziswiler@toradex.com>

Rather than a power key WAKE1_MICO is actually a standard Apalis MXM3
pin used for wake-up purpose which this patch fixes.

Signed-off-by: Marcel Ziswiler <marcel.ziswiler at toradex.com>
---

 arch/arm/boot/dts/tegra30-apalis-eval.dts | 6 +++---
 1 file changed, 3 insertions(+), 3 deletions(-)

diff --git a/arch/arm/boot/dts/tegra30-apalis-eval.dts b/arch/arm/boot/dts/tegra30-apalis-eval.dts
index c832c15..f2879cf 100644
--- a/arch/arm/boot/dts/tegra30-apalis-eval.dts
+++ b/arch/arm/boot/dts/tegra30-apalis-eval.dts
@@ -191,10 +191,10 @@
 	gpio-keys {
 		compatible = "gpio-keys";
 
-		power {
-			label = "Power";
+		wakeup {
+			label = "WAKE1_MICO";
 			gpios = <&gpio TEGRA_GPIO(V, 1) GPIO_ACTIVE_LOW>;
-			linux,code = <KEY_POWER>;
+			linux,code = <KEY_WAKEUP>;
 			debounce-interval = <10>;
 			gpio-key,wakeup;
 		};
-- 
2.4.3



From luis at debethencourt.com  Fri Aug 28 05:43:54 2015
From: luis at debethencourt.com (Luis de Bethencourt)
Date: Fri, 28 Aug 2015 14:43:54 +0200
Subject: [PATCH 3/5] clk: sunxi: sun6i-ar100: Fix module autoload for OF
 platform driver
Message-ID: <20150828124354.GA26610@goodgumbo.baconseed.org>

This platform driver has a OF device ID table but the OF module
alias information is not created so module autoloading won't work.

Signed-off-by: Luis de Bethencourt <luis at debethencourt.com>
---
 drivers/clk/sunxi/clk-sun6i-ar100.c | 1 +
 1 file changed, 1 insertion(+)

diff --git a/drivers/clk/sunxi/clk-sun6i-ar100.c b/drivers/clk/sunxi/clk-sun6i-ar100.c
index 63cf149..40828fb 100644
--- a/drivers/clk/sunxi/clk-sun6i-ar100.c
+++ b/drivers/clk/sunxi/clk-sun6i-ar100.c
@@ -219,6 +219,7 @@ static const struct of_device_id sun6i_a31_ar100_clk_dt_ids[] = {
 	{ .compatible = "allwinner,sun6i-a31-ar100-clk" },
 	{ /* sentinel */ }
 };
+MODULE_DEVICE_TABLE(of, sun6i_a31_ar100_clk_dt_ids);
 
 static struct platform_driver sun6i_a31_ar100_clk_driver = {
 	.driver = {
-- 
2.4.6



From luis at debethencourt.com  Fri Aug 28 05:44:14 2015
From: luis at debethencourt.com (Luis de Bethencourt)
Date: Fri, 28 Aug 2015 14:44:14 +0200
Subject: [PATCH 4/5] clk: sunxi: sun8i-apb0: Fix module autoload for OF
 platform driver
Message-ID: <20150828124414.GA26661@goodgumbo.baconseed.org>

This platform driver has a OF device ID table but the OF module
alias information is not created so module autoloading won't work.

Signed-off-by: Luis de Bethencourt <luis at debethencourt.com>
---
 drivers/clk/sunxi/clk-sun8i-apb0.c | 1 +
 1 file changed, 1 insertion(+)

diff --git a/drivers/clk/sunxi/clk-sun8i-apb0.c b/drivers/clk/sunxi/clk-sun8i-apb0.c
index 155d002..7ae5d2c 100644
--- a/drivers/clk/sunxi/clk-sun8i-apb0.c
+++ b/drivers/clk/sunxi/clk-sun8i-apb0.c
@@ -52,6 +52,7 @@ static const struct of_device_id sun8i_a23_apb0_clk_dt_ids[] = {
 	{ .compatible = "allwinner,sun8i-a23-apb0-clk" },
 	{ /* sentinel */ }
 };
+MODULE_DEVICE_TABLE(of, sun8i_a23_apb0_clk_dt_ids);
 
 static struct platform_driver sun8i_a23_apb0_clk_driver = {
 	.driver = {
-- 
2.4.6



From luis at debethencourt.com  Fri Aug 28 05:44:32 2015
From: luis at debethencourt.com (Luis de Bethencourt)
Date: Fri, 28 Aug 2015 14:44:32 +0200
Subject: [PATCH 5/5] clk: sunxi: sun9i-mmc: Fix module autoload for OF
 platform driver
Message-ID: <20150828124432.GA26670@goodgumbo.baconseed.org>

This platform driver has a OF device ID table but the OF module
alias information is not created so module autoloading won't work.

Signed-off-by: Luis de Bethencourt <luis at debethencourt.com>
---
 drivers/clk/sunxi/clk-sun9i-mmc.c | 1 +
 1 file changed, 1 insertion(+)

diff --git a/drivers/clk/sunxi/clk-sun9i-mmc.c b/drivers/clk/sunxi/clk-sun9i-mmc.c
index 710c273..7618b13 100644
--- a/drivers/clk/sunxi/clk-sun9i-mmc.c
+++ b/drivers/clk/sunxi/clk-sun9i-mmc.c
@@ -203,6 +203,7 @@ static const struct of_device_id sun9i_a80_mmc_config_clk_dt_ids[] = {
 	{ .compatible = "allwinner,sun9i-a80-mmc-config-clk" },
 	{ /* sentinel */ }
 };
+MODULE_DEVICE_TABLE(of, sun9i_a80_mmc_config_clk_dt_ids);
 
 static struct platform_driver sun9i_a80_mmc_config_clk_driver = {
 	.driver = {
-- 
2.4.6



From maxime.ripard at free-electrons.com  Fri Aug 28 05:58:51 2015
From: maxime.ripard at free-electrons.com (Maxime Ripard)
Date: Fri, 28 Aug 2015 14:58:51 +0200
Subject: [PATCH 0/5] clk: sunxi: Fix module autoload for OF platform driver
In-Reply-To: <20150828124222.GA24923@goodgumbo.baconseed.org>
References: <20150828124222.GA24923@goodgumbo.baconseed.org>
Message-ID: <20150828125851.GO29389@lukather>

On Fri, Aug 28, 2015 at 02:42:22PM +0200, Luis de Bethencourt wrote:
> Hello,
> 
> This series add the missing MODULE_DEVICE_TABLE() for OF to eport
> that information so modules have the correct aliases built-in
> and autoloading works correctly.
> 
> A longer explanation by Javier Canillas can be found here:
> https://lkml.org/lkml/2015/7/30/519

On the whole serie,
Acked-by: Maxime Ripard <maxime.ripard at free-electrons.com>

Mike, Stephen, can you apply them directly as fixes for 4.3 ?

Thanks,
Maxime

-- 
Maxime Ripard, Free Electrons
Embedded Linux, Kernel and Android engineering
http://free-electrons.com
-------------- next part --------------
A non-text attachment was scrubbed...
Name: signature.asc
Type: application/pgp-signature
Size: 819 bytes
Desc: Digital signature
URL: <http://lists.infradead.org/pipermail/linux-arm-kernel/attachments/20150828/9b893158/attachment-0001.sig>

From marcel.ziswiler at toradex.com  Fri Aug 28 05:42:34 2015
From: marcel.ziswiler at toradex.com (Marcel Ziswiler)
Date: Fri, 28 Aug 2015 14:42:34 +0200
Subject: [PATCH 7/9] arm: tegra: apalis_t30: set otg dr_mode for eval board
In-Reply-To: <1440765756-1382-1-git-send-email-marcel.ziswiler@toradex.com>
References: <1440765756-1382-1-git-send-email-marcel.ziswiler@toradex.com>
Message-ID: <1440765756-1382-8-git-send-email-marcel.ziswiler@toradex.com>

This has currently no functional effect as neither USB device nor OTG
is currently supported on any Tegras in mainline as of yet. However
once we use the same device tree on U-Boot this will actually make it
work properly there.

Signed-off-by: Marcel Ziswiler <marcel.ziswiler at toradex.com>
---

 arch/arm/boot/dts/tegra30-apalis-eval.dts | 1 +
 1 file changed, 1 insertion(+)

diff --git a/arch/arm/boot/dts/tegra30-apalis-eval.dts b/arch/arm/boot/dts/tegra30-apalis-eval.dts
index 5a49f03..37437c6 100644
--- a/arch/arm/boot/dts/tegra30-apalis-eval.dts
+++ b/arch/arm/boot/dts/tegra30-apalis-eval.dts
@@ -153,6 +153,7 @@
 
 	usb-phy at 7d000000 {
 		status = "okay";
+		dr_mode = "otg";
 		vbus-supply = <&usbo1_vbus_reg>;
 	};
 
-- 
2.4.3



From marcel.ziswiler at toradex.com  Fri Aug 28 05:42:27 2015
From: marcel.ziswiler at toradex.com (Marcel Ziswiler)
Date: Fri, 28 Aug 2015 14:42:27 +0200
Subject: [PATCH 0/9] arm: tegra: apalis_t30: fix pin mux, hdmi,
 wakeup and enable hda
Message-ID: <1440765756-1382-1-git-send-email-marcel.ziswiler@toradex.com>

This series finally continues on my previous Easter efforts (BTW:
thanks all for the feedback and all the patches thereof already having
been applied) and additionally to fixing the pin muxing and enabling
HDA audio also fixes HDMI and the wake-up key.


Marcel Ziswiler (9):
  arm: tegra: apalis_t30: update hardware revisions compatibility
    comment
  arm: tegra: apalis_t30: fix hdmi supply
  arm: tegra: apalis_t30: fix pin muxing
  arm: tegra: apalis_t30: add comment concerning emmc
  arm: tegra: apalis_t30: add digital audio pin muxing
  arm: tegra: apalis_t30: enable hda for eval board
  arm: tegra: apalis_t30: set otg dr_mode for eval board
  arm: tegra: apalis_t30: fix backlight pwm comment for eval board
  arm: tegra: apalis_t30: fix power/wakeup key for eval board

 arch/arm/boot/dts/tegra30-apalis-eval.dts | 13 +++--
 arch/arm/boot/dts/tegra30-apalis.dtsi     | 80 ++++++++++++++++++++++++-------
 2 files changed, 73 insertions(+), 20 deletions(-)

-- 
2.4.3



From marcel.ziswiler at toradex.com  Fri Aug 28 05:42:33 2015
From: marcel.ziswiler at toradex.com (Marcel Ziswiler)
Date: Fri, 28 Aug 2015 14:42:33 +0200
Subject: [PATCH 6/9] arm: tegra: apalis_t30: enable hda for eval board
In-Reply-To: <1440765756-1382-1-git-send-email-marcel.ziswiler@toradex.com>
References: <1440765756-1382-1-git-send-email-marcel.ziswiler@toradex.com>
Message-ID: <1440765756-1382-7-git-send-email-marcel.ziswiler@toradex.com>

Actually enable HDA now that it should otherwise be supported driver
and device tree wise.

Signed-off-by: Marcel Ziswiler <marcel.ziswiler at toradex.com>
---

 arch/arm/boot/dts/tegra30-apalis-eval.dts | 4 ++++
 1 file changed, 4 insertions(+)

diff --git a/arch/arm/boot/dts/tegra30-apalis-eval.dts b/arch/arm/boot/dts/tegra30-apalis-eval.dts
index 6236bde..5a49f03 100644
--- a/arch/arm/boot/dts/tegra30-apalis-eval.dts
+++ b/arch/arm/boot/dts/tegra30-apalis-eval.dts
@@ -126,6 +126,10 @@
 		};
 	};
 
+	hda at 70030000 {
+		status = "okay";
+	};
+
 	sd1: sdhci at 78000000 {
 		status = "okay";
 		bus-width = <4>;
-- 
2.4.3



From marcel.ziswiler at toradex.com  Fri Aug 28 05:42:30 2015
From: marcel.ziswiler at toradex.com (Marcel Ziswiler)
Date: Fri, 28 Aug 2015 14:42:30 +0200
Subject: [PATCH 3/9] arm: tegra: apalis_t30: fix pin muxing
In-Reply-To: <1440765756-1382-1-git-send-email-marcel.ziswiler@toradex.com>
References: <1440765756-1382-1-git-send-email-marcel.ziswiler@toradex.com>
Message-ID: <1440765756-1382-4-git-send-email-marcel.ziswiler@toradex.com>

Fix pin muxing which got broken due to certain stuff having been
fixed/renamed since.

Signed-off-by: Marcel Ziswiler <marcel.ziswiler at toradex.com>
---

 arch/arm/boot/dts/tegra30-apalis.dtsi | 18 +++++++++---------
 1 file changed, 9 insertions(+), 9 deletions(-)

diff --git a/arch/arm/boot/dts/tegra30-apalis.dtsi b/arch/arm/boot/dts/tegra30-apalis.dtsi
index fd6c94e..84744dc 100644
--- a/arch/arm/boot/dts/tegra30-apalis.dtsi
+++ b/arch/arm/boot/dts/tegra30-apalis.dtsi
@@ -66,7 +66,7 @@
 			/* BKL1_PWM_EN#, disable TPS65911 PMIC PWM backlight */
 			uart3_cts_n_pa1 {
 				nvidia,pins =	"uart3_cts_n_pa1";
-				nvidia,function = "rsvd1";
+				nvidia,function = "rsvd2";
 				nvidia,pull = <TEGRA_PIN_PULL_UP>;
 				nvidia,tristate = <TEGRA_PIN_DISABLE>;
 			};
@@ -152,32 +152,32 @@
 			};
 
 			/* Apalis PWM1 */
-			gpio_pu6 {
-				nvidia,pins =	"gpio_pu6";
+			pu6 {
+				nvidia,pins =	"pu6";
 				nvidia,function = "pwm3";
 				nvidia,pull = <TEGRA_PIN_PULL_NONE>;
 				nvidia,tristate = <TEGRA_PIN_DISABLE>;
 			};
 
 			/* Apalis PWM2 */
-			gpio_pu5 {
-				nvidia,pins =	"gpio_pu5";
+			pu5 {
+				nvidia,pins =	"pu5";
 				nvidia,function = "pwm2";
 				nvidia,pull = <TEGRA_PIN_PULL_NONE>;
 				nvidia,tristate = <TEGRA_PIN_DISABLE>;
 			};
 
 			/* Apalis PWM3 */
-			gpio_pu4 {
-				nvidia,pins =	"gpio_pu4";
+			pu4 {
+				nvidia,pins =	"pu4";
 				nvidia,function = "pwm1";
 				nvidia,pull = <TEGRA_PIN_PULL_NONE>;
 				nvidia,tristate = <TEGRA_PIN_DISABLE>;
 			};
 
 			/* Apalis PWM4 */
-			gpio_pu3 {
-				nvidia,pins =	"gpio_pu3";
+			pu3 {
+				nvidia,pins =	"pu3";
 				nvidia,function = "pwm0";
 				nvidia,pull = <TEGRA_PIN_PULL_NONE>;
 				nvidia,tristate = <TEGRA_PIN_DISABLE>;
-- 
2.4.3



From mchehab at infradead.org  Fri Aug 28 06:08:02 2015
From: mchehab at infradead.org (Mauro Carvalho Chehab)
Date: Fri, 28 Aug 2015 10:08:02 -0300
Subject: [PATCH v7 10/44] [media] media: rename the function that create
 pad links
In-Reply-To: <20150826115403.7a794597@recife.lan>
References: <cover.1440359643.git.mchehab@osg.samsung.com>
 <f095b87884d435e296a455ab07a9951a74c0c3a6.1440359643.git.mchehab@osg.samsung.com>
 <55DCBA2D.9090901@osg.samsung.com>
 <20150826115403.7a794597@recife.lan>
Message-ID: <20150828100802.6e626e4c@recife.lan>

Em Wed, 26 Aug 2015 11:54:03 -0300
Mauro Carvalho Chehab <mchehab at osg.samsung.com> escreveu:

> Em Tue, 25 Aug 2015 12:55:41 -0600
> Shuah Khan <shuahkh at osg.samsung.com> escreveu:
> 
> > On 08/23/2015 02:17 PM, Mauro Carvalho Chehab wrote:
> > > Now that a link can be either between two different graph
> > > objects, we'll need to add more functions to create links.
> > 
> > Is this an incomplete sentence. Should it read: "either between
> > two different graph objects or two pads" ?
> 
> That would be redundant, as pad is a graph object ;)

Renamed the patch description to:

	With the new API, a link can be either between two PADs or between an interface
	and an entity. So, we need to use a better name for the function that create
	links between two pads.

	So, rename the such function to media_create_pad_link().

	No functional changes.

	This patch was created via this shell script:
		for i in $(find drivers/media -name '*.[ch]' -type f) $(find drivers/staging/media -name '*.[ch]' -type f) $(find include/ -name '*.h' -type f) ; do sed s,media_entity_create_link,media_create_pad_link,g <$i >a && mv a $i; done

	Signed-off-by: Mauro Carvalho Chehab <mchehab at osg.samsung.com>
	Acked-by: Hans Verkuil <hans.verkuil at cisco.com>

Regards,
Mauro

> 
> > 
> > > So, rename the existing one that create links only between
> > > two pads as media_create_pad_link().
> > 
> > > 
> > > No functional changes.
> > > 
> > > This patch was created via this shell script:
> > > 	for i in $(find drivers/media -name '*.[ch]' -type f) $(find drivers/staging/media -name '*.[ch]' -type f) $(find include/ -name '*.h' -type f) ; do sed s,media_entity_create_link,media_create_pad_link,g <$i >a && mv a $i; done
> > > 
> > 
> > Didn't want to experiment with Coccinelle?? :)
> 
> I use Coccinelle, but only when I need more complex changes, as
> Coccinelle may mangle with comments.
> 
> > 
> > > Signed-off-by: Mauro Carvalho Chehab <mchehab at osg.samsung.com>
> > > Acked-by: Hans Verkuil <hans.verkuil at cisco.com>
> > > Signed-off-by: Mauro Carvalho Chehab <mchehab at osg.samsung.com>
> > > 
> > 
> > Changes look good to me. After fixing the commit log:
> > 
> > Acked-by: Shuah Khan <shuahkh at osg.samsung.com>
> > 
> > thanks,
> > -- Shuah
> > 
> > 
> --
> To unsubscribe from this list: send the line "unsubscribe linux-media" in
> the body of a message to majordomo at vger.kernel.org
> More majordomo info at  http://vger.kernel.org/majordomo-info.html


From hdegoede at redhat.com  Fri Aug 28 06:15:06 2015
From: hdegoede at redhat.com (Hans de Goede)
Date: Fri, 28 Aug 2015 15:15:06 +0200
Subject: [PATCH 0/1] ARM: dts: sun5i: inet98v_rev2 fix regulator for the
 usb wifi
In-Reply-To: <20150828122847.GH29389@lukather>
References: <1440700651-30575-1-git-send-email-hdegoede@redhat.com>
 <20150828122847.GH29389@lukather>
Message-ID: <55E05EDA.7040501@redhat.com>

Hi,

On 28-08-15 14:28, Maxime Ripard wrote:
> Hi Hans,
>
> On Thu, Aug 27, 2015 at 08:37:30PM +0200, Hans de Goede wrote:
>> Hi Maxime,
>>
>> Here is a fixup patch for the patch adding a dts for the inet98v_rev2.
>>
>> I'm not sure if you've merged the original patch yet, hence I'm sending
>> this as a follow-up patch. If you've not yet merged the original patch
>> feel free to squash this fix in.
>
> Have you ever submitted that first patch in the first place?
>
> I'm don't have the DTS file you're patching in my tree, and I don't
> see any email and/or patch relating to that board.

Oh, I thought I had posted it, ah well. I'll do a v2 (which I guess
really is v1 then) with the fix squashed in.

Regards,

Hans


From hdegoede at redhat.com  Fri Aug 28 06:15:17 2015
From: hdegoede at redhat.com (Hans de Goede)
Date: Fri, 28 Aug 2015 15:15:17 +0200
Subject: [PATCH v2] ARM: dts: sun5i: Add dts file for inet98v_rev2 based
 tablets
Message-ID: <1440767717-10601-1-git-send-email-hdegoede@redhat.com>

The inet98v_rev2 is a pcb used in generic A13 based tablets. It features
volume buttons, a power barrel, micro-usb otg, headphone connector and
a power button.

Signed-off-by: Hans de Goede <hdegoede at redhat.com>
---
Changes in v2:
-Use the right regulator for thw usb-wifi module / usb1
---
 arch/arm/boot/dts/Makefile                    |   1 +
 arch/arm/boot/dts/sun5i-a13-inet-98v-rev2.dts | 227 ++++++++++++++++++++++++++
 2 files changed, 228 insertions(+)
 create mode 100644 arch/arm/boot/dts/sun5i-a13-inet-98v-rev2.dts

diff --git a/arch/arm/boot/dts/Makefile b/arch/arm/boot/dts/Makefile
index 2111d03..e981fd6 100644
--- a/arch/arm/boot/dts/Makefile
+++ b/arch/arm/boot/dts/Makefile
@@ -569,6 +569,7 @@ dtb-$(CONFIG_MACH_SUN5I) += \
 	sun5i-a10s-olinuxino-micro.dtb \
 	sun5i-a10s-r7-tv-dongle.dtb \
 	sun5i-a13-hsg-h702.dtb \
+	sun5i-a13-inet-98v-rev2.dtb \
 	sun5i-a13-olinuxino.dtb \
 	sun5i-a13-olinuxino-micro.dtb \
 	sun5i-a13-utoo-p66.dtb \
diff --git a/arch/arm/boot/dts/sun5i-a13-inet-98v-rev2.dts b/arch/arm/boot/dts/sun5i-a13-inet-98v-rev2.dts
new file mode 100644
index 0000000..6fa54b6
--- /dev/null
+++ b/arch/arm/boot/dts/sun5i-a13-inet-98v-rev2.dts
@@ -0,0 +1,227 @@
+/*
+ * Copyright 2015 Hans de Goede <hdegoede at redhat.com>
+ *
+ * This file is dual-licensed: you can use it either under the terms
+ * of the GPL or the X11 license, at your option. Note that this dual
+ * licensing only applies to this file, and not this project as a
+ * whole.
+ *
+ *  a) This file is free software; you can redistribute it and/or
+ *     modify it under the terms of the GNU General Public License as
+ *     published by the Free Software Foundation; either version 2 of the
+ *     License, or (at your option) any later version.
+ *
+ *     This file is distributed in the hope that it will be useful,
+ *     but WITHOUT ANY WARRANTY; without even the implied warranty of
+ *     MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ *     GNU General Public License for more details.
+ *
+ * Or, alternatively,
+ *
+ *  b) Permission is hereby granted, free of charge, to any person
+ *     obtaining a copy of this software and associated documentation
+ *     files (the "Software"), to deal in the Software without
+ *     restriction, including without limitation the rights to use,
+ *     copy, modify, merge, publish, distribute, sublicense, and/or
+ *     sell copies of the Software, and to permit persons to whom the
+ *     Software is furnished to do so, subject to the following
+ *     conditions:
+ *
+ *     The above copyright notice and this permission notice shall be
+ *     included in all copies or substantial portions of the Software.
+ *
+ *     THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
+ *     EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES
+ *     OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
+ *     NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT
+ *     HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY,
+ *     WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
+ *     FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR
+ *     OTHER DEALINGS IN THE SOFTWARE.
+ */
+
+/dts-v1/;
+#include "sun5i-a13.dtsi"
+#include "sunxi-common-regulators.dtsi"
+#include <dt-bindings/gpio/gpio.h>
+#include <dt-bindings/input/input.h>
+#include <dt-bindings/interrupt-controller/irq.h>
+#include <dt-bindings/pinctrl/sun4i-a10.h>
+
+/ {
+	model = "INet-98V Rev 02";
+	compatible = "primux,inet98v-rev2", "allwinner,sun5i-a13";
+
+	aliases {
+		serial0 = &uart1;
+	};
+
+	chosen {
+		stdout-path = "serial0:115200n8";
+	};
+
+};
+
+&cpu0 {
+	cpu-supply = <&reg_dcdc2>;
+};
+
+&ehci0 {
+	status = "okay";
+};
+
+&i2c0 {
+	pinctrl-names = "default";
+	pinctrl-0 = <&i2c0_pins_a>;
+	status = "okay";
+
+	axp209: pmic at 34 {
+		reg = <0x34>;
+		interrupts = <0>;
+	};
+};
+
+#include "axp209.dtsi"
+
+&i2c1 {
+	pinctrl-names = "default";
+	pinctrl-0 = <&i2c1_pins_a>;
+	status = "okay";
+
+	pcf8563: rtc at 51 {
+		compatible = "nxp,pcf8563";
+		reg = <0x51>;
+	};
+};
+
+&lradc {
+	vref-supply = <&reg_ldo2>;
+	status = "okay";
+
+	button at 200 {
+		label = "Volume Up";
+		linux,code = <KEY_VOLUMEUP>;
+		channel = <0>;
+		voltage = <200000>;
+	};
+
+	button at 400 {
+		label = "Volume Down";
+		linux,code = <KEY_VOLUMEDOWN>;
+		channel = <0>;
+		voltage = <400000>;
+	};
+};
+
+&mmc0 {
+	pinctrl-names = "default";
+	pinctrl-0 = <&mmc0_pins_a>, <&mmc0_cd_pin_inet98fv2>;
+	vmmc-supply = <&reg_vcc3v3>;
+	bus-width = <4>;
+	cd-gpios = <&pio 6 0 GPIO_ACTIVE_HIGH>; /* PG0 */
+	cd-inverted;
+	status = "okay";
+};
+
+&mmc2 {
+	pinctrl-names = "default";
+	pinctrl-0 = <&mmc2_pins_a>;
+	vmmc-supply = <&reg_vcc3v3>;
+	bus-width = <8>;
+	non-removable;
+	status = "okay";
+
+	mmccard: mmccard at 0 {
+		reg = <0>;
+		compatible = "mmc-card";
+		broken-hpi;
+	};
+};
+
+&otg_sram {
+	status = "okay";
+};
+
+&pio {
+	mmc0_cd_pin_inet98fv2: mmc0_cd_pin at 0 {
+		allwinner,pins = "PG0";
+		allwinner,function = "gpio_in";
+		allwinner,drive = <SUN4I_PINCTRL_10_MA>;
+		allwinner,pull = <SUN4I_PINCTRL_PULL_UP>;
+	};
+
+	usb0_vbus_detect_pin: usb0_vbus_detect_pin at 0 {
+		allwinner,pins = "PG1";
+		allwinner,function = "gpio_in";
+		allwinner,drive = <SUN4I_PINCTRL_10_MA>;
+		allwinner,pull = <SUN4I_PINCTRL_PULL_DOWN>;
+	};
+
+	usb0_id_detect_pin: usb0_id_detect_pin at 0 {
+		allwinner,pins = "PG2";
+		allwinner,function = "gpio_in";
+		allwinner,drive = <SUN4I_PINCTRL_10_MA>;
+		allwinner,pull = <SUN4I_PINCTRL_PULL_UP>;
+	};
+};
+
+&reg_dcdc2 {
+	regulator-always-on;
+	regulator-min-microvolt = <1000000>;
+	regulator-max-microvolt = <1400000>;
+	regulator-name = "vdd-cpu";
+};
+
+&reg_dcdc3 {
+	regulator-always-on;
+	regulator-min-microvolt = <1250000>;
+	regulator-max-microvolt = <1250000>;
+	regulator-name = "vdd-int-pll";
+};
+
+&reg_ldo1 {
+	regulator-name = "vdd-rtc";
+};
+
+&reg_ldo2 {
+	regulator-always-on;
+	regulator-min-microvolt = <3000000>;
+	regulator-max-microvolt = <3000000>;
+	regulator-name = "avcc";
+};
+
+&reg_ldo3 {
+	regulator-min-microvolt = <3300000>;
+	regulator-max-microvolt = <3300000>;
+	regulator-name = "vcc-wifi";
+};
+
+&reg_usb0_vbus {
+	gpio = <&pio 6 12 GPIO_ACTIVE_HIGH>; /* PG12 */
+	status = "okay";
+};
+
+&uart1 {
+	pinctrl-names = "default";
+	pinctrl-0 = <&uart1_pins_b>;
+	status = "okay";
+};
+
+&usb_otg {
+	dr_mode = "otg";
+	status = "okay";
+};
+
+&usb0_vbus_pin_a {
+	allwinner,pins = "PG12";
+};
+
+&usbphy {
+	pinctrl-names = "default";
+	pinctrl-0 = <&usb0_id_detect_pin>, <&usb0_vbus_detect_pin>;
+	usb0_id_det-gpio = <&pio 6 2 GPIO_ACTIVE_HIGH>; /* PG2 */
+	usb0_vbus_det-gpio = <&pio 6 1 GPIO_ACTIVE_HIGH>; /* PG1 */
+	usb0_vbus-supply = <&reg_usb0_vbus>;
+	usb1_vbus-supply = <&reg_ldo3>;
+	status = "okay";
+};
-- 
2.4.3



From siarhei.siamashka at gmail.com  Fri Aug 28 06:31:44 2015
From: siarhei.siamashka at gmail.com (Siarhei Siamashka)
Date: Fri, 28 Aug 2015 16:31:44 +0300
Subject: [PATCH 6/6] ARM: dts: sun6i: Add dts file for MSI Primo81 tablet
In-Reply-To: <20150828123805.GN29389@lukather>
References: <1440755679-8266-1-git-send-email-wens@csie.org>
 <1440755679-8266-7-git-send-email-wens@csie.org>
 <20150828123805.GN29389@lukather>
Message-ID: <20150828163144.239e9bd5@i7>

On Fri, 28 Aug 2015 14:38:05 +0200
Maxime Ripard <maxime.ripard at free-electrons.com> wrote:

> On Fri, Aug 28, 2015 at 05:54:39PM +0800, Chen-Yu Tsai wrote:
> > From: Karsten Merker <merker at debian.org>
> > 
> > The MSI Primo81 is an A31s based tablet, with 1G RAM, 16G NAND,
> > 768x1024 IPS LCD display, mono speaker, 0.3 MP front camera, 2.0 MP
> > rear camera, 3500 mAh battery, gt911 touchscreen, mma8452 accelerometer
> > and rtl8188etv usb wifi. Has "power", "volume+" and "volume-" buttons
> > (both volume buttons are also connected to the UBOOT_SEL pin). The

Actually this part about both volume buttons turned out to be not
perfectly accurate. We have discussed it with Chen-Yu Tsai on IRC
several days ago and also corrected this information in the wiki:

    http://linux-sunxi.org/index.php?title=MSI_Primo81&diff=14802&oldid=14767

That's just a minor nitpick. And I'm sorry for providing this originally
wrong information in the first revision of the patch in the first place.

> > external connectors are represented by MicroSD slot, MiniHDMI, MicroUSB
> > OTG and 3.5mm headphone jack. More details are available at
> > 
> >     http://linux-sunxi.org/MSI_Primo81
> 
> Again, not a huge fan of the commit logs URL...

But you are not strongly objecting to it either, right?

AFAIK many people are in favour of having links to the device pages in
the linux-sunxi wiki listed somewhere in the commit logs or along with
the board maintainer contact information (in U-Boot). Because these
pages contain the most relevant and up to date information about the
device, various pictures, tips and tricks, etc.

If you are worried about linux-sunxi.org suddenly going down and not
coming back, there is also webarchive:

    http://web.archive.org/web/*/http://linux-sunxi.org/MSI_Primo81

> This commit log is already fine without it.

This commit log is a nice example of why having a link to the wiki page
is a good idea. The errors and omissions in the wiki page can be
corrected. The old commit logs can't.

> > 
> > USB OTG is enabled in host only mode. AXP221 USB power supply and
> > GPIO support are required for full USB OTG support.
> > 
> > Signed-off-by: Siarhei Siamashka <siarhei.siamashka at gmail.com>
> > Signed-off-by: Karsten Merker <merker at debian.org>
> > Signed-off-by: Chen-Yu Tsai <wens at csie.org>
> > ---
> > 
> > Changes since v4:
> > 
> >   - Use axp221.dtsi and add all active regulators.
> >   - Enable i2c controllers for capacitive touch panel and accelerometer.
> >   - Mark i2c controller for camera sensors as failed for now.
> >   - Enable USB OTG in host only mode.
> >   - Drop uart0 as this is not tested.
> >   - s/library/file/ in GPL header.
> > 
> > ---
> >  arch/arm/boot/dts/Makefile               |   1 +
> >  arch/arm/boot/dts/sun6i-a31s-primo81.dts | 255 +++++++++++++++++++++++++++++++
> >  2 files changed, 256 insertions(+)
> >  create mode 100644 arch/arm/boot/dts/sun6i-a31s-primo81.dts
> > 
> > diff --git a/arch/arm/boot/dts/Makefile b/arch/arm/boot/dts/Makefile
> > index ada5156fdd49..c87513ed4eb4 100644
> > --- a/arch/arm/boot/dts/Makefile
> > +++ b/arch/arm/boot/dts/Makefile
> > @@ -579,6 +579,7 @@ dtb-$(CONFIG_MACH_SUN6I) += \
> >  	sun6i-a31-m9.dtb \
> >  	sun6i-a31-mele-a1000g-quad.dtb \
> >  	sun6i-a31s-cs908.dtb \
> > +	sun6i-a31s-primo81.dtb \
> >  	sun6i-a31s-sina31s.dtb
> >  dtb-$(CONFIG_MACH_SUN7I) += \
> >  	sun7i-a20-bananapi.dtb \
> > diff --git a/arch/arm/boot/dts/sun6i-a31s-primo81.dts b/arch/arm/boot/dts/sun6i-a31s-primo81.dts
> > new file mode 100644
> > index 000000000000..d22befaf363b
> > --- /dev/null
> > +++ b/arch/arm/boot/dts/sun6i-a31s-primo81.dts
> > @@ -0,0 +1,255 @@
> > +/*
> > + * Copyright 2014 Siarhei Siamashka <siarhei.siamashka at gmail.com>
> > + * Copyright 2015 Karsten Merker <merker at debian.org>
> > + * Copyright 2015 Chen-Yu Tsai <wens at csie.org>
> > + *
> > + * This file is dual-licensed: you can use it either under the terms
> > + * of the GPL or the X11 license, at your option. Note that this dual
> > + * licensing only applies to this file, and not this project as a
> > + * whole.
> > + *
> > + *  a) This file is free software; you can redistribute it and/or
> > + *     modify it under the terms of the GNU General Public License as
> > + *     published by the Free Software Foundation; either version 2 of the
> > + *     License, or (at your option) any later version.
> > + *
> > + *     This file is distributed in the hope that it will be useful,
> > + *     but WITHOUT ANY WARRANTY; without even the implied warranty of
> > + *     MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
> > + *     GNU General Public License for more details.
> > + *
> > + * Or, alternatively,
> > + *
> > + *  b) Permission is hereby granted, free of charge, to any person
> > + *     obtaining a copy of this software and associated documentation
> > + *     files (the "Software"), to deal in the Software without
> > + *     restriction, including without limitation the rights to use,
> > + *     copy, modify, merge, publish, distribute, sublicense, and/or
> > + *     sell copies of the Software, and to permit persons to whom the
> > + *     Software is furnished to do so, subject to the following
> > + *     conditions:
> > + *
> > + *     The above copyright notice and this permission notice shall be
> > + *     included in all copies or substantial portions of the Software.
> > + *
> > + *     THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
> > + *     EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES
> > + *     OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
> > + *     NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT
> > + *     HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY,
> > + *     WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
> > + *     FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR
> > + *     OTHER DEALINGS IN THE SOFTWARE.
> > + */
> > +
> > +/dts-v1/;
> > +#include "sun6i-a31s.dtsi"
> > +#include "sunxi-common-regulators.dtsi"
> > +
> > +#include <dt-bindings/gpio/gpio.h>
> > +#include <dt-bindings/input/input.h>
> > +#include <dt-bindings/pinctrl/sun4i-a10.h>
> > +
> > +/ {
> > +	model = "MSI Primo81 tablet";
> > +	compatible = "msi,primo81", "allwinner,sun6i-a31s";
> > +};
> > +
> > +&cpu0 {
> > +	cpu-supply = <&reg_dcdc2>;
> > +};
> > +
> > +&ehci0 {
> > +	/* rtl8188etv wifi is connected here */
> > +	status = "okay";
> > +};
> > +
> > +&i2c0 {
> > +	pinctrl-names = "default";
> > +	pinctrl-0 = <&i2c0_pins_a>;
> > +	/* pull-ups and device VDDIO require AXP221 DLDO3 */
> 
> Now that we have AXP221, that can probably be solved, right?
> 
> > +	status = "failed";
> > +};
> > +
> > +&i2c1 {
> > +	pinctrl-names = "default";
> > +	pinctrl-0 = <&i2c1_pins_a>;
> > +	status = "okay";
> > +
> > +	ctp at 5d {
> > +		pinctrl-names = "default";
> > +		pinctrl-0 = <&gt911_int_primo81>;
> > +		compatible = "goodix,gt911";
> > +		reg = <0x5d>;
> > +		interrupt-parent = <&pio>;
> > +		interrupts = <0 3 IRQ_TYPE_LEVEL_HIGH>; /* PA3 */
> > +		/*
> > +		 * The default 0,0 coordinate is at the corner closest to
> > +		 * the headphone jack. X goes along the long side, while
> > +		 * Y goes along the short side.
> > +		 */
> 
> I'm not exactly sure what that comment is supposed to be for...

It's probably a human readable comment intended to be read by humans.

Yeah, this information might actually better belong to the wiki page.
But then again, this brings us to the question whether we should have
a link to the linux-sunxi wiki page somewhere in the dts.

-- 
Best regards,
Siarhei Siamashka


From matt at codeblueprint.co.uk  Fri Aug 28 06:32:04 2015
From: matt at codeblueprint.co.uk (Matt Fleming)
Date: Fri, 28 Aug 2015 14:32:04 +0100
Subject: [PATCH 2/3] arm64: use core efi=debug instead of uefi_debug
 command line parameter
In-Reply-To: <1440595498-30630-3-git-send-email-leif.lindholm@linaro.org>
References: <1440595498-30630-1-git-send-email-leif.lindholm@linaro.org>
 <1440595498-30630-3-git-send-email-leif.lindholm@linaro.org>
Message-ID: <20150828133204.GG2759@codeblueprint.co.uk>

On Wed, 26 Aug, at 02:24:57PM, Leif Lindholm wrote:
> Now that we have an efi=debug command line option in the core code, use
> this instead of the arm64-specific uefi_debug option.
> 
> Signed-off-by: Leif Lindholm <leif.lindholm at linaro.org>
> ---
>  Documentation/arm/uefi.txt |  2 --
>  arch/arm64/kernel/efi.c    | 19 +++++--------------
>  2 files changed, 5 insertions(+), 16 deletions(-)

Thanks Leif, applied.

-- 
Matt Fleming, Intel Open Source Technology Center


From matt at codeblueprint.co.uk  Fri Aug 28 06:32:18 2015
From: matt at codeblueprint.co.uk (Matt Fleming)
Date: Fri, 28 Aug 2015 14:32:18 +0100
Subject: [PATCH 3/3] efi/arm64: clean up efi_get_fdt_params() interface
In-Reply-To: <1440595498-30630-4-git-send-email-leif.lindholm@linaro.org>
References: <1440595498-30630-1-git-send-email-leif.lindholm@linaro.org>
 <1440595498-30630-4-git-send-email-leif.lindholm@linaro.org>
Message-ID: <20150828133218.GH2759@codeblueprint.co.uk>

On Wed, 26 Aug, at 02:24:58PM, Leif Lindholm wrote:
> As we now have a common debug infrastructure between core and arm64 efi,
> drop the bit of the interface passing verbose output flags around.
> 
> Signed-off-by: Leif Lindholm <leif.lindholm at linaro.org>
> ---
>  arch/arm64/kernel/efi.c    | 2 +-
>  drivers/firmware/efi/efi.c | 6 ++----
>  include/linux/efi.h        | 2 +-
>  3 files changed, 4 insertions(+), 6 deletions(-)

Thanks, applied.

-- 
Matt Fleming, Intel Open Source Technology Center


From rjw at rjwysocki.net  Fri Aug 28 07:06:16 2015
From: rjw at rjwysocki.net (Rafael J. Wysocki)
Date: Fri, 28 Aug 2015 16:06:16 +0200
Subject: [RESEND PATCH 0/3 v6] Add Mediatek MT8173 cpufreq driver
In-Reply-To: <CALx668V2herrp6XOtCDR7nNvFhd7DLLMjXmr86cjfCOQ_cgmrw@mail.gmail.com>
References: <1439803465-19683-1-git-send-email-pi-cheng.chen@linaro.org>
 <20150826021659.GD8784@linux>
 <CALx668V2herrp6XOtCDR7nNvFhd7DLLMjXmr86cjfCOQ_cgmrw@mail.gmail.com>
Message-ID: <22538895.vrRgZUmQTV@vostro.rjw.lan>

On Wednesday, August 26, 2015 02:53:39 PM Pi-Cheng Chen wrote:
> On Wed, Aug 26, 2015 at 10:16 AM, Viresh Kumar <viresh.kumar at linaro.org> wrote:
> > On 26-08-15, 09:25, Pi-Cheng Chen wrote:
> >> The [3/3] is based on Mediatek SoC maintainer tree[1] and the patch which
> >> introduce a new clock type[2] consumed by MT8173 cpufreq driver. So it will
> >> cause some conflicts if it goes through your tree. I am not sure how this
> >> should be handled, but should it be merged through Mediatek SoC maintainer
> >> tree?
> >
> > Just get that applied to MTK tree, it doesn't have any dependency on
> > rest of the patches for build/boot. The only thing is that cpufreq
> > wouldn't work and it will work as soon as Rafael's and MTK's trees are
> > merged by Linus.
> 
> Thanks for your explanation.
> 
> @Rafael, Would you please apply [1,2] to your tree?

Applied, thanks!


-- 
I speak only for myself.
Rafael J. Wysocki, Intel Open Source Technology Center.


From m-karicheri2 at ti.com  Fri Aug 28 06:57:24 2015
From: m-karicheri2 at ti.com (Murali Karicheri)
Date: Fri, 28 Aug 2015 09:57:24 -0400
Subject: [PATCH v1] soc: ti: reset irq affinity before freeing irq
In-Reply-To: <55DF9611.4060801@oracle.com>
References: <1440711847-24747-1-git-send-email-m-karicheri2@ti.com>
 <55DF9611.4060801@oracle.com>
Message-ID: <55E068C4.2060606@ti.com>

On 08/27/2015 06:58 PM, santosh shilimkar wrote:
>
>
> On 8/27/2015 2:44 PM, Murali Karicheri wrote:
>> When using accumulator queue for rx side for network driver, following
>> warning is seen when doing a reboot command from Linux console. This
>> is because, affinity value is not reset before calling free_irq(). This
>> patch fixes this.
>>
>> Deconfiguring network interfaces...
>> [   55.176589] ------------[ cut here ]-----------
>> [   55.181232] WARNING: CPU: 0 PID: 2081 at kernel/irq/manage.c:1370
>> __free_irq+0x208/0x214
>> [   55.181232] WARNING: CPU: 0 PID: 2081 at kernel/irq/manage.c:1370
>> __free_irq+0x208/0x214
>> ()
>> [   55.189527] Modules linked in:
>> [   55.192598] CPU: 0 PID: 2081 Comm: ifconfig Not tainted
>> 4.1.5-00908-g1049e206-dirty #1
>> [   55.200543] Hardware name: Keystone
>> [   55.204040] Backtrace:
>> [   55.206507] [<c0012b98>] (dump_backtrace) from [<c0012dbc>]
>> (show_stack+0x18/0x1c)
>> [   55.214102]  r7:c005d0a8 r6:c06e2184 r5:c06e2184 r4:00000000
>> [   55.219811] [<c0012da4>] (show_stack) from [<c04e7168>]
>> (dump_stack+0x8c/0xcc)
>> [   55.227065] [<c04e70dc>] (dump_stack) from [<c0025944>]
>> (warn_slowpath_common+0x88/0xb8)
>> [   55.235183]  r7:c005d0a8 r6:0000055a r5:00000009 r4:00000000
>> [   55.240889] [<c00258bc>] (warn_slowpath_common) from [<c0025a18>]
>> (warn_slowpath_null+0x
>> 24/0x2c)
>> [   55.249704]  r8:0000006c r7:ee513f60 r6:ee513f00 r5:ee611010
>> r4:cc873a00
>> [   55.256458] [<c00259f4>] (warn_slowpath_null) from [<c005d0a8>]
>> (__free_irq+0x208/0x214)
>> [   55.264580] [<c005cea0>] (__free_irq) from [<c005d158>]
>>   (free_irq+0x54/0xac)
>> [   55.271652]  r10:00000002 r9:00000000 r8:00000000 r7:ee611010
>> r6:0000006c r5:00000000
>> [   55.279538]  r4:ee513f00 r3:00000000
>> [   55.283140] [<c005d104>] (free_irq) from [<c02a81b0>]
>> (knav_range_setup_acc_irq+0xb0/0x1
>> 28)
>> [   55.291519]  r7:00000001 r6:0000006c r5:ee611010 r4:00000001
>> [   55.297223] [<c02a8100>] (knav_range_setup_acc_irq) from [<c02a8248>]
>> (knav_acc_close_qu
>> eue+0x20/0x24)
>> [   55.306563]  r8:edd1a4c8 r7:00001000 r6:eed89980 r5:ee616650
>> r4:edf9d990
>> [   55.313320] [<c02a8228>] (knav_acc_close_queue) from [<c02a6160>]
>> (knav_queue_close+0xb4
>> /0xb8)
>> [   55.321969] [<c02a60ac>] (knav_queue_close) from [<c0336270>]
>> (netcp_free_navigator_reso
>> urces+0x1d4/0x2c0)
>> [   55.331656]  r5:edd1a480 r4:00000400
>> [   55.335255] [<c033609c>] (netcp_free_navigator_resources) from
>> [<c033657c>] (netcp_ndo_stop+0x220/0x230)
>> [   55.344768]  r10:00008914 r9:edf34400 r8:00000000 r7:edd1a5d8
>> r6:edd1a480 r5:00000400
>> [   55.352653]  r4:edd1a000
>> [   55.355202] [<c033635c>] (netcp_ndo_stop) from [<c03d9c80>]
>> (__dev_close_many+0x90/0xd8)
>> [   55.363320]  r7:00001003 r6:00001042 r5:edb0de20 r4:edd1a000
>> [   55.369023] [<c03d9bf0>] (__dev_close_many) from [<c03d9df4>]
>> (__dev_close+0x30/0x48)
>> [   55.376880]  r5:00000001 r4:edd1a000
>> [   55.380480] [<c03d9dc4>] (__dev_close) from [<c03e175c>]
>> (__dev_change_flags+0x9c/0x14c)
>> [   55.388602] [<c03e16c0>] (__dev_change_flags) from [<c03e182c>]
>> (dev_change_flags+0x20/0
>> x50)
>> [   55.397069]  r9:edf34400 r8:00000000 r7:00000000 r6:00001003
>> r5:edd1a138
>> r4:edd1a000
>> [   55.404875] [<c03e180c>] (dev_change_flags) from [<c0446f94>]
>> (devinet_ioctl+0x680/0x754
>> )
>> [   55.413080]  r9:edf34400 r8:bef6af3c r7:00000000 r6:bef6ac64
>> r5:edf3440c
>> r4:00000000
>> [   55.420882] [<c0446914>] (devinet_ioctl) from [<c0448760>]
>> (inet_ioctl+0x1a8/0x1d0)
>> [   55.428564]  r10:00000000 r9:edb0c000 r8:bef6ac64 r7:00000003
>> r6:bef6ac64 r5:bef6ac64
>> [   55.436449]  r4:00008914
>> [   55.438996] [<c04485b8>] (inet_ioctl) from [<c03c72fc>]
>> (sock_ioctl+0x1d0/0x2a8)
>> [   55.446423] [<c03c712c>] (sock_ioctl) from [<c00eb608>]
>> (do_vfs_ioctl+0x414/0x604)
>> [   55.454018]  r7:00000003 r6:ed8b60c0 r5:bef6ac64 r4:ccc88f20
>> [   55.459721] [<c00eb1f4>] (do_vfs_ioctl) from [<c00eb834>]
>> (SyS_ioctl+0x3c/0x64)
>> [   55.467055]  r9:edb0c000 r8:bef6ac64 r7:00008914 r6:ed8b60c0
>> r5:00000003
>> r4:ed8b60c0
>> [   55.474858] [<c00eb7f8>] (SyS_ioctl) from [<c000f780>]
>> (ret_fast_syscall+0x0/0x3c)
>> [   55.482452]  r9:edb0c000 r8:c000f924 r7:00000036 r6:0007e77c
>> r5:bef6ac64
>> r4:0007e7d0
>> [   55.490252] ---[ end trace f565594c905af0b4 ]---
>>
>> Signed-off-by: Murali Karicheri <m-karicheri2 at ti.com>
>> ---
>>   - v1 - added all of the call trace per comment
>>   - Applies to v4.2.0-rc8
>>
> Thanks Murali. I will drop time stamp while applying it.
>
> Regards,
> Santosh
>
>
Ok. Thanks
-- 
Murali Karicheri
Linux Kernel, Keystone


From robherring2 at gmail.com  Fri Aug 28 07:02:35 2015
From: robherring2 at gmail.com (Rob Herring)
Date: Fri, 28 Aug 2015 09:02:35 -0500
Subject: [PATCH v5 2/4] Documentation: arm64/arm: dt bindings for numa.
In-Reply-To: <20150828123228.GE31748@leverpostej>
References: <1439570374-4079-1-git-send-email-gkulkarni@caviumnetworks.com>
 <1439570374-4079-3-git-send-email-gkulkarni@caviumnetworks.com>
 <20150828123228.GE31748@leverpostej>
Message-ID: <CAL_JsqLOpUTVeKbkJ6uPi0EYistd=BowAHdtSmaUYYDhU6c9Sg@mail.gmail.com>

+benh

On Fri, Aug 28, 2015 at 7:32 AM, Mark Rutland <mark.rutland at arm.com> wrote:
> Hi,
>
> On Fri, Aug 14, 2015 at 05:39:32PM +0100, Ganapatrao Kulkarni wrote:
>> DT bindings for numa map for memory, cores and IOs using
>> arm,associativity device node property.
>
> Given this is just a copy of ibm,associativity, I'm not sure I see much
> point in renaming the properties.

So just keep the ibm? I'm okay with that. That would help move to
common code. Alternatively, we could drop the vendor prefix and have
common code just check for both.

>
> However, (somewhat counter to that) I'm also concerned that this isn't
> sufficient for systems we're beginning to see today (more on that
> below), so I don't think a simple copy of ibm,associativity is good
> enough.
>
>>
>> Signed-off-by: Ganapatrao Kulkarni <gkulkarni at caviumnetworks.com>
>> ---
>>  Documentation/devicetree/bindings/arm/numa.txt | 212 +++++++++++++++++++++++++
>>  1 file changed, 212 insertions(+)
>>  create mode 100644 Documentation/devicetree/bindings/arm/numa.txt
>>
>> diff --git a/Documentation/devicetree/bindings/arm/numa.txt b/Documentation/devicetree/bindings/arm/numa.txt
>> new file mode 100644
>> index 0000000..dc3ef86
>> --- /dev/null
>> +++ b/Documentation/devicetree/bindings/arm/numa.txt
>> @@ -0,0 +1,212 @@
>> +==============================================================================
>> +NUMA binding description.
>> +==============================================================================
>> +
>> +==============================================================================
>> +1 - Introduction
>> +==============================================================================
>> +
>> +Systems employing a Non Uniform Memory Access (NUMA) architecture contain
>> +collections of hardware resources including processors, memory, and I/O buses,
>> +that comprise what is commonly known as a NUMA node.
>> +Processor accesses to memory within the local NUMA node is generally faster
>> +than processor accesses to memory outside of the local NUMA node.
>> +DT defines interfaces that allow the platform to convey NUMA node
>> +topology information to OS.
>> +
>> +==============================================================================
>> +2 - arm,associativity
>> +==============================================================================
>> +The mapping is done using arm,associativity device property.
>> +this property needs to be present in every device node which needs to to be
>> +mapped to numa nodes.
>
> Can't there be some inheritance? e.g. all devices on a bus with an
> arm,associativity property being assumed to share that value?

There is actually already based on kernel code. So the documentation
just needs to be explicit.

>
>> +
>> +arm,associativity property is set of 32-bit integers which defines level of
>
> s/set/list/ -- the order is important.
>
>> +topology and boundary in the system at which a significant difference in
>> +performance can be measured between cross-device accesses within
>> +a single location and those spanning multiple locations.
>> +The first cell always contains the broadest subdivision within the system,
>> +while the last cell enumerates the individual devices, such as an SMT thread
>> +of a CPU, or a bus bridge within an SoC".
>
> While this gives us some hierarchy, this doesn't seem to encode relative
> distances at all. That seems like an oversight.
>
> Additionally, I'm somewhat unclear on how what you'd be expected to
> provide for this property in cases like ring or mesh interconnects,
> where there isn't a strict hierarchy (see systems with ARM's own CCN, or
> Tilera's TILE-Mx), but there is some measure of closeness.
>
> Must all of these have the same length? If so, why not have a
> #(whatever)-cells property in the root to describe the expected length?
> If not, how are they to be interpreted relative to each other?

All points that could be asked of the IBM binding. Perhaps Arnd or Ben
can provide some insight or know who can?

Rob


From msalter at redhat.com  Fri Aug 28 07:29:46 2015
From: msalter at redhat.com (Mark Salter)
Date: Fri, 28 Aug 2015 10:29:46 -0400
Subject: [PATCH] ARM64: kernel: implement ACPI parking protocol
In-Reply-To: <20150828102314.GC15924@red-moon>
References: <1436959990-32054-1-git-send-email-lorenzo.pieralisi@arm.com>
 <1437063431.3583.2.camel@redhat.com> <20150716171221.GB18582@red-moon>
 <1437068449.3583.4.camel@redhat.com> <20150828102314.GC15924@red-moon>
Message-ID: <1440772186.31961.8.camel@redhat.com>

On Fri, 2015-08-28 at 11:23 +0100, Lorenzo Pieralisi wrote:
> Mark,
> 
> On Thu, Jul 16, 2015 at 06:40:49PM +0100, Mark Salter wrote:
> 
> [...]
> 
> > On Thu, 2015-07-16 at 18:12 +0100, Lorenzo Pieralisi wrote:
> > > > The kernel will only add cached memory regions to linear mapping 
> > > > and
> > > > presumably, the FW will mark the mailboxes as uncached. Otherwise, 
> > > > it
> > > > is a FW bug. But I suppose we could run into problems with kernels
> > > > using 64K pagesize since firmware assumes 4k.
> > > 
> > > Nope, ioremap takes care of that, everything should be fine.
> > 
> > The mailbox is 4K. If it is next to a cached UEFI region, the kernel 
> > may
> > have to overlap the mailbox with a cached 64K mapping in order to 
> > include
> > the adjoining UEFI region in the linear map. Then the ioremap would 
> > fail
> > because the mailbox is included in the linear mapping.
> 
> So that I understand: are you referring to memrange_efi_to_native()
> in arch/arm64/kernel/efi.c ? Is it safe to round up (and add it to
> the memblock layer) the memory region size to PAGE_SIZE without checking
> attributes of overlapping (within PAGE_SIZE) UEFI regions ?

The problem is that nothing in the UEFI spec or parking protocol spec
prevents firmware from placing a 4K parking protocol mailbox area in
the same 64K page as normal cached memory which winds up mapped in
the kernel linear mapping. The kernel might be able to work around
that by not putting the 64K page in the linear map. There's nothing
the kernel could do if the mailbox is in same 64K page with UEFI runtime
memory which would use a cached mapping.



From julien.grall at citrix.com  Fri Aug 28 07:29:19 2015
From: julien.grall at citrix.com (Julien Grall)
Date: Fri, 28 Aug 2015 15:29:19 +0100
Subject: [Xen-devel] [PATCH v3 04/20] xen/grant: Introduce helpers to
 split a page into grant
In-Reply-To: <55D5A337.7090704@citrix.com>
References: <1438966019-19322-1-git-send-email-julien.grall@citrix.com>
 <1438966019-19322-5-git-send-email-julien.grall@citrix.com>
 <55D5A337.7090704@citrix.com>
Message-ID: <55E0703F.5060003@citrix.com>

Hi David,

On 20/08/15 10:51, David Vrabel wrote:
> On 07/08/15 17:46, Julien Grall wrote:
>> Currently, a grant is always based on the Xen page granularity (i.e
>> 4KB). When Linux is using a different page granularity, a single page
>> will be split between multiple grants.
>>
>> The new helpers will be in charge to split the Linux page into grants and
>> call a function given by the caller on each grant.
>>
>> Also provide an helper to count the number of grants within a given
>> contiguous region.
>>
>> Note that the x86/include/asm/xen/page.h is now including
>> xen/interface/grant_table.h rather than xen/grant_table.h. It's
>> necessary because xen/grant_table.h depends on asm/xen/page.h and will
>> break the compilation. Furthermore, only definition in
>> interface/grant_table.h was required.
> 
> Reviewed-by: David Vrabel <david.vrabel at citrix.com>
> But...
> 
>> +/* Helper to get to call fn only on the first "grant chunk" */
>> +static inline void gnttab_one_grant(struct page *page, unsigned int offset,
>> +				    unsigned len, xen_grant_fn_t fn,
>> +				    void *data)
> 
> ...call this gnttab_for_one_grant().

Will rename it on the next version.

Regards,

-- 
Julien Grall


From matthias.bgg at gmail.com  Fri Aug 28 07:31:50 2015
From: matthias.bgg at gmail.com (Matthias Brugger)
Date: Fri, 28 Aug 2015 16:31:50 +0200
Subject: [PATCH v5 0/8] arm64, numa: Add numa support for arm64 platforms.
In-Reply-To: <1439570374-4079-1-git-send-email-gkulkarni@caviumnetworks.com>
References: <1439570374-4079-1-git-send-email-gkulkarni@caviumnetworks.com>
Message-ID: <55E070D6.8060604@gmail.com>



On 14/08/15 18:39, Ganapatrao Kulkarni wrote:
> v5:
> 	- created base verion of numa.c which creates dummy numa without using dt
> 	  on single socket platforms. Then added patches for dt support.
> 	- Incorporated review comments from Hanjun Guo.
>
> v4:
> done changes as per Arnd review comments.
>
> v3:
> Added changes to support numa on arm64 based platforms.
> Tested these patches on cavium's multinode(2 node topology) platform.
> In this patchset, defined and implemented dt bindings for numa mapping
> for core and memory using device node property arm,associativity.
>
> v2:
> Defined and implemented numa map for memory, cores to node and
> proximity distance matrix of nodes.
>
> v1:
> Initial patchset to support numa on arm64 platforms.
>
> Note:
> 	1. This patchset is tested for numa with dt on
> 	   thunderx single socket and dual socket boards.
> 	2. Numa DT booting needs the dt memory nodes, which are deleted in current efi-stub,
> 	hence to try numa with dt, you need to rebase with ard's patchset.
> 	http://git.linaro.org/people/ard.biesheuvel/linux-arm.git/shortlog/refs/heads/arm64-uefi-early-fdt-handling
>
>
> Ganapatrao Kulkarni (4):
>    arm64, numa: adding numa support for arm64 platforms.
>    Documentation: arm64/arm: dt bindings for numa.
>    arm64, numa: adding numa support for arm64 platforms.
>    arm64, dt, thunderx: Add initial dts for Cavium Thunder SoC in 2 Node
>      topology.
>
>   Documentation/devicetree/bindings/arm/numa.txt  | 212 +++++++
>   arch/arm64/Kconfig                              |  32 +
>   arch/arm64/boot/dts/cavium/Makefile             |   2 +-
>   arch/arm64/boot/dts/cavium/thunder-88xx-2n.dts  |  78 +++
>   arch/arm64/boot/dts/cavium/thunder-88xx-2n.dtsi | 790 ++++++++++++++++++++++++
>   arch/arm64/include/asm/mmzone.h                 |  32 +
>   arch/arm64/include/asm/numa.h                   |  49 ++
>   arch/arm64/kernel/Makefile                      |   1 +
>   arch/arm64/kernel/dt_numa.c                     | 316 ++++++++++
>   arch/arm64/kernel/setup.c                       |   9 +
>   arch/arm64/kernel/smp.c                         |   3 +
>   arch/arm64/mm/Makefile                          |   1 +
>   arch/arm64/mm/init.c                            |  34 +-
>   arch/arm64/mm/numa.c                            | 563 +++++++++++++++++
>   14 files changed, 2115 insertions(+), 7 deletions(-)
>   create mode 100644 Documentation/devicetree/bindings/arm/numa.txt
>   create mode 100644 arch/arm64/boot/dts/cavium/thunder-88xx-2n.dts
>   create mode 100644 arch/arm64/boot/dts/cavium/thunder-88xx-2n.dtsi
>   create mode 100644 arch/arm64/include/asm/mmzone.h
>   create mode 100644 arch/arm64/include/asm/numa.h
>   create mode 100644 arch/arm64/kernel/dt_numa.c
>   create mode 100644 arch/arm64/mm/numa.c
>

On which version is this patch-set based?

Regards,
Matthias


From matt at codeblueprint.co.uk  Fri Aug 28 07:43:58 2015
From: matt at codeblueprint.co.uk (Matt Fleming)
Date: Fri, 28 Aug 2015 15:43:58 +0100
Subject: [PATCH v2] x86, efi, kasan: #undef memset/memcpy/memmove per arch.
In-Reply-To: <1440760199-18111-1-git-send-email-ryabinin.a.a@gmail.com>
References: <20150828062745.GB1928@gmail.com>
 <1440760199-18111-1-git-send-email-ryabinin.a.a@gmail.com>
Message-ID: <20150828144358.GI2759@codeblueprint.co.uk>

On Fri, 28 Aug, at 02:09:59PM, Andrey Ryabinin wrote:
> In not-instrumented code KASAN replaces instrumented
> memset/memcpy/memmove with not-instrumented analogues
> __memset/__memcpy/__memove.
> However, on x86 the EFI stub is not linked with the kernel.
> It uses not-instrumented mem*() functions from
> arch/x86/boot/compressed/string.c
> So we don't replace them with __mem*() variants in EFI stub.
> 
> On ARM64 the EFI stub is linked with the kernel, so we should
> replace mem*() functions with __mem*(), because the EFI stub
> runs before KASAN sets up early shadow.
> 
> So let's move these #undef mem* into arch's asm/efi.h which is
> also included by the EFI stub.
> 
> Signed-off-by: Andrey Ryabinin <ryabinin.a.a at gmail.com>
> ---
>  arch/x86/include/asm/efi.h             | 11 +++++++++++
>  drivers/firmware/efi/libstub/efistub.h |  4 ----
>  2 files changed, 11 insertions(+), 4 deletions(-)
> 
> diff --git a/arch/x86/include/asm/efi.h b/arch/x86/include/asm/efi.h
> index 155162e..6862f11 100644
> --- a/arch/x86/include/asm/efi.h
> +++ b/arch/x86/include/asm/efi.h
> @@ -25,6 +25,17 @@
>  #define EFI32_LOADER_SIGNATURE	"EL32"
>  #define EFI64_LOADER_SIGNATURE	"EL64"
>  
> +/*
> + * Sometimes we may redefine memset to __memset.
> + * The EFI stub doesn't have __memset() because it's not
> + * linked with the kernel. So we should use standard
> + * memset from arch/x86/boot/compressed/string.c
> + * The same applies to memcpy and memmove.
> + */
> +#undef memcpy
> +#undef memset
> +#undef memmove
> +

I think the key piece of information missing in this comment is that
it's redefined for KASAN, right?

>  #ifdef CONFIG_X86_32
>  
>  
> diff --git a/drivers/firmware/efi/libstub/efistub.h b/drivers/firmware/efi/libstub/efistub.h
> index e334a01..6b6548f 100644
> --- a/drivers/firmware/efi/libstub/efistub.h
> +++ b/drivers/firmware/efi/libstub/efistub.h
> @@ -5,10 +5,6 @@
>  /* error code which can't be mistaken for valid address */
>  #define EFI_ERROR	(~0UL)
>  
> -#undef memcpy
> -#undef memset
> -#undef memmove
> -
>  void efi_char16_printk(efi_system_table_t *, efi_char16_t *);
>  
>  efi_status_t efi_open_volume(efi_system_table_t *sys_table_arg, void *__image,

Does this patch have any negative consequences for arm64? Can we
safely remove these #undefs without breaking the arm64 EFI stub?

-- 
Matt Fleming, Intel Open Source Technology Center


From ryabinin.a.a at gmail.com  Fri Aug 28 07:57:14 2015
From: ryabinin.a.a at gmail.com (Andrey Ryabinin)
Date: Fri, 28 Aug 2015 17:57:14 +0300
Subject: [PATCH v2] x86, efi, kasan: #undef memset/memcpy/memmove per arch.
In-Reply-To: <20150828144358.GI2759@codeblueprint.co.uk>
References: <20150828062745.GB1928@gmail.com>
 <1440760199-18111-1-git-send-email-ryabinin.a.a@gmail.com>
 <20150828144358.GI2759@codeblueprint.co.uk>
Message-ID: <CAPAsAGwDQC36yRRPGVqSp6Fy5o2xgO6g7j8Bz_BysMJJAriv3g@mail.gmail.com>

2015-08-28 17:43 GMT+03:00 Matt Fleming <matt at codeblueprint.co.uk>:
> On Fri, 28 Aug, at 02:09:59PM, Andrey Ryabinin wrote:
>> In not-instrumented code KASAN replaces instrumented
>> memset/memcpy/memmove with not-instrumented analogues
>> __memset/__memcpy/__memove.
>> However, on x86 the EFI stub is not linked with the kernel.
>> It uses not-instrumented mem*() functions from
>> arch/x86/boot/compressed/string.c
>> So we don't replace them with __mem*() variants in EFI stub.
>>
>> On ARM64 the EFI stub is linked with the kernel, so we should
>> replace mem*() functions with __mem*(), because the EFI stub
>> runs before KASAN sets up early shadow.
>>
>> So let's move these #undef mem* into arch's asm/efi.h which is
>> also included by the EFI stub.
>>
>> Signed-off-by: Andrey Ryabinin <ryabinin.a.a at gmail.com>
>> ---
>>  arch/x86/include/asm/efi.h             | 11 +++++++++++
>>  drivers/firmware/efi/libstub/efistub.h |  4 ----
>>  2 files changed, 11 insertions(+), 4 deletions(-)
>>
>> diff --git a/arch/x86/include/asm/efi.h b/arch/x86/include/asm/efi.h
>> index 155162e..6862f11 100644
>> --- a/arch/x86/include/asm/efi.h
>> +++ b/arch/x86/include/asm/efi.h
>> @@ -25,6 +25,17 @@
>>  #define EFI32_LOADER_SIGNATURE       "EL32"
>>  #define EFI64_LOADER_SIGNATURE       "EL64"
>>
>> +/*
>> + * Sometimes we may redefine memset to __memset.
>> + * The EFI stub doesn't have __memset() because it's not
>> + * linked with the kernel. So we should use standard
>> + * memset from arch/x86/boot/compressed/string.c
>> + * The same applies to memcpy and memmove.
>> + */
>> +#undef memcpy
>> +#undef memset
>> +#undef memmove
>> +
>
> I think the key piece of information missing in this comment is that
> it's redefined for KASAN, right?
>

Right.

>>  #ifdef CONFIG_X86_32
>>
>>
>> diff --git a/drivers/firmware/efi/libstub/efistub.h b/drivers/firmware/efi/libstub/efistub.h
>> index e334a01..6b6548f 100644
>> --- a/drivers/firmware/efi/libstub/efistub.h
>> +++ b/drivers/firmware/efi/libstub/efistub.h
>> @@ -5,10 +5,6 @@
>>  /* error code which can't be mistaken for valid address */
>>  #define EFI_ERROR    (~0UL)
>>
>> -#undef memcpy
>> -#undef memset
>> -#undef memmove
>> -
>>  void efi_char16_printk(efi_system_table_t *, efi_char16_t *);
>>
>>  efi_status_t efi_open_volume(efi_system_table_t *sys_table_arg, void *__image,
>
> Does this patch have any negative consequences for arm64? Can we
> safely remove these #undefs without breaking the arm64 EFI stub?
>

The whole point of this patch is to remove these #undefs on ARM64.
Otherwise we end up calling instrumented memset, which will access to
kasan shadow,
before we set it up
So on ARM64 we should use not-instumented __memset on ARM64, iow we
need to keep #define memset __memset.

> --
> Matt Fleming, Intel Open Source Technology Center


From gpkulkarni at gmail.com  Fri Aug 28 07:59:05 2015
From: gpkulkarni at gmail.com (Ganapatrao Kulkarni)
Date: Fri, 28 Aug 2015 20:29:05 +0530
Subject: [PATCH v5 0/8] arm64, numa: Add numa support for arm64 platforms.
In-Reply-To: <55E070D6.8060604@gmail.com>
References: <1439570374-4079-1-git-send-email-gkulkarni@caviumnetworks.com>
 <55E070D6.8060604@gmail.com>
Message-ID: <CAFpQJXUYycrvxp_p=A_pmeNUpHVs=8kYUfZP9dYDhYLqeCTZ3Q@mail.gmail.com>

On Fri, Aug 28, 2015 at 8:01 PM, Matthias Brugger
<matthias.bgg at gmail.com> wrote:
>
>
> On 14/08/15 18:39, Ganapatrao Kulkarni wrote:
>>
>> v5:
>>         - created base verion of numa.c which creates dummy numa without
>> using dt
>>           on single socket platforms. Then added patches for dt support.
>>         - Incorporated review comments from Hanjun Guo.
>>
>> v4:
>> done changes as per Arnd review comments.
>>
>> v3:
>> Added changes to support numa on arm64 based platforms.
>> Tested these patches on cavium's multinode(2 node topology) platform.
>> In this patchset, defined and implemented dt bindings for numa mapping
>> for core and memory using device node property arm,associativity.
>>
>> v2:
>> Defined and implemented numa map for memory, cores to node and
>> proximity distance matrix of nodes.
>>
>> v1:
>> Initial patchset to support numa on arm64 platforms.
>>
>> Note:
>>         1. This patchset is tested for numa with dt on
>>            thunderx single socket and dual socket boards.
>>         2. Numa DT booting needs the dt memory nodes, which are deleted in
>> current efi-stub,
>>         hence to try numa with dt, you need to rebase with ard's patchset.
>>
>> http://git.linaro.org/people/ard.biesheuvel/linux-arm.git/shortlog/refs/heads/arm64-uefi-early-fdt-handling
>>
>>
>> Ganapatrao Kulkarni (4):
>>    arm64, numa: adding numa support for arm64 platforms.
>>    Documentation: arm64/arm: dt bindings for numa.
>>    arm64, numa: adding numa support for arm64 platforms.
>>    arm64, dt, thunderx: Add initial dts for Cavium Thunder SoC in 2 Node
>>      topology.
>>
>>   Documentation/devicetree/bindings/arm/numa.txt  | 212 +++++++
>>   arch/arm64/Kconfig                              |  32 +
>>   arch/arm64/boot/dts/cavium/Makefile             |   2 +-
>>   arch/arm64/boot/dts/cavium/thunder-88xx-2n.dts  |  78 +++
>>   arch/arm64/boot/dts/cavium/thunder-88xx-2n.dtsi | 790
>> ++++++++++++++++++++++++
>>   arch/arm64/include/asm/mmzone.h                 |  32 +
>>   arch/arm64/include/asm/numa.h                   |  49 ++
>>   arch/arm64/kernel/Makefile                      |   1 +
>>   arch/arm64/kernel/dt_numa.c                     | 316 ++++++++++
>>   arch/arm64/kernel/setup.c                       |   9 +
>>   arch/arm64/kernel/smp.c                         |   3 +
>>   arch/arm64/mm/Makefile                          |   1 +
>>   arch/arm64/mm/init.c                            |  34 +-
>>   arch/arm64/mm/numa.c                            | 563 +++++++++++++++++
>>   14 files changed, 2115 insertions(+), 7 deletions(-)
>>   create mode 100644 Documentation/devicetree/bindings/arm/numa.txt
>>   create mode 100644 arch/arm64/boot/dts/cavium/thunder-88xx-2n.dts
>>   create mode 100644 arch/arm64/boot/dts/cavium/thunder-88xx-2n.dtsi
>>   create mode 100644 arch/arm64/include/asm/mmzone.h
>>   create mode 100644 arch/arm64/include/asm/numa.h
>>   create mode 100644 arch/arm64/kernel/dt_numa.c
>>   create mode 100644 arch/arm64/mm/numa.c
>>
>
> On which version is this patch-set based?
4.2 -rc5
>
> Regards,
> Matthias

thanks
Ganapat


From aleksey.makarov at auriga.com  Fri Aug 28 07:59:53 2015
From: aleksey.makarov at auriga.com (Aleksey Makarov)
Date: Fri, 28 Aug 2015 17:59:53 +0300
Subject: [PATCH net-next 1/8] net: thunderx: fix MAINTAINERS
Message-ID: <1440774004-27923-1-git-send-email-aleksey.makarov@auriga.com>

From: Aleksey Makarov <aleksey.makarov at caviumnetworks.com>

The liquidio and thunder drivers have different maintainers.

Signed-off-by: Aleksey Makarov <aleksey.makarov at caviumnetworks.com>
---
 MAINTAINERS | 3 +--
 1 file changed, 1 insertion(+), 2 deletions(-)

diff --git a/MAINTAINERS b/MAINTAINERS
index 4e6dcb6..43cf79e 100644
--- a/MAINTAINERS
+++ b/MAINTAINERS
@@ -928,7 +928,7 @@ M:	Sunil Goutham <sgoutham at cavium.com>
 M:	Robert Richter <rric at kernel.org>
 L:	linux-arm-kernel at lists.infradead.org (moderated for non-subscribers)
 S:	Supported
-F:	drivers/net/ethernet/cavium/
+F:	drivers/net/ethernet/cavium/thunder/
 
 ARM/CIRRUS LOGIC CLPS711X ARM ARCHITECTURE
 M:	Alexander Shiyan <shc_work at mail.ru>
@@ -2543,7 +2543,6 @@ M:     Raghu Vatsavayi <raghu.vatsavayi at caviumnetworks.com>
 L:     netdev at vger.kernel.org
 W:     http://www.cavium.com
 S:     Supported
-F:     drivers/net/ethernet/cavium/
 F:     drivers/net/ethernet/cavium/liquidio/
 
 CC2520 IEEE-802.15.4 RADIO DRIVER
-- 
2.5.0



From aleksey.makarov at auriga.com  Fri Aug 28 07:59:54 2015
From: aleksey.makarov at auriga.com (Aleksey Makarov)
Date: Fri, 28 Aug 2015 17:59:54 +0300
Subject: [PATCH net-next 2/8] net: thunderx: Add receive error stats reporting
 via ethtool
In-Reply-To: <1440774004-27923-1-git-send-email-aleksey.makarov@auriga.com>
References: <1440774004-27923-1-git-send-email-aleksey.makarov@auriga.com>
Message-ID: <1440774004-27923-2-git-send-email-aleksey.makarov@auriga.com>

From: Sunil Goutham <sgoutham at cavium.com>

Added ethtool support to dump receive packet error statistics reported
in CQE. Also made some small fixes

Signed-off-by: Sunil Goutham <sgoutham at cavium.com>
Signed-off-by: Aleksey Makarov <aleksey.makarov at caviumnetworks.com>
---
 drivers/net/ethernet/cavium/thunder/nic.h          | 36 +++++++--
 .../net/ethernet/cavium/thunder/nicvf_ethtool.c    | 34 +++++++--
 drivers/net/ethernet/cavium/thunder/nicvf_main.c   | 26 ++++---
 drivers/net/ethernet/cavium/thunder/nicvf_queues.c | 86 +++++++---------------
 drivers/net/ethernet/cavium/thunder/nicvf_queues.h | 41 -----------
 5 files changed, 103 insertions(+), 120 deletions(-)

diff --git a/drivers/net/ethernet/cavium/thunder/nic.h b/drivers/net/ethernet/cavium/thunder/nic.h
index 8aee250..58adfd6 100644
--- a/drivers/net/ethernet/cavium/thunder/nic.h
+++ b/drivers/net/ethernet/cavium/thunder/nic.h
@@ -190,10 +190,10 @@ enum tx_stats_reg_offset {
 };
 
 struct nicvf_hw_stats {
-	u64 rx_bytes_ok;
-	u64 rx_ucast_frames_ok;
-	u64 rx_bcast_frames_ok;
-	u64 rx_mcast_frames_ok;
+	u64 rx_bytes;
+	u64 rx_ucast_frames;
+	u64 rx_bcast_frames;
+	u64 rx_mcast_frames;
 	u64 rx_fcs_errors;
 	u64 rx_l2_errors;
 	u64 rx_drop_red;
@@ -204,6 +204,31 @@ struct nicvf_hw_stats {
 	u64 rx_drop_mcast;
 	u64 rx_drop_l3_bcast;
 	u64 rx_drop_l3_mcast;
+	u64 rx_bgx_truncated_pkts;
+	u64 rx_jabber_errs;
+	u64 rx_fcs_errs;
+	u64 rx_bgx_errs;
+	u64 rx_prel2_errs;
+	u64 rx_l2_hdr_malformed;
+	u64 rx_oversize;
+	u64 rx_undersize;
+	u64 rx_l2_len_mismatch;
+	u64 rx_l2_pclp;
+	u64 rx_ip_ver_errs;
+	u64 rx_ip_csum_errs;
+	u64 rx_ip_hdr_malformed;
+	u64 rx_ip_payload_malformed;
+	u64 rx_ip_ttl_errs;
+	u64 rx_l3_pclp;
+	u64 rx_l4_malformed;
+	u64 rx_l4_csum_errs;
+	u64 rx_udp_len_errs;
+	u64 rx_l4_port_errs;
+	u64 rx_tcp_flag_errs;
+	u64 rx_tcp_offset_errs;
+	u64 rx_l4_pclp;
+	u64 rx_truncated_pkts;
+
 	u64 tx_bytes_ok;
 	u64 tx_ucast_frames_ok;
 	u64 tx_bcast_frames_ok;
@@ -222,6 +247,7 @@ struct nicvf_drv_stats {
 	u64 rx_frames_1518;
 	u64 rx_frames_jumbo;
 	u64 rx_drops;
+
 	/* Tx */
 	u64 tx_frames_ok;
 	u64 tx_drops;
@@ -257,7 +283,7 @@ struct nicvf {
 	u32			cq_coalesce_usecs;
 
 	u32			msg_enable;
-	struct nicvf_hw_stats   stats;
+	struct nicvf_hw_stats   hw_stats;
 	struct nicvf_drv_stats  drv_stats;
 	struct bgx_stats	bgx_stats;
 	struct work_struct	reset_task;
diff --git a/drivers/net/ethernet/cavium/thunder/nicvf_ethtool.c b/drivers/net/ethernet/cavium/thunder/nicvf_ethtool.c
index a4228e6..a961aa3 100644
--- a/drivers/net/ethernet/cavium/thunder/nicvf_ethtool.c
+++ b/drivers/net/ethernet/cavium/thunder/nicvf_ethtool.c
@@ -35,10 +35,10 @@ struct nicvf_stat {
 }
 
 static const struct nicvf_stat nicvf_hw_stats[] = {
-	NICVF_HW_STAT(rx_bytes_ok),
-	NICVF_HW_STAT(rx_ucast_frames_ok),
-	NICVF_HW_STAT(rx_bcast_frames_ok),
-	NICVF_HW_STAT(rx_mcast_frames_ok),
+	NICVF_HW_STAT(rx_bytes),
+	NICVF_HW_STAT(rx_ucast_frames),
+	NICVF_HW_STAT(rx_bcast_frames),
+	NICVF_HW_STAT(rx_mcast_frames),
 	NICVF_HW_STAT(rx_fcs_errors),
 	NICVF_HW_STAT(rx_l2_errors),
 	NICVF_HW_STAT(rx_drop_red),
@@ -49,6 +49,30 @@ static const struct nicvf_stat nicvf_hw_stats[] = {
 	NICVF_HW_STAT(rx_drop_mcast),
 	NICVF_HW_STAT(rx_drop_l3_bcast),
 	NICVF_HW_STAT(rx_drop_l3_mcast),
+	NICVF_HW_STAT(rx_bgx_truncated_pkts),
+	NICVF_HW_STAT(rx_jabber_errs),
+	NICVF_HW_STAT(rx_fcs_errs),
+	NICVF_HW_STAT(rx_bgx_errs),
+	NICVF_HW_STAT(rx_prel2_errs),
+	NICVF_HW_STAT(rx_l2_hdr_malformed),
+	NICVF_HW_STAT(rx_oversize),
+	NICVF_HW_STAT(rx_undersize),
+	NICVF_HW_STAT(rx_l2_len_mismatch),
+	NICVF_HW_STAT(rx_l2_pclp),
+	NICVF_HW_STAT(rx_ip_ver_errs),
+	NICVF_HW_STAT(rx_ip_csum_errs),
+	NICVF_HW_STAT(rx_ip_hdr_malformed),
+	NICVF_HW_STAT(rx_ip_payload_malformed),
+	NICVF_HW_STAT(rx_ip_ttl_errs),
+	NICVF_HW_STAT(rx_l3_pclp),
+	NICVF_HW_STAT(rx_l4_malformed),
+	NICVF_HW_STAT(rx_l4_csum_errs),
+	NICVF_HW_STAT(rx_udp_len_errs),
+	NICVF_HW_STAT(rx_l4_port_errs),
+	NICVF_HW_STAT(rx_tcp_flag_errs),
+	NICVF_HW_STAT(rx_tcp_offset_errs),
+	NICVF_HW_STAT(rx_l4_pclp),
+	NICVF_HW_STAT(rx_truncated_pkts),
 	NICVF_HW_STAT(tx_bytes_ok),
 	NICVF_HW_STAT(tx_ucast_frames_ok),
 	NICVF_HW_STAT(tx_bcast_frames_ok),
@@ -195,7 +219,7 @@ static void nicvf_get_ethtool_stats(struct net_device *netdev,
 	nicvf_update_lmac_stats(nic);
 
 	for (stat = 0; stat < nicvf_n_hw_stats; stat++)
-		*(data++) = ((u64 *)&nic->stats)
+		*(data++) = ((u64 *)&nic->hw_stats)
 				[nicvf_hw_stats[stat].index];
 	for (stat = 0; stat < nicvf_n_drv_stats; stat++)
 		*(data++) = ((u64 *)&nic->drv_stats)
diff --git a/drivers/net/ethernet/cavium/thunder/nicvf_main.c b/drivers/net/ethernet/cavium/thunder/nicvf_main.c
index 3b90afb..670ff9b 100644
--- a/drivers/net/ethernet/cavium/thunder/nicvf_main.c
+++ b/drivers/net/ethernet/cavium/thunder/nicvf_main.c
@@ -456,6 +456,12 @@ static void nicvf_rcv_pkt_handler(struct net_device *netdev,
 			       skb->data, skb->len, true);
 	}
 
+	/* If error packet, drop it here */
+	if (err) {
+		dev_kfree_skb_any(skb);
+		return;
+	}
+
 	nicvf_set_rx_frame_cnt(nic, skb);
 
 	skb_record_rx_queue(skb, cqe_rx->rq_idx);
@@ -1118,7 +1124,7 @@ void nicvf_update_lmac_stats(struct nicvf *nic)
 void nicvf_update_stats(struct nicvf *nic)
 {
 	int qidx;
-	struct nicvf_hw_stats *stats = &nic->stats;
+	struct nicvf_hw_stats *stats = &nic->hw_stats;
 	struct nicvf_drv_stats *drv_stats = &nic->drv_stats;
 	struct queue_set *qs = nic->qs;
 
@@ -1127,14 +1133,16 @@ void nicvf_update_stats(struct nicvf *nic)
 #define GET_TX_STATS(reg) \
 	nicvf_reg_read(nic, NIC_VNIC_TX_STAT_0_4 | (reg << 3))
 
-	stats->rx_bytes_ok = GET_RX_STATS(RX_OCTS);
-	stats->rx_ucast_frames_ok = GET_RX_STATS(RX_UCAST);
-	stats->rx_bcast_frames_ok = GET_RX_STATS(RX_BCAST);
-	stats->rx_mcast_frames_ok = GET_RX_STATS(RX_MCAST);
+	stats->rx_bytes = GET_RX_STATS(RX_OCTS);
+	stats->rx_ucast_frames = GET_RX_STATS(RX_UCAST);
+	stats->rx_bcast_frames = GET_RX_STATS(RX_BCAST);
+	stats->rx_mcast_frames = GET_RX_STATS(RX_MCAST);
 	stats->rx_fcs_errors = GET_RX_STATS(RX_FCS);
 	stats->rx_l2_errors = GET_RX_STATS(RX_L2ERR);
 	stats->rx_drop_red = GET_RX_STATS(RX_RED);
+	stats->rx_drop_red_bytes = GET_RX_STATS(RX_RED_OCTS);
 	stats->rx_drop_overrun = GET_RX_STATS(RX_ORUN);
+	stats->rx_drop_overrun_bytes = GET_RX_STATS(RX_ORUN_OCTS);
 	stats->rx_drop_bcast = GET_RX_STATS(RX_DRP_BCAST);
 	stats->rx_drop_mcast = GET_RX_STATS(RX_DRP_MCAST);
 	stats->rx_drop_l3_bcast = GET_RX_STATS(RX_DRP_L3BCAST);
@@ -1146,9 +1154,6 @@ void nicvf_update_stats(struct nicvf *nic)
 	stats->tx_mcast_frames_ok = GET_TX_STATS(TX_MCAST);
 	stats->tx_drops = GET_TX_STATS(TX_DROP);
 
-	drv_stats->rx_frames_ok = stats->rx_ucast_frames_ok +
-				  stats->rx_bcast_frames_ok +
-				  stats->rx_mcast_frames_ok;
 	drv_stats->tx_frames_ok = stats->tx_ucast_frames_ok +
 				  stats->tx_bcast_frames_ok +
 				  stats->tx_mcast_frames_ok;
@@ -1167,14 +1172,15 @@ static struct rtnl_link_stats64 *nicvf_get_stats64(struct net_device *netdev,
 					    struct rtnl_link_stats64 *stats)
 {
 	struct nicvf *nic = netdev_priv(netdev);
-	struct nicvf_hw_stats *hw_stats = &nic->stats;
+	struct nicvf_hw_stats *hw_stats = &nic->hw_stats;
 	struct nicvf_drv_stats *drv_stats = &nic->drv_stats;
 
 	nicvf_update_stats(nic);
 
-	stats->rx_bytes = hw_stats->rx_bytes_ok;
+	stats->rx_bytes = hw_stats->rx_bytes;
 	stats->rx_packets = drv_stats->rx_frames_ok;
 	stats->rx_dropped = drv_stats->rx_drops;
+	stats->multicast = hw_stats->rx_mcast_frames;
 
 	stats->tx_bytes = hw_stats->tx_bytes_ok;
 	stats->tx_packets = drv_stats->tx_frames_ok;
diff --git a/drivers/net/ethernet/cavium/thunder/nicvf_queues.c b/drivers/net/ethernet/cavium/thunder/nicvf_queues.c
index ca4240a..4fc40d83 100644
--- a/drivers/net/ethernet/cavium/thunder/nicvf_queues.c
+++ b/drivers/net/ethernet/cavium/thunder/nicvf_queues.c
@@ -1371,10 +1371,11 @@ void nicvf_update_sq_stats(struct nicvf *nic, int sq_idx)
 int nicvf_check_cqe_rx_errs(struct nicvf *nic,
 			    struct cmp_queue *cq, struct cqe_rx_t *cqe_rx)
 {
-	struct cmp_queue_stats *stats = &cq->stats;
+	struct nicvf_hw_stats *stats = &nic->hw_stats;
+	struct nicvf_drv_stats *drv_stats = &nic->drv_stats;
 
 	if (!cqe_rx->err_level && !cqe_rx->err_opcode) {
-		stats->rx.errop.good++;
+		drv_stats->rx_frames_ok++;
 		return 0;
 	}
 
@@ -1384,111 +1385,78 @@ int nicvf_check_cqe_rx_errs(struct nicvf *nic,
 			   nic->netdev->name,
 			   cqe_rx->err_level, cqe_rx->err_opcode);
 
-	switch (cqe_rx->err_level) {
-	case CQ_ERRLVL_MAC:
-		stats->rx.errlvl.mac_errs++;
-		break;
-	case CQ_ERRLVL_L2:
-		stats->rx.errlvl.l2_errs++;
-		break;
-	case CQ_ERRLVL_L3:
-		stats->rx.errlvl.l3_errs++;
-		break;
-	case CQ_ERRLVL_L4:
-		stats->rx.errlvl.l4_errs++;
-		break;
-	}
-
 	switch (cqe_rx->err_opcode) {
 	case CQ_RX_ERROP_RE_PARTIAL:
-		stats->rx.errop.partial_pkts++;
+		stats->rx_bgx_truncated_pkts++;
 		break;
 	case CQ_RX_ERROP_RE_JABBER:
-		stats->rx.errop.jabber_errs++;
+		stats->rx_jabber_errs++;
 		break;
 	case CQ_RX_ERROP_RE_FCS:
-		stats->rx.errop.fcs_errs++;
-		break;
-	case CQ_RX_ERROP_RE_TERMINATE:
-		stats->rx.errop.terminate_errs++;
+		stats->rx_fcs_errs++;
 		break;
 	case CQ_RX_ERROP_RE_RX_CTL:
-		stats->rx.errop.bgx_rx_errs++;
+		stats->rx_bgx_errs++;
 		break;
 	case CQ_RX_ERROP_PREL2_ERR:
-		stats->rx.errop.prel2_errs++;
-		break;
-	case CQ_RX_ERROP_L2_FRAGMENT:
-		stats->rx.errop.l2_frags++;
-		break;
-	case CQ_RX_ERROP_L2_OVERRUN:
-		stats->rx.errop.l2_overruns++;
-		break;
-	case CQ_RX_ERROP_L2_PFCS:
-		stats->rx.errop.l2_pfcs++;
-		break;
-	case CQ_RX_ERROP_L2_PUNY:
-		stats->rx.errop.l2_puny++;
+		stats->rx_prel2_errs++;
 		break;
 	case CQ_RX_ERROP_L2_MAL:
-		stats->rx.errop.l2_hdr_malformed++;
+		stats->rx_l2_hdr_malformed++;
 		break;
 	case CQ_RX_ERROP_L2_OVERSIZE:
-		stats->rx.errop.l2_oversize++;
+		stats->rx_oversize++;
 		break;
 	case CQ_RX_ERROP_L2_UNDERSIZE:
-		stats->rx.errop.l2_undersize++;
+		stats->rx_undersize++;
 		break;
 	case CQ_RX_ERROP_L2_LENMISM:
-		stats->rx.errop.l2_len_mismatch++;
+		stats->rx_l2_len_mismatch++;
 		break;
 	case CQ_RX_ERROP_L2_PCLP:
-		stats->rx.errop.l2_pclp++;
+		stats->rx_l2_pclp++;
 		break;
 	case CQ_RX_ERROP_IP_NOT:
-		stats->rx.errop.non_ip++;
+		stats->rx_ip_ver_errs++;
 		break;
 	case CQ_RX_ERROP_IP_CSUM_ERR:
-		stats->rx.errop.ip_csum_err++;
+		stats->rx_ip_csum_errs++;
 		break;
 	case CQ_RX_ERROP_IP_MAL:
-		stats->rx.errop.ip_hdr_malformed++;
+		stats->rx_ip_hdr_malformed++;
 		break;
 	case CQ_RX_ERROP_IP_MALD:
-		stats->rx.errop.ip_payload_malformed++;
+		stats->rx_ip_payload_malformed++;
 		break;
 	case CQ_RX_ERROP_IP_HOP:
-		stats->rx.errop.ip_hop_errs++;
-		break;
-	case CQ_RX_ERROP_L3_ICRC:
-		stats->rx.errop.l3_icrc_errs++;
+		stats->rx_ip_ttl_errs++;
 		break;
 	case CQ_RX_ERROP_L3_PCLP:
-		stats->rx.errop.l3_pclp++;
+		stats->rx_l3_pclp++;
 		break;
 	case CQ_RX_ERROP_L4_MAL:
-		stats->rx.errop.l4_malformed++;
+		stats->rx_l4_malformed++;
 		break;
 	case CQ_RX_ERROP_L4_CHK:
-		stats->rx.errop.l4_csum_errs++;
+		stats->rx_l4_csum_errs++;
 		break;
 	case CQ_RX_ERROP_UDP_LEN:
-		stats->rx.errop.udp_len_err++;
+		stats->rx_udp_len_errs++;
 		break;
 	case CQ_RX_ERROP_L4_PORT:
-		stats->rx.errop.bad_l4_port++;
+		stats->rx_l4_port_errs++;
 		break;
 	case CQ_RX_ERROP_TCP_FLAG:
-		stats->rx.errop.bad_tcp_flag++;
+		stats->rx_tcp_flag_errs++;
 		break;
 	case CQ_RX_ERROP_TCP_OFFSET:
-		stats->rx.errop.tcp_offset_errs++;
+		stats->rx_tcp_offset_errs++;
 		break;
 	case CQ_RX_ERROP_L4_PCLP:
-		stats->rx.errop.l4_pclp++;
+		stats->rx_l4_pclp++;
 		break;
 	case CQ_RX_ERROP_RBDR_TRUNC:
-		stats->rx.errop.pkt_truncated++;
+		stats->rx_truncated_pkts++;
 		break;
 	}
 
diff --git a/drivers/net/ethernet/cavium/thunder/nicvf_queues.h b/drivers/net/ethernet/cavium/thunder/nicvf_queues.h
index f0937b7..dc73872 100644
--- a/drivers/net/ethernet/cavium/thunder/nicvf_queues.h
+++ b/drivers/net/ethernet/cavium/thunder/nicvf_queues.h
@@ -181,47 +181,6 @@ enum CQ_TX_ERROP_E {
 };
 
 struct cmp_queue_stats {
-	struct rx_stats {
-		struct {
-			u64 mac_errs;
-			u64 l2_errs;
-			u64 l3_errs;
-			u64 l4_errs;
-		} errlvl;
-		struct {
-			u64 good;
-			u64 partial_pkts;
-			u64 jabber_errs;
-			u64 fcs_errs;
-			u64 terminate_errs;
-			u64 bgx_rx_errs;
-			u64 prel2_errs;
-			u64 l2_frags;
-			u64 l2_overruns;
-			u64 l2_pfcs;
-			u64 l2_puny;
-			u64 l2_hdr_malformed;
-			u64 l2_oversize;
-			u64 l2_undersize;
-			u64 l2_len_mismatch;
-			u64 l2_pclp;
-			u64 non_ip;
-			u64 ip_csum_err;
-			u64 ip_hdr_malformed;
-			u64 ip_payload_malformed;
-			u64 ip_hop_errs;
-			u64 l3_icrc_errs;
-			u64 l3_pclp;
-			u64 l4_malformed;
-			u64 l4_csum_errs;
-			u64 udp_len_err;
-			u64 bad_l4_port;
-			u64 bad_tcp_flag;
-			u64 tcp_offset_errs;
-			u64 l4_pclp;
-			u64 pkt_truncated;
-		} errop;
-	} rx;
 	struct tx_stats {
 		u64 good;
 		u64 desc_fault;
-- 
2.5.0



From aleksey.makarov at auriga.com  Fri Aug 28 07:59:55 2015
From: aleksey.makarov at auriga.com (Aleksey Makarov)
Date: Fri, 28 Aug 2015 17:59:55 +0300
Subject: [PATCH net-next 3/8] net: thunderx: mailboxes: remove code duplication
In-Reply-To: <1440774004-27923-1-git-send-email-aleksey.makarov@auriga.com>
References: <1440774004-27923-1-git-send-email-aleksey.makarov@auriga.com>
Message-ID: <1440774004-27923-3-git-send-email-aleksey.makarov@auriga.com>

From: Sunil Goutham <sgoutham at cavium.com>

Use the nicvf_send_msg_to_pf() function in the mailbox code.

Signed-off-by: Sunil Goutham <sgoutham at cavium.com>
Signed-off-by: Robert Richter <rrichter at cavium.com>
Signed-off-by: Aleksey Makarov <aleksey.makarov at caviumnetworks.com>
---
 drivers/net/ethernet/cavium/thunder/nic.h        |  3 +-
 drivers/net/ethernet/cavium/thunder/nicvf_main.c | 44 ++++++------------------
 2 files changed, 11 insertions(+), 36 deletions(-)

diff --git a/drivers/net/ethernet/cavium/thunder/nic.h b/drivers/net/ethernet/cavium/thunder/nic.h
index 58adfd6..a83f567 100644
--- a/drivers/net/ethernet/cavium/thunder/nic.h
+++ b/drivers/net/ethernet/cavium/thunder/nic.h
@@ -295,10 +295,9 @@ struct nicvf {
 	char			irq_name[NIC_VF_MSIX_VECTORS][20];
 	bool			irq_allocated[NIC_VF_MSIX_VECTORS];
 
-	bool			pf_ready_to_rcv_msg;
+	/* VF <-> PF mailbox communication */
 	bool			pf_acked;
 	bool			pf_nacked;
-	bool			bgx_stats_acked;
 	bool			set_mac_pending;
 } ____cacheline_aligned_in_smp;
 
diff --git a/drivers/net/ethernet/cavium/thunder/nicvf_main.c b/drivers/net/ethernet/cavium/thunder/nicvf_main.c
index 670ff9b..d4ad36e 100644
--- a/drivers/net/ethernet/cavium/thunder/nicvf_main.c
+++ b/drivers/net/ethernet/cavium/thunder/nicvf_main.c
@@ -105,7 +105,6 @@ u64 nicvf_queue_reg_read(struct nicvf *nic, u64 offset, u64 qidx)
 }
 
 /* VF -> PF mailbox communication */
-
 static void nicvf_write_to_mbx(struct nicvf *nic, union nic_mbx *mbx)
 {
 	u64 *msg = (u64 *)mbx;
@@ -147,26 +146,15 @@ int nicvf_send_msg_to_pf(struct nicvf *nic, union nic_mbx *mbx)
 */
 static int nicvf_check_pf_ready(struct nicvf *nic)
 {
-	int timeout = 5000, sleep = 20;
 	union nic_mbx mbx = {};
 
 	mbx.msg.msg = NIC_MBOX_MSG_READY;
-
-	nic->pf_ready_to_rcv_msg = false;
-
-	nicvf_write_to_mbx(nic, &mbx);
-
-	while (!nic->pf_ready_to_rcv_msg) {
-		msleep(sleep);
-		if (nic->pf_ready_to_rcv_msg)
-			break;
-		timeout -= sleep;
-		if (!timeout) {
-			netdev_err(nic->netdev,
-				   "PF didn't respond to READY msg\n");
-			return 0;
-		}
+	if (nicvf_send_msg_to_pf(nic, &mbx)) {
+		netdev_err(nic->netdev,
+			   "PF didn't respond to READY msg\n");
+		return 0;
 	}
+
 	return 1;
 }
 
@@ -197,7 +185,7 @@ static void  nicvf_handle_mbx_intr(struct nicvf *nic)
 	netdev_dbg(nic->netdev, "Mbox message: msg: 0x%x\n", mbx.msg.msg);
 	switch (mbx.msg.msg) {
 	case NIC_MBOX_MSG_READY:
-		nic->pf_ready_to_rcv_msg = true;
+		nic->pf_acked = true;
 		nic->vf_id = mbx.nic_cfg.vf_id & 0x7F;
 		nic->tns_mode = mbx.nic_cfg.tns_mode & 0x7F;
 		nic->node = mbx.nic_cfg.node_id;
@@ -221,7 +209,6 @@ static void  nicvf_handle_mbx_intr(struct nicvf *nic)
 	case NIC_MBOX_MSG_BGX_STATS:
 		nicvf_read_bgx_stats(nic, &mbx.bgx_stats);
 		nic->pf_acked = true;
-		nic->bgx_stats_acked = true;
 		break;
 	case NIC_MBOX_MSG_BGX_LINK_CHANGE:
 		nic->pf_acked = true;
@@ -1083,7 +1070,6 @@ void nicvf_update_lmac_stats(struct nicvf *nic)
 {
 	int stat = 0;
 	union nic_mbx mbx = {};
-	int timeout;
 
 	if (!netif_running(nic->netdev))
 		return;
@@ -1093,14 +1079,9 @@ void nicvf_update_lmac_stats(struct nicvf *nic)
 	/* Rx stats */
 	mbx.bgx_stats.rx = 1;
 	while (stat < BGX_RX_STATS_COUNT) {
-		nic->bgx_stats_acked = 0;
 		mbx.bgx_stats.idx = stat;
-		nicvf_send_msg_to_pf(nic, &mbx);
-		timeout = 0;
-		while ((!nic->bgx_stats_acked) && (timeout < 10)) {
-			msleep(2);
-			timeout++;
-		}
+		if (nicvf_send_msg_to_pf(nic, &mbx))
+			return;
 		stat++;
 	}
 
@@ -1109,14 +1090,9 @@ void nicvf_update_lmac_stats(struct nicvf *nic)
 	/* Tx stats */
 	mbx.bgx_stats.rx = 0;
 	while (stat < BGX_TX_STATS_COUNT) {
-		nic->bgx_stats_acked = 0;
 		mbx.bgx_stats.idx = stat;
-		nicvf_send_msg_to_pf(nic, &mbx);
-		timeout = 0;
-		while ((!nic->bgx_stats_acked) && (timeout < 10)) {
-			msleep(2);
-			timeout++;
-		}
+		if (nicvf_send_msg_to_pf(nic, &mbx))
+			return;
 		stat++;
 	}
 }
-- 
2.5.0



From aleksey.makarov at auriga.com  Fri Aug 28 07:59:56 2015
From: aleksey.makarov at auriga.com (Aleksey Makarov)
Date: Fri, 28 Aug 2015 17:59:56 +0300
Subject: [PATCH net-next 4/8] net: thunderx: Receive hashing HW offload support
In-Reply-To: <1440774004-27923-1-git-send-email-aleksey.makarov@auriga.com>
References: <1440774004-27923-1-git-send-email-aleksey.makarov@auriga.com>
Message-ID: <1440774004-27923-4-git-send-email-aleksey.makarov@auriga.com>

From: Sunil Goutham <sgoutham at cavium.com>

Adding support for receive hashing HW offload by using RSS_ALG
and RSS_TAG fields of CQE_RX descriptor. Also removed dependency
on minimum receive queue count to configure RSS so that hash is
always generated.

This hash is used by RPS logic to distribute flows across multiple
CPUs. Offload can be disabled via ethtool.

Signed-off-by: Robert Richter <rrichter at cavium.com>
Signed-off-by: Sunil Goutham <sgoutham at cavium.com>
Signed-off-by: Aleksey Makarov <aleksey.makarov at caviumnetworks.com>
---
 .../net/ethernet/cavium/thunder/nicvf_ethtool.c    | 14 ++++-----
 drivers/net/ethernet/cavium/thunder/nicvf_main.c   | 35 ++++++++++++++++++++--
 2 files changed, 39 insertions(+), 10 deletions(-)

diff --git a/drivers/net/ethernet/cavium/thunder/nicvf_ethtool.c b/drivers/net/ethernet/cavium/thunder/nicvf_ethtool.c
index a961aa3..1eec2cd 100644
--- a/drivers/net/ethernet/cavium/thunder/nicvf_ethtool.c
+++ b/drivers/net/ethernet/cavium/thunder/nicvf_ethtool.c
@@ -525,17 +525,15 @@ static int nicvf_set_rxfh(struct net_device *dev, const u32 *indir,
 	struct nicvf_rss_info *rss = &nic->rss_info;
 	int idx;
 
-	if ((nic->qs->rq_cnt <= 1) || (nic->cpi_alg != CPI_ALG_NONE)) {
-		rss->enable = false;
-		rss->hash_bits = 0;
-		return -EIO;
-	}
-
-	/* We do not allow change in unsupported parameters */
 	if (hfunc != ETH_RSS_HASH_NO_CHANGE && hfunc != ETH_RSS_HASH_TOP)
 		return -EOPNOTSUPP;
 
-	rss->enable = true;
+	if (!rss->enable) {
+		netdev_err(nic->netdev,
+			   "RSS is disabled, cannot change settings\n");
+		return -EIO;
+	}
+
 	if (indir) {
 		for (idx = 0; idx < rss->rss_size; idx++)
 			rss->ind_tbl[idx] = indir[idx];
diff --git a/drivers/net/ethernet/cavium/thunder/nicvf_main.c b/drivers/net/ethernet/cavium/thunder/nicvf_main.c
index d4ad36e..afd8ad4 100644
--- a/drivers/net/ethernet/cavium/thunder/nicvf_main.c
+++ b/drivers/net/ethernet/cavium/thunder/nicvf_main.c
@@ -313,7 +313,7 @@ static int nicvf_rss_init(struct nicvf *nic)
 
 	nicvf_get_rss_size(nic);
 
-	if ((nic->qs->rq_cnt <= 1) || (cpi_alg != CPI_ALG_NONE)) {
+	if (cpi_alg != CPI_ALG_NONE) {
 		rss->enable = false;
 		rss->hash_bits = 0;
 		return 0;
@@ -416,6 +416,34 @@ static void nicvf_snd_pkt_handler(struct net_device *netdev,
 	}
 }
 
+static inline void nicvf_set_rxhash(struct net_device *netdev,
+				    struct cqe_rx_t *cqe_rx,
+				    struct sk_buff *skb)
+{
+	u8 hash_type;
+	u32 hash;
+
+	if (!(netdev->features & NETIF_F_RXHASH))
+		return;
+
+	switch (cqe_rx->rss_alg) {
+	case RSS_ALG_TCP_IP:
+	case RSS_ALG_UDP_IP:
+		hash_type = PKT_HASH_TYPE_L4;
+		hash = cqe_rx->rss_tag;
+		break;
+	case RSS_ALG_IP:
+		hash_type = PKT_HASH_TYPE_L3;
+		hash = cqe_rx->rss_tag;
+		break;
+	default:
+		hash_type = PKT_HASH_TYPE_NONE;
+		hash = 0;
+	}
+
+	skb_set_hash(skb, hash, hash_type);
+}
+
 static void nicvf_rcv_pkt_handler(struct net_device *netdev,
 				  struct napi_struct *napi,
 				  struct cmp_queue *cq,
@@ -451,6 +479,8 @@ static void nicvf_rcv_pkt_handler(struct net_device *netdev,
 
 	nicvf_set_rx_frame_cnt(nic, skb);
 
+	nicvf_set_rxhash(netdev, cqe_rx, skb);
+
 	skb_record_rx_queue(skb, cqe_rx->rq_idx);
 	if (netdev->hw_features & NETIF_F_RXCSUM) {
 		/* HW by default verifies TCP/UDP/SCTP checksums */
@@ -1272,7 +1302,8 @@ static int nicvf_probe(struct pci_dev *pdev, const struct pci_device_id *ent)
 		goto err_free_netdev;
 
 	netdev->features |= (NETIF_F_RXCSUM | NETIF_F_IP_CSUM | NETIF_F_SG |
-			     NETIF_F_TSO | NETIF_F_GRO);
+			     NETIF_F_TSO | NETIF_F_GRO | NETIF_F_RXHASH);
+
 	netdev->hw_features = netdev->features;
 
 	netdev->netdev_ops = &nicvf_netdev_ops;
-- 
2.5.0



From julien.grall at citrix.com  Fri Aug 28 08:03:14 2015
From: julien.grall at citrix.com (Julien Grall)
Date: Fri, 28 Aug 2015 16:03:14 +0100
Subject: [Xen-devel] [PATCH v3 11/20] tty/hvc: xen: Use xen page definition
In-Reply-To: <55D5A42E.7070800@citrix.com>
References: <1438966019-19322-1-git-send-email-julien.grall@citrix.com>
 <1438966019-19322-12-git-send-email-julien.grall@citrix.com>
 <55D5A42E.7070800@citrix.com>
Message-ID: <55E07832.1010802@citrix.com>

Hi David,

On 20/08/15 10:55, David Vrabel wrote:
> On 07/08/15 17:46, Julien Grall wrote:
>> The console ring is always based on the page granularity of Xen.
> [...]
>> --- a/drivers/tty/hvc/hvc_xen.c
>> +++ b/drivers/tty/hvc/hvc_xen.c
>> @@ -230,7 +230,7 @@ static int xen_hvm_console_init(void)
>>  	if (r < 0 || v == 0)
>>  		goto err;
>>  	gfn = v;
>> -	info->intf = xen_remap(gfn << PAGE_SHIFT, PAGE_SIZE);
>> +	info->intf = xen_remap(gfn << XEN_PAGE_SHIFT, PAGE_SIZE);
> 
> You need XEN_PAGE_SIZE here I think...

Right, I did the mistake while rebase on my s/mfn/gfn/ series. I will
fix it in the next version.

Regards,

-- 
Julien Grall


From aleksey.makarov at auriga.com  Fri Aug 28 07:59:58 2015
From: aleksey.makarov at auriga.com (Aleksey Makarov)
Date: Fri, 28 Aug 2015 17:59:58 +0300
Subject: [PATCH net-next 6/8] net: thunderx: Rework interrupt handler
In-Reply-To: <1440774004-27923-1-git-send-email-aleksey.makarov@auriga.com>
References: <1440774004-27923-1-git-send-email-aleksey.makarov@auriga.com>
Message-ID: <1440774004-27923-6-git-send-email-aleksey.makarov@auriga.com>

From: Sunil Goutham <sgoutham at cavium.com>

Rework interrupt handler to avoid checking IRQ affinity of
CQ interrupts. Now separate handlers are registered for each IRQ
including RBDR. Also register interrupt handlers for only those
which are being used.

Signed-off-by: Sunil Goutham <sgoutham at cavium.com>
Signed-off-by: Aleksey Makarov <aleksey.makarov at caviumnetworks.com>
---
 drivers/net/ethernet/cavium/thunder/nic.h          |   1 +
 drivers/net/ethernet/cavium/thunder/nicvf_main.c   | 172 ++++++++++++---------
 drivers/net/ethernet/cavium/thunder/nicvf_queues.h |   2 +
 3 files changed, 103 insertions(+), 72 deletions(-)

diff --git a/drivers/net/ethernet/cavium/thunder/nic.h b/drivers/net/ethernet/cavium/thunder/nic.h
index a83f567..89b997e 100644
--- a/drivers/net/ethernet/cavium/thunder/nic.h
+++ b/drivers/net/ethernet/cavium/thunder/nic.h
@@ -135,6 +135,7 @@
 #define	NICVF_TX_TIMEOUT		(50 * HZ)
 
 struct nicvf_cq_poll {
+	struct  nicvf *nicvf;
 	u8	cq_idx;		/* Completion queue index */
 	struct	napi_struct napi;
 };
diff --git a/drivers/net/ethernet/cavium/thunder/nicvf_main.c b/drivers/net/ethernet/cavium/thunder/nicvf_main.c
index de51828..2198f61 100644
--- a/drivers/net/ethernet/cavium/thunder/nicvf_main.c
+++ b/drivers/net/ethernet/cavium/thunder/nicvf_main.c
@@ -653,11 +653,20 @@ static void nicvf_handle_qs_err(unsigned long data)
 	nicvf_enable_intr(nic, NICVF_INTR_QS_ERR, 0);
 }
 
+static inline void nicvf_dump_intr_status(struct nicvf *nic)
+{
+	if (netif_msg_intr(nic))
+		netdev_info(nic->netdev, "%s: interrupt status 0x%llx\n",
+			    nic->netdev->name, nicvf_reg_read(nic, NIC_VF_INT));
+}
+
 static irqreturn_t nicvf_misc_intr_handler(int irq, void *nicvf_irq)
 {
 	struct nicvf *nic = (struct nicvf *)nicvf_irq;
 	u64 intr;
 
+	nicvf_dump_intr_status(nic);
+
 	intr = nicvf_reg_read(nic, NIC_VF_INT);
 	/* Check for spurious interrupt */
 	if (!(intr & NICVF_INTR_MBOX_MASK))
@@ -668,59 +677,58 @@ static irqreturn_t nicvf_misc_intr_handler(int irq, void *nicvf_irq)
 	return IRQ_HANDLED;
 }
 
-static irqreturn_t nicvf_intr_handler(int irq, void *nicvf_irq)
+static irqreturn_t nicvf_intr_handler(int irq, void *cq_irq)
+{
+	struct nicvf_cq_poll *cq_poll = (struct nicvf_cq_poll *)cq_irq;
+	struct nicvf *nic = cq_poll->nicvf;
+	int qidx = cq_poll->cq_idx;
+
+	nicvf_dump_intr_status(nic);
+
+	/* Disable interrupts */
+	nicvf_disable_intr(nic, NICVF_INTR_CQ, qidx);
+
+	/* Schedule NAPI */
+	napi_schedule(&cq_poll->napi);
+
+	/* Clear interrupt */
+	nicvf_clear_intr(nic, NICVF_INTR_CQ, qidx);
+
+	return IRQ_HANDLED;
+}
+
+static irqreturn_t nicvf_rbdr_intr_handler(int irq, void *nicvf_irq)
 {
-	u64 qidx, intr, clear_intr = 0;
-	u64 cq_intr, rbdr_intr, qs_err_intr;
 	struct nicvf *nic = (struct nicvf *)nicvf_irq;
-	struct queue_set *qs = nic->qs;
-	struct nicvf_cq_poll *cq_poll = NULL;
+	u8 qidx;
 
-	intr = nicvf_reg_read(nic, NIC_VF_INT);
-	if (netif_msg_intr(nic))
-		netdev_info(nic->netdev, "%s: interrupt status 0x%llx\n",
-			    nic->netdev->name, intr);
-
-	qs_err_intr = intr & NICVF_INTR_QS_ERR_MASK;
-	if (qs_err_intr) {
-		/* Disable Qset err interrupt and schedule softirq */
-		nicvf_disable_intr(nic, NICVF_INTR_QS_ERR, 0);
-		tasklet_hi_schedule(&nic->qs_err_task);
-		clear_intr |= qs_err_intr;
-	}
 
-	/* Disable interrupts and start polling */
-	cq_intr = (intr & NICVF_INTR_CQ_MASK) >> NICVF_INTR_CQ_SHIFT;
-	for (qidx = 0; qidx < qs->cq_cnt; qidx++) {
-		if (!(cq_intr & (1 << qidx)))
-			continue;
-		if (!nicvf_is_intr_enabled(nic, NICVF_INTR_CQ, qidx))
+	nicvf_dump_intr_status(nic);
+
+	/* Disable RBDR interrupt and schedule softirq */
+	for (qidx = 0; qidx < nic->qs->rbdr_cnt; qidx++) {
+		if (!nicvf_is_intr_enabled(nic, NICVF_INTR_RBDR, qidx))
 			continue;
+		nicvf_disable_intr(nic, NICVF_INTR_RBDR, qidx);
+		tasklet_hi_schedule(&nic->rbdr_task);
+		/* Clear interrupt */
+		nicvf_clear_intr(nic, NICVF_INTR_RBDR, qidx);
+	}
 
-		nicvf_disable_intr(nic, NICVF_INTR_CQ, qidx);
-		clear_intr |= ((1 << qidx) << NICVF_INTR_CQ_SHIFT);
+	return IRQ_HANDLED;
+}
 
-		cq_poll = nic->napi[qidx];
-		/* Schedule NAPI */
-		if (cq_poll)
-			napi_schedule(&cq_poll->napi);
-	}
+static irqreturn_t nicvf_qs_err_intr_handler(int irq, void *nicvf_irq)
+{
+	struct nicvf *nic = (struct nicvf *)nicvf_irq;
 
-	/* Handle RBDR interrupts */
-	rbdr_intr = (intr & NICVF_INTR_RBDR_MASK) >> NICVF_INTR_RBDR_SHIFT;
-	if (rbdr_intr) {
-		/* Disable RBDR interrupt and schedule softirq */
-		for (qidx = 0; qidx < qs->rbdr_cnt; qidx++) {
-			if (!nicvf_is_intr_enabled(nic, NICVF_INTR_RBDR, qidx))
-				continue;
-			nicvf_disable_intr(nic, NICVF_INTR_RBDR, qidx);
-			tasklet_hi_schedule(&nic->rbdr_task);
-			clear_intr |= ((1 << qidx) << NICVF_INTR_RBDR_SHIFT);
-		}
-	}
+	nicvf_dump_intr_status(nic);
+
+	/* Disable Qset err interrupt and schedule softirq */
+	nicvf_disable_intr(nic, NICVF_INTR_QS_ERR, 0);
+	tasklet_hi_schedule(&nic->qs_err_task);
+	nicvf_clear_intr(nic, NICVF_INTR_QS_ERR, 0);
 
-	/* Clear interrupts */
-	nicvf_reg_write(nic, NIC_VF_INT, clear_intr);
 	return IRQ_HANDLED;
 }
 
@@ -754,7 +762,7 @@ static void nicvf_disable_msix(struct nicvf *nic)
 
 static int nicvf_register_interrupts(struct nicvf *nic)
 {
-	int irq, free, ret = 0;
+	int irq, ret = 0;
 	int vector;
 
 	for_each_cq_irq(irq)
@@ -769,44 +777,42 @@ static int nicvf_register_interrupts(struct nicvf *nic)
 		sprintf(nic->irq_name[irq], "NICVF%d RBDR%d",
 			nic->vf_id, irq - NICVF_INTR_ID_RBDR);
 
-	/* Register all interrupts except mailbox */
-	for (irq = 0; irq < NICVF_INTR_ID_SQ; irq++) {
+	/* Register CQ interrupts */
+	for (irq = 0; irq < nic->qs->cq_cnt; irq++) {
 		vector = nic->msix_entries[irq].vector;
 		ret = request_irq(vector, nicvf_intr_handler,
-				  0, nic->irq_name[irq], nic);
+				  0, nic->irq_name[irq], nic->napi[irq]);
 		if (ret)
-			break;
+			goto err;
 		nic->irq_allocated[irq] = true;
 	}
 
-	for (irq = NICVF_INTR_ID_SQ; irq < NICVF_INTR_ID_MISC; irq++) {
+	/* Register RBDR interrupt */
+	for (irq = NICVF_INTR_ID_RBDR;
+	     irq < (NICVF_INTR_ID_RBDR + nic->qs->rbdr_cnt); irq++) {
 		vector = nic->msix_entries[irq].vector;
-		ret = request_irq(vector, nicvf_intr_handler,
+		ret = request_irq(vector, nicvf_rbdr_intr_handler,
 				  0, nic->irq_name[irq], nic);
 		if (ret)
-			break;
+			goto err;
 		nic->irq_allocated[irq] = true;
 	}
 
+	/* Register QS error interrupt */
 	sprintf(nic->irq_name[NICVF_INTR_ID_QS_ERR],
 		"NICVF%d Qset error", nic->vf_id);
-	if (!ret) {
-		vector = nic->msix_entries[NICVF_INTR_ID_QS_ERR].vector;
-		irq = NICVF_INTR_ID_QS_ERR;
-		ret = request_irq(vector, nicvf_intr_handler,
-				  0, nic->irq_name[irq], nic);
-		if (!ret)
-			nic->irq_allocated[irq] = true;
-	}
+	irq = NICVF_INTR_ID_QS_ERR;
+	ret = request_irq(nic->msix_entries[irq].vector,
+			  nicvf_qs_err_intr_handler,
+			  0, nic->irq_name[irq], nic);
+	if (!ret)
+		nic->irq_allocated[irq] = true;
 
-	if (ret) {
-		netdev_err(nic->netdev, "Request irq failed\n");
-		for (free = 0; free < irq; free++)
-			free_irq(nic->msix_entries[free].vector, nic);
-		return ret;
-	}
+err:
+	if (ret)
+		netdev_err(nic->netdev, "request_irq failed, vector %d\n", irq);
 
-	return 0;
+	return ret;
 }
 
 static void nicvf_unregister_interrupts(struct nicvf *nic)
@@ -815,8 +821,14 @@ static void nicvf_unregister_interrupts(struct nicvf *nic)
 
 	/* Free registered interrupts */
 	for (irq = 0; irq < nic->num_vec; irq++) {
-		if (nic->irq_allocated[irq])
+		if (!nic->irq_allocated[irq])
+			continue;
+
+		if (irq < NICVF_INTR_ID_SQ)
+			free_irq(nic->msix_entries[irq].vector, nic->napi[irq]);
+		else
 			free_irq(nic->msix_entries[irq].vector, nic);
+
 		nic->irq_allocated[irq] = false;
 	}
 
@@ -888,6 +900,20 @@ static netdev_tx_t nicvf_xmit(struct sk_buff *skb, struct net_device *netdev)
 	return NETDEV_TX_OK;
 }
 
+static inline void nicvf_free_cq_poll(struct nicvf *nic)
+{
+	struct nicvf_cq_poll *cq_poll = NULL;
+	int qidx;
+
+	for (qidx = 0; qidx < nic->qs->cq_cnt; qidx++) {
+		cq_poll = nic->napi[qidx];
+		if (!cq_poll)
+			continue;
+		nic->napi[qidx] = NULL;
+		kfree(cq_poll);
+	}
+}
+
 int nicvf_stop(struct net_device *netdev)
 {
 	int irq, qidx;
@@ -922,7 +948,6 @@ int nicvf_stop(struct net_device *netdev)
 		cq_poll = nic->napi[qidx];
 		if (!cq_poll)
 			continue;
-		nic->napi[qidx] = NULL;
 		napi_synchronize(&cq_poll->napi);
 		/* CQ intr is enabled while napi_complete,
 		 * so disable it now
@@ -931,7 +956,6 @@ int nicvf_stop(struct net_device *netdev)
 		nicvf_clear_intr(nic, NICVF_INTR_CQ, qidx);
 		napi_disable(&cq_poll->napi);
 		netif_napi_del(&cq_poll->napi);
-		kfree(cq_poll);
 	}
 
 	netif_tx_disable(netdev);
@@ -947,6 +971,8 @@ int nicvf_stop(struct net_device *netdev)
 
 	nicvf_unregister_interrupts(nic);
 
+	nicvf_free_cq_poll(nic);
+
 	return 0;
 }
 
@@ -973,6 +999,7 @@ int nicvf_open(struct net_device *netdev)
 			goto napi_del;
 		}
 		cq_poll->cq_idx = qidx;
+		cq_poll->nicvf = nic;
 		netif_napi_add(netdev, &cq_poll->napi, nicvf_poll,
 			       NAPI_POLL_WEIGHT);
 		napi_enable(&cq_poll->napi);
@@ -1040,6 +1067,8 @@ int nicvf_open(struct net_device *netdev)
 cleanup:
 	nicvf_disable_intr(nic, NICVF_INTR_MBOX, 0);
 	nicvf_unregister_interrupts(nic);
+	tasklet_kill(&nic->qs_err_task);
+	tasklet_kill(&nic->rbdr_task);
 napi_del:
 	for (qidx = 0; qidx < qs->cq_cnt; qidx++) {
 		cq_poll = nic->napi[qidx];
@@ -1047,9 +1076,8 @@ napi_del:
 			continue;
 		napi_disable(&cq_poll->napi);
 		netif_napi_del(&cq_poll->napi);
-		kfree(cq_poll);
-		nic->napi[qidx] = NULL;
 	}
+	nicvf_free_cq_poll(nic);
 	return err;
 }
 
diff --git a/drivers/net/ethernet/cavium/thunder/nicvf_queues.h b/drivers/net/ethernet/cavium/thunder/nicvf_queues.h
index 8b93dd6..c2ce270 100644
--- a/drivers/net/ethernet/cavium/thunder/nicvf_queues.h
+++ b/drivers/net/ethernet/cavium/thunder/nicvf_queues.h
@@ -251,6 +251,8 @@ struct cmp_queue {
 	void		*desc;
 	struct q_desc_mem   dmem;
 	struct cmp_queue_stats	stats;
+	int		irq;
+	cpumask_t	affinity_mask;
 } ____cacheline_aligned_in_smp;
 
 struct snd_queue {
-- 
2.5.0



From aleksey.makarov at auriga.com  Fri Aug 28 07:59:57 2015
From: aleksey.makarov at auriga.com (Aleksey Makarov)
Date: Fri, 28 Aug 2015 17:59:57 +0300
Subject: [PATCH net-next 5/8] net: thunderx: Support for HW VLAN stripping
In-Reply-To: <1440774004-27923-1-git-send-email-aleksey.makarov@auriga.com>
References: <1440774004-27923-1-git-send-email-aleksey.makarov@auriga.com>
Message-ID: <1440774004-27923-5-git-send-email-aleksey.makarov@auriga.com>

From: Sunil Goutham <sgoutham at cavium.com>

This patch configures HW to strip 802.1Q header if found in a
receiving packet. The stripped VLAN ID and TCI information is
passed on to software via CQE_RX. Also sets netdev's 'vlan_features'
so that other HW offload features can be used for tagged packets.

This offload feature can be enabled or disabled via ethtool.

Network stack normally ignores RPS for 802.1Q packets and hence low
throughput. With this offload enabled throughput for tagged packets
will be almost same as normal packets.

Note: This patch doesn't enable HW VLAN insertion for transmit packets.

Signed-off-by: Sunil Goutham <sgoutham at cavium.com>
Signed-off-by: Aleksey Makarov <aleksey.makarov at caviumnetworks.com>
---
 drivers/net/ethernet/cavium/thunder/nic_main.c     |  4 ++++
 drivers/net/ethernet/cavium/thunder/nicvf_main.c   | 28 +++++++++++++++++++---
 drivers/net/ethernet/cavium/thunder/nicvf_queues.c | 28 ++++++++++++++++++----
 drivers/net/ethernet/cavium/thunder/nicvf_queues.h |  2 ++
 4 files changed, 55 insertions(+), 7 deletions(-)

diff --git a/drivers/net/ethernet/cavium/thunder/nic_main.c b/drivers/net/ethernet/cavium/thunder/nic_main.c
index 6e0c031..7dfec4a 100644
--- a/drivers/net/ethernet/cavium/thunder/nic_main.c
+++ b/drivers/net/ethernet/cavium/thunder/nic_main.c
@@ -329,6 +329,10 @@ static void nic_init_hw(struct nicpf *nic)
 
 	/* Timer config */
 	nic_reg_write(nic, NIC_PF_INTR_TIMER_CFG, NICPF_CLK_PER_INT_TICK);
+
+	/* Enable VLAN ethertype matching and stripping */
+	nic_reg_write(nic, NIC_PF_RX_ETYPE_0_7,
+		      (2 << 19) | (ETYPE_ALG_VLAN_STRIP << 16) | ETH_P_8021Q);
 }
 
 /* Channel parse index configuration */
diff --git a/drivers/net/ethernet/cavium/thunder/nicvf_main.c b/drivers/net/ethernet/cavium/thunder/nicvf_main.c
index afd8ad4..de51828 100644
--- a/drivers/net/ethernet/cavium/thunder/nicvf_main.c
+++ b/drivers/net/ethernet/cavium/thunder/nicvf_main.c
@@ -10,6 +10,7 @@
 #include <linux/interrupt.h>
 #include <linux/pci.h>
 #include <linux/netdevice.h>
+#include <linux/if_vlan.h>
 #include <linux/etherdevice.h>
 #include <linux/ethtool.h>
 #include <linux/log2.h>
@@ -491,6 +492,11 @@ static void nicvf_rcv_pkt_handler(struct net_device *netdev,
 
 	skb->protocol = eth_type_trans(skb, netdev);
 
+	/* Check for stripped VLAN */
+	if (cqe_rx->vlan_found && cqe_rx->vlan_stripped)
+		__vlan_hwaccel_put_tag(skb, htons(ETH_P_8021Q),
+				       ntohs((__force __be16)cqe_rx->vlan_tci));
+
 	if (napi && (netdev->features & NETIF_F_GRO))
 		napi_gro_receive(napi, skb);
 	else
@@ -1220,6 +1226,18 @@ static void nicvf_reset_task(struct work_struct *work)
 	nic->netdev->trans_start = jiffies;
 }
 
+static int nicvf_set_features(struct net_device *netdev,
+			      netdev_features_t features)
+{
+	struct nicvf *nic = netdev_priv(netdev);
+	netdev_features_t changed = features ^ netdev->features;
+
+	if (changed & NETIF_F_HW_VLAN_CTAG_RX)
+		nicvf_config_vlan_stripping(nic, features);
+
+	return 0;
+}
+
 static const struct net_device_ops nicvf_netdev_ops = {
 	.ndo_open		= nicvf_open,
 	.ndo_stop		= nicvf_stop,
@@ -1228,6 +1246,7 @@ static const struct net_device_ops nicvf_netdev_ops = {
 	.ndo_set_mac_address	= nicvf_set_mac_address,
 	.ndo_get_stats64	= nicvf_get_stats64,
 	.ndo_tx_timeout         = nicvf_tx_timeout,
+	.ndo_set_features       = nicvf_set_features,
 };
 
 static int nicvf_probe(struct pci_dev *pdev, const struct pci_device_id *ent)
@@ -1301,10 +1320,13 @@ static int nicvf_probe(struct pci_dev *pdev, const struct pci_device_id *ent)
 	if (err)
 		goto err_free_netdev;
 
-	netdev->features |= (NETIF_F_RXCSUM | NETIF_F_IP_CSUM | NETIF_F_SG |
-			     NETIF_F_TSO | NETIF_F_GRO | NETIF_F_RXHASH);
+	netdev->hw_features = (NETIF_F_RXCSUM | NETIF_F_IP_CSUM | NETIF_F_SG |
+			       NETIF_F_TSO | NETIF_F_GRO |
+			       NETIF_F_HW_VLAN_CTAG_RX | NETIF_F_RXHASH);
+
+	netdev->features |= netdev->hw_features;
 
-	netdev->hw_features = netdev->features;
+	netdev->vlan_features = NETIF_F_SG | NETIF_F_IP_CSUM | NETIF_F_TSO;
 
 	netdev->netdev_ops = &nicvf_netdev_ops;
 	netdev->watchdog_timeo = NICVF_TX_TIMEOUT;
diff --git a/drivers/net/ethernet/cavium/thunder/nicvf_queues.c b/drivers/net/ethernet/cavium/thunder/nicvf_queues.c
index 4fc40d83..b294d67 100644
--- a/drivers/net/ethernet/cavium/thunder/nicvf_queues.c
+++ b/drivers/net/ethernet/cavium/thunder/nicvf_queues.c
@@ -475,6 +475,27 @@ static void nicvf_reclaim_rbdr(struct nicvf *nic,
 		return;
 }
 
+void nicvf_config_vlan_stripping(struct nicvf *nic, netdev_features_t features)
+{
+	u64 rq_cfg;
+	int sqs;
+
+	rq_cfg = nicvf_queue_reg_read(nic, NIC_QSET_RQ_GEN_CFG, 0);
+
+	/* Enable first VLAN stripping */
+	if (features & NETIF_F_HW_VLAN_CTAG_RX)
+		rq_cfg |= (1ULL << 25);
+	else
+		rq_cfg &= ~(1ULL << 25);
+	nicvf_queue_reg_write(nic, NIC_QSET_RQ_GEN_CFG, 0, rq_cfg);
+
+	/* Configure Secondary Qsets, if any */
+	for (sqs = 0; sqs < nic->sqs_count; sqs++)
+		if (nic->snicvf[sqs])
+			nicvf_queue_reg_write(nic->snicvf[sqs],
+					      NIC_QSET_RQ_GEN_CFG, 0, rq_cfg);
+}
+
 /* Configures receive queue */
 static void nicvf_rcv_queue_config(struct nicvf *nic, struct queue_set *qs,
 				   int qidx, bool enable)
@@ -524,7 +545,9 @@ static void nicvf_rcv_queue_config(struct nicvf *nic, struct queue_set *qs,
 	mbx.rq.cfg = (1ULL << 62) | (RQ_CQ_DROP << 8);
 	nicvf_send_msg_to_pf(nic, &mbx);
 
-	nicvf_queue_reg_write(nic, NIC_QSET_RQ_GEN_CFG, qidx, 0x00);
+	nicvf_queue_reg_write(nic, NIC_QSET_RQ_GEN_CFG, 0, 0x00);
+	if (!nic->sqs_mode)
+		nicvf_config_vlan_stripping(nic, nic->netdev->features);
 
 	/* Enable Receive queue */
 	rq_cfg.ena = 1;
@@ -961,9 +984,6 @@ nicvf_sq_add_hdr_subdesc(struct snd_queue *sq, int qentry,
 
 	/* Offload checksum calculation to HW */
 	if (skb->ip_summed == CHECKSUM_PARTIAL) {
-		if (skb->protocol != htons(ETH_P_IP))
-			return;
-
 		hdr->csum_l3 = 1; /* Enable IP csum calculation */
 		hdr->l3_offset = skb_network_offset(skb);
 		hdr->l4_offset = skb_transport_offset(skb);
diff --git a/drivers/net/ethernet/cavium/thunder/nicvf_queues.h b/drivers/net/ethernet/cavium/thunder/nicvf_queues.h
index dc73872..8b93dd6 100644
--- a/drivers/net/ethernet/cavium/thunder/nicvf_queues.h
+++ b/drivers/net/ethernet/cavium/thunder/nicvf_queues.h
@@ -306,6 +306,8 @@ struct queue_set {
 
 #define	CQ_ERR_MASK	(CQ_WR_FULL | CQ_WR_DISABLE | CQ_WR_FAULT)
 
+void nicvf_config_vlan_stripping(struct nicvf *nic,
+				 netdev_features_t features);
 int nicvf_set_qset_resources(struct nicvf *nic);
 int nicvf_config_data_transfer(struct nicvf *nic, bool enable);
 void nicvf_qset_config(struct nicvf *nic, bool enable);
-- 
2.5.0



From aleksey.makarov at auriga.com  Fri Aug 28 08:00:00 2015
From: aleksey.makarov at auriga.com (Aleksey Makarov)
Date: Fri, 28 Aug 2015 18:00:00 +0300
Subject: [PATCH net-next 8/8] net: thunderx: Support for internal loopback mode
In-Reply-To: <1440774004-27923-1-git-send-email-aleksey.makarov@auriga.com>
References: <1440774004-27923-1-git-send-email-aleksey.makarov@auriga.com>
Message-ID: <1440774004-27923-8-git-send-email-aleksey.makarov@auriga.com>

From: Sunil Goutham <sgoutham at cavium.com>

Support for setting VF's corresponding BGX LMAC in internal
loopback mode. This mode can be used for verifying basic HW
functionality such as packet I/O, RX checksum validation,
CQ/RBDR interrupts, stats e.t.c. Useful when DUT has no external
network connectivity.

'loopback' mode can be enabled or disabled via ethtool.

Note: This feature is not supported when no of VFs enabled are
morethan no of physical interfaces i.e active BGX LMACs

Signed-off-by: Sunil Goutham <sgoutham at cavium.com>
Signed-off-by: Aleksey Makarov <aleksey.makarov at caviumnetworks.com>
---
 drivers/net/ethernet/cavium/thunder/nic.h         | 11 ++++++++
 drivers/net/ethernet/cavium/thunder/nic_main.c    | 21 +++++++++++++++
 drivers/net/ethernet/cavium/thunder/nicvf_main.c  | 30 ++++++++++++++++++++++
 drivers/net/ethernet/cavium/thunder/thunder_bgx.c | 31 +++++++++++++++++++++++
 drivers/net/ethernet/cavium/thunder/thunder_bgx.h |  4 +++
 5 files changed, 97 insertions(+)

diff --git a/drivers/net/ethernet/cavium/thunder/nic.h b/drivers/net/ethernet/cavium/thunder/nic.h
index 35b2ee1..d3950b2 100644
--- a/drivers/net/ethernet/cavium/thunder/nic.h
+++ b/drivers/net/ethernet/cavium/thunder/nic.h
@@ -265,6 +265,7 @@ struct nicvf {
 	u8			node;
 	u8			tns_mode:1;
 	u8			sqs_mode:1;
+	u8			loopback_supported:1;
 	u16			mtu;
 	struct queue_set	*qs;
 #define	MAX_SQS_PER_VF_SINGLE_NODE		5
@@ -344,6 +345,7 @@ struct nicvf {
 #define	NIC_MBOX_MSG_NICVF_PTR		0x13	/* Send nicvf ptr to PF */
 #define	NIC_MBOX_MSG_PNICVF_PTR		0x14	/* Get primary qset nicvf ptr */
 #define	NIC_MBOX_MSG_SNICVF_PTR		0x15	/* Send sqet nicvf ptr to PVF */
+#define	NIC_MBOX_MSG_LOOPBACK		0x16	/* Set interface in loopback */
 #define	NIC_MBOX_MSG_CFG_DONE		0xF0	/* VF configuration done */
 #define	NIC_MBOX_MSG_SHUTDOWN		0xF1	/* VF is being shutdown */
 
@@ -353,6 +355,7 @@ struct nic_cfg_msg {
 	u8    node_id;
 	u8    tns_mode:1;
 	u8    sqs_mode:1;
+	u8    loopback_supported:1;
 	u8    mac_addr[ETH_ALEN];
 };
 
@@ -452,6 +455,13 @@ struct nicvf_ptr {
 	u64   nicvf;
 };
 
+/* Set interface in loopback mode */
+struct set_loopback {
+	u8    msg;
+	u8    vf_id;
+	bool  enable;
+};
+
 /* 128 bit shared memory between PF and each VF */
 union nic_mbx {
 	struct { u8 msg; }	msg;
@@ -468,6 +478,7 @@ union nic_mbx {
 	struct bgx_link_status  link_status;
 	struct sqs_alloc        sqs_alloc;
 	struct nicvf_ptr	nicvf;
+	struct set_loopback	lbk;
 };
 
 #define NIC_NODE_ID_MASK	0x03
diff --git a/drivers/net/ethernet/cavium/thunder/nic_main.c b/drivers/net/ethernet/cavium/thunder/nic_main.c
index 51f3048..fd36820 100644
--- a/drivers/net/ethernet/cavium/thunder/nic_main.c
+++ b/drivers/net/ethernet/cavium/thunder/nic_main.c
@@ -154,6 +154,9 @@ static void nic_mbx_send_ready(struct nicpf *nic, int vf)
 	}
 	mbx.nic_cfg.sqs_mode = (vf >= nic->num_vf_en) ? true : false;
 	mbx.nic_cfg.node_id = nic->node;
+
+	mbx.nic_cfg.loopback_supported = vf < MAX_LMAC;
+
 	nic_send_msg_to_vf(nic, vf, &mbx);
 }
 
@@ -579,6 +582,21 @@ send_mbox:
 	nic_send_msg_to_vf(nic, sqs->vf_id, &mbx);
 }
 
+static int nic_config_loopback(struct nicpf *nic, struct set_loopback *lbk)
+{
+	int bgx_idx, lmac_idx;
+
+	if (lbk->vf_id > MAX_LMAC)
+		return -1;
+
+	bgx_idx = NIC_GET_BGX_FROM_VF_LMAC_MAP(nic->vf_lmac_map[lbk->vf_id]);
+	lmac_idx = NIC_GET_LMAC_FROM_VF_LMAC_MAP(nic->vf_lmac_map[lbk->vf_id]);
+
+	bgx_lmac_internal_loopback(nic->node, bgx_idx, lmac_idx, lbk->enable);
+
+	return 0;
+}
+
 /* Interrupt handler to handle mailbox messages from VFs */
 static void nic_handle_mbx_intr(struct nicpf *nic, int vf)
 {
@@ -702,6 +720,9 @@ static void nic_handle_mbx_intr(struct nicpf *nic, int vf)
 	case NIC_MBOX_MSG_BGX_STATS:
 		nic_get_bgx_stats(nic, &mbx.bgx_stats);
 		goto unlock;
+	case NIC_MBOX_MSG_LOOPBACK:
+		ret = nic_config_loopback(nic, &mbx.lbk);
+		break;
 	default:
 		dev_err(&nic->pdev->dev,
 			"Invalid msg from VF%d, msg 0x%x\n", vf, mbx.msg.msg);
diff --git a/drivers/net/ethernet/cavium/thunder/nicvf_main.c b/drivers/net/ethernet/cavium/thunder/nicvf_main.c
index 9a1091a..49228b6 100644
--- a/drivers/net/ethernet/cavium/thunder/nicvf_main.c
+++ b/drivers/net/ethernet/cavium/thunder/nicvf_main.c
@@ -202,6 +202,7 @@ static void  nicvf_handle_mbx_intr(struct nicvf *nic)
 			ether_addr_copy(nic->netdev->dev_addr,
 					mbx.nic_cfg.mac_addr);
 		nic->sqs_mode = mbx.nic_cfg.sqs_mode;
+		nic->loopback_supported = mbx.nic_cfg.loopback_supported;
 		nic->link_up = false;
 		nic->duplex = 0;
 		nic->speed = 0;
@@ -1404,6 +1405,30 @@ static void nicvf_reset_task(struct work_struct *work)
 	nic->netdev->trans_start = jiffies;
 }
 
+static int nicvf_config_loopback(struct nicvf *nic,
+				 netdev_features_t features)
+{
+	union nic_mbx mbx = {};
+
+	mbx.lbk.msg = NIC_MBOX_MSG_LOOPBACK;
+	mbx.lbk.vf_id = nic->vf_id;
+	mbx.lbk.enable = (features & NETIF_F_LOOPBACK) != 0;
+
+	return nicvf_send_msg_to_pf(nic, &mbx);
+}
+
+static netdev_features_t nicvf_fix_features(struct net_device *netdev,
+					    netdev_features_t features)
+{
+	struct nicvf *nic = netdev_priv(netdev);
+
+	if ((features & NETIF_F_LOOPBACK) &&
+	    netif_running(netdev) && !nic->loopback_supported)
+		features &= ~NETIF_F_LOOPBACK;
+
+	return features;
+}
+
 static int nicvf_set_features(struct net_device *netdev,
 			      netdev_features_t features)
 {
@@ -1413,6 +1438,9 @@ static int nicvf_set_features(struct net_device *netdev,
 	if (changed & NETIF_F_HW_VLAN_CTAG_RX)
 		nicvf_config_vlan_stripping(nic, features);
 
+	if ((changed & NETIF_F_LOOPBACK) && netif_running(netdev))
+		return nicvf_config_loopback(nic, features);
+
 	return 0;
 }
 
@@ -1424,6 +1452,7 @@ static const struct net_device_ops nicvf_netdev_ops = {
 	.ndo_set_mac_address	= nicvf_set_mac_address,
 	.ndo_get_stats64	= nicvf_get_stats64,
 	.ndo_tx_timeout         = nicvf_tx_timeout,
+	.ndo_fix_features       = nicvf_fix_features,
 	.ndo_set_features       = nicvf_set_features,
 };
 
@@ -1518,6 +1547,7 @@ static int nicvf_probe(struct pci_dev *pdev, const struct pci_device_id *ent)
 	netdev->hw_features |= NETIF_F_RXHASH;
 
 	netdev->features |= netdev->hw_features;
+	netdev->hw_features |= NETIF_F_LOOPBACK;
 
 	netdev->vlan_features = NETIF_F_SG | NETIF_F_IP_CSUM | NETIF_F_TSO;
 
diff --git a/drivers/net/ethernet/cavium/thunder/thunder_bgx.c b/drivers/net/ethernet/cavium/thunder/thunder_bgx.c
index 5e54186..574c492 100644
--- a/drivers/net/ethernet/cavium/thunder/thunder_bgx.c
+++ b/drivers/net/ethernet/cavium/thunder/thunder_bgx.c
@@ -329,6 +329,37 @@ static void bgx_flush_dmac_addrs(struct bgx *bgx, int lmac)
 	}
 }
 
+/* Configure BGX LMAC in internal loopback mode */
+void bgx_lmac_internal_loopback(int node, int bgx_idx,
+				int lmac_idx, bool enable)
+{
+	struct bgx *bgx;
+	struct lmac *lmac;
+	u64    cfg;
+
+	bgx = bgx_vnic[(node * MAX_BGX_PER_CN88XX) + bgx_idx];
+	if (!bgx)
+		return;
+
+	lmac = &bgx->lmac[lmac_idx];
+	if (lmac->is_sgmii) {
+		cfg = bgx_reg_read(bgx, lmac_idx, BGX_GMP_PCS_MRX_CTL);
+		if (enable)
+			cfg |= PCS_MRX_CTL_LOOPBACK1;
+		else
+			cfg &= ~PCS_MRX_CTL_LOOPBACK1;
+		bgx_reg_write(bgx, lmac_idx, BGX_GMP_PCS_MRX_CTL, cfg);
+	} else {
+		cfg = bgx_reg_read(bgx, lmac_idx, BGX_SPUX_CONTROL1);
+		if (enable)
+			cfg |= SPU_CTL_LOOPBACK;
+		else
+			cfg &= ~SPU_CTL_LOOPBACK;
+		bgx_reg_write(bgx, lmac_idx, BGX_SPUX_CONTROL1, cfg);
+	}
+}
+EXPORT_SYMBOL(bgx_lmac_internal_loopback);
+
 static int bgx_lmac_sgmii_init(struct bgx *bgx, int lmacid)
 {
 	u64 cfg;
diff --git a/drivers/net/ethernet/cavium/thunder/thunder_bgx.h b/drivers/net/ethernet/cavium/thunder/thunder_bgx.h
index ba4f53b..07b7ec6 100644
--- a/drivers/net/ethernet/cavium/thunder/thunder_bgx.h
+++ b/drivers/net/ethernet/cavium/thunder/thunder_bgx.h
@@ -72,6 +72,7 @@
 
 #define BGX_SPUX_CONTROL1		0x10000
 #define  SPU_CTL_LOW_POWER			BIT_ULL(11)
+#define  SPU_CTL_LOOPBACK			BIT_ULL(14)
 #define  SPU_CTL_RESET				BIT_ULL(15)
 #define BGX_SPUX_STATUS1		0x10008
 #define  SPU_STATUS1_RCV_LNK			BIT_ULL(2)
@@ -126,6 +127,7 @@
 #define	 PCS_MRX_CTL_RST_AN			BIT_ULL(9)
 #define	 PCS_MRX_CTL_PWR_DN			BIT_ULL(11)
 #define	 PCS_MRX_CTL_AN_EN			BIT_ULL(12)
+#define	 PCS_MRX_CTL_LOOPBACK1			BIT_ULL(14)
 #define	 PCS_MRX_CTL_RESET			BIT_ULL(15)
 #define BGX_GMP_PCS_MRX_STATUS		0x30008
 #define	 PCS_MRX_STATUS_AN_CPT			BIT_ULL(5)
@@ -186,6 +188,8 @@ int bgx_get_lmac_count(int node, int bgx);
 const u8 *bgx_get_lmac_mac(int node, int bgx_idx, int lmacid);
 void bgx_set_lmac_mac(int node, int bgx_idx, int lmacid, const u8 *mac);
 void bgx_get_lmac_link_state(int node, int bgx_idx, int lmacid, void *status);
+void bgx_lmac_internal_loopback(int node, int bgx_idx,
+				int lmac_idx, bool enable);
 u64 bgx_get_rx_stats(int node, int bgx_idx, int lmac, int idx);
 u64 bgx_get_tx_stats(int node, int bgx_idx, int lmac, int idx);
 #define BGX_RX_STATS_COUNT 11
-- 
2.5.0



From aleksey.makarov at auriga.com  Fri Aug 28 07:59:59 2015
From: aleksey.makarov at auriga.com (Aleksey Makarov)
Date: Fri, 28 Aug 2015 17:59:59 +0300
Subject: [PATCH net-next 7/8] net: thunderx: Support for upto 96 queues for a
 VF
In-Reply-To: <1440774004-27923-1-git-send-email-aleksey.makarov@auriga.com>
References: <1440774004-27923-1-git-send-email-aleksey.makarov@auriga.com>
Message-ID: <1440774004-27923-7-git-send-email-aleksey.makarov@auriga.com>

From: Sunil Goutham <sgoutham at cavium.com>

This patch adds support for handling multiple qsets assigned to a
single VF. There by increasing no of queues from earlier 8 to max
no of CPUs in the system i.e 48 queues on a single node and 96 on
dual node system. User doesn't have option to assign which Qsets/VFs
 to be merged. Upon request from VF, PF assigns next free Qsets as
secondary qsets. To maintain current behavior no of queues is kept
to 8 by default which can be increased via ethtool.

If user wants to unbind NICVF driver from a secondary Qset then it
should be done after tearing down primary VF's interface.

Signed-off-by: Sunil Goutham <sgoutham at cavium.com>
Signed-off-by: Aleksey Makarov <aleksey.makarov at caviumnetworks.com>
Signed-off-by: Robert Richter <rrichter at cavium.com>
---
 drivers/net/ethernet/cavium/thunder/nic.h          |  42 ++++-
 drivers/net/ethernet/cavium/thunder/nic_main.c     | 173 +++++++++++++++--
 .../net/ethernet/cavium/thunder/nicvf_ethtool.c    | 136 +++++++++----
 drivers/net/ethernet/cavium/thunder/nicvf_main.c   | 210 +++++++++++++++++++--
 drivers/net/ethernet/cavium/thunder/nicvf_queues.c |  32 +++-
 5 files changed, 507 insertions(+), 86 deletions(-)

diff --git a/drivers/net/ethernet/cavium/thunder/nic.h b/drivers/net/ethernet/cavium/thunder/nic.h
index 89b997e..35b2ee1 100644
--- a/drivers/net/ethernet/cavium/thunder/nic.h
+++ b/drivers/net/ethernet/cavium/thunder/nic.h
@@ -258,13 +258,23 @@ struct nicvf_drv_stats {
 };
 
 struct nicvf {
+	struct nicvf		*pnicvf;
 	struct net_device	*netdev;
 	struct pci_dev		*pdev;
 	u8			vf_id;
 	u8			node;
-	u8			tns_mode;
+	u8			tns_mode:1;
+	u8			sqs_mode:1;
 	u16			mtu;
 	struct queue_set	*qs;
+#define	MAX_SQS_PER_VF_SINGLE_NODE		5
+#define	MAX_SQS_PER_VF				11
+	u8			sqs_id;
+	u8			sqs_count; /* Secondary Qset count */
+	struct nicvf		*snicvf[MAX_SQS_PER_VF];
+	u8			rx_queues;
+	u8			tx_queues;
+	u8			max_queues;
 	void __iomem		*reg_base;
 	bool			link_up;
 	u8			duplex;
@@ -330,14 +340,19 @@ struct nicvf {
 #define	NIC_MBOX_MSG_RQ_SW_SYNC		0x0F	/* Flush inflight pkts to RQ */
 #define	NIC_MBOX_MSG_BGX_STATS		0x10	/* Get stats from BGX */
 #define	NIC_MBOX_MSG_BGX_LINK_CHANGE	0x11	/* BGX:LMAC link status */
-#define NIC_MBOX_MSG_CFG_DONE		0x12	/* VF configuration done */
-#define NIC_MBOX_MSG_SHUTDOWN		0x13	/* VF is being shutdown */
+#define	NIC_MBOX_MSG_ALLOC_SQS		0x12	/* Allocate secondary Qset */
+#define	NIC_MBOX_MSG_NICVF_PTR		0x13	/* Send nicvf ptr to PF */
+#define	NIC_MBOX_MSG_PNICVF_PTR		0x14	/* Get primary qset nicvf ptr */
+#define	NIC_MBOX_MSG_SNICVF_PTR		0x15	/* Send sqet nicvf ptr to PVF */
+#define	NIC_MBOX_MSG_CFG_DONE		0xF0	/* VF configuration done */
+#define	NIC_MBOX_MSG_SHUTDOWN		0xF1	/* VF is being shutdown */
 
 struct nic_cfg_msg {
 	u8    msg;
 	u8    vf_id;
-	u8    tns_mode;
 	u8    node_id;
+	u8    tns_mode:1;
+	u8    sqs_mode:1;
 	u8    mac_addr[ETH_ALEN];
 };
 
@@ -345,6 +360,7 @@ struct nic_cfg_msg {
 struct qs_cfg_msg {
 	u8    msg;
 	u8    num;
+	u8    sqs_count;
 	u64   cfg;
 };
 
@@ -361,6 +377,7 @@ struct sq_cfg_msg {
 	u8    msg;
 	u8    qs_num;
 	u8    sq_num;
+	bool  sqs_mode;
 	u64   cfg;
 };
 
@@ -420,6 +437,21 @@ struct bgx_link_status {
 	u32   speed;
 };
 
+/* Get Extra Qset IDs */
+struct sqs_alloc {
+	u8    msg;
+	u8    vf_id;
+	u8    qs_count;
+};
+
+struct nicvf_ptr {
+	u8    msg;
+	u8    vf_id;
+	bool  sqs_mode;
+	u8    sqs_id;
+	u64   nicvf;
+};
+
 /* 128 bit shared memory between PF and each VF */
 union nic_mbx {
 	struct { u8 msg; }	msg;
@@ -434,6 +466,8 @@ union nic_mbx {
 	struct rss_cfg_msg	rss_cfg;
 	struct bgx_stats_msg    bgx_stats;
 	struct bgx_link_status  link_status;
+	struct sqs_alloc        sqs_alloc;
+	struct nicvf_ptr	nicvf;
 };
 
 #define NIC_NODE_ID_MASK	0x03
diff --git a/drivers/net/ethernet/cavium/thunder/nic_main.c b/drivers/net/ethernet/cavium/thunder/nic_main.c
index 7dfec4a..51f3048 100644
--- a/drivers/net/ethernet/cavium/thunder/nic_main.c
+++ b/drivers/net/ethernet/cavium/thunder/nic_main.c
@@ -28,6 +28,11 @@ struct nicpf {
 	u8			num_vf_en;      /* No of VF enabled */
 	bool			vf_enabled[MAX_NUM_VFS_SUPPORTED];
 	void __iomem		*reg_base;       /* Register start address */
+	u8			num_sqs_en;	/* Secondary qsets enabled */
+	u64			nicvf[MAX_NUM_VFS_SUPPORTED];
+	u8			vf_sqs[MAX_NUM_VFS_SUPPORTED][MAX_SQS_PER_VF];
+	u8			pqs_vf[MAX_NUM_VFS_SUPPORTED];
+	bool			sqs_used[MAX_NUM_VFS_SUPPORTED];
 	struct pkind_cfg	pkind;
 #define	NIC_SET_VF_LMAC_MAP(bgx, lmac)	(((bgx & 0xF) << 4) | (lmac & 0xF))
 #define	NIC_GET_BGX_FROM_VF_LMAC_MAP(map)	((map >> 4) & 0xF)
@@ -139,13 +144,15 @@ static void nic_mbx_send_ready(struct nicpf *nic, int vf)
 
 	mbx.nic_cfg.tns_mode = NIC_TNS_BYPASS_MODE;
 
-	bgx_idx = NIC_GET_BGX_FROM_VF_LMAC_MAP(nic->vf_lmac_map[vf]);
-	lmac = NIC_GET_LMAC_FROM_VF_LMAC_MAP(nic->vf_lmac_map[vf]);
-
-	mac = bgx_get_lmac_mac(nic->node, bgx_idx, lmac);
-	if (mac)
-		ether_addr_copy((u8 *)&mbx.nic_cfg.mac_addr, mac);
+	if (vf < MAX_LMAC) {
+		bgx_idx = NIC_GET_BGX_FROM_VF_LMAC_MAP(nic->vf_lmac_map[vf]);
+		lmac = NIC_GET_LMAC_FROM_VF_LMAC_MAP(nic->vf_lmac_map[vf]);
 
+		mac = bgx_get_lmac_mac(nic->node, bgx_idx, lmac);
+		if (mac)
+			ether_addr_copy((u8 *)&mbx.nic_cfg.mac_addr, mac);
+	}
+	mbx.nic_cfg.sqs_mode = (vf >= nic->num_vf_en) ? true : false;
 	mbx.nic_cfg.node_id = nic->node;
 	nic_send_msg_to_vf(nic, vf, &mbx);
 }
@@ -433,6 +440,12 @@ static void nic_config_rss(struct nicpf *nic, struct rss_cfg_msg *cfg)
 	qset = cfg->vf_id;
 
 	for (; rssi < (rssi_base + cfg->tbl_len); rssi++) {
+		u8 svf = cfg->ind_tbl[idx] >> 3;
+
+		if (svf)
+			qset = nic->vf_sqs[cfg->vf_id][svf - 1];
+		else
+			qset = cfg->vf_id;
 		nic_reg_write(nic, NIC_PF_RSSI_0_4097_RQ | (rssi << 3),
 			      (qset << 3) | (cfg->ind_tbl[idx] & 0x7));
 		idx++;
@@ -456,19 +469,31 @@ static void nic_config_rss(struct nicpf *nic, struct rss_cfg_msg *cfg)
  * VNIC6-SQ0 -> TL4(528) -> TL3[132] -> TL2[33] -> TL1[1] -> BGX1
  * VNIC7-SQ0 -> TL4(536) -> TL3[134] -> TL2[33] -> TL1[1] -> BGX1
  */
-static void nic_tx_channel_cfg(struct nicpf *nic, u8 vnic, u8 sq_idx)
+static void nic_tx_channel_cfg(struct nicpf *nic, u8 vnic,
+			       struct sq_cfg_msg *sq)
 {
 	u32 bgx, lmac, chan;
 	u32 tl2, tl3, tl4;
 	u32 rr_quantum;
+	u8 sq_idx = sq->sq_num;
+	u8 pqs_vnic;
+
+	if (sq->sqs_mode)
+		pqs_vnic = nic->pqs_vf[vnic];
+	else
+		pqs_vnic = vnic;
+
+	bgx = NIC_GET_BGX_FROM_VF_LMAC_MAP(nic->vf_lmac_map[pqs_vnic]);
+	lmac = NIC_GET_LMAC_FROM_VF_LMAC_MAP(nic->vf_lmac_map[pqs_vnic]);
 
-	bgx = NIC_GET_BGX_FROM_VF_LMAC_MAP(nic->vf_lmac_map[vnic]);
-	lmac = NIC_GET_LMAC_FROM_VF_LMAC_MAP(nic->vf_lmac_map[vnic]);
 	/* 24 bytes for FCS, IPG and preamble */
 	rr_quantum = ((NIC_HW_MAX_FRS + 24) / 4);
 
 	tl4 = (lmac * NIC_TL4_PER_LMAC) + (bgx * NIC_TL4_PER_BGX);
 	tl4 += sq_idx;
+	if (sq->sqs_mode)
+		tl4 += vnic * 8;
+
 	tl3 = tl4 / (NIC_MAX_TL4 / NIC_MAX_TL3);
 	nic_reg_write(nic, NIC_PF_QSET_0_127_SQ_0_7_CFG2 |
 		      ((u64)vnic << NIC_QS_ID_SHIFT) |
@@ -489,6 +514,71 @@ static void nic_tx_channel_cfg(struct nicpf *nic, u8 vnic, u8 sq_idx)
 	nic_reg_write(nic, NIC_PF_TL2_0_63_PRI | (tl2 << 3), 0x00);
 }
 
+/* Send primary nicvf pointer to secondary QS's VF */
+static void nic_send_pnicvf(struct nicpf *nic, int sqs)
+{
+	union nic_mbx mbx = {};
+
+	mbx.nicvf.msg = NIC_MBOX_MSG_PNICVF_PTR;
+	mbx.nicvf.nicvf = nic->nicvf[nic->pqs_vf[sqs]];
+	nic_send_msg_to_vf(nic, sqs, &mbx);
+}
+
+/* Send SQS's nicvf pointer to primary QS's VF */
+static void nic_send_snicvf(struct nicpf *nic, struct nicvf_ptr *nicvf)
+{
+	union nic_mbx mbx = {};
+	int sqs_id = nic->vf_sqs[nicvf->vf_id][nicvf->sqs_id];
+
+	mbx.nicvf.msg = NIC_MBOX_MSG_SNICVF_PTR;
+	mbx.nicvf.sqs_id = nicvf->sqs_id;
+	mbx.nicvf.nicvf = nic->nicvf[sqs_id];
+	nic_send_msg_to_vf(nic, nicvf->vf_id, &mbx);
+}
+
+/* Find next available Qset that can be assigned as a
+ * secondary Qset to a VF.
+ */
+static int nic_nxt_avail_sqs(struct nicpf *nic)
+{
+	int sqs;
+
+	for (sqs = 0; sqs < nic->num_sqs_en; sqs++) {
+		if (!nic->sqs_used[sqs])
+			nic->sqs_used[sqs] = true;
+		else
+			continue;
+		return sqs + nic->num_vf_en;
+	}
+	return -1;
+}
+
+/* Allocate additional Qsets for requested VF */
+static void nic_alloc_sqs(struct nicpf *nic, struct sqs_alloc *sqs)
+{
+	union nic_mbx mbx = {};
+	int idx, alloc_qs = 0;
+	int sqs_id;
+
+	if (!nic->num_sqs_en)
+		goto send_mbox;
+
+	for (idx = 0; idx < sqs->qs_count; idx++) {
+		sqs_id = nic_nxt_avail_sqs(nic);
+		if (sqs_id < 0)
+			break;
+		nic->vf_sqs[sqs->vf_id][idx] = sqs_id;
+		nic->pqs_vf[sqs_id] = sqs->vf_id;
+		alloc_qs++;
+	}
+
+send_mbox:
+	mbx.sqs_alloc.msg = NIC_MBOX_MSG_ALLOC_SQS;
+	mbx.sqs_alloc.vf_id = sqs->vf_id;
+	mbx.sqs_alloc.qs_count = alloc_qs;
+	nic_send_msg_to_vf(nic, sqs->vf_id, &mbx);
+}
+
 /* Interrupt handler to handle mailbox messages from VFs */
 static void nic_handle_mbx_intr(struct nicpf *nic, int vf)
 {
@@ -496,6 +586,7 @@ static void nic_handle_mbx_intr(struct nicpf *nic, int vf)
 	u64 *mbx_data;
 	u64 mbx_addr;
 	u64 reg_addr;
+	u64 cfg;
 	int bgx, lmac;
 	int i;
 	int ret = 0;
@@ -516,15 +607,24 @@ static void nic_handle_mbx_intr(struct nicpf *nic, int vf)
 	switch (mbx.msg.msg) {
 	case NIC_MBOX_MSG_READY:
 		nic_mbx_send_ready(nic, vf);
-		nic->link[vf] = 0;
-		nic->duplex[vf] = 0;
-		nic->speed[vf] = 0;
+		if (vf < MAX_LMAC) {
+			nic->link[vf] = 0;
+			nic->duplex[vf] = 0;
+			nic->speed[vf] = 0;
+		}
 		ret = 1;
 		break;
 	case NIC_MBOX_MSG_QS_CFG:
 		reg_addr = NIC_PF_QSET_0_127_CFG |
 			   (mbx.qs.num << NIC_QS_ID_SHIFT);
-		nic_reg_write(nic, reg_addr, mbx.qs.cfg);
+		cfg = mbx.qs.cfg;
+		/* Check if its a secondary Qset */
+		if (vf >= nic->num_vf_en) {
+			cfg = cfg & (~0x7FULL);
+			/* Assign this Qset to primary Qset's VF */
+			cfg |= nic->pqs_vf[vf];
+		}
+		nic_reg_write(nic, reg_addr, cfg);
 		break;
 	case NIC_MBOX_MSG_RQ_CFG:
 		reg_addr = NIC_PF_QSET_0_127_RQ_0_7_CFG |
@@ -552,9 +652,11 @@ static void nic_handle_mbx_intr(struct nicpf *nic, int vf)
 			   (mbx.sq.qs_num << NIC_QS_ID_SHIFT) |
 			   (mbx.sq.sq_num << NIC_Q_NUM_SHIFT);
 		nic_reg_write(nic, reg_addr, mbx.sq.cfg);
-		nic_tx_channel_cfg(nic, mbx.qs.num, mbx.sq.sq_num);
+		nic_tx_channel_cfg(nic, mbx.qs.num, &mbx.sq);
 		break;
 	case NIC_MBOX_MSG_SET_MAC:
+		if (vf >= nic->num_vf_en)
+			break;
 		lmac = mbx.mac.vf_id;
 		bgx = NIC_GET_BGX_FROM_VF_LMAC_MAP(nic->vf_lmac_map[lmac]);
 		lmac = NIC_GET_LMAC_FROM_VF_LMAC_MAP(nic->vf_lmac_map[lmac]);
@@ -581,7 +683,22 @@ static void nic_handle_mbx_intr(struct nicpf *nic, int vf)
 	case NIC_MBOX_MSG_SHUTDOWN:
 		/* First msg in VF teardown sequence */
 		nic->vf_enabled[vf] = false;
+		if (vf >= nic->num_vf_en)
+			nic->sqs_used[vf - nic->num_vf_en] = false;
+		nic->pqs_vf[vf] = 0;
+		break;
+	case NIC_MBOX_MSG_ALLOC_SQS:
+		nic_alloc_sqs(nic, &mbx.sqs_alloc);
+		goto unlock;
+	case NIC_MBOX_MSG_NICVF_PTR:
+		nic->nicvf[vf] = mbx.nicvf.nicvf;
 		break;
+	case NIC_MBOX_MSG_PNICVF_PTR:
+		nic_send_pnicvf(nic, vf);
+		goto unlock;
+	case NIC_MBOX_MSG_SNICVF_PTR:
+		nic_send_snicvf(nic, &mbx.nicvf);
+		goto unlock;
 	case NIC_MBOX_MSG_BGX_STATS:
 		nic_get_bgx_stats(nic, &mbx.bgx_stats);
 		goto unlock;
@@ -610,8 +727,7 @@ static void nic_mbx_intr_handler (struct nicpf *nic, int mbx)
 		if (intr & (1ULL << vf)) {
 			dev_dbg(&nic->pdev->dev, "Intr from VF %d\n",
 				vf + (mbx * vf_per_mbx_reg));
-			if ((vf + (mbx * vf_per_mbx_reg)) > nic->num_vf_en)
-				break;
+
 			nic_handle_mbx_intr(nic, vf + (mbx * vf_per_mbx_reg));
 			nic_clear_mbx_intr(nic, vf, mbx);
 		}
@@ -717,9 +833,24 @@ static void nic_unregister_interrupts(struct nicpf *nic)
 	nic_disable_msix(nic);
 }
 
+static int nic_num_sqs_en(struct nicpf *nic, int vf_en)
+{
+	int pos = 0, sqs_per_vf = MAX_SQS_PER_VF_SINGLE_NODE;
+	u16 total_vf;
+
+	/* Check if its a multi-node environment */
+	if (nr_node_ids > 1)
+		sqs_per_vf = MAX_SQS_PER_VF;
+
+	pos = pci_find_ext_capability(nic->pdev, PCI_EXT_CAP_ID_SRIOV);
+	pci_read_config_word(nic->pdev, (pos + PCI_SRIOV_TOTAL_VF), &total_vf);
+	return min(total_vf - vf_en, vf_en * sqs_per_vf);
+}
+
 static int nic_sriov_init(struct pci_dev *pdev, struct nicpf *nic)
 {
 	int pos = 0;
+	int vf_en;
 	int err;
 	u16 total_vf_cnt;
 
@@ -736,16 +867,20 @@ static int nic_sriov_init(struct pci_dev *pdev, struct nicpf *nic)
 	if (!total_vf_cnt)
 		return 0;
 
-	err = pci_enable_sriov(pdev, nic->num_vf_en);
+	vf_en = nic->num_vf_en;
+	nic->num_sqs_en = nic_num_sqs_en(nic, nic->num_vf_en);
+	vf_en += nic->num_sqs_en;
+
+	err = pci_enable_sriov(pdev, vf_en);
 	if (err) {
 		dev_err(&pdev->dev, "SRIOV enable failed, num VF is %d\n",
-			nic->num_vf_en);
+			vf_en);
 		nic->num_vf_en = 0;
 		return err;
 	}
 
 	dev_info(&pdev->dev, "SRIOV enabled, number of VF available %d\n",
-		 nic->num_vf_en);
+		 vf_en);
 
 	nic->flags |= NIC_SRIOV_ENABLED;
 	return 0;
diff --git a/drivers/net/ethernet/cavium/thunder/nicvf_ethtool.c b/drivers/net/ethernet/cavium/thunder/nicvf_ethtool.c
index 1eec2cd..e4fa98a 100644
--- a/drivers/net/ethernet/cavium/thunder/nicvf_ethtool.c
+++ b/drivers/net/ethernet/cavium/thunder/nicvf_ethtool.c
@@ -149,10 +149,33 @@ static void nicvf_set_msglevel(struct net_device *netdev, u32 lvl)
 	nic->msg_enable = lvl;
 }
 
+static void nicvf_get_qset_strings(struct nicvf *nic, u8 **data, int qset)
+{
+	int stats, qidx;
+	int start_qidx = qset * MAX_RCV_QUEUES_PER_QS;
+
+	for (qidx = 0; qidx < nic->qs->rq_cnt; qidx++) {
+		for (stats = 0; stats < nicvf_n_queue_stats; stats++) {
+			sprintf(*data, "rxq%d: %s", qidx + start_qidx,
+				nicvf_queue_stats[stats].name);
+			*data += ETH_GSTRING_LEN;
+		}
+	}
+
+	for (qidx = 0; qidx < nic->qs->sq_cnt; qidx++) {
+		for (stats = 0; stats < nicvf_n_queue_stats; stats++) {
+			sprintf(*data, "txq%d: %s", qidx + start_qidx,
+				nicvf_queue_stats[stats].name);
+			*data += ETH_GSTRING_LEN;
+		}
+	}
+}
+
 static void nicvf_get_strings(struct net_device *netdev, u32 sset, u8 *data)
 {
 	struct nicvf *nic = netdev_priv(netdev);
-	int stats, qidx;
+	int stats;
+	int sqs;
 
 	if (sset != ETH_SS_STATS)
 		return;
@@ -167,20 +190,12 @@ static void nicvf_get_strings(struct net_device *netdev, u32 sset, u8 *data)
 		data += ETH_GSTRING_LEN;
 	}
 
-	for (qidx = 0; qidx < nic->qs->rq_cnt; qidx++) {
-		for (stats = 0; stats < nicvf_n_queue_stats; stats++) {
-			sprintf(data, "rxq%d: %s", qidx,
-				nicvf_queue_stats[stats].name);
-			data += ETH_GSTRING_LEN;
-		}
-	}
+	nicvf_get_qset_strings(nic, &data, 0);
 
-	for (qidx = 0; qidx < nic->qs->sq_cnt; qidx++) {
-		for (stats = 0; stats < nicvf_n_queue_stats; stats++) {
-			sprintf(data, "txq%d: %s", qidx,
-				nicvf_queue_stats[stats].name);
-			data += ETH_GSTRING_LEN;
-		}
+	for (sqs = 0; sqs < nic->sqs_count; sqs++) {
+		if (!nic->snicvf[sqs])
+			continue;
+		nicvf_get_qset_strings(nic->snicvf[sqs], &data, sqs + 1);
 	}
 
 	for (stats = 0; stats < BGX_RX_STATS_COUNT; stats++) {
@@ -197,21 +212,58 @@ static void nicvf_get_strings(struct net_device *netdev, u32 sset, u8 *data)
 static int nicvf_get_sset_count(struct net_device *netdev, int sset)
 {
 	struct nicvf *nic = netdev_priv(netdev);
+	int qstats_count;
+	int sqs;
 
 	if (sset != ETH_SS_STATS)
 		return -EINVAL;
 
+	qstats_count = nicvf_n_queue_stats *
+		       (nic->qs->rq_cnt + nic->qs->sq_cnt);
+	for (sqs = 0; sqs < nic->sqs_count; sqs++) {
+		struct nicvf *snic;
+
+		snic = nic->snicvf[sqs];
+		if (!snic)
+			continue;
+		qstats_count += nicvf_n_queue_stats *
+				(snic->qs->rq_cnt + snic->qs->sq_cnt);
+	}
+
 	return nicvf_n_hw_stats + nicvf_n_drv_stats +
-		(nicvf_n_queue_stats *
-		 (nic->qs->rq_cnt + nic->qs->sq_cnt)) +
+		qstats_count +
 		BGX_RX_STATS_COUNT + BGX_TX_STATS_COUNT;
 }
 
+static void nicvf_get_qset_stats(struct nicvf *nic,
+				 struct ethtool_stats *stats, u64 **data)
+{
+	int stat, qidx;
+
+	if (!nic)
+		return;
+
+	for (qidx = 0; qidx < nic->qs->rq_cnt; qidx++) {
+		nicvf_update_rq_stats(nic, qidx);
+		for (stat = 0; stat < nicvf_n_queue_stats; stat++)
+			*((*data)++) = ((u64 *)&nic->qs->rq[qidx].stats)
+					[nicvf_queue_stats[stat].index];
+	}
+
+	for (qidx = 0; qidx < nic->qs->sq_cnt; qidx++) {
+		nicvf_update_sq_stats(nic, qidx);
+		for (stat = 0; stat < nicvf_n_queue_stats; stat++)
+			*((*data)++) = ((u64 *)&nic->qs->sq[qidx].stats)
+					[nicvf_queue_stats[stat].index];
+	}
+}
+
 static void nicvf_get_ethtool_stats(struct net_device *netdev,
 				    struct ethtool_stats *stats, u64 *data)
 {
 	struct nicvf *nic = netdev_priv(netdev);
-	int stat, qidx;
+	int stat;
+	int sqs;
 
 	nicvf_update_stats(nic);
 
@@ -225,16 +277,12 @@ static void nicvf_get_ethtool_stats(struct net_device *netdev,
 		*(data++) = ((u64 *)&nic->drv_stats)
 				[nicvf_drv_stats[stat].index];
 
-	for (qidx = 0; qidx < nic->qs->rq_cnt; qidx++) {
-		for (stat = 0; stat < nicvf_n_queue_stats; stat++)
-			*(data++) = ((u64 *)&nic->qs->rq[qidx].stats)
-					[nicvf_queue_stats[stat].index];
-	}
+	nicvf_get_qset_stats(nic, stats, &data);
 
-	for (qidx = 0; qidx < nic->qs->sq_cnt; qidx++) {
-		for (stat = 0; stat < nicvf_n_queue_stats; stat++)
-			*(data++) = ((u64 *)&nic->qs->sq[qidx].stats)
-					[nicvf_queue_stats[stat].index];
+	for (sqs = 0; sqs < nic->sqs_count; sqs++) {
+		if (!nic->snicvf[sqs])
+			continue;
+		nicvf_get_qset_stats(nic->snicvf[sqs], stats, &data);
 	}
 
 	for (stat = 0; stat < BGX_RX_STATS_COUNT; stat++)
@@ -393,7 +441,7 @@ static int nicvf_get_rxnfc(struct net_device *dev,
 
 	switch (info->cmd) {
 	case ETHTOOL_GRXRINGS:
-		info->data = nic->qs->rq_cnt;
+		info->data = nic->rx_queues;
 		ret = 0;
 		break;
 	case ETHTOOL_GRXFH:
@@ -556,11 +604,11 @@ static void nicvf_get_channels(struct net_device *dev,
 
 	memset(channel, 0, sizeof(*channel));
 
-	channel->max_rx = MAX_RCV_QUEUES_PER_QS;
-	channel->max_tx = MAX_SND_QUEUES_PER_QS;
+	channel->max_rx = nic->max_queues;
+	channel->max_tx = nic->max_queues;
 
-	channel->rx_count = nic->qs->rq_cnt;
-	channel->tx_count = nic->qs->sq_cnt;
+	channel->rx_count = nic->rx_queues;
+	channel->tx_count = nic->tx_queues;
 }
 
 /* Set no of Tx, Rx queues to be used */
@@ -568,24 +616,36 @@ static int nicvf_set_channels(struct net_device *dev,
 			      struct ethtool_channels *channel)
 {
 	struct nicvf *nic = netdev_priv(dev);
-	int err = 0;
 	bool if_up = netif_running(dev);
+	int cqcount;
+	int err = 0;
 
 	if (!channel->rx_count || !channel->tx_count)
 		return -EINVAL;
-	if (channel->rx_count > MAX_RCV_QUEUES_PER_QS)
+	if (channel->rx_count > nic->max_queues)
 		return -EINVAL;
-	if (channel->tx_count > MAX_SND_QUEUES_PER_QS)
+	if (channel->tx_count > nic->max_queues)
 		return -EINVAL;
 
 	if (if_up)
 		nicvf_stop(dev);
 
-	nic->qs->rq_cnt = channel->rx_count;
-	nic->qs->sq_cnt = channel->tx_count;
+	cqcount = max(channel->rx_count, channel->tx_count);
+
+	if (cqcount > MAX_CMP_QUEUES_PER_QS) {
+		nic->sqs_count = roundup(cqcount, MAX_CMP_QUEUES_PER_QS);
+		nic->sqs_count = (nic->sqs_count / MAX_CMP_QUEUES_PER_QS) - 1;
+	} else {
+		nic->sqs_count = 0;
+	}
+
+	nic->qs->rq_cnt = min_t(u32, channel->rx_count, MAX_RCV_QUEUES_PER_QS);
+	nic->qs->sq_cnt = min_t(u32, channel->tx_count, MAX_SND_QUEUES_PER_QS);
 	nic->qs->cq_cnt = max(nic->qs->rq_cnt, nic->qs->sq_cnt);
 
-	err = nicvf_set_real_num_queues(dev, nic->qs->sq_cnt, nic->qs->rq_cnt);
+	nic->rx_queues = channel->rx_count;
+	nic->tx_queues = channel->tx_count;
+	err = nicvf_set_real_num_queues(dev, nic->tx_queues, nic->rx_queues);
 	if (err)
 		return err;
 
@@ -593,7 +653,7 @@ static int nicvf_set_channels(struct net_device *dev,
 		nicvf_open(dev);
 
 	netdev_info(dev, "Setting num Tx rings to %d, Rx rings to %d success\n",
-		    nic->qs->sq_cnt, nic->qs->rq_cnt);
+		    nic->tx_queues, nic->rx_queues);
 
 	return err;
 }
diff --git a/drivers/net/ethernet/cavium/thunder/nicvf_main.c b/drivers/net/ethernet/cavium/thunder/nicvf_main.c
index 2198f61..9a1091a 100644
--- a/drivers/net/ethernet/cavium/thunder/nicvf_main.c
+++ b/drivers/net/ethernet/cavium/thunder/nicvf_main.c
@@ -51,6 +51,14 @@ module_param(cpi_alg, int, S_IRUGO);
 MODULE_PARM_DESC(cpi_alg,
 		 "PFC algorithm (0=none, 1=VLAN, 2=VLAN16, 3=IP Diffserv)");
 
+static inline u8 nicvf_netdev_qidx(struct nicvf *nic, u8 qidx)
+{
+	if (nic->sqs_mode)
+		return qidx + ((nic->sqs_id + 1) * MAX_CMP_QUEUES_PER_QS);
+	else
+		return qidx;
+}
+
 static inline void nicvf_set_rx_frame_cnt(struct nicvf *nic,
 					  struct sk_buff *skb)
 {
@@ -193,6 +201,7 @@ static void  nicvf_handle_mbx_intr(struct nicvf *nic)
 		if (!nic->set_mac_pending)
 			ether_addr_copy(nic->netdev->dev_addr,
 					mbx.nic_cfg.mac_addr);
+		nic->sqs_mode = mbx.nic_cfg.sqs_mode;
 		nic->link_up = false;
 		nic->duplex = 0;
 		nic->speed = 0;
@@ -230,6 +239,26 @@ static void  nicvf_handle_mbx_intr(struct nicvf *nic)
 			netif_tx_stop_all_queues(nic->netdev);
 		}
 		break;
+	case NIC_MBOX_MSG_ALLOC_SQS:
+		nic->sqs_count = mbx.sqs_alloc.qs_count;
+		nic->pf_acked = true;
+		break;
+	case NIC_MBOX_MSG_SNICVF_PTR:
+		/* Primary VF: make note of secondary VF's pointer
+		 * to be used while packet transmission.
+		 */
+		nic->snicvf[mbx.nicvf.sqs_id] =
+			(struct nicvf *)mbx.nicvf.nicvf;
+		nic->pf_acked = true;
+		break;
+	case NIC_MBOX_MSG_PNICVF_PTR:
+		/* Secondary VF/Qset: make note of primary VF's pointer
+		 * to be used while packet reception, to handover packet
+		 * to primary VF's netdev.
+		 */
+		nic->pnicvf = (struct nicvf *)mbx.nicvf.nicvf;
+		nic->pf_acked = true;
+		break;
 	default:
 		netdev_err(nic->netdev,
 			   "Invalid message from PF, msg 0x%x\n", mbx.msg.msg);
@@ -338,11 +367,100 @@ static int nicvf_rss_init(struct nicvf *nic)
 
 	for (idx = 0; idx < rss->rss_size; idx++)
 		rss->ind_tbl[idx] = ethtool_rxfh_indir_default(idx,
-							       nic->qs->rq_cnt);
+							       nic->rx_queues);
 	nicvf_config_rss(nic);
 	return 1;
 }
 
+/* Request PF to allocate additional Qsets */
+static void nicvf_request_sqs(struct nicvf *nic)
+{
+	union nic_mbx mbx = {};
+	int sqs;
+	int sqs_count = nic->sqs_count;
+	int rx_queues = 0, tx_queues = 0;
+
+	/* Only primary VF should request */
+	if (nic->sqs_mode ||  !nic->sqs_count)
+		return;
+
+	mbx.sqs_alloc.msg = NIC_MBOX_MSG_ALLOC_SQS;
+	mbx.sqs_alloc.vf_id = nic->vf_id;
+	mbx.sqs_alloc.qs_count = nic->sqs_count;
+	if (nicvf_send_msg_to_pf(nic, &mbx)) {
+		/* No response from PF */
+		nic->sqs_count = 0;
+		return;
+	}
+
+	/* Return if no Secondary Qsets available */
+	if (!nic->sqs_count)
+		return;
+
+	if (nic->rx_queues > MAX_RCV_QUEUES_PER_QS)
+		rx_queues = nic->rx_queues - MAX_RCV_QUEUES_PER_QS;
+	if (nic->tx_queues > MAX_SND_QUEUES_PER_QS)
+		tx_queues = nic->tx_queues - MAX_SND_QUEUES_PER_QS;
+
+	/* Set no of Rx/Tx queues in each of the SQsets */
+	for (sqs = 0; sqs < nic->sqs_count; sqs++) {
+		mbx.nicvf.msg = NIC_MBOX_MSG_SNICVF_PTR;
+		mbx.nicvf.vf_id = nic->vf_id;
+		mbx.nicvf.sqs_id = sqs;
+		nicvf_send_msg_to_pf(nic, &mbx);
+
+		nic->snicvf[sqs]->sqs_id = sqs;
+		if (rx_queues > MAX_RCV_QUEUES_PER_QS) {
+			nic->snicvf[sqs]->qs->rq_cnt = MAX_RCV_QUEUES_PER_QS;
+			rx_queues -= MAX_RCV_QUEUES_PER_QS;
+		} else {
+			nic->snicvf[sqs]->qs->rq_cnt = rx_queues;
+			rx_queues = 0;
+		}
+
+		if (tx_queues > MAX_SND_QUEUES_PER_QS) {
+			nic->snicvf[sqs]->qs->sq_cnt = MAX_SND_QUEUES_PER_QS;
+			tx_queues -= MAX_SND_QUEUES_PER_QS;
+		} else {
+			nic->snicvf[sqs]->qs->sq_cnt = tx_queues;
+			tx_queues = 0;
+		}
+
+		nic->snicvf[sqs]->qs->cq_cnt =
+		max(nic->snicvf[sqs]->qs->rq_cnt, nic->snicvf[sqs]->qs->sq_cnt);
+
+		/* Initialize secondary Qset's queues and its interrupts */
+		nicvf_open(nic->snicvf[sqs]->netdev);
+	}
+
+	/* Update stack with actual Rx/Tx queue count allocated */
+	if (sqs_count != nic->sqs_count)
+		nicvf_set_real_num_queues(nic->netdev,
+					  nic->tx_queues, nic->rx_queues);
+}
+
+/* Send this Qset's nicvf pointer to PF.
+ * PF inturn sends primary VF's nicvf struct to secondary Qsets/VFs
+ * so that packets received by these Qsets can use primary VF's netdev
+ */
+static void nicvf_send_vf_struct(struct nicvf *nic)
+{
+	union nic_mbx mbx = {};
+
+	mbx.nicvf.msg = NIC_MBOX_MSG_NICVF_PTR;
+	mbx.nicvf.sqs_mode = nic->sqs_mode;
+	mbx.nicvf.nicvf = (u64)nic;
+	nicvf_send_msg_to_pf(nic, &mbx);
+}
+
+static void nicvf_get_primary_vf_struct(struct nicvf *nic)
+{
+	union nic_mbx mbx = {};
+
+	mbx.nicvf.msg = NIC_MBOX_MSG_PNICVF_PTR;
+	nicvf_send_msg_to_pf(nic, &mbx);
+}
+
 int nicvf_set_real_num_queues(struct net_device *netdev,
 			      int tx_queues, int rx_queues)
 {
@@ -453,6 +571,15 @@ static void nicvf_rcv_pkt_handler(struct net_device *netdev,
 	struct sk_buff *skb;
 	struct nicvf *nic = netdev_priv(netdev);
 	int err = 0;
+	int rq_idx;
+
+	rq_idx = nicvf_netdev_qidx(nic, cqe_rx->rq_idx);
+
+	if (nic->sqs_mode) {
+		/* Use primary VF's 'nicvf' struct */
+		nic = nic->pnicvf;
+		netdev = nic->netdev;
+	}
 
 	/* Check for errors */
 	err = nicvf_check_cqe_rx_errs(nic, cq, cqe_rx);
@@ -482,7 +609,7 @@ static void nicvf_rcv_pkt_handler(struct net_device *netdev,
 
 	nicvf_set_rxhash(netdev, cqe_rx, skb);
 
-	skb_record_rx_queue(skb, cqe_rx->rq_idx);
+	skb_record_rx_queue(skb, rq_idx);
 	if (netdev->hw_features & NETIF_F_RXCSUM) {
 		/* HW by default verifies TCP/UDP/SCTP checksums */
 		skb->ip_summed = CHECKSUM_UNNECESSARY;
@@ -578,8 +705,11 @@ loop:
 done:
 	/* Wakeup TXQ if its stopped earlier due to SQ full */
 	if (tx_done) {
-		txq = netdev_get_tx_queue(netdev, cq_idx);
-		if (netif_tx_queue_stopped(txq)) {
+		netdev = nic->pnicvf->netdev;
+		txq = netdev_get_tx_queue(netdev,
+					  nicvf_netdev_qidx(nic, cq_idx));
+		nic = nic->pnicvf;
+		if (netif_tx_queue_stopped(txq) && netif_carrier_ok(netdev)) {
 			netif_tx_start_queue(txq);
 			nic->drv_stats.txq_wake++;
 			if (netif_msg_tx_err(nic))
@@ -893,7 +1023,6 @@ static netdev_tx_t nicvf_xmit(struct sk_buff *skb, struct net_device *netdev)
 			netdev_warn(netdev,
 				    "%s: Transmit ring full, stopping SQ%d\n",
 				    netdev->name, qid);
-
 		return NETDEV_TX_BUSY;
 	}
 
@@ -926,6 +1055,17 @@ int nicvf_stop(struct net_device *netdev)
 	nicvf_send_msg_to_pf(nic, &mbx);
 
 	netif_carrier_off(netdev);
+	netif_tx_stop_all_queues(nic->netdev);
+
+	/* Teardown secondary qsets first */
+	if (!nic->sqs_mode) {
+		for (qidx = 0; qidx < nic->sqs_count; qidx++) {
+			if (!nic->snicvf[qidx])
+				continue;
+			nicvf_stop(nic->snicvf[qidx]->netdev);
+			nic->snicvf[qidx] = NULL;
+		}
+	}
 
 	/* Disable RBDR & QS error interrupts */
 	for (qidx = 0; qidx < qs->rbdr_cnt; qidx++) {
@@ -973,6 +1113,10 @@ int nicvf_stop(struct net_device *netdev)
 
 	nicvf_free_cq_poll(nic);
 
+	/* Clear multiqset info */
+	nic->pnicvf = nic;
+	nic->sqs_count = 0;
+
 	return 0;
 }
 
@@ -1028,10 +1172,16 @@ int nicvf_open(struct net_device *netdev)
 
 	/* Configure CPI alorithm */
 	nic->cpi_alg = cpi_alg;
-	nicvf_config_cpi(nic);
+	if (!nic->sqs_mode)
+		nicvf_config_cpi(nic);
+
+	nicvf_request_sqs(nic);
+	if (nic->sqs_mode)
+		nicvf_get_primary_vf_struct(nic);
 
 	/* Configure receive side scaling */
-	nicvf_rss_init(nic);
+	if (!nic->sqs_mode)
+		nicvf_rss_init(nic);
 
 	err = nicvf_register_interrupts(nic);
 	if (err)
@@ -1282,8 +1432,7 @@ static int nicvf_probe(struct pci_dev *pdev, const struct pci_device_id *ent)
 	struct device *dev = &pdev->dev;
 	struct net_device *netdev;
 	struct nicvf *nic;
-	struct queue_set *qs;
-	int    err;
+	int    err, qcount;
 
 	err = pci_enable_device(pdev);
 	if (err) {
@@ -1309,9 +1458,17 @@ static int nicvf_probe(struct pci_dev *pdev, const struct pci_device_id *ent)
 		goto err_release_regions;
 	}
 
-	netdev = alloc_etherdev_mqs(sizeof(struct nicvf),
-				    MAX_RCV_QUEUES_PER_QS,
-				    MAX_SND_QUEUES_PER_QS);
+	qcount = MAX_CMP_QUEUES_PER_QS;
+
+	/* Restrict multiqset support only for host bound VFs */
+	if (pdev->is_virtfn) {
+		/* Set max number of queues per VF */
+		qcount = roundup(num_online_cpus(), MAX_CMP_QUEUES_PER_QS);
+		qcount = min(qcount,
+			     (MAX_SQS_PER_VF + 1) * MAX_CMP_QUEUES_PER_QS);
+	}
+
+	netdev = alloc_etherdev_mqs(sizeof(struct nicvf), qcount, qcount);
 	if (!netdev) {
 		err = -ENOMEM;
 		goto err_release_regions;
@@ -1324,6 +1481,8 @@ static int nicvf_probe(struct pci_dev *pdev, const struct pci_device_id *ent)
 	nic = netdev_priv(netdev);
 	nic->netdev = netdev;
 	nic->pdev = pdev;
+	nic->pnicvf = nic;
+	nic->max_queues = qcount;
 
 	/* MAP VF's configuration registers */
 	nic->reg_base = pcim_iomap(pdev, PCI_CFG_REG_BAR_NUM, 0);
@@ -1337,20 +1496,26 @@ static int nicvf_probe(struct pci_dev *pdev, const struct pci_device_id *ent)
 	if (err)
 		goto err_free_netdev;
 
-	qs = nic->qs;
-
-	err = nicvf_set_real_num_queues(netdev, qs->sq_cnt, qs->rq_cnt);
-	if (err)
-		goto err_free_netdev;
-
 	/* Check if PF is alive and get MAC address for this VF */
 	err = nicvf_register_misc_interrupt(nic);
 	if (err)
 		goto err_free_netdev;
 
+	nicvf_send_vf_struct(nic);
+
+	/* Check if this VF is in QS only mode */
+	if (nic->sqs_mode)
+		return 0;
+
+	err = nicvf_set_real_num_queues(netdev, nic->tx_queues, nic->rx_queues);
+	if (err)
+		goto err_unregister_interrupts;
+
 	netdev->hw_features = (NETIF_F_RXCSUM | NETIF_F_IP_CSUM | NETIF_F_SG |
 			       NETIF_F_TSO | NETIF_F_GRO |
-			       NETIF_F_HW_VLAN_CTAG_RX | NETIF_F_RXHASH);
+			       NETIF_F_HW_VLAN_CTAG_RX);
+
+	netdev->hw_features |= NETIF_F_RXHASH;
 
 	netdev->features |= netdev->hw_features;
 
@@ -1389,8 +1554,13 @@ static void nicvf_remove(struct pci_dev *pdev)
 {
 	struct net_device *netdev = pci_get_drvdata(pdev);
 	struct nicvf *nic = netdev_priv(netdev);
+	struct net_device *pnetdev = nic->pnicvf->netdev;
 
-	unregister_netdev(netdev);
+	/* Check if this Qset is assigned to different VF.
+	 * If yes, clean primary and all secondary Qsets.
+	 */
+	if (pnetdev && (pnetdev->reg_state == NETREG_REGISTERED))
+		unregister_netdev(pnetdev);
 	nicvf_unregister_interrupts(nic);
 	pci_set_drvdata(pdev, NULL);
 	free_netdev(netdev);
diff --git a/drivers/net/ethernet/cavium/thunder/nicvf_queues.c b/drivers/net/ethernet/cavium/thunder/nicvf_queues.c
index b294d67..63a870a 100644
--- a/drivers/net/ethernet/cavium/thunder/nicvf_queues.c
+++ b/drivers/net/ethernet/cavium/thunder/nicvf_queues.c
@@ -478,7 +478,7 @@ static void nicvf_reclaim_rbdr(struct nicvf *nic,
 void nicvf_config_vlan_stripping(struct nicvf *nic, netdev_features_t features)
 {
 	u64 rq_cfg;
-	int sqs;
+	int sqs = 0;
 
 	rq_cfg = nicvf_queue_reg_read(nic, NIC_QSET_RQ_GEN_CFG, 0);
 
@@ -621,6 +621,7 @@ static void nicvf_snd_queue_config(struct nicvf *nic, struct queue_set *qs,
 	mbx.sq.msg = NIC_MBOX_MSG_SQ_CFG;
 	mbx.sq.qs_num = qs->vnic_id;
 	mbx.sq.sq_num = qidx;
+	mbx.sq.sqs_mode = nic->sqs_mode;
 	mbx.sq.cfg = (sq->cq_qs << 3) | sq->cq_idx;
 	nicvf_send_msg_to_pf(nic, &mbx);
 
@@ -702,6 +703,7 @@ void nicvf_qset_config(struct nicvf *nic, bool enable)
 	/* Send a mailbox msg to PF to config Qset */
 	mbx.qs.msg = NIC_MBOX_MSG_QS_CFG;
 	mbx.qs.num = qs->vnic_id;
+	mbx.qs.sqs_count = nic->sqs_count;
 
 	mbx.qs.cfg = 0;
 	qs_cfg = (struct qs_cfg *)&mbx.qs.cfg;
@@ -782,6 +784,10 @@ int nicvf_set_qset_resources(struct nicvf *nic)
 	qs->rbdr_len = RCV_BUF_COUNT;
 	qs->sq_len = SND_QUEUE_LEN;
 	qs->cq_len = CMP_QUEUE_LEN;
+
+	nic->rx_queues = qs->rq_cnt;
+	nic->tx_queues = qs->sq_cnt;
+
 	return 0;
 }
 
@@ -1025,7 +1031,7 @@ static inline void nicvf_sq_add_gather_subdesc(struct snd_queue *sq, int qentry,
  * them to SQ for transfer
  */
 static int nicvf_sq_append_tso(struct nicvf *nic, struct snd_queue *sq,
-			       int qentry, struct sk_buff *skb)
+			       int sq_num, int qentry, struct sk_buff *skb)
 {
 	struct tso_t tso;
 	int seg_subdescs = 0, desc_cnt = 0;
@@ -1085,7 +1091,7 @@ static int nicvf_sq_append_tso(struct nicvf *nic, struct snd_queue *sq,
 
 	/* Inform HW to xmit all TSO segments */
 	nicvf_queue_reg_write(nic, NIC_QSET_SQ_0_7_DOOR,
-			      skb_get_queue_mapping(skb), desc_cnt);
+			      sq_num, desc_cnt);
 	nic->drv_stats.tx_tso++;
 	return 1;
 }
@@ -1096,10 +1102,24 @@ int nicvf_sq_append_skb(struct nicvf *nic, struct sk_buff *skb)
 	int i, size;
 	int subdesc_cnt;
 	int sq_num, qentry;
-	struct queue_set *qs = nic->qs;
+	struct queue_set *qs;
 	struct snd_queue *sq;
 
 	sq_num = skb_get_queue_mapping(skb);
+	if (sq_num >= MAX_SND_QUEUES_PER_QS) {
+		/* Get secondary Qset's SQ structure */
+		i = sq_num / MAX_SND_QUEUES_PER_QS;
+		if (!nic->snicvf[i - 1]) {
+			netdev_warn(nic->netdev,
+				    "Secondary Qset#%d's ptr not initialized\n",
+				    i - 1);
+			return 1;
+		}
+		nic = (struct nicvf *)nic->snicvf[i - 1];
+		sq_num = sq_num % MAX_SND_QUEUES_PER_QS;
+	}
+
+	qs = nic->qs;
 	sq = &qs->sq[sq_num];
 
 	subdesc_cnt = nicvf_sq_subdesc_required(nic, skb);
@@ -1110,7 +1130,7 @@ int nicvf_sq_append_skb(struct nicvf *nic, struct sk_buff *skb)
 
 	/* Check if its a TSO packet */
 	if (skb_shinfo(skb)->gso_size)
-		return nicvf_sq_append_tso(nic, sq, qentry, skb);
+		return nicvf_sq_append_tso(nic, sq, sq_num, qentry, skb);
 
 	/* Add SQ header subdesc */
 	nicvf_sq_add_hdr_subdesc(sq, qentry, subdesc_cnt - 1, skb, skb->len);
@@ -1146,6 +1166,8 @@ doorbell:
 	return 1;
 
 append_fail:
+	/* Use original PCI dev for debug log */
+	nic = nic->pnicvf;
 	netdev_dbg(nic->netdev, "Not enough SQ descriptors to xmit pkt\n");
 	return 0;
 }
-- 
2.5.0



From julien.grall at citrix.com  Fri Aug 28 08:10:24 2015
From: julien.grall at citrix.com (Julien Grall)
Date: Fri, 28 Aug 2015 16:10:24 +0100
Subject: [Xen-devel] [PATCH v3 12/20] xen/balloon: Don't rely on the page
 granularity is the same for Xen and Linux
In-Reply-To: <55D5A51D.2060106@citrix.com>
References: <1438966019-19322-1-git-send-email-julien.grall@citrix.com>
 <1438966019-19322-13-git-send-email-julien.grall@citrix.com>
 <55D5A51D.2060106@citrix.com>
Message-ID: <55E079E0.3000507@citrix.com>

On 20/08/15 10:59, David Vrabel wrote:
> On 07/08/15 17:46, Julien Grall wrote:
>> For ARM64 guests, Linux is able to support either 64K or 4K page
>> granularity. Although, the hypercall interface is always based on 4K
>> page granularity.
>>
>> With 64K page granularity, a single page will be spread over multiple
>> Xen frame.
>>
>> To avoid splitting the page into 4K frame, take advantage of the
>> extent_order field to directly allocate/free chunk of the Linux page
>> size.
>>
>> Note that PVMMU is only used for PV guest (which is x86) and the page
>> granularity is always 4KB. Some BUILD_BUG_ON has been added to ensure
>> that because the code has not been modified.
> [...]
>>  #ifdef CONFIG_XEN_HAVE_PVMMU
>> +		/* We don't support PV MMU when Linux and Xen is using
>> +		 * different page granularity.
>> +		 */
>> +		BUILD_BUG_ON(XEN_PAGE_SIZE != PAGE_SIZE);
> 
> You don't need this BUILD_BUG_ON() twice.

I put twice the BUILD_BUG_ON so if we ever decide to drop one of the
#ifdef CONFIG_XEN_HAVE_PVMMU, the check will still be present.

So I'd like to keep it.

> Otherwise,
> 
> Reviewed-by: David Vrabel <david.vrabel at citrix.com>

Based on the discussion with Stefano I rework a bit the balloon code to
re-use lru field (see [1]), so I won't retain your reviewed-by on the
next series.

Regards,

[1] http://lists.xen.org/archives/html/xen-devel/2015-08/msg00781.html

-- 
Julien Grall


From Nathan_Lynch at mentor.com  Fri Aug 28 08:23:14 2015
From: Nathan_Lynch at mentor.com (Nathan Lynch)
Date: Fri, 28 Aug 2015 10:23:14 -0500
Subject: [PATCH v2 4/4] remoteproc: debugfs: Add ability to boot remote
 processor using debugfs
In-Reply-To: <1440757911-9120-5-git-send-email-lee.jones@linaro.org>
References: <1440757911-9120-1-git-send-email-lee.jones@linaro.org>
 <1440757911-9120-5-git-send-email-lee.jones@linaro.org>
Message-ID: <55E07CE2.2050704@mentor.com>

On 08/28/2015 05:31 AM, Lee Jones wrote:
> +static ssize_t rproc_state_write(struct file *filp, const char __user *userbuf,
> +				 size_t count, loff_t *ppos)
> +{
> +	struct rproc *rproc = filp->private_data;
> +	char buf[2];
> +	int ret;
> +
> +	ret = copy_from_user(buf, userbuf, 1);
> +	if (ret)
> +		return -EFAULT;
> +
> +	switch (buf[0]) {
> +	case '0':
> +		rproc_shutdown(rproc);
> +		break;
> +	case '1':
> +		ret = rproc_boot(rproc);
> +		if (ret)
> +			dev_warn(&rproc->dev, "Boot failed: %d\n", ret);
> +		break;
> +	default:
> +		dev_err(&rproc->dev, "Unrecognised option: %x\n", buf[1]);
> +		return -EINVAL;

This prints uninitialized kernel stack contents instead of what was
copied from user space.

Is the dev_err statement really necessary anyway?


> +	}
> +
> +	return count;
> +}

If rproc_boot fails, that should be reflected in the syscall result.

This interface is essentially exposing the remoteproc->power refcount to
user space; is that okay?  Seems like it makes it easy to underflow
remoteproc->power through successive shutdown calls.

The other debugfs interface in remoteproc that has a write method
(recovery) accepts more expressive string commands as opposed to 0/1.
It would be more consistent for this interface to take commands such as
"boot" and "shutdown" IMO.



From grygorii.strashko at ti.com  Fri Aug 28 08:27:39 2015
From: grygorii.strashko at ti.com (Grygorii Strashko)
Date: Fri, 28 Aug 2015 18:27:39 +0300
Subject: [PATCH v2] ARM: OMAP2+: omap-device: fix race deferred probe of
 omap_hsmmc vs omap_device_late_init
Message-ID: <1440775659-21014-1-git-send-email-grygorii.strashko@ti.com>

Kernel fails to boot 50% of times (form build to build) with
RT-patchset applied due to the following race - on late boot
stages deferred_probe_work_func->omap_hsmmc_probe races with omap_device_late_ini.

The same issue has been reported now on linux-next (4.3) by Keerthy [1]

late_initcall
 - deferred_probe_initcal() tries to re-probe all pending driver's probe.

- later on, some driver is probing in this case It's cpsw.c
  (but could be any other drivers)
  cpsw_init
  - platform_driver_register
    - really_probe
       - driver_bound
         - driver_deferred_probe_trigger
  and boot proceed.
  So, at this moment we have deferred_probe_work_func scheduled.

late_initcall_sync
  - omap_device_late_init
    - omap_device_idle

CPU1					CPU2
  - deferred_probe_work_func
    - really_probe
      - omap_hsmmc_probe
	- pm_runtime_get_sync
					late_initcall_sync
					- omap_device_late_init
						if (od->_driver_status != BUS_NOTIFY_BOUND_DRIVER) {
							if (od->_state == OMAP_DEVICE_STATE_ENABLED) {
								- omap_device_idle [ops - IP is disabled]
	- [fail]
	- pm_runtime_put_sync
          - omap_hsmmc_runtime_suspend [ooops!]

== log ==
 omap_hsmmc 480b4000.mmc: unable to get vmmc regulator -517
 davinci_mdio 48485000.mdio: davinci mdio revision 1.6
 davinci_mdio 48485000.mdio: detected phy mask fffffff3
 libphy: 48485000.mdio: probed
 davinci_mdio 48485000.mdio: phy[2]: device 48485000.mdio:02, driver unknown
 davinci_mdio 48485000.mdio: phy[3]: device 48485000.mdio:03, driver unknown
 omap_hsmmc 480b4000.mmc: unable to get vmmc regulator -517
 cpsw 48484000.ethernet: Detected MACID = b4:99:4c:c7:d2:48
 cpsw 48484000.ethernet: cpsw: Detected MACID = b4:99:4c:c7:d2:49
 hctosys: unable to open rtc device (rtc0)
 omap_hsmmc 480b4000.mmc: omap_device_late_idle: enabled but no driver.  Idling
 ldousb: disabling
 Unhandled fault: imprecise external abort (0x1406) at 0x00000000
 [00000000] *pgd=00000000
 Internal error: : 1406 [#1] PREEMPT SMP ARM
 Modules linked in:
 CPU: 1 PID: 58 Comm: kworker/u4:1 Not tainted 4.1.2-rt1-00467-g6da3c0a-dirty #5
 Hardware name: Generic DRA74X (Flattened Device Tree)
 Workqueue: deferwq deferred_probe_work_func
 task: ee6ddb00 ti: edd3c000 task.ti: edd3c000
 PC is at omap_hsmmc_runtime_suspend+0x1c/0x12c
 LR is at _od_runtime_suspend+0xc/0x24
 pc : [<c0471998>]    lr : [<c0029590>]    psr: a0000013
 sp : edd3dda0  ip : ee6ddb00  fp : c07be540
 r10: 00000000  r9 : c07be540  r8 : 00000008
 r7 : 00000000  r6 : ee646c10  r5 : ee646c10  r4 : edd79380
 r3 : fa0b4100  r2 : 00000000  r1 : 00000000  r0 : ee646c10
 Flags: NzCv  IRQs on  FIQs on  Mode SVC_32  ISA ARM  Segment kernel
 Control: 10c5387d  Table: 8000406a  DAC: 00000015
 Process kworker/u4:1 (pid: 58, stack limit = 0xedd3c218)
 Stack: (0xedd3dda0 to 0xedd3e000)
 dda0: ee646c70 ee646c10 c0029584 00000000 00000008 c0029590 ee646c70 ee646c10
 ddc0: c0029584 c03adfb8 ee646c10 00000004 0000000c c03adff0 ee646c10 00000004
 dde0: 0000000c c03ae4ec 00000000 edd3c000 ee646c10 00000004 ee646c70 00000004
 de00: fa0b4000 c03aec20 ee6ddb00 ee646c10 00000004 ee646c70 ee646c10 fffffdfb
 de20: edd79380 00000000 fa0b4000 c03aee90 fffffdfb edd79000 ee646c00 c0474290
 de40: 00000000 edda24c0 edd79380 edc81f00 00000000 00000200 00000001 c06dd488
 de60: edda3960 ee646c10 ee646c10 c0824cc4 fffffdfb c0880c94 00000002 edc92600
 de80: c0836378 c03a7f84 ee646c10 c0824cc4 00000000 c0880c80 c0880c94 c03a6568
 dea0: 00000000 ee646c10 c03a66ac ee4f8000 00000000 00000001 edc92600 c03a4b40
 dec0: ee404c94 edc83c4c ee646c10 ee646c10 ee646c44 c03a63c4 ee646c10 ee646c10
 dee0: c0814448 c03a5aa8 ee646c10 c0814220 edd3c000 c03a5ec0 c0814250 ee6be400
 df00: edd3c000 c004e5bc ee6ddb01 00000078 ee6ddb00 ee4f8000 ee6be418 edd3c000
 df20: ee4f8028 00000088 c0836045 ee4f8000 ee6be400 c004e928 ee4f8028 00000000
 df40: c004e8ec 00000000 ee6bf1c0 ee6be400 c004e8ec 00000000 00000000 00000000
 df60: 00000000 c0053450 2e56fa97 00000000 afdffbd7 ee6be400 00000000 00000000
 df80: edd3df80 edd3df80 00000000 00000000 edd3df90 edd3df90 edd3dfac ee6bf1c0
 dfa0: c0053384 00000000 00000000 c000f668 00000000 00000000 00000000 00000000
 dfc0: 00000000 00000000 00000000 00000000 00000000 00000000 00000000 00000000
 dfe0: 00000000 00000000 00000000 00000000 00000013 00000000 f1fc9d7e febfbdff
 [<c0471998>] (omap_hsmmc_runtime_suspend) from [<c0029590>] (_od_runtime_suspend+0xc/0x24)
 [<c0029590>] (_od_runtime_suspend) from [<c03adfb8>] (__rpm_callback+0x24/0x3c)
 [<c03adfb8>] (__rpm_callback) from [<c03adff0>] (rpm_callback+0x20/0x80)
 [<c03adff0>] (rpm_callback) from [<c03ae4ec>] (rpm_suspend+0xe4/0x618)
 [<c03ae4ec>] (rpm_suspend) from [<c03aee90>] (__pm_runtime_idle+0x60/0x80)
 [<c03aee90>] (__pm_runtime_idle) from [<c0474290>] (omap_hsmmc_probe+0x6bc/0xa7c)
 [<c0474290>] (omap_hsmmc_probe) from [<c03a7f84>] (platform_drv_probe+0x44/0xa4)
 [<c03a7f84>] (platform_drv_probe) from [<c03a6568>] (driver_probe_device+0x170/0x2b4)
 [<c03a6568>] (driver_probe_device) from [<c03a4b40>] (bus_for_each_drv+0x64/0x98)
 [<c03a4b40>] (bus_for_each_drv) from [<c03a63c4>] (device_attach+0x70/0x88)
 [<c03a63c4>] (device_attach) from [<c03a5aa8>] (bus_probe_device+0x84/0xac)
 [<c03a5aa8>] (bus_probe_device) from [<c03a5ec0>] (deferred_probe_work_func+0x58/0x88)
 [<c03a5ec0>] (deferred_probe_work_func) from [<c004e5bc>] (process_one_work+0x134/0x464)
 [<c004e5bc>] (process_one_work) from [<c004e928>] (worker_thread+0x3c/0x4fc)
 [<c004e928>] (worker_thread) from [<c0053450>] (kthread+0xcc/0xe4)
 [<c0053450>] (kthread) from [<c000f668>] (ret_from_fork+0x14/0x2c)
 Code: e594302c e593202c e584205c e594302c (e5932128)
 ---[ end trace 0000000000000002 ]---

The issue happens because omap_device_late_init() do not take into
account that some drivers are present, but their probes were not
finished successfully and where deferred instead. This is the valid
case, and omap_device_late_init() should not idle such devices.

To fix this issue, the value of omap_device->_driver_status field
should be checked not only for BUS_NOTIFY_BOUND_DRIVER (driver is
present and has been bound to device successfully), but also checked
for BUS_NOTIFY_BIND_DRIVER (driver about to be bound) - which means
driver is present and there was try to bind it to device.

[1] http://www.spinics.net/lists/arm-kernel/msg441880.html
Cc: Tero Kristo <t-kristo at ti.com>
Cc: Keerthy <j-keerthy at ti.com>
Tested-by: Keerthy <j-keerthy at ti.com>
Signed-off-by: Grygorii Strashko <grygorii.strashko at ti.com>
---
Changes in v2:
 - implementation changed: added additional check for BUS_NOTIFY_BIND_DRIVER
   instead of removing omap_device_late_init.

Link on v1:
 http://www.spinics.net/lists/arm-kernel/msg441594.html

 arch/arm/mach-omap2/omap_device.c | 3 ++-
 1 file changed, 2 insertions(+), 1 deletion(-)

diff --git a/arch/arm/mach-omap2/omap_device.c b/arch/arm/mach-omap2/omap_device.c
index 4cb8fd9..72ebc4c 100644
--- a/arch/arm/mach-omap2/omap_device.c
+++ b/arch/arm/mach-omap2/omap_device.c
@@ -901,7 +901,8 @@ static int __init omap_device_late_idle(struct device *dev, void *data)
 		if (od->hwmods[i]->flags & HWMOD_INIT_NO_IDLE)
 			return 0;
 
-	if (od->_driver_status != BUS_NOTIFY_BOUND_DRIVER) {
+	if (od->_driver_status != BUS_NOTIFY_BOUND_DRIVER &&
+	    od->_driver_status != BUS_NOTIFY_BIND_DRIVER) {
 		if (od->_state == OMAP_DEVICE_STATE_ENABLED) {
 			dev_warn(dev, "%s: enabled but no driver.  Idling\n",
 				 __func__);
-- 
2.5.0



From lorenzo.pieralisi at arm.com  Fri Aug 28 08:32:12 2015
From: lorenzo.pieralisi at arm.com (Lorenzo Pieralisi)
Date: Fri, 28 Aug 2015 16:32:12 +0100
Subject: [PATCH] ARM64: kernel: implement ACPI parking protocol
In-Reply-To: <1440772186.31961.8.camel@redhat.com>
References: <1436959990-32054-1-git-send-email-lorenzo.pieralisi@arm.com>
 <1437063431.3583.2.camel@redhat.com>
 <20150716171221.GB18582@red-moon>
 <1437068449.3583.4.camel@redhat.com>
 <20150828102314.GC15924@red-moon>
 <1440772186.31961.8.camel@redhat.com>
Message-ID: <20150828153212.GG15924@red-moon>

[Cc'ing Leif and Ard]

On Fri, Aug 28, 2015 at 03:29:46PM +0100, Mark Salter wrote:
> On Fri, 2015-08-28 at 11:23 +0100, Lorenzo Pieralisi wrote:
> > Mark,
> > 
> > On Thu, Jul 16, 2015 at 06:40:49PM +0100, Mark Salter wrote:
> > 
> > [...]
> > 
> > > On Thu, 2015-07-16 at 18:12 +0100, Lorenzo Pieralisi wrote:
> > > > > The kernel will only add cached memory regions to linear mapping 
> > > > > and
> > > > > presumably, the FW will mark the mailboxes as uncached. Otherwise, 
> > > > > it
> > > > > is a FW bug. But I suppose we could run into problems with kernels
> > > > > using 64K pagesize since firmware assumes 4k.
> > > > 
> > > > Nope, ioremap takes care of that, everything should be fine.
> > > 
> > > The mailbox is 4K. If it is next to a cached UEFI region, the kernel 
> > > may
> > > have to overlap the mailbox with a cached 64K mapping in order to 
> > > include
> > > the adjoining UEFI region in the linear map. Then the ioremap would 
> > > fail
> > > because the mailbox is included in the linear mapping.
> > 
> > So that I understand: are you referring to memrange_efi_to_native()
> > in arch/arm64/kernel/efi.c ? Is it safe to round up (and add it to
> > the memblock layer) the memory region size to PAGE_SIZE without checking
> > attributes of overlapping (within PAGE_SIZE) UEFI regions ?
> 
> The problem is that nothing in the UEFI spec or parking protocol spec
> prevents firmware from placing a 4K parking protocol mailbox area in
> the same 64K page as normal cached memory which winds up mapped in
> the kernel linear mapping. The kernel might be able to work around
> that by not putting the 64K page in the linear map. There's nothing
> the kernel could do if the mailbox is in same 64K page with UEFI runtime
> memory which would use a cached mapping.

Ok, I failed to explain myself. Let's imagine that we have a, say, 64k
aligned memory region (EFI_MEMORY_WB - size 16k) that lives in the same
64K memory frame as a device's registers memory space.
The code I pointed at above creates a 64K memory frame out of the 16K
region and adds it to the memblock so that it ends up in the kernel linear
mapping which ends up mapping the device registers too with cacheable
attributes and that's not correct.

I am not sure what's the best way to solve that, probably we should
amend the UEFI specs to enforce uniform 64K memory region attributes,
comments welcome.

Thanks,
Lorenzo


From julien.grall at citrix.com  Fri Aug 28 08:33:25 2015
From: julien.grall at citrix.com (Julien Grall)
Date: Fri, 28 Aug 2015 16:33:25 +0100
Subject: [PATCH v3 15/20] block/xen-blkfront: Make it running on 64KB
 page granularity
In-Reply-To: <55D58B6F.8010904@citrix.com>
References: <1438966019-19322-1-git-send-email-julien.grall@citrix.com>
 <1438966019-19322-16-git-send-email-julien.grall@citrix.com>
 <55D58B6F.8010904@citrix.com>
Message-ID: <55E07F45.5020501@citrix.com>

On 20/08/15 09:10, Roger Pau Monn? wrote:
> Hello,

Hi,

> I have some comments regarding the commit message, IMHO it would be good
> that a native English speaker reviews it too.
> 
> El 07/08/15 a les 18.46, Julien Grall ha escrit:
>> The PV block protocol is using 4KB page granularity. The goal of this
>> patch is to allow a Linux using 64KB page granularity using block
>> device on a non-modified Xen.
>>
>> The block API is using segment which should at least be the size of a
>> Linux page. Therefore, the driver will have to break the page in chunk
>> of 4K before giving the page to the backend.
>>
>> Breaking a 64KB segment in 4KB chunk will result to have some chunk with
>> no data.
> 
> I would rewrite the above line as:
> 
> When breaking a 64KB segment into 4KB chunks it is possible that some
Correct,
> chunks are empty.

Sounds good, I will replace with it.

>> As the PV protocol always require to have data in the chunk, we
>> have to count the number of Xen page which will be in use and avoid to
>                                   ^pages
>> sent empty chunk.
>   ^and avoid sending empty chunks.
>>
>> Note that, a pre-defined number of grant is reserved before preparing
>                                      ^grants are
>> the request. This pre-defined number is based on the number and the
>> maximum size of the segments. If each segment contain a very small
>                                                 ^contains
>> amount of data, the driver may reserve too much grant (16 grant is
>                                              ^many grants   ^grants are
>> reserved per segment with 64KB page granularity).
>>
>> Futhermore, in the case of persistent grant we allocate one Linux page
>                                         ^grants
>> per grant although only the 4KB of the page will be effectively use.
>                              ^first                              ^in
>> This could be improved by share the page with multiple grants.
>                             ^sharing
>>
>> Signed-off-by: Julien Grall <julien.grall at citrix.com>
> 
> LGTM:
> 
> Acked-by: Roger Pau Monn? <roger.pau at citrix.com>

Thank you, I will fix all the typos in the next version.

> Just one question.

[..]

>> +		gnttab_foreach_grant_in_range(sg_page(sg),
>> +					      sg->offset,
>> +					      sg->length,
>> +					      blkif_setup_rw_req_grant,
>> +					      &setup);
> 
> If I'm understanding this right, on x86 gnttab_foreach_grant_in_range is
> only going to perform one iteration, since XEN_PAGE_SIZE == PAGE_SIZE.

Correct, it will only perform when iteration for x86 but also for arm32
and arm64 (when 4KB page is in use).

Regards,

-- 
Julien Grall


From matthias.bgg at gmail.com  Fri Aug 28 08:36:29 2015
From: matthias.bgg at gmail.com (Matthias Brugger)
Date: Fri, 28 Aug 2015 17:36:29 +0200
Subject: [PATCH v5 0/8] arm64, numa: Add numa support for arm64 platforms.
In-Reply-To: <CAFpQJXUYycrvxp_p=A_pmeNUpHVs=8kYUfZP9dYDhYLqeCTZ3Q@mail.gmail.com>
References: <1439570374-4079-1-git-send-email-gkulkarni@caviumnetworks.com>
 <55E070D6.8060604@gmail.com>
 <CAFpQJXUYycrvxp_p=A_pmeNUpHVs=8kYUfZP9dYDhYLqeCTZ3Q@mail.gmail.com>
Message-ID: <55E07FFD.6030204@gmail.com>



On 28/08/15 16:59, Ganapatrao Kulkarni wrote:
> On Fri, Aug 28, 2015 at 8:01 PM, Matthias Brugger
> <matthias.bgg at gmail.com> wrote:
>>
>>
>> On 14/08/15 18:39, Ganapatrao Kulkarni wrote:
>>>
>>> v5:
>>>          - created base verion of numa.c which creates dummy numa without
>>> using dt
>>>            on single socket platforms. Then added patches for dt support.
>>>          - Incorporated review comments from Hanjun Guo.
>>>
>>> v4:
>>> done changes as per Arnd review comments.
>>>
>>> v3:
>>> Added changes to support numa on arm64 based platforms.
>>> Tested these patches on cavium's multinode(2 node topology) platform.
>>> In this patchset, defined and implemented dt bindings for numa mapping
>>> for core and memory using device node property arm,associativity.
>>>
>>> v2:
>>> Defined and implemented numa map for memory, cores to node and
>>> proximity distance matrix of nodes.
>>>
>>> v1:
>>> Initial patchset to support numa on arm64 platforms.
>>>
>>> Note:
>>>          1. This patchset is tested for numa with dt on
>>>             thunderx single socket and dual socket boards.
>>>          2. Numa DT booting needs the dt memory nodes, which are deleted in
>>> current efi-stub,
>>>          hence to try numa with dt, you need to rebase with ard's patchset.
>>>
>>> http://git.linaro.org/people/ard.biesheuvel/linux-arm.git/shortlog/refs/heads/arm64-uefi-early-fdt-handling
>>>
>>>
>>> Ganapatrao Kulkarni (4):
>>>     arm64, numa: adding numa support for arm64 platforms.
>>>     Documentation: arm64/arm: dt bindings for numa.
>>>     arm64, numa: adding numa support for arm64 platforms.
>>>     arm64, dt, thunderx: Add initial dts for Cavium Thunder SoC in 2 Node
>>>       topology.
>>>
>>>    Documentation/devicetree/bindings/arm/numa.txt  | 212 +++++++
>>>    arch/arm64/Kconfig                              |  32 +
>>>    arch/arm64/boot/dts/cavium/Makefile             |   2 +-
>>>    arch/arm64/boot/dts/cavium/thunder-88xx-2n.dts  |  78 +++
>>>    arch/arm64/boot/dts/cavium/thunder-88xx-2n.dtsi | 790
>>> ++++++++++++++++++++++++
>>>    arch/arm64/include/asm/mmzone.h                 |  32 +
>>>    arch/arm64/include/asm/numa.h                   |  49 ++
>>>    arch/arm64/kernel/Makefile                      |   1 +
>>>    arch/arm64/kernel/dt_numa.c                     | 316 ++++++++++
>>>    arch/arm64/kernel/setup.c                       |   9 +
>>>    arch/arm64/kernel/smp.c                         |   3 +
>>>    arch/arm64/mm/Makefile                          |   1 +
>>>    arch/arm64/mm/init.c                            |  34 +-
>>>    arch/arm64/mm/numa.c                            | 563 +++++++++++++++++
>>>    14 files changed, 2115 insertions(+), 7 deletions(-)
>>>    create mode 100644 Documentation/devicetree/bindings/arm/numa.txt
>>>    create mode 100644 arch/arm64/boot/dts/cavium/thunder-88xx-2n.dts
>>>    create mode 100644 arch/arm64/boot/dts/cavium/thunder-88xx-2n.dtsi
>>>    create mode 100644 arch/arm64/include/asm/mmzone.h
>>>    create mode 100644 arch/arm64/include/asm/numa.h
>>>    create mode 100644 arch/arm64/kernel/dt_numa.c
>>>    create mode 100644 arch/arm64/mm/numa.c
>>>
>>
>> On which version is this patch-set based?
> 4.2 -rc5

Seems as if
"arm64: add support for memtest" (36dd9086cb)
is not taken into account. I wasn't able to apply the set without 
conflicts, neither on v4.2-rc5, v4.2-rc8, nor on
arm64-uefi-early-fdt-handling.

Regards,
Matthias


From robherring2 at gmail.com  Fri Aug 28 08:41:19 2015
From: robherring2 at gmail.com (Rob Herring)
Date: Fri, 28 Aug 2015 10:41:19 -0500
Subject: [PATCH v2 2/5] ARM: NSP: add minimal Northstar Plus device tree
In-Reply-To: <1440628530-6137-3-git-send-email-jonmason@broadcom.com>
References: <1440628530-6137-1-git-send-email-jonmason@broadcom.com>
 <1440628530-6137-3-git-send-email-jonmason@broadcom.com>
Message-ID: <CAL_JsqJb+Pj7c=3Q9ViPhU_=tJxqOzEhOPALctf-zaFHQv+bWg@mail.gmail.com>

On Wed, Aug 26, 2015 at 5:35 PM, Jon Mason <jonmason at broadcom.com> wrote:
> Add a very minimalistic set of Northstar Plus Device Tree files which
> describes the SoC and the BCM958625 implementation.  The perpherials
> described are:
>
> ARM Cortex A9 CPU
> 2 8250 UARTs
> ARM GIC
> PL310 L2 Cache
> ARM A9 Global timer
>
> Signed-off-by: Kapil Hali <kapilh at broadcom.com>
> Signed-off-by: Jon Mason <jonmason at broadcom.com>
> ---
>  arch/arm/boot/dts/Makefile       |   2 +
>  arch/arm/boot/dts/bcm-nsp.dtsi   | 105 +++++++++++++++++++++++++++++++++++++++
>  arch/arm/boot/dts/bcm958625k.dts |  57 +++++++++++++++++++++
>  3 files changed, 164 insertions(+)
>  create mode 100644 arch/arm/boot/dts/bcm-nsp.dtsi
>  create mode 100644 arch/arm/boot/dts/bcm958625k.dts
>
> diff --git a/arch/arm/boot/dts/Makefile b/arch/arm/boot/dts/Makefile
> index 246473a..adb5732 100644
> --- a/arch/arm/boot/dts/Makefile
> +++ b/arch/arm/boot/dts/Makefile
> @@ -82,6 +82,8 @@ dtb-$(CONFIG_ARCH_BCM_CYGNUS) += \
>  dtb-$(CONFIG_ARCH_BCM_MOBILE) += \
>         bcm28155-ap.dtb \
>         bcm21664-garnet.dtb
> +dtb-$(CONFIG_ARCH_BCM_NSP) += \
> +       bcm958625k.dtb
>  dtb-$(CONFIG_ARCH_BERLIN) += \
>         berlin2-sony-nsz-gs7.dtb \
>         berlin2cd-google-chromecast.dtb \
> diff --git a/arch/arm/boot/dts/bcm-nsp.dtsi b/arch/arm/boot/dts/bcm-nsp.dtsi
> new file mode 100644
> index 0000000..77f9bfc
> --- /dev/null
> +++ b/arch/arm/boot/dts/bcm-nsp.dtsi
> @@ -0,0 +1,105 @@
> +/*
> + *  BSD LICENSE
> + *
> + *  Copyright(c) 2015 Broadcom Corporation.  All rights reserved.
> + *
> + *  Redistribution and use in source and binary forms, with or without
> + *  modification, are permitted provided that the following conditions
> + *  are met:
> + *
> + *    * Redistributions of source code must retain the above copyright
> + *      notice, this list of conditions and the following disclaimer.
> + *    * Redistributions in binary form must reproduce the above copyright
> + *      notice, this list of conditions and the following disclaimer in
> + *      the documentation and/or other materials provided with the
> + *      distribution.
> + *    * Neither the name of Broadcom Corporation nor the names of its
> + *      contributors may be used to endorse or promote products derived
> + *      from this software without specific prior written permission.
> + *
> + *  THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
> + *  "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
> + *  LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
> + *  A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
> + *  OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
> + *  SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
> + *  LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
> + *  DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
> + *  THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
> + *  (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
> + *  OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
> + */
> +
> +#include <dt-bindings/interrupt-controller/arm-gic.h>
> +#include <dt-bindings/interrupt-controller/irq.h>
> +
> +#include "skeleton.dtsi"
> +
> +/ {
> +       compatible = "brcm,nsp";
> +       model = "Broadcom Northstar Plus SoC";
> +       interrupt-parent = <&gic>;
> +
> +       cpus {
> +               #address-cells = <1>;
> +               #size-cells = <0>;
> +
> +               cpu at 0 {
> +                       device_type = "cpu";
> +                       compatible = "arm,cortex-a9";
> +                       next-level-cache = <&L2>;
> +                       reg = <0x0>;
> +               };
> +       };
> +
> +       clocks {
> +               #address-cells = <1>;
> +               #size-cells = <1>;
> +               ranges;
> +
> +               periph_clk: periph_clk {
> +                       compatible = "fixed-clock";
> +                       #clock-cells = <0>;
> +                       clock-frequency = <500000000>;
> +               };
> +       };
> +
> +       uart0: serial at 18000300 {

All these devices should go under a bus node.

> +               compatible = "ns16550a";
> +               reg = <0x18000300 0x100>;
> +               interrupts = <GIC_SPI 85 IRQ_TYPE_LEVEL_HIGH>;
> +               clock-frequency = <62499840>;
> +               status = "disabled";
> +       };
> +
> +       uart1: serial at 18000400 {
> +               compatible = "ns16550a";
> +               reg = <0x18000400 0x100>;
> +               interrupts = <GIC_SPI 85 IRQ_TYPE_LEVEL_HIGH>;
> +               clock-frequency = <62499840>;
> +               status = "disabled";
> +       };
> +
> +       gic: interrupt-controller at 19021000 {
> +               compatible = "arm,cortex-a9-gic";
> +               #interrupt-cells = <3>;
> +               #address-cells = <0>;
> +               interrupt-controller;
> +               reg = <0x19021000 0x1000>,
> +                     <0x19020100 0x100>;
> +       };
> +
> +       L2: l2-cache {
> +               compatible = "arm,pl310-cache";
> +               reg = <0x19022000 0x1000>;
> +               cache-unified;
> +               cache-level = <2>;
> +       };
> +
> +       timer at 19020200 {
> +               compatible = "arm,cortex-a9-global-timer";
> +               reg = <0x19020200 0x100>;
> +               interrupts = <GIC_PPI 11 IRQ_TYPE_LEVEL_HIGH>;
> +               clocks = <&periph_clk>;
> +       };
> +};
> diff --git a/arch/arm/boot/dts/bcm958625k.dts b/arch/arm/boot/dts/bcm958625k.dts
> new file mode 100644
> index 0000000..16303db
> --- /dev/null
> +++ b/arch/arm/boot/dts/bcm958625k.dts
> @@ -0,0 +1,57 @@
> +/*
> + *  BSD LICENSE
> + *
> + *  Copyright(c) 2015 Broadcom Corporation.  All rights reserved.
> + *
> + *  Redistribution and use in source and binary forms, with or without
> + *  modification, are permitted provided that the following conditions
> + *  are met:
> + *
> + *    * Redistributions of source code must retain the above copyright
> + *      notice, this list of conditions and the following disclaimer.
> + *    * Redistributions in binary form must reproduce the above copyright
> + *      notice, this list of conditions and the following disclaimer in
> + *      the documentation and/or other materials provided with the
> + *      distribution.
> + *    * Neither the name of Broadcom Corporation nor the names of its
> + *      contributors may be used to endorse or promote products derived
> + *      from this software without specific prior written permission.
> + *
> + *  THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
> + *  "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
> + *  LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
> + *  A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
> + *  OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
> + *  SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
> + *  LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
> + *  DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
> + *  THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
> + *  (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
> + *  OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
> + */
> +
> +/dts-v1/;
> +
> +#include "bcm-nsp.dtsi"
> +
> +/ {
> +       model = "NorthStar Plus SVK (BCM958625K)";
> +       compatible = "brcm,bcm58625", "brcm,nsp";
> +
> +       aliases {
> +               serial0 = &uart0;
> +               serial1 = &uart1;
> +       };
> +
> +       chosen {
> +               stdout-path = "serial0:115200n8";
> +       };
> +};
> +
> +&uart0 {
> +       status = "okay";
> +};
> +
> +&uart1 {
> +       status = "okay";
> +};
> --
> 1.9.1
>


From msalter at redhat.com  Fri Aug 28 08:56:36 2015
From: msalter at redhat.com (Mark Salter)
Date: Fri, 28 Aug 2015 11:56:36 -0400
Subject: [PATCH] ARM64: kernel: implement ACPI parking protocol
In-Reply-To: <20150828153212.GG15924@red-moon>
References: <1436959990-32054-1-git-send-email-lorenzo.pieralisi@arm.com>
 <1437063431.3583.2.camel@redhat.com> <20150716171221.GB18582@red-moon>
 <1437068449.3583.4.camel@redhat.com> <20150828102314.GC15924@red-moon>
 <1440772186.31961.8.camel@redhat.com> <20150828153212.GG15924@red-moon>
Message-ID: <1440777396.31961.13.camel@redhat.com>

On Fri, 2015-08-28 at 16:32 +0100, Lorenzo Pieralisi wrote:
> [Cc'ing Leif and Ard]
> 
> On Fri, Aug 28, 2015 at 03:29:46PM +0100, Mark Salter wrote:
> > On Fri, 2015-08-28 at 11:23 +0100, Lorenzo Pieralisi wrote:
> > > Mark,
> > > 
> > > On Thu, Jul 16, 2015 at 06:40:49PM +0100, Mark Salter wrote:
> > > 
> > > [...]
> > > 
> > > > On Thu, 2015-07-16 at 18:12 +0100, Lorenzo Pieralisi wrote:
> > > > > > The kernel will only add cached memory regions to linear 
> > > > > > mapping 
> > > > > > and
> > > > > > presumably, the FW will mark the mailboxes as uncached. 
> > > > > > Otherwise, 
> > > > > > it
> > > > > > is a FW bug. But I suppose we could run into problems with 
> > > > > > kernels
> > > > > > using 64K pagesize since firmware assumes 4k.
> > > > > 
> > > > > Nope, ioremap takes care of that, everything should be fine.
> > > > 
> > > > The mailbox is 4K. If it is next to a cached UEFI region, the 
> > > > kernel 
> > > > may
> > > > have to overlap the mailbox with a cached 64K mapping in order to 
> > > > include
> > > > the adjoining UEFI region in the linear map. Then the ioremap would 
> > > > fail
> > > > because the mailbox is included in the linear mapping.
> > > 
> > > So that I understand: are you referring to memrange_efi_to_native()
> > > in arch/arm64/kernel/efi.c ? Is it safe to round up (and add it to
> > > the memblock layer) the memory region size to PAGE_SIZE without 
> > > checking
> > > attributes of overlapping (within PAGE_SIZE) UEFI regions ?
> > 
> > The problem is that nothing in the UEFI spec or parking protocol spec
> > prevents firmware from placing a 4K parking protocol mailbox area in
> > the same 64K page as normal cached memory which winds up mapped in
> > the kernel linear mapping. The kernel might be able to work around
> > that by not putting the 64K page in the linear map. There's nothing
> > the kernel could do if the mailbox is in same 64K page with UEFI 
> > runtime
> > memory which would use a cached mapping.
> 
> Ok, I failed to explain myself. Let's imagine that we have a, say, 64k
> aligned memory region (EFI_MEMORY_WB - size 16k) that lives in the same
> 64K memory frame as a device's registers memory space.
> The code I pointed at above creates a 64K memory frame out of the 16K
> region and adds it to the memblock so that it ends up in the kernel 
> linear
> mapping which ends up mapping the device registers too with cacheable
> attributes and that's not correct.
> 
> I am not sure what's the best way to solve that, probably we should
> amend the UEFI specs to enforce uniform 64K memory region attributes,
> comments welcome.

OIC. Well it is a potential problem. Hardware designers do some whacky
things, but I'd like to think I/O regions and cached mem regions bordering
on such a small power of two boundary is not one of them.

> 
> Thanks,
> Lorenzo



From michael at dinsnail.net  Fri Aug 28 08:58:26 2015
From: michael at dinsnail.net (Michael Weiser)
Date: Fri, 28 Aug 2015 17:58:26 +0200
Subject: no booting due to handle_domain_irq on orion5x/kurobox
Message-ID: <20150828155826.GD2776@dinsnail.net>

Hi,

I've got vanilla kernels running on a Buffalo Linkstation Pro
(orion5x/Kurobox Pro). The last release kernel to work is 3.17.8.
Anything after that just says "Uncompressing Linux... Ok. booting the
kernel" and stops. 

By building and booting various intermediate stages from git, I've
narrowed it down to the following three commits:

76ba59f8366f2d9282cb5bda9de75b4b68cbe55f genirq: Add irq_domain-aware core IRQ handler
a71b092a9c68685a270ebdde7b5986ba8787e575 ARM: Convert handle_IRQ to use __handle_domain_irq
f4bc9288b4a29ead48425dd7d1bf4b825a8aff58 irqchip: orion: Convert to handle_domain_irq

If I revert those from an otherwise unmodified current
torvalds/linux.git HEAD it boots up just fine.

I'm afraid that's as far as my kernel debugging know-how will take me.
Any help in how to proceed further in order to get current kernels
running on my box would be highly appreciated.
-- 
Thanks,
Michael


From marcel.ziswiler at toradex.com  Fri Aug 28 08:59:37 2015
From: marcel.ziswiler at toradex.com (Marcel Ziswiler)
Date: Fri, 28 Aug 2015 17:59:37 +0200
Subject: [PATCH 02/11] arm: tegra: colibri_t30: fix hdmi supply
In-Reply-To: <1440777586-19545-1-git-send-email-marcel.ziswiler@toradex.com>
References: <1440777586-19545-1-git-send-email-marcel.ziswiler@toradex.com>
Message-ID: <1440777586-19545-3-git-send-email-marcel.ziswiler@toradex.com>

Fix HDMI supplies (both regular VDD as well as PLL ones) being switched
by the TPS65911 PMIC's GPIO6 aka EN_VDD_HDMI by introducing two new
GPIO switched fixed regulators avdd_hdmi_pll_1v8_reg and
avdd_hdmi_3v3_reg.

Signed-off-by: Marcel Ziswiler <marcel.ziswiler at toradex.com>
---

 arch/arm/boot/dts/tegra30-colibri.dtsi | 32 +++++++++++++++++++++++++++-----
 1 file changed, 27 insertions(+), 5 deletions(-)

diff --git a/arch/arm/boot/dts/tegra30-colibri.dtsi b/arch/arm/boot/dts/tegra30-colibri.dtsi
index 83ba3f2..5e6a47e 100644
--- a/arch/arm/boot/dts/tegra30-colibri.dtsi
+++ b/arch/arm/boot/dts/tegra30-colibri.dtsi
@@ -15,8 +15,8 @@
 
 	host1x at 50000000 {
 		hdmi at 54280000 {
-			vdd-supply = <&sys_3v3_reg>;
-			pll-supply = <&vio_reg>;
+			vdd-supply = <&avdd_hdmi_3v3_reg>;
+			pll-supply = <&avdd_hdmi_pll_1v8_reg>;
 
 			nvidia,hpd-gpio =
 				<&gpio TEGRA_GPIO(N, 7) GPIO_ACTIVE_HIGH>;
@@ -365,18 +365,40 @@
 		#address-cells = <1>;
 		#size-cells = <0>;
 
-		sys_3v3_reg: regulator at 100 {
+		avdd_hdmi_pll_1v8_reg: regulator at 100 {
 			compatible = "regulator-fixed";
 			reg = <100>;
+			regulator-name = "+V1.8_AVDD_HDMI_PLL";
+			regulator-min-microvolt = <1800000>;
+			regulator-max-microvolt = <1800000>;
+			enable-active-high;
+			gpio = <&pmic 6 GPIO_ACTIVE_HIGH>;
+			vin-supply = <&vio_reg>;
+		};
+
+		sys_3v3_reg: regulator at 101 {
+			compatible = "regulator-fixed";
+			reg = <101>;
 			regulator-name = "3v3";
 			regulator-min-microvolt = <3300000>;
 			regulator-max-microvolt = <3300000>;
 			regulator-always-on;
 		};
 
-		charge_pump_5v0_reg: regulator at 101 {
+		avdd_hdmi_3v3_reg: regulator at 102 {
 			compatible = "regulator-fixed";
-			reg = <101>;
+			reg = <102>;
+			regulator-name = "+V3.3_AVDD_HDMI";
+			regulator-min-microvolt = <3300000>;
+			regulator-max-microvolt = <3300000>;
+			enable-active-high;
+			gpio = <&pmic 6 GPIO_ACTIVE_HIGH>;
+			vin-supply = <&sys_3v3_reg>;
+		};
+
+		charge_pump_5v0_reg: regulator at 103 {
+			compatible = "regulator-fixed";
+			reg = <103>;
 			regulator-name = "5v0";
 			regulator-min-microvolt = <5000000>;
 			regulator-max-microvolt = <5000000>;
-- 
2.4.3



From marcel.ziswiler at toradex.com  Fri Aug 28 08:59:39 2015
From: marcel.ziswiler at toradex.com (Marcel Ziswiler)
Date: Fri, 28 Aug 2015 17:59:39 +0200
Subject: [PATCH 04/11] arm: tegra: colibri_t30: add pin muxing for on-module
 power i2c
In-Reply-To: <1440777586-19545-1-git-send-email-marcel.ziswiler@toradex.com>
References: <1440777586-19545-1-git-send-email-marcel.ziswiler@toradex.com>
Message-ID: <1440777586-19545-5-git-send-email-marcel.ziswiler@toradex.com>

Add pin muxing for the on-module power I2C bus which connects to the
PMICs, temperature sensor and touch screen controller.

Signed-off-by: Marcel Ziswiler <marcel.ziswiler at toradex.com>
---

 arch/arm/boot/dts/tegra30-colibri.dtsi | 12 ++++++++++++
 1 file changed, 12 insertions(+)

diff --git a/arch/arm/boot/dts/tegra30-colibri.dtsi b/arch/arm/boot/dts/tegra30-colibri.dtsi
index 074123f..4ddccfa 100644
--- a/arch/arm/boot/dts/tegra30-colibri.dtsi
+++ b/arch/arm/boot/dts/tegra30-colibri.dtsi
@@ -159,6 +159,18 @@
 				nvidia,tristate = <TEGRA_PIN_DISABLE>;
 			};
 
+			/* Power I2C (On-module) */
+			pwr_i2c_scl_pz6 {
+				nvidia,pins = "pwr_i2c_scl_pz6",
+					      "pwr_i2c_sda_pz7";
+				nvidia,function = "i2cpwr";
+				nvidia,pull = <TEGRA_PIN_PULL_NONE>;
+				nvidia,tristate = <TEGRA_PIN_DISABLE>;
+				nvidia,enable-input = <TEGRA_PIN_ENABLE>;
+				nvidia,lock = <TEGRA_PIN_DISABLE>;
+				nvidia,open-drain = <TEGRA_PIN_ENABLE>;
+			};
+
 			/*
 			 * THERMD_ALERT#, unlatched I2C address pin of LM95245
 			 * temperature sensor therefore requires disabling for
-- 
2.4.3



From marcel.ziswiler at toradex.com  Fri Aug 28 08:59:38 2015
From: marcel.ziswiler at toradex.com (Marcel Ziswiler)
Date: Fri, 28 Aug 2015 17:59:38 +0200
Subject: [PATCH 03/11] arm: tegra: colibri_t30: improve comment about thermal
 alert pin
In-Reply-To: <1440777586-19545-1-git-send-email-marcel.ziswiler@toradex.com>
References: <1440777586-19545-1-git-send-email-marcel.ziswiler@toradex.com>
Message-ID: <1440777586-19545-4-git-send-email-marcel.ziswiler@toradex.com>

Improve the comment about the THERMD_ALERT# pin which is the unlatched
I2C address pin of the LM95245 temperature sensor and therefore
requires disabling for now otherwise it won't get detected properly.

While at it also move that pin further down to have it alphabetically
sorted again.

Signed-off-by: Marcel Ziswiler <marcel.ziswiler at toradex.com>
---

 arch/arm/boot/dts/tegra30-colibri.dtsi | 22 +++++++++++++---------
 1 file changed, 13 insertions(+), 9 deletions(-)

diff --git a/arch/arm/boot/dts/tegra30-colibri.dtsi b/arch/arm/boot/dts/tegra30-colibri.dtsi
index 5e6a47e..074123f 100644
--- a/arch/arm/boot/dts/tegra30-colibri.dtsi
+++ b/arch/arm/boot/dts/tegra30-colibri.dtsi
@@ -66,15 +66,6 @@
 				nvidia,enable-input = <TEGRA_PIN_ENABLE>;
 			};
 
-			/* Thermal alert, need to be disabled */
-			lcd_dc1_pd2 {
-				nvidia,pins = "lcd_dc1_pd2";
-				nvidia,function = "rsvd3";
-				nvidia,pull = <TEGRA_PIN_PULL_NONE>;
-				nvidia,tristate = <TEGRA_PIN_DISABLE>;
-				nvidia,enable-input = <TEGRA_PIN_ENABLE>;
-			};
-
 			/* Colibri MMC */
 			kb_row10_ps2 {
 				nvidia,pins = "kb_row10_ps2";
@@ -167,6 +158,19 @@
 				nvidia,pull = <TEGRA_PIN_PULL_UP>;
 				nvidia,tristate = <TEGRA_PIN_DISABLE>;
 			};
+
+			/*
+			 * THERMD_ALERT#, unlatched I2C address pin of LM95245
+			 * temperature sensor therefore requires disabling for
+			 * now
+			 */
+			lcd_dc1_pd2 {
+				nvidia,pins = "lcd_dc1_pd2";
+				nvidia,function = "rsvd3";
+				nvidia,pull = <TEGRA_PIN_PULL_NONE>;
+				nvidia,tristate = <TEGRA_PIN_DISABLE>;
+				nvidia,enable-input = <TEGRA_PIN_ENABLE>;
+			};
 		};
 	};
 
-- 
2.4.3



From marcel.ziswiler at toradex.com  Fri Aug 28 08:59:35 2015
From: marcel.ziswiler at toradex.com (Marcel Ziswiler)
Date: Fri, 28 Aug 2015 17:59:35 +0200
Subject: [PATCH 00/11] arm: tegra: colibri_t30: fix hdmi, power i2c,
 wakeup and activate touch
Message-ID: <1440777586-19545-1-git-send-email-marcel.ziswiler@toradex.com>

This series finally continues on my previous Easter efforts (BTW:
thanks all for the feedback and all the patches thereof already having
been applied) and additionally to activating the STMPE811 touch
controller also fixes HDMI, power I2C and the wake-up key.


Marcel Ziswiler (11):
  arm: tegra: colibri_t30: update hardware revisions compatible comment
  arm: tegra: colibri_t30: fix hdmi supply
  arm: tegra: colibri_t30: improve comment about thermal alert pin
  arm: tegra: colibri_t30: add pin muxing for on-module power i2c
  arm: tegra: colibri_t30: fix comment about 3v3 fixed supply
  arm: tegra: colibri_t30: add touch pen interrupt pin muxing
  arm: tegra: colibri_t30: activate stmpe811 touch controller
  arm: tegra: colibri_t30: replace emmc label by comment
  arm: tegra: colibri_t30: fix vendor string of m41t0m6 rtc on eval
    board
  arm: tegra: colibri_t30: add comment concerning sd/mmc for eval board
  arm: tegra: colibri_t30: fix power/wakeup key for eval board

 arch/arm/boot/dts/tegra30-colibri-eval-v3.dts |   9 +-
 arch/arm/boot/dts/tegra30-colibri.dtsi        | 124 ++++++++++++++++++++++----
 2 files changed, 111 insertions(+), 22 deletions(-)

-- 
2.4.3



From marcel.ziswiler at toradex.com  Fri Aug 28 08:59:44 2015
From: marcel.ziswiler at toradex.com (Marcel Ziswiler)
Date: Fri, 28 Aug 2015 17:59:44 +0200
Subject: [PATCH 09/11] arm: tegra: colibri_t30: fix vendor string of m41t0m6
 rtc on eval board
In-Reply-To: <1440777586-19545-1-git-send-email-marcel.ziswiler@toradex.com>
References: <1440777586-19545-1-git-send-email-marcel.ziswiler@toradex.com>
Message-ID: <1440777586-19545-10-git-send-email-marcel.ziswiler@toradex.com>

Fix compatible vendor string of M41T0M6 real time clock as found on the
Colibri Evaluation board.

Signed-off-by: Marcel Ziswiler <marcel.ziswiler at toradex.com>
---

 arch/arm/boot/dts/tegra30-colibri-eval-v3.dts | 2 +-
 1 file changed, 1 insertion(+), 1 deletion(-)

diff --git a/arch/arm/boot/dts/tegra30-colibri-eval-v3.dts b/arch/arm/boot/dts/tegra30-colibri-eval-v3.dts
index 4d3ddc5..46a7c2d 100644
--- a/arch/arm/boot/dts/tegra30-colibri-eval-v3.dts
+++ b/arch/arm/boot/dts/tegra30-colibri-eval-v3.dts
@@ -55,7 +55,7 @@
 
 		/* M41T0M6 real time clock on carrier board */
 		rtc at 68 {
-			compatible = "stm,m41t00";
+			compatible = "st,m41t00";
 			reg = <0x68>;
 		};
 	};
-- 
2.4.3



From marcel.ziswiler at toradex.com  Fri Aug 28 08:59:40 2015
From: marcel.ziswiler at toradex.com (Marcel Ziswiler)
Date: Fri, 28 Aug 2015 17:59:40 +0200
Subject: [PATCH 05/11] arm: tegra: colibri_t30: fix comment about 3v3 fixed
 supply
In-Reply-To: <1440777586-19545-1-git-send-email-marcel.ziswiler@toradex.com>
References: <1440777586-19545-1-git-send-email-marcel.ziswiler@toradex.com>
Message-ID: <1440777586-19545-6-git-send-email-marcel.ziswiler@toradex.com>

Fix the comment about the 3v3 fixed supply as the previous v3_3 was
bogus.

Signed-off-by: Marcel Ziswiler <marcel.ziswiler at toradex.com>
---

 arch/arm/boot/dts/tegra30-colibri.dtsi | 2 +-
 1 file changed, 1 insertion(+), 1 deletion(-)

diff --git a/arch/arm/boot/dts/tegra30-colibri.dtsi b/arch/arm/boot/dts/tegra30-colibri.dtsi
index 4ddccfa..57335c3 100644
--- a/arch/arm/boot/dts/tegra30-colibri.dtsi
+++ b/arch/arm/boot/dts/tegra30-colibri.dtsi
@@ -252,7 +252,7 @@
 				/*
 				 * EN_+V3.3 switching via FET:
 				 * +V3.3_AUDIO_AVDD_S, +V3.3 and +V1.8_VDD_LAN
-				 * see also v3_3 fixed supply
+				 * see also 3v3 fixed supply
 				 */
 				ldo2_reg: ldo2 {
 					regulator-name = "en_3v3";
-- 
2.4.3



From marcel.ziswiler at toradex.com  Fri Aug 28 08:59:36 2015
From: marcel.ziswiler at toradex.com (Marcel Ziswiler)
Date: Fri, 28 Aug 2015 17:59:36 +0200
Subject: [PATCH 01/11] arm: tegra: colibri_t30: update hardware revisions
 compatible comment
In-Reply-To: <1440777586-19545-1-git-send-email-marcel.ziswiler@toradex.com>
References: <1440777586-19545-1-git-send-email-marcel.ziswiler@toradex.com>
Message-ID: <1440777586-19545-2-git-send-email-marcel.ziswiler@toradex.com>

Update introductory comment about what exact hardware revisions this
device tree is compatible with as a hint for our customers.

Signed-off-by: Marcel Ziswiler <marcel.ziswiler at toradex.com>
---

 arch/arm/boot/dts/tegra30-colibri.dtsi | 4 ++--
 1 file changed, 2 insertions(+), 2 deletions(-)

diff --git a/arch/arm/boot/dts/tegra30-colibri.dtsi b/arch/arm/boot/dts/tegra30-colibri.dtsi
index c4ed1be..83ba3f2 100644
--- a/arch/arm/boot/dts/tegra30-colibri.dtsi
+++ b/arch/arm/boot/dts/tegra30-colibri.dtsi
@@ -2,8 +2,8 @@
 #include "tegra30.dtsi"
 
 /*
- * Toradex Colibri T30 Device Tree
- * Compatible for Revisions 1.1B/1.1C/1.1D
+ * Toradex Colibri T30 Module Device Tree
+ * Compatible for Revisions V1.1B, V1.1C, V1.1D, V1.1E; IT: V1.1A
  */
 / {
 	model = "Toradex Colibri T30";
-- 
2.4.3



From marcel.ziswiler at toradex.com  Fri Aug 28 08:59:43 2015
From: marcel.ziswiler at toradex.com (Marcel Ziswiler)
Date: Fri, 28 Aug 2015 17:59:43 +0200
Subject: [PATCH 08/11] arm: tegra: colibri_t30: replace emmc label by comment
In-Reply-To: <1440777586-19545-1-git-send-email-marcel.ziswiler@toradex.com>
References: <1440777586-19545-1-git-send-email-marcel.ziswiler@toradex.com>
Message-ID: <1440777586-19545-9-git-send-email-marcel.ziswiler@toradex.com>

Rather than a bogus label just add a comment identifying the SDHCI
instance connected to the on-module eMMC.

Signed-off-by: Marcel Ziswiler <marcel.ziswiler at toradex.com>
---

 arch/arm/boot/dts/tegra30-colibri.dtsi | 3 ++-
 1 file changed, 2 insertions(+), 1 deletion(-)

diff --git a/arch/arm/boot/dts/tegra30-colibri.dtsi b/arch/arm/boot/dts/tegra30-colibri.dtsi
index 5f8ec5c..67ba943 100644
--- a/arch/arm/boot/dts/tegra30-colibri.dtsi
+++ b/arch/arm/boot/dts/tegra30-colibri.dtsi
@@ -396,7 +396,8 @@
 		nvidia,sys-clock-req-active-high;
 	};
 
-	emmc: sdhci at 78000600 {
+	/* eMMC */
+	sdhci at 78000600 {
 		status = "okay";
 		bus-width = <8>;
 		non-removable;
-- 
2.4.3



From marcel.ziswiler at toradex.com  Fri Aug 28 08:59:42 2015
From: marcel.ziswiler at toradex.com (Marcel Ziswiler)
Date: Fri, 28 Aug 2015 17:59:42 +0200
Subject: [PATCH 07/11] arm: tegra: colibri_t30: activate stmpe811 touch
 controller
In-Reply-To: <1440777586-19545-1-git-send-email-marcel.ziswiler@toradex.com>
References: <1440777586-19545-1-git-send-email-marcel.ziswiler@toradex.com>
Message-ID: <1440777586-19545-8-git-send-email-marcel.ziswiler@toradex.com>

Activate STMPE811 touch controller as found on Colibri T30 modules.

Signed-off-by: Marcel Ziswiler <marcel.ziswiler at toradex.com>
---

 arch/arm/boot/dts/tegra30-colibri.dtsi | 40 ++++++++++++++++++++++++++++++++++
 1 file changed, 40 insertions(+)

diff --git a/arch/arm/boot/dts/tegra30-colibri.dtsi b/arch/arm/boot/dts/tegra30-colibri.dtsi
index fba3d2a..5f8ec5c 100644
--- a/arch/arm/boot/dts/tegra30-colibri.dtsi
+++ b/arch/arm/boot/dts/tegra30-colibri.dtsi
@@ -320,6 +320,46 @@
 			};
 		};
 
+		/* STMPE811 touch screen controller */
+		stmpe811 at 41 {
+			compatible = "st,stmpe811";
+			#address-cells = <1>;
+			#size-cells = <0>;
+			reg = <0x41>;
+			interrupts = <TEGRA_GPIO(V, 0) IRQ_TYPE_LEVEL_LOW>;
+			interrupt-parent = <&gpio>;
+			interrupt-controller;
+			id = <0>;
+			blocks = <0x5>;
+			irq-trigger = <0x1>;
+
+			stmpe_touchscreen {
+				compatible = "st,stmpe-ts";
+				reg = <0>;
+				/* 3.25 MHz ADC clock speed */
+				st,adc-freq = <1>;
+				/* 8 sample average control */
+				st,ave-ctrl = <3>;
+				/* 7 length fractional part in z */
+				st,fraction-z = <7>;
+				/*
+				 * 50 mA typical 80 mA max touchscreen drivers
+				 * current limit value
+				 */
+				st,i-drive = <1>;
+				/* 12-bit ADC */
+				st,mod-12b = <1>;
+				/* internal ADC reference */
+				st,ref-sel = <0>;
+				/* ADC converstion time: 80 clocks */
+				st,sample-time = <4>;
+				/* 1 ms panel driver settling time */
+				st,settling = <3>;
+				/* 5 ms touch detect interrupt delay */
+				st,touch-det-delay = <5>;
+			};
+		};
+
 		/*
 		 * LM95245 temperature sensor
 		 * Note: OVERT_N directly connected to PMIC PWRDN
-- 
2.4.3



From marcel.ziswiler at toradex.com  Fri Aug 28 08:59:45 2015
From: marcel.ziswiler at toradex.com (Marcel Ziswiler)
Date: Fri, 28 Aug 2015 17:59:45 +0200
Subject: [PATCH 10/11] arm: tegra: colibri_t30: add comment concerning sd/mmc
 for eval board
In-Reply-To: <1440777586-19545-1-git-send-email-marcel.ziswiler@toradex.com>
References: <1440777586-19545-1-git-send-email-marcel.ziswiler@toradex.com>
Message-ID: <1440777586-19545-11-git-send-email-marcel.ziswiler@toradex.com>

Instead of adding an otherwise unused sdmmc label just add a comment.

Signed-off-by: Marcel Ziswiler <marcel.ziswiler at toradex.com>
---

 arch/arm/boot/dts/tegra30-colibri-eval-v3.dts | 1 +
 1 file changed, 1 insertion(+)

diff --git a/arch/arm/boot/dts/tegra30-colibri-eval-v3.dts b/arch/arm/boot/dts/tegra30-colibri-eval-v3.dts
index 46a7c2d..a6c98b1 100644
--- a/arch/arm/boot/dts/tegra30-colibri-eval-v3.dts
+++ b/arch/arm/boot/dts/tegra30-colibri-eval-v3.dts
@@ -84,6 +84,7 @@
 		};
 	};
 
+	/* SD/MMC */
 	sdhci at 78000200 {
 		status = "okay";
 		bus-width = <4>;
-- 
2.4.3



From marcel.ziswiler at toradex.com  Fri Aug 28 08:59:46 2015
From: marcel.ziswiler at toradex.com (Marcel Ziswiler)
Date: Fri, 28 Aug 2015 17:59:46 +0200
Subject: [PATCH 11/11] arm: tegra: colibri_t30: fix power/wakeup key for eval
 board
In-Reply-To: <1440777586-19545-1-git-send-email-marcel.ziswiler@toradex.com>
References: <1440777586-19545-1-git-send-email-marcel.ziswiler@toradex.com>
Message-ID: <1440777586-19545-12-git-send-email-marcel.ziswiler@toradex.com>

Rather than a power key SODIMM pin 45 is actually used for wake-up
purpose which this patch fixes.

Signed-off-by: Marcel Ziswiler <marcel.ziswiler at toradex.com>
---

 arch/arm/boot/dts/tegra30-colibri-eval-v3.dts | 6 +++---
 1 file changed, 3 insertions(+), 3 deletions(-)

diff --git a/arch/arm/boot/dts/tegra30-colibri-eval-v3.dts b/arch/arm/boot/dts/tegra30-colibri-eval-v3.dts
index a6c98b1..3ff019f 100644
--- a/arch/arm/boot/dts/tegra30-colibri-eval-v3.dts
+++ b/arch/arm/boot/dts/tegra30-colibri-eval-v3.dts
@@ -137,10 +137,10 @@
 	gpio-keys {
 		compatible = "gpio-keys";
 
-		power {
-			label = "Power";
+		wakeup {
+			label = "SODIMM pin 45 wakeup";
 			gpios = <&gpio TEGRA_GPIO(V, 1) GPIO_ACTIVE_HIGH>;
-			linux,code = <KEY_POWER>;
+			linux,code = <KEY_WAKEUP>;
 			debounce-interval = <10>;
 			gpio-key,wakeup;
 		};
-- 
2.4.3



From marcel.ziswiler at toradex.com  Fri Aug 28 08:59:41 2015
From: marcel.ziswiler at toradex.com (Marcel Ziswiler)
Date: Fri, 28 Aug 2015 17:59:41 +0200
Subject: [PATCH 06/11] arm: tegra: colibri_t30: add touch pen interrupt pin
 muxing
In-Reply-To: <1440777586-19545-1-git-send-email-marcel.ziswiler@toradex.com>
References: <1440777586-19545-1-git-send-email-marcel.ziswiler@toradex.com>
Message-ID: <1440777586-19545-7-git-send-email-marcel.ziswiler@toradex.com>

Add TOUCH_PEN_INT# pin muxing required for proper STMPE811 touch screen
controller operation.

Signed-off-by: Marcel Ziswiler <marcel.ziswiler at toradex.com>
---

 arch/arm/boot/dts/tegra30-colibri.dtsi | 9 +++++++++
 1 file changed, 9 insertions(+)

diff --git a/arch/arm/boot/dts/tegra30-colibri.dtsi b/arch/arm/boot/dts/tegra30-colibri.dtsi
index 57335c3..fba3d2a 100644
--- a/arch/arm/boot/dts/tegra30-colibri.dtsi
+++ b/arch/arm/boot/dts/tegra30-colibri.dtsi
@@ -183,6 +183,15 @@
 				nvidia,tristate = <TEGRA_PIN_DISABLE>;
 				nvidia,enable-input = <TEGRA_PIN_ENABLE>;
 			};
+
+			/* TOUCH_PEN_INT# */
+			pv0 {
+				nvidia,pins = "pv0";
+				nvidia,function = "rsvd1";
+				nvidia,pull = <TEGRA_PIN_PULL_NONE>;
+				nvidia,tristate = <TEGRA_PIN_DISABLE>;
+				nvidia,enable-input = <TEGRA_PIN_ENABLE>;
+			};
 		};
 	};
 
-- 
2.4.3



From wens at csie.org  Fri Aug 28 09:09:55 2015
From: wens at csie.org (Chen-Yu Tsai)
Date: Sat, 29 Aug 2015 00:09:55 +0800
Subject: [PATCH 2/6] ARM: dts: sunxi: Add dtsi for AXP221 PMIC
In-Reply-To: <20150828123159.GJ29389@lukather>
References: <1440755679-8266-1-git-send-email-wens@csie.org>
 <1440755679-8266-3-git-send-email-wens@csie.org>
 <20150828123159.GJ29389@lukather>
Message-ID: <CAGb2v66nBh+_P=EDxrNYeFoUUXqPWuZyfq1OEQww_aSMhT8wVQ@mail.gmail.com>

On Fri, Aug 28, 2015 at 8:31 PM, Maxime Ripard
<maxime.ripard at free-electrons.com> wrote:
> On Fri, Aug 28, 2015 at 05:54:35PM +0800, Chen-Yu Tsai wrote:
>> The AXP221 PMIC is used with some Allwinner SoCs. This patch adds
>> a dtsi file listing all the regulator nodes. The regulators are
>> initialized based on their device node names.
>>
>> This can later be used with the AXP223 PMIC as well, which has
>> the same functionality as AXP221, except for its host interface.
>>
>> Signed-off-by: Chen-Yu Tsai <wens at csie.org>
>> ---
>>  arch/arm/boot/dts/axp221.dtsi | 148 ++++++++++++++++++++++++++++++++++++++++++
>>  1 file changed, 148 insertions(+)
>>  create mode 100644 arch/arm/boot/dts/axp221.dtsi
>>
>> diff --git a/arch/arm/boot/dts/axp221.dtsi b/arch/arm/boot/dts/axp221.dtsi
>> new file mode 100644
>> index 000000000000..74836f329863
>> --- /dev/null
>> +++ b/arch/arm/boot/dts/axp221.dtsi
>> @@ -0,0 +1,148 @@
>> +/*
>> + * Copyright 2015 Chen-Yu Tsai
>> + *
>> + * Chen-Yu Tsai <wens at csie.org>
>> + *
>> + * This file is dual-licensed: you can use it either under the terms
>> + * of the GPL or the X11 license, at your option. Note that this dual
>> + * licensing only applies to this file, and not this project as a
>> + * whole.
>> + *
>> + *  a) This file is free software; you can redistribute it and/or
>> + *     modify it under the terms of the GNU General Public License as
>> + *     published by the Free Software Foundation; either version 2 of the
>> + *     License, or (at your option) any later version.
>> + *
>> + *     This file is distributed in the hope that it will be useful,
>> + *     but WITHOUT ANY WARRANTY; without even the implied warranty of
>> + *     MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
>> + *     GNU General Public License for more details.
>> + *
>> + * Or, alternatively,
>> + *
>> + *  b) Permission is hereby granted, free of charge, to any person
>> + *     obtaining a copy of this software and associated documentation
>> + *     files (the "Software"), to deal in the Software without
>> + *     restriction, including without limitation the rights to use,
>> + *     copy, modify, merge, publish, distribute, sublicense, and/or
>> + *     sell copies of the Software, and to permit persons to whom the
>> + *     Software is furnished to do so, subject to the following
>> + *     conditions:
>> + *
>> + *     The above copyright notice and this permission notice shall be
>> + *     included in all copies or substantial portions of the Software.
>> + *
>> + *     THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
>> + *     EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES
>> + *     OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
>> + *     NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT
>> + *     HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY,
>> + *     WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
>> + *     FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR
>> + *     OTHER DEALINGS IN THE SOFTWARE.
>> + */
>> +
>> +/*
>> + * AXP221/221s/223 Integrated Power Management Chip
>> + * http://www.x-powers.com/product/AXP22X.php
>> + * http://dl.linux-sunxi.org/AXP/AXP221%20Datasheet%20V1.2%2020130326%20.pdf
>> + */
>
> I'm usually not really fond of URLs in the source code and/or the
> commit logs. They tend to be broken very easily.

OK. Would you rather I put them in Documentation/arm/sunxi/README?
It's not immediately clear that sunxi and axp* are connected though.

>> +
>> +&axp221 {
>> +     compatible = "x-powers,axp221";
>> +     interrupt-controller;
>> +     #interrupt-cells = <1>;
>> +
>> +     regulators {
>> +             /* Default work frequency for buck regulators */
>> +             x-powers,dcdc-freq = <3000>;
>> +
>> +             /* supplies for dc1sw & dc5ldo are connected internally */
>> +             dcdc1-supply = <&reg_dcdc1>;
>> +             dcdc5-supply = <&reg_dcdc5>;
>
> so the parent regulator of DCDC1 is DCDC1 ?

These probably aren't the best names. These are the supplies for DC1SW and
DC5LDO, respectively. They are connected internally, so there aren't named
pins for them. The comment above explains it, though probably not clearly
enough. Furthermore, the input pins for DCDC1/5 are VIN1/5.


Regards
ChenYu


From lorenzo.pieralisi at arm.com  Fri Aug 28 09:10:35 2015
From: lorenzo.pieralisi at arm.com (Lorenzo Pieralisi)
Date: Fri, 28 Aug 2015 17:10:35 +0100
Subject: [PATCH] ARM64: kernel: implement ACPI parking protocol
In-Reply-To: <1440777396.31961.13.camel@redhat.com>
References: <1436959990-32054-1-git-send-email-lorenzo.pieralisi@arm.com>
 <1437063431.3583.2.camel@redhat.com>
 <20150716171221.GB18582@red-moon>
 <1437068449.3583.4.camel@redhat.com>
 <20150828102314.GC15924@red-moon>
 <1440772186.31961.8.camel@redhat.com>
 <20150828153212.GG15924@red-moon>
 <1440777396.31961.13.camel@redhat.com>
Message-ID: <20150828161035.GH15924@red-moon>

On Fri, Aug 28, 2015 at 04:56:36PM +0100, Mark Salter wrote:
> On Fri, 2015-08-28 at 16:32 +0100, Lorenzo Pieralisi wrote:
> > [Cc'ing Leif and Ard]
> > 
> > On Fri, Aug 28, 2015 at 03:29:46PM +0100, Mark Salter wrote:
> > > On Fri, 2015-08-28 at 11:23 +0100, Lorenzo Pieralisi wrote:
> > > > Mark,
> > > > 
> > > > On Thu, Jul 16, 2015 at 06:40:49PM +0100, Mark Salter wrote:
> > > > 
> > > > [...]
> > > > 
> > > > > On Thu, 2015-07-16 at 18:12 +0100, Lorenzo Pieralisi wrote:
> > > > > > > The kernel will only add cached memory regions to linear 
> > > > > > > mapping 
> > > > > > > and
> > > > > > > presumably, the FW will mark the mailboxes as uncached. 
> > > > > > > Otherwise, 
> > > > > > > it
> > > > > > > is a FW bug. But I suppose we could run into problems with 
> > > > > > > kernels
> > > > > > > using 64K pagesize since firmware assumes 4k.
> > > > > > 
> > > > > > Nope, ioremap takes care of that, everything should be fine.
> > > > > 
> > > > > The mailbox is 4K. If it is next to a cached UEFI region, the 
> > > > > kernel 
> > > > > may
> > > > > have to overlap the mailbox with a cached 64K mapping in order to 
> > > > > include
> > > > > the adjoining UEFI region in the linear map. Then the ioremap would 
> > > > > fail
> > > > > because the mailbox is included in the linear mapping.
> > > > 
> > > > So that I understand: are you referring to memrange_efi_to_native()
> > > > in arch/arm64/kernel/efi.c ? Is it safe to round up (and add it to
> > > > the memblock layer) the memory region size to PAGE_SIZE without 
> > > > checking
> > > > attributes of overlapping (within PAGE_SIZE) UEFI regions ?
> > > 
> > > The problem is that nothing in the UEFI spec or parking protocol spec
> > > prevents firmware from placing a 4K parking protocol mailbox area in
> > > the same 64K page as normal cached memory which winds up mapped in
> > > the kernel linear mapping. The kernel might be able to work around
> > > that by not putting the 64K page in the linear map. There's nothing
> > > the kernel could do if the mailbox is in same 64K page with UEFI 
> > > runtime
> > > memory which would use a cached mapping.
> > 
> > Ok, I failed to explain myself. Let's imagine that we have a, say, 64k
> > aligned memory region (EFI_MEMORY_WB - size 16k) that lives in the same
> > 64K memory frame as a device's registers memory space.
> > The code I pointed at above creates a 64K memory frame out of the 16K
> > region and adds it to the memblock so that it ends up in the kernel 
> > linear
> > mapping which ends up mapping the device registers too with cacheable
> > attributes and that's not correct.
> > 
> > I am not sure what's the best way to solve that, probably we should
> > amend the UEFI specs to enforce uniform 64K memory region attributes,
> > comments welcome.
> 
> OIC. Well it is a potential problem. Hardware designers do some whacky
> things, but I'd like to think I/O regions and cached mem regions bordering
> on such a small power of two boundary is not one of them.

Yes, I agree with you as far as I/O is concerned, I just wanted
to understand if the issue you mentioned is a consequence of how
the code above performs the rounding (it could discard memory regions
having mixed attributes within PAGE_SIZE instead, if we enforce it in
the specs).

Unfortunately for the mailboxes, since it is RAM, it might well happen.
If we change the UEFI specs to enforce uniform attributes on 64K regions
the problem you raised is solved at UEFI spec level instead of changing
the ACPI parking protocol specs.

I will raise the point, apart from that I will send a v2 soon with
the issue you raised addressed in the specs.

Thanks,
Lorenzo


From gregory.clement at free-electrons.com  Fri Aug 28 09:08:36 2015
From: gregory.clement at free-electrons.com (Gregory CLEMENT)
Date: Fri, 28 Aug 2015 18:08:36 +0200
Subject: no booting due to handle_domain_irq on orion5x/kurobox
In-Reply-To: <20150828155826.GD2776@dinsnail.net> (Michael Weiser's message of
 "Fri, 28 Aug 2015 17:58:26 +0200")
References: <20150828155826.GD2776@dinsnail.net>
Message-ID: <87vbbz75vf.fsf@free-electrons.com>

Hi Michael,

Michael Weiser <michael at dinsnail.net> writes:
> Hi,
>
> I've got vanilla kernels running on a Buffalo Linkstation Pro
> (orion5x/Kurobox Pro). The last release kernel to work is 3.17.8.
> Anything after that just says "Uncompressing Linux... Ok. booting the
> kernel" and stops. 
>
> By building and booting various intermediate stages from git, I've
> narrowed it down to the following three commits:
>
> 76ba59f8366f2d9282cb5bda9de75b4b68cbe55f genirq: Add irq_domain-aware core IRQ handler
> a71b092a9c68685a270ebdde7b5986ba8787e575 ARM: Convert handle_IRQ to use __handle_domain_irq
> f4bc9288b4a29ead48425dd7d1bf4b825a8aff58 irqchip: orion: Convert to handle_domain_irq
>
> If I revert those from an otherwise unmodified current
> torvalds/linux.git HEAD it boots up just fine.
>
> I'm afraid that's as far as my kernel debugging know-how will take me.
> Any help in how to proceed further in order to get current kernels
> running on my box would be highly appreciated.

The good new is that a fix have already been submitted, the bad news is
that it won't be in 4.2, but it will be in 4.3-rc1 and as it was tagged
as stable it would be part of the older stable kernel in the next weeks.
You can cherry-pick it from linux-next:

http://git.kernel.org/cgit/linux/kernel/git/next/linux-next.git/commit/?id=5be9fc23cdb42e1d383ecc8eae8a8ff70a752708

Thanks,

Gregory

-- 
Gregory Clement, Free Electrons
Kernel, drivers, real-time and embedded Linux
development, consulting, training and support.
http://free-electrons.com


From leif.lindholm at linaro.org  Fri Aug 28 09:11:29 2015
From: leif.lindholm at linaro.org (Leif Lindholm)
Date: Fri, 28 Aug 2015 17:11:29 +0100
Subject: [PATCH] ARM64: kernel: implement ACPI parking protocol
In-Reply-To: <1440777396.31961.13.camel@redhat.com>
References: <1436959990-32054-1-git-send-email-lorenzo.pieralisi@arm.com>
 <1437063431.3583.2.camel@redhat.com>
 <20150716171221.GB18582@red-moon>
 <1437068449.3583.4.camel@redhat.com>
 <20150828102314.GC15924@red-moon>
 <1440772186.31961.8.camel@redhat.com>
 <20150828153212.GG15924@red-moon>
 <1440777396.31961.13.camel@redhat.com>
Message-ID: <20150828161128.GQ10728@bivouac.eciton.net>

On Fri, Aug 28, 2015 at 11:56:36AM -0400, Mark Salter wrote:
> > > > So that I understand: are you referring to memrange_efi_to_native()
> > > > in arch/arm64/kernel/efi.c ? Is it safe to round up (and add it to
> > > > the memblock layer) the memory region size to PAGE_SIZE without 
> > > > checking
> > > > attributes of overlapping (within PAGE_SIZE) UEFI regions ?
> > > 
> > > The problem is that nothing in the UEFI spec or parking protocol spec
> > > prevents firmware from placing a 4K parking protocol mailbox area in
> > > the same 64K page as normal cached memory which winds up mapped in
> > > the kernel linear mapping. The kernel might be able to work around
> > > that by not putting the 64K page in the linear map. There's nothing
> > > the kernel could do if the mailbox is in same 64K page with UEFI 
> > > runtime memory which would use a cached mapping.

Indeed.

> > Ok, I failed to explain myself. Let's imagine that we have a, say, 64k
> > aligned memory region (EFI_MEMORY_WB - size 16k) that lives in the same
> > 64K memory frame as a device's registers memory space.
> > The code I pointed at above creates a 64K memory frame out of the 16K
> > region and adds it to the memblock so that it ends up in the kernel 
> > linear
> > mapping which ends up mapping the device registers too with cacheable
> > attributes and that's not correct.
> > 
> > I am not sure what's the best way to solve that, probably we should
> > amend the UEFI specs to enforce uniform 64K memory region attributes,
> > comments welcome.

Agreed.

> OIC. Well it is a potential problem. Hardware designers do some whacky
> things, but I'd like to think I/O regions and cached mem regions bordering
> on such a small power of two boundary is not one of them.

Sure. But the same applies to memory regions _mapped_ as Device.
Which is (apparently) necessary for the spin-tables used by the
parking protocol.

So the spec should ban use of incompatible memory attributes between
any regions kept around at runtime, as opposed to specifically the
regions used for runtime services (the current wording in the spec).

/
    Leif


From Nathan_Lynch at mentor.com  Fri Aug 28 09:24:20 2015
From: Nathan_Lynch at mentor.com (Nathan Lynch)
Date: Fri, 28 Aug 2015 11:24:20 -0500
Subject: [PATCH v2 3/4] remoteproc: Supply controller driver for ST's
 Remote Processors
In-Reply-To: <1440757911-9120-4-git-send-email-lee.jones@linaro.org>
References: <1440757911-9120-1-git-send-email-lee.jones@linaro.org>
 <1440757911-9120-4-git-send-email-lee.jones@linaro.org>
Message-ID: <55E08B34.9080102@mentor.com>

On 08/28/2015 05:31 AM, Lee Jones wrote:
> diff --git a/drivers/remoteproc/Kconfig b/drivers/remoteproc/Kconfig
> index 28c711f..72e97d7 100644
> --- a/drivers/remoteproc/Kconfig
> +++ b/drivers/remoteproc/Kconfig
> @@ -77,4 +77,13 @@ config DA8XX_REMOTEPROC
>  	  It's safe to say n here if you're not interested in multimedia
>  	  offloading.
>  
> +config ST_REMOTEPROC
> +	tristate "ST remoteproc support"
> +	depends on ARCH_STI
> +	select REMOTEPROC
> +	help
> +	  Say y here to support ST's adjunct processors via the remote
> +	  processor framework.
> +	  This can be either built-in or a loadable module.
> +

The code uses reset_control_* APIs, so this should depend on
RESET_CONTROLLER, no?

> +/*
> + * ST's Remote Processor Control Driver
> + *
> + * Copyright (C) 2015 STMicroelectronics - All Rights Reserved
> + *
> + * Author: Ludovic Barre <ludovic.barre at st.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, or (at your option)
> + * any later version.
> + */

OK, but:

> +MODULE_LICENSE("GPL v2");

These are not in agreement.  You want "GPL" for MODULE_LICENSE if you
intend v2 or later.


> +static int st_rproc_stop(struct rproc *rproc)
> +{
> +	struct st_rproc *st_rproc = rproc->priv;
> +	int ret, err = 0;
> +
> +	if (st_rproc->config->sw_reset) {
> +		ret = reset_control_assert(st_rproc->sw_reset);
> +		if (ret)
> +			dev_err(&rproc->dev, "Failed to assert S/W Reset\n");
> +	}
> +
> +	if (st_rproc->config->pwr_reset) {
> +		err = reset_control_assert(st_rproc->pwr_reset);
> +		if (err)
> +			dev_err(&rproc->dev, "Failed to assert Power Reset\n");
> +	}
> +
> +	clk_disable(st_rproc->clk);
> +
> +	return ret ?: err;
> +}

Sorry, but I think this is a stylistically inadequate response to my
earlier comments.  At least name the status variables sw_ret and pwr_ret
or something.  And it looks like ret could be used uninitialized.

Also, do you want to unconditionally call clk_disable even if you've
encountered errors?


> +static int st_rproc_start(struct rproc *rproc)
> +{
> +	struct st_rproc *st_rproc = rproc->priv;
> +	int err;
> +
> +	regmap_update_bits(st_rproc->boot_base, st_rproc->boot_offset,
> +			   st_rproc->config->bootaddr_mask, rproc->bootaddr);
> +
> +	err = clk_enable(st_rproc->clk);
> +	if (err) {
> +		dev_err(&rproc->dev, "Failed to enable clock\n");
> +		return err;
> +	}
> +
> +	if (st_rproc->config->sw_reset) {
> +		err = reset_control_deassert(st_rproc->sw_reset);
> +		if (err) {
> +			dev_err(&rproc->dev, "Failed to deassert S/W Reset\n");
> +			return err;
> +		}
> +	}
> +
> +	if (st_rproc->config->pwr_reset) {
> +		err = reset_control_deassert(st_rproc->pwr_reset);
> +		if (err) {
> +			dev_err(&rproc->dev, "Failed to deassert Power Reset\n");
> +			return err;
> +		}
> +	}
> +
> +	dev_info(&rproc->dev, "Started from 0x%x\n", rproc->bootaddr);
> +
> +	return 0;
> +}

Does this want to unwind any of its operations if it encounters a failure?



From mathieu.poirier at linaro.org  Fri Aug 28 09:28:13 2015
From: mathieu.poirier at linaro.org (Mathieu Poirier)
Date: Fri, 28 Aug 2015 10:28:13 -0600
Subject: [PATCH v2] Coresight: ETMv4: Prevent TRCRSCTLR0&1 from being
 accessed
In-Reply-To: <1440735001-29760-1-git-send-email-zhang.chunyan@linaro.org>
References: <1440735001-29760-1-git-send-email-zhang.chunyan@linaro.org>
Message-ID: <CANLsYkxhvf5n8HW51xT83K_=WrJ=1PG8=3q=_L9GEN7RFFzAFA@mail.gmail.com>

On 27 August 2015 at 22:10, Chunyan Zhang <zhang.chunyan at linaro.org> wrote:
> 1. TRCRSCTLRn - Resource Selection Control Registers n=0~1 are reserved,
>    we shouldn't access them.
> 2. The max number of 'n' here is defined in TRCIDR4.NUMRSPAIR whoes value
>    indicates the number of resource selection *pairs*, and 0 indicates
>    one resource selection pair, 1 indicates two pairs, and so on ...
>
> So, the total number of resource selection control registers which we can
> access is (TRCIDR4.NUMRSPAIR * 2)
>
> Signed-off-by: Chunyan Zhang <zhang.chunyan at linaro.org>
> ---
>  drivers/hwtracing/coresight/coresight-etm4x.c | 17 +++++++++++------
>  1 file changed, 11 insertions(+), 6 deletions(-)
>
> diff --git a/drivers/hwtracing/coresight/coresight-etm4x.c b/drivers/hwtracing/coresight/coresight-etm4x.c
> index 1312e99..fe93b47 100644
> --- a/drivers/hwtracing/coresight/coresight-etm4x.c
> +++ b/drivers/hwtracing/coresight/coresight-etm4x.c
> @@ -136,7 +136,9 @@ static void etm4_enable_hw(void *info)
>                 writel_relaxed(drvdata->cntr_val[i],
>                                drvdata->base + TRCCNTVRn(i));
>         }
> -       for (i = 0; i < drvdata->nr_resource; i++)
> +
> +       /* Resource selector pair 0 is always implemented and reserved */
> +       for (i = 2; i < drvdata->nr_resource * 2; i++)
>                 writel_relaxed(drvdata->res_ctrl[i],
>                                drvdata->base + TRCRSCTLRn(i));
>
> @@ -489,8 +491,9 @@ static ssize_t reset_store(struct device *dev,
>                 drvdata->cntr_val[i] = 0x0;
>         }
>
> -       drvdata->res_idx = 0x0;
> -       for (i = 0; i < drvdata->nr_resource; i++)
> +       /* Resource selector pair 0 is always implemented and reserved */
> +       drvdata->res_idx = 0x2;
> +       for (i = 2; i < drvdata->nr_resource * 2; i++)
>                 drvdata->res_ctrl[i] = 0x0;
>
>         for (i = 0; i < drvdata->nr_ss_cmp; i++) {
> @@ -1729,7 +1732,7 @@ static ssize_t res_idx_store(struct device *dev,
>         if (kstrtoul(buf, 16, &val))
>                 return -EINVAL;
>         /* Resource selector pair 0 is always implemented and reserved */
> -       if ((val == 0) || (val >= drvdata->nr_resource))
> +       if (val < 2 || val >= drvdata->nr_resource * 2)
>                 return -EINVAL;
>
>         /*
> @@ -2410,8 +2413,8 @@ static void etm4_init_arch_data(void *info)
>         drvdata->nr_addr_cmp = BMVAL(etmidr4, 0, 3);
>         /* NUMPC, bits[15:12] number of PE comparator inputs for tracing */
>         drvdata->nr_pe_cmp = BMVAL(etmidr4, 12, 15);
> -       /* NUMRSPAIR, bits[19:16] the number of resource pairs for tracing */
> -       drvdata->nr_resource = BMVAL(etmidr4, 16, 19);
> +       /* NUMRSPAIR, bits[19:16] the number of resource pairs minus one */
> +       drvdata->nr_resource = BMVAL(etmidr4, 16, 19) + 1;
>         /*
>          * NUMSSCC, bits[23:20] the number of single-shot
>          * comparator control for tracing
> @@ -2498,6 +2501,8 @@ static void etm4_init_default_data(struct etmv4_drvdata *drvdata)
>                 drvdata->cntr_val[i] = 0x0;
>         }
>
> +       /* Resource selector pair 0 is always implemented and reserved */
> +       drvdata->res_idx = 0x2;
>         for (i = 2; i < drvdata->nr_resource * 2; i++)
>                 drvdata->res_ctrl[i] = 0x0;
>
> --
> 1.9.1
>

Applied with a modification to the "NUMRSPAIR" comment - thanks,

Mathieu


From fainelli at broadcom.com  Fri Aug 28 09:36:42 2015
From: fainelli at broadcom.com (Florian Fainelli)
Date: Fri, 28 Aug 2015 09:36:42 -0700
Subject: [PATCH v2 2/5] ARM: NSP: add minimal Northstar Plus device tree
In-Reply-To: <CAL_JsqJb+Pj7c=3Q9ViPhU_=tJxqOzEhOPALctf-zaFHQv+bWg@mail.gmail.com>
References: <1440628530-6137-1-git-send-email-jonmason@broadcom.com>
 <1440628530-6137-3-git-send-email-jonmason@broadcom.com>
 <CAL_JsqJb+Pj7c=3Q9ViPhU_=tJxqOzEhOPALctf-zaFHQv+bWg@mail.gmail.com>
Message-ID: <55E08E1A.8050805@broadcom.com>

On 28/08/15 08:41, Rob Herring wrote:
> On Wed, Aug 26, 2015 at 5:35 PM, Jon Mason <jonmason at broadcom.com> wrote:
>> Add a very minimalistic set of Northstar Plus Device Tree files which
>> describes the SoC and the BCM958625 implementation.  The perpherials
>> described are:
>>
>> ARM Cortex A9 CPU
>> 2 8250 UARTs
>> ARM GIC
>> PL310 L2 Cache
>> ARM A9 Global timer
>>
>> Signed-off-by: Kapil Hali <kapilh at broadcom.com>
>> Signed-off-by: Jon Mason <jonmason at broadcom.com>
>> ---
[snip]
>> +       clocks {
>> +               #address-cells = <1>;
>> +               #size-cells = <1>;
>> +               ranges;
>> +
>> +               periph_clk: periph_clk {
>> +                       compatible = "fixed-clock";
>> +                       #clock-cells = <0>;
>> +                       clock-frequency = <500000000>;
>> +               };
>> +       };
>> +
>> +       uart0: serial at 18000300 {
> 
> All these devices should go under a bus node.

Jon, you can send a replacement patch and I would drop this one. Thanks!
-- 
Florian


From luis at debethencourt.com  Fri Aug 28 09:44:03 2015
From: luis at debethencourt.com (Luis de Bethencourt)
Date: Fri, 28 Aug 2015 18:44:03 +0200
Subject: [PATCH 2/3] crypto: picoxcell: Fix module autoload for OF platform
 driver
Message-ID: <20150828164403.GA5083@goodgumbo.baconseed.org>

This platform driver has a OF device ID table but the OF module
alias information is not created so module autoloading won't work.

Signed-off-by: Luis de Bethencourt <luis at debethencourt.com>
---
 drivers/crypto/picoxcell_crypto.c | 1 +
 1 file changed, 1 insertion(+)

diff --git a/drivers/crypto/picoxcell_crypto.c b/drivers/crypto/picoxcell_crypto.c
index 4f56f36..b6ec2a4 100644
--- a/drivers/crypto/picoxcell_crypto.c
+++ b/drivers/crypto/picoxcell_crypto.c
@@ -1673,6 +1673,7 @@ static const struct of_device_id spacc_of_id_table[] = {
 	{ .compatible = "picochip,spacc-l2" },
 	{}
 };
+MODULE_DEVICE_TABLE(of, spacc_of_id_table);
 #endif /* CONFIG_OF */
 
 static bool spacc_is_compatible(struct platform_device *pdev,
-- 
2.4.6



From wens at csie.org  Fri Aug 28 09:47:00 2015
From: wens at csie.org (Chen-Yu Tsai)
Date: Sat, 29 Aug 2015 00:47:00 +0800
Subject: [PATCH 3/6] ARM: dts: sun6i: hummingbird: Use axp221.dtsi for
 axp221 regulators
In-Reply-To: <20150828123244.GK29389@lukather>
References: <1440755679-8266-1-git-send-email-wens@csie.org>
 <1440755679-8266-4-git-send-email-wens@csie.org>
 <20150828123244.GK29389@lukather>
Message-ID: <CAGb2v67wEXNTDYrPm9Hf2P59+B4nGHAR8kTPCuLVuS+TLHxMRQ@mail.gmail.com>

On Fri, Aug 28, 2015 at 8:32 PM, Maxime Ripard
<maxime.ripard at free-electrons.com> wrote:
> On Fri, Aug 28, 2015 at 05:54:36PM +0800, Chen-Yu Tsai wrote:
>> Now that we have axp221.dtsi describing common axp22x hardware, use
>> it and reference the nodes instead of declaring the whole tree.
>>
>> Also add regulator reference for cpu0 supply.
>>
>> Signed-off-by: Chen-Yu Tsai <wens at csie.org>
>> ---
>>  arch/arm/boot/dts/sun6i-a31-hummingbird.dts | 114 ++++++++++++++--------------
>>  1 file changed, 56 insertions(+), 58 deletions(-)
>>
>> diff --git a/arch/arm/boot/dts/sun6i-a31-hummingbird.dts b/arch/arm/boot/dts/sun6i-a31-hummingbird.dts
>> index d0cfadac0691..d019cb70acec 100644
>> --- a/arch/arm/boot/dts/sun6i-a31-hummingbird.dts
>> +++ b/arch/arm/boot/dts/sun6i-a31-hummingbird.dts
>> @@ -67,6 +67,10 @@
>>       };
>>  };
>>
>> +&cpu0 {
>> +     cpu-supply = <&reg_dcdc2>;
>> +};
>> +
>>  &ehci0 {
>>       status = "okay";
>>  };
>> @@ -119,7 +123,7 @@
>>  &mmc0 {
>>       pinctrl-names = "default";
>>       pinctrl-0 = <&mmc0_pins_a>, <&mmc0_cd_pin_hummingbird>;
>> -     vmmc-supply = <&vcc_3v0>;
>> +     vmmc-supply = <&reg_dcdc1>;
>>       bus-width = <4>;
>>       cd-gpios = <&pio 0 8 GPIO_ACTIVE_HIGH>; /* PA8 */
>>       cd-inverted;
>> @@ -134,7 +138,7 @@
>>  &mmc1 {
>>       pinctrl-names = "default";
>>       pinctrl-0 = <&mmc1_pins_a>, <&wifi_reset_pin_hummingbird>;
>> -     vmmc-supply = <&vcc_wifi>;
>> +     vmmc-supply = <&reg_aldo1>;
>>       mmc-pwrseq = <&wifi_pwrseq>;
>>       bus-width = <4>;
>>       non-removable;
>> @@ -169,65 +173,59 @@
>>               reg = <0x68>;
>>               interrupt-parent = <&nmi_intc>;
>>               interrupts = <0 IRQ_TYPE_LEVEL_LOW>;
>> -             interrupt-controller;
>> -             #interrupt-cells = <1>;
>> -             dcdc1-supply = <&vcc_3v0>;
>> -             dcdc5-supply = <&vcc_dram>;
>> -
>> -             regulators {
>> -                     x-powers,dcdc-freq = <3000>;
>> -
>> -                     vcc_3v0: dcdc1 {
>> -                             regulator-always-on;
>> -                             regulator-min-microvolt = <3000000>;
>> -                             regulator-max-microvolt = <3000000>;
>> -                             regulator-name = "vcc-3v0";
>> -                     };
>> -
>> -                     vdd_cpu: dcdc2 {
>> -                             regulator-always-on;
>> -                             regulator-min-microvolt = <700000>;
>> -                             regulator-max-microvolt = <1320000>;
>> -                             regulator-name = "vdd-cpu";
>> -                     };
>> -
>> -                     vdd_gpu: dcdc3 {
>> -                             regulator-always-on;
>> -                             regulator-min-microvolt = <700000>;
>> -                             regulator-max-microvolt = <1320000>;
>> -                             regulator-name = "vdd-gpu";
>> -                     };
>> -
>> -                     vdd_sys_dll: dcdc4 {
>> -                             regulator-always-on;
>> -                             regulator-min-microvolt = <1100000>;
>> -                             regulator-max-microvolt = <1100000>;
>> -                             regulator-name = "vdd-sys-dll";
>> -                     };
>> -
>> -                     vcc_dram: dcdc5 {
>> -                             regulator-always-on;
>> -                             regulator-min-microvolt = <1500000>;
>> -                             regulator-max-microvolt = <1500000>;
>> -                             regulator-name = "vcc-dram";
>> -                     };
>> -
>> -                     vcc_wifi: aldo1 {
>> -                             regulator-min-microvolt = <3300000>;
>> -                             regulator-max-microvolt = <3300000>;
>> -                             regulator-name = "vcc_wifi";
>> -                     };
>> -
>> -                     avcc: aldo3 {
>> -                             regulator-always-on;
>> -                             regulator-min-microvolt = <3000000>;
>> -                             regulator-max-microvolt = <3000000>;
>> -                             regulator-name = "avcc";
>> -                     };
>> -             };
>>       };
>>  };
>>
>> +#include "axp221.dtsi"
>> +
>> +&reg_aldo1 {
>> +     regulator-min-microvolt = <3300000>;
>> +     regulator-max-microvolt = <3300000>;
>> +     regulator-name = "vcc-wifi";
>> +};
>> +
>> +&reg_aldo3 {
>> +     regulator-always-on;
>> +     regulator-min-microvolt = <3000000>;
>> +     regulator-max-microvolt = <3000000>;
>> +     regulator-name = "avcc";
>> +};
>> +
>> +&reg_dcdc1 {
>> +     regulator-always-on;
>> +     regulator-min-microvolt = <3000000>;
>> +     regulator-max-microvolt = <3000000>;
>> +     regulator-name = "vcc-3v0";
>> +};
>> +
>> +&reg_dcdc2 {
>> +     regulator-always-on;
>> +     regulator-min-microvolt = <700000>;
>> +     regulator-max-microvolt = <1320000>;
>> +     regulator-name = "vdd-cpu";
>> +};
>> +
>> +&reg_dcdc3 {
>> +     regulator-always-on;
>> +     regulator-min-microvolt = <700000>;
>> +     regulator-max-microvolt = <1320000>;
>> +     regulator-name = "vdd-gpu";
>> +};
>
> I'm know it's just a mechanical change from your part, but is the GPU
> regulator really need to be always on?

I don't think so. It shouldn't affect anything else, though I can't
think of a way to thoroughly test it. Maybe I just disable it for.
If anyone complains later on when adding new peripherals they can
turn it back on.

ChenYu


From broonie at kernel.org  Fri Aug 28 09:51:32 2015
From: broonie at kernel.org (Mark Brown)
Date: Fri, 28 Aug 2015 17:51:32 +0100
Subject: [PATCH] arm: tegra: update default configuration
In-Reply-To: <986a8cee-f090-4888-91f2-7b564c4b3d1d@email.android.com>
References: <986a8cee-f090-4888-91f2-7b564c4b3d1d@email.android.com>
Message-ID: <20150828165132.GQ12027@sirena.org.uk>

On Fri, Aug 28, 2015 at 05:41:43AM +0000, Marcel Ziswiler wrote:

Please fix your mailer to word wrap within paragraphs so that your mails
are legible.

> On 27 Aug 2015 16:55, Mark Brown <broonie at kernel.org> wrote:

> > Does the system really have the wm9712 wired up as a battery monitor?

> Well, remember we are talking about a system on module. Those WM9712
> pins all go to the 200 pin SODIMM edge connector and I know that
> certain customers indeed have carrier boards that use it that way. If
> there is any opposition and considering this being rather optional I
> may also drop this one but audio/touch is definitely a standard
> feature available on all or carrier boards.

Does that actually work with mainline?  The driver requires platform
data to do anything useful (there's no DT bindings for it) and I can't
see anything providing that on Tegra systems.
-------------- next part --------------
A non-text attachment was scrubbed...
Name: signature.asc
Type: application/pgp-signature
Size: 473 bytes
Desc: Digital signature
URL: <http://lists.infradead.org/pipermail/linux-arm-kernel/attachments/20150828/93e25501/attachment.sig>

From festevam at gmail.com  Fri Aug 28 09:54:25 2015
From: festevam at gmail.com (Fabio Estevam)
Date: Fri, 28 Aug 2015 13:54:25 -0300
Subject: [PATCH v3] ARM: configs: Add Freescale LS1021A defconfig
In-Reply-To: <BN3PR0301MB0867591B07957C47F30C9711FE6E0@BN3PR0301MB0867.namprd03.prod.outlook.com>
References: <1438941784-38403-1-git-send-email-b18965@freescale.com>
 <55CB4829.40204@freescale.com> <55CE1FFE.2080200@freescale.com>
 <CAOMZO5By_15OCsb7z2pbywPi3n9vKGj=393hWYHVEQ32=jDNaA@mail.gmail.com>
 <BN3PR0301MB08672520CA978383BBF2CF6CFE790@BN3PR0301MB0867.namprd03.prod.outlook.com>
 <55D6073C.1020000@freescale.com>
 <BN3PR0301MB0867591B07957C47F30C9711FE6E0@BN3PR0301MB0867.namprd03.prod.outlook.com>
Message-ID: <CAOMZO5DY+HqH-FeFF5rD5rCettfdmni62nHJRAPU5fdXijw=sA@mail.gmail.com>

On Fri, Aug 28, 2015 at 5:04 AM, Huan Wang <alison.wang at freescale.com> wrote:

> I need Fabio's confirmation about removing CONFIG_SOC_LS1021A from imx_v6_v7_config.
>
> Fabio, Do you agree it?

Yes, if Shawn accepts ls1021a_defconfig then we should remove
CONFIG_SOC_LS1021A from imx_v6_v7_config.

Regards,

Fabio Estevam


From peter.griffin at linaro.org  Fri Aug 28 10:07:40 2015
From: peter.griffin at linaro.org (Peter Griffin)
Date: Fri, 28 Aug 2015 18:07:40 +0100
Subject: [PATCH v2 2/5] ARM: DT: STi: STiH407: Add c8sectpfe LinuxDVB DT
 node.
In-Reply-To: <20150828070100.GF4796@x1>
References: <1440678575-21646-1-git-send-email-peter.griffin@linaro.org>
 <1440678575-21646-3-git-send-email-peter.griffin@linaro.org>
 <20150828070100.GF4796@x1>
Message-ID: <20150828170740.GA18136@griffinp-ThinkPad-X1-Carbon-2nd>

Hi Lee,

On Fri, 28 Aug 2015, Lee Jones wrote:

> On Thu, 27 Aug 2015, Peter Griffin wrote:
> 
> > This patch adds in the required DT node for the c8sectpfe
> > Linux DVB demux driver which allows the tsin channels
> > to be used on an upstream kernel.
> > 
> > Signed-off-by: Peter Griffin <peter.griffin at linaro.org>
> > ---
> >  arch/arm/boot/dts/stihxxx-b2120.dtsi | 34 ++++++++++++++++++++++++++++++++++
> >  1 file changed, 34 insertions(+)
> > 
> > diff --git a/arch/arm/boot/dts/stihxxx-b2120.dtsi b/arch/arm/boot/dts/stihxxx-b2120.dtsi
> > index 62994ae..c014173 100644
> > --- a/arch/arm/boot/dts/stihxxx-b2120.dtsi
> > +++ b/arch/arm/boot/dts/stihxxx-b2120.dtsi
> > @@ -6,6 +6,9 @@
> >   * it under the terms of the GNU General Public License version 2 as
> >   * published by the Free Software Foundation.
> >   */
> > +
> > +#include <dt-bindings/clock/stih407-clks.h>
> > +#include <dt-bindings/media/c8sectpfe.h>
> >  / {
> >  	soc {
> >  		sbc_serial0: serial at 9530000 {
> > @@ -85,5 +88,36 @@
> >  			status = "okay";
> >  		};
> >  
> > +		demux at 08a20000 {
> > +			compatible	= "st,stih407-c8sectpfe";
> > +			status		= "okay";
> > +			reg		= <0x08a20000 0x10000>,
> > +					  <0x08a00000 0x4000>;
> 
> These look like they're the wrong way round.

No, it isn't the wrong way round.

> 
> > +			reg-names	= "c8sectpfe", "c8sectpfe-ram";
> > +			interrupts	= <GIC_SPI 34 IRQ_TYPE_NONE>,
> > +					  <GIC_SPI 35 IRQ_TYPE_NONE>;
> > +			interrupt-names	= "c8sectpfe-error-irq",
> > +					  "c8sectpfe-idle-irq";
> > +			pinctrl-names	= "tsin0-serial",
> > +					  "tsin0-parallel",
> > +					  "tsin3-serial",
> > +					  "tsin4-serial",
> > +					  "tsin5-serial";
> > +			pinctrl-0	= <&pinctrl_tsin0_serial>;
> > +			pinctrl-1	= <&pinctrl_tsin0_parallel>;
> > +			pinctrl-2	= <&pinctrl_tsin3_serial>;
> > +			pinctrl-3	= <&pinctrl_tsin4_serial_alt3>;
> > +			pinctrl-4	= <&pinctrl_tsin5_serial_alt1>;
> > +			clock-names	= "c8sectpfe";
> > +			clocks		= <&clk_s_c0_flexgen CLK_PROC_STFE>;
> 
> Personal preferenc is that the *-names properties should come *after*
> the ones they reference.

Ok, will fix this in v3.

> 
> > +			/* tsin0 is TSA on NIMA */
> > +			tsin0: port at 0 {
> > +				tsin-num	= <0>;
> > +				serial-not-parallel;
> > +				i2c-bus		= <&ssc2>;
> > +				rst-gpio	= <&pio15 4 0>;
> 
> "reset-gpios"?
> 
> Use the GPIO DEFINES.

This change is done in patch 4/5 as one atomic commit
(code, dt doc, and dt node).

I could have used the GPIO_DEFINE in this patch and
updated the dt binding in 4/5.

I'll do that in v3.

regards,

Peter.


From peter.griffin at linaro.org  Fri Aug 28 10:09:24 2015
From: peter.griffin at linaro.org (Peter Griffin)
Date: Fri, 28 Aug 2015 18:09:24 +0100
Subject: [PATCH v2 3/5] [media] c8sectpfe: Remove select on undefined
 LIBELF_32
In-Reply-To: <20150828065830.GE4796@x1>
References: <1440678575-21646-1-git-send-email-peter.griffin@linaro.org>
 <1440678575-21646-4-git-send-email-peter.griffin@linaro.org>
 <20150828065830.GE4796@x1>
Message-ID: <20150828170924.GB18136@griffinp-ThinkPad-X1-Carbon-2nd>

Hi Lee,

On Fri, 28 Aug 2015, Lee Jones wrote:

> On Thu, 27 Aug 2015, Peter Griffin wrote:
> 
> > LIBELF_32 is not defined in Kconfig, and is left over legacy
> > which is not required in the upstream driver, so remove it.
> > 
> > Signed-off-by: Peter Griffin <peter.griffin at linaro.org>
> > Suggested-by: Valentin Rothberg <valentinrothberg at gmail.com>
> 
> These are the wrong way round, they should be in chronological order.

Ok will fix in v3.

regards,

Peter.


From agross at codeaurora.org  Fri Aug 28 10:19:04 2015
From: agross at codeaurora.org (Andy Gross)
Date: Fri, 28 Aug 2015 12:19:04 -0500
Subject: [GIT PULL] qcom SoC changes for 4.3-rc2
In-Reply-To: <20150828001603.GO13472@usrtlx11787.corpusers.net>
References: <1440710899-29214-1-git-send-email-agross@codeaurora.org>
 <20150828001603.GO13472@usrtlx11787.corpusers.net>
Message-ID: <20150828171903.GA7886@qualcomm.com>

On Thu, Aug 27, 2015 at 05:16:03PM -0700, Bjorn Andersson wrote:
> On Thu 27 Aug 14:28 PDT 2015, Andy Gross wrote:
> 
> > The following changes since commit 72af1ff60d08a57e223b9753f9c52396fb4c3897:
> > 
> >   Merge tag 'qcom-soc-for-4.3' into for-soc-new (2015-08-27 12:14:29 -0500)
> > 
> > are available in the git repository at:
> > 
> > 
> >   git://codeaurora.org/quic/kernel/agross-msm.git tags/qcom-soc-for-4.3-rc2
> > 
> > for you to fetch changes up to 3427446d72e21f6992534a3b68055f1b4c722546:
> > 
> >   soc: qcom: smd: Use correct remote processor ID (2015-08-27 12:15:58 -0500)
> > 
> > ----------------------------------------------------------------
> > Qualcomm ARM Based SoC Updates for 4.3-rc2
> > 
> > * Fix errant private access in SMEM
> > * Fix use of correct remote processor ID in SMD transactions
> > 
> 
> I was hoping to see my fBLOCKREADINTR fix [1] here as well, as the issue
> it's fixing it a never ending stall if we're trying to send data with a
> full tx fifo - i.e. a rather bad result...
> 
> But I'm fine with you queuing it for -rc3 too...
> 
> [1] https://lkml.org/lkml/2015/8/24/756
> 
> Regards,
> Bjorn

Ack, sorry.  I'll resend it after bumping the subject

-- 
Qualcomm Innovation Center, Inc.
The Qualcomm Innovation Center, Inc. is a member of the Code Aurora Forum,
a Linux Foundation Collaborative Project



From f.fainelli at gmail.com  Fri Aug 28 10:17:28 2015
From: f.fainelli at gmail.com (Florian Fainelli)
Date: Fri, 28 Aug 2015 10:17:28 -0700
Subject: [PATCH v2 4/4] remoteproc: debugfs: Add ability to boot remote
 processor using debugfs
In-Reply-To: <1440757911-9120-5-git-send-email-lee.jones@linaro.org>
References: <1440757911-9120-1-git-send-email-lee.jones@linaro.org>
 <1440757911-9120-5-git-send-email-lee.jones@linaro.org>
Message-ID: <55E097A8.4080305@gmail.com>

On 28/08/15 03:31, Lee Jones wrote:
> This functionality is especially useful during the testing phase.  When
> used in conjunction with Mailbox's Test Framework we can trivially conduct
> end-to-end testing i.e. boot co-processor, send and receive messages to
> the co-processor, then shut it down again (repeat as required).

This does not strike me as a particularly well defined nor suitable
interface for controlling a remote processor's state. I know you are
just extending the existing debugfs interface here, but someone ought to
remove that piece of code and make it a proper character device or
netlink or whatever that allows someone to get proper signaling of
what's going on with the remote processor state by polling or listening
to a socket.

What's the intended use case behind debugfs for this after all? Is your
application expected to keep reading the state file in a loop until it
is happy and reads "running", how is that not racy by nature?

> 
> Signed-off-by: Ludovic Barre <ludovic.barre at st.com>
> Signed-off-by: Lee Jones <lee.jones at linaro.org>
> ---
>  drivers/remoteproc/remoteproc_debugfs.c | 29 +++++++++++++++++++++++++++++
>  1 file changed, 29 insertions(+)
> 
> diff --git a/drivers/remoteproc/remoteproc_debugfs.c b/drivers/remoteproc/remoteproc_debugfs.c
> index 9d30809..464470d 100644
> --- a/drivers/remoteproc/remoteproc_debugfs.c
> +++ b/drivers/remoteproc/remoteproc_debugfs.c
> @@ -88,8 +88,37 @@ static ssize_t rproc_state_read(struct file *filp, char __user *userbuf,
>  	return simple_read_from_buffer(userbuf, count, ppos, buf, i);
>  }
>  
> +static ssize_t rproc_state_write(struct file *filp, const char __user *userbuf,
> +				 size_t count, loff_t *ppos)
> +{
> +	struct rproc *rproc = filp->private_data;
> +	char buf[2];
> +	int ret;
> +
> +	ret = copy_from_user(buf, userbuf, 1);
> +	if (ret)
> +		return -EFAULT;
> +
> +	switch (buf[0]) {
> +	case '0':
> +		rproc_shutdown(rproc);
> +		break;
> +	case '1':
> +		ret = rproc_boot(rproc);
> +		if (ret)
> +			dev_warn(&rproc->dev, "Boot failed: %d\n", ret);
> +		break;
> +	default:
> +		dev_err(&rproc->dev, "Unrecognised option: %x\n", buf[1]);
> +		return -EINVAL;
> +	}
> +
> +	return count;
> +}
> +
>  static const struct file_operations rproc_state_ops = {
>  	.read = rproc_state_read,
> +	.write = rproc_state_write,
>  	.open = simple_open,
>  	.llseek	= generic_file_llseek,
>  };
> 


-- 
Florian


From peter.griffin at linaro.org  Fri Aug 28 10:25:59 2015
From: peter.griffin at linaro.org (Peter Griffin)
Date: Fri, 28 Aug 2015 18:25:59 +0100
Subject: [PATCH v2 5/5] [media] c8sectpfe: Update DT binding doc with
 some minor fixes
In-Reply-To: <20150828065702.GC4796@x1>
References: <1440678575-21646-1-git-send-email-peter.griffin@linaro.org>
 <1440678575-21646-6-git-send-email-peter.griffin@linaro.org>
 <20150828065702.GC4796@x1>
Message-ID: <20150828172559.GC18136@griffinp-ThinkPad-X1-Carbon-2nd>

Hi Lee,

On Fri, 28 Aug 2015, Lee Jones wrote:

> On Thu, 27 Aug 2015, Peter Griffin wrote:
> 
> > Signed-off-by: Peter Griffin <peter.griffin at linaro.org>
> > ---
> >  .../devicetree/bindings/media/stih407-c8sectpfe.txt      | 16 +++++++---------
> >  1 file changed, 7 insertions(+), 9 deletions(-)
> > 
> > diff --git a/Documentation/devicetree/bindings/media/stih407-c8sectpfe.txt b/Documentation/devicetree/bindings/media/stih407-c8sectpfe.txt
> > index e70d840..5d6438c 100644
> > --- a/Documentation/devicetree/bindings/media/stih407-c8sectpfe.txt
> > +++ b/Documentation/devicetree/bindings/media/stih407-c8sectpfe.txt
> > @@ -55,21 +55,20 @@ Example:
> >  		status = "okay";
> >  		reg = <0x08a20000 0x10000>, <0x08a00000 0x4000>;
> >  		reg-names = "stfe", "stfe-ram";
> > -		interrupts = <0 34 0>, <0 35 0>;
> > +		interrupts = <GIC_SPI 34 IRQ_TYPE_NONE>, <GIC_SPI 35 IRQ_TYPE_NONE>;
> >  		interrupt-names = "stfe-error-irq", "stfe-idle-irq";
> > -
> > -		pinctrl-names	= "tsin0-serial", "tsin0-parallel", "tsin3-serial",
> > -				"tsin4-serial", "tsin5-serial";
> > -
> > +		pinctrl-names	= "tsin0-serial",
> > +				  "tsin0-parallel",
> > +				  "tsin3-serial",
> > +				  "tsin4-serial",
> > +				  "tsin5-serial";
> >  		pinctrl-0	= <&pinctrl_tsin0_serial>;
> >  		pinctrl-1	= <&pinctrl_tsin0_parallel>;
> >  		pinctrl-2	= <&pinctrl_tsin3_serial>;
> >  		pinctrl-3	= <&pinctrl_tsin4_serial_alt3>;
> >  		pinctrl-4	= <&pinctrl_tsin5_serial_alt1>;
> > -
> >  		clocks = <&clk_s_c0_flexgen CLK_PROC_STFE>;
> > -		clock-names = "stfe";
> > -
> > +		clock-names = "c8sectpfe";
> 
> Are you sure you even need this property?  I'm thinking that *-names
> properties are *usually* only required if there are more than one in a
> single property.

Yes that is true, but for tsout and merged input stream
functionality the driver will require additional clocks. As I
mentioned in a previous email I hope to add support for this in the
near future.

> 
> >  		/* tsin0 is TSA on NIMA */
> >  		tsin0: port at 0 {
> >  			tsin-num		= <0>;
> > @@ -78,7 +77,6 @@ Example:
> >  			reset-gpios		= <&pio15 4 GPIO_ACTIVE_HIGH>;
> >  			dvb-card		= <STV0367_TDA18212_NIMA_1>;
> >  		};
> > -
> 
> My personal preference is to have a '\n' between nodes.

Yes mine as well, I removed it due to your earlier comment about "superflous \n".
I will add it back in again in v3.

> 
> >  		tsin3: port at 3 {
> >  			tsin-num		= <3>;
> >  			serial-not-parallel;
> 
> But these comments are pretty trivial, so agree or not, or fix-up or
> not, it's that big of a deal.

I agree all trivial, but will fixup in v3.
> 
> Either way,
>   Acked-by: Lee Jones <lee.jones at linaro.org>

Thanks & regards,

Peter.


From broonie at kernel.org  Fri Aug 28 10:33:48 2015
From: broonie at kernel.org (Mark Brown)
Date: Fri, 28 Aug 2015 18:33:48 +0100
Subject: [PATCH v3 0/4] regmap: i2c block support
In-Reply-To: <1440657872-24554-1-git-send-email-mpa@pengutronix.de>
References: <1440657872-24554-1-git-send-email-mpa@pengutronix.de>
Message-ID: <20150828173348.GS12027@sirena.org.uk>

On Thu, Aug 27, 2015 at 08:44:28AM +0200, Markus Pargmann wrote:

> Changes in v3:
> - Rebased onto latest version of "regmap: fixes" series

New code not intended as bug fixes needs to apply against the latest
development code, not a fixes branch (and especially not some out of
tree patch series which may have ended up in multiple branches or
something).  git says it doesn't know what you generated this
against...
-------------- next part --------------
A non-text attachment was scrubbed...
Name: signature.asc
Type: application/pgp-signature
Size: 473 bytes
Desc: Digital signature
URL: <http://lists.infradead.org/pipermail/linux-arm-kernel/attachments/20150828/060ceb9d/attachment.sig>

From peter.griffin at linaro.org  Fri Aug 28 10:52:36 2015
From: peter.griffin at linaro.org (Peter Griffin)
Date: Fri, 28 Aug 2015 18:52:36 +0100
Subject: [PATCH v3 0/6] [media] c8sectpfe: Various fixups
Message-ID: <1440784362-31217-1-git-send-email-peter.griffin@linaro.org>

Hi Mauro,

This series includes a couple of fixes for the c8sectpfe Linux dvb driver.

One was caused by omitting a patch from the original c8sectpfe series which
defined the ssc2 and ssc3 dt nodes, which was then used by the later DT patch.
This patch is included, along with the original patch which you reverted.

Also Valentin Rothberg spotted LIBELF32 Kconfig symbol I was selecting in the
Kconfig, this isn't required upstream and is left over legacy so I've removed
it.

Also included are some fixups spotted by Lee Jones.

Changes since v2:
 - Add some "\n" and other formatting fixes
 - 'Suggested by' should be in chronological order
 - Simplify load_slim_core_fw loop

Changes since v1:
 - Various formating patches to DT node
 - Update to reset-gpios
 - Use GPIO_ACTIVE_HIGH, GIC_SPI and IRQ_TYPE_NONE defines

kind regards,

Peter.

Peter Griffin (6):
  ARM: DT: STi: stihxxx-b2120: Add pulse-width properties to ssc2 & ssc3
  ARM: DT: STi: STiH407: Add c8sectpfe LinuxDVB DT node.
  [media] c8sectpfe: Remove select on undefined LIBELF_32
  [media] c8sectpfe: Update binding to reset-gpios
  [media] c8sectpfe: Update DT binding doc with some minor fixes
  [media] c8sectpfe: Simplify for loop in load_slim_core_fw

 .../bindings/media/stih407-c8sectpfe.txt           | 20 +++++-----
 arch/arm/boot/dts/stihxxx-b2120.dtsi               | 45 +++++++++++++++++++++-
 drivers/media/platform/sti/c8sectpfe/Kconfig       |  1 -
 .../media/platform/sti/c8sectpfe/c8sectpfe-core.c  |  9 +++--
 4 files changed, 58 insertions(+), 17 deletions(-)

-- 
1.9.1



From peter.griffin at linaro.org  Fri Aug 28 10:52:37 2015
From: peter.griffin at linaro.org (Peter Griffin)
Date: Fri, 28 Aug 2015 18:52:37 +0100
Subject: [PATCH v3 1/6] ARM: DT: STi: stihxxx-b2120: Add pulse-width
 properties to ssc2 & ssc3
In-Reply-To: <1440784362-31217-1-git-send-email-peter.griffin@linaro.org>
References: <1440784362-31217-1-git-send-email-peter.griffin@linaro.org>
Message-ID: <1440784362-31217-2-git-send-email-peter.griffin@linaro.org>

Adding these properties makes the I2C bus to the demodulators much
more reliable, and we no longer suffer from I2C errors when tuning.

Signed-off-by: Peter Griffin <peter.griffin at linaro.org>
Acked-by: Lee Jones <lee.jones at linaro.org>
---
 arch/arm/boot/dts/stihxxx-b2120.dtsi | 10 ++++++++--
 1 file changed, 8 insertions(+), 2 deletions(-)

diff --git a/arch/arm/boot/dts/stihxxx-b2120.dtsi b/arch/arm/boot/dts/stihxxx-b2120.dtsi
index f589fe4..62994ae 100644
--- a/arch/arm/boot/dts/stihxxx-b2120.dtsi
+++ b/arch/arm/boot/dts/stihxxx-b2120.dtsi
@@ -27,12 +27,18 @@
 			};
 		};
 
-		i2c at 9842000 {
+		ssc2: i2c at 9842000 {
 			status = "okay";
+			clock-frequency = <100000>;
+			st,i2c-min-scl-pulse-width-us = <0>;
+			st,i2c-min-sda-pulse-width-us = <5>;
 		};
 
-		i2c at 9843000 {
+		ssc3: i2c at 9843000 {
 			status = "okay";
+			clock-frequency = <100000>;
+			st,i2c-min-scl-pulse-width-us = <0>;
+			st,i2c-min-sda-pulse-width-us = <5>;
 		};
 
 		i2c at 9844000 {
-- 
1.9.1



From peter.griffin at linaro.org  Fri Aug 28 10:52:39 2015
From: peter.griffin at linaro.org (Peter Griffin)
Date: Fri, 28 Aug 2015 18:52:39 +0100
Subject: [PATCH v3 3/6] [media] c8sectpfe: Remove select on undefined LIBELF_32
In-Reply-To: <1440784362-31217-1-git-send-email-peter.griffin@linaro.org>
References: <1440784362-31217-1-git-send-email-peter.griffin@linaro.org>
Message-ID: <1440784362-31217-4-git-send-email-peter.griffin@linaro.org>

LIBELF_32 is not defined in Kconfig, and is left over legacy
which is not required in the upstream driver, so remove it.

Suggested-by: Valentin Rothberg <valentinrothberg at gmail.com>
Signed-off-by: Peter Griffin <peter.griffin at linaro.org>
Acked-by: Lee Jones <lee.jones at linaro.org>
---
 drivers/media/platform/sti/c8sectpfe/Kconfig | 1 -
 1 file changed, 1 deletion(-)

diff --git a/drivers/media/platform/sti/c8sectpfe/Kconfig b/drivers/media/platform/sti/c8sectpfe/Kconfig
index d1bfd4c..b9ec667 100644
--- a/drivers/media/platform/sti/c8sectpfe/Kconfig
+++ b/drivers/media/platform/sti/c8sectpfe/Kconfig
@@ -1,7 +1,6 @@
 config DVB_C8SECTPFE
 	tristate "STMicroelectronics C8SECTPFE DVB support"
 	depends on DVB_CORE && I2C && (ARCH_STI || ARCH_MULTIPLATFORM)
-	select LIBELF_32
 	select FW_LOADER
 	select FW_LOADER_USER_HELPER_FALLBACK
 	select DEBUG_FS
-- 
1.9.1



From peter.griffin at linaro.org  Fri Aug 28 10:52:40 2015
From: peter.griffin at linaro.org (Peter Griffin)
Date: Fri, 28 Aug 2015 18:52:40 +0100
Subject: [PATCH v3 4/6] [media] c8sectpfe: Update binding to reset-gpios
In-Reply-To: <1440784362-31217-1-git-send-email-peter.griffin@linaro.org>
References: <1440784362-31217-1-git-send-email-peter.griffin@linaro.org>
Message-ID: <1440784362-31217-5-git-send-email-peter.griffin@linaro.org>

gpio.txt documents that GPIO properties should be named
"[<name>-]gpios", with <name> being the purpose of this
GPIO for the device.

This change has been done as one atomic commit.

Signed-off-by: Peter Griffin <peter.griffin at linaro.org>
Acked-by: Lee Jones <lee.jones at linaro.org>
---
 Documentation/devicetree/bindings/media/stih407-c8sectpfe.txt | 6 +++---
 arch/arm/boot/dts/stihxxx-b2120.dtsi                          | 4 ++--
 drivers/media/platform/sti/c8sectpfe/c8sectpfe-core.c         | 2 +-
 3 files changed, 6 insertions(+), 6 deletions(-)

diff --git a/Documentation/devicetree/bindings/media/stih407-c8sectpfe.txt b/Documentation/devicetree/bindings/media/stih407-c8sectpfe.txt
index d4def76..e70d840 100644
--- a/Documentation/devicetree/bindings/media/stih407-c8sectpfe.txt
+++ b/Documentation/devicetree/bindings/media/stih407-c8sectpfe.txt
@@ -35,7 +35,7 @@ Required properties (tsin (child) node):
 
 - tsin-num	: tsin id of the InputBlock (must be between 0 to 6)
 - i2c-bus	: phandle to the I2C bus DT node which the demodulators & tuners on this tsin channel are connected.
-- rst-gpio	: reset gpio for this tsin channel.
+- reset-gpios	: reset gpio for this tsin channel.
 
 Optional properties (tsin (child) node):
 
@@ -75,7 +75,7 @@ Example:
 			tsin-num		= <0>;
 			serial-not-parallel;
 			i2c-bus			= <&ssc2>;
-			rst-gpio		= <&pio15 4 0>;
+			reset-gpios		= <&pio15 4 GPIO_ACTIVE_HIGH>;
 			dvb-card		= <STV0367_TDA18212_NIMA_1>;
 		};
 
@@ -83,7 +83,7 @@ Example:
 			tsin-num		= <3>;
 			serial-not-parallel;
 			i2c-bus			= <&ssc3>;
-			rst-gpio		= <&pio15 7 0>;
+			reset-gpios		= <&pio15 7 GPIO_ACTIVE_HIGH>;
 			dvb-card		= <STV0367_TDA18212_NIMB_1>;
 		};
 	};
diff --git a/arch/arm/boot/dts/stihxxx-b2120.dtsi b/arch/arm/boot/dts/stihxxx-b2120.dtsi
index f9fca10..0b7592e 100644
--- a/arch/arm/boot/dts/stihxxx-b2120.dtsi
+++ b/arch/arm/boot/dts/stihxxx-b2120.dtsi
@@ -6,8 +6,8 @@
  * it under the terms of the GNU General Public License version 2 as
  * published by the Free Software Foundation.
  */
-
 #include <dt-bindings/clock/stih407-clks.h>
+#include <dt-bindings/gpio/gpio.h>
 #include <dt-bindings/media/c8sectpfe.h>
 / {
 	soc {
@@ -116,7 +116,7 @@
 				tsin-num	= <0>;
 				serial-not-parallel;
 				i2c-bus		= <&ssc2>;
-				rst-gpio	= <&pio15 4 GPIO_ACTIVE_HIGH>;
+				reset-gpios	= <&pio15 4 GPIO_ACTIVE_HIGH>;
 				dvb-card	= <STV0367_TDA18212_NIMA_1>;
 			};
 		};
diff --git a/drivers/media/platform/sti/c8sectpfe/c8sectpfe-core.c b/drivers/media/platform/sti/c8sectpfe/c8sectpfe-core.c
index 3a91093..c691e13 100644
--- a/drivers/media/platform/sti/c8sectpfe/c8sectpfe-core.c
+++ b/drivers/media/platform/sti/c8sectpfe/c8sectpfe-core.c
@@ -822,7 +822,7 @@ static int c8sectpfe_probe(struct platform_device *pdev)
 		}
 		of_node_put(i2c_bus);
 
-		tsin->rst_gpio = of_get_named_gpio(child, "rst-gpio", 0);
+		tsin->rst_gpio = of_get_named_gpio(child, "reset-gpios", 0);
 
 		ret = gpio_is_valid(tsin->rst_gpio);
 		if (!ret) {
-- 
1.9.1



From peter.griffin at linaro.org  Fri Aug 28 10:52:42 2015
From: peter.griffin at linaro.org (Peter Griffin)
Date: Fri, 28 Aug 2015 18:52:42 +0100
Subject: [PATCH v3 6/6] [media] c8sectpfe: Simplify for loop in
 load_slim_core_fw
In-Reply-To: <1440784362-31217-1-git-send-email-peter.griffin@linaro.org>
References: <1440784362-31217-1-git-send-email-peter.griffin@linaro.org>
Message-ID: <1440784362-31217-7-git-send-email-peter.griffin@linaro.org>

Signed-off-by: Peter Griffin <peter.griffin at linaro.org>
---
 drivers/media/platform/sti/c8sectpfe/c8sectpfe-core.c | 7 ++++---
 1 file changed, 4 insertions(+), 3 deletions(-)

diff --git a/drivers/media/platform/sti/c8sectpfe/c8sectpfe-core.c b/drivers/media/platform/sti/c8sectpfe/c8sectpfe-core.c
index c691e13..ce72ffb 100644
--- a/drivers/media/platform/sti/c8sectpfe/c8sectpfe-core.c
+++ b/drivers/media/platform/sti/c8sectpfe/c8sectpfe-core.c
@@ -1096,7 +1096,7 @@ static int load_slim_core_fw(const struct firmware *fw, void *context)
 	Elf32_Ehdr *ehdr;
 	Elf32_Phdr *phdr;
 	u8 __iomem *dst;
-	int err, i;
+	int err = 0, i;
 
 	if (!fw || !context)
 		return -EINVAL;
@@ -1105,7 +1105,7 @@ static int load_slim_core_fw(const struct firmware *fw, void *context)
 	phdr = (Elf32_Phdr *)(fw->data + ehdr->e_phoff);
 
 	/* go through the available ELF segments */
-	for (i = 0; i < ehdr->e_phnum && !err; i++, phdr++) {
+	for (i = 0; i < ehdr->e_phnum; i++, phdr++) {
 
 		/* Only consider LOAD segments */
 		if (phdr->p_type != PT_LOAD)
@@ -1118,7 +1118,7 @@ static int load_slim_core_fw(const struct firmware *fw, void *context)
 			dev_err(fei->dev,
 				"Segment %d is outside of firmware file\n", i);
 			err = -EINVAL;
-			break;
+			goto err;
 		}
 
 		/*
@@ -1146,6 +1146,7 @@ static int load_slim_core_fw(const struct firmware *fw, void *context)
 		}
 	}
 
+err:
 	release_firmware(fw);
 	return err;
 }
-- 
1.9.1



From peter.griffin at linaro.org  Fri Aug 28 10:59:22 2015
From: peter.griffin at linaro.org (Peter Griffin)
Date: Fri, 28 Aug 2015 18:59:22 +0100
Subject: [PATCH 3/7] dmaengine: st_fdma: Add STMicroelectronics FDMA
 engine driver support
In-Reply-To: <1436429872.20619.77.camel@tiscali.nl>
References: <1436371888-27863-1-git-send-email-peter.griffin@linaro.org>
 <1436371888-27863-4-git-send-email-peter.griffin@linaro.org>
 <1436429872.20619.77.camel@tiscali.nl>
Message-ID: <20150828175922.GA2853@griffinp-ThinkPad-X1-Carbon-2nd>

Hi Paul,

Thanks for reviewing.

On Thu, 09 Jul 2015, Paul Bolle wrote:

> On wo, 2015-07-08 at 17:11 +0100, Peter Griffin wrote:
> > --- a/drivers/dma/Kconfig
> > +++ b/drivers/dma/Kconfig
>  
> > +config ST_FDMA
> > +	bool "ST FDMA dmaengine support"
> > +	depends on ARCH_STI
> > +	select DMA_ENGINE
> > +	select FW_LOADER
> > +	select FW_LOADER_USER_HELPER_FALLBACK
> > +	select LIBELF_32
> > +	select DMA_VIRTUAL_CHANNELS
> > +	help
> > +	  Enable support for ST FDMA controller.
> > +	  It supports 16 independent DMA channels, accepts up to 32 DMA requests
> > +
> > +	  Say Y here if you have such a chipset.
> > +	  If unsure, say N.
> 
> > --- a/drivers/dma/Makefile
> > +++ b/drivers/dma/Makefile
> > 
> > +obj-$(CONFIG_ST_FDMA) += st_fdma.o
> 
> ST_FDMA is a bool symbol, so st_fdma.o can only be built-in.

Yes good spot, that is a mistake it should be tristate. Will fix in v2.

> 
> > --- /dev/null
> > +++ b/drivers/dma/st_fdma.c
> 
> > +#include <linux/module.h>
> 
> Needed?
> 
> > +void *st_fdma_seg_to_mem(struct st_fdma_dev *fdev, u64 da, int len)
> 
> static?

Fixed in v2.

> 
> > +{
> > +	[...]
> > +}
> 
> > +static int
> > +st_fdma_elf_load_segments(struct st_fdma_dev *fdev, const struct 
> > firmware *fw)
> > +{
> > +	[...]
> > +		dst = st_fdma_seg_to_mem(fdev, da, memsz);
> > +		[...]
> > +}
> 
> > +static const struct of_device_id st_fdma_match[] = {
> > +	{ .compatible = "st,fdma_mpe31", .data = &fdma_mpe31 },
> > +	{},
> > +};
> > +MODULE_DEVICE_TABLE(of, st_fdma_match);
> 
> MODULE_DEVICE_TABLE() is preprocessed away for built-in only code.
> 
> > +static int __exit st_fdma_remove(struct platform_device *pdev)
> > +{
> > +	struct st_fdma_dev *fdev = platform_get_drvdata(pdev);
> > +
> > +	wait_for_completion(&fdev->fw_ack);
> > +
> > +	st_fdma_clk_disable(fdev);
> > +
> > +	return 0;
> > +}
> 
> Since this driver is built-in only this means st_fdma_remove() can never
> be used, right?

Will be capable of being a module in v2.

> 
> > +static struct platform_driver st_fdma_platform_driver = {
> > +	.driver = {
> > +		.name = "st-fdma",
> > +		.of_match_table = st_fdma_match,
> > +		.pm = ST_FDMA_PM,
> > +	},
> > +	.probe = st_fdma_probe,
> > +	.remove = st_fdma_remove,
> > +};
> > +module_platform_driver(st_fdma_platform_driver);
> 
> So can .remove be dropped?
> 
> Since v4.2-rc1 there's builtin_platform_driver() for built-in only code.

Thanks for the pointer, I wasn't aware of that function.

> 
> > +bool st_fdma_filter_fn(struct dma_chan *chan, void *param)
> > +{
> > +	[...]
> > +}
> > +EXPORT_SYMBOL(st_fdma_filter_fn);
> 
> This series adds no users of this export. I suppose they will be added
> in another series. Is that correct?

No the export is not required. Will fix in v2.

> 
> > +MODULE_LICENSE("GPL v2");
> > +MODULE_DESCRIPTION("STMicroelectronics FDMA engine driver");
> > +MODULE_AUTHOR("Ludovic.barre <Ludovic.barre at st.com>");
> 
> These macros will, basically, be preprocessed away for built-in only
> code.

The driver will be capable of being a module in v2.

regards,

Peter.


From peter.griffin at linaro.org  Fri Aug 28 10:52:41 2015
From: peter.griffin at linaro.org (Peter Griffin)
Date: Fri, 28 Aug 2015 18:52:41 +0100
Subject: [PATCH v3 5/6] [media] c8sectpfe: Update DT binding doc with some
 minor fixes
In-Reply-To: <1440784362-31217-1-git-send-email-peter.griffin@linaro.org>
References: <1440784362-31217-1-git-send-email-peter.griffin@linaro.org>
Message-ID: <1440784362-31217-6-git-send-email-peter.griffin@linaro.org>

Signed-off-by: Peter Griffin <peter.griffin at linaro.org>
Acked-by: Lee Jones <lee.jones at linaro.org>
---
 .../devicetree/bindings/media/stih407-c8sectpfe.txt        | 14 +++++++-------
 1 file changed, 7 insertions(+), 7 deletions(-)

diff --git a/Documentation/devicetree/bindings/media/stih407-c8sectpfe.txt b/Documentation/devicetree/bindings/media/stih407-c8sectpfe.txt
index e70d840..cc51b1f 100644
--- a/Documentation/devicetree/bindings/media/stih407-c8sectpfe.txt
+++ b/Documentation/devicetree/bindings/media/stih407-c8sectpfe.txt
@@ -55,20 +55,20 @@ Example:
 		status = "okay";
 		reg = <0x08a20000 0x10000>, <0x08a00000 0x4000>;
 		reg-names = "stfe", "stfe-ram";
-		interrupts = <0 34 0>, <0 35 0>;
+		interrupts = <GIC_SPI 34 IRQ_TYPE_NONE>, <GIC_SPI 35 IRQ_TYPE_NONE>;
 		interrupt-names = "stfe-error-irq", "stfe-idle-irq";
-
-		pinctrl-names	= "tsin0-serial", "tsin0-parallel", "tsin3-serial",
-				"tsin4-serial", "tsin5-serial";
-
 		pinctrl-0	= <&pinctrl_tsin0_serial>;
 		pinctrl-1	= <&pinctrl_tsin0_parallel>;
 		pinctrl-2	= <&pinctrl_tsin3_serial>;
 		pinctrl-3	= <&pinctrl_tsin4_serial_alt3>;
 		pinctrl-4	= <&pinctrl_tsin5_serial_alt1>;
-
+		pinctrl-names	= "tsin0-serial",
+				  "tsin0-parallel",
+				  "tsin3-serial",
+				  "tsin4-serial",
+				  "tsin5-serial";
 		clocks = <&clk_s_c0_flexgen CLK_PROC_STFE>;
-		clock-names = "stfe";
+		clock-names = "c8sectpfe";
 
 		/* tsin0 is TSA on NIMA */
 		tsin0: port at 0 {
-- 
1.9.1



From peter.griffin at linaro.org  Fri Aug 28 10:52:38 2015
From: peter.griffin at linaro.org (Peter Griffin)
Date: Fri, 28 Aug 2015 18:52:38 +0100
Subject: [PATCH v3 2/6] ARM: DT: STi: STiH407: Add c8sectpfe LinuxDVB DT node.
In-Reply-To: <1440784362-31217-1-git-send-email-peter.griffin@linaro.org>
References: <1440784362-31217-1-git-send-email-peter.griffin@linaro.org>
Message-ID: <1440784362-31217-3-git-send-email-peter.griffin@linaro.org>

This patch adds in the required DT node for the c8sectpfe
Linux DVB demux driver which allows the tsin channels
to be used on an upstream kernel.

Signed-off-by: Peter Griffin <peter.griffin at linaro.org>
---
 arch/arm/boot/dts/stihxxx-b2120.dtsi | 35 +++++++++++++++++++++++++++++++++++
 1 file changed, 35 insertions(+)

diff --git a/arch/arm/boot/dts/stihxxx-b2120.dtsi b/arch/arm/boot/dts/stihxxx-b2120.dtsi
index 62994ae..f9fca10 100644
--- a/arch/arm/boot/dts/stihxxx-b2120.dtsi
+++ b/arch/arm/boot/dts/stihxxx-b2120.dtsi
@@ -6,6 +6,9 @@
  * it under the terms of the GNU General Public License version 2 as
  * published by the Free Software Foundation.
  */
+
+#include <dt-bindings/clock/stih407-clks.h>
+#include <dt-bindings/media/c8sectpfe.h>
 / {
 	soc {
 		sbc_serial0: serial at 9530000 {
@@ -85,5 +88,37 @@
 			status = "okay";
 		};
 
+		demux at 08a20000 {
+			compatible	= "st,stih407-c8sectpfe";
+			status		= "okay";
+			reg		= <0x08a20000 0x10000>,
+					  <0x08a00000 0x4000>;
+			reg-names	= "c8sectpfe", "c8sectpfe-ram";
+			interrupts	= <GIC_SPI 34 IRQ_TYPE_NONE>,
+					  <GIC_SPI 35 IRQ_TYPE_NONE>;
+			interrupt-names	= "c8sectpfe-error-irq",
+					  "c8sectpfe-idle-irq";
+			pinctrl-0	= <&pinctrl_tsin0_serial>;
+			pinctrl-1	= <&pinctrl_tsin0_parallel>;
+			pinctrl-2	= <&pinctrl_tsin3_serial>;
+			pinctrl-3	= <&pinctrl_tsin4_serial_alt3>;
+			pinctrl-4	= <&pinctrl_tsin5_serial_alt1>;
+			pinctrl-names	= "tsin0-serial",
+					  "tsin0-parallel",
+					  "tsin3-serial",
+					  "tsin4-serial",
+					  "tsin5-serial";
+			clocks		= <&clk_s_c0_flexgen CLK_PROC_STFE>;
+			clock-names	= "c8sectpfe";
+
+			/* tsin0 is TSA on NIMA */
+			tsin0: port at 0 {
+				tsin-num	= <0>;
+				serial-not-parallel;
+				i2c-bus		= <&ssc2>;
+				rst-gpio	= <&pio15 4 GPIO_ACTIVE_HIGH>;
+				dvb-card	= <STV0367_TDA18212_NIMA_1>;
+			};
+		};
 	};
 };
-- 
1.9.1



From sboyd at codeaurora.org  Fri Aug 28 11:18:49 2015
From: sboyd at codeaurora.org (Stephen Boyd)
Date: Fri, 28 Aug 2015 11:18:49 -0700
Subject: [PATCH] soc: qcom: smem: Avoid NULL pointer exception on remove
Message-ID: <1440785929-22441-1-git-send-email-sboyd@codeaurora.org>

Don't set a pointer to NULL and then dereference it in the next
line.

Cc: Bjorn Andersson <bjorn.andersson at sonymobile.com>
Signed-off-by: Stephen Boyd <sboyd at codeaurora.org>
---
 drivers/soc/qcom/smem.c | 2 +-
 1 file changed, 1 insertion(+), 1 deletion(-)

diff --git a/drivers/soc/qcom/smem.c b/drivers/soc/qcom/smem.c
index 6603201d7fc7..4c347e7c5880 100644
--- a/drivers/soc/qcom/smem.c
+++ b/drivers/soc/qcom/smem.c
@@ -737,8 +737,8 @@ static int qcom_smem_probe(struct platform_device *pdev)
 
 static int qcom_smem_remove(struct platform_device *pdev)
 {
-	__smem = NULL;
 	hwspin_lock_free(__smem->hwlock);
+	__smem = NULL;
 
 	return 0;
 }
-- 
The Qualcomm Innovation Center, Inc. is a member of the Code Aurora Forum,
a Linux Foundation Collaborative Project



From sonnyrao at chromium.org  Fri Aug 28 11:19:52 2015
From: sonnyrao at chromium.org (Sonny Rao)
Date: Fri, 28 Aug 2015 11:19:52 -0700
Subject: [PATCH 1/5] DMA: pl330: support burst mode for dev-to-mem and
 mem-to-dev transmit
In-Reply-To: <55DF1072.1070905@rock-chips.com>
References: <1440665280-31557-1-git-send-email-shawn.lin@rock-chips.com>
 <1440665313-31603-1-git-send-email-shawn.lin@rock-chips.com>
 <CAJKOXPdw+ZZURRPUNvKHdx7wRG7M-Frqmvq46KFM_ckGq8h0Yg@mail.gmail.com>
 <55DF1072.1070905@rock-chips.com>
Message-ID: <CAPz6YkX-d8B1wPgjnULDAY8+nyuFePVrEU2NQe0rV2CsjYEj3Q@mail.gmail.com>

On Thu, Aug 27, 2015 at 6:28 AM, Shawn Lin <shawn.lin at rock-chips.com> wrote:
> ? 2015/8/27 20:57, Krzysztof Kozlowski ??:
>>
>> 2015-08-27 17:48 GMT+09:00 Shawn Lin <shawn.lin at rock-chips.com>:
>>>
>>>
>>> This patch adds to support burst mode for dev-to-mem and
>>> mem-to-dev transmit.
>>>
>>> Signed-off-by: Boojin Kim <boojin.kim at samsung.com>
>>> Signed-off-by: Addy Ke <addy.ke at rock-chips.com>
>>> Signed-off-by: Shawn Lin <shawn.lin at rock-chips.com>
>>> cc: Heiko Stuebner <heiko at sntech.de>
>>> cc: Doug Anderson <dianders at chromium.org>
>>> cc: Olof Johansson <olofj at google.com>
>>> Reviewed-and-tested-by: Sonny Rao <sonnyrao at chromium.org>
>>
>>
>> For the entire patchset: I would prefer to see someone's
>> reviewed/tested tag in his response. Sending a version 1 of patchset
>> (regardless of Boojin Kim's work two years ago) with such tag could
>> mean anything. I cannot verify it easily (unless digging somewhere...
>> or asking people). You could add for example: Reviewed-by Santa Claus.
>> Should I sent a letter to him asking for confirmation? :)
>>
>
> :) yes, you are right. I should comply with the rule, even if the patchest
> had been reviewed or tested by someone on another tree.

Hi, yeah I reviewed on a different tree, so you shouldn't put that tag
here, thanks for removing it.
I can re-review if you'd like.

>
>
>> More seriously - reviewed-by is a statement (please look at
>> Documentation/SubmittingPatches) and you cannot force someone to make
>> that statement. He must make such statement on his own.
>>
>> That's all from my side since I don't feel skilled enough to review the
>> code.
>>
>> Best regards,
>> Krzysztof
>>
>>>
>>> ---
>>>
>>>   drivers/dma/pl330.c | 18 ++++++++++++------
>>>   1 file changed, 12 insertions(+), 6 deletions(-)
>>>
>>> diff --git a/drivers/dma/pl330.c b/drivers/dma/pl330.c
>>> index ecab4ea0..0d544d2 100644
>>> --- a/drivers/dma/pl330.c
>>> +++ b/drivers/dma/pl330.c
>>> @@ -1141,10 +1141,13 @@ static inline int _ldst_devtomem(unsigned
>>> dry_run, u8 buf[],
>>>                  const struct _xfer_spec *pxs, int cyc)
>>>   {
>>>          int off = 0;
>>> +       enum pl330_cond cond;
>>> +
>>> +       cond = (pxs->desc->rqcfg.brst_len == 1) ? SINGLE : BURST;
>>>
>>>          while (cyc--) {
>>> -               off += _emit_WFP(dry_run, &buf[off], SINGLE,
>>> pxs->desc->peri);
>>> -               off += _emit_LDP(dry_run, &buf[off], SINGLE,
>>> pxs->desc->peri);
>>> +               off += _emit_WFP(dry_run, &buf[off], cond,
>>> pxs->desc->peri);
>>> +               off += _emit_LDP(dry_run, &buf[off], cond,
>>> pxs->desc->peri);
>>>                  off += _emit_ST(dry_run, &buf[off], ALWAYS);
>>>                  off += _emit_FLUSHP(dry_run, &buf[off],
>>> pxs->desc->peri);
>>>          }
>>> @@ -1156,11 +1159,14 @@ static inline int _ldst_memtodev(unsigned
>>> dry_run, u8 buf[],
>>>                  const struct _xfer_spec *pxs, int cyc)
>>>   {
>>>          int off = 0;
>>> +       enum pl330_cond cond;
>>> +
>>> +       cond = (pxs->desc->rqcfg.brst_len == 1) ? SINGLE : BURST;
>>>
>>>          while (cyc--) {
>>> -               off += _emit_WFP(dry_run, &buf[off], SINGLE,
>>> pxs->desc->peri);
>>> +               off += _emit_WFP(dry_run, &buf[off], cond,
>>> pxs->desc->peri);
>>>                  off += _emit_LD(dry_run, &buf[off], ALWAYS);
>>> -               off += _emit_STP(dry_run, &buf[off], SINGLE,
>>> pxs->desc->peri);
>>> +               off += _emit_STP(dry_run, &buf[off], cond,
>>> pxs->desc->peri);
>>>                  off += _emit_FLUSHP(dry_run, &buf[off],
>>> pxs->desc->peri);
>>>          }
>>>
>>> @@ -2557,7 +2563,7 @@ static struct dma_async_tx_descriptor
>>> *pl330_prep_dma_cyclic(
>>>
>>>                  desc->rqtype = direction;
>>>                  desc->rqcfg.brst_size = pch->burst_sz;
>>> -               desc->rqcfg.brst_len = 1;
>>> +               desc->rqcfg.brst_len = pch->burst_len;
>>>                  desc->bytes_requested = period_len;
>>>                  fill_px(&desc->px, dst, src, period_len);
>>>
>>> @@ -2702,7 +2708,7 @@ pl330_prep_slave_sg(struct dma_chan *chan, struct
>>> scatterlist *sgl,
>>>                  }
>>>
>>>                  desc->rqcfg.brst_size = pch->burst_sz;
>>> -               desc->rqcfg.brst_len = 1;
>>> +               desc->rqcfg.brst_len = pch->burst_len;
>>>                  desc->rqtype = direction;
>>>                  desc->bytes_requested = sg_dma_len(sg);
>>>          }
>>> --
>>> 2.3.7
>>>
>>>
>>> --
>>> To unsubscribe from this list: send the line "unsubscribe dmaengine" in
>>> the body of a message to majordomo at vger.kernel.org
>>> More majordomo info at  http://vger.kernel.org/majordomo-info.html
>>
>>
>>
>>
>
>
> --
> Best Regards
> Shawn Lin
>
> --
> To unsubscribe from this list: send the line "unsubscribe linux-kernel" in
> the body of a message to majordomo at vger.kernel.org
> More majordomo info at  http://vger.kernel.org/majordomo-info.html
> Please read the FAQ at  http://www.tux.org/lkml/


From sboyd at codeaurora.org  Fri Aug 28 11:23:33 2015
From: sboyd at codeaurora.org (Stephen Boyd)
Date: Fri, 28 Aug 2015 11:23:33 -0700
Subject: [PATCH] soc: qcom: Reorder SMEM/SMD configs
Message-ID: <1440786213-23375-1-git-send-email-sboyd@codeaurora.org>

When I make nconfig, having the SMEM option after the SMD option
causes the configurator to get confused when I'm enabling and
disabling these options. Let's move SMEM before SMD so there's a
clear indented dependency chain.

Cc: Bjorn Andersson <bjorn.andersson at sonymobile.com>
Signed-off-by: Stephen Boyd <sboyd at codeaurora.org>
---
 drivers/soc/qcom/Kconfig | 16 ++++++++--------
 1 file changed, 8 insertions(+), 8 deletions(-)

diff --git a/drivers/soc/qcom/Kconfig b/drivers/soc/qcom/Kconfig
index ba47b70f4d85..3e4d2133c3d2 100644
--- a/drivers/soc/qcom/Kconfig
+++ b/drivers/soc/qcom/Kconfig
@@ -19,6 +19,14 @@ config QCOM_PM
 	  modes. It interface with various system drivers to put the cores in
 	  low power modes.
 
+config QCOM_SMEM
+	tristate "Qualcomm Shared Memory Manager (SMEM)"
+	depends on ARCH_QCOM
+	help
+	  Say y here to enable support for the Qualcomm Shared Memory Manager.
+	  The driver provides an interface to items in a heap shared among all
+	  processors in a Qualcomm platform.
+
 config QCOM_SMD
 	tristate "Qualcomm Shared Memory Driver (SMD)"
 	depends on QCOM_SMEM
@@ -40,11 +48,3 @@ config QCOM_SMD_RPM
 
 	  Say M here if you want to include support for the Qualcomm RPM as a
 	  module. This will build a module called "qcom-smd-rpm".
-
-config QCOM_SMEM
-	tristate "Qualcomm Shared Memory Manager (SMEM)"
-	depends on ARCH_QCOM
-	help
-	  Say y here to enable support for the Qualcomm Shared Memory Manager.
-	  The driver provides an interface to items in a heap shared among all
-	  processors in a Qualcomm platform.
-- 
The Qualcomm Innovation Center, Inc. is a member of the Code Aurora Forum,
a Linux Foundation Collaborative Project



From sjg at chromium.org  Fri Aug 28 11:27:03 2015
From: sjg at chromium.org (Simon Glass)
Date: Fri, 28 Aug 2015 12:27:03 -0600
Subject: [PATCH] arm: rpi: Device tree modifications for U-Boot
In-Reply-To: <CAL_JsqJ-N+nFEMEEmg4O45DVF0g382fUvjGTH=fP_HbgK38aKw@mail.gmail.com>
References: <1439303153-12171-1-git-send-email-sjg@chromium.org>
 <1439312701.2451.3.camel@lynxeye.de>
 <CAPnjgZ3ztXnkxZJvitiXiKMzq5+x46hbv0PW4HcF7yGgsXUV+Q@mail.gmail.com>
 <CAPnjgZ0hzyjy=8o8ocaGCoOC7Js4CirhystidbvtabzbhRi4RQ@mail.gmail.com>
 <CAL_Jsq++ihz6svJAKWwT7-=KyJvyWXjdf=tZb4aDGgV_Dc=-Nw@mail.gmail.com>
 <CAPnjgZ3ubK_5j4AV4wO6xgoRf8iN+G8YSQm0pSW5fVzwpxYu5Q@mail.gmail.com>
 <CAL_JsqJ-N+nFEMEEmg4O45DVF0g382fUvjGTH=fP_HbgK38aKw@mail.gmail.com>
Message-ID: <CAPnjgZ2L1TOOmiUSKk-=gpAUt8tvZU1SkGBmdbHJR1tBhE2nTA@mail.gmail.com>

Hi Rob,

On 25 August 2015 at 10:22, Rob Herring <robherring2 at gmail.com> wrote:
> On Sat, Aug 15, 2015 at 8:46 AM, Simon Glass <sjg at chromium.org> wrote:
>> Hi Rob,
>>
>> On 14 August 2015 at 14:29, Rob Herring <robherring2 at gmail.com> wrote:
>>> On Fri, Aug 14, 2015 at 1:34 PM, Simon Glass <sjg at chromium.org> wrote:
>>>> -linux-tegra
>>>>
>>>> Hi,
>>>>
>>>> On 12 August 2015 at 07:21, Simon Glass <sjg at chromium.org> wrote:
>>>>> Hi Lucas,
>>>>>
>>>>> On 11 August 2015 at 11:05, Lucas Stach <dev at lynxeye.de> wrote:
>>>>>> Hi Simon,
>>>>>>
>>>>>> why did you send this to the Tegra ML?
>>>>>>
>>>>>> Am Dienstag, den 11.08.2015, 08:25 -0600 schrieb Simon Glass:
>>>>>>> This updates the device tree from the kernel version to something suitable
>>>>>>> for U-Boot:
>>>>>>>
>>>>>>> - Add stdout-path alias for console
>>>>>>> - Mark the /soc node to be available pre-relocation so that the early
>>>>>>> serial console works (we need the 'ranges' property to be available)
>>>
>>> I find it quite strange that you must explicitly enable the parent
>>> node, but not the uart node.
>>
>> U-Boot tries hard to find and bind the UART using the stdout-path
>> link. I would like to add it in the UART node also but we were able to
>> work around it so far.
>>
>>>
>>>>>>>
>>>>>>> Signed-off-by: Simon Glass <sjg at chromium.org>
>>>>>>> ---
>>>>>>>
>>>>>>>  arch/arm/boot/dts/bcm2835.dtsi | 4 +++-
>>>>>>>  1 file changed, 3 insertions(+), 1 deletion(-)
>>>>>>>
>>>>>>> diff --git a/arch/arm/boot/dts/bcm2835.dtsi b/arch/arm/boot/dts/bcm2835.dtsi
>>>>>>> index 301c73f..bd6bff6 100644
>>>>>>> --- a/arch/arm/boot/dts/bcm2835.dtsi
>>>>>>> +++ b/arch/arm/boot/dts/bcm2835.dtsi
>>>>>>> @@ -8,6 +8,7 @@
>>>>>>>
>>>>>>>       chosen {
>>>>>>>               bootargs = "earlyprintk console=ttyAMA0";
>>>>>>> +             stdout-path = &uart;
>>>>>>>       };
>>>>>>>
>>>>>>>       soc {
>>>>>>> @@ -16,6 +17,7 @@
>>>>>>>               #size-cells = <1>;
>>>>>>>               ranges = <0x7e000000 0x20000000 0x02000000>;
>>>>>>>               dma-ranges = <0x40000000 0x00000000 0x20000000>;
>>>>>>> +             u-boot,dm-pre-reloc;
>>>>>>
>>>>>> Why do you need this and why should upstream carry your favourite
>>>>>> bootloaders configuration? This is in no way hardware description.
>>>>>
>>>>> I'm not sure how much you know about U-Boot, so let me know if you
>>>>> need more info.
>>>>>
>>>>> U-Boot normally starts up by setting up its serial UART and displaying
>>>>> a banner message. At this stage typically only a few devices are
>>>>> initialised (e.g. maybe just the UART). It then relocates itself to
>>>>> the top of memory and starts up all the devices. It throws away any
>>>>> previous devices that it set up before relocation and starts again.
>>>>>
>>>>> U-Boot uses a thing called driver model (dm) which handles driver
>>>>> binding and probing. Driver model has the device tree and would
>>>>> normally scan through it and create devices for everything it finds.
>>>
>>> How do you debug the DM itself? It seems like you still would need
>>> something earlier for debug like earlycon in the kernel. u-boot DM is
>>> probably simple enough you can get away with using it early, but you
>>> often can't as the complexity increases. Ultimately you need something
>>> simple that just hits all the registers needed to get characters out.
>>> What happens when you add pinmux, clocks, PMIC, power domains, etc. to
>>> the DM and they all become dependencies for the UART?
>>
>> This doesn't seem like a device tree binding question but let me try
>> to answer it.
>>
>> This is a problem - one of the challenges of driver model is that the
>> UART gets further away from the reset vector.
>
> This is a common problem for any complex embedded system. Nothing
> special about u-boot here. So either we don't need anything because
> everyone else has dealt with the problem in some way or we need a
> common solution because we all have this problem.

I'm struggling to understand the value of this statement - is it just
philosophizing? I do have a real problem and would like to solve it.
Please make a concrete suggestion.

>
>> In U-Boot there is a single debug UART which can be supported by the
>> various serial drivers (only one can be selected on each platform).
>> There is a special debug_uart_init() function which is supposed to set
>> up the UART for that platform. After that, and until driver model UART
>> is up, console output can go through the debug UART.
>
> So you don't need this for the common case of an early console, but
> only for platforms needing some other platform specific setup?

The debug UART is generally disabled and has very limited use. It is
hard-coded and does not use the device tree. I mentioned it because
you asked "How do you debug the DM itself". You dropped that from the
context so this thread is now quite confusing.

Let's ignore the debug UART.

>
>>>>> Before relocation we don't need every device. Also the CPU is often
>>>>> running slowly, perhaps without the cache enabled. SDRAM may not be
>>>>> available yet so space is short. We want to avoid starting up things
>>>>> that will not be used.
>>>>>
>>>>> So this property indicates that the device is needed before relocation
>>>>> and should be set up by driver model. We need it to avoid a very slow
>>>>> and memory-hungry startup.
>>>
>>> Can't the need for that property change over time? Either as more
>>> drivers are converted to DM you need to add this or you add some
>>> feature that depends on a driver (e.g. get a board rev or boot mode
>>> from GPIO). You would have backwards compatibility issues with this.
>>> I'm somewhat less worried about that for u-boot as we should be
>>> bundling the dtb and bootloader rather than kernel and dtb. For the
>>> UART, you can just get which UART to initialize early from
>>> stdout-path. But for other cases, couldn't you just have the platform
>>> provide the list of needed drivers. Then when u-boot needs change, you
>>> just change u-boot.
>>
>> Yes U-Boot and its device tree are normally built from the same tree
>> at the same time. We don't expect to have to support an older or newer
>> device tree with the same U-Boot binary. So I don't see a problem
>> here.
>
> My point is that if I had to pick how bootloader+dtb+kernel are
> bundled or not, I would rather see the dtb in sync with the bootloader
> rather than the kernel. But I can't decide that for everyone and
> neither can you. You still have a compatibility problem and that has
> to be addressed.

What are you getting at here? If I move to a new kernel and still use
an old device tree I may be missing features, or fail to boot. Don't
do that!

But do we need to talk about this? How does this affect my patch?

>
>> The UART should have as few dependencies as possible. But if the
>> particular platform needs to check a GPIO to find out the UART number
>> (i.e. stdout-path cannot be used) then we would need to support that
>> case. It hasn't come up yet but it might. I certainly see platforms
>> where we need some other nodes before relocation and would like to
>> mark them as such. But I hope that for UART we can generally use
>> stdout-path.
>>
>> The list of drivers doesn't help that much. What would I do with such
>> a list, and where would I keep such platform-specific information
>> other than in the device tree? It seems much simpler to hold the
>> information about what the platform needs to get through early boot in
>> one place. Then we have just a few lines of generic code to deal with
>> it.
>
> If you need certain drivers such as gpio, then you obviously have some
> board specific code using those drivers already. If you can tell the
> DM which devices to enumerate via DT, you can also tell the DM with C
> code.
>
> While doing everything generically without board code is nice, we
> should only do that for the common cases and handle the screwy cases
> with board code.

OK so let's ignore the GPIO example.

After reading your email I am none the wiser about what you are suggesting.

This is not a screwy case. Every board will have a console. In some
cases it is inside a 'soc {' node and in some cases it is not. The
pure solution would be to mark every UART node with
u-boot,dm-pre-reloc and we can do that if you prefer. It isn't
necessary though for the reasons I previously explained.

It seems reasonable that U-Boot should be able to add private
properties to the device tree, intended for U-Boot, just as Linux
does. What is the problem here?

If are you asking for a generic property that any bootloader could
use, to locate what is needed to bring up the serial console then
please propose something and I can take a look. But I know that not
all bootloaders work like U-Boot (small space-constrained SPL,
relocatable main loader, try to output something on a serial port as
early as possible).

How can we resolve this so that the device tree files in U-Boot and
Linux can stay in sync?

Regards,
Simon


From tony at atomide.com  Fri Aug 28 11:44:49 2015
From: tony at atomide.com (Tony Lindgren)
Date: Fri, 28 Aug 2015 11:44:49 -0700
Subject: [PATCH] gpio: omap: Fix gpiochip_add() handling for deferred probe
Message-ID: <1440787489-15992-1-git-send-email-tony@atomide.com>

Currently we gpio-omap breaks if gpiochip_add() returns -EPROBE_DEFER:

[    0.570000] gpiochip_add: GPIOs 0..31 (gpio) failed to register
[    0.570000] omap_gpio 48310000.gpio: Could not register gpio chip -517
...
[    3.670000] omap_gpio 48310000.gpio: Unbalanced pm_runtime_enable!

Let's fix the issue by adding the missing pm_runtime_put() on error.

Cc: Grygorii Strashko <grygorii.strashko at ti.com>
Cc: Javier Martinez Canillas <javier at dowhile0.org>
Cc: Kevin Hilman <khilman at deeprootsystems.com>
Cc: Santosh Shilimkar <ssantosh at kernel.org>
Signed-off-by: Tony Lindgren <tony at atomide.com>
---
 drivers/gpio/gpio-omap.c | 5 ++++-
 1 file changed, 4 insertions(+), 1 deletion(-)

diff --git a/drivers/gpio/gpio-omap.c b/drivers/gpio/gpio-omap.c
index b0c57d5..f09bf0b 100644
--- a/drivers/gpio/gpio-omap.c
+++ b/drivers/gpio/gpio-omap.c
@@ -1232,8 +1232,11 @@ static int omap_gpio_probe(struct platform_device *pdev)
 	omap_gpio_mod_init(bank);
 
 	ret = omap_gpio_chip_init(bank, irqc);
-	if (ret)
+	if (ret) {
+		pm_runtime_put_sync(bank->dev);
+		pm_runtime_disable(bank->dev);
 		return ret;
+	}
 
 	omap_gpio_show_rev(bank);
 
-- 
2.1.4



From tony at atomide.com  Fri Aug 28 12:06:16 2015
From: tony at atomide.com (Tony Lindgren)
Date: Fri, 28 Aug 2015 12:06:16 -0700
Subject: [PATCH] ARM: OMAP2+: Fix booting if no timer parent clock is available
Message-ID: <1440788776-19978-1-git-send-email-tony@atomide.com>

When bringing up a new SoC we needlessly prevent booting at timer
init if timer clock_set_parent fails. This can fail if the system
is booting on bootloader configured PLL values until the clock
framework driver for the PLL is implemented.

Let's just WARN instead, this will provide helpful information
for anybody bringing up a new SoC what needs to be fixed.

Signed-off-by: Tony Lindgren <tony at atomide.com>
---
 arch/arm/mach-omap2/timer.c | 8 ++------
 1 file changed, 2 insertions(+), 6 deletions(-)

diff --git a/arch/arm/mach-omap2/timer.c b/arch/arm/mach-omap2/timer.c
index e4d8701..a556551 100644
--- a/arch/arm/mach-omap2/timer.c
+++ b/arch/arm/mach-omap2/timer.c
@@ -297,12 +297,8 @@ static int __init omap_dm_timer_init_one(struct omap_dm_timer *timer,
 	if (IS_ERR(src))
 		return PTR_ERR(src);
 
-	r = clk_set_parent(timer->fclk, src);
-	if (r < 0) {
-		pr_warn("%s: %s cannot set source\n", __func__, oh->name);
-		clk_put(src);
-		return r;
-	}
+	WARN(clk_set_parent(timer->fclk, src) < 0,
+	     "Cannot set timer parent clock, no PLL clock driver?");
 
 	clk_put(src);
 
-- 
2.1.4



From tglx at linutronix.de  Fri Aug 28 12:11:26 2015
From: tglx at linutronix.de (Thomas Gleixner)
Date: Fri, 28 Aug 2015 21:11:26 +0200 (CEST)
Subject: [PATCH v2 1/1] irqchip: imx-gpcv2: Simplify the implementation
In-Reply-To: <1440617755-2942-1-git-send-email-shenwei.wang@freescale.com>
References: <1440617755-2942-1-git-send-email-shenwei.wang@freescale.com>
Message-ID: <alpine.DEB.2.11.1508282110260.15006@nanos>

On Wed, 26 Aug 2015, Shenwei Wang wrote:
>  u32 imx_gpcv2_get_wakeup_source(u32 **sources)
>  {
> -	if (!imx_gpcv2_instance)
> +	struct gpcv2_irqchip_data *cd;
> +	void __iomem *reg;
> +	int i;
> +
> +	cd = imx_gpcv2_instance;
> +	if (!cd)
>  		return 0;
> 
> +	for (i = 0; i < IMR_NUM; i++) {
> +		reg = cd->gpc_base + cd->cpu2wakeup + i * 4;
> +		cd->wakeup_sources[i] = readl_relaxed(reg);
> +	}
> +
>  	if (sources)
> -		*sources = imx_gpcv2_instance->wakeup_sources;
> +		*sources = cd->wakeup_sources;
> 
>  	return IMR_NUM;
>  }

So once again. As you said before nothing is going to use the case
where source == NULL, can we please get rid of it?

Thanks,

	tglx


From tony at atomide.com  Fri Aug 28 12:19:42 2015
From: tony at atomide.com (Tony Lindgren)
Date: Fri, 28 Aug 2015 12:19:42 -0700
Subject: [PATCH] ARM: omap2plus_defconfig: Enable MUSB DMA support
Message-ID: <1440789582-25392-1-git-send-email-tony@atomide.com>

With recent MUSB changes we can now build in support for multiple
DMA implementations. So let's enable DMA by default to make life
easier for distro use.

Cc: Felipe Balbi <balbi at ti.com>
Signed-off-by: Tony Lindgren <tony at atomide.com>
---
 arch/arm/configs/omap2plus_defconfig | 2 ++
 1 file changed, 2 insertions(+)

diff --git a/arch/arm/configs/omap2plus_defconfig b/arch/arm/configs/omap2plus_defconfig
index 789fa5a8..1d5f80f 100644
--- a/arch/arm/configs/omap2plus_defconfig
+++ b/arch/arm/configs/omap2plus_defconfig
@@ -350,6 +350,8 @@ CONFIG_USB_MUSB_HDRC=m
 CONFIG_USB_MUSB_OMAP2PLUS=m
 CONFIG_USB_MUSB_AM35X=m
 CONFIG_USB_MUSB_DSPS=m
+CONFIG_USB_INVENTRA_DMA=y
+CONFIG_USB_TI_CPPI41_DMA=y
 CONFIG_USB_DWC3=m
 CONFIG_USB_TEST=m
 CONFIG_AM335X_PHY_USB=y
-- 
2.1.4



From sboyd at codeaurora.org  Fri Aug 28 12:21:42 2015
From: sboyd at codeaurora.org (Stephen Boyd)
Date: Fri, 28 Aug 2015 12:21:42 -0700
Subject: [PATCH] spmi: pmic-arb: Don't byte swap when reading/writing FIFO
Message-ID: <1440789702-1648-1-git-send-email-sboyd@codeaurora.org>

We don't want to swap bytes that we're reading and writing to the
FIFOs when we're running on a big-endian CPU. Doing so causes
problems like where the qcom-spmi-iadc driver can't detect the
type of device because the bytes are all mixed up. Use the raw IO
accessors for these API instead, and collapse pmic_arb_base_read()
into the byte reading API so that we aren't tempted to read non-FIFO
data like commands with that function.

Cc: Andy Gross <agross at codeaurora.org>
Cc: Bjorn Andersson <bjorn.andersson at sonymobile.com>
Signed-off-by: Stephen Boyd <sboyd at codeaurora.org>
---
 drivers/spmi/spmi-pmic-arb.c | 9 ++-------
 1 file changed, 2 insertions(+), 7 deletions(-)

diff --git a/drivers/spmi/spmi-pmic-arb.c b/drivers/spmi/spmi-pmic-arb.c
index bdfb3c84c3cb..5e834bd23c09 100644
--- a/drivers/spmi/spmi-pmic-arb.c
+++ b/drivers/spmi/spmi-pmic-arb.c
@@ -168,11 +168,6 @@ struct pmic_arb_ver_ops {
 	u32 (*irq_clear)(u8 n);
 };
 
-static inline u32 pmic_arb_base_read(struct spmi_pmic_arb_dev *dev, u32 offset)
-{
-	return readl_relaxed(dev->rd_base + offset);
-}
-
 static inline void pmic_arb_base_write(struct spmi_pmic_arb_dev *dev,
 				       u32 offset, u32 val)
 {
@@ -193,7 +188,7 @@ static inline void pmic_arb_set_rd_cmd(struct spmi_pmic_arb_dev *dev,
  */
 static void pa_read_data(struct spmi_pmic_arb_dev *dev, u8 *buf, u32 reg, u8 bc)
 {
-	u32 data = pmic_arb_base_read(dev, reg);
+	u32 data = __raw_readl(dev->rd_base + reg);
 	memcpy(buf, &data, (bc & 3) + 1);
 }
 
@@ -208,7 +203,7 @@ pa_write_data(struct spmi_pmic_arb_dev *dev, const u8 *buf, u32 reg, u8 bc)
 {
 	u32 data = 0;
 	memcpy(&data, buf, (bc & 3) + 1);
-	pmic_arb_base_write(dev, reg, data);
+	__raw_writel(data, dev->wr_base + reg);
 }
 
 static int pmic_arb_wait_for_done(struct spmi_controller *ctrl,
-- 
The Qualcomm Innovation Center, Inc. is a member of the Code Aurora Forum,
a Linux Foundation Collaborative Project



From Shenwei.Wang at freescale.com  Fri Aug 28 12:23:18 2015
From: Shenwei.Wang at freescale.com (Shenwei Wang)
Date: Fri, 28 Aug 2015 19:23:18 +0000
Subject: [PATCH v2 1/1] irqchip: imx-gpcv2: Simplify the implementation
In-Reply-To: <alpine.DEB.2.11.1508282110260.15006@nanos>
References: <1440617755-2942-1-git-send-email-shenwei.wang@freescale.com>
 <alpine.DEB.2.11.1508282110260.15006@nanos>
Message-ID: <CY1PR0301MB08439B2D50D3A2C0EC80D579836E0@CY1PR0301MB0843.namprd03.prod.outlook.com>



> -----Original Message-----
> From: Thomas Gleixner [mailto:tglx at linutronix.de]
> Sent: 2015?8?28? 14:11
> To: Wang Shenwei-B38339
> Cc: shawn.guo at linaro.org; jason at lakedaemon.net; sudeep.holla at arm.com;
> linux-arm-kernel at lists.infradead.org; linux-kernel at vger.kernel.org; Huang
> Yongcai-B20788
> Subject: Re: [PATCH v2 1/1] irqchip: imx-gpcv2: Simplify the implementation
> 
> On Wed, 26 Aug 2015, Shenwei Wang wrote:
> >  u32 imx_gpcv2_get_wakeup_source(u32 **sources)  {
> > -	if (!imx_gpcv2_instance)
> > +	struct gpcv2_irqchip_data *cd;
> > +	void __iomem *reg;
> > +	int i;
> > +
> > +	cd = imx_gpcv2_instance;
> > +	if (!cd)
> >  		return 0;
> >
> > +	for (i = 0; i < IMR_NUM; i++) {
> > +		reg = cd->gpc_base + cd->cpu2wakeup + i * 4;
> > +		cd->wakeup_sources[i] = readl_relaxed(reg);
> > +	}
> > +
> >  	if (sources)
> > -		*sources = imx_gpcv2_instance->wakeup_sources;
> > +		*sources = cd->wakeup_sources;
> >
> >  	return IMR_NUM;
> >  }
> 
> So once again. As you said before nothing is going to use the case where source
> == NULL, can we please get rid of it?

It will be used to allocate the memory for the predefined values of interrupts for each power
Domain. Can we keep it?

Thanks,
Shenwei

> Thanks,
> 
> 	tglx

From sboyd at codeaurora.org  Fri Aug 28 12:31:10 2015
From: sboyd at codeaurora.org (Stephen Boyd)
Date: Fri, 28 Aug 2015 12:31:10 -0700
Subject: [PATCH] spmi: pmic-arb: u8 <= 0xff is always true
Message-ID: <1440790270-14859-1-git-send-email-sboyd@codeaurora.org>

Silences this static checker warning:

 drivers/spmi/spmi-pmic-arb.c:363
 pmic_arb_write_cmd() warn: always true condition
 '(opc <= 255) => (0-255 <= 255)'

Cc: Andy Gross <agross at codeaurora.org>
Cc: Bjorn Andersson <bjorn.andersson at sonymobile.com>
Signed-off-by: Stephen Boyd <sboyd at codeaurora.org>
---
 drivers/spmi/spmi-pmic-arb.c | 2 +-
 1 file changed, 1 insertion(+), 1 deletion(-)

diff --git a/drivers/spmi/spmi-pmic-arb.c b/drivers/spmi/spmi-pmic-arb.c
index 5e834bd23c09..c7aa6f1a898e 100644
--- a/drivers/spmi/spmi-pmic-arb.c
+++ b/drivers/spmi/spmi-pmic-arb.c
@@ -360,7 +360,7 @@ static int pmic_arb_write_cmd(struct spmi_controller *ctrl, u8 opc, u8 sid,
 		opc = PMIC_ARB_OP_EXT_WRITE;
 	else if (opc >= 0x30 && opc <= 0x37)
 		opc = PMIC_ARB_OP_EXT_WRITEL;
-	else if (opc >= 0x80 && opc <= 0xFF)
+	else if (opc >= 0x80)
 		opc = PMIC_ARB_OP_ZERO_WRITE;
 	else
 		return -EINVAL;
-- 
The Qualcomm Innovation Center, Inc. is a member of the Code Aurora Forum,
a Linux Foundation Collaborative Project



From tglx at linutronix.de  Fri Aug 28 12:42:26 2015
From: tglx at linutronix.de (Thomas Gleixner)
Date: Fri, 28 Aug 2015 21:42:26 +0200 (CEST)
Subject: CONFIG_DEBUG_SHIRQ and PM
In-Reply-To: <20150825195830.GH27534@saruman.tx.rr.com>
References: <20150825195830.GH27534@saruman.tx.rr.com>
Message-ID: <alpine.DEB.2.11.1508282122480.15006@nanos>

On Tue, 25 Aug 2015, Felipe Balbi wrote:
> Hi Ingo,

Thanks for not cc'ing the irq maintainer ....
 
> I'm facing an issue with CONFIG_DEBUG_SHIRQ and pm_runtime when using
> devm_request_*irq().
> 
> If we using devm_request_*irq(), that irq will be freed after device
> drivers' ->remove() gets called. If on ->remove(), we're calling
> pm_runtime_put_sync(); pm_runtime_disable(), device's clocks might get
> gated and, because we do an extra call to the device's IRQ handler when
> CONFIG_DEBUG_SHIRQ=y, we might trigger an abort exception if, inside the
> IRQ handler, we try to read a register which is clocked by the device's
> clock.
> 
> This is, of course, really old code which has been in tree for many,
> many years. I guess nobody has been running their tests in the setup
> mentioned above (CONFIG_DEBUG_SHIRQ=y, pm_runtime_put_sync() on
> ->remove(), a register read on IRQ handler, and a shared IRQ handler),
> so that's why we never caught this before.
> 
> Disabling CONFIG_DEBUG_SHIRQ, of course, makes the problem go away, but
> if driver *must* be ready to receive, and handle, an IRQ even during
> module removal, I wonder what the IRQ handler should do. We can't, in
> most cases, call pm_runtime_put_sync() from IRQ handler.

Well, a shared interrupt handler must handle this situation, no matter
what. Assume the following:

irqreturn_t dev_irq(int irq, void *data)
{
	struct devdata *dd = data;
	u32 state;

	state = readl(dd->base);
	...
}

void module_exit(void)
{	
	/* Write to the device interrupt register */
	disable_device_irq(dd->base);
	/*
	 * After this point the device does not longer
	 * raise an interrupt
	 */
	iounmap(dd->base);
	free_irq();

If the other device which shares the interrupt line raises an
interrupt after the unmap and before free_irq() removed the device
handler from the irq, the machine is toast, because the dev_irq
handler is still called.

If the handler is shut down after critical parts of the driver/device
are shut down, then you can 

 - either can change the setup/teardown ordering

	disable_device_irq(dd->base);
	free_irq();
	iounmap(dd->base);

 - or have a proper flag in the private data which tells the interrupt
   handler to sod off.

irqreturn_t dev_irq(int irq, void *data)
{
	struct devdata *dd = data;

	if (dd->shutdown)
		return IRQ_NONE;
	...

void module_exit(void)
{	
	disable_device_irq(dd->base);
	dd->shutdown = 1;

	/* On an SMP machine you also need: */	
	synchronize_irq(dd->irq);

So for the problem at hand, the devm magic needs to make sure that the
crucial parts are still alive when the devm allocated irq is released.

I have no idea how that runtime PM stuff is integrated into devm (I
fear not at all), so it's hard to give you a proper advise on that.

Thanks,

	tglx


From tglx at linutronix.de  Fri Aug 28 12:44:19 2015
From: tglx at linutronix.de (Thomas Gleixner)
Date: Fri, 28 Aug 2015 21:44:19 +0200 (CEST)
Subject: [PATCH v2 1/1] irqchip: imx-gpcv2: Simplify the implementation
In-Reply-To: <CY1PR0301MB08439B2D50D3A2C0EC80D579836E0@CY1PR0301MB0843.namprd03.prod.outlook.com>
References: <1440617755-2942-1-git-send-email-shenwei.wang@freescale.com>
 <alpine.DEB.2.11.1508282110260.15006@nanos>
 <CY1PR0301MB08439B2D50D3A2C0EC80D579836E0@CY1PR0301MB0843.namprd03.prod.outlook.com>
Message-ID: <alpine.DEB.2.11.1508282143310.15006@nanos>

On Fri, 28 Aug 2015, Shenwei Wang wrote:
> > So once again. As you said before nothing is going to use the case where source
> > == NULL, can we please get rid of it?
> 
> It will be used to allocate the memory for the predefined values of
> interrupts for each power Domain. Can we keep it?

If there is a user depending on it, yes. Seems I misread your answer
on that.

Thanks,

	tglx


From dhdang at apm.com  Fri Aug 28 13:00:03 2015
From: dhdang at apm.com (Duc Dang)
Date: Fri, 28 Aug 2015 13:00:03 -0700
Subject: [PATCH 0/2 RESEND] power: reset: Add syscon reboot/poweroff
 device nodes for APM X-Gene platform
In-Reply-To: <20150726183742.GA24272@localhost>
References: <1433272747-27114-1-git-send-email-ttnguyen@apm.com>
 <20150714084004.GA14593@localhost>
 <CAPw-ZT=d2=dh-Hjugo9BStCuhTp82MMapUa1EGrD01EoTOG-nA@mail.gmail.com>
 <CAOesGMhKRxUtr6XXsZgCJVUFTFL3eHySP8y-SmEzi=R53MxLRw@mail.gmail.com>
 <CAPw-ZTnk8cZyFyMnBMUYXuxs9=2ydqxOzm+dYsg-=9_Suq+q7A@mail.gmail.com>
 <CAOesGMimzcUDW4e1etxZNerEusWmEtT_um8XZoT0MkFpCnTf5w@mail.gmail.com>
 <CADaLNDmPqb73UrOaVphkywZh8mfd4sPdA6i25USLt53sZ3hFuw@mail.gmail.com>
 <20150726183742.GA24272@localhost>
Message-ID: <CADaLNDk5FT8ENQfiMQ+++NGg3VhuiTpnQtGW0L5DMYAuDKZ27g@mail.gmail.com>

On Sun, Jul 26, 2015 at 11:37 AM, Olof Johansson <olof at lixom.net> wrote:
>
> On Sat, Jul 25, 2015 at 11:34:42AM -0700, Duc Dang wrote:
> > Hi Olof,
> >
> > We are debating whether we should setup a company server (where we can
> > have full control about storage, user permissions, backup, ...) or
> > just use github.com to host our X-Gene kernel tree.
> >
> > Github seems already provide everything we need for a public source
> > tree. Per your experience, what is your (and probably other
> > maintainers) reference in git hosting server? Is there any
> > inconvenience or difficulty for the maintainers to pull/merge code
> > from Github versus from a company server?
>
> Hosting on github is fine with us in general. We do prefer to get
> signed pull requests in particular when they come from other sources
> than kernel.org, mostly because there's another third party involved in
> hosting the repo and by using signed tags there's less room for anyone
> to do bad stuff with the repository without someone noticing.
>
> If you host on github, please still use native git pull requests and not the
> ones that github provides via the web interface.
>
> Note however, that given the total volume of patches there's no strong need for
> you to have a public repo just to send code to us -- we're happy applying
> patches at the volumes we're currently looking at. I can imagine other reasons
> for why you would like to have a public repo though.

Hi Olof,

I have APM X-Gene git ready on github. According to your response
above, I need to
send a signed pull request. I created a PGP key on public server
(https://pgp.mit.edu/pks/lookup?search=duc+dang&op=index) and signed the tag on
APM X-Gene tree with my key.

Please let me know if I need anything else before sending the git pull
request to you.
My key is not signed by any maintainer yet, would you mind to arrange some
time next week to meet and help sign my key as well?

>
>
> Thanks,
>
> -Olof

-- 
Thanks and regards,
Duc Dang.


From michael at dinsnail.net  Fri Aug 28 12:02:25 2015
From: michael at dinsnail.net (Michael Weiser)
Date: Fri, 28 Aug 2015 21:02:25 +0200
Subject: no booting due to handle_domain_irq on orion5x/kurobox
In-Reply-To: <87vbbz75vf.fsf@free-electrons.com>
References: <20150828155826.GD2776@dinsnail.net>
 <87vbbz75vf.fsf@free-electrons.com>
Message-ID: <20150828190225.GA26848@weiser.dinsnail.net>

Hi Gregory,

On Fri, Aug 28, 2015 at 06:08:36PM +0200, Gregory CLEMENT wrote:
> The good new is that a fix have already been submitted, the bad news is
> that it won't be in 4.2, but it will be in 4.3-rc1 and as it was tagged
> as stable it would be part of the older stable kernel in the next weeks.
> You can cherry-pick it from linux-next:

> http://git.kernel.org/cgit/linux/kernel/git/next/linux-next.git/commit/?id=5be9fc23cdb42e1d383ecc8eae8a8ff70a752708

Awesome, thanks!
-- 
Micha


From mturquette at linaro.org  Fri Aug 28 13:02:38 2015
From: mturquette at linaro.org (Michael Turquette)
Date: Fri, 28 Aug 2015 13:02:38 -0700
Subject: [RESEND PATCH v16 4/4] ARM: dts: add the support power-domain
 node on RK3288 SoCs
In-Reply-To: <CAD=FV=VTR-PBcXXX1jHNw65x_cMP9CKwVWBs+XCcFqFPp7msjA@mail.gmail.com>
References: <1440487486-6154-1-git-send-email-wxt@rock-chips.com>
 <1440487486-6154-5-git-send-email-wxt@rock-chips.com>
 <7hfv37axhj.fsf@deeprootsystems.com>
 <CAD=FV=V6oG+9U=W_JZmqCuNo-9-5wW8ffZzG7ZE_3cnSTNAjFQ@mail.gmail.com>
 <7htwrn6l7g.fsf@deeprootsystems.com>
 <CAKdAkRS=9Dq+YpMNSjpij0Am4ZD6uUURv74OLLYf+akD=W885A@mail.gmail.com>
 <7hmvxc45w2.fsf@deeprootsystems.com>
 <CAD=FV=VTR-PBcXXX1jHNw65x_cMP9CKwVWBs+XCcFqFPp7msjA@mail.gmail.com>
Message-ID: <20150828200238.30921.24441@quantum>

Hi Doug,

Quoting Doug Anderson (2015-08-27 19:03:20)
> Kevin,
> 
> On Thu, Aug 27, 2015 at 5:24 PM, Kevin Hilman <khilman at kernel.org> wrote:
> >> That is not really workable: the attach and detach happen in
> >> probe/remove path; if you do not have driver for the device you will
> >> miss the clocks for it.
> >
> > And in my proposal, I suggested that clocks without drivers are
> > good candidates to list in the domain, with the caveat that the be
> > called out (documented) as being device clocks that are missing a
> > driver, so when a driver shows up they can be moved accordingly, and in
> > a way that actually describes the hardware.
> 
> What happens if someone disables the driver using the CONFIG subsystem?

Kevin asked me to chime in on this thread, as I have a half-baked idea
that might solve the problem posed by your question above.

One thing I have been considering for a while is a fallback compatible
string that can be used for an IP block when either there is no driver
loaded or no driver exists at all. Something like "generic-ip-block".

The purpose of this compatible string is to allow us to model resource
consumption in dts accurately, regardless of whether or not a proper
driver has been written in Linux. This idea was born out of the
simple-fb binding/driver discussion last year[0].

Obviously such a binding would not enable any of the logic or function
of that IP block; that would require a proper driver. But it would allow
us to properly link system-wide resources that are consumed: the
generic-ip could consume clocks and regulators, it could belong to power
domains, etc. For this reason I have also thought that
"generic-resource-consumer" is an accurate compatible string.

This spares us from having to encode nasty details into the power domain
binding, which is exactly what would happen if you needed a dedicated
list of clocks in the power domain node that were not claimed by device
nodes/drivers.

Note that a real driver might exist for an IP block, but if that driver
is disabled in Kconfig AND the corresponding dt node has this fallback
compatible string, then we could be OK, from the perspective of the
power domain problem.

> 
> What happens if this is a device that someone has set to 'status =
> "disabled";' in the device tree?

If someone does that, then I think we should let that break power domain
transitions.

> 
> Even if the device is disabled in one of those two ways, we still need
> the clocks to be turned on.  ...so if we turn on/off the VIO domain we
> need to turn on the EDP clock even if there's no EDP in the current
> board / config.  We might turn on/off VIO for one of the other devices
> in the VIO domain for one of the other devices in VIO that we are
> using.

I'm hesitant to mention this but I am working on a patch series to
implement a clock "handoff" mechanism (also inspired by the simplefb
discussion). This allows us to set a per-clock flag that tells the
framework to enable that clock at registration time, and then the first
clock consumer driver to come along and claim that clock inherits that
clock enable reference count.

I'm working on v2 that lets us set this flag from DT, but I really only
plan to do this for special cases. For the normal case the flag should
be set in the Linux clock provider driver. In the mean time v1 is under
discussion[1].

[0] http://lkml.kernel.org/r/<1407914239-12054-5-git-send-email-libv at skynet.be>
[1] http://lkml.kernel.org/r/<1438974570-20812-1-git-send-email-mturquette at baylibre.com>

Regards,
Mike

> 
> -Doug
> --
> To unsubscribe from this list: send the line "unsubscribe linux-kernel" in
> the body of a message to majordomo at vger.kernel.org
> More majordomo info at  http://vger.kernel.org/majordomo-info.html
> Please read the FAQ at  http://www.tux.org/lkml/


From olof at lixom.net  Fri Aug 28 13:06:34 2015
From: olof at lixom.net (Olof Johansson)
Date: Fri, 28 Aug 2015 13:06:34 -0700
Subject: [PATCH 0/2 RESEND] power: reset: Add syscon reboot/poweroff
 device nodes for APM X-Gene platform
In-Reply-To: <CADaLNDk5FT8ENQfiMQ+++NGg3VhuiTpnQtGW0L5DMYAuDKZ27g@mail.gmail.com>
References: <1433272747-27114-1-git-send-email-ttnguyen@apm.com>
 <20150714084004.GA14593@localhost>
 <CAPw-ZT=d2=dh-Hjugo9BStCuhTp82MMapUa1EGrD01EoTOG-nA@mail.gmail.com>
 <CAOesGMhKRxUtr6XXsZgCJVUFTFL3eHySP8y-SmEzi=R53MxLRw@mail.gmail.com>
 <CAPw-ZTnk8cZyFyMnBMUYXuxs9=2ydqxOzm+dYsg-=9_Suq+q7A@mail.gmail.com>
 <CAOesGMimzcUDW4e1etxZNerEusWmEtT_um8XZoT0MkFpCnTf5w@mail.gmail.com>
 <CADaLNDmPqb73UrOaVphkywZh8mfd4sPdA6i25USLt53sZ3hFuw@mail.gmail.com>
 <20150726183742.GA24272@localhost>
 <CADaLNDk5FT8ENQfiMQ+++NGg3VhuiTpnQtGW0L5DMYAuDKZ27g@mail.gmail.com>
Message-ID: <CAOesGMj7E6ux3v5_RhdCGJFVCJoA_GP0hifZCvFMYMv6x7Pu+g@mail.gmail.com>

Hi,

On Fri, Aug 28, 2015 at 1:00 PM, Duc Dang <dhdang at apm.com> wrote:
> On Sun, Jul 26, 2015 at 11:37 AM, Olof Johansson <olof at lixom.net> wrote:
>>
>> On Sat, Jul 25, 2015 at 11:34:42AM -0700, Duc Dang wrote:
>> > Hi Olof,
>> >
>> > We are debating whether we should setup a company server (where we can
>> > have full control about storage, user permissions, backup, ...) or
>> > just use github.com to host our X-Gene kernel tree.
>> >
>> > Github seems already provide everything we need for a public source
>> > tree. Per your experience, what is your (and probably other
>> > maintainers) reference in git hosting server? Is there any
>> > inconvenience or difficulty for the maintainers to pull/merge code
>> > from Github versus from a company server?
>>
>> Hosting on github is fine with us in general. We do prefer to get
>> signed pull requests in particular when they come from other sources
>> than kernel.org, mostly because there's another third party involved in
>> hosting the repo and by using signed tags there's less room for anyone
>> to do bad stuff with the repository without someone noticing.
>>
>> If you host on github, please still use native git pull requests and not the
>> ones that github provides via the web interface.
>>
>> Note however, that given the total volume of patches there's no strong need for
>> you to have a public repo just to send code to us -- we're happy applying
>> patches at the volumes we're currently looking at. I can imagine other reasons
>> for why you would like to have a public repo though.
>
> Hi Olof,
>
> I have APM X-Gene git ready on github. According to your response
> above, I need to
> send a signed pull request. I created a PGP key on public server
> (https://pgp.mit.edu/pks/lookup?search=duc+dang&op=index) and signed the tag on
> APM X-Gene tree with my key.
>
> Please let me know if I need anything else before sending the git pull
> request to you.
> My key is not signed by any maintainer yet, would you mind to arrange some
> time next week to meet and help sign my key as well?

Yeah, I can do that, and you can get more signatures at Linaro Connect
in case you're attending.

(let's sort out details off-list).


-Olof


From agross at codeaurora.org  Fri Aug 28 13:18:28 2015
From: agross at codeaurora.org (Andy Gross)
Date: Fri, 28 Aug 2015 15:18:28 -0500
Subject: [GIT PULL] qcom SoC changes for 4.3-rc2 Part 2
Message-ID: <1440793108-10849-1-git-send-email-agross@codeaurora.org>

The following changes since commit 3427446d72e21f6992534a3b68055f1b4c722546:

  soc: qcom: smd: Use correct remote processor ID (2015-08-27 12:15:58 -0500)

are available in the git repository at:

  git://codeaurora.org/quic/kernel/agross-msm.git tags/qcom-soc-for-4.3-rc2-1

for you to fetch changes up to 8208b90daca1a685eb19e90bbef23af00449f46c:

  soc: qcom: smd: Correct fBLOCKREADINTR handling (2015-08-28 14:54:08 -0500)

----------------------------------------------------------------
Qualcomm ARM Based SoC Updates for 4.3-rc2-1

* Correct SMD fBLOCKREADINTR handling

----------------------------------------------------------------
Bjorn Andersson (1):
      soc: qcom: smd: Correct fBLOCKREADINTR handling

 drivers/soc/qcom/smd.c |    6 +++---
 1 file changed, 3 insertions(+), 3 deletions(-)


From marcel.ziswiler at toradex.com  Fri Aug 28 13:30:35 2015
From: marcel.ziswiler at toradex.com (Marcel Ziswiler)
Date: Fri, 28 Aug 2015 20:30:35 +0000
Subject: [PATCH] arm: tegra: update default configuration
In-Reply-To: <20150828165132.GQ12027@sirena.org.uk>
References: <986a8cee-f090-4888-91f2-7b564c4b3d1d@email.android.com>
 <20150828165132.GQ12027@sirena.org.uk>
Message-ID: <1440793833.2795.57.camel@toradex.com>

On Fri, 2015-08-28 at 16:51 +0000, Mark Brown wrote:

> Please fix your mailer to word wrap within paragraphs so that your
> mails
> are legible.

Sure, sorry. At times I forget that Android isn't sane in that respect
and can't be used to send mailing list compliant emails.

> > On 27 Aug 2015 16:55, Mark Brown <broonie at kernel.org> wrote:
> 
> > > Does the system really have the wm9712 wired up as a battery
> > > monitor?
> 
> > Well, remember we are talking about a system on module. Those
> > WM9712
> > pins all go to the 200 pin SODIMM edge connector and I know that
> > certain customers indeed have carrier boards that use it that way.
> > If
> > there is any opposition and considering this being rather optional
> > I
> > may also drop this one but audio/touch is definitely a standard
> > feature available on all or carrier boards.
> 
> Does that actually work with mainline?  The driver requires platform
> data to do anything useful (there's no DT bindings for it) and I
> can't
> see anything providing that on Tegra systems.

To be honest I have not really tried it resp. I did actually notice it
bailing out but haven't had time to look closer into it yet. We are
using it with NVIDIA's still platform data based downstream L4T R16.5
and I do know that it works there so I just kind of assumed there will
be a way to make it work in mainline as well. However rather than
adding such platform data I guess migrating it to DT would make more
sense. But until such a migration has been completed I guess we rather
just drop enabling it for now and I will send out a v2 in that respect.

From maxime.ripard at free-electrons.com  Fri Aug 28 13:43:51 2015
From: maxime.ripard at free-electrons.com (Maxime Ripard)
Date: Fri, 28 Aug 2015 22:43:51 +0200
Subject: [PATCH 2/6] ARM: dts: sunxi: Add dtsi for AXP221 PMIC
In-Reply-To: <CAGb2v66nBh+_P=EDxrNYeFoUUXqPWuZyfq1OEQww_aSMhT8wVQ@mail.gmail.com>
References: <1440755679-8266-1-git-send-email-wens@csie.org>
 <1440755679-8266-3-git-send-email-wens@csie.org>
 <20150828123159.GJ29389@lukather>
 <CAGb2v66nBh+_P=EDxrNYeFoUUXqPWuZyfq1OEQww_aSMhT8wVQ@mail.gmail.com>
Message-ID: <20150828204351.GS29389@lukather>

On Sat, Aug 29, 2015 at 12:09:55AM +0800, Chen-Yu Tsai wrote:
> >> +/*
> >> + * AXP221/221s/223 Integrated Power Management Chip
> >> + * http://www.x-powers.com/product/AXP22X.php
> >> + * http://dl.linux-sunxi.org/AXP/AXP221%20Datasheet%20V1.2%2020130326%20.pdf
> >> + */
> >
> > I'm usually not really fond of URLs in the source code and/or the
> > commit logs. They tend to be broken very easily.
> 
> OK. Would you rather I put them in Documentation/arm/sunxi/README?
> It's not immediately clear that sunxi and axp* are connected though.

It's one of the first things that pop up when googling, and it's not
really related to sunxi, so I'd say simply leave them out.

> >> +
> >> +&axp221 {
> >> +     compatible = "x-powers,axp221";
> >> +     interrupt-controller;
> >> +     #interrupt-cells = <1>;
> >> +
> >> +     regulators {
> >> +             /* Default work frequency for buck regulators */
> >> +             x-powers,dcdc-freq = <3000>;
> >> +
> >> +             /* supplies for dc1sw & dc5ldo are connected internally */
> >> +             dcdc1-supply = <&reg_dcdc1>;
> >> +             dcdc5-supply = <&reg_dcdc5>;
> >
> > so the parent regulator of DCDC1 is DCDC1 ?
> 
> These probably aren't the best names. These are the supplies for DC1SW and
> DC5LDO, respectively. They are connected internally, so there aren't named
> pins for them. The comment above explains it, though probably not clearly
> enough. Furthermore, the input pins for DCDC1/5 are VIN1/5.

I'm not quite sure I understand. They're connected internally but they
have pins ?

Maxime

-- 
Maxime Ripard, Free Electrons
Embedded Linux, Kernel and Android engineering
http://free-electrons.com
-------------- next part --------------
A non-text attachment was scrubbed...
Name: signature.asc
Type: application/pgp-signature
Size: 819 bytes
Desc: Digital signature
URL: <http://lists.infradead.org/pipermail/linux-arm-kernel/attachments/20150828/165096b7/attachment.sig>

From maxime.ripard at free-electrons.com  Fri Aug 28 13:44:35 2015
From: maxime.ripard at free-electrons.com (Maxime Ripard)
Date: Fri, 28 Aug 2015 22:44:35 +0200
Subject: [PATCH 3/6] ARM: dts: sun6i: hummingbird: Use axp221.dtsi for
 axp221 regulators
In-Reply-To: <CAGb2v67wEXNTDYrPm9Hf2P59+B4nGHAR8kTPCuLVuS+TLHxMRQ@mail.gmail.com>
References: <1440755679-8266-1-git-send-email-wens@csie.org>
 <1440755679-8266-4-git-send-email-wens@csie.org>
 <20150828123244.GK29389@lukather>
 <CAGb2v67wEXNTDYrPm9Hf2P59+B4nGHAR8kTPCuLVuS+TLHxMRQ@mail.gmail.com>
Message-ID: <20150828204435.GT29389@lukather>

On Sat, Aug 29, 2015 at 12:47:00AM +0800, Chen-Yu Tsai wrote:
> >> +&reg_dcdc3 {
> >> +     regulator-always-on;
> >> +     regulator-min-microvolt = <700000>;
> >> +     regulator-max-microvolt = <1320000>;
> >> +     regulator-name = "vdd-gpu";
> >> +};
> >
> > I'm know it's just a mechanical change from your part, but is the GPU
> > regulator really need to be always on?
> 
> I don't think so. It shouldn't affect anything else, though I can't
> think of a way to thoroughly test it. Maybe I just disable it for.
> If anyone complains later on when adding new peripherals they can
> turn it back on.

Sounds good. That also applies to your other patches though.

Maxime

-- 
Maxime Ripard, Free Electrons
Embedded Linux, Kernel and Android engineering
http://free-electrons.com
-------------- next part --------------
A non-text attachment was scrubbed...
Name: signature.asc
Type: application/pgp-signature
Size: 819 bytes
Desc: Digital signature
URL: <http://lists.infradead.org/pipermail/linux-arm-kernel/attachments/20150828/91bb260f/attachment.sig>

From balbi at ti.com  Fri Aug 28 13:12:28 2015
From: balbi at ti.com (Felipe Balbi)
Date: Fri, 28 Aug 2015 15:12:28 -0500
Subject: [PATCH] ARM: omap2plus_defconfig: Enable MUSB DMA support
In-Reply-To: <1440789582-25392-1-git-send-email-tony@atomide.com>
References: <1440789582-25392-1-git-send-email-tony@atomide.com>
Message-ID: <20150828201228.GE7334@saruman.tx.rr.com>

On Fri, Aug 28, 2015 at 12:19:42PM -0700, Tony Lindgren wrote:
> With recent MUSB changes we can now build in support for multiple
> DMA implementations. So let's enable DMA by default to make life
> easier for distro use.
> 
> Cc: Felipe Balbi <balbi at ti.com>
> Signed-off-by: Tony Lindgren <tony at atomide.com>

Acked-by: Felipe Balbi <balbi at ti.com>

> ---
>  arch/arm/configs/omap2plus_defconfig | 2 ++
>  1 file changed, 2 insertions(+)
> 
> diff --git a/arch/arm/configs/omap2plus_defconfig b/arch/arm/configs/omap2plus_defconfig
> index 789fa5a8..1d5f80f 100644
> --- a/arch/arm/configs/omap2plus_defconfig
> +++ b/arch/arm/configs/omap2plus_defconfig
> @@ -350,6 +350,8 @@ CONFIG_USB_MUSB_HDRC=m
>  CONFIG_USB_MUSB_OMAP2PLUS=m
>  CONFIG_USB_MUSB_AM35X=m
>  CONFIG_USB_MUSB_DSPS=m
> +CONFIG_USB_INVENTRA_DMA=y
> +CONFIG_USB_TI_CPPI41_DMA=y
>  CONFIG_USB_DWC3=m
>  CONFIG_USB_TEST=m
>  CONFIG_AM335X_PHY_USB=y
> -- 
> 2.1.4
> 

-- 
balbi
-------------- next part --------------
A non-text attachment was scrubbed...
Name: signature.asc
Type: application/pgp-signature
Size: 819 bytes
Desc: Digital signature
URL: <http://lists.infradead.org/pipermail/linux-arm-kernel/attachments/20150828/793f5691/attachment.sig>

From maxime.ripard at free-electrons.com  Fri Aug 28 14:02:08 2015
From: maxime.ripard at free-electrons.com (Maxime Ripard)
Date: Fri, 28 Aug 2015 23:02:08 +0200
Subject: [PATCH 6/6] ARM: dts: sun6i: Add dts file for MSI Primo81 tablet
In-Reply-To: <20150828163144.239e9bd5@i7>
References: <1440755679-8266-1-git-send-email-wens@csie.org>
 <1440755679-8266-7-git-send-email-wens@csie.org>
 <20150828123805.GN29389@lukather> <20150828163144.239e9bd5@i7>
Message-ID: <20150828210208.GU29389@lukather>

Hi,

On Fri, Aug 28, 2015 at 04:31:44PM +0300, Siarhei Siamashka wrote:
> > > external connectors are represented by MicroSD slot, MiniHDMI, MicroUSB
> > > OTG and 3.5mm headphone jack. More details are available at
> > > 
> > >     http://linux-sunxi.org/MSI_Primo81
> > 
> > Again, not a huge fan of the commit logs URL...
> 
> But you are not strongly objecting to it either, right?
> 
> AFAIK many people are in favour of having links to the device pages in
> the linux-sunxi wiki listed somewhere in the commit logs or along with
> the board maintainer contact information (in U-Boot).

[citation needed]

And it's a good thing that we're in Linux then.

> Because these pages contain the most relevant and up to date
> information about the device, various pictures, tips and tricks,
> etc.
> 
> If you are worried about linux-sunxi.org suddenly going down and not
> coming back, there is also webarchive:
> 
>     http://web.archive.org/web/*/http://linux-sunxi.org/MSI_Primo81

If you have to look in web archive to find that page, you can just as
well use google in the first place?

> > This commit log is already fine without it.
> 
> This commit log is a nice example of why having a link to the wiki page
> is a good idea. The errors and omissions in the wiki page can be
> corrected. The old commit logs can't.

Which is exactly why we shouldn't have URLs. Because we can't fix them
when they become irrelevant.

Plus, quoting SubmittingPatches

"
When you submit or resubmit a patch or patch series, include the
complete patch description and justification for it.  Don't just
say that this is version N of the patch (series).  Don't expect the
subsystem maintainer to refer back to earlier patch versions or referenced
URLs to find the patch description and put that into the patch.
I.e., the patch (series) and its description should be self-contained.
"

If the patch description is self-contained, there's no need for a
URL. And I really don't care about the board description being
comprehensive either, so there's nothing to edit.

> > > +&i2c1 {
> > > +	pinctrl-names = "default";
> > > +	pinctrl-0 = <&i2c1_pins_a>;
> > > +	status = "okay";
> > > +
> > > +	ctp at 5d {
> > > +		pinctrl-names = "default";
> > > +		pinctrl-0 = <&gt911_int_primo81>;
> > > +		compatible = "goodix,gt911";
> > > +		reg = <0x5d>;
> > > +		interrupt-parent = <&pio>;
> > > +		interrupts = <0 3 IRQ_TYPE_LEVEL_HIGH>; /* PA3 */
> > > +		/*
> > > +		 * The default 0,0 coordinate is at the corner closest to
> > > +		 * the headphone jack. X goes along the long side, while
> > > +		 * Y goes along the short side.
> > > +		 */
> > 
> > I'm not exactly sure what that comment is supposed to be for...
> 
> It's probably a human readable comment intended to be read by humans.
> 
> Yeah, this information might actually better belong to the wiki page.
> But then again, this brings us to the question whether we should have
> a link to the linux-sunxi wiki page somewhere in the dts.

I guess I'm not a human then, but a DT is definitely not the place I
would look at for such information, and I'm not sure a user that
didn't even build his kernel will either.

However, I'm pretty sure that if it was in a wiki page, any search
engine would return exactly the info I need, far more reliably than if
it was in the kernel source.

Maxime

-- 
Maxime Ripard, Free Electrons
Embedded Linux, Kernel and Android engineering
http://free-electrons.com
-------------- next part --------------
A non-text attachment was scrubbed...
Name: signature.asc
Type: application/pgp-signature
Size: 819 bytes
Desc: Digital signature
URL: <http://lists.infradead.org/pipermail/linux-arm-kernel/attachments/20150828/a72d198b/attachment-0001.sig>

From maxime.ripard at free-electrons.com  Fri Aug 28 14:04:40 2015
From: maxime.ripard at free-electrons.com (Maxime Ripard)
Date: Fri, 28 Aug 2015 23:04:40 +0200
Subject: [PATCH v2] ARM: dts: sun5i: Add dts file for inet98v_rev2 based
 tablets
In-Reply-To: <1440767717-10601-1-git-send-email-hdegoede@redhat.com>
References: <1440767717-10601-1-git-send-email-hdegoede@redhat.com>
Message-ID: <20150828210440.GV29389@lukather>

On Fri, Aug 28, 2015 at 03:15:17PM +0200, Hans de Goede wrote:
> The inet98v_rev2 is a pcb used in generic A13 based tablets. It features
> volume buttons, a power barrel, micro-usb otg, headphone connector and
> a power button.
> 
> Signed-off-by: Hans de Goede <hdegoede at redhat.com>

Queued, thanks!

Maxime

-- 
Maxime Ripard, Free Electrons
Embedded Linux, Kernel and Android engineering
http://free-electrons.com
-------------- next part --------------
A non-text attachment was scrubbed...
Name: signature.asc
Type: application/pgp-signature
Size: 819 bytes
Desc: Digital signature
URL: <http://lists.infradead.org/pipermail/linux-arm-kernel/attachments/20150828/a4567a1a/attachment.sig>

From marcel.ziswiler at toradex.com  Fri Aug 28 14:08:15 2015
From: marcel.ziswiler at toradex.com (Marcel Ziswiler)
Date: Fri, 28 Aug 2015 23:08:15 +0200
Subject: [PATCH v2] arm: tegra: update default configuration
Message-ID: <1440796095-26962-1-git-send-email-marcel.ziswiler@toradex.com>

  * Expose hardware/virtual IRQ mapping via debugfs
  * WM9712 audio/touch controller as found on Colibri T20
  * sysfs interface for GPIOs
  * NFS client support for NFS version 4

Signed-off-by: Marcel Ziswiler <marcel.ziswiler at toradex.com>
---

Changes in v2:
- drop WM9712 battery support as that driver still requires platform
  data rather than a device tree as pointed out by Mark

 arch/arm/configs/tegra_defconfig | 7 +++++++
 1 file changed, 7 insertions(+)

diff --git a/arch/arm/configs/tegra_defconfig b/arch/arm/configs/tegra_defconfig
index 9808581..9114bfe 100644
--- a/arch/arm/configs/tegra_defconfig
+++ b/arch/arm/configs/tegra_defconfig
@@ -1,5 +1,6 @@
 CONFIG_SYSVIPC=y
 CONFIG_FHANDLE=y
+CONFIG_IRQ_DOMAIN_DEBUG=y
 CONFIG_NO_HZ=y
 CONFIG_HIGH_RES_TIMERS=y
 CONFIG_IKCONFIG=y
@@ -121,6 +122,9 @@ CONFIG_KEYBOARD_CROS_EC=y
 CONFIG_MOUSE_PS2_ELANTECH=y
 CONFIG_INPUT_TOUCHSCREEN=y
 CONFIG_TOUCHSCREEN_ATMEL_MXT=y
+CONFIG_TOUCHSCREEN_WM97XX=y
+# CONFIG_TOUCHSCREEN_WM9705 is not set
+# CONFIG_TOUCHSCREEN_WM9713 is not set
 CONFIG_TOUCHSCREEN_STMPE=y
 CONFIG_INPUT_MISC=y
 CONFIG_INPUT_MPU3050=y
@@ -142,6 +146,7 @@ CONFIG_SPI_TEGRA20_SFLASH=y
 CONFIG_SPI_TEGRA20_SLINK=y
 CONFIG_PINCTRL_AS3722=y
 CONFIG_PINCTRL_PALMAS=y
+CONFIG_GPIO_SYSFS=y
 CONFIG_GPIO_PCA953X=y
 CONFIG_GPIO_PCA953X_IRQ=y
 CONFIG_GPIO_PALMAS=y
@@ -208,6 +213,7 @@ CONFIG_SND_SOC_TEGRA=y
 CONFIG_SND_SOC_TEGRA_RT5640=y
 CONFIG_SND_SOC_TEGRA_WM8753=y
 CONFIG_SND_SOC_TEGRA_WM8903=y
+CONFIG_SND_SOC_TEGRA_WM9712=y
 CONFIG_SND_SOC_TEGRA_TRIMSLICE=y
 CONFIG_SND_SOC_TEGRA_ALC5632=y
 CONFIG_SND_SOC_TEGRA_MAX98090=y
@@ -278,6 +284,7 @@ CONFIG_SQUASHFS=y
 CONFIG_SQUASHFS_LZO=y
 CONFIG_SQUASHFS_XZ=y
 CONFIG_NFS_FS=y
+CONFIG_NFS_V4=y
 CONFIG_ROOT_NFS=y
 CONFIG_NLS_CODEPAGE_437=y
 CONFIG_NLS_ISO8859_1=y
-- 
2.4.3



From dianders at chromium.org  Fri Aug 28 14:08:52 2015
From: dianders at chromium.org (Doug Anderson)
Date: Fri, 28 Aug 2015 14:08:52 -0700
Subject: [RESEND PATCH v16 4/4] ARM: dts: add the support power-domain
 node on RK3288 SoCs
In-Reply-To: <20150828200238.30921.24441@quantum>
References: <1440487486-6154-1-git-send-email-wxt@rock-chips.com>
 <1440487486-6154-5-git-send-email-wxt@rock-chips.com>
 <7hfv37axhj.fsf@deeprootsystems.com>
 <CAD=FV=V6oG+9U=W_JZmqCuNo-9-5wW8ffZzG7ZE_3cnSTNAjFQ@mail.gmail.com>
 <7htwrn6l7g.fsf@deeprootsystems.com>
 <CAKdAkRS=9Dq+YpMNSjpij0Am4ZD6uUURv74OLLYf+akD=W885A@mail.gmail.com>
 <7hmvxc45w2.fsf@deeprootsystems.com>
 <CAD=FV=VTR-PBcXXX1jHNw65x_cMP9CKwVWBs+XCcFqFPp7msjA@mail.gmail.com>
 <20150828200238.30921.24441@quantum>
Message-ID: <CAD=FV=UrWauwX143MSZpus=L7N__jL1dU-FwaE8BU7wi=Lu2Qg@mail.gmail.com>

Mike,

On Fri, Aug 28, 2015 at 1:02 PM, Michael Turquette
<mturquette at linaro.org> wrote:
> Hi Doug,
>
> Quoting Doug Anderson (2015-08-27 19:03:20)
>> Kevin,
>>
>> On Thu, Aug 27, 2015 at 5:24 PM, Kevin Hilman <khilman at kernel.org> wrote:
>> >> That is not really workable: the attach and detach happen in
>> >> probe/remove path; if you do not have driver for the device you will
>> >> miss the clocks for it.
>> >
>> > And in my proposal, I suggested that clocks without drivers are
>> > good candidates to list in the domain, with the caveat that the be
>> > called out (documented) as being device clocks that are missing a
>> > driver, so when a driver shows up they can be moved accordingly, and in
>> > a way that actually describes the hardware.
>>
>> What happens if someone disables the driver using the CONFIG subsystem?
>
> Kevin asked me to chime in on this thread, as I have a half-baked idea
> that might solve the problem posed by your question above.
>
> One thing I have been considering for a while is a fallback compatible
> string that can be used for an IP block when either there is no driver
> loaded or no driver exists at all. Something like "generic-ip-block".
>
> The purpose of this compatible string is to allow us to model resource
> consumption in dts accurately, regardless of whether or not a proper
> driver has been written in Linux. This idea was born out of the
> simple-fb binding/driver discussion last year[0].
>
> Obviously such a binding would not enable any of the logic or function
> of that IP block; that would require a proper driver. But it would allow
> us to properly link system-wide resources that are consumed: the
> generic-ip could consume clocks and regulators, it could belong to power
> domains, etc. For this reason I have also thought that
> "generic-resource-consumer" is an accurate compatible string.
>
> This spares us from having to encode nasty details into the power domain
> binding, which is exactly what would happen if you needed a dedicated
> list of clocks in the power domain node that were not claimed by device
> nodes/drivers.
>
> Note that a real driver might exist for an IP block, but if that driver
> is disabled in Kconfig AND the corresponding dt node has this fallback
> compatible string, then we could be OK, from the perspective of the
> power domain problem.

OK, so that could solve the "Kconfig" problem.


>> What happens if this is a device that someone has set to 'status =
>> "disabled";' in the device tree?
>
> If someone does that, then I think we should let that break power domain
> transitions.

So if you're on a board that doesn't use EDP but uses LVDS then their
suspend/resume should be broken?

Specifically, it's my understanding that on this SoC:

1. There's a single "video IO" power domain that contains things like
the video output processor, EDP, LVDS, HDMI, etc.

2. When you turn on/off the power domain it's important to clock all
devices in the domain during the reset.

3. If you don't clock all devices during the reset they get left in a
"wedged" state.

4. If you try to do things like suspend/resume it will query all
devices.  If they've been left in the wedged state then suspend/resume
will be blocked.

...so this problem is still not solved.

>> Even if the device is disabled in one of those two ways, we still need
>> the clocks to be turned on.  ...so if we turn on/off the VIO domain we
>> need to turn on the EDP clock even if there's no EDP in the current
>> board / config.  We might turn on/off VIO for one of the other devices
>> in the VIO domain for one of the other devices in VIO that we are
>> using.
>
> I'm hesitant to mention this but I am working on a patch series to
> implement a clock "handoff" mechanism (also inspired by the simplefb
> discussion). This allows us to set a per-clock flag that tells the
> framework to enable that clock at registration time, and then the first
> clock consumer driver to come along and claim that clock inherits that
> clock enable reference count.
>
> I'm working on v2 that lets us set this flag from DT, but I really only
> plan to do this for special cases. For the normal case the flag should
> be set in the Linux clock provider driver. In the mean time v1 is under
> discussion[1].

In this case if we're using LVDS and HDMI on a system, we don't want
the EDP clock always on (that just wastes power).  We just need to
clock it for the power domain transition.


Note that nothing in the above solves the problem that not all clocks
for a given device need to be turned on during power domain
transitions.  If we're trying to describe hardware perfectly, we'd
really need to add to each device:

clocks = <clk1>, <clk2>, <clk3>, ...
clock-names = "name1", "name2", "name3", ...
clocks-for-power-domain-transition = "name2", "name3";

...since perhaps the clock named "name1" isn't required for power
domain transitions and so shouldn't be turned on.  Note that once
we're going through and adding a special list, it doesn't seem that
different than just adding the list in the power domain node instead
(other than being more complex).


From bpringle at sympatico.ca  Fri Aug 28 14:14:08 2015
From: bpringle at sympatico.ca (Bill Pringlemeir)
Date: Fri, 28 Aug 2015 17:14:08 -0400
Subject: [PATCH v10 2/5] mtd: nand: vf610_nfc: add hardware BCH-ECC support
In-Reply-To: <20150826213448.GU81844@google.com> (Brian Norris's message of
 "Wed, 26 Aug 2015 14:34:48 -0700")
References: <1438594050-4595-1-git-send-email-stefan@agner.ch>
 <1438594050-4595-3-git-send-email-stefan@agner.ch>
 <ff2e2716578a1ae5f0c4b0e0ca8bbdc3@agner.ch>
 <20150825195411.GJ81844@google.com>
 <07a479863eef4c53ab2ef6ef85321680@agner.ch>
 <20150826213448.GU81844@google.com>
Message-ID: <BLU436-SMTP79A4D637801F08C772536AB86E0@phx.gbl>


On 26 Aug 2015, computersforpeace at gmail.com wrote:

> On Wed, Aug 26, 2015 at 10:57:38AM -0700, Stefan Agner wrote:
>> When printing the ECC error count on ECC fail when reading an erased
>> NAND flash, the numbers of bit flips (stuck at zero) seem to widely
>> correlate with the number returned by the controller. While it seems
>> to correlate widely, there are exceptions, as discussed in the
>> thread: http://thread.gmane.org/gmane.linux.ports.arm.kernel/295424

>> Maybe this is an artifact of the ECC algorithm we just
>> can't/shouldn't rely on? I am not sure where this originated, I did
>> not found any indication in the reference manual about what that
>> value contains in the error case.

> Doesn't sound too reliable to me. And I'm not sure even if it was
> reliable, that it would provide much value. We have to a lot of
> re-counting anyway, so we might as well just be using our own
> threshold.  Or maybe I'm missing the point.

>> Bill, do you have an idea why we used that value as threshold in
>> early implementations?

>> Otherwise I also think we should just drop the use of this value.

Yes, using this value is not especially useful if we re-read with ECC
disabled to count the bit flips for erased pages.   I think this is what
Stefan has done in the 11th patch set.

-- 
Married men live  longer than single men, but married  men are much more
willing to die - Dilworth


From bhelgaas at google.com  Fri Aug 28 14:14:44 2015
From: bhelgaas at google.com (Bjorn Helgaas)
Date: Fri, 28 Aug 2015 16:14:44 -0500
Subject: [PATCH] ARM64: PCI: do not enable resources on PROBE_ONLY systems
In-Reply-To: <1438262039-32085-1-git-send-email-lorenzo.pieralisi@arm.com>
References: <1438262039-32085-1-git-send-email-lorenzo.pieralisi@arm.com>
Message-ID: <20150828211444.GA27890@google.com>

Hi Lorenzo,

On Thu, Jul 30, 2015 at 02:13:59PM +0100, Lorenzo Pieralisi wrote:
> On ARM64 PROBE_ONLY PCI systems resources are not currently claimed,
> therefore they can't be enabled since they do not have a valid
> parent pointer; this in turn prevents enabling PCI devices on
> ARM64 PROBE_ONLY systems, causing PCI devices initialization to
> fail.

Where does arm64 claim PCI BAR resources for the non-PROBE_ONLY case?
I know it must be there somewhere, but I don't see it.

> To solve this issue, resources must be claimed when devices are
> added on PROBE_ONLY systems, which ensures that the resource hierarchy
> is validated and the resource tree is sane, but this requires changes
> in the ARM64 resource management that can affect adversely existing
> PCI set-ups (claiming resources on !PROBE_ONLY systems might break
> existing ARM64 PCI platform implementations).
> 
> As a temporary solution in preparation for a proper resources claiming
> implementation in ARM64 core, to enable PCI PROBE_ONLY systems on ARM64,
> this patch adds a pcibios_enable_device() arch implementation that
> simply prevents enabling resources on PROBE_ONLY systems (mirroring ARM
> behaviour).
> 
> This is always a safe thing to do because on PROBE_ONLY systems the
> configuration space set-up can be considered immutable, and it is in
> preparation of proper resource claiming that would finally validate
> the PCI resources tree in the ARM64 arch implementation on PROBE_ONLY
> systems.
> 
> For !PROBE_ONLY systems resources enablement in pcibios_enable_device()
> on ARM64 is implemented as in current PCI core, leaving the behaviour
> unchanged.
> 
> Signed-off-by: Lorenzo Pieralisi <lorenzo.pieralisi at arm.com>
> Cc: Will Deacon <will.deacon at arm.com>
> Cc: Bjorn Helgaas <bhelgaas at google.com>
> Cc: Catalin Marinas <catalin.marinas at arm.com>
> ---
> Bjorn, all,
> 
> as I mention in the commit log, this patch is a temporary solution
> in preparation for proper resources claiming in ARM64, so that
> we can safely enable the PCI generic host controller on ARM64 systems.
> 
> It mirrors ARM implementation and I will work on changing both
> ARM and ARM64 to convert them to proper resources claiming in
> the respective implementations.
> 
> Lorenzo
> 
>  arch/arm64/kernel/pci.c | 13 +++++++++++++
>  1 file changed, 13 insertions(+)
> 
> diff --git a/arch/arm64/kernel/pci.c b/arch/arm64/kernel/pci.c
> index 4095379..b3d098b 100644
> --- a/arch/arm64/kernel/pci.c
> +++ b/arch/arm64/kernel/pci.c
> @@ -38,6 +38,19 @@ resource_size_t pcibios_align_resource(void *data, const struct resource *res,
>  	return res->start;
>  }
>  
> +/**
> + * pcibios_enable_device - Enable I/O and memory.
> + * @dev: PCI device to be enabled
> + * @mask: bitmask of BARs to enable
> + */
> +int pcibios_enable_device(struct pci_dev *dev, int mask)
> +{
> +	if (pci_has_flag(PCI_PROBE_ONLY))
> +		return 0;
> +
> +	return pci_enable_resources(dev, mask);
> +}
> +
>  /*
>   * Try to assign the IRQ number from DT when adding a new device
>   */
> -- 
> 2.2.1
> 


From davem at davemloft.net  Fri Aug 28 14:26:40 2015
From: davem at davemloft.net (David Miller)
Date: Fri, 28 Aug 2015 14:26:40 -0700 (PDT)
Subject: [PATCH net-next 6/8] net: thunderx: Rework interrupt handler
In-Reply-To: <1440774004-27923-6-git-send-email-aleksey.makarov@auriga.com>
References: <1440774004-27923-1-git-send-email-aleksey.makarov@auriga.com>
 <1440774004-27923-6-git-send-email-aleksey.makarov@auriga.com>
Message-ID: <20150828.142640.647193074690125620.davem@davemloft.net>

From: Aleksey Makarov <aleksey.makarov at auriga.com>
Date: Fri, 28 Aug 2015 17:59:58 +0300

> @@ -251,6 +251,8 @@ struct cmp_queue {
>  	void		*desc;
>  	struct q_desc_mem   dmem;
>  	struct cmp_queue_stats	stats;
> +	int		irq;
> +	cpumask_t	affinity_mask;
>  } ____cacheline_aligned_in_smp;
>  
>  struct snd_queue {

This new "affinity_mask" member is not used, please remove it and respin
this patch series.

Thanks.


From khilman at kernel.org  Fri Aug 28 14:28:11 2015
From: khilman at kernel.org (Kevin Hilman)
Date: Fri, 28 Aug 2015 14:28:11 -0700
Subject: [RESEND PATCH v16 4/4] ARM: dts: add the support power-domain
 node on RK3288 SoCs
In-Reply-To: <20150828200238.30921.24441@quantum> (Michael Turquette's message
 of "Fri, 28 Aug 2015 13:02:38 -0700")
References: <1440487486-6154-1-git-send-email-wxt@rock-chips.com>
 <1440487486-6154-5-git-send-email-wxt@rock-chips.com>
 <7hfv37axhj.fsf@deeprootsystems.com>
 <CAD=FV=V6oG+9U=W_JZmqCuNo-9-5wW8ffZzG7ZE_3cnSTNAjFQ@mail.gmail.com>
 <7htwrn6l7g.fsf@deeprootsystems.com>
 <CAKdAkRS=9Dq+YpMNSjpij0Am4ZD6uUURv74OLLYf+akD=W885A@mail.gmail.com>
 <7hmvxc45w2.fsf@deeprootsystems.com>
 <CAD=FV=VTR-PBcXXX1jHNw65x_cMP9CKwVWBs+XCcFqFPp7msjA@mail.gmail.com>
 <20150828200238.30921.24441@quantum>
Message-ID: <7hmvxb2jdg.fsf@deeprootsystems.com>

Michael Turquette <mturquette at linaro.org> writes:

> Hi Doug,
>
> Quoting Doug Anderson (2015-08-27 19:03:20)
>> Kevin,
>> 
>> On Thu, Aug 27, 2015 at 5:24 PM, Kevin Hilman <khilman at kernel.org> wrote:
>> >> That is not really workable: the attach and detach happen in
>> >> probe/remove path; if you do not have driver for the device you will
>> >> miss the clocks for it.
>> >
>> > And in my proposal, I suggested that clocks without drivers are
>> > good candidates to list in the domain, with the caveat that the be
>> > called out (documented) as being device clocks that are missing a
>> > driver, so when a driver shows up they can be moved accordingly, and in
>> > a way that actually describes the hardware.
>> 
>> What happens if someone disables the driver using the CONFIG subsystem?
>
> Kevin asked me to chime in on this thread, as I have a half-baked idea
> that might solve the problem posed by your question above.
>
> One thing I have been considering for a while is a fallback compatible
> string that can be used for an IP block when either there is no driver
> loaded or no driver exists at all. Something like "generic-ip-block".
>
> The purpose of this compatible string is to allow us to model resource
> consumption in dts accurately, regardless of whether or not a proper
> driver has been written in Linux. This idea was born out of the
> simple-fb binding/driver discussion last year[0].
>
> Obviously such a binding would not enable any of the logic or function
> of that IP block; that would require a proper driver. But it would allow
> us to properly link system-wide resources that are consumed: the
> generic-ip could consume clocks and regulators, it could belong to power
> domains, etc. For this reason I have also thought that
> "generic-resource-consumer" is an accurate compatible string.
>
> This spares us from having to encode nasty details into the power domain
> binding, which is exactly what would happen if you needed a dedicated
> list of clocks in the power domain node that were not claimed by device
> nodes/drivers.
>
> Note that a real driver might exist for an IP block, but if that driver
> is disabled in Kconfig AND the corresponding dt node has this fallback
> compatible string, then we could be OK, from the perspective of the
> power domain problem.
>
>> 
>> What happens if this is a device that someone has set to 'status =
>> "disabled";' in the device tree?
>
> If someone does that, then I think we should let that break power domain
> transitions.
>

Well, the catch here is that status=disabled doesn't necessarily mean
that the IP block isn't present.  It can mean "not used", "not needed",
"not wired up to external iface" etc., but if the IP block is physcially
present, then its clocks are still needed for a power domain reset.  If
a node is marked as status=disabled, then even the fallback compatible
doesn't help, as the fallback driver won't be probed/loaded either. :(

Speaking of loading, the module loading/unloading complicates this even
further.  Even if a pm-domain is managing the clocks from a device node,
if a driver is unloaded (and thus removed from the pm domain), the pm
domain driver would stop managing that clock and then the domain reset
would stop working again.  Ugh.  

The more I think through all these corner cases, and also the fact that
we never seem to be able to get a fully accurate description of how the
SoCs actually work at this level (due to missing/poor/wrong docs), I
think the having both the power domain and the device nodes claiming
clocks is the most flexible solution. It's using the clock consumer
binding in a perfectly acceptable way, and the clock fwk usecounting
will manage usecounting etc.

However, I still stick by my earlier insistence that the DT nodes be
thorougly documented though, and be very specific why the clocks are
needed by the power domain, and especially which clocks are device
clocks, etc.  I (and hopefully others) will be looking closely at the
DTs that come through and make that clocks listed in the domains are
well described.

@Doug: thanks for taking the time to spell out the variou corner cases.

Kevin


From benh at kernel.crashing.org  Fri Aug 28 14:37:36 2015
From: benh at kernel.crashing.org (Benjamin Herrenschmidt)
Date: Sat, 29 Aug 2015 07:37:36 +1000
Subject: [PATCH v5 2/4] Documentation: arm64/arm: dt bindings for numa.
In-Reply-To: <CAL_JsqLOpUTVeKbkJ6uPi0EYistd=BowAHdtSmaUYYDhU6c9Sg@mail.gmail.com>
References: <1439570374-4079-1-git-send-email-gkulkarni@caviumnetworks.com>
 <1439570374-4079-3-git-send-email-gkulkarni@caviumnetworks.com>
 <20150828123228.GE31748@leverpostej>
 <CAL_JsqLOpUTVeKbkJ6uPi0EYistd=BowAHdtSmaUYYDhU6c9Sg@mail.gmail.com>
Message-ID: <1440797856.2912.239.camel@kernel.crashing.org>

On Fri, 2015-08-28 at 09:02 -0500, Rob Herring wrote:

> So just keep the ibm? I'm okay with that. That would help move to
> common code. Alternatively, we could drop the vendor prefix and have
> common code just check for both.

That wouldn't be the first time we go down that path and it makes sense
imho.

> All points that could be asked of the IBM binding. Perhaps Arnd or 
> Ben can provide some insight or know who can?

They are part of the PAPR specification which we've been trying to get
published for a while now but that hasn't happened yet. Beware that
there are variants of the format based on some other property. There's
also 
"ibm,associativity-reference-points" which is used to calculate
distances. I'll see if I can get you an excerpt of the PAPR chapter, or
reword it, in the next few days (please poke me if I drop the ball next
week).

Cheers,
Ben.



From sboyd at codeaurora.org  Fri Aug 28 14:48:56 2015
From: sboyd at codeaurora.org (Stephen Boyd)
Date: Fri, 28 Aug 2015 14:48:56 -0700
Subject: [PATCH] gpio: msm: Remove unused driver
Message-ID: <1440798536-8337-1-git-send-email-sboyd@codeaurora.org>

Remove this driver now that Bjorn has introduced a pinctrl driver
for msm8660 and the dts files have been updated with the pinctrl
compatibles.

Cc: Bjorn Andersson <bjorn.andersson at sonymobile.com>
Cc: Andy Gross <agross at codeaurora.org>
Signed-off-by: Stephen Boyd <sboyd at codeaurora.org>
---
 .../devicetree/bindings/gpio/gpio-msm.txt          |  26 --
 drivers/gpio/Kconfig                               |   8 -
 drivers/gpio/Makefile                              |   1 -
 drivers/gpio/gpio-msm-v2.c                         | 453 ---------------------
 4 files changed, 488 deletions(-)
 delete mode 100644 Documentation/devicetree/bindings/gpio/gpio-msm.txt
 delete mode 100644 drivers/gpio/gpio-msm-v2.c

diff --git a/Documentation/devicetree/bindings/gpio/gpio-msm.txt b/Documentation/devicetree/bindings/gpio/gpio-msm.txt
deleted file mode 100644
index ac20e68a004e..000000000000
--- a/Documentation/devicetree/bindings/gpio/gpio-msm.txt
+++ /dev/null
@@ -1,26 +0,0 @@
-MSM GPIO controller bindings
-
-Required properties:
-- compatible:
-  - "qcom,msm-gpio" for MSM controllers
-- #gpio-cells : Should be two.
-  - first cell is the pin number
-  - second cell is used to specify optional parameters (unused)
-- gpio-controller : Marks the device node as a GPIO controller.
-- #interrupt-cells : Should be 2.
-- interrupt-controller: Mark the device node as an interrupt controller
-- interrupts : Specify the TLMM summary interrupt number
-- ngpio : Specify the number of MSM GPIOs
-
-Example:
-
-	msmgpio: gpio at fd510000 {
-		compatible = "qcom,msm-gpio";
-		gpio-controller;
-		#gpio-cells = <2>;
-		interrupt-controller;
-		#interrupt-cells = <2>;
-		reg = <0xfd510000 0x4000>;
-		interrupts = <0 208 0>;
-		ngpio = <150>;
-	};
diff --git a/drivers/gpio/Kconfig b/drivers/gpio/Kconfig
index b4fc9e4d24c6..3ddf881e0c34 100644
--- a/drivers/gpio/Kconfig
+++ b/drivers/gpio/Kconfig
@@ -297,14 +297,6 @@ config GPIO_MPC8XXX
 	  Say Y here if you're going to use hardware that connects to the
 	  MPC512x/831x/834x/837x/8572/8610 GPIOs.
 
-config GPIO_MSM_V2
-	tristate "Qualcomm MSM GPIO v2"
-	depends on GPIOLIB && OF && ARCH_QCOM
-	help
-	  Say yes here to support the GPIO interface on ARM v7 based
-	  Qualcomm MSM chips.  Most of the pins on the MSM can be
-	  selected for GPIO, and are controlled by this driver.
-
 config GPIO_MVEBU
 	def_bool y
 	depends on PLAT_ORION
diff --git a/drivers/gpio/Makefile b/drivers/gpio/Makefile
index f79a7c482a99..0d30b645965b 100644
--- a/drivers/gpio/Makefile
+++ b/drivers/gpio/Makefile
@@ -64,7 +64,6 @@ obj-$(CONFIG_GPIO_MOXART)	+= gpio-moxart.o
 obj-$(CONFIG_GPIO_MPC5200)	+= gpio-mpc5200.o
 obj-$(CONFIG_GPIO_MPC8XXX)	+= gpio-mpc8xxx.o
 obj-$(CONFIG_GPIO_MSIC)		+= gpio-msic.o
-obj-$(CONFIG_GPIO_MSM_V2)	+= gpio-msm-v2.o
 obj-$(CONFIG_GPIO_MVEBU)        += gpio-mvebu.o
 obj-$(CONFIG_GPIO_MXC)		+= gpio-mxc.o
 obj-$(CONFIG_GPIO_MXS)		+= gpio-mxs.o
diff --git a/drivers/gpio/gpio-msm-v2.c b/drivers/gpio/gpio-msm-v2.c
deleted file mode 100644
index d2012cfb5571..000000000000
--- a/drivers/gpio/gpio-msm-v2.c
+++ /dev/null
@@ -1,453 +0,0 @@
-/* Copyright (c) 2010-2011, Code Aurora Forum. All rights reserved.
- *
- * This program is free software; you can redistribute it and/or modify
- * it under the terms of the GNU General Public License version 2 and
- * only 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.
- *
- * You should have received a copy of the GNU General Public License
- * along with this program; if not, write to the Free Software
- * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA
- * 02110-1301, USA.
- *
- */
-#define pr_fmt(fmt) "%s: " fmt, __func__
-
-#include <linux/bitmap.h>
-#include <linux/bitops.h>
-#include <linux/err.h>
-#include <linux/gpio.h>
-#include <linux/init.h>
-#include <linux/interrupt.h>
-#include <linux/io.h>
-#include <linux/irqchip/chained_irq.h>
-#include <linux/irq.h>
-#include <linux/irqdomain.h>
-#include <linux/module.h>
-#include <linux/of_address.h>
-#include <linux/platform_device.h>
-#include <linux/spinlock.h>
-#include <linux/slab.h>
-
-#define MAX_NR_GPIO 300
-
-/* Bits of interest in the GPIO_IN_OUT register.
- */
-enum {
-	GPIO_IN  = 0,
-	GPIO_OUT = 1
-};
-
-/* Bits of interest in the GPIO_INTR_STATUS register.
- */
-enum {
-	INTR_STATUS = 0,
-};
-
-/* Bits of interest in the GPIO_CFG register.
- */
-enum {
-	GPIO_OE = 9,
-};
-
-/* Bits of interest in the GPIO_INTR_CFG register.
- * When a GPIO triggers, two separate decisions are made, controlled
- * by two separate flags.
- *
- * - First, INTR_RAW_STATUS_EN controls whether or not the GPIO_INTR_STATUS
- * register for that GPIO will be updated to reflect the triggering of that
- * gpio.  If this bit is 0, this register will not be updated.
- * - Second, INTR_ENABLE controls whether an interrupt is triggered.
- *
- * If INTR_ENABLE is set and INTR_RAW_STATUS_EN is NOT set, an interrupt
- * can be triggered but the status register will not reflect it.
- */
-enum {
-	INTR_ENABLE        = 0,
-	INTR_POL_CTL       = 1,
-	INTR_DECT_CTL      = 2,
-	INTR_RAW_STATUS_EN = 3,
-};
-
-/* Codes of interest in GPIO_INTR_CFG_SU.
- */
-enum {
-	TARGET_PROC_SCORPION = 4,
-	TARGET_PROC_NONE     = 7,
-};
-
-/**
- * struct msm_gpio_dev: the MSM8660 SoC GPIO device structure
- *
- * @enabled_irqs: a bitmap used to optimize the summary-irq handler.  By
- * keeping track of which gpios are unmasked as irq sources, we avoid
- * having to do readl calls on hundreds of iomapped registers each time
- * the summary interrupt fires in order to locate the active interrupts.
- *
- * @wake_irqs: a bitmap for tracking which interrupt lines are enabled
- * as wakeup sources.  When the device is suspended, interrupts which are
- * not wakeup sources are disabled.
- *
- * @dual_edge_irqs: a bitmap used to track which irqs are configured
- * as dual-edge, as this is not supported by the hardware and requires
- * some special handling in the driver.
- */
-struct msm_gpio_dev {
-	struct gpio_chip gpio_chip;
-	DECLARE_BITMAP(enabled_irqs, MAX_NR_GPIO);
-	DECLARE_BITMAP(wake_irqs, MAX_NR_GPIO);
-	DECLARE_BITMAP(dual_edge_irqs, MAX_NR_GPIO);
-	struct irq_domain *domain;
-	int summary_irq;
-	void __iomem *msm_tlmm_base;
-};
-
-static struct msm_gpio_dev msm_gpio;
-
-#define GPIO_INTR_CFG_SU(gpio)    (msm_gpio.msm_tlmm_base + 0x0400 + \
-								(0x04 * (gpio)))
-#define GPIO_CONFIG(gpio)         (msm_gpio.msm_tlmm_base + 0x1000 + \
-								(0x10 * (gpio)))
-#define GPIO_IN_OUT(gpio)         (msm_gpio.msm_tlmm_base + 0x1004 + \
-								(0x10 * (gpio)))
-#define GPIO_INTR_CFG(gpio)       (msm_gpio.msm_tlmm_base + 0x1008 + \
-								(0x10 * (gpio)))
-#define GPIO_INTR_STATUS(gpio)    (msm_gpio.msm_tlmm_base + 0x100c + \
-								(0x10 * (gpio)))
-
-static DEFINE_SPINLOCK(tlmm_lock);
-
-static inline struct msm_gpio_dev *to_msm_gpio_dev(struct gpio_chip *chip)
-{
-	return container_of(chip, struct msm_gpio_dev, gpio_chip);
-}
-
-static inline void set_gpio_bits(unsigned n, void __iomem *reg)
-{
-	writel(readl(reg) | n, reg);
-}
-
-static inline void clear_gpio_bits(unsigned n, void __iomem *reg)
-{
-	writel(readl(reg) & ~n, reg);
-}
-
-static int msm_gpio_get(struct gpio_chip *chip, unsigned offset)
-{
-	return readl(GPIO_IN_OUT(offset)) & BIT(GPIO_IN);
-}
-
-static void msm_gpio_set(struct gpio_chip *chip, unsigned offset, int val)
-{
-	writel(val ? BIT(GPIO_OUT) : 0, GPIO_IN_OUT(offset));
-}
-
-static int msm_gpio_direction_input(struct gpio_chip *chip, unsigned offset)
-{
-	unsigned long irq_flags;
-
-	spin_lock_irqsave(&tlmm_lock, irq_flags);
-	clear_gpio_bits(BIT(GPIO_OE), GPIO_CONFIG(offset));
-	spin_unlock_irqrestore(&tlmm_lock, irq_flags);
-	return 0;
-}
-
-static int msm_gpio_direction_output(struct gpio_chip *chip,
-				unsigned offset,
-				int val)
-{
-	unsigned long irq_flags;
-
-	spin_lock_irqsave(&tlmm_lock, irq_flags);
-	msm_gpio_set(chip, offset, val);
-	set_gpio_bits(BIT(GPIO_OE), GPIO_CONFIG(offset));
-	spin_unlock_irqrestore(&tlmm_lock, irq_flags);
-	return 0;
-}
-
-static int msm_gpio_request(struct gpio_chip *chip, unsigned offset)
-{
-	return 0;
-}
-
-static void msm_gpio_free(struct gpio_chip *chip, unsigned offset)
-{
-	return;
-}
-
-static int msm_gpio_to_irq(struct gpio_chip *chip, unsigned offset)
-{
-	struct msm_gpio_dev *g_dev = to_msm_gpio_dev(chip);
-	struct irq_domain *domain = g_dev->domain;
-
-	return irq_create_mapping(domain, offset);
-}
-
-/* For dual-edge interrupts in software, since the hardware has no
- * such support:
- *
- * At appropriate moments, this function may be called to flip the polarity
- * settings of both-edge irq lines to try and catch the next edge.
- *
- * The attempt is considered successful if:
- * - the status bit goes high, indicating that an edge was caught, or
- * - the input value of the gpio doesn't change during the attempt.
- * If the value changes twice during the process, that would cause the first
- * test to fail but would force the second, as two opposite
- * transitions would cause a detection no matter the polarity setting.
- *
- * The do-loop tries to sledge-hammer closed the timing hole between
- * the initial value-read and the polarity-write - if the line value changes
- * during that window, an interrupt is lost, the new polarity setting is
- * incorrect, and the first success test will fail, causing a retry.
- *
- * Algorithm comes from Google's msmgpio driver, see mach-msm/gpio.c.
- */
-static void msm_gpio_update_dual_edge_pos(unsigned gpio)
-{
-	int loop_limit = 100;
-	unsigned val, val2, intstat;
-
-	do {
-		val = readl(GPIO_IN_OUT(gpio)) & BIT(GPIO_IN);
-		if (val)
-			clear_gpio_bits(BIT(INTR_POL_CTL), GPIO_INTR_CFG(gpio));
-		else
-			set_gpio_bits(BIT(INTR_POL_CTL), GPIO_INTR_CFG(gpio));
-		val2 = readl(GPIO_IN_OUT(gpio)) & BIT(GPIO_IN);
-		intstat = readl(GPIO_INTR_STATUS(gpio)) & BIT(INTR_STATUS);
-		if (intstat || val == val2)
-			return;
-	} while (loop_limit-- > 0);
-	pr_err("%s: dual-edge irq failed to stabilize, "
-	       "interrupts dropped. %#08x != %#08x\n",
-	       __func__, val, val2);
-}
-
-static void msm_gpio_irq_ack(struct irq_data *d)
-{
-	int gpio = d->hwirq;
-
-	writel(BIT(INTR_STATUS), GPIO_INTR_STATUS(gpio));
-	if (test_bit(gpio, msm_gpio.dual_edge_irqs))
-		msm_gpio_update_dual_edge_pos(gpio);
-}
-
-static void msm_gpio_irq_mask(struct irq_data *d)
-{
-	unsigned long irq_flags;
-	int gpio = d->hwirq;
-
-	spin_lock_irqsave(&tlmm_lock, irq_flags);
-	writel(TARGET_PROC_NONE, GPIO_INTR_CFG_SU(gpio));
-	clear_gpio_bits(BIT(INTR_RAW_STATUS_EN) | BIT(INTR_ENABLE), GPIO_INTR_CFG(gpio));
-	__clear_bit(gpio, msm_gpio.enabled_irqs);
-	spin_unlock_irqrestore(&tlmm_lock, irq_flags);
-}
-
-static void msm_gpio_irq_unmask(struct irq_data *d)
-{
-	unsigned long irq_flags;
-	int gpio = d->hwirq;
-
-	spin_lock_irqsave(&tlmm_lock, irq_flags);
-	__set_bit(gpio, msm_gpio.enabled_irqs);
-	set_gpio_bits(BIT(INTR_RAW_STATUS_EN) | BIT(INTR_ENABLE), GPIO_INTR_CFG(gpio));
-	writel(TARGET_PROC_SCORPION, GPIO_INTR_CFG_SU(gpio));
-	spin_unlock_irqrestore(&tlmm_lock, irq_flags);
-}
-
-static int msm_gpio_irq_set_type(struct irq_data *d, unsigned int flow_type)
-{
-	unsigned long irq_flags;
-	int gpio = d->hwirq;
-	uint32_t bits;
-
-	spin_lock_irqsave(&tlmm_lock, irq_flags);
-
-	bits = readl(GPIO_INTR_CFG(gpio));
-
-	if (flow_type & IRQ_TYPE_EDGE_BOTH) {
-		bits |= BIT(INTR_DECT_CTL);
-		irq_set_handler_locked(d, handle_edge_irq);
-		if ((flow_type & IRQ_TYPE_EDGE_BOTH) == IRQ_TYPE_EDGE_BOTH)
-			__set_bit(gpio, msm_gpio.dual_edge_irqs);
-		else
-			__clear_bit(gpio, msm_gpio.dual_edge_irqs);
-	} else {
-		bits &= ~BIT(INTR_DECT_CTL);
-		irq_set_handler_locked(d, handle_level_irq);
-		__clear_bit(gpio, msm_gpio.dual_edge_irqs);
-	}
-
-	if (flow_type & (IRQ_TYPE_EDGE_RISING | IRQ_TYPE_LEVEL_HIGH))
-		bits |= BIT(INTR_POL_CTL);
-	else
-		bits &= ~BIT(INTR_POL_CTL);
-
-	writel(bits, GPIO_INTR_CFG(gpio));
-
-	if ((flow_type & IRQ_TYPE_EDGE_BOTH) == IRQ_TYPE_EDGE_BOTH)
-		msm_gpio_update_dual_edge_pos(gpio);
-
-	spin_unlock_irqrestore(&tlmm_lock, irq_flags);
-
-	return 0;
-}
-
-/*
- * When the summary IRQ is raised, any number of GPIO lines may be high.
- * It is the job of the summary handler to find all those GPIO lines
- * which have been set as summary IRQ lines and which are triggered,
- * and to call their interrupt handlers.
- */
-static void msm_summary_irq_handler(unsigned int irq, struct irq_desc *desc)
-{
-	unsigned long i;
-	struct irq_chip *chip = irq_desc_get_chip(desc);
-
-	chained_irq_enter(chip, desc);
-
-	for_each_set_bit(i, msm_gpio.enabled_irqs, MAX_NR_GPIO) {
-		if (readl(GPIO_INTR_STATUS(i)) & BIT(INTR_STATUS))
-			generic_handle_irq(irq_find_mapping(msm_gpio.domain,
-								i));
-	}
-
-	chained_irq_exit(chip, desc);
-}
-
-static int msm_gpio_irq_set_wake(struct irq_data *d, unsigned int on)
-{
-	int gpio = d->hwirq;
-
-	if (on) {
-		if (bitmap_empty(msm_gpio.wake_irqs, MAX_NR_GPIO))
-			irq_set_irq_wake(msm_gpio.summary_irq, 1);
-		set_bit(gpio, msm_gpio.wake_irqs);
-	} else {
-		clear_bit(gpio, msm_gpio.wake_irqs);
-		if (bitmap_empty(msm_gpio.wake_irqs, MAX_NR_GPIO))
-			irq_set_irq_wake(msm_gpio.summary_irq, 0);
-	}
-
-	return 0;
-}
-
-static struct irq_chip msm_gpio_irq_chip = {
-	.name		= "msmgpio",
-	.irq_mask	= msm_gpio_irq_mask,
-	.irq_unmask	= msm_gpio_irq_unmask,
-	.irq_ack	= msm_gpio_irq_ack,
-	.irq_set_type	= msm_gpio_irq_set_type,
-	.irq_set_wake	= msm_gpio_irq_set_wake,
-};
-
-static struct lock_class_key msm_gpio_lock_class;
-
-static int msm_gpio_irq_domain_map(struct irq_domain *d, unsigned int irq,
-				   irq_hw_number_t hwirq)
-{
-	irq_set_lockdep_class(irq, &msm_gpio_lock_class);
-	irq_set_chip_and_handler(irq, &msm_gpio_irq_chip,
-			handle_level_irq);
-
-	return 0;
-}
-
-static const struct irq_domain_ops msm_gpio_irq_domain_ops = {
-	.xlate = irq_domain_xlate_twocell,
-	.map = msm_gpio_irq_domain_map,
-};
-
-static int msm_gpio_probe(struct platform_device *pdev)
-{
-	int ret, ngpio;
-	struct resource *res;
-
-	if (of_property_read_u32(pdev->dev.of_node, "ngpio", &ngpio)) {
-		dev_err(&pdev->dev, "%s: ngpio property missing\n", __func__);
-		return -EINVAL;
-	}
-
-	if (ngpio > MAX_NR_GPIO)
-		WARN(1, "ngpio exceeds the MAX_NR_GPIO. Increase MAX_NR_GPIO\n");
-
-	bitmap_zero(msm_gpio.enabled_irqs, MAX_NR_GPIO);
-	bitmap_zero(msm_gpio.wake_irqs, MAX_NR_GPIO);
-	bitmap_zero(msm_gpio.dual_edge_irqs, MAX_NR_GPIO);
-
-	res = platform_get_resource(pdev, IORESOURCE_MEM, 0);
-	msm_gpio.msm_tlmm_base = devm_ioremap_resource(&pdev->dev, res);
-	if (IS_ERR(msm_gpio.msm_tlmm_base))
-		return PTR_ERR(msm_gpio.msm_tlmm_base);
-
-	msm_gpio.gpio_chip.ngpio = ngpio;
-	msm_gpio.gpio_chip.label = pdev->name;
-	msm_gpio.gpio_chip.dev = &pdev->dev;
-	msm_gpio.gpio_chip.base = 0;
-	msm_gpio.gpio_chip.direction_input = msm_gpio_direction_input;
-	msm_gpio.gpio_chip.direction_output = msm_gpio_direction_output;
-	msm_gpio.gpio_chip.get = msm_gpio_get;
-	msm_gpio.gpio_chip.set = msm_gpio_set;
-	msm_gpio.gpio_chip.to_irq = msm_gpio_to_irq;
-	msm_gpio.gpio_chip.request = msm_gpio_request;
-	msm_gpio.gpio_chip.free = msm_gpio_free;
-
-	ret = gpiochip_add(&msm_gpio.gpio_chip);
-	if (ret < 0) {
-		dev_err(&pdev->dev, "gpiochip_add failed with error %d\n", ret);
-		return ret;
-	}
-
-	msm_gpio.summary_irq = platform_get_irq(pdev, 0);
-	if (msm_gpio.summary_irq < 0) {
-		dev_err(&pdev->dev, "No Summary irq defined for msmgpio\n");
-		return msm_gpio.summary_irq;
-	}
-
-	msm_gpio.domain = irq_domain_add_linear(pdev->dev.of_node, ngpio,
-						&msm_gpio_irq_domain_ops,
-						&msm_gpio);
-	if (!msm_gpio.domain)
-		return -ENODEV;
-
-	irq_set_chained_handler(msm_gpio.summary_irq, msm_summary_irq_handler);
-
-	return 0;
-}
-
-static const struct of_device_id msm_gpio_of_match[] = {
-	{ .compatible = "qcom,msm-gpio", },
-	{ },
-};
-MODULE_DEVICE_TABLE(of, msm_gpio_of_match);
-
-static int msm_gpio_remove(struct platform_device *dev)
-{
-	gpiochip_remove(&msm_gpio.gpio_chip);
-
-	irq_set_handler(msm_gpio.summary_irq, NULL);
-
-	return 0;
-}
-
-static struct platform_driver msm_gpio_driver = {
-	.probe = msm_gpio_probe,
-	.remove = msm_gpio_remove,
-	.driver = {
-		.name = "msmgpio",
-		.of_match_table = msm_gpio_of_match,
-	},
-};
-
-module_platform_driver(msm_gpio_driver)
-
-MODULE_AUTHOR("Gregory Bean <gbean at codeaurora.org>");
-MODULE_DESCRIPTION("Driver for Qualcomm MSM TLMMv2 SoC GPIOs");
-MODULE_LICENSE("GPL v2");
-MODULE_ALIAS("platform:msmgpio");
-- 
The Qualcomm Innovation Center, Inc. is a member of the Code Aurora Forum,
a Linux Foundation Collaborative Project



From khilman at kernel.org  Fri Aug 28 15:23:20 2015
From: khilman at kernel.org (Kevin Hilman)
Date: Fri, 28 Aug 2015 15:23:20 -0700
Subject: arm64: how to check endianness of Image file?
Message-ID: <CAMAWPa8EW92OAAVn7FOkBzPbtsQLQDpU1F0TM3uuTFa9P6bYOA@mail.gmail.com>

Will, Catalin,

Any suggestions on a quick way to check if an arm64 kernel Image file
is big-endian?

We're adding more boot support for arm64 defconfig +
CONFIG_CPU_BIG_ENDIAN=y to kernelci.org, and are looking for a
reliable way to check the endianness of the kernel Image file, we
don't have the vmlinux around to check the ELF headers.

On arm32, the zImage has some magic fields set from
arch/arm/boot/compressed/head.S, but arm64 doesn't have the
equivalent.

Kevin


From bjorn.andersson at sonymobile.com  Fri Aug 28 12:52:40 2015
From: bjorn.andersson at sonymobile.com (Bjorn Andersson)
Date: Fri, 28 Aug 2015 12:52:40 -0700
Subject: [PATCH] soc: qcom: Reorder SMEM/SMD configs
In-Reply-To: <1440786213-23375-1-git-send-email-sboyd@codeaurora.org>
References: <1440786213-23375-1-git-send-email-sboyd@codeaurora.org>
Message-ID: <20150828195239.GR13472@usrtlx11787.corpusers.net>

On Fri 28 Aug 11:23 PDT 2015, Stephen Boyd wrote:

> When I make nconfig, having the SMEM option after the SMD option
> causes the configurator to get confused when I'm enabling and
> disabling these options. Let's move SMEM before SMD so there's a
> clear indented dependency chain.
> 
> Cc: Bjorn Andersson <bjorn.andersson at sonymobile.com>

Reviewed-by: Bjorn Andersson <bjorn.andersson at sonymobile.com>

Regards,
Bjorn


From bjorn.andersson at sonymobile.com  Fri Aug 28 12:53:16 2015
From: bjorn.andersson at sonymobile.com (Bjorn Andersson)
Date: Fri, 28 Aug 2015 12:53:16 -0700
Subject: [PATCH] soc: qcom: smem: Avoid NULL pointer exception on remove
In-Reply-To: <1440785929-22441-1-git-send-email-sboyd@codeaurora.org>
References: <1440785929-22441-1-git-send-email-sboyd@codeaurora.org>
Message-ID: <20150828195316.GS13472@usrtlx11787.corpusers.net>

On Fri 28 Aug 11:18 PDT 2015, Stephen Boyd wrote:

> Don't set a pointer to NULL and then dereference it in the next
> line.
> 

Sorry about that.

Reviewed-by: Bjorn Andersson <bjorn.andersson at sonymobile.com>

Regards,
Bjorn


From bjorn.andersson at sonymobile.com  Fri Aug 28 12:55:45 2015
From: bjorn.andersson at sonymobile.com (Bjorn Andersson)
Date: Fri, 28 Aug 2015 12:55:45 -0700
Subject: [PATCH] spmi: pmic-arb: u8 <= 0xff is always true
In-Reply-To: <1440790270-14859-1-git-send-email-sboyd@codeaurora.org>
References: <1440790270-14859-1-git-send-email-sboyd@codeaurora.org>
Message-ID: <20150828195545.GT13472@usrtlx11787.corpusers.net>

On Fri 28 Aug 12:31 PDT 2015, Stephen Boyd wrote:

> Silences this static checker warning:
> 
>  drivers/spmi/spmi-pmic-arb.c:363
>  pmic_arb_write_cmd() warn: always true condition
>  '(opc <= 255) => (0-255 <= 255)'
> 
> Cc: Andy Gross <agross at codeaurora.org>
Reviewed-by: Bjorn Andersson <bjorn.andersson at sonymobile.com>

Regards,
Bjorn


From bjorn.andersson at sonymobile.com  Fri Aug 28 13:01:06 2015
From: bjorn.andersson at sonymobile.com (Bjorn Andersson)
Date: Fri, 28 Aug 2015 13:01:06 -0700
Subject: [PATCH] spmi: pmic-arb: Don't byte swap when reading/writing FIFO
In-Reply-To: <1440789702-1648-1-git-send-email-sboyd@codeaurora.org>
References: <1440789702-1648-1-git-send-email-sboyd@codeaurora.org>
Message-ID: <20150828200106.GU13472@usrtlx11787.corpusers.net>

On Fri 28 Aug 12:21 PDT 2015, Stephen Boyd wrote:

> We don't want to swap bytes that we're reading and writing to the
> FIFOs when we're running on a big-endian CPU. Doing so causes
> problems like where the qcom-spmi-iadc driver can't detect the
> type of device because the bytes are all mixed up. Use the raw IO
> accessors for these API instead, and collapse pmic_arb_base_read()
> into the byte reading API so that we aren't tempted to read non-FIFO
> data like commands with that function.
> 
> Cc: Andy Gross <agross at codeaurora.org>

Acked-by: Bjorn Andersson <bjorn.andersson at sonymobile.com>

Regards,
Bjorn



From bjorn.andersson at sonymobile.com  Fri Aug 28 15:24:03 2015
From: bjorn.andersson at sonymobile.com (Bjorn Andersson)
Date: Fri, 28 Aug 2015 15:24:03 -0700
Subject: [PATCH] gpio: msm: Remove unused driver
In-Reply-To: <1440798536-8337-1-git-send-email-sboyd@codeaurora.org>
References: <1440798536-8337-1-git-send-email-sboyd@codeaurora.org>
Message-ID: <20150828222403.GV13472@usrtlx11787.corpusers.net>

On Fri 28 Aug 14:48 PDT 2015, Stephen Boyd wrote:

> Remove this driver now that Bjorn has introduced a pinctrl driver
> for msm8660 and the dts files have been updated with the pinctrl
> compatibles.
> 

Reviewed-by: Bjorn Andersson <bjorn.andersson at sonymobile.com>
> Cc: Andy Gross <agross at codeaurora.org>
> Signed-off-by: Stephen Boyd <sboyd at codeaurora.org>
> ---

Regards,
Bjorn


From mturquette at baylibre.com  Fri Aug 28 15:53:49 2015
From: mturquette at baylibre.com (Michael Turquette)
Date: Fri, 28 Aug 2015 15:53:49 -0700
Subject: [RESEND PATCH v16 4/4] ARM: dts: add the support power-domain
 node on RK3288 SoCs
In-Reply-To: <CAD=FV=UrWauwX143MSZpus=L7N__jL1dU-FwaE8BU7wi=Lu2Qg@mail.gmail.com>
References: <1440487486-6154-1-git-send-email-wxt@rock-chips.com>
 <1440487486-6154-5-git-send-email-wxt@rock-chips.com>
 <7hfv37axhj.fsf@deeprootsystems.com>
 <CAD=FV=V6oG+9U=W_JZmqCuNo-9-5wW8ffZzG7ZE_3cnSTNAjFQ@mail.gmail.com>
 <7htwrn6l7g.fsf@deeprootsystems.com>
 <CAKdAkRS=9Dq+YpMNSjpij0Am4ZD6uUURv74OLLYf+akD=W885A@mail.gmail.com>
 <7hmvxc45w2.fsf@deeprootsystems.com>
 <CAD=FV=VTR-PBcXXX1jHNw65x_cMP9CKwVWBs+XCcFqFPp7msjA@mail.gmail.com>
 <20150828200238.30921.24441@quantum>
 <CAD=FV=UrWauwX143MSZpus=L7N__jL1dU-FwaE8BU7wi=Lu2Qg@mail.gmail.com>
Message-ID: <20150828225349.11508.41285@quantum>

Quoting Doug Anderson (2015-08-28 14:08:52)
> Mike,
> 
> On Fri, Aug 28, 2015 at 1:02 PM, Michael Turquette
> <mturquette at linaro.org> wrote:
> > Hi Doug,
> >
> > Quoting Doug Anderson (2015-08-27 19:03:20)
> >> Kevin,
> >>
> >> On Thu, Aug 27, 2015 at 5:24 PM, Kevin Hilman <khilman at kernel.org> wrote:
> >> >> That is not really workable: the attach and detach happen in
> >> >> probe/remove path; if you do not have driver for the device you will
> >> >> miss the clocks for it.
> >> >
> >> > And in my proposal, I suggested that clocks without drivers are
> >> > good candidates to list in the domain, with the caveat that the be
> >> > called out (documented) as being device clocks that are missing a
> >> > driver, so when a driver shows up they can be moved accordingly, and in
> >> > a way that actually describes the hardware.
> >>
> >> What happens if someone disables the driver using the CONFIG subsystem?
> >
> > Kevin asked me to chime in on this thread, as I have a half-baked idea
> > that might solve the problem posed by your question above.
> >
> > One thing I have been considering for a while is a fallback compatible
> > string that can be used for an IP block when either there is no driver
> > loaded or no driver exists at all. Something like "generic-ip-block".
> >
> > The purpose of this compatible string is to allow us to model resource
> > consumption in dts accurately, regardless of whether or not a proper
> > driver has been written in Linux. This idea was born out of the
> > simple-fb binding/driver discussion last year[0].
> >
> > Obviously such a binding would not enable any of the logic or function
> > of that IP block; that would require a proper driver. But it would allow
> > us to properly link system-wide resources that are consumed: the
> > generic-ip could consume clocks and regulators, it could belong to power
> > domains, etc. For this reason I have also thought that
> > "generic-resource-consumer" is an accurate compatible string.
> >
> > This spares us from having to encode nasty details into the power domain
> > binding, which is exactly what would happen if you needed a dedicated
> > list of clocks in the power domain node that were not claimed by device
> > nodes/drivers.
> >
> > Note that a real driver might exist for an IP block, but if that driver
> > is disabled in Kconfig AND the corresponding dt node has this fallback
> > compatible string, then we could be OK, from the perspective of the
> > power domain problem.
> 
> OK, so that could solve the "Kconfig" problem.
> 
> 
> >> What happens if this is a device that someone has set to 'status =
> >> "disabled";' in the device tree?
> >
> > If someone does that, then I think we should let that break power domain
> > transitions.
> 
> So if you're on a board that doesn't use EDP but uses LVDS then their
> suspend/resume should be broken?
> 
> Specifically, it's my understanding that on this SoC:
> 
> 1. There's a single "video IO" power domain that contains things like
> the video output processor, EDP, LVDS, HDMI, etc.
> 
> 2. When you turn on/off the power domain it's important to clock all
> devices in the domain during the reset.
> 
> 3. If you don't clock all devices during the reset they get left in a
> "wedged" state.
> 
> 4. If you try to do things like suspend/resume it will query all
> devices.  If they've been left in the wedged state then suspend/resume
> will be blocked.
> 
> ...so this problem is still not solved.

I talked to Kevin about this and we both agree that the power domain's
use of the clock consumer binding is totally valid. So I still think
there might be a use for the generic-ip binding, but I also think the
solution in this original patch also looks sane.

A paraphrase of my discussion with Kevin is that we can think of both
the device (EDP, LVDS) and the power domain as clock consumers, so
basically there is nothing weird going on here. Feel free to add:

Reviewed-by: Michael Turquette <mturquette at baylibre.com>

I do also agree with Kevin that we have a lot of layering issues to
consider here with description of PM hardware, and there are temptations
to take the shortest route to get things working. Truly modeling
relationships is the best way forward and we need to keep that in mind
over the long haul.

> 
> >> Even if the device is disabled in one of those two ways, we still need
> >> the clocks to be turned on.  ...so if we turn on/off the VIO domain we
> >> need to turn on the EDP clock even if there's no EDP in the current
> >> board / config.  We might turn on/off VIO for one of the other devices
> >> in the VIO domain for one of the other devices in VIO that we are
> >> using.
> >
> > I'm hesitant to mention this but I am working on a patch series to
> > implement a clock "handoff" mechanism (also inspired by the simplefb
> > discussion). This allows us to set a per-clock flag that tells the
> > framework to enable that clock at registration time, and then the first
> > clock consumer driver to come along and claim that clock inherits that
> > clock enable reference count.
> >
> > I'm working on v2 that lets us set this flag from DT, but I really only
> > plan to do this for special cases. For the normal case the flag should
> > be set in the Linux clock provider driver. In the mean time v1 is under
> > discussion[1].
> 
> In this case if we're using LVDS and HDMI on a system, we don't want
> the EDP clock always on (that just wastes power).  We just need to
> clock it for the power domain transition.
> 
> 
> Note that nothing in the above solves the problem that not all clocks
> for a given device need to be turned on during power domain
> transitions.  If we're trying to describe hardware perfectly, we'd
> really need to add to each device:
> 
> clocks = <clk1>, <clk2>, <clk3>, ...
> clock-names = "name1", "name2", "name3", ...
> clocks-for-power-domain-transition = "name2", "name3";
> 
> ...since perhaps the clock named "name1" isn't required for power
> domain transitions and so shouldn't be turned on.  Note that once
> we're going through and adding a special list, it doesn't seem that
> different than just adding the list in the power domain node instead
> (other than being more complex).

Yes, this is a broader issue with mapping clocks onto consumer use
cases. The same is exactly true for any consumer driver that consumes
multiple clocks and enables/disables them differently (e.g. interface
clocks versus functional clocks). How to convey that in DT?

Regards,
Mike


From javier at osg.samsung.com  Fri Aug 28 16:25:01 2015
From: javier at osg.samsung.com (Javier Martinez Canillas)
Date: Sat, 29 Aug 2015 01:25:01 +0200
Subject: [PATCH] pinctrl: mediatek: Consistently use the BIT() macro
Message-ID: <1440804302-6903-1-git-send-email-javier@osg.samsung.com>

The mediatek pinctrl driver uses the BIT() macro instead of open
coding 1 << n in all but one place. Replace this occurrence with
the BIT() macro for consistency.

Signed-off-by: Javier Martinez Canillas <javier at osg.samsung.com>

---

 drivers/pinctrl/mediatek/pinctrl-mtk-common.c | 2 +-
 1 file changed, 1 insertion(+), 1 deletion(-)

diff --git a/drivers/pinctrl/mediatek/pinctrl-mtk-common.c b/drivers/pinctrl/mediatek/pinctrl-mtk-common.c
index 23f2de07f598..497b9125342a 100644
--- a/drivers/pinctrl/mediatek/pinctrl-mtk-common.c
+++ b/drivers/pinctrl/mediatek/pinctrl-mtk-common.c
@@ -898,7 +898,7 @@ static int mtk_eint_flip_edge(struct mtk_pinctrl *pctl, int hwirq)
 	int start_level, curr_level;
 	unsigned int reg_offset;
 	const struct mtk_eint_offsets *eint_offsets = &(pctl->devdata->eint_offsets);
-	u32 mask = 1 << (hwirq & 0x1f);
+	u32 mask = BIT(hwirq & 0x1f);
 	u32 port = (hwirq >> 5) & eint_offsets->port_mask;
 	void __iomem *reg = pctl->eint_reg_base + (port << 2);
 	const struct mtk_desc_pin *pin;
-- 
2.4.3



From shawn.lin at rock-chips.com  Fri Aug 28 16:40:41 2015
From: shawn.lin at rock-chips.com (Shawn Lin)
Date: Sat, 29 Aug 2015 07:40:41 +0800
Subject: [PATCH 1/5] DMA: pl330: support burst mode for dev-to-mem and
 mem-to-dev transmit
In-Reply-To: <CAPz6YkX-d8B1wPgjnULDAY8+nyuFePVrEU2NQe0rV2CsjYEj3Q@mail.gmail.com>
References: <1440665280-31557-1-git-send-email-shawn.lin@rock-chips.com>
 <1440665313-31603-1-git-send-email-shawn.lin@rock-chips.com>
 <CAJKOXPdw+ZZURRPUNvKHdx7wRG7M-Frqmvq46KFM_ckGq8h0Yg@mail.gmail.com>
 <55DF1072.1070905@rock-chips.com>
 <CAPz6YkX-d8B1wPgjnULDAY8+nyuFePVrEU2NQe0rV2CsjYEj3Q@mail.gmail.com>
Message-ID: <55E0F179.2020601@rock-chips.com>

? 2015/8/29 2:19, Sonny Rao ??:
> On Thu, Aug 27, 2015 at 6:28 AM, Shawn Lin <shawn.lin at rock-chips.com> wrote:
>> ? 2015/8/27 20:57, Krzysztof Kozlowski ??:
>>>
>>> 2015-08-27 17:48 GMT+09:00 Shawn Lin <shawn.lin at rock-chips.com>:
>>>>
>>>>
>>>> This patch adds to support burst mode for dev-to-mem and
>>>> mem-to-dev transmit.
>>>>
>>>> Signed-off-by: Boojin Kim <boojin.kim at samsung.com>
>>>> Signed-off-by: Addy Ke <addy.ke at rock-chips.com>
>>>> Signed-off-by: Shawn Lin <shawn.lin at rock-chips.com>
>>>> cc: Heiko Stuebner <heiko at sntech.de>
>>>> cc: Doug Anderson <dianders at chromium.org>
>>>> cc: Olof Johansson <olofj at google.com>
>>>> Reviewed-and-tested-by: Sonny Rao <sonnyrao at chromium.org>
>>>
>>>
>>> For the entire patchset: I would prefer to see someone's
>>> reviewed/tested tag in his response. Sending a version 1 of patchset
>>> (regardless of Boojin Kim's work two years ago) with such tag could
>>> mean anything. I cannot verify it easily (unless digging somewhere...
>>> or asking people). You could add for example: Reviewed-by Santa Claus.
>>> Should I sent a letter to him asking for confirmation? :)
>>>
>>
>> :) yes, you are right. I should comply with the rule, even if the patchest
>> had been reviewed or tested by someone on another tree.
>
> Hi, yeah I reviewed on a different tree, so you shouldn't put that tag
> here, thanks for removing it.
> I can re-review if you'd like.
>

Hi, sunny, Thanks for reply.
It's very great if you can help me re-review the patchset here. :)

>>
>>
>>> More seriously - reviewed-by is a statement (please look at
>>> Documentation/SubmittingPatches) and you cannot force someone to make
>>> that statement. He must make such statement on his own.
>>>
>>> That's all from my side since I don't feel skilled enough to review the
>>> code.
>>>
>>> Best regards,
>>> Krzysztof
>>>
>>>>
>>>> ---
>>>>
>>>>    drivers/dma/pl330.c | 18 ++++++++++++------
>>>>    1 file changed, 12 insertions(+), 6 deletions(-)
>>>>
>>>> diff --git a/drivers/dma/pl330.c b/drivers/dma/pl330.c
>>>> index ecab4ea0..0d544d2 100644
>>>> --- a/drivers/dma/pl330.c
>>>> +++ b/drivers/dma/pl330.c
>>>> @@ -1141,10 +1141,13 @@ static inline int _ldst_devtomem(unsigned
>>>> dry_run, u8 buf[],
>>>>                   const struct _xfer_spec *pxs, int cyc)
>>>>    {
>>>>           int off = 0;
>>>> +       enum pl330_cond cond;
>>>> +
>>>> +       cond = (pxs->desc->rqcfg.brst_len == 1) ? SINGLE : BURST;
>>>>
>>>>           while (cyc--) {
>>>> -               off += _emit_WFP(dry_run, &buf[off], SINGLE,
>>>> pxs->desc->peri);
>>>> -               off += _emit_LDP(dry_run, &buf[off], SINGLE,
>>>> pxs->desc->peri);
>>>> +               off += _emit_WFP(dry_run, &buf[off], cond,
>>>> pxs->desc->peri);
>>>> +               off += _emit_LDP(dry_run, &buf[off], cond,
>>>> pxs->desc->peri);
>>>>                   off += _emit_ST(dry_run, &buf[off], ALWAYS);
>>>>                   off += _emit_FLUSHP(dry_run, &buf[off],
>>>> pxs->desc->peri);
>>>>           }
>>>> @@ -1156,11 +1159,14 @@ static inline int _ldst_memtodev(unsigned
>>>> dry_run, u8 buf[],
>>>>                   const struct _xfer_spec *pxs, int cyc)
>>>>    {
>>>>           int off = 0;
>>>> +       enum pl330_cond cond;
>>>> +
>>>> +       cond = (pxs->desc->rqcfg.brst_len == 1) ? SINGLE : BURST;
>>>>
>>>>           while (cyc--) {
>>>> -               off += _emit_WFP(dry_run, &buf[off], SINGLE,
>>>> pxs->desc->peri);
>>>> +               off += _emit_WFP(dry_run, &buf[off], cond,
>>>> pxs->desc->peri);
>>>>                   off += _emit_LD(dry_run, &buf[off], ALWAYS);
>>>> -               off += _emit_STP(dry_run, &buf[off], SINGLE,
>>>> pxs->desc->peri);
>>>> +               off += _emit_STP(dry_run, &buf[off], cond,
>>>> pxs->desc->peri);
>>>>                   off += _emit_FLUSHP(dry_run, &buf[off],
>>>> pxs->desc->peri);
>>>>           }
>>>>
>>>> @@ -2557,7 +2563,7 @@ static struct dma_async_tx_descriptor
>>>> *pl330_prep_dma_cyclic(
>>>>
>>>>                   desc->rqtype = direction;
>>>>                   desc->rqcfg.brst_size = pch->burst_sz;
>>>> -               desc->rqcfg.brst_len = 1;
>>>> +               desc->rqcfg.brst_len = pch->burst_len;
>>>>                   desc->bytes_requested = period_len;
>>>>                   fill_px(&desc->px, dst, src, period_len);
>>>>
>>>> @@ -2702,7 +2708,7 @@ pl330_prep_slave_sg(struct dma_chan *chan, struct
>>>> scatterlist *sgl,
>>>>                   }
>>>>
>>>>                   desc->rqcfg.brst_size = pch->burst_sz;
>>>> -               desc->rqcfg.brst_len = 1;
>>>> +               desc->rqcfg.brst_len = pch->burst_len;
>>>>                   desc->rqtype = direction;
>>>>                   desc->bytes_requested = sg_dma_len(sg);
>>>>           }
>>>> --
>>>> 2.3.7
>>>>
>>>>
>>>> --
>>>> To unsubscribe from this list: send the line "unsubscribe dmaengine" in
>>>> the body of a message to majordomo at vger.kernel.org
>>>> More majordomo info at  http://vger.kernel.org/majordomo-info.html
>>>
>>>
>>>
>>>
>>
>>
>> --
>> Best Regards
>> Shawn Lin
>>
>> --
>> To unsubscribe from this list: send the line "unsubscribe linux-kernel" in
>> the body of a message to majordomo at vger.kernel.org
>> More majordomo info at  http://vger.kernel.org/majordomo-info.html
>> Please read the FAQ at  http://www.tux.org/lkml/
>
>
>


-- 
Best Regards
Shawn Lin



From jonmason at broadcom.com  Fri Aug 28 16:47:24 2015
From: jonmason at broadcom.com (Jon Mason)
Date: Fri, 28 Aug 2015 19:47:24 -0400
Subject: [PATCH v3 2/5] ARM: NSP: add minimal Northstar Plus device tree
Message-ID: <1440805644-18241-1-git-send-email-jonmason@broadcom.com>

Add a very minimalistic set of Northstar Plus Device Tree files which
describes the SoC and the BCM958625 implementation.  The perpherials
described are:

ARM Cortex A9 CPU
2 8250 UARTs
ARM GIC
PL310 L2 Cache
ARM A9 Global timer

Signed-off-by: Kapil Hali <kapilh at broadcom.com>
Signed-off-by: Jon Mason <jonmason at broadcom.com>
---
 arch/arm/boot/dts/Makefile       |   2 +
 arch/arm/boot/dts/bcm-nsp.dtsi   | 120 +++++++++++++++++++++++++++++++++++++++
 arch/arm/boot/dts/bcm958625k.dts |  57 +++++++++++++++++++
 3 files changed, 179 insertions(+)
 create mode 100644 arch/arm/boot/dts/bcm-nsp.dtsi
 create mode 100644 arch/arm/boot/dts/bcm958625k.dts

diff --git a/arch/arm/boot/dts/Makefile b/arch/arm/boot/dts/Makefile
index 246473a..adb5732 100644
--- a/arch/arm/boot/dts/Makefile
+++ b/arch/arm/boot/dts/Makefile
@@ -82,6 +82,8 @@ dtb-$(CONFIG_ARCH_BCM_CYGNUS) += \
 dtb-$(CONFIG_ARCH_BCM_MOBILE) += \
 	bcm28155-ap.dtb \
 	bcm21664-garnet.dtb
+dtb-$(CONFIG_ARCH_BCM_NSP) += \
+	bcm958625k.dtb
 dtb-$(CONFIG_ARCH_BERLIN) += \
 	berlin2-sony-nsz-gs7.dtb \
 	berlin2cd-google-chromecast.dtb \
diff --git a/arch/arm/boot/dts/bcm-nsp.dtsi b/arch/arm/boot/dts/bcm-nsp.dtsi
new file mode 100644
index 0000000..f5f494f
--- /dev/null
+++ b/arch/arm/boot/dts/bcm-nsp.dtsi
@@ -0,0 +1,120 @@
+/*
+ *  BSD LICENSE
+ *
+ *  Copyright(c) 2015 Broadcom Corporation.  All rights reserved.
+ *
+ *  Redistribution and use in source and binary forms, with or without
+ *  modification, are permitted provided that the following conditions
+ *  are met:
+ *
+ *    * Redistributions of source code must retain the above copyright
+ *      notice, this list of conditions and the following disclaimer.
+ *    * Redistributions in binary form must reproduce the above copyright
+ *      notice, this list of conditions and the following disclaimer in
+ *      the documentation and/or other materials provided with the
+ *      distribution.
+ *    * Neither the name of Broadcom Corporation nor the names of its
+ *      contributors may be used to endorse or promote products derived
+ *      from this software without specific prior written permission.
+ *
+ *  THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+ *  "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+ *  LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
+ *  A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
+ *  OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
+ *  SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
+ *  LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
+ *  DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
+ *  THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+ *  (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
+ *  OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ */
+
+#include <dt-bindings/interrupt-controller/arm-gic.h>
+#include <dt-bindings/interrupt-controller/irq.h>
+
+#include "skeleton.dtsi"
+
+/ {
+	compatible = "brcm,nsp";
+	model = "Broadcom Northstar Plus SoC";
+	interrupt-parent = <&gic>;
+
+	mpcore {
+		compatible = "simple-bus";
+		ranges = <0x00000000 0x19020000 0x00003000>;
+		#address-cells = <1>;
+		#size-cells = <1>;
+
+		cpus {
+			#address-cells = <1>;
+			#size-cells = <0>;
+
+			cpu at 0 {
+				device_type = "cpu";
+				compatible = "arm,cortex-a9";
+				next-level-cache = <&L2>;
+				reg = <0x0>;
+			};
+		};
+
+		L2: l2-cache {
+			compatible = "arm,pl310-cache";
+			reg = <0x2000 0x1000>;
+			cache-unified;
+			cache-level = <2>;
+		};
+
+		gic: interrupt-controller at 19021000 {
+			compatible = "arm,cortex-a9-gic";
+			#interrupt-cells = <3>;
+			#address-cells = <0>;
+			interrupt-controller;
+			reg = <0x1000 0x1000>,
+			      <0x0100 0x100>;
+		};
+
+		timer at 19020200 {
+			compatible = "arm,cortex-a9-global-timer";
+			reg = <0x0200 0x100>;
+			interrupts = <GIC_PPI 11 IRQ_TYPE_LEVEL_HIGH>;
+			clocks = <&periph_clk>;
+		};
+	};
+
+	clocks {
+		#address-cells = <1>;
+		#size-cells = <1>;
+		ranges;
+
+		periph_clk: periph_clk {
+			compatible = "fixed-clock";
+			#clock-cells = <0>;
+			clock-frequency = <500000000>;
+		};
+	};
+
+	apb {
+		compatible = "arm,amba-bus", "simple-bus";
+		interrupt-parent = <&gic>;
+		ranges = <0x00000000 0x18000000 0x00001000>;
+		#address-cells = <1>;
+		#size-cells = <1>;
+
+		uart0: serial at 18000300 {
+			compatible = "ns16550a";
+			reg = <0x0300 0x100>;
+			interrupts = <GIC_SPI 85 IRQ_TYPE_LEVEL_HIGH>;
+			clock-frequency = <62499840>;
+			status = "disabled";
+		};
+
+		uart1: serial at 18000400 {
+			compatible = "ns16550a";
+			reg = <0x0400 0x100>;
+			interrupts = <GIC_SPI 85 IRQ_TYPE_LEVEL_HIGH>;
+			clock-frequency = <62499840>;
+			status = "disabled";
+		};
+	};
+};
diff --git a/arch/arm/boot/dts/bcm958625k.dts b/arch/arm/boot/dts/bcm958625k.dts
new file mode 100644
index 0000000..16303db
--- /dev/null
+++ b/arch/arm/boot/dts/bcm958625k.dts
@@ -0,0 +1,57 @@
+/*
+ *  BSD LICENSE
+ *
+ *  Copyright(c) 2015 Broadcom Corporation.  All rights reserved.
+ *
+ *  Redistribution and use in source and binary forms, with or without
+ *  modification, are permitted provided that the following conditions
+ *  are met:
+ *
+ *    * Redistributions of source code must retain the above copyright
+ *      notice, this list of conditions and the following disclaimer.
+ *    * Redistributions in binary form must reproduce the above copyright
+ *      notice, this list of conditions and the following disclaimer in
+ *      the documentation and/or other materials provided with the
+ *      distribution.
+ *    * Neither the name of Broadcom Corporation nor the names of its
+ *      contributors may be used to endorse or promote products derived
+ *      from this software without specific prior written permission.
+ *
+ *  THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+ *  "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+ *  LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
+ *  A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
+ *  OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
+ *  SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
+ *  LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
+ *  DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
+ *  THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+ *  (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
+ *  OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ */
+
+/dts-v1/;
+
+#include "bcm-nsp.dtsi"
+
+/ {
+	model = "NorthStar Plus SVK (BCM958625K)";
+	compatible = "brcm,bcm58625", "brcm,nsp";
+
+	aliases {
+		serial0 = &uart0;
+		serial1 = &uart1;
+	};
+
+	chosen {
+		stdout-path = "serial0:115200n8";
+	};
+};
+
+&uart0 {
+	status = "okay";
+};
+
+&uart1 {
+	status = "okay";
+};
-- 
1.9.1



From rjui at broadcom.com  Fri Aug 28 17:20:20 2015
From: rjui at broadcom.com (Ray Jui)
Date: Fri, 28 Aug 2015 17:20:20 -0700
Subject: [PATCH v3 2/5] ARM: NSP: add minimal Northstar Plus device tree
In-Reply-To: <1440805644-18241-1-git-send-email-jonmason@broadcom.com>
References: <1440805644-18241-1-git-send-email-jonmason@broadcom.com>
Message-ID: <55E0FAC4.2040108@broadcom.com>



On 8/28/2015 4:47 PM, Jon Mason wrote:
> Add a very minimalistic set of Northstar Plus Device Tree files which
> describes the SoC and the BCM958625 implementation.  The perpherials
> described are:
> 
> ARM Cortex A9 CPU
> 2 8250 UARTs
> ARM GIC
> PL310 L2 Cache
> ARM A9 Global timer
> 
> Signed-off-by: Kapil Hali <kapilh at broadcom.com>
> Signed-off-by: Jon Mason <jonmason at broadcom.com>
> ---
>  arch/arm/boot/dts/Makefile       |   2 +
>  arch/arm/boot/dts/bcm-nsp.dtsi   | 120 +++++++++++++++++++++++++++++++++++++++
>  arch/arm/boot/dts/bcm958625k.dts |  57 +++++++++++++++++++
>  3 files changed, 179 insertions(+)
>  create mode 100644 arch/arm/boot/dts/bcm-nsp.dtsi
>  create mode 100644 arch/arm/boot/dts/bcm958625k.dts
> 
> diff --git a/arch/arm/boot/dts/Makefile b/arch/arm/boot/dts/Makefile
> index 246473a..adb5732 100644
> --- a/arch/arm/boot/dts/Makefile
> +++ b/arch/arm/boot/dts/Makefile
> @@ -82,6 +82,8 @@ dtb-$(CONFIG_ARCH_BCM_CYGNUS) += \
>  dtb-$(CONFIG_ARCH_BCM_MOBILE) += \
>  	bcm28155-ap.dtb \
>  	bcm21664-garnet.dtb
> +dtb-$(CONFIG_ARCH_BCM_NSP) += \
> +	bcm958625k.dtb
>  dtb-$(CONFIG_ARCH_BERLIN) += \
>  	berlin2-sony-nsz-gs7.dtb \
>  	berlin2cd-google-chromecast.dtb \
> diff --git a/arch/arm/boot/dts/bcm-nsp.dtsi b/arch/arm/boot/dts/bcm-nsp.dtsi
> new file mode 100644
> index 0000000..f5f494f
> --- /dev/null
> +++ b/arch/arm/boot/dts/bcm-nsp.dtsi
> @@ -0,0 +1,120 @@
> +/*
> + *  BSD LICENSE
> + *
> + *  Copyright(c) 2015 Broadcom Corporation.  All rights reserved.
> + *
> + *  Redistribution and use in source and binary forms, with or without
> + *  modification, are permitted provided that the following conditions
> + *  are met:
> + *
> + *    * Redistributions of source code must retain the above copyright
> + *      notice, this list of conditions and the following disclaimer.
> + *    * Redistributions in binary form must reproduce the above copyright
> + *      notice, this list of conditions and the following disclaimer in
> + *      the documentation and/or other materials provided with the
> + *      distribution.
> + *    * Neither the name of Broadcom Corporation nor the names of its
> + *      contributors may be used to endorse or promote products derived
> + *      from this software without specific prior written permission.
> + *
> + *  THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
> + *  "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
> + *  LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
> + *  A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
> + *  OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
> + *  SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
> + *  LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
> + *  DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
> + *  THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
> + *  (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
> + *  OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
> + */
> +
> +#include <dt-bindings/interrupt-controller/arm-gic.h>
> +#include <dt-bindings/interrupt-controller/irq.h>
> +
> +#include "skeleton.dtsi"
> +
> +/ {
> +	compatible = "brcm,nsp";
> +	model = "Broadcom Northstar Plus SoC";
> +	interrupt-parent = <&gic>;
> +
> +	mpcore {
> +		compatible = "simple-bus";
> +		ranges = <0x00000000 0x19020000 0x00003000>;
> +		#address-cells = <1>;
> +		#size-cells = <1>;
> +
> +		cpus {
> +			#address-cells = <1>;
> +			#size-cells = <0>;
> +
> +			cpu at 0 {
> +				device_type = "cpu";
> +				compatible = "arm,cortex-a9";
> +				next-level-cache = <&L2>;
> +				reg = <0x0>;
> +			};
> +		};
> +
> +		L2: l2-cache {
> +			compatible = "arm,pl310-cache";
> +			reg = <0x2000 0x1000>;
> +			cache-unified;
> +			cache-level = <2>;
> +		};
> +
> +		gic: interrupt-controller at 19021000 {
> +			compatible = "arm,cortex-a9-gic";
> +			#interrupt-cells = <3>;
> +			#address-cells = <0>;
> +			interrupt-controller;
> +			reg = <0x1000 0x1000>,
> +			      <0x0100 0x100>;
> +		};
> +
> +		timer at 19020200 {
> +			compatible = "arm,cortex-a9-global-timer";
> +			reg = <0x0200 0x100>;
> +			interrupts = <GIC_PPI 11 IRQ_TYPE_LEVEL_HIGH>;
> +			clocks = <&periph_clk>;
> +		};
> +	};
> +
> +	clocks {
> +		#address-cells = <1>;
> +		#size-cells = <1>;
> +		ranges;
> +
> +		periph_clk: periph_clk {
> +			compatible = "fixed-clock";
> +			#clock-cells = <0>;
> +			clock-frequency = <500000000>;
> +		};
> +	};
> +
> +	apb {
> +		compatible = "arm,amba-bus", "simple-bus";

Should "arm,amba-bus" has a separate bus node with AMBA compatible
devices declared in there (e.g, pl330, spi-pl022, and etc.) in the
future after they are brought up? To my best knowledge, "ns16550a" UART
is NOT an AMBA compatible device.

> +		interrupt-parent = <&gic>;
> +		ranges = <0x00000000 0x18000000 0x00001000>;

Does the 'apb' bus mean to cover all peripherals connected through APB?
If so, the size is only 0x1000 and that seems to be too small...

> +		#address-cells = <1>;
> +		#size-cells = <1>;
> +
> +		uart0: serial at 18000300 {
> +			compatible = "ns16550a";
> +			reg = <0x0300 0x100>;
> +			interrupts = <GIC_SPI 85 IRQ_TYPE_LEVEL_HIGH>;
> +			clock-frequency = <62499840>;
> +			status = "disabled";
> +		};
> +
> +		uart1: serial at 18000400 {
> +			compatible = "ns16550a";
> +			reg = <0x0400 0x100>;
> +			interrupts = <GIC_SPI 85 IRQ_TYPE_LEVEL_HIGH>;
> +			clock-frequency = <62499840>;
> +			status = "disabled";
> +		};
> +	};
> +};
> diff --git a/arch/arm/boot/dts/bcm958625k.dts b/arch/arm/boot/dts/bcm958625k.dts
> new file mode 100644
> index 0000000..16303db
> --- /dev/null
> +++ b/arch/arm/boot/dts/bcm958625k.dts
> @@ -0,0 +1,57 @@
> +/*
> + *  BSD LICENSE
> + *
> + *  Copyright(c) 2015 Broadcom Corporation.  All rights reserved.
> + *
> + *  Redistribution and use in source and binary forms, with or without
> + *  modification, are permitted provided that the following conditions
> + *  are met:
> + *
> + *    * Redistributions of source code must retain the above copyright
> + *      notice, this list of conditions and the following disclaimer.
> + *    * Redistributions in binary form must reproduce the above copyright
> + *      notice, this list of conditions and the following disclaimer in
> + *      the documentation and/or other materials provided with the
> + *      distribution.
> + *    * Neither the name of Broadcom Corporation nor the names of its
> + *      contributors may be used to endorse or promote products derived
> + *      from this software without specific prior written permission.
> + *
> + *  THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
> + *  "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
> + *  LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
> + *  A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
> + *  OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
> + *  SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
> + *  LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
> + *  DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
> + *  THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
> + *  (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
> + *  OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
> + */
> +
> +/dts-v1/;
> +
> +#include "bcm-nsp.dtsi"
> +
> +/ {
> +	model = "NorthStar Plus SVK (BCM958625K)";
> +	compatible = "brcm,bcm58625", "brcm,nsp";
> +
> +	aliases {
> +		serial0 = &uart0;
> +		serial1 = &uart1;
> +	};
> +
> +	chosen {
> +		stdout-path = "serial0:115200n8";
> +	};
> +};
> +
> +&uart0 {
> +	status = "okay";
> +};
> +
> +&uart1 {
> +	status = "okay";
> +};
> 


From sboyd at codeaurora.org  Fri Aug 28 17:44:10 2015
From: sboyd at codeaurora.org (Stephen Boyd)
Date: Fri, 28 Aug 2015 17:44:10 -0700
Subject: [PATCH] soc: qcom: smem: Handle big endian CPUs
Message-ID: <1440809050-8718-1-git-send-email-sboyd@codeaurora.org>

The contents of smem are always in little endian, but the smem
driver is not capable of being used on big endian CPUs. Annotate
the little endian data members and update the code to do the
proper byte swapping.

Cc: Bjorn Andersson <bjorn.andersson at sonymobile.com>
Signed-off-by: Stephen Boyd <sboyd at codeaurora.org>
---
 drivers/soc/qcom/smem.c | 230 +++++++++++++++++++++++++++++-------------------
 1 file changed, 139 insertions(+), 91 deletions(-)

diff --git a/drivers/soc/qcom/smem.c b/drivers/soc/qcom/smem.c
index 4c347e7c5880..eba4cbaaacbe 100644
--- a/drivers/soc/qcom/smem.c
+++ b/drivers/soc/qcom/smem.c
@@ -92,9 +92,9 @@
   * @params:	parameters to the command
   */
 struct smem_proc_comm {
-	u32 command;
-	u32 status;
-	u32 params[2];
+	__le32 command;
+	__le32 status;
+	__le32 params[2];
 };
 
 /**
@@ -106,10 +106,10 @@ struct smem_proc_comm {
  *		the default region. bits 0,1 are reserved
  */
 struct smem_global_entry {
-	u32 allocated;
-	u32 offset;
-	u32 size;
-	u32 aux_base; /* bits 1:0 reserved */
+	__le32 allocated;
+	__le32 offset;
+	__le32 size;
+	__le32 aux_base; /* bits 1:0 reserved */
 };
 #define AUX_BASE_MASK		0xfffffffc
 
@@ -125,11 +125,11 @@ struct smem_global_entry {
  */
 struct smem_header {
 	struct smem_proc_comm proc_comm[4];
-	u32 version[32];
-	u32 initialized;
-	u32 free_offset;
-	u32 available;
-	u32 reserved;
+	__le32 version[32];
+	__le32 initialized;
+	__le32 free_offset;
+	__le32 available;
+	__le32 reserved;
 	struct smem_global_entry toc[SMEM_ITEM_COUNT];
 };
 
@@ -143,12 +143,12 @@ struct smem_header {
  * @reserved:	reserved entries for later use
  */
 struct smem_ptable_entry {
-	u32 offset;
-	u32 size;
-	u32 flags;
-	u16 host0;
-	u16 host1;
-	u32 reserved[8];
+	__le32 offset;
+	__le32 size;
+	__le32 flags;
+	__le16 host0;
+	__le16 host1;
+	__le32 reserved[8];
 };
 
 /**
@@ -160,13 +160,14 @@ struct smem_ptable_entry {
  * @entry:	list of @smem_ptable_entry for the @num_entries partitions
  */
 struct smem_ptable {
-	u32 magic;
-	u32 version;
-	u32 num_entries;
-	u32 reserved[5];
+	u8 magic[4];
+	__le32 version;
+	__le32 num_entries;
+	__le32 reserved[5];
 	struct smem_ptable_entry entry[];
 };
-#define SMEM_PTABLE_MAGIC	0x434f5424 /* "$TOC" */
+
+static const u8 SMEM_PTABLE_MAGIC[] = { 0x24, 0x54, 0x4f, 0x43 }; /* "$TOC" */
 
 /**
  * struct smem_partition_header - header of the partitions
@@ -181,15 +182,16 @@ struct smem_ptable {
  * @reserved:	for now reserved entries
  */
 struct smem_partition_header {
-	u32 magic;
-	u16 host0;
-	u16 host1;
-	u32 size;
-	u32 offset_free_uncached;
-	u32 offset_free_cached;
-	u32 reserved[3];
+	u8 magic[4];
+	__le16 host0;
+	__le16 host1;
+	__le32 size;
+	__le32 offset_free_uncached;
+	__le32 offset_free_cached;
+	__le32 reserved[3];
 };
-#define SMEM_PART_MAGIC		0x54525024 /* "$PRT" */
+
+static const u8 SMEM_PART_MAGIC[] = { 0x24, 0x50, 0x52, 0x54 };
 
 /**
  * struct smem_private_entry - header of each item in the private partition
@@ -201,12 +203,12 @@ struct smem_partition_header {
  * @reserved:	for now reserved entry
  */
 struct smem_private_entry {
-	u16 canary;
-	u16 item;
-	u32 size; /* includes padding bytes */
-	u16 padding_data;
-	u16 padding_hdr;
-	u32 reserved;
+	u16 canary; /* bytes are the same so no swapping needed */
+	__le16 item;
+	__le32 size; /* includes padding bytes */
+	__le16 padding_data;
+	__le16 padding_hdr;
+	__le32 reserved;
 };
 #define SMEM_PRIVATE_CANARY	0xa5a5
 
@@ -242,6 +244,45 @@ struct qcom_smem {
 	struct smem_region regions[0];
 };
 
+static struct smem_private_entry *
+phdr_to_last_private_entry(struct smem_partition_header *phdr)
+{
+	void *p = phdr;
+
+	return p + le32_to_cpu(phdr->offset_free_uncached);
+}
+
+static void *phdr_to_first_cached_entry(struct smem_partition_header *phdr)
+{
+	void *p = phdr;
+
+	return p + le32_to_cpu(phdr->offset_free_cached);
+}
+
+static struct smem_private_entry *
+phdr_to_first_private_entry(struct smem_partition_header *phdr)
+{
+	void *p = phdr;
+
+	return p + sizeof(*phdr);
+}
+
+static struct smem_private_entry *
+private_entry_next(struct smem_private_entry *e)
+{
+	void *p = e;
+
+	return p + sizeof(*e) + le16_to_cpu(e->padding_hdr) +
+	       le32_to_cpu(e->size);
+}
+
+static void *entry_to_item(struct smem_private_entry *e)
+{
+	void *p = e;
+
+	return p + sizeof(*e) + le16_to_cpu(e->padding_hdr);
+}
+
 /* Pointer to the one and only smem handle */
 static struct qcom_smem *__smem;
 
@@ -254,20 +295,20 @@ static int qcom_smem_alloc_private(struct qcom_smem *smem,
 				   size_t size)
 {
 	struct smem_partition_header *phdr;
-	struct smem_private_entry *hdr;
+	struct smem_private_entry *hdr, *end;
 	size_t alloc_size;
-	void *p;
+	void *cached;
 
 	/* We're not going to find it if there's no matching partition */
 	if (host >= SMEM_HOST_COUNT || !smem->partitions[host])
 		return -ENOENT;
 
 	phdr = smem->partitions[host];
+	hdr = phdr_to_first_private_entry(phdr);
+	end = phdr_to_last_private_entry(phdr);
+	cached = phdr_to_first_cached_entry(phdr);
 
-	p = (void *)phdr + sizeof(*phdr);
-	while (p < (void *)phdr + phdr->offset_free_uncached) {
-		hdr = p;
-
+	while (hdr < end) {
 		if (hdr->canary != SMEM_PRIVATE_CANARY) {
 			dev_err(smem->dev,
 				"Found invalid canary in host %d partition\n",
@@ -275,24 +316,23 @@ static int qcom_smem_alloc_private(struct qcom_smem *smem,
 			return -EINVAL;
 		}
 
-		if (hdr->item == item)
+		if (le16_to_cpu(hdr->item) == item)
 			return -EEXIST;
 
-		p += sizeof(*hdr) + hdr->padding_hdr + hdr->size;
+		hdr = private_entry_next(hdr);
 	}
 
 	/* Check that we don't grow into the cached region */
 	alloc_size = sizeof(*hdr) + ALIGN(size, 8);
-	if (p + alloc_size >= (void *)phdr + phdr->offset_free_cached) {
+	if ((void *)hdr + alloc_size >= cached) {
 		dev_err(smem->dev, "Out of memory\n");
 		return -ENOSPC;
 	}
 
-	hdr = p;
 	hdr->canary = SMEM_PRIVATE_CANARY;
-	hdr->item = item;
-	hdr->size = ALIGN(size, 8);
-	hdr->padding_data = hdr->size - size;
+	hdr->item = cpu_to_le16(item);
+	hdr->size = cpu_to_le32(ALIGN(size, 8));
+	hdr->padding_data = cpu_to_le16(le32_to_cpu(hdr->size) - size);
 	hdr->padding_hdr = 0;
 
 	/*
@@ -301,7 +341,7 @@ static int qcom_smem_alloc_private(struct qcom_smem *smem,
 	 * gets a consistent view of the linked list.
 	 */
 	wmb();
-	phdr->offset_free_uncached += alloc_size;
+	le32_add_cpu(&phdr->offset_free_uncached, alloc_size);
 
 	return 0;
 }
@@ -322,11 +362,11 @@ static int qcom_smem_alloc_global(struct qcom_smem *smem,
 		return -EEXIST;
 
 	size = ALIGN(size, 8);
-	if (WARN_ON(size > header->available))
+	if (WARN_ON(size > le32_to_cpu(header->available)))
 		return -ENOMEM;
 
 	entry->offset = header->free_offset;
-	entry->size = size;
+	entry->size = cpu_to_le32(size);
 
 	/*
 	 * Ensure the header is consistent before we mark the item allocated,
@@ -334,10 +374,10 @@ static int qcom_smem_alloc_global(struct qcom_smem *smem,
 	 * even though they do not take the spinlock on read.
 	 */
 	wmb();
-	entry->allocated = 1;
+	entry->allocated = cpu_to_le32(1);
 
-	header->free_offset += size;
-	header->available -= size;
+	le32_add_cpu(&header->free_offset, size);
+	le32_add_cpu(&header->available, -size);
 
 	return 0;
 }
@@ -401,19 +441,20 @@ static int qcom_smem_get_global(struct qcom_smem *smem,
 		return -ENXIO;
 
 	if (ptr != NULL) {
-		aux_base = entry->aux_base & AUX_BASE_MASK;
+		aux_base = le32_to_cpu(entry->aux_base) & AUX_BASE_MASK;
 
 		for (i = 0; i < smem->num_regions; i++) {
 			area = &smem->regions[i];
 
 			if (area->aux_base == aux_base || !aux_base) {
-				*ptr = area->virt_base + entry->offset;
+				*ptr = area->virt_base +
+				       le32_to_cpu(entry->offset);
 				break;
 			}
 		}
 	}
 	if (size != NULL)
-		*size = entry->size;
+		*size = le32_to_cpu(entry->size);
 
 	return 0;
 }
@@ -425,37 +466,36 @@ static int qcom_smem_get_private(struct qcom_smem *smem,
 				 size_t *size)
 {
 	struct smem_partition_header *phdr;
-	struct smem_private_entry *hdr;
-	void *p;
+	struct smem_private_entry *e, *end;
 
 	/* We're not going to find it if there's no matching partition */
 	if (host >= SMEM_HOST_COUNT || !smem->partitions[host])
 		return -ENOENT;
 
 	phdr = smem->partitions[host];
+	e = phdr_to_first_private_entry(phdr);
+	end = phdr_to_last_private_entry(phdr);
 
-	p = (void *)phdr + sizeof(*phdr);
-	while (p < (void *)phdr + phdr->offset_free_uncached) {
-		hdr = p;
-
-		if (hdr->canary != SMEM_PRIVATE_CANARY) {
+	while (e < end) {
+		if (e->canary != SMEM_PRIVATE_CANARY) {
 			dev_err(smem->dev,
 				"Found invalid canary in host %d partition\n",
 				host);
 			return -EINVAL;
 		}
 
-		if (hdr->item == item) {
+		if (le16_to_cpu(e->item) == item) {
 			if (ptr != NULL)
-				*ptr = p + sizeof(*hdr) + hdr->padding_hdr;
+				*ptr = entry_to_item(e);
 
 			if (size != NULL)
-				*size = hdr->size - hdr->padding_data;
+				*size = le32_to_cpu(e->size) -
+					le16_to_cpu(e->padding_data);
 
 			return 0;
 		}
 
-		p += sizeof(*hdr) + hdr->padding_hdr + hdr->size;
+		e = private_entry_next(e);
 	}
 
 	return -ENOENT;
@@ -513,10 +553,11 @@ int qcom_smem_get_free_space(unsigned host)
 
 	if (host < SMEM_HOST_COUNT && __smem->partitions[host]) {
 		phdr = __smem->partitions[host];
-		ret = phdr->offset_free_cached - phdr->offset_free_uncached;
+		ret = le32_to_cpu(phdr->offset_free_cached) -
+		      le32_to_cpu(phdr->offset_free_uncached);
 	} else {
 		header = __smem->regions[0].virt_base;
-		ret = header->available;
+		ret = le32_to_cpu(header->available);
 	}
 
 	return ret;
@@ -525,7 +566,7 @@ EXPORT_SYMBOL(qcom_smem_get_free_space);
 
 static int qcom_smem_get_sbl_version(struct qcom_smem *smem)
 {
-	unsigned *versions;
+	__le32 *versions;
 	size_t size;
 	int ret;
 
@@ -541,7 +582,7 @@ static int qcom_smem_get_sbl_version(struct qcom_smem *smem)
 		return -EINVAL;
 	}
 
-	return versions[SMEM_MASTER_SBL_VERSION_INDEX];
+	return le32_to_cpu(versions[SMEM_MASTER_SBL_VERSION_INDEX]);
 }
 
 static int qcom_smem_enumerate_partitions(struct qcom_smem *smem,
@@ -551,35 +592,38 @@ static int qcom_smem_enumerate_partitions(struct qcom_smem *smem,
 	struct smem_ptable_entry *entry;
 	struct smem_ptable *ptable;
 	unsigned remote_host;
+	u32 version, host0, host1;
 	int i;
 
 	ptable = smem->regions[0].virt_base + smem->regions[0].size - SZ_4K;
-	if (ptable->magic != SMEM_PTABLE_MAGIC)
+	if (memcmp(ptable->magic, SMEM_PTABLE_MAGIC, sizeof(ptable->magic)))
 		return 0;
 
-	if (ptable->version != 1) {
+	version = le32_to_cpu(ptable->version);
+	if (version != 1) {
 		dev_err(smem->dev,
-			"Unsupported partition header version %d\n",
-			ptable->version);
+			"Unsupported partition header version %d\n", version);
 		return -EINVAL;
 	}
 
-	for (i = 0; i < ptable->num_entries; i++) {
+	for (i = 0; i < le32_to_cpu(ptable->num_entries); i++) {
 		entry = &ptable->entry[i];
+		host0 = le16_to_cpu(entry->host0);
+		host1 = le16_to_cpu(entry->host1);
 
-		if (entry->host0 != local_host && entry->host1 != local_host)
+		if (host0 != local_host && host1 != local_host)
 			continue;
 
-		if (!entry->offset)
+		if (!le32_to_cpu(entry->offset))
 			continue;
 
-		if (!entry->size)
+		if (!le32_to_cpu(entry->size))
 			continue;
 
-		if (entry->host0 == local_host)
-			remote_host = entry->host1;
+		if (host0 == local_host)
+			remote_host = host1;
 		else
-			remote_host = entry->host0;
+			remote_host = host0;
 
 		if (remote_host >= SMEM_HOST_COUNT) {
 			dev_err(smem->dev,
@@ -595,21 +639,24 @@ static int qcom_smem_enumerate_partitions(struct qcom_smem *smem,
 			return -EINVAL;
 		}
 
-		header = smem->regions[0].virt_base + entry->offset;
+		header = smem->regions[0].virt_base + le32_to_cpu(entry->offset);
+		host0 = le16_to_cpu(header->host0);
+		host1 = le16_to_cpu(header->host1);
 
-		if (header->magic != SMEM_PART_MAGIC) {
+		if (memcmp(header->magic, SMEM_PART_MAGIC,
+			    sizeof(header->magic))) {
 			dev_err(smem->dev,
 				"Partition %d has invalid magic\n", i);
 			return -EINVAL;
 		}
 
-		if (header->host0 != local_host && header->host1 != local_host) {
+		if (host0 != local_host && host1 != local_host) {
 			dev_err(smem->dev,
 				"Partition %d hosts are invalid\n", i);
 			return -EINVAL;
 		}
 
-		if (header->host0 != remote_host && header->host1 != remote_host) {
+		if (host0 != remote_host && host1 != remote_host) {
 			dev_err(smem->dev,
 				"Partition %d hosts are invalid\n", i);
 			return -EINVAL;
@@ -621,7 +668,7 @@ static int qcom_smem_enumerate_partitions(struct qcom_smem *smem,
 			return -EINVAL;
 		}
 
-		if (header->offset_free_uncached > header->size) {
+		if (le32_to_cpu(header->offset_free_uncached) > le32_to_cpu(header->size)) {
 			dev_err(smem->dev,
 				"Partition %d has invalid free pointer\n", i);
 			return -EINVAL;
@@ -705,7 +752,8 @@ static int qcom_smem_probe(struct platform_device *pdev)
 	}
 
 	header = smem->regions[0].virt_base;
-	if (header->initialized != 1 || header->reserved) {
+	if (le32_to_cpu(header->initialized) != 1 ||
+	    le32_to_cpu(header->reserved)) {
 		dev_err(&pdev->dev, "SMEM is not initialized by SBL\n");
 		return -EINVAL;
 	}
-- 
The Qualcomm Innovation Center, Inc. is a member of the Code Aurora Forum,
a Linux Foundation Collaborative Project



From stefan at agner.ch  Fri Aug 28 18:08:19 2015
From: stefan at agner.ch (Stefan Agner)
Date: Fri, 28 Aug 2015 18:08:19 -0700
Subject: [PATCH] remoteproc: report error if resource table doesn't exist
Message-ID: <1440810499-24327-1-git-send-email-stefan@agner.ch>

Currently, if the resource table is completely missing in the
firmware, powering up the remoteproc fails silently. Add a message
indicating that the resource table is missing in the firmware.

Signed-off-by: Stefan Agner <stefan at agner.ch>
---
Hi Ohad,

I am currently working on remoteproc support for Freescale Vybrid's
secondary Cortex-M4 core. I stumbled upon this rough spot since the
little test firmware I am using now does not have a resource table
yet.

This also opens up a more general question: Is it mandatory to have
a resource table in the firmware? Theoretically a remoteproc could
also work completely independent, all what would be used from the
remoteproc framework is the loading and starting capabilities...

--
Stefan

 drivers/remoteproc/remoteproc_core.c | 4 +++-
 1 file changed, 3 insertions(+), 1 deletion(-)

diff --git a/drivers/remoteproc/remoteproc_core.c b/drivers/remoteproc/remoteproc_core.c
index 8b3130f..29db8b3 100644
--- a/drivers/remoteproc/remoteproc_core.c
+++ b/drivers/remoteproc/remoteproc_core.c
@@ -823,8 +823,10 @@ static int rproc_fw_boot(struct rproc *rproc, const struct firmware *fw)
 
 	/* look for the resource table */
 	table = rproc_find_rsc_table(rproc, fw, &tablesz);
-	if (!table)
+	if (!table) {
+		dev_err(dev, "Failed to find resource table\n");
 		goto clean_up;
+	}
 
 	/* Verify that resource table in loaded fw is unchanged */
 	if (rproc->table_csum != crc32(0, table, tablesz)) {
-- 
2.5.0



From klimov.linux at gmail.com  Fri Aug 28 18:45:03 2015
From: klimov.linux at gmail.com (Alexey Klimov)
Date: Sat, 29 Aug 2015 04:45:03 +0300
Subject: [PATCH net-next 7/8] net: thunderx: Support for upto 96 queues
 for a VF
In-Reply-To: <1440774004-27923-7-git-send-email-aleksey.makarov@auriga.com>
References: <1440774004-27923-1-git-send-email-aleksey.makarov@auriga.com>
 <1440774004-27923-7-git-send-email-aleksey.makarov@auriga.com>
Message-ID: <CALW4P+KVjSFA3F+9wHTMiyMHkFjrbedP2LpUu033-o0k32F0nw@mail.gmail.com>

On Fri, Aug 28, 2015 at 5:59 PM, Aleksey Makarov
<aleksey.makarov at auriga.com> wrote:
> From: Sunil Goutham <sgoutham at cavium.com>
>
> This patch adds support for handling multiple qsets assigned to a
> single VF. There by increasing no of queues from earlier 8 to max
> no of CPUs in the system i.e 48 queues on a single node and 96 on
> dual node system. User doesn't have option to assign which Qsets/VFs
>  to be merged. Upon request from VF, PF assigns next free Qsets as
> secondary qsets. To maintain current behavior no of queues is kept
> to 8 by default which can be increased via ethtool.
>
> If user wants to unbind NICVF driver from a secondary Qset then it
> should be done after tearing down primary VF's interface.
>
> Signed-off-by: Sunil Goutham <sgoutham at cavium.com>
> Signed-off-by: Aleksey Makarov <aleksey.makarov at caviumnetworks.com>
> Signed-off-by: Robert Richter <rrichter at cavium.com>
> ---
>  drivers/net/ethernet/cavium/thunder/nic.h          |  42 ++++-
>  drivers/net/ethernet/cavium/thunder/nic_main.c     | 173 +++++++++++++++--
>  .../net/ethernet/cavium/thunder/nicvf_ethtool.c    | 136 +++++++++----
>  drivers/net/ethernet/cavium/thunder/nicvf_main.c   | 210 +++++++++++++++++++--
>  drivers/net/ethernet/cavium/thunder/nicvf_queues.c |  32 +++-
>  5 files changed, 507 insertions(+), 86 deletions(-)
>
> diff --git a/drivers/net/ethernet/cavium/thunder/nic.h b/drivers/net/ethernet/cavium/thunder/nic.h
> index 89b997e..35b2ee1 100644
> --- a/drivers/net/ethernet/cavium/thunder/nic.h
> +++ b/drivers/net/ethernet/cavium/thunder/nic.h
> @@ -258,13 +258,23 @@ struct nicvf_drv_stats {
>  };
>
>  struct nicvf {
> +       struct nicvf            *pnicvf;
>         struct net_device       *netdev;
>         struct pci_dev          *pdev;
>         u8                      vf_id;
>         u8                      node;
> -       u8                      tns_mode;
> +       u8                      tns_mode:1;
> +       u8                      sqs_mode:1;
>         u16                     mtu;
>         struct queue_set        *qs;
> +#define        MAX_SQS_PER_VF_SINGLE_NODE              5
> +#define        MAX_SQS_PER_VF                          11
> +       u8                      sqs_id;
> +       u8                      sqs_count; /* Secondary Qset count */
> +       struct nicvf            *snicvf[MAX_SQS_PER_VF];
> +       u8                      rx_queues;
> +       u8                      tx_queues;
> +       u8                      max_queues;
>         void __iomem            *reg_base;
>         bool                    link_up;
>         u8                      duplex;
> @@ -330,14 +340,19 @@ struct nicvf {
>  #define        NIC_MBOX_MSG_RQ_SW_SYNC         0x0F    /* Flush inflight pkts to RQ */
>  #define        NIC_MBOX_MSG_BGX_STATS          0x10    /* Get stats from BGX */
>  #define        NIC_MBOX_MSG_BGX_LINK_CHANGE    0x11    /* BGX:LMAC link status */
> -#define NIC_MBOX_MSG_CFG_DONE          0x12    /* VF configuration done */
> -#define NIC_MBOX_MSG_SHUTDOWN          0x13    /* VF is being shutdown */
> +#define        NIC_MBOX_MSG_ALLOC_SQS          0x12    /* Allocate secondary Qset */
> +#define        NIC_MBOX_MSG_NICVF_PTR          0x13    /* Send nicvf ptr to PF */
> +#define        NIC_MBOX_MSG_PNICVF_PTR         0x14    /* Get primary qset nicvf ptr */
> +#define        NIC_MBOX_MSG_SNICVF_PTR         0x15    /* Send sqet nicvf ptr to PVF */
> +#define        NIC_MBOX_MSG_CFG_DONE           0xF0    /* VF configuration done */
> +#define        NIC_MBOX_MSG_SHUTDOWN           0xF1    /* VF is being shutdown */
>
>  struct nic_cfg_msg {
>         u8    msg;
>         u8    vf_id;
> -       u8    tns_mode;
>         u8    node_id;
> +       u8    tns_mode:1;
> +       u8    sqs_mode:1;
>         u8    mac_addr[ETH_ALEN];
>  };
>
> @@ -345,6 +360,7 @@ struct nic_cfg_msg {
>  struct qs_cfg_msg {
>         u8    msg;
>         u8    num;
> +       u8    sqs_count;
>         u64   cfg;
>  };
>
> @@ -361,6 +377,7 @@ struct sq_cfg_msg {
>         u8    msg;
>         u8    qs_num;
>         u8    sq_num;
> +       bool  sqs_mode;
>         u64   cfg;
>  };
>
> @@ -420,6 +437,21 @@ struct bgx_link_status {
>         u32   speed;
>  };
>
> +/* Get Extra Qset IDs */
> +struct sqs_alloc {
> +       u8    msg;
> +       u8    vf_id;
> +       u8    qs_count;
> +};
> +
> +struct nicvf_ptr {
> +       u8    msg;
> +       u8    vf_id;
> +       bool  sqs_mode;
> +       u8    sqs_id;
> +       u64   nicvf;
> +};
> +
>  /* 128 bit shared memory between PF and each VF */
>  union nic_mbx {
>         struct { u8 msg; }      msg;
> @@ -434,6 +466,8 @@ union nic_mbx {
>         struct rss_cfg_msg      rss_cfg;
>         struct bgx_stats_msg    bgx_stats;
>         struct bgx_link_status  link_status;
> +       struct sqs_alloc        sqs_alloc;
> +       struct nicvf_ptr        nicvf;
>  };
>
>  #define NIC_NODE_ID_MASK       0x03
> diff --git a/drivers/net/ethernet/cavium/thunder/nic_main.c b/drivers/net/ethernet/cavium/thunder/nic_main.c
> index 7dfec4a..51f3048 100644
> --- a/drivers/net/ethernet/cavium/thunder/nic_main.c
> +++ b/drivers/net/ethernet/cavium/thunder/nic_main.c
> @@ -28,6 +28,11 @@ struct nicpf {
>         u8                      num_vf_en;      /* No of VF enabled */
>         bool                    vf_enabled[MAX_NUM_VFS_SUPPORTED];
>         void __iomem            *reg_base;       /* Register start address */
> +       u8                      num_sqs_en;     /* Secondary qsets enabled */
> +       u64                     nicvf[MAX_NUM_VFS_SUPPORTED];
> +       u8                      vf_sqs[MAX_NUM_VFS_SUPPORTED][MAX_SQS_PER_VF];
> +       u8                      pqs_vf[MAX_NUM_VFS_SUPPORTED];
> +       bool                    sqs_used[MAX_NUM_VFS_SUPPORTED];
>         struct pkind_cfg        pkind;
>  #define        NIC_SET_VF_LMAC_MAP(bgx, lmac)  (((bgx & 0xF) << 4) | (lmac & 0xF))
>  #define        NIC_GET_BGX_FROM_VF_LMAC_MAP(map)       ((map >> 4) & 0xF)
> @@ -139,13 +144,15 @@ static void nic_mbx_send_ready(struct nicpf *nic, int vf)
>
>         mbx.nic_cfg.tns_mode = NIC_TNS_BYPASS_MODE;
>
> -       bgx_idx = NIC_GET_BGX_FROM_VF_LMAC_MAP(nic->vf_lmac_map[vf]);
> -       lmac = NIC_GET_LMAC_FROM_VF_LMAC_MAP(nic->vf_lmac_map[vf]);
> -
> -       mac = bgx_get_lmac_mac(nic->node, bgx_idx, lmac);
> -       if (mac)
> -               ether_addr_copy((u8 *)&mbx.nic_cfg.mac_addr, mac);
> +       if (vf < MAX_LMAC) {
> +               bgx_idx = NIC_GET_BGX_FROM_VF_LMAC_MAP(nic->vf_lmac_map[vf]);
> +               lmac = NIC_GET_LMAC_FROM_VF_LMAC_MAP(nic->vf_lmac_map[vf]);
>
> +               mac = bgx_get_lmac_mac(nic->node, bgx_idx, lmac);
> +               if (mac)
> +                       ether_addr_copy((u8 *)&mbx.nic_cfg.mac_addr, mac);
> +       }
> +       mbx.nic_cfg.sqs_mode = (vf >= nic->num_vf_en) ? true : false;
>         mbx.nic_cfg.node_id = nic->node;
>         nic_send_msg_to_vf(nic, vf, &mbx);
>  }
> @@ -433,6 +440,12 @@ static void nic_config_rss(struct nicpf *nic, struct rss_cfg_msg *cfg)
>         qset = cfg->vf_id;
>
>         for (; rssi < (rssi_base + cfg->tbl_len); rssi++) {
> +               u8 svf = cfg->ind_tbl[idx] >> 3;
> +
> +               if (svf)
> +                       qset = nic->vf_sqs[cfg->vf_id][svf - 1];
> +               else
> +                       qset = cfg->vf_id;
>                 nic_reg_write(nic, NIC_PF_RSSI_0_4097_RQ | (rssi << 3),
>                               (qset << 3) | (cfg->ind_tbl[idx] & 0x7));
>                 idx++;
> @@ -456,19 +469,31 @@ static void nic_config_rss(struct nicpf *nic, struct rss_cfg_msg *cfg)
>   * VNIC6-SQ0 -> TL4(528) -> TL3[132] -> TL2[33] -> TL1[1] -> BGX1
>   * VNIC7-SQ0 -> TL4(536) -> TL3[134] -> TL2[33] -> TL1[1] -> BGX1
>   */
> -static void nic_tx_channel_cfg(struct nicpf *nic, u8 vnic, u8 sq_idx)
> +static void nic_tx_channel_cfg(struct nicpf *nic, u8 vnic,
> +                              struct sq_cfg_msg *sq)
>  {
>         u32 bgx, lmac, chan;
>         u32 tl2, tl3, tl4;
>         u32 rr_quantum;
> +       u8 sq_idx = sq->sq_num;
> +       u8 pqs_vnic;
> +
> +       if (sq->sqs_mode)
> +               pqs_vnic = nic->pqs_vf[vnic];
> +       else
> +               pqs_vnic = vnic;
> +
> +       bgx = NIC_GET_BGX_FROM_VF_LMAC_MAP(nic->vf_lmac_map[pqs_vnic]);
> +       lmac = NIC_GET_LMAC_FROM_VF_LMAC_MAP(nic->vf_lmac_map[pqs_vnic]);
>
> -       bgx = NIC_GET_BGX_FROM_VF_LMAC_MAP(nic->vf_lmac_map[vnic]);
> -       lmac = NIC_GET_LMAC_FROM_VF_LMAC_MAP(nic->vf_lmac_map[vnic]);
>         /* 24 bytes for FCS, IPG and preamble */
>         rr_quantum = ((NIC_HW_MAX_FRS + 24) / 4);
>
>         tl4 = (lmac * NIC_TL4_PER_LMAC) + (bgx * NIC_TL4_PER_BGX);
>         tl4 += sq_idx;
> +       if (sq->sqs_mode)
> +               tl4 += vnic * 8;
> +
>         tl3 = tl4 / (NIC_MAX_TL4 / NIC_MAX_TL3);
>         nic_reg_write(nic, NIC_PF_QSET_0_127_SQ_0_7_CFG2 |
>                       ((u64)vnic << NIC_QS_ID_SHIFT) |
> @@ -489,6 +514,71 @@ static void nic_tx_channel_cfg(struct nicpf *nic, u8 vnic, u8 sq_idx)
>         nic_reg_write(nic, NIC_PF_TL2_0_63_PRI | (tl2 << 3), 0x00);
>  }
>
> +/* Send primary nicvf pointer to secondary QS's VF */
> +static void nic_send_pnicvf(struct nicpf *nic, int sqs)
> +{
> +       union nic_mbx mbx = {};
> +
> +       mbx.nicvf.msg = NIC_MBOX_MSG_PNICVF_PTR;
> +       mbx.nicvf.nicvf = nic->nicvf[nic->pqs_vf[sqs]];
> +       nic_send_msg_to_vf(nic, sqs, &mbx);
> +}
> +
> +/* Send SQS's nicvf pointer to primary QS's VF */
> +static void nic_send_snicvf(struct nicpf *nic, struct nicvf_ptr *nicvf)
> +{
> +       union nic_mbx mbx = {};
> +       int sqs_id = nic->vf_sqs[nicvf->vf_id][nicvf->sqs_id];
> +
> +       mbx.nicvf.msg = NIC_MBOX_MSG_SNICVF_PTR;
> +       mbx.nicvf.sqs_id = nicvf->sqs_id;
> +       mbx.nicvf.nicvf = nic->nicvf[sqs_id];
> +       nic_send_msg_to_vf(nic, nicvf->vf_id, &mbx);
> +}
> +
> +/* Find next available Qset that can be assigned as a
> + * secondary Qset to a VF.
> + */
> +static int nic_nxt_avail_sqs(struct nicpf *nic)
> +{
> +       int sqs;
> +
> +       for (sqs = 0; sqs < nic->num_sqs_en; sqs++) {
> +               if (!nic->sqs_used[sqs])
> +                       nic->sqs_used[sqs] = true;
> +               else
> +                       continue;
> +               return sqs + nic->num_vf_en;
> +       }
> +       return -1;
> +}
> +
> +/* Allocate additional Qsets for requested VF */
> +static void nic_alloc_sqs(struct nicpf *nic, struct sqs_alloc *sqs)
> +{
> +       union nic_mbx mbx = {};
> +       int idx, alloc_qs = 0;
> +       int sqs_id;
> +
> +       if (!nic->num_sqs_en)
> +               goto send_mbox;
> +
> +       for (idx = 0; idx < sqs->qs_count; idx++) {
> +               sqs_id = nic_nxt_avail_sqs(nic);
> +               if (sqs_id < 0)
> +                       break;
> +               nic->vf_sqs[sqs->vf_id][idx] = sqs_id;
> +               nic->pqs_vf[sqs_id] = sqs->vf_id;
> +               alloc_qs++;
> +       }
> +
> +send_mbox:
> +       mbx.sqs_alloc.msg = NIC_MBOX_MSG_ALLOC_SQS;
> +       mbx.sqs_alloc.vf_id = sqs->vf_id;
> +       mbx.sqs_alloc.qs_count = alloc_qs;
> +       nic_send_msg_to_vf(nic, sqs->vf_id, &mbx);
> +}
> +
>  /* Interrupt handler to handle mailbox messages from VFs */
>  static void nic_handle_mbx_intr(struct nicpf *nic, int vf)
>  {
> @@ -496,6 +586,7 @@ static void nic_handle_mbx_intr(struct nicpf *nic, int vf)
>         u64 *mbx_data;
>         u64 mbx_addr;
>         u64 reg_addr;
> +       u64 cfg;
>         int bgx, lmac;
>         int i;
>         int ret = 0;
> @@ -516,15 +607,24 @@ static void nic_handle_mbx_intr(struct nicpf *nic, int vf)
>         switch (mbx.msg.msg) {
>         case NIC_MBOX_MSG_READY:
>                 nic_mbx_send_ready(nic, vf);
> -               nic->link[vf] = 0;
> -               nic->duplex[vf] = 0;
> -               nic->speed[vf] = 0;
> +               if (vf < MAX_LMAC) {
> +                       nic->link[vf] = 0;
> +                       nic->duplex[vf] = 0;
> +                       nic->speed[vf] = 0;
> +               }
>                 ret = 1;
>                 break;
>         case NIC_MBOX_MSG_QS_CFG:
>                 reg_addr = NIC_PF_QSET_0_127_CFG |
>                            (mbx.qs.num << NIC_QS_ID_SHIFT);
> -               nic_reg_write(nic, reg_addr, mbx.qs.cfg);
> +               cfg = mbx.qs.cfg;
> +               /* Check if its a secondary Qset */
> +               if (vf >= nic->num_vf_en) {
> +                       cfg = cfg & (~0x7FULL);
> +                       /* Assign this Qset to primary Qset's VF */
> +                       cfg |= nic->pqs_vf[vf];
> +               }
> +               nic_reg_write(nic, reg_addr, cfg);
>                 break;
>         case NIC_MBOX_MSG_RQ_CFG:
>                 reg_addr = NIC_PF_QSET_0_127_RQ_0_7_CFG |
> @@ -552,9 +652,11 @@ static void nic_handle_mbx_intr(struct nicpf *nic, int vf)
>                            (mbx.sq.qs_num << NIC_QS_ID_SHIFT) |
>                            (mbx.sq.sq_num << NIC_Q_NUM_SHIFT);
>                 nic_reg_write(nic, reg_addr, mbx.sq.cfg);
> -               nic_tx_channel_cfg(nic, mbx.qs.num, mbx.sq.sq_num);
> +               nic_tx_channel_cfg(nic, mbx.qs.num, &mbx.sq);
>                 break;
>         case NIC_MBOX_MSG_SET_MAC:
> +               if (vf >= nic->num_vf_en)
> +                       break;
>                 lmac = mbx.mac.vf_id;
>                 bgx = NIC_GET_BGX_FROM_VF_LMAC_MAP(nic->vf_lmac_map[lmac]);
>                 lmac = NIC_GET_LMAC_FROM_VF_LMAC_MAP(nic->vf_lmac_map[lmac]);
> @@ -581,7 +683,22 @@ static void nic_handle_mbx_intr(struct nicpf *nic, int vf)
>         case NIC_MBOX_MSG_SHUTDOWN:
>                 /* First msg in VF teardown sequence */
>                 nic->vf_enabled[vf] = false;
> +               if (vf >= nic->num_vf_en)
> +                       nic->sqs_used[vf - nic->num_vf_en] = false;
> +               nic->pqs_vf[vf] = 0;
> +               break;
> +       case NIC_MBOX_MSG_ALLOC_SQS:
> +               nic_alloc_sqs(nic, &mbx.sqs_alloc);
> +               goto unlock;
> +       case NIC_MBOX_MSG_NICVF_PTR:
> +               nic->nicvf[vf] = mbx.nicvf.nicvf;
>                 break;
> +       case NIC_MBOX_MSG_PNICVF_PTR:
> +               nic_send_pnicvf(nic, vf);
> +               goto unlock;
> +       case NIC_MBOX_MSG_SNICVF_PTR:
> +               nic_send_snicvf(nic, &mbx.nicvf);
> +               goto unlock;
>         case NIC_MBOX_MSG_BGX_STATS:
>                 nic_get_bgx_stats(nic, &mbx.bgx_stats);
>                 goto unlock;
> @@ -610,8 +727,7 @@ static void nic_mbx_intr_handler (struct nicpf *nic, int mbx)
>                 if (intr & (1ULL << vf)) {
>                         dev_dbg(&nic->pdev->dev, "Intr from VF %d\n",
>                                 vf + (mbx * vf_per_mbx_reg));
> -                       if ((vf + (mbx * vf_per_mbx_reg)) > nic->num_vf_en)
> -                               break;
> +
>                         nic_handle_mbx_intr(nic, vf + (mbx * vf_per_mbx_reg));
>                         nic_clear_mbx_intr(nic, vf, mbx);
>                 }
> @@ -717,9 +833,24 @@ static void nic_unregister_interrupts(struct nicpf *nic)
>         nic_disable_msix(nic);
>  }
>
> +static int nic_num_sqs_en(struct nicpf *nic, int vf_en)
> +{
> +       int pos = 0, sqs_per_vf = MAX_SQS_PER_VF_SINGLE_NODE;

Please check if you really need to initialize 'pos' by zero here.


> +       u16 total_vf;
> +
> +       /* Check if its a multi-node environment */
> +       if (nr_node_ids > 1)
> +               sqs_per_vf = MAX_SQS_PER_VF;
> +
> +       pos = pci_find_ext_capability(nic->pdev, PCI_EXT_CAP_ID_SRIOV);
> +       pci_read_config_word(nic->pdev, (pos + PCI_SRIOV_TOTAL_VF), &total_vf);
> +       return min(total_vf - vf_en, vf_en * sqs_per_vf);
> +}
> +
>  static int nic_sriov_init(struct pci_dev *pdev, struct nicpf *nic)
>  {
>         int pos = 0;
> +       int vf_en;
>         int err;
>         u16 total_vf_cnt;
>
> @@ -736,16 +867,20 @@ static int nic_sriov_init(struct pci_dev *pdev, struct nicpf *nic)
>         if (!total_vf_cnt)
>                 return 0;
>
> -       err = pci_enable_sriov(pdev, nic->num_vf_en);
> +       vf_en = nic->num_vf_en;
> +       nic->num_sqs_en = nic_num_sqs_en(nic, nic->num_vf_en);
> +       vf_en += nic->num_sqs_en;
> +
> +       err = pci_enable_sriov(pdev, vf_en);
>         if (err) {
>                 dev_err(&pdev->dev, "SRIOV enable failed, num VF is %d\n",
> -                       nic->num_vf_en);
> +                       vf_en);
>                 nic->num_vf_en = 0;
>                 return err;
>         }
>
>         dev_info(&pdev->dev, "SRIOV enabled, number of VF available %d\n",
> -                nic->num_vf_en);
> +                vf_en);
>
>         nic->flags |= NIC_SRIOV_ENABLED;
>         return 0;
> diff --git a/drivers/net/ethernet/cavium/thunder/nicvf_ethtool.c b/drivers/net/ethernet/cavium/thunder/nicvf_ethtool.c
> index 1eec2cd..e4fa98a 100644
> --- a/drivers/net/ethernet/cavium/thunder/nicvf_ethtool.c
> +++ b/drivers/net/ethernet/cavium/thunder/nicvf_ethtool.c
> @@ -149,10 +149,33 @@ static void nicvf_set_msglevel(struct net_device *netdev, u32 lvl)
>         nic->msg_enable = lvl;
>  }
>
> +static void nicvf_get_qset_strings(struct nicvf *nic, u8 **data, int qset)
> +{
> +       int stats, qidx;
> +       int start_qidx = qset * MAX_RCV_QUEUES_PER_QS;
> +
> +       for (qidx = 0; qidx < nic->qs->rq_cnt; qidx++) {
> +               for (stats = 0; stats < nicvf_n_queue_stats; stats++) {
> +                       sprintf(*data, "rxq%d: %s", qidx + start_qidx,
> +                               nicvf_queue_stats[stats].name);
> +                       *data += ETH_GSTRING_LEN;
> +               }
> +       }
> +
> +       for (qidx = 0; qidx < nic->qs->sq_cnt; qidx++) {
> +               for (stats = 0; stats < nicvf_n_queue_stats; stats++) {
> +                       sprintf(*data, "txq%d: %s", qidx + start_qidx,
> +                               nicvf_queue_stats[stats].name);
> +                       *data += ETH_GSTRING_LEN;
> +               }
> +       }
> +}
> +
>  static void nicvf_get_strings(struct net_device *netdev, u32 sset, u8 *data)
>  {
>         struct nicvf *nic = netdev_priv(netdev);
> -       int stats, qidx;
> +       int stats;
> +       int sqs;
>
>         if (sset != ETH_SS_STATS)
>                 return;
> @@ -167,20 +190,12 @@ static void nicvf_get_strings(struct net_device *netdev, u32 sset, u8 *data)
>                 data += ETH_GSTRING_LEN;
>         }
>
> -       for (qidx = 0; qidx < nic->qs->rq_cnt; qidx++) {
> -               for (stats = 0; stats < nicvf_n_queue_stats; stats++) {
> -                       sprintf(data, "rxq%d: %s", qidx,
> -                               nicvf_queue_stats[stats].name);
> -                       data += ETH_GSTRING_LEN;
> -               }
> -       }
> +       nicvf_get_qset_strings(nic, &data, 0);
>
> -       for (qidx = 0; qidx < nic->qs->sq_cnt; qidx++) {
> -               for (stats = 0; stats < nicvf_n_queue_stats; stats++) {
> -                       sprintf(data, "txq%d: %s", qidx,
> -                               nicvf_queue_stats[stats].name);
> -                       data += ETH_GSTRING_LEN;
> -               }
> +       for (sqs = 0; sqs < nic->sqs_count; sqs++) {
> +               if (!nic->snicvf[sqs])
> +                       continue;
> +               nicvf_get_qset_strings(nic->snicvf[sqs], &data, sqs + 1);
>         }
>
>         for (stats = 0; stats < BGX_RX_STATS_COUNT; stats++) {
> @@ -197,21 +212,58 @@ static void nicvf_get_strings(struct net_device *netdev, u32 sset, u8 *data)
>  static int nicvf_get_sset_count(struct net_device *netdev, int sset)
>  {
>         struct nicvf *nic = netdev_priv(netdev);
> +       int qstats_count;
> +       int sqs;
>
>         if (sset != ETH_SS_STATS)
>                 return -EINVAL;
>
> +       qstats_count = nicvf_n_queue_stats *
> +                      (nic->qs->rq_cnt + nic->qs->sq_cnt);
> +       for (sqs = 0; sqs < nic->sqs_count; sqs++) {
> +               struct nicvf *snic;
> +
> +               snic = nic->snicvf[sqs];
> +               if (!snic)
> +                       continue;
> +               qstats_count += nicvf_n_queue_stats *
> +                               (snic->qs->rq_cnt + snic->qs->sq_cnt);
> +       }
> +
>         return nicvf_n_hw_stats + nicvf_n_drv_stats +
> -               (nicvf_n_queue_stats *
> -                (nic->qs->rq_cnt + nic->qs->sq_cnt)) +
> +               qstats_count +
>                 BGX_RX_STATS_COUNT + BGX_TX_STATS_COUNT;
>  }
>
> +static void nicvf_get_qset_stats(struct nicvf *nic,
> +                                struct ethtool_stats *stats, u64 **data)
> +{
> +       int stat, qidx;
> +
> +       if (!nic)
> +               return;
> +
> +       for (qidx = 0; qidx < nic->qs->rq_cnt; qidx++) {
> +               nicvf_update_rq_stats(nic, qidx);
> +               for (stat = 0; stat < nicvf_n_queue_stats; stat++)
> +                       *((*data)++) = ((u64 *)&nic->qs->rq[qidx].stats)
> +                                       [nicvf_queue_stats[stat].index];
> +       }
> +
> +       for (qidx = 0; qidx < nic->qs->sq_cnt; qidx++) {
> +               nicvf_update_sq_stats(nic, qidx);
> +               for (stat = 0; stat < nicvf_n_queue_stats; stat++)
> +                       *((*data)++) = ((u64 *)&nic->qs->sq[qidx].stats)
> +                                       [nicvf_queue_stats[stat].index];
> +       }
> +}
> +
>  static void nicvf_get_ethtool_stats(struct net_device *netdev,
>                                     struct ethtool_stats *stats, u64 *data)
>  {
>         struct nicvf *nic = netdev_priv(netdev);
> -       int stat, qidx;
> +       int stat;
> +       int sqs;
>
>         nicvf_update_stats(nic);
>
> @@ -225,16 +277,12 @@ static void nicvf_get_ethtool_stats(struct net_device *netdev,
>                 *(data++) = ((u64 *)&nic->drv_stats)
>                                 [nicvf_drv_stats[stat].index];
>
> -       for (qidx = 0; qidx < nic->qs->rq_cnt; qidx++) {
> -               for (stat = 0; stat < nicvf_n_queue_stats; stat++)
> -                       *(data++) = ((u64 *)&nic->qs->rq[qidx].stats)
> -                                       [nicvf_queue_stats[stat].index];
> -       }
> +       nicvf_get_qset_stats(nic, stats, &data);
>
> -       for (qidx = 0; qidx < nic->qs->sq_cnt; qidx++) {
> -               for (stat = 0; stat < nicvf_n_queue_stats; stat++)
> -                       *(data++) = ((u64 *)&nic->qs->sq[qidx].stats)
> -                                       [nicvf_queue_stats[stat].index];
> +       for (sqs = 0; sqs < nic->sqs_count; sqs++) {
> +               if (!nic->snicvf[sqs])
> +                       continue;
> +               nicvf_get_qset_stats(nic->snicvf[sqs], stats, &data);
>         }
>
>         for (stat = 0; stat < BGX_RX_STATS_COUNT; stat++)
> @@ -393,7 +441,7 @@ static int nicvf_get_rxnfc(struct net_device *dev,
>
>         switch (info->cmd) {
>         case ETHTOOL_GRXRINGS:
> -               info->data = nic->qs->rq_cnt;
> +               info->data = nic->rx_queues;
>                 ret = 0;
>                 break;
>         case ETHTOOL_GRXFH:
> @@ -556,11 +604,11 @@ static void nicvf_get_channels(struct net_device *dev,
>
>         memset(channel, 0, sizeof(*channel));
>
> -       channel->max_rx = MAX_RCV_QUEUES_PER_QS;
> -       channel->max_tx = MAX_SND_QUEUES_PER_QS;
> +       channel->max_rx = nic->max_queues;
> +       channel->max_tx = nic->max_queues;
>
> -       channel->rx_count = nic->qs->rq_cnt;
> -       channel->tx_count = nic->qs->sq_cnt;
> +       channel->rx_count = nic->rx_queues;
> +       channel->tx_count = nic->tx_queues;
>  }
>
>  /* Set no of Tx, Rx queues to be used */
> @@ -568,24 +616,36 @@ static int nicvf_set_channels(struct net_device *dev,
>                               struct ethtool_channels *channel)
>  {
>         struct nicvf *nic = netdev_priv(dev);
> -       int err = 0;
>         bool if_up = netif_running(dev);
> +       int cqcount;

> +       int err = 0;


Probably this initialization is not needed.

>
>         if (!channel->rx_count || !channel->tx_count)
>                 return -EINVAL;
> -       if (channel->rx_count > MAX_RCV_QUEUES_PER_QS)
> +       if (channel->rx_count > nic->max_queues)
>                 return -EINVAL;
> -       if (channel->tx_count > MAX_SND_QUEUES_PER_QS)
> +       if (channel->tx_count > nic->max_queues)
>                 return -EINVAL;
>
>         if (if_up)
>                 nicvf_stop(dev);
>
> -       nic->qs->rq_cnt = channel->rx_count;
> -       nic->qs->sq_cnt = channel->tx_count;
> +       cqcount = max(channel->rx_count, channel->tx_count);
> +
> +       if (cqcount > MAX_CMP_QUEUES_PER_QS) {
> +               nic->sqs_count = roundup(cqcount, MAX_CMP_QUEUES_PER_QS);
> +               nic->sqs_count = (nic->sqs_count / MAX_CMP_QUEUES_PER_QS) - 1;
> +       } else {
> +               nic->sqs_count = 0;
> +       }
> +
> +       nic->qs->rq_cnt = min_t(u32, channel->rx_count, MAX_RCV_QUEUES_PER_QS);
> +       nic->qs->sq_cnt = min_t(u32, channel->tx_count, MAX_SND_QUEUES_PER_QS);
>         nic->qs->cq_cnt = max(nic->qs->rq_cnt, nic->qs->sq_cnt);
>
> -       err = nicvf_set_real_num_queues(dev, nic->qs->sq_cnt, nic->qs->rq_cnt);
> +       nic->rx_queues = channel->rx_count;
> +       nic->tx_queues = channel->tx_count;
> +       err = nicvf_set_real_num_queues(dev, nic->tx_queues, nic->rx_queues);
>         if (err)
>                 return err;
>
> @@ -593,7 +653,7 @@ static int nicvf_set_channels(struct net_device *dev,
>                 nicvf_open(dev);
>
>         netdev_info(dev, "Setting num Tx rings to %d, Rx rings to %d success\n",
> -                   nic->qs->sq_cnt, nic->qs->rq_cnt);
> +                   nic->tx_queues, nic->rx_queues);
>
>         return err;
>  }
> diff --git a/drivers/net/ethernet/cavium/thunder/nicvf_main.c b/drivers/net/ethernet/cavium/thunder/nicvf_main.c
> index 2198f61..9a1091a 100644
> --- a/drivers/net/ethernet/cavium/thunder/nicvf_main.c
> +++ b/drivers/net/ethernet/cavium/thunder/nicvf_main.c
> @@ -51,6 +51,14 @@ module_param(cpi_alg, int, S_IRUGO);
>  MODULE_PARM_DESC(cpi_alg,
>                  "PFC algorithm (0=none, 1=VLAN, 2=VLAN16, 3=IP Diffserv)");
>
> +static inline u8 nicvf_netdev_qidx(struct nicvf *nic, u8 qidx)
> +{
> +       if (nic->sqs_mode)
> +               return qidx + ((nic->sqs_id + 1) * MAX_CMP_QUEUES_PER_QS);
> +       else
> +               return qidx;
> +}
> +
>  static inline void nicvf_set_rx_frame_cnt(struct nicvf *nic,
>                                           struct sk_buff *skb)
>  {
> @@ -193,6 +201,7 @@ static void  nicvf_handle_mbx_intr(struct nicvf *nic)
>                 if (!nic->set_mac_pending)
>                         ether_addr_copy(nic->netdev->dev_addr,
>                                         mbx.nic_cfg.mac_addr);
> +               nic->sqs_mode = mbx.nic_cfg.sqs_mode;
>                 nic->link_up = false;
>                 nic->duplex = 0;
>                 nic->speed = 0;
> @@ -230,6 +239,26 @@ static void  nicvf_handle_mbx_intr(struct nicvf *nic)
>                         netif_tx_stop_all_queues(nic->netdev);
>                 }
>                 break;
> +       case NIC_MBOX_MSG_ALLOC_SQS:
> +               nic->sqs_count = mbx.sqs_alloc.qs_count;
> +               nic->pf_acked = true;
> +               break;
> +       case NIC_MBOX_MSG_SNICVF_PTR:
> +               /* Primary VF: make note of secondary VF's pointer
> +                * to be used while packet transmission.
> +                */
> +               nic->snicvf[mbx.nicvf.sqs_id] =
> +                       (struct nicvf *)mbx.nicvf.nicvf;
> +               nic->pf_acked = true;
> +               break;
> +       case NIC_MBOX_MSG_PNICVF_PTR:
> +               /* Secondary VF/Qset: make note of primary VF's pointer
> +                * to be used while packet reception, to handover packet
> +                * to primary VF's netdev.
> +                */
> +               nic->pnicvf = (struct nicvf *)mbx.nicvf.nicvf;
> +               nic->pf_acked = true;
> +               break;
>         default:
>                 netdev_err(nic->netdev,
>                            "Invalid message from PF, msg 0x%x\n", mbx.msg.msg);
> @@ -338,11 +367,100 @@ static int nicvf_rss_init(struct nicvf *nic)
>
>         for (idx = 0; idx < rss->rss_size; idx++)
>                 rss->ind_tbl[idx] = ethtool_rxfh_indir_default(idx,
> -                                                              nic->qs->rq_cnt);
> +                                                              nic->rx_queues);
>         nicvf_config_rss(nic);
>         return 1;
>  }
>
> +/* Request PF to allocate additional Qsets */
> +static void nicvf_request_sqs(struct nicvf *nic)
> +{
> +       union nic_mbx mbx = {};
> +       int sqs;
> +       int sqs_count = nic->sqs_count;
> +       int rx_queues = 0, tx_queues = 0;
> +
> +       /* Only primary VF should request */
> +       if (nic->sqs_mode ||  !nic->sqs_count)
> +               return;
> +
> +       mbx.sqs_alloc.msg = NIC_MBOX_MSG_ALLOC_SQS;
> +       mbx.sqs_alloc.vf_id = nic->vf_id;
> +       mbx.sqs_alloc.qs_count = nic->sqs_count;
> +       if (nicvf_send_msg_to_pf(nic, &mbx)) {
> +               /* No response from PF */
> +               nic->sqs_count = 0;
> +               return;
> +       }
> +
> +       /* Return if no Secondary Qsets available */
> +       if (!nic->sqs_count)
> +               return;
> +
> +       if (nic->rx_queues > MAX_RCV_QUEUES_PER_QS)
> +               rx_queues = nic->rx_queues - MAX_RCV_QUEUES_PER_QS;
> +       if (nic->tx_queues > MAX_SND_QUEUES_PER_QS)
> +               tx_queues = nic->tx_queues - MAX_SND_QUEUES_PER_QS;
> +
> +       /* Set no of Rx/Tx queues in each of the SQsets */
> +       for (sqs = 0; sqs < nic->sqs_count; sqs++) {
> +               mbx.nicvf.msg = NIC_MBOX_MSG_SNICVF_PTR;
> +               mbx.nicvf.vf_id = nic->vf_id;
> +               mbx.nicvf.sqs_id = sqs;
> +               nicvf_send_msg_to_pf(nic, &mbx);
> +
> +               nic->snicvf[sqs]->sqs_id = sqs;
> +               if (rx_queues > MAX_RCV_QUEUES_PER_QS) {
> +                       nic->snicvf[sqs]->qs->rq_cnt = MAX_RCV_QUEUES_PER_QS;
> +                       rx_queues -= MAX_RCV_QUEUES_PER_QS;
> +               } else {
> +                       nic->snicvf[sqs]->qs->rq_cnt = rx_queues;
> +                       rx_queues = 0;
> +               }
> +
> +               if (tx_queues > MAX_SND_QUEUES_PER_QS) {
> +                       nic->snicvf[sqs]->qs->sq_cnt = MAX_SND_QUEUES_PER_QS;
> +                       tx_queues -= MAX_SND_QUEUES_PER_QS;
> +               } else {
> +                       nic->snicvf[sqs]->qs->sq_cnt = tx_queues;
> +                       tx_queues = 0;
> +               }
> +
> +               nic->snicvf[sqs]->qs->cq_cnt =
> +               max(nic->snicvf[sqs]->qs->rq_cnt, nic->snicvf[sqs]->qs->sq_cnt);
> +
> +               /* Initialize secondary Qset's queues and its interrupts */
> +               nicvf_open(nic->snicvf[sqs]->netdev);
> +       }
> +
> +       /* Update stack with actual Rx/Tx queue count allocated */
> +       if (sqs_count != nic->sqs_count)
> +               nicvf_set_real_num_queues(nic->netdev,
> +                                         nic->tx_queues, nic->rx_queues);
> +}
> +
> +/* Send this Qset's nicvf pointer to PF.
> + * PF inturn sends primary VF's nicvf struct to secondary Qsets/VFs
> + * so that packets received by these Qsets can use primary VF's netdev
> + */
> +static void nicvf_send_vf_struct(struct nicvf *nic)
> +{
> +       union nic_mbx mbx = {};
> +
> +       mbx.nicvf.msg = NIC_MBOX_MSG_NICVF_PTR;
> +       mbx.nicvf.sqs_mode = nic->sqs_mode;
> +       mbx.nicvf.nicvf = (u64)nic;
> +       nicvf_send_msg_to_pf(nic, &mbx);
> +}
> +
> +static void nicvf_get_primary_vf_struct(struct nicvf *nic)
> +{
> +       union nic_mbx mbx = {};
> +
> +       mbx.nicvf.msg = NIC_MBOX_MSG_PNICVF_PTR;
> +       nicvf_send_msg_to_pf(nic, &mbx);
> +}
> +
>  int nicvf_set_real_num_queues(struct net_device *netdev,
>                               int tx_queues, int rx_queues)
>  {
> @@ -453,6 +571,15 @@ static void nicvf_rcv_pkt_handler(struct net_device *netdev,
>         struct sk_buff *skb;
>         struct nicvf *nic = netdev_priv(netdev);
>         int err = 0;
> +       int rq_idx;
> +
> +       rq_idx = nicvf_netdev_qidx(nic, cqe_rx->rq_idx);
> +
> +       if (nic->sqs_mode) {
> +               /* Use primary VF's 'nicvf' struct */
> +               nic = nic->pnicvf;
> +               netdev = nic->netdev;
> +       }
>
>         /* Check for errors */
>         err = nicvf_check_cqe_rx_errs(nic, cq, cqe_rx);
> @@ -482,7 +609,7 @@ static void nicvf_rcv_pkt_handler(struct net_device *netdev,
>
>         nicvf_set_rxhash(netdev, cqe_rx, skb);
>
> -       skb_record_rx_queue(skb, cqe_rx->rq_idx);
> +       skb_record_rx_queue(skb, rq_idx);
>         if (netdev->hw_features & NETIF_F_RXCSUM) {
>                 /* HW by default verifies TCP/UDP/SCTP checksums */
>                 skb->ip_summed = CHECKSUM_UNNECESSARY;
> @@ -578,8 +705,11 @@ loop:
>  done:
>         /* Wakeup TXQ if its stopped earlier due to SQ full */
>         if (tx_done) {
> -               txq = netdev_get_tx_queue(netdev, cq_idx);
> -               if (netif_tx_queue_stopped(txq)) {
> +               netdev = nic->pnicvf->netdev;
> +               txq = netdev_get_tx_queue(netdev,
> +                                         nicvf_netdev_qidx(nic, cq_idx));
> +               nic = nic->pnicvf;
> +               if (netif_tx_queue_stopped(txq) && netif_carrier_ok(netdev)) {
>                         netif_tx_start_queue(txq);
>                         nic->drv_stats.txq_wake++;
>                         if (netif_msg_tx_err(nic))
> @@ -893,7 +1023,6 @@ static netdev_tx_t nicvf_xmit(struct sk_buff *skb, struct net_device *netdev)
>                         netdev_warn(netdev,
>                                     "%s: Transmit ring full, stopping SQ%d\n",
>                                     netdev->name, qid);
> -
>                 return NETDEV_TX_BUSY;
>         }
>
> @@ -926,6 +1055,17 @@ int nicvf_stop(struct net_device *netdev)
>         nicvf_send_msg_to_pf(nic, &mbx);
>
>         netif_carrier_off(netdev);
> +       netif_tx_stop_all_queues(nic->netdev);
> +
> +       /* Teardown secondary qsets first */
> +       if (!nic->sqs_mode) {
> +               for (qidx = 0; qidx < nic->sqs_count; qidx++) {
> +                       if (!nic->snicvf[qidx])
> +                               continue;
> +                       nicvf_stop(nic->snicvf[qidx]->netdev);
> +                       nic->snicvf[qidx] = NULL;
> +               }
> +       }
>
>         /* Disable RBDR & QS error interrupts */
>         for (qidx = 0; qidx < qs->rbdr_cnt; qidx++) {
> @@ -973,6 +1113,10 @@ int nicvf_stop(struct net_device *netdev)
>
>         nicvf_free_cq_poll(nic);
>
> +       /* Clear multiqset info */
> +       nic->pnicvf = nic;
> +       nic->sqs_count = 0;
> +
>         return 0;
>  }
>
> @@ -1028,10 +1172,16 @@ int nicvf_open(struct net_device *netdev)
>
>         /* Configure CPI alorithm */
>         nic->cpi_alg = cpi_alg;
> -       nicvf_config_cpi(nic);
> +       if (!nic->sqs_mode)
> +               nicvf_config_cpi(nic);
> +
> +       nicvf_request_sqs(nic);
> +       if (nic->sqs_mode)
> +               nicvf_get_primary_vf_struct(nic);
>
>         /* Configure receive side scaling */
> -       nicvf_rss_init(nic);
> +       if (!nic->sqs_mode)
> +               nicvf_rss_init(nic);
>
>         err = nicvf_register_interrupts(nic);
>         if (err)
> @@ -1282,8 +1432,7 @@ static int nicvf_probe(struct pci_dev *pdev, const struct pci_device_id *ent)
>         struct device *dev = &pdev->dev;
>         struct net_device *netdev;
>         struct nicvf *nic;
> -       struct queue_set *qs;
> -       int    err;
> +       int    err, qcount;
>
>         err = pci_enable_device(pdev);
>         if (err) {
> @@ -1309,9 +1458,17 @@ static int nicvf_probe(struct pci_dev *pdev, const struct pci_device_id *ent)
>                 goto err_release_regions;
>         }
>
> -       netdev = alloc_etherdev_mqs(sizeof(struct nicvf),
> -                                   MAX_RCV_QUEUES_PER_QS,
> -                                   MAX_SND_QUEUES_PER_QS);
> +       qcount = MAX_CMP_QUEUES_PER_QS;
> +
> +       /* Restrict multiqset support only for host bound VFs */
> +       if (pdev->is_virtfn) {
> +               /* Set max number of queues per VF */
> +               qcount = roundup(num_online_cpus(), MAX_CMP_QUEUES_PER_QS);
> +               qcount = min(qcount,
> +                            (MAX_SQS_PER_VF + 1) * MAX_CMP_QUEUES_PER_QS);
> +       }
> +
> +       netdev = alloc_etherdev_mqs(sizeof(struct nicvf), qcount, qcount);
>         if (!netdev) {
>                 err = -ENOMEM;
>                 goto err_release_regions;
> @@ -1324,6 +1481,8 @@ static int nicvf_probe(struct pci_dev *pdev, const struct pci_device_id *ent)
>         nic = netdev_priv(netdev);
>         nic->netdev = netdev;
>         nic->pdev = pdev;
> +       nic->pnicvf = nic;
> +       nic->max_queues = qcount;
>
>         /* MAP VF's configuration registers */
>         nic->reg_base = pcim_iomap(pdev, PCI_CFG_REG_BAR_NUM, 0);
> @@ -1337,20 +1496,26 @@ static int nicvf_probe(struct pci_dev *pdev, const struct pci_device_id *ent)
>         if (err)
>                 goto err_free_netdev;
>
> -       qs = nic->qs;
> -
> -       err = nicvf_set_real_num_queues(netdev, qs->sq_cnt, qs->rq_cnt);
> -       if (err)
> -               goto err_free_netdev;
> -
>         /* Check if PF is alive and get MAC address for this VF */
>         err = nicvf_register_misc_interrupt(nic);
>         if (err)
>                 goto err_free_netdev;
>
> +       nicvf_send_vf_struct(nic);
> +
> +       /* Check if this VF is in QS only mode */
> +       if (nic->sqs_mode)
> +               return 0;
> +
> +       err = nicvf_set_real_num_queues(netdev, nic->tx_queues, nic->rx_queues);
> +       if (err)
> +               goto err_unregister_interrupts;
> +
>         netdev->hw_features = (NETIF_F_RXCSUM | NETIF_F_IP_CSUM | NETIF_F_SG |
>                                NETIF_F_TSO | NETIF_F_GRO |
> -                              NETIF_F_HW_VLAN_CTAG_RX | NETIF_F_RXHASH);
> +                              NETIF_F_HW_VLAN_CTAG_RX);
> +
> +       netdev->hw_features |= NETIF_F_RXHASH;
>
>         netdev->features |= netdev->hw_features;
>
> @@ -1389,8 +1554,13 @@ static void nicvf_remove(struct pci_dev *pdev)
>  {
>         struct net_device *netdev = pci_get_drvdata(pdev);
>         struct nicvf *nic = netdev_priv(netdev);
> +       struct net_device *pnetdev = nic->pnicvf->netdev;
>
> -       unregister_netdev(netdev);
> +       /* Check if this Qset is assigned to different VF.
> +        * If yes, clean primary and all secondary Qsets.
> +        */
> +       if (pnetdev && (pnetdev->reg_state == NETREG_REGISTERED))
> +               unregister_netdev(pnetdev);
>         nicvf_unregister_interrupts(nic);
>         pci_set_drvdata(pdev, NULL);
>         free_netdev(netdev);
> diff --git a/drivers/net/ethernet/cavium/thunder/nicvf_queues.c b/drivers/net/ethernet/cavium/thunder/nicvf_queues.c
> index b294d67..63a870a 100644
> --- a/drivers/net/ethernet/cavium/thunder/nicvf_queues.c
> +++ b/drivers/net/ethernet/cavium/thunder/nicvf_queues.c


> @@ -478,7 +478,7 @@ static void nicvf_reclaim_rbdr(struct nicvf *nic,
>  void nicvf_config_vlan_stripping(struct nicvf *nic, netdev_features_t features)
>  {
>         u64 rq_cfg;
> -       int sqs;
> +       int sqs = 0;
>
>         rq_cfg = nicvf_queue_reg_read(nic, NIC_QSET_RQ_GEN_CFG, 0);
>

This change in nicvf_config_vlan_stripping() probably is not part of
this patch. It fits better into 5/8. But please check if you really
need this change at all.

> @@ -621,6 +621,7 @@ static void nicvf_snd_queue_config(struct nicvf *nic, struct queue_set *qs,
>         mbx.sq.msg = NIC_MBOX_MSG_SQ_CFG;
>         mbx.sq.qs_num = qs->vnic_id;
>         mbx.sq.sq_num = qidx;
> +       mbx.sq.sqs_mode = nic->sqs_mode;
>         mbx.sq.cfg = (sq->cq_qs << 3) | sq->cq_idx;
>         nicvf_send_msg_to_pf(nic, &mbx);
>
> @@ -702,6 +703,7 @@ void nicvf_qset_config(struct nicvf *nic, bool enable)
>         /* Send a mailbox msg to PF to config Qset */
>         mbx.qs.msg = NIC_MBOX_MSG_QS_CFG;
>         mbx.qs.num = qs->vnic_id;
> +       mbx.qs.sqs_count = nic->sqs_count;
>
>         mbx.qs.cfg = 0;
>         qs_cfg = (struct qs_cfg *)&mbx.qs.cfg;
> @@ -782,6 +784,10 @@ int nicvf_set_qset_resources(struct nicvf *nic)
>         qs->rbdr_len = RCV_BUF_COUNT;
>         qs->sq_len = SND_QUEUE_LEN;
>         qs->cq_len = CMP_QUEUE_LEN;
> +
> +       nic->rx_queues = qs->rq_cnt;
> +       nic->tx_queues = qs->sq_cnt;
> +
>         return 0;
>  }
>
> @@ -1025,7 +1031,7 @@ static inline void nicvf_sq_add_gather_subdesc(struct snd_queue *sq, int qentry,
>   * them to SQ for transfer
>   */
>  static int nicvf_sq_append_tso(struct nicvf *nic, struct snd_queue *sq,
> -                              int qentry, struct sk_buff *skb)
> +                              int sq_num, int qentry, struct sk_buff *skb)
>  {
>         struct tso_t tso;
>         int seg_subdescs = 0, desc_cnt = 0;
> @@ -1085,7 +1091,7 @@ static int nicvf_sq_append_tso(struct nicvf *nic, struct snd_queue *sq,
>
>         /* Inform HW to xmit all TSO segments */
>         nicvf_queue_reg_write(nic, NIC_QSET_SQ_0_7_DOOR,
> -                             skb_get_queue_mapping(skb), desc_cnt);
> +                             sq_num, desc_cnt);
>         nic->drv_stats.tx_tso++;
>         return 1;
>  }
> @@ -1096,10 +1102,24 @@ int nicvf_sq_append_skb(struct nicvf *nic, struct sk_buff *skb)
>         int i, size;
>         int subdesc_cnt;
>         int sq_num, qentry;
> -       struct queue_set *qs = nic->qs;
> +       struct queue_set *qs;
>         struct snd_queue *sq;
>
>         sq_num = skb_get_queue_mapping(skb);
> +       if (sq_num >= MAX_SND_QUEUES_PER_QS) {
> +               /* Get secondary Qset's SQ structure */
> +               i = sq_num / MAX_SND_QUEUES_PER_QS;
> +               if (!nic->snicvf[i - 1]) {
> +                       netdev_warn(nic->netdev,
> +                                   "Secondary Qset#%d's ptr not initialized\n",
> +                                   i - 1);
> +                       return 1;
> +               }
> +               nic = (struct nicvf *)nic->snicvf[i - 1];
> +               sq_num = sq_num % MAX_SND_QUEUES_PER_QS;
> +       }
> +
> +       qs = nic->qs;
>         sq = &qs->sq[sq_num];
>
>         subdesc_cnt = nicvf_sq_subdesc_required(nic, skb);
> @@ -1110,7 +1130,7 @@ int nicvf_sq_append_skb(struct nicvf *nic, struct sk_buff *skb)
>
>         /* Check if its a TSO packet */
>         if (skb_shinfo(skb)->gso_size)
> -               return nicvf_sq_append_tso(nic, sq, qentry, skb);
> +               return nicvf_sq_append_tso(nic, sq, sq_num, qentry, skb);
>
>         /* Add SQ header subdesc */
>         nicvf_sq_add_hdr_subdesc(sq, qentry, subdesc_cnt - 1, skb, skb->len);
> @@ -1146,6 +1166,8 @@ doorbell:
>         return 1;
>
>  append_fail:
> +       /* Use original PCI dev for debug log */
> +       nic = nic->pnicvf;
>         netdev_dbg(nic->netdev, "Not enough SQ descriptors to xmit pkt\n");
>         return 0;
>  }
> --
> 2.5.0
>
>
> _______________________________________________
> linux-arm-kernel mailing list
> linux-arm-kernel at lists.infradead.org
> http://lists.infradead.org/mailman/listinfo/linux-arm-kernel



-- 
Best regards, Klimov Alexey


From wens at csie.org  Fri Aug 28 19:07:12 2015
From: wens at csie.org (Chen-Yu Tsai)
Date: Sat, 29 Aug 2015 10:07:12 +0800
Subject: [PATCH 2/6] ARM: dts: sunxi: Add dtsi for AXP221 PMIC
In-Reply-To: <20150828204351.GS29389@lukather>
References: <1440755679-8266-1-git-send-email-wens@csie.org>
 <1440755679-8266-3-git-send-email-wens@csie.org>
 <20150828123159.GJ29389@lukather>
 <CAGb2v66nBh+_P=EDxrNYeFoUUXqPWuZyfq1OEQww_aSMhT8wVQ@mail.gmail.com>
 <20150828204351.GS29389@lukather>
Message-ID: <CAGb2v66qxgpGGzYHTP8=m-jhy2B2W2Z0iQmSed+e49PJVX_Q_w@mail.gmail.com>

On Sat, Aug 29, 2015 at 4:43 AM, Maxime Ripard
<maxime.ripard at free-electrons.com> wrote:
> On Sat, Aug 29, 2015 at 12:09:55AM +0800, Chen-Yu Tsai wrote:
>> >> +/*
>> >> + * AXP221/221s/223 Integrated Power Management Chip
>> >> + * http://www.x-powers.com/product/AXP22X.php
>> >> + * http://dl.linux-sunxi.org/AXP/AXP221%20Datasheet%20V1.2%2020130326%20.pdf
>> >> + */
>> >
>> > I'm usually not really fond of URLs in the source code and/or the
>> > commit logs. They tend to be broken very easily.
>>
>> OK. Would you rather I put them in Documentation/arm/sunxi/README?
>> It's not immediately clear that sunxi and axp* are connected though.
>
> It's one of the first things that pop up when googling, and it's not
> really related to sunxi, so I'd say simply leave them out.

Ok.

>> >> +
>> >> +&axp221 {
>> >> +     compatible = "x-powers,axp221";
>> >> +     interrupt-controller;
>> >> +     #interrupt-cells = <1>;
>> >> +
>> >> +     regulators {
>> >> +             /* Default work frequency for buck regulators */
>> >> +             x-powers,dcdc-freq = <3000>;
>> >> +
>> >> +             /* supplies for dc1sw & dc5ldo are connected internally */
>> >> +             dcdc1-supply = <&reg_dcdc1>;
>> >> +             dcdc5-supply = <&reg_dcdc5>;
>> >
>> > so the parent regulator of DCDC1 is DCDC1 ?
>>
>> These probably aren't the best names. These are the supplies for DC1SW and
>> DC5LDO, respectively. They are connected internally, so there aren't named
>> pins for them. The comment above explains it, though probably not clearly
>> enough. Furthermore, the input pins for DCDC1/5 are VIN1/5.
>
> I'm not quite sure I understand. They're connected internally but they
> have pins ?

Internally, DCDC1's output feeds the input for DC1SW (which is just a switch
BTW), and DCDC5's output feeds DC5LDO (which is an LDO). Both these extra
regulators have separate controls. There are no external pins to name the
supplies after, so I just named them after which regulator supplies them.

ChenYu


From siarhei.siamashka at gmail.com  Fri Aug 28 21:43:03 2015
From: siarhei.siamashka at gmail.com (Siarhei Siamashka)
Date: Sat, 29 Aug 2015 07:43:03 +0300
Subject: [PATCH 6/6] ARM: dts: sun6i: Add dts file for MSI Primo81 tablet
In-Reply-To: <20150828210208.GU29389@lukather>
References: <1440755679-8266-1-git-send-email-wens@csie.org>
 <1440755679-8266-7-git-send-email-wens@csie.org>
 <20150828123805.GN29389@lukather> <20150828163144.239e9bd5@i7>
 <20150828210208.GU29389@lukather>
Message-ID: <20150829074303.0b2a4c0d@i7>

On Fri, 28 Aug 2015 23:02:08 +0200
Maxime Ripard <maxime.ripard at free-electrons.com> wrote:

> Hi,
> 
> On Fri, Aug 28, 2015 at 04:31:44PM +0300, Siarhei Siamashka wrote:
> > > > external connectors are represented by MicroSD slot, MiniHDMI, MicroUSB
> > > > OTG and 3.5mm headphone jack. More details are available at
> > > > 
> > > >     http://linux-sunxi.org/MSI_Primo81
> > > 
> > > Again, not a huge fan of the commit logs URL...
> > 
> > But you are not strongly objecting to it either, right?
> > 
> > AFAIK many people are in favour of having links to the device pages in
> > the linux-sunxi wiki listed somewhere in the commit logs or along with
> > the board maintainer contact information (in U-Boot).
> 
> [citation needed]

Sure. I'm not going to search for every possible post in the mailing
lists on this particular subject, but you can check this one for
example:
    http://lists.denx.de/pipermail/u-boot/2015-June/215675.html
And also look here:
    https://git.kernel.org/cgit/linux/kernel/git/torvalds/linux.git/commit/?id=0ff1ffd3fe86840c80458ea45c2379014c86b660

> And it's a good thing that we're in Linux then.

What do you mean by this?

> > Because these pages contain the most relevant and up to date
> > information about the device, various pictures, tips and tricks,
> > etc.
> > 
> > If you are worried about linux-sunxi.org suddenly going down and not
> > coming back, there is also webarchive:
> > 
> >     http://web.archive.org/web/*/http://linux-sunxi.org/MSI_Primo81
> 
> If you have to look in web archive to find that page, you can just as
> well use google in the first place?

You *don't* have to look in web archive to find that page. That's only
an emergency option, just in case if shit hits the fan. Hopefully we
are never going to have to resort to this.

Do you mean that the users probably will not think about the webarchive
alternative in the case of emergency? If you are really so paranoid, it
is possible to provide both the real wiki page url and the webarchive
url. Does this solve the problem?

> > > This commit log is already fine without it.
> > 
> > This commit log is a nice example of why having a link to the wiki page
> > is a good idea. The errors and omissions in the wiki page can be
> > corrected. The old commit logs can't.
> 
> Which is exactly why we shouldn't have URLs. Because we can't fix them
> when they become irrelevant.

By the very same reasoning, we shouldn't ever have e-mail addresses in
the commit messages, documentation or source files. Because you know,
they sometimes may change too. I mentioned e-mail addresses here because
wiki pages and e-mail addresses both serve a very similar purpose:
that's a contact information.

> 
> Plus, quoting SubmittingPatches
> 
> "
> When you submit or resubmit a patch or patch series, include the
> complete patch description and justification for it.  Don't just
> say that this is version N of the patch (series).  Don't expect the
> subsystem maintainer to refer back to earlier patch versions or referenced
> URLs to find the patch description and put that into the patch.
> I.e., the patch (series) and its description should be self-contained.
> "

There is a significant difference between "patch description" mentioned
in this quotation (in other words, a commit message) and an external
URL with additional useful information.

If you search "http:" substring in the "git log" output, then you can
find a lot of various links to external web pages. Most of them are
links to the archived discussions in the mailing lists or references
to bugtracker issues. AFAIK there is no strict policy about prohibiting
URLs in general.

> If the patch description is self-contained, there's no need for a
> URL. And I really don't care about the board description being
> comprehensive either, so there's nothing to edit.

Finally looks like we have the real reasoning for stripping out URLs
and other extra information: *you* don't care. Basically, that's your
whim. And don't get me wrong, that's a perfectly valid explanation.
 
> > > > +&i2c1 {
> > > > +	pinctrl-names = "default";
> > > > +	pinctrl-0 = <&i2c1_pins_a>;
> > > > +	status = "okay";
> > > > +
> > > > +	ctp at 5d {
> > > > +		pinctrl-names = "default";
> > > > +		pinctrl-0 = <&gt911_int_primo81>;
> > > > +		compatible = "goodix,gt911";
> > > > +		reg = <0x5d>;
> > > > +		interrupt-parent = <&pio>;
> > > > +		interrupts = <0 3 IRQ_TYPE_LEVEL_HIGH>; /* PA3 */
> > > > +		/*
> > > > +		 * The default 0,0 coordinate is at the corner closest to
> > > > +		 * the headphone jack. X goes along the long side, while
> > > > +		 * Y goes along the short side.
> > > > +		 */
> > > 
> > > I'm not exactly sure what that comment is supposed to be for...
> > 
> > It's probably a human readable comment intended to be read by humans.
> > 
> > Yeah, this information might actually better belong to the wiki page.
> > But then again, this brings us to the question whether we should have
> > a link to the linux-sunxi wiki page somewhere in the dts.
> 
> I guess I'm not a human then, but a DT is definitely not the place I
> would look at for such information, and I'm not sure a user that
> didn't even build his kernel will either.

Why not? If the users are troubleshooting problems with the peripherals
in their devices (such as the touchscreen in this particular example),
why would they not look into a DTS file? It is one of the possible
culprits and also a source of valuable information, which may aid
debugging.

And if a user doesn't have any device yet, but is only considering to
buy something that is well supported by the Linux kernel, then why
would (s)he not look though the list of the available DTS files as
the first step in this search?

> However, I'm pretty sure that if it was in a wiki page, any search
> engine would return exactly the info I need, far more reliably than if
> it was in the kernel source.

That's just a speculation. I'm not sharing your enthusiasm about "any"
search engine and about "exactly". And we are talking not about you,
but about a wider population of users with varying levels of skills
and experience.

-- 
Best regards,
Siarhei Siamashka


From davem at davemloft.net  Fri Aug 28 22:10:49 2015
From: davem at davemloft.net (David Miller)
Date: Fri, 28 Aug 2015 22:10:49 -0700 (PDT)
Subject: [PATCH net-next 7/8] net: thunderx: Support for upto 96 queues
 for a VF
In-Reply-To: <CALW4P+KVjSFA3F+9wHTMiyMHkFjrbedP2LpUu033-o0k32F0nw@mail.gmail.com>
References: <1440774004-27923-1-git-send-email-aleksey.makarov@auriga.com>
 <1440774004-27923-7-git-send-email-aleksey.makarov@auriga.com>
 <CALW4P+KVjSFA3F+9wHTMiyMHkFjrbedP2LpUu033-o0k32F0nw@mail.gmail.com>
Message-ID: <20150828.221049.256686243264204039.davem@davemloft.net>

From: Alexey Klimov <klimov.linux at gmail.com>
Date: Sat, 29 Aug 2015 04:45:03 +0300

>> @@ -717,9 +833,24 @@ static void nic_unregister_interrupts(struct nicpf *nic)
>>         nic_disable_msix(nic);
>>  }
>>
>> +static int nic_num_sqs_en(struct nicpf *nic, int vf_en)
>> +{
>> +       int pos = 0, sqs_per_vf = MAX_SQS_PER_VF_SINGLE_NODE;
> 
> Please check if you really need to initialize 'pos' by zero here.

Please do _NOT_ quote hundreds of lines of code only to give feedback
on one particular hunk.

Quote _ONLY_ the exact context required, nothing more.

Everyone has to scroll through all of this unrelated crap you quoted,
and that makes more work for everyone.

Think particularly of _ME_ who has to be aware of what's going on in
every discussion thread for every patch that gets posted to this list.


From k.kozlowski at samsung.com  Sat Aug 29 00:45:55 2015
From: k.kozlowski at samsung.com (Krzysztof Kozlowski)
Date: Sat, 29 Aug 2015 16:45:55 +0900
Subject: [RFC] ARM: EXYNOS: reset KFC cores when cpu is up
In-Reply-To: <55A70DA4.3010405@samsung.com>
References: <1436924213-29732-1-git-send-email-parkch98@gmail.com>
 <CAJKOXPdcdREhwQZ22RcqbUSTpOn0XmqJ_3n5uUyzEgPihRYwNQ@mail.gmail.com>
 <CAPTzV17TRxTXKSucMWEk-5k6TtYsXkO0XFuuaCXKgNc2AoGQjA@mail.gmail.com>
 <55A70DA4.3010405@samsung.com>
Message-ID: <CAJKOXPdayKaDghOwP=MRfycFCuAr5=E7rAONQZVbnoTNocxfbw@mail.gmail.com>

2015-07-16 10:49 GMT+09:00 Krzysztof Kozlowski <k.kozlowski at samsung.com>:
> On 16.07.2015 10:36, Chanho Park wrote:
>> Hi,
>>
>> On Wed, Jul 15, 2015 at 8:35 PM, Krzysztof Kozlowski
>> <k.kozlowski at samsung.com> wrote:
>>> 2015-07-15 10:36 GMT+09:00 Chanho Park <parkch98 at gmail.com>:
>>>> The cpu booting of exynos5422 has been still broken since we discussed
>>>> it in last year[1]. I found this resetting codes from odroid-xu3 kernel of
>>>> hardkernel, it could help to boot 8 cores well. This patch need to have
>>>> more test like STR and other SoC especially exynos5800 which is variant
>>>> of exynos5422. If this patch is broken on exynos5800, I'll find another
>>>> way to check exynos5422.
>>>>
>>>> This patch is top of my previous exynos5422 cpu ordering patch[2] and
>>>> need to enable CONFIG_EXYNOS5420_MCPM=y
>>>>
>>>> [    0.047509] CPU0: update cpu_capacity 448
>>>> [    0.047534] CPU0: thread -1, cpu 0, socket 1, mpidr 80000100
>>>> [    0.047874] Setting up static identity map for 0x400082c0 -
>>>> 0x40008318
>>>> [    0.048340] ARM CCI driver probed
>>>> [    0.048597] Exynos MCPM support installed
>>>> [    0.065676] CPU1: update cpu_capacity 448
>>>> [    0.065685] CPU1: thread -1, cpu 1, socket 1, mpidr 80000101
>>>> [    0.070672] CPU2: update cpu_capacity 448
>>>> [    0.070680] CPU2: thread -1, cpu 2, socket 1, mpidr 80000102
>>>> [    0.075644] CPU3: update cpu_capacity 448
>>>> [    0.075653] CPU3: thread -1, cpu 3, socket 1, mpidr 80000103
>>>> [    0.080590] CPU4: update cpu_capacity 1535
>>>> [    0.080600] CPU4: thread -1, cpu 0, socket 0, mpidr 80000000
>>>> [    0.085591] CPU5: update cpu_capacity 1535
>>>> [    0.085599] CPU5: thread -1, cpu 1, socket 0, mpidr 80000001
>>>> [    0.090590] CPU6: update cpu_capacity 1535
>>>> [    0.090598] CPU6: thread -1, cpu 2, socket 0, mpidr 80000002
>>>> [    0.095585] CPU7: update cpu_capacity 1535
>>>> [    0.095593] CPU7: thread -1, cpu 3, socket 0, mpidr 80000003
>>>> [    0.095720] Brought up 8 CPUs
>>>>
>>>> [1]:http://lists.infradead.org/pipermail/linux-arm-kernel/2015-June/350632.html
>>>> [2]:https://patchwork.kernel.org/patch/6782891/
>>>
>>> Few questions/issues:
>>> 1. For the proper patch the commit message needs to be fixed a little.
>>> The dmesg above is meaningless but instead you can put short dmesg (2
>>> or 4 lines) with failed booting of CPUs.
>>
>> They will be gone when I make a official patch.
>>
>>> 2. Why only MCPM? Isn't this also needed without MCPM?
>>
>> Current exynos platsmp is not aware multi clusters. MCPM covered
>> secondary cpu booting of exynos big.Little cores. Without MCPM, same
>> approach and codes will be required on platsmp thus I think it's
>> redundant.
>
> Okay.
>
>>
>>>
>>>>
>>>> Cc: Joonyoung Shim <jy0922.shim at samsung.com>
>>>> Cc: Chanwoo Choi <cw00.choi at samsung.com>
>>>> Cc: Kevin Hilman <khilman at kernel.org>
>>>> Cc: Heesub Shin <heesub.shin at samsung.com>
>>>> Cc: Mauro Ribeiro <mauro.ribeiro at hardkernel.com>
>>>> Cc: Abhilash Kesavan <a.kesavan at samsung.com>
>>>> Cc: Przemyslaw Marczak <p.marczak at samsung.com>
>>>> Cc: Marek Szyprowski <m.szyprowski at samsung.com>
>>>> Cc: Krzysztof Kozlowski <k.kozlowski at samsung.com>
>>>> Signed-off-by: Chanho Park <chanho61.park at samsung.com>
>>>> Signed-off-by: Chanho Park <parkch98 at gmail.com>
>>>
>>> I think both Chanho Parks are the same person :) so you may leave only
>>> one (the one matching "From").
>>>
>>>> ---
>>>>  arch/arm/mach-exynos/mcpm-exynos.c | 13 ++++++++++++-
>>>>  arch/arm/mach-exynos/regs-pmu.h    |  6 ++++++
>>>>  2 files changed, 18 insertions(+), 1 deletion(-)
>>>>
>>>> diff --git a/arch/arm/mach-exynos/mcpm-exynos.c b/arch/arm/mach-exynos/mcpm-exynos.c
>>>> index 9bdf547..a076dde 100644
>>>> --- a/arch/arm/mach-exynos/mcpm-exynos.c
>>>> +++ b/arch/arm/mach-exynos/mcpm-exynos.c
>>>> @@ -70,7 +70,18 @@ static int exynos_cpu_powerup(unsigned int cpu, unsigned int cluster)
>>>>                 cluster >= EXYNOS5420_NR_CLUSTERS)
>>>>                 return -EINVAL;
>>>>
>>>> -       exynos_cpu_power_up(cpunr);
>>>> +       if (!exynos_cpu_power_state(cpunr)) {
>>>> +               exynos_cpu_power_up(cpunr);
>>>
>>> This second exynos_cpu_power_up() is needed? Do you know why?
>>
>> It's redirected to exynos's platsmp and it turned on CPU through pmu registers.
>>  -> exynos_cpu_powerup: mcpm-exynos.c
>>  -> exynos_cpu_power_up: platsmp.c
>>
>> Current mcpm exynos tried to run exynos_cpu_power_up twice during
>> secondary cpu is up. The first is from cpu_power_up of mcpm and the
>> second is from cpu_is_up. I want to avoid second power up the cpu if
>> it already turned on.
>>
>> static void exynos_cpu_is_up(unsigned int cpu, unsigned int cluster)
>> {
>>         /* especially when resuming: make sure power control is set */
>>
>>         exynos_cpu_powerup(cpu, cluster);
>> }
>
> Okay, I get it. I misunderstood the patch. It's fine.
>
>>
>>
>>>
>>>> +
>>>> +               if (soc_is_exynos5800() && cluster) {
>>>
>>> If of_machine_is_compatible() can be used then please use it. Javier
>>> also mentioned it and he pointed that this is not necessary on
>>> Chromebooks.
>>
>> Okay. I'll use of_machine_is_compatible() instead of soc_is_exynos5800
>> to avoid running it from exynos5800.
>>
>>>
>>>> +                       while (!pmu_raw_readl(S5P_PMU_SPARE2))
>>>> +                               udelay(10);
>>>> +
>>>> +                       pmu_raw_writel(EXYNOS5420_KFC_CORE_RESET(cpu),
>>>> +                                       EXYNOS_SWRESET);
>>>
>>> This is quite similar to existing exynos_core_restart(). Can you
>>> extend it for this purpose? Or at least put it as separate function
>>> near exynos_core_restart() so this would be grouped close to each
>>> other?
>>
>> As I said above, the platsmp is not aware multi clusters. I feel like
>> it would be dirty if I try to merge them.
>
> But here you are not reseting the cluster but reseting a CPU. Very
> similar function exists already - for waiting on SPARE2 and reseting
> CPU. I don't see what multiple clusters are changing here?
>
>>>
>>> Documenting this behaviour would be really nice (you can combine some
>>> of my findings on SPARE2 from previous discussion, if they are useful
>>> of course).
>>
>> No one knows exactly why we should wait until SPARE2 is up. I'll
>> specify known issue of it with your findings.
>
> Right, no one... at least publicly (probably the guys who have access to
> sources of BL1/BL2 know). Still it is important to document the reason
> why we think these steps are necessary. Some 3rd party developer won't
> have a clue why you are spinning on some SPARE2 register...


Dear Chanho,

Do you plan to send next version of the patchset? I tested it on my
Odroid XU3L (5422) and it works good so the idea you had is correct.

Best regards,
Krzysztof


From dingtianhong at huawei.com  Sat Aug 29 01:50:11 2015
From: dingtianhong at huawei.com (Ding Tianhong)
Date: Sat, 29 Aug 2015 16:50:11 +0800
Subject: [PATCH 1/2] arm64: hip05-d02: Document devicetree bindings for
 Hisilicon Hip05-D02 Board
In-Reply-To: <1440838213-9732-1-git-send-email-dingtianhong@huawei.com>
References: <1440838213-9732-1-git-send-email-dingtianhong@huawei.com>
Message-ID: <1440838213-9732-2-git-send-email-dingtianhong@huawei.com>

This patch adds documentation for the devicetree bindings used by the
DT files of Hisilicon Hip05-D02 development board.

Signed-off-by: Ding Tianhong <dingtianhong at huawei.com>
Signed-off-by: Kefeng Wang <wangkefeng.wang at huawei.com>
---
 Documentation/devicetree/bindings/arm/hisilicon/hisilicon.txt | 4 ++++
 1 file changed, 4 insertions(+)

diff --git a/Documentation/devicetree/bindings/arm/hisilicon/hisilicon.txt b/Documentation/devicetree/bindings/arm/hisilicon/hisilicon.txt
index c431c67..f98b39d 100644
--- a/Documentation/devicetree/bindings/arm/hisilicon/hisilicon.txt
+++ b/Documentation/devicetree/bindings/arm/hisilicon/hisilicon.txt
@@ -20,6 +20,10 @@ HiKey Board
 Required root node properties:
 	- compatible = "hisilicon,hi6220-hikey", "hisilicon,hi6220";
 
+HiP05 D02 Board
+Required root node properties:
+	- compatible = "hisilicon,hip05-d02";
+
 Hisilicon system controller
 
 Required properties:
-- 
1.9.0




From dingtianhong at huawei.com  Sat Aug 29 01:50:10 2015
From: dingtianhong at huawei.com (Ding Tianhong)
Date: Sat, 29 Aug 2015 16:50:10 +0800
Subject: [PATCH 0/2] arm64: Support Hisilicon Hip05-D02 board
Message-ID: <1440838213-9732-1-git-send-email-dingtianhong@huawei.com>

Hip05-D02 Development Board is based on Cortex-A57, this patchset
contains initial support for Hip05-D02 Soc and Board. Initial support
is minimal and includes just the arch configuration, device tree
configuration.

PSCI is enabled in device tree and there is no problem to boot all the
16 cores, and the CPU hotplug is also working now, you can download and
compile the latest firmware based on the following link to run this
patch set.

https://github.com/hisilicon/estuary/blob/master/README

Ding Tianhong (2):
  arm64: hip05-d02: Document devicetree bindings for Hisilicon Hip05-D02
    Board
  arm64: dts: add dts files for Hisilicon Hip05-D02 Development Board

 .../bindings/arm/hisilicon/hisilicon.txt           |   4 +
 arch/arm64/boot/dts/hisilicon/Makefile             |   2 +-
 arch/arm64/boot/dts/hisilicon/hip05-d02.dts        |  36 +++
 arch/arm64/boot/dts/hisilicon/hip05.dtsi           | 271 +++++++++++++++++++++
 4 files changed, 312 insertions(+), 1 deletion(-)
 create mode 100644 arch/arm64/boot/dts/hisilicon/hip05-d02.dts
 create mode 100644 arch/arm64/boot/dts/hisilicon/hip05.dtsi

-- 
1.9.0




From dingtianhong at huawei.com  Sat Aug 29 01:50:12 2015
From: dingtianhong at huawei.com (Ding Tianhong)
Date: Sat, 29 Aug 2015 16:50:12 +0800
Subject: [PATCH 2/2] arm64: dts: add dts files for Hisilicon Hip05-D02
 Development Board
In-Reply-To: <1440838213-9732-1-git-send-email-dingtianhong@huawei.com>
References: <1440838213-9732-1-git-send-email-dingtianhong@huawei.com>
Message-ID: <1440838213-9732-3-git-send-email-dingtianhong@huawei.com>

Add initial dtsi file to support Hisilicon Hip05-D02 Board with
support of CPUs in four clusters and each cluster has quard Cortex-A57.

Also add dts file to support Hip05-D02 development board.

Signed-off-by: Ding Tianhong <dingtianhong at huawei.com>
Signed-off-by: Kefeng Wang <wangkefeng.wang at huawei.com>
---
 arch/arm64/boot/dts/hisilicon/Makefile      |   2 +-
 arch/arm64/boot/dts/hisilicon/hip05-d02.dts |  36 ++++
 arch/arm64/boot/dts/hisilicon/hip05.dtsi    | 271 ++++++++++++++++++++++++++++
 3 files changed, 308 insertions(+), 1 deletion(-)
 create mode 100644 arch/arm64/boot/dts/hisilicon/hip05-d02.dts
 create mode 100644 arch/arm64/boot/dts/hisilicon/hip05.dtsi

diff --git a/arch/arm64/boot/dts/hisilicon/Makefile b/arch/arm64/boot/dts/hisilicon/Makefile
index fa81a6e..cd158b8 100644
--- a/arch/arm64/boot/dts/hisilicon/Makefile
+++ b/arch/arm64/boot/dts/hisilicon/Makefile
@@ -1,4 +1,4 @@
-dtb-$(CONFIG_ARCH_HISI) += hi6220-hikey.dtb
+dtb-$(CONFIG_ARCH_HISI) += hi6220-hikey.dtb hip05-d02.dtb
 
 always		:= $(dtb-y)
 subdir-y	:= $(dts-dirs)
diff --git a/arch/arm64/boot/dts/hisilicon/hip05-d02.dts b/arch/arm64/boot/dts/hisilicon/hip05-d02.dts
new file mode 100644
index 0000000..ae34e25
--- /dev/null
+++ b/arch/arm64/boot/dts/hisilicon/hip05-d02.dts
@@ -0,0 +1,36 @@
+/**
+ * dts file for Hisilicon D02 Development Board
+ *
+ * Copyright (C) 2014,2015 Hisilicon Ltd.
+ *
+ * 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
+ * publishhed by the Free Software Foundation.
+ *
+ */
+
+/dts-v1/;
+
+#include "hip05.dtsi"
+
+/ {
+	model = "Hisilicon Hip05 D02 Development Board";
+	compatible = "hisilicon,hip05-d02";
+
+	memory at 00000000 {
+		device_type = "memory";
+		reg = <0x0 0x00000000 0x0 0x80000000>;
+	};
+
+	aliases {
+		serial0 = &uart0;
+	};
+
+	chosen {
+		stdout-path = "serial0:115200n8";
+	};
+};
+
+&uart0 {
+	status = "ok";
+};
diff --git a/arch/arm64/boot/dts/hisilicon/hip05.dtsi b/arch/arm64/boot/dts/hisilicon/hip05.dtsi
new file mode 100644
index 0000000..da12d94
--- /dev/null
+++ b/arch/arm64/boot/dts/hisilicon/hip05.dtsi
@@ -0,0 +1,271 @@
+/**
+ * dts file for Hisilicon D02 Development Board
+ *
+ * Copyright (C) 2014,2015 Hisilicon Ltd.
+ *
+ * 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
+ * publishhed by the Free Software Foundation.
+ *
+ */
+
+#include <dt-bindings/interrupt-controller/arm-gic.h>
+
+/ {
+	compatible = "hisilicon,hip05-d02";
+	interrupt-parent = <&gic>;
+	#address-cells = <2>;
+	#size-cells = <2>;
+
+	psci {
+		compatible = "arm,psci-0.2";
+		method = "smc";
+	};
+
+	cpus {
+		#address-cells = <1>;
+		#size-cells = <0>;
+
+		cpu-map {
+			cluster0 {
+				core0 {
+					cpu = <&cpu0>;
+				};
+				core1 {
+					cpu = <&cpu1>;
+				};
+				core2 {
+					cpu = <&cpu2>;
+				};
+				core3 {
+					cpu = <&cpu3>;
+				};
+			};
+			cluster1 {
+				core0 {
+					cpu = <&cpu4>;
+				};
+				core1 {
+					cpu = <&cpu5>;
+				};
+				core2 {
+					cpu = <&cpu6>;
+				};
+				core3 {
+					cpu = <&cpu7>;
+				};
+			};
+			cluster2 {
+				core0 {
+					cpu = <&cpu8>;
+				};
+				core1 {
+					cpu = <&cpu9>;
+				};
+				core2 {
+					cpu = <&cpu10>;
+				};
+				core3 {
+					cpu = <&cpu11>;
+				};
+			};
+			cluster3 {
+				core0 {
+					cpu = <&cpu12>;
+				};
+				core1 {
+					cpu = <&cpu13>;
+				};
+				core2 {
+					cpu = <&cpu14>;
+				};
+				core3 {
+					cpu = <&cpu15>;
+				};
+			};
+		};
+
+		cpu0: cpu at 20000 {
+			device_type = "cpu";
+			compatible = "arm,armv8";
+			reg = <0x20000>;
+			enable-method = "psci";
+		};
+
+		cpu1: cpu at 20001 {
+			device_type = "cpu";
+			compatible = "arm,armv8";
+			reg = <0x20001>;
+			enable-method = "psci";
+		};
+
+		cpu2: cpu at 20002 {
+			device_type = "cpu";
+			compatible = "arm,armv8";
+			reg = <0x20002>;
+			enable-method = "psci";
+		};
+
+		cpu3: cpu at 20003 {
+			device_type = "cpu";
+			compatible = "arm,armv8";
+			reg = <0x20003>;
+			enable-method = "psci";
+		};
+
+		cpu4: cpu at 20100 {
+			device_type = "cpu";
+			compatible = "arm,armv8";
+			reg = <0x20100>;
+			enable-method = "psci";
+		};
+
+		cpu5: cpu at 20101 {
+			device_type = "cpu";
+			compatible = "arm,armv8";
+			reg = <0x20101>;
+			enable-method = "psci";
+		};
+
+		cpu6: cpu at 20102 {
+			device_type = "cpu";
+			compatible = "arm,armv8";
+			reg = <0x20102>;
+			enable-method = "psci";
+		};
+
+		cpu7: cpu at 20103 {
+			device_type = "cpu";
+			compatible = "arm,armv8";
+			reg = <0x20103>;
+			enable-method = "psci";
+		};
+
+		cpu8: cpu at 20200 {
+			device_type = "cpu";
+			compatible = "arm,armv8";
+			reg = <0x20200>;
+			enable-method = "psci";
+		};
+
+		cpu9: cpu at 20201 {
+			device_type = "cpu";
+			compatible = "arm,armv8";
+			reg = <0x20201>;
+			enable-method = "psci";
+		};
+
+		cpu10: cpu at 20202 {
+			device_type = "cpu";
+			compatible = "arm,armv8";
+			reg = <0x20202>;
+			enable-method = "psci";
+		};
+
+		cpu11: cpu at 20203 {
+			device_type = "cpu";
+			compatible = "arm,armv8";
+			reg = <0x20203>;
+			enable-method = "psci";
+		};
+
+		cpu12: cpu at 20300 {
+			device_type = "cpu";
+			compatible = "arm,armv8";
+			reg = <0x20300>;
+			enable-method = "psci";
+		};
+
+		cpu13: cpu at 20301 {
+			device_type = "cpu";
+			compatible = "arm,armv8";
+			reg = <0x20301>;
+			enable-method = "psci";
+		};
+
+		cpu14: cpu at 20302 {
+			device_type = "cpu";
+			compatible = "arm,armv8";
+			reg = <0x20302>;
+			enable-method = "psci";
+		};
+
+		cpu15: cpu at 20303 {
+			device_type = "cpu";
+			compatible = "arm,armv8";
+			reg = <0x20303>;
+			enable-method = "psci";
+		};
+	};
+
+	gic: interrupt-controller at 8d000000 {
+		compatible = "arm,gic-v3";
+                #interrupt-cells = <3>;
+                #address-cells = <2>;
+                #size-cells = <2>;
+                ranges;
+                interrupt-controller;
+                #redistributor-regions = <1>;
+                redistributor-stride = <0x0 0x30000>;
+		reg = <0x0 0x8d000000 0 0x10000>,	/* GICD */
+		      <0x0 0x8d100000 0 0x300000>,	/* GICR */
+		      <0x0 0xfe000000 0 0x10000>,	/* GICC */
+		      <0x0 0xfe010000 0 0x10000>,       /* GICH */
+		      <0x0 0xfe020000 0 0x10000>;       /* GICV */
+		interrupts = <GIC_PPI 9 (GIC_CPU_MASK_SIMPLE(8) | IRQ_TYPE_LEVEL_HIGH)>;
+
+		its_totems: interrupt-controller at 8c000000 {
+			compatible = "arm,gic-v3-its";
+			msi-controller;
+			reg = <0x0 0x8c000000 0x0 0x1000000>;
+		};
+	};
+
+	timer {
+		compatible = "arm,armv8-timer";
+		interrupts = <GIC_PPI 13 (GIC_CPU_MASK_SIMPLE(8) | IRQ_TYPE_LEVEL_LOW)>,
+			     <GIC_PPI 14 (GIC_CPU_MASK_SIMPLE(8) | IRQ_TYPE_LEVEL_LOW)>,
+			     <GIC_PPI 11 (GIC_CPU_MASK_SIMPLE(8) | IRQ_TYPE_LEVEL_LOW)>,
+			     <GIC_PPI 10 (GIC_CPU_MASK_SIMPLE(8) | IRQ_TYPE_LEVEL_LOW)>;
+	};
+
+	pmu {
+		compatible = "arm,armv8-pmuv3";
+		interrupts = <GIC_PPI 7 IRQ_TYPE_LEVEL_HIGH>;
+	};
+
+	soc {
+		compatible = "simple-bus";
+		#address-cells = <2>;
+		#size-cells = <2>;
+		ranges;
+
+		refclk200mhz: refclk200mhz {
+			compatible = "fixed-clock";
+			#clock-cells = <0>;
+			clock-frequency = <200000000>;
+		};
+
+		uart0: uart at 80300000 {
+			compatible = "snps,dw-apb-uart";
+			reg = <0x0 0x80300000 0x0 0x10000>;
+			interrupts = <GIC_SPI 317 IRQ_TYPE_LEVEL_HIGH>;
+			clocks = <&refclk200mhz>;
+			clock-names = "apb_pclk";
+			reg-shift = <2>;
+			reg-io-width = <4>;
+			status = "disabled";
+		};
+
+		uart1: uart at 80310000 {
+			compatible = "snps,dw-apb-uart";
+			reg = <0x0 0x80310000 0x0 0x10000>;
+			interrupts = <GIC_SPI 318 IRQ_TYPE_LEVEL_HIGH>;
+			clocks = <&refclk200mhz>;
+			clock-names = "apb_pclk";
+			reg-shift = <2>;
+			reg-io-width = <4>;
+			status = "disabled";
+		};
+	};
+};
-- 
1.9.0




From dingtianhong at huawei.com  Sat Aug 29 01:52:40 2015
From: dingtianhong at huawei.com (Ding Tianhong)
Date: Sat, 29 Aug 2015 16:52:40 +0800
Subject: [PATCH 1/2] arm64: hip05-d02: Document devicetree bindings for
 Hisilicon Hip05-D02 Board
In-Reply-To: <1440838361-1468-1-git-send-email-dingtianhong@huawei.com>
References: <1440838361-1468-1-git-send-email-dingtianhong@huawei.com>
Message-ID: <1440838361-1468-2-git-send-email-dingtianhong@huawei.com>

This patch adds documentation for the devicetree bindings used by the
DT files of Hisilicon Hip05-D02 development board.

Signed-off-by: Ding Tianhong <dingtianhong at huawei.com>
Signed-off-by: Kefeng Wang <wangkefeng.wang at huawei.com>
---
 Documentation/devicetree/bindings/arm/hisilicon/hisilicon.txt | 4 ++++
 1 file changed, 4 insertions(+)

diff --git a/Documentation/devicetree/bindings/arm/hisilicon/hisilicon.txt b/Documentation/devicetree/bindings/arm/hisilicon/hisilicon.txt
index c431c67..f98b39d 100644
--- a/Documentation/devicetree/bindings/arm/hisilicon/hisilicon.txt
+++ b/Documentation/devicetree/bindings/arm/hisilicon/hisilicon.txt
@@ -20,6 +20,10 @@ HiKey Board
 Required root node properties:
 	- compatible = "hisilicon,hi6220-hikey", "hisilicon,hi6220";
 
+HiP05 D02 Board
+Required root node properties:
+	- compatible = "hisilicon,hip05-d02";
+
 Hisilicon system controller
 
 Required properties:
-- 
1.9.0




From dingtianhong at huawei.com  Sat Aug 29 01:52:39 2015
From: dingtianhong at huawei.com (Ding Tianhong)
Date: Sat, 29 Aug 2015 16:52:39 +0800
Subject: [PATCH 0/2] arm64: Support Hisilicon Hip05-D02 board
Message-ID: <1440838361-1468-1-git-send-email-dingtianhong@huawei.com>

Hip05-D02 Development Board is based on Cortex-A57, this patchset
contains initial support for Hip05-D02 Soc and Board. Initial support
is minimal and includes just the arch configuration, device tree
configuration.

PSCI is enabled in device tree and there is no problem to boot all the
16 cores, and the CPU hotplug is also working now, you can download and
compile the latest firmware based on the following link to run this
patch set.

https://github.com/hisilicon/estuary/blob/master/README

Ding Tianhong (2):
  arm64: hip05-d02: Document devicetree bindings for Hisilicon Hip05-D02
    Board
  arm64: dts: add dts files for Hisilicon Hip05-D02 Development Board

 .../bindings/arm/hisilicon/hisilicon.txt           |   4 +
 arch/arm64/boot/dts/hisilicon/Makefile             |   2 +-
 arch/arm64/boot/dts/hisilicon/hip05-d02.dts        |  36 +++
 arch/arm64/boot/dts/hisilicon/hip05.dtsi           | 271 +++++++++++++++++++++
 4 files changed, 312 insertions(+), 1 deletion(-)
 create mode 100644 arch/arm64/boot/dts/hisilicon/hip05-d02.dts
 create mode 100644 arch/arm64/boot/dts/hisilicon/hip05.dtsi

-- 
1.9.0




From dingtianhong at huawei.com  Sat Aug 29 01:52:41 2015
From: dingtianhong at huawei.com (Ding Tianhong)
Date: Sat, 29 Aug 2015 16:52:41 +0800
Subject: [PATCH 2/2] arm64: dts: add dts files for Hisilicon Hip05-D02
 Development Board
In-Reply-To: <1440838361-1468-1-git-send-email-dingtianhong@huawei.com>
References: <1440838361-1468-1-git-send-email-dingtianhong@huawei.com>
Message-ID: <1440838361-1468-3-git-send-email-dingtianhong@huawei.com>

Add initial dtsi file to support Hisilicon Hip05-D02 Board with
support of CPUs in four clusters and each cluster has quard Cortex-A57.

Also add dts file to support Hip05-D02 development board.

Signed-off-by: Ding Tianhong <dingtianhong at huawei.com>
Signed-off-by: Kefeng Wang <wangkefeng.wang at huawei.com>
---
 arch/arm64/boot/dts/hisilicon/Makefile      |   2 +-
 arch/arm64/boot/dts/hisilicon/hip05-d02.dts |  36 ++++
 arch/arm64/boot/dts/hisilicon/hip05.dtsi    | 271 ++++++++++++++++++++++++++++
 3 files changed, 308 insertions(+), 1 deletion(-)
 create mode 100644 arch/arm64/boot/dts/hisilicon/hip05-d02.dts
 create mode 100644 arch/arm64/boot/dts/hisilicon/hip05.dtsi

diff --git a/arch/arm64/boot/dts/hisilicon/Makefile b/arch/arm64/boot/dts/hisilicon/Makefile
index fa81a6e..cd158b8 100644
--- a/arch/arm64/boot/dts/hisilicon/Makefile
+++ b/arch/arm64/boot/dts/hisilicon/Makefile
@@ -1,4 +1,4 @@
-dtb-$(CONFIG_ARCH_HISI) += hi6220-hikey.dtb
+dtb-$(CONFIG_ARCH_HISI) += hi6220-hikey.dtb hip05-d02.dtb
 
 always		:= $(dtb-y)
 subdir-y	:= $(dts-dirs)
diff --git a/arch/arm64/boot/dts/hisilicon/hip05-d02.dts b/arch/arm64/boot/dts/hisilicon/hip05-d02.dts
new file mode 100644
index 0000000..ae34e25
--- /dev/null
+++ b/arch/arm64/boot/dts/hisilicon/hip05-d02.dts
@@ -0,0 +1,36 @@
+/**
+ * dts file for Hisilicon D02 Development Board
+ *
+ * Copyright (C) 2014,2015 Hisilicon Ltd.
+ *
+ * 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
+ * publishhed by the Free Software Foundation.
+ *
+ */
+
+/dts-v1/;
+
+#include "hip05.dtsi"
+
+/ {
+	model = "Hisilicon Hip05 D02 Development Board";
+	compatible = "hisilicon,hip05-d02";
+
+	memory at 00000000 {
+		device_type = "memory";
+		reg = <0x0 0x00000000 0x0 0x80000000>;
+	};
+
+	aliases {
+		serial0 = &uart0;
+	};
+
+	chosen {
+		stdout-path = "serial0:115200n8";
+	};
+};
+
+&uart0 {
+	status = "ok";
+};
diff --git a/arch/arm64/boot/dts/hisilicon/hip05.dtsi b/arch/arm64/boot/dts/hisilicon/hip05.dtsi
new file mode 100644
index 0000000..da12d94
--- /dev/null
+++ b/arch/arm64/boot/dts/hisilicon/hip05.dtsi
@@ -0,0 +1,271 @@
+/**
+ * dts file for Hisilicon D02 Development Board
+ *
+ * Copyright (C) 2014,2015 Hisilicon Ltd.
+ *
+ * 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
+ * publishhed by the Free Software Foundation.
+ *
+ */
+
+#include <dt-bindings/interrupt-controller/arm-gic.h>
+
+/ {
+	compatible = "hisilicon,hip05-d02";
+	interrupt-parent = <&gic>;
+	#address-cells = <2>;
+	#size-cells = <2>;
+
+	psci {
+		compatible = "arm,psci-0.2";
+		method = "smc";
+	};
+
+	cpus {
+		#address-cells = <1>;
+		#size-cells = <0>;
+
+		cpu-map {
+			cluster0 {
+				core0 {
+					cpu = <&cpu0>;
+				};
+				core1 {
+					cpu = <&cpu1>;
+				};
+				core2 {
+					cpu = <&cpu2>;
+				};
+				core3 {
+					cpu = <&cpu3>;
+				};
+			};
+			cluster1 {
+				core0 {
+					cpu = <&cpu4>;
+				};
+				core1 {
+					cpu = <&cpu5>;
+				};
+				core2 {
+					cpu = <&cpu6>;
+				};
+				core3 {
+					cpu = <&cpu7>;
+				};
+			};
+			cluster2 {
+				core0 {
+					cpu = <&cpu8>;
+				};
+				core1 {
+					cpu = <&cpu9>;
+				};
+				core2 {
+					cpu = <&cpu10>;
+				};
+				core3 {
+					cpu = <&cpu11>;
+				};
+			};
+			cluster3 {
+				core0 {
+					cpu = <&cpu12>;
+				};
+				core1 {
+					cpu = <&cpu13>;
+				};
+				core2 {
+					cpu = <&cpu14>;
+				};
+				core3 {
+					cpu = <&cpu15>;
+				};
+			};
+		};
+
+		cpu0: cpu at 20000 {
+			device_type = "cpu";
+			compatible = "arm,armv8";
+			reg = <0x20000>;
+			enable-method = "psci";
+		};
+
+		cpu1: cpu at 20001 {
+			device_type = "cpu";
+			compatible = "arm,armv8";
+			reg = <0x20001>;
+			enable-method = "psci";
+		};
+
+		cpu2: cpu at 20002 {
+			device_type = "cpu";
+			compatible = "arm,armv8";
+			reg = <0x20002>;
+			enable-method = "psci";
+		};
+
+		cpu3: cpu at 20003 {
+			device_type = "cpu";
+			compatible = "arm,armv8";
+			reg = <0x20003>;
+			enable-method = "psci";
+		};
+
+		cpu4: cpu at 20100 {
+			device_type = "cpu";
+			compatible = "arm,armv8";
+			reg = <0x20100>;
+			enable-method = "psci";
+		};
+
+		cpu5: cpu at 20101 {
+			device_type = "cpu";
+			compatible = "arm,armv8";
+			reg = <0x20101>;
+			enable-method = "psci";
+		};
+
+		cpu6: cpu at 20102 {
+			device_type = "cpu";
+			compatible = "arm,armv8";
+			reg = <0x20102>;
+			enable-method = "psci";
+		};
+
+		cpu7: cpu at 20103 {
+			device_type = "cpu";
+			compatible = "arm,armv8";
+			reg = <0x20103>;
+			enable-method = "psci";
+		};
+
+		cpu8: cpu at 20200 {
+			device_type = "cpu";
+			compatible = "arm,armv8";
+			reg = <0x20200>;
+			enable-method = "psci";
+		};
+
+		cpu9: cpu at 20201 {
+			device_type = "cpu";
+			compatible = "arm,armv8";
+			reg = <0x20201>;
+			enable-method = "psci";
+		};
+
+		cpu10: cpu at 20202 {
+			device_type = "cpu";
+			compatible = "arm,armv8";
+			reg = <0x20202>;
+			enable-method = "psci";
+		};
+
+		cpu11: cpu at 20203 {
+			device_type = "cpu";
+			compatible = "arm,armv8";
+			reg = <0x20203>;
+			enable-method = "psci";
+		};
+
+		cpu12: cpu at 20300 {
+			device_type = "cpu";
+			compatible = "arm,armv8";
+			reg = <0x20300>;
+			enable-method = "psci";
+		};
+
+		cpu13: cpu at 20301 {
+			device_type = "cpu";
+			compatible = "arm,armv8";
+			reg = <0x20301>;
+			enable-method = "psci";
+		};
+
+		cpu14: cpu at 20302 {
+			device_type = "cpu";
+			compatible = "arm,armv8";
+			reg = <0x20302>;
+			enable-method = "psci";
+		};
+
+		cpu15: cpu at 20303 {
+			device_type = "cpu";
+			compatible = "arm,armv8";
+			reg = <0x20303>;
+			enable-method = "psci";
+		};
+	};
+
+	gic: interrupt-controller at 8d000000 {
+		compatible = "arm,gic-v3";
+                #interrupt-cells = <3>;
+                #address-cells = <2>;
+                #size-cells = <2>;
+                ranges;
+                interrupt-controller;
+                #redistributor-regions = <1>;
+                redistributor-stride = <0x0 0x30000>;
+		reg = <0x0 0x8d000000 0 0x10000>,	/* GICD */
+		      <0x0 0x8d100000 0 0x300000>,	/* GICR */
+		      <0x0 0xfe000000 0 0x10000>,	/* GICC */
+		      <0x0 0xfe010000 0 0x10000>,       /* GICH */
+		      <0x0 0xfe020000 0 0x10000>;       /* GICV */
+		interrupts = <GIC_PPI 9 (GIC_CPU_MASK_SIMPLE(8) | IRQ_TYPE_LEVEL_HIGH)>;
+
+		its_totems: interrupt-controller at 8c000000 {
+			compatible = "arm,gic-v3-its";
+			msi-controller;
+			reg = <0x0 0x8c000000 0x0 0x1000000>;
+		};
+	};
+
+	timer {
+		compatible = "arm,armv8-timer";
+		interrupts = <GIC_PPI 13 (GIC_CPU_MASK_SIMPLE(8) | IRQ_TYPE_LEVEL_LOW)>,
+			     <GIC_PPI 14 (GIC_CPU_MASK_SIMPLE(8) | IRQ_TYPE_LEVEL_LOW)>,
+			     <GIC_PPI 11 (GIC_CPU_MASK_SIMPLE(8) | IRQ_TYPE_LEVEL_LOW)>,
+			     <GIC_PPI 10 (GIC_CPU_MASK_SIMPLE(8) | IRQ_TYPE_LEVEL_LOW)>;
+	};
+
+	pmu {
+		compatible = "arm,armv8-pmuv3";
+		interrupts = <GIC_PPI 7 IRQ_TYPE_LEVEL_HIGH>;
+	};
+
+	soc {
+		compatible = "simple-bus";
+		#address-cells = <2>;
+		#size-cells = <2>;
+		ranges;
+
+		refclk200mhz: refclk200mhz {
+			compatible = "fixed-clock";
+			#clock-cells = <0>;
+			clock-frequency = <200000000>;
+		};
+
+		uart0: uart at 80300000 {
+			compatible = "snps,dw-apb-uart";
+			reg = <0x0 0x80300000 0x0 0x10000>;
+			interrupts = <GIC_SPI 317 IRQ_TYPE_LEVEL_HIGH>;
+			clocks = <&refclk200mhz>;
+			clock-names = "apb_pclk";
+			reg-shift = <2>;
+			reg-io-width = <4>;
+			status = "disabled";
+		};
+
+		uart1: uart at 80310000 {
+			compatible = "snps,dw-apb-uart";
+			reg = <0x0 0x80310000 0x0 0x10000>;
+			interrupts = <GIC_SPI 318 IRQ_TYPE_LEVEL_HIGH>;
+			clocks = <&refclk200mhz>;
+			clock-names = "apb_pclk";
+			reg-shift = <2>;
+			reg-io-width = <4>;
+			status = "disabled";
+		};
+	};
+};
-- 
1.9.0




From k.kozlowski at samsung.com  Sat Aug 29 02:01:39 2015
From: k.kozlowski at samsung.com (Krzysztof Kozlowski)
Date: Sat, 29 Aug 2015 18:01:39 +0900
Subject: [PATCH] ARM: exynos_defconfig: Enable big.LITTLE CPUidle support
In-Reply-To: <1440749769-10135-1-git-send-email-javier@osg.samsung.com>
References: <1440749769-10135-1-git-send-email-javier@osg.samsung.com>
Message-ID: <55E174F3.1030202@samsung.com>

W dniu 28.08.2015 o 17:16, Javier Martinez Canillas pisze:
> Some Exynos big.LITTLE boards (i.e: Exynos5420 and Exynos5800 based
> Chromebooks) have proper firmware that allow the big.LITTLE CPUidle
> driver to work correctly, so enable support for this.
> 
> Signed-off-by: Javier Martinez Canillas <javier at osg.samsung.com>
> 
> ---
> Kukjin and Krzysztof,
> 
> As you know there are other boards like the Exynos5422 based Odroid XU{3,4}
> whose firmware is broken due leaving CCI in secure mode which means that the
> kernel MCPM support can't properly manage CCI.
> 
> So if you pick this patch, it should be tested in kernelci before appearing
> in linux-next to prevent any boot issues.
> 
> But if that happens, I believe that is better to do a fix / workaround in
> those broken platforms since nothing prevents users to enable this option
> anyways. For example the CCI device node could be disabled in the DTS.
> 
>  arch/arm/configs/exynos_defconfig | 1 +
>  1 file changed, 1 insertion(+)

On Odroid XU3L (next-20150828, Hardkernel u-boot) boot hangs just after:

[    2.568650] dwmmc_exynos 12200000.mmc: num-slots property not found,
assuming 1 slot is available

... so no. NACK :). First the boards, firmware, bootloader or kernel
code have to be fixed.

Best regards,
Krzysztof

> 
> diff --git a/arch/arm/configs/exynos_defconfig b/arch/arm/configs/exynos_defconfig
> index 729e2fae3e58..228ee945b8ed 100644
> --- a/arch/arm/configs/exynos_defconfig
> +++ b/arch/arm/configs/exynos_defconfig
> @@ -30,6 +30,7 @@ CONFIG_CPU_FREQ=y
>  CONFIG_CPU_FREQ_DEFAULT_GOV_ONDEMAND=y
>  CONFIG_CPUFREQ_DT=y
>  CONFIG_CPU_IDLE=y
> +CONFIG_ARM_BIG_LITTLE_CPUIDLE=y
>  CONFIG_ARM_EXYNOS_CPUIDLE=y
>  CONFIG_VFP=y
>  CONFIG_NEON=y
> 



From javier at osg.samsung.com  Sat Aug 29 02:33:10 2015
From: javier at osg.samsung.com (Javier Martinez Canillas)
Date: Sat, 29 Aug 2015 11:33:10 +0200
Subject: [PATCH] ARM: exynos_defconfig: Enable big.LITTLE CPUidle support
In-Reply-To: <55E174F3.1030202@samsung.com>
References: <1440749769-10135-1-git-send-email-javier@osg.samsung.com>
 <55E174F3.1030202@samsung.com>
Message-ID: <55E17C56.4080200@osg.samsung.com>

Hello Krzysztof,

On 08/29/2015 11:01 AM, Krzysztof Kozlowski wrote:
> W dniu 28.08.2015 o 17:16, Javier Martinez Canillas pisze:
>> Some Exynos big.LITTLE boards (i.e: Exynos5420 and Exynos5800 based
>> Chromebooks) have proper firmware that allow the big.LITTLE CPUidle
>> driver to work correctly, so enable support for this.
>>
>> Signed-off-by: Javier Martinez Canillas <javier at osg.samsung.com>
>>
>> ---
>> Kukjin and Krzysztof,
>>
>> As you know there are other boards like the Exynos5422 based Odroid XU{3,4}
>> whose firmware is broken due leaving CCI in secure mode which means that the
>> kernel MCPM support can't properly manage CCI.
>>
>> So if you pick this patch, it should be tested in kernelci before appearing
>> in linux-next to prevent any boot issues.
>>
>> But if that happens, I believe that is better to do a fix / workaround in
>> those broken platforms since nothing prevents users to enable this option
>> anyways. For example the CCI device node could be disabled in the DTS.
>>
>>  arch/arm/configs/exynos_defconfig | 1 +
>>  1 file changed, 1 insertion(+)
> 
> On Odroid XU3L (next-20150828, Hardkernel u-boot) boot hangs just after:
>

Thanks for testing, I was expecting that is just that I don't have a
Odroid XU{3,4} board for test here, I guess I should get one.
 
> [    2.568650] dwmmc_exynos 12200000.mmc: num-slots property not found,
> assuming 1 slot is available
> 
> ... so no. NACK :). First the boards, firmware, bootloader or kernel

Agreed with the nack :)

> code have to be fixed.
>

Or disable CCI, could you please test the following patch [0] so I
can post it properly?
 
> Best regards,
> Krzysztof
> 

Best regards,
-- 
Javier Martinez Canillas
Open Source Group
Samsung Research America

[0]:
>From 0fc5649b8d939ccfb7d3be1aa09df5e1f89a5a82 Mon Sep 17 00:00:00 2001
From: Javier Martinez Canillas <javier at osg.samsung.com>
Date: Sat, 29 Aug 2015 11:21:39 +0200
Subject: [RFT PATCH] ARM: dts: Disable CCI support for Odroid XU{3,4} boards

The Exynos5422 based Odroid XU{3,4} boards have a broken firmware that
leaves CCI in secure mode which means that the kernel MCPM support can
not properly manage CCI. This causes the machine to hang when entering
into low power states for example triggered by the b.L CPUidle driver.

The patch is based on commit 25217fef3551 ("ARM: dts: disable CCI on
exynos5420 based arndale-octa")

Signed-off-by: Javier Martinez Canillas <javier at osg.samsung.com>
---
 arch/arm/boot/dts/exynos5422-odroidxu3-common.dtsi | 4 ++++
 1 file changed, 4 insertions(+)

diff --git a/arch/arm/boot/dts/exynos5422-odroidxu3-common.dtsi b/arch/arm/boot/dts/exynos5422-odroidxu3-common.dtsi
index dd8bc86d9de4..1e076458fab6 100644
--- a/arch/arm/boot/dts/exynos5422-odroidxu3-common.dtsi
+++ b/arch/arm/boot/dts/exynos5422-odroidxu3-common.dtsi
@@ -525,3 +525,7 @@
 	vdd33-supply = <&ldo9_reg>;
 	vdd10-supply = <&ldo11_reg>;
 };
+
+&cci {
+	status = "disabled";
+};
-- 
2.4.3


From broonie at kernel.org  Sat Aug 29 02:35:48 2015
From: broonie at kernel.org (Mark Brown)
Date: Sat, 29 Aug 2015 10:35:48 +0100
Subject: [PATCH v3 0/4] regmap: i2c block support
In-Reply-To: <1440657872-24554-1-git-send-email-mpa@pengutronix.de>
References: <1440657872-24554-1-git-send-email-mpa@pengutronix.de>
Message-ID: <20150829093548.GY12027@sirena.org.uk>

On Thu, Aug 27, 2015 at 08:44:28AM +0200, Markus Pargmann wrote:
> Hi,
> 
> This series adds support for i2c block read/writes. To support the maximum 32
> byte read/write operations, the regmap core is extended by max_raw_read and
> max_raw_write. bulk operations are splitted depending of the size of
> max_raw_read/write.

...and reverted because it broke the build, probably because it was not
a patch against current development trees:

  http://kernelci.org/build/broonie-regmap/kernel/v4.2-rc8-34-gd535ae53edec/

-------------- next part --------------
A non-text attachment was scrubbed...
Name: signature.asc
Type: application/pgp-signature
Size: 473 bytes
Desc: Digital signature
URL: <http://lists.infradead.org/pipermail/linux-arm-kernel/attachments/20150829/ab2985c7/attachment.sig>

From thunder.leizhen at huawei.com  Sat Aug 29 02:46:00 2015
From: thunder.leizhen at huawei.com (Leizhen (ThunderTown))
Date: Sat, 29 Aug 2015 17:46:00 +0800
Subject: [PATCH v5 2/4] Documentation: arm64/arm: dt bindings for numa.
In-Reply-To: <CAL_JsqLOpUTVeKbkJ6uPi0EYistd=BowAHdtSmaUYYDhU6c9Sg@mail.gmail.com>
References: <1439570374-4079-1-git-send-email-gkulkarni@caviumnetworks.com>
 <1439570374-4079-3-git-send-email-gkulkarni@caviumnetworks.com>
 <20150828123228.GE31748@leverpostej>
 <CAL_JsqLOpUTVeKbkJ6uPi0EYistd=BowAHdtSmaUYYDhU6c9Sg@mail.gmail.com>
Message-ID: <55E17F58.5020101@huawei.com>



On 2015/8/28 22:02, Rob Herring wrote:
> +benh
> 
> On Fri, Aug 28, 2015 at 7:32 AM, Mark Rutland <mark.rutland at arm.com> wrote:
>> Hi,
>>
>> On Fri, Aug 14, 2015 at 05:39:32PM +0100, Ganapatrao Kulkarni wrote:
>>> DT bindings for numa map for memory, cores and IOs using
>>> arm,associativity device node property.
>>
>> Given this is just a copy of ibm,associativity, I'm not sure I see much
>> point in renaming the properties.
> 
> So just keep the ibm? I'm okay with that. That would help move to
> common code. Alternatively, we could drop the vendor prefix and have
> common code just check for both.
> 

Hi all,

Why not copy the method of ACPI numa? There only three elements should be configured:
1) a cpu belong to which node
2) a memory block belong to which node
3) the distance of each two nodes

The devicetree nodes of numa can be like below:
/ {
	...

	numa-nodes-info {
		node-name: node-description {
			mem-ranges = <...>;
			cpus-list = <...>;
		};

		nodes-distance {
			distance-list = <...>;
		};
	};

	...
};

Sorry, I don't think xxx,associativity is a good method, it's hard to config, and it
seems hardware-dependent. Especially, when we want to support memory hot-add, it's too hard.
Because xxx,associativity have no obvious information about it. Like powerpc, it use another
property: "/ibm,dynamic-reconfiguration-memory".

I spend almost a whole month to implement of_numa(configured by dt-nodes), base upon my opinion
mentioned above. If somebody are interested in it, I can send my patchset to show it.

Regards,
Thunder.



From k.kozlowski at samsung.com  Sat Aug 29 02:55:21 2015
From: k.kozlowski at samsung.com (Krzysztof Kozlowski)
Date: Sat, 29 Aug 2015 18:55:21 +0900
Subject: [PATCH] ARM: exynos_defconfig: Enable big.LITTLE CPUidle support
In-Reply-To: <55E17C56.4080200@osg.samsung.com>
References: <1440749769-10135-1-git-send-email-javier@osg.samsung.com>
 <55E174F3.1030202@samsung.com> <55E17C56.4080200@osg.samsung.com>
Message-ID: <CAJKOXPerJFZqeqNrVrdQnP7YB23LiWf+ZWYHBsWGRvqDQ-PJGA@mail.gmail.com>

2015-08-29 18:33 GMT+09:00 Javier Martinez Canillas <javier at osg.samsung.com>:
> Hello Krzysztof,
>
> On 08/29/2015 11:01 AM, Krzysztof Kozlowski wrote:
>> W dniu 28.08.2015 o 17:16, Javier Martinez Canillas pisze:
>>> Some Exynos big.LITTLE boards (i.e: Exynos5420 and Exynos5800 based
>>> Chromebooks) have proper firmware that allow the big.LITTLE CPUidle
>>> driver to work correctly, so enable support for this.
>>>
>>> Signed-off-by: Javier Martinez Canillas <javier at osg.samsung.com>
>>>
>>> ---
>>> Kukjin and Krzysztof,
>>>
>>> As you know there are other boards like the Exynos5422 based Odroid XU{3,4}
>>> whose firmware is broken due leaving CCI in secure mode which means that the
>>> kernel MCPM support can't properly manage CCI.
>>>
>>> So if you pick this patch, it should be tested in kernelci before appearing
>>> in linux-next to prevent any boot issues.
>>>
>>> But if that happens, I believe that is better to do a fix / workaround in
>>> those broken platforms since nothing prevents users to enable this option
>>> anyways. For example the CCI device node could be disabled in the DTS.
>>>
>>>  arch/arm/configs/exynos_defconfig | 1 +
>>>  1 file changed, 1 insertion(+)
>>
>> On Odroid XU3L (next-20150828, Hardkernel u-boot) boot hangs just after:
>>
>
> Thanks for testing, I was expecting that is just that I don't have a
> Odroid XU{3,4} board for test here, I guess I should get one.
>
>> [    2.568650] dwmmc_exynos 12200000.mmc: num-slots property not found,
>> assuming 1 slot is available
>>
>> ... so no. NACK :). First the boards, firmware, bootloader or kernel
>
> Agreed with the nack :)
>
>> code have to be fixed.
>>
>
> Or disable CCI, could you please test the following patch [0] so I
> can post it properly?

It fixes the boot hang but causes other issues. Not all CPUs boot (I
tested it on Chanho Park's patch for fixing CPU boot with SWRESET):
[    0.010781] CPU0: update cpu_capacity 448
[    0.010839] CPU0: thread -1, cpu 0, socket 1, mpidr 80000100
[    0.011098] Setting up static identity map for 0x40008280 - 0x400082d8
[    0.056329] CPU1: update cpu_capacity 448
[    0.056337] CPU1: thread -1, cpu 1, socket 0, mpidr 80000001
[    0.071100] CPU2: update cpu_capacity 448
[    0.071107] CPU2: thread -1, cpu 2, socket 0, mpidr 80000002
[    0.086103] CPU3: update cpu_capacity 448
[    0.086111] CPU3: thread -1, cpu 3, socket 0, mpidr 80000003
[    0.101100] CPU4: update cpu_capacity 1535
[    0.101108] CPU4: thread -1, cpu 0, socket 0, mpidr 80000000
[    1.115009] CPU5: failed to boot: -110
[    2.130019] CPU6: failed to boot: -110
[    3.145049] CPU7: failed to boot: -110
[    3.145151] Brought up 5 CPUs
[    3.145196] SMP: Total of 5 processors activated (240.00 BogoMIPS).
[    3.145251] CPU: WARNING: CPU(s) started in wrong/inconsistent
modes (primary CPU mode 0x13)
[    3.145327] CPU: This may indicate a broken bootloader or firmware.
[    3.149347] devtmpfs: initialized

Best regards,
Krzysztof


>
>> Best regards,
>> Krzysztof
>>
>
> Best regards,
> --
> Javier Martinez Canillas
> Open Source Group
> Samsung Research America
>
> [0]:
> From 0fc5649b8d939ccfb7d3be1aa09df5e1f89a5a82 Mon Sep 17 00:00:00 2001
> From: Javier Martinez Canillas <javier at osg.samsung.com>
> Date: Sat, 29 Aug 2015 11:21:39 +0200
> Subject: [RFT PATCH] ARM: dts: Disable CCI support for Odroid XU{3,4} boards
>
> The Exynos5422 based Odroid XU{3,4} boards have a broken firmware that
> leaves CCI in secure mode which means that the kernel MCPM support can
> not properly manage CCI. This causes the machine to hang when entering
> into low power states for example triggered by the b.L CPUidle driver.
>
> The patch is based on commit 25217fef3551 ("ARM: dts: disable CCI on
> exynos5420 based arndale-octa")
>
> Signed-off-by: Javier Martinez Canillas <javier at osg.samsung.com>
> ---
>  arch/arm/boot/dts/exynos5422-odroidxu3-common.dtsi | 4 ++++
>  1 file changed, 4 insertions(+)
>
> diff --git a/arch/arm/boot/dts/exynos5422-odroidxu3-common.dtsi b/arch/arm/boot/dts/exynos5422-odroidxu3-common.dtsi
> index dd8bc86d9de4..1e076458fab6 100644
> --- a/arch/arm/boot/dts/exynos5422-odroidxu3-common.dtsi
> +++ b/arch/arm/boot/dts/exynos5422-odroidxu3-common.dtsi
> @@ -525,3 +525,7 @@
>         vdd33-supply = <&ldo9_reg>;
>         vdd10-supply = <&ldo11_reg>;
>  };
> +
> +&cci {
> +       status = "disabled";
> +};
> --
> 2.4.3
> --
> To unsubscribe from this list: send the line "unsubscribe linux-samsung-soc" in
> the body of a message to majordomo at vger.kernel.org
> More majordomo info at  http://vger.kernel.org/majordomo-info.html


From javier at dowhile0.org  Sat Aug 29 03:07:45 2015
From: javier at dowhile0.org (Javier Martinez Canillas)
Date: Sat, 29 Aug 2015 12:07:45 +0200
Subject: [PATCH] ARM: exynos_defconfig: Enable big.LITTLE CPUidle support
In-Reply-To: <CAJKOXPerJFZqeqNrVrdQnP7YB23LiWf+ZWYHBsWGRvqDQ-PJGA@mail.gmail.com>
References: <1440749769-10135-1-git-send-email-javier@osg.samsung.com>
 <55E174F3.1030202@samsung.com> <55E17C56.4080200@osg.samsung.com>
 <CAJKOXPerJFZqeqNrVrdQnP7YB23LiWf+ZWYHBsWGRvqDQ-PJGA@mail.gmail.com>
Message-ID: <CABxcv=nwXc-_Y7qdZ56EGxM266Yifm56m6+Pb8iTHSWLHHSkfA@mail.gmail.com>

Hello Krzysztof,

On Sat, Aug 29, 2015 at 11:55 AM, Krzysztof Kozlowski
<k.kozlowski at samsung.com> wrote:
> 2015-08-29 18:33 GMT+09:00 Javier Martinez Canillas <javier at osg.samsung.com>:
>> Hello Krzysztof,
>>
>> On 08/29/2015 11:01 AM, Krzysztof Kozlowski wrote:
>>> W dniu 28.08.2015 o 17:16, Javier Martinez Canillas pisze:
>>>> Some Exynos big.LITTLE boards (i.e: Exynos5420 and Exynos5800 based
>>>> Chromebooks) have proper firmware that allow the big.LITTLE CPUidle
>>>> driver to work correctly, so enable support for this.
>>>>
>>>> Signed-off-by: Javier Martinez Canillas <javier at osg.samsung.com>
>>>>
>>>> ---
>>>> Kukjin and Krzysztof,
>>>>
>>>> As you know there are other boards like the Exynos5422 based Odroid XU{3,4}
>>>> whose firmware is broken due leaving CCI in secure mode which means that the
>>>> kernel MCPM support can't properly manage CCI.
>>>>
>>>> So if you pick this patch, it should be tested in kernelci before appearing
>>>> in linux-next to prevent any boot issues.
>>>>
>>>> But if that happens, I believe that is better to do a fix / workaround in
>>>> those broken platforms since nothing prevents users to enable this option
>>>> anyways. For example the CCI device node could be disabled in the DTS.
>>>>
>>>>  arch/arm/configs/exynos_defconfig | 1 +
>>>>  1 file changed, 1 insertion(+)
>>>
>>> On Odroid XU3L (next-20150828, Hardkernel u-boot) boot hangs just after:
>>>
>>
>> Thanks for testing, I was expecting that is just that I don't have a
>> Odroid XU{3,4} board for test here, I guess I should get one.
>>
>>> [    2.568650] dwmmc_exynos 12200000.mmc: num-slots property not found,
>>> assuming 1 slot is available
>>>
>>> ... so no. NACK :). First the boards, firmware, bootloader or kernel
>>
>> Agreed with the nack :)
>>
>>> code have to be fixed.
>>>
>>
>> Or disable CCI, could you please test the following patch [0] so I
>> can post it properly?
>
> It fixes the boot hang but causes other issues. Not all CPUs boot (I

Thanks for testing.

> tested it on Chanho Park's patch for fixing CPU boot with SWRESET):
> [    0.010781] CPU0: update cpu_capacity 448
> [    0.010839] CPU0: thread -1, cpu 0, socket 1, mpidr 80000100
> [    0.011098] Setting up static identity map for 0x40008280 - 0x400082d8
> [    0.056329] CPU1: update cpu_capacity 448
> [    0.056337] CPU1: thread -1, cpu 1, socket 0, mpidr 80000001
> [    0.071100] CPU2: update cpu_capacity 448
> [    0.071107] CPU2: thread -1, cpu 2, socket 0, mpidr 80000002
> [    0.086103] CPU3: update cpu_capacity 448
> [    0.086111] CPU3: thread -1, cpu 3, socket 0, mpidr 80000003
> [    0.101100] CPU4: update cpu_capacity 1535
> [    0.101108] CPU4: thread -1, cpu 0, socket 0, mpidr 80000000
> [    1.115009] CPU5: failed to boot: -110
> [    2.130019] CPU6: failed to boot: -110
> [    3.145049] CPU7: failed to boot: -110
> [    3.145151] Brought up 5 CPUs
> [    3.145196] SMP: Total of 5 processors activated (240.00 BogoMIPS).
> [    3.145251] CPU: WARNING: CPU(s) started in wrong/inconsistent
> modes (primary CPU mode 0x13)
> [    3.145327] CPU: This may indicate a broken bootloader or firmware.
> [    3.149347] devtmpfs: initialized
>

Sigh, such an inconsistent behavior between Exynos5420/5422/5800 boards :-/

Any ideas? I agree that the b.L CPUidle support shouldn't be enabled
by default in exynos_defconfig but as I said nothing prevents the user
to enable that option and make the board to hang on boot.

> Best regards,
> Krzysztof
>

Best regards,
Javier


From k.kozlowski at samsung.com  Sat Aug 29 03:22:57 2015
From: k.kozlowski at samsung.com (Krzysztof Kozlowski)
Date: Sat, 29 Aug 2015 19:22:57 +0900
Subject: [PATCH] ARM: exynos_defconfig: Enable big.LITTLE CPUidle support
In-Reply-To: <CABxcv=nwXc-_Y7qdZ56EGxM266Yifm56m6+Pb8iTHSWLHHSkfA@mail.gmail.com>
References: <1440749769-10135-1-git-send-email-javier@osg.samsung.com>
 <55E174F3.1030202@samsung.com> <55E17C56.4080200@osg.samsung.com>
 <CAJKOXPerJFZqeqNrVrdQnP7YB23LiWf+ZWYHBsWGRvqDQ-PJGA@mail.gmail.com>
 <CABxcv=nwXc-_Y7qdZ56EGxM266Yifm56m6+Pb8iTHSWLHHSkfA@mail.gmail.com>
Message-ID: <CAJKOXPdVDSPgFPkdnLBezimSHs+N0=5KCyXB=CQqMQy3LAcFVw@mail.gmail.com>

2015-08-29 19:07 GMT+09:00 Javier Martinez Canillas <javier at dowhile0.org>:
> Hello Krzysztof,
>
> On Sat, Aug 29, 2015 at 11:55 AM, Krzysztof Kozlowski
> <k.kozlowski at samsung.com> wrote:
>> 2015-08-29 18:33 GMT+09:00 Javier Martinez Canillas <javier at osg.samsung.com>:
>>> Hello Krzysztof,
>>>
>>> On 08/29/2015 11:01 AM, Krzysztof Kozlowski wrote:
>>>> W dniu 28.08.2015 o 17:16, Javier Martinez Canillas pisze:
>>>>> Some Exynos big.LITTLE boards (i.e: Exynos5420 and Exynos5800 based
>>>>> Chromebooks) have proper firmware that allow the big.LITTLE CPUidle
>>>>> driver to work correctly, so enable support for this.
>>>>>
>>>>> Signed-off-by: Javier Martinez Canillas <javier at osg.samsung.com>
>>>>>
>>>>> ---
>>>>> Kukjin and Krzysztof,
>>>>>
>>>>> As you know there are other boards like the Exynos5422 based Odroid XU{3,4}
>>>>> whose firmware is broken due leaving CCI in secure mode which means that the
>>>>> kernel MCPM support can't properly manage CCI.
>>>>>
>>>>> So if you pick this patch, it should be tested in kernelci before appearing
>>>>> in linux-next to prevent any boot issues.
>>>>>
>>>>> But if that happens, I believe that is better to do a fix / workaround in
>>>>> those broken platforms since nothing prevents users to enable this option
>>>>> anyways. For example the CCI device node could be disabled in the DTS.
>>>>>
>>>>>  arch/arm/configs/exynos_defconfig | 1 +
>>>>>  1 file changed, 1 insertion(+)
>>>>
>>>> On Odroid XU3L (next-20150828, Hardkernel u-boot) boot hangs just after:
>>>>
>>>
>>> Thanks for testing, I was expecting that is just that I don't have a
>>> Odroid XU{3,4} board for test here, I guess I should get one.
>>>
>>>> [    2.568650] dwmmc_exynos 12200000.mmc: num-slots property not found,
>>>> assuming 1 slot is available
>>>>
>>>> ... so no. NACK :). First the boards, firmware, bootloader or kernel
>>>
>>> Agreed with the nack :)
>>>
>>>> code have to be fixed.
>>>>
>>>
>>> Or disable CCI, could you please test the following patch [0] so I
>>> can post it properly?
>>
>> It fixes the boot hang but causes other issues. Not all CPUs boot (I
>
> Thanks for testing.
>
>> tested it on Chanho Park's patch for fixing CPU boot with SWRESET):
>> [    0.010781] CPU0: update cpu_capacity 448
>> [    0.010839] CPU0: thread -1, cpu 0, socket 1, mpidr 80000100
>> [    0.011098] Setting up static identity map for 0x40008280 - 0x400082d8
>> [    0.056329] CPU1: update cpu_capacity 448
>> [    0.056337] CPU1: thread -1, cpu 1, socket 0, mpidr 80000001
>> [    0.071100] CPU2: update cpu_capacity 448
>> [    0.071107] CPU2: thread -1, cpu 2, socket 0, mpidr 80000002
>> [    0.086103] CPU3: update cpu_capacity 448
>> [    0.086111] CPU3: thread -1, cpu 3, socket 0, mpidr 80000003
>> [    0.101100] CPU4: update cpu_capacity 1535
>> [    0.101108] CPU4: thread -1, cpu 0, socket 0, mpidr 80000000
>> [    1.115009] CPU5: failed to boot: -110
>> [    2.130019] CPU6: failed to boot: -110
>> [    3.145049] CPU7: failed to boot: -110
>> [    3.145151] Brought up 5 CPUs
>> [    3.145196] SMP: Total of 5 processors activated (240.00 BogoMIPS).
>> [    3.145251] CPU: WARNING: CPU(s) started in wrong/inconsistent
>> modes (primary CPU mode 0x13)
>> [    3.145327] CPU: This may indicate a broken bootloader or firmware.
>> [    3.149347] devtmpfs: initialized
>>
>
> Sigh, such an inconsistent behavior between Exynos5420/5422/5800 boards :-/

I put all my hope into Przemyslaw's work :)

>
> Any ideas? I agree that the b.L CPUidle support shouldn't be enabled
> by default in exynos_defconfig but as I said nothing prevents the user
> to enable that option and make the board to hang on boot.

I think these are actually two different issues:
1. If user enables b.L cpuidle manually, some of the Exynos542x boards
would work (Peach Pi, AFAIU?) and some would not (Odroid XU3, probably
also Arndale Octa). If we cannot fix firmware then we could implement
a workaround in Exynos code. However it shouldn't be DTS but rather
the mach code.
2. The default config should be a reference config so it should work
on all boards and should offer all necessary features on them (or even
all features). Enabling the b.L in it makes sense only if it does not
introduce regressions to other boards. If we cannot achieve that
(Odroid XU3 will be affected negatively) then still we could fix issue
#1 so user's manual setting would work.

BR,
Krzysztof


From javier at dowhile0.org  Sat Aug 29 03:31:47 2015
From: javier at dowhile0.org (Javier Martinez Canillas)
Date: Sat, 29 Aug 2015 12:31:47 +0200
Subject: [PATCH] ARM: exynos_defconfig: Enable big.LITTLE CPUidle support
In-Reply-To: <CAJKOXPdVDSPgFPkdnLBezimSHs+N0=5KCyXB=CQqMQy3LAcFVw@mail.gmail.com>
References: <1440749769-10135-1-git-send-email-javier@osg.samsung.com>
 <55E174F3.1030202@samsung.com> <55E17C56.4080200@osg.samsung.com>
 <CAJKOXPerJFZqeqNrVrdQnP7YB23LiWf+ZWYHBsWGRvqDQ-PJGA@mail.gmail.com>
 <CABxcv=nwXc-_Y7qdZ56EGxM266Yifm56m6+Pb8iTHSWLHHSkfA@mail.gmail.com>
 <CAJKOXPdVDSPgFPkdnLBezimSHs+N0=5KCyXB=CQqMQy3LAcFVw@mail.gmail.com>
Message-ID: <CABxcv=m0K_jR689RiEGGJ40sVASK8E6S02cUY344qMXdtwLo9g@mail.gmail.com>

Hello Krzysztof,

On Sat, Aug 29, 2015 at 12:22 PM, Krzysztof Kozlowski
<k.kozlowski at samsung.com> wrote:
> 2015-08-29 19:07 GMT+09:00 Javier Martinez Canillas <javier at dowhile0.org>:
>> Hello Krzysztof,
>>
>> On Sat, Aug 29, 2015 at 11:55 AM, Krzysztof Kozlowski
>> <k.kozlowski at samsung.com> wrote:
>>> 2015-08-29 18:33 GMT+09:00 Javier Martinez Canillas <javier at osg.samsung.com>:
>>>> Hello Krzysztof,
>>>>
>>>> On 08/29/2015 11:01 AM, Krzysztof Kozlowski wrote:
>>>>> W dniu 28.08.2015 o 17:16, Javier Martinez Canillas pisze:
>>>>>> Some Exynos big.LITTLE boards (i.e: Exynos5420 and Exynos5800 based
>>>>>> Chromebooks) have proper firmware that allow the big.LITTLE CPUidle
>>>>>> driver to work correctly, so enable support for this.
>>>>>>
>>>>>> Signed-off-by: Javier Martinez Canillas <javier at osg.samsung.com>
>>>>>>
>>>>>> ---
>>>>>> Kukjin and Krzysztof,
>>>>>>
>>>>>> As you know there are other boards like the Exynos5422 based Odroid XU{3,4}
>>>>>> whose firmware is broken due leaving CCI in secure mode which means that the
>>>>>> kernel MCPM support can't properly manage CCI.
>>>>>>
>>>>>> So if you pick this patch, it should be tested in kernelci before appearing
>>>>>> in linux-next to prevent any boot issues.
>>>>>>
>>>>>> But if that happens, I believe that is better to do a fix / workaround in
>>>>>> those broken platforms since nothing prevents users to enable this option
>>>>>> anyways. For example the CCI device node could be disabled in the DTS.
>>>>>>
>>>>>>  arch/arm/configs/exynos_defconfig | 1 +
>>>>>>  1 file changed, 1 insertion(+)
>>>>>
>>>>> On Odroid XU3L (next-20150828, Hardkernel u-boot) boot hangs just after:
>>>>>
>>>>
>>>> Thanks for testing, I was expecting that is just that I don't have a
>>>> Odroid XU{3,4} board for test here, I guess I should get one.
>>>>
>>>>> [    2.568650] dwmmc_exynos 12200000.mmc: num-slots property not found,
>>>>> assuming 1 slot is available
>>>>>
>>>>> ... so no. NACK :). First the boards, firmware, bootloader or kernel
>>>>
>>>> Agreed with the nack :)
>>>>
>>>>> code have to be fixed.
>>>>>
>>>>
>>>> Or disable CCI, could you please test the following patch [0] so I
>>>> can post it properly?
>>>
>>> It fixes the boot hang but causes other issues. Not all CPUs boot (I
>>
>> Thanks for testing.
>>
>>> tested it on Chanho Park's patch for fixing CPU boot with SWRESET):
>>> [    0.010781] CPU0: update cpu_capacity 448
>>> [    0.010839] CPU0: thread -1, cpu 0, socket 1, mpidr 80000100
>>> [    0.011098] Setting up static identity map for 0x40008280 - 0x400082d8
>>> [    0.056329] CPU1: update cpu_capacity 448
>>> [    0.056337] CPU1: thread -1, cpu 1, socket 0, mpidr 80000001
>>> [    0.071100] CPU2: update cpu_capacity 448
>>> [    0.071107] CPU2: thread -1, cpu 2, socket 0, mpidr 80000002
>>> [    0.086103] CPU3: update cpu_capacity 448
>>> [    0.086111] CPU3: thread -1, cpu 3, socket 0, mpidr 80000003
>>> [    0.101100] CPU4: update cpu_capacity 1535
>>> [    0.101108] CPU4: thread -1, cpu 0, socket 0, mpidr 80000000
>>> [    1.115009] CPU5: failed to boot: -110
>>> [    2.130019] CPU6: failed to boot: -110
>>> [    3.145049] CPU7: failed to boot: -110
>>> [    3.145151] Brought up 5 CPUs
>>> [    3.145196] SMP: Total of 5 processors activated (240.00 BogoMIPS).
>>> [    3.145251] CPU: WARNING: CPU(s) started in wrong/inconsistent
>>> modes (primary CPU mode 0x13)
>>> [    3.145327] CPU: This may indicate a broken bootloader or firmware.
>>> [    3.149347] devtmpfs: initialized
>>>
>>
>> Sigh, such an inconsistent behavior between Exynos5420/5422/5800 boards :-/
>
> I put all my hope into Przemyslaw's work :)
>

Me too :)

>>
>> Any ideas? I agree that the b.L CPUidle support shouldn't be enabled
>> by default in exynos_defconfig but as I said nothing prevents the user
>> to enable that option and make the board to hang on boot.
>
> I think these are actually two different issues:
> 1. If user enables b.L cpuidle manually, some of the Exynos542x boards
> would work (Peach Pi, AFAIU?) and some would not (Odroid XU3, probably

Yes, Exynos5800 Peach Pi and Exynos5420 Peach Pit IIRC.

> also Arndale Octa). If we cannot fix firmware then we could implement
> a workaround in Exynos code. However it shouldn't be DTS but rather
> the mach code.

Agreed about adding a workaround in mach code.

> 2. The default config should be a reference config so it should work
> on all boards and should offer all necessary features on them (or even
> all features). Enabling the b.L in it makes sense only if it does not
> introduce regressions to other boards. If we cannot achieve that
> (Odroid XU3 will be affected negatively) then still we could fix issue
> #1 so user's manual setting would work.
>

Yes but if we achieve #1, then I think that b.L CPUidle support should
be enabled by default in exynos_defconfig even when it does not work
on some boards (as long as don't affect negatively) so users of boards
that do work can have that feature out of the box without figuring out
what additional config options needs to be enabled.

Or that's what you meant and I misunderstood?

> BR,
> Krzysztof

Best regards,
Javier


From k.kozlowski at samsung.com  Sat Aug 29 03:39:38 2015
From: k.kozlowski at samsung.com (Krzysztof Kozlowski)
Date: Sat, 29 Aug 2015 19:39:38 +0900
Subject: [PATCH] ARM: exynos_defconfig: Enable big.LITTLE CPUidle support
In-Reply-To: <CABxcv=m0K_jR689RiEGGJ40sVASK8E6S02cUY344qMXdtwLo9g@mail.gmail.com>
References: <1440749769-10135-1-git-send-email-javier@osg.samsung.com>
 <55E174F3.1030202@samsung.com> <55E17C56.4080200@osg.samsung.com>
 <CAJKOXPerJFZqeqNrVrdQnP7YB23LiWf+ZWYHBsWGRvqDQ-PJGA@mail.gmail.com>
 <CABxcv=nwXc-_Y7qdZ56EGxM266Yifm56m6+Pb8iTHSWLHHSkfA@mail.gmail.com>
 <CAJKOXPdVDSPgFPkdnLBezimSHs+N0=5KCyXB=CQqMQy3LAcFVw@mail.gmail.com>
 <CABxcv=m0K_jR689RiEGGJ40sVASK8E6S02cUY344qMXdtwLo9g@mail.gmail.com>
Message-ID: <CAJKOXPeHPstPXxzyw1yBFKY-XR44j8vOfEPm4vq-_Fi6k09EGg@mail.gmail.com>

2015-08-29 19:31 GMT+09:00 Javier Martinez Canillas <javier at dowhile0.org>:
> Hello Krzysztof,
>
> On Sat, Aug 29, 2015 at 12:22 PM, Krzysztof Kozlowski
> <k.kozlowski at samsung.com> wrote:
>> 2015-08-29 19:07 GMT+09:00 Javier Martinez Canillas <javier at dowhile0.org>:
>>> Hello Krzysztof,
>>>
>>> On Sat, Aug 29, 2015 at 11:55 AM, Krzysztof Kozlowski
>>> <k.kozlowski at samsung.com> wrote:
>>>> 2015-08-29 18:33 GMT+09:00 Javier Martinez Canillas <javier at osg.samsung.com>:
>>>>> Hello Krzysztof,
>>>>>
>>>>> On 08/29/2015 11:01 AM, Krzysztof Kozlowski wrote:
>>>>>> W dniu 28.08.2015 o 17:16, Javier Martinez Canillas pisze:
>>>>>>> Some Exynos big.LITTLE boards (i.e: Exynos5420 and Exynos5800 based
>>>>>>> Chromebooks) have proper firmware that allow the big.LITTLE CPUidle
>>>>>>> driver to work correctly, so enable support for this.
>>>>>>>
>>>>>>> Signed-off-by: Javier Martinez Canillas <javier at osg.samsung.com>
>>>>>>>
>>>>>>> ---
>>>>>>> Kukjin and Krzysztof,
>>>>>>>
>>>>>>> As you know there are other boards like the Exynos5422 based Odroid XU{3,4}
>>>>>>> whose firmware is broken due leaving CCI in secure mode which means that the
>>>>>>> kernel MCPM support can't properly manage CCI.
>>>>>>>
>>>>>>> So if you pick this patch, it should be tested in kernelci before appearing
>>>>>>> in linux-next to prevent any boot issues.
>>>>>>>
>>>>>>> But if that happens, I believe that is better to do a fix / workaround in
>>>>>>> those broken platforms since nothing prevents users to enable this option
>>>>>>> anyways. For example the CCI device node could be disabled in the DTS.
>>>>>>>
>>>>>>>  arch/arm/configs/exynos_defconfig | 1 +
>>>>>>>  1 file changed, 1 insertion(+)
>>>>>>
>>>>>> On Odroid XU3L (next-20150828, Hardkernel u-boot) boot hangs just after:
>>>>>>
>>>>>
>>>>> Thanks for testing, I was expecting that is just that I don't have a
>>>>> Odroid XU{3,4} board for test here, I guess I should get one.
>>>>>
>>>>>> [    2.568650] dwmmc_exynos 12200000.mmc: num-slots property not found,
>>>>>> assuming 1 slot is available
>>>>>>
>>>>>> ... so no. NACK :). First the boards, firmware, bootloader or kernel
>>>>>
>>>>> Agreed with the nack :)
>>>>>
>>>>>> code have to be fixed.
>>>>>>
>>>>>
>>>>> Or disable CCI, could you please test the following patch [0] so I
>>>>> can post it properly?
>>>>
>>>> It fixes the boot hang but causes other issues. Not all CPUs boot (I
>>>
>>> Thanks for testing.
>>>
>>>> tested it on Chanho Park's patch for fixing CPU boot with SWRESET):
>>>> [    0.010781] CPU0: update cpu_capacity 448
>>>> [    0.010839] CPU0: thread -1, cpu 0, socket 1, mpidr 80000100
>>>> [    0.011098] Setting up static identity map for 0x40008280 - 0x400082d8
>>>> [    0.056329] CPU1: update cpu_capacity 448
>>>> [    0.056337] CPU1: thread -1, cpu 1, socket 0, mpidr 80000001
>>>> [    0.071100] CPU2: update cpu_capacity 448
>>>> [    0.071107] CPU2: thread -1, cpu 2, socket 0, mpidr 80000002
>>>> [    0.086103] CPU3: update cpu_capacity 448
>>>> [    0.086111] CPU3: thread -1, cpu 3, socket 0, mpidr 80000003
>>>> [    0.101100] CPU4: update cpu_capacity 1535
>>>> [    0.101108] CPU4: thread -1, cpu 0, socket 0, mpidr 80000000
>>>> [    1.115009] CPU5: failed to boot: -110
>>>> [    2.130019] CPU6: failed to boot: -110
>>>> [    3.145049] CPU7: failed to boot: -110
>>>> [    3.145151] Brought up 5 CPUs
>>>> [    3.145196] SMP: Total of 5 processors activated (240.00 BogoMIPS).
>>>> [    3.145251] CPU: WARNING: CPU(s) started in wrong/inconsistent
>>>> modes (primary CPU mode 0x13)
>>>> [    3.145327] CPU: This may indicate a broken bootloader or firmware.
>>>> [    3.149347] devtmpfs: initialized
>>>>
>>>
>>> Sigh, such an inconsistent behavior between Exynos5420/5422/5800 boards :-/
>>
>> I put all my hope into Przemyslaw's work :)
>>
>
> Me too :)
>
>>>
>>> Any ideas? I agree that the b.L CPUidle support shouldn't be enabled
>>> by default in exynos_defconfig but as I said nothing prevents the user
>>> to enable that option and make the board to hang on boot.
>>
>> I think these are actually two different issues:
>> 1. If user enables b.L cpuidle manually, some of the Exynos542x boards
>> would work (Peach Pi, AFAIU?) and some would not (Odroid XU3, probably
>
> Yes, Exynos5800 Peach Pi and Exynos5420 Peach Pit IIRC.
>
>> also Arndale Octa). If we cannot fix firmware then we could implement
>> a workaround in Exynos code. However it shouldn't be DTS but rather
>> the mach code.
>
> Agreed about adding a workaround in mach code.
>
>> 2. The default config should be a reference config so it should work
>> on all boards and should offer all necessary features on them (or even
>> all features). Enabling the b.L in it makes sense only if it does not
>> introduce regressions to other boards. If we cannot achieve that
>> (Odroid XU3 will be affected negatively) then still we could fix issue
>> #1 so user's manual setting would work.
>>
>
> Yes but if we achieve #1, then I think that b.L CPUidle support should
> be enabled by default in exynos_defconfig even when it does not work
> on some boards (as long as don't affect negatively) so users of boards
> that do work can have that feature out of the box without figuring out
> what additional config options needs to be enabled.
>
> Or that's what you meant and I misunderstood?

If there won't be negative impact then sure, it could be enabled.
However as we saw above, disabling CCI (which is a fix for cpuidle b.L
on XU3) has negative impact. Of course there could be other
workarounds...

Best regards,
Krzysztof


From benh at kernel.crashing.org  Sat Aug 29 03:37:11 2015
From: benh at kernel.crashing.org (Benjamin Herrenschmidt)
Date: Sat, 29 Aug 2015 20:37:11 +1000
Subject: [PATCH v5 2/4] Documentation: arm64/arm: dt bindings for numa.
In-Reply-To: <55E17F58.5020101@huawei.com>
References: <1439570374-4079-1-git-send-email-gkulkarni@caviumnetworks.com>
 <1439570374-4079-3-git-send-email-gkulkarni@caviumnetworks.com>
 <20150828123228.GE31748@leverpostej>
 <CAL_JsqLOpUTVeKbkJ6uPi0EYistd=BowAHdtSmaUYYDhU6c9Sg@mail.gmail.com>
 <55E17F58.5020101@huawei.com>
Message-ID: <1440844631.2912.248.camel@kernel.crashing.org>

On Sat, 2015-08-29 at 17:46 +0800, Leizhen (ThunderTown) wrote:
> Why not copy the method of ACPI numa? There only three elements
> should be configured:
> 1) a cpu belong to which node
> 2) a memory block belong to which node
> 3) the distance of each two nodes

This means your are bolting into the DT representation the concept of
"Node" which isn't necessarily very meaningful.

Your system is really a hierarchy of objects. You can have cores on a
chip, already possibly sharing some level of cache or not, you can have
chips on a module, modules linked at various distances, etc...

What is "a node" ?

For example, I have a P8 chip with 2 chips on a module (fast X-bus) and
2 modules (slightly slower A-bus). All 4 chips have 2 memory
controllers each.

Is a "node" a chip or a module ?

The Linux concept of node is too restrictive. The associativity
properties avoid this by allowing you to define as many "levels" of
associativity as you wish. Also since it's right justified, a given
component doesn't need to have all levels (a MC can stop at chip while
cores can go down one more level for example).

The reference points property gives a hint as "interesting" levels can
typically be used as a hint for chosing what Linux will use as a "node"
at least until Linux gets smarter. It can also be used to calculate
distances.

Cheers,
Ben.



From javier at dowhile0.org  Sat Aug 29 03:47:53 2015
From: javier at dowhile0.org (Javier Martinez Canillas)
Date: Sat, 29 Aug 2015 12:47:53 +0200
Subject: [PATCH] ARM: exynos_defconfig: Enable big.LITTLE CPUidle support
In-Reply-To: <CAJKOXPeHPstPXxzyw1yBFKY-XR44j8vOfEPm4vq-_Fi6k09EGg@mail.gmail.com>
References: <1440749769-10135-1-git-send-email-javier@osg.samsung.com>
 <55E174F3.1030202@samsung.com> <55E17C56.4080200@osg.samsung.com>
 <CAJKOXPerJFZqeqNrVrdQnP7YB23LiWf+ZWYHBsWGRvqDQ-PJGA@mail.gmail.com>
 <CABxcv=nwXc-_Y7qdZ56EGxM266Yifm56m6+Pb8iTHSWLHHSkfA@mail.gmail.com>
 <CAJKOXPdVDSPgFPkdnLBezimSHs+N0=5KCyXB=CQqMQy3LAcFVw@mail.gmail.com>
 <CABxcv=m0K_jR689RiEGGJ40sVASK8E6S02cUY344qMXdtwLo9g@mail.gmail.com>
 <CAJKOXPeHPstPXxzyw1yBFKY-XR44j8vOfEPm4vq-_Fi6k09EGg@mail.gmail.com>
Message-ID: <CABxcv=nHWEBJc0w_26W+Xs5=PQv0Pz=9aFYQnaFyhzwu08110g@mail.gmail.com>

Hello Krzysztof,

On Sat, Aug 29, 2015 at 12:39 PM, Krzysztof Kozlowski
<k.kozlowski at samsung.com> wrote:
> 2015-08-29 19:31 GMT+09:00 Javier Martinez Canillas <javier at dowhile0.org>:
>> Hello Krzysztof,
>>
>> On Sat, Aug 29, 2015 at 12:22 PM, Krzysztof Kozlowski
>> <k.kozlowski at samsung.com> wrote:
>>> 2015-08-29 19:07 GMT+09:00 Javier Martinez Canillas <javier at dowhile0.org>:
>>>> Hello Krzysztof,
>>>>
>>>> On Sat, Aug 29, 2015 at 11:55 AM, Krzysztof Kozlowski
>>>> <k.kozlowski at samsung.com> wrote:
>>>>> 2015-08-29 18:33 GMT+09:00 Javier Martinez Canillas <javier at osg.samsung.com>:
>>>>>> Hello Krzysztof,
>>>>>>
>>>>>> On 08/29/2015 11:01 AM, Krzysztof Kozlowski wrote:
>>>>>>> W dniu 28.08.2015 o 17:16, Javier Martinez Canillas pisze:
>>>>>>>> Some Exynos big.LITTLE boards (i.e: Exynos5420 and Exynos5800 based
>>>>>>>> Chromebooks) have proper firmware that allow the big.LITTLE CPUidle
>>>>>>>> driver to work correctly, so enable support for this.
>>>>>>>>
>>>>>>>> Signed-off-by: Javier Martinez Canillas <javier at osg.samsung.com>
>>>>>>>>
>>>>>>>> ---
>>>>>>>> Kukjin and Krzysztof,
>>>>>>>>
>>>>>>>> As you know there are other boards like the Exynos5422 based Odroid XU{3,4}
>>>>>>>> whose firmware is broken due leaving CCI in secure mode which means that the
>>>>>>>> kernel MCPM support can't properly manage CCI.
>>>>>>>>
>>>>>>>> So if you pick this patch, it should be tested in kernelci before appearing
>>>>>>>> in linux-next to prevent any boot issues.
>>>>>>>>
>>>>>>>> But if that happens, I believe that is better to do a fix / workaround in
>>>>>>>> those broken platforms since nothing prevents users to enable this option
>>>>>>>> anyways. For example the CCI device node could be disabled in the DTS.
>>>>>>>>
>>>>>>>>  arch/arm/configs/exynos_defconfig | 1 +
>>>>>>>>  1 file changed, 1 insertion(+)
>>>>>>>
>>>>>>> On Odroid XU3L (next-20150828, Hardkernel u-boot) boot hangs just after:
>>>>>>>
>>>>>>
>>>>>> Thanks for testing, I was expecting that is just that I don't have a
>>>>>> Odroid XU{3,4} board for test here, I guess I should get one.
>>>>>>
>>>>>>> [    2.568650] dwmmc_exynos 12200000.mmc: num-slots property not found,
>>>>>>> assuming 1 slot is available
>>>>>>>
>>>>>>> ... so no. NACK :). First the boards, firmware, bootloader or kernel
>>>>>>
>>>>>> Agreed with the nack :)
>>>>>>
>>>>>>> code have to be fixed.
>>>>>>>
>>>>>>
>>>>>> Or disable CCI, could you please test the following patch [0] so I
>>>>>> can post it properly?
>>>>>
>>>>> It fixes the boot hang but causes other issues. Not all CPUs boot (I
>>>>
>>>> Thanks for testing.
>>>>
>>>>> tested it on Chanho Park's patch for fixing CPU boot with SWRESET):
>>>>> [    0.010781] CPU0: update cpu_capacity 448
>>>>> [    0.010839] CPU0: thread -1, cpu 0, socket 1, mpidr 80000100
>>>>> [    0.011098] Setting up static identity map for 0x40008280 - 0x400082d8
>>>>> [    0.056329] CPU1: update cpu_capacity 448
>>>>> [    0.056337] CPU1: thread -1, cpu 1, socket 0, mpidr 80000001
>>>>> [    0.071100] CPU2: update cpu_capacity 448
>>>>> [    0.071107] CPU2: thread -1, cpu 2, socket 0, mpidr 80000002
>>>>> [    0.086103] CPU3: update cpu_capacity 448
>>>>> [    0.086111] CPU3: thread -1, cpu 3, socket 0, mpidr 80000003
>>>>> [    0.101100] CPU4: update cpu_capacity 1535
>>>>> [    0.101108] CPU4: thread -1, cpu 0, socket 0, mpidr 80000000
>>>>> [    1.115009] CPU5: failed to boot: -110
>>>>> [    2.130019] CPU6: failed to boot: -110
>>>>> [    3.145049] CPU7: failed to boot: -110
>>>>> [    3.145151] Brought up 5 CPUs
>>>>> [    3.145196] SMP: Total of 5 processors activated (240.00 BogoMIPS).
>>>>> [    3.145251] CPU: WARNING: CPU(s) started in wrong/inconsistent
>>>>> modes (primary CPU mode 0x13)
>>>>> [    3.145327] CPU: This may indicate a broken bootloader or firmware.
>>>>> [    3.149347] devtmpfs: initialized
>>>>>
>>>>
>>>> Sigh, such an inconsistent behavior between Exynos5420/5422/5800 boards :-/
>>>
>>> I put all my hope into Przemyslaw's work :)
>>>
>>
>> Me too :)
>>
>>>>
>>>> Any ideas? I agree that the b.L CPUidle support shouldn't be enabled
>>>> by default in exynos_defconfig but as I said nothing prevents the user
>>>> to enable that option and make the board to hang on boot.
>>>
>>> I think these are actually two different issues:
>>> 1. If user enables b.L cpuidle manually, some of the Exynos542x boards
>>> would work (Peach Pi, AFAIU?) and some would not (Odroid XU3, probably
>>
>> Yes, Exynos5800 Peach Pi and Exynos5420 Peach Pit IIRC.
>>
>>> also Arndale Octa). If we cannot fix firmware then we could implement
>>> a workaround in Exynos code. However it shouldn't be DTS but rather
>>> the mach code.
>>
>> Agreed about adding a workaround in mach code.
>>
>>> 2. The default config should be a reference config so it should work
>>> on all boards and should offer all necessary features on them (or even
>>> all features). Enabling the b.L in it makes sense only if it does not
>>> introduce regressions to other boards. If we cannot achieve that
>>> (Odroid XU3 will be affected negatively) then still we could fix issue
>>> #1 so user's manual setting would work.
>>>
>>
>> Yes but if we achieve #1, then I think that b.L CPUidle support should
>> be enabled by default in exynos_defconfig even when it does not work
>> on some boards (as long as don't affect negatively) so users of boards
>> that do work can have that feature out of the box without figuring out
>> what additional config options needs to be enabled.
>>
>> Or that's what you meant and I misunderstood?
>
> If there won't be negative impact then sure, it could be enabled.
> However as we saw above, disabling CCI (which is a fix for cpuidle b.L
> on XU3) has negative impact. Of course there could be other
> workarounds...
>

Yeah, I meant after / if we find a workaround in mach code as you
explained in #1.

> Best regards,
> Krzysztof

Best regards,
Javier


From lorenzo.pieralisi at arm.com  Sat Aug 29 05:44:57 2015
From: lorenzo.pieralisi at arm.com (Lorenzo Pieralisi)
Date: Sat, 29 Aug 2015 13:44:57 +0100
Subject: [PATCH] ARM64: PCI: do not enable resources on PROBE_ONLY systems
In-Reply-To: <20150828211444.GA27890@google.com>
References: <1438262039-32085-1-git-send-email-lorenzo.pieralisi@arm.com>
 <20150828211444.GA27890@google.com>
Message-ID: <20150829124457.GA18125@red-moon>

Hi Bjorn,

On Fri, Aug 28, 2015 at 10:14:44PM +0100, Bjorn Helgaas wrote:
> Hi Lorenzo,
> 
> On Thu, Jul 30, 2015 at 02:13:59PM +0100, Lorenzo Pieralisi wrote:
> > On ARM64 PROBE_ONLY PCI systems resources are not currently claimed,
> > therefore they can't be enabled since they do not have a valid
> > parent pointer; this in turn prevents enabling PCI devices on
> > ARM64 PROBE_ONLY systems, causing PCI devices initialization to
> > fail.
> 
> Where does arm64 claim PCI BAR resources for the non-PROBE_ONLY case?

arm64 (and arm) does not claim resources in arch code, they are always
assigned in the respective host controllers (or the pcibios on arm),
except for the PCI generic host when in PROBE_ONLY mode, where resources
are neither claimed nor assigned (the reason for this patch to exist).

Certainly something to consolidate as part of the rework we talked
about at LPC (PCI ACPI probing is yet another reason to consolidate it).

I am working on this, in particular I want to test how claiming the
resources by default will impact ARM systems.

For the records, Will kindly provided me with an Alpha box so that I can
test on it too.

> I know it must be there somewhere, but I don't see it.

It is not there, it is done in the host controllers by assigning the
resources (which also "claim" them by assigning the parent pointer).

Thanks,
Lorenzo

> 
> > To solve this issue, resources must be claimed when devices are
> > added on PROBE_ONLY systems, which ensures that the resource hierarchy
> > is validated and the resource tree is sane, but this requires changes
> > in the ARM64 resource management that can affect adversely existing
> > PCI set-ups (claiming resources on !PROBE_ONLY systems might break
> > existing ARM64 PCI platform implementations).
> > 
> > As a temporary solution in preparation for a proper resources claiming
> > implementation in ARM64 core, to enable PCI PROBE_ONLY systems on ARM64,
> > this patch adds a pcibios_enable_device() arch implementation that
> > simply prevents enabling resources on PROBE_ONLY systems (mirroring ARM
> > behaviour).
> > 
> > This is always a safe thing to do because on PROBE_ONLY systems the
> > configuration space set-up can be considered immutable, and it is in
> > preparation of proper resource claiming that would finally validate
> > the PCI resources tree in the ARM64 arch implementation on PROBE_ONLY
> > systems.
> > 
> > For !PROBE_ONLY systems resources enablement in pcibios_enable_device()
> > on ARM64 is implemented as in current PCI core, leaving the behaviour
> > unchanged.
> > 
> > Signed-off-by: Lorenzo Pieralisi <lorenzo.pieralisi at arm.com>
> > Cc: Will Deacon <will.deacon at arm.com>
> > Cc: Bjorn Helgaas <bhelgaas at google.com>
> > Cc: Catalin Marinas <catalin.marinas at arm.com>
> > ---
> > Bjorn, all,
> > 
> > as I mention in the commit log, this patch is a temporary solution
> > in preparation for proper resources claiming in ARM64, so that
> > we can safely enable the PCI generic host controller on ARM64 systems.
> > 
> > It mirrors ARM implementation and I will work on changing both
> > ARM and ARM64 to convert them to proper resources claiming in
> > the respective implementations.
> > 
> > Lorenzo
> > 
> >  arch/arm64/kernel/pci.c | 13 +++++++++++++
> >  1 file changed, 13 insertions(+)
> > 
> > diff --git a/arch/arm64/kernel/pci.c b/arch/arm64/kernel/pci.c
> > index 4095379..b3d098b 100644
> > --- a/arch/arm64/kernel/pci.c
> > +++ b/arch/arm64/kernel/pci.c
> > @@ -38,6 +38,19 @@ resource_size_t pcibios_align_resource(void *data, const struct resource *res,
> >  	return res->start;
> >  }
> >  
> > +/**
> > + * pcibios_enable_device - Enable I/O and memory.
> > + * @dev: PCI device to be enabled
> > + * @mask: bitmask of BARs to enable
> > + */
> > +int pcibios_enable_device(struct pci_dev *dev, int mask)
> > +{
> > +	if (pci_has_flag(PCI_PROBE_ONLY))
> > +		return 0;
> > +
> > +	return pci_enable_resources(dev, mask);
> > +}
> > +
> >  /*
> >   * Try to assign the IRQ number from DT when adding a new device
> >   */
> > -- 
> > 2.2.1
> > 
> 


From yangyingliang at huawei.com  Sat Aug 29 06:00:57 2015
From: yangyingliang at huawei.com (Yang Yingliang)
Date: Sat, 29 Aug 2015 21:00:57 +0800
Subject: [PATCH] arm64: fix a migrating irq bug when hotplug cpu
Message-ID: <55E1AD09.7020701@huawei.com>

From: Yang Yingliang <yangyingliang at huawei.com>

When cpu is disabled, all irqs will be migratged to another cpu.
In some cases, a new affinity is different, it needed to be coppied
to irq's affinity. But if the type of irq is LPI, it's affinity will
not be coppied because of irq_set_affinity's return value.
So copy the affinity, when the return value is IRQ_SET_MASK_OK_DONE.

Cc: Jiang Liu <jiang.liu at linux.intel.com>
Cc: Thomas Gleixner <tglx at linutronix.de>
Cc: Marc Zyngier <marc.zyngier at arm.com>
Cc: Mark Rutland <mark.rutland at arm.com>
Cc: Will Deacon <will.deacon at arm.com>
---
  arch/arm64/kernel/irq.c | 9 ++++++---
  1 file changed, 6 insertions(+), 3 deletions(-)

diff --git a/arch/arm64/kernel/irq.c b/arch/arm64/kernel/irq.c
index 463fa2e..2acc8ec 100644
--- a/arch/arm64/kernel/irq.c
+++ b/arch/arm64/kernel/irq.c
@@ -78,10 +78,13 @@ static bool migrate_one_irq(struct irq_desc *desc)
  	}

  	c = irq_data_get_irq_chip(d);
-	if (!c->irq_set_affinity)
+	if (!c->irq_set_affinity) {
  		pr_debug("IRQ%u: unable to set affinity\n", d->irq);
-	else if (c->irq_set_affinity(d, affinity, false) == IRQ_SET_MASK_OK && 
ret)
-		cpumask_copy(irq_data_get_affinity_mask(d), affinity);
+	} else if (c->irq_set_affinity(d, affinity, false) == IRQ_SET_MASK_OK 
&& ret) {
+		int r = c->irq_set_affinity(d, affinity, false);
+		if ((r == IRQ_SET_MASK_OK || r == IRQ_SET_MASK_OK_DONE) && ret)
+			cpumask_copy(irq_data_get_affinity_mask(d), affinity);
+	}

  	return ret;
  }
-- 
2.5.0



From yangyingliang at huawei.com  Sat Aug 29 06:07:17 2015
From: yangyingliang at huawei.com (Yang Yingliang)
Date: Sat, 29 Aug 2015 21:07:17 +0800
Subject: [PATCH] ARM: fix a migrating irq bug when hotplug cpu
Message-ID: <55E1AE85.20500@huawei.com>

From: Yang Yingliang <yangyingliang at huawei.com>

When cpu is disabled, all irqs will be migratged to another cpu.
In some cases, a new affinity is different, it needed to be coppied
to irq's affinity. But if the type of irq is LPI, it's affinity will
not be coppied because of irq_set_affinity's return value.
So copy the affinity, when the return value is IRQ_SET_MASK_OK_DONE.

Cc: Jiang Liu <jiang.liu at linux.intel.com>
Cc: Thomas Gleixner <tglx at linutronix.de>
Cc: Marc Zyngier <marc.zyngier at arm.com>
Cc: Mark Rutland <mark.rutland at arm.com>
Cc: Will Deacon <will.deacon at arm.com>
Cc: Russell King - ARM Linux <linux at arm.linux.org.uk>
---
  arch/arm/kernel/irq.c | 9 ++++++---
  1 file changed, 6 insertions(+), 3 deletions(-)

diff --git a/arch/arm/kernel/irq.c b/arch/arm/kernel/irq.c
index 350f188..32f2140 100644
--- a/arch/arm/kernel/irq.c
+++ b/arch/arm/kernel/irq.c
@@ -157,10 +157,13 @@ static bool migrate_one_irq(struct irq_desc *desc)
  	}

  	c = irq_data_get_irq_chip(d);
-	if (!c->irq_set_affinity)
+	if (!c->irq_set_affinity) {
  		pr_debug("IRQ%u: unable to set affinity\n", d->irq);
-	else if (c->irq_set_affinity(d, affinity, false) == IRQ_SET_MASK_OK && 
ret)
-		cpumask_copy(d->affinity, affinity);
+	} else {
+		int r = c->irq_set_affinity(d, affinity, false);
+		if ((r == IRQ_SET_MASK_OK || r == IRQ_SET_MASK_OK_DONE) && ret)
+			cpumask_copy(d->affinity, affinity);
+	}

  	return ret;
  }
-- 
2.5.0



From romain.perier at gmail.com  Sat Aug 29 07:48:04 2015
From: romain.perier at gmail.com (Romain Perier)
Date: Sat, 29 Aug 2015 16:48:04 +0200
Subject: [PATCH] ARM: dts: rockchip: Add support for SD/MMC on
 MarsBoard-RK3066
In-Reply-To: <1510107.CgsiuXuzAt@phil>
References: <1440432281-491-1-git-send-email-romain.perier@gmail.com>
 <110804682.VHnft3L4vc@phil> <1510107.CgsiuXuzAt@phil>
Message-ID: <CABgxDoLfxYfVQSHvR4+VrfN15mmnhAGnP700Q313-=FQ0QL5JA@mail.gmail.com>

Hi,

Sure no problem.
Romain

2015-08-27 19:59 GMT+02:00 Heiko Stuebner <heiko at sntech.de>:
> Am Montag, 24. August 2015, 19:21:53 schrieb Heiko Stuebner:
>> Am Montag, 24. August 2015, 18:04:41 schrieb Romain Perier:
>> > This enables SDMMC0 on the board and gives a basic support for SD cards.
>> >
>> > Signed-off-by: Romain Perier <romain.perier at gmail.com>
>>
>> applied to my dts branch, after moving it above the "&pinctrl" node
>
> just as notice, this moved down to linux-4.4 material


From gpkulkarni at gmail.com  Sat Aug 29 07:56:42 2015
From: gpkulkarni at gmail.com (Ganapatrao Kulkarni)
Date: Sat, 29 Aug 2015 20:26:42 +0530
Subject: [PATCH v5 2/4] Documentation: arm64/arm: dt bindings for numa.
In-Reply-To: <55E17F58.5020101@huawei.com>
References: <1439570374-4079-1-git-send-email-gkulkarni@caviumnetworks.com>
 <1439570374-4079-3-git-send-email-gkulkarni@caviumnetworks.com>
 <20150828123228.GE31748@leverpostej>
 <CAL_JsqLOpUTVeKbkJ6uPi0EYistd=BowAHdtSmaUYYDhU6c9Sg@mail.gmail.com>
 <55E17F58.5020101@huawei.com>
Message-ID: <CAFpQJXWO0xT0kxWf09L_XcAOXm1Lov8i2U2BQzk-x0TStj7vBg@mail.gmail.com>

Hi Thunder,

On Sat, Aug 29, 2015 at 3:16 PM, Leizhen (ThunderTown)
<thunder.leizhen at huawei.com> wrote:
>
>
> On 2015/8/28 22:02, Rob Herring wrote:
>> +benh
>>
>> On Fri, Aug 28, 2015 at 7:32 AM, Mark Rutland <mark.rutland at arm.com> wrote:
>>> Hi,
>>>
>>> On Fri, Aug 14, 2015 at 05:39:32PM +0100, Ganapatrao Kulkarni wrote:
>>>> DT bindings for numa map for memory, cores and IOs using
>>>> arm,associativity device node property.
>>>
>>> Given this is just a copy of ibm,associativity, I'm not sure I see much
>>> point in renaming the properties.
>>
>> So just keep the ibm? I'm okay with that. That would help move to
>> common code. Alternatively, we could drop the vendor prefix and have
>> common code just check for both.
>>
>
> Hi all,
>
> Why not copy the method of ACPI numa? There only three elements should be configured:
> 1) a cpu belong to which node
> 2) a memory block belong to which node
> 3) the distance of each two nodes
>
> The devicetree nodes of numa can be like below:
> / {
>         ...
>
>         numa-nodes-info {
>                 node-name: node-description {
>                         mem-ranges = <...>;
>                         cpus-list = <...>;
>                 };
>
>                 nodes-distance {
>                         distance-list = <...>;
>                 };
>         };
>
>         ...
> };
>
some what similar to what your are proposing is already implemented in
my v2 patchset.
https://lwn.net/Articles/623920/
http://lists.infradead.org/pipermail/linux-arm-kernel/2014-November/305164.html
we have went to associativity property based implementation to keep it
more generic.
i do have both acpi(using linaro/hanjun's patches) and associativity
based implementations on our internal tree
and tested on thunderx platform.
i do see issue in creating numa mapping using ACPI for IOs(for
example, i am not able to create numa mapping for ITS which is on each
node, using ACPI tables),  since ACPI spec (tables SRAT and SLIT)
talks only about processor and memory.
however associativity is generic and you can apply on any dt node.
> Sorry, I don't think xxx,associativity is a good method, it's hard to config, and it
> seems hardware-dependent. Especially, when we want to support memory hot-add, it's too hard.
> Because xxx,associativity have no obvious information about it. Like powerpc, it use another
> property: "/ibm,dynamic-reconfiguration-memory".
>
> I spend almost a whole month to implement of_numa(configured by dt-nodes), base upon my opinion
> mentioned above. If somebody are interested in it, I can send my patchset to show it.
>
> Regards,
> Thunder.
>
thanks
ganapat


From jiang.liu at linux.intel.com  Sat Aug 29 08:12:41 2015
From: jiang.liu at linux.intel.com (Jiang Liu)
Date: Sat, 29 Aug 2015 23:12:41 +0800
Subject: [PATCH] arm64: fix a migrating irq bug when hotplug cpu
In-Reply-To: <55E1AD09.7020701@huawei.com>
References: <55E1AD09.7020701@huawei.com>
Message-ID: <55E1CBE9.6080705@linux.intel.com>

On 2015/8/29 21:00, Yang Yingliang wrote:
> From: Yang Yingliang <yangyingliang at huawei.com>
> 
> When cpu is disabled, all irqs will be migratged to another cpu.
> In some cases, a new affinity is different, it needed to be coppied
> to irq's affinity. But if the type of irq is LPI, it's affinity will
> not be coppied because of irq_set_affinity's return value.
> So copy the affinity, when the return value is IRQ_SET_MASK_OK_DONE.
Hi Yingliang,
	If irq_set_affinity callback returns IRQ_SET_MASK_OK_DONE,
it means that irq_set_affinity has copied the new CPU mask to irq
affinity mask. It would be better to change irq_set_affinity for LPI
to follow this rule.
Thanks!
Gerry
> 
> Cc: Jiang Liu <jiang.liu at linux.intel.com>
> Cc: Thomas Gleixner <tglx at linutronix.de>
> Cc: Marc Zyngier <marc.zyngier at arm.com>
> Cc: Mark Rutland <mark.rutland at arm.com>
> Cc: Will Deacon <will.deacon at arm.com>
> ---
>  arch/arm64/kernel/irq.c | 9 ++++++---
>  1 file changed, 6 insertions(+), 3 deletions(-)
> 
> diff --git a/arch/arm64/kernel/irq.c b/arch/arm64/kernel/irq.c
> index 463fa2e..2acc8ec 100644
> --- a/arch/arm64/kernel/irq.c
> +++ b/arch/arm64/kernel/irq.c
> @@ -78,10 +78,13 @@ static bool migrate_one_irq(struct irq_desc *desc)
>      }
> 
>      c = irq_data_get_irq_chip(d);
> -    if (!c->irq_set_affinity)
> +    if (!c->irq_set_affinity) {
>          pr_debug("IRQ%u: unable to set affinity\n", d->irq);
> -    else if (c->irq_set_affinity(d, affinity, false) == IRQ_SET_MASK_OK
> && ret)
> -        cpumask_copy(irq_data_get_affinity_mask(d), affinity);
> +    } else if (c->irq_set_affinity(d, affinity, false) ==
> IRQ_SET_MASK_OK && ret) {
> +        int r = c->irq_set_affinity(d, affinity, false);
> +        if ((r == IRQ_SET_MASK_OK || r == IRQ_SET_MASK_OK_DONE) && ret)
> +            cpumask_copy(irq_data_get_affinity_mask(d), affinity);
> +    }
> 
>      return ret;
>  }


From yury.norov at gmail.com  Sat Aug 29 08:15:15 2015
From: yury.norov at gmail.com (Yury)
Date: Sat, 29 Aug 2015 18:15:15 +0300
Subject: [PATCH] lib: Make _find_next_bit helper function inline
In-Reply-To: <CALW4P+LU2iLkT7d=BiaC_=oSJ6K_g152VsVSjfcQGUKx_5q4tQ@mail.gmail.com>
References: <1438110564-19932-1-git-send-email-cburden@codeaurora.org>
 <55B7F2C6.9010000@gmail.com>
 <20150728144537.67d46b5714c99d25f0bb33fb@linux-foundation.org>
 <1438176656.18723.8.camel@ceres> <55B93A47.90107@codeaurora.org>
 <CALW4P+LU2iLkT7d=BiaC_=oSJ6K_g152VsVSjfcQGUKx_5q4tQ@mail.gmail.com>
Message-ID: <55E1CC83.1010007@gmail.com>


On 24.08.2015 01:53, Alexey Klimov wrote:
> Hi Cassidy,
>
>
> On Wed, Jul 29, 2015 at 11:40 PM, Cassidy Burden <cburden at codeaurora.org> wrote:
>> I changed the test module to now set the entire array to all 0/1s and
>> only flip a few bits. There appears to be a performance benefit, but
>> it's only 2-3% better (if that). If the main benefit of the original
>> patch was to save space then inlining definitely doesn't seem worth the
>> small gains in real use cases.
>>
>> find_next_zero_bit (us)
>> old      new     inline
>> 14440    17080   17086
>> 4779     5181    5069
>> 10844    12720   12746
>> 9642     11312   11253
>> 3858     3818    3668
>> 10540    12349   12307
>> 12470    14716   14697
>> 5403     6002    5942
>> 2282     1820    1418
>> 13632    16056   15998
>> 11048    13019   13030
>> 6025     6790    6706
>> 13255    15586   15605
>> 3038     2744    2539
>> 10353    12219   12239
>> 10498    12251   12322
>> 14767    17452   17454
>> 12785    15048   15052
>> 1655     1034    691
>> 9924     11611   11558
>>
>> find_next_bit (us)
>> old      new     inline
>> 8535     9936    9667
>> 14666    17372   16880
>> 2315     1799    1355
>> 6578     9092    8806
>> 6548     7558    7274
>> 9448     11213   10821
>> 3467     3497    3449
>> 2719     3079    2911
>> 6115     7989    7796
>> 13582    16113   15643
>> 4643     4946    4766
>> 3406     3728    3536
>> 7118     9045    8805
>> 3174     3011    2701
>> 13300    16780   16252
>> 14285    16848   16330
>> 11583    13669   13207
>> 13063    15455   14989
>> 12661    14955   14500
>> 12068    14166   13790
>>
>> On 7/29/2015 6:30 AM, Alexey Klimov wrote:
>>>
>>> I will re-check on another machine. It's really interesting if
>>> __always_inline makes things better for aarch64 and worse for x86_64. It
>>> will be nice if someone will check it on x86_64 too.
>>
>>
>> Very odd, this may be related to the other compiler optimizations Yuri
>> mentioned?
>
> It's better to ask Yury, i hope he can answer some day.
>
> Do you need to re-check this (with more iterations or on another machine(s))?
>

Hi, Alexey, Cassidy,

(restoring Rasmus, George)

I found no difference between original and inline versions for x86_64:
(Intel(R) Core(TM) i7-2630QM CPU @ 2.00GHz)

find_next_bit		find_next_zero_bit
old	new	inline	old	new	inline
24	27	28	22	28	28
24	27	28      23	27	28
24	27	28      23	27	28
           	
Inspecting assembler code, I found that GCC wants to see helper separated,
even if you provide '__always_inline':

inline <find_next_bit_new>:			current <find_next_bit_new>:			
280:	cmp    %rdx,%rsi                        210:	cmp    %rdx,%rsi
283:	jbe    295 <find_next_bit_new+0x15>     213:	jbe    227 <find_next_bit_new+0x17>
285:	test   %rsi,%rsi                        215:	test   %rsi,%rsi
288:	je     295 <find_next_bit_new+0x15>     218:	je     227 <find_next_bit_new+0x17>
28a:	push   %rbp                             21a:	push   %rbp
28b:	mov    %rsp,%rbp                        21b:	xor    %ecx,%ecx
28e:	callq  0 <find_next_bit_new.part.0>     21d:	mov    %rsp,%rbp
293:	pop    %rbp                             220:	callq  0 <_find_next_bit.part.0>
294:	retq                                    225:	pop    %rbp
295:	mov    %rsi,%rax                        226:	retq
298:	retq                                    227:	mov    %rsi,%rax
299:	nopl   0x0(%rax)                        22a:	retq
       				                22b:	nopl   0x0(%rax,%rax,1)

So things are looking like x86_64 gcc (at least 4.9.2 build for Ubuntu)
ignores '__always_inline' hint as well as 'inline'. But in case of
__always_inline compiler does something not really smart: it introduces
<find_next_bit_new.part.0> and <find_next_zero_bit_new.part.1> helpers
and so increases text size from 0x250 to 0x2b9 bytes, but doesn't really
inline to optimize push/pop and call/ret. I don't like inline, as I
already told, but I believe that complete disabling is bad idea.
Maybe someone knows another trick to make inline work?


From simon.guinot at sequanux.org  Sat Aug 29 09:46:45 2015
From: simon.guinot at sequanux.org (Simon Guinot)
Date: Sat, 29 Aug 2015 18:46:45 +0200
Subject: [PATCH 3/3] ARM: mvebu: enable options for Seagate NAS in
 mvebu_v7_defconfig
In-Reply-To: <1440866805-31731-1-git-send-email-simon.guinot@sequanux.org>
References: <1440866805-31731-1-git-send-email-simon.guinot@sequanux.org>
Message-ID: <1440866805-31731-4-git-send-email-simon.guinot@sequanux.org>

This patch enables the following options needed by the Seagate
Personal Cloud 1 and 2-Bay and the Seagate NAS 2 and 4-Bay:

SATA_AHCI
POWER_RESET_GPIO
RTC_DRV_DS1307
RTC_DRV_PCF8563

Additionnally this patch also enables NEW_LEDS which was missing for
some reasons.

Signed-off-by: Simon Guinot <simon.guinot at sequanux.org>
---
 arch/arm/configs/mvebu_v7_defconfig | 9 ++++++++-
 1 file changed, 8 insertions(+), 1 deletion(-)

diff --git a/arch/arm/configs/mvebu_v7_defconfig b/arch/arm/configs/mvebu_v7_defconfig
index 13fcd020e375..c6729bf0a8dd 100644
--- a/arch/arm/configs/mvebu_v7_defconfig
+++ b/arch/arm/configs/mvebu_v7_defconfig
@@ -61,6 +61,7 @@ CONFIG_MTD_SPI_NOR=y
 CONFIG_EEPROM_AT24=y
 CONFIG_BLK_DEV_SD=y
 CONFIG_ATA=y
+CONFIG_SATA_AHCI=y
 CONFIG_AHCI_MVEBU=y
 CONFIG_SATA_MV=y
 CONFIG_NETDEVICES=y
@@ -85,6 +86,9 @@ CONFIG_SPI=y
 CONFIG_SPI_ORION=y
 CONFIG_GPIO_SYSFS=y
 CONFIG_GPIO_PCA953X=y
+CONFIG_POWER_SUPPLY=y
+CONFIG_POWER_RESET=y
+CONFIG_POWER_RESET_GPIO=y
 CONFIG_SENSORS_GPIO_FAN=y
 CONFIG_THERMAL=y
 CONFIG_ARMADA_THERMAL=y
@@ -111,12 +115,15 @@ CONFIG_MMC_SDHCI_PLTFM=y
 CONFIG_MMC_SDHCI_DOVE=y
 CONFIG_MMC_SDHCI_PXAV3=y
 CONFIG_MMC_MVSDIO=y
-CONFIG_LEDS_GPIO=y
+CONFIG_NEW_LEDS=y
 CONFIG_LEDS_CLASS=y
+CONFIG_LEDS_GPIO=y
 CONFIG_LEDS_TRIGGERS=y
 CONFIG_LEDS_TRIGGER_TIMER=y
 CONFIG_LEDS_TRIGGER_HEARTBEAT=y
 CONFIG_RTC_CLASS=y
+CONFIG_RTC_DRV_DS1307=y
+CONFIG_RTC_DRV_PCF8563=y
 CONFIG_RTC_DRV_S35390A=y
 CONFIG_RTC_DRV_MV=y
 CONFIG_RTC_DRV_ARMADA38X=y
-- 
2.1.4



From simon.guinot at sequanux.org  Sat Aug 29 09:46:42 2015
From: simon.guinot at sequanux.org (Simon Guinot)
Date: Sat, 29 Aug 2015 18:46:42 +0200
Subject: [PATCH 0/3] Add support for the Armada-370-based Seagate NAS
Message-ID: <1440866805-31731-1-git-send-email-simon.guinot@sequanux.org>

Hi,

This patch series adds support for the Seagate machines based on the
Armada-370 Marvell SoC. This includes the Personal Cloud 1 and 2-Bay
and the Seagate NAS 2 and 4-Bay.

Thanks,

Simon

Simon Guinot (2):
  ARM: mvebu: add DT support for Seagate Personal Cloud
  ARM: mvebu: enable options for Seagate NAS in mvebu_v7_defconfig

Vincent Donnefort (1):
  ARM: mvebu: add DT support for Seagate NAS 2 and 4-Bay

 arch/arm/boot/dts/Makefile                |   4 +
 arch/arm/boot/dts/armada-370-n090103.dts  |  28 ++++
 arch/arm/boot/dts/armada-370-n090201.dts  |  28 ++++
 arch/arm/boot/dts/armada-370-n090203.dts  |  42 ++++++
 arch/arm/boot/dts/armada-370-n090401.dts  | 124 ++++++++++++++++
 arch/arm/boot/dts/armada-370-n090x01.dtsi | 232 ++++++++++++++++++++++++++++++
 arch/arm/boot/dts/armada-370-n090x03.dtsi | 174 ++++++++++++++++++++++
 arch/arm/configs/mvebu_v7_defconfig       |   9 +-
 8 files changed, 640 insertions(+), 1 deletion(-)
 create mode 100644 arch/arm/boot/dts/armada-370-n090103.dts
 create mode 100644 arch/arm/boot/dts/armada-370-n090201.dts
 create mode 100644 arch/arm/boot/dts/armada-370-n090203.dts
 create mode 100644 arch/arm/boot/dts/armada-370-n090401.dts
 create mode 100644 arch/arm/boot/dts/armada-370-n090x01.dtsi
 create mode 100644 arch/arm/boot/dts/armada-370-n090x03.dtsi

-- 
2.1.4



From simon.guinot at sequanux.org  Sat Aug 29 09:46:44 2015
From: simon.guinot at sequanux.org (Simon Guinot)
Date: Sat, 29 Aug 2015 18:46:44 +0200
Subject: [PATCH 2/3] ARM: mvebu: add DT support for Seagate Personal Cloud
In-Reply-To: <1440866805-31731-1-git-send-email-simon.guinot@sequanux.org>
References: <1440866805-31731-1-git-send-email-simon.guinot@sequanux.org>
Message-ID: <1440866805-31731-3-git-send-email-simon.guinot@sequanux.org>

This patch adds DT support for the Seagate Personal Cloud 1 and 2-Bay
(n090103 and n090203).

Chipset list:
- SoC Marvell Armada 370 88F6707, CPU @1GHz
- SDRAM memory: 512MB DDR3 667MHz (16-bits bandwidth)
- SPI flash 1MB (Macronix MX25L8006E)
- 1 or 2 SATA internal ports
- 1 Ethernet Gigabit port (PHY Marvell 88E1518)
- 1 USB3 host port (PCIe controller ASM1042)
- 1 USB2 host port (SoC)
- 2 push buttons (power and reset)
- 1 SATA LED (bi-color, white and red)

Note that support for the white SATA LED is missing. A dedicated LED
driver is needed.

Signed-off-by: Simon Guinot <simon.guinot at sequanux.org>
---
 arch/arm/boot/dts/Makefile                |   2 +
 arch/arm/boot/dts/armada-370-n090103.dts  |  28 +++++
 arch/arm/boot/dts/armada-370-n090203.dts  |  42 ++++++++
 arch/arm/boot/dts/armada-370-n090x03.dtsi | 174 ++++++++++++++++++++++++++++++
 4 files changed, 246 insertions(+)
 create mode 100644 arch/arm/boot/dts/armada-370-n090103.dts
 create mode 100644 arch/arm/boot/dts/armada-370-n090203.dts
 create mode 100644 arch/arm/boot/dts/armada-370-n090x03.dtsi

diff --git a/arch/arm/boot/dts/Makefile b/arch/arm/boot/dts/Makefile
index 0a46613e90d2..2b30300db972 100644
--- a/arch/arm/boot/dts/Makefile
+++ b/arch/arm/boot/dts/Makefile
@@ -699,7 +699,9 @@ dtb-$(CONFIG_MACH_ARMADA_370) += \
 	armada-370-db.dtb \
 	armada-370-dlink-dns327l.dtb \
 	armada-370-mirabox.dtb \
+	armada-370-n090103.dtb \
 	armada-370-n090201.dtb \
+	armada-370-n090203.dtb \
 	armada-370-n090401.dtb \
 	armada-370-netgear-rn102.dtb \
 	armada-370-netgear-rn104.dtb \
diff --git a/arch/arm/boot/dts/armada-370-n090103.dts b/arch/arm/boot/dts/armada-370-n090103.dts
new file mode 100644
index 000000000000..c94bed449050
--- /dev/null
+++ b/arch/arm/boot/dts/armada-370-n090103.dts
@@ -0,0 +1,28 @@
+/*
+ * Device Tree file for Seagate Personal Cloud NAS (n090103).
+ *
+ * Copyright (C) 2015 Seagate
+ *
+ * Author: Simon Guinot <simon.guinot at sequanux.org>
+ *
+ * This file is licensed under the terms of the GNU General Public
+ * License version 2.  This program is licensed "as is" without any
+ * warranty of any kind, whether express or implied.
+ */
+
+/dts-v1/;
+#include "armada-370-n090x03.dtsi"
+
+/ {
+	model = "Seagate Personal Cloud";
+	compatible = "seagate,n090103", "marvell,armada370", "marvell,armada-370-xp";
+
+	soc {
+		internal-regs {
+			sata at a0000 {
+				status = "okay";
+				nr-ports = <1>;
+			};
+		};
+	};
+};
diff --git a/arch/arm/boot/dts/armada-370-n090203.dts b/arch/arm/boot/dts/armada-370-n090203.dts
new file mode 100644
index 000000000000..3bc62b9f0b0c
--- /dev/null
+++ b/arch/arm/boot/dts/armada-370-n090203.dts
@@ -0,0 +1,42 @@
+/*
+ * Device Tree file for Seagate Personnal Cloud 2-Bay NAS (n090203).
+ *
+ * Copyright (C) 2015 Seagate
+ *
+ * Author: Simon Guinot <simon.guinot at sequanux.org>
+ *
+ * This file is licensed under the terms of the GNU General Public
+ * License version 2.  This program is licensed "as is" without any
+ * warranty of any kind, whether express or implied.
+ */
+
+/dts-v1/;
+#include "armada-370-n090x03.dtsi"
+
+/ {
+	model = "Seagate Personnal Cloud 2-Bay";
+	compatible = "seagate,n090203", "marvell,armada370", "marvell,armada-370-xp";
+
+	soc {
+		internal-regs {
+			sata at a0000 {
+				status = "okay";
+				nr-ports = <2>;
+			};
+		};
+	};
+
+	regulators {
+		regulator at 2 {
+			compatible = "regulator-fixed";
+			reg = <2>;
+			regulator-name = "SATA1 power";
+			regulator-min-microvolt = <5000000>;
+			regulator-max-microvolt = <5000000>;
+			enable-active-high;
+			regulator-always-on;
+			regulator-boot-on;
+			gpio = <&gpio1 22 GPIO_ACTIVE_HIGH>;
+		};
+	};
+};
diff --git a/arch/arm/boot/dts/armada-370-n090x03.dtsi b/arch/arm/boot/dts/armada-370-n090x03.dtsi
new file mode 100644
index 000000000000..1bd67869ba78
--- /dev/null
+++ b/arch/arm/boot/dts/armada-370-n090x03.dtsi
@@ -0,0 +1,174 @@
+/*
+ * Device Tree common file for the Seagate Personal Cloud 1 and 2-Bay
+ * (n090103 and n090203).
+ *
+ * Copyright (C) 2015 Seagate
+ *
+ * Author: Simon Guinot <simon.guinot at sequanux.org>
+ *
+ * This file is licensed under the terms of the GNU General Public
+ * License version 2.  This program is licensed "as is" without any
+ * warranty of any kind, whether express or implied.
+ */
+
+/*
+ * TODO: add support for the white SATA LED.
+ */
+
+#include "armada-370.dtsi"
+#include <dt-bindings/gpio/gpio.h>
+#include <dt-bindings/input/input.h>
+
+/ {
+	chosen {
+		stdout-path = "serial0:115200n8";
+	};
+
+	memory {
+		device_type = "memory";
+		reg = <0x00000000 0x20000000>; /* 512 MB */
+	};
+
+	soc {
+		ranges = <MBUS_ID(0xf0, 0x01) 0 0xf1000000 0x100000
+			  MBUS_ID(0x01, 0xe0) 0 0xfff00000 0x100000>;
+
+		pcie-controller {
+			status = "okay";
+
+			/* USB 3.0 Bridge ASM1042A */
+			pcie at 1,0 {
+				status = "okay";
+			};
+		};
+
+		internal-regs {
+			serial at 12000 {
+				status = "okay";
+			};
+
+			mdio {
+				pinctrl-0 = <&mdio_pins>;
+				pinctrl-names = "default";
+
+				phy0: ethernet-phy at 0 {
+					reg = <0>;
+				};
+			};
+
+			ethernet at 74000 {
+				status = "okay";
+				pinctrl-0 = <&ge1_rgmii_pins>;
+				pinctrl-names = "default";
+				phy = <&phy0>;
+				phy-mode = "rgmii-id";
+			};
+
+			spi at 10600 {
+				status = "okay";
+				pinctrl-0 = <&spi0_pins2>;
+				pinctrl-names = "default";
+
+				spi-flash at 0 {
+					#address-cells = <1>;
+					#size-cells = <1>;
+					/* MX25L8006E */
+					compatible = "mxicy,mx25l8005", "jedec,spi-nor";
+					reg = <0>; /* Chip select 0 */
+					spi-max-frequency = <50000000>;
+
+					partition at 0 {
+						label = "u-boot";
+						reg = <0x0 0x100000>;
+					};
+				};
+			};
+
+			usb at 50000 {
+				status = "okay";
+			};
+		};
+	};
+
+	regulators {
+		compatible = "simple-bus";
+		#address-cells = <1>;
+		#size-cells = <0>;
+
+		regulator at 0 {
+			compatible = "regulator-fixed";
+			reg = <0>;
+			regulator-name = "USB Power";
+			regulator-min-microvolt = <5000000>;
+			regulator-max-microvolt = <5000000>;
+			regulator-always-on;
+			regulator-boot-on;
+			gpio = <&gpio1 27 GPIO_ACTIVE_LOW>;
+		};
+		regulator at 1 {
+			compatible = "regulator-fixed";
+			reg = <1>;
+			regulator-name = "SATA0 power";
+			regulator-min-microvolt = <5000000>;
+			regulator-max-microvolt = <5000000>;
+			enable-active-high;
+			regulator-always-on;
+			regulator-boot-on;
+			gpio = <&gpio1 18 GPIO_ACTIVE_HIGH>;
+		};
+	};
+
+	gpio-keys {
+		compatible = "gpio-keys";
+		#address-cells = <1>;
+		#size-cells = <0>;
+
+		button at 1 {
+			label = "Power button";
+			linux,code = <KEY_POWER>;
+			gpios = <&gpio1 19 GPIO_ACTIVE_HIGH>;
+			debounce-interval = <100>;
+		};
+		button at 2 {
+			label = "Reset Button";
+			linux,code = <KEY_RESTART>;
+			gpios = <&gpio1 23 GPIO_ACTIVE_LOW>;
+			debounce-interval = <100>;
+		};
+		button at 3 {
+			label = "USB VBUS error";
+			linux,code = <KEY_UNKNOWN>;
+			gpios = <&gpio1 21 GPIO_ACTIVE_LOW>;
+			debounce-interval = <100>;
+		};
+	};
+
+	gpio-leds {
+		compatible = "gpio-leds";
+
+		red-sata0 {
+			label = "n090x03:red:sata0";
+			gpios = <&gpio1 26 GPIO_ACTIVE_HIGH>;
+			default-state = "off";
+		};
+	};
+
+	gpio_poweroff {
+		compatible = "gpio-poweroff";
+		gpios = <&gpio1 25 GPIO_ACTIVE_HIGH>;
+	};
+};
+
+&pinctrl {
+	pinctrl-0 = <&sata_led_pin>;
+	pinctrl-names = "default";
+
+	sata_led_pin: sata-led-pin {
+		marvell,pins = "mpp60";
+		marvell,function = "sata0";
+	};
+	gpio_led_pin: gpio-led-pin {
+		marvell,pins = "mpp60";
+		marvell,function = "gpio";
+	};
+};
-- 
2.1.4



From simon.guinot at sequanux.org  Sat Aug 29 09:46:43 2015
From: simon.guinot at sequanux.org (Simon Guinot)
Date: Sat, 29 Aug 2015 18:46:43 +0200
Subject: [PATCH 1/3] ARM: mvebu: add DT support for Seagate NAS 2 and 4-Bay
In-Reply-To: <1440866805-31731-1-git-send-email-simon.guinot@sequanux.org>
References: <1440866805-31731-1-git-send-email-simon.guinot@sequanux.org>
Message-ID: <1440866805-31731-2-git-send-email-simon.guinot@sequanux.org>

From: Vincent Donnefort <vdonnefort at gmail.com>

This patch adds DT support for the Seagate NAS 2 and 4-Bay (n090201 and
n090401).

Chipset list (common):
- SoC Marvell Armada 370 88F6707, CPU @1.2GHz
- SDRAM memory: 512MB DDR3 600MHz (16-bits bandwidth)
- NAND flash 256MB, 8-bits (Micron MT29F2G08AAB or Hinyx H27U2G8F2CTR-BC)
- 2 SATA II ports (SoC)
- 1 Ethernet Gigabit ports (PHY Marvell 88E1518)
- 2 USB3 host ports (PCIe controller ASM1042)
- GPIO fan (4 speeds)
- External I2C RTC (MCP7940NT)
- 3 push buttons (power, backup and reset)
- 2 SATA LEDs (bi-color, blue and red)
- 1 power LED (bi-color, blue and red)

Only on 4-Bay models:
- 2 extra SATA III ports (PCIe AHCI controller Marvell 88SE9170)
- 1 extra Ethernet Gigabit ports (PHY Marvell 88E1518)
- I2C GPIO expander (PCA9554A)
- 2 extra SATA LEDs (bi-color, blue and red)

Note that support for the white SATA LEDs associated with HDDs 0 and 1
is missing. A dedicated LED driver is needed.

Signed-off-by: Vincent Donnefort <vdonnefort at gmail.com>
---
 arch/arm/boot/dts/Makefile                |   2 +
 arch/arm/boot/dts/armada-370-n090201.dts  |  28 ++++
 arch/arm/boot/dts/armada-370-n090401.dts  | 124 ++++++++++++++++
 arch/arm/boot/dts/armada-370-n090x01.dtsi | 232 ++++++++++++++++++++++++++++++
 4 files changed, 386 insertions(+)
 create mode 100644 arch/arm/boot/dts/armada-370-n090201.dts
 create mode 100644 arch/arm/boot/dts/armada-370-n090401.dts
 create mode 100644 arch/arm/boot/dts/armada-370-n090x01.dtsi

diff --git a/arch/arm/boot/dts/Makefile b/arch/arm/boot/dts/Makefile
index 233159d2eaab..0a46613e90d2 100644
--- a/arch/arm/boot/dts/Makefile
+++ b/arch/arm/boot/dts/Makefile
@@ -699,6 +699,8 @@ dtb-$(CONFIG_MACH_ARMADA_370) += \
 	armada-370-db.dtb \
 	armada-370-dlink-dns327l.dtb \
 	armada-370-mirabox.dtb \
+	armada-370-n090201.dtb \
+	armada-370-n090401.dtb \
 	armada-370-netgear-rn102.dtb \
 	armada-370-netgear-rn104.dtb \
 	armada-370-rd.dtb \
diff --git a/arch/arm/boot/dts/armada-370-n090201.dts b/arch/arm/boot/dts/armada-370-n090201.dts
new file mode 100644
index 000000000000..b92b1ee067d6
--- /dev/null
+++ b/arch/arm/boot/dts/armada-370-n090201.dts
@@ -0,0 +1,28 @@
+/*
+ * Device Tree file for Seagate NAS 2-Bay (n090201)
+ *
+ * Copyright (C) 2015 Seagate
+ *
+ * Author: Vincent Donnefort <vdonnefort at gmail.com>
+ *
+ * This file is licensed under the terms of the GNU General Public
+ * License version 2.  This program is licensed "as is" without any
+ * warranty of any kind, whether express or implied.
+ */
+
+/dts-v1/;
+
+#include "armada-370-n090x01.dtsi"
+
+/ {
+	model = "Seagate NAS 2-Bay";
+	compatible = "seagate,n090201", "marvell,armada370", "marvell,armada-370-xp";
+
+	gpio-fan {
+		gpio-fan,speed-map =
+			<   0 3
+			  950 2
+			 1400 1
+			 1800 0>;
+	};
+};
diff --git a/arch/arm/boot/dts/armada-370-n090401.dts b/arch/arm/boot/dts/armada-370-n090401.dts
new file mode 100644
index 000000000000..c36f10f0eb04
--- /dev/null
+++ b/arch/arm/boot/dts/armada-370-n090401.dts
@@ -0,0 +1,124 @@
+/*
+ * Device Tree file for Seagate NAS 4-Bay
+ *
+ * Copyright (C) 2015 Seagate
+ *
+ * Author: Vincent Donnefort <vdonnefort at gmail.com>
+ *
+ * This file is licensed under the terms of the GNU General Public
+ * License version 2.  This program is licensed "as is" without any
+ * warranty of any kind, whether express or implied.
+ */
+
+/dts-v1/;
+#include "armada-370-n090x01.dtsi"
+#include <dt-bindings/leds/leds-ns2.h>
+
+/ {
+	model = "Seagate NAS 4-Bay";
+	compatible = "seagate,n090401", "marvell,armada370", "marvell,armada-370-xp";
+
+	soc {
+		pcie-controller {
+			/* SATA AHCI controller 88SE9170 */
+			pcie at 1,0 {
+				status = "okay";
+			};
+		};
+
+		internal-regs {
+			mdio {
+				phy1: ethernet-phy at 1 {
+					reg = <1>;
+				};
+			};
+
+			ethernet at 74000 {
+				status = "okay";
+				pinctrl-0 = <&ge1_rgmii_pins>;
+				pinctrl-names = "default";
+				phy = <&phy1>;
+				phy-mode = "rgmii-id";
+			};
+
+			i2c at 11000 {
+				/* I2C GPIO expander (PCA9554A) */
+				pca9554: pca9554 at 21 {
+					compatible = "nxp,pca9554";
+					reg = <0x21>;
+					#gpio-cells = <2>;
+					gpio-controller;
+				};
+			};
+		};
+	};
+
+	regulators {
+		regulator at 3 {
+			compatible = "regulator-fixed";
+			reg = <3>;
+			regulator-name = "SATA2 power";
+			regulator-min-microvolt = <5000000>;
+			regulator-max-microvolt = <5000000>;
+			enable-active-high;
+			regulator-always-on;
+			regulator-boot-on;
+			gpio = <&pca9554 6 GPIO_ACTIVE_HIGH>;
+		};
+		regulator at 4 {
+			compatible = "regulator-fixed";
+			reg = <4>;
+			regulator-name = "SATA3 power";
+			regulator-min-microvolt = <5000000>;
+			regulator-max-microvolt = <5000000>;
+			enable-active-high;
+			regulator-always-on;
+			regulator-boot-on;
+			gpio = <&pca9554 7 GPIO_ACTIVE_HIGH>;
+		};
+	};
+
+	gpio-leds {
+		red-sata2 {
+			label = "n090x01:red:sata2";
+			gpios = <&pca9554 0 GPIO_ACTIVE_LOW>;
+		};
+		red-sata3 {
+			label = "n090x01:red:sata3";
+			gpios = <&pca9554 3 GPIO_ACTIVE_LOW>;
+		};
+	};
+
+	leds-ns2 {
+		compatible = "lacie,ns2-leds";
+
+		white-sata2 {
+			label = "n090x01:white:sata2";
+			cmd-gpio = <&pca9554 1 GPIO_ACTIVE_HIGH>;
+			slow-gpio = <&pca9554 2 GPIO_ACTIVE_HIGH>;
+			num-modes = <4>;
+			modes-map = <NS_V2_LED_SATA 0 0
+				     NS_V2_LED_OFF  0 1
+				     NS_V2_LED_ON   1 0
+				     NS_V2_LED_ON   1 1>;
+		};
+		white-sata3 {
+			label = "n090x01:white:sata3";
+			cmd-gpio = <&pca9554 4 GPIO_ACTIVE_HIGH>;
+			slow-gpio = <&pca9554 5 GPIO_ACTIVE_HIGH>;
+			num-modes = <4>;
+			modes-map = <NS_V2_LED_SATA 0 0
+				     NS_V2_LED_OFF  0 1
+				     NS_V2_LED_ON   1 0
+				     NS_V2_LED_ON   1 1>;
+		};
+	};
+
+	gpio-fan {
+		gpio-fan,speed-map =
+			<   0 3
+			  800 2
+			  1050 1
+			  1300 0>;
+	};
+};
diff --git a/arch/arm/boot/dts/armada-370-n090x01.dtsi b/arch/arm/boot/dts/armada-370-n090x01.dtsi
new file mode 100644
index 000000000000..6142136f2db5
--- /dev/null
+++ b/arch/arm/boot/dts/armada-370-n090x01.dtsi
@@ -0,0 +1,232 @@
+/*
+ * Device Tree common file for the Seagate NAS 2 and 4-bay
+ * (n090201 and n090401).
+ *
+ * Copyright (C) 2015 Seagate
+ *
+ * Author: Vincent Donnefort <vdonnefort at gmail.com>
+ *
+ * This file is licensed under the terms of the GNU General Public
+ * License version 2.  This program is licensed "as is" without any
+ * warranty of any kind, whether express or implied.
+ */
+
+/*
+ * TODO: add support for the white SATA LEDs associated with HDD 0 and 1.
+ */
+
+#include "armada-370.dtsi"
+#include <dt-bindings/gpio/gpio.h>
+#include <dt-bindings/input/input.h>
+
+/ {
+	chosen {
+		stdout-path = "serial0:115200n8";
+	};
+
+	memory {
+		device_type = "memory";
+		reg = <0x00000000 0x20000000>; /* 512 MB */
+	};
+
+	soc {
+		ranges = <MBUS_ID(0xf0, 0x01) 0 0xf1000000 0x100000
+			  MBUS_ID(0x01, 0xe0) 0 0xfff00000 0x100000>;
+
+		pcie-controller {
+			status = "okay";
+
+			/* USB 3.0 bridge ASM1042A */
+			pcie at 2,0 {
+				status = "okay";
+			};
+		};
+
+		internal-regs {
+			serial at 12000 {
+				status = "okay";
+			};
+
+			sata at a0000 {
+				nr-ports = <2>;
+				status = "okay";
+			};
+
+			mdio {
+				pinctrl-0 = <&mdio_pins>;
+				pinctrl-names = "default";
+
+				phy0: ethernet-phy at 0 {
+					reg = <0>;
+				};
+			};
+
+			ethernet at 70000 {
+				status = "okay";
+				pinctrl-0 = <&ge0_rgmii_pins>;
+				pinctrl-names = "default";
+				phy = <&phy0>;
+				phy-mode = "rgmii-id";
+			};
+
+			i2c at 11000 {
+				status = "okay";
+				pinctrl-0 = <&i2c0_pins>;
+				pinctrl-names = "default";
+				clock-frequency = <100000>;
+
+				/* RTC - NXP 8563T (second source) */
+				rtc: rtc at 51 {
+					compatible = "nxp,pcf8563";
+					reg = <0x51>;
+					interrupts = <110>;
+				};
+				/* RTC - MCP7940NT */
+				rtc: rtc at 6f {
+					compatible = "microchip,mcp7941x";
+					reg = <0x6f>;
+					interrupts = <110>;
+				};
+			};
+
+			nand at d0000 {
+				status = "okay";
+				num-cs = <1>;
+				marvell,nand-keep-config;
+				marvell,nand-enable-arbiter;
+				nand-on-flash-bbt;
+				nand-ecc-strength = <4>;
+				nand-ecc-step-size = <512>;
+
+				partition at 0 {
+					label = "u-boot";
+					reg = <0x0 0x300000>;
+				};
+				partition at 300000 {
+					label = "device-tree";
+					reg = <0x300000 0x20000>;
+				};
+				partition at 320000 {
+					label = "linux";
+					reg = <0x320000 0x2000000>;
+				};
+				partition at 2320000 {
+					label = "rootfs";
+					reg = <0x2320000 0xdce0000>;
+				};
+			};
+		};
+
+	};
+
+	regulators {
+		compatible = "simple-bus";
+		#address-cells = <1>;
+		#size-cells = <0>;
+		pinctrl-names = "default";
+
+		regulator at 1 {
+			compatible = "regulator-fixed";
+			reg = <1>;
+			regulator-name = "SATA0 power";
+			regulator-min-microvolt = <5000000>;
+			regulator-max-microvolt = <5000000>;
+			enable-active-high;
+			regulator-always-on;
+			regulator-boot-on;
+			gpio = <&gpio1 18 GPIO_ACTIVE_HIGH>;
+		};
+		regulator at 2 {
+			compatible = "regulator-fixed";
+			reg = <2>;
+			regulator-name = "SATA1 power";
+			regulator-min-microvolt = <5000000>;
+			regulator-max-microvolt = <5000000>;
+			enable-active-high;
+			regulator-always-on;
+			regulator-boot-on;
+			gpio = <&gpio1 22 GPIO_ACTIVE_HIGH>;
+		};
+	};
+
+	gpio-fan {
+		compatible = "gpio-fan";
+		gpios = <&gpio2 0 0
+			 &gpio2 1 0>;
+	};
+
+	gpio-keys {
+		compatible = "gpio-keys";
+		#address-cells = <1>;
+		#size-cells = <0>;
+
+		button at 1 {
+			label = "Power button";
+			linux,code = <KEY_POWER>;
+			gpios = <&gpio1 19 GPIO_ACTIVE_LOW>;
+			debounce-interval = <100>;
+		};
+		button at 2 {
+			label = "Backup button";
+			linux,code = <KEY_OPTION>;
+			gpios = <&gpio0 31 GPIO_ACTIVE_LOW>;
+			debounce-interval = <100>;
+		};
+		button at 3 {
+			label = "Reset Button";
+			linux,code = <KEY_RESTART>;
+			gpios = <&gpio1 23 GPIO_ACTIVE_LOW>;
+			debounce-interval = <100>;
+		};
+	};
+
+	gpio-leds {
+		compatible = "gpio-leds";
+
+		white-power {
+			label = "n090x01:white:power";
+			gpios = <&gpio1 28 GPIO_ACTIVE_HIGH>;
+			linux,default-trigger = "timer";
+
+		};
+		red-power {
+			label = "n090x01:red:power";
+			gpios = <&gpio1 31 GPIO_ACTIVE_HIGH>;
+		};
+		red-sata0 {
+			label = "n090x01:red:sata0";
+			gpios = <&gpio1 15 GPIO_ACTIVE_LOW>;
+		};
+		red-sata1 {
+			label = "n090x01:red:sata1";
+			gpios = <&gpio1 21 GPIO_ACTIVE_LOW>;
+		};
+	};
+
+	gpio_poweroff {
+		compatible = "gpio-poweroff";
+		gpios = <&gpio1 30 GPIO_ACTIVE_LOW>;
+	};
+};
+
+&pinctrl {
+	pinctrl-0 = <&hdd0_led_sata_pin>, <&hdd1_led_sata_pin>;
+	pinctrl-names = "default";
+
+	hdd0_led_sata_pin: hdd0-led-sata-pin {
+		marvell,pins = "mpp48";
+		marvell,function = "sata1";
+	};
+	hdd0_led_gpio_pin: hdd0-led-gpio-pin {
+		marvell,pins = "mpp48";
+		marvell,function = "gpio";
+	};
+	hdd1_led_sata_pin: hdd1-led-sata-pin {
+		marvell,pins = "mpp57";
+		marvell,function = "sata0";
+	};
+	hdd1_led_gpio_pin: hdd1-led-gpio-pin {
+		marvell,pins = "mpp57";
+		marvell,function = "gpio";
+	};
+};
-- 
2.1.4



From santosh.shilimkar at oracle.com  Sat Aug 29 10:11:23 2015
From: santosh.shilimkar at oracle.com (santosh shilimkar)
Date: Sat, 29 Aug 2015 10:11:23 -0700
Subject: [PATCH] gpio: omap: Fix gpiochip_add() handling for deferred probe
In-Reply-To: <1440787489-15992-1-git-send-email-tony@atomide.com>
References: <1440787489-15992-1-git-send-email-tony@atomide.com>
Message-ID: <55E1E7BB.7020200@oracle.com>

8/28/2015 11:44 AM, Tony Lindgren wrote:
> Currently we gpio-omap breaks if gpiochip_add() returns -EPROBE_DEFER:
>
> [    0.570000] gpiochip_add: GPIOs 0..31 (gpio) failed to register
> [    0.570000] omap_gpio 48310000.gpio: Could not register gpio chip -517
> ...
> [    3.670000] omap_gpio 48310000.gpio: Unbalanced pm_runtime_enable!
>
> Let's fix the issue by adding the missing pm_runtime_put() on error.
>
> Cc: Grygorii Strashko <grygorii.strashko at ti.com>
> Cc: Javier Martinez Canillas <javier at dowhile0.org>
> Cc: Kevin Hilman <khilman at deeprootsystems.com>
> Cc: Santosh Shilimkar <ssantosh at kernel.org>
> Signed-off-by: Tony Lindgren <tony at atomide.com>
> ---
>   drivers/gpio/gpio-omap.c | 5 ++++-
>   1 file changed, 4 insertions(+), 1 deletion(-)
>
Acked-by: Santosh Shilimkar <ssantosh at kernel.org>


From marc.zyngier at arm.com  Sat Aug 29 11:12:40 2015
From: marc.zyngier at arm.com (Marc Zyngier)
Date: Sat, 29 Aug 2015 19:12:40 +0100
Subject: [PATCH] arm64: fix a migrating irq bug when hotplug cpu
In-Reply-To: <55E1CBE9.6080705@linux.intel.com>
References: <55E1AD09.7020701@huawei.com> <55E1CBE9.6080705@linux.intel.com>
Message-ID: <66e158e6da958d355d54543ef69e5e94@www.loen.fr>

On 2015-08-29 16:12, Jiang Liu wrote:
> On 2015/8/29 21:00, Yang Yingliang wrote:
>> From: Yang Yingliang <yangyingliang at huawei.com>
>>
>> When cpu is disabled, all irqs will be migratged to another cpu.
>> In some cases, a new affinity is different, it needed to be coppied
>> to irq's affinity. But if the type of irq is LPI, it's affinity will
>> not be coppied because of irq_set_affinity's return value.
>> So copy the affinity, when the return value is IRQ_SET_MASK_OK_DONE.
> Hi Yingliang,
> 	If irq_set_affinity callback returns IRQ_SET_MASK_OK_DONE,
> it means that irq_set_affinity has copied the new CPU mask to irq
> affinity mask. It would be better to change irq_set_affinity for LPI
> to follow this rule.

The main issue here seems to be that we do not call irq_set_affinity, 
but
that we directly call into the top-level irqchip method, which relies 
on
the core code to do the copy (see irq_do_set_affinity). Too bad.

It feels like the arm/arm64 code would probably be better consolidated 
into
kernel/irq/migration.c, which already deals with some of this for x86
and ia64. It would save us the duplication and will make sure we don't
miss things next time we add a new return code, as irq_do_set_affinity
would handle this properly.

Thoughts?

          M.
-- 
Fast, cheap, reliable. Pick two.


From apinski at cavium.com  Sat Aug 29 11:38:40 2015
From: apinski at cavium.com (Andrew Pinski)
Date: Sun, 30 Aug 2015 02:38:40 +0800
Subject: [PATCH] ARM64: Add AT_ARM64_MIDR to the aux vector
Message-ID: <1440873520-43899-1-git-send-email-apinski@cavium.com>

It is useful to pass down MIDR register down to userland if all of
the online cores are all the same type.  This adds AT_ARM64_MIDR
aux vector type and passes down the midr system register.

This is alternative to MIDR_EL1 part of
http://lists.infradead.org/pipermail/linux-arm-kernel/2015-July/358995.html.
It allows for faster access to midr_el1 than going through a trap and
does not exist if the set of cores are not the same.

Signed-off-by: Andrew Pinski <apinski at cavium.com>
---
 arch/arm64/include/asm/cpu.h |    1 +
 arch/arm64/include/asm/elf.h |    6 ++++++
 arch/arm64/kernel/cpuinfo.c  |   22 ++++++++++++++++++++++
 3 files changed, 29 insertions(+)

diff --git a/arch/arm64/include/asm/cpu.h b/arch/arm64/include/asm/cpu.h
index 8e797b2..fab0aa1 100644
--- a/arch/arm64/include/asm/cpu.h
+++ b/arch/arm64/include/asm/cpu.h
@@ -62,5 +62,6 @@ DECLARE_PER_CPU(struct cpuinfo_arm64, cpu_data);
 
 void cpuinfo_store_cpu(void);
 void __init cpuinfo_store_boot_cpu(void);
+u32 get_arm64_midr(void);
 
 #endif /* __ASM_CPU_H */
diff --git a/arch/arm64/include/asm/elf.h b/arch/arm64/include/asm/elf.h
index faad6df..d3549de 100644
--- a/arch/arm64/include/asm/elf.h
+++ b/arch/arm64/include/asm/elf.h
@@ -17,6 +17,7 @@
 #define __ASM_ELF_H
 
 #include <asm/hwcap.h>
+#include <asm/cpu.h>
 
 /*
  * ELF register definitions..
@@ -138,8 +139,13 @@ typedef struct user_fpsimd_state elf_fpregset_t;
 
 #define ARCH_DLINFO							\
 do {									\
+	u32 midr;							\
+									\
 	NEW_AUX_ENT(AT_SYSINFO_EHDR,					\
 		    (elf_addr_t)current->mm->context.vdso);		\
+	midr = get_arm64_midr();					\
+	if (midr != 0)							\
+		NEW_AUX_ENT(AT_ARM64_MIDR, (elf_addr_t)midr);		\
 } while (0)
 
 #define ARCH_HAS_SETUP_ADDITIONAL_PAGES
diff --git a/arch/arm64/kernel/cpuinfo.c b/arch/arm64/kernel/cpuinfo.c
index 75d5a86..b14c87d 100644
--- a/arch/arm64/kernel/cpuinfo.c
+++ b/arch/arm64/kernel/cpuinfo.c
@@ -254,3 +254,25 @@ void __init cpuinfo_store_boot_cpu(void)
 
 	boot_cpu_data = *info;
 }
+
+u32 get_arm64_midr(void)
+{
+	int i;
+	u32 midr = 0;
+
+	for_each_online_cpu(i) {
+		struct cpuinfo_arm64 *cpuinfo = &per_cpu(cpu_data, i);
+		u32 oldmidr = midr;
+
+		midr = cpuinfo->reg_midr;
+		/*
+		 * If there are cpus which have a different
+		 * midr just return 0.
+		 */
+		if (oldmidr && oldmidr != midr)
+			return 0;
+	}
+
+	return midr;
+}
+
-- 
1.7.10.4



From apinski at cavium.com  Sat Aug 29 11:46:22 2015
From: apinski at cavium.com (Andrew Pinski)
Date: Sun, 30 Aug 2015 02:46:22 +0800
Subject: [PATCHv2] ARM64: Add AT_ARM64_MIDR to the aux vector
Message-ID: <1440873982-44062-1-git-send-email-apinski@cavium.com>

It is useful to pass down MIDR register down to userland if all of
the online cores are all the same type.  This adds AT_ARM64_MIDR
aux vector type and passes down the midr system register.

This is alternative to MIDR_EL1 part of
http://lists.infradead.org/pipermail/linux-arm-kernel/2015-July/358995.html.
It allows for faster access to midr_el1 than going through a trap and
does not exist if the set of cores are not the same.

Changes from v1:
Forgot to include the auxvec.h part.

Signed-off-by: Andrew Pinski <apinski at cavium.com>
---
 arch/arm64/include/asm/cpu.h         |    1 +
 arch/arm64/include/asm/elf.h         |    6 ++++++
 arch/arm64/include/uapi/asm/auxvec.h |    3 +++
 arch/arm64/kernel/cpuinfo.c          |   22 ++++++++++++++++++++++
 4 files changed, 32 insertions(+)

diff --git a/arch/arm64/include/asm/cpu.h b/arch/arm64/include/asm/cpu.h
index 8e797b2..fab0aa1 100644
--- a/arch/arm64/include/asm/cpu.h
+++ b/arch/arm64/include/asm/cpu.h
@@ -62,5 +62,6 @@ DECLARE_PER_CPU(struct cpuinfo_arm64, cpu_data);
 
 void cpuinfo_store_cpu(void);
 void __init cpuinfo_store_boot_cpu(void);
+u32 get_arm64_midr(void);
 
 #endif /* __ASM_CPU_H */
diff --git a/arch/arm64/include/asm/elf.h b/arch/arm64/include/asm/elf.h
index faad6df..d3549de 100644
--- a/arch/arm64/include/asm/elf.h
+++ b/arch/arm64/include/asm/elf.h
@@ -17,6 +17,7 @@
 #define __ASM_ELF_H
 
 #include <asm/hwcap.h>
+#include <asm/cpu.h>
 
 /*
  * ELF register definitions..
@@ -138,8 +139,13 @@ typedef struct user_fpsimd_state elf_fpregset_t;
 
 #define ARCH_DLINFO							\
 do {									\
+	u32 midr;							\
+									\
 	NEW_AUX_ENT(AT_SYSINFO_EHDR,					\
 		    (elf_addr_t)current->mm->context.vdso);		\
+	midr = get_arm64_midr();					\
+	if (midr != 0)							\
+		NEW_AUX_ENT(AT_ARM64_MIDR, (elf_addr_t)midr);		\
 } while (0)
 
 #define ARCH_HAS_SETUP_ADDITIONAL_PAGES
diff --git a/arch/arm64/include/uapi/asm/auxvec.h b/arch/arm64/include/uapi/asm/auxvec.h
index 22d6d88..dc55c56 100644
--- a/arch/arm64/include/uapi/asm/auxvec.h
+++ b/arch/arm64/include/uapi/asm/auxvec.h
@@ -19,4 +19,7 @@
 /* vDSO location */
 #define AT_SYSINFO_EHDR	33
 
+/* Machine IDenfier Register (MDIR). */
+#define AT_ARM64_MIDR 38
+
 #endif
diff --git a/arch/arm64/kernel/cpuinfo.c b/arch/arm64/kernel/cpuinfo.c
index 75d5a86..b14c87d 100644
--- a/arch/arm64/kernel/cpuinfo.c
+++ b/arch/arm64/kernel/cpuinfo.c
@@ -254,3 +254,25 @@ void __init cpuinfo_store_boot_cpu(void)
 
 	boot_cpu_data = *info;
 }
+
+u32 get_arm64_midr(void)
+{
+	int i;
+	u32 midr = 0;
+
+	for_each_online_cpu(i) {
+		struct cpuinfo_arm64 *cpuinfo = &per_cpu(cpu_data, i);
+		u32 oldmidr = midr;
+
+		midr = cpuinfo->reg_midr;
+		/*
+		 * If there are cpus which have a different
+		 * midr just return 0.
+		 */
+		if (oldmidr && oldmidr != midr)
+			return 0;
+	}
+
+	return midr;
+}
+
-- 
1.7.10.4



From robert.jarzmik at free.fr  Sat Aug 29 13:12:08 2015
From: robert.jarzmik at free.fr (Robert Jarzmik)
Date: Sat, 29 Aug 2015 22:12:08 +0200
Subject: Possible regression: module insertion, relocation misalignement
Message-ID: <87egil26sn.fsf@belgarion.home>

Hello,

I have a strange regression with linux-next on module insertion. The stack I get
when inserting a module is in [3]. I'm using the gcc in [1], and added a small
print in [2]. This happens on a pxa310 cm-x300 platform.

As far as I understand the Oops, this is an unaligned access on the following
relocation (0xbf009a26):
	*(u32 *)loc += sym->st_value;

This happens regardless of the module I try, by that fat.ko, pxa3xx-nand.ko, etc
.. I add that I have not changed my toolchain for quite some time.

Is there anyone also affected by this bug ?

Cheers.

-- 
Robert

[1] gcc version
===============
rj at belgarion:~/mio_linux/kernel$ arm-linux-gnueabi-gcc -v
Using built-in specs.
COLLECT_GCC=/usr/bin/arm-linux-gnueabi-gcc
COLLECT_LTO_WRAPPER=/usr/lib/gcc/arm-linux-gnueabi/4.9/lto-wrapper
Target: arm-linux-gnueabi
Configured with: ../src/configure -v --with-pkgversion=' 4.9.2-10' --with-bugurl=file:///usr/share/doc/gcc-4.9/README.Bugs --enable-languages=c,c++,go,fortran,objc --prefix=/usr --program-suffix=-4.9 --enable-shared --enable-linker-build-id --libexecdir=/usr/lib --without-included-gettext --enable-threads=posix --with-gxx-include-dir=/usr/include/c++/4.9 --libdir=/usr/lib --enable-nls --with-sysroot=/ --enable-clocale=gnu --enable-libstdcxx-debug --enable-libstdcxx-time=yes --enable-gnu-unique-object --disable-libitm --disable-libquadmath --enable-plugin --with-system-zlib --enable-objc-gc --enable-multiarch --disable-sjlj-exceptions --with-arch=armv4t --with-float=soft --enable-checking=release --build=x86_64-linux-gnu --host=x86_64-linux-gnu --target=arm-linux-gnueabi --program-prefix=arm-linux-gnueabi-
Thread model: posix
gcc version 4.9.2 ( 4.9.2-10) 

[2] Debug patch in arch/arm/kernel/module.c
===========================================
diff --git a/arch/arm/kernel/module.c b/arch/arm/kernel/module.c
index efdddcb97dd1..aed935c55d63 100644
--- a/arch/arm/kernel/module.c
+++ b/arch/arm/kernel/module.c
@@ -88,6 +88,9 @@ apply_relocate(Elf32_Shdr *sechdrs, const char *strtab, unsigned int symindex,
                        return -ENOEXEC;
                }
 
+               pr_info("%s():%d dstsec=%p dstsec->sh_addr=%p rel=%p rel->r_offset=%u\n",
+                       __func__, __LINE__, dstsec, dstsec,
+                       dstsec->sh_addr, rel, rel->r_offset);
                loc = dstsec->sh_addr + rel->r_offset;
 
                switch (ELF32_R_TYPE(rel->r_info)) {

[3] Backtrace
=============
apply_relocate():93 dstsec=e4aa4e74 dstsec->sh_addr=e4aa4e74 rel=bf009420 rel->r_offset=3836194428
apply_relocate():93 dstsec=e4aa4eec dstsec->sh_addr=e4aa4eec rel=bf009a26 rel->r_offset=3836194436
Unable to handle kernel paging request at virtual address bf009a26
pgd = e1e28000
[bf009a26] *pgd=c1f0e851, *pte=c1f0a04f, *ppte=c1f0a01f
Internal error: Oops: 23 [#1] ARM
Modules linked in:
CPU: 0 PID: 607 Comm: insmod Not tainted 4.2.0-rc8-next-20150828-cm-x300+ #876
Hardware name: CM-X300 module
task: e222e700 ti: e1d6c000 task.ti: e1d6c000
PC is at apply_relocate+0x294/0x37c
LR is at 0xbf009a26
pc : [<c000e9a8>]    lr : [<bf009a26>]    psr: 80000013
sp : e1d6de40  ip : 60000013  fp : e4aa4f14
r10: e4a7ae84  r9 : e4a77ed8  r8 : e4aa552c
r7 : 00000000  r6 : e4a7ae84  r5 : e4aa4eec  r4 : bf00e0d4
r3 : bf009a26  r2 : 00000002  r1 : 00000000  r0 : bf000000
Flags: Nzcv  IRQs on  FIQs on  Mode SVC_32  ISA ARM  Segment none
Control: 0000397f  Table: c1e28018  DAC: 00000051
Process insmod (pid: 607, stack limit = 0xe1d6c198)
Stack: (0xe1d6de40 to 0xe1d6e000)
de40: ???????? ???????? ???????? ???????? ???????? ???????? ???????? ????????
de60: ???????? ???????? ???????? ???????? ???????? ???????? ???????? ????????
de80: ???????? ???????? ???????? ???????? ???????? ???????? ???????? ????????
dea0: ???????? ???????? ???????? ???????? ???????? ???????? ???????? ????????
dec0: ???????? ???????? ???????? ???????? ???????? ???????? ???????? ????????
dee0: ???????? ???????? ???????? ???????? ???????? ???????? ???????? ????????
df00: ???????? ???????? ???????? ???????? ???????? ???????? ???????? ????????
df20: ???????? ???????? ???????? ???????? ???????? ???????? ???????? ????????
df40: ???????? ???????? ???????? ???????? ???????? ???????? ???????? ????????
df60: ???????? ???????? ???????? ???????? ???????? ???????? ???????? ????????
df80: ???????? ???????? ???????? ???????? ???????? ???????? ???????? ????????
dfa0: ???????? ???????? ???????? ???????? ???????? ???????? ???????? ????????
dfc0: ???????? ???????? ???????? ???????? ???????? ???????? ???????? ????????
dfe0: ???????? ???????? ???????? ???????? ???????? ???????? ???????? ????????
[<c000e9a8>] (apply_relocate) from [<c005c8bc>] (load_module+0x1150/0x1d8c)
[<c005c8bc>] (load_module) from [<c005d5d4>] (SyS_init_module+0xdc/0x140)
[<c005d5d4>] (SyS_init_module) from [<c000a420>] (ret_fast_syscall+0x0/0x38)
Code: bad PC value
---[ end trace 6006e5b4059a4901 ]---
Segmentation fault


From robh at kernel.org  Sat Aug 29 16:01:20 2015
From: robh at kernel.org (Rob Herring)
Date: Sat, 29 Aug 2015 18:01:20 -0500
Subject: [PATCH v3 RESEND 0/5] Remaining part of kill off set_irq_flags usage
Message-ID: <1440889285-5637-1-git-send-email-robh@kernel.org>

Thomas,

As requested, here are the remaining patches for killing off 
set_irq_flags which have not been picked up. The rest of the 
series has been picked up and are in -next. 

Rob

Rob Herring (5):
  gpu/drm: kill off set_irq_flags usage
  irqchip: kill off set_irq_flags usage
  sh: kill off set_irq_flags usage
  ARM: remove ununsed set_irq_flags
  arm64: remove ununsed set_irq_flags

 arch/arm/include/asm/hw_irq.h             |  6 ------
 arch/arm/kernel/irq.c                     | 20 --------------------
 arch/arm64/include/asm/hardirq.h          |  5 -----
 drivers/gpu/drm/msm/mdp/mdp5/mdp5_irq.c   |  1 -
 drivers/gpu/ipu-v3/ipu-common.c           |  3 +--
 drivers/irqchip/exynos-combiner.c         |  2 +-
 drivers/irqchip/irq-armada-370-xp.c       |  3 +--
 drivers/irqchip/irq-bcm2835.c             |  2 +-
 drivers/irqchip/irq-clps711x.c            |  6 +++---
 drivers/irqchip/irq-gic-v3.c              |  5 ++---
 drivers/irqchip/irq-gic.c                 |  4 ++--
 drivers/irqchip/irq-hip04.c               |  4 ++--
 drivers/irqchip/irq-keystone.c            |  2 +-
 drivers/irqchip/irq-mmp.c                 |  3 ---
 drivers/irqchip/irq-mxs.c                 |  1 -
 drivers/irqchip/irq-renesas-intc-irqpin.c |  1 -
 drivers/irqchip/irq-renesas-irqc.c        |  1 -
 drivers/irqchip/irq-s3c24xx.c             | 14 ++------------
 drivers/irqchip/irq-sun4i.c               |  2 +-
 drivers/irqchip/irq-versatile-fpga.c      |  2 +-
 drivers/irqchip/irq-vic.c                 |  2 +-
 drivers/irqchip/irq-vt8500.c              |  1 -
 drivers/irqchip/spear-shirq.c             |  1 -
 drivers/sh/intc/internals.h               | 10 +---------
 24 files changed, 20 insertions(+), 81 deletions(-)

-- 
2.1.4



From robh at kernel.org  Sat Aug 29 16:01:21 2015
From: robh at kernel.org (Rob Herring)
Date: Sat, 29 Aug 2015 18:01:21 -0500
Subject: [RESEND PATCH v3 1/5] gpu/drm: kill off set_irq_flags usage
In-Reply-To: <1440889285-5637-1-git-send-email-robh@kernel.org>
References: <1440889285-5637-1-git-send-email-robh@kernel.org>
Message-ID: <1440889285-5637-2-git-send-email-robh@kernel.org>

set_irq_flags is ARM specific with custom flags which have genirq
equivalents. Convert drivers to use the genirq interfaces directly, so we
can kill off set_irq_flags. The translation of flags is as follows:

IRQF_VALID -> !IRQ_NOREQUEST
IRQF_PROBE -> !IRQ_NOPROBE
IRQF_NOAUTOEN -> IRQ_NOAUTOEN

For IRQs managed by an irqdomain, the irqdomain core code handles clearing
and setting IRQ_NOREQUEST already, so there is no need to do this in
.map() functions and we can simply remove the set_irq_flags calls. Some
users also modify IRQ_NOPROBE and this has been maintained although it
is not clear that is really needed. There appears to be a great deal of
blind copy and paste of this code.

Signed-off-by: Rob Herring <robh at kernel.org>
Cc: David Airlie <airlied at linux.ie>
Cc: dri-devel at lists.freedesktop.org
---
 drivers/gpu/drm/msm/mdp/mdp5/mdp5_irq.c | 1 -
 drivers/gpu/ipu-v3/ipu-common.c         | 3 +--
 2 files changed, 1 insertion(+), 3 deletions(-)

diff --git a/drivers/gpu/drm/msm/mdp/mdp5/mdp5_irq.c b/drivers/gpu/drm/msm/mdp/mdp5/mdp5_irq.c
index 33bd4c6..9a6a747 100644
--- a/drivers/gpu/drm/msm/mdp/mdp5/mdp5_irq.c
+++ b/drivers/gpu/drm/msm/mdp/mdp5/mdp5_irq.c
@@ -165,7 +165,6 @@ static int mdp5_hw_irqdomain_map(struct irq_domain *d,
 
 	irq_set_chip_and_handler(irq, &mdp5_hw_irq_chip, handle_level_irq);
 	irq_set_chip_data(irq, mdp5_kms);
-	set_irq_flags(irq, IRQF_VALID);
 
 	return 0;
 }
diff --git a/drivers/gpu/ipu-v3/ipu-common.c b/drivers/gpu/ipu-v3/ipu-common.c
index 00f2058..4ac9e05 100644
--- a/drivers/gpu/ipu-v3/ipu-common.c
+++ b/drivers/gpu/ipu-v3/ipu-common.c
@@ -1099,8 +1099,7 @@ static int ipu_irq_init(struct ipu_soc *ipu)
 	}
 
 	ret = irq_alloc_domain_generic_chips(ipu->domain, 32, 1, "IPU",
-					     handle_level_irq, 0,
-					     IRQF_VALID, 0);
+					     handle_level_irq, 0, 0, 0);
 	if (ret < 0) {
 		dev_err(ipu->dev, "failed to alloc generic irq chips\n");
 		irq_domain_remove(ipu->domain);
-- 
2.1.4



From robh at kernel.org  Sat Aug 29 16:01:22 2015
From: robh at kernel.org (Rob Herring)
Date: Sat, 29 Aug 2015 18:01:22 -0500
Subject: [RESEND PATCH v3 2/5] irqchip: kill off set_irq_flags usage
In-Reply-To: <1440889285-5637-1-git-send-email-robh@kernel.org>
References: <1440889285-5637-1-git-send-email-robh@kernel.org>
Message-ID: <1440889285-5637-3-git-send-email-robh@kernel.org>

set_irq_flags is ARM specific with custom flags which have genirq
equivalents. Convert drivers to use the genirq interfaces directly, so we
can kill off set_irq_flags. The translation of flags is as follows:

IRQF_VALID -> !IRQ_NOREQUEST
IRQF_PROBE -> !IRQ_NOPROBE
IRQF_NOAUTOEN -> IRQ_NOAUTOEN

For IRQs managed by an irqdomain, the irqdomain core code handles clearing
and setting IRQ_NOREQUEST already, so there is no need to do this in
.map() functions and we can simply remove the set_irq_flags calls. Some
users also modify IRQ_NOPROBE and this has been maintained although it
is not clear that is really needed. There appears to be a great deal of
blind copy and paste of this code.

Signed-off-by: Rob Herring <robh at kernel.org>
Cc: Thomas Gleixner <tglx at linutronix.de>
Cc: Jason Cooper <jason at lakedaemon.net>
Cc: Kukjin Kim <kgene at kernel.org>
Cc: Krzysztof Kozlowski <k.kozlowski at samsung.com>
Cc: Stephen Warren <swarren at wwwdotorg.org>
Cc: Lee Jones <lee at kernel.org>
Cc: Alexander Shiyan <shc_work at mail.ru>
Cc: Maxime Ripard <maxime.ripard at free-electrons.com>
Cc: linux-arm-kernel at lists.infradead.org
Cc: linux-samsung-soc at vger.kernel.org
Cc: linux-rpi-kernel at lists.infradead.org
---
 drivers/irqchip/exynos-combiner.c         |  2 +-
 drivers/irqchip/irq-armada-370-xp.c       |  3 +--
 drivers/irqchip/irq-bcm2835.c             |  2 +-
 drivers/irqchip/irq-clps711x.c            |  6 +++---
 drivers/irqchip/irq-gic-v3.c              |  5 ++---
 drivers/irqchip/irq-gic.c                 |  4 ++--
 drivers/irqchip/irq-hip04.c               |  4 ++--
 drivers/irqchip/irq-keystone.c            |  2 +-
 drivers/irqchip/irq-mmp.c                 |  3 ---
 drivers/irqchip/irq-mxs.c                 |  1 -
 drivers/irqchip/irq-renesas-intc-irqpin.c |  1 -
 drivers/irqchip/irq-renesas-irqc.c        |  1 -
 drivers/irqchip/irq-s3c24xx.c             | 14 ++------------
 drivers/irqchip/irq-sun4i.c               |  2 +-
 drivers/irqchip/irq-versatile-fpga.c      |  2 +-
 drivers/irqchip/irq-vic.c                 |  2 +-
 drivers/irqchip/irq-vt8500.c              |  1 -
 drivers/irqchip/spear-shirq.c             |  1 -
 18 files changed, 18 insertions(+), 38 deletions(-)

diff --git a/drivers/irqchip/exynos-combiner.c b/drivers/irqchip/exynos-combiner.c
index 5c82e3b..a62cfd3 100644
--- a/drivers/irqchip/exynos-combiner.c
+++ b/drivers/irqchip/exynos-combiner.c
@@ -165,7 +165,7 @@ static int combiner_irq_domain_map(struct irq_domain *d, unsigned int irq,
 
 	irq_set_chip_and_handler(irq, &combiner_chip, handle_level_irq);
 	irq_set_chip_data(irq, &combiner_data[hw >> 3]);
-	set_irq_flags(irq, IRQF_VALID | IRQF_PROBE);
+	irq_set_probe(irq);
 
 	return 0;
 }
diff --git a/drivers/irqchip/irq-armada-370-xp.c b/drivers/irqchip/irq-armada-370-xp.c
index 0d3b0fe..017f881 100644
--- a/drivers/irqchip/irq-armada-370-xp.c
+++ b/drivers/irqchip/irq-armada-370-xp.c
@@ -201,7 +201,6 @@ static int armada_370_xp_msi_map(struct irq_domain *domain, unsigned int virq,
 {
 	irq_set_chip_and_handler(virq, &armada_370_xp_msi_irq_chip,
 				 handle_simple_irq);
-	set_irq_flags(virq, IRQF_VALID);
 
 	return 0;
 }
@@ -318,7 +317,7 @@ static int armada_370_xp_mpic_irq_map(struct irq_domain *h,
 		irq_set_chip_and_handler(virq, &armada_370_xp_irq_chip,
 					handle_level_irq);
 	}
-	set_irq_flags(virq, IRQF_VALID | IRQF_PROBE);
+	irq_set_probe(virq);
 
 	return 0;
 }
diff --git a/drivers/irqchip/irq-bcm2835.c b/drivers/irqchip/irq-bcm2835.c
index e68c3b6..9c4ba16 100644
--- a/drivers/irqchip/irq-bcm2835.c
+++ b/drivers/irqchip/irq-bcm2835.c
@@ -165,7 +165,7 @@ static int __init armctrl_of_init(struct device_node *node,
 			BUG_ON(irq <= 0);
 			irq_set_chip_and_handler(irq, &armctrl_chip,
 				handle_level_irq);
-			set_irq_flags(irq, IRQF_VALID | IRQF_PROBE);
+			irq_set_probe(irq);
 		}
 	}
 
diff --git a/drivers/irqchip/irq-clps711x.c b/drivers/irqchip/irq-clps711x.c
index 33127f1..2e74e81 100644
--- a/drivers/irqchip/irq-clps711x.c
+++ b/drivers/irqchip/irq-clps711x.c
@@ -133,14 +133,14 @@ static int __init clps711x_intc_irq_map(struct irq_domain *h, unsigned int virq,
 					irq_hw_number_t hw)
 {
 	irq_flow_handler_t handler = handle_level_irq;
-	unsigned int flags = IRQF_VALID | IRQF_PROBE;
+	unsigned int flags = 0;
 
 	if (!clps711x_irqs[hw].flags)
 		return 0;
 
 	if (clps711x_irqs[hw].flags & CLPS711X_FLAG_FIQ) {
 		handler = handle_bad_irq;
-		flags |= IRQF_NOAUTOEN;
+		flags |= IRQ_NOAUTOEN;
 	} else if (clps711x_irqs[hw].eoi) {
 		handler = handle_fasteoi_irq;
 	}
@@ -150,7 +150,7 @@ static int __init clps711x_intc_irq_map(struct irq_domain *h, unsigned int virq,
 		writel_relaxed(0, clps711x_intc->base + clps711x_irqs[hw].eoi);
 
 	irq_set_chip_and_handler(virq, &clps711x_intc_chip, handler);
-	set_irq_flags(virq, flags);
+	irq_modify_status(virq, IRQ_NOPROBE, flags);
 
 	return 0;
 }
diff --git a/drivers/irqchip/irq-gic-v3.c b/drivers/irqchip/irq-gic-v3.c
index c52f7ba..16f9028 100644
--- a/drivers/irqchip/irq-gic-v3.c
+++ b/drivers/irqchip/irq-gic-v3.c
@@ -681,13 +681,13 @@ static int gic_irq_domain_map(struct irq_domain *d, unsigned int irq,
 		irq_set_percpu_devid(irq);
 		irq_domain_set_info(d, irq, hw, &gic_chip, d->host_data,
 				    handle_percpu_devid_irq, NULL, NULL);
-		set_irq_flags(irq, IRQF_VALID | IRQF_NOAUTOEN);
+		irq_set_status_flags(irq, IRQ_NOAUTOEN);
 	}
 	/* SPIs */
 	if (hw >= 32 && hw < gic_data.irq_nr) {
 		irq_domain_set_info(d, irq, hw, &gic_chip, d->host_data,
 				    handle_fasteoi_irq, NULL, NULL);
-		set_irq_flags(irq, IRQF_VALID | IRQF_PROBE);
+		irq_set_probe(irq);
 	}
 	/* LPIs */
 	if (hw >= 8192 && hw < GIC_ID_NR) {
@@ -695,7 +695,6 @@ static int gic_irq_domain_map(struct irq_domain *d, unsigned int irq,
 			return -EPERM;
 		irq_domain_set_info(d, irq, hw, &gic_chip, d->host_data,
 				    handle_fasteoi_irq, NULL, NULL);
-		set_irq_flags(irq, IRQF_VALID);
 	}
 
 	return 0;
diff --git a/drivers/irqchip/irq-gic.c b/drivers/irqchip/irq-gic.c
index 4dd8826..d6a1ba1 100644
--- a/drivers/irqchip/irq-gic.c
+++ b/drivers/irqchip/irq-gic.c
@@ -793,11 +793,11 @@ static int gic_irq_domain_map(struct irq_domain *d, unsigned int irq,
 		irq_set_percpu_devid(irq);
 		irq_domain_set_info(d, irq, hw, &gic_chip, d->host_data,
 				    handle_percpu_devid_irq, NULL, NULL);
-		set_irq_flags(irq, IRQF_VALID | IRQF_NOAUTOEN);
+		irq_set_status_flags(irq, IRQ_NOAUTOEN);
 	} else {
 		irq_domain_set_info(d, irq, hw, &gic_chip, d->host_data,
 				    handle_fasteoi_irq, NULL, NULL);
-		set_irq_flags(irq, IRQF_VALID | IRQF_PROBE);
+		irq_set_probe(irq);
 	}
 	return 0;
 }
diff --git a/drivers/irqchip/irq-hip04.c b/drivers/irqchip/irq-hip04.c
index 0cae45d..469fba6 100644
--- a/drivers/irqchip/irq-hip04.c
+++ b/drivers/irqchip/irq-hip04.c
@@ -305,11 +305,11 @@ static int hip04_irq_domain_map(struct irq_domain *d, unsigned int irq,
 		irq_set_percpu_devid(irq);
 		irq_set_chip_and_handler(irq, &hip04_irq_chip,
 					 handle_percpu_devid_irq);
-		set_irq_flags(irq, IRQF_VALID | IRQF_NOAUTOEN);
+		irq_set_status_flags(irq, IRQ_NOAUTOEN);
 	} else {
 		irq_set_chip_and_handler(irq, &hip04_irq_chip,
 					 handle_fasteoi_irq);
-		set_irq_flags(irq, IRQF_VALID | IRQF_PROBE);
+		irq_set_probe(irq);
 	}
 	irq_set_chip_data(irq, d->host_data);
 	return 0;
diff --git a/drivers/irqchip/irq-keystone.c b/drivers/irqchip/irq-keystone.c
index 81e3cf5..e7090ec 100644
--- a/drivers/irqchip/irq-keystone.c
+++ b/drivers/irqchip/irq-keystone.c
@@ -127,7 +127,7 @@ static int keystone_irq_map(struct irq_domain *h, unsigned int virq,
 
 	irq_set_chip_data(virq, kirq);
 	irq_set_chip_and_handler(virq, &kirq->chip, handle_level_irq);
-	set_irq_flags(virq, IRQF_VALID | IRQF_PROBE);
+	irq_set_probe(virq);
 	return 0;
 }
 
diff --git a/drivers/irqchip/irq-mmp.c b/drivers/irqchip/irq-mmp.c
index c0da57b..3dfef63 100644
--- a/drivers/irqchip/irq-mmp.c
+++ b/drivers/irqchip/irq-mmp.c
@@ -164,7 +164,6 @@ static int mmp_irq_domain_map(struct irq_domain *d, unsigned int irq,
 			      irq_hw_number_t hw)
 {
 	irq_set_chip_and_handler(irq, &icu_irq_chip, handle_level_irq);
-	set_irq_flags(irq, IRQF_VALID);
 	return 0;
 }
 
@@ -234,7 +233,6 @@ void __init icu_init_irq(void)
 	for (irq = 0; irq < 64; irq++) {
 		icu_mask_irq(irq_get_irq_data(irq));
 		irq_set_chip_and_handler(irq, &icu_irq_chip, handle_level_irq);
-		set_irq_flags(irq, IRQF_VALID);
 	}
 	irq_set_default_host(icu_data[0].domain);
 	set_handle_irq(mmp_handle_irq);
@@ -337,7 +335,6 @@ void __init mmp2_init_icu(void)
 			irq_set_chip_and_handler(irq, &icu_irq_chip,
 						 handle_level_irq);
 		}
-		set_irq_flags(irq, IRQF_VALID);
 	}
 	irq_set_default_host(icu_data[0].domain);
 	set_handle_irq(mmp2_handle_irq);
diff --git a/drivers/irqchip/irq-mxs.c b/drivers/irqchip/irq-mxs.c
index 04bf97b..ffe85d6 100644
--- a/drivers/irqchip/irq-mxs.c
+++ b/drivers/irqchip/irq-mxs.c
@@ -85,7 +85,6 @@ static int icoll_irq_domain_map(struct irq_domain *d, unsigned int virq,
 				irq_hw_number_t hw)
 {
 	irq_set_chip_and_handler(virq, &mxs_icoll_chip, handle_level_irq);
-	set_irq_flags(virq, IRQF_VALID);
 
 	return 0;
 }
diff --git a/drivers/irqchip/irq-renesas-intc-irqpin.c b/drivers/irqchip/irq-renesas-intc-irqpin.c
index 0670ab4..20a86de 100644
--- a/drivers/irqchip/irq-renesas-intc-irqpin.c
+++ b/drivers/irqchip/irq-renesas-intc-irqpin.c
@@ -343,7 +343,6 @@ static int intc_irqpin_irq_domain_map(struct irq_domain *h, unsigned int virq,
 	intc_irqpin_dbg(&p->irq[hw], "map");
 	irq_set_chip_data(virq, h->host_data);
 	irq_set_chip_and_handler(virq, &p->irq_chip, handle_level_irq);
-	set_irq_flags(virq, IRQF_VALID); /* kill me now */
 	return 0;
 }
 
diff --git a/drivers/irqchip/irq-renesas-irqc.c b/drivers/irqchip/irq-renesas-irqc.c
index 778bd07..74e980f 100644
--- a/drivers/irqchip/irq-renesas-irqc.c
+++ b/drivers/irqchip/irq-renesas-irqc.c
@@ -162,7 +162,6 @@ static int irqc_irq_domain_map(struct irq_domain *h, unsigned int virq,
 	irqc_dbg(&p->irq[hw], "map");
 	irq_set_chip_data(virq, h->host_data);
 	irq_set_chip_and_handler(virq, &p->irq_chip, handle_level_irq);
-	set_irq_flags(virq, IRQF_VALID); /* kill me now */
 	return 0;
 }
 
diff --git a/drivers/irqchip/irq-s3c24xx.c b/drivers/irqchip/irq-s3c24xx.c
index e96717f..19d1fc4 100644
--- a/drivers/irqchip/irq-s3c24xx.c
+++ b/drivers/irqchip/irq-s3c24xx.c
@@ -469,13 +469,11 @@ static int s3c24xx_irq_map(struct irq_domain *h, unsigned int virq,
 
 	irq_set_chip_data(virq, irq_data);
 
-	set_irq_flags(virq, IRQF_VALID);
-
 	if (parent_intc && irq_data->type != S3C_IRQTYPE_NONE) {
 		if (irq_data->parent_irq > 31) {
 			pr_err("irq-s3c24xx: parent irq %lu is out of range\n",
 			       irq_data->parent_irq);
-			goto err;
+			return -EINVAL;
 		}
 
 		parent_irq_data = &parent_intc->irqs[irq_data->parent_irq];
@@ -488,18 +486,12 @@ static int s3c24xx_irq_map(struct irq_domain *h, unsigned int virq,
 		if (!irqno) {
 			pr_err("irq-s3c24xx: could not find mapping for parent irq %lu\n",
 			       irq_data->parent_irq);
-			goto err;
+			return -EINVAL;
 		}
 		irq_set_chained_handler(irqno, s3c_irq_demux);
 	}
 
 	return 0;
-
-err:
-	set_irq_flags(virq, 0);
-
-	/* the only error can result from bad mapping data*/
-	return -EINVAL;
 }
 
 static const struct irq_domain_ops s3c24xx_irq_ops = {
@@ -1177,8 +1169,6 @@ static int s3c24xx_irq_map_of(struct irq_domain *h, unsigned int virq,
 
 	irq_set_chip_data(virq, irq_data);
 
-	set_irq_flags(virq, IRQF_VALID);
-
 	return 0;
 }
 
diff --git a/drivers/irqchip/irq-sun4i.c b/drivers/irqchip/irq-sun4i.c
index 83d6aa6..f1f401c 100644
--- a/drivers/irqchip/irq-sun4i.c
+++ b/drivers/irqchip/irq-sun4i.c
@@ -84,7 +84,7 @@ static int sun4i_irq_map(struct irq_domain *d, unsigned int virq,
 			 irq_hw_number_t hw)
 {
 	irq_set_chip_and_handler(virq, &sun4i_irq_chip, handle_fasteoi_irq);
-	set_irq_flags(virq, IRQF_VALID | IRQF_PROBE);
+	irq_set_probe(virq);
 
 	return 0;
 }
diff --git a/drivers/irqchip/irq-versatile-fpga.c b/drivers/irqchip/irq-versatile-fpga.c
index 888111b..e96b4fe 100644
--- a/drivers/irqchip/irq-versatile-fpga.c
+++ b/drivers/irqchip/irq-versatile-fpga.c
@@ -128,7 +128,7 @@ static int fpga_irqdomain_map(struct irq_domain *d, unsigned int irq,
 	irq_set_chip_data(irq, f);
 	irq_set_chip_and_handler(irq, &f->chip,
 				handle_level_irq);
-	set_irq_flags(irq, IRQF_VALID | IRQF_PROBE);
+	irq_set_probe(irq);
 	return 0;
 }
 
diff --git a/drivers/irqchip/irq-vic.c b/drivers/irqchip/irq-vic.c
index d4ce331..401561c 100644
--- a/drivers/irqchip/irq-vic.c
+++ b/drivers/irqchip/irq-vic.c
@@ -202,7 +202,7 @@ static int vic_irqdomain_map(struct irq_domain *d, unsigned int irq,
 		return -EPERM;
 	irq_set_chip_and_handler(irq, &vic_chip, handle_level_irq);
 	irq_set_chip_data(irq, v->base);
-	set_irq_flags(irq, IRQF_VALID | IRQF_PROBE);
+	irq_set_probe(irq);
 	return 0;
 }
 
diff --git a/drivers/irqchip/irq-vt8500.c b/drivers/irqchip/irq-vt8500.c
index 0b29700..8b235c9 100644
--- a/drivers/irqchip/irq-vt8500.c
+++ b/drivers/irqchip/irq-vt8500.c
@@ -168,7 +168,6 @@ static int vt8500_irq_map(struct irq_domain *h, unsigned int virq,
 							irq_hw_number_t hw)
 {
 	irq_set_chip_and_handler(virq, &vt8500_irq_chip, handle_level_irq);
-	set_irq_flags(virq, IRQF_VALID);
 
 	return 0;
 }
diff --git a/drivers/irqchip/spear-shirq.c b/drivers/irqchip/spear-shirq.c
index acb721b..e2b4e99 100644
--- a/drivers/irqchip/spear-shirq.c
+++ b/drivers/irqchip/spear-shirq.c
@@ -212,7 +212,6 @@ static void __init spear_shirq_register(struct spear_shirq *shirq,
 	for (i = 0; i < shirq->nr_irqs; i++) {
 		irq_set_chip_and_handler(shirq->virq_base + i,
 					 shirq->irq_chip, handle_simple_irq);
-		set_irq_flags(shirq->virq_base + i, IRQF_VALID);
 		irq_set_chip_data(shirq->virq_base + i, shirq);
 	}
 }
-- 
2.1.4



From robh at kernel.org  Sat Aug 29 16:01:23 2015
From: robh at kernel.org (Rob Herring)
Date: Sat, 29 Aug 2015 18:01:23 -0500
Subject: [RESEND PATCH v3 3/5] sh: kill off set_irq_flags usage
In-Reply-To: <1440889285-5637-1-git-send-email-robh@kernel.org>
References: <1440889285-5637-1-git-send-email-robh@kernel.org>
Message-ID: <1440889285-5637-4-git-send-email-robh@kernel.org>

set_irq_flags is ARM specific with custom flags which have genirq
equivalents. Convert drivers to use the genirq interfaces directly, so we
can kill off set_irq_flags. The translation of flags is as follows:

IRQF_VALID -> !IRQ_NOREQUEST
IRQF_PROBE -> !IRQ_NOPROBE
IRQF_NOAUTOEN -> IRQ_NOAUTOEN

For IRQs managed by an irqdomain, the irqdomain core code handles clearing
and setting IRQ_NOREQUEST already, so there is no need to do this in
.map() functions and we can simply remove the set_irq_flags calls. Some
users also modify IRQ_NOPROBE and this has been maintained although it
is not clear that is really needed. There appears to be a great deal of
blind copy and paste of this code.

Signed-off-by: Rob Herring <robh at kernel.org>
Acked-by: Simon Horman <horms at verge.net.au>
Cc: Magnus Damm <magnus.damm at gmail.com>
Cc: linux-sh at vger.kernel.org
---
 drivers/sh/intc/internals.h | 10 +---------
 1 file changed, 1 insertion(+), 9 deletions(-)

diff --git a/drivers/sh/intc/internals.h b/drivers/sh/intc/internals.h
index 7dff08e..6ce7f0d 100644
--- a/drivers/sh/intc/internals.h
+++ b/drivers/sh/intc/internals.h
@@ -99,15 +99,7 @@ static inline struct intc_desc_int *get_intc_desc(unsigned int irq)
  */
 static inline void activate_irq(int irq)
 {
-#ifdef CONFIG_ARM
-	/* ARM requires an extra step to clear IRQ_NOREQUEST, which it
-	 * sets on behalf of every irq_chip.  Also sets IRQ_NOPROBE.
-	 */
-	set_irq_flags(irq, IRQF_VALID);
-#else
-	/* same effect on other architectures */
-	irq_set_noprobe(irq);
-#endif
+	irq_modify_status(irq, IRQ_NOREQUEST, IRQ_NOPROBE);
 }
 
 static inline int intc_handle_int_cmp(const void *a, const void *b)
-- 
2.1.4



From robh at kernel.org  Sat Aug 29 16:01:24 2015
From: robh at kernel.org (Rob Herring)
Date: Sat, 29 Aug 2015 18:01:24 -0500
Subject: [RESEND PATCH v3 4/5] ARM: remove ununsed set_irq_flags
In-Reply-To: <1440889285-5637-1-git-send-email-robh@kernel.org>
References: <1440889285-5637-1-git-send-email-robh@kernel.org>
Message-ID: <1440889285-5637-5-git-send-email-robh@kernel.org>

Now that all users of set_irq_flags and custom flags are converted to
genirq functions, the ARM specific set_irq_flags can be removed.

Signed-off-by: Rob Herring <robh at kernel.org>
Cc: Russell King <linux at arm.linux.org.uk>
Cc: linux-arm-kernel at lists.infradead.org
Tested-by: Kevin Hilman <khilman at linaro.org>
---
 arch/arm/include/asm/hw_irq.h |  6 ------
 arch/arm/kernel/irq.c         | 20 --------------------
 2 files changed, 26 deletions(-)

diff --git a/arch/arm/include/asm/hw_irq.h b/arch/arm/include/asm/hw_irq.h
index af79da4..9beb929 100644
--- a/arch/arm/include/asm/hw_irq.h
+++ b/arch/arm/include/asm/hw_irq.h
@@ -11,12 +11,6 @@ static inline void ack_bad_irq(int irq)
 	pr_crit("unexpected IRQ trap at vector %02x\n", irq);
 }
 
-void set_irq_flags(unsigned int irq, unsigned int flags);
-
-#define IRQF_VALID	(1 << 0)
-#define IRQF_PROBE	(1 << 1)
-#define IRQF_NOAUTOEN	(1 << 2)
-
 #define ARCH_IRQ_INIT_FLAGS	(IRQ_NOREQUEST | IRQ_NOPROBE)
 
 #endif
diff --git a/arch/arm/kernel/irq.c b/arch/arm/kernel/irq.c
index 350f188..4072266 100644
--- a/arch/arm/kernel/irq.c
+++ b/arch/arm/kernel/irq.c
@@ -78,26 +78,6 @@ asm_do_IRQ(unsigned int irq, struct pt_regs *regs)
 	handle_IRQ(irq, regs);
 }
 
-void set_irq_flags(unsigned int irq, unsigned int iflags)
-{
-	unsigned long clr = 0, set = IRQ_NOREQUEST | IRQ_NOPROBE | IRQ_NOAUTOEN;
-
-	if (irq >= nr_irqs) {
-		pr_err("Trying to set irq flags for IRQ%d\n", irq);
-		return;
-	}
-
-	if (iflags & IRQF_VALID)
-		clr |= IRQ_NOREQUEST;
-	if (iflags & IRQF_PROBE)
-		clr |= IRQ_NOPROBE;
-	if (!(iflags & IRQF_NOAUTOEN))
-		clr |= IRQ_NOAUTOEN;
-	/* Order is clear bits in "clr" then set bits in "set" */
-	irq_modify_status(irq, clr, set & ~clr);
-}
-EXPORT_SYMBOL_GPL(set_irq_flags);
-
 void __init init_IRQ(void)
 {
 	int ret;
-- 
2.1.4



From robh at kernel.org  Sat Aug 29 16:01:25 2015
From: robh at kernel.org (Rob Herring)
Date: Sat, 29 Aug 2015 18:01:25 -0500
Subject: [RESEND PATCH v3 5/5] arm64: remove ununsed set_irq_flags
In-Reply-To: <1440889285-5637-1-git-send-email-robh@kernel.org>
References: <1440889285-5637-1-git-send-email-robh@kernel.org>
Message-ID: <1440889285-5637-6-git-send-email-robh@kernel.org>

Now that all users of set_irq_flags and custom flags are converted to
genirq functions, the ARM specific set_irq_flags can be removed.

Signed-off-by: Rob Herring <robh at kernel.org>
Acked-by: Catalin Marinas <catalin.marinas at arm.com>
Cc: Will Deacon <will.deacon at arm.com>
Cc: linux-arm-kernel at lists.infradead.org
---
 arch/arm64/include/asm/hardirq.h | 5 -----
 1 file changed, 5 deletions(-)

diff --git a/arch/arm64/include/asm/hardirq.h b/arch/arm64/include/asm/hardirq.h
index 6aae421..1679d22 100644
--- a/arch/arm64/include/asm/hardirq.h
+++ b/arch/arm64/include/asm/hardirq.h
@@ -47,9 +47,4 @@ static inline void ack_bad_irq(unsigned int irq)
 	irq_err_count++;
 }
 
-/*
- * No arch-specific IRQ flags.
- */
-#define set_irq_flags(irq, flags)
-
 #endif /* __ASM_HARDIRQ_H */
-- 
2.1.4



From andrew.c12 at gmail.com  Sat Aug 29 18:11:08 2015
From: andrew.c12 at gmail.com (Andrew Innes)
Date: Sun, 30 Aug 2015 09:11:08 +0800
Subject: Trying to get a Pogoplug v4 board description added
In-Reply-To: <20150829153646.GB31545@lunn.ch>
References: <CAAKvOShfrRn-E9o2Gjek5xb8xfGucUmO_FRu7c3T7S2V=co-2g@mail.gmail.com>
 <20150829153646.GB31545@lunn.ch>
Message-ID: <CAAKvOSg7h=YOVWQ1gKLv-WGw6BGF_rBfp+Zb=za7FkKE2Zwbhg@mail.gmail.com>

I have found the author and I have sent ebbix a pivate message
informing him of what I'm doing and asking for his email address.
http://archlinuxarm.org/forum/
There is a severe lack of licence information.

The following is me trying to find the author.

This is the first dts I remember being available
Postby ebbix ? Tue Mar 11, 2014 4:25 pm
http://archlinuxarm.org/forum/viewtopic.php?f=53&t=6974

ebbix posting it to a thread for bodhi
http://forum.doozan.com/read.php?3,14697,17934,quote=1

The fIle I included in the previous e-mail is from this 4.1 kernel
maintained by bodhi <mibodhi at gmail.com> just with the commented out
sections removed
He credits ebbix for the original dts in the 3.17 credits
Credits: Thanks the ALARM devs at Arch site for the GoFlex Home and
Pogo E02 DTS, and forum member ebbix for Pogo V4 DTS, and pkirchhofer
for the NSA325 DTS.
http://forum.doozan.com/read.php?2,12096


Then there are various different versions around the Internet

moonman made a committ on github containing it
https://github.com/archlinuxarm/PKGBUILDs/blob/master/core/linux-kirkwood-dt/pogoplugv4_fdt.patch

line 2041
https://github.com/davidedg/NAS-NSA325-mod/blob/57c412d98295ee25a53f9a2f326a4e44159074ab/kernel/linux-4.1.0-kirkwood-tld-2.patch

Openwrt
https://www.mail-archive.com/openwrt-devel at lists.openwrt.org/msg27147.html

Even a bsd lisenced one from freebsd that looks like it was written from scratch
https://bz-attachments.freebsd.org/attachment.cgi?id=155083

On Sat, Aug 29, 2015 at 11:36 PM, Andrew Lunn <andrew at lunn.ch> wrote:
> On Sat, Aug 29, 2015 at 01:04:54PM +0800, Andrew Innes wrote:
>> Hi Andrew
>> Sorry to contact you like this but I was a little bit unsure on how to
>> go about getting a device tree description added to the kernel.
>
> No problems as a first contact. However, the rest should be done on
> list.
>
>> I own a couple of these devices and there is an out of tree patch with
>> this description.
>> I haven't seen any attempt to get them added on the device tree
>> mailing list archives so I thought I would try.
>
> Device tree would actually be the wrong list. You should send it to
> the four maintainers, me, Jason, Gregory and Sebastian.  You can find
> emails addresses in the MAINTAINERS file, section:
>
> ARM/Marvell Kirkwood and Armada 370, 375, 38x, XP SOC support
>
> and also CC linux-arm-kernel at lists.infradead.org
>
>> Would you be able to offer any advice on the quality of the included file.
>
> At a first look, it seems pretty good. Once you post it, i will take a
> proper look.
>
> What does need to be sorted out is copyright and license. Who actually
> wrote it, and what license is it released under. Can you try to find
> that out?
>
> Thanks
>         Andrew
>
>
>>
>>
>> kirkwood-pogoplug_v4.dts
>> /dts-v1/;
>>
>> #include "kirkwood.dtsi"
>> #include "kirkwood-6192.dtsi"
>>
>> / {
>>         model = "Pogoplug v4";
>>         compatible = "cloudengines,pogoplug-v4",
>> "cloudengines,pogoplug-mobile", "marvell,kirkwood-88f6192",
>> "marvell,kirkwood";
>>
>>         memory {
>>                 device_type = "memory";
>>                 reg = <0x00000000 0x8000000>;
>>         };
>>
>>         chosen {
>>                 bootargs = "console=ttyS0,115200";
>>                 stdout-path = &uart0;
>>         };
>>
>>         mbus {
>>                 pcie-controller {
>>                         status = "okay";
>>
>>                         pcie at 1,0 {
>>                                 status = "okay";
>>                         };
>>                 };
>>         };
>>
>>         ocp at f1000000 {
>>                 pinctrl: pin-controller at 10000 {
>>                         pmx_led_green: pmx-led-green {
>>                                 marvell,pins = "mpp22";
>>                                 marvell,function = "gpio";
>>                         };
>>                         pmx_led_red: pmx-led-red {
>>                                 marvell,pins = "mpp24";
>>                                 marvell,function = "gpio";
>>                         };
>>                         pmx_button_eject: pmx-button-eject {
>>                                 marvell,pins = "mpp29";
>>                                 marvell,function = "gpio";
>>                         };
>>                 };
>>
>>                 serial at 12000 {
>>                         status = "okay";
>>                 };
>>
>>                 sata at 80000 {
>>                         status = "okay";
>>                         nr-ports = <1>;
>>                         phys = <&sata_phy0>;
>>                         phy-names = "port0";
>>                 };
>>
>>                 mvsdio at 90000 {
>>                         pinctrl-0 = <&pmx_sdio>;
>>                         pinctrl-names = "default";
>>                         status = "okay";
>>                         cd-gpios = <&gpio0 27 GPIO_ACTIVE_HIGH>;
>>                         /* No WP GPIO */
>>                 };
>>         };
>>
>>         gpio-leds {
>>                 compatible = "gpio-leds";
>>                 pinctrl-0 = <&pmx_led_red &pmx_led_green>;
>>                 pinctrl-names = "default";
>>
>>                 health {
>>                         label = "status:green:health";
>>                         gpios = <&gpio0 22 GPIO_ACTIVE_LOW>;
>>                         default-state = "keep";
>>                 };
>>                 fault {
>>                         label = "status:red:fault";
>>                         gpios = <&gpio0 24 GPIO_ACTIVE_LOW>;
>>                 };
>>         };
>>
>>         gpio_keys {
>>                 compatible = "gpio-keys";
>>                 #address-cells = <1>;
>>                 #size-cells = <0>;
>>                 pinctrl-0 = <&pmx_button_eject>;
>>                 pinctrl-names = "default";
>>
>>                 button at 1 {
>>                         label = "Eject Button";
>>                         linux,code = <KEY_EJECTCD>;
>>                         gpios = <&gpio0 29 GPIO_ACTIVE_LOW>;
>>                 };
>>         };
>> };
>>
>> &nand {
>>         status = "okay";
>>
>>         partition at 0 {
>>                 label = "u-boot";
>>                 reg = <0x0000000 0x200000>;
>>                 read-only;
>>         };
>>
>>         partition at 200000 {
>>                 label = "uImage";
>>                 reg = <0x200000 0x300000>;
>>         };
>>
>>         partition at 500000 {
>>                 label = "uImage2";
>>                 reg = <0x500000 0x300000>;
>>         };
>>
>>         partition at 800000 {
>>                 label = "failsafe";
>>                 reg = <0x800000 0x800000>;
>>         };
>>
>>         partition at 1000000 {
>>                 label = "root";
>>                 reg = <0x1000000 0x7000000>;
>>         };
>> };
>>
>> &mdio {
>>         status = "okay";
>>
>>         ethphy0: ethernet-phy at 0 {
>>                 reg = <0>;
>>         };
>> };
>>
>> &eth0 {
>>         status = "okay";
>>         ethernet0-port at 0 {
>>                 phy-handle = <&ethphy0>;
>>         };
>> };


From mchehab at osg.samsung.com  Sat Aug 29 20:06:11 2015
From: mchehab at osg.samsung.com (Mauro Carvalho Chehab)
Date: Sun, 30 Aug 2015 00:06:11 -0300
Subject: [PATCH v8 00/55] MC next generation patches
Message-ID: <cover.1440902901.git.mchehab@osg.samsung.com>

That's the 8th version of the MC next generation patches.

Differences from version 7:

- Patches reworked to make the reviewers happy;
- Bug fixes;
- ALSA changes got their own separate patches;
- Javier patches got integrated into this series;
- media-entity.h structs are now properly documented;
- Tested on both au0828 and omap3isp.

Due to the complexity of this change, other platform drivers may
require some fixes. 

As the patch series sent before, this is not meant to be sent
upstream yet. Its goal is to merge it for Kernel 4.4, in order to
give people enough time to review and fix pending issues.

Regards,
Mauro

Javier Martinez Canillas (6):
  [media] staging: omap4iss: get entity ID using media_entity_id()
  [media] omap3isp: get entity ID using media_entity_id()
  [media] media: use entity.graph_obj.mdev instead of .parent
  [media] media: remove media entity .parent field
  [media] omap3isp: separate links creation from entities init
  [media] omap3isp: create links after all subdevs have been bound

Mauro Carvalho Chehab (49):
  [media] media: create a macro to get entity ID
  [media] media: add a common struct to be embed on media graph objects
  [media] media: use media_gobj inside entities
  [media] media: use media_gobj inside pads
  [media] media: use media_gobj inside links
  [media] media: add messages when media device gets (un)registered
  [media] media: add a debug message to warn about gobj creation/removal
  [media] media: rename the function that create pad links
  [media] uapi/media.h: Declare interface types for V4L2 and DVB
  [media] media: add functions to allow creating interfaces
  [media] uapi/media.h: Declare interface types for ALSA
  [media] media: Don't accept early-created links
  [media] media: convert links from array to list
  [media] media: make add link more generic
  [media] media: make media_link more generic to handle interace links
  [media] media: make link debug printk more generic
  [media] media: add support to link interfaces and entities
  [media] media-entity: add a helper function to create interface
  [media] dvbdev: add support for interfaces
  [media] media: add a linked list to track interfaces by mdev
  [media] dvbdev: add support for indirect interface links
  [media] uapi/media.h: Fix entity namespace
  [media] replace all occurrences of MEDIA_ENT_T_DEVNODE_V4L
  [media] replace all occurrences of MEDIA_ENT_T_DEVNODE_DVB
  [media] media: add macros to check if subdev or V4L2 DMA
  [media] media: use macros to check for V4L2 subdev entities
  [media] omap3/omap4/davinci: get rid of MEDIA_ENT_T_V4L2_SUBDEV abuse
  [media] s5c73m3: fix subdev type
  [media] s5k5baf: fix subdev type
  [media] davinci_vbpe: stop MEDIA_ENT_T_V4L2_SUBDEV abuse
  [media] omap4iss: stop MEDIA_ENT_T_V4L2_SUBDEV abuse
  [media] v4l2-subdev: use MEDIA_ENT_T_UNKNOWN for new subdevs
  [media] media controller: get rid of entity subtype on Kernel
  [media] media.h: don't use legacy entity macros at Kernel
  [media] DocBook: update descriptions for the media controller entities
  [media] dvb: modify core to implement interfaces/entities at MC new
    gen
  [media] media: report if a pad is sink or source at debug msg
  [media] uapi/media.h: Add MEDIA_IOC_G_TOPOLOGY ioctl
  [media] media: Use a macro to interate between all interfaces
  [media] media: move mdev list init to gobj
  [media] media-device: add pads and links to media_device
  [media] media_device: add a topology version field
  [media] media-device: add support for MEDIA_IOC_G_TOPOLOGY ioctl
  [media] media-entity: unregister entity links
  [media] remove interface links at media_entity_unregister()
  [media] media-device: remove interfaces and interface links
  [media] v4l2-core: create MC interfaces for devnodes
  [media] au0828: unregister MC at the end
  [media] media-entity.h: document all the structs

 .../DocBook/media/v4l/media-ioc-enum-entities.xml  |  57 +--
 Documentation/media-framework.txt                  |   2 +-
 drivers/media/dvb-core/dmxdev.c                    |   4 +-
 drivers/media/dvb-core/dvb_ca_en50221.c            |   2 +-
 drivers/media/dvb-core/dvb_frontend.c              |  11 +-
 drivers/media/dvb-core/dvb_net.c                   |   2 +-
 drivers/media/dvb-core/dvbdev.c                    | 278 +++++++++---
 drivers/media/dvb-core/dvbdev.h                    |  10 +-
 drivers/media/firewire/firedtv-ci.c                |   2 +-
 drivers/media/i2c/s5c73m3/s5c73m3-core.c           |   8 +-
 drivers/media/i2c/s5k5baf.c                        |   4 +-
 drivers/media/i2c/smiapp/smiapp-core.c             |   4 +-
 drivers/media/media-device.c                       | 245 +++++++++--
 drivers/media/media-entity.c                       | 473 +++++++++++++++++----
 drivers/media/pci/bt8xx/dst_ca.c                   |   3 +-
 drivers/media/pci/ddbridge/ddbridge-core.c         |   2 +-
 drivers/media/pci/ngene/ngene-core.c               |   2 +-
 drivers/media/pci/ttpci/av7110.c                   |   2 +-
 drivers/media/pci/ttpci/av7110_av.c                |   4 +-
 drivers/media/pci/ttpci/av7110_ca.c                |   2 +-
 drivers/media/platform/exynos4-is/common.c         |   3 +-
 drivers/media/platform/exynos4-is/fimc-capture.c   |   5 +-
 drivers/media/platform/exynos4-is/fimc-isp-video.c |   9 +-
 drivers/media/platform/exynos4-is/fimc-lite.c      |  18 +-
 drivers/media/platform/exynos4-is/media-dev.c      |  25 +-
 drivers/media/platform/exynos4-is/media-dev.h      |   8 +-
 drivers/media/platform/omap3isp/isp.c              | 202 +++++----
 drivers/media/platform/omap3isp/ispccdc.c          |  39 +-
 drivers/media/platform/omap3isp/ispccdc.h          |   1 +
 drivers/media/platform/omap3isp/ispccp2.c          |  35 +-
 drivers/media/platform/omap3isp/ispccp2.h          |   1 +
 drivers/media/platform/omap3isp/ispcsi2.c          |  33 +-
 drivers/media/platform/omap3isp/ispcsi2.h          |   1 +
 drivers/media/platform/omap3isp/isppreview.c       |  48 ++-
 drivers/media/platform/omap3isp/isppreview.h       |   1 +
 drivers/media/platform/omap3isp/ispresizer.c       |  46 +-
 drivers/media/platform/omap3isp/ispresizer.h       |   1 +
 drivers/media/platform/omap3isp/ispvideo.c         |  17 +-
 drivers/media/platform/s3c-camif/camif-capture.c   |   2 +-
 drivers/media/platform/s3c-camif/camif-core.c      |   4 +-
 drivers/media/platform/vsp1/vsp1_drv.c             |   4 +-
 drivers/media/platform/vsp1/vsp1_rpf.c             |   2 +-
 drivers/media/platform/vsp1/vsp1_video.c           |  15 +-
 drivers/media/platform/vsp1/vsp1_wpf.c             |   2 +-
 drivers/media/platform/xilinx/xilinx-dma.c         |  10 +-
 drivers/media/platform/xilinx/xilinx-vipp.c        |   4 +-
 drivers/media/usb/au0828/au0828-core.c             |  18 +-
 drivers/media/usb/au0828/au0828-video.c            |   8 +-
 drivers/media/usb/cx231xx/cx231xx-cards.c          |   6 +-
 drivers/media/usb/cx231xx/cx231xx-video.c          |   8 +-
 drivers/media/usb/uvc/uvc_entity.c                 |   2 +-
 drivers/media/v4l2-core/v4l2-dev.c                 | 105 ++++-
 drivers/media/v4l2-core/v4l2-device.c              |  10 +-
 drivers/media/v4l2-core/v4l2-subdev.c              |   6 +-
 drivers/staging/media/davinci_vpfe/dm365_ipipe.c   |   9 +-
 drivers/staging/media/davinci_vpfe/dm365_ipipeif.c |  15 +-
 drivers/staging/media/davinci_vpfe/dm365_isif.c    |  15 +-
 drivers/staging/media/davinci_vpfe/dm365_resizer.c |  33 +-
 .../staging/media/davinci_vpfe/vpfe_mc_capture.c   |  10 +-
 drivers/staging/media/davinci_vpfe/vpfe_video.c    |  17 +-
 drivers/staging/media/omap4iss/iss.c               |  32 +-
 drivers/staging/media/omap4iss/iss_csi2.c          |  13 +-
 drivers/staging/media/omap4iss/iss_ipipe.c         |   9 +-
 drivers/staging/media/omap4iss/iss_ipipeif.c       |  15 +-
 drivers/staging/media/omap4iss/iss_resizer.c       |  13 +-
 drivers/staging/media/omap4iss/iss_video.c         |   9 +-
 include/media/media-device.h                       |  34 +-
 include/media/media-entity.h                       | 305 +++++++++++--
 include/media/v4l2-dev.h                           |   1 +
 include/uapi/linux/media.h                         | 205 ++++++++-
 70 files changed, 1924 insertions(+), 627 deletions(-)

-- 
2.4.3



From mchehab at osg.samsung.com  Sat Aug 29 20:06:22 2015
From: mchehab at osg.samsung.com (Mauro Carvalho Chehab)
Date: Sun, 30 Aug 2015 00:06:22 -0300
Subject: [PATCH v8 11/55] [media] media: use entity.graph_obj.mdev instead of
 .parent
In-Reply-To: <cover.1440902901.git.mchehab@osg.samsung.com>
References: <cover.1440902901.git.mchehab@osg.samsung.com>
Message-ID: <839dfe25382b7b31e3c1ea1bfb0ca0f2850536ad.1440902901.git.mchehab@osg.samsung.com>

From: Javier Martinez Canillas <javier at osg.samsung.com>

The struct media_entity has a .parent field that stores a pointer
to the parent struct media_device. But recently a media_gobj was
embedded into the entities and since struct media_gojb already has
a pointer to a struct media_device in the .mdev field, the .parent
field becomes redundant and can be removed.

This patch replaces all the usage of .parent by .graph_obj.mdev so
that field will become unused and can be removed on a later patch.

No functional changes.

The transformation was made using the following coccinelle spatch:

@@
struct media_entity *me;
@@

- me->parent
+ me->graph_obj.mdev

@@
struct media_entity *link;
@@

- link->source->entity->parent
+ link->source->entity->graph_obj.mdev

@@
struct exynos_video_entity *ve;
@@

- ve->vdev.entity.parent
+ ve->vdev.entity.graph_obj.mdev

Suggested-by: Mauro Carvalho Chehab <mchehab at osg.samsung.com>
Signed-off-by: Javier Martinez Canillas <javier at osg.samsung.com>
Acked-by: Hans Verkuil <hans.verkuil at cisco.com>
Signed-off-by: Mauro Carvalho Chehab <mchehab at osg.samsung.com>

diff --git a/drivers/media/media-device.c b/drivers/media/media-device.c
index 0f3844470147..138b18416460 100644
--- a/drivers/media/media-device.c
+++ b/drivers/media/media-device.c
@@ -435,8 +435,8 @@ int __must_check media_device_register_entity(struct media_device *mdev,
 	int i;
 
 	/* Warn if we apparently re-register an entity */
-	WARN_ON(entity->parent != NULL);
-	entity->parent = mdev;
+	WARN_ON(entity->graph_obj.mdev != NULL);
+	entity->graph_obj.mdev = mdev;
 
 	spin_lock(&mdev->lock);
 	/* Initialize media_gobj embedded at the entity */
@@ -471,7 +471,7 @@ EXPORT_SYMBOL_GPL(media_device_register_entity);
 void media_device_unregister_entity(struct media_entity *entity)
 {
 	int i;
-	struct media_device *mdev = entity->parent;
+	struct media_device *mdev = entity->graph_obj.mdev;
 
 	if (mdev == NULL)
 		return;
@@ -484,7 +484,7 @@ void media_device_unregister_entity(struct media_entity *entity)
 	media_gobj_remove(&entity->graph_obj);
 	list_del(&entity->list);
 	spin_unlock(&mdev->lock);
-	entity->parent = NULL;
+	entity->graph_obj.mdev = NULL;
 }
 EXPORT_SYMBOL_GPL(media_device_unregister_entity);
 
diff --git a/drivers/media/media-entity.c b/drivers/media/media-entity.c
index 35e52cd1fc5a..a23c93369a04 100644
--- a/drivers/media/media-entity.c
+++ b/drivers/media/media-entity.c
@@ -332,7 +332,7 @@ EXPORT_SYMBOL_GPL(media_entity_graph_walk_next);
 __must_check int media_entity_pipeline_start(struct media_entity *entity,
 					     struct media_pipeline *pipe)
 {
-	struct media_device *mdev = entity->parent;
+	struct media_device *mdev = entity->graph_obj.mdev;
 	struct media_entity_graph graph;
 	struct media_entity *entity_err = entity;
 	int ret;
@@ -387,7 +387,7 @@ __must_check int media_entity_pipeline_start(struct media_entity *entity,
 
 			ret = entity->ops->link_validate(link);
 			if (ret < 0 && ret != -ENOIOCTLCMD) {
-				dev_dbg(entity->parent->dev,
+				dev_dbg(entity->graph_obj.mdev->dev,
 					"link validation failed for \"%s\":%u -> \"%s\":%u, error %d\n",
 					link->source->entity->name,
 					link->source->index,
@@ -401,7 +401,7 @@ __must_check int media_entity_pipeline_start(struct media_entity *entity,
 
 		if (!bitmap_full(active, entity->num_pads)) {
 			ret = -EPIPE;
-			dev_dbg(entity->parent->dev,
+			dev_dbg(entity->graph_obj.mdev->dev,
 				"\"%s\":%u must be connected by an enabled link\n",
 				entity->name,
 				(unsigned)find_first_zero_bit(
@@ -454,7 +454,7 @@ EXPORT_SYMBOL_GPL(media_entity_pipeline_start);
  */
 void media_entity_pipeline_stop(struct media_entity *entity)
 {
-	struct media_device *mdev = entity->parent;
+	struct media_device *mdev = entity->graph_obj.mdev;
 	struct media_entity_graph graph;
 
 	mutex_lock(&mdev->graph_mutex);
@@ -490,8 +490,8 @@ struct media_entity *media_entity_get(struct media_entity *entity)
 	if (entity == NULL)
 		return NULL;
 
-	if (entity->parent->dev &&
-	    !try_module_get(entity->parent->dev->driver->owner))
+	if (entity->graph_obj.mdev->dev &&
+	    !try_module_get(entity->graph_obj.mdev->dev->driver->owner))
 		return NULL;
 
 	return entity;
@@ -511,8 +511,8 @@ void media_entity_put(struct media_entity *entity)
 	if (entity == NULL)
 		return;
 
-	if (entity->parent->dev)
-		module_put(entity->parent->dev->driver->owner);
+	if (entity->graph_obj.mdev->dev)
+		module_put(entity->graph_obj.mdev->dev->driver->owner);
 }
 EXPORT_SYMBOL_GPL(media_entity_put);
 
@@ -561,7 +561,8 @@ media_create_pad_link(struct media_entity *source, u16 source_pad,
 	link->flags = flags;
 
 	/* Initialize graph object embedded at the new link */
-	media_gobj_init(source->parent, MEDIA_GRAPH_LINK, &link->graph_obj);
+	media_gobj_init(source->graph_obj.mdev, MEDIA_GRAPH_LINK,
+			&link->graph_obj);
 
 	/* Create the backlink. Backlinks are used to help graph traversal and
 	 * are not reported to userspace.
@@ -577,7 +578,8 @@ media_create_pad_link(struct media_entity *source, u16 source_pad,
 	backlink->flags = flags;
 
 	/* Initialize graph object embedded at the new link */
-	media_gobj_init(sink->parent, MEDIA_GRAPH_LINK, &backlink->graph_obj);
+	media_gobj_init(sink->graph_obj.mdev, MEDIA_GRAPH_LINK,
+			&backlink->graph_obj);
 
 	link->reverse = backlink;
 	backlink->reverse = link;
@@ -629,12 +631,12 @@ EXPORT_SYMBOL_GPL(__media_entity_remove_links);
 void media_entity_remove_links(struct media_entity *entity)
 {
 	/* Do nothing if the entity is not registered. */
-	if (entity->parent == NULL)
+	if (entity->graph_obj.mdev == NULL)
 		return;
 
-	mutex_lock(&entity->parent->graph_mutex);
+	mutex_lock(&entity->graph_obj.mdev->graph_mutex);
 	__media_entity_remove_links(entity);
-	mutex_unlock(&entity->parent->graph_mutex);
+	mutex_unlock(&entity->graph_obj.mdev->graph_mutex);
 }
 EXPORT_SYMBOL_GPL(media_entity_remove_links);
 
@@ -703,7 +705,7 @@ int __media_entity_setup_link(struct media_link *link, u32 flags)
 	    (source->stream_count || sink->stream_count))
 		return -EBUSY;
 
-	mdev = source->parent;
+	mdev = source->graph_obj.mdev;
 
 	if (mdev->link_notify) {
 		ret = mdev->link_notify(link, flags,
@@ -724,9 +726,9 @@ int media_entity_setup_link(struct media_link *link, u32 flags)
 {
 	int ret;
 
-	mutex_lock(&link->source->entity->parent->graph_mutex);
+	mutex_lock(&link->source->entity->graph_obj.mdev->graph_mutex);
 	ret = __media_entity_setup_link(link, flags);
-	mutex_unlock(&link->source->entity->parent->graph_mutex);
+	mutex_unlock(&link->source->entity->graph_obj.mdev->graph_mutex);
 
 	return ret;
 }
diff --git a/drivers/media/platform/exynos4-is/fimc-isp-video.c b/drivers/media/platform/exynos4-is/fimc-isp-video.c
index b7dc5ac66e36..3d9ccbf5f10f 100644
--- a/drivers/media/platform/exynos4-is/fimc-isp-video.c
+++ b/drivers/media/platform/exynos4-is/fimc-isp-video.c
@@ -288,7 +288,7 @@ static int isp_video_open(struct file *file)
 		goto rel_fh;
 
 	if (v4l2_fh_is_singular_file(file)) {
-		mutex_lock(&me->parent->graph_mutex);
+		mutex_lock(&me->graph_obj.mdev->graph_mutex);
 
 		ret = fimc_pipeline_call(ve, open, me, true);
 
@@ -296,7 +296,7 @@ static int isp_video_open(struct file *file)
 		if (ret == 0)
 			me->use_count++;
 
-		mutex_unlock(&me->parent->graph_mutex);
+		mutex_unlock(&me->graph_obj.mdev->graph_mutex);
 	}
 	if (!ret)
 		goto unlock;
@@ -312,7 +312,7 @@ static int isp_video_release(struct file *file)
 	struct fimc_isp *isp = video_drvdata(file);
 	struct fimc_is_video *ivc = &isp->video_capture;
 	struct media_entity *entity = &ivc->ve.vdev.entity;
-	struct media_device *mdev = entity->parent;
+	struct media_device *mdev = entity->graph_obj.mdev;
 
 	mutex_lock(&isp->video_lock);
 
diff --git a/drivers/media/platform/exynos4-is/fimc-lite.c b/drivers/media/platform/exynos4-is/fimc-lite.c
index e8f707d1729b..b2607da4ad14 100644
--- a/drivers/media/platform/exynos4-is/fimc-lite.c
+++ b/drivers/media/platform/exynos4-is/fimc-lite.c
@@ -500,7 +500,7 @@ static int fimc_lite_open(struct file *file)
 	    atomic_read(&fimc->out_path) != FIMC_IO_DMA)
 		goto unlock;
 
-	mutex_lock(&me->parent->graph_mutex);
+	mutex_lock(&me->graph_obj.mdev->graph_mutex);
 
 	ret = fimc_pipeline_call(&fimc->ve, open, me, true);
 
@@ -508,7 +508,7 @@ static int fimc_lite_open(struct file *file)
 	if (ret == 0)
 		me->use_count++;
 
-	mutex_unlock(&me->parent->graph_mutex);
+	mutex_unlock(&me->graph_obj.mdev->graph_mutex);
 
 	if (!ret) {
 		fimc_lite_clear_event_counters(fimc);
@@ -541,9 +541,9 @@ static int fimc_lite_release(struct file *file)
 		fimc_pipeline_call(&fimc->ve, close);
 		clear_bit(ST_FLITE_IN_USE, &fimc->state);
 
-		mutex_lock(&entity->parent->graph_mutex);
+		mutex_lock(&entity->graph_obj.mdev->graph_mutex);
 		entity->use_count--;
-		mutex_unlock(&entity->parent->graph_mutex);
+		mutex_unlock(&entity->graph_obj.mdev->graph_mutex);
 	}
 
 	_vb2_fop_release(file, NULL);
diff --git a/drivers/media/platform/exynos4-is/media-dev.c b/drivers/media/platform/exynos4-is/media-dev.c
index 3ba76940eef5..92dbade2fffc 100644
--- a/drivers/media/platform/exynos4-is/media-dev.c
+++ b/drivers/media/platform/exynos4-is/media-dev.c
@@ -1046,7 +1046,7 @@ static int __fimc_md_modify_pipeline(struct media_entity *entity, bool enable)
 	return ret;
 }
 
-/* Locking: called with entity->parent->graph_mutex mutex held. */
+/* Locking: called with entity->graph_obj.mdev->graph_mutex mutex held. */
 static int __fimc_md_modify_pipelines(struct media_entity *entity, bool enable)
 {
 	struct media_entity *entity_err = entity;
diff --git a/drivers/media/platform/exynos4-is/media-dev.h b/drivers/media/platform/exynos4-is/media-dev.h
index 03214541f149..9a69913b31cb 100644
--- a/drivers/media/platform/exynos4-is/media-dev.h
+++ b/drivers/media/platform/exynos4-is/media-dev.h
@@ -164,8 +164,8 @@ struct fimc_sensor_info *source_to_sensor_info(struct fimc_source_info *si)
 
 static inline struct fimc_md *entity_to_fimc_mdev(struct media_entity *me)
 {
-	return me->parent == NULL ? NULL :
-		container_of(me->parent, struct fimc_md, media_dev);
+	return me->graph_obj.mdev == NULL ? NULL :
+		container_of(me->graph_obj.mdev, struct fimc_md, media_dev);
 }
 
 static inline struct fimc_md *notifier_to_fimc_md(struct v4l2_async_notifier *n)
@@ -175,12 +175,12 @@ static inline struct fimc_md *notifier_to_fimc_md(struct v4l2_async_notifier *n)
 
 static inline void fimc_md_graph_lock(struct exynos_video_entity *ve)
 {
-	mutex_lock(&ve->vdev.entity.parent->graph_mutex);
+	mutex_lock(&ve->vdev.entity.graph_obj.mdev->graph_mutex);
 }
 
 static inline void fimc_md_graph_unlock(struct exynos_video_entity *ve)
 {
-	mutex_unlock(&ve->vdev.entity.parent->graph_mutex);
+	mutex_unlock(&ve->vdev.entity.graph_obj.mdev->graph_mutex);
 }
 
 int fimc_md_set_camclk(struct v4l2_subdev *sd, bool on);
diff --git a/drivers/media/platform/omap3isp/isp.c b/drivers/media/platform/omap3isp/isp.c
index 6351f35b0a65..aa13b17d19a0 100644
--- a/drivers/media/platform/omap3isp/isp.c
+++ b/drivers/media/platform/omap3isp/isp.c
@@ -787,7 +787,7 @@ int omap3isp_pipeline_pm_use(struct media_entity *entity, int use)
 	int change = use ? 1 : -1;
 	int ret;
 
-	mutex_lock(&entity->parent->graph_mutex);
+	mutex_lock(&entity->graph_obj.mdev->graph_mutex);
 
 	/* Apply use count to node. */
 	entity->use_count += change;
@@ -798,7 +798,7 @@ int omap3isp_pipeline_pm_use(struct media_entity *entity, int use)
 	if (ret < 0)
 		entity->use_count -= change;
 
-	mutex_unlock(&entity->parent->graph_mutex);
+	mutex_unlock(&entity->graph_obj.mdev->graph_mutex);
 
 	return ret;
 }
diff --git a/drivers/media/platform/omap3isp/ispvideo.c b/drivers/media/platform/omap3isp/ispvideo.c
index 6c89dc40df85..4c367352b1f7 100644
--- a/drivers/media/platform/omap3isp/ispvideo.c
+++ b/drivers/media/platform/omap3isp/ispvideo.c
@@ -226,7 +226,7 @@ static int isp_video_get_graph_data(struct isp_video *video,
 {
 	struct media_entity_graph graph;
 	struct media_entity *entity = &video->video.entity;
-	struct media_device *mdev = entity->parent;
+	struct media_device *mdev = entity->graph_obj.mdev;
 	struct isp_video *far_end = NULL;
 
 	mutex_lock(&mdev->graph_mutex);
diff --git a/drivers/media/platform/vsp1/vsp1_video.c b/drivers/media/platform/vsp1/vsp1_video.c
index debe4e539df6..1f94c1a54e00 100644
--- a/drivers/media/platform/vsp1/vsp1_video.c
+++ b/drivers/media/platform/vsp1/vsp1_video.c
@@ -409,7 +409,7 @@ static int vsp1_pipeline_validate(struct vsp1_pipeline *pipe,
 {
 	struct media_entity_graph graph;
 	struct media_entity *entity = &video->video.entity;
-	struct media_device *mdev = entity->parent;
+	struct media_device *mdev = entity->graph_obj.mdev;
 	unsigned int i;
 	int ret;
 
diff --git a/drivers/media/platform/xilinx/xilinx-dma.c b/drivers/media/platform/xilinx/xilinx-dma.c
index f7f9aa353a55..92e8116dc28f 100644
--- a/drivers/media/platform/xilinx/xilinx-dma.c
+++ b/drivers/media/platform/xilinx/xilinx-dma.c
@@ -181,7 +181,7 @@ static int xvip_pipeline_validate(struct xvip_pipeline *pipe,
 {
 	struct media_entity_graph graph;
 	struct media_entity *entity = &start->video.entity;
-	struct media_device *mdev = entity->parent;
+	struct media_device *mdev = entity->graph_obj.mdev;
 	unsigned int num_inputs = 0;
 	unsigned int num_outputs = 0;
 
diff --git a/drivers/staging/media/davinci_vpfe/vpfe_video.c b/drivers/staging/media/davinci_vpfe/vpfe_video.c
index 61a8d5beff58..92573fa852a9 100644
--- a/drivers/staging/media/davinci_vpfe/vpfe_video.c
+++ b/drivers/staging/media/davinci_vpfe/vpfe_video.c
@@ -130,7 +130,7 @@ __vpfe_video_get_format(struct vpfe_video_device *video,
 static void vpfe_prepare_pipeline(struct vpfe_video_device *video)
 {
 	struct media_entity *entity = &video->video_dev.entity;
-	struct media_device *mdev = entity->parent;
+	struct media_device *mdev = entity->graph_obj.mdev;
 	struct vpfe_pipeline *pipe = &video->pipe;
 	struct vpfe_video_device *far_end = NULL;
 	struct media_entity_graph graph;
@@ -288,7 +288,7 @@ static int vpfe_pipeline_enable(struct vpfe_pipeline *pipe)
 	else
 		entity = &pipe->inputs[0]->video_dev.entity;
 
-	mdev = entity->parent;
+	mdev = entity->graph_obj.mdev;
 	mutex_lock(&mdev->graph_mutex);
 	media_entity_graph_walk_start(&graph, entity);
 	while ((entity = media_entity_graph_walk_next(&graph))) {
@@ -328,7 +328,7 @@ static int vpfe_pipeline_disable(struct vpfe_pipeline *pipe)
 	else
 		entity = &pipe->inputs[0]->video_dev.entity;
 
-	mdev = entity->parent;
+	mdev = entity->graph_obj.mdev;
 	mutex_lock(&mdev->graph_mutex);
 	media_entity_graph_walk_start(&graph, entity);
 
diff --git a/drivers/staging/media/omap4iss/iss.c b/drivers/staging/media/omap4iss/iss.c
index 7226553ceb2f..40591963b42b 100644
--- a/drivers/staging/media/omap4iss/iss.c
+++ b/drivers/staging/media/omap4iss/iss.c
@@ -494,7 +494,7 @@ int omap4iss_pipeline_pm_use(struct media_entity *entity, int use)
 	int change = use ? 1 : -1;
 	int ret;
 
-	mutex_lock(&entity->parent->graph_mutex);
+	mutex_lock(&entity->graph_obj.mdev->graph_mutex);
 
 	/* Apply use count to node. */
 	entity->use_count += change;
@@ -505,7 +505,7 @@ int omap4iss_pipeline_pm_use(struct media_entity *entity, int use)
 	if (ret < 0)
 		entity->use_count -= change;
 
-	mutex_unlock(&entity->parent->graph_mutex);
+	mutex_unlock(&entity->graph_obj.mdev->graph_mutex);
 
 	return ret;
 }
diff --git a/drivers/staging/media/omap4iss/iss_video.c b/drivers/staging/media/omap4iss/iss_video.c
index 25e9e7a6b99d..45a3f2d778fc 100644
--- a/drivers/staging/media/omap4iss/iss_video.c
+++ b/drivers/staging/media/omap4iss/iss_video.c
@@ -207,7 +207,7 @@ iss_video_far_end(struct iss_video *video)
 {
 	struct media_entity_graph graph;
 	struct media_entity *entity = &video->video.entity;
-	struct media_device *mdev = entity->parent;
+	struct media_device *mdev = entity->graph_obj.mdev;
 	struct iss_video *far_end = NULL;
 
 	mutex_lock(&mdev->graph_mutex);
-- 
2.4.3



From mchehab at osg.samsung.com  Sat Aug 29 20:06:21 2015
From: mchehab at osg.samsung.com (Mauro Carvalho Chehab)
Date: Sun, 30 Aug 2015 00:06:21 -0300
Subject: [PATCH v8 10/55] [media] media: rename the function that create pad
 links
In-Reply-To: <cover.1440902901.git.mchehab@osg.samsung.com>
References: <cover.1440902901.git.mchehab@osg.samsung.com>
Message-ID: <06bad8b26ee0cef02d9c52d578af3a51a0f03b1f.1440902901.git.mchehab@osg.samsung.com>

With the new API, a link can be either between two PADs or between an interface
and an entity. So, we need to use a better name for the function that create
links between two pads.

So, rename the such function to media_create_pad_link().

No functional changes.

This patch was created via this shell script:
	for i in $(find drivers/media -name '*.[ch]' -type f) $(find drivers/staging/media -name '*.[ch]' -type f) $(find include/ -name '*.h' -type f) ; do sed s,media_entity_create_link,media_create_pad_link,g <$i >a && mv a $i; done

Signed-off-by: Mauro Carvalho Chehab <mchehab at osg.samsung.com>
Acked-by: Hans Verkuil <hans.verkuil at cisco.com>
Signed-off-by: Mauro Carvalho Chehab <mchehab at osg.samsung.com>

diff --git a/Documentation/media-framework.txt b/Documentation/media-framework.txt
index 6903b2503577..b424de6c3bb3 100644
--- a/Documentation/media-framework.txt
+++ b/Documentation/media-framework.txt
@@ -199,7 +199,7 @@ pre-allocated and grows dynamically as needed.
 
 Drivers create links by calling
 
-	media_entity_create_link(struct media_entity *source, u16 source_pad,
+	media_create_pad_link(struct media_entity *source, u16 source_pad,
 				 struct media_entity *sink,   u16 sink_pad,
 				 u32 flags);
 
diff --git a/drivers/media/dvb-core/dvbdev.c b/drivers/media/dvb-core/dvbdev.c
index 2fdcbb5f000a..65f59f2124b4 100644
--- a/drivers/media/dvb-core/dvbdev.c
+++ b/drivers/media/dvb-core/dvbdev.c
@@ -412,16 +412,16 @@ void dvb_create_media_graph(struct dvb_adapter *adap)
 	}
 
 	if (tuner && fe)
-		media_entity_create_link(tuner, 0, fe, 0, 0);
+		media_create_pad_link(tuner, 0, fe, 0, 0);
 
 	if (fe && demux)
-		media_entity_create_link(fe, 1, demux, 0, MEDIA_LNK_FL_ENABLED);
+		media_create_pad_link(fe, 1, demux, 0, MEDIA_LNK_FL_ENABLED);
 
 	if (demux && dvr)
-		media_entity_create_link(demux, 1, dvr, 0, MEDIA_LNK_FL_ENABLED);
+		media_create_pad_link(demux, 1, dvr, 0, MEDIA_LNK_FL_ENABLED);
 
 	if (demux && ca)
-		media_entity_create_link(demux, 1, ca, 0, MEDIA_LNK_FL_ENABLED);
+		media_create_pad_link(demux, 1, ca, 0, MEDIA_LNK_FL_ENABLED);
 }
 EXPORT_SYMBOL_GPL(dvb_create_media_graph);
 #endif
diff --git a/drivers/media/i2c/s5c73m3/s5c73m3-core.c b/drivers/media/i2c/s5c73m3/s5c73m3-core.c
index 6d167428727d..c81bfbfea32f 100644
--- a/drivers/media/i2c/s5c73m3/s5c73m3-core.c
+++ b/drivers/media/i2c/s5c73m3/s5c73m3-core.c
@@ -1482,11 +1482,11 @@ static int s5c73m3_oif_registered(struct v4l2_subdev *sd)
 		return ret;
 	}
 
-	ret = media_entity_create_link(&state->sensor_sd.entity,
+	ret = media_create_pad_link(&state->sensor_sd.entity,
 			S5C73M3_ISP_PAD, &state->oif_sd.entity, OIF_ISP_PAD,
 			MEDIA_LNK_FL_IMMUTABLE | MEDIA_LNK_FL_ENABLED);
 
-	ret = media_entity_create_link(&state->sensor_sd.entity,
+	ret = media_create_pad_link(&state->sensor_sd.entity,
 			S5C73M3_JPEG_PAD, &state->oif_sd.entity, OIF_JPEG_PAD,
 			MEDIA_LNK_FL_IMMUTABLE | MEDIA_LNK_FL_ENABLED);
 
diff --git a/drivers/media/i2c/s5k5baf.c b/drivers/media/i2c/s5k5baf.c
index 30a9ca62e034..d3bff30bcb6f 100644
--- a/drivers/media/i2c/s5k5baf.c
+++ b/drivers/media/i2c/s5k5baf.c
@@ -1756,7 +1756,7 @@ static int s5k5baf_registered(struct v4l2_subdev *sd)
 		v4l2_err(sd, "failed to register subdev %s\n",
 			 state->cis_sd.name);
 	else
-		ret = media_entity_create_link(&state->cis_sd.entity, PAD_CIS,
+		ret = media_create_pad_link(&state->cis_sd.entity, PAD_CIS,
 					       &state->sd.entity, PAD_CIS,
 					       MEDIA_LNK_FL_IMMUTABLE |
 					       MEDIA_LNK_FL_ENABLED);
diff --git a/drivers/media/i2c/smiapp/smiapp-core.c b/drivers/media/i2c/smiapp/smiapp-core.c
index 308613ea0aed..5aa49eb393a9 100644
--- a/drivers/media/i2c/smiapp/smiapp-core.c
+++ b/drivers/media/i2c/smiapp/smiapp-core.c
@@ -2495,7 +2495,7 @@ static int smiapp_register_subdevs(struct smiapp_sensor *sensor)
 			return rval;
 		}
 
-		rval = media_entity_create_link(&this->sd.entity,
+		rval = media_create_pad_link(&this->sd.entity,
 						this->source_pad,
 						&last->sd.entity,
 						last->sink_pad,
@@ -2503,7 +2503,7 @@ static int smiapp_register_subdevs(struct smiapp_sensor *sensor)
 						MEDIA_LNK_FL_IMMUTABLE);
 		if (rval) {
 			dev_err(&client->dev,
-				"media_entity_create_link failed\n");
+				"media_create_pad_link failed\n");
 			return rval;
 		}
 
diff --git a/drivers/media/media-entity.c b/drivers/media/media-entity.c
index 6d515e149d7f..35e52cd1fc5a 100644
--- a/drivers/media/media-entity.c
+++ b/drivers/media/media-entity.c
@@ -542,7 +542,7 @@ static struct media_link *media_entity_add_link(struct media_entity *entity)
 }
 
 int
-media_entity_create_link(struct media_entity *source, u16 source_pad,
+media_create_pad_link(struct media_entity *source, u16 source_pad,
 			 struct media_entity *sink, u16 sink_pad, u32 flags)
 {
 	struct media_link *link;
@@ -586,7 +586,7 @@ media_entity_create_link(struct media_entity *source, u16 source_pad,
 
 	return 0;
 }
-EXPORT_SYMBOL_GPL(media_entity_create_link);
+EXPORT_SYMBOL_GPL(media_create_pad_link);
 
 void __media_entity_remove_links(struct media_entity *entity)
 {
diff --git a/drivers/media/platform/exynos4-is/media-dev.c b/drivers/media/platform/exynos4-is/media-dev.c
index 4f5586a4cbff..3ba76940eef5 100644
--- a/drivers/media/platform/exynos4-is/media-dev.c
+++ b/drivers/media/platform/exynos4-is/media-dev.c
@@ -729,7 +729,7 @@ static int __fimc_md_create_fimc_sink_links(struct fimc_md *fmd,
 		flags = ((1 << i) & link_mask) ? MEDIA_LNK_FL_ENABLED : 0;
 
 		sink = &fmd->fimc[i]->vid_cap.subdev.entity;
-		ret = media_entity_create_link(source, pad, sink,
+		ret = media_create_pad_link(source, pad, sink,
 					      FIMC_SD_PAD_SINK_CAM, flags);
 		if (ret)
 			return ret;
@@ -749,7 +749,7 @@ static int __fimc_md_create_fimc_sink_links(struct fimc_md *fmd,
 			continue;
 
 		sink = &fmd->fimc_lite[i]->subdev.entity;
-		ret = media_entity_create_link(source, pad, sink,
+		ret = media_create_pad_link(source, pad, sink,
 					       FLITE_SD_PAD_SINK, 0);
 		if (ret)
 			return ret;
@@ -781,13 +781,13 @@ static int __fimc_md_create_flite_source_links(struct fimc_md *fmd)
 		source = &fimc->subdev.entity;
 		sink = &fimc->ve.vdev.entity;
 		/* FIMC-LITE's subdev and video node */
-		ret = media_entity_create_link(source, FLITE_SD_PAD_SOURCE_DMA,
+		ret = media_create_pad_link(source, FLITE_SD_PAD_SOURCE_DMA,
 					       sink, 0, 0);
 		if (ret)
 			break;
 		/* Link from FIMC-LITE to IS-ISP subdev */
 		sink = &fmd->fimc_is->isp.subdev.entity;
-		ret = media_entity_create_link(source, FLITE_SD_PAD_SOURCE_ISP,
+		ret = media_create_pad_link(source, FLITE_SD_PAD_SOURCE_ISP,
 					       sink, 0, 0);
 		if (ret)
 			break;
@@ -811,7 +811,7 @@ static int __fimc_md_create_fimc_is_links(struct fimc_md *fmd)
 
 		/* Link from FIMC-IS-ISP subdev to FIMC */
 		sink = &fmd->fimc[i]->vid_cap.subdev.entity;
-		ret = media_entity_create_link(source, FIMC_ISP_SD_PAD_SRC_FIFO,
+		ret = media_create_pad_link(source, FIMC_ISP_SD_PAD_SRC_FIFO,
 					       sink, FIMC_SD_PAD_SINK_FIFO, 0);
 		if (ret)
 			return ret;
@@ -824,7 +824,7 @@ static int __fimc_md_create_fimc_is_links(struct fimc_md *fmd)
 	if (sink->num_pads == 0)
 		return 0;
 
-	return media_entity_create_link(source, FIMC_ISP_SD_PAD_SRC_DMA,
+	return media_create_pad_link(source, FIMC_ISP_SD_PAD_SRC_DMA,
 					sink, 0, 0);
 }
 
@@ -873,7 +873,7 @@ static int fimc_md_create_links(struct fimc_md *fmd)
 				return -EINVAL;
 
 			pad = sensor->entity.num_pads - 1;
-			ret = media_entity_create_link(&sensor->entity, pad,
+			ret = media_create_pad_link(&sensor->entity, pad,
 					      &csis->entity, CSIS_PAD_SINK,
 					      MEDIA_LNK_FL_IMMUTABLE |
 					      MEDIA_LNK_FL_ENABLED);
@@ -927,7 +927,7 @@ static int fimc_md_create_links(struct fimc_md *fmd)
 		source = &fmd->fimc[i]->vid_cap.subdev.entity;
 		sink = &fmd->fimc[i]->vid_cap.ve.vdev.entity;
 
-		ret = media_entity_create_link(source, FIMC_SD_PAD_SOURCE,
+		ret = media_create_pad_link(source, FIMC_SD_PAD_SOURCE,
 					      sink, 0, flags);
 		if (ret)
 			break;
diff --git a/drivers/media/platform/omap3isp/isp.c b/drivers/media/platform/omap3isp/isp.c
index e08183f9d0f7..6351f35b0a65 100644
--- a/drivers/media/platform/omap3isp/isp.c
+++ b/drivers/media/platform/omap3isp/isp.c
@@ -1865,7 +1865,7 @@ static int isp_link_entity(
 		return -EINVAL;
 	}
 
-	return media_entity_create_link(entity, i, input, pad, flags);
+	return media_create_pad_link(entity, i, input, pad, flags);
 }
 
 static int isp_register_entities(struct isp_device *isp)
@@ -2004,51 +2004,51 @@ static int isp_initialize_modules(struct isp_device *isp)
 	}
 
 	/* Connect the submodules. */
-	ret = media_entity_create_link(
+	ret = media_create_pad_link(
 			&isp->isp_csi2a.subdev.entity, CSI2_PAD_SOURCE,
 			&isp->isp_ccdc.subdev.entity, CCDC_PAD_SINK, 0);
 	if (ret < 0)
 		goto error_link;
 
-	ret = media_entity_create_link(
+	ret = media_create_pad_link(
 			&isp->isp_ccp2.subdev.entity, CCP2_PAD_SOURCE,
 			&isp->isp_ccdc.subdev.entity, CCDC_PAD_SINK, 0);
 	if (ret < 0)
 		goto error_link;
 
-	ret = media_entity_create_link(
+	ret = media_create_pad_link(
 			&isp->isp_ccdc.subdev.entity, CCDC_PAD_SOURCE_VP,
 			&isp->isp_prev.subdev.entity, PREV_PAD_SINK, 0);
 	if (ret < 0)
 		goto error_link;
 
-	ret = media_entity_create_link(
+	ret = media_create_pad_link(
 			&isp->isp_ccdc.subdev.entity, CCDC_PAD_SOURCE_OF,
 			&isp->isp_res.subdev.entity, RESZ_PAD_SINK, 0);
 	if (ret < 0)
 		goto error_link;
 
-	ret = media_entity_create_link(
+	ret = media_create_pad_link(
 			&isp->isp_prev.subdev.entity, PREV_PAD_SOURCE,
 			&isp->isp_res.subdev.entity, RESZ_PAD_SINK, 0);
 	if (ret < 0)
 		goto error_link;
 
-	ret = media_entity_create_link(
+	ret = media_create_pad_link(
 			&isp->isp_ccdc.subdev.entity, CCDC_PAD_SOURCE_VP,
 			&isp->isp_aewb.subdev.entity, 0,
 			MEDIA_LNK_FL_ENABLED | MEDIA_LNK_FL_IMMUTABLE);
 	if (ret < 0)
 		goto error_link;
 
-	ret = media_entity_create_link(
+	ret = media_create_pad_link(
 			&isp->isp_ccdc.subdev.entity, CCDC_PAD_SOURCE_VP,
 			&isp->isp_af.subdev.entity, 0,
 			MEDIA_LNK_FL_ENABLED | MEDIA_LNK_FL_IMMUTABLE);
 	if (ret < 0)
 		goto error_link;
 
-	ret = media_entity_create_link(
+	ret = media_create_pad_link(
 			&isp->isp_ccdc.subdev.entity, CCDC_PAD_SOURCE_VP,
 			&isp->isp_hist.subdev.entity, 0,
 			MEDIA_LNK_FL_ENABLED | MEDIA_LNK_FL_IMMUTABLE);
diff --git a/drivers/media/platform/omap3isp/ispccdc.c b/drivers/media/platform/omap3isp/ispccdc.c
index d96e3be5e252..27555e4f4aa8 100644
--- a/drivers/media/platform/omap3isp/ispccdc.c
+++ b/drivers/media/platform/omap3isp/ispccdc.c
@@ -2667,7 +2667,7 @@ static int ccdc_init_entities(struct isp_ccdc_device *ccdc)
 		goto error_video;
 
 	/* Connect the CCDC subdev to the video node. */
-	ret = media_entity_create_link(&ccdc->subdev.entity, CCDC_PAD_SOURCE_OF,
+	ret = media_create_pad_link(&ccdc->subdev.entity, CCDC_PAD_SOURCE_OF,
 			&ccdc->video_out.video.entity, 0, 0);
 	if (ret < 0)
 		goto error_link;
diff --git a/drivers/media/platform/omap3isp/ispccp2.c b/drivers/media/platform/omap3isp/ispccp2.c
index e1b5f5bea541..b215eb5049d6 100644
--- a/drivers/media/platform/omap3isp/ispccp2.c
+++ b/drivers/media/platform/omap3isp/ispccp2.c
@@ -1100,7 +1100,7 @@ static int ccp2_init_entities(struct isp_ccp2_device *ccp2)
 		goto error_video;
 
 	/* Connect the video node to the ccp2 subdev. */
-	ret = media_entity_create_link(&ccp2->video_in.video.entity, 0,
+	ret = media_create_pad_link(&ccp2->video_in.video.entity, 0,
 				       &ccp2->subdev.entity, CCP2_PAD_SINK, 0);
 	if (ret < 0)
 		goto error_link;
diff --git a/drivers/media/platform/omap3isp/ispcsi2.c b/drivers/media/platform/omap3isp/ispcsi2.c
index 6fff92f0813a..fcefc1e74881 100644
--- a/drivers/media/platform/omap3isp/ispcsi2.c
+++ b/drivers/media/platform/omap3isp/ispcsi2.c
@@ -1265,7 +1265,7 @@ static int csi2_init_entities(struct isp_csi2_device *csi2)
 		goto error_video;
 
 	/* Connect the CSI2 subdev to the video node. */
-	ret = media_entity_create_link(&csi2->subdev.entity, CSI2_PAD_SOURCE,
+	ret = media_create_pad_link(&csi2->subdev.entity, CSI2_PAD_SOURCE,
 				       &csi2->video_out.video.entity, 0, 0);
 	if (ret < 0)
 		goto error_link;
diff --git a/drivers/media/platform/omap3isp/isppreview.c b/drivers/media/platform/omap3isp/isppreview.c
index b440c6342ca4..ad38d20c7770 100644
--- a/drivers/media/platform/omap3isp/isppreview.c
+++ b/drivers/media/platform/omap3isp/isppreview.c
@@ -2312,12 +2312,12 @@ static int preview_init_entities(struct isp_prev_device *prev)
 		goto error_video_out;
 
 	/* Connect the video nodes to the previewer subdev. */
-	ret = media_entity_create_link(&prev->video_in.video.entity, 0,
+	ret = media_create_pad_link(&prev->video_in.video.entity, 0,
 			&prev->subdev.entity, PREV_PAD_SINK, 0);
 	if (ret < 0)
 		goto error_link;
 
-	ret = media_entity_create_link(&prev->subdev.entity, PREV_PAD_SOURCE,
+	ret = media_create_pad_link(&prev->subdev.entity, PREV_PAD_SOURCE,
 			&prev->video_out.video.entity, 0, 0);
 	if (ret < 0)
 		goto error_link;
diff --git a/drivers/media/platform/omap3isp/ispresizer.c b/drivers/media/platform/omap3isp/ispresizer.c
index 3deb1ec4a973..b48ad4d4b834 100644
--- a/drivers/media/platform/omap3isp/ispresizer.c
+++ b/drivers/media/platform/omap3isp/ispresizer.c
@@ -1756,12 +1756,12 @@ static int resizer_init_entities(struct isp_res_device *res)
 	res->video_out.video.entity.flags |= MEDIA_ENT_FL_DEFAULT;
 
 	/* Connect the video nodes to the resizer subdev. */
-	ret = media_entity_create_link(&res->video_in.video.entity, 0,
+	ret = media_create_pad_link(&res->video_in.video.entity, 0,
 			&res->subdev.entity, RESZ_PAD_SINK, 0);
 	if (ret < 0)
 		goto error_link;
 
-	ret = media_entity_create_link(&res->subdev.entity, RESZ_PAD_SOURCE,
+	ret = media_create_pad_link(&res->subdev.entity, RESZ_PAD_SOURCE,
 			&res->video_out.video.entity, 0, 0);
 	if (ret < 0)
 		goto error_link;
diff --git a/drivers/media/platform/s3c-camif/camif-core.c b/drivers/media/platform/s3c-camif/camif-core.c
index f47b332f0418..3e33c60be004 100644
--- a/drivers/media/platform/s3c-camif/camif-core.c
+++ b/drivers/media/platform/s3c-camif/camif-core.c
@@ -263,7 +263,7 @@ static int camif_create_media_links(struct camif_dev *camif)
 {
 	int i, ret;
 
-	ret = media_entity_create_link(&camif->sensor.sd->entity, 0,
+	ret = media_create_pad_link(&camif->sensor.sd->entity, 0,
 				&camif->subdev.entity, CAMIF_SD_PAD_SINK,
 				MEDIA_LNK_FL_IMMUTABLE |
 				MEDIA_LNK_FL_ENABLED);
@@ -271,7 +271,7 @@ static int camif_create_media_links(struct camif_dev *camif)
 		return ret;
 
 	for (i = 1; i < CAMIF_SD_PADS_NUM && !ret; i++) {
-		ret = media_entity_create_link(&camif->subdev.entity, i,
+		ret = media_create_pad_link(&camif->subdev.entity, i,
 				&camif->vp[i - 1].vdev.entity, 0,
 				MEDIA_LNK_FL_IMMUTABLE |
 				MEDIA_LNK_FL_ENABLED);
diff --git a/drivers/media/platform/vsp1/vsp1_drv.c b/drivers/media/platform/vsp1/vsp1_drv.c
index 4e61886384e3..9cd94a76a9ed 100644
--- a/drivers/media/platform/vsp1/vsp1_drv.c
+++ b/drivers/media/platform/vsp1/vsp1_drv.c
@@ -101,7 +101,7 @@ static int vsp1_create_links(struct vsp1_device *vsp1, struct vsp1_entity *sink)
 			if (!(entity->pads[pad].flags & MEDIA_PAD_FL_SINK))
 				continue;
 
-			ret = media_entity_create_link(&source->subdev.entity,
+			ret = media_create_pad_link(&source->subdev.entity,
 						       source->source_pad,
 						       entity, pad, flags);
 			if (ret < 0)
@@ -262,7 +262,7 @@ static int vsp1_create_entities(struct vsp1_device *vsp1)
 	}
 
 	if (vsp1->pdata.features & VSP1_HAS_LIF) {
-		ret = media_entity_create_link(
+		ret = media_create_pad_link(
 			&vsp1->wpf[0]->entity.subdev.entity, RWPF_PAD_SOURCE,
 			&vsp1->lif->entity.subdev.entity, LIF_PAD_SINK, 0);
 		if (ret < 0)
diff --git a/drivers/media/platform/vsp1/vsp1_rpf.c b/drivers/media/platform/vsp1/vsp1_rpf.c
index 3294529a3108..b60a528a8fe8 100644
--- a/drivers/media/platform/vsp1/vsp1_rpf.c
+++ b/drivers/media/platform/vsp1/vsp1_rpf.c
@@ -278,7 +278,7 @@ struct vsp1_rwpf *vsp1_rpf_create(struct vsp1_device *vsp1, unsigned int index)
 	rpf->entity.video = video;
 
 	/* Connect the video device to the RPF. */
-	ret = media_entity_create_link(&rpf->video.video.entity, 0,
+	ret = media_create_pad_link(&rpf->video.video.entity, 0,
 				       &rpf->entity.subdev.entity,
 				       RWPF_PAD_SINK,
 				       MEDIA_LNK_FL_ENABLED |
diff --git a/drivers/media/platform/vsp1/vsp1_wpf.c b/drivers/media/platform/vsp1/vsp1_wpf.c
index 1d2b3a2f1573..d39aa4b8aea1 100644
--- a/drivers/media/platform/vsp1/vsp1_wpf.c
+++ b/drivers/media/platform/vsp1/vsp1_wpf.c
@@ -284,7 +284,7 @@ struct vsp1_rwpf *vsp1_wpf_create(struct vsp1_device *vsp1, unsigned int index)
 	if (!(vsp1->pdata.features & VSP1_HAS_LIF) || index != 0)
 		flags |= MEDIA_LNK_FL_IMMUTABLE;
 
-	ret = media_entity_create_link(&wpf->entity.subdev.entity,
+	ret = media_create_pad_link(&wpf->entity.subdev.entity,
 				       RWPF_PAD_SOURCE,
 				       &wpf->video.video.entity, 0, flags);
 	if (ret < 0)
diff --git a/drivers/media/platform/xilinx/xilinx-vipp.c b/drivers/media/platform/xilinx/xilinx-vipp.c
index 7b7cb9c28d2c..79d4be7ce9a5 100644
--- a/drivers/media/platform/xilinx/xilinx-vipp.c
+++ b/drivers/media/platform/xilinx/xilinx-vipp.c
@@ -156,7 +156,7 @@ static int xvip_graph_build_one(struct xvip_composite_device *xdev,
 			local->name, local_pad->index,
 			remote->name, remote_pad->index);
 
-		ret = media_entity_create_link(local, local_pad->index,
+		ret = media_create_pad_link(local, local_pad->index,
 					       remote, remote_pad->index,
 					       link_flags);
 		if (ret < 0) {
@@ -270,7 +270,7 @@ static int xvip_graph_build_dma(struct xvip_composite_device *xdev)
 			source->name, source_pad->index,
 			sink->name, sink_pad->index);
 
-		ret = media_entity_create_link(source, source_pad->index,
+		ret = media_create_pad_link(source, source_pad->index,
 					       sink, sink_pad->index,
 					       link_flags);
 		if (ret < 0) {
diff --git a/drivers/media/usb/au0828/au0828-core.c b/drivers/media/usb/au0828/au0828-core.c
index 0378a2c99ebb..a55eb524ea21 100644
--- a/drivers/media/usb/au0828/au0828-core.c
+++ b/drivers/media/usb/au0828/au0828-core.c
@@ -260,13 +260,13 @@ static void au0828_create_media_graph(struct au0828_dev *dev)
 		return;
 
 	if (tuner)
-		media_entity_create_link(tuner, 0, decoder, 0,
+		media_create_pad_link(tuner, 0, decoder, 0,
 					 MEDIA_LNK_FL_ENABLED);
 	if (dev->vdev.entity.links)
-		media_entity_create_link(decoder, 1, &dev->vdev.entity, 0,
+		media_create_pad_link(decoder, 1, &dev->vdev.entity, 0,
 				 MEDIA_LNK_FL_ENABLED);
 	if (dev->vbi_dev.entity.links)
-		media_entity_create_link(decoder, 2, &dev->vbi_dev.entity, 0,
+		media_create_pad_link(decoder, 2, &dev->vbi_dev.entity, 0,
 				 MEDIA_LNK_FL_ENABLED);
 #endif
 }
diff --git a/drivers/media/usb/cx231xx/cx231xx-cards.c b/drivers/media/usb/cx231xx/cx231xx-cards.c
index 4a117a58c39a..3b5c9ae39ad3 100644
--- a/drivers/media/usb/cx231xx/cx231xx-cards.c
+++ b/drivers/media/usb/cx231xx/cx231xx-cards.c
@@ -1264,11 +1264,11 @@ static void cx231xx_create_media_graph(struct cx231xx *dev)
 		return;
 
 	if (tuner)
-		media_entity_create_link(tuner, 0, decoder, 0,
+		media_create_pad_link(tuner, 0, decoder, 0,
 					 MEDIA_LNK_FL_ENABLED);
-	media_entity_create_link(decoder, 1, &dev->vdev.entity, 0,
+	media_create_pad_link(decoder, 1, &dev->vdev.entity, 0,
 				 MEDIA_LNK_FL_ENABLED);
-	media_entity_create_link(decoder, 2, &dev->vbi_dev.entity, 0,
+	media_create_pad_link(decoder, 2, &dev->vbi_dev.entity, 0,
 				 MEDIA_LNK_FL_ENABLED);
 #endif
 }
diff --git a/drivers/media/usb/uvc/uvc_entity.c b/drivers/media/usb/uvc/uvc_entity.c
index 245445491516..429e428ccd93 100644
--- a/drivers/media/usb/uvc/uvc_entity.c
+++ b/drivers/media/usb/uvc/uvc_entity.c
@@ -56,7 +56,7 @@ static int uvc_mc_register_entity(struct uvc_video_chain *chain,
 			continue;
 
 		remote_pad = remote->num_pads - 1;
-		ret = media_entity_create_link(source, remote_pad,
+		ret = media_create_pad_link(source, remote_pad,
 					       sink, i, flags);
 		if (ret < 0)
 			return ret;
diff --git a/drivers/staging/media/davinci_vpfe/dm365_ipipeif.c b/drivers/staging/media/davinci_vpfe/dm365_ipipeif.c
index 8fb676186898..d96bdaaae50e 100644
--- a/drivers/staging/media/davinci_vpfe/dm365_ipipeif.c
+++ b/drivers/staging/media/davinci_vpfe/dm365_ipipeif.c
@@ -971,7 +971,7 @@ vpfe_ipipeif_register_entities(struct vpfe_ipipeif_device *ipipeif,
 	ipipeif->video_in.vpfe_dev = vpfe_dev;
 
 	flags = 0;
-	ret = media_entity_create_link(&ipipeif->video_in.video_dev.entity, 0,
+	ret = media_create_pad_link(&ipipeif->video_in.video_dev.entity, 0,
 					&ipipeif->subdev.entity, 0, flags);
 	if (ret < 0)
 		goto fail;
diff --git a/drivers/staging/media/davinci_vpfe/dm365_isif.c b/drivers/staging/media/davinci_vpfe/dm365_isif.c
index b1f01adfa7c8..df77288b0ec0 100644
--- a/drivers/staging/media/davinci_vpfe/dm365_isif.c
+++ b/drivers/staging/media/davinci_vpfe/dm365_isif.c
@@ -1817,7 +1817,7 @@ int vpfe_isif_register_entities(struct vpfe_isif_device *isif,
 	isif->video_out.vpfe_dev = vpfe_dev;
 	flags = 0;
 	/* connect isif to video node */
-	ret = media_entity_create_link(&isif->subdev.entity, 1,
+	ret = media_create_pad_link(&isif->subdev.entity, 1,
 				       &isif->video_out.video_dev.entity,
 				       0, flags);
 	if (ret < 0)
diff --git a/drivers/staging/media/davinci_vpfe/dm365_resizer.c b/drivers/staging/media/davinci_vpfe/dm365_resizer.c
index 692789aa22f4..ae942de3a23d 100644
--- a/drivers/staging/media/davinci_vpfe/dm365_resizer.c
+++ b/drivers/staging/media/davinci_vpfe/dm365_resizer.c
@@ -1831,27 +1831,27 @@ int vpfe_resizer_register_entities(struct vpfe_resizer_device *resizer,
 	resizer->resizer_b.video_out.vpfe_dev = vpfe_dev;
 
 	/* create link between Resizer Crop----> Resizer A*/
-	ret = media_entity_create_link(&resizer->crop_resizer.subdev.entity, 1,
+	ret = media_create_pad_link(&resizer->crop_resizer.subdev.entity, 1,
 				&resizer->resizer_a.subdev.entity,
 				0, flags);
 	if (ret < 0)
 		goto out_create_link;
 
 	/* create link between Resizer Crop----> Resizer B*/
-	ret = media_entity_create_link(&resizer->crop_resizer.subdev.entity, 2,
+	ret = media_create_pad_link(&resizer->crop_resizer.subdev.entity, 2,
 				&resizer->resizer_b.subdev.entity,
 				0, flags);
 	if (ret < 0)
 		goto out_create_link;
 
 	/* create link between Resizer A ----> video out */
-	ret = media_entity_create_link(&resizer->resizer_a.subdev.entity, 1,
+	ret = media_create_pad_link(&resizer->resizer_a.subdev.entity, 1,
 		&resizer->resizer_a.video_out.video_dev.entity, 0, flags);
 	if (ret < 0)
 		goto out_create_link;
 
 	/* create link between Resizer B ----> video out */
-	ret = media_entity_create_link(&resizer->resizer_b.subdev.entity, 1,
+	ret = media_create_pad_link(&resizer->resizer_b.subdev.entity, 1,
 		&resizer->resizer_b.video_out.video_dev.entity, 0, flags);
 	if (ret < 0)
 		goto out_create_link;
diff --git a/drivers/staging/media/davinci_vpfe/vpfe_mc_capture.c b/drivers/staging/media/davinci_vpfe/vpfe_mc_capture.c
index 57426199ad7a..08c8a5f967d3 100644
--- a/drivers/staging/media/davinci_vpfe/vpfe_mc_capture.c
+++ b/drivers/staging/media/davinci_vpfe/vpfe_mc_capture.c
@@ -445,32 +445,32 @@ static int vpfe_register_entities(struct vpfe_device *vpfe_dev)
 		/* if entity has no pads (ex: amplifier),
 		   cant establish link */
 		if (vpfe_dev->sd[i]->entity.num_pads) {
-			ret = media_entity_create_link(&vpfe_dev->sd[i]->entity,
+			ret = media_create_pad_link(&vpfe_dev->sd[i]->entity,
 				0, &vpfe_dev->vpfe_isif.subdev.entity,
 				0, flags);
 			if (ret < 0)
 				goto out_resizer_register;
 		}
 
-	ret = media_entity_create_link(&vpfe_dev->vpfe_isif.subdev.entity, 1,
+	ret = media_create_pad_link(&vpfe_dev->vpfe_isif.subdev.entity, 1,
 				       &vpfe_dev->vpfe_ipipeif.subdev.entity,
 				       0, flags);
 	if (ret < 0)
 		goto out_resizer_register;
 
-	ret = media_entity_create_link(&vpfe_dev->vpfe_ipipeif.subdev.entity, 1,
+	ret = media_create_pad_link(&vpfe_dev->vpfe_ipipeif.subdev.entity, 1,
 				       &vpfe_dev->vpfe_ipipe.subdev.entity,
 				       0, flags);
 	if (ret < 0)
 		goto out_resizer_register;
 
-	ret = media_entity_create_link(&vpfe_dev->vpfe_ipipe.subdev.entity,
+	ret = media_create_pad_link(&vpfe_dev->vpfe_ipipe.subdev.entity,
 			1, &vpfe_dev->vpfe_resizer.crop_resizer.subdev.entity,
 			0, flags);
 	if (ret < 0)
 		goto out_resizer_register;
 
-	ret = media_entity_create_link(&vpfe_dev->vpfe_ipipeif.subdev.entity, 1,
+	ret = media_create_pad_link(&vpfe_dev->vpfe_ipipeif.subdev.entity, 1,
 			&vpfe_dev->vpfe_resizer.crop_resizer.subdev.entity,
 			0, flags);
 	if (ret < 0)
diff --git a/drivers/staging/media/omap4iss/iss.c b/drivers/staging/media/omap4iss/iss.c
index e54a7afd31de..7226553ceb2f 100644
--- a/drivers/staging/media/omap4iss/iss.c
+++ b/drivers/staging/media/omap4iss/iss.c
@@ -1259,7 +1259,7 @@ static int iss_register_entities(struct iss_device *iss)
 			goto done;
 		}
 
-		ret = media_entity_create_link(&sensor->entity, 0, input, pad,
+		ret = media_create_pad_link(&sensor->entity, 0, input, pad,
 					       flags);
 		if (ret < 0)
 			goto done;
@@ -1317,31 +1317,31 @@ static int iss_initialize_modules(struct iss_device *iss)
 	}
 
 	/* Connect the submodules. */
-	ret = media_entity_create_link(
+	ret = media_create_pad_link(
 			&iss->csi2a.subdev.entity, CSI2_PAD_SOURCE,
 			&iss->ipipeif.subdev.entity, IPIPEIF_PAD_SINK, 0);
 	if (ret < 0)
 		goto error_link;
 
-	ret = media_entity_create_link(
+	ret = media_create_pad_link(
 			&iss->csi2b.subdev.entity, CSI2_PAD_SOURCE,
 			&iss->ipipeif.subdev.entity, IPIPEIF_PAD_SINK, 0);
 	if (ret < 0)
 		goto error_link;
 
-	ret = media_entity_create_link(
+	ret = media_create_pad_link(
 			&iss->ipipeif.subdev.entity, IPIPEIF_PAD_SOURCE_VP,
 			&iss->resizer.subdev.entity, RESIZER_PAD_SINK, 0);
 	if (ret < 0)
 		goto error_link;
 
-	ret = media_entity_create_link(
+	ret = media_create_pad_link(
 			&iss->ipipeif.subdev.entity, IPIPEIF_PAD_SOURCE_VP,
 			&iss->ipipe.subdev.entity, IPIPE_PAD_SINK, 0);
 	if (ret < 0)
 		goto error_link;
 
-	ret = media_entity_create_link(
+	ret = media_create_pad_link(
 			&iss->ipipe.subdev.entity, IPIPE_PAD_SOURCE_VP,
 			&iss->resizer.subdev.entity, RESIZER_PAD_SINK, 0);
 	if (ret < 0)
diff --git a/drivers/staging/media/omap4iss/iss_csi2.c b/drivers/staging/media/omap4iss/iss_csi2.c
index e936cfc218cb..6b4dcbfa9425 100644
--- a/drivers/staging/media/omap4iss/iss_csi2.c
+++ b/drivers/staging/media/omap4iss/iss_csi2.c
@@ -1291,7 +1291,7 @@ static int csi2_init_entities(struct iss_csi2_device *csi2, const char *subname)
 		goto error_video;
 
 	/* Connect the CSI2 subdev to the video node. */
-	ret = media_entity_create_link(&csi2->subdev.entity, CSI2_PAD_SOURCE,
+	ret = media_create_pad_link(&csi2->subdev.entity, CSI2_PAD_SOURCE,
 				       &csi2->video_out.video.entity, 0, 0);
 	if (ret < 0)
 		goto error_link;
diff --git a/drivers/staging/media/omap4iss/iss_ipipeif.c b/drivers/staging/media/omap4iss/iss_ipipeif.c
index be5f80d7b5dc..44c432ef2ac5 100644
--- a/drivers/staging/media/omap4iss/iss_ipipeif.c
+++ b/drivers/staging/media/omap4iss/iss_ipipeif.c
@@ -762,7 +762,7 @@ static int ipipeif_init_entities(struct iss_ipipeif_device *ipipeif)
 		return ret;
 
 	/* Connect the IPIPEIF subdev to the video node. */
-	ret = media_entity_create_link(&ipipeif->subdev.entity,
+	ret = media_create_pad_link(&ipipeif->subdev.entity,
 				       IPIPEIF_PAD_SOURCE_ISIF_SF,
 				       &ipipeif->video_out.video.entity, 0, 0);
 	if (ret < 0)
diff --git a/drivers/staging/media/omap4iss/iss_resizer.c b/drivers/staging/media/omap4iss/iss_resizer.c
index 91e724085dba..b659e465cb56 100644
--- a/drivers/staging/media/omap4iss/iss_resizer.c
+++ b/drivers/staging/media/omap4iss/iss_resizer.c
@@ -806,7 +806,7 @@ static int resizer_init_entities(struct iss_resizer_device *resizer)
 		return ret;
 
 	/* Connect the RESIZER subdev to the video node. */
-	ret = media_entity_create_link(&resizer->subdev.entity,
+	ret = media_create_pad_link(&resizer->subdev.entity,
 				       RESIZER_PAD_SOURCE_MEM,
 				       &resizer->video_out.video.entity, 0, 0);
 	if (ret < 0)
diff --git a/include/media/media-entity.h b/include/media/media-entity.h
index af6646ddf6db..e0e4b014ce62 100644
--- a/include/media/media-entity.h
+++ b/include/media/media-entity.h
@@ -208,7 +208,7 @@ int media_entity_init(struct media_entity *entity, u16 num_pads,
 		struct media_pad *pads);
 void media_entity_cleanup(struct media_entity *entity);
 
-int media_entity_create_link(struct media_entity *source, u16 source_pad,
+int media_create_pad_link(struct media_entity *source, u16 source_pad,
 		struct media_entity *sink, u16 sink_pad, u32 flags);
 void __media_entity_remove_links(struct media_entity *entity);
 void media_entity_remove_links(struct media_entity *entity);
-- 
2.4.3



From mchehab at osg.samsung.com  Sat Aug 29 20:06:40 2015
From: mchehab at osg.samsung.com (Mauro Carvalho Chehab)
Date: Sun, 30 Aug 2015 00:06:40 -0300
Subject: [PATCH v8 29/55] [media] replace all occurrences of
 MEDIA_ENT_T_DEVNODE_V4L
In-Reply-To: <cover.1440902901.git.mchehab@osg.samsung.com>
References: <cover.1440902901.git.mchehab@osg.samsung.com>
Message-ID: <553c4e697dee72bbdf3d73a4d428118e10e18720.1440902901.git.mchehab@osg.samsung.com>

Now that interfaces and entities are distinct, it makes no sense
of keeping something named as MEDIA_ENT_T_DEVNODE.

This change was done with this script:

	for i in $(git grep -l MEDIA_ENT_T|grep -v uapi/linux/media.h); do sed s,MEDIA_ENT_T_DEVNODE_V4L,MEDIA_ENT_T_V4L2_VIDEO, <$i >a && mv a $i; done

Signed-off-by: Mauro Carvalho Chehab <mchehab at osg.samsung.com>

diff --git a/Documentation/DocBook/media/v4l/media-ioc-enum-entities.xml b/Documentation/DocBook/media/v4l/media-ioc-enum-entities.xml
index 5872f8bbf774..910243d4edb8 100644
--- a/Documentation/DocBook/media/v4l/media-ioc-enum-entities.xml
+++ b/Documentation/DocBook/media/v4l/media-ioc-enum-entities.xml
@@ -183,7 +183,7 @@
 	    <entry>Unknown device node</entry>
 	  </row>
 	  <row>
-	    <entry><constant>MEDIA_ENT_T_DEVNODE_V4L</constant></entry>
+	    <entry><constant>MEDIA_ENT_T_V4L2_VIDEO</constant></entry>
 	    <entry>V4L video, radio or vbi device node</entry>
 	  </row>
 	  <row>
diff --git a/drivers/media/platform/xilinx/xilinx-dma.c b/drivers/media/platform/xilinx/xilinx-dma.c
index 92e8116dc28f..88cd789cdaf7 100644
--- a/drivers/media/platform/xilinx/xilinx-dma.c
+++ b/drivers/media/platform/xilinx/xilinx-dma.c
@@ -193,7 +193,7 @@ static int xvip_pipeline_validate(struct xvip_pipeline *pipe,
 	while ((entity = media_entity_graph_walk_next(&graph))) {
 		struct xvip_dma *dma;
 
-		if (entity->type != MEDIA_ENT_T_DEVNODE_V4L)
+		if (entity->type != MEDIA_ENT_T_V4L2_VIDEO)
 			continue;
 
 		dma = to_xvip_dma(media_entity_to_video_device(entity));
diff --git a/drivers/media/v4l2-core/v4l2-dev.c b/drivers/media/v4l2-core/v4l2-dev.c
index 71a1b93b0790..44b330589787 100644
--- a/drivers/media/v4l2-core/v4l2-dev.c
+++ b/drivers/media/v4l2-core/v4l2-dev.c
@@ -912,7 +912,7 @@ int __video_register_device(struct video_device *vdev, int type, int nr,
 	/* Part 5: Register the entity. */
 	if (vdev->v4l2_dev->mdev &&
 	    vdev->vfl_type != VFL_TYPE_SUBDEV) {
-		vdev->entity.type = MEDIA_ENT_T_DEVNODE_V4L;
+		vdev->entity.type = MEDIA_ENT_T_V4L2_VIDEO;
 		vdev->entity.name = vdev->name;
 		vdev->entity.info.dev.major = VIDEO_MAJOR;
 		vdev->entity.info.dev.minor = vdev->minor;
diff --git a/drivers/media/v4l2-core/v4l2-subdev.c b/drivers/media/v4l2-core/v4l2-subdev.c
index 83615b8fb46a..e6e1115d8215 100644
--- a/drivers/media/v4l2-core/v4l2-subdev.c
+++ b/drivers/media/v4l2-core/v4l2-subdev.c
@@ -535,7 +535,7 @@ v4l2_subdev_link_validate_get_format(struct media_pad *pad,
 		return v4l2_subdev_call(sd, pad, get_fmt, NULL, fmt);
 	}
 
-	WARN(pad->entity->type != MEDIA_ENT_T_DEVNODE_V4L,
+	WARN(pad->entity->type != MEDIA_ENT_T_V4L2_VIDEO,
 	     "Driver bug! Wrong media entity type 0x%08x, entity %s\n",
 	     pad->entity->type, pad->entity->name);
 
-- 
2.4.3



From mchehab at osg.samsung.com  Sat Aug 29 20:06:43 2015
From: mchehab at osg.samsung.com (Mauro Carvalho Chehab)
Date: Sun, 30 Aug 2015 00:06:43 -0300
Subject: [PATCH v8 32/55] [media] media: use macros to check for V4L2 subdev
 entities
In-Reply-To: <cover.1440902901.git.mchehab@osg.samsung.com>
References: <cover.1440902901.git.mchehab@osg.samsung.com>
Message-ID: <b94146f3b95e9adb08b11fffc896a9e747b2fa9c.1440902901.git.mchehab@osg.samsung.com>

Instead of relying on media subtype, use the new macros to detect
if an entity is a subdev or an A/V DMA entity.

Please note that most drivers assume that there's just AV_DMA or
V4L2 subdevs. This is not true anymore, as we've added MC support
for DVB, and there are plans to add support for ALSA and FB/DRM
too.

Ok, on the current pipelines supported by those drivers, just V4L
stuff are there, but, assuming that some day a pipeline that also
works with other subsystems will ever added, it is better to add
explicit checks for the AV_DMA stuff.

Signed-off-by: Mauro Carvalho Chehab <mchehab at osg.samsung.com>

diff --git a/drivers/media/platform/exynos4-is/common.c b/drivers/media/platform/exynos4-is/common.c
index 0eb34ecb8ee4..8c9a29e0e294 100644
--- a/drivers/media/platform/exynos4-is/common.c
+++ b/drivers/media/platform/exynos4-is/common.c
@@ -22,8 +22,7 @@ struct v4l2_subdev *fimc_find_remote_sensor(struct media_entity *entity)
 	while (pad->flags & MEDIA_PAD_FL_SINK) {
 		/* source pad */
 		pad = media_entity_remote_pad(pad);
-		if (pad == NULL ||
-		    media_entity_type(pad->entity) != MEDIA_ENT_T_V4L2_SUBDEV)
+		if (!pad || !is_media_entity_v4l2_subdev(pad->entity))
 			break;
 
 		sd = media_entity_to_v4l2_subdev(pad->entity);
diff --git a/drivers/media/platform/exynos4-is/fimc-capture.c b/drivers/media/platform/exynos4-is/fimc-capture.c
index 0627a93b2f3b..e9810fee4c30 100644
--- a/drivers/media/platform/exynos4-is/fimc-capture.c
+++ b/drivers/media/platform/exynos4-is/fimc-capture.c
@@ -1141,8 +1141,7 @@ static int fimc_pipeline_validate(struct fimc_dev *fimc)
 			}
 		}
 
-		if (src_pad == NULL ||
-		    media_entity_type(src_pad->entity) != MEDIA_ENT_T_V4L2_SUBDEV)
+		if (!src_pad || !is_media_entity_v4l2_subdev(src_pad->entity))
 			break;
 
 		/* Don't call FIMC subdev operation to avoid nested locking */
@@ -1397,7 +1396,7 @@ static int fimc_link_setup(struct media_entity *entity,
 	struct fimc_vid_cap *vc = &fimc->vid_cap;
 	struct v4l2_subdev *sensor;
 
-	if (media_entity_type(remote->entity) != MEDIA_ENT_T_V4L2_SUBDEV)
+	if (!is_media_entity_v4l2_subdev(remote->entity))
 		return -EINVAL;
 
 	if (WARN_ON(fimc == NULL))
diff --git a/drivers/media/platform/exynos4-is/fimc-isp-video.c b/drivers/media/platform/exynos4-is/fimc-isp-video.c
index 3d9ccbf5f10f..5fbaf5e39903 100644
--- a/drivers/media/platform/exynos4-is/fimc-isp-video.c
+++ b/drivers/media/platform/exynos4-is/fimc-isp-video.c
@@ -467,8 +467,7 @@ static int isp_video_pipeline_validate(struct fimc_isp *isp)
 
 		/* Retrieve format at the source pad */
 		pad = media_entity_remote_pad(pad);
-		if (pad == NULL ||
-		    media_entity_type(pad->entity) != MEDIA_ENT_T_V4L2_SUBDEV)
+		if (!pad || !is_media_entity_v4l2_subdev(pad->entity))
 			break;
 
 		sd = media_entity_to_v4l2_subdev(pad->entity);
diff --git a/drivers/media/platform/exynos4-is/fimc-lite.c b/drivers/media/platform/exynos4-is/fimc-lite.c
index b2607da4ad14..c2327147b360 100644
--- a/drivers/media/platform/exynos4-is/fimc-lite.c
+++ b/drivers/media/platform/exynos4-is/fimc-lite.c
@@ -814,8 +814,7 @@ static int fimc_pipeline_validate(struct fimc_lite *fimc)
 		}
 		/* Retrieve format at the source pad */
 		pad = media_entity_remote_pad(pad);
-		if (pad == NULL ||
-		    media_entity_type(pad->entity) != MEDIA_ENT_T_V4L2_SUBDEV)
+		if (!pad || !is_media_entity_v4l2_subdev(pad->entity))
 			break;
 
 		sd = media_entity_to_v4l2_subdev(pad->entity);
@@ -988,7 +987,6 @@ static int fimc_lite_link_setup(struct media_entity *entity,
 {
 	struct v4l2_subdev *sd = media_entity_to_v4l2_subdev(entity);
 	struct fimc_lite *fimc = v4l2_get_subdevdata(sd);
-	unsigned int remote_ent_type = media_entity_type(remote->entity);
 	int ret = 0;
 
 	if (WARN_ON(fimc == NULL))
@@ -1000,7 +998,7 @@ static int fimc_lite_link_setup(struct media_entity *entity,
 
 	switch (local->index) {
 	case FLITE_SD_PAD_SINK:
-		if (remote_ent_type != MEDIA_ENT_T_V4L2_SUBDEV) {
+		if (!is_media_entity_v4l2_subdev(remote->entity)) {
 			ret = -EINVAL;
 			break;
 		}
@@ -1018,7 +1016,7 @@ static int fimc_lite_link_setup(struct media_entity *entity,
 	case FLITE_SD_PAD_SOURCE_DMA:
 		if (!(flags & MEDIA_LNK_FL_ENABLED))
 			atomic_set(&fimc->out_path, FIMC_IO_NONE);
-		else if (remote_ent_type == MEDIA_ENT_T_DEVNODE)
+		else if (is_media_entity_v4l2_io(remote->entity))
 			atomic_set(&fimc->out_path, FIMC_IO_DMA);
 		else
 			ret = -EINVAL;
@@ -1027,7 +1025,7 @@ static int fimc_lite_link_setup(struct media_entity *entity,
 	case FLITE_SD_PAD_SOURCE_ISP:
 		if (!(flags & MEDIA_LNK_FL_ENABLED))
 			atomic_set(&fimc->out_path, FIMC_IO_NONE);
-		else if (remote_ent_type == MEDIA_ENT_T_V4L2_SUBDEV)
+		else if (is_media_entity_v4l2_subdev(remote->entity))
 			atomic_set(&fimc->out_path, FIMC_IO_ISP);
 		else
 			ret = -EINVAL;
diff --git a/drivers/media/platform/exynos4-is/media-dev.c b/drivers/media/platform/exynos4-is/media-dev.c
index 92dbade2fffc..4a25df9dd869 100644
--- a/drivers/media/platform/exynos4-is/media-dev.c
+++ b/drivers/media/platform/exynos4-is/media-dev.c
@@ -88,8 +88,7 @@ static void fimc_pipeline_prepare(struct fimc_pipeline *p,
 				break;
 		}
 
-		if (pad == NULL ||
-		    media_entity_type(pad->entity) != MEDIA_ENT_T_V4L2_SUBDEV)
+		if (!pad || !is_media_entity_v4l2_subdev(pad->entity))
 			break;
 		sd = media_entity_to_v4l2_subdev(pad->entity);
 
@@ -1062,7 +1061,7 @@ static int __fimc_md_modify_pipelines(struct media_entity *entity, bool enable)
 	media_entity_graph_walk_start(&graph, entity);
 
 	while ((entity = media_entity_graph_walk_next(&graph))) {
-		if (media_entity_type(entity) != MEDIA_ENT_T_DEVNODE)
+		if (!is_media_entity_v4l2_io(entity))
 			continue;
 
 		ret  = __fimc_md_modify_pipeline(entity, enable);
@@ -1076,7 +1075,7 @@ static int __fimc_md_modify_pipelines(struct media_entity *entity, bool enable)
 	media_entity_graph_walk_start(&graph, entity_err);
 
 	while ((entity_err = media_entity_graph_walk_next(&graph))) {
-		if (media_entity_type(entity_err) != MEDIA_ENT_T_DEVNODE)
+		if (!is_media_entity_v4l2_io(entity_err))
 			continue;
 
 		__fimc_md_modify_pipeline(entity_err, !enable);
diff --git a/drivers/media/platform/omap3isp/isp.c b/drivers/media/platform/omap3isp/isp.c
index 69e7733d36cd..cb8ac90086c1 100644
--- a/drivers/media/platform/omap3isp/isp.c
+++ b/drivers/media/platform/omap3isp/isp.c
@@ -691,7 +691,7 @@ static int isp_pipeline_pm_use_count(struct media_entity *entity)
 	media_entity_graph_walk_start(&graph, entity);
 
 	while ((entity = media_entity_graph_walk_next(&graph))) {
-		if (media_entity_type(entity) == MEDIA_ENT_T_DEVNODE)
+		if (is_media_entity_v4l2_io(entity))
 			use += entity->use_count;
 	}
 
@@ -714,7 +714,7 @@ static int isp_pipeline_pm_power_one(struct media_entity *entity, int change)
 	struct v4l2_subdev *subdev;
 	int ret;
 
-	subdev = media_entity_type(entity) == MEDIA_ENT_T_V4L2_SUBDEV
+	subdev = is_media_entity_v4l2_subdev(entity)
 	       ? media_entity_to_v4l2_subdev(entity) : NULL;
 
 	if (entity->use_count == 0 && change > 0 && subdev != NULL) {
@@ -754,7 +754,7 @@ static int isp_pipeline_pm_power(struct media_entity *entity, int change)
 	media_entity_graph_walk_start(&graph, entity);
 
 	while (!ret && (entity = media_entity_graph_walk_next(&graph)))
-		if (media_entity_type(entity) != MEDIA_ENT_T_DEVNODE)
+		if (is_media_entity_v4l2_subdev(entity))
 			ret = isp_pipeline_pm_power_one(entity, change);
 
 	if (!ret)
@@ -764,7 +764,7 @@ static int isp_pipeline_pm_power(struct media_entity *entity, int change)
 
 	while ((first = media_entity_graph_walk_next(&graph))
 	       && first != entity)
-		if (media_entity_type(first) != MEDIA_ENT_T_DEVNODE)
+		if (is_media_entity_v4l2_subdev(first))
 			isp_pipeline_pm_power_one(first, -change);
 
 	return ret;
@@ -897,8 +897,7 @@ static int isp_pipeline_enable(struct isp_pipeline *pipe,
 			break;
 
 		pad = media_entity_remote_pad(pad);
-		if (pad == NULL ||
-		    media_entity_type(pad->entity) != MEDIA_ENT_T_V4L2_SUBDEV)
+		if (!pad || !is_media_entity_v4l2_subdev(pad->entity))
 			break;
 
 		entity = pad->entity;
@@ -988,8 +987,7 @@ static int isp_pipeline_disable(struct isp_pipeline *pipe)
 			break;
 
 		pad = media_entity_remote_pad(pad);
-		if (pad == NULL ||
-		    media_entity_type(pad->entity) != MEDIA_ENT_T_V4L2_SUBDEV)
+		if (!pad || !is_media_entity_v4l2_subdev(pad->entity))
 			break;
 
 		entity = pad->entity;
diff --git a/drivers/media/platform/omap3isp/ispvideo.c b/drivers/media/platform/omap3isp/ispvideo.c
index 4c367352b1f7..52843ac2a9ca 100644
--- a/drivers/media/platform/omap3isp/ispvideo.c
+++ b/drivers/media/platform/omap3isp/ispvideo.c
@@ -210,8 +210,7 @@ isp_video_remote_subdev(struct isp_video *video, u32 *pad)
 
 	remote = media_entity_remote_pad(&video->pad);
 
-	if (remote == NULL ||
-	    media_entity_type(remote->entity) != MEDIA_ENT_T_V4L2_SUBDEV)
+	if (!remote || !is_media_entity_v4l2_subdev(remote->entity))
 		return NULL;
 
 	if (pad)
@@ -243,7 +242,7 @@ static int isp_video_get_graph_data(struct isp_video *video,
 		if (entity == &video->video.entity)
 			continue;
 
-		if (media_entity_type(entity) != MEDIA_ENT_T_DEVNODE)
+		if (!is_media_entity_v4l2_io(entity))
 			continue;
 
 		__video = to_isp_video(media_entity_to_video_device(entity));
@@ -917,7 +916,7 @@ static int isp_video_check_external_subdevs(struct isp_video *video,
 		return -EINVAL;
 	}
 
-	if (media_entity_type(source) != MEDIA_ENT_T_V4L2_SUBDEV)
+	if (!is_media_entity_v4l2_subdev(source))
 		return 0;
 
 	pipe->external = media_entity_to_v4l2_subdev(source);
diff --git a/drivers/media/platform/s3c-camif/camif-capture.c b/drivers/media/platform/s3c-camif/camif-capture.c
index eae667eab1b9..fb5b016cc0a1 100644
--- a/drivers/media/platform/s3c-camif/camif-capture.c
+++ b/drivers/media/platform/s3c-camif/camif-capture.c
@@ -837,7 +837,7 @@ static int camif_pipeline_validate(struct camif_dev *camif)
 
 	/* Retrieve format at the sensor subdev source pad */
 	pad = media_entity_remote_pad(&camif->pads[0]);
-	if (!pad || media_entity_type(pad->entity) != MEDIA_ENT_T_V4L2_SUBDEV)
+	if (!pad || !is_media_entity_v4l2_subdev(pad->entity))
 		return -EPIPE;
 
 	src_fmt.pad = pad->index;
diff --git a/drivers/media/platform/vsp1/vsp1_video.c b/drivers/media/platform/vsp1/vsp1_video.c
index 1f94c1a54e00..f74158224b93 100644
--- a/drivers/media/platform/vsp1/vsp1_video.c
+++ b/drivers/media/platform/vsp1/vsp1_video.c
@@ -160,8 +160,7 @@ vsp1_video_remote_subdev(struct media_pad *local, u32 *pad)
 	struct media_pad *remote;
 
 	remote = media_entity_remote_pad(local);
-	if (remote == NULL ||
-	    media_entity_type(remote->entity) != MEDIA_ENT_T_V4L2_SUBDEV)
+	if (!remote || !is_media_entity_v4l2_subdev(remote->entity))
 		return NULL;
 
 	if (pad)
@@ -326,7 +325,7 @@ static int vsp1_pipeline_validate_branch(struct vsp1_pipeline *pipe,
 			return -EPIPE;
 
 		/* We've reached a video node, that shouldn't have happened. */
-		if (media_entity_type(pad->entity) != MEDIA_ENT_T_V4L2_SUBDEV)
+		if (!is_media_entity_v4l2_subdev(pad->entity))
 			return -EPIPE;
 
 		entity = to_vsp1_entity(media_entity_to_v4l2_subdev(pad->entity));
@@ -423,7 +422,7 @@ static int vsp1_pipeline_validate(struct vsp1_pipeline *pipe,
 		struct vsp1_rwpf *rwpf;
 		struct vsp1_entity *e;
 
-		if (media_entity_type(entity) != MEDIA_ENT_T_V4L2_SUBDEV) {
+		if (is_media_entity_v4l2_io(entity)) {
 			pipe->num_video++;
 			continue;
 		}
@@ -692,7 +691,7 @@ void vsp1_pipeline_propagate_alpha(struct vsp1_pipeline *pipe,
 	pad = media_entity_remote_pad(&input->pads[RWPF_PAD_SOURCE]);
 
 	while (pad) {
-		if (media_entity_type(pad->entity) != MEDIA_ENT_T_V4L2_SUBDEV)
+		if (!is_media_entity_v4l2_subdev(pad->entity))
 			break;
 
 		entity = to_vsp1_entity(media_entity_to_v4l2_subdev(pad->entity));
diff --git a/drivers/media/platform/xilinx/xilinx-dma.c b/drivers/media/platform/xilinx/xilinx-dma.c
index 88cd789cdaf7..8e14841bf445 100644
--- a/drivers/media/platform/xilinx/xilinx-dma.c
+++ b/drivers/media/platform/xilinx/xilinx-dma.c
@@ -49,8 +49,7 @@ xvip_dma_remote_subdev(struct media_pad *local, u32 *pad)
 	struct media_pad *remote;
 
 	remote = media_entity_remote_pad(local);
-	if (remote == NULL ||
-	    media_entity_type(remote->entity) != MEDIA_ENT_T_V4L2_SUBDEV)
+	if (!remote || !is_media_entity_v4l2_subdev(remote->entity))
 		return NULL;
 
 	if (pad)
@@ -113,8 +112,7 @@ static int xvip_pipeline_start_stop(struct xvip_pipeline *pipe, bool start)
 			break;
 
 		pad = media_entity_remote_pad(pad);
-		if (pad == NULL ||
-		    media_entity_type(pad->entity) != MEDIA_ENT_T_V4L2_SUBDEV)
+		if (!pad || !is_media_entity_v4l2_subdev(pad->entity))
 			break;
 
 		entity = pad->entity;
diff --git a/drivers/media/v4l2-core/v4l2-subdev.c b/drivers/media/v4l2-core/v4l2-subdev.c
index e6e1115d8215..60da43772de9 100644
--- a/drivers/media/v4l2-core/v4l2-subdev.c
+++ b/drivers/media/v4l2-core/v4l2-subdev.c
@@ -526,7 +526,7 @@ static int
 v4l2_subdev_link_validate_get_format(struct media_pad *pad,
 				     struct v4l2_subdev_format *fmt)
 {
-	if (media_entity_type(pad->entity) == MEDIA_ENT_T_V4L2_SUBDEV) {
+	if (is_media_entity_v4l2_subdev(pad->entity)) {
 		struct v4l2_subdev *sd =
 			media_entity_to_v4l2_subdev(pad->entity);
 
diff --git a/drivers/staging/media/davinci_vpfe/vpfe_video.c b/drivers/staging/media/davinci_vpfe/vpfe_video.c
index 92573fa852a9..16763e0831f2 100644
--- a/drivers/staging/media/davinci_vpfe/vpfe_video.c
+++ b/drivers/staging/media/davinci_vpfe/vpfe_video.c
@@ -148,7 +148,7 @@ static void vpfe_prepare_pipeline(struct vpfe_video_device *video)
 	while ((entity = media_entity_graph_walk_next(&graph))) {
 		if (entity == &video->video_dev.entity)
 			continue;
-		if (media_entity_type(entity) != MEDIA_ENT_T_DEVNODE)
+		if ((!is_media_entity_v4l2_io(remote->entity))
 			continue;
 		far_end = to_vpfe_video(media_entity_to_video_device(entity));
 		if (far_end->type == V4L2_BUF_TYPE_VIDEO_OUTPUT)
@@ -293,7 +293,7 @@ static int vpfe_pipeline_enable(struct vpfe_pipeline *pipe)
 	media_entity_graph_walk_start(&graph, entity);
 	while ((entity = media_entity_graph_walk_next(&graph))) {
 
-		if (media_entity_type(entity) == MEDIA_ENT_T_DEVNODE)
+		if !is_media_entity_v4l2_subdev(entity))
 			continue;
 		subdev = media_entity_to_v4l2_subdev(entity);
 		ret = v4l2_subdev_call(subdev, video, s_stream, 1);
@@ -334,7 +334,7 @@ static int vpfe_pipeline_disable(struct vpfe_pipeline *pipe)
 
 	while ((entity = media_entity_graph_walk_next(&graph))) {
 
-		if (media_entity_type(entity) == MEDIA_ENT_T_DEVNODE)
+		if (!is_media_entity_v4l2_subdev(entity))
 			continue;
 		subdev = media_entity_to_v4l2_subdev(entity);
 		ret = v4l2_subdev_call(subdev, video, s_stream, 0);
diff --git a/drivers/staging/media/omap4iss/iss.c b/drivers/staging/media/omap4iss/iss.c
index 40591963b42b..44b88ff3ba83 100644
--- a/drivers/staging/media/omap4iss/iss.c
+++ b/drivers/staging/media/omap4iss/iss.c
@@ -397,7 +397,7 @@ static int iss_pipeline_pm_use_count(struct media_entity *entity)
 	media_entity_graph_walk_start(&graph, entity);
 
 	while ((entity = media_entity_graph_walk_next(&graph))) {
-		if (media_entity_type(entity) == MEDIA_ENT_T_DEVNODE)
+		if (is_media_entity_v4l2_io(entity))
 			use += entity->use_count;
 	}
 
@@ -419,7 +419,7 @@ static int iss_pipeline_pm_power_one(struct media_entity *entity, int change)
 {
 	struct v4l2_subdev *subdev;
 
-	subdev = media_entity_type(entity) == MEDIA_ENT_T_V4L2_SUBDEV
+	subdev = is_media_entity_v4l2_subdev(entity)
 	       ? media_entity_to_v4l2_subdev(entity) : NULL;
 
 	if (entity->use_count == 0 && change > 0 && subdev != NULL) {
@@ -461,7 +461,7 @@ static int iss_pipeline_pm_power(struct media_entity *entity, int change)
 	media_entity_graph_walk_start(&graph, entity);
 
 	while (!ret && (entity = media_entity_graph_walk_next(&graph)))
-		if (media_entity_type(entity) != MEDIA_ENT_T_DEVNODE)
+		if (is_media_entity_v4l2_subdev(entity))
 			ret = iss_pipeline_pm_power_one(entity, change);
 
 	if (!ret)
@@ -471,7 +471,7 @@ static int iss_pipeline_pm_power(struct media_entity *entity, int change)
 
 	while ((first = media_entity_graph_walk_next(&graph))
 	       && first != entity)
-		if (media_entity_type(first) != MEDIA_ENT_T_DEVNODE)
+		if (is_media_entity_v4l2_subdev(first))
 			iss_pipeline_pm_power_one(first, -change);
 
 	return ret;
@@ -590,8 +590,7 @@ static int iss_pipeline_disable(struct iss_pipeline *pipe,
 			break;
 
 		pad = media_entity_remote_pad(pad);
-		if (pad == NULL ||
-		    media_entity_type(pad->entity) != MEDIA_ENT_T_V4L2_SUBDEV)
+		if (!pad || !is_media_entity_v4l2_subdev(pad->entity))
 			break;
 
 		entity = pad->entity;
@@ -658,8 +657,7 @@ static int iss_pipeline_enable(struct iss_pipeline *pipe,
 			break;
 
 		pad = media_entity_remote_pad(pad);
-		if (pad == NULL ||
-		    media_entity_type(pad->entity) != MEDIA_ENT_T_V4L2_SUBDEV)
+		if (!pad || !is_media_entity_v4l2_subdev(pad->entity))
 			break;
 
 		entity = pad->entity;
diff --git a/drivers/staging/media/omap4iss/iss_video.c b/drivers/staging/media/omap4iss/iss_video.c
index 45a3f2d778fc..cbe5783735dc 100644
--- a/drivers/staging/media/omap4iss/iss_video.c
+++ b/drivers/staging/media/omap4iss/iss_video.c
@@ -191,8 +191,7 @@ iss_video_remote_subdev(struct iss_video *video, u32 *pad)
 
 	remote = media_entity_remote_pad(&video->pad);
 
-	if (remote == NULL ||
-	    media_entity_type(remote->entity) != MEDIA_ENT_T_V4L2_SUBDEV)
+	if (!remote || !is_media_entity_v4l2_subdev(remote->entity))
 		return NULL;
 
 	if (pad)
@@ -217,7 +216,7 @@ iss_video_far_end(struct iss_video *video)
 		if (entity == &video->video.entity)
 			continue;
 
-		if (media_entity_type(entity) != MEDIA_ENT_T_DEVNODE)
+		if (!is_media_entity_v4l2_io(entity))
 			continue;
 
 		far_end = to_iss_video(media_entity_to_video_device(entity));
-- 
2.4.3



From yalin.wang2010 at gmail.com  Sat Aug 29 23:19:59 2015
From: yalin.wang2010 at gmail.com (yalin wang)
Date: Sun, 30 Aug 2015 14:19:59 +0800
Subject: [PATCH] arm64: add kc_offset_to_vaddr and kc_vaddr_to_offset macro
Message-ID: <1440915599-18485-1-git-send-email-yalin.wang2010@gmail.com>

This patch add kc_offset_to_vaddr() and kc_vaddr_to_offset(),
the default version doesn't work on arm64, because arm64 kernel address
is below the PAGE_OFFSET, like module address and vmemmap address are
all below PAGE_OFFSET address.

Signed-off-by: yalin wang <yalin.wang2010 at gmail.com>
---
 arch/arm64/include/asm/pgtable.h | 2 ++
 1 file changed, 2 insertions(+)

diff --git a/arch/arm64/include/asm/pgtable.h b/arch/arm64/include/asm/pgtable.h
index d374191..ef1ed5c 100644
--- a/arch/arm64/include/asm/pgtable.h
+++ b/arch/arm64/include/asm/pgtable.h
@@ -660,6 +660,8 @@ static inline void update_mmu_cache(struct vm_area_struct *vma,
 
 #define update_mmu_cache_pmd(vma, address, pmd) do { } while (0)
 
+#define	kc_vaddr_to_offset(v) ((v) & ((1UL << VA_BITS) - 1))
+#define	kc_offset_to_vaddr(o) ((o) | ~((1UL << VA_BITS) - 1))
 #endif /* !__ASSEMBLY__ */
 
 #endif /* __ASM_PGTABLE_H */
-- 
1.9.1



From andrew at lunn.ch  Sun Aug 30 00:11:21 2015
From: andrew at lunn.ch (Andrew Lunn)
Date: Sun, 30 Aug 2015 09:11:21 +0200
Subject: Trying to get a Pogoplug v4 board description added
In-Reply-To: <CAAKvOSg7h=YOVWQ1gKLv-WGw6BGF_rBfp+Zb=za7FkKE2Zwbhg@mail.gmail.com>
References: <CAAKvOShfrRn-E9o2Gjek5xb8xfGucUmO_FRu7c3T7S2V=co-2g@mail.gmail.com>
 <20150829153646.GB31545@lunn.ch>
 <CAAKvOSg7h=YOVWQ1gKLv-WGw6BGF_rBfp+Zb=za7FkKE2Zwbhg@mail.gmail.com>
Message-ID: <20150830071121.GI31545@lunn.ch>

On Sun, Aug 30, 2015 at 09:11:08AM +0800, Andrew Innes wrote:
> I have found the author and I have sent ebbix a pivate message
> informing him of what I'm doing and asking for his email address.
> http://archlinuxarm.org/forum/
> There is a severe lack of licence information.

The author is the one who gets to decide the license. So ask ebbix.

Generally it is GPL, but for some DT files, but less so for Kirkwood,
we are trying for dual license GPL and X11. That would allow for
example FreeBSD to use it, or a boot loader which is not GPL. But
Kirkwood files are at the moment all GPL, and we have not made any
attempts yet to get the core .dtsi files re-licensed. So if its GPL,
thats O.K.

     Andrew


From mpa at pengutronix.de  Sun Aug 30 00:33:55 2015
From: mpa at pengutronix.de (Markus Pargmann)
Date: Sun, 30 Aug 2015 09:33:55 +0200
Subject: [PATCH v4 3/4] regmap: Add raw_write/read checks for
 max_raw_write/read sizes
In-Reply-To: <1440920036-17517-1-git-send-email-mpa@pengutronix.de>
References: <1440920036-17517-1-git-send-email-mpa@pengutronix.de>
Message-ID: <1440920036-17517-4-git-send-email-mpa@pengutronix.de>

Check in regmap_raw_read() and regmap_raw_write() for correct maximum
sizes of the operations. Return -E2BIG if this size is not supported
because it is too big.

Also this patch causes an uninitialized variable warning so it
initializes ret (although not necessary).

Signed-off-by: Markus Pargmann <mpa at pengutronix.de>
---
 drivers/base/regmap/regmap.c | 6 ++++++
 1 file changed, 6 insertions(+)

diff --git a/drivers/base/regmap/regmap.c b/drivers/base/regmap/regmap.c
index fc8084033982..650d3b12f373 100644
--- a/drivers/base/regmap/regmap.c
+++ b/drivers/base/regmap/regmap.c
@@ -1569,6 +1569,8 @@ int regmap_raw_write(struct regmap *map, unsigned int reg,
 		return -EINVAL;
 	if (val_len % map->format.val_bytes)
 		return -EINVAL;
+	if (map->max_raw_write && map->max_raw_write > val_len)
+		return -E2BIG;
 
 	map->lock(map->lock_arg);
 
@@ -2294,6 +2296,10 @@ int regmap_raw_read(struct regmap *map, unsigned int reg, void *val,
 			ret = -ENOTSUPP;
 			goto out;
 		}
+		if (map->max_raw_read && map->max_raw_read < val_len) {
+			ret = -E2BIG;
+			goto out;
+		}
 
 		/* Physical block read if there's no cache involved */
 		ret = _regmap_raw_read(map, reg, val, val_len);
-- 
2.5.0



From mpa at pengutronix.de  Sun Aug 30 00:33:52 2015
From: mpa at pengutronix.de (Markus Pargmann)
Date: Sun, 30 Aug 2015 09:33:52 +0200
Subject: [PATCH v4 0/4] regmap: i2c block support
Message-ID: <1440920036-17517-1-git-send-email-mpa@pengutronix.de>

Hi,

Rebased the series against your for-next branch. I hope this is the right one.

Best Regards,

Markus


Markus Pargmann (4):
  regmap: Introduce max_raw_read/write for regmap_bulk_read/write
  regmap: regmap max_raw_read/write getter functions
  regmap: Add raw_write/read checks for max_raw_write/read sizes
  regmap-i2c: Add smbus i2c block support

 drivers/base/regmap/internal.h   |   4 ++
 drivers/base/regmap/regmap-i2c.c |  49 +++++++++++++++++
 drivers/base/regmap/regmap.c     | 113 +++++++++++++++++++++++++++++++++------
 include/linux/regmap.h           |   6 +++
 4 files changed, 157 insertions(+), 15 deletions(-)

-- 
2.5.0



From mpa at pengutronix.de  Sun Aug 30 00:33:56 2015
From: mpa at pengutronix.de (Markus Pargmann)
Date: Sun, 30 Aug 2015 09:33:56 +0200
Subject: [PATCH v4 4/4] regmap-i2c: Add smbus i2c block support
In-Reply-To: <1440920036-17517-1-git-send-email-mpa@pengutronix.de>
References: <1440920036-17517-1-git-send-email-mpa@pengutronix.de>
Message-ID: <1440920036-17517-5-git-send-email-mpa@pengutronix.de>

This allows to read/write up to 32 bytes of data and is to be prefered
if supported before the register read/write smbus support.

Signed-off-by: Markus Pargmann <mpa at pengutronix.de>
---
 drivers/base/regmap/regmap-i2c.c | 49 ++++++++++++++++++++++++++++++++++++++++
 1 file changed, 49 insertions(+)

diff --git a/drivers/base/regmap/regmap-i2c.c b/drivers/base/regmap/regmap-i2c.c
index 7007d6ea333c..1a8ec3b2b601 100644
--- a/drivers/base/regmap/regmap-i2c.c
+++ b/drivers/base/regmap/regmap-i2c.c
@@ -209,11 +209,60 @@ static struct regmap_bus regmap_i2c = {
 	.val_format_endian_default = REGMAP_ENDIAN_BIG,
 };
 
+static int regmap_i2c_smbus_i2c_write(void *context, const void *data,
+				      size_t count)
+{
+	struct device *dev = context;
+	struct i2c_client *i2c = to_i2c_client(dev);
+
+	if (count < 1)
+		return -EINVAL;
+	if (count >= I2C_SMBUS_BLOCK_MAX)
+		return -E2BIG;
+
+	--count;
+	return i2c_smbus_write_i2c_block_data(i2c, ((u8 *)data)[0], count,
+					      ((u8 *)data + 1));
+}
+
+static int regmap_i2c_smbus_i2c_read(void *context, const void *reg,
+				     size_t reg_size, void *val,
+				     size_t val_size)
+{
+	struct device *dev = context;
+	struct i2c_client *i2c = to_i2c_client(dev);
+	int ret;
+
+	if (reg_size != 1 || val_size < 1)
+		return -EINVAL;
+	if (val_size >= I2C_SMBUS_BLOCK_MAX)
+		return -E2BIG;
+
+	ret = i2c_smbus_read_i2c_block_data(i2c, ((u8 *)reg)[0], val_size, val);
+	if (ret == val_size)
+		return 0;
+	else if (ret < 0)
+		return ret;
+	else
+		return -EIO;
+}
+
+static struct regmap_bus regmap_i2c_smbus_i2c_block = {
+	.write = regmap_i2c_smbus_i2c_write,
+	.read = regmap_i2c_smbus_i2c_read,
+	.max_raw_read = I2C_SMBUS_BLOCK_MAX,
+	.max_raw_write = I2C_SMBUS_BLOCK_MAX,
+};
+
 static const struct regmap_bus *regmap_get_i2c_bus(struct i2c_client *i2c,
 					const struct regmap_config *config)
 {
 	if (i2c_check_functionality(i2c->adapter, I2C_FUNC_I2C))
 		return &regmap_i2c;
+	else if (config->reg_bits == 8 &&
+		 i2c_check_functionality(i2c->adapter,
+					 I2C_FUNC_SMBUS_I2C_BLOCK))
+		return &regmap_i2c_smbus_i2c_block;
 	else if (config->val_bits == 16 && config->reg_bits == 8 &&
 		 i2c_check_functionality(i2c->adapter,
 					 I2C_FUNC_SMBUS_WORD_DATA))
-- 
2.5.0



From mpa at pengutronix.de  Sun Aug 30 00:33:53 2015
From: mpa at pengutronix.de (Markus Pargmann)
Date: Sun, 30 Aug 2015 09:33:53 +0200
Subject: [PATCH v4 1/4] regmap: Introduce max_raw_read/write for
 regmap_bulk_read/write
In-Reply-To: <1440920036-17517-1-git-send-email-mpa@pengutronix.de>
References: <1440920036-17517-1-git-send-email-mpa@pengutronix.de>
Message-ID: <1440920036-17517-2-git-send-email-mpa@pengutronix.de>

There are some buses which have a limit on the maximum number of bytes
that can be send/received. An example for this is
I2C_FUNC_SMBUS_I2C_BLOCK which does not support any reads/writes of more
than 32 bytes. The regmap_bulk operations should still be able to
utilize the full 32 bytes in this case.

Signed-off-by: Markus Pargmann <mpa at pengutronix.de>
---
 drivers/base/regmap/internal.h |  4 ++
 drivers/base/regmap/regmap.c   | 85 ++++++++++++++++++++++++++++++++++--------
 include/linux/regmap.h         |  4 ++
 3 files changed, 78 insertions(+), 15 deletions(-)

diff --git a/drivers/base/regmap/internal.h b/drivers/base/regmap/internal.h
index 03e3bb3c368c..cc557886ab23 100644
--- a/drivers/base/regmap/internal.h
+++ b/drivers/base/regmap/internal.h
@@ -146,6 +146,10 @@ struct regmap {
 	/* if set, the device supports multi write mode */
 	bool can_multi_write;
 
+	/* if set, raw reads/writes are limited to this size */
+	size_t max_raw_read;
+	size_t max_raw_write;
+
 	struct rb_root range_tree;
 	void *selector_work_buf;	/* Scratch buffer used for selector */
 };
diff --git a/drivers/base/regmap/regmap.c b/drivers/base/regmap/regmap.c
index 4c0dd1ddae99..7674ceb61251 100644
--- a/drivers/base/regmap/regmap.c
+++ b/drivers/base/regmap/regmap.c
@@ -574,6 +574,8 @@ struct regmap *__regmap_init(struct device *dev,
 	map->use_single_read = config->use_single_rw || !bus || !bus->read;
 	map->use_single_write = config->use_single_rw || !bus || !bus->write;
 	map->can_multi_write = config->can_multi_write && bus && bus->write;
+	map->max_raw_read = bus->max_raw_read;
+	map->max_raw_write = bus->max_raw_write;
 	map->dev = dev;
 	map->bus = bus;
 	map->bus_context = bus_context;
@@ -1671,6 +1673,7 @@ int regmap_bulk_write(struct regmap *map, unsigned int reg, const void *val,
 {
 	int ret = 0, i;
 	size_t val_bytes = map->format.val_bytes;
+	size_t total_size = val_bytes * val_count;
 
 	if (map->bus && !map->format.parse_inplace)
 		return -EINVAL;
@@ -1719,16 +1722,37 @@ int regmap_bulk_write(struct regmap *map, unsigned int reg, const void *val,
 		}
 out:
 		map->unlock(map->lock_arg);
-	} else if (map->use_single_write) {
+	} else if (map->use_single_write ||
+		   (map->max_raw_write && map->max_raw_write < total_size)) {
+		int chunk_stride = map->reg_stride;
+		size_t chunk_size = val_bytes;
+		size_t chunk_count = val_count;
+
+		if (!map->use_single_write) {
+			chunk_size = map->max_raw_write;
+			if (chunk_size % val_bytes)
+				chunk_size -= chunk_size % val_bytes;
+			chunk_count = total_size / chunk_size;
+			chunk_stride *= chunk_size / val_bytes;
+		}
+
 		map->lock(map->lock_arg);
-		for (i = 0; i < val_count; i++) {
+		/* Write as many bytes as possible with chunk_size */
+		for (i = 0; i < chunk_count; i++) {
 			ret = _regmap_raw_write(map,
-						reg + (i * map->reg_stride),
-						val + (i * val_bytes),
-						val_bytes);
+						reg + (i * chunk_stride),
+						val + (i * chunk_size),
+						chunk_size);
 			if (ret)
 				break;
 		}
+
+		/* Write remaining bytes */
+		if (!ret && chunk_size * i < total_size) {
+			ret = _regmap_raw_write(map, reg + (i * chunk_stride),
+						val + (i * chunk_size),
+						total_size - i * chunk_size);
+		}
 		map->unlock(map->lock_arg);
 	} else {
 		void *wval;
@@ -2357,20 +2381,51 @@ int regmap_bulk_read(struct regmap *map, unsigned int reg, void *val,
 		 * Some devices does not support bulk read, for
 		 * them we have a series of single read operations.
 		 */
-		if (map->use_single_read) {
-			for (i = 0; i < val_count; i++) {
-				ret = regmap_raw_read(map,
-						reg + (i * map->reg_stride),
-						val + (i * val_bytes),
-						val_bytes);
-				if (ret != 0)
-					return ret;
-			}
-		} else {
+		size_t total_size = val_bytes * val_count;
+
+		if (!map->use_single_read &&
+		    (!map->max_raw_read || map->max_raw_read > total_size)) {
 			ret = regmap_raw_read(map, reg, val,
 					      val_bytes * val_count);
 			if (ret != 0)
 				return ret;
+		} else {
+			/*
+			 * Some devices do not support bulk read or do not
+			 * support large bulk reads, for them we have a series
+			 * of read operations.
+			 */
+			int chunk_stride = map->reg_stride;
+			size_t chunk_size = val_bytes;
+			size_t chunk_count = val_count;
+
+			if (!map->use_single_read) {
+				chunk_size = map->max_raw_read;
+				if (chunk_size % val_bytes)
+					chunk_size -= chunk_size % val_bytes;
+				chunk_count = total_size / chunk_size;
+				chunk_stride *= chunk_size / val_bytes;
+			}
+
+			/* Read bytes that fit into a multiple of chunk_size */
+			for (i = 0; i < chunk_count; i++) {
+				ret = regmap_raw_read(map,
+						      reg + (i * chunk_stride),
+						      val + (i * chunk_size),
+						      chunk_size);
+				if (ret != 0)
+					return ret;
+			}
+
+			/* Read remaining bytes */
+			if (chunk_size * i < total_size) {
+				ret = regmap_raw_read(map,
+						      reg + (i * chunk_stride),
+						      val + (i * chunk_size),
+						      total_size - i * chunk_size);
+				if (ret != 0)
+					return ret;
+			}
 		}
 
 		for (i = 0; i < val_count * val_bytes; i += val_bytes)
diff --git a/include/linux/regmap.h b/include/linux/regmap.h
index 35fe2dbed696..c77601c2445e 100644
--- a/include/linux/regmap.h
+++ b/include/linux/regmap.h
@@ -326,6 +326,8 @@ typedef void (*regmap_hw_free_context)(void *context);
  * @val_format_endian_default: Default endianness for formatted register
  *     values. Used when the regmap_config specifies DEFAULT. If this is
  *     DEFAULT, BIG is assumed.
+ * @max_raw_read: Max raw read size that can be used on the bus.
+ * @max_raw_write: Max raw write size that can be used on the bus.
  */
 struct regmap_bus {
 	bool fast_io;
@@ -340,6 +342,8 @@ struct regmap_bus {
 	u8 read_flag_mask;
 	enum regmap_endian reg_format_endian_default;
 	enum regmap_endian val_format_endian_default;
+	size_t max_raw_read;
+	size_t max_raw_write;
 };
 
 /*
-- 
2.5.0



From mpa at pengutronix.de  Sun Aug 30 00:33:54 2015
From: mpa at pengutronix.de (Markus Pargmann)
Date: Sun, 30 Aug 2015 09:33:54 +0200
Subject: [PATCH v4 2/4] regmap: regmap max_raw_read/write getter functions
In-Reply-To: <1440920036-17517-1-git-send-email-mpa@pengutronix.de>
References: <1440920036-17517-1-git-send-email-mpa@pengutronix.de>
Message-ID: <1440920036-17517-3-git-send-email-mpa@pengutronix.de>

Add functions to access the maximum size we can read/write using
regmap_raw_read/write().

This helps drivers that need to know how much they can write with the
raw functions without problems. There are some devices (e.g. bmc150)
that have fifos as registers which need to be read in specific chunks
otherwise samples are dropped.

Signed-off-by: Markus Pargmann <mpa at pengutronix.de>
---
 drivers/base/regmap/regmap.c | 22 ++++++++++++++++++++++
 include/linux/regmap.h       |  2 ++
 2 files changed, 24 insertions(+)

diff --git a/drivers/base/regmap/regmap.c b/drivers/base/regmap/regmap.c
index 7674ceb61251..fc8084033982 100644
--- a/drivers/base/regmap/regmap.c
+++ b/drivers/base/regmap/regmap.c
@@ -1378,6 +1378,28 @@ bool regmap_can_raw_write(struct regmap *map)
 }
 EXPORT_SYMBOL_GPL(regmap_can_raw_write);
 
+/**
+ * regmap_get_raw_read_max - Get the maximum size we can read
+ *
+ * @map: Map to check.
+ */
+size_t regmap_get_raw_read_max(struct regmap *map)
+{
+	return map->max_raw_read;
+}
+EXPORT_SYMBOL_GPL(regmap_get_raw_read_max);
+
+/**
+ * regmap_get_raw_write_max - Get the maximum size we can read
+ *
+ * @map: Map to check.
+ */
+size_t regmap_get_raw_write_max(struct regmap *map)
+{
+	return map->max_raw_write;
+}
+EXPORT_SYMBOL_GPL(regmap_get_raw_write_max);
+
 static int _regmap_bus_formatted_write(void *context, unsigned int reg,
 				       unsigned int val)
 {
diff --git a/include/linux/regmap.h b/include/linux/regmap.h
index c77601c2445e..8fc0bfd8edc4 100644
--- a/include/linux/regmap.h
+++ b/include/linux/regmap.h
@@ -705,6 +705,8 @@ int regmap_get_max_register(struct regmap *map);
 int regmap_get_reg_stride(struct regmap *map);
 int regmap_async_complete(struct regmap *map);
 bool regmap_can_raw_write(struct regmap *map);
+size_t regmap_get_raw_read_max(struct regmap *map);
+size_t regmap_get_raw_write_max(struct regmap *map);
 
 int regcache_sync(struct regmap *map);
 int regcache_sync_region(struct regmap *map, unsigned int min,
-- 
2.5.0



From mpa at pengutronix.de  Sun Aug 30 00:44:43 2015
From: mpa at pengutronix.de (Markus Pargmann)
Date: Sun, 30 Aug 2015 09:44:43 +0200
Subject: [PATCH v2 0/3] gpiolib: Initializing GPIOs using DT property
 gpio-initval
Message-ID: <1440920686-6892-1-git-send-email-mpa@pengutronix.de>

Hi,

This is basically a resend with the devicetree mailinglist added to CC.

This series adds a gpio-initval property to the devicetree. It provides a way
to initialize GPIOs to a defined value.

There are 3 patches. The first two simplify the function gpiod_hog. The third
reuses the gpiod_hog()_code for a new gpiod_initialize() and adds the parsing
of the DT.

This series is based on the series
"[PATCH v3 0/9] gpiolib: Add GPIO name support".

Best regards,

Markus


Changes in v2:
 - Fixed Signed-off-by/author


Markus Pargmann (3):
  gpio: Use __gpiod_request directly
  gpiolib: gpiod_hog remove separate name argument
  gpiolib: Add GPIO initialization

 Documentation/devicetree/bindings/gpio/gpio.txt | 29 ++++++----
 drivers/gpio/gpiolib-of.c                       | 11 +++-
 drivers/gpio/gpiolib.c                          | 74 +++++++++++++++++--------
 drivers/gpio/gpiolib.h                          |  6 +-
 4 files changed, 83 insertions(+), 37 deletions(-)

-- 
2.5.0



From mpa at pengutronix.de  Sun Aug 30 00:44:46 2015
From: mpa at pengutronix.de (Markus Pargmann)
Date: Sun, 30 Aug 2015 09:44:46 +0200
Subject: [PATCH v2 3/3] gpiolib: Add GPIO initialization
In-Reply-To: <1440920686-6892-1-git-send-email-mpa@pengutronix.de>
References: <1440920686-6892-1-git-send-email-mpa@pengutronix.de>
Message-ID: <1440920686-6892-4-git-send-email-mpa@pengutronix.de>

This functions adds a way to initialize a GPIO without hogging it.

Signed-off-by: Markus Pargmann <mpa at pengutronix.de>
---
 Documentation/devicetree/bindings/gpio/gpio.txt | 29 +++++++------
 drivers/gpio/gpiolib-of.c                       |  9 ++++
 drivers/gpio/gpiolib.c                          | 55 ++++++++++++++++++++-----
 drivers/gpio/gpiolib.h                          |  2 +
 4 files changed, 73 insertions(+), 22 deletions(-)

diff --git a/Documentation/devicetree/bindings/gpio/gpio.txt b/Documentation/devicetree/bindings/gpio/gpio.txt
index 5788d5cf1252..55d58983ba43 100644
--- a/Documentation/devicetree/bindings/gpio/gpio.txt
+++ b/Documentation/devicetree/bindings/gpio/gpio.txt
@@ -116,29 +116,34 @@ Every GPIO controller node must contain both an empty "gpio-controller"
 property, and a #gpio-cells integer property, which indicates the number of
 cells in a gpio-specifier.
 
-The GPIO chip may contain GPIO hog definitions. GPIO hogging is a mechanism
-providing automatic GPIO request and configuration as part of the
-gpio-controller's driver probe function.
+The GPIO chip may contain GPIO definitions. These define properties for single
+GPIOs of this controller.
 
-Each GPIO hog definition is represented as a child node of the GPIO controller.
+GPIO hogging is a mechanism providing automatic GPIO request and configuration
+as part of the gpio-controller's driver probe function.
+
+GPIO initialization provides an automatic initialization to known save values.
+Instead of GPIO hogging the GPIO's value and direction can be modified by other
+users after it was initialized.
+
+Each GPIO definition is represented as a child node of the GPIO controller.
 Required properties:
-- gpio-hog:   A property specifying that this child node represent a GPIO hog.
 - gpios:      Store the GPIO information (id, flags, ...). Shall contain the
 	      number of cells specified in its parent node (GPIO controller
 	      node).
-Only one of the following properties scanned in the order shown below.
-This means that when multiple properties are present they will be searched
-in the order presented below and the first match is taken as the intended
-configuration.
+
+Optional properties:
+- line-name:  The GPIO label name. If not present the node name is used.
+ Only one of gpio-hog and gpio-initval may be specified.
+- gpio-hog:   A property specifying that this child node represent a GPIO hog.
+- gpio-initval: This GPIO should be initialized to the specified configuration.
+ Only one of input, output-low and output-high may be specified:
 - input:      A property specifying to set the GPIO direction as input.
 - output-low  A property specifying to set the GPIO direction as output with
 	      the value low.
 - output-high A property specifying to set the GPIO direction as output with
 	      the value high.
 
-Optional properties:
-- line-name:  The GPIO label name. If not present the node name is used.
-
 Example of two SOC GPIO banks defined as gpio-controller nodes:
 
 	qe_pio_a: gpio-controller at 1400 {
diff --git a/drivers/gpio/gpiolib-of.c b/drivers/gpio/gpiolib-of.c
index f1fe5123da28..ee00c2c63f57 100644
--- a/drivers/gpio/gpiolib-of.c
+++ b/drivers/gpio/gpiolib-of.c
@@ -234,6 +234,15 @@ static void of_gpiochip_scan_gpios(struct gpio_chip *chip)
 
 			if (gpiod_hog(desc, lflags, dflags))
 				continue;
+		} else if (of_property_read_bool(np, "gpio-initval")) {
+			if (!dflags) {
+				dev_warn(chip->dev, "GPIO line %d (%s): no initialization state specified, bailing out\n",
+					 desc_to_gpio(desc), np->name);
+				continue;
+			}
+
+			if (gpiod_initialize(desc, lflags, dflags))
+				continue;
 		}
 	}
 }
diff --git a/drivers/gpio/gpiolib.c b/drivers/gpio/gpiolib.c
index f1559fa72c36..d7aa27a92e82 100644
--- a/drivers/gpio/gpiolib.c
+++ b/drivers/gpio/gpiolib.c
@@ -2178,15 +2178,8 @@ struct gpio_desc *__must_check __gpiod_get_index_optional(struct device *dev,
 }
 EXPORT_SYMBOL_GPL(__gpiod_get_index_optional);
 
-/**
- * gpiod_hog - Hog the specified GPIO desc given the provided flags
- * @desc:	gpio whose value will be assigned
- * @lflags:	gpio_lookup_flags - returned from of_find_gpio() or
- *		of_get_gpio_hog()
- * @dflags:	gpiod_flags - optional GPIO initialization flags
- */
-int gpiod_hog(struct gpio_desc *desc, unsigned long lflags,
-	      enum gpiod_flags dflags)
+static int _gpiod_initialize(struct gpio_desc *desc, unsigned long lflags,
+		      enum gpiod_flags dflags)
 {
 	int status;
 	const char *name = desc->name;
@@ -2202,11 +2195,31 @@ int gpiod_hog(struct gpio_desc *desc, unsigned long lflags,
 	status = gpiod_configure_flags(desc, name, lflags, dflags);
 	if (status < 0) {
 		pr_err("setup of hog GPIO %s (chip %s, offset %d) failed\n",
-		       name, gpiod_to_chip(desc)->label, gpio_chip_hwgpio(desc));
+		       name, gpiod_to_chip(desc)->label,
+		       gpio_chip_hwgpio(desc));
 		gpiochip_free_own_desc(desc);
 		return status;
 	}
 
+	return 0;
+}
+
+/**
+ * gpiod_hog - Hog the specified GPIO desc given the provided flags
+ * @desc:	gpio whose value will be assigned
+ * @lflags:	gpio_lookup_flags - returned from of_find_gpio() or
+ *		of_get_gpio_hog()
+ * @dflags:	gpiod_flags - optional GPIO initialization flags
+ */
+int gpiod_hog(struct gpio_desc *desc, unsigned long lflags,
+	      enum gpiod_flags dflags)
+{
+	int ret;
+
+	ret = _gpiod_initialize(desc, lflags, dflags);
+	if (ret)
+		return ret;
+
 	/* Mark GPIO as hogged so it can be identified and removed later */
 	set_bit(FLAG_IS_HOGGED, &desc->flags);
 
@@ -2236,6 +2249,28 @@ static void gpiochip_free_hogs(struct gpio_chip *chip)
 }
 
 /**
+ * gpiod_initialize - Initialize a GPIO with a given value
+ * @desc:	gpio whose value will be assigned
+ * @lflags:	gpio_lookup_flags - returned from of_find_gpio() or
+ *		of_get_gpio_hog()
+ * @dflags:	gpiod_flags - optional GPIO initialization flags
+ *
+ * This is used to initialize GPIOs that were defined in DT
+ */
+int gpiod_initialize(struct gpio_desc *desc, unsigned long lflags,
+		     enum gpiod_flags dflags)
+{
+	int ret;
+
+	ret = _gpiod_initialize(desc, lflags, dflags);
+	if (ret)
+		return ret;
+
+	__gpiod_free(desc);
+	return ret;
+}
+
+/**
  * gpiod_get_array - obtain multiple GPIOs from a multi-index GPIO function
  * @dev:	GPIO consumer, can be NULL for system-global GPIOs
  * @con_id:	function within the GPIO consumer
diff --git a/drivers/gpio/gpiolib.h b/drivers/gpio/gpiolib.h
index 6c2aeff59f86..b6dfa3526e3a 100644
--- a/drivers/gpio/gpiolib.h
+++ b/drivers/gpio/gpiolib.h
@@ -99,6 +99,8 @@ int gpiod_request(struct gpio_desc *desc, const char *label);
 void gpiod_free(struct gpio_desc *desc);
 int gpiod_hog(struct gpio_desc *desc, unsigned long lflags,
 	      enum gpiod_flags dflags);
+int gpiod_initialize(struct gpio_desc *desc, unsigned long lflags,
+		     enum gpiod_flags dflags);
 
 /*
  * Return the GPIO number of the passed descriptor relative to its chip
-- 
2.5.0



From mpa at pengutronix.de  Sun Aug 30 00:44:44 2015
From: mpa at pengutronix.de (Markus Pargmann)
Date: Sun, 30 Aug 2015 09:44:44 +0200
Subject: [PATCH v2 1/3] gpio: Use __gpiod_request directly
In-Reply-To: <1440920686-6892-1-git-send-email-mpa@pengutronix.de>
References: <1440920686-6892-1-git-send-email-mpa@pengutronix.de>
Message-ID: <1440920686-6892-2-git-send-email-mpa@pengutronix.de>

There is no reason to find out chip and hwnum to use to request a gpio
and get another gpio descriptor. We already have the descriptor we want
to use so we can directly use it.

Signed-off-by: Markus Pargmann <mpa at pengutronix.de>
---
 drivers/gpio/gpiolib.c | 17 ++++++-----------
 1 file changed, 6 insertions(+), 11 deletions(-)

diff --git a/drivers/gpio/gpiolib.c b/drivers/gpio/gpiolib.c
index 79a0b41ce57b..872fdd3617c1 100644
--- a/drivers/gpio/gpiolib.c
+++ b/drivers/gpio/gpiolib.c
@@ -2189,25 +2189,20 @@ EXPORT_SYMBOL_GPL(__gpiod_get_index_optional);
 int gpiod_hog(struct gpio_desc *desc, const char *name,
 	      unsigned long lflags, enum gpiod_flags dflags)
 {
-	struct gpio_chip *chip;
-	struct gpio_desc *local_desc;
-	int hwnum;
 	int status;
 
-	chip = gpiod_to_chip(desc);
-	hwnum = gpio_chip_hwgpio(desc);
-
-	local_desc = gpiochip_request_own_desc(chip, hwnum, name);
-	if (IS_ERR(local_desc)) {
+	status = __gpiod_request(desc, name);
+	if (status) {
 		pr_err("requesting hog GPIO %s (chip %s, offset %d) failed\n",
-		       name, chip->label, hwnum);
-		return PTR_ERR(local_desc);
+		       name, gpiod_to_chip(desc)->label,
+		       gpio_chip_hwgpio(desc));
+		return status;
 	}
 
 	status = gpiod_configure_flags(desc, name, lflags, dflags);
 	if (status < 0) {
 		pr_err("setup of hog GPIO %s (chip %s, offset %d) failed\n",
-		       name, chip->label, hwnum);
+		       name, gpiod_to_chip(desc)->label, gpio_chip_hwgpio(desc));
 		gpiochip_free_own_desc(desc);
 		return status;
 	}
-- 
2.5.0



From mpa at pengutronix.de  Sun Aug 30 00:44:45 2015
From: mpa at pengutronix.de (Markus Pargmann)
Date: Sun, 30 Aug 2015 09:44:45 +0200
Subject: [PATCH v2 2/3] gpiolib: gpiod_hog remove separate name argument
In-Reply-To: <1440920686-6892-1-git-send-email-mpa@pengutronix.de>
References: <1440920686-6892-1-git-send-email-mpa@pengutronix.de>
Message-ID: <1440920686-6892-3-git-send-email-mpa@pengutronix.de>

The gpio name is now stored in the gpio descriptor, so we can simply use
that instead of an argument to the function.

Signed-off-by: Markus Pargmann <mpa at pengutronix.de>
---
 drivers/gpio/gpiolib-of.c | 2 +-
 drivers/gpio/gpiolib.c    | 8 ++++----
 drivers/gpio/gpiolib.h    | 4 ++--
 3 files changed, 7 insertions(+), 7 deletions(-)

diff --git a/drivers/gpio/gpiolib-of.c b/drivers/gpio/gpiolib-of.c
index 48a7579dd62d..f1fe5123da28 100644
--- a/drivers/gpio/gpiolib-of.c
+++ b/drivers/gpio/gpiolib-of.c
@@ -232,7 +232,7 @@ static void of_gpiochip_scan_gpios(struct gpio_chip *chip)
 				continue;
 			}
 
-			if (gpiod_hog(desc, name, lflags, dflags))
+			if (gpiod_hog(desc, lflags, dflags))
 				continue;
 		}
 	}
diff --git a/drivers/gpio/gpiolib.c b/drivers/gpio/gpiolib.c
index 872fdd3617c1..f1559fa72c36 100644
--- a/drivers/gpio/gpiolib.c
+++ b/drivers/gpio/gpiolib.c
@@ -2181,15 +2181,15 @@ EXPORT_SYMBOL_GPL(__gpiod_get_index_optional);
 /**
  * gpiod_hog - Hog the specified GPIO desc given the provided flags
  * @desc:	gpio whose value will be assigned
- * @name:	gpio line name
  * @lflags:	gpio_lookup_flags - returned from of_find_gpio() or
  *		of_get_gpio_hog()
  * @dflags:	gpiod_flags - optional GPIO initialization flags
  */
-int gpiod_hog(struct gpio_desc *desc, const char *name,
-	      unsigned long lflags, enum gpiod_flags dflags)
+int gpiod_hog(struct gpio_desc *desc, unsigned long lflags,
+	      enum gpiod_flags dflags)
 {
 	int status;
+	const char *name = desc->name;
 
 	status = __gpiod_request(desc, name);
 	if (status) {
@@ -2211,7 +2211,7 @@ int gpiod_hog(struct gpio_desc *desc, const char *name,
 	set_bit(FLAG_IS_HOGGED, &desc->flags);
 
 	pr_info("GPIO line %d (%s) hogged as %s%s\n",
-		desc_to_gpio(desc), name,
+		desc_to_gpio(desc), desc->name,
 		(dflags&GPIOD_FLAGS_BIT_DIR_OUT) ? "output" : "input",
 		(dflags&GPIOD_FLAGS_BIT_DIR_OUT) ?
 		  (dflags&GPIOD_FLAGS_BIT_DIR_VAL) ? "/high" : "/low":"");
diff --git a/drivers/gpio/gpiolib.h b/drivers/gpio/gpiolib.h
index 78e634d1c719..6c2aeff59f86 100644
--- a/drivers/gpio/gpiolib.h
+++ b/drivers/gpio/gpiolib.h
@@ -97,8 +97,8 @@ struct gpio_desc {
 
 int gpiod_request(struct gpio_desc *desc, const char *label);
 void gpiod_free(struct gpio_desc *desc);
-int gpiod_hog(struct gpio_desc *desc, const char *name,
-		unsigned long lflags, enum gpiod_flags dflags);
+int gpiod_hog(struct gpio_desc *desc, unsigned long lflags,
+	      enum gpiod_flags dflags);
 
 /*
  * Return the GPIO number of the passed descriptor relative to its chip
-- 
2.5.0



From feumilieu at gmail.com  Sun Aug 30 02:20:38 2015
From: feumilieu at gmail.com (Aleksey Makarov)
Date: Sun, 30 Aug 2015 12:20:38 +0300
Subject: [PATCH net-next 6/8] net: thunderx: Rework interrupt handler
In-Reply-To: <CALW4P++2cG5epoit8BXBjp7Z2PK=P5wqbxkDqrt6kCa7SaZK+g@mail.gmail.com>
References: <CALW4P++2cG5epoit8BXBjp7Z2PK=P5wqbxkDqrt6kCa7SaZK+g@mail.gmail.com>
Message-ID: <55E2CAE6.1040305@auriga.com>

On 29.08.2015 04:44, Alexey Klimov wrote:

>> -static irqreturn_t nicvf_intr_handler(int irq, void *nicvf_irq)
>> +static irqreturn_t nicvf_intr_handler(int irq, void *cq_irq)
>> +{
>> +       struct nicvf_cq_poll *cq_poll = (struct nicvf_cq_poll *)cq_irq;
>> +       struct nicvf *nic = cq_poll->nicvf;
>> +       int qidx = cq_poll->cq_idx;
>> +
>> +       nicvf_dump_intr_status(nic);
>> +
>> +       /* Disable interrupts */
>> +       nicvf_disable_intr(nic, NICVF_INTR_CQ, qidx);
>> +
>> +       /* Schedule NAPI */
>> +       napi_schedule(&cq_poll->napi);
>> +
>> +       /* Clear interrupt */
>> +       nicvf_clear_intr(nic, NICVF_INTR_CQ, qidx);
>> +
>> +       return IRQ_HANDLED;
>> +}
>
> You're not considering spurious irqs in all new irq handlers here and
> below and schedule napi/tasklets unconditionally. Is it correct?
> For me it looks like previous implementation relied on reading of
> NIC_VF_INT to understand irq type and what actions should be
> performed. It generally had idea that no interrupt might occur.

1. The previous version of the handler did not handle spurious 
interrupts either.  Probably that means that the author of the patch 
knows for sure that they do not happen.

2. Instead of reading the status register new version registers 
different handlers for different irqs.  I don't see why it can be wrong.

I am going to address your other suggestions in the next version of the 
patchset.

Thank you
Aleksey Makarov




From aleksey.makarov at auriga.com  Sun Aug 30 02:29:08 2015
From: aleksey.makarov at auriga.com (Aleksey Makarov)
Date: Sun, 30 Aug 2015 12:29:08 +0300
Subject: [PATCH net-next v2 0/8] net: thunderx: New features and fixes
Message-ID: <1440926958-1874-1-git-send-email-aleksey.makarov@auriga.com>

v2:
  - The unused affinity_mask field of the structure cmp_queue 
  has been deleted. (thanks to David Miller)
  - The unneeded initializers have been dropped. (thanks to Alexey Klimov)
  - The commit message "net: thunderx: Rework interrupt handling"
  has been fixed. (thanks to Alexey Klimov)

Aleksey Makarov (1):
  net: thunderx: fix MAINTAINERS

Sunil Goutham (7):
  net: thunderx: Add receive error stats reporting via ethtool
  net: thunderx: mailboxes: remove code duplication
  net: thunderx: Receive hashing HW offload support
  net: thunderx: Support for HW VLAN stripping
  net: thunderx: Rework interrupt handling
  net: thunderx: Support for upto 96 queues for a VF
  net: thunderx: Support for internal loopback mode

 MAINTAINERS                                        |   3 +-
 drivers/net/ethernet/cavium/thunder/nic.h          |  93 +++-
 drivers/net/ethernet/cavium/thunder/nic_main.c     | 198 +++++++-
 .../net/ethernet/cavium/thunder/nicvf_ethtool.c    | 182 +++++--
 drivers/net/ethernet/cavium/thunder/nicvf_main.c   | 541 +++++++++++++++------
 drivers/net/ethernet/cavium/thunder/nicvf_queues.c | 144 +++---
 drivers/net/ethernet/cavium/thunder/nicvf_queues.h |  44 +-
 drivers/net/ethernet/cavium/thunder/thunder_bgx.c  |  31 ++
 drivers/net/ethernet/cavium/thunder/thunder_bgx.h  |   4 +
 9 files changed, 911 insertions(+), 329 deletions(-)

-- 
2.5.0



From aleksey.makarov at auriga.com  Sun Aug 30 02:29:09 2015
From: aleksey.makarov at auriga.com (Aleksey Makarov)
Date: Sun, 30 Aug 2015 12:29:09 +0300
Subject: [PATCH net-next v2 1/8] net: thunderx: fix MAINTAINERS
In-Reply-To: <1440926958-1874-1-git-send-email-aleksey.makarov@auriga.com>
References: <1440926958-1874-1-git-send-email-aleksey.makarov@auriga.com>
Message-ID: <1440926958-1874-2-git-send-email-aleksey.makarov@auriga.com>

From: Aleksey Makarov <aleksey.makarov at caviumnetworks.com>

The liquidio and thunder drivers have different maintainers.

Signed-off-by: Aleksey Makarov <aleksey.makarov at caviumnetworks.com>
---
 MAINTAINERS | 3 +--
 1 file changed, 1 insertion(+), 2 deletions(-)

diff --git a/MAINTAINERS b/MAINTAINERS
index 4e6dcb6..43cf79e 100644
--- a/MAINTAINERS
+++ b/MAINTAINERS
@@ -928,7 +928,7 @@ M:	Sunil Goutham <sgoutham at cavium.com>
 M:	Robert Richter <rric at kernel.org>
 L:	linux-arm-kernel at lists.infradead.org (moderated for non-subscribers)
 S:	Supported
-F:	drivers/net/ethernet/cavium/
+F:	drivers/net/ethernet/cavium/thunder/
 
 ARM/CIRRUS LOGIC CLPS711X ARM ARCHITECTURE
 M:	Alexander Shiyan <shc_work at mail.ru>
@@ -2543,7 +2543,6 @@ M:     Raghu Vatsavayi <raghu.vatsavayi at caviumnetworks.com>
 L:     netdev at vger.kernel.org
 W:     http://www.cavium.com
 S:     Supported
-F:     drivers/net/ethernet/cavium/
 F:     drivers/net/ethernet/cavium/liquidio/
 
 CC2520 IEEE-802.15.4 RADIO DRIVER
-- 
2.5.0



From aleksey.makarov at auriga.com  Sun Aug 30 02:29:10 2015
From: aleksey.makarov at auriga.com (Aleksey Makarov)
Date: Sun, 30 Aug 2015 12:29:10 +0300
Subject: [PATCH net-next v2 2/8] net: thunderx: Add receive error stats
 reporting via ethtool
In-Reply-To: <1440926958-1874-1-git-send-email-aleksey.makarov@auriga.com>
References: <1440926958-1874-1-git-send-email-aleksey.makarov@auriga.com>
Message-ID: <1440926958-1874-3-git-send-email-aleksey.makarov@auriga.com>

From: Sunil Goutham <sgoutham at cavium.com>

Added ethtool support to dump receive packet error statistics reported
in CQE. Also made some small fixes

Signed-off-by: Sunil Goutham <sgoutham at cavium.com>
Signed-off-by: Aleksey Makarov <aleksey.makarov at caviumnetworks.com>
---
 drivers/net/ethernet/cavium/thunder/nic.h          | 36 +++++++--
 .../net/ethernet/cavium/thunder/nicvf_ethtool.c    | 34 +++++++--
 drivers/net/ethernet/cavium/thunder/nicvf_main.c   | 26 ++++---
 drivers/net/ethernet/cavium/thunder/nicvf_queues.c | 86 +++++++---------------
 drivers/net/ethernet/cavium/thunder/nicvf_queues.h | 41 -----------
 5 files changed, 103 insertions(+), 120 deletions(-)

diff --git a/drivers/net/ethernet/cavium/thunder/nic.h b/drivers/net/ethernet/cavium/thunder/nic.h
index 8aee250..58adfd6 100644
--- a/drivers/net/ethernet/cavium/thunder/nic.h
+++ b/drivers/net/ethernet/cavium/thunder/nic.h
@@ -190,10 +190,10 @@ enum tx_stats_reg_offset {
 };
 
 struct nicvf_hw_stats {
-	u64 rx_bytes_ok;
-	u64 rx_ucast_frames_ok;
-	u64 rx_bcast_frames_ok;
-	u64 rx_mcast_frames_ok;
+	u64 rx_bytes;
+	u64 rx_ucast_frames;
+	u64 rx_bcast_frames;
+	u64 rx_mcast_frames;
 	u64 rx_fcs_errors;
 	u64 rx_l2_errors;
 	u64 rx_drop_red;
@@ -204,6 +204,31 @@ struct nicvf_hw_stats {
 	u64 rx_drop_mcast;
 	u64 rx_drop_l3_bcast;
 	u64 rx_drop_l3_mcast;
+	u64 rx_bgx_truncated_pkts;
+	u64 rx_jabber_errs;
+	u64 rx_fcs_errs;
+	u64 rx_bgx_errs;
+	u64 rx_prel2_errs;
+	u64 rx_l2_hdr_malformed;
+	u64 rx_oversize;
+	u64 rx_undersize;
+	u64 rx_l2_len_mismatch;
+	u64 rx_l2_pclp;
+	u64 rx_ip_ver_errs;
+	u64 rx_ip_csum_errs;
+	u64 rx_ip_hdr_malformed;
+	u64 rx_ip_payload_malformed;
+	u64 rx_ip_ttl_errs;
+	u64 rx_l3_pclp;
+	u64 rx_l4_malformed;
+	u64 rx_l4_csum_errs;
+	u64 rx_udp_len_errs;
+	u64 rx_l4_port_errs;
+	u64 rx_tcp_flag_errs;
+	u64 rx_tcp_offset_errs;
+	u64 rx_l4_pclp;
+	u64 rx_truncated_pkts;
+
 	u64 tx_bytes_ok;
 	u64 tx_ucast_frames_ok;
 	u64 tx_bcast_frames_ok;
@@ -222,6 +247,7 @@ struct nicvf_drv_stats {
 	u64 rx_frames_1518;
 	u64 rx_frames_jumbo;
 	u64 rx_drops;
+
 	/* Tx */
 	u64 tx_frames_ok;
 	u64 tx_drops;
@@ -257,7 +283,7 @@ struct nicvf {
 	u32			cq_coalesce_usecs;
 
 	u32			msg_enable;
-	struct nicvf_hw_stats   stats;
+	struct nicvf_hw_stats   hw_stats;
 	struct nicvf_drv_stats  drv_stats;
 	struct bgx_stats	bgx_stats;
 	struct work_struct	reset_task;
diff --git a/drivers/net/ethernet/cavium/thunder/nicvf_ethtool.c b/drivers/net/ethernet/cavium/thunder/nicvf_ethtool.c
index a4228e6..a961aa3 100644
--- a/drivers/net/ethernet/cavium/thunder/nicvf_ethtool.c
+++ b/drivers/net/ethernet/cavium/thunder/nicvf_ethtool.c
@@ -35,10 +35,10 @@ struct nicvf_stat {
 }
 
 static const struct nicvf_stat nicvf_hw_stats[] = {
-	NICVF_HW_STAT(rx_bytes_ok),
-	NICVF_HW_STAT(rx_ucast_frames_ok),
-	NICVF_HW_STAT(rx_bcast_frames_ok),
-	NICVF_HW_STAT(rx_mcast_frames_ok),
+	NICVF_HW_STAT(rx_bytes),
+	NICVF_HW_STAT(rx_ucast_frames),
+	NICVF_HW_STAT(rx_bcast_frames),
+	NICVF_HW_STAT(rx_mcast_frames),
 	NICVF_HW_STAT(rx_fcs_errors),
 	NICVF_HW_STAT(rx_l2_errors),
 	NICVF_HW_STAT(rx_drop_red),
@@ -49,6 +49,30 @@ static const struct nicvf_stat nicvf_hw_stats[] = {
 	NICVF_HW_STAT(rx_drop_mcast),
 	NICVF_HW_STAT(rx_drop_l3_bcast),
 	NICVF_HW_STAT(rx_drop_l3_mcast),
+	NICVF_HW_STAT(rx_bgx_truncated_pkts),
+	NICVF_HW_STAT(rx_jabber_errs),
+	NICVF_HW_STAT(rx_fcs_errs),
+	NICVF_HW_STAT(rx_bgx_errs),
+	NICVF_HW_STAT(rx_prel2_errs),
+	NICVF_HW_STAT(rx_l2_hdr_malformed),
+	NICVF_HW_STAT(rx_oversize),
+	NICVF_HW_STAT(rx_undersize),
+	NICVF_HW_STAT(rx_l2_len_mismatch),
+	NICVF_HW_STAT(rx_l2_pclp),
+	NICVF_HW_STAT(rx_ip_ver_errs),
+	NICVF_HW_STAT(rx_ip_csum_errs),
+	NICVF_HW_STAT(rx_ip_hdr_malformed),
+	NICVF_HW_STAT(rx_ip_payload_malformed),
+	NICVF_HW_STAT(rx_ip_ttl_errs),
+	NICVF_HW_STAT(rx_l3_pclp),
+	NICVF_HW_STAT(rx_l4_malformed),
+	NICVF_HW_STAT(rx_l4_csum_errs),
+	NICVF_HW_STAT(rx_udp_len_errs),
+	NICVF_HW_STAT(rx_l4_port_errs),
+	NICVF_HW_STAT(rx_tcp_flag_errs),
+	NICVF_HW_STAT(rx_tcp_offset_errs),
+	NICVF_HW_STAT(rx_l4_pclp),
+	NICVF_HW_STAT(rx_truncated_pkts),
 	NICVF_HW_STAT(tx_bytes_ok),
 	NICVF_HW_STAT(tx_ucast_frames_ok),
 	NICVF_HW_STAT(tx_bcast_frames_ok),
@@ -195,7 +219,7 @@ static void nicvf_get_ethtool_stats(struct net_device *netdev,
 	nicvf_update_lmac_stats(nic);
 
 	for (stat = 0; stat < nicvf_n_hw_stats; stat++)
-		*(data++) = ((u64 *)&nic->stats)
+		*(data++) = ((u64 *)&nic->hw_stats)
 				[nicvf_hw_stats[stat].index];
 	for (stat = 0; stat < nicvf_n_drv_stats; stat++)
 		*(data++) = ((u64 *)&nic->drv_stats)
diff --git a/drivers/net/ethernet/cavium/thunder/nicvf_main.c b/drivers/net/ethernet/cavium/thunder/nicvf_main.c
index 3b90afb..670ff9b 100644
--- a/drivers/net/ethernet/cavium/thunder/nicvf_main.c
+++ b/drivers/net/ethernet/cavium/thunder/nicvf_main.c
@@ -456,6 +456,12 @@ static void nicvf_rcv_pkt_handler(struct net_device *netdev,
 			       skb->data, skb->len, true);
 	}
 
+	/* If error packet, drop it here */
+	if (err) {
+		dev_kfree_skb_any(skb);
+		return;
+	}
+
 	nicvf_set_rx_frame_cnt(nic, skb);
 
 	skb_record_rx_queue(skb, cqe_rx->rq_idx);
@@ -1118,7 +1124,7 @@ void nicvf_update_lmac_stats(struct nicvf *nic)
 void nicvf_update_stats(struct nicvf *nic)
 {
 	int qidx;
-	struct nicvf_hw_stats *stats = &nic->stats;
+	struct nicvf_hw_stats *stats = &nic->hw_stats;
 	struct nicvf_drv_stats *drv_stats = &nic->drv_stats;
 	struct queue_set *qs = nic->qs;
 
@@ -1127,14 +1133,16 @@ void nicvf_update_stats(struct nicvf *nic)
 #define GET_TX_STATS(reg) \
 	nicvf_reg_read(nic, NIC_VNIC_TX_STAT_0_4 | (reg << 3))
 
-	stats->rx_bytes_ok = GET_RX_STATS(RX_OCTS);
-	stats->rx_ucast_frames_ok = GET_RX_STATS(RX_UCAST);
-	stats->rx_bcast_frames_ok = GET_RX_STATS(RX_BCAST);
-	stats->rx_mcast_frames_ok = GET_RX_STATS(RX_MCAST);
+	stats->rx_bytes = GET_RX_STATS(RX_OCTS);
+	stats->rx_ucast_frames = GET_RX_STATS(RX_UCAST);
+	stats->rx_bcast_frames = GET_RX_STATS(RX_BCAST);
+	stats->rx_mcast_frames = GET_RX_STATS(RX_MCAST);
 	stats->rx_fcs_errors = GET_RX_STATS(RX_FCS);
 	stats->rx_l2_errors = GET_RX_STATS(RX_L2ERR);
 	stats->rx_drop_red = GET_RX_STATS(RX_RED);
+	stats->rx_drop_red_bytes = GET_RX_STATS(RX_RED_OCTS);
 	stats->rx_drop_overrun = GET_RX_STATS(RX_ORUN);
+	stats->rx_drop_overrun_bytes = GET_RX_STATS(RX_ORUN_OCTS);
 	stats->rx_drop_bcast = GET_RX_STATS(RX_DRP_BCAST);
 	stats->rx_drop_mcast = GET_RX_STATS(RX_DRP_MCAST);
 	stats->rx_drop_l3_bcast = GET_RX_STATS(RX_DRP_L3BCAST);
@@ -1146,9 +1154,6 @@ void nicvf_update_stats(struct nicvf *nic)
 	stats->tx_mcast_frames_ok = GET_TX_STATS(TX_MCAST);
 	stats->tx_drops = GET_TX_STATS(TX_DROP);
 
-	drv_stats->rx_frames_ok = stats->rx_ucast_frames_ok +
-				  stats->rx_bcast_frames_ok +
-				  stats->rx_mcast_frames_ok;
 	drv_stats->tx_frames_ok = stats->tx_ucast_frames_ok +
 				  stats->tx_bcast_frames_ok +
 				  stats->tx_mcast_frames_ok;
@@ -1167,14 +1172,15 @@ static struct rtnl_link_stats64 *nicvf_get_stats64(struct net_device *netdev,
 					    struct rtnl_link_stats64 *stats)
 {
 	struct nicvf *nic = netdev_priv(netdev);
-	struct nicvf_hw_stats *hw_stats = &nic->stats;
+	struct nicvf_hw_stats *hw_stats = &nic->hw_stats;
 	struct nicvf_drv_stats *drv_stats = &nic->drv_stats;
 
 	nicvf_update_stats(nic);
 
-	stats->rx_bytes = hw_stats->rx_bytes_ok;
+	stats->rx_bytes = hw_stats->rx_bytes;
 	stats->rx_packets = drv_stats->rx_frames_ok;
 	stats->rx_dropped = drv_stats->rx_drops;
+	stats->multicast = hw_stats->rx_mcast_frames;
 
 	stats->tx_bytes = hw_stats->tx_bytes_ok;
 	stats->tx_packets = drv_stats->tx_frames_ok;
diff --git a/drivers/net/ethernet/cavium/thunder/nicvf_queues.c b/drivers/net/ethernet/cavium/thunder/nicvf_queues.c
index ca4240a..4fc40d83 100644
--- a/drivers/net/ethernet/cavium/thunder/nicvf_queues.c
+++ b/drivers/net/ethernet/cavium/thunder/nicvf_queues.c
@@ -1371,10 +1371,11 @@ void nicvf_update_sq_stats(struct nicvf *nic, int sq_idx)
 int nicvf_check_cqe_rx_errs(struct nicvf *nic,
 			    struct cmp_queue *cq, struct cqe_rx_t *cqe_rx)
 {
-	struct cmp_queue_stats *stats = &cq->stats;
+	struct nicvf_hw_stats *stats = &nic->hw_stats;
+	struct nicvf_drv_stats *drv_stats = &nic->drv_stats;
 
 	if (!cqe_rx->err_level && !cqe_rx->err_opcode) {
-		stats->rx.errop.good++;
+		drv_stats->rx_frames_ok++;
 		return 0;
 	}
 
@@ -1384,111 +1385,78 @@ int nicvf_check_cqe_rx_errs(struct nicvf *nic,
 			   nic->netdev->name,
 			   cqe_rx->err_level, cqe_rx->err_opcode);
 
-	switch (cqe_rx->err_level) {
-	case CQ_ERRLVL_MAC:
-		stats->rx.errlvl.mac_errs++;
-		break;
-	case CQ_ERRLVL_L2:
-		stats->rx.errlvl.l2_errs++;
-		break;
-	case CQ_ERRLVL_L3:
-		stats->rx.errlvl.l3_errs++;
-		break;
-	case CQ_ERRLVL_L4:
-		stats->rx.errlvl.l4_errs++;
-		break;
-	}
-
 	switch (cqe_rx->err_opcode) {
 	case CQ_RX_ERROP_RE_PARTIAL:
-		stats->rx.errop.partial_pkts++;
+		stats->rx_bgx_truncated_pkts++;
 		break;
 	case CQ_RX_ERROP_RE_JABBER:
-		stats->rx.errop.jabber_errs++;
+		stats->rx_jabber_errs++;
 		break;
 	case CQ_RX_ERROP_RE_FCS:
-		stats->rx.errop.fcs_errs++;
-		break;
-	case CQ_RX_ERROP_RE_TERMINATE:
-		stats->rx.errop.terminate_errs++;
+		stats->rx_fcs_errs++;
 		break;
 	case CQ_RX_ERROP_RE_RX_CTL:
-		stats->rx.errop.bgx_rx_errs++;
+		stats->rx_bgx_errs++;
 		break;
 	case CQ_RX_ERROP_PREL2_ERR:
-		stats->rx.errop.prel2_errs++;
-		break;
-	case CQ_RX_ERROP_L2_FRAGMENT:
-		stats->rx.errop.l2_frags++;
-		break;
-	case CQ_RX_ERROP_L2_OVERRUN:
-		stats->rx.errop.l2_overruns++;
-		break;
-	case CQ_RX_ERROP_L2_PFCS:
-		stats->rx.errop.l2_pfcs++;
-		break;
-	case CQ_RX_ERROP_L2_PUNY:
-		stats->rx.errop.l2_puny++;
+		stats->rx_prel2_errs++;
 		break;
 	case CQ_RX_ERROP_L2_MAL:
-		stats->rx.errop.l2_hdr_malformed++;
+		stats->rx_l2_hdr_malformed++;
 		break;
 	case CQ_RX_ERROP_L2_OVERSIZE:
-		stats->rx.errop.l2_oversize++;
+		stats->rx_oversize++;
 		break;
 	case CQ_RX_ERROP_L2_UNDERSIZE:
-		stats->rx.errop.l2_undersize++;
+		stats->rx_undersize++;
 		break;
 	case CQ_RX_ERROP_L2_LENMISM:
-		stats->rx.errop.l2_len_mismatch++;
+		stats->rx_l2_len_mismatch++;
 		break;
 	case CQ_RX_ERROP_L2_PCLP:
-		stats->rx.errop.l2_pclp++;
+		stats->rx_l2_pclp++;
 		break;
 	case CQ_RX_ERROP_IP_NOT:
-		stats->rx.errop.non_ip++;
+		stats->rx_ip_ver_errs++;
 		break;
 	case CQ_RX_ERROP_IP_CSUM_ERR:
-		stats->rx.errop.ip_csum_err++;
+		stats->rx_ip_csum_errs++;
 		break;
 	case CQ_RX_ERROP_IP_MAL:
-		stats->rx.errop.ip_hdr_malformed++;
+		stats->rx_ip_hdr_malformed++;
 		break;
 	case CQ_RX_ERROP_IP_MALD:
-		stats->rx.errop.ip_payload_malformed++;
+		stats->rx_ip_payload_malformed++;
 		break;
 	case CQ_RX_ERROP_IP_HOP:
-		stats->rx.errop.ip_hop_errs++;
-		break;
-	case CQ_RX_ERROP_L3_ICRC:
-		stats->rx.errop.l3_icrc_errs++;
+		stats->rx_ip_ttl_errs++;
 		break;
 	case CQ_RX_ERROP_L3_PCLP:
-		stats->rx.errop.l3_pclp++;
+		stats->rx_l3_pclp++;
 		break;
 	case CQ_RX_ERROP_L4_MAL:
-		stats->rx.errop.l4_malformed++;
+		stats->rx_l4_malformed++;
 		break;
 	case CQ_RX_ERROP_L4_CHK:
-		stats->rx.errop.l4_csum_errs++;
+		stats->rx_l4_csum_errs++;
 		break;
 	case CQ_RX_ERROP_UDP_LEN:
-		stats->rx.errop.udp_len_err++;
+		stats->rx_udp_len_errs++;
 		break;
 	case CQ_RX_ERROP_L4_PORT:
-		stats->rx.errop.bad_l4_port++;
+		stats->rx_l4_port_errs++;
 		break;
 	case CQ_RX_ERROP_TCP_FLAG:
-		stats->rx.errop.bad_tcp_flag++;
+		stats->rx_tcp_flag_errs++;
 		break;
 	case CQ_RX_ERROP_TCP_OFFSET:
-		stats->rx.errop.tcp_offset_errs++;
+		stats->rx_tcp_offset_errs++;
 		break;
 	case CQ_RX_ERROP_L4_PCLP:
-		stats->rx.errop.l4_pclp++;
+		stats->rx_l4_pclp++;
 		break;
 	case CQ_RX_ERROP_RBDR_TRUNC:
-		stats->rx.errop.pkt_truncated++;
+		stats->rx_truncated_pkts++;
 		break;
 	}
 
diff --git a/drivers/net/ethernet/cavium/thunder/nicvf_queues.h b/drivers/net/ethernet/cavium/thunder/nicvf_queues.h
index f0937b7..dc73872 100644
--- a/drivers/net/ethernet/cavium/thunder/nicvf_queues.h
+++ b/drivers/net/ethernet/cavium/thunder/nicvf_queues.h
@@ -181,47 +181,6 @@ enum CQ_TX_ERROP_E {
 };
 
 struct cmp_queue_stats {
-	struct rx_stats {
-		struct {
-			u64 mac_errs;
-			u64 l2_errs;
-			u64 l3_errs;
-			u64 l4_errs;
-		} errlvl;
-		struct {
-			u64 good;
-			u64 partial_pkts;
-			u64 jabber_errs;
-			u64 fcs_errs;
-			u64 terminate_errs;
-			u64 bgx_rx_errs;
-			u64 prel2_errs;
-			u64 l2_frags;
-			u64 l2_overruns;
-			u64 l2_pfcs;
-			u64 l2_puny;
-			u64 l2_hdr_malformed;
-			u64 l2_oversize;
-			u64 l2_undersize;
-			u64 l2_len_mismatch;
-			u64 l2_pclp;
-			u64 non_ip;
-			u64 ip_csum_err;
-			u64 ip_hdr_malformed;
-			u64 ip_payload_malformed;
-			u64 ip_hop_errs;
-			u64 l3_icrc_errs;
-			u64 l3_pclp;
-			u64 l4_malformed;
-			u64 l4_csum_errs;
-			u64 udp_len_err;
-			u64 bad_l4_port;
-			u64 bad_tcp_flag;
-			u64 tcp_offset_errs;
-			u64 l4_pclp;
-			u64 pkt_truncated;
-		} errop;
-	} rx;
 	struct tx_stats {
 		u64 good;
 		u64 desc_fault;
-- 
2.5.0



From aleksey.makarov at auriga.com  Sun Aug 30 02:29:11 2015
From: aleksey.makarov at auriga.com (Aleksey Makarov)
Date: Sun, 30 Aug 2015 12:29:11 +0300
Subject: [PATCH net-next v2 3/8] net: thunderx: mailboxes: remove code
 duplication
In-Reply-To: <1440926958-1874-1-git-send-email-aleksey.makarov@auriga.com>
References: <1440926958-1874-1-git-send-email-aleksey.makarov@auriga.com>
Message-ID: <1440926958-1874-4-git-send-email-aleksey.makarov@auriga.com>

From: Sunil Goutham <sgoutham at cavium.com>

Use the nicvf_send_msg_to_pf() function in the mailbox code.

Signed-off-by: Sunil Goutham <sgoutham at cavium.com>
Signed-off-by: Robert Richter <rrichter at cavium.com>
Signed-off-by: Aleksey Makarov <aleksey.makarov at caviumnetworks.com>
---
 drivers/net/ethernet/cavium/thunder/nic.h        |  3 +-
 drivers/net/ethernet/cavium/thunder/nicvf_main.c | 44 ++++++------------------
 2 files changed, 11 insertions(+), 36 deletions(-)

diff --git a/drivers/net/ethernet/cavium/thunder/nic.h b/drivers/net/ethernet/cavium/thunder/nic.h
index 58adfd6..a83f567 100644
--- a/drivers/net/ethernet/cavium/thunder/nic.h
+++ b/drivers/net/ethernet/cavium/thunder/nic.h
@@ -295,10 +295,9 @@ struct nicvf {
 	char			irq_name[NIC_VF_MSIX_VECTORS][20];
 	bool			irq_allocated[NIC_VF_MSIX_VECTORS];
 
-	bool			pf_ready_to_rcv_msg;
+	/* VF <-> PF mailbox communication */
 	bool			pf_acked;
 	bool			pf_nacked;
-	bool			bgx_stats_acked;
 	bool			set_mac_pending;
 } ____cacheline_aligned_in_smp;
 
diff --git a/drivers/net/ethernet/cavium/thunder/nicvf_main.c b/drivers/net/ethernet/cavium/thunder/nicvf_main.c
index 670ff9b..d4ad36e 100644
--- a/drivers/net/ethernet/cavium/thunder/nicvf_main.c
+++ b/drivers/net/ethernet/cavium/thunder/nicvf_main.c
@@ -105,7 +105,6 @@ u64 nicvf_queue_reg_read(struct nicvf *nic, u64 offset, u64 qidx)
 }
 
 /* VF -> PF mailbox communication */
-
 static void nicvf_write_to_mbx(struct nicvf *nic, union nic_mbx *mbx)
 {
 	u64 *msg = (u64 *)mbx;
@@ -147,26 +146,15 @@ int nicvf_send_msg_to_pf(struct nicvf *nic, union nic_mbx *mbx)
 */
 static int nicvf_check_pf_ready(struct nicvf *nic)
 {
-	int timeout = 5000, sleep = 20;
 	union nic_mbx mbx = {};
 
 	mbx.msg.msg = NIC_MBOX_MSG_READY;
-
-	nic->pf_ready_to_rcv_msg = false;
-
-	nicvf_write_to_mbx(nic, &mbx);
-
-	while (!nic->pf_ready_to_rcv_msg) {
-		msleep(sleep);
-		if (nic->pf_ready_to_rcv_msg)
-			break;
-		timeout -= sleep;
-		if (!timeout) {
-			netdev_err(nic->netdev,
-				   "PF didn't respond to READY msg\n");
-			return 0;
-		}
+	if (nicvf_send_msg_to_pf(nic, &mbx)) {
+		netdev_err(nic->netdev,
+			   "PF didn't respond to READY msg\n");
+		return 0;
 	}
+
 	return 1;
 }
 
@@ -197,7 +185,7 @@ static void  nicvf_handle_mbx_intr(struct nicvf *nic)
 	netdev_dbg(nic->netdev, "Mbox message: msg: 0x%x\n", mbx.msg.msg);
 	switch (mbx.msg.msg) {
 	case NIC_MBOX_MSG_READY:
-		nic->pf_ready_to_rcv_msg = true;
+		nic->pf_acked = true;
 		nic->vf_id = mbx.nic_cfg.vf_id & 0x7F;
 		nic->tns_mode = mbx.nic_cfg.tns_mode & 0x7F;
 		nic->node = mbx.nic_cfg.node_id;
@@ -221,7 +209,6 @@ static void  nicvf_handle_mbx_intr(struct nicvf *nic)
 	case NIC_MBOX_MSG_BGX_STATS:
 		nicvf_read_bgx_stats(nic, &mbx.bgx_stats);
 		nic->pf_acked = true;
-		nic->bgx_stats_acked = true;
 		break;
 	case NIC_MBOX_MSG_BGX_LINK_CHANGE:
 		nic->pf_acked = true;
@@ -1083,7 +1070,6 @@ void nicvf_update_lmac_stats(struct nicvf *nic)
 {
 	int stat = 0;
 	union nic_mbx mbx = {};
-	int timeout;
 
 	if (!netif_running(nic->netdev))
 		return;
@@ -1093,14 +1079,9 @@ void nicvf_update_lmac_stats(struct nicvf *nic)
 	/* Rx stats */
 	mbx.bgx_stats.rx = 1;
 	while (stat < BGX_RX_STATS_COUNT) {
-		nic->bgx_stats_acked = 0;
 		mbx.bgx_stats.idx = stat;
-		nicvf_send_msg_to_pf(nic, &mbx);
-		timeout = 0;
-		while ((!nic->bgx_stats_acked) && (timeout < 10)) {
-			msleep(2);
-			timeout++;
-		}
+		if (nicvf_send_msg_to_pf(nic, &mbx))
+			return;
 		stat++;
 	}
 
@@ -1109,14 +1090,9 @@ void nicvf_update_lmac_stats(struct nicvf *nic)
 	/* Tx stats */
 	mbx.bgx_stats.rx = 0;
 	while (stat < BGX_TX_STATS_COUNT) {
-		nic->bgx_stats_acked = 0;
 		mbx.bgx_stats.idx = stat;
-		nicvf_send_msg_to_pf(nic, &mbx);
-		timeout = 0;
-		while ((!nic->bgx_stats_acked) && (timeout < 10)) {
-			msleep(2);
-			timeout++;
-		}
+		if (nicvf_send_msg_to_pf(nic, &mbx))
+			return;
 		stat++;
 	}
 }
-- 
2.5.0



From aleksey.makarov at auriga.com  Sun Aug 30 02:29:12 2015
From: aleksey.makarov at auriga.com (Aleksey Makarov)
Date: Sun, 30 Aug 2015 12:29:12 +0300
Subject: [PATCH net-next v2 4/8] net: thunderx: Receive hashing HW offload
 support
In-Reply-To: <1440926958-1874-1-git-send-email-aleksey.makarov@auriga.com>
References: <1440926958-1874-1-git-send-email-aleksey.makarov@auriga.com>
Message-ID: <1440926958-1874-5-git-send-email-aleksey.makarov@auriga.com>

From: Sunil Goutham <sgoutham at cavium.com>

Adding support for receive hashing HW offload by using RSS_ALG
and RSS_TAG fields of CQE_RX descriptor. Also removed dependency
on minimum receive queue count to configure RSS so that hash is
always generated.

This hash is used by RPS logic to distribute flows across multiple
CPUs. Offload can be disabled via ethtool.

Signed-off-by: Robert Richter <rrichter at cavium.com>
Signed-off-by: Sunil Goutham <sgoutham at cavium.com>
Signed-off-by: Aleksey Makarov <aleksey.makarov at caviumnetworks.com>
---
 .../net/ethernet/cavium/thunder/nicvf_ethtool.c    | 14 ++++-----
 drivers/net/ethernet/cavium/thunder/nicvf_main.c   | 35 ++++++++++++++++++++--
 2 files changed, 39 insertions(+), 10 deletions(-)

diff --git a/drivers/net/ethernet/cavium/thunder/nicvf_ethtool.c b/drivers/net/ethernet/cavium/thunder/nicvf_ethtool.c
index a961aa3..1eec2cd 100644
--- a/drivers/net/ethernet/cavium/thunder/nicvf_ethtool.c
+++ b/drivers/net/ethernet/cavium/thunder/nicvf_ethtool.c
@@ -525,17 +525,15 @@ static int nicvf_set_rxfh(struct net_device *dev, const u32 *indir,
 	struct nicvf_rss_info *rss = &nic->rss_info;
 	int idx;
 
-	if ((nic->qs->rq_cnt <= 1) || (nic->cpi_alg != CPI_ALG_NONE)) {
-		rss->enable = false;
-		rss->hash_bits = 0;
-		return -EIO;
-	}
-
-	/* We do not allow change in unsupported parameters */
 	if (hfunc != ETH_RSS_HASH_NO_CHANGE && hfunc != ETH_RSS_HASH_TOP)
 		return -EOPNOTSUPP;
 
-	rss->enable = true;
+	if (!rss->enable) {
+		netdev_err(nic->netdev,
+			   "RSS is disabled, cannot change settings\n");
+		return -EIO;
+	}
+
 	if (indir) {
 		for (idx = 0; idx < rss->rss_size; idx++)
 			rss->ind_tbl[idx] = indir[idx];
diff --git a/drivers/net/ethernet/cavium/thunder/nicvf_main.c b/drivers/net/ethernet/cavium/thunder/nicvf_main.c
index d4ad36e..afd8ad4 100644
--- a/drivers/net/ethernet/cavium/thunder/nicvf_main.c
+++ b/drivers/net/ethernet/cavium/thunder/nicvf_main.c
@@ -313,7 +313,7 @@ static int nicvf_rss_init(struct nicvf *nic)
 
 	nicvf_get_rss_size(nic);
 
-	if ((nic->qs->rq_cnt <= 1) || (cpi_alg != CPI_ALG_NONE)) {
+	if (cpi_alg != CPI_ALG_NONE) {
 		rss->enable = false;
 		rss->hash_bits = 0;
 		return 0;
@@ -416,6 +416,34 @@ static void nicvf_snd_pkt_handler(struct net_device *netdev,
 	}
 }
 
+static inline void nicvf_set_rxhash(struct net_device *netdev,
+				    struct cqe_rx_t *cqe_rx,
+				    struct sk_buff *skb)
+{
+	u8 hash_type;
+	u32 hash;
+
+	if (!(netdev->features & NETIF_F_RXHASH))
+		return;
+
+	switch (cqe_rx->rss_alg) {
+	case RSS_ALG_TCP_IP:
+	case RSS_ALG_UDP_IP:
+		hash_type = PKT_HASH_TYPE_L4;
+		hash = cqe_rx->rss_tag;
+		break;
+	case RSS_ALG_IP:
+		hash_type = PKT_HASH_TYPE_L3;
+		hash = cqe_rx->rss_tag;
+		break;
+	default:
+		hash_type = PKT_HASH_TYPE_NONE;
+		hash = 0;
+	}
+
+	skb_set_hash(skb, hash, hash_type);
+}
+
 static void nicvf_rcv_pkt_handler(struct net_device *netdev,
 				  struct napi_struct *napi,
 				  struct cmp_queue *cq,
@@ -451,6 +479,8 @@ static void nicvf_rcv_pkt_handler(struct net_device *netdev,
 
 	nicvf_set_rx_frame_cnt(nic, skb);
 
+	nicvf_set_rxhash(netdev, cqe_rx, skb);
+
 	skb_record_rx_queue(skb, cqe_rx->rq_idx);
 	if (netdev->hw_features & NETIF_F_RXCSUM) {
 		/* HW by default verifies TCP/UDP/SCTP checksums */
@@ -1272,7 +1302,8 @@ static int nicvf_probe(struct pci_dev *pdev, const struct pci_device_id *ent)
 		goto err_free_netdev;
 
 	netdev->features |= (NETIF_F_RXCSUM | NETIF_F_IP_CSUM | NETIF_F_SG |
-			     NETIF_F_TSO | NETIF_F_GRO);
+			     NETIF_F_TSO | NETIF_F_GRO | NETIF_F_RXHASH);
+
 	netdev->hw_features = netdev->features;
 
 	netdev->netdev_ops = &nicvf_netdev_ops;
-- 
2.5.0



From aleksey.makarov at auriga.com  Sun Aug 30 02:29:13 2015
From: aleksey.makarov at auriga.com (Aleksey Makarov)
Date: Sun, 30 Aug 2015 12:29:13 +0300
Subject: [PATCH net-next v2 5/8] net: thunderx: Support for HW VLAN stripping
In-Reply-To: <1440926958-1874-1-git-send-email-aleksey.makarov@auriga.com>
References: <1440926958-1874-1-git-send-email-aleksey.makarov@auriga.com>
Message-ID: <1440926958-1874-6-git-send-email-aleksey.makarov@auriga.com>

From: Sunil Goutham <sgoutham at cavium.com>

This patch configures HW to strip 802.1Q header if found in a
receiving packet. The stripped VLAN ID and TCI information is
passed on to software via CQE_RX. Also sets netdev's 'vlan_features'
so that other HW offload features can be used for tagged packets.

This offload feature can be enabled or disabled via ethtool.

Network stack normally ignores RPS for 802.1Q packets and hence low
throughput. With this offload enabled throughput for tagged packets
will be almost same as normal packets.

Note: This patch doesn't enable HW VLAN insertion for transmit packets.

Signed-off-by: Sunil Goutham <sgoutham at cavium.com>
Signed-off-by: Aleksey Makarov <aleksey.makarov at caviumnetworks.com>
---
 drivers/net/ethernet/cavium/thunder/nic_main.c     |  4 ++++
 drivers/net/ethernet/cavium/thunder/nicvf_main.c   | 28 +++++++++++++++++++---
 drivers/net/ethernet/cavium/thunder/nicvf_queues.c | 28 ++++++++++++++++++----
 drivers/net/ethernet/cavium/thunder/nicvf_queues.h |  2 ++
 4 files changed, 55 insertions(+), 7 deletions(-)

diff --git a/drivers/net/ethernet/cavium/thunder/nic_main.c b/drivers/net/ethernet/cavium/thunder/nic_main.c
index 6e0c031..7dfec4a 100644
--- a/drivers/net/ethernet/cavium/thunder/nic_main.c
+++ b/drivers/net/ethernet/cavium/thunder/nic_main.c
@@ -329,6 +329,10 @@ static void nic_init_hw(struct nicpf *nic)
 
 	/* Timer config */
 	nic_reg_write(nic, NIC_PF_INTR_TIMER_CFG, NICPF_CLK_PER_INT_TICK);
+
+	/* Enable VLAN ethertype matching and stripping */
+	nic_reg_write(nic, NIC_PF_RX_ETYPE_0_7,
+		      (2 << 19) | (ETYPE_ALG_VLAN_STRIP << 16) | ETH_P_8021Q);
 }
 
 /* Channel parse index configuration */
diff --git a/drivers/net/ethernet/cavium/thunder/nicvf_main.c b/drivers/net/ethernet/cavium/thunder/nicvf_main.c
index afd8ad4..de51828 100644
--- a/drivers/net/ethernet/cavium/thunder/nicvf_main.c
+++ b/drivers/net/ethernet/cavium/thunder/nicvf_main.c
@@ -10,6 +10,7 @@
 #include <linux/interrupt.h>
 #include <linux/pci.h>
 #include <linux/netdevice.h>
+#include <linux/if_vlan.h>
 #include <linux/etherdevice.h>
 #include <linux/ethtool.h>
 #include <linux/log2.h>
@@ -491,6 +492,11 @@ static void nicvf_rcv_pkt_handler(struct net_device *netdev,
 
 	skb->protocol = eth_type_trans(skb, netdev);
 
+	/* Check for stripped VLAN */
+	if (cqe_rx->vlan_found && cqe_rx->vlan_stripped)
+		__vlan_hwaccel_put_tag(skb, htons(ETH_P_8021Q),
+				       ntohs((__force __be16)cqe_rx->vlan_tci));
+
 	if (napi && (netdev->features & NETIF_F_GRO))
 		napi_gro_receive(napi, skb);
 	else
@@ -1220,6 +1226,18 @@ static void nicvf_reset_task(struct work_struct *work)
 	nic->netdev->trans_start = jiffies;
 }
 
+static int nicvf_set_features(struct net_device *netdev,
+			      netdev_features_t features)
+{
+	struct nicvf *nic = netdev_priv(netdev);
+	netdev_features_t changed = features ^ netdev->features;
+
+	if (changed & NETIF_F_HW_VLAN_CTAG_RX)
+		nicvf_config_vlan_stripping(nic, features);
+
+	return 0;
+}
+
 static const struct net_device_ops nicvf_netdev_ops = {
 	.ndo_open		= nicvf_open,
 	.ndo_stop		= nicvf_stop,
@@ -1228,6 +1246,7 @@ static const struct net_device_ops nicvf_netdev_ops = {
 	.ndo_set_mac_address	= nicvf_set_mac_address,
 	.ndo_get_stats64	= nicvf_get_stats64,
 	.ndo_tx_timeout         = nicvf_tx_timeout,
+	.ndo_set_features       = nicvf_set_features,
 };
 
 static int nicvf_probe(struct pci_dev *pdev, const struct pci_device_id *ent)
@@ -1301,10 +1320,13 @@ static int nicvf_probe(struct pci_dev *pdev, const struct pci_device_id *ent)
 	if (err)
 		goto err_free_netdev;
 
-	netdev->features |= (NETIF_F_RXCSUM | NETIF_F_IP_CSUM | NETIF_F_SG |
-			     NETIF_F_TSO | NETIF_F_GRO | NETIF_F_RXHASH);
+	netdev->hw_features = (NETIF_F_RXCSUM | NETIF_F_IP_CSUM | NETIF_F_SG |
+			       NETIF_F_TSO | NETIF_F_GRO |
+			       NETIF_F_HW_VLAN_CTAG_RX | NETIF_F_RXHASH);
+
+	netdev->features |= netdev->hw_features;
 
-	netdev->hw_features = netdev->features;
+	netdev->vlan_features = NETIF_F_SG | NETIF_F_IP_CSUM | NETIF_F_TSO;
 
 	netdev->netdev_ops = &nicvf_netdev_ops;
 	netdev->watchdog_timeo = NICVF_TX_TIMEOUT;
diff --git a/drivers/net/ethernet/cavium/thunder/nicvf_queues.c b/drivers/net/ethernet/cavium/thunder/nicvf_queues.c
index 4fc40d83..b294d67 100644
--- a/drivers/net/ethernet/cavium/thunder/nicvf_queues.c
+++ b/drivers/net/ethernet/cavium/thunder/nicvf_queues.c
@@ -475,6 +475,27 @@ static void nicvf_reclaim_rbdr(struct nicvf *nic,
 		return;
 }
 
+void nicvf_config_vlan_stripping(struct nicvf *nic, netdev_features_t features)
+{
+	u64 rq_cfg;
+	int sqs;
+
+	rq_cfg = nicvf_queue_reg_read(nic, NIC_QSET_RQ_GEN_CFG, 0);
+
+	/* Enable first VLAN stripping */
+	if (features & NETIF_F_HW_VLAN_CTAG_RX)
+		rq_cfg |= (1ULL << 25);
+	else
+		rq_cfg &= ~(1ULL << 25);
+	nicvf_queue_reg_write(nic, NIC_QSET_RQ_GEN_CFG, 0, rq_cfg);
+
+	/* Configure Secondary Qsets, if any */
+	for (sqs = 0; sqs < nic->sqs_count; sqs++)
+		if (nic->snicvf[sqs])
+			nicvf_queue_reg_write(nic->snicvf[sqs],
+					      NIC_QSET_RQ_GEN_CFG, 0, rq_cfg);
+}
+
 /* Configures receive queue */
 static void nicvf_rcv_queue_config(struct nicvf *nic, struct queue_set *qs,
 				   int qidx, bool enable)
@@ -524,7 +545,9 @@ static void nicvf_rcv_queue_config(struct nicvf *nic, struct queue_set *qs,
 	mbx.rq.cfg = (1ULL << 62) | (RQ_CQ_DROP << 8);
 	nicvf_send_msg_to_pf(nic, &mbx);
 
-	nicvf_queue_reg_write(nic, NIC_QSET_RQ_GEN_CFG, qidx, 0x00);
+	nicvf_queue_reg_write(nic, NIC_QSET_RQ_GEN_CFG, 0, 0x00);
+	if (!nic->sqs_mode)
+		nicvf_config_vlan_stripping(nic, nic->netdev->features);
 
 	/* Enable Receive queue */
 	rq_cfg.ena = 1;
@@ -961,9 +984,6 @@ nicvf_sq_add_hdr_subdesc(struct snd_queue *sq, int qentry,
 
 	/* Offload checksum calculation to HW */
 	if (skb->ip_summed == CHECKSUM_PARTIAL) {
-		if (skb->protocol != htons(ETH_P_IP))
-			return;
-
 		hdr->csum_l3 = 1; /* Enable IP csum calculation */
 		hdr->l3_offset = skb_network_offset(skb);
 		hdr->l4_offset = skb_transport_offset(skb);
diff --git a/drivers/net/ethernet/cavium/thunder/nicvf_queues.h b/drivers/net/ethernet/cavium/thunder/nicvf_queues.h
index dc73872..8b93dd6 100644
--- a/drivers/net/ethernet/cavium/thunder/nicvf_queues.h
+++ b/drivers/net/ethernet/cavium/thunder/nicvf_queues.h
@@ -306,6 +306,8 @@ struct queue_set {
 
 #define	CQ_ERR_MASK	(CQ_WR_FULL | CQ_WR_DISABLE | CQ_WR_FAULT)
 
+void nicvf_config_vlan_stripping(struct nicvf *nic,
+				 netdev_features_t features);
 int nicvf_set_qset_resources(struct nicvf *nic);
 int nicvf_config_data_transfer(struct nicvf *nic, bool enable);
 void nicvf_qset_config(struct nicvf *nic, bool enable);
-- 
2.5.0



From aleksey.makarov at auriga.com  Sun Aug 30 02:29:14 2015
From: aleksey.makarov at auriga.com (Aleksey Makarov)
Date: Sun, 30 Aug 2015 12:29:14 +0300
Subject: [PATCH net-next v2 6/8] net: thunderx: Rework interrupt handling
In-Reply-To: <1440926958-1874-1-git-send-email-aleksey.makarov@auriga.com>
References: <1440926958-1874-1-git-send-email-aleksey.makarov@auriga.com>
Message-ID: <1440926958-1874-7-git-send-email-aleksey.makarov@auriga.com>

From: Sunil Goutham <sgoutham at cavium.com>

Rework interrupt handler to avoid checking IRQ affinity of
CQ interrupts. Now separate handlers are registered for each IRQ
including RBDR. Register interrupt handlers for only those
which are being used. Add nicvf_dump_intr_status() and use it
in irq handlers.

Signed-off-by: Sunil Goutham <sgoutham at cavium.com>
Signed-off-by: Aleksey Makarov <aleksey.makarov at caviumnetworks.com>
---
 drivers/net/ethernet/cavium/thunder/nic.h          |   1 +
 drivers/net/ethernet/cavium/thunder/nicvf_main.c   | 172 ++++++++++++---------
 drivers/net/ethernet/cavium/thunder/nicvf_queues.h |   1 +
 3 files changed, 102 insertions(+), 72 deletions(-)

diff --git a/drivers/net/ethernet/cavium/thunder/nic.h b/drivers/net/ethernet/cavium/thunder/nic.h
index a83f567..89b997e 100644
--- a/drivers/net/ethernet/cavium/thunder/nic.h
+++ b/drivers/net/ethernet/cavium/thunder/nic.h
@@ -135,6 +135,7 @@
 #define	NICVF_TX_TIMEOUT		(50 * HZ)
 
 struct nicvf_cq_poll {
+	struct  nicvf *nicvf;
 	u8	cq_idx;		/* Completion queue index */
 	struct	napi_struct napi;
 };
diff --git a/drivers/net/ethernet/cavium/thunder/nicvf_main.c b/drivers/net/ethernet/cavium/thunder/nicvf_main.c
index de51828..85213f3 100644
--- a/drivers/net/ethernet/cavium/thunder/nicvf_main.c
+++ b/drivers/net/ethernet/cavium/thunder/nicvf_main.c
@@ -653,11 +653,20 @@ static void nicvf_handle_qs_err(unsigned long data)
 	nicvf_enable_intr(nic, NICVF_INTR_QS_ERR, 0);
 }
 
+static void nicvf_dump_intr_status(struct nicvf *nic)
+{
+	if (netif_msg_intr(nic))
+		netdev_info(nic->netdev, "%s: interrupt status 0x%llx\n",
+			    nic->netdev->name, nicvf_reg_read(nic, NIC_VF_INT));
+}
+
 static irqreturn_t nicvf_misc_intr_handler(int irq, void *nicvf_irq)
 {
 	struct nicvf *nic = (struct nicvf *)nicvf_irq;
 	u64 intr;
 
+	nicvf_dump_intr_status(nic);
+
 	intr = nicvf_reg_read(nic, NIC_VF_INT);
 	/* Check for spurious interrupt */
 	if (!(intr & NICVF_INTR_MBOX_MASK))
@@ -668,59 +677,58 @@ static irqreturn_t nicvf_misc_intr_handler(int irq, void *nicvf_irq)
 	return IRQ_HANDLED;
 }
 
-static irqreturn_t nicvf_intr_handler(int irq, void *nicvf_irq)
+static irqreturn_t nicvf_intr_handler(int irq, void *cq_irq)
+{
+	struct nicvf_cq_poll *cq_poll = (struct nicvf_cq_poll *)cq_irq;
+	struct nicvf *nic = cq_poll->nicvf;
+	int qidx = cq_poll->cq_idx;
+
+	nicvf_dump_intr_status(nic);
+
+	/* Disable interrupts */
+	nicvf_disable_intr(nic, NICVF_INTR_CQ, qidx);
+
+	/* Schedule NAPI */
+	napi_schedule(&cq_poll->napi);
+
+	/* Clear interrupt */
+	nicvf_clear_intr(nic, NICVF_INTR_CQ, qidx);
+
+	return IRQ_HANDLED;
+}
+
+static irqreturn_t nicvf_rbdr_intr_handler(int irq, void *nicvf_irq)
 {
-	u64 qidx, intr, clear_intr = 0;
-	u64 cq_intr, rbdr_intr, qs_err_intr;
 	struct nicvf *nic = (struct nicvf *)nicvf_irq;
-	struct queue_set *qs = nic->qs;
-	struct nicvf_cq_poll *cq_poll = NULL;
+	u8 qidx;
 
-	intr = nicvf_reg_read(nic, NIC_VF_INT);
-	if (netif_msg_intr(nic))
-		netdev_info(nic->netdev, "%s: interrupt status 0x%llx\n",
-			    nic->netdev->name, intr);
-
-	qs_err_intr = intr & NICVF_INTR_QS_ERR_MASK;
-	if (qs_err_intr) {
-		/* Disable Qset err interrupt and schedule softirq */
-		nicvf_disable_intr(nic, NICVF_INTR_QS_ERR, 0);
-		tasklet_hi_schedule(&nic->qs_err_task);
-		clear_intr |= qs_err_intr;
-	}
 
-	/* Disable interrupts and start polling */
-	cq_intr = (intr & NICVF_INTR_CQ_MASK) >> NICVF_INTR_CQ_SHIFT;
-	for (qidx = 0; qidx < qs->cq_cnt; qidx++) {
-		if (!(cq_intr & (1 << qidx)))
-			continue;
-		if (!nicvf_is_intr_enabled(nic, NICVF_INTR_CQ, qidx))
+	nicvf_dump_intr_status(nic);
+
+	/* Disable RBDR interrupt and schedule softirq */
+	for (qidx = 0; qidx < nic->qs->rbdr_cnt; qidx++) {
+		if (!nicvf_is_intr_enabled(nic, NICVF_INTR_RBDR, qidx))
 			continue;
+		nicvf_disable_intr(nic, NICVF_INTR_RBDR, qidx);
+		tasklet_hi_schedule(&nic->rbdr_task);
+		/* Clear interrupt */
+		nicvf_clear_intr(nic, NICVF_INTR_RBDR, qidx);
+	}
 
-		nicvf_disable_intr(nic, NICVF_INTR_CQ, qidx);
-		clear_intr |= ((1 << qidx) << NICVF_INTR_CQ_SHIFT);
+	return IRQ_HANDLED;
+}
 
-		cq_poll = nic->napi[qidx];
-		/* Schedule NAPI */
-		if (cq_poll)
-			napi_schedule(&cq_poll->napi);
-	}
+static irqreturn_t nicvf_qs_err_intr_handler(int irq, void *nicvf_irq)
+{
+	struct nicvf *nic = (struct nicvf *)nicvf_irq;
 
-	/* Handle RBDR interrupts */
-	rbdr_intr = (intr & NICVF_INTR_RBDR_MASK) >> NICVF_INTR_RBDR_SHIFT;
-	if (rbdr_intr) {
-		/* Disable RBDR interrupt and schedule softirq */
-		for (qidx = 0; qidx < qs->rbdr_cnt; qidx++) {
-			if (!nicvf_is_intr_enabled(nic, NICVF_INTR_RBDR, qidx))
-				continue;
-			nicvf_disable_intr(nic, NICVF_INTR_RBDR, qidx);
-			tasklet_hi_schedule(&nic->rbdr_task);
-			clear_intr |= ((1 << qidx) << NICVF_INTR_RBDR_SHIFT);
-		}
-	}
+	nicvf_dump_intr_status(nic);
+
+	/* Disable Qset err interrupt and schedule softirq */
+	nicvf_disable_intr(nic, NICVF_INTR_QS_ERR, 0);
+	tasklet_hi_schedule(&nic->qs_err_task);
+	nicvf_clear_intr(nic, NICVF_INTR_QS_ERR, 0);
 
-	/* Clear interrupts */
-	nicvf_reg_write(nic, NIC_VF_INT, clear_intr);
 	return IRQ_HANDLED;
 }
 
@@ -754,7 +762,7 @@ static void nicvf_disable_msix(struct nicvf *nic)
 
 static int nicvf_register_interrupts(struct nicvf *nic)
 {
-	int irq, free, ret = 0;
+	int irq, ret = 0;
 	int vector;
 
 	for_each_cq_irq(irq)
@@ -769,44 +777,42 @@ static int nicvf_register_interrupts(struct nicvf *nic)
 		sprintf(nic->irq_name[irq], "NICVF%d RBDR%d",
 			nic->vf_id, irq - NICVF_INTR_ID_RBDR);
 
-	/* Register all interrupts except mailbox */
-	for (irq = 0; irq < NICVF_INTR_ID_SQ; irq++) {
+	/* Register CQ interrupts */
+	for (irq = 0; irq < nic->qs->cq_cnt; irq++) {
 		vector = nic->msix_entries[irq].vector;
 		ret = request_irq(vector, nicvf_intr_handler,
-				  0, nic->irq_name[irq], nic);
+				  0, nic->irq_name[irq], nic->napi[irq]);
 		if (ret)
-			break;
+			goto err;
 		nic->irq_allocated[irq] = true;
 	}
 
-	for (irq = NICVF_INTR_ID_SQ; irq < NICVF_INTR_ID_MISC; irq++) {
+	/* Register RBDR interrupt */
+	for (irq = NICVF_INTR_ID_RBDR;
+	     irq < (NICVF_INTR_ID_RBDR + nic->qs->rbdr_cnt); irq++) {
 		vector = nic->msix_entries[irq].vector;
-		ret = request_irq(vector, nicvf_intr_handler,
+		ret = request_irq(vector, nicvf_rbdr_intr_handler,
 				  0, nic->irq_name[irq], nic);
 		if (ret)
-			break;
+			goto err;
 		nic->irq_allocated[irq] = true;
 	}
 
+	/* Register QS error interrupt */
 	sprintf(nic->irq_name[NICVF_INTR_ID_QS_ERR],
 		"NICVF%d Qset error", nic->vf_id);
-	if (!ret) {
-		vector = nic->msix_entries[NICVF_INTR_ID_QS_ERR].vector;
-		irq = NICVF_INTR_ID_QS_ERR;
-		ret = request_irq(vector, nicvf_intr_handler,
-				  0, nic->irq_name[irq], nic);
-		if (!ret)
-			nic->irq_allocated[irq] = true;
-	}
+	irq = NICVF_INTR_ID_QS_ERR;
+	ret = request_irq(nic->msix_entries[irq].vector,
+			  nicvf_qs_err_intr_handler,
+			  0, nic->irq_name[irq], nic);
+	if (!ret)
+		nic->irq_allocated[irq] = true;
 
-	if (ret) {
-		netdev_err(nic->netdev, "Request irq failed\n");
-		for (free = 0; free < irq; free++)
-			free_irq(nic->msix_entries[free].vector, nic);
-		return ret;
-	}
+err:
+	if (ret)
+		netdev_err(nic->netdev, "request_irq failed, vector %d\n", irq);
 
-	return 0;
+	return ret;
 }
 
 static void nicvf_unregister_interrupts(struct nicvf *nic)
@@ -815,8 +821,14 @@ static void nicvf_unregister_interrupts(struct nicvf *nic)
 
 	/* Free registered interrupts */
 	for (irq = 0; irq < nic->num_vec; irq++) {
-		if (nic->irq_allocated[irq])
+		if (!nic->irq_allocated[irq])
+			continue;
+
+		if (irq < NICVF_INTR_ID_SQ)
+			free_irq(nic->msix_entries[irq].vector, nic->napi[irq]);
+		else
 			free_irq(nic->msix_entries[irq].vector, nic);
+
 		nic->irq_allocated[irq] = false;
 	}
 
@@ -888,6 +900,20 @@ static netdev_tx_t nicvf_xmit(struct sk_buff *skb, struct net_device *netdev)
 	return NETDEV_TX_OK;
 }
 
+static inline void nicvf_free_cq_poll(struct nicvf *nic)
+{
+	struct nicvf_cq_poll *cq_poll;
+	int qidx;
+
+	for (qidx = 0; qidx < nic->qs->cq_cnt; qidx++) {
+		cq_poll = nic->napi[qidx];
+		if (!cq_poll)
+			continue;
+		nic->napi[qidx] = NULL;
+		kfree(cq_poll);
+	}
+}
+
 int nicvf_stop(struct net_device *netdev)
 {
 	int irq, qidx;
@@ -922,7 +948,6 @@ int nicvf_stop(struct net_device *netdev)
 		cq_poll = nic->napi[qidx];
 		if (!cq_poll)
 			continue;
-		nic->napi[qidx] = NULL;
 		napi_synchronize(&cq_poll->napi);
 		/* CQ intr is enabled while napi_complete,
 		 * so disable it now
@@ -931,7 +956,6 @@ int nicvf_stop(struct net_device *netdev)
 		nicvf_clear_intr(nic, NICVF_INTR_CQ, qidx);
 		napi_disable(&cq_poll->napi);
 		netif_napi_del(&cq_poll->napi);
-		kfree(cq_poll);
 	}
 
 	netif_tx_disable(netdev);
@@ -947,6 +971,8 @@ int nicvf_stop(struct net_device *netdev)
 
 	nicvf_unregister_interrupts(nic);
 
+	nicvf_free_cq_poll(nic);
+
 	return 0;
 }
 
@@ -973,6 +999,7 @@ int nicvf_open(struct net_device *netdev)
 			goto napi_del;
 		}
 		cq_poll->cq_idx = qidx;
+		cq_poll->nicvf = nic;
 		netif_napi_add(netdev, &cq_poll->napi, nicvf_poll,
 			       NAPI_POLL_WEIGHT);
 		napi_enable(&cq_poll->napi);
@@ -1040,6 +1067,8 @@ int nicvf_open(struct net_device *netdev)
 cleanup:
 	nicvf_disable_intr(nic, NICVF_INTR_MBOX, 0);
 	nicvf_unregister_interrupts(nic);
+	tasklet_kill(&nic->qs_err_task);
+	tasklet_kill(&nic->rbdr_task);
 napi_del:
 	for (qidx = 0; qidx < qs->cq_cnt; qidx++) {
 		cq_poll = nic->napi[qidx];
@@ -1047,9 +1076,8 @@ napi_del:
 			continue;
 		napi_disable(&cq_poll->napi);
 		netif_napi_del(&cq_poll->napi);
-		kfree(cq_poll);
-		nic->napi[qidx] = NULL;
 	}
+	nicvf_free_cq_poll(nic);
 	return err;
 }
 
diff --git a/drivers/net/ethernet/cavium/thunder/nicvf_queues.h b/drivers/net/ethernet/cavium/thunder/nicvf_queues.h
index 8b93dd6..fb4957d 100644
--- a/drivers/net/ethernet/cavium/thunder/nicvf_queues.h
+++ b/drivers/net/ethernet/cavium/thunder/nicvf_queues.h
@@ -251,6 +251,7 @@ struct cmp_queue {
 	void		*desc;
 	struct q_desc_mem   dmem;
 	struct cmp_queue_stats	stats;
+	int		irq;
 } ____cacheline_aligned_in_smp;
 
 struct snd_queue {
-- 
2.5.0



From aleksey.makarov at auriga.com  Sun Aug 30 02:29:15 2015
From: aleksey.makarov at auriga.com (Aleksey Makarov)
Date: Sun, 30 Aug 2015 12:29:15 +0300
Subject: [PATCH net-next v2 7/8] net: thunderx: Support for upto 96 queues for
 a VF
In-Reply-To: <1440926958-1874-1-git-send-email-aleksey.makarov@auriga.com>
References: <1440926958-1874-1-git-send-email-aleksey.makarov@auriga.com>
Message-ID: <1440926958-1874-8-git-send-email-aleksey.makarov@auriga.com>

From: Sunil Goutham <sgoutham at cavium.com>

This patch adds support for handling multiple qsets assigned to a
single VF. There by increasing no of queues from earlier 8 to max
no of CPUs in the system i.e 48 queues on a single node and 96 on
dual node system. User doesn't have option to assign which Qsets/VFs
 to be merged. Upon request from VF, PF assigns next free Qsets as
secondary qsets. To maintain current behavior no of queues is kept
to 8 by default which can be increased via ethtool.

If user wants to unbind NICVF driver from a secondary Qset then it
should be done after tearing down primary VF's interface.

Signed-off-by: Sunil Goutham <sgoutham at cavium.com>
Signed-off-by: Aleksey Makarov <aleksey.makarov at caviumnetworks.com>
Signed-off-by: Robert Richter <rrichter at cavium.com>
---
 drivers/net/ethernet/cavium/thunder/nic.h          |  42 ++++-
 drivers/net/ethernet/cavium/thunder/nic_main.c     | 173 +++++++++++++++--
 .../net/ethernet/cavium/thunder/nicvf_ethtool.c    | 134 +++++++++----
 drivers/net/ethernet/cavium/thunder/nicvf_main.c   | 210 +++++++++++++++++++--
 drivers/net/ethernet/cavium/thunder/nicvf_queues.c |  30 ++-
 5 files changed, 505 insertions(+), 84 deletions(-)

diff --git a/drivers/net/ethernet/cavium/thunder/nic.h b/drivers/net/ethernet/cavium/thunder/nic.h
index 89b997e..35b2ee1 100644
--- a/drivers/net/ethernet/cavium/thunder/nic.h
+++ b/drivers/net/ethernet/cavium/thunder/nic.h
@@ -258,13 +258,23 @@ struct nicvf_drv_stats {
 };
 
 struct nicvf {
+	struct nicvf		*pnicvf;
 	struct net_device	*netdev;
 	struct pci_dev		*pdev;
 	u8			vf_id;
 	u8			node;
-	u8			tns_mode;
+	u8			tns_mode:1;
+	u8			sqs_mode:1;
 	u16			mtu;
 	struct queue_set	*qs;
+#define	MAX_SQS_PER_VF_SINGLE_NODE		5
+#define	MAX_SQS_PER_VF				11
+	u8			sqs_id;
+	u8			sqs_count; /* Secondary Qset count */
+	struct nicvf		*snicvf[MAX_SQS_PER_VF];
+	u8			rx_queues;
+	u8			tx_queues;
+	u8			max_queues;
 	void __iomem		*reg_base;
 	bool			link_up;
 	u8			duplex;
@@ -330,14 +340,19 @@ struct nicvf {
 #define	NIC_MBOX_MSG_RQ_SW_SYNC		0x0F	/* Flush inflight pkts to RQ */
 #define	NIC_MBOX_MSG_BGX_STATS		0x10	/* Get stats from BGX */
 #define	NIC_MBOX_MSG_BGX_LINK_CHANGE	0x11	/* BGX:LMAC link status */
-#define NIC_MBOX_MSG_CFG_DONE		0x12	/* VF configuration done */
-#define NIC_MBOX_MSG_SHUTDOWN		0x13	/* VF is being shutdown */
+#define	NIC_MBOX_MSG_ALLOC_SQS		0x12	/* Allocate secondary Qset */
+#define	NIC_MBOX_MSG_NICVF_PTR		0x13	/* Send nicvf ptr to PF */
+#define	NIC_MBOX_MSG_PNICVF_PTR		0x14	/* Get primary qset nicvf ptr */
+#define	NIC_MBOX_MSG_SNICVF_PTR		0x15	/* Send sqet nicvf ptr to PVF */
+#define	NIC_MBOX_MSG_CFG_DONE		0xF0	/* VF configuration done */
+#define	NIC_MBOX_MSG_SHUTDOWN		0xF1	/* VF is being shutdown */
 
 struct nic_cfg_msg {
 	u8    msg;
 	u8    vf_id;
-	u8    tns_mode;
 	u8    node_id;
+	u8    tns_mode:1;
+	u8    sqs_mode:1;
 	u8    mac_addr[ETH_ALEN];
 };
 
@@ -345,6 +360,7 @@ struct nic_cfg_msg {
 struct qs_cfg_msg {
 	u8    msg;
 	u8    num;
+	u8    sqs_count;
 	u64   cfg;
 };
 
@@ -361,6 +377,7 @@ struct sq_cfg_msg {
 	u8    msg;
 	u8    qs_num;
 	u8    sq_num;
+	bool  sqs_mode;
 	u64   cfg;
 };
 
@@ -420,6 +437,21 @@ struct bgx_link_status {
 	u32   speed;
 };
 
+/* Get Extra Qset IDs */
+struct sqs_alloc {
+	u8    msg;
+	u8    vf_id;
+	u8    qs_count;
+};
+
+struct nicvf_ptr {
+	u8    msg;
+	u8    vf_id;
+	bool  sqs_mode;
+	u8    sqs_id;
+	u64   nicvf;
+};
+
 /* 128 bit shared memory between PF and each VF */
 union nic_mbx {
 	struct { u8 msg; }	msg;
@@ -434,6 +466,8 @@ union nic_mbx {
 	struct rss_cfg_msg	rss_cfg;
 	struct bgx_stats_msg    bgx_stats;
 	struct bgx_link_status  link_status;
+	struct sqs_alloc        sqs_alloc;
+	struct nicvf_ptr	nicvf;
 };
 
 #define NIC_NODE_ID_MASK	0x03
diff --git a/drivers/net/ethernet/cavium/thunder/nic_main.c b/drivers/net/ethernet/cavium/thunder/nic_main.c
index 7dfec4a..dac8094 100644
--- a/drivers/net/ethernet/cavium/thunder/nic_main.c
+++ b/drivers/net/ethernet/cavium/thunder/nic_main.c
@@ -28,6 +28,11 @@ struct nicpf {
 	u8			num_vf_en;      /* No of VF enabled */
 	bool			vf_enabled[MAX_NUM_VFS_SUPPORTED];
 	void __iomem		*reg_base;       /* Register start address */
+	u8			num_sqs_en;	/* Secondary qsets enabled */
+	u64			nicvf[MAX_NUM_VFS_SUPPORTED];
+	u8			vf_sqs[MAX_NUM_VFS_SUPPORTED][MAX_SQS_PER_VF];
+	u8			pqs_vf[MAX_NUM_VFS_SUPPORTED];
+	bool			sqs_used[MAX_NUM_VFS_SUPPORTED];
 	struct pkind_cfg	pkind;
 #define	NIC_SET_VF_LMAC_MAP(bgx, lmac)	(((bgx & 0xF) << 4) | (lmac & 0xF))
 #define	NIC_GET_BGX_FROM_VF_LMAC_MAP(map)	((map >> 4) & 0xF)
@@ -139,13 +144,15 @@ static void nic_mbx_send_ready(struct nicpf *nic, int vf)
 
 	mbx.nic_cfg.tns_mode = NIC_TNS_BYPASS_MODE;
 
-	bgx_idx = NIC_GET_BGX_FROM_VF_LMAC_MAP(nic->vf_lmac_map[vf]);
-	lmac = NIC_GET_LMAC_FROM_VF_LMAC_MAP(nic->vf_lmac_map[vf]);
-
-	mac = bgx_get_lmac_mac(nic->node, bgx_idx, lmac);
-	if (mac)
-		ether_addr_copy((u8 *)&mbx.nic_cfg.mac_addr, mac);
+	if (vf < MAX_LMAC) {
+		bgx_idx = NIC_GET_BGX_FROM_VF_LMAC_MAP(nic->vf_lmac_map[vf]);
+		lmac = NIC_GET_LMAC_FROM_VF_LMAC_MAP(nic->vf_lmac_map[vf]);
 
+		mac = bgx_get_lmac_mac(nic->node, bgx_idx, lmac);
+		if (mac)
+			ether_addr_copy((u8 *)&mbx.nic_cfg.mac_addr, mac);
+	}
+	mbx.nic_cfg.sqs_mode = (vf >= nic->num_vf_en) ? true : false;
 	mbx.nic_cfg.node_id = nic->node;
 	nic_send_msg_to_vf(nic, vf, &mbx);
 }
@@ -433,6 +440,12 @@ static void nic_config_rss(struct nicpf *nic, struct rss_cfg_msg *cfg)
 	qset = cfg->vf_id;
 
 	for (; rssi < (rssi_base + cfg->tbl_len); rssi++) {
+		u8 svf = cfg->ind_tbl[idx] >> 3;
+
+		if (svf)
+			qset = nic->vf_sqs[cfg->vf_id][svf - 1];
+		else
+			qset = cfg->vf_id;
 		nic_reg_write(nic, NIC_PF_RSSI_0_4097_RQ | (rssi << 3),
 			      (qset << 3) | (cfg->ind_tbl[idx] & 0x7));
 		idx++;
@@ -456,19 +469,31 @@ static void nic_config_rss(struct nicpf *nic, struct rss_cfg_msg *cfg)
  * VNIC6-SQ0 -> TL4(528) -> TL3[132] -> TL2[33] -> TL1[1] -> BGX1
  * VNIC7-SQ0 -> TL4(536) -> TL3[134] -> TL2[33] -> TL1[1] -> BGX1
  */
-static void nic_tx_channel_cfg(struct nicpf *nic, u8 vnic, u8 sq_idx)
+static void nic_tx_channel_cfg(struct nicpf *nic, u8 vnic,
+			       struct sq_cfg_msg *sq)
 {
 	u32 bgx, lmac, chan;
 	u32 tl2, tl3, tl4;
 	u32 rr_quantum;
+	u8 sq_idx = sq->sq_num;
+	u8 pqs_vnic;
+
+	if (sq->sqs_mode)
+		pqs_vnic = nic->pqs_vf[vnic];
+	else
+		pqs_vnic = vnic;
+
+	bgx = NIC_GET_BGX_FROM_VF_LMAC_MAP(nic->vf_lmac_map[pqs_vnic]);
+	lmac = NIC_GET_LMAC_FROM_VF_LMAC_MAP(nic->vf_lmac_map[pqs_vnic]);
 
-	bgx = NIC_GET_BGX_FROM_VF_LMAC_MAP(nic->vf_lmac_map[vnic]);
-	lmac = NIC_GET_LMAC_FROM_VF_LMAC_MAP(nic->vf_lmac_map[vnic]);
 	/* 24 bytes for FCS, IPG and preamble */
 	rr_quantum = ((NIC_HW_MAX_FRS + 24) / 4);
 
 	tl4 = (lmac * NIC_TL4_PER_LMAC) + (bgx * NIC_TL4_PER_BGX);
 	tl4 += sq_idx;
+	if (sq->sqs_mode)
+		tl4 += vnic * 8;
+
 	tl3 = tl4 / (NIC_MAX_TL4 / NIC_MAX_TL3);
 	nic_reg_write(nic, NIC_PF_QSET_0_127_SQ_0_7_CFG2 |
 		      ((u64)vnic << NIC_QS_ID_SHIFT) |
@@ -489,6 +514,71 @@ static void nic_tx_channel_cfg(struct nicpf *nic, u8 vnic, u8 sq_idx)
 	nic_reg_write(nic, NIC_PF_TL2_0_63_PRI | (tl2 << 3), 0x00);
 }
 
+/* Send primary nicvf pointer to secondary QS's VF */
+static void nic_send_pnicvf(struct nicpf *nic, int sqs)
+{
+	union nic_mbx mbx = {};
+
+	mbx.nicvf.msg = NIC_MBOX_MSG_PNICVF_PTR;
+	mbx.nicvf.nicvf = nic->nicvf[nic->pqs_vf[sqs]];
+	nic_send_msg_to_vf(nic, sqs, &mbx);
+}
+
+/* Send SQS's nicvf pointer to primary QS's VF */
+static void nic_send_snicvf(struct nicpf *nic, struct nicvf_ptr *nicvf)
+{
+	union nic_mbx mbx = {};
+	int sqs_id = nic->vf_sqs[nicvf->vf_id][nicvf->sqs_id];
+
+	mbx.nicvf.msg = NIC_MBOX_MSG_SNICVF_PTR;
+	mbx.nicvf.sqs_id = nicvf->sqs_id;
+	mbx.nicvf.nicvf = nic->nicvf[sqs_id];
+	nic_send_msg_to_vf(nic, nicvf->vf_id, &mbx);
+}
+
+/* Find next available Qset that can be assigned as a
+ * secondary Qset to a VF.
+ */
+static int nic_nxt_avail_sqs(struct nicpf *nic)
+{
+	int sqs;
+
+	for (sqs = 0; sqs < nic->num_sqs_en; sqs++) {
+		if (!nic->sqs_used[sqs])
+			nic->sqs_used[sqs] = true;
+		else
+			continue;
+		return sqs + nic->num_vf_en;
+	}
+	return -1;
+}
+
+/* Allocate additional Qsets for requested VF */
+static void nic_alloc_sqs(struct nicpf *nic, struct sqs_alloc *sqs)
+{
+	union nic_mbx mbx = {};
+	int idx, alloc_qs = 0;
+	int sqs_id;
+
+	if (!nic->num_sqs_en)
+		goto send_mbox;
+
+	for (idx = 0; idx < sqs->qs_count; idx++) {
+		sqs_id = nic_nxt_avail_sqs(nic);
+		if (sqs_id < 0)
+			break;
+		nic->vf_sqs[sqs->vf_id][idx] = sqs_id;
+		nic->pqs_vf[sqs_id] = sqs->vf_id;
+		alloc_qs++;
+	}
+
+send_mbox:
+	mbx.sqs_alloc.msg = NIC_MBOX_MSG_ALLOC_SQS;
+	mbx.sqs_alloc.vf_id = sqs->vf_id;
+	mbx.sqs_alloc.qs_count = alloc_qs;
+	nic_send_msg_to_vf(nic, sqs->vf_id, &mbx);
+}
+
 /* Interrupt handler to handle mailbox messages from VFs */
 static void nic_handle_mbx_intr(struct nicpf *nic, int vf)
 {
@@ -496,6 +586,7 @@ static void nic_handle_mbx_intr(struct nicpf *nic, int vf)
 	u64 *mbx_data;
 	u64 mbx_addr;
 	u64 reg_addr;
+	u64 cfg;
 	int bgx, lmac;
 	int i;
 	int ret = 0;
@@ -516,15 +607,24 @@ static void nic_handle_mbx_intr(struct nicpf *nic, int vf)
 	switch (mbx.msg.msg) {
 	case NIC_MBOX_MSG_READY:
 		nic_mbx_send_ready(nic, vf);
-		nic->link[vf] = 0;
-		nic->duplex[vf] = 0;
-		nic->speed[vf] = 0;
+		if (vf < MAX_LMAC) {
+			nic->link[vf] = 0;
+			nic->duplex[vf] = 0;
+			nic->speed[vf] = 0;
+		}
 		ret = 1;
 		break;
 	case NIC_MBOX_MSG_QS_CFG:
 		reg_addr = NIC_PF_QSET_0_127_CFG |
 			   (mbx.qs.num << NIC_QS_ID_SHIFT);
-		nic_reg_write(nic, reg_addr, mbx.qs.cfg);
+		cfg = mbx.qs.cfg;
+		/* Check if its a secondary Qset */
+		if (vf >= nic->num_vf_en) {
+			cfg = cfg & (~0x7FULL);
+			/* Assign this Qset to primary Qset's VF */
+			cfg |= nic->pqs_vf[vf];
+		}
+		nic_reg_write(nic, reg_addr, cfg);
 		break;
 	case NIC_MBOX_MSG_RQ_CFG:
 		reg_addr = NIC_PF_QSET_0_127_RQ_0_7_CFG |
@@ -552,9 +652,11 @@ static void nic_handle_mbx_intr(struct nicpf *nic, int vf)
 			   (mbx.sq.qs_num << NIC_QS_ID_SHIFT) |
 			   (mbx.sq.sq_num << NIC_Q_NUM_SHIFT);
 		nic_reg_write(nic, reg_addr, mbx.sq.cfg);
-		nic_tx_channel_cfg(nic, mbx.qs.num, mbx.sq.sq_num);
+		nic_tx_channel_cfg(nic, mbx.qs.num, &mbx.sq);
 		break;
 	case NIC_MBOX_MSG_SET_MAC:
+		if (vf >= nic->num_vf_en)
+			break;
 		lmac = mbx.mac.vf_id;
 		bgx = NIC_GET_BGX_FROM_VF_LMAC_MAP(nic->vf_lmac_map[lmac]);
 		lmac = NIC_GET_LMAC_FROM_VF_LMAC_MAP(nic->vf_lmac_map[lmac]);
@@ -581,7 +683,22 @@ static void nic_handle_mbx_intr(struct nicpf *nic, int vf)
 	case NIC_MBOX_MSG_SHUTDOWN:
 		/* First msg in VF teardown sequence */
 		nic->vf_enabled[vf] = false;
+		if (vf >= nic->num_vf_en)
+			nic->sqs_used[vf - nic->num_vf_en] = false;
+		nic->pqs_vf[vf] = 0;
+		break;
+	case NIC_MBOX_MSG_ALLOC_SQS:
+		nic_alloc_sqs(nic, &mbx.sqs_alloc);
+		goto unlock;
+	case NIC_MBOX_MSG_NICVF_PTR:
+		nic->nicvf[vf] = mbx.nicvf.nicvf;
 		break;
+	case NIC_MBOX_MSG_PNICVF_PTR:
+		nic_send_pnicvf(nic, vf);
+		goto unlock;
+	case NIC_MBOX_MSG_SNICVF_PTR:
+		nic_send_snicvf(nic, &mbx.nicvf);
+		goto unlock;
 	case NIC_MBOX_MSG_BGX_STATS:
 		nic_get_bgx_stats(nic, &mbx.bgx_stats);
 		goto unlock;
@@ -610,8 +727,7 @@ static void nic_mbx_intr_handler (struct nicpf *nic, int mbx)
 		if (intr & (1ULL << vf)) {
 			dev_dbg(&nic->pdev->dev, "Intr from VF %d\n",
 				vf + (mbx * vf_per_mbx_reg));
-			if ((vf + (mbx * vf_per_mbx_reg)) > nic->num_vf_en)
-				break;
+
 			nic_handle_mbx_intr(nic, vf + (mbx * vf_per_mbx_reg));
 			nic_clear_mbx_intr(nic, vf, mbx);
 		}
@@ -717,9 +833,24 @@ static void nic_unregister_interrupts(struct nicpf *nic)
 	nic_disable_msix(nic);
 }
 
+static int nic_num_sqs_en(struct nicpf *nic, int vf_en)
+{
+	int pos, sqs_per_vf = MAX_SQS_PER_VF_SINGLE_NODE;
+	u16 total_vf;
+
+	/* Check if its a multi-node environment */
+	if (nr_node_ids > 1)
+		sqs_per_vf = MAX_SQS_PER_VF;
+
+	pos = pci_find_ext_capability(nic->pdev, PCI_EXT_CAP_ID_SRIOV);
+	pci_read_config_word(nic->pdev, (pos + PCI_SRIOV_TOTAL_VF), &total_vf);
+	return min(total_vf - vf_en, vf_en * sqs_per_vf);
+}
+
 static int nic_sriov_init(struct pci_dev *pdev, struct nicpf *nic)
 {
 	int pos = 0;
+	int vf_en;
 	int err;
 	u16 total_vf_cnt;
 
@@ -736,16 +867,20 @@ static int nic_sriov_init(struct pci_dev *pdev, struct nicpf *nic)
 	if (!total_vf_cnt)
 		return 0;
 
-	err = pci_enable_sriov(pdev, nic->num_vf_en);
+	vf_en = nic->num_vf_en;
+	nic->num_sqs_en = nic_num_sqs_en(nic, nic->num_vf_en);
+	vf_en += nic->num_sqs_en;
+
+	err = pci_enable_sriov(pdev, vf_en);
 	if (err) {
 		dev_err(&pdev->dev, "SRIOV enable failed, num VF is %d\n",
-			nic->num_vf_en);
+			vf_en);
 		nic->num_vf_en = 0;
 		return err;
 	}
 
 	dev_info(&pdev->dev, "SRIOV enabled, number of VF available %d\n",
-		 nic->num_vf_en);
+		 vf_en);
 
 	nic->flags |= NIC_SRIOV_ENABLED;
 	return 0;
diff --git a/drivers/net/ethernet/cavium/thunder/nicvf_ethtool.c b/drivers/net/ethernet/cavium/thunder/nicvf_ethtool.c
index 1eec2cd..af54c10 100644
--- a/drivers/net/ethernet/cavium/thunder/nicvf_ethtool.c
+++ b/drivers/net/ethernet/cavium/thunder/nicvf_ethtool.c
@@ -149,10 +149,33 @@ static void nicvf_set_msglevel(struct net_device *netdev, u32 lvl)
 	nic->msg_enable = lvl;
 }
 
+static void nicvf_get_qset_strings(struct nicvf *nic, u8 **data, int qset)
+{
+	int stats, qidx;
+	int start_qidx = qset * MAX_RCV_QUEUES_PER_QS;
+
+	for (qidx = 0; qidx < nic->qs->rq_cnt; qidx++) {
+		for (stats = 0; stats < nicvf_n_queue_stats; stats++) {
+			sprintf(*data, "rxq%d: %s", qidx + start_qidx,
+				nicvf_queue_stats[stats].name);
+			*data += ETH_GSTRING_LEN;
+		}
+	}
+
+	for (qidx = 0; qidx < nic->qs->sq_cnt; qidx++) {
+		for (stats = 0; stats < nicvf_n_queue_stats; stats++) {
+			sprintf(*data, "txq%d: %s", qidx + start_qidx,
+				nicvf_queue_stats[stats].name);
+			*data += ETH_GSTRING_LEN;
+		}
+	}
+}
+
 static void nicvf_get_strings(struct net_device *netdev, u32 sset, u8 *data)
 {
 	struct nicvf *nic = netdev_priv(netdev);
-	int stats, qidx;
+	int stats;
+	int sqs;
 
 	if (sset != ETH_SS_STATS)
 		return;
@@ -167,20 +190,12 @@ static void nicvf_get_strings(struct net_device *netdev, u32 sset, u8 *data)
 		data += ETH_GSTRING_LEN;
 	}
 
-	for (qidx = 0; qidx < nic->qs->rq_cnt; qidx++) {
-		for (stats = 0; stats < nicvf_n_queue_stats; stats++) {
-			sprintf(data, "rxq%d: %s", qidx,
-				nicvf_queue_stats[stats].name);
-			data += ETH_GSTRING_LEN;
-		}
-	}
+	nicvf_get_qset_strings(nic, &data, 0);
 
-	for (qidx = 0; qidx < nic->qs->sq_cnt; qidx++) {
-		for (stats = 0; stats < nicvf_n_queue_stats; stats++) {
-			sprintf(data, "txq%d: %s", qidx,
-				nicvf_queue_stats[stats].name);
-			data += ETH_GSTRING_LEN;
-		}
+	for (sqs = 0; sqs < nic->sqs_count; sqs++) {
+		if (!nic->snicvf[sqs])
+			continue;
+		nicvf_get_qset_strings(nic->snicvf[sqs], &data, sqs + 1);
 	}
 
 	for (stats = 0; stats < BGX_RX_STATS_COUNT; stats++) {
@@ -197,21 +212,58 @@ static void nicvf_get_strings(struct net_device *netdev, u32 sset, u8 *data)
 static int nicvf_get_sset_count(struct net_device *netdev, int sset)
 {
 	struct nicvf *nic = netdev_priv(netdev);
+	int qstats_count;
+	int sqs;
 
 	if (sset != ETH_SS_STATS)
 		return -EINVAL;
 
+	qstats_count = nicvf_n_queue_stats *
+		       (nic->qs->rq_cnt + nic->qs->sq_cnt);
+	for (sqs = 0; sqs < nic->sqs_count; sqs++) {
+		struct nicvf *snic;
+
+		snic = nic->snicvf[sqs];
+		if (!snic)
+			continue;
+		qstats_count += nicvf_n_queue_stats *
+				(snic->qs->rq_cnt + snic->qs->sq_cnt);
+	}
+
 	return nicvf_n_hw_stats + nicvf_n_drv_stats +
-		(nicvf_n_queue_stats *
-		 (nic->qs->rq_cnt + nic->qs->sq_cnt)) +
+		qstats_count +
 		BGX_RX_STATS_COUNT + BGX_TX_STATS_COUNT;
 }
 
+static void nicvf_get_qset_stats(struct nicvf *nic,
+				 struct ethtool_stats *stats, u64 **data)
+{
+	int stat, qidx;
+
+	if (!nic)
+		return;
+
+	for (qidx = 0; qidx < nic->qs->rq_cnt; qidx++) {
+		nicvf_update_rq_stats(nic, qidx);
+		for (stat = 0; stat < nicvf_n_queue_stats; stat++)
+			*((*data)++) = ((u64 *)&nic->qs->rq[qidx].stats)
+					[nicvf_queue_stats[stat].index];
+	}
+
+	for (qidx = 0; qidx < nic->qs->sq_cnt; qidx++) {
+		nicvf_update_sq_stats(nic, qidx);
+		for (stat = 0; stat < nicvf_n_queue_stats; stat++)
+			*((*data)++) = ((u64 *)&nic->qs->sq[qidx].stats)
+					[nicvf_queue_stats[stat].index];
+	}
+}
+
 static void nicvf_get_ethtool_stats(struct net_device *netdev,
 				    struct ethtool_stats *stats, u64 *data)
 {
 	struct nicvf *nic = netdev_priv(netdev);
-	int stat, qidx;
+	int stat;
+	int sqs;
 
 	nicvf_update_stats(nic);
 
@@ -225,16 +277,12 @@ static void nicvf_get_ethtool_stats(struct net_device *netdev,
 		*(data++) = ((u64 *)&nic->drv_stats)
 				[nicvf_drv_stats[stat].index];
 
-	for (qidx = 0; qidx < nic->qs->rq_cnt; qidx++) {
-		for (stat = 0; stat < nicvf_n_queue_stats; stat++)
-			*(data++) = ((u64 *)&nic->qs->rq[qidx].stats)
-					[nicvf_queue_stats[stat].index];
-	}
+	nicvf_get_qset_stats(nic, stats, &data);
 
-	for (qidx = 0; qidx < nic->qs->sq_cnt; qidx++) {
-		for (stat = 0; stat < nicvf_n_queue_stats; stat++)
-			*(data++) = ((u64 *)&nic->qs->sq[qidx].stats)
-					[nicvf_queue_stats[stat].index];
+	for (sqs = 0; sqs < nic->sqs_count; sqs++) {
+		if (!nic->snicvf[sqs])
+			continue;
+		nicvf_get_qset_stats(nic->snicvf[sqs], stats, &data);
 	}
 
 	for (stat = 0; stat < BGX_RX_STATS_COUNT; stat++)
@@ -393,7 +441,7 @@ static int nicvf_get_rxnfc(struct net_device *dev,
 
 	switch (info->cmd) {
 	case ETHTOOL_GRXRINGS:
-		info->data = nic->qs->rq_cnt;
+		info->data = nic->rx_queues;
 		ret = 0;
 		break;
 	case ETHTOOL_GRXFH:
@@ -556,11 +604,11 @@ static void nicvf_get_channels(struct net_device *dev,
 
 	memset(channel, 0, sizeof(*channel));
 
-	channel->max_rx = MAX_RCV_QUEUES_PER_QS;
-	channel->max_tx = MAX_SND_QUEUES_PER_QS;
+	channel->max_rx = nic->max_queues;
+	channel->max_tx = nic->max_queues;
 
-	channel->rx_count = nic->qs->rq_cnt;
-	channel->tx_count = nic->qs->sq_cnt;
+	channel->rx_count = nic->rx_queues;
+	channel->tx_count = nic->tx_queues;
 }
 
 /* Set no of Tx, Rx queues to be used */
@@ -570,22 +618,34 @@ static int nicvf_set_channels(struct net_device *dev,
 	struct nicvf *nic = netdev_priv(dev);
 	int err = 0;
 	bool if_up = netif_running(dev);
+	int cqcount;
 
 	if (!channel->rx_count || !channel->tx_count)
 		return -EINVAL;
-	if (channel->rx_count > MAX_RCV_QUEUES_PER_QS)
+	if (channel->rx_count > nic->max_queues)
 		return -EINVAL;
-	if (channel->tx_count > MAX_SND_QUEUES_PER_QS)
+	if (channel->tx_count > nic->max_queues)
 		return -EINVAL;
 
 	if (if_up)
 		nicvf_stop(dev);
 
-	nic->qs->rq_cnt = channel->rx_count;
-	nic->qs->sq_cnt = channel->tx_count;
+	cqcount = max(channel->rx_count, channel->tx_count);
+
+	if (cqcount > MAX_CMP_QUEUES_PER_QS) {
+		nic->sqs_count = roundup(cqcount, MAX_CMP_QUEUES_PER_QS);
+		nic->sqs_count = (nic->sqs_count / MAX_CMP_QUEUES_PER_QS) - 1;
+	} else {
+		nic->sqs_count = 0;
+	}
+
+	nic->qs->rq_cnt = min_t(u32, channel->rx_count, MAX_RCV_QUEUES_PER_QS);
+	nic->qs->sq_cnt = min_t(u32, channel->tx_count, MAX_SND_QUEUES_PER_QS);
 	nic->qs->cq_cnt = max(nic->qs->rq_cnt, nic->qs->sq_cnt);
 
-	err = nicvf_set_real_num_queues(dev, nic->qs->sq_cnt, nic->qs->rq_cnt);
+	nic->rx_queues = channel->rx_count;
+	nic->tx_queues = channel->tx_count;
+	err = nicvf_set_real_num_queues(dev, nic->tx_queues, nic->rx_queues);
 	if (err)
 		return err;
 
@@ -593,7 +653,7 @@ static int nicvf_set_channels(struct net_device *dev,
 		nicvf_open(dev);
 
 	netdev_info(dev, "Setting num Tx rings to %d, Rx rings to %d success\n",
-		    nic->qs->sq_cnt, nic->qs->rq_cnt);
+		    nic->tx_queues, nic->rx_queues);
 
 	return err;
 }
diff --git a/drivers/net/ethernet/cavium/thunder/nicvf_main.c b/drivers/net/ethernet/cavium/thunder/nicvf_main.c
index 85213f3..68b2dce 100644
--- a/drivers/net/ethernet/cavium/thunder/nicvf_main.c
+++ b/drivers/net/ethernet/cavium/thunder/nicvf_main.c
@@ -51,6 +51,14 @@ module_param(cpi_alg, int, S_IRUGO);
 MODULE_PARM_DESC(cpi_alg,
 		 "PFC algorithm (0=none, 1=VLAN, 2=VLAN16, 3=IP Diffserv)");
 
+static inline u8 nicvf_netdev_qidx(struct nicvf *nic, u8 qidx)
+{
+	if (nic->sqs_mode)
+		return qidx + ((nic->sqs_id + 1) * MAX_CMP_QUEUES_PER_QS);
+	else
+		return qidx;
+}
+
 static inline void nicvf_set_rx_frame_cnt(struct nicvf *nic,
 					  struct sk_buff *skb)
 {
@@ -193,6 +201,7 @@ static void  nicvf_handle_mbx_intr(struct nicvf *nic)
 		if (!nic->set_mac_pending)
 			ether_addr_copy(nic->netdev->dev_addr,
 					mbx.nic_cfg.mac_addr);
+		nic->sqs_mode = mbx.nic_cfg.sqs_mode;
 		nic->link_up = false;
 		nic->duplex = 0;
 		nic->speed = 0;
@@ -230,6 +239,26 @@ static void  nicvf_handle_mbx_intr(struct nicvf *nic)
 			netif_tx_stop_all_queues(nic->netdev);
 		}
 		break;
+	case NIC_MBOX_MSG_ALLOC_SQS:
+		nic->sqs_count = mbx.sqs_alloc.qs_count;
+		nic->pf_acked = true;
+		break;
+	case NIC_MBOX_MSG_SNICVF_PTR:
+		/* Primary VF: make note of secondary VF's pointer
+		 * to be used while packet transmission.
+		 */
+		nic->snicvf[mbx.nicvf.sqs_id] =
+			(struct nicvf *)mbx.nicvf.nicvf;
+		nic->pf_acked = true;
+		break;
+	case NIC_MBOX_MSG_PNICVF_PTR:
+		/* Secondary VF/Qset: make note of primary VF's pointer
+		 * to be used while packet reception, to handover packet
+		 * to primary VF's netdev.
+		 */
+		nic->pnicvf = (struct nicvf *)mbx.nicvf.nicvf;
+		nic->pf_acked = true;
+		break;
 	default:
 		netdev_err(nic->netdev,
 			   "Invalid message from PF, msg 0x%x\n", mbx.msg.msg);
@@ -338,11 +367,100 @@ static int nicvf_rss_init(struct nicvf *nic)
 
 	for (idx = 0; idx < rss->rss_size; idx++)
 		rss->ind_tbl[idx] = ethtool_rxfh_indir_default(idx,
-							       nic->qs->rq_cnt);
+							       nic->rx_queues);
 	nicvf_config_rss(nic);
 	return 1;
 }
 
+/* Request PF to allocate additional Qsets */
+static void nicvf_request_sqs(struct nicvf *nic)
+{
+	union nic_mbx mbx = {};
+	int sqs;
+	int sqs_count = nic->sqs_count;
+	int rx_queues = 0, tx_queues = 0;
+
+	/* Only primary VF should request */
+	if (nic->sqs_mode ||  !nic->sqs_count)
+		return;
+
+	mbx.sqs_alloc.msg = NIC_MBOX_MSG_ALLOC_SQS;
+	mbx.sqs_alloc.vf_id = nic->vf_id;
+	mbx.sqs_alloc.qs_count = nic->sqs_count;
+	if (nicvf_send_msg_to_pf(nic, &mbx)) {
+		/* No response from PF */
+		nic->sqs_count = 0;
+		return;
+	}
+
+	/* Return if no Secondary Qsets available */
+	if (!nic->sqs_count)
+		return;
+
+	if (nic->rx_queues > MAX_RCV_QUEUES_PER_QS)
+		rx_queues = nic->rx_queues - MAX_RCV_QUEUES_PER_QS;
+	if (nic->tx_queues > MAX_SND_QUEUES_PER_QS)
+		tx_queues = nic->tx_queues - MAX_SND_QUEUES_PER_QS;
+
+	/* Set no of Rx/Tx queues in each of the SQsets */
+	for (sqs = 0; sqs < nic->sqs_count; sqs++) {
+		mbx.nicvf.msg = NIC_MBOX_MSG_SNICVF_PTR;
+		mbx.nicvf.vf_id = nic->vf_id;
+		mbx.nicvf.sqs_id = sqs;
+		nicvf_send_msg_to_pf(nic, &mbx);
+
+		nic->snicvf[sqs]->sqs_id = sqs;
+		if (rx_queues > MAX_RCV_QUEUES_PER_QS) {
+			nic->snicvf[sqs]->qs->rq_cnt = MAX_RCV_QUEUES_PER_QS;
+			rx_queues -= MAX_RCV_QUEUES_PER_QS;
+		} else {
+			nic->snicvf[sqs]->qs->rq_cnt = rx_queues;
+			rx_queues = 0;
+		}
+
+		if (tx_queues > MAX_SND_QUEUES_PER_QS) {
+			nic->snicvf[sqs]->qs->sq_cnt = MAX_SND_QUEUES_PER_QS;
+			tx_queues -= MAX_SND_QUEUES_PER_QS;
+		} else {
+			nic->snicvf[sqs]->qs->sq_cnt = tx_queues;
+			tx_queues = 0;
+		}
+
+		nic->snicvf[sqs]->qs->cq_cnt =
+		max(nic->snicvf[sqs]->qs->rq_cnt, nic->snicvf[sqs]->qs->sq_cnt);
+
+		/* Initialize secondary Qset's queues and its interrupts */
+		nicvf_open(nic->snicvf[sqs]->netdev);
+	}
+
+	/* Update stack with actual Rx/Tx queue count allocated */
+	if (sqs_count != nic->sqs_count)
+		nicvf_set_real_num_queues(nic->netdev,
+					  nic->tx_queues, nic->rx_queues);
+}
+
+/* Send this Qset's nicvf pointer to PF.
+ * PF inturn sends primary VF's nicvf struct to secondary Qsets/VFs
+ * so that packets received by these Qsets can use primary VF's netdev
+ */
+static void nicvf_send_vf_struct(struct nicvf *nic)
+{
+	union nic_mbx mbx = {};
+
+	mbx.nicvf.msg = NIC_MBOX_MSG_NICVF_PTR;
+	mbx.nicvf.sqs_mode = nic->sqs_mode;
+	mbx.nicvf.nicvf = (u64)nic;
+	nicvf_send_msg_to_pf(nic, &mbx);
+}
+
+static void nicvf_get_primary_vf_struct(struct nicvf *nic)
+{
+	union nic_mbx mbx = {};
+
+	mbx.nicvf.msg = NIC_MBOX_MSG_PNICVF_PTR;
+	nicvf_send_msg_to_pf(nic, &mbx);
+}
+
 int nicvf_set_real_num_queues(struct net_device *netdev,
 			      int tx_queues, int rx_queues)
 {
@@ -453,6 +571,15 @@ static void nicvf_rcv_pkt_handler(struct net_device *netdev,
 	struct sk_buff *skb;
 	struct nicvf *nic = netdev_priv(netdev);
 	int err = 0;
+	int rq_idx;
+
+	rq_idx = nicvf_netdev_qidx(nic, cqe_rx->rq_idx);
+
+	if (nic->sqs_mode) {
+		/* Use primary VF's 'nicvf' struct */
+		nic = nic->pnicvf;
+		netdev = nic->netdev;
+	}
 
 	/* Check for errors */
 	err = nicvf_check_cqe_rx_errs(nic, cq, cqe_rx);
@@ -482,7 +609,7 @@ static void nicvf_rcv_pkt_handler(struct net_device *netdev,
 
 	nicvf_set_rxhash(netdev, cqe_rx, skb);
 
-	skb_record_rx_queue(skb, cqe_rx->rq_idx);
+	skb_record_rx_queue(skb, rq_idx);
 	if (netdev->hw_features & NETIF_F_RXCSUM) {
 		/* HW by default verifies TCP/UDP/SCTP checksums */
 		skb->ip_summed = CHECKSUM_UNNECESSARY;
@@ -578,8 +705,11 @@ loop:
 done:
 	/* Wakeup TXQ if its stopped earlier due to SQ full */
 	if (tx_done) {
-		txq = netdev_get_tx_queue(netdev, cq_idx);
-		if (netif_tx_queue_stopped(txq)) {
+		netdev = nic->pnicvf->netdev;
+		txq = netdev_get_tx_queue(netdev,
+					  nicvf_netdev_qidx(nic, cq_idx));
+		nic = nic->pnicvf;
+		if (netif_tx_queue_stopped(txq) && netif_carrier_ok(netdev)) {
 			netif_tx_start_queue(txq);
 			nic->drv_stats.txq_wake++;
 			if (netif_msg_tx_err(nic))
@@ -893,7 +1023,6 @@ static netdev_tx_t nicvf_xmit(struct sk_buff *skb, struct net_device *netdev)
 			netdev_warn(netdev,
 				    "%s: Transmit ring full, stopping SQ%d\n",
 				    netdev->name, qid);
-
 		return NETDEV_TX_BUSY;
 	}
 
@@ -926,6 +1055,17 @@ int nicvf_stop(struct net_device *netdev)
 	nicvf_send_msg_to_pf(nic, &mbx);
 
 	netif_carrier_off(netdev);
+	netif_tx_stop_all_queues(nic->netdev);
+
+	/* Teardown secondary qsets first */
+	if (!nic->sqs_mode) {
+		for (qidx = 0; qidx < nic->sqs_count; qidx++) {
+			if (!nic->snicvf[qidx])
+				continue;
+			nicvf_stop(nic->snicvf[qidx]->netdev);
+			nic->snicvf[qidx] = NULL;
+		}
+	}
 
 	/* Disable RBDR & QS error interrupts */
 	for (qidx = 0; qidx < qs->rbdr_cnt; qidx++) {
@@ -973,6 +1113,10 @@ int nicvf_stop(struct net_device *netdev)
 
 	nicvf_free_cq_poll(nic);
 
+	/* Clear multiqset info */
+	nic->pnicvf = nic;
+	nic->sqs_count = 0;
+
 	return 0;
 }
 
@@ -1028,10 +1172,16 @@ int nicvf_open(struct net_device *netdev)
 
 	/* Configure CPI alorithm */
 	nic->cpi_alg = cpi_alg;
-	nicvf_config_cpi(nic);
+	if (!nic->sqs_mode)
+		nicvf_config_cpi(nic);
+
+	nicvf_request_sqs(nic);
+	if (nic->sqs_mode)
+		nicvf_get_primary_vf_struct(nic);
 
 	/* Configure receive side scaling */
-	nicvf_rss_init(nic);
+	if (!nic->sqs_mode)
+		nicvf_rss_init(nic);
 
 	err = nicvf_register_interrupts(nic);
 	if (err)
@@ -1282,8 +1432,7 @@ static int nicvf_probe(struct pci_dev *pdev, const struct pci_device_id *ent)
 	struct device *dev = &pdev->dev;
 	struct net_device *netdev;
 	struct nicvf *nic;
-	struct queue_set *qs;
-	int    err;
+	int    err, qcount;
 
 	err = pci_enable_device(pdev);
 	if (err) {
@@ -1309,9 +1458,17 @@ static int nicvf_probe(struct pci_dev *pdev, const struct pci_device_id *ent)
 		goto err_release_regions;
 	}
 
-	netdev = alloc_etherdev_mqs(sizeof(struct nicvf),
-				    MAX_RCV_QUEUES_PER_QS,
-				    MAX_SND_QUEUES_PER_QS);
+	qcount = MAX_CMP_QUEUES_PER_QS;
+
+	/* Restrict multiqset support only for host bound VFs */
+	if (pdev->is_virtfn) {
+		/* Set max number of queues per VF */
+		qcount = roundup(num_online_cpus(), MAX_CMP_QUEUES_PER_QS);
+		qcount = min(qcount,
+			     (MAX_SQS_PER_VF + 1) * MAX_CMP_QUEUES_PER_QS);
+	}
+
+	netdev = alloc_etherdev_mqs(sizeof(struct nicvf), qcount, qcount);
 	if (!netdev) {
 		err = -ENOMEM;
 		goto err_release_regions;
@@ -1324,6 +1481,8 @@ static int nicvf_probe(struct pci_dev *pdev, const struct pci_device_id *ent)
 	nic = netdev_priv(netdev);
 	nic->netdev = netdev;
 	nic->pdev = pdev;
+	nic->pnicvf = nic;
+	nic->max_queues = qcount;
 
 	/* MAP VF's configuration registers */
 	nic->reg_base = pcim_iomap(pdev, PCI_CFG_REG_BAR_NUM, 0);
@@ -1337,20 +1496,26 @@ static int nicvf_probe(struct pci_dev *pdev, const struct pci_device_id *ent)
 	if (err)
 		goto err_free_netdev;
 
-	qs = nic->qs;
-
-	err = nicvf_set_real_num_queues(netdev, qs->sq_cnt, qs->rq_cnt);
-	if (err)
-		goto err_free_netdev;
-
 	/* Check if PF is alive and get MAC address for this VF */
 	err = nicvf_register_misc_interrupt(nic);
 	if (err)
 		goto err_free_netdev;
 
+	nicvf_send_vf_struct(nic);
+
+	/* Check if this VF is in QS only mode */
+	if (nic->sqs_mode)
+		return 0;
+
+	err = nicvf_set_real_num_queues(netdev, nic->tx_queues, nic->rx_queues);
+	if (err)
+		goto err_unregister_interrupts;
+
 	netdev->hw_features = (NETIF_F_RXCSUM | NETIF_F_IP_CSUM | NETIF_F_SG |
 			       NETIF_F_TSO | NETIF_F_GRO |
-			       NETIF_F_HW_VLAN_CTAG_RX | NETIF_F_RXHASH);
+			       NETIF_F_HW_VLAN_CTAG_RX);
+
+	netdev->hw_features |= NETIF_F_RXHASH;
 
 	netdev->features |= netdev->hw_features;
 
@@ -1389,8 +1554,13 @@ static void nicvf_remove(struct pci_dev *pdev)
 {
 	struct net_device *netdev = pci_get_drvdata(pdev);
 	struct nicvf *nic = netdev_priv(netdev);
+	struct net_device *pnetdev = nic->pnicvf->netdev;
 
-	unregister_netdev(netdev);
+	/* Check if this Qset is assigned to different VF.
+	 * If yes, clean primary and all secondary Qsets.
+	 */
+	if (pnetdev && (pnetdev->reg_state == NETREG_REGISTERED))
+		unregister_netdev(pnetdev);
 	nicvf_unregister_interrupts(nic);
 	pci_set_drvdata(pdev, NULL);
 	free_netdev(netdev);
diff --git a/drivers/net/ethernet/cavium/thunder/nicvf_queues.c b/drivers/net/ethernet/cavium/thunder/nicvf_queues.c
index b294d67..e404ea8 100644
--- a/drivers/net/ethernet/cavium/thunder/nicvf_queues.c
+++ b/drivers/net/ethernet/cavium/thunder/nicvf_queues.c
@@ -621,6 +621,7 @@ static void nicvf_snd_queue_config(struct nicvf *nic, struct queue_set *qs,
 	mbx.sq.msg = NIC_MBOX_MSG_SQ_CFG;
 	mbx.sq.qs_num = qs->vnic_id;
 	mbx.sq.sq_num = qidx;
+	mbx.sq.sqs_mode = nic->sqs_mode;
 	mbx.sq.cfg = (sq->cq_qs << 3) | sq->cq_idx;
 	nicvf_send_msg_to_pf(nic, &mbx);
 
@@ -702,6 +703,7 @@ void nicvf_qset_config(struct nicvf *nic, bool enable)
 	/* Send a mailbox msg to PF to config Qset */
 	mbx.qs.msg = NIC_MBOX_MSG_QS_CFG;
 	mbx.qs.num = qs->vnic_id;
+	mbx.qs.sqs_count = nic->sqs_count;
 
 	mbx.qs.cfg = 0;
 	qs_cfg = (struct qs_cfg *)&mbx.qs.cfg;
@@ -782,6 +784,10 @@ int nicvf_set_qset_resources(struct nicvf *nic)
 	qs->rbdr_len = RCV_BUF_COUNT;
 	qs->sq_len = SND_QUEUE_LEN;
 	qs->cq_len = CMP_QUEUE_LEN;
+
+	nic->rx_queues = qs->rq_cnt;
+	nic->tx_queues = qs->sq_cnt;
+
 	return 0;
 }
 
@@ -1025,7 +1031,7 @@ static inline void nicvf_sq_add_gather_subdesc(struct snd_queue *sq, int qentry,
  * them to SQ for transfer
  */
 static int nicvf_sq_append_tso(struct nicvf *nic, struct snd_queue *sq,
-			       int qentry, struct sk_buff *skb)
+			       int sq_num, int qentry, struct sk_buff *skb)
 {
 	struct tso_t tso;
 	int seg_subdescs = 0, desc_cnt = 0;
@@ -1085,7 +1091,7 @@ static int nicvf_sq_append_tso(struct nicvf *nic, struct snd_queue *sq,
 
 	/* Inform HW to xmit all TSO segments */
 	nicvf_queue_reg_write(nic, NIC_QSET_SQ_0_7_DOOR,
-			      skb_get_queue_mapping(skb), desc_cnt);
+			      sq_num, desc_cnt);
 	nic->drv_stats.tx_tso++;
 	return 1;
 }
@@ -1096,10 +1102,24 @@ int nicvf_sq_append_skb(struct nicvf *nic, struct sk_buff *skb)
 	int i, size;
 	int subdesc_cnt;
 	int sq_num, qentry;
-	struct queue_set *qs = nic->qs;
+	struct queue_set *qs;
 	struct snd_queue *sq;
 
 	sq_num = skb_get_queue_mapping(skb);
+	if (sq_num >= MAX_SND_QUEUES_PER_QS) {
+		/* Get secondary Qset's SQ structure */
+		i = sq_num / MAX_SND_QUEUES_PER_QS;
+		if (!nic->snicvf[i - 1]) {
+			netdev_warn(nic->netdev,
+				    "Secondary Qset#%d's ptr not initialized\n",
+				    i - 1);
+			return 1;
+		}
+		nic = (struct nicvf *)nic->snicvf[i - 1];
+		sq_num = sq_num % MAX_SND_QUEUES_PER_QS;
+	}
+
+	qs = nic->qs;
 	sq = &qs->sq[sq_num];
 
 	subdesc_cnt = nicvf_sq_subdesc_required(nic, skb);
@@ -1110,7 +1130,7 @@ int nicvf_sq_append_skb(struct nicvf *nic, struct sk_buff *skb)
 
 	/* Check if its a TSO packet */
 	if (skb_shinfo(skb)->gso_size)
-		return nicvf_sq_append_tso(nic, sq, qentry, skb);
+		return nicvf_sq_append_tso(nic, sq, sq_num, qentry, skb);
 
 	/* Add SQ header subdesc */
 	nicvf_sq_add_hdr_subdesc(sq, qentry, subdesc_cnt - 1, skb, skb->len);
@@ -1146,6 +1166,8 @@ doorbell:
 	return 1;
 
 append_fail:
+	/* Use original PCI dev for debug log */
+	nic = nic->pnicvf;
 	netdev_dbg(nic->netdev, "Not enough SQ descriptors to xmit pkt\n");
 	return 0;
 }
-- 
2.5.0



From aleksey.makarov at auriga.com  Sun Aug 30 02:29:16 2015
From: aleksey.makarov at auriga.com (Aleksey Makarov)
Date: Sun, 30 Aug 2015 12:29:16 +0300
Subject: [PATCH net-next v2 8/8] net: thunderx: Support for internal loopback
 mode
In-Reply-To: <1440926958-1874-1-git-send-email-aleksey.makarov@auriga.com>
References: <1440926958-1874-1-git-send-email-aleksey.makarov@auriga.com>
Message-ID: <1440926958-1874-9-git-send-email-aleksey.makarov@auriga.com>

From: Sunil Goutham <sgoutham at cavium.com>

Support for setting VF's corresponding BGX LMAC in internal
loopback mode. This mode can be used for verifying basic HW
functionality such as packet I/O, RX checksum validation,
CQ/RBDR interrupts, stats e.t.c. Useful when DUT has no external
network connectivity.

'loopback' mode can be enabled or disabled via ethtool.

Note: This feature is not supported when no of VFs enabled are
morethan no of physical interfaces i.e active BGX LMACs

Signed-off-by: Sunil Goutham <sgoutham at cavium.com>
Signed-off-by: Aleksey Makarov <aleksey.makarov at caviumnetworks.com>
---
 drivers/net/ethernet/cavium/thunder/nic.h         | 11 ++++++++
 drivers/net/ethernet/cavium/thunder/nic_main.c    | 21 +++++++++++++++
 drivers/net/ethernet/cavium/thunder/nicvf_main.c  | 30 ++++++++++++++++++++++
 drivers/net/ethernet/cavium/thunder/thunder_bgx.c | 31 +++++++++++++++++++++++
 drivers/net/ethernet/cavium/thunder/thunder_bgx.h |  4 +++
 5 files changed, 97 insertions(+)

diff --git a/drivers/net/ethernet/cavium/thunder/nic.h b/drivers/net/ethernet/cavium/thunder/nic.h
index 35b2ee1..d3950b2 100644
--- a/drivers/net/ethernet/cavium/thunder/nic.h
+++ b/drivers/net/ethernet/cavium/thunder/nic.h
@@ -265,6 +265,7 @@ struct nicvf {
 	u8			node;
 	u8			tns_mode:1;
 	u8			sqs_mode:1;
+	u8			loopback_supported:1;
 	u16			mtu;
 	struct queue_set	*qs;
 #define	MAX_SQS_PER_VF_SINGLE_NODE		5
@@ -344,6 +345,7 @@ struct nicvf {
 #define	NIC_MBOX_MSG_NICVF_PTR		0x13	/* Send nicvf ptr to PF */
 #define	NIC_MBOX_MSG_PNICVF_PTR		0x14	/* Get primary qset nicvf ptr */
 #define	NIC_MBOX_MSG_SNICVF_PTR		0x15	/* Send sqet nicvf ptr to PVF */
+#define	NIC_MBOX_MSG_LOOPBACK		0x16	/* Set interface in loopback */
 #define	NIC_MBOX_MSG_CFG_DONE		0xF0	/* VF configuration done */
 #define	NIC_MBOX_MSG_SHUTDOWN		0xF1	/* VF is being shutdown */
 
@@ -353,6 +355,7 @@ struct nic_cfg_msg {
 	u8    node_id;
 	u8    tns_mode:1;
 	u8    sqs_mode:1;
+	u8    loopback_supported:1;
 	u8    mac_addr[ETH_ALEN];
 };
 
@@ -452,6 +455,13 @@ struct nicvf_ptr {
 	u64   nicvf;
 };
 
+/* Set interface in loopback mode */
+struct set_loopback {
+	u8    msg;
+	u8    vf_id;
+	bool  enable;
+};
+
 /* 128 bit shared memory between PF and each VF */
 union nic_mbx {
 	struct { u8 msg; }	msg;
@@ -468,6 +478,7 @@ union nic_mbx {
 	struct bgx_link_status  link_status;
 	struct sqs_alloc        sqs_alloc;
 	struct nicvf_ptr	nicvf;
+	struct set_loopback	lbk;
 };
 
 #define NIC_NODE_ID_MASK	0x03
diff --git a/drivers/net/ethernet/cavium/thunder/nic_main.c b/drivers/net/ethernet/cavium/thunder/nic_main.c
index dac8094..b3a5947 100644
--- a/drivers/net/ethernet/cavium/thunder/nic_main.c
+++ b/drivers/net/ethernet/cavium/thunder/nic_main.c
@@ -154,6 +154,9 @@ static void nic_mbx_send_ready(struct nicpf *nic, int vf)
 	}
 	mbx.nic_cfg.sqs_mode = (vf >= nic->num_vf_en) ? true : false;
 	mbx.nic_cfg.node_id = nic->node;
+
+	mbx.nic_cfg.loopback_supported = vf < MAX_LMAC;
+
 	nic_send_msg_to_vf(nic, vf, &mbx);
 }
 
@@ -579,6 +582,21 @@ send_mbox:
 	nic_send_msg_to_vf(nic, sqs->vf_id, &mbx);
 }
 
+static int nic_config_loopback(struct nicpf *nic, struct set_loopback *lbk)
+{
+	int bgx_idx, lmac_idx;
+
+	if (lbk->vf_id > MAX_LMAC)
+		return -1;
+
+	bgx_idx = NIC_GET_BGX_FROM_VF_LMAC_MAP(nic->vf_lmac_map[lbk->vf_id]);
+	lmac_idx = NIC_GET_LMAC_FROM_VF_LMAC_MAP(nic->vf_lmac_map[lbk->vf_id]);
+
+	bgx_lmac_internal_loopback(nic->node, bgx_idx, lmac_idx, lbk->enable);
+
+	return 0;
+}
+
 /* Interrupt handler to handle mailbox messages from VFs */
 static void nic_handle_mbx_intr(struct nicpf *nic, int vf)
 {
@@ -702,6 +720,9 @@ static void nic_handle_mbx_intr(struct nicpf *nic, int vf)
 	case NIC_MBOX_MSG_BGX_STATS:
 		nic_get_bgx_stats(nic, &mbx.bgx_stats);
 		goto unlock;
+	case NIC_MBOX_MSG_LOOPBACK:
+		ret = nic_config_loopback(nic, &mbx.lbk);
+		break;
 	default:
 		dev_err(&nic->pdev->dev,
 			"Invalid msg from VF%d, msg 0x%x\n", vf, mbx.msg.msg);
diff --git a/drivers/net/ethernet/cavium/thunder/nicvf_main.c b/drivers/net/ethernet/cavium/thunder/nicvf_main.c
index 68b2dce..b63e579 100644
--- a/drivers/net/ethernet/cavium/thunder/nicvf_main.c
+++ b/drivers/net/ethernet/cavium/thunder/nicvf_main.c
@@ -202,6 +202,7 @@ static void  nicvf_handle_mbx_intr(struct nicvf *nic)
 			ether_addr_copy(nic->netdev->dev_addr,
 					mbx.nic_cfg.mac_addr);
 		nic->sqs_mode = mbx.nic_cfg.sqs_mode;
+		nic->loopback_supported = mbx.nic_cfg.loopback_supported;
 		nic->link_up = false;
 		nic->duplex = 0;
 		nic->speed = 0;
@@ -1404,6 +1405,30 @@ static void nicvf_reset_task(struct work_struct *work)
 	nic->netdev->trans_start = jiffies;
 }
 
+static int nicvf_config_loopback(struct nicvf *nic,
+				 netdev_features_t features)
+{
+	union nic_mbx mbx = {};
+
+	mbx.lbk.msg = NIC_MBOX_MSG_LOOPBACK;
+	mbx.lbk.vf_id = nic->vf_id;
+	mbx.lbk.enable = (features & NETIF_F_LOOPBACK) != 0;
+
+	return nicvf_send_msg_to_pf(nic, &mbx);
+}
+
+static netdev_features_t nicvf_fix_features(struct net_device *netdev,
+					    netdev_features_t features)
+{
+	struct nicvf *nic = netdev_priv(netdev);
+
+	if ((features & NETIF_F_LOOPBACK) &&
+	    netif_running(netdev) && !nic->loopback_supported)
+		features &= ~NETIF_F_LOOPBACK;
+
+	return features;
+}
+
 static int nicvf_set_features(struct net_device *netdev,
 			      netdev_features_t features)
 {
@@ -1413,6 +1438,9 @@ static int nicvf_set_features(struct net_device *netdev,
 	if (changed & NETIF_F_HW_VLAN_CTAG_RX)
 		nicvf_config_vlan_stripping(nic, features);
 
+	if ((changed & NETIF_F_LOOPBACK) && netif_running(netdev))
+		return nicvf_config_loopback(nic, features);
+
 	return 0;
 }
 
@@ -1424,6 +1452,7 @@ static const struct net_device_ops nicvf_netdev_ops = {
 	.ndo_set_mac_address	= nicvf_set_mac_address,
 	.ndo_get_stats64	= nicvf_get_stats64,
 	.ndo_tx_timeout         = nicvf_tx_timeout,
+	.ndo_fix_features       = nicvf_fix_features,
 	.ndo_set_features       = nicvf_set_features,
 };
 
@@ -1518,6 +1547,7 @@ static int nicvf_probe(struct pci_dev *pdev, const struct pci_device_id *ent)
 	netdev->hw_features |= NETIF_F_RXHASH;
 
 	netdev->features |= netdev->hw_features;
+	netdev->hw_features |= NETIF_F_LOOPBACK;
 
 	netdev->vlan_features = NETIF_F_SG | NETIF_F_IP_CSUM | NETIF_F_TSO;
 
diff --git a/drivers/net/ethernet/cavium/thunder/thunder_bgx.c b/drivers/net/ethernet/cavium/thunder/thunder_bgx.c
index 5e54186..574c492 100644
--- a/drivers/net/ethernet/cavium/thunder/thunder_bgx.c
+++ b/drivers/net/ethernet/cavium/thunder/thunder_bgx.c
@@ -329,6 +329,37 @@ static void bgx_flush_dmac_addrs(struct bgx *bgx, int lmac)
 	}
 }
 
+/* Configure BGX LMAC in internal loopback mode */
+void bgx_lmac_internal_loopback(int node, int bgx_idx,
+				int lmac_idx, bool enable)
+{
+	struct bgx *bgx;
+	struct lmac *lmac;
+	u64    cfg;
+
+	bgx = bgx_vnic[(node * MAX_BGX_PER_CN88XX) + bgx_idx];
+	if (!bgx)
+		return;
+
+	lmac = &bgx->lmac[lmac_idx];
+	if (lmac->is_sgmii) {
+		cfg = bgx_reg_read(bgx, lmac_idx, BGX_GMP_PCS_MRX_CTL);
+		if (enable)
+			cfg |= PCS_MRX_CTL_LOOPBACK1;
+		else
+			cfg &= ~PCS_MRX_CTL_LOOPBACK1;
+		bgx_reg_write(bgx, lmac_idx, BGX_GMP_PCS_MRX_CTL, cfg);
+	} else {
+		cfg = bgx_reg_read(bgx, lmac_idx, BGX_SPUX_CONTROL1);
+		if (enable)
+			cfg |= SPU_CTL_LOOPBACK;
+		else
+			cfg &= ~SPU_CTL_LOOPBACK;
+		bgx_reg_write(bgx, lmac_idx, BGX_SPUX_CONTROL1, cfg);
+	}
+}
+EXPORT_SYMBOL(bgx_lmac_internal_loopback);
+
 static int bgx_lmac_sgmii_init(struct bgx *bgx, int lmacid)
 {
 	u64 cfg;
diff --git a/drivers/net/ethernet/cavium/thunder/thunder_bgx.h b/drivers/net/ethernet/cavium/thunder/thunder_bgx.h
index ba4f53b..07b7ec6 100644
--- a/drivers/net/ethernet/cavium/thunder/thunder_bgx.h
+++ b/drivers/net/ethernet/cavium/thunder/thunder_bgx.h
@@ -72,6 +72,7 @@
 
 #define BGX_SPUX_CONTROL1		0x10000
 #define  SPU_CTL_LOW_POWER			BIT_ULL(11)
+#define  SPU_CTL_LOOPBACK			BIT_ULL(14)
 #define  SPU_CTL_RESET				BIT_ULL(15)
 #define BGX_SPUX_STATUS1		0x10008
 #define  SPU_STATUS1_RCV_LNK			BIT_ULL(2)
@@ -126,6 +127,7 @@
 #define	 PCS_MRX_CTL_RST_AN			BIT_ULL(9)
 #define	 PCS_MRX_CTL_PWR_DN			BIT_ULL(11)
 #define	 PCS_MRX_CTL_AN_EN			BIT_ULL(12)
+#define	 PCS_MRX_CTL_LOOPBACK1			BIT_ULL(14)
 #define	 PCS_MRX_CTL_RESET			BIT_ULL(15)
 #define BGX_GMP_PCS_MRX_STATUS		0x30008
 #define	 PCS_MRX_STATUS_AN_CPT			BIT_ULL(5)
@@ -186,6 +188,8 @@ int bgx_get_lmac_count(int node, int bgx);
 const u8 *bgx_get_lmac_mac(int node, int bgx_idx, int lmacid);
 void bgx_set_lmac_mac(int node, int bgx_idx, int lmacid, const u8 *mac);
 void bgx_get_lmac_link_state(int node, int bgx_idx, int lmacid, void *status);
+void bgx_lmac_internal_loopback(int node, int bgx_idx,
+				int lmac_idx, bool enable);
 u64 bgx_get_rx_stats(int node, int bgx_idx, int lmac, int idx);
 u64 bgx_get_tx_stats(int node, int bgx_idx, int lmac, int idx);
 #define BGX_RX_STATS_COUNT 11
-- 
2.5.0



From romain.perier at gmail.com  Sun Aug 30 05:16:15 2015
From: romain.perier at gmail.com (Romain Perier)
Date: Sun, 30 Aug 2015 14:16:15 +0200
Subject: [PATCH v3 0/14] Add Analogix Core Display Port Driver
In-Reply-To: <20150821131631.GC22118@ulmo.nvidia.com>
References: <1439995728-18046-1-git-send-email-ykk@rock-chips.com>
 <105A0032-83A0-4B75-AE94-258F12451670@gmail.com>
 <55D6F6F8.70504@rock-chips.com>
 <8384E112-E1F4-4CD3-85BF-A2A25989783F@gmail.com>
 <20150821131631.GC22118@ulmo.nvidia.com>
Message-ID: <CABgxDoKcsRye43pqzZC=4A=D1+iDj5Bmy9XZjx+K8ekca0=FwQ@mail.gmail.com>

Hi,

Could you rebase your serie onto linux-next or 4.2-rc8 ? it does not
apply here...

Regards,
Romain

2015-08-21 15:16 GMT+02:00 Thierry Reding <treding at nvidia.com>:
> On Fri, Aug 21, 2015 at 08:24:16PM +0900, Jingoo Han wrote:
>> On 2015. 8. 21., at PM 7:01, Yakir Yang <ykk at rock-chips.com> wrote:
>> >
>> > Hi Jingoo,
>> >
>> >> ? 2015/8/21 16:20, Jingoo Han ??:
>> >>> On 2015. 8. 19., at PM 11:48, Yakir Yang <ykk at rock-chips.com> wrote:
>> >>
>> >> .....
>> >>
>> >>> .../bindings/video/analogix_dp-rockchip.txt        |   83 ++
>> >>> .../devicetree/bindings/video/exynos_dp.txt        |   51 +-
>> >>> arch/arm/boot/dts/exynos5250-arndale.dts           |   10 +-
>> >>> arch/arm/boot/dts/exynos5250-smdk5250.dts          |   10 +-
>> >>> arch/arm/boot/dts/exynos5250-snow.dts              |   12 +-
>> >>> arch/arm/boot/dts/exynos5250-spring.dts            |   12 +-
>> >>> arch/arm/boot/dts/exynos5420-peach-pit.dts         |   12 +-
>> >>> arch/arm/boot/dts/exynos5420-smdk5420.dts          |   10 +-
>> >>> arch/arm/boot/dts/exynos5800-peach-pi.dts          |   12 +-
>> >>> drivers/gpu/drm/bridge/Kconfig                     |    5 +
>> >>> drivers/gpu/drm/bridge/Makefile                    |    1 +
>> >>> drivers/gpu/drm/bridge/analogix_dp_core.c          | 1382 +++++++++++++++++++
>> >>> drivers/gpu/drm/bridge/analogix_dp_core.h          |  286 ++++
>> >>> drivers/gpu/drm/bridge/analogix_dp_reg.c           | 1294 ++++++++++++++++++
>> >>> .../exynos_dp_reg.h => bridge/analogix_dp_reg.h}   |  270 ++--
>> >>> drivers/gpu/drm/exynos/Kconfig                     |    5 +-
>> >>> drivers/gpu/drm/exynos/Makefile                    |    2 +-
>> >>> drivers/gpu/drm/exynos/analogix_dp-exynos.c        |  347 +++++
>> >> Would you change this file name to "exynos_dp.c"?
>> >
>> > Sorry, I don't think so  ;(
>> >
>> > I think IP_name+Soc_name would be better in this re-use case.
>>
>> So? Is there the naming rule such as "IP_name+SoC_name"?
>>
>> > Beside I see
>> > there are lots of driver named with this format in kernel, such as dw_hdmi & dw_mmc
>>
>> Please look at other dw cases.
>> For example, look at dw_pcie.
>>
>> drivers/pci/host/
>> pcie-designware.c
>> pci-spear13xx.c
>> pci-exynos.c
>>
>> In this case, pci-spear13xx.c and pci-exynos.c do not use "IP_name+SoC_name", even though these are dw IPs.
>>
>> Also, naming consistency is more important.
>> Now, Exynos DRM files are using "exynos_drm_" prefix.
>>
>> drivers/gpu/drm/exynos/
>> exynos_drm_buf.c
>> exynos_drm_core.c
>> ....
>>
>> However, "analogix_dp-exynos.c" looks very inconsistent.
>>
>> If there is no strict naming rule, please use "exynos_dp.c"
>> or "exynos_drm_dp.c".
>
> Exynos DRM maintainers get to pick their filenames, so Yakir, please
> rename as Jingoo suggested.
>
> Even if you didn't the first thing that would go into the Exynos DRM
> driver tree after this is merged is a rename patch anyway.
>
> Thierry


From hanjun.guo at linaro.org  Sun Aug 30 06:15:56 2015
From: hanjun.guo at linaro.org (Hanjun Guo)
Date: Sun, 30 Aug 2015 21:15:56 +0800
Subject: [PATCH] arm64: fix a migrating irq bug when hotplug cpu
In-Reply-To: <66e158e6da958d355d54543ef69e5e94@www.loen.fr>
References: <55E1AD09.7020701@huawei.com> <55E1CBE9.6080705@linux.intel.com>
 <66e158e6da958d355d54543ef69e5e94@www.loen.fr>
Message-ID: <55E3020C.8020303@linaro.org>

On 08/30/2015 02:12 AM, Marc Zyngier wrote:
> On 2015-08-29 16:12, Jiang Liu wrote:
>> On 2015/8/29 21:00, Yang Yingliang wrote:
>>> From: Yang Yingliang <yangyingliang at huawei.com>
>>>
>>> When cpu is disabled, all irqs will be migratged to another cpu.
>>> In some cases, a new affinity is different, it needed to be coppied
>>> to irq's affinity. But if the type of irq is LPI, it's affinity will
>>> not be coppied because of irq_set_affinity's return value.
>>> So copy the affinity, when the return value is IRQ_SET_MASK_OK_DONE.
>> Hi Yingliang,
>>     If irq_set_affinity callback returns IRQ_SET_MASK_OK_DONE,
>> it means that irq_set_affinity has copied the new CPU mask to irq
>> affinity mask. It would be better to change irq_set_affinity for LPI
>> to follow this rule.
>
> The main issue here seems to be that we do not call irq_set_affinity, but
> that we directly call into the top-level irqchip method, which relies on
> the core code to do the copy (see irq_do_set_affinity). Too bad.
>
> It feels like the arm/arm64 code would probably be better consolidated into
> kernel/irq/migration.c, which already deals with some of this for x86
> and ia64. It would save us the duplication and will make sure we don't
> miss things next time we add a new return code, as irq_do_set_affinity
> would handle this properly.
>
> Thoughts?

I agree. In arch/arm64/kernel/irq.c the irq migrate code is the same
as ARM32, and it's duplicate. But this is a bugfix, can we fix it in
a simple way, and refactor the code later?

Thanks
Hanjun


From christoffer.dall at linaro.org  Sun Aug 30 06:54:17 2015
From: christoffer.dall at linaro.org (Christoffer Dall)
Date: Sun, 30 Aug 2015 15:54:17 +0200
Subject: [PATCH 0/9] Rework architected timer and fix UEFI reset
Message-ID: <1440942866-23802-1-git-send-email-christoffer.dall@linaro.org>

The architected timer integration with the vgic had some shortcomings in
that certain guests (one being UEFI) weren't fully supported.

In fixing this I also found that we are scheduling the hrtimer for the
virtual timer way too often, with a potential performance overhead.

This series tries to address these problems in proviging level-triggered
semantics for the arch timer and vgic intergration and seeks to clarify
the behavior when setting/clearing the active state on the physical
distributor.

Series based on kvmarm/next and also available at:
https://git.linaro.org/people/christoffer.dall/linux-kvm-arm.git timer-rework

Christoffer Dall (9):
  KVM: Add kvm_arch_vcpu_{un}blocking callbacks
  arm/arm64: KVM: arch_timer: Only schedule soft timer on vcpu_block
  arm/arm64: KVM: vgic: Factor out level irq processing on guest exit
  arm/arm64: Implement GICD_ICFGR as RO for PPIs
  arm/arm64: KVM: Use appropriate define in VGIC reset code
  arm/arm64: KVM: Add mapped interrupts documentation
  arm/arm64: KVM: vgic: Move active state handling to flush_hwstate
  arm/arm64: KVM: Rework the arch timer to use level-triggered semantics
  arm/arm64: KVM: arch timer: Reset CNTV_CTL to 0

 Documentation/virtual/kvm/arm/vgic-mapped-irqs.txt |  59 ++++++
 arch/arm/kvm/arm.c                                 |  21 ++-
 arch/mips/include/asm/kvm_host.h                   |   2 +
 arch/powerpc/include/asm/kvm_host.h                |   2 +
 arch/s390/include/asm/kvm_host.h                   |   2 +
 arch/x86/include/asm/kvm_host.h                    |   3 +
 include/kvm/arm_arch_timer.h                       |   4 +-
 include/kvm/arm_vgic.h                             |   3 -
 include/linux/kvm_host.h                           |   2 +
 virt/kvm/arm/arch_timer.c                          | 160 +++++++++++-----
 virt/kvm/arm/vgic.c                                | 201 +++++++++++----------
 virt/kvm/kvm_main.c                                |   3 +
 12 files changed, 308 insertions(+), 154 deletions(-)
 create mode 100644 Documentation/virtual/kvm/arm/vgic-mapped-irqs.txt

-- 
2.1.2.330.g565301e.dirty



From christoffer.dall at linaro.org  Sun Aug 30 06:54:18 2015
From: christoffer.dall at linaro.org (Christoffer Dall)
Date: Sun, 30 Aug 2015 15:54:18 +0200
Subject: [PATCH 1/9] KVM: Add kvm_arch_vcpu_{un}blocking callbacks
In-Reply-To: <1440942866-23802-1-git-send-email-christoffer.dall@linaro.org>
References: <1440942866-23802-1-git-send-email-christoffer.dall@linaro.org>
Message-ID: <1440942866-23802-2-git-send-email-christoffer.dall@linaro.org>

Some times it is useful for architecture implementations of KVM to know
when the VCPU thread is about to block or when it comes back from
blocking (arm/arm64 needs to know this to properly implement timers, for
example).

Therefore provide a generic architecture callback function in line with
what we do elsewhere for KVM generic-arch interactions.

Signed-off-by: Christoffer Dall <christoffer.dall at linaro.org>
---
 arch/arm/include/asm/kvm_host.h     | 3 +++
 arch/arm64/include/asm/kvm_host.h   | 3 +++
 arch/mips/include/asm/kvm_host.h    | 2 ++
 arch/powerpc/include/asm/kvm_host.h | 2 ++
 arch/s390/include/asm/kvm_host.h    | 2 ++
 arch/x86/include/asm/kvm_host.h     | 3 +++
 include/linux/kvm_host.h            | 2 ++
 virt/kvm/kvm_main.c                 | 3 +++
 8 files changed, 20 insertions(+)

diff --git a/arch/arm/include/asm/kvm_host.h b/arch/arm/include/asm/kvm_host.h
index dcba0fa..86fcf6e 100644
--- a/arch/arm/include/asm/kvm_host.h
+++ b/arch/arm/include/asm/kvm_host.h
@@ -236,4 +236,7 @@ static inline void kvm_arm_setup_debug(struct kvm_vcpu *vcpu) {}
 static inline void kvm_arm_clear_debug(struct kvm_vcpu *vcpu) {}
 static inline void kvm_arm_reset_debug_ptr(struct kvm_vcpu *vcpu) {}
 
+static inline void kvm_arch_vcpu_blocking(struct kvm_vcpu *vcpu) {}
+static inline void kvm_arch_vcpu_unblocking(struct kvm_vcpu *vcpu) {}
+
 #endif /* __ARM_KVM_HOST_H__ */
diff --git a/arch/arm64/include/asm/kvm_host.h b/arch/arm64/include/asm/kvm_host.h
index 415938d..dd143f5 100644
--- a/arch/arm64/include/asm/kvm_host.h
+++ b/arch/arm64/include/asm/kvm_host.h
@@ -257,4 +257,7 @@ void kvm_arm_setup_debug(struct kvm_vcpu *vcpu);
 void kvm_arm_clear_debug(struct kvm_vcpu *vcpu);
 void kvm_arm_reset_debug_ptr(struct kvm_vcpu *vcpu);
 
+static inline void kvm_arch_vcpu_blocking(struct kvm_vcpu *vcpu) {}
+static inline void kvm_arch_vcpu_unblocking(struct kvm_vcpu *vcpu) {}
+
 #endif /* __ARM64_KVM_HOST_H__ */
diff --git a/arch/mips/include/asm/kvm_host.h b/arch/mips/include/asm/kvm_host.h
index e8c8d9d..58f0f4d 100644
--- a/arch/mips/include/asm/kvm_host.h
+++ b/arch/mips/include/asm/kvm_host.h
@@ -845,5 +845,7 @@ static inline void kvm_arch_flush_shadow_memslot(struct kvm *kvm,
 		struct kvm_memory_slot *slot) {}
 static inline void kvm_arch_vcpu_uninit(struct kvm_vcpu *vcpu) {}
 static inline void kvm_arch_sched_in(struct kvm_vcpu *vcpu, int cpu) {}
+static inline void kvm_arch_vcpu_blocking(struct kvm_vcpu *vcpu) {}
+static inline void kvm_arch_vcpu_unblocking(struct kvm_vcpu *vcpu) {}
 
 #endif /* __MIPS_KVM_HOST_H__ */
diff --git a/arch/powerpc/include/asm/kvm_host.h b/arch/powerpc/include/asm/kvm_host.h
index d91f65b..179f9a7 100644
--- a/arch/powerpc/include/asm/kvm_host.h
+++ b/arch/powerpc/include/asm/kvm_host.h
@@ -702,5 +702,7 @@ static inline void kvm_arch_memslots_updated(struct kvm *kvm, struct kvm_memslot
 static inline void kvm_arch_flush_shadow_all(struct kvm *kvm) {}
 static inline void kvm_arch_sched_in(struct kvm_vcpu *vcpu, int cpu) {}
 static inline void kvm_arch_exit(void) {}
+static inline void kvm_arch_vcpu_blocking(struct kvm_vcpu *vcpu) {}
+static inline void kvm_arch_vcpu_unblocking(struct kvm_vcpu *vcpu) {}
 
 #endif /* __POWERPC_KVM_HOST_H__ */
diff --git a/arch/s390/include/asm/kvm_host.h b/arch/s390/include/asm/kvm_host.h
index 3024acb..04a97df 100644
--- a/arch/s390/include/asm/kvm_host.h
+++ b/arch/s390/include/asm/kvm_host.h
@@ -640,5 +640,7 @@ static inline void kvm_arch_memslots_updated(struct kvm *kvm, struct kvm_memslot
 static inline void kvm_arch_flush_shadow_all(struct kvm *kvm) {}
 static inline void kvm_arch_flush_shadow_memslot(struct kvm *kvm,
 		struct kvm_memory_slot *slot) {}
+static inline void kvm_arch_vcpu_blocking(struct kvm_vcpu *vcpu) {}
+static inline void kvm_arch_vcpu_unblocking(struct kvm_vcpu *vcpu) {}
 
 #endif
diff --git a/arch/x86/include/asm/kvm_host.h b/arch/x86/include/asm/kvm_host.h
index 2a7f5d7..26c4086 100644
--- a/arch/x86/include/asm/kvm_host.h
+++ b/arch/x86/include/asm/kvm_host.h
@@ -1202,4 +1202,7 @@ int __x86_set_memory_region(struct kvm *kvm,
 int x86_set_memory_region(struct kvm *kvm,
 			  const struct kvm_userspace_memory_region *mem);
 
+static inline void kvm_arch_vcpu_blocking(struct kvm_vcpu *vcpu) {}
+static inline void kvm_arch_vcpu_unblocking(struct kvm_vcpu *vcpu) {}
+
 #endif /* _ASM_X86_KVM_HOST_H */
diff --git a/include/linux/kvm_host.h b/include/linux/kvm_host.h
index 9564fd7..87d7be6 100644
--- a/include/linux/kvm_host.h
+++ b/include/linux/kvm_host.h
@@ -619,6 +619,8 @@ int kvm_vcpu_write_guest(struct kvm_vcpu *vcpu, gpa_t gpa, const void *data,
 void kvm_vcpu_mark_page_dirty(struct kvm_vcpu *vcpu, gfn_t gfn);
 
 void kvm_vcpu_block(struct kvm_vcpu *vcpu);
+void kvm_arch_vcpu_blocking(struct kvm_vcpu *vcpu);
+void kvm_arch_vcpu_unblocking(struct kvm_vcpu *vcpu);
 void kvm_vcpu_kick(struct kvm_vcpu *vcpu);
 int kvm_vcpu_yield_to(struct kvm_vcpu *target);
 void kvm_vcpu_on_spin(struct kvm_vcpu *vcpu);
diff --git a/virt/kvm/kvm_main.c b/virt/kvm/kvm_main.c
index 8b8a444..04b59dd 100644
--- a/virt/kvm/kvm_main.c
+++ b/virt/kvm/kvm_main.c
@@ -1946,6 +1946,8 @@ void kvm_vcpu_block(struct kvm_vcpu *vcpu)
 		} while (single_task_running() && ktime_before(cur, stop));
 	}
 
+	kvm_arch_vcpu_blocking(vcpu);
+
 	for (;;) {
 		prepare_to_wait(&vcpu->wq, &wait, TASK_INTERRUPTIBLE);
 
@@ -1959,6 +1961,7 @@ void kvm_vcpu_block(struct kvm_vcpu *vcpu)
 	finish_wait(&vcpu->wq, &wait);
 	cur = ktime_get();
 
+	kvm_arch_vcpu_unblocking(vcpu);
 out:
 	trace_kvm_vcpu_wakeup(ktime_to_ns(cur) - ktime_to_ns(start), waited);
 }
-- 
2.1.2.330.g565301e.dirty



From christoffer.dall at linaro.org  Sun Aug 30 06:54:23 2015
From: christoffer.dall at linaro.org (Christoffer Dall)
Date: Sun, 30 Aug 2015 15:54:23 +0200
Subject: [PATCH 6/9] arm/arm64: KVM: Add mapped interrupts documentation
In-Reply-To: <1440942866-23802-1-git-send-email-christoffer.dall@linaro.org>
References: <1440942866-23802-1-git-send-email-christoffer.dall@linaro.org>
Message-ID: <1440942866-23802-7-git-send-email-christoffer.dall@linaro.org>

Mapped interrupts on arm/arm64 is a tricky concept and the way we deal
with them is not apparently easy to understand by reading various specs.

Therefore, add a proper documentation file explaining the flow and
rationale of the behavior of the vgic.

Some of this text was contributed by Marc Zyngier.

Signed-off-by: Christoffer Dall <christoffer.dall at linaro.org>
---
 Documentation/virtual/kvm/arm/vgic-mapped-irqs.txt | 59 ++++++++++++++++++++++
 1 file changed, 59 insertions(+)
 create mode 100644 Documentation/virtual/kvm/arm/vgic-mapped-irqs.txt

diff --git a/Documentation/virtual/kvm/arm/vgic-mapped-irqs.txt b/Documentation/virtual/kvm/arm/vgic-mapped-irqs.txt
new file mode 100644
index 0000000..49e1357
--- /dev/null
+++ b/Documentation/virtual/kvm/arm/vgic-mapped-irqs.txt
@@ -0,0 +1,59 @@
+KVM/ARM VGIC Mapped Interrupts
+==============================
+
+Setting the Physical Active State for Edge vs. Level Triggered IRQs
+-------------------------------------------------------------------
+
+Mapped non-shared interrupts injected to a guest should always mark the
+interrupt as active on the physical distributor.
+
+The reasoning for level-triggered interrupts:
+For level-triggered interrupts, we have to mark the interrupt as active
+on the physical distributor, because otherwise, as the line remains
+asserted, the guest will never execute because the host will keep taking
+interrupts.  As soon as the guest deactivates the interrupt, the
+physical line is sampled by the hardware again and the host takes a new
+interrupt if the physical line is still asserted.
+
+The reasoning for edge-triggered interrupts:
+For edge-triggered interrupts, if we set the HW bit in the LR we also
+have to mark the interrupt as active on the physical distributor.  If we
+don't set the physical active bit and the interrupt hits again before
+the guest has deactivated the interrupt, the interrupt goes to the host,
+which cannot set the state to ACTIVE+PENDING in the LR, because that is
+not supported when setting the HW bit in the LR.
+
+An alternative could be to not use HW bit at all, and inject
+edge-triggered interrupts from a physical assigned device as pure
+virtual interrupts, but that would potentially slow down handling of the
+interrupt in the guest, because a physical interrupt occurring in the
+middle of the guest ISR would preempt the guest for the host to handle
+the interrupt.
+
+
+Life Cycle for Forwarded Physical Interrupts
+--------------------------------------------
+
+By forwarded physical interrupts we mean interrupts presented to a guest
+representing a real HW event originally signaled to the host as a
+physical interrupt and injecting this as a virtual interrupt with the HW
+bit set in the LR.
+
+The state of such an interrupt is managed in the following way:
+
+  - LR.Pending must be set when the interrupt is first injected, because this
+    is the only way the GICV interface is going to present it to the guest.
+  - LR.Pending will stay set as long as the guest has not acked the interrupt.
+  - LR.Pending transitions to LR.Active on read of IAR, as expected.
+  - On EOI, the *physical distributor* active bit gets cleared, but the
+    LR.Active is left untouched - it looks like the GIC can only clear a
+    single bit (either the virtual active, or the physical one).
+  - This means we cannot trust LR.Active to find out about the state of the
+    interrupt, and we definitely need to look at the distributor version.
+
+Consequently, when we context switch the state of a VCPU with forwarded
+physical interrupts, we must context switch set pending *or* active bits in the
+LR for that VCPU until the guest has deactivated the physical interrupt, and
+then clear the corresponding bits in the LR.  If we ever set an LR to pending or
+mapped when switching in a VCPU for a forwarded physical interrupt, we must also
+set the active state on the *physical distributor*.
-- 
2.1.2.330.g565301e.dirty



From christoffer.dall at linaro.org  Sun Aug 30 06:54:20 2015
From: christoffer.dall at linaro.org (Christoffer Dall)
Date: Sun, 30 Aug 2015 15:54:20 +0200
Subject: [PATCH 3/9] arm/arm64: KVM: vgic: Factor out level irq processing on
 guest exit
In-Reply-To: <1440942866-23802-1-git-send-email-christoffer.dall@linaro.org>
References: <1440942866-23802-1-git-send-email-christoffer.dall@linaro.org>
Message-ID: <1440942866-23802-4-git-send-email-christoffer.dall@linaro.org>

Currently vgic_process_maintenance() processes dealing with a completed
level-triggered interrupt directly, but we are soon going to reuse this
logic for level-triggered mapped interrupts with the HW bit set, so
move this logic into a separate static function.

Probably the most scary part of this commit is convincing yourself that
the current flow is safe compared to the old one.  In the following I
try to list the changes and why they are harmless:

  Move vgic_irq_clear_queued after kvm_notify_acked_irq:
    Harmless because the effect of clearing the queued flag wrt.
    kvm_set_irq is only that vgic_update_irq_pending does not set the
    pending bit on the emulated CPU interface or in the pending_on_cpu
    bitmask, but we set this in __kvm_vgic_sync_hwstate later on if the
    level is stil high.

  Move vgic_set_lr before kvm_notify_acked_irq:
    Also, harmless because the LR are cpu-local operations and
    kvm_notify_acked only affects the dist

  Move vgic_dist_irq_clear_soft_pend after kvm_notify_acked_irq:
    Also harmless because it's just a bit which is cleared and altering
    the line state does not affect this bit.

Signed-off-by: Christoffer Dall <christoffer.dall at linaro.org>
---
 virt/kvm/arm/vgic.c | 88 ++++++++++++++++++++++++++++++-----------------------
 1 file changed, 50 insertions(+), 38 deletions(-)

diff --git a/virt/kvm/arm/vgic.c b/virt/kvm/arm/vgic.c
index 9eb489a..c5750be 100644
--- a/virt/kvm/arm/vgic.c
+++ b/virt/kvm/arm/vgic.c
@@ -1312,12 +1312,56 @@ epilog:
 	}
 }
 
+static int process_level_irq(struct kvm_vcpu *vcpu, int lr, struct vgic_lr vlr)
+{
+	int level_pending = 0;
+
+	vlr.state = 0;
+	vlr.hwirq = 0;
+	vgic_set_lr(vcpu, lr, vlr);
+
+	/*
+	 * If the IRQ was EOIed (called from vgic_process_maintenance) or it
+	 * went from active to non-active (called from vgic_sync_hwirq) it was
+	 * also ACKed and we we therefore assume we can clear the soft pending
+	 * state (should it had been set) for this interrupt.
+	 *
+	 * Note: if the IRQ soft pending state was set after the IRQ was
+	 * acked, it actually shouldn't be cleared, but we have no way of
+	 * knowing that unless we start trapping ACKs when the soft-pending
+	 * state is set.
+	 */
+	vgic_dist_irq_clear_soft_pend(vcpu, vlr.irq);
+
+	/*
+	 * Tell the gic to start sampling the line of this interrupt again.
+	 */
+	vgic_irq_clear_queued(vcpu, vlr.irq);
+
+	/* Any additional pending interrupt? */
+	if (vgic_dist_irq_get_level(vcpu, vlr.irq)) {
+		vgic_cpu_irq_set(vcpu, vlr.irq);
+		level_pending = 1;
+	} else {
+		vgic_dist_irq_clear_pending(vcpu, vlr.irq);
+		vgic_cpu_irq_clear(vcpu, vlr.irq);
+	}
+
+	/*
+	 * Despite being EOIed, the LR may not have
+	 * been marked as empty.
+	 */
+	vgic_sync_lr_elrsr(vcpu, lr, vlr);
+
+	return level_pending;
+}
+
 static bool vgic_process_maintenance(struct kvm_vcpu *vcpu)
 {
 	u32 status = vgic_get_interrupt_status(vcpu);
 	struct vgic_dist *dist = &vcpu->kvm->arch.vgic;
-	bool level_pending = false;
 	struct kvm *kvm = vcpu->kvm;
+	int level_pending = 0;
 
 	kvm_debug("STATUS = %08x\n", status);
 
@@ -1332,54 +1376,22 @@ static bool vgic_process_maintenance(struct kvm_vcpu *vcpu)
 
 		for_each_set_bit(lr, eisr_ptr, vgic->nr_lr) {
 			struct vgic_lr vlr = vgic_get_lr(vcpu, lr);
-			WARN_ON(vgic_irq_is_edge(vcpu, vlr.irq));
 
-			spin_lock(&dist->lock);
-			vgic_irq_clear_queued(vcpu, vlr.irq);
+			WARN_ON(vgic_irq_is_edge(vcpu, vlr.irq));
 			WARN_ON(vlr.state & LR_STATE_MASK);
-			vlr.state = 0;
-			vgic_set_lr(vcpu, lr, vlr);
 
-			/*
-			 * If the IRQ was EOIed it was also ACKed and we we
-			 * therefore assume we can clear the soft pending
-			 * state (should it had been set) for this interrupt.
-			 *
-			 * Note: if the IRQ soft pending state was set after
-			 * the IRQ was acked, it actually shouldn't be
-			 * cleared, but we have no way of knowing that unless
-			 * we start trapping ACKs when the soft-pending state
-			 * is set.
-			 */
-			vgic_dist_irq_clear_soft_pend(vcpu, vlr.irq);
 
 			/*
 			 * kvm_notify_acked_irq calls kvm_set_irq()
-			 * to reset the IRQ level. Need to release the
-			 * lock for kvm_set_irq to grab it.
+			 * to reset the IRQ level, which grabs the dist->lock
+			 * so we call this before taking the dist->lock.
 			 */
-			spin_unlock(&dist->lock);
-
 			kvm_notify_acked_irq(kvm, 0,
 					     vlr.irq - VGIC_NR_PRIVATE_IRQS);
-			spin_lock(&dist->lock);
-
-			/* Any additional pending interrupt? */
-			if (vgic_dist_irq_get_level(vcpu, vlr.irq)) {
-				vgic_cpu_irq_set(vcpu, vlr.irq);
-				level_pending = true;
-			} else {
-				vgic_dist_irq_clear_pending(vcpu, vlr.irq);
-				vgic_cpu_irq_clear(vcpu, vlr.irq);
-			}
 
+			spin_lock(&dist->lock);
+			level_pending |= process_level_irq(vcpu, lr, vlr);
 			spin_unlock(&dist->lock);
-
-			/*
-			 * Despite being EOIed, the LR may not have
-			 * been marked as empty.
-			 */
-			vgic_sync_lr_elrsr(vcpu, lr, vlr);
 		}
 	}
 
-- 
2.1.2.330.g565301e.dirty



From christoffer.dall at linaro.org  Sun Aug 30 06:54:19 2015
From: christoffer.dall at linaro.org (Christoffer Dall)
Date: Sun, 30 Aug 2015 15:54:19 +0200
Subject: [PATCH 2/9] arm/arm64: KVM: arch_timer: Only schedule soft timer on
 vcpu_block
In-Reply-To: <1440942866-23802-1-git-send-email-christoffer.dall@linaro.org>
References: <1440942866-23802-1-git-send-email-christoffer.dall@linaro.org>
Message-ID: <1440942866-23802-3-git-send-email-christoffer.dall@linaro.org>

We currently schedule a soft timer every time we exit the guest if the
timer did not expire while running the guest.  This is really not
necessary, because the only work we do in the timer work function is to
kick the vcpu.

Kicking the vcpu does two things:
(1) If the vpcu thread is on a waitqueue, make it runnable and remove it
from the waitqueue.
(2) If the vcpu is running on a different physical CPU from the one
doing the kick, it sends a reschedule IPI.

The second case cannot happen, because the soft timer is only ever
scheduled when the vcpu is not running.  The first case is only relevant
when the vcpu thread is on a waitqueue, which is only the case when the
vcpu thread has called kvm_vcpu_block().

Therefore, we only need to make sure a timer is scheduled for
kvm_vcpu_block(), which we do by encapsulating all calls to
kvm_vcpu_block() with kvm_timer_{un}schedule calls.

Additionally, we only schedule a soft timer if the timer is enabled and
unmasked, since it is useless otherwise.

Note that theoretically userspace can use the SET_ONE_REG interface to
change registers that should cause the timer to fire, even if the vcpu
is blocked without a scheduled timer, but this case was not supported
before this patch and we leave it for future work for now.

Signed-off-by: Christoffer Dall <christoffer.dall at linaro.org>
---
 arch/arm/include/asm/kvm_host.h   |  3 --
 arch/arm/kvm/arm.c                | 10 +++++
 arch/arm64/include/asm/kvm_host.h |  3 --
 include/kvm/arm_arch_timer.h      |  2 +
 virt/kvm/arm/arch_timer.c         | 89 +++++++++++++++++++++++++--------------
 5 files changed, 70 insertions(+), 37 deletions(-)

diff --git a/arch/arm/include/asm/kvm_host.h b/arch/arm/include/asm/kvm_host.h
index 86fcf6e..dcba0fa 100644
--- a/arch/arm/include/asm/kvm_host.h
+++ b/arch/arm/include/asm/kvm_host.h
@@ -236,7 +236,4 @@ static inline void kvm_arm_setup_debug(struct kvm_vcpu *vcpu) {}
 static inline void kvm_arm_clear_debug(struct kvm_vcpu *vcpu) {}
 static inline void kvm_arm_reset_debug_ptr(struct kvm_vcpu *vcpu) {}
 
-static inline void kvm_arch_vcpu_blocking(struct kvm_vcpu *vcpu) {}
-static inline void kvm_arch_vcpu_unblocking(struct kvm_vcpu *vcpu) {}
-
 #endif /* __ARM_KVM_HOST_H__ */
diff --git a/arch/arm/kvm/arm.c b/arch/arm/kvm/arm.c
index ce404a5..bdf8871 100644
--- a/arch/arm/kvm/arm.c
+++ b/arch/arm/kvm/arm.c
@@ -271,6 +271,16 @@ int kvm_cpu_has_pending_timer(struct kvm_vcpu *vcpu)
 	return kvm_timer_should_fire(vcpu);
 }
 
+void kvm_arch_vcpu_blocking(struct kvm_vcpu *vcpu)
+{
+	kvm_timer_schedule(vcpu);
+}
+
+void kvm_arch_vcpu_unblocking(struct kvm_vcpu *vcpu)
+{
+	kvm_timer_unschedule(vcpu);
+}
+
 int kvm_arch_vcpu_init(struct kvm_vcpu *vcpu)
 {
 	/* Force users to call KVM_ARM_VCPU_INIT */
diff --git a/arch/arm64/include/asm/kvm_host.h b/arch/arm64/include/asm/kvm_host.h
index dd143f5..415938d 100644
--- a/arch/arm64/include/asm/kvm_host.h
+++ b/arch/arm64/include/asm/kvm_host.h
@@ -257,7 +257,4 @@ void kvm_arm_setup_debug(struct kvm_vcpu *vcpu);
 void kvm_arm_clear_debug(struct kvm_vcpu *vcpu);
 void kvm_arm_reset_debug_ptr(struct kvm_vcpu *vcpu);
 
-static inline void kvm_arch_vcpu_blocking(struct kvm_vcpu *vcpu) {}
-static inline void kvm_arch_vcpu_unblocking(struct kvm_vcpu *vcpu) {}
-
 #endif /* __ARM64_KVM_HOST_H__ */
diff --git a/include/kvm/arm_arch_timer.h b/include/kvm/arm_arch_timer.h
index e1e4d7c..ef14cc1 100644
--- a/include/kvm/arm_arch_timer.h
+++ b/include/kvm/arm_arch_timer.h
@@ -71,5 +71,7 @@ u64 kvm_arm_timer_get_reg(struct kvm_vcpu *, u64 regid);
 int kvm_arm_timer_set_reg(struct kvm_vcpu *, u64 regid, u64 value);
 
 bool kvm_timer_should_fire(struct kvm_vcpu *vcpu);
+void kvm_timer_schedule(struct kvm_vcpu *vcpu);
+void kvm_timer_unschedule(struct kvm_vcpu *vcpu);
 
 #endif
diff --git a/virt/kvm/arm/arch_timer.c b/virt/kvm/arm/arch_timer.c
index 76e38d2..018f3d6 100644
--- a/virt/kvm/arm/arch_timer.c
+++ b/virt/kvm/arm/arch_timer.c
@@ -111,14 +111,21 @@ static enum hrtimer_restart kvm_timer_expire(struct hrtimer *hrt)
 	return HRTIMER_NORESTART;
 }
 
+static bool kvm_timer_irq_enabled(struct kvm_vcpu *vcpu)
+{
+	struct arch_timer_cpu *timer = &vcpu->arch.timer_cpu;
+
+	return !(timer->cntv_ctl & ARCH_TIMER_CTRL_IT_MASK) &&
+		(timer->cntv_ctl & ARCH_TIMER_CTRL_ENABLE) &&
+		!kvm_vgic_get_phys_irq_active(timer->map);
+}
+
 bool kvm_timer_should_fire(struct kvm_vcpu *vcpu)
 {
 	struct arch_timer_cpu *timer = &vcpu->arch.timer_cpu;
 	cycle_t cval, now;
 
-	if ((timer->cntv_ctl & ARCH_TIMER_CTRL_IT_MASK) ||
-	    !(timer->cntv_ctl & ARCH_TIMER_CTRL_ENABLE) ||
-	    kvm_vgic_get_phys_irq_active(timer->map))
+	if (!kvm_timer_irq_enabled(vcpu))
 		return false;
 
 	cval = timer->cntv_cval;
@@ -127,24 +134,59 @@ bool kvm_timer_should_fire(struct kvm_vcpu *vcpu)
 	return cval <= now;
 }
 
-/**
- * kvm_timer_flush_hwstate - prepare to move the virt timer to the cpu
- * @vcpu: The vcpu pointer
- *
- * Disarm any pending soft timers, since the world-switch code will write the
- * virtual timer state back to the physical CPU.
+/*
+ * Schedule the background timer before calling kvm_vcpu_block, so that this
+ * thread is removed from its waitqueue and made runnable when there's a timer
+ * interrupt to handle.
  */
-void kvm_timer_flush_hwstate(struct kvm_vcpu *vcpu)
+void kvm_timer_schedule(struct kvm_vcpu *vcpu)
 {
 	struct arch_timer_cpu *timer = &vcpu->arch.timer_cpu;
+	u64 ns;
+	cycle_t cval, now;
+
+	/*
+	 * No need to schedule a background timer if the guest timer has
+	 * already expired, because kvm_vcpu_block will return before putting
+	 * the thread to sleep.
+	 */
+	if (kvm_timer_should_fire(vcpu))
+		return;
 
 	/*
-	 * We're about to run this vcpu again, so there is no need to
-	 * keep the background timer running, as we're about to
-	 * populate the CPU timer again.
+	 * If the timer is either not capable of raising interrupts (disabled
+	 * or masked) or if we already have a background timer, then there's
+	 * no more work for us to do.
 	 */
+	if (!kvm_timer_irq_enabled(vcpu) || timer_is_armed(timer))
+		return;
+
+	/*  The timer has not yet expired, schedule a background timer */
+	cval = timer->cntv_cval;
+	now = kvm_phys_timer_read() - vcpu->kvm->arch.timer.cntvoff;
+
+	ns = cyclecounter_cyc2ns(timecounter->cc,
+				 cval - now,
+				 timecounter->mask,
+				 &timecounter->frac);
+	timer_arm(timer, ns);
+}
+
+void kvm_timer_unschedule(struct kvm_vcpu *vcpu)
+{
+	struct arch_timer_cpu *timer = &vcpu->arch.timer_cpu;
 	timer_disarm(timer);
+}
 
+/**
+ * kvm_timer_flush_hwstate - prepare to move the virt timer to the cpu
+ * @vcpu: The vcpu pointer
+ *
+ * Check if the virtual timer has expired while we were running in the host,
+ * and inject an interrupt if that was the case.
+ */
+void kvm_timer_flush_hwstate(struct kvm_vcpu *vcpu)
+{
 	/*
 	 * If the timer expired while we were not scheduled, now is the time
 	 * to inject it.
@@ -157,32 +199,17 @@ void kvm_timer_flush_hwstate(struct kvm_vcpu *vcpu)
  * kvm_timer_sync_hwstate - sync timer state from cpu
  * @vcpu: The vcpu pointer
  *
- * Check if the virtual timer was armed and either schedule a corresponding
- * soft timer or inject directly if already expired.
+ * Check if the virtual timer has expired while we werer running in the guest,
+ * and inject an interrupt if that was the case.
  */
 void kvm_timer_sync_hwstate(struct kvm_vcpu *vcpu)
 {
 	struct arch_timer_cpu *timer = &vcpu->arch.timer_cpu;
-	cycle_t cval, now;
-	u64 ns;
 
 	BUG_ON(timer_is_armed(timer));
 
-	if (kvm_timer_should_fire(vcpu)) {
-		/*
-		 * Timer has already expired while we were not
-		 * looking. Inject the interrupt and carry on.
-		 */
+	if (kvm_timer_should_fire(vcpu))
 		kvm_timer_inject_irq(vcpu);
-		return;
-	}
-
-	cval = timer->cntv_cval;
-	now = kvm_phys_timer_read() - vcpu->kvm->arch.timer.cntvoff;
-
-	ns = cyclecounter_cyc2ns(timecounter->cc, cval - now, timecounter->mask,
-				 &timecounter->frac);
-	timer_arm(timer, ns);
 }
 
 int kvm_timer_vcpu_reset(struct kvm_vcpu *vcpu,
-- 
2.1.2.330.g565301e.dirty



From christoffer.dall at linaro.org  Sun Aug 30 06:54:21 2015
From: christoffer.dall at linaro.org (Christoffer Dall)
Date: Sun, 30 Aug 2015 15:54:21 +0200
Subject: [PATCH 4/9] arm/arm64: Implement GICD_ICFGR as RO for PPIs
In-Reply-To: <1440942866-23802-1-git-send-email-christoffer.dall@linaro.org>
References: <1440942866-23802-1-git-send-email-christoffer.dall@linaro.org>
Message-ID: <1440942866-23802-5-git-send-email-christoffer.dall@linaro.org>

The GICD_ICFGR allows the bits for the SGIs and PPIs to be read only.
We currently simulate this behavior by writing a hardcoded value to the
register for the SGIs and PPIs on every write of these bits to the
register (ignoring what the guest actually wrote), and by writing the
same value as the reset value to the register.

This is a bit counter-intuitive, as the register is RO for these bits,
and we can just implement it that way, allowing us to control the value
of the bits purely in the reset code.

Signed-off-by: Christoffer Dall <christoffer.dall at linaro.org>
---
 virt/kvm/arm/vgic.c | 2 +-
 1 file changed, 1 insertion(+), 1 deletion(-)

diff --git a/virt/kvm/arm/vgic.c b/virt/kvm/arm/vgic.c
index c5750be..0ba92d3 100644
--- a/virt/kvm/arm/vgic.c
+++ b/virt/kvm/arm/vgic.c
@@ -655,7 +655,7 @@ bool vgic_handle_cfg_reg(u32 *reg, struct kvm_exit_mmio *mmio,
 			ACCESS_READ_VALUE | ACCESS_WRITE_VALUE);
 	if (mmio->is_write) {
 		if (offset < 8) {
-			*reg = ~0U; /* Force PPIs/SGIs to 1 */
+			/* Ignore writes to read-only SGI and PPI bits */
 			return false;
 		}
 
-- 
2.1.2.330.g565301e.dirty



From christoffer.dall at linaro.org  Sun Aug 30 06:54:22 2015
From: christoffer.dall at linaro.org (Christoffer Dall)
Date: Sun, 30 Aug 2015 15:54:22 +0200
Subject: [PATCH 5/9] arm/arm64: KVM: Use appropriate define in VGIC reset code
In-Reply-To: <1440942866-23802-1-git-send-email-christoffer.dall@linaro.org>
References: <1440942866-23802-1-git-send-email-christoffer.dall@linaro.org>
Message-ID: <1440942866-23802-6-git-send-email-christoffer.dall@linaro.org>

We currently initialize the SGIs to be enabled in the VGIC code, but we
use the VGIC_NR_PPIS define for this purpose, instead of the the more
natural VGIC_NR_SGIS.  Change this slightly confusing use of the
defines.

Note: This should have no functional change, as both names are defined
to the number 16.

Signed-off-by: Christoffer Dall <christoffer.dall at linaro.org>
---
 virt/kvm/arm/vgic.c | 2 +-
 1 file changed, 1 insertion(+), 1 deletion(-)

diff --git a/virt/kvm/arm/vgic.c b/virt/kvm/arm/vgic.c
index 0ba92d3..8299c24 100644
--- a/virt/kvm/arm/vgic.c
+++ b/virt/kvm/arm/vgic.c
@@ -2099,7 +2099,7 @@ int vgic_init(struct kvm *kvm)
 		}
 
 		for (i = 0; i < dist->nr_irqs; i++) {
-			if (i < VGIC_NR_PPIS)
+			if (i < VGIC_NR_SGIS)
 				vgic_bitmap_set_irq_val(&dist->irq_enabled,
 							vcpu->vcpu_id, i, 1);
 			if (i < VGIC_NR_PRIVATE_IRQS)
-- 
2.1.2.330.g565301e.dirty



From christoffer.dall at linaro.org  Sun Aug 30 06:54:24 2015
From: christoffer.dall at linaro.org (Christoffer Dall)
Date: Sun, 30 Aug 2015 15:54:24 +0200
Subject: [PATCH 7/9] arm/arm64: KVM: vgic: Move active state handling to
 flush_hwstate
In-Reply-To: <1440942866-23802-1-git-send-email-christoffer.dall@linaro.org>
References: <1440942866-23802-1-git-send-email-christoffer.dall@linaro.org>
Message-ID: <1440942866-23802-8-git-send-email-christoffer.dall@linaro.org>

We currently set the physical active state only when we *inject* a new
pending virtual interrupt, but this is actually not correct, because we
could have been preempted and run something else on the system that
resets the active state to clear.  This causes us to run the VM with the
timer set to fire, but without setting the physical active state.

The solution is to always check the LR configurations, and we if have a
mapped interrupt in th LR in either the pending or active state
(virtual), then set the physical active state.

Signed-off-by: Christoffer Dall <christoffer.dall at linaro.org>
---
 virt/kvm/arm/vgic.c | 42 ++++++++++++++++++++++++++----------------
 1 file changed, 26 insertions(+), 16 deletions(-)

diff --git a/virt/kvm/arm/vgic.c b/virt/kvm/arm/vgic.c
index 8299c24..9ed8d53 100644
--- a/virt/kvm/arm/vgic.c
+++ b/virt/kvm/arm/vgic.c
@@ -1144,26 +1144,11 @@ static void vgic_queue_irq_to_lr(struct kvm_vcpu *vcpu, int irq,
 		struct irq_phys_map *map;
 		map = vgic_irq_map_search(vcpu, irq);
 
-		/*
-		 * If we have a mapping, and the virtual interrupt is
-		 * being injected, then we must set the state to
-		 * active in the physical world. Otherwise the
-		 * physical interrupt will fire and the guest will
-		 * exit before processing the virtual interrupt.
-		 */
 		if (map) {
-			int ret;
-
-			BUG_ON(!map->active);
 			vlr.hwirq = map->phys_irq;
 			vlr.state |= LR_HW;
 			vlr.state &= ~LR_EOI_INT;
 
-			ret = irq_set_irqchip_state(map->irq,
-						    IRQCHIP_STATE_ACTIVE,
-						    true);
-			WARN_ON(ret);
-
 			/*
 			 * Make sure we're not going to sample this
 			 * again, as a HW-backed interrupt cannot be
@@ -1255,7 +1240,7 @@ static void __kvm_vgic_flush_hwstate(struct kvm_vcpu *vcpu)
 	struct vgic_cpu *vgic_cpu = &vcpu->arch.vgic_cpu;
 	struct vgic_dist *dist = &vcpu->kvm->arch.vgic;
 	unsigned long *pa_percpu, *pa_shared;
-	int i, vcpu_id;
+	int i, vcpu_id, lr, ret;
 	int overflow = 0;
 	int nr_shared = vgic_nr_shared_irqs(dist);
 
@@ -1310,6 +1295,31 @@ epilog:
 		 */
 		clear_bit(vcpu_id, dist->irq_pending_on_cpu);
 	}
+
+	for (lr = 0; lr < vgic->nr_lr; lr++) {
+		struct vgic_lr vlr;
+
+		if (!test_bit(lr, vgic_cpu->lr_used))
+			continue;
+
+		vlr = vgic_get_lr(vcpu, lr);
+
+		/*
+		 * If we have a mapping, and the virtual interrupt is
+		 * presented to the guest (as pending or active), then we must
+		 * set the state to active in the physical world. See
+		 * Documentation/virtual/kvm/arm/vgic-mapped-irqs.txt.
+		 */
+		if (vlr.state & LR_HW) {
+			struct irq_phys_map *map;
+			map = vgic_irq_map_search(vcpu, vlr.irq);
+
+			ret = irq_set_irqchip_state(map->irq,
+						    IRQCHIP_STATE_ACTIVE,
+						    true);
+			WARN_ON(ret);
+		}
+	}
 }
 
 static int process_level_irq(struct kvm_vcpu *vcpu, int lr, struct vgic_lr vlr)
-- 
2.1.2.330.g565301e.dirty



From christoffer.dall at linaro.org  Sun Aug 30 06:54:26 2015
From: christoffer.dall at linaro.org (Christoffer Dall)
Date: Sun, 30 Aug 2015 15:54:26 +0200
Subject: [PATCH 9/9] arm/arm64: KVM: arch timer: Reset CNTV_CTL to 0
In-Reply-To: <1440942866-23802-1-git-send-email-christoffer.dall@linaro.org>
References: <1440942866-23802-1-git-send-email-christoffer.dall@linaro.org>
Message-ID: <1440942866-23802-10-git-send-email-christoffer.dall@linaro.org>

Provide a better quality of implementation and be architecture compliant
on ARMv7 for the architected timer by resetting the CNTV_CTL to 0 on
reset of the timer, and call kvm_timer_update_state(vcpu) at the same
time, ensuring the timer output is not asserted after, for example, a
PSCI system reset.

This change alone fixes the UEFI reset issue reported by Laszlo back in
February.

Cc: Laszlo Ersek <lersek at redhat.com>
Cc: Ard Biesheuvel <ard.biesheuvel at linaro.org>
Cc: Drew Jones <drjones at redhat.com>
Cc: Wei Huang <wei at redhat.com>
Cc: Peter Maydell <peter.maydell at linaro.org>
Signed-off-by: Christoffer Dall <christoffer.dall at linaro.org>
---
 virt/kvm/arm/arch_timer.c | 9 +++++++++
 1 file changed, 9 insertions(+)

diff --git a/virt/kvm/arm/arch_timer.c b/virt/kvm/arm/arch_timer.c
index 747302f..8a0fdfc 100644
--- a/virt/kvm/arm/arch_timer.c
+++ b/virt/kvm/arm/arch_timer.c
@@ -255,6 +255,15 @@ int kvm_timer_vcpu_reset(struct kvm_vcpu *vcpu,
 	timer->irq.irq = irq->irq;
 
 	/*
+	 * The bits in CNTV_CTL are architecturally reset to UNKNOWN for ARMv8
+	 * and to 0 for ARMv7.  We provide an implementation that always
+	 * resets the timer to be disabled and unmasked and is compliant with
+	 * the ARMv7 architecture.
+	 */
+	timer->cntv_ctl = 0;
+	kvm_timer_update_state(vcpu);
+
+	/*
 	 * Tell the VGIC that the virtual interrupt is tied to a
 	 * physical interrupt. We do that once per VCPU.
 	 */
-- 
2.1.2.330.g565301e.dirty



From christoffer.dall at linaro.org  Sun Aug 30 06:54:25 2015
From: christoffer.dall at linaro.org (Christoffer Dall)
Date: Sun, 30 Aug 2015 15:54:25 +0200
Subject: [PATCH 8/9] arm/arm64: KVM: Rework the arch timer to use
 level-triggered semantics
In-Reply-To: <1440942866-23802-1-git-send-email-christoffer.dall@linaro.org>
References: <1440942866-23802-1-git-send-email-christoffer.dall@linaro.org>
Message-ID: <1440942866-23802-9-git-send-email-christoffer.dall@linaro.org>

The arch timer currently uses edge-triggered semantics in the sense that
the line is never sampled by the vgic and lowering the line from the
timer to the vgic doesn't have any affect on the pending state of
virtual interrupts in the vgic.  This means that we do not support a
guest with the otherwise valid behavior of (1) disable interrupts (2)
enable the timer (3) disable the timer (4) enable interrupts.  Such a
guest would validly not expect to see any interrupts on real hardware,
but will see interrupts on KVM.

This patches fixes this shortcoming through the following series of
changes.

First, we change the flow of the timer/vgic sync/flush operations.  Now
the timer is always flushed/synced before the vgic, because the vgic
samples the state of the timer output.  This has the implication that we
move the timer operations in to non-preempible sections, but that is
fine after the previous commit getting rid of hrtimer schedules on every
entry/exit.

Second, we change the internal behavior of the timer, letting the timer
keep track of its previous output state, and only lower/raise the line
to the vgic when the state changes.  Note that in theory this could have
been accomplished more simply by signalling the vgic every time the
state *potentially* changed, but we don't want to be hitting the vgic
more often than necessary.

Third, we get rid of the use of the map->active field in the vgic and
instead simply set the interrupt as active on the physical distributor
whenever we signal a mapped interrupt to the guest, and we reset the
active state when we sync back the HW state from the vgic.

Fourth, and finally, we now initialize the timer PPIs (and all the other
unused PPIs for now), to be level-triggered, and modify the sync code to
sample the line state on HW sync and re-inject a new interrupt if it is
still pending at that time.

Signed-off-by: Christoffer Dall <christoffer.dall at linaro.org>
---
 arch/arm/kvm/arm.c           | 11 +++++--
 include/kvm/arm_arch_timer.h |  2 +-
 include/kvm/arm_vgic.h       |  3 --
 virt/kvm/arm/arch_timer.c    | 68 +++++++++++++++++++++++++++++++-------------
 virt/kvm/arm/vgic.c          | 67 +++++++++++++++----------------------------
 5 files changed, 81 insertions(+), 70 deletions(-)

diff --git a/arch/arm/kvm/arm.c b/arch/arm/kvm/arm.c
index bdf8871..102a4aa 100644
--- a/arch/arm/kvm/arm.c
+++ b/arch/arm/kvm/arm.c
@@ -561,9 +561,9 @@ int kvm_arch_vcpu_ioctl_run(struct kvm_vcpu *vcpu, struct kvm_run *run)
 
 		if (ret <= 0 || need_new_vmid_gen(vcpu->kvm)) {
 			local_irq_enable();
+			kvm_timer_sync_hwstate(vcpu);
 			kvm_vgic_sync_hwstate(vcpu);
 			preempt_enable();
-			kvm_timer_sync_hwstate(vcpu);
 			continue;
 		}
 
@@ -608,12 +608,17 @@ int kvm_arch_vcpu_ioctl_run(struct kvm_vcpu *vcpu, struct kvm_run *run)
 		kvm_guest_exit();
 		trace_kvm_exit(kvm_vcpu_trap_get_class(vcpu), *vcpu_pc(vcpu));
 
+		/*
+		 * We must sync the timer state before the vgic state so that
+		 * the vgic can properly sample the updated state of the
+		 * interrupt line.
+		 */
+		kvm_timer_sync_hwstate(vcpu);
+
 		kvm_vgic_sync_hwstate(vcpu);
 
 		preempt_enable();
 
-		kvm_timer_sync_hwstate(vcpu);
-
 		ret = handle_exit(vcpu, run, ret);
 	}
 
diff --git a/include/kvm/arm_arch_timer.h b/include/kvm/arm_arch_timer.h
index ef14cc1..1800227 100644
--- a/include/kvm/arm_arch_timer.h
+++ b/include/kvm/arm_arch_timer.h
@@ -51,7 +51,7 @@ struct arch_timer_cpu {
 	bool				armed;
 
 	/* Timer IRQ */
-	const struct kvm_irq_level	*irq;
+	struct kvm_irq_level		irq;
 
 	/* VGIC mapping */
 	struct irq_phys_map		*map;
diff --git a/include/kvm/arm_vgic.h b/include/kvm/arm_vgic.h
index d901f1a..99011a0 100644
--- a/include/kvm/arm_vgic.h
+++ b/include/kvm/arm_vgic.h
@@ -163,7 +163,6 @@ struct irq_phys_map {
 	u32			virt_irq;
 	u32			phys_irq;
 	u32			irq;
-	bool			active;
 };
 
 struct irq_phys_map_entry {
@@ -358,8 +357,6 @@ int kvm_vgic_vcpu_active_irq(struct kvm_vcpu *vcpu);
 struct irq_phys_map *kvm_vgic_map_phys_irq(struct kvm_vcpu *vcpu,
 					   int virt_irq, int irq);
 int kvm_vgic_unmap_phys_irq(struct kvm_vcpu *vcpu, struct irq_phys_map *map);
-bool kvm_vgic_get_phys_irq_active(struct irq_phys_map *map);
-void kvm_vgic_set_phys_irq_active(struct irq_phys_map *map, bool active);
 
 #define irqchip_in_kernel(k)	(!!((k)->arch.vgic.in_kernel))
 #define vgic_initialized(k)	(!!((k)->arch.vgic.nr_cpus))
diff --git a/virt/kvm/arm/arch_timer.c b/virt/kvm/arm/arch_timer.c
index 018f3d6..747302f 100644
--- a/virt/kvm/arm/arch_timer.c
+++ b/virt/kvm/arm/arch_timer.c
@@ -59,18 +59,6 @@ static void timer_disarm(struct arch_timer_cpu *timer)
 	}
 }
 
-static void kvm_timer_inject_irq(struct kvm_vcpu *vcpu)
-{
-	int ret;
-	struct arch_timer_cpu *timer = &vcpu->arch.timer_cpu;
-
-	kvm_vgic_set_phys_irq_active(timer->map, true);
-	ret = kvm_vgic_inject_mapped_irq(vcpu->kvm, vcpu->vcpu_id,
-					 timer->map,
-					 timer->irq->level);
-	WARN_ON(ret);
-}
-
 static irqreturn_t kvm_arch_timer_handler(int irq, void *dev_id)
 {
 	struct kvm_vcpu *vcpu = *(struct kvm_vcpu **)dev_id;
@@ -116,8 +104,7 @@ static bool kvm_timer_irq_enabled(struct kvm_vcpu *vcpu)
 	struct arch_timer_cpu *timer = &vcpu->arch.timer_cpu;
 
 	return !(timer->cntv_ctl & ARCH_TIMER_CTRL_IT_MASK) &&
-		(timer->cntv_ctl & ARCH_TIMER_CTRL_ENABLE) &&
-		!kvm_vgic_get_phys_irq_active(timer->map);
+		(timer->cntv_ctl & ARCH_TIMER_CTRL_ENABLE);
 }
 
 bool kvm_timer_should_fire(struct kvm_vcpu *vcpu)
@@ -134,6 +121,45 @@ bool kvm_timer_should_fire(struct kvm_vcpu *vcpu)
 	return cval <= now;
 }
 
+static void kvm_timer_update_irq(struct kvm_vcpu *vcpu)
+{
+	int ret;
+	struct arch_timer_cpu *timer = &vcpu->arch.timer_cpu;
+
+	BUG_ON(!vgic_initialized(vcpu->kvm));
+
+	ret = kvm_vgic_inject_mapped_irq(vcpu->kvm, vcpu->vcpu_id,
+					 timer->map,
+					 timer->irq.level);
+	WARN_ON(ret);
+}
+
+/*
+ * Check if there was a change in the timer state (should we raise or lower
+ * the line level to the GIC).
+ */
+static void kvm_timer_update_state(struct kvm_vcpu *vcpu)
+{
+	struct arch_timer_cpu *timer = &vcpu->arch.timer_cpu;
+
+	/*
+	 * If userspace modified the timer registers via SET_ONE_REG before
+	 * the vgic was initialized, we mustn't set the timer->irq.level value
+	 * because the guest would never see the interrupt.  Instead wait
+	 * until we call this funciton from kvm_timer_flush_hwstate.
+	 */
+	if (!vgic_initialized(vcpu->kvm))
+	    return;
+
+	if (kvm_timer_should_fire(vcpu) && !timer->irq.level) {
+		timer->irq.level = 1;
+		kvm_timer_update_irq(vcpu);
+	} else if (!kvm_timer_should_fire(vcpu) && timer->irq.level) {
+		timer->irq.level = 0;
+		kvm_timer_update_irq(vcpu);
+	}
+}
+
 /*
  * Schedule the background timer before calling kvm_vcpu_block, so that this
  * thread is removed from its waitqueue and made runnable when there's a timer
@@ -191,8 +217,7 @@ void kvm_timer_flush_hwstate(struct kvm_vcpu *vcpu)
 	 * If the timer expired while we were not scheduled, now is the time
 	 * to inject it.
 	 */
-	if (kvm_timer_should_fire(vcpu))
-		kvm_timer_inject_irq(vcpu);
+	kvm_timer_update_state(vcpu);
 }
 
 /**
@@ -208,8 +233,11 @@ void kvm_timer_sync_hwstate(struct kvm_vcpu *vcpu)
 
 	BUG_ON(timer_is_armed(timer));
 
-	if (kvm_timer_should_fire(vcpu))
-		kvm_timer_inject_irq(vcpu);
+	/*
+	 * The guest could have modified the timer registers or the timer
+	 * could have expired, update the timer state.
+	 */
+	kvm_timer_update_state(vcpu);
 }
 
 int kvm_timer_vcpu_reset(struct kvm_vcpu *vcpu,
@@ -224,7 +252,7 @@ int kvm_timer_vcpu_reset(struct kvm_vcpu *vcpu,
 	 * kvm_vcpu_set_target(). To handle this, we determine
 	 * vcpu timer irq number when the vcpu is reset.
 	 */
-	timer->irq = irq;
+	timer->irq.irq = irq->irq;
 
 	/*
 	 * Tell the VGIC that the virtual interrupt is tied to a
@@ -269,6 +297,8 @@ int kvm_arm_timer_set_reg(struct kvm_vcpu *vcpu, u64 regid, u64 value)
 	default:
 		return -1;
 	}
+
+	kvm_timer_update_state(vcpu);
 	return 0;
 }
 
diff --git a/virt/kvm/arm/vgic.c b/virt/kvm/arm/vgic.c
index 9ed8d53..f4ea950 100644
--- a/virt/kvm/arm/vgic.c
+++ b/virt/kvm/arm/vgic.c
@@ -1422,34 +1422,43 @@ static bool vgic_process_maintenance(struct kvm_vcpu *vcpu)
 /*
  * Save the physical active state, and reset it to inactive.
  *
- * Return 1 if HW interrupt went from active to inactive, and 0 otherwise.
+ * Return true if there's a pending level triggered interrupt line to queue.
  */
-static int vgic_sync_hwirq(struct kvm_vcpu *vcpu, struct vgic_lr vlr)
+static bool vgic_sync_hwirq(struct kvm_vcpu *vcpu, int lr, struct vgic_lr vlr)
 {
 	struct irq_phys_map *map;
+	bool phys_active;
 	int ret;
 
 	if (!(vlr.state & LR_HW))
 		return 0;
 
 	map = vgic_irq_map_search(vcpu, vlr.irq);
-	BUG_ON(!map || !map->active);
+	BUG_ON(!map);
 
 	ret = irq_get_irqchip_state(map->irq,
 				    IRQCHIP_STATE_ACTIVE,
-				    &map->active);
+				    &phys_active);
 
 	WARN_ON(ret);
 
-	if (map->active) {
+	if (phys_active) {
+		/*
+		 * Interrupt still marked as active on the physical
+		 * distributor, so guest did not EOI it yet.  Reset to
+		 * non-active so that other VMs can see interrupts from this
+		 * device.
+		 */
 		ret = irq_set_irqchip_state(map->irq,
 					    IRQCHIP_STATE_ACTIVE,
 					    false);
 		WARN_ON(ret);
-		return 0;
+		return false;
 	}
 
-	return 1;
+	/* Mapped edge-triggered interrupts not yet supported. */
+	WARN_ON(vgic_irq_is_edge(vcpu, vlr.irq));
+	return process_level_irq(vcpu, lr, vlr);
 }
 
 /* Sync back the VGIC state after a guest run */
@@ -1474,18 +1483,8 @@ static void __kvm_vgic_sync_hwstate(struct kvm_vcpu *vcpu)
 			continue;
 
 		vlr = vgic_get_lr(vcpu, lr);
-		if (vgic_sync_hwirq(vcpu, vlr)) {
-			/*
-			 * So this is a HW interrupt that the guest
-			 * EOI-ed. Clean the LR state and allow the
-			 * interrupt to be sampled again.
-			 */
-			vlr.state = 0;
-			vlr.hwirq = 0;
-			vgic_set_lr(vcpu, lr, vlr);
-			vgic_irq_clear_queued(vcpu, vlr.irq);
-			set_bit(lr, elrsr_ptr);
-		}
+		if (vgic_sync_hwirq(vcpu, lr, vlr))
+			level_pending = true;
 
 		if (!test_bit(lr, elrsr_ptr))
 			continue;
@@ -1861,30 +1860,6 @@ static void vgic_free_phys_irq_map_rcu(struct rcu_head *rcu)
 }
 
 /**
- * kvm_vgic_get_phys_irq_active - Return the active state of a mapped IRQ
- *
- * Return the logical active state of a mapped interrupt. This doesn't
- * necessarily reflects the current HW state.
- */
-bool kvm_vgic_get_phys_irq_active(struct irq_phys_map *map)
-{
-	BUG_ON(!map);
-	return map->active;
-}
-
-/**
- * kvm_vgic_set_phys_irq_active - Set the active state of a mapped IRQ
- *
- * Set the logical active state of a mapped interrupt. This doesn't
- * immediately affects the HW state.
- */
-void kvm_vgic_set_phys_irq_active(struct irq_phys_map *map, bool active)
-{
-	BUG_ON(!map);
-	map->active = active;
-}
-
-/**
  * kvm_vgic_unmap_phys_irq - Remove a virtual to physical IRQ mapping
  * @vcpu: The VCPU pointer
  * @map: The pointer to a mapping obtained through kvm_vgic_map_phys_irq
@@ -2112,10 +2087,14 @@ int vgic_init(struct kvm *kvm)
 			if (i < VGIC_NR_SGIS)
 				vgic_bitmap_set_irq_val(&dist->irq_enabled,
 							vcpu->vcpu_id, i, 1);
-			if (i < VGIC_NR_PRIVATE_IRQS)
+			if (i < VGIC_NR_SGIS)
 				vgic_bitmap_set_irq_val(&dist->irq_cfg,
 							vcpu->vcpu_id, i,
 							VGIC_CFG_EDGE);
+			else if (i < VGIC_NR_PRIVATE_IRQS) /* PPIs */
+				vgic_bitmap_set_irq_val(&dist->irq_cfg,
+							vcpu->vcpu_id, i,
+							VGIC_CFG_LEVEL);
 		}
 
 		vgic_enable(vcpu);
-- 
2.1.2.330.g565301e.dirty



From christoffer.dall at linaro.org  Sun Aug 30 06:55:21 2015
From: christoffer.dall at linaro.org (Christoffer Dall)
Date: Sun, 30 Aug 2015 15:55:21 +0200
Subject: [PATCH 1/2] arm/arm64: KVM: Add tracepoints for vgic and timer
In-Reply-To: <1440942922-23955-1-git-send-email-christoffer.dall@linaro.org>
References: <1440942922-23955-1-git-send-email-christoffer.dall@linaro.org>
Message-ID: <1440942922-23955-2-git-send-email-christoffer.dall@linaro.org>

The VGIC and timer code for KVM arm/arm64 doesn't have any tracepoints
or tracepoint infrastructure defined.  Rewriting some of the timer code
handling showed me how much we need this, so let's add these simple
trace points once and for all and we can easily expand with additional
trace points in these files as we go along.

Signed-off-by: Christoffer Dall <christoffer.dall at linaro.org>
---
 virt/kvm/arm/arch_timer.c |  4 ++
 virt/kvm/arm/trace.h      | 97 +++++++++++++++++++++++++++++++++++++++++++++++
 virt/kvm/arm/vgic.c       |  9 +++++
 3 files changed, 110 insertions(+)
 create mode 100644 virt/kvm/arm/trace.h

diff --git a/virt/kvm/arm/arch_timer.c b/virt/kvm/arm/arch_timer.c
index 8a0fdfc..f63b208 100644
--- a/virt/kvm/arm/arch_timer.c
+++ b/virt/kvm/arm/arch_timer.c
@@ -28,6 +28,8 @@
 #include <kvm/arm_vgic.h>
 #include <kvm/arm_arch_timer.h>
 
+#include "trace.h"
+
 static struct timecounter *timecounter;
 static struct workqueue_struct *wqueue;
 static unsigned int host_vtimer_irq;
@@ -128,6 +130,8 @@ static void kvm_timer_update_irq(struct kvm_vcpu *vcpu)
 
 	BUG_ON(!vgic_initialized(vcpu->kvm));
 
+	trace_kvm_timer_update_irq(vcpu->vcpu_id, timer->map->virt_irq,
+				   timer->irq->level);
 	ret = kvm_vgic_inject_mapped_irq(vcpu->kvm, vcpu->vcpu_id,
 					 timer->map,
 					 timer->irq.level);
diff --git a/virt/kvm/arm/trace.h b/virt/kvm/arm/trace.h
new file mode 100644
index 0000000..48c3c90
--- /dev/null
+++ b/virt/kvm/arm/trace.h
@@ -0,0 +1,97 @@
+#if !defined(_TRACE_KVM_H) || defined(TRACE_HEADER_MULTI_READ)
+#define _TRACE_KVM_H
+
+#include <linux/tracepoint.h>
+
+#undef TRACE_SYSTEM
+#define TRACE_SYSTEM kvm
+
+/*
+ * Tracepoints for vgic
+ */
+TRACE_EVENT(kvm_vgic_set_irqchip_active,
+	TP_PROTO(unsigned long vcpu_id, __u32 irq),
+	TP_ARGS(vcpu_id, irq),
+
+	TP_STRUCT__entry(
+		__field(	unsigned long,	vcpu_id	)
+		__field(	__u32,		irq	)
+	),
+
+	TP_fast_assign(
+		__entry->vcpu_id	= vcpu_id;
+		__entry->irq		= irq;
+	),
+
+	TP_printk("VCPU: %ld, IRQ %d", __entry->vcpu_id, __entry->irq)
+);
+
+TRACE_EVENT(kvm_vgic_clear_irqchip_active,
+	TP_PROTO(unsigned long vcpu_id, __u32 irq),
+	TP_ARGS(vcpu_id, irq),
+
+	TP_STRUCT__entry(
+		__field(	unsigned long,	vcpu_id	)
+		__field(	__u32,		irq	)
+	),
+
+	TP_fast_assign(
+		__entry->vcpu_id	= vcpu_id;
+		__entry->irq		= irq;
+	),
+
+	TP_printk("VCPU: %ld, IRQ %d", __entry->vcpu_id, __entry->irq)
+);
+
+TRACE_EVENT(vgic_update_irq_pending,
+	TP_PROTO(unsigned long vcpu_id, __u32 irq, bool level),
+	TP_ARGS(vcpu_id, irq, level),
+
+	TP_STRUCT__entry(
+		__field(	unsigned long,	vcpu_id	)
+		__field(	__u32,		irq	)
+		__field(	bool,		level	)
+	),
+
+	TP_fast_assign(
+		__entry->vcpu_id	= vcpu_id;
+		__entry->irq		= irq;
+		__entry->level		= level;
+	),
+
+	TP_printk("VCPU: %ld, IRQ %d, level: %d",
+		  __entry->vcpu_id, __entry->irq, __entry->level)
+);
+
+/*
+ * Tracepoints for arch_timer
+ */
+TRACE_EVENT(kvm_timer_inject_irq,
+	TP_PROTO(unsigned long vcpu_id, __u32 irq, int level),
+	TP_ARGS(vcpu_id, irq, level),
+
+	TP_STRUCT__entry(
+		__field(	unsigned long,	vcpu_id	)
+		__field(	__u32,		irq	)
+		__field(	int,		level	)
+	),
+
+	TP_fast_assign(
+		__entry->vcpu_id	= vcpu_id;
+		__entry->irq		= irq;
+		__entry->level		= level;
+	),
+
+	TP_printk("VCPU: %ld, IRQ %d, level %d",
+		  __entry->vcpu_id, __entry->irq, __entry->level)
+);
+
+#endif /* _TRACE_KVM_H */
+
+#undef TRACE_INCLUDE_PATH
+#define TRACE_INCLUDE_PATH ../../../virt/kvm/arm
+#undef TRACE_INCLUDE_FILE
+#define TRACE_INCLUDE_FILE trace
+
+/* This part must be outside protection */
+#include <trace/define_trace.h>
diff --git a/virt/kvm/arm/vgic.c b/virt/kvm/arm/vgic.c
index f4ea950..45c95a0 100644
--- a/virt/kvm/arm/vgic.c
+++ b/virt/kvm/arm/vgic.c
@@ -34,6 +34,9 @@
 #include <asm/kvm.h>
 #include <kvm/iodev.h>
 
+#define CREATE_TRACE_POINTS
+#include "trace.h"
+
 /*
  * How the whole thing works (courtesy of Christoffer Dall):
  *
@@ -1314,6 +1317,8 @@ epilog:
 			struct irq_phys_map *map;
 			map = vgic_irq_map_search(vcpu, vlr.irq);
 
+			trace_kvm_vgic_set_irqchip_active(vcpu->vcpu_id,
+							  vlr.irq);
 			ret = irq_set_irqchip_state(map->irq,
 						    IRQCHIP_STATE_ACTIVE,
 						    true);
@@ -1449,6 +1454,8 @@ static bool vgic_sync_hwirq(struct kvm_vcpu *vcpu, int lr, struct vgic_lr vlr)
 		 * non-active so that other VMs can see interrupts from this
 		 * device.
 		 */
+		trace_kvm_vgic_clear_irqchip_active(vcpu->vcpu_id,
+						    vlr.irq);
 		ret = irq_set_irqchip_state(map->irq,
 					    IRQCHIP_STATE_ACTIVE,
 					    false);
@@ -1585,6 +1592,8 @@ static int vgic_update_irq_pending(struct kvm *kvm, int cpuid,
 	int enabled;
 	bool ret = true, can_inject = true;
 
+	trace_vgic_update_irq_pending(cpuid, irq_num, level);
+
 	if (irq_num >= min(kvm->arch.vgic.nr_irqs, 1020))
 		return -EINVAL;
 
-- 
2.1.2.330.g565301e.dirty



From christoffer.dall at linaro.org  Sun Aug 30 06:55:22 2015
From: christoffer.dall at linaro.org (Christoffer Dall)
Date: Sun, 30 Aug 2015 15:55:22 +0200
Subject: [PATCH 2/2] arm/arm64: KVM: Improve kvm_exit tracepoint
In-Reply-To: <1440942922-23955-1-git-send-email-christoffer.dall@linaro.org>
References: <1440942922-23955-1-git-send-email-christoffer.dall@linaro.org>
Message-ID: <1440942922-23955-3-git-send-email-christoffer.dall@linaro.org>

The ARM architecture only saves the exit class to the HSR (ESR_EL2 for
arm64) on synchronous exceptions, not on asynchronous exceptions like an
IRQ.  However, we only report the exception class on kvm_exit, which is
confusing because an IRQ looks like it exited at some PC with the same
reason as the previous exit.  Add a lookup table for the exception index
and prepend the kvm_exit tracepoint text with the exception type to
clarify this situation.

Also resolve the exception class (EC) to a human-friendly text version
so the trace output becomes immediately usable for debugging this code.

Signed-off-by: Christoffer Dall <christoffer.dall at linaro.org>
---
 arch/arm/include/asm/kvm_arm.h   | 20 ++++++++++++++++++++
 arch/arm/kvm/arm.c               |  2 +-
 arch/arm/kvm/trace.h             | 10 +++++++---
 arch/arm64/include/asm/kvm_arm.h | 16 ++++++++++++++++
 4 files changed, 44 insertions(+), 4 deletions(-)

diff --git a/arch/arm/include/asm/kvm_arm.h b/arch/arm/include/asm/kvm_arm.h
index d995821..dc641dd 100644
--- a/arch/arm/include/asm/kvm_arm.h
+++ b/arch/arm/include/asm/kvm_arm.h
@@ -218,4 +218,24 @@
 #define HSR_DABT_CM		(1U << 8)
 #define HSR_DABT_EA		(1U << 9)
 
+#define kvm_arm_exception_type	\
+	{0, "RESET" }, 		\
+	{1, "UNDEFINED" },	\
+	{2, "SOFTWARE" },	\
+	{3, "PREF_ABORT" },	\
+	{4, "DATA_ABORT" },	\
+	{5, "IRQ" },		\
+	{6, "FIQ" },		\
+	{7, "HVC" }
+
+#define HSRECN(x) { HSR_EC_##x, #x }
+
+#define kvm_arm_exception_class \
+	HSRECN(UNKNOWN), HSRECN(WFI), HSRECN(CP15_32), HSRECN(CP15_64), \
+	HSRECN(CP14_MR), HSRECN(CP14_LS), HSRECN(CP_0_13), HSRECN(CP10_ID), \
+	HSRECN(JAZELLE), HSRECN(BXJ), HSRECN(CP14_64), HSRECN(SVC_HYP), \
+	HSRECN(HVC), HSRECN(SMC), HSRECN(IABT), HSRECN(IABT_HYP), \
+	HSRECN(DABT), HSRECN(DABT_HYP)
+
+
 #endif /* __ARM_KVM_ARM_H__ */
diff --git a/arch/arm/kvm/arm.c b/arch/arm/kvm/arm.c
index 102a4aa..ffec2f2 100644
--- a/arch/arm/kvm/arm.c
+++ b/arch/arm/kvm/arm.c
@@ -606,7 +606,7 @@ int kvm_arch_vcpu_ioctl_run(struct kvm_vcpu *vcpu, struct kvm_run *run)
 		 * guest time.
 		 */
 		kvm_guest_exit();
-		trace_kvm_exit(kvm_vcpu_trap_get_class(vcpu), *vcpu_pc(vcpu));
+		trace_kvm_exit(ret, kvm_vcpu_trap_get_class(vcpu), *vcpu_pc(vcpu));
 
 		/*
 		 * We must sync the timer state before the vgic state so that
diff --git a/arch/arm/kvm/trace.h b/arch/arm/kvm/trace.h
index 0ec3539..c25a885 100644
--- a/arch/arm/kvm/trace.h
+++ b/arch/arm/kvm/trace.h
@@ -25,21 +25,25 @@ TRACE_EVENT(kvm_entry,
 );
 
 TRACE_EVENT(kvm_exit,
-	TP_PROTO(unsigned int exit_reason, unsigned long vcpu_pc),
-	TP_ARGS(exit_reason, vcpu_pc),
+	TP_PROTO(int idx, unsigned int exit_reason, unsigned long vcpu_pc),
+	TP_ARGS(idx, exit_reason, vcpu_pc),
 
 	TP_STRUCT__entry(
+		__field(	int,		idx		)
 		__field(	unsigned int,	exit_reason	)
 		__field(	unsigned long,	vcpu_pc		)
 	),
 
 	TP_fast_assign(
+		__entry->idx			= idx;
 		__entry->exit_reason		= exit_reason;
 		__entry->vcpu_pc		= vcpu_pc;
 	),
 
-	TP_printk("HSR_EC: 0x%04x, PC: 0x%08lx",
+	TP_printk("%s: HSR_EC: 0x%04x (%s), PC: 0x%08lx",
+		  __print_symbolic(__entry->idx, kvm_arm_exception_type),
 		  __entry->exit_reason,
+		  __print_symbolic(__entry->exit_reason, kvm_arm_exception_class),
 		  __entry->vcpu_pc)
 );
 
diff --git a/arch/arm64/include/asm/kvm_arm.h b/arch/arm64/include/asm/kvm_arm.h
index 7605e09..ffb86bf 100644
--- a/arch/arm64/include/asm/kvm_arm.h
+++ b/arch/arm64/include/asm/kvm_arm.h
@@ -197,4 +197,20 @@
 /* Hyp Prefetch Fault Address Register (HPFAR/HDFAR) */
 #define HPFAR_MASK	(~UL(0xf))
 
+#define kvm_arm_exception_type	\
+	{0, "IRQ" }, 		\
+	{1, "TRAP" }
+
+#define ECN(x) { ESR_ELx_EC_##x, #x }
+
+#define kvm_arm_exception_class \
+	ECN(UNKNOWN), ECN(WFx), ECN(CP15_32), ECN(CP15_64), ECN(CP14_MR), \
+	ECN(CP14_LS), ECN(FP_ASIMD), ECN(CP10_ID), ECN(CP14_64), ECN(SVC64), \
+	ECN(HVC64), ECN(SMC64), ECN(SYS64), ECN(IMP_DEF), ECN(IABT_LOW), \
+	ECN(IABT_CUR), ECN(PC_ALIGN), ECN(DABT_LOW), ECN(DABT_CUR), \
+	ECN(SP_ALIGN), ECN(FP_EXC32), ECN(FP_EXC64), ECN(SERROR), \
+	ECN(BREAKPT_LOW), ECN(BREAKPT_CUR), ECN(SOFTSTP_LOW), \
+	ECN(SOFTSTP_CUR), ECN(WATCHPT_LOW), ECN(WATCHPT_CUR), \
+	ECN(BKPT32), ECN(VECTOR32), ECN(BRK64)
+
 #endif /* __ARM64_KVM_ARM_H__ */
-- 
2.1.2.330.g565301e.dirty



From christoffer.dall at linaro.org  Sun Aug 30 06:55:20 2015
From: christoffer.dall at linaro.org (Christoffer Dall)
Date: Sun, 30 Aug 2015 15:55:20 +0200
Subject: [PATCH 0/2] Improve and add tracepoints for KVM on arm/arm64
Message-ID: <1440942922-23955-1-git-send-email-christoffer.dall@linaro.org>

The timer and vgic code didn't have tracepoints for quite a while and
we've been adding those ad-hoc when doing development a lot of times.
Add some simple tracepoints for those parts of KVM to get the
infrastructure in place.

Also improve the kvm_exit tracepoint on arm/arm64 to print something
meaningful and be much less misleading compared to what we have now.

This series depends on the "Rework architected timer and fix UEFI reset"
series sent earlier.  It is also available here:

https://git.linaro.org/people/christoffer.dall/linux-kvm-arm.git tracing-fixup

I borrowed some of this code from Alex Benn?e, thanks!

Christoffer Dall (2):
  arm/arm64: KVM: Add tracepoints for vgic and timer
  arm/arm64: KVM: Improve kvm_exit tracepoint

 arch/arm/include/asm/kvm_arm.h   | 20 +++++++++
 arch/arm/kvm/arm.c               |  2 +-
 arch/arm/kvm/trace.h             | 10 +++--
 arch/arm64/include/asm/kvm_arm.h | 16 +++++++
 virt/kvm/arm/arch_timer.c        |  4 ++
 virt/kvm/arm/trace.h             | 97 ++++++++++++++++++++++++++++++++++++++++
 virt/kvm/arm/vgic.c              |  9 ++++
 7 files changed, 154 insertions(+), 4 deletions(-)
 create mode 100644 virt/kvm/arm/trace.h

-- 
2.1.2.330.g565301e.dirty



From mchehab at osg.samsung.com  Sun Aug 30 07:27:53 2015
From: mchehab at osg.samsung.com (Mauro Carvalho Chehab)
Date: Sun, 30 Aug 2015 11:27:53 -0300
Subject: [PATCH v8 00/55] MC next generation patches
In-Reply-To: <cover.1440902901.git.mchehab@osg.samsung.com>
References: <cover.1440902901.git.mchehab@osg.samsung.com>
Message-ID: <20150830112753.65858fdd@recife.lan>

Em Sun, 30 Aug 2015 00:06:11 -0300
Mauro Carvalho Chehab <mchehab at osg.samsung.com> escreveu:

> That's the 8th version of the MC next generation patches.
> 
> Differences from version 7:
> 
> - Patches reworked to make the reviewers happy;
> - Bug fixes;
> - ALSA changes got their own separate patches;
> - Javier patches got integrated into this series;
> - media-entity.h structs are now properly documented;
> - Tested on both au0828 and omap3isp.
> 
> Due to the complexity of this change, other platform drivers may
> require some fixes. 
> 
> As the patch series sent before, this is not meant to be sent
> upstream yet. Its goal is to merge it for Kernel 4.4, in order to
> give people enough time to review and fix pending issues.

As on the previous series, the patches are available on my experimental
tree:
	http://git.linuxtv.org/cgit.cgi/mchehab/experimental.git/log/?h=mc_next_gen

There's one additional patch there that removes the backlinks from G_TOPOLOGY
ioctl. I'll be posting it in separate at the ML.

I also added a new branch:
	http://git.linuxtv.org/cgit.cgi/mchehab/experimental.git/log/?h=mc_next_gen_test

Based on the first one. It contains a hack for au0828 that exposes the tuner
also via subdev devnode, and reduces the number of output pads of the DVB
demux to just 5, as the default is too high to produce a .dot file that
would be useful. Of course, this patch should never leave my experimental
tree ;) 

There are a few other from Javier there meant to allow testing the omap3isp
on my Beaglebone (that doesn't have any sensor on it) and on his omap3
devices.

I added support at the mc_nextgen_test tool to produce Graphviz .dot
files. It is still experimental, but it is good enough to already produce
some useful graphs. The newest version is at:

	http://git.linuxtv.org/cgit.cgi/mchehab/experimental-v4l-utils.git/log/?h=mc-next-gen

I added some graphs produced by it at:
	https://mchehab.fedorapeople.org/mc-next-gen/

Regards,
Mauro


From j at jannau.net  Sun Aug 30 08:24:28 2015
From: j at jannau.net (Janne Grunau)
Date: Sun, 30 Aug 2015 17:24:28 +0200
Subject: [arm64/apm] add support for the gigabyte mp30-ar0 board
Message-ID: <1440948270-1991-1-git-send-email-j@jannau.net>

Hi,

following two patches add support for the gigabyte mp30-ar0 mainboard
based on the APM X-Gene Storm (APM883408). The only difference to the
APM88320T used in the mustang board seems to be that it has 4 instead
of 2 DDR memory controllers.

Every device defined in 4.2-rc8's apm-storm.dtsi appears to work.
I haven't tested the 10G ethernet device and the PCIexpress slots.
The second 10G device is missing. It boots only with clk_ignored_unused.
I haven't had a chance to investigate why. The bootloader doesn't clear
x2 and x3.

The board ships with u-boot (U-Boot 2013.04 (Jun 02 2015 - 10:54:10)
REV: 1.15.01-F05), Linux 3.12 and a buildroot based initrd. There seems
no sources available for the shipped binaries. There is no mention of
the GPL in the handbook or shipped materials. The handbook is available
from http://b2b.gigabyte.com/products/product-page.aspx?pid=5422#manual .
The binaries are also available as download from http://b2b.gigabyte.com/products/product-page.aspx?pid=5422#bios .

I asked Thursday for sources of the GPL licensed parts but have of
course no answer yet.

cheers,

Janne


 arch/arm64/boot/dts/apm/Makefile              |  1 +
 arch/arm64/boot/dts/apm/apm-mustang.dts       |  1 +
 arch/arm64/boot/dts/apm/apm-storm-883208.dtsi | 99 +++++++++++++++++++++++++++++++++++++++++++++++++++
 arch/arm64/boot/dts/apm/apm-storm-883408.dtsi | 98 ++++++++++++++++++++++++++++++++++++++++++++++++++
 arch/arm64/boot/dts/apm/apm-storm.dtsi        | 87 --------------------------------------------
 arch/arm64/boot/dts/apm/mp30ar0.dts           | 85 +++++++++++++++++++++++++++++++++++++++++++



From j at jannau.net  Sun Aug 30 08:24:30 2015
From: j at jannau.net (Janne Grunau)
Date: Sun, 30 Aug 2015 17:24:30 +0200
Subject: [PATCH 2/2] arm64/apm: add dts for Gigabyte MP30-AR0 board
In-Reply-To: <1440948270-1991-1-git-send-email-j@jannau.net>
References: <1440948270-1991-1-git-send-email-j@jannau.net>
Message-ID: <1440948270-1991-3-git-send-email-j@jannau.net>

Creates apm-storm-883408.dtsi which should be shareable with the HP
Moonshot m400 cartridge.

Signed-off-by: Janne Grunau <j at jannau.net>
---
 arch/arm64/boot/dts/apm/Makefile              |  1 +
 arch/arm64/boot/dts/apm/apm-storm-883408.dtsi | 98 +++++++++++++++++++++++++++
 arch/arm64/boot/dts/apm/mp30ar0.dts           | 85 +++++++++++++++++++++++
 3 files changed, 184 insertions(+)
 create mode 100644 arch/arm64/boot/dts/apm/apm-storm-883408.dtsi
 create mode 100644 arch/arm64/boot/dts/apm/mp30ar0.dts

diff --git a/arch/arm64/boot/dts/apm/Makefile b/arch/arm64/boot/dts/apm/Makefile
index a2afabb..b0ec2b6 100644
--- a/arch/arm64/boot/dts/apm/Makefile
+++ b/arch/arm64/boot/dts/apm/Makefile
@@ -1,4 +1,5 @@
 dtb-$(CONFIG_ARCH_XGENE) += apm-mustang.dtb
+dtb-$(CONFIG_ARCH_XGENE) += mp30ar0.dtb
 
 always		:= $(dtb-y)
 subdir-y	:= $(dts-dirs)
diff --git a/arch/arm64/boot/dts/apm/apm-storm-883408.dtsi b/arch/arm64/boot/dts/apm/apm-storm-883408.dtsi
new file mode 100644
index 0000000..83116df
--- /dev/null
+++ b/arch/arm64/boot/dts/apm/apm-storm-883408.dtsi
@@ -0,0 +1,98 @@
+/*
+ * dts file for AppliedMicro (APM) X-Gene Storm SOC APM883408
+ *
+ * Copyright (C) 2013, Applied Micro Circuits Corporation
+ *
+ * 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.
+ */
+
+/ {
+	compatible = "apm,xgene-storm";
+	interrupt-parent = <&gic>;
+	#address-cells = <2>;
+	#size-cells = <2>;
+
+	cpus {
+		#address-cells = <2>;
+		#size-cells = <0>;
+
+		cpu at 000 {
+			device_type = "cpu";
+			compatible = "apm,potenza", "arm,armv8";
+			reg = <0x0 0x000>;
+			enable-method = "spin-table";
+			cpu-release-addr = <0x40 0x0000fff8>;
+		};
+		cpu at 001 {
+			device_type = "cpu";
+			compatible = "apm,potenza", "arm,armv8";
+			reg = <0x0 0x001>;
+			enable-method = "spin-table";
+			cpu-release-addr = <0x40 0x0000fff8>;
+		};
+		cpu at 100 {
+			device_type = "cpu";
+			compatible = "apm,potenza", "arm,armv8";
+			reg = <0x0 0x100>;
+			enable-method = "spin-table";
+			cpu-release-addr = <0x40 0x0000fff8>;
+		};
+		cpu at 101 {
+			device_type = "cpu";
+			compatible = "apm,potenza", "arm,armv8";
+			reg = <0x0 0x101>;
+			enable-method = "spin-table";
+			cpu-release-addr = <0x40 0x0000fff8>;
+		};
+		cpu at 200 {
+			device_type = "cpu";
+			compatible = "apm,potenza", "arm,armv8";
+			reg = <0x0 0x200>;
+			enable-method = "spin-table";
+			cpu-release-addr = <0x40 0x0000fff8>;
+		};
+		cpu at 201 {
+			device_type = "cpu";
+			compatible = "apm,potenza", "arm,armv8";
+			reg = <0x0 0x201>;
+			enable-method = "spin-table";
+			cpu-release-addr = <0x40 0x0000fff8>;
+		};
+		cpu at 300 {
+			device_type = "cpu";
+			compatible = "apm,potenza", "arm,armv8";
+			reg = <0x0 0x300>;
+			enable-method = "spin-table";
+			cpu-release-addr = <0x40 0x0000fff8>;
+		};
+		cpu at 301 {
+			device_type = "cpu";
+			compatible = "apm,potenza", "arm,armv8";
+			reg = <0x0 0x301>;
+			enable-method = "spin-table";
+			cpu-release-addr = <0x40 0x0000fff8>;
+		};
+	};
+
+	gic: interrupt-controller at 78090000 {
+		compatible = "arm,cortex-a15-gic";
+		#interrupt-cells = <3>;
+		interrupt-controller;
+		reg = <0x0 0x78090000 0x0 0x10000>,	/* GIC Dist */
+		      <0x0 0x780a0000 0x0 0x10000>,	/* GIC CPU */
+		      <0x0 0x780c0000 0x0 0x20000>,	/* GIC VCPU Control */
+		      <0x0 0x780e0000 0x0 0x20000>;	/* GIC VCPU */
+		interrupts = <1 9 0xf04>;
+	};
+	timer {
+		compatible = "arm,armv8-timer";
+		interrupts = <1 0 0xff04>,	/* Secure Phys IRQ */
+			     <1 13 0xff04>,	/* Non-secure Phys IRQ */
+			     <1 14 0xff04>,	/* Virt IRQ */
+			     <1 15 0xff04>;	/* Hyp IRQ */
+		clock-frequency = <50000000>;
+	};
+};
diff --git a/arch/arm64/boot/dts/apm/mp30ar0.dts b/arch/arm64/boot/dts/apm/mp30ar0.dts
new file mode 100644
index 0000000..f7a9dae5
--- /dev/null
+++ b/arch/arm64/boot/dts/apm/mp30ar0.dts
@@ -0,0 +1,85 @@
+/*
+ * dts file for Gigabyte MP30-AR0 board
+ *
+ * Copyright (C) 2013, Applied Micro Circuits Corporation
+ *
+ * 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.
+ */
+
+/dts-v1/;
+
+/include/ "apm-storm-883408.dtsi"
+/include/ "apm-storm-soc.dtsi"
+
+/ {
+	pmu {
+		compatible = "arm,armv8-pmuv3";
+		interrupts = <0x1 0xc 0xff04>;
+	};
+
+	memory {
+		#address-cells = <0x2>;
+		#size-cells = <0x2>;
+		device_type = "memory";
+		reg = <0x0 0x0 0x0 0x2000000>;
+	};
+
+	poweroff_mbox: poweroff_mbox at 10548000 {
+		compatible = "syscon";
+		reg = <0x0 0x10548000 0x0 0x100>;
+	};
+
+	poweroff at 10548010 {
+		compatible = "syscon-poweroff";
+		regmap = <&poweroff_mbox>;
+		offset = <0x10>;
+		mask = <0x1>;
+	};
+
+	chosen {
+		linux,stdout-path = "/soc/serial at 1c020000";
+	};
+};
+
+&pcie0clk {
+	status = "ok";
+};
+
+&pcie2clk {
+	status = "ok";
+};
+
+&pcie3clk {
+	status = "ok";
+};
+
+&pcie0 {
+	status = "ok";
+};
+
+&pcie2 {
+	status = "ok";
+};
+
+&pcie3 {
+	status = "ok";
+};
+
+&serial0 {
+	status = "ok";
+};
+
+&sgenet0 {
+	status = "ok";
+};
+
+&sgenet1 {
+	status = "ok";
+};
+
+&xgenet {
+	status = "ok";
+};
-- 
2.5.0



From j at jannau.net  Sun Aug 30 08:24:29 2015
From: j at jannau.net (Janne Grunau)
Date: Sun, 30 Aug 2015 17:24:29 +0200
Subject: [PATCH 1/2] arm64/apm: create X-Gene storm chip variant dtsi
In-Reply-To: <1440948270-1991-1-git-send-email-j@jannau.net>
References: <1440948270-1991-1-git-send-email-j@jannau.net>
Message-ID: <1440948270-1991-2-git-send-email-j@jannau.net>

The CPU and timer table and GIC registers differ between APM883208 and
APM883408 chip variants.  Move them to their own file so the soc node in
apm-storm.dtsi can be shared.

Signed-off-by: Janne Grunau <j at jannau.net>
---
 arch/arm64/boot/dts/apm/apm-mustang.dts       |  1 +
 arch/arm64/boot/dts/apm/apm-storm-883208.dtsi | 99 +++++++++++++++++++++++++++
 arch/arm64/boot/dts/apm/apm-storm.dtsi        | 87 -----------------------
 3 files changed, 100 insertions(+), 87 deletions(-)
 create mode 100644 arch/arm64/boot/dts/apm/apm-storm-883208.dtsi

diff --git a/arch/arm64/boot/dts/apm/apm-mustang.dts b/arch/arm64/boot/dts/apm/apm-mustang.dts
index 4c55833..096e5ec 100644
--- a/arch/arm64/boot/dts/apm/apm-mustang.dts
+++ b/arch/arm64/boot/dts/apm/apm-mustang.dts
@@ -11,6 +11,7 @@
 
 /dts-v1/;
 
+/include/ "apm-storm-883208.dtsi"
 /include/ "apm-storm.dtsi"
 
 / {
diff --git a/arch/arm64/boot/dts/apm/apm-storm-883208.dtsi b/arch/arm64/boot/dts/apm/apm-storm-883208.dtsi
new file mode 100644
index 0000000..e4daaf9
--- /dev/null
+++ b/arch/arm64/boot/dts/apm/apm-storm-883208.dtsi
@@ -0,0 +1,99 @@
+/*
+ * dts file for AppliedMicro (APM) X-Gene Storm SOC
+ *
+ * Copyright (C) 2013, Applied Micro Circuits Corporation
+ *
+ * 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.
+ */
+
+/ {
+	compatible = "apm,xgene-storm";
+	interrupt-parent = <&gic>;
+	#address-cells = <2>;
+	#size-cells = <2>;
+
+	cpus {
+		#address-cells = <2>;
+		#size-cells = <0>;
+
+		cpu at 000 {
+			device_type = "cpu";
+			compatible = "apm,potenza", "arm,armv8";
+			reg = <0x0 0x000>;
+			enable-method = "spin-table";
+			cpu-release-addr = <0x1 0x0000fff8>;
+		};
+		cpu at 001 {
+			device_type = "cpu";
+			compatible = "apm,potenza", "arm,armv8";
+			reg = <0x0 0x001>;
+			enable-method = "spin-table";
+			cpu-release-addr = <0x1 0x0000fff8>;
+		};
+		cpu at 100 {
+			device_type = "cpu";
+			compatible = "apm,potenza", "arm,armv8";
+			reg = <0x0 0x100>;
+			enable-method = "spin-table";
+			cpu-release-addr = <0x1 0x0000fff8>;
+		};
+		cpu at 101 {
+			device_type = "cpu";
+			compatible = "apm,potenza", "arm,armv8";
+			reg = <0x0 0x101>;
+			enable-method = "spin-table";
+			cpu-release-addr = <0x1 0x0000fff8>;
+		};
+		cpu at 200 {
+			device_type = "cpu";
+			compatible = "apm,potenza", "arm,armv8";
+			reg = <0x0 0x200>;
+			enable-method = "spin-table";
+			cpu-release-addr = <0x1 0x0000fff8>;
+		};
+		cpu at 201 {
+			device_type = "cpu";
+			compatible = "apm,potenza", "arm,armv8";
+			reg = <0x0 0x201>;
+			enable-method = "spin-table";
+			cpu-release-addr = <0x1 0x0000fff8>;
+		};
+		cpu at 300 {
+			device_type = "cpu";
+			compatible = "apm,potenza", "arm,armv8";
+			reg = <0x0 0x300>;
+			enable-method = "spin-table";
+			cpu-release-addr = <0x1 0x0000fff8>;
+		};
+		cpu at 301 {
+			device_type = "cpu";
+			compatible = "apm,potenza", "arm,armv8";
+			reg = <0x0 0x301>;
+			enable-method = "spin-table";
+			cpu-release-addr = <0x1 0x0000fff8>;
+		};
+	};
+
+	gic: interrupt-controller at 78010000 {
+		compatible = "arm,cortex-a15-gic";
+		#interrupt-cells = <3>;
+		interrupt-controller;
+		reg = <0x0 0x78010000 0x0 0x1000>,	/* GIC Dist */
+		      <0x0 0x78020000 0x0 0x1000>,	/* GIC CPU */
+		      <0x0 0x78040000 0x0 0x2000>,	/* GIC VCPU Control */
+		      <0x0 0x78060000 0x0 0x2000>;	/* GIC VCPU */
+		interrupts = <1 9 0xf04>;	/* GIC Maintenence IRQ */
+	};
+
+	timer {
+		compatible = "arm,armv8-timer";
+		interrupts = <1 0 0xff01>,	/* Secure Phys IRQ */
+			     <1 13 0xff01>,	/* Non-secure Phys IRQ */
+			     <1 14 0xff01>,	/* Virt IRQ */
+			     <1 15 0xff01>;	/* Hyp IRQ */
+		clock-frequency = <50000000>;
+	};
+};
diff --git a/arch/arm64/boot/dts/apm/apm-storm.dtsi b/arch/arm64/boot/dts/apm/apm-storm.dtsi
index 58093ed..4177b3d 100644
--- a/arch/arm64/boot/dts/apm/apm-storm.dtsi
+++ b/arch/arm64/boot/dts/apm/apm-storm.dtsi
@@ -10,93 +10,6 @@
  */
 
 / {
-	compatible = "apm,xgene-storm";
-	interrupt-parent = <&gic>;
-	#address-cells = <2>;
-	#size-cells = <2>;
-
-	cpus {
-		#address-cells = <2>;
-		#size-cells = <0>;
-
-		cpu at 000 {
-			device_type = "cpu";
-			compatible = "apm,potenza", "arm,armv8";
-			reg = <0x0 0x000>;
-			enable-method = "spin-table";
-			cpu-release-addr = <0x1 0x0000fff8>;
-		};
-		cpu at 001 {
-			device_type = "cpu";
-			compatible = "apm,potenza", "arm,armv8";
-			reg = <0x0 0x001>;
-			enable-method = "spin-table";
-			cpu-release-addr = <0x1 0x0000fff8>;
-		};
-		cpu at 100 {
-			device_type = "cpu";
-			compatible = "apm,potenza", "arm,armv8";
-			reg = <0x0 0x100>;
-			enable-method = "spin-table";
-			cpu-release-addr = <0x1 0x0000fff8>;
-		};
-		cpu at 101 {
-			device_type = "cpu";
-			compatible = "apm,potenza", "arm,armv8";
-			reg = <0x0 0x101>;
-			enable-method = "spin-table";
-			cpu-release-addr = <0x1 0x0000fff8>;
-		};
-		cpu at 200 {
-			device_type = "cpu";
-			compatible = "apm,potenza", "arm,armv8";
-			reg = <0x0 0x200>;
-			enable-method = "spin-table";
-			cpu-release-addr = <0x1 0x0000fff8>;
-		};
-		cpu at 201 {
-			device_type = "cpu";
-			compatible = "apm,potenza", "arm,armv8";
-			reg = <0x0 0x201>;
-			enable-method = "spin-table";
-			cpu-release-addr = <0x1 0x0000fff8>;
-		};
-		cpu at 300 {
-			device_type = "cpu";
-			compatible = "apm,potenza", "arm,armv8";
-			reg = <0x0 0x300>;
-			enable-method = "spin-table";
-			cpu-release-addr = <0x1 0x0000fff8>;
-		};
-		cpu at 301 {
-			device_type = "cpu";
-			compatible = "apm,potenza", "arm,armv8";
-			reg = <0x0 0x301>;
-			enable-method = "spin-table";
-			cpu-release-addr = <0x1 0x0000fff8>;
-		};
-	};
-
-	gic: interrupt-controller at 78010000 {
-		compatible = "arm,cortex-a15-gic";
-		#interrupt-cells = <3>;
-		interrupt-controller;
-		reg = <0x0 0x78010000 0x0 0x1000>,	/* GIC Dist */
-		      <0x0 0x78020000 0x0 0x1000>,	/* GIC CPU */
-		      <0x0 0x78040000 0x0 0x2000>,	/* GIC VCPU Control */
-		      <0x0 0x78060000 0x0 0x2000>;	/* GIC VCPU */
-		interrupts = <1 9 0xf04>;	/* GIC Maintenence IRQ */
-	};
-
-	timer {
-		compatible = "arm,armv8-timer";
-		interrupts = <1 0 0xff01>,	/* Secure Phys IRQ */
-			     <1 13 0xff01>,	/* Non-secure Phys IRQ */
-			     <1 14 0xff01>,	/* Virt IRQ */
-			     <1 15 0xff01>;	/* Hyp IRQ */
-		clock-frequency = <50000000>;
-	};
-
 	soc {
 		compatible = "simple-bus";
 		#address-cells = <2>;
-- 
2.5.0



From sunil.kovvuri at gmail.com  Sun Aug 30 09:31:04 2015
From: sunil.kovvuri at gmail.com (Sunil Kovvuri)
Date: Sun, 30 Aug 2015 22:01:04 +0530
Subject: [PATCH net-next 6/8] net: thunderx: Rework interrupt handler
In-Reply-To: <55E2CAE6.1040305@auriga.com>
References: <CALW4P++2cG5epoit8BXBjp7Z2PK=P5wqbxkDqrt6kCa7SaZK+g@mail.gmail.com>
 <55E2CAE6.1040305@auriga.com>
Message-ID: <CA+sq2CdEn4vq3FD5RyQwuagmE9TNu91XmamjEFLaF4SOyrp64A@mail.gmail.com>

On Sun, Aug 30, 2015 at 2:50 PM, Aleksey Makarov <feumilieu at gmail.com> wrote:
> On 29.08.2015 04:44, Alexey Klimov wrote:
>
>>> -static irqreturn_t nicvf_intr_handler(int irq, void *nicvf_irq)
>>> +static irqreturn_t nicvf_intr_handler(int irq, void *cq_irq)
>>> +{
>>> +       struct nicvf_cq_poll *cq_poll = (struct nicvf_cq_poll *)cq_irq;
>>> +       struct nicvf *nic = cq_poll->nicvf;
>>> +       int qidx = cq_poll->cq_idx;
>>> +
>>> +       nicvf_dump_intr_status(nic);
>>> +
>>> +       /* Disable interrupts */
>>> +       nicvf_disable_intr(nic, NICVF_INTR_CQ, qidx);
>>> +
>>> +       /* Schedule NAPI */
>>> +       napi_schedule(&cq_poll->napi);
>>> +
>>> +       /* Clear interrupt */
>>> +       nicvf_clear_intr(nic, NICVF_INTR_CQ, qidx);
>>> +
>>> +       return IRQ_HANDLED;
>>> +}
>>
>>
>> You're not considering spurious irqs in all new irq handlers here and
>> below and schedule napi/tasklets unconditionally. Is it correct?
>> For me it looks like previous implementation relied on reading of
>> NIC_VF_INT to understand irq type and what actions should be
>> performed. It generally had idea that no interrupt might occur.
>
>
> 1. The previous version of the handler did not handle spurious interrupts
> either.  Probably that means that the author of the patch knows for sure
> that they do not happen.

Yes, no spurious interrupts are expected from hardware.
Even if it does the NAPI poll routine will handle it as valid
descriptor count would be zero.
Don't think it makes sense to check for spurious interrupt upon every interrupt.

>
> 2. Instead of reading the status register new version registers different
> handlers for different irqs.  I don't see why it can be wrong.

Previous implementation results on scheduling multiple NAPI poll handlers
on the same CPU even if IRQ's affinities are set to different CPUs.
Hence they are seperated now.

>
> I am going to address your other suggestions in the next version of the
> patchset.
>
> Thank you
> Aleksey Makarov
>


From christoffer.dall at linaro.org  Sun Aug 30 09:53:00 2015
From: christoffer.dall at linaro.org (Christoffer Dall)
Date: Sun, 30 Aug 2015 18:53:00 +0200
Subject: [PATCH] arm64/kvm: set {v,}TCR_EL2 RES1 bits
In-Reply-To: <1440423725-31700-1-git-send-email-mark.rutland@arm.com>
References: <1440423725-31700-1-git-send-email-mark.rutland@arm.com>
Message-ID: <20150830165300.GF24113@cbox>

On Mon, Aug 24, 2015 at 02:42:05PM +0100, Mark Rutland wrote:
> Currently we don't set the RES1 bits of TCR_EL2 and VTCR_EL2 when
> configuring them, which could lead to unexpected behaviour when an
> architectural meaning is defined for those bits.
> 
> Set the RES1 bits to avoid issues.
> 
> Signed-off-by: Mark Rutland <mark.rutland at arm.com>
> Cc: Catalin Marinas <catalin.marinas at arm.com>
> Cc: Christoffer Dall <christoffer.dall at linaro.org>
> Cc: Marc Zyngier <marc.zyngier at arm.com>
> Cc: Suzuki Poulose <suzuki.poulose at arm.com>
> Cc: Will Deacon <will.deacon at arm.com>

Reviewed-by: Christoffer Dall <christoffer.dall at linaro.org>


From j at jannau.net  Sun Aug 30 10:26:32 2015
From: j at jannau.net (Janne Grunau)
Date: Sun, 30 Aug 2015 19:26:32 +0200
Subject: [PATCH 2/2] arm64/apm: add dts for Gigabyte MP30-AR0 board
In-Reply-To: <1440948270-1991-3-git-send-email-j@jannau.net>
References: <1440948270-1991-1-git-send-email-j@jannau.net>
 <1440948270-1991-3-git-send-email-j@jannau.net>
Message-ID: <20150830172632.GH17056@jannau.net>

On 2015-08-30 17:24:30 +0200, Janne Grunau wrote:
> Creates apm-storm-883408.dtsi which should be shareable with the HP
> Moonshot m400 cartridge.
> 
> Signed-off-by: Janne Grunau <j at jannau.net>
> ---
>  arch/arm64/boot/dts/apm/Makefile              |  1 +
>  arch/arm64/boot/dts/apm/apm-storm-883408.dtsi | 98 +++++++++++++++++++++++++++
>  arch/arm64/boot/dts/apm/mp30ar0.dts           | 85 +++++++++++++++++++++++
>  3 files changed, 184 insertions(+)
>  create mode 100644 arch/arm64/boot/dts/apm/apm-storm-883408.dtsi
>  create mode 100644 arch/arm64/boot/dts/apm/mp30ar0.dts
>
> diff --git a/arch/arm64/boot/dts/apm/mp30ar0.dts b/arch/arm64/boot/dts/apm/mp30ar0.dts
> new file mode 100644
> index 0000000..f7a9dae5
> --- /dev/null
> +++ b/arch/arm64/boot/dts/apm/mp30ar0.dts
> @@ -0,0 +1,85 @@
> +/*
> + * dts file for Gigabyte MP30-AR0 board
> + *
> + * Copyright (C) 2013, Applied Micro Circuits Corporation
> + *
> + * 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.
> + */
> +
> +/dts-v1/;
> +
> +/include/ "apm-storm-883408.dtsi"
> +/include/ "apm-storm-soc.dtsi"

/include/ "apm-storm.dtsi"

I split the soc node first into its own file but then decided that 
keeping the larger part in the same file introduces less merge 
conflicts.

> +
> +/ {
> +	pmu {
> +		compatible = "arm,armv8-pmuv3";
> +		interrupts = <0x1 0xc 0xff04>;
> +	};
> +
> +	memory {
> +		#address-cells = <0x2>;
> +		#size-cells = <0x2>;
> +		device_type = "memory";
> +		reg = <0x0 0x0 0x0 0x2000000>;
> +	};
> +
> +	poweroff_mbox: poweroff_mbox at 10548000 {
> +		compatible = "syscon";
> +		reg = <0x0 0x10548000 0x0 0x100>;
> +	};
> +
> +	poweroff at 10548010 {
> +		compatible = "syscon-poweroff";
> +		regmap = <&poweroff_mbox>;
> +		offset = <0x10>;
> +		mask = <0x1>;
> +	};

This doesn't seem to work, even with the poweroff/reset patches for 
mustang.

Janne


From vladimir_zapolskiy at mentor.com  Sun Aug 30 14:34:30 2015
From: vladimir_zapolskiy at mentor.com (Vladimir Zapolskiy)
Date: Mon, 31 Aug 2015 00:34:30 +0300
Subject: [PATCH v3 2/2] drm: bridge/dw_hdmi: add dw hdmi i2c bus adapter
 support
Message-ID: <1440970470-7155-1-git-send-email-vladimir_zapolskiy@mentor.com>

The change adds support of internal HDMI I2C master controller, this
subdevice is used by default, if "ddc-i2c-bus" DT property is omitted.

The main purpose of this functionality is to support reading EDID from
an HDMI monitor on boards, which don't have an I2C bus connected to
DDC pins.

The current implementation does not support "I2C Master Interface
Extended Read Mode" to read data addressed by non-zero segment
pointer, this means that if EDID has more than 1 extension blocks,
EDID reading operation won't succeed, in my practice all tested HDMI
monitors have at maximum one extension block.

Signed-off-by: Vladimir Zapolskiy <vladimir_zapolskiy at mentor.com>
---
The change is based on today's v4.2, please let me know, if it should be rebased.

The change has compilation dependency on I2CM_ADDRESS register name fix,
see http://lists.freedesktop.org/archives/dri-devel/2015-May/082980.html

>From http://lists.freedesktop.org/archives/dri-devel/2015-May/082981.html
v1 of the change was

  Tested-by: Philipp Zabel <p.zabel at pengutronix.de>

but I hesitate to add the tag here due to multiple updates in v2.

Changes from v2 to v3, thanks to Russell:
- moved register field value definitions to dw_hdmi.h
- made completions uninterruptible to avoid transfer retries if interrupted
- use one completion for both read and write transfers as in v1, operation_reg is removed
- redundant i2c->stat = 0 is removed from dw_hdmi_i2c_read/write()
- struct i2c_algorithm dw_hdmi_algorithm is qualified as const
- dw_hdmi_i2c_adapter() does not modify struct dw_hdmi on error path
- dw_hdmi_i2c_irq() does not modify hdmi->i2c->stat, if interrupt is not for I2CM
- spin lock is removed from dw_hdmi_i2c_irq()
- removed spin lock from dw_hdmi_i2c_xfer() around write to HDMI_IH_MUTE_I2CM_STAT0 register
- split loop over message array in dw_hdmi_i2c_xfer() to validation and transfer parts
- added a mutex to serialize I2C transfer requests, i2c->lock is completely removed
- removed if(len) check from dw_hdmi_i2c_write(), hardware supports only len>0 transfers
- described extension blocks <= 1 limitation in the commit message
- a number of minor clean ups

Changes from v1 to v2:
- fixed a devm_kfree() signature
- split completions for read and write operations

 drivers/gpu/drm/bridge/dw_hdmi.c | 262 ++++++++++++++++++++++++++++++++++++++-
 drivers/gpu/drm/bridge/dw_hdmi.h |  19 +++
 2 files changed, 275 insertions(+), 6 deletions(-)

diff --git a/drivers/gpu/drm/bridge/dw_hdmi.c b/drivers/gpu/drm/bridge/dw_hdmi.c
index 816d104..d329e04 100644
--- a/drivers/gpu/drm/bridge/dw_hdmi.c
+++ b/drivers/gpu/drm/bridge/dw_hdmi.c
@@ -1,14 +1,15 @@
 /*
+ * DesignWare High-Definition Multimedia Interface (HDMI) driver
+ *
+ * Copyright (C) 2013-2015 Mentor Graphics Inc.
  * Copyright (C) 2011-2013 Freescale Semiconductor, Inc.
+ * Copyright (C) 2010, Guennadi Liakhovetski <g.liakhovetski at gmx.de>
  *
  * 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.
  *
- * Designware High-Definition Multimedia Interface (HDMI) driver
- *
- * Copyright (C) 2010, Guennadi Liakhovetski <g.liakhovetski at gmx.de>
  */
 #include <linux/module.h>
 #include <linux/irq.h>
@@ -102,6 +103,17 @@ struct hdmi_data_info {
 	struct hdmi_vmode video_mode;
 };
 
+struct dw_hdmi_i2c {
+	struct i2c_adapter	adap;
+
+	struct mutex		lock;
+	struct completion	cmp;
+	u8			stat;
+
+	u8			slave_reg;
+	bool			is_regaddr;
+};
+
 struct dw_hdmi {
 	struct drm_connector connector;
 	struct drm_encoder *encoder;
@@ -111,6 +123,7 @@ struct dw_hdmi {
 	struct device *dev;
 	struct clk *isfr_clk;
 	struct clk *iahb_clk;
+	struct dw_hdmi_i2c *i2c;
 
 	struct hdmi_data_info hdmi_data;
 	const struct dw_hdmi_plat_data *plat_data;
@@ -179,6 +192,200 @@ static void hdmi_mask_writeb(struct dw_hdmi *hdmi, u8 data, unsigned int reg,
 	hdmi_modb(hdmi, data << shift, mask, reg);
 }
 
+static void dw_hdmi_i2c_init(struct dw_hdmi *hdmi)
+{
+	/* Set Fast Mode speed */
+	hdmi_writeb(hdmi, 0x0b, HDMI_I2CM_DIV);
+
+	/* Software reset */
+	hdmi_writeb(hdmi, 0x00, HDMI_I2CM_SOFTRSTZ);
+
+	/* Set done, not acknowledged and arbitration interrupt polarities */
+	hdmi_writeb(hdmi, HDMI_I2CM_INT_DONE_POL, HDMI_I2CM_INT);
+	hdmi_writeb(hdmi, HDMI_I2CM_CTLINT_NAC_POL | HDMI_I2CM_CTLINT_ARB_POL,
+		    HDMI_I2CM_CTLINT);
+
+	/* Clear DONE and ERROR interrupts */
+	hdmi_writeb(hdmi, HDMI_IH_I2CM_STAT0_ERROR | HDMI_IH_I2CM_STAT0_DONE,
+		    HDMI_IH_I2CM_STAT0);
+
+	/* Mute DONE and ERROR interrupts */
+	hdmi_writeb(hdmi, HDMI_IH_I2CM_STAT0_ERROR | HDMI_IH_I2CM_STAT0_DONE,
+		    HDMI_IH_MUTE_I2CM_STAT0);
+}
+
+static int dw_hdmi_i2c_read(struct dw_hdmi *hdmi,
+			    unsigned char *buf, unsigned int length)
+{
+	struct dw_hdmi_i2c *i2c = hdmi->i2c;
+	int stat;
+
+	if (!i2c->is_regaddr) {
+		dev_dbg(hdmi->dev, "set read register address to 0\n");
+		i2c->slave_reg = 0x00;
+		i2c->is_regaddr = true;
+	}
+
+	while (length--) {
+		reinit_completion(&i2c->cmp);
+
+		hdmi_writeb(hdmi, i2c->slave_reg++, HDMI_I2CM_ADDRESS);
+		hdmi_writeb(hdmi, HDMI_I2CM_OPERATION_READ,
+			    HDMI_I2CM_OPERATION);
+
+		stat = wait_for_completion_timeout(&i2c->cmp, HZ / 10);
+		if (!stat)
+			return -EAGAIN;
+
+		/* Check for error condition on the bus */
+		if (i2c->stat & HDMI_IH_I2CM_STAT0_ERROR)
+			return -EIO;
+
+		*buf++ = hdmi_readb(hdmi, HDMI_I2CM_DATAI);
+	}
+
+	return 0;
+}
+
+static int dw_hdmi_i2c_write(struct dw_hdmi *hdmi,
+			     unsigned char *buf, unsigned int length)
+{
+	struct dw_hdmi_i2c *i2c = hdmi->i2c;
+	int stat;
+
+	if (!i2c->is_regaddr) {
+		/* Use the first write byte as register address */
+		i2c->slave_reg = buf[0];
+		length--;
+		buf++;
+		i2c->is_regaddr = true;
+	}
+
+	while (length--) {
+		reinit_completion(&i2c->cmp);
+
+		hdmi_writeb(hdmi, *buf++, HDMI_I2CM_DATAO);
+		hdmi_writeb(hdmi, i2c->slave_reg++, HDMI_I2CM_ADDRESS);
+		hdmi_writeb(hdmi, HDMI_I2CM_OPERATION_WRITE,
+			    HDMI_I2CM_OPERATION);
+
+		stat = wait_for_completion_timeout(&i2c->cmp, HZ / 10);
+		if (!stat)
+			return -EAGAIN;
+
+		/* Check for error condition on the bus */
+		if (i2c->stat & HDMI_IH_I2CM_STAT0_ERROR)
+			return -EIO;
+	}
+
+	return 0;
+}
+
+static int dw_hdmi_i2c_xfer(struct i2c_adapter *adap,
+			    struct i2c_msg *msgs, int num)
+{
+	struct dw_hdmi *hdmi = i2c_get_adapdata(adap);
+	struct dw_hdmi_i2c *i2c = hdmi->i2c;
+	u8 addr = msgs[0].addr;
+	int i, ret = 0;
+
+	dev_dbg(hdmi->dev, "xfer: num: %d, addr: %#x\n", num, addr);
+
+	for (i = 0; i < num; i++) {
+		if (msgs[i].addr != addr) {
+			dev_warn(hdmi->dev,
+				 "unsupported transfer, changed slave address\n");
+			return -EOPNOTSUPP;
+		}
+
+		if (msgs[i].len == 0) {
+			dev_dbg(hdmi->dev,
+				"unsupported transfer %d/%d, no data\n",
+				i + 1, num);
+			return -EOPNOTSUPP;
+		}
+	}
+
+	mutex_lock(&i2c->lock);
+
+	hdmi_writeb(hdmi, 0x00, HDMI_IH_MUTE_I2CM_STAT0);
+
+	/* Set slave device address taken from the first I2C message */
+	hdmi_writeb(hdmi, addr, HDMI_I2CM_SLAVE);
+
+	/* Set slave device register address on transfer */
+	i2c->is_regaddr = false;
+
+	for (i = 0; i < num; i++) {
+		dev_dbg(hdmi->dev, "xfer: num: %d/%d, len: %d, flags: %#x\n",
+			i + 1, num, msgs[i].len, msgs[i].flags);
+
+		if (msgs[i].flags & I2C_M_RD)
+			ret = dw_hdmi_i2c_read(hdmi, msgs[i].buf, msgs[i].len);
+		else
+			ret = dw_hdmi_i2c_write(hdmi, msgs[i].buf, msgs[i].len);
+
+		if (ret < 0)
+			break;
+	}
+
+	if (!ret)
+		ret = num;
+
+	/* Mute DONE and ERROR interrupts */
+	hdmi_writeb(hdmi, HDMI_IH_I2CM_STAT0_ERROR | HDMI_IH_I2CM_STAT0_DONE,
+		    HDMI_IH_MUTE_I2CM_STAT0);
+
+	mutex_unlock(&i2c->lock);
+
+	return ret;
+}
+
+static u32 dw_hdmi_i2c_func(struct i2c_adapter *adapter)
+{
+	return I2C_FUNC_I2C | I2C_FUNC_SMBUS_EMUL;
+}
+
+static const struct i2c_algorithm dw_hdmi_algorithm = {
+	.master_xfer	= dw_hdmi_i2c_xfer,
+	.functionality	= dw_hdmi_i2c_func,
+};
+
+static struct i2c_adapter *dw_hdmi_i2c_adapter(struct dw_hdmi *hdmi)
+{
+	struct i2c_adapter *adap;
+	struct dw_hdmi_i2c *i2c;
+	int ret;
+
+	i2c = devm_kzalloc(hdmi->dev, sizeof(*i2c), GFP_KERNEL);
+	if (!i2c)
+		return ERR_PTR(-ENOMEM);
+
+	mutex_init(&i2c->lock);
+	init_completion(&i2c->cmp);
+
+	adap = &i2c->adap;
+	adap->class = I2C_CLASS_DDC;
+	adap->owner = THIS_MODULE;
+	adap->dev.parent = hdmi->dev;
+	adap->algo = &dw_hdmi_algorithm;
+	strlcpy(adap->name, "DesignWare HDMI", sizeof(adap->name));
+	i2c_set_adapdata(adap, hdmi);
+
+	ret = i2c_add_adapter(adap);
+	if (ret) {
+		dev_warn(hdmi->dev, "cannot add %s I2C adapter\n", adap->name);
+		devm_kfree(hdmi->dev, i2c);
+		return ERR_PTR(ret);
+	}
+
+	hdmi->i2c = i2c;
+
+	dev_info(hdmi->dev, "registered %s I2C bus driver\n", adap->name);
+
+	return adap;
+}
+
 static void hdmi_set_cts_n(struct dw_hdmi *hdmi, unsigned int cts,
 			   unsigned int n)
 {
@@ -1466,16 +1673,40 @@ static struct drm_bridge_funcs dw_hdmi_bridge_funcs = {
 	.mode_fixup = dw_hdmi_bridge_mode_fixup,
 };
 
+static irqreturn_t dw_hdmi_i2c_irq(struct dw_hdmi *hdmi)
+{
+	struct dw_hdmi_i2c *i2c = hdmi->i2c;
+	unsigned int stat;
+
+	stat = hdmi_readb(hdmi, HDMI_IH_I2CM_STAT0);
+	if (!stat)
+		return IRQ_NONE;
+
+	hdmi_writeb(hdmi, stat, HDMI_IH_I2CM_STAT0);
+
+	i2c->stat = stat;
+
+	complete(&i2c->cmp);
+
+	return IRQ_HANDLED;
+}
+
 static irqreturn_t dw_hdmi_hardirq(int irq, void *dev_id)
 {
 	struct dw_hdmi *hdmi = dev_id;
 	u8 intr_stat;
+	irqreturn_t ret = IRQ_NONE;
+
+	if (hdmi->i2c)
+		ret = dw_hdmi_i2c_irq(hdmi);
 
 	intr_stat = hdmi_readb(hdmi, HDMI_IH_PHY_STAT0);
-	if (intr_stat)
+	if (intr_stat) {
 		hdmi_writeb(hdmi, ~0, HDMI_IH_MUTE_PHY_STAT0);
+		return IRQ_WAKE_THREAD;
+	}
 
-	return intr_stat ? IRQ_WAKE_THREAD : IRQ_NONE;
+	return ret;
 }
 
 static irqreturn_t dw_hdmi_irq(int irq, void *dev_id)
@@ -1654,6 +1885,13 @@ int dw_hdmi_bind(struct device *dev, struct device *master,
 	 */
 	hdmi_init_clk_regenerator(hdmi);
 
+	/* If DDC bus is not specified, try to register HDMI I2C bus */
+	if (!hdmi->ddc) {
+		hdmi->ddc = dw_hdmi_i2c_adapter(hdmi);
+		if (IS_ERR(hdmi->ddc))
+			hdmi->ddc = NULL;
+	}
+
 	/*
 	 * Configure registers related to HDMI interrupt
 	 * generation before registering IRQ.
@@ -1674,11 +1912,18 @@ int dw_hdmi_bind(struct device *dev, struct device *master,
 	/* Unmute interrupts */
 	hdmi_writeb(hdmi, ~HDMI_IH_PHY_STAT0_HPD, HDMI_IH_MUTE_PHY_STAT0);
 
+	/* Unmute I2CM interrupts and reset HDMI DDC I2C master controller */
+	if (hdmi->i2c)
+		dw_hdmi_i2c_init(hdmi);
+
 	dev_set_drvdata(dev, hdmi);
 
 	return 0;
 
 err_iahb:
+	if (hdmi->i2c)
+		i2c_del_adapter(&hdmi->i2c->adap);
+
 	clk_disable_unprepare(hdmi->iahb_clk);
 err_isfr:
 	clk_disable_unprepare(hdmi->isfr_clk);
@@ -1699,13 +1944,18 @@ void dw_hdmi_unbind(struct device *dev, struct device *master, void *data)
 
 	clk_disable_unprepare(hdmi->iahb_clk);
 	clk_disable_unprepare(hdmi->isfr_clk);
-	i2c_put_adapter(hdmi->ddc);
+
+	if (hdmi->i2c)
+		i2c_del_adapter(&hdmi->i2c->adap);
+	else
+		i2c_put_adapter(hdmi->ddc);
 }
 EXPORT_SYMBOL_GPL(dw_hdmi_unbind);
 
 MODULE_AUTHOR("Sascha Hauer <s.hauer at pengutronix.de>");
 MODULE_AUTHOR("Andy Yan <andy.yan at rock-chips.com>");
 MODULE_AUTHOR("Yakir Yang <ykk at rock-chips.com>");
+MODULE_AUTHOR("Vladimir Zapolskiy <vladimir_zapolskiy at mentor.com>");
 MODULE_DESCRIPTION("DW HDMI transmitter driver");
 MODULE_LICENSE("GPL");
 MODULE_ALIAS("platform:dw-hdmi");
diff --git a/drivers/gpu/drm/bridge/dw_hdmi.h b/drivers/gpu/drm/bridge/dw_hdmi.h
index ee7f7ed..9ed85eb 100644
--- a/drivers/gpu/drm/bridge/dw_hdmi.h
+++ b/drivers/gpu/drm/bridge/dw_hdmi.h
@@ -563,6 +563,10 @@ enum {
 	HDMI_IH_PHY_STAT0_TX_PHY_LOCK = 0x2,
 	HDMI_IH_PHY_STAT0_HPD = 0x1,
 
+/* IH_I2CM_STAT0 and IH_MUTE_I2CM_STAT0 field values */
+	HDMI_IH_I2CM_STAT0_DONE = 0x2,
+	HDMI_IH_I2CM_STAT0_ERROR = 0x1,
+
 /* IH_MUTE_I2CMPHY_STAT0 field values */
 	HDMI_IH_MUTE_I2CMPHY_STAT0_I2CMPHYDONE = 0x2,
 	HDMI_IH_MUTE_I2CMPHY_STAT0_I2CMPHYERROR = 0x1,
@@ -1029,6 +1033,21 @@ enum {
 	HDMI_A_VIDPOLCFG_HSYNCPOL_MASK = 0x2,
 	HDMI_A_VIDPOLCFG_HSYNCPOL_ACTIVE_HIGH = 0x2,
 	HDMI_A_VIDPOLCFG_HSYNCPOL_ACTIVE_LOW = 0x0,
+
+/* I2CM_OPERATION field values */
+	HDMI_I2CM_OPERATION_WRITE = 0x10,
+	HDMI_I2CM_OPERATION_READ_EXT = 0x2,
+	HDMI_I2CM_OPERATION_READ = 0x1,
+
+/* I2CM_INT field values */
+	HDMI_I2CM_INT_DONE_POL = 0x8,
+	HDMI_I2CM_INT_DONE_MASK = 0x4,
+
+/* I2CM_CTLINT field values */
+	HDMI_I2CM_CTLINT_NAC_POL = 0x80,
+	HDMI_I2CM_CTLINT_NAC_MASK = 0x40,
+	HDMI_I2CM_CTLINT_ARB_POL = 0x8,
+	HDMI_I2CM_CTLINT_ARB_MASK = 0x4,
 };
 
 #endif /* __DW_HDMI_H__ */
-- 
2.5.0



From linux at rasmusvillemoes.dk  Sun Aug 30 14:47:20 2015
From: linux at rasmusvillemoes.dk (Rasmus Villemoes)
Date: Sun, 30 Aug 2015 23:47:20 +0200
Subject: [PATCH] lib: Make _find_next_bit helper function inline
In-Reply-To: <55E1CC83.1010007@gmail.com> (Yury's message of "Sat, 29 Aug 2015
 18:15:15 +0300")
References: <1438110564-19932-1-git-send-email-cburden@codeaurora.org>
 <55B7F2C6.9010000@gmail.com>
 <20150728144537.67d46b5714c99d25f0bb33fb@linux-foundation.org>
 <1438176656.18723.8.camel@ceres> <55B93A47.90107@codeaurora.org>
 <CALW4P+LU2iLkT7d=BiaC_=oSJ6K_g152VsVSjfcQGUKx_5q4tQ@mail.gmail.com>
 <55E1CC83.1010007@gmail.com>
Message-ID: <87si701maf.fsf@rasmusvillemoes.dk>

I've lost track of what's up and down in this, but now that I look at
this again let me throw in my two observations of stupid gcc behaviour:
For the current code, both debian's gcc (4.7) and 5.1 partially inlines
_find_next_bit, namely the "if (!nbits || start >= nbits)" test. I know it
does it to avoid a function call, but in this case the early return
condition is unlikely, so there's not much to gain. Moreover, it fails
to optimize the test to simply "if (start >= nbits)" - everything being
unsigned, these are obviously equivalent.

Rasmus


From thunder.leizhen at huawei.com  Sun Aug 30 18:46:48 2015
From: thunder.leizhen at huawei.com (Leizhen (ThunderTown))
Date: Mon, 31 Aug 2015 09:46:48 +0800
Subject: [PATCH v5 2/4] Documentation: arm64/arm: dt bindings for numa.
In-Reply-To: <1440844631.2912.248.camel@kernel.crashing.org>
References: <1439570374-4079-1-git-send-email-gkulkarni@caviumnetworks.com>
 <1439570374-4079-3-git-send-email-gkulkarni@caviumnetworks.com>
 <20150828123228.GE31748@leverpostej>
 <CAL_JsqLOpUTVeKbkJ6uPi0EYistd=BowAHdtSmaUYYDhU6c9Sg@mail.gmail.com>
 <55E17F58.5020101@huawei.com> <1440844631.2912.248.camel@kernel.crashing.org>
Message-ID: <55E3B208.3020404@huawei.com>



On 2015/8/29 18:37, Benjamin Herrenschmidt wrote:
> On Sat, 2015-08-29 at 17:46 +0800, Leizhen (ThunderTown) wrote:
>> Why not copy the method of ACPI numa? There only three elements
>> should be configured:
>> 1) a cpu belong to which node
>> 2) a memory block belong to which node
>> 3) the distance of each two nodes

Sorry, I forgot to write something:
4) a device(maybe a bus device) belongs to which node

For example:
device-name {
        ...
        numa-node = <&node0>;
};

To simplify the discussion, I will not mention device again. Treat both
cpus and devices as masters, memorys as slaves.

A bus is not a master, we allow binding numa node to a bus, because we may
want all devices on the bus to inherit its numa node-id without obvious configured one by one.

> 
> This means your are bolting into the DT representation the concept of
> "Node" which isn't necessarily very meaningful.
> 
> Your system is really a hierarchy of objects. You can have cores on a
> chip, already possibly sharing some level of cache or not, you can have
> chips on a module, modules linked at various distances, etc...
> 
> What is "a node" ?
> 
> For example, I have a P8 chip with 2 chips on a module (fast X-bus) and
> 2 modules (slightly slower A-bus). All 4 chips have 2 memory
> controllers each.
> 
> Is a "node" a chip or a module ?

A numa node is a abstract concept, it needn't related to a real hardware level.
A numa node normally contains both cpus and mems, but may only contains cpus or mems,
or maybe nothing(quite rare). We put cpus or mems into a node, because we want to use
node-distance to implement the nearest memory access, the nearest process schedule.

In your example:
On fast X-bus, have a module contains 2 chips.
On slightly slower A-bus, have 2 modules(treat them as 2 chips).
Each chip contains 2 memory controllers.

Suppose each chip access its local bus memory faster than another.

Case1:
Each chip access its 2 local memory controllers faster than others. Then we can define numa nodes:
node-xbus-0: a chip and 2 local memory.
node-xbus-1: a chip and 2 local memory.
node-abus-0: a chip(module) and 2 local memory.
node-abus-1: a chip(module) and 2 local memory.

Case2:
Each chip access any memory controllers on its local bus are the same. Then we can define numa nodes:
node-xbus: 2 chips and 4 local memory.
node-abus: 2 chips(modules) and 4 local memory.


> 
> The Linux concept of node is too restrictive. The associativity
> properties avoid this by allowing you to define as many "levels" of
> associativity as you wish. Also since it's right justified, a given
> component doesn't need to have all levels (a MC can stop at chip while
> cores can go down one more level for example).
> 
> The reference points property gives a hint as "interesting" levels can
> typically be used as a hint for chosing what Linux will use as a "node"
> at least until Linux gets smarter. It can also be used to calculate
> distances.
> 
> Cheers,
> Ben.
> 
> 
> .
> 



From jonmason at broadcom.com  Sun Aug 30 19:24:17 2015
From: jonmason at broadcom.com (Jon Mason)
Date: Sun, 30 Aug 2015 22:24:17 -0400
Subject: [PATCH v3 2/5] ARM: NSP: add minimal Northstar Plus device tree
In-Reply-To: <55E0FAC4.2040108@broadcom.com>
References: <1440805644-18241-1-git-send-email-jonmason@broadcom.com>
 <55E0FAC4.2040108@broadcom.com>
Message-ID: <20150831022417.GA27066@broadcom.com>

On Fri, Aug 28, 2015 at 05:20:20PM -0700, Ray Jui wrote:
> 
> 
> On 8/28/2015 4:47 PM, Jon Mason wrote:
> > Add a very minimalistic set of Northstar Plus Device Tree files which
> > describes the SoC and the BCM958625 implementation.  The perpherials
> > described are:
> > 
> > ARM Cortex A9 CPU
> > 2 8250 UARTs
> > ARM GIC
> > PL310 L2 Cache
> > ARM A9 Global timer
> > 
> > Signed-off-by: Kapil Hali <kapilh at broadcom.com>
> > Signed-off-by: Jon Mason <jonmason at broadcom.com>
> > ---
> >  arch/arm/boot/dts/Makefile       |   2 +
> >  arch/arm/boot/dts/bcm-nsp.dtsi   | 120 +++++++++++++++++++++++++++++++++++++++
> >  arch/arm/boot/dts/bcm958625k.dts |  57 +++++++++++++++++++
> >  3 files changed, 179 insertions(+)
> >  create mode 100644 arch/arm/boot/dts/bcm-nsp.dtsi
> >  create mode 100644 arch/arm/boot/dts/bcm958625k.dts
> > 
> > diff --git a/arch/arm/boot/dts/Makefile b/arch/arm/boot/dts/Makefile
> > index 246473a..adb5732 100644
> > --- a/arch/arm/boot/dts/Makefile
> > +++ b/arch/arm/boot/dts/Makefile
> > @@ -82,6 +82,8 @@ dtb-$(CONFIG_ARCH_BCM_CYGNUS) += \
> >  dtb-$(CONFIG_ARCH_BCM_MOBILE) += \
> >  	bcm28155-ap.dtb \
> >  	bcm21664-garnet.dtb
> > +dtb-$(CONFIG_ARCH_BCM_NSP) += \
> > +	bcm958625k.dtb
> >  dtb-$(CONFIG_ARCH_BERLIN) += \
> >  	berlin2-sony-nsz-gs7.dtb \
> >  	berlin2cd-google-chromecast.dtb \
> > diff --git a/arch/arm/boot/dts/bcm-nsp.dtsi b/arch/arm/boot/dts/bcm-nsp.dtsi
> > new file mode 100644
> > index 0000000..f5f494f
> > --- /dev/null
> > +++ b/arch/arm/boot/dts/bcm-nsp.dtsi
> > @@ -0,0 +1,120 @@
> > +/*
> > + *  BSD LICENSE
> > + *
> > + *  Copyright(c) 2015 Broadcom Corporation.  All rights reserved.
> > + *
> > + *  Redistribution and use in source and binary forms, with or without
> > + *  modification, are permitted provided that the following conditions
> > + *  are met:
> > + *
> > + *    * Redistributions of source code must retain the above copyright
> > + *      notice, this list of conditions and the following disclaimer.
> > + *    * Redistributions in binary form must reproduce the above copyright
> > + *      notice, this list of conditions and the following disclaimer in
> > + *      the documentation and/or other materials provided with the
> > + *      distribution.
> > + *    * Neither the name of Broadcom Corporation nor the names of its
> > + *      contributors may be used to endorse or promote products derived
> > + *      from this software without specific prior written permission.
> > + *
> > + *  THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
> > + *  "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
> > + *  LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
> > + *  A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
> > + *  OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
> > + *  SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
> > + *  LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
> > + *  DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
> > + *  THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
> > + *  (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
> > + *  OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
> > + */
> > +
> > +#include <dt-bindings/interrupt-controller/arm-gic.h>
> > +#include <dt-bindings/interrupt-controller/irq.h>
> > +
> > +#include "skeleton.dtsi"
> > +
> > +/ {
> > +	compatible = "brcm,nsp";
> > +	model = "Broadcom Northstar Plus SoC";
> > +	interrupt-parent = <&gic>;
> > +
> > +	mpcore {
> > +		compatible = "simple-bus";
> > +		ranges = <0x00000000 0x19020000 0x00003000>;
> > +		#address-cells = <1>;
> > +		#size-cells = <1>;
> > +
> > +		cpus {
> > +			#address-cells = <1>;
> > +			#size-cells = <0>;
> > +
> > +			cpu at 0 {
> > +				device_type = "cpu";
> > +				compatible = "arm,cortex-a9";
> > +				next-level-cache = <&L2>;
> > +				reg = <0x0>;
> > +			};
> > +		};
> > +
> > +		L2: l2-cache {
> > +			compatible = "arm,pl310-cache";
> > +			reg = <0x2000 0x1000>;
> > +			cache-unified;
> > +			cache-level = <2>;
> > +		};
> > +
> > +		gic: interrupt-controller at 19021000 {
> > +			compatible = "arm,cortex-a9-gic";
> > +			#interrupt-cells = <3>;
> > +			#address-cells = <0>;
> > +			interrupt-controller;
> > +			reg = <0x1000 0x1000>,
> > +			      <0x0100 0x100>;
> > +		};
> > +
> > +		timer at 19020200 {
> > +			compatible = "arm,cortex-a9-global-timer";
> > +			reg = <0x0200 0x100>;
> > +			interrupts = <GIC_PPI 11 IRQ_TYPE_LEVEL_HIGH>;
> > +			clocks = <&periph_clk>;
> > +		};
> > +	};
> > +
> > +	clocks {
> > +		#address-cells = <1>;
> > +		#size-cells = <1>;
> > +		ranges;
> > +
> > +		periph_clk: periph_clk {
> > +			compatible = "fixed-clock";
> > +			#clock-cells = <0>;
> > +			clock-frequency = <500000000>;
> > +		};
> > +	};
> > +
> > +	apb {
> > +		compatible = "arm,amba-bus", "simple-bus";
> 
> Should "arm,amba-bus" has a separate bus node with AMBA compatible
> devices declared in there (e.g, pl330, spi-pl022, and etc.) in the
> future after they are brought up? To my best knowledge, "ns16550a" UART
> is NOT an AMBA compatible device.

APB is an AMBA bus, so this part is accurate.  The block diagram of
the SoC has the UARTs (and other perpherials) hanging off of the APB
bus.  So, this organization follows the block diagram.  While the
UART drivers are not AMBA aware, there appears to be no issues with
this layout (as the HW/drivers come up without issue).  Unless there
is an unforeseen issue with having non-AMBA aware devices on the DT
AMBA bus, I would think it best to organize it to match the block
disgram.

> > +		interrupt-parent = <&gic>;
> > +		ranges = <0x00000000 0x18000000 0x00001000>;
> 
> Does the 'apb' bus mean to cover all peripherals connected through APB?
> If so, the size is only 0x1000 and that seems to be too small...

This is all that is currently needed.  I was planning on expanding it
as I added more devices.

Thanks,
Jon

> > +		#address-cells = <1>;
> > +		#size-cells = <1>;
> > +
> > +		uart0: serial at 18000300 {
> > +			compatible = "ns16550a";
> > +			reg = <0x0300 0x100>;
> > +			interrupts = <GIC_SPI 85 IRQ_TYPE_LEVEL_HIGH>;
> > +			clock-frequency = <62499840>;
> > +			status = "disabled";
> > +		};
> > +
> > +		uart1: serial at 18000400 {
> > +			compatible = "ns16550a";
> > +			reg = <0x0400 0x100>;
> > +			interrupts = <GIC_SPI 85 IRQ_TYPE_LEVEL_HIGH>;
> > +			clock-frequency = <62499840>;
> > +			status = "disabled";
> > +		};
> > +	};
> > +};
> > diff --git a/arch/arm/boot/dts/bcm958625k.dts b/arch/arm/boot/dts/bcm958625k.dts
> > new file mode 100644
> > index 0000000..16303db
> > --- /dev/null
> > +++ b/arch/arm/boot/dts/bcm958625k.dts
> > @@ -0,0 +1,57 @@
> > +/*
> > + *  BSD LICENSE
> > + *
> > + *  Copyright(c) 2015 Broadcom Corporation.  All rights reserved.
> > + *
> > + *  Redistribution and use in source and binary forms, with or without
> > + *  modification, are permitted provided that the following conditions
> > + *  are met:
> > + *
> > + *    * Redistributions of source code must retain the above copyright
> > + *      notice, this list of conditions and the following disclaimer.
> > + *    * Redistributions in binary form must reproduce the above copyright
> > + *      notice, this list of conditions and the following disclaimer in
> > + *      the documentation and/or other materials provided with the
> > + *      distribution.
> > + *    * Neither the name of Broadcom Corporation nor the names of its
> > + *      contributors may be used to endorse or promote products derived
> > + *      from this software without specific prior written permission.
> > + *
> > + *  THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
> > + *  "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
> > + *  LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
> > + *  A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
> > + *  OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
> > + *  SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
> > + *  LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
> > + *  DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
> > + *  THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
> > + *  (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
> > + *  OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
> > + */
> > +
> > +/dts-v1/;
> > +
> > +#include "bcm-nsp.dtsi"
> > +
> > +/ {
> > +	model = "NorthStar Plus SVK (BCM958625K)";
> > +	compatible = "brcm,bcm58625", "brcm,nsp";
> > +
> > +	aliases {
> > +		serial0 = &uart0;
> > +		serial1 = &uart1;
> > +	};
> > +
> > +	chosen {
> > +		stdout-path = "serial0:115200n8";
> > +	};
> > +};
> > +
> > +&uart0 {
> > +	status = "okay";
> > +};
> > +
> > +&uart1 {
> > +	status = "okay";
> > +};
> > 


From ykk at rock-chips.com  Sun Aug 30 19:40:38 2015
From: ykk at rock-chips.com (Yakir Yang)
Date: Mon, 31 Aug 2015 10:40:38 +0800
Subject: [PATCH v3 0/14] Add Analogix Core Display Port Driver
In-Reply-To: <CABgxDoKcsRye43pqzZC=4A=D1+iDj5Bmy9XZjx+K8ekca0=FwQ@mail.gmail.com>
References: <1439995728-18046-1-git-send-email-ykk@rock-chips.com>	<105A0032-83A0-4B75-AE94-258F12451670@gmail.com>	<55D6F6F8.70504@rock-chips.com>	<8384E112-E1F4-4CD3-85BF-A2A25989783F@gmail.com>	<20150821131631.GC22118@ulmo.nvidia.com>
 <CABgxDoKcsRye43pqzZC=4A=D1+iDj5Bmy9XZjx+K8ekca0=FwQ@mail.gmail.com>
Message-ID: <55E3BEA6.50407@rock-chips.com>

Hi Romain,

? 08/30/2015 08:16 PM, Romain Perier ??:
> Hi,
>
> Could you rebase your serie onto linux-next or 4.2-rc8 ? it does not
> apply here...

Thanks for try to applied, and feel sorry for that failed.

This v3 series was rebased on github.com/torvalds/linux.git, so I should
rebase on kernel/next/linux-next.git when I'm preparing v4 series.

Thanks,
- Yakir

> Regards,
> Romain
>
> 2015-08-21 15:16 GMT+02:00 Thierry Reding <treding at nvidia.com>:
>> On Fri, Aug 21, 2015 at 08:24:16PM +0900, Jingoo Han wrote:
>>> On 2015. 8. 21., at PM 7:01, Yakir Yang <ykk at rock-chips.com> wrote:
>>>> Hi Jingoo,
>>>>
>>>>> ? 2015/8/21 16:20, Jingoo Han ??:
>>>>>> On 2015. 8. 19., at PM 11:48, Yakir Yang <ykk at rock-chips.com> wrote:
>>>>> .....
>>>>>
>>>>>> .../bindings/video/analogix_dp-rockchip.txt        |   83 ++
>>>>>> .../devicetree/bindings/video/exynos_dp.txt        |   51 +-
>>>>>> arch/arm/boot/dts/exynos5250-arndale.dts           |   10 +-
>>>>>> arch/arm/boot/dts/exynos5250-smdk5250.dts          |   10 +-
>>>>>> arch/arm/boot/dts/exynos5250-snow.dts              |   12 +-
>>>>>> arch/arm/boot/dts/exynos5250-spring.dts            |   12 +-
>>>>>> arch/arm/boot/dts/exynos5420-peach-pit.dts         |   12 +-
>>>>>> arch/arm/boot/dts/exynos5420-smdk5420.dts          |   10 +-
>>>>>> arch/arm/boot/dts/exynos5800-peach-pi.dts          |   12 +-
>>>>>> drivers/gpu/drm/bridge/Kconfig                     |    5 +
>>>>>> drivers/gpu/drm/bridge/Makefile                    |    1 +
>>>>>> drivers/gpu/drm/bridge/analogix_dp_core.c          | 1382 +++++++++++++++++++
>>>>>> drivers/gpu/drm/bridge/analogix_dp_core.h          |  286 ++++
>>>>>> drivers/gpu/drm/bridge/analogix_dp_reg.c           | 1294 ++++++++++++++++++
>>>>>> .../exynos_dp_reg.h => bridge/analogix_dp_reg.h}   |  270 ++--
>>>>>> drivers/gpu/drm/exynos/Kconfig                     |    5 +-
>>>>>> drivers/gpu/drm/exynos/Makefile                    |    2 +-
>>>>>> drivers/gpu/drm/exynos/analogix_dp-exynos.c        |  347 +++++
>>>>> Would you change this file name to "exynos_dp.c"?
>>>> Sorry, I don't think so  ;(
>>>>
>>>> I think IP_name+Soc_name would be better in this re-use case.
>>> So? Is there the naming rule such as "IP_name+SoC_name"?
>>>
>>>> Beside I see
>>>> there are lots of driver named with this format in kernel, such as dw_hdmi & dw_mmc
>>> Please look at other dw cases.
>>> For example, look at dw_pcie.
>>>
>>> drivers/pci/host/
>>> pcie-designware.c
>>> pci-spear13xx.c
>>> pci-exynos.c
>>>
>>> In this case, pci-spear13xx.c and pci-exynos.c do not use "IP_name+SoC_name", even though these are dw IPs.
>>>
>>> Also, naming consistency is more important.
>>> Now, Exynos DRM files are using "exynos_drm_" prefix.
>>>
>>> drivers/gpu/drm/exynos/
>>> exynos_drm_buf.c
>>> exynos_drm_core.c
>>> ....
>>>
>>> However, "analogix_dp-exynos.c" looks very inconsistent.
>>>
>>> If there is no strict naming rule, please use "exynos_dp.c"
>>> or "exynos_drm_dp.c".
>> Exynos DRM maintainers get to pick their filenames, so Yakir, please
>> rename as Jingoo suggested.
>>
>> Even if you didn't the first thing that would go into the Exynos DRM
>> driver tree after this is merged is a rename patch anyway.
>>
>> Thierry
>
>




From thunder.leizhen at huawei.com  Sun Aug 30 19:53:04 2015
From: thunder.leizhen at huawei.com (Leizhen (ThunderTown))
Date: Mon, 31 Aug 2015 10:53:04 +0800
Subject: [PATCH v5 2/4] Documentation: arm64/arm: dt bindings for numa.
In-Reply-To: <CAFpQJXWO0xT0kxWf09L_XcAOXm1Lov8i2U2BQzk-x0TStj7vBg@mail.gmail.com>
References: <1439570374-4079-1-git-send-email-gkulkarni@caviumnetworks.com>
 <1439570374-4079-3-git-send-email-gkulkarni@caviumnetworks.com>
 <20150828123228.GE31748@leverpostej>
 <CAL_JsqLOpUTVeKbkJ6uPi0EYistd=BowAHdtSmaUYYDhU6c9Sg@mail.gmail.com>
 <55E17F58.5020101@huawei.com>
 <CAFpQJXWO0xT0kxWf09L_XcAOXm1Lov8i2U2BQzk-x0TStj7vBg@mail.gmail.com>
Message-ID: <55E3C190.30407@huawei.com>



On 2015/8/29 22:56, Ganapatrao Kulkarni wrote:
> Hi Thunder,
> 
> On Sat, Aug 29, 2015 at 3:16 PM, Leizhen (ThunderTown)
> <thunder.leizhen at huawei.com> wrote:
>>
>>
>> On 2015/8/28 22:02, Rob Herring wrote:
>>> +benh
>>>
>>> On Fri, Aug 28, 2015 at 7:32 AM, Mark Rutland <mark.rutland at arm.com> wrote:
>>>> Hi,
>>>>
>>>> On Fri, Aug 14, 2015 at 05:39:32PM +0100, Ganapatrao Kulkarni wrote:
>>>>> DT bindings for numa map for memory, cores and IOs using
>>>>> arm,associativity device node property.
>>>>
>>>> Given this is just a copy of ibm,associativity, I'm not sure I see much
>>>> point in renaming the properties.
>>>
>>> So just keep the ibm? I'm okay with that. That would help move to
>>> common code. Alternatively, we could drop the vendor prefix and have
>>> common code just check for both.
>>>
>>
>> Hi all,
>>
>> Why not copy the method of ACPI numa? There only three elements should be configured:
>> 1) a cpu belong to which node
>> 2) a memory block belong to which node
>> 3) the distance of each two nodes
>>
>> The devicetree nodes of numa can be like below:
>> / {
>>         ...
>>
>>         numa-nodes-info {
>>                 node-name: node-description {
>>                         mem-ranges = <...>;
>>                         cpus-list = <...>;
>>                 };
>>
>>                 nodes-distance {
>>                         distance-list = <...>;
>>                 };
>>         };
>>
>>         ...
>> };
>>
> some what similar to what your are proposing is already implemented in
> my v2 patchset.
> https://lwn.net/Articles/623920/
> http://lists.infradead.org/pipermail/linux-arm-kernel/2014-November/305164.html

Sorry, I have not read your old version patchsets before.

The basic ideas are consistent, but details are different. I think your v2 patchset may meet some problem:

-------------------------
+- cpu-map:	This property defines the association of range of processors
+		(range of cpu ids) and the proximity domain to which
+		the processor belongs.

+		cpu-map = <0 7 0>,
+			  <8 15 1>;
-------------------------

1.
I am not sure the cpu ids is logical cpu-ids in Linux or the sequence number of the CPU dt-nodes in dts.
The former case: logical cpu-id is allocated by Linux, we can not ensure that cpu0 is the first CPU dt-node.
The latter case: depend on Linux strictly parse CPU dt-nodes follow the sequence in dts.

2. You should put most codes into /drivers/of/, because it can be shared with other ARCHs which base upon devicetree.

Here is my detailed example:
Examples:
/ {
	#address-cells = <2>;
	#size-cells = <2>;

	memory at 0 {
		device_type = "memory";
		reg = <0x0 0x00000000 0x0 0x40000000>,
		      <0x1 0x00000000 0x1 0x00000000>,
		      <0x2 0x00000000 0x0 0x40000000>,
		      <0x2 0x80000000 0x0 0x40000000>;
	};

	CPU0: cpu at 10000 {
		device_type = "cpu";
		reg = <0x10000>;
		...
	};

	numa-nodes-info {
		node0: cluster0 {
			mem-ranges = <0x0 0x00000000 0x1 0x00000000>;
			cpus-list = <&CPU0 &CPU1>;
		};

		node1: cluster1 {
			mem-ranges = <0x1 0x00000000 0x1 0x00000000>;
			cpus-list = <&CPU2>;
		};

		node2: cluster2 {
			mem-ranges = <0x2 0x00000000 0x1 0x00000000>;
			cpus-list = <&CPU3 &CPU4 &CPU5>;
		};

		nodes-distance {
			distance-list = <&node0 &node1 15>, <&node1 &node2 18>;
		};
	};

> we have went to associativity property based implementation to keep it
> more generic.
> i do have both acpi(using linaro/hanjun's patches) and associativity
> based implementations on our internal tree
> and tested on thunderx platform.
> i do see issue in creating numa mapping using ACPI for IOs(for
> example, i am not able to create numa mapping for ITS which is on each
> node, using ACPI tables),  since ACPI spec (tables SRAT and SLIT)
> talks only about processor and memory.
> however associativity is generic and you can apply on any dt node.
>> Sorry, I don't think xxx,associativity is a good method, it's hard to config, and it
>> seems hardware-dependent. Especially, when we want to support memory hot-add, it's too hard.
>> Because xxx,associativity have no obvious information about it. Like powerpc, it use another
>> property: "/ibm,dynamic-reconfiguration-memory".
>>
>> I spend almost a whole month to implement of_numa(configured by dt-nodes), base upon my opinion
>> mentioned above. If somebody are interested in it, I can send my patchset to show it.
>>
>> Regards,
>> Thunder.
>>
> thanks
> ganapat
> 
> .
> 



From punnaia at xilinx.com  Sun Aug 30 20:37:00 2015
From: punnaia at xilinx.com (punnaiah choudary kalluri)
Date: Mon, 31 Aug 2015 09:07:00 +0530
Subject: [PATCH v4 1/2] Documentation: dt: Add Xilinx zynqmp dma device
 tree binding documentation
In-Reply-To: <CAGnW=BbS0V-avm+oV-V5J0995YUXwP9v0uZFwc4i9587u1SDTg@mail.gmail.com>
References: <1438831173-8761-1-git-send-email-punnaia@xilinx.com>
 <CAL_Jsq+261JzSorbgEyQ4BFCHbsFsBaJQnpWJX-G=SX3yhqZJw@mail.gmail.com>
 <CAGnW=BbS0V-avm+oV-V5J0995YUXwP9v0uZFwc4i9587u1SDTg@mail.gmail.com>
Message-ID: <CAGnW=Ba4PjsEXaxeSPNRgLCNBX02BwnxAfxrRQEwighpC9NOjg@mail.gmail.com>

On Tue, Aug 25, 2015 at 12:16 PM, punnaiah choudary kalluri
<punnaia at xilinx.com> wrote:
> Hi Rob,
>
> On Tue, Aug 25, 2015 at 12:23 AM, Rob Herring <robherring2 at gmail.com> wrote:
>> On Wed, Aug 5, 2015 at 10:19 PM, Punnaiah Choudary Kalluri
>> <punnaiah.choudary.kalluri at xilinx.com> wrote:
>>> Device-tree binding documentation for Xilinx zynqmp dma engine used in
>>> Zynq UltraScale+ MPSoC.
>>>
>>> Signed-off-by: Punnaiah Choudary Kalluri <punnaia at xilinx.com>
>>> ---
>>> Changes in v4:
>>> - None
>>> Changes in v3:
>>> - None
>>> Changes in v2:
>>> - None
>>> ---
>>>  .../devicetree/bindings/dma/xilinx/zynqmp_dma.txt  |   61 ++++++++++++++++++++
>>>  1 files changed, 61 insertions(+), 0 deletions(-)
>>>  create mode 100644 Documentation/devicetree/bindings/dma/xilinx/zynqmp_dma.txt
>>>
>>> diff --git a/Documentation/devicetree/bindings/dma/xilinx/zynqmp_dma.txt b/Documentation/devicetree/bindings/dma/xilinx/zynqmp_dma.txt
>>> new file mode 100644
>>> index 0000000..e4f92b9
>>> --- /dev/null
>>> +++ b/Documentation/devicetree/bindings/dma/xilinx/zynqmp_dma.txt
>>> @@ -0,0 +1,61 @@
>>> +Xilinx ZynqMP DMA engine, it does support memory to memory transfers,
>>> +memory to device and device to memory transfers. It also has flow
>>> +control and rate control support for slave/peripheral dma access.
>>> +
>>> +Required properties:
>>> +- compatible: Should be "xlnx,zynqmp-dma-1.0"
>>> +- #dma-cells: Should be <1>, a single cell holding a line request number
>>> +- reg: Memory map for module access
>>> +- interrupt-parent: Interrupt controller the interrupt is routed through
>>> +- interrupts: Should contain DMA channel interrupt
>>> +- xlnx,bus-width: AXI buswidth in bits. Should contain 128 or 64
>>> +
>>> +Optional properties:
>>> +- xlnx,include-sg: Indicates the controller to operate in simple or scatter
>>> +                  gather dma mode
>>> +- xlnx,ratectrl: Scheduling interval in terms of clock cycles for
>>> +                source AXI transaction
>>> +- xlnx,overfetch: Tells whether the channel is allowed to over fetch the data
>>> +- xlnx,src-issue: Number of AXI outstanding transactions on source side
>>> +- xlnx,desc-axi-cohrnt: Tells whether the AXI transactions generated for the
>>> +                       descriptor read are marked Non-coherent
>>> +- xlnx,src-axi-cohrnt: Tells whether the AXI transactions generated for the
>>> +                       source descriptor payload are marked Non-coherent
>>> +- xlnx,dst-axi-cohrnt: Tells whether the AXI transactions generated for the
>>> +                       dst descriptor payload are marked Non-coherent
>>
>> Do you really need 3? dma-coherent property doesn't work for you?
>>
>> Not that it should dictate the binding, but the kernel doesn't support
>> a device needing both coherent and non-coherent DMA ops.
>
> I will get back to you shortly on this

Yes. dma-coherent property works. I will modify the bindings.

Thanks,
Punnaiah
>
>>
>>> +- xlnx,desc-axi-qos: AXI QOS bits to be used for descriptor fetch
>>> +- xlnx,src-axi-qos: AXI QOS bits to be used for data read
>>> +- xlnx,dst-axi-qos: AXI QOS bits to be used for data write
>>> +- xlnx,desc-axi-cache: AXI cache bits to be used for descriptor fetch.
>>> +- xlnx,desc-axi-cache: AXI cache bits to be used for data read
>>> +- xlnx,desc-axi-cache: AXI cache bits to be used for data write
>>
>> These signals are generally part of the coherent or not setting. This
>> allows for potentially invalid combinations.
>>
>> Plus you have a copy/paste error.
>
> I will fix this.
>
> Thanks,
> Punnaiah
>>
>>> +- xlnx,src-burst-len: AXI length for data read. Support only power of 2 values
>>> +                     i.e 1,2,4,8 and 16
>>> +- xlnx,dst-burst-len: AXI length for data write. Support only power of 2 values
>>> +                     i.e 1,2,4,8 and 16
>>> +
>>> +Example:
>>> +++++++++
>>> +fpd_dma_chan1: dma at FD500000 {
>>> +       compatible = "xlnx,zynqmp-dma-1.0";
>>> +       reg = <0x0 0xFD500000 0x1000>;
>>> +       #dma_cells = <1>;
>>> +       interrupt-parent = <&gic>;
>>> +       interrupts = <0 117 4>;
>>> +       xlnx,bus-width = <128>;
>>> +       xlnx,include-sg;
>>> +       xlnx,overfetch;
>>> +       xlnx,ratectrl = <0>;
>>> +       xlnx,src-issue = <16>;
>>> +       xlnx,desc-axi-cohrnt;
>>> +       xlnx,src-axi-cohrnt;
>>> +       xlnx,dst-axi-cohrnt;
>>> +       xlnx,desc-axi-qos = <0>;
>>> +       xlnx,desc-axi-cache = <0>;
>>> +       xlnx,src-axi-qos = <0>;
>>> +       xlnx,src-axi-cache = <2>;
>>> +       xlnx,dst-axi-qos = <0>;
>>> +       xlnx,dst-axi-cache = <2>;
>>> +       xlnx,src-burst-len = <4>;
>>> +       xlnx,dst-burst-len = <4>;
>>> +};
>>> --
>>> 1.7.4
>>>
>>>
>>> _______________________________________________
>>> linux-arm-kernel mailing list
>>> linux-arm-kernel at lists.infradead.org
>>> http://lists.infradead.org/mailman/listinfo/linux-arm-kernel


From jianwei.wang.chn at gmail.com  Sun Aug 30 20:39:57 2015
From: jianwei.wang.chn at gmail.com (Jianwei Wang)
Date: Mon, 31 Aug 2015 11:39:57 +0800
Subject: [PATCH] drm/fsl-dcu: Fix no fb check bug
Message-ID: <1440992397-40533-1-git-send-email-jianwei.wang.chn@gmail.com>

For state->fb may be NULL in fsl_dcu_drm_plane_atomic_check function,
if so, return -EINVAL. No need check in fsl_dcu_drm_plane_atomic_update
anymore.

Signed-off-by: Jianwei Wang <jianwei.wang.chn at gmail.com>
---
 drivers/gpu/drm/fsl-dcu/fsl_dcu_drm_plane.c | 6 +++---
 1 file changed, 3 insertions(+), 3 deletions(-)

diff --git a/drivers/gpu/drm/fsl-dcu/fsl_dcu_drm_plane.c b/drivers/gpu/drm/fsl-dcu/fsl_dcu_drm_plane.c
index 82be6b8..8787920 100644
--- a/drivers/gpu/drm/fsl-dcu/fsl_dcu_drm_plane.c
+++ b/drivers/gpu/drm/fsl-dcu/fsl_dcu_drm_plane.c
@@ -41,6 +41,9 @@ static int fsl_dcu_drm_plane_atomic_check(struct drm_plane *plane,
 {
 	struct drm_framebuffer *fb = state->fb;
 
+	if (!fb)
+		return -EINVAL;
+
 	switch (fb->pixel_format) {
 	case DRM_FORMAT_RGB565:
 	case DRM_FORMAT_RGB888:
@@ -84,9 +87,6 @@ static void fsl_dcu_drm_plane_atomic_update(struct drm_plane *plane,
 	unsigned int alpha, bpp;
 	int index, ret;
 
-	if (!fb)
-		return;
-
 	index = fsl_dcu_drm_plane_index(plane);
 	if (index < 0)
 		return;
-- 
2.1.0.27.g96db324



From k.kozlowski at samsung.com  Sun Aug 30 20:56:05 2015
From: k.kozlowski at samsung.com (Krzysztof Kozlowski)
Date: Mon, 31 Aug 2015 12:56:05 +0900
Subject: [PATCH] ARM: dts: Add exynos5422-odroidxu4 board
Message-ID: <1440993365-26896-1-git-send-email-k.kozlowski@samsung.com>

Add Hardkernel Odroid XU4 board Device Tree sources. The board differs
from Odroid XU3 and XU3-Lite by:
1. No green and red leds (except standard red power led).
2. No audio codec.
3. Two USB3 ports in host mode (no micro USB3 connector for OTG).
4. Realtek RTL8153-CG gigabit network adapter (instead of SMSC9514).
5. Additional connector with IO ports (I2S_0, I2C_5).
6. No DisplayPort.
7. No TI INA231 power measurement sensors.

Signed-off-by: Krzysztof Kozlowski <k.kozlowski at samsung.com>
---
 arch/arm/boot/dts/Makefile                         |  1 +
 arch/arm/boot/dts/exynos5422-odroidxu3-audio.dtsi  | 56 ++++++++++++++
 arch/arm/boot/dts/exynos5422-odroidxu3-common.dtsi | 90 +---------------------
 arch/arm/boot/dts/exynos5422-odroidxu3-lite.dts    | 52 +++++++++++++
 arch/arm/boot/dts/exynos5422-odroidxu3.dts         | 52 +++++++++++++
 arch/arm/boot/dts/exynos5422-odroidxu4.dts         | 48 ++++++++++++
 6 files changed, 210 insertions(+), 89 deletions(-)
 create mode 100644 arch/arm/boot/dts/exynos5422-odroidxu3-audio.dtsi
 create mode 100644 arch/arm/boot/dts/exynos5422-odroidxu4.dts

diff --git a/arch/arm/boot/dts/Makefile b/arch/arm/boot/dts/Makefile
index 233159d2eaab..3d27fe34647f 100644
--- a/arch/arm/boot/dts/Makefile
+++ b/arch/arm/boot/dts/Makefile
@@ -123,6 +123,7 @@ dtb-$(CONFIG_ARCH_EXYNOS5) += \
 	exynos5420-smdk5420.dtb \
 	exynos5422-odroidxu3.dtb \
 	exynos5422-odroidxu3-lite.dtb \
+	exynos5422-odroidxu4.dtb \
 	exynos5440-sd5v1.dtb \
 	exynos5440-ssdk5440.dtb \
 	exynos5800-peach-pi.dtb
diff --git a/arch/arm/boot/dts/exynos5422-odroidxu3-audio.dtsi b/arch/arm/boot/dts/exynos5422-odroidxu3-audio.dtsi
new file mode 100644
index 000000000000..eee16a820484
--- /dev/null
+++ b/arch/arm/boot/dts/exynos5422-odroidxu3-audio.dtsi
@@ -0,0 +1,56 @@
+/*
+ * Hardkernel Odroid XU3 Audio Codec device tree source
+ *
+ * Copyright (c) 2015 Krzysztof Kozlowski
+ * Copyright (c) 2014 Collabora Ltd.
+ * Copyright (c) 2013 Samsung Electronics Co., Ltd.
+ *		http://www.samsung.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.
+*/
+
+/ {
+	sound: sound {
+		compatible = "simple-audio-card";
+
+		simple-audio-card,name = "Odroid-XU3";
+		simple-audio-card,widgets =
+			"Headphone", "Headphone Jack",
+			"Speakers", "Speakers";
+		simple-audio-card,routing =
+			"Headphone Jack", "HPL",
+			"Headphone Jack", "HPR",
+			"Headphone Jack", "MICBIAS",
+			"IN1", "Headphone Jack",
+			"Speakers", "SPKL",
+			"Speakers", "SPKR";
+
+		simple-audio-card,format = "i2s";
+		simple-audio-card,bitclock-master = <&link0_codec>;
+		simple-audio-card,frame-master = <&link0_codec>;
+
+		simple-audio-card,cpu {
+			sound-dai = <&i2s0 0>;
+			system-clock-frequency = <19200000>;
+		};
+
+		link0_codec: simple-audio-card,codec {
+			sound-dai = <&max98090>;
+			clocks = <&i2s0 CLK_I2S_CDCLK>;
+		};
+	};
+};
+
+&hsi2c_5 {
+	max98090: max98090 at 10 {
+		compatible = "maxim,max98090";
+		reg = <0x10>;
+		interrupt-parent = <&gpx3>;
+		interrupts = <2 0>;
+		clocks = <&i2s0 CLK_I2S_CDCLK>;
+		clock-names = "mclk";
+		#sound-dai-cells = <0>;
+	};
+};
diff --git a/arch/arm/boot/dts/exynos5422-odroidxu3-common.dtsi b/arch/arm/boot/dts/exynos5422-odroidxu3-common.dtsi
index dd8bc86d9de4..52c34d8e791f 100644
--- a/arch/arm/boot/dts/exynos5422-odroidxu3-common.dtsi
+++ b/arch/arm/boot/dts/exynos5422-odroidxu3-common.dtsi
@@ -46,70 +46,6 @@
 		reset-gpios = <&gpd1 0 1>;
 	};
 
-	pwmleds {
-		compatible = "pwm-leds";
-
-		greenled {
-			label = "green:mmc0";
-			pwms = <&pwm 1 2000000 0>;
-			pwm-names = "pwm1";
-			/*
-			 * Green LED is much brighter than the others
-			 * so limit its max brightness
-			 */
-			max_brightness = <127>;
-			linux,default-trigger = "mmc0";
-		};
-
-		blueled {
-			label = "blue:heartbeat";
-			pwms = <&pwm 2 2000000 0>;
-			pwm-names = "pwm2";
-			max_brightness = <255>;
-			linux,default-trigger = "heartbeat";
-		};
-	};
-
-	gpioleds {
-		compatible = "gpio-leds";
-		redled {
-			label = "red:microSD";
-			gpios = <&gpx2 3 GPIO_ACTIVE_HIGH>;
-			default-state = "off";
-			linux,default-trigger = "mmc1";
-		};
-	};
-
-	sound: sound {
-		compatible = "simple-audio-card";
-
-		simple-audio-card,name = "Odroid-XU3";
-		simple-audio-card,widgets =
-			"Headphone", "Headphone Jack",
-			"Speakers", "Speakers";
-		simple-audio-card,routing =
-			"Headphone Jack", "HPL",
-			"Headphone Jack", "HPR",
-			"Headphone Jack", "MICBIAS",
-			"IN1", "Headphone Jack",
-			"Speakers", "SPKL",
-			"Speakers", "SPKR";
-
-		simple-audio-card,format = "i2s";
-		simple-audio-card,bitclock-master = <&link0_codec>;
-		simple-audio-card,frame-master = <&link0_codec>;
-
-		simple-audio-card,cpu {
-			sound-dai = <&i2s0 0>;
-			system-clock-frequency = <19200000>;
-		};
-
-		link0_codec: simple-audio-card,codec {
-			sound-dai = <&max98090>;
-			clocks = <&i2s0 CLK_I2S_CDCLK>;
-		};
-	};
-
 	fan0: pwm-fan {
 		compatible = "pwm-fan";
 		pwms = <&pwm 0 20972 0>;
@@ -378,15 +314,6 @@
 
 &hsi2c_5 {
 	status = "okay";
-	max98090: max98090 at 10 {
-		compatible = "maxim,max98090";
-		reg = <0x10>;
-		interrupt-parent = <&gpx3>;
-		interrupts = <2 0>;
-		clocks = <&i2s0 CLK_I2S_CDCLK>;
-		clock-names = "mclk";
-		#sound-dai-cells = <0>;
-	};
 };
 
 &i2c_2 {
@@ -464,19 +391,6 @@
 	};
 };
 
-&pwm {
-	/*
-	 * PWM 0 -- fan
-	 * PWM 1 -- Green LED
-	 * PWM 2 -- Blue LED
-	 * PWM 3 -- on MIPI connector for backlight
-	 */
-	pinctrl-0 = <&pwm0_out &pwm1_out &pwm2_out &pwm3_out>;
-	pinctrl-names = "default";
-	samsung,pwm-outputs = <0>;
-	status = "okay";
-};
-
 &tmu_cpu0 {
 	vtmu-supply = <&ldo7_reg>;
 	status = "okay";
@@ -512,9 +426,7 @@
 	dr_mode = "host";
 };
 
-&usbdrd_dwc3_1 {
-	dr_mode = "otg";
-};
+/* usbdrd_dwc3_1 mode customized in each board */
 
 &usbdrd3_0 {
 	vdd33-supply = <&ldo9_reg>;
diff --git a/arch/arm/boot/dts/exynos5422-odroidxu3-lite.dts b/arch/arm/boot/dts/exynos5422-odroidxu3-lite.dts
index c06882bbb822..379cd61178ee 100644
--- a/arch/arm/boot/dts/exynos5422-odroidxu3-lite.dts
+++ b/arch/arm/boot/dts/exynos5422-odroidxu3-lite.dts
@@ -13,8 +13,60 @@
 
 /dts-v1/;
 #include "exynos5422-odroidxu3-common.dtsi"
+#include "exynos5422-odroidxu3-audio.dtsi"
 
 / {
 	model = "Hardkernel Odroid XU3 Lite";
 	compatible = "hardkernel,odroid-xu3-lite", "samsung,exynos5800", "samsung,exynos5";
+
+	pwmleds {
+		compatible = "pwm-leds";
+
+		greenled {
+			label = "green:mmc0";
+			pwms = <&pwm 1 2000000 0>;
+			pwm-names = "pwm1";
+			/*
+			 * Green LED is much brighter than the others
+			 * so limit its max brightness
+			 */
+			max_brightness = <127>;
+			linux,default-trigger = "mmc0";
+		};
+
+		blueled {
+			label = "blue:heartbeat";
+			pwms = <&pwm 2 2000000 0>;
+			pwm-names = "pwm2";
+			max_brightness = <255>;
+			linux,default-trigger = "heartbeat";
+		};
+	};
+
+	gpioleds {
+		compatible = "gpio-leds";
+		redled {
+			label = "red:microSD";
+			gpios = <&gpx2 3 GPIO_ACTIVE_HIGH>;
+			default-state = "off";
+			linux,default-trigger = "mmc1";
+		};
+	};
+};
+
+&pwm {
+	/*
+	 * PWM 0 -- fan
+	 * PWM 1 -- Green LED
+	 * PWM 2 -- Blue LED
+	 * PWM 3 -- on MIPI connector for backlight
+	 */
+	pinctrl-0 = <&pwm0_out &pwm1_out &pwm2_out &pwm3_out>;
+	pinctrl-names = "default";
+	samsung,pwm-outputs = <0>;
+	status = "okay";
+};
+
+&usbdrd_dwc3_1 {
+	dr_mode = "otg";
 };
diff --git a/arch/arm/boot/dts/exynos5422-odroidxu3.dts b/arch/arm/boot/dts/exynos5422-odroidxu3.dts
index 78e6a502f320..c7509690131d 100644
--- a/arch/arm/boot/dts/exynos5422-odroidxu3.dts
+++ b/arch/arm/boot/dts/exynos5422-odroidxu3.dts
@@ -12,10 +12,45 @@
 
 /dts-v1/;
 #include "exynos5422-odroidxu3-common.dtsi"
+#include "exynos5422-odroidxu3-audio.dtsi"
 
 / {
 	model = "Hardkernel Odroid XU3";
 	compatible = "hardkernel,odroid-xu3", "samsung,exynos5800", "samsung,exynos5";
+
+	pwmleds {
+		compatible = "pwm-leds";
+
+		greenled {
+			label = "green:mmc0";
+			pwms = <&pwm 1 2000000 0>;
+			pwm-names = "pwm1";
+			/*
+			 * Green LED is much brighter than the others
+			 * so limit its max brightness
+			 */
+			max_brightness = <127>;
+			linux,default-trigger = "mmc0";
+		};
+
+		blueled {
+			label = "blue:heartbeat";
+			pwms = <&pwm 2 2000000 0>;
+			pwm-names = "pwm2";
+			max_brightness = <255>;
+			linux,default-trigger = "heartbeat";
+		};
+	};
+
+	gpioleds {
+		compatible = "gpio-leds";
+		redled {
+			label = "red:microSD";
+			gpios = <&gpx2 3 GPIO_ACTIVE_HIGH>;
+			default-state = "off";
+			linux,default-trigger = "mmc1";
+		};
+	};
 };
 
 &i2c_0 {
@@ -49,3 +84,20 @@
 		shunt-resistor = <10000>;
 	};
 };
+
+&pwm {
+	/*
+	 * PWM 0 -- fan
+	 * PWM 1 -- Green LED
+	 * PWM 2 -- Blue LED
+	 * PWM 3 -- on MIPI connector for backlight
+	 */
+	pinctrl-0 = <&pwm0_out &pwm1_out &pwm2_out &pwm3_out>;
+	pinctrl-names = "default";
+	samsung,pwm-outputs = <0>;
+	status = "okay";
+};
+
+&usbdrd_dwc3_1 {
+	dr_mode = "otg";
+};
diff --git a/arch/arm/boot/dts/exynos5422-odroidxu4.dts b/arch/arm/boot/dts/exynos5422-odroidxu4.dts
new file mode 100644
index 000000000000..087c485b6084
--- /dev/null
+++ b/arch/arm/boot/dts/exynos5422-odroidxu4.dts
@@ -0,0 +1,48 @@
+/*
+ * Hardkernel Odroid XU4 board device tree source
+ *
+ * Copyright (c) 2015 Krzysztof Kozlowski
+ * Copyright (c) 2014 Collabora Ltd.
+ * Copyright (c) 2013 Samsung Electronics Co., Ltd.
+ *		http://www.samsung.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.
+*/
+
+/dts-v1/;
+#include "exynos5422-odroidxu3-common.dtsi"
+
+/ {
+	model = "Hardkernel Odroid XU4";
+	compatible = "hardkernel,odroid-xu4", "samsung,exynos5800", \
+		     "samsung,exynos5";
+
+	pwmleds {
+		compatible = "pwm-leds";
+
+		blueled {
+			label = "blue:heartbeat";
+			pwms = <&pwm 2 2000000 0>;
+			pwm-names = "pwm2";
+			max_brightness = <255>;
+			linux,default-trigger = "heartbeat";
+		};
+	};
+};
+
+&pwm {
+	/*
+	 * PWM 0 -- fan
+	 * PWM 2 -- Blue LED
+	 */
+	pinctrl-0 = <&pwm0_out &pwm2_out>;
+	pinctrl-names = "default";
+	samsung,pwm-outputs = <0>;
+	status = "okay";
+};
+
+&usbdrd_dwc3_1 {
+	dr_mode = "host";
+};
-- 
1.9.1



From davem at davemloft.net  Sun Aug 30 21:54:26 2015
From: davem at davemloft.net (David Miller)
Date: Sun, 30 Aug 2015 21:54:26 -0700 (PDT)
Subject: [PATCH net-next v2 0/8] net: thunderx: New features and fixes
In-Reply-To: <1440926958-1874-1-git-send-email-aleksey.makarov@auriga.com>
References: <1440926958-1874-1-git-send-email-aleksey.makarov@auriga.com>
Message-ID: <20150830.215426.1263274449496319755.davem@davemloft.net>

From: Aleksey Makarov <aleksey.makarov at auriga.com>
Date: Sun, 30 Aug 2015 12:29:08 +0300

> v2:
>   - The unused affinity_mask field of the structure cmp_queue 
>   has been deleted. (thanks to David Miller)
>   - The unneeded initializers have been dropped. (thanks to Alexey Klimov)
>   - The commit message "net: thunderx: Rework interrupt handling"
>   has been fixed. (thanks to Alexey Klimov)

Series applied, thanks.


From horms at verge.net.au  Sun Aug 30 22:01:04 2015
From: horms at verge.net.au (Simon Horman)
Date: Mon, 31 Aug 2015 14:01:04 +0900
Subject: [RESEND PATCH v3 3/5] sh: kill off set_irq_flags usage
In-Reply-To: <1440889285-5637-4-git-send-email-robh@kernel.org>
References: <1440889285-5637-1-git-send-email-robh@kernel.org>
 <1440889285-5637-4-git-send-email-robh@kernel.org>
Message-ID: <20150831050104.GA26119@verge.net.au>

Hi Rob,

On Sat, Aug 29, 2015 at 06:01:23PM -0500, Rob Herring wrote:
> set_irq_flags is ARM specific with custom flags which have genirq
> equivalents. Convert drivers to use the genirq interfaces directly, so we
> can kill off set_irq_flags. The translation of flags is as follows:
> 
> IRQF_VALID -> !IRQ_NOREQUEST
> IRQF_PROBE -> !IRQ_NOPROBE
> IRQF_NOAUTOEN -> IRQ_NOAUTOEN
> 
> For IRQs managed by an irqdomain, the irqdomain core code handles clearing
> and setting IRQ_NOREQUEST already, so there is no need to do this in
> .map() functions and we can simply remove the set_irq_flags calls. Some
> users also modify IRQ_NOPROBE and this has been maintained although it
> is not clear that is really needed. There appears to be a great deal of
> blind copy and paste of this code.
> 
> Signed-off-by: Rob Herring <robh at kernel.org>
> Acked-by: Simon Horman <horms at verge.net.au>
> Cc: Magnus Damm <magnus.damm at gmail.com>
> Cc: linux-sh at vger.kernel.org

I have queued this up. Please let me know if that was not your intent.

The patch is queued up in the sh-drivers-for-v4.3 branch of my renesas tree.
At this point I plan to send a pull-request once dt changes that other
patches in that branch depend on hit Linus's tree via the ARM SoC tree.
I anticipate that being during the rc1 or rc2 timeframe.


From jianwei.wang.chn at gmail.com  Sun Aug 30 22:14:33 2015
From: jianwei.wang.chn at gmail.com (Jianwei Wang)
Date: Mon, 31 Aug 2015 13:14:33 +0800
Subject: [PATCH] drm/fsl-dcu: Cleanup vblank interrupt mask and status setting
 code
Message-ID: <1440998073-31851-1-git-send-email-jianwei.wang.chn@gmail.com>

Switch update interrupt mask bit with regmap_update_bits, and clear
interrupt status by writing 1 to relevant bit before setting mask in
fsl_dcu_drm_irq_init function.

Signed-off-by: Jianwei Wang <jianwei.wang.chn at gmail.com>
---
 drivers/gpu/drm/fsl-dcu/fsl_dcu_drm_drv.c | 26 +++++++-------------------
 1 file changed, 7 insertions(+), 19 deletions(-)

diff --git a/drivers/gpu/drm/fsl-dcu/fsl_dcu_drm_drv.c b/drivers/gpu/drm/fsl-dcu/fsl_dcu_drm_drv.c
index 9a8e2da..bf36971 100644
--- a/drivers/gpu/drm/fsl-dcu/fsl_dcu_drm_drv.c
+++ b/drivers/gpu/drm/fsl-dcu/fsl_dcu_drm_drv.c
@@ -38,21 +38,17 @@ static const struct regmap_config fsl_dcu_regmap_config = {
 static int fsl_dcu_drm_irq_init(struct drm_device *dev)
 {
 	struct fsl_dcu_drm_device *fsl_dev = dev->dev_private;
-	unsigned int value;
 	int ret;
 
 	ret = drm_irq_install(dev, fsl_dev->irq);
 	if (ret < 0)
 		dev_err(dev->dev, "failed to install IRQ handler\n");
 
-	ret = regmap_write(fsl_dev->regmap, DCU_INT_STATUS, 0);
+	ret = regmap_write(fsl_dev->regmap, DCU_INT_STATUS, 0xffffffff);
 	if (ret)
 		dev_err(dev->dev, "set DCU_INT_STATUS failed\n");
-	ret = regmap_read(fsl_dev->regmap, DCU_INT_MASK, &value);
-	if (ret)
-		dev_err(dev->dev, "read DCU_INT_MASK failed\n");
-	value &= DCU_INT_MASK_VBLANK;
-	ret = regmap_write(fsl_dev->regmap, DCU_INT_MASK, value);
+	ret = regmap_update_bits(fsl_dev->regmap, DCU_INT_MASK,
+				 DCU_INT_MASK_VBLANK, ~DCU_INT_MASK_VBLANK);
 	if (ret)
 		dev_err(dev->dev, "set DCU_INT_MASK failed\n");
 	ret = regmap_write(fsl_dev->regmap, DCU_UPDATE_MODE,
@@ -143,14 +139,10 @@ static irqreturn_t fsl_dcu_drm_irq(int irq, void *arg)
 static int fsl_dcu_drm_enable_vblank(struct drm_device *dev, int crtc)
 {
 	struct fsl_dcu_drm_device *fsl_dev = dev->dev_private;
-	unsigned int value;
 	int ret;
 
-	ret = regmap_read(fsl_dev->regmap, DCU_INT_MASK, &value);
-	if (ret)
-		dev_err(dev->dev, "read DCU_INT_MASK failed\n");
-	value &= ~DCU_INT_MASK_VBLANK;
-	ret = regmap_write(fsl_dev->regmap, DCU_INT_MASK, value);
+	ret = regmap_update_bits(fsl_dev->regmap, DCU_INT_MASK,
+				 DCU_INT_MASK_VBLANK, ~DCU_INT_MASK_VBLANK);
 	if (ret)
 		dev_err(dev->dev, "set DCU_INT_MASK failed\n");
 	return 0;
@@ -159,14 +151,10 @@ static int fsl_dcu_drm_enable_vblank(struct drm_device *dev, int crtc)
 static void fsl_dcu_drm_disable_vblank(struct drm_device *dev, int crtc)
 {
 	struct fsl_dcu_drm_device *fsl_dev = dev->dev_private;
-	unsigned int value;
 	int ret;
 
-	ret = regmap_read(fsl_dev->regmap, DCU_INT_MASK, &value);
-	if (ret)
-		dev_err(dev->dev, "read DCU_INT_MASK failed\n");
-	value |= DCU_INT_MASK_VBLANK;
-	ret = regmap_write(fsl_dev->regmap, DCU_INT_MASK, value);
+	ret = regmap_update_bits(fsl_dev->regmap, DCU_INT_MASK,
+				 DCU_INT_MASK_VBLANK, DCU_INT_MASK_VBLANK);
 	if (ret)
 		dev_err(dev->dev, "set DCU_INT_MASK failed\n");
 }
-- 
2.1.0.27.g96db324



From k.kozlowski at samsung.com  Sun Aug 30 22:42:53 2015
From: k.kozlowski at samsung.com (Krzysztof Kozlowski)
Date: Mon, 31 Aug 2015 14:42:53 +0900
Subject: [PATCH] arm64: dts: Add BUS1 instance pinctrl support
In-Reply-To: <1440761134-27639-1-git-send-email-alim.akhtar@samsung.com>
References: <1440761134-27639-1-git-send-email-alim.akhtar@samsung.com>
Message-ID: <55E3E95D.50003@samsung.com>

On 28.08.2015 20:25, Alim Akhtar wrote:
> This adds BUS1 instance pinctrl for exynos7 soc.
> 
> Signed-off-by: Alim Akhtar <alim.akhtar at samsung.com>
> ---
>  arch/arm64/boot/dts/exynos/exynos7-pinctrl.dtsi |  111 +++++++++++++++++++++++
>  arch/arm64/boot/dts/exynos/exynos7.dtsi         |    7 ++
>  2 files changed, 118 insertions(+)

The "etc1" GPIO in my datasheet is not fully documented but the rest
looks good:

Reviewed-by: Krzysztof Kozlowski <k.kozlowski at samsung.com>

Best regards,
Krzysztof



From sunil.kovvuri at gmail.com  Mon Aug 31 00:01:25 2015
From: sunil.kovvuri at gmail.com (Sunil Kovvuri)
Date: Mon, 31 Aug 2015 12:31:25 +0530
Subject: [PATCH net-next v2 0/8] net: thunderx: New features and fixes
In-Reply-To: <20150830.215426.1263274449496319755.davem@davemloft.net>
References: <1440926958-1874-1-git-send-email-aleksey.makarov@auriga.com>
 <20150830.215426.1263274449496319755.davem@davemloft.net>
Message-ID: <CA+sq2Cd6N+oP5hL6qjsJVf=o=NBRnY_eMPcryLVAY3sof-MU7A@mail.gmail.com>

>>
>> Series applied, thanks.
>> --
Thanks a lot.


From rjui at broadcom.com  Mon Aug 31 00:18:13 2015
From: rjui at broadcom.com (Ray Jui)
Date: Mon, 31 Aug 2015 00:18:13 -0700
Subject: [PATCH v3 2/5] ARM: NSP: add minimal Northstar Plus device tree
In-Reply-To: <20150831022417.GA27066@broadcom.com>
References: <1440805644-18241-1-git-send-email-jonmason@broadcom.com>
 <55E0FAC4.2040108@broadcom.com> <20150831022417.GA27066@broadcom.com>
Message-ID: <55E3FFB5.6090703@broadcom.com>



On 8/30/2015 7:24 PM, Jon Mason wrote:
> On Fri, Aug 28, 2015 at 05:20:20PM -0700, Ray Jui wrote:
>>
>>
>> On 8/28/2015 4:47 PM, Jon Mason wrote:
>>> Add a very minimalistic set of Northstar Plus Device Tree files which
>>> describes the SoC and the BCM958625 implementation.  The perpherials
>>> described are:
>>>
>>> ARM Cortex A9 CPU
>>> 2 8250 UARTs
>>> ARM GIC
>>> PL310 L2 Cache
>>> ARM A9 Global timer
>>>
>>> Signed-off-by: Kapil Hali <kapilh at broadcom.com>
>>> Signed-off-by: Jon Mason <jonmason at broadcom.com>
>>> ---
>>>  arch/arm/boot/dts/Makefile       |   2 +
>>>  arch/arm/boot/dts/bcm-nsp.dtsi   | 120 +++++++++++++++++++++++++++++++++++++++
>>>  arch/arm/boot/dts/bcm958625k.dts |  57 +++++++++++++++++++
>>>  3 files changed, 179 insertions(+)
>>>  create mode 100644 arch/arm/boot/dts/bcm-nsp.dtsi
>>>  create mode 100644 arch/arm/boot/dts/bcm958625k.dts
>>>
>>> diff --git a/arch/arm/boot/dts/Makefile b/arch/arm/boot/dts/Makefile
>>> index 246473a..adb5732 100644
>>> --- a/arch/arm/boot/dts/Makefile
>>> +++ b/arch/arm/boot/dts/Makefile
>>> @@ -82,6 +82,8 @@ dtb-$(CONFIG_ARCH_BCM_CYGNUS) += \
>>>  dtb-$(CONFIG_ARCH_BCM_MOBILE) += \
>>>  	bcm28155-ap.dtb \
>>>  	bcm21664-garnet.dtb
>>> +dtb-$(CONFIG_ARCH_BCM_NSP) += \
>>> +	bcm958625k.dtb
>>>  dtb-$(CONFIG_ARCH_BERLIN) += \
>>>  	berlin2-sony-nsz-gs7.dtb \
>>>  	berlin2cd-google-chromecast.dtb \
>>> diff --git a/arch/arm/boot/dts/bcm-nsp.dtsi b/arch/arm/boot/dts/bcm-nsp.dtsi
>>> new file mode 100644
>>> index 0000000..f5f494f
>>> --- /dev/null
>>> +++ b/arch/arm/boot/dts/bcm-nsp.dtsi
>>> @@ -0,0 +1,120 @@
>>> +/*
>>> + *  BSD LICENSE
>>> + *
>>> + *  Copyright(c) 2015 Broadcom Corporation.  All rights reserved.
>>> + *
>>> + *  Redistribution and use in source and binary forms, with or without
>>> + *  modification, are permitted provided that the following conditions
>>> + *  are met:
>>> + *
>>> + *    * Redistributions of source code must retain the above copyright
>>> + *      notice, this list of conditions and the following disclaimer.
>>> + *    * Redistributions in binary form must reproduce the above copyright
>>> + *      notice, this list of conditions and the following disclaimer in
>>> + *      the documentation and/or other materials provided with the
>>> + *      distribution.
>>> + *    * Neither the name of Broadcom Corporation nor the names of its
>>> + *      contributors may be used to endorse or promote products derived
>>> + *      from this software without specific prior written permission.
>>> + *
>>> + *  THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
>>> + *  "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
>>> + *  LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
>>> + *  A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
>>> + *  OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
>>> + *  SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
>>> + *  LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
>>> + *  DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
>>> + *  THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
>>> + *  (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
>>> + *  OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
>>> + */
>>> +
>>> +#include <dt-bindings/interrupt-controller/arm-gic.h>
>>> +#include <dt-bindings/interrupt-controller/irq.h>
>>> +
>>> +#include "skeleton.dtsi"
>>> +
>>> +/ {
>>> +	compatible = "brcm,nsp";
>>> +	model = "Broadcom Northstar Plus SoC";
>>> +	interrupt-parent = <&gic>;
>>> +
>>> +	mpcore {
>>> +		compatible = "simple-bus";
>>> +		ranges = <0x00000000 0x19020000 0x00003000>;
>>> +		#address-cells = <1>;
>>> +		#size-cells = <1>;
>>> +
>>> +		cpus {
>>> +			#address-cells = <1>;
>>> +			#size-cells = <0>;
>>> +
>>> +			cpu at 0 {
>>> +				device_type = "cpu";
>>> +				compatible = "arm,cortex-a9";
>>> +				next-level-cache = <&L2>;
>>> +				reg = <0x0>;
>>> +			};
>>> +		};
>>> +
>>> +		L2: l2-cache {
>>> +			compatible = "arm,pl310-cache";
>>> +			reg = <0x2000 0x1000>;
>>> +			cache-unified;
>>> +			cache-level = <2>;
>>> +		};
>>> +
>>> +		gic: interrupt-controller at 19021000 {
>>> +			compatible = "arm,cortex-a9-gic";
>>> +			#interrupt-cells = <3>;
>>> +			#address-cells = <0>;
>>> +			interrupt-controller;
>>> +			reg = <0x1000 0x1000>,
>>> +			      <0x0100 0x100>;
>>> +		};
>>> +
>>> +		timer at 19020200 {
>>> +			compatible = "arm,cortex-a9-global-timer";
>>> +			reg = <0x0200 0x100>;
>>> +			interrupts = <GIC_PPI 11 IRQ_TYPE_LEVEL_HIGH>;
>>> +			clocks = <&periph_clk>;
>>> +		};
>>> +	};
>>> +
>>> +	clocks {
>>> +		#address-cells = <1>;
>>> +		#size-cells = <1>;
>>> +		ranges;
>>> +
>>> +		periph_clk: periph_clk {
>>> +			compatible = "fixed-clock";
>>> +			#clock-cells = <0>;
>>> +			clock-frequency = <500000000>;
>>> +		};
>>> +	};
>>> +
>>> +	apb {
>>> +		compatible = "arm,amba-bus", "simple-bus";
>>
>> Should "arm,amba-bus" has a separate bus node with AMBA compatible
>> devices declared in there (e.g, pl330, spi-pl022, and etc.) in the
>> future after they are brought up? To my best knowledge, "ns16550a" UART
>> is NOT an AMBA compatible device.
> 
> APB is an AMBA bus, so this part is accurate.  The block diagram of
> the SoC has the UARTs (and other perpherials) hanging off of the APB
> bus.  So, this organization follows the block diagram.

Okay so the "apb" node can be used for amba compatible devices
(arm,amba-bus) and/or simple platform devices (simple-bus). I guess
that's fine and I now see that there are some other dtsi also doing it
this way.

> While the
> UART drivers are not AMBA aware, there appears to be no issues with
> this layout (as the HW/drivers come up without issue). Unless there
> is an unforeseen issue with having non-AMBA aware devices on the DT
> AMBA bus, I would think it best to organize it to match the block
> disgram.
> 

UART runs fine because you also have "simple-bus" listed as the
compatible string so uart is populated as standard platform device.

>>> +		interrupt-parent = <&gic>;
>>> +		ranges = <0x00000000 0x18000000 0x00001000>;
>>
>> Does the 'apb' bus mean to cover all peripherals connected through APB?
>> If so, the size is only 0x1000 and that seems to be too small...
> 
> This is all that is currently needed.  I was planning on expanding it
> as I added more devices.

Sure.

I haven't checked the datahsheet but based on the layout (which seems
quite similar to Cygnus), I assume the range for these devices should be
0x18000000 - 0x18ffffff? Just want to make sure there are no other
devices come before 0x18000000 so you don't need to change all these reg
offsets in the future.

> 
> Thanks,
> Jon
> 

Thanks,

Ray


From s.hauer at pengutronix.de  Mon Aug 31 00:34:03 2015
From: s.hauer at pengutronix.de (Sascha Hauer)
Date: Mon, 31 Aug 2015 09:34:03 +0200
Subject: [PATCH v8] Add Mediatek thermal support
Message-ID: <1441006446-4558-1-git-send-email-s.hauer@pengutronix.de>

This series adds support for the thermal sensors included in the
MT8173 SoC. Currently only basic temperature reading is supported
without any interrupt support.

The cpufreq driver for MT8173 is currently under review, so there's no
real cooling device available in mainline. Until this is available the
thermal driver can be tested with the following dts snippet. It creates
a fake gpio fan and a fake trip point which is so low that it can easily
be reached with a "cat /dev/zero > /dev/null" on the command line.

Please review and let me know what's missing to be included in mainline.

changes since v7:
- re-add some used defines removed in v5
- Use MT8173_THERMAL_ZONE_* defines as array indices in static initializers

changes since v6:
- remove dot in Hanyi Wus name

changes since v5:
- update copyright
- remove unused defines

Changes since v4:
- give calibration constants more meaningful names (offset, slope)
- Use define instead of 0x00c for register access.

Changes since v3:
- add include/dt-bindings/thermal/mt8173.h for to be able to use sensor names
  in dts files
- fix disabling wrong clock in error path
- remove now unused reset-names property from binding document
- rename MT8173_NUM_BANKS -> MT8173_NUM_ZONES
- rename MT8173_NUM_SENSING_POINTS -> MT8173_NUM_SENSORS_PER_ZONE
- rename struct thermal_zone_device *tz -> struct thermal_zone_device *tzd

Changes since v2:
- sort #includes alphabetically
- Add prefix to register defines
- drop some members from struct mtk_thermal
- simplify raw_to_mcelsius()
- add and use more register bit defines
- use device_reset() instead of devm_reset_control_get()/reset_control_reset()
- misc other stuff

Changes since v1:
- Use "mediatek," prefix for custom properties
- Drop "thermal: consistently use int for temperatures" dependency

Sascha

        fan: gpio_fan {
                compatible = "gpio-fan";
                gpios = <&pio 24 0>;
                gpio-fan,speed-map = <0    0
                                      4500 1>;
                #cooling-cells = <2>;
        };

        thermal-zones {
                cpu_thermal: cpu_thermal {
                        polling-delay-passive = <1000>; /* milliseconds */
                        polling-delay = <1000>; /* milliseconds */

                        thermal-sensors = <&thermal 0>;

                        trips {
                                cpu_passive: cpu_passive {
                                        temperature = <47000>; /* millicelsius */
                                        hysteresis = <2000>; /* millicelsius */
                                        type = "passive";
                                };

                                cpu_crit {
                                        temperature = <90000>; /* millicelsius */
                                        hysteresis = <2000>; /* millicelsius */
                                        type = "critical";
                                };
                        };

                        cooling-maps {
                                map0 {
                                        trip = <&cpu_passive>;
                                        cooling-device = <&fan THERMAL_NO_LIMIT THERMAL_NO_LIMIT>;
                                };
                        };
                };
        };


From s.hauer at pengutronix.de  Mon Aug 31 00:34:04 2015
From: s.hauer at pengutronix.de (Sascha Hauer)
Date: Mon, 31 Aug 2015 09:34:04 +0200
Subject: [PATCH 1/3] dt-bindings: thermal: Add binding document for Mediatek
 thermal controller
In-Reply-To: <1441006446-4558-1-git-send-email-s.hauer@pengutronix.de>
References: <1441006446-4558-1-git-send-email-s.hauer@pengutronix.de>
Message-ID: <1441006446-4558-2-git-send-email-s.hauer@pengutronix.de>

Signed-off-by: Sascha Hauer <s.hauer at pengutronix.de>
Reviewed-by: Daniel Kurtz <djkurtz at chromium.org>
---
 .../bindings/thermal/mediatek-thermal.txt          | 38 ++++++++++++++++++++++
 include/dt-bindings/thermal/mt8173.h               | 13 ++++++++
 2 files changed, 51 insertions(+)
 create mode 100644 Documentation/devicetree/bindings/thermal/mediatek-thermal.txt
 create mode 100644 include/dt-bindings/thermal/mt8173.h

diff --git a/Documentation/devicetree/bindings/thermal/mediatek-thermal.txt b/Documentation/devicetree/bindings/thermal/mediatek-thermal.txt
new file mode 100644
index 0000000..1697375
--- /dev/null
+++ b/Documentation/devicetree/bindings/thermal/mediatek-thermal.txt
@@ -0,0 +1,38 @@
+* Mediatek Thermal
+
+This describes the device tree binding for the Mediatek thermal controller
+which measures the on-SoC temperatures. This device does not have its own ADC,
+instead it directly controls the AUXADC via AHB bus accesses. For this reason
+this device needs phandles to the AUXADC. Also it controls a mux in the
+apmixedsys register space via AHB bus accesses, so a phandle to the APMIXEDSYS
+is also needed.
+
+Required properties:
+- compatible: "mediatek,mt8173-thermal"
+- reg: Address range of the thermal controller
+- interrupts: IRQ for the thermal controller
+- clocks, clock-names: Clocks needed for the thermal controller. required
+                       clocks are:
+		       "therm":	 Main clock needed for register access
+		       "auxadc": The AUXADC clock
+- resets: Reference to the reset controller controlling the thermal controller.
+- mediatek,auxadc: A phandle to the AUXADC which the thermal controller uses
+- mediatek,apmixedsys: A phandle to the APMIXEDSYS controller.
+- #thermal-sensor-cells : Should be 1. See ./thermal.txt for a description. See
+			  include/dt-bindings/thermal/mt8173.h for valid sensor
+			  numbers.
+
+Example:
+
+	thermal: thermal at 1100b000 {
+		#thermal-sensor-cells = <1>;
+		compatible = "mediatek,mt8173-thermal";
+		reg = <0 0x1100b000 0 0x1000>;
+		interrupts = <0 70 IRQ_TYPE_LEVEL_LOW>;
+		clocks = <&pericfg CLK_PERI_THERM>, <&pericfg CLK_PERI_AUXADC>;
+		clock-names = "therm", "auxadc";
+		resets = <&pericfg MT8173_PERI_THERM_SW_RST>;
+		reset-names = "therm";
+		mediatek,auxadc = <&auxadc>;
+		mediatek,apmixedsys = <&apmixedsys>;
+	};
diff --git a/include/dt-bindings/thermal/mt8173.h b/include/dt-bindings/thermal/mt8173.h
new file mode 100644
index 0000000..692e74c
--- /dev/null
+++ b/include/dt-bindings/thermal/mt8173.h
@@ -0,0 +1,13 @@
+/*
+ * This header provides constants for mediatek,mt8173-thermal
+ */
+
+#ifndef _DT_BINDINGS_THERMAL_MEDIATEK_MT8173_H
+#define _DT_BINDINGS_THERMAL_MEDIATEK_MT8173_H
+
+#define MT8173_THERMAL_ZONE_CA53	0
+#define MT8173_THERMAL_ZONE_CA57	1
+#define MT8173_THERMAL_ZONE_GPU		2
+#define MT8173_THERMAL_ZONE_CORE	3
+
+#endif /* _DT_BINDINGS_THERMAL_MEDIATEK_MT8173_H */
-- 
2.5.0



From s.hauer at pengutronix.de  Mon Aug 31 00:34:05 2015
From: s.hauer at pengutronix.de (Sascha Hauer)
Date: Mon, 31 Aug 2015 09:34:05 +0200
Subject: [PATCH 2/3] thermal: Add Mediatek thermal controller support
In-Reply-To: <1441006446-4558-1-git-send-email-s.hauer@pengutronix.de>
References: <1441006446-4558-1-git-send-email-s.hauer@pengutronix.de>
Message-ID: <1441006446-4558-3-git-send-email-s.hauer@pengutronix.de>

This adds support for the Mediatek thermal controller found on MT8173
and likely other SoCs.
The controller is a bit special. It does not have its own ADC, instead
it controls the on-SoC AUXADC via AHB bus accesses. For this reason
we need the physical address of the AUXADC. Also it controls a mux
using AHB bus accesses, so we need the APMIXEDSYS physical address aswell.

Signed-off-by: Sascha Hauer <s.hauer at pengutronix.de>
Reviewed-by: Daniel Kurtz <djkurtz at chromium.org>
---
 drivers/thermal/Kconfig       |   8 +
 drivers/thermal/Makefile      |   1 +
 drivers/thermal/mtk_thermal.c | 537 ++++++++++++++++++++++++++++++++++++++++++
 3 files changed, 546 insertions(+)
 create mode 100644 drivers/thermal/mtk_thermal.c

diff --git a/drivers/thermal/Kconfig b/drivers/thermal/Kconfig
index 118938e..07ad114 100644
--- a/drivers/thermal/Kconfig
+++ b/drivers/thermal/Kconfig
@@ -340,6 +340,14 @@ config ACPI_THERMAL_REL
 	tristate
 	depends on ACPI
 
+config MTK_THERMAL
+	tristate "Temperature sensor driver for mediatek SoCs"
+	depends on ARCH_MEDIATEK || COMPILE_TEST
+	default y
+	help
+	  Enable this option if you want to have support for thermal management
+	  controller present in Mediatek SoCs
+
 menu "Texas Instruments thermal drivers"
 source "drivers/thermal/ti-soc-thermal/Kconfig"
 endmenu
diff --git a/drivers/thermal/Makefile b/drivers/thermal/Makefile
index 535dfee..cc1cab3 100644
--- a/drivers/thermal/Makefile
+++ b/drivers/thermal/Makefile
@@ -44,3 +44,4 @@ obj-$(CONFIG_INT340X_THERMAL)  += int340x_thermal/
 obj-$(CONFIG_ST_THERMAL)	+= st/
 obj-$(CONFIG_TEGRA_SOCTHERM)	+= tegra_soctherm.o
 obj-$(CONFIG_HISI_THERMAL)     += hisi_thermal.o
+obj-$(CONFIG_MTK_THERMAL)	+= mtk_thermal.o
diff --git a/drivers/thermal/mtk_thermal.c b/drivers/thermal/mtk_thermal.c
new file mode 100644
index 0000000..229d8a7
--- /dev/null
+++ b/drivers/thermal/mtk_thermal.c
@@ -0,0 +1,537 @@
+/*
+ * Copyright (c) 2015 MediaTek Inc.
+ * Author: Hanyi Wu <hanyi.wu at 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/clk.h>
+#include <linux/delay.h>
+#include <linux/interrupt.h>
+#include <linux/kernel.h>
+#include <linux/module.h>
+#include <linux/of.h>
+#include <linux/of_address.h>
+#include <linux/of_irq.h>
+#include <linux/platform_device.h>
+#include <linux/slab.h>
+#include <linux/thermal.h>
+#include <linux/reset.h>
+#include <linux/time.h>
+#include <linux/types.h>
+#include <dt-bindings/thermal/mt8173.h>
+
+/* AUXADC Registers */
+#define AUXADC_CON0_V		0x000
+#define AUXADC_CON1_V		0x004
+#define AUXADC_CON1_SET_V	0x008
+#define AUXADC_CON1_CLR_V	0x00c
+#define AUXADC_CON2_V		0x010
+#define AUXADC_DATA(channel)	(0x14 + (channel) * 4)
+#define AUXADC_MISC_V		0x094
+
+#define AUXADC_CON1_CHANNEL(x)	BIT(x)
+
+#define APMIXED_SYS_TS_CON1	0x604
+
+/* Thermal Controller Registers */
+#define TEMP_MONCTL0		0x000
+#define TEMP_MONCTL1		0x004
+#define TEMP_MONCTL2		0x008
+#define TEMP_MONIDET0		0x014
+#define TEMP_MONIDET1		0x018
+#define TEMP_MSRCTL0		0x038
+#define TEMP_AHBPOLL		0x040
+#define TEMP_AHBTO		0x044
+#define TEMP_ADCPNP0		0x048
+#define TEMP_ADCPNP1		0x04c
+#define TEMP_ADCPNP2		0x050
+#define TEMP_ADCPNP3		0x0b4
+
+#define TEMP_ADCMUX		0x054
+#define TEMP_ADCEN		0x060
+#define TEMP_PNPMUXADDR		0x064
+#define TEMP_ADCMUXADDR		0x068
+#define TEMP_ADCENADDR		0x074
+#define TEMP_ADCVALIDADDR	0x078
+#define TEMP_ADCVOLTADDR	0x07c
+#define TEMP_RDCTRL		0x080
+#define TEMP_ADCVALIDMASK	0x084
+#define TEMP_ADCVOLTAGESHIFT	0x088
+#define TEMP_ADCWRITECTRL	0x08c
+#define TEMP_MSR0		0x090
+#define TEMP_MSR1		0x094
+#define TEMP_MSR2		0x098
+#define TEMP_MSR3		0x0B8
+
+#define TEMP_SPARE0		0x0f0
+
+#define PTPCORESEL		0x400
+
+#define TEMP_MONCTL1_PERIOD_UNIT(x)	((x) & 0x3ff)
+
+#define TEMP_MONCTL2_FILTER_INTERVAL(x)	(((x) & 0x3ff)) << 16
+#define TEMP_MONCTL2_SENSOR_INTERVAL(x)	((x) & 0x3ff)
+
+#define TEMP_AHBPOLL_ADC_POLL_INTERVAL(x)	(x)
+
+#define TEMP_ADCWRITECTRL_ADC_PNP_WRITE		BIT(0)
+#define TEMP_ADCWRITECTRL_ADC_MUX_WRITE		BIT(1)
+
+#define TEMP_ADCVALIDMASK_VALID_HIGH		BIT(5)
+#define TEMP_ADCVALIDMASK_VALID_POS(bit)	(bit)
+
+#define MT8173_TS1	0
+#define MT8173_TS2	1
+#define MT8173_TS3	2
+#define MT8173_TS4	3
+#define MT8173_TSABB	4
+
+/* AUXADC channel 11 is used for the temperature sensors */
+#define MT8173_TEMP_AUXADC_CHANNEL	11
+
+/* The total number of temperature sensors in the MT8173 */
+#define MT8173_NUM_SENSORS		5
+
+/* The number of banks in the MT8173 */
+#define MT8173_NUM_ZONES		4
+
+/* The number of sensing points per bank */
+#define MT8173_NUM_SENSORS_PER_ZONE	4
+
+#define THERMAL_NAME    "mtk-thermal"
+
+struct mtk_thermal;
+
+struct mtk_thermal_bank {
+	struct mtk_thermal *mt;
+	struct thermal_zone_device *tzd;
+	int id;
+};
+
+struct mtk_thermal {
+	struct device *dev;
+	void __iomem *thermal_base;
+
+	struct clk *clk_peri_therm;
+	struct clk *clk_auxadc;
+
+	struct mtk_thermal_bank banks[MT8173_NUM_ZONES];
+
+	struct mutex lock;
+
+	/* Calibration values */
+	int calib_slope;
+	int calib_offset;
+};
+
+struct mtk_thermal_bank_cfg {
+	unsigned int num_sensors;
+	unsigned int sensors[MT8173_NUM_SENSORS_PER_ZONE];
+};
+
+static const int sensor_mux_values[MT8173_NUM_SENSORS] = { 0, 1, 2, 3, 16 };
+
+/*
+ * The MT8173 thermal controller has four banks. Each bank can read up to
+ * four temperature sensors simultaneously. The MT8173 has a total of 5
+ * temperature sensors. We use each bank to measure a certain area of the
+ * SoC. Since TS2 is located centrally in the SoC it is influenced by multiple
+ * areas, hence is used in different banks.
+ */
+static const struct mtk_thermal_bank_cfg bank_data[] = {
+	[MT8173_THERMAL_ZONE_CA53] = {
+		.num_sensors = 2,
+		.sensors = { MT8173_TS2, MT8173_TS3 },
+	},
+
+	[MT8173_THERMAL_ZONE_CA57] = {
+		.num_sensors = 2,
+		.sensors = { MT8173_TS2, MT8173_TS4 },
+	},
+
+	[MT8173_THERMAL_ZONE_GPU] = {
+		.num_sensors = 3,
+		.sensors = { MT8173_TS1, MT8173_TS2, MT8173_TSABB },
+	},
+
+	[MT8173_THERMAL_ZONE_CORE] = {
+		.num_sensors = 1,
+		.sensors = { MT8173_TS2 },
+	},
+};
+
+struct mtk_thermal_sense_point {
+	int msr;
+	int adcpnp;
+};
+
+static const struct mtk_thermal_sense_point
+		sensing_points[MT8173_NUM_SENSORS_PER_ZONE] = {
+	{
+		.msr = TEMP_MSR0,
+		.adcpnp = TEMP_ADCPNP0,
+	}, {
+		.msr = TEMP_MSR1,
+		.adcpnp = TEMP_ADCPNP1,
+	}, {
+		.msr = TEMP_MSR2,
+		.adcpnp = TEMP_ADCPNP2,
+	}, {
+		.msr = TEMP_MSR3,
+		.adcpnp = TEMP_ADCPNP3,
+	},
+};
+
+/**
+ * raw_to_mcelsius - convert a raw ADC value to mcelsius
+ * @mt:		The thermal controller
+ * @raw:	raw ADC value
+ *
+ * This converts the raw ADC value to mcelsius using the SoC specific
+ * calibration constants
+ */
+static int raw_to_mcelsius(struct mtk_thermal *mt, u32 raw)
+{
+	return mt->calib_offset + mt->calib_slope * (raw & 0xfff);
+}
+
+/**
+ * mtk_thermal_get_bank - get bank
+ * @bank:	The bank
+ *
+ * The bank registers are banked, we have to select a bank in the
+ * PTPCORESEL register to access it.
+ */
+static void mtk_thermal_get_bank(struct mtk_thermal_bank *bank)
+{
+	struct mtk_thermal *mt = bank->mt;
+	u32 val;
+
+	mutex_lock(&mt->lock);
+
+	val = readl(mt->thermal_base + PTPCORESEL);
+	val &= ~0xf;
+	val |= bank->id;
+	writel(val, mt->thermal_base + PTPCORESEL);
+}
+
+/**
+ * mtk_thermal_put_bank - release bank
+ * @bank:	The bank
+ *
+ * release a bank previously taken with mtk_thermal_get_bank,
+ */
+static void mtk_thermal_put_bank(struct mtk_thermal_bank *bank)
+{
+	struct mtk_thermal *mt = bank->mt;
+
+	mutex_unlock(&mt->lock);
+}
+
+/**
+ * mtk_thermal_bank_temperature - get the temperature of a bank
+ * @bank:	The bank
+ *
+ * The temperature of a bank is considered the maximum temperature of
+ * the sensors associated to the bank.
+ */
+static int mtk_thermal_bank_temperature(struct mtk_thermal_bank *bank)
+{
+	struct mtk_thermal *mt = bank->mt;
+	int temp, i, max;
+	u32 raw;
+
+	temp = max = INT_MIN;
+
+	for (i = 0; i < bank_data[bank->id].num_sensors; i++) {
+		raw = readl(mt->thermal_base + sensing_points[i].msr);
+
+		temp = raw_to_mcelsius(mt, raw);
+
+		/*
+		 * The first read of a sensor often contains very high bogus
+		 * temperature value. Filter these out so that the system does
+		 * not immediately shut down.
+		 */
+		if (temp > 200000)
+			temp = 0;
+
+		if (temp > max)
+			max = temp;
+	}
+
+	return max;
+}
+
+static int mtk_read_temp(void *data, long *temp)
+{
+	struct mtk_thermal_bank *bank = data;
+
+	mtk_thermal_get_bank(bank);
+
+	*temp = mtk_thermal_bank_temperature(bank);
+
+	mtk_thermal_put_bank(bank);
+
+	return 0;
+}
+
+static const struct thermal_zone_of_device_ops mtk_thermal_ops = {
+	.get_temp = mtk_read_temp,
+};
+
+static void mtk_thermal_init_bank(struct mtk_thermal *mt, int num,
+		u32 apmixed_phys_base, u32 auxadc_phys_base)
+{
+	struct mtk_thermal_bank *bank = &mt->banks[num];
+	const struct mtk_thermal_bank_cfg *cfg = &bank_data[num];
+	int i;
+
+	bank->id = num;
+	bank->mt = mt;
+
+	mtk_thermal_get_bank(bank);
+
+	/* bus clock 66M counting unit is 12 * 15.15ns * 256 = 46.540us */
+	writel(TEMP_MONCTL1_PERIOD_UNIT(12), mt->thermal_base + TEMP_MONCTL1);
+
+	/*
+	 * filt interval is 1 * 46.540us = 46.54us,
+	 * sen interval is 429 * 46.540us = 19.96ms
+	 */
+	writel(TEMP_MONCTL2_FILTER_INTERVAL(1) |
+			TEMP_MONCTL2_SENSOR_INTERVAL(429),
+			mt->thermal_base + TEMP_MONCTL2);
+
+	/* poll is set to 10u */
+	writel(TEMP_AHBPOLL_ADC_POLL_INTERVAL(768),
+			mt->thermal_base + TEMP_AHBPOLL);
+
+	/* temperature sampling control, 1 sample */
+	writel(0x00000000, mt->thermal_base + TEMP_MSRCTL0);
+
+	/* exceed this polling time, IRQ would be inserted */
+	writel(0xffffffff, mt->thermal_base + TEMP_AHBTO);
+
+	/* number of interrupts per event, 1 is enough */
+	writel(0x0, mt->thermal_base + TEMP_MONIDET0);
+	writel(0x0, mt->thermal_base + TEMP_MONIDET1);
+
+	/*
+	 * The MT8173 thermal controller does not have its own ADC. Instead it
+	 * uses AHB bus accesses to control the AUXADC. To do this the thermal
+	 * controller has to be programmed with the physical addresses of the
+	 * AUXADC registers and with the various bit positions in the AUXADC.
+	 * Also the thermal controller controls a mux in the APMIXEDSYS register
+	 * space.
+	 */
+
+	/*
+	 * this value will be stored to TEMP_PNPMUXADDR (TEMP_SPARE0)
+	 * automatically by hw
+	 */
+	writel(BIT(MT8173_TEMP_AUXADC_CHANNEL), mt->thermal_base + TEMP_ADCMUX);
+
+	/* AHB address for auxadc mux selection */
+	writel(auxadc_phys_base + AUXADC_CON1_CLR_V,
+			mt->thermal_base + TEMP_ADCMUXADDR);
+
+	/* AHB address for pnp sensor mux selection */
+	writel(apmixed_phys_base + APMIXED_SYS_TS_CON1,
+			mt->thermal_base + TEMP_PNPMUXADDR);
+
+	/* AHB value for auxadc enable */
+	writel(BIT(MT8173_TEMP_AUXADC_CHANNEL), mt->thermal_base + TEMP_ADCEN);
+
+	/* AHB address for auxadc enable (channel 0 immediate mode selected) */
+	writel(auxadc_phys_base + AUXADC_CON1_SET_V,
+			mt->thermal_base + TEMP_ADCENADDR);
+
+	/* AHB address for auxadc valid bit */
+	writel(auxadc_phys_base + AUXADC_DATA(MT8173_TEMP_AUXADC_CHANNEL),
+			mt->thermal_base + TEMP_ADCVALIDADDR);
+
+	/* AHB address for auxadc voltage output */
+	writel(auxadc_phys_base + AUXADC_DATA(MT8173_TEMP_AUXADC_CHANNEL),
+			mt->thermal_base + TEMP_ADCVOLTADDR);
+
+	/* read valid & voltage are at the same register */
+	writel(0x0, mt->thermal_base + TEMP_RDCTRL);
+
+	/* indicate where the valid bit is */
+	writel(TEMP_ADCVALIDMASK_VALID_HIGH | TEMP_ADCVALIDMASK_VALID_POS(12),
+			mt->thermal_base + TEMP_ADCVALIDMASK);
+
+	/* no shift */
+	writel(0x0, mt->thermal_base + TEMP_ADCVOLTAGESHIFT);
+
+	/* enable auxadc mux write transaction */
+	writel(TEMP_ADCWRITECTRL_ADC_MUX_WRITE,
+			mt->thermal_base + TEMP_ADCWRITECTRL);
+
+	for (i = 0; i < cfg->num_sensors; i++)
+		writel(sensor_mux_values[cfg->sensors[i]],
+				mt->thermal_base + sensing_points[i].adcpnp);
+
+	writel((1 << cfg->num_sensors) - 1, mt->thermal_base + TEMP_MONCTL0);
+
+	writel(TEMP_ADCWRITECTRL_ADC_PNP_WRITE | TEMP_ADCWRITECTRL_ADC_MUX_WRITE,
+			mt->thermal_base + TEMP_ADCWRITECTRL);
+
+	mtk_thermal_put_bank(bank);
+}
+
+static u64 of_get_phys_base(struct device_node *np)
+{
+	u64 size64;
+	const __be32 *regaddr_p;
+
+	regaddr_p = of_get_address(np, 0, &size64, NULL);
+	if (!regaddr_p)
+		return OF_BAD_ADDR;
+
+	return of_translate_address(np, regaddr_p);
+}
+
+static int mtk_thermal_probe(struct platform_device *pdev)
+{
+	int ret, i;
+	struct device_node *auxadc, *apmixedsys, *np = pdev->dev.of_node;
+	struct mtk_thermal *mt;
+	struct resource *res;
+	u64 auxadc_phys_base, apmixed_phys_base;
+
+	mt = devm_kzalloc(&pdev->dev, sizeof(*mt), GFP_KERNEL);
+	if (!mt)
+		return -ENOMEM;
+
+	mt->clk_peri_therm = devm_clk_get(&pdev->dev, "therm");
+	if (IS_ERR(mt->clk_peri_therm))
+		return PTR_ERR(mt->clk_peri_therm);
+
+	mt->clk_auxadc = devm_clk_get(&pdev->dev, "auxadc");
+	if (IS_ERR(mt->clk_auxadc))
+		return PTR_ERR(mt->clk_auxadc);
+
+	res = platform_get_resource(pdev, IORESOURCE_MEM, 0);
+	mt->thermal_base = devm_ioremap_resource(&pdev->dev, res);
+	if (IS_ERR(mt->thermal_base))
+		return PTR_ERR(mt->thermal_base);
+
+	mutex_init(&mt->lock);
+
+	mt->dev = &pdev->dev;
+
+	auxadc = of_parse_phandle(np, "mediatek,auxadc", 0);
+	if (!auxadc) {
+		dev_err(&pdev->dev, "missing auxadc node\n");
+		return -ENODEV;
+	}
+
+	auxadc_phys_base = of_get_phys_base(auxadc);
+	if (auxadc_phys_base == OF_BAD_ADDR) {
+		dev_err(&pdev->dev, "Can't get auxadc phys address\n");
+		return -EINVAL;
+	}
+
+	apmixedsys = of_parse_phandle(np, "mediatek,apmixedsys", 0);
+	if (!apmixedsys) {
+		dev_err(&pdev->dev, "missing apmixedsys node\n");
+		return -ENODEV;
+	}
+
+	apmixed_phys_base = of_get_phys_base(apmixedsys);
+	if (apmixed_phys_base == OF_BAD_ADDR) {
+		dev_err(&pdev->dev, "Can't get auxadc phys address\n");
+		return -EINVAL;
+	}
+
+	ret = clk_prepare_enable(mt->clk_auxadc);
+	if (ret) {
+		dev_err(&pdev->dev, "Can't enable auxadc clk: %d\n", ret);
+		return ret;
+	}
+
+	ret = device_reset(&pdev->dev);
+	if (ret)
+		goto err_disable_clk_auxadc;
+
+	ret = clk_prepare_enable(mt->clk_peri_therm);
+	if (ret) {
+		dev_err(&pdev->dev, "Can't enable peri clk: %d\n", ret);
+		goto err_disable_clk_auxadc;
+	}
+
+	/*
+	 * These calibration values should finally be provided by the
+	 * firmware or fuses. For now use default values.
+	 */
+	mt->calib_slope = -123;
+	mt->calib_offset = 465124;
+
+	for (i = 0; i < MT8173_NUM_ZONES; i++)
+		mtk_thermal_init_bank(mt, i, apmixed_phys_base, auxadc_phys_base);
+
+	platform_set_drvdata(pdev, mt);
+
+	for (i = 0; i < MT8173_NUM_ZONES; i++) {
+		struct mtk_thermal_bank *bank = &mt->banks[i];
+
+		bank->tzd = thermal_zone_of_sensor_register(&pdev->dev, i, bank,
+				&mtk_thermal_ops);
+	}
+
+	return 0;
+
+err_disable_clk_auxadc:
+	clk_disable_unprepare(mt->clk_auxadc);
+
+	return ret;
+}
+
+static int mtk_thermal_remove(struct platform_device *pdev)
+{
+	struct mtk_thermal *mt = platform_get_drvdata(pdev);
+	int i;
+
+	for (i = 0; i < MT8173_NUM_ZONES; i++) {
+		struct mtk_thermal_bank *bank = &mt->banks[i];
+
+		thermal_zone_of_sensor_unregister(&pdev->dev, bank->tzd);
+	}
+
+	clk_disable_unprepare(mt->clk_peri_therm);
+	clk_disable_unprepare(mt->clk_auxadc);
+
+	return 0;
+}
+
+static const struct of_device_id mtk_thermal_of_match[] = {
+	{
+		.compatible = "mediatek,mt8173-thermal",
+	}, {
+	},
+};
+
+static struct platform_driver mtk_thermal_driver = {
+	.probe = mtk_thermal_probe,
+	.remove = mtk_thermal_remove,
+	.driver = {
+		.name = THERMAL_NAME,
+		.of_match_table = mtk_thermal_of_match,
+	},
+};
+
+module_platform_driver(mtk_thermal_driver);
+
+MODULE_AUTHOR("Sascha Hauer <s.hauer at pengutronix.de");
+MODULE_DESCRIPTION("Mediatek thermal driver");
+MODULE_LICENSE("GPL v2");
-- 
2.5.0



From s.hauer at pengutronix.de  Mon Aug 31 00:34:06 2015
From: s.hauer at pengutronix.de (Sascha Hauer)
Date: Mon, 31 Aug 2015 09:34:06 +0200
Subject: [PATCH 3/3] ARM64: dts: mt8173: Add thermal/auxadc device nodes
In-Reply-To: <1441006446-4558-1-git-send-email-s.hauer@pengutronix.de>
References: <1441006446-4558-1-git-send-email-s.hauer@pengutronix.de>
Message-ID: <1441006446-4558-4-git-send-email-s.hauer@pengutronix.de>

Signed-off-by: Sascha Hauer <s.hauer at pengutronix.de>
Reviewed-by: Daniel Kurtz <djkurtz at chromium.org>
---
 arch/arm64/boot/dts/mediatek/mt8173.dtsi | 17 +++++++++++++++++
 1 file changed, 17 insertions(+)

diff --git a/arch/arm64/boot/dts/mediatek/mt8173.dtsi b/arch/arm64/boot/dts/mediatek/mt8173.dtsi
index 27237a1..ddacb86 100644
--- a/arch/arm64/boot/dts/mediatek/mt8173.dtsi
+++ b/arch/arm64/boot/dts/mediatek/mt8173.dtsi
@@ -151,6 +151,11 @@
 				(GIC_CPU_MASK_SIMPLE(4) | IRQ_TYPE_LEVEL_HIGH)>;
 		};
 
+		auxadc: auxadc at 11001000 {
+			compatible = "mediatek,mt8173-auxadc";
+			reg = <0 0x11001000 0 0x1000>;
+		};
+
 		uart0: serial at 11002000 {
 			compatible = "mediatek,mt8173-uart",
 				     "mediatek,mt6577-uart";
@@ -186,6 +191,18 @@
 			clocks = <&uart_clk>;
 			status = "disabled";
 		};
+
+		thermal: thermal at 1100b000 {
+			#thermal-sensor-cells = <1>;
+			compatible = "mediatek,mt8173-thermal";
+			reg = <0 0x1100b000 0 0x1000>;
+			interrupts = <0 70 IRQ_TYPE_LEVEL_LOW>;
+			clocks = <&pericfg CLK_PERI_THERM>, <&pericfg CLK_PERI_AUXADC>;
+			clock-names = "therm", "auxadc";
+			resets = <&pericfg MT8173_PERI_THERM_SW_RST>;
+			mediatek,auxadc = <&auxadc>;
+			mediatek,apmixedsys = <&apmixedsys>;
+		};
 	};
 };
 
-- 
2.5.0



From maxime.coquelin at st.com  Mon Aug 31 00:49:41 2015
From: maxime.coquelin at st.com (Maxime Coquelin)
Date: Mon, 31 Aug 2015 09:49:41 +0200
Subject: [PATCH 3/7] dmaengine: st_fdma: Add STMicroelectronics FDMA
 engine driver support
In-Reply-To: <1436429872.20619.77.camel@tiscali.nl>
References: <1436371888-27863-1-git-send-email-peter.griffin@linaro.org>
 <1436371888-27863-4-git-send-email-peter.griffin@linaro.org>
 <1436429872.20619.77.camel@tiscali.nl>
Message-ID: <55E40715.1040204@st.com>

Hi Paul,

On 07/09/2015 10:17 AM, Paul Bolle wrote:
>> >+static int __exit st_fdma_remove(struct platform_device *pdev)
>> >+{
>> >+	struct st_fdma_dev *fdev = platform_get_drvdata(pdev);
>> >+
>> >+	wait_for_completion(&fdev->fw_ack);
>> >+
>> >+	st_fdma_clk_disable(fdev);
>> >+
>> >+	return 0;
>> >+}
> Since this driver is built-in only this means st_fdma_remove() can never
> be used, right?
>

It's not because a driver is built-in only that it does not need a 
remove callback.
An instance can be probed/removed any time via driver's bind/unbind 
SysFS entries.
Am I missing something?

Kind regards,
Maxime


From drinkcat at chromium.org  Mon Aug 31 00:54:13 2015
From: drinkcat at chromium.org (Nicolas Boichat)
Date: Mon, 31 Aug 2015 15:54:13 +0800
Subject: [PATCH v2] spi: bitbang: Replace spinlock by mutex
In-Reply-To: <1439783574-5933-1-git-send-email-drinkcat@chromium.org>
References: <1439783574-5933-1-git-send-email-drinkcat@chromium.org>
Message-ID: <CANMq1KAOsyhT1w54dc1u6JRzUdrjo-RpCb7CQBD66OdrSyPh=w@mail.gmail.com>

Hi Mark,

On Mon, Aug 17, 2015 at 11:52 AM, Nicolas Boichat <drinkcat at chromium.org> wrote:
> chipselect (in the case of spi-gpio: spi_gpio_chipselect, which
> calls gpiod_set_raw_value_cansleep) can sleep, so we should not
> hold a spinlock while calling it from spi_bitbang_setup.
>
> This issue was introduced by this commit, which converted spi-gpio
> to cansleep variants:
> d9dda5a191 "spi: spi-gpio: Use 'cansleep' variants to access GPIO"
>
> Replacing the lock variable by a mutex fixes the issue: This is
> safe as all instances where the lock is used are called from
> contexts that can sleep.
>
> Finally, update spi-ppc4xx and and spi-s3c24xx to use mutex
> functions, as they directly hold the lock for similar purpose.
>
> Signed-off-by: Nicolas Boichat <drinkcat at chromium.org>
> ---
> Going the "safer" way and just replacing the spinlock by a
> mutex.
>
> Applies on top of broonie-sound/for-next, and compile-tested on
> x86-64/arm (allyesconfig) and ppc44x (defconfig+SPI driver),
> and runtime-tested on an arm platform.
>
> Thanks!

Any update on this patch? It still applies on for-next but happy to
resend if necessary (patchwork:
https://patchwork.kernel.org/patch/7023091/).

Best,

>  drivers/spi/spi-bitbang.c       | 17 +++++++----------
>  drivers/spi/spi-ppc4xx.c        |  4 ++--
>  drivers/spi/spi-s3c24xx.c       |  4 ++--
>  include/linux/spi/spi_bitbang.h |  2 +-
>  4 files changed, 12 insertions(+), 15 deletions(-)
>
> diff --git a/drivers/spi/spi-bitbang.c b/drivers/spi/spi-bitbang.c
> index 840a498..ef43ef5 100644
> --- a/drivers/spi/spi-bitbang.c
> +++ b/drivers/spi/spi-bitbang.c
> @@ -180,7 +180,6 @@ int spi_bitbang_setup(struct spi_device *spi)
>  {
>         struct spi_bitbang_cs   *cs = spi->controller_state;
>         struct spi_bitbang      *bitbang;
> -       unsigned long           flags;
>
>         bitbang = spi_master_get_devdata(spi->master);
>
> @@ -210,12 +209,12 @@ int spi_bitbang_setup(struct spi_device *spi)
>          */
>
>         /* deselect chip (low or high) */
> -       spin_lock_irqsave(&bitbang->lock, flags);
> +       mutex_lock(&bitbang->lock);
>         if (!bitbang->busy) {
>                 bitbang->chipselect(spi, BITBANG_CS_INACTIVE);
>                 ndelay(cs->nsecs);
>         }
> -       spin_unlock_irqrestore(&bitbang->lock, flags);
> +       mutex_unlock(&bitbang->lock);
>
>         return 0;
>  }
> @@ -255,13 +254,12 @@ static int spi_bitbang_bufs(struct spi_device *spi, struct spi_transfer *t)
>  static int spi_bitbang_prepare_hardware(struct spi_master *spi)
>  {
>         struct spi_bitbang      *bitbang;
> -       unsigned long           flags;
>
>         bitbang = spi_master_get_devdata(spi);
>
> -       spin_lock_irqsave(&bitbang->lock, flags);
> +       mutex_lock(&bitbang->lock);
>         bitbang->busy = 1;
> -       spin_unlock_irqrestore(&bitbang->lock, flags);
> +       mutex_unlock(&bitbang->lock);
>
>         return 0;
>  }
> @@ -378,13 +376,12 @@ static int spi_bitbang_transfer_one(struct spi_master *master,
>  static int spi_bitbang_unprepare_hardware(struct spi_master *spi)
>  {
>         struct spi_bitbang      *bitbang;
> -       unsigned long           flags;
>
>         bitbang = spi_master_get_devdata(spi);
>
> -       spin_lock_irqsave(&bitbang->lock, flags);
> +       mutex_lock(&bitbang->lock);
>         bitbang->busy = 0;
> -       spin_unlock_irqrestore(&bitbang->lock, flags);
> +       mutex_unlock(&bitbang->lock);
>
>         return 0;
>  }
> @@ -427,7 +424,7 @@ int spi_bitbang_start(struct spi_bitbang *bitbang)
>         if (!master || !bitbang->chipselect)
>                 return -EINVAL;
>
> -       spin_lock_init(&bitbang->lock);
> +       mutex_init(&bitbang->lock);
>
>         if (!master->mode_bits)
>                 master->mode_bits = SPI_CPOL | SPI_CPHA | bitbang->flags;
> diff --git a/drivers/spi/spi-ppc4xx.c b/drivers/spi/spi-ppc4xx.c
> index 54fb984..dd3d0a2 100644
> --- a/drivers/spi/spi-ppc4xx.c
> +++ b/drivers/spi/spi-ppc4xx.c
> @@ -210,12 +210,12 @@ static int spi_ppc4xx_setupxfer(struct spi_device *spi, struct spi_transfer *t)
>         if (in_8(&hw->regs->cdm) != cdm)
>                 out_8(&hw->regs->cdm, cdm);
>
> -       spin_lock(&hw->bitbang.lock);
> +       mutex_lock(&hw->bitbang.lock);
>         if (!hw->bitbang.busy) {
>                 hw->bitbang.chipselect(spi, BITBANG_CS_INACTIVE);
>                 /* Need to ndelay here? */
>         }
> -       spin_unlock(&hw->bitbang.lock);
> +       mutex_unlock(&hw->bitbang.lock);
>
>         return 0;
>  }
> diff --git a/drivers/spi/spi-s3c24xx.c b/drivers/spi/spi-s3c24xx.c
> index f36bc32..4e7d1bf 100644
> --- a/drivers/spi/spi-s3c24xx.c
> +++ b/drivers/spi/spi-s3c24xx.c
> @@ -198,12 +198,12 @@ static int s3c24xx_spi_setup(struct spi_device *spi)
>         if (ret)
>                 return ret;
>
> -       spin_lock(&hw->bitbang.lock);
> +       mutex_lock(&hw->bitbang.lock);
>         if (!hw->bitbang.busy) {
>                 hw->bitbang.chipselect(spi, BITBANG_CS_INACTIVE);
>                 /* need to ndelay for 0.5 clocktick ? */
>         }
> -       spin_unlock(&hw->bitbang.lock);
> +       mutex_unlock(&hw->bitbang.lock);
>
>         return 0;
>  }
> diff --git a/include/linux/spi/spi_bitbang.h b/include/linux/spi/spi_bitbang.h
> index 85578d4..154788e 100644
> --- a/include/linux/spi/spi_bitbang.h
> +++ b/include/linux/spi/spi_bitbang.h
> @@ -4,7 +4,7 @@
>  #include <linux/workqueue.h>
>
>  struct spi_bitbang {
> -       spinlock_t              lock;
> +       struct mutex            lock;
>         u8                      busy;
>         u8                      use_dma;
>         u8                      flags;          /* extra spi->mode support */
> --
> 2.5.0.276.gf5e568e
>


From pebolle at tiscali.nl  Mon Aug 31 01:08:01 2015
From: pebolle at tiscali.nl (Paul Bolle)
Date: Mon, 31 Aug 2015 10:08:01 +0200
Subject: [PATCH 3/7] dmaengine: st_fdma: Add STMicroelectronics FDMA
 engine driver support
In-Reply-To: <55E40715.1040204@st.com>
References: <1436371888-27863-1-git-send-email-peter.griffin@linaro.org>
 <1436371888-27863-4-git-send-email-peter.griffin@linaro.org>
 <1436429872.20619.77.camel@tiscali.nl> <55E40715.1040204@st.com>
Message-ID: <1441008481.8272.10.camel@tiscali.nl>

Hi Maxime,

On ma, 2015-08-31 at 09:49 +0200, Maxime Coquelin wrote:
> On 07/09/2015 10:17 AM, Paul Bolle wrote:
> > > > +static int __exit st_fdma_remove(struct platform_device *pdev)
> > > > +{
> > > > +	struct st_fdma_dev *fdev = platform_get_drvdata(pdev);
> > > > +
> > > > +	wait_for_completion(&fdev->fw_ack);
> > > > +
> > > > +	st_fdma_clk_disable(fdev);
> > > > +
> > > > +	return 0;
> > > > +}
> > Since this driver is built-in only this means st_fdma_remove() can 
> > never be used, right?

> It's not because a driver is built-in only that it does not need a 
> remove callback.
> An instance can be probed/removed any time via driver's bind/unbind 
> SysFS entries.
> Am I missing something?

(This discussion is moot because Peter already stated that a new version
will be modular.)

It follows from the __exit tag that st_fdma_remove() should never be
part of the kernel image (in this version of the patch), doesn't it?

(I don't know what happens in this situation if an unbind sysfs entry is
used to remove a driver. I've never tried that.)


Paul Bolle


From eric.auger at linaro.org  Mon Aug 31 01:42:43 2015
From: eric.auger at linaro.org (Eric Auger)
Date: Mon, 31 Aug 2015 10:42:43 +0200
Subject: [PATCH v2 01/15] KVM: arm/arm64: VGIC: don't track used LRs in
 the distributor
In-Reply-To: <55DB474F.7010202@arm.com>
References: <1436538111-4294-1-git-send-email-andre.przywara@arm.com>
 <1436538111-4294-2-git-send-email-andre.przywara@arm.com>
 <55CB0B80.5040508@linaro.org> <55DB474F.7010202@arm.com>
Message-ID: <55E41383.2000109@linaro.org>

On 08/24/2015 06:33 PM, Andre Przywara wrote:
> Hi Eric,
> 
> On 12/08/15 10:01, Eric Auger wrote:
> ....
>>> diff --git a/virt/kvm/arm/vgic.c b/virt/kvm/arm/vgic.c
>>> index bc40137..394622c 100644
>>> --- a/virt/kvm/arm/vgic.c
>>> +++ b/virt/kvm/arm/vgic.c
>>> @@ -79,7 +79,6 @@
>>>  #include "vgic.h"
>>>  
>>>  static void vgic_retire_disabled_irqs(struct kvm_vcpu *vcpu);
>>> -static void vgic_retire_lr(int lr_nr, int irq, struct kvm_vcpu *vcpu);
>>>  static struct vgic_lr vgic_get_lr(const struct kvm_vcpu *vcpu, int lr);
>>>  static void vgic_set_lr(struct kvm_vcpu *vcpu, int lr, struct vgic_lr lr_desc);
>>>  
>>> @@ -647,6 +646,17 @@ bool vgic_handle_cfg_reg(u32 *reg, struct kvm_exit_mmio *mmio,
>>>  	return false;
>>>  }
>>>  
>>> +static void vgic_sync_lr_elrsr(struct kvm_vcpu *vcpu, int lr,
>>> +			       struct vgic_lr vlr)
>>> +{
>>> +	vgic_ops->sync_lr_elrsr(vcpu, lr, vlr);
>>> +}
>> why not renaming this into vgic_set_elrsr. This would be homogeneous
>> with other virtual interface control register setters?
> 
> But that would involve renaming the vgic_ops members as well to be
> consistent, right?
yes
 As there is no change in the behaviour, a naming
> change sounds unmotivated to me. And _set_ wouldn't be exact, as this
> function deals only with only one bit at a time and allows to clear it
> as well.
OK. Not that much important. That's just I had in mind the
__kvm_vgic_SYNC_hwstate which has more intelligence ;-) That function
just sets one bit of elrsr ...
> 
>>> +
>>> +static inline u64 vgic_get_elrsr(struct kvm_vcpu *vcpu)
>>> +{
>>> +	return vgic_ops->get_elrsr(vcpu);
>>> +}
>> If I am not wrong, each time you manipulate the elrsr you handle the
>> bitmap. why not directly returning an unsigned long * then (elrsr_ptr)?
> 
> Because the pointer needs to point somewhere, and that storage is
> currently located on the caller's stack. Directly returning a pointer
> would require the caller to provide some memory for the u64, which does
> not save you so much in terms on LOC:
> 
> -	u64 elrsr = vgic_get_elrsr(vcpu);
> -	unsigned long *elrsr_ptr = u64_to_bitmask(&elrsr);
> +	u64 elrsr;
> +	unsigned long *elrsr_ptr = vgic_get_elrsr_bm(vcpu, &elrsr);
> 
> Also we need u64_to_bitmask() in one case when converting the EISR
> value, so we cannot get lost of that function.

OK fair enough
> 
>>> +
>>>  /**
>>>   * vgic_unqueue_irqs - move pending/active IRQs from LRs to the distributor
>>>   * @vgic_cpu: Pointer to the vgic_cpu struct holding the LRs
>>> @@ -658,9 +668,11 @@ bool vgic_handle_cfg_reg(u32 *reg, struct kvm_exit_mmio *mmio,
>>>  void vgic_unqueue_irqs(struct kvm_vcpu *vcpu)
>>>  {
>>>  	struct vgic_cpu *vgic_cpu = &vcpu->arch.vgic_cpu;
>>> +	u64 elrsr = vgic_get_elrsr(vcpu);
>>> +	unsigned long *elrsr_ptr = u64_to_bitmask(&elrsr);
>>>  	int i;
>>>  
>>> -	for_each_set_bit(i, vgic_cpu->lr_used, vgic_cpu->nr_lr) {
>>> +	for_each_clear_bit(i, elrsr_ptr, vgic_cpu->nr_lr) {
>>>  		struct vgic_lr lr = vgic_get_lr(vcpu, i);
>>>  
>>>  		/*
>>> @@ -703,7 +715,7 @@ void vgic_unqueue_irqs(struct kvm_vcpu *vcpu)
>>>  		 * Mark the LR as free for other use.
>>>  		 */
>>>  		BUG_ON(lr.state & LR_STATE_MASK);
>>> -		vgic_retire_lr(i, lr.irq, vcpu);
>>> +		vgic_sync_lr_elrsr(vcpu, i, lr);
>>>  		vgic_irq_clear_queued(vcpu, lr.irq);
>>>  
>>>  		/* Finally update the VGIC state. */
>>> @@ -1011,17 +1023,6 @@ static void vgic_set_lr(struct kvm_vcpu *vcpu, int lr,
>>>  	vgic_ops->set_lr(vcpu, lr, vlr);
>>>  }
>>>  
>>> -static void vgic_sync_lr_elrsr(struct kvm_vcpu *vcpu, int lr,
>>> -			       struct vgic_lr vlr)
>>> -{
>>> -	vgic_ops->sync_lr_elrsr(vcpu, lr, vlr);
>>> -}
>>> -
>>> -static inline u64 vgic_get_elrsr(struct kvm_vcpu *vcpu)
>>> -{
>>> -	return vgic_ops->get_elrsr(vcpu);
>>> -}
>>> -
>>>  static inline u64 vgic_get_eisr(struct kvm_vcpu *vcpu)
>>>  {
>>>  	return vgic_ops->get_eisr(vcpu);
>>> @@ -1062,18 +1063,6 @@ static inline void vgic_enable(struct kvm_vcpu *vcpu)
>>>  	vgic_ops->enable(vcpu);
>>>  }
>>>  
>>> -static void vgic_retire_lr(int lr_nr, int irq, struct kvm_vcpu *vcpu)
>>> -{
>>> -	struct vgic_cpu *vgic_cpu = &vcpu->arch.vgic_cpu;
>>> -	struct vgic_lr vlr = vgic_get_lr(vcpu, lr_nr);
>>> -
>>> -	vlr.state = 0;
>>> -	vgic_set_lr(vcpu, lr_nr, vlr);
>>> -	clear_bit(lr_nr, vgic_cpu->lr_used);
>>> -	vgic_cpu->vgic_irq_lr_map[irq] = LR_EMPTY;
>>> -	vgic_sync_lr_elrsr(vcpu, lr_nr, vlr);
>>> -}
>>> -
>>>  /*
>>>   * An interrupt may have been disabled after being made pending on the
>>>   * CPU interface (the classic case is a timer running while we're
>>> @@ -1085,23 +1074,32 @@ static void vgic_retire_lr(int lr_nr, int irq, struct kvm_vcpu *vcpu)
>>>   */
>>>  static void vgic_retire_disabled_irqs(struct kvm_vcpu *vcpu)
>>>  {
>>> -	struct vgic_cpu *vgic_cpu = &vcpu->arch.vgic_cpu;
>>> +	u64 elrsr = vgic_get_elrsr(vcpu);
>>> +	unsigned long *elrsr_ptr = u64_to_bitmask(&elrsr);
>> if you agree with above modif I would simply rename elrsr_ptr into elrsr.
>>>  	int lr;
>>> +	struct vgic_lr vlr;
>> why moving this declaration here. I think this can remain in the block.
> 
> Possibly. Don't remember the reason of this move, I think it was due to
> some other changes I later removed. I will revert it.
> 
>>>  
>>> -	for_each_set_bit(lr, vgic_cpu->lr_used, vgic->nr_lr) {
>>> -		struct vgic_lr vlr = vgic_get_lr(vcpu, lr);
>>> +	for_each_clear_bit(lr, elrsr_ptr, vgic->nr_lr) {
>>> +		vlr = vgic_get_lr(vcpu, lr);
>>>  
>>>  		if (!vgic_irq_is_enabled(vcpu, vlr.irq)) {
>>> -			vgic_retire_lr(lr, vlr.irq, vcpu);
>>> -			if (vgic_irq_is_queued(vcpu, vlr.irq))
>>> -				vgic_irq_clear_queued(vcpu, vlr.irq);
>>> +			vlr.state = 0;
>>> +			vgic_set_lr(vcpu, lr, vlr);
>>> +			vgic_sync_lr_elrsr(vcpu, lr, vlr);
>> vgic_set_elrsr?
>>
>> the "if (vgic_irq_is_queued(vcpu, vlr.irq))" check disappeared. This
>> change might be introduced separately.
> 
> OK, this is an admittedly independent optimization to avoid the needless
> check for "clear only set bits". I didn't find it useful to spin a
> separate patch for this, so just fixed this while reworking this code
> anyway.
OK
> 
>>> +			vgic_irq_clear_queued(vcpu, vlr.irq);
>>>  		}
>>>  	}
>>>  }
>>>  
>>>  static void vgic_queue_irq_to_lr(struct kvm_vcpu *vcpu, int irq,
>>> -				 int lr_nr, struct vgic_lr vlr)
>> I don't think this change of proto is compatible with Marc's "KVM:
>> arm/arm64: vgic: Allow HW interrupts to be queued to a guest".
>> I think we need to keep former signature.
> 
> I will need to rebase my series on top of the 4.3 pull request anyway,
> so: yes, I will adapt to Marc's series.
> 
>>> +				 int lr_nr, int sgi_source_id)
>>>  {
>>> +	struct vgic_lr vlr;
>>> +
>>> +	vlr.state = 0;
>>> +	vlr.irq = irq;
>>> +	vlr.source = sgi_source_id;
>>> +
>>>  	if (vgic_irq_is_active(vcpu, irq)) {
>>>  		vlr.state |= LR_STATE_ACTIVE;
>>>  		kvm_debug("Set active, clear distributor: 0x%x\n", vlr.state);
>>> @@ -1126,9 +1124,9 @@ static void vgic_queue_irq_to_lr(struct kvm_vcpu *vcpu, int irq,
>>>   */
>>>  bool vgic_queue_irq(struct kvm_vcpu *vcpu, u8 sgi_source_id, int irq)
>>>  {
>>> -	struct vgic_cpu *vgic_cpu = &vcpu->arch.vgic_cpu;
>>>  	struct vgic_dist *dist = &vcpu->kvm->arch.vgic;
>>> -	struct vgic_lr vlr;
>>> +	u64 elrsr = vgic_get_elrsr(vcpu);
>>> +	unsigned long *elrsr_ptr = u64_to_bitmask(&elrsr);
>>>  	int lr;
>>>  
>>>  	/* Sanitize the input... */
>>> @@ -1138,42 +1136,20 @@ bool vgic_queue_irq(struct kvm_vcpu *vcpu, u8 sgi_source_id, int irq)
>>>  
>>>  	kvm_debug("Queue IRQ%d\n", irq);
>>>  
>>> -	lr = vgic_cpu->vgic_irq_lr_map[irq];
>>> -
>>> -	/* Do we have an active interrupt for the same CPUID? */
>>> -	if (lr != LR_EMPTY) {
>>> -		vlr = vgic_get_lr(vcpu, lr);
>>> -		if (vlr.source == sgi_source_id) {
>>> -			kvm_debug("LR%d piggyback for IRQ%d\n", lr, vlr.irq);
>>> -			BUG_ON(!test_bit(lr, vgic_cpu->lr_used));
>>> -			vgic_queue_irq_to_lr(vcpu, irq, lr, vlr);
>>> -			return true;
>>> -		}
>>> -	}
>>> +	lr = find_first_bit(elrsr_ptr, vgic->nr_lr);
>>>  
>>> -	/* Try to use another LR for this interrupt */
>>> -	lr = find_first_zero_bit((unsigned long *)vgic_cpu->lr_used,
>>> -			       vgic->nr_lr);
>>>  	if (lr >= vgic->nr_lr)
>>>  		return false;
>>>  
>>>  	kvm_debug("LR%d allocated for IRQ%d %x\n", lr, irq, sgi_source_id);
>>> -	vgic_cpu->vgic_irq_lr_map[irq] = lr;
>>> -	set_bit(lr, vgic_cpu->lr_used);
>>>  
>>> -	vlr.irq = irq;
>>> -	vlr.source = sgi_source_id;
>>> -	vlr.state = 0;
>>> -	vgic_queue_irq_to_lr(vcpu, irq, lr, vlr);
>>> +	vgic_queue_irq_to_lr(vcpu, irq, lr, sgi_source_id);
>>>  
>>>  	return true;
>>>  }
>>>  
>>>  static bool vgic_queue_hwirq(struct kvm_vcpu *vcpu, int irq)
>>>  {
>>> -	if (!vgic_can_sample_irq(vcpu, irq))
>>> -		return true; /* level interrupt, already queued */
>>> -
>> I think that change needs to be introduced in a separate patch as the
>> other one mentioned above and justified since it affects the state machine.
> 
> But this change is dependent on this patch: it will not work without
> this patch and this patch will not work without that change.
> So the idea is that on returning from the guest we now harvest all
> _used_ LRs by copying their state back into the distributor. The
> previous behaviour was to just check _unused_ LRs for completed IRQs.
> So now all IRQs need to be re-inserted into the LRs before the next
> guest run, that's why we have to remove the test which skipped this for
> IRQs where the code knew that they were still in the LRs.
> Does that make sense?
In level sensitive case, what if the IRQ'LR state was active. LR was
kept intact. IRQ is queued. With previous code we wouldn't inject a new
IRQ. Here aren't we going to inject it?

In the sync when you move the IRQ from the LR reg to the state variable,
shouldn't you reset the queued state for level sensitive case? In such a
case I think you could keep that check.

Cheers

Eric
> 
> Cheers,
> Andre.
> 



From maxime.coquelin at st.com  Mon Aug 31 01:44:40 2015
From: maxime.coquelin at st.com (Maxime Coquelin)
Date: Mon, 31 Aug 2015 10:44:40 +0200
Subject: [PATCH 3/7] dmaengine: st_fdma: Add STMicroelectronics FDMA
 engine driver support
In-Reply-To: <1441008481.8272.10.camel@tiscali.nl>
References: <1436371888-27863-1-git-send-email-peter.griffin@linaro.org>
 <1436371888-27863-4-git-send-email-peter.griffin@linaro.org>
 <1436429872.20619.77.camel@tiscali.nl> <55E40715.1040204@st.com>
 <1441008481.8272.10.camel@tiscali.nl>
Message-ID: <55E413F8.6070307@st.com>



On 08/31/2015 10:08 AM, Paul Bolle wrote:
> Hi Maxime,
>
> On ma, 2015-08-31 at 09:49 +0200, Maxime Coquelin wrote:
>> On 07/09/2015 10:17 AM, Paul Bolle wrote:
>>>>> +static int __exit st_fdma_remove(struct platform_device *pdev)
>>>>> +{
>>>>> +	struct st_fdma_dev *fdev = platform_get_drvdata(pdev);
>>>>> +
>>>>> +	wait_for_completion(&fdev->fw_ack);
>>>>> +
>>>>> +	st_fdma_clk_disable(fdev);
>>>>> +
>>>>> +	return 0;
>>>>> +}
>>> Since this driver is built-in only this means st_fdma_remove() can
>>> never be used, right?
>> It's not because a driver is built-in only that it does not need a
>> remove callback.
>> An instance can be probed/removed any time via driver's bind/unbind
>> SysFS entries.
>> Am I missing something?
> (This discussion is moot because Peter already stated that a new version
> will be modular.)
>
> It follows from the __exit tag that st_fdma_remove() should never be
> part of the kernel image (in this version of the patch), doesn't it?
Yes, you are right.
The remove callback is relevant, but without the __exit tag.
>
> (I don't know what happens in this situation if an unbind sysfs entry is
> used to remove a driver. I've never tried that.)
>
>
Not checked whether the function is omitted when built-in, but in any 
case, I thnk remove callbacks should not be tagged with __exit.

Regards,
Maxime




From ard.biesheuvel at linaro.org  Mon Aug 31 01:46:59 2015
From: ard.biesheuvel at linaro.org (Ard Biesheuvel)
Date: Mon, 31 Aug 2015 10:46:59 +0200
Subject: [PATCH 9/9] arm/arm64: KVM: arch timer: Reset CNTV_CTL to 0
In-Reply-To: <1440942866-23802-10-git-send-email-christoffer.dall@linaro.org>
References: <1440942866-23802-1-git-send-email-christoffer.dall@linaro.org>
 <1440942866-23802-10-git-send-email-christoffer.dall@linaro.org>
Message-ID: <CAKv+Gu-4KKUUt7J==CPK6J79mWXLeMJFsG_fj85tYB2orzfrZg@mail.gmail.com>

On 30 August 2015 at 15:54, Christoffer Dall
<christoffer.dall at linaro.org> wrote:
> Provide a better quality of implementation and be architecture compliant
> on ARMv7 for the architected timer by resetting the CNTV_CTL to 0 on
> reset of the timer, and call kvm_timer_update_state(vcpu) at the same
> time, ensuring the timer output is not asserted after, for example, a
> PSCI system reset.
>
> This change alone fixes the UEFI reset issue reported by Laszlo back in
> February.
>

Do you have a link to that report? I can't quite remember the details ...

> Cc: Laszlo Ersek <lersek at redhat.com>
> Cc: Ard Biesheuvel <ard.biesheuvel at linaro.org>
> Cc: Drew Jones <drjones at redhat.com>
> Cc: Wei Huang <wei at redhat.com>
> Cc: Peter Maydell <peter.maydell at linaro.org>
> Signed-off-by: Christoffer Dall <christoffer.dall at linaro.org>
> ---
>  virt/kvm/arm/arch_timer.c | 9 +++++++++
>  1 file changed, 9 insertions(+)
>
> diff --git a/virt/kvm/arm/arch_timer.c b/virt/kvm/arm/arch_timer.c
> index 747302f..8a0fdfc 100644
> --- a/virt/kvm/arm/arch_timer.c
> +++ b/virt/kvm/arm/arch_timer.c
> @@ -255,6 +255,15 @@ int kvm_timer_vcpu_reset(struct kvm_vcpu *vcpu,
>         timer->irq.irq = irq->irq;
>
>         /*
> +        * The bits in CNTV_CTL are architecturally reset to UNKNOWN for ARMv8
> +        * and to 0 for ARMv7.  We provide an implementation that always
> +        * resets the timer to be disabled and unmasked and is compliant with
> +        * the ARMv7 architecture.
> +        */
> +       timer->cntv_ctl = 0;
> +       kvm_timer_update_state(vcpu);
> +
> +       /*
>          * Tell the VGIC that the virtual interrupt is tied to a
>          * physical interrupt. We do that once per VCPU.
>          */
> --
> 2.1.2.330.g565301e.dirty
>


From christoffer.dall at linaro.org  Mon Aug 31 01:57:52 2015
From: christoffer.dall at linaro.org (Christoffer Dall)
Date: Mon, 31 Aug 2015 10:57:52 +0200
Subject: [PATCH 9/9] arm/arm64: KVM: arch timer: Reset CNTV_CTL to 0
In-Reply-To: <CAKv+Gu-4KKUUt7J==CPK6J79mWXLeMJFsG_fj85tYB2orzfrZg@mail.gmail.com>
References: <1440942866-23802-1-git-send-email-christoffer.dall@linaro.org>
 <1440942866-23802-10-git-send-email-christoffer.dall@linaro.org>
 <CAKv+Gu-4KKUUt7J==CPK6J79mWXLeMJFsG_fj85tYB2orzfrZg@mail.gmail.com>
Message-ID: <20150831085752.GH24113@cbox>

On Mon, Aug 31, 2015 at 10:46:59AM +0200, Ard Biesheuvel wrote:
> On 30 August 2015 at 15:54, Christoffer Dall
> <christoffer.dall at linaro.org> wrote:
> > Provide a better quality of implementation and be architecture compliant
> > on ARMv7 for the architected timer by resetting the CNTV_CTL to 0 on
> > reset of the timer, and call kvm_timer_update_state(vcpu) at the same
> > time, ensuring the timer output is not asserted after, for example, a
> > PSCI system reset.
> >
> > This change alone fixes the UEFI reset issue reported by Laszlo back in
> > February.
> >
> 
> Do you have a link to that report? I can't quite remember the details ...
> 
There was no public mailing list cc'ed on the report, and the bugzilla
bug was created in a non-public Red Hat instance.

But you were cc'ed on the original mail from Laszlo.  Look for an e-mail
from February 5th with the subject "virtual timer interrupt stuck across
guest firmware reboot on KVM".

-Christoffer


From jianwei.wang.chn at gmail.com  Mon Aug 31 01:53:35 2015
From: jianwei.wang.chn at gmail.com (Jianwei Wang)
Date: Mon, 31 Aug 2015 16:53:35 +0800
Subject: [PATCH] drm/fsl-dcu: Add multi layers support
Message-ID: <1441011215-3769-1-git-send-email-jianwei.wang.chn@gmail.com>

For DCU support atmost 16 layers(on ls1021a) or 64 layers(on vf610),
add (total_layer - 1) overlay planes.

Signed-off-by: Jianwei Wang <jianwei.wang.chn at gmail.com>
---
 drivers/gpu/drm/fsl-dcu/fsl_dcu_drm_plane.c | 27 ++++++++++++++++++++++++++-
 1 file changed, 26 insertions(+), 1 deletion(-)

diff --git a/drivers/gpu/drm/fsl-dcu/fsl_dcu_drm_plane.c b/drivers/gpu/drm/fsl-dcu/fsl_dcu_drm_plane.c
index 8787920..1195568 100644
--- a/drivers/gpu/drm/fsl-dcu/fsl_dcu_drm_plane.c
+++ b/drivers/gpu/drm/fsl-dcu/fsl_dcu_drm_plane.c
@@ -236,7 +236,10 @@ static const u32 fsl_dcu_drm_plane_formats[] = {
 
 struct drm_plane *fsl_dcu_drm_primary_create_plane(struct drm_device *dev)
 {
+	struct fsl_dcu_drm_device *fsl_dev = dev->dev_private;
 	struct drm_plane *primary;
+	struct drm_plane *overlay;
+	unsigned int total_layer, formats_size, i;
 	int ret;
 
 	primary = kzalloc(sizeof(*primary), GFP_KERNEL);
@@ -245,11 +248,12 @@ struct drm_plane *fsl_dcu_drm_primary_create_plane(struct drm_device *dev)
 		return NULL;
 	}
 
+	formats_size = ARRAY_SIZE(fsl_dcu_drm_plane_formats);
 	/* possible_crtc's will be filled in later by crtc_init */
 	ret = drm_universal_plane_init(dev, primary, 0,
 				       &fsl_dcu_drm_plane_funcs,
 				       fsl_dcu_drm_plane_formats,
-				       ARRAY_SIZE(fsl_dcu_drm_plane_formats),
+				       formats_size,
 				       DRM_PLANE_TYPE_PRIMARY);
 	if (ret) {
 		kfree(primary);
@@ -257,5 +261,26 @@ struct drm_plane *fsl_dcu_drm_primary_create_plane(struct drm_device *dev)
 	}
 	drm_plane_helper_add(primary, &fsl_dcu_drm_plane_helper_funcs);
 
+	total_layer = fsl_dev->soc->total_layer;
+	for (i = 0; i < total_layer - 1; i++) {
+		overlay = kzalloc(sizeof(*overlay), GFP_KERNEL);
+		if (!overlay) {
+			DRM_DEBUG_KMS("Failed to allocate overlay plane\n");
+			goto out;
+		}
+
+		ret = drm_universal_plane_init(dev, overlay, 1,
+					       &fsl_dcu_drm_plane_funcs,
+					       fsl_dcu_drm_plane_formats,
+					       formats_size,
+					       DRM_PLANE_TYPE_OVERLAY);
+		if (ret) {
+			kfree(overlay);
+			goto out;
+		}
+		drm_plane_helper_add(overlay, &fsl_dcu_drm_plane_helper_funcs);
+	}
+
+out:
 	return primary;
 }
-- 
2.1.0.27.g96db324



From ard.biesheuvel at linaro.org  Mon Aug 31 02:02:53 2015
From: ard.biesheuvel at linaro.org (Ard Biesheuvel)
Date: Mon, 31 Aug 2015 11:02:53 +0200
Subject: [PATCH 9/9] arm/arm64: KVM: arch timer: Reset CNTV_CTL to 0
In-Reply-To: <20150831085752.GH24113@cbox>
References: <1440942866-23802-1-git-send-email-christoffer.dall@linaro.org>
 <1440942866-23802-10-git-send-email-christoffer.dall@linaro.org>
 <CAKv+Gu-4KKUUt7J==CPK6J79mWXLeMJFsG_fj85tYB2orzfrZg@mail.gmail.com>
 <20150831085752.GH24113@cbox>
Message-ID: <CAKv+Gu_f97gu+TftpdJDef4X89sjYB2udUybpmm=M113_TTiPw@mail.gmail.com>

On 31 August 2015 at 10:57, Christoffer Dall
<christoffer.dall at linaro.org> wrote:
> On Mon, Aug 31, 2015 at 10:46:59AM +0200, Ard Biesheuvel wrote:
>> On 30 August 2015 at 15:54, Christoffer Dall
>> <christoffer.dall at linaro.org> wrote:
>> > Provide a better quality of implementation and be architecture compliant
>> > on ARMv7 for the architected timer by resetting the CNTV_CTL to 0 on
>> > reset of the timer, and call kvm_timer_update_state(vcpu) at the same
>> > time, ensuring the timer output is not asserted after, for example, a
>> > PSCI system reset.
>> >
>> > This change alone fixes the UEFI reset issue reported by Laszlo back in
>> > February.
>> >
>>
>> Do you have a link to that report? I can't quite remember the details ...
>>
> There was no public mailing list cc'ed on the report, and the bugzilla
> bug was created in a non-public Red Hat instance.
>
> But you were cc'ed on the original mail from Laszlo.  Look for an e-mail
> from February 5th with the subject "virtual timer interrupt stuck across
> guest firmware reboot on KVM".
>

Found it, thanks.


From grygorii.strashko at ti.com  Mon Aug 31 02:03:42 2015
From: grygorii.strashko at ti.com (Grygorii Strashko)
Date: Mon, 31 Aug 2015 12:03:42 +0300
Subject: [PATCH] gpio: omap: Fix gpiochip_add() handling for deferred probe
In-Reply-To: <1440787489-15992-1-git-send-email-tony@atomide.com>
References: <1440787489-15992-1-git-send-email-tony@atomide.com>
Message-ID: <55E4186E.7090605@ti.com>

Hi Tony,

On 08/28/2015 09:44 PM, Tony Lindgren wrote:
> Currently we gpio-omap breaks if gpiochip_add() returns -EPROBE_DEFER:
>
> [    0.570000] gpiochip_add: GPIOs 0..31 (gpio) failed to register
> [    0.570000] omap_gpio 48310000.gpio: Could not register gpio chip -517
> ...
> [    3.670000] omap_gpio 48310000.gpio: Unbalanced pm_runtime_enable!

I have no objection to the patch itself.

But I curious, How have you got this error output? Was it simulated?

>
> Let's fix the issue by adding the missing pm_runtime_put() on error.
>
> Cc: Grygorii Strashko <grygorii.strashko at ti.com>
> Cc: Javier Martinez Canillas <javier at dowhile0.org>
> Cc: Kevin Hilman <khilman at deeprootsystems.com>
> Cc: Santosh Shilimkar <ssantosh at kernel.org>
> Signed-off-by: Tony Lindgren <tony at atomide.com>
> ---
>   drivers/gpio/gpio-omap.c | 5 ++++-
>   1 file changed, 4 insertions(+), 1 deletion(-)
>
> diff --git a/drivers/gpio/gpio-omap.c b/drivers/gpio/gpio-omap.c
> index b0c57d5..f09bf0b 100644
> --- a/drivers/gpio/gpio-omap.c
> +++ b/drivers/gpio/gpio-omap.c
> @@ -1232,8 +1232,11 @@ static int omap_gpio_probe(struct platform_device *pdev)
>   	omap_gpio_mod_init(bank);
>
>   	ret = omap_gpio_chip_init(bank, irqc);
> -	if (ret)
> +	if (ret) {
> +		pm_runtime_put_sync(bank->dev);
> +		pm_runtime_disable(bank->dev);
>   		return ret;
> +	}
>
>   	omap_gpio_show_rev(bank);
>
>


-- 
regards,
-grygorii


From p.zabel at pengutronix.de  Mon Aug 31 02:22:43 2015
From: p.zabel at pengutronix.de (Philipp Zabel)
Date: Mon, 31 Aug 2015 11:22:43 +0200
Subject: [PATCH v3 2/2] drm: bridge/dw_hdmi: add dw hdmi i2c bus adapter
 support
In-Reply-To: <1440970470-7155-1-git-send-email-vladimir_zapolskiy@mentor.com>
References: <1440970470-7155-1-git-send-email-vladimir_zapolskiy@mentor.com>
Message-ID: <1441012963.3234.28.camel@pengutronix.de>

Hi Vladimir,

Am Montag, den 31.08.2015, 00:34 +0300 schrieb Vladimir Zapolskiy:
> The change adds support of internal HDMI I2C master controller, this
> subdevice is used by default, if "ddc-i2c-bus" DT property is omitted.

I think this should be mentioned in
Documentation/devicetree/bindings/drm/bridge/dw_hdmi.txt

> The main purpose of this functionality is to support reading EDID from
> an HDMI monitor on boards, which don't have an I2C bus connected to
> DDC pins.
> 
> The current implementation does not support "I2C Master Interface
> Extended Read Mode" to read data addressed by non-zero segment
> pointer, this means that if EDID has more than 1 extension blocks,
> EDID reading operation won't succeed, in my practice all tested HDMI
> monitors have at maximum one extension block.
> 
> Signed-off-by: Vladimir Zapolskiy <vladimir_zapolskiy at mentor.com>
> ---
> The change is based on today's v4.2, please let me know, if it should be rebased.
> 
> The change has compilation dependency on I2CM_ADDRESS register name fix,
> see http://lists.freedesktop.org/archives/dri-devel/2015-May/082980.html
> 
> From http://lists.freedesktop.org/archives/dri-devel/2015-May/082981.html
> v1 of the change was
> 
>   Tested-by: Philipp Zabel <p.zabel at pengutronix.de>
> 
> but I hesitate to add the tag here due to multiple updates in v2.

Tested again, v2 still works fine on Nitrogen6X with HDMI monitor.

regards
Philipp



From eric.auger at linaro.org  Mon Aug 31 02:31:37 2015
From: eric.auger at linaro.org (Eric Auger)
Date: Mon, 31 Aug 2015 11:31:37 +0200
Subject: [PATCH v2 05/15] KVM: arm/arm64: make GIC frame address
 initialization model specific
In-Reply-To: <55DB534C.8040207@arm.com>
References: <1436538111-4294-1-git-send-email-andre.przywara@arm.com>
 <1436538111-4294-6-git-send-email-andre.przywara@arm.com>
 <55CB43FB.4070400@linaro.org> <55DB534C.8040207@arm.com>
Message-ID: <55E41EF9.6020901@linaro.org>

On 08/24/2015 07:24 PM, Andre Przywara wrote:
> Hi,
> 
> On 12/08/15 14:02, Eric Auger wrote:
>> On 07/10/2015 04:21 PM, Andre Przywara wrote:
>>> Currently we initialize all the possible GIC frame addresses in one
>>> function, without looking at the specific GIC model we instantiate
>>> for the guest.
>>> As this gets confusing when adding another VGIC model later, lets
>>> move these initializations into the respective model's init 
>> nit: tobe more precise the init emulation function (not the
>> vgic_v2/v3_init_model model's init function). pfouh?! ;-)
>> functions.
> 
> OK, will try to find a wording that is not completely confusing.
> 
>>>
>>> Signed-off-by: Andre Przywara <andre.przywara at arm.com>
>>> ---
>>>  virt/kvm/arm/vgic-v2-emul.c | 3 +++
>>>  virt/kvm/arm/vgic-v3-emul.c | 3 +++
>>>  virt/kvm/arm/vgic.c         | 3 ---
>>>  3 files changed, 6 insertions(+), 3 deletions(-)
>>>
>>> diff --git a/virt/kvm/arm/vgic-v2-emul.c b/virt/kvm/arm/vgic-v2-emul.c
>>> index 1390797..8faa28c 100644
>>> --- a/virt/kvm/arm/vgic-v2-emul.c
>>> +++ b/virt/kvm/arm/vgic-v2-emul.c
>>> @@ -567,6 +567,9 @@ void vgic_v2_init_emulation(struct kvm *kvm)
>>>  	dist->vm_ops.init_model = vgic_v2_init_model;
>>>  	dist->vm_ops.map_resources = vgic_v2_map_resources;
>>>  
>>> +	dist->vgic_cpu_base = VGIC_ADDR_UNDEF;
>>> +	dist->vgic_dist_base = VGIC_ADDR_UNDEF;
>> Looks strange to see the common dist_base here. Why don't you leave it
>> in common part, kvm_vgic_create; all the more so you left
>> kvm->arch.vgic.vctrl_base = vgic->vctrl_base in kvm_vgic_create.
> 
> The idea behind this is that dist_base refers to similar, but not
> identical distributors (v2 vs. v3), so I found it a good idea to
> initialize it in here. Also vctrl_base is host facing and not set by
> userland, so this doesn't really compare here.
ok

Eric
> 
> Cheers,
> Andre.
> 
>>> +
>>>  	kvm->arch.max_vcpus = VGIC_V2_MAX_CPUS;
>>>  }
>>>  
>>> diff --git a/virt/kvm/arm/vgic-v3-emul.c b/virt/kvm/arm/vgic-v3-emul.c
>>> index d2eeb20..1f42348 100644
>>> --- a/virt/kvm/arm/vgic-v3-emul.c
>>> +++ b/virt/kvm/arm/vgic-v3-emul.c
>>> @@ -885,6 +885,9 @@ void vgic_v3_init_emulation(struct kvm *kvm)
>>>  	dist->vm_ops.destroy_model = vgic_v3_destroy_model;
>>>  	dist->vm_ops.map_resources = vgic_v3_map_resources;
>>>  
>>> +	dist->vgic_dist_base = VGIC_ADDR_UNDEF;
>>> +	dist->vgic_redist_base = VGIC_ADDR_UNDEF;
>>> +
>>>  	kvm->arch.max_vcpus = KVM_MAX_VCPUS;
>>>  }
>>>  
>>> diff --git a/virt/kvm/arm/vgic.c b/virt/kvm/arm/vgic.c
>>> index cc8f5ed..59f1801 100644
>>> --- a/virt/kvm/arm/vgic.c
>>> +++ b/virt/kvm/arm/vgic.c
>>> @@ -1830,9 +1830,6 @@ int kvm_vgic_create(struct kvm *kvm, u32 type)
>>>  	kvm->arch.vgic.in_kernel = true;
>>>  	kvm->arch.vgic.vgic_model = type;
>>>  	kvm->arch.vgic.vctrl_base = vgic->vctrl_base;
>>> -	kvm->arch.vgic.vgic_dist_base = VGIC_ADDR_UNDEF;
>>> -	kvm->arch.vgic.vgic_cpu_base = VGIC_ADDR_UNDEF;
>>> -	kvm->arch.vgic.vgic_redist_base = VGIC_ADDR_UNDEF;
>>>  
>>>  out_unlock:
>>>  	for (; vcpu_lock_idx >= 0; vcpu_lock_idx--) {
>>>
>>



From eric.auger at linaro.org  Mon Aug 31 02:45:24 2015
From: eric.auger at linaro.org (Eric Auger)
Date: Mon, 31 Aug 2015 11:45:24 +0200
Subject: [PATCH v2 11/15] KVM: arm64: handle pending bit for LPIs in ITS
 emulation
In-Reply-To: <55DC7CDE.3020409@arm.com>
References: <1436538111-4294-1-git-send-email-andre.przywara@arm.com>
 <1436538111-4294-12-git-send-email-andre.przywara@arm.com>
 <55CDD7ED.90008@linaro.org> <55DC7CDE.3020409@arm.com>
Message-ID: <55E42234.1010700@linaro.org>

On 08/25/2015 04:34 PM, Andre Przywara wrote:
> Hi Eric,
> 
> On 14/08/15 12:58, Eric Auger wrote:
>> On 07/10/2015 04:21 PM, Andre Przywara wrote:
>>> As the actual LPI number in a guest can be quite high, but is mostly
>>> assigned using a very sparse allocation scheme, bitmaps and arrays
>>> for storing the virtual interrupt status are a waste of memory.
>>> We use our equivalent of the "Interrupt Translation Table Entry"
>>> (ITTE) to hold this extra status information for a virtual LPI.
>>> As the normal VGIC code cannot use it's fancy bitmaps to manage
>>> pending interrupts, we provide a hook in the VGIC code to let the
>>> ITS emulation handle the list register queueing itself.
>>> LPIs are located in a separate number range (>=8192), so
>>> distinguishing them is easy. With LPIs being only edge-triggered, we
>>> get away with a less complex IRQ handling.
>>>
>>> Signed-off-by: Andre Przywara <andre.przywara at arm.com>
>>> ---
>>>  include/kvm/arm_vgic.h      |  2 ++
>>>  virt/kvm/arm/its-emul.c     | 71 ++++++++++++++++++++++++++++++++++++++++++++
>>>  virt/kvm/arm/its-emul.h     |  3 ++
>>>  virt/kvm/arm/vgic-v3-emul.c |  2 ++
>>>  virt/kvm/arm/vgic.c         | 72 ++++++++++++++++++++++++++++++++++-----------
>>>  5 files changed, 133 insertions(+), 17 deletions(-)
>>>
>>> diff --git a/include/kvm/arm_vgic.h b/include/kvm/arm_vgic.h
>>> index 1648668..2a67a10 100644
>>> --- a/include/kvm/arm_vgic.h
>>> +++ b/include/kvm/arm_vgic.h
>>> @@ -147,6 +147,8 @@ struct vgic_vm_ops {
>>>       int     (*init_model)(struct kvm *);
>>>       void    (*destroy_model)(struct kvm *);
>>>       int     (*map_resources)(struct kvm *, const struct vgic_params *);
>>> +     bool    (*queue_lpis)(struct kvm_vcpu *);
>>> +     void    (*unqueue_lpi)(struct kvm_vcpu *, int irq);
>>>  };
>>>
>>>  struct vgic_io_device {
>>> diff --git a/virt/kvm/arm/its-emul.c b/virt/kvm/arm/its-emul.c
>>> index 7f217fa..b9c40d7 100644
>>> --- a/virt/kvm/arm/its-emul.c
>>> +++ b/virt/kvm/arm/its-emul.c
>>> @@ -50,8 +50,26 @@ struct its_itte {
>>>       struct its_collection *collection;
>>>       u32 lpi;
>>>       u32 event_id;
>>> +     bool enabled;
>>> +     unsigned long *pending;
>>>  };
>>>
>>> +#define for_each_lpi(dev, itte, kvm) \
>>> +     list_for_each_entry(dev, &(kvm)->arch.vgic.its.device_list, dev_list) \
>>> +             list_for_each_entry(itte, &(dev)->itt, itte_list)
>>> +
>> You have a checkpatch error here:
>>
>> ERROR: Macros with complex values should be enclosed in parentheses
>> #52: FILE: virt/kvm/arm/its-emul.c:57:
>> +#define for_each_lpi(dev, itte, kvm) \
>> +       list_for_each_entry(dev, &(kvm)->arch.vgic.its.device_list, dev_list) \
>> +               list_for_each_entry(itte, &(dev)->itt, itte_list)
> 
> I know about that one. The problem is that if I add the parentheses it
> breaks the usage below due to the curly brackets. But the definition
> above is just so convenient and I couldn't find another neat solution so
> far. If you are concerned about that I can give it another try,
> otherwise I tend to just ignore checkpatch here.
OK maybe you can add a comment then?
> 
>>> +static struct its_itte *find_itte_by_lpi(struct kvm *kvm, int lpi)
>>> +{
>> can't we have the same LPI present in different interrupt translation
>> tables? I don't know it is a sensible setting but I did not succeed in
>> finding it was not possible.
> 
> Thanks to Marc I am happy (and relieved!) to point you to 6.1.1 LPI INTIDs:
> "The behavior of the GIC is UNPREDICTABLE if software:
> - Maps multiple EventID/DeviceID combinations to the same physical LPI
> INTID."
> 
> So I exercise the freedom of UNPREDICTABLE here ;-)

OK
> 
>>> +     struct its_device *device;
>>> +     struct its_itte *itte;
>>> +
>>> +     for_each_lpi(device, itte, kvm) {
>>> +             if (itte->lpi == lpi)
>>> +                     return itte;
>>> +     }
>>> +     return NULL;
>>> +}
>>> +
>>>  #define BASER_BASE_ADDRESS(x) ((x) & 0xfffffffff000ULL)
>>>
>>>  /* The distributor lock is held by the VGIC MMIO handler. */
>>> @@ -145,6 +163,59 @@ static bool handle_mmio_gits_idregs(struct kvm_vcpu *vcpu,
>>>       return false;
>>>  }
>>>
>>> +/*
>>> + * Find all enabled and pending LPIs and queue them into the list
>>> + * registers.
>>> + * The dist lock is held by the caller.
>>> + */
>>> +bool vits_queue_lpis(struct kvm_vcpu *vcpu)
>>> +{
>>> +     struct vgic_its *its = &vcpu->kvm->arch.vgic.its;
>>> +     struct its_device *device;
>>> +     struct its_itte *itte;
>>> +     bool ret = true;
>>> +
>>> +     if (!vgic_has_its(vcpu->kvm))
>>> +             return true;
>>> +     if (!its->enabled || !vcpu->kvm->arch.vgic.lpis_enabled)
>>> +             return true;
>>> +
>>> +     spin_lock(&its->lock);
>>> +     for_each_lpi(device, itte, vcpu->kvm) {
>>> +             if (!itte->enabled || !test_bit(vcpu->vcpu_id, itte->pending))
>>> +                     continue;
>>> +
>>> +             if (!itte->collection)
>>> +                     continue;
>>> +
>>> +             if (itte->collection->target_addr != vcpu->vcpu_id)
>>> +                     continue;
>>> +
>>> +             __clear_bit(vcpu->vcpu_id, itte->pending);
>>> +
>>> +             ret &= vgic_queue_irq(vcpu, 0, itte->lpi);
>> what if the vgic_queue_irq fails since no LR can be found, the
>> itte->pending was cleared so we forget that LPI? shouldn't we restore
>> the pending state in ITT? in vgic_queue_hwirq the state change only is
>> performed if the vgic_queue_irq succeeds
> 
> Of course you are right. I will just only clear the bit if the call
> succeeds.
> 
>>> +     }
>>> +
>>> +     spin_unlock(&its->lock);
>>> +     return ret;
>>> +}
>>> +
>>> +/* Called with the distributor lock held by the caller. */
>>> +void vits_unqueue_lpi(struct kvm_vcpu *vcpu, int lpi)
>> I was a bit confused by the name of the function, with regard to
>> existing vgic_unqueue_irqs which restores the states in accordance to
>> what we have in LR. Wouldn't it make sense to call it
>> vits_lpi_set_pending(vcpu, lpi) or something that looks more similar to
>> vgic_dist_irq_set_pending setter which I think it mirrors.
> 
> Well, vgic_unqueue_irqs() "move[s] pending/active IRQs from LRs to the
> distributor", this is what vits_unqueue_lpi() also does, just for one
> _single_ LPI instead of iterating over all LRs. Originally I planned to
> call vgic_unqueue_irqs on every guest exit, so this would have a more
> obvious match.
> Admittedly the function does not do much "unqueueing", as this is done
> in the caller, so I will think about the renaming part.
> 
>>> +{
>>> +     struct vgic_its *its = &vcpu->kvm->arch.vgic.its;
>>> +     struct its_itte *itte;
>>> +
>>> +     spin_lock(&its->lock);
>>> +
>>> +     /* Find the right ITTE and put the pending state back in there */
>>> +     itte = find_itte_by_lpi(vcpu->kvm, lpi);
>>> +     if (itte)
>>> +             __set_bit(vcpu->vcpu_id, itte->pending);
>>> +
>>> +     spin_unlock(&its->lock);
>>> +}
>>> +
>>>  static int vits_handle_command(struct kvm_vcpu *vcpu, u64 *its_cmd)
>>>  {
>>>       return -ENODEV;
>>> diff --git a/virt/kvm/arm/its-emul.h b/virt/kvm/arm/its-emul.h
>>> index 472a6d0..cc5d5ff 100644
>>> --- a/virt/kvm/arm/its-emul.h
>>> +++ b/virt/kvm/arm/its-emul.h
>>> @@ -33,4 +33,7 @@ void vgic_enable_lpis(struct kvm_vcpu *vcpu);
>>>  int vits_init(struct kvm *kvm);
>>>  void vits_destroy(struct kvm *kvm);
>>>
>>> +bool vits_queue_lpis(struct kvm_vcpu *vcpu);
>>> +void vits_unqueue_lpi(struct kvm_vcpu *vcpu, int irq);
>>> +
>>>  #endif
>>> diff --git a/virt/kvm/arm/vgic-v3-emul.c b/virt/kvm/arm/vgic-v3-emul.c
>>> index 49be3c3..4132c26 100644
>>> --- a/virt/kvm/arm/vgic-v3-emul.c
>>> +++ b/virt/kvm/arm/vgic-v3-emul.c
>>> @@ -948,6 +948,8 @@ void vgic_v3_init_emulation(struct kvm *kvm)
>>>       dist->vm_ops.init_model = vgic_v3_init_model;
>>>       dist->vm_ops.destroy_model = vgic_v3_destroy_model;
>>>       dist->vm_ops.map_resources = vgic_v3_map_resources;
>>> +     dist->vm_ops.queue_lpis = vits_queue_lpis;
>>> +     dist->vm_ops.unqueue_lpi = vits_unqueue_lpi;
>>>
>>>       dist->vgic_dist_base = VGIC_ADDR_UNDEF;
>>>       dist->vgic_redist_base = VGIC_ADDR_UNDEF;
>>> diff --git a/virt/kvm/arm/vgic.c b/virt/kvm/arm/vgic.c
>>> index 49ee92b..9dfd094 100644
>>> --- a/virt/kvm/arm/vgic.c
>>> +++ b/virt/kvm/arm/vgic.c
>>> @@ -95,6 +95,20 @@ static bool queue_sgi(struct kvm_vcpu *vcpu, int irq)
>>>       return vcpu->kvm->arch.vgic.vm_ops.queue_sgi(vcpu, irq);
>>>  }
>>>
>>> +static bool vgic_queue_lpis(struct kvm_vcpu *vcpu)
>>> +{
>>> +     if (vcpu->kvm->arch.vgic.vm_ops.queue_lpis)
>>> +             return vcpu->kvm->arch.vgic.vm_ops.queue_lpis(vcpu);
>>> +     else
>>> +             return true;
>>> +}
>>> +
>>> +static void vgic_unqueue_lpi(struct kvm_vcpu *vcpu, int irq)
>>> +{
>>> +     if (vcpu->kvm->arch.vgic.vm_ops.unqueue_lpi)
>>> +             vcpu->kvm->arch.vgic.vm_ops.unqueue_lpi(vcpu, irq);
>>> +}
>>> +
>>>  int kvm_vgic_map_resources(struct kvm *kvm)
>>>  {
>>>       return kvm->arch.vgic.vm_ops.map_resources(kvm, vgic);
>>> @@ -1135,6 +1149,10 @@ static void vgic_retire_disabled_irqs(struct kvm_vcpu *vcpu)
>>>       for_each_clear_bit(lr, elrsr_ptr, vgic->nr_lr) {
>>>               vlr = vgic_get_lr(vcpu, lr);
>>>
>>> +             /* We don't care about LPIs here */
>>> +             if (vlr.irq >= 8192)
>>> +                     continue;
>>> +
>>>               if (!vgic_irq_is_enabled(vcpu, vlr.irq)) {
>>>                       vlr.state = 0;
>>>                       vgic_set_lr(vcpu, lr, vlr);
>>> @@ -1147,25 +1165,33 @@ static void vgic_retire_disabled_irqs(struct kvm_vcpu *vcpu)
>>>  static void vgic_queue_irq_to_lr(struct kvm_vcpu *vcpu, int irq,
>>>                                int lr_nr, int sgi_source_id)
>>>  {
>>> +     struct vgic_dist *dist = &vcpu->kvm->arch.vgic;
>>>       struct vgic_lr vlr;
>>>
>>>       vlr.state = 0;
>>>       vlr.irq = irq;
>>>       vlr.source = sgi_source_id;
>>>
>>> -     if (vgic_irq_is_active(vcpu, irq)) {
>>> -             vlr.state |= LR_STATE_ACTIVE;
>>> -             kvm_debug("Set active, clear distributor: 0x%x\n", vlr.state);
>>> -             vgic_irq_clear_active(vcpu, irq);
>>> -             vgic_update_state(vcpu->kvm);
>>> -     } else if (vgic_dist_irq_is_pending(vcpu, irq)) {
>>> -             vlr.state |= LR_STATE_PENDING;
>>> -             kvm_debug("Set pending: 0x%x\n", vlr.state);
>>> -     }
>>> -
>>> -     if (!vgic_irq_is_edge(vcpu, irq))
>>> -             vlr.state |= LR_EOI_INT;
>>> +     /* We care only about state for SGIs/PPIs/SPIs, not for LPIs */
>>> +     if (irq < dist->nr_irqs) {
>>> +             if (vgic_irq_is_active(vcpu, irq)) {
>>> +                     vlr.state |= LR_STATE_ACTIVE;
>>> +                     kvm_debug("Set active, clear distributor: 0x%x\n",
>>> +                               vlr.state);
>>> +                     vgic_irq_clear_active(vcpu, irq);
>>> +                     vgic_update_state(vcpu->kvm);
>>> +             } else if (vgic_dist_irq_is_pending(vcpu, irq)) {
>>> +                     vlr.state |= LR_STATE_PENDING;
>>> +                     kvm_debug("Set pending: 0x%x\n", vlr.state);
>>> +             }
>>>
>>> +             if (!vgic_irq_is_edge(vcpu, irq))
>>> +                     vlr.state |= LR_EOI_INT;
>>> +     } else {
>>> +             /* If this is an LPI, it can only be pending */
>>> +             if (irq >= 8192)
>>> +                     vlr.state |= LR_STATE_PENDING;
>>> +     }
>>>       vgic_set_lr(vcpu, lr_nr, vlr);
>>>       vgic_sync_lr_elrsr(vcpu, lr_nr, vlr);
>>>  }
>>> @@ -1177,7 +1203,6 @@ static void vgic_queue_irq_to_lr(struct kvm_vcpu *vcpu, int irq,
>>>   */
>>>  bool vgic_queue_irq(struct kvm_vcpu *vcpu, u8 sgi_source_id, int irq)
>>>  {
>>> -     struct vgic_dist *dist = &vcpu->kvm->arch.vgic;
>>>       u64 elrsr = vgic_get_elrsr(vcpu);
>>>       unsigned long *elrsr_ptr = u64_to_bitmask(&elrsr);
>>>       int lr;
>>> @@ -1185,7 +1210,6 @@ bool vgic_queue_irq(struct kvm_vcpu *vcpu, u8 sgi_source_id, int irq)
>>>       /* Sanitize the input... */
>>>       BUG_ON(sgi_source_id & ~7);
>>>       BUG_ON(sgi_source_id && irq >= VGIC_NR_SGIS);
>>> -     BUG_ON(irq >= dist->nr_irqs);
>> Is it safe to remove that check. What if it is attempted to inject an
>> SPI larger than supported. I think you should refine the check but not
>> remove it.
> 
> The check is now in vgic_queue_irq_to_lr (see above), where we
> differentiate between LPIs (>=8192) and SPIs (<dist->nr_irqs). Please
> correct me if I am wrong on this, but since we are not setting any state
> bits the vgic_set_lr() and vgic_sync_lr_elrsr() calls should be NOPs in
> this case, right?
Looks OK indeed.

Cheers

Eric
> I may re-add the explicit check here for the sake of clarity, though.
> 
>>>
>>>       kvm_debug("Queue IRQ%d\n", irq);
>>>
>>> @@ -1265,8 +1289,12 @@ static void __kvm_vgic_flush_hwstate(struct kvm_vcpu *vcpu)
>>>                       overflow = 1;
>>>       }
>>>
>>> -
>>> -
>>> +     /*
>>> +      * LPIs are not mapped in our bitmaps, so we leave the iteration
>>> +      * to the ITS emulation code.
>>> +      */
>>> +     if (!vgic_queue_lpis(vcpu))
>>> +             overflow = 1;
>>>
>>>  epilog:
>>>       if (overflow) {
>>> @@ -1387,6 +1415,16 @@ static void __kvm_vgic_sync_hwstate(struct kvm_vcpu *vcpu)
>>>       for_each_clear_bit(lr_nr, elrsr_ptr, vgic_cpu->nr_lr) {
>>>               vlr = vgic_get_lr(vcpu, lr_nr);
>>>
>>> +             /* LPIs are handled separately */
>>> +             if (vlr.irq >= 8192) {
>>> +                     /* We just need to take care about still pending LPIs */
>>> +                     if (vlr.state & LR_STATE_PENDING) {
>>> +                             vgic_unqueue_lpi(vcpu, vlr.irq);
>>> +                             pending = true;
>>> +                     }
>>> +                     continue;
>> don't we need to reset the LR & update elrsr?
> 
> Mmmh, interesting, I just wonder how it worked before. I will move most
> of the lower part into an else clause and call the LR maintainance code
> in both cases.
> 
> Cheers,
> Andre.
> 
>>> +             }
>>> +
>>>               BUG_ON(!(vlr.state & LR_STATE_MASK));
>>>               pending = true;
>>>
>>> @@ -1411,7 +1449,7 @@ static void __kvm_vgic_sync_hwstate(struct kvm_vcpu *vcpu)
>>>       }
>>>       vgic_update_state(vcpu->kvm);
>>>
>>> -     /* vgic_update_state would not cover only-active IRQs */
>>> +     /* vgic_update_state would not cover only-active IRQs or LPIs */
>>>       if (pending)
>>>               set_bit(vcpu->vcpu_id, dist->irq_pending_on_cpu);
>>>  }
>>>
>>



From eric.auger at linaro.org  Mon Aug 31 02:47:55 2015
From: eric.auger at linaro.org (Eric Auger)
Date: Mon, 31 Aug 2015 11:47:55 +0200
Subject: [PATCH v2 12/15] KVM: arm64: sync LPI configuration and pending
 tables
In-Reply-To: <55DC8950.3050306@arm.com>
References: <1436538111-4294-1-git-send-email-andre.przywara@arm.com>
 <1436538111-4294-13-git-send-email-andre.przywara@arm.com>
 <55CDD7CB.9020103@linaro.org> <55DC8950.3050306@arm.com>
Message-ID: <55E422CB.2070709@linaro.org>

On 08/25/2015 05:27 PM, Andre Przywara wrote:
> Hi Eric,
> 
> On 14/08/15 12:58, Eric Auger wrote:
>> On 07/10/2015 04:21 PM, Andre Przywara wrote:
>>> The LPI configuration and pending tables of the GICv3 LPIs are held
>>> in tables in (guest) memory. To achieve reasonable performance, we
>>> cache this data in our own data structures, so we need to sync those
>>> two views from time to time. This behaviour is well described in the
>>> GICv3 spec and is also exercised by hardware, so the sync points are
>>> well known.
>>>
>>> Provide functions that read the guest memory and store the
>>> information from the configuration and pending tables in the kernel.
>>>
>>> Signed-off-by: Andre Przywara <andre.przywara at arm.com>
>>> ---
>> would help to have change log between v1 -> v2 (valid for the whole series)
>>>  include/kvm/arm_vgic.h  |   2 +
>>>  virt/kvm/arm/its-emul.c | 124 ++++++++++++++++++++++++++++++++++++++++++++++++
>>>  virt/kvm/arm/its-emul.h |   3 ++
>>>  3 files changed, 129 insertions(+)
>>>
>>> diff --git a/include/kvm/arm_vgic.h b/include/kvm/arm_vgic.h
>>> index 2a67a10..323c33a 100644
>>> --- a/include/kvm/arm_vgic.h
>>> +++ b/include/kvm/arm_vgic.h
>>> @@ -167,6 +167,8 @@ struct vgic_its {
>>>  	int			cwriter;
>>>  	struct list_head	device_list;
>>>  	struct list_head	collection_list;
>>> +	/* memory used for buffering guest's memory */
>>> +	void			*buffer_page;
>>>  };
>>>  
>>>  struct vgic_dist {
>>> diff --git a/virt/kvm/arm/its-emul.c b/virt/kvm/arm/its-emul.c
>>> index b9c40d7..05245cb 100644
>>> --- a/virt/kvm/arm/its-emul.c
>>> +++ b/virt/kvm/arm/its-emul.c
>>> @@ -50,6 +50,7 @@ struct its_itte {
>>>  	struct its_collection *collection;
>>>  	u32 lpi;
>>>  	u32 event_id;
>>> +	u8 priority;
>>>  	bool enabled;
>>>  	unsigned long *pending;
>>>  };
>>> @@ -70,8 +71,124 @@ static struct its_itte *find_itte_by_lpi(struct kvm *kvm, int lpi)
>>>  	return NULL;
>>>  }
>>>  
>>> +#define LPI_PROP_ENABLE_BIT(p)	((p) & LPI_PROP_ENABLED)
>>> +#define LPI_PROP_PRIORITY(p)	((p) & 0xfc)
>>> +
>>> +/* stores the priority and enable bit for a given LPI */
>>> +static void update_lpi_config(struct kvm *kvm, struct its_itte *itte, u8 prop)
>>> +{
>>> +	itte->priority = LPI_PROP_PRIORITY(prop);
>>> +	itte->enabled  = LPI_PROP_ENABLE_BIT(prop);
>>> +}
>>> +
>>> +#define GIC_LPI_OFFSET 8192
>>> +
>>> +/* We scan the table in chunks the size of the smallest page size */
>> 4kB chunks?
> 
> Marc was complaining about this wording, I think. The rationale was that
> "4K" is already in the code and thus does not need to be repeated in the
> comment, whereas the comment should explain the meaning of the value.

understood

Eric
> 
>>> +#define CHUNK_SIZE 4096U
>>> +
>>>  #define BASER_BASE_ADDRESS(x) ((x) & 0xfffffffff000ULL)
>>>  
>>> +static int nr_idbits_propbase(u64 propbaser)
>>> +{
>>> +	int nr_idbits = (1U << (propbaser & 0x1f)) + 1;
>>> +
>>> +	return max(nr_idbits, INTERRUPT_ID_BITS_ITS);
>>> +}
>>> +
>>> +/*
>>> + * Scan the whole LPI configuration table and put the LPI configuration
>>> + * data in our own data structures. This relies on the LPI being
>>> + * mapped before.
>>> + */
>>> +static bool its_update_lpis_configuration(struct kvm *kvm)
>>> +{
>>> +	struct vgic_dist *dist = &kvm->arch.vgic;
>>> +	u8 *prop = dist->its.buffer_page;
>>> +	u32 tsize;
>>> +	gpa_t propbase;
>>> +	int lpi = GIC_LPI_OFFSET;
>>> +	struct its_itte *itte;
>>> +	struct its_device *device;
>>> +	int ret;
>>> +
>>> +	propbase = BASER_BASE_ADDRESS(dist->propbaser);
>>> +	tsize = nr_idbits_propbase(dist->propbaser);
>>> +
>>> +	while (tsize > 0) {
>>> +		int chunksize = min(tsize, CHUNK_SIZE);
>>> +
>>> +		ret = kvm_read_guest(kvm, propbase, prop, chunksize);
>> I think you still have the spin_lock issue  since if my understanding is
>> correct this is called from
>> vgic_handle_mmio_access/vcall_range_handler/gic_enable_lpis
>> where vgic_handle_mmio_access. Or does it take another path?
> 
> Well, it's (also) called on handling the INVALL command, but you are
> right that on that enable path the dist lock is held. I reckon that this
> init part isn't racy so that shouldn't be a problem (famous last words ;-).
> Let me see whether I can find a way to just drop the lock around the
> while loop.
> 
> Cheers,
> Andre.
> 
>>
>> Shouldn't we create a new kvm_io_device to avoid holding the dist lock?
>>
>> Eric



From eric.auger at linaro.org  Mon Aug 31 02:51:33 2015
From: eric.auger at linaro.org (Eric Auger)
Date: Mon, 31 Aug 2015 11:51:33 +0200
Subject: [PATCH v2 12/15] KVM: arm64: sync LPI configuration and pending
 tables
In-Reply-To: <55DC8DF5.3010303@arm.com>
References: <1436538111-4294-1-git-send-email-andre.przywara@arm.com>
 <1436538111-4294-13-git-send-email-andre.przywara@arm.com>
 <55CDD7CB.9020103@linaro.org> <55CDE0A6.5010906@linaro.org>
 <55DC8DF5.3010303@arm.com>
Message-ID: <55E423A5.9080703@linaro.org>

On 08/25/2015 05:47 PM, Andre Przywara wrote:
> Hi Eric,
> 
> On 14/08/15 13:35, Eric Auger wrote:
>> On 08/14/2015 01:58 PM, Eric Auger wrote:
>>> On 07/10/2015 04:21 PM, Andre Przywara wrote:
>>>> The LPI configuration and pending tables of the GICv3 LPIs are held
>>>> in tables in (guest) memory. To achieve reasonable performance, we
>>>> cache this data in our own data structures, so we need to sync those
>>>> two views from time to time. This behaviour is well described in the
>>>> GICv3 spec and is also exercised by hardware, so the sync points are
>>>> well known.
>>>>
>>>> Provide functions that read the guest memory and store the
>>>> information from the configuration and pending tables in the kernel.
>>>>
>>>> Signed-off-by: Andre Przywara <andre.przywara at arm.com>
>>>> ---
>>> would help to have change log between v1 -> v2 (valid for the whole series)
>>>>  include/kvm/arm_vgic.h  |   2 +
>>>>  virt/kvm/arm/its-emul.c | 124 ++++++++++++++++++++++++++++++++++++++++++++++++
>>>>  virt/kvm/arm/its-emul.h |   3 ++
>>>>  3 files changed, 129 insertions(+)
>>>>
>>>> diff --git a/include/kvm/arm_vgic.h b/include/kvm/arm_vgic.h
>>>> index 2a67a10..323c33a 100644
>>>> --- a/include/kvm/arm_vgic.h
>>>> +++ b/include/kvm/arm_vgic.h
>>>> @@ -167,6 +167,8 @@ struct vgic_its {
>>>>  	int			cwriter;
>>>>  	struct list_head	device_list;
>>>>  	struct list_head	collection_list;
>>>> +	/* memory used for buffering guest's memory */
>>>> +	void			*buffer_page;
>>>>  };
>>>>  
>>>>  struct vgic_dist {
>>>> diff --git a/virt/kvm/arm/its-emul.c b/virt/kvm/arm/its-emul.c
>>>> index b9c40d7..05245cb 100644
>>>> --- a/virt/kvm/arm/its-emul.c
>>>> +++ b/virt/kvm/arm/its-emul.c
>>>> @@ -50,6 +50,7 @@ struct its_itte {
>>>>  	struct its_collection *collection;
>>>>  	u32 lpi;
>>>>  	u32 event_id;
>>>> +	u8 priority;
>>>>  	bool enabled;
>>>>  	unsigned long *pending;
>>>>  };
>>>> @@ -70,8 +71,124 @@ static struct its_itte *find_itte_by_lpi(struct kvm *kvm, int lpi)
>>>>  	return NULL;
>>>>  }
>>>>  
>>>> +#define LPI_PROP_ENABLE_BIT(p)	((p) & LPI_PROP_ENABLED)
>>>> +#define LPI_PROP_PRIORITY(p)	((p) & 0xfc)
>>>> +
>>>> +/* stores the priority and enable bit for a given LPI */
>>>> +static void update_lpi_config(struct kvm *kvm, struct its_itte *itte, u8 prop)
>>>> +{
>>>> +	itte->priority = LPI_PROP_PRIORITY(prop);
>>>> +	itte->enabled  = LPI_PROP_ENABLE_BIT(prop);
>>>> +}
>>>> +
>>>> +#define GIC_LPI_OFFSET 8192
>>>> +
>>>> +/* We scan the table in chunks the size of the smallest page size */
>>> 4kB chunks?
>>>> +#define CHUNK_SIZE 4096U
>>>> +
>>>>  #define BASER_BASE_ADDRESS(x) ((x) & 0xfffffffff000ULL)
>>>>  
>>>> +static int nr_idbits_propbase(u64 propbaser)
>>>> +{
>>>> +	int nr_idbits = (1U << (propbaser & 0x1f)) + 1;
>>>> +
>>>> +	return max(nr_idbits, INTERRUPT_ID_BITS_ITS);
>>>> +}
>>>> +
>>>> +/*
>>>> + * Scan the whole LPI configuration table and put the LPI configuration
>>>> + * data in our own data structures. This relies on the LPI being
>>>> + * mapped before.
>>>> + */
>>>> +static bool its_update_lpis_configuration(struct kvm *kvm)
>>>> +{
>>>> +	struct vgic_dist *dist = &kvm->arch.vgic;
>>>> +	u8 *prop = dist->its.buffer_page;
>>>> +	u32 tsize;
>>>> +	gpa_t propbase;
>>>> +	int lpi = GIC_LPI_OFFSET;
>>>> +	struct its_itte *itte;
>>>> +	struct its_device *device;
>>>> +	int ret;
>>>> +
>>>> +	propbase = BASER_BASE_ADDRESS(dist->propbaser);
>>>> +	tsize = nr_idbits_propbase(dist->propbaser);
>>>> +
>>>> +	while (tsize > 0) {
>>>> +		int chunksize = min(tsize, CHUNK_SIZE);
>>>> +
>>>> +		ret = kvm_read_guest(kvm, propbase, prop, chunksize);
>>> I think you still have the spin_lock issue  since if my understanding is
>>> correct this is called from
>>> vgic_handle_mmio_access/vcall_range_handler/gic_enable_lpis
>>> where vgic_handle_mmio_access. Or does it take another path?
>>>
>>> Shouldn't we create a new kvm_io_device to avoid holding the dist lock?
>>
>> Sorry I forgot it was the case already. But currently we always register
>> the same io ops (registration entry point being
>> vgic_register_kvm_io_dev) and maybe we should have separate dispatcher
>> function for dist, redit and its?
> 
> What would be the idea behind it? To have separate locks for each? I
> don't think that will work, as some ITS functions are called from GICv3
> register handler functions which manipulate members of the distributor
> structure.

Yes it was the idea.

 So I am more in favour of dropping the dist lock in these
> cases before handing off execution to ITS specific functions.

OK. Let's see how the refactoring looks like then

Cheers

Eric
> 
> Cheers,
> Andre.
> 



From christoffer.dall at linaro.org  Mon Aug 31 03:12:24 2015
From: christoffer.dall at linaro.org (Christoffer Dall)
Date: Mon, 31 Aug 2015 12:12:24 +0200
Subject: [PATCH v2 3/4] KVM: arm/arm64: check power_off in critical
 section before VCPU run
In-Reply-To: <1438963713-10460-4-git-send-email-eric.auger@linaro.org>
References: <1438963713-10460-1-git-send-email-eric.auger@linaro.org>
 <1438963713-10460-4-git-send-email-eric.auger@linaro.org>
Message-ID: <20150831101224.GN24113@cbox>

On Fri, Aug 07, 2015 at 06:08:32PM +0200, Eric Auger wrote:
> In case KVM_SET_MP_STATE ioctl is called just after we executed the
> vcpu_sleep check, we can enter the guest although KVM_MP_STATE_STOPPED
> is set. Let's check the power_off state in the critical section,
> just before entering the guest.

I don't think this can happen from the KVM_SET_MP_STATE, because that is
a vcpu ioctl and would therefore require userspace sets this before even
entering the run loop in the kernel, but it could happen at the PSCI
system event preparation.

> 
> Signed-off-by: Eric Auger <eric.auger at linaro.org>
> Reported-by: Christoffer Dall <christoffer.dall at linaro.org>
> ---
>  arch/arm/kvm/arm.c | 3 ++-
>  1 file changed, 2 insertions(+), 1 deletion(-)
> 
> diff --git a/arch/arm/kvm/arm.c b/arch/arm/kvm/arm.c
> index 4f50be3..cc404a8 100644
> --- a/arch/arm/kvm/arm.c
> +++ b/arch/arm/kvm/arm.c
> @@ -555,7 +555,8 @@ int kvm_arch_vcpu_ioctl_run(struct kvm_vcpu *vcpu, struct kvm_run *run)
>  			run->exit_reason = KVM_EXIT_INTR;
>  		}
>  
> -		if (ret <= 0 || need_new_vmid_gen(vcpu->kvm)) {
> +		if (ret <= 0 || need_new_vmid_gen(vcpu->kvm) ||
> +			vcpu->arch.power_off) {
>  			local_irq_enable();
>  			kvm_vgic_sync_hwstate(vcpu);
>  			preempt_enable();
> -- 
> 1.9.1
> 


From broonie at kernel.org  Mon Aug 31 03:31:59 2015
From: broonie at kernel.org (Mark Brown)
Date: Mon, 31 Aug 2015 11:31:59 +0100
Subject: [PATCH v2] spi: bitbang: Replace spinlock by mutex
In-Reply-To: <CANMq1KAOsyhT1w54dc1u6JRzUdrjo-RpCb7CQBD66OdrSyPh=w@mail.gmail.com>
References: <1439783574-5933-1-git-send-email-drinkcat@chromium.org>
 <CANMq1KAOsyhT1w54dc1u6JRzUdrjo-RpCb7CQBD66OdrSyPh=w@mail.gmail.com>
Message-ID: <20150831103159.GJ12027@sirena.org.uk>

On Mon, Aug 31, 2015 at 03:54:13PM +0800, Nicolas Boichat wrote:
> On Mon, Aug 17, 2015 at 11:52 AM, Nicolas Boichat <drinkcat at chromium.org> wrote:

> Any update on this patch? It still applies on for-next but happy to
> resend if necessary (patchwork:
> https://patchwork.kernel.org/patch/7023091/).

Please don't send content free pings and please allow a reasonable
amount of time for review.
-------------- next part --------------
A non-text attachment was scrubbed...
Name: signature.asc
Type: application/pgp-signature
Size: 473 bytes
Desc: Digital signature
URL: <http://lists.infradead.org/pipermail/linux-arm-kernel/attachments/20150831/6b015b8e/attachment.sig>

From christoffer.dall at linaro.org  Mon Aug 31 03:43:33 2015
From: christoffer.dall at linaro.org (Christoffer Dall)
Date: Mon, 31 Aug 2015 12:43:33 +0200
Subject: [PATCH v2 4/4] KVM: arm/arm64: implement
 kvm_arm_[halt,resume]_guest
In-Reply-To: <1438963713-10460-5-git-send-email-eric.auger@linaro.org>
References: <1438963713-10460-1-git-send-email-eric.auger@linaro.org>
 <1438963713-10460-5-git-send-email-eric.auger@linaro.org>
Message-ID: <20150831104333.GO24113@cbox>

On Fri, Aug 07, 2015 at 06:08:33PM +0200, Eric Auger wrote:
> We introduce kvm_arm_halt_guest and resume functions. They
> will be used for IRQ forward state change.
> 
> Halt is synchronous and prevents the guest from being re-entered.
> We use the same mechanism put in place for PSCI former pause,
> now renamed power_off. A new flag is introduced in arch vcpu state,
> pause, only meant to be used by those functions.
> 
> Signed-off-by: Eric Auger <eric.auger at linaro.org>
> 
> ---
> v1 -> v2:
> - check pause in kvm_arch_vcpu_runnable
> - we cannot use kvm_vcpu_block since this latter would exit on
>   IRQ/FIQ and this is not what we want
> ---
>  arch/arm/include/asm/kvm_host.h   |  3 +++
>  arch/arm/kvm/arm.c                | 35 +++++++++++++++++++++++++++++++----
>  arch/arm64/include/asm/kvm_host.h |  3 +++
>  3 files changed, 37 insertions(+), 4 deletions(-)
> 
> diff --git a/arch/arm/include/asm/kvm_host.h b/arch/arm/include/asm/kvm_host.h
> index 304004d..dac85f6 100644
> --- a/arch/arm/include/asm/kvm_host.h
> +++ b/arch/arm/include/asm/kvm_host.h
> @@ -132,6 +132,9 @@ struct kvm_vcpu_arch {
>  	/* vcpu power-off state */
>  	bool power_off;
>  
> +	 /* Exit and don't run the guest (internal implementation need) */

Why exit?  I think it's slightly more correct to just say.
"Don't run the guest (internal implementation need)"

> +	bool pause;
> +
>  	/* IO related fields */
>  	struct kvm_decode mmio_decode;
>  
> diff --git a/arch/arm/kvm/arm.c b/arch/arm/kvm/arm.c
> index cc404a8..0529b38 100644
> --- a/arch/arm/kvm/arm.c
> +++ b/arch/arm/kvm/arm.c
> @@ -348,7 +348,7 @@ int kvm_arch_vcpu_ioctl_set_mpstate(struct kvm_vcpu *vcpu,
>  int kvm_arch_vcpu_runnable(struct kvm_vcpu *v)
>  {
>  	return ((!!v->arch.irq_lines || kvm_vgic_vcpu_pending_irq(v))
> -		&& !v->arch.power_off);
> +		&& !v->arch.power_off && !v->arch.pause);
>  }
>  
>  /* Just ensure a guest exit from a particular CPU */
> @@ -474,11 +474,38 @@ bool kvm_arch_intc_initialized(struct kvm *kvm)
>  	return vgic_initialized(kvm);
>  }
>  
> +static void kvm_arm_halt_guest(struct kvm *kvm) __maybe_unused;
> +static void kvm_arm_resume_guest(struct kvm *kvm) __maybe_unused;
> +
> +static void kvm_arm_halt_guest(struct kvm *kvm)
> +{
> +	int i;
> +	struct kvm_vcpu *vcpu;
> +
> +	kvm_for_each_vcpu(i, vcpu, kvm)
> +		vcpu->arch.pause = true;
> +	force_vm_exit(cpu_all_mask);
> +}
> +
> +static void kvm_arm_resume_guest(struct kvm *kvm)
> +{
> +	int i;
> +	struct kvm_vcpu *vcpu;
> +
> +	kvm_for_each_vcpu(i, vcpu, kvm) {
> +		wait_queue_head_t *wq = kvm_arch_vcpu_wq(vcpu);
> +
> +		vcpu->arch.pause = false;
> +		wake_up_interruptible(wq);
> +	}
> +}
> +
>  static void vcpu_sleep(struct kvm_vcpu *vcpu)
>  {
>  	wait_queue_head_t *wq = kvm_arch_vcpu_wq(vcpu);
>  
> -	wait_event_interruptible(*wq, !vcpu->arch.power_off);
> +	wait_event_interruptible(*wq, ((!vcpu->arch.power_off) &&
> +				       (!vcpu->arch.pause)));
>  }
>  
>  static int kvm_vcpu_initialized(struct kvm_vcpu *vcpu)
> @@ -528,7 +555,7 @@ int kvm_arch_vcpu_ioctl_run(struct kvm_vcpu *vcpu, struct kvm_run *run)
>  
>  		update_vttbr(vcpu->kvm);
>  
> -		if (vcpu->arch.power_off)
> +		if (vcpu->arch.power_off || vcpu->arch.pause)
>  			vcpu_sleep(vcpu);
>  
>  		/*
> @@ -556,7 +583,7 @@ int kvm_arch_vcpu_ioctl_run(struct kvm_vcpu *vcpu, struct kvm_run *run)
>  		}
>  
>  		if (ret <= 0 || need_new_vmid_gen(vcpu->kvm) ||
> -			vcpu->arch.power_off) {
> +			vcpu->arch.power_off || vcpu->arch.pause) {
>  			local_irq_enable();
>  			kvm_vgic_sync_hwstate(vcpu);
>  			preempt_enable();
> diff --git a/arch/arm64/include/asm/kvm_host.h b/arch/arm64/include/asm/kvm_host.h
> index 009da6b..69e3785 100644
> --- a/arch/arm64/include/asm/kvm_host.h
> +++ b/arch/arm64/include/asm/kvm_host.h
> @@ -125,6 +125,9 @@ struct kvm_vcpu_arch {
>  	/* vcpu power-off state */
>  	bool power_off;
>  
> +	/* Don't run the guest */

Can we have the same comment on the arm and arm64 version?

> +	bool pause;
> +
>  	/* IO related fields */
>  	struct kvm_decode mmio_decode;
>  
> -- 
> 1.9.1
> 

Besides these commenting nits, I think this looks reasonable overall.

Reviewed-by: Christoffer Dall <christoffer.dall at linaro.org>

On the series.


From tomasz.nowicki at linaro.org  Mon Aug 31 04:01:33 2015
From: tomasz.nowicki at linaro.org (Tomasz Nowicki)
Date: Mon, 31 Aug 2015 13:01:33 +0200
Subject: [PATCH 05/11] x86, pci, acpi: Move arch-agnostic MMCONFIG (aka
 ECAM) and ACPI code out of arch/x86/ directory
In-Reply-To: <20150608151443.GA16151@red-moon>
References: <1432644564-24746-1-git-send-email-hanjun.guo@linaro.org>
 <1432644564-24746-6-git-send-email-hanjun.guo@linaro.org>
 <20150526170817.GU1565@arm.com> <55657B02.5090805@linaro.org>
 <20150602133215.GC23650@red-moon> <55701A31.808@linaro.org>
 <20150604102253.GA31773@red-moon> <5570447D.3020705@linaro.org>
 <557504A2.3060203@linaro.org> <20150608151443.GA16151@red-moon>
Message-ID: <55E4340D.6050004@linaro.org>

On 08.06.2015 17:14, Lorenzo Pieralisi wrote:
> On Mon, Jun 08, 2015 at 03:57:38AM +0100, Hanjun Guo wrote:
>
> [...]
>
>>>>>>>> Why can't we make use of the ECAM implementation used by
>>>>>>>> pci-host-generic
>>>>>>>> and drivers/pci/access.c?
>>>>>>>
>>>>>>> We had that question when I had posted MMCFG patch set separately,
>>>>>>> please see:
>>>>>>> https://lkml.org/lkml/2015/3/11/492
>>>>>>
>>>>>> Yes, but the real question is, why do we need to have PCI config space
>>>>>> up and running before a bus struct is even created ? I think the
>>>>>> reason is
>>>>>> the PCI configuration address space format (ACPI 6.0, Table 5-27, page
>>>>>> 108):
>>>>>>
>>>>>> "PCI Configuration space addresses must be confined to devices on
>>>>>> PCI Segment Group 0, bus 0. This restriction exists to accommodate
>>>>>> access to fixed hardware prior to PCI bus enumeration".
>>>>>>
>>>>>> On HW reduced platforms I do not even think this is required at all,
>>>>>> we have to look into this to avoid code duplication that might well
>>>>>> turn out useless.
>>>>>
>>>>> This is only for the fixed hardware, which will be not available for
>>>>> ARM64 (reduced hardware mode), but in Generic Hardware Programming
>>>>> Model, we using OEM-provided ACPI Machine Language (AML) code to access
>>>>> generic hardware registers, this will be available for reduced hardware
>>>>> too.
>>>>>
>>>>> So in ACPI spec, it says: (ACPI 6.0 page 66, last paragraph)
>>>>>
>>>>> ACPI defines eight address spaces that may be accessed by generic
>>>>> hardware implementations. These include:
>>>>> * System I/O space
>>>>> * System memory space
>>>>> * PCI configuration space
>>>>> * Embedded controller space
>>>>> * System Management Bus (SMBus) space
>>>>> * CMOS
>>>>> * PCI BAR Target
>>>>> * IPMI space
>>>>>
>>>>> So if any device using the PCI address space for control, such
>>>>> as a system reset control device, its address space can be reside
>>>>> in PCI configuration space (who can prevent a OEM do that crazy
>>>>> thing? :) ), and it should be accessible before the PCI bus is
>>>>> created.
>>>>
>>>> Us, by changing attitude and questioning features whose usefulness
>>>> is questionable. I will look into this and raise the point, I am not
>>>> thrilled by the idea of adding another set of PCI accessor functions
>>>> and drivers because we have to access a register through PCI before
>>>> enumerating the bus (and on arm64 this is totally useless since
>>>> we are not meant to support fixed HW anyway). Maybe we can make acpica
>>>> code use a "special" stub (ACPI specific, PCI configuration space address
>>>> space has restrictions anyway), I have to review this set in its
>>>> entirety to see how to do that (and I would kindly ask you to do
>>>> it too, before saying it is not possible to implement it).
>>>
>>> I'm willing to do that, actually, if we don't need a mechanism to
>>> access PCI config space before the bus is created, the code can be
>>> simplified a lot.
>>
>> After more investigation on the spec and the ACPI core code, I'm
>> still not convinced that accessing to PCI config space before PCI
>> bus creating is impossible, also there is no enough ARM64 hardware
>> to prove that too. But I think we can go in this way, reuse the
>> ECAM implementation by pci-host-generic for now, and implement the PCI
>> accessor functions before enumerating PCI bus when needed in the
>> future, does it make sense?
>
> You mean we rewrite the patch to make sure we can use the PCI host generic
> driver with MCFG and we leave the acpica PCI config call empty stubs on
> arm64 (as they are now) ?
>

Hi Bjorn, Rafael,

Lorenzo pointed out very important problem we are having with PCI config 
space access for ARM64. Please refer to the above discussion and add 
your 2 cents. Can we forget about accessing PCI config space (for 
Hardware Reduced profile) before PCI bus creation? If not, do you see a 
way to use drivers/pci/access.c accessors here, like acpica change? Any 
opinion is very appreciated.

Regards,
Tomasz


From hverkuil at xs4all.nl  Mon Aug 31 04:22:02 2015
From: hverkuil at xs4all.nl (Hans Verkuil)
Date: Mon, 31 Aug 2015 13:22:02 +0200
Subject: [PATCH v8 29/55] [media] replace all occurrences of
 MEDIA_ENT_T_DEVNODE_V4L
In-Reply-To: <553c4e697dee72bbdf3d73a4d428118e10e18720.1440902901.git.mchehab@osg.samsung.com>
References: <cover.1440902901.git.mchehab@osg.samsung.com>
 <553c4e697dee72bbdf3d73a4d428118e10e18720.1440902901.git.mchehab@osg.samsung.com>
Message-ID: <55E438DA.7050701@xs4all.nl>

On 08/30/2015 05:06 AM, Mauro Carvalho Chehab wrote:
> Now that interfaces and entities are distinct, it makes no sense
> of keeping something named as MEDIA_ENT_T_DEVNODE.
> 
> This change was done with this script:
> 
> 	for i in $(git grep -l MEDIA_ENT_T|grep -v uapi/linux/media.h); do sed s,MEDIA_ENT_T_DEVNODE_V4L,MEDIA_ENT_T_V4L2_VIDEO, <$i >a && mv a $i; done
> 
> Signed-off-by: Mauro Carvalho Chehab <mchehab at osg.samsung.com>

Acked-by: Hans Verkuil <hans.verkuil at cisco.com>

> 
> diff --git a/Documentation/DocBook/media/v4l/media-ioc-enum-entities.xml b/Documentation/DocBook/media/v4l/media-ioc-enum-entities.xml
> index 5872f8bbf774..910243d4edb8 100644
> --- a/Documentation/DocBook/media/v4l/media-ioc-enum-entities.xml
> +++ b/Documentation/DocBook/media/v4l/media-ioc-enum-entities.xml
> @@ -183,7 +183,7 @@
>  	    <entry>Unknown device node</entry>
>  	  </row>
>  	  <row>
> -	    <entry><constant>MEDIA_ENT_T_DEVNODE_V4L</constant></entry>
> +	    <entry><constant>MEDIA_ENT_T_V4L2_VIDEO</constant></entry>
>  	    <entry>V4L video, radio or vbi device node</entry>
>  	  </row>
>  	  <row>
> diff --git a/drivers/media/platform/xilinx/xilinx-dma.c b/drivers/media/platform/xilinx/xilinx-dma.c
> index 92e8116dc28f..88cd789cdaf7 100644
> --- a/drivers/media/platform/xilinx/xilinx-dma.c
> +++ b/drivers/media/platform/xilinx/xilinx-dma.c
> @@ -193,7 +193,7 @@ static int xvip_pipeline_validate(struct xvip_pipeline *pipe,
>  	while ((entity = media_entity_graph_walk_next(&graph))) {
>  		struct xvip_dma *dma;
>  
> -		if (entity->type != MEDIA_ENT_T_DEVNODE_V4L)
> +		if (entity->type != MEDIA_ENT_T_V4L2_VIDEO)
>  			continue;
>  
>  		dma = to_xvip_dma(media_entity_to_video_device(entity));
> diff --git a/drivers/media/v4l2-core/v4l2-dev.c b/drivers/media/v4l2-core/v4l2-dev.c
> index 71a1b93b0790..44b330589787 100644
> --- a/drivers/media/v4l2-core/v4l2-dev.c
> +++ b/drivers/media/v4l2-core/v4l2-dev.c
> @@ -912,7 +912,7 @@ int __video_register_device(struct video_device *vdev, int type, int nr,
>  	/* Part 5: Register the entity. */
>  	if (vdev->v4l2_dev->mdev &&
>  	    vdev->vfl_type != VFL_TYPE_SUBDEV) {
> -		vdev->entity.type = MEDIA_ENT_T_DEVNODE_V4L;
> +		vdev->entity.type = MEDIA_ENT_T_V4L2_VIDEO;
>  		vdev->entity.name = vdev->name;
>  		vdev->entity.info.dev.major = VIDEO_MAJOR;
>  		vdev->entity.info.dev.minor = vdev->minor;
> diff --git a/drivers/media/v4l2-core/v4l2-subdev.c b/drivers/media/v4l2-core/v4l2-subdev.c
> index 83615b8fb46a..e6e1115d8215 100644
> --- a/drivers/media/v4l2-core/v4l2-subdev.c
> +++ b/drivers/media/v4l2-core/v4l2-subdev.c
> @@ -535,7 +535,7 @@ v4l2_subdev_link_validate_get_format(struct media_pad *pad,
>  		return v4l2_subdev_call(sd, pad, get_fmt, NULL, fmt);
>  	}
>  
> -	WARN(pad->entity->type != MEDIA_ENT_T_DEVNODE_V4L,
> +	WARN(pad->entity->type != MEDIA_ENT_T_V4L2_VIDEO,
>  	     "Driver bug! Wrong media entity type 0x%08x, entity %s\n",
>  	     pad->entity->type, pad->entity->name);
>  
> 



From antonios.motakis at huawei.com  Mon Aug 31 04:43:56 2015
From: antonios.motakis at huawei.com (Antonios Motakis)
Date: Mon, 31 Aug 2015 13:43:56 +0200
Subject: [PATCH v3 04/10] VFIO: platform: add vfio_platform_set_automasked
In-Reply-To: <1439919864.4023.626.camel@redhat.com>
References: <1439212864-12954-1-git-send-email-eric.auger@linaro.org>
 <1439212864-12954-5-git-send-email-eric.auger@linaro.org>
 <1439405794.4023.528.camel@redhat.com> <55D1FFE8.9050104@linaro.org>
 <1439919864.4023.626.camel@redhat.com>
Message-ID: <55E43DFC.8050608@huawei.com>



On 18-Aug-15 19:44, Alex Williamson wrote:
> On Mon, 2015-08-17 at 17:38 +0200, Eric Auger wrote:
>> On 08/12/2015 08:56 PM, Alex Williamson wrote:
>>> On Mon, 2015-08-10 at 15:20 +0200, Eric Auger wrote:
>>>> This function makes possible to change the automasked mode.
>>>>
>>>> Signed-off-by: Eric Auger <eric.auger at linaro.org>
>>>>
>>>> ---
>>>>
>>>> v1 -> v2:
>>>> - set forwarded flag
>>>> ---
>>>>  drivers/vfio/platform/vfio_platform_irq.c | 19 +++++++++++++++++++
>>>>  1 file changed, 19 insertions(+)
>>>>
>>>> diff --git a/drivers/vfio/platform/vfio_platform_irq.c b/drivers/vfio/platform/vfio_platform_irq.c
>>>> index b31b1f0..a285384 100644
>>>> --- a/drivers/vfio/platform/vfio_platform_irq.c
>>>> +++ b/drivers/vfio/platform/vfio_platform_irq.c
>>>> @@ -186,6 +186,25 @@ static irqreturn_t vfio_handler(int irq, void *dev_id)
>>>>  	return ret;
>>>>  }
>>>>  
>>>> +static int vfio_platform_set_automasked(struct vfio_platform_irq *irq,
>>>> +					   bool automasked)
>>>> +{
>>>> +	unsigned long flags;
>>>> +
>>>> +	spin_lock_irqsave(&irq->lock, flags);
>>>> +	if (automasked) {
>>>> +		irq->forwarded = true;
>>>> +		irq->flags |= VFIO_IRQ_INFO_AUTOMASKED;
>>>> +		irq->handler = vfio_automasked_irq_handler;
>>>> +	} else {
>>>> +		irq->forwarded = false;
>>>> +		irq->flags &= ~VFIO_IRQ_INFO_AUTOMASKED;
>>>> +		irq->handler = vfio_irq_handler;
>>>> +	}
>>>> +	spin_unlock_irqrestore(&irq->lock, flags);
>>>> +	return 0;
>>>
>>> In vfio-speak, automasked means level and we're not magically changing
>>> the IRQ from level to edge, we're simply able to handle level
>>> differently based on a hardware optimization.  Should the user visible
>>> flags therefore change based on this?  Aren't we really setting the
>>> forwarded state rather than the automasked state?
>>
>> Well actually this was following the discussion we had a long time ago
>> about that topic:
>>
>> http://lkml.iu.edu/hypermail/linux/kernel/1409.1/03659.html
>>
>> I did not really know how to conclude ...
>>
>> If it is preferred I can hide this to the userspace, no problem.
> 
> I think that was based on the user being involved in enabling forwarding
> though, now that it's hidden and automatic, it doesn't make much sense
> to me to toggle any of the interrupt info details based on the state of
> the forward.  The user always needs to handle the interrupt as level
> since the bypass can be torn down at any point in time.  We're taking
> advantage of the in-kernel path to make further optimizations, which
> seems like they should be transparent to the user.  Thanks,

I wonder if it makes sense to rename VFIO_IRQ_INFO_AUTOMASKED to
VFIO_IRQ_INFO_LEVEL_TRIGGERED, and reintroduce VFIO_IRQ_INFO_AUTOMASKED as
an alias, so compatibility with user space can be maintained? This way
this semantic misunderstanding could be left behind.

Cheers,
Antonios

> 
> Alex
> 
> _______________________________________________
> kvmarm mailing list
> kvmarm at lists.cs.columbia.edu
> https://lists.cs.columbia.edu/mailman/listinfo/kvmarm
> 

-- 
Antonios Motakis
Virtualization Engineer
Huawei Technologies Duesseldorf GmbH
European Research Center
Riesstrasse 25, 80992 M?nchen



From tomasz.nowicki at linaro.org  Mon Aug 31 05:04:23 2015
From: tomasz.nowicki at linaro.org (Tomasz Nowicki)
Date: Mon, 31 Aug 2015 14:04:23 +0200
Subject: [PATCH 02/11] x86, pci: Clean up comment about buggy MMIO config
 space access for AMD Fam10h CPUs.
In-Reply-To: <1432644564-24746-3-git-send-email-hanjun.guo@linaro.org>
References: <1432644564-24746-1-git-send-email-hanjun.guo@linaro.org>
 <1432644564-24746-3-git-send-email-hanjun.guo@linaro.org>
Message-ID: <55E442C7.7060509@linaro.org>

On 26.05.2015 14:49, Hanjun Guo wrote:
> From: Tomasz Nowicki <tomasz.nowicki at linaro.org>
>
> - fix typo
> - improve explanation
> - add reference to the related document
>
> Signed-off-by: Tomasz Nowicki <tomasz.nowicki at linaro.org>
> Signed-off-by: Hanjun Guo <hanjun.guo at linaro.org>
> Tested-by: Suravee Suthikulpanit <Suravee.Suthikulpanit at amd.com>
> ---
>   arch/x86/include/asm/pci_x86.h | 9 ++++++---
>   1 file changed, 6 insertions(+), 3 deletions(-)
>
> diff --git a/arch/x86/include/asm/pci_x86.h b/arch/x86/include/asm/pci_x86.h
> index 164e3f8..eddf8f0 100644
> --- a/arch/x86/include/asm/pci_x86.h
> +++ b/arch/x86/include/asm/pci_x86.h
> @@ -154,10 +154,13 @@ extern struct list_head pci_mmcfg_list;
>
>   /*
>    * AMD Fam10h CPUs are buggy, and cannot access MMIO config space
> - * on their northbrige except through the * %eax register. As such, you MUST
> - * NOT use normal IOMEM accesses, you need to only use the magic mmio-config
> + * on their northbridge except through the * %eax register. As such, you MUST
> + * NOT use normal IOMEM accesses, you need to only use the magic mmio_config_*
>    * accessor functions.
> - * In fact just use pci_config_*, nothing else please.
> + *
> + * Please refer to the following doc:
> + * "BIOS and Kernel Developer's Guide (BKDG) For AMD Family 10h Processors",
> + * rev. 3.48, sec 2.11.1, "MMIO Configuration Coding Requirements".
>    */
>   static inline unsigned char mmio_config_readb(void __iomem *pos)
>   {
>

Hi Bjorn,

Can you please consider to pick up this one patch?

Regards,
Tomasz


From marc.zyngier at arm.com  Mon Aug 31 05:20:31 2015
From: marc.zyngier at arm.com (Marc Zyngier)
Date: Mon, 31 Aug 2015 13:20:31 +0100
Subject: [PATCH] arm64: fix a migrating irq bug when hotplug cpu
In-Reply-To: <55E3020C.8020303@linaro.org>
References: <55E1AD09.7020701@huawei.com> <55E1CBE9.6080705@linux.intel.com>
 <66e158e6da958d355d54543ef69e5e94@www.loen.fr>
 <55E3020C.8020303@linaro.org>
Message-ID: <20150831132031.2a017df1@arm.com>

On Sun, 30 Aug 2015 21:15:56 +0800
Hanjun Guo <hanjun.guo at linaro.org> wrote:

> On 08/30/2015 02:12 AM, Marc Zyngier wrote:
> > On 2015-08-29 16:12, Jiang Liu wrote:
> >> On 2015/8/29 21:00, Yang Yingliang wrote:
> >>> From: Yang Yingliang <yangyingliang at huawei.com>
> >>>
> >>> When cpu is disabled, all irqs will be migratged to another cpu.
> >>> In some cases, a new affinity is different, it needed to be coppied
> >>> to irq's affinity. But if the type of irq is LPI, it's affinity will
> >>> not be coppied because of irq_set_affinity's return value.
> >>> So copy the affinity, when the return value is IRQ_SET_MASK_OK_DONE.
> >> Hi Yingliang,
> >>     If irq_set_affinity callback returns IRQ_SET_MASK_OK_DONE,
> >> it means that irq_set_affinity has copied the new CPU mask to irq
> >> affinity mask. It would be better to change irq_set_affinity for LPI
> >> to follow this rule.
> >
> > The main issue here seems to be that we do not call irq_set_affinity, but
> > that we directly call into the top-level irqchip method, which relies on
> > the core code to do the copy (see irq_do_set_affinity). Too bad.
> >
> > It feels like the arm/arm64 code would probably be better consolidated into
> > kernel/irq/migration.c, which already deals with some of this for x86
> > and ia64. It would save us the duplication and will make sure we don't
> > miss things next time we add a new return code, as irq_do_set_affinity
> > would handle this properly.
> >
> > Thoughts?
> 
> I agree. In arch/arm64/kernel/irq.c the irq migrate code is the same
> as ARM32, and it's duplicate. But this is a bugfix, can we fix it in
> a simple way, and refactor the code later?

I'm not buying this.

I really can't see how adding more duplication can be beneficial. It is
not so much that there is duplication between arm and arm64 that
bothers me (as if that was the only thing...). The real issue is that
there is duplication between the arch code and the core code.

Migrating interrupts is a core code matter, and that's were it should
be handled IMHO. Plus, we're in the merge window, and there is plenty
of time to get this fixed the proper way.

Thanks,

	M.
-- 
Jazz is not dead. It just smells funny.


From jason at lakedaemon.net  Mon Aug 31 05:39:44 2015
From: jason at lakedaemon.net (Jason Cooper)
Date: Mon, 31 Aug 2015 12:39:44 +0000
Subject: [PATCH 0/3] Add support for the Armada-370-based Seagate NAS
In-Reply-To: <1440866805-31731-1-git-send-email-simon.guinot@sequanux.org>
References: <1440866805-31731-1-git-send-email-simon.guinot@sequanux.org>
Message-ID: <20150831123944.GK3684@io.lakedaemon.net>

On Sat, Aug 29, 2015 at 06:46:42PM +0200, Simon Guinot wrote:
> Hi,
> 
> This patch series adds support for the Seagate machines based on the
> Armada-370 Marvell SoC. This includes the Personal Cloud 1 and 2-Bay
> and the Seagate NAS 2 and 4-Bay.
> 
> Thanks,
> 
> Simon
> 
> Simon Guinot (2):
>   ARM: mvebu: add DT support for Seagate Personal Cloud
>   ARM: mvebu: enable options for Seagate NAS in mvebu_v7_defconfig
> 
> Vincent Donnefort (1):
>   ARM: mvebu: add DT support for Seagate NAS 2 and 4-Bay
> 
>  arch/arm/boot/dts/Makefile                |   4 +
>  arch/arm/boot/dts/armada-370-n090103.dts  |  28 ++++
>  arch/arm/boot/dts/armada-370-n090201.dts  |  28 ++++
>  arch/arm/boot/dts/armada-370-n090203.dts  |  42 ++++++
>  arch/arm/boot/dts/armada-370-n090401.dts  | 124 ++++++++++++++++
>  arch/arm/boot/dts/armada-370-n090x01.dtsi | 232 ++++++++++++++++++++++++++++++
>  arch/arm/boot/dts/armada-370-n090x03.dtsi | 174 ++++++++++++++++++++++
>  arch/arm/configs/mvebu_v7_defconfig       |   9 +-
>  8 files changed, 640 insertions(+), 1 deletion(-)
>  create mode 100644 arch/arm/boot/dts/armada-370-n090103.dts
>  create mode 100644 arch/arm/boot/dts/armada-370-n090201.dts
>  create mode 100644 arch/arm/boot/dts/armada-370-n090203.dts
>  create mode 100644 arch/arm/boot/dts/armada-370-n090401.dts
>  create mode 100644 arch/arm/boot/dts/armada-370-n090x01.dtsi
>  create mode 100644 arch/arm/boot/dts/armada-370-n090x03.dtsi

Could you please name these something more informative?  e.g.
armada-370-seagate-personal-cloud-{1,2}.dts, etc?

thx,

Jason.


From andrew at lunn.ch  Mon Aug 31 05:43:14 2015
From: andrew at lunn.ch (Andrew Lunn)
Date: Mon, 31 Aug 2015 14:43:14 +0200
Subject: [PATCH 1/3] ARM: mvebu: add DT support for Seagate NAS 2 and 4-Bay
In-Reply-To: <1440866805-31731-2-git-send-email-simon.guinot@sequanux.org>
References: <1440866805-31731-1-git-send-email-simon.guinot@sequanux.org>
 <1440866805-31731-2-git-send-email-simon.guinot@sequanux.org>
Message-ID: <20150831124314.GE14459@lunn.ch>

On Sat, Aug 29, 2015 at 06:46:43PM +0200, Simon Guinot wrote:
> From: Vincent Donnefort <vdonnefort at gmail.com>
> 
> This patch adds DT support for the Seagate NAS 2 and 4-Bay (n090201 and
> n090401).
> 
> Chipset list (common):
> - SoC Marvell Armada 370 88F6707, CPU @1.2GHz
> - SDRAM memory: 512MB DDR3 600MHz (16-bits bandwidth)
> - NAND flash 256MB, 8-bits (Micron MT29F2G08AAB or Hinyx H27U2G8F2CTR-BC)
> - 2 SATA II ports (SoC)
> - 1 Ethernet Gigabit ports (PHY Marvell 88E1518)
> - 2 USB3 host ports (PCIe controller ASM1042)
> - GPIO fan (4 speeds)
> - External I2C RTC (MCP7940NT)
> - 3 push buttons (power, backup and reset)
> - 2 SATA LEDs (bi-color, blue and red)
> - 1 power LED (bi-color, blue and red)
> 
> Only on 4-Bay models:
> - 2 extra SATA III ports (PCIe AHCI controller Marvell 88SE9170)
> - 1 extra Ethernet Gigabit ports (PHY Marvell 88E1518)
> - I2C GPIO expander (PCA9554A)
> - 2 extra SATA LEDs (bi-color, blue and red)
> 
> Note that support for the white SATA LEDs associated with HDDs 0 and 1
> is missing. A dedicated LED driver is needed.
> 
> Signed-off-by: Vincent Donnefort <vdonnefort at gmail.com>
> ---
>  arch/arm/boot/dts/Makefile                |   2 +
>  arch/arm/boot/dts/armada-370-n090201.dts  |  28 ++++
>  arch/arm/boot/dts/armada-370-n090401.dts  | 124 ++++++++++++++++
>  arch/arm/boot/dts/armada-370-n090x01.dtsi | 232 ++++++++++++++++++++++++++++++
>  4 files changed, 386 insertions(+)
>  create mode 100644 arch/arm/boot/dts/armada-370-n090201.dts
>  create mode 100644 arch/arm/boot/dts/armada-370-n090401.dts
>  create mode 100644 arch/arm/boot/dts/armada-370-n090x01.dtsi
> 
> diff --git a/arch/arm/boot/dts/Makefile b/arch/arm/boot/dts/Makefile
> index 233159d2eaab..0a46613e90d2 100644
> --- a/arch/arm/boot/dts/Makefile
> +++ b/arch/arm/boot/dts/Makefile
> @@ -699,6 +699,8 @@ dtb-$(CONFIG_MACH_ARMADA_370) += \
>  	armada-370-db.dtb \
>  	armada-370-dlink-dns327l.dtb \
>  	armada-370-mirabox.dtb \
> +	armada-370-n090201.dtb \
> +	armada-370-n090401.dtb \
>  	armada-370-netgear-rn102.dtb \
>  	armada-370-netgear-rn104.dtb \
>  	armada-370-rd.dtb \
> diff --git a/arch/arm/boot/dts/armada-370-n090201.dts b/arch/arm/boot/dts/armada-370-n090201.dts
> new file mode 100644
> index 000000000000..b92b1ee067d6
> --- /dev/null
> +++ b/arch/arm/boot/dts/armada-370-n090201.dts
> @@ -0,0 +1,28 @@
> +/*
> + * Device Tree file for Seagate NAS 2-Bay (n090201)
> + *
> + * Copyright (C) 2015 Seagate
> + *
> + * Author: Vincent Donnefort <vdonnefort at gmail.com>
> + *
> + * This file is licensed under the terms of the GNU General Public
> + * License version 2.  This program is licensed "as is" without any
> + * warranty of any kind, whether express or implied.
> + */
> +
> +/dts-v1/;
> +
> +#include "armada-370-n090x01.dtsi"
> +
> +/ {
> +	model = "Seagate NAS 2-Bay";

On a similar line to Jason's comment. I'm sure Seagate has/is going to
have more than this 2-bay NAS. Can we have a more descriptive model
string here?

I could imagine an installer which looks through the list of available
DT blobs and creates a list showing the model and compatible string,
and asks the user, which should it use.

    Andrew


From robh at kernel.org  Mon Aug 31 05:52:07 2015
From: robh at kernel.org (Rob Herring)
Date: Mon, 31 Aug 2015 07:52:07 -0500
Subject: [RESEND PATCH v3 3/5] sh: kill off set_irq_flags usage
In-Reply-To: <20150831050104.GA26119@verge.net.au>
References: <1440889285-5637-1-git-send-email-robh@kernel.org>
 <1440889285-5637-4-git-send-email-robh@kernel.org>
 <20150831050104.GA26119@verge.net.au>
Message-ID: <CAL_JsqJuPtkvFMFvcSwaFssXoLYrHs9bM3EedXSzj21YAPmwDQ@mail.gmail.com>

On Mon, Aug 31, 2015 at 12:01 AM, Simon Horman <horms at verge.net.au> wrote:
> Hi Rob,
>
> On Sat, Aug 29, 2015 at 06:01:23PM -0500, Rob Herring wrote:
>> set_irq_flags is ARM specific with custom flags which have genirq
>> equivalents. Convert drivers to use the genirq interfaces directly, so we
>> can kill off set_irq_flags. The translation of flags is as follows:
>>
>> IRQF_VALID -> !IRQ_NOREQUEST
>> IRQF_PROBE -> !IRQ_NOPROBE
>> IRQF_NOAUTOEN -> IRQ_NOAUTOEN
>>
>> For IRQs managed by an irqdomain, the irqdomain core code handles clearing
>> and setting IRQ_NOREQUEST already, so there is no need to do this in
>> .map() functions and we can simply remove the set_irq_flags calls. Some
>> users also modify IRQ_NOPROBE and this has been maintained although it
>> is not clear that is really needed. There appears to be a great deal of
>> blind copy and paste of this code.
>>
>> Signed-off-by: Rob Herring <robh at kernel.org>
>> Acked-by: Simon Horman <horms at verge.net.au>
>> Cc: Magnus Damm <magnus.damm at gmail.com>
>> Cc: linux-sh at vger.kernel.org
>
> I have queued this up. Please let me know if that was not your intent.
>
> The patch is queued up in the sh-drivers-for-v4.3 branch of my renesas tree.
> At this point I plan to send a pull-request once dt changes that other
> patches in that branch depend on hit Linus's tree via the ARM SoC tree.
> I anticipate that being during the rc1 or rc2 timeframe.

This needs to go in before -rc1 so the final 2 patches removing
set_irq_flags can go in at the end of the merge window. Given your
timeline, I think you can just leave this one for Thomas to apply with
those 2.

Rob


From simon.guinot at sequanux.org  Mon Aug 31 06:02:36 2015
From: simon.guinot at sequanux.org (Simon Guinot)
Date: Mon, 31 Aug 2015 15:02:36 +0200
Subject: [PATCH 0/3] Add support for the Armada-370-based Seagate NAS
In-Reply-To: <20150831123944.GK3684@io.lakedaemon.net>
References: <1440866805-31731-1-git-send-email-simon.guinot@sequanux.org>
 <20150831123944.GK3684@io.lakedaemon.net>
Message-ID: <20150831130236.GN30993@kw.sim.vm.gnt>

On Mon, Aug 31, 2015 at 12:39:44PM +0000, Jason Cooper wrote:
> On Sat, Aug 29, 2015 at 06:46:42PM +0200, Simon Guinot wrote:
> > Hi,
> > 
> > This patch series adds support for the Seagate machines based on the
> > Armada-370 Marvell SoC. This includes the Personal Cloud 1 and 2-Bay
> > and the Seagate NAS 2 and 4-Bay.
> > 
> > Thanks,
> > 
> > Simon
> > 
> > Simon Guinot (2):
> >   ARM: mvebu: add DT support for Seagate Personal Cloud
> >   ARM: mvebu: enable options for Seagate NAS in mvebu_v7_defconfig
> > 
> > Vincent Donnefort (1):
> >   ARM: mvebu: add DT support for Seagate NAS 2 and 4-Bay
> > 
> >  arch/arm/boot/dts/Makefile                |   4 +
> >  arch/arm/boot/dts/armada-370-n090103.dts  |  28 ++++
> >  arch/arm/boot/dts/armada-370-n090201.dts  |  28 ++++
> >  arch/arm/boot/dts/armada-370-n090203.dts  |  42 ++++++
> >  arch/arm/boot/dts/armada-370-n090401.dts  | 124 ++++++++++++++++
> >  arch/arm/boot/dts/armada-370-n090x01.dtsi | 232 ++++++++++++++++++++++++++++++
> >  arch/arm/boot/dts/armada-370-n090x03.dtsi | 174 ++++++++++++++++++++++
> >  arch/arm/configs/mvebu_v7_defconfig       |   9 +-
> >  8 files changed, 640 insertions(+), 1 deletion(-)
> >  create mode 100644 arch/arm/boot/dts/armada-370-n090103.dts
> >  create mode 100644 arch/arm/boot/dts/armada-370-n090201.dts
> >  create mode 100644 arch/arm/boot/dts/armada-370-n090203.dts
> >  create mode 100644 arch/arm/boot/dts/armada-370-n090401.dts
> >  create mode 100644 arch/arm/boot/dts/armada-370-n090x01.dtsi
> >  create mode 100644 arch/arm/boot/dts/armada-370-n090x03.dtsi

Hi Jason,

> 
> Could you please name these something more informative?  e.g.
> armada-370-seagate-personal-cloud-{1,2}.dts, etc?

Sure I can. But note that n090103 is an hardware name while Seagate
Personal Cloud is a product name. The former is unique while the latter
is not. For example, it is possible that we will see in a near future an
hardware update for the Personal Cloud.

But if you still feel it is the right way to go, I'll be glad to do the
changes.

Thanks,

Simon
-------------- next part --------------
A non-text attachment was scrubbed...
Name: signature.asc
Type: application/pgp-signature
Size: 181 bytes
Desc: Digital signature
URL: <http://lists.infradead.org/pipermail/linux-arm-kernel/attachments/20150831/888a4915/attachment.sig>

From jason at lakedaemon.net  Mon Aug 31 05:59:26 2015
From: jason at lakedaemon.net (Jason Cooper)
Date: Mon, 31 Aug 2015 12:59:26 +0000
Subject: [PATCH 2/3] ARM: mvebu: add DT support for Seagate Personal Cloud
In-Reply-To: <1440866805-31731-3-git-send-email-simon.guinot@sequanux.org>
References: <1440866805-31731-1-git-send-email-simon.guinot@sequanux.org>
 <1440866805-31731-3-git-send-email-simon.guinot@sequanux.org>
Message-ID: <20150831125926.GL3684@io.lakedaemon.net>

On Sat, Aug 29, 2015 at 06:46:44PM +0200, Simon Guinot wrote:
> This patch adds DT support for the Seagate Personal Cloud 1 and 2-Bay
> (n090103 and n090203).
> 
> Chipset list:
> - SoC Marvell Armada 370 88F6707, CPU @1GHz
> - SDRAM memory: 512MB DDR3 667MHz (16-bits bandwidth)
> - SPI flash 1MB (Macronix MX25L8006E)
> - 1 or 2 SATA internal ports
> - 1 Ethernet Gigabit port (PHY Marvell 88E1518)
> - 1 USB3 host port (PCIe controller ASM1042)
> - 1 USB2 host port (SoC)
> - 2 push buttons (power and reset)
> - 1 SATA LED (bi-color, white and red)

Do you have long term URLs for these products?  It would be nice to add
those.  The best I could find is:

  http://www.seagate.com/www-content/product-content/personal-cloud/en-us/doc/personal-cloud-ds1838-1-1501us.pdf

But none of the model numbers match what you've used in this patch
series.  I imagine this will make it harder for newcomers to find the
relevant code.

> Note that support for the white SATA LED is missing. A dedicated LED
> driver is needed.
> 
> Signed-off-by: Simon Guinot <simon.guinot at sequanux.org>
> ---
>  arch/arm/boot/dts/Makefile                |   2 +
>  arch/arm/boot/dts/armada-370-n090103.dts  |  28 +++++
>  arch/arm/boot/dts/armada-370-n090203.dts  |  42 ++++++++
>  arch/arm/boot/dts/armada-370-n090x03.dtsi | 174 ++++++++++++++++++++++++++++++
>  4 files changed, 246 insertions(+)
>  create mode 100644 arch/arm/boot/dts/armada-370-n090103.dts
>  create mode 100644 arch/arm/boot/dts/armada-370-n090203.dts
>  create mode 100644 arch/arm/boot/dts/armada-370-n090x03.dtsi
> 

...

> diff --git a/arch/arm/boot/dts/armada-370-n090103.dts b/arch/arm/boot/dts/armada-370-n090103.dts
> new file mode 100644
> index 000000000000..c94bed449050
> --- /dev/null
> +++ b/arch/arm/boot/dts/armada-370-n090103.dts
> @@ -0,0 +1,28 @@
> +/*
> + * Device Tree file for Seagate Personal Cloud NAS (n090103).
> + *
> + * Copyright (C) 2015 Seagate
> + *
> + * Author: Simon Guinot <simon.guinot at sequanux.org>
> + *
> + * This file is licensed under the terms of the GNU General Public
> + * License version 2.  This program is licensed "as is" without any
> + * warranty of any kind, whether express or implied.
> + */

Based on previous discussions, I'm pretty sure I know what the answer
is, but I have to at least ask in case it was accidental.  All other
armada-* files are dual licensed, GPLv2/X11.  Was it intentional to
license these as GPLv2 only?

> +
> +/dts-v1/;
> +#include "armada-370-n090x03.dtsi"
> +
> +/ {
> +	model = "Seagate Personal Cloud";
> +	compatible = "seagate,n090103", "marvell,armada370", "marvell,armada-370-xp";

In line with my previous comment, can we add a compatible string here?

	compatible = "seagate,n090103", "seagate,personalcloud", "marvell,armada370", "marvell,armada-370-xp";

> diff --git a/arch/arm/boot/dts/armada-370-n090203.dts b/arch/arm/boot/dts/armada-370-n090203.dts
> new file mode 100644
> index 000000000000..3bc62b9f0b0c
> --- /dev/null
> +++ b/arch/arm/boot/dts/armada-370-n090203.dts
> @@ -0,0 +1,42 @@
> +/*
> + * Device Tree file for Seagate Personnal Cloud 2-Bay NAS (n090203).
> + *
> + * Copyright (C) 2015 Seagate
> + *
> + * Author: Simon Guinot <simon.guinot at sequanux.org>
> + *
> + * This file is licensed under the terms of the GNU General Public
> + * License version 2.  This program is licensed "as is" without any
> + * warranty of any kind, whether express or implied.
> + */
> +
> +/dts-v1/;
> +#include "armada-370-n090x03.dtsi"
> +
> +/ {
> +	model = "Seagate Personnal Cloud 2-Bay";
> +	compatible = "seagate,n090203", "marvell,armada370", "marvell,armada-370-xp";

And then here:

	compatible = "seagate,n090103", "seagate,personalcloud2", "marvell,armada370", "marvell,armada-370-xp";

or similar.

The same comments apply to the NAS versions as well.

thx,

Jason.


From jason at lakedaemon.net  Mon Aug 31 06:03:38 2015
From: jason at lakedaemon.net (Jason Cooper)
Date: Mon, 31 Aug 2015 13:03:38 +0000
Subject: [PATCH 0/3] Add support for the Armada-370-based Seagate NAS
In-Reply-To: <20150831130236.GN30993@kw.sim.vm.gnt>
References: <1440866805-31731-1-git-send-email-simon.guinot@sequanux.org>
 <20150831123944.GK3684@io.lakedaemon.net>
 <20150831130236.GN30993@kw.sim.vm.gnt>
Message-ID: <20150831130337.GM3684@io.lakedaemon.net>

On Mon, Aug 31, 2015 at 03:02:36PM +0200, Simon Guinot wrote:
> On Mon, Aug 31, 2015 at 12:39:44PM +0000, Jason Cooper wrote:
> > On Sat, Aug 29, 2015 at 06:46:42PM +0200, Simon Guinot wrote:
> > > Hi,
> > > 
> > > This patch series adds support for the Seagate machines based on the
> > > Armada-370 Marvell SoC. This includes the Personal Cloud 1 and 2-Bay
> > > and the Seagate NAS 2 and 4-Bay.
> > > 
> > > Thanks,
> > > 
> > > Simon
> > > 
> > > Simon Guinot (2):
> > >   ARM: mvebu: add DT support for Seagate Personal Cloud
> > >   ARM: mvebu: enable options for Seagate NAS in mvebu_v7_defconfig
> > > 
> > > Vincent Donnefort (1):
> > >   ARM: mvebu: add DT support for Seagate NAS 2 and 4-Bay
> > > 
> > >  arch/arm/boot/dts/Makefile                |   4 +
> > >  arch/arm/boot/dts/armada-370-n090103.dts  |  28 ++++
> > >  arch/arm/boot/dts/armada-370-n090201.dts  |  28 ++++
> > >  arch/arm/boot/dts/armada-370-n090203.dts  |  42 ++++++
> > >  arch/arm/boot/dts/armada-370-n090401.dts  | 124 ++++++++++++++++
> > >  arch/arm/boot/dts/armada-370-n090x01.dtsi | 232 ++++++++++++++++++++++++++++++
> > >  arch/arm/boot/dts/armada-370-n090x03.dtsi | 174 ++++++++++++++++++++++
> > >  arch/arm/configs/mvebu_v7_defconfig       |   9 +-
> > >  8 files changed, 640 insertions(+), 1 deletion(-)
> > >  create mode 100644 arch/arm/boot/dts/armada-370-n090103.dts
> > >  create mode 100644 arch/arm/boot/dts/armada-370-n090201.dts
> > >  create mode 100644 arch/arm/boot/dts/armada-370-n090203.dts
> > >  create mode 100644 arch/arm/boot/dts/armada-370-n090401.dts
> > >  create mode 100644 arch/arm/boot/dts/armada-370-n090x01.dtsi
> > >  create mode 100644 arch/arm/boot/dts/armada-370-n090x03.dtsi
> 
> Hi Jason,
> 
> > 
> > Could you please name these something more informative?  e.g.
> > armada-370-seagate-personal-cloud-{1,2}.dts, etc?
> 
> Sure I can. But note that n090103 is an hardware name while Seagate
> Personal Cloud is a product name. The former is unique while the latter
> is not. For example, it is possible that we will see in a near future an
> hardware update for the Personal Cloud.

Understood, but I'd also like to make it a bit easier for hackers not
intimately familiar with the tree/products to find the file they are
interested in.

I've no problem with 'armada-370-seagate-personalcloud-n090103.dts'
either.

thx,

Jason.


From simon.guinot at sequanux.org  Mon Aug 31 06:13:06 2015
From: simon.guinot at sequanux.org (Simon Guinot)
Date: Mon, 31 Aug 2015 15:13:06 +0200
Subject: [PATCH 1/3] ARM: mvebu: add DT support for Seagate NAS 2 and 4-Bay
In-Reply-To: <20150831124314.GE14459@lunn.ch>
References: <1440866805-31731-1-git-send-email-simon.guinot@sequanux.org>
 <1440866805-31731-2-git-send-email-simon.guinot@sequanux.org>
 <20150831124314.GE14459@lunn.ch>
Message-ID: <20150831131306.GO30993@kw.sim.vm.gnt>

On Mon, Aug 31, 2015 at 02:43:14PM +0200, Andrew Lunn wrote:
> On Sat, Aug 29, 2015 at 06:46:43PM +0200, Simon Guinot wrote:
> > From: Vincent Donnefort <vdonnefort at gmail.com>
> > 
> > This patch adds DT support for the Seagate NAS 2 and 4-Bay (n090201 and
> > n090401).
> > 
> > Chipset list (common):
> > - SoC Marvell Armada 370 88F6707, CPU @1.2GHz
> > - SDRAM memory: 512MB DDR3 600MHz (16-bits bandwidth)
> > - NAND flash 256MB, 8-bits (Micron MT29F2G08AAB or Hinyx H27U2G8F2CTR-BC)
> > - 2 SATA II ports (SoC)
> > - 1 Ethernet Gigabit ports (PHY Marvell 88E1518)
> > - 2 USB3 host ports (PCIe controller ASM1042)
> > - GPIO fan (4 speeds)
> > - External I2C RTC (MCP7940NT)
> > - 3 push buttons (power, backup and reset)
> > - 2 SATA LEDs (bi-color, blue and red)
> > - 1 power LED (bi-color, blue and red)
> > 
> > Only on 4-Bay models:
> > - 2 extra SATA III ports (PCIe AHCI controller Marvell 88SE9170)
> > - 1 extra Ethernet Gigabit ports (PHY Marvell 88E1518)
> > - I2C GPIO expander (PCA9554A)
> > - 2 extra SATA LEDs (bi-color, blue and red)
> > 
> > Note that support for the white SATA LEDs associated with HDDs 0 and 1
> > is missing. A dedicated LED driver is needed.
> > 
> > Signed-off-by: Vincent Donnefort <vdonnefort at gmail.com>
> > ---
> >  arch/arm/boot/dts/Makefile                |   2 +
> >  arch/arm/boot/dts/armada-370-n090201.dts  |  28 ++++
> >  arch/arm/boot/dts/armada-370-n090401.dts  | 124 ++++++++++++++++
> >  arch/arm/boot/dts/armada-370-n090x01.dtsi | 232 ++++++++++++++++++++++++++++++
> >  4 files changed, 386 insertions(+)
> >  create mode 100644 arch/arm/boot/dts/armada-370-n090201.dts
> >  create mode 100644 arch/arm/boot/dts/armada-370-n090401.dts
> >  create mode 100644 arch/arm/boot/dts/armada-370-n090x01.dtsi
> > 
> > diff --git a/arch/arm/boot/dts/Makefile b/arch/arm/boot/dts/Makefile
> > index 233159d2eaab..0a46613e90d2 100644
> > --- a/arch/arm/boot/dts/Makefile
> > +++ b/arch/arm/boot/dts/Makefile
> > @@ -699,6 +699,8 @@ dtb-$(CONFIG_MACH_ARMADA_370) += \
> >  	armada-370-db.dtb \
> >  	armada-370-dlink-dns327l.dtb \
> >  	armada-370-mirabox.dtb \
> > +	armada-370-n090201.dtb \
> > +	armada-370-n090401.dtb \
> >  	armada-370-netgear-rn102.dtb \
> >  	armada-370-netgear-rn104.dtb \
> >  	armada-370-rd.dtb \
> > diff --git a/arch/arm/boot/dts/armada-370-n090201.dts b/arch/arm/boot/dts/armada-370-n090201.dts
> > new file mode 100644
> > index 000000000000..b92b1ee067d6
> > --- /dev/null
> > +++ b/arch/arm/boot/dts/armada-370-n090201.dts
> > @@ -0,0 +1,28 @@
> > +/*
> > + * Device Tree file for Seagate NAS 2-Bay (n090201)
> > + *
> > + * Copyright (C) 2015 Seagate
> > + *
> > + * Author: Vincent Donnefort <vdonnefort at gmail.com>
> > + *
> > + * This file is licensed under the terms of the GNU General Public
> > + * License version 2.  This program is licensed "as is" without any
> > + * warranty of any kind, whether express or implied.
> > + */
> > +
> > +/dts-v1/;
> > +
> > +#include "armada-370-n090x01.dtsi"
> > +
> > +/ {
> > +	model = "Seagate NAS 2-Bay";

Hi Andrew,

> 
> On a similar line to Jason's comment. I'm sure Seagate has/is going to
> have more than this 2-bay NAS. Can we have a more descriptive model
> string here?

It may sound crazy but I have nothing more than the hardware and product
names which are respectively "n090201" and "Seagate NAS 2-Bay" for this
board.

Maybe I could mix them both in the model string:
"Seagate NAS 2-Bay (n090201)" ?

> 
> I could imagine an installer which looks through the list of available
> DT blobs and creates a list showing the model and compatible string,
> and asks the user, which should it use.

I can too.

Simon
-------------- next part --------------
A non-text attachment was scrubbed...
Name: signature.asc
Type: application/pgp-signature
Size: 181 bytes
Desc: Digital signature
URL: <http://lists.infradead.org/pipermail/linux-arm-kernel/attachments/20150831/81d47cba/attachment.sig>

From leo.yan at linaro.org  Mon Aug 31 06:12:44 2015
From: leo.yan at linaro.org (Leo Yan)
Date: Mon, 31 Aug 2015 21:12:44 +0800
Subject: [PATCH 2/2] arm64: dts: add dts files for Hisilicon Hip05-D02
 Development Board
In-Reply-To: <1440838361-1468-3-git-send-email-dingtianhong@huawei.com>
References: <1440838361-1468-1-git-send-email-dingtianhong@huawei.com>
 <1440838361-1468-3-git-send-email-dingtianhong@huawei.com>
Message-ID: <20150831131244.GB6194@leoy-linaro>

On Sat, Aug 29, 2015 at 04:52:41PM +0800, Ding Tianhong wrote:
> Add initial dtsi file to support Hisilicon Hip05-D02 Board with
> support of CPUs in four clusters and each cluster has quard Cortex-A57.
> 
> Also add dts file to support Hip05-D02 development board.
> 
> Signed-off-by: Ding Tianhong <dingtianhong at huawei.com>
> Signed-off-by: Kefeng Wang <wangkefeng.wang at huawei.com>
> ---
>  arch/arm64/boot/dts/hisilicon/Makefile      |   2 +-
>  arch/arm64/boot/dts/hisilicon/hip05-d02.dts |  36 ++++
>  arch/arm64/boot/dts/hisilicon/hip05.dtsi    | 271 ++++++++++++++++++++++++++++
>  3 files changed, 308 insertions(+), 1 deletion(-)
>  create mode 100644 arch/arm64/boot/dts/hisilicon/hip05-d02.dts
>  create mode 100644 arch/arm64/boot/dts/hisilicon/hip05.dtsi
> 
> diff --git a/arch/arm64/boot/dts/hisilicon/Makefile b/arch/arm64/boot/dts/hisilicon/Makefile
> index fa81a6e..cd158b8 100644
> --- a/arch/arm64/boot/dts/hisilicon/Makefile
> +++ b/arch/arm64/boot/dts/hisilicon/Makefile
> @@ -1,4 +1,4 @@
> -dtb-$(CONFIG_ARCH_HISI) += hi6220-hikey.dtb
> +dtb-$(CONFIG_ARCH_HISI) += hi6220-hikey.dtb hip05-d02.dtb
>  
>  always		:= $(dtb-y)
>  subdir-y	:= $(dts-dirs)
> diff --git a/arch/arm64/boot/dts/hisilicon/hip05-d02.dts b/arch/arm64/boot/dts/hisilicon/hip05-d02.dts
> new file mode 100644
> index 0000000..ae34e25
> --- /dev/null
> +++ b/arch/arm64/boot/dts/hisilicon/hip05-d02.dts
> @@ -0,0 +1,36 @@
> +/**
> + * dts file for Hisilicon D02 Development Board
> + *
> + * Copyright (C) 2014,2015 Hisilicon Ltd.
> + *
> + * 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
> + * publishhed by the Free Software Foundation.
> + *
> + */
> +
> +/dts-v1/;
> +
> +#include "hip05.dtsi"
> +
> +/ {
> +	model = "Hisilicon Hip05 D02 Development Board";
> +	compatible = "hisilicon,hip05-d02";
> +
> +	memory at 00000000 {
> +		device_type = "memory";
> +		reg = <0x0 0x00000000 0x0 0x80000000>;
> +	};
> +
> +	aliases {
> +		serial0 = &uart0;
> +	};
> +
> +	chosen {
> +		stdout-path = "serial0:115200n8";
> +	};
> +};
> +
> +&uart0 {
> +	status = "ok";
> +};
> diff --git a/arch/arm64/boot/dts/hisilicon/hip05.dtsi b/arch/arm64/boot/dts/hisilicon/hip05.dtsi
> new file mode 100644
> index 0000000..da12d94
> --- /dev/null
> +++ b/arch/arm64/boot/dts/hisilicon/hip05.dtsi
> @@ -0,0 +1,271 @@
> +/**
> + * dts file for Hisilicon D02 Development Board
> + *
> + * Copyright (C) 2014,2015 Hisilicon Ltd.
> + *
> + * 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
> + * publishhed by the Free Software Foundation.
> + *
> + */
> +
> +#include <dt-bindings/interrupt-controller/arm-gic.h>
> +
> +/ {
> +	compatible = "hisilicon,hip05-d02";
> +	interrupt-parent = <&gic>;
> +	#address-cells = <2>;
> +	#size-cells = <2>;
> +
> +	psci {
> +		compatible = "arm,psci-0.2";
> +		method = "smc";
> +	};
> +
> +	cpus {
> +		#address-cells = <1>;
> +		#size-cells = <0>;
> +
> +		cpu-map {
> +			cluster0 {
> +				core0 {
> +					cpu = <&cpu0>;
> +				};
> +				core1 {
> +					cpu = <&cpu1>;
> +				};
> +				core2 {
> +					cpu = <&cpu2>;
> +				};
> +				core3 {
> +					cpu = <&cpu3>;
> +				};
> +			};
> +			cluster1 {
> +				core0 {
> +					cpu = <&cpu4>;
> +				};
> +				core1 {
> +					cpu = <&cpu5>;
> +				};
> +				core2 {
> +					cpu = <&cpu6>;
> +				};
> +				core3 {
> +					cpu = <&cpu7>;
> +				};
> +			};
> +			cluster2 {
> +				core0 {
> +					cpu = <&cpu8>;
> +				};
> +				core1 {
> +					cpu = <&cpu9>;
> +				};
> +				core2 {
> +					cpu = <&cpu10>;
> +				};
> +				core3 {
> +					cpu = <&cpu11>;
> +				};
> +			};
> +			cluster3 {
> +				core0 {
> +					cpu = <&cpu12>;
> +				};
> +				core1 {
> +					cpu = <&cpu13>;
> +				};
> +				core2 {
> +					cpu = <&cpu14>;
> +				};
> +				core3 {
> +					cpu = <&cpu15>;
> +				};
> +			};
> +		};
> +
> +		cpu0: cpu at 20000 {
> +			device_type = "cpu";
> +			compatible = "arm,armv8";

Change to "arm,cortex-a57","arm,armv8"?

> +			reg = <0x20000>;
> +			enable-method = "psci";
> +		};
> +
> +		cpu1: cpu at 20001 {
> +			device_type = "cpu";
> +			compatible = "arm,armv8";
> +			reg = <0x20001>;
> +			enable-method = "psci";
> +		};
> +
> +		cpu2: cpu at 20002 {
> +			device_type = "cpu";
> +			compatible = "arm,armv8";
> +			reg = <0x20002>;
> +			enable-method = "psci";
> +		};
> +
> +		cpu3: cpu at 20003 {
> +			device_type = "cpu";
> +			compatible = "arm,armv8";
> +			reg = <0x20003>;
> +			enable-method = "psci";
> +		};
> +
> +		cpu4: cpu at 20100 {
> +			device_type = "cpu";
> +			compatible = "arm,armv8";
> +			reg = <0x20100>;
> +			enable-method = "psci";
> +		};
> +
> +		cpu5: cpu at 20101 {
> +			device_type = "cpu";
> +			compatible = "arm,armv8";
> +			reg = <0x20101>;
> +			enable-method = "psci";
> +		};
> +
> +		cpu6: cpu at 20102 {
> +			device_type = "cpu";
> +			compatible = "arm,armv8";
> +			reg = <0x20102>;
> +			enable-method = "psci";
> +		};
> +
> +		cpu7: cpu at 20103 {
> +			device_type = "cpu";
> +			compatible = "arm,armv8";
> +			reg = <0x20103>;
> +			enable-method = "psci";
> +		};
> +
> +		cpu8: cpu at 20200 {
> +			device_type = "cpu";
> +			compatible = "arm,armv8";
> +			reg = <0x20200>;
> +			enable-method = "psci";
> +		};
> +
> +		cpu9: cpu at 20201 {
> +			device_type = "cpu";
> +			compatible = "arm,armv8";
> +			reg = <0x20201>;
> +			enable-method = "psci";
> +		};
> +
> +		cpu10: cpu at 20202 {
> +			device_type = "cpu";
> +			compatible = "arm,armv8";
> +			reg = <0x20202>;
> +			enable-method = "psci";
> +		};
> +
> +		cpu11: cpu at 20203 {
> +			device_type = "cpu";
> +			compatible = "arm,armv8";
> +			reg = <0x20203>;
> +			enable-method = "psci";
> +		};
> +
> +		cpu12: cpu at 20300 {
> +			device_type = "cpu";
> +			compatible = "arm,armv8";
> +			reg = <0x20300>;
> +			enable-method = "psci";
> +		};
> +
> +		cpu13: cpu at 20301 {
> +			device_type = "cpu";
> +			compatible = "arm,armv8";
> +			reg = <0x20301>;
> +			enable-method = "psci";
> +		};
> +
> +		cpu14: cpu at 20302 {
> +			device_type = "cpu";
> +			compatible = "arm,armv8";
> +			reg = <0x20302>;
> +			enable-method = "psci";
> +		};
> +
> +		cpu15: cpu at 20303 {
> +			device_type = "cpu";
> +			compatible = "arm,armv8";
> +			reg = <0x20303>;
> +			enable-method = "psci";
> +		};
> +	};
> +
> +	gic: interrupt-controller at 8d000000 {
> +		compatible = "arm,gic-v3";
> +                #interrupt-cells = <3>;
> +                #address-cells = <2>;
> +                #size-cells = <2>;
> +                ranges;
> +                interrupt-controller;
> +                #redistributor-regions = <1>;
> +                redistributor-stride = <0x0 0x30000>;
> +		reg = <0x0 0x8d000000 0 0x10000>,	/* GICD */
> +		      <0x0 0x8d100000 0 0x300000>,	/* GICR */
> +		      <0x0 0xfe000000 0 0x10000>,	/* GICC */
> +		      <0x0 0xfe010000 0 0x10000>,       /* GICH */
> +		      <0x0 0xfe020000 0 0x10000>;       /* GICV */
> +		interrupts = <GIC_PPI 9 (GIC_CPU_MASK_SIMPLE(8) | IRQ_TYPE_LEVEL_HIGH)>;
> +
> +		its_totems: interrupt-controller at 8c000000 {
> +			compatible = "arm,gic-v3-its";
> +			msi-controller;
> +			reg = <0x0 0x8c000000 0x0 0x1000000>;
> +		};
> +	};
> +
> +	timer {
> +		compatible = "arm,armv8-timer";
> +		interrupts = <GIC_PPI 13 (GIC_CPU_MASK_SIMPLE(8) | IRQ_TYPE_LEVEL_LOW)>,
> +			     <GIC_PPI 14 (GIC_CPU_MASK_SIMPLE(8) | IRQ_TYPE_LEVEL_LOW)>,
> +			     <GIC_PPI 11 (GIC_CPU_MASK_SIMPLE(8) | IRQ_TYPE_LEVEL_LOW)>,
> +			     <GIC_PPI 10 (GIC_CPU_MASK_SIMPLE(8) | IRQ_TYPE_LEVEL_LOW)>;

Here have a question:
In devcie tree binding file: Documentation/devicetree/bindings/arm/gic.txt,
it only considers for maximum 8 cpus. So will we need change the
binding file and also use GIC_CPU_MASK_SIMPLE(16) for 16 cores?

> +	};
> +
> +	pmu {
> +		compatible = "arm,armv8-pmuv3";
> +		interrupts = <GIC_PPI 7 IRQ_TYPE_LEVEL_HIGH>;
> +	};
> +
> +	soc {
> +		compatible = "simple-bus";
> +		#address-cells = <2>;
> +		#size-cells = <2>;
> +		ranges;
> +
> +		refclk200mhz: refclk200mhz {
> +			compatible = "fixed-clock";
> +			#clock-cells = <0>;
> +			clock-frequency = <200000000>;
> +		};
> +
> +		uart0: uart at 80300000 {
> +			compatible = "snps,dw-apb-uart";
> +			reg = <0x0 0x80300000 0x0 0x10000>;
> +			interrupts = <GIC_SPI 317 IRQ_TYPE_LEVEL_HIGH>;
> +			clocks = <&refclk200mhz>;
> +			clock-names = "apb_pclk";
> +			reg-shift = <2>;
> +			reg-io-width = <4>;
> +			status = "disabled";
> +		};
> +
> +		uart1: uart at 80310000 {
> +			compatible = "snps,dw-apb-uart";
> +			reg = <0x0 0x80310000 0x0 0x10000>;
> +			interrupts = <GIC_SPI 318 IRQ_TYPE_LEVEL_HIGH>;
> +			clocks = <&refclk200mhz>;
> +			clock-names = "apb_pclk";
> +			reg-shift = <2>;
> +			reg-io-width = <4>;
> +			status = "disabled";
> +		};
> +	};
> +};
> -- 
> 1.9.0
> 
> 
> 
> _______________________________________________
> linux-arm-kernel mailing list
> linux-arm-kernel at lists.infradead.org
> http://lists.infradead.org/mailman/listinfo/linux-arm-kernel


From andrew at lunn.ch  Mon Aug 31 06:11:19 2015
From: andrew at lunn.ch (Andrew Lunn)
Date: Mon, 31 Aug 2015 15:11:19 +0200
Subject: Trying to get a Pogoplug v4 board description added
In-Reply-To: <CAAKvOSg7h=YOVWQ1gKLv-WGw6BGF_rBfp+Zb=za7FkKE2Zwbhg@mail.gmail.com>
References: <CAAKvOShfrRn-E9o2Gjek5xb8xfGucUmO_FRu7c3T7S2V=co-2g@mail.gmail.com>
 <20150829153646.GB31545@lunn.ch>
 <CAAKvOSg7h=YOVWQ1gKLv-WGw6BGF_rBfp+Zb=za7FkKE2Zwbhg@mail.gmail.com>
Message-ID: <20150831131119.GF14459@lunn.ch>

Hi Andrew

Once you have the copyright and licence sort out, we should have a
header here with this information.

> >> kirkwood-pogoplug_v4.dts
> >> /dts-v1/;
> >>
> >> #include "kirkwood.dtsi"
> >> #include "kirkwood-6192.dtsi"
> >>
> >> / {
> >>         model = "Pogoplug v4";
> >>         compatible = "cloudengines,pogoplug-v4",
> >> "cloudengines,pogoplug-mobile", "marvell,kirkwood-88f6192",
> >> "marvell,kirkwood";
> >>
> >>         memory {
> >>                 device_type = "memory";
> >>                 reg = <0x00000000 0x8000000>;
> >>         };
> >>
> >>         chosen {
> >>                 bootargs = "console=ttyS0,115200";
> >>                 stdout-path = &uart0;

You can combine this into one line:

    		     stdout-path = "uart0:115200n8"

I don't think any Kirkwood boards do this yet, but it should work.

> >>         };
> >>
> >>         mbus {
> >>                 pcie-controller {
> >>                         status = "okay";
> >>
> >>                         pcie at 1,0 {
> >>                                 status = "okay";
> >>                         };

Optional, but it is nice to comment on what is connected to the PCIe
bus. I think it is the USB 3 controller? Adding the make model makes
it easier for people to get the driver build into the kernel or as a
module.

> >>                 };
> >>         };
> >>
> >>         ocp at f1000000 {
> >>                 pinctrl: pin-controller at 10000 {
> >>                         pmx_led_green: pmx-led-green {
> >>                                 marvell,pins = "mpp22";
> >>                                 marvell,function = "gpio";
> >>                         };
> >>                         pmx_led_red: pmx-led-red {
> >>                                 marvell,pins = "mpp24";
> >>                                 marvell,function = "gpio";
> >>                         };
> >>                         pmx_button_eject: pmx-button-eject {
> >>                                 marvell,pins = "mpp29";
> >>                                 marvell,function = "gpio";
> >>                         };
> >>                 };
> >>
> >>                 serial at 12000 {
> >>                         status = "okay";
> >>                 };
> >>
> >>                 sata at 80000 {
> >>                         status = "okay";
> >>                         nr-ports = <1>;
> >>                         phys = <&sata_phy0>;
> >>                         phy-names = "port0";

You should not need these last two lines. They are provided by the
.dtsi file.

> >>                 };
> >>
> >>                 mvsdio at 90000 {
> >>                         pinctrl-0 = <&pmx_sdio>;
> >>                         pinctrl-names = "default";
> >>                         status = "okay";
> >>                         cd-gpios = <&gpio0 27 GPIO_ACTIVE_HIGH>;

You should have a pinmux definition for this. See for example
kirkwood-sheevaplug-esata.dts and kirkwood-sheevaplug-common.dtsi

> >>                         /* No WP GPIO */
> >>                 };
> >>         };
> >>
> >>         gpio-leds {
> >>                 compatible = "gpio-leds";
> >>                 pinctrl-0 = <&pmx_led_red &pmx_led_green>;
> >>                 pinctrl-names = "default";
> >>
> >>                 health {
> >>                         label = "status:green:health";
> >>                         gpios = <&gpio0 22 GPIO_ACTIVE_LOW>;
> >>                         default-state = "keep";
> >>                 };
> >>                 fault {
> >>                         label = "status:red:fault";
> >>                         gpios = <&gpio0 24 GPIO_ACTIVE_LOW>;
> >>                 };

A common problem here, the labels don't fit what is documented.
Documentation/leds/leds.txt says:

"devicename:colour:function"

so you should change status to pogoplugv4

> >>         };
> >>

Please also add this file to the Makefile, keeping things in order.

       Andrew


From leilk.liu at mediatek.com  Mon Aug 31 06:18:55 2015
From: leilk.liu at mediatek.com (Leilk Liu)
Date: Mon, 31 Aug 2015 21:18:55 +0800
Subject: [PATCH 0/3] Fix Mediatek SPI bus driver clock usage error
Message-ID: <1441027138-16458-1-git-send-email-leilk.liu@mediatek.com>

From: Leilk Liu <leilk.liu at mediatek.com>

This series are based on 4.2-rc1 and provide three patches
to fix mediatek spi driver clock usage error.

spi clock manages flow:
  CLK_TOP_SYSPLL3_D2 ---> CLK_TOP_SPI_SEL ---> CLK_PERI_SPI0
    (source clock)           (clock mux)       (clock gate)
spi driver should choose source clock by clock mux, then enable clock gate.

Leilk Liu (3):
  spi: mediatek: remove clk_disable_unprepare()
  spi: mediatek: fix spi clock usage error
  spi: Mediatek: Document devicetree bindings update for spi bus

 .../devicetree/bindings/spi/spi-mt65xx.txt         | 16 +++++++++------
 drivers/spi/spi-mt65xx.c                           | 24 ++++++++++++++--------
 2 files changed, 25 insertions(+), 15 deletions(-)

--
1.8.1.1.dirty



From leilk.liu at mediatek.com  Mon Aug 31 06:18:57 2015
From: leilk.liu at mediatek.com (Leilk Liu)
Date: Mon, 31 Aug 2015 21:18:57 +0800
Subject: [PATCH 2/3] spi: mediatek: fix spi clock usage error
In-Reply-To: <1441027138-16458-1-git-send-email-leilk.liu@mediatek.com>
References: <1441027138-16458-1-git-send-email-leilk.liu@mediatek.com>
Message-ID: <1441027138-16458-3-git-send-email-leilk.liu@mediatek.com>

spi clock manages flow:
  CLK_TOP_SYSPLL3_D2 ---> CLK_TOP_SPI_SEL ---> CLK_PERI_SPI0
     (source clock)           (clock mux)       (clock gate)
spi driver should choose source clock by clock mux, then enable
clock gate.

Signed-off-by: Leilk Liu <leilk.liu at mediatek.com>
---
 drivers/spi/spi-mt65xx.c | 23 +++++++++++++++--------
 1 file changed, 15 insertions(+), 8 deletions(-)

diff --git a/drivers/spi/spi-mt65xx.c b/drivers/spi/spi-mt65xx.c
index 3a177d0..5ecd644 100644
--- a/drivers/spi/spi-mt65xx.c
+++ b/drivers/spi/spi-mt65xx.c
@@ -85,7 +85,7 @@ struct mtk_spi {
 	void __iomem *base;
 	u32 state;
 	u32 pad_sel;
-	struct clk *spi_clk, *parent_clk;
+	struct clk *parent_clk, *sel_clk, *spi_clk;
 	struct spi_transfer *cur_transfer;
 	u32 xfer_len;
 	struct scatterlist *tx_sgl, *rx_sgl;
@@ -576,17 +576,24 @@ static int mtk_spi_probe(struct platform_device *pdev)
 		goto err_put_master;
 	}
 
-	mdata->spi_clk = devm_clk_get(&pdev->dev, "spi-clk");
-	if (IS_ERR(mdata->spi_clk)) {
+	mdata->parent_clk = devm_clk_get(&pdev->dev, "parent-clk");
+	if (IS_ERR(mdata->parent_clk)) {
+		ret = PTR_ERR(mdata->parent_clk);
+		dev_err(&pdev->dev, "failed to get parent-clk: %d\n", ret);
+		goto err_put_master;
+	}
+
+	mdata->sel_clk = devm_clk_get(&pdev->dev, "sel-clk");
+	if (IS_ERR(mdata->sel_clk)) {
 		ret = PTR_ERR(mdata->spi_clk);
-		dev_err(&pdev->dev, "failed to get spi-clk: %d\n", ret);
+		dev_err(&pdev->dev, "failed to get sel-clk: %d\n", ret);
 		goto err_put_master;
 	}
 
-	mdata->parent_clk = devm_clk_get(&pdev->dev, "parent-clk");
-	if (IS_ERR(mdata->parent_clk)) {
+	mdata->spi_clk = devm_clk_get(&pdev->dev, "spi-clk");
+	if (IS_ERR(mdata->spi_clk)) {
 		ret = PTR_ERR(mdata->parent_clk);
-		dev_err(&pdev->dev, "failed to get parent-clk: %d\n", ret);
+		dev_err(&pdev->dev, "failed to get spi-clk: %d\n", ret);
 		goto err_put_master;
 	}
 
@@ -596,7 +603,7 @@ static int mtk_spi_probe(struct platform_device *pdev)
 		goto err_put_master;
 	}
 
-	ret = clk_set_parent(mdata->spi_clk, mdata->parent_clk);
+	ret = clk_set_parent(mdata->sel_clk, mdata->parent_clk);
 	if (ret < 0) {
 		dev_err(&pdev->dev, "failed to clk_set_parent (%d)\n", ret);
 		goto err_disable_clk;
-- 
1.8.1.1.dirty



From leilk.liu at mediatek.com  Mon Aug 31 06:18:56 2015
From: leilk.liu at mediatek.com (Leilk Liu)
Date: Mon, 31 Aug 2015 21:18:56 +0800
Subject: [PATCH 1/3] spi: mediatek: remove clk_disable_unprepare()
In-Reply-To: <1441027138-16458-1-git-send-email-leilk.liu@mediatek.com>
References: <1441027138-16458-1-git-send-email-leilk.liu@mediatek.com>
Message-ID: <1441027138-16458-2-git-send-email-leilk.liu@mediatek.com>

This patch removes clk_disable_unprepare() in mtk_spi_remove().
clk_disable_prepare/unprepare must be balance, spi-clk is disabled
in mtk_spi_probe, so not needs to disable again.

Signed-off-by: Leilk Liu <leilk.liu at mediatek.com>
---
 drivers/spi/spi-mt65xx.c | 1 -
 1 file changed, 1 deletion(-)

diff --git a/drivers/spi/spi-mt65xx.c b/drivers/spi/spi-mt65xx.c
index d882261..3a177d0 100644
--- a/drivers/spi/spi-mt65xx.c
+++ b/drivers/spi/spi-mt65xx.c
@@ -630,7 +630,6 @@ static int mtk_spi_remove(struct platform_device *pdev)
 	pm_runtime_disable(&pdev->dev);
 
 	mtk_spi_reset(mdata);
-	clk_disable_unprepare(mdata->spi_clk);
 	spi_master_put(master);
 
 	return 0;
-- 
1.8.1.1.dirty



From leilk.liu at mediatek.com  Mon Aug 31 06:18:58 2015
From: leilk.liu at mediatek.com (Leilk Liu)
Date: Mon, 31 Aug 2015 21:18:58 +0800
Subject: [PATCH 3/3] spi: Mediatek: Document devicetree bindings update for
 spi bus
In-Reply-To: <1441027138-16458-1-git-send-email-leilk.liu@mediatek.com>
References: <1441027138-16458-1-git-send-email-leilk.liu@mediatek.com>
Message-ID: <1441027138-16458-4-git-send-email-leilk.liu@mediatek.com>

This patch updates spi bindings, fixs clock usage description.

Signed-off-by: Leilk Liu <leilk.liu at mediatek.com>
---
 Documentation/devicetree/bindings/spi/spi-mt65xx.txt | 16 ++++++++++------
 1 file changed, 10 insertions(+), 6 deletions(-)

diff --git a/Documentation/devicetree/bindings/spi/spi-mt65xx.txt b/Documentation/devicetree/bindings/spi/spi-mt65xx.txt
index dcefc43..6160ffb 100644
--- a/Documentation/devicetree/bindings/spi/spi-mt65xx.txt
+++ b/Documentation/devicetree/bindings/spi/spi-mt65xx.txt
@@ -15,17 +15,18 @@ Required properties:
 - interrupts: Should contain spi interrupt
 
 - clocks: phandles to input clocks.
-  The first should be <&topckgen CLK_TOP_SPI_SEL>.
-  The second should be one of the following.
+  The first should be one of the following. It's PLL.
    -  <&clk26m>: specify parent clock 26MHZ.
    -  <&topckgen CLK_TOP_SYSPLL3_D2>: specify parent clock 109MHZ.
 				      It's the default one.
    -  <&topckgen CLK_TOP_SYSPLL4_D2>: specify parent clock 78MHZ.
    -  <&topckgen CLK_TOP_UNIVPLL2_D4>: specify parent clock 104MHZ.
    -  <&topckgen CLK_TOP_UNIVPLL1_D8>: specify parent clock 78MHZ.
+  The second should be <&topckgen CLK_TOP_SPI_SEL>. It's clock mux.
+  The third is <&pericfg CLK_PERI_SPI0>. It's clock gate.
 
-- clock-names: shall be "spi-clk" for the controller clock, and
-  "parent-clk" for the parent clock.
+- clock-names: shall be "parent-clk" for the parent clock, "sel-clk" for the
+  muxes clock, and "spi-clk" for the clock gate.
 
 Optional properties:
 - mediatek,pad-select: specify which pins group(ck/mi/mo/cs) spi
@@ -44,8 +45,11 @@ spi: spi at 1100a000 {
 	#size-cells = <0>;
 	reg = <0 0x1100a000 0 0x1000>;
 	interrupts = <GIC_SPI 110 IRQ_TYPE_LEVEL_LOW>;
-	clocks = <&topckgen CLK_TOP_SPI_SEL>, <&topckgen CLK_TOP_SYSPLL3_D2>;
-	clock-names = "spi-clk", "parent-clk";
+	clocks = <&topckgen CLK_TOP_SYSPLL3_D2>,
+		 <&topckgen CLK_TOP_SPI_SEL>,
+		 <&pericfg CLK_PERI_SPI0>;
+	clock-names = "parent-clk", "sel-clk", "spi-clk";
+
 	mediatek,pad-select = <0>;
 	status = "disabled";
 };
-- 
1.8.1.1.dirty



From andrew at lunn.ch  Mon Aug 31 06:16:10 2015
From: andrew at lunn.ch (Andrew Lunn)
Date: Mon, 31 Aug 2015 15:16:10 +0200
Subject: [PATCH 1/3] ARM: mvebu: add DT support for Seagate NAS 2 and 4-Bay
In-Reply-To: <20150831131306.GO30993@kw.sim.vm.gnt>
References: <1440866805-31731-1-git-send-email-simon.guinot@sequanux.org>
 <1440866805-31731-2-git-send-email-simon.guinot@sequanux.org>
 <20150831124314.GE14459@lunn.ch>
 <20150831131306.GO30993@kw.sim.vm.gnt>
Message-ID: <20150831131610.GG14459@lunn.ch>

> It may sound crazy but I have nothing more than the hardware and product
> names which are respectively "n090201" and "Seagate NAS 2-Bay" for this
> board.

Does it have a plate on the back with identification information? Is
this n090201 on the ID plate?

     Thanks
	Andrew


From bhelgaas at google.com  Mon Aug 31 06:28:03 2015
From: bhelgaas at google.com (Bjorn Helgaas)
Date: Mon, 31 Aug 2015 08:28:03 -0500
Subject: [PATCH] ARM64: PCI: do not enable resources on PROBE_ONLY systems
In-Reply-To: <20150829124457.GA18125@red-moon>
References: <1438262039-32085-1-git-send-email-lorenzo.pieralisi@arm.com>
 <20150828211444.GA27890@google.com>
 <20150829124457.GA18125@red-moon>
Message-ID: <20150831132803.GB647@google.com>

On Sat, Aug 29, 2015 at 01:44:57PM +0100, Lorenzo Pieralisi wrote:
> On Fri, Aug 28, 2015 at 10:14:44PM +0100, Bjorn Helgaas wrote:
> > On Thu, Jul 30, 2015 at 02:13:59PM +0100, Lorenzo Pieralisi wrote:
> > > On ARM64 PROBE_ONLY PCI systems resources are not currently claimed,
> > > therefore they can't be enabled since they do not have a valid
> > > parent pointer; this in turn prevents enabling PCI devices on
> > > ARM64 PROBE_ONLY systems, causing PCI devices initialization to
> > > fail.
> > 
> > Where does arm64 claim PCI BAR resources for the non-PROBE_ONLY case?
> 
> arm64 (and arm) does not claim resources in arch code, they are always
> assigned in the respective host controllers (or the pcibios on arm),
> except for the PCI generic host when in PROBE_ONLY mode, where resources
> are neither claimed nor assigned (the reason for this patch to exist).
> ...
> 
> > I know it must be there somewhere, but I don't see it.
> 
> It is not there, it is done in the host controllers by assigning the
> resources (which also "claim" them by assigning the parent pointer).

The host controller drivers should claim the apertures forwarded to
the PCI bus.  For pci-host-generic, this happens when
gen_pci_parse_request_of_pci_ranges() calls devm_request_resource().
But that doesn't do anything for the BARs of the PCI devices
themselves, of course.

If this patch fixes a problem that will occur in the future, when we
add arm/arm64 code to claim BARs, let's make this patch part of that
series.  If it fixes a problem in the current tree, I'll merge it now,
but so far I haven't been able to make the connection between this
patch and a problem in the current code.

> > > To solve this issue, resources must be claimed when devices are
> > > added on PROBE_ONLY systems, which ensures that the resource hierarchy
> > > is validated and the resource tree is sane, but this requires changes
> > > in the ARM64 resource management that can affect adversely existing
> > > PCI set-ups (claiming resources on !PROBE_ONLY systems might break
> > > existing ARM64 PCI platform implementations).
> > > 
> > > As a temporary solution in preparation for a proper resources claiming
> > > implementation in ARM64 core, to enable PCI PROBE_ONLY systems on ARM64,
> > > this patch adds a pcibios_enable_device() arch implementation that
> > > simply prevents enabling resources on PROBE_ONLY systems (mirroring ARM
> > > behaviour).
> > > 
> > > This is always a safe thing to do because on PROBE_ONLY systems the
> > > configuration space set-up can be considered immutable, and it is in
> > > preparation of proper resource claiming that would finally validate
> > > the PCI resources tree in the ARM64 arch implementation on PROBE_ONLY
> > > systems.
> > > 
> > > For !PROBE_ONLY systems resources enablement in pcibios_enable_device()
> > > on ARM64 is implemented as in current PCI core, leaving the behaviour
> > > unchanged.
> > > 
> > > Signed-off-by: Lorenzo Pieralisi <lorenzo.pieralisi at arm.com>
> > > Cc: Will Deacon <will.deacon at arm.com>
> > > Cc: Bjorn Helgaas <bhelgaas at google.com>
> > > Cc: Catalin Marinas <catalin.marinas at arm.com>
> > > ---
> > > Bjorn, all,
> > > 
> > > as I mention in the commit log, this patch is a temporary solution
> > > in preparation for proper resources claiming in ARM64, so that
> > > we can safely enable the PCI generic host controller on ARM64 systems.
> > > 
> > > It mirrors ARM implementation and I will work on changing both
> > > ARM and ARM64 to convert them to proper resources claiming in
> > > the respective implementations.
> > > 
> > > Lorenzo
> > > 
> > >  arch/arm64/kernel/pci.c | 13 +++++++++++++
> > >  1 file changed, 13 insertions(+)
> > > 
> > > diff --git a/arch/arm64/kernel/pci.c b/arch/arm64/kernel/pci.c
> > > index 4095379..b3d098b 100644
> > > --- a/arch/arm64/kernel/pci.c
> > > +++ b/arch/arm64/kernel/pci.c
> > > @@ -38,6 +38,19 @@ resource_size_t pcibios_align_resource(void *data, const struct resource *res,
> > >  	return res->start;
> > >  }
> > >  
> > > +/**
> > > + * pcibios_enable_device - Enable I/O and memory.
> > > + * @dev: PCI device to be enabled
> > > + * @mask: bitmask of BARs to enable
> > > + */
> > > +int pcibios_enable_device(struct pci_dev *dev, int mask)
> > > +{
> > > +	if (pci_has_flag(PCI_PROBE_ONLY))
> > > +		return 0;
> > > +
> > > +	return pci_enable_resources(dev, mask);
> > > +}
> > > +
> > >  /*
> > >   * Try to assign the IRQ number from DT when adding a new device
> > >   */
> > > -- 
> > > 2.2.1
> > > 
> > 


From leilk.liu at mediatek.com  Mon Aug 31 06:44:19 2015
From: leilk.liu at mediatek.com (Leilk Liu)
Date: Mon, 31 Aug 2015 21:44:19 +0800
Subject: [PATCH v7] arm64: dts: Add spi bus dts
Message-ID: <1441028659-19068-1-git-send-email-leilk.liu@mediatek.com>

This patch adds MT8173 spi bus controllers into device tree.

Signed-off-by: Leilk Liu <leilk.liu at mediatek.com>
---
Change in this patch:
1. fix spi clock flow usage error.
---
 arch/arm64/boot/dts/mediatek/mt8173-evb.dts | 18 ++++++++++++++++++
 arch/arm64/boot/dts/mediatek/mt8173.dtsi    | 13 +++++++++++++
 2 files changed, 31 insertions(+)

diff --git a/arch/arm64/boot/dts/mediatek/mt8173-evb.dts b/arch/arm64/boot/dts/mediatek/mt8173-evb.dts
index 4be66ca..811cb76 100644
--- a/arch/arm64/boot/dts/mediatek/mt8173-evb.dts
+++ b/arch/arm64/boot/dts/mediatek/mt8173-evb.dts
@@ -387,6 +387,24 @@
 	};
 };
 
+&pio {
+	spi_pins_a: spi0 {
+		pins_spi {
+			pinmux = <MT8173_PIN_69_SPI_CK__FUNC_SPI_CK_0_>,
+				<MT8173_PIN_70_SPI_MI__FUNC_SPI_MI_0_>,
+				<MT8173_PIN_71_SPI_MO__FUNC_SPI_MO_0_>,
+				<MT8173_PIN_72_SPI_CS__FUNC_SPI_CS_0_>;
+		};
+	};
+};
+
+&spi {
+	pinctrl-names = "default";
+	pinctrl-0 = <&spi_pins_a>;
+	mediatek,pad-select = <0>;
+	status = "okay";
+};
+
 &uart0 {
 	status = "okay";
 };
diff --git a/arch/arm64/boot/dts/mediatek/mt8173.dtsi b/arch/arm64/boot/dts/mediatek/mt8173.dtsi
index d18ee42..fcb4860 100644
--- a/arch/arm64/boot/dts/mediatek/mt8173.dtsi
+++ b/arch/arm64/boot/dts/mediatek/mt8173.dtsi
@@ -365,6 +365,19 @@
 			status = "disabled";
 		};
 
+		spi: spi at 1100a000 {
+			compatible = "mediatek,mt8173-spi";
+			#address-cells = <1>;
+			#size-cells = <0>;
+			reg = <0 0x1100a000 0 0x1000>;
+			interrupts = <GIC_SPI 110 IRQ_TYPE_LEVEL_LOW>;
+			clocks = <&topckgen CLK_TOP_SYSPLL3_D2>,
+				 <&topckgen CLK_TOP_SPI_SEL>,
+				 <&pericfg CLK_PERI_SPI0>;
+			clock-names = "parent-clk", "sel-clk", "spi-clk";
+			status = "disabled";
+		};
+
 		i2c3: i2c3 at 11010000 {
 			compatible = "mediatek,mt8173-i2c";
 			reg = <0 0x11010000 0 0x70>,
-- 
1.8.1.1.dirty



From dingtianhong at huawei.com  Mon Aug 31 06:44:38 2015
From: dingtianhong at huawei.com (Ding Tianhong)
Date: Mon, 31 Aug 2015 21:44:38 +0800
Subject: [PATCH 2/2] arm64: dts: add dts files for Hisilicon Hip05-D02
 Development Board
In-Reply-To: <20150831131244.GB6194@leoy-linaro>
References: <1440838361-1468-1-git-send-email-dingtianhong@huawei.com>
 <1440838361-1468-3-git-send-email-dingtianhong@huawei.com>
 <20150831131244.GB6194@leoy-linaro>
Message-ID: <55E45A46.7040805@huawei.com>

On 2015/8/31 21:12, Leo Yan wrote:
> On Sat, Aug 29, 2015 at 04:52:41PM +0800, Ding Tianhong wrote:
>> Add initial dtsi file to support Hisilicon Hip05-D02 Board with
>> support of CPUs in four clusters and each cluster has quard Cortex-A57.
>>
>> Also add dts file to support Hip05-D02 development board.
>>
>> Signed-off-by: Ding Tianhong <dingtianhong at huawei.com>
>> Signed-off-by: Kefeng Wang <wangkefeng.wang at huawei.com>
>> ---
>>  arch/arm64/boot/dts/hisilicon/Makefile      |   2 +-
>>  arch/arm64/boot/dts/hisilicon/hip05-d02.dts |  36 ++++
>>  arch/arm64/boot/dts/hisilicon/hip05.dtsi    | 271 ++++++++++++++++++++++++++++
>>  3 files changed, 308 insertions(+), 1 deletion(-)
>>  create mode 100644 arch/arm64/boot/dts/hisilicon/hip05-d02.dts
>>  create mode 100644 arch/arm64/boot/dts/hisilicon/hip05.dtsi
>>
>> diff --git a/arch/arm64/boot/dts/hisilicon/Makefile b/arch/arm64/boot/dts/hisilicon/Makefile
>> index fa81a6e..cd158b8 100644
>> --- a/arch/arm64/boot/dts/hisilicon/Makefile
>> +++ b/arch/arm64/boot/dts/hisilicon/Makefile
>> @@ -1,4 +1,4 @@
>> -dtb-$(CONFIG_ARCH_HISI) += hi6220-hikey.dtb
>> +dtb-$(CONFIG_ARCH_HISI) += hi6220-hikey.dtb hip05-d02.dtb
>>  
>>  always		:= $(dtb-y)
>>  subdir-y	:= $(dts-dirs)
>> diff --git a/arch/arm64/boot/dts/hisilicon/hip05-d02.dts b/arch/arm64/boot/dts/hisilicon/hip05-d02.dts
>> new file mode 100644
>> index 0000000..ae34e25
>> --- /dev/null
>> +++ b/arch/arm64/boot/dts/hisilicon/hip05-d02.dts
>> @@ -0,0 +1,36 @@
>> +/**
>> + * dts file for Hisilicon D02 Development Board
>> + *
>> + * Copyright (C) 2014,2015 Hisilicon Ltd.
>> + *
>> + * 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
>> + * publishhed by the Free Software Foundation.
>> + *
>> + */
>> +
>> +/dts-v1/;
>> +
>> +#include "hip05.dtsi"
>> +
>> +/ {
>> +	model = "Hisilicon Hip05 D02 Development Board";
>> +	compatible = "hisilicon,hip05-d02";
>> +
>> +	memory at 00000000 {
>> +		device_type = "memory";
>> +		reg = <0x0 0x00000000 0x0 0x80000000>;
>> +	};
>> +
>> +	aliases {
>> +		serial0 = &uart0;
>> +	};
>> +
>> +	chosen {
>> +		stdout-path = "serial0:115200n8";
>> +	};
>> +};
>> +
>> +&uart0 {
>> +	status = "ok";
>> +};
>> diff --git a/arch/arm64/boot/dts/hisilicon/hip05.dtsi b/arch/arm64/boot/dts/hisilicon/hip05.dtsi
>> new file mode 100644
>> index 0000000..da12d94
>> --- /dev/null
>> +++ b/arch/arm64/boot/dts/hisilicon/hip05.dtsi
>> @@ -0,0 +1,271 @@
>> +/**
>> + * dts file for Hisilicon D02 Development Board
>> + *
>> + * Copyright (C) 2014,2015 Hisilicon Ltd.
>> + *
>> + * 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
>> + * publishhed by the Free Software Foundation.
>> + *
>> + */
>> +
>> +#include <dt-bindings/interrupt-controller/arm-gic.h>
>> +
>> +/ {
>> +	compatible = "hisilicon,hip05-d02";
>> +	interrupt-parent = <&gic>;
>> +	#address-cells = <2>;
>> +	#size-cells = <2>;
>> +
>> +	psci {
>> +		compatible = "arm,psci-0.2";
>> +		method = "smc";
>> +	};
>> +
>> +	cpus {
>> +		#address-cells = <1>;
>> +		#size-cells = <0>;
>> +
>> +		cpu-map {
>> +			cluster0 {
>> +				core0 {
>> +					cpu = <&cpu0>;
>> +				};
>> +				core1 {
>> +					cpu = <&cpu1>;
>> +				};
>> +				core2 {
>> +					cpu = <&cpu2>;
>> +				};
>> +				core3 {
>> +					cpu = <&cpu3>;
>> +				};
>> +			};
>> +			cluster1 {
>> +				core0 {
>> +					cpu = <&cpu4>;
>> +				};
>> +				core1 {
>> +					cpu = <&cpu5>;
>> +				};
>> +				core2 {
>> +					cpu = <&cpu6>;
>> +				};
>> +				core3 {
>> +					cpu = <&cpu7>;
>> +				};
>> +			};
>> +			cluster2 {
>> +				core0 {
>> +					cpu = <&cpu8>;
>> +				};
>> +				core1 {
>> +					cpu = <&cpu9>;
>> +				};
>> +				core2 {
>> +					cpu = <&cpu10>;
>> +				};
>> +				core3 {
>> +					cpu = <&cpu11>;
>> +				};
>> +			};
>> +			cluster3 {
>> +				core0 {
>> +					cpu = <&cpu12>;
>> +				};
>> +				core1 {
>> +					cpu = <&cpu13>;
>> +				};
>> +				core2 {
>> +					cpu = <&cpu14>;
>> +				};
>> +				core3 {
>> +					cpu = <&cpu15>;
>> +				};
>> +			};
>> +		};
>> +
>> +		cpu0: cpu at 20000 {
>> +			device_type = "cpu";
>> +			compatible = "arm,armv8";
> 
> Change to "arm,cortex-a57","arm,armv8"?
> 

Ok?but I think should be "hisilicon,hip05","arm,armv8".

>> +			reg = <0x20000>;
>> +			enable-method = "psci";
>> +		};
>> +
>> +		cpu1: cpu at 20001 {
>> +			device_type = "cpu";
>> +			compatible = "arm,armv8";
>> +			reg = <0x20001>;
>> +			enable-method = "psci";
>> +		};
>> +
>> +		cpu2: cpu at 20002 {
>> +			device_type = "cpu";
>> +			compatible = "arm,armv8";
>> +			reg = <0x20002>;
>> +			enable-method = "psci";
>> +		};
>> +
>> +		cpu3: cpu at 20003 {
>> +			device_type = "cpu";
>> +			compatible = "arm,armv8";
>> +			reg = <0x20003>;
>> +			enable-method = "psci";
>> +		};
>> +
>> +		cpu4: cpu at 20100 {
>> +			device_type = "cpu";
>> +			compatible = "arm,armv8";
>> +			reg = <0x20100>;
>> +			enable-method = "psci";
>> +		};
>> +
>> +		cpu5: cpu at 20101 {
>> +			device_type = "cpu";
>> +			compatible = "arm,armv8";
>> +			reg = <0x20101>;
>> +			enable-method = "psci";
>> +		};
>> +
>> +		cpu6: cpu at 20102 {
>> +			device_type = "cpu";
>> +			compatible = "arm,armv8";
>> +			reg = <0x20102>;
>> +			enable-method = "psci";
>> +		};
>> +
>> +		cpu7: cpu at 20103 {
>> +			device_type = "cpu";
>> +			compatible = "arm,armv8";
>> +			reg = <0x20103>;
>> +			enable-method = "psci";
>> +		};
>> +
>> +		cpu8: cpu at 20200 {
>> +			device_type = "cpu";
>> +			compatible = "arm,armv8";
>> +			reg = <0x20200>;
>> +			enable-method = "psci";
>> +		};
>> +
>> +		cpu9: cpu at 20201 {
>> +			device_type = "cpu";
>> +			compatible = "arm,armv8";
>> +			reg = <0x20201>;
>> +			enable-method = "psci";
>> +		};
>> +
>> +		cpu10: cpu at 20202 {
>> +			device_type = "cpu";
>> +			compatible = "arm,armv8";
>> +			reg = <0x20202>;
>> +			enable-method = "psci";
>> +		};
>> +
>> +		cpu11: cpu at 20203 {
>> +			device_type = "cpu";
>> +			compatible = "arm,armv8";
>> +			reg = <0x20203>;
>> +			enable-method = "psci";
>> +		};
>> +
>> +		cpu12: cpu at 20300 {
>> +			device_type = "cpu";
>> +			compatible = "arm,armv8";
>> +			reg = <0x20300>;
>> +			enable-method = "psci";
>> +		};
>> +
>> +		cpu13: cpu at 20301 {
>> +			device_type = "cpu";
>> +			compatible = "arm,armv8";
>> +			reg = <0x20301>;
>> +			enable-method = "psci";
>> +		};
>> +
>> +		cpu14: cpu at 20302 {
>> +			device_type = "cpu";
>> +			compatible = "arm,armv8";
>> +			reg = <0x20302>;
>> +			enable-method = "psci";
>> +		};
>> +
>> +		cpu15: cpu at 20303 {
>> +			device_type = "cpu";
>> +			compatible = "arm,armv8";
>> +			reg = <0x20303>;
>> +			enable-method = "psci";
>> +		};
>> +	};
>> +
>> +	gic: interrupt-controller at 8d000000 {
>> +		compatible = "arm,gic-v3";
>> +                #interrupt-cells = <3>;
>> +                #address-cells = <2>;
>> +                #size-cells = <2>;
>> +                ranges;
>> +                interrupt-controller;
>> +                #redistributor-regions = <1>;
>> +                redistributor-stride = <0x0 0x30000>;
>> +		reg = <0x0 0x8d000000 0 0x10000>,	/* GICD */
>> +		      <0x0 0x8d100000 0 0x300000>,	/* GICR */
>> +		      <0x0 0xfe000000 0 0x10000>,	/* GICC */
>> +		      <0x0 0xfe010000 0 0x10000>,       /* GICH */
>> +		      <0x0 0xfe020000 0 0x10000>;       /* GICV */
>> +		interrupts = <GIC_PPI 9 (GIC_CPU_MASK_SIMPLE(8) | IRQ_TYPE_LEVEL_HIGH)>;
>> +
>> +		its_totems: interrupt-controller at 8c000000 {
>> +			compatible = "arm,gic-v3-its";
>> +			msi-controller;
>> +			reg = <0x0 0x8c000000 0x0 0x1000000>;
>> +		};
>> +	};
>> +
>> +	timer {
>> +		compatible = "arm,armv8-timer";
>> +		interrupts = <GIC_PPI 13 (GIC_CPU_MASK_SIMPLE(8) | IRQ_TYPE_LEVEL_LOW)>,
>> +			     <GIC_PPI 14 (GIC_CPU_MASK_SIMPLE(8) | IRQ_TYPE_LEVEL_LOW)>,
>> +			     <GIC_PPI 11 (GIC_CPU_MASK_SIMPLE(8) | IRQ_TYPE_LEVEL_LOW)>,
>> +			     <GIC_PPI 10 (GIC_CPU_MASK_SIMPLE(8) | IRQ_TYPE_LEVEL_LOW)>;
> 
> Here have a question:
> In devcie tree binding file: Documentation/devicetree/bindings/arm/gic.txt,
> it only considers for maximum 8 cpus. So will we need change the
> binding file and also use GIC_CPU_MASK_SIMPLE(16) for 16 cores?
> 

Looks like should updtate gic.txt and use the GIC_CPU_MASK_SIMPLE(16) for 16 cores.

Ding

>> +	};
>> +
>> +	pmu {
>> +		compatible = "arm,armv8-pmuv3";
>> +		interrupts = <GIC_PPI 7 IRQ_TYPE_LEVEL_HIGH>;
>> +	};
>> +
>> +	soc {
>> +		compatible = "simple-bus";
>> +		#address-cells = <2>;
>> +		#size-cells = <2>;
>> +		ranges;
>> +
>> +		refclk200mhz: refclk200mhz {
>> +			compatible = "fixed-clock";
>> +			#clock-cells = <0>;
>> +			clock-frequency = <200000000>;
>> +		};
>> +
>> +		uart0: uart at 80300000 {
>> +			compatible = "snps,dw-apb-uart";
>> +			reg = <0x0 0x80300000 0x0 0x10000>;
>> +			interrupts = <GIC_SPI 317 IRQ_TYPE_LEVEL_HIGH>;
>> +			clocks = <&refclk200mhz>;
>> +			clock-names = "apb_pclk";
>> +			reg-shift = <2>;
>> +			reg-io-width = <4>;
>> +			status = "disabled";
>> +		};
>> +
>> +		uart1: uart at 80310000 {
>> +			compatible = "snps,dw-apb-uart";
>> +			reg = <0x0 0x80310000 0x0 0x10000>;
>> +			interrupts = <GIC_SPI 318 IRQ_TYPE_LEVEL_HIGH>;
>> +			clocks = <&refclk200mhz>;
>> +			clock-names = "apb_pclk";
>> +			reg-shift = <2>;
>> +			reg-io-width = <4>;
>> +			status = "disabled";
>> +		};
>> +	};
>> +};
>> -- 
>> 1.9.0
>>
>>
>>
>> _______________________________________________
>> linux-arm-kernel mailing list
>> linux-arm-kernel at lists.infradead.org
>> http://lists.infradead.org/mailman/listinfo/linux-arm-kernel
> 
> .
> 




From vichy.kuo at gmail.com  Mon Aug 31 07:03:33 2015
From: vichy.kuo at gmail.com (vichy)
Date: Mon, 31 Aug 2015 22:03:33 +0800
Subject: about system time incorrect after changing cpu frequency
Message-ID: <CAOVJa8GTDj3UJpgUd4nH1wknUKa6fgac=1SsqC8g=UCG0MGuDw@mail.gmail.com>

hi all:
My platform is like below:
1. single core Cortex A9
2. use global timer for system timer

after I porting cpu frequency driver based on snow ball, the cpu
frequency did change as I expected.
But the system time is incorrect( since pherial clk is got from cpu frequency)

for example:
a) cpu 1G (pherial clk = 250M) --> sleep 1 sec (OK)
b) cpu 500M  (pherial clk = 125M) --> sleep 1 sec (will be measured as 2 sec)

I try to call below 2 functions to change the frequency of clocksource
and clockevent, but the above b) sleep time is still incorrect when
cpu runs in 500Mhz.
    clockevents_update_freq(this_cpu_ptr(gt_evt), gt_clk_rate);
    __clocksource_updatefreq_hz(&gt_clocksource, gt_clk_rate);

in Arm cortex A9 single core system with Global timer as system timer,
is there any kernel api to change system timer period when cpu/pherial
frequency change?

appreciate your kind help in advance,


From tony at atomide.com  Mon Aug 31 07:11:34 2015
From: tony at atomide.com (Tony Lindgren)
Date: Mon, 31 Aug 2015 07:11:34 -0700
Subject: [PATCH] gpio: omap: Fix gpiochip_add() handling for deferred probe
In-Reply-To: <55E4186E.7090605@ti.com>
References: <1440787489-15992-1-git-send-email-tony@atomide.com>
 <55E4186E.7090605@ti.com>
Message-ID: <20150831141134.GA4215@atomide.com>

* Grygorii Strashko <grygorii.strashko at ti.com> [150831 02:07]:
> Hi Tony,
> 
> On 08/28/2015 09:44 PM, Tony Lindgren wrote:
> >Currently we gpio-omap breaks if gpiochip_add() returns -EPROBE_DEFER:
> >
> >[    0.570000] gpiochip_add: GPIOs 0..31 (gpio) failed to register
> >[    0.570000] omap_gpio 48310000.gpio: Could not register gpio chip -517
> >...
> >[    3.670000] omap_gpio 48310000.gpio: Unbalanced pm_runtime_enable!
> 
> I have no objection to the patch itself.
> 
> But I curious, How have you got this error output? Was it simulated?

I ran into it when trying to get rid of all the custom initcalls
for various drivers. And especially if adding dts mappings for
gpio-ranges to try to find some solution for the 1.158 issue that
keeps me from having a mainline GPIO PM regresion test with
pinging wl12xx during off idle :)

Regards,

Tony


From tglx at linutronix.de  Mon Aug 31 07:13:18 2015
From: tglx at linutronix.de (Thomas Gleixner)
Date: Mon, 31 Aug 2015 16:13:18 +0200 (CEST)
Subject: [PATCH v3 RESEND 0/5] Remaining part of kill off set_irq_flags
 usage
In-Reply-To: <1440889285-5637-1-git-send-email-robh@kernel.org>
References: <1440889285-5637-1-git-send-email-robh@kernel.org>
Message-ID: <alpine.DEB.2.11.1508311612320.15006@nanos>

On Sat, 29 Aug 2015, Rob Herring wrote:
> Thomas,
> 
> As requested, here are the remaining patches for killing off 
> set_irq_flags which have not been picked up. The rest of the 
> series has been picked up and are in -next. 

I pick it up, stick it into tip irq/urgent let it brew for a couple of
days in next and send it to Linus after that.

Thanks,

	tglx


From simon.guinot at sequanux.org  Mon Aug 31 07:28:57 2015
From: simon.guinot at sequanux.org (Simon Guinot)
Date: Mon, 31 Aug 2015 16:28:57 +0200
Subject: [PATCH 2/3] ARM: mvebu: add DT support for Seagate Personal Cloud
In-Reply-To: <20150831125926.GL3684@io.lakedaemon.net>
References: <1440866805-31731-1-git-send-email-simon.guinot@sequanux.org>
 <1440866805-31731-3-git-send-email-simon.guinot@sequanux.org>
 <20150831125926.GL3684@io.lakedaemon.net>
Message-ID: <20150831142857.GP30993@kw.sim.vm.gnt>

On Mon, Aug 31, 2015 at 12:59:26PM +0000, Jason Cooper wrote:
> On Sat, Aug 29, 2015 at 06:46:44PM +0200, Simon Guinot wrote:
> > This patch adds DT support for the Seagate Personal Cloud 1 and 2-Bay
> > (n090103 and n090203).
> > 
> > Chipset list:
> > - SoC Marvell Armada 370 88F6707, CPU @1GHz
> > - SDRAM memory: 512MB DDR3 667MHz (16-bits bandwidth)
> > - SPI flash 1MB (Macronix MX25L8006E)
> > - 1 or 2 SATA internal ports
> > - 1 Ethernet Gigabit port (PHY Marvell 88E1518)
> > - 1 USB3 host port (PCIe controller ASM1042)
> > - 1 USB2 host port (SoC)
> > - 2 push buttons (power and reset)
> > - 1 SATA LED (bi-color, white and red)
> 
> Do you have long term URLs for these products?  It would be nice to add
> those.  The best I could find is:
> 
>   http://www.seagate.com/www-content/product-content/personal-cloud/en-us/doc/personal-cloud-ds1838-1-1501us.pdf

Definitively, it is not a long term URL. There is none available.

For the customer products such as the Personal Cloud, I don't think
that the hardware specifications are available. For the professional
products, it is a little bit better.

> 
> But none of the model numbers match what you've used in this patch
> series.  I imagine this will make it harder for newcomers to find the
> relevant code.

Indeed, the model number can be used to identify the product and the
hardware board. But unfortunately, I don't know how to read it. There is
a lot of informations encoded inside this number and the specifications
are not fully available to me. That's why I don't think it is a good
idea to use it.

And indeed again, the hardware name I am using can't be found easily by
a user. It is not written on the PCB nor on the casing. But the hardware
name is used by the stock U-Boot image to build an environment variable:
target.dtb. This variable holds the name of the DTB file to load
(armada-370-n090103.dtb for example) from hard disk during the boot
process. I was hoping I could keep Linux mainline naming compatible with
the stock U-Boot.

Simon

> 
> > Note that support for the white SATA LED is missing. A dedicated LED
> > driver is needed.
> > 
> > Signed-off-by: Simon Guinot <simon.guinot at sequanux.org>
> > ---
> >  arch/arm/boot/dts/Makefile                |   2 +
> >  arch/arm/boot/dts/armada-370-n090103.dts  |  28 +++++
> >  arch/arm/boot/dts/armada-370-n090203.dts  |  42 ++++++++
> >  arch/arm/boot/dts/armada-370-n090x03.dtsi | 174 ++++++++++++++++++++++++++++++
> >  4 files changed, 246 insertions(+)
> >  create mode 100644 arch/arm/boot/dts/armada-370-n090103.dts
> >  create mode 100644 arch/arm/boot/dts/armada-370-n090203.dts
> >  create mode 100644 arch/arm/boot/dts/armada-370-n090x03.dtsi
> > 
> 
> ...
> 
> > diff --git a/arch/arm/boot/dts/armada-370-n090103.dts b/arch/arm/boot/dts/armada-370-n090103.dts
> > new file mode 100644
> > index 000000000000..c94bed449050
> > --- /dev/null
> > +++ b/arch/arm/boot/dts/armada-370-n090103.dts
> > @@ -0,0 +1,28 @@
> > +/*
> > + * Device Tree file for Seagate Personal Cloud NAS (n090103).
> > + *
> > + * Copyright (C) 2015 Seagate
> > + *
> > + * Author: Simon Guinot <simon.guinot at sequanux.org>
> > + *
> > + * This file is licensed under the terms of the GNU General Public
> > + * License version 2.  This program is licensed "as is" without any
> > + * warranty of any kind, whether express or implied.
> > + */
> 
> Based on previous discussions, I'm pretty sure I know what the answer
> is, but I have to at least ask in case it was accidental.  All other
> armada-* files are dual licensed, GPLv2/X11.  Was it intentional to
> license these as GPLv2 only?
> 
> > +
> > +/dts-v1/;
> > +#include "armada-370-n090x03.dtsi"
> > +
> > +/ {
> > +	model = "Seagate Personal Cloud";
> > +	compatible = "seagate,n090103", "marvell,armada370", "marvell,armada-370-xp";
> 
> In line with my previous comment, can we add a compatible string here?
> 
> 	compatible = "seagate,n090103", "seagate,personalcloud", "marvell,armada370", "marvell,armada-370-xp";
> 
> > diff --git a/arch/arm/boot/dts/armada-370-n090203.dts b/arch/arm/boot/dts/armada-370-n090203.dts
> > new file mode 100644
> > index 000000000000..3bc62b9f0b0c
> > --- /dev/null
> > +++ b/arch/arm/boot/dts/armada-370-n090203.dts
> > @@ -0,0 +1,42 @@
> > +/*
> > + * Device Tree file for Seagate Personnal Cloud 2-Bay NAS (n090203).
> > + *
> > + * Copyright (C) 2015 Seagate
> > + *
> > + * Author: Simon Guinot <simon.guinot at sequanux.org>
> > + *
> > + * This file is licensed under the terms of the GNU General Public
> > + * License version 2.  This program is licensed "as is" without any
> > + * warranty of any kind, whether express or implied.
> > + */
> > +
> > +/dts-v1/;
> > +#include "armada-370-n090x03.dtsi"
> > +
> > +/ {
> > +	model = "Seagate Personnal Cloud 2-Bay";
> > +	compatible = "seagate,n090203", "marvell,armada370", "marvell,armada-370-xp";
> 
> And then here:
> 
> 	compatible = "seagate,n090103", "seagate,personalcloud2", "marvell,armada370", "marvell,armada-370-xp";
> 
> or similar.
> 
> The same comments apply to the NAS versions as well.
> 
> thx,
> 
> Jason.
-------------- next part --------------
A non-text attachment was scrubbed...
Name: signature.asc
Type: application/pgp-signature
Size: 181 bytes
Desc: Digital signature
URL: <http://lists.infradead.org/pipermail/linux-arm-kernel/attachments/20150831/eec6621c/attachment-0001.sig>

From parkch98 at gmail.com  Mon Aug 31 07:25:11 2015
From: parkch98 at gmail.com (Chanho Park)
Date: Mon, 31 Aug 2015 23:25:11 +0900
Subject: [PATCH] ARM: EXYNOS: reset KFC cores when cpu is up
Message-ID: <1441031111-6549-1-git-send-email-parkch98@gmail.com>

The cpu booting of exynos5422 has been still broken since we discussed
it in last year[1]. This patch is inspired from odroid xu3
code(Actually, it was from samsung exynos vendor kernel)[2]. This weird
reset code was founded exynos5420 octa cores series SoCs and only
required for the first boot core is the little core(kingfisher core).
Some of the exynos5420 boards and all of the exynos5422 boards will be
required this code.
There is two ways to check the little core is the first cpu. One is
checking GPG2CON[1] gpio value and the other is checking the cluster
number of the first cpu. I selected the latter because it's more easier
than the former.

Changes since RFC[3]:
- drop checking soc_is_exynos5800 to extend this codes to
exynos5420/5422 boards.
- kfc cores will be reset only if the cpu0 is kfc core.
- Rebase top of the kukjin's for-next branch

[1]:http://lists.infradead.org/pipermail/linux-arm-kernel/2015-June/350632.html
[2]:https://patchwork.kernel.org/patch/6782891/
[3]:http://lists.infradead.org/pipermail/linux-arm-kernel/2015-July/356610.html

Cc: Joonyoung Shim <jy0922.shim at samsung.com>
Cc: Chanwoo Choi <cw00.choi at samsung.com>
Cc: Kevin Hilman <khilman at kernel.org>
Cc: Heesub Shin <heesub.shin at samsung.com>
Cc: Mauro Ribeiro <mauro.ribeiro at hardkernel.com>
Cc: Abhilash Kesavan <a.kesavan at samsung.com>
Cc: Przemyslaw Marczak <p.marczak at samsung.com>
Cc: Marek Szyprowski <m.szyprowski at samsung.com>
Cc: Krzysztof Kozlowski <k.kozlowski at samsung.com>
Signed-off-by: Chanho Park <parkch98 at gmail.com>
---
 arch/arm/mach-exynos/mcpm-exynos.c | 18 +++++++++++++++++-
 arch/arm/mach-exynos/regs-pmu.h    |  6 ++++++
 2 files changed, 23 insertions(+), 1 deletion(-)

diff --git a/arch/arm/mach-exynos/mcpm-exynos.c b/arch/arm/mach-exynos/mcpm-exynos.c
index 9bdf547..5b69ed2 100644
--- a/arch/arm/mach-exynos/mcpm-exynos.c
+++ b/arch/arm/mach-exynos/mcpm-exynos.c
@@ -20,6 +20,7 @@
 #include <asm/cputype.h>
 #include <asm/cp15.h>
 #include <asm/mcpm.h>
+#include <asm/smp_plat.h>
 
 #include "regs-pmu.h"
 #include "common.h"
@@ -70,7 +71,22 @@ static int exynos_cpu_powerup(unsigned int cpu, unsigned int cluster)
 		cluster >= EXYNOS5420_NR_CLUSTERS)
 		return -EINVAL;
 
-	exynos_cpu_power_up(cpunr);
+	if (!exynos_cpu_power_state(cpunr)) {
+		exynos_cpu_power_up(cpunr);
+
+		/* This assumes the cluster number of the eagle is 0 and the
+		 * kfc is 1. When the system was booted from the kfc core,
+		 * they should be reset */
+		if (cluster &&
+		    cluster == MPIDR_AFFINITY_LEVEL(cpu_logical_map(0), 1)) {
+			while (!pmu_raw_readl(S5P_PMU_SPARE2))
+				udelay(10);
+
+			pmu_raw_writel(EXYNOS5420_KFC_CORE_RESET(cpu),
+					EXYNOS_SWRESET);
+		}
+	}
+
 	return 0;
 }
 
diff --git a/arch/arm/mach-exynos/regs-pmu.h b/arch/arm/mach-exynos/regs-pmu.h
index b761433..fba9068 100644
--- a/arch/arm/mach-exynos/regs-pmu.h
+++ b/arch/arm/mach-exynos/regs-pmu.h
@@ -513,6 +513,12 @@ static inline unsigned int exynos_pmu_cpunr(unsigned int mpidr)
 #define SPREAD_ENABLE						0xF
 #define SPREAD_USE_STANDWFI					0xF
 
+#define EXYNOS5420_KFC_CORE_RESET0				BIT(8)
+#define EXYNOS5420_KFC_ETM_RESET0				BIT(20)
+
+#define EXYNOS5420_KFC_CORE_RESET(_nr)				\
+	((EXYNOS5420_KFC_CORE_RESET0 | EXYNOS5420_KFC_ETM_RESET0) << (_nr))
+
 #define EXYNOS5420_BB_CON1					0x0784
 #define EXYNOS5420_BB_SEL_EN					BIT(31)
 #define EXYNOS5420_BB_PMOS_EN					BIT(7)
-- 
2.1.0



From simon.guinot at sequanux.org  Mon Aug 31 07:31:05 2015
From: simon.guinot at sequanux.org (Simon Guinot)
Date: Mon, 31 Aug 2015 16:31:05 +0200
Subject: [PATCH 1/3] ARM: mvebu: add DT support for Seagate NAS 2 and 4-Bay
In-Reply-To: <20150831131610.GG14459@lunn.ch>
References: <1440866805-31731-1-git-send-email-simon.guinot@sequanux.org>
 <1440866805-31731-2-git-send-email-simon.guinot@sequanux.org>
 <20150831124314.GE14459@lunn.ch>
 <20150831131306.GO30993@kw.sim.vm.gnt>
 <20150831131610.GG14459@lunn.ch>
Message-ID: <20150831143105.GQ30993@kw.sim.vm.gnt>

On Mon, Aug 31, 2015 at 03:16:10PM +0200, Andrew Lunn wrote:
> > It may sound crazy but I have nothing more than the hardware and product
> > names which are respectively "n090201" and "Seagate NAS 2-Bay" for this
> > board.
> 
> Does it have a plate on the back with identification information? Is
> this n090201 on the ID plate?

No it is not. Else it would have been too easy :) Please, see my answer
to Jason who is more or less asking for the same thing.

Simon
-------------- next part --------------
A non-text attachment was scrubbed...
Name: signature.asc
Type: application/pgp-signature
Size: 181 bytes
Desc: Digital signature
URL: <http://lists.infradead.org/pipermail/linux-arm-kernel/attachments/20150831/eb3b84ca/attachment.sig>

From grygorii.strashko at ti.com  Mon Aug 31 07:37:22 2015
From: grygorii.strashko at ti.com (Grygorii Strashko)
Date: Mon, 31 Aug 2015 17:37:22 +0300
Subject: [PATCH] gpio: omap: Fix gpiochip_add() handling for deferred probe
In-Reply-To: <20150831141134.GA4215@atomide.com>
References: <1440787489-15992-1-git-send-email-tony@atomide.com>
 <55E4186E.7090605@ti.com> <20150831141134.GA4215@atomide.com>
Message-ID: <55E466A2.9080900@ti.com>

On 08/31/2015 05:11 PM, Tony Lindgren wrote:
> * Grygorii Strashko <grygorii.strashko at ti.com> [150831 02:07]:
>> Hi Tony,
>>
>> On 08/28/2015 09:44 PM, Tony Lindgren wrote:
>>> Currently we gpio-omap breaks if gpiochip_add() returns -EPROBE_DEFER:
>>>
>>> [    0.570000] gpiochip_add: GPIOs 0..31 (gpio) failed to register
>>> [    0.570000] omap_gpio 48310000.gpio: Could not register gpio chip -517
>>> ...
>>> [    3.670000] omap_gpio 48310000.gpio: Unbalanced pm_runtime_enable!
>>
>> I have no objection to the patch itself.
>>
>> But I curious, How have you got this error output? Was it simulated?
> 
> I ran into it when trying to get rid of all the custom initcalls
> for various drivers. And especially if adding dts mappings for
> gpio-ranges to try to find some solution for the 1.158 issue that
> keeps me from having a mainline GPIO PM regresion test with
> pinging wl12xx during off idle :)
> 

Ah. So, -EPROBE_DEFER was returned by of_gpiochip_add_pin_range(),
I was not able to find a place where gpiochip_add() can return -EPROBE_DEFER ;)

Thanks for clarification.


-- 
regards,
-grygorii


From leo.yan at linaro.org  Mon Aug 31 07:40:19 2015
From: leo.yan at linaro.org (Leo Yan)
Date: Mon, 31 Aug 2015 22:40:19 +0800
Subject: [PATCH 2/2] arm64: dts: add dts files for Hisilicon Hip05-D02
 Development Board
In-Reply-To: <55E45A46.7040805@huawei.com>
References: <1440838361-1468-1-git-send-email-dingtianhong@huawei.com>
 <1440838361-1468-3-git-send-email-dingtianhong@huawei.com>
 <20150831131244.GB6194@leoy-linaro> <55E45A46.7040805@huawei.com>
Message-ID: <20150831144019.GA22491@leoy-linaro>

On Mon, Aug 31, 2015 at 09:44:38PM +0800, Ding Tianhong wrote:
> On 2015/8/31 21:12, Leo Yan wrote:
> > On Sat, Aug 29, 2015 at 04:52:41PM +0800, Ding Tianhong wrote:
> >> Add initial dtsi file to support Hisilicon Hip05-D02 Board with
> >> support of CPUs in four clusters and each cluster has quard Cortex-A57.
> >>
> >> Also add dts file to support Hip05-D02 development board.
> >>
> >> Signed-off-by: Ding Tianhong <dingtianhong at huawei.com>
> >> Signed-off-by: Kefeng Wang <wangkefeng.wang at huawei.com>
> >> ---
> >>  arch/arm64/boot/dts/hisilicon/Makefile      |   2 +-
> >>  arch/arm64/boot/dts/hisilicon/hip05-d02.dts |  36 ++++
> >>  arch/arm64/boot/dts/hisilicon/hip05.dtsi    | 271 ++++++++++++++++++++++++++++
> >>  3 files changed, 308 insertions(+), 1 deletion(-)
> >>  create mode 100644 arch/arm64/boot/dts/hisilicon/hip05-d02.dts
> >>  create mode 100644 arch/arm64/boot/dts/hisilicon/hip05.dtsi
> >>
> >> diff --git a/arch/arm64/boot/dts/hisilicon/Makefile b/arch/arm64/boot/dts/hisilicon/Makefile
> >> index fa81a6e..cd158b8 100644
> >> --- a/arch/arm64/boot/dts/hisilicon/Makefile
> >> +++ b/arch/arm64/boot/dts/hisilicon/Makefile
> >> @@ -1,4 +1,4 @@
> >> -dtb-$(CONFIG_ARCH_HISI) += hi6220-hikey.dtb
> >> +dtb-$(CONFIG_ARCH_HISI) += hi6220-hikey.dtb hip05-d02.dtb
> >>  
> >>  always		:= $(dtb-y)
> >>  subdir-y	:= $(dts-dirs)
> >> diff --git a/arch/arm64/boot/dts/hisilicon/hip05-d02.dts b/arch/arm64/boot/dts/hisilicon/hip05-d02.dts
> >> new file mode 100644
> >> index 0000000..ae34e25
> >> --- /dev/null
> >> +++ b/arch/arm64/boot/dts/hisilicon/hip05-d02.dts
> >> @@ -0,0 +1,36 @@
> >> +/**
> >> + * dts file for Hisilicon D02 Development Board
> >> + *
> >> + * Copyright (C) 2014,2015 Hisilicon Ltd.
> >> + *
> >> + * 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
> >> + * publishhed by the Free Software Foundation.
> >> + *
> >> + */
> >> +
> >> +/dts-v1/;
> >> +
> >> +#include "hip05.dtsi"
> >> +
> >> +/ {
> >> +	model = "Hisilicon Hip05 D02 Development Board";
> >> +	compatible = "hisilicon,hip05-d02";
> >> +
> >> +	memory at 00000000 {
> >> +		device_type = "memory";
> >> +		reg = <0x0 0x00000000 0x0 0x80000000>;
> >> +	};
> >> +
> >> +	aliases {
> >> +		serial0 = &uart0;
> >> +	};
> >> +
> >> +	chosen {
> >> +		stdout-path = "serial0:115200n8";
> >> +	};
> >> +};
> >> +
> >> +&uart0 {
> >> +	status = "ok";
> >> +};
> >> diff --git a/arch/arm64/boot/dts/hisilicon/hip05.dtsi b/arch/arm64/boot/dts/hisilicon/hip05.dtsi
> >> new file mode 100644
> >> index 0000000..da12d94
> >> --- /dev/null
> >> +++ b/arch/arm64/boot/dts/hisilicon/hip05.dtsi
> >> @@ -0,0 +1,271 @@
> >> +/**
> >> + * dts file for Hisilicon D02 Development Board
> >> + *
> >> + * Copyright (C) 2014,2015 Hisilicon Ltd.
> >> + *
> >> + * 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
> >> + * publishhed by the Free Software Foundation.
> >> + *
> >> + */
> >> +
> >> +#include <dt-bindings/interrupt-controller/arm-gic.h>
> >> +
> >> +/ {
> >> +	compatible = "hisilicon,hip05-d02";
> >> +	interrupt-parent = <&gic>;
> >> +	#address-cells = <2>;
> >> +	#size-cells = <2>;
> >> +
> >> +	psci {
> >> +		compatible = "arm,psci-0.2";
> >> +		method = "smc";
> >> +	};
> >> +
> >> +	cpus {
> >> +		#address-cells = <1>;
> >> +		#size-cells = <0>;
> >> +
> >> +		cpu-map {
> >> +			cluster0 {
> >> +				core0 {
> >> +					cpu = <&cpu0>;
> >> +				};
> >> +				core1 {
> >> +					cpu = <&cpu1>;
> >> +				};
> >> +				core2 {
> >> +					cpu = <&cpu2>;
> >> +				};
> >> +				core3 {
> >> +					cpu = <&cpu3>;
> >> +				};
> >> +			};
> >> +			cluster1 {
> >> +				core0 {
> >> +					cpu = <&cpu4>;
> >> +				};
> >> +				core1 {
> >> +					cpu = <&cpu5>;
> >> +				};
> >> +				core2 {
> >> +					cpu = <&cpu6>;
> >> +				};
> >> +				core3 {
> >> +					cpu = <&cpu7>;
> >> +				};
> >> +			};
> >> +			cluster2 {
> >> +				core0 {
> >> +					cpu = <&cpu8>;
> >> +				};
> >> +				core1 {
> >> +					cpu = <&cpu9>;
> >> +				};
> >> +				core2 {
> >> +					cpu = <&cpu10>;
> >> +				};
> >> +				core3 {
> >> +					cpu = <&cpu11>;
> >> +				};
> >> +			};
> >> +			cluster3 {
> >> +				core0 {
> >> +					cpu = <&cpu12>;
> >> +				};
> >> +				core1 {
> >> +					cpu = <&cpu13>;
> >> +				};
> >> +				core2 {
> >> +					cpu = <&cpu14>;
> >> +				};
> >> +				core3 {
> >> +					cpu = <&cpu15>;
> >> +				};
> >> +			};
> >> +		};
> >> +
> >> +		cpu0: cpu at 20000 {
> >> +			device_type = "cpu";
> >> +			compatible = "arm,armv8";
> > 
> > Change to "arm,cortex-a57","arm,armv8"?
> > 
> 
> Ok?but I think should be "hisilicon,hip05","arm,armv8".

If the CPU is a starndard ARM core (such like CA53, CA57, etc), you
need directly use the CPU type which has been defined in:
Documentation/devicetree/bindings/arm/cpus.txt. So here hip05 is the
naming code for SoC? or for the CPU customized by Hisilicon?

[...]

Thanks,
Leo Yan


From romain.perier at gmail.com  Mon Aug 31 07:42:13 2015
From: romain.perier at gmail.com (Romain Perier)
Date: Mon, 31 Aug 2015 16:42:13 +0200
Subject: [PATCH v2] clk: rockchip: Add pclk_peri to critical clocks on
 RK3066/RK3188
In-Reply-To: <1440322357-2621-1-git-send-email-romain.perier@gmail.com>
References: <1440322357-2621-1-git-send-email-romain.perier@gmail.com>
Message-ID: <CABgxDo+otZrYoqTNK-ea=L6Dsd5p_b_MFCi4H4XJZZ25PV_qnA@mail.gmail.com>

ping

2015-08-23 11:32 GMT+02:00 Romain Perier <romain.perier at gmail.com>:
> Now that the rockchip clock subsystem does clock gating with GPIO banks,
> these are no longer enabled once during probe and no longer stay enabled
> for eternity. When all these clocks are disabled, the parent clock pclk_peri
> might be disabled too, as no other child claims it. So, we need to add pclk_peri
> to the critical clocks.
>
> Signed-off-by: Romain Perier <romain.perier at gmail.com>
> Tested-by: Michael Niewoehner <linux at mniewoehner.de>
> ---
>
> changes in v2:
> - Improved commit messages
> - Added "Tested-by" from Michael Niewoehner, as he tested v1 and no code changed
>
>  drivers/clk/rockchip/clk-rk3188.c | 1 +
>  1 file changed, 1 insertion(+)
>
> diff --git a/drivers/clk/rockchip/clk-rk3188.c b/drivers/clk/rockchip/clk-rk3188.c
> index bf20214..839a22a 100644
> --- a/drivers/clk/rockchip/clk-rk3188.c
> +++ b/drivers/clk/rockchip/clk-rk3188.c
> @@ -717,6 +717,7 @@ static const char *const rk3188_critical_clocks[] __initconst = {
>         "aclk_peri",
>         "hclk_peri",
>         "pclk_cpu",
> +       "pclk_peri",
>  };
>
>  static void __init rk3188_common_clk_init(struct device_node *np)
> --
> 2.1.4
>


From andrew at lunn.ch  Mon Aug 31 07:36:17 2015
From: andrew at lunn.ch (Andrew Lunn)
Date: Mon, 31 Aug 2015 16:36:17 +0200
Subject: [PATCH 2/3] ARM: mvebu: add DT support for Seagate Personal Cloud
In-Reply-To: <20150831142857.GP30993@kw.sim.vm.gnt>
References: <1440866805-31731-1-git-send-email-simon.guinot@sequanux.org>
 <1440866805-31731-3-git-send-email-simon.guinot@sequanux.org>
 <20150831125926.GL3684@io.lakedaemon.net>
 <20150831142857.GP30993@kw.sim.vm.gnt>
Message-ID: <20150831143617.GC20180@lunn.ch>

> But the hardware name is used by the stock U-Boot image to build an
> environment variable: target.dtb. This variable holds the name of
> the DTB file to load (armada-370-n090103.dtb for example) from hard
> disk during the boot process. I was hoping I could keep Linux
> mainline naming compatible with the stock U-Boot.

Hi Simon

Could you make the suggestion towards the product managers that future
new products include seagate in the filename? That will greatly
increase the chance of keeping naming compatibility.

	 Andrew


From alex.williamson at redhat.com  Mon Aug 31 07:54:34 2015
From: alex.williamson at redhat.com (Alex Williamson)
Date: Mon, 31 Aug 2015 08:54:34 -0600
Subject: [PATCH v3 04/10] VFIO: platform: add vfio_platform_set_automasked
In-Reply-To: <55E43DFC.8050608@huawei.com>
References: <1439212864-12954-1-git-send-email-eric.auger@linaro.org>
 <1439212864-12954-5-git-send-email-eric.auger@linaro.org>
 <1439405794.4023.528.camel@redhat.com> <55D1FFE8.9050104@linaro.org>
 <1439919864.4023.626.camel@redhat.com> <55E43DFC.8050608@huawei.com>
Message-ID: <1441032874.20355.126.camel@redhat.com>

On Mon, 2015-08-31 at 13:43 +0200, Antonios Motakis wrote:
> 
> On 18-Aug-15 19:44, Alex Williamson wrote:
> > On Mon, 2015-08-17 at 17:38 +0200, Eric Auger wrote:
> >> On 08/12/2015 08:56 PM, Alex Williamson wrote:
> >>> On Mon, 2015-08-10 at 15:20 +0200, Eric Auger wrote:
> >>>> This function makes possible to change the automasked mode.
> >>>>
> >>>> Signed-off-by: Eric Auger <eric.auger at linaro.org>
> >>>>
> >>>> ---
> >>>>
> >>>> v1 -> v2:
> >>>> - set forwarded flag
> >>>> ---
> >>>>  drivers/vfio/platform/vfio_platform_irq.c | 19 +++++++++++++++++++
> >>>>  1 file changed, 19 insertions(+)
> >>>>
> >>>> diff --git a/drivers/vfio/platform/vfio_platform_irq.c b/drivers/vfio/platform/vfio_platform_irq.c
> >>>> index b31b1f0..a285384 100644
> >>>> --- a/drivers/vfio/platform/vfio_platform_irq.c
> >>>> +++ b/drivers/vfio/platform/vfio_platform_irq.c
> >>>> @@ -186,6 +186,25 @@ static irqreturn_t vfio_handler(int irq, void *dev_id)
> >>>>  	return ret;
> >>>>  }
> >>>>  
> >>>> +static int vfio_platform_set_automasked(struct vfio_platform_irq *irq,
> >>>> +					   bool automasked)
> >>>> +{
> >>>> +	unsigned long flags;
> >>>> +
> >>>> +	spin_lock_irqsave(&irq->lock, flags);
> >>>> +	if (automasked) {
> >>>> +		irq->forwarded = true;
> >>>> +		irq->flags |= VFIO_IRQ_INFO_AUTOMASKED;
> >>>> +		irq->handler = vfio_automasked_irq_handler;
> >>>> +	} else {
> >>>> +		irq->forwarded = false;
> >>>> +		irq->flags &= ~VFIO_IRQ_INFO_AUTOMASKED;
> >>>> +		irq->handler = vfio_irq_handler;
> >>>> +	}
> >>>> +	spin_unlock_irqrestore(&irq->lock, flags);
> >>>> +	return 0;
> >>>
> >>> In vfio-speak, automasked means level and we're not magically changing
> >>> the IRQ from level to edge, we're simply able to handle level
> >>> differently based on a hardware optimization.  Should the user visible
> >>> flags therefore change based on this?  Aren't we really setting the
> >>> forwarded state rather than the automasked state?
> >>
> >> Well actually this was following the discussion we had a long time ago
> >> about that topic:
> >>
> >> http://lkml.iu.edu/hypermail/linux/kernel/1409.1/03659.html
> >>
> >> I did not really know how to conclude ...
> >>
> >> If it is preferred I can hide this to the userspace, no problem.
> > 
> > I think that was based on the user being involved in enabling forwarding
> > though, now that it's hidden and automatic, it doesn't make much sense
> > to me to toggle any of the interrupt info details based on the state of
> > the forward.  The user always needs to handle the interrupt as level
> > since the bypass can be torn down at any point in time.  We're taking
> > advantage of the in-kernel path to make further optimizations, which
> > seems like they should be transparent to the user.  Thanks,
> 
> I wonder if it makes sense to rename VFIO_IRQ_INFO_AUTOMASKED to
> VFIO_IRQ_INFO_LEVEL_TRIGGERED, and reintroduce VFIO_IRQ_INFO_AUTOMASKED as
> an alias, so compatibility with user space can be maintained? This way
> this semantic misunderstanding could be left behind.

Is there really a misunderstanding here?  I think the change is that the
user was previously involved and updating the flag reinforced that.  Now
the user is not involved and the flag changing is just unexpected noise.
"automasked" is intentionally not "level" because being level triggered
may not be the only reason we'd need to mask an interrupt upon receiving
it.  We could actually have automasked edge triggered interrupts if we
wanted.  We don't do that, so we can equate automasked to level
currently, but technically automasked simply indicates that an unmask is
required to get the next interrupt.  In this case the VM is able to
effectively do the unmask itself.  Thanks,

Alex



From jic23 at kernel.org  Mon Aug 31 08:20:08 2015
From: jic23 at kernel.org (Jonathan Cameron)
Date: Mon, 31 Aug 2015 16:20:08 +0100
Subject: [PATCH v4] iio: adc: vf610: Add IIO buffer support for Vybrid ADC
In-Reply-To: <BN3PR0301MB121977040608F337E69ADADEF5660@BN3PR0301MB1219.namprd03.prod.outlook.com>
References: <d556443a26070be505f9a5f5f0999253b73d9b71.1439283162.git.maitysanchayan@gmail.com>
 <9be567ec7d6f6370dd42a41438d64cf7aaa47635.1439826018.git.maitysanchayan@gmail.com>
 <BN3PR0301MB121977040608F337E69ADADEF5660@BN3PR0301MB1219.namprd03.prod.outlook.com>
Message-ID: <55E470A8.4000200@kernel.org>

On 20/08/15 07:50, Duan Andy wrote:
> From: Sanchayan Maity <maitysanchayan at gmail.com> Sent: Monday, August 17, 2015 11:52 PM
>> To: jic23 at kernel.org; linux-iio at vger.kernel.org
>> Cc: stefan at agner.ch; Duan Fugang-B38611; pmeerw at pmeerw.net; linux-
>> kernel at vger.kernel.org; linux-arm-kernel at lists.infradead.org; Sanchayan
>> Maity
>> Subject: [PATCH v4] iio: adc: vf610: Add IIO buffer support for Vybrid
>> ADC
>>
>> This patch adds support for IIO buffer to the Vybrid ADC driver.
>> IIO triggered buffer infrastructure along with iio sysfs trigger is used
>> to leverage continuous sampling support provided by the ADC block.
>>
>> Signed-off-by: Sanchayan Maity <maitysanchayan at gmail.com>
>> ---
>>
>> Changes since v3:
>> Fix iio_buffer_setup_ops for postenable and predisable functions to match
>> pairwise. Before this the predisable work was being done in postdisable.
>>
>> Changes since v2:
>> 1. Fix the wrong buffer size for statically allocated buffer 2. Drop the
>> use of .address field from the iio_chan_spec 3. Use iio_buffer_enabled
>> call inside the lock 4. Drop wrapper function around iio_trigered_*
>> function calls 5. Drop Kconfig select of sysfs trigger 6. Drop Kconfig
>> select IIO_TRIGGER as it is already selected by IIO_TRIGGERED_BUFFER
>>
>> Changes since v1:
>> 1. Use a fixed size buffer instead of kmalloc allocated during update
>> scan mode 2. Remove a write to read only register ADC_HS (COCO bit)
>>
>>  drivers/iio/adc/Kconfig     |   2 +
>>  drivers/iio/adc/vf610_adc.c | 105
>> +++++++++++++++++++++++++++++++++++++++++---
>>  2 files changed, 100 insertions(+), 7 deletions(-)
>>
> 
> The version is fine for me. Thanks for your effort.
> 
> Acked-by: Fugang Duan <B38611 at freescale.com>
Applied to the togreg branch of iio.git - will be initially pushed out
as testing for the autobuilders to play with it.

Thanks,

Jonathan
> --
> To unsubscribe from this list: send the line "unsubscribe linux-iio" in
> the body of a message to majordomo at vger.kernel.org
> More majordomo info at  http://vger.kernel.org/majordomo-info.html
> 



From robherring2 at gmail.com  Mon Aug 31 08:25:22 2015
From: robherring2 at gmail.com (Rob Herring)
Date: Mon, 31 Aug 2015 10:25:22 -0500
Subject: [PATCH v3 4/6] [media] c8sectpfe: Update binding to reset-gpios
In-Reply-To: <1440784362-31217-5-git-send-email-peter.griffin@linaro.org>
References: <1440784362-31217-1-git-send-email-peter.griffin@linaro.org>
 <1440784362-31217-5-git-send-email-peter.griffin@linaro.org>
Message-ID: <CAL_JsqLYes5L2Bg0R45ui24yYWgHzFSLgBPajieSLgLz09=1aw@mail.gmail.com>

On Fri, Aug 28, 2015 at 12:52 PM, Peter Griffin
<peter.griffin at linaro.org> wrote:
> gpio.txt documents that GPIO properties should be named
> "[<name>-]gpios", with <name> being the purpose of this
> GPIO for the device.
>
> This change has been done as one atomic commit.

dtb and kernel updates are not necessarily atomic, so you are breaking
compatibility with older dtbs. You should certainly highlight that in
the commit message. I only point this out. I'll leave it to platform
maintainers whether or not this breakage is acceptable.

Rob

>
> Signed-off-by: Peter Griffin <peter.griffin at linaro.org>
> Acked-by: Lee Jones <lee.jones at linaro.org>
> ---
>  Documentation/devicetree/bindings/media/stih407-c8sectpfe.txt | 6 +++---
>  arch/arm/boot/dts/stihxxx-b2120.dtsi                          | 4 ++--
>  drivers/media/platform/sti/c8sectpfe/c8sectpfe-core.c         | 2 +-
>  3 files changed, 6 insertions(+), 6 deletions(-)
>
> diff --git a/Documentation/devicetree/bindings/media/stih407-c8sectpfe.txt b/Documentation/devicetree/bindings/media/stih407-c8sectpfe.txt
> index d4def76..e70d840 100644
> --- a/Documentation/devicetree/bindings/media/stih407-c8sectpfe.txt
> +++ b/Documentation/devicetree/bindings/media/stih407-c8sectpfe.txt
> @@ -35,7 +35,7 @@ Required properties (tsin (child) node):
>
>  - tsin-num     : tsin id of the InputBlock (must be between 0 to 6)
>  - i2c-bus      : phandle to the I2C bus DT node which the demodulators & tuners on this tsin channel are connected.
> -- rst-gpio     : reset gpio for this tsin channel.
> +- reset-gpios  : reset gpio for this tsin channel.
>
>  Optional properties (tsin (child) node):
>
> @@ -75,7 +75,7 @@ Example:
>                         tsin-num                = <0>;
>                         serial-not-parallel;
>                         i2c-bus                 = <&ssc2>;
> -                       rst-gpio                = <&pio15 4 0>;
> +                       reset-gpios             = <&pio15 4 GPIO_ACTIVE_HIGH>;
>                         dvb-card                = <STV0367_TDA18212_NIMA_1>;
>                 };
>
> @@ -83,7 +83,7 @@ Example:
>                         tsin-num                = <3>;
>                         serial-not-parallel;
>                         i2c-bus                 = <&ssc3>;
> -                       rst-gpio                = <&pio15 7 0>;
> +                       reset-gpios             = <&pio15 7 GPIO_ACTIVE_HIGH>;
>                         dvb-card                = <STV0367_TDA18212_NIMB_1>;
>                 };
>         };
> diff --git a/arch/arm/boot/dts/stihxxx-b2120.dtsi b/arch/arm/boot/dts/stihxxx-b2120.dtsi
> index f9fca10..0b7592e 100644
> --- a/arch/arm/boot/dts/stihxxx-b2120.dtsi
> +++ b/arch/arm/boot/dts/stihxxx-b2120.dtsi
> @@ -6,8 +6,8 @@
>   * it under the terms of the GNU General Public License version 2 as
>   * published by the Free Software Foundation.
>   */
> -
>  #include <dt-bindings/clock/stih407-clks.h>
> +#include <dt-bindings/gpio/gpio.h>
>  #include <dt-bindings/media/c8sectpfe.h>
>  / {
>         soc {
> @@ -116,7 +116,7 @@
>                                 tsin-num        = <0>;
>                                 serial-not-parallel;
>                                 i2c-bus         = <&ssc2>;
> -                               rst-gpio        = <&pio15 4 GPIO_ACTIVE_HIGH>;
> +                               reset-gpios     = <&pio15 4 GPIO_ACTIVE_HIGH>;
>                                 dvb-card        = <STV0367_TDA18212_NIMA_1>;
>                         };
>                 };
> diff --git a/drivers/media/platform/sti/c8sectpfe/c8sectpfe-core.c b/drivers/media/platform/sti/c8sectpfe/c8sectpfe-core.c
> index 3a91093..c691e13 100644
> --- a/drivers/media/platform/sti/c8sectpfe/c8sectpfe-core.c
> +++ b/drivers/media/platform/sti/c8sectpfe/c8sectpfe-core.c
> @@ -822,7 +822,7 @@ static int c8sectpfe_probe(struct platform_device *pdev)
>                 }
>                 of_node_put(i2c_bus);
>
> -               tsin->rst_gpio = of_get_named_gpio(child, "rst-gpio", 0);
> +               tsin->rst_gpio = of_get_named_gpio(child, "reset-gpios", 0);
>
>                 ret = gpio_is_valid(tsin->rst_gpio);
>                 if (!ret) {
> --
> 1.9.1
>
>
> _______________________________________________
> linux-arm-kernel mailing list
> linux-arm-kernel at lists.infradead.org
> http://lists.infradead.org/mailman/listinfo/linux-arm-kernel


From robherring2 at gmail.com  Mon Aug 31 08:28:05 2015
From: robherring2 at gmail.com (Rob Herring)
Date: Mon, 31 Aug 2015 10:28:05 -0500
Subject: [PATCH v2 2/4] remoteproc: dt: Provide bindings for ST's Remote
 Processor Controller driver
In-Reply-To: <1440757911-9120-3-git-send-email-lee.jones@linaro.org>
References: <1440757911-9120-1-git-send-email-lee.jones@linaro.org>
 <1440757911-9120-3-git-send-email-lee.jones@linaro.org>
Message-ID: <CAL_JsqLuF2iAJhzjDh5CL-RgYk+H+N+D05wsWqUT01zvq9SOxA@mail.gmail.com>

On Fri, Aug 28, 2015 at 5:31 AM, Lee Jones <lee.jones at linaro.org> wrote:
> Signed-off-by: Ludovic Barre <ludovic.barre at st.com>
> Signed-off-by: Lee Jones <lee.jones at linaro.org>
> ---
>  .../devicetree/bindings/remoteproc/st-rproc.txt    | 35 ++++++++++++++++++++++
>  1 file changed, 35 insertions(+)
>  create mode 100644 Documentation/devicetree/bindings/remoteproc/st-rproc.txt
>
> diff --git a/Documentation/devicetree/bindings/remoteproc/st-rproc.txt b/Documentation/devicetree/bindings/remoteproc/st-rproc.txt
> new file mode 100644
> index 0000000..fbd7d78
> --- /dev/null
> +++ b/Documentation/devicetree/bindings/remoteproc/st-rproc.txt
> @@ -0,0 +1,35 @@
> +STMicroelectronics Remote Processor

"remote processor" is what STM datasheets call them? This seems like
Linux naming is leaking in here.

Rob


From nsekhar at ti.com  Mon Aug 31 08:39:08 2015
From: nsekhar at ti.com (Sekhar Nori)
Date: Mon, 31 Aug 2015 21:09:08 +0530
Subject: [PATCH 1/2] usb: dwc3: support for pinctrl state change during system
 sleep
In-Reply-To: <cover.1441029572.git.nsekhar@ti.com>
References: <cover.1441029572.git.nsekhar@ti.com>
Message-ID: <9dd70870cfee40154a37186d4cf3ae0e9a452cbd.1441029572.git.nsekhar@ti.com>

Add support for USB DRVVBUS pinctrl state change during
suspend/resume. This helps is conserving power during
system sleep.

Signed-off-by: Sekhar Nori <nsekhar at ti.com>
---
 drivers/usb/dwc3/core.c | 4 ++++
 1 file changed, 4 insertions(+)

diff --git a/drivers/usb/dwc3/core.c b/drivers/usb/dwc3/core.c
index ff5773c66b84..a5ffa66e39fb 100644
--- a/drivers/usb/dwc3/core.c
+++ b/drivers/usb/dwc3/core.c
@@ -1093,6 +1093,8 @@ static int dwc3_suspend(struct device *dev)
 	phy_exit(dwc->usb2_generic_phy);
 	phy_exit(dwc->usb3_generic_phy);
 
+	pinctrl_pm_select_sleep_state(dev);
+
 	return 0;
 }
 
@@ -1102,6 +1104,8 @@ static int dwc3_resume(struct device *dev)
 	unsigned long	flags;
 	int		ret;
 
+	pinctrl_pm_select_default_state(dev);
+
 	usb_phy_init(dwc->usb3_phy);
 	usb_phy_init(dwc->usb2_phy);
 	ret = phy_init(dwc->usb2_generic_phy);
-- 
2.4.4.408.g16da57c



From nsekhar at ti.com  Mon Aug 31 08:39:07 2015
From: nsekhar at ti.com (Sekhar Nori)
Date: Mon, 31 Aug 2015 21:09:07 +0530
Subject: [PATCH 0/2] AM437x: USB DWC3: save power during system sleep
Message-ID: <cover.1441029572.git.nsekhar@ti.com>

Hi,

This series add support to DWC3 core to conserve
power during system sleep by setting the USB
DRVVBUS line to a lower power consuming state.

Tested to make sure USB host and device works on
AM437x with v4.2. Tested for power savings on v4.1
kernel where there is an implementation of suspend-
to-RAM for AM437x available.

Dave Gerlach (1):
  ARM: dts: am437x-gp-evm: Add pinctrl states for usb

Sekhar Nori (1):
  usb: dwc3: support for pinctrl state change during system sleep

 arch/arm/boot/dts/am437x-gp-evm.dts | 30 ++++++++++++++++++++++++++++++
 drivers/usb/dwc3/core.c             |  4 ++++
 2 files changed, 34 insertions(+)

-- 
2.4.4.408.g16da57c



From nsekhar at ti.com  Mon Aug 31 08:39:09 2015
From: nsekhar at ti.com (Sekhar Nori)
Date: Mon, 31 Aug 2015 21:09:09 +0530
Subject: [PATCH 2/2] ARM: dts: am437x-gp-evm: Add pinctrl states for usb
In-Reply-To: <cover.1441029572.git.nsekhar@ti.com>
References: <cover.1441029572.git.nsekhar@ti.com>
Message-ID: <4a8a072030c2a82867c6548627739146681b35a5.1441029572.git.nsekhar@ti.com>

From: Dave Gerlach <d-gerlach at ti.com>

Add pinctrl default and sleep states for each usb device.
The only pin that can be controlled is USB_DRVVBUS, this
must be set to MUX_MODE7 (gpio) during sleep to conserve
power.

Signed-off-by: Dave Gerlach <d-gerlach at ti.com>
[nsekhar at ti.com: move pins to core dwc3]
Signed-off-by: Sekhar Nori <nsekhar at ti.com>
---
 arch/arm/boot/dts/am437x-gp-evm.dts | 30 ++++++++++++++++++++++++++++++
 1 file changed, 30 insertions(+)

diff --git a/arch/arm/boot/dts/am437x-gp-evm.dts b/arch/arm/boot/dts/am437x-gp-evm.dts
index 84aa30c3235a..2e990a5f9e95 100644
--- a/arch/arm/boot/dts/am437x-gp-evm.dts
+++ b/arch/arm/boot/dts/am437x-gp-evm.dts
@@ -409,6 +409,30 @@
 			0x234 (PIN_OUTPUT_PULLDOWN | MUX_MODE0) /* uart3_rtsn.uart3_rtsn */
 		>;
 	};
+
+	usb1_pins_default: usb1_pins_default {
+		pinctrl-single,pins = <
+			0x2c0 (DS0_PULL_UP_DOWN_EN | PIN_INPUT_PULLDOWN | MUX_MODE0)
+		>;
+	};
+
+	usb1_pins_sleep: usb1_pins_sleep {
+		pinctrl-single,pins = <
+			0x2c0 (DS0_PULL_UP_DOWN_EN | PIN_INPUT_PULLDOWN | MUX_MODE7)
+		>;
+	};
+
+	usb2_pins_default: usb2_pins_default {
+		pinctrl-single,pins = <
+			0x2c4 (DS0_PULL_UP_DOWN_EN | PIN_INPUT_PULLDOWN | MUX_MODE0)
+		>;
+	};
+
+	usb2_pins_sleep: usb2_pins_sleep {
+		pinctrl-single,pins = <
+			0x2c4 (DS0_PULL_UP_DOWN_EN | PIN_INPUT_PULLDOWN | MUX_MODE7)
+		>;
+	};
 };
 
 &i2c0 {
@@ -615,6 +639,9 @@
 &usb1 {
 	dr_mode = "peripheral";
 	status = "okay";
+	pinctrl-names = "default", "sleep";
+	pinctrl-0 = <&usb1_pins_default>;
+	pinctrl-1 = <&usb1_pins_sleep>;
 };
 
 &usb2_phy2 {
@@ -624,6 +651,9 @@
 &usb2 {
 	dr_mode = "host";
 	status = "okay";
+	pinctrl-names = "default", "sleep";
+	pinctrl-0 = <&usb2_pins_default>;
+	pinctrl-1 = <&usb2_pins_sleep>;
 };
 
 &mac {
-- 
2.4.4.408.g16da57c



From paul at pwsan.com  Mon Aug 31 08:51:06 2015
From: paul at pwsan.com (Paul Walmsley)
Date: Mon, 31 Aug 2015 15:51:06 +0000 (UTC)
Subject: [PATCH v2 2/5] ARM: OMAP2+: DRA7: Add hwmod entries for PWMSS
In-Reply-To: <55A7CE59.6010600@ti.com>
References: <1433332284-10766-1-git-send-email-vigneshr@ti.com>
 <1433332284-10766-3-git-send-email-vigneshr@ti.com>
 <alpine.DEB.2.02.1507152029460.32764@utopia.booyaka.com>
 <55A7CE59.6010600@ti.com>
Message-ID: <alpine.DEB.2.02.1508121700500.7154@utopia.booyaka.com>

Hi

On Thu, 16 Jul 2015, R, Vignesh wrote:

> On 07/16/2015 03:24 AM, Paul Walmsley wrote:
> > 
> > On Wed, 3 Jun 2015, Vignesh R wrote:
> > 
> >> Add hwmod entries for the PWMSS on DRA7.
> >>
> >> Set l4_root_clk_div as the main_clk of PWMSS. It is fixed-factored clock
> >> equal to L4PER2_L3_GICLK/2(l3_iclk_div/2).
> >> As per AM57x TRM SPRUHZ6[1], October 2014, Section 29.1.3 Table 29-4,
> >> clock source to PWMSS is L4PER2_L3_GICLK. But it is actually
> >> L4PER2_L3_GICLK/2. The TRM does not show the division by 2.
> > 
> > Is the divide-by-two coming from PWMSS_EPWM.EPWM_TBCTL[HSPCLKDIV]?  Or is 
> > HSPCLKDIV a separate divider after the divide-by-2 you mention above?
> 
> No, it not related to HSPCLKDIV. The TRM wrongly states L4PER2_L3_GICLK
> as clock input for PWMSS. But actually  L4PER2_L4_GICLK(=L3_GICLK/2) is
> the clock input for PWMSS. This will be updated in TRM soon.

OK

> >> --- a/arch/arm/mach-omap2/omap_hwmod_7xx_data.c
> >> +++ b/arch/arm/mach-omap2/omap_hwmod_7xx_data.c
> >> @@ -362,6 +362,149 @@ static struct omap_hwmod dra7xx_dcan2_hwmod = {
> >>  	},
> >>  };
> >>  
> >> +/* pwmss  */
> >> +static struct omap_hwmod_class_sysconfig dra7xx_epwmss_sysc = {
> >> +	.rev_offs	= 0x0,
> >> +	.sysc_offs	= 0x4,
> >> +	.sysc_flags	= SYSC_HAS_SIDLEMODE | SYSC_HAS_RESET_STATUS,
> > 
> > This doesn't match SPRUHZ6 Table 29-13 "PWMSS_SYSCONFIG".  There's no 
> > RESETSTATUS bit.  There is a SOFTRESET bit. 
> > 
> > Could you please confirm whether this is intentional?
> 
> sorry my bad... I will change this in v3.

OK

> >> +/* ecap0 */
> >> +struct omap_hwmod dra7xx_ecap0_hwmod = {
> >> +	.name		= "ecap0",
> >> +	.class		= &dra7xx_ecap_hwmod_class,
> >> +	.clkdm_name	= "l4per2_clkdm",
> >> +	.main_clk	= "l4_root_clk_div",
> > 
> > Looking at SPRUHZ6 Section 29.1.4.2 "PWMSS Modules Local Clock Gating", 
> > there appears to be a local "mini-PRCM" for the PWMSS which implements 
> > clock gating and reports back on the status of what I'd guess is the local 
> > clock gating FSM.
> > 
> > So from that point of view, you should probably create a clock driver that 
> > manages both the clock gate request bit and the FSM status bit.  It should 
> > be something that can be reused for the other PWMSS IP blocks.  Then 
> > you'd create per-IP block clock nodes and set the main_clk to point to 
> > that node.
> 
> Since, this register is within the config space of PWMSS, the individual
> gating and reporting for the modules within PWMSS
> (PWMSS_CLKCONFIG) is currently being taken care by pwm-tipwmss.c(almost
> the sole function this driver is doing). It has been the same since
> am335x. Adding new clock nodes will result in driver changes and also
> changes to am335x, am437x (and other platforms) hwmod files. It also
> involves adding new nodes to clocks.dtsi and it will be difficult to
> maintain backward compatibility for older platforms. Is it not better to
> keep this as is, in order to maintain consistency (with am335x, am437x
> etc) and also that these clock bits are within IP's config space?

It's certainly possible that we as maintainers didn't look closely enough 
at the AM33xx data for the PWMSS when we merged it.  But if that's 
incorrect too, then now is the time to fix this.  Otherwise it will never 
get fixed, since each new group of people patching this code will keep 
punting it off to the indeterminate future.

In terms of hwmod data: based on the register maps in sections 29.4.3, 
29.3.3, and 29.2.3 of SPRUHZ6, none of these subdevices are hwmod devices.  
They don't support the Highlander OCP registers, they have no individual 
PRCM registers or register bitfields, and all of the idle and status 
reporting is to the PWMSS top-level IP block itself.  So it looks to me 
like the eCAP, eQEP, and ePWM modules should be registered via DT, rather 
than via hwmod.  It looks like you can get away with using the 
"simple-bus" abstraction, but you might ultimately have to define 
something custom here.  However, the PWMSS top level subsystem, described 
in section 29.1, does have the OCP registers, sideband signals, etc., and 
thus should remain a hwmod-registered device (via DT).

In terms of the clock data: based on section 29.1.4, section 29.1.5.2, 
figure 29-3, and table 29-4, there are several clock gating control bits.  
These should be modeled as clock nodes in the Linux common clock 
framework.  Furthermore these registers are located inside the PWMSS 
subsystem itself, and are only accessible when the PWMSS IP block is 
functional in a PM runtime point of view: i.e., when the block is mapped 
into memory space, clocked and out of reset, etc.  So the clock types for 
the PWMSS_CFG IP block should most likely be implemented in the PWMSS 
driver.  I think you'll still be able to define the clock node data itself 
in DT, but this will probably need a closer look.  Ideally, since the 
clock node register address data is the same for all three subsystem 
instances, one would be able to simply include a DT include file three 
times; but the DT binding data format may ultimately make this 
impractical.

In terms of the transition from the old approach to this approach, it ooks 
to me like the first thing to do would be to convert
drivers/pwm/pwm-tipwmss.c to define some clk_ops and register some clock
nodes with the CCF.  You've got the meat of the clock gating control code
there already.  Then the next thing to do would be to to get rid of
pwmss_submodule_state_change() and use
clk_{prepare,enable,disable,unprepare}*() in the drivers/pwm/pwm-ti*.c
subdrivers instead.  All of that looks like it should be possible to  
implement in a backwards-compatible way.  Then you'd convert the eCAP, 
eQEP, and ePWM code to probe as platform_devices, driven from a simple-bus 
or pwmss-bus or whatever in the DT data.  Naturally, the AM33xx/43xx data 
should be fixed also.  


- Paul


From gregory.clement at free-electrons.com  Mon Aug 31 08:52:42 2015
From: gregory.clement at free-electrons.com (Gregory CLEMENT)
Date: Mon, 31 Aug 2015 17:52:42 +0200
Subject: [PATCH] usb: musb: dsps: handle the
 otg_state_a_wait_vrise_timeout case
In-Reply-To: <55D719B1.8010700@free-electrons.com> (Gregory CLEMENT's message
 of "Fri, 21 Aug 2015 14:29:37 +0200")
References: <1440087153-31084-1-git-send-email-gregory.clement@free-electrons.com>
 <55D719B1.8010700@free-electrons.com>
Message-ID: <87twrfsbed.fsf@free-electrons.com>

Hi Felipe,
 
 On ven., ao?t 21 2015, Gregory CLEMENT <gregory.clement at free-electrons.com> wrote:
>> According to the OTG specification after a timeout of
>> OTG_TIME_A_WAIT_VRISE (the maximum value is 100ms) the driver must
>> move from the state a_wait_vrise to the state a_wait_bcon. However,
>> the dsps version of musb does not handle this case.
>> 
>> Without it, the driver could remain stuck in the a_wait_vrise. It can
>> be reproduce with the following steps:
>> 
>> 1) Boot a board with no USB adapter inserted
>> 2) Insert an empty OTG adapter
>> 3) Wait 2 seconds then remove the OTG adapter
>> 4) The unit is now stuck in host mode, the VBUS switch is latched on
>> and the ID pin is no longer polled.
>> 
>> The only way to exit this state was to insert a OTG adapter with an
>> USB device connected. Until this, the usb device mode was not
>> available.
>> 
>> It was tested on a AM35x based board.
>> 
>> CC: <stable at vger.kernel.org>
>> Signed-off-by: Gregory CLEMENT <gregory.clement at free-electrons.com>
>> ---
>>  drivers/usb/musb/musb_dsps.c | 14 +++++++++++++-
>>  1 file changed, 13 insertions(+), 1 deletion(-)
>> 
>> diff --git a/drivers/usb/musb/musb_dsps.c b/drivers/usb/musb/musb_dsps.c
>> index 65d931a..2d22683 100644
>> --- a/drivers/usb/musb/musb_dsps.c
>> +++ b/drivers/usb/musb/musb_dsps.c
>> @@ -145,6 +145,7 @@ struct dsps_glue {
>>  	struct timer_list timer;	/* otg_workaround timer */
>>  	unsigned long last_timer;    /* last timer data for each instance */
>>  	bool sw_babble_enabled;
>> +	int otg_state_a_wait_vrise_timeout;
>>  
>>  	struct dsps_context context;
>>  	struct debugfs_regset32 regset;
>> @@ -268,9 +269,18 @@ static void otg_timer(unsigned long _musb)
>>  
>>  	spin_lock_irqsave(&musb->lock, flags);
>>  	switch (musb->xceiv->otg->state) {
>> +	case OTG_STATE_A_WAIT_VRISE:
>> +		if ((glue->otg_state_a_wait_vrise_timeout)) {
>> +				musb->xceiv->otg->state = OTG_STATE_A_WAIT_BCON;
>> +				musb->is_active = 0;
>> +			}
>> +		mod_timer(&glue->timer, jiffies +
>> +			  msecs_to_jiffies(OTG_TIME_A_WAIT_VRISE));
>
> After more test on more USB drive, it seems that for some of them
> OTG_TIME_A_WAIT_VRISE is too short. 200ms seems better. It is
> disturbing because according to the OTG specification the maximum
> is 100ms, however I am not so surprised that USB device maker don't
> follow it.

So after many tests on different devices, 200ms is enough for most of
them, but for one, 2000ms (2s) was needed!

I see several option:
- adding a sysfs entry to setup the time
- adding a debugs entry entry
- adding configuration option in menuconfig
- using 2000ms and hopping it was enough for everyone

My preference would go to the first option, what is your opinion?

Thanks,

Gregory

>
>
>> +		break;
>>  	case OTG_STATE_A_WAIT_BCON:
>>  		dsps_writeb(musb->mregs, MUSB_DEVCTL, 0);
>>  		skip_session = 1;
>> +		glue->otg_state_a_wait_vrise_timeout = 0;
>>  		/* fall */
>>  
>>  	case OTG_STATE_A_IDLE:
>> @@ -359,7 +369,9 @@ static irqreturn_t dsps_interrupt(int irq, void *hci)
>>  			MUSB_HST_MODE(musb);
>>  			musb->xceiv->otg->default_a = 1;
>>  			musb->xceiv->otg->state = OTG_STATE_A_WAIT_VRISE;
>> -			del_timer(&glue->timer);
>> +			glue->otg_state_a_wait_vrise_timeout = 1;
>> +			mod_timer(&glue->timer, jiffies +
>> +				  msecs_to_jiffies(OTG_TIME_A_WAIT_VRISE));
>>  		} else {
>>  			musb->is_active = 0;
>>  			MUSB_DEV_MODE(musb);
>> 
>
>
> -- 
> Gregory Clement, Free Electrons
> Kernel, drivers, real-time and embedded Linux
> development, consulting, training and support.
> http://free-electrons.com
> --
> To unsubscribe from this list: send the line "unsubscribe linux-usb" in
> the body of a message to majordomo at vger.kernel.org
> More majordomo info at  http://vger.kernel.org/majordomo-info.html

-- 
Gregory Clement, Free Electrons
Kernel, drivers, real-time and embedded Linux
development, consulting, training and support.
http://free-electrons.com


From lorenzo.pieralisi at arm.com  Mon Aug 31 09:33:14 2015
From: lorenzo.pieralisi at arm.com (Lorenzo Pieralisi)
Date: Mon, 31 Aug 2015 17:33:14 +0100
Subject: [PATCH] ARM64: PCI: do not enable resources on PROBE_ONLY systems
In-Reply-To: <20150831132803.GB647@google.com>
References: <1438262039-32085-1-git-send-email-lorenzo.pieralisi@arm.com>
 <20150828211444.GA27890@google.com>
 <20150829124457.GA18125@red-moon> <20150831132803.GB647@google.com>
Message-ID: <20150831163314.GA19309@red-moon>

On Mon, Aug 31, 2015 at 02:28:03PM +0100, Bjorn Helgaas wrote:
> On Sat, Aug 29, 2015 at 01:44:57PM +0100, Lorenzo Pieralisi wrote:
> > On Fri, Aug 28, 2015 at 10:14:44PM +0100, Bjorn Helgaas wrote:
> > > On Thu, Jul 30, 2015 at 02:13:59PM +0100, Lorenzo Pieralisi wrote:
> > > > On ARM64 PROBE_ONLY PCI systems resources are not currently claimed,
> > > > therefore they can't be enabled since they do not have a valid
> > > > parent pointer; this in turn prevents enabling PCI devices on
> > > > ARM64 PROBE_ONLY systems, causing PCI devices initialization to
> > > > fail.
> > > 
> > > Where does arm64 claim PCI BAR resources for the non-PROBE_ONLY case?
> > 
> > arm64 (and arm) does not claim resources in arch code, they are always
> > assigned in the respective host controllers (or the pcibios on arm),
> > except for the PCI generic host when in PROBE_ONLY mode, where resources
> > are neither claimed nor assigned (the reason for this patch to exist).
> > ...
> > 
> > > I know it must be there somewhere, but I don't see it.
> > 
> > It is not there, it is done in the host controllers by assigning the
> > resources (which also "claim" them by assigning the parent pointer).
> 
> The host controller drivers should claim the apertures forwarded to
> the PCI bus.  For pci-host-generic, this happens when
> gen_pci_parse_request_of_pci_ranges() calls devm_request_resource().

Yes, the generic host claims the apertures at DT probing time.

> But that doesn't do anything for the BARs of the PCI devices
> themselves, of course.
> 
> If this patch fixes a problem that will occur in the future, when we
> add arm/arm64 code to claim BARs, let's make this patch part of that
> series.  If it fixes a problem in the current tree, I'll merge it now,
> but so far I haven't been able to make the connection between this
> patch and a problem in the current code.

It fixes a problem in the current tree (I mean when the PCI pull is
merged - it contains code that enables PCI host generic on arm64),
since without it PROBE_ONLY systems (ie PCI host generic on kvmtool) would
try to enable resources and fail, since the resources were not claimed.

It works the same way as arm, I will rework both arches when I am done
refactoring the resource claiming implementation.

Will picked it up already I do not know what's the best way to
merge it I guess it can go via the arm64 tree if you do not have any
objections.

Thank you !
Lorenzo

> > > > To solve this issue, resources must be claimed when devices are
> > > > added on PROBE_ONLY systems, which ensures that the resource hierarchy
> > > > is validated and the resource tree is sane, but this requires changes
> > > > in the ARM64 resource management that can affect adversely existing
> > > > PCI set-ups (claiming resources on !PROBE_ONLY systems might break
> > > > existing ARM64 PCI platform implementations).
> > > > 
> > > > As a temporary solution in preparation for a proper resources claiming
> > > > implementation in ARM64 core, to enable PCI PROBE_ONLY systems on ARM64,
> > > > this patch adds a pcibios_enable_device() arch implementation that
> > > > simply prevents enabling resources on PROBE_ONLY systems (mirroring ARM
> > > > behaviour).
> > > > 
> > > > This is always a safe thing to do because on PROBE_ONLY systems the
> > > > configuration space set-up can be considered immutable, and it is in
> > > > preparation of proper resource claiming that would finally validate
> > > > the PCI resources tree in the ARM64 arch implementation on PROBE_ONLY
> > > > systems.
> > > > 
> > > > For !PROBE_ONLY systems resources enablement in pcibios_enable_device()
> > > > on ARM64 is implemented as in current PCI core, leaving the behaviour
> > > > unchanged.
> > > > 
> > > > Signed-off-by: Lorenzo Pieralisi <lorenzo.pieralisi at arm.com>
> > > > Cc: Will Deacon <will.deacon at arm.com>
> > > > Cc: Bjorn Helgaas <bhelgaas at google.com>
> > > > Cc: Catalin Marinas <catalin.marinas at arm.com>
> > > > ---
> > > > Bjorn, all,
> > > > 
> > > > as I mention in the commit log, this patch is a temporary solution
> > > > in preparation for proper resources claiming in ARM64, so that
> > > > we can safely enable the PCI generic host controller on ARM64 systems.
> > > > 
> > > > It mirrors ARM implementation and I will work on changing both
> > > > ARM and ARM64 to convert them to proper resources claiming in
> > > > the respective implementations.
> > > > 
> > > > Lorenzo
> > > > 
> > > >  arch/arm64/kernel/pci.c | 13 +++++++++++++
> > > >  1 file changed, 13 insertions(+)
> > > > 
> > > > diff --git a/arch/arm64/kernel/pci.c b/arch/arm64/kernel/pci.c
> > > > index 4095379..b3d098b 100644
> > > > --- a/arch/arm64/kernel/pci.c
> > > > +++ b/arch/arm64/kernel/pci.c
> > > > @@ -38,6 +38,19 @@ resource_size_t pcibios_align_resource(void *data, const struct resource *res,
> > > >  	return res->start;
> > > >  }
> > > >  
> > > > +/**
> > > > + * pcibios_enable_device - Enable I/O and memory.
> > > > + * @dev: PCI device to be enabled
> > > > + * @mask: bitmask of BARs to enable
> > > > + */
> > > > +int pcibios_enable_device(struct pci_dev *dev, int mask)
> > > > +{
> > > > +	if (pci_has_flag(PCI_PROBE_ONLY))
> > > > +		return 0;
> > > > +
> > > > +	return pci_enable_resources(dev, mask);
> > > > +}
> > > > +
> > > >  /*
> > > >   * Try to assign the IRQ number from DT when adding a new device
> > > >   */
> > > > -- 
> > > > 2.2.1
> > > > 
> > > 
> 


From l.stach at pengutronix.de  Mon Aug 31 09:36:27 2015
From: l.stach at pengutronix.de (Lucas Stach)
Date: Mon, 31 Aug 2015 18:36:27 +0200
Subject: [PATCH 0/8] i.MX early debug UART clock fixes
In-Reply-To: <1440693561-28095-1-git-send-email-l.stach@pengutronix.de>
References: <1440693561-28095-1-git-send-email-l.stach@pengutronix.de>
Message-ID: <1441038987.3652.44.camel@pengutronix.de>

Am Donnerstag, den 27.08.2015, 18:39 +0200 schrieb Lucas Stach:
> This series fixes a long standing interaction issue between the
> kernels early debug facilities and the i.MX clock drivers.
> 
> Both earlyprintk and earlycon rely on the bootloader setup clocks
> for the UARTs to be retained during kernel init. As those clocks are
> only enabled in hardware, but not referenced in software they (or even
> their parent clocks) may get disabled as a result of other clocks being
> en-/disabled during boot.
> 
> This results in missing messages from the early debug console until the
> regular system console takes over, or even worse system hangs in response
> to unclocked register accesses. This renders those debugging facilities a
> lot less useful.
> 
> The fix implemented here is to check if any of this early debugging is
> enabled and keep the UART clocks referenced and enabled in that case.
> The clocks will then only be disabled at the end of kernel init, at which
> point the real console should have taken over and the early outputs being
> disabled.
> 
> I've runtime tested this on i.MX6Q and i.MX53, other platforms are only
> compile tested. This is mostly a mechanical change, but still I would
> appreciate some testing.
> 
And Philipp noted that passing in a list of clocks from the clock
providers look a lot better than the current direct clock enable calling
and the needed callback.

I'm self-nacking this series, so I can spin a V2 with changes as above.

> Regards,
> Lucas
> 
> Lucas Stach (8):
>   clk: imx: add common logic to detect early UART usage
>   clk: imx25: retain early UART clocks during kernel init
>   clk: imx27: retain early UART clocks during kernel init
>   clk: imx31: retain early UART clocks during kernel init
>   clk: imx35: retain early UART clocks during kernel init
>   clk: imx5: retain early UART clocks during kernel init
>   clk: imx6: retain early UART clocks during kernel init
>   clk: imx7d: retain early UART clocks during kernel init
> 
>  drivers/clk/imx/clk-imx25.c       | 20 ++++++++++++++++++++
>  drivers/clk/imx/clk-imx27.c       | 22 ++++++++++++++++++++++
>  drivers/clk/imx/clk-imx31.c       | 20 ++++++++++++++++++++
>  drivers/clk/imx/clk-imx35.c       | 16 ++++++++++++++++
>  drivers/clk/imx/clk-imx51-imx53.c | 28 ++++++++++++++++++++++++++++
>  drivers/clk/imx/clk-imx6q.c       | 12 ++++++++++++
>  drivers/clk/imx/clk-imx6sl.c      | 12 ++++++++++++
>  drivers/clk/imx/clk-imx6sx.c      | 12 ++++++++++++
>  drivers/clk/imx/clk-imx7d.c       | 22 ++++++++++++++++++++++
>  drivers/clk/imx/clk.c             | 33 +++++++++++++++++++++++++++++++++
>  drivers/clk/imx/clk.h             |  2 ++
>  11 files changed, 199 insertions(+)
> 

-- 
Pengutronix e.K.             | Lucas Stach                 |
Industrial Linux Solutions   | http://www.pengutronix.de/  |



From bhelgaas at google.com  Mon Aug 31 09:49:20 2015
From: bhelgaas at google.com (Bjorn Helgaas)
Date: Mon, 31 Aug 2015 11:49:20 -0500
Subject: [PATCH] ARM64: PCI: do not enable resources on PROBE_ONLY systems
In-Reply-To: <20150831163314.GA19309@red-moon>
References: <1438262039-32085-1-git-send-email-lorenzo.pieralisi@arm.com>
 <20150828211444.GA27890@google.com> <20150829124457.GA18125@red-moon>
 <20150831132803.GB647@google.com> <20150831163314.GA19309@red-moon>
Message-ID: <CAErSpo5188hGiySG+JweWOvfj6aZtAfVta4=0wwwRmMTp+9tFg@mail.gmail.com>

On Mon, Aug 31, 2015 at 11:33 AM, Lorenzo Pieralisi
<lorenzo.pieralisi at arm.com> wrote:
> On Mon, Aug 31, 2015 at 02:28:03PM +0100, Bjorn Helgaas wrote:
>> On Sat, Aug 29, 2015 at 01:44:57PM +0100, Lorenzo Pieralisi wrote:
>> > On Fri, Aug 28, 2015 at 10:14:44PM +0100, Bjorn Helgaas wrote:
>> > > On Thu, Jul 30, 2015 at 02:13:59PM +0100, Lorenzo Pieralisi wrote:
>> > > > On ARM64 PROBE_ONLY PCI systems resources are not currently claimed,
>> > > > therefore they can't be enabled since they do not have a valid
>> > > > parent pointer; this in turn prevents enabling PCI devices on
>> > > > ARM64 PROBE_ONLY systems, causing PCI devices initialization to
>> > > > fail.
>> > >
>> > > Where does arm64 claim PCI BAR resources for the non-PROBE_ONLY case?
>> >
>> > arm64 (and arm) does not claim resources in arch code, they are always
>> > assigned in the respective host controllers (or the pcibios on arm),
>> > except for the PCI generic host when in PROBE_ONLY mode, where resources
>> > are neither claimed nor assigned (the reason for this patch to exist).
>> > ...
>> >
>> > > I know it must be there somewhere, but I don't see it.
>> >
>> > It is not there, it is done in the host controllers by assigning the
>> > resources (which also "claim" them by assigning the parent pointer).
>>
>> The host controller drivers should claim the apertures forwarded to
>> the PCI bus.  For pci-host-generic, this happens when
>> gen_pci_parse_request_of_pci_ranges() calls devm_request_resource().
>
> Yes, the generic host claims the apertures at DT probing time.
>
>> But that doesn't do anything for the BARs of the PCI devices
>> themselves, of course.
>>
>> If this patch fixes a problem that will occur in the future, when we
>> add arm/arm64 code to claim BARs, let's make this patch part of that
>> series.  If it fixes a problem in the current tree, I'll merge it now,
>> but so far I haven't been able to make the connection between this
>> patch and a problem in the current code.
>
> It fixes a problem in the current tree (I mean when the PCI pull is
> merged - it contains code that enables PCI host generic on arm64),
> since without it PROBE_ONLY systems (ie PCI host generic on kvmtool) would
> try to enable resources and fail, since the resources were not claimed.
>
> It works the same way as arm, I will rework both arches when I am done
> refactoring the resource claiming implementation.
>
> Will picked it up already I do not know what's the best way to
> merge it I guess it can go via the arm64 tree if you do not have any
> objections.

OK, if it fixes a problem in my v4.3 pull request, we need to merge
it.  I missed the connection, probably because I was browsing the
v4.2-rc1 tree, which wouldn't have those changes.

It's OK with me to merge it via the arm64 tree.

>> > > > To solve this issue, resources must be claimed when devices are
>> > > > added on PROBE_ONLY systems, which ensures that the resource hierarchy
>> > > > is validated and the resource tree is sane, but this requires changes
>> > > > in the ARM64 resource management that can affect adversely existing
>> > > > PCI set-ups (claiming resources on !PROBE_ONLY systems might break
>> > > > existing ARM64 PCI platform implementations).
>> > > >
>> > > > As a temporary solution in preparation for a proper resources claiming
>> > > > implementation in ARM64 core, to enable PCI PROBE_ONLY systems on ARM64,
>> > > > this patch adds a pcibios_enable_device() arch implementation that
>> > > > simply prevents enabling resources on PROBE_ONLY systems (mirroring ARM
>> > > > behaviour).
>> > > >
>> > > > This is always a safe thing to do because on PROBE_ONLY systems the
>> > > > configuration space set-up can be considered immutable, and it is in
>> > > > preparation of proper resource claiming that would finally validate
>> > > > the PCI resources tree in the ARM64 arch implementation on PROBE_ONLY
>> > > > systems.
>> > > >
>> > > > For !PROBE_ONLY systems resources enablement in pcibios_enable_device()
>> > > > on ARM64 is implemented as in current PCI core, leaving the behaviour
>> > > > unchanged.
>> > > >
>> > > > Signed-off-by: Lorenzo Pieralisi <lorenzo.pieralisi at arm.com>
>> > > > Cc: Will Deacon <will.deacon at arm.com>
>> > > > Cc: Bjorn Helgaas <bhelgaas at google.com>
>> > > > Cc: Catalin Marinas <catalin.marinas at arm.com>
>> > > > ---
>> > > > Bjorn, all,
>> > > >
>> > > > as I mention in the commit log, this patch is a temporary solution
>> > > > in preparation for proper resources claiming in ARM64, so that
>> > > > we can safely enable the PCI generic host controller on ARM64 systems.
>> > > >
>> > > > It mirrors ARM implementation and I will work on changing both
>> > > > ARM and ARM64 to convert them to proper resources claiming in
>> > > > the respective implementations.
>> > > >
>> > > > Lorenzo
>> > > >
>> > > >  arch/arm64/kernel/pci.c | 13 +++++++++++++
>> > > >  1 file changed, 13 insertions(+)
>> > > >
>> > > > diff --git a/arch/arm64/kernel/pci.c b/arch/arm64/kernel/pci.c
>> > > > index 4095379..b3d098b 100644
>> > > > --- a/arch/arm64/kernel/pci.c
>> > > > +++ b/arch/arm64/kernel/pci.c
>> > > > @@ -38,6 +38,19 @@ resource_size_t pcibios_align_resource(void *data, const struct resource *res,
>> > > >         return res->start;
>> > > >  }
>> > > >
>> > > > +/**
>> > > > + * pcibios_enable_device - Enable I/O and memory.
>> > > > + * @dev: PCI device to be enabled
>> > > > + * @mask: bitmask of BARs to enable
>> > > > + */
>> > > > +int pcibios_enable_device(struct pci_dev *dev, int mask)
>> > > > +{
>> > > > +       if (pci_has_flag(PCI_PROBE_ONLY))
>> > > > +               return 0;
>> > > > +
>> > > > +       return pci_enable_resources(dev, mask);
>> > > > +}
>> > > > +
>> > > >  /*
>> > > >   * Try to assign the IRQ number from DT when adding a new device
>> > > >   */
>> > > > --
>> > > > 2.2.1
>> > > >
>> > >
>>


From jic23 at kernel.org  Mon Aug 31 10:06:07 2015
From: jic23 at kernel.org (Jonathan Cameron)
Date: Mon, 31 Aug 2015 18:06:07 +0100
Subject: [V4] [TWL4030 MADC] Fix ADC[3:6] readings
In-Reply-To: <CAFeBWL5JT=+X9SCwRefn8L9Epx_c0yaizS5=1W4eq_O3Fpg7Lg@mail.gmail.com>
References: <1438712148-27004-1-git-send-email-adam.yh.lee@gmail.com>
 <1438712148-27004-2-git-send-email-adam.yh.lee@gmail.com>
 <55C61D22.7080604@kernel.org>
 <CAFeBWL5JT=+X9SCwRefn8L9Epx_c0yaizS5=1W4eq_O3Fpg7Lg@mail.gmail.com>
Message-ID: <55E4897F.8060809@kernel.org>

On 10/08/15 17:56, Adam Lee wrote:
> Yes I will do a better job in following the patch submission conventions.
> Thanks for your comment Jonathan.
> 
> @Sebastian, let me know if you have any concerns with the patch.
This has been sat around for long enough that I suspect Sebastian isn't
going to reply.  As such I've just applied it as is to the fixes-togreg
branch of iio.git (with some editing of the patch description!)

Thanks,

Jonathan
> 
> 
> 
> On Sat, Aug 8, 2015 at 8:15 AM Jonathan Cameron <jic23 at kernel.org <mailto:jic23 at kernel.org>> wrote:
> 
>     On 04/08/15 19:15, Adam YH Lee wrote:
>     > MADC[3:6] reads incorrect values without these two following changes:
>     >
>     > - enable the 3v1 bias regulator for ADC[3:6]
>     > - configure ADC[3:6] lines as input, not as USB
>     >
>     > Signed-off-by: Adam YH Lee <adam.yh.lee at gmail.com <mailto:adam.yh.lee at gmail.com>>
>     I'd ideally like an ack from the driver author or Sebastian as this isn't
>     a driver I'm particular familiar with.
> 
>     Also, for future reference, patches should be titled something like
>     [Patch v4] iio: twl4030 madc: Fix ADC[3:6] readings.
>     (the patch bit is standard, the rest is iio convention)
> 
>     Jonathan
> 
>     > ---
>     >  drivers/iio/adc/twl4030-madc.c | 34 ++++++++++++++++++++++++++++++++++
>     >  1 file changed, 34 insertions(+)
>     >
>     > diff --git a/drivers/iio/adc/twl4030-madc.c b/drivers/iio/adc/twl4030-madc.c
>     > index 94c5f05..8c58498 100644
>     > --- a/drivers/iio/adc/twl4030-madc.c
>     > +++ b/drivers/iio/adc/twl4030-madc.c
>     > @@ -45,13 +45,18 @@
>     >  #include <linux/types.h>
>     >  #include <linux/gfp.h>
>     >  #include <linux/err.h>
>     > +#include <linux/regulator/consumer.h>
>     >
>     >  #include <linux/iio/iio.h>
>     >
>     > +#define TWL4030_USB_SEL_MADC_MCPC    (1<<3)
>     > +#define TWL4030_USB_CARKIT_ANA_CTRL  0xBB
>     > +
>     >  /**
>     >   * struct twl4030_madc_data - a container for madc info
>     >   * @dev:             Pointer to device structure for madc
>     >   * @lock:            Mutex protecting this data structure
>     > + * @regulator:               Pointer to bias regulator for madc
>     >   * @requests:                Array of request struct corresponding to SW1, SW2 and RT
>     >   * @use_second_irq:  IRQ selection (main or co-processor)
>     >   * @imr:             Interrupt mask register of MADC
>     > @@ -60,6 +65,7 @@
>     >  struct twl4030_madc_data {
>     >       struct device *dev;
>     >       struct mutex lock;      /* mutex protecting this data structure */
>     > +     struct regulator *usb3v1;
>     >       struct twl4030_madc_request requests[TWL4030_MADC_NUM_METHODS];
>     >       bool use_second_irq;
>     >       u8 imr;
>     > @@ -842,6 +848,32 @@ static int twl4030_madc_probe(struct platform_device *pdev)
>     >       }
>     >       twl4030_madc = madc;
>     >
>     > +     /* Configure MADC[3:6] */
>     > +     ret = twl_i2c_read_u8(TWL_MODULE_USB, &regval,
>     > +                     TWL4030_USB_CARKIT_ANA_CTRL);
>     > +     if (ret) {
>     > +             dev_err(&pdev->dev, "unable to read reg CARKIT_ANA_CTRL  0x%X\n",
>     > +                             TWL4030_USB_CARKIT_ANA_CTRL);
>     > +             goto err_i2c;
>     > +     }
>     > +     regval |= TWL4030_USB_SEL_MADC_MCPC;
>     > +     ret = twl_i2c_write_u8(TWL_MODULE_USB, regval,
>     > +                              TWL4030_USB_CARKIT_ANA_CTRL);
>     > +     if (ret) {
>     > +             dev_err(&pdev->dev, "unable to write reg CARKIT_ANA_CTRL 0x%X\n",
>     > +                             TWL4030_USB_CARKIT_ANA_CTRL);
>     > +             goto err_i2c;
>     > +     }
>     > +
>     > +     /* Enable 3v1 bias regulator for MADC[3:6] */
>     > +     madc->usb3v1 = devm_regulator_get(madc->dev, "vusb3v1");
>     > +     if (IS_ERR(madc->usb3v1))
>     > +             return -ENODEV;
>     > +
>     > +     ret = regulator_enable(madc->usb3v1);
>     > +     if (ret)
>     > +             dev_err(madc->dev, "could not enable 3v1 bias regulator\n");
>     > +
>     >       ret = iio_device_register(iio_dev);
>     >       if (ret) {
>     >               dev_err(&pdev->dev, "could not register iio device\n");
>     > @@ -867,6 +899,8 @@ static int twl4030_madc_remove(struct platform_device *pdev)
>     >       twl4030_madc_set_current_generator(madc, 0, 0);
>     >       twl4030_madc_set_power(madc, 0);
>     >
>     > +     regulator_disable(madc->usb3v1);
>     > +
>     >       return 0;
>     >  }
>     >
>     >
> 



From heiko at sntech.de  Mon Aug 31 11:24:03 2015
From: heiko at sntech.de (Heiko Stuebner)
Date: Mon, 31 Aug 2015 20:24:03 +0200
Subject: [PATCH 5/8] mmc: dw_mmc: dt-binding: Add tuning related things
In-Reply-To: <1441045446-30858-1-git-send-email-heiko@sntech.de>
References: <1441045446-30858-1-git-send-email-heiko@sntech.de>
Message-ID: <1441045446-30858-6-git-send-email-heiko@sntech.de>

From: Alexandru M Stan <amstan at chromium.org>

Add ciu_drv, ciu_sample clocks and default-sample-phase. This will later
be used by tuning code.

We do not touch ciu_drive (and by extension define default-drive-phase).
Drive phase is mostly used to define minimum hold times, while one could
write some code to determine what phase meets the minimum hold time
(ex 10 degrees) this will not work with the current clock phase framework
(which floors angles, so we'll get 0 deg, and there's no way to know what
resolution the floors happen at). We assume that the default drive angles
set by the hardware are good enough.

Signed-off-by: Alexandru M Stan <amstan at chromium.org>
Signed-off-by: Heiko Stuebner <heiko at sntech.de>
---
 Documentation/devicetree/bindings/mmc/synopsys-dw-mshc.txt | 14 ++++++++++----
 1 file changed, 10 insertions(+), 4 deletions(-)

diff --git a/Documentation/devicetree/bindings/mmc/synopsys-dw-mshc.txt b/Documentation/devicetree/bindings/mmc/synopsys-dw-mshc.txt
index 346c609..5edadc2 100644
--- a/Documentation/devicetree/bindings/mmc/synopsys-dw-mshc.txt
+++ b/Documentation/devicetree/bindings/mmc/synopsys-dw-mshc.txt
@@ -42,11 +42,13 @@ Optional properties:
 * clocks: from common clock binding: handle to biu and ciu clocks for the
   bus interface unit clock and the card interface unit clock.
 
-* clock-names: from common clock binding: Shall be "biu" and "ciu".
-  If the biu clock is missing we'll simply skip enabling it.  If the
-  ciu clock is missing we'll just assume that the clock is running at
+* clock-names: from common clock binding: Shall be "biu", "ciu", "ciu_drv" and
+  "ciu_sample".  If the biu clock is missing we'll simply skip enabling it.
+  If the ciu clock is missing we'll just assume that the clock is running at
   clock-frequency.  It is an error to omit both the ciu clock and the
-  clock-frequency.
+  clock-frequency.  "ciu_drv" and "ciu_sample" are used to control the clock
+  phases, "ciu_sample" is required for tuning high speed modes (if no other
+  custom tuning method is defined).
 
 * clock-frequency: should be the frequency (in Hz) of the ciu clock.  If this
   is specified and the ciu clock is specified then we'll try to set the ciu
@@ -75,6 +77,10 @@ Optional properties:
 * vmmc-supply: The phandle to the regulator to use for vmmc.  If this is
   specified we'll defer probe until we can find this regulator.
 
+* default-sample-phase: The default phase to set ciu_sample at probing, low
+  speeds or in case where all phases work at tuning time. If not specified
+  0 deg will be used.
+
 Aliases:
 
 - All the MSHC controller nodes should be represented in the aliases node using
-- 
2.1.4



From heiko at sntech.de  Mon Aug 31 11:23:58 2015
From: heiko at sntech.de (Heiko Stuebner)
Date: Mon, 31 Aug 2015 20:23:58 +0200
Subject: [PATCH 0/8] mmc: dw_mmc: allow tuning using the clk-phase api
Message-ID: <1441045446-30858-1-git-send-email-heiko@sntech.de>

This series resurrects and adapts some individual patches whose sum
enable the dw_mmc hosts on Rockchip socs to tune clock phases using
the generic phase api (rk3288 and following have this capability).

The changes to the original mmc-phase clocks are expanded by further
findings resulting from devices being used in the field.

Similarly the regulator handling changes do use the brand new
regulator_set_voltage_triplet call to allow specifying lower and upper
limits. One possible point of discussion are the two voltage ranges
that are tried for the 3.3V signal level. Trying to stay near vmmc
at first and only then opening the range to the full 2.7-3.6V.

This mainly circumvents a shortcoming of the regulator voltage
setting, in that even with regulator_set_voltage_triplet the regulator
framework will take the lowest possible voltage when the possible
voltages are below the target voltage. While it may be ideal to solve
this on the regulator side, I'm not seeing this appearing in the short
term, mainly because all regulator parts (including regulator drivers)
are keyed to selecting the lowest voltage from the range, while on the
mmc side we know which voltages may work and trying this in two steps
does not create to much overhead, as unsupported voltages are already
filtered out by the regulator_is_voltage_selected calls.


Alexandru M Stan (3):
  mmc: dw_mmc: dt-binding: Add tuning related things
  mmc: dw_mmc: Generic MMC tuning with the clock phase framework
  ARM: dts: rockchip: Add drive/sample clocks for rk3288 dw_mmc devices

Douglas Anderson (4):
  clk: rockchip: Allow more precision for some mmc clock phases
  clk: rockchip: Make calculations use rounding
  mmc: core: Add mmc_regulator_set_vqmmc()
  mmc: dw_mmc: Use mmc_regulator_set_vqmmc in
    start_signal_voltage_switch

Heiko Stuebner (1):
  ARM: dts: rockchip: add tuning related settings to veyron devices

 .../devicetree/bindings/mmc/synopsys-dw-mshc.txt   |  14 +-
 arch/arm/boot/dts/rk3288-veyron-sdmmc.dtsi         |   7 +-
 arch/arm/boot/dts/rk3288-veyron.dtsi               |   6 +
 arch/arm/boot/dts/rk3288.dtsi                      |  20 +--
 drivers/clk/rockchip/clk-mmc-phase.c               |  54 ++++---
 drivers/mmc/core/core.c                            |  68 +++++++++
 drivers/mmc/host/dw_mmc.c                          | 159 +++++++++++++++++++--
 include/linux/mmc/dw_mmc.h                         |   3 +
 include/linux/mmc/host.h                           |   7 +
 9 files changed, 295 insertions(+), 43 deletions(-)

-- 
2.1.4



From heiko at sntech.de  Mon Aug 31 11:24:06 2015
From: heiko at sntech.de (Heiko Stuebner)
Date: Mon, 31 Aug 2015 20:24:06 +0200
Subject: [PATCH 8/8] ARM: dts: rockchip: add tuning related settings to veyron
 devices
In-Reply-To: <1441045446-30858-1-git-send-email-heiko@sntech.de>
References: <1441045446-30858-1-git-send-email-heiko@sntech.de>
Message-ID: <1441045446-30858-9-git-send-email-heiko@sntech.de>

This allows the tuning code to run and use higher speeds on capable cards.

Signed-off-by: Heiko Stuebner <heiko at sntech.de>
---
 arch/arm/boot/dts/rk3288-veyron-sdmmc.dtsi | 7 ++++++-
 arch/arm/boot/dts/rk3288-veyron.dtsi       | 6 ++++++
 2 files changed, 12 insertions(+), 1 deletion(-)

diff --git a/arch/arm/boot/dts/rk3288-veyron-sdmmc.dtsi b/arch/arm/boot/dts/rk3288-veyron-sdmmc.dtsi
index b5334ec..24a7a11 100644
--- a/arch/arm/boot/dts/rk3288-veyron-sdmmc.dtsi
+++ b/arch/arm/boot/dts/rk3288-veyron-sdmmc.dtsi
@@ -90,7 +90,7 @@
 	regulators {
 		vccio_sd: LDO_REG4 {
 			regulator-name = "vccio_sd";
-			regulator-min-microvolt = <3300000>;
+			regulator-min-microvolt = <1800000>;
 			regulator-max-microvolt = <3300000>;
 			regulator-state-mem {
 				regulator-off-in-suspend;
@@ -116,7 +116,12 @@
 	cap-sd-highspeed;
 	card-detect-delay = <200>;
 	cd-gpios = <&gpio7 5 GPIO_ACTIVE_LOW>;
+	default-sample-phase = <90>;
 	num-slots = <1>;
+	sd-uhs-sdr12;
+	sd-uhs-sdr25;
+	sd-uhs-sdr50;
+	sd-uhs-sdr104;
 	vmmc-supply = <&vcc33_sd>;
 	vqmmc-supply = <&vccio_sd>;
 };
diff --git a/arch/arm/boot/dts/rk3288-veyron.dtsi b/arch/arm/boot/dts/rk3288-veyron.dtsi
index df7d70d..394aa80 100644
--- a/arch/arm/boot/dts/rk3288-veyron.dtsi
+++ b/arch/arm/boot/dts/rk3288-veyron.dtsi
@@ -194,7 +194,9 @@
 	broken-cd;
 	bus-width = <8>;
 	cap-mmc-highspeed;
+	default-sample-phase = <158>;
 	disable-wp;
+	mmc-hs200-1_8v;
 	mmc-pwrseq = <&emmc_pwrseq>;
 	non-removable;
 	num-slots = <1>;
@@ -409,6 +411,10 @@
 	num-slots = <1>;
 	pinctrl-names = "default";
 	pinctrl-0 = <&sdio0_clk &sdio0_cmd &sdio0_bus4>;
+	sd-uhs-sdr12;
+	sd-uhs-sdr25;
+	sd-uhs-sdr50;
+	sd-uhs-sdr104;
 	vmmc-supply = <&vcc33_sys>;
 	vqmmc-supply = <&vcc18_wl>;
 };
-- 
2.1.4



From heiko at sntech.de  Mon Aug 31 11:23:59 2015
From: heiko at sntech.de (Heiko Stuebner)
Date: Mon, 31 Aug 2015 20:23:59 +0200
Subject: [PATCH 1/8] clk: rockchip: Allow more precision for some mmc clock
 phases
In-Reply-To: <1441045446-30858-1-git-send-email-heiko@sntech.de>
References: <1441045446-30858-1-git-send-email-heiko@sntech.de>
Message-ID: <1441045446-30858-2-git-send-email-heiko@sntech.de>

From: Douglas Anderson <dianders at chromium.org>

Because of the inexact nature of the extra MMC delay elements (it's
not possible to keep the phase monotonic and to also make phases (mod
90) > 70), we previously only allowed phases (mod 90) of 22.5, 45,
and 67.5.

But it's not the end of the world if the MMC clock phase goes
non-monotonic.  At most we'll be 25 degrees off.  It's way better to
test more phases to look for bad ones than to be 25 degrees off, because
in the case of MMC really the point is to find bad phases and get as far
asway from the as possible.  If we get to test extra phases by going
slightly non-monotonic then that might be fine.  Worst case we would
end up at a phases that's slight differnt than the one we wanted, but
at least we'd still be quite far away from the a bad phase.

Signed-off-by: Douglas Anderson <dianders at chromium.org>

Fold in more precise variance-values of 44-77 instead of 40-80.
Fold in the actual removal of the monotonic requirement and adapt
patch message accordingly.
Signed-off-by: Heiko Stuebner <heiko at sntech.de>
---
 drivers/clk/rockchip/clk-mmc-phase.c | 45 ++++++++++++++++++++++++------------
 1 file changed, 30 insertions(+), 15 deletions(-)

diff --git a/drivers/clk/rockchip/clk-mmc-phase.c b/drivers/clk/rockchip/clk-mmc-phase.c
index 9b61342..a797d86 100644
--- a/drivers/clk/rockchip/clk-mmc-phase.c
+++ b/drivers/clk/rockchip/clk-mmc-phase.c
@@ -45,8 +45,8 @@ static unsigned long rockchip_mmc_recalc(struct clk_hw *hw,
 #define PSECS_PER_SEC 1000000000000LL
 
 /*
- * Each fine delay is between 40ps-80ps. Assume each fine delay is 60ps to
- * simplify calculations. So 45degs could be anywhere between 33deg and 66deg.
+ * Each fine delay is between 44ps-77ps. Assume each fine delay is 60ps to
+ * simplify calculations. So 45degs could be anywhere between 33deg and 57.8deg.
  */
 #define ROCKCHIP_MMC_DELAY_ELEMENT_PSEC 60
 
@@ -84,22 +84,37 @@ static int rockchip_mmc_set_phase(struct clk_hw *hw, int degrees)
 	u32 raw_value;
 	u64 delay;
 
-	/* allow 22 to be 22.5 */
-	degrees++;
-	/* floor to 22.5 increment */
-	degrees -= ((degrees) * 10 % 225) / 10;
-
 	nineties = degrees / 90;
-	/* 22.5 multiples */
-	remainder = (degrees % 90) / 22;
-
+	remainder = (degrees % 90);
+
+	/*
+	 * Due to the inexact nature of the "fine" delay, we might
+	 * actually go non-monotonic.  We don't go _too_ monotonic
+	 * though, so we should be OK.  Here are options of how we may
+	 * work:
+	 *
+	 * Ideally we end up with:
+	 *   1.0, 2.0, ..., 69.0, 70.0, ...,  89.0, 90.0
+	 *
+	 * On one extreme (if delay is actually 44ps):
+	 *   .73, 1.5, ..., 50.6, 51.3, ...,  65.3, 90.0
+	 * The other (if delay is actually 77ps):
+	 *   1.3, 2.6, ..., 88.6. 89.8, ..., 114.0, 90
+	 *
+	 * It's possible we might make a delay that is up to 25
+	 * degrees off from what we think we're making.  That's OK
+	 * though because we should be REALLY far from any bad range.
+	 */
+
+	/*
+	 * Convert to delay; do a little extra work to make sure we
+	 * don't overflow 32-bit / 64-bit numbers.
+	 */
 	delay = PSECS_PER_SEC;
-	do_div(delay, rate);
-	/* / 360 / 22.5 */
-	do_div(delay, 16);
-	do_div(delay, ROCKCHIP_MMC_DELAY_ELEMENT_PSEC);
-
 	delay *= remainder;
+	do_div(delay, 10000);
+	do_div(delay, (rate / 1000) * 36 * ROCKCHIP_MMC_DELAY_ELEMENT_PSEC);
+
 	delay_num = (u8) min(delay, 255ULL);
 
 	raw_value = delay_num ? ROCKCHIP_MMC_DELAY_SEL : 0;
-- 
2.1.4



From heiko at sntech.de  Mon Aug 31 11:24:01 2015
From: heiko at sntech.de (Heiko Stuebner)
Date: Mon, 31 Aug 2015 20:24:01 +0200
Subject: [PATCH 3/8] mmc: core: Add mmc_regulator_set_vqmmc()
In-Reply-To: <1441045446-30858-1-git-send-email-heiko@sntech.de>
References: <1441045446-30858-1-git-send-email-heiko@sntech.de>
Message-ID: <1441045446-30858-4-git-send-email-heiko@sntech.de>

From: Douglas Anderson <dianders at chromium.org>

This adds logic to the MMC core to set VQMMC.  This is expected to be
called by MMC drivers like dw_mmc as part of (or instead of) their
start_signal_voltage_switch() callback.

A few notes:

* When setting the signal voltage to 3.3V we do our best to make VQMMC
  and VMMC match.  It's been reported that this makes some old cards
  happy since they were tested back in the day before UHS when VQMMC
  and VMMC were provided by the same regulator.  A nice side effect of
  this is that we don't end up on the hairy edge of VQMMC (2.7V),
  which some EEs claim is a little too close to the minimum for
  comfort.
  If this is not supported by the supplying regulator we try to find
  a suitable voltage within the whole 2.7V-3.6V area of the spec.

* When setting the signal voltage to 1.8V or 1.2V we aim for that
  specific voltage instead of picking the lowest one in the range.

* We very purposely don't print errors in mmc_regulator_set_vqmmc().
  There are cases where the MMC core will try several different
  voltages and we don't want to pollute the logs.

Signed-off-by: Douglas Anderson <dianders at chromium.org>
Signed-off-by: Heiko Stuebner <heiko at sntech.de>
---
 drivers/mmc/core/core.c  | 68 ++++++++++++++++++++++++++++++++++++++++++++++++
 include/linux/mmc/host.h |  7 +++++
 2 files changed, 75 insertions(+)

diff --git a/drivers/mmc/core/core.c b/drivers/mmc/core/core.c
index 0520064..9dc0b65 100644
--- a/drivers/mmc/core/core.c
+++ b/drivers/mmc/core/core.c
@@ -1437,6 +1437,74 @@ int mmc_regulator_set_ocr(struct mmc_host *mmc,
 }
 EXPORT_SYMBOL_GPL(mmc_regulator_set_ocr);
 
+static int mmc_regulator_set_voltage_if_supported(struct regulator *regulator,
+						  int min_uV, int target_uV,
+						  int max_uV)
+{
+	/*
+	 * Check if supported first to avoid errors since we may try several
+	 * signal levels during power up and don't want to show errors.
+	 */
+	if (!regulator_is_supported_voltage(regulator, min_uV, max_uV))
+		return -EINVAL;
+
+	return regulator_set_voltage_triplet(regulator, min_uV, target_uV,
+					     max_uV);
+}
+
+/**
+ * mmc_regulator_set_vqmmc - Set VQMMC as per the ios
+ *
+ * For 3.3V signaling, we try to match VQMMC to VMMC as closely as possible.
+ * That will match the behavior of old boards where VQMMC and VMMC were supplied
+ * by the same supply.  The Bus Operating conditions for 3.3V signaling in the
+ * SD card spec also define VQMMC in terms of VMMC.
+ * If this is not possible we'll try the full 2.7-3.6V of the spec.
+ *
+ * For 1.2V and 1.8V signaling we'll try to get as close as possible to the
+ * requested voltage.  This is definitely a good idea for UHS where there's a
+ * separate regulator on the card that's trying to make 1.8V and it's best if
+ * we match.
+ *
+ * This function is expected to be used by a controller's
+ * start_signal_voltage_switch() function.
+ */
+int mmc_regulator_set_vqmmc(struct mmc_host *mmc, struct mmc_ios *ios)
+{
+	int volt, min_uV, max_uV;
+
+	/* If no vqmmc supply then we can't change the voltage */
+	if (IS_ERR(mmc->supply.vqmmc))
+		return -EINVAL;
+
+	switch (ios->signal_voltage) {
+	case MMC_SIGNAL_VOLTAGE_120:
+		return mmc_regulator_set_voltage_if_supported(mmc->supply.vqmmc,
+						1100000, 1200000, 1300000);
+	case MMC_SIGNAL_VOLTAGE_180:
+		return mmc_regulator_set_voltage_if_supported(mmc->supply.vqmmc,
+						1700000, 1800000, 1950000);
+	case MMC_SIGNAL_VOLTAGE_330:
+		volt = regulator_get_voltage(mmc->supply.vmmc);
+		if (volt < 0)
+			return volt;
+
+		min_uV = max(volt - 300000, 2700000);
+		max_uV = min(volt + 300000, 3600000);
+
+		/* try to stay close to vmmc at first */
+		if (!mmc_regulator_set_voltage_if_supported(mmc->supply.vqmmc,
+						min_uV, volt, max_uV))
+			return 0;
+
+		return mmc_regulator_set_voltage_if_supported(mmc->supply.vqmmc,
+						2700000, volt, 3600000);
+	default:
+		return -EINVAL;
+	}
+}
+EXPORT_SYMBOL_GPL(mmc_regulator_set_vqmmc);
+
 #endif /* CONFIG_REGULATOR */
 
 int mmc_regulator_get_supply(struct mmc_host *mmc)
diff --git a/include/linux/mmc/host.h b/include/linux/mmc/host.h
index 83b81fd..a2a78eb 100644
--- a/include/linux/mmc/host.h
+++ b/include/linux/mmc/host.h
@@ -423,6 +423,7 @@ int mmc_regulator_get_ocrmask(struct regulator *supply);
 int mmc_regulator_set_ocr(struct mmc_host *mmc,
 			struct regulator *supply,
 			unsigned short vdd_bit);
+int mmc_regulator_set_vqmmc(struct mmc_host *mmc, struct mmc_ios *ios);
 #else
 static inline int mmc_regulator_get_ocrmask(struct regulator *supply)
 {
@@ -435,6 +436,12 @@ static inline int mmc_regulator_set_ocr(struct mmc_host *mmc,
 {
 	return 0;
 }
+
+static inline int mmc_regulator_set_vqmmc(struct mmc_host *mmc,
+					  struct mmc_ios *ios)
+{
+	return -EINVAL;
+}
 #endif
 
 int mmc_regulator_get_supply(struct mmc_host *mmc);
-- 
2.1.4



From heiko at sntech.de  Mon Aug 31 11:24:05 2015
From: heiko at sntech.de (Heiko Stuebner)
Date: Mon, 31 Aug 2015 20:24:05 +0200
Subject: [PATCH 7/8] ARM: dts: rockchip: Add drive/sample clocks for rk3288
 dw_mmc devices
In-Reply-To: <1441045446-30858-1-git-send-email-heiko@sntech.de>
References: <1441045446-30858-1-git-send-email-heiko@sntech.de>
Message-ID: <1441045446-30858-8-git-send-email-heiko@sntech.de>

From: Alexandru M Stan <amstan at chromium.org>

The drive/sample clocks can be phase shifted.  The drive clock
could be used in a future patch to adjust hold times.  The sample
clock is used for tuning.

Signed-off-by: Alexandru M Stan <amstan at chromium.org>
Signed-off-by: Heiko Stuebner <heiko at sntech.de>
---
 arch/arm/boot/dts/rk3288.dtsi | 20 ++++++++++++--------
 1 file changed, 12 insertions(+), 8 deletions(-)

diff --git a/arch/arm/boot/dts/rk3288.dtsi b/arch/arm/boot/dts/rk3288.dtsi
index 118fe74..b084bc6 100644
--- a/arch/arm/boot/dts/rk3288.dtsi
+++ b/arch/arm/boot/dts/rk3288.dtsi
@@ -222,8 +222,9 @@
 	sdmmc: dwmmc at ff0c0000 {
 		compatible = "rockchip,rk3288-dw-mshc";
 		clock-freq-min-max = <400000 150000000>;
-		clocks = <&cru HCLK_SDMMC>, <&cru SCLK_SDMMC>;
-		clock-names = "biu", "ciu";
+		clocks = <&cru HCLK_SDMMC>, <&cru SCLK_SDMMC>,
+			 <&cru SCLK_SDMMC_DRV>, <&cru SCLK_SDMMC_SAMPLE>;
+		clock-names = "biu", "ciu", "ciu_drv", "ciu_sample";
 		fifo-depth = <0x100>;
 		interrupts = <GIC_SPI 32 IRQ_TYPE_LEVEL_HIGH>;
 		reg = <0xff0c0000 0x4000>;
@@ -233,8 +234,9 @@
 	sdio0: dwmmc at ff0d0000 {
 		compatible = "rockchip,rk3288-dw-mshc";
 		clock-freq-min-max = <400000 150000000>;
-		clocks = <&cru HCLK_SDIO0>, <&cru SCLK_SDIO0>;
-		clock-names = "biu", "ciu";
+		clocks = <&cru HCLK_SDIO0>, <&cru SCLK_SDIO0>,
+			 <&cru SCLK_SDIO0_DRV>, <&cru SCLK_SDIO0_SAMPLE>;
+		clock-names = "biu", "ciu", "ciu_drv", "ciu_sample";
 		fifo-depth = <0x100>;
 		interrupts = <GIC_SPI 33 IRQ_TYPE_LEVEL_HIGH>;
 		reg = <0xff0d0000 0x4000>;
@@ -244,8 +246,9 @@
 	sdio1: dwmmc at ff0e0000 {
 		compatible = "rockchip,rk3288-dw-mshc";
 		clock-freq-min-max = <400000 150000000>;
-		clocks = <&cru HCLK_SDIO1>, <&cru SCLK_SDIO1>;
-		clock-names = "biu", "ciu";
+		clocks = <&cru HCLK_SDIO1>, <&cru SCLK_SDIO1>,
+			 <&cru SCLK_SDIO1_DRV>, <&cru SCLK_SDIO1_SAMPLE>;
+		clock-names = "biu", "ciu", "ciu_drv", "ciu_sample";
 		fifo-depth = <0x100>;
 		interrupts = <GIC_SPI 34 IRQ_TYPE_LEVEL_HIGH>;
 		reg = <0xff0e0000 0x4000>;
@@ -255,8 +258,9 @@
 	emmc: dwmmc at ff0f0000 {
 		compatible = "rockchip,rk3288-dw-mshc";
 		clock-freq-min-max = <400000 150000000>;
-		clocks = <&cru HCLK_EMMC>, <&cru SCLK_EMMC>;
-		clock-names = "biu", "ciu";
+		clocks = <&cru HCLK_EMMC>, <&cru SCLK_EMMC>,
+			 <&cru SCLK_EMMC_DRV>, <&cru SCLK_EMMC_SAMPLE>;
+		clock-names = "biu", "ciu", "ciu_drv", "ciu_sample";
 		fifo-depth = <0x100>;
 		interrupts = <GIC_SPI 35 IRQ_TYPE_LEVEL_HIGH>;
 		reg = <0xff0f0000 0x4000>;
-- 
2.1.4



From heiko at sntech.de  Mon Aug 31 11:24:00 2015
From: heiko at sntech.de (Heiko Stuebner)
Date: Mon, 31 Aug 2015 20:24:00 +0200
Subject: [PATCH 2/8] clk: rockchip: Make calculations use rounding
In-Reply-To: <1441045446-30858-1-git-send-email-heiko@sntech.de>
References: <1441045446-30858-1-git-send-email-heiko@sntech.de>
Message-ID: <1441045446-30858-3-git-send-email-heiko@sntech.de>

From: Douglas Anderson <dianders at chromium.org>

Let's use DIV_ROUND_CLOSEST for rounding, not just truncating
division.  This lets us get closer to the right rate.

Before this:
  set_phase(86) delay_nums=26 reg[0xf000420c]=0x468 actual_degrees=83
  set_phase(89) delay_nums=27 reg[0xf000420c]=0x46c actual_degrees=86

After this:
  set_phase(86) delay_nums=27 reg[0xf000420c]=0x46c actual_degrees=86
  set_phase(89) delay_nums=28 reg[0xf000420c]=0x470 actual_degrees=90

Signed-off-by: Douglas Anderson <dianders at chromium.org>
Signed-off-by: Heiko Stuebner <heiko at sntech.de>
---
 drivers/clk/rockchip/clk-mmc-phase.c | 13 +++++++------
 1 file changed, 7 insertions(+), 6 deletions(-)

diff --git a/drivers/clk/rockchip/clk-mmc-phase.c b/drivers/clk/rockchip/clk-mmc-phase.c
index a797d86..bc24e5a 100644
--- a/drivers/clk/rockchip/clk-mmc-phase.c
+++ b/drivers/clk/rockchip/clk-mmc-phase.c
@@ -69,7 +69,7 @@ static int rockchip_mmc_get_phase(struct clk_hw *hw)
 
 		delay_num = (raw_value & ROCKCHIP_MMC_DELAYNUM_MASK);
 		delay_num >>= ROCKCHIP_MMC_DELAYNUM_OFFSET;
-		degrees += delay_num * factor / 10000;
+		degrees += DIV_ROUND_CLOSEST(delay_num * factor, 10000);
 	}
 
 	return degrees % 360;
@@ -82,7 +82,7 @@ static int rockchip_mmc_set_phase(struct clk_hw *hw, int degrees)
 	u8 nineties, remainder;
 	u8 delay_num;
 	u32 raw_value;
-	u64 delay;
+	u32 delay;
 
 	nineties = degrees / 90;
 	remainder = (degrees % 90);
@@ -110,12 +110,13 @@ static int rockchip_mmc_set_phase(struct clk_hw *hw, int degrees)
 	 * Convert to delay; do a little extra work to make sure we
 	 * don't overflow 32-bit / 64-bit numbers.
 	 */
-	delay = PSECS_PER_SEC;
+	delay = 10000000; /* PSECS_PER_SEC / 10000 / 10 */
 	delay *= remainder;
-	do_div(delay, 10000);
-	do_div(delay, (rate / 1000) * 36 * ROCKCHIP_MMC_DELAY_ELEMENT_PSEC);
+	delay = DIV_ROUND_CLOSEST(delay,
+			(rate / 1000) * 36 *
+				(ROCKCHIP_MMC_DELAY_ELEMENT_PSEC / 10));
 
-	delay_num = (u8) min(delay, 255ULL);
+	delay_num = (u8) min_t(u32, delay, 255);
 
 	raw_value = delay_num ? ROCKCHIP_MMC_DELAY_SEL : 0;
 	raw_value |= delay_num << ROCKCHIP_MMC_DELAYNUM_OFFSET;
-- 
2.1.4



From heiko at sntech.de  Mon Aug 31 11:24:02 2015
From: heiko at sntech.de (Heiko Stuebner)
Date: Mon, 31 Aug 2015 20:24:02 +0200
Subject: [PATCH 4/8] mmc: dw_mmc: Use mmc_regulator_set_vqmmc in
 start_signal_voltage_switch
In-Reply-To: <1441045446-30858-1-git-send-email-heiko@sntech.de>
References: <1441045446-30858-1-git-send-email-heiko@sntech.de>
Message-ID: <1441045446-30858-5-git-send-email-heiko@sntech.de>

From: Douglas Anderson <dianders at chromium.org>

We've introduced a new helper in the MMC core:
mmc_regulator_set_vqmmc().  Let's use this in dw_mmc.  Using this new
helper has some advantages:

1. We get the mmc_regulator_set_vqmmc() behavior of trying to match
   VQMMC and VMMC when the signal voltage is 3.3V.  This ensures max
   compatibility.

2. We get rid of a few more warnings when probing unsupported
   voltages.

3. We get rid of some non-dw_mmc specific code in dw_mmc.

Signed-off-by: Douglas Anderson <dianders at chromium.org>
Signed-off-by: Heiko Stuebner <heiko at sntech.de>
---
 drivers/mmc/host/dw_mmc.c | 17 ++++++-----------
 1 file changed, 6 insertions(+), 11 deletions(-)

diff --git a/drivers/mmc/host/dw_mmc.c b/drivers/mmc/host/dw_mmc.c
index fcbf552..b1b7e7f 100644
--- a/drivers/mmc/host/dw_mmc.c
+++ b/drivers/mmc/host/dw_mmc.c
@@ -1279,7 +1279,6 @@ static int dw_mci_switch_voltage(struct mmc_host *mmc, struct mmc_ios *ios)
 	const struct dw_mci_drv_data *drv_data = host->drv_data;
 	u32 uhs;
 	u32 v18 = SDMMC_UHS_18V << slot->id;
-	int min_uv, max_uv;
 	int ret;
 
 	if (drv_data && drv_data->switch_voltage)
@@ -1291,22 +1290,18 @@ static int dw_mci_switch_voltage(struct mmc_host *mmc, struct mmc_ios *ios)
 	 * does no harm but you need to set the regulator directly.  Try both.
 	 */
 	uhs = mci_readl(host, UHS_REG);
-	if (ios->signal_voltage == MMC_SIGNAL_VOLTAGE_330) {
-		min_uv = 2700000;
-		max_uv = 3600000;
+	if (ios->signal_voltage == MMC_SIGNAL_VOLTAGE_330)
 		uhs &= ~v18;
-	} else {
-		min_uv = 1700000;
-		max_uv = 1950000;
+	else
 		uhs |= v18;
-	}
+
 	if (!IS_ERR(mmc->supply.vqmmc)) {
-		ret = regulator_set_voltage(mmc->supply.vqmmc, min_uv, max_uv);
+		ret = mmc_regulator_set_vqmmc(mmc, ios);
 
 		if (ret) {
 			dev_dbg(&mmc->class_dev,
-					 "Regulator set error %d: %d - %d\n",
-					 ret, min_uv, max_uv);
+					 "Regulator set error %d - %s V\n",
+					 ret, uhs & v18 ? "1.8" : "3.3");
 			return ret;
 		}
 	}
-- 
2.1.4



From heiko at sntech.de  Mon Aug 31 11:24:04 2015
From: heiko at sntech.de (Heiko Stuebner)
Date: Mon, 31 Aug 2015 20:24:04 +0200
Subject: [PATCH 6/8] mmc: dw_mmc: Generic MMC tuning with the clock phase
 framework
In-Reply-To: <1441045446-30858-1-git-send-email-heiko@sntech.de>
References: <1441045446-30858-1-git-send-email-heiko@sntech.de>
Message-ID: <1441045446-30858-7-git-send-email-heiko@sntech.de>

From: Alexandru M Stan <amstan at chromium.org>

This algorithm will try 1 degree increments, since there's no way to tell
what resolution the underlying phase code uses. As an added bonus, doing
many tunings yields better results since some tests are run more than once
(ex: if the underlying driver uses 45 degree increments, the tuning code
will try the same angle more than once).

It will then construct a list of good phase ranges (even ranges that cross
360/0), will pick the biggest range then it will set the sample_clk to the
middle of that range.

We do not touch ciu_drive (and by extension define default-drive-phase).
Drive phase is mostly used to define minimum hold times, while one could
write some code to determine what phase meets the minimum hold time (ex 10
degrees) this will not work with the current clock phase framework (which
floors angles, so we'll get 0 deg, and there's no way to know what
resolution the floors happen at). We assume that the default drive angles
set by the hardware are good enough.

If a device has device specific code (like exynos) then that will still
take precedence, otherwise this new code will execute. If the device wants
to tune, but has no sample_clk defined we'll return EIO with an error
message.

Signed-off-by: Alexandru M Stan <amstan at chromium.org>

Convert to mmc_send_tuning()
Fold in from the ChromeOS-tree:
 - mmc: dw_mmc: Change tuning to only 16 phases
 - mmc: dw_mmc: Test more phases
Signed-off-by: Heiko Stuebner <heiko at sntech.de>
---
 drivers/mmc/host/dw_mmc.c  | 142 +++++++++++++++++++++++++++++++++++++++++++++
 include/linux/mmc/dw_mmc.h |   3 +
 2 files changed, 145 insertions(+)

diff --git a/drivers/mmc/host/dw_mmc.c b/drivers/mmc/host/dw_mmc.c
index b1b7e7f..13bcde0 100644
--- a/drivers/mmc/host/dw_mmc.c
+++ b/drivers/mmc/host/dw_mmc.c
@@ -1194,6 +1194,12 @@ static void dw_mci_set_ios(struct mmc_host *mmc, struct mmc_ios *ios)
 	if (drv_data && drv_data->set_ios)
 		drv_data->set_ios(slot->host, ios);
 
+	/* Make sure we use phases which we can enumerate with */
+	if (!IS_ERR(slot->host->sample_clk)) {
+		clk_set_phase(slot->host->sample_clk,
+			      slot->host->default_sample_phase);
+	}
+
 	switch (ios->power_mode) {
 	case MMC_POWER_UP:
 		if (!IS_ERR(mmc->supply.vmmc)) {
@@ -1414,6 +1420,127 @@ static void dw_mci_enable_sdio_irq(struct mmc_host *mmc, int enb)
 	spin_unlock_irqrestore(&host->irq_lock, irqflags);
 }
 
+#define NUM_PHASES			360
+#define TUNING_ITERATION_TO_PHASE(i)	(DIV_ROUND_UP((i) * 360, NUM_PHASES))
+
+static int dw_mci_execute_generic_tuning(struct dw_mci_slot *slot)
+{
+	struct dw_mci *host = slot->host;
+	struct mmc_host *mmc = slot->mmc;
+	int ret = 0;
+	int i;
+	bool v, prev_v = 0, first_v;
+	struct range_t {
+		int start;
+		int end; /* inclusive */
+	};
+	struct range_t *ranges;
+	unsigned int range_count = 0;
+	int longest_range_len = -1;
+	int longest_range = -1;
+	int middle_phase;
+
+	if (IS_ERR(host->sample_clk)) {
+		dev_err(host->dev, "Tuning clock (sample_clk) not defined.\n");
+		return -EIO;
+	}
+
+	ranges = kmalloc_array(NUM_PHASES / 2 + 1, sizeof(*ranges), GFP_KERNEL);
+	if (!ranges)
+		return -ENOMEM;
+
+	/* Try each phase and extract good ranges */
+	for (i = 0; i < NUM_PHASES; ) {
+		clk_set_phase(host->sample_clk, TUNING_ITERATION_TO_PHASE(i));
+
+		v = !mmc_send_tuning(mmc);
+
+		if (i == 0)
+			first_v = v;
+
+		if ((!prev_v) && v) {
+			range_count++;
+			ranges[range_count-1].start = i;
+		}
+		if (v) {
+			ranges[range_count-1].end = i;
+			i++;
+		} else if (i == NUM_PHASES - 1) {
+			/* No extra skipping rules if we're at the end */
+			i++;
+		} else {
+			/*
+			 * No need to check too close to an invalid
+			 * one since testing bad phases is slow.  Skip
+			 * 20 degrees.
+			 */
+			i += DIV_ROUND_UP(20 * NUM_PHASES, 360);
+
+			/* Always test the last one */
+			if (i >= NUM_PHASES)
+				i = NUM_PHASES - 1;
+		}
+
+		prev_v = v;
+	}
+
+	if (range_count == 0) {
+		dev_warn(host->dev, "All phases bad!");
+		ret = -EIO;
+		goto free;
+	}
+
+	/* wrap around case, merge the end points */
+	if ((range_count > 1) && first_v && v) {
+		ranges[0].start = ranges[range_count-1].start;
+		range_count--;
+	}
+
+	if (ranges[0].start == 0 && ranges[0].end == NUM_PHASES - 1) {
+		clk_set_phase(host->sample_clk, host->default_sample_phase);
+		dev_info(host->dev, "All phases work, using default phase %d.",
+			 host->default_sample_phase);
+		goto free;
+	}
+
+	/* Find the longest range */
+	for (i = 0; i < range_count; i++) {
+		int len = (ranges[i].end - ranges[i].start + 1);
+
+		if (len < 0)
+			len += NUM_PHASES;
+
+		if (longest_range_len < len) {
+			longest_range_len = len;
+			longest_range = i;
+		}
+
+		dev_dbg(host->dev, "Good phase range %d-%d (%d len)\n",
+			TUNING_ITERATION_TO_PHASE(ranges[i].start),
+			TUNING_ITERATION_TO_PHASE(ranges[i].end),
+			len
+		);
+	}
+
+	dev_dbg(host->dev, "Best phase range %d-%d (%d len)\n",
+		TUNING_ITERATION_TO_PHASE(ranges[longest_range].start),
+		TUNING_ITERATION_TO_PHASE(ranges[longest_range].end),
+		longest_range_len
+	);
+
+	middle_phase = ranges[longest_range].start + longest_range_len / 2;
+	middle_phase %= NUM_PHASES;
+	dev_info(host->dev, "Successfully tuned phase to %d\n",
+		 TUNING_ITERATION_TO_PHASE(middle_phase));
+
+	clk_set_phase(host->sample_clk,
+		      TUNING_ITERATION_TO_PHASE(middle_phase));
+
+free:
+	kfree(ranges);
+	return ret;
+}
+
 static int dw_mci_execute_tuning(struct mmc_host *mmc, u32 opcode)
 {
 	struct dw_mci_slot *slot = mmc_priv(mmc);
@@ -1423,6 +1550,8 @@ static int dw_mci_execute_tuning(struct mmc_host *mmc, u32 opcode)
 
 	if (drv_data && drv_data->execute_tuning)
 		err = drv_data->execute_tuning(slot);
+	else
+		err = dw_mci_execute_generic_tuning(slot);
 	return err;
 }
 
@@ -2741,6 +2870,11 @@ static struct dw_mci_board *dw_mci_parse_dt(struct dw_mci *host)
 	if (!of_property_read_u32(np, "clock-frequency", &clock_frequency))
 		pdata->bus_hz = clock_frequency;
 
+	if (of_property_read_u32(np, "default-sample-phase",
+					&host->default_sample_phase)) {
+		host->default_sample_phase = 0;
+	}
+
 	if (drv_data && drv_data->parse_dt) {
 		ret = drv_data->parse_dt(host);
 		if (ret)
@@ -2843,6 +2977,14 @@ int dw_mci_probe(struct dw_mci *host)
 		host->bus_hz = clk_get_rate(host->ciu_clk);
 	}
 
+	host->drv_clk = devm_clk_get(host->dev, "ciu_drv");
+	if (IS_ERR(host->drv_clk))
+		dev_dbg(host->dev, "ciu_drv not available\n");
+
+	host->sample_clk = devm_clk_get(host->dev, "ciu_sample");
+	if (IS_ERR(host->sample_clk))
+		dev_dbg(host->dev, "ciu_sample not available\n");
+
 	if (!host->bus_hz) {
 		dev_err(host->dev,
 			"Platform data must supply bus speed\n");
diff --git a/include/linux/mmc/dw_mmc.h b/include/linux/mmc/dw_mmc.h
index 134c574..40187ba 100644
--- a/include/linux/mmc/dw_mmc.h
+++ b/include/linux/mmc/dw_mmc.h
@@ -176,7 +176,10 @@ struct dw_mci {
 	void			*priv;
 	struct clk		*biu_clk;
 	struct clk		*ciu_clk;
+	struct clk		*drv_clk;
+	struct clk		*sample_clk;
 	struct dw_mci_slot	*slot[MAX_MCI_SLOTS];
+	int			default_sample_phase;
 
 	/* FIFO push and pull */
 	int			fifo_depth;
-- 
2.1.4



From christoffer.dall at linaro.org  Mon Aug 31 11:46:23 2015
From: christoffer.dall at linaro.org (Christoffer Dall)
Date: Mon, 31 Aug 2015 20:46:23 +0200
Subject: [PATCH 09/13] arm64: KVM: VHE: Add alternatives for VHE-enabled
 world-switch
In-Reply-To: <1436372356-30410-10-git-send-email-marc.zyngier@arm.com>
References: <1436372356-30410-1-git-send-email-marc.zyngier@arm.com>
 <1436372356-30410-10-git-send-email-marc.zyngier@arm.com>
Message-ID: <20150831184623.GB10991@cbox>

On Wed, Jul 08, 2015 at 05:19:12PM +0100, Marc Zyngier wrote:
> In order to switch between host and guest, a VHE-enabled kernel
> must use different accessors for certain system registers.
> 
> This patch uses runtime patching to use the right instruction
> when required...

So am I reading this patch correctly as we basically still switch all
the EL1 state for which there is separate EL2 state for the host, on
every exit?

Wouldn't that defeat the entire purpose of VHE, more or less, where you
should only be saving/restoring all this system register state on
vcpu_put?

Or was it a conscious design decision to not introduce anything for
performance in this series, and just make it functionally correct for
now?  If so, I think the series deserves a big fat comment explaining
this in the cover letter.

I am a bit concerned overall that this will become hugely difficult to
read and maintain, especially considering if we add a bunch of more
optimizations to the code.

Have you given any thought to simply splitting up the logic between VHE
and non-VHE KVM on arm64 for the low-level stuff?

-Christoffer

> 
> Signed-off-by: Marc Zyngier <marc.zyngier at arm.com>
> ---
>  arch/arm64/include/asm/kvm_asm.h |  40 ++++++--
>  arch/arm64/kvm/hyp.S             | 210 ++++++++++++++++++++++++++-------------
>  arch/arm64/kvm/vhe-macros.h      |  18 ++++
>  3 files changed, 191 insertions(+), 77 deletions(-)
> 
> diff --git a/arch/arm64/include/asm/kvm_asm.h b/arch/arm64/include/asm/kvm_asm.h
> index 3c5fe68..a932be0 100644
> --- a/arch/arm64/include/asm/kvm_asm.h
> +++ b/arch/arm64/include/asm/kvm_asm.h
> @@ -18,6 +18,7 @@
>  #ifndef __ARM_KVM_ASM_H__
>  #define __ARM_KVM_ASM_H__
>  
> +#include <asm/sysreg.h>
>  #include <asm/virt.h>
>  
>  /*
> @@ -27,7 +28,7 @@
>  #define	MPIDR_EL1	1	/* MultiProcessor Affinity Register */
>  #define	CSSELR_EL1	2	/* Cache Size Selection Register */
>  #define	SCTLR_EL1	3	/* System Control Register */
> -#define	ACTLR_EL1	4	/* Auxiliary Control Register */
> +#define	AMAIR_EL1	4	/* Aux Memory Attribute Indirection Register */
>  #define	CPACR_EL1	5	/* Coprocessor Access Control */
>  #define	TTBR0_EL1	6	/* Translation Table Base Register 0 */
>  #define	TTBR1_EL1	7	/* Translation Table Base Register 1 */
> @@ -39,13 +40,13 @@
>  #define	MAIR_EL1	13	/* Memory Attribute Indirection Register */
>  #define	VBAR_EL1	14	/* Vector Base Address Register */
>  #define	CONTEXTIDR_EL1	15	/* Context ID Register */
> -#define	TPIDR_EL0	16	/* Thread ID, User R/W */
> -#define	TPIDRRO_EL0	17	/* Thread ID, User R/O */
> -#define	TPIDR_EL1	18	/* Thread ID, Privileged */
> -#define	AMAIR_EL1	19	/* Aux Memory Attribute Indirection Register */
> -#define	CNTKCTL_EL1	20	/* Timer Control Register (EL1) */
> -#define	PAR_EL1		21	/* Physical Address Register */
> -#define MDSCR_EL1	22	/* Monitor Debug System Control Register */
> +#define	CNTKCTL_EL1	16	/* Timer Control Register (EL1) */
> +#define	PAR_EL1		17	/* Physical Address Register */
> +#define	MDSCR_EL1	18	/* Monitor Debug System Control Register */
> +#define	TPIDR_EL0	19	/* Thread ID, User R/W */
> +#define	TPIDRRO_EL0	20	/* Thread ID, User R/O */
> +#define	TPIDR_EL1	21	/* Thread ID, Privileged */
> +#define	ACTLR_EL1	22	/* Auxiliary Control Register */
>  #define DBGBCR0_EL1	23	/* Debug Breakpoint Control Registers (0-15) */
>  #define DBGBCR15_EL1	38
>  #define DBGBVR0_EL1	39	/* Debug Breakpoint Value Registers (0-15) */
> @@ -106,6 +107,29 @@
>  
>  #define NR_COPRO_REGS	(NR_SYS_REGS * 2)
>  
> +#define sctlr_EL12              sys_reg(3, 5, 1, 0, 0)
> +#define cpacr_EL12              sys_reg(3, 5, 1, 0, 2)
> +#define ttbr0_EL12              sys_reg(3, 5, 2, 0, 0)
> +#define ttbr1_EL12              sys_reg(3, 5, 2, 0, 1)
> +#define tcr_EL12                sys_reg(3, 5, 2, 0, 2)
> +#define afsr0_EL12              sys_reg(3, 5, 5, 1, 0)
> +#define afsr1_EL12              sys_reg(3, 5, 5, 1, 1)
> +#define esr_EL12                sys_reg(3, 5, 5, 2, 0)
> +#define far_EL12                sys_reg(3, 5, 6, 0, 0)
> +#define mair_EL12               sys_reg(3, 5, 10, 2, 0)
> +#define amair_EL12              sys_reg(3, 5, 10, 3, 0)
> +#define vbar_EL12               sys_reg(3, 5, 12, 0, 0)
> +#define contextidr_EL12         sys_reg(3, 5, 13, 0, 1)
> +#define cntkctl_EL12            sys_reg(3, 5, 14, 1, 0)
> +#define cntp_tval_EL02          sys_reg(3, 5, 14, 2, 0)
> +#define cntp_ctl_EL02           sys_reg(3, 5, 14, 2, 1)
> +#define cntp_cval_EL02          sys_reg(3, 5, 14, 2, 2)
> +#define cntv_tval_EL02          sys_reg(3, 5, 14, 3, 0)
> +#define cntv_ctl_EL02           sys_reg(3, 5, 14, 3, 1)
> +#define cntv_cval_EL02          sys_reg(3, 5, 14, 3, 2)
> +#define spsr_EL12               sys_reg(3, 5, 4, 0, 0)
> +#define elr_EL12                sys_reg(3, 5, 4, 0, 1)
> +
>  #define ARM_EXCEPTION_IRQ	  0
>  #define ARM_EXCEPTION_TRAP	  1
>  
> diff --git a/arch/arm64/kvm/hyp.S b/arch/arm64/kvm/hyp.S
> index ad5821b..b61591b 100644
> --- a/arch/arm64/kvm/hyp.S
> +++ b/arch/arm64/kvm/hyp.S
> @@ -1,5 +1,5 @@
>  /*
> - * Copyright (C) 2012,2013 - ARM Ltd
> + * Copyright (C) 2012-2015 - ARM Ltd
>   * Author: Marc Zyngier <marc.zyngier at arm.com>
>   *
>   * This program is free software; you can redistribute it and/or modify
> @@ -67,40 +67,52 @@
>  	stp	x29, lr, [x3, #80]
>  
>  	mrs	x19, sp_el0
> -	mrs	x20, elr_el2		// pc before entering el2
> -	mrs	x21, spsr_el2		// pstate before entering el2
> +	str	x19, [x3, #96]
> +.endm
>  
> -	stp	x19, x20, [x3, #96]
> -	str	x21, [x3, #112]
> +.macro save_el1_state
> +	mrs_hyp(x20, ELR)		// pc before entering el2
> +	mrs_hyp(x21, SPSR)		// pstate before entering el2
>  
>  	mrs	x22, sp_el1
> -	mrs	x23, elr_el1
> -	mrs	x24, spsr_el1
> +
> +	mrs_el1(x23, elr)
> +	mrs_el1(x24, spsr)
> +
> +	add	x3, x2, #CPU_XREG_OFFSET(31)	// SP_EL0
> +	stp	x20, x21, [x3, #8]	// HACK: Store to the regs after SP_EL0
>  
>  	str	x22, [x2, #CPU_GP_REG_OFFSET(CPU_SP_EL1)]
>  	str	x23, [x2, #CPU_GP_REG_OFFSET(CPU_ELR_EL1)]
>  	str	x24, [x2, #CPU_SPSR_OFFSET(KVM_SPSR_EL1)]
>  .endm
>  
> -.macro restore_common_regs
> +.macro restore_el1_state
>  	// x2: base address for cpu context
>  	// x3: tmp register
>  
> +	add	x3, x2, #CPU_XREG_OFFSET(31)    // SP_EL0
> +	ldp	x20, x21, [x3, #8] // Same hack again, get guest PC and pstate
> +
>  	ldr	x22, [x2, #CPU_GP_REG_OFFSET(CPU_SP_EL1)]
>  	ldr	x23, [x2, #CPU_GP_REG_OFFSET(CPU_ELR_EL1)]
>  	ldr	x24, [x2, #CPU_SPSR_OFFSET(KVM_SPSR_EL1)]
>  
> +	msr_hyp(ELR, x20) 		// pc on return from el2
> +	msr_hyp(SPSR, x21) 		// pstate on return from el2
> +
>  	msr	sp_el1, x22
> -	msr	elr_el1, x23
> -	msr	spsr_el1, x24
>  
> -	add	x3, x2, #CPU_XREG_OFFSET(31)    // SP_EL0
> -	ldp	x19, x20, [x3]
> -	ldr	x21, [x3, #16]
> +	msr_el1(elr, x23)
> +	msr_el1(spsr, x24)
> +.endm
>  
> +.macro restore_common_regs
> +	// x2: base address for cpu context
> +	// x3: tmp register
> +
> +	ldr	x19, [x2, #CPU_XREG_OFFSET(31)] // SP_EL0
>  	msr	sp_el0, x19
> -	msr	elr_el2, x20 		// pc on return from el2
> -	msr	spsr_el2, x21 		// pstate on return from el2
>  
>  	add	x3, x2, #CPU_XREG_OFFSET(19)
>  	ldp	x19, x20, [x3]
> @@ -113,9 +125,15 @@
>  
>  .macro save_host_regs
>  	save_common_regs
> +ifnvhe	nop,					"b	skip_el1_save"
> +	save_el1_state
> +skip_el1_save:
>  .endm
>  
>  .macro restore_host_regs
> +ifnvhe	nop,					"b	skip_el1_restore"
> +	restore_el1_state
> +skip_el1_restore:
>  	restore_common_regs
>  .endm
>  
> @@ -159,6 +177,7 @@
>  	stp	x6, x7, [x3, #16]
>  
>  	save_common_regs
> +	save_el1_state
>  .endm
>  
>  .macro restore_guest_regs
> @@ -184,6 +203,7 @@
>  	ldr	x18, [x3, #144]
>  
>  	// x19-x29, lr, sp*, elr*, spsr*
> +	restore_el1_state
>  	restore_common_regs
>  
>  	// Last bits of the 64bit state
> @@ -203,6 +223,38 @@
>   * In other words, don't touch any of these unless you know what
>   * you are doing.
>   */
> +
> +.macro save_shared_sysregs
> +	// x2: base address for cpu context
> +	// x3: tmp register
> +
> +	add	x3, x2, #CPU_SYSREG_OFFSET(TPIDR_EL0)
> +
> +	mrs	x4, tpidr_el0
> +	mrs	x5, tpidrro_el0
> +	mrs	x6, tpidr_el1
> +	mrs	x7, actlr_el1
> +
> +	stp	x4, x5, [x3]
> +	stp	x6, x7, [x3, #16]
> +.endm
> +
> +.macro restore_shared_sysregs
> +	// x2: base address for cpu context
> +	// x3: tmp register
> +
> +	add	x3, x2, #CPU_SYSREG_OFFSET(TPIDR_EL0)
> +
> +	ldp	x4, x5, [x3]
> +	ldp	x6, x7, [x3, #16]
> +
> +	msr	tpidr_el0,      x4
> +	msr	tpidrro_el0,    x5
> +	msr	tpidr_el1,      x6
> +	msr	actlr_el1,      x7
> +.endm
> +
> +
>  .macro save_sysregs
>  	// x2: base address for cpu context
>  	// x3: tmp register
> @@ -211,26 +263,27 @@
>  
>  	mrs	x4,	vmpidr_el2
>  	mrs	x5,	csselr_el1
> -	mrs	x6,	sctlr_el1
> -	mrs	x7,	actlr_el1
> -	mrs	x8,	cpacr_el1
> -	mrs	x9,	ttbr0_el1
> -	mrs	x10,	ttbr1_el1
> -	mrs	x11,	tcr_el1
> -	mrs	x12,	esr_el1
> -	mrs	x13, 	afsr0_el1
> -	mrs	x14,	afsr1_el1
> -	mrs	x15,	far_el1
> -	mrs	x16,	mair_el1
> -	mrs	x17,	vbar_el1
> -	mrs	x18,	contextidr_el1
> -	mrs	x19,	tpidr_el0
> -	mrs	x20,	tpidrro_el0
> -	mrs	x21,	tpidr_el1
> -	mrs	x22, 	amair_el1
> -	mrs	x23, 	cntkctl_el1
> -	mrs	x24,	par_el1
> -	mrs	x25,	mdscr_el1
> +	mrs_el1(x6,	sctlr)
> +	mrs_el1(x7, 	amair)
> +	mrs_el1(x8,	cpacr)
> +	mrs_el1(x9,	ttbr0)
> +	mrs_el1(x10,	ttbr1)
> +	mrs_el1(x11,	tcr)
> +	mrs_el1(x12,	esr)
> +	mrs_el1(x13, 	afsr0)
> +	mrs_el1(x14,	afsr1)
> +	mrs_el1(x15,	far)
> +	mrs_el1(x16,	mair)
> +	mrs_el1(x17,	vbar)
> +	mrs_el1(x18,	contextidr)
> +	mrs_el1(x19, 	cntkctl)
> +	mrs	x20,	par_el1
> +	mrs	x21,	mdscr_el1
> +
> +	mrs	x22,	tpidr_el0
> +	mrs	x23,	tpidrro_el0
> +	mrs	x24,	tpidr_el1
> +	mrs	x25,	actlr_el1
>  
>  	stp	x4, x5, [x3]
>  	stp	x6, x7, [x3, #16]
> @@ -460,26 +513,27 @@
>  
>  	msr	vmpidr_el2,	x4
>  	msr	csselr_el1,	x5
> -	msr	sctlr_el1,	x6
> -	msr	actlr_el1,	x7
> -	msr	cpacr_el1,	x8
> -	msr	ttbr0_el1,	x9
> -	msr	ttbr1_el1,	x10
> -	msr	tcr_el1,	x11
> -	msr	esr_el1,	x12
> -	msr	afsr0_el1,	x13
> -	msr	afsr1_el1,	x14
> -	msr	far_el1,	x15
> -	msr	mair_el1,	x16
> -	msr	vbar_el1,	x17
> -	msr	contextidr_el1,	x18
> -	msr	tpidr_el0,	x19
> -	msr	tpidrro_el0,	x20
> -	msr	tpidr_el1,	x21
> -	msr	amair_el1,	x22
> -	msr	cntkctl_el1,	x23
> -	msr	par_el1,	x24
> -	msr	mdscr_el1,	x25
> +	msr_el1(sctlr,		x6)
> +	msr_el1(amair,		x7)
> +	msr_el1(cpacr,		x8)
> +	msr_el1(ttbr0,		x9)
> +	msr_el1(ttbr1,		x10)
> +	msr_el1(tcr,		x11)
> +	msr_el1(esr,		x12)
> +	msr_el1(afsr0,		x13)
> +	msr_el1(afsr1,		x14)
> +	msr_el1(far,		x15)
> +	msr_el1(mair,		x16)
> +	msr_el1(vbar,		x17)
> +	msr_el1(contextidr,	x18)
> +	msr_el1(cntkctl,	x19)
> +	msr	par_el1,	x20
> +	msr	mdscr_el1,	x21
> +
> +	msr	tpidr_el0,	x22
> +	msr	tpidrro_el0,	x23
> +	msr	tpidr_el1,	x24
> +	msr	actlr_el1,	x25
>  .endm
>  
>  .macro restore_debug
> @@ -779,8 +833,11 @@
>  .macro activate_traps
>  	ldr     x2, [x0, #VCPU_HCR_EL2]
>  	msr     hcr_el2, x2
> -	mov	x2, #CPTR_EL2_TTA
> -	msr	cptr_el2, x2
> +	adr	x3, __kvm_hyp_vector
> +ifnvhe	nop,					"msr	vbar_el1, x3"
> +ifnvhe	nop,					"mrs	x2, cpacr_el1"
> +ifnvhe _S_(ldr	x2, =(CPTR_EL2_TTA)),		"orr x2, x2, #(1 << 28)"
> +ifnvhe "msr	cptr_el2, x2",			"msr	cpacr_el1, x2"
>  
>  	mov	x2, #(1 << 15)	// Trap CP15 Cr=15
>  	msr	hstr_el2, x2
> @@ -803,12 +860,20 @@
>  ifnvhe _S_(mov	x2, #HCR_RW),			_S_(mov	x2, #HCR_RW|HCR_TGE)
>  ifnvhe 	nop,					_S_(orr	x2, x2, #HCR_E2H)
>  	msr	hcr_el2, x2
> -	msr	cptr_el2, xzr
> +
> +ifnvhe	nop,					"mrs	x2, cpacr_el1"
> +ifnvhe	nop,					"movn	x3, #(1 << 12), lsl #16"
> +ifnvhe	nop,					"and	x2, x2, x3"
> +ifnvhe "msr	cptr_el2, xzr",			"msr	cpacr_el1, x2"
>  	msr	hstr_el2, xzr
>  
>  	mrs	x2, mdcr_el2
>  	and	x2, x2, #MDCR_EL2_HPMN_MASK
>  	msr	mdcr_el2, x2
> +
> +	adrp	x2, vectors
> +	add	x2, x2, #:lo12:vectors
> +ifnvhe	nop,					"msr	vbar_el1, x2"
>  .endm
>  
>  .macro activate_vm
> @@ -853,15 +918,15 @@ ifnvhe 	nop,					_S_(orr	x2, x2, #HCR_E2H)
>  	ldr	w3, [x2, #KVM_TIMER_ENABLED]
>  	cbz	w3, 1f
>  
> -	mrs	x3, cntv_ctl_el0
> +	mrs_el0(x3, cntv_ctl)
>  	and	x3, x3, #3
>  	str	w3, [x0, #VCPU_TIMER_CNTV_CTL]
>  	bic	x3, x3, #1		// Clear Enable
> -	msr	cntv_ctl_el0, x3
> +	msr_el0(cntv_ctl, x3)
>  
>  	isb
>  
> -	mrs	x3, cntv_cval_el0
> +	mrs_el0(x3, cntv_cval)
>  	str	x3, [x0, #VCPU_TIMER_CNTV_CVAL]
>  
>  1:
> @@ -871,7 +936,7 @@ ifnvhe 	nop,					_S_(orr	x2, x2, #HCR_E2H)
>  	msr	cnthctl_el2, x2
>  
>  	// Clear cntvoff for the host
> -	msr	cntvoff_el2, xzr
> +ifnvhe "msr	cntvoff_el2, xzr",		nop
>  .endm
>  
>  .macro restore_timer_state
> @@ -891,12 +956,12 @@ ifnvhe 	nop,					_S_(orr	x2, x2, #HCR_E2H)
>  	ldr	x3, [x2, #KVM_TIMER_CNTVOFF]
>  	msr	cntvoff_el2, x3
>  	ldr	x2, [x0, #VCPU_TIMER_CNTV_CVAL]
> -	msr	cntv_cval_el0, x2
> +	msr_el0(cntv_cval, x2)
>  	isb
>  
>  	ldr	w2, [x0, #VCPU_TIMER_CNTV_CTL]
>  	and	x2, x2, #3
> -	msr	cntv_ctl_el0, x2
> +	msr_el0(cntv_ctl, x2)
>  1:
>  .endm
>  
> @@ -945,8 +1010,10 @@ ENTRY(__kvm_vcpu_run)
>  
>  	save_host_regs
>  	bl __save_fpsimd
> -	bl __save_sysregs
> -
> +ifnvhe "bl	__save_sysregs",		nop
> +ifnvhe "b	1f",				nop
> +	save_shared_sysregs
> +1:
>  	compute_debug_state 1f
>  	bl	__save_debug
>  1:
> @@ -997,7 +1064,10 @@ __kvm_vcpu_return:
>  	ldr	x2, [x0, #VCPU_HOST_CONTEXT]
>  	kern_hyp_va x2
>  
> -	bl __restore_sysregs
> +ifnvhe "bl	__restore_sysregs",		nop
> +ifnvhe "b	1f",				nop
> +	restore_shared_sysregs
> +1:
>  	bl __restore_fpsimd
>  
>  	skip_debug_state x3, 1f
> @@ -1104,6 +1174,8 @@ __kvm_hyp_panic:
>  	mrs	x6, par_el1
>  	mrs	x7, tpidr_el2
>  
> +ifnvhe	nop,					"b	panic"
> +
>  	mov	lr, #(PSR_F_BIT | PSR_I_BIT | PSR_A_BIT | PSR_D_BIT |\
>  		      PSR_MODE_EL1h)
>  	msr	spsr_el2, lr
> @@ -1248,7 +1320,7 @@ el1_trap:
>  	 * As such, we can use the EL1 translation regime, and don't have
>  	 * to distinguish between EL0 and EL1 access.
>  	 */
> -	mrs	x2, far_el2
> +ifnvhe "mrs	x2, far_el2",			"mrs	x2, far_el1"
>  	at	s1e1r, x2
>  	isb
>  
> @@ -1262,7 +1334,7 @@ el1_trap:
>  	b	2f
>  
>  1:	mrs	x3, hpfar_el2
> -	mrs	x2, far_el2
> +ifnvhe "mrs	x2, far_el2",			"mrs	x2, far_el1"
>  
>  2:	mrs	x0, tpidr_el2
>  	str	w1, [x0, #VCPU_ESR_EL2]
> diff --git a/arch/arm64/kvm/vhe-macros.h b/arch/arm64/kvm/vhe-macros.h
> index da7f9da..1e94235 100644
> --- a/arch/arm64/kvm/vhe-macros.h
> +++ b/arch/arm64/kvm/vhe-macros.h
> @@ -31,6 +31,24 @@
>  	alternative_insn	"\nonvhe", "\vhe", ARM64_HAS_VIRT_HOST_EXTN
>  .endm
>  
> +#define mrs_el0(reg, sysreg)	\
> +	ifnvhe  _S_(mrs reg, sysreg##_EL0), _S_(mrs_s reg, sysreg##_EL02)
> +
> +#define msr_el0(sysreg, reg)	\
> +	ifnvhe  _S_(msr sysreg##_EL0, reg), _S_(msr_s sysreg##_EL02, reg)
> +
> +#define mrs_el1(reg, sysreg)	\
> +	ifnvhe  _S_(mrs reg, sysreg##_EL1), _S_(mrs_s reg, sysreg##_EL12)
> +
> +#define msr_el1(sysreg, reg)	\
> +	ifnvhe  _S_(msr sysreg##_EL1, reg), _S_(msr_s sysreg##_EL12, reg)
> +
> +#define mrs_hyp(reg, sysreg)	\
> +	ifnvhe  _S_(mrs reg, sysreg##_EL2), _S_(mrs reg, sysreg##_EL1)
> +
> +#define msr_hyp(sysreg, reg)	\
> +	ifnvhe  _S_(msr sysreg##_EL2, reg), _S_(msr sysreg##_EL1, reg)
> +
>  #endif
>  
>  #endif	/*__ARM64_VHE_MACROS_H__  */
> -- 
> 2.1.4
> 


From christoffer.dall at linaro.org  Mon Aug 31 11:49:17 2015
From: christoffer.dall at linaro.org (Christoffer Dall)
Date: Mon, 31 Aug 2015 20:49:17 +0200
Subject: [PATCH 12/13] arm64: KVM: Split sysreg save/restore
In-Reply-To: <1436372356-30410-13-git-send-email-marc.zyngier@arm.com>
References: <1436372356-30410-1-git-send-email-marc.zyngier@arm.com>
 <1436372356-30410-13-git-send-email-marc.zyngier@arm.com>
Message-ID: <20150831184917.GC10991@cbox>

On Wed, Jul 08, 2015 at 05:19:15PM +0100, Marc Zyngier wrote:
> As we're starting to get different requirements for non-VHE and VHE
> code paths, use a slightly more fine-grained approach:
> 
> - __save/restore_sysregs: save/restore non-shared sysregs
> - __save/restore_shared_sysregs: save/restore only shared sysregs
> 
> Of course, non-VHE always requires both.
> 

I'm sorry, I don't really understand what this patch does.

What is a 'shared sysreg' exactly?  One that is shared between the host
and the guest?

Or one that is shared between EL1 and EL2?  Or is that the same thing?

> Signed-off-by: Marc Zyngier <marc.zyngier at arm.com>
> ---
>  arch/arm64/kvm/hyp.S | 91 +++++++++++++++++++++++++---------------------------
>  1 file changed, 44 insertions(+), 47 deletions(-)
> 
> diff --git a/arch/arm64/kvm/hyp.S b/arch/arm64/kvm/hyp.S
> index b61591b..3cbd2c4 100644
> --- a/arch/arm64/kvm/hyp.S
> +++ b/arch/arm64/kvm/hyp.S
> @@ -280,11 +280,6 @@ skip_el1_restore:
>  	mrs	x20,	par_el1
>  	mrs	x21,	mdscr_el1
>  
> -	mrs	x22,	tpidr_el0
> -	mrs	x23,	tpidrro_el0
> -	mrs	x24,	tpidr_el1
> -	mrs	x25,	actlr_el1
> -
>  	stp	x4, x5, [x3]
>  	stp	x6, x7, [x3, #16]
>  	stp	x8, x9, [x3, #32]
> @@ -294,8 +289,6 @@ skip_el1_restore:
>  	stp	x16, x17, [x3, #96]
>  	stp	x18, x19, [x3, #112]
>  	stp	x20, x21, [x3, #128]
> -	stp	x22, x23, [x3, #144]
> -	stp	x24, x25, [x3, #160]
>  .endm
>  
>  .macro save_debug
> @@ -508,8 +501,6 @@ skip_el1_restore:
>  	ldp	x16, x17, [x3, #96]
>  	ldp	x18, x19, [x3, #112]
>  	ldp	x20, x21, [x3, #128]
> -	ldp	x22, x23, [x3, #144]
> -	ldp	x24, x25, [x3, #160]
>  
>  	msr	vmpidr_el2,	x4
>  	msr	csselr_el1,	x5
> @@ -529,11 +520,6 @@ skip_el1_restore:
>  	msr_el1(cntkctl,	x19)
>  	msr	par_el1,	x20
>  	msr	mdscr_el1,	x21
> -
> -	msr	tpidr_el0,	x22
> -	msr	tpidrro_el0,	x23
> -	msr	tpidr_el1,	x24
> -	msr	actlr_el1,	x25
>  .endm
>  
>  .macro restore_debug
> @@ -913,10 +899,12 @@ ifnvhe	nop,					"msr	vbar_el1, x2"
>  
>  .macro save_timer_state
>  	// x0: vcpu pointer
> -	ldr	x2, [x0, #VCPU_KVM]
> -	kern_hyp_va x2
> -	ldr	w3, [x2, #KVM_TIMER_ENABLED]
> -	cbz	w3, 1f
> +	// x1: return code
> +	// x2: vcpu context
> +	ldr	x3, [x0, #VCPU_KVM]
> +	kern_hyp_va x3
> +	ldr	w4, [x3, #KVM_TIMER_ENABLED]
> +	cbz	w4, 1f
>  
>  	mrs_el0(x3, cntv_ctl)
>  	and	x3, x3, #3
> @@ -931,9 +919,9 @@ ifnvhe	nop,					"msr	vbar_el1, x2"
>  
>  1:
>  	// Allow physical timer/counter access for the host
> -	mrs	x2, cnthctl_el2
> -	orr	x2, x2, #3
> -	msr	cnthctl_el2, x2
> +	mrs	x3, cnthctl_el2
> +	orr	x3, x3, #3
> +	msr	cnthctl_el2, x3
>  
>  	// Clear cntvoff for the host
>  ifnvhe "msr	cntvoff_el2, xzr",		nop
> @@ -941,34 +929,43 @@ ifnvhe "msr	cntvoff_el2, xzr",		nop
>  
>  .macro restore_timer_state
>  	// x0: vcpu pointer
> +	// x2: vcpu context
>  	// Disallow physical timer access for the guest
>  	// Physical counter access is allowed
> -	mrs	x2, cnthctl_el2
> -	orr	x2, x2, #1
> -	bic	x2, x2, #2
> -	msr	cnthctl_el2, x2
> -
> -	ldr	x2, [x0, #VCPU_KVM]
> -	kern_hyp_va x2
> -	ldr	w3, [x2, #KVM_TIMER_ENABLED]
> -	cbz	w3, 1f
> -
> -	ldr	x3, [x2, #KVM_TIMER_CNTVOFF]
> -	msr	cntvoff_el2, x3
> -	ldr	x2, [x0, #VCPU_TIMER_CNTV_CVAL]
> -	msr_el0(cntv_cval, x2)
> +	mrs	x3, cnthctl_el2
> +	orr	x3, x3, #1
> +	bic	x3, x3, #2
> +	msr	cnthctl_el2, x3
> +
> +	ldr	x3, [x0, #VCPU_KVM]
> +	kern_hyp_va x3
> +	ldr	w4, [x3, #KVM_TIMER_ENABLED]
> +	cbz	w4, 1f
> +
> +	ldr	x4, [x3, #KVM_TIMER_CNTVOFF]
> +	msr	cntvoff_el2, x4
> +	ldr	x4, [x0, #VCPU_TIMER_CNTV_CVAL]
> +	msr_el0(cntv_cval, x4)
>  	isb
>  
> -	ldr	w2, [x0, #VCPU_TIMER_CNTV_CTL]
> -	and	x2, x2, #3
> -	msr_el0(cntv_ctl, x2)
> +	ldr	w4, [x0, #VCPU_TIMER_CNTV_CTL]
> +	and	x4, x4, #3
> +	msr_el0(cntv_ctl, x4)
>  1:
>  .endm
>  
> +__save_shared_sysregs:
> +	save_shared_sysregs
> +	ret
> +
>  __save_sysregs:
>  	save_sysregs
>  	ret
>  
> +__restore_shared_sysregs:
> +	restore_shared_sysregs
> +	ret
> +
>  __restore_sysregs:
>  	restore_sysregs
>  	ret
> @@ -1010,10 +1007,9 @@ ENTRY(__kvm_vcpu_run)
>  
>  	save_host_regs
>  	bl __save_fpsimd
> -ifnvhe "bl	__save_sysregs",		nop
> -ifnvhe "b	1f",				nop
> -	save_shared_sysregs
> -1:
> +ifnvhe "bl	__save_sysregs",		"nop"
> +	bl	__save_shared_sysregs
> +
>  	compute_debug_state 1f
>  	bl	__save_debug
>  1:
> @@ -1027,6 +1023,7 @@ ifnvhe "b	1f",				nop
>  	add	x2, x0, #VCPU_CONTEXT
>  
>  	bl __restore_sysregs
> +	bl __restore_shared_sysregs
>  	bl __restore_fpsimd
>  
>  	skip_debug_state x3, 1f
> @@ -1048,6 +1045,7 @@ __kvm_vcpu_return:
>  	save_guest_regs
>  	bl __save_fpsimd
>  	bl __save_sysregs
> +	bl __save_shared_sysregs
>  
>  	skip_debug_state x3, 1f
>  	bl	__save_debug
> @@ -1064,10 +1062,8 @@ __kvm_vcpu_return:
>  	ldr	x2, [x0, #VCPU_HOST_CONTEXT]
>  	kern_hyp_va x2
>  
> -ifnvhe "bl	__restore_sysregs",		nop
> -ifnvhe "b	1f",				nop
> -	restore_shared_sysregs
> -1:
> +ifnvhe "bl	__restore_sysregs",		"nop"
> +	bl	__restore_shared_sysregs
>  	bl __restore_fpsimd
>  
>  	skip_debug_state x3, 1f
> @@ -1159,7 +1155,8 @@ __kvm_hyp_panic:
>  	ldr	x2, [x0, #VCPU_HOST_CONTEXT]
>  	kern_hyp_va x2
>  
> -	bl __restore_sysregs
> +ifnvhe "bl __restore_sysregs",			"nop"
> +	bl __restore_shared_sysregs
>  
>  1:	adr	x0, __hyp_panic_str
>  	adr	x1, 2f
> -- 
> 2.1.4
> 


From christoffer.dall at linaro.org  Mon Aug 31 11:52:26 2015
From: christoffer.dall at linaro.org (Christoffer Dall)
Date: Mon, 31 Aug 2015 20:52:26 +0200
Subject: [PATCH 13/13] arm64: KVM: VHE: Early interrupt handling
In-Reply-To: <1436372356-30410-14-git-send-email-marc.zyngier@arm.com>
References: <1436372356-30410-1-git-send-email-marc.zyngier@arm.com>
 <1436372356-30410-14-git-send-email-marc.zyngier@arm.com>
Message-ID: <20150831185226.GD10991@cbox>

On Wed, Jul 08, 2015 at 05:19:16PM +0100, Marc Zyngier wrote:
> With VHE enabled, it is possible to let the kernel handle an interrupt
> without saving the full guest context, and without restoring the full
> host context either. This reduces the latency of handling an interrupt.
> 
> When an interrupt fires we can:
> - save the guest's general purpose registers, shared system registers
>   and timer state
> - switch to a host context (setting vectors, deactivating traps and
>   stage-2 translation)
> - restore the host's shared sysregs
> 
> At that stage, we're able to jump to the interrupt handler.
> 
> On return from the handler, we can finish the switch (save/restore
> whatever is missing from the above).

This feels like a specific optimization, and again it looks to me like
we're just going to see more of this.

For example, sending a virtual IPI shoud ideally be done without having
to do all the crazy save/restore stuff.

Maybe I'm missing something overall here, but I feel the whole design of
this solution requires some justification in the cover letter.

Thanks,
-Christoffer

> 
> Signed-off-by: Marc Zyngier <marc.zyngier at arm.com>
> ---
>  arch/arm/kvm/arm.c              |  3 +++
>  arch/arm64/kvm/hyp.S            | 56 ++++++++++++++++++++++++++++++++++++++---
>  arch/arm64/kvm/vgic-v2-switch.S | 19 +++++++++++---
>  arch/arm64/kvm/vgic-v3-switch.S | 33 +++++++++++++-----------
>  4 files changed, 90 insertions(+), 21 deletions(-)
> 
> diff --git a/arch/arm/kvm/arm.c b/arch/arm/kvm/arm.c
> index ca3c662..ab9333f 100644
> --- a/arch/arm/kvm/arm.c
> +++ b/arch/arm/kvm/arm.c
> @@ -573,6 +573,9 @@ int kvm_arch_vcpu_ioctl_run(struct kvm_vcpu *vcpu, struct kvm_run *run)
>  		 * disabled.  Enabling the interrupts now will have
>  		 * the effect of taking the interrupt again, in SVC
>  		 * mode this time.
> +		 *
> +		 * With VHE, the interrupt is likely to have been
> +		 * already taken already.
>  		 */
>  		local_irq_enable();
>  
> diff --git a/arch/arm64/kvm/hyp.S b/arch/arm64/kvm/hyp.S
> index 3cbd2c4..ac95ba3 100644
> --- a/arch/arm64/kvm/hyp.S
> +++ b/arch/arm64/kvm/hyp.S
> @@ -714,8 +714,10 @@ skip_el1_restore:
>  .endm
>  
>  .macro skip_32bit_state tmp, target
> -	// Skip 32bit state if not needed
> -	mrs	\tmp, hcr_el2
> +	// Skip 32bit state if not needed.
> +	// With VHE, we may have cleared the RW bit in HCR_EL2 early,
> +	// and have to rely on the memory version instead.
> +ifnvhe "mrs	\tmp, hcr_el2",			_S_(ldr	\tmp, [x0, #VCPU_HCR_EL2])
>  	tbnz	\tmp, #HCR_RW_SHIFT, \target
>  .endm
>  
> @@ -1053,11 +1055,18 @@ __kvm_vcpu_return:
>  	save_guest_32bit_state
>  
>  	save_timer_state
> +ifnvhe "b	1f",		nop
> +	alternative_insn	"bl __vgic_v2_disable", \
> +				"bl __vgic_v3_disable", \
> +				ARM64_HAS_SYSREG_GIC_CPUIF
> +1:
>  	save_vgic_state
>  
>  	deactivate_traps
>  	deactivate_vm
>  
> +__kvm_vcpu_return_irq:
> +
>  	// Host context
>  	ldr	x2, [x0, #VCPU_HOST_CONTEXT]
>  	kern_hyp_va x2
> @@ -1355,8 +1364,47 @@ el1_irq:
>  	push	x0, x1
>  	push	x2, x3
>  	mrs	x0, tpidr_el2
> -	mov	x1, #ARM_EXCEPTION_IRQ
> -	b	__kvm_vcpu_return
> +ifnvhe _S_(mov	x1, #ARM_EXCEPTION_IRQ),	nop
> +ifnvhe "b	__kvm_vcpu_return", 		nop
> +
> +	// Fallthrough for VHE
> +	add	x2, x0, #VCPU_CONTEXT
> +
> +	save_guest_regs
> +	bl	__save_shared_sysregs
> +	save_timer_state
> +	alternative_insn	"bl __vgic_v2_disable", \
> +				"bl __vgic_v3_disable", \
> +				ARM64_HAS_SYSREG_GIC_CPUIF
> +	deactivate_traps
> +	deactivate_vm
> +
> +	isb	// Needed to ensure TGE is on and vectors have been switched
> +
> +	ldr	x2, [x0, #VCPU_HOST_CONTEXT]
> +	restore_shared_sysregs
> +
> +	mov	x0, x2
> +	adrp	x1, handle_arch_irq
> +	add	x1, x1, #:lo12:handle_arch_irq
> +	ldr	x1, [x1]
> +	blr	x1
> +
> +	// Back from the interrupt handler, finalize the world switch
> +	mrs	x0, tpidr_el2
> +	add	x2, x0, #VCPU_CONTEXT
> +
> +	bl	__save_fpsimd
> +	bl	__save_sysregs	// We've already saved the shared regs
> +	save_guest_32bit_state
> +
> +	skip_debug_state x3, 1f
> +	bl	__save_debug
> +1:
> +	save_vgic_state
> +
> +	mov	x1,	#ARM_EXCEPTION_IRQ
> +	b	__kvm_vcpu_return_irq
>  
>  	.ltorg
>  
> diff --git a/arch/arm64/kvm/vgic-v2-switch.S b/arch/arm64/kvm/vgic-v2-switch.S
> index 3f00071..c8864b4 100644
> --- a/arch/arm64/kvm/vgic-v2-switch.S
> +++ b/arch/arm64/kvm/vgic-v2-switch.S
> @@ -26,16 +26,30 @@
>  #include <asm/kvm_arm.h>
>  #include <asm/kvm_mmu.h>
>  
> +#include "vhe-macros.h"
> +
>  	.text
>  	.pushsection	.hyp.text, "ax"
>  
> +ENTRY(__vgic_v2_disable)
> +	/* Get VGIC VCTRL base into x2 */
> +	ldr	x2, [x0, #VCPU_KVM]
> +	kern_hyp_va	x2
> +	ldr	x2, [x2, #KVM_VGIC_VCTRL]
> +	kern_hyp_va	x2
> +	cbz	x2, 1f		// disabled
> +
> +	/* Clear GICH_HCR */
> +	str	wzr, [x2, #GICH_HCR]
> +1:	ret
> +ENDPROC(__vgic_v2_disable)
> +
>  /*
>   * Save the VGIC CPU state into memory
>   * x0: Register pointing to VCPU struct
>   * Do not corrupt x1!!!
>   */
>  ENTRY(__save_vgic_v2_state)
> -__save_vgic_v2_state:
>  	/* Get VGIC VCTRL base into x2 */
>  	ldr	x2, [x0, #VCPU_KVM]
>  	kern_hyp_va	x2
> @@ -75,7 +89,7 @@ CPU_BE(	str	w10, [x3, #VGIC_V2_CPU_ELRSR] )
>  	str	w11, [x3, #VGIC_V2_CPU_APR]
>  
>  	/* Clear GICH_HCR */
> -	str	wzr, [x2, #GICH_HCR]
> +ifnvhe	_S_(str	wzr, [x2, #GICH_HCR]),		nop
>  
>  	/* Save list registers */
>  	add	x2, x2, #GICH_LR0
> @@ -95,7 +109,6 @@ ENDPROC(__save_vgic_v2_state)
>   * x0: Register pointing to VCPU struct
>   */
>  ENTRY(__restore_vgic_v2_state)
> -__restore_vgic_v2_state:
>  	/* Get VGIC VCTRL base into x2 */
>  	ldr	x2, [x0, #VCPU_KVM]
>  	kern_hyp_va	x2
> diff --git a/arch/arm64/kvm/vgic-v3-switch.S b/arch/arm64/kvm/vgic-v3-switch.S
> index 3c20730..b9b45e3 100644
> --- a/arch/arm64/kvm/vgic-v3-switch.S
> +++ b/arch/arm64/kvm/vgic-v3-switch.S
> @@ -25,6 +25,8 @@
>  #include <asm/kvm_asm.h>
>  #include <asm/kvm_arm.h>
>  
> +#include "vhe-macros.h"
> +
>  	.text
>  	.pushsection	.hyp.text, "ax"
>  
> @@ -35,11 +37,21 @@
>  #define LR_OFFSET(n)	(VGIC_V3_CPU_LR + (15 - n) * 8)
>  
>  /*
> + * Disable the vcpu interface, preventing interrupts from
> + * being delivered.
> + */
> +ENTRY(__vgic_v3_disable)
> +	// Nuke the HCR register.
> +	msr_s	ICH_HCR_EL2, xzr
> +	ret
> +ENDPROC(__vgic_v3_disable)
> +
> +/*
>   * Save the VGIC CPU state into memory
>   * x0: Register pointing to VCPU struct
>   * Do not corrupt x1!!!
>   */
> -.macro	save_vgic_v3_state
> +ENTRY(__save_vgic_v3_state)
>  	// Compute the address of struct vgic_cpu
>  	add	x3, x0, #VCPU_VGIC_CPU
>  
> @@ -58,7 +70,7 @@
>  	str	w7, [x3, #VGIC_V3_CPU_EISR]
>  	str	w8, [x3, #VGIC_V3_CPU_ELRSR]
>  
> -	msr_s	ICH_HCR_EL2, xzr
> +ifnvhe	_S_(msr_s	ICH_HCR_EL2, xzr),	nop
>  
>  	mrs_s	x21, ICH_VTR_EL2
>  	mvn	w22, w21
> @@ -137,15 +149,17 @@
>  	orr	x5, x5, #ICC_SRE_EL2_ENABLE
>  	msr_s	ICC_SRE_EL2, x5
>  	isb
> -	mov	x5, #1
> +	// If using VHE, we don't care about EL1 and can early out.
> +ifnvhe "mov	x5, #1",			ret
>  	msr_s	ICC_SRE_EL1, x5
> -.endm
> +	ret
> +ENDPROC(__save_vgic_v3_state)
>  
>  /*
>   * Restore the VGIC CPU state from memory
>   * x0: Register pointing to VCPU struct
>   */
> -.macro	restore_vgic_v3_state
> +ENTRY(__restore_vgic_v3_state)
>  	// Compute the address of struct vgic_cpu
>  	add	x3, x0, #VCPU_VGIC_CPU
>  
> @@ -249,15 +263,6 @@
>  	and	x5, x5, #~ICC_SRE_EL2_ENABLE
>  	msr_s	ICC_SRE_EL2, x5
>  1:
> -.endm
> -
> -ENTRY(__save_vgic_v3_state)
> -	save_vgic_v3_state
> -	ret
> -ENDPROC(__save_vgic_v3_state)
> -
> -ENTRY(__restore_vgic_v3_state)
> -	restore_vgic_v3_state
>  	ret
>  ENDPROC(__restore_vgic_v3_state)
>  
> -- 
> 2.1.4
> 


From dhdang at apm.com  Mon Aug 31 11:58:48 2015
From: dhdang at apm.com (Duc Dang)
Date: Mon, 31 Aug 2015 11:58:48 -0700
Subject: [PATCH v7 1/2] usb: make xhci platform driver use 64 bit or 32
 bit DMA
In-Reply-To: <69e6f5bf693d02fba001d02047453bed0519499d.1440098398.git.dhdang@apm.com>
References: <1522889.9kdnRk8vHo@wuerfel>
 <69e6f5bf693d02fba001d02047453bed0519499d.1440098398.git.dhdang@apm.com>
Message-ID: <CADaLNDnPaeHcMjywsuQ4oiUpWsNpStshdKVtW=tuUorrcQkZ=g@mail.gmail.com>

On Thu, Aug 20, 2015 at 12:38 PM, Duc Dang <dhdang at apm.com> wrote:
> The xhci platform driver needs to work on systems that
> either only support 64-bit DMA or only support 32-bit DMA.
> Attempt to set a coherent dma mask for 64-bit DMA, and
> attempt again with 32-bit DMA if that fails.
>
> [dhdang: regenerate the patch over 4.2-rc5 and address new comments]
> Signed-off-by: Mark Langsdorf <mlangsdo at redhat.com>
> Tested-by: Mark Salter <msalter at redhat.com>
> Signed-off-by: Duc Dang <dhdang at apm.com>
>
> ---
> Changes from v6:
>         -Add WARN_ON if dma_mask is NULL
>         -Use dma_coerce_mask_and_coherent to assign
>         dma_mask and coherent_dma_mask
>
> Changes from v5:
>         -Change comment
>         -Assign dma_mask to coherent_dma_mask if dma_mask is NULL
>         to make sure dma_set_mask_and_coherent does not fail prematurely.
>
> Changes from v4:
>         -None
>
> Changes from v3:
>         -Re-generate the patch over 4.2-rc5
>         -No code change.
>
> Changes from v2:
>         -None
>
> Changes from v1:
>         -Consolidated to use dma_set_mask_and_coherent
>         -Got rid of the check against sizeof(dma_addr_t)
>
>  drivers/usb/host/xhci-plat.c | 21 +++++++++++++--------
>  1 file changed, 13 insertions(+), 8 deletions(-)
>
> diff --git a/drivers/usb/host/xhci-plat.c b/drivers/usb/host/xhci-plat.c
> index 890ad9d..e4c7f9d 100644
> --- a/drivers/usb/host/xhci-plat.c
> +++ b/drivers/usb/host/xhci-plat.c
> @@ -93,14 +93,19 @@ static int xhci_plat_probe(struct platform_device *pdev)
>         if (irq < 0)
>                 return -ENODEV;
>
> -       /* Initialize dma_mask and coherent_dma_mask to 32-bits */
> -       ret = dma_set_coherent_mask(&pdev->dev, DMA_BIT_MASK(32));
> -       if (ret)
> -               return ret;
> -       if (!pdev->dev.dma_mask)
> -               pdev->dev.dma_mask = &pdev->dev.coherent_dma_mask;
> -       else
> -               dma_set_mask(&pdev->dev, DMA_BIT_MASK(32));
> +       /* Throw a waring if broken platform code didn't initialize dma_mask */
> +       WARN_ON(!pdev->dev.dma_mask);
> +       /*
> +        * Try setting dma_mask and coherent_dma_mask to 64 bits,
> +        * then try 32 bits
> +        */
> +       ret = dma_coerce_mask_and_coherent(&pdev->dev, DMA_BIT_MASK(64));
> +       if (ret) {
> +               ret = dma_coerce_mask_and_coherent(&pdev->dev,
> +                                                  DMA_BIT_MASK(32));
> +               if (ret)
> +                       return ret;
> +       }
>
>         hcd = usb_create_hcd(driver, &pdev->dev, dev_name(&pdev->dev));
>         if (!hcd)
> --
> 1.9.1
>

Hi Greg, Arnd, Russell,

Do you have any more comment about this patch set?

-- 
Duc Dang.


From jogo at openwrt.org  Mon Aug 31 12:22:12 2015
From: jogo at openwrt.org (Jonas Gorski)
Date: Mon, 31 Aug 2015 21:22:12 +0200
Subject: [PATCH linux-next v5 1/5] mtd: spi-nor: notify (Q)SPI controller
 about protocol change
In-Reply-To: <55DEDDBD.8060408@atmel.com>
References: <cover.1440580764.git.cyrille.pitchen@atmel.com>
 <464fce12d75a5ba2105456cfd0a385b2d40305ba.1440580764.git.cyrille.pitchen@atmel.com>
 <CAOiHx=n+byfsbJNhnboqDEwhruOT8uKDJ+CcES7QBqPDLVAMsw@mail.gmail.com>
 <55DEDDBD.8060408@atmel.com>
Message-ID: <CAOiHx=m0FhuH5BR-EYp4yQyB83yGRzdCFAPVfqB0b0+BvRE-6Q@mail.gmail.com>

Hi,

On Thu, Aug 27, 2015 at 11:51 AM, Cyrille Pitchen
<cyrille.pitchen at atmel.com> wrote:
> Hi Jonas,
>
> Le 26/08/2015 16:02, Jonas Gorski a ?crit :
>> On Wed, Aug 26, 2015 at 2:30 PM, Cyrille Pitchen
>> <cyrille.pitchen at atmel.com> wrote:
>>> Once the Quad SPI mode has been enabled on a Micron flash memory, this
>>> device expects ALL the following commands to use the SPI 4-4-4 protocol.
>>> The (Q)SPI controller needs to be notified about the protocol change so it
>>> can adapt and keep on dialoging with the Micron memory.
>>
>> Doesn't that mean you need to disable quad mode on removal? Else the
>> following will break/fail:
>>
>> insmod atmel-quadspi.ko ~> spi-nor attaches -> sees micron -> enables quad mode
>> rmmod atmel-quadspi.ko ~> spi-nor detaches
>> insmod atmel-quadspi.ko ~> spi-nor attaches -> fails to read the id
>> because flash is still in quad mode.
>>
>
> Indeed you're right such an issue does exist. So as you said one solution
> could be create a new function to "clean" what have been done by spi_nor_scan()
> then call it from remove() function of each driver calling spi_nor_scan() from
> its probe().
> However we could also enhance the probing of the memory. It is true that Micron
> spi nor memories only accept SPI 4-4-4 commands once switched in quad mode but
> actually they also provide a new command for this purpose:
> "Multiple I/O Read ID" (0xAF).
> Hence we could first try to probe using the regular Read ID (0x9F) command then
> change the protocol, for instance to SPI 4-4-4, and try the 0xAF command.
> I don't think all combinations for command/protocol need to be tested: for
> Micron memories, their datasheets claim the 0x9F command is only supported in
> "extended spi mode" so for the SPI 1-1-1 protocol whereas the 0xAF command
> only works in dual or quad modes.
> On the other hand Spansion memories still reply to the regular 0x9F command in
> SPI 1-1-1 protocol even after their quad mode had been enabled.
> For other manufacturers, well... I don't know!

At least from the two spansion datasheets I looked at, there is no 2_
or 4_ mode for spansion flashes, and the quad mode only enables the
1_x_4 commands, where as on micron the 1_x_4 commands are always
available, and you only need to switch to DIO or QIO if you want to
use 2_2_2 or 4_4_4.

The question is how to detect if the READID command failed. Hopefully
it will result in an invalid command, and we get 0xff... (or 0x00...)
for the the id. And from there on we can first test 4_4_4 MIORDID (so
it won't a a full command on a DIO-enabled flash), and if that fails,
2_2_2. We need to tell the spi-nor controller to send these
accordingly though. I wonder if it might not be better to pass the
c_a_d as an additional parameter to the read_reg/write_reg etc call
backs, because they might change depending on the command used. E.g.
when using SPI_NOR_QUAD, we might want to make use of the quad page
program command (which is 1_1_4), but there is no 1_1_2 version, so we
cannot rely on a global "protocol" member for that, unless we want to
do a set_protocol before every command.

>
> Some of the advantages of the probe solution as compared to the remove one are:
> - we don't need to patch all drivers using spi_nor_scan() to call a new
>   function from their remove().
> - it doesn't rely on the assumption that the spi-nor memory starts in
>   SPI 1-1-1 protocol. As a matter of fact the remove() won't be called for
>   built-in modules or in many (all ?) cases of reset. Moreover some bootloaders
>   may have already enabled the quad mode before starting the Linux kernel. This
>   is what the sama5d2 romcode does when it is configured to boot from a QSPI
>   memory.
>
> Anyway you're right and the issue need to be addressed but maybe in another
> dedicated patch ?

Yes, probably as a prerequisite to the quad mode on micron flashes. I
think we should also add a separate flag for the DIO/QIO modes for
micron flashes, as these are something separate from just the DOR/QOR
commands usually implied by SPI_NOR_DUAL/QUAD (well they are the same,
but work differently)

>>> Signed-off-by: Cyrille Pitchen <cyrille.pitchen at atmel.com>
>>> Acked-by: Marek Vasut <marex at denx.de>
>>> Acked-by: Bean Huo <beanhuo at micron.com>
>>> ---
>>>  drivers/mtd/spi-nor/spi-nor.c | 21 +++++++++++++++++++++
>>>  include/linux/mtd/spi-nor.h   | 13 +++++++++++++
>>>  2 files changed, 34 insertions(+)
>>>
>>> diff --git a/drivers/mtd/spi-nor/spi-nor.c b/drivers/mtd/spi-nor/spi-nor.c
>>> index c27d427fead4..c8810313a752 100644
>>> --- a/drivers/mtd/spi-nor/spi-nor.c
>>> +++ b/drivers/mtd/spi-nor/spi-nor.c
>>> @@ -165,6 +165,22 @@ static inline int write_disable(struct spi_nor *nor)
>>>         return nor->write_reg(nor, SPINOR_OP_WRDI, NULL, 0, 0);
>>>  }
>>>
>>> +/*
>>> + * Let the spi-nor framework notify lower layers, especially the driver of the
>>> + * (Q)SPI controller, about the new protocol to be used. Indeed, once the
>>> + * spi-nor framework has sent manufacturer specific commands to a memory to
>>> + * enable its Quad SPI mode, it should immediately after tell the QSPI
>>> + * controller to use the very same Quad SPI protocol as expected by the memory.
>>> + */
>>> +static inline int spi_nor_set_protocol(struct spi_nor *nor,
>>> +                                      enum spi_protocol proto)
>>> +{
>>> +       if (nor->set_protocol)
>>> +               return nor->set_protocol(nor, proto);
>>> +
>>> +       return 0;
>>
>> Shouldn't the default assumption be that it won't support it? Also it
>> might make sense to first check if it's supported before enabling it
>> in the chip, so that we don't enable something just to then find out
>> we can't back out of it.
>>
>> I also wonder if we need an extra flag for that as at least SPI has
>> RX_{DUAL,QUAD} and TX_{DUAL,QUAD} separated, so in theory there could
>> be a controller that supports quad read, but not quad write, so we
>> shouldn't be using the quad mode in that case. m25p80 currently sets
>> SPI_NOR_{DUAL,QUAD} only based on SPI_RX_{DUAL,QUAD}, so that would
>> then fail.
>>
>> At least the n25q32 seems to support the "boring" 1_1_2 and 1_1_4
>> commands, so these should work in case the spi controller does not
>> support quad tx, but quad rx.
>>
>> So maybe an additional flag for the "full" dual/quad modes would be in order.
>>
>
> My first thought was to return -ENOSYS when the set_protocol() callback is not
> implemented but logically none of the already existing drivers implements it.
> So I made this new callback optional. This way, micron_quad_enable() works the
> exact same way as before for all the existing drivers so no regression or side-
> effect should be introduced by this patch.

If they don't implement the callback, then they won't know that they
are supposed to use a different protocol, so change will definitely
have broken them. Therefore an error return value and or a dev_warn
would be IMHO better.

> So more accurate checks should be done before calling set_quad_mode(). Maybe
> the range of values for the mode parameter of spi_nor_scan() is too small.
> SPI_NOR_QUAD doesn't allow to make the difference between SPI protocols 1-1-4,
> 1-4-4 or 4-4-4. Knowing the exact set of protocols supported by both the
> controller and the memory could help making the right decision and choosing the
> best suited Fast Read command.
> The RX_{DUAL_QUAD} and TX_{DUAL,QUAD} flags from the spi->mode in the m25p80
> driver provide more information than the limited "mode" argument of
> spi_nor_scan().

so from the controller side we need to know whether it can do
RX_{DUAL,QUAD} and TX_{DUAL,QUAD}; but for the flash supported
commands we have a bit more variety (the x_y_z you mentioned).

Funny enough, once we are on QIO on spansion, there is no difference
anymore between FAST (0x0b), QOR (0x6b) and QIOR (0xeb), they all work
in the 4_4_4 mode.

>> Last but not least, the protocol probably should be stored somewhere
>> in the nor struct, so that users don't have to store it themselves (I
>> assume they will need to check it for each command again to know if
>> the cmd/address should be send in serial or quad mode).
>>
>>
> I agree with you, this could be an improvement for some spi controller drivers :)
>
>> Jonas
>>
>
> thanks for your review!
>
> Best regards,
>
> Cyrille


Regards
Jonas


From jonmason at broadcom.com  Mon Aug 31 12:44:04 2015
From: jonmason at broadcom.com (Jon Mason)
Date: Mon, 31 Aug 2015 15:44:04 -0400
Subject: [PATCH v3 2/5] ARM: NSP: add minimal Northstar Plus device tree
In-Reply-To: <55E3FFB5.6090703@broadcom.com>
References: <1440805644-18241-1-git-send-email-jonmason@broadcom.com>
 <55E0FAC4.2040108@broadcom.com>
 <20150831022417.GA27066@broadcom.com>
 <55E3FFB5.6090703@broadcom.com>
Message-ID: <20150831194404.GA28848@broadcom.com>

On Mon, Aug 31, 2015 at 12:18:13AM -0700, Ray Jui wrote:
> 
> 
> On 8/30/2015 7:24 PM, Jon Mason wrote:
> > On Fri, Aug 28, 2015 at 05:20:20PM -0700, Ray Jui wrote:
> >>
> >>
> >> On 8/28/2015 4:47 PM, Jon Mason wrote:
> >>> Add a very minimalistic set of Northstar Plus Device Tree files which
> >>> describes the SoC and the BCM958625 implementation.  The perpherials
> >>> described are:
> >>>
> >>> ARM Cortex A9 CPU
> >>> 2 8250 UARTs
> >>> ARM GIC
> >>> PL310 L2 Cache
> >>> ARM A9 Global timer
> >>>
> >>> Signed-off-by: Kapil Hali <kapilh at broadcom.com>
> >>> Signed-off-by: Jon Mason <jonmason at broadcom.com>
> >>> ---
> >>>  arch/arm/boot/dts/Makefile       |   2 +
> >>>  arch/arm/boot/dts/bcm-nsp.dtsi   | 120 +++++++++++++++++++++++++++++++++++++++
> >>>  arch/arm/boot/dts/bcm958625k.dts |  57 +++++++++++++++++++
> >>>  3 files changed, 179 insertions(+)
> >>>  create mode 100644 arch/arm/boot/dts/bcm-nsp.dtsi
> >>>  create mode 100644 arch/arm/boot/dts/bcm958625k.dts
> >>>
> >>> diff --git a/arch/arm/boot/dts/Makefile b/arch/arm/boot/dts/Makefile
> >>> index 246473a..adb5732 100644
> >>> --- a/arch/arm/boot/dts/Makefile
> >>> +++ b/arch/arm/boot/dts/Makefile
> >>> @@ -82,6 +82,8 @@ dtb-$(CONFIG_ARCH_BCM_CYGNUS) += \
> >>>  dtb-$(CONFIG_ARCH_BCM_MOBILE) += \
> >>>  	bcm28155-ap.dtb \
> >>>  	bcm21664-garnet.dtb
> >>> +dtb-$(CONFIG_ARCH_BCM_NSP) += \
> >>> +	bcm958625k.dtb
> >>>  dtb-$(CONFIG_ARCH_BERLIN) += \
> >>>  	berlin2-sony-nsz-gs7.dtb \
> >>>  	berlin2cd-google-chromecast.dtb \
> >>> diff --git a/arch/arm/boot/dts/bcm-nsp.dtsi b/arch/arm/boot/dts/bcm-nsp.dtsi
> >>> new file mode 100644
> >>> index 0000000..f5f494f
> >>> --- /dev/null
> >>> +++ b/arch/arm/boot/dts/bcm-nsp.dtsi
> >>> @@ -0,0 +1,120 @@
> >>> +/*
> >>> + *  BSD LICENSE
> >>> + *
> >>> + *  Copyright(c) 2015 Broadcom Corporation.  All rights reserved.
> >>> + *
> >>> + *  Redistribution and use in source and binary forms, with or without
> >>> + *  modification, are permitted provided that the following conditions
> >>> + *  are met:
> >>> + *
> >>> + *    * Redistributions of source code must retain the above copyright
> >>> + *      notice, this list of conditions and the following disclaimer.
> >>> + *    * Redistributions in binary form must reproduce the above copyright
> >>> + *      notice, this list of conditions and the following disclaimer in
> >>> + *      the documentation and/or other materials provided with the
> >>> + *      distribution.
> >>> + *    * Neither the name of Broadcom Corporation nor the names of its
> >>> + *      contributors may be used to endorse or promote products derived
> >>> + *      from this software without specific prior written permission.
> >>> + *
> >>> + *  THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
> >>> + *  "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
> >>> + *  LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
> >>> + *  A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
> >>> + *  OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
> >>> + *  SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
> >>> + *  LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
> >>> + *  DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
> >>> + *  THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
> >>> + *  (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
> >>> + *  OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
> >>> + */
> >>> +
> >>> +#include <dt-bindings/interrupt-controller/arm-gic.h>
> >>> +#include <dt-bindings/interrupt-controller/irq.h>
> >>> +
> >>> +#include "skeleton.dtsi"
> >>> +
> >>> +/ {
> >>> +	compatible = "brcm,nsp";
> >>> +	model = "Broadcom Northstar Plus SoC";
> >>> +	interrupt-parent = <&gic>;
> >>> +
> >>> +	mpcore {
> >>> +		compatible = "simple-bus";
> >>> +		ranges = <0x00000000 0x19020000 0x00003000>;
> >>> +		#address-cells = <1>;
> >>> +		#size-cells = <1>;
> >>> +
> >>> +		cpus {
> >>> +			#address-cells = <1>;
> >>> +			#size-cells = <0>;
> >>> +
> >>> +			cpu at 0 {
> >>> +				device_type = "cpu";
> >>> +				compatible = "arm,cortex-a9";
> >>> +				next-level-cache = <&L2>;
> >>> +				reg = <0x0>;
> >>> +			};
> >>> +		};
> >>> +
> >>> +		L2: l2-cache {
> >>> +			compatible = "arm,pl310-cache";
> >>> +			reg = <0x2000 0x1000>;
> >>> +			cache-unified;
> >>> +			cache-level = <2>;
> >>> +		};
> >>> +
> >>> +		gic: interrupt-controller at 19021000 {
> >>> +			compatible = "arm,cortex-a9-gic";
> >>> +			#interrupt-cells = <3>;
> >>> +			#address-cells = <0>;
> >>> +			interrupt-controller;
> >>> +			reg = <0x1000 0x1000>,
> >>> +			      <0x0100 0x100>;
> >>> +		};
> >>> +
> >>> +		timer at 19020200 {
> >>> +			compatible = "arm,cortex-a9-global-timer";
> >>> +			reg = <0x0200 0x100>;
> >>> +			interrupts = <GIC_PPI 11 IRQ_TYPE_LEVEL_HIGH>;
> >>> +			clocks = <&periph_clk>;
> >>> +		};
> >>> +	};
> >>> +
> >>> +	clocks {
> >>> +		#address-cells = <1>;
> >>> +		#size-cells = <1>;
> >>> +		ranges;
> >>> +
> >>> +		periph_clk: periph_clk {
> >>> +			compatible = "fixed-clock";
> >>> +			#clock-cells = <0>;
> >>> +			clock-frequency = <500000000>;
> >>> +		};
> >>> +	};
> >>> +
> >>> +	apb {
> >>> +		compatible = "arm,amba-bus", "simple-bus";
> >>
> >> Should "arm,amba-bus" has a separate bus node with AMBA compatible
> >> devices declared in there (e.g, pl330, spi-pl022, and etc.) in the
> >> future after they are brought up? To my best knowledge, "ns16550a" UART
> >> is NOT an AMBA compatible device.
> > 
> > APB is an AMBA bus, so this part is accurate.  The block diagram of
> > the SoC has the UARTs (and other perpherials) hanging off of the APB
> > bus.  So, this organization follows the block diagram.
> 
> Okay so the "apb" node can be used for amba compatible devices
> (arm,amba-bus) and/or simple platform devices (simple-bus). I guess
> that's fine and I now see that there are some other dtsi also doing it
> this way.
> 
> > While the
> > UART drivers are not AMBA aware, there appears to be no issues with
> > this layout (as the HW/drivers come up without issue). Unless there
> > is an unforeseen issue with having non-AMBA aware devices on the DT
> > AMBA bus, I would think it best to organize it to match the block
> > disgram.
> > 
> 
> UART runs fine because you also have "simple-bus" listed as the
> compatible string so uart is populated as standard platform device.
> 
> >>> +		interrupt-parent = <&gic>;
> >>> +		ranges = <0x00000000 0x18000000 0x00001000>;
> >>
> >> Does the 'apb' bus mean to cover all peripherals connected through APB?
> >> If so, the size is only 0x1000 and that seems to be too small...
> > 
> > This is all that is currently needed.  I was planning on expanding it
> > as I added more devices.
> 
> Sure.
> 
> I haven't checked the datahsheet but based on the layout (which seems
> quite similar to Cygnus), I assume the range for these devices should be
> 0x18000000 - 0x18ffffff? Just want to make sure there are no other
> devices come before 0x18000000 so you don't need to change all these reg
> offsets in the future.

Based on the devices listed in the block diagram (and not including
those on the AXI bus):
i2c 0x18038000
spi 0x18027200
gpio 0x18000060
pwm 0x18031000
wdt 0x18039000

and a few others.  

Looking at the sources, all the ARM IP is 0x19000000 and the rest is
0x18000000.  The only part that is a little harry is the clocks, which
have BCM and ARM (which causes the addresses to be both 0x19000000 and
0x18000000).  But, we can handle that when we upstream that part (which
should be very soon).

Thanks,
Jon

> > 
> > Thanks,
> > Jon
> > 
> 
> Thanks,
> 
> Ray


From alexandre.belloni at free-electrons.com  Mon Aug 31 13:09:44 2015
From: alexandre.belloni at free-electrons.com (Alexandre Belloni)
Date: Mon, 31 Aug 2015 22:09:44 +0200
Subject: [PATCH] rtc: Fix module autoload for rtc-{ab8500,max8997,s5m}
 drivers
In-Reply-To: <1440671672-26590-1-git-send-email-javier@osg.samsung.com>
References: <1440671672-26590-1-git-send-email-javier@osg.samsung.com>
Message-ID: <20150831200944.GA3409@piout.net>

On 27/08/2015 at 12:34:32 +0200, Javier Martinez Canillas wrote :
> These platform drivers have a platform device ID table but the module
> alias information is not created so module autoloading will not work.
> 
> Signed-off-by: Javier Martinez Canillas <javier at osg.samsung.com>
> 
> ---
> 
>  drivers/rtc/rtc-ab8500.c  | 1 +
>  drivers/rtc/rtc-max8997.c | 1 +
>  drivers/rtc/rtc-s5m.c     | 1 +
>  3 files changed, 3 insertions(+)
Applied, thanks.

-- 
Alexandre Belloni, Free Electrons
Embedded Linux, Kernel and Android engineering
http://free-electrons.com


From alexandre.belloni at free-electrons.com  Mon Aug 31 13:15:23 2015
From: alexandre.belloni at free-electrons.com (Alexandre Belloni)
Date: Mon, 31 Aug 2015 22:15:23 +0200
Subject: [PATCH] rtc: Fix module autoload for OF platform drivers
In-Reply-To: <1440676322-19870-1-git-send-email-javier@osg.samsung.com>
References: <1440676322-19870-1-git-send-email-javier@osg.samsung.com>
Message-ID: <20150831201523.GB3409@piout.net>

On 27/08/2015 at 13:52:02 +0200, Javier Martinez Canillas wrote :
> These platform drivers have a OF device ID table but the OF module
> alias information is not created so module autoloading won't work.
> 
> Signed-off-by: Javier Martinez Canillas <javier at osg.samsung.com>
> 
> ---
> 
>  drivers/rtc/rtc-armada38x.c | 1 +
>  drivers/rtc/rtc-coh901331.c | 1 +
>  drivers/rtc/rtc-da9063.c    | 1 +
>  drivers/rtc/rtc-moxart.c    | 1 +
>  drivers/rtc/rtc-mpc5121.c   | 1 +
>  drivers/rtc/rtc-mt6397.c    | 1 +
>  drivers/rtc/rtc-mv.c        | 1 +
>  drivers/rtc/rtc-vt8500.c    | 1 +
>  8 files changed, 8 insertions(+)
> 
Applied, thanks.

-- 
Alexandre Belloni, Free Electrons
Embedded Linux, Kernel and Android engineering
http://free-electrons.com


From lho at apm.com  Mon Aug 31 14:26:11 2015
From: lho at apm.com (Loc Ho)
Date: Mon, 31 Aug 2015 14:26:11 -0700
Subject: [PATCH v4 0/4] edac: Add L3/SoC support to the APM X-Gene SoC
 EDAC driver
In-Reply-To: <1439534769-22811-1-git-send-email-lho@apm.com>
References: <1439534769-22811-1-git-send-email-lho@apm.com>
Message-ID: <CAPw-ZTm_n6o2jXc5LuSZLrdZy3ZCmJmrRAP6S+7S-EO2ZAGANg@mail.gmail.com>

Hi Borislav,

Are you okay with this version to pull in for 4.3 release?

-Loc

On Thu, Aug 13, 2015 at 11:46 PM, Loc Ho <lho at apm.com> wrote:
> v4:
> * Remove function for EDAC debugfs node and replace with export variable
> * Switch the driver to use the exported edac_debugfs variable
> * Revert the if statement logic for function as necessary
> * Remove un-necessary code in debugfs creation functions
>
> v3:
> * Add an function to retrieve the EDAC debugfs node
> * Move all debugfs node under EDAC code debugfs node
> * Update L3 to check for v1 errata
> * Rename error label for L3/SoC add routines
> * Re-structure SoC EDAC functions for code readability
> * Inline the function xgene_edac_soc_mem_data
> * Remove un-necessary { }
>
> v2:
> * Update binding documentation accordingly
> * Change all single bit defines to BIT(x)
> * Add support for L3 version 1 and 2 HW's
> * Change to use debug file system for error injection
> * In L3/SoC instance add function, allocate EDAC context after all
>   initalization successed
> * Support raw or detail info for SoC EDAC error reporting
>
> v1:
> * Add L3/SoC support to the APM X-Gene SoC EDAC driver
> ---
> Loc Ho (4):
>   edac: Export edac_debugfs
>   Documentation: Update the APM X-Gene SoC EDAC DTS binding for L3/SoC
>     subnodes
>   edac: Add L3/SoC EDAC support to the APM X-Gene SoC EDAC driver
>   arm64: Add L3/SoC DT subnodes to the APM X-Gene SoC EDAC node
>
>  .../devicetree/bindings/edac/apm-xgene-edac.txt    |   23 +
>  arch/arm64/boot/dts/apm/apm-storm.dtsi             |   10 +
>  drivers/edac/edac_core.h                           |    1 +
>  drivers/edac/edac_mc_sysfs.c                       |    5 +-
>  drivers/edac/xgene_edac.c                          | 1169 ++++++++++++++++----
>  5 files changed, 1012 insertions(+), 196 deletions(-)
>


From anders.roxell at linaro.org  Mon Aug 31 14:28:44 2015
From: anders.roxell at linaro.org (Anders Roxell)
Date: Mon, 31 Aug 2015 23:28:44 +0200
Subject: [PATCH] drivers: i2c: exynos5: irq spinlock rt-safe
In-Reply-To: <alpine.DEB.2.11.1508252349070.15006@nanos>
References: <1440489125-20082-1-git-send-email-anders.roxell@linaro.org>
 <alpine.DEB.2.11.1508252349070.15006@nanos>
Message-ID: <20150831212844.GI13774@localhost.localdomain>

On 2015-08-25 23:51, Thomas Gleixner wrote:
> On Tue, 25 Aug 2015, Anders Roxell wrote:
> 
> > The exynos5_i2c_message_start enables interrupts while holding the i2c
> > lock which is sought by the irq handler. If an IRQ is received before
> > this lock is released then a deadlock occurs.
> 
> That's crap. The interrupt handler runs in an irq thread as RT forces
> all normal interrupts to that.

You are right, I will send a v2 with a better changelog.

Cheers,
Anders


From sonnyrao at chromium.org  Mon Aug 31 14:40:10 2015
From: sonnyrao at chromium.org (Sonny Rao)
Date: Mon, 31 Aug 2015 14:40:10 -0700
Subject: [PATCH v2 0/5] Fix broken DMAFLUSHP on Rockchips platform
In-Reply-To: <1440722176-31588-1-git-send-email-shawn.lin@rock-chips.com>
References: <1440722176-31588-1-git-send-email-shawn.lin@rock-chips.com>
Message-ID: <CAPz6YkXmGkQsB4WbQ5VbBAPRCTQFYCUR=Nf6G+syhbXSPA2DeQ@mail.gmail.com>

On Thu, Aug 27, 2015 at 5:36 PM, Shawn Lin <shawn.lin at rock-chips.com> wrote:
>
> The purpose of the DMAFLUSHP instruction:
> - Tell the peripheral to clear its status and control registers.
> - Send a message to the peripheral to resend its level status.
>
> There are 3 timings described in PL330 Technical Reference Manual:
> - Timing 1: Burst request, can work well without DMAFLUSHP.
> - Timing 2: Single and burst request, DMAC will ignore the single
>             transfer request. This timing happens if there are single
>             and burst request.
> - Timing 3: Single transfers for a burst request, DMAC should signals
>             datype to request the peripheral to flush the contents of
>             any control registers. This timing happens if there is
>             not enough MFIFO to places the burst data.
>
> A peripheral may signal a DMA request during the execution of
> DMAFLUSHP instruction, that cause DMA request being ignored by DMAC.
>
> But DMAC and all peripherals on RK3X SoCs DO NOT support DMAFLUSHP.
> It can't send a message to the peripheral to resend DMA request,
> and the peripheral can't acknowledge a flush request from DMAC.
> So all DMA requests should NOT be ignored by DMAC, and DMAC will not
> notify the peripheral to flush.
>
> To fix this problem, we need:
> - Do NOT execute DMAFLUSHP instruction.
> - Timing 2 and timing 3 should not happen.
>
> Because on RK3X SoCs, there are 6 or below  channels and 32 MFIFO depth
> for DMAC_BUS, and 8 channels and 64 MFIFO depth for DMAC_PERI, it is
> impossible to hit the timing 3 if burst length is equal or less than 4.

Fixing this issue also requires changes to drivers, so it would be
nice if you put those changes into the same patchset.
Otherwise someone may apply this series and expect things to work but
they will still be broken. Specifically the peripherals should be
setting their burst sizes for their DMA requests low enough to avoid
needing the working DMAFLUSHP instruction.

Also, I remember we ran into an issue when we tried using burst length
of 4 with the i2s device on RK3288 because we could get requests that
either weren't aligned or a multiple of 4 sizes and some transfers
would just fail, so we ended up using a burst size of 1.  I recommend
if we aren't sure about size or alignment for a particular peripheral,
a burst size of 1 is safest.  For something like a block device, I
think we can use the larger size bursts.  That's another reason to
include the driver fixes in the series, just so we get it right,
thanks.

>
> Since the request type signal by the peripheral can only be set by
> software. We can set Rockchip Soc's GRF_PERIDMAC_CON0[2:1] to select single
> or burst request, if it is set b01,  all of the peripharals will signal a brust
> request. So the timing 2 will not happen, too.
>
> So DMAC on RK3X can support single or burst transfer, but can't support
> mixed transfer.
>
> Because burst transfer is more efficient than single transfer, this is
> confirmed by our ASIC team, who strongly suggest to use burst transfer.
> And this is confirmed by Addy's test on RK3288-Pink2 board, the speed of
> spi flash burst transfer will increase about two times than single transfer.
> Also, I have tested dw_mmc with pl330 on RK3188 platform to double confirm
> the result. That means burst transfer is reansonable.
>
> So we need a quirk not to execute DMAFLUSHP instruction and to use burst
> transfer.
>
> Note:
> - The Rockchip Soc default value of GRF_PERIDMAC_CON0[2:1] is b01. To
>   support brust transfer, these bits should not be changed in bootloader.
>
>
> Changes in v2:
> - amend the author
> - reorder the patches suggested by Doug
> - add Reviewed-by: Doug Anderson <dianders at chromium.org> for
>   rk3288.dtsi patch and arm-pl330.txt patch
> - amend Olof's mail address
>
> Changes in v1:
> - rename broken-no-flushp to "arm,pl330-broken-no-flushp" suggested
>   by Krzysztof.
> - add From original author.
> - remove Sunny's tag
>
> Addy Ke (2):
>   DMA: pl330: add quirk for broken no flushp
>   ARM: dts: Add arm,pl330-broken-no-flushp quirk for rk3288 platform
>
> Boojin Kim (1):
>   DMA: pl330: support burst mode for dev-to-mem and mem-to-dev transmit
>
> Shawn Lin (2):
>   Documentation: arm-pl330: add description of
>     arm,pl330-broken-no-flushp
>   ARM: dts: Add arm,pl330-broken-no-flushp quirk for rk3xxx platform
>
>  .../devicetree/bindings/dma/arm-pl330.txt          |   1 +
>  arch/arm/boot/dts/rk3288.dtsi                      |   3 +
>  arch/arm/boot/dts/rk3xxx.dtsi                      |   3 +
>  drivers/dma/pl330.c                                | 101 +++++++++++++++------
>  4 files changed, 79 insertions(+), 29 deletions(-)
>
> --
> 2.3.7
>
>
> --
> To unsubscribe from this list: send the line "unsubscribe linux-kernel" in
> the body of a message to majordomo at vger.kernel.org
> More majordomo info at  http://vger.kernel.org/majordomo-info.html
> Please read the FAQ at  http://www.tux.org/lkml/


From robherring2 at gmail.com  Mon Aug 31 14:49:10 2015
From: robherring2 at gmail.com (Rob Herring)
Date: Mon, 31 Aug 2015 16:49:10 -0500
Subject: [PATCH v3 2/5] ARM: NSP: add minimal Northstar Plus device tree
In-Reply-To: <20150831194404.GA28848@broadcom.com>
References: <1440805644-18241-1-git-send-email-jonmason@broadcom.com>
 <55E0FAC4.2040108@broadcom.com> <20150831022417.GA27066@broadcom.com>
 <55E3FFB5.6090703@broadcom.com> <20150831194404.GA28848@broadcom.com>
Message-ID: <CAL_JsqL1=WoaidMgLN4exvhF7bYr4FNGmtMgYO8e-c=NxP3JbQ@mail.gmail.com>

On Mon, Aug 31, 2015 at 2:44 PM, Jon Mason <jonmason at broadcom.com> wrote:
> On Mon, Aug 31, 2015 at 12:18:13AM -0700, Ray Jui wrote:
>>
>>
>> On 8/30/2015 7:24 PM, Jon Mason wrote:
>> > On Fri, Aug 28, 2015 at 05:20:20PM -0700, Ray Jui wrote:
>> >>
>> >>
>> >> On 8/28/2015 4:47 PM, Jon Mason wrote:
>> >>> Add a very minimalistic set of Northstar Plus Device Tree files which
>> >>> describes the SoC and the BCM958625 implementation.  The perpherials
>> >>> described are:
>> >>>
>> >>> ARM Cortex A9 CPU
>> >>> 2 8250 UARTs
>> >>> ARM GIC
>> >>> PL310 L2 Cache
>> >>> ARM A9 Global timer

[...]

>> >>> + apb {
>> >>> +         compatible = "arm,amba-bus", "simple-bus";
>> >>
>> >> Should "arm,amba-bus" has a separate bus node with AMBA compatible
>> >> devices declared in there (e.g, pl330, spi-pl022, and etc.) in the
>> >> future after they are brought up? To my best knowledge, "ns16550a" UART
>> >> is NOT an AMBA compatible device.

IIRC, "arm,amba-bus" is not documented nor used. It isn't really
needed as there is no s/w visible feature to an AMBA bus. There are
also multiple flavors of AMBA buses, so it is pretty meaningless.

>> > APB is an AMBA bus, so this part is accurate.  The block diagram of
>> > the SoC has the UARTs (and other perpherials) hanging off of the APB
>> > bus.  So, this organization follows the block diagram.
>>
>> Okay so the "apb" node can be used for amba compatible devices
>> (arm,amba-bus) and/or simple platform devices (simple-bus). I guess
>> that's fine and I now see that there are some other dtsi also doing it
>> this way.

I think what is meant here by "amba compatible devices" is really ARM
Primecell peripherals which are the ARM IP with standard ID registers.
These are designated by "arm,primecell" compatible strings for the
device not the bus compatible string.

>>
>> > While the
>> > UART drivers are not AMBA aware, there appears to be no issues with
>> > this layout (as the HW/drivers come up without issue). Unless there
>> > is an unforeseen issue with having non-AMBA aware devices on the DT
>> > AMBA bus, I would think it best to organize it to match the block
>> > disgram.
>> >
>>
>> UART runs fine because you also have "simple-bus" listed as the
>> compatible string so uart is populated as standard platform device.
>>
>> >>> +         interrupt-parent = <&gic>;
>> >>> +         ranges = <0x00000000 0x18000000 0x00001000>;
>> >>
>> >> Does the 'apb' bus mean to cover all peripherals connected through APB?
>> >> If so, the size is only 0x1000 and that seems to be too small...
>> >
>> > This is all that is currently needed.  I was planning on expanding it
>> > as I added more devices.
>>
>> Sure.
>>
>> I haven't checked the datahsheet but based on the layout (which seems
>> quite similar to Cygnus), I assume the range for these devices should be
>> 0x18000000 - 0x18ffffff? Just want to make sure there are no other
>> devices come before 0x18000000 so you don't need to change all these reg
>> offsets in the future.
>
> Based on the devices listed in the block diagram (and not including
> those on the AXI bus):
> i2c 0x18038000
> spi 0x18027200
> gpio 0x18000060
> pwm 0x18031000
> wdt 0x18039000
>
> and a few others.
>
> Looking at the sources, all the ARM IP is 0x19000000 and the rest is
> 0x18000000.  The only part that is a little harry is the clocks, which
> have BCM and ARM (which causes the addresses to be both 0x19000000 and
> 0x18000000).  But, we can handle that when we upstream that part (which
> should be very soon).

If you can tell that 0x19000000 is a separate bus at some level, then
it makes sense to separate it. You can't always tell without detailed
internal bus diagrams.

Rob


From sonnyrao at chromium.org  Mon Aug 31 14:53:18 2015
From: sonnyrao at chromium.org (Sonny Rao)
Date: Mon, 31 Aug 2015 14:53:18 -0700
Subject: [PATCH v2 2/5] DMA: pl330: add quirk for broken no flushp
In-Reply-To: <1440722280-31678-1-git-send-email-shawn.lin@rock-chips.com>
References: <1440722176-31588-1-git-send-email-shawn.lin@rock-chips.com>
 <1440722280-31678-1-git-send-email-shawn.lin@rock-chips.com>
Message-ID: <CAPz6YkWeBsp2_9VD+0RpcGFC7FvdcY1kyYONBMV0yunR3orKyQ@mail.gmail.com>

On Thu, Aug 27, 2015 at 5:38 PM, Shawn Lin <shawn.lin at rock-chips.com> wrote:
> From: Addy Ke <addy.ke at rock-chips.com>
>
> This patch add "arm,pl330-broken-no-flushp" quirk to avoid execute
> DMAFLUSHP if Soc doesn't support it.
>
> Signed-off-by: Addy Ke <addy.ke at rock-chips.com>
> Signed-off-by: Shawn Lin <shawn.lin at rock-chips.com>
> cc: Doug Anderson <dianders at chromium.org>
> cc: Heiko Stuebner <heiko at sntech.de>
> cc: Olof Johansson <olof at lixom.net>
>
> ---
>
> Changes in v2:
> - amend the author
> - amend Olof's mail address
>
> Changes in v1:
> - rename broken-no-flushp to "arm,pl330-broken-no-flushp" suggested
>   by Krzysztof.
> - remove Sunny's tag
>
>  drivers/dma/pl330.c | 87 ++++++++++++++++++++++++++++++++++++++---------------
>  1 file changed, 62 insertions(+), 25 deletions(-)
>
> diff --git a/drivers/dma/pl330.c b/drivers/dma/pl330.c
> index 0d544d2..3b9b426 100644
> --- a/drivers/dma/pl330.c
> +++ b/drivers/dma/pl330.c
> @@ -34,6 +34,8 @@
>  #define PL330_MAX_IRQS         32
>  #define PL330_MAX_PERI         32
>
> +#define PL330_QUIRK_BROKEN_NO_FLUSHP BIT(0)
> +
>  enum pl330_cachectrl {
>         CCTRL0,         /* Noncacheable and nonbufferable */
>         CCTRL1,         /* Bufferable only */
> @@ -488,6 +490,17 @@ struct pl330_dmac {
>         /* Peripheral channels connected to this DMAC */
>         unsigned int num_peripherals;
>         struct dma_pl330_chan *peripherals; /* keep at end */
> +       int quirks;
> +};
> +
> +static struct pl330_of_quirks {
> +       char *quirk;
> +       int id;
> +} of_quirks[] = {
> +       {
> +               .quirk = "arm,pl330-broken-no-flushp",
> +               .id = PL330_QUIRK_BROKEN_NO_FLUSHP,
> +       }
>  };
>
>  struct dma_pl330_desc {
> @@ -1137,53 +1150,68 @@ static inline int _ldst_memtomem(unsigned dry_run, u8 buf[],
>         return off;
>  }
>
> -static inline int _ldst_devtomem(unsigned dry_run, u8 buf[],
> -               const struct _xfer_spec *pxs, int cyc)
> +static inline int _ldst_devtomem(struct pl330_dmac *pl330, unsigned dry_run,
> +                                u8 buf[], const struct _xfer_spec *pxs,
> +                                int cyc)
>  {
>         int off = 0;
>         enum pl330_cond cond;
>
> -       cond = (pxs->desc->rqcfg.brst_len == 1) ? SINGLE : BURST;
> +       if (pl330->quirks & PL330_QUIRK_BROKEN_NO_FLUSHP)
> +               cond = BURST;
> +       else
> +               cond = (pxs->desc->rqcfg.brst_len == 1) ? SINGLE : BURST;
>
>         while (cyc--) {
>                 off += _emit_WFP(dry_run, &buf[off], cond, pxs->desc->peri);
>                 off += _emit_LDP(dry_run, &buf[off], cond, pxs->desc->peri);
>                 off += _emit_ST(dry_run, &buf[off], ALWAYS);
> -               off += _emit_FLUSHP(dry_run, &buf[off], pxs->desc->peri);
> +
> +               if (!(pl330->quirks & PL330_QUIRK_BROKEN_NO_FLUSHP))
> +                       off += _emit_FLUSHP(dry_run, &buf[off],
> +                                           pxs->desc->peri);
>         }
>
>         return off;
>  }
>
> -static inline int _ldst_memtodev(unsigned dry_run, u8 buf[],
> -               const struct _xfer_spec *pxs, int cyc)
> +static inline int _ldst_memtodev(struct pl330_dmac *pl330,
> +                                unsigned dry_run, u8 buf[],
> +                                const struct _xfer_spec *pxs, int cyc)
>  {
>         int off = 0;
>         enum pl330_cond cond;
>
> -       cond = (pxs->desc->rqcfg.brst_len == 1) ? SINGLE : BURST;
> +       if (pl330->quirks & PL330_QUIRK_BROKEN_NO_FLUSHP)
> +               cond = BURST;
> +       else
> +               cond = (pxs->desc->rqcfg.brst_len == 1) ? SINGLE : BURST;
> +
>
>         while (cyc--) {
>                 off += _emit_WFP(dry_run, &buf[off], cond, pxs->desc->peri);
>                 off += _emit_LD(dry_run, &buf[off], ALWAYS);
>                 off += _emit_STP(dry_run, &buf[off], cond, pxs->desc->peri);
> -               off += _emit_FLUSHP(dry_run, &buf[off], pxs->desc->peri);
> +
> +               if (!(pl330->quirks & PL330_QUIRK_BROKEN_NO_FLUSHP))
> +                       off += _emit_FLUSHP(dry_run, &buf[off],
> +                                           pxs->desc->peri);
>         }
>
>         return off;
>  }
>
> -static int _bursts(unsigned dry_run, u8 buf[],
> +static int _bursts(struct pl330_dmac *pl330, unsigned dry_run, u8 buf[],
>                 const struct _xfer_spec *pxs, int cyc)
>  {
>         int off = 0;
>
>         switch (pxs->desc->rqtype) {
>         case DMA_MEM_TO_DEV:
> -               off += _ldst_memtodev(dry_run, &buf[off], pxs, cyc);
> +               off += _ldst_memtodev(pl330, dry_run, &buf[off], pxs, cyc);
>                 break;
>         case DMA_DEV_TO_MEM:
> -               off += _ldst_devtomem(dry_run, &buf[off], pxs, cyc);
> +               off += _ldst_devtomem(pl330, dry_run, &buf[off], pxs, cyc);
>                 break;
>         case DMA_MEM_TO_MEM:
>                 off += _ldst_memtomem(dry_run, &buf[off], pxs, cyc);
> @@ -1197,7 +1225,7 @@ static int _bursts(unsigned dry_run, u8 buf[],
>  }
>
>  /* Returns bytes consumed and updates bursts */
> -static inline int _loop(unsigned dry_run, u8 buf[],
> +static inline int _loop(struct pl330_dmac *pl330, unsigned dry_run, u8 buf[],
>                 unsigned long *bursts, const struct _xfer_spec *pxs)
>  {
>         int cyc, cycmax, szlp, szlpend, szbrst, off;
> @@ -1220,7 +1248,7 @@ static inline int _loop(unsigned dry_run, u8 buf[],
>         }
>
>         szlp = _emit_LP(1, buf, 0, 0);
> -       szbrst = _bursts(1, buf, pxs, 1);
> +       szbrst = _bursts(pl330, 1, buf, pxs, 1);
>
>         lpend.cond = ALWAYS;
>         lpend.forever = false;
> @@ -1252,7 +1280,7 @@ static inline int _loop(unsigned dry_run, u8 buf[],
>         off += _emit_LP(dry_run, &buf[off], 1, lcnt1);
>         ljmp1 = off;
>
> -       off += _bursts(dry_run, &buf[off], pxs, cyc);
> +       off += _bursts(pl330, dry_run, &buf[off], pxs, cyc);
>
>         lpend.cond = ALWAYS;
>         lpend.forever = false;
> @@ -1275,8 +1303,9 @@ static inline int _loop(unsigned dry_run, u8 buf[],
>         return off;
>  }
>
> -static inline int _setup_loops(unsigned dry_run, u8 buf[],
> -               const struct _xfer_spec *pxs)
> +static inline int _setup_loops(struct pl330_dmac *pl330,
> +                              unsigned dry_run, u8 buf[],
> +                              const struct _xfer_spec *pxs)
>  {
>         struct pl330_xfer *x = &pxs->desc->px;
>         u32 ccr = pxs->ccr;
> @@ -1285,15 +1314,16 @@ static inline int _setup_loops(unsigned dry_run, u8 buf[],
>
>         while (bursts) {
>                 c = bursts;
> -               off += _loop(dry_run, &buf[off], &c, pxs);
> +               off += _loop(pl330, dry_run, &buf[off], &c, pxs);
>                 bursts -= c;
>         }
>
>         return off;
>  }
>
> -static inline int _setup_xfer(unsigned dry_run, u8 buf[],
> -               const struct _xfer_spec *pxs)
> +static inline int _setup_xfer(struct pl330_dmac *pl330,
> +                             unsigned dry_run, u8 buf[],
> +                             const struct _xfer_spec *pxs)
>  {
>         struct pl330_xfer *x = &pxs->desc->px;
>         int off = 0;
> @@ -1304,7 +1334,7 @@ static inline int _setup_xfer(unsigned dry_run, u8 buf[],
>         off += _emit_MOV(dry_run, &buf[off], DAR, x->dst_addr);
>
>         /* Setup Loop(s) */
> -       off += _setup_loops(dry_run, &buf[off], pxs);
> +       off += _setup_loops(pl330, dry_run, &buf[off], pxs);
>
>         return off;
>  }
> @@ -1313,8 +1343,9 @@ static inline int _setup_xfer(unsigned dry_run, u8 buf[],
>   * A req is a sequence of one or more xfer units.
>   * Returns the number of bytes taken to setup the MC for the req.
>   */
> -static int _setup_req(unsigned dry_run, struct pl330_thread *thrd,
> -               unsigned index, struct _xfer_spec *pxs)
> +static int _setup_req(struct pl330_dmac *pl330, unsigned dry_run,
> +                     struct pl330_thread *thrd, unsigned index,
> +                     struct _xfer_spec *pxs)
>  {
>         struct _pl330_req *req = &thrd->req[index];
>         struct pl330_xfer *x;
> @@ -1331,7 +1362,7 @@ static int _setup_req(unsigned dry_run, struct pl330_thread *thrd,
>         if (x->bytes % (BRST_SIZE(pxs->ccr) * BRST_LEN(pxs->ccr)))
>                 return -EINVAL;
>
> -       off += _setup_xfer(dry_run, &buf[off], pxs);
> +       off += _setup_xfer(pl330, dry_run, &buf[off], pxs);
>
>         /* DMASEV peripheral/event */
>         off += _emit_SEV(dry_run, &buf[off], thrd->ev);
> @@ -1425,7 +1456,7 @@ static int pl330_submit_req(struct pl330_thread *thrd,
>         xs.desc = desc;
>
>         /* First dry run to check if req is acceptable */
> -       ret = _setup_req(1, thrd, idx, &xs);
> +       ret = _setup_req(pl330, 1, thrd, idx, &xs);
>         if (ret < 0)
>                 goto xfer_exit;
>
> @@ -1439,7 +1470,7 @@ static int pl330_submit_req(struct pl330_thread *thrd,
>         /* Hook the request */
>         thrd->lstenq = idx;
>         thrd->req[idx].desc = desc;
> -       _setup_req(0, thrd, idx, &xs);
> +       _setup_req(pl330, 0, thrd, idx, &xs);
>
>         ret = 0;
>
> @@ -2784,6 +2815,7 @@ pl330_probe(struct amba_device *adev, const struct amba_id *id)
>         struct resource *res;
>         int i, ret, irq;
>         int num_chan;
> +       struct device_node *np = adev->dev.of_node;
>
>         pdat = dev_get_platdata(&adev->dev);
>
> @@ -2803,6 +2835,11 @@ pl330_probe(struct amba_device *adev, const struct amba_id *id)
>
>         pl330->mcbufsz = pdat ? pdat->mcbuf_sz : 0;
>
> +       /* get quirk */
> +       for (i = 0; i < ARRAY_SIZE(of_quirks); i++)
> +               if (of_property_read_bool(np, of_quirks[i].quirk))
> +                       pl330->quirks |= of_quirks[i].id;
> +
>         res = &adev->res;
>         pl330->base = devm_ioremap_resource(&adev->dev, res);
>         if (IS_ERR(pl330->base))
> --
> 2.3.7
>

Reviewed-by: Sonny Rao <sonnyrao at chromium.org>


>
>
> _______________________________________________
> Linux-rockchip mailing list
> Linux-rockchip at lists.infradead.org
> http://lists.infradead.org/mailman/listinfo/linux-rockchip


From khilman at kernel.org  Mon Aug 31 15:11:26 2015
From: khilman at kernel.org (Kevin Hilman)
Date: Mon, 31 Aug 2015 15:11:26 -0700
Subject: [PATCH] ARM: EXYNOS: reset KFC cores when cpu is up
In-Reply-To: <1441031111-6549-1-git-send-email-parkch98@gmail.com> (Chanho
 Park's message of "Mon, 31 Aug 2015 23:25:11 +0900")
References: <1441031111-6549-1-git-send-email-parkch98@gmail.com>
Message-ID: <7hmvx785wx.fsf@deeprootsystems.com>

Chanho Park <parkch98 at gmail.com> writes:

> The cpu booting of exynos5422 has been still broken since we discussed
> it in last year[1]. This patch is inspired from odroid xu3
> code(Actually, it was from samsung exynos vendor kernel)[2]. This weird
> reset code was founded exynos5420 octa cores series SoCs and only
> required for the first boot core is the little core(kingfisher core).
> Some of the exynos5420 boards and all of the exynos5422 boards will be
> required this code.
> There is two ways to check the little core is the first cpu. One is
> checking GPG2CON[1] gpio value and the other is checking the cluster
> number of the first cpu. I selected the latter because it's more easier
> than the former.
>
> Changes since RFC[3]:
> - drop checking soc_is_exynos5800 to extend this codes to
> exynos5420/5422 boards.
> - kfc cores will be reset only if the cpu0 is kfc core.
> - Rebase top of the kukjin's for-next branch
>
> [1]:http://lists.infradead.org/pipermail/linux-arm-kernel/2015-June/350632.html
> [2]:https://patchwork.kernel.org/patch/6782891/
> [3]:http://lists.infradead.org/pipermail/linux-arm-kernel/2015-July/356610.html
>
> Cc: Joonyoung Shim <jy0922.shim at samsung.com>
> Cc: Chanwoo Choi <cw00.choi at samsung.com>
> Cc: Kevin Hilman <khilman at kernel.org>
> Cc: Heesub Shin <heesub.shin at samsung.com>
> Cc: Mauro Ribeiro <mauro.ribeiro at hardkernel.com>
> Cc: Abhilash Kesavan <a.kesavan at samsung.com>
> Cc: Przemyslaw Marczak <p.marczak at samsung.com>
> Cc: Marek Szyprowski <m.szyprowski at samsung.com>
> Cc: Krzysztof Kozlowski <k.kozlowski at samsung.com>
> Signed-off-by: Chanho Park <parkch98 at gmail.com>

> ---
>  arch/arm/mach-exynos/mcpm-exynos.c | 18 +++++++++++++++++-
>  arch/arm/mach-exynos/regs-pmu.h    |  6 ++++++
>  2 files changed, 23 insertions(+), 1 deletion(-)
>
> diff --git a/arch/arm/mach-exynos/mcpm-exynos.c b/arch/arm/mach-exynos/mcpm-exynos.c
> index 9bdf547..5b69ed2 100644
> --- a/arch/arm/mach-exynos/mcpm-exynos.c
> +++ b/arch/arm/mach-exynos/mcpm-exynos.c
> @@ -20,6 +20,7 @@
>  #include <asm/cputype.h>
>  #include <asm/cp15.h>
>  #include <asm/mcpm.h>
> +#include <asm/smp_plat.h>
>  
>  #include "regs-pmu.h"
>  #include "common.h"
> @@ -70,7 +71,22 @@ static int exynos_cpu_powerup(unsigned int cpu, unsigned int cluster)
>  		cluster >= EXYNOS5420_NR_CLUSTERS)
>  		return -EINVAL;
>  
> -	exynos_cpu_power_up(cpunr);
> +	if (!exynos_cpu_power_state(cpunr)) {
> +		exynos_cpu_power_up(cpunr);
> +
> +		/* This assumes the cluster number of the eagle is 0 and the
> +		 * kfc is 1. When the system was booted from the kfc core,
> +		 * they should be reset */

minor: fix multi-line comment style (search for 'multi-line' in
Documentation/CodingStyle)

Also minor, but personally, I prefer seeing A15/A7 instead of eagle/KFC
as those names are fading from my memory and I can't seem to remember
which one is which. :/

> +		if (cluster &&
> +		    cluster == MPIDR_AFFINITY_LEVEL(cpu_logical_map(0), 1)) {
> +			while (!pmu_raw_readl(S5P_PMU_SPARE2))
> +				udelay(10);
> +
> +			pmu_raw_writel(EXYNOS5420_KFC_CORE_RESET(cpu),
> +					EXYNOS_SWRESET);
> +		}
> +	}
> +
>  	return 0;
>  }

I tested this on top of mainline (v4.2) using exynos_defconfig (with
BL_SWITCHER disabled) and I now see all 8 CPUs booting.  Nice!

Tested-by: Kevin Hilman <khilman at linaro.org>

Also, please note that this does not fix another fundamental problem
with this board in that the firmware puts CCI into secure mode, so
linux/MCPM cannot manage it, causing hangs whenever CPUidle is enabled
(because b.L cpuidle driver tries to use MCPM, which needs to manage
CCI.)

In order for this to not hang when using CPUidle, the following patch is
also needed.

Kevin

diff --git a/arch/arm/boot/dts/exynos5422-odroidxu3.dts
b/arch/arm/boot/dts/exynos5422-odroidxu3.dts
index 78e6a502f320..7891bd05bf8e 100644
--- a/arch/arm/boot/dts/exynos5422-odroidxu3.dts
+++ b/arch/arm/boot/dts/exynos5422-odroidxu3.dts
@@ -49,3 +49,11 @@
                shunt-resistor = <10000>;
        };
 };
+
+/*
+ * Secure firmware prevents CCI access/usage from linux, so must be
disabled
+ * to prevent usage by MCPM.
+ */
+&cci {
+       status = "disabled";
+};




From sonnyrao at chromium.org  Mon Aug 31 15:22:59 2015
From: sonnyrao at chromium.org (Sonny Rao)
Date: Mon, 31 Aug 2015 15:22:59 -0700
Subject: [PATCH v2 1/5] DMA: pl330: support burst mode for dev-to-mem and
 mem-to-dev transmit
In-Reply-To: <1440722268-31637-1-git-send-email-shawn.lin@rock-chips.com>
References: <1440722176-31588-1-git-send-email-shawn.lin@rock-chips.com>
 <1440722268-31637-1-git-send-email-shawn.lin@rock-chips.com>
Message-ID: <CAPz6YkWOV0fZGF=Ac6WuZV-rAO8gpS8zuuSSpPPHd_-eeJxQ_Q@mail.gmail.com>

On Thu, Aug 27, 2015 at 5:37 PM, Shawn Lin <shawn.lin at rock-chips.com> wrote:
> From: Boojin Kim <boojin.kim at samsung.com>
>
> This patch adds to support burst mode for dev-to-mem and
> mem-to-dev transmit.
>
> Signed-off-by: Boojin Kim <boojin.kim at samsung.com>
> Signed-off-by: Addy Ke <addy.ke at rock-chips.com>
> Signed-off-by: Shawn Lin <shawn.lin at rock-chips.com>
> cc: Heiko Stuebner <heiko at sntech.de>
> cc: Doug Anderson <dianders at chromium.org>
> cc: Olof Johansson <olof at lixom.net>
>
> ---
>
> Changes in v2:
> - amend the author
> - amend Olof's mail address
>
> Changes in v1:
> - rename broken-no-flushp to "arm,pl330-broken-no-flushp" suggested
>   by Krzysztof.
> - add From original author.
> - remove Sunny's tag
>
>  drivers/dma/pl330.c | 18 ++++++++++++------
>  1 file changed, 12 insertions(+), 6 deletions(-)
>
> diff --git a/drivers/dma/pl330.c b/drivers/dma/pl330.c
> index ecab4ea0..0d544d2 100644
> --- a/drivers/dma/pl330.c
> +++ b/drivers/dma/pl330.c
> @@ -1141,10 +1141,13 @@ static inline int _ldst_devtomem(unsigned dry_run, u8 buf[],
>                 const struct _xfer_spec *pxs, int cyc)
>  {
>         int off = 0;
> +       enum pl330_cond cond;
> +
> +       cond = (pxs->desc->rqcfg.brst_len == 1) ? SINGLE : BURST;
>
>         while (cyc--) {
> -               off += _emit_WFP(dry_run, &buf[off], SINGLE, pxs->desc->peri);
> -               off += _emit_LDP(dry_run, &buf[off], SINGLE, pxs->desc->peri);
> +               off += _emit_WFP(dry_run, &buf[off], cond, pxs->desc->peri);
> +               off += _emit_LDP(dry_run, &buf[off], cond, pxs->desc->peri);
>                 off += _emit_ST(dry_run, &buf[off], ALWAYS);
>                 off += _emit_FLUSHP(dry_run, &buf[off], pxs->desc->peri);
>         }
> @@ -1156,11 +1159,14 @@ static inline int _ldst_memtodev(unsigned dry_run, u8 buf[],
>                 const struct _xfer_spec *pxs, int cyc)
>  {
>         int off = 0;
> +       enum pl330_cond cond;
> +
> +       cond = (pxs->desc->rqcfg.brst_len == 1) ? SINGLE : BURST;
>
>         while (cyc--) {
> -               off += _emit_WFP(dry_run, &buf[off], SINGLE, pxs->desc->peri);
> +               off += _emit_WFP(dry_run, &buf[off], cond, pxs->desc->peri);
>                 off += _emit_LD(dry_run, &buf[off], ALWAYS);
> -               off += _emit_STP(dry_run, &buf[off], SINGLE, pxs->desc->peri);
> +               off += _emit_STP(dry_run, &buf[off], cond, pxs->desc->peri);
>                 off += _emit_FLUSHP(dry_run, &buf[off], pxs->desc->peri);
>         }
>
> @@ -2557,7 +2563,7 @@ static struct dma_async_tx_descriptor *pl330_prep_dma_cyclic(
>
>                 desc->rqtype = direction;
>                 desc->rqcfg.brst_size = pch->burst_sz;
> -               desc->rqcfg.brst_len = 1;
> +               desc->rqcfg.brst_len = pch->burst_len;
>                 desc->bytes_requested = period_len;
>                 fill_px(&desc->px, dst, src, period_len);
>
> @@ -2702,7 +2708,7 @@ pl330_prep_slave_sg(struct dma_chan *chan, struct scatterlist *sgl,
>                 }
>
>                 desc->rqcfg.brst_size = pch->burst_sz;
> -               desc->rqcfg.brst_len = 1;
> +               desc->rqcfg.brst_len = pch->burst_len;
>                 desc->rqtype = direction;
>                 desc->bytes_requested = sg_dma_len(sg);
>         }
> --
> 2.3.7

Reviewed-by: Sonny Rao <sonnyrao at chromium.org>

>
>
> --
> To unsubscribe from this list: send the line "unsubscribe linux-kernel" in
> the body of a message to majordomo at vger.kernel.org
> More majordomo info at  http://vger.kernel.org/majordomo-info.html
> Please read the FAQ at  http://www.tux.org/lkml/


From sonnyrao at chromium.org  Mon Aug 31 15:23:47 2015
From: sonnyrao at chromium.org (Sonny Rao)
Date: Mon, 31 Aug 2015 15:23:47 -0700
Subject: [PATCH v2 3/5] Documentation: arm-pl330: add description of arm,
 pl330-broken-no-flushp
In-Reply-To: <1440722292-31721-1-git-send-email-shawn.lin@rock-chips.com>
References: <1440722176-31588-1-git-send-email-shawn.lin@rock-chips.com>
 <1440722292-31721-1-git-send-email-shawn.lin@rock-chips.com>
Message-ID: <CAPz6YkVdGp_Qu=uoZWY10R_DxyWocxM_Sw4L2epdcerkrgWjUw@mail.gmail.com>

On Thu, Aug 27, 2015 at 5:38 PM, Shawn Lin <shawn.lin at rock-chips.com> wrote:
> Signed-off-by: Shawn Lin <shawn.lin at rock-chips.com>
> Reviewed-by: Doug Anderson <dianders at chromium.org>
> ---
>
> Changes in v2:
> - add Reviewed-by: Doug Anderson <dianders at chromium.org>
> - reorder this patch before the usage of the quirk
>
> Changes in v1:
> - rename broken-no-flushp to "arm,pl330-broken-no-flushp" suggested
>   by Krzysztof.
>
>  Documentation/devicetree/bindings/dma/arm-pl330.txt | 1 +
>  1 file changed, 1 insertion(+)
>
> diff --git a/Documentation/devicetree/bindings/dma/arm-pl330.txt b/Documentation/devicetree/bindings/dma/arm-pl330.txt
> index 2675658..db7e226 100644
> --- a/Documentation/devicetree/bindings/dma/arm-pl330.txt
> +++ b/Documentation/devicetree/bindings/dma/arm-pl330.txt
> @@ -15,6 +15,7 @@ Optional properties:
>      cells in the dmas property of client device.
>    - dma-channels: contains the total number of DMA channels supported by the DMAC
>    - dma-requests: contains the total number of DMA requests supported by the DMAC
> +  - arm,pl330-broken-no-flushp: quirk for avoiding to execute DMAFLUSHP
>
>  Example:
>
> --
> 2.3.7

Reviewed-by: Sonny Rao <sonnyrao at chromium.org>

>
>
> --
> To unsubscribe from this list: send the line "unsubscribe linux-kernel" in
> the body of a message to majordomo at vger.kernel.org
> More majordomo info at  http://vger.kernel.org/majordomo-info.html
> Please read the FAQ at  http://www.tux.org/lkml/


From javier at osg.samsung.com  Mon Aug 31 15:46:22 2015
From: javier at osg.samsung.com (Javier Martinez Canillas)
Date: Tue, 1 Sep 2015 00:46:22 +0200
Subject: [PATCH] ARM: EXYNOS: reset KFC cores when cpu is up
In-Reply-To: <7hmvx785wx.fsf@deeprootsystems.com>
References: <1441031111-6549-1-git-send-email-parkch98@gmail.com>
 <7hmvx785wx.fsf@deeprootsystems.com>
Message-ID: <55E4D93E.4090307@osg.samsung.com>


[adding Krzysztof Kozlowski to cc list]

Hello Kevin,

On 09/01/2015 12:11 AM, Kevin Hilman wrote:
> Chanho Park <parkch98 at gmail.com> writes:
> 
>> The cpu booting of exynos5422 has been still broken since we discussed
>> it in last year[1]. This patch is inspired from odroid xu3
>> code(Actually, it was from samsung exynos vendor kernel)[2]. This weird
>> reset code was founded exynos5420 octa cores series SoCs and only
>> required for the first boot core is the little core(kingfisher core).
>> Some of the exynos5420 boards and all of the exynos5422 boards will be
>> required this code.
>> There is two ways to check the little core is the first cpu. One is
>> checking GPG2CON[1] gpio value and the other is checking the cluster
>> number of the first cpu. I selected the latter because it's more easier
>> than the former.
>>
>> Changes since RFC[3]:
>> - drop checking soc_is_exynos5800 to extend this codes to
>> exynos5420/5422 boards.
>> - kfc cores will be reset only if the cpu0 is kfc core.
>> - Rebase top of the kukjin's for-next branch
>>
>> [1]:http://lists.infradead.org/pipermail/linux-arm-kernel/2015-June/350632.html
>> [2]:https://patchwork.kernel.org/patch/6782891/
>> [3]:http://lists.infradead.org/pipermail/linux-arm-kernel/2015-July/356610.html
>>
>> Cc: Joonyoung Shim <jy0922.shim at samsung.com>
>> Cc: Chanwoo Choi <cw00.choi at samsung.com>
>> Cc: Kevin Hilman <khilman at kernel.org>
>> Cc: Heesub Shin <heesub.shin at samsung.com>
>> Cc: Mauro Ribeiro <mauro.ribeiro at hardkernel.com>
>> Cc: Abhilash Kesavan <a.kesavan at samsung.com>
>> Cc: Przemyslaw Marczak <p.marczak at samsung.com>
>> Cc: Marek Szyprowski <m.szyprowski at samsung.com>
>> Cc: Krzysztof Kozlowski <k.kozlowski at samsung.com>
>> Signed-off-by: Chanho Park <parkch98 at gmail.com>
> 
>> ---
>>  arch/arm/mach-exynos/mcpm-exynos.c | 18 +++++++++++++++++-
>>  arch/arm/mach-exynos/regs-pmu.h    |  6 ++++++
>>  2 files changed, 23 insertions(+), 1 deletion(-)
>>
>> diff --git a/arch/arm/mach-exynos/mcpm-exynos.c b/arch/arm/mach-exynos/mcpm-exynos.c
>> index 9bdf547..5b69ed2 100644
>> --- a/arch/arm/mach-exynos/mcpm-exynos.c
>> +++ b/arch/arm/mach-exynos/mcpm-exynos.c
>> @@ -20,6 +20,7 @@
>>  #include <asm/cputype.h>
>>  #include <asm/cp15.h>
>>  #include <asm/mcpm.h>
>> +#include <asm/smp_plat.h>
>>  
>>  #include "regs-pmu.h"
>>  #include "common.h"
>> @@ -70,7 +71,22 @@ static int exynos_cpu_powerup(unsigned int cpu, unsigned int cluster)
>>  		cluster >= EXYNOS5420_NR_CLUSTERS)
>>  		return -EINVAL;
>>  
>> -	exynos_cpu_power_up(cpunr);
>> +	if (!exynos_cpu_power_state(cpunr)) {
>> +		exynos_cpu_power_up(cpunr);
>> +
>> +		/* This assumes the cluster number of the eagle is 0 and the
>> +		 * kfc is 1. When the system was booted from the kfc core,
>> +		 * they should be reset */
> 
> minor: fix multi-line comment style (search for 'multi-line' in
> Documentation/CodingStyle)
> 
> Also minor, but personally, I prefer seeing A15/A7 instead of eagle/KFC
> as those names are fading from my memory and I can't seem to remember
> which one is which. :/
> 
>> +		if (cluster &&
>> +		    cluster == MPIDR_AFFINITY_LEVEL(cpu_logical_map(0), 1)) {
>> +			while (!pmu_raw_readl(S5P_PMU_SPARE2))
>> +				udelay(10);
>> +
>> +			pmu_raw_writel(EXYNOS5420_KFC_CORE_RESET(cpu),
>> +					EXYNOS_SWRESET);
>> +		}
>> +	}
>> +
>>  	return 0;
>>  }
> 
> I tested this on top of mainline (v4.2) using exynos_defconfig (with
> BL_SWITCHER disabled) and I now see all 8 CPUs booting.  Nice!
> 
> Tested-by: Kevin Hilman <khilman at linaro.org>
> 
> Also, please note that this does not fix another fundamental problem
> with this board in that the firmware puts CCI into secure mode, so
> linux/MCPM cannot manage it, causing hangs whenever CPUidle is enabled
> (because b.L cpuidle driver tries to use MCPM, which needs to manage
> CCI.)
> 
> In order for this to not hang when using CPUidle, the following patch is
> also needed.
> 
> Kevin
> 
> diff --git a/arch/arm/boot/dts/exynos5422-odroidxu3.dts
> b/arch/arm/boot/dts/exynos5422-odroidxu3.dts
> index 78e6a502f320..7891bd05bf8e 100644
> --- a/arch/arm/boot/dts/exynos5422-odroidxu3.dts
> +++ b/arch/arm/boot/dts/exynos5422-odroidxu3.dts
> @@ -49,3 +49,11 @@
>                 shunt-resistor = <10000>;
>         };
>  };
> +
> +/*
> + * Secure firmware prevents CCI access/usage from linux, so must be
> disabled
> + * to prevent usage by MCPM.
> + */
> +&cci {
> +       status = "disabled";
> +};
> 
>

I posted a similar patch that instead disabling CCI for the XU3 board,
it disables in exynos5422-odroidxu3-common.dtsi since all Exynos5422
Odroid boards have the same broken firmware and so the same issue:

https://lkml.org/lkml/2015/8/29/59

Krzysztof tested it on an Odroid XU3 Lite and reported that disabling
CCI caused some CPUs to fail to boot even with $subject applied:

https://lkml.org/lkml/2015/8/29/65

Did you succeed booting all CPUs with CONFIG_ARM_BIG_LITTLE_CPUIDLE
enabled and CCI disabled in the the Odroid XU3 DTS?

Best regards,
-- 
Javier Martinez Canillas
Open Source Group
Samsung Research America


From jonmason at broadcom.com  Mon Aug 31 16:00:09 2015
From: jonmason at broadcom.com (Jon Mason)
Date: Mon, 31 Aug 2015 19:00:09 -0400
Subject: [PATCH v3 2/5] ARM: NSP: add minimal Northstar Plus device tree
In-Reply-To: <CAL_JsqL1=WoaidMgLN4exvhF7bYr4FNGmtMgYO8e-c=NxP3JbQ@mail.gmail.com>
References: <1440805644-18241-1-git-send-email-jonmason@broadcom.com>
 <55E0FAC4.2040108@broadcom.com>
 <20150831022417.GA27066@broadcom.com>
 <55E3FFB5.6090703@broadcom.com>
 <20150831194404.GA28848@broadcom.com>
 <CAL_JsqL1=WoaidMgLN4exvhF7bYr4FNGmtMgYO8e-c=NxP3JbQ@mail.gmail.com>
Message-ID: <20150831230009.GA29316@broadcom.com>

On Mon, Aug 31, 2015 at 04:49:10PM -0500, Rob Herring wrote:
> On Mon, Aug 31, 2015 at 2:44 PM, Jon Mason <jonmason at broadcom.com> wrote:
> > On Mon, Aug 31, 2015 at 12:18:13AM -0700, Ray Jui wrote:
> >>
> >>
> >> On 8/30/2015 7:24 PM, Jon Mason wrote:
> >> > On Fri, Aug 28, 2015 at 05:20:20PM -0700, Ray Jui wrote:
> >> >>
> >> >>
> >> >> On 8/28/2015 4:47 PM, Jon Mason wrote:
> >> >>> Add a very minimalistic set of Northstar Plus Device Tree files which
> >> >>> describes the SoC and the BCM958625 implementation.  The perpherials
> >> >>> described are:
> >> >>>
> >> >>> ARM Cortex A9 CPU
> >> >>> 2 8250 UARTs
> >> >>> ARM GIC
> >> >>> PL310 L2 Cache
> >> >>> ARM A9 Global timer
> 
> [...]
> 
> >> >>> + apb {
> >> >>> +         compatible = "arm,amba-bus", "simple-bus";
> >> >>
> >> >> Should "arm,amba-bus" has a separate bus node with AMBA compatible
> >> >> devices declared in there (e.g, pl330, spi-pl022, and etc.) in the
> >> >> future after they are brought up? To my best knowledge, "ns16550a" UART
> >> >> is NOT an AMBA compatible device.
> 
> IIRC, "arm,amba-bus" is not documented nor used. It isn't really
> needed as there is no s/w visible feature to an AMBA bus. There are
> also multiple flavors of AMBA buses, so it is pretty meaningless.
> 
> >> > APB is an AMBA bus, so this part is accurate.  The block diagram of
> >> > the SoC has the UARTs (and other perpherials) hanging off of the APB
> >> > bus.  So, this organization follows the block diagram.
> >>
> >> Okay so the "apb" node can be used for amba compatible devices
> >> (arm,amba-bus) and/or simple platform devices (simple-bus). I guess
> >> that's fine and I now see that there are some other dtsi also doing it
> >> this way.
> 
> I think what is meant here by "amba compatible devices" is really ARM
> Primecell peripherals which are the ARM IP with standard ID registers.
> These are designated by "arm,primecell" compatible strings for the
> device not the bus compatible string.

Okay, based on this and the comments above, I'll remove all references
to the amba bus and just make a simple bus called AXI (off which all
of the prepherials will be located).

Thanks,
Jon

> 
> >>
> >> > While the
> >> > UART drivers are not AMBA aware, there appears to be no issues with
> >> > this layout (as the HW/drivers come up without issue). Unless there
> >> > is an unforeseen issue with having non-AMBA aware devices on the DT
> >> > AMBA bus, I would think it best to organize it to match the block
> >> > disgram.
> >> >
> >>
> >> UART runs fine because you also have "simple-bus" listed as the
> >> compatible string so uart is populated as standard platform device.
> >>
> >> >>> +         interrupt-parent = <&gic>;
> >> >>> +         ranges = <0x00000000 0x18000000 0x00001000>;
> >> >>
> >> >> Does the 'apb' bus mean to cover all peripherals connected through APB?
> >> >> If so, the size is only 0x1000 and that seems to be too small...
> >> >
> >> > This is all that is currently needed.  I was planning on expanding it
> >> > as I added more devices.
> >>
> >> Sure.
> >>
> >> I haven't checked the datahsheet but based on the layout (which seems
> >> quite similar to Cygnus), I assume the range for these devices should be
> >> 0x18000000 - 0x18ffffff? Just want to make sure there are no other
> >> devices come before 0x18000000 so you don't need to change all these reg
> >> offsets in the future.
> >
> > Based on the devices listed in the block diagram (and not including
> > those on the AXI bus):
> > i2c 0x18038000
> > spi 0x18027200
> > gpio 0x18000060
> > pwm 0x18031000
> > wdt 0x18039000
> >
> > and a few others.
> >
> > Looking at the sources, all the ARM IP is 0x19000000 and the rest is
> > 0x18000000.  The only part that is a little harry is the clocks, which
> > have BCM and ARM (which causes the addresses to be both 0x19000000 and
> > 0x18000000).  But, we can handle that when we upstream that part (which
> > should be very soon).
> 
> If you can tell that 0x19000000 is a separate bus at some level, then
> it makes sense to separate it. You can't always tell without detailed
> internal bus diagrams.
> 
> Rob


From robert.jarzmik at free.fr  Mon Aug 31 16:00:39 2015
From: robert.jarzmik at free.fr (Robert Jarzmik)
Date: Tue, 01 Sep 2015 01:00:39 +0200
Subject: Possible regression: module insertion, relocation misalignement
In-Reply-To: <87egil26sn.fsf@belgarion.home> (Robert Jarzmik's message of
 "Sat, 29 Aug 2015 22:12:08 +0200")
References: <87egil26sn.fsf@belgarion.home>
Message-ID: <87vbbvysfc.fsf@belgarion.home>

Robert Jarzmik <robert.jarzmik at free.fr> writes:
> Hello,
>
> I have a strange regression with linux-next on module insertion. The stack I get
> when inserting a module is in [3]. I'm using the gcc in [1], and added a small
> print in [2]. This happens on a pxa310 cm-x300 platform.
>
> As far as I understand the Oops, this is an unaligned access on the following
> relocation (0xbf009a26):
> 	*(u32 *)loc += sym->st_value;
>
> This happens regardless of the module I try, by that fat.ko, pxa3xx-nand.ko, etc
> .. I add that I have not changed my toolchain for quite some time.
Hi Russell,

After digging a bit in the problem, and even if I don't understand why this
happens, I know at least _what_ happens. I'd like to know if this is specific to
xscale or a wider problem, hence this mail to you.

The summary of my problem :
 - on linux-next (20150828), module insertion Oopses (see [3])
 - the Oops is as far as I understand an unaligned access (message above)
   It is in arch/arm/kernel/module.h, the line:
		*(u32 *)loc += sym->st_value;
 - the unalignement comes from a relocation in section __bug_table (see [1])
   The address is 0xbf0021ea.
 - the module readelf in [2] shows the relocation in __bug_table

Do you know if other ARM platform are affected, and if an alignement of "1" is
normal for a __bug_table section (as opposed to an alignement of 4) ? And I'm
wondering how it is I have never seen that before also ...

If I have omitted some data, please tell me so that I can complete this report.

Cheers.

-- 
Robert

[1] module.c kernel debug messages
==================================
init_module: umod=000b5018, len=28664, uargs=000b5008
Core section allocation order:
	.text
	.exit.text
	.note.gnu.build-id
	.ARM.extab
	.ARM.exidx
	.rodata.str
	__bug_table
	.ARM.extab.init.text
	.ARM.exidx.init.text
	.ARM.extab.exit.text
	.ARM.exidx.exit.text
	.rodata
	__param
	.rodata.str1.8
	.data
	.gnu.linkonce.this_module
	.bss
Init section allocation order:
	.init.text
	.symtab
	.strtab
final section addresses:
	0xbf0020d0 .note.gnu.build-id
	0xbf000000 .text
	0xbf007000 .init.text
	0xbf0020c4 .exit.text
	0xbf0020f4 .ARM.extab
	0xbf0020f4 .ARM.exidx
	0xbf0021ac .rodata.str
	0xbf0021ea __bug_table
	0xbf002202 .ARM.extab.init.text
	0xbf002204 .ARM.exidx.init.text
	0xbf00220c .ARM.extab.exit.text
	0xbf00220c .ARM.exidx.exit.text
	0xbf002218 .rodata
	0xbf002490 __param
	0xbf0024a8 .rodata.str1.8
	0xbf002938 .data
	0xbf004d00 .gnu.linkonce.this_module
	0xbf004e80 .bss
	0xbf007014 .symtab
	0xbf007aa4 .strtab
Absolute symbol: 0x00000000
Absolute symbol: 0x00000000
...

[2] readelf -Sr pxa3xx_nand.ko
==============================
There are 36 section headers, starting at offset 0x6a58:

Section Headers:
  [Nr] Name              Type            Addr     Off    Size   ES Flg Lk Inf Al
  [ 0]                   NULL            00000000 000000 000000 00      0   0  0
  [ 1] .note.gnu.build-i NOTE            00000000 000034 000024 00   A  0   0  4
  [ 2] .text             PROGBITS        00000000 000058 0020c4 00  AX  0   0  4
  [ 3] .rel.text         REL             00000000 006378 0004b8 08   I 34   2  4
  [ 4] .init.text        PROGBITS        00000000 00211c 000014 00  AX  0   0  4
  [ 5] .rel.init.text    REL             00000000 006830 000018 08   I 34   4  4
  [ 6] .exit.text        PROGBITS        00000000 002130 00000c 00  AX  0   0  4
  [ 7] .rel.exit.text    REL             00000000 006848 000010 08   I 34   6  4
  [ 8] .ARM.extab        PROGBITS        00000000 00213c 000000 00   A  0   0  1
  [ 9] .ARM.exidx        ARM_EXIDX       00000000 00213c 0000b8 00  AL  2   0  4
  [10] .rel.ARM.exidx    REL             00000000 006858 0000c0 08   I 34   9  4
  [11] .rodata.str       PROGBITS        00000000 0021f4 00003e 01 AMS  0   0  1
  [12] __bug_table       PROGBITS        00000000 002232 000018 00   A  0   0  1
  [13] .rel__bug_table   REL             00000000 006918 000020 08   I 34  12  4
  [14] .ARM.extab.init.t PROGBITS        00000000 00224a 000000 00   A  0   0  1
  [15] .ARM.exidx.init.t ARM_EXIDX       00000000 00224c 000008 00  AL  4   0  4
  [16] .rel.ARM.exidx.in REL             00000000 006938 000010 08   I 34  15  4
  [17] .ARM.extab.exit.t PROGBITS        00000000 002254 000000 00   A  0   0  1
  [18] .ARM.exidx.exit.t ARM_EXIDX       00000000 002254 000008 00  AL  6   0  4
  [19] .rel.ARM.exidx.ex REL             00000000 006948 000010 08   I 34  18  4
  [20] .rodata           PROGBITS        00000000 002260 000278 00   A  0   0  8
  [21] .modinfo          PROGBITS        00000000 0024d8 000138 00   A  0   0  8
  [22] __param           PROGBITS        00000000 002610 000014 00   A  0   0  4
  [23] .rel__param       REL             00000000 006958 000020 08   I 34  22  4
  [24] .rodata.str1.8    PROGBITS        00000000 002628 000490 01 AMS  0   0  8
  [25] .data             PROGBITS        00000000 002ab8 0023c0 00  WA  0   0  4
  [26] .rel.data         REL             00000000 006978 0000d0 08   I 34  25  4
  [27] .gnu.linkonce.thi PROGBITS        00000000 004e80 000180 00  WA  0   0 32
  [28] .rel.gnu.linkonce REL             00000000 006a48 000010 08   I 34  27  4
  [29] .bss              NOBITS          00000000 005000 000000 00  WA  0   0  4
  [30] .comment          PROGBITS        00000000 005000 000030 01  MS  0   0  1
  [31] .note.GNU-stack   PROGBITS        00000000 005030 000000 00      0   0  1
  [32] .ARM.attributes   ARM_ATTRIBUTES  00000000 005030 00002b 00      0   0  1
  [33] .shstrtab         STRTAB          00000000 00505b 00016a 00      0   0  1
  [34] .symtab           SYMTAB          00000000 0051c8 000a90 10     35 121  4
  [35] .strtab           STRTAB          00000000 005c58 000720 00      0   0  1
Key to Flags:
  W (write), A (alloc), X (execute), M (merge), S (strings)
  I (info), L (link order), G (group), T (TLS), E (exclude), x (unknown)
  O (extra OS processing required) o (OS specific), p (processor specific)
...
Relocation section '.rel__bug_table' at offset 0x6918 contains 4 entries:
 Offset     Info    Type            Sym.Value  Sym. Name
00000000  00000202 R_ARM_ABS32       00000000   .text
00000004  00000702 R_ARM_ABS32       00000000   .rodata.str
0000000c  00000202 R_ARM_ABS32       00000000   .text
00000010  00000702 R_ARM_ABS32       00000000   .rodata.str


[3] Backtrace
=============
apply_relocate(): pxa3xx_nand: section 13 reloc 0 sym ''
RJK: apply_relocate():97 dstsec=e49e8c38 dstsec->sh_addr=bf0021ea rel=e49e8918 rel->r_offset=0x0 sec_shdr={addr=0x0 off=0x0 size=0x0 flags=0x0}
Unable to handle kernel paging request at virtual address bf0021ea
pgd = e1cd0000
[bf0021ea] *pgd=c1cce851, *pte=c1cde04f, *ppte=c1cde01f
Internal error: Oops: 23 [#1] ARM
Modules linked in:
CPU: 0 PID: 606 Comm: insmod Not tainted 4.2.0-rc8-next-20150828-cm-x300+ #887
Hardware name: CM-X300 module
task: e1c68700 ti: e1c3e000 task.ti: e1c3e000
PC is at apply_relocate+0x2f4/0x3d4
LR is at 0xbf0021ea
pc : [<c000e7c8>]    lr : [<bf0021ea>]    psr: 80000013
sp : e1c3fe30  ip : 60000013  fp : e49e8c60
r10: e49e8fa8  r9 : 00000000  r8 : e49e7c58
r7 : e49e8c38  r6 : e49e8a58  r5 : e49e8920  r4 : e49e8918
r3 : bf0021ea  r2 : bf007034  r1 : 00000000  r0 : bf000000
Flags: Nzcv  IRQs on  FIQs on  Mode SVC_32  ISA ARM  Segment none
Control: 0000397f  Table: c1cd0018  DAC: 00000051
Process insmod (pid: 606, stack limit = 0xe1c3e198)
Stack: (0xe1c3fe30 to 0xe1c40000)
fe20:                                     ???????? ???????? ???????? ????????
fe40: ???????? ???????? ???????? ???????? ???????? ???????? ???????? ????????
fe60: ???????? ???????? ???????? ???????? ???????? ???????? ???????? ????????
fe80: ???????? ???????? ???????? ???????? ???????? ???????? ???????? ????????
fea0: ???????? ???????? ???????? ???????? ???????? ???????? ???????? ????????
fec0: ???????? ???????? ???????? ???????? ???????? ???????? ???????? ????????
fee0: ???????? ???????? ???????? ???????? ???????? ???????? ???????? ????????
ff00: ???????? ???????? ???????? ???????? ???????? ???????? ???????? ????????
ff20: ???????? ???????? ???????? ???????? ???????? ???????? ???????? ????????
ff40: ???????? ???????? ???????? ???????? ???????? ???????? ???????? ????????
ff60: ???????? ???????? ???????? ???????? ???????? ???????? ???????? ????????
ff80: ???????? ???????? ???????? ???????? ???????? ???????? ???????? ????????
ffa0: ???????? ???????? ???????? ???????? ???????? ???????? ???????? ????????
ffc0: ???????? ???????? ???????? ???????? ???????? ???????? ???????? ????????
ffe0: ???????? ???????? ???????? ???????? ???????? ???????? ???????? ????????
[<c000e7c8>] (apply_relocate) from [<c005ce5c>] (load_module+0x1248/0x1f5c)
[<c005ce5c>] (load_module) from [<c005dc54>] (SyS_init_module+0xe4/0x170)
[<c005dc54>] (SyS_init_module) from [<c000a420>] (ret_fast_syscall+0x0/0x38)
Code: bad PC value
---[ end trace 53a5b8d1316bd52d ]---

[4] gcc version
===============
rj at belgarion:~/mio_linux/kernel$ arm-linux-gnueabi-gcc -v
Using built-in specs.
COLLECT_GCC=/usr/bin/arm-linux-gnueabi-gcc
COLLECT_LTO_WRAPPER=/usr/lib/gcc/arm-linux-gnueabi/4.9/lto-wrapper
Target: arm-linux-gnueabi
Configured with: ../src/configure -v --with-pkgversion=' 4.9.2-10' --with-bugurl=file:///usr/share/doc/gcc-4.9/README.Bugs --enable-languages=c,c++,go,fortran,objc --prefix=/usr --program-suffix=-4.9 --enable-shared --enable-linker-build-id --libexecdir=/usr/lib --without-included-gettext --enable-threads=posix --with-gxx-include-dir=/usr/include/c++/4.9 --libdir=/usr/lib --enable-nls --with-sysroot=/ --enable-clocale=gnu --enable-libstdcxx-debug --enable-libstdcxx-time=yes --enable-gnu-unique-object --disable-libitm --disable-libquadmath --enable-plugin --with-system-zlib --enable-objc-gc --enable-multiarch --disable-sjlj-exceptions --with-arch=armv4t --with-float=soft --enable-checking=release --build=x86_64-linux-gnu --host=x86_64-linux-gnu --target=arm-linux-gnueabi --program-prefix=arm-linux-gnueabi-
Thread model: posix
gcc version 4.9.2 ( 4.9.2-10) 


From linux at arm.linux.org.uk  Mon Aug 31 16:46:38 2015
From: linux at arm.linux.org.uk (Russell King - ARM Linux)
Date: Tue, 1 Sep 2015 00:46:38 +0100
Subject: Possible regression: module insertion, relocation misalignement
In-Reply-To: <87vbbvysfc.fsf@belgarion.home>
References: <87egil26sn.fsf@belgarion.home>
 <87vbbvysfc.fsf@belgarion.home>
Message-ID: <20150831234638.GI21084@n2100.arm.linux.org.uk>

On Tue, Sep 01, 2015 at 01:00:39AM +0200, Robert Jarzmik wrote:
> [2] readelf -Sr pxa3xx_nand.ko
> ==============================
> There are 36 section headers, starting at offset 0x6a58:
> 
> Section Headers:
>   [Nr] Name              Type            Addr     Off    Size   ES Flg Lk Inf Al
>   [ 0]                   NULL            00000000 000000 000000 00      0   0  0
>   [ 1] .note.gnu.build-i NOTE            00000000 000034 000024 00   A  0   0  4
>   [ 2] .text             PROGBITS        00000000 000058 0020c4 00  AX  0   0  4
>   [ 3] .rel.text         REL             00000000 006378 0004b8 08   I 34   2  4
>   [ 4] .init.text        PROGBITS        00000000 00211c 000014 00  AX  0   0  4
>   [ 5] .rel.init.text    REL             00000000 006830 000018 08   I 34   4  4
>   [ 6] .exit.text        PROGBITS        00000000 002130 00000c 00  AX  0   0  4
>   [ 7] .rel.exit.text    REL             00000000 006848 000010 08   I 34   6  4
>   [ 8] .ARM.extab        PROGBITS        00000000 00213c 000000 00   A  0   0  1
>   [ 9] .ARM.exidx        ARM_EXIDX       00000000 00213c 0000b8 00  AL  2   0  4
>   [10] .rel.ARM.exidx    REL             00000000 006858 0000c0 08   I 34   9  4
>   [11] .rodata.str       PROGBITS        00000000 0021f4 00003e 01 AMS  0   0  1
>   [12] __bug_table       PROGBITS        00000000 002232 000018 00   A  0   0  1

This shows that the bug table has an alignment of 1, which is silly as
it contains 32-bit values - this really ought to be indicating an
alignment of 4.

I notice that a bunch of my modules are the same as well.  Try adding
".align 2" into arch/arm/include/asm/bug.h, __BUG() macro, just after
".pushsection __bug_table" which should have the effect of increasing
the alignment of the section.

It probably hasn't been noticed on ARMv6 and later because they'll
always fix up these relocations transparently.

For ARMv5 and older, you really ought to have the alignment handler
enabled - IP networking pretty much relies on this being present to
catch corner cases (eg, with TCP options mis-aligning subsequent data.)

-- 
FTTC broadband for 0.8mile line: currently at 9.6Mbps down 400kbps up
according to speedtest.net.


From jonmason at broadcom.com  Mon Aug 31 16:48:53 2015
From: jonmason at broadcom.com (Jon Mason)
Date: Mon, 31 Aug 2015 19:48:53 -0400
Subject: [PATCH v4 2/5] ARM: NSP: add minimal Northstar Plus device tree
Message-ID: <1441064933-6723-1-git-send-email-jonmason@broadcom.com>

Add a very minimalistic set of Northstar Plus Device Tree files which
describes the SoC and the BCM958625 implementation.  The perpherials
described are:

ARM Cortex A9 CPU
2 8250 UARTs
ARM GIC
PL310 L2 Cache
ARM A9 Global timer

Signed-off-by: Kapil Hali <kapilh at broadcom.com>
Signed-off-by: Jon Mason <jonmason at broadcom.com>
---
 arch/arm/boot/dts/Makefile       |   2 +
 arch/arm/boot/dts/bcm-nsp.dtsi   | 119 +++++++++++++++++++++++++++++++++++++++
 arch/arm/boot/dts/bcm958625k.dts |  57 +++++++++++++++++++
 3 files changed, 178 insertions(+)
 create mode 100644 arch/arm/boot/dts/bcm-nsp.dtsi
 create mode 100644 arch/arm/boot/dts/bcm958625k.dts

diff --git a/arch/arm/boot/dts/Makefile b/arch/arm/boot/dts/Makefile
index 246473a..adb5732 100644
--- a/arch/arm/boot/dts/Makefile
+++ b/arch/arm/boot/dts/Makefile
@@ -82,6 +82,8 @@ dtb-$(CONFIG_ARCH_BCM_CYGNUS) += \
 dtb-$(CONFIG_ARCH_BCM_MOBILE) += \
 	bcm28155-ap.dtb \
 	bcm21664-garnet.dtb
+dtb-$(CONFIG_ARCH_BCM_NSP) += \
+	bcm958625k.dtb
 dtb-$(CONFIG_ARCH_BERLIN) += \
 	berlin2-sony-nsz-gs7.dtb \
 	berlin2cd-google-chromecast.dtb \
diff --git a/arch/arm/boot/dts/bcm-nsp.dtsi b/arch/arm/boot/dts/bcm-nsp.dtsi
new file mode 100644
index 0000000..58aca27
--- /dev/null
+++ b/arch/arm/boot/dts/bcm-nsp.dtsi
@@ -0,0 +1,119 @@
+/*
+ *  BSD LICENSE
+ *
+ *  Copyright(c) 2015 Broadcom Corporation.  All rights reserved.
+ *
+ *  Redistribution and use in source and binary forms, with or without
+ *  modification, are permitted provided that the following conditions
+ *  are met:
+ *
+ *    * Redistributions of source code must retain the above copyright
+ *      notice, this list of conditions and the following disclaimer.
+ *    * Redistributions in binary form must reproduce the above copyright
+ *      notice, this list of conditions and the following disclaimer in
+ *      the documentation and/or other materials provided with the
+ *      distribution.
+ *    * Neither the name of Broadcom Corporation nor the names of its
+ *      contributors may be used to endorse or promote products derived
+ *      from this software without specific prior written permission.
+ *
+ *  THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+ *  "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+ *  LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
+ *  A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
+ *  OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
+ *  SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
+ *  LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
+ *  DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
+ *  THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+ *  (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
+ *  OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ */
+
+#include <dt-bindings/interrupt-controller/arm-gic.h>
+#include <dt-bindings/interrupt-controller/irq.h>
+
+#include "skeleton.dtsi"
+
+/ {
+	compatible = "brcm,nsp";
+	model = "Broadcom Northstar Plus SoC";
+	interrupt-parent = <&gic>;
+
+	mpcore {
+		compatible = "simple-bus";
+		ranges = <0x00000000 0x19020000 0x00003000>;
+		#address-cells = <1>;
+		#size-cells = <1>;
+
+		cpus {
+			#address-cells = <1>;
+			#size-cells = <0>;
+
+			cpu at 0 {
+				device_type = "cpu";
+				compatible = "arm,cortex-a9";
+				next-level-cache = <&L2>;
+				reg = <0x0>;
+			};
+		};
+
+		L2: l2-cache {
+			compatible = "arm,pl310-cache";
+			reg = <0x2000 0x1000>;
+			cache-unified;
+			cache-level = <2>;
+		};
+
+		gic: interrupt-controller at 19021000 {
+			compatible = "arm,cortex-a9-gic";
+			#interrupt-cells = <3>;
+			#address-cells = <0>;
+			interrupt-controller;
+			reg = <0x1000 0x1000>,
+			      <0x0100 0x100>;
+		};
+
+		timer at 19020200 {
+			compatible = "arm,cortex-a9-global-timer";
+			reg = <0x0200 0x100>;
+			interrupts = <GIC_PPI 11 IRQ_TYPE_LEVEL_HIGH>;
+			clocks = <&periph_clk>;
+		};
+	};
+
+	clocks {
+		#address-cells = <1>;
+		#size-cells = <1>;
+		ranges;
+
+		periph_clk: periph_clk {
+			compatible = "fixed-clock";
+			#clock-cells = <0>;
+			clock-frequency = <500000000>;
+		};
+	};
+
+	axi {
+		compatible = "simple-bus";
+		ranges = <0x00000000 0x18000000 0x00001000>;
+		#address-cells = <1>;
+		#size-cells = <1>;
+
+		uart0: serial at 18000300 {
+			compatible = "ns16550a";
+			reg = <0x0300 0x100>;
+			interrupts = <GIC_SPI 85 IRQ_TYPE_LEVEL_HIGH>;
+			clock-frequency = <62499840>;
+			status = "disabled";
+		};
+
+		uart1: serial at 18000400 {
+			compatible = "ns16550a";
+			reg = <0x0400 0x100>;
+			interrupts = <GIC_SPI 85 IRQ_TYPE_LEVEL_HIGH>;
+			clock-frequency = <62499840>;
+			status = "disabled";
+		};
+	};
+};
diff --git a/arch/arm/boot/dts/bcm958625k.dts b/arch/arm/boot/dts/bcm958625k.dts
new file mode 100644
index 0000000..16303db
--- /dev/null
+++ b/arch/arm/boot/dts/bcm958625k.dts
@@ -0,0 +1,57 @@
+/*
+ *  BSD LICENSE
+ *
+ *  Copyright(c) 2015 Broadcom Corporation.  All rights reserved.
+ *
+ *  Redistribution and use in source and binary forms, with or without
+ *  modification, are permitted provided that the following conditions
+ *  are met:
+ *
+ *    * Redistributions of source code must retain the above copyright
+ *      notice, this list of conditions and the following disclaimer.
+ *    * Redistributions in binary form must reproduce the above copyright
+ *      notice, this list of conditions and the following disclaimer in
+ *      the documentation and/or other materials provided with the
+ *      distribution.
+ *    * Neither the name of Broadcom Corporation nor the names of its
+ *      contributors may be used to endorse or promote products derived
+ *      from this software without specific prior written permission.
+ *
+ *  THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+ *  "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+ *  LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
+ *  A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
+ *  OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
+ *  SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
+ *  LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
+ *  DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
+ *  THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+ *  (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
+ *  OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ */
+
+/dts-v1/;
+
+#include "bcm-nsp.dtsi"
+
+/ {
+	model = "NorthStar Plus SVK (BCM958625K)";
+	compatible = "brcm,bcm58625", "brcm,nsp";
+
+	aliases {
+		serial0 = &uart0;
+		serial1 = &uart1;
+	};
+
+	chosen {
+		stdout-path = "serial0:115200n8";
+	};
+};
+
+&uart0 {
+	status = "okay";
+};
+
+&uart1 {
+	status = "okay";
+};
-- 
1.9.1



From olof at lixom.net  Mon Aug 31 17:07:03 2015
From: olof at lixom.net (Olof Johansson)
Date: Mon, 31 Aug 2015 17:07:03 -0700
Subject: [GIT PULL 0/7] ARM: SoC changes for v4.3
Message-ID: <1441066030-23225-1-git-send-email-olof@lixom.net>

Hi Linus,

Here's the main batch of changes from arm-soc for 4.3. Besides this we
also have a branch of changes that looked to be late-arriving (right
before -rc7), and we'll leave those to a separate pull request a little
later.

Nothing in here should be controversial at this point. We have more
external dependencies than we've had for a while, mostly with the clk
tree.  We also picked up some other misc drivers with appropriate acks
(rtc, pci, etc) through the platform maintainers the drivers are for.

We've been able to keep conflicts down this cycle, only a few and none
are hairy. I've described them in the affected pull requests.

There's a branch "armsoc-resolved" available with my version of the
resolutions.

Please merge!


Thanks,

-Olof



From olof at lixom.net  Mon Aug 31 17:07:04 2015
From: olof at lixom.net (Olof Johansson)
Date: Mon, 31 Aug 2015 17:07:04 -0700
Subject: [GIT PULL 1/7] ARM: SoC non-urgent fixes for 4.3
In-Reply-To: <1441066030-23225-1-git-send-email-olof@lixom.net>
References: <1441066030-23225-1-git-send-email-olof@lixom.net>
Message-ID: <1441066030-23225-2-git-send-email-olof@lixom.net>

We normally collect non-urgent fixes during the release cycle and queue them for the merge window.

This time around the list is short (in part because some have gone in other
branches).

- Maintainers addition for bcm2835
- IRQ number fix for orion5x (been present since 3.18)
- DT fix for display on exynos3250
- Exynos fix to use of IOMEM_ERR_PTR properly

----------------------------------------------------------------

The following changes since commit 64291f7db5bd8150a74ad2036f1037e6a0428df2:

  Linux 4.2

are available in the git repository at:

  git://git.kernel.org/pub/scm/linux/kernel/git/arm/arm-soc.git tags/armsoc-fixes-nc

for you to fetch changes up to 330349fae46f8400e86ef98ee05af4ba13466f49:

  Merge tag 'mvebu-fixes-4.2-1' of git://git.infradead.org/linux-mvebu into next/fixes-non-critical

----------------------------------------------------------------

Benjamin Cama (1):
      ARM: orion5x: fix legacy orion5x IRQ numbers

Eric Anholt (2):
      MAINTAINERS: Add myself as a bcm2835 co-maintainer.
      MAINTAINERS: Explicitly add linux-arm-kernel for bcm2835

Hyungwon Hwang (1):
      ARM: dts: fix clock-frequency of display timing0 for exynos3250-rinato

Krzysztof Kozlowski (1):
      ARM: EXYNOS: Use IOMEM_ERR_PTR when function returns iomem

Olof Johansson (3):
      Merge tag 'samsung-non-critical-1' of git://git.kernel.org/.../kgene/linux-samsung into next/fixes-non-critical
      Merge tag 'arm-soc/for-4.3/maintainers' of http://github.com/broadcom/stblinux into next/fixes-non-critical
      Merge tag 'mvebu-fixes-4.2-1' of git://git.infradead.org/linux-mvebu into next/fixes-non-critical


 MAINTAINERS                               |  2 +
 arch/arm/Kconfig                          |  1 +
 arch/arm/boot/dts/exynos3250-rinato.dts   |  2 +-
 arch/arm/mach-exynos/platsmp.c            |  2 +-
 arch/arm/mach-orion5x/include/mach/irqs.h | 64 +++++++++++++-------------
 arch/arm/mach-orion5x/irq.c               |  4 +-
 6 files changed, 39 insertions(+), 36 deletions(-)


From olof at lixom.net  Mon Aug 31 17:07:05 2015
From: olof at lixom.net (Olof Johansson)
Date: Mon, 31 Aug 2015 17:07:05 -0700
Subject: [GIT PULL 2/7] ARM: SoC cleanups for v4.3
In-Reply-To: <1441066030-23225-1-git-send-email-olof@lixom.net>
References: <1441066030-23225-1-git-send-email-olof@lixom.net>
Message-ID: <1441066030-23225-3-git-send-email-olof@lixom.net>

A large cleanup branch this release, with a healthy 10k negative line delta.

Most of this is removal of legacy (non-DT) support of shmobile
platforms. There is also removal of two non-DT platforms on OMAP,
and the plat-samsung directory is cleaned out by moving most of the
previously shared-location-but-not-actually-shared files from there to
the appropriate mach directories instead.

There are other sets of changes in here as well:

- Rob Herring removed use of set_irq_flags under all platforms and
moved to genirq alternatives
- A series of timer API conversions to set-state interface
- ep93xx, nomadik and ux500 cleanups from Linus Walleij
- __init annotation fixes from Nicolas Pitre
+ a bunch of other changes that all add up to a nice set of cleanups

----------------------------------------------------------------

The following changes since commit 8f844fac5c5b97534cff57310b1d660e8210ee00:

  Merge branch 'next/fixes-non-critical' into HEAD

are available in the git repository at:

  git://git.kernel.org/pub/scm/linux/kernel/git/arm/arm-soc.git tags/armsoc-cleanup

for you to fetch changes up to 97a2482d9891f0ad6a3710e0b6ae9949c140c7f1:

  Merge tag 'tegra-for-4.3-cleanup' of git://git.kernel.org/pub/scm/linux/kernel/git/tegra/linux into next/cleanup

----------------------------------------------------------------

Florian Fainelli (1):
      ARM: BCM63xx: Remove custom secondary_startup function

Geert Uytterhoeven (24):
      ARM: shmobile: R-Mobile: Move to_rmobile_pd from header to source file
      ARM: shmobile: R-Mobile: Use BIT() macro instead of open coding
      ARM: shmobile: r8a7779: Remove GENPD_FLAG_PM_CLK flag
      ARM: shmobile: Remove legacy board code for KZM-A9-GT
      ARM: shmobile: Remove legacy kzm9g_defconfig
      ARM: shmobile: Drop sh73a0-kzm9g.dtb for legacy builds
      ARM: shmobile: Remove legacy SoC code for SH-Mobile AG5
      ARM: shmobile: Remove legacy board code for Armadillo-800 EVA
      ARM: shmobile: Remove legacy armadillo800eva_defconfig
      ARM: shmobile: Drop r8a7740-armadillo800eva.dtb for legacy builds
      ARM: shmobile: Remove legacy SoC code for R-Mobile A1
      ARM: shmobile: Remove unused dma-register.h
      ARM: shmobile: R-Mobile: Remove legacy PM Domain code
      ARM: shmobile: Remove obsolete zboot support
      ARM: shmobile: R-Car Gen2: CONFIG_ARCH_SHMOBILE_MULTI is always set
      ARM: shmobile: timer: r8a73a4 and r8a7790 are multi-platform only
      ARM: shmobile: R-Car: Improve documentation
      ARM: shmobile: R-Car: Shrink rcar_sysc_ch size
      ARM: shmobile: R-Car: Break infinite loop
      ARM: shmobile: R-Car: Make struct rcar_sysc_ch * parameters const
      ARM: shmobile: R-Car: Use BIT() macro instead of open coding
      ARM: shmobile: R-Car: Get rid of on_off_fn() function pointer
      ARM: shmobile: r8a7779: Make struct rcar_sysc_ch const
      ARM: shmobile: r8a7790: Make struct rcar_sysc_ch const

H Hartley Sweeten (3):
      ARM: ep93xx: remove memory configuration options
      ARM: ep93xx: vision_ep9307: enable DMA for SPI
      ARM: ep93xx: vision_ep9307: add audio support

Hans Ulli Kroll (3):
      ARM: gemini: Add missing register definitions for gemini timer
      ARM: gemini: Use timer1 for clockevent
      ARM: gemini: Setup timer3 as free running timer

Jiang Liu (2):
      ARM/irq: Use access helper irq_data_get_affinity_mask()
      ARM, irq: Use irq_desc_get_xxx() to avoid redundant lookup of irq_desc

Joe Perches (1):
      ARM: orion5x: Use vsprintf %pM extension

Krzysztof Kozlowski (3):
      ARM: EXYNOS: Make local function static
      ARM: EXYNOS: Remove duplicated define of SLEEP_MAGIC
      ARM: EXYNOS: Drop owner assignment in pmu.c

Kukjin Kim (14):
      ARM: SAMSUNG: make local setup-camif in mach-s3c24xx
      ARM: SAMSUNG: make local dev-backlight in mach-s3c64xx
      ARM: SAMSUNG: make local s5p-dev-mfc in mach-exynos
      ARM: SAMSUNG: local regs-srom header in mach-exynos
      ARM: SAMSUNG: local fb-core header in mach-s3c24xx
      ARM: SAMSUNG: local nand-core header in mach-s3c24xx
      ARM: SAMSUNG: local spi-core header in mach-s3c24xx
      ARM: SAMSUNG: local regs-usb-hsotg-phy header in mach-s3c64xx
      ARM: SAMSUNG: local ata-core header in mach-s3c64xx
      ARM: SAMSUNG: local backlight header in mach-s3c64xx
      ARM: SAMSUNG: local irq-uart header in mach-s3c64xx
      ARM: SAMSUNG: local onenand-core header in mach-s3c64xx
      ARM: SAMSUNG: local watchdog-reset header in mach-s3c64xx
      ARM: SAMSUNG: remove keypad-core header in plat-samsung

Linus Walleij (13):
      ARM: ep93xx: move timer to its own file
      ARM: ep93xx: switch to GENERIC_CLOCKEVENTS
      ARM: ep93xx: use non-raw accessors for timer
      ARM: ep93xx: switch clockevent to timer 3
      ARM: ep93xx: update comment on timer usage
      ARM: ep93xx: toss the device ID into the entropy pool
      ARM: ep93xx: simone: enable DMA on the SPI host
      ARM: ux500: simplify secondary CPU boot
      ARM: nomadik: move hog code to use DT hogs
      ARM: nomadik: selectively enable UART0 on boards
      ARM: nomadik: move l2x0 setup to device tree
      ARM: nomadik: push accelerometer down to boards
      ARM/fb: ep93xx: switch framebuffer to use modedb only

Magnus Damm (6):
      ARM: shmobile: r8a7779: Generic CCF and timer support
      ARM: shmobile: r8a7779: Generic SMP ops
      ARM: shmobile: marzen-reference: Remove C board code
      ARM: shmobile: r8a7779: Cleanup header file
      ARM: shmobile: marzen: Remove legacy board code
      ARM: shmobile: r8a7779: Remove legacy SoC code

Marcel Ziswiler (1):
      ALSA: hda/tegra - Fix hda2codec_2x clock and reset names

Nicolas Pitre (1):
      ARM: appropriate __init annotation for const data

Olof Johansson (14):
      Merge tag 'renesas-cleanup-for-v4.3' of git://git.kernel.org/.../horms/renesas into next/cleanup
      Merge tag 'renesas-pm-domain-for-v4.3' of git://git.kernel.org/.../horms/renesas into next/cleanup
      Merge branch 'ARM/clkevt/set-state-4.3' of git://git.kernel.org/.../vireshk/linux into next/cleanup
      Merge tag 'mvebu-cleanup-4.3-1' of git://git.infradead.org/linux-mvebu into next/cleanup
      Merge tag 'arm-soc/for-4.3/soc' of http://github.com/broadcom/stblinux into next/cleanup
      Merge tag 'ep93xx-cleanup' of git://git.kernel.org/.../linusw/linux-integrator into next/cleanup
      Merge tag 'omap-for-v4.3/legacy-v2-signed' of git://git.kernel.org/.../tmlind/linux-omap into next/cleanup
      Merge tag 'renesas-cleanup2-for-v4.3' of git://git.kernel.org/.../horms/renesas into next/cleanup
      Merge branch 'queue/irq/arm' of git://git.kernel.org/.../tip/tip into next/cleanup
      Merge tag 'renesas-marzen-board-removal-for-v4.3' of git://git.kernel.org/.../horms/renesas into next/cleanup
      Merge branch 'fixes' into next/cleanup
      ARM: shmobile: Fix mismerges
      Merge tag 'samsung-cleanup' of git://git.kernel.org/.../kgene/linux-samsung into next/cleanup
      Merge tag 'tegra-for-4.3-cleanup' of git://git.kernel.org/.../tegra/linux into next/cleanup

Rob Herring (1):
      ARM: kill off set_irq_flags usage

Sudeep Holla (1):
      ARM: BCM63xx: fix parameter to of_get_cpu_node in bcm63138_smp_boot_secondary

Thierry Reding (1):
      ALSA: hda/tegra: Order clock and reset names consistently

Thomas Gleixner (9):
      ARM/orion: Consolidate chained IRQ handler install/remove
      ARM/locomo: Consolidate chained IRQ handler install/remove
      ARM/LPC32xx: Use irq_set_handler_locked()
      ARM/locomo: Prepare locomo_handler for irq argument removal
      ARM/sa1111: Prepare sa1111_irq_handler for irq argument removal
      ARM/dove: Prepare pmu_irq_handler for irq argument removal
      ARM/pxa: Prepare *_irq_handler for irq argument removal
      ARM/pxa: Prepare balloon3_irq_handler for irq argument removal
      ARM/orion/gpio: Prepare gpio_irq_handler for irq argument removal

Thomas Petazzoni (1):
      ARM: mvebu: add missing newline at end of messages

Tony Lindgren (2):
      ARM: OMAP2+: Remove legacy booting support for LogicPD Torpedo
      ARM: OMAP2+: Remove legacy booting support for Pandora

Viresh Kumar (19):
      ARM/smp_twd: Migrate to new 'set-state' interface
      ARM/cns3xxx/timer: Migrate to new 'set-state' interface
      ARM/davinci/time: Migrate to new 'set-state' interface
      ARM/dc21285-timer: Migrate to new 'set-state' interface
      ARM/gemini/time: Migrate to new 'set-state' interface
      ARM/imx/epit: Migrate to new 'set-state' interface
      ARM/ixp4xx/timer: Migrate to new 'set-state' interface
      ARM/ks8695/time: Migrate to new 'set-state' interface
      ARM/lpc32xx/timer: Migrate to new 'set-state' interface
      ARM/mmp/time: Migrate to new 'set-state' interface
      ARM/netx/time: Migrate to new 'set-state' interface
      ARM/omap1/time: Migrate to new 'set-state' interface
      ARM/omap1/timer32: Migrate to new 'set-state' interface
      ARM/omap2/timer: Migrate to new 'set-state' interface
      ARM/SPEAr/time: Migrate to new 'set-state' interface
      ARM/w90x900/time: Migrate to new 'set-state' interface
      ARM/iop/time: Migrate to new 'set-state' interface
      ARM/orion/time: Migrate to new 'set-state' interface
      ARM: ep93xx/timer: Migrate to new 'set-state' interface

Wolfram Sang (1):
      ARM: shmobile: apmu: silence build warnings


 .../bindings/sound/nvidia,tegra30-hda.txt       |    8 +-
 MAINTAINERS                                     |    2 -
 arch/arm/Kconfig                                |   11 +-
 arch/arm/boot/compressed/Makefile               |    4 -
 arch/arm/boot/compressed/head-shmobile.S        |   71 -
 arch/arm/boot/dts/Makefile                      |    5 +-
 arch/arm/boot/dts/ste-nomadik-nhk15.dts         |   39 +-
 arch/arm/boot/dts/ste-nomadik-s8815.dts         |   44 +-
 arch/arm/boot/dts/ste-nomadik-stn8815.dtsi      |   22 +-
 arch/arm/common/it8152.c                        |    2 +-
 arch/arm/common/locomo.c                        |   11 +-
 arch/arm/common/sa1111.c                        |    9 +-
 arch/arm/configs/armadillo800eva_defconfig      |  162 ---
 arch/arm/configs/kzm9g_defconfig                |  154 --
 arch/arm/kernel/irq.c                           |    4 +-
 arch/arm/kernel/psci.c                          |    2 +-
 arch/arm/kernel/smp_twd.c                       |   48 +-
 arch/arm/mach-at91/at91rm9200.c                 |    2 +-
 arch/arm/mach-at91/at91sam9.c                   |    6 +-
 arch/arm/mach-at91/pm.c                         |    2 +-
 arch/arm/mach-at91/sama5.c                      |    4 +-
 arch/arm/mach-bcm/Makefile                      |    4 +-
 arch/arm/mach-bcm/bcm63xx_headsmp.S             |   23 -
 arch/arm/mach-bcm/bcm63xx_smp.c                 |    4 +-
 arch/arm/mach-bcm/bcm63xx_smp.h                 |    1 -
 arch/arm/mach-bcm/bcm_5301x.c                   |    2 +-
 arch/arm/mach-bcm/bcm_kona_smc.c                |    2 +-
 arch/arm/mach-clps711x/board-autcpu12.c         |    2 +-
 arch/arm/mach-cns3xxx/core.c                    |   59 +-
 arch/arm/mach-davinci/cp_intc.c                 |    2 +-
 arch/arm/mach-davinci/da850.c                   |    4 +-
 arch/arm/mach-davinci/da8xx-dt.c                |    4 +-
 arch/arm/mach-davinci/time.c                    |   54 +-
 arch/arm/mach-digicolor/digicolor.c             |    2 +-
 arch/arm/mach-dove/irq.c                        |    5 +-
 arch/arm/mach-ebsa110/core.c                    |    2 +-
 arch/arm/mach-ep93xx/Kconfig                    |   54 -
 arch/arm/mach-ep93xx/Makefile                   |    2 +-
 arch/arm/mach-ep93xx/Makefile.boot              |   15 +-
 arch/arm/mach-ep93xx/core.c                     |  116 +-
 arch/arm/mach-ep93xx/edb93xx.c                  |    2 -
 arch/arm/mach-ep93xx/simone.c                   |    3 +-
 arch/arm/mach-ep93xx/snappercl15.c              |    2 -
 arch/arm/mach-ep93xx/timer-ep93xx.c             |  143 ++
 arch/arm/mach-ep93xx/vision_ep9307.c            |   63 +-
 arch/arm/mach-exynos/Kconfig                    |    5 +
 arch/arm/mach-exynos/Makefile                   |    2 +
 arch/arm/mach-exynos/common.h                   |    6 +
 arch/arm/mach-exynos/firmware.c                 |    2 -
 arch/arm/mach-exynos/pmu.c                      |    3 +-
 .../include/plat => mach-exynos}/regs-srom.h    |    3 +-
 .../{plat-samsung => mach-exynos}/s5p-dev-mfc.c |    0
 arch/arm/mach-exynos/suspend.c                  |    8 +-
 arch/arm/mach-footbridge/common.c               |    2 +-
 arch/arm/mach-footbridge/dc21285-timer.c        |   48 +-
 arch/arm/mach-footbridge/isa-irq.c              |    8 +-
 arch/arm/mach-gemini/gpio.c                     |    2 +-
 arch/arm/mach-gemini/include/mach/hardware.h    |    3 -
 arch/arm/mach-gemini/irq.c                      |    2 +-
 arch/arm/mach-gemini/time.c                     |  219 ++-
 arch/arm/mach-imx/3ds_debugboard.c              |    2 +-
 arch/arm/mach-imx/epit.c                        |   67 +-
 arch/arm/mach-imx/mach-imx7d.c                  |    2 +-
 arch/arm/mach-imx/mach-mx31ads.c                |    2 +-
 arch/arm/mach-iop13xx/irq.c                     |    2 +-
 arch/arm/mach-iop32x/irq.c                      |    2 +-
 arch/arm/mach-iop33x/irq.c                      |    2 +-
 arch/arm/mach-ixp4xx/common.c                   |   70 +-
 arch/arm/mach-ks8695/irq.c                      |    2 +-
 arch/arm/mach-ks8695/time.c                     |   43 +-
 arch/arm/mach-lpc32xx/irq.c                     |   10 +-
 arch/arm/mach-lpc32xx/phy3250.c                 |    4 +-
 arch/arm/mach-lpc32xx/timer.c                   |   40 +-
 arch/arm/mach-mmp/mmp-dt.c                      |    4 +-
 arch/arm/mach-mmp/mmp2-dt.c                     |    2 +-
 arch/arm/mach-mmp/time.c                        |   29 +-
 arch/arm/mach-mvebu/pmsu.c                      |    4 +-
 arch/arm/mach-mxs/mach-mxs.c                    |    4 +-
 arch/arm/mach-netx/generic.c                    |    2 +-
 arch/arm/mach-netx/time.c                       |   61 +-
 arch/arm/mach-nomadik/cpu-8815.c                |   41 +-
 arch/arm/mach-omap1/fpga.c                      |    2 +-
 arch/arm/mach-omap1/irq.c                       |    2 +-
 arch/arm/mach-omap1/time.c                      |   35 +-
 arch/arm/mach-omap1/timer32k.c                  |   33 +-
 arch/arm/mach-omap2/Kconfig                     |   20 -
 arch/arm/mach-omap2/Makefile                    |    3 -
 arch/arm/mach-omap2/board-omap3logic.c          |  249 ----
 arch/arm/mach-omap2/board-omap3pandora.c        |  633 --------
 arch/arm/mach-omap2/prm_common.c                |    2 +-
 arch/arm/mach-omap2/timer.c                     |   48 +-
 arch/arm/mach-omap2/vc.c                        |    2 +-
 arch/arm/mach-omap2/voltagedomains3xxx_data.c   |    2 +-
 arch/arm/mach-omap2/voltagedomains44xx_data.c   |    2 +-
 arch/arm/mach-omap2/voltagedomains54xx_data.c   |    2 +-
 arch/arm/mach-orion5x/dns323-setup.c            |    4 +-
 arch/arm/mach-orion5x/tsx09-common.c            |    4 +-
 arch/arm/mach-pxa/balloon3.c                    |   16 +-
 arch/arm/mach-pxa/cm-x2xx-pci.c                 |    3 +-
 arch/arm/mach-pxa/irq.c                         |    1 -
 arch/arm/mach-pxa/lpd270.c                      |    5 +-
 arch/arm/mach-pxa/pcm990-baseboard.c            |    5 +-
 arch/arm/mach-pxa/pxa-dt.c                      |    4 +-
 arch/arm/mach-pxa/pxa3xx.c                      |    2 +-
 arch/arm/mach-pxa/viper.c                       |    5 +-
 arch/arm/mach-pxa/zeus.c                        |    5 +-
 arch/arm/mach-realview/realview-dt.c            |    2 +-
 arch/arm/mach-rpc/ecard.c                       |    2 +-
 arch/arm/mach-rpc/irq.c                         |   16 +-
 arch/arm/mach-s3c24xx/Kconfig                   |    5 +
 arch/arm/mach-s3c24xx/Makefile                  |    1 +
 arch/arm/mach-s3c24xx/bast-irq.c                |    2 +-
 .../include/plat => mach-s3c24xx}/fb-core.h     |    2 -
 arch/arm/mach-s3c24xx/mach-s3c2416-dt.c         |    2 +-
 .../include/plat => mach-s3c24xx}/nand-core.h   |    3 +-
 arch/arm/mach-s3c24xx/s3c2412.c                 |    2 +-
 arch/arm/mach-s3c24xx/s3c2416.c                 |    6 +-
 arch/arm/mach-s3c24xx/s3c2443.c                 |    7 +-
 arch/arm/mach-s3c24xx/s3c244x.c                 |    2 +-
 .../setup-camif.c                               |    0
 .../include/plat => mach-s3c24xx}/spi-core.h    |    0
 arch/arm/mach-s3c64xx/Kconfig                   |    6 +
 arch/arm/mach-s3c64xx/Makefile                  |    2 +
 .../include/plat => mach-s3c64xx}/ata-core.h    |    3 +-
 .../include/plat => mach-s3c64xx}/backlight.h   |    3 +-
 arch/arm/mach-s3c64xx/common.c                  |    6 +-
 .../dev-backlight.c                             |    6 +-
 .../include/plat => mach-s3c64xx}/irq-uart.h    |    3 +-
 arch/arm/mach-s3c64xx/mach-s3c64xx-dt.c         |    5 +-
 arch/arm/mach-s3c64xx/mach-smdk6410.c           |    2 +-
 .../plat => mach-s3c64xx}/onenand-core.h        |    2 -
 .../plat => mach-s3c64xx}/regs-usb-hsotg-phy.h  |    3 +-
 arch/arm/mach-s3c64xx/s3c6400.c                 |    2 +-
 arch/arm/mach-s3c64xx/s3c6410.c                 |    4 +-
 arch/arm/mach-s3c64xx/setup-usb-phy.c           |    2 +-
 .../plat => mach-s3c64xx}/watchdog-reset.h      |    3 +-
 arch/arm/mach-sa1100/neponset.c                 |    4 +-
 arch/arm/mach-shmobile/Kconfig                  |   47 -
 arch/arm/mach-shmobile/Makefile                 |   14 +-
 arch/arm/mach-shmobile/Makefile.boot            |    3 -
 arch/arm/mach-shmobile/board-armadillo800eva.c  | 1365 ------------------
 arch/arm/mach-shmobile/board-bockw-reference.c  |    2 +-
 arch/arm/mach-shmobile/board-bockw.c            |    2 +-
 arch/arm/mach-shmobile/board-kzm9g.c            |  916 ------------
 arch/arm/mach-shmobile/board-marzen-reference.c |   56 -
 arch/arm/mach-shmobile/board-marzen.c           |  347 -----
 arch/arm/mach-shmobile/clock-r8a7740.c          |  675 ---------
 arch/arm/mach-shmobile/clock-r8a7779.c          |  271 ----
 arch/arm/mach-shmobile/clock-sh73a0.c           |  752 ----------
 arch/arm/mach-shmobile/dma-register.h           |   84 --
 .../mach-shmobile/include/mach/head-kzm9g.txt   |  410 ------
 arch/arm/mach-shmobile/include/mach/zboot.h     |   19 -
 .../mach-shmobile/include/mach/zboot_macros.h   |  108 --
 arch/arm/mach-shmobile/intc-sh73a0.c            |  337 -----
 arch/arm/mach-shmobile/platsmp-apmu.c           |    4 +-
 arch/arm/mach-shmobile/pm-r8a7740.c             |  129 --
 arch/arm/mach-shmobile/pm-r8a7779.c             |    4 +-
 arch/arm/mach-shmobile/pm-rcar.c                |  105 +-
 arch/arm/mach-shmobile/pm-rcar.h                |   12 +-
 arch/arm/mach-shmobile/pm-rmobile.c             |   49 +-
 arch/arm/mach-shmobile/pm-rmobile.h             |   30 -
 arch/arm/mach-shmobile/pm-sh73a0.c              |   32 -
 arch/arm/mach-shmobile/r8a7740.h                |   58 -
 arch/arm/mach-shmobile/r8a7779.h                |   19 -
 arch/arm/mach-shmobile/setup-r7s72100.c         |    2 +-
 arch/arm/mach-shmobile/setup-r8a73a4.c          |    2 +-
 arch/arm/mach-shmobile/setup-r8a7740.c          |  680 +--------
 arch/arm/mach-shmobile/setup-r8a7778.c          |    2 +-
 arch/arm/mach-shmobile/setup-r8a7779.c          |  683 +--------
 arch/arm/mach-shmobile/setup-r8a7791.c          |    2 +-
 arch/arm/mach-shmobile/setup-rcar-gen2.c        |    2 -
 arch/arm/mach-shmobile/setup-sh73a0.c           |  741 +---------
 arch/arm/mach-shmobile/sh73a0.h                 |   83 --
 arch/arm/mach-shmobile/smp-r8a7779.c            |   21 +-
 arch/arm/mach-shmobile/smp-r8a7790.c            |    4 +-
 arch/arm/mach-shmobile/smp-sh73a0.c             |    8 -
 arch/arm/mach-shmobile/timer.c                  |   12 -
 arch/arm/mach-spear/time.c                      |   91 +-
 arch/arm/mach-sti/board-dt.c                    |    2 +-
 arch/arm/mach-ux500/Makefile                    |    2 +-
 arch/arm/mach-ux500/cpu-db8500.c                |    1 -
 arch/arm/mach-ux500/headsmp.S                   |   37 -
 arch/arm/mach-ux500/platsmp.c                   |  132 +-
 arch/arm/mach-ux500/setup.h                     |    1 -
 arch/arm/mach-w90x900/irq.c                     |    2 +-
 arch/arm/mach-w90x900/time.c                    |   51 +-
 arch/arm/mach-zx/zx296702.c                     |    2 +-
 arch/arm/plat-iop/time.c                        |   70 +-
 arch/arm/plat-orion/gpio.c                      |    9 +-
 arch/arm/plat-orion/time.c                      |   93 +-
 arch/arm/plat-samsung/Kconfig                   |   17 -
 arch/arm/plat-samsung/Makefile                  |    5 -
 .../arm/plat-samsung/include/plat/keypad-core.h |   31 -
 drivers/irqchip/irq-sa11x0.c                    |    1 -
 drivers/video/fbdev/ep93xx-fb.c                 |   30 +-
 include/linux/platform_data/video-ep93xx.h      |    8 -
 196 files changed, 1281 insertions(+), 10483 deletions(-)
 delete mode 100644 arch/arm/boot/compressed/head-shmobile.S
 delete mode 100644 arch/arm/configs/armadillo800eva_defconfig
 delete mode 100644 arch/arm/configs/kzm9g_defconfig
 delete mode 100644 arch/arm/mach-bcm/bcm63xx_headsmp.S
 create mode 100644 arch/arm/mach-ep93xx/timer-ep93xx.c
 rename arch/arm/{plat-samsung/include/plat => mach-exynos}/regs-srom.h (96%)
 rename arch/arm/{plat-samsung => mach-exynos}/s5p-dev-mfc.c (100%)
 delete mode 100644 arch/arm/mach-omap2/board-omap3logic.c
 delete mode 100644 arch/arm/mach-omap2/board-omap3pandora.c
 rename arch/arm/{plat-samsung/include/plat => mach-s3c24xx}/fb-core.h (93%)
 rename arch/arm/{plat-samsung/include/plat => mach-s3c24xx}/nand-core.h (93%)
 rename arch/arm/{plat-samsung => mach-s3c24xx}/setup-camif.c (100%)
 rename arch/arm/{plat-samsung/include/plat => mach-s3c24xx}/spi-core.h (100%)
 rename arch/arm/{plat-samsung/include/plat => mach-s3c64xx}/ata-core.h (92%)
 rename arch/arm/{plat-samsung/include/plat => mach-s3c64xx}/backlight.h (92%)
 rename arch/arm/{plat-samsung => mach-s3c64xx}/dev-backlight.c (98%)
 rename arch/arm/{plat-samsung/include/plat => mach-s3c64xx}/irq-uart.h (90%)
 rename arch/arm/{plat-samsung/include/plat => mach-s3c64xx}/onenand-core.h (95%)
 rename arch/arm/{plat-samsung/include/plat => mach-s3c64xx}/regs-usb-hsotg-phy.h (96%)
 rename arch/arm/{plat-samsung/include/plat => mach-s3c64xx}/watchdog-reset.h (91%)
 delete mode 100644 arch/arm/mach-shmobile/board-armadillo800eva.c
 delete mode 100644 arch/arm/mach-shmobile/board-kzm9g.c
 delete mode 100644 arch/arm/mach-shmobile/board-marzen-reference.c
 delete mode 100644 arch/arm/mach-shmobile/board-marzen.c
 delete mode 100644 arch/arm/mach-shmobile/clock-r8a7740.c
 delete mode 100644 arch/arm/mach-shmobile/clock-r8a7779.c
 delete mode 100644 arch/arm/mach-shmobile/clock-sh73a0.c
 delete mode 100644 arch/arm/mach-shmobile/dma-register.h
 delete mode 100644 arch/arm/mach-shmobile/include/mach/head-kzm9g.txt
 delete mode 100644 arch/arm/mach-shmobile/include/mach/zboot.h
 delete mode 100644 arch/arm/mach-shmobile/include/mach/zboot_macros.h
 delete mode 100644 arch/arm/mach-shmobile/intc-sh73a0.c
 delete mode 100644 arch/arm/mach-shmobile/pm-r8a7740.c
 delete mode 100644 arch/arm/mach-shmobile/pm-sh73a0.c
 delete mode 100644 arch/arm/mach-shmobile/r8a7740.h
 delete mode 100644 arch/arm/mach-ux500/headsmp.S
 delete mode 100644 arch/arm/plat-samsung/include/plat/keypad-core.h


From olof at lixom.net  Mon Aug 31 17:07:06 2015
From: olof at lixom.net (Olof Johansson)
Date: Mon, 31 Aug 2015 17:07:06 -0700
Subject: [GIT PULL 3/7] ARM: SoC platform updates for v4.3
In-Reply-To: <1441066030-23225-1-git-send-email-olof@lixom.net>
References: <1441066030-23225-1-git-send-email-olof@lixom.net>
Message-ID: <1441066030-23225-4-git-send-email-olof@lixom.net>

New or improved SoC support:

- Addition of support for Atmel's SAMA5D2 SoC
- Addition of Freescale i.MX6UL
- Improved support of TI's DM814x platform
- Misc fixes and improvements for RockChip platforms
- Marvell MVEBU suspend/resume support

A few driver changes that ideally would belong in the drivers branch are
also here (acked by appropriate maintainers):

- Power key input driver for Freescale platforms (svns)
- RTC driver updates for Freescale platforms (svns/mxc)
- Clk fixes for TI DM814/816X

+ a bunch of other changes for various platforms


Conflicts:

arch/arm/mach-at91/sama5.c:

Change/add with cleanup branch. Keep array declaration from HEAD, add
sama5d2 entry from branch.

----------------------------------------------------------------

The following changes since commit 597e2b048c61a26437706c85e0ad4323b6df8c41:

  Merge branch 'next/cleanup' into HEAD

are available in the git repository at:

  git://git.kernel.org/pub/scm/linux/kernel/git/arm/arm-soc.git tags/armsoc-soc

for you to fetch changes up to 1ec6f701707e4e97e451ff8b662360f1262a6c59:

  Merge tag 'v4.3-rockchip32-soc3' of git://git.kernel.org/pub/scm/linux/kernel/git/mmind/linux-rockchip into next/soc

----------------------------------------------------------------

Anson Huang (1):
      ARM: imx: add low-level debug support for i.mx6ul

Arun Chandran (1):
      ARM: zynq: Fix earlyprintk in big endian mode

Caesar Wang (4):
      ARM: rockchip: fix the CPU soft reset
      ARM: rockchip: ensure CPU to enter WFI/WFE state
      ARM: rockchip: fix the SMP code style
      ARM: rockchip: fix broken build

Chris Zhong (2):
      ARM: rockchip: add support holding 24Mhz osc during suspend
      ARM: rockchip: remove some useless macro in pm.h

Dinh Nguyen (1):
      ARM: socfpga: add reset for the Arria 10 platform

Doug Anderson (1):
      ARM: rockchip: restore dapswjdp after suspend

Fabio Estevam (2):
      ARM: imx: mach-imx6ul: Fix allmodconfig build
      ARM: rockchip: pm: Fix PTR_ERR() argument

Frank Li (4):
      ARM: imx: add i.mx6ul msl support
      rtc: snvs: use syscon to access register
      Document: dt: fsl: snvs: change support syscon
      Document: devicetree: input: imx: i.mx snvs power device tree bindings

Fugang Duan (2):
      ARM: imx6ul: add fec bits to GPR syscon definition
      ARM: imx6ul: add fec MAC refrence clock and phy fixup init

Gregory CLEMENT (3):
      ARM: mvebu: Use __init for the PM initialization functions
      ARM: mvebu: Add standby support
      ARM: mvebu: Warn about the wake-up sources not taken into account in suspend

Gregory Fong (2):
      ARM: BCM: Enable ARM erratum 798181 for BRCMSTB
      ARM: brcmstb: select ARCH_DMA_ADDR_T_64BIT for LPAE

Heiko Stuebner (3):
      ARM: rockchip: rename osc_switch_to_32k variable
      ARM: rockchip: set correct stabilization thresholds in suspend
      ARM: rockchip: enable PMU_GPIOINT_WAKEUP_EN when entering shallow suspend

Hiraku Toyooka (1):
      ARM: socfpga: add smp_ops.cpu_kill to make kexec/kdump available

Jun Nie (1):
      ARM: zx: Add power domains for ZX296702

Keerthy (6):
      ARM: OMAP4: PRM: Remove hardcoding of PRM_IO_PMCTRL_OFFSET register
      ARM: AM43xx: Add the PRM IRQ register offsets
      ARM: dts: AM4372: Add PRCM IRQ entry
      ARM: OMAP: PRM: Remove hardcoding of IRQENABLE_MPU_2 and IRQSTATUS_MPU_2 register offsets
      ARM: OMAP4+: PRM: Add AM437x specific data
      ARM: PRM: AM437x: Enable IO wakeup feature

Krzysztof Kozlowski (1):
      soc: mediatek: Drop owner assignment from platform_driver

Lokesh Vutla (1):
      ARM: OMAP2+: hwmod: add support for lock and unlock hooks

Markus Elfring (1):
      ARM: OMAP2: Delete an unnecessary check

Masahiro Yamada (3):
      MAINTAINERS: add entries for UniPhier device trees and drivers
      clk: zynq: remove redundant $(CONFIG_ARCH_ZYNQ) in Makefile
      ARM: uniphier: drop v7_invalidate_l1 call at secondary entry

Matthias Brugger (2):
      ARM: mediatek: Add regmap to mediatek Kconfig
      soc: mediatek: Fix SCPSYS compilation

Nadav Haklai (1):
      ARM: mvebu: prepare set_cpu_coherent() for future extension

Nathan Lynch (1):
      ARM: zynq: reserve space for jump target in secondary trampoline

Nicolas Ferre (1):
      ARM: at91/soc: add basic support for new sama5d2 SoC

Nishanth Menon (1):
      ARM: DRA7: Provide proper IO map table

Olof Johansson (13):
      Merge tag 'v4.3-rockchip32-soc1' of git://git.kernel.org/.../mmind/linux-rockchip into next/soc
      Merge tag 'sti-soc-for-v4.3-1' of https://git.kernel.org/.../mcoquelin/sti into next/soc
      Merge tag 'renesas-soc-for-v4.3' of git://git.kernel.org/.../horms/renesas into next/soc
      Merge tag 'omap-for-v4.3/soc-signed' of git://git.kernel.org/.../tmlind/linux-omap into next/soc
      Merge tag 'pxa-for-4.3-v2' of https://github.com/rjarzmik/linux into next/soc
      Merge tag 'v4.2-next-soc' of https://github.com/mbgg/linux-mediatek into next/soc
      Merge tag 'socfpga_updates_for_v4.3' of git://git.kernel.org/.../dinguyen/linux into next/soc
      Merge tag 'zynq-soc-for-4.3' of https://github.com/Xilinx/linux-xlnx into next/soc
      Merge tag 'mvebu-soc-4.3-1' of git://git.infradead.org/linux-mvebu into next/soc
      Merge tag 'v4.3-rockchip32-soc2' of git://git.kernel.org/.../mmind/linux-rockchip into next/soc
      Merge tag 'imx-soc-4.3' of git://git.kernel.org/.../shawnguo/linux into next/soc
      Merge tag 'omap-for-v4.3/soc-pt2' of git://git.kernel.org/.../tmlind/linux-omap into next/soc
      Merge tag 'v4.3-rockchip32-soc3' of git://git.kernel.org/.../mmind/linux-rockchip into next/soc

Paul Walmsley (1):
      Merge branch 'prcm-a-for-v4.3' into hwmod-prcm-for-v4.3

Peter Griffin (2):
      ARM: STi: Add code to release secondary cores from holding pen.
      ARM: STi: Remove platform call to trace_hardirqs_off()

Philippe Reynes (3):
      rtc: mxc: use a second rtc clock
      dt-binding: document the binding for mxc rtc
      rtc: mxc: add support of device tree

Rob Herring (1):
      memory: kill off set_irq_flags usage

Robert Jarzmik (1):
      ARM: pxa: transition to dmaengine phase 1

Robin Gong (1):
      input: keyboard: imx: add snvs power key driver

Sascha Hauer (3):
      soc: mediatek: Add infracfg misc driver support
      dt-bindings: soc: Add documentation for the MediaTek SCPSYS unit
      soc: Mediatek: Add SCPSYS power domain driver

Sekhar Nori (2):
      ARM: OMAP2+: sparse: add missing static declaration
      ARM: OMAP2+: sparse: add missing function declarations

Shawn Guo (2):
      input: snvs_pwrkey: use "wakeup-source" as deivce tree property name
      rtc: snvs: select option REGMAP_MMIO

Soren Brinkmann (1):
      MAINTAINERS: Update Zynq git tree location

Stephen Rothwell (1):
      clk: ti: fix for definition movement

Sudeep Holla (1):
      ARM: davinci: cp_intc: use IRQCHIP_SKIP_SET_WAKE instead of irq_set_wake callback

Suman Anna (1):
      ARM: OMAP2+: Remove module references from IOMMU machine layer

Thomas Betker (1):
      ARM: zynq: Set bit 22 in PL310 AuxCtrl register (6395/1)

Thomas Petazzoni (3):
      ARM: mvebu: do not check machine in mvebu_pm_init()
      ARM: mvebu: prepare mvebu_pm_store_bootinfo() to support multiple SoCs
      ARM: mvebu: prepare pm-board.c for the introduction of Armada 38x support

Tony Lindgren (11):
      ARM: OMAP2+: Clean up omap4_local_timer_init
      ARM: OMAP2+: Fix dm814x DT_MACHINE_START
      ARM: OMAP2+: Fix scm compatible for dm814x
      ARM: OMAP2+: Add minimal clockdomains for dm814x
      ARM: OMAP2+: Add custom prwdm_operations for 81xx to support dm814x
      ARM: OMAP2+: Add support for initializing dm814x clocks
      Merge tag 'for-v4.3/omap-hwmod-prcm-a' of git://git.kernel.org/.../pjw/omap-pending into omap-for-v4.3/soc
      ARM: OMAP2+: Prepare dm81xx hwmod code for adding minimal dm814x support
      ARM: OMAP2: Add minimal dm814x hwmod support
      Merge branch 'dm814x-soc' into omap-for-v4.3/soc
      ARM: OMAP2+: Fix power domain operations regression caused by 81xx

Ulrich Hecht (2):
      ARM: shmobile: Basic r8a7793 SoC support
      ARM: shmobile: gose: enable R-Car Gen2 regulator quirk

Vaishali Thakkar (2):
      ARM: pxa: Use module_platform_driver
      ARM: pxa: Use setup_timer

Vignesh R (1):
      ARM: OMAP2+: DRA7: clockdomain: change l4per2_7xx_clkdm to SW_WKUP


 Documentation/arm/Atmel/README                  |   5 +
 .../devicetree/bindings/arm/atmel-at91.txt      |   2 +
 .../devicetree/bindings/crypto/fsl-sec4.txt     |  91 ++-
 .../devicetree/bindings/input/snvs-pwrkey.txt   |   1 +
 .../devicetree/bindings/rtc/rtc-mxc.txt         |  26 +
 .../devicetree/bindings/soc/mediatek/scpsys.txt |  41 ++
 MAINTAINERS                                     |   5 +-
 arch/arm/Kconfig.debug                          |  15 +
 arch/arm/boot/dts/am4372.dtsi                   |   1 +
 arch/arm/include/debug/at91.S                   |   5 +-
 arch/arm/include/debug/imx-uart.h               |  13 +
 arch/arm/include/debug/zynq.S                   |   2 +-
 arch/arm/mach-at91/Kconfig                      |  12 +
 arch/arm/mach-at91/sama5.c                      |   3 +
 arch/arm/mach-at91/soc.h                        |   3 +
 arch/arm/mach-bcm/Kconfig                       |   2 +
 arch/arm/mach-davinci/cp_intc.c                 |  12 +-
 arch/arm/mach-imx/Kconfig                       |   8 +
 arch/arm/mach-imx/Makefile                      |   1 +
 arch/arm/mach-imx/cpu.c                         |   3 +
 arch/arm/mach-imx/mach-imx6ul.c                 |  88 +++
 arch/arm/mach-imx/mxc.h                         |   6 +
 arch/arm/mach-mediatek/Kconfig                  |   1 +
 arch/arm/mach-mvebu/coherency.c                 |  29 +-
 arch/arm/mach-mvebu/common.h                    |   4 +-
 arch/arm/mach-mvebu/pm-board.c                  |  30 +-
 arch/arm/mach-mvebu/pm.c                        |  79 ++-
 arch/arm/mach-omap2/Makefile                    |   3 +-
 arch/arm/mach-omap2/board-generic.c             |   6 +-
 arch/arm/mach-omap2/clockdomain.h               |   3 +-
 arch/arm/mach-omap2/clockdomains7xx_data.c      |   2 +-
 arch/arm/mach-omap2/clockdomains81xx_data.c     |  23 +-
 arch/arm/mach-omap2/common.h                    |   1 +
 arch/arm/mach-omap2/control.c                   |   1 +
 arch/arm/mach-omap2/io.c                        |  70 ++-
 arch/arm/mach-omap2/iomap.h                     |  63 ++
 arch/arm/mach-omap2/omap-iommu.c                |  13 +-
 arch/arm/mach-omap2/omap-mpuss-lowpower.c       |   2 +-
 arch/arm/mach-omap2/omap3-restart.c             |   1 +
 arch/arm/mach-omap2/omap4-restart.c             |   1 +
 arch/arm/mach-omap2/omap54xx.h                  |   8 +
 arch/arm/mach-omap2/omap_hwmod.c                |  16 +-
 arch/arm/mach-omap2/omap_hwmod.h                |   7 +-
 .../mach-omap2/omap_hwmod_2xxx_ipblock_data.c   |   2 +-
 arch/arm/mach-omap2/omap_hwmod_43xx_data.c      |   2 +-
 arch/arm/mach-omap2/omap_hwmod_81xx_data.c      | 571 ++++++++++++-------
 arch/arm/mach-omap2/pdata-quirks.c              |   6 +-
 arch/arm/mach-omap2/powerdomains3xxx_data.c     | 126 +++-
 arch/arm/mach-omap2/prcm-common.h               |   8 +
 arch/arm/mach-omap2/prcm43xx.h                  |   7 +
 arch/arm/mach-omap2/prm44xx.c                   |  61 +-
 arch/arm/mach-omap2/prm_common.c                |   1 +
 arch/arm/mach-omap2/timer.c                     |  18 +-
 arch/arm/mach-pxa/devices.c                     |  37 ++
 arch/arm/mach-pxa/pxa25x.c                      |   1 +
 arch/arm/mach-pxa/pxa27x.c                      |   1 +
 arch/arm/mach-pxa/pxa3xx.c                      |   1 +
 arch/arm/mach-pxa/sharpsl_pm.c                  |   6 +-
 arch/arm/mach-pxa/tosa-bt.c                     |  15 +-
 arch/arm/mach-rockchip/platsmp.c                |  56 +-
 arch/arm/mach-rockchip/pm.c                     |  78 ++-
 arch/arm/mach-rockchip/pm.h                     |  12 +-
 arch/arm/mach-shmobile/Kconfig                  |   5 +
 arch/arm/mach-shmobile/Makefile                 |   2 +
 .../mach-shmobile/regulator-quirk-rcar-gen2.c   |   3 +-
 arch/arm/mach-shmobile/setup-r8a7793.c          |  33 ++
 arch/arm/mach-socfpga/core.h                    |   1 +
 arch/arm/mach-socfpga/platsmp.c                 |  13 +
 arch/arm/mach-socfpga/socfpga.c                 |  26 +
 arch/arm/mach-sti/headsmp.S                     |   1 +
 arch/arm/mach-sti/platsmp.c                     |  57 +-
 arch/arm/mach-sti/smp.h                         |   2 +
 arch/arm/mach-uniphier/platsmp.c                |   8 +-
 arch/arm/mach-zx/Kconfig                        |   1 +
 arch/arm/mach-zx/Makefile                       |   2 +-
 arch/arm/mach-zx/zx296702-pm-domain.c           | 202 +++++++
 arch/arm/mach-zynq/common.c                     |   4 +-
 arch/arm/mach-zynq/headsmp.S                    |   2 +-
 arch/arm/plat-pxa/dma.c                         |  22 +-
 arch/arm/plat-pxa/include/plat/dma.h            |  15 +
 drivers/clk/ti/Makefile                         |   2 +-
 drivers/clk/ti/clk-814x.c                       |  33 ++
 drivers/clk/ti/clk-816x.c                       |   2 +-
 drivers/clk/zynq/Makefile                       |   2 +-
 drivers/input/keyboard/Kconfig                  |  11 +
 drivers/input/keyboard/Makefile                 |   1 +
 drivers/input/keyboard/snvs_pwrkey.c            | 227 ++++++++
 drivers/memory/omap-gpmc.c                      |   5 +-
 drivers/rtc/Kconfig                             |   1 +
 drivers/rtc/rtc-mxc.c                           |  60 +-
 drivers/rtc/rtc-snvs.c                          | 132 ++---
 drivers/soc/mediatek/Kconfig                    |  19 +
 drivers/soc/mediatek/Makefile                   |   2 +
 drivers/soc/mediatek/mtk-infracfg.c             |  91 +++
 drivers/soc/mediatek/mtk-pmic-wrap.c            |   1 -
 drivers/soc/mediatek/mtk-scpsys.c               | 488 ++++++++++++++++
 include/dt-bindings/power/mt8173-power.h        |  15 +
 include/linux/clk/ti.h                          |   3 +-
 include/linux/mfd/syscon/imx6q-iomuxc-gpr.h     |   8 +
 include/linux/soc/mediatek/infracfg.h           |  26 +
 100 files changed, 2728 insertions(+), 517 deletions(-)
 create mode 100644 Documentation/devicetree/bindings/input/snvs-pwrkey.txt
 create mode 100644 Documentation/devicetree/bindings/rtc/rtc-mxc.txt
 create mode 100644 Documentation/devicetree/bindings/soc/mediatek/scpsys.txt
 create mode 100644 arch/arm/mach-imx/mach-imx6ul.c
 create mode 100644 arch/arm/mach-shmobile/setup-r8a7793.c
 create mode 100644 arch/arm/mach-zx/zx296702-pm-domain.c
 create mode 100644 drivers/clk/ti/clk-814x.c
 create mode 100644 drivers/input/keyboard/snvs_pwrkey.c
 create mode 100644 drivers/soc/mediatek/mtk-infracfg.c
 create mode 100644 drivers/soc/mediatek/mtk-scpsys.c
 create mode 100644 include/dt-bindings/power/mt8173-power.h
 create mode 100644 include/linux/soc/mediatek/infracfg.h


From olof at lixom.net  Mon Aug 31 17:07:07 2015
From: olof at lixom.net (Olof Johansson)
Date: Mon, 31 Aug 2015 17:07:07 -0700
Subject: [GIT PULL 4/7] ARM: SoC driver updates for v4.3
In-Reply-To: <1441066030-23225-1-git-send-email-olof@lixom.net>
References: <1441066030-23225-1-git-send-email-olof@lixom.net>
Message-ID: <1441066030-23225-5-git-send-email-olof@lixom.net>

Some releases this branch is nearly empty, others we have more stuff. It
tends to gather drivers that need SoC modification or dependencies such
that they have to (also) go in through our tree.

For this release, we have merged in part of the reset controller tree
(with handshake that the parts we have merged in will remain stable),
as well as dependencies on a few clock branches.

In general, new items here are:

- Qualcomm driver for SMM/SMD, which is how they communicate with the
coprocessors on (some) of their platforms
- Memory controller work for ARM's PL172 memory controller
- Reset drivers for various platforms
- PMU power domain support for Marvell platforms
- Tegra support for T132/T210 SoCs: PMC, fuse, memory controller per-SoC support

----------------------------------------------------------------

The following changes since commit 995140c8ab9423d63f23f106815550801c93e599:

  Merge branch 'next/soc' into HEAD

are available in the git repository at:

  git://git.kernel.org/pub/scm/linux/kernel/git/arm/arm-soc.git tags/armsoc-drivers

for you to fetch changes up to 21815b9a24c6e6d3488703609561bd2892d3d9f3:

  Merge tag 'tegra-for-4.3-memory' of git://git.kernel.org/pub/scm/linux/kernel/git/tegra/linux into next/drivers

----------------------------------------------------------------

Alban Bedel (3):
      devicetree: Add bindings for the ATH79 reset controller
      reset: Add a driver for the reset controller on the AR71XX/AR9XXX
      MIPS: ath79: Add the reset controller to the AR9132 dtsi

Bjorn Andersson (5):
      soc: qcom: Add Shared Memory Manager driver
      soc: qcom: Add device tree binding for Shared Memory Device
      soc: qcom: Add Shared Memory Driver
      soc: qcom: Driver for the Qualcomm RPM over SMD
      devicetree: soc: Add Qualcomm SMD based RPM DT binding

Dinh Nguyen (1):
      reset: socfpga: Update reset-socfpga to read the altr,modrst-offset property

Fabian Frederick (1):
      reset: sti: constify of_device_id array

Geert Uytterhoeven (5):
      clk: shmobile: Add CPG/MSTP Clock Domain support
      clk: shmobile: r8a7778: Add CPG/MSTP Clock Domain support
      clk: shmobile: r8a7779: Add CPG/MSTP Clock Domain support
      clk: shmobile: rcar-gen2: Add CPG/MSTP Clock Domain support
      clk: shmobile: rz: Add CPG/MSTP Clock Domain support

Joachim Eastwood (5):
      memory: add ARM PL172 MultiPort Memory Controller driver
      doc: dt: add documentation for pl172 memory bindings
      memory: pl172: fix modular build
      reset: add driver for lpc18xx rgu
      doc: dt: add documentation for lpc1850-rgu reset driver

Lina Iyer (1):
      drivers: qcom: Select QCOM_SCM unconditionally for QCOM_PM

Masahiro Yamada (1):
      soc: tegra: Remove redundant $(CONFIG_ARCH_TEGRA) in Makefile

Moritz Fischer (2):
      docs: dts: Added documentation for Xilinx Zynq Reset Controller bindings.
      reset: reset-zynq: Adding support for Xilinx Zynq reset controller.

Olof Johansson (7):
      Merge tag 'mvebu-soc-4.3-2' of git://git.infradead.org/linux-mvebu into next/drivers
      Merge tag 'qcom-soc-for-4.3' of git://codeaurora.org/quic/kernel/agross-msm into next/drivers
      Merge tag 'renesas-clk-for-v4.3' of git://git.kernel.org/.../horms/renesas into next/drivers
      Merge tag 'reset-for-4.3' of git://git.pengutronix.de/git/pza/linux into next/drivers
      Merge tag 'tegra-for-4.3-soc' of git://git.kernel.org/.../tegra/linux into next/drivers
      Merge tag 'tegra-for-4.3-cpufreq' of git://git.kernel.org/.../tegra/linux into next/drivers
      Merge tag 'tegra-for-4.3-memory' of git://git.kernel.org/.../tegra/linux into next/drivers

Paul Walmsley (1):
      memory: tegra: Add support for a variable-size client ID bitfield

Philipp Zabel (3):
      MAINTAINERS: add include/dt-bindings/reset path to reset controller entry
      ARM: STi: DT: Move reset controller constants into common location
      Merge branch 'reset/ath79' into reset/next

Russell King (1):
      ARM: dove: create a proper PMU driver for power domains, PMU IRQs and resets

Thierry Reding (17):
      soc/tegra: Add Tegra132 support
      soc/tegra: Add Tegra210 support
      memory: tegra: Expose supported rates via debugfs
      soc/tegra: pmc: Avoid usage of uninitialized variable
      soc/tegra: pmc: Restrict legacy code to 32-bit ARM
      soc/tegra: pmc: Add Tegra210 support
      soc/tegra: fuse: Restrict legacy code to 32-bit ARM
      soc/tegra: fuse: Unify Tegra20 and Tegra30 drivers
      soc/tegra: fuse: Add Tegra210 support
      soc/tegra: fuse: Rename core_* to soc_*
      soc/tegra: fuse: Add spare bit offset for Tegra114
      soc/tegra: fuse: Add spare bit offset for Tegra124
      soc/tegra: fuse: Add spare bit offset for Tegra210
      memory: tegra: Add Tegra210 support
      soc/tegra: pmc: Remove unnecessary return statement
      soc/tegra: pmc: Use existing pclk reference
      ARM: tegra: Disable cpuidle if PSCI is available

Tomeu Vizoso (1):
      ARM: tegra: cpuidle: implement cpuidle_state.enter_freeze()

Tuomas Tynkkynen (3):
      cpufreq: tegra124: Add device tree bindings
      cpufreq: tegra: Rename tegra-cpufreq to tegra20-cpufreq
      cpufreq: Add cpufreq driver for Tegra124


 .../clock/renesas,r8a7778-cpg-clocks.txt        |   29 +-
 .../clock/renesas,r8a7779-cpg-clocks.txt        |   30 +-
 .../clock/renesas,rcar-gen2-cpg-clocks.txt      |   26 +-
 .../bindings/clock/renesas,rz-cpg-clocks.txt    |   29 +-
 .../bindings/cpufreq/tegra124-cpufreq.txt       |   44 +
 .../bindings/memory-controllers/arm,pl172.txt   |  125 ++
 .../devicetree/bindings/reset/ath79-reset.txt   |   20 +
 .../bindings/reset/nxp,lpc1850-rgu.txt          |   84 ++
 .../bindings/reset/st,sti-picophyreset.txt      |    2 +-
 .../bindings/reset/st,sti-powerdown.txt         |    4 +-
 .../bindings/reset/st,sti-softreset.txt         |    4 +-
 .../devicetree/bindings/reset/zynq-reset.txt    |   68 +
 .../devicetree/bindings/soc/qcom,smd-rpm.txt    |  117 ++
 .../devicetree/bindings/soc/qcom/qcom,smd.txt   |   79 ++
 MAINTAINERS                                     |    1 +
 arch/arm/boot/dts/stih407-family.dtsi           |    2 +-
 arch/arm/boot/dts/stih415.dtsi                  |    2 +-
 arch/arm/boot/dts/stih416.dtsi                  |    2 +-
 arch/arm/mach-mvebu/Kconfig                     |    1 +
 arch/arm/mach-mvebu/dove.c                      |    2 +
 arch/arm/mach-shmobile/Kconfig                  |    2 +
 arch/arm/mach-tegra/cpuidle-tegra114.c          |   19 +-
 arch/arm/mach-tegra/iomap.h                     |    3 -
 arch/mips/Kconfig                               |    1 +
 arch/mips/boot/dts/qca/ar9132.dtsi              |    8 +
 drivers/clk/shmobile/clk-mstp.c                 |   87 ++
 drivers/clk/shmobile/clk-r8a7778.c              |    2 +
 drivers/clk/shmobile/clk-r8a7779.c              |    2 +
 drivers/clk/shmobile/clk-rcar-gen2.c            |    2 +
 drivers/clk/shmobile/clk-rz.c                   |    3 +
 drivers/cpufreq/Kconfig.arm                     |   13 +-
 drivers/cpufreq/Makefile                        |    3 +-
 drivers/cpufreq/tegra124-cpufreq.c              |  214 +++
 .../{tegra-cpufreq.c => tegra20-cpufreq.c}      |    0
 drivers/iommu/Kconfig                           |    2 +-
 drivers/memory/Kconfig                          |    8 +
 drivers/memory/Makefile                         |    1 +
 drivers/memory/pl172.c                          |  301 ++++
 drivers/memory/tegra/Makefile                   |    1 +
 drivers/memory/tegra/mc.c                       |    8 +-
 drivers/memory/tegra/mc.h                       |    4 +
 drivers/memory/tegra/tegra114.c                 |    1 +
 drivers/memory/tegra/tegra124-emc.c             |   42 +-
 drivers/memory/tegra/tegra124.c                 |    2 +
 drivers/memory/tegra/tegra210.c                 | 1080 ++++++++++++++
 drivers/memory/tegra/tegra30.c                  |    1 +
 drivers/reset/Makefile                          |    3 +
 drivers/reset/reset-ath79.c                     |  128 ++
 drivers/reset/reset-lpc18xx.c                   |  258 ++++
 drivers/reset/reset-socfpga.c                   |   19 +-
 drivers/reset/reset-zynq.c                      |  155 ++
 drivers/reset/sti/reset-stih407.c               |    4 +-
 drivers/reset/sti/reset-stih415.c               |    4 +-
 drivers/reset/sti/reset-stih416.c               |    4 +-
 drivers/soc/Makefile                            |    1 +
 drivers/soc/dove/Makefile                       |    1 +
 drivers/soc/dove/pmu.c                          |  412 ++++++
 drivers/soc/qcom/Kconfig                        |   31 +
 drivers/soc/qcom/Makefile                       |    3 +
 drivers/soc/qcom/smd-rpm.c                      |  244 ++++
 drivers/soc/qcom/smd.c                          | 1319 ++++++++++++++++++
 drivers/soc/qcom/smem.c                         |  775 ++++++++++
 drivers/soc/tegra/Makefile                      |    6 +-
 drivers/soc/tegra/common.c                      |    2 +
 drivers/soc/tegra/fuse/Makefile                 |    2 +
 drivers/soc/tegra/fuse/fuse-tegra.c             |  257 +++-
 drivers/soc/tegra/fuse/fuse-tegra20.c           |  175 +--
 drivers/soc/tegra/fuse/fuse-tegra30.c           |  232 ++-
 drivers/soc/tegra/fuse/fuse.h                   |   95 +-
 drivers/soc/tegra/fuse/speedo-tegra114.c        |   22 +-
 drivers/soc/tegra/fuse/speedo-tegra124.c        |   26 +-
 drivers/soc/tegra/fuse/speedo-tegra20.c         |   28 +-
 drivers/soc/tegra/fuse/speedo-tegra210.c        |  184 +++
 drivers/soc/tegra/fuse/speedo-tegra30.c         |   48 +-
 drivers/soc/tegra/fuse/tegra-apbmisc.c          |   76 +-
 drivers/soc/tegra/pmc.c                         |  125 +-
 include/dt-bindings/memory/tegra210-mc.h        |   36 +
 .../stih407-resets.h                            |    0
 .../stih415-resets.h                            |    0
 .../stih416-resets.h                            |    0
 include/linux/clk/shmobile.h                    |   12 +
 include/linux/soc/dove/pmu.h                    |    6 +
 include/linux/soc/qcom/smd-rpm.h                |   35 +
 include/linux/soc/qcom/smd.h                    |   46 +
 include/linux/soc/qcom/smem.h                   |   11 +
 include/soc/tegra/fuse.h                        |    6 +-
 include/soc/tegra/mc.h                          |    2 +
 include/soc/tegra/pmc.h                         |    5 +
 88 files changed, 6781 insertions(+), 498 deletions(-)
 create mode 100644 Documentation/devicetree/bindings/cpufreq/tegra124-cpufreq.txt
 create mode 100644 Documentation/devicetree/bindings/memory-controllers/arm,pl172.txt
 create mode 100644 Documentation/devicetree/bindings/reset/ath79-reset.txt
 create mode 100644 Documentation/devicetree/bindings/reset/nxp,lpc1850-rgu.txt
 create mode 100644 Documentation/devicetree/bindings/reset/zynq-reset.txt
 create mode 100644 Documentation/devicetree/bindings/soc/qcom,smd-rpm.txt
 create mode 100644 Documentation/devicetree/bindings/soc/qcom/qcom,smd.txt
 create mode 100644 drivers/cpufreq/tegra124-cpufreq.c
 rename drivers/cpufreq/{tegra-cpufreq.c => tegra20-cpufreq.c} (100%)
 create mode 100644 drivers/memory/pl172.c
 create mode 100644 drivers/memory/tegra/tegra210.c
 create mode 100644 drivers/reset/reset-ath79.c
 create mode 100644 drivers/reset/reset-lpc18xx.c
 create mode 100644 drivers/reset/reset-zynq.c
 create mode 100644 drivers/soc/dove/Makefile
 create mode 100644 drivers/soc/dove/pmu.c
 create mode 100644 drivers/soc/qcom/smd-rpm.c
 create mode 100644 drivers/soc/qcom/smd.c
 create mode 100644 drivers/soc/qcom/smem.c
 create mode 100644 drivers/soc/tegra/fuse/speedo-tegra210.c
 create mode 100644 include/dt-bindings/memory/tegra210-mc.h
 rename include/dt-bindings/{reset-controller => reset}/stih407-resets.h (100%)
 rename include/dt-bindings/{reset-controller => reset}/stih415-resets.h (100%)
 rename include/dt-bindings/{reset-controller => reset}/stih416-resets.h (100%)
 create mode 100644 include/linux/soc/dove/pmu.h
 create mode 100644 include/linux/soc/qcom/smd-rpm.h
 create mode 100644 include/linux/soc/qcom/smd.h
 create mode 100644 include/linux/soc/qcom/smem.h


From olof at lixom.net  Mon Aug 31 17:07:10 2015
From: olof at lixom.net (Olof Johansson)
Date: Mon, 31 Aug 2015 17:07:10 -0700
Subject: [GIT PULL 7/7] ARM: SoC 64-bit changes for v4.3
In-Reply-To: <1441066030-23225-1-git-send-email-olof@lixom.net>
References: <1441066030-23225-1-git-send-email-olof@lixom.net>
Message-ID: <1441066030-23225-8-git-send-email-olof@lixom.net>

Here's our branch of ARM64 contents for this merge window.

Most of this is DT contents for new SoCs (or those who have seen new
device support added). Maybe we should stop separating out the arm64
contents here to avoid the kind of internal conflicts as we got this
time around, where 32- and 64-bit contents conflicted.

Anyhow, on the actual contents:

New SoCs:

- Broadcom North Star 2 (ns2)
- Marvell Berlin4CT
- Mediatek MT6795
- Rockchip RK3368

In addition, there are enhancements for the following platforms:

- Mediatek MT8173: cpuidle-dt updates, misc other additions
- ZyncMP: A bunch of devices added to the existing DTSI
- Qualcomm MSM8916 and APQ8016 updates for USB, etc.

+ A handful of other updates for various platforms


Conflicts:

Documentation/devicetree/bindings/serial/mtk-uart.txt:

Add/add conflict with 32-bit DT additions of MT6795 and 64-bit addition
of MT8173.
Keep both sides, which means rewrapping the last line. Entries are
sorted in decreasing order, which is a bit unusual.

----------------------------------------------------------------

The following changes since commit c055798226422b953ee59e68ba33f4a9bfc894bb:

  Merge branch 'next/defconfig' into HEAD

are available in the git repository at:

  git://git.kernel.org/pub/scm/linux/kernel/git/arm/arm-soc.git tags/armsoc-arm64

for you to fetch changes up to 341a670abd1c086d44e09901f0ebee3dd86a60ba:

  ARM64: dts: vexpress: Use assigned-clock-parents for sp810

----------------------------------------------------------------

Chunyan Zhang (1):
      arm64: dts: sprd: adding ETM entries to Spreadtrum SC9836

Eddie Huang (4):
      arm64: dts: mt8173: Add watchdog device node
      arm64: dts: mt8173: Add I2C device node
      arm64: dts: mt8173-evb: Add PMIC support
      arm64: dts: mediatek: Add MT8173 MMC dts

Heiko Stuebner (11):
      clk: rockchip: rk3288: add CLK_SET_RATE_PARENT to sclk_mac
      clk: rockchip: fix faulty vip parent name on rk3288
      clk: rockchip: protect register macros against multipart values
      clk: rockchip: add COMPOSITE_NOGATE_DIVTBL variant
      clk: rockchip: add support for phase inverters
      clk: rockchip: fix issues in the mmc-phase clock
      clk: rockchip: define the inverters of rk3066/rk3188 and rk3288
      dt-bindings: add documentation of rk3668 clock controller
      clk: rockchip: add dt-binding header for rk3368
      clk: rockchip: add missing include guards
      clk: rockchip: add rk3368 clock controller

Heiko St?bner (3):
      arm64: add Rockchip architecture entry
      arm64: defconfig: enable ARCH_ROCKCHIP
      arm64: dts: add Rockchip rk3368 core dtsi and board dts for the r88 board

Henry Chen (1):
      dts: mt8173-evb: Add da9211 to i2c1

Howard Chen (1):
      ARM: dts: mt8173: support arm64 cpuidle-dt

Ivan T. Ivanov (6):
      arm64: dts: qcom: Extend msm8916 pinctrl device coverage
      arm64: dts: qcom: Add msm8916 BLSP device nodes
      arm64: dts: qcom: Add msm8916 USB configuration nodes
      arm64: dts: qcom: apq8016-sbc: Don't hog client driver pins
      arm64: dts: qcom: Fix apq8016-sbc board USB related pin definitions
      arm64: dts: qcom: Add apq8016-sbc board LED's related device nodes

Jisheng Zhang (3):
      arm64: dts: Add dts files for Marvell Berlin4CT SoC
      arm64: Enable Marvell Berlin SoC family in Kconfig
      arm64: Enable Marvell Berlin SoC family in defconfig

Koro Chen (1):
      arm64: dts: mt8173: Add afe device node

Mars Cheng (2):
      Document: DT: Add bindings for mediatek MT6795 SoC Platform
      arm64: dts: mediatek: add mt6795 support

Michal Simek (10):
      ARM64: zynqmp: Use zynqmp specific compatible string for gpio
      ARM64: zynqmp: Add CANs node for platform
      ARM64: zynqmp: Add SMMU support
      ARM64: zynqmp: Add DWC3 usb support
      ARM64: zynqmp: Enable watchdog on ep108
      ARM64: zynqmp: Enable sdhci on ep108
      ARM64: zynqmp: Add eeprom memories on i2c bus
      ARM64: zynqmp: Enable spi flashes on ep108
      ARM64: zynqmp: Move uart and ttcs to the right location
      ARM64: zynqmp: Move SPI nodes to the right location

Olof Johansson (8):
      arm64: Split out platform options to separate Kconfig
      Merge branch 'depends/clk-rk3368' into next/arm64
      arm64: fix Kconfig include path
      Merge tag 'v4.2-next-arm64' of https://github.com/mbgg/linux-mediatek into next/arm64
      Merge tag 'qcom-arm64-for-4.3' of git://codeaurora.org/quic/kernel/agross-msm into next/arm64
      Merge tag 'zynqmp-dt-for-4.3' of https://github.com/Xilinx/linux-xlnx into next/arm64
      Merge tag 'v4.2-next-arm64-2' of https://github.com/mbgg/linux-mediatek into next/arm64
      Merge tag 'berlin64-for-v4.3-1' of git://git.infradead.org/users/hesselba/linux-berlin into next/arm64

Ray Jui (5):
      PCI: iproc: enable arm64 support for iProc PCIe
      PCI: iproc: Fix ARM64 dependency in Kconfig
      arm64: Add Broadcom iProc family support
      arm64: dts: Add Broadcom North Star 2 support
      PCI: iproc: Fix BCMA dependency in Kconfig

Sascha Hauer (4):
      arm64: dts: mt8173: Add clock controller device nodes
      arm64: dts: mt8173: Use real clock for UARTs
      arm64: dts: mt8173: Add PMIC wrapper device node
      ARM64: MediaTek MT8173: Add SCPSYS device node

Scott Shu (1):
      ARM64: dts: mt6795: enable basic SMP bringup for MT6795

Srinivas Kandagatla (1):
      arm64: dts: qcom: Add msm8916 sdhci configuration nodes

Stephen Boyd (1):
      ARM64: dts: vexpress: Use assigned-clock-parents for sp810

Suneel Garapati (1):
      devicetree: xilinx: zynqmp: add sata node


 .../devicetree/bindings/arm/bcm/ns2.txt         |   9 +
 .../devicetree/bindings/arm/mediatek.txt        |   9 +-
 .../bindings/arm/mediatek/mediatek,sysirq.txt   |   3 +-
 .../bindings/clock/rockchip,rk3368-cru.txt      |  61 ++
 .../devicetree/bindings/serial/mtk-uart.txt     |   5 +-
 arch/arm64/Kconfig                              | 105 +--
 arch/arm64/Kconfig.platforms                    | 125 +++
 arch/arm64/boot/dts/Makefile                    |   3 +
 arch/arm64/boot/dts/arm/juno-motherboard.dtsi   |   2 +
 .../arm64/boot/dts/arm/rtsm_ve-motherboard.dtsi |   2 +
 arch/arm64/boot/dts/broadcom/Makefile           |   5 +
 arch/arm64/boot/dts/broadcom/ns2-svk.dts        |  59 ++
 arch/arm64/boot/dts/broadcom/ns2.dtsi           | 118 +++
 arch/arm64/boot/dts/marvell/Makefile            |   5 +
 arch/arm64/boot/dts/marvell/berlin4ct-dmp.dts   |  66 ++
 arch/arm64/boot/dts/marvell/berlin4ct.dtsi      | 164 ++++
 arch/arm64/boot/dts/mediatek/Makefile           |   1 +
 arch/arm64/boot/dts/mediatek/mt6795-evb.dts     |  41 +
 arch/arm64/boot/dts/mediatek/mt6795.dtsi        | 175 ++++
 arch/arm64/boot/dts/mediatek/mt8173-evb.dts     | 353 ++++++++
 arch/arm64/boot/dts/mediatek/mt8173.dtsi        | 327 ++++++-
 .../boot/dts/qcom/apq8016-sbc-pmic-pins.dtsi    |  34 +-
 .../boot/dts/qcom/apq8016-sbc-soc-pins.dtsi     |  14 +-
 arch/arm64/boot/dts/qcom/apq8016-sbc.dtsi       |  51 ++
 arch/arm64/boot/dts/qcom/msm8916-pins.dtsi      | 430 +++++++++
 arch/arm64/boot/dts/qcom/msm8916.dtsi           | 227 ++++-
 arch/arm64/boot/dts/rockchip/Makefile           |   5 +
 arch/arm64/boot/dts/rockchip/rk3368-r88.dts     | 354 ++++++++
 arch/arm64/boot/dts/rockchip/rk3368.dtsi        | 900 +++++++++++++++++++
 arch/arm64/boot/dts/sprd/sc9836.dtsi            |  99 +-
 arch/arm64/boot/dts/xilinx/zynqmp-ep108.dts     |  89 ++
 arch/arm64/boot/dts/xilinx/zynqmp.dtsi          | 233 +++--
 arch/arm64/configs/defconfig                    |   4 +
 drivers/clk/rockchip/Makefile                   |   2 +
 drivers/clk/rockchip/clk-inverter.c             | 116 +++
 drivers/clk/rockchip/clk-mmc-phase.c            |   6 +-
 drivers/clk/rockchip/clk-rk3188.c               |   9 +-
 drivers/clk/rockchip/clk-rk3288.c               |  13 +-
 drivers/clk/rockchip/clk-rk3368.c               | 881 ++++++++++++++++++
 drivers/clk/rockchip/clk.c                      |   7 +
 drivers/clk/rockchip/clk.h                      |  72 +-
 drivers/pci/host/Kconfig                        |   4 +-
 drivers/pci/host/pcie-iproc.c                   |  27 +-
 drivers/pci/host/pcie-iproc.h                   |   4 +-
 include/dt-bindings/clock/rk3066a-cru.h         |   5 +
 include/dt-bindings/clock/rk3188-cru-common.h   |   5 +
 include/dt-bindings/clock/rk3188-cru.h          |   5 +
 include/dt-bindings/clock/rk3288-cru.h          |   5 +
 include/dt-bindings/clock/rk3368-cru.h          | 384 ++++++++
 49 files changed, 5341 insertions(+), 282 deletions(-)
 create mode 100644 Documentation/devicetree/bindings/arm/bcm/ns2.txt
 create mode 100644 Documentation/devicetree/bindings/clock/rockchip,rk3368-cru.txt
 create mode 100644 arch/arm64/Kconfig.platforms
 create mode 100644 arch/arm64/boot/dts/broadcom/Makefile
 create mode 100644 arch/arm64/boot/dts/broadcom/ns2-svk.dts
 create mode 100644 arch/arm64/boot/dts/broadcom/ns2.dtsi
 create mode 100644 arch/arm64/boot/dts/marvell/Makefile
 create mode 100644 arch/arm64/boot/dts/marvell/berlin4ct-dmp.dts
 create mode 100644 arch/arm64/boot/dts/marvell/berlin4ct.dtsi
 create mode 100644 arch/arm64/boot/dts/mediatek/mt6795-evb.dts
 create mode 100644 arch/arm64/boot/dts/mediatek/mt6795.dtsi
 create mode 100644 arch/arm64/boot/dts/qcom/msm8916-pins.dtsi
 create mode 100644 arch/arm64/boot/dts/rockchip/Makefile
 create mode 100644 arch/arm64/boot/dts/rockchip/rk3368-r88.dts
 create mode 100644 arch/arm64/boot/dts/rockchip/rk3368.dtsi
 create mode 100644 drivers/clk/rockchip/clk-inverter.c
 create mode 100644 drivers/clk/rockchip/clk-rk3368.c
 create mode 100644 include/dt-bindings/clock/rk3368-cru.h


From olof at lixom.net  Mon Aug 31 17:07:09 2015
From: olof at lixom.net (Olof Johansson)
Date: Mon, 31 Aug 2015 17:07:09 -0700
Subject: [GIT PULL 6/7] ARM: SoC defconfig updates for v4.3
In-Reply-To: <1441066030-23225-1-git-send-email-olof@lixom.net>
References: <1441066030-23225-1-git-send-email-olof@lixom.net>
Message-ID: <1441066030-23225-7-git-send-email-olof@lixom.net>

We mostly keep defconfigs updates on a separate branch due to their tendency
to conflict between platforms and this encourages more careful separation of
code changes and config changes.

Most updates here are minor tweaks, enabling new drivers for various platforms,
and so on. Renesas also removed one defconfig (marzen_defconfig).

----------------------------------------------------------------

The following changes since commit 64e21c2bcc7dcc916c5cdcd9e612fc23891f8e23:

  Merge branch 'next/dt' into HEAD

are available in the git repository at:

  git://git.kernel.org/pub/scm/linux/kernel/git/arm/arm-soc.git tags/armsoc-defconfig

for you to fetch changes up to ba5d183bced6cb60b2838a0bf04665c1c1e4bff1:

  Merge tag 'tegra-for-4.3-defconfig' of git://git.kernel.org/pub/scm/linux/kernel/git/tegra/linux into next/defconfig

----------------------------------------------------------------

Alexandre Belloni (1):
      ARM: at91/defconfig: at91_dt: remove ARM_AT91_ETHER

Barry Song (5):
      ARM: prima2_defconfig: fix the outdated defconfig
      ARM: prima2_defconfig: enable build for SiRFSoC SDHC host
      ARM: prima2_defconfig: enable build for misc input
      ARM: prima2_defconfig: enable build for RTC
      ARM: prima2_defconfig: enable build for hwspinlock

Baruch Siach (1):
      ARM: multi_v7_defconfig: enable Conexant Digicolor watchdog

Chen-Yu Tsai (2):
      ARM: sunxi_defconfig: Enable DMA_SUN6I, P2WI, PWM, cryptodev, EXTCON, FHANDLE
      ARM: multi_v7_defconfig: Enable Allwinner P2WI, PWM, DMA_SUN6I, cryptodev

Fabio Estevam (4):
      ARM: imx_v6_v7_defconfig: Enable kexec support
      ARM: imx_v6_v7_defconfig: Select HCIUART_H4
      ARM: imx_v6_v7_defconfig: Select CONFIG_IKCONFIG_PROC
      ARM: multi_v7_defconfig: Select MX6UL and MX7D

Frank Li (2):
      ARM: imx_v6_v7_defconfig: enable powerkey and syscon power off
      ARM: imx: imx_v6_v7_defconfig enable imx6ul support

Josh Wu (2):
      ARM: at91: at91_dt_defconfig: enable ISI and ov2640 support
      ARM: at91/defconfig: at91_dt: enable DRM hlcdc support

Kuninori Morimoto (2):
      ARM: shmobile: defconfig: add Renesas DPCM Sound Card
      ARM: multi_v7_defconfig: add Renesas DPCM Sound Card

Lee Jones (2):
      ARM: multi_v7_defconfig: Enable ST's PWM driver
      ARM: multi_v7_defconfig: Enable support for PWM Regulators

Linus Walleij (7):
      ARM: ep93xx: activate NO_HZ and high-res timers
      ARM: ep93xx: enable all boards in the EP93xx defconfig
      ARM: ep93xx: enable SIM.ONE MMC/SD hardware
      ARM: ep93xx: add LEDs and triggers to defconfig
      ARM: ep93xx: add GPIO I2C to defconfig
      ARM: ep93xx: add DMA engine to the defconfig
      ARM: ep93xx: add framebuffer to the defconfig

Magnus Damm (1):
      ARM: shmobile: Remove marzen_defconfig

Masahiro Yamada (1):
      ARM: multi_v7_defconfig: enable UniPhier UART driver

Nicolas Pitre (1):
      ARM: add TC2 PM support to multi_v7_defconfig

Olof Johansson (12):
      Merge tag 'mvebu-config-4.3-1' of git://git.infradead.org/linux-mvebu into next/defconfig
      Merge tag 'ep93xx-defconfig' of git://git.kernel.org/.../linusw/linux-integrator into next/defconfig
      Merge tag 'omap-for-v4.3/defconfig-signed' of git://git.kernel.org/.../tmlind/linux-omap into next/defconfig
      Merge tag 'sti-defconfig-for-v4.3-1' of https://git.kernel.org/.../mcoquelin/sti into next/defconfig
      Merge tag 'renesas-defconfig-for-v4.3' of git://git.kernel.org/.../horms/renesas into next/defconfig
      Merge tag 'prima2-defconfig-for-4.2' of git://git.kernel.org/.../baohua/linux into next/defconfig
      Merge tag 'renesas-defconfig2-for-v4.3' of git://git.kernel.org/.../horms/renesas into next/defconfig
      Merge tag 'qcom-defconfig-for-4.3' of git://codeaurora.org/quic/kernel/agross-msm into next/defconfig
      Merge tag 'mvebu-config-4.3-2' of git://git.infradead.org/linux-mvebu into next/defconfig
      Merge tag 'sunxi-defconfig-for-4.3' of https://git.kernel.org/.../mripard/linux into next/defconfig
      Merge tag 'imx-defconfig-4.3' of git://git.kernel.org/.../shawnguo/linux into next/defconfig
      Merge tag 'tegra-for-4.3-defconfig' of git://git.kernel.org/.../tegra/linux into next/defconfig

Roger Shimizu (1):
      ARM: defconfig: orion5x: add DT support

Sekhar Nori (4):
      ARM: omap2plus_defconfig: enable support for TI ADC
      ARM: omap2plus_defconfig: enable support for TI touchscreen
      ARM: omap2plus_defconfig: enable support for TI CPTS
      ARM: omap2plus_defconfig: enable support for M25P80 SPI NOR

Shengjiu Wang (1):
      ARM: imx_v6_v7_defconfig: build in audio driver

Simon Horman (3):
      ARM: shmobile: Enable gose board in multiplatform defconfig
      ARM: multi_v7_defconfig: Enable shmobile r8a7793/gose platform
      ARM: shmobile: Enable fixed voltage regulator in shmobile_defconfig

Stephen Boyd (1):
      ARM: qcom_defconfig: Enable options for KS8851 ethernet

Thierry Reding (1):
      ARM: tegra: Update multi_v7_defconfig

Thomas Petazzoni (1):
      ARM: mvebu: update mvebu_v7_defconfig with features needed for Armada 388 GP

Tuomas Tynkkynen (1):
      ARM: tegra: Update default configuration


 arch/arm/configs/at91_dt_defconfig   |  13 +++-
 arch/arm/configs/ep93xx_defconfig    |  29 ++++++-
 arch/arm/configs/imx_v6_v7_defconfig |  31 ++++----
 arch/arm/configs/marzen_defconfig    | 124 ------------------------------
 arch/arm/configs/multi_v7_defconfig  |  23 ++++++
 arch/arm/configs/mvebu_v7_defconfig  |   4 +
 arch/arm/configs/omap2plus_defconfig |   7 ++
 arch/arm/configs/orion5x_defconfig   |   3 +
 arch/arm/configs/prima2_defconfig    |  12 +--
 arch/arm/configs/qcom_defconfig      |   3 +
 arch/arm/configs/shmobile_defconfig  |   3 +
 arch/arm/configs/sunxi_defconfig     |  10 ++-
 arch/arm/configs/tegra_defconfig     |   9 +--
 13 files changed, 118 insertions(+), 153 deletions(-)
 delete mode 100644 arch/arm/configs/marzen_defconfig


From olof at lixom.net  Mon Aug 31 17:07:08 2015
From: olof at lixom.net (Olof Johansson)
Date: Mon, 31 Aug 2015 17:07:08 -0700
Subject: [GIT PULL 5/7] ARM: DT updates for v4.3
In-Reply-To: <1441066030-23225-1-git-send-email-olof@lixom.net>
References: <1441066030-23225-1-git-send-email-olof@lixom.net>
Message-ID: <1441066030-23225-6-git-send-email-olof@lixom.net>

Ladies and gentlemen, we proudly announce to you the latest branch of ARM
device tree contents for the mainline kernel. Come and see, come and see!

No less than twentythree thousand lines of additions! Just imagine the
joy you will have of using your mainline kernel on newly supported
hardware such as Rockchip Chromebooks, Freescale i.MX6UL boards or
UniPhier hardware!

For those of you feeling less adventurous, added hardware support on
platforms such as TI DM814x and Gumstix Overo platforms might be more
of your liking.

We've got something for everyone here!

Ahem. Cough. So, anyway...

This is the usual large batch of DT updates. Lots and lots of smaller
changes, some of the larger ones to point out are:

- Rockchip veyron (Chromebook) support, as well as several other new boards
- DRM support on Atmel AT91SAM9N12EK
- USB additions on some Allwinner platforms
- Freescale i.MX6UL support
- Cleanups for Renesas shmobile platforms
- Lots of added devices on LPC18xx
- Lots of added devices and boards on UniPhier

There's also some dependent code added here, in particular some branches
that are primarily merged through the clock tree.


Conflicts:

arch/arm/boot/dts/imx6qdl-gw5*xx.dtsi:

Change/add conflict with DT fix merged through MMC tree.
Keep the GPIO piece from HEAD, pinctrl pieces from branch.

----------------------------------------------------------------

The following changes since commit df782b553c2914d98f86b1a54eb51fcb7c208a4d:

  Merge branch 'next/drivers' into HEAD

are available in the git repository at:

  git://git.kernel.org/pub/scm/linux/kernel/git/arm/arm-soc.git tags/armsoc-dt

for you to fetch changes up to 4c80a00388dd7b9d9e7ebf31e62b96c7b74178b8:

  Merge tag 'v4.3-rockchip32-dts3' of git://git.kernel.org/pub/scm/linux/kernel/git/mmind/linux-rockchip into next/dt

----------------------------------------------------------------

Adam YH Lee (2):
      ARM: dts: overo: Enable McBSP2 for all Overo COMs
      ARM: dts: overo: Add device tree for Palo35 board

Alex Wilson (1):
      ARM: zynq: DT: Add missing interrupt for L2 pl310

Alexandre Belloni (17):
      ARM: at91/dt: sama5d4: fix external trigger property
      ARM: at91/dt: sama5d4: move ADC pinctrl to board device trees
      Documentation: dt: atmel-at91: add clocks to system timer, rstc and shdwc
      Documentation: watchdog: at91sam9_wdt: add clocks property
      Documentation: dt: rtc: at91rm9200: add clocks property
      ARM: at91/dt: at91rm9200: use slow clock where necessary
      ARM: at91/dt: at91sam9260: use slow clock where necessary
      ARM: at91/dt: at91sam9261: use slow clock where necessary
      ARM: at91/dt: at91sam9263: use slow clock where necessary
      ARM: at91/dt: at91sam9g45: use slow clock where necessary
      ARM: at91/dt: at91sam9n12: use slow clock where necessary
      ARM: at91/dt: at91sam9rl: use slow clock where necessary
      ARM: at91/dt: at91sam9x5: use slow clock where necessary
      ARM: at91/dt: sama5d3: use slow clock where necessary
      ARM: at91/dt: sama5d4: use slow clock where necessary
      ARM: at91/dt: at91sam9x5dm: add support for the touschscreen
      ARM: at91/dt: sama5d2: use slow clock where necessary

Alexandre Courbot (2):
      ARM: tegra: Add IOMMU node to GK20A
      ARM: tegra: jetson-tk1: Add GK20A GPU DT node

Alexandru M Stan (3):
      ARM: dts: rockchip: add shared rk3288-veyron files
      ARM: dts: rockchip: add veyron-jerry board
      ARM: dts: rockchip: add veyron-minnie board

Alison Wang (1):
      ARM: dts: ls1021a: Add dts nodes for audio on LS1021A

Anand Moon (5):
      ARM: dts: Enable USB3 regulators for exynos5422-odroidxu3
      ARM: dts: Add pwm-fan node for exynos5422-odroidxu3
      ARM: dts: Enable TMU for exynos5422-odroidxu3
      ARM: dts: Define default thermal-zones for exynos5422
      ARM: dts: Enable thermal-zones for exynos5422-odroidxu3

Andreas Faerber (1):
      ARM: dts: Clean up indentation for exynos5410-smdk5410

Andy Sun (1):
      ARM: dts: atlas7: add a GPIO key for rearview button

Anson Huang (4):
      ARM: dts: imx6sx: correct property name for wakeup source
      ARM: dts: imx6ul: enable GPC as extended interrupt controller
      ARM: dts: imx6ul: add RTC support
      ARM: dts: imx6ul: add snvs power key support

Anthoine Bourgeois (7):
      ARM: dts: omap3-devkit8000: Add user button support
      ARM: dts: omap3-devkit8000: Add PMU stat support
      ARM: dts: omap3-devkit8000: Add keymap support
      ARM: dts: omap3-devkit8000: Add S-video output support
      ARM: dts: omap3-devkit8000: Add DSS' DVI support
      ARM: dts: omap3-devkit8000: add LCD panels
      ARM: dts: omap3-devkit8000: Add ADS7846 Touchscreen support

Aparna Balasubramanian (1):
      ARM: dts: omap5-uevm: Add Palmas power button support

Ariel D'Alessandro (2):
      ARM: dts: lpc4350-hitex-eval: add pinctrl and uart0 muxing
      ARM: dts: lpc4350-hitex-eval: add ethernet

Ash Charles (2):
      ARM: dts: Add DTS for Gumstix TobiDuo expansion board
      ARM: dts: overo: Support PoP NAND

Balaji T K (1):
      ARM: dts: dra7-evm: add evm_3v3_sd regulator

Baruch Siach (2):
      ARM: digicolor: enable watchdog device
      ARM: digicolor: dts: use stdout-path for console configuration

Benjamin Cama (1):
      ARM: dts: Convert Linkstation Mini to Device Tree

Bjorn Andersson (3):
      ARM: dts: qcom: Replace gpio node with pinctrl node
      ARM: dts: msm8974: Add tcsr mutex node
      ARM: dts: msm8974: Add smem reservation and node

Bo Shen (1):
      ARM: at91/dt: add drm support for at91sam9n12ek

Boris Brezillon (5):
      Documentation: dt: atmel-at91: add slow clock to tcb
      ARM: at91/dt: define hlcdc node in at91sam9x5_lcd.dtsi
      ARM: at91/dt: include lcd dtsi in at91sam9x5 dtsis
      ARM: at91/dt: add at91sam9x5-ek Display Module dtsi
      ARM: at91/dt: enable lcd support for at91sam9x5 SoCs

Brian Norris (2):
      ARM: dts: rockchip: correct regulator PM properties
      ARM: dts: rockchip: correct regulator power states for suspend

Chen-Yu Tsai (4):
      ARM: dts: sun8i: Add support for USB controllers on A23/A33
      ARM: dts: sun8i: sina33: Enable USB hosts
      ARM: dts: sun5i: hsg-h702: Enable side volume buttons with LRADC
      ARM: dts: sun5i: hsg-h702: Enable USB OTG controller

Chris Zhong (1):
      ARM: dts: Add sbs-battery dts fragment used by chromebooks

Claudiu Manoil (2):
      ARM: dts: ls1021a: Add the eTSEC controller nodes
      ARM: dts: ls1021a: Enable the eTSEC ports on QDS and TWR

Cory Tusar (4):
      ARM: dts: vf610: Extend I2C support to all available buses.
      ARM: dts: vf610: Add missing QuadSPI register mapping and names.
      ARM: dts: vfxxx: Include support for qspi1 functionality.
      ARM: dts: vfxxx: Include support for esdhc0 functionality.

Dalon Westergreen (1):
      ARM: dts: socfpga: Add support of Terasic DE0 Atlas board

Daniel Thompson (1):
      ARM: dts: stm32f429: Adopt STM32F4 clock driver

Dave Gerlach (3):
      ARM: OMAP2+: Use pdata-quirks for wkup_m3 reset management
      ARM: dts: am43xx: Introduce MUX_MODE9 for pinctrl
      ARM: dts: am437x-gp-evm: Add regulator-always-on and regulator-boot-on for RTC DCDCs

Dinh Nguyen (8):
      ARM: dts: socfpga: enable the data and instruction prefetch for the l2 cache
      ARM: dts: socfpga: use stdout-path for chosen node
      ARM: socfpga: dts: Correct the parent clock for l3_sp_clk and dbg_clk
      ARM: socfpga: dts: Fix gpio dts entry for the correct clock
      ARM: socfpga: dts: add osc1 as a possible parent for dbg_base_clk
      dt-bindings: Add reset manager offsets for Arria10
      ARM: socfpga: dts: add "altr,modrst-offset" property
      ARM: socfpga: dts: Add resets for EMACs on Arria10

Dongli Li (1):
      ARM: dts: atlas7: add lost G2D node

Eric Anholt (2):
      ARM: bcm2835: Add the firmware driver information to the RPi DT
      dt/bindings: Add binding for the Raspberry Pi firmware driver

Ezequiel Garcia (2):
      of: add vendor prefix for CIAA project
      ARM: dts: add DT for CIAA LPC4337 industrial computer

Ezra Savard (1):
      ARM: zynq: DT: Add zc702 pushbuttons to DT as gpio-keys

Fabien Dessenne (1):
      ARM: DT: STiH410: Add bdisp dt nodes

Fabio Estevam (8):
      clk: imx: clk-imx6q: Provide initial IPU clock settings for mx6dl
      ARM: dts: imx6sl-warp: Add the SD2_RESET pin
      ARM: dts: imx6qdl-sabreauto: Add HDMI support
      ARM: dts: imx6qdl-sabresd: Allow HDMI and LVDS to work simultaneously
      ARM: dts: imx6sl-warp: Add changes for rev1.12
      ARM: dts: imx6qdl-sabrelite: Allow HDMI and LVDS to work simultaneously
      ARM: dts: imx6qdl-nitrogen6x: Allow HDMI and LVDS to work simultaneously
      ARM: dts: imx6qdl-sabreauto: Allow HDMI and LVDS to work simultaneously

Felipe Balbi (2):
      ARM: dts: am4372: Add named interrupt property for dwc3
      arm: boot: dts: am4372: add ARM timers and SCU nodes

Felix Fietkau (1):
      ARM: BCM5301X: Add profiling support

Frank Li (12):
      clk: imx: add imx6ul clk tree support
      ARM: dts: imx7d: add watch dog support
      ARM: dts: imx6sx: enable snvs power key
      ARM: dts: imx7d: add cortex-a7 coresight component
      Document: dt: binding: imx: update document for imx6ul support
      ARM: dts: add i.mx6ul pin function include file
      ARM: dts: imx: add imx6ul and imx6ul evk board support
      ARM: dts: imx: update snvs to use syscon access register
      ARM: dts: imx6ul: add usb host and function support
      ARM: dts: imx6ul: fix low case define in imx6ul-pinfunc.h
      ARM: dts: imx6ul: add qspi support
      ARM: dts: imx7d: enable snvs rtc, onoffkey and power off

Fugang Duan (3):
      ARM: dts: omap3: correct the format of u16 values for tsc2046 node
      ARM: dts: imx: add fec1 and fec2 nodes for SOC i.MX6UL
      ARM: dts: imx6ul-14x14-evk: add fec1 and fec2 support

Gabriel Fernandez (1):
      ARM: STi: DT: Rename st_pll3200c32_407_c0_x into st_pll3200c32_cx_x

Geert Uytterhoeven (16):
      ARM: shmobile: armadillo800eva dts: Add pinctrl and gpio-hog for lcdc0
      ARM: shmobile: r8a73a4 dtsi: Use "arm,gic-400" for GIC
      ARM: shmobile: r8a7790 dtsi: Use "arm,gic-400" for GIC
      ARM: shmobile: r8a7791 dtsi: Use "arm,gic-400" for GIC
      ARM: shmobile: r8a7793 dtsi: Use "arm,gic-400" for GIC
      ARM: shmobile: r8a7794 dtsi: Use "arm,gic-400" for GIC
      ARM: shmobile: r8a73a4 dtsi: Add missing "gpio-ranges" to gpio node
      ARM: shmobile: r8a7740 dtsi: Add missing "gpio-ranges" to gpio node
      ARM: shmobile: sh73a0 dtsi: Add missing "gpio-ranges" to gpio node
      ARM: shmobile: r7s72100 dtsi: Add CPG/MSTP Clock Domain
      ARM: shmobile: r8a7778 dtsi: Add CPG/MSTP Clock Domain
      ARM: shmobile: r8a7779 dtsi: Add CPG/MSTP Clock Domain
      ARM: shmobile: r8a7790 dtsi: Add CPG/MSTP Clock Domain
      ARM: shmobile: r8a7791 dtsi: Add CPG/MSTP Clock Domain
      ARM: shmobile: r8a7793 dtsi: Add CPG/MSTP Clock Domain
      ARM: shmobile: r8a7794 dtsi: Add CPG/MSTP Clock Domain

Grazvydas Ignotas (4):
      ARM: dts: omap3-pandora: miscellaneous corrections
      ARM: dts: omap3-pandora: add support for usb host and 32k buffer
      ARM: OMAP2+: omap3-pandora: add backlight support
      ARM: OMAP2+: omap3-pandora: add wifi support

Gregory Fong (1):
      ARM: dts: brcmstb: add BCM7445 GPIO nodes

Guo Zeng (1):
      ARM: dts: atlas7: add lost PWM node

Haikun Wang (1):
      ARM: dts: ls1021a: Update 'dspi' device node compatible string

Hans de Goede (22):
      ARM: dts: sun4i: Add USB Dual Role Controller
      ARM: dts: sun5i: Add USB Dual Role Controller
      ARM: dts: sun6i: Add USB Dual Role Controller
      ARM: dts: sun8i: Add A23 usb-phy and otg nodes
      ARM: dts: sun8i: Add A33 usb-phy and otg nodes
      ARM: dts: sun4i: Enable USB DRC on Chuwi V7 CW0825
      ARM: dts: sun4i: Enable USB DRC on the Cubieboard
      ARM: dts: sun5i: Enable USB DRC on UTOO P66
      ARM: dts: sun6i: Enable USB DRC on the Mele A1000G quad
      ARM: dts: sun7i: Enable USB DRC on A20-OLinuxIno-Lime
      ARM: dts: sun7i: Enable USB DRC on A20-OLinuxIno-Micro
      ARM: dts: sun8i: Enable USB DRC on Ippo Q8H-A23 tablets
      ARM: dts: sun8i: Enable USB DRC on GA10H-A33 tablets
      ARM: dts: sun8i: Enable USB host on GA10H-A33 tablets
      ARM: sun8i: dts: Add Ippo-q8h v1.2 with A33
      ARM: dts: sunxi: Add regulator-boot-on to usb host port regulator nodes
      ARM: dts: sun4i: Enable otg controller on the ba10-tvbox
      ARM: dts: sun4i: Enable otg controller on the mini-x
      ARM: dts: sun6i: Enable otg controller on the cs908
      ARM: dts: sun5i: Enable USB DRC on A10s OLinuxIno Micro
      ARM: dts: sun8i: Enable USB DRC on Ippo Q8H-A33 tablet
      ARM: dts: sun7i: Change cubietruck wifi enable pin to use mmc-pwrseq

Hauke Mehrtens (1):
      ARM: BCM5301X: activate some additional options in pl310 cache controller

Heiko Stuebner (11):
      ARM: dts: rockchip: fix rk3288 watchdog irq
      dt-bindings: add vendor prefix for Netxeon Technology
      ARM: dts: rockchip: add Netxeon R89 board
      ARM: dts: rockchip: add veyron-pinky board
      ARM: dts: rockchip: add missing device_type = "memory" to boards
      dt-bindings: document rk3368 R88 board from Rockchip
      ARM: dts: rockchip: add rk3288 arm-pmu irq affinity
      ARM: dts: rockchip: set correct dwc2 params for cortex-a9 socs
      ARM: dts: rockchip: add usb phys to Cortex-A9 socs
      ARM: dts: rockchip: enable usb controller on marsboard
      ARM: dts: rockchip: reserve unusable memory region on rk3288

Huayi Li (1):
      ARM: dts: atlas7: put pinctl property to get pinmux for NAND

James Liao (1):
      ARM: dts: mediatek: Enable clock support for Mediatek MT8135.

Javier Martinez Canillas (4):
      ARM: dts: Include exynos5250-pinctrl after the nodes were defined for exynos5250
      ARM: dts: Extend exynos5250-pinctrl nodes using labels instead of paths
      ARM: dts: Include exynos5420-pinctrl after the nodes were defined for exynos5420
      ARM: dts: Extend exynos5420-pinctrl nodes using labels instead of paths

Joachim Eastwood (22):
      ARM: dts: lpc18xx: add cgu and ccu clock-controller nodes
      ARM: dts: lpc18xx: add uart new compat string and clk names
      ARM: dts: lpc18xx: add pinctrl node
      ARM: dts: lpc18xx: add gpio node
      ARM: dts: lpc18xx: add ssp nodes
      ARM: dts: lpc18xx: add can nodes
      ARM: dts: lpc18xx: add mmcsd node
      ARM: dts: lpc18xx: add creg (syscon) node
      ARM: dts: lpc18xx: add ethernet node
      ARM: dts: lpc18xx: add usb nodes
      ARM: dts: lpc4357-ea4357: add pinctrl and uart0 muxing
      ARM: dts: lpc4357-ea4357: add mmcsd
      ARM: dts: lpc4357-ea4357: add gpio joystick
      ARM: dts: lpc4357-ea4357: add ethernet
      ARM: dts: lpc4357-ea4357: add uart3
      ARM: dts: lpc18xx: add usb otg phy node
      ARM: dts: lpc18xx: add pl111 lcd controller node
      ARM: dts: lpc18xx: add pl172 memory-controller node
      ARM: dts: lpc4357-ea4357: add usb0
      ARM: dts: lpc4357-ea4357: add emc pins and static memory devices
      ARM: dts: lpc4357-ea4357: add mmio-gpio leds
      ARM: dts: lpc4350-hitex-eval: add emc pins and static memory devices

Josef Gajdusek (1):
      ARM: dts: sun4i: Add Iteaduino Plus A10

Josh Wu (2):
      ARM: at91/dt: add isi & ov2640 dt nodes for at91sam9m10g45ek board
      ARM: at91/dt: sama5: update rstc to correct compatible string

Jyri Sarha (1):
      ARM: dts: am335x-boneblack: Use new binding for HDMI

Karsten Merker (1):
      devicetree: Add msi to the vendor-prefix list

Keerthy (4):
      ARM: dts: AM437X: add dpll_clksel_mac_clk node
      ARM: dts: am4372: Set the default clock rate for dpll_clksel_mac_clk clock
      ARM: dts: AM4372: Reorder the rtc compatible string
      ARM: dts: AM4372: Add the am4372-rtc compatible string

Kishon Vijay Abraham I (5):
      ARM: dts: dra72-evm: add evm_3v3_sd regulator
      ARM: dts: dra72-evm: Set max clock frequency of MMC1 and MMC2
      ARM: dts: am57xx-beagle-x15: mmc1: remove redundant pbias-supply property
      ARM: dts: dra7-evm: Fix spurious card insert/removal interrupt
      ARM: dts: dra72-evm: Fix spurious card insert/removal interrupt

Krzysztof Kozlowski (2):
      ARM: dts: Set max17047 over heat and voltage thresholds for exynos4412-trats2
      ARM: dts: Use labels for overriding nodes for exynos4210-universal_c210

Kuninori Morimoto (6):
      ARM: shmobile: lager: add sound label on DTS
      ARM: shmobile: koelsch: add sound label on DTS
      ARM: shmobile: r8a7790: Add Audio CTU support on DTSI
      ARM: shmobile: r8a7790: Add Audio MIX support on DTSI
      ARM: shmobile: r8a7791: Add Audio CTU support on DTSI
      ARM: shmobile: r8a7791: Add Audio MIX support on DTSI

Kyle Huey (1):
      ARM: tegra: Add Tegra124 PMU support

Laurent Pinchart (1):
      ARM: shmobile: lager: Fix adv7511 IRQ sensing

Lee Jones (2):
      ARM: STi: STiH407: Move PWM nodes STiH407 => STiH407-family
      ARM: STi: STiH407: Add PWM Regulator node

Lily.Li (1):
      ARM: dts: atlas7: add lost jpeg node

Lucas Stach (1):
      ARM: dts: imx53-qsb: select open-drain mode for i2c1 pads

Ludovic Desroches (1):
      ARM: at91/dt: add basic dtsi for sama5d2 SoC

Magnus Damm (1):
      ARM: shmobile: r8a7779: Configure IRLM mode via DT

Mark Janssen (1):
      ARM: dts: sun5i: Enable USB DRC on A13 OLinuxIno

Mars Cheng (2):
      Document: DT: Add bindings for mediatek MT6580 SoC Platform
      ARM: dts: mediatek: add mt6580 basic support

Masahiro Yamada (9):
      ARM: dts: UniPhier: add on-chip UART device nodes
      ARM: dts: UniPhier: add USB EHCI device nodes
      ARM: dts: UniPhier: add pinctrl device nodes
      ARM: dts: UniPhier: add UART and USB pinmux nodes
      ARM: dts: uniphier: add I2C controller device nodes
      ARM: dts: uniphier: add PH1-Pro5 SoC support
      ARM: dts: uniphier: add ProXstream2 and PH1-LD6b SoC/board support
      ARM: dts: UniPhier: add reference daughter board
      ARM: dts: UniPhier: fix PPI interrupt CPU mask of timer nodes

Matthew Gerlach (1):
      ARM: socfpga: dts: add missing clock gates to socfpga.dtsi

Maxime Coquelin (2):
      ARM: dts: Add STM32429i-EVAL board support
      ARM: dts: Use stdout-path in STM32F429 Discovery board

Maxime Ripard (1):
      ARM: sunxi: dt: Convert users to the PIO interrupts binding

Michal Simek (1):
      ARM: dts: zynq: Add OCM node

Michal Suchanek (2):
      ARM: dts: axp152: Add a dtsi file for the axp152 pmic
      ARM: dts: A10s-OLinuxIno: Add a node for axp152 pmic

Mikhail Ulyanov (2):
      ARM: shmobile: r8a7790: Add JPU device node.
      ARM: shmobile: r8a7791: Add JPU device node.

Mikko Perttunen (2):
      clk: tegra: Introduce ability for SoC-specific reset control callbacks
      ARM: tegra: Add CPU regulator to the Jetson TK1 device tree

Moritz Fischer (1):
      ARM: dts: zynq: Add devicetree entry for Xilinx Zynq reset controller.

Nicolas Chauvet (1):
      ARM: tegra: Fix AHB base address on Tegra20, Tegra30 and Tegra114

Nicolas Ferre (2):
      ARM: at91/dt: add minimal sama5d2 Xplained board
      ARM: at91/dt: at91sam9x5dm: add QT1070 touch button controller

Nishanth Menon (2):
      pinctrl: dra: dt-bindings: Add virtual mode configuration option
      ARM: dts: dra7-evm: Add MMCSD card removal GPIO

Olof Johansson (33):
      Merge tag 'renesas-dt-for-v4.3' of git://git.kernel.org/.../horms/renesas into next/dt
      Merge tag 'omap-for-v4.3/dt-pt1' of git://git.kernel.org/.../tmlind/linux-omap into next/dt
      Merge branch 'lpc18xx_43xx_dts_4.3' of https://github.com/manabian/linux-lpc into next/dt
      Merge tag 'mvebu-dt-4.3-1' of git://git.infradead.org/linux-mvebu into next/dt
      Merge tag 'arm-soc/for-4.3/dts' of http://github.com/broadcom/stblinux into next/dt
      Merge tag 'v4.3-rockchip32-dts1' of git://git.kernel.org/.../mmind/linux-rockchip into next/dt
      Merge tag 'tags/pxa-dt-4.3' of https://github.com/rjarzmik/linux into next/dt
      Merge tag 'omap-for-v4.3/dt-pt2' of git://git.kernel.org/.../tmlind/linux-omap into next/dt
      Merge tag 'sti-dt-for-v4.3-1' of https://git.kernel.org/.../mcoquelin/sti into next/dt
      Merge tag 'stm32-dt-for-v4.3-1b' of https://git.kernel.org/.../mcoquelin/stm32 into next/dt
      Merge tag 'renesas-dt2-for-v4.3' of git://git.kernel.org/.../horms/renesas into next/dt
      Merge tag 'omap-for-v4.3/dt-dm814x' of git://git.kernel.org/.../tmlind/linux-omap into next/dt
      Merge tag 'v4.2-next-dts' of https://github.com/mbgg/linux-mediatek into next/dt
      Merge tag 'socfpga_dts_for_v4.3' of git://git.kernel.org/.../dinguyen/linux into next/dt
      Merge tag 'at91-dt' of git://git.kernel.org/.../nferre/linux-at91 into next/dt
      Merge tag 'qcom-dt-for-4.3' of git://codeaurora.org/quic/kernel/agross-msm into next/dt
      Merge tag 'zynq-dt-for-4.3' of https://github.com/Xilinx/linux-xlnx into next/dt
      Merge tag 'mvebu-dt-4.3-2' of git://git.infradead.org/linux-mvebu into next/dt
      Merge tag 'sunxi-dt-for-4.3' of https://git.kernel.org/.../mripard/linux into next/dt
      Merge tag 'samsung-dt-1' of git://git.kernel.org/.../kgene/linux-samsung into next/dt
      Merge tag 'sirf-dts-for-4.3' of git://git.kernel.org/.../baohua/linux into next/dt
      Merge tag 'omap-for-v4.3/dt-pt3' of git://git.kernel.org/.../tmlind/linux-omap into next/dt
      Merge tag 'renesas-dt3-for-v4.3' of git://git.kernel.org/.../horms/renesas into next/dt
      Merge tag 'at91-ab-dt2' of git://git.kernel.org/.../abelloni/linux into next/dt
      Merge tag 'mvebu-dt-4.3-3' of git://git.infradead.org/linux-mvebu into next/dt
      Merge tag 'v4.3-rockchip32-dts2' of git://git.kernel.org/.../mmind/linux-rockchip into next/dt
      Merge tag 'socfpga_dts_for_v4.3_part_2' of git://git.kernel.org/.../dinguyen/linux into next/dt
      Merge tag 'rpi-dt-for-armsoc-4.3' of git://git.kernel.org/.../rpi/linux-rpi into next/dt
      Merge tag 'imx-dt-4.3' of git://git.kernel.org/.../shawnguo/linux into next/dt
      Merge tag 'renesas-dt4-for-v4.3' of git://git.kernel.org/.../horms/renesas into next/dt
      Merge tag 'omap-for-v4.3/dt-pt4-v2' of git://git.kernel.org/.../tmlind/linux-omap into next/dt
      Merge tag 'tegra-for-4.3-dt' of git://git.kernel.org/.../tegra/linux into next/dt
      Merge tag 'v4.3-rockchip32-dts3' of git://git.kernel.org/.../mmind/linux-rockchip into next/dt

Paul Walmsley (1):
      clk: tegra: Add DFLL DVCO reset control for Tegra124

Peter Chen (1):
      ARM: imx6qdl-sabreauto.dtsi: enable USB support

Peter Griffin (11):
      ARM: STi: DT: Add STiH407 family tsin0 pinctrl configuration
      ARM: STi: DT: Add STiH407 family tsin1 pinctrl configuration
      ARM: STi: DT: Add STiH407 family tsin2 pinctrl configuration
      ARM: STi: DT: Add STiH407 family tsin3 pinctrl configuration
      ARM: STi: DT: Add STiH407 family tsin4 pinctrl configuration
      ARM: STi: DT: Add STiH407 family tsin5 pinctrl configuration
      ARM: STi: DT: Add STiH407 family tsout0 pinctrl configuration
      ARM: STi: DT: Add STiH407 family tsout1 pinctrl configuration
      ARM: STi: DT: Add STiH407 family mtsin0 pinctrl configuration
      ARM: STi: DT: STiH407: Add cpu-release-addr dt property.
      ARM: STi: DT: STiH418: Add cpu-release-addr dt property.

Peter Seiderer (2):
      ARM: dts: nitrogen6x: add CAN support
      ARM: dts: sabrelite: add CAN support

Peter Ujfalusi (21):
      ARM: dts: dra7x: Integrate sDMA crossbar
      ARM: omap2plus_defconfig: Enable audio related config options
      ARM: dts: am437x-sk-evm: Add sleep pin settings for mcasp1
      ARM: dts: am437x-sk-evm: Switch using simple-audio-card for audio support
      ARM: dts: am43xx-epos-evm: Add gpio-hog for configuring the display/audio mux
      ARM: dts: am43xx-epos-evm: Add regulator for VBAT and DCDC4 of tps65218
      ARM: dts: am43xx-epos-evm: McASP1 node for audio support
      ARM: dts: am43xx-epos-evm: Add node for tlv320aic3111 audio codec
      ARM: dts: am43xx-epos-evm: Enable analog audio via simple-card
      ARM: dts: am437x-gp-evm: Add gpio-hog for configuring the display/audio mux
      ARM: dts: am437x-gp-evm: Rename fixed regulator vmmcsd_fixed to evm_v3_3d
      ARM: dts: am437x-gp-evm: Add node for tlv320aic3106 audio codec
      ARM: dts: am437x-gp-evm: McASP1 node for audio support
      ARM: dts: am437x-gp-evm: Enable analog audio via simple-card
      ARM: dts: am335x-evmsk: Fix mcasp1 node's indentation
      ARM: dts: am335x-evmsk: Add sleep pin settings for mcasp1
      ARM: dts: am335x-evmsk: Switch using simple-audio-card for audio support
      ARM: dts: am335x-evm: Fix mcasp1 node's indentation
      ARM: dts: am335x-evm: Rename pinctrl section for McASP1
      ARM: dts: am335x-evm: Add sleep pin settings for mcasp1
      ARM: dts: am335x-evm: Switch using simple-audio-card for audio support

Philippe Reynes (1):
      ARM: dts: imx27: add support of internal rtc

Pramod Gurav (1):
      ARM: dts: apq8064: Add DT support for GSBI6 and for UART pin mux

Punnaiah Choudary Kalluri (1):
      Documentation: devicetree: Add ECC information to synopsys ddr controller

Qipan Li (1):
      ARM: dts: atlas7: add alias name for spi device

Rafa? Mi?ecki (1):
      ARM: BCM5301X: Enable UART0 on tested devices

Ray Jui (1):
      ARM: dts: enable clock support for Broadcom Cygnus

Remy van Elst (1):
      ARM: dts: sun4i: Enable USB DRC on A10 OLinuxIno Lime

Robert Jarzmik (6):
      ARM: dts: pxa: add dma controller
      ARM: dts: pxa: add dma engine node to pxa3xx-nand
      ARM: dts: pxa: add dma pxamci nodes to pxa3xx
      ARM: dts: pxa: add embedded pxa camera capture interface
      ARM: dts: pxa: add the usb host controller
      ARM: dts: pxa: fix power i2c definition

Roger Quadros (7):
      ARM: dts: omap5: Add named interrupt property for dwc3
      ARM: dts: dra7: Add named interrupt property for dwc3
      ARM: dts: dra7: Remove ctrl_core and ctrl_general nodes
      ARM: dts: dra7: fix pinmux at 1400 resource length
      ARM: dts: dra7: Add scm_conf at 1c04 node
      ARM: dts: am437x-gp-evm: Add gpio-hog for configuring eMMC/NAND driver
      ARM: dts: am437x-gp-evm: Add eMMC support

Roger Shimizu (3):
      ARM: dts: add buffalo linkstation ls-wxl/wsxl
      ARM: dts: add buffalo linkstation ls-wvl/vl
      ARM: dts: orion5x: add buffalo linkstation ls-wtgl

Romain Perier (4):
      ARM: dts: rockchip: Add STMMAC reset signal in GMAC interface for rk3288
      ARM: dts: rockchip: Add ramp delay for vdd_cpu in firefly board dts
      ARM: dts: rockchip: Use correct dts properties for tsadc node on veyron
      ARM: dts: rockchip: Add veyron-speedy board

Roman Byshko (2):
      ARM: dts: sun7i: Add USB Dual Role Controller
      ARM: dts: sun7i: Enable USB DRC on Cubietruck

Russell King (4):
      ARM: dt: Add PMU node, making PMU child devices childs of this node
      ARM: dt: dove: wire up RTC interrupt
      ARM: dt: dove: add video decoder power domain description
      ARM: dt: dove: add GPU power domain description

Sanchayan Maity (1):
      ARM: dts: vfxxx: Add io-channel-cells property for ADC node

Sascha Hauer (3):
      ARM: dts: mt8135: Add pmic wrapper nodes
      ARM: dts: mt8135-evbp1: Add PMIC support
      ARM: dts: mediatek mt8135: Use real UART clocks

Sekhar Nori (1):
      ARM: dts: am437x: add aliases for all UART instances

Sergei Shtylyov (7):
      ARM: shmobile: r8a7790: add EtherAVB clocks
      ARM: shmobile: r8a7790: add EtherAVB DT support
      ARM: shmobile: r8a7794: add PFC DT support
      ARM: shmobile: silk: initial device tree
      ARM: shmobile: silk: add Ether DT support
      ARM: shmobile: r8a7794: add MMCIF DT support
      ARM: shmobile: silk: add eMMC DT support

Shengjiu Wang (1):
      ARM: dts: imx6qdl-sabreauto: Add audio support

Simon Horman (1):
      Merge branch 'clk-for-v4.3' into dt-for-v4.3

Srinivas Kandagatla (6):
      ARM: dts: apq8064: Add pm8921 mfd and its gpio node
      ARM: dts: apq8064: add pm8921 mpp support
      ARM: dts: apq8064: fix missing gsbi cell-index
      ARM: dts: apq8064: remove temporary fixed regulator for mmc
      ARM: dts: ifc6410: add real regulators for sdcc nodes.
      ARM: dts: qs600: Add real regulators to sdcc

Stefan Agner (2):
      ARM: dts: vf-colibri: define stdout-path property
      ARM: dts: add property for maximum ADC clock frequencies

Stephen Boyd (5):
      ARM: dts: qcom: Replace gpio node with pinctrl node
      ARM: dts: qcom: Add MSM8960 RPM and RPM regulator nodes
      ARM: dts: qcom: Add MSM8960 CDP RPM regulators
      ARM: dts: qcom: Add ks8851 node for wired ethernet
      ARM: dts: vexpress: Use assigned-clock-parents for sp810

Suman Anna (4):
      ARM: dts: AM33xx: Update and move wkup_m3 node to l4 node
      ARM: dts: AM4372: Add the wkupm3 rproc node
      ARM: dts: AM33xx: Add the wkup_m3_ipc node
      ARM: dts: AM4372: Add the wkup_m3_ipc node

Teresa Remmet (2):
      ARM: dts: Add support for phyCORE-AM335x SoM
      ARM: dts: Add phyBOARD-WEGA-AM335x rdk

Thierry Reding (3):
      Merge branch 'for-4.3/pinctrl' into for-4.3/dt
      Merge branch 'for-4.3/clk' into for-4.3/dt
      ARM: tegra: venice2: Add GK20A GPU DT node

Thomas Petazzoni (4):
      ARM: mvebu: use armada-380-xor on Armada 38x and 39x
      ARM: mvebu: use DT properties to fine-tune the L2 configuration
      ARM: mvebu: fix description of pwr-sata0 regulator on Armada 388 GP
      ARM: mvebu: update EEPROM description of Armada 388 GP

Tim Harvey (1):
      ARM: dts: ventana: add UHS-I support for Ventana boards

Tomeu Vizoso (2):
      pinctrl: tegra: Only set the gpio range if needed
      ARM: tegra: Add gpio-ranges property

Tony Lindgren (7):
      ARM: dts: Remove L3 compatible value for dm816x
      ARM: dts: Add minimal dm814x support
      ARM: dts: Add minimal clocks for dm814x
      ARM: dts: Add minimal dts support for dm8148-evm
      ARM: dts: Add minimal support for HP T410
      ARM: OMAP2+: Add custom abort handler for t410
      Merge branch 'for-4.3/ti-clk-dt' of https://github.com/t-kristo/linux-pm into omap-for-v4.3/dt-v2

Tuomas Tynkkynen (10):
      clk: tegra: Add binding for the Tegra124 DFLL clocksource
      clk: tegra: Add library for the DFLL clock source (open-loop mode)
      clk: tegra: Add closed loop support for the DFLL
      clk: tegra: Add functions for parsing CVB tables
      clk: tegra: Add Tegra124 DFLL clocksource platform driver
      clk: tegra: Save/restore CCLKG_BURST_POLICY on suspend
      clk: tegra: Add the DFLL as a possible parent of the cclk_g clock
      ARM: tegra: Add the DFLL to Tegra124 device tree
      ARM: tegra: Enable the DFLL on the Jetson TK1
      ARM: tegra: Add entries for cpufreq on Tegra124

Ulrich Hecht (2):
      ARM: shmobile: add r8a7793 minimal SoC device tree
      ARM: shmobile: r8a7793: add minimal Gose board device tree

Vignesh R (1):
      ARM: dts: DRA72: switch to cpsw slave0 for ethernet

Wolfram Sang (2):
      ARM: shmobile: emev2: add IIC cores to dtsi
      ARM: shmobile: emev2: kzm9d: enable IIC busses

Xiaofeng Fei (1):
      ARM: dts: atlas7: add multimedia codec node

Ye He (2):
      ARM: dts: atlas7: add performance monitor unit node
      ARM: dts: atlas7: add lost gmac node

Yonghui Zhang (1):
      ARM: dts: atlas7: add software digital radio nodes and its DMA channels


 .../devicetree/bindings/arm/atmel-at91.txt      |   13 +-
 .../arm/bcm/raspberrypi,bcm2835-firmware.txt    |   14 +
 .../bindings/arm/marvell,kirkwood.txt           |    2 +
 .../devicetree/bindings/arm/mediatek.txt        |    4 +
 .../bindings/arm/mediatek/mediatek,sysirq.txt   |    1 +
 .../devicetree/bindings/arm/omap/omap.txt       |    3 +
 .../devicetree/bindings/arm/rockchip.txt        |   35 +
 .../devicetree/bindings/clock/imx6ul-clock.txt  |   13 +
 .../bindings/clock/nvidia,tegra124-dfll.txt     |   79 +
 .../bindings/clock/st/st,clkgen-pll.txt         |    4 +-
 .../bindings/memory-controllers/synopsys.txt    |    4 +
 .../bindings/pinctrl/fsl,imx6ul-pinctrl.txt     |   36 +
 .../devicetree/bindings/reset/socfpga-reset.txt |    2 +
 .../bindings/rtc/atmel,at91rm9200-rtc.txt       |    2 +
 .../devicetree/bindings/rtc/rtc-omap.txt        |    1 +
 .../devicetree/bindings/serial/mtk-uart.txt     |    3 +-
 .../bindings/timer/mediatek,mtk-timer.txt       |    6 +-
 .../devicetree/bindings/vendor-prefixes.txt     |    3 +
 .../devicetree/bindings/watchdog/atmel-wdt.txt  |    2 +
 arch/arm/boot/dts/Makefile                      |   41 +-
 arch/arm/boot/dts/am335x-boneblack.dts          |   20 +-
 arch/arm/boot/dts/am335x-evm.dts                |   69 +-
 arch/arm/boot/dts/am335x-evmsk.dts              |   62 +-
 arch/arm/boot/dts/am335x-phycore-som.dtsi       |  368 ++++
 arch/arm/boot/dts/am335x-wega-rdk.dts           |   22 +
 arch/arm/boot/dts/am335x-wega.dtsi              |  151 ++
 arch/arm/boot/dts/am33xx.dtsi                   |   25 +-
 arch/arm/boot/dts/am4372.dtsi                   |   67 +-
 arch/arm/boot/dts/am437x-gp-evm.dts             |  185 +-
 arch/arm/boot/dts/am437x-sk-evm.dts             |   45 +-
 arch/arm/boot/dts/am43x-epos-evm.dts            |  130 +-
 arch/arm/boot/dts/am43xx-clocks.dtsi            |    9 +
 arch/arm/boot/dts/am57xx-beagle-x15.dts         |    1 -
 arch/arm/boot/dts/armada-375.dtsi               |    4 +
 arch/arm/boot/dts/armada-388-gp.dts             |   12 +-
 arch/arm/boot/dts/armada-38x.dtsi               |    8 +-
 arch/arm/boot/dts/armada-39x.dtsi               |    8 +-
 arch/arm/boot/dts/at91-sama5d2_xplained.dts     |  134 ++
 arch/arm/boot/dts/at91-sama5d4_xplained.dts     |    9 +
 arch/arm/boot/dts/at91-sama5d4ek.dts            |    9 +
 arch/arm/boot/dts/at91rm9200.dtsi               |   10 +-
 arch/arm/boot/dts/at91sam9260.dtsi              |   11 +-
 arch/arm/boot/dts/at91sam9261.dtsi              |    7 +-
 arch/arm/boot/dts/at91sam9263.dtsi              |    7 +-
 arch/arm/boot/dts/at91sam9g15.dtsi              |    1 +
 arch/arm/boot/dts/at91sam9g15ek.dts             |   25 +
 arch/arm/boot/dts/at91sam9g35.dtsi              |    1 +
 arch/arm/boot/dts/at91sam9g35ek.dts             |   21 +
 arch/arm/boot/dts/at91sam9g45.dtsi              |   60 +-
 arch/arm/boot/dts/at91sam9m10g45ek.dts          |   47 +
 arch/arm/boot/dts/at91sam9n12.dtsi              |   83 +-
 arch/arm/boot/dts/at91sam9n12ek.dts             |   61 +
 arch/arm/boot/dts/at91sam9rl.dtsi               |    8 +-
 arch/arm/boot/dts/at91sam9x35.dtsi              |    1 +
 arch/arm/boot/dts/at91sam9x35ek.dts             |   20 +
 arch/arm/boot/dts/at91sam9x5.dtsi               |   12 +-
 arch/arm/boot/dts/at91sam9x5_lcd.dtsi           |  139 ++
 arch/arm/boot/dts/at91sam9x5dm.dtsi             |  101 +
 arch/arm/boot/dts/atlas7-evb.dts                |   18 +
 arch/arm/boot/dts/atlas7.dtsi                   |   97 +-
 arch/arm/boot/dts/axp152.dtsi                   |   49 +
 arch/arm/boot/dts/bcm-cygnus-clock.dtsi         |   89 +-
 arch/arm/boot/dts/bcm2835-rpi.dtsi              |    7 +
 .../boot/dts/bcm4708-buffalo-wzr-1750dhp.dts    |    4 +
 arch/arm/boot/dts/bcm4708-luxul-xwc-1000.dts    |    4 +
 arch/arm/boot/dts/bcm4708-netgear-r6250.dts     |   14 +-
 arch/arm/boot/dts/bcm4708-smartrg-sr400ac.dts   |    4 +
 .../boot/dts/bcm47081-buffalo-wzr-600dhp2.dts   |    4 +
 arch/arm/boot/dts/bcm5301x.dtsi                 |   10 +
 arch/arm/boot/dts/bcm7445.dtsi                  |   50 +
 arch/arm/boot/dts/cros-ec-sbs.dtsi              |   52 +
 arch/arm/boot/dts/cx92755.dtsi                  |    7 +
 arch/arm/boot/dts/cx92755_equinox.dts           |    3 +-
 arch/arm/boot/dts/dm8148-evm.dts                |   28 +
 arch/arm/boot/dts/dm8148-t410.dts               |   28 +
 arch/arm/boot/dts/dm814x-clocks.dtsi            |  109 ++
 arch/arm/boot/dts/dm814x.dtsi                   |  333 ++++
 arch/arm/boot/dts/dm816x.dtsi                   |    2 +-
 arch/arm/boot/dts/dove.dtsi                     |  604 +++---
 arch/arm/boot/dts/dra7-evm.dts                  |   18 +-
 arch/arm/boot/dts/dra7.dtsi                     |   95 +-
 arch/arm/boot/dts/dra72-evm.dts                 |   26 +-
 arch/arm/boot/dts/dra74x.dtsi                   |    7 +-
 arch/arm/boot/dts/emev2-kzm9d.dts               |    8 +
 arch/arm/boot/dts/emev2.dtsi                    |   48 +
 arch/arm/boot/dts/exynos4210-universal_c210.dts |  620 +++----
 arch/arm/boot/dts/exynos4412-trats2.dts         |    3 +
 arch/arm/boot/dts/exynos5250-pinctrl.dtsi       | 1600 ++++++++--------
 arch/arm/boot/dts/exynos5250.dtsi               |    3 +-
 arch/arm/boot/dts/exynos5410-smdk5410.dts       |    6 +-
 arch/arm/boot/dts/exynos5420-pinctrl.dtsi       | 1411 +++++++-------
 arch/arm/boot/dts/exynos5420.dtsi               |    3 +-
 arch/arm/boot/dts/exynos5422-cpu-thermal.dtsi   |   59 +
 .../boot/dts/exynos5422-odroidxu3-common.dtsi   |   46 +
 arch/arm/boot/dts/imx27.dtsi                    |    9 +
 arch/arm/boot/dts/imx53-qsb-common.dtsi         |    5 +-
 arch/arm/boot/dts/imx53-qsrb.dts                |   14 +-
 arch/arm/boot/dts/imx6qdl-gw51xx.dtsi           |    1 -
 arch/arm/boot/dts/imx6qdl-gw52xx.dtsi           |   35 +-
 arch/arm/boot/dts/imx6qdl-gw53xx.dtsi           |   35 +-
 arch/arm/boot/dts/imx6qdl-gw54xx.dtsi           |   34 +-
 arch/arm/boot/dts/imx6qdl-gw551x.dtsi           |    1 -
 arch/arm/boot/dts/imx6qdl-gw552x.dtsi           |    1 -
 arch/arm/boot/dts/imx6qdl-nitrogen6x.dtsi       |   39 +
 arch/arm/boot/dts/imx6qdl-sabreauto.dtsi        |  137 ++
 arch/arm/boot/dts/imx6qdl-sabrelite.dtsi        |   39 +
 arch/arm/boot/dts/imx6qdl-sabresd.dtsi          |    7 +
 arch/arm/boot/dts/imx6qdl.dtsi                  |   52 +-
 arch/arm/boot/dts/imx6sl-warp.dts               |   32 +-
 arch/arm/boot/dts/imx6sl.dtsi                   |   21 +-
 arch/arm/boot/dts/imx6sx.dtsi                   |   28 +-
 arch/arm/boot/dts/imx6ul-14x14-evk.dts          |  343 ++++
 arch/arm/boot/dts/imx6ul-pinfunc.h              |  938 ++++++++++
 arch/arm/boot/dts/imx6ul.dtsi                   |  707 +++++++
 arch/arm/boot/dts/imx7d.dtsi                    |  260 ++-
 arch/arm/boot/dts/kirkwood-lswvl.dts            |  301 +++
 arch/arm/boot/dts/kirkwood-lswxl.dts            |  301 +++
 arch/arm/boot/dts/lpc18xx.dtsi                  |  267 ++-
 arch/arm/boot/dts/lpc4337-ciaa.dts              |  187 ++
 arch/arm/boot/dts/lpc4350-hitex-eval.dts        |  244 ++-
 arch/arm/boot/dts/lpc4357-ea4357-devkit.dts     |  467 +++++
 arch/arm/boot/dts/ls1021a-qds.dts               |   89 +
 arch/arm/boot/dts/ls1021a-twr.dts               |   81 +
 arch/arm/boot/dts/ls1021a.dtsi                  |  106 +-
 arch/arm/boot/dts/mt6580-evbp1.dts              |   38 +
 arch/arm/boot/dts/mt6580.dtsi                   |  116 ++
 arch/arm/boot/dts/mt8135-evbp1.dts              |  193 ++
 arch/arm/boot/dts/mt8135.dtsi                   |   58 +-
 arch/arm/boot/dts/omap3-devkit8000-common.dtsi  |  369 ++++
 .../boot/dts/omap3-devkit8000-lcd-common.dtsi   |   73 +
 arch/arm/boot/dts/omap3-devkit8000-lcd43.dts    |   37 +
 arch/arm/boot/dts/omap3-devkit8000-lcd70.dts    |   37 +
 arch/arm/boot/dts/omap3-devkit8000.dts          |  191 +-
 arch/arm/boot/dts/omap3-lilly-a83x.dtsi         |   12 +-
 arch/arm/boot/dts/omap3-overo-base.dtsi         |   55 +
 arch/arm/boot/dts/omap3-overo-common-lcd35.dtsi |    3 +-
 .../arm/boot/dts/omap3-overo-palo35-common.dtsi |   53 +
 arch/arm/boot/dts/omap3-overo-palo35.dts        |   37 +
 arch/arm/boot/dts/omap3-overo-storm-palo35.dts  |   37 +
 arch/arm/boot/dts/omap3-overo-storm-tobiduo.dts |   21 +
 .../boot/dts/omap3-overo-tobiduo-common.dtsi    |   65 +
 arch/arm/boot/dts/omap3-overo-tobiduo.dts       |   21 +
 arch/arm/boot/dts/omap3-overo.dtsi              |    4 -
 arch/arm/boot/dts/omap3-pandora-1ghz.dts        |    2 +-
 arch/arm/boot/dts/omap3-pandora-600mhz.dts      |    2 +-
 arch/arm/boot/dts/omap3-pandora-common.dtsi     |   54 +-
 arch/arm/boot/dts/omap5-uevm.dts                |    7 +
 arch/arm/boot/dts/omap5.dtsi                    |    7 +-
 .../arm/boot/dts/orion5x-linkstation-lswtgl.dts |  273 +++
 arch/arm/boot/dts/orion5x-lswsgl.dts            |  276 +++
 arch/arm/boot/dts/pxa27x.dtsi                   |   36 +
 arch/arm/boot/dts/pxa2xx.dtsi                   |    4 +
 arch/arm/boot/dts/pxa3xx.dtsi                   |   52 +
 arch/arm/boot/dts/qcom-apq8064-cm-qs600.dts     |   20 +
 arch/arm/boot/dts/qcom-apq8064-ifc6410.dts      |   40 +
 arch/arm/boot/dts/qcom-apq8064.dtsi             |   91 +-
 arch/arm/boot/dts/qcom-msm8660.dtsi             |   11 +-
 arch/arm/boot/dts/qcom-msm8960-cdp.dts          |  302 +++
 arch/arm/boot/dts/qcom-msm8960.dtsi             |   49 +-
 arch/arm/boot/dts/qcom-msm8974.dtsi             |   32 +
 arch/arm/boot/dts/r7s72100.dtsi                 |   19 +
 arch/arm/boot/dts/r8a73a4.dtsi                  |    9 +-
 arch/arm/boot/dts/r8a7740-armadillo800eva.dts   |   13 +
 arch/arm/boot/dts/r8a7740.dtsi                  |    1 +
 arch/arm/boot/dts/r8a7778.dtsi                  |   22 +
 arch/arm/boot/dts/r8a7779.dtsi                  |   28 +-
 arch/arm/boot/dts/r8a7790-lager.dts             |    4 +-
 arch/arm/boot/dts/r8a7790.dtsi                  |  138 +-
 arch/arm/boot/dts/r8a7791-koelsch.dts           |    2 +-
 arch/arm/boot/dts/r8a7791.dtsi                  |  120 +-
 arch/arm/boot/dts/r8a7793-gose.dts              |   63 +
 arch/arm/boot/dts/r8a7793.dtsi                  |  374 ++++
 arch/arm/boot/dts/r8a7794-silk.dts              |  102 +
 arch/arm/boot/dts/r8a7794.dtsi                  |   48 +-
 arch/arm/boot/dts/rk3066a-bqcurie2.dts          |    1 +
 arch/arm/boot/dts/rk3066a-marsboard.dts         |   13 +
 arch/arm/boot/dts/rk3066a-rayeager.dts          |    5 +
 arch/arm/boot/dts/rk3066a.dtsi                  |   22 +
 arch/arm/boot/dts/rk3188-radxarock.dts          |    5 +
 arch/arm/boot/dts/rk3188.dtsi                   |   22 +
 arch/arm/boot/dts/rk3288-evb.dtsi               |    1 +
 arch/arm/boot/dts/rk3288-firefly.dtsi           |    3 +
 arch/arm/boot/dts/rk3288-popmetal.dts           |    1 +
 arch/arm/boot/dts/rk3288-r89.dts                |  413 +++++
 arch/arm/boot/dts/rk3288-veyron-chromebook.dtsi |  232 +++
 arch/arm/boot/dts/rk3288-veyron-jerry.dts       |  197 ++
 arch/arm/boot/dts/rk3288-veyron-minnie.dts      |  230 +++
 arch/arm/boot/dts/rk3288-veyron-pinky.dts       |  128 ++
 arch/arm/boot/dts/rk3288-veyron-sdmmc.dtsi      |  122 ++
 arch/arm/boot/dts/rk3288-veyron-speedy.dts      |  155 ++
 arch/arm/boot/dts/rk3288-veyron.dtsi            |  563 ++++++
 arch/arm/boot/dts/rk3288.dtsi                   |   31 +-
 arch/arm/boot/dts/rk3xxx.dtsi                   |   10 +
 arch/arm/boot/dts/sama5d2.dtsi                  |  926 +++++++++
 arch/arm/boot/dts/sama5d3.dtsi                  |   10 +-
 arch/arm/boot/dts/sama5d3_tcb1.dtsi             |    4 +-
 arch/arm/boot/dts/sama5d4.dtsi                  |   25 +-
 arch/arm/boot/dts/sh73a0.dtsi                   |    3 +
 arch/arm/boot/dts/socfpga.dtsi                  |   46 +-
 arch/arm/boot/dts/socfpga_arria10.dtsi          |   11 +
 arch/arm/boot/dts/socfpga_arria10_socdk.dtsi    |    3 +-
 arch/arm/boot/dts/socfpga_arria5_socdk.dts      |    3 +-
 .../boot/dts/socfpga_cyclone5_de0_sockit.dts    |  111 ++
 arch/arm/boot/dts/socfpga_cyclone5_socdk.dts    |    3 +-
 arch/arm/boot/dts/socfpga_cyclone5_sockit.dts   |    3 +-
 arch/arm/boot/dts/stih407-clock.dtsi            |    4 +-
 arch/arm/boot/dts/stih407-family.dtsi           |   45 +
 arch/arm/boot/dts/stih407-pinctrl.dtsi          |  200 ++
 arch/arm/boot/dts/stih407.dtsi                  |   28 -
 arch/arm/boot/dts/stih410-clock.dtsi            |    4 +-
 arch/arm/boot/dts/stih410.dtsi                  |   12 +
 arch/arm/boot/dts/stih418-clock.dtsi            |    4 +-
 arch/arm/boot/dts/stih418.dtsi                  |    4 +
 arch/arm/boot/dts/stm32429i-eval.dts            |   75 +
 arch/arm/boot/dts/stm32f429-disco.dts           |    8 +-
 arch/arm/boot/dts/stm32f429.dtsi                |   79 +-
 arch/arm/boot/dts/sun4i-a10-ba10-tvbox.dts      |   15 +
 arch/arm/boot/dts/sun4i-a10-chuwi-v7-cw0825.dts |   34 +
 arch/arm/boot/dts/sun4i-a10-cubieboard.dts      |   19 +
 .../boot/dts/sun4i-a10-itead-iteaduino-plus.dts |  202 ++
 arch/arm/boot/dts/sun4i-a10-mini-xplus.dts      |   15 +
 arch/arm/boot/dts/sun4i-a10-olinuxino-lime.dts  |   32 +
 arch/arm/boot/dts/sun4i-a10.dtsi                |   16 +-
 .../arm/boot/dts/sun5i-a10s-olinuxino-micro.dts |   37 +-
 arch/arm/boot/dts/sun5i-a13-hsg-h702.dts        |   58 +
 arch/arm/boot/dts/sun5i-a13-olinuxino.dts       |   37 +
 arch/arm/boot/dts/sun5i-a13-utoo-p66.dts        |   29 +-
 arch/arm/boot/dts/sun5i.dtsi                    |   16 +-
 .../arm/boot/dts/sun6i-a31-mele-a1000g-quad.dts |    5 +
 arch/arm/boot/dts/sun6i-a31.dtsi                |   16 +-
 arch/arm/boot/dts/sun6i-a31s-cs908.dts          |    5 +
 arch/arm/boot/dts/sun7i-a20-cubietruck.dts      |   56 +-
 arch/arm/boot/dts/sun7i-a20-i12-tvbox.dts       |    2 +-
 arch/arm/boot/dts/sun7i-a20-olinuxino-lime.dts  |   32 +
 arch/arm/boot/dts/sun7i-a20-olinuxino-micro.dts |   32 +
 arch/arm/boot/dts/sun7i-a20.dtsi                |   16 +-
 arch/arm/boot/dts/sun8i-a23-a33.dtsi            |   25 +-
 arch/arm/boot/dts/sun8i-a23-ippo-q8h-v5.dts     |    9 +
 arch/arm/boot/dts/sun8i-a23.dtsi                |   33 +
 arch/arm/boot/dts/sun8i-a33-ga10h-v1.1.dts      |   17 +
 arch/arm/boot/dts/sun8i-a33-ippo-q8h-v1.2.dts   |  133 ++
 arch/arm/boot/dts/sun8i-a33-sinlinx-sina33.dts  |   13 +
 arch/arm/boot/dts/sun8i-a33.dtsi                |   33 +
 arch/arm/boot/dts/sunxi-common-regulators.dtsi  |    2 +
 arch/arm/boot/dts/tegra114.dtsi                 |    5 +-
 arch/arm/boot/dts/tegra124-jetson-tk1.dts       |   25 +-
 arch/arm/boot/dts/tegra124-venice2.dts          |   10 +-
 arch/arm/boot/dts/tegra124.dtsi                 |   50 +
 arch/arm/boot/dts/tegra20.dtsi                  |    5 +-
 arch/arm/boot/dts/tegra30.dtsi                  |    5 +-
 arch/arm/boot/dts/uniphier-ph1-ld4-ref.dts      |   38 +-
 arch/arm/boot/dts/uniphier-ph1-ld4.dtsi         |  143 ++
 arch/arm/boot/dts/uniphier-ph1-ld6b-ref.dts     |  105 ++
 arch/arm/boot/dts/uniphier-ph1-ld6b.dtsi        |   67 +
 arch/arm/boot/dts/uniphier-ph1-pro4-ref.dts     |   40 +-
 arch/arm/boot/dts/uniphier-ph1-pro4.dtsi        |  158 ++
 arch/arm/boot/dts/uniphier-ph1-pro5.dtsi        |  252 +++
 arch/arm/boot/dts/uniphier-ph1-sld3-ref.dts     |   46 +-
 arch/arm/boot/dts/uniphier-ph1-sld3.dtsi        |  122 ++
 arch/arm/boot/dts/uniphier-ph1-sld8-ref.dts     |   42 +-
 arch/arm/boot/dts/uniphier-ph1-sld8.dtsi        |  143 ++
 arch/arm/boot/dts/uniphier-pinctrl.dtsi         |  105 ++
 arch/arm/boot/dts/uniphier-proxstream2.dtsi     |  273 +++
 arch/arm/boot/dts/uniphier-ref-daughter.dtsi    |   50 +
 arch/arm/boot/dts/vexpress-v2m-rs1.dtsi         |    2 +
 arch/arm/boot/dts/vexpress-v2m.dtsi             |    2 +
 arch/arm/boot/dts/vf-colibri-eval-v3.dtsi       |    2 +-
 arch/arm/boot/dts/vfxxx.dtsi                    |   85 +-
 arch/arm/boot/dts/zynq-7000.dtsi                |   10 +-
 arch/arm/boot/dts/zynq-zc702.dts                |   28 +
 arch/arm/configs/omap2plus_defconfig            |    3 +
 arch/arm/mach-omap2/pdata-quirks.c              |  157 ++
 arch/arm/mach-orion5x/Kconfig                   |    6 +-
 arch/arm/mach-orion5x/Makefile                  |    1 -
 arch/arm/mach-orion5x/lsmini-setup.c            |  280 ---
 arch/arm/mach-tegra/Kconfig                     |    1 +
 drivers/clk/imx/Makefile                        |    1 +
 drivers/clk/imx/clk-imx6q.c                     |    4 +
 drivers/clk/imx/clk-imx6ul.c                    |  432 +++++
 drivers/clk/tegra/Makefile                      |    3 +
 drivers/clk/tegra/clk-dfll.c                    | 1755 ++++++++++++++++++
 drivers/clk/tegra/clk-dfll.h                    |   54 +
 drivers/clk/tegra/clk-tegra-super-gen4.c        |    4 +-
 drivers/clk/tegra/clk-tegra124-dfll-fcpu.c      |  166 ++
 drivers/clk/tegra/clk-tegra124.c                |   82 +
 drivers/clk/tegra/clk.c                         |   39 +-
 drivers/clk/tegra/clk.h                         |    3 +
 drivers/clk/tegra/cvb.c                         |  140 ++
 drivers/clk/tegra/cvb.h                         |   67 +
 drivers/clk/ti/clk-43xx.c                       |    1 +
 drivers/pinctrl/pinctrl-tegra.c                 |   19 +-
 include/dt-bindings/clock/imx6ul-clock.h        |  240 +++
 include/dt-bindings/clock/r8a7790-clock.h       |    3 +
 include/dt-bindings/clock/r8a7791-clock.h       |    2 +
 include/dt-bindings/clock/r8a7793-clock.h       |  164 ++
 include/dt-bindings/pinctrl/am43xx.h            |    1 +
 include/dt-bindings/pinctrl/dra.h               |   20 +
 include/dt-bindings/reset/altr,rst-mgr-a10.h    |  110 ++
 include/dt-bindings/reset/tegra124-car.h        |   12 +
 299 files changed, 23173 insertions(+), 3206 deletions(-)
 create mode 100644 Documentation/devicetree/bindings/arm/bcm/raspberrypi,bcm2835-firmware.txt
 create mode 100644 Documentation/devicetree/bindings/clock/imx6ul-clock.txt
 create mode 100644 Documentation/devicetree/bindings/clock/nvidia,tegra124-dfll.txt
 create mode 100644 Documentation/devicetree/bindings/pinctrl/fsl,imx6ul-pinctrl.txt
 create mode 100644 arch/arm/boot/dts/am335x-phycore-som.dtsi
 create mode 100644 arch/arm/boot/dts/am335x-wega-rdk.dts
 create mode 100644 arch/arm/boot/dts/am335x-wega.dtsi
 create mode 100644 arch/arm/boot/dts/at91-sama5d2_xplained.dts
 create mode 100644 arch/arm/boot/dts/at91sam9x5dm.dtsi
 create mode 100644 arch/arm/boot/dts/axp152.dtsi
 create mode 100644 arch/arm/boot/dts/cros-ec-sbs.dtsi
 create mode 100644 arch/arm/boot/dts/dm8148-evm.dts
 create mode 100644 arch/arm/boot/dts/dm8148-t410.dts
 create mode 100644 arch/arm/boot/dts/dm814x-clocks.dtsi
 create mode 100644 arch/arm/boot/dts/dm814x.dtsi
 create mode 100644 arch/arm/boot/dts/exynos5422-cpu-thermal.dtsi
 create mode 100644 arch/arm/boot/dts/imx6ul-14x14-evk.dts
 create mode 100644 arch/arm/boot/dts/imx6ul-pinfunc.h
 create mode 100644 arch/arm/boot/dts/imx6ul.dtsi
 create mode 100644 arch/arm/boot/dts/kirkwood-lswvl.dts
 create mode 100644 arch/arm/boot/dts/kirkwood-lswxl.dts
 create mode 100644 arch/arm/boot/dts/lpc4337-ciaa.dts
 create mode 100644 arch/arm/boot/dts/mt6580-evbp1.dts
 create mode 100644 arch/arm/boot/dts/mt6580.dtsi
 create mode 100644 arch/arm/boot/dts/omap3-devkit8000-common.dtsi
 create mode 100644 arch/arm/boot/dts/omap3-devkit8000-lcd-common.dtsi
 create mode 100644 arch/arm/boot/dts/omap3-devkit8000-lcd43.dts
 create mode 100644 arch/arm/boot/dts/omap3-devkit8000-lcd70.dts
 create mode 100644 arch/arm/boot/dts/omap3-overo-palo35-common.dtsi
 create mode 100644 arch/arm/boot/dts/omap3-overo-palo35.dts
 create mode 100644 arch/arm/boot/dts/omap3-overo-storm-palo35.dts
 create mode 100644 arch/arm/boot/dts/omap3-overo-storm-tobiduo.dts
 create mode 100644 arch/arm/boot/dts/omap3-overo-tobiduo-common.dtsi
 create mode 100644 arch/arm/boot/dts/omap3-overo-tobiduo.dts
 create mode 100644 arch/arm/boot/dts/orion5x-linkstation-lswtgl.dts
 create mode 100644 arch/arm/boot/dts/orion5x-lswsgl.dts
 create mode 100644 arch/arm/boot/dts/r8a7793-gose.dts
 create mode 100644 arch/arm/boot/dts/r8a7793.dtsi
 create mode 100644 arch/arm/boot/dts/r8a7794-silk.dts
 create mode 100644 arch/arm/boot/dts/rk3288-r89.dts
 create mode 100644 arch/arm/boot/dts/rk3288-veyron-chromebook.dtsi
 create mode 100644 arch/arm/boot/dts/rk3288-veyron-jerry.dts
 create mode 100644 arch/arm/boot/dts/rk3288-veyron-minnie.dts
 create mode 100644 arch/arm/boot/dts/rk3288-veyron-pinky.dts
 create mode 100644 arch/arm/boot/dts/rk3288-veyron-sdmmc.dtsi
 create mode 100644 arch/arm/boot/dts/rk3288-veyron-speedy.dts
 create mode 100644 arch/arm/boot/dts/rk3288-veyron.dtsi
 create mode 100644 arch/arm/boot/dts/sama5d2.dtsi
 create mode 100644 arch/arm/boot/dts/socfpga_cyclone5_de0_sockit.dts
 create mode 100644 arch/arm/boot/dts/stm32429i-eval.dts
 create mode 100644 arch/arm/boot/dts/sun4i-a10-itead-iteaduino-plus.dts
 create mode 100644 arch/arm/boot/dts/sun8i-a33-ippo-q8h-v1.2.dts
 create mode 100644 arch/arm/boot/dts/uniphier-ph1-ld6b-ref.dts
 create mode 100644 arch/arm/boot/dts/uniphier-ph1-ld6b.dtsi
 create mode 100644 arch/arm/boot/dts/uniphier-ph1-pro5.dtsi
 create mode 100644 arch/arm/boot/dts/uniphier-pinctrl.dtsi
 create mode 100644 arch/arm/boot/dts/uniphier-proxstream2.dtsi
 create mode 100644 arch/arm/boot/dts/uniphier-ref-daughter.dtsi
 delete mode 100644 arch/arm/mach-orion5x/lsmini-setup.c
 create mode 100644 drivers/clk/imx/clk-imx6ul.c
 create mode 100644 drivers/clk/tegra/clk-dfll.c
 create mode 100644 drivers/clk/tegra/clk-dfll.h
 create mode 100644 drivers/clk/tegra/clk-tegra124-dfll-fcpu.c
 create mode 100644 drivers/clk/tegra/cvb.c
 create mode 100644 drivers/clk/tegra/cvb.h
 create mode 100644 include/dt-bindings/clock/imx6ul-clock.h
 create mode 100644 include/dt-bindings/clock/r8a7793-clock.h
 create mode 100644 include/dt-bindings/reset/altr,rst-mgr-a10.h
 create mode 100644 include/dt-bindings/reset/tegra124-car.h


From k.kozlowski at samsung.com  Mon Aug 31 17:08:24 2015
From: k.kozlowski at samsung.com (Krzysztof Kozlowski)
Date: Tue, 01 Sep 2015 09:08:24 +0900
Subject: [PATCH] ARM: EXYNOS: reset KFC cores when cpu is up
In-Reply-To: <1441031111-6549-1-git-send-email-parkch98@gmail.com>
References: <1441031111-6549-1-git-send-email-parkch98@gmail.com>
Message-ID: <55E4EC78.8050507@samsung.com>

On 31.08.2015 23:25, Chanho Park wrote:
> The cpu booting of exynos5422 has been still broken since we discussed
s/cpu/CPU/ (here and in other places)

> it in last year[1]. This patch is inspired from odroid xu3

s/odroid xu3/Odroid XU3/

> code(Actually, it was from samsung exynos vendor kernel)[2]. This weird

Space before parenthesis.

> reset code was founded exynos5420 octa cores series SoCs and only
> required for the first boot core is the little core(kingfisher core).

Again space before parenthesis.

> Some of the exynos5420 boards and all of the exynos5422 boards will be
> required this code.

s/will be required/require/

> There is two ways to check the little core is the first cpu. One is
> checking GPG2CON[1] gpio value and the other is checking the cluster

s/gpio/GPIO/

> number of the first cpu. I selected the latter because it's more easier
> than the former.
> 
> Changes since RFC[3]:
> - drop checking soc_is_exynos5800 to extend this codes to
> exynos5420/5422 boards.
> - kfc cores will be reset only if the cpu0 is kfc core.
> - Rebase top of the kukjin's for-next branch

Changelog and its references ([3]) goes after '---'.

> 
> [1]:http://lists.infradead.org/pipermail/linux-arm-kernel/2015-June/350632.html
> [2]:https://patchwork.kernel.org/patch/6782891/
> [3]:http://lists.infradead.org/pipermail/linux-arm-kernel/2015-July/356610.html


> 
> Cc: Joonyoung Shim <jy0922.shim at samsung.com>
> Cc: Chanwoo Choi <cw00.choi at samsung.com>
> Cc: Kevin Hilman <khilman at kernel.org>
> Cc: Heesub Shin <heesub.shin at samsung.com>
> Cc: Mauro Ribeiro <mauro.ribeiro at hardkernel.com>
> Cc: Abhilash Kesavan <a.kesavan at samsung.com>
> Cc: Przemyslaw Marczak <p.marczak at samsung.com>
> Cc: Marek Szyprowski <m.szyprowski at samsung.com>
> Cc: Krzysztof Kozlowski <k.kozlowski at samsung.com>
> Signed-off-by: Chanho Park <parkch98 at gmail.com>

That's a huge CC-list. Everyone are important to CC? Definitely you can
remove me because I appear as a maintainer. :)
I think you can leave only people who participated in the recent
discussions.

> ---
>  arch/arm/mach-exynos/mcpm-exynos.c | 18 +++++++++++++++++-
>  arch/arm/mach-exynos/regs-pmu.h    |  6 ++++++
>  2 files changed, 23 insertions(+), 1 deletion(-)
> 
> diff --git a/arch/arm/mach-exynos/mcpm-exynos.c b/arch/arm/mach-exynos/mcpm-exynos.c
> index 9bdf547..5b69ed2 100644
> --- a/arch/arm/mach-exynos/mcpm-exynos.c
> +++ b/arch/arm/mach-exynos/mcpm-exynos.c
> @@ -20,6 +20,7 @@
>  #include <asm/cputype.h>
>  #include <asm/cp15.h>
>  #include <asm/mcpm.h>
> +#include <asm/smp_plat.h>
>  
>  #include "regs-pmu.h"
>  #include "common.h"
> @@ -70,7 +71,22 @@ static int exynos_cpu_powerup(unsigned int cpu, unsigned int cluster)
>  		cluster >= EXYNOS5420_NR_CLUSTERS)
>  		return -EINVAL;
>  
> -	exynos_cpu_power_up(cpunr);
> +	if (!exynos_cpu_power_state(cpunr)) {
> +		exynos_cpu_power_up(cpunr);
> +
> +		/* This assumes the cluster number of the eagle is 0 and the
> +		 * kfc is 1. When the system was booted from the kfc core,
> +		 * they should be reset */
> +		if (cluster &&
> +		    cluster == MPIDR_AFFINITY_LEVEL(cpu_logical_map(0), 1)) {

I already asked for that - please describe what happens here. Why we are
spinning on SPARE2? At least one or two lines. Grepping through commits
or mailing lists is less efficient than looking at comment at code.

Everything boils to firmware on Exynos5422 boards which uses SPARE2 as
synchronisation mechanism. After powering up a CPU, if SPARE2 is not set
to 1, then firmware (BL1 or code in IROM) spins over it and we can
safely execute software reset.

The patch is itself good, just please fix these minor nits.

Best regards,
Krzysztof


> +			while (!pmu_raw_readl(S5P_PMU_SPARE2))
> +				udelay(10);
> +
> +			pmu_raw_writel(EXYNOS5420_KFC_CORE_RESET(cpu),
> +					EXYNOS_SWRESET);
> +		}
> +	}
> +
>  	return 0;
>  }
>  
> diff --git a/arch/arm/mach-exynos/regs-pmu.h b/arch/arm/mach-exynos/regs-pmu.h
> index b761433..fba9068 100644
> --- a/arch/arm/mach-exynos/regs-pmu.h
> +++ b/arch/arm/mach-exynos/regs-pmu.h
> @@ -513,6 +513,12 @@ static inline unsigned int exynos_pmu_cpunr(unsigned int mpidr)
>  #define SPREAD_ENABLE						0xF
>  #define SPREAD_USE_STANDWFI					0xF
>  
> +#define EXYNOS5420_KFC_CORE_RESET0				BIT(8)
> +#define EXYNOS5420_KFC_ETM_RESET0				BIT(20)
> +
> +#define EXYNOS5420_KFC_CORE_RESET(_nr)				\
> +	((EXYNOS5420_KFC_CORE_RESET0 | EXYNOS5420_KFC_ETM_RESET0) << (_nr))
> +
>  #define EXYNOS5420_BB_CON1					0x0784
>  #define EXYNOS5420_BB_SEL_EN					BIT(31)
>  #define EXYNOS5420_BB_PMOS_EN					BIT(7)
> 



From shawn.lin at rock-chips.com  Mon Aug 31 17:16:05 2015
From: shawn.lin at rock-chips.com (Shawn Lin)
Date: Tue, 1 Sep 2015 08:16:05 +0800
Subject: [PATCH v2 0/5] Fix broken DMAFLUSHP on Rockchips platform
In-Reply-To: <CAPz6YkXmGkQsB4WbQ5VbBAPRCTQFYCUR=Nf6G+syhbXSPA2DeQ@mail.gmail.com>
References: <1440722176-31588-1-git-send-email-shawn.lin@rock-chips.com>
 <CAPz6YkXmGkQsB4WbQ5VbBAPRCTQFYCUR=Nf6G+syhbXSPA2DeQ@mail.gmail.com>
Message-ID: <55E4EE45.5020002@rock-chips.com>

? 2015/9/1 5:40, Sonny Rao ??:
> On Thu, Aug 27, 2015 at 5:36 PM, Shawn Lin <shawn.lin at rock-chips.com> wrote:
>>
>> The purpose of the DMAFLUSHP instruction:
>> - Tell the peripheral to clear its status and control registers.
>> - Send a message to the peripheral to resend its level status.
>>
>> There are 3 timings described in PL330 Technical Reference Manual:
>> - Timing 1: Burst request, can work well without DMAFLUSHP.
>> - Timing 2: Single and burst request, DMAC will ignore the single
>>              transfer request. This timing happens if there are single
>>              and burst request.
>> - Timing 3: Single transfers for a burst request, DMAC should signals
>>              datype to request the peripheral to flush the contents of
>>              any control registers. This timing happens if there is
>>              not enough MFIFO to places the burst data.
>>
>> A peripheral may signal a DMA request during the execution of
>> DMAFLUSHP instruction, that cause DMA request being ignored by DMAC.
>>
>> But DMAC and all peripherals on RK3X SoCs DO NOT support DMAFLUSHP.
>> It can't send a message to the peripheral to resend DMA request,
>> and the peripheral can't acknowledge a flush request from DMAC.
>> So all DMA requests should NOT be ignored by DMAC, and DMAC will not
>> notify the peripheral to flush.
>>
>> To fix this problem, we need:
>> - Do NOT execute DMAFLUSHP instruction.
>> - Timing 2 and timing 3 should not happen.
>>
>> Because on RK3X SoCs, there are 6 or below  channels and 32 MFIFO depth
>> for DMAC_BUS, and 8 channels and 64 MFIFO depth for DMAC_PERI, it is
>> impossible to hit the timing 3 if burst length is equal or less than 4.
>
> Fixing this issue also requires changes to drivers, so it would be
> nice if you put those changes into the same patchset.
> Otherwise someone may apply this series and expect things to work but
> they will still be broken. Specifically the peripherals should be
> setting their burst sizes for their DMA requests low enough to avoid
> needing the working DMAFLUSHP instruction.
>
> Also, I remember we ran into an issue when we tried using burst length
> of 4 with the i2s device on RK3288 because we could get requests that
> either weren't aligned or a multiple of 4 sizes and some transfers
> would just fail, so we ended up using a burst size of 1.  I recommend
> if we aren't sure about size or alignment for a particular peripheral,
> a burst size of 1 is safest.  For something like a block device, I
> think we can use the larger size bursts.  That's another reason to

Agreed. Those changes will be added in v3.

Thanks, Sunny.

> include the driver fixes in the series, just so we get it right,
> thanks.
>
>>
>> Since the request type signal by the peripheral can only be set by
>> software. We can set Rockchip Soc's GRF_PERIDMAC_CON0[2:1] to select single
>> or burst request, if it is set b01,  all of the peripharals will signal a brust
>> request. So the timing 2 will not happen, too.
>>
>> So DMAC on RK3X can support single or burst transfer, but can't support
>> mixed transfer.
>>
>> Because burst transfer is more efficient than single transfer, this is
>> confirmed by our ASIC team, who strongly suggest to use burst transfer.
>> And this is confirmed by Addy's test on RK3288-Pink2 board, the speed of
>> spi flash burst transfer will increase about two times than single transfer.
>> Also, I have tested dw_mmc with pl330 on RK3188 platform to double confirm
>> the result. That means burst transfer is reansonable.
>>
>> So we need a quirk not to execute DMAFLUSHP instruction and to use burst
>> transfer.
>>
>> Note:
>> - The Rockchip Soc default value of GRF_PERIDMAC_CON0[2:1] is b01. To
>>    support brust transfer, these bits should not be changed in bootloader.
>>
>>
>> Changes in v2:
>> - amend the author
>> - reorder the patches suggested by Doug
>> - add Reviewed-by: Doug Anderson <dianders at chromium.org> for
>>    rk3288.dtsi patch and arm-pl330.txt patch
>> - amend Olof's mail address
>>
>> Changes in v1:
>> - rename broken-no-flushp to "arm,pl330-broken-no-flushp" suggested
>>    by Krzysztof.
>> - add From original author.
>> - remove Sunny's tag
>>
>> Addy Ke (2):
>>    DMA: pl330: add quirk for broken no flushp
>>    ARM: dts: Add arm,pl330-broken-no-flushp quirk for rk3288 platform
>>
>> Boojin Kim (1):
>>    DMA: pl330: support burst mode for dev-to-mem and mem-to-dev transmit
>>
>> Shawn Lin (2):
>>    Documentation: arm-pl330: add description of
>>      arm,pl330-broken-no-flushp
>>    ARM: dts: Add arm,pl330-broken-no-flushp quirk for rk3xxx platform
>>
>>   .../devicetree/bindings/dma/arm-pl330.txt          |   1 +
>>   arch/arm/boot/dts/rk3288.dtsi                      |   3 +
>>   arch/arm/boot/dts/rk3xxx.dtsi                      |   3 +
>>   drivers/dma/pl330.c                                | 101 +++++++++++++++------
>>   4 files changed, 79 insertions(+), 29 deletions(-)
>>
>> --
>> 2.3.7
>>
>>
>> --
>> To unsubscribe from this list: send the line "unsubscribe linux-kernel" in
>> the body of a message to majordomo at vger.kernel.org
>> More majordomo info at  http://vger.kernel.org/majordomo-info.html
>> Please read the FAQ at  http://www.tux.org/lkml/
>
>
>


-- 
Best Regards
Shawn Lin



From k.kozlowski at samsung.com  Mon Aug 31 17:21:55 2015
From: k.kozlowski at samsung.com (Krzysztof Kozlowski)
Date: Tue, 01 Sep 2015 09:21:55 +0900
Subject: [PATCH] ARM: EXYNOS: reset KFC cores when cpu is up
In-Reply-To: <55E4D93E.4090307@osg.samsung.com>
References: <1441031111-6549-1-git-send-email-parkch98@gmail.com>
 <7hmvx785wx.fsf@deeprootsystems.com> <55E4D93E.4090307@osg.samsung.com>
Message-ID: <55E4EFA3.1050007@samsung.com>

On 01.09.2015 07:46, Javier Martinez Canillas wrote:
> 
> [adding Krzysztof Kozlowski to cc list]
> 
> Hello Kevin,
> 
> On 09/01/2015 12:11 AM, Kevin Hilman wrote:
>> Chanho Park <parkch98 at gmail.com> writes:
>>
>>> The cpu booting of exynos5422 has been still broken since we discussed
>>> it in last year[1]. This patch is inspired from odroid xu3
>>> code(Actually, it was from samsung exynos vendor kernel)[2]. This weird
>>> reset code was founded exynos5420 octa cores series SoCs and only
>>> required for the first boot core is the little core(kingfisher core).
>>> Some of the exynos5420 boards and all of the exynos5422 boards will be
>>> required this code.
>>> There is two ways to check the little core is the first cpu. One is
>>> checking GPG2CON[1] gpio value and the other is checking the cluster
>>> number of the first cpu. I selected the latter because it's more easier
>>> than the former.
>>>
>>> Changes since RFC[3]:
>>> - drop checking soc_is_exynos5800 to extend this codes to
>>> exynos5420/5422 boards.
>>> - kfc cores will be reset only if the cpu0 is kfc core.
>>> - Rebase top of the kukjin's for-next branch
>>>
>>> [1]:http://lists.infradead.org/pipermail/linux-arm-kernel/2015-June/350632.html
>>> [2]:https://patchwork.kernel.org/patch/6782891/
>>> [3]:http://lists.infradead.org/pipermail/linux-arm-kernel/2015-July/356610.html
>>>
>>> Cc: Joonyoung Shim <jy0922.shim at samsung.com>
>>> Cc: Chanwoo Choi <cw00.choi at samsung.com>
>>> Cc: Kevin Hilman <khilman at kernel.org>
>>> Cc: Heesub Shin <heesub.shin at samsung.com>
>>> Cc: Mauro Ribeiro <mauro.ribeiro at hardkernel.com>
>>> Cc: Abhilash Kesavan <a.kesavan at samsung.com>
>>> Cc: Przemyslaw Marczak <p.marczak at samsung.com>
>>> Cc: Marek Szyprowski <m.szyprowski at samsung.com>
>>> Cc: Krzysztof Kozlowski <k.kozlowski at samsung.com>
>>> Signed-off-by: Chanho Park <parkch98 at gmail.com>
>>
>>> ---
>>>  arch/arm/mach-exynos/mcpm-exynos.c | 18 +++++++++++++++++-
>>>  arch/arm/mach-exynos/regs-pmu.h    |  6 ++++++
>>>  2 files changed, 23 insertions(+), 1 deletion(-)
>>>
>>> diff --git a/arch/arm/mach-exynos/mcpm-exynos.c b/arch/arm/mach-exynos/mcpm-exynos.c
>>> index 9bdf547..5b69ed2 100644
>>> --- a/arch/arm/mach-exynos/mcpm-exynos.c
>>> +++ b/arch/arm/mach-exynos/mcpm-exynos.c
>>> @@ -20,6 +20,7 @@
>>>  #include <asm/cputype.h>
>>>  #include <asm/cp15.h>
>>>  #include <asm/mcpm.h>
>>> +#include <asm/smp_plat.h>
>>>  
>>>  #include "regs-pmu.h"
>>>  #include "common.h"
>>> @@ -70,7 +71,22 @@ static int exynos_cpu_powerup(unsigned int cpu, unsigned int cluster)
>>>  		cluster >= EXYNOS5420_NR_CLUSTERS)
>>>  		return -EINVAL;
>>>  
>>> -	exynos_cpu_power_up(cpunr);
>>> +	if (!exynos_cpu_power_state(cpunr)) {
>>> +		exynos_cpu_power_up(cpunr);
>>> +
>>> +		/* This assumes the cluster number of the eagle is 0 and the
>>> +		 * kfc is 1. When the system was booted from the kfc core,
>>> +		 * they should be reset */
>>
>> minor: fix multi-line comment style (search for 'multi-line' in
>> Documentation/CodingStyle)
>>
>> Also minor, but personally, I prefer seeing A15/A7 instead of eagle/KFC
>> as those names are fading from my memory and I can't seem to remember
>> which one is which. :/
>>
>>> +		if (cluster &&
>>> +		    cluster == MPIDR_AFFINITY_LEVEL(cpu_logical_map(0), 1)) {
>>> +			while (!pmu_raw_readl(S5P_PMU_SPARE2))
>>> +				udelay(10);
>>> +
>>> +			pmu_raw_writel(EXYNOS5420_KFC_CORE_RESET(cpu),
>>> +					EXYNOS_SWRESET);
>>> +		}
>>> +	}
>>> +
>>>  	return 0;
>>>  }
>>
>> I tested this on top of mainline (v4.2) using exynos_defconfig (with
>> BL_SWITCHER disabled) and I now see all 8 CPUs booting.  Nice!
>>
>> Tested-by: Kevin Hilman <khilman at linaro.org>
>>
>> Also, please note that this does not fix another fundamental problem
>> with this board in that the firmware puts CCI into secure mode, so
>> linux/MCPM cannot manage it, causing hangs whenever CPUidle is enabled
>> (because b.L cpuidle driver tries to use MCPM, which needs to manage
>> CCI.)
>>
>> In order for this to not hang when using CPUidle, the following patch is
>> also needed.
>>
>> Kevin
>>
>> diff --git a/arch/arm/boot/dts/exynos5422-odroidxu3.dts
>> b/arch/arm/boot/dts/exynos5422-odroidxu3.dts
>> index 78e6a502f320..7891bd05bf8e 100644
>> --- a/arch/arm/boot/dts/exynos5422-odroidxu3.dts
>> +++ b/arch/arm/boot/dts/exynos5422-odroidxu3.dts
>> @@ -49,3 +49,11 @@
>>                 shunt-resistor = <10000>;
>>         };
>>  };
>> +
>> +/*
>> + * Secure firmware prevents CCI access/usage from linux, so must be
>> disabled
>> + * to prevent usage by MCPM.
>> + */
>> +&cci {
>> +       status = "disabled";
>> +};
>>
>>
> 
> I posted a similar patch that instead disabling CCI for the XU3 board,
> it disables in exynos5422-odroidxu3-common.dtsi since all Exynos5422
> Odroid boards have the same broken firmware and so the same issue:
> 
> https://lkml.org/lkml/2015/8/29/59
> 
> Krzysztof tested it on an Odroid XU3 Lite and reported that disabling
> CCI caused some CPUs to fail to boot even with $subject applied:
> 
> https://lkml.org/lkml/2015/8/29/65

Indeed. On Odroid XU3 Chanho's patch gives me 8 CPUs up. Disabling CCI
causes fails on CPU{5,6,7} (Cortex-A15).

Best regards,
Krzysztof

> 
> Did you succeed booting all CPUs with CONFIG_ARM_BIG_LITTLE_CPUIDLE
> enabled and CCI disabled in the the Odroid XU3 DTS?
> 
> Best regards,
> 



From olof at lixom.net  Mon Aug 31 17:48:36 2015
From: olof at lixom.net (Olof Johansson)
Date: Mon, 31 Aug 2015 17:48:36 -0700
Subject: [GIT PULL 0/7] ARM: SoC changes for v4.3
In-Reply-To: <1441066030-23225-1-git-send-email-olof@lixom.net>
References: <1441066030-23225-1-git-send-email-olof@lixom.net>
Message-ID: <CAOesGMj_Gk8gcbBojzCwGbT6nufNdm0ocH62vVyjh_aMEBsfQg@mail.gmail.com>

On Mon, Aug 31, 2015 at 5:07 PM, Olof Johansson <olof at lixom.net> wrote:

> We've been able to keep conflicts down this cycle, only a few and none
> are hairy. I've described them in the affected pull requests.

Grmbl, I just fetched your tree and looked for new conflicts, and it
looks like a few more have crept in and diffstats are likely off from
the ones in my pull requests. Sorry about that.

New conflicts:

drivers/clk/ti/Makefike: Looks like an add/remove conflict on nearby
lines due to our addition of clk-814x.

drivers/pci/host/Kconfig: Bjorn and I picked up different versions of
the same fix for a problem that surfaced through the new arm64
dependencies. Go with Bjorn's.

drivers/pci/host/pci-iproc.c: Looks like whitespace delta on nearby changes.


-Olof


From scottwood at freescale.com  Mon Aug 31 17:49:51 2015
From: scottwood at freescale.com (Scott Wood)
Date: Mon, 31 Aug 2015 19:49:51 -0500
Subject: [RFC][PATCH 2/2] crypto: caam - handle core endianness != caam
 endianness
In-Reply-To: <1440762608-7866-1-git-send-email-horia.geanta@freescale.com>
References: <1440762306-7764-1-git-send-email-horia.geanta@freescale.com>
 <1440762608-7866-1-git-send-email-horia.geanta@freescale.com>
Message-ID: <1441068591.4966.47.camel@freescale.com>

On Fri, 2015-08-28 at 14:50 +0300, Horia Geant? wrote:
>  
> -#ifdef __BIG_ENDIAN
> -#define wr_reg32(reg, data) out_be32(reg, data)
> -#define rd_reg32(reg) in_be32(reg)
> +#ifdef CONFIG_CRYPTO_DEV_FSL_CAAM_LE
> +#define caam16_to_cpu(value) le16_to_cpu(value)
> +#define cpu_to_caam16(value) cpu_to_le16(value)
> +#define caam32_to_cpu(value) le32_to_cpu(value)
> +#define cpu_to_caam32(value) cpu_to_le32(value)
> +#define caam64_to_cpu(value) le64_to_cpu(value)
> +#define cpu_to_caam64(value) cpu_to_le64(value)

What if we want to build a kernel that supports a chip with an LE CAAM and 
another chip with a BE CAAM (e.g. ls1043a plus ls2080a)?  This information 
needs to come at runtime.

> +#ifdef CONFIG_ARCH_DMA_ADDR_T_64BIT
> +#ifdef CONFIG_SOC_IMX7D

Likewise, why is there an ifdef for a particular SoC type?

-Scott



From horms at verge.net.au  Mon Aug 31 18:09:58 2015
From: horms at verge.net.au (Simon Horman)
Date: Tue, 1 Sep 2015 10:09:58 +0900
Subject: [RESEND PATCH v3 3/5] sh: kill off set_irq_flags usage
In-Reply-To: <CAL_JsqJuPtkvFMFvcSwaFssXoLYrHs9bM3EedXSzj21YAPmwDQ@mail.gmail.com>
References: <1440889285-5637-1-git-send-email-robh@kernel.org>
 <1440889285-5637-4-git-send-email-robh@kernel.org>
 <20150831050104.GA26119@verge.net.au>
 <CAL_JsqJuPtkvFMFvcSwaFssXoLYrHs9bM3EedXSzj21YAPmwDQ@mail.gmail.com>
Message-ID: <20150901010958.GA29746@verge.net.au>

On Mon, Aug 31, 2015 at 07:52:07AM -0500, Rob Herring wrote:
> On Mon, Aug 31, 2015 at 12:01 AM, Simon Horman <horms at verge.net.au> wrote:
> > Hi Rob,
> >
> > On Sat, Aug 29, 2015 at 06:01:23PM -0500, Rob Herring wrote:
> >> set_irq_flags is ARM specific with custom flags which have genirq
> >> equivalents. Convert drivers to use the genirq interfaces directly, so we
> >> can kill off set_irq_flags. The translation of flags is as follows:
> >>
> >> IRQF_VALID -> !IRQ_NOREQUEST
> >> IRQF_PROBE -> !IRQ_NOPROBE
> >> IRQF_NOAUTOEN -> IRQ_NOAUTOEN
> >>
> >> For IRQs managed by an irqdomain, the irqdomain core code handles clearing
> >> and setting IRQ_NOREQUEST already, so there is no need to do this in
> >> .map() functions and we can simply remove the set_irq_flags calls. Some
> >> users also modify IRQ_NOPROBE and this has been maintained although it
> >> is not clear that is really needed. There appears to be a great deal of
> >> blind copy and paste of this code.
> >>
> >> Signed-off-by: Rob Herring <robh at kernel.org>
> >> Acked-by: Simon Horman <horms at verge.net.au>
> >> Cc: Magnus Damm <magnus.damm at gmail.com>
> >> Cc: linux-sh at vger.kernel.org
> >
> > I have queued this up. Please let me know if that was not your intent.
> >
> > The patch is queued up in the sh-drivers-for-v4.3 branch of my renesas tree.
> > At this point I plan to send a pull-request once dt changes that other
> > patches in that branch depend on hit Linus's tree via the ARM SoC tree.
> > I anticipate that being during the rc1 or rc2 timeframe.
> 
> This needs to go in before -rc1 so the final 2 patches removing
> set_irq_flags can go in at the end of the merge window. Given your
> timeline, I think you can just leave this one for Thomas to apply with
> those 2.

Sure, will do.


From dingtianhong at huawei.com  Mon Aug 31 18:14:12 2015
From: dingtianhong at huawei.com (Ding Tianhong)
Date: Tue, 1 Sep 2015 09:14:12 +0800
Subject: [PATCH 2/2] arm64: dts: add dts files for Hisilicon Hip05-D02
 Development Board
In-Reply-To: <20150831144019.GA22491@leoy-linaro>
References: <1440838361-1468-1-git-send-email-dingtianhong@huawei.com>
 <1440838361-1468-3-git-send-email-dingtianhong@huawei.com>
 <20150831131244.GB6194@leoy-linaro> <55E45A46.7040805@huawei.com>
 <20150831144019.GA22491@leoy-linaro>
Message-ID: <55E4FBE4.3010808@huawei.com>

On 2015/8/31 22:40, Leo Yan wrote:
> On Mon, Aug 31, 2015 at 09:44:38PM +0800, Ding Tianhong wrote:
>> On 2015/8/31 21:12, Leo Yan wrote:
>>> On Sat, Aug 29, 2015 at 04:52:41PM +0800, Ding Tianhong wrote:
>>>> Add initial dtsi file to support Hisilicon Hip05-D02 Board with
>>>> support of CPUs in four clusters and each cluster has quard Cortex-A57.
>>>>
>>>> Also add dts file to support Hip05-D02 development board.
>>>>
>>>> Signed-off-by: Ding Tianhong <dingtianhong at huawei.com>
>>>> Signed-off-by: Kefeng Wang <wangkefeng.wang at huawei.com>
>>>> ---
>>>>  arch/arm64/boot/dts/hisilicon/Makefile      |   2 +-
>>>>  arch/arm64/boot/dts/hisilicon/hip05-d02.dts |  36 ++++
>>>>  arch/arm64/boot/dts/hisilicon/hip05.dtsi    | 271 ++++++++++++++++++++++++++++
>>>>  3 files changed, 308 insertions(+), 1 deletion(-)
>>>>  create mode 100644 arch/arm64/boot/dts/hisilicon/hip05-d02.dts
>>>>  create mode 100644 arch/arm64/boot/dts/hisilicon/hip05.dtsi
>>>>
>>>> diff --git a/arch/arm64/boot/dts/hisilicon/Makefile b/arch/arm64/boot/dts/hisilicon/Makefile
>>>> index fa81a6e..cd158b8 100644
>>>> --- a/arch/arm64/boot/dts/hisilicon/Makefile
>>>> +++ b/arch/arm64/boot/dts/hisilicon/Makefile
>>>> @@ -1,4 +1,4 @@
>>>> -dtb-$(CONFIG_ARCH_HISI) += hi6220-hikey.dtb
>>>> +dtb-$(CONFIG_ARCH_HISI) += hi6220-hikey.dtb hip05-d02.dtb
>>>>  
>>>>  always		:= $(dtb-y)
>>>>  subdir-y	:= $(dts-dirs)
>>>> diff --git a/arch/arm64/boot/dts/hisilicon/hip05-d02.dts b/arch/arm64/boot/dts/hisilicon/hip05-d02.dts
>>>> new file mode 100644
>>>> index 0000000..ae34e25
>>>> --- /dev/null
>>>> +++ b/arch/arm64/boot/dts/hisilicon/hip05-d02.dts
>>>> @@ -0,0 +1,36 @@
>>>> +/**
>>>> + * dts file for Hisilicon D02 Development Board
>>>> + *
>>>> + * Copyright (C) 2014,2015 Hisilicon Ltd.
>>>> + *
>>>> + * 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
>>>> + * publishhed by the Free Software Foundation.
>>>> + *
>>>> + */
>>>> +
>>>> +/dts-v1/;
>>>> +
>>>> +#include "hip05.dtsi"
>>>> +
>>>> +/ {
>>>> +	model = "Hisilicon Hip05 D02 Development Board";
>>>> +	compatible = "hisilicon,hip05-d02";
>>>> +
>>>> +	memory at 00000000 {
>>>> +		device_type = "memory";
>>>> +		reg = <0x0 0x00000000 0x0 0x80000000>;
>>>> +	};
>>>> +
>>>> +	aliases {
>>>> +		serial0 = &uart0;
>>>> +	};
>>>> +
>>>> +	chosen {
>>>> +		stdout-path = "serial0:115200n8";
>>>> +	};
>>>> +};
>>>> +
>>>> +&uart0 {
>>>> +	status = "ok";
>>>> +};
>>>> diff --git a/arch/arm64/boot/dts/hisilicon/hip05.dtsi b/arch/arm64/boot/dts/hisilicon/hip05.dtsi
>>>> new file mode 100644
>>>> index 0000000..da12d94
>>>> --- /dev/null
>>>> +++ b/arch/arm64/boot/dts/hisilicon/hip05.dtsi
>>>> @@ -0,0 +1,271 @@
>>>> +/**
>>>> + * dts file for Hisilicon D02 Development Board
>>>> + *
>>>> + * Copyright (C) 2014,2015 Hisilicon Ltd.
>>>> + *
>>>> + * 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
>>>> + * publishhed by the Free Software Foundation.
>>>> + *
>>>> + */
>>>> +
>>>> +#include <dt-bindings/interrupt-controller/arm-gic.h>
>>>> +
>>>> +/ {
>>>> +	compatible = "hisilicon,hip05-d02";
>>>> +	interrupt-parent = <&gic>;
>>>> +	#address-cells = <2>;
>>>> +	#size-cells = <2>;
>>>> +
>>>> +	psci {
>>>> +		compatible = "arm,psci-0.2";
>>>> +		method = "smc";
>>>> +	};
>>>> +
>>>> +	cpus {
>>>> +		#address-cells = <1>;
>>>> +		#size-cells = <0>;
>>>> +
>>>> +		cpu-map {
>>>> +			cluster0 {
>>>> +				core0 {
>>>> +					cpu = <&cpu0>;
>>>> +				};
>>>> +				core1 {
>>>> +					cpu = <&cpu1>;
>>>> +				};
>>>> +				core2 {
>>>> +					cpu = <&cpu2>;
>>>> +				};
>>>> +				core3 {
>>>> +					cpu = <&cpu3>;
>>>> +				};
>>>> +			};
>>>> +			cluster1 {
>>>> +				core0 {
>>>> +					cpu = <&cpu4>;
>>>> +				};
>>>> +				core1 {
>>>> +					cpu = <&cpu5>;
>>>> +				};
>>>> +				core2 {
>>>> +					cpu = <&cpu6>;
>>>> +				};
>>>> +				core3 {
>>>> +					cpu = <&cpu7>;
>>>> +				};
>>>> +			};
>>>> +			cluster2 {
>>>> +				core0 {
>>>> +					cpu = <&cpu8>;
>>>> +				};
>>>> +				core1 {
>>>> +					cpu = <&cpu9>;
>>>> +				};
>>>> +				core2 {
>>>> +					cpu = <&cpu10>;
>>>> +				};
>>>> +				core3 {
>>>> +					cpu = <&cpu11>;
>>>> +				};
>>>> +			};
>>>> +			cluster3 {
>>>> +				core0 {
>>>> +					cpu = <&cpu12>;
>>>> +				};
>>>> +				core1 {
>>>> +					cpu = <&cpu13>;
>>>> +				};
>>>> +				core2 {
>>>> +					cpu = <&cpu14>;
>>>> +				};
>>>> +				core3 {
>>>> +					cpu = <&cpu15>;
>>>> +				};
>>>> +			};
>>>> +		};
>>>> +
>>>> +		cpu0: cpu at 20000 {
>>>> +			device_type = "cpu";
>>>> +			compatible = "arm,armv8";
>>>
>>> Change to "arm,cortex-a57","arm,armv8"?
>>>
>>
>> Ok?but I think should be "hisilicon,hip05","arm,armv8".
> 
> If the CPU is a starndard ARM core (such like CA53, CA57, etc), you
> need directly use the CPU type which has been defined in:
> Documentation/devicetree/bindings/arm/cpus.txt. So here hip05 is the
> naming code for SoC? or for the CPU customized by Hisilicon?
> 
> [...]

Hip05 is the name for SoC.

> 
> Thanks,
> Leo Yan
> 
> .
> 




From sboyd at codeaurora.org  Mon Aug 31 18:39:53 2015
From: sboyd at codeaurora.org (Stephen Boyd)
Date: Mon, 31 Aug 2015 18:39:53 -0700
Subject: [PATCH 2/3] soc: qcom: smd: Use __iowrite32_copy() instead of
 open-coding it
In-Reply-To: <1441071594-15941-1-git-send-email-sboyd@codeaurora.org>
References: <1441071594-15941-1-git-send-email-sboyd@codeaurora.org>
Message-ID: <1441071594-15941-3-git-send-email-sboyd@codeaurora.org>

We already have a function to do this and it silences some sparse
warnings along the way.

Cc: Bjorn Andersson <bjorn.andersson at sonymobile.com>
Signed-off-by: Stephen Boyd <sboyd at codeaurora.org>
---
 drivers/soc/qcom/smd.c | 13 ++++---------
 1 file changed, 4 insertions(+), 9 deletions(-)

diff --git a/drivers/soc/qcom/smd.c b/drivers/soc/qcom/smd.c
index c16547b85e05..91b7f5668962 100644
--- a/drivers/soc/qcom/smd.c
+++ b/drivers/soc/qcom/smd.c
@@ -371,20 +371,15 @@ static void qcom_smd_channel_set_state(struct qcom_smd_channel *channel,
 /*
  * Copy count bytes of data using 32bit accesses, if that's required.
  */
-static void smd_copy_to_fifo(void __iomem *_dst,
-			     const void *_src,
+static void smd_copy_to_fifo(void __iomem *dst,
+			     const void *src,
 			     size_t count,
 			     bool word_aligned)
 {
-	u32 *dst = (u32 *)_dst;
-	u32 *src = (u32 *)_src;
-
 	if (word_aligned) {
-		count /= sizeof(u32);
-		while (count--)
-			writel_relaxed(*src++, dst++);
+		__iowrite32_copy(dst, src, count / sizeof(u32));
 	} else {
-		memcpy_toio(_dst, _src, count);
+		memcpy_toio(dst, src, count);
 	}
 }
 
-- 
The Qualcomm Innovation Center, Inc. is a member of the Code Aurora Forum,
a Linux Foundation Collaborative Project



From sboyd at codeaurora.org  Mon Aug 31 18:39:51 2015
From: sboyd at codeaurora.org (Stephen Boyd)
Date: Mon, 31 Aug 2015 18:39:51 -0700
Subject: [PATCH 0/3] qcom smd big endian support
Message-ID: <1441071594-15941-1-git-send-email-sboyd@codeaurora.org>

This set of patches does some tidying in the beginning to prepare
for adding big endian CPU support to the smd code. It builds on a
previous patch to add big endian support to smem.

Stephen Boyd (3):
  soc: qcom: smd: Represent channel layout in structures
  soc: qcom: smd: Use __iowrite32_copy() instead of open-coding it
  soc: qcom: smd: Handle big endian CPUs

 drivers/soc/qcom/smd.c | 221 ++++++++++++++++++++++++++++++-------------------
 1 file changed, 136 insertions(+), 85 deletions(-)

-- 
The Qualcomm Innovation Center, Inc. is a member of the Code Aurora Forum,
a Linux Foundation Collaborative Project



From sboyd at codeaurora.org  Mon Aug 31 18:39:52 2015
From: sboyd at codeaurora.org (Stephen Boyd)
Date: Mon, 31 Aug 2015 18:39:52 -0700
Subject: [PATCH 1/3] soc: qcom: smd: Represent channel layout in structures
In-Reply-To: <1441071594-15941-1-git-send-email-sboyd@codeaurora.org>
References: <1441071594-15941-1-git-send-email-sboyd@codeaurora.org>
Message-ID: <1441071594-15941-2-git-send-email-sboyd@codeaurora.org>

The rx and tx channel info are laid out in memory next to each
other, and there are two types of channel info structures, byte
based and word based. We have 4 pointers to these info
structures, when we really only need two to point to the
different types of structures. Encapsulate the byte based and word
based tx/rx structures in a "full channel" structure that
describes the layout of memory and reduces the number of pointers
in the smd channel structure by two.

Cc: Bjorn Andersson <bjorn.andersson at sonymobile.com>
Signed-off-by: Stephen Boyd <sboyd at codeaurora.org>
---
 drivers/soc/qcom/smd.c | 61 +++++++++++++++++++++++++++-----------------------
 1 file changed, 33 insertions(+), 28 deletions(-)

diff --git a/drivers/soc/qcom/smd.c b/drivers/soc/qcom/smd.c
index edd9d9a37238..c16547b85e05 100644
--- a/drivers/soc/qcom/smd.c
+++ b/drivers/soc/qcom/smd.c
@@ -65,7 +65,9 @@
  */
 
 struct smd_channel_info;
+struct smd_full_channel_info;
 struct smd_channel_info_word;
+struct smd_full_channel_info_word;
 
 #define SMD_ALLOC_TBL_COUNT	2
 #define SMD_ALLOC_TBL_SIZE	64
@@ -151,10 +153,8 @@ enum smd_channel_state {
  * @name:		name of the channel
  * @state:		local state of the channel
  * @remote_state:	remote state of the channel
- * @tx_info:		byte aligned outgoing channel info
- * @rx_info:		byte aligned incoming channel info
- * @tx_info_word:	word aligned outgoing channel info
- * @rx_info_word:	word aligned incoming channel info
+ * @info:		byte aligned outgoing/incoming channel info
+ * @info_word:		word aligned outgoing/incoming channel info
  * @tx_lock:		lock to make writes to the channel mutually exclusive
  * @fblockread_event:	wakeup event tied to tx fBLOCKREADINTR
  * @tx_fifo:		pointer to the outgoing ring buffer
@@ -175,11 +175,8 @@ struct qcom_smd_channel {
 	enum smd_channel_state state;
 	enum smd_channel_state remote_state;
 
-	struct smd_channel_info *tx_info;
-	struct smd_channel_info *rx_info;
-
-	struct smd_channel_info_word *tx_info_word;
-	struct smd_channel_info_word *rx_info_word;
+	struct smd_full_channel_info *info;
+	struct smd_full_channel_info_word *info_word;
 
 	struct mutex tx_lock;
 	wait_queue_head_t fblockread_event;
@@ -228,6 +225,11 @@ struct smd_channel_info {
 	u32 head;
 };
 
+struct smd_full_channel_info {
+	struct smd_channel_info tx;
+	struct smd_channel_info rx;
+};
+
 /*
  * Format of the smd_info smem items, for word aligned channels.
  */
@@ -245,25 +247,30 @@ struct smd_channel_info_word {
 	u32 head;
 };
 
+struct smd_full_channel_info_word {
+	struct smd_channel_info_word tx;
+	struct smd_channel_info_word rx;
+};
+
 #define GET_RX_CHANNEL_INFO(channel, param) \
-	(channel->rx_info_word ? \
-		channel->rx_info_word->param : \
-		channel->rx_info->param)
+	(channel->info_word ? \
+		channel->info_word->rx.param : \
+		channel->info->rx.param)
 
 #define SET_RX_CHANNEL_INFO(channel, param, value) \
-	(channel->rx_info_word ? \
-		(channel->rx_info_word->param = value) : \
-		(channel->rx_info->param = value))
+	(channel->info_word ? \
+		(channel->info_word->rx.param = value) : \
+		(channel->info->rx.param = value))
 
 #define GET_TX_CHANNEL_INFO(channel, param) \
-	(channel->tx_info_word ? \
-		channel->tx_info_word->param : \
-		channel->tx_info->param)
+	(channel->info_word ? \
+		channel->info_word->tx.param : \
+		channel->info->tx.param)
 
 #define SET_TX_CHANNEL_INFO(channel, param, value) \
-	(channel->tx_info_word ? \
-		(channel->tx_info_word->param = value) : \
-		(channel->tx_info->param = value))
+	(channel->info_word ? \
+		(channel->info_word->tx.param = value) : \
+		(channel->info->tx.param = value))
 
 /**
  * struct qcom_smd_alloc_entry - channel allocation entry
@@ -412,7 +419,7 @@ static size_t qcom_smd_channel_peek(struct qcom_smd_channel *channel,
 	unsigned tail;
 	size_t len;
 
-	word_aligned = channel->rx_info_word != NULL;
+	word_aligned = channel->info_word;
 	tail = GET_RX_CHANNEL_INFO(channel, tail);
 
 	len = min_t(size_t, count, channel->fifo_size - tail);
@@ -627,7 +634,7 @@ static int qcom_smd_write_fifo(struct qcom_smd_channel *channel,
 	unsigned head;
 	size_t len;
 
-	word_aligned = channel->tx_info_word != NULL;
+	word_aligned = channel->info_word;
 	head = GET_TX_CHANNEL_INFO(channel, head);
 
 	len = min_t(size_t, count, channel->fifo_size - head);
@@ -670,7 +677,7 @@ int qcom_smd_send(struct qcom_smd_channel *channel, const void *data, int len)
 	int ret;
 
 	/* Word aligned channels only accept word size aligned data */
-	if (channel->rx_info_word != NULL && len % 4)
+	if (channel->info_word && len % 4)
 		return -EINVAL;
 
 	ret = mutex_lock_interruptible(&channel->tx_lock);
@@ -988,11 +995,9 @@ static struct qcom_smd_channel *qcom_smd_create_channel(struct qcom_smd_edge *ed
 	 * use.
 	 */
 	if (info_size == 2 * sizeof(struct smd_channel_info_word)) {
-		channel->tx_info_word = info;
-		channel->rx_info_word = info + sizeof(struct smd_channel_info_word);
+		channel->info_word = info;
 	} else if (info_size == 2 * sizeof(struct smd_channel_info)) {
-		channel->tx_info = info;
-		channel->rx_info = info + sizeof(struct smd_channel_info);
+		channel->info = info;
 	} else {
 		dev_err(smd->dev,
 			"channel info of size %zu not supported\n", info_size);
-- 
The Qualcomm Innovation Center, Inc. is a member of the Code Aurora Forum,
a Linux Foundation Collaborative Project



From sboyd at codeaurora.org  Mon Aug 31 18:39:54 2015
From: sboyd at codeaurora.org (Stephen Boyd)
Date: Mon, 31 Aug 2015 18:39:54 -0700
Subject: [PATCH 3/3] soc: qcom: smd: Handle big endian CPUs
In-Reply-To: <1441071594-15941-1-git-send-email-sboyd@codeaurora.org>
References: <1441071594-15941-1-git-send-email-sboyd@codeaurora.org>
Message-ID: <1441071594-15941-4-git-send-email-sboyd@codeaurora.org>

The smd structures are always in little endian, but the smd
driver is not capable of being used on big endian CPUs. Annotate
the little endian data members and update the code to do the
proper byte swapping.

Cc: Bjorn Andersson <bjorn.andersson at sonymobile.com>
Signed-off-by: Stephen Boyd <sboyd at codeaurora.org>
---
 drivers/soc/qcom/smd.c | 173 ++++++++++++++++++++++++++++++++-----------------
 1 file changed, 112 insertions(+), 61 deletions(-)

diff --git a/drivers/soc/qcom/smd.c b/drivers/soc/qcom/smd.c
index 91b7f5668962..53642a874339 100644
--- a/drivers/soc/qcom/smd.c
+++ b/drivers/soc/qcom/smd.c
@@ -212,7 +212,7 @@ struct qcom_smd {
  * Format of the smd_info smem items, for byte aligned channels.
  */
 struct smd_channel_info {
-	u32 state;
+	__le32 state;
 	u8  fDSR;
 	u8  fCTS;
 	u8  fCD;
@@ -221,8 +221,8 @@ struct smd_channel_info {
 	u8  fTAIL;
 	u8  fSTATE;
 	u8  fBLOCKREADINTR;
-	u32 tail;
-	u32 head;
+	__le32 tail;
+	__le32 head;
 };
 
 struct smd_full_channel_info {
@@ -234,17 +234,17 @@ struct smd_full_channel_info {
  * Format of the smd_info smem items, for word aligned channels.
  */
 struct smd_channel_info_word {
-	u32 state;
-	u32 fDSR;
-	u32 fCTS;
-	u32 fCD;
-	u32 fRI;
-	u32 fHEAD;
-	u32 fTAIL;
-	u32 fSTATE;
-	u32 fBLOCKREADINTR;
-	u32 tail;
-	u32 head;
+	__le32 state;
+	__le32 fDSR;
+	__le32 fCTS;
+	__le32 fCD;
+	__le32 fRI;
+	__le32 fHEAD;
+	__le32 fTAIL;
+	__le32 fSTATE;
+	__le32 fBLOCKREADINTR;
+	__le32 tail;
+	__le32 head;
 };
 
 struct smd_full_channel_info_word {
@@ -252,25 +252,73 @@ struct smd_full_channel_info_word {
 	struct smd_channel_info_word rx;
 };
 
-#define GET_RX_CHANNEL_INFO(channel, param) \
-	(channel->info_word ? \
-		channel->info_word->rx.param : \
-		channel->info->rx.param)
-
-#define SET_RX_CHANNEL_INFO(channel, param, value) \
-	(channel->info_word ? \
-		(channel->info_word->rx.param = value) : \
-		(channel->info->rx.param = value))
-
-#define GET_TX_CHANNEL_INFO(channel, param) \
-	(channel->info_word ? \
-		channel->info_word->tx.param : \
-		channel->info->tx.param)
-
-#define SET_TX_CHANNEL_INFO(channel, param, value) \
-	(channel->info_word ? \
-		(channel->info_word->tx.param = value) : \
-		(channel->info->tx.param = value))
+#define GET_RX_CHANNEL_INFO8(channel, param)				     \
+	({								     \
+		BUILD_BUG_ON(sizeof(channel->info->rx.param) != sizeof(u8)); \
+		channel->info_word ?					     \
+			le32_to_cpu(channel->info_word->rx.param) :	     \
+			channel->info->rx.param;			     \
+	})
+
+#define GET_RX_CHANNEL_INFO(channel, param)				      \
+	({								      \
+		BUILD_BUG_ON(sizeof(channel->info->rx.param) != sizeof(u32)); \
+		le32_to_cpu(channel->info_word ?			      \
+			channel->info_word->rx.param :			      \
+			channel->info->rx.param);			      \
+	})
+
+#define SET_RX_CHANNEL_INFO8(channel, param, value)			     \
+	({								     \
+		BUILD_BUG_ON(sizeof(channel->info->rx.param) != sizeof(u8)); \
+		if (channel->info_word)					     \
+			channel->info_word->rx.param = cpu_to_le32(value);   \
+		else							     \
+			channel->info->rx.param = value;		     \
+	})
+
+#define SET_RX_CHANNEL_INFO(channel, param, value)			      \
+	({								      \
+		BUILD_BUG_ON(sizeof(channel->info->rx.param) != sizeof(u32)); \
+		if (channel->info_word)					      \
+			channel->info_word->rx.param = cpu_to_le32(value);   \
+		else							      \
+			channel->info->rx.param = cpu_to_le32(value);	      \
+	})
+
+#define GET_TX_CHANNEL_INFO8(channel, param)				     \
+	({								     \
+		BUILD_BUG_ON(sizeof(channel->info->tx.param) != sizeof(u8)); \
+		channel->info_word ?					     \
+			le32_to_cpu(channel->info_word->tx.param) :          \
+			channel->info->tx.param;			     \
+	})
+
+#define GET_TX_CHANNEL_INFO(channel, param)				      \
+	({								      \
+		BUILD_BUG_ON(sizeof(channel->info->tx.param) != sizeof(u32)); \
+		le32_to_cpu(channel->info_word ?			      \
+			channel->info_word->tx.param :			      \
+			channel->info->tx.param);			      \
+	})
+
+#define SET_TX_CHANNEL_INFO8(channel, param, value)			     \
+	({								     \
+		BUILD_BUG_ON(sizeof(channel->info->tx.param) != sizeof(u8)); \
+		if (channel->info_word)					     \
+			channel->info_word->tx.param = cpu_to_le32(value);   \
+		else							     \
+			channel->info->tx.param = value;		     \
+	})
+
+#define SET_TX_CHANNEL_INFO(channel, param, value)			      \
+	({								      \
+		BUILD_BUG_ON(sizeof(channel->info->tx.param) != sizeof(u32)); \
+		if (channel->info_word)					      \
+			channel->info_word->tx.param = cpu_to_le32(value);   \
+		else							      \
+			channel->info->tx.param = cpu_to_le32(value);	      \
+	})
 
 /**
  * struct qcom_smd_alloc_entry - channel allocation entry
@@ -281,9 +329,9 @@ struct smd_full_channel_info_word {
  */
 struct qcom_smd_alloc_entry {
 	u8 name[20];
-	u32 cid;
-	u32 flags;
-	u32 ref_count;
+	__le32 cid;
+	__le32 flags;
+	__le32 ref_count;
 } __packed;
 
 #define SMD_CHANNEL_FLAGS_EDGE_MASK	0xff
@@ -312,14 +360,14 @@ static void qcom_smd_signal_channel(struct qcom_smd_channel *channel)
 static void qcom_smd_channel_reset(struct qcom_smd_channel *channel)
 {
 	SET_TX_CHANNEL_INFO(channel, state, SMD_CHANNEL_CLOSED);
-	SET_TX_CHANNEL_INFO(channel, fDSR, 0);
-	SET_TX_CHANNEL_INFO(channel, fCTS, 0);
-	SET_TX_CHANNEL_INFO(channel, fCD, 0);
-	SET_TX_CHANNEL_INFO(channel, fRI, 0);
-	SET_TX_CHANNEL_INFO(channel, fHEAD, 0);
-	SET_TX_CHANNEL_INFO(channel, fTAIL, 0);
-	SET_TX_CHANNEL_INFO(channel, fSTATE, 1);
-	SET_TX_CHANNEL_INFO(channel, fBLOCKREADINTR, 0);
+	SET_TX_CHANNEL_INFO8(channel, fDSR, 0);
+	SET_TX_CHANNEL_INFO8(channel, fCTS, 0);
+	SET_TX_CHANNEL_INFO8(channel, fCD, 0);
+	SET_TX_CHANNEL_INFO8(channel, fRI, 0);
+	SET_TX_CHANNEL_INFO8(channel, fHEAD, 0);
+	SET_TX_CHANNEL_INFO8(channel, fTAIL, 0);
+	SET_TX_CHANNEL_INFO8(channel, fSTATE, 1);
+	SET_TX_CHANNEL_INFO8(channel, fBLOCKREADINTR, 0);
 	SET_TX_CHANNEL_INFO(channel, head, 0);
 	SET_TX_CHANNEL_INFO(channel, tail, 0);
 
@@ -357,12 +405,12 @@ static void qcom_smd_channel_set_state(struct qcom_smd_channel *channel,
 
 	dev_dbg(edge->smd->dev, "set_state(%s, %d)\n", channel->name, state);
 
-	SET_TX_CHANNEL_INFO(channel, fDSR, is_open);
-	SET_TX_CHANNEL_INFO(channel, fCTS, is_open);
-	SET_TX_CHANNEL_INFO(channel, fCD, is_open);
+	SET_TX_CHANNEL_INFO8(channel, fDSR, is_open);
+	SET_TX_CHANNEL_INFO8(channel, fCTS, is_open);
+	SET_TX_CHANNEL_INFO8(channel, fCD, is_open);
 
 	SET_TX_CHANNEL_INFO(channel, state, state);
-	SET_TX_CHANNEL_INFO(channel, fSTATE, 1);
+	SET_TX_CHANNEL_INFO8(channel, fSTATE, 1);
 
 	channel->state = state;
 	qcom_smd_signal_channel(channel);
@@ -504,10 +552,10 @@ static bool qcom_smd_channel_intr(struct qcom_smd_channel *channel)
 		need_state_scan = true;
 	}
 	/* Indicate that we have seen any state change */
-	SET_RX_CHANNEL_INFO(channel, fSTATE, 0);
+	SET_RX_CHANNEL_INFO8(channel, fSTATE, 0);
 
 	/* Signal waiting qcom_smd_send() about the interrupt */
-	if (!GET_TX_CHANNEL_INFO(channel, fBLOCKREADINTR))
+	if (!GET_TX_CHANNEL_INFO8(channel, fBLOCKREADINTR))
 		wake_up_interruptible(&channel->fblockread_event);
 
 	/* Don't consume any data until we've opened the channel */
@@ -515,7 +563,7 @@ static bool qcom_smd_channel_intr(struct qcom_smd_channel *channel)
 		goto out;
 
 	/* Indicate that we've seen the new data */
-	SET_RX_CHANNEL_INFO(channel, fHEAD, 0);
+	SET_RX_CHANNEL_INFO8(channel, fHEAD, 0);
 
 	/* Consume data */
 	for (;;) {
@@ -535,10 +583,10 @@ static bool qcom_smd_channel_intr(struct qcom_smd_channel *channel)
 	}
 
 	/* Indicate that we have seen and updated tail */
-	SET_RX_CHANNEL_INFO(channel, fTAIL, 1);
+	SET_RX_CHANNEL_INFO8(channel, fTAIL, 1);
 
 	/* Signal the remote that we've consumed the data (if requested) */
-	if (!GET_RX_CHANNEL_INFO(channel, fBLOCKREADINTR)) {
+	if (!GET_RX_CHANNEL_INFO8(channel, fBLOCKREADINTR)) {
 		/* Ensure ordering of channel info updates */
 		wmb();
 
@@ -685,7 +733,7 @@ int qcom_smd_send(struct qcom_smd_channel *channel, const void *data, int len)
 			goto out;
 		}
 
-		SET_TX_CHANNEL_INFO(channel, fBLOCKREADINTR, 1);
+		SET_TX_CHANNEL_INFO8(channel, fBLOCKREADINTR, 1);
 
 		ret = wait_event_interruptible(channel->fblockread_event,
 				       qcom_smd_get_tx_avail(channel) >= tlen ||
@@ -693,15 +741,15 @@ int qcom_smd_send(struct qcom_smd_channel *channel, const void *data, int len)
 		if (ret)
 			goto out;
 
-		SET_TX_CHANNEL_INFO(channel, fBLOCKREADINTR, 0);
+		SET_TX_CHANNEL_INFO8(channel, fBLOCKREADINTR, 0);
 	}
 
-	SET_TX_CHANNEL_INFO(channel, fTAIL, 0);
+	SET_TX_CHANNEL_INFO8(channel, fTAIL, 0);
 
 	qcom_smd_write_fifo(channel, hdr, sizeof(hdr));
 	qcom_smd_write_fifo(channel, data, len);
 
-	SET_TX_CHANNEL_INFO(channel, fHEAD, 1);
+	SET_TX_CHANNEL_INFO8(channel, fHEAD, 1);
 
 	/* Ensure ordering of channel info updates */
 	wmb();
@@ -1043,6 +1091,7 @@ static void qcom_discover_channels(struct qcom_smd_edge *edge)
 	int ret;
 	int tbl;
 	int i;
+	u32 eflags, cid;
 
 	for (tbl = 0; tbl < SMD_ALLOC_TBL_COUNT; tbl++) {
 		ret = qcom_smem_get(edge->remote_pid,
@@ -1054,6 +1103,7 @@ static void qcom_discover_channels(struct qcom_smd_edge *edge)
 
 		for (i = 0; i < SMD_ALLOC_TBL_SIZE; i++) {
 			entry = &alloc_tbl[i];
+			eflags = le32_to_cpu(entry->flags);
 			if (test_bit(i, edge->allocated[tbl]))
 				continue;
 
@@ -1063,14 +1113,15 @@ static void qcom_discover_channels(struct qcom_smd_edge *edge)
 			if (!entry->name[0])
 				continue;
 
-			if (!(entry->flags & SMD_CHANNEL_FLAGS_PACKET))
+			if (!(eflags & SMD_CHANNEL_FLAGS_PACKET))
 				continue;
 
-			if ((entry->flags & SMD_CHANNEL_FLAGS_EDGE_MASK) != edge->edge_id)
+			if ((eflags & SMD_CHANNEL_FLAGS_EDGE_MASK) != edge->edge_id)
 				continue;
 
-			info_id = smem_items[tbl].info_base_id + entry->cid;
-			fifo_id = smem_items[tbl].fifo_base_id + entry->cid;
+			cid = le32_to_cpu(entry->cid);
+			info_id = smem_items[tbl].info_base_id + cid;
+			fifo_id = smem_items[tbl].fifo_base_id + cid;
 
 			channel = qcom_smd_create_channel(edge, info_id, fifo_id, entry->name);
 			if (IS_ERR(channel))
-- 
The Qualcomm Innovation Center, Inc. is a member of the Code Aurora Forum,
a Linux Foundation Collaborative Project



From sboyd at codeaurora.org  Mon Aug 31 18:41:06 2015
From: sboyd at codeaurora.org (Stephen Boyd)
Date: Mon, 31 Aug 2015 18:41:06 -0700
Subject: [PATCH] soc: qcom: Make qcom_smem_get() return a pointer
Message-ID: <1441071666-16156-1-git-send-email-sboyd@codeaurora.org>

Passing a void ** almost always requires a cast at the call site.
Instead of littering the code with casts every time this function
is called, have qcom_smem_get() return a void pointer to the
location of the smem item. This frees the caller from having to
cast the pointer with the small downside of doing some extra work
to find the item in the case that the caller doesn't care to use
the pointer.

Cc: Bjorn Andersson <bjorn.andersson at sonymobile.com>
Signed-off-by: Stephen Boyd <sboyd at codeaurora.org>
---

This is on top of the smd and smem big endian support.

 drivers/soc/qcom/smd.c        | 30 +++++++++---------
 drivers/soc/qcom/smem.c       | 73 +++++++++++++++++++------------------------
 include/linux/soc/qcom/smem.h |  2 +-
 3 files changed, 48 insertions(+), 57 deletions(-)

diff --git a/drivers/soc/qcom/smd.c b/drivers/soc/qcom/smd.c
index 53642a874339..b3526d096d05 100644
--- a/drivers/soc/qcom/smd.c
+++ b/drivers/soc/qcom/smd.c
@@ -1028,10 +1028,11 @@ static struct qcom_smd_channel *qcom_smd_create_channel(struct qcom_smd_edge *ed
 	spin_lock_init(&channel->recv_lock);
 	init_waitqueue_head(&channel->fblockread_event);
 
-	ret = qcom_smem_get(edge->remote_pid, smem_info_item, (void **)&info,
-			    &info_size);
-	if (ret)
+	info = qcom_smem_get(edge->remote_pid, smem_info_item, &info_size);
+	if (IS_ERR(info)) {
+		ret = PTR_ERR(info);
 		goto free_name_and_channel;
+	}
 
 	/*
 	 * Use the size of the item to figure out which channel info struct to
@@ -1048,10 +1049,11 @@ static struct qcom_smd_channel *qcom_smd_create_channel(struct qcom_smd_edge *ed
 		goto free_name_and_channel;
 	}
 
-	ret = qcom_smem_get(edge->remote_pid, smem_fifo_item, &fifo_base,
-			    &fifo_size);
-	if (ret)
+	fifo_base = qcom_smem_get(edge->remote_pid, smem_fifo_item, &fifo_size);
+	if (IS_ERR(fifo_base)) {
+		ret =  PTR_ERR(fifo_base);
 		goto free_name_and_channel;
+	}
 
 	/* The channel consist of a rx and tx fifo of equal size */
 	fifo_size /= 2;
@@ -1088,17 +1090,14 @@ static void qcom_discover_channels(struct qcom_smd_edge *edge)
 	unsigned long flags;
 	unsigned fifo_id;
 	unsigned info_id;
-	int ret;
 	int tbl;
 	int i;
 	u32 eflags, cid;
 
 	for (tbl = 0; tbl < SMD_ALLOC_TBL_COUNT; tbl++) {
-		ret = qcom_smem_get(edge->remote_pid,
-				    smem_items[tbl].alloc_tbl_id,
-				    (void **)&alloc_tbl,
-				    NULL);
-		if (ret < 0)
+		alloc_tbl = qcom_smem_get(edge->remote_pid,
+				    smem_items[tbl].alloc_tbl_id, NULL);
+		if (IS_ERR(alloc_tbl))
 			continue;
 
 		for (i = 0; i < SMD_ALLOC_TBL_SIZE; i++) {
@@ -1278,11 +1277,12 @@ static int qcom_smd_probe(struct platform_device *pdev)
 	int num_edges;
 	int ret;
 	int i = 0;
+	void *p;
 
 	/* Wait for smem */
-	ret = qcom_smem_get(QCOM_SMEM_HOST_ANY, smem_items[0].alloc_tbl_id, NULL, NULL);
-	if (ret == -EPROBE_DEFER)
-		return ret;
+	p = qcom_smem_get(QCOM_SMEM_HOST_ANY, smem_items[0].alloc_tbl_id, NULL);
+	if (PTR_ERR(p) == -EPROBE_DEFER)
+		return PTR_ERR(p);
 
 	num_edges = of_get_available_child_count(pdev->dev.of_node);
 	array_size = sizeof(*smd) + num_edges * sizeof(struct qcom_smd_edge);
diff --git a/drivers/soc/qcom/smem.c b/drivers/soc/qcom/smem.c
index 889bd23316fd..74017114ce6e 100644
--- a/drivers/soc/qcom/smem.c
+++ b/drivers/soc/qcom/smem.c
@@ -418,10 +418,9 @@ int qcom_smem_alloc(unsigned host, unsigned item, size_t size)
 }
 EXPORT_SYMBOL(qcom_smem_alloc);
 
-static int qcom_smem_get_global(struct qcom_smem *smem,
-				unsigned item,
-				void **ptr,
-				size_t *size)
+static void *qcom_smem_get_global(struct qcom_smem *smem,
+				  unsigned item,
+				  size_t *size)
 {
 	struct smem_header *header;
 	struct smem_region *area;
@@ -430,37 +429,32 @@ static int qcom_smem_get_global(struct qcom_smem *smem,
 	unsigned i;
 
 	if (WARN_ON(item >= SMEM_ITEM_COUNT))
-		return -EINVAL;
+		return ERR_PTR(-EINVAL);
 
 	header = smem->regions[0].virt_base;
 	entry = &header->toc[item];
 	if (!entry->allocated)
-		return -ENXIO;
+		return ERR_PTR(-ENXIO);
 
-	if (ptr != NULL) {
-		aux_base = le32_to_cpu(entry->aux_base) & AUX_BASE_MASK;
+	aux_base = le32_to_cpu(entry->aux_base) & AUX_BASE_MASK;
 
-		for (i = 0; i < smem->num_regions; i++) {
-			area = &smem->regions[i];
+	for (i = 0; i < smem->num_regions; i++) {
+		area = &smem->regions[i];
 
-			if (area->aux_base == aux_base || !aux_base) {
-				*ptr = area->virt_base +
-				       le32_to_cpu(entry->offset);
-				break;
-			}
+		if (area->aux_base == aux_base || !aux_base) {
+			if (size != NULL)
+				*size = le32_to_cpu(entry->size);
+			return area->virt_base + le32_to_cpu(entry->offset);
 		}
 	}
-	if (size != NULL)
-		*size = le32_to_cpu(entry->size);
 
-	return 0;
+	return ERR_PTR(-ENOENT);
 }
 
-static int qcom_smem_get_private(struct qcom_smem *smem,
-				 unsigned host,
-				 unsigned item,
-				 void **ptr,
-				 size_t *size)
+static void *qcom_smem_get_private(struct qcom_smem *smem,
+				   unsigned host,
+				   unsigned item,
+				   size_t *size)
 {
 	struct smem_partition_header *phdr;
 	struct smem_private_entry *e, *end;
@@ -474,56 +468,55 @@ static int qcom_smem_get_private(struct qcom_smem *smem,
 			dev_err(smem->dev,
 				"Found invalid canary in host %d partition\n",
 				host);
-			return -EINVAL;
+			return ERR_PTR(-EINVAL);
 		}
 
 		if (le16_to_cpu(e->item) == item) {
-			if (ptr != NULL)
-				*ptr = entry_to_item(e);
-
 			if (size != NULL)
 				*size = le32_to_cpu(e->size) -
 					le16_to_cpu(e->padding_data);
 
-			return 0;
+			return entry_to_item(e);
 		}
 
 		e = private_entry_next(e);
 	}
 
-	return -ENOENT;
+	return ERR_PTR(-ENOENT);
 }
 
 /**
  * qcom_smem_get() - resolve ptr of size of a smem item
  * @host:	the remote processor, or -1
  * @item:	smem item handle
- * @ptr:	pointer to be filled out with address of the item
  * @size:	pointer to be filled out with size of the item
  *
- * Looks up pointer and size of a smem item.
+ * Looks up smem item and returns pointer to it. Size of smem
+ * item is returned in @size.
  */
-int qcom_smem_get(unsigned host, unsigned item, void **ptr, size_t *size)
+void *qcom_smem_get(unsigned host, unsigned item, size_t *size)
 {
 	unsigned long flags;
 	int ret;
+	void *ptr = ERR_PTR(-EPROBE_DEFER);
 
 	if (!__smem)
-		return -EPROBE_DEFER;
+		return ptr;
 
 	ret = hwspin_lock_timeout_irqsave(__smem->hwlock,
 					  HWSPINLOCK_TIMEOUT,
 					  &flags);
 	if (ret)
-		return ret;
+		return ERR_PTR(ret);
 
 	if (host < SMEM_HOST_COUNT && __smem->partitions[host])
-		ret = qcom_smem_get_private(__smem, host, item, ptr, size);
+		ptr = qcom_smem_get_private(__smem, host, item, size);
 	else
-		ret = qcom_smem_get_global(__smem, item, ptr, size);
+		ptr = qcom_smem_get_global(__smem, item, size);
 
 	hwspin_unlock_irqrestore(__smem->hwlock, &flags);
-	return ret;
+
+	return ptr;
 
 }
 EXPORT_SYMBOL(qcom_smem_get);
@@ -561,11 +554,9 @@ static int qcom_smem_get_sbl_version(struct qcom_smem *smem)
 {
 	__le32 *versions;
 	size_t size;
-	int ret;
 
-	ret = qcom_smem_get_global(smem, SMEM_ITEM_VERSION,
-				   (void **)&versions, &size);
-	if (ret < 0) {
+	versions = qcom_smem_get_global(smem, SMEM_ITEM_VERSION, &size);
+	if (IS_ERR(versions)) {
 		dev_err(smem->dev, "Unable to read the version item\n");
 		return -ENOENT;
 	}
diff --git a/include/linux/soc/qcom/smem.h b/include/linux/soc/qcom/smem.h
index bc9630d3aced..785e196ee2ca 100644
--- a/include/linux/soc/qcom/smem.h
+++ b/include/linux/soc/qcom/smem.h
@@ -4,7 +4,7 @@
 #define QCOM_SMEM_HOST_ANY -1
 
 int qcom_smem_alloc(unsigned host, unsigned item, size_t size);
-int qcom_smem_get(unsigned host, unsigned item, void **ptr, size_t *size);
+void *qcom_smem_get(unsigned host, unsigned item, size_t *size);
 
 int qcom_smem_get_free_space(unsigned host);
 
-- 
The Qualcomm Innovation Center, Inc. is a member of the Code Aurora Forum,
a Linux Foundation Collaborative Project



From shijie.huang at arm.com  Mon Aug 31 18:41:23 2015
From: shijie.huang at arm.com (Huang Shijie)
Date: Tue,  1 Sep 2015 09:41:23 +0800
Subject: [PATCH] arm64: dts: juno: replace the hardcode with the proper macros
Message-ID: <1441071683-3497-1-git-send-email-shijie.huang@arm.com>

The old code uses hardcode for the memtimer's interrupt property,
this patch replaces the hardcode with the proper macros.

Signed-off-by: Huang Shijie <shijie.huang at arm.com>
---
 arch/arm64/boot/dts/arm/juno-base.dtsi | 2 +-
 1 file changed, 1 insertion(+), 1 deletion(-)

diff --git a/arch/arm64/boot/dts/arm/juno-base.dtsi b/arch/arm64/boot/dts/arm/juno-base.dtsi
index e3ee960..ad0221a 100644
--- a/arch/arm64/boot/dts/arm/juno-base.dtsi
+++ b/arch/arm64/boot/dts/arm/juno-base.dtsi
@@ -12,7 +12,7 @@
 		status = "disabled";
 		frame at 2a830000 {
 			frame-number = <1>;
-			interrupts = <0 60 4>;
+			interrupts = <GIC_SPI 60 IRQ_TYPE_LEVEL_HIGH>;
 			reg = <0x0 0x2a830000 0x0 0x10000>;
 		};
 	};
-- 
2.1.4



From majun258 at huawei.com  Mon Aug 31 18:45:40 2015
From: majun258 at huawei.com (majun (F))
Date: Tue, 1 Sep 2015 09:45:40 +0800
Subject: [PATCH v4 1/2] Add the driver of mbigen interrupt controller
In-Reply-To: <CALW4P+JABDw=dOtpC1MgEjXt7hN4Pm1f4NPDna9XYoE+yc=Grg@mail.gmail.com>
References: <CALW4P+JABDw=dOtpC1MgEjXt7hN4Pm1f4NPDna9XYoE+yc=Grg@mail.gmail.com>
Message-ID: <55E50344.9090104@huawei.com>

Hi Alexey:

? 2015/8/29 11:13, Alexey Klimov ??:
> Hi Ma Jun,
> 
> On Wed, Aug 19, 2015 at 5:55 AM, MaJun <majun258 at huawei.com> wrote:
>> From: Ma Jun <majun258 at huawei.com>
>>
>> Mbigen means Message Based Interrupt Generator(MBIGEN).
>>
>> Its a kind of interrupt controller that collects
>>
>> the interrupts from external devices and generate msi interrupt.
>>


>> +
>> +#include <linux/init.h>
>> +#include <linux/io.h>
>> +#include <linux/slab.h>
>> +#include <linux/interrupt.h>
>> +#include <linux/irqchip/chained_irq.h>
>> +#include <linux/of_address.h>
>> +#include <linux/of_irq.h>
>> +#include <linux/of_platform.h>
>> +#include <linux/kernel.h>
>> +#include <linux/platform_device.h>
>> +#include <linux/module.h>
>> +#include <linux/msi.h>
> 
> What do you think about sorting this?
ok
> 
> 
>> +#include "irqchip.h"
>> +
[...]
>> +*/
>> +static u32 calc_irq_index(struct mbigen_device *dev, u32 nid, u32 offset)
>> +{
>> +       struct mbigen_node *mgn_node = NULL, *tmp;
>> +       unsigned long flags;
>> +       u32 index = 0;
>> +
>> +       raw_spin_lock_irqsave(&dev->lock, flags);
>> +       list_for_each_entry(tmp, &dev->mbigen_node_list, entry) {
>> +               if (tmp->node_num == nid)
>> +                       mgn_node = tmp;
>> +       }
>> +       raw_spin_unlock_irqrestore(&dev->lock, flags);
>> +
>> +       if (mgn_node == NULL) {
>> +               pr_err("No mbigen node found in device:%s\n",
>> +                        dev->node->full_name);
>> +               return -ENXIO;
>> +       }
>> +
>> +       if ((offset <= (mgn_node->pin_offset + mgn_node->irq_nr))
>> +           && (offset >= mgn_node->pin_offset))
>> +               index = mgn_node->index_offset + (offset - mgn_node->pin_offset);
>> +       else {
>> +               pr_err("Err: no invalid index\n");
> 
> Please check this message.
> 1. I don't know all details about this driver but is it really correct
> "no invalid index"? Maybe you mean "no vaild index" or just "invalid
> index"?
> Just checking if i correctly understand this.
> 
You are right.  This should be "no valid index"
> 2. Imagine what info user/dmesg reader gets when she or he will see
> such message? I suggest to add some info about driver that printed
> this message.
> You already have nice name in mbigen_irq_chip: "MBIGEN-v2". What do
> you think about using it as prefix in your printk-based messages?
> Please also consider revisiting other messages in this patch.
> 
good suggestion.
> 
>> +               index = -EINVAL;
>> +       }
>> +
>> +       return index;
>> +}
[...]
>> +       INIT_LIST_HEAD(dev_to_msi_list(&mgn_dev->dev));
>> +
>> +       ret = platform_msi_domain_alloc_irqs(&mgn_dev->dev,
>> +                                            nvec, mbigen_write_msg);
>> +       if (ret)
>> +               goto out_free_dev;
>> +
>> +       INIT_LIST_HEAD(&mgn_dev->entry);
>> +       raw_spin_lock_init(&mgn_dev->lock);
>> +       INIT_LIST_HEAD(&mgn_dev->mbigen_node_list);
>> +
>> +       /* Parse and get the info of mbigen nodes this
>> +        * device connected
>> +        */
>> +       parse_mbigen_node(mgn_dev);
>> +
>> +       mgn_irq_data = kcalloc(nvec, sizeof(*mgn_irq_data), GFP_KERNEL);
>> +       if (!mgn_irq_data)
>> +               return -ENOMEM;
> 
> Hm. Do you need error path here instead of simple return -ENOMEM?
> Maybe 'goto out_free_dev' will work for you.
Right. Memory leak happened.
> 
>> +       mgn_dev->mgn_data = mgn_irq_data;
>> +
>> +       for_each_msi_entry(desc, &mgn_dev->dev) {
>> +               mbigen_set_irq_handler_data(desc, mgn_dev,
>> +                                           &mgn_irq_data[desc->platform.msi_index]);
>> +               irq_set_chained_handler(desc->irq, mbigen_handle_cascade_irq);
>> +       }
>> +
>> +       raw_spin_lock(&chip->lock);
>> +       list_add(&mgn_dev->entry, &chip->mbigen_device_list);
>> +       raw_spin_unlock(&chip->lock);
>> +
>> +       return 0;
>> +
>> +out_free_dev:
>> +       kfree(mgn_dev);
>> +       pr_err("failed to get MSIs for device:%s (%d)\n", node->full_name,
>> +               ret);
>> +       return ret;
>> +}
>> +
>> +/*
>> + * Early initialization as an interrupt controller
>> + */
>> +static int __init mbigen_of_init(struct device_node *node)
>> +{
>> +       struct mbigen_chip *mgn_chip;
>> +       struct device_node *child;
>> +       struct irq_domain *domain;
>> +       void __iomem *base;
>> +       int err;
>> +
>> +       base = of_iomap(node, 0);
>> +       if (!base) {
>> +               pr_err("%s: unable to map registers\n", node->full_name);
>> +               return -ENOMEM;
>> +       }
>> +
>> +       mgn_chip = kzalloc(sizeof(*mgn_chip), GFP_KERNEL);
>> +       if (!mgn_chip) {
>> +               err = -ENOMEM;
>> +               goto unmap_reg;
>> +       }
>> +
>> +       mgn_chip->base = base;
>> +       mgn_chip->node = node;
>> +
>> +       domain = irq_domain_add_tree(node, &mbigen_domain_ops, mgn_chip);
>> +       mgn_chip->domain = domain;
>> +
>> +       raw_spin_lock_init(&mgn_chip->lock);
>> +       INIT_LIST_HEAD(&mgn_chip->entry);
>> +       INIT_LIST_HEAD(&mgn_chip->mbigen_device_list);
>> +
>> +       for_each_child_of_node(node, child) {
>> +               mbigen_device_init(mgn_chip, child);
> 
> You don't check error from mbigen_device_init()
I don't think we need to check errors here.
mbigen_device_init() handle all errors.

Thanks
Ma Jun

> 
>> +       }
>> +
>> +       spin_lock(&mbigen_chip_lock);
>> +       list_add(&mgn_chip->entry, &mbigen_chip_list);
>> +       spin_unlock(&mbigen_chip_lock);
>> +
>> +       return 0;
>> +
>> +unmap_reg:
>> +       iounmap(base);
>> +       pr_err("MBIGEN: failed probing:%s (%d)\n", node->full_name, err);
>> +       return err;
>> +}
>> +
>> +static struct of_device_id mbigen_chip_id[] = {
>> +       {       .compatible = "hisilicon,mbigen-v2",},
>> +       {},
>> +};
>> +
>> +static int __init mbigen_init(void)
>> +{
>> +       struct device_node *np;
>> +
>> +       for (np = of_find_matching_node(NULL, mbigen_chip_id); np;
>> +            np = of_find_matching_node(np, mbigen_chip_id)) {
>> +               mbigen_of_init(np);
>> +       }
>> +
>> +       return 0;
>> +}
>> +
>> +core_initcall(mbigen_init);
>> +
>> +MODULE_AUTHOR("Jun Ma <majun258 at huawei.com>");
>> +MODULE_AUTHOR("Yun Wu <wuyun.wu at huawei.com>");
>> +MODULE_LICENSE("GPL");
>> +MODULE_DESCRIPTION("Hisilicon MBI Generator driver");
>> --
>> 1.7.1
>>
>>
>> --
>> To unsubscribe from this list: send the line "unsubscribe linux-kernel" in
>> the body of a message to majordomo at vger.kernel.org
>> More majordomo info at  http://vger.kernel.org/majordomo-info.html
>> Please read the FAQ at  http://www.tux.org/lkml/
> 
> 
> 



From axel.lin at ingics.com  Mon Aug 31 18:52:21 2015
From: axel.lin at ingics.com (Axel Lin)
Date: Tue, 01 Sep 2015 09:52:21 +0800
Subject: [PATCH] ARM: pxa: balloon3: Fix build error
Message-ID: <1441072341.12012.0.camel@ingics.com>

irq_data_get_chip() function does not exist, call irq_desc_get_chip()
instead.

Fixes: 9ec97561aa6d ("ARM/pxa: Prepare balloon3_irq_handler for irq argument removal")
Signed-off-by: Axel Lin <axel.lin at ingics.com>
---
 arch/arm/mach-pxa/balloon3.c | 2 +-
 1 file changed, 1 insertion(+), 1 deletion(-)

diff --git a/arch/arm/mach-pxa/balloon3.c b/arch/arm/mach-pxa/balloon3.c
index 70366b3..c1cda98 100644
--- a/arch/arm/mach-pxa/balloon3.c
+++ b/arch/arm/mach-pxa/balloon3.c
@@ -502,7 +502,7 @@ static void balloon3_irq_handler(unsigned int __irq, struct irq_desc *desc)
 					balloon3_irq_enabled;
 	do {
 		struct irq_data *d = irq_desc_get_irq_data(desc);
-		struct irq_chip *chip = irq_data_get_chip(d);
+		struct irq_chip *chip = irq_desc_get_chip(desc);
 		unsigned int irq;
 
 		/* clear useless edge notification */
-- 
2.1.0





From yalin.wang2010 at gmail.com  Mon Aug 31 19:00:04 2015
From: yalin.wang2010 at gmail.com (yalin wang)
Date: Tue, 1 Sep 2015 10:00:04 +0800
Subject: [PATCH] arm64: add kc_offset_to_vaddr and kc_vaddr_to_offset macro
In-Reply-To: <1440915599-18485-1-git-send-email-yalin.wang2010@gmail.com>
References: <1440915599-18485-1-git-send-email-yalin.wang2010@gmail.com>
Message-ID: <385BEB9B-288F-4898-8728-CC4948DF0907@gmail.com>

Ping ?
> On Aug 30, 2015, at 14:19, yalin wang <yalin.wang2010 at gmail.com> wrote:
> 
> This patch add kc_offset_to_vaddr() and kc_vaddr_to_offset(),
> the default version doesn't work on arm64, because arm64 kernel address
> is below the PAGE_OFFSET, like module address and vmemmap address are
> all below PAGE_OFFSET address.
> 
> Signed-off-by: yalin wang <yalin.wang2010 at gmail.com>
> ---
> arch/arm64/include/asm/pgtable.h | 2 ++
> 1 file changed, 2 insertions(+)
> 
> diff --git a/arch/arm64/include/asm/pgtable.h b/arch/arm64/include/asm/pgtable.h
> index d374191..ef1ed5c 100644
> --- a/arch/arm64/include/asm/pgtable.h
> +++ b/arch/arm64/include/asm/pgtable.h
> @@ -660,6 +660,8 @@ static inline void update_mmu_cache(struct vm_area_struct *vma,
> 
> #define update_mmu_cache_pmd(vma, address, pmd) do { } while (0)
> 
> +#define	kc_vaddr_to_offset(v) ((v) & ((1UL << VA_BITS) - 1))
> +#define	kc_offset_to_vaddr(o) ((o) | ~((1UL << VA_BITS) - 1))
> #endif /* !__ASSEMBLY__ */
> 
> #endif /* __ASM_PGTABLE_H */
> -- 
> 1.9.1
> 



From axel.lin at ingics.com  Mon Aug 31 19:04:33 2015
From: axel.lin at ingics.com (Axel Lin)
Date: Tue, 01 Sep 2015 10:04:33 +0800
Subject: ARM: pxa: build error in arch/arm/plat-pxa/ssp.c
Message-ID: <1441073073.12012.3.camel@ingics.com>

  CC [M]  arch/arm/plat-pxa/ssp.o
arch/arm/plat-pxa/ssp.c:110:52: error: 'LPSS_SSP' undeclared here (not in a function)
scripts/Makefile.build:264: recipe for target 'arch/arm/plat-pxa/ssp.o' failed
make[1]: *** [arch/arm/plat-pxa/ssp.o] Error 1
Makefile:965: recipe for target 'arch/arm/plat-pxa' failed
make: *** [arch/arm/plat-pxa] Error 2


The build error is introduced by:
commit 03fbf488cece461468d3abb795f5e5f055e00040
Author: Jarkko Nikula <jarkko.nikula at linux.intel.com>
Date:   Thu Jun 4 16:55:10 2015 +0300

    spi: pxa2xx: Differentiate Intel LPSS types




From viresh.kumar at linaro.org  Mon Aug 31 20:57:13 2015
From: viresh.kumar at linaro.org (Viresh Kumar)
Date: Tue, 1 Sep 2015 09:27:13 +0530
Subject: about system time incorrect after changing cpu frequency
In-Reply-To: <CAOVJa8GTDj3UJpgUd4nH1wknUKa6fgac=1SsqC8g=UCG0MGuDw@mail.gmail.com>
References: <CAOVJa8GTDj3UJpgUd4nH1wknUKa6fgac=1SsqC8g=UCG0MGuDw@mail.gmail.com>
Message-ID: <CAOh2x=ky8_uwqvdH-krKxgMSby5jgovJp7odK6x=MpqNL+YoGg@mail.gmail.com>

On Mon, Aug 31, 2015 at 7:33 PM, vichy <vichy.kuo at gmail.com> wrote:
> hi all:
> My platform is like below:
> 1. single core Cortex A9
> 2. use global timer for system timer
>
> after I porting cpu frequency driver based on snow ball, the cpu
> frequency did change as I expected.
> But the system time is incorrect( since pherial clk is got from cpu frequency)
>
> for example:
> a) cpu 1G (pherial clk = 250M) --> sleep 1 sec (OK)
> b) cpu 500M  (pherial clk = 125M) --> sleep 1 sec (will be measured as 2 sec)
>
> I try to call below 2 functions to change the frequency of clocksource
> and clockevent, but the above b) sleep time is still incorrect when
> cpu runs in 500Mhz.
>     clockevents_update_freq(this_cpu_ptr(gt_evt), gt_clk_rate);
>     __clocksource_updatefreq_hz(&gt_clocksource, gt_clk_rate);
>
> in Arm cortex A9 single core system with Global timer as system timer,
> is there any kernel api to change system timer period when cpu/pherial
> frequency change?
>
> appreciate your kind help in advance,

The list cpufreq at vger.kernel.org is the wrong list for posting cpufreq queries
as we have moved to Linux PM list <linux-pm at vger.kernel.org> list now.

Try unsetting CPUFREQ_CONST_LOOPS flag in your driver, if you have it
set.


From bp at alien8.de  Mon Aug 31 21:32:20 2015
From: bp at alien8.de (Borislav Petkov)
Date: Tue, 1 Sep 2015 06:32:20 +0200
Subject: [PATCH v4 0/4] edac: Add L3/SoC support to the APM X-Gene SoC
 EDAC driver
In-Reply-To: <CAPw-ZTm_n6o2jXc5LuSZLrdZy3ZCmJmrRAP6S+7S-EO2ZAGANg@mail.gmail.com>
References: <1439534769-22811-1-git-send-email-lho@apm.com>
 <CAPw-ZTm_n6o2jXc5LuSZLrdZy3ZCmJmrRAP6S+7S-EO2ZAGANg@mail.gmail.com>
Message-ID: <20150901043220.GA32458@nazgul.tnic>

On Mon, Aug 31, 2015 at 02:26:11PM -0700, Loc Ho wrote:
> Are you okay with this version to pull in for 4.3 release?

It was already too late for 4.3 when you sent them. I'll take a look at
them after the merge window is over and also someone (Arnd?) needs to
check the DT changes.

-- 
Regards/Gruss,
    Boris.

ECO tip #101: Trim your mails when you reply.
--


From bjorn.andersson at sonymobile.com  Mon Aug 31 21:50:55 2015
From: bjorn.andersson at sonymobile.com (Bjorn Andersson)
Date: Mon, 31 Aug 2015 21:50:55 -0700
Subject: [PATCH] soc: qcom: Make qcom_smem_get() return a pointer
In-Reply-To: <1441071666-16156-1-git-send-email-sboyd@codeaurora.org>
References: <1441071666-16156-1-git-send-email-sboyd@codeaurora.org>
Message-ID: <20150901045055.GA13472@usrtlx11787.corpusers.net>

On Mon 31 Aug 18:41 PDT 2015, Stephen Boyd wrote:

> Passing a void ** almost always requires a cast at the call site.
> Instead of littering the code with casts every time this function
> is called, have qcom_smem_get() return a void pointer to the
> location of the smem item. This frees the caller from having to
> cast the pointer with the small downside of doing some extra work
> to find the item in the case that the caller doesn't care to use
> the pointer.
> 

We still need to find the item even if the caller is not interested, to
know if we should have returned -ENOENT, so I think it's just a matter
of style.

I did have the API to return the pointer earlier in development, but it
didn't look good and uniform. But in the final piece, that was picked
up, I think it makes more sense (and looks better) to do it this way.

Reviewed-by: Bjorn Andersson <bjorn.andersson at sonymobile.com>
> Signed-off-by: Stephen Boyd <sboyd at codeaurora.org>
> ---
> 
> This is on top of the smd and smem big endian support.
> 

How sneaky of you, then we need to approve those patches before we
add new consumers of this API...

Regards,
Bjorn


From bjorn.andersson at sonymobile.com  Mon Aug 31 21:55:02 2015
From: bjorn.andersson at sonymobile.com (Bjorn Andersson)
Date: Mon, 31 Aug 2015 21:55:02 -0700
Subject: [PATCH 1/3] soc: qcom: smd: Represent channel layout in structures
In-Reply-To: <1441071594-15941-2-git-send-email-sboyd@codeaurora.org>
References: <1441071594-15941-1-git-send-email-sboyd@codeaurora.org>
 <1441071594-15941-2-git-send-email-sboyd@codeaurora.org>
Message-ID: <20150901045502.GB13472@usrtlx11787.corpusers.net>

On Mon 31 Aug 18:39 PDT 2015, Stephen Boyd wrote:

> The rx and tx channel info are laid out in memory next to each
> other, and there are two types of channel info structures, byte
> based and word based. We have 4 pointers to these info
> structures, when we really only need two to point to the
> different types of structures. Encapsulate the byte based and word
> based tx/rx structures in a "full channel" structure that
> describes the layout of memory and reduces the number of pointers
> in the smd channel structure by two.
> 

Saving the extra pointer doesn't feel like worth the change, but
representing the pair of info structs as one sounds like a reasonable
cleanup.

Reviewed-by: Bjorn Andersson <bjorn.andersson at sonymobile.com>
> Signed-off-by: Stephen Boyd <sboyd at codeaurora.org>
> ---
>  drivers/soc/qcom/smd.c | 61 +++++++++++++++++++++++++++-----------------------
>  1 file changed, 33 insertions(+), 28 deletions(-)
> 
> diff --git a/drivers/soc/qcom/smd.c b/drivers/soc/qcom/smd.c
> index edd9d9a37238..c16547b85e05 100644
> --- a/drivers/soc/qcom/smd.c
> +++ b/drivers/soc/qcom/smd.c
> @@ -65,7 +65,9 @@
>   */
>  
>  struct smd_channel_info;
> +struct smd_full_channel_info;

I would have called this "smd_channel_info_pair"...

>  struct smd_channel_info_word;
> +struct smd_full_channel_info_word;
>  

Regards,
Bjorn


From bjorn.andersson at sonymobile.com  Mon Aug 31 21:59:45 2015
From: bjorn.andersson at sonymobile.com (Bjorn Andersson)
Date: Mon, 31 Aug 2015 21:59:45 -0700
Subject: [PATCH 2/3] soc: qcom: smd: Use __iowrite32_copy() instead of
 open-coding it
In-Reply-To: <1441071594-15941-3-git-send-email-sboyd@codeaurora.org>
References: <1441071594-15941-1-git-send-email-sboyd@codeaurora.org>
 <1441071594-15941-3-git-send-email-sboyd@codeaurora.org>
Message-ID: <20150901045945.GC13472@usrtlx11787.corpusers.net>

On Mon 31 Aug 18:39 PDT 2015, Stephen Boyd wrote:

> We already have a function to do this and it silences some sparse
> warnings along the way.
> 

Didn't know that, thanks. Do you know why there's no equivalent for
transfers in the other direction? Should we hack one up to do the same
simplification in smd_copy_from_fifo()?

Reviewed-by: Bjorn Andersson <bjorn.andersson at sonymobile.com>
> Signed-off-by: Stephen Boyd <sboyd at codeaurora.org>

Regards,
Bjorn


From bjorn.andersson at sonymobile.com  Mon Aug 31 22:06:44 2015
From: bjorn.andersson at sonymobile.com (Bjorn Andersson)
Date: Mon, 31 Aug 2015 22:06:44 -0700
Subject: [PATCH 3/3] soc: qcom: smd: Handle big endian CPUs
In-Reply-To: <1441071594-15941-4-git-send-email-sboyd@codeaurora.org>
References: <1441071594-15941-1-git-send-email-sboyd@codeaurora.org>
 <1441071594-15941-4-git-send-email-sboyd@codeaurora.org>
Message-ID: <20150901050644.GD13472@usrtlx11787.corpusers.net>

On Mon 31 Aug 18:39 PDT 2015, Stephen Boyd wrote:

> The smd structures are always in little endian, but the smd
> driver is not capable of being used on big endian CPUs. Annotate
> the little endian data members and update the code to do the
> proper byte swapping.
> 

I think this looks good, but I think it would be better to reference
the 8-bit entries of the info struct as "flags" rather than INFO8s.

Could you please change the name of the macros to
{G,S}ET_{R,T}X_CHANNEL_FLAG() to make the code slightly easier to
follow?

Regards,
Bjorn


From s.hauer at pengutronix.de  Mon Aug 31 22:26:04 2015
From: s.hauer at pengutronix.de (Sascha Hauer)
Date: Tue, 1 Sep 2015 07:26:04 +0200
Subject: [PATCH 1/3] dt-bindings: thermal: Add binding document for
 Mediatek thermal controller
In-Reply-To: <1441006446-4558-2-git-send-email-s.hauer@pengutronix.de>
References: <1441006446-4558-1-git-send-email-s.hauer@pengutronix.de>
 <1441006446-4558-2-git-send-email-s.hauer@pengutronix.de>
Message-ID: <20150901052604.GU5161@pengutronix.de>

On Mon, Aug 31, 2015 at 09:34:04AM +0200, Sascha Hauer wrote:
> Signed-off-by: Sascha Hauer <s.hauer at pengutronix.de>
> Reviewed-by: Daniel Kurtz <djkurtz at chromium.org>

Uh, still forgot the commit log. Will add something like:

This adds the device tree binding documentation for the mediatek thermal
controller found on Mediatek MT8173 and other SoCs.

Sascha

> ---
>  .../bindings/thermal/mediatek-thermal.txt          | 38 ++++++++++++++++++++++
>  include/dt-bindings/thermal/mt8173.h               | 13 ++++++++
>  2 files changed, 51 insertions(+)
>  create mode 100644 Documentation/devicetree/bindings/thermal/mediatek-thermal.txt
>  create mode 100644 include/dt-bindings/thermal/mt8173.h
> 
> diff --git a/Documentation/devicetree/bindings/thermal/mediatek-thermal.txt b/Documentation/devicetree/bindings/thermal/mediatek-thermal.txt
> new file mode 100644
> index 0000000..1697375
> --- /dev/null
> +++ b/Documentation/devicetree/bindings/thermal/mediatek-thermal.txt
> @@ -0,0 +1,38 @@
> +* Mediatek Thermal
> +
> +This describes the device tree binding for the Mediatek thermal controller
> +which measures the on-SoC temperatures. This device does not have its own ADC,
> +instead it directly controls the AUXADC via AHB bus accesses. For this reason
> +this device needs phandles to the AUXADC. Also it controls a mux in the
> +apmixedsys register space via AHB bus accesses, so a phandle to the APMIXEDSYS
> +is also needed.
> +
> +Required properties:
> +- compatible: "mediatek,mt8173-thermal"
> +- reg: Address range of the thermal controller
> +- interrupts: IRQ for the thermal controller
> +- clocks, clock-names: Clocks needed for the thermal controller. required
> +                       clocks are:
> +		       "therm":	 Main clock needed for register access
> +		       "auxadc": The AUXADC clock
> +- resets: Reference to the reset controller controlling the thermal controller.
> +- mediatek,auxadc: A phandle to the AUXADC which the thermal controller uses
> +- mediatek,apmixedsys: A phandle to the APMIXEDSYS controller.
> +- #thermal-sensor-cells : Should be 1. See ./thermal.txt for a description. See
> +			  include/dt-bindings/thermal/mt8173.h for valid sensor
> +			  numbers.
> +
> +Example:
> +
> +	thermal: thermal at 1100b000 {
> +		#thermal-sensor-cells = <1>;
> +		compatible = "mediatek,mt8173-thermal";
> +		reg = <0 0x1100b000 0 0x1000>;
> +		interrupts = <0 70 IRQ_TYPE_LEVEL_LOW>;
> +		clocks = <&pericfg CLK_PERI_THERM>, <&pericfg CLK_PERI_AUXADC>;
> +		clock-names = "therm", "auxadc";
> +		resets = <&pericfg MT8173_PERI_THERM_SW_RST>;
> +		reset-names = "therm";
> +		mediatek,auxadc = <&auxadc>;
> +		mediatek,apmixedsys = <&apmixedsys>;
> +	};
> diff --git a/include/dt-bindings/thermal/mt8173.h b/include/dt-bindings/thermal/mt8173.h
> new file mode 100644
> index 0000000..692e74c
> --- /dev/null
> +++ b/include/dt-bindings/thermal/mt8173.h
> @@ -0,0 +1,13 @@
> +/*
> + * This header provides constants for mediatek,mt8173-thermal
> + */
> +
> +#ifndef _DT_BINDINGS_THERMAL_MEDIATEK_MT8173_H
> +#define _DT_BINDINGS_THERMAL_MEDIATEK_MT8173_H
> +
> +#define MT8173_THERMAL_ZONE_CA53	0
> +#define MT8173_THERMAL_ZONE_CA57	1
> +#define MT8173_THERMAL_ZONE_GPU		2
> +#define MT8173_THERMAL_ZONE_CORE	3
> +
> +#endif /* _DT_BINDINGS_THERMAL_MEDIATEK_MT8173_H */
> -- 
> 2.5.0
> 
> 

-- 
Pengutronix e.K.                           |                             |
Industrial Linux Solutions                 | http://www.pengutronix.de/  |
Peiner Str. 6-8, 31137 Hildesheim, Germany | Phone: +49-5121-206917-0    |
Amtsgericht Hildesheim, HRA 2686           | Fax:   +49-5121-206917-5555 |


From vichy.kuo at gmail.com  Mon Aug 31 22:36:54 2015
From: vichy.kuo at gmail.com (vichy)
Date: Tue, 1 Sep 2015 13:36:54 +0800
Subject: about system time incorrect after changing cpu frequency
In-Reply-To: <CAOh2x=ky8_uwqvdH-krKxgMSby5jgovJp7odK6x=MpqNL+YoGg@mail.gmail.com>
References: <CAOVJa8GTDj3UJpgUd4nH1wknUKa6fgac=1SsqC8g=UCG0MGuDw@mail.gmail.com>
 <CAOh2x=ky8_uwqvdH-krKxgMSby5jgovJp7odK6x=MpqNL+YoGg@mail.gmail.com>
Message-ID: <CAOVJa8HNQ-s=yDfADCcoL+r22ALpHFtTjWZ=oxTkBUriYbCk+Q@mail.gmail.com>

hi Viresh:


2015-09-01 11:57 GMT+08:00 Viresh Kumar <viresh.kumar at linaro.org>:
> On Mon, Aug 31, 2015 at 7:33 PM, vichy <vichy.kuo at gmail.com> wrote:
>> hi all:
>> My platform is like below:
>> 1. single core Cortex A9
>> 2. use global timer for system timer
>>
>> after I porting cpu frequency driver based on snow ball, the cpu
>> frequency did change as I expected.
>> But the system time is incorrect( since pherial clk is got from cpu frequency)
>>
>> for example:
>> a) cpu 1G (pherial clk = 250M) --> sleep 1 sec (OK)
>> b) cpu 500M  (pherial clk = 125M) --> sleep 1 sec (will be measured as 2 sec)
>>
>> I try to call below 2 functions to change the frequency of clocksource
>> and clockevent, but the above b) sleep time is still incorrect when
>> cpu runs in 500Mhz.
>>     clockevents_update_freq(this_cpu_ptr(gt_evt), gt_clk_rate);
>>     __clocksource_updatefreq_hz(&gt_clocksource, gt_clk_rate);
>>
>> in Arm cortex A9 single core system with Global timer as system timer,
>> is there any kernel api to change system timer period when cpu/pherial
>> frequency change?
>>
>> appreciate your kind help in advance,
>
> The list cpufreq at vger.kernel.org is the wrong list for posting cpufreq queries
> as we have moved to Linux PM list <linux-pm at vger.kernel.org> list now.
>
> Try unsetting CPUFREQ_CONST_LOOPS flag in your driver, if you have it
> set.

I DIDN'T set the CPUFREQ_CONST_LOOPS when I register my cpufreq driver
I pasted my cpufreq driver declariation as below:

static struct cpufreq_driver plat_cpufreq_driver = {
    .flags  = CPUFREQ_STICKY,
    .verify = plat_cpufreq_verify_speed,
    .target = plat_cpufreq_target,
    .get    = plat_cpufreq_getspeed,
    .init   = plat_cpufreq_init,
    .name   = "plat-cpufreq",
    .attr   = plat_cpufreq_attr,
};


I have traced the kernel code
if I guess correctly, the sleep accurate is based on jiffies and
tick_handle_periodic will periodically update the next event interval

void tick_handle_periodic
-->
  for (;;) {
          if (!clockevents_program_event(dev, next, false))
              return;
          /*
           * Have to be careful here. If we're in oneshot mode,
           * before we call tick_periodic() in a loop, we need
           * to be sure we're using a real hardware clocksource.
           * Otherwise we could get trapped in an infinite
           * loop, as the tick_periodic() increments jiffies,
           * when then will increment time, posibly causing
           * the loop to trigger again and again.
           */
          if (timekeeping_valid_for_hres())
              tick_periodic(cpu);
          next = ktime_add(next, tick_period);
      }

and in clockevents_program_event, we will use mult, shift to calculate
the cycles need for global timer triggering next interrupt event.

    clc = ((unsigned long long) delta * dev->mult) >> dev->shift;
    rc = dev->set_next_event((unsigned long) clc, dev);

belwo is my tick device information in /proc/timer_list
and multi did change to 1/2 when I change cpu freq from 1G to 500Mhz.
when cpu run 1GHz

except multi and shift, is there any place I need to take care for
system timer accurate?
appreciate your kind help,

Tick Device: mode:     1
Per CPU device: 0
Clock Event Device: arm_global_timer
 max_delta_ns:   17043521021
 min_delta_ns:   1000
 mult:           541165879
 shift:          31
 mode:           3
 next_event:     2176344000000 nsecs
 set_next_event: gt_clockevent_set_next_event
 set_mode:       gt_clockevent_set_mode
 event_handler:  hrtimer_interrupt
 retries:        0

when cpu run in 500Mhz
Tick Device: mode:     1
Per CPU device: 0
Clock Event Device: arm_global_timer
 max_delta_ns:   34087041979
 min_delta_ns:   1000
 mult:           270582940
 shift:          31
 mode:           3
 next_event:     2230100000000 nsecs
 set_next_event: gt_clockevent_set_next_event
 set_mode:       gt_clockevent_set_mode
 event_handler:  hrtimer_interrupt
 retries:        0


From ykk at rock-chips.com  Mon Aug 31 22:46:11 2015
From: ykk at rock-chips.com (Yakir Yang)
Date: Tue,  1 Sep 2015 13:46:11 +0800
Subject: [PATCH v4 0/16] Add Analogix Core Display Port Driver
Message-ID: <1441086371-24838-1-git-send-email-ykk@rock-chips.com>

Hi all,

   The Samsung Exynos eDP controller and Rockchip RK3288 eDP controller
share the same IP, so a lot of parts can be re-used. I split the common
code into bridge directory, then rk3288 and exynos only need to keep
some platform code. Cause I can't find the exact IP name of exynos dp
controller, so I decide to name dp core driver with "analogix" which I
find in rk3288 eDP TRM ;)

Beyond that, there are three light registers setting differents bewteen
exynos and rk3288.
1. RK3288 have five special pll resigters which not indicata in exynos
   dp controller.
2. The address of DP_PHY_PD(dp phy power manager register) are different
   between rk3288 and exynos.
3. Rk3288 and exynos have different setting with AUX_HW_RETRY_CTL(dp debug
   register).

I have verified this series on two kinds of rockchip platform board, one
is rk3288 sdk board which connect with a 2K display port monitor, the other
is google jerry chromebook which connect with a eDP screen "cnm,n116bgeea2",
both of them works rightlly.

I haven't verified the dp function on samsung platform, cause I haven't got
exynos boards. I can only ensure that there are no build error on samsung
platform, wish some samsung guys help to test. ;)

Besides, The v4 version have been rebased on linux-next master branch
(git://git.kernel.org/pub/scm/linux/kernel/git/next/linux-next.git), tag name is
next-20150828 (latest is next-2015-0831). So I think if someone try to apply
this series, there would be no conflict  ;)

Thanks,
- Yakir

Changes in v4:
- Take Romain suggest, rebase on linux-next branch.
- Take Rob suggest, update "analogix,hpd-gpios" to "hpd-gpios" DT propery.
- Take Jingoo suggest, rename "analogix_dp-exynos.c" file name to "exynos_dp.c"
- Take Archit suggest, create a separate folder for analogix code in bridge/
- Take Jingoo Han suggest, update commit message more readable.
- Adjust the order from 05 to 04
- Take Krzysztof suggest, provide backword compatibility with samsung.
- Take Thierry suggest, add "color-depth" and "color-space" dynamic parsed.
- Take Krzysztof suggest, split all DTS changes, and provide backward compatibility.
  Mark old properties as deprecated but still support them.
- Take Rob suggest, update "analogix,hpd-gpio" to "hpd-gpios" prop name.
- Take Thierry suggest, deprecated some properties which could parsed from Edid/Mode/DPCD.
    "analogix,color-space" & "analogix,color-depth"   &
    "analogix,link-rate"   & "analogix,lane-count"    &
    "analogix,ycbcr-coeff" & "analogix,dynamic-range" &
    "vsync-active-high"    & "hsync-active-high"      & "interlaces"
- Take Krzysztof suggest, separate all DTS changes to a separate patch.
- Remove some deprecated DT properties in rockchip dp document.
- Take Kishon suggest, add commit message, and remove the redundant
  rockchip_dp_phy_init() function, move those code to probe() method.
  And remove driver .owner number.
- Take Thierry suggest, seprate the link-rate and lane-count limit
  out with the device_type flag.
- Take Jingoo suggest, add commit messages.
- Call drm_panel_prepare() in .get_modes function, ensure panel should
  power on before driver try to read edid message.

Changes in v3:
- Take Thierry Reding suggest, move exynos's video_timing code
  to analogix_dp-exynos platform driver, add get_modes method
  to struct analogix_dp_plat_data.
- Take Heiko suggest, rename some "samsung*" dts propery to "analogix*".
- Take Thierry Reding suggest, link_rate and lane_count shouldn't config to
  the DT property value directly, but we can take those as hardware limite.
  For example, RK3288 only support 4 physical lanes of 2.7/1.62 Gbps/lane,
  so DT property would like "link-rate = 0x0a" "lane-count = 4".
- Take Thierry Reding suggest, dynamic parse video timing info from
  struct drm_display_mode and struct drm_display_info.
- Take Heiko suggest, add devicetree binding documents.
- Take Thierry Reding suggest, remove sync pol & colorimetry properies
  from the new analogix dp driver devicetree binding.
- Update the exist exynos dtsi file with the latest DP DT properies.
- Take Thierry Reding and Heiko suggest, leave "sclk_edp_24m" to rockchip
  dp phy driver which name to "24m", and leave "sclk_edp" to analogix dp
  core driver which name to "dp", and leave "pclk_edp" to rockchip dp platform
  driver which name to "pclk".
- Take Heiko suggest, add devicetree binding document.
- Take Heiko suggest, remove "rockchip,panel" DT property, take use of remote
  point to get panel node.
- Add the new function point analogix_dp_platdata.get_modes init.
- Take Heiko suggest, add rockchip dp phy driver,
  collect the phy clocks and power control.
- Add "analogix,need-force-hpd" to indicate whether driver need foce
  hpd when hpd detect failed.
- move dp hpd detect to connector detect function.
- Add edid modes parse support

Changes in v2:
- Take Joe Preches advise, improved commit message more readable, and
  avoid using some uncommon style like bellow:
  -  retval = exynos_dp_read_bytes_from_i2c(...
				...)
  +  retval =
  +  exynos_dp_read_bytes_from_i2c(......);
- Take Jingoo Han suggest, just remove my name from author list.
- Take Jingoo Han suggest, remove new copyright
- Fix compiled failed dut to analogix_dp_device misspell
- Take Heiko suggest, get panel node with remote-endpoint method,
  and create devicetree binding for driver.
- Remove the clock enable/disbale with "sclk_edp" & "sclk_edp_24m",
  leave those clock to rockchip dp phy driver.
- Add GNU license v2 declared and samsung copyright
- Fix compile failed dut to phy_pd_addr variable misspell error

Mark Yao (1):
  drm: rockchip: add bpc and color mode setting

Yakir Yang (15):
  drm: exynos/dp: fix code style
  drm: exynos/dp: convert to drm bridge mode
  drm: bridge: analogix/dp: split exynos dp driver to bridge dir
  drm: bridge: analogix/dp: remove duplicate configuration of link rate
    and link count
  drm: bridge: analogix/dp: dynamic parse sync_pol & interlace &
    colorimetry
  Documentation: drm/bridge: add document for analogix_dp
  ARM: dts: exynos/dp: remove some properties that deprecated by
    analogix_dp driver
  drm: rockchip/dp: add rockchip platform dp driver
  phy: Add driver for rockchip Display Port PHY
  drm: bridge: analogix/dp: add platform device type support
  drm: bridge: analogix/dp: add some rk3288 special registers setting
  drm: bridge: analogix/dp: add max link rate and lane count limit for
    RK3288
  drm: bridge: analogix/dp: try force hpd after plug in lookup failed
  drm: bridge: analogix/dp: move hpd detect to connector detect function
  drm: bridge: analogix/dp: add edid modes parse in get_modes method

 .../devicetree/bindings/drm/bridge/analogix_dp.txt |   52 +
 .../devicetree/bindings/phy/rockchip-dp-phy.txt    |   26 +
 .../bindings/video/analogix_dp-rockchip.txt        |   75 +
 .../devicetree/bindings/video/exynos_dp.txt        |   64 +-
 arch/arm/boot/dts/exynos5250-arndale.dts           |    2 -
 arch/arm/boot/dts/exynos5250-smdk5250.dts          |    2 -
 arch/arm/boot/dts/exynos5250-snow.dts              |    4 +-
 arch/arm/boot/dts/exynos5250-spring.dts            |    4 +-
 arch/arm/boot/dts/exynos5420-peach-pit.dts         |    4 +-
 arch/arm/boot/dts/exynos5420-smdk5420.dts          |    2 -
 arch/arm/boot/dts/exynos5800-peach-pi.dts          |    4 +-
 drivers/gpu/drm/bridge/Kconfig                     |    2 +
 drivers/gpu/drm/bridge/Makefile                    |    1 +
 drivers/gpu/drm/bridge/analogix/Kconfig            |    4 +
 drivers/gpu/drm/bridge/analogix/Makefile           |    1 +
 drivers/gpu/drm/bridge/analogix/analogix_dp_core.c | 1409 +++++++++++++++++++
 drivers/gpu/drm/bridge/analogix/analogix_dp_core.h |  286 ++++
 drivers/gpu/drm/bridge/analogix/analogix_dp_reg.c  | 1294 ++++++++++++++++++
 .../analogix/analogix_dp_reg.h}                    |  270 ++--
 drivers/gpu/drm/exynos/Kconfig                     |    3 +-
 drivers/gpu/drm/exynos/Makefile                    |    2 +-
 drivers/gpu/drm/exynos/exynos_dp.c                 |  355 +++++
 drivers/gpu/drm/exynos/exynos_dp_core.c            | 1427 --------------------
 drivers/gpu/drm/exynos/exynos_dp_core.h            |  281 ----
 drivers/gpu/drm/exynos/exynos_dp_reg.c             | 1263 -----------------
 drivers/gpu/drm/rockchip/Kconfig                   |    9 +
 drivers/gpu/drm/rockchip/Makefile                  |    1 +
 drivers/gpu/drm/rockchip/analogix_dp-rockchip.c    |  416 ++++++
 drivers/gpu/drm/rockchip/dw_hdmi-rockchip.c        |    2 +-
 drivers/gpu/drm/rockchip/rockchip_drm_drv.h        |    2 +-
 drivers/gpu/drm/rockchip/rockchip_drm_vop.c        |   33 +-
 drivers/phy/Kconfig                                |    7 +
 drivers/phy/Makefile                               |    1 +
 drivers/phy/phy-rockchip-dp.c                      |  166 +++
 include/drm/bridge/analogix_dp.h                   |   40 +
 35 files changed, 4347 insertions(+), 3167 deletions(-)
 create mode 100644 Documentation/devicetree/bindings/drm/bridge/analogix_dp.txt
 create mode 100644 Documentation/devicetree/bindings/phy/rockchip-dp-phy.txt
 create mode 100644 Documentation/devicetree/bindings/video/analogix_dp-rockchip.txt
 create mode 100644 drivers/gpu/drm/bridge/analogix/Kconfig
 create mode 100644 drivers/gpu/drm/bridge/analogix/Makefile
 create mode 100644 drivers/gpu/drm/bridge/analogix/analogix_dp_core.c
 create mode 100644 drivers/gpu/drm/bridge/analogix/analogix_dp_core.h
 create mode 100644 drivers/gpu/drm/bridge/analogix/analogix_dp_reg.c
 rename drivers/gpu/drm/{exynos/exynos_dp_reg.h => bridge/analogix/analogix_dp_reg.h} (62%)
 create mode 100644 drivers/gpu/drm/exynos/exynos_dp.c
 delete mode 100644 drivers/gpu/drm/exynos/exynos_dp_core.c
 delete mode 100644 drivers/gpu/drm/exynos/exynos_dp_core.h
 delete mode 100644 drivers/gpu/drm/exynos/exynos_dp_reg.c
 create mode 100644 drivers/gpu/drm/rockchip/analogix_dp-rockchip.c
 create mode 100644 drivers/phy/phy-rockchip-dp.c
 create mode 100644 include/drm/bridge/analogix_dp.h

-- 
2.1.2




From ykk at rock-chips.com  Mon Aug 31 22:46:39 2015
From: ykk at rock-chips.com (Yakir Yang)
Date: Tue,  1 Sep 2015 13:46:39 +0800
Subject: [PATCH v4 01/16] drm: exynos/dp: fix code style
In-Reply-To: <1441086371-24838-1-git-send-email-ykk@rock-chips.com>
References: <1441086371-24838-1-git-send-email-ykk@rock-chips.com>
Message-ID: <1441086399-24889-1-git-send-email-ykk@rock-chips.com>

After run "checkpatch.pl -f --subjective" command, I see there
are lots of alignment problem in exynos_dp driver, so let just
fix them.

- Take Romain suggest, rebase on linux-next branch

Signed-off-by: Yakir Yang <ykk at rock-chips.com>
---
Changes in v4: None
Changes in v3: None
Changes in v2:
- Take Joe Preches advise, improved commit message more readable, and
  avoid using some uncommon style like bellow:
  -  retval = exynos_dp_read_bytes_from_i2c(...
				...)
  +  retval =
  +  exynos_dp_read_bytes_from_i2c(......);

 drivers/gpu/drm/exynos/exynos_dp_core.c | 226 ++++++++++++++++----------------
 drivers/gpu/drm/exynos/exynos_dp_core.h |  54 ++++----
 drivers/gpu/drm/exynos/exynos_dp_reg.c  | 106 +++++++--------
 3 files changed, 188 insertions(+), 198 deletions(-)

diff --git a/drivers/gpu/drm/exynos/exynos_dp_core.c b/drivers/gpu/drm/exynos/exynos_dp_core.c
index d66ade0..266f7f7 100644
--- a/drivers/gpu/drm/exynos/exynos_dp_core.c
+++ b/drivers/gpu/drm/exynos/exynos_dp_core.c
@@ -115,8 +115,8 @@ static int exynos_dp_read_edid(struct exynos_dp_device *dp)
 
 	/* Read Extension Flag, Number of 128-byte EDID extension blocks */
 	retval = exynos_dp_read_byte_from_i2c(dp, I2C_EDID_DEVICE_ADDR,
-				EDID_EXTENSION_FLAG,
-				&extend_block);
+					      EDID_EXTENSION_FLAG,
+					      &extend_block);
 	if (retval)
 		return retval;
 
@@ -124,10 +124,11 @@ static int exynos_dp_read_edid(struct exynos_dp_device *dp)
 		dev_dbg(dp->dev, "EDID data includes a single extension!\n");
 
 		/* Read EDID data */
-		retval = exynos_dp_read_bytes_from_i2c(dp, I2C_EDID_DEVICE_ADDR,
-						EDID_HEADER_PATTERN,
-						EDID_BLOCK_LENGTH,
-						&edid[EDID_HEADER_PATTERN]);
+		retval = exynos_dp_read_bytes_from_i2c(
+					dp, I2C_EDID_DEVICE_ADDR,
+					EDID_HEADER_PATTERN,
+					EDID_BLOCK_LENGTH,
+					&edid[EDID_HEADER_PATTERN]);
 		if (retval != 0) {
 			dev_err(dp->dev, "EDID Read failed!\n");
 			return -EIO;
@@ -139,11 +140,11 @@ static int exynos_dp_read_edid(struct exynos_dp_device *dp)
 		}
 
 		/* Read additional EDID data */
-		retval = exynos_dp_read_bytes_from_i2c(dp,
-				I2C_EDID_DEVICE_ADDR,
-				EDID_BLOCK_LENGTH,
-				EDID_BLOCK_LENGTH,
-				&edid[EDID_BLOCK_LENGTH]);
+		retval = exynos_dp_read_bytes_from_i2c(
+					dp, I2C_EDID_DEVICE_ADDR,
+					EDID_BLOCK_LENGTH,
+					EDID_BLOCK_LENGTH,
+					&edid[EDID_BLOCK_LENGTH]);
 		if (retval != 0) {
 			dev_err(dp->dev, "EDID Read failed!\n");
 			return -EIO;
@@ -155,24 +156,22 @@ static int exynos_dp_read_edid(struct exynos_dp_device *dp)
 		}
 
 		exynos_dp_read_byte_from_dpcd(dp, DP_TEST_REQUEST,
-					&test_vector);
+					      &test_vector);
 		if (test_vector & DP_TEST_LINK_EDID_READ) {
-			exynos_dp_write_byte_to_dpcd(dp,
-				DP_TEST_EDID_CHECKSUM,
+			exynos_dp_write_byte_to_dpcd(
+				dp, DP_TEST_EDID_CHECKSUM,
 				edid[EDID_BLOCK_LENGTH + EDID_CHECKSUM]);
-			exynos_dp_write_byte_to_dpcd(dp,
-				DP_TEST_RESPONSE,
+			exynos_dp_write_byte_to_dpcd(
+				dp, DP_TEST_RESPONSE,
 				DP_TEST_EDID_CHECKSUM_WRITE);
 		}
 	} else {
 		dev_info(dp->dev, "EDID data does not include any extensions.\n");
 
 		/* Read EDID data */
-		retval = exynos_dp_read_bytes_from_i2c(dp,
-				I2C_EDID_DEVICE_ADDR,
-				EDID_HEADER_PATTERN,
-				EDID_BLOCK_LENGTH,
-				&edid[EDID_HEADER_PATTERN]);
+		retval = exynos_dp_read_bytes_from_i2c(
+				dp, I2C_EDID_DEVICE_ADDR, EDID_HEADER_PATTERN,
+				EDID_BLOCK_LENGTH, &edid[EDID_HEADER_PATTERN]);
 		if (retval != 0) {
 			dev_err(dp->dev, "EDID Read failed!\n");
 			return -EIO;
@@ -183,16 +182,15 @@ static int exynos_dp_read_edid(struct exynos_dp_device *dp)
 			return -EIO;
 		}
 
-		exynos_dp_read_byte_from_dpcd(dp,
-			DP_TEST_REQUEST,
-			&test_vector);
+		exynos_dp_read_byte_from_dpcd(dp, DP_TEST_REQUEST,
+					      &test_vector);
 		if (test_vector & DP_TEST_LINK_EDID_READ) {
-			exynos_dp_write_byte_to_dpcd(dp,
-				DP_TEST_EDID_CHECKSUM,
-				edid[EDID_CHECKSUM]);
-			exynos_dp_write_byte_to_dpcd(dp,
-				DP_TEST_RESPONSE,
-				DP_TEST_EDID_CHECKSUM_WRITE);
+			exynos_dp_write_byte_to_dpcd(
+					dp, DP_TEST_EDID_CHECKSUM,
+					edid[EDID_CHECKSUM]);
+			exynos_dp_write_byte_to_dpcd(
+					dp, DP_TEST_RESPONSE,
+					DP_TEST_EDID_CHECKSUM_WRITE);
 		}
 	}
 
@@ -207,8 +205,7 @@ static int exynos_dp_handle_edid(struct exynos_dp_device *dp)
 	int retval;
 
 	/* Read DPCD DP_DPCD_REV~RECEIVE_PORT1_CAP_1 */
-	retval = exynos_dp_read_bytes_from_dpcd(dp, DP_DPCD_REV,
-				12, buf);
+	retval = exynos_dp_read_bytes_from_dpcd(dp, DP_DPCD_REV, 12, buf);
 	if (retval)
 		return retval;
 
@@ -223,7 +220,7 @@ static int exynos_dp_handle_edid(struct exynos_dp_device *dp)
 }
 
 static void exynos_dp_enable_rx_to_enhanced_mode(struct exynos_dp_device *dp,
-						bool enable)
+						 bool enable)
 {
 	u8 data;
 
@@ -231,11 +228,11 @@ static void exynos_dp_enable_rx_to_enhanced_mode(struct exynos_dp_device *dp,
 
 	if (enable)
 		exynos_dp_write_byte_to_dpcd(dp, DP_LANE_COUNT_SET,
-			DP_LANE_COUNT_ENHANCED_FRAME_EN |
-			DPCD_LANE_COUNT_SET(data));
+					     DP_LANE_COUNT_ENHANCED_FRAME_EN |
+					     DPCD_LANE_COUNT_SET(data));
 	else
 		exynos_dp_write_byte_to_dpcd(dp, DP_LANE_COUNT_SET,
-			DPCD_LANE_COUNT_SET(data));
+					     DPCD_LANE_COUNT_SET(data));
 }
 
 static int exynos_dp_is_enhanced_mode_available(struct exynos_dp_device *dp)
@@ -262,13 +259,12 @@ static void exynos_dp_training_pattern_dis(struct exynos_dp_device *dp)
 {
 	exynos_dp_set_training_pattern(dp, DP_NONE);
 
-	exynos_dp_write_byte_to_dpcd(dp,
-		DP_TRAINING_PATTERN_SET,
-		DP_TRAINING_PATTERN_DISABLE);
+	exynos_dp_write_byte_to_dpcd(dp, DP_TRAINING_PATTERN_SET,
+				     DP_TRAINING_PATTERN_DISABLE);
 }
 
 static void exynos_dp_set_lane_lane_pre_emphasis(struct exynos_dp_device *dp,
-					int pre_emphasis, int lane)
+						 int pre_emphasis, int lane)
 {
 	switch (lane) {
 	case 0:
@@ -308,15 +304,14 @@ static int exynos_dp_link_start(struct exynos_dp_device *dp)
 	/* Setup RX configuration */
 	buf[0] = dp->link_train.link_rate;
 	buf[1] = dp->link_train.lane_count;
-	retval = exynos_dp_write_bytes_to_dpcd(dp, DP_LINK_BW_SET,
-				2, buf);
+	retval = exynos_dp_write_bytes_to_dpcd(dp, DP_LINK_BW_SET, 2, buf);
 	if (retval)
 		return retval;
 
 	/* Set TX pre-emphasis to minimum */
 	for (lane = 0; lane < lane_count; lane++)
-		exynos_dp_set_lane_lane_pre_emphasis(dp,
-			PRE_EMPHASIS_LEVEL_0, lane);
+		exynos_dp_set_lane_lane_pre_emphasis(dp, PRE_EMPHASIS_LEVEL_0,
+						     lane);
 
 	/* Wait for PLL lock */
 	pll_tries = 0;
@@ -334,9 +329,9 @@ static int exynos_dp_link_start(struct exynos_dp_device *dp)
 	exynos_dp_set_training_pattern(dp, TRAINING_PTN1);
 
 	/* Set RX training pattern */
-	retval = exynos_dp_write_byte_to_dpcd(dp,
-			DP_TRAINING_PATTERN_SET,
-			DP_LINK_SCRAMBLING_DISABLE | DP_TRAINING_PATTERN_1);
+	retval = exynos_dp_write_byte_to_dpcd(dp, DP_TRAINING_PATTERN_SET,
+					      DP_LINK_SCRAMBLING_DISABLE |
+					      DP_TRAINING_PATTERN_1);
 	if (retval)
 		return retval;
 
@@ -345,7 +340,7 @@ static int exynos_dp_link_start(struct exynos_dp_device *dp)
 			    DP_TRAIN_VOLTAGE_SWING_LEVEL_0;
 
 	retval = exynos_dp_write_bytes_to_dpcd(dp, DP_TRAINING_LANE0_SET,
-			lane_count, buf);
+					       lane_count, buf);
 
 	return retval;
 }
@@ -353,7 +348,7 @@ static int exynos_dp_link_start(struct exynos_dp_device *dp)
 static unsigned char exynos_dp_get_lane_status(u8 link_status[2], int lane)
 {
 	int shift = (lane & 1) * 4;
-	u8 link_value = link_status[lane>>1];
+	u8 link_value = link_status[lane >> 1];
 
 	return (link_value >> shift) & 0xf;
 }
@@ -372,7 +367,7 @@ static int exynos_dp_clock_recovery_ok(u8 link_status[2], int lane_count)
 }
 
 static int exynos_dp_channel_eq_ok(u8 link_status[2], u8 link_align,
-				int lane_count)
+				   int lane_count)
 {
 	int lane;
 	u8 lane_status;
@@ -391,10 +386,10 @@ static int exynos_dp_channel_eq_ok(u8 link_status[2], u8 link_align,
 }
 
 static unsigned char exynos_dp_get_adjust_request_voltage(u8 adjust_request[2],
-							int lane)
+							  int lane)
 {
 	int shift = (lane & 1) * 4;
-	u8 link_value = adjust_request[lane>>1];
+	u8 link_value = adjust_request[lane >> 1];
 
 	return (link_value >> shift) & 0x3;
 }
@@ -404,13 +399,13 @@ static unsigned char exynos_dp_get_adjust_request_pre_emphasis(
 					int lane)
 {
 	int shift = (lane & 1) * 4;
-	u8 link_value = adjust_request[lane>>1];
+	u8 link_value = adjust_request[lane >> 1];
 
 	return ((link_value >> shift) & 0xc) >> 2;
 }
 
 static void exynos_dp_set_lane_link_training(struct exynos_dp_device *dp,
-					u8 training_lane_set, int lane)
+					     u8 training_lane_set, int lane)
 {
 	switch (lane) {
 	case 0:
@@ -430,9 +425,8 @@ static void exynos_dp_set_lane_link_training(struct exynos_dp_device *dp,
 	}
 }
 
-static unsigned int exynos_dp_get_lane_link_training(
-				struct exynos_dp_device *dp,
-				int lane)
+static unsigned int
+exynos_dp_get_lane_link_training(struct exynos_dp_device *dp, int lane)
 {
 	u32 reg;
 
@@ -466,7 +460,7 @@ static void exynos_dp_reduce_link_rate(struct exynos_dp_device *dp)
 }
 
 static void exynos_dp_get_adjust_training_lane(struct exynos_dp_device *dp,
-					u8 adjust_request[2])
+					       u8 adjust_request[2])
 {
 	int lane, lane_count;
 	u8 voltage_swing, pre_emphasis, training_lane;
@@ -499,13 +493,13 @@ static int exynos_dp_process_clock_recovery(struct exynos_dp_device *dp)
 
 	lane_count = dp->link_train.lane_count;
 
-	retval =  exynos_dp_read_bytes_from_dpcd(dp,
-			DP_LANE0_1_STATUS, 2, link_status);
+	retval =  exynos_dp_read_bytes_from_dpcd(dp, DP_LANE0_1_STATUS,
+						 2, link_status);
 	if (retval)
 		return retval;
 
-	retval =  exynos_dp_read_bytes_from_dpcd(dp,
-			DP_ADJUST_REQUEST_LANE0_1, 2, adjust_request);
+	retval =  exynos_dp_read_bytes_from_dpcd(dp, DP_ADJUST_REQUEST_LANE0_1,
+						 2, adjust_request);
 	if (retval)
 		return retval;
 
@@ -513,8 +507,8 @@ static int exynos_dp_process_clock_recovery(struct exynos_dp_device *dp)
 		/* set training pattern 2 for EQ */
 		exynos_dp_set_training_pattern(dp, TRAINING_PTN2);
 
-		retval = exynos_dp_write_byte_to_dpcd(dp,
-				DP_TRAINING_PATTERN_SET,
+		retval = exynos_dp_write_byte_to_dpcd(
+				dp, DP_TRAINING_PATTERN_SET,
 				DP_LINK_SCRAMBLING_DISABLE |
 				DP_TRAINING_PATTERN_2);
 		if (retval)
@@ -552,11 +546,11 @@ static int exynos_dp_process_clock_recovery(struct exynos_dp_device *dp)
 	exynos_dp_get_adjust_training_lane(dp, adjust_request);
 
 	for (lane = 0; lane < lane_count; lane++)
-		exynos_dp_set_lane_link_training(dp,
-			dp->link_train.training_lane[lane], lane);
+		exynos_dp_set_lane_link_training(
+				dp, dp->link_train.training_lane[lane], lane);
 
-	retval = exynos_dp_write_bytes_to_dpcd(dp,
-			DP_TRAINING_LANE0_SET, lane_count,
+	retval = exynos_dp_write_bytes_to_dpcd(
+			dp, DP_TRAINING_LANE0_SET, lane_count,
 			dp->link_train.training_lane);
 	if (retval)
 		return retval;
@@ -574,8 +568,8 @@ static int exynos_dp_process_equalizer_training(struct exynos_dp_device *dp)
 
 	lane_count = dp->link_train.lane_count;
 
-	retval = exynos_dp_read_bytes_from_dpcd(dp,
-			DP_LANE0_1_STATUS, 2, link_status);
+	retval = exynos_dp_read_bytes_from_dpcd(dp, DP_LANE0_1_STATUS,
+						2, link_status);
 	if (retval)
 		return retval;
 
@@ -584,13 +578,13 @@ static int exynos_dp_process_equalizer_training(struct exynos_dp_device *dp)
 		return -EIO;
 	}
 
-	retval = exynos_dp_read_bytes_from_dpcd(dp,
-			DP_ADJUST_REQUEST_LANE0_1, 2, adjust_request);
+	retval = exynos_dp_read_bytes_from_dpcd(dp, DP_ADJUST_REQUEST_LANE0_1,
+						2, adjust_request);
 	if (retval)
 		return retval;
 
-	retval = exynos_dp_read_byte_from_dpcd(dp,
-			DP_LANE_ALIGN_STATUS_UPDATED, &link_align);
+	retval = exynos_dp_read_byte_from_dpcd(dp, DP_LANE_ALIGN_STATUS_UPDATED,
+					       &link_align);
 	if (retval)
 		return retval;
 
@@ -629,17 +623,18 @@ static int exynos_dp_process_equalizer_training(struct exynos_dp_device *dp)
 	}
 
 	for (lane = 0; lane < lane_count; lane++)
-		exynos_dp_set_lane_link_training(dp,
-			dp->link_train.training_lane[lane], lane);
+		exynos_dp_set_lane_link_training(
+				dp, dp->link_train.training_lane[lane], lane);
 
 	retval = exynos_dp_write_bytes_to_dpcd(dp, DP_TRAINING_LANE0_SET,
-			lane_count, dp->link_train.training_lane);
+					       lane_count,
+					       dp->link_train.training_lane);
 
 	return retval;
 }
 
 static void exynos_dp_get_max_rx_bandwidth(struct exynos_dp_device *dp,
-					u8 *bandwidth)
+					   u8 *bandwidth)
 {
 	u8 data;
 
@@ -652,7 +647,7 @@ static void exynos_dp_get_max_rx_bandwidth(struct exynos_dp_device *dp,
 }
 
 static void exynos_dp_get_max_rx_lane_count(struct exynos_dp_device *dp,
-					u8 *lane_count)
+					    u8 *lane_count)
 {
 	u8 data;
 
@@ -665,8 +660,8 @@ static void exynos_dp_get_max_rx_lane_count(struct exynos_dp_device *dp,
 }
 
 static void exynos_dp_init_training(struct exynos_dp_device *dp,
-			enum link_lane_count_type max_lane,
-			enum link_rate_type max_rate)
+				    enum link_lane_count_type max_lane,
+				    enum link_rate_type max_rate)
 {
 	/*
 	 * MACRO_RST must be applied after the PLL_LOCK to avoid
@@ -679,7 +674,7 @@ static void exynos_dp_init_training(struct exynos_dp_device *dp,
 	exynos_dp_get_max_rx_lane_count(dp, &dp->link_train.lane_count);
 
 	if ((dp->link_train.link_rate != LINK_RATE_1_62GBPS) &&
-	   (dp->link_train.link_rate != LINK_RATE_2_70GBPS)) {
+	    (dp->link_train.link_rate != LINK_RATE_2_70GBPS)) {
 		dev_err(dp->dev, "Rx Max Link Rate is abnormal :%x !\n",
 			dp->link_train.link_rate);
 		dp->link_train.link_rate = LINK_RATE_1_62GBPS;
@@ -739,8 +734,7 @@ static int exynos_dp_sw_link_training(struct exynos_dp_device *dp)
 }
 
 static int exynos_dp_set_link_train(struct exynos_dp_device *dp,
-				u32 count,
-				u32 bwtype)
+				    u32 count, u32 bwtype)
 {
 	int i;
 	int retval;
@@ -828,21 +822,19 @@ static void exynos_dp_enable_scramble(struct exynos_dp_device *dp, bool enable)
 	if (enable) {
 		exynos_dp_enable_scrambling(dp);
 
-		exynos_dp_read_byte_from_dpcd(dp,
-			DP_TRAINING_PATTERN_SET,
-			&data);
-		exynos_dp_write_byte_to_dpcd(dp,
-			DP_TRAINING_PATTERN_SET,
-			(u8)(data & ~DP_LINK_SCRAMBLING_DISABLE));
+		exynos_dp_read_byte_from_dpcd(dp, DP_TRAINING_PATTERN_SET,
+					      &data);
+		exynos_dp_write_byte_to_dpcd(
+				dp, DP_TRAINING_PATTERN_SET,
+				(u8)(data & ~DP_LINK_SCRAMBLING_DISABLE));
 	} else {
 		exynos_dp_disable_scrambling(dp);
 
-		exynos_dp_read_byte_from_dpcd(dp,
-			DP_TRAINING_PATTERN_SET,
-			&data);
-		exynos_dp_write_byte_to_dpcd(dp,
-			DP_TRAINING_PATTERN_SET,
-			(u8)(data | DP_LINK_SCRAMBLING_DISABLE));
+		exynos_dp_read_byte_from_dpcd(dp, DP_TRAINING_PATTERN_SET,
+					      &data);
+		exynos_dp_write_byte_to_dpcd(
+				dp, DP_TRAINING_PATTERN_SET,
+				(u8)(data | DP_LINK_SCRAMBLING_DISABLE));
 	}
 }
 
@@ -913,7 +905,7 @@ static void exynos_dp_commit(struct drm_encoder *encoder)
 	}
 
 	ret = exynos_dp_set_link_train(dp, dp->video_info->lane_count,
-					dp->video_info->link_rate);
+				       dp->video_info->link_rate);
 	if (ret) {
 		dev_err(dp->dev, "unable to do link train\n");
 		return;
@@ -941,8 +933,8 @@ static void exynos_dp_commit(struct drm_encoder *encoder)
 	exynos_dp_start_video(dp);
 }
 
-static enum drm_connector_status exynos_dp_detect(
-				struct drm_connector *connector, bool force)
+static enum drm_connector_status
+exynos_dp_detect(struct drm_connector *connector, bool force)
 {
 	return connector_status_connected;
 }
@@ -990,8 +982,8 @@ static int exynos_dp_get_modes(struct drm_connector *connector)
 	return 1;
 }
 
-static struct drm_encoder *exynos_dp_best_encoder(
-			struct drm_connector *connector)
+static struct drm_encoder *
+exynos_dp_best_encoder(struct drm_connector *connector)
 {
 	struct exynos_dp_device *dp = ctx_from_connector(connector);
 
@@ -1005,7 +997,7 @@ static struct drm_connector_helper_funcs exynos_dp_connector_helper_funcs = {
 
 /* returns the number of bridges attached */
 static int exynos_drm_attach_lcd_bridge(struct exynos_dp_device *dp,
-		struct drm_encoder *encoder)
+					struct drm_encoder *encoder)
 {
 	int ret;
 
@@ -1036,7 +1028,8 @@ static int exynos_dp_create_connector(struct drm_encoder *encoder)
 	connector->polled = DRM_CONNECTOR_POLL_HPD;
 
 	ret = drm_connector_init(dp->drm_dev, connector,
-			&exynos_dp_connector_funcs, DRM_MODE_CONNECTOR_eDP);
+				 &exynos_dp_connector_funcs,
+				 DRM_MODE_CONNECTOR_eDP);
 	if (ret) {
 		DRM_ERROR("Failed to initialize connector with drm\n");
 		return ret;
@@ -1139,8 +1132,8 @@ static struct video_info *exynos_dp_dt_parse_pdata(struct device *dev)
 	struct device_node *dp_node = dev->of_node;
 	struct video_info *dp_video_config;
 
-	dp_video_config = devm_kzalloc(dev,
-				sizeof(*dp_video_config), GFP_KERNEL);
+	dp_video_config = devm_kzalloc(dev, sizeof(*dp_video_config),
+				       GFP_KERNEL);
 	if (!dp_video_config)
 		return ERR_PTR(-ENOMEM);
 
@@ -1154,37 +1147,37 @@ static struct video_info *exynos_dp_dt_parse_pdata(struct device *dev)
 		of_property_read_bool(dp_node, "interlaced");
 
 	if (of_property_read_u32(dp_node, "samsung,color-space",
-				&dp_video_config->color_space)) {
+				 &dp_video_config->color_space)) {
 		dev_err(dev, "failed to get color-space\n");
 		return ERR_PTR(-EINVAL);
 	}
 
 	if (of_property_read_u32(dp_node, "samsung,dynamic-range",
-				&dp_video_config->dynamic_range)) {
+				 &dp_video_config->dynamic_range)) {
 		dev_err(dev, "failed to get dynamic-range\n");
 		return ERR_PTR(-EINVAL);
 	}
 
 	if (of_property_read_u32(dp_node, "samsung,ycbcr-coeff",
-				&dp_video_config->ycbcr_coeff)) {
+				 &dp_video_config->ycbcr_coeff)) {
 		dev_err(dev, "failed to get ycbcr-coeff\n");
 		return ERR_PTR(-EINVAL);
 	}
 
 	if (of_property_read_u32(dp_node, "samsung,color-depth",
-				&dp_video_config->color_depth)) {
+				 &dp_video_config->color_depth)) {
 		dev_err(dev, "failed to get color-depth\n");
 		return ERR_PTR(-EINVAL);
 	}
 
 	if (of_property_read_u32(dp_node, "samsung,link-rate",
-				&dp_video_config->link_rate)) {
+				 &dp_video_config->link_rate)) {
 		dev_err(dev, "failed to get link-rate\n");
 		return ERR_PTR(-EINVAL);
 	}
 
 	if (of_property_read_u32(dp_node, "samsung,lane-count",
-				&dp_video_config->lane_count)) {
+				 &dp_video_config->lane_count)) {
 		dev_err(dev, "failed to get lane-count\n");
 		return ERR_PTR(-EINVAL);
 	}
@@ -1197,7 +1190,7 @@ static int exynos_dp_dt_parse_panel(struct exynos_dp_device *dp)
 	int ret;
 
 	ret = of_get_videomode(dp->dev->of_node, &dp->priv.vm,
-			OF_USE_NATIVE_MODE);
+			       OF_USE_NATIVE_MODE);
 	if (ret) {
 		DRM_ERROR("failed: of_get_videomode() : %d\n", ret);
 		return ret;
@@ -1294,7 +1287,7 @@ static int exynos_dp_bind(struct device *dev, struct device *master, void *data)
 	exynos_dp_init_dp(dp);
 
 	ret = devm_request_irq(&pdev->dev, dp->irq, exynos_dp_irq_handler,
-			irq_flags, "exynos-dp", dp);
+			       irq_flags, "exynos-dp", dp);
 	if (ret) {
 		dev_err(&pdev->dev, "failed to request irq\n");
 		return ret;
@@ -1328,7 +1321,7 @@ static int exynos_dp_bind(struct device *dev, struct device *master, void *data)
 }
 
 static void exynos_dp_unbind(struct device *dev, struct device *master,
-				void *data)
+			     void *data)
 {
 	struct exynos_dp_device *dp = dev_get_drvdata(dev);
 
@@ -1347,7 +1340,7 @@ static int exynos_dp_probe(struct platform_device *pdev)
 	struct exynos_dp_device *dp;
 
 	dp = devm_kzalloc(&pdev->dev, sizeof(struct exynos_dp_device),
-				GFP_KERNEL);
+			  GFP_KERNEL);
 	if (!dp)
 		return -ENOMEM;
 
@@ -1369,8 +1362,9 @@ static int exynos_dp_probe(struct platform_device *pdev)
 			of_node_put(bridge_node);
 			if (!dp->bridge)
 				return -EPROBE_DEFER;
-		} else
+		} else {
 			return -EPROBE_DEFER;
+		}
 	}
 
 	return component_add(&pdev->dev, &exynos_dp_ops);
diff --git a/drivers/gpu/drm/exynos/exynos_dp_core.h b/drivers/gpu/drm/exynos/exynos_dp_core.h
index e413b6f..71f2b86 100644
--- a/drivers/gpu/drm/exynos/exynos_dp_core.h
+++ b/drivers/gpu/drm/exynos/exynos_dp_core.h
@@ -179,8 +179,8 @@ void exynos_dp_config_interrupt(struct exynos_dp_device *dp);
 enum pll_status exynos_dp_get_pll_lock_status(struct exynos_dp_device *dp);
 void exynos_dp_set_pll_power_down(struct exynos_dp_device *dp, bool enable);
 void exynos_dp_set_analog_power_down(struct exynos_dp_device *dp,
-				enum analog_power_block block,
-				bool enable);
+				     enum analog_power_block block,
+				     bool enable);
 void exynos_dp_init_analog_func(struct exynos_dp_device *dp);
 void exynos_dp_init_hpd(struct exynos_dp_device *dp);
 enum dp_irq_type exynos_dp_get_irq_type(struct exynos_dp_device *dp);
@@ -191,50 +191,50 @@ int exynos_dp_get_plug_in_status(struct exynos_dp_device *dp);
 void exynos_dp_enable_sw_function(struct exynos_dp_device *dp);
 int exynos_dp_start_aux_transaction(struct exynos_dp_device *dp);
 int exynos_dp_write_byte_to_dpcd(struct exynos_dp_device *dp,
-				unsigned int reg_addr,
-				unsigned char data);
+				 unsigned int reg_addr,
+				 unsigned char data);
 int exynos_dp_read_byte_from_dpcd(struct exynos_dp_device *dp,
-				unsigned int reg_addr,
-				unsigned char *data);
+				  unsigned int reg_addr,
+				  unsigned char *data);
 int exynos_dp_write_bytes_to_dpcd(struct exynos_dp_device *dp,
-				unsigned int reg_addr,
-				unsigned int count,
-				unsigned char data[]);
+				  unsigned int reg_addr,
+				  unsigned int count,
+				  unsigned char data[]);
 int exynos_dp_read_bytes_from_dpcd(struct exynos_dp_device *dp,
-				unsigned int reg_addr,
-				unsigned int count,
-				unsigned char data[]);
+				   unsigned int reg_addr,
+				   unsigned int count,
+				   unsigned char data[]);
 int exynos_dp_select_i2c_device(struct exynos_dp_device *dp,
 				unsigned int device_addr,
 				unsigned int reg_addr);
 int exynos_dp_read_byte_from_i2c(struct exynos_dp_device *dp,
-				unsigned int device_addr,
-				unsigned int reg_addr,
-				unsigned int *data);
+				 unsigned int device_addr,
+				 unsigned int reg_addr,
+				 unsigned int *data);
 int exynos_dp_read_bytes_from_i2c(struct exynos_dp_device *dp,
-				unsigned int device_addr,
-				unsigned int reg_addr,
-				unsigned int count,
-				unsigned char edid[]);
+				  unsigned int device_addr,
+				  unsigned int reg_addr,
+				  unsigned int count,
+				  unsigned char edid[]);
 void exynos_dp_set_link_bandwidth(struct exynos_dp_device *dp, u32 bwtype);
 void exynos_dp_get_link_bandwidth(struct exynos_dp_device *dp, u32 *bwtype);
 void exynos_dp_set_lane_count(struct exynos_dp_device *dp, u32 count);
 void exynos_dp_get_lane_count(struct exynos_dp_device *dp, u32 *count);
 void exynos_dp_enable_enhanced_mode(struct exynos_dp_device *dp, bool enable);
 void exynos_dp_set_training_pattern(struct exynos_dp_device *dp,
-				 enum pattern_set pattern);
+				    enum pattern_set pattern);
 void exynos_dp_set_lane0_pre_emphasis(struct exynos_dp_device *dp, u32 level);
 void exynos_dp_set_lane1_pre_emphasis(struct exynos_dp_device *dp, u32 level);
 void exynos_dp_set_lane2_pre_emphasis(struct exynos_dp_device *dp, u32 level);
 void exynos_dp_set_lane3_pre_emphasis(struct exynos_dp_device *dp, u32 level);
 void exynos_dp_set_lane0_link_training(struct exynos_dp_device *dp,
-				u32 training_lane);
+				       u32 training_lane);
 void exynos_dp_set_lane1_link_training(struct exynos_dp_device *dp,
-				u32 training_lane);
+				       u32 training_lane);
 void exynos_dp_set_lane2_link_training(struct exynos_dp_device *dp,
-				u32 training_lane);
+				       u32 training_lane);
 void exynos_dp_set_lane3_link_training(struct exynos_dp_device *dp,
-				u32 training_lane);
+				       u32 training_lane);
 u32 exynos_dp_get_lane0_link_training(struct exynos_dp_device *dp);
 u32 exynos_dp_get_lane1_link_training(struct exynos_dp_device *dp);
 u32 exynos_dp_get_lane2_link_training(struct exynos_dp_device *dp);
@@ -245,9 +245,9 @@ void exynos_dp_init_video(struct exynos_dp_device *dp);
 void exynos_dp_set_video_color_format(struct exynos_dp_device *dp);
 int exynos_dp_is_slave_video_stream_clock_on(struct exynos_dp_device *dp);
 void exynos_dp_set_video_cr_mn(struct exynos_dp_device *dp,
-			enum clock_recovery_m_value_type type,
-			u32 m_value,
-			u32 n_value);
+			       enum clock_recovery_m_value_type type,
+			       u32 m_value,
+			       u32 n_value);
 void exynos_dp_set_video_timing_mode(struct exynos_dp_device *dp, u32 type);
 void exynos_dp_enable_video_master(struct exynos_dp_device *dp, bool enable);
 void exynos_dp_start_video(struct exynos_dp_device *dp);
diff --git a/drivers/gpu/drm/exynos/exynos_dp_reg.c b/drivers/gpu/drm/exynos/exynos_dp_reg.c
index c1f87a2..5aff19a 100644
--- a/drivers/gpu/drm/exynos/exynos_dp_reg.c
+++ b/drivers/gpu/drm/exynos/exynos_dp_reg.c
@@ -202,8 +202,8 @@ void exynos_dp_set_pll_power_down(struct exynos_dp_device *dp, bool enable)
 }
 
 void exynos_dp_set_analog_power_down(struct exynos_dp_device *dp,
-				enum analog_power_block block,
-				bool enable)
+				     enum analog_power_block block,
+				     bool enable)
 {
 	u32 reg;
 
@@ -399,8 +399,8 @@ void exynos_dp_init_aux(struct exynos_dp_device *dp)
 	exynos_dp_reset_aux(dp);
 
 	/* Disable AUX transaction H/W retry */
-	reg = AUX_BIT_PERIOD_EXPECTED_DELAY(3) | AUX_HW_RETRY_COUNT_SEL(0)|
-		AUX_HW_RETRY_INTERVAL_600_MICROSECONDS;
+	reg = AUX_BIT_PERIOD_EXPECTED_DELAY(3) | AUX_HW_RETRY_COUNT_SEL(0) |
+	      AUX_HW_RETRY_INTERVAL_600_MICROSECONDS;
 	writel(reg, dp->reg_base + EXYNOS_DP_AUX_HW_RETRY_CTL);
 
 	/* Receive AUX Channel DEFER commands equal to DEFFER_COUNT*64 */
@@ -483,8 +483,8 @@ int exynos_dp_start_aux_transaction(struct exynos_dp_device *dp)
 }
 
 int exynos_dp_write_byte_to_dpcd(struct exynos_dp_device *dp,
-				unsigned int reg_addr,
-				unsigned char data)
+				 unsigned int reg_addr,
+				 unsigned char data)
 {
 	u32 reg;
 	int i;
@@ -519,17 +519,16 @@ int exynos_dp_write_byte_to_dpcd(struct exynos_dp_device *dp,
 		retval = exynos_dp_start_aux_transaction(dp);
 		if (retval == 0)
 			break;
-		else
-			dev_dbg(dp->dev, "%s: Aux Transaction fail!\n",
-				__func__);
+
+		dev_dbg(dp->dev, "%s: Aux Transaction fail!\n", __func__);
 	}
 
 	return retval;
 }
 
 int exynos_dp_read_byte_from_dpcd(struct exynos_dp_device *dp,
-				unsigned int reg_addr,
-				unsigned char *data)
+				  unsigned int reg_addr,
+				  unsigned char *data)
 {
 	u32 reg;
 	int i;
@@ -560,9 +559,8 @@ int exynos_dp_read_byte_from_dpcd(struct exynos_dp_device *dp,
 		retval = exynos_dp_start_aux_transaction(dp);
 		if (retval == 0)
 			break;
-		else
-			dev_dbg(dp->dev, "%s: Aux Transaction fail!\n",
-				__func__);
+
+		dev_dbg(dp->dev, "%s: Aux Transaction fail!\n", __func__);
 	}
 
 	/* Read data buffer */
@@ -573,9 +571,9 @@ int exynos_dp_read_byte_from_dpcd(struct exynos_dp_device *dp,
 }
 
 int exynos_dp_write_bytes_to_dpcd(struct exynos_dp_device *dp,
-				unsigned int reg_addr,
-				unsigned int count,
-				unsigned char data[])
+				  unsigned int reg_addr,
+				  unsigned int count,
+				  unsigned char data[])
 {
 	u32 reg;
 	unsigned int start_offset;
@@ -625,9 +623,9 @@ int exynos_dp_write_bytes_to_dpcd(struct exynos_dp_device *dp,
 			retval = exynos_dp_start_aux_transaction(dp);
 			if (retval == 0)
 				break;
-			else
-				dev_dbg(dp->dev, "%s: Aux Transaction fail!\n",
-					__func__);
+
+			dev_dbg(dp->dev, "%s: Aux Transaction fail!\n",
+				__func__);
 		}
 
 		start_offset += cur_data_count;
@@ -637,9 +635,9 @@ int exynos_dp_write_bytes_to_dpcd(struct exynos_dp_device *dp,
 }
 
 int exynos_dp_read_bytes_from_dpcd(struct exynos_dp_device *dp,
-				unsigned int reg_addr,
-				unsigned int count,
-				unsigned char data[])
+				   unsigned int reg_addr,
+				   unsigned int count,
+				   unsigned char data[])
 {
 	u32 reg;
 	unsigned int start_offset;
@@ -683,9 +681,9 @@ int exynos_dp_read_bytes_from_dpcd(struct exynos_dp_device *dp,
 			retval = exynos_dp_start_aux_transaction(dp);
 			if (retval == 0)
 				break;
-			else
-				dev_dbg(dp->dev, "%s: Aux Transaction fail!\n",
-					__func__);
+
+			dev_dbg(dp->dev, "%s: Aux Transaction fail!\n",
+				__func__);
 		}
 
 		for (cur_data_idx = 0; cur_data_idx < cur_data_count;
@@ -736,9 +734,9 @@ int exynos_dp_select_i2c_device(struct exynos_dp_device *dp,
 }
 
 int exynos_dp_read_byte_from_i2c(struct exynos_dp_device *dp,
-				unsigned int device_addr,
-				unsigned int reg_addr,
-				unsigned int *data)
+				 unsigned int device_addr,
+				 unsigned int reg_addr,
+				 unsigned int *data)
 {
 	u32 reg;
 	int i;
@@ -767,9 +765,8 @@ int exynos_dp_read_byte_from_i2c(struct exynos_dp_device *dp,
 		retval = exynos_dp_start_aux_transaction(dp);
 		if (retval == 0)
 			break;
-		else
-			dev_dbg(dp->dev, "%s: Aux Transaction fail!\n",
-				__func__);
+
+		dev_dbg(dp->dev, "%s: Aux Transaction fail!\n", __func__);
 	}
 
 	/* Read data */
@@ -780,10 +777,10 @@ int exynos_dp_read_byte_from_i2c(struct exynos_dp_device *dp,
 }
 
 int exynos_dp_read_bytes_from_i2c(struct exynos_dp_device *dp,
-				unsigned int device_addr,
-				unsigned int reg_addr,
-				unsigned int count,
-				unsigned char edid[])
+				  unsigned int device_addr,
+				  unsigned int reg_addr,
+				  unsigned int count,
+				  unsigned char edid[])
 {
 	u32 reg;
 	unsigned int i, j;
@@ -807,8 +804,8 @@ int exynos_dp_read_bytes_from_i2c(struct exynos_dp_device *dp,
 			 * request without sending address
 			 */
 			if (!defer)
-				retval = exynos_dp_select_i2c_device(dp,
-						device_addr, reg_addr + i);
+				retval = exynos_dp_select_i2c_device(
+						dp, device_addr, reg_addr + i);
 			else
 				defer = 0;
 
@@ -819,24 +816,23 @@ int exynos_dp_read_bytes_from_i2c(struct exynos_dp_device *dp,
 				 * If Bit 3 is 0, I2C transaction.
 				 */
 				reg = AUX_LENGTH(16) |
-					AUX_TX_COMM_I2C_TRANSACTION |
-					AUX_TX_COMM_READ;
+				      AUX_TX_COMM_I2C_TRANSACTION |
+				      AUX_TX_COMM_READ;
 				writel(reg, dp->reg_base +
-					EXYNOS_DP_AUX_CH_CTL_1);
+				       EXYNOS_DP_AUX_CH_CTL_1);
 
 				/* Start AUX transaction */
 				retval = exynos_dp_start_aux_transaction(dp);
 				if (retval == 0)
 					break;
-				else
-					dev_dbg(dp->dev,
-						"%s: Aux Transaction fail!\n",
-						__func__);
+
+				dev_dbg(dp->dev, "%s: Aux Transaction fail!\n",
+					__func__);
 			}
 			/* Check if Rx sends defer */
 			reg = readl(dp->reg_base + EXYNOS_DP_AUX_RX_COMM);
 			if (reg == AUX_RX_COMM_AUX_DEFER ||
-				reg == AUX_RX_COMM_I2C_DEFER) {
+			    reg == AUX_RX_COMM_I2C_DEFER) {
 				dev_err(dp->dev, "Defer: %d\n\n", reg);
 				defer = 1;
 			}
@@ -901,7 +897,7 @@ void exynos_dp_enable_enhanced_mode(struct exynos_dp_device *dp, bool enable)
 }
 
 void exynos_dp_set_training_pattern(struct exynos_dp_device *dp,
-				 enum pattern_set pattern)
+				    enum pattern_set pattern)
 {
 	u32 reg;
 
@@ -974,7 +970,7 @@ void exynos_dp_set_lane3_pre_emphasis(struct exynos_dp_device *dp, u32 level)
 }
 
 void exynos_dp_set_lane0_link_training(struct exynos_dp_device *dp,
-					u32 training_lane)
+				       u32 training_lane)
 {
 	u32 reg;
 
@@ -983,7 +979,7 @@ void exynos_dp_set_lane0_link_training(struct exynos_dp_device *dp,
 }
 
 void exynos_dp_set_lane1_link_training(struct exynos_dp_device *dp,
-					u32 training_lane)
+				       u32 training_lane)
 {
 	u32 reg;
 
@@ -992,7 +988,7 @@ void exynos_dp_set_lane1_link_training(struct exynos_dp_device *dp,
 }
 
 void exynos_dp_set_lane2_link_training(struct exynos_dp_device *dp,
-					u32 training_lane)
+				       u32 training_lane)
 {
 	u32 reg;
 
@@ -1001,7 +997,7 @@ void exynos_dp_set_lane2_link_training(struct exynos_dp_device *dp,
 }
 
 void exynos_dp_set_lane3_link_training(struct exynos_dp_device *dp,
-					u32 training_lane)
+				       u32 training_lane)
 {
 	u32 reg;
 
@@ -1125,9 +1121,9 @@ int exynos_dp_is_slave_video_stream_clock_on(struct exynos_dp_device *dp)
 }
 
 void exynos_dp_set_video_cr_mn(struct exynos_dp_device *dp,
-		enum clock_recovery_m_value_type type,
-		u32 m_value,
-		u32 n_value)
+			       enum clock_recovery_m_value_type type,
+			       u32 m_value,
+			       u32 n_value)
 {
 	u32 reg;
 
@@ -1221,7 +1217,7 @@ void exynos_dp_config_video_slave_mode(struct exynos_dp_device *dp)
 	u32 reg;
 
 	reg = readl(dp->reg_base + EXYNOS_DP_FUNC_EN_1);
-	reg &= ~(MASTER_VID_FUNC_EN_N|SLAVE_VID_FUNC_EN_N);
+	reg &= ~(MASTER_VID_FUNC_EN_N | SLAVE_VID_FUNC_EN_N);
 	reg |= MASTER_VID_FUNC_EN_N;
 	writel(reg, dp->reg_base + EXYNOS_DP_FUNC_EN_1);
 
-- 
2.1.2




From ykk at rock-chips.com  Mon Aug 31 22:49:01 2015
From: ykk at rock-chips.com (Yakir Yang)
Date: Tue,  1 Sep 2015 13:49:01 +0800
Subject: [PATCH v4 02/16] drm: exynos/dp: convert to drm bridge mode
In-Reply-To: <1441086371-24838-1-git-send-email-ykk@rock-chips.com>
References: <1441086371-24838-1-git-send-email-ykk@rock-chips.com>
Message-ID: <1441086541-24943-1-git-send-email-ykk@rock-chips.com>

In order to move exynos dp code to bridge directory,
we need to convert driver drm bridge mode first. As
dp driver already have a ptn3460 bridge, so we need
to move ptn bridge to the next bridge of dp bridge.

Signed-off-by: Yakir Yang <ykk at rock-chips.com>
---
Changes in v4:
- Take Romain suggest, rebase on linux-next branch.

Changes in v3: None
Changes in v2:
- Take Jingoo Han suggest, just remove my name from author list.

 drivers/gpu/drm/exynos/exynos_dp_core.c | 104 +++++++++++++++++++++++---------
 drivers/gpu/drm/exynos/exynos_dp_core.h |   1 +
 2 files changed, 78 insertions(+), 27 deletions(-)

diff --git a/drivers/gpu/drm/exynos/exynos_dp_core.c b/drivers/gpu/drm/exynos/exynos_dp_core.c
index 266f7f7..bed0252 100644
--- a/drivers/gpu/drm/exynos/exynos_dp_core.c
+++ b/drivers/gpu/drm/exynos/exynos_dp_core.c
@@ -1001,9 +1001,9 @@ static int exynos_drm_attach_lcd_bridge(struct exynos_dp_device *dp,
 {
 	int ret;
 
-	encoder->bridge = dp->bridge;
-	dp->bridge->encoder = encoder;
-	ret = drm_bridge_attach(encoder->dev, dp->bridge);
+	encoder->bridge->next = dp->ptn_bridge;
+	dp->ptn_bridge->encoder = encoder;
+	ret = drm_bridge_attach(encoder->dev, dp->ptn_bridge);
 	if (ret) {
 		DRM_ERROR("Failed to attach bridge to drm\n");
 		return ret;
@@ -1012,14 +1012,15 @@ static int exynos_drm_attach_lcd_bridge(struct exynos_dp_device *dp,
 	return 0;
 }
 
-static int exynos_dp_create_connector(struct drm_encoder *encoder)
+static int exynos_dp_bridge_attach(struct drm_bridge *bridge)
 {
-	struct exynos_dp_device *dp = encoder_to_dp(encoder);
+	struct exynos_dp_device *dp = bridge->driver_private;
+	struct drm_encoder *encoder = &dp->encoder;
 	struct drm_connector *connector = &dp->connector;
 	int ret;
 
 	/* Pre-empt DP connector creation if there's a bridge */
-	if (dp->bridge) {
+	if (dp->ptn_bridge) {
 		ret = exynos_drm_attach_lcd_bridge(dp, encoder);
 		if (!ret)
 			return 0;
@@ -1045,22 +1046,9 @@ static int exynos_dp_create_connector(struct drm_encoder *encoder)
 	return ret;
 }
 
-static bool exynos_dp_mode_fixup(struct drm_encoder *encoder,
-				 const struct drm_display_mode *mode,
-				 struct drm_display_mode *adjusted_mode)
-{
-	return true;
-}
-
-static void exynos_dp_mode_set(struct drm_encoder *encoder,
-			       struct drm_display_mode *mode,
-			       struct drm_display_mode *adjusted_mode)
-{
-}
-
-static void exynos_dp_enable(struct drm_encoder *encoder)
+static void exynos_dp_bridge_enable(struct drm_bridge *bridge)
 {
-	struct exynos_dp_device *dp = encoder_to_dp(encoder);
+	struct exynos_dp_device *dp = bridge->driver_private;
 	struct exynos_drm_crtc *crtc = dp_to_crtc(dp);
 
 	if (dp->dpms_mode == DRM_MODE_DPMS_ON)
@@ -1085,9 +1073,9 @@ static void exynos_dp_enable(struct drm_encoder *encoder)
 	dp->dpms_mode = DRM_MODE_DPMS_ON;
 }
 
-static void exynos_dp_disable(struct drm_encoder *encoder)
+static void exynos_dp_bridge_disable(struct drm_bridge *bridge)
 {
-	struct exynos_dp_device *dp = encoder_to_dp(encoder);
+	struct exynos_dp_device *dp = bridge->driver_private;
 	struct exynos_drm_crtc *crtc = dp_to_crtc(dp);
 
 	if (dp->dpms_mode != DRM_MODE_DPMS_ON)
@@ -1116,6 +1104,68 @@ static void exynos_dp_disable(struct drm_encoder *encoder)
 	dp->dpms_mode = DRM_MODE_DPMS_OFF;
 }
 
+static void exynos_dp_bridge_nop(struct drm_bridge *bridge)
+{
+	/* do nothing */
+}
+
+static const struct drm_bridge_funcs exynos_dp_bridge_funcs = {
+	.enable = exynos_dp_bridge_enable,
+	.disable = exynos_dp_bridge_disable,
+	.pre_enable = exynos_dp_bridge_nop,
+	.post_disable = exynos_dp_bridge_nop,
+	.attach = exynos_dp_bridge_attach,
+};
+
+static int exynos_dp_create_connector(struct drm_encoder *encoder)
+{
+	struct exynos_dp_device *dp = encoder_to_dp(encoder);
+	struct drm_device *drm_dev = dp->drm_dev;
+	struct drm_bridge *bridge;
+	int ret;
+
+	bridge = devm_kzalloc(drm_dev->dev, sizeof(*bridge), GFP_KERNEL);
+	if (!bridge) {
+		DRM_ERROR("failed to allocate for drm bridge\n");
+		return -ENOMEM;
+	}
+
+	dp->bridge = bridge;
+
+	bridge->driver_private = dp;
+	bridge->encoder = encoder;
+	bridge->funcs = &exynos_dp_bridge_funcs;
+
+	ret = drm_bridge_attach(drm_dev, bridge);
+	if (ret) {
+		DRM_ERROR("failed to attach drm bridge\n");
+		return -EINVAL;
+	}
+
+	return 0;
+}
+
+static bool exynos_dp_mode_fixup(struct drm_encoder *encoder,
+				 const struct drm_display_mode *mode,
+				 struct drm_display_mode *adjusted_mode)
+{
+	return true;
+}
+
+static void exynos_dp_mode_set(struct drm_encoder *encoder,
+			       struct drm_display_mode *mode,
+			       struct drm_display_mode *adjusted_mode)
+{
+}
+
+static void exynos_dp_enable(struct drm_encoder *encoder)
+{
+}
+
+static void exynos_dp_disable(struct drm_encoder *encoder)
+{
+}
+
 static struct drm_encoder_helper_funcs exynos_dp_encoder_helper_funcs = {
 	.mode_fixup = exynos_dp_mode_fixup,
 	.mode_set = exynos_dp_mode_set,
@@ -1358,9 +1408,9 @@ static int exynos_dp_probe(struct platform_device *pdev)
 	if (endpoint) {
 		bridge_node = of_graph_get_remote_port_parent(endpoint);
 		if (bridge_node) {
-			dp->bridge = of_drm_find_bridge(bridge_node);
+			dp->ptn_bridge = of_drm_find_bridge(bridge_node);
 			of_node_put(bridge_node);
-			if (!dp->bridge)
+			if (!dp->ptn_bridge)
 				return -EPROBE_DEFER;
 		} else {
 			return -EPROBE_DEFER;
@@ -1382,7 +1432,7 @@ static int exynos_dp_suspend(struct device *dev)
 {
 	struct exynos_dp_device *dp = dev_get_drvdata(dev);
 
-	exynos_dp_disable(&dp->encoder);
+	exynos_dp_bridge_disable(dp->bridge);
 	return 0;
 }
 
@@ -1390,7 +1440,7 @@ static int exynos_dp_resume(struct device *dev)
 {
 	struct exynos_dp_device *dp = dev_get_drvdata(dev);
 
-	exynos_dp_enable(&dp->encoder);
+	exynos_dp_bridge_enable(dp->bridge);
 	return 0;
 }
 #endif
diff --git a/drivers/gpu/drm/exynos/exynos_dp_core.h b/drivers/gpu/drm/exynos/exynos_dp_core.h
index 71f2b86..7ff754f 100644
--- a/drivers/gpu/drm/exynos/exynos_dp_core.h
+++ b/drivers/gpu/drm/exynos/exynos_dp_core.h
@@ -153,6 +153,7 @@ struct exynos_dp_device {
 	struct drm_connector	connector;
 	struct drm_panel	*panel;
 	struct drm_bridge	*bridge;
+	struct drm_bridge	*ptn_bridge;
 	struct clk		*clock;
 	unsigned int		irq;
 	void __iomem		*reg_base;
-- 
2.1.2




From ykk at rock-chips.com  Mon Aug 31 22:52:41 2015
From: ykk at rock-chips.com (Yakir Yang)
Date: Tue,  1 Sep 2015 13:52:41 +0800
Subject: [PATCH v4 04/16] drm: bridge: analogix/dp: remove duplicate
 configuration of link rate and link count
In-Reply-To: <1441086371-24838-1-git-send-email-ykk@rock-chips.com>
References: <1441086371-24838-1-git-send-email-ykk@rock-chips.com>
Message-ID: <1441086761-25052-1-git-send-email-ykk@rock-chips.com>

link_rate and lane_count already configured in analogix_dp_set_link_train(),
so we don't need to config those repeatly after training finished, just
remove them out.

Beside Display Port 1.2 already support 5.4Gbps link rate, the maximum sets
would change from {1.62Gbps, 2.7Gbps} to {1.62Gbps, 2.7Gbps, 5.4Gbps}.

Signed-off-by: Yakir Yang <ykk at rock-chips.com>
---
Changes in v4:
- Take Jingoo Han suggest, update commit message more readable.
- Adjust the order from 05 to 04

Changes in v3:
- Take Thierry Reding suggest, link_rate and lane_count shouldn't config to
  the DT property value directly, but we can take those as hardware limite.
  For example, RK3288 only support 4 physical lanes of 2.7/1.62 Gbps/lane,
  so DT property would like "link-rate = 0x0a" "lane-count = 4".

Changes in v2: None

 drivers/gpu/drm/bridge/analogix/analogix_dp_core.c | 8 ++++----
 drivers/gpu/drm/bridge/analogix/analogix_dp_core.h | 5 +++--
 2 files changed, 7 insertions(+), 6 deletions(-)

diff --git a/drivers/gpu/drm/bridge/analogix/analogix_dp_core.c b/drivers/gpu/drm/bridge/analogix/analogix_dp_core.c
index 7d62f22..7196097 100644
--- a/drivers/gpu/drm/bridge/analogix/analogix_dp_core.c
+++ b/drivers/gpu/drm/bridge/analogix/analogix_dp_core.c
@@ -631,6 +631,8 @@ static void analogix_dp_get_max_rx_bandwidth(struct analogix_dp_device *dp,
 	/*
 	 * For DP rev.1.1, Maximum link rate of Main Link lanes
 	 * 0x06 = 1.62 Gbps, 0x0a = 2.7 Gbps
+	 * For DP rev.1.2, Maximum link rate of Main Link lanes
+	 * 0x06 = 1.62 Gbps, 0x0a = 2.7 Gbps, 0x14 = 5.4Gbps
 	 */
 	analogix_dp_read_byte_from_dpcd(dp, DP_MAX_LINK_RATE, &data);
 	*bandwidth = data;
@@ -664,7 +666,8 @@ static void analogix_dp_init_training(struct analogix_dp_device *dp,
 	analogix_dp_get_max_rx_lane_count(dp, &dp->link_train.lane_count);
 
 	if ((dp->link_train.link_rate != LINK_RATE_1_62GBPS) &&
-	    (dp->link_train.link_rate != LINK_RATE_2_70GBPS)) {
+	    (dp->link_train.link_rate != LINK_RATE_2_70GBPS) &&
+	    (dp->link_train.link_rate != LINK_RATE_5_40GBPS)) {
 		dev_err(dp->dev, "Rx Max Link Rate is abnormal :%x !\n",
 			dp->link_train.link_rate);
 		dp->link_train.link_rate = LINK_RATE_1_62GBPS;
@@ -905,9 +908,6 @@ static void analogix_dp_commit(struct analogix_dp_device *dp)
 	analogix_dp_enable_rx_to_enhanced_mode(dp, 1);
 	analogix_dp_enable_enhanced_mode(dp, 1);
 
-	analogix_dp_set_lane_count(dp, dp->video_info->lane_count);
-	analogix_dp_set_link_bandwidth(dp, dp->video_info->link_rate);
-
 	analogix_dp_init_video(dp);
 	ret = analogix_dp_config_video(dp);
 	if (ret)
diff --git a/drivers/gpu/drm/bridge/analogix/analogix_dp_core.h b/drivers/gpu/drm/bridge/analogix/analogix_dp_core.h
index d7e47e0..ffabbd0 100644
--- a/drivers/gpu/drm/bridge/analogix/analogix_dp_core.h
+++ b/drivers/gpu/drm/bridge/analogix/analogix_dp_core.h
@@ -21,8 +21,9 @@
 #define MAX_EQ_LOOP 5
 
 enum link_rate_type {
-	LINK_RATE_1_62GBPS = 0x06,
-	LINK_RATE_2_70GBPS = 0x0a
+	LINK_RATE_1_62GBPS = DP_LINK_BW_1_62,
+	LINK_RATE_2_70GBPS = DP_LINK_BW_2_7,
+	LINK_RATE_5_40GBPS = DP_LINK_BW_5_4,
 };
 
 enum link_lane_count_type {
-- 
2.1.2




From ykk at rock-chips.com  Mon Aug 31 22:55:34 2015
From: ykk at rock-chips.com (Yakir Yang)
Date: Tue,  1 Sep 2015 13:55:34 +0800
Subject: [PATCH v4 05/16] drm: bridge: analogix/dp: dynamic parse sync_pol &
 interlace & colorimetry
In-Reply-To: <1441086371-24838-1-git-send-email-ykk@rock-chips.com>
References: <1441086371-24838-1-git-send-email-ykk@rock-chips.com>
Message-ID: <1441086934-25107-1-git-send-email-ykk@rock-chips.com>

Both hsync/vsync polarity and interlace mode can be parsed from
drm display mode, and dynamic_range and ycbcr_coeff can be judge
by the video code, same to color space and color depth can be
parsed from EDID.

But presumably Exynos still relaies on the DT properties, so take
good use of mode_fixup() in to achieve the compatibility hacks.

Signed-off-by: Yakir Yang <ykk at rock-chips.com>
---
Changes in v4:
- Take Krzysztof suggest, provide backword compatibility with samsung.
- Take Thierry suggest, add "color-depth" and "color-space" dynamic parsed.

Changes in v3:
- Take Thierry Reding suggest, dynamic parse video timing info from
  struct drm_display_mode and struct drm_display_info.

Changes in v2: None

 drivers/gpu/drm/bridge/analogix/analogix_dp_core.c | 141 +++++++++++++--------
 drivers/gpu/drm/bridge/analogix/analogix_dp_core.h |   2 +-
 drivers/gpu/drm/bridge/analogix/analogix_dp_reg.c  |  14 +-
 drivers/gpu/drm/exynos/exynos_dp.c                 |  58 ++++++++-
 4 files changed, 151 insertions(+), 64 deletions(-)

diff --git a/drivers/gpu/drm/bridge/analogix/analogix_dp_core.c b/drivers/gpu/drm/bridge/analogix/analogix_dp_core.c
index 7196097..f0db92e 100644
--- a/drivers/gpu/drm/bridge/analogix/analogix_dp_core.c
+++ b/drivers/gpu/drm/bridge/analogix/analogix_dp_core.c
@@ -897,8 +897,8 @@ static void analogix_dp_commit(struct analogix_dp_device *dp)
 		return;
 	}
 
-	ret = analogix_dp_set_link_train(dp, dp->video_info->lane_count,
-					 dp->video_info->link_rate);
+	ret = analogix_dp_set_link_train(dp, dp->video_info.lane_count,
+					 dp->video_info.link_rate);
 	if (ret) {
 		dev_err(dp->dev, "unable to do link train\n");
 		return;
@@ -1081,6 +1081,82 @@ static void analogix_dp_bridge_disable(struct drm_bridge *bridge)
 	dp->dpms_mode = DRM_MODE_DPMS_OFF;
 }
 
+static void analogix_dp_bridge_mode_set(struct drm_bridge *bridge,
+					struct drm_display_mode *orig_mode,
+					struct drm_display_mode *mode)
+{
+	struct analogix_dp_device *dp = bridge->driver_private;
+	struct drm_display_info *display_info = &dp->connector.display_info;
+	struct video_info *video_info = &dp->video_info;
+	struct device_node *dp_node = dp->dev->of_node;
+	int vic;
+
+	/* interlaces & hsync pol & vsync pol */
+	video_info->interlaced = !!(mode->flags & DRM_MODE_FLAG_INTERLACE);
+	video_info->v_sync_polarity = !!(mode->flags & DRM_MODE_FLAG_NVSYNC);
+	video_info->h_sync_polarity = !!(mode->flags & DRM_MODE_FLAG_NHSYNC);
+
+	/* dynamic_range & colorimetry */
+	vic = drm_match_cea_mode(mode);
+	if ((vic == 6) || (vic == 7) || (vic == 21) || (vic == 22) ||
+	    (vic == 2) || (vic == 3) || (vic == 17) || (vic == 18)) {
+		video_info->dynamic_range = CEA;
+		video_info->ycbcr_coeff = COLOR_YCBCR601;
+	} else if (vic) {
+		video_info->dynamic_range = CEA;
+		video_info->ycbcr_coeff = COLOR_YCBCR709;
+	} else {
+		video_info->dynamic_range = VESA;
+		video_info->ycbcr_coeff = COLOR_YCBCR709;
+	}
+
+	switch (display_info->bpc) {
+	case 12:
+		video_info->color_depth = COLOR_12;
+		break;
+	case 10:
+		video_info->color_depth = COLOR_10;
+		break;
+	case 8:
+		video_info->color_depth = COLOR_8;
+		break;
+	case 6:
+		video_info->color_depth = COLOR_6;
+		break;
+	default:
+		video_info->color_depth = COLOR_8;
+		break;
+	}
+
+	if (display_info->color_formats | DRM_COLOR_FORMAT_YCRCB444)
+		video_info->color_space = COLOR_YCBCR444;
+	else if (display_info->color_formats | DRM_COLOR_FORMAT_YCRCB422)
+		video_info->color_space = COLOR_YCBCR422;
+	else if (display_info->color_formats | DRM_COLOR_FORMAT_RGB444)
+		video_info->color_space = COLOR_RGB;
+	else
+		video_info->color_space = COLOR_RGB;
+
+	/*
+	 * NOTE: those property parseing code is used for
+	 * providing backward compatibility for samsung platform.
+	 */
+	of_property_read_u32(dp_node, "samsung,color-space",
+			     &video_info->color_space);
+	of_property_read_u32(dp_node, "samsung,dynamic-range",
+			     &video_info->dynamic_range);
+	of_property_read_u32(dp_node, "samsung,ycbcr-coeff",
+			     &video_info->ycbcr_coeff);
+	of_property_read_u32(dp_node, "samsung,color-depth",
+			     &video_info->color_depth);
+	of_property_read_u32(dp_node, "hsync-active-high",
+			     (unsigned int *)&video_info->h_sync_polarity);
+	of_property_read_u32(dp_node, "vsync-active-high",
+			     (unsigned int *)&video_info->v_sync_polarity);
+	of_property_read_u32(dp_node, "interlaced",
+			     (unsigned int *)&video_info->interlaced);
+}
+
 static void analogix_dp_bridge_nop(struct drm_bridge *bridge)
 {
 	/* do nothing */
@@ -1091,6 +1167,7 @@ static const struct drm_bridge_funcs analogix_dp_bridge_funcs = {
 	.disable = analogix_dp_bridge_disable,
 	.pre_enable = analogix_dp_bridge_nop,
 	.post_disable = analogix_dp_bridge_nop,
+	.mode_set = analogix_dp_bridge_mode_set,
 	.attach = analogix_dp_bridge_attach,
 };
 
@@ -1121,62 +1198,24 @@ static int analogix_dp_create_bridge(struct drm_device *drm_dev,
 	return 0;
 }
 
-static struct video_info *analogix_dp_dt_parse_pdata(struct device *dev)
+static int analogix_dp_dt_parse_pdata(struct analogix_dp_device *dp)
 {
-	struct device_node *dp_node = dev->of_node;
-	struct video_info *dp_video_config;
-
-	dp_video_config = devm_kzalloc(dev, sizeof(*dp_video_config),
-				       GFP_KERNEL);
-	if (!dp_video_config)
-		return ERR_PTR(-ENOMEM);
-
-	dp_video_config->h_sync_polarity =
-		of_property_read_bool(dp_node, "hsync-active-high");
-
-	dp_video_config->v_sync_polarity =
-		of_property_read_bool(dp_node, "vsync-active-high");
-
-	dp_video_config->interlaced =
-		of_property_read_bool(dp_node, "interlaced");
-
-	if (of_property_read_u32(dp_node, "samsung,color-space",
-				 &dp_video_config->color_space)) {
-		dev_err(dev, "failed to get color-space\n");
-		return ERR_PTR(-EINVAL);
-	}
-
-	if (of_property_read_u32(dp_node, "samsung,dynamic-range",
-				 &dp_video_config->dynamic_range)) {
-		dev_err(dev, "failed to get dynamic-range\n");
-		return ERR_PTR(-EINVAL);
-	}
-
-	if (of_property_read_u32(dp_node, "samsung,ycbcr-coeff",
-				 &dp_video_config->ycbcr_coeff)) {
-		dev_err(dev, "failed to get ycbcr-coeff\n");
-		return ERR_PTR(-EINVAL);
-	}
-
-	if (of_property_read_u32(dp_node, "samsung,color-depth",
-				 &dp_video_config->color_depth)) {
-		dev_err(dev, "failed to get color-depth\n");
-		return ERR_PTR(-EINVAL);
-	}
+	struct device_node *dp_node = dp->dev->of_node;
+	struct video_info *video_config = &dp->video_info;
 
 	if (of_property_read_u32(dp_node, "samsung,link-rate",
-				 &dp_video_config->link_rate)) {
+				 &video_info->link_rate)) {
 		dev_err(dev, "failed to get link-rate\n");
-		return ERR_PTR(-EINVAL);
+		return -EINVAL;
 	}
 
 	if (of_property_read_u32(dp_node, "samsung,lane-count",
-				 &dp_video_config->lane_count)) {
+				 &video_info->lane_count)) {
 		dev_err(dev, "failed to get lane-count\n");
-		return ERR_PTR(-EINVAL);
+		return -EINVAL;
 	}
 
-	return dp_video_config;
+	return 0;
 }
 
 int analogix_dp_bind(struct device *dev, struct drm_device *drm_dev,
@@ -1205,9 +1244,9 @@ int analogix_dp_bind(struct device *dev, struct drm_device *drm_dev,
 	 */
 	dp->plat_data = plat_data;
 
-	dp->video_info = analogix_dp_dt_parse_pdata(&pdev->dev);
-	if (IS_ERR(dp->video_info))
-		return PTR_ERR(dp->video_info);
+	ret = analogix_dp_dt_parse_pdata(dp);
+	if (ret)
+		return ret;
 
 	dp->phy = devm_phy_get(dp->dev, "dp");
 	if (IS_ERR(dp->phy)) {
diff --git a/drivers/gpu/drm/bridge/analogix/analogix_dp_core.h b/drivers/gpu/drm/bridge/analogix/analogix_dp_core.h
index ffabbd0..6e3d5bc 100644
--- a/drivers/gpu/drm/bridge/analogix/analogix_dp_core.h
+++ b/drivers/gpu/drm/bridge/analogix/analogix_dp_core.h
@@ -154,7 +154,7 @@ struct analogix_dp_device {
 	unsigned int		irq;
 	void __iomem		*reg_base;
 
-	struct video_info	*video_info;
+	struct video_info	video_info;
 	struct link_train	link_train;
 	struct work_struct	hotplug_work;
 	struct phy		*phy;
diff --git a/drivers/gpu/drm/bridge/analogix/analogix_dp_reg.c b/drivers/gpu/drm/bridge/analogix/analogix_dp_reg.c
index b879d8c..6a643be 100644
--- a/drivers/gpu/drm/bridge/analogix/analogix_dp_reg.c
+++ b/drivers/gpu/drm/bridge/analogix/analogix_dp_reg.c
@@ -1084,15 +1084,15 @@ void analogix_dp_set_video_color_format(struct analogix_dp_device *dp)
 	u32 reg;
 
 	/* Configure the input color depth, color space, dynamic range */
-	reg = (dp->video_info->dynamic_range << IN_D_RANGE_SHIFT) |
-		(dp->video_info->color_depth << IN_BPC_SHIFT) |
-		(dp->video_info->color_space << IN_COLOR_F_SHIFT);
+	reg = (dp->video_info.dynamic_range << IN_D_RANGE_SHIFT) |
+		(dp->video_info.color_depth << IN_BPC_SHIFT) |
+		(dp->video_info.color_space << IN_COLOR_F_SHIFT);
 	writel(reg, dp->reg_base + ANALOGIX_DP_VIDEO_CTL_2);
 
 	/* Set Input Color YCbCr Coefficients to ITU601 or ITU709 */
 	reg = readl(dp->reg_base + ANALOGIX_DP_VIDEO_CTL_3);
 	reg &= ~IN_YC_COEFFI_MASK;
-	if (dp->video_info->ycbcr_coeff)
+	if (dp->video_info.ycbcr_coeff)
 		reg |= IN_YC_COEFFI_ITU709;
 	else
 		reg |= IN_YC_COEFFI_ITU601;
@@ -1229,17 +1229,17 @@ void analogix_dp_config_video_slave_mode(struct analogix_dp_device *dp)
 
 	reg = readl(dp->reg_base + ANALOGIX_DP_VIDEO_CTL_10);
 	reg &= ~INTERACE_SCAN_CFG;
-	reg |= (dp->video_info->interlaced << 2);
+	reg |= (dp->video_info.interlaced << 2);
 	writel(reg, dp->reg_base + ANALOGIX_DP_VIDEO_CTL_10);
 
 	reg = readl(dp->reg_base + ANALOGIX_DP_VIDEO_CTL_10);
 	reg &= ~VSYNC_POLARITY_CFG;
-	reg |= (dp->video_info->v_sync_polarity << 1);
+	reg |= (dp->video_info.v_sync_polarity << 1);
 	writel(reg, dp->reg_base + ANALOGIX_DP_VIDEO_CTL_10);
 
 	reg = readl(dp->reg_base + ANALOGIX_DP_VIDEO_CTL_10);
 	reg &= ~HSYNC_POLARITY_CFG;
-	reg |= (dp->video_info->h_sync_polarity << 0);
+	reg |= (dp->video_info.h_sync_polarity << 0);
 	writel(reg, dp->reg_base + ANALOGIX_DP_VIDEO_CTL_10);
 
 	reg = AUDIO_MODE_SPDIF_MODE | VIDEO_MODE_SLAVE_MODE;
diff --git a/drivers/gpu/drm/exynos/exynos_dp.c b/drivers/gpu/drm/exynos/exynos_dp.c
index 7e1be72..6060d2c 100644
--- a/drivers/gpu/drm/exynos/exynos_dp.c
+++ b/drivers/gpu/drm/exynos/exynos_dp.c
@@ -28,8 +28,13 @@
 
 #include "exynos_drm_crtc.h"
 
-#define plat_data_to_dp(pd) \
-		container_of(pd, struct exynos_dp_device, plat_data)
+#define to_dp(nm)	container_of(nm, struct exynos_dp_device, nm)
+
+struct video_info {
+	bool h_sync_polarity;
+	bool v_sync_polarity;
+	bool interlaced;
+};
 
 struct exynos_dp_device {
 	struct drm_encoder         encoder;
@@ -39,12 +44,13 @@ struct exynos_dp_device {
 
 	struct exynos_drm_panel_info priv;
 	struct analogix_dp_plat_data plat_data;
+	struct video_info            video_info;
 };
 
 int exynos_dp_crtc_clock_enable(struct analogix_dp_plat_data *plat_data,
 				bool enable)
 {
-	struct exynos_dp_device *dp = plat_data_to_dp(plat_data);
+	struct exynos_dp_device *dp = to_dp(plat_data);
 	struct drm_encoder *encoder = &dp->encoder;
 	struct exynos_drm_crtc *crtc;
 
@@ -71,7 +77,7 @@ static int exynos_dp_poweroff(struct analogix_dp_plat_data *plat_data)
 static int exynos_dp_get_modes(struct analogix_dp_plat_data *plat_data,
 			       struct drm_connector *connector)
 {
-	struct exynos_dp_device *dp = plat_data_to_dp(plat_data);
+	struct exynos_dp_device *dp = to_dp(plat_data);
 	struct drm_display_mode *mode;
 
 	if (dp->plat_data.panel)
@@ -99,7 +105,7 @@ static int exynos_dp_get_modes(struct analogix_dp_plat_data *plat_data,
 static int exynos_dp_bridge_attach(struct analogix_dp_plat_data *plat_data,
 				   struct drm_bridge *bridge)
 {
-	struct exynos_dp_device *dp = plat_data_to_dp(plat_data);
+	struct exynos_dp_device *dp = to_dp(plat_data);
 	struct drm_encoder *encoder = &dp->encoder;
 	int ret;
 
@@ -122,6 +128,28 @@ static bool exynos_dp_mode_fixup(struct drm_encoder *encoder,
 				 const struct drm_display_mode *mode,
 				 struct drm_display_mode *adjusted_mode)
 {
+	struct exynos_dp_device *dp = to_dp(encoder);
+	int flags = adjusted_mode->flags;
+
+	flags &= ~(DRM_MODE_FLAG_PHSYNC | DRM_MODE_FLAG_NHSYNC |
+		   DRM_MODE_FLAG_PVSYNC | DRM_MODE_FLAG_NVSYNC |
+		   DRM_MODE_FLAG_INTERLACE);
+
+	if (dp->video_info.h_sync_polarity)
+		flags |= DRM_MODE_FLAG_PHSYNC;
+	else
+		flags |= DRM_MODE_FLAG_NHSYNC;
+
+	if (dp->video_info.v_sync_polarity)
+		flags |= DRM_MODE_FLAG_PVSYNC;
+	else
+		flags |= DRM_MODE_FLAG_NVSYNC;
+
+	if (dp->video_info.interlaced)
+		flags |= DRM_MODE_FLAG_INTERLACE;
+
+	adjusted_mode->flags = flags;
+
 	return true;
 }
 
@@ -163,6 +191,22 @@ static int exynos_dp_dt_parse_panel(struct exynos_dp_device *dp)
 	return 0;
 }
 
+static int exynos_dp_dt_parse_video_info(struct exynos_dp_device *dp)
+{
+	struct device_node *dp_node = dp->dev->of_node;
+
+	dp->video_info.h_sync_polarity =
+		of_property_read_bool(dp_node, "hsync-active-high");
+
+	dp->video_info.v_sync_polarity =
+		of_property_read_bool(dp_node, "vsync-active-high");
+
+	dp->video_info.interlaced =
+		of_property_read_bool(dp_node, "interlaced");
+
+	return 0;
+}
+
 static int exynos_dp_bind(struct device *dev, struct device *master, void *data)
 {
 	struct exynos_dp_device *dp = dev_get_drvdata(dev);
@@ -191,6 +235,10 @@ static int exynos_dp_bind(struct device *dev, struct device *master, void *data)
 			return ret;
 	}
 
+	ret = exynos_dp_dt_parse_video_info(dp);
+	if (ret)
+		return ret;
+
 	pipe = exynos_drm_crtc_get_pipe_from_type(drm_dev,
 						  EXYNOS_DISPLAY_TYPE_LCD);
 	if (pipe < 0)
-- 
2.1.2




From ykk at rock-chips.com  Mon Aug 31 22:58:52 2015
From: ykk at rock-chips.com (Yakir Yang)
Date: Tue,  1 Sep 2015 13:58:52 +0800
Subject: [PATCH v4 06/16] Documentation: drm/bridge: add document for
 analogix_dp
In-Reply-To: <1441086371-24838-1-git-send-email-ykk@rock-chips.com>
References: <1441086371-24838-1-git-send-email-ykk@rock-chips.com>
Message-ID: <1441087132-25295-1-git-send-email-ykk@rock-chips.com>

Analogix dp driver is split from exynos dp driver, so we just
make an copy of exynos_dp.txt, and then simplify exynos_dp.txt

Beside update some exynos dtsi file with the latest change
according to the devicetree binding documents.

Signed-off-by: Yakir Yang <ykk at rock-chips.com>
---
Changes in v4:
- Take Krzysztof suggest, split all DTS changes, and provide backward compatibility.
  Mark old properties as deprecated but still support them.
- Take Rob suggest, update "analogix,hpd-gpio" to "hpd-gpios" prop name.
- Take Thierry suggest, deprecated some properties which could parsed from Edid/Mode/DPCD.
    "analogix,color-space" & "analogix,color-depth"   &
    "analogix,link-rate"   & "analogix,lane-count"    &
    "analogix,ycbcr-coeff" & "analogix,dynamic-range" &
    "vsync-active-high"    & "hsync-active-high"      & "interlaces"

Changes in v3:
- Take Heiko suggest, add devicetree binding documents.
- Take Thierry Reding suggest, remove sync pol & colorimetry properies
  from the new analogix dp driver devicetree binding.
- Update the exist exynos dtsi file with the latest DP DT properies.

Changes in v2: None

 .../devicetree/bindings/drm/bridge/analogix_dp.txt | 50 +++++++++++++++++
 .../devicetree/bindings/video/exynos_dp.txt        | 63 ++++++++--------------
 2 files changed, 71 insertions(+), 42 deletions(-)
 create mode 100644 Documentation/devicetree/bindings/drm/bridge/analogix_dp.txt

diff --git a/Documentation/devicetree/bindings/drm/bridge/analogix_dp.txt b/Documentation/devicetree/bindings/drm/bridge/analogix_dp.txt
new file mode 100644
index 0000000..f54dc3e
--- /dev/null
+++ b/Documentation/devicetree/bindings/drm/bridge/analogix_dp.txt
@@ -0,0 +1,50 @@
+Analogix Display Port bridge bindings
+
+Required properties for dp-controller:
+	-compatible:
+		platform specific such as:
+		 * "samsung,exynos5-dp"
+		 * "rockchip,rk3288-dp"
+	-reg:
+		physical base address of the controller and length
+		of memory mapped region.
+	-interrupts:
+		interrupt combiner values.
+	-clocks:
+		from common clock binding: handle to dp clock.
+	-clock-names:
+		from common clock binding: Shall be "dp".
+	-interrupt-parent:
+		phandle to Interrupt combiner node.
+	-phys:
+		from general PHY binding: the phandle for the PHY device.
+	-phy-names:
+		from general PHY binding: Should be "dp".
+
+Optional properties for dp-controller:
+	-hpd-gpios:
+		Hotplug detect GPIO.
+		Indicates which GPIO should be used for hotplug detection
+	-port@[X]: SoC specific port nodes with endpoint definitions as defined
+		in Documentation/devicetree/bindings/media/video-interfaces.txt,
+		please refer to the SoC specific binding document:
+		* Documentation/devicetree/bindings/video/exynos_dp.txt
+		* Documentation/devicetree/bindings/video/analogix_dp-rockchip.txt
+
+
+[1]: Documentation/devicetree/bindings/media/video-interfaces.txt
+-------------------------------------------------------------------------------
+
+Example:
+
+	dp-controller {
+		compatible = "samsung,exynos5-dp";
+		reg = <0x145b0000 0x10000>;
+		interrupts = <10 3>;
+		interrupt-parent = <&combiner>;
+		clocks = <&clock 342>;
+		clock-names = "dp";
+
+		phys = <&dp_phy>;
+		phy-names = "dp";
+	};
diff --git a/Documentation/devicetree/bindings/video/exynos_dp.txt b/Documentation/devicetree/bindings/video/exynos_dp.txt
index 7a3a9cd..ea03b3a 100644
--- a/Documentation/devicetree/bindings/video/exynos_dp.txt
+++ b/Documentation/devicetree/bindings/video/exynos_dp.txt
@@ -31,45 +31,31 @@ Required properties for dp-controller:
 		from general PHY binding: the phandle for the PHY device.
 	-phy-names:
 		from general PHY binding: Should be "dp".
-	-samsung,color-space:
-		input video data format.
-			COLOR_RGB = 0, COLOR_YCBCR422 = 1, COLOR_YCBCR444 = 2
-	-samsung,dynamic-range:
-		dynamic range for input video data.
-			VESA = 0, CEA = 1
-	-samsung,ycbcr-coeff:
-		YCbCr co-efficients for input video.
-			COLOR_YCBCR601 = 0, COLOR_YCBCR709 = 1
-	-samsung,color-depth:
-		number of bits per colour component.
-			COLOR_6 = 0, COLOR_8 = 1, COLOR_10 = 2, COLOR_12 = 3
-	-samsung,link-rate:
-		link rate supported by the panel.
-			LINK_RATE_1_62GBPS = 0x6, LINK_RATE_2_70GBPS = 0x0A
-	-samsung,lane-count:
-		number of lanes supported by the panel.
-			LANE_COUNT1 = 1, LANE_COUNT2 = 2, LANE_COUNT4 = 4
+
+Optional properties for dp-controller:
 	- display-timings: timings for the connected panel as described by
 		Documentation/devicetree/bindings/video/display-timing.txt
 
-Optional properties for dp-controller:
-	-interlaced:
-		interlace scan mode.
-			Progressive if defined, Interlaced if not defined
-	-vsync-active-high:
-		VSYNC polarity configuration.
-			High if defined, Low if not defined
-	-hsync-active-high:
-		HSYNC polarity configuration.
-			High if defined, Low if not defined
-	-samsung,hpd-gpio:
-		Hotplug detect GPIO.
-			Indicates which GPIO should be used for hotplug
-			detection
-	-video interfaces: Device node can contain video interface port
-			    nodes according to [1].
+For the below properties, please refer to Analogix DP binding document:
+ * Documentation/devicetree/bindings/drm/bridge/analogix_dp.txt
+	-phys (required)
+	-phy-names (required)
+	-hpd-gpios (optional)
+	-video interfaces (optional)
 
-[1]: Documentation/devicetree/bindings/media/video-interfaces.txt
+Deprecated properties for DisplayPort:
+-interlaced:            deprecated prop that can parsed frm drm_display_mode.
+-vsync-active-high:     deprecated prop that can parsed frm drm_display_mode.
+-hsync-active-high:     deprecated prop that can parsed frm drm_display_mode.
+-samsung,ycbcr-coeff:   deprecated prop that can parsed frm drm_display_mode.
+-samsung,dynamic-range: deprecated prop that can parsed frm drm_display_mode.
+-samsung,color-space:   deprecated prop that can parsed from drm_display_info.
+-samsung,color-depth:   deprecated prop that can parsed from drm_display_info.
+-samsung,link-rate:     deprecated prop that can reading from monitor by dpcd method.
+-samsung,lane-count:    deprecated prop that can reading from monitor by dpcd method.
+-samsung,hpd-gpio:      deprecated name for hpd-gpios.
+
+-------------------------------------------------------------------------------
 
 Example:
 
@@ -88,13 +74,6 @@ SOC specific portion:
 
 Board Specific portion:
 	dp-controller {
-		samsung,color-space = <0>;
-		samsung,dynamic-range = <0>;
-		samsung,ycbcr-coeff = <0>;
-		samsung,color-depth = <1>;
-		samsung,link-rate = <0x0a>;
-		samsung,lane-count = <4>;
-
 		display-timings {
 			native-mode = <&lcd_timing>;
 			lcd_timing: 1366x768 {
-- 
2.1.2




From ykk at rock-chips.com  Mon Aug 31 23:01:11 2015
From: ykk at rock-chips.com (Yakir Yang)
Date: Tue,  1 Sep 2015 14:01:11 +0800
Subject: [PATCH v4 07/16] ARM: dts: exynos/dp: remove some properties that
 deprecated by analogix_dp driver
In-Reply-To: <1441086371-24838-1-git-send-email-ykk@rock-chips.com>
References: <1441086371-24838-1-git-send-email-ykk@rock-chips.com>
Message-ID: <1441087272-25353-1-git-send-email-ykk@rock-chips.com>

After exynos_dp have been splited the common IP code into analogix_dp driver,
the analogix_dp driver have deprecated some samsung platform properties which
could be dynamic parsed from EDID/MODE/DPCD message, so this is an update for
exynos DTS file for dp-controller.

Beside analogix_dp have provide the backward compatibility, so there are no
bisectability break that make this change in a separate patch.

Signed-off-by: Yakir Yang <ykk at rock-chips.com>
---
Changes in v4:
- Take Krzysztof suggest, separate all DTS changes to a separate patch.

Changes in v3: None
Changes in v2: None

 arch/arm/boot/dts/exynos5250-arndale.dts   | 2 --
 arch/arm/boot/dts/exynos5250-smdk5250.dts  | 2 --
 arch/arm/boot/dts/exynos5250-snow.dts      | 4 +---
 arch/arm/boot/dts/exynos5250-spring.dts    | 4 +---
 arch/arm/boot/dts/exynos5420-peach-pit.dts | 4 +---
 arch/arm/boot/dts/exynos5420-smdk5420.dts  | 2 --
 arch/arm/boot/dts/exynos5800-peach-pi.dts  | 4 +---
 7 files changed, 4 insertions(+), 18 deletions(-)

diff --git a/arch/arm/boot/dts/exynos5250-arndale.dts b/arch/arm/boot/dts/exynos5250-arndale.dts
index db3f65f..4636862 100644
--- a/arch/arm/boot/dts/exynos5250-arndale.dts
+++ b/arch/arm/boot/dts/exynos5250-arndale.dts
@@ -124,8 +124,6 @@
 &dp {
 	status = "okay";
 	samsung,color-space = <0>;
-	samsung,dynamic-range = <0>;
-	samsung,ycbcr-coeff = <0>;
 	samsung,color-depth = <1>;
 	samsung,link-rate = <0x0a>;
 	samsung,lane-count = <4>;
diff --git a/arch/arm/boot/dts/exynos5250-smdk5250.dts b/arch/arm/boot/dts/exynos5250-smdk5250.dts
index c625e71..cd424d6 100644
--- a/arch/arm/boot/dts/exynos5250-smdk5250.dts
+++ b/arch/arm/boot/dts/exynos5250-smdk5250.dts
@@ -80,8 +80,6 @@
 
 &dp {
 	samsung,color-space = <0>;
-	samsung,dynamic-range = <0>;
-	samsung,ycbcr-coeff = <0>;
 	samsung,color-depth = <1>;
 	samsung,link-rate = <0x0a>;
 	samsung,lane-count = <4>;
diff --git a/arch/arm/boot/dts/exynos5250-snow.dts b/arch/arm/boot/dts/exynos5250-snow.dts
index 0720caa..242b621 100644
--- a/arch/arm/boot/dts/exynos5250-snow.dts
+++ b/arch/arm/boot/dts/exynos5250-snow.dts
@@ -244,12 +244,10 @@
 	pinctrl-names = "default";
 	pinctrl-0 = <&dp_hpd>;
 	samsung,color-space = <0>;
-	samsung,dynamic-range = <0>;
-	samsung,ycbcr-coeff = <0>;
 	samsung,color-depth = <1>;
 	samsung,link-rate = <0x0a>;
 	samsung,lane-count = <2>;
-	samsung,hpd-gpio = <&gpx0 7 GPIO_ACTIVE_HIGH>;
+	hpd-gpios = <&gpx0 7 GPIO_ACTIVE_HIGH>;
 
 	ports {
 		port at 0 {
diff --git a/arch/arm/boot/dts/exynos5250-spring.dts b/arch/arm/boot/dts/exynos5250-spring.dts
index c1edd6d..91881d7 100644
--- a/arch/arm/boot/dts/exynos5250-spring.dts
+++ b/arch/arm/boot/dts/exynos5250-spring.dts
@@ -74,12 +74,10 @@
 	pinctrl-names = "default";
 	pinctrl-0 = <&dp_hpd_gpio>;
 	samsung,color-space = <0>;
-	samsung,dynamic-range = <0>;
-	samsung,ycbcr-coeff = <0>;
 	samsung,color-depth = <1>;
 	samsung,link-rate = <0x0a>;
 	samsung,lane-count = <1>;
-	samsung,hpd-gpio = <&gpc3 0 GPIO_ACTIVE_HIGH>;
+	hpd-gpios = <&gpc3 0 GPIO_ACTIVE_HIGH>;
 };
 
 &ehci {
diff --git a/arch/arm/boot/dts/exynos5420-peach-pit.dts b/arch/arm/boot/dts/exynos5420-peach-pit.dts
index 8f4d76c..7433683 100644
--- a/arch/arm/boot/dts/exynos5420-peach-pit.dts
+++ b/arch/arm/boot/dts/exynos5420-peach-pit.dts
@@ -148,12 +148,10 @@
 	pinctrl-names = "default";
 	pinctrl-0 = <&dp_hpd_gpio>;
 	samsung,color-space = <0>;
-	samsung,dynamic-range = <0>;
-	samsung,ycbcr-coeff = <0>;
 	samsung,color-depth = <1>;
 	samsung,link-rate = <0x06>;
 	samsung,lane-count = <2>;
-	samsung,hpd-gpio = <&gpx2 6 0>;
+	hpd-gpio = <&gpx2 6 0>;
 
 	ports {
 		port at 0 {
diff --git a/arch/arm/boot/dts/exynos5420-smdk5420.dts b/arch/arm/boot/dts/exynos5420-smdk5420.dts
index 98871f9..b3df3c1 100644
--- a/arch/arm/boot/dts/exynos5420-smdk5420.dts
+++ b/arch/arm/boot/dts/exynos5420-smdk5420.dts
@@ -92,8 +92,6 @@
 	pinctrl-names = "default";
 	pinctrl-0 = <&dp_hpd>;
 	samsung,color-space = <0>;
-	samsung,dynamic-range = <0>;
-	samsung,ycbcr-coeff = <0>;
 	samsung,color-depth = <1>;
 	samsung,link-rate = <0x0a>;
 	samsung,lane-count = <4>;
diff --git a/arch/arm/boot/dts/exynos5800-peach-pi.dts b/arch/arm/boot/dts/exynos5800-peach-pi.dts
index 7d5b386..b89bff5 100644
--- a/arch/arm/boot/dts/exynos5800-peach-pi.dts
+++ b/arch/arm/boot/dts/exynos5800-peach-pi.dts
@@ -142,12 +142,10 @@
 	pinctrl-names = "default";
 	pinctrl-0 = <&dp_hpd_gpio>;
 	samsung,color-space = <0>;
-	samsung,dynamic-range = <0>;
-	samsung,ycbcr-coeff = <0>;
 	samsung,color-depth = <1>;
 	samsung,link-rate = <0x0a>;
 	samsung,lane-count = <2>;
-	samsung,hpd-gpio = <&gpx2 6 0>;
+	hpd-gpios = <&gpx2 6 0>;
 	panel = <&panel>;
 };
 
-- 
2.1.2




From ykk at rock-chips.com  Mon Aug 31 23:01:28 2015
From: ykk at rock-chips.com (Yakir Yang)
Date: Tue,  1 Sep 2015 14:01:28 +0800
Subject: [PATCH v4 08/16] drm: rockchip/dp: add rockchip platform dp driver
In-Reply-To: <1441086371-24838-1-git-send-email-ykk@rock-chips.com>
References: <1441086371-24838-1-git-send-email-ykk@rock-chips.com>
Message-ID: <1441087288-25404-1-git-send-email-ykk@rock-chips.com>

Rockchip have three clocks for dp controller, we leave pclk_edp
to analogix_dp driver control, and keep the sclk_edp_24m and
sclk_edp in platform driver.

Signed-off-by: Yakir Yang <ykk at rock-chips.com>
---
Changes in v4:
- Remove some deprecated DT properties in rockchip dp document.

Changes in v3:
- Take Thierry Reding and Heiko suggest, leave "sclk_edp_24m" to rockchip
  dp phy driver which name to "24m", and leave "sclk_edp" to analogix dp
  core driver which name to "dp", and leave "pclk_edp" to rockchip dp platform
  driver which name to "pclk".
- Take Heiko suggest, add devicetree binding document.
- Take Heiko suggest, remove "rockchip,panel" DT property, take use of remote
  point to get panel node.
- Add the new function point analogix_dp_platdata.get_modes init.

Changes in v2:
- Take Heiko suggest, get panel node with remote-endpoint method,
  and create devicetree binding for driver.
- Remove the clock enable/disbale with "sclk_edp" & "sclk_edp_24m",
  leave those clock to rockchip dp phy driver.

 .../bindings/video/analogix_dp-rockchip.txt        |  74 ++++
 drivers/gpu/drm/rockchip/Kconfig                   |   9 +
 drivers/gpu/drm/rockchip/Makefile                  |   1 +
 drivers/gpu/drm/rockchip/analogix_dp-rockchip.c    | 389 +++++++++++++++++++++
 4 files changed, 473 insertions(+)
 create mode 100644 Documentation/devicetree/bindings/video/analogix_dp-rockchip.txt
 create mode 100644 drivers/gpu/drm/rockchip/analogix_dp-rockchip.c

diff --git a/Documentation/devicetree/bindings/video/analogix_dp-rockchip.txt b/Documentation/devicetree/bindings/video/analogix_dp-rockchip.txt
new file mode 100644
index 0000000..502483e
--- /dev/null
+++ b/Documentation/devicetree/bindings/video/analogix_dp-rockchip.txt
@@ -0,0 +1,74 @@
+Rockchip RK3288 specific extensions to the Analogix Display Port
+================================
+
+Required properties:
+- compatible: "rockchip,rk3288-edp";
+
+- reg: physical base address of the controller and length
+
+- clocks: from common clock binding: handle to dp clock.
+	  of memory mapped region.
+
+- clock-names: from common clock binding:
+	       Required elements: "dp" "pclk"
+
+- resets: Must contain an entry for each entry in reset-names.
+	  See ../reset/reset.txt for details.
+
+- reset-names: Must include the name "dp"
+
+- rockchip,grf: this soc should set GRF regs, so need get grf here.
+
+- ports: contain a port node with endpoint definitions as defined in
+  Documentation/devicetree/bindings/media/video-interfaces.txt.
+
+
+For the below properties, please refer to Analogix DP binding document:
+ * Documentation/devicetree/bindings/drm/bridge/analogix_dp.txt
+- phys (required)
+- phy-names (required)
+- hpd-gpios (optional)
+-------------------------------------------------------------------------------
+
+Example:
+	dp-controller: dp at ff970000 {
+		compatible = "rockchip,rk3288-dp";
+		reg = <0xff970000 0x4000>;
+		interrupts = <GIC_SPI 98 IRQ_TYPE_LEVEL_HIGH>;
+		clocks = <&cru SCLK_EDP>, <&cru PCLK_EDP_CTRL>;
+		clock-names = "dp", "pclk";
+		phys = <&dp_phy>;
+		phy-names = "dp";
+
+		rockchip,grf = <&grf>;
+		resets = <&cru 111>;
+		reset-names = "dp";
+
+		status = "disabled";
+
+		ports {
+			edp_in: port {
+				#address-cells = <1>;
+				#size-cells = <0>;
+				edp_in_vopb: endpoint at 0 {
+					reg = <0>;
+					remote-endpoint = <&vopb_out_edp>;
+				};
+				edp_in_vopl: endpoint at 1 {
+					reg = <1>;
+					remote-endpoint = <&vopl_out_edp>;
+				};
+			};
+
+			edp_out: port at 1 {
+				reg = <1>;
+				#address-cells = <1>;
+				#size-cells = <0>;
+				edp_out_panel: endpoint {
+					reg = <0>;
+					remote-endpoint = <&panel_in_edp>
+				};
+			};
+		};
+	};
+
diff --git a/drivers/gpu/drm/rockchip/Kconfig b/drivers/gpu/drm/rockchip/Kconfig
index 35215f6..c2ba945 100644
--- a/drivers/gpu/drm/rockchip/Kconfig
+++ b/drivers/gpu/drm/rockchip/Kconfig
@@ -25,3 +25,12 @@ config ROCKCHIP_DW_HDMI
 	  for the Synopsys DesignWare HDMI driver. If you want to
 	  enable HDMI on RK3288 based SoC, you should selet this
 	  option.
+
+config ROCKCHIP_ANALOGIX_DP
+        tristate "Rockchip specific extensions for Analogix DP driver"
+        depends on DRM_ROCKCHIP
+        select DRM_ANALOGIX_DP
+        help
+	  This selects support for Rockchip SoC specific extensions
+	  for the Analogix Core DP driver. If you want to enable DP
+	  on RK3288 based SoC, you should selet this option.
diff --git a/drivers/gpu/drm/rockchip/Makefile b/drivers/gpu/drm/rockchip/Makefile
index f3d8a19..8ad01fb 100644
--- a/drivers/gpu/drm/rockchip/Makefile
+++ b/drivers/gpu/drm/rockchip/Makefile
@@ -6,5 +6,6 @@ rockchipdrm-y := rockchip_drm_drv.o rockchip_drm_fb.o rockchip_drm_fbdev.o \
 		rockchip_drm_gem.o
 
 obj-$(CONFIG_ROCKCHIP_DW_HDMI) += dw_hdmi-rockchip.o
+obj-$(CONFIG_ROCKCHIP_ANALOGIX_DP) += analogix_dp-rockchip.o
 
 obj-$(CONFIG_DRM_ROCKCHIP) += rockchipdrm.o rockchip_drm_vop.o
diff --git a/drivers/gpu/drm/rockchip/analogix_dp-rockchip.c b/drivers/gpu/drm/rockchip/analogix_dp-rockchip.c
new file mode 100644
index 0000000..cebff9e
--- /dev/null
+++ b/drivers/gpu/drm/rockchip/analogix_dp-rockchip.c
@@ -0,0 +1,389 @@
+/*
+ * Rockchip SoC DP (Display Port) interface driver.
+ *
+ * Copyright (C) Fuzhou Rockchip Electronics Co., Ltd.
+ * Author: Andy Yan <andy.yan at rock-chips.com>
+ *         Yakir Yang <ykk at rock-chips.com>
+ *         Jeff Chen <jeff.chen at 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.
+ */
+#include <drm/drmP.h>
+#include <drm/drm_crtc_helper.h>
+#include <drm/drm_panel.h>
+#include <drm/drm_of.h>
+#include <drm/drm_dp_helper.h>
+
+#include <linux/component.h>
+#include <linux/mfd/syscon.h>
+#include <linux/of_graph.h>
+#include <linux/regmap.h>
+#include <linux/reset.h>
+#include <linux/clk.h>
+
+#include <video/of_videomode.h>
+#include <video/videomode.h>
+
+#include <drm/bridge/analogix_dp.h>
+
+#include "rockchip_drm_drv.h"
+#include "rockchip_drm_vop.h"
+
+#define encoder_to_dp(c) \
+		container_of(c, struct rockchip_dp_device, encoder)
+
+#define plat_data_to_dp(pd) \
+		container_of(pd, struct rockchip_dp_device, plat_data)
+
+/* dp grf register offset */
+#define GRF_GPIO7B_IOMUX                        0x0070
+#define GPIO7B3_SEL_MASK                        (0x03 << 6)
+#define GPIO7B3_SEL_EDP_HOTPLUG                 BIT(7)
+
+#define GRF_SOC_CON6                            0x025c
+#define GRF_EDP_LCD_SEL_MASK                    BIT(5)
+#define GRF_EDP_SEL_VOP_LIT                     BIT(5)
+#define GRF_EDP_SEL_VOP_BIG                     0
+
+struct rockchip_dp_device {
+	struct drm_device        *drm_dev;
+	struct device            *dev;
+	struct drm_encoder       encoder;
+	struct drm_display_mode  mode;
+
+	struct clk               *pclk;
+	struct regmap            *grf;
+	struct reset_control     *rst;
+
+	struct analogix_dp_plat_data plat_data;
+};
+
+static int rockchip_dp_pre_init(struct rockchip_dp_device *dp)
+{
+	u32 val;
+	int ret;
+
+	val = GPIO7B3_SEL_EDP_HOTPLUG | (GPIO7B3_SEL_MASK << 16);
+	ret = regmap_write(dp->grf, GRF_GPIO7B_IOMUX, val);
+	if (ret != 0) {
+		dev_err(dp->dev, "Could not config GRF edp hpd: %d\n", ret);
+		return ret;
+	}
+
+	reset_control_assert(dp->rst);
+	usleep_range(10, 20);
+	reset_control_deassert(dp->rst);
+
+	return 0;
+}
+
+static int rockchip_dp_poweron(struct analogix_dp_plat_data *plat_data)
+{
+	struct rockchip_dp_device *dp = plat_data_to_dp(plat_data);
+	int ret;
+
+	ret = clk_prepare_enable(dp->pclk);
+	if (ret < 0) {
+		dev_err(dp->dev, "failed to enable pclk %d\n", ret);
+		return ret;
+	}
+
+	ret = rockchip_dp_pre_init(dp);
+	if (ret < 0) {
+		dev_err(dp->dev, "failed to dp pre init %d\n", ret);
+		return ret;
+	}
+
+	return 0;
+}
+
+static int rockchip_dp_powerdown(struct analogix_dp_plat_data *plat_data)
+{
+	struct rockchip_dp_device *dp = plat_data_to_dp(plat_data);
+
+	clk_disable_unprepare(dp->pclk);
+
+	return 0;
+}
+
+static bool
+rockchip_dp_drm_encoder_mode_fixup(struct drm_encoder *encoder,
+				   const struct drm_display_mode *mode,
+				   struct drm_display_mode *adjusted_mode)
+{
+	/* do nothing */
+	return true;
+}
+
+static void rockchip_dp_drm_encoder_mode_set(struct drm_encoder *encoder,
+					     struct drm_display_mode *mode,
+					     struct drm_display_mode *adjusted)
+{
+	/* do nothing */
+}
+
+static void rockchip_dp_drm_encoder_prepare(struct drm_encoder *encoder)
+{
+	struct rockchip_dp_device *dp = encoder_to_dp(encoder);
+	u32 val;
+	int ret;
+
+	ret = rockchip_drm_crtc_mode_config(encoder->crtc,
+					    DRM_MODE_CONNECTOR_eDP,
+					    ROCKCHIP_OUT_MODE_AAAA);
+	if (ret < 0) {
+		dev_err(dp->dev, "Could not set crtc mode config: %d.\n", ret);
+		return;
+	}
+
+	ret = rockchip_drm_encoder_get_mux_id(dp->dev->of_node, encoder);
+	if (ret < 0)
+		return;
+
+	if (ret)
+		val = GRF_EDP_SEL_VOP_LIT | (GRF_EDP_LCD_SEL_MASK << 16);
+	else
+		val = GRF_EDP_SEL_VOP_BIG | (GRF_EDP_LCD_SEL_MASK << 16);
+
+	dev_dbg(dp->dev, "vop %s output to dp\n", (ret) ? "LIT" : "BIG");
+
+	ret = regmap_write(dp->grf, GRF_SOC_CON6, val);
+	if (ret != 0) {
+		dev_err(dp->dev, "Could not write to GRF: %d\n", ret);
+		return;
+	}
+}
+
+static void rockchip_dp_drm_encoder_nop(struct drm_encoder *encoder)
+{
+	/* do nothing */
+}
+
+static struct drm_encoder_helper_funcs rockchip_dp_encoder_helper_funcs = {
+	.mode_fixup = rockchip_dp_drm_encoder_mode_fixup,
+	.mode_set = rockchip_dp_drm_encoder_mode_set,
+	.prepare = rockchip_dp_drm_encoder_prepare,
+	.commit = rockchip_dp_drm_encoder_nop,
+	.disable = rockchip_dp_drm_encoder_nop,
+};
+
+static void rockchip_dp_drm_encoder_destroy(struct drm_encoder *encoder)
+{
+	drm_encoder_cleanup(encoder);
+}
+
+static struct drm_encoder_funcs rockchip_dp_encoder_funcs = {
+	.destroy = rockchip_dp_drm_encoder_destroy,
+};
+
+static int rockchip_dp_init(struct rockchip_dp_device *dp)
+{
+	struct device *dev = dp->dev;
+	struct device_node *np = dev->of_node;
+	int ret;
+
+	dp->grf = syscon_regmap_lookup_by_phandle(np, "rockchip,grf");
+	if (IS_ERR(dp->grf)) {
+		dev_err(dev, "failed to get rockchip,grf property\n");
+		return PTR_ERR(dp->grf);
+	}
+
+	dp->pclk = devm_clk_get(dev, "pclk");
+	if (IS_ERR(dp->pclk)) {
+		dev_err(dev, "failed to get pclk property\n");
+		return PTR_ERR(dp->pclk);
+	}
+
+	dp->rst = devm_reset_control_get(dev, "dp");
+	if (IS_ERR(dp->rst)) {
+		dev_err(dev, "failed to get dp reset control\n");
+		return PTR_ERR(dp->rst);
+	}
+
+	ret = clk_prepare_enable(dp->pclk);
+	if (ret < 0) {
+		dev_err(dp->dev, "failed to enable pclk %d\n", ret);
+		return ret;
+	}
+
+	ret = rockchip_dp_pre_init(dp);
+	if (ret < 0) {
+		dev_err(dp->dev, "failed to pre init %d\n", ret);
+		return ret;
+	}
+
+	return 0;
+}
+
+static int rockchip_dp_drm_create_encoder(struct rockchip_dp_device *dp)
+{
+	struct drm_encoder *encoder = &dp->encoder;
+	struct drm_device *drm_dev = dp->drm_dev;
+	struct device *dev = dp->dev;
+	int ret;
+
+	encoder->possible_crtcs = drm_of_find_possible_crtcs(drm_dev,
+							     dev->of_node);
+	DRM_DEBUG_KMS("possible_crtcs = 0x%x\n", encoder->possible_crtcs);
+
+	ret = drm_encoder_init(drm_dev, encoder, &rockchip_dp_encoder_funcs,
+			       DRM_MODE_ENCODER_TMDS);
+	if (ret) {
+		DRM_ERROR("failed to initialize encoder with drm\n");
+		return ret;
+	}
+
+	drm_encoder_helper_add(encoder, &rockchip_dp_encoder_helper_funcs);
+
+	return 0;
+}
+
+static int rockchip_dp_bind(struct device *dev, struct device *master,
+			    void *data)
+{
+	struct rockchip_dp_device *dp = dev_get_drvdata(dev);
+	struct drm_device *drm_dev = data;
+	int ret;
+
+	/*
+	 * Just like the probe function said, we don't need the
+	 * device drvrate anymore, we should leave the charge to
+	 * analogix dp driver, set the device drvdata to NULL.
+	 */
+	dev_set_drvdata(dev, NULL);
+
+	ret = rockchip_dp_init(dp);
+	if (ret < 0)
+		return ret;
+
+	dp->drm_dev = drm_dev;
+
+	ret = rockchip_dp_drm_create_encoder(dp);
+	if (ret) {
+		DRM_ERROR("failed to create drm encoder\n");
+		return ret;
+	}
+
+	dp->plat_data.attach = NULL;
+	dp->plat_data.get_modes = NULL;
+	dp->plat_data.power_on = rockchip_dp_poweron;
+	dp->plat_data.power_off = rockchip_dp_powerdown;
+
+	return analogix_dp_bind(dev, dp->drm_dev, &dp->encoder,
+				&dp->plat_data);
+}
+
+static void rockchip_dp_unbind(struct device *dev, struct device *master,
+			       void *data)
+{
+	return analogix_dp_unbind(dev, master, data);
+}
+
+static const struct component_ops rockchip_dp_component_ops = {
+	.bind = rockchip_dp_bind,
+	.unbind = rockchip_dp_unbind,
+};
+
+static int rockchip_dp_probe(struct platform_device *pdev)
+{
+	struct device *dev = &pdev->dev;
+	struct device_node *panel_node, *port, *endpoint;
+	struct rockchip_dp_device *dp;
+	struct drm_panel *panel;
+
+	port = of_graph_get_port_by_id(dev->of_node, 1);
+	if (!port) {
+		dev_err(dev, "can't find output port\n");
+		return -EINVAL;
+	}
+
+	endpoint = of_get_child_by_name(port, "endpoint");
+	of_node_put(port);
+	if (!endpoint) {
+		dev_err(dev, "no output endpoint found\n");
+		return -EINVAL;
+	}
+
+	panel_node = of_graph_get_remote_port_parent(endpoint);
+	of_node_put(endpoint);
+	if (!panel_node) {
+		dev_err(dev, "no output node found\n");
+		return -EINVAL;
+	}
+
+	panel = of_drm_find_panel(panel_node);
+	if (!panel) {
+		DRM_ERROR("failed to find panel\n");
+		of_node_put(panel_node);
+		return -EPROBE_DEFER;
+	}
+
+	of_node_put(panel_node);
+
+	dp = devm_kzalloc(dev, sizeof(*dp), GFP_KERNEL);
+	if (!dp)
+		return -ENOMEM;
+
+	dp->dev = dev;
+
+	dp->plat_data.panel = panel;
+
+	/*
+	 * We just use the drvdata until driver run into component
+	 * add function, and then we would set drvdata to null, so
+	 * that analogix dp driver could take charge of the drvdata.
+	 */
+	platform_set_drvdata(pdev, dp);
+
+	return component_add(dev, &rockchip_dp_component_ops);
+}
+
+static int rockchip_dp_remove(struct platform_device *pdev)
+{
+	component_del(&pdev->dev, &rockchip_dp_component_ops);
+
+	return 0;
+}
+
+#ifdef CONFIG_PM_SLEEP
+static int rockchip_dp_suspend(struct device *dev)
+{
+	return analogix_dp_suspend(dev);
+}
+
+static int rockchip_dp_resume(struct device *dev)
+{
+	return analogix_dp_resume(dev);
+}
+#endif
+
+static const struct dev_pm_ops rockchip_dp_pm_ops = {
+	SET_SYSTEM_SLEEP_PM_OPS(rockchip_dp_suspend, rockchip_dp_resume)
+};
+
+static const struct of_device_id rockchip_dp_dt_ids[] = {
+	{.compatible = "rockchip,rk3288-dp",},
+	{}
+};
+MODULE_DEVICE_TABLE(of, rockchip_dp_dt_ids);
+
+static struct platform_driver rockchip_dp_driver = {
+	.probe = rockchip_dp_probe,
+	.remove = rockchip_dp_remove,
+	.driver = {
+		   .name = "rockchip-dp",
+		   .owner = THIS_MODULE,
+		   .pm = &rockchip_dp_pm_ops,
+		   .of_match_table = of_match_ptr(rockchip_dp_dt_ids),
+	},
+};
+
+module_platform_driver(rockchip_dp_driver);
+
+MODULE_AUTHOR("Yakir Yang <ykk at rock-chips.com>");
+MODULE_AUTHOR("Jeff chen <jeff.chen at rock-chips.com>");
+MODULE_DESCRIPTION("Rockchip Specific Analogix-DP Driver Extension");
+MODULE_LICENSE("GPL v2");
-- 
2.1.2




From viresh.kumar at linaro.org  Mon Aug 31 23:02:36 2015
From: viresh.kumar at linaro.org (Viresh Kumar)
Date: Tue, 1 Sep 2015 11:32:36 +0530
Subject: about system time incorrect after changing cpu frequency
In-Reply-To: <CAOVJa8HNQ-s=yDfADCcoL+r22ALpHFtTjWZ=oxTkBUriYbCk+Q@mail.gmail.com>
References: <CAOVJa8GTDj3UJpgUd4nH1wknUKa6fgac=1SsqC8g=UCG0MGuDw@mail.gmail.com>
 <CAOh2x=ky8_uwqvdH-krKxgMSby5jgovJp7odK6x=MpqNL+YoGg@mail.gmail.com>
 <CAOVJa8HNQ-s=yDfADCcoL+r22ALpHFtTjWZ=oxTkBUriYbCk+Q@mail.gmail.com>
Message-ID: <20150901060236.GB1456@linux>

On 01-09-15, 13:36, vichy wrote:
> >> I try to call below 2 functions to change the frequency of clocksource
> >> and clockevent, but the above b) sleep time is still incorrect when
> >> cpu runs in 500Mhz.
> >>     clockevents_update_freq(this_cpu_ptr(gt_evt), gt_clk_rate);
> >>     __clocksource_updatefreq_hz(&gt_clocksource, gt_clk_rate);

How and when were you calling them? What kernel version is it ?

> Clock Event Device: arm_global_timer

This driver doesn't have support to update clkevt device's freq. You
may need to modify that based on how arch/arm/kernel/smp_twd.c is
updated. look for: clockevents_update_freq().

-- 
viresh


From ykk at rock-chips.com  Mon Aug 31 23:01:48 2015
From: ykk at rock-chips.com (Yakir Yang)
Date: Tue,  1 Sep 2015 14:01:48 +0800
Subject: [PATCH v4 09/16] drm: rockchip: add bpc and color mode setting
In-Reply-To: <1441086371-24838-1-git-send-email-ykk@rock-chips.com>
References: <1441086371-24838-1-git-send-email-ykk@rock-chips.com>
Message-ID: <1441087308-25455-1-git-send-email-ykk@rock-chips.com>

From: Mark Yao <yzq at rock-chips.com>

Add bpc and color mode setting in rockchip_drm_vop driver, so
connector could try to use the edid drm_display_info to config
vop output mode.

Signed-off-by: Mark Yao <yzq at rock-chips.com>
Signed-off-by: Yakir Yang <ykk at rock-chips.com>
---
Changes in v4: None
Changes in v3: None
Changes in v2: None

 drivers/gpu/drm/rockchip/analogix_dp-rockchip.c | 46 +++++++++++++++++++------
 drivers/gpu/drm/rockchip/dw_hdmi-rockchip.c     |  2 +-
 drivers/gpu/drm/rockchip/rockchip_drm_drv.h     |  2 +-
 drivers/gpu/drm/rockchip/rockchip_drm_vop.c     | 33 ++++++++++++++++--
 4 files changed, 68 insertions(+), 15 deletions(-)

diff --git a/drivers/gpu/drm/rockchip/analogix_dp-rockchip.c b/drivers/gpu/drm/rockchip/analogix_dp-rockchip.c
index cebff9e..efea045 100644
--- a/drivers/gpu/drm/rockchip/analogix_dp-rockchip.c
+++ b/drivers/gpu/drm/rockchip/analogix_dp-rockchip.c
@@ -11,11 +11,6 @@
  * Free Software Foundation; either version 2 of the License, or (at your
  * option) any later version.
  */
-#include <drm/drmP.h>
-#include <drm/drm_crtc_helper.h>
-#include <drm/drm_panel.h>
-#include <drm/drm_of.h>
-#include <drm/drm_dp_helper.h>
 
 #include <linux/component.h>
 #include <linux/mfd/syscon.h>
@@ -27,6 +22,13 @@
 #include <video/of_videomode.h>
 #include <video/videomode.h>
 
+#include <drm/drmP.h>
+#include <drm/drm_crtc.h>
+#include <drm/drm_crtc_helper.h>
+#include <drm/drm_panel.h>
+#include <drm/drm_of.h>
+#include <drm/drm_dp_helper.h>
+
 #include <drm/bridge/analogix_dp.h>
 
 #include "rockchip_drm_drv.h"
@@ -125,20 +127,44 @@ static void rockchip_dp_drm_encoder_mode_set(struct drm_encoder *encoder,
 	/* do nothing */
 }
 
+static drm_connector *rockchip_dp_get_connector(struct rockchip_dp_device *dp)
+{
+	struct drm_connector *connector;
+	struct drm_device *drm_dev = dp->drm_dev;
+
+	drm_for_each_connector(connector, drm_dev) {
+		if (connector->encoder != &dp->encoder)
+			return connector;
+	}
+
+	return NULL;
+}
+
 static void rockchip_dp_drm_encoder_prepare(struct drm_encoder *encoder)
 {
 	struct rockchip_dp_device *dp = encoder_to_dp(encoder);
+	struct drm_connector *connector;
+	int ret = 0;
 	u32 val;
-	int ret;
 
-	ret = rockchip_drm_crtc_mode_config(encoder->crtc,
-					    DRM_MODE_CONNECTOR_eDP,
-					    ROCKCHIP_OUT_MODE_AAAA);
-	if (ret < 0) {
+	connector = rockchip_dp_get_connector(dp);
+	if (!connector) {
+		DRM_ERROR("Failed to get connector by encoder[%p]\n", encoder);
+		return;
+	}
+
+	if (connector->display_info.color_formats | DRM_COLOR_FORMAT_RGB444)
+		ret = rockchip_drm_crtc_mode_config(
+			encoder->crtc, DRM_MODE_CONNECTOR_eDP,
+			connector->display_info.bpc, DRM_COLOR_FORMAT_RGB444);
+	if (!ret) {
 		dev_err(dp->dev, "Could not set crtc mode config: %d.\n", ret);
 		return;
 	}
 
+	connector->display_info.bpc = ret;
+	connector->display_info.color_formats = DRM_COLOR_FORMAT_RGB444;
+
 	ret = rockchip_drm_encoder_get_mux_id(dp->dev->of_node, encoder);
 	if (ret < 0)
 		return;
diff --git a/drivers/gpu/drm/rockchip/dw_hdmi-rockchip.c b/drivers/gpu/drm/rockchip/dw_hdmi-rockchip.c
index 80d6fc8..428a3c1 100644
--- a/drivers/gpu/drm/rockchip/dw_hdmi-rockchip.c
+++ b/drivers/gpu/drm/rockchip/dw_hdmi-rockchip.c
@@ -215,7 +215,7 @@ static void dw_hdmi_rockchip_encoder_commit(struct drm_encoder *encoder)
 static void dw_hdmi_rockchip_encoder_prepare(struct drm_encoder *encoder)
 {
 	rockchip_drm_crtc_mode_config(encoder->crtc, DRM_MODE_CONNECTOR_HDMIA,
-				      ROCKCHIP_OUT_MODE_AAAA);
+				      10, DRM_COLOR_FORMAT_RGB444);
 }
 
 static struct drm_encoder_helper_funcs dw_hdmi_rockchip_encoder_helper_funcs = {
diff --git a/drivers/gpu/drm/rockchip/rockchip_drm_drv.h b/drivers/gpu/drm/rockchip/rockchip_drm_drv.h
index dc4e5f0..ef1d7fb 100644
--- a/drivers/gpu/drm/rockchip/rockchip_drm_drv.h
+++ b/drivers/gpu/drm/rockchip/rockchip_drm_drv.h
@@ -59,7 +59,7 @@ void rockchip_unregister_crtc_funcs(struct drm_device *dev, int pipe);
 int rockchip_drm_encoder_get_mux_id(struct device_node *node,
 				    struct drm_encoder *encoder);
 int rockchip_drm_crtc_mode_config(struct drm_crtc *crtc, int connector_type,
-				  int out_mode);
+				  int bpc, int color);
 int rockchip_drm_dma_attach_device(struct drm_device *drm_dev,
 				   struct device *dev);
 void rockchip_drm_dma_detach_device(struct drm_device *drm_dev,
diff --git a/drivers/gpu/drm/rockchip/rockchip_drm_vop.c b/drivers/gpu/drm/rockchip/rockchip_drm_vop.c
index 34b78e7..5d7f9b6 100644
--- a/drivers/gpu/drm/rockchip/rockchip_drm_vop.c
+++ b/drivers/gpu/drm/rockchip/rockchip_drm_vop.c
@@ -811,14 +811,41 @@ static const struct drm_plane_funcs vop_plane_funcs = {
 
 int rockchip_drm_crtc_mode_config(struct drm_crtc *crtc,
 				  int connector_type,
-				  int out_mode)
+				  int bpc, int color)
 {
 	struct vop *vop = to_vop(crtc);
-
 	vop->connector_type = connector_type;
 	vop->connector_out_mode = out_mode;
 
-	return 0;
+	/*
+	 * RK3288 vop only support RGB Color output.
+	 */
+	if (color != DRM_COLOR_FORMAT_RGB444) {
+		DRM_ERROR("Only support output RGB444, not support%d\n",
+			  color);
+		return -EINVAL;
+	}
+
+	/*
+	 * Fixme: I don't know how to describe the ROCKCHIP_OUT_MODE_P565's
+	 * bpc, 5 or 6?
+	 *
+	 */
+	if (bpc >= 10) {
+		bpc = 10;
+		vop->connector_out_mode = ROCKCHIP_OUT_MODE_AAAA;
+	} else if (bpc >= 8) {
+		bpc = 8;
+		vop->connector_out_mode = ROCKCHIP_OUT_MODE_P888;
+	} else if (bpc >= 6) {
+		bpc = 6;
+		vop->connector_out_mode = ROCKCHIP_OUT_MODE_P888;
+	} else {
+		DRM_ERROR("unsupport bpc %d\n", bpc);
+		return -EINVAL;
+	}
+
+	return bpc;
 }
 EXPORT_SYMBOL_GPL(rockchip_drm_crtc_mode_config);
 
-- 
2.1.2




From ykk at rock-chips.com  Mon Aug 31 23:04:15 2015
From: ykk at rock-chips.com (Yakir Yang)
Date: Tue,  1 Sep 2015 14:04:15 +0800
Subject: [PATCH v4 10/16] phy: Add driver for rockchip Display Port PHY
In-Reply-To: <1441086371-24838-1-git-send-email-ykk@rock-chips.com>
References: <1441086371-24838-1-git-send-email-ykk@rock-chips.com>
Message-ID: <1441087455-25533-1-git-send-email-ykk@rock-chips.com>

This phy driver would control the Rockchip DisplayPort module
phy clock and phy power, it is relate to analogix_dp-rockchip
dp driver. If you want DP works rightly on rockchip platform,
then you should select both of them.

Signed-off-by: Yakir Yang <ykk at rock-chips.com>
---
Changes in v4:
- Take Kishon suggest, add commit message, and remove the redundant
  rockchip_dp_phy_init() function, move those code to probe() method.
  And remove driver .owner number.

Changes in v3:
- Take Heiko suggest, add rockchip dp phy driver,
  collect the phy clocks and power control.

Changes in v2: None

 .../devicetree/bindings/phy/rockchip-dp-phy.txt    |  26 ++++
 drivers/phy/Kconfig                                |   7 +
 drivers/phy/Makefile                               |   1 +
 drivers/phy/phy-rockchip-dp.c                      | 166 +++++++++++++++++++++
 4 files changed, 200 insertions(+)
 create mode 100644 Documentation/devicetree/bindings/phy/rockchip-dp-phy.txt
 create mode 100644 drivers/phy/phy-rockchip-dp.c

diff --git a/Documentation/devicetree/bindings/phy/rockchip-dp-phy.txt b/Documentation/devicetree/bindings/phy/rockchip-dp-phy.txt
new file mode 100644
index 0000000..5de1088
--- /dev/null
+++ b/Documentation/devicetree/bindings/phy/rockchip-dp-phy.txt
@@ -0,0 +1,26 @@
+Rockchip Soc Seroes Display Port PHY
+------------------------------------
+
+Required properties:
+- compatible : should be one of the following supported values:
+	 - "rockchip.rk3288-dp-phy"
+
+- reg : a list of registers used by phy driver
+- clocks: from common clock binding: handle to dp clock.
+	of memory mapped region.
+- clock-names: from common clock binding:
+	Required elements: "sclk_dp" "sclk_dp_24m"
+
+- rockchip,grf: this soc should set GRF regs, so need get grf here.
+- #phy-cells : from the generic PHY bindings, must be 0;
+
+Example:
+
+edp_phy: phy at ff770274 {
+	compatilble = "rockchip,rk3288-dp-phy";
+	reg = <0xff770274 4>;
+	rockchip,grf = <&grf>;
+	clocks = <&cru SCLK_EDP_24M>;
+	clock-names = "24m";
+	#phy-cells = <0>;
+}
diff --git a/drivers/phy/Kconfig b/drivers/phy/Kconfig
index 47da573..8f2bc4f 100644
--- a/drivers/phy/Kconfig
+++ b/drivers/phy/Kconfig
@@ -310,6 +310,13 @@ config PHY_ROCKCHIP_USB
 	help
 	  Enable this to support the Rockchip USB 2.0 PHY.
 
+config PHY_ROCKCHIP_DP
+	tristate "Rockchip Display Port PHY Driver"
+	depends on ARCH_ROCKCHIP && OF
+	select GENERIC_PHY
+	help
+	  Enable this to support the Rockchip Display Port PHY.
+
 config PHY_ST_SPEAR1310_MIPHY
 	tristate "ST SPEAR1310-MIPHY driver"
 	select GENERIC_PHY
diff --git a/drivers/phy/Makefile b/drivers/phy/Makefile
index a5b18c1..e281f35 100644
--- a/drivers/phy/Makefile
+++ b/drivers/phy/Makefile
@@ -34,6 +34,7 @@ phy-exynos-usb2-$(CONFIG_PHY_S5PV210_USB2)	+= phy-s5pv210-usb2.o
 obj-$(CONFIG_PHY_EXYNOS5_USBDRD)	+= phy-exynos5-usbdrd.o
 obj-$(CONFIG_PHY_QCOM_APQ8064_SATA)	+= phy-qcom-apq8064-sata.o
 obj-$(CONFIG_PHY_ROCKCHIP_USB) += phy-rockchip-usb.o
+obj-$(CONFIG_PHY_ROCKCHIP_DP)		+= phy-rockchip-dp.o
 obj-$(CONFIG_PHY_QCOM_IPQ806X_SATA)	+= phy-qcom-ipq806x-sata.o
 obj-$(CONFIG_PHY_ST_SPEAR1310_MIPHY)	+= phy-spear1310-miphy.o
 obj-$(CONFIG_PHY_ST_SPEAR1340_MIPHY)	+= phy-spear1340-miphy.o
diff --git a/drivers/phy/phy-rockchip-dp.c b/drivers/phy/phy-rockchip-dp.c
new file mode 100644
index 0000000..e9a726e
--- /dev/null
+++ b/drivers/phy/phy-rockchip-dp.c
@@ -0,0 +1,166 @@
+/*
+ * Rockchip DP PHY driver
+ *
+ * Copyright (C) 2015 FuZhou Rockchip Co., Ltd.
+ * Author: Yakir Yang <ykk@@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.
+ */
+
+#include <linux/io.h>
+#include <linux/kernel.h>
+#include <linux/module.h>
+#include <linux/of.h>
+#include <linux/of_address.h>
+#include <linux/clk.h>
+#include <linux/phy/phy.h>
+#include <linux/regmap.h>
+#include <linux/mfd/syscon.h>
+#include <linux/platform_device.h>
+
+#define GRF_SOC_CON12                   0x0274
+#define GRF_EDP_REF_CLK_SEL_INTER       BIT(4)
+
+#define DP_PHY_SIDDQ_WRITE_EN           BIT(21)
+#define DP_PHY_SIDDQ_ON                 0
+#define DP_PHY_SIDDQ_OFF                BIT(5)
+
+struct rockchip_dp_phy {
+	struct device  *dev;
+	struct regmap  *grf;
+	void __iomem   *regs;
+	struct clk     *phy_24m;
+};
+
+static int rockchip_dp_phy_clk_enable(struct rockchip_dp_phy *dp)
+{
+	int ret = 0;
+
+	ret = clk_set_rate(dp->phy_24m, 24000000);
+	if (ret < 0) {
+		dev_err(dp->dev, "cannot set clock phy_24m %d\n", ret);
+		return ret;
+	}
+
+	ret = clk_prepare_enable(dp->phy_24m);
+	if (ret < 0) {
+		dev_err(dp->dev, "cannot enable clock phy_24m %d\n", ret);
+		return ret;
+	}
+
+	return 0;
+}
+
+static int rockchip_dp_phy_clk_disable(struct rockchip_dp_phy *dp)
+{
+	clk_disable_unprepare(dp->phy_24m);
+
+	return 0;
+}
+
+static int rockchip_set_phy_state(struct phy *phy, bool enable)
+{
+	struct rockchip_dp_phy *dp = phy_get_drvdata(phy);
+
+	if (enable) {
+		rockchip_dp_phy_clk_enable(dp);
+		writel(DP_PHY_SIDDQ_WRITE_EN | DP_PHY_SIDDQ_ON, dp->regs);
+	} else {
+		rockchip_dp_phy_clk_disable(dp);
+		writel(DP_PHY_SIDDQ_WRITE_EN | DP_PHY_SIDDQ_OFF, dp->regs);
+	}
+
+	return 0;
+}
+
+static int rockchip_dp_phy_power_on(struct phy *phy)
+{
+	return rockchip_set_phy_state(phy, true);
+}
+
+static int rockchip_dp_phy_power_off(struct phy *phy)
+{
+	return rockchip_set_phy_state(phy, false);
+}
+
+static struct phy_ops rockchip_dp_phy_ops = {
+	.power_on	= rockchip_dp_phy_power_on,
+	.power_off	= rockchip_dp_phy_power_off,
+	.owner		= THIS_MODULE,
+};
+
+static int rockchip_dp_phy_probe(struct platform_device *pdev)
+{
+	struct device *dev = &pdev->dev;
+	struct device_node *np = dev->of_node;
+	struct phy_provider *phy_provider;
+	struct rockchip_dp_phy *dp;
+	struct resource *res;
+	struct phy *phy;
+	int ret;
+
+	dp = devm_kzalloc(dev, sizeof(*dp), GFP_KERNEL);
+	if (IS_ERR(dp))
+		return -ENOMEM;
+
+	dp->dev = dev;
+
+	res = platform_get_resource(pdev, IORESOURCE_MEM, 0);
+	dp->regs = devm_ioremap_resource(dev, res);
+	if (IS_ERR(dp->regs))
+		return PTR_ERR(dp->regs);
+
+	dp->phy_24m = devm_clk_get(dev, "24m");
+	if (IS_ERR(dp->phy_24m)) {
+		dev_err(dev, "cannot get clock 24m\n");
+		return PTR_ERR(dp->phy_24m);
+	}
+
+	dp->grf = syscon_regmap_lookup_by_phandle(np, "rockchip,grf");
+	if (IS_ERR(dp->grf)) {
+		dev_err(dev, "rk3288-dp needs rockchip,grf property\n");
+		return PTR_ERR(dp->grf);
+	}
+
+	ret = regmap_write(dp->grf, GRF_SOC_CON12,
+			   GRF_EDP_REF_CLK_SEL_INTER |
+			   (GRF_EDP_REF_CLK_SEL_INTER << 16));
+	if (ret != 0) {
+		dev_err(dp->dev, "Could not config GRF edp ref clk: %d\n", ret);
+		return ret;
+	}
+
+	phy = devm_phy_create(dev, NULL, &rockchip_dp_phy_ops, NULL);
+	if (IS_ERR(phy)) {
+		dev_err(dev, "failed to create phy\n");
+		return PTR_ERR(phy);
+	}
+	phy_set_drvdata(phy, dp);
+
+	phy_provider = devm_of_phy_provider_register(dev, of_phy_simple_xlate);
+
+	return PTR_ERR_OR_ZERO(phy_provider);
+}
+
+static const struct of_device_id rockchip_dp_phy_dt_ids[] = {
+	{ .compatible = "rockchip,rk3288-dp-phy" },
+	{}
+};
+
+MODULE_DEVICE_TABLE(of, rockchip_dp_phy_dt_ids);
+
+static struct platform_driver rockchip_dp_phy_driver = {
+	.probe		= rockchip_dp_phy_probe,
+	.driver		= {
+		.name	= "rockchip-dp-phy",
+		.of_match_table = rockchip_dp_phy_dt_ids,
+	},
+};
+
+module_platform_driver(rockchip_dp_phy_driver);
+
+MODULE_AUTHOR("Yakir Yang <ykk at rock-chips.com>");
+MODULE_DESCRIPTION("Rockchip DP PHY driver");
+MODULE_LICENSE("GPL v2");
-- 
2.1.2




From ykk at rock-chips.com  Mon Aug 31 23:07:00 2015
From: ykk at rock-chips.com (Yakir Yang)
Date: Tue,  1 Sep 2015 14:07:00 +0800
Subject: [PATCH v4 11/16] drm: bridge: analogix/dp: add platform device type
 support
In-Reply-To: <1441086371-24838-1-git-send-email-ykk@rock-chips.com>
References: <1441086371-24838-1-git-send-email-ykk@rock-chips.com>
Message-ID: <1441087620-25586-1-git-send-email-ykk@rock-chips.com>

Signed-off-by: Yakir Yang <ykk at rock-chips.com>
---
Changes in v4: None
Changes in v3: None
Changes in v2:
- Add GNU license v2 declared and samsung copyright

 drivers/gpu/drm/exynos/exynos_dp.c              |  1 +
 drivers/gpu/drm/rockchip/analogix_dp-rockchip.c |  1 +
 include/drm/bridge/analogix_dp.h                | 16 ++++++++++++++++
 3 files changed, 18 insertions(+)

diff --git a/drivers/gpu/drm/exynos/exynos_dp.c b/drivers/gpu/drm/exynos/exynos_dp.c
index 6060d2c..40ef727 100644
--- a/drivers/gpu/drm/exynos/exynos_dp.c
+++ b/drivers/gpu/drm/exynos/exynos_dp.c
@@ -224,6 +224,7 @@ static int exynos_dp_bind(struct device *dev, struct device *master, void *data)
 	dp->dev = dev;
 	dp->drm_dev = drm_dev;
 
+	dp->plat_data.dev_type = EXYNOS_DP;
 	dp->plat_data.power_on = exynos_dp_poweron;
 	dp->plat_data.power_off = exynos_dp_poweroff;
 	dp->plat_data.get_modes = exynos_dp_get_modes;
diff --git a/drivers/gpu/drm/rockchip/analogix_dp-rockchip.c b/drivers/gpu/drm/rockchip/analogix_dp-rockchip.c
index efea045..4934271 100644
--- a/drivers/gpu/drm/rockchip/analogix_dp-rockchip.c
+++ b/drivers/gpu/drm/rockchip/analogix_dp-rockchip.c
@@ -293,6 +293,7 @@ static int rockchip_dp_bind(struct device *dev, struct device *master,
 		return ret;
 	}
 
+	dp->plat_data.dev_type = RK3288_DP;
 	dp->plat_data.attach = NULL;
 	dp->plat_data.get_modes = NULL;
 	dp->plat_data.power_on = rockchip_dp_poweron;
diff --git a/include/drm/bridge/analogix_dp.h b/include/drm/bridge/analogix_dp.h
index 8b4ffad..7209a64 100644
--- a/include/drm/bridge/analogix_dp.h
+++ b/include/drm/bridge/analogix_dp.h
@@ -1,9 +1,25 @@
+/*
+ * Analogix Core DP (Display Port) interface driver.
+ *
+ * Copyright (C) 2012 Samsung Electronics Co., Ltd.
+ *
+ * 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.
+ */
 #ifndef _ANALOGIX_DP_H_
 #define _ANALOGIX_DP_H_
 
 #include <drm/drm_crtc.h>
 
+enum analogix_dp_devtype {
+	EXYNOS_DP,
+	RK3288_DP,
+};
+
 struct analogix_dp_plat_data {
+	enum analogix_dp_devtype dev_type;
 	struct drm_panel *panel;
 
 	int (*power_on)(struct analogix_dp_plat_data *);
-- 
2.1.2




From ykk at rock-chips.com  Mon Aug 31 23:09:17 2015
From: ykk at rock-chips.com (Yakir Yang)
Date: Tue,  1 Sep 2015 14:09:17 +0800
Subject: [PATCH v4 12/16] drm: bridge: analogix/dp: add some rk3288 special
 registers setting
In-Reply-To: <1441086371-24838-1-git-send-email-ykk@rock-chips.com>
References: <1441086371-24838-1-git-send-email-ykk@rock-chips.com>
Message-ID: <1441087757-25642-1-git-send-email-ykk@rock-chips.com>

RK3288 need some special registers setting, we can separate
them out by the dev_type of plat_data.

Signed-off-by: Yakir Yang <ykk at rock-chips.com>
---
Changes in v4: None
Changes in v3: None
Changes in v2:
- Fix compile failed dut to phy_pd_addr variable misspell error

 drivers/gpu/drm/bridge/analogix/analogix_dp_reg.c | 76 ++++++++++++++---------
 drivers/gpu/drm/bridge/analogix/analogix_dp_reg.h | 12 ++++
 2 files changed, 60 insertions(+), 28 deletions(-)

diff --git a/drivers/gpu/drm/bridge/analogix/analogix_dp_reg.c b/drivers/gpu/drm/bridge/analogix/analogix_dp_reg.c
index 6a643be..15346fe 100644
--- a/drivers/gpu/drm/bridge/analogix/analogix_dp_reg.c
+++ b/drivers/gpu/drm/bridge/analogix/analogix_dp_reg.c
@@ -15,6 +15,8 @@
 #include <linux/delay.h>
 #include <linux/gpio.h>
 
+#include <drm/bridge/analogix_dp.h>
+
 #include "analogix_dp_core.h"
 #include "analogix_dp_reg.h"
 
@@ -72,6 +74,14 @@ void analogix_dp_init_analog_param(struct analogix_dp_device *dp)
 	reg = SEL_24M | TX_DVDD_BIT_1_0625V;
 	writel(reg, dp->reg_base + ANALOGIX_DP_ANALOG_CTL_2);
 
+	if (dp->plat_data && (dp->plat_data->dev_type == RK3288_DP)) {
+		writel(REF_CLK_24M, dp->reg_base + ANALOGIX_DP_PLL_REG_1);
+		writel(0x95, dp->reg_base + ANALOGIX_DP_PLL_REG_2);
+		writel(0x40, dp->reg_base + ANALOGIX_DP_PLL_REG_3);
+		writel(0x58, dp->reg_base + ANALOGIX_DP_PLL_REG_4);
+		writel(0x22, dp->reg_base + ANALOGIX_DP_PLL_REG_5);
+	}
+
 	reg = DRIVE_DVDD_BIT_1_0625V | VCO_BIT_600_MICRO;
 	writel(reg, dp->reg_base + ANALOGIX_DP_ANALOG_CTL_3);
 
@@ -206,81 +216,85 @@ void analogix_dp_set_analog_power_down(struct analogix_dp_device *dp,
 				       bool enable)
 {
 	u32 reg;
+	u32 phy_pd_addr = ANALOGIX_DP_PHY_PD;
+
+	if (dp->plat_data && (dp->plat_data->dev_type == RK3288_DP))
+		phy_pd_addr = ANALOGIX_DP_PD;
 
 	switch (block) {
 	case AUX_BLOCK:
 		if (enable) {
-			reg = readl(dp->reg_base + ANALOGIX_DP_PHY_PD);
+			reg = readl(dp->reg_base + phy_pd_addr);
 			reg |= AUX_PD;
-			writel(reg, dp->reg_base + ANALOGIX_DP_PHY_PD);
+			writel(reg, dp->reg_base + phy_pd_addr);
 		} else {
-			reg = readl(dp->reg_base + ANALOGIX_DP_PHY_PD);
+			reg = readl(dp->reg_base + phy_pd_addr);
 			reg &= ~AUX_PD;
-			writel(reg, dp->reg_base + ANALOGIX_DP_PHY_PD);
+			writel(reg, dp->reg_base + phy_pd_addr);
 		}
 		break;
 	case CH0_BLOCK:
 		if (enable) {
-			reg = readl(dp->reg_base + ANALOGIX_DP_PHY_PD);
+			reg = readl(dp->reg_base + phy_pd_addr);
 			reg |= CH0_PD;
-			writel(reg, dp->reg_base + ANALOGIX_DP_PHY_PD);
+			writel(reg, dp->reg_base + phy_pd_addr);
 		} else {
-			reg = readl(dp->reg_base + ANALOGIX_DP_PHY_PD);
+			reg = readl(dp->reg_base + phy_pd_addr);
 			reg &= ~CH0_PD;
-			writel(reg, dp->reg_base + ANALOGIX_DP_PHY_PD);
+			writel(reg, dp->reg_base + phy_pd_addr);
 		}
 		break;
 	case CH1_BLOCK:
 		if (enable) {
-			reg = readl(dp->reg_base + ANALOGIX_DP_PHY_PD);
+			reg = readl(dp->reg_base + phy_pd_addr);
 			reg |= CH1_PD;
-			writel(reg, dp->reg_base + ANALOGIX_DP_PHY_PD);
+			writel(reg, dp->reg_base + phy_pd_addr);
 		} else {
-			reg = readl(dp->reg_base + ANALOGIX_DP_PHY_PD);
+			reg = readl(dp->reg_base + phy_pd_addr);
 			reg &= ~CH1_PD;
-			writel(reg, dp->reg_base + ANALOGIX_DP_PHY_PD);
+			writel(reg, dp->reg_base + phy_pd_addr);
 		}
 		break;
 	case CH2_BLOCK:
 		if (enable) {
-			reg = readl(dp->reg_base + ANALOGIX_DP_PHY_PD);
+			reg = readl(dp->reg_base + phy_pd_addr);
 			reg |= CH2_PD;
-			writel(reg, dp->reg_base + ANALOGIX_DP_PHY_PD);
+			writel(reg, dp->reg_base + phy_pd_addr);
 		} else {
-			reg = readl(dp->reg_base + ANALOGIX_DP_PHY_PD);
+			reg = readl(dp->reg_base + phy_pd_addr);
 			reg &= ~CH2_PD;
-			writel(reg, dp->reg_base + ANALOGIX_DP_PHY_PD);
+			writel(reg, dp->reg_base + phy_pd_addr);
 		}
 		break;
 	case CH3_BLOCK:
 		if (enable) {
-			reg = readl(dp->reg_base + ANALOGIX_DP_PHY_PD);
+			reg = readl(dp->reg_base + phy_pd_addr);
 			reg |= CH3_PD;
-			writel(reg, dp->reg_base + ANALOGIX_DP_PHY_PD);
+			writel(reg, dp->reg_base + phy_pd_addr);
 		} else {
-			reg = readl(dp->reg_base + ANALOGIX_DP_PHY_PD);
+			reg = readl(dp->reg_base + phy_pd_addr);
 			reg &= ~CH3_PD;
-			writel(reg, dp->reg_base + ANALOGIX_DP_PHY_PD);
+			writel(reg, dp->reg_base + phy_pd_addr);
 		}
 		break;
 	case ANALOG_TOTAL:
 		if (enable) {
-			reg = readl(dp->reg_base + ANALOGIX_DP_PHY_PD);
+			reg = readl(dp->reg_base + phy_pd_addr);
 			reg |= DP_PHY_PD;
-			writel(reg, dp->reg_base + ANALOGIX_DP_PHY_PD);
+			writel(reg, dp->reg_base + phy_pd_addr);
 		} else {
-			reg = readl(dp->reg_base + ANALOGIX_DP_PHY_PD);
+			reg = readl(dp->reg_base + phy_pd_addr);
 			reg &= ~DP_PHY_PD;
-			writel(reg, dp->reg_base + ANALOGIX_DP_PHY_PD);
+			writel(reg, dp->reg_base + phy_pd_addr);
 		}
 		break;
 	case POWER_ALL:
 		if (enable) {
 			reg = DP_PHY_PD | AUX_PD | CH3_PD | CH2_PD |
 				CH1_PD | CH0_PD;
-			writel(reg, dp->reg_base + ANALOGIX_DP_PHY_PD);
+			writel(reg, dp->reg_base + phy_pd_addr);
 		} else {
-			writel(0x00, dp->reg_base + ANALOGIX_DP_PHY_PD);
+			writel(0x00, dp->reg_base + phy_pd_addr);
 		}
 		break;
 	default:
@@ -399,8 +413,14 @@ void analogix_dp_init_aux(struct analogix_dp_device *dp)
 	analogix_dp_reset_aux(dp);
 
 	/* Disable AUX transaction H/W retry */
-	reg = AUX_BIT_PERIOD_EXPECTED_DELAY(3) | AUX_HW_RETRY_COUNT_SEL(0) |
-	      AUX_HW_RETRY_INTERVAL_600_MICROSECONDS;
+	if (dp->plat_data && (dp->plat_data->dev_type == RK3288_DP))
+		reg = AUX_BIT_PERIOD_EXPECTED_DELAY(0) |
+		      AUX_HW_RETRY_COUNT_SEL(3) |
+		      AUX_HW_RETRY_INTERVAL_600_MICROSECONDS;
+	else
+		reg = AUX_BIT_PERIOD_EXPECTED_DELAY(3) |
+		      AUX_HW_RETRY_COUNT_SEL(0) |
+		      AUX_HW_RETRY_INTERVAL_600_MICROSECONDS;
 	writel(reg, dp->reg_base + ANALOGIX_DP_AUX_HW_RETRY_CTL);
 
 	/* Receive AUX Channel DEFER commands equal to DEFFER_COUNT*64 */
diff --git a/drivers/gpu/drm/bridge/analogix/analogix_dp_reg.h b/drivers/gpu/drm/bridge/analogix/analogix_dp_reg.h
index 2d878fd..21330aa 100644
--- a/drivers/gpu/drm/bridge/analogix/analogix_dp_reg.h
+++ b/drivers/gpu/drm/bridge/analogix/analogix_dp_reg.h
@@ -22,6 +22,14 @@
 #define ANALOGIX_DP_VIDEO_CTL_8			0x3C
 #define ANALOGIX_DP_VIDEO_CTL_10			0x44
 
+#define ANALOGIX_DP_PLL_REG_1			0xfc
+#define ANALOGIX_DP_PLL_REG_2			0x9e4
+#define ANALOGIX_DP_PLL_REG_3			0x9e8
+#define ANALOGIX_DP_PLL_REG_4			0x9ec
+#define ANALOGIX_DP_PLL_REG_5			0xa00
+
+#define ANALOGIX_DP_PD                          0x12c
+
 #define ANALOGIX_DP_LANE_MAP			0x35C
 
 #define ANALOGIX_DP_ANALOG_CTL_1			0x370
@@ -154,6 +162,10 @@
 #define VSYNC_POLARITY_CFG			(0x1 << 1)
 #define HSYNC_POLARITY_CFG			(0x1 << 0)
 
+/* ANALOGIX_DP_PLL_REG_1 */
+#define REF_CLK_24M				(0x1 << 1)
+#define REF_CLK_27M				(0x0 << 1)
+
 /* ANALOGIX_DP_LANE_MAP */
 #define LANE3_MAP_LOGIC_LANE_0			(0x0 << 6)
 #define LANE3_MAP_LOGIC_LANE_1			(0x1 << 6)
-- 
2.1.2




From ykk at rock-chips.com  Mon Aug 31 23:11:30 2015
From: ykk at rock-chips.com (Yakir Yang)
Date: Tue,  1 Sep 2015 14:11:30 +0800
Subject: [PATCH v4 13/16] drm: bridge: analogix/dp: add max link rate and lane
 count limit for RK3288
In-Reply-To: <1441086371-24838-1-git-send-email-ykk@rock-chips.com>
References: <1441086371-24838-1-git-send-email-ykk@rock-chips.com>
Message-ID: <1441087890-25722-1-git-send-email-ykk@rock-chips.com>

There are some IP limit on rk3288 that only support 4 physical lanes
of 2.7/1.6 Gbps/lane, so seprate them out by device_type flag.

Signed-off-by: Yakir Yang <ykk at rock-chips.com>
---
Changes in v4:
- Take Thierry suggest, seprate the link-rate and lane-count limit
  out with the device_type flag.

Changes in v3: None
Changes in v2: None

 drivers/gpu/drm/bridge/analogix/analogix_dp_core.c | 35 ++++++++++++++--------
 drivers/gpu/drm/bridge/analogix/analogix_dp_core.h |  4 +--
 2 files changed, 24 insertions(+), 15 deletions(-)

diff --git a/drivers/gpu/drm/bridge/analogix/analogix_dp_core.c b/drivers/gpu/drm/bridge/analogix/analogix_dp_core.c
index f0db92e..f7227ec 100644
--- a/drivers/gpu/drm/bridge/analogix/analogix_dp_core.c
+++ b/drivers/gpu/drm/bridge/analogix/analogix_dp_core.c
@@ -897,8 +897,8 @@ static void analogix_dp_commit(struct analogix_dp_device *dp)
 		return;
 	}
 
-	ret = analogix_dp_set_link_train(dp, dp->video_info.lane_count,
-					 dp->video_info.link_rate);
+	ret = analogix_dp_set_link_train(dp, dp->video_info.max_lane_count,
+					 dp->video_info.max_link_rate);
 	if (ret) {
 		dev_err(dp->dev, "unable to do link train\n");
 		return;
@@ -1201,18 +1201,27 @@ static int analogix_dp_create_bridge(struct drm_device *drm_dev,
 static int analogix_dp_dt_parse_pdata(struct analogix_dp_device *dp)
 {
 	struct device_node *dp_node = dp->dev->of_node;
-	struct video_info *video_config = &dp->video_info;
-
-	if (of_property_read_u32(dp_node, "samsung,link-rate",
-				 &video_info->link_rate)) {
-		dev_err(dev, "failed to get link-rate\n");
-		return -EINVAL;
-	}
+	struct video_info *video_info = &dp->video_info;
 
-	if (of_property_read_u32(dp_node, "samsung,lane-count",
-				 &video_info->lane_count)) {
-		dev_err(dev, "failed to get lane-count\n");
-		return -EINVAL;
+	switch (dp->plat_data && dp->plat_data->dev_type) {
+	case RK3288_DP:
+		/*
+		 * Like Rk3288 DisplayPort TRM indicate that "Main link
+		 * containing 4 physical lanes of 2.7/1.62 Gbps/lane".
+		 */
+		video_info->max_link_rate = 0x0A;
+		video_info->max_lane_count = 0x04;
+		break;
+	case EXYNOS_DP:
+		/*
+		 * NOTE: those property parseing code is used for
+		 * providing backward compatibility for samsung platform.
+		 */
+		of_property_read_u32(dp_node, "samsung,link-rate",
+				     &video_info->max_link_rate);
+		of_property_read_u32(dp_node, "samsung,lane-count",
+				     &video_info->max_lane_count);
+		break;
 	}
 
 	return 0;
diff --git a/drivers/gpu/drm/bridge/analogix/analogix_dp_core.h b/drivers/gpu/drm/bridge/analogix/analogix_dp_core.h
index 6e3d5bc..d8945e2 100644
--- a/drivers/gpu/drm/bridge/analogix/analogix_dp_core.h
+++ b/drivers/gpu/drm/bridge/analogix/analogix_dp_core.h
@@ -129,8 +129,8 @@ struct video_info {
 	enum color_coefficient ycbcr_coeff;
 	enum color_depth color_depth;
 
-	enum link_rate_type link_rate;
-	enum link_lane_count_type lane_count;
+	enum link_rate_type max_link_rate;
+	enum link_lane_count_type max_lane_count;
 };
 
 struct link_train {
-- 
2.1.2




From ykk at rock-chips.com  Mon Aug 31 23:14:39 2015
From: ykk at rock-chips.com (Yakir Yang)
Date: Tue,  1 Sep 2015 14:14:39 +0800
Subject: [PATCH v4 14/16] drm: bridge: analogix/dp: try force hpd after plug
 in lookup failed
In-Reply-To: <1441086371-24838-1-git-send-email-ykk@rock-chips.com>
References: <1441086371-24838-1-git-send-email-ykk@rock-chips.com>
Message-ID: <1441088079-25809-1-git-send-email-ykk@rock-chips.com>

Some edp screen do not have hpd signal, so we can't just return
failed when hpd plug in detect failed.

This is an hardware property, so we need add a devicetree property
"analogix,need-force-hpd" to indicate this sutiation.

Signed-off-by: Yakir Yang <ykk at rock-chips.com>
---
Changes in v4: None
Changes in v3:
- Add "analogix,need-force-hpd" to indicate whether driver need foce
  hpd when hpd detect failed.

Changes in v2: None

 .../devicetree/bindings/drm/bridge/analogix_dp.txt |  4 ++-
 .../bindings/video/analogix_dp-rockchip.txt        |  1 +
 .../devicetree/bindings/video/exynos_dp.txt        |  1 +
 drivers/gpu/drm/bridge/analogix/analogix_dp_core.c | 36 +++++++++++++++++++---
 drivers/gpu/drm/bridge/analogix/analogix_dp_core.h |  2 ++
 drivers/gpu/drm/bridge/analogix/analogix_dp_reg.c  |  9 ++++++
 6 files changed, 47 insertions(+), 6 deletions(-)

diff --git a/Documentation/devicetree/bindings/drm/bridge/analogix_dp.txt b/Documentation/devicetree/bindings/drm/bridge/analogix_dp.txt
index f54dc3e..c310367 100644
--- a/Documentation/devicetree/bindings/drm/bridge/analogix_dp.txt
+++ b/Documentation/devicetree/bindings/drm/bridge/analogix_dp.txt
@@ -22,6 +22,9 @@ Required properties for dp-controller:
 		from general PHY binding: Should be "dp".
 
 Optional properties for dp-controller:
+	-analogix,need-force-hpd:
+		Indicate driver need force hpd when hpd detect failed, this
+		is used for some eDP screen which don't have hpd signal.
 	-hpd-gpios:
 		Hotplug detect GPIO.
 		Indicates which GPIO should be used for hotplug detection
@@ -31,7 +34,6 @@ Optional properties for dp-controller:
 		* Documentation/devicetree/bindings/video/exynos_dp.txt
 		* Documentation/devicetree/bindings/video/analogix_dp-rockchip.txt
 
-
 [1]: Documentation/devicetree/bindings/media/video-interfaces.txt
 -------------------------------------------------------------------------------
 
diff --git a/Documentation/devicetree/bindings/video/analogix_dp-rockchip.txt b/Documentation/devicetree/bindings/video/analogix_dp-rockchip.txt
index 502483e..8b9ed7d 100644
--- a/Documentation/devicetree/bindings/video/analogix_dp-rockchip.txt
+++ b/Documentation/devicetree/bindings/video/analogix_dp-rockchip.txt
@@ -28,6 +28,7 @@ For the below properties, please refer to Analogix DP binding document:
 - phys (required)
 - phy-names (required)
 - hpd-gpios (optional)
+- analogix,need-force-hpd (optional)
 -------------------------------------------------------------------------------
 
 Example:
diff --git a/Documentation/devicetree/bindings/video/exynos_dp.txt b/Documentation/devicetree/bindings/video/exynos_dp.txt
index ea03b3a..4f06e80 100644
--- a/Documentation/devicetree/bindings/video/exynos_dp.txt
+++ b/Documentation/devicetree/bindings/video/exynos_dp.txt
@@ -41,6 +41,7 @@ For the below properties, please refer to Analogix DP binding document:
 	-phys (required)
 	-phy-names (required)
 	-hpd-gpios (optional)
+	-analogix,need-force-hpd (optional)
 	-video interfaces (optional)
 
 Deprecated properties for DisplayPort:
diff --git a/drivers/gpu/drm/bridge/analogix/analogix_dp_core.c b/drivers/gpu/drm/bridge/analogix/analogix_dp_core.c
index f7227ec..e6b328a 100644
--- a/drivers/gpu/drm/bridge/analogix/analogix_dp_core.c
+++ b/drivers/gpu/drm/bridge/analogix/analogix_dp_core.c
@@ -63,15 +63,38 @@ static int analogix_dp_detect_hpd(struct analogix_dp_device *dp)
 {
 	int timeout_loop = 0;
 
-	while (analogix_dp_get_plug_in_status(dp) != 0) {
+	while (timeout_loop < DP_TIMEOUT_LOOP_COUNT) {
+		if (analogix_dp_get_plug_in_status(dp) == 0)
+			return 0;
+
 		timeout_loop++;
-		if (DP_TIMEOUT_LOOP_COUNT < timeout_loop) {
-			dev_err(dp->dev, "failed to get hpd plug status\n");
-			return -ETIMEDOUT;
-		}
 		usleep_range(10, 11);
 	}
 
+	/*
+	 * Some edp screen do not have hpd signal, so we can't just
+	 * return failed when hpd plug in detect failed, DT property
+	 * "need-force-hpd" would indicate whether driver need this.
+	 */
+	if (!dp->need_force_hpd)
+		return -ETIMEDOUT;
+
+	/*
+	 * The eDP TRM indicate that if HPD_STATUS(RO) is 0, AUX CH
+	 * will not work, so we need to give a force hpd action to
+	 * set HPD_STATUS manually.
+	 */
+	dev_dbg(dp->dev, "failed to get hpd plug status, try to force hpd\n");
+
+	analogix_dp_force_hpd(dp);
+
+	if (analogix_dp_get_plug_in_status(dp) != 0) {
+		dev_err(dp->dev, "failed to get hpd plug in status\n");
+		return -EINVAL;
+	}
+
+	dev_dbg(dp->dev, "success to get plug in status after force hpd\n");
+
 	return 0;
 }
 
@@ -1287,6 +1310,9 @@ int analogix_dp_bind(struct device *dev, struct drm_device *drm_dev,
 	if (IS_ERR(dp->reg_base))
 		return PTR_ERR(dp->reg_base);
 
+	dp->need_force_hpd =
+		of_property_read_bool(dev->of_node, "analogix,need-force-hpd");
+
 	dp->hpd_gpio = of_get_named_gpio(dev->of_node, "hpd-gpios", 0);
 	if (gpio_is_valid(dp->hpd_gpio))
 		dp->hpd_gpio = of_get_named_gpio(dev->of_node,
diff --git a/drivers/gpu/drm/bridge/analogix/analogix_dp_core.h b/drivers/gpu/drm/bridge/analogix/analogix_dp_core.h
index d8945e2..6960ab3 100644
--- a/drivers/gpu/drm/bridge/analogix/analogix_dp_core.h
+++ b/drivers/gpu/drm/bridge/analogix/analogix_dp_core.h
@@ -160,6 +160,7 @@ struct analogix_dp_device {
 	struct phy		*phy;
 	int			dpms_mode;
 	int			hpd_gpio;
+	bool                    need_force_hpd;
 
 	struct analogix_dp_plat_data *plat_data;
 };
@@ -180,6 +181,7 @@ void analogix_dp_set_analog_power_down(struct analogix_dp_device *dp,
 				       bool enable);
 void analogix_dp_init_analog_func(struct analogix_dp_device *dp);
 void analogix_dp_init_hpd(struct analogix_dp_device *dp);
+void analogix_dp_force_hpd(struct analogix_dp_device *dp);
 enum dp_irq_type analogix_dp_get_irq_type(struct analogix_dp_device *dp);
 void analogix_dp_clear_hotplug_interrupts(struct analogix_dp_device *dp);
 void analogix_dp_reset_aux(struct analogix_dp_device *dp);
diff --git a/drivers/gpu/drm/bridge/analogix/analogix_dp_reg.c b/drivers/gpu/drm/bridge/analogix/analogix_dp_reg.c
index 15346fe..3086afc 100644
--- a/drivers/gpu/drm/bridge/analogix/analogix_dp_reg.c
+++ b/drivers/gpu/drm/bridge/analogix/analogix_dp_reg.c
@@ -365,6 +365,15 @@ void analogix_dp_init_hpd(struct analogix_dp_device *dp)
 	writel(reg, dp->reg_base + ANALOGIX_DP_SYS_CTL_3);
 }
 
+void analogix_dp_force_hpd(struct analogix_dp_device *dp)
+{
+	u32 reg;
+
+	reg = readl(dp->reg_base + ANALOGIX_DP_SYS_CTL_3);
+	reg = (F_HPD | HPD_CTRL);
+	writel(reg, dp->reg_base + ANALOGIX_DP_SYS_CTL_3);
+}
+
 enum dp_irq_type analogix_dp_get_irq_type(struct analogix_dp_device *dp)
 {
 	u32 reg;
-- 
2.1.2




From ykk at rock-chips.com  Mon Aug 31 23:17:40 2015
From: ykk at rock-chips.com (Yakir Yang)
Date: Tue,  1 Sep 2015 14:17:40 +0800
Subject: [PATCH v4 15/16] drm: bridge: analogix/dp: move hpd detect to
 connector detect function
In-Reply-To: <1441086371-24838-1-git-send-email-ykk@rock-chips.com>
References: <1441086371-24838-1-git-send-email-ykk@rock-chips.com>
Message-ID: <1441088260-25867-1-git-send-email-ykk@rock-chips.com>

This change just make a little clean to make code more like
drm core expect, move hdp detect code from bridge->enable(),
and place them into connector->detect().

Signed-off-by: Yakir Yang <ykk at rock-chips.com>
---
Changes in v4:
- Take Jingoo suggest, add commit messages.

Changes in v3:
- move dp hpd detect to connector detect function.

Changes in v2: None

 drivers/gpu/drm/bridge/analogix/analogix_dp_core.c | 12 ++++++------
 1 file changed, 6 insertions(+), 6 deletions(-)

diff --git a/drivers/gpu/drm/bridge/analogix/analogix_dp_core.c b/drivers/gpu/drm/bridge/analogix/analogix_dp_core.c
index e6b328a..499ec57 100644
--- a/drivers/gpu/drm/bridge/analogix/analogix_dp_core.c
+++ b/drivers/gpu/drm/bridge/analogix/analogix_dp_core.c
@@ -908,12 +908,6 @@ static void analogix_dp_commit(struct analogix_dp_device *dp)
 			DRM_ERROR("failed to disable the panel\n");
 	}
 
-	ret = analogix_dp_detect_hpd(dp);
-	if (ret) {
-		/* Cable has been disconnected, we're done */
-		return;
-	}
-
 	ret = analogix_dp_handle_edid(dp);
 	if (ret) {
 		dev_err(dp->dev, "unable to handle edid\n");
@@ -949,6 +943,12 @@ static void analogix_dp_commit(struct analogix_dp_device *dp)
 static enum drm_connector_status
 analogix_dp_detect(struct drm_connector *connector, bool force)
 {
+	struct analogix_dp_device *dp = connector_to_dp(connector);
+
+	if (analogix_dp_detect_hpd(dp))
+		/* Cable has been disconnected, we're done */
+		return connector_status_disconnected;
+
 	return connector_status_connected;
 }
 
-- 
2.1.2




From ykk at rock-chips.com  Mon Aug 31 23:20:18 2015
From: ykk at rock-chips.com (Yakir Yang)
Date: Tue,  1 Sep 2015 14:20:18 +0800
Subject: [PATCH v4 16/16] drm: bridge: analogix/dp: add edid modes parse in
 get_modes method
In-Reply-To: <1441086371-24838-1-git-send-email-ykk@rock-chips.com>
References: <1441086371-24838-1-git-send-email-ykk@rock-chips.com>
Message-ID: <1441088418-25922-1-git-send-email-ykk@rock-chips.com>

Display Port monitor could support kinds of mode which indicate
in monitor edid, not just one single display resolution which
defined in panel or devivetree property display timing.

Signed-off-by: Yakir Yang <ykk at rock-chips.com>
---
Changes in v4:
- Call drm_panel_prepare() in .get_modes function, ensure panel should
  power on before driver try to read edid message.

Changes in v3:
- Add edid modes parse support

Changes in v2: None

 drivers/gpu/drm/bridge/analogix/analogix_dp_core.c | 31 ++++++++-------
 drivers/gpu/drm/bridge/analogix/analogix_dp_core.h | 46 +++++++++++-----------
 2 files changed, 40 insertions(+), 37 deletions(-)

diff --git a/drivers/gpu/drm/bridge/analogix/analogix_dp_core.c b/drivers/gpu/drm/bridge/analogix/analogix_dp_core.c
index 499ec57..c71e5f6 100644
--- a/drivers/gpu/drm/bridge/analogix/analogix_dp_core.c
+++ b/drivers/gpu/drm/bridge/analogix/analogix_dp_core.c
@@ -111,7 +111,7 @@ static unsigned char analogix_dp_calc_edid_check_sum(unsigned char *edid_data)
 
 static int analogix_dp_read_edid(struct analogix_dp_device *dp)
 {
-	unsigned char edid[EDID_BLOCK_LENGTH * 2];
+	unsigned char *edid = dp->edid;
 	unsigned int extend_block = 0;
 	unsigned char sum;
 	unsigned char test_vector;
@@ -908,12 +908,6 @@ static void analogix_dp_commit(struct analogix_dp_device *dp)
 			DRM_ERROR("failed to disable the panel\n");
 	}
 
-	ret = analogix_dp_handle_edid(dp);
-	if (ret) {
-		dev_err(dp->dev, "unable to handle edid\n");
-		return;
-	}
-
 	ret = analogix_dp_set_link_train(dp, dp->video_info.max_lane_count,
 					 dp->video_info.max_link_rate);
 	if (ret) {
@@ -972,8 +966,24 @@ static int analogix_dp_get_modes(struct drm_connector *connector)
 {
 	struct analogix_dp_device *dp = connector_to_dp(connector);
 	struct analogix_dp_plat_data *plat_data = dp->plat_data;
+	struct edid *edid = (struct edid *)dp->edid;
 	int num_modes = 0;
 
+	if (dp->plat_data && dp->plat_data->panel) {
+		if (drm_panel_prepare(dp->plat_data->panel)) {
+			DRM_ERROR("failed to setup the panel\n");
+			return -EINVAL;
+		}
+	}
+
+	if (analogix_dp_handle_edid(dp)) {
+		dev_err(dp->dev, "unable to handle edid\n");
+		return -EINVAL;
+	}
+
+	drm_mode_connector_update_edid_property(connector, edid);
+	num_modes += drm_add_edid_modes(connector, edid);
+
 	if (plat_data && plat_data->panel)
 		num_modes += drm_panel_get_modes(plat_data->panel);
 
@@ -1055,13 +1065,6 @@ static void analogix_dp_bridge_enable(struct drm_bridge *bridge)
 	if (dp->dpms_mode == DRM_MODE_DPMS_ON)
 		return;
 
-	if (dp->plat_data && dp->plat_data->panel) {
-		if (drm_panel_prepare(dp->plat_data->panel)) {
-			DRM_ERROR("failed to setup the panel\n");
-			return;
-		}
-	}
-
 	if (dp->plat_data && dp->plat_data->power_on)
 		dp->plat_data->power_on(dp->plat_data);
 
diff --git a/drivers/gpu/drm/bridge/analogix/analogix_dp_core.h b/drivers/gpu/drm/bridge/analogix/analogix_dp_core.h
index 6960ab3..5348b1b 100644
--- a/drivers/gpu/drm/bridge/analogix/analogix_dp_core.h
+++ b/drivers/gpu/drm/bridge/analogix/analogix_dp_core.h
@@ -20,6 +20,28 @@
 #define MAX_CR_LOOP 5
 #define MAX_EQ_LOOP 5
 
+/* I2C EDID Chip ID, Slave Address */
+#define I2C_EDID_DEVICE_ADDR			0x50
+#define I2C_E_EDID_DEVICE_ADDR			0x30
+
+#define EDID_BLOCK_LENGTH			0x80
+#define EDID_HEADER_PATTERN			0x00
+#define EDID_EXTENSION_FLAG			0x7e
+#define EDID_CHECKSUM				0x7f
+
+/* DP_MAX_LANE_COUNT */
+#define DPCD_ENHANCED_FRAME_CAP(x)		(((x) >> 7) & 0x1)
+#define DPCD_MAX_LANE_COUNT(x)			((x) & 0x1f)
+
+/* DP_LANE_COUNT_SET */
+#define DPCD_LANE_COUNT_SET(x)			((x) & 0x1f)
+
+/* DP_TRAINING_LANE0_SET */
+#define DPCD_PRE_EMPHASIS_SET(x)		(((x) & 0x3) << 3)
+#define DPCD_PRE_EMPHASIS_GET(x)		(((x) >> 3) & 0x3)
+#define DPCD_VOLTAGE_SWING_SET(x)		(((x) & 0x3) << 0)
+#define DPCD_VOLTAGE_SWING_GET(x)		(((x) >> 0) & 0x3)
+
 enum link_rate_type {
 	LINK_RATE_1_62GBPS = DP_LINK_BW_1_62,
 	LINK_RATE_2_70GBPS = DP_LINK_BW_2_7,
@@ -161,6 +183,7 @@ struct analogix_dp_device {
 	int			dpms_mode;
 	int			hpd_gpio;
 	bool                    need_force_hpd;
+	unsigned char           edid[EDID_BLOCK_LENGTH * 2];
 
 	struct analogix_dp_plat_data *plat_data;
 };
@@ -260,27 +283,4 @@ int analogix_dp_is_video_stream_on(struct analogix_dp_device *dp);
 void analogix_dp_config_video_slave_mode(struct analogix_dp_device *dp);
 void analogix_dp_enable_scrambling(struct analogix_dp_device *dp);
 void analogix_dp_disable_scrambling(struct analogix_dp_device *dp);
-
-/* I2C EDID Chip ID, Slave Address */
-#define I2C_EDID_DEVICE_ADDR			0x50
-#define I2C_E_EDID_DEVICE_ADDR			0x30
-
-#define EDID_BLOCK_LENGTH			0x80
-#define EDID_HEADER_PATTERN			0x00
-#define EDID_EXTENSION_FLAG			0x7e
-#define EDID_CHECKSUM				0x7f
-
-/* DP_MAX_LANE_COUNT */
-#define DPCD_ENHANCED_FRAME_CAP(x)		(((x) >> 7) & 0x1)
-#define DPCD_MAX_LANE_COUNT(x)			((x) & 0x1f)
-
-/* DP_LANE_COUNT_SET */
-#define DPCD_LANE_COUNT_SET(x)			((x) & 0x1f)
-
-/* DP_TRAINING_LANE0_SET */
-#define DPCD_PRE_EMPHASIS_SET(x)		(((x) & 0x3) << 3)
-#define DPCD_PRE_EMPHASIS_GET(x)		(((x) >> 3) & 0x3)
-#define DPCD_VOLTAGE_SWING_SET(x)		(((x) & 0x3) << 0)
-#define DPCD_VOLTAGE_SWING_GET(x)		(((x) >> 0) & 0x3)
-
 #endif /* _ANALOGIX_DP_CORE_H */
-- 
2.1.2




From maxime.ripard at free-electrons.com  Mon Aug 31 23:29:23 2015
From: maxime.ripard at free-electrons.com (Maxime Ripard)
Date: Tue, 1 Sep 2015 08:29:23 +0200
Subject: [PATCH 2/6] ARM: dts: sunxi: Add dtsi for AXP221 PMIC
In-Reply-To: <CAGb2v66qxgpGGzYHTP8=m-jhy2B2W2Z0iQmSed+e49PJVX_Q_w@mail.gmail.com>
References: <1440755679-8266-1-git-send-email-wens@csie.org>
 <1440755679-8266-3-git-send-email-wens@csie.org>
 <20150828123159.GJ29389@lukather>
 <CAGb2v66nBh+_P=EDxrNYeFoUUXqPWuZyfq1OEQww_aSMhT8wVQ@mail.gmail.com>
 <20150828204351.GS29389@lukather>
 <CAGb2v66qxgpGGzYHTP8=m-jhy2B2W2Z0iQmSed+e49PJVX_Q_w@mail.gmail.com>
Message-ID: <20150901062923.GE29389@lukather>

On Sat, Aug 29, 2015 at 10:07:12AM +0800, Chen-Yu Tsai wrote:
> >> >> +
> >> >> +&axp221 {
> >> >> +     compatible = "x-powers,axp221";
> >> >> +     interrupt-controller;
> >> >> +     #interrupt-cells = <1>;
> >> >> +
> >> >> +     regulators {
> >> >> +             /* Default work frequency for buck regulators */
> >> >> +             x-powers,dcdc-freq = <3000>;
> >> >> +
> >> >> +             /* supplies for dc1sw & dc5ldo are connected internally */
> >> >> +             dcdc1-supply = <&reg_dcdc1>;
> >> >> +             dcdc5-supply = <&reg_dcdc5>;
> >> >
> >> > so the parent regulator of DCDC1 is DCDC1 ?
> >>
> >> These probably aren't the best names. These are the supplies for DC1SW and
> >> DC5LDO, respectively. They are connected internally, so there aren't named
> >> pins for them. The comment above explains it, though probably not clearly
> >> enough. Furthermore, the input pins for DCDC1/5 are VIN1/5.
> >
> > I'm not quite sure I understand. They're connected internally but they
> > have pins ?
> 
> Internally, DCDC1's output feeds the input for DC1SW (which is just a switch
> BTW) and DCDC5's output feeds DC5LDO (which is an LDO). Both these extra
> regulators have separate controls. There are no external pins to name the
> supplies after, so I just named them after which regulator supplies them.

Well, there is. dc5ldo and dc1sw. And it is also how you called these
regulators in your DT, so it would make much more sense to have it
listed as such.

Maxime

-- 
Maxime Ripard, Free Electrons
Embedded Linux, Kernel and Android engineering
http://free-electrons.com
-------------- next part --------------
A non-text attachment was scrubbed...
Name: signature.asc
Type: application/pgp-signature
Size: 819 bytes
Desc: Digital signature
URL: <http://lists.infradead.org/pipermail/linux-arm-kernel/attachments/20150901/f437a683/attachment.sig>

From jarkko.nikula at linux.intel.com  Mon Aug 31 23:36:04 2015
From: jarkko.nikula at linux.intel.com (Jarkko Nikula)
Date: Tue, 01 Sep 2015 09:36:04 +0300
Subject: ARM: pxa: build error in arch/arm/plat-pxa/ssp.c
In-Reply-To: <1441073073.12012.3.camel@ingics.com>
References: <1441073073.12012.3.camel@ingics.com>
Message-ID: <55E54754.1060002@linux.intel.com>

Hi

Adding linux-spi and Mark Brown.

On 09/01/2015 05:04 AM, Axel Lin wrote:
>    CC [M]  arch/arm/plat-pxa/ssp.o
> arch/arm/plat-pxa/ssp.c:110:52: error: 'LPSS_SSP' undeclared here (not in a function)
> scripts/Makefile.build:264: recipe for target 'arch/arm/plat-pxa/ssp.o' failed
> make[1]: *** [arch/arm/plat-pxa/ssp.o] Error 1
> Makefile:965: recipe for target 'arch/arm/plat-pxa' failed
> make: *** [arch/arm/plat-pxa] Error 2
>
>
> The build error is introduced by:
> commit 03fbf488cece461468d3abb795f5e5f055e00040
> Author: Jarkko Nikula <jarkko.nikula at linux.intel.com>
> Date:   Thu Jun 4 16:55:10 2015 +0300
>
>      spi: pxa2xx: Differentiate Intel LPSS types
>
I obviously didn't do tree wide grep for LPSS_SSP and pxa3xx_defconfig 
don't reveal it without setting CONFIG_USE_OF. Sorry about that.

No I'm pondering how to fix this. I see these bindings are added by the 
commit a6e56c28a178 ("ARM: pxa: ssp: add DT bindings") but some of the 
types are not used anywhere. For instance PXA168_SSP or PXA910_SSP. Then 
PXA3xx_SSP is used in sound/soc/pxa/pxa-ssp.c and CE4100_SSP in 
drivers/spi/spi-pxa2xx.c (where LPSS_SSP was used too before 
differentiating it).

What I'm wondering is this binding below correct in 
arch/arm/plat-pxa/ssp.c? LPSS_SSP was meant to be for Intel Intel Low 
Power Subsystem SPI.

"{ .compatible = "mrvl,lpss-ssp",	.data = (void *) LPSS_SSP }"

Mika, Daniel: do you know is there any change there is a Marvell PXA 
platform compatible with Intel LPSS or is above binding bogus?

-- 
Jarkko


From jszhang at marvell.com  Mon Aug 31 23:39:23 2015
From: jszhang at marvell.com (Jisheng Zhang)
Date: Tue, 1 Sep 2015 14:39:23 +0800
Subject: about system time incorrect after changing cpu frequency
In-Reply-To: <20150901060236.GB1456@linux>
References: <CAOVJa8GTDj3UJpgUd4nH1wknUKa6fgac=1SsqC8g=UCG0MGuDw@mail.gmail.com>
 <CAOh2x=ky8_uwqvdH-krKxgMSby5jgovJp7odK6x=MpqNL+YoGg@mail.gmail.com>
 <CAOVJa8HNQ-s=yDfADCcoL+r22ALpHFtTjWZ=oxTkBUriYbCk+Q@mail.gmail.com>
 <20150901060236.GB1456@linux>
Message-ID: <20150901143923.11b075b5@xhacker>

On Tue, 1 Sep 2015 11:32:36 +0530
Viresh Kumar <viresh.kumar at linaro.org> wrote:

> On 01-09-15, 13:36, vichy wrote:
> > >> I try to call below 2 functions to change the frequency of clocksource
> > >> and clockevent, but the above b) sleep time is still incorrect when
> > >> cpu runs in 500Mhz.
> > >>     clockevents_update_freq(this_cpu_ptr(gt_evt), gt_clk_rate);
> > >>     __clocksource_updatefreq_hz(&gt_clocksource, gt_clk_rate);
> 
> How and when were you calling them? What kernel version is it ?
> 
> > Clock Event Device: arm_global_timer
> 
> This driver doesn't have support to update clkevt device's freq. You
> may need to modify that based on how arch/arm/kernel/smp_twd.c is
> updated. look for: clockevents_update_freq().
> 

This can only help the clockevent. Even with this cpufreq notifier
update, the globaltimer clocksource still can't hold correct/accurate time.

I think the arm global timer is not suitable for clocksource if cpufreq is
enabled.



From wens at csie.org  Mon Aug 31 23:40:23 2015
From: wens at csie.org (Chen-Yu Tsai)
Date: Tue, 1 Sep 2015 14:40:23 +0800
Subject: [PATCH 2/6] ARM: dts: sunxi: Add dtsi for AXP221 PMIC
In-Reply-To: <20150901062923.GE29389@lukather>
References: <1440755679-8266-1-git-send-email-wens@csie.org>
 <1440755679-8266-3-git-send-email-wens@csie.org>
 <20150828123159.GJ29389@lukather>
 <CAGb2v66nBh+_P=EDxrNYeFoUUXqPWuZyfq1OEQww_aSMhT8wVQ@mail.gmail.com>
 <20150828204351.GS29389@lukather>
 <CAGb2v66qxgpGGzYHTP8=m-jhy2B2W2Z0iQmSed+e49PJVX_Q_w@mail.gmail.com>
 <20150901062923.GE29389@lukather>
Message-ID: <CAGb2v66BP8UjeqF6DxHHMEsw=vo-OZvnwQavk=EC4OGE4_78MQ@mail.gmail.com>

On Tue, Sep 1, 2015 at 2:29 PM, Maxime Ripard
<maxime.ripard at free-electrons.com> wrote:
> On Sat, Aug 29, 2015 at 10:07:12AM +0800, Chen-Yu Tsai wrote:
>> >> >> +
>> >> >> +&axp221 {
>> >> >> +     compatible = "x-powers,axp221";
>> >> >> +     interrupt-controller;
>> >> >> +     #interrupt-cells = <1>;
>> >> >> +
>> >> >> +     regulators {
>> >> >> +             /* Default work frequency for buck regulators */
>> >> >> +             x-powers,dcdc-freq = <3000>;
>> >> >> +
>> >> >> +             /* supplies for dc1sw & dc5ldo are connected internally */
>> >> >> +             dcdc1-supply = <&reg_dcdc1>;
>> >> >> +             dcdc5-supply = <&reg_dcdc5>;
>> >> >
>> >> > so the parent regulator of DCDC1 is DCDC1 ?
>> >>
>> >> These probably aren't the best names. These are the supplies for DC1SW and
>> >> DC5LDO, respectively. They are connected internally, so there aren't named
>> >> pins for them. The comment above explains it, though probably not clearly
>> >> enough. Furthermore, the input pins for DCDC1/5 are VIN1/5.
>> >
>> > I'm not quite sure I understand. They're connected internally but they
>> > have pins ?
>>
>> Internally, DCDC1's output feeds the input for DC1SW (which is just a switch
>> BTW) and DCDC5's output feeds DC5LDO (which is an LDO). Both these extra
>> regulators have separate controls. There are no external pins to name the
>> supplies after, so I just named them after which regulator supplies them.
>
> Well, there is. dc5ldo and dc1sw. And it is also how you called these
> regulators in your DT, so it would make much more sense to have it
> listed as such.

I was under the impression that we name them after the input pins. The names
are also documented in Documentation/devicetree/bindings/mfd/axp20x.txt

Do you want to change them?


Regards
ChenYu


